From 5c8a554282e8340a52510fe861ddd35e9b6ebe35 Mon Sep 17 00:00:00 2001 From: plumedbot Date: Fri, 19 Apr 2024 12:12:46 +0000 Subject: [PATCH] Update to plumed/plumed2@1daf1a9 --- .nojekyll | 0 README.md | 12 + coverage-libs/amber.png | Bin 0 -> 141 bytes .../asmjit/arch.cpp.func-sort-c.html | 81 + coverage-libs/asmjit/arch.cpp.func.html | 81 + coverage-libs/asmjit/arch.cpp.gcov.html | 264 + coverage-libs/asmjit/arch.h.func-sort-c.html | 73 + coverage-libs/asmjit/arch.h.func.html | 73 + coverage-libs/asmjit/arch.h.gcov.html | 305 + .../asmjit/assembler.cpp.func-sort-c.html | 145 + coverage-libs/asmjit/assembler.cpp.func.html | 145 + coverage-libs/asmjit/assembler.cpp.gcov.html | 550 + .../asmjit/assembler.h.func-sort-c.html | 73 + coverage-libs/asmjit/assembler.h.func.html | 73 + coverage-libs/asmjit/assembler.h.gcov.html | 260 + .../asmjit/codebuilder.cpp.func-sort-c.html | 205 + .../asmjit/codebuilder.cpp.func.html | 205 + .../asmjit/codebuilder.cpp.gcov.html | 687 + .../asmjit/codebuilder.h.func-sort-c.html | 73 + coverage-libs/asmjit/codebuilder.h.func.html | 73 + coverage-libs/asmjit/codebuilder.h.gcov.html | 1021 + .../asmjit/codecompiler.cpp.func-sort-c.html | 217 + .../asmjit/codecompiler.cpp.func.html | 217 + .../asmjit/codecompiler.cpp.gcov.html | 676 + .../asmjit/codecompiler.h.func-sort-c.html | 73 + coverage-libs/asmjit/codecompiler.h.func.html | 73 + coverage-libs/asmjit/codecompiler.h.gcov.html | 844 + .../asmjit/codeemitter.cpp.func-sort-c.html | 197 + .../asmjit/codeemitter.cpp.func.html | 197 + .../asmjit/codeemitter.cpp.gcov.html | 339 + .../asmjit/codeemitter.h.func-sort-c.html | 73 + coverage-libs/asmjit/codeemitter.h.func.html | 73 + coverage-libs/asmjit/codeemitter.h.gcov.html | 605 + .../asmjit/codeholder.cpp.func-sort-c.html | 173 + coverage-libs/asmjit/codeholder.cpp.func.html | 173 + coverage-libs/asmjit/codeholder.cpp.gcov.html | 800 + .../asmjit/codeholder.h.func-sort-c.html | 73 + coverage-libs/asmjit/codeholder.h.func.html | 73 + coverage-libs/asmjit/codeholder.h.gcov.html | 854 + .../asmjit/constpool.cpp.func-sort-c.html | 105 + coverage-libs/asmjit/constpool.cpp.func.html | 105 + coverage-libs/asmjit/constpool.cpp.gcov.html | 614 + .../asmjit/constpool.h.func-sort-c.html | 73 + coverage-libs/asmjit/constpool.h.func.html | 73 + coverage-libs/asmjit/constpool.h.gcov.html | 363 + .../asmjit/cpuinfo.cpp.func-sort-c.html | 85 + coverage-libs/asmjit/cpuinfo.cpp.func.html | 85 + coverage-libs/asmjit/cpuinfo.cpp.gcov.html | 777 + .../asmjit/cpuinfo.h.func-sort-c.html | 73 + coverage-libs/asmjit/cpuinfo.h.func.html | 73 + coverage-libs/asmjit/cpuinfo.h.gcov.html | 479 + .../asmjit/func.cpp.func-sort-c.html | 101 + coverage-libs/asmjit/func.cpp.func.html | 101 + coverage-libs/asmjit/func.cpp.gcov.html | 289 + coverage-libs/asmjit/func.h.func-sort-c.html | 73 + coverage-libs/asmjit/func.h.func.html | 73 + coverage-libs/asmjit/func.h.gcov.html | 1404 + .../asmjit/globals.cpp.func-sort-c.html | 85 + coverage-libs/asmjit/globals.cpp.func.html | 85 + coverage-libs/asmjit/globals.cpp.gcov.html | 221 + .../asmjit/globals.h.func-sort-c.html | 73 + coverage-libs/asmjit/globals.h.func.html | 73 + coverage-libs/asmjit/globals.h.gcov.html | 447 + coverage-libs/asmjit/index-sort-f.html | 604 + coverage-libs/asmjit/index-sort-l.html | 604 + coverage-libs/asmjit/index.html | 604 + .../asmjit/inst.cpp.func-sort-c.html | 81 + coverage-libs/asmjit/inst.cpp.func.html | 81 + coverage-libs/asmjit/inst.cpp.gcov.html | 180 + coverage-libs/asmjit/inst.h.func-sort-c.html | 73 + coverage-libs/asmjit/inst.h.func.html | 73 + coverage-libs/asmjit/inst.h.gcov.html | 214 + .../asmjit/logging.cpp.func-sort-c.html | 173 + coverage-libs/asmjit/logging.cpp.func.html | 173 + coverage-libs/asmjit/logging.cpp.gcov.html | 601 + .../asmjit/logging.h.func-sort-c.html | 73 + coverage-libs/asmjit/logging.h.func.html | 73 + coverage-libs/asmjit/logging.h.gcov.html | 394 + .../asmjit/moved_string.h.func-sort-c.html | 73 + coverage-libs/asmjit/moved_string.h.func.html | 73 + coverage-libs/asmjit/moved_string.h.gcov.html | 395 + .../asmjit/operand.h.func-sort-c.html | 73 + coverage-libs/asmjit/operand.h.func.html | 73 + coverage-libs/asmjit/operand.h.gcov.html | 1676 + .../asmjit/osutils.cpp.func-sort-c.html | 93 + coverage-libs/asmjit/osutils.cpp.func.html | 93 + coverage-libs/asmjit/osutils.cpp.gcov.html | 331 + .../asmjit/osutils.h.func-sort-c.html | 73 + coverage-libs/asmjit/osutils.h.func.html | 73 + coverage-libs/asmjit/osutils.h.gcov.html | 284 + .../asmjit/regalloc.cpp.func-sort-c.html | 125 + coverage-libs/asmjit/regalloc.cpp.func.html | 125 + coverage-libs/asmjit/regalloc.cpp.gcov.html | 697 + .../asmjit/regalloc_p.h.func-sort-c.html | 73 + coverage-libs/asmjit/regalloc_p.h.func.html | 73 + coverage-libs/asmjit/regalloc_p.h.gcov.html | 674 + .../asmjit/runtime.cpp.func-sort-c.html | 121 + coverage-libs/asmjit/runtime.cpp.func.html | 121 + coverage-libs/asmjit/runtime.cpp.gcov.html | 250 + .../asmjit/runtime.h.func-sort-c.html | 73 + coverage-libs/asmjit/runtime.h.func.html | 73 + coverage-libs/asmjit/runtime.h.gcov.html | 304 + .../asmjit/string.cpp.func-sort-c.html | 129 + coverage-libs/asmjit/string.cpp.func.html | 129 + coverage-libs/asmjit/string.cpp.gcov.html | 456 + coverage-libs/asmjit/utils.h.func-sort-c.html | 73 + coverage-libs/asmjit/utils.h.func.html | 73 + coverage-libs/asmjit/utils.h.gcov.html | 1464 + .../asmjit/vmem.cpp.func-sort-c.html | 129 + coverage-libs/asmjit/vmem.cpp.func.html | 129 + coverage-libs/asmjit/vmem.cpp.gcov.html | 1180 + .../asmjit/x86assembler.cpp.func-sort-c.html | 101 + .../asmjit/x86assembler.cpp.func.html | 101 + .../asmjit/x86assembler.cpp.gcov.html | 4722 +++ .../asmjit/x86assembler.h.func-sort-c.html | 73 + coverage-libs/asmjit/x86assembler.h.func.html | 73 + coverage-libs/asmjit/x86assembler.h.gcov.html | 202 + .../asmjit/x86builder.cpp.func-sort-c.html | 93 + coverage-libs/asmjit/x86builder.cpp.func.html | 93 + coverage-libs/asmjit/x86builder.cpp.gcov.html | 169 + .../asmjit/x86compiler.cpp.func-sort-c.html | 101 + .../asmjit/x86compiler.cpp.func.html | 101 + .../asmjit/x86compiler.cpp.gcov.html | 479 + .../asmjit/x86compiler.h.func-sort-c.html | 81 + coverage-libs/asmjit/x86compiler.h.func.html | 81 + coverage-libs/asmjit/x86compiler.h.gcov.html | 399 + .../asmjit/x86emitter.h.func-sort-c.html | 73 + coverage-libs/asmjit/x86emitter.h.func.html | 73 + coverage-libs/asmjit/x86emitter.h.gcov.html | 5226 +++ .../asmjit/x86inst.cpp.func-sort-c.html | 81 + coverage-libs/asmjit/x86inst.cpp.func.html | 81 + coverage-libs/asmjit/x86inst.cpp.gcov.html | 3830 ++ .../asmjit/x86inst.h.func-sort-c.html | 73 + coverage-libs/asmjit/x86inst.h.func.html | 73 + coverage-libs/asmjit/x86inst.h.gcov.html | 2624 ++ .../asmjit/x86instimpl.cpp.func-sort-c.html | 85 + .../asmjit/x86instimpl.cpp.func.html | 85 + .../asmjit/x86instimpl.cpp.gcov.html | 834 + .../asmjit/x86internal.cpp.func-sort-c.html | 129 + .../asmjit/x86internal.cpp.func.html | 129 + .../asmjit/x86internal.cpp.gcov.html | 1459 + .../asmjit/x86logging.cpp.func-sort-c.html | 105 + coverage-libs/asmjit/x86logging.cpp.func.html | 105 + coverage-libs/asmjit/x86logging.cpp.gcov.html | 787 + .../asmjit/x86misc.h.func-sort-c.html | 73 + coverage-libs/asmjit/x86misc.h.func.html | 73 + coverage-libs/asmjit/x86misc.h.gcov.html | 494 + .../asmjit/x86operand.h.func-sort-c.html | 73 + coverage-libs/asmjit/x86operand.h.func.html | 73 + coverage-libs/asmjit/x86operand.h.gcov.html | 1210 + .../asmjit/x86regalloc.cpp.func-sort-c.html | 189 + .../asmjit/x86regalloc.cpp.func.html | 189 + .../asmjit/x86regalloc.cpp.gcov.html | 4165 +++ .../asmjit/x86regalloc_p.h.func-sort-c.html | 73 + .../asmjit/x86regalloc_p.h.func.html | 73 + .../asmjit/x86regalloc_p.h.gcov.html | 811 + .../asmjit/zone.cpp.func-sort-c.html | 161 + coverage-libs/asmjit/zone.cpp.func.html | 161 + coverage-libs/asmjit/zone.cpp.gcov.html | 936 + coverage-libs/asmjit/zone.h.func-sort-c.html | 81 + coverage-libs/asmjit/zone.h.func.html | 81 + coverage-libs/asmjit/zone.h.gcov.html | 1234 + coverage-libs/blas/blas.cpp.func-sort-c.html | 217 + coverage-libs/blas/blas.cpp.func.html | 217 + coverage-libs/blas/blas.cpp.gcov.html | 3767 ++ coverage-libs/blas/index-sort-f.html | 94 + coverage-libs/blas/index-sort-l.html | 94 + coverage-libs/blas/index.html | 94 + coverage-libs/emerald.png | Bin 0 -> 141 bytes coverage-libs/gcov.css | 519 + coverage-libs/glass.png | Bin 0 -> 167 bytes coverage-libs/index-sort-f.html | 144 + coverage-libs/index-sort-l.html | 144 + coverage-libs/index.html | 144 + coverage-libs/lapack/index-sort-f.html | 94 + coverage-libs/lapack/index-sort-l.html | 94 + coverage-libs/lapack/index.html | 94 + .../lapack/lapack.cpp.func-sort-c.html | 797 + coverage-libs/lapack/lapack.cpp.func.html | 797 + coverage-libs/lapack/lapack.cpp.gcov.html | 31100 ++++++++++++++++ .../CompiledExpression.cpp.func-sort-c.html | 149 + .../lepton/CompiledExpression.cpp.func.html | 149 + .../lepton/CompiledExpression.cpp.gcov.html | 586 + .../CompiledExpression.h.func-sort-c.html | 73 + .../lepton/CompiledExpression.h.func.html | 73 + .../lepton/CompiledExpression.h.gcov.html | 241 + .../lepton/Exception.h.func-sort-c.html | 89 + coverage-libs/lepton/Exception.h.func.html | 89 + coverage-libs/lepton/Exception.h.gcov.html | 170 + .../ExpressionProgram.cpp.func-sort-c.html | 121 + .../lepton/ExpressionProgram.cpp.func.html | 121 + .../lepton/ExpressionProgram.cpp.gcov.html | 221 + .../ExpressionTreeNode.cpp.func-sort-c.html | 133 + .../lepton/ExpressionTreeNode.cpp.func.html | 133 + .../lepton/ExpressionTreeNode.cpp.gcov.html | 264 + .../lepton/Operation.cpp.func-sort-c.html | 301 + coverage-libs/lepton/Operation.cpp.func.html | 301 + coverage-libs/lepton/Operation.cpp.gcov.html | 747 + .../lepton/Operation.h.func-sort-c.html | 1233 + coverage-libs/lepton/Operation.h.func.html | 1233 + coverage-libs/lepton/Operation.h.gcov.html | 1379 + .../ParsedExpression.cpp.func-sort-c.html | 157 + .../lepton/ParsedExpression.cpp.func.html | 157 + .../lepton/ParsedExpression.cpp.gcov.html | 528 + .../ParsedExpression.h.func-sort-c.html | 73 + .../lepton/ParsedExpression.h.func.html | 73 + .../lepton/ParsedExpression.h.gcov.html | 242 + .../lepton/Parser.cpp.func-sort-c.html | 113 + coverage-libs/lepton/Parser.cpp.func.html | 113 + coverage-libs/lepton/Parser.cpp.gcov.html | 585 + coverage-libs/lepton/index-sort-f.html | 184 + coverage-libs/lepton/index-sort-l.html | 184 + coverage-libs/lepton/index.html | 184 + .../molfile/Gromacs.h.func-sort-c.html | 217 + coverage-libs/molfile/Gromacs.h.func.html | 217 + coverage-libs/molfile/Gromacs.h.gcov.html | 2090 ++ .../molfile/crdplugin.cpp.func-sort-c.html | 109 + coverage-libs/molfile/crdplugin.cpp.func.html | 109 + coverage-libs/molfile/crdplugin.cpp.gcov.html | 339 + .../molfile/dcdplugin.cpp.func-sort-c.html | 149 + coverage-libs/molfile/dcdplugin.cpp.func.html | 149 + coverage-libs/molfile/dcdplugin.cpp.gcov.html | 1394 + .../molfile/endianswap.h.func-sort-c.html | 89 + coverage-libs/molfile/endianswap.h.func.html | 89 + coverage-libs/molfile/endianswap.h.gcov.html | 294 + .../molfile/fastio.h.func-sort-c.html | 101 + coverage-libs/molfile/fastio.h.func.html | 101 + coverage-libs/molfile/fastio.h.gcov.html | 760 + .../gromacsplugin.cpp.func-sort-c.html | 165 + .../molfile/gromacsplugin.cpp.func.html | 165 + .../molfile/gromacsplugin.cpp.gcov.html | 937 + coverage-libs/molfile/index-sort-f.html | 174 + coverage-libs/molfile/index-sort-l.html | 174 + coverage-libs/molfile/index.html | 174 + .../molfile/pdbplugin.cpp.func-sort-c.html | 129 + coverage-libs/molfile/pdbplugin.cpp.func.html | 129 + coverage-libs/molfile/pdbplugin.cpp.gcov.html | 725 + .../molfile/periodic_table.h.func-sort-c.html | 89 + .../molfile/periodic_table.h.func.html | 89 + .../molfile/periodic_table.h.gcov.html | 325 + .../molfile/readpdb.h.func-sort-c.html | 105 + coverage-libs/molfile/readpdb.h.func.html | 105 + coverage-libs/molfile/readpdb.h.gcov.html | 524 + coverage-libs/ruby.png | Bin 0 -> 141 bytes coverage-libs/snow.png | Bin 0 -> 141 bytes coverage-libs/updown.png | Bin 0 -> 117 bytes coverage-libs/xdrfile/index-sort-f.html | 114 + coverage-libs/xdrfile/index-sort-l.html | 114 + coverage-libs/xdrfile/index.html | 114 + .../xdrfile/xdrfile.cpp.func-sort-c.html | 397 + coverage-libs/xdrfile/xdrfile.cpp.func.html | 397 + coverage-libs/xdrfile/xdrfile.cpp.gcov.html | 2725 ++ .../xdrfile/xdrfile_trr.cpp.func-sort-c.html | 101 + .../xdrfile/xdrfile_trr.cpp.func.html | 101 + .../xdrfile/xdrfile_trr.cpp.gcov.html | 606 + .../xdrfile/xdrfile_xtc.cpp.func-sort-c.html | 93 + .../xdrfile/xdrfile_xtc.cpp.func.html | 93 + .../xdrfile/xdrfile_xtc.cpp.gcov.html | 242 + .../ActionWithMatrix.cpp.func-sort-c.html | 161 + .../adjmat/ActionWithMatrix.cpp.func.html | 161 + .../adjmat/ActionWithMatrix.cpp.gcov.html | 312 + .../ActionWithMatrix.h.func-sort-c.html | 97 + coverage/adjmat/ActionWithMatrix.h.func.html | 97 + coverage/adjmat/ActionWithMatrix.h.gcov.html | 227 + .../AdjacencyMatrixBase.cpp.func-sort-c.html | 129 + .../adjmat/AdjacencyMatrixBase.cpp.func.html | 129 + .../adjmat/AdjacencyMatrixBase.cpp.gcov.html | 470 + .../AdjacencyMatrixBase.h.func-sort-c.html | 89 + .../adjmat/AdjacencyMatrixBase.h.func.html | 89 + .../adjmat/AdjacencyMatrixBase.h.gcov.html | 190 + coverage/adjmat/Bridge.cpp.func-sort-c.html | 85 + coverage/adjmat/Bridge.cpp.func.html | 85 + coverage/adjmat/Bridge.cpp.gcov.html | 152 + .../adjmat/BridgeMatrix.cpp.func-sort-c.html | 89 + coverage/adjmat/BridgeMatrix.cpp.func.html | 89 + coverage/adjmat/BridgeMatrix.cpp.gcov.html | 213 + .../adjmat/ContactMatrix.cpp.func-sort-c.html | 93 + coverage/adjmat/ContactMatrix.cpp.func.html | 93 + coverage/adjmat/ContactMatrix.cpp.gcov.html | 201 + ...ContactMatrixShortcut.cpp.func-sort-c.html | 85 + .../ContactMatrixShortcut.cpp.func.html | 85 + .../ContactMatrixShortcut.cpp.gcov.html | 215 + .../CovarianceMatrix.cpp.func-sort-c.html | 85 + .../adjmat/CovarianceMatrix.cpp.func.html | 85 + .../adjmat/CovarianceMatrix.cpp.gcov.html | 163 + .../adjmat/Determinent.cpp.func-sort-c.html | 85 + coverage/adjmat/Determinent.cpp.func.html | 85 + coverage/adjmat/Determinent.cpp.gcov.html | 139 + .../DiagonalizeMatrix.cpp.func-sort-c.html | 101 + .../adjmat/DiagonalizeMatrix.cpp.func.html | 101 + .../adjmat/DiagonalizeMatrix.cpp.gcov.html | 230 + .../DistanceMatrix.cpp.func-sort-c.html | 89 + coverage/adjmat/DistanceMatrix.cpp.func.html | 89 + coverage/adjmat/DistanceMatrix.cpp.gcov.html | 164 + .../FunctionOfMatrix.h.func-sort-c.html | 505 + coverage/adjmat/FunctionOfMatrix.h.func.html | 505 + coverage/adjmat/FunctionOfMatrix.h.gcov.html | 514 + .../adjmat/HbondMatrix.cpp.func-sort-c.html | 89 + coverage/adjmat/HbondMatrix.cpp.func.html | 89 + coverage/adjmat/HbondMatrix.cpp.gcov.html | 237 + .../adjmat/InvertMatrix.cpp.func-sort-c.html | 101 + coverage/adjmat/InvertMatrix.cpp.func.html | 101 + coverage/adjmat/InvertMatrix.cpp.gcov.html | 176 + .../MatrixOperationBase.cpp.func-sort-c.html | 93 + .../adjmat/MatrixOperationBase.cpp.func.html | 93 + .../adjmat/MatrixOperationBase.cpp.gcov.html | 159 + .../MatrixTimesMatrix.cpp.func-sort-c.html | 113 + .../adjmat/MatrixTimesMatrix.cpp.func.html | 113 + .../adjmat/MatrixTimesMatrix.cpp.gcov.html | 245 + .../MatrixTimesVector.cpp.func-sort-c.html | 117 + .../adjmat/MatrixTimesVector.cpp.func.html | 117 + .../adjmat/MatrixTimesVector.cpp.gcov.html | 271 + .../adjmat/Neighbors.cpp.func-sort-c.html | 113 + coverage/adjmat/Neighbors.cpp.func.html | 113 + coverage/adjmat/Neighbors.cpp.gcov.html | 213 + .../adjmat/OuterProduct.cpp.func-sort-c.html | 109 + coverage/adjmat/OuterProduct.cpp.func.html | 109 + coverage/adjmat/OuterProduct.cpp.gcov.html | 237 + coverage/adjmat/Sprint.cpp.func-sort-c.html | 85 + coverage/adjmat/Sprint.cpp.func.html | 85 + coverage/adjmat/Sprint.cpp.gcov.html | 220 + .../TopologyMatrix.cpp.func-sort-c.html | 89 + coverage/adjmat/TopologyMatrix.cpp.func.html | 89 + coverage/adjmat/TopologyMatrix.cpp.gcov.html | 347 + .../TorsionsMatrix.cpp.func-sort-c.html | 105 + coverage/adjmat/TorsionsMatrix.cpp.func.html | 105 + coverage/adjmat/TorsionsMatrix.cpp.gcov.html | 237 + .../TransposeMatrix.cpp.func-sort-c.html | 105 + coverage/adjmat/TransposeMatrix.cpp.func.html | 105 + coverage/adjmat/TransposeMatrix.cpp.gcov.html | 209 + coverage/adjmat/VStack.cpp.func-sort-c.html | 113 + coverage/adjmat/VStack.cpp.func.html | 113 + coverage/adjmat/VStack.cpp.gcov.html | 238 + coverage/adjmat/Voronoi.cpp.func-sort-c.html | 113 + coverage/adjmat/Voronoi.cpp.func.html | 113 + coverage/adjmat/Voronoi.cpp.gcov.html | 162 + coverage/adjmat/index-sort-f.html | 344 + coverage/adjmat/index-sort-l.html | 344 + coverage/adjmat/index.html | 344 + coverage/amber.png | Bin 0 -> 141 bytes .../analysis/Accumulate.cpp.func-sort-c.html | 109 + coverage/analysis/Accumulate.cpp.func.html | 109 + coverage/analysis/Accumulate.cpp.gcov.html | 197 + .../analysis/Average.cpp.func-sort-c.html | 85 + coverage/analysis/Average.cpp.func.html | 85 + coverage/analysis/Average.cpp.gcov.html | 218 + .../analysis/Collect.cpp.func-sort-c.html | 109 + coverage/analysis/Collect.cpp.func.html | 109 + coverage/analysis/Collect.cpp.gcov.html | 211 + .../CollectFrames.cpp.func-sort-c.html | 89 + coverage/analysis/CollectFrames.cpp.func.html | 89 + coverage/analysis/CollectFrames.cpp.gcov.html | 219 + .../analysis/Committor.cpp.func-sort-c.html | 93 + coverage/analysis/Committor.cpp.func.html | 93 + coverage/analysis/Committor.cpp.gcov.html | 268 + .../analysis/CreateMask.cpp.func-sort-c.html | 101 + coverage/analysis/CreateMask.cpp.func.html | 101 + coverage/analysis/CreateMask.cpp.gcov.html | 203 + ...FarthestPointSampling.cpp.func-sort-c.html | 105 + .../FarthestPointSampling.cpp.func.html | 105 + .../FarthestPointSampling.cpp.gcov.html | 188 + .../GatherReplicas.cpp.func-sort-c.html | 97 + .../analysis/GatherReplicas.cpp.func.html | 97 + .../analysis/GatherReplicas.cpp.gcov.html | 191 + .../analysis/Histogram.cpp.func-sort-c.html | 85 + coverage/analysis/Histogram.cpp.func.html | 85 + coverage/analysis/Histogram.cpp.gcov.html | 340 + .../LandmarkSelection.cpp.func-sort-c.html | 85 + .../analysis/LandmarkSelection.cpp.func.html | 85 + .../analysis/LandmarkSelection.cpp.gcov.html | 236 + .../analysis/LogSumExp.cpp.func-sort-c.html | 85 + coverage/analysis/LogSumExp.cpp.func.html | 85 + coverage/analysis/LogSumExp.cpp.gcov.html | 153 + coverage/analysis/Wham.cpp.func-sort-c.html | 97 + coverage/analysis/Wham.cpp.func.html | 97 + coverage/analysis/Wham.cpp.gcov.html | 247 + .../WhamHistogram.cpp.func-sort-c.html | 85 + coverage/analysis/WhamHistogram.cpp.func.html | 85 + coverage/analysis/WhamHistogram.cpp.gcov.html | 211 + .../analysis/WhamWeights.cpp.func-sort-c.html | 85 + coverage/analysis/WhamWeights.cpp.func.html | 85 + coverage/analysis/WhamWeights.cpp.gcov.html | 187 + coverage/analysis/index-sort-f.html | 224 + coverage/analysis/index-sort-l.html | 224 + coverage/analysis/index.html | 224 + coverage/annfunc/ANN.cpp.func-sort-c.html | 97 + coverage/annfunc/ANN.cpp.func.html | 97 + coverage/annfunc/ANN.cpp.gcov.html | 474 + coverage/annfunc/index-sort-f.html | 94 + coverage/annfunc/index-sort-l.html | 94 + coverage/annfunc/index.html | 94 + coverage/bias/ABMD.cpp.func-sort-c.html | 89 + coverage/bias/ABMD.cpp.func.html | 89 + coverage/bias/ABMD.cpp.gcov.html | 263 + coverage/bias/Bias.cpp.func-sort-c.html | 89 + coverage/bias/Bias.cpp.func.html | 89 + coverage/bias/Bias.cpp.gcov.html | 170 + coverage/bias/Bias.h.func-sort-c.html | 85 + coverage/bias/Bias.h.func.html | 85 + coverage/bias/Bias.h.gcov.html | 160 + coverage/bias/BiasValue.cpp.func-sort-c.html | 89 + coverage/bias/BiasValue.cpp.func.html | 89 + coverage/bias/BiasValue.cpp.gcov.html | 194 + .../ExtendedLagrangian.cpp.func-sort-c.html | 93 + .../bias/ExtendedLagrangian.cpp.func.html | 93 + .../bias/ExtendedLagrangian.cpp.gcov.html | 339 + coverage/bias/External.cpp.func-sort-c.html | 89 + coverage/bias/External.cpp.func.html | 89 + coverage/bias/External.cpp.gcov.html | 257 + coverage/bias/LWalls.cpp.func-sort-c.html | 89 + coverage/bias/LWalls.cpp.func.html | 89 + coverage/bias/LWalls.cpp.gcov.html | 235 + coverage/bias/MaxEnt.cpp.func-sort-c.html | 117 + coverage/bias/MaxEnt.cpp.func.html | 117 + coverage/bias/MaxEnt.cpp.gcov.html | 561 + coverage/bias/MetaD.cpp.func-sort-c.html | 185 + coverage/bias/MetaD.cpp.func.html | 185 + coverage/bias/MetaD.cpp.gcov.html | 2381 ++ .../bias/MovingRestraint.cpp.func-sort-c.html | 89 + coverage/bias/MovingRestraint.cpp.func.html | 89 + coverage/bias/MovingRestraint.cpp.gcov.html | 357 + coverage/bias/PBMetaD.cpp.func-sort-c.html | 133 + coverage/bias/PBMetaD.cpp.func.html | 133 + coverage/bias/PBMetaD.cpp.gcov.html | 1391 + coverage/bias/Restraint.cpp.func-sort-c.html | 89 + coverage/bias/Restraint.cpp.func.html | 89 + coverage/bias/Restraint.cpp.gcov.html | 213 + .../RestraintShortcut.cpp.func-sort-c.html | 85 + coverage/bias/RestraintShortcut.cpp.func.html | 85 + coverage/bias/RestraintShortcut.cpp.gcov.html | 186 + .../bias/ReweightBase.cpp.func-sort-c.html | 89 + coverage/bias/ReweightBase.cpp.func.html | 89 + coverage/bias/ReweightBase.cpp.gcov.html | 130 + coverage/bias/ReweightBase.h.func-sort-c.html | 97 + coverage/bias/ReweightBase.h.func.html | 97 + coverage/bias/ReweightBase.h.gcov.html | 130 + .../bias/ReweightBias.cpp.func-sort-c.html | 89 + coverage/bias/ReweightBias.cpp.func.html | 89 + coverage/bias/ReweightBias.cpp.gcov.html | 175 + .../bias/ReweightMetad.cpp.func-sort-c.html | 89 + coverage/bias/ReweightMetad.cpp.func.html | 89 + coverage/bias/ReweightMetad.cpp.gcov.html | 172 + ...htTemperaturePressure.cpp.func-sort-c.html | 89 + .../ReweightTemperaturePressure.cpp.func.html | 89 + .../ReweightTemperaturePressure.cpp.gcov.html | 341 + coverage/bias/UWalls.cpp.func-sort-c.html | 89 + coverage/bias/UWalls.cpp.func.html | 89 + coverage/bias/UWalls.cpp.gcov.html | 234 + coverage/bias/Walls.cpp.func-sort-c.html | 85 + coverage/bias/Walls.cpp.func.html | 85 + coverage/bias/Walls.cpp.gcov.html | 196 + coverage/bias/index-sort-f.html | 284 + coverage/bias/index-sort-l.html | 284 + coverage/bias/index.html | 284 + .../cltools/Benchmark.cpp.func-sort-c.html | 181 + coverage/cltools/Benchmark.cpp.func.html | 181 + coverage/cltools/Benchmark.cpp.gcov.html | 881 + .../cltools/Completion.cpp.func-sort-c.html | 101 + coverage/cltools/Completion.cpp.func.html | 101 + coverage/cltools/Completion.cpp.gcov.html | 212 + coverage/cltools/Driver.cpp.func-sort-c.html | 121 + coverage/cltools/Driver.cpp.func.html | 121 + coverage/cltools/Driver.cpp.gcov.html | 1258 + .../cltools/DriverDouble.cpp.func-sort-c.html | 85 + coverage/cltools/DriverDouble.cpp.func.html | 85 + coverage/cltools/DriverDouble.cpp.gcov.html | 114 + .../cltools/DriverFloat.cpp.func-sort-c.html | 89 + coverage/cltools/DriverFloat.cpp.func.html | 89 + coverage/cltools/DriverFloat.cpp.gcov.html | 119 + .../cltools/GenExample.cpp.func-sort-c.html | 109 + coverage/cltools/GenExample.cpp.func.html | 109 + coverage/cltools/GenExample.cpp.gcov.html | 428 + coverage/cltools/GenJson.cpp.func-sort-c.html | 101 + coverage/cltools/GenJson.cpp.func.html | 101 + coverage/cltools/GenJson.cpp.gcov.html | 267 + .../cltools/GenTemplate.cpp.func-sort-c.html | 101 + coverage/cltools/GenTemplate.cpp.func.html | 101 + coverage/cltools/GenTemplate.cpp.gcov.html | 179 + coverage/cltools/Info.cpp.func-sort-c.html | 101 + coverage/cltools/Info.cpp.func.html | 101 + coverage/cltools/Info.cpp.gcov.html | 200 + coverage/cltools/Manual.cpp.func-sort-c.html | 101 + coverage/cltools/Manual.cpp.func.html | 101 + coverage/cltools/Manual.cpp.gcov.html | 178 + .../cltools/PdbRenumber.cpp.func-sort-c.html | 101 + coverage/cltools/PdbRenumber.cpp.func.html | 101 + coverage/cltools/PdbRenumber.cpp.gcov.html | 275 + .../cltools/ShowGraph.cpp.func-sort-c.html | 125 + coverage/cltools/ShowGraph.cpp.func.html | 125 + coverage/cltools/ShowGraph.cpp.gcov.html | 404 + .../cltools/SimpleMD.cpp.func-sort-c.html | 153 + coverage/cltools/SimpleMD.cpp.func.html | 153 + coverage/cltools/SimpleMD.cpp.gcov.html | 685 + .../cltools/SumHills.cpp.func-sort-c.html | 105 + coverage/cltools/SumHills.cpp.func.html | 105 + coverage/cltools/SumHills.cpp.gcov.html | 702 + .../SwitchingPlotter.cpp.func-sort-c.html | 101 + .../cltools/SwitchingPlotter.cpp.func.html | 101 + .../cltools/SwitchingPlotter.cpp.gcov.html | 269 + coverage/cltools/index-sort-f.html | 254 + coverage/cltools/index-sort-l.html | 254 + coverage/cltools/index.html | 254 + coverage/cltools/kT.cpp.func-sort-c.html | 101 + coverage/cltools/kT.cpp.func.html | 101 + coverage/cltools/kT.cpp.gcov.html | 164 + coverage/cltools/pesmd.cpp.func-sort-c.html | 101 + coverage/cltools/pesmd.cpp.func.html | 101 + coverage/cltools/pesmd.cpp.gcov.html | 389 + .../ClusterDiameter.cpp.func-sort-c.html | 85 + .../clusters/ClusterDiameter.cpp.func.html | 85 + .../clusters/ClusterDiameter.cpp.gcov.html | 175 + .../ClusterDistribution.cpp.func-sort-c.html | 109 + .../ClusterDistribution.cpp.func.html | 109 + .../ClusterDistribution.cpp.gcov.html | 261 + .../ClusterNatoms.cpp.func-sort-c.html | 85 + coverage/clusters/ClusterNatoms.cpp.func.html | 85 + coverage/clusters/ClusterNatoms.cpp.gcov.html | 140 + .../ClusterProperties.cpp.func-sort-c.html | 85 + .../clusters/ClusterProperties.cpp.func.html | 85 + .../clusters/ClusterProperties.cpp.gcov.html | 168 + .../ClusterWeights.cpp.func-sort-c.html | 97 + .../clusters/ClusterWeights.cpp.func.html | 97 + .../clusters/ClusterWeights.cpp.gcov.html | 188 + .../ClusterWithSurface.cpp.func-sort-c.html | 85 + .../clusters/ClusterWithSurface.cpp.func.html | 85 + .../clusters/ClusterWithSurface.cpp.gcov.html | 157 + .../ClusteringBase.cpp.func-sort-c.html | 97 + .../clusters/ClusteringBase.cpp.func.html | 97 + .../clusters/ClusteringBase.cpp.gcov.html | 168 + .../ClusteringBase.h.func-sort-c.html | 81 + coverage/clusters/ClusteringBase.h.func.html | 81 + coverage/clusters/ClusteringBase.h.gcov.html | 143 + .../DFSClustering.cpp.func-sort-c.html | 93 + coverage/clusters/DFSClustering.cpp.func.html | 93 + coverage/clusters/DFSClustering.cpp.gcov.html | 227 + .../OutputCluster.cpp.func-sort-c.html | 85 + coverage/clusters/OutputCluster.cpp.func.html | 85 + coverage/clusters/OutputCluster.cpp.gcov.html | 170 + coverage/clusters/index-sort-f.html | 184 + coverage/clusters/index-sort-l.html | 184 + coverage/clusters/index.html | 184 + coverage/colvar/Angle.cpp.func-sort-c.html | 101 + coverage/colvar/Angle.cpp.func.html | 101 + coverage/colvar/Angle.cpp.gcov.html | 271 + coverage/colvar/Cell.cpp.func-sort-c.html | 89 + coverage/colvar/Cell.cpp.func.html | 89 + coverage/colvar/Cell.cpp.gcov.html | 186 + .../colvar/ColvarShortcut.h.func-sort-c.html | 145 + coverage/colvar/ColvarShortcut.h.func.html | 145 + coverage/colvar/ColvarShortcut.h.gcov.html | 151 + .../colvar/ContactMap.cpp.func-sort-c.html | 93 + coverage/colvar/ContactMap.cpp.func.html | 93 + coverage/colvar/ContactMap.cpp.gcov.html | 404 + .../colvar/Coordination.cpp.func-sort-c.html | 89 + coverage/colvar/Coordination.cpp.func.html | 89 + coverage/colvar/Coordination.cpp.gcov.html | 231 + .../CoordinationBase.cpp.func-sort-c.html | 105 + .../colvar/CoordinationBase.cpp.func.html | 105 + .../colvar/CoordinationBase.cpp.gcov.html | 284 + coverage/colvar/DHEnergy.cpp.func-sort-c.html | 89 + coverage/colvar/DHEnergy.cpp.func.html | 89 + coverage/colvar/DHEnergy.cpp.gcov.html | 220 + coverage/colvar/DRMSD.cpp.func-sort-c.html | 85 + coverage/colvar/DRMSD.cpp.func.html | 85 + coverage/colvar/DRMSD.cpp.gcov.html | 347 + .../DihedralCorrelation.cpp.func-sort-c.html | 101 + .../colvar/DihedralCorrelation.cpp.func.html | 101 + .../colvar/DihedralCorrelation.cpp.gcov.html | 256 + coverage/colvar/Dimer.cpp.func-sort-c.html | 93 + coverage/colvar/Dimer.cpp.func.html | 93 + coverage/colvar/Dimer.cpp.gcov.html | 395 + coverage/colvar/Dipole.cpp.func-sort-c.html | 101 + coverage/colvar/Dipole.cpp.func.html | 101 + coverage/colvar/Dipole.cpp.gcov.html | 301 + coverage/colvar/Distance.cpp.func-sort-c.html | 101 + coverage/colvar/Distance.cpp.func.html | 101 + coverage/colvar/Distance.cpp.gcov.html | 385 + coverage/colvar/EEFSolv.cpp.func-sort-c.html | 105 + coverage/colvar/EEFSolv.cpp.func.html | 105 + coverage/colvar/EEFSolv.cpp.gcov.html | 1254 + coverage/colvar/ERMSD.cpp.func-sort-c.html | 89 + coverage/colvar/ERMSD.cpp.func.html | 89 + coverage/colvar/ERMSD.cpp.gcov.html | 291 + coverage/colvar/Energy.cpp.func-sort-c.html | 93 + coverage/colvar/Energy.cpp.func.html | 93 + coverage/colvar/Energy.cpp.gcov.html | 202 + coverage/colvar/ExtraCV.cpp.func-sort-c.html | 85 + coverage/colvar/ExtraCV.cpp.func.html | 85 + coverage/colvar/ExtraCV.cpp.gcov.html | 156 + coverage/colvar/Fake.cpp.func-sort-c.html | 89 + coverage/colvar/Fake.cpp.func.html | 89 + coverage/colvar/Fake.cpp.gcov.html | 200 + coverage/colvar/GHBFIX.cpp.func-sort-c.html | 89 + coverage/colvar/GHBFIX.cpp.func.html | 89 + coverage/colvar/GHBFIX.cpp.gcov.html | 294 + coverage/colvar/Gyration.cpp.func-sort-c.html | 89 + coverage/colvar/Gyration.cpp.func.html | 89 + coverage/colvar/Gyration.cpp.gcov.html | 447 + .../GyrationShortcut.cpp.func-sort-c.html | 85 + .../colvar/GyrationShortcut.cpp.func.html | 85 + .../colvar/GyrationShortcut.cpp.gcov.html | 259 + .../MultiColvarTemplate.h.func-sort-c.html | 361 + .../colvar/MultiColvarTemplate.h.func.html | 361 + .../colvar/MultiColvarTemplate.h.gcov.html | 284 + .../colvar/MultiRMSD.cpp.func-sort-c.html | 85 + coverage/colvar/MultiRMSD.cpp.func.html | 85 + coverage/colvar/MultiRMSD.cpp.gcov.html | 207 + coverage/colvar/PCARMSD.cpp.func-sort-c.html | 93 + coverage/colvar/PCARMSD.cpp.func.html | 93 + coverage/colvar/PCARMSD.cpp.gcov.html | 343 + coverage/colvar/PathMSD.cpp.func-sort-c.html | 85 + coverage/colvar/PathMSD.cpp.func.html | 85 + coverage/colvar/PathMSD.cpp.gcov.html | 206 + .../colvar/PathMSDBase.cpp.func-sort-c.html | 105 + coverage/colvar/PathMSDBase.cpp.func.html | 105 + coverage/colvar/PathMSDBase.cpp.gcov.html | 414 + .../colvar/PathMSDBase.h.func-sort-c.html | 73 + coverage/colvar/PathMSDBase.h.func.html | 73 + coverage/colvar/PathMSDBase.h.gcov.html | 178 + coverage/colvar/Plane.cpp.func-sort-c.html | 101 + coverage/colvar/Plane.cpp.func.html | 101 + coverage/colvar/Plane.cpp.gcov.html | 254 + coverage/colvar/Position.cpp.func-sort-c.html | 101 + coverage/colvar/Position.cpp.func.html | 101 + coverage/colvar/Position.cpp.gcov.html | 316 + .../ProjectionOnAxis.cpp.func-sort-c.html | 89 + .../colvar/ProjectionOnAxis.cpp.func.html | 89 + .../colvar/ProjectionOnAxis.cpp.gcov.html | 246 + .../colvar/PropertyMap.cpp.func-sort-c.html | 85 + coverage/colvar/PropertyMap.cpp.func.html | 85 + coverage/colvar/PropertyMap.cpp.gcov.html | 229 + .../colvar/Puckering.cpp.func-sort-c.html | 97 + coverage/colvar/Puckering.cpp.func.html | 97 + coverage/colvar/Puckering.cpp.gcov.html | 497 + coverage/colvar/RMSD.cpp.func-sort-c.html | 89 + coverage/colvar/RMSD.cpp.func.html | 89 + coverage/colvar/RMSD.cpp.gcov.html | 307 + .../colvar/RMSDShortcut.cpp.func-sort-c.html | 85 + coverage/colvar/RMSDShortcut.cpp.func.html | 85 + coverage/colvar/RMSDShortcut.cpp.gcov.html | 183 + .../colvar/RMSDVector.cpp.func-sort-c.html | 121 + coverage/colvar/RMSDVector.cpp.func.html | 121 + coverage/colvar/RMSDVector.cpp.gcov.html | 367 + .../SelectMassCharge.cpp.func-sort-c.html | 101 + .../colvar/SelectMassCharge.cpp.func.html | 101 + .../colvar/SelectMassCharge.cpp.gcov.html | 236 + coverage/colvar/Template.cpp.func-sort-c.html | 89 + coverage/colvar/Template.cpp.func.html | 89 + coverage/colvar/Template.cpp.gcov.html | 191 + coverage/colvar/Torsion.cpp.func-sort-c.html | 101 + coverage/colvar/Torsion.cpp.func.html | 101 + coverage/colvar/Torsion.cpp.gcov.html | 338 + coverage/colvar/Volume.cpp.func-sort-c.html | 89 + coverage/colvar/Volume.cpp.func.html | 89 + coverage/colvar/Volume.cpp.gcov.html | 162 + coverage/colvar/index-sort-f.html | 464 + coverage/colvar/index-sort-l.html | 464 + coverage/colvar/index.html | 464 + coverage/config/Config.inc.func-sort-c.html | 173 + coverage/config/Config.inc.func.html | 173 + coverage/config/Config.inc.gcov.html | 273 + .../config/ConfigInstall.inc.func-sort-c.html | 173 + coverage/config/ConfigInstall.inc.func.html | 173 + coverage/config/ConfigInstall.inc.gcov.html | 273 + coverage/config/index-sort-f.html | 104 + coverage/config/index-sort-l.html | 104 + coverage/config/index.html | 104 + .../ContourFindingBase.cpp.func-sort-c.html | 89 + .../contour/ContourFindingBase.cpp.func.html | 89 + .../contour/ContourFindingBase.cpp.gcov.html | 124 + .../ContourFindingBase.h.func-sort-c.html | 77 + .../contour/ContourFindingBase.h.func.html | 77 + .../contour/ContourFindingBase.h.gcov.html | 150 + .../DistanceFromContour.cpp.func-sort-c.html | 93 + .../contour/DistanceFromContour.cpp.func.html | 93 + .../contour/DistanceFromContour.cpp.gcov.html | 323 + ...stanceFromContourBase.cpp.func-sort-c.html | 105 + .../DistanceFromContourBase.cpp.func.html | 105 + .../DistanceFromContourBase.cpp.gcov.html | 222 + ...DistanceFromContourBase.h.func-sort-c.html | 81 + .../DistanceFromContourBase.h.func.html | 81 + .../DistanceFromContourBase.h.gcov.html | 156 + ...eFromSphericalContour.cpp.func-sort-c.html | 93 + ...DistanceFromSphericalContour.cpp.func.html | 93 + ...DistanceFromSphericalContour.cpp.gcov.html | 185 + .../contour/DumpContour.cpp.func-sort-c.html | 105 + coverage/contour/DumpContour.cpp.func.html | 105 + coverage/contour/DumpContour.cpp.gcov.html | 180 + .../contour/FindContour.cpp.func-sort-c.html | 109 + coverage/contour/FindContour.cpp.func.html | 109 + coverage/contour/FindContour.cpp.gcov.html | 264 + .../contour/FindContour.h.func-sort-c.html | 81 + coverage/contour/FindContour.h.func.html | 81 + coverage/contour/FindContour.h.gcov.html | 127 + .../FindContourSurface.cpp.func-sort-c.html | 109 + .../contour/FindContourSurface.cpp.func.html | 109 + .../contour/FindContourSurface.cpp.gcov.html | 315 + .../FindSphericalContour.cpp.func-sort-c.html | 109 + .../FindSphericalContour.cpp.func.html | 109 + .../FindSphericalContour.cpp.gcov.html | 279 + coverage/contour/index-sort-f.html | 194 + coverage/contour/index-sort-l.html | 194 + coverage/contour/index.html | 194 + coverage/core/Action.cpp.func-sort-c.html | 221 + coverage/core/Action.cpp.func.html | 221 + coverage/core/Action.cpp.gcov.html | 441 + coverage/core/Action.h.func-sort-c.html | 225 + coverage/core/Action.h.func.html | 225 + coverage/core/Action.h.gcov.html | 559 + .../core/ActionAnyorder.cpp.func-sort-c.html | 85 + coverage/core/ActionAnyorder.cpp.func.html | 85 + coverage/core/ActionAnyorder.cpp.gcov.html | 115 + .../core/ActionAnyorder.h.func-sort-c.html | 81 + coverage/core/ActionAnyorder.h.func.html | 81 + coverage/core/ActionAnyorder.h.gcov.html | 125 + .../core/ActionAtomistic.cpp.func-sort-c.html | 177 + coverage/core/ActionAtomistic.cpp.func.html | 177 + coverage/core/ActionAtomistic.cpp.gcov.html | 536 + .../core/ActionAtomistic.h.func-sort-c.html | 109 + coverage/core/ActionAtomistic.h.func.html | 109 + coverage/core/ActionAtomistic.h.gcov.html | 380 + .../ActionForInterface.cpp.func-sort-c.html | 89 + .../core/ActionForInterface.cpp.func.html | 89 + .../core/ActionForInterface.cpp.gcov.html | 126 + .../ActionForInterface.h.func-sort-c.html | 101 + coverage/core/ActionForInterface.h.func.html | 101 + coverage/core/ActionForInterface.h.gcov.html | 167 + .../core/ActionPilot.cpp.func-sort-c.html | 97 + coverage/core/ActionPilot.cpp.func.html | 97 + coverage/core/ActionPilot.cpp.gcov.html | 132 + coverage/core/ActionPilot.h.func-sort-c.html | 73 + coverage/core/ActionPilot.h.func.html | 73 + coverage/core/ActionPilot.h.gcov.html | 135 + .../core/ActionRegister.cpp.func-sort-c.html | 105 + coverage/core/ActionRegister.cpp.func.html | 105 + coverage/core/ActionRegister.cpp.gcov.html | 172 + .../core/ActionRegister.h.func-sort-c.html | 4681 +++ coverage/core/ActionRegister.h.func.html | 4681 +++ coverage/core/ActionRegister.h.gcov.html | 199 + coverage/core/ActionSet.cpp.func-sort-c.html | 89 + coverage/core/ActionSet.cpp.func.html | 89 + coverage/core/ActionSet.cpp.gcov.html | 129 + coverage/core/ActionSet.h.func-sort-c.html | 197 + coverage/core/ActionSet.h.func.html | 197 + coverage/core/ActionSet.h.gcov.html | 227 + .../core/ActionSetup.cpp.func-sort-c.html | 85 + coverage/core/ActionSetup.cpp.func.html | 85 + coverage/core/ActionSetup.cpp.gcov.html | 125 + coverage/core/ActionSetup.h.func-sort-c.html | 81 + coverage/core/ActionSetup.h.func.html | 81 + coverage/core/ActionSetup.h.gcov.html | 125 + .../core/ActionShortcut.cpp.func-sort-c.html | 113 + coverage/core/ActionShortcut.cpp.func.html | 113 + coverage/core/ActionShortcut.cpp.gcov.html | 239 + .../core/ActionShortcut.h.func-sort-c.html | 85 + coverage/core/ActionShortcut.h.func.html | 85 + coverage/core/ActionShortcut.h.gcov.html | 142 + .../core/ActionToGetData.cpp.func-sort-c.html | 101 + coverage/core/ActionToGetData.cpp.func.html | 101 + coverage/core/ActionToGetData.cpp.gcov.html | 161 + .../core/ActionToGetData.h.func-sort-c.html | 81 + coverage/core/ActionToGetData.h.func.html | 81 + coverage/core/ActionToGetData.h.gcov.html | 135 + .../core/ActionToPutData.cpp.func-sort-c.html | 141 + coverage/core/ActionToPutData.cpp.func.html | 141 + coverage/core/ActionToPutData.cpp.gcov.html | 260 + .../core/ActionToPutData.h.func-sort-c.html | 97 + coverage/core/ActionToPutData.h.func.html | 97 + coverage/core/ActionToPutData.h.gcov.html | 173 + .../ActionWithArguments.cpp.func-sort-c.html | 129 + .../core/ActionWithArguments.cpp.func.html | 129 + .../core/ActionWithArguments.cpp.gcov.html | 437 + .../ActionWithArguments.h.func-sort-c.html | 101 + coverage/core/ActionWithArguments.h.func.html | 101 + coverage/core/ActionWithArguments.h.gcov.html | 216 + .../core/ActionWithValue.cpp.func-sort-c.html | 205 + coverage/core/ActionWithValue.cpp.func.html | 205 + coverage/core/ActionWithValue.cpp.gcov.html | 410 + .../core/ActionWithValue.h.func-sort-c.html | 101 + coverage/core/ActionWithValue.h.func.html | 101 + coverage/core/ActionWithValue.h.gcov.html | 330 + .../ActionWithVector.cpp.func-sort-c.html | 289 + coverage/core/ActionWithVector.cpp.func.html | 289 + coverage/core/ActionWithVector.cpp.gcov.html | 848 + .../core/ActionWithVector.h.func-sort-c.html | 101 + coverage/core/ActionWithVector.h.func.html | 101 + coverage/core/ActionWithVector.h.gcov.html | 268 + ...ActionWithVirtualAtom.cpp.func-sort-c.html | 101 + .../core/ActionWithVirtualAtom.cpp.func.html | 101 + .../core/ActionWithVirtualAtom.cpp.gcov.html | 208 + .../ActionWithVirtualAtom.h.func-sort-c.html | 97 + .../core/ActionWithVirtualAtom.h.func.html | 97 + .../core/ActionWithVirtualAtom.h.gcov.html | 197 + coverage/core/CLTool.cpp.func-sort-c.html | 113 + coverage/core/CLTool.cpp.func.html | 113 + coverage/core/CLTool.cpp.gcov.html | 293 + coverage/core/CLTool.h.func-sort-c.html | 133 + coverage/core/CLTool.h.func.html | 133 + coverage/core/CLTool.h.gcov.html | 242 + coverage/core/CLToolMain.cpp.func-sort-c.html | 93 + coverage/core/CLToolMain.cpp.func.html | 93 + coverage/core/CLToolMain.cpp.gcov.html | 364 + .../core/CLToolRegister.cpp.func-sort-c.html | 101 + coverage/core/CLToolRegister.cpp.func.html | 101 + coverage/core/CLToolRegister.cpp.gcov.html | 165 + .../core/CLToolRegister.h.func-sort-c.html | 73 + coverage/core/CLToolRegister.h.func.html | 73 + coverage/core/CLToolRegister.h.gcov.html | 185 + coverage/core/Colvar.cpp.func-sort-c.html | 101 + coverage/core/Colvar.cpp.func.html | 101 + coverage/core/Colvar.cpp.gcov.html | 150 + coverage/core/Colvar.h.func-sort-c.html | 89 + coverage/core/Colvar.h.func.html | 89 + coverage/core/Colvar.h.gcov.html | 194 + .../DataPassingObject.cpp.func-sort-c.html | 189 + coverage/core/DataPassingObject.cpp.func.html | 189 + coverage/core/DataPassingObject.cpp.gcov.html | 271 + .../core/DataPassingObject.h.func-sort-c.html | 73 + coverage/core/DataPassingObject.h.func.html | 73 + coverage/core/DataPassingObject.h.gcov.html | 163 + .../DataPassingTools.cpp.func-sort-c.html | 105 + coverage/core/DataPassingTools.cpp.func.html | 105 + coverage/core/DataPassingTools.cpp.gcov.html | 149 + .../core/DataPassingTools.h.func-sort-c.html | 81 + coverage/core/DataPassingTools.h.func.html | 81 + coverage/core/DataPassingTools.h.gcov.html | 131 + .../DomainDecomposition.cpp.func-sort-c.html | 205 + .../core/DomainDecomposition.cpp.func.html | 205 + .../core/DomainDecomposition.cpp.gcov.html | 577 + .../DomainDecomposition.h.func-sort-c.html | 85 + coverage/core/DomainDecomposition.h.func.html | 85 + coverage/core/DomainDecomposition.h.gcov.html | 191 + .../ExchangePatterns.cpp.func-sort-c.html | 101 + coverage/core/ExchangePatterns.cpp.func.html | 101 + coverage/core/ExchangePatterns.cpp.gcov.html | 149 + .../core/FlexibleBin.cpp.func-sort-c.html | 101 + coverage/core/FlexibleBin.cpp.func.html | 101 + coverage/core/FlexibleBin.cpp.gcov.html | 413 + coverage/core/GREX.cpp.func-sort-c.html | 97 + coverage/core/GREX.cpp.func.html | 97 + coverage/core/GREX.cpp.gcov.html | 292 + .../core/GenericMolInfo.cpp.func-sort-c.html | 145 + coverage/core/GenericMolInfo.cpp.func.html | 145 + coverage/core/GenericMolInfo.cpp.gcov.html | 445 + .../core/GenericMolInfo.h.func-sort-c.html | 81 + coverage/core/GenericMolInfo.h.func.html | 81 + coverage/core/GenericMolInfo.h.gcov.html | 163 + coverage/core/Group.cpp.func-sort-c.html | 89 + coverage/core/Group.cpp.func.html | 89 + coverage/core/Group.cpp.gcov.html | 306 + coverage/core/Group.h.func-sort-c.html | 81 + coverage/core/Group.h.func.html | 81 + coverage/core/Group.h.gcov.html | 118 + coverage/core/PbcAction.cpp.func-sort-c.html | 97 + coverage/core/PbcAction.cpp.func.html | 97 + coverage/core/PbcAction.cpp.gcov.html | 157 + coverage/core/PbcAction.h.func-sort-c.html | 77 + coverage/core/PbcAction.h.func.html | 77 + coverage/core/PbcAction.h.gcov.html | 136 + coverage/core/PlumedMain.cpp.func-sort-c.html | 337 + coverage/core/PlumedMain.cpp.func.html | 337 + coverage/core/PlumedMain.cpp.gcov.html | 1577 + coverage/core/PlumedMain.h.func-sort-c.html | 73 + coverage/core/PlumedMain.h.func.html | 73 + coverage/core/PlumedMain.h.gcov.html | 690 + ...PlumedMainInitializer.cpp.func-sort-c.html | 137 + .../core/PlumedMainInitializer.cpp.func.html | 137 + .../core/PlumedMainInitializer.cpp.gcov.html | 567 + .../core/RegisterBase.cpp.func-sort-c.html | 137 + coverage/core/RegisterBase.cpp.func.html | 137 + coverage/core/RegisterBase.cpp.gcov.html | 223 + coverage/core/RegisterBase.h.func-sort-c.html | 161 + coverage/core/RegisterBase.h.func.html | 161 + coverage/core/RegisterBase.h.gcov.html | 369 + coverage/core/TargetDist.cpp.func-sort-c.html | 85 + coverage/core/TargetDist.cpp.func.html | 85 + coverage/core/TargetDist.cpp.gcov.html | 148 + coverage/core/Value.cpp.func-sort-c.html | 217 + coverage/core/Value.cpp.func.html | 217 + coverage/core/Value.cpp.gcov.html | 483 + coverage/core/Value.h.func-sort-c.html | 121 + coverage/core/Value.h.func.html | 121 + coverage/core/Value.h.gcov.html | 621 + coverage/core/WithCmd.h.func-sort-c.html | 97 + coverage/core/WithCmd.h.func.html | 97 + coverage/core/WithCmd.h.gcov.html | 144 + coverage/core/index-sort-f.html | 694 + coverage/core/index-sort-l.html | 694 + coverage/core/index.html | 694 + .../BopsShortcut.cpp.func-sort-c.html | 85 + .../crystdistrib/BopsShortcut.cpp.func.html | 85 + .../crystdistrib/BopsShortcut.cpp.gcov.html | 233 + .../DopsShortcut.cpp.func-sort-c.html | 85 + .../crystdistrib/DopsShortcut.cpp.func.html | 85 + .../crystdistrib/DopsShortcut.cpp.gcov.html | 189 + .../Quaternion.cpp.func-sort-c.html | 101 + .../crystdistrib/Quaternion.cpp.func.html | 101 + .../crystdistrib/Quaternion.cpp.gcov.html | 471 + ...nionBondProductMatrix.cpp.func-sort-c.html | 105 + .../QuaternionBondProductMatrix.cpp.func.html | 105 + .../QuaternionBondProductMatrix.cpp.gcov.html | 461 + ...aternionProductMatrix.cpp.func-sort-c.html | 105 + .../QuaternionProductMatrix.cpp.func.html | 105 + .../QuaternionProductMatrix.cpp.gcov.html | 274 + .../RopsShortcut.cpp.func-sort-c.html | 85 + .../crystdistrib/RopsShortcut.cpp.func.html | 85 + .../crystdistrib/RopsShortcut.cpp.gcov.html | 223 + coverage/crystdistrib/index-sort-f.html | 144 + coverage/crystdistrib/index-sort-l.html | 144 + coverage/crystdistrib/index.html | 144 + .../dimred/ArrangePoints.cpp.func-sort-c.html | 117 + coverage/dimred/ArrangePoints.cpp.func.html | 117 + coverage/dimred/ArrangePoints.cpp.gcov.html | 407 + ...ltiDimensionalScaling.cpp.func-sort-c.html | 85 + ...sicalMultiDimensionalScaling.cpp.func.html | 85 + ...sicalMultiDimensionalScaling.cpp.gcov.html | 312 + coverage/dimred/PCA.cpp.func-sort-c.html | 85 + coverage/dimred/PCA.cpp.func.html | 85 + coverage/dimred/PCA.cpp.gcov.html | 260 + .../dimred/ProjectPoints.cpp.func-sort-c.html | 113 + coverage/dimred/ProjectPoints.cpp.func.html | 113 + coverage/dimred/ProjectPoints.cpp.gcov.html | 260 + coverage/dimred/SMACOF.cpp.func-sort-c.html | 85 + coverage/dimred/SMACOF.cpp.func.html | 85 + coverage/dimred/SMACOF.cpp.gcov.html | 187 + coverage/dimred/SMACOF.h.func-sort-c.html | 77 + coverage/dimred/SMACOF.h.func.html | 77 + coverage/dimred/SMACOF.h.gcov.html | 132 + .../dimred/SketchMap.cpp.func-sort-c.html | 85 + coverage/dimred/SketchMap.cpp.func.html | 85 + coverage/dimred/SketchMap.cpp.gcov.html | 216 + .../SketchMapProjection.cpp.func-sort-c.html | 85 + .../dimred/SketchMapProjection.cpp.func.html | 85 + .../dimred/SketchMapProjection.cpp.gcov.html | 163 + coverage/dimred/index-sort-f.html | 164 + coverage/dimred/index-sort-l.html | 164 + coverage/dimred/index.html | 164 + coverage/drr/DRR.cpp.func-sort-c.html | 173 + coverage/drr/DRR.cpp.func.html | 173 + coverage/drr/DRR.cpp.gcov.html | 635 + coverage/drr/DRR.h.func-sort-c.html | 129 + coverage/drr/DRR.h.func.html | 129 + coverage/drr/DRR.h.gcov.html | 435 + ...cReferenceRestraining.cpp.func-sort-c.html | 109 + .../DynamicReferenceRestraining.cpp.func.html | 109 + .../DynamicReferenceRestraining.cpp.gcov.html | 969 + .../drr/colvar_UIestimator.h.func-sort-c.html | 209 + coverage/drr/colvar_UIestimator.h.func.html | 209 + coverage/drr/colvar_UIestimator.h.gcov.html | 932 + coverage/drr/drrtool.cpp.func-sort-c.html | 121 + coverage/drr/drrtool.cpp.func.html | 121 + coverage/drr/drrtool.cpp.gcov.html | 345 + coverage/drr/index-sort-f.html | 134 + coverage/drr/index-sort-l.html | 134 + coverage/drr/index.html | 134 + coverage/eds/EDS.cpp.func-sort-c.html | 153 + coverage/eds/EDS.cpp.func.html | 153 + coverage/eds/EDS.cpp.gcov.html | 1251 + coverage/eds/index-sort-f.html | 94 + coverage/eds/index-sort-l.html | 94 + coverage/eds/index.html | 94 + coverage/emerald.png | Bin 0 -> 141 bytes ...EnvironmentSimilarity.cpp.func-sort-c.html | 89 + .../EnvironmentSimilarity.cpp.func.html | 89 + .../EnvironmentSimilarity.cpp.gcov.html | 524 + coverage/envsim/index-sort-f.html | 94 + coverage/envsim/index-sort-l.html | 94 + coverage/envsim/index.html | 94 + coverage/fisst/FISST.cpp.func-sort-c.html | 149 + coverage/fisst/FISST.cpp.func.html | 149 + coverage/fisst/FISST.cpp.gcov.html | 736 + coverage/fisst/index-sort-f.html | 104 + coverage/fisst/index-sort-l.html | 104 + coverage/fisst/index.html | 104 + .../legendre_rule_fast.cpp.func-sort-c.html | 101 + .../fisst/legendre_rule_fast.cpp.func.html | 101 + .../fisst/legendre_rule_fast.cpp.gcov.html | 642 + .../FourierTransform.cpp.func-sort-c.html | 109 + .../fourier/FourierTransform.cpp.func.html | 109 + .../fourier/FourierTransform.cpp.gcov.html | 333 + coverage/fourier/index-sort-f.html | 94 + coverage/fourier/index-sort-l.html | 94 + coverage/fourier/index.html | 94 + coverage/function/Bessel.cpp.func-sort-c.html | 97 + coverage/function/Bessel.cpp.func.html | 97 + coverage/function/Bessel.cpp.gcov.html | 272 + .../function/Between.cpp.func-sort-c.html | 85 + coverage/function/Between.cpp.func.html | 85 + coverage/function/Between.cpp.gcov.html | 173 + coverage/function/Between.h.func-sort-c.html | 77 + coverage/function/Between.h.func.html | 77 + coverage/function/Between.h.gcov.html | 119 + .../function/Combine.cpp.func-sort-c.html | 85 + coverage/function/Combine.cpp.func.html | 85 + coverage/function/Combine.cpp.gcov.html | 225 + coverage/function/Combine.h.func-sort-c.html | 73 + coverage/function/Combine.h.func.html | 73 + coverage/function/Combine.h.gcov.html | 121 + coverage/function/Custom.cpp.func-sort-c.html | 97 + coverage/function/Custom.cpp.func.html | 97 + coverage/function/Custom.cpp.gcov.html | 421 + .../function/Ensemble.cpp.func-sort-c.html | 89 + coverage/function/Ensemble.cpp.func.html | 89 + coverage/function/Ensemble.cpp.gcov.html | 340 + .../FuncPathGeneral.cpp.func-sort-c.html | 97 + .../function/FuncPathGeneral.cpp.func.html | 97 + .../function/FuncPathGeneral.cpp.gcov.html | 418 + .../function/FuncPathMSD.cpp.func-sort-c.html | 93 + coverage/function/FuncPathMSD.cpp.func.html | 93 + coverage/function/FuncPathMSD.cpp.gcov.html | 445 + .../FuncSumHills.cpp.func-sort-c.html | 121 + coverage/function/FuncSumHills.cpp.func.html | 121 + coverage/function/FuncSumHills.cpp.gcov.html | 715 + .../function/Function.cpp.func-sort-c.html | 97 + coverage/function/Function.cpp.func.html | 97 + coverage/function/Function.cpp.gcov.html | 139 + coverage/function/Function.h.func-sort-c.html | 85 + coverage/function/Function.h.func.html | 85 + coverage/function/Function.h.gcov.html | 160 + .../FunctionOfScalar.h.func-sort-c.html | 353 + .../function/FunctionOfScalar.h.func.html | 353 + .../function/FunctionOfScalar.h.gcov.html | 190 + .../FunctionOfVector.h.func-sort-c.html | 709 + .../function/FunctionOfVector.h.func.html | 709 + .../function/FunctionOfVector.h.gcov.html | 420 + .../FunctionShortcut.h.func-sort-c.html | 257 + .../function/FunctionShortcut.h.func.html | 257 + .../function/FunctionShortcut.h.gcov.html | 168 + .../FunctionTemplateBase.h.func-sort-c.html | 145 + .../function/FunctionTemplateBase.h.func.html | 145 + .../function/FunctionTemplateBase.h.gcov.html | 212 + .../function/Highest.cpp.func-sort-c.html | 93 + coverage/function/Highest.cpp.func.html | 93 + coverage/function/Highest.cpp.gcov.html | 205 + .../function/LessThan.cpp.func-sort-c.html | 85 + coverage/function/LessThan.cpp.func.html | 85 + coverage/function/LessThan.cpp.gcov.html | 174 + coverage/function/LessThan.h.func-sort-c.html | 77 + coverage/function/LessThan.h.func.html | 77 + coverage/function/LessThan.h.gcov.html | 120 + .../LocalEnsemble.cpp.func-sort-c.html | 89 + coverage/function/LocalEnsemble.cpp.func.html | 89 + coverage/function/LocalEnsemble.cpp.gcov.html | 228 + .../function/Moments.cpp.func-sort-c.html | 101 + coverage/function/Moments.cpp.func.html | 101 + coverage/function/Moments.cpp.gcov.html | 233 + .../function/MoreThan.cpp.func-sort-c.html | 85 + coverage/function/MoreThan.cpp.func.html | 85 + coverage/function/MoreThan.cpp.gcov.html | 174 + coverage/function/MoreThan.h.func-sort-c.html | 77 + coverage/function/MoreThan.h.func.html | 77 + coverage/function/MoreThan.h.gcov.html | 120 + .../function/Piecewise.cpp.func-sort-c.html | 89 + coverage/function/Piecewise.cpp.func.html | 89 + coverage/function/Piecewise.cpp.gcov.html | 223 + .../function/Product.cpp.func-sort-c.html | 85 + coverage/function/Product.cpp.func.html | 85 + coverage/function/Product.cpp.gcov.html | 140 + coverage/function/Sort.cpp.func-sort-c.html | 101 + coverage/function/Sort.cpp.func.html | 101 + coverage/function/Sort.cpp.gcov.html | 213 + coverage/function/Stats.cpp.func-sort-c.html | 89 + coverage/function/Stats.cpp.func.html | 89 + coverage/function/Stats.cpp.gcov.html | 316 + coverage/function/Sum.cpp.func-sort-c.html | 93 + coverage/function/Sum.cpp.func.html | 93 + coverage/function/Sum.cpp.gcov.html | 195 + coverage/function/Sum.h.func-sort-c.html | 73 + coverage/function/Sum.h.func.html | 73 + coverage/function/Sum.h.gcov.html | 120 + coverage/function/index-sort-f.html | 374 + coverage/function/index-sort-l.html | 374 + coverage/function/index.html | 374 + coverage/funnel/FPS.cpp.func-sort-c.html | 89 + coverage/funnel/FPS.cpp.func.html | 89 + coverage/funnel/FPS.cpp.gcov.html | 396 + coverage/funnel/Funnel.cpp.func-sort-c.html | 93 + coverage/funnel/Funnel.cpp.func.html | 93 + coverage/funnel/Funnel.cpp.gcov.html | 529 + coverage/funnel/index-sort-f.html | 104 + coverage/funnel/index-sort-l.html | 104 + coverage/funnel/index.html | 104 + coverage/gcov.css | 519 + .../generic/Constant.cpp.func-sort-c.html | 101 + coverage/generic/Constant.cpp.func.html | 101 + coverage/generic/Constant.cpp.gcov.html | 229 + coverage/generic/Debug.cpp.func-sort-c.html | 93 + coverage/generic/Debug.cpp.func.html | 93 + coverage/generic/Debug.cpp.gcov.html | 217 + .../generic/DumpAtoms.cpp.func-sort-c.html | 125 + coverage/generic/DumpAtoms.cpp.func.html | 125 + coverage/generic/DumpAtoms.cpp.gcov.html | 439 + .../DumpDerivatives.cpp.func-sort-c.html | 109 + .../generic/DumpDerivatives.cpp.func.html | 109 + .../generic/DumpDerivatives.cpp.gcov.html | 212 + .../generic/DumpForces.cpp.func-sort-c.html | 109 + coverage/generic/DumpForces.cpp.func.html | 109 + coverage/generic/DumpForces.cpp.gcov.html | 196 + .../DumpMassCharge.cpp.func-sort-c.html | 117 + coverage/generic/DumpMassCharge.cpp.func.html | 117 + coverage/generic/DumpMassCharge.cpp.gcov.html | 264 + coverage/generic/DumpPDB.cpp.func-sort-c.html | 105 + coverage/generic/DumpPDB.cpp.func.html | 105 + coverage/generic/DumpPDB.cpp.gcov.html | 262 + .../DumpProjections.cpp.func-sort-c.html | 113 + .../generic/DumpProjections.cpp.func.html | 113 + .../generic/DumpProjections.cpp.gcov.html | 197 + .../generic/DumpVector.cpp.func-sort-c.html | 109 + coverage/generic/DumpVector.cpp.func.html | 109 + coverage/generic/DumpVector.cpp.gcov.html | 210 + .../EffectiveEnergyDrift.cpp.func-sort-c.html | 109 + .../EffectiveEnergyDrift.cpp.func.html | 109 + .../EffectiveEnergyDrift.cpp.gcov.html | 448 + .../generic/EndPlumed.cpp.func-sort-c.html | 89 + coverage/generic/EndPlumed.cpp.func.html | 89 + coverage/generic/EndPlumed.cpp.gcov.html | 157 + .../FitToTemplate.cpp.func-sort-c.html | 101 + coverage/generic/FitToTemplate.cpp.func.html | 101 + coverage/generic/FitToTemplate.cpp.gcov.html | 461 + coverage/generic/Flush.cpp.func-sort-c.html | 93 + coverage/generic/Flush.cpp.func.html | 93 + coverage/generic/Flush.cpp.gcov.html | 168 + coverage/generic/Include.cpp.func-sort-c.html | 93 + coverage/generic/Include.cpp.func.html | 93 + coverage/generic/Include.cpp.gcov.html | 256 + coverage/generic/Ones.cpp.func-sort-c.html | 85 + coverage/generic/Ones.cpp.func.html | 85 + coverage/generic/Ones.cpp.gcov.html | 138 + .../generic/PDB2Constant.cpp.func-sort-c.html | 85 + coverage/generic/PDB2Constant.cpp.func.html | 85 + coverage/generic/PDB2Constant.cpp.gcov.html | 196 + coverage/generic/Plumed.cpp.func-sort-c.html | 121 + coverage/generic/Plumed.cpp.func.html | 121 + coverage/generic/Plumed.cpp.gcov.html | 494 + coverage/generic/Print.cpp.func-sort-c.html | 117 + coverage/generic/Print.cpp.func.html | 117 + coverage/generic/Print.cpp.gcov.html | 264 + .../generic/PrintNDX.cpp.func-sort-c.html | 125 + coverage/generic/PrintNDX.cpp.func.html | 125 + coverage/generic/PrintNDX.cpp.gcov.html | 222 + .../RandomExchanges.cpp.func-sort-c.html | 89 + .../generic/RandomExchanges.cpp.func.html | 89 + .../generic/RandomExchanges.cpp.gcov.html | 179 + coverage/generic/Read.cpp.func-sort-c.html | 117 + coverage/generic/Read.cpp.func.html | 117 + coverage/generic/Read.cpp.gcov.html | 332 + .../generic/ResetCell.cpp.func-sort-c.html | 93 + coverage/generic/ResetCell.cpp.func.html | 93 + coverage/generic/ResetCell.cpp.gcov.html | 284 + coverage/generic/Time.cpp.func-sort-c.html | 97 + coverage/generic/Time.cpp.func.html | 97 + coverage/generic/Time.cpp.gcov.html | 156 + .../generic/UpdateIf.cpp.func-sort-c.html | 113 + coverage/generic/UpdateIf.cpp.func.html | 113 + coverage/generic/UpdateIf.cpp.gcov.html | 235 + .../WholeMolecules.cpp.func-sort-c.html | 97 + coverage/generic/WholeMolecules.cpp.func.html | 97 + coverage/generic/WholeMolecules.cpp.gcov.html | 346 + .../generic/WrapAround.cpp.func-sort-c.html | 97 + coverage/generic/WrapAround.cpp.func.html | 97 + coverage/generic/WrapAround.cpp.gcov.html | 334 + coverage/generic/index-sort-f.html | 344 + coverage/generic/index-sort-l.html | 344 + coverage/generic/index.html | 344 + coverage/glass.png | Bin 0 -> 167 bytes .../ActionWithGrid.cpp.func-sort-c.html | 93 + .../gridtools/ActionWithGrid.cpp.func.html | 93 + .../gridtools/ActionWithGrid.cpp.gcov.html | 132 + .../ConvertToFES.cpp.func-sort-c.html | 85 + coverage/gridtools/ConvertToFES.cpp.func.html | 85 + coverage/gridtools/ConvertToFES.cpp.gcov.html | 175 + .../gridtools/DumpGrid.cpp.func-sort-c.html | 105 + coverage/gridtools/DumpGrid.cpp.func.html | 105 + coverage/gridtools/DumpGrid.cpp.gcov.html | 426 + ...valuateFunctionOnGrid.cpp.func-sort-c.html | 85 + .../EvaluateFunctionOnGrid.cpp.func.html | 85 + .../EvaluateFunctionOnGrid.cpp.gcov.html | 186 + .../EvaluateGridFunction.cpp.func-sort-c.html | 97 + .../EvaluateGridFunction.cpp.func.html | 97 + .../EvaluateGridFunction.cpp.gcov.html | 228 + .../EvaluateGridFunction.h.func-sort-c.html | 77 + .../EvaluateGridFunction.h.func.html | 77 + .../EvaluateGridFunction.h.gcov.html | 168 + .../FindGridOptimum.cpp.func-sort-c.html | 113 + .../gridtools/FindGridOptimum.cpp.func.html | 113 + .../gridtools/FindGridOptimum.cpp.gcov.html | 228 + .../FunctionOfGrid.h.func-sort-c.html | 153 + coverage/gridtools/FunctionOfGrid.h.func.html | 153 + coverage/gridtools/FunctionOfGrid.h.gcov.html | 305 + .../gridtools/Gradient.cpp.func-sort-c.html | 85 + coverage/gridtools/Gradient.cpp.func.html | 85 + coverage/gridtools/Gradient.cpp.gcov.html | 182 + ...GridCoordinatesObject.cpp.func-sort-c.html | 153 + .../GridCoordinatesObject.cpp.func.html | 153 + .../GridCoordinatesObject.cpp.gcov.html | 414 + .../GridCoordinatesObject.h.func-sort-c.html | 81 + .../GridCoordinatesObject.h.func.html | 81 + .../GridCoordinatesObject.h.gcov.html | 244 + .../gridtools/GridSearch.h.func-sort-c.html | 85 + coverage/gridtools/GridSearch.h.func.html | 85 + coverage/gridtools/GridSearch.h.gcov.html | 194 + .../InterpolateGrid.cpp.func-sort-c.html | 113 + .../gridtools/InterpolateGrid.cpp.func.html | 113 + .../gridtools/InterpolateGrid.cpp.gcov.html | 259 + .../Interpolator.cpp.func-sort-c.html | 77 + coverage/gridtools/Interpolator.cpp.func.html | 77 + coverage/gridtools/Interpolator.cpp.gcov.html | 152 + .../gridtools/Interpolator.h.func-sort-c.html | 73 + coverage/gridtools/Interpolator.h.func.html | 73 + coverage/gridtools/Interpolator.h.gcov.html | 121 + coverage/gridtools/KDE.cpp.func-sort-c.html | 149 + coverage/gridtools/KDE.cpp.func.html | 149 + coverage/gridtools/KDE.cpp.gcov.html | 652 + .../gridtools/KLEntropy.cpp.func-sort-c.html | 85 + coverage/gridtools/KLEntropy.cpp.func.html | 85 + coverage/gridtools/KLEntropy.cpp.gcov.html | 146 + .../MultiColvarDensity.cpp.func-sort-c.html | 85 + .../MultiColvarDensity.cpp.func.html | 85 + .../MultiColvarDensity.cpp.gcov.html | 234 + .../PairEntropies.cpp.func-sort-c.html | 85 + .../gridtools/PairEntropies.cpp.func.html | 85 + .../gridtools/PairEntropies.cpp.gcov.html | 160 + .../PairEntropy.cpp.func-sort-c.html | 85 + coverage/gridtools/PairEntropy.cpp.func.html | 85 + coverage/gridtools/PairEntropy.cpp.gcov.html | 166 + coverage/gridtools/RDF.cpp.func-sort-c.html | 89 + coverage/gridtools/RDF.cpp.func.html | 89 + coverage/gridtools/RDF.cpp.gcov.html | 208 + .../ReadGridInSetup.cpp.func-sort-c.html | 109 + .../gridtools/ReadGridInSetup.cpp.func.html | 109 + .../gridtools/ReadGridInSetup.cpp.gcov.html | 360 + coverage/gridtools/index-sort-f.html | 304 + coverage/gridtools/index-sort-l.html | 304 + coverage/gridtools/index.html | 304 + coverage/index-sort-f.html | 534 + coverage/index-sort-l.html | 534 + coverage/index.html | 534 + .../isdb/CS2Backbone.cpp.func-sort-c.html | 165 + coverage/isdb/CS2Backbone.cpp.func.html | 165 + coverage/isdb/CS2Backbone.cpp.gcov.html | 1921 + coverage/isdb/Caliber.cpp.func-sort-c.html | 105 + coverage/isdb/Caliber.cpp.func.html | 105 + coverage/isdb/Caliber.cpp.gcov.html | 424 + coverage/isdb/EMMI.cpp.func-sort-c.html | 229 + coverage/isdb/EMMI.cpp.func.html | 229 + coverage/isdb/EMMI.cpp.gcov.html | 1824 + coverage/isdb/EMMIVox.cpp.func-sort-c.html | 177 + coverage/isdb/EMMIVox.cpp.func.html | 177 + coverage/isdb/EMMIVox.cpp.gcov.html | 1655 + .../isdb/FretEfficiency.cpp.func-sort-c.html | 89 + coverage/isdb/FretEfficiency.cpp.func.html | 89 + coverage/isdb/FretEfficiency.cpp.gcov.html | 232 + coverage/isdb/Jcoupling.cpp.func-sort-c.html | 93 + coverage/isdb/Jcoupling.cpp.func.html | 93 + coverage/isdb/Jcoupling.cpp.gcov.html | 471 + .../isdb/Metainference.cpp.func-sort-c.html | 181 + coverage/isdb/Metainference.cpp.func.html | 181 + coverage/isdb/Metainference.cpp.gcov.html | 1879 + .../MetainferenceBase.cpp.func-sort-c.html | 185 + coverage/isdb/MetainferenceBase.cpp.func.html | 185 + coverage/isdb/MetainferenceBase.cpp.gcov.html | 1637 + .../isdb/MetainferenceBase.h.func-sort-c.html | 117 + coverage/isdb/MetainferenceBase.h.func.html | 117 + coverage/isdb/MetainferenceBase.h.gcov.html | 463 + coverage/isdb/NOE.cpp.func-sort-c.html | 93 + coverage/isdb/NOE.cpp.func.html | 93 + coverage/isdb/NOE.cpp.gcov.html | 351 + coverage/isdb/PRE.cpp.func-sort-c.html | 93 + coverage/isdb/PRE.cpp.func.html | 93 + coverage/isdb/PRE.cpp.gcov.html | 417 + coverage/isdb/RDC.cpp.func-sort-c.html | 97 + coverage/isdb/RDC.cpp.func.html | 97 + coverage/isdb/RDC.cpp.gcov.html | 598 + coverage/isdb/Rescale.cpp.func-sort-c.html | 121 + coverage/isdb/Rescale.cpp.func.html | 121 + coverage/isdb/Rescale.cpp.gcov.html | 590 + coverage/isdb/SAXS.cpp.func-sort-c.html | 165 + coverage/isdb/SAXS.cpp.func.html | 165 + coverage/isdb/SAXS.cpp.gcov.html | 7939 ++++ coverage/isdb/Select.cpp.func-sort-c.html | 89 + coverage/isdb/Select.cpp.func.html | 89 + coverage/isdb/Select.cpp.gcov.html | 193 + coverage/isdb/Selector.cpp.func-sort-c.html | 89 + coverage/isdb/Selector.cpp.func.html | 89 + coverage/isdb/Selector.cpp.gcov.html | 169 + coverage/isdb/Shadow.cpp.func-sort-c.html | 93 + coverage/isdb/Shadow.cpp.func.html | 93 + coverage/isdb/Shadow.cpp.gcov.html | 301 + coverage/isdb/index-sort-f.html | 254 + coverage/isdb/index-sort-l.html | 254 + coverage/isdb/index.html | 254 + coverage/logmfd/LogMFD.cpp.func-sort-c.html | 125 + coverage/logmfd/LogMFD.cpp.func.html | 125 + coverage/logmfd/LogMFD.cpp.gcov.html | 1317 + coverage/logmfd/index-sort-f.html | 94 + coverage/logmfd/index-sort-l.html | 94 + coverage/logmfd/index.html | 94 + coverage/main/index-sort-f.html | 94 + coverage/main/index-sort-l.html | 94 + coverage/main/index.html | 94 + coverage/main/main.cpp.func-sort-c.html | 77 + coverage/main/main.cpp.func.html | 77 + coverage/main/main.cpp.gcov.html | 148 + .../mapping/AdaptivePath.cpp.func-sort-c.html | 85 + coverage/mapping/AdaptivePath.cpp.func.html | 85 + coverage/mapping/AdaptivePath.cpp.gcov.html | 244 + .../GeometricPath.cpp.func-sort-c.html | 97 + coverage/mapping/GeometricPath.cpp.func.html | 97 + coverage/mapping/GeometricPath.cpp.gcov.html | 216 + ...GeometricPathShortcut.cpp.func-sort-c.html | 85 + .../GeometricPathShortcut.cpp.func.html | 85 + .../GeometricPathShortcut.cpp.gcov.html | 157 + coverage/mapping/PCAVars.cpp.func-sort-c.html | 85 + coverage/mapping/PCAVars.cpp.func.html | 85 + coverage/mapping/PCAVars.cpp.gcov.html | 377 + coverage/mapping/Path.cpp.func-sort-c.html | 101 + coverage/mapping/Path.cpp.func.html | 101 + coverage/mapping/Path.cpp.gcov.html | 424 + .../PathDisplacements.cpp.func-sort-c.html | 105 + .../mapping/PathDisplacements.cpp.func.html | 105 + .../mapping/PathDisplacements.cpp.gcov.html | 253 + ...hProjectionCalculator.cpp.func-sort-c.html | 105 + .../PathProjectionCalculator.cpp.func.html | 105 + .../PathProjectionCalculator.cpp.gcov.html | 220 + ...athReparameterization.cpp.func-sort-c.html | 113 + .../PathReparameterization.cpp.func.html | 113 + .../PathReparameterization.cpp.gcov.html | 306 + .../mapping/PathTools.cpp.func-sort-c.html | 105 + coverage/mapping/PathTools.cpp.func.html | 105 + coverage/mapping/PathTools.cpp.gcov.html | 521 + coverage/mapping/index-sort-f.html | 174 + coverage/mapping/index-sort-l.html | 174 + coverage/mapping/index.html | 174 + coverage/maze/Loss.cpp.func-sort-c.html | 89 + coverage/maze/Loss.cpp.func.html | 89 + coverage/maze/Loss.cpp.gcov.html | 191 + coverage/maze/Loss.h.func-sort-c.html | 85 + coverage/maze/Loss.h.func.html | 85 + coverage/maze/Loss.h.gcov.html | 163 + coverage/maze/Member.h.func-sort-c.html | 81 + coverage/maze/Member.h.func.html | 81 + coverage/maze/Member.h.gcov.html | 143 + coverage/maze/Memetic.cpp.func-sort-c.html | 89 + coverage/maze/Memetic.cpp.func.html | 89 + coverage/maze/Memetic.cpp.gcov.html | 359 + coverage/maze/Memetic.h.func-sort-c.html | 153 + coverage/maze/Memetic.h.func.html | 153 + coverage/maze/Memetic.h.gcov.html | 883 + coverage/maze/Optimizer.cpp.func-sort-c.html | 113 + coverage/maze/Optimizer.cpp.func.html | 113 + coverage/maze/Optimizer.cpp.gcov.html | 587 + coverage/maze/Optimizer.h.func-sort-c.html | 77 + coverage/maze/Optimizer.h.func.html | 77 + coverage/maze/Optimizer.h.gcov.html | 434 + .../maze/Optimizer_Bias.cpp.func-sort-c.html | 97 + coverage/maze/Optimizer_Bias.cpp.func.html | 97 + coverage/maze/Optimizer_Bias.cpp.gcov.html | 511 + ...andom_Acceleration_MD.cpp.func-sort-c.html | 89 + .../maze/Random_Acceleration_MD.cpp.func.html | 89 + .../maze/Random_Acceleration_MD.cpp.gcov.html | 280 + coverage/maze/Random_MT.cpp.func-sort-c.html | 97 + coverage/maze/Random_MT.cpp.func.html | 97 + coverage/maze/Random_MT.cpp.gcov.html | 158 + coverage/maze/Random_MT.h.func-sort-c.html | 89 + coverage/maze/Random_MT.h.func.html | 89 + coverage/maze/Random_MT.h.gcov.html | 233 + .../maze/Random_Walk.cpp.func-sort-c.html | 89 + coverage/maze/Random_Walk.cpp.func.html | 89 + coverage/maze/Random_Walk.cpp.gcov.html | 201 + .../Simulated_Annealing.cpp.func-sort-c.html | 93 + .../maze/Simulated_Annealing.cpp.func.html | 93 + .../maze/Simulated_Annealing.cpp.gcov.html | 352 + coverage/maze/Steered_MD.cpp.func-sort-c.html | 89 + coverage/maze/Steered_MD.cpp.func.html | 89 + coverage/maze/Steered_MD.cpp.gcov.html | 253 + coverage/maze/Tools.h.func-sort-c.html | 89 + coverage/maze/Tools.h.func.html | 89 + coverage/maze/Tools.h.gcov.html | 257 + coverage/maze/index-sort-f.html | 234 + coverage/maze/index-sort-l.html | 234 + coverage/maze/index.html | 234 + .../FusionPoreExpansionP.cpp.func-sort-c.html | 89 + .../FusionPoreExpansionP.cpp.func.html | 89 + .../FusionPoreExpansionP.cpp.gcov.html | 682 + ...FusionPoreNucleationP.cpp.func-sort-c.html | 89 + .../FusionPoreNucleationP.cpp.func.html | 89 + .../FusionPoreNucleationP.cpp.gcov.html | 884 + .../MemFusionP.cpp.func-sort-c.html | 89 + .../membranefusion/MemFusionP.cpp.func.html | 89 + .../membranefusion/MemFusionP.cpp.gcov.html | 685 + coverage/membranefusion/index-sort-f.html | 114 + coverage/membranefusion/index-sort-l.html | 114 + coverage/membranefusion/index.html | 114 + .../AlphaBeta.cpp.func-sort-c.html | 85 + coverage/multicolvar/AlphaBeta.cpp.func.html | 85 + coverage/multicolvar/AlphaBeta.cpp.gcov.html | 187 + .../multicolvar/Angles.cpp.func-sort-c.html | 85 + coverage/multicolvar/Angles.cpp.func.html | 85 + coverage/multicolvar/Angles.cpp.gcov.html | 252 + .../CoordAngles.cpp.func-sort-c.html | 89 + .../multicolvar/CoordAngles.cpp.func.html | 89 + .../multicolvar/CoordAngles.cpp.gcov.html | 185 + .../multicolvar/Dihcor.cpp.func-sort-c.html | 85 + coverage/multicolvar/Dihcor.cpp.func.html | 85 + coverage/multicolvar/Dihcor.cpp.gcov.html | 183 + .../Distances.cpp.func-sort-c.html | 85 + coverage/multicolvar/Distances.cpp.func.html | 85 + coverage/multicolvar/Distances.cpp.gcov.html | 364 + .../DumpMultiColvar.cpp.func-sort-c.html | 85 + .../multicolvar/DumpMultiColvar.cpp.func.html | 85 + .../multicolvar/DumpMultiColvar.cpp.gcov.html | 142 + .../InPlaneDistances.cpp.func-sort-c.html | 85 + .../InPlaneDistances.cpp.func.html | 85 + .../InPlaneDistances.cpp.gcov.html | 158 + .../MFilterLess.cpp.func-sort-c.html | 85 + .../multicolvar/MFilterLess.cpp.func.html | 85 + .../multicolvar/MFilterLess.cpp.gcov.html | 144 + .../MFilterMore.cpp.func-sort-c.html | 85 + .../multicolvar/MFilterMore.cpp.func.html | 85 + .../multicolvar/MFilterMore.cpp.gcov.html | 155 + .../MultiColvarShortcuts.cpp.func-sort-c.html | 93 + .../MultiColvarShortcuts.cpp.func.html | 93 + .../MultiColvarShortcuts.cpp.gcov.html | 328 + .../multicolvar/Planes.cpp.func-sort-c.html | 89 + coverage/multicolvar/Planes.cpp.func.html | 89 + coverage/multicolvar/Planes.cpp.gcov.html | 189 + .../multicolvar/Torsions.cpp.func-sort-c.html | 85 + coverage/multicolvar/Torsions.cpp.func.html | 85 + coverage/multicolvar/Torsions.cpp.gcov.html | 174 + .../multicolvar/UWalls.cpp.func-sort-c.html | 85 + coverage/multicolvar/UWalls.cpp.func.html | 85 + coverage/multicolvar/UWalls.cpp.gcov.html | 151 + .../multicolvar/XAngle.cpp.func-sort-c.html | 85 + coverage/multicolvar/XAngle.cpp.func.html | 85 + coverage/multicolvar/XAngle.cpp.gcov.html | 179 + .../XYTorsions.cpp.func-sort-c.html | 85 + coverage/multicolvar/XYTorsions.cpp.func.html | 85 + coverage/multicolvar/XYTorsions.cpp.gcov.html | 227 + coverage/multicolvar/index-sort-f.html | 234 + coverage/multicolvar/index-sort-l.html | 234 + coverage/multicolvar/index.html | 234 + coverage/opes/ECVcustom.cpp.func-sort-c.html | 117 + coverage/opes/ECVcustom.cpp.func.html | 117 + coverage/opes/ECVcustom.cpp.gcov.html | 315 + coverage/opes/ECVlinear.cpp.func-sort-c.html | 113 + coverage/opes/ECVlinear.cpp.func.html | 113 + coverage/opes/ECVlinear.cpp.gcov.html | 345 + .../opes/ECVmultiThermal.cpp.func-sort-c.html | 113 + coverage/opes/ECVmultiThermal.cpp.func.html | 113 + coverage/opes/ECVmultiThermal.cpp.gcov.html | 345 + .../ECVmultiThermalBaric.cpp.func-sort-c.html | 121 + .../opes/ECVmultiThermalBaric.cpp.func.html | 121 + .../opes/ECVmultiThermalBaric.cpp.gcov.html | 607 + .../ECVumbrellasFile.cpp.func-sort-c.html | 113 + coverage/opes/ECVumbrellasFile.cpp.func.html | 113 + coverage/opes/ECVumbrellasFile.cpp.gcov.html | 372 + .../ECVumbrellasLine.cpp.func-sort-c.html | 113 + coverage/opes/ECVumbrellasLine.cpp.func.html | 113 + coverage/opes/ECVumbrellasLine.cpp.gcov.html | 378 + .../opes/ExpansionCVs.cpp.func-sort-c.html | 113 + coverage/opes/ExpansionCVs.cpp.func.html | 113 + coverage/opes/ExpansionCVs.cpp.gcov.html | 299 + coverage/opes/ExpansionCVs.h.func-sort-c.html | 85 + coverage/opes/ExpansionCVs.h.func.html | 85 + coverage/opes/ExpansionCVs.h.gcov.html | 149 + .../opes/OPESexpanded.cpp.func-sort-c.html | 125 + coverage/opes/OPESexpanded.cpp.func.html | 125 + coverage/opes/OPESexpanded.cpp.gcov.html | 1021 + coverage/opes/OPESmetad.cpp.func-sort-c.html | 185 + coverage/opes/OPESmetad.cpp.func.html | 185 + coverage/opes/OPESmetad.cpp.gcov.html | 1829 + coverage/opes/index-sort-f.html | 184 + coverage/opes/index-sort-l.html | 184 + coverage/opes/index.html | 184 + .../pamm/HBPammMatrix.cpp.func-sort-c.html | 101 + coverage/pamm/HBPammMatrix.cpp.func.html | 101 + coverage/pamm/HBPammMatrix.cpp.gcov.html | 335 + coverage/pamm/PAMM.cpp.func-sort-c.html | 85 + coverage/pamm/PAMM.cpp.func.html | 85 + coverage/pamm/PAMM.cpp.gcov.html | 264 + coverage/pamm/index-sort-f.html | 104 + coverage/pamm/index-sort-l.html | 104 + coverage/pamm/index.html | 104 + coverage/piv/PIV.cpp.func-sort-c.html | 93 + coverage/piv/PIV.cpp.func.html | 93 + coverage/piv/PIV.cpp.gcov.html | 1340 + coverage/piv/index-sort-f.html | 94 + coverage/piv/index-sort-l.html | 94 + coverage/piv/index.html | 94 + .../pytorch/PytorchModel.cpp.func-sort-c.html | 93 + coverage/pytorch/PytorchModel.cpp.func.html | 93 + coverage/pytorch/PytorchModel.cpp.gcov.html | 321 + coverage/pytorch/index-sort-f.html | 94 + coverage/pytorch/index-sort-l.html | 94 + coverage/pytorch/index.html | 94 + .../refdist/Difference.cpp.func-sort-c.html | 89 + coverage/refdist/Difference.cpp.func.html | 89 + coverage/refdist/Difference.cpp.gcov.html | 196 + .../refdist/Displacement.cpp.func-sort-c.html | 93 + coverage/refdist/Displacement.cpp.func.html | 93 + coverage/refdist/Displacement.cpp.gcov.html | 174 + .../EuclideanDistance.cpp.func-sort-c.html | 85 + .../refdist/EuclideanDistance.cpp.func.html | 85 + .../refdist/EuclideanDistance.cpp.gcov.html | 157 + coverage/refdist/Kernel.cpp.func-sort-c.html | 89 + coverage/refdist/Kernel.cpp.func.html | 89 + coverage/refdist/Kernel.cpp.gcov.html | 290 + .../MahalanobisDistance.cpp.func-sort-c.html | 85 + .../refdist/MahalanobisDistance.cpp.func.html | 85 + .../refdist/MahalanobisDistance.cpp.gcov.html | 209 + ...MatrixProductDiagonal.cpp.func-sort-c.html | 97 + .../MatrixProductDiagonal.cpp.func.html | 97 + .../MatrixProductDiagonal.cpp.gcov.html | 216 + ...izedEuclideanDistance.cpp.func-sort-c.html | 85 + .../NormalizedEuclideanDistance.cpp.func.html | 85 + .../NormalizedEuclideanDistance.cpp.gcov.html | 166 + coverage/refdist/index-sort-f.html | 154 + coverage/refdist/index-sort-l.html | 154 + coverage/refdist/index.html | 154 + coverage/ruby.png | Bin 0 -> 141 bytes .../s2cm/S2ContactModel.cpp.func-sort-c.html | 105 + coverage/s2cm/S2ContactModel.cpp.func.html | 105 + coverage/s2cm/S2ContactModel.cpp.gcov.html | 402 + coverage/s2cm/index-sort-f.html | 94 + coverage/s2cm/index-sort-l.html | 94 + coverage/s2cm/index.html | 94 + coverage/sasa/index-sort-f.html | 104 + coverage/sasa/index-sort-l.html | 104 + coverage/sasa/index.html | 104 + coverage/sasa/sasa_HASEL.cpp.func-sort-c.html | 125 + coverage/sasa/sasa_HASEL.cpp.func.html | 125 + coverage/sasa/sasa_HASEL.cpp.gcov.html | 1089 + coverage/sasa/sasa_LCPO.cpp.func-sort-c.html | 125 + coverage/sasa/sasa_LCPO.cpp.func.html | 125 + coverage/sasa/sasa_LCPO.cpp.gcov.html | 1157 + .../AlphaRMSD.cpp.func-sort-c.html | 85 + .../AlphaRMSD.cpp.func.html | 85 + .../AlphaRMSD.cpp.gcov.html | 252 + .../AntibetaRMSD.cpp.func-sort-c.html | 85 + .../AntibetaRMSD.cpp.func.html | 85 + .../AntibetaRMSD.cpp.gcov.html | 309 + .../ParabetaRMSD.cpp.func-sort-c.html | 85 + .../ParabetaRMSD.cpp.func.html | 85 + .../ParabetaRMSD.cpp.gcov.html | 355 + ...econdaryStructureRMSD.cpp.func-sort-c.html | 113 + .../SecondaryStructureRMSD.cpp.func.html | 113 + .../SecondaryStructureRMSD.cpp.gcov.html | 405 + .../SecondaryStructureRMSD.h.func-sort-c.html | 77 + .../SecondaryStructureRMSD.h.func.html | 77 + .../SecondaryStructureRMSD.h.gcov.html | 162 + coverage/secondarystructure/index-sort-f.html | 134 + coverage/secondarystructure/index-sort-l.html | 134 + coverage/secondarystructure/index.html | 134 + coverage/setup/Load.cpp.func-sort-c.html | 85 + coverage/setup/Load.cpp.func.html | 85 + coverage/setup/Load.cpp.gcov.html | 223 + coverage/setup/Restart.cpp.func-sort-c.html | 85 + coverage/setup/Restart.cpp.func.html | 85 + coverage/setup/Restart.cpp.gcov.html | 202 + coverage/setup/Units.cpp.func-sort-c.html | 85 + coverage/setup/Units.cpp.func.html | 85 + coverage/setup/Units.cpp.gcov.html | 275 + coverage/setup/index-sort-f.html | 114 + coverage/setup/index-sort-l.html | 114 + coverage/setup/index.html | 114 + coverage/small_vector/index-sort-f.html | 94 + coverage/small_vector/index-sort-l.html | 94 + coverage/small_vector/index.html | 94 + .../small_vector.h.func-sort-c.html | 245 + .../small_vector/small_vector.h.func.html | 245 + .../small_vector/small_vector.h.gcov.html | 6560 ++++ coverage/snow.png | Bin 0 -> 141 bytes .../symfunc/AngularTetra.cpp.func-sort-c.html | 85 + coverage/symfunc/AngularTetra.cpp.func.html | 85 + coverage/symfunc/AngularTetra.cpp.gcov.html | 162 + .../symfunc/AtomicSMAC.cpp.func-sort-c.html | 85 + coverage/symfunc/AtomicSMAC.cpp.func.html | 85 + coverage/symfunc/AtomicSMAC.cpp.gcov.html | 188 + ...rdShellVectorFunction.cpp.func-sort-c.html | 85 + .../CoordShellVectorFunction.cpp.func.html | 85 + .../CoordShellVectorFunction.cpp.gcov.html | 307 + .../CoordinationNumbers.cpp.func-sort-c.html | 93 + .../symfunc/CoordinationNumbers.cpp.func.html | 93 + .../symfunc/CoordinationNumbers.cpp.gcov.html | 272 + .../CylindricalHarmonic.cpp.func-sort-c.html | 89 + .../symfunc/CylindricalHarmonic.cpp.func.html | 89 + .../symfunc/CylindricalHarmonic.cpp.gcov.html | 174 + coverage/symfunc/Fccubic.cpp.func-sort-c.html | 85 + coverage/symfunc/Fccubic.cpp.func.html | 85 + coverage/symfunc/Fccubic.cpp.gcov.html | 226 + .../HexaticParameter.cpp.func-sort-c.html | 89 + .../symfunc/HexaticParameter.cpp.func.html | 89 + .../symfunc/HexaticParameter.cpp.gcov.html | 206 + .../symfunc/LocalAverage.cpp.func-sort-c.html | 89 + coverage/symfunc/LocalAverage.cpp.func.html | 89 + coverage/symfunc/LocalAverage.cpp.gcov.html | 247 + .../LocalCrystalinity.cpp.func-sort-c.html | 85 + .../symfunc/LocalCrystalinity.cpp.func.html | 85 + .../symfunc/LocalCrystalinity.cpp.gcov.html | 183 + .../LocalSteinhardt.cpp.func-sort-c.html | 93 + .../symfunc/LocalSteinhardt.cpp.func.html | 93 + .../symfunc/LocalSteinhardt.cpp.gcov.html | 522 + .../symfunc/RadialTetra.cpp.func-sort-c.html | 85 + coverage/symfunc/RadialTetra.cpp.func.html | 85 + coverage/symfunc/RadialTetra.cpp.gcov.html | 178 + coverage/symfunc/SMAC.cpp.func-sort-c.html | 85 + coverage/symfunc/SMAC.cpp.func.html | 85 + coverage/symfunc/SMAC.cpp.gcov.html | 200 + .../SphericalHarmonic.cpp.func-sort-c.html | 105 + .../symfunc/SphericalHarmonic.cpp.func.html | 105 + .../symfunc/SphericalHarmonic.cpp.gcov.html | 314 + .../symfunc/Steinhardt.cpp.func-sort-c.html | 93 + coverage/symfunc/Steinhardt.cpp.func.html | 93 + coverage/symfunc/Steinhardt.cpp.gcov.html | 469 + .../ThreeBodyGFunctions.cpp.func-sort-c.html | 97 + .../symfunc/ThreeBodyGFunctions.cpp.func.html | 97 + .../symfunc/ThreeBodyGFunctions.cpp.gcov.html | 254 + coverage/symfunc/index-sort-f.html | 234 + coverage/symfunc/index-sort-l.html | 234 + coverage/symfunc/index.html | 234 + coverage/tools/Angle.cpp.func-sort-c.html | 81 + coverage/tools/Angle.cpp.func.html | 81 + coverage/tools/Angle.cpp.gcov.html | 145 + coverage/tools/AtomNumber.h.func-sort-c.html | 81 + coverage/tools/AtomNumber.h.func.html | 81 + coverage/tools/AtomNumber.h.gcov.html | 229 + .../BiasRepresentation.cpp.func-sort-c.html | 149 + .../tools/BiasRepresentation.cpp.func.html | 149 + .../tools/BiasRepresentation.cpp.gcov.html | 364 + .../Brent1DRootSearch.h.func-sort-c.html | 109 + coverage/tools/Brent1DRootSearch.h.func.html | 109 + coverage/tools/Brent1DRootSearch.h.gcov.html | 197 + .../tools/CheckInRange.cpp.func-sort-c.html | 89 + coverage/tools/CheckInRange.cpp.func.html | 89 + coverage/tools/CheckInRange.cpp.gcov.html | 165 + .../tools/CheckInRange.h.func-sort-c.html | 73 + coverage/tools/CheckInRange.h.func.html | 73 + coverage/tools/CheckInRange.h.gcov.html | 121 + coverage/tools/Citations.cpp.func-sort-c.html | 89 + coverage/tools/Citations.cpp.func.html | 89 + coverage/tools/Citations.cpp.gcov.html | 133 + coverage/tools/Citations.h.func-sort-c.html | 73 + coverage/tools/Citations.h.func.html | 73 + coverage/tools/Citations.h.gcov.html | 151 + .../tools/Communicator.cpp.func-sort-c.html | 217 + coverage/tools/Communicator.cpp.func.html | 217 + coverage/tools/Communicator.cpp.gcov.html | 395 + .../tools/Communicator.h.func-sort-c.html | 313 + coverage/tools/Communicator.h.func.html | 313 + coverage/tools/Communicator.h.gcov.html | 329 + .../ConjugateGradient.h.func-sort-c.html | 85 + coverage/tools/ConjugateGradient.h.func.html | 85 + coverage/tools/ConjugateGradient.h.gcov.html | 143 + coverage/tools/DLLoader.cpp.func-sort-c.html | 105 + coverage/tools/DLLoader.cpp.func.html | 105 + coverage/tools/DLLoader.cpp.gcov.html | 217 + coverage/tools/DynamicList.h.func-sort-c.html | 101 + coverage/tools/DynamicList.h.func.html | 101 + coverage/tools/DynamicList.h.gcov.html | 456 + coverage/tools/ERMSD.cpp.func-sort-c.html | 93 + coverage/tools/ERMSD.cpp.func.html | 93 + coverage/tools/ERMSD.cpp.gcov.html | 380 + coverage/tools/ERMSD.h.func-sort-c.html | 73 + coverage/tools/ERMSD.h.func.html | 73 + coverage/tools/ERMSD.h.gcov.html | 150 + coverage/tools/Exception.cpp.func-sort-c.html | 97 + coverage/tools/Exception.cpp.func.html | 97 + coverage/tools/Exception.cpp.gcov.html | 233 + coverage/tools/Exception.h.func-sort-c.html | 621 + coverage/tools/Exception.h.func.html | 621 + coverage/tools/Exception.h.gcov.html | 480 + coverage/tools/FileBase.cpp.func-sort-c.html | 133 + coverage/tools/FileBase.cpp.func.html | 133 + coverage/tools/FileBase.cpp.gcov.html | 252 + coverage/tools/FileBase.h.func-sort-c.html | 73 + coverage/tools/FileBase.h.func.html | 73 + coverage/tools/FileBase.h.gcov.html | 229 + coverage/tools/ForwardDecl.h.func-sort-c.html | 125 + coverage/tools/ForwardDecl.h.func.html | 125 + coverage/tools/ForwardDecl.h.gcov.html | 132 + coverage/tools/Grid.cpp.func-sort-c.html | 713 + coverage/tools/Grid.cpp.func.html | 713 + coverage/tools/Grid.cpp.gcov.html | 1190 + coverage/tools/Grid.h.func-sort-c.html | 173 + coverage/tools/Grid.h.func.html | 173 + coverage/tools/Grid.h.gcov.html | 696 + .../tools/HistogramBead.cpp.func-sort-c.html | 117 + coverage/tools/HistogramBead.cpp.func.html | 117 + coverage/tools/HistogramBead.cpp.gcov.html | 342 + .../tools/HistogramBead.h.func-sort-c.html | 81 + coverage/tools/HistogramBead.h.func.html | 81 + coverage/tools/HistogramBead.h.gcov.html | 191 + coverage/tools/IFile.cpp.func-sort-c.html | 173 + coverage/tools/IFile.cpp.func.html | 173 + coverage/tools/IFile.cpp.gcov.html | 372 + coverage/tools/IFile.h.func-sort-c.html | 73 + coverage/tools/IFile.h.func.html | 73 + coverage/tools/IFile.h.gcov.html | 194 + .../KernelFunctions.cpp.func-sort-c.html | 113 + coverage/tools/KernelFunctions.cpp.func.html | 113 + coverage/tools/KernelFunctions.cpp.gcov.html | 532 + .../tools/KernelFunctions.h.func-sort-c.html | 77 + coverage/tools/KernelFunctions.h.func.html | 77 + coverage/tools/KernelFunctions.h.gcov.html | 174 + coverage/tools/Keywords.cpp.func-sort-c.html | 249 + coverage/tools/Keywords.cpp.func.html | 249 + coverage/tools/Keywords.cpp.gcov.html | 755 + coverage/tools/Keywords.h.func-sort-c.html | 81 + coverage/tools/Keywords.h.func.html | 81 + coverage/tools/Keywords.h.gcov.html | 272 + .../LatticeReduction.cpp.func-sort-c.html | 113 + coverage/tools/LatticeReduction.cpp.func.html | 113 + coverage/tools/LatticeReduction.cpp.gcov.html | 292 + .../tools/LeptonCall.cpp.func-sort-c.html | 85 + coverage/tools/LeptonCall.cpp.func.html | 85 + coverage/tools/LeptonCall.cpp.gcov.html | 168 + coverage/tools/LeptonCall.h.func-sort-c.html | 73 + coverage/tools/LeptonCall.h.func.html | 73 + coverage/tools/LeptonCall.h.gcov.html | 135 + coverage/tools/LinkCells.cpp.func-sort-c.html | 117 + coverage/tools/LinkCells.cpp.func.html | 117 + coverage/tools/LinkCells.cpp.gcov.html | 259 + coverage/tools/LinkCells.h.func-sort-c.html | 73 + coverage/tools/LinkCells.h.func.html | 73 + coverage/tools/LinkCells.h.gcov.html | 178 + .../tools/LoopUnroller.h.func-sort-c.html | 285 + coverage/tools/LoopUnroller.h.func.html | 285 + coverage/tools/LoopUnroller.h.gcov.html | 237 + coverage/tools/Matrix.h.func-sort-c.html | 109 + coverage/tools/Matrix.h.func.html | 109 + coverage/tools/Matrix.h.gcov.html | 491 + ...rixSquareBracketsAccess.h.func-sort-c.html | 145 + .../MatrixSquareBracketsAccess.h.func.html | 145 + .../MatrixSquareBracketsAccess.h.gcov.html | 215 + .../tools/MergeVectorTools.h.func-sort-c.html | 81 + coverage/tools/MergeVectorTools.h.func.html | 81 + coverage/tools/MergeVectorTools.h.gcov.html | 211 + .../tools/Minimise1DBrent.h.func-sort-c.html | 121 + coverage/tools/Minimise1DBrent.h.func.html | 121 + coverage/tools/Minimise1DBrent.h.gcov.html | 272 + .../tools/MinimiseBase.h.func-sort-c.html | 145 + coverage/tools/MinimiseBase.h.func.html | 145 + coverage/tools/MinimiseBase.h.gcov.html | 192 + .../tools/MolDataClass.cpp.func-sort-c.html | 93 + coverage/tools/MolDataClass.cpp.func.html | 93 + coverage/tools/MolDataClass.cpp.gcov.html | 664 + .../tools/MultiValue.cpp.func-sort-c.html | 113 + coverage/tools/MultiValue.cpp.func.html | 113 + coverage/tools/MultiValue.cpp.gcov.html | 253 + coverage/tools/MultiValue.h.func-sort-c.html | 89 + coverage/tools/MultiValue.h.func.html | 89 + coverage/tools/MultiValue.h.gcov.html | 537 + .../tools/NeighborList.cpp.func-sort-c.html | 137 + coverage/tools/NeighborList.cpp.func.html | 137 + coverage/tools/NeighborList.cpp.gcov.html | 371 + .../tools/NeighborList.h.func-sort-c.html | 73 + coverage/tools/NeighborList.h.func.html | 73 + coverage/tools/NeighborList.h.gcov.html | 189 + coverage/tools/OFile.cpp.func-sort-c.html | 193 + coverage/tools/OFile.cpp.func.html | 193 + coverage/tools/OFile.cpp.gcov.html | 513 + coverage/tools/OFile.h.func-sort-c.html | 505 + coverage/tools/OFile.h.func.html | 505 + coverage/tools/OFile.h.gcov.html | 363 + coverage/tools/OpenMP.cpp.func-sort-c.html | 89 + coverage/tools/OpenMP.cpp.func.html | 89 + coverage/tools/OpenMP.cpp.gcov.html | 159 + coverage/tools/OpenMP.h.func-sort-c.html | 85 + coverage/tools/OpenMP.h.func.html | 85 + coverage/tools/OpenMP.h.gcov.html | 149 + coverage/tools/PDB.cpp.func-sort-c.html | 249 + coverage/tools/PDB.cpp.func.html | 249 + coverage/tools/PDB.cpp.gcov.html | 835 + coverage/tools/Pbc.cpp.func-sort-c.html | 125 + coverage/tools/Pbc.cpp.func.html | 125 + coverage/tools/Pbc.cpp.gcov.html | 368 + coverage/tools/Pbc.h.func-sort-c.html | 73 + coverage/tools/Pbc.h.func.html | 73 + coverage/tools/Pbc.h.gcov.html | 225 + .../tools/PlumedHandle.cpp.func-sort-c.html | 105 + coverage/tools/PlumedHandle.cpp.func.html | 105 + coverage/tools/PlumedHandle.cpp.gcov.html | 185 + coverage/tools/RMSD.cpp.func-sort-c.html | 393 + coverage/tools/RMSD.cpp.func.html | 393 + coverage/tools/RMSD.cpp.gcov.html | 1549 + coverage/tools/RMSD.h.func-sort-c.html | 109 + coverage/tools/RMSD.h.func.html | 109 + coverage/tools/RMSD.h.gcov.html | 453 + coverage/tools/Random.cpp.func-sort-c.html | 117 + coverage/tools/Random.cpp.func.html | 117 + coverage/tools/Random.cpp.gcov.html | 246 + coverage/tools/Random.h.func-sort-c.html | 73 + coverage/tools/Random.h.func.html | 73 + coverage/tools/Random.h.gcov.html | 149 + .../tools/RootFindingBase.h.func-sort-c.html | 97 + coverage/tools/RootFindingBase.h.func.html | 97 + coverage/tools/RootFindingBase.h.gcov.html | 154 + coverage/tools/Stopwatch.cpp.func-sort-c.html | 85 + coverage/tools/Stopwatch.cpp.func.html | 85 + coverage/tools/Stopwatch.cpp.gcov.html | 155 + coverage/tools/Stopwatch.h.func-sort-c.html | 117 + coverage/tools/Stopwatch.h.func.html | 117 + coverage/tools/Stopwatch.h.gcov.html | 543 + .../tools/Subprocess.cpp.func-sort-c.html | 137 + coverage/tools/Subprocess.cpp.func.html | 137 + coverage/tools/Subprocess.cpp.gcov.html | 257 + coverage/tools/Subprocess.h.func-sort-c.html | 81 + coverage/tools/Subprocess.h.func.html | 81 + coverage/tools/Subprocess.h.gcov.html | 219 + .../SwitchingFunction.cpp.func-sort-c.html | 497 + .../tools/SwitchingFunction.cpp.func.html | 497 + .../tools/SwitchingFunction.cpp.gcov.html | 1040 + .../SwitchingFunction.h.func-sort-c.html | 73 + coverage/tools/SwitchingFunction.h.func.html | 73 + coverage/tools/SwitchingFunction.h.gcov.html | 195 + coverage/tools/Tensor.cpp.func-sort-c.html | 77 + coverage/tools/Tensor.cpp.func.html | 77 + coverage/tools/Tensor.cpp.gcov.html | 116 + coverage/tools/Tensor.h.func-sort-c.html | 349 + coverage/tools/Tensor.h.func.html | 349 + coverage/tools/Tensor.h.gcov.html | 651 + coverage/tools/Tools.cpp.func-sort-c.html | 301 + coverage/tools/Tools.cpp.func.html | 301 + coverage/tools/Tools.cpp.gcov.html | 597 + coverage/tools/Tools.h.func-sort-c.html | 297 + coverage/tools/Tools.h.func.html | 297 + coverage/tools/Tools.h.gcov.html | 597 + coverage/tools/Torsion.cpp.func-sort-c.html | 81 + coverage/tools/Torsion.cpp.func.html | 81 + coverage/tools/Torsion.cpp.gcov.html | 157 + coverage/tools/Tree.cpp.func-sort-c.html | 85 + coverage/tools/Tree.cpp.func.html | 85 + coverage/tools/Tree.cpp.gcov.html | 201 + coverage/tools/Tree.h.func-sort-c.html | 73 + coverage/tools/Tree.h.func.html | 73 + coverage/tools/Tree.h.gcov.html | 129 + .../tools/TypesafePtr.cpp.func-sort-c.html | 85 + coverage/tools/TypesafePtr.cpp.func.html | 85 + coverage/tools/TypesafePtr.cpp.gcov.html | 134 + coverage/tools/TypesafePtr.h.func-sort-c.html | 293 + coverage/tools/TypesafePtr.h.func.html | 293 + coverage/tools/TypesafePtr.h.gcov.html | 476 + coverage/tools/Units.cpp.func-sort-c.html | 117 + coverage/tools/Units.cpp.func.html | 117 + coverage/tools/Units.cpp.gcov.html | 235 + coverage/tools/Units.h.func-sort-c.html | 73 + coverage/tools/Units.h.func.html | 73 + coverage/tools/Units.h.gcov.html | 244 + coverage/tools/Vector.h.func-sort-c.html | 341 + coverage/tools/Vector.h.func.html | 341 + coverage/tools/Vector.h.gcov.html | 420 + coverage/tools/h36.cpp.func-sort-c.html | 121 + coverage/tools/h36.cpp.func.html | 121 + coverage/tools/h36.cpp.gcov.html | 412 + coverage/tools/index-sort-f.html | 864 + coverage/tools/index-sort-l.html | 864 + coverage/tools/index.html | 864 + coverage/updown.png | Bin 0 -> 117 bytes .../valtools/Concatenate.cpp.func-sort-c.html | 97 + coverage/valtools/Concatenate.cpp.func.html | 97 + coverage/valtools/Concatenate.cpp.gcov.html | 266 + .../valtools/Flatten.cpp.func-sort-c.html | 97 + coverage/valtools/Flatten.cpp.func.html | 97 + coverage/valtools/Flatten.cpp.gcov.html | 171 + .../SelectComponents.cpp.func-sort-c.html | 85 + .../valtools/SelectComponents.cpp.func.html | 85 + .../valtools/SelectComponents.cpp.gcov.html | 166 + .../SelectWithMask.cpp.func-sort-c.html | 109 + .../valtools/SelectWithMask.cpp.func.html | 109 + .../valtools/SelectWithMask.cpp.gcov.html | 281 + coverage/valtools/index-sort-f.html | 124 + coverage/valtools/index-sort-l.html | 124 + coverage/valtools/index.html | 124 + .../vatom/ArgsToVatom.cpp.func-sort-c.html | 97 + coverage/vatom/ArgsToVatom.cpp.func.html | 97 + coverage/vatom/ArgsToVatom.cpp.gcov.html | 238 + coverage/vatom/Center.cpp.func-sort-c.html | 89 + coverage/vatom/Center.cpp.func.html | 89 + coverage/vatom/Center.cpp.gcov.html | 405 + .../vatom/CenterShortcut.cpp.func-sort-c.html | 85 + coverage/vatom/CenterShortcut.cpp.func.html | 85 + coverage/vatom/CenterShortcut.cpp.gcov.html | 231 + coverage/vatom/FixedAtom.cpp.func-sort-c.html | 89 + coverage/vatom/FixedAtom.cpp.func.html | 89 + coverage/vatom/FixedAtom.cpp.gcov.html | 227 + coverage/vatom/Ghost.cpp.func-sort-c.html | 89 + coverage/vatom/Ghost.cpp.func.html | 89 + coverage/vatom/Ghost.cpp.gcov.html | 263 + coverage/vatom/index-sort-f.html | 134 + coverage/vatom/index-sort-l.html | 134 + coverage/vatom/index.html | 134 + .../ves/BF_Chebyshev.cpp.func-sort-c.html | 89 + coverage/ves/BF_Chebyshev.cpp.func.html | 89 + coverage/ves/BF_Chebyshev.cpp.gcov.html | 233 + coverage/ves/BF_Combined.cpp.func-sort-c.html | 93 + coverage/ves/BF_Combined.cpp.func.html | 93 + coverage/ves/BF_Combined.cpp.gcov.html | 279 + coverage/ves/BF_Cosine.cpp.func-sort-c.html | 93 + coverage/ves/BF_Cosine.cpp.func.html | 93 + coverage/ves/BF_Cosine.cpp.gcov.html | 229 + .../ves/BF_CubicBsplines.cpp.func-sort-c.html | 89 + coverage/ves/BF_CubicBsplines.cpp.func.html | 89 + coverage/ves/BF_CubicBsplines.cpp.gcov.html | 278 + coverage/ves/BF_Custom.cpp.func-sort-c.html | 93 + coverage/ves/BF_Custom.cpp.func.html | 93 + coverage/ves/BF_Custom.cpp.gcov.html | 446 + coverage/ves/BF_Fourier.cpp.func-sort-c.html | 93 + coverage/ves/BF_Fourier.cpp.func.html | 93 + coverage/ves/BF_Fourier.cpp.gcov.html | 233 + .../ves/BF_Gaussians.cpp.func-sort-c.html | 89 + coverage/ves/BF_Gaussians.cpp.func.html | 89 + coverage/ves/BF_Gaussians.cpp.gcov.html | 266 + coverage/ves/BF_Legendre.cpp.func-sort-c.html | 89 + coverage/ves/BF_Legendre.cpp.func.html | 89 + coverage/ves/BF_Legendre.cpp.gcov.html | 249 + coverage/ves/BF_Powers.cpp.func-sort-c.html | 89 + coverage/ves/BF_Powers.cpp.func.html | 89 + coverage/ves/BF_Powers.cpp.gcov.html | 222 + coverage/ves/BF_Sine.cpp.func-sort-c.html | 93 + coverage/ves/BF_Sine.cpp.func.html | 93 + coverage/ves/BF_Sine.cpp.gcov.html | 228 + coverage/ves/BF_Wavelets.cpp.func-sort-c.html | 93 + coverage/ves/BF_Wavelets.cpp.func.html | 93 + coverage/ves/BF_Wavelets.cpp.gcov.html | 495 + .../ves/BasisFunctions.cpp.func-sort-c.html | 157 + coverage/ves/BasisFunctions.cpp.func.html | 157 + coverage/ves/BasisFunctions.cpp.gcov.html | 482 + .../ves/BasisFunctions.h.func-sort-c.html | 105 + coverage/ves/BasisFunctions.h.func.html | 105 + coverage/ves/BasisFunctions.h.gcov.html | 394 + coverage/ves/CoeffsBase.cpp.func-sort-c.html | 201 + coverage/ves/CoeffsBase.cpp.func.html | 201 + coverage/ves/CoeffsBase.cpp.gcov.html | 594 + coverage/ves/CoeffsBase.h.func-sort-c.html | 81 + coverage/ves/CoeffsBase.h.func.html | 81 + coverage/ves/CoeffsBase.h.gcov.html | 336 + .../ves/CoeffsMatrix.cpp.func-sort-c.html | 389 + coverage/ves/CoeffsMatrix.cpp.func.html | 389 + coverage/ves/CoeffsMatrix.cpp.gcov.html | 792 + coverage/ves/CoeffsMatrix.h.func-sort-c.html | 73 + coverage/ves/CoeffsMatrix.h.func.html | 73 + coverage/ves/CoeffsMatrix.h.gcov.html | 288 + .../ves/CoeffsVector.cpp.func-sort-c.html | 469 + coverage/ves/CoeffsVector.cpp.func.html | 469 + coverage/ves/CoeffsVector.cpp.gcov.html | 972 + coverage/ves/CoeffsVector.h.func-sort-c.html | 73 + coverage/ves/CoeffsVector.h.func.html | 73 + coverage/ves/CoeffsVector.h.gcov.html | 317 + ...ermiSwitchingFunction.cpp.func-sort-c.html | 109 + .../ves/FermiSwitchingFunction.cpp.func.html | 109 + .../ves/FermiSwitchingFunction.cpp.gcov.html | 219 + ...ridIntegrationWeights.cpp.func-sort-c.html | 85 + .../ves/GridIntegrationWeights.cpp.func.html | 85 + .../ves/GridIntegrationWeights.cpp.gcov.html | 185 + ...idLinearInterpolation.cpp.func-sort-c.html | 109 + .../ves/GridLinearInterpolation.cpp.func.html | 109 + .../ves/GridLinearInterpolation.cpp.gcov.html | 312 + ...GridLinearInterpolation.h.func-sort-c.html | 77 + .../ves/GridLinearInterpolation.h.func.html | 77 + .../ves/GridLinearInterpolation.h.gcov.html | 159 + .../ves/GridProjWeights.h.func-sort-c.html | 89 + coverage/ves/GridProjWeights.h.func.html | 89 + coverage/ves/GridProjWeights.h.gcov.html | 127 + ...nearBasisSetExpansion.cpp.func-sort-c.html | 217 + .../ves/LinearBasisSetExpansion.cpp.func.html | 217 + .../ves/LinearBasisSetExpansion.cpp.gcov.html | 694 + ...LinearBasisSetExpansion.h.func-sort-c.html | 85 + .../ves/LinearBasisSetExpansion.h.func.html | 85 + .../ves/LinearBasisSetExpansion.h.gcov.html | 327 + ...MD_LinearExpansionPES.cpp.func-sort-c.html | 109 + .../ves/MD_LinearExpansionPES.cpp.func.html | 109 + .../ves/MD_LinearExpansionPES.cpp.gcov.html | 758 + coverage/ves/Opt_Adam.cpp.func-sort-c.html | 89 + coverage/ves/Opt_Adam.cpp.func.html | 89 + coverage/ves/Opt_Adam.cpp.gcov.html | 273 + .../Opt_BachAveragedSGD.cpp.func-sort-c.html | 89 + .../ves/Opt_BachAveragedSGD.cpp.func.html | 89 + .../ves/Opt_BachAveragedSGD.cpp.gcov.html | 379 + coverage/ves/Opt_Dummy.cpp.func-sort-c.html | 89 + coverage/ves/Opt_Dummy.cpp.func.html | 89 + coverage/ves/Opt_Dummy.cpp.gcov.html | 198 + .../Opt_RobbinsMonroSGD.cpp.func-sort-c.html | 89 + .../ves/Opt_RobbinsMonroSGD.cpp.func.html | 89 + .../ves/Opt_RobbinsMonroSGD.cpp.gcov.html | 173 + coverage/ves/Optimizer.cpp.func-sort-c.html | 201 + coverage/ves/Optimizer.cpp.func.html | 201 + coverage/ves/Optimizer.cpp.gcov.html | 1338 + coverage/ves/Optimizer.h.func-sort-c.html | 113 + coverage/ves/Optimizer.h.func.html | 113 + coverage/ves/Optimizer.h.gcov.html | 431 + .../OutputBasisFunctions.cpp.func-sort-c.html | 89 + .../ves/OutputBasisFunctions.cpp.func.html | 89 + .../ves/OutputBasisFunctions.cpp.gcov.html | 313 + .../ves/OutputFesBias.cpp.func-sort-c.html | 93 + coverage/ves/OutputFesBias.cpp.func.html | 93 + coverage/ves/OutputFesBias.cpp.gcov.html | 307 + ...putTargetDistribution.cpp.func-sort-c.html | 89 + .../OutputTargetDistribution.cpp.func.html | 89 + .../OutputTargetDistribution.cpp.gcov.html | 303 + coverage/ves/TD_Chi.cpp.func-sort-c.html | 85 + coverage/ves/TD_Chi.cpp.func.html | 85 + coverage/ves/TD_Chi.cpp.gcov.html | 230 + .../ves/TD_ChiSquared.cpp.func-sort-c.html | 85 + coverage/ves/TD_ChiSquared.cpp.func.html | 85 + coverage/ves/TD_ChiSquared.cpp.gcov.html | 229 + coverage/ves/TD_Custom.cpp.func-sort-c.html | 101 + coverage/ves/TD_Custom.cpp.func.html | 101 + coverage/ves/TD_Custom.cpp.gcov.html | 372 + .../ves/TD_Exponential.cpp.func-sort-c.html | 85 + coverage/ves/TD_Exponential.cpp.func.html | 85 + coverage/ves/TD_Exponential.cpp.gcov.html | 206 + ...iallyModifiedGaussian.cpp.func-sort-c.html | 89 + ...xponentiallyModifiedGaussian.cpp.func.html | 89 + ...xponentiallyModifiedGaussian.cpp.gcov.html | 301 + coverage/ves/TD_Gaussian.cpp.func-sort-c.html | 93 + coverage/ves/TD_Gaussian.cpp.func.html | 93 + coverage/ves/TD_Gaussian.cpp.gcov.html | 392 + ...neralizedExtremeValue.cpp.func-sort-c.html | 89 + .../TD_GeneralizedExtremeValue.cpp.func.html | 89 + .../TD_GeneralizedExtremeValue.cpp.gcov.html | 254 + .../TD_GeneralizedNormal.cpp.func-sort-c.html | 89 + .../ves/TD_GeneralizedNormal.cpp.func.html | 89 + .../ves/TD_GeneralizedNormal.cpp.gcov.html | 304 + coverage/ves/TD_Grid.cpp.func-sort-c.html | 85 + coverage/ves/TD_Grid.cpp.func.html | 85 + coverage/ves/TD_Grid.cpp.gcov.html | 295 + .../TD_LinearCombination.cpp.func-sort-c.html | 113 + .../ves/TD_LinearCombination.cpp.func.html | 113 + .../ves/TD_LinearCombination.cpp.gcov.html | 354 + .../TD_Multicanonical.cpp.func-sort-c.html | 97 + coverage/ves/TD_Multicanonical.cpp.func.html | 97 + coverage/ves/TD_Multicanonical.cpp.gcov.html | 551 + ...ultithermalMultibaric.cpp.func-sort-c.html | 97 + .../TD_MultithermalMultibaric.cpp.func.html | 97 + .../TD_MultithermalMultibaric.cpp.gcov.html | 534 + ...TD_ProductCombination.cpp.func-sort-c.html | 113 + .../ves/TD_ProductCombination.cpp.func.html | 113 + .../ves/TD_ProductCombination.cpp.gcov.html | 341 + ...D_ProductDistribution.cpp.func-sort-c.html | 113 + .../ves/TD_ProductDistribution.cpp.func.html | 113 + .../ves/TD_ProductDistribution.cpp.gcov.html | 302 + coverage/ves/TD_Uniform.cpp.func-sort-c.html | 89 + coverage/ves/TD_Uniform.cpp.func.html | 89 + coverage/ves/TD_Uniform.cpp.gcov.html | 382 + coverage/ves/TD_VonMises.cpp.func-sort-c.html | 93 + coverage/ves/TD_VonMises.cpp.func.html | 93 + coverage/ves/TD_VonMises.cpp.gcov.html | 316 + .../ves/TD_WellTempered.cpp.func-sort-c.html | 97 + coverage/ves/TD_WellTempered.cpp.func.html | 97 + coverage/ves/TD_WellTempered.cpp.gcov.html | 241 + .../ves/TargetDistModifer.h.func-sort-c.html | 77 + coverage/ves/TargetDistModifer.h.func.html | 77 + coverage/ves/TargetDistModifer.h.gcov.html | 130 + .../TargetDistribution.cpp.func-sort-c.html | 177 + coverage/ves/TargetDistribution.cpp.func.html | 177 + coverage/ves/TargetDistribution.cpp.gcov.html | 465 + .../ves/TargetDistribution.h.func-sort-c.html | 97 + coverage/ves/TargetDistribution.h.func.html | 97 + coverage/ves/TargetDistribution.h.gcov.html | 286 + coverage/ves/VesBias.cpp.func-sort-c.html | 253 + coverage/ves/VesBias.cpp.func.html | 253 + coverage/ves/VesBias.cpp.gcov.html | 830 + coverage/ves/VesBias.h.func-sort-c.html | 173 + coverage/ves/VesBias.h.func.html | 173 + coverage/ves/VesBias.h.gcov.html | 492 + coverage/ves/VesDeltaF.cpp.func-sort-c.html | 105 + coverage/ves/VesDeltaF.cpp.func.html | 105 + coverage/ves/VesDeltaF.cpp.gcov.html | 792 + .../VesLinearExpansion.cpp.func-sort-c.html | 157 + coverage/ves/VesLinearExpansion.cpp.func.html | 157 + coverage/ves/VesLinearExpansion.cpp.gcov.html | 634 + coverage/ves/VesTools.cpp.func-sort-c.html | 81 + coverage/ves/VesTools.cpp.func.html | 81 + coverage/ves/VesTools.cpp.gcov.html | 171 + coverage/ves/VesTools.h.func-sort-c.html | 93 + coverage/ves/VesTools.h.func.html | 93 + coverage/ves/VesTools.h.gcov.html | 217 + .../ves/WaveletCoeffs.cpp.func-sort-c.html | 77 + coverage/ves/WaveletCoeffs.cpp.func.html | 77 + coverage/ves/WaveletCoeffs.cpp.gcov.html | 1059 + coverage/ves/WaveletGrid.cpp.func-sort-c.html | 105 + coverage/ves/WaveletGrid.cpp.func.html | 105 + coverage/ves/WaveletGrid.cpp.gcov.html | 331 + coverage/ves/index-sort-f.html | 724 + coverage/ves/index-sort-l.html | 724 + coverage/ves/index.html | 724 + .../volumes/ActionVolume.cpp.func-sort-c.html | 113 + coverage/volumes/ActionVolume.cpp.func.html | 113 + coverage/volumes/ActionVolume.cpp.gcov.html | 214 + .../volumes/ActionVolume.h.func-sort-c.html | 81 + coverage/volumes/ActionVolume.h.func.html | 81 + coverage/volumes/ActionVolume.h.gcov.html | 165 + coverage/volumes/Density.cpp.func-sort-c.html | 85 + coverage/volumes/Density.cpp.func.html | 85 + coverage/volumes/Density.cpp.gcov.html | 140 + .../volumes/VolumeAround.cpp.func-sort-c.html | 93 + coverage/volumes/VolumeAround.cpp.func.html | 93 + coverage/volumes/VolumeAround.cpp.gcov.html | 245 + ...VolumeBetweenContours.cpp.func-sort-c.html | 93 + .../VolumeBetweenContours.cpp.func.html | 93 + .../VolumeBetweenContours.cpp.gcov.html | 239 + .../volumes/VolumeCavity.cpp.func-sort-c.html | 109 + coverage/volumes/VolumeCavity.cpp.func.html | 109 + coverage/volumes/VolumeCavity.cpp.gcov.html | 497 + .../VolumeInCylinder.cpp.func-sort-c.html | 93 + .../volumes/VolumeInCylinder.cpp.func.html | 93 + .../volumes/VolumeInCylinder.cpp.gcov.html | 250 + .../VolumeInSphere.cpp.func-sort-c.html | 93 + coverage/volumes/VolumeInSphere.cpp.func.html | 93 + coverage/volumes/VolumeInSphere.cpp.gcov.html | 214 + .../volumes/VolumeShortcut.h.func-sort-c.html | 121 + coverage/volumes/VolumeShortcut.h.func.html | 121 + coverage/volumes/VolumeShortcut.h.gcov.html | 199 + .../VolumeTetrapore.cpp.func-sort-c.html | 109 + .../volumes/VolumeTetrapore.cpp.func.html | 109 + .../volumes/VolumeTetrapore.cpp.gcov.html | 534 + coverage/volumes/index-sort-f.html | 184 + coverage/volumes/index-sort-l.html | 184 + coverage/volumes/index.html | 184 + coverage/wrapper/Plumed.h.func-sort-c.html | 1089 + coverage/wrapper/Plumed.h.func.html | 1089 + coverage/wrapper/Plumed.h.gcov.html | 4478 +++ coverage/wrapper/index-sort-f.html | 94 + coverage/wrapper/index-sort-l.html | 94 + coverage/wrapper/index.html | 94 + index.html | 14 + 2126 files changed, 509703 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/ActionWithMatrix.cpp.func-sort-c.html create mode 100644 coverage/adjmat/ActionWithMatrix.cpp.func.html create mode 100644 coverage/adjmat/ActionWithMatrix.cpp.gcov.html create mode 100644 coverage/adjmat/ActionWithMatrix.h.func-sort-c.html create mode 100644 coverage/adjmat/ActionWithMatrix.h.func.html create mode 100644 coverage/adjmat/ActionWithMatrix.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/Bridge.cpp.func-sort-c.html create mode 100644 coverage/adjmat/Bridge.cpp.func.html create mode 100644 coverage/adjmat/Bridge.cpp.gcov.html create mode 100644 coverage/adjmat/BridgeMatrix.cpp.func-sort-c.html create mode 100644 coverage/adjmat/BridgeMatrix.cpp.func.html create mode 100644 coverage/adjmat/BridgeMatrix.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/ContactMatrixShortcut.cpp.func-sort-c.html create mode 100644 coverage/adjmat/ContactMatrixShortcut.cpp.func.html create mode 100644 coverage/adjmat/ContactMatrixShortcut.cpp.gcov.html create mode 100644 coverage/adjmat/CovarianceMatrix.cpp.func-sort-c.html create mode 100644 coverage/adjmat/CovarianceMatrix.cpp.func.html create mode 100644 coverage/adjmat/CovarianceMatrix.cpp.gcov.html create mode 100644 coverage/adjmat/Determinent.cpp.func-sort-c.html create mode 100644 coverage/adjmat/Determinent.cpp.func.html create mode 100644 coverage/adjmat/Determinent.cpp.gcov.html create mode 100644 coverage/adjmat/DiagonalizeMatrix.cpp.func-sort-c.html create mode 100644 coverage/adjmat/DiagonalizeMatrix.cpp.func.html create mode 100644 coverage/adjmat/DiagonalizeMatrix.cpp.gcov.html create mode 100644 coverage/adjmat/DistanceMatrix.cpp.func-sort-c.html create mode 100644 coverage/adjmat/DistanceMatrix.cpp.func.html create mode 100644 coverage/adjmat/DistanceMatrix.cpp.gcov.html create mode 100644 coverage/adjmat/FunctionOfMatrix.h.func-sort-c.html create mode 100644 coverage/adjmat/FunctionOfMatrix.h.func.html create mode 100644 coverage/adjmat/FunctionOfMatrix.h.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/InvertMatrix.cpp.func-sort-c.html create mode 100644 coverage/adjmat/InvertMatrix.cpp.func.html create mode 100644 coverage/adjmat/InvertMatrix.cpp.gcov.html create mode 100644 coverage/adjmat/MatrixOperationBase.cpp.func-sort-c.html create mode 100644 coverage/adjmat/MatrixOperationBase.cpp.func.html create mode 100644 coverage/adjmat/MatrixOperationBase.cpp.gcov.html create mode 100644 coverage/adjmat/MatrixTimesMatrix.cpp.func-sort-c.html create mode 100644 coverage/adjmat/MatrixTimesMatrix.cpp.func.html create mode 100644 coverage/adjmat/MatrixTimesMatrix.cpp.gcov.html create mode 100644 coverage/adjmat/MatrixTimesVector.cpp.func-sort-c.html create mode 100644 coverage/adjmat/MatrixTimesVector.cpp.func.html create mode 100644 coverage/adjmat/MatrixTimesVector.cpp.gcov.html create mode 100644 coverage/adjmat/Neighbors.cpp.func-sort-c.html create mode 100644 coverage/adjmat/Neighbors.cpp.func.html create mode 100644 coverage/adjmat/Neighbors.cpp.gcov.html create mode 100644 coverage/adjmat/OuterProduct.cpp.func-sort-c.html create mode 100644 coverage/adjmat/OuterProduct.cpp.func.html create mode 100644 coverage/adjmat/OuterProduct.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/TorsionsMatrix.cpp.func-sort-c.html create mode 100644 coverage/adjmat/TorsionsMatrix.cpp.func.html create mode 100644 coverage/adjmat/TorsionsMatrix.cpp.gcov.html create mode 100644 coverage/adjmat/TransposeMatrix.cpp.func-sort-c.html create mode 100644 coverage/adjmat/TransposeMatrix.cpp.func.html create mode 100644 coverage/adjmat/TransposeMatrix.cpp.gcov.html create mode 100644 coverage/adjmat/VStack.cpp.func-sort-c.html create mode 100644 coverage/adjmat/VStack.cpp.func.html create mode 100644 coverage/adjmat/VStack.cpp.gcov.html create mode 100644 coverage/adjmat/Voronoi.cpp.func-sort-c.html create mode 100644 coverage/adjmat/Voronoi.cpp.func.html create mode 100644 coverage/adjmat/Voronoi.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/Accumulate.cpp.func-sort-c.html create mode 100644 coverage/analysis/Accumulate.cpp.func.html create mode 100644 coverage/analysis/Accumulate.cpp.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/Collect.cpp.func-sort-c.html create mode 100644 coverage/analysis/Collect.cpp.func.html create mode 100644 coverage/analysis/Collect.cpp.gcov.html create mode 100644 coverage/analysis/CollectFrames.cpp.func-sort-c.html create mode 100644 coverage/analysis/CollectFrames.cpp.func.html create mode 100644 coverage/analysis/CollectFrames.cpp.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/CreateMask.cpp.func-sort-c.html create mode 100644 coverage/analysis/CreateMask.cpp.func.html create mode 100644 coverage/analysis/CreateMask.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/GatherReplicas.cpp.func-sort-c.html create mode 100644 coverage/analysis/GatherReplicas.cpp.func.html create mode 100644 coverage/analysis/GatherReplicas.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/LandmarkSelection.cpp.func-sort-c.html create mode 100644 coverage/analysis/LandmarkSelection.cpp.func.html create mode 100644 coverage/analysis/LandmarkSelection.cpp.gcov.html create mode 100644 coverage/analysis/LogSumExp.cpp.func-sort-c.html create mode 100644 coverage/analysis/LogSumExp.cpp.func.html create mode 100644 coverage/analysis/LogSumExp.cpp.gcov.html create mode 100644 coverage/analysis/Wham.cpp.func-sort-c.html create mode 100644 coverage/analysis/Wham.cpp.func.html create mode 100644 coverage/analysis/Wham.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/RestraintShortcut.cpp.func-sort-c.html create mode 100644 coverage/bias/RestraintShortcut.cpp.func.html create mode 100644 coverage/bias/RestraintShortcut.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/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/Walls.cpp.func-sort-c.html create mode 100644 coverage/bias/Walls.cpp.func.html create mode 100644 coverage/bias/Walls.cpp.gcov.html create mode 100644 coverage/bias/index-sort-f.html create mode 100644 coverage/bias/index-sort-l.html create mode 100644 coverage/bias/index.html create mode 100644 coverage/cltools/Benchmark.cpp.func-sort-c.html create mode 100644 coverage/cltools/Benchmark.cpp.func.html create mode 100644 coverage/cltools/Benchmark.cpp.gcov.html create mode 100644 coverage/cltools/Completion.cpp.func-sort-c.html create mode 100644 coverage/cltools/Completion.cpp.func.html create mode 100644 coverage/cltools/Completion.cpp.gcov.html create mode 100644 coverage/cltools/Driver.cpp.func-sort-c.html create mode 100644 coverage/cltools/Driver.cpp.func.html create mode 100644 coverage/cltools/Driver.cpp.gcov.html create mode 100644 coverage/cltools/DriverDouble.cpp.func-sort-c.html create mode 100644 coverage/cltools/DriverDouble.cpp.func.html create mode 100644 coverage/cltools/DriverDouble.cpp.gcov.html create mode 100644 coverage/cltools/DriverFloat.cpp.func-sort-c.html create mode 100644 coverage/cltools/DriverFloat.cpp.func.html create mode 100644 coverage/cltools/DriverFloat.cpp.gcov.html create mode 100644 coverage/cltools/GenExample.cpp.func-sort-c.html create mode 100644 coverage/cltools/GenExample.cpp.func.html create mode 100644 coverage/cltools/GenExample.cpp.gcov.html create mode 100644 coverage/cltools/GenJson.cpp.func-sort-c.html create mode 100644 coverage/cltools/GenJson.cpp.func.html create mode 100644 coverage/cltools/GenJson.cpp.gcov.html create mode 100644 coverage/cltools/GenTemplate.cpp.func-sort-c.html create mode 100644 coverage/cltools/GenTemplate.cpp.func.html create mode 100644 coverage/cltools/GenTemplate.cpp.gcov.html create mode 100644 coverage/cltools/Info.cpp.func-sort-c.html create mode 100644 coverage/cltools/Info.cpp.func.html create mode 100644 coverage/cltools/Info.cpp.gcov.html create mode 100644 coverage/cltools/Manual.cpp.func-sort-c.html create mode 100644 coverage/cltools/Manual.cpp.func.html create mode 100644 coverage/cltools/Manual.cpp.gcov.html create mode 100644 coverage/cltools/PdbRenumber.cpp.func-sort-c.html create mode 100644 coverage/cltools/PdbRenumber.cpp.func.html create mode 100644 coverage/cltools/PdbRenumber.cpp.gcov.html create mode 100644 coverage/cltools/ShowGraph.cpp.func-sort-c.html create mode 100644 coverage/cltools/ShowGraph.cpp.func.html create mode 100644 coverage/cltools/ShowGraph.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/SwitchingPlotter.cpp.func-sort-c.html create mode 100644 coverage/cltools/SwitchingPlotter.cpp.func.html create mode 100644 coverage/cltools/SwitchingPlotter.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/clusters/ClusterDiameter.cpp.func-sort-c.html create mode 100644 coverage/clusters/ClusterDiameter.cpp.func.html create mode 100644 coverage/clusters/ClusterDiameter.cpp.gcov.html create mode 100644 coverage/clusters/ClusterDistribution.cpp.func-sort-c.html create mode 100644 coverage/clusters/ClusterDistribution.cpp.func.html create mode 100644 coverage/clusters/ClusterDistribution.cpp.gcov.html create mode 100644 coverage/clusters/ClusterNatoms.cpp.func-sort-c.html create mode 100644 coverage/clusters/ClusterNatoms.cpp.func.html create mode 100644 coverage/clusters/ClusterNatoms.cpp.gcov.html create mode 100644 coverage/clusters/ClusterProperties.cpp.func-sort-c.html create mode 100644 coverage/clusters/ClusterProperties.cpp.func.html create mode 100644 coverage/clusters/ClusterProperties.cpp.gcov.html create mode 100644 coverage/clusters/ClusterWeights.cpp.func-sort-c.html create mode 100644 coverage/clusters/ClusterWeights.cpp.func.html create mode 100644 coverage/clusters/ClusterWeights.cpp.gcov.html create mode 100644 coverage/clusters/ClusterWithSurface.cpp.func-sort-c.html create mode 100644 coverage/clusters/ClusterWithSurface.cpp.func.html create mode 100644 coverage/clusters/ClusterWithSurface.cpp.gcov.html create mode 100644 coverage/clusters/ClusteringBase.cpp.func-sort-c.html create mode 100644 coverage/clusters/ClusteringBase.cpp.func.html create mode 100644 coverage/clusters/ClusteringBase.cpp.gcov.html create mode 100644 coverage/clusters/ClusteringBase.h.func-sort-c.html create mode 100644 coverage/clusters/ClusteringBase.h.func.html create mode 100644 coverage/clusters/ClusteringBase.h.gcov.html create mode 100644 coverage/clusters/DFSClustering.cpp.func-sort-c.html create mode 100644 coverage/clusters/DFSClustering.cpp.func.html create mode 100644 coverage/clusters/DFSClustering.cpp.gcov.html create mode 100644 coverage/clusters/OutputCluster.cpp.func-sort-c.html create mode 100644 coverage/clusters/OutputCluster.cpp.func.html create mode 100644 coverage/clusters/OutputCluster.cpp.gcov.html create mode 100644 coverage/clusters/index-sort-f.html create mode 100644 coverage/clusters/index-sort-l.html create mode 100644 coverage/clusters/index.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/ColvarShortcut.h.func-sort-c.html create mode 100644 coverage/colvar/ColvarShortcut.h.func.html create mode 100644 coverage/colvar/ColvarShortcut.h.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/DihedralCorrelation.cpp.func-sort-c.html create mode 100644 coverage/colvar/DihedralCorrelation.cpp.func.html create mode 100644 coverage/colvar/DihedralCorrelation.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/GyrationShortcut.cpp.func-sort-c.html create mode 100644 coverage/colvar/GyrationShortcut.cpp.func.html create mode 100644 coverage/colvar/GyrationShortcut.cpp.gcov.html create mode 100644 coverage/colvar/MultiColvarTemplate.h.func-sort-c.html create mode 100644 coverage/colvar/MultiColvarTemplate.h.func.html create mode 100644 coverage/colvar/MultiColvarTemplate.h.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/Plane.cpp.func-sort-c.html create mode 100644 coverage/colvar/Plane.cpp.func.html create mode 100644 coverage/colvar/Plane.cpp.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/RMSDShortcut.cpp.func-sort-c.html create mode 100644 coverage/colvar/RMSDShortcut.cpp.func.html create mode 100644 coverage/colvar/RMSDShortcut.cpp.gcov.html create mode 100644 coverage/colvar/RMSDVector.cpp.func-sort-c.html create mode 100644 coverage/colvar/RMSDVector.cpp.func.html create mode 100644 coverage/colvar/RMSDVector.cpp.gcov.html create mode 100644 coverage/colvar/SelectMassCharge.cpp.func-sort-c.html create mode 100644 coverage/colvar/SelectMassCharge.cpp.func.html create mode 100644 coverage/colvar/SelectMassCharge.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/contour/ContourFindingBase.cpp.func-sort-c.html create mode 100644 coverage/contour/ContourFindingBase.cpp.func.html create mode 100644 coverage/contour/ContourFindingBase.cpp.gcov.html create mode 100644 coverage/contour/ContourFindingBase.h.func-sort-c.html create mode 100644 coverage/contour/ContourFindingBase.h.func.html create mode 100644 coverage/contour/ContourFindingBase.h.gcov.html create mode 100644 coverage/contour/DistanceFromContour.cpp.func-sort-c.html create mode 100644 coverage/contour/DistanceFromContour.cpp.func.html create mode 100644 coverage/contour/DistanceFromContour.cpp.gcov.html create mode 100644 coverage/contour/DistanceFromContourBase.cpp.func-sort-c.html create mode 100644 coverage/contour/DistanceFromContourBase.cpp.func.html create mode 100644 coverage/contour/DistanceFromContourBase.cpp.gcov.html create mode 100644 coverage/contour/DistanceFromContourBase.h.func-sort-c.html create mode 100644 coverage/contour/DistanceFromContourBase.h.func.html create mode 100644 coverage/contour/DistanceFromContourBase.h.gcov.html create mode 100644 coverage/contour/DistanceFromSphericalContour.cpp.func-sort-c.html create mode 100644 coverage/contour/DistanceFromSphericalContour.cpp.func.html create mode 100644 coverage/contour/DistanceFromSphericalContour.cpp.gcov.html create mode 100644 coverage/contour/DumpContour.cpp.func-sort-c.html create mode 100644 coverage/contour/DumpContour.cpp.func.html create mode 100644 coverage/contour/DumpContour.cpp.gcov.html create mode 100644 coverage/contour/FindContour.cpp.func-sort-c.html create mode 100644 coverage/contour/FindContour.cpp.func.html create mode 100644 coverage/contour/FindContour.cpp.gcov.html create mode 100644 coverage/contour/FindContour.h.func-sort-c.html create mode 100644 coverage/contour/FindContour.h.func.html create mode 100644 coverage/contour/FindContour.h.gcov.html create mode 100644 coverage/contour/FindContourSurface.cpp.func-sort-c.html create mode 100644 coverage/contour/FindContourSurface.cpp.func.html create mode 100644 coverage/contour/FindContourSurface.cpp.gcov.html create mode 100644 coverage/contour/FindSphericalContour.cpp.func-sort-c.html create mode 100644 coverage/contour/FindSphericalContour.cpp.func.html create mode 100644 coverage/contour/FindSphericalContour.cpp.gcov.html create mode 100644 coverage/contour/index-sort-f.html create mode 100644 coverage/contour/index-sort-l.html create mode 100644 coverage/contour/index.html create mode 100644 coverage/core/Action.cpp.func-sort-c.html create mode 100644 coverage/core/Action.cpp.func.html create mode 100644 coverage/core/Action.cpp.gcov.html create mode 100644 coverage/core/Action.h.func-sort-c.html create mode 100644 coverage/core/Action.h.func.html create mode 100644 coverage/core/Action.h.gcov.html create mode 100644 coverage/core/ActionAnyorder.cpp.func-sort-c.html create mode 100644 coverage/core/ActionAnyorder.cpp.func.html create mode 100644 coverage/core/ActionAnyorder.cpp.gcov.html create mode 100644 coverage/core/ActionAnyorder.h.func-sort-c.html create mode 100644 coverage/core/ActionAnyorder.h.func.html create mode 100644 coverage/core/ActionAnyorder.h.gcov.html create mode 100644 coverage/core/ActionAtomistic.cpp.func-sort-c.html create mode 100644 coverage/core/ActionAtomistic.cpp.func.html create mode 100644 coverage/core/ActionAtomistic.cpp.gcov.html create mode 100644 coverage/core/ActionAtomistic.h.func-sort-c.html create mode 100644 coverage/core/ActionAtomistic.h.func.html create mode 100644 coverage/core/ActionAtomistic.h.gcov.html create mode 100644 coverage/core/ActionForInterface.cpp.func-sort-c.html create mode 100644 coverage/core/ActionForInterface.cpp.func.html create mode 100644 coverage/core/ActionForInterface.cpp.gcov.html create mode 100644 coverage/core/ActionForInterface.h.func-sort-c.html create mode 100644 coverage/core/ActionForInterface.h.func.html create mode 100644 coverage/core/ActionForInterface.h.gcov.html create mode 100644 coverage/core/ActionPilot.cpp.func-sort-c.html create mode 100644 coverage/core/ActionPilot.cpp.func.html create mode 100644 coverage/core/ActionPilot.cpp.gcov.html create mode 100644 coverage/core/ActionPilot.h.func-sort-c.html create mode 100644 coverage/core/ActionPilot.h.func.html create mode 100644 coverage/core/ActionPilot.h.gcov.html create mode 100644 coverage/core/ActionRegister.cpp.func-sort-c.html create mode 100644 coverage/core/ActionRegister.cpp.func.html create mode 100644 coverage/core/ActionRegister.cpp.gcov.html create mode 100644 coverage/core/ActionRegister.h.func-sort-c.html create mode 100644 coverage/core/ActionRegister.h.func.html create mode 100644 coverage/core/ActionRegister.h.gcov.html create mode 100644 coverage/core/ActionSet.cpp.func-sort-c.html create mode 100644 coverage/core/ActionSet.cpp.func.html create mode 100644 coverage/core/ActionSet.cpp.gcov.html create mode 100644 coverage/core/ActionSet.h.func-sort-c.html create mode 100644 coverage/core/ActionSet.h.func.html create mode 100644 coverage/core/ActionSet.h.gcov.html create mode 100644 coverage/core/ActionSetup.cpp.func-sort-c.html create mode 100644 coverage/core/ActionSetup.cpp.func.html create mode 100644 coverage/core/ActionSetup.cpp.gcov.html create mode 100644 coverage/core/ActionSetup.h.func-sort-c.html create mode 100644 coverage/core/ActionSetup.h.func.html create mode 100644 coverage/core/ActionSetup.h.gcov.html create mode 100644 coverage/core/ActionShortcut.cpp.func-sort-c.html create mode 100644 coverage/core/ActionShortcut.cpp.func.html create mode 100644 coverage/core/ActionShortcut.cpp.gcov.html create mode 100644 coverage/core/ActionShortcut.h.func-sort-c.html create mode 100644 coverage/core/ActionShortcut.h.func.html create mode 100644 coverage/core/ActionShortcut.h.gcov.html create mode 100644 coverage/core/ActionToGetData.cpp.func-sort-c.html create mode 100644 coverage/core/ActionToGetData.cpp.func.html create mode 100644 coverage/core/ActionToGetData.cpp.gcov.html create mode 100644 coverage/core/ActionToGetData.h.func-sort-c.html create mode 100644 coverage/core/ActionToGetData.h.func.html create mode 100644 coverage/core/ActionToGetData.h.gcov.html create mode 100644 coverage/core/ActionToPutData.cpp.func-sort-c.html create mode 100644 coverage/core/ActionToPutData.cpp.func.html create mode 100644 coverage/core/ActionToPutData.cpp.gcov.html create mode 100644 coverage/core/ActionToPutData.h.func-sort-c.html create mode 100644 coverage/core/ActionToPutData.h.func.html create mode 100644 coverage/core/ActionToPutData.h.gcov.html create mode 100644 coverage/core/ActionWithArguments.cpp.func-sort-c.html create mode 100644 coverage/core/ActionWithArguments.cpp.func.html create mode 100644 coverage/core/ActionWithArguments.cpp.gcov.html create mode 100644 coverage/core/ActionWithArguments.h.func-sort-c.html create mode 100644 coverage/core/ActionWithArguments.h.func.html create mode 100644 coverage/core/ActionWithArguments.h.gcov.html create mode 100644 coverage/core/ActionWithValue.cpp.func-sort-c.html create mode 100644 coverage/core/ActionWithValue.cpp.func.html create mode 100644 coverage/core/ActionWithValue.cpp.gcov.html create mode 100644 coverage/core/ActionWithValue.h.func-sort-c.html create mode 100644 coverage/core/ActionWithValue.h.func.html create mode 100644 coverage/core/ActionWithValue.h.gcov.html create mode 100644 coverage/core/ActionWithVector.cpp.func-sort-c.html create mode 100644 coverage/core/ActionWithVector.cpp.func.html create mode 100644 coverage/core/ActionWithVector.cpp.gcov.html create mode 100644 coverage/core/ActionWithVector.h.func-sort-c.html create mode 100644 coverage/core/ActionWithVector.h.func.html create mode 100644 coverage/core/ActionWithVector.h.gcov.html create mode 100644 coverage/core/ActionWithVirtualAtom.cpp.func-sort-c.html create mode 100644 coverage/core/ActionWithVirtualAtom.cpp.func.html create mode 100644 coverage/core/ActionWithVirtualAtom.cpp.gcov.html create mode 100644 coverage/core/ActionWithVirtualAtom.h.func-sort-c.html create mode 100644 coverage/core/ActionWithVirtualAtom.h.func.html create mode 100644 coverage/core/ActionWithVirtualAtom.h.gcov.html create mode 100644 coverage/core/CLTool.cpp.func-sort-c.html create mode 100644 coverage/core/CLTool.cpp.func.html create mode 100644 coverage/core/CLTool.cpp.gcov.html create mode 100644 coverage/core/CLTool.h.func-sort-c.html create mode 100644 coverage/core/CLTool.h.func.html create mode 100644 coverage/core/CLTool.h.gcov.html create mode 100644 coverage/core/CLToolMain.cpp.func-sort-c.html create mode 100644 coverage/core/CLToolMain.cpp.func.html create mode 100644 coverage/core/CLToolMain.cpp.gcov.html create mode 100644 coverage/core/CLToolRegister.cpp.func-sort-c.html create mode 100644 coverage/core/CLToolRegister.cpp.func.html create mode 100644 coverage/core/CLToolRegister.cpp.gcov.html create mode 100644 coverage/core/CLToolRegister.h.func-sort-c.html create mode 100644 coverage/core/CLToolRegister.h.func.html create mode 100644 coverage/core/CLToolRegister.h.gcov.html create mode 100644 coverage/core/Colvar.cpp.func-sort-c.html create mode 100644 coverage/core/Colvar.cpp.func.html create mode 100644 coverage/core/Colvar.cpp.gcov.html create mode 100644 coverage/core/Colvar.h.func-sort-c.html create mode 100644 coverage/core/Colvar.h.func.html create mode 100644 coverage/core/Colvar.h.gcov.html create mode 100644 coverage/core/DataPassingObject.cpp.func-sort-c.html create mode 100644 coverage/core/DataPassingObject.cpp.func.html create mode 100644 coverage/core/DataPassingObject.cpp.gcov.html create mode 100644 coverage/core/DataPassingObject.h.func-sort-c.html create mode 100644 coverage/core/DataPassingObject.h.func.html create mode 100644 coverage/core/DataPassingObject.h.gcov.html create mode 100644 coverage/core/DataPassingTools.cpp.func-sort-c.html create mode 100644 coverage/core/DataPassingTools.cpp.func.html create mode 100644 coverage/core/DataPassingTools.cpp.gcov.html create mode 100644 coverage/core/DataPassingTools.h.func-sort-c.html create mode 100644 coverage/core/DataPassingTools.h.func.html create mode 100644 coverage/core/DataPassingTools.h.gcov.html create mode 100644 coverage/core/DomainDecomposition.cpp.func-sort-c.html create mode 100644 coverage/core/DomainDecomposition.cpp.func.html create mode 100644 coverage/core/DomainDecomposition.cpp.gcov.html create mode 100644 coverage/core/DomainDecomposition.h.func-sort-c.html create mode 100644 coverage/core/DomainDecomposition.h.func.html create mode 100644 coverage/core/DomainDecomposition.h.gcov.html create mode 100644 coverage/core/ExchangePatterns.cpp.func-sort-c.html create mode 100644 coverage/core/ExchangePatterns.cpp.func.html create mode 100644 coverage/core/ExchangePatterns.cpp.gcov.html create mode 100644 coverage/core/FlexibleBin.cpp.func-sort-c.html create mode 100644 coverage/core/FlexibleBin.cpp.func.html create mode 100644 coverage/core/FlexibleBin.cpp.gcov.html create mode 100644 coverage/core/GREX.cpp.func-sort-c.html create mode 100644 coverage/core/GREX.cpp.func.html create mode 100644 coverage/core/GREX.cpp.gcov.html create mode 100644 coverage/core/GenericMolInfo.cpp.func-sort-c.html create mode 100644 coverage/core/GenericMolInfo.cpp.func.html create mode 100644 coverage/core/GenericMolInfo.cpp.gcov.html create mode 100644 coverage/core/GenericMolInfo.h.func-sort-c.html create mode 100644 coverage/core/GenericMolInfo.h.func.html create mode 100644 coverage/core/GenericMolInfo.h.gcov.html create mode 100644 coverage/core/Group.cpp.func-sort-c.html create mode 100644 coverage/core/Group.cpp.func.html create mode 100644 coverage/core/Group.cpp.gcov.html create mode 100644 coverage/core/Group.h.func-sort-c.html create mode 100644 coverage/core/Group.h.func.html create mode 100644 coverage/core/Group.h.gcov.html create mode 100644 coverage/core/PbcAction.cpp.func-sort-c.html create mode 100644 coverage/core/PbcAction.cpp.func.html create mode 100644 coverage/core/PbcAction.cpp.gcov.html create mode 100644 coverage/core/PbcAction.h.func-sort-c.html create mode 100644 coverage/core/PbcAction.h.func.html create mode 100644 coverage/core/PbcAction.h.gcov.html create mode 100644 coverage/core/PlumedMain.cpp.func-sort-c.html create mode 100644 coverage/core/PlumedMain.cpp.func.html create mode 100644 coverage/core/PlumedMain.cpp.gcov.html create mode 100644 coverage/core/PlumedMain.h.func-sort-c.html create mode 100644 coverage/core/PlumedMain.h.func.html create mode 100644 coverage/core/PlumedMain.h.gcov.html create mode 100644 coverage/core/PlumedMainInitializer.cpp.func-sort-c.html create mode 100644 coverage/core/PlumedMainInitializer.cpp.func.html create mode 100644 coverage/core/PlumedMainInitializer.cpp.gcov.html create mode 100644 coverage/core/RegisterBase.cpp.func-sort-c.html create mode 100644 coverage/core/RegisterBase.cpp.func.html create mode 100644 coverage/core/RegisterBase.cpp.gcov.html create mode 100644 coverage/core/RegisterBase.h.func-sort-c.html create mode 100644 coverage/core/RegisterBase.h.func.html create mode 100644 coverage/core/RegisterBase.h.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/crystdistrib/BopsShortcut.cpp.func-sort-c.html create mode 100644 coverage/crystdistrib/BopsShortcut.cpp.func.html create mode 100644 coverage/crystdistrib/BopsShortcut.cpp.gcov.html create mode 100644 coverage/crystdistrib/DopsShortcut.cpp.func-sort-c.html create mode 100644 coverage/crystdistrib/DopsShortcut.cpp.func.html create mode 100644 coverage/crystdistrib/DopsShortcut.cpp.gcov.html create mode 100644 coverage/crystdistrib/Quaternion.cpp.func-sort-c.html create mode 100644 coverage/crystdistrib/Quaternion.cpp.func.html create mode 100644 coverage/crystdistrib/Quaternion.cpp.gcov.html create mode 100644 coverage/crystdistrib/QuaternionBondProductMatrix.cpp.func-sort-c.html create mode 100644 coverage/crystdistrib/QuaternionBondProductMatrix.cpp.func.html create mode 100644 coverage/crystdistrib/QuaternionBondProductMatrix.cpp.gcov.html create mode 100644 coverage/crystdistrib/QuaternionProductMatrix.cpp.func-sort-c.html create mode 100644 coverage/crystdistrib/QuaternionProductMatrix.cpp.func.html create mode 100644 coverage/crystdistrib/QuaternionProductMatrix.cpp.gcov.html create mode 100644 coverage/crystdistrib/RopsShortcut.cpp.func-sort-c.html create mode 100644 coverage/crystdistrib/RopsShortcut.cpp.func.html create mode 100644 coverage/crystdistrib/RopsShortcut.cpp.gcov.html create mode 100644 coverage/crystdistrib/index-sort-f.html create mode 100644 coverage/crystdistrib/index-sort-l.html create mode 100644 coverage/crystdistrib/index.html create mode 100644 coverage/dimred/ArrangePoints.cpp.func-sort-c.html create mode 100644 coverage/dimred/ArrangePoints.cpp.func.html create mode 100644 coverage/dimred/ArrangePoints.cpp.gcov.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/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/ProjectPoints.cpp.func-sort-c.html create mode 100644 coverage/dimred/ProjectPoints.cpp.func.html create mode 100644 coverage/dimred/ProjectPoints.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/SMACOF.h.func-sort-c.html create mode 100644 coverage/dimred/SMACOF.h.func.html create mode 100644 coverage/dimred/SMACOF.h.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/SketchMapProjection.cpp.func-sort-c.html create mode 100644 coverage/dimred/SketchMapProjection.cpp.func.html create mode 100644 coverage/dimred/SketchMapProjection.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/envsim/EnvironmentSimilarity.cpp.func-sort-c.html create mode 100644 coverage/envsim/EnvironmentSimilarity.cpp.func.html create mode 100644 coverage/envsim/EnvironmentSimilarity.cpp.gcov.html create mode 100644 coverage/envsim/index-sort-f.html create mode 100644 coverage/envsim/index-sort-l.html create mode 100644 coverage/envsim/index.html 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/fourier/FourierTransform.cpp.func-sort-c.html create mode 100644 coverage/fourier/FourierTransform.cpp.func.html create mode 100644 coverage/fourier/FourierTransform.cpp.gcov.html create mode 100644 coverage/fourier/index-sort-f.html create mode 100644 coverage/fourier/index-sort-l.html create mode 100644 coverage/fourier/index.html create mode 100644 coverage/function/Bessel.cpp.func-sort-c.html create mode 100644 coverage/function/Bessel.cpp.func.html create mode 100644 coverage/function/Bessel.cpp.gcov.html create mode 100644 coverage/function/Between.cpp.func-sort-c.html create mode 100644 coverage/function/Between.cpp.func.html create mode 100644 coverage/function/Between.cpp.gcov.html create mode 100644 coverage/function/Between.h.func-sort-c.html create mode 100644 coverage/function/Between.h.func.html create mode 100644 coverage/function/Between.h.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/Combine.h.func-sort-c.html create mode 100644 coverage/function/Combine.h.func.html create mode 100644 coverage/function/Combine.h.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/FunctionOfScalar.h.func-sort-c.html create mode 100644 coverage/function/FunctionOfScalar.h.func.html create mode 100644 coverage/function/FunctionOfScalar.h.gcov.html create mode 100644 coverage/function/FunctionOfVector.h.func-sort-c.html create mode 100644 coverage/function/FunctionOfVector.h.func.html create mode 100644 coverage/function/FunctionOfVector.h.gcov.html create mode 100644 coverage/function/FunctionShortcut.h.func-sort-c.html create mode 100644 coverage/function/FunctionShortcut.h.func.html create mode 100644 coverage/function/FunctionShortcut.h.gcov.html create mode 100644 coverage/function/FunctionTemplateBase.h.func-sort-c.html create mode 100644 coverage/function/FunctionTemplateBase.h.func.html create mode 100644 coverage/function/FunctionTemplateBase.h.gcov.html create mode 100644 coverage/function/Highest.cpp.func-sort-c.html create mode 100644 coverage/function/Highest.cpp.func.html create mode 100644 coverage/function/Highest.cpp.gcov.html create mode 100644 coverage/function/LessThan.cpp.func-sort-c.html create mode 100644 coverage/function/LessThan.cpp.func.html create mode 100644 coverage/function/LessThan.cpp.gcov.html create mode 100644 coverage/function/LessThan.h.func-sort-c.html create mode 100644 coverage/function/LessThan.h.func.html create mode 100644 coverage/function/LessThan.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/Moments.cpp.func-sort-c.html create mode 100644 coverage/function/Moments.cpp.func.html create mode 100644 coverage/function/Moments.cpp.gcov.html create mode 100644 coverage/function/MoreThan.cpp.func-sort-c.html create mode 100644 coverage/function/MoreThan.cpp.func.html create mode 100644 coverage/function/MoreThan.cpp.gcov.html create mode 100644 coverage/function/MoreThan.h.func-sort-c.html create mode 100644 coverage/function/MoreThan.h.func.html create mode 100644 coverage/function/MoreThan.h.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/Product.cpp.func-sort-c.html create mode 100644 coverage/function/Product.cpp.func.html create mode 100644 coverage/function/Product.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/Sum.cpp.func-sort-c.html create mode 100644 coverage/function/Sum.cpp.func.html create mode 100644 coverage/function/Sum.cpp.gcov.html create mode 100644 coverage/function/Sum.h.func-sort-c.html create mode 100644 coverage/function/Sum.h.func.html create mode 100644 coverage/function/Sum.h.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/Constant.cpp.func-sort-c.html create mode 100644 coverage/generic/Constant.cpp.func.html create mode 100644 coverage/generic/Constant.cpp.gcov.html 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/DumpPDB.cpp.func-sort-c.html create mode 100644 coverage/generic/DumpPDB.cpp.func.html create mode 100644 coverage/generic/DumpPDB.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/DumpVector.cpp.func-sort-c.html create mode 100644 coverage/generic/DumpVector.cpp.func.html create mode 100644 coverage/generic/DumpVector.cpp.gcov.html create mode 100644 coverage/generic/EffectiveEnergyDrift.cpp.func-sort-c.html create mode 100644 coverage/generic/EffectiveEnergyDrift.cpp.func.html create mode 100644 coverage/generic/EffectiveEnergyDrift.cpp.gcov.html create mode 100644 coverage/generic/EndPlumed.cpp.func-sort-c.html create mode 100644 coverage/generic/EndPlumed.cpp.func.html create mode 100644 coverage/generic/EndPlumed.cpp.gcov.html create mode 100644 coverage/generic/FitToTemplate.cpp.func-sort-c.html create mode 100644 coverage/generic/FitToTemplate.cpp.func.html create mode 100644 coverage/generic/FitToTemplate.cpp.gcov.html create mode 100644 coverage/generic/Flush.cpp.func-sort-c.html create mode 100644 coverage/generic/Flush.cpp.func.html create mode 100644 coverage/generic/Flush.cpp.gcov.html create mode 100644 coverage/generic/Include.cpp.func-sort-c.html create mode 100644 coverage/generic/Include.cpp.func.html create mode 100644 coverage/generic/Include.cpp.gcov.html create mode 100644 coverage/generic/Ones.cpp.func-sort-c.html create mode 100644 coverage/generic/Ones.cpp.func.html create mode 100644 coverage/generic/Ones.cpp.gcov.html create mode 100644 coverage/generic/PDB2Constant.cpp.func-sort-c.html create mode 100644 coverage/generic/PDB2Constant.cpp.func.html create mode 100644 coverage/generic/PDB2Constant.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/PrintNDX.cpp.func-sort-c.html create mode 100644 coverage/generic/PrintNDX.cpp.func.html create mode 100644 coverage/generic/PrintNDX.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/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/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/EvaluateFunctionOnGrid.cpp.func-sort-c.html create mode 100644 coverage/gridtools/EvaluateFunctionOnGrid.cpp.func.html create mode 100644 coverage/gridtools/EvaluateFunctionOnGrid.cpp.gcov.html create mode 100644 coverage/gridtools/EvaluateGridFunction.cpp.func-sort-c.html create mode 100644 coverage/gridtools/EvaluateGridFunction.cpp.func.html create mode 100644 coverage/gridtools/EvaluateGridFunction.cpp.gcov.html create mode 100644 coverage/gridtools/EvaluateGridFunction.h.func-sort-c.html create mode 100644 coverage/gridtools/EvaluateGridFunction.h.func.html create mode 100644 coverage/gridtools/EvaluateGridFunction.h.gcov.html create mode 100644 coverage/gridtools/FindGridOptimum.cpp.func-sort-c.html create mode 100644 coverage/gridtools/FindGridOptimum.cpp.func.html create mode 100644 coverage/gridtools/FindGridOptimum.cpp.gcov.html create mode 100644 coverage/gridtools/FunctionOfGrid.h.func-sort-c.html create mode 100644 coverage/gridtools/FunctionOfGrid.h.func.html create mode 100644 coverage/gridtools/FunctionOfGrid.h.gcov.html create mode 100644 coverage/gridtools/Gradient.cpp.func-sort-c.html create mode 100644 coverage/gridtools/Gradient.cpp.func.html create mode 100644 coverage/gridtools/Gradient.cpp.gcov.html create mode 100644 coverage/gridtools/GridCoordinatesObject.cpp.func-sort-c.html create mode 100644 coverage/gridtools/GridCoordinatesObject.cpp.func.html create mode 100644 coverage/gridtools/GridCoordinatesObject.cpp.gcov.html create mode 100644 coverage/gridtools/GridCoordinatesObject.h.func-sort-c.html create mode 100644 coverage/gridtools/GridCoordinatesObject.h.func.html create mode 100644 coverage/gridtools/GridCoordinatesObject.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/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/Interpolator.cpp.func-sort-c.html create mode 100644 coverage/gridtools/Interpolator.cpp.func.html create mode 100644 coverage/gridtools/Interpolator.cpp.gcov.html create mode 100644 coverage/gridtools/Interpolator.h.func-sort-c.html create mode 100644 coverage/gridtools/Interpolator.h.func.html create mode 100644 coverage/gridtools/Interpolator.h.gcov.html create mode 100644 coverage/gridtools/KDE.cpp.func-sort-c.html create mode 100644 coverage/gridtools/KDE.cpp.func.html create mode 100644 coverage/gridtools/KDE.cpp.gcov.html create mode 100644 coverage/gridtools/KLEntropy.cpp.func-sort-c.html create mode 100644 coverage/gridtools/KLEntropy.cpp.func.html create mode 100644 coverage/gridtools/KLEntropy.cpp.gcov.html create mode 100644 coverage/gridtools/MultiColvarDensity.cpp.func-sort-c.html create mode 100644 coverage/gridtools/MultiColvarDensity.cpp.func.html create mode 100644 coverage/gridtools/MultiColvarDensity.cpp.gcov.html create mode 100644 coverage/gridtools/PairEntropies.cpp.func-sort-c.html create mode 100644 coverage/gridtools/PairEntropies.cpp.func.html create mode 100644 coverage/gridtools/PairEntropies.cpp.gcov.html create mode 100644 coverage/gridtools/PairEntropy.cpp.func-sort-c.html create mode 100644 coverage/gridtools/PairEntropy.cpp.func.html create mode 100644 coverage/gridtools/PairEntropy.cpp.gcov.html create mode 100644 coverage/gridtools/RDF.cpp.func-sort-c.html create mode 100644 coverage/gridtools/RDF.cpp.func.html create mode 100644 coverage/gridtools/RDF.cpp.gcov.html create mode 100644 coverage/gridtools/ReadGridInSetup.cpp.func-sort-c.html create mode 100644 coverage/gridtools/ReadGridInSetup.cpp.func.html create mode 100644 coverage/gridtools/ReadGridInSetup.cpp.gcov.html create mode 100644 coverage/gridtools/index-sort-f.html create mode 100644 coverage/gridtools/index-sort-l.html create mode 100644 coverage/gridtools/index.html create mode 100644 coverage/index-sort-f.html create mode 100644 coverage/index-sort-l.html create mode 100644 coverage/index.html create mode 100644 coverage/isdb/CS2Backbone.cpp.func-sort-c.html create mode 100644 coverage/isdb/CS2Backbone.cpp.func.html create mode 100644 coverage/isdb/CS2Backbone.cpp.gcov.html create mode 100644 coverage/isdb/Caliber.cpp.func-sort-c.html create mode 100644 coverage/isdb/Caliber.cpp.func.html create mode 100644 coverage/isdb/Caliber.cpp.gcov.html create mode 100644 coverage/isdb/EMMI.cpp.func-sort-c.html create mode 100644 coverage/isdb/EMMI.cpp.func.html create mode 100644 coverage/isdb/EMMI.cpp.gcov.html create mode 100644 coverage/isdb/EMMIVox.cpp.func-sort-c.html create mode 100644 coverage/isdb/EMMIVox.cpp.func.html create mode 100644 coverage/isdb/EMMIVox.cpp.gcov.html create mode 100644 coverage/isdb/FretEfficiency.cpp.func-sort-c.html create mode 100644 coverage/isdb/FretEfficiency.cpp.func.html create mode 100644 coverage/isdb/FretEfficiency.cpp.gcov.html create mode 100644 coverage/isdb/Jcoupling.cpp.func-sort-c.html create mode 100644 coverage/isdb/Jcoupling.cpp.func.html create mode 100644 coverage/isdb/Jcoupling.cpp.gcov.html create mode 100644 coverage/isdb/Metainference.cpp.func-sort-c.html create mode 100644 coverage/isdb/Metainference.cpp.func.html create mode 100644 coverage/isdb/Metainference.cpp.gcov.html create mode 100644 coverage/isdb/MetainferenceBase.cpp.func-sort-c.html create mode 100644 coverage/isdb/MetainferenceBase.cpp.func.html create mode 100644 coverage/isdb/MetainferenceBase.cpp.gcov.html create mode 100644 coverage/isdb/MetainferenceBase.h.func-sort-c.html create mode 100644 coverage/isdb/MetainferenceBase.h.func.html create mode 100644 coverage/isdb/MetainferenceBase.h.gcov.html create mode 100644 coverage/isdb/NOE.cpp.func-sort-c.html create mode 100644 coverage/isdb/NOE.cpp.func.html create mode 100644 coverage/isdb/NOE.cpp.gcov.html create mode 100644 coverage/isdb/PRE.cpp.func-sort-c.html create mode 100644 coverage/isdb/PRE.cpp.func.html create mode 100644 coverage/isdb/PRE.cpp.gcov.html create mode 100644 coverage/isdb/RDC.cpp.func-sort-c.html create mode 100644 coverage/isdb/RDC.cpp.func.html create mode 100644 coverage/isdb/RDC.cpp.gcov.html create mode 100644 coverage/isdb/Rescale.cpp.func-sort-c.html create mode 100644 coverage/isdb/Rescale.cpp.func.html create mode 100644 coverage/isdb/Rescale.cpp.gcov.html create mode 100644 coverage/isdb/SAXS.cpp.func-sort-c.html create mode 100644 coverage/isdb/SAXS.cpp.func.html create mode 100644 coverage/isdb/SAXS.cpp.gcov.html create mode 100644 coverage/isdb/Select.cpp.func-sort-c.html create mode 100644 coverage/isdb/Select.cpp.func.html create mode 100644 coverage/isdb/Select.cpp.gcov.html create mode 100644 coverage/isdb/Selector.cpp.func-sort-c.html create mode 100644 coverage/isdb/Selector.cpp.func.html create mode 100644 coverage/isdb/Selector.cpp.gcov.html create mode 100644 coverage/isdb/Shadow.cpp.func-sort-c.html create mode 100644 coverage/isdb/Shadow.cpp.func.html create mode 100644 coverage/isdb/Shadow.cpp.gcov.html create mode 100644 coverage/isdb/index-sort-f.html create mode 100644 coverage/isdb/index-sort-l.html create mode 100644 coverage/isdb/index.html create mode 100644 coverage/logmfd/LogMFD.cpp.func-sort-c.html create mode 100644 coverage/logmfd/LogMFD.cpp.func.html create mode 100644 coverage/logmfd/LogMFD.cpp.gcov.html create mode 100644 coverage/logmfd/index-sort-f.html create mode 100644 coverage/logmfd/index-sort-l.html create mode 100644 coverage/logmfd/index.html create mode 100644 coverage/main/index-sort-f.html create mode 100644 coverage/main/index-sort-l.html create mode 100644 coverage/main/index.html create mode 100644 coverage/main/main.cpp.func-sort-c.html create mode 100644 coverage/main/main.cpp.func.html create mode 100644 coverage/main/main.cpp.gcov.html create mode 100644 coverage/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/GeometricPath.cpp.func-sort-c.html create mode 100644 coverage/mapping/GeometricPath.cpp.func.html create mode 100644 coverage/mapping/GeometricPath.cpp.gcov.html create mode 100644 coverage/mapping/GeometricPathShortcut.cpp.func-sort-c.html create mode 100644 coverage/mapping/GeometricPathShortcut.cpp.func.html create mode 100644 coverage/mapping/GeometricPathShortcut.cpp.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/PathDisplacements.cpp.func-sort-c.html create mode 100644 coverage/mapping/PathDisplacements.cpp.func.html create mode 100644 coverage/mapping/PathDisplacements.cpp.gcov.html create mode 100644 coverage/mapping/PathProjectionCalculator.cpp.func-sort-c.html create mode 100644 coverage/mapping/PathProjectionCalculator.cpp.func.html create mode 100644 coverage/mapping/PathProjectionCalculator.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/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/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/CoordAngles.cpp.func-sort-c.html create mode 100644 coverage/multicolvar/CoordAngles.cpp.func.html create mode 100644 coverage/multicolvar/CoordAngles.cpp.gcov.html create mode 100644 coverage/multicolvar/Dihcor.cpp.func-sort-c.html create mode 100644 coverage/multicolvar/Dihcor.cpp.func.html create mode 100644 coverage/multicolvar/Dihcor.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/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/MFilterLess.cpp.func-sort-c.html create mode 100644 coverage/multicolvar/MFilterLess.cpp.func.html create mode 100644 coverage/multicolvar/MFilterLess.cpp.gcov.html create mode 100644 coverage/multicolvar/MFilterMore.cpp.func-sort-c.html create mode 100644 coverage/multicolvar/MFilterMore.cpp.func.html create mode 100644 coverage/multicolvar/MFilterMore.cpp.gcov.html create mode 100644 coverage/multicolvar/MultiColvarShortcuts.cpp.func-sort-c.html create mode 100644 coverage/multicolvar/MultiColvarShortcuts.cpp.func.html create mode 100644 coverage/multicolvar/MultiColvarShortcuts.cpp.gcov.html create mode 100644 coverage/multicolvar/Planes.cpp.func-sort-c.html create mode 100644 coverage/multicolvar/Planes.cpp.func.html create mode 100644 coverage/multicolvar/Planes.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/UWalls.cpp.func-sort-c.html create mode 100644 coverage/multicolvar/UWalls.cpp.func.html create mode 100644 coverage/multicolvar/UWalls.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/XYTorsions.cpp.func-sort-c.html create mode 100644 coverage/multicolvar/XYTorsions.cpp.func.html create mode 100644 coverage/multicolvar/XYTorsions.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/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/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/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/refdist/Difference.cpp.func-sort-c.html create mode 100644 coverage/refdist/Difference.cpp.func.html create mode 100644 coverage/refdist/Difference.cpp.gcov.html create mode 100644 coverage/refdist/Displacement.cpp.func-sort-c.html create mode 100644 coverage/refdist/Displacement.cpp.func.html create mode 100644 coverage/refdist/Displacement.cpp.gcov.html create mode 100644 coverage/refdist/EuclideanDistance.cpp.func-sort-c.html create mode 100644 coverage/refdist/EuclideanDistance.cpp.func.html create mode 100644 coverage/refdist/EuclideanDistance.cpp.gcov.html create mode 100644 coverage/refdist/Kernel.cpp.func-sort-c.html create mode 100644 coverage/refdist/Kernel.cpp.func.html create mode 100644 coverage/refdist/Kernel.cpp.gcov.html create mode 100644 coverage/refdist/MahalanobisDistance.cpp.func-sort-c.html create mode 100644 coverage/refdist/MahalanobisDistance.cpp.func.html create mode 100644 coverage/refdist/MahalanobisDistance.cpp.gcov.html create mode 100644 coverage/refdist/MatrixProductDiagonal.cpp.func-sort-c.html create mode 100644 coverage/refdist/MatrixProductDiagonal.cpp.func.html create mode 100644 coverage/refdist/MatrixProductDiagonal.cpp.gcov.html create mode 100644 coverage/refdist/NormalizedEuclideanDistance.cpp.func-sort-c.html create mode 100644 coverage/refdist/NormalizedEuclideanDistance.cpp.func.html create mode 100644 coverage/refdist/NormalizedEuclideanDistance.cpp.gcov.html create mode 100644 coverage/refdist/index-sort-f.html create mode 100644 coverage/refdist/index-sort-l.html create mode 100644 coverage/refdist/index.html create mode 100644 coverage/ruby.png create mode 100644 coverage/s2cm/S2ContactModel.cpp.func-sort-c.html create mode 100644 coverage/s2cm/S2ContactModel.cpp.func.html create mode 100644 coverage/s2cm/S2ContactModel.cpp.gcov.html create mode 100644 coverage/s2cm/index-sort-f.html create mode 100644 coverage/s2cm/index-sort-l.html create mode 100644 coverage/s2cm/index.html create mode 100644 coverage/sasa/index-sort-f.html create mode 100644 coverage/sasa/index-sort-l.html create mode 100644 coverage/sasa/index.html create mode 100644 coverage/sasa/sasa_HASEL.cpp.func-sort-c.html create mode 100644 coverage/sasa/sasa_HASEL.cpp.func.html create mode 100644 coverage/sasa/sasa_HASEL.cpp.gcov.html create mode 100644 coverage/sasa/sasa_LCPO.cpp.func-sort-c.html create mode 100644 coverage/sasa/sasa_LCPO.cpp.func.html create mode 100644 coverage/sasa/sasa_LCPO.cpp.gcov.html create mode 100644 coverage/secondarystructure/AlphaRMSD.cpp.func-sort-c.html create mode 100644 coverage/secondarystructure/AlphaRMSD.cpp.func.html create mode 100644 coverage/secondarystructure/AlphaRMSD.cpp.gcov.html create mode 100644 coverage/secondarystructure/AntibetaRMSD.cpp.func-sort-c.html create mode 100644 coverage/secondarystructure/AntibetaRMSD.cpp.func.html create mode 100644 coverage/secondarystructure/AntibetaRMSD.cpp.gcov.html create mode 100644 coverage/secondarystructure/ParabetaRMSD.cpp.func-sort-c.html create mode 100644 coverage/secondarystructure/ParabetaRMSD.cpp.func.html create mode 100644 coverage/secondarystructure/ParabetaRMSD.cpp.gcov.html create mode 100644 coverage/secondarystructure/SecondaryStructureRMSD.cpp.func-sort-c.html create mode 100644 coverage/secondarystructure/SecondaryStructureRMSD.cpp.func.html create mode 100644 coverage/secondarystructure/SecondaryStructureRMSD.cpp.gcov.html create mode 100644 coverage/secondarystructure/SecondaryStructureRMSD.h.func-sort-c.html create mode 100644 coverage/secondarystructure/SecondaryStructureRMSD.h.func.html create mode 100644 coverage/secondarystructure/SecondaryStructureRMSD.h.gcov.html create mode 100644 coverage/secondarystructure/index-sort-f.html create mode 100644 coverage/secondarystructure/index-sort-l.html create mode 100644 coverage/secondarystructure/index.html create mode 100644 coverage/setup/Load.cpp.func-sort-c.html create mode 100644 coverage/setup/Load.cpp.func.html create mode 100644 coverage/setup/Load.cpp.gcov.html create mode 100644 coverage/setup/Restart.cpp.func-sort-c.html create mode 100644 coverage/setup/Restart.cpp.func.html create mode 100644 coverage/setup/Restart.cpp.gcov.html create mode 100644 coverage/setup/Units.cpp.func-sort-c.html create mode 100644 coverage/setup/Units.cpp.func.html create mode 100644 coverage/setup/Units.cpp.gcov.html create mode 100644 coverage/setup/index-sort-f.html create mode 100644 coverage/setup/index-sort-l.html create mode 100644 coverage/setup/index.html create mode 100644 coverage/small_vector/index-sort-f.html create mode 100644 coverage/small_vector/index-sort-l.html create mode 100644 coverage/small_vector/index.html create mode 100644 coverage/small_vector/small_vector.h.func-sort-c.html create mode 100644 coverage/small_vector/small_vector.h.func.html create mode 100644 coverage/small_vector/small_vector.h.gcov.html create mode 100644 coverage/snow.png create mode 100644 coverage/symfunc/AngularTetra.cpp.func-sort-c.html create mode 100644 coverage/symfunc/AngularTetra.cpp.func.html create mode 100644 coverage/symfunc/AngularTetra.cpp.gcov.html create mode 100644 coverage/symfunc/AtomicSMAC.cpp.func-sort-c.html create mode 100644 coverage/symfunc/AtomicSMAC.cpp.func.html create mode 100644 coverage/symfunc/AtomicSMAC.cpp.gcov.html create mode 100644 coverage/symfunc/CoordShellVectorFunction.cpp.func-sort-c.html create mode 100644 coverage/symfunc/CoordShellVectorFunction.cpp.func.html create mode 100644 coverage/symfunc/CoordShellVectorFunction.cpp.gcov.html create mode 100644 coverage/symfunc/CoordinationNumbers.cpp.func-sort-c.html create mode 100644 coverage/symfunc/CoordinationNumbers.cpp.func.html create mode 100644 coverage/symfunc/CoordinationNumbers.cpp.gcov.html create mode 100644 coverage/symfunc/CylindricalHarmonic.cpp.func-sort-c.html create mode 100644 coverage/symfunc/CylindricalHarmonic.cpp.func.html create mode 100644 coverage/symfunc/CylindricalHarmonic.cpp.gcov.html create mode 100644 coverage/symfunc/Fccubic.cpp.func-sort-c.html create mode 100644 coverage/symfunc/Fccubic.cpp.func.html create mode 100644 coverage/symfunc/Fccubic.cpp.gcov.html create mode 100644 coverage/symfunc/HexaticParameter.cpp.func-sort-c.html create mode 100644 coverage/symfunc/HexaticParameter.cpp.func.html create mode 100644 coverage/symfunc/HexaticParameter.cpp.gcov.html create mode 100644 coverage/symfunc/LocalAverage.cpp.func-sort-c.html create mode 100644 coverage/symfunc/LocalAverage.cpp.func.html create mode 100644 coverage/symfunc/LocalAverage.cpp.gcov.html create mode 100644 coverage/symfunc/LocalCrystalinity.cpp.func-sort-c.html create mode 100644 coverage/symfunc/LocalCrystalinity.cpp.func.html create mode 100644 coverage/symfunc/LocalCrystalinity.cpp.gcov.html create mode 100644 coverage/symfunc/LocalSteinhardt.cpp.func-sort-c.html create mode 100644 coverage/symfunc/LocalSteinhardt.cpp.func.html create mode 100644 coverage/symfunc/LocalSteinhardt.cpp.gcov.html create mode 100644 coverage/symfunc/RadialTetra.cpp.func-sort-c.html create mode 100644 coverage/symfunc/RadialTetra.cpp.func.html create mode 100644 coverage/symfunc/RadialTetra.cpp.gcov.html create mode 100644 coverage/symfunc/SMAC.cpp.func-sort-c.html create mode 100644 coverage/symfunc/SMAC.cpp.func.html create mode 100644 coverage/symfunc/SMAC.cpp.gcov.html create mode 100644 coverage/symfunc/SphericalHarmonic.cpp.func-sort-c.html create mode 100644 coverage/symfunc/SphericalHarmonic.cpp.func.html create mode 100644 coverage/symfunc/SphericalHarmonic.cpp.gcov.html create mode 100644 coverage/symfunc/Steinhardt.cpp.func-sort-c.html create mode 100644 coverage/symfunc/Steinhardt.cpp.func.html create mode 100644 coverage/symfunc/Steinhardt.cpp.gcov.html create mode 100644 coverage/symfunc/ThreeBodyGFunctions.cpp.func-sort-c.html create mode 100644 coverage/symfunc/ThreeBodyGFunctions.cpp.func.html create mode 100644 coverage/symfunc/ThreeBodyGFunctions.cpp.gcov.html create mode 100644 coverage/symfunc/index-sort-f.html create mode 100644 coverage/symfunc/index-sort-l.html create mode 100644 coverage/symfunc/index.html 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/CheckInRange.cpp.func-sort-c.html create mode 100644 coverage/tools/CheckInRange.cpp.func.html create mode 100644 coverage/tools/CheckInRange.cpp.gcov.html create mode 100644 coverage/tools/CheckInRange.h.func-sort-c.html create mode 100644 coverage/tools/CheckInRange.h.func.html create mode 100644 coverage/tools/CheckInRange.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/LeptonCall.cpp.func-sort-c.html create mode 100644 coverage/tools/LeptonCall.cpp.func.html create mode 100644 coverage/tools/LeptonCall.cpp.gcov.html create mode 100644 coverage/tools/LeptonCall.h.func-sort-c.html create mode 100644 coverage/tools/LeptonCall.h.func.html create mode 100644 coverage/tools/LeptonCall.h.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/MergeVectorTools.h.func-sort-c.html create mode 100644 coverage/tools/MergeVectorTools.h.func.html create mode 100644 coverage/tools/MergeVectorTools.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/SwitchingFunction.h.func-sort-c.html create mode 100644 coverage/tools/SwitchingFunction.h.func.html create mode 100644 coverage/tools/SwitchingFunction.h.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/valtools/Concatenate.cpp.func-sort-c.html create mode 100644 coverage/valtools/Concatenate.cpp.func.html create mode 100644 coverage/valtools/Concatenate.cpp.gcov.html create mode 100644 coverage/valtools/Flatten.cpp.func-sort-c.html create mode 100644 coverage/valtools/Flatten.cpp.func.html create mode 100644 coverage/valtools/Flatten.cpp.gcov.html create mode 100644 coverage/valtools/SelectComponents.cpp.func-sort-c.html create mode 100644 coverage/valtools/SelectComponents.cpp.func.html create mode 100644 coverage/valtools/SelectComponents.cpp.gcov.html create mode 100644 coverage/valtools/SelectWithMask.cpp.func-sort-c.html create mode 100644 coverage/valtools/SelectWithMask.cpp.func.html create mode 100644 coverage/valtools/SelectWithMask.cpp.gcov.html create mode 100644 coverage/valtools/index-sort-f.html create mode 100644 coverage/valtools/index-sort-l.html create mode 100644 coverage/valtools/index.html create mode 100644 coverage/vatom/ArgsToVatom.cpp.func-sort-c.html create mode 100644 coverage/vatom/ArgsToVatom.cpp.func.html create mode 100644 coverage/vatom/ArgsToVatom.cpp.gcov.html 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/CenterShortcut.cpp.func-sort-c.html create mode 100644 coverage/vatom/CenterShortcut.cpp.func.html create mode 100644 coverage/vatom/CenterShortcut.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/volumes/ActionVolume.cpp.func-sort-c.html create mode 100644 coverage/volumes/ActionVolume.cpp.func.html create mode 100644 coverage/volumes/ActionVolume.cpp.gcov.html create mode 100644 coverage/volumes/ActionVolume.h.func-sort-c.html create mode 100644 coverage/volumes/ActionVolume.h.func.html create mode 100644 coverage/volumes/ActionVolume.h.gcov.html create mode 100644 coverage/volumes/Density.cpp.func-sort-c.html create mode 100644 coverage/volumes/Density.cpp.func.html create mode 100644 coverage/volumes/Density.cpp.gcov.html create mode 100644 coverage/volumes/VolumeAround.cpp.func-sort-c.html create mode 100644 coverage/volumes/VolumeAround.cpp.func.html create mode 100644 coverage/volumes/VolumeAround.cpp.gcov.html create mode 100644 coverage/volumes/VolumeBetweenContours.cpp.func-sort-c.html create mode 100644 coverage/volumes/VolumeBetweenContours.cpp.func.html create mode 100644 coverage/volumes/VolumeBetweenContours.cpp.gcov.html create mode 100644 coverage/volumes/VolumeCavity.cpp.func-sort-c.html create mode 100644 coverage/volumes/VolumeCavity.cpp.func.html create mode 100644 coverage/volumes/VolumeCavity.cpp.gcov.html create mode 100644 coverage/volumes/VolumeInCylinder.cpp.func-sort-c.html create mode 100644 coverage/volumes/VolumeInCylinder.cpp.func.html create mode 100644 coverage/volumes/VolumeInCylinder.cpp.gcov.html create mode 100644 coverage/volumes/VolumeInSphere.cpp.func-sort-c.html create mode 100644 coverage/volumes/VolumeInSphere.cpp.func.html create mode 100644 coverage/volumes/VolumeInSphere.cpp.gcov.html create mode 100644 coverage/volumes/VolumeShortcut.h.func-sort-c.html create mode 100644 coverage/volumes/VolumeShortcut.h.func.html create mode 100644 coverage/volumes/VolumeShortcut.h.gcov.html create mode 100644 coverage/volumes/VolumeTetrapore.cpp.func-sort-c.html create mode 100644 coverage/volumes/VolumeTetrapore.cpp.func.html create mode 100644 coverage/volumes/VolumeTetrapore.cpp.gcov.html create mode 100644 coverage/volumes/index-sort-f.html create mode 100644 coverage/volumes/index-sort-l.html create mode 100644 coverage/volumes/index.html create mode 100644 coverage/wrapper/Plumed.h.func-sort-c.html create mode 100644 coverage/wrapper/Plumed.h.func.html create mode 100644 coverage/wrapper/Plumed.h.gcov.html create mode 100644 coverage/wrapper/index-sort-f.html create mode 100644 coverage/wrapper/index-sort-l.html create mode 100644 coverage/wrapper/index.html create mode 100644 index.html diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/README.md b/README.md new file mode 100644 index 000000000000..34926e9cb6e6 --- /dev/null +++ b/README.md @@ -0,0 +1,12 @@ +Coverage scan for PLUMED master +----------------------------- + +This repository hosts the coverage scan for [PLUMED](http://www.plumed.org) master, +git revision [1daf1a9](https://github.com/plumed/plumed2/commit/1daf1a9). + +Coverage scan done on [GiHub actions](http://github.com/plumed/plumed2/actions) on Fri Apr 19 12:12:37 UTC 2024. + +To browse the scan you should go [here](http://plumed.github.io/coverage-master). + +You can also download a full copy of the scan for offline access +at [this link](http://github.com/plumed/coverage-master/archive/gh-pages.zip). diff --git a/coverage-libs/amber.png b/coverage-libs/amber.png new file mode 100644 index 0000000000000000000000000000000000000000..2cab170d8359081983a4e343848dfe06bc490f12 GIT binary patch literal 141 zcmeAS@N?(olHy`uVBq!ia0vp^j3CU&3?x-=hn)ga>?NMQuI!iC1^G2tW}LqE04T&+ z;1OBOz`!j8!i<;h*8KqrvZOouIx;Y9?C1WI$O`1M1^9%x{(levWG + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/arch.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - arch.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:254062.5 %
Date:2024-04-19 12:12:36Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit8ArchInfo4initEjj256
_ZN4PLMD6asmjit9ArchUtils15typeIdToRegInfoEjRjRNS0_7RegInfoE315112
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/arch.cpp.func.html b/coverage-libs/asmjit/arch.cpp.func.html new file mode 100644 index 000000000000..01836cc9112d --- /dev/null +++ b/coverage-libs/asmjit/arch.cpp.func.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/arch.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - arch.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:254062.5 %
Date:2024-04-19 12:12:36Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit8ArchInfo4initEjj256
_ZN4PLMD6asmjit9ArchUtils15typeIdToRegInfoEjRjRNS0_7RegInfoE315112
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/arch.cpp.gcov.html b/coverage-libs/asmjit/arch.cpp.gcov.html new file mode 100644 index 000000000000..55301302a51d --- /dev/null +++ b/coverage-libs/asmjit/arch.cpp.gcov.html @@ -0,0 +1,264 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/arch.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - arch.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:254062.5 %
Date:2024-04-19 12:12:36Functions: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         256 : ASMJIT_FAVOR_SIZE void ArchInfo::init(uint32_t type, uint32_t subType) noexcept {
+      62         256 :   uint32_t index = type < ASMJIT_ARRAY_SIZE(archInfoTable) ? type : uint32_t(0);
+      63             : 
+      64             :   // Make sure the `archInfoTable` array is correctly indexed.
+      65         256 :   _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         256 :   _type = type;
+      71         256 :   _subType = subType;
+      72         256 : }
+      73             : 
+      74             : // ============================================================================
+      75             : // [asmjit::ArchUtils]
+      76             : // ============================================================================
+      77             : 
+      78      315112 : ASMJIT_FAVOR_SIZE Error ArchUtils::typeIdToRegInfo(uint32_t archType, uint32_t& typeIdInOut, RegInfo& regInfo) noexcept {
+      79      315112 :   uint32_t typeId = typeIdInOut;
+      80             : 
+      81             :   // Zero the signature so it's clear in case that typeId is not invalid.
+      82      315112 :   regInfo._signature = 0;
+      83             : 
+      84             : #if defined(ASMJIT_BUILD_X86)
+      85      315112 :   if (ArchInfo::isX86Family(archType)) {
+      86             :     // Passed RegType instead of TypeId?
+      87      315112 :     if (typeId <= Reg::kRegMax)
+      88           0 :       typeId = x86OpData.archRegs.regTypeToTypeId[typeId];
+      89             : 
+      90      315112 :     if (ASMJIT_UNLIKELY(!TypeId::isValid(typeId)))
+      91             :       return DebugUtils::errored(kErrorInvalidTypeId);
+      92             : 
+      93             :     // First normalize architecture dependent types.
+      94      315112 :     if (TypeId::isAbstract(typeId)) {
+      95      104670 :       if (typeId == TypeId::kIntPtr)
+      96      104670 :         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      315112 :     if (ASMJIT_UNLIKELY(!size))
+     105             :       return DebugUtils::errored(kErrorInvalidTypeId);
+     106             : 
+     107      315112 :     if (ASMJIT_UNLIKELY(typeId == TypeId::kF80))
+     108             :       return DebugUtils::errored(kErrorInvalidUseOfF80);
+     109             : 
+     110             :     uint32_t regType = 0;
+     111             : 
+     112      315112 :     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      104670 :       case TypeId::kI64:
+     129             :       case TypeId::kU64:
+     130      104670 :         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      210442 :       default:
+     163      210442 :         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      315112 :     typeIdInOut = typeId;
+     173      315112 :     regInfo._signature = x86OpData.archRegs.regInfo[regType].getSignature();
+     174      315112 :     return kErrorOk;
+     175             :   }
+     176             : #endif // ASMJIT_BUILD_X86
+     177             : 
+     178             :   return DebugUtils::errored(kErrorInvalidArch);
+     179             : }
+     180             : 
+     181             : } // asmjit namespace
+     182             : } // namespace PLMD
+     183             : 
+     184             : // [Api-End]
+     185             : #include "./asmjit_apiend.h"
+     186             : #pragma GCC diagnostic pop
+     187             : #endif // __PLUMED_HAS_ASMJIT
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/arch.h.func-sort-c.html b/coverage-libs/asmjit/arch.h.func-sort-c.html new file mode 100644 index 000000000000..efc8fa4e0c26 --- /dev/null +++ b/coverage-libs/asmjit/arch.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/arch.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - arch.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:6875.0 %
Date:2024-04-19 12:12:36Functions:00-
+
+ +
+ + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/arch.h.gcov.html b/coverage-libs/asmjit/arch.h.gcov.html new file mode 100644 index 000000000000..a794076261af --- /dev/null +++ b/coverage-libs/asmjit/arch.h.gcov.html @@ -0,0 +1,305 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/arch.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - arch.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:6875.0 %
Date:2024-04-19 12:12:36Functions: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      442692 :   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      127866 :   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       31895 :   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      442692 :   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       63790 :   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       31895 :   ASMJIT_INLINE uint32_t getGpSize() const noexcept { return _gpSize; }
+     168             :   //! Get number of general-purpose registers.
+     169             :   ASMJIT_INLINE uint32_t getGpCount() const noexcept { return _gpCount; }
+     170             : 
+     171             :   // --------------------------------------------------------------------------
+     172             :   // [Operator Overload]
+     173             :   // --------------------------------------------------------------------------
+     174             : 
+     175             :   ASMJIT_INLINE ArchInfo& operator=(const ArchInfo& other) noexcept = default;
+     176             :   ASMJIT_INLINE bool operator==(const ArchInfo& other) const noexcept { return _signature == other._signature; }
+     177             :   ASMJIT_INLINE bool operator!=(const ArchInfo& other) const noexcept { return _signature != other._signature; }
+     178             : 
+     179             :   // --------------------------------------------------------------------------
+     180             :   // [Members]
+     181             :   // --------------------------------------------------------------------------
+     182             : 
+     183             :   union {
+     184             :     struct {
+     185             :       uint8_t _type;                     //!< Architecture type.
+     186             :       uint8_t _subType;                  //!< Architecture sub-type.
+     187             :       uint8_t _gpSize;                   //!< Default size of a general purpose register.
+     188             :       uint8_t _gpCount;                  //!< Count of all general purpose registers.
+     189             :     };
+     190             :     uint32_t _signature;                 //!< Architecture signature (32-bit int).
+     191             :   };
+     192             : };
+     193             : 
+     194             : // ============================================================================
+     195             : // [asmjit::ArchRegs]
+     196             : // ============================================================================
+     197             : 
+     198             : //! Information about all architecture registers.
+     199             : struct ArchRegs {
+     200             :   //! Register information and signatures indexed by \ref Reg::Type.
+     201             :   RegInfo regInfo[Reg::kRegMax + 1];
+     202             :   //! Count (maximum) of registers per \ref Reg::Type.
+     203             :   uint8_t regCount[Reg::kRegMax + 1];
+     204             :   //! Converts RegType to TypeId, see \ref TypeId::Id.
+     205             :   uint8_t regTypeToTypeId[Reg::kRegMax + 1];
+     206             : };
+     207             : 
+     208             : // ============================================================================
+     209             : // [asmjit::ArchUtils]
+     210             : // ============================================================================
+     211             : 
+     212             : struct ArchUtils {
+     213             :   ASMJIT_API static Error typeIdToRegInfo(uint32_t archType, uint32_t& typeIdInOut, RegInfo& regInfo) noexcept;
+     214             : };
+     215             : 
+     216             : //! \}
+     217             : 
+     218             : } // asmjit namespace
+     219             : } // namespace PLMD
+     220             : 
+     221             : // [Api-End]
+     222             : #include "./asmjit_apiend.h"
+     223             : 
+     224             : // [Guard]
+     225             : #endif // _ASMJIT_BASE_ARCH_H
+     226             : #pragma GCC diagnostic pop
+     227             : #endif // __PLUMED_HAS_ASMJIT
+     228             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/assembler.cpp.func-sort-c.html b/coverage-libs/asmjit/assembler.cpp.func-sort-c.html new file mode 100644 index 000000000000..cf829435c8a9 --- /dev/null +++ b/coverage-libs/asmjit/assembler.cpp.func-sort-c.html @@ -0,0 +1,145 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/assembler.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - assembler.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:4017423.0 %
Date:2024-04-19 12:12:36Functions: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_10CodeHolderE31895
_ZN4PLMD6asmjit9AssemblerC2Ev31895
_ZN4PLMD6asmjit9AssemblerD2Ev31895
_ZN4PLMD6asmjit9Assembler4bindERKNS0_5LabelE63790
_ZN4PLMD6asmjit9Assembler4syncEv63790
_ZN4PLMD6asmjit9Assembler12_emitOpArrayEjPKNS0_8Operand_Em587564
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/assembler.cpp.func.html b/coverage-libs/asmjit/assembler.cpp.func.html new file mode 100644 index 000000000000..c136394ed536 --- /dev/null +++ b/coverage-libs/asmjit/assembler.cpp.func.html @@ -0,0 +1,145 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/assembler.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - assembler.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:4017423.0 %
Date:2024-04-19 12:12:36Functions: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_Em587564
_ZN4PLMD6asmjit9Assembler13newNamedLabelEPKcmjj0
_ZN4PLMD6asmjit9Assembler14embedConstPoolERKNS0_5LabelERKNS0_9ConstPoolE0
_ZN4PLMD6asmjit9Assembler4bindERKNS0_5LabelE63790
_ZN4PLMD6asmjit9Assembler4syncEv63790
_ZN4PLMD6asmjit9Assembler5_emitEjRKNS0_8Operand_ES4_S4_S4_S4_S4_0
_ZN4PLMD6asmjit9Assembler5embedEPKvj0
_ZN4PLMD6asmjit9Assembler7commentEPKcm0
_ZN4PLMD6asmjit9Assembler8_emitLogEjjRKNS0_8Operand_ES4_S4_S4_jjPh0
_ZN4PLMD6asmjit9Assembler8newLabelEv0
_ZN4PLMD6asmjit9Assembler8onAttachEPNS0_10CodeHolderE31895
_ZN4PLMD6asmjit9Assembler8onDetachEPNS0_10CodeHolderE0
_ZN4PLMD6asmjit9Assembler9setOffsetEm0
_ZN4PLMD6asmjit9AssemblerC2Ev31895
_ZN4PLMD6asmjit9AssemblerD0Ev0
_ZN4PLMD6asmjit9AssemblerD2Ev31895
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/assembler.cpp.gcov.html b/coverage-libs/asmjit/assembler.cpp.gcov.html new file mode 100644 index 000000000000..31e1d1923053 --- /dev/null +++ b/coverage-libs/asmjit/assembler.cpp.gcov.html @@ -0,0 +1,550 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/assembler.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - assembler.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:4017423.0 %
Date:2024-04-19 12:12:36Functions: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       31895 : Assembler::Assembler() noexcept
+      49             :   : CodeEmitter(kTypeAssembler),
+      50       31895 :     _section(nullptr),
+      51       31895 :     _bufferData(nullptr),
+      52       31895 :     _bufferEnd(nullptr),
+      53       31895 :     _bufferPtr(nullptr),
+      54       31895 :     _op4(),
+      55       31895 :     _op5() {}
+      56             : 
+      57       31895 : Assembler::~Assembler() noexcept {
+      58       31895 :   if (_code) sync();
+      59       31895 : }
+      60             : 
+      61             : // ============================================================================
+      62             : // [asmjit::Assembler - Events]
+      63             : // ============================================================================
+      64             : 
+      65       31895 : Error Assembler::onAttach(CodeHolder* code) noexcept {
+      66             :   // Attach to the end of the .text section.
+      67       31895 :   _section = code->_sections[0];
+      68       31895 :   uint8_t* p = _section->_buffer._data;
+      69             : 
+      70       31895 :   _bufferData = p;
+      71       31895 :   _bufferEnd  = p + _section->_buffer._capacity;
+      72       31895 :   _bufferPtr  = p + _section->_buffer._length;
+      73             : 
+      74             :   _op4.reset();
+      75             :   _op5.reset();
+      76             : 
+      77       31895 :   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      587564 : Error Assembler::_emitOpArray(uint32_t instId, const Operand_* opArray, size_t opCount) {
+     104             :   const Operand_* op = opArray;
+     105      587564 :   switch (opCount) {
+     106       31895 :     case 0: return _emit(instId, _none, _none, _none, _none);
+     107       26962 :     case 1: return _emit(instId, op[0], _none, _none, _none);
+     108      526437 :     case 2: return _emit(instId, op[0], op[1], _none, _none);
+     109        2270 :     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       63790 : 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       63790 :   size_t offset = (size_t)(_bufferPtr - _bufferData);
+     140       63790 :   if (_section->getBuffer().getLength() < offset)
+     141       31895 :     _section->_buffer._length = offset;
+     142       63790 : }
+     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       63790 : Error Assembler::bind(const Label& label) {
+     212       63790 :   if (_lastError) return _lastError;
+     213             :   ASMJIT_ASSERT(_code != nullptr);
+     214             : 
+     215       63790 :   LabelEntry* le = _code->getLabelEntry(label);
+     216       63790 :   if (ASMJIT_UNLIKELY(!le))
+     217           0 :     return setLastError(DebugUtils::errored(kErrorInvalidLabel));
+     218             : 
+     219             :   // Label can be bound only once.
+     220       63790 :   if (ASMJIT_UNLIKELY(le->isBound()))
+     221           0 :     return setLastError(DebugUtils::errored(kErrorLabelAlreadyBound));
+     222             : 
+     223             : #if !defined(ASMJIT_DISABLE_LOGGING)
+     224       63790 :   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       63790 :   LabelLink* link = le->_links;
+     244             :   LabelLink* prev = nullptr;
+     245             : 
+     246       63790 :   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       63790 :   le->_sectionId = _section->getId();
+     280       63790 :   le->_offset = pos;
+     281       63790 :   le->_links = nullptr;
+     282             :   resetInlineComment();
+     283             : 
+     284       63790 :   if (err != kErrorOk)
+     285           0 :     return setLastError(err);
+     286             : 
+     287             :   return kErrorOk;
+     288             : }
+     289             : 
+     290           0 : Error Assembler::embed(const void* data, uint32_t size) {
+     291           0 :   if (_lastError) return _lastError;
+     292             : 
+     293           0 :   if (getRemainingSpace() < size) {
+     294           0 :     Error err = _code->growBuffer(&_section->_buffer, size);
+     295           0 :     if (ASMJIT_UNLIKELY(err != kErrorOk)) return setLastError(err);
+     296             :   }
+     297             : 
+     298           0 :   ::memcpy(_bufferPtr, data, size);
+     299           0 :   _bufferPtr += size;
+     300             : 
+     301             : #if !defined(ASMJIT_DISABLE_LOGGING)
+     302           0 :   if (_globalOptions & kOptionLoggingEnabled)
+     303           0 :     _code->_logger->logBinary(data, size);
+     304             : #endif // !ASMJIT_DISABLE_LOGGING
+     305             : 
+     306             :   return kErrorOk;
+     307             : }
+     308             : 
+     309           0 : Error Assembler::embedLabel(const Label& label) {
+     310           0 :   if (_lastError) return _lastError;
+     311             :   ASMJIT_ASSERT(_code != nullptr);
+     312             : 
+     313             :   RelocEntry* re;
+     314           0 :   LabelEntry* le = _code->getLabelEntry(label);
+     315             : 
+     316           0 :   if (ASMJIT_UNLIKELY(!le))
+     317           0 :     return setLastError(DebugUtils::errored(kErrorInvalidLabel));
+     318             : 
+     319             :   Error err;
+     320             :   uint32_t gpSize = getGpSize();
+     321             : 
+     322           0 :   if (getRemainingSpace() < gpSize) {
+     323           0 :     err = _code->growBuffer(&_section->_buffer, gpSize);
+     324           0 :     if (ASMJIT_UNLIKELY(err)) return setLastError(err);
+     325             :   }
+     326             : 
+     327             : #if !defined(ASMJIT_DISABLE_LOGGING)
+     328           0 :   if (_globalOptions & kOptionLoggingEnabled)
+     329           0 :     _code->_logger->logf(gpSize == 4 ? ".dd L%u\n" : ".dq L%u\n", Operand::unpackId(label.getId()));
+     330             : #endif // !ASMJIT_DISABLE_LOGGING
+     331             : 
+     332           0 :   err = _code->newRelocEntry(&re, RelocEntry::kTypeRelToAbs, gpSize);
+     333           0 :   if (ASMJIT_UNLIKELY(err)) return setLastError(err);
+     334             : 
+     335           0 :   re->_sourceSectionId = _section->getId();
+     336           0 :   re->_sourceOffset = static_cast<uint64_t>(getOffset());
+     337             : 
+     338           0 :   if (le->isBound()) {
+     339           0 :     re->_targetSectionId = le->getSectionId();
+     340           0 :     re->_data = static_cast<uint64_t>(static_cast<int64_t>(le->getOffset()));
+     341             :   }
+     342             :   else {
+     343           0 :     LabelLink* link = _code->newLabelLink(le, _section->getId(), getOffset(), 0);
+     344           0 :     if (ASMJIT_UNLIKELY(!link))
+     345           0 :       return setLastError(DebugUtils::errored(kErrorNoHeapMemory));
+     346           0 :     link->relocId = re->getId();
+     347             :   }
+     348             : 
+     349             :   // Emit dummy DWORD/QWORD depending on the address size.
+     350           0 :   ::memset(_bufferPtr, 0, gpSize);
+     351           0 :   _bufferPtr += gpSize;
+     352             : 
+     353           0 :   return kErrorOk;
+     354             : }
+     355             : 
+     356           0 : Error Assembler::embedConstPool(const Label& label, const ConstPool& pool) {
+     357           0 :   if (_lastError) return _lastError;
+     358             : 
+     359           0 :   if (!isLabelValid(label))
+     360             :     return DebugUtils::errored(kErrorInvalidLabel);
+     361             : 
+     362           0 :   ASMJIT_PROPAGATE(align(kAlignData, static_cast<uint32_t>(pool.getAlignment())));
+     363           0 :   ASMJIT_PROPAGATE(bind(label));
+     364             : 
+     365             :   size_t size = pool.getSize();
+     366           0 :   if (getRemainingSpace() < size) {
+     367           0 :     Error err = _code->growBuffer(&_section->_buffer, size);
+     368           0 :     if (ASMJIT_UNLIKELY(err)) return setLastError(err);
+     369             :   }
+     370             : 
+     371           0 :   uint8_t* p = _bufferPtr;
+     372           0 :   pool.fill(p);
+     373             : 
+     374             : #if !defined(ASMJIT_DISABLE_LOGGING)
+     375           0 :   if (_globalOptions & kOptionLoggingEnabled)
+     376           0 :     _code->_logger->logBinary(p, size);
+     377             : #endif // !ASMJIT_DISABLE_LOGGING
+     378             : 
+     379           0 :   _bufferPtr += size;
+     380           0 :   return kErrorOk;
+     381             : }
+     382             : 
+     383             : // ============================================================================
+     384             : // [asmjit::Assembler - Emit-Helpers]
+     385             : // ============================================================================
+     386             : 
+     387             : #if !defined(ASMJIT_DISABLE_LOGGING)
+     388           0 : void Assembler::_emitLog(
+     389             :   uint32_t instId, uint32_t options, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3,
+     390             :   uint32_t relSize, uint32_t imLen, uint8_t* afterCursor) {
+     391             : 
+     392           0 :   Logger* logger = _code->getLogger();
+     393             :   ASMJIT_ASSERT(logger != nullptr);
+     394             :   ASMJIT_ASSERT(options & CodeEmitter::kOptionLoggingEnabled);
+     395             : 
+     396             :   StringBuilderTmp<256> sb;
+     397             :   uint32_t logOptions = logger->getOptions();
+     398             : 
+     399           0 :   uint8_t* beforeCursor = _bufferPtr;
+     400           0 :   intptr_t emittedSize = (intptr_t)(afterCursor - beforeCursor);
+     401             : 
+     402             :   sb.appendString(logger->getIndentation());
+     403             : 
+     404             :   Operand_ opArray[6];
+     405             :   opArray[0].copyFrom(o0);
+     406             :   opArray[1].copyFrom(o1);
+     407             :   opArray[2].copyFrom(o2);
+     408             :   opArray[3].copyFrom(o3);
+     409             : 
+     410           0 :   if (options & kOptionOp4Op5Used) {
+     411             :     opArray[4].copyFrom(_op4);
+     412             :     opArray[5].copyFrom(_op5);
+     413             :   }
+     414             :   else {
+     415             :     opArray[4].reset();
+     416             :     opArray[5].reset();
+     417             :   }
+     418             : 
+     419           0 :   Logging::formatInstruction(
+     420             :     sb, logOptions,
+     421             :     this, getArchType(),
+     422           0 :     Inst::Detail(instId, options, _extraReg), opArray, 6);
+     423             : 
+     424           0 :   if ((logOptions & Logger::kOptionBinaryForm) != 0)
+     425           0 :     Logging::formatLine(sb, _bufferPtr, emittedSize, relSize, imLen, getInlineComment());
+     426             :   else
+     427           0 :     Logging::formatLine(sb, nullptr, Globals::kInvalidIndex, 0, 0, getInlineComment());
+     428             : 
+     429             :   logger->log(sb.getData(), sb.getLength());
+     430           0 : }
+     431             : 
+     432           0 : Error Assembler::_emitFailed(
+     433             :   Error err,
+     434             :   uint32_t instId, uint32_t options, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3) {
+     435             : 
+     436             :   StringBuilderTmp<256> sb;
+     437           0 :   sb.appendString(DebugUtils::errorAsString(err));
+     438             :   sb.appendString(": ");
+     439             : 
+     440             :   Operand_ opArray[6];
+     441             :   opArray[0].copyFrom(o0);
+     442             :   opArray[1].copyFrom(o1);
+     443             :   opArray[2].copyFrom(o2);
+     444             :   opArray[3].copyFrom(o3);
+     445             : 
+     446           0 :   if (options & kOptionOp4Op5Used) {
+     447             :     opArray[4].copyFrom(_op4);
+     448             :     opArray[5].copyFrom(_op5);
+     449             :   }
+     450             :   else {
+     451             :     opArray[4].reset();
+     452             :     opArray[5].reset();
+     453             :   }
+     454             : 
+     455           0 :   Logging::formatInstruction(
+     456             :     sb, 0,
+     457             :     this, getArchType(),
+     458           0 :     Inst::Detail(instId, options, _extraReg), opArray, 6);
+     459             : 
+     460             :   resetOptions();
+     461             :   resetExtraReg();
+     462             :   resetInlineComment();
+     463           0 :   return setLastError(err, sb.getData());
+     464             : }
+     465             : #endif
+     466             : 
+     467             : } // asmjit namespace
+     468             : } // namespace PLMD
+     469             : 
+     470             : // [Api-End]
+     471             : #include "./asmjit_apiend.h"
+     472             : #pragma GCC diagnostic pop
+     473             : #endif // __PLUMED_HAS_ASMJIT
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/assembler.h.func-sort-c.html b/coverage-libs/asmjit/assembler.h.func-sort-c.html new file mode 100644 index 000000000000..025744c66a56 --- /dev/null +++ b/coverage-libs/asmjit/assembler.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/assembler.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - assembler.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:1250.0 %
Date:2024-04-19 12:12:36Functions:00-
+
+ +
+ + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/assembler.h.gcov.html b/coverage-libs/asmjit/assembler.h.gcov.html new file mode 100644 index 000000000000..82a48fab8e0f --- /dev/null +++ b/coverage-libs/asmjit/assembler.h.gcov.html @@ -0,0 +1,260 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/assembler.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - assembler.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:1250.0 %
Date:2024-04-19 12:12:36Functions: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       95685 :   ASMJIT_INLINE size_t getOffset() const noexcept { return (size_t)(_bufferPtr - _bufferData); }
+     104             :   //! Set the current position in the CodeBuffer to `offset`.
+     105             :   //!
+     106             :   //! NOTE: The `offset` cannot be outside of the buffer length (even if it's
+     107             :   //! within buffer's capacity).
+     108             :   ASMJIT_API Error setOffset(size_t offset);
+     109             : 
+     110             :   //! Get start of the CodeBuffer of the current section.
+     111             :   ASMJIT_INLINE uint8_t* getBufferData() const noexcept { return _bufferData; }
+     112             :   //! Get end (first invalid byte) of the current section.
+     113             :   ASMJIT_INLINE uint8_t* getBufferEnd() const noexcept { return _bufferEnd; }
+     114             :   //! Get pointer in the CodeBuffer of the current section.
+     115             :   ASMJIT_INLINE uint8_t* getBufferPtr() const noexcept { return _bufferPtr; }
+     116             : 
+     117             :   // --------------------------------------------------------------------------
+     118             :   // [Code-Generation]
+     119             :   // --------------------------------------------------------------------------
+     120             : 
+     121             :   ASMJIT_API Label newLabel() override;
+     122             :   ASMJIT_API Label newNamedLabel(
+     123             :     const char* name,
+     124             :     size_t nameLength = Globals::kInvalidIndex,
+     125             :     uint32_t type = Label::kTypeGlobal,
+     126             :     uint32_t parentId = 0) override;
+     127             :   ASMJIT_API Error bind(const Label& label) override;
+     128             :   ASMJIT_API Error embed(const void* data, uint32_t size) override;
+     129             :   ASMJIT_API Error embedLabel(const Label& label) override;
+     130             :   ASMJIT_API Error embedConstPool(const Label& label, const ConstPool& pool) override;
+     131             :   ASMJIT_API Error comment(const char* s, size_t len = Globals::kInvalidIndex) override;
+     132             : 
+     133             :   // --------------------------------------------------------------------------
+     134             :   // [Emit-Helpers]
+     135             :   // --------------------------------------------------------------------------
+     136             : 
+     137             : protected:
+     138             : #if !defined(ASMJIT_DISABLE_LOGGING)
+     139             :   void _emitLog(
+     140             :     uint32_t instId, uint32_t options, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3,
+     141             :     uint32_t relSize, uint32_t imLen, uint8_t* afterCursor);
+     142             : 
+     143             :   Error _emitFailed(
+     144             :     Error err,
+     145             :     uint32_t instId, uint32_t options, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3);
+     146             : #else
+     147             :   ASMJIT_INLINE Error _emitFailed(
+     148             :     uint32_t err,
+     149             :     uint32_t instId, uint32_t options, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3) {
+     150             : 
+     151             :     resetOptions();
+     152             :     resetInlineComment();
+     153             :     return setLastError(err);
+     154             :   }
+     155             : #endif
+     156             : 
+     157             :   // --------------------------------------------------------------------------
+     158             :   // [Members]
+     159             :   // --------------------------------------------------------------------------
+     160             : 
+     161             : public:
+     162             :   SectionEntry* _section;                //!< Current section where the assembling happens.
+     163             :   uint8_t* _bufferData;                  //!< Start of the CodeBuffer of the current section.
+     164             :   uint8_t* _bufferEnd;                   //!< End (first invalid byte) of the current section.
+     165             :   uint8_t* _bufferPtr;                   //!< Pointer in the CodeBuffer of the current section.
+     166             : 
+     167             :   Operand_ _op4;                         //!< 5th operand data, used only temporarily.
+     168             :   Operand_ _op5;                         //!< 6th operand data, used only temporarily.
+     169             : };
+     170             : 
+     171             : //! \}
+     172             : 
+     173             : } // asmjit namespace
+     174             : } // namespace PLMD
+     175             : 
+     176             : // [Api-End]
+     177             : #include "./asmjit_apiend.h"
+     178             : 
+     179             : // [Guard]
+     180             : #endif // _ASMJIT_BASE_ASSEMBLER_H
+     181             : #pragma GCC diagnostic pop
+     182             : #endif // __PLUMED_HAS_ASMJIT
+     183             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/codebuilder.cpp.func-sort-c.html b/coverage-libs/asmjit/codebuilder.cpp.func-sort-c.html new file mode 100644 index 000000000000..06e19cd483f8 --- /dev/null +++ b/coverage-libs/asmjit/codebuilder.cpp.func-sort-c.html @@ -0,0 +1,205 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/codebuilder.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - codebuilder.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:6025723.3 %
Date:2024-04-19 12:12:36Functions: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
_ZN4PLMD6asmjit11CodeBuilder12newLabelNodeEv31895
_ZN4PLMD6asmjit11CodeBuilder7addPassEPNS0_6CBPassE31895
_ZN4PLMD6asmjit11CodeBuilder8onAttachEPNS0_10CodeHolderE31895
_ZN4PLMD6asmjit11CodeBuilder9serializeEPNS0_11CodeEmitterE31895
_ZN4PLMD6asmjit11CodeBuilderC2Ev31895
_ZN4PLMD6asmjit11CodeBuilderD2Ev31895
_ZN4PLMD6asmjit6CBPassC2EPKc31895
_ZN4PLMD6asmjit11CodeBuilder17registerLabelNodeEPNS0_7CBLabelE63790
_ZN4PLMD6asmjit11CodeBuilder9setCursorEPNS0_6CBNodeE63790
_ZN4PLMD6asmjit11CodeBuilder7addNodeEPNS0_6CBNodeE715144
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/codebuilder.cpp.func.html b/coverage-libs/asmjit/codebuilder.cpp.func.html new file mode 100644 index 000000000000..0c296870f2e1 --- /dev/null +++ b/coverage-libs/asmjit/codebuilder.cpp.func.html @@ -0,0 +1,205 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/codebuilder.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - codebuilder.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:6025723.3 %
Date:2024-04-19 12:12:36Functions: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
_ZN4PLMD6asmjit11CodeBuilder12newLabelNodeEv31895
_ZN4PLMD6asmjit11CodeBuilder13newNamedLabelEPKcmjj0
_ZN4PLMD6asmjit11CodeBuilder14embedConstPoolERKNS0_5LabelERKNS0_9ConstPoolE0
_ZN4PLMD6asmjit11CodeBuilder14newCommentNodeEPKcm0
_ZN4PLMD6asmjit11CodeBuilder17registerLabelNodeEPNS0_7CBLabelE63790
_ZN4PLMD6asmjit11CodeBuilder4bindERKNS0_5LabelE0
_ZN4PLMD6asmjit11CodeBuilder5alignEjj0
_ZN4PLMD6asmjit11CodeBuilder5embedEPKvj0
_ZN4PLMD6asmjit11CodeBuilder7addNodeEPNS0_6CBNodeE715144
_ZN4PLMD6asmjit11CodeBuilder7addPassEPNS0_6CBPassE31895
_ZN4PLMD6asmjit11CodeBuilder7commentEPKcm0
_ZN4PLMD6asmjit11CodeBuilder8addAfterEPNS0_6CBNodeES3_0
_ZN4PLMD6asmjit11CodeBuilder8newLabelEv0
_ZN4PLMD6asmjit11CodeBuilder8onAttachEPNS0_10CodeHolderE31895
_ZN4PLMD6asmjit11CodeBuilder8onDetachEPNS0_10CodeHolderE0
_ZN4PLMD6asmjit11CodeBuilder9addBeforeEPNS0_6CBNodeES3_0
_ZN4PLMD6asmjit11CodeBuilder9serializeEPNS0_11CodeEmitterE31895
_ZN4PLMD6asmjit11CodeBuilder9setCursorEPNS0_6CBNodeE63790
_ZN4PLMD6asmjit11CodeBuilderC2Ev31895
_ZN4PLMD6asmjit11CodeBuilderD0Ev0
_ZN4PLMD6asmjit11CodeBuilderD2Ev31895
_ZN4PLMD6asmjit6CBPassC2EPKc31895
_ZN4PLMD6asmjit6CBPassD0Ev0
_ZN4PLMD6asmjit6CBPassD2Ev0
_ZNK4PLMD6asmjit11CodeBuilder13getPassByNameEPKc0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/codebuilder.cpp.gcov.html b/coverage-libs/asmjit/codebuilder.cpp.gcov.html new file mode 100644 index 000000000000..d6574dd0736d --- /dev/null +++ b/coverage-libs/asmjit/codebuilder.cpp.gcov.html @@ -0,0 +1,687 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/codebuilder.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - codebuilder.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:6025723.3 %
Date:2024-04-19 12:12:36Functions: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       31895 : CodeBuilder::CodeBuilder() noexcept
+      50             :   : CodeEmitter(kTypeBuilder),
+      51       31895 :     _cbBaseZone(32768 - Zone::kZoneOverhead),
+      52       31895 :     _cbDataZone(16384 - Zone::kZoneOverhead),
+      53       31895 :     _cbPassZone(32768 - Zone::kZoneOverhead),
+      54       31895 :     _cbHeap(&_cbBaseZone),
+      55             :     _cbPasses(),
+      56             :     _cbLabels(),
+      57       31895 :     _firstNode(nullptr),
+      58       31895 :     _lastNode(nullptr),
+      59       31895 :     _cursor(nullptr),
+      60       31895 :     _position(0),
+      61       31895 :     _nodeFlags(0) {}
+      62       31895 : CodeBuilder::~CodeBuilder() noexcept {}
+      63             : 
+      64             : // ============================================================================
+      65             : // [asmjit::CodeBuilder - Events]
+      66             : // ============================================================================
+      67             : 
+      68       31895 : Error CodeBuilder::onAttach(CodeHolder* code) noexcept {
+      69       31895 :   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       63790 : Error CodeBuilder::registerLabelNode(CBLabel* node) noexcept {
+     119       63790 :   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       63790 :   ASMJIT_PROPAGATE(_code->newLabelId(id));
+     126       63790 :   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       63790 :   ASMJIT_PROPAGATE(_cbLabels.resize(&_cbHeap, index + 1));
+     131             : 
+     132       63790 :   _cbLabels[index] = node;
+     133       63790 :   node->_id = id;
+     134       63790 :   return kErrorOk;
+     135             : }
+     136             : 
+     137       31895 : CBLabel* CodeBuilder::newLabelNode() noexcept {
+     138             :   CBLabel* node = newNodeT<CBLabel>();
+     139       31895 :   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      715144 : CBNode* CodeBuilder::addNode(CBNode* node) noexcept {
+     302             :   ASMJIT_ASSERT(node);
+     303             :   ASMJIT_ASSERT(node->_prev == nullptr);
+     304             :   ASMJIT_ASSERT(node->_next == nullptr);
+     305             : 
+     306      715144 :   if (!_cursor) {
+     307       31895 :     if (!_firstNode) {
+     308       31895 :       _firstNode = node;
+     309       31895 :       _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      683249 :     CBNode* next = _cursor->_next;
+     320             : 
+     321      683249 :     node->_prev = prev;
+     322      683249 :     node->_next = next;
+     323             : 
+     324      683249 :     prev->_next = node;
+     325      683249 :     if (next)
+     326      619459 :       next->_prev = node;
+     327             :     else
+     328       63790 :       _lastNode = node;
+     329             :   }
+     330             : 
+     331      715144 :   _cursor = node;
+     332      715144 :   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       63790 : CBNode* CodeBuilder::setCursor(CBNode* node) noexcept {
+     467       63790 :   CBNode* old = _cursor;
+     468       63790 :   _cursor = node;
+     469       63790 :   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       31895 : ASMJIT_FAVOR_SIZE Error CodeBuilder::addPass(CBPass* pass) noexcept {
+     487       31895 :   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       31895 :   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       31895 :   ASMJIT_PROPAGATE(_cbPasses.append(&_cbHeap, pass));
+     500       31895 :   pass->_cb = this;
+     501       31895 :   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       31895 : Error CodeBuilder::serialize(CodeEmitter* dst) {
+     528             :   Error err = kErrorOk;
+     529             :   CBNode* node_ = getFirstNode();
+     530             : 
+     531             :   do {
+     532             :     dst->setInlineComment(node_->getInlineComment());
+     533             : 
+     534      715144 :     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       63790 :       case CBNode::kNodeFunc:
+     548             :       case CBNode::kNodeLabel: {
+     549             :         CBLabel* node = static_cast<CBLabel*>(node_);
+     550       63790 :         err = dst->bind(node->getLabel());
+     551       63790 :         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      587564 :         err = dst->emitOpArray(node->getInstId(), node->getOpArray(), node->getOpCount());
+     572      587564 :         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      715144 :     if (err) break;
+     586             :     node_ = node_->getNext();
+     587      715144 :   } while (node_);
+     588             : 
+     589       31895 :   return err;
+     590             : }
+     591             : 
+     592             : // ============================================================================
+     593             : // [asmjit::CBPass]
+     594             : // ============================================================================
+     595             : 
+     596       31895 : CBPass::CBPass(const char* name) noexcept
+     597       31895 :   : _cb(nullptr),
+     598       31895 :     _name(name) {}
+     599           0 : CBPass::~CBPass() noexcept {}
+     600             : 
+     601             : } // asmjit namespace
+     602             : } // namespace PLMD
+     603             : 
+     604             : // [Api-End]
+     605             : #include "./asmjit_apiend.h"
+     606             : 
+     607             : // [Guard]
+     608             : #endif // !ASMJIT_DISABLE_BUILDER
+     609             : #pragma GCC diagnostic pop
+     610             : #endif // __PLUMED_HAS_ASMJIT
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/codebuilder.h.func-sort-c.html b/coverage-libs/asmjit/codebuilder.h.func-sort-c.html new file mode 100644 index 000000000000..76ffcee3399e --- /dev/null +++ b/coverage-libs/asmjit/codebuilder.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/codebuilder.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - codebuilder.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:509453.2 %
Date:2024-04-19 12:12:36Functions:00-
+
+ +
+ + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/codebuilder.h.gcov.html b/coverage-libs/asmjit/codebuilder.h.gcov.html new file mode 100644 index 000000000000..c0f1c314727e --- /dev/null +++ b/coverage-libs/asmjit/codebuilder.h.gcov.html @@ -0,0 +1,1021 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/codebuilder.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - codebuilder.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:509453.2 %
Date:2024-04-19 12:12:36Functions: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       63790 :   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       63790 :   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       31895 :   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       31895 :   ASMJIT_INLINE CBNode* getCursor() const noexcept { return _cursor; }
+     186             :   //! Set the current node without returning the previous node.
+     187      140494 :   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       31895 :   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       31895 :   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       31895 :   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      715144 :   ASMJIT_INLINE CBNode(CodeBuilder* cb, uint32_t type) noexcept {
+     369      715144 :     _prev = nullptr;
+     370      715144 :     _next = nullptr;
+     371      683249 :     _type = static_cast<uint8_t>(type);
+     372      127580 :     _opCount = 0;
+     373      715144 :     _flags = static_cast<uint16_t>(cb->_nodeFlags);
+     374      715144 :     _position = cb->_position;
+     375      715144 :     _inlineComment = nullptr;
+     376      638440 :     _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      979558 :   ASMJIT_INLINE CBNode* getPrev() const noexcept { return _prev; }
+     392             :   //! Get next node in the compiler stream.
+     393     1896843 :   ASMJIT_INLINE CBNode* getNext() const noexcept { return _next; }
+     394             : 
+     395             :   //! Get the node type, see \ref Type.
+     396     3321371 :   ASMJIT_INLINE uint32_t getType() const noexcept { return _type; }
+     397             :   //! Get the node flags.
+     398      413075 :   ASMJIT_INLINE uint32_t getFlags() const noexcept { return _flags; }
+     399             : 
+     400             :   //! Get whether the instruction has flag `flag`.
+     401     2899214 :   ASMJIT_INLINE bool hasFlag(uint32_t flag) const noexcept { return (static_cast<uint32_t>(_flags) & flag) != 0; }
+     402             :   //! Set node flags to `flags`.
+     403      413075 :   ASMJIT_INLINE void setFlags(uint32_t flags) noexcept { _flags = static_cast<uint16_t>(flags); }
+     404             :   //! Add instruction `flags`.
+     405       31895 :   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      553569 :   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      715144 :   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     1501232 :   ASMJIT_INLINE bool hasPassData() const noexcept { return _passData != nullptr; }
+     452             :   //! Get work-data - data used during processing & transformations.
+     453             :   template<typename T>
+     454     5631237 :   ASMJIT_INLINE T* getPassData() const noexcept { return (T*)_passData; }
+     455             :   //! Set work-data to `data`.
+     456             :   template<typename T>
+     457      553569 :   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      587564 :     : CBNode(cb, kNodeInst) {
+     495             : 
+     496             :     orFlags(kFlagIsRemovable);
+     497      587564 :     _instDetail.instId = static_cast<uint16_t>(instId);
+     498      587564 :     _instDetail.options = options;
+     499             : 
+     500      587564 :     _opCount = static_cast<uint8_t>(opCount);
+     501      587564 :     _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     1000639 :   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     1000125 :   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      587564 :   ASMJIT_INLINE uint32_t getOpCount() const noexcept { return _opCount; }
+     550             :   //! Get operands list.
+     551     1426628 :   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      524805 :   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      174273 :     return static_cast<T*>(&_opArray[_memOpIndex]);
+     570             :   }
+     571             : 
+     572             :   //! Set memory operand index, `0xFF` means no memory operand.
+     573      670729 :   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     1460011 :     for (i = 0; i < opCount; i++)
+     587     1046720 :       if (opArray[i].isMem())
+     588      174273 :         goto Update;
+     589             :     i = 0xFF;
+     590             : 
+     591      587564 : 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       63790 :     : CBNode(cb, kNodeLabel),
+     767       63790 :       _id(id),
+     768       63790 :       _numRefs(0),
+     769       63790 :       _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       63790 :   ASMJIT_INLINE Label getLabel() const noexcept { return Label(_id); }
+     781             : 
+     782             :   //! Get first jmp instruction.
+     783           0 :   ASMJIT_INLINE CBJump* getFrom() const noexcept { return _from; }
+     784             : 
+     785             :   //! Get number of jumps to this target.
+     786           0 :   ASMJIT_INLINE uint32_t getNumRefs() const noexcept { return _numRefs; }
+     787             :   //! Set number of jumps to this target.
+     788             :   ASMJIT_INLINE void setNumRefs(uint32_t i) noexcept { _numRefs = i; }
+     789             : 
+     790             :   //! Add number of jumps to this target.
+     791           0 :   ASMJIT_INLINE void addNumRefs(uint32_t i = 1) noexcept { _numRefs += i; }
+     792             :   //! Subtract number of jumps to this target.
+     793           0 :   ASMJIT_INLINE void subNumRefs(uint32_t i = 1) noexcept { _numRefs -= i; }
+     794             : 
+     795             :   // --------------------------------------------------------------------------
+     796             :   // [Members]
+     797             :   // --------------------------------------------------------------------------
+     798             : 
+     799             :   uint32_t _id;                          //!< Label id.
+     800             :   uint32_t _numRefs;                     //!< Count of jumps here.
+     801             :   CBJump* _from;                         //!< Linked-list of nodes that can jump here.
+     802             : };
+     803             : 
+     804             : // ============================================================================
+     805             : // [asmjit::CBLabelData]
+     806             : // ============================================================================
+     807             : 
+     808             : class CBLabelData : public CBNode {
+     809             : public:
+     810             :   ASMJIT_NONCOPYABLE(CBLabelData)
+     811             : 
+     812             :   // --------------------------------------------------------------------------
+     813             :   // [Construction / Destruction]
+     814             :   // --------------------------------------------------------------------------
+     815             : 
+     816             :   //! Create a new `CBLabelData` instance.
+     817             :   ASMJIT_INLINE CBLabelData(CodeBuilder* cb, uint32_t id = kInvalidValue) noexcept
+     818           0 :     : CBNode(cb, kNodeLabelData),
+     819           0 :       _id(id) {}
+     820             : 
+     821             :   //! Destroy the `CBLabelData` instance (NEVER CALLED).
+     822             :   ASMJIT_INLINE ~CBLabelData() noexcept {}
+     823             : 
+     824             :   // --------------------------------------------------------------------------
+     825             :   // [Interface]
+     826             :   // --------------------------------------------------------------------------
+     827             : 
+     828             :   //! Get the label id.
+     829             :   ASMJIT_INLINE uint32_t getId() const noexcept { return _id; }
+     830             :   //! Get the label as `Label` operand.
+     831           0 :   ASMJIT_INLINE Label getLabel() const noexcept { return Label(_id); }
+     832             : 
+     833             :   // --------------------------------------------------------------------------
+     834             :   // [Members]
+     835             :   // --------------------------------------------------------------------------
+     836             : 
+     837             :   uint32_t _id;
+     838             : };
+     839             : 
+     840             : // ============================================================================
+     841             : // [asmjit::CBConstPool]
+     842             : // ============================================================================
+     843             : 
+     844             : class CBConstPool : public CBLabel {
+     845             : public:
+     846             :   ASMJIT_NONCOPYABLE(CBConstPool)
+     847             : 
+     848             :   // --------------------------------------------------------------------------
+     849             :   // [Construction / Destruction]
+     850             :   // --------------------------------------------------------------------------
+     851             : 
+     852             :   //! Create a new `CBConstPool` instance.
+     853             :   ASMJIT_INLINE CBConstPool(CodeBuilder* cb, uint32_t id = kInvalidValue) noexcept
+     854           0 :     : CBLabel(cb, id),
+     855           0 :       _constPool(&cb->_cbBaseZone) { _type = kNodeConstPool; }
+     856             : 
+     857             :   //! Destroy the `CBConstPool` instance (NEVER CALLED).
+     858             :   ASMJIT_INLINE ~CBConstPool() noexcept {}
+     859             : 
+     860             :   // --------------------------------------------------------------------------
+     861             :   // [Interface]
+     862             :   // --------------------------------------------------------------------------
+     863             : 
+     864           0 :   ASMJIT_INLINE ConstPool& getConstPool() noexcept { return _constPool; }
+     865             :   ASMJIT_INLINE const ConstPool& getConstPool() const noexcept { return _constPool; }
+     866             : 
+     867             :   //! Get whether the constant-pool is empty.
+     868             :   ASMJIT_INLINE bool isEmpty() const noexcept { return _constPool.isEmpty(); }
+     869             :   //! Get the size of the constant-pool in bytes.
+     870             :   ASMJIT_INLINE size_t getSize() const noexcept { return _constPool.getSize(); }
+     871             :   //! Get minimum alignment.
+     872             :   ASMJIT_INLINE size_t getAlignment() const noexcept { return _constPool.getAlignment(); }
+     873             : 
+     874             :   //! See \ref ConstPool::add().
+     875             :   ASMJIT_INLINE Error add(const void* data, size_t size, size_t& dstOffset) noexcept {
+     876           0 :     return _constPool.add(data, size, dstOffset);
+     877             :   }
+     878             : 
+     879             :   // --------------------------------------------------------------------------
+     880             :   // [Members]
+     881             :   // --------------------------------------------------------------------------
+     882             : 
+     883             :   ConstPool _constPool;
+     884             : };
+     885             : 
+     886             : // ============================================================================
+     887             : // [asmjit::CBComment]
+     888             : // ============================================================================
+     889             : 
+     890             : //! Comment (CodeBuilder).
+     891             : class CBComment : public CBNode {
+     892             : public:
+     893             :   ASMJIT_NONCOPYABLE(CBComment)
+     894             : 
+     895             :   // --------------------------------------------------------------------------
+     896             :   // [Construction / Destruction]
+     897             :   // --------------------------------------------------------------------------
+     898             : 
+     899             :   //! Create a new `CBComment` instance.
+     900             :   ASMJIT_INLINE CBComment(CodeBuilder* cb, const char* comment) noexcept : CBNode(cb, kNodeComment) {
+     901             :     orFlags(kFlagIsRemovable | kFlagIsInformative);
+     902           0 :     _inlineComment = comment;
+     903             :   }
+     904             : 
+     905             :   //! Destroy the `CBComment` instance (NEVER CALLED).
+     906             :   ASMJIT_INLINE ~CBComment() noexcept {}
+     907             : };
+     908             : 
+     909             : // ============================================================================
+     910             : // [asmjit::CBSentinel]
+     911             : // ============================================================================
+     912             : 
+     913             : //! Sentinel (CodeBuilder).
+     914             : //!
+     915             : //! Sentinel is a marker that is completely ignored by the code builder. It's
+     916             : //! used to remember a position in a code as it never gets removed by any pass.
+     917             : class CBSentinel : public CBNode {
+     918             : public:
+     919             :   ASMJIT_NONCOPYABLE(CBSentinel)
+     920             : 
+     921             :   // --------------------------------------------------------------------------
+     922             :   // [Construction / Destruction]
+     923             :   // --------------------------------------------------------------------------
+     924             : 
+     925             :   //! Create a new `CBSentinel` instance.
+     926             :   ASMJIT_INLINE CBSentinel(CodeBuilder* cb) noexcept : CBNode(cb, kNodeSentinel) {}
+     927             :   //! Destroy the `CBSentinel` instance (NEVER CALLED).
+     928             :   ASMJIT_INLINE ~CBSentinel() noexcept {}
+     929             : };
+     930             : 
+     931             : //! \}
+     932             : 
+     933             : } // asmjit namespace
+     934             : } // namespace PLMD
+     935             : 
+     936             : // [Api-End]
+     937             : #include "./asmjit_apiend.h"
+     938             : 
+     939             : // [Guard]
+     940             : #endif // !ASMJIT_DISABLE_BUILDER
+     941             : #endif // _ASMJIT_BASE_CODEBUILDER_H
+     942             : #pragma GCC diagnostic pop
+     943             : #endif // __PLUMED_HAS_ASMJIT
+     944             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/codecompiler.cpp.func-sort-c.html b/coverage-libs/asmjit/codecompiler.cpp.func-sort-c.html new file mode 100644 index 000000000000..10590e0acaba --- /dev/null +++ b/coverage-libs/asmjit/codecompiler.cpp.func-sort-c.html @@ -0,0 +1,217 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/codecompiler.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - codecompiler.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:8923937.2 %
Date:2024-04-19 12:12:36Functions: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_E12914
_ZN4PLMD6asmjit12CodeCompiler7addCallEjRKNS0_8Operand_ERKNS0_13FuncSignatureE12914
_ZN4PLMD6asmjit12CodeCompiler7newCallEjRKNS0_8Operand_ERKNS0_13FuncSignatureE12914
_ZN4PLMD6asmjit10CCFuncCall7_setArgEjRKNS0_8Operand_E13428
_ZN4PLMD6asmjit12CodeCompiler6addRetERKNS0_8Operand_ES4_31895
_ZN4PLMD6asmjit12CodeCompiler6newRetERKNS0_8Operand_ES4_31895
_ZN4PLMD6asmjit12CodeCompiler7addFuncEPNS0_6CCFuncE31895
_ZN4PLMD6asmjit12CodeCompiler7addFuncERKNS0_13FuncSignatureE31895
_ZN4PLMD6asmjit12CodeCompiler7endFuncEv31895
_ZN4PLMD6asmjit12CodeCompiler7newFuncERKNS0_13FuncSignatureE31895
_ZN4PLMD6asmjit12CodeCompiler8onAttachEPNS0_10CodeHolderE31895
_ZN4PLMD6asmjit12CodeCompilerC2Ev31895
_ZN4PLMD6asmjit12CodeCompilerD2Ev31895
_ZN4PLMD6asmjit12CodeCompiler10newVirtRegEjjPKc315112
_ZN4PLMD6asmjit12CodeCompiler7_newRegERNS0_3RegEjPKc315112
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/codecompiler.cpp.func.html b/coverage-libs/asmjit/codecompiler.cpp.func.html new file mode 100644 index 000000000000..da3ffe75c138 --- /dev/null +++ b/coverage-libs/asmjit/codecompiler.cpp.func.html @@ -0,0 +1,217 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/codecompiler.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - codecompiler.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:8923937.2 %
Date:2024-04-19 12:12:36Functions:153641.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit10CCFuncCall7_setArgEjRKNS0_8Operand_E13428
_ZN4PLMD6asmjit10CCFuncCall7_setRetEjRKNS0_8Operand_E12914
_ZN4PLMD6asmjit12CodeCompiler10newVirtRegEjjPKc315112
_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_31895
_ZN4PLMD6asmjit12CodeCompiler6newRetERKNS0_8Operand_ES4_31895
_ZN4PLMD6asmjit12CodeCompiler6renameERNS0_3RegEPKcz0
_ZN4PLMD6asmjit12CodeCompiler6setArgEjRKNS0_3RegE0
_ZN4PLMD6asmjit12CodeCompiler7_newRegERNS0_3RegERKS2_PKc0
_ZN4PLMD6asmjit12CodeCompiler7_newRegERNS0_3RegERKS2_PKcP13__va_list_tag0
_ZN4PLMD6asmjit12CodeCompiler7_newRegERNS0_3RegEjPKc315112
_ZN4PLMD6asmjit12CodeCompiler7_newRegERNS0_3RegEjPKcP13__va_list_tag0
_ZN4PLMD6asmjit12CodeCompiler7addCallEjRKNS0_8Operand_ERKNS0_13FuncSignatureE12914
_ZN4PLMD6asmjit12CodeCompiler7addFuncEPNS0_6CCFuncE31895
_ZN4PLMD6asmjit12CodeCompiler7addFuncERKNS0_13FuncSignatureE31895
_ZN4PLMD6asmjit12CodeCompiler7endFuncEv31895
_ZN4PLMD6asmjit12CodeCompiler7newCallEjRKNS0_8Operand_ERKNS0_13FuncSignatureE12914
_ZN4PLMD6asmjit12CodeCompiler7newFuncERKNS0_13FuncSignatureE31895
_ZN4PLMD6asmjit12CodeCompiler8onAttachEPNS0_10CodeHolderE31895
_ZN4PLMD6asmjit12CodeCompiler8onDetachEPNS0_10CodeHolderE0
_ZN4PLMD6asmjit12CodeCompiler9_newConstERNS0_3MemEjPKvm0
_ZN4PLMD6asmjit12CodeCompiler9_newStackERNS0_3MemEjjPKc0
_ZN4PLMD6asmjit12CodeCompilerC2Ev31895
_ZN4PLMD6asmjit12CodeCompilerD0Ev0
_ZN4PLMD6asmjit12CodeCompilerD2Ev31895
_ZNK4PLMD6asmjit12CodeCompiler11getPriorityERNS0_3RegE0
_ZNK4PLMD6asmjit12CodeCompiler14getSaveOnUnuseERNS0_3RegE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/codecompiler.cpp.gcov.html b/coverage-libs/asmjit/codecompiler.cpp.gcov.html new file mode 100644 index 000000000000..a06d8a1926a4 --- /dev/null +++ b/coverage-libs/asmjit/codecompiler.cpp.gcov.html @@ -0,0 +1,676 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/codecompiler.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - codecompiler.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:8923937.2 %
Date:2024-04-19 12:12:36Functions: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       13428 : bool CCFuncCall::_setArg(uint32_t i, const Operand_& op) noexcept {
+      62       13428 :   if ((i & ~kFuncArgHi) >= _funcDetail.getArgCount())
+      63             :     return false;
+      64             : 
+      65       13428 :   _args[i] = op;
+      66       13428 :   return true;
+      67             : }
+      68             : 
+      69       12914 : bool CCFuncCall::_setRet(uint32_t i, const Operand_& op) noexcept {
+      70       12914 :   if (i >= 2)
+      71             :     return false;
+      72             : 
+      73       12914 :   _ret[i] = op;
+      74       12914 :   return true;
+      75             : }
+      76             : 
+      77             : // ============================================================================
+      78             : // [asmjit::CodeCompiler - Construction / Destruction]
+      79             : // ============================================================================
+      80             : 
+      81       31895 : CodeCompiler::CodeCompiler() noexcept
+      82             :   : CodeBuilder(),
+      83       31895 :     _func(nullptr),
+      84       31895 :     _vRegZone(4096 - Zone::kZoneOverhead),
+      85             :     _vRegArray(),
+      86       31895 :     _localConstPool(nullptr),
+      87       31895 :     _globalConstPool(nullptr) {
+      88             : 
+      89       31895 :   _type = kTypeCompiler;
+      90       31895 : }
+      91       31895 : CodeCompiler::~CodeCompiler() noexcept {}
+      92             : 
+      93             : // ============================================================================
+      94             : // [asmjit::CodeCompiler - Events]
+      95             : // ============================================================================
+      96             : 
+      97       31895 : Error CodeCompiler::onAttach(CodeHolder* code) noexcept {
+      98       31895 :   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       31895 : CCFunc* CodeCompiler::newFunc(const FuncSignature& sign) noexcept {
+     129             :   Error err;
+     130             : 
+     131             :   CCFunc* func = newNodeT<CCFunc>();
+     132       31895 :   if (!func) goto _NoMemory;
+     133             : 
+     134       31895 :   err = registerLabelNode(func);
+     135       31895 :   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       31895 :   func->_exitNode = newLabelNode();
+     143       31895 :   func->_end = newNodeT<CBSentinel>();
+     144             : 
+     145       31895 :   if (!func->_exitNode || !func->_end)
+     146           0 :     goto _NoMemory;
+     147             : 
+     148             :   // Function prototype.
+     149       31895 :   err = func->getDetail().init(sign);
+     150       31895 :   if (err != kErrorOk) {
+     151           0 :     setLastError(err);
+     152           0 :     return nullptr;
+     153             :   }
+     154             : 
+     155             :   // If the CodeInfo guarantees higher alignment honor it.
+     156       31895 :   if (_codeInfo.getStackAlignment() > func->_funcDetail._callConv.getNaturalStackAlignment())
+     157             :     func->_funcDetail._callConv.setNaturalStackAlignment(_codeInfo.getStackAlignment());
+     158             : 
+     159             :   // Allocate space for function arguments.
+     160       31895 :   func->_args = nullptr;
+     161       31895 :   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       31895 : CCFunc* CodeCompiler::addFunc(CCFunc* func) {
+     176             :   ASMJIT_ASSERT(_func == nullptr);
+     177       31895 :   _func = func;
+     178             : 
+     179       31895 :   addNode(func);                 // Function node.
+     180             :   CBNode* cursor = getCursor();  // {CURSOR}.
+     181       31895 :   addNode(func->getExitNode());  // Function exit label.
+     182       31895 :   addNode(func->getEnd());       // Function end marker.
+     183             : 
+     184             :   _setCursor(cursor);
+     185       31895 :   return func;
+     186             : }
+     187             : 
+     188       31895 : CCFunc* CodeCompiler::addFunc(const FuncSignature& sign) {
+     189       31895 :   CCFunc* func = newFunc(sign);
+     190             : 
+     191       31895 :   if (!func) {
+     192           0 :     setLastError(DebugUtils::errored(kErrorNoHeapMemory));
+     193           0 :     return nullptr;
+     194             :   }
+     195             : 
+     196       31895 :   return addFunc(func);
+     197             : }
+     198             : 
+     199       31895 : CBSentinel* CodeCompiler::endFunc() {
+     200             :   CCFunc* func = getFunc();
+     201       31895 :   if (!func) {
+     202             :     // TODO:
+     203             :     return nullptr;
+     204             :   }
+     205             : 
+     206             :   // Add the local constant pool at the end of the function (if exists).
+     207       31895 :   if (_localConstPool) {
+     208           0 :     setCursor(func->getEnd()->getPrev());
+     209           0 :     addNode(_localConstPool);
+     210           0 :     _localConstPool = nullptr;
+     211             :   }
+     212             : 
+     213             :   // Mark as finished.
+     214       31895 :   func->_isFinished = true;
+     215       31895 :   _func = nullptr;
+     216             : 
+     217             :   CBSentinel* end = func->getEnd();
+     218       31895 :   setCursor(end);
+     219       31895 :   return end;
+     220             : }
+     221             : 
+     222             : // ============================================================================
+     223             : // [asmjit::CodeCompiler - Ret]
+     224             : // ============================================================================
+     225             : 
+     226       31895 : CCFuncRet* CodeCompiler::newRet(const Operand_& o0, const Operand_& o1) noexcept {
+     227       31895 :   CCFuncRet* node = newNodeT<CCFuncRet>(o0, o1);
+     228       31895 :   if (!node) {
+     229           0 :     setLastError(DebugUtils::errored(kErrorNoHeapMemory));
+     230           0 :     return nullptr;
+     231             :   }
+     232             :   return node;
+     233             : }
+     234             : 
+     235       31895 : CCFuncRet* CodeCompiler::addRet(const Operand_& o0, const Operand_& o1) noexcept {
+     236       31895 :   CCFuncRet* node = newRet(o0, o1);
+     237       31895 :   if (!node) return nullptr;
+     238       31895 :   return static_cast<CCFuncRet*>(addNode(node));
+     239             : }
+     240             : 
+     241             : // ============================================================================
+     242             : // [asmjit::CodeCompiler - Call]
+     243             : // ============================================================================
+     244             : 
+     245       12914 : CCFuncCall* CodeCompiler::newCall(uint32_t instId, const Operand_& o0, const FuncSignature& sign) noexcept {
+     246             :   Error err;
+     247             :   uint32_t nArgs;
+     248             : 
+     249       12914 :   CCFuncCall* node = _cbHeap.allocT<CCFuncCall>(sizeof(CCFuncCall) + sizeof(Operand));
+     250       12914 :   Operand* opArray = reinterpret_cast<Operand*>(reinterpret_cast<uint8_t*>(node) + sizeof(CCFuncCall));
+     251             : 
+     252       12914 :   if (ASMJIT_UNLIKELY(!node))
+     253           0 :     goto _NoMemory;
+     254             : 
+     255       12914 :   opArray[0].copyFrom(o0);
+     256             :   new (node) CCFuncCall(this, instId, 0, opArray, 1);
+     257             : 
+     258       12914 :   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       12914 :   if ((nArgs = sign.getArgCount()) == 0)
+     265             :     return node;
+     266             : 
+     267       12914 :   node->_args = static_cast<Operand*>(_cbHeap.alloc(nArgs * sizeof(Operand)));
+     268       12914 :   if (!node->_args) goto _NoMemory;
+     269             : 
+     270             :   ::memset(node->_args, 0, nArgs * sizeof(Operand));
+     271       12914 :   return node;
+     272             : 
+     273           0 : _NoMemory:
+     274           0 :   setLastError(DebugUtils::errored(kErrorNoHeapMemory));
+     275           0 :   return nullptr;
+     276             : }
+     277             : 
+     278       12914 : CCFuncCall* CodeCompiler::addCall(uint32_t instId, const Operand_& o0, const FuncSignature& sign) noexcept {
+     279       12914 :   CCFuncCall* node = newCall(instId, o0, sign);
+     280       12914 :   if (!node) return nullptr;
+     281       12914 :   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      315112 : VirtReg* CodeCompiler::newVirtReg(uint32_t typeId, uint32_t signature, const char* name) noexcept {
+     322             :   size_t index = _vRegArray.getLength();
+     323      315112 :   if (ASMJIT_UNLIKELY(index > Operand::kPackedIdCount))
+     324             :     return nullptr;
+     325             : 
+     326             :   VirtReg* vreg;
+     327      384791 :   if (_vRegArray.willGrow(&_cbHeap, 1) != kErrorOk || !(vreg = _vRegZone.allocZeroedT<VirtReg>()))
+     328           0 :     return nullptr;
+     329             : 
+     330      315112 :   vreg->_id = Operand::packId(static_cast<uint32_t>(index));
+     331      315112 :   vreg->_regInfo._signature = signature;
+     332      315112 :   vreg->_name = noName;
+     333             : 
+     334             : #if !defined(ASMJIT_DISABLE_LOGGING)
+     335      315112 :   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      315112 :   vreg->_size = TypeId::sizeOf(typeId);
+     340      315112 :   vreg->_typeId = typeId;
+     341      315112 :   vreg->_alignment = static_cast<uint8_t>(std::min<uint32_t>(vreg->_size, 64));
+     342      315112 :   vreg->_priority = 10;
+     343             : 
+     344             :   // The following are only used by `RAPass`.
+     345      315112 :   vreg->_raId = kInvalidValue;
+     346      315112 :   vreg->_state = VirtReg::kStateNone;
+     347      315112 :   vreg->_physId = Globals::kInvalidRegId;
+     348             : 
+     349             :   _vRegArray.appendUnsafe(vreg);
+     350      315112 :   return vreg;
+     351             : }
+     352             : 
+     353      315112 : Error CodeCompiler::_newReg(Reg& out, uint32_t typeId, const char* name) {
+     354             :   RegInfo regInfo;
+     355             : 
+     356      315112 :   Error err = ArchUtils::typeIdToRegInfo(getArchType(), typeId, regInfo);
+     357      315112 :   if (ASMJIT_UNLIKELY(err)) return setLastError(err);
+     358             : 
+     359      315112 :   VirtReg* vReg = newVirtReg(typeId, regInfo.getSignature(), name);
+     360      315112 :   if (ASMJIT_UNLIKELY(!vReg)) {
+     361             :     out.reset();
+     362           0 :     return setLastError(DebugUtils::errored(kErrorNoHeapMemory));
+     363             :   }
+     364             : 
+     365             :   out._initReg(regInfo.getSignature(), vReg->getId());
+     366      315112 :   return kErrorOk;
+     367             : }
+     368             : 
+     369           0 : Error CodeCompiler::_newReg(Reg& out, uint32_t typeId, const char* nameFmt, va_list ap) {
+     370             :   StringBuilderTmp<256> sb;
+     371             :   sb.appendFormatVA(nameFmt, ap);
+     372           0 :   return _newReg(out, typeId, sb.getData());
+     373             : }
+     374             : 
+     375           0 : Error CodeCompiler::_newReg(Reg& out, const Reg& ref, const char* name) {
+     376             :   RegInfo regInfo;
+     377             :   uint32_t typeId;
+     378             : 
+     379           0 :   if (isVirtRegValid(ref)) {
+     380             :     VirtReg* vRef = getVirtReg(ref);
+     381           0 :     typeId = vRef->getTypeId();
+     382             : 
+     383             :     // NOTE: It's possible to cast one register type to another if it's the
+     384             :     // same register kind. However, VirtReg always contains the TypeId that
+     385             :     // was used to create the register. This means that in some cases we may
+     386             :     // end up having different size of `ref` and `vRef`. In such case we
+     387             :     // adjust the TypeId to match the `ref` register type instead of the
+     388             :     // original register type, which should be the expected behavior.
+     389             :     uint32_t typeSize = TypeId::sizeOf(typeId);
+     390             :     uint32_t refSize = ref.getSize();
+     391             : 
+     392           0 :     if (typeSize != refSize) {
+     393           0 :       if (TypeId::isInt(typeId)) {
+     394             :         // GP register - change TypeId to match `ref`, but keep sign of `vRef`.
+     395           0 :         switch (refSize) {
+     396           0 :           case  1: typeId = TypeId::kI8  | (typeId & 1); break;
+     397           0 :           case  2: typeId = TypeId::kI16 | (typeId & 1); break;
+     398           0 :           case  4: typeId = TypeId::kI32 | (typeId & 1); break;
+     399           0 :           case  8: typeId = TypeId::kI64 | (typeId & 1); break;
+     400           0 :           default: typeId = TypeId::kVoid; break;
+     401             :         }
+     402             :       }
+     403           0 :       else if (TypeId::isMmx(typeId)) {
+     404             :         // MMX register - always use 64-bit.
+     405           0 :         typeId = TypeId::kMmx64;
+     406             :       }
+     407           0 :       else if (TypeId::isMask(typeId)) {
+     408             :         // Mask register - change TypeId to match `ref` size.
+     409           0 :         switch (refSize) {
+     410           0 :           case  1: typeId = TypeId::kMask8; break;
+     411           0 :           case  2: typeId = TypeId::kMask16; break;
+     412           0 :           case  4: typeId = TypeId::kMask32; break;
+     413           0 :           case  8: typeId = TypeId::kMask64; break;
+     414           0 :           default: typeId = TypeId::kVoid; break;
+     415             :         }
+     416             :       }
+     417             :       else {
+     418             :         // VEC register - change TypeId to match `ref` size, keep vector metadata.
+     419             :         uint32_t elementTypeId = TypeId::elementOf(typeId);
+     420             : 
+     421           0 :         switch (refSize) {
+     422           0 :           case 16: typeId = TypeId::_kVec128Start + (elementTypeId - TypeId::kI8); break;
+     423           0 :           case 32: typeId = TypeId::_kVec256Start + (elementTypeId - TypeId::kI8); break;
+     424           0 :           case 64: typeId = TypeId::_kVec512Start + (elementTypeId - TypeId::kI8); break;
+     425           0 :           default: typeId = TypeId::kVoid; break;
+     426             :         }
+     427             :       }
+     428             : 
+     429           0 :       if (typeId == TypeId::kVoid)
+     430           0 :         return setLastError(DebugUtils::errored(kErrorInvalidState));
+     431             :     }
+     432             :   }
+     433             :   else {
+     434           0 :     typeId = ref.getType();
+     435             :   }
+     436             : 
+     437           0 :   Error err = ArchUtils::typeIdToRegInfo(getArchType(), typeId, regInfo);
+     438           0 :   if (ASMJIT_UNLIKELY(err)) return setLastError(err);
+     439             : 
+     440           0 :   VirtReg* vReg = newVirtReg(typeId, regInfo.getSignature(), name);
+     441           0 :   if (ASMJIT_UNLIKELY(!vReg)) {
+     442             :     out.reset();
+     443           0 :     return setLastError(DebugUtils::errored(kErrorNoHeapMemory));
+     444             :   }
+     445             : 
+     446             :   out._initReg(regInfo.getSignature(), vReg->getId());
+     447           0 :   return kErrorOk;
+     448             : }
+     449             : 
+     450           0 : Error CodeCompiler::_newReg(Reg& out, const Reg& ref, const char* nameFmt, va_list ap) {
+     451             :   StringBuilderTmp<256> sb;
+     452             :   sb.appendFormatVA(nameFmt, ap);
+     453           0 :   return _newReg(out, ref, sb.getData());
+     454             : }
+     455             : 
+     456           0 : Error CodeCompiler::_newStack(Mem& out, uint32_t size, uint32_t alignment, const char* name) {
+     457           0 :   if (size == 0)
+     458           0 :     return setLastError(DebugUtils::errored(kErrorInvalidArgument));
+     459             : 
+     460             :   if (alignment == 0) alignment = 1;
+     461             :   if (!Utils::isPowerOf2(alignment))
+     462           0 :     return setLastError(DebugUtils::errored(kErrorInvalidArgument));
+     463             : 
+     464             :   if (alignment > 64) alignment = 64;
+     465             : 
+     466           0 :   VirtReg* vReg = newVirtReg(0, 0, name);
+     467           0 :   if (ASMJIT_UNLIKELY(!vReg)) {
+     468             :     out.reset();
+     469           0 :     return setLastError(DebugUtils::errored(kErrorNoHeapMemory));
+     470             :   }
+     471             : 
+     472           0 :   vReg->_size = size;
+     473           0 :   vReg->_isStack = true;
+     474           0 :   vReg->_alignment = static_cast<uint8_t>(alignment);
+     475             : 
+     476             :   // Set the memory operand to GPD/GPQ and its id to VirtReg.
+     477           0 :   out = Mem(Init, _nativeGpReg.getType(), vReg->getId(), Reg::kRegNone, kInvalidValue, 0, 0, Mem::kSignatureMemRegHomeFlag);
+     478           0 :   return kErrorOk;
+     479             : }
+     480             : 
+     481           0 : Error CodeCompiler::_newConst(Mem& out, uint32_t scope, const void* data, size_t size) {
+     482             :   CBConstPool** pPool;
+     483           0 :   if (scope == kConstScopeLocal)
+     484           0 :     pPool = &_localConstPool;
+     485           0 :   else if (scope == kConstScopeGlobal)
+     486           0 :     pPool = &_globalConstPool;
+     487             :   else
+     488           0 :     return setLastError(DebugUtils::errored(kErrorInvalidArgument));
+     489             : 
+     490           0 :   if (!*pPool && !(*pPool = newConstPool()))
+     491           0 :     return setLastError(DebugUtils::errored(kErrorNoHeapMemory));
+     492             : 
+     493           0 :   CBConstPool* pool = *pPool;
+     494             :   size_t off;
+     495             : 
+     496             :   Error err = pool->add(data, size, off);
+     497           0 :   if (ASMJIT_UNLIKELY(err)) return setLastError(err);
+     498             : 
+     499           0 :   out = Mem(Init,
+     500             :     Label::kLabelTag,             // Base type.
+     501             :     pool->getId(),                // Base id.
+     502             :     0,                            // Index type.
+     503             :     kInvalidValue,                // Index id.
+     504             :     static_cast<int32_t>(off),    // Offset.
+     505             :     static_cast<uint32_t>(size),  // Size.
+     506             :     0);                           // Flags.
+     507           0 :   return kErrorOk;
+     508             : }
+     509             : 
+     510           0 : Error CodeCompiler::alloc(Reg& reg) {
+     511           0 :   if (!reg.isVirtReg()) return kErrorOk;
+     512           0 :   return _hint(reg, CCHint::kHintAlloc, kInvalidValue);
+     513             : }
+     514             : 
+     515           0 : Error CodeCompiler::alloc(Reg& reg, uint32_t physId) {
+     516           0 :   if (!reg.isVirtReg()) return kErrorOk;
+     517           0 :   return _hint(reg, CCHint::kHintAlloc, physId);
+     518             : }
+     519             : 
+     520           0 : Error CodeCompiler::alloc(Reg& reg, const Reg& physReg) {
+     521           0 :   if (!reg.isVirtReg()) return kErrorOk;
+     522           0 :   return _hint(reg, CCHint::kHintAlloc, physReg.getId());
+     523             : }
+     524             : 
+     525           0 : Error CodeCompiler::save(Reg& reg) {
+     526           0 :   if (!reg.isVirtReg()) return kErrorOk;
+     527           0 :   return _hint(reg, CCHint::kHintSave, kInvalidValue);
+     528             : }
+     529             : 
+     530           0 : Error CodeCompiler::spill(Reg& reg) {
+     531           0 :   if (!reg.isVirtReg()) return kErrorOk;
+     532           0 :   return _hint(reg, CCHint::kHintSpill, kInvalidValue);
+     533             : }
+     534             : 
+     535           0 : Error CodeCompiler::unuse(Reg& reg) {
+     536           0 :   if (!reg.isVirtReg()) return kErrorOk;
+     537           0 :   return _hint(reg, CCHint::kHintUnuse, kInvalidValue);
+     538             : }
+     539             : 
+     540           0 : uint32_t CodeCompiler::getPriority(Reg& reg) const {
+     541           0 :   if (!reg.isVirtReg()) return 0;
+     542           0 :   return getVirtRegById(reg.getId())->getPriority();
+     543             : }
+     544             : 
+     545           0 : void CodeCompiler::setPriority(Reg& reg, uint32_t priority) {
+     546           0 :   if (!reg.isVirtReg()) return;
+     547             :   if (priority > 255) priority = 255;
+     548             : 
+     549             :   VirtReg* vreg = getVirtRegById(reg.getId());
+     550           0 :   if (vreg) vreg->_priority = static_cast<uint8_t>(priority);
+     551             : }
+     552             : 
+     553           0 : bool CodeCompiler::getSaveOnUnuse(Reg& reg) const {
+     554           0 :   if (!reg.isVirtReg()) return false;
+     555             : 
+     556             :   VirtReg* vreg = getVirtRegById(reg.getId());
+     557           0 :   return static_cast<bool>(vreg->_saveOnUnuse);
+     558             : }
+     559             : 
+     560           0 : void CodeCompiler::setSaveOnUnuse(Reg& reg, bool value) {
+     561           0 :   if (!reg.isVirtReg()) return;
+     562             : 
+     563             :   VirtReg* vreg = getVirtRegById(reg.getId());
+     564           0 :   if (!vreg) return;
+     565             : 
+     566           0 :   vreg->_saveOnUnuse = value;
+     567             : }
+     568             : 
+     569           0 : void CodeCompiler::rename(Reg& reg, const char* fmt, ...) {
+     570           0 :   if (!reg.isVirtReg()) return;
+     571             : 
+     572             :   VirtReg* vreg = getVirtRegById(reg.getId());
+     573           0 :   if (!vreg) return;
+     574             : 
+     575           0 :   vreg->_name = noName;
+     576           0 :   if (fmt && fmt[0] != '\0') {
+     577             :     char buf[64];
+     578             : 
+     579             :     va_list ap;
+     580           0 :     va_start(ap, fmt);
+     581             : 
+     582             :     vsnprintf(buf, ASMJIT_ARRAY_SIZE(buf), fmt, ap);
+     583           0 :     buf[ASMJIT_ARRAY_SIZE(buf) - 1] = '\0';
+     584             : 
+     585           0 :     vreg->_name = static_cast<char*>(_cbDataZone.dup(buf, ::strlen(buf), true));
+     586           0 :     va_end(ap);
+     587             :   }
+     588             : }
+     589             : 
+     590             : } // asmjit namespace
+     591             : } // namespace PLMD
+     592             : 
+     593             : // [Api-End]
+     594             : #include "./asmjit_apiend.h"
+     595             : 
+     596             : // [Guard]
+     597             : #endif // !ASMJIT_DISABLE_COMPILER
+     598             : #pragma GCC diagnostic pop
+     599             : #endif // __PLUMED_HAS_ASMJIT
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/codecompiler.h.func-sort-c.html b/coverage-libs/asmjit/codecompiler.h.func-sort-c.html new file mode 100644 index 000000000000..512c8f2b2b5b --- /dev/null +++ b/coverage-libs/asmjit/codecompiler.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/codecompiler.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - codecompiler.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:416464.1 %
Date:2024-04-19 12:12:36Functions:00-
+
+ +
+ + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/codecompiler.h.gcov.html b/coverage-libs/asmjit/codecompiler.h.gcov.html new file mode 100644 index 000000000000..1e1de11e6062 --- /dev/null +++ b/coverage-libs/asmjit/codecompiler.h.gcov.html @@ -0,0 +1,844 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/codecompiler.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - codecompiler.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:416464.1 %
Date:2024-04-19 12:12:36Functions: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      406220 :   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      105652 :   ASMJIT_INLINE uint32_t getTypeId() const noexcept { return _typeId; }
+     110             : 
+     111             :   //! Get virtual-register's size.
+     112      336336 :   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       68002 :   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      326424 :   }
+     131             : 
+     132             :   //! Get register index.
+     133     2348360 :   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       14544 :     _physId = static_cast<uint8_t>(physId);
+     138             :   }
+     139             :   //! Reset register index.
+     140             :   ASMJIT_INLINE void resetPhysId() {
+     141      650025 :     _physId = static_cast<uint8_t>(Globals::kInvalidRegId);
+     142             :   }
+     143             : 
+     144             :   //! Get home registers mask.
+     145      365188 :   ASMJIT_INLINE uint32_t getHomeMask() const { return _homeMask; }
+     146             :   //! Add a home register index to the home registers mask.
+     147       51696 :   ASMJIT_INLINE void addHomeId(uint32_t physId) { _homeMask |= Utils::mask(physId); }
+     148             : 
+     149      366382 :   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      122577 :   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      129248 :   ASMJIT_INLINE bool isModified() const noexcept { return static_cast<bool>(_modified); }
+     159             :   //! Set whether the variable was changed.
+     160     1137960 :   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       91108 :   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       31895 :     : CBLabel(cb),
+     298       31895 :       _funcDetail(),
+     299       31895 :       _frameInfo(),
+     300       31895 :       _exitNode(nullptr),
+     301       31895 :       _end(nullptr),
+     302       31895 :       _args(nullptr),
+     303       31895 :       _isFinished(false) {
+     304             : 
+     305       31895 :     _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      127580 :   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      127580 :   ASMJIT_INLINE CBSentinel* getEnd() const noexcept { return _end; }
+     322             : 
+     323             :   //! Get function declaration.
+     324       31895 :   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       31895 :   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       31895 :   ASMJIT_INLINE CCFuncRet(CodeBuilder* cb, const Operand_& o0, const Operand_& o1) noexcept : CBNode(cb, kNodeFuncExit) {
+     393             :     orFlags(kFlagIsRet);
+     394       31895 :     _ret[0].copyFrom(o0);
+     395       31895 :     _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       12914 :     : CBInst(cb, instId, options, opArray, opCount),
+     439       12914 :       _funcDetail(),
+     440       12914 :       _args(nullptr) {
+     441             : 
+     442       12914 :     _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       12512 :   ASMJIT_INLINE bool setArg(uint32_t i, const Reg& reg) noexcept { return _setArg(i, reg); }
+     503             :   //! Set argument at `i` to `imm`.
+     504         402 :   ASMJIT_INLINE bool setArg(uint32_t i, const Imm& imm) noexcept { return _setArg(i, imm); }
+     505             : 
+     506             :   //! Set return at `i` to `var`.
+     507       12914 :   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       31895 :   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      166330 :     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     1463913 :     size_t index = Operand::unpackId(id);
+     705             : 
+     706             :     ASMJIT_ASSERT(index < _vRegArray.getLength());
+     707     1630243 :     return _vRegArray[index];
+     708             :   }
+     709             : 
+     710             :   //! Get an array of all virtual registers managed by CodeCompiler.
+     711             :   ASMJIT_INLINE const ZoneVector<VirtReg*>& getVirtRegArray() const noexcept { return _vRegArray; }
+     712             : 
+     713             :   //! Alloc a virtual register `reg`.
+     714             :   ASMJIT_API Error alloc(Reg& reg);
+     715             :   //! Alloc a virtual register `reg` using `physId` as a register id.
+     716             :   ASMJIT_API Error alloc(Reg& reg, uint32_t physId);
+     717             :   //! Alloc a virtual register `reg` using `ref` as a register operand.
+     718             :   ASMJIT_API Error alloc(Reg& reg, const Reg& ref);
+     719             :   //! Spill a virtual register `reg`.
+     720             :   ASMJIT_API Error spill(Reg& reg);
+     721             :   //! Save a virtual register `reg` if the status is `modified` at this point.
+     722             :   ASMJIT_API Error save(Reg& reg);
+     723             :   //! Unuse a virtual register `reg`.
+     724             :   ASMJIT_API Error unuse(Reg& reg);
+     725             : 
+     726             :   //! Get priority of a virtual register `reg`.
+     727             :   ASMJIT_API uint32_t getPriority(Reg& reg) const;
+     728             :   //! Set priority of variable `reg` to `priority`.
+     729             :   ASMJIT_API void setPriority(Reg& reg, uint32_t priority);
+     730             : 
+     731             :   //! Get save-on-unuse `reg` property.
+     732             :   ASMJIT_API bool getSaveOnUnuse(Reg& reg) const;
+     733             :   //! Set save-on-unuse `reg` property to `value`.
+     734             :   ASMJIT_API void setSaveOnUnuse(Reg& reg, bool value);
+     735             : 
+     736             :   //! Rename variable `reg` to `name`.
+     737             :   //!
+     738             :   //! NOTE: Only new name will appear in the logger.
+     739             :   ASMJIT_API void rename(Reg& reg, const char* fmt, ...);
+     740             : 
+     741             :   // --------------------------------------------------------------------------
+     742             :   // [Members]
+     743             :   // --------------------------------------------------------------------------
+     744             : 
+     745             :   CCFunc* _func;                         //!< Current function.
+     746             : 
+     747             :   Zone _vRegZone;                        //!< Allocates \ref VirtReg objects.
+     748             :   ZoneVector<VirtReg*> _vRegArray;       //!< Stores array of \ref VirtReg pointers.
+     749             : 
+     750             :   CBConstPool* _localConstPool;          //!< Local constant pool, flushed at the end of each function.
+     751             :   CBConstPool* _globalConstPool;         //!< Global constant pool, flushed at the end of the compilation.
+     752             : };
+     753             : 
+     754             : //! \}
+     755             : 
+     756             : } // asmjit namespace
+     757             : } // namespace PLMD
+     758             : 
+     759             : // [Api-End]
+     760             : #include "./asmjit_apiend.h"
+     761             : 
+     762             : // [Guard]
+     763             : #endif // !ASMJIT_DISABLE_COMPILER
+     764             : #endif // _ASMJIT_BASE_CODECOMPILER_H
+     765             : #pragma GCC diagnostic pop
+     766             : #endif // __PLUMED_HAS_ASMJIT
+     767             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/codeemitter.cpp.func-sort-c.html b/coverage-libs/asmjit/codeemitter.cpp.func-sort-c.html new file mode 100644 index 000000000000..8b12b8b3f1b2 --- /dev/null +++ b/coverage-libs/asmjit/codeemitter.cpp.func-sort-c.html @@ -0,0 +1,197 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/codeemitter.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - codeemitter.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:329533.7 %
Date:2024-04-19 12:12:36Functions: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_2270
_ZN4PLMD6asmjit11CodeEmitter4emitEjRKNS0_8Operand_Ei4588
_ZN4PLMD6asmjit11CodeEmitter4emitEjRKNS0_8Operand_El4588
_ZN4PLMD6asmjit11CodeEmitter4emitEjRKNS0_8Operand_E14048
_ZN4PLMD6asmjit11CodeEmitter4emitEj31895
_ZN4PLMD6asmjit11CodeEmitter8onAttachEPNS0_10CodeHolderE63790
_ZN4PLMD6asmjit11CodeEmitterC2Ej63790
_ZN4PLMD6asmjit11CodeEmitterD2Ev63790
_ZN4PLMD6asmjit11CodeEmitter4emitEjRKNS0_8Operand_ES4_517261
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/codeemitter.cpp.func.html b/coverage-libs/asmjit/codeemitter.cpp.func.html new file mode 100644 index 000000000000..d12ab4e1c556 --- /dev/null +++ b/coverage-libs/asmjit/codeemitter.cpp.func.html @@ -0,0 +1,197 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/codeemitter.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - codeemitter.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:329533.7 %
Date:2024-04-19 12:12:36Functions:93129.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit11CodeEmitter12_emitOpArrayEjPKNS0_8Operand_Em0
_ZN4PLMD6asmjit11CodeEmitter12setLastErrorEjPKc0
_ZN4PLMD6asmjit11CodeEmitter14getLabelByNameEPKcmj0
_ZN4PLMD6asmjit11CodeEmitter4emitEj31895
_ZN4PLMD6asmjit11CodeEmitter4emitEjRKNS0_8Operand_E14048
_ZN4PLMD6asmjit11CodeEmitter4emitEjRKNS0_8Operand_ES4_517261
_ZN4PLMD6asmjit11CodeEmitter4emitEjRKNS0_8Operand_ES4_S4_2270
_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_Ei4588
_ZN4PLMD6asmjit11CodeEmitter4emitEjRKNS0_8Operand_El4588
_ZN4PLMD6asmjit11CodeEmitter4emitEji0
_ZN4PLMD6asmjit11CodeEmitter4emitEjl0
_ZN4PLMD6asmjit11CodeEmitter8commentfEPKcz0
_ZN4PLMD6asmjit11CodeEmitter8commentvEPKcP13__va_list_tag0
_ZN4PLMD6asmjit11CodeEmitter8finalizeEv0
_ZN4PLMD6asmjit11CodeEmitter8onAttachEPNS0_10CodeHolderE63790
_ZN4PLMD6asmjit11CodeEmitter8onDetachEPNS0_10CodeHolderE0
_ZN4PLMD6asmjit11CodeEmitterC2Ej63790
_ZN4PLMD6asmjit11CodeEmitterD0Ev0
_ZN4PLMD6asmjit11CodeEmitterD2Ev63790
_ZNK4PLMD6asmjit11CodeEmitter12isLabelValidEj0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/codeemitter.cpp.gcov.html b/coverage-libs/asmjit/codeemitter.cpp.gcov.html new file mode 100644 index 000000000000..fa359948401c --- /dev/null +++ b/coverage-libs/asmjit/codeemitter.cpp.gcov.html @@ -0,0 +1,339 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/codeemitter.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - codeemitter.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:329533.7 %
Date:2024-04-19 12:12:36Functions: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       63790 : CodeEmitter::CodeEmitter(uint32_t type) noexcept
+      56             :   : _codeInfo(),
+      57       63790 :     _code(nullptr),
+      58       63790 :     _nextEmitter(nullptr),
+      59       63790 :     _type(static_cast<uint8_t>(type)),
+      60       63790 :     _destroyed(false),
+      61       63790 :     _finalized(false),
+      62       63790 :     _reserved(false),
+      63       63790 :     _lastError(kErrorNotInitialized),
+      64       63790 :     _privateData(0),
+      65       63790 :     _globalHints(0),
+      66       63790 :     _globalOptions(kOptionMaybeFailureCase),
+      67       63790 :     _options(0),
+      68       63790 :     _extraReg(),
+      69       63790 :     _inlineComment(nullptr),
+      70       63790 :     _none(),
+      71             :     _nativeGpReg(),
+      72       63790 :     _nativeGpArray(nullptr) {}
+      73             : 
+      74       63790 : CodeEmitter::~CodeEmitter() noexcept {
+      75       63790 :   if (_code) {
+      76       63790 :     _destroyed = true;
+      77       63790 :     _code->detach(this);
+      78             :   }
+      79       63790 : }
+      80             : 
+      81             : // ============================================================================
+      82             : // [asmjit::CodeEmitter - Events]
+      83             : // ============================================================================
+      84             : 
+      85       63790 : Error CodeEmitter::onAttach(CodeHolder* code) noexcept {
+      86             :   _codeInfo = code->getCodeInfo();
+      87       63790 :   _lastError = kErrorOk;
+      88             : 
+      89       63790 :   _globalHints = code->getGlobalHints();
+      90       63790 :   _globalOptions = code->getGlobalOptions();
+      91             : 
+      92       63790 :   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       31895 : Error CodeEmitter::emit(uint32_t instId) { return _emit(instId, _none, _none, _none, _none); }
+     232       14048 : Error CodeEmitter::emit(uint32_t instId, OP o0) { return _emit(instId, o0, _none, _none, _none); }
+     233      517261 : Error CodeEmitter::emit(uint32_t instId, OP o0, OP o1) { return _emit(instId, o0, o1, _none, _none); }
+     234        2270 : 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        4588 : 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        4588 : Error CodeEmitter::emit(uint32_t instId, OP o0, int64_t o1) { return _emit(instId, o0, Imm(o1), _none, _none); }
+     248           0 : Error CodeEmitter::emit(uint32_t instId, OP o0, OP o1, int64_t o2) { return _emit(instId, o0, o1, Imm(o2), _none); }
+     249           0 : Error CodeEmitter::emit(uint32_t instId, OP o0, OP o1, OP o2, int64_t o3) { return _emit(instId, o0, o1, o2, Imm(o3)); }
+     250             : 
+     251           0 : Error CodeEmitter::emit(uint32_t instId, OP o0, OP o1, OP o2, OP o3, int64_t o4) { return _emit(instId, o0, o1, o2, o3, Imm(o4), _none); }
+     252           0 : Error CodeEmitter::emit(uint32_t instId, OP o0, OP o1, OP o2, OP o3, OP o4, int64_t o5) { return _emit(instId, o0, o1, o2, o3, o4, Imm(o5)); }
+     253             : 
+     254             : #undef OP
+     255             : 
+     256             : } // asmjit namespace
+     257             : } // namespace PLMD
+     258             : 
+     259             : // [Api-End]
+     260             : #include "./asmjit_apiend.h"
+     261             : #pragma GCC diagnostic pop
+     262             : #endif // __PLUMED_HAS_ASMJIT
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/codeemitter.h.func-sort-c.html b/coverage-libs/asmjit/codeemitter.h.func-sort-c.html new file mode 100644 index 000000000000..120b8c1b11c3 --- /dev/null +++ b/coverage-libs/asmjit/codeemitter.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/codeemitter.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - codeemitter.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:91181.8 %
Date:2024-04-19 12:12:36Functions:00-
+
+ +
+ + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/codeemitter.h.gcov.html b/coverage-libs/asmjit/codeemitter.h.gcov.html new file mode 100644 index 000000000000..8cfa412a51b6 --- /dev/null +++ b/coverage-libs/asmjit/codeemitter.h.gcov.html @@ -0,0 +1,605 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/codeemitter.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - codeemitter.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:91181.8 %
Date:2024-04-19 12:12:36Functions: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      127580 :   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     1226004 :   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     1162214 :   ASMJIT_INLINE uint32_t getOptions() const noexcept { return _options; }
+     336             :   //! Set options of the next instruction.
+     337      587564 :   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     1162214 :   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      574650 :   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      820796 :   ASMJIT_INLINE void setInlineComment(const char* s) noexcept { _inlineComment = s; }
+     362             :   //! Reset annotation of the next instruction to null.
+     363     1226004 :   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      587564 :     return _emitOpArray(instId, opArray, opCount);
+     487             :   }
+     488             : 
+     489             :   // --------------------------------------------------------------------------
+     490             :   // [Members]
+     491             :   // --------------------------------------------------------------------------
+     492             : 
+     493             :   CodeInfo _codeInfo;                    //!< Basic information about the code (matches CodeHolder::_codeInfo).
+     494             :   CodeHolder* _code;                     //!< CodeHolder the CodeEmitter is attached to.
+     495             :   CodeEmitter* _nextEmitter;             //!< Linked list of `CodeEmitter`s attached to the same \ref CodeHolder.
+     496             : 
+     497             :   uint8_t _type;                         //!< See CodeEmitter::Type.
+     498             :   uint8_t _destroyed;                    //!< Set by ~CodeEmitter() before calling `_code->detach()`.
+     499             :   uint8_t _finalized;                    //!< True if the CodeEmitter is finalized (CodeBuilder & CodeCompiler).
+     500             :   uint8_t _reserved;                     //!< \internal
+     501             :   Error _lastError;                      //!< Last error code.
+     502             : 
+     503             :   uint32_t _privateData;                 //!< Internal private data used freely by any CodeEmitter.
+     504             :   uint32_t _globalHints;                 //!< Global hints, always in sync with CodeHolder.
+     505             :   uint32_t _globalOptions;               //!< Global options, combined with `_options` before used by each instruction.
+     506             : 
+     507             :   uint32_t _options;                     //!< Used to pass instruction options        (affects the next instruction).
+     508             :   RegOnly _extraReg;                     //!< Extra register (op-mask {k} on AVX-512) (affects the next instruction).
+     509             :   const char* _inlineComment;            //!< Inline comment of the next instruction  (affects the next instruction).
+     510             : 
+     511             :   Operand_ _none;                        //!< Used to pass unused operands to `_emit()` instead of passing null.
+     512             :   Reg _nativeGpReg;                      //!< Native GP register with zero id.
+     513             :   const Reg* _nativeGpArray;             //!< Array of native registers indexed from zero.
+     514             : };
+     515             : 
+     516             : //! \}
+     517             : 
+     518             : } // asmjit namespace
+     519             : } // namespace PLMD
+     520             : 
+     521             : // [Api-End]
+     522             : #include "./asmjit_apiend.h"
+     523             : 
+     524             : // [Guard]
+     525             : #endif // _ASMJIT_BASE_CODEEMITTER_H
+     526             : #pragma GCC diagnostic pop
+     527             : #endif // __PLUMED_HAS_ASMJIT
+     528             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/codeholder.cpp.func-sort-c.html b/coverage-libs/asmjit/codeholder.cpp.func-sort-c.html new file mode 100644 index 000000000000..f27718955ce7 --- /dev/null +++ b/coverage-libs/asmjit/codeholder.cpp.func-sort-c.html @@ -0,0 +1,173 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/codeholder.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - codeholder.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:12025946.3 %
Date:2024-04-19 12:12:36Functions: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_10CodeBufferEm31895
_ZN4PLMD6asmjit10CodeHolder4initERKNS0_8CodeInfoE31895
_ZN4PLMD6asmjit10CodeHolderC2Ev31895
_ZN4PLMD6asmjit10CodeHolderD2Ev31895
_ZN4PLMD6asmjitL24CodeHolder_resetInternalEPNS0_10CodeHolderEb31895
_ZN4PLMD6asmjitL26CodeHolder_reserveInternalEPNS0_10CodeHolderEPNS0_10CodeBufferEm31895
_ZNK4PLMD6asmjit10CodeHolder8relocateEPvm31895
_ZN4PLMD6asmjit10CodeHolder10newLabelIdERj63790
_ZN4PLMD6asmjit10CodeHolder4syncEv63790
_ZN4PLMD6asmjit10CodeHolder6attachEPNS0_11CodeEmitterE63790
_ZN4PLMD6asmjit10CodeHolder6detachEPNS0_11CodeEmitterE63790
_ZNK4PLMD6asmjit10CodeHolder11getCodeSizeEv63790
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/codeholder.cpp.func.html b/coverage-libs/asmjit/codeholder.cpp.func.html new file mode 100644 index 000000000000..a0aa2325f28b --- /dev/null +++ b/coverage-libs/asmjit/codeholder.cpp.func.html @@ -0,0 +1,173 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/codeholder.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - codeholder.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:12025946.3 %
Date:2024-04-19 12:12:36Functions:122548.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit10CodeHolder10growBufferEPNS0_10CodeBufferEm31895
_ZN4PLMD6asmjit10CodeHolder10newLabelIdERj63790
_ZN4PLMD6asmjit10CodeHolder12newLabelLinkEPNS0_10LabelEntryEjml0
_ZN4PLMD6asmjit10CodeHolder13newRelocEntryEPPNS0_10RelocEntryEjj0
_ZN4PLMD6asmjit10CodeHolder13reserveBufferEPNS0_10CodeBufferEm0
_ZN4PLMD6asmjit10CodeHolder15newNamedLabelIdERjPKcmjj0
_ZN4PLMD6asmjit10CodeHolder15setErrorHandlerEPNS0_12ErrorHandlerE0
_ZN4PLMD6asmjit10CodeHolder16getLabelIdByNameEPKcmj0
_ZN4PLMD6asmjit10CodeHolder4initERKNS0_8CodeInfoE31895
_ZN4PLMD6asmjit10CodeHolder4syncEv63790
_ZN4PLMD6asmjit10CodeHolder5resetEb0
_ZN4PLMD6asmjit10CodeHolder6attachEPNS0_11CodeEmitterE63790
_ZN4PLMD6asmjit10CodeHolder6detachEPNS0_11CodeEmitterE63790
_ZN4PLMD6asmjit10CodeHolder9setLoggerEPNS0_6LoggerE0
_ZN4PLMD6asmjit10CodeHolderC2Ev31895
_ZN4PLMD6asmjit10CodeHolderD2Ev31895
_ZN4PLMD6asmjit12ErrorHandlerC2Ev0
_ZN4PLMD6asmjit12ErrorHandlerD0Ev0
_ZN4PLMD6asmjit12ErrorHandlerD2Ev0
_ZN4PLMD6asmjit12_GLOBAL__N_1L28CodeHolder_hashNameAndFixLenEPKcRm0
_ZN4PLMD6asmjitL24CodeHolder_resetInternalEPNS0_10CodeHolderEb31895
_ZN4PLMD6asmjitL26CodeHolder_reserveInternalEPNS0_10CodeHolderEPNS0_10CodeBufferEm31895
_ZN4PLMD6asmjitL26CodeHolder_setGlobalOptionEPNS0_10CodeHolderEjj0
_ZNK4PLMD6asmjit10CodeHolder11getCodeSizeEv63790
_ZNK4PLMD6asmjit10CodeHolder8relocateEPvm31895
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/codeholder.cpp.gcov.html b/coverage-libs/asmjit/codeholder.cpp.gcov.html new file mode 100644 index 000000000000..2049cd604d1c --- /dev/null +++ b/coverage-libs/asmjit/codeholder.cpp.gcov.html @@ -0,0 +1,800 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/codeholder.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - codeholder.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:12025946.3 %
Date:2024-04-19 12:12:36Functions: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       31895 : static void CodeHolder_resetInternal(CodeHolder* self, bool releaseMemory) noexcept {
+      67             :   // Detach all `CodeEmitter`s.
+      68       31895 :   while (self->_emitters)
+      69           0 :     self->detach(self->_emitters);
+      70             : 
+      71             :   // Reset everything into its construction state.
+      72             :   self->_codeInfo.reset();
+      73       31895 :   self->_globalHints = 0;
+      74       31895 :   self->_globalOptions = 0;
+      75       31895 :   self->_logger = nullptr;
+      76       31895 :   self->_errorHandler = nullptr;
+      77             : 
+      78       31895 :   self->_unresolvedLabelsCount = 0;
+      79       31895 :   self->_trampolinesSize = 0;
+      80             : 
+      81             :   // Reset all sections.
+      82             :   size_t numSections = self->_sections.getLength();
+      83       63790 :   for (size_t i = 0; i < numSections; i++) {
+      84       31895 :     SectionEntry* section = self->_sections[i];
+      85       31895 :     if (section->_buffer.hasData() && !section->_buffer.isExternal())
+      86             :       Internal::releaseMemory(section->_buffer._data);
+      87       31895 :     section->_buffer._data = nullptr;
+      88       31895 :     section->_buffer._capacity = 0;
+      89             :   }
+      90             : 
+      91             :   // Reset zone allocator and all containers using it.
+      92       31895 :   ZoneHeap* heap = &self->_baseHeap;
+      93             : 
+      94       31895 :   self->_namedLabels.reset(heap);
+      95             :   self->_relocations.reset();
+      96             :   self->_labels.reset();
+      97             :   self->_sections.reset();
+      98             : 
+      99       31895 :   heap->reset(&self->_baseZone);
+     100       31895 :   self->_baseZone.reset(releaseMemory);
+     101       31895 : }
+     102             : 
+     103             : // ============================================================================
+     104             : // [asmjit::CodeHolder - Construction / Destruction]
+     105             : // ============================================================================
+     106             : 
+     107       31895 : CodeHolder::CodeHolder() noexcept
+     108             :   : _codeInfo(),
+     109       31895 :     _globalHints(0),
+     110       31895 :     _globalOptions(0),
+     111       31895 :     _emitters(nullptr),
+     112       31895 :     _cgAsm(nullptr),
+     113       31895 :     _logger(nullptr),
+     114       31895 :     _errorHandler(nullptr),
+     115       31895 :     _unresolvedLabelsCount(0),
+     116       31895 :     _trampolinesSize(0),
+     117       31895 :     _baseZone(16384 - Zone::kZoneOverhead),
+     118       31895 :     _dataZone(16384 - Zone::kZoneOverhead),
+     119       31895 :     _baseHeap(&_baseZone),
+     120       31895 :     _namedLabels(&_baseHeap) {}
+     121             : 
+     122       31895 : CodeHolder::~CodeHolder() noexcept {
+     123       31895 :   CodeHolder_resetInternal(this, true);
+     124       31895 : }
+     125             : 
+     126             : // ============================================================================
+     127             : // [asmjit::CodeHolder - Init / Reset]
+     128             : // ============================================================================
+     129             : 
+     130       31895 : Error CodeHolder::init(const CodeInfo& info) noexcept {
+     131             :   // Cannot reinitialize if it's locked or there is one or more CodeEmitter
+     132             :   // attached.
+     133       31895 :   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       31895 :   Error err = _sections.willGrow(&_baseHeap);
+     141       31895 :   if (err == kErrorOk) {
+     142       31895 :     SectionEntry* se = _baseZone.allocZeroedT<SectionEntry>();
+     143       31895 :     if (ASMJIT_LIKELY(se)) {
+     144       31895 :       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       31895 :   if (ASMJIT_UNLIKELY(err)) {
+     154           0 :     _baseZone.reset(false);
+     155           0 :     return err;
+     156             :   }
+     157             :   else {
+     158             :     _codeInfo = info;
+     159       31895 :     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       63790 : Error CodeHolder::attach(CodeEmitter* emitter) noexcept {
+     172             :   // Catch a possible misuse of the API.
+     173       63790 :   if (!emitter)
+     174             :     return DebugUtils::errored(kErrorInvalidArgument);
+     175             : 
+     176             :   uint32_t type = emitter->getType();
+     177       63790 :   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       63790 :   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       63790 :   if (type == CodeEmitter::kTypeAssembler) {
+     189       31895 :     if (_cgAsm)
+     190             :       return DebugUtils::errored(kErrorSlotOccupied);
+     191       31895 :     pSlot = reinterpret_cast<CodeEmitter**>(&_cgAsm);
+     192             :   }
+     193             : 
+     194       63790 :   Error err = emitter->onAttach(this);
+     195       63790 :   if (err != kErrorOk) return err;
+     196             : 
+     197             :   // Add to a single-linked list of `CodeEmitter`s.
+     198       63790 :   emitter->_nextEmitter = _emitters;
+     199       63790 :   _emitters = emitter;
+     200       63790 :   if (pSlot) *pSlot = emitter;
+     201             : 
+     202             :   // Establish the connection.
+     203       63790 :   emitter->_code = this;
+     204       63790 :   return kErrorOk;
+     205             : }
+     206             : 
+     207       63790 : Error CodeHolder::detach(CodeEmitter* emitter) noexcept {
+     208       63790 :   if (!emitter)
+     209             :     return DebugUtils::errored(kErrorInvalidArgument);
+     210             : 
+     211       63790 :   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       63790 :   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       63790 :   if (type == CodeEmitter::kTypeAssembler)
+     228       31895 :     _cgAsm = nullptr;
+     229             : 
+     230             :   // Remove from a single-linked list of `CodeEmitter`s.
+     231       63790 :   CodeEmitter** pPrev = &_emitters;
+     232             :   for (;;) {
+     233             :     ASMJIT_ASSERT(*pPrev != nullptr);
+     234       63790 :     CodeEmitter* cur = *pPrev;
+     235             : 
+     236       63790 :     if (cur == emitter) {
+     237       63790 :       *pPrev = emitter->_nextEmitter;
+     238             :       break;
+     239             :     }
+     240             : 
+     241           0 :     pPrev = &cur->_nextEmitter;
+     242           0 :   }
+     243             : 
+     244       63790 :   emitter->_code = nullptr;
+     245       63790 :   emitter->_nextEmitter = nullptr;
+     246             : 
+     247       63790 :   return err;
+     248             : }
+     249             : 
+     250             : // ============================================================================
+     251             : // [asmjit::CodeHolder - Sync]
+     252             : // ============================================================================
+     253             : 
+     254       63790 : void CodeHolder::sync() noexcept {
+     255       63790 :   if (_cgAsm) _cgAsm->sync();
+     256       63790 : }
+     257             : 
+     258             : // ============================================================================
+     259             : // [asmjit::CodeHolder - Result Information]
+     260             : // ============================================================================
+     261             : 
+     262       63790 : size_t CodeHolder::getCodeSize() const noexcept {
+     263             :   // Reflect all changes first.
+     264       63790 :   const_cast<CodeHolder*>(this)->sync();
+     265             : 
+     266             :   // TODO: Support sections.
+     267       63790 :   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       31895 : static Error CodeHolder_reserveInternal(CodeHolder* self, CodeBuffer* cb, size_t n) noexcept {
+     294       31895 :   uint8_t* oldData = cb->_data;
+     295             :   uint8_t* newData;
+     296             : 
+     297       31895 :   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       31895 :   if (ASMJIT_UNLIKELY(!newData))
+     303             :     return DebugUtils::errored(kErrorNoHeapMemory);
+     304             : 
+     305       31895 :   cb->_data = newData;
+     306       31895 :   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       31895 :   Assembler* a = self->_cgAsm;
+     312       31895 :   if (a && &a->_section->_buffer == cb) {
+     313             :     size_t offset = a->getOffset();
+     314             : 
+     315       31895 :     a->_bufferData = newData;
+     316       31895 :     a->_bufferEnd  = newData + n;
+     317       31895 :     a->_bufferPtr  = newData + offset;
+     318             :   }
+     319             : 
+     320             :   return kErrorOk;
+     321             : }
+     322             : 
+     323       31895 : 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       31895 :   if (_cgAsm) _cgAsm->sync();
+     329             : 
+     330             :   // Now the length of the section must be valid.
+     331             :   size_t length = cb->getLength();
+     332       31895 :   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       31895 :   size_t required = cb->getLength() + n;
+     339       31895 :   if (ASMJIT_UNLIKELY(required <= capacity)) return kErrorOk;
+     340             : 
+     341       31895 :   if (cb->isFixedSize())
+     342             :     return DebugUtils::errored(kErrorCodeTooLarge);
+     343             : 
+     344       31895 :   if (capacity < 8096)
+     345             :     capacity = 8096;
+     346             :   else
+     347           0 :     capacity += Globals::kAllocOverhead;
+     348             : 
+     349             :   do {
+     350             :     size_t old = capacity;
+     351       31895 :     if (capacity < Globals::kAllocThreshold)
+     352       31895 :       capacity *= 2;
+     353             :     else
+     354           0 :       capacity += Globals::kAllocThreshold;
+     355             : 
+     356       31895 :     if (capacity < Globals::kAllocThreshold)
+     357       31895 :       capacity *= 2;
+     358             :     else
+     359           0 :       capacity += Globals::kAllocThreshold;
+     360             : 
+     361             :     // Overflow.
+     362       31895 :     if (ASMJIT_UNLIKELY(old > capacity))
+     363             :       return DebugUtils::errored(kErrorNoHeapMemory);
+     364       31895 :   } while (capacity - Globals::kAllocOverhead < required);
+     365             : 
+     366       31895 :   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       63790 : Error CodeHolder::newLabelId(uint32_t& idOut) noexcept {
+     450       63790 :   idOut = 0;
+     451             : 
+     452             :   size_t index = _labels.getLength();
+     453       63790 :   if (ASMJIT_LIKELY(index >= Operand::kPackedIdCount))
+     454             :     return DebugUtils::errored(kErrorLabelIndexOverflow);
+     455             : 
+     456       95685 :   ASMJIT_PROPAGATE(_labels.willGrow(&_baseHeap));
+     457       63790 :   LabelEntry* le = _baseHeap.allocZeroedT<LabelEntry>();
+     458             : 
+     459       63790 :   if (ASMJIT_UNLIKELY(!le))
+     460             :     return DebugUtils::errored(kErrorNoHeapMemory);;
+     461             : 
+     462       63790 :   uint32_t id = Operand::packId(static_cast<uint32_t>(index));
+     463             :   le->_setId(id);
+     464       63790 :   le->_parentId = 0;
+     465       63790 :   le->_sectionId = SectionEntry::kInvalidId;
+     466       63790 :   le->_offset = 0;
+     467             : 
+     468             :   _labels.appendUnsafe(le);
+     469       63790 :   idOut = id;
+     470       63790 :   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       31895 : size_t CodeHolder::relocate(void* _dst, uint64_t baseAddress) const noexcept {
+     588       31895 :   SectionEntry* section = _sections[0];
+     589             :   ASMJIT_ASSERT(section != nullptr);
+     590             : 
+     591             :   uint8_t* dst = static_cast<uint8_t*>(_dst);
+     592       31895 :   if (baseAddress == Globals::kNoBaseAddress)
+     593       31895 :     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       31895 :   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       31895 :   ::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       31895 :   for (size_t i = 0; i < numRelocs; i++) {
+     614           0 :     const RelocEntry* re = reArray[i];
+     615             : 
+     616             :     // Possibly deleted or optimized out relocation entry.
+     617           0 :     if (re->getType() == RelocEntry::kTypeNone)
+     618           0 :       continue;
+     619             : 
+     620             :     uint64_t ptr = re->getData();
+     621             :     size_t codeOffset = static_cast<size_t>(re->getSourceOffset());
+     622             : 
+     623             :     // Make sure that the `RelocEntry` is correct, we don't want to write
+     624             :     // out of bounds in `dst`.
+     625           0 :     if (ASMJIT_UNLIKELY(codeOffset + re->getSize() > maxCodeSize))
+     626             :       return DebugUtils::errored(kErrorInvalidRelocEntry);
+     627             : 
+     628             :     // Whether to use trampoline, can be only used if relocation type is `kRelocTrampoline`.
+     629             :     bool useTrampoline = false;
+     630             : 
+     631           0 :     switch (re->getType()) {
+     632             :       case RelocEntry::kTypeAbsToAbs: {
+     633             :         break;
+     634             :       }
+     635             : 
+     636           0 :       case RelocEntry::kTypeRelToAbs: {
+     637           0 :         ptr += baseAddress;
+     638           0 :         break;
+     639             :       }
+     640             : 
+     641             :       case RelocEntry::kTypeAbsToRel: {
+     642           0 :         ptr -= baseAddress + re->getSourceOffset() + re->getSize();
+     643           0 :         break;
+     644             :       }
+     645             : 
+     646             :       case RelocEntry::kTypeTrampoline: {
+     647           0 :         if (re->getSize() != 4)
+     648             :           return DebugUtils::errored(kErrorInvalidRelocEntry);
+     649             : 
+     650           0 :         ptr -= baseAddress + re->getSourceOffset() + re->getSize();
+     651           0 :         if (!Utils::isInt32(static_cast<int64_t>(ptr))) {
+     652           0 :           ptr = (uint64_t)trampOffset - re->getSourceOffset() - re->getSize();
+     653             :           useTrampoline = true;
+     654             :         }
+     655             :         break;
+     656             :       }
+     657             : 
+     658             :       default:
+     659             :         return DebugUtils::errored(kErrorInvalidRelocEntry);
+     660             :     }
+     661             : 
+     662           0 :     switch (re->getSize()) {
+     663           0 :       case 1:
+     664           0 :         Utils::writeU8(dst + codeOffset, static_cast<uint32_t>(ptr & 0xFFU));
+     665             :         break;
+     666             : 
+     667           0 :       case 4:
+     668           0 :         Utils::writeU32u(dst + codeOffset, static_cast<uint32_t>(ptr & 0xFFFFFFFFU));
+     669             :         break;
+     670             : 
+     671           0 :       case 8:
+     672           0 :         Utils::writeU64u(dst + codeOffset, ptr);
+     673             :         break;
+     674             : 
+     675             :       default:
+     676             :         return DebugUtils::errored(kErrorInvalidRelocEntry);
+     677             :     }
+     678             : 
+     679             :     // Handle the trampoline case.
+     680           0 :     if (useTrampoline) {
+     681             :       // Bytes that replace [REX, OPCODE] bytes.
+     682             :       uint32_t byte0 = 0xFF;
+     683           0 :       uint32_t byte1 = dst[codeOffset - 1];
+     684             : 
+     685           0 :       if (byte1 == 0xE8) {
+     686             :         // Patch CALL/MOD byte to FF/2 (-> 0x15).
+     687             :         byte1 = x86EncodeMod(0, 2, 5);
+     688             :       }
+     689           0 :       else if (byte1 == 0xE9) {
+     690             :         // Patch JMP/MOD byte to FF/4 (-> 0x25).
+     691             :         byte1 = x86EncodeMod(0, 4, 5);
+     692             :       }
+     693             :       else {
+     694             :         return DebugUtils::errored(kErrorInvalidRelocEntry);
+     695             :       }
+     696             : 
+     697             :       // Patch `jmp/call` instruction.
+     698             :       ASMJIT_ASSERT(codeOffset >= 2);
+     699           0 :       dst[codeOffset - 2] = static_cast<uint8_t>(byte0);
+     700           0 :       dst[codeOffset - 1] = static_cast<uint8_t>(byte1);
+     701             : 
+     702             :       // Store absolute address and advance the trampoline pointer.
+     703           0 :       Utils::writeU64u(dst + trampOffset, re->getData());
+     704           0 :       trampOffset += 8;
+     705             : 
+     706             : #if !defined(ASMJIT_DISABLE_LOGGING)
+     707           0 :       if (logger)
+     708           0 :         logger->logf("[reloc] dq 0x%016llX ; Trampoline\n", re->getData());
+     709             : #endif // !ASMJIT_DISABLE_LOGGING
+     710             :     }
+     711             :   }
+     712             : 
+     713             :   // If there are no trampolines this is the same as `minCodeSize`.
+     714             :   return trampOffset;
+     715             : }
+     716             : 
+     717             : } // asmjit namespace
+     718             : } // namespace PLMD
+     719             : 
+     720             : // [Api-End]
+     721             : #include "./asmjit_apiend.h"
+     722             : #pragma GCC diagnostic pop
+     723             : #endif // __PLUMED_HAS_ASMJIT
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/codeholder.h.func-sort-c.html b/coverage-libs/asmjit/codeholder.h.func-sort-c.html new file mode 100644 index 000000000000..86f2391c9889 --- /dev/null +++ b/coverage-libs/asmjit/codeholder.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/codeholder.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - codeholder.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:324178.0 %
Date:2024-04-19 12:12:36Functions:00-
+
+ +
+ + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/codeholder.h.gcov.html b/coverage-libs/asmjit/codeholder.h.gcov.html new file mode 100644 index 000000000000..393246b5c991 --- /dev/null +++ b/coverage-libs/asmjit/codeholder.h.gcov.html @@ -0,0 +1,854 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/codeholder.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - codeholder.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:324178.0 %
Date:2024-04-19 12:12:36Functions: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      127610 :     : _archInfo(),
+     137      127610 :       _stackAlignment(0),
+     138      127610 :       _cdeclCallConv(CallConv::kIdNone),
+     139      127610 :       _stdCallConv(CallConv::kIdNone),
+     140      127610 :       _fastCallConv(CallConv::kIdNone),
+     141      127610 :       _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       31895 :     return _archInfo._type != ArchInfo::kTypeNone;
+     155             :   }
+     156             : 
+     157             :   ASMJIT_INLINE void init(const CodeInfo& other) noexcept {
+     158       95685 :     _archInfo = other._archInfo;
+     159       95685 :     _packedMiscInfo = other._packedMiscInfo;
+     160       95685 :     _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       31895 :     _stackAlignment = 0;
+     172       31895 :     _cdeclCallConv = CallConv::kIdNone;
+     173       31895 :     _stdCallConv = CallConv::kIdNone;
+     174       31895 :     _fastCallConv = CallConv::kIdNone;
+     175       31895 :     _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       31895 :   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       31895 :   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       95685 :   ASMJIT_INLINE size_t getLength() const noexcept { return _length; }
+     263       31895 :   ASMJIT_INLINE size_t getCapacity() const noexcept { return _capacity; }
+     264             : 
+     265       31895 :   ASMJIT_INLINE bool isExternal() const noexcept { return _isExternal; }
+     266       31895 :   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       63790 :   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       31895 :     _nameAsU32[0] = Utils::pack32_4x8(c0, c1, c2, c3);
+     310       31895 :     _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       63790 :   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       63790 :   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       63790 :   ASMJIT_INLINE uint32_t getGlobalHints() const noexcept { return _globalHints; }
+     575             :   //! Get global options, internally propagated to all `CodeEmitter`s attached.
+     576       63790 :   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       63790 :   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       31895 :   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       63790 :     size_t index = static_cast<size_t>(Operand::unpackId(id));
+     700       63790 :     return index < _labels.getLength() ? _labels[index] : static_cast<LabelEntry*>(nullptr);
+     701             :   }
+     702             : 
+     703             :   // --------------------------------------------------------------------------
+     704             :   // [Relocations]
+     705             :   // --------------------------------------------------------------------------
+     706             : 
+     707             :   //! Create a new relocation entry of type `type` and size `size`.
+     708             :   //!
+     709             :   //! Additional fields can be set after the relocation entry was created.
+     710             :   ASMJIT_API Error newRelocEntry(RelocEntry** dst, uint32_t type, uint32_t size) noexcept;
+     711             : 
+     712             :   //! Get if the code contains relocations.
+     713             :   ASMJIT_INLINE bool hasRelocations() const noexcept { return !_relocations.isEmpty(); }
+     714             :   //! Get array of `RelocEntry*` records.
+     715             :   ASMJIT_INLINE const ZoneVector<RelocEntry*>& getRelocEntries() const noexcept { return _relocations; }
+     716             : 
+     717             :   ASMJIT_INLINE RelocEntry* getRelocEntry(uint32_t id) const noexcept { return _relocations[id]; }
+     718             : 
+     719             :   //! Relocate the code to `baseAddress` and copy it to `dst`.
+     720             :   //!
+     721             :   //! \param dst Contains the location where the relocated code should be
+     722             :   //! copied. The pointer can be address returned by virtual memory allocator
+     723             :   //! or any other address that has sufficient space.
+     724             :   //!
+     725             :   //! \param baseAddress Base address used for relocation. `JitRuntime` always
+     726             :   //! sets the `baseAddress` to be the same as `dst`.
+     727             :   //!
+     728             :   //! \return The number bytes actually used. If the code emitter reserved
+     729             :   //! space for possible trampolines, but didn't use it, the number of bytes
+     730             :   //! used can actually be less than the expected worst case. Virtual memory
+     731             :   //! allocator can shrink the memory it allocated initially.
+     732             :   //!
+     733             :   //! A given buffer will be overwritten, to get the number of bytes required,
+     734             :   //! use `getCodeSize()`.
+     735             :   ASMJIT_API size_t relocate(void* dst, uint64_t baseAddress = Globals::kNoBaseAddress) const noexcept;
+     736             : 
+     737             :   // --------------------------------------------------------------------------
+     738             :   // [Members]
+     739             :   // --------------------------------------------------------------------------
+     740             : 
+     741             :   CodeInfo _codeInfo;                    //!< Basic information about the code (architecture and other info).
+     742             : 
+     743             :   uint32_t _globalHints;                 //!< Global hints, propagated to all `CodeEmitter`s.
+     744             :   uint32_t _globalOptions;               //!< Global options, propagated to all `CodeEmitter`s.
+     745             : 
+     746             :   CodeEmitter* _emitters;                //!< Linked-list of all attached `CodeEmitter`s.
+     747             :   Assembler* _cgAsm;                     //!< Attached \ref Assembler (only one at a time).
+     748             : 
+     749             :   Logger* _logger;                       //!< Attached \ref Logger, used by all consumers.
+     750             :   ErrorHandler* _errorHandler;           //!< Attached \ref ErrorHandler.
+     751             : 
+     752             :   uint32_t _unresolvedLabelsCount;       //!< Count of label references which were not resolved.
+     753             :   uint32_t _trampolinesSize;             //!< Size of all possible trampolines.
+     754             : 
+     755             :   Zone _baseZone;                        //!< Base zone (used to allocate core structures).
+     756             :   Zone _dataZone;                        //!< Data zone (used to allocate extra data like label names).
+     757             :   ZoneHeap _baseHeap;                    //!< Zone allocator, used to manage internal containers.
+     758             : 
+     759             :   ZoneVector<SectionEntry*> _sections;   //!< Section entries.
+     760             :   ZoneVector<LabelEntry*> _labels;       //!< Label entries (each label is stored here).
+     761             :   ZoneVector<RelocEntry*> _relocations;  //!< Relocation entries.
+     762             :   ZoneHash<LabelEntry> _namedLabels;     //!< Label name -> LabelEntry (only named labels).
+     763             : };
+     764             : 
+     765             : //! \}
+     766             : 
+     767             : } // asmjit namespace
+     768             : } // namespace PLMD
+     769             : 
+     770             : // [Api-End]
+     771             : #include "./asmjit_apiend.h"
+     772             : 
+     773             : // [Guard]
+     774             : #endif // _ASMJIT_BASE_CODEHOLDER_H
+     775             : #pragma GCC diagnostic pop
+     776             : #endif // __PLUMED_HAS_ASMJIT
+     777             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/constpool.cpp.func-sort-c.html b/coverage-libs/asmjit/constpool.cpp.func-sort-c.html new file mode 100644 index 000000000000..2a50890fa7e3 --- /dev/null +++ b/coverage-libs/asmjit/constpool.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/constpool.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - constpool.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:01100.0 %
Date:2024-04-19 12:12:36Functions:080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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

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

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

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

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

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit7CpuInfo6detectEv256
_ZN4PLMD6asmjitL16x86DetectCpuInfoEPNS0_7CpuInfoE256
_ZN4PLMD6asmjit7CpuInfo7getHostEv31925
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/cpuinfo.cpp.func.html b/coverage-libs/asmjit/cpuinfo.cpp.func.html new file mode 100644 index 000000000000..4b20232bbf92 --- /dev/null +++ b/coverage-libs/asmjit/cpuinfo.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/cpuinfo.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - cpuinfo.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:13714991.9 %
Date:2024-04-19 12:12:36Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

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

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

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/cpuinfo.h.gcov.html b/coverage-libs/asmjit/cpuinfo.h.gcov.html new file mode 100644 index 000000000000..7f5c4698a204 --- /dev/null +++ b/coverage-libs/asmjit/cpuinfo.h.gcov.html @@ -0,0 +1,479 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/cpuinfo.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - cpuinfo.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:61154.5 %
Date:2024-04-19 12:12:36Functions: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         256 :   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         512 :     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         512 :     _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         256 :   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         256 :   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       12544 :   ASMJIT_INLINE CpuInfo& addFeature(uint32_t feature) noexcept { _features.add(feature); return *this; }
+     328             : 
+     329             :   //! Get CPU vendor string.
+     330             :   ASMJIT_INLINE const char* getVendorString() const noexcept { return _vendorString; }
+     331             :   //! Get CPU brand string.
+     332             :   ASMJIT_INLINE const char* getBrandString() const noexcept { return _brandString; }
+     333             : 
+     334             :   // --------------------------------------------------------------------------
+     335             :   // [Accessors - ARM]
+     336             :   // --------------------------------------------------------------------------
+     337             : 
+     338             :   // --------------------------------------------------------------------------
+     339             :   // [Accessors - X86]
+     340             :   // --------------------------------------------------------------------------
+     341             : 
+     342             :   //! Get processor type.
+     343             :   ASMJIT_INLINE uint32_t getX86ProcessorType() const noexcept {
+     344             :     return _x86Data._processorType;
+     345             :   }
+     346             : 
+     347             :   //! Get brand index.
+     348             :   ASMJIT_INLINE uint32_t getX86BrandIndex() const noexcept {
+     349             :     return _x86Data._brandIndex;
+     350             :   }
+     351             : 
+     352             :   //! Get flush cache line size.
+     353             :   ASMJIT_INLINE uint32_t getX86FlushCacheLineSize() const noexcept {
+     354             :     return _x86Data._flushCacheLineSize;
+     355             :   }
+     356             : 
+     357             :   //! Get maximum logical processors count.
+     358             :   ASMJIT_INLINE uint32_t getX86MaxLogicalProcessors() const noexcept {
+     359             :     return _x86Data._maxLogicalProcessors;
+     360             :   }
+     361             : 
+     362             :   // --------------------------------------------------------------------------
+     363             :   // [Statics]
+     364             :   // --------------------------------------------------------------------------
+     365             : 
+     366             :   //! Get the host CPU information.
+     367             :   ASMJIT_API static const CpuInfo& getHost() noexcept;
+     368             : 
+     369             :   // --------------------------------------------------------------------------
+     370             :   // [Members]
+     371             :   // --------------------------------------------------------------------------
+     372             : 
+     373             :   ArchInfo _archInfo;                    //!< CPU architecture information.
+     374             :   uint32_t _vendorId;                    //!< CPU vendor id, see \ref Vendor.
+     375             :   uint32_t _family;                      //!< CPU family ID.
+     376             :   uint32_t _model;                       //!< CPU model ID.
+     377             :   uint32_t _stepping;                    //!< CPU stepping.
+     378             :   uint32_t _hwThreadsCount;              //!< Number of hardware threads.
+     379             :   CpuFeatures _features;                 //!< CPU features.
+     380             :   char _vendorString[16];                //!< CPU vendor string.
+     381             :   char _brandString[64];                 //!< CPU brand string.
+     382             : 
+     383             :   // Architecture specific data.
+     384             :   union {
+     385             :     ArmData _armData;
+     386             :     X86Data _x86Data;
+     387             :   };
+     388             : };
+     389             : 
+     390             : //! \}
+     391             : 
+     392             : } // asmjit namespace
+     393             : } // namespace PLMD
+     394             : 
+     395             : // [Api-End]
+     396             : #include "./asmjit_apiend.h"
+     397             : 
+     398             : // [Guard]
+     399             : #endif // _ASMJIT_BASE_CPUINFO_H
+     400             : #pragma GCC diagnostic pop
+     401             : #endif // __PLUMED_HAS_ASMJIT
+     402             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/func.cpp.func-sort-c.html b/coverage-libs/asmjit/func.cpp.func-sort-c.html new file mode 100644 index 000000000000..87e63b2075de --- /dev/null +++ b/coverage-libs/asmjit/func.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/func.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - func.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:243177.4 %
Date:2024-04-19 12:12:36Functions:5771.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit9FuncUtils9allocArgsEPNS0_11CodeEmitterERKNS0_15FuncFrameLayoutERKNS0_14FuncArgsMapperE0
_ZNK4PLMD6asmjit14FuncArgsMapper15updateFrameInfoERNS0_13FuncFrameInfoE0
_ZN4PLMD6asmjit15FuncFrameLayout4initERKNS0_10FuncDetailERKNS0_13FuncFrameInfoE31895
_ZN4PLMD6asmjit9FuncUtils10emitEpilogEPNS0_11CodeEmitterERKNS0_15FuncFrameLayoutE31895
_ZN4PLMD6asmjit9FuncUtils10emitPrologEPNS0_11CodeEmitterERKNS0_15FuncFrameLayoutE31895
_ZN4PLMD6asmjit10FuncDetail4initERKNS0_13FuncSignatureE44809
_ZN4PLMD6asmjit8CallConv4initEj44809
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/func.cpp.func.html b/coverage-libs/asmjit/func.cpp.func.html new file mode 100644 index 000000000000..169f502aa22f --- /dev/null +++ b/coverage-libs/asmjit/func.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/func.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - func.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:243177.4 %
Date:2024-04-19 12:12:36Functions:5771.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit10FuncDetail4initERKNS0_13FuncSignatureE44809
_ZN4PLMD6asmjit15FuncFrameLayout4initERKNS0_10FuncDetailERKNS0_13FuncFrameInfoE31895
_ZN4PLMD6asmjit8CallConv4initEj44809
_ZN4PLMD6asmjit9FuncUtils10emitEpilogEPNS0_11CodeEmitterERKNS0_15FuncFrameLayoutE31895
_ZN4PLMD6asmjit9FuncUtils10emitPrologEPNS0_11CodeEmitterERKNS0_15FuncFrameLayoutE31895
_ZN4PLMD6asmjit9FuncUtils9allocArgsEPNS0_11CodeEmitterERKNS0_15FuncFrameLayoutERKNS0_14FuncArgsMapperE0
_ZNK4PLMD6asmjit14FuncArgsMapper15updateFrameInfoERNS0_13FuncFrameInfoE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/func.cpp.gcov.html b/coverage-libs/asmjit/func.cpp.gcov.html new file mode 100644 index 000000000000..62e3ac80c49b --- /dev/null +++ b/coverage-libs/asmjit/func.cpp.gcov.html @@ -0,0 +1,289 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/func.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - func.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:243177.4 %
Date:2024-04-19 12:12:36Functions: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       44809 : ASMJIT_FAVOR_SIZE Error CallConv::init(uint32_t ccId) noexcept {
+      57             :   reset();
+      58             : 
+      59             : #if defined(ASMJIT_BUILD_X86)
+      60       44809 :   if (CallConv::isX86Family(ccId))
+      61       44809 :     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       44809 : ASMJIT_FAVOR_SIZE Error FuncDetail::init(const FuncSignature& sign) {
+      77             :   uint32_t ccId = sign.getCallConv();
+      78       44809 :   CallConv& cc = _callConv;
+      79             : 
+      80             :   uint32_t argCount = sign.getArgCount();
+      81       44809 :   if (ASMJIT_UNLIKELY(argCount > kFuncArgCount))
+      82             :     return DebugUtils::errored(kErrorInvalidArgument);
+      83             : 
+      84       44809 :   ASMJIT_PROPAGATE(cc.init(ccId));
+      85             : 
+      86       44809 :   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       58237 :   for (uint32_t i = 0; i < argCount; i++) {
+      91             :     Value& arg = _args[i];
+      92       13428 :     arg.initTypeId(TypeId::deabstract(args[i], deabstractDelta));
+      93             :   }
+      94       44809 :   _argCount = static_cast<uint8_t>(argCount);
+      95             : 
+      96             :   uint32_t ret = sign.getRet();
+      97       44809 :   if (ret != TypeId::kVoid) {
+      98             :     _rets[0].initTypeId(TypeId::deabstract(ret, deabstractDelta));
+      99       44809 :     _retCount = 1;
+     100             :   }
+     101             : 
+     102             : #if defined(ASMJIT_BUILD_X86)
+     103       44809 :   if (CallConv::isX86Family(ccId))
+     104       44809 :     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       31895 : 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       31895 :   if (CallConv::isX86Family(ccId))
+     126       31895 :     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       31895 : ASMJIT_FAVOR_SIZE Error FuncUtils::emitProlog(CodeEmitter* emitter, const FuncFrameLayout& layout) {
+     165             : #if defined(ASMJIT_BUILD_X86)
+     166       31895 :   if (emitter->getArchInfo().isX86Family())
+     167       31895 :     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       31895 : ASMJIT_FAVOR_SIZE Error FuncUtils::emitEpilog(CodeEmitter* emitter, const FuncFrameLayout& layout) {
+     179             : #if defined(ASMJIT_BUILD_X86)
+     180       31895 :   if (emitter->getArchInfo().isX86Family())
+     181       31895 :     return X86Internal::emitEpilog(static_cast<X86Emitter*>(emitter), layout);
+     182             : #endif // ASMJIT_BUILD_X86
+     183             : 
+     184             : #if defined(ASMJIT_BUILD_ARM)
+     185             :   if (emitter->getArchInfo().isArmFamily())
+     186             :     return ArmInternal::emitEpilog(static_cast<ArmEmitter*>(emitter), layout);
+     187             : #endif // ASMJIT_BUILD_ARM
+     188             : 
+     189             :   return DebugUtils::errored(kErrorInvalidArch);
+     190             : }
+     191             : 
+     192           0 : ASMJIT_FAVOR_SIZE Error FuncUtils::allocArgs(CodeEmitter* emitter, const FuncFrameLayout& layout, const FuncArgsMapper& args) {
+     193             : #if defined(ASMJIT_BUILD_X86)
+     194           0 :   if (emitter->getArchInfo().isX86Family())
+     195           0 :     return X86Internal::allocArgs(static_cast<X86Emitter*>(emitter), layout, args);
+     196             : #endif // ASMJIT_BUILD_X86
+     197             : 
+     198             : #if defined(ASMJIT_BUILD_ARM)
+     199             :   if (emitter->getArchInfo().isArmFamily())
+     200             :     return ArmInternal::allocArgs(static_cast<ArmEmitter*>(emitter), layout, args);
+     201             : #endif // ASMJIT_BUILD_ARM
+     202             : 
+     203             :   return DebugUtils::errored(kErrorInvalidArch);
+     204             : }
+     205             : 
+     206             : } // asmjit namespace
+     207             : } // namespace PLMD
+     208             : 
+     209             : // [Api-End]
+     210             : #include "./asmjit_apiend.h"
+     211             : #pragma GCC diagnostic pop
+     212             : #endif // __PLUMED_HAS_ASMJIT
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/func.h.func-sort-c.html b/coverage-libs/asmjit/func.h.func-sort-c.html new file mode 100644 index 000000000000..b23eab9b1988 --- /dev/null +++ b/coverage-libs/asmjit/func.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/func.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - func.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:689770.1 %
Date:2024-04-19 12:12:36Functions:00-
+
+ +
+ + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/func.h.gcov.html b/coverage-libs/asmjit/func.h.gcov.html new file mode 100644 index 000000000000..67ecea274017 --- /dev/null +++ b/coverage-libs/asmjit/func.h.gcov.html @@ -0,0 +1,1404 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/func.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - func.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:689770.1 %
Date:2024-04-19 12:12:36Functions: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       44809 :   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       44809 :     ::memset(_passedOrder, 0xFF, sizeof(_passedOrder));
+     263             :   }
+     264             : 
+     265             :   // --------------------------------------------------------------------------
+     266             :   // [Accessors]
+     267             :   // --------------------------------------------------------------------------
+     268             : 
+     269             :   //! Get calling convention id, see \ref Id.
+     270       31895 :   ASMJIT_INLINE uint32_t getId() const noexcept { return _id; }
+     271             :   //! Set calling convention id, see \ref Id.
+     272       44809 :   ASMJIT_INLINE void setId(uint32_t id) noexcept { _id = static_cast<uint8_t>(id); }
+     273             : 
+     274             :   //! Get architecture type.
+     275       76704 :   ASMJIT_INLINE uint32_t getArchType() const noexcept { return _archType; }
+     276             :   //! Set architecture type.
+     277       44809 :   ASMJIT_INLINE void setArchType(uint32_t archType) noexcept { _archType = static_cast<uint8_t>(archType); }
+     278             : 
+     279             :   //! Get calling convention algorithm, see \ref Algorithm.
+     280       44809 :   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       57433 :   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       95685 :   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       44809 :     _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       31895 :   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       44809 :   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      172389 :     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       44809 :     _passedOrder[kind].packed[0] = p0;
+     334       44809 :     _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      140494 :     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       44809 :   }
+     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       44809 :     _callConv = static_cast<uint8_t>(ccId);
+     443       44809 :     _argCount = static_cast<uint8_t>(argCount);
+     444       44809 :     _vaIndex = kNoVarArgs;
+     445       44809 :     _ret = ret;
+     446       44809 :     _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       44809 :   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       57723 :   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       44809 :   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       44809 :   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       31895 :   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       12400 :   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         514 :   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       58237 :     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       12624 :       _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         804 :       _value |= (regType << kRegTypeShift) | (regId << kRegIdShift) | kIsByReg;
+     732       44809 :     }
+     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       51366 :     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       59041 :     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       70347 :     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       71151 :     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       44809 :   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       44809 :   ASMJIT_INLINE uint32_t getRetCount() const noexcept { return _retCount; }
+     795             :   //! Get the number of function arguments.
+     796      147855 :   ASMJIT_INLINE uint32_t getArgCount() const noexcept { return _argCount; }
+     797             : 
+     798             :   //! Get whether the function has a return value.
+     799       31895 :   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       57723 :     return _usedRegs[kind];
+     853             :   }
+     854             : 
+     855             :   ASMJIT_INLINE void addUsedRegs(uint32_t kind, uint32_t regs) noexcept {
+     856             :     ASMJIT_ASSERT(kind < kMaxVRegKinds);
+     857       13428 :     _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       31895 :   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       31895 :     _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       95685 :   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       27307 :   ASMJIT_INLINE bool hasCalls() const noexcept { return (_attributes & kAttrHasCalls) != 0; }
+     952             :   //! Set `kFlagHasCalls` to true.
+     953       12914 :   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       31895 :   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       31895 :   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       31895 :   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      127580 :     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       31895 :     _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       31895 :   ASMJIT_INLINE uint32_t getStackFrameAlignment() const noexcept { return _stackFrameAlignment; }
+    1015             :   //! Get minimum call-frame alignment required by the function.
+    1016       31895 :   ASMJIT_INLINE uint32_t getCallFrameAlignment() const noexcept { return _callFrameAlignment; }
+    1017             : 
+    1018       31895 :   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       31895 :     _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       12914 :   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       31895 :   ASMJIT_INLINE uint32_t getStackArgsRegId() const noexcept { return _stackArgsRegId; }
+    1048       31895 :   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      127580 :   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       95685 :   ASMJIT_INLINE bool hasDynamicAlignment() const noexcept { return static_cast<bool>(_dynamicAlignment); }
+    1096             : 
+    1097       31895 :   ASMJIT_INLINE bool hasMmxCleanup() const noexcept { return static_cast<bool>(_mmxCleanup); }
+    1098       31895 :   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      127580 :     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       31895 :   ASMJIT_INLINE uint32_t getStackArgsRegId() const noexcept { return _stackArgsRegId; }
+    1122           0 :   ASMJIT_INLINE uint32_t getStackArgsOffset() const noexcept { return _stackArgsOffset; }
+    1123             : 
+    1124       63790 :   ASMJIT_INLINE bool hasStackAdjustment() const noexcept { return _stackAdjustment != 0; }
+    1125             :   ASMJIT_INLINE uint32_t getStackAdjustment() const noexcept { return _stackAdjustment; }
+    1126             : 
+    1127       31895 :   ASMJIT_INLINE bool hasCalleeStackCleanup() const noexcept { return _calleeStackCleanup != 0; }
+    1128             :   ASMJIT_INLINE uint32_t getCalleeStackCleanup() const noexcept { return _calleeStackCleanup; }
+    1129             : 
+    1130             :   // --------------------------------------------------------------------------
+    1131             :   // [Members]
+    1132             :   // --------------------------------------------------------------------------
+    1133             : 
+    1134             :   uint8_t _stackAlignment;               //!< Final stack alignment of the functions.
+    1135             :   uint8_t _stackBaseRegId;               //!< GP register that holds address of base stack address.
+    1136             :   uint8_t _stackArgsRegId;               //!< GP register that holds address of the first argument passed by stack.
+    1137             : 
+    1138             :   uint32_t _savedRegs[kMaxVRegKinds];    //!< Registers that will be saved/restored in prolog/epilog.
+    1139             : 
+    1140             :   uint32_t _preservedFP : 1;             //!< Function preserves frame-pointer.
+    1141             :   uint32_t _dsaSlotUsed : 1;             //!< True if `_dsaSlot` contains a valid memory slot/offset.
+    1142             :   uint32_t _alignedVecSR : 1;            //!< Use instructions that perform aligned ops to save/restore XMM regs.
+    1143             :   uint32_t _dynamicAlignment : 1;        //!< Function must dynamically align the stack.
+    1144             : 
+    1145             :   uint32_t _mmxCleanup : 1;              //!< Emit 'emms' in epilog (X86).
+    1146             :   uint32_t _avxCleanup : 1;              //!< Emit 'vzeroupper' in epilog (X86).
+    1147             :   uint32_t _avxEnabled : 1;              //!< Use AVX instead of SSE for SIMD saves/restores (X86).
+    1148             : 
+    1149             :   uint32_t _stackSize;                   //!< Stack size (sum of function's stack and call stack).
+    1150             :   uint32_t _stackBaseOffset;             //!< Stack offset (non-zero if kFlagHasCalls is set).
+    1151             :   uint32_t _stackAdjustment;             //!< Stack adjustment in prolog/epilog.
+    1152             :   uint32_t _stackArgsOffset;             //!< Offset to the first argument passed by stack of _stackArgsRegId.
+    1153             : 
+    1154             :   uint32_t _dsaSlot;                     //!< Memory slot where the prolog inserter stores previous (unaligned) ESP.
+    1155             :   uint16_t _calleeStackCleanup;          //!< How many bytes the callee should add to the stack (X86 STDCALL).
+    1156             :   uint16_t _gpStackSize;                 //!< Stack size required to save GP regs.
+    1157             :   uint16_t _vecStackSize;                //!< Stack size required to save VEC regs.
+    1158             :   uint32_t _gpStackOffset;               //!< Offset where saved GP regs are stored.
+    1159             :   uint32_t _vecStackOffset;              //!< Offset where saved GP regs are stored.
+    1160             : };
+    1161             : 
+    1162             : // ============================================================================
+    1163             : // [asmjit::FuncArgsMapper]
+    1164             : // ============================================================================
+    1165             : 
+    1166             : //! Assign a physical register to each function argument.
+    1167             : //!
+    1168             : //! This is used to specify where each function argument should be shuffled
+    1169             : //! or allocated (in case it's passed by stack).
+    1170             : class FuncArgsMapper {
+    1171             : public:
+    1172             :   struct Value {
+    1173             :     // NOTE: The layout is compatible with FuncDetail::Value except stack.
+    1174             :     ASMJIT_ENUM(Parts) {
+    1175             :       kTypeIdShift      = 24,
+    1176             :       kTypeIdMask       = 0xFF000000U,
+    1177             : 
+    1178             :       kRegTypeShift     = 8,
+    1179             :       kRegTypeMask      = 0x0000FF00U,
+    1180             : 
+    1181             :       kRegIdShift       = 0,
+    1182             :       kRegIdMask        = 0x000000FFU,
+    1183             : 
+    1184             :       kIsAssigned       = 0x00010000U
+    1185             :     };
+    1186             : 
+    1187             :     //! Get if this value is initialized (i.e. contains a valid data).
+    1188           0 :     ASMJIT_INLINE bool isAssigned() const noexcept { return _value != 0; }
+    1189             :     //! Initialize this in/out by a given `typeId`, `regType`, and `regId`.
+    1190             :     ASMJIT_INLINE void assign(uint32_t typeId, uint32_t regType, uint32_t regId) noexcept {
+    1191             :       _value = (typeId << kTypeIdShift) | (regType << kRegTypeShift) | (regId << kRegIdShift) | kIsAssigned;
+    1192             :     }
+    1193             :     //! Reset the value to its unassigned state.
+    1194             :     ASMJIT_INLINE void reset() noexcept { _value = 0; }
+    1195             : 
+    1196             :     //! Get virtual type of this argument or return value.
+    1197           0 :     ASMJIT_INLINE uint32_t getTypeId() const noexcept { return _value >> kTypeIdShift; }
+    1198             :     //! Get a register type of the register used to pass the argument or return the value.
+    1199           0 :     ASMJIT_INLINE uint32_t getRegType() const noexcept { return (_value & kRegTypeMask) >> kRegTypeShift; }
+    1200             :     //! Get a physical id of the register used to pass the argument or return the value.
+    1201           0 :     ASMJIT_INLINE uint32_t getRegId() const noexcept { return (_value & kRegIdMask) >> kRegIdShift; }
+    1202             : 
+    1203             :     uint32_t _value;
+    1204             :   };
+    1205             : 
+    1206             :   // --------------------------------------------------------------------------
+    1207             :   // [Construction / Destruction]
+    1208             :   // --------------------------------------------------------------------------
+    1209             : 
+    1210             :   explicit ASMJIT_INLINE FuncArgsMapper(const FuncDetail* fd) noexcept { reset(fd); }
+    1211             :   ASMJIT_INLINE FuncArgsMapper(const FuncArgsMapper& other) noexcept {
+    1212             :     ::memcpy(this, &other, sizeof(*this));
+    1213             :   }
+    1214             : 
+    1215             :   // --------------------------------------------------------------------------
+    1216             :   // [Reset]
+    1217             :   // --------------------------------------------------------------------------
+    1218             : 
+    1219             :   ASMJIT_INLINE void reset(const FuncDetail* fd = nullptr) noexcept {
+    1220             :     _funcDetail = fd;
+    1221             :     ::memset(_args, 0, sizeof(_args));
+    1222             :   }
+    1223             : 
+    1224             :   // --------------------------------------------------------------------------
+    1225             :   // [Accessors]
+    1226             :   // --------------------------------------------------------------------------
+    1227             : 
+    1228           0 :   ASMJIT_INLINE const FuncDetail* getFuncDetail() const noexcept { return _funcDetail; }
+    1229             :   ASMJIT_INLINE void setFuncDetail(const FuncDetail* fd) noexcept { _funcDetail = fd; }
+    1230             : 
+    1231             :   ASMJIT_INLINE Value& getArg(size_t index) noexcept {
+    1232             :     ASMJIT_ASSERT(index < ASMJIT_ARRAY_SIZE(_args));
+    1233             :     return _args[index];
+    1234             :   }
+    1235             :   ASMJIT_INLINE const Value& getArg(size_t index) const noexcept {
+    1236             :     ASMJIT_ASSERT(index < ASMJIT_ARRAY_SIZE(_args));
+    1237             :     return _args[index];
+    1238             :   }
+    1239             : 
+    1240             :   ASMJIT_INLINE bool isAssigned(size_t index) const noexcept {
+    1241             :     ASMJIT_ASSERT(index < ASMJIT_ARRAY_SIZE(_args));
+    1242             :     return _args[index].isAssigned();
+    1243             :   }
+    1244             : 
+    1245             :   ASMJIT_INLINE void assign(size_t index, const Reg& reg, uint32_t typeId = TypeId::kVoid) noexcept {
+    1246             :     // Not designed for virtual registers.
+    1247             :     ASMJIT_ASSERT(index < ASMJIT_ARRAY_SIZE(_args));
+    1248             :     ASMJIT_ASSERT(reg.isPhysReg());
+    1249             : 
+    1250             :     _args[index].assign(typeId, reg.getType(), reg.getId());
+    1251             :   }
+    1252             : 
+    1253             :   // NOTE: All `assignAll()` methods are shortcuts to assign all arguments at
+    1254             :   // once, however, since registers are passed all at once these initializers
+    1255             :   // don't provide any way to pass TypeId and/or to keep any argument between
+    1256             :   // the arguments passed uninitialized.
+    1257             :   ASMJIT_INLINE void assignAll(const Reg& a0) noexcept {
+    1258             :     assign(0, a0);
+    1259             :   }
+    1260             :   ASMJIT_INLINE void assignAll(const Reg& a0, const Reg& a1) noexcept {
+    1261             :     assign(0, a0); assign(1, a1);
+    1262             :   }
+    1263             :   ASMJIT_INLINE void assignAll(const Reg& a0, const Reg& a1, const Reg& a2) noexcept {
+    1264             :     assign(0, a0); assign(1, a1); assign(2, a2);
+    1265             :   }
+    1266             :   ASMJIT_INLINE void assignAll(const Reg& a0, const Reg& a1, const Reg& a2, const Reg& a3) noexcept {
+    1267             :     assign(0, a0); assign(1, a1); assign(2, a2); assign(3, a3);
+    1268             :   }
+    1269             :   ASMJIT_INLINE void assignAll(const Reg& a0, const Reg& a1, const Reg& a2, const Reg& a3, const Reg& a4) noexcept {
+    1270             :     assign(0, a0); assign(1, a1); assign(2, a2); assign(3, a3);
+    1271             :     assign(4, a4);
+    1272             :   }
+    1273             :   ASMJIT_INLINE void assignAll(const Reg& a0, const Reg& a1, const Reg& a2, const Reg& a3, const Reg& a4, const Reg& a5) noexcept {
+    1274             :     assign(0, a0); assign(1, a1); assign(2, a2); assign(3, a3);
+    1275             :     assign(4, a4); assign(5, a5);
+    1276             :   }
+    1277             :   ASMJIT_INLINE void assignAll(const Reg& a0, const Reg& a1, const Reg& a2, const Reg& a3, const Reg& a4, const Reg& a5, const Reg& a6) noexcept {
+    1278             :     assign(0, a0); assign(1, a1); assign(2, a2); assign(3, a3);
+    1279             :     assign(4, a4); assign(5, a5); assign(6, a6);
+    1280             :   }
+    1281             :   ASMJIT_INLINE void assignAll(const Reg& a0, const Reg& a1, const Reg& a2, const Reg& a3, const Reg& a4, const Reg& a5, const Reg& a6, const Reg& a7) noexcept {
+    1282             :     assign(0, a0); assign(1, a1); assign(2, a2); assign(3, a3);
+    1283             :     assign(4, a4); assign(5, a5); assign(6, a6); assign(7, a7);
+    1284             :   }
+    1285             : 
+    1286             :   // --------------------------------------------------------------------------
+    1287             :   // [Utilities]
+    1288             :   // --------------------------------------------------------------------------
+    1289             : 
+    1290             :   //! Update `FuncFrameInfo` accordingly to FuncArgsMapper.
+    1291             :   //!
+    1292             :   //! This method must be called if you use `FuncArgsMapper` and you plan to
+    1293             :   //! use `FuncUtils::allocArgs()` to remap all arguments after the prolog is
+    1294             :   //! inserted.
+    1295             :   ASMJIT_API Error updateFrameInfo(FuncFrameInfo& ffi) const noexcept;
+    1296             : 
+    1297             :   // --------------------------------------------------------------------------
+    1298             :   // [Members]
+    1299             :   // --------------------------------------------------------------------------
+    1300             : 
+    1301             :   const FuncDetail* _funcDetail;         //!< Function detail.
+    1302             :   Value _args[kFuncArgCountLoHi];        //!< Mapping of each function argument.
+    1303             : };
+    1304             : 
+    1305             : // ============================================================================
+    1306             : // [asmjit::FuncUtils]
+    1307             : // ============================================================================
+    1308             : 
+    1309             : struct FuncUtils {
+    1310             :   ASMJIT_API static Error emitProlog(CodeEmitter* emitter, const FuncFrameLayout& layout);
+    1311             :   ASMJIT_API static Error emitEpilog(CodeEmitter* emitter, const FuncFrameLayout& layout);
+    1312             :   ASMJIT_API static Error allocArgs(CodeEmitter* emitter, const FuncFrameLayout& layout, const FuncArgsMapper& args);
+    1313             : };
+    1314             : 
+    1315             : //! \}
+    1316             : 
+    1317             : } // asmjit namespace
+    1318             : } // namespace PLMD
+    1319             : 
+    1320             : // [Api-End]
+    1321             : #include "./asmjit_apiend.h"
+    1322             : 
+    1323             : // [Guard]
+    1324             : #endif // _ASMJIT_BASE_FUNC_H
+    1325             : #pragma GCC diagnostic pop
+    1326             : #endif // __PLUMED_HAS_ASMJIT
+    1327             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/globals.cpp.func-sort-c.html b/coverage-libs/asmjit/globals.cpp.func-sort-c.html new file mode 100644 index 000000000000..7f8ecc0d16ae --- /dev/null +++ b/coverage-libs/asmjit/globals.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/globals.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - globals.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:090.0 %
Date:2024-04-19 12:12:36Functions:030.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

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

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

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

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

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/globals.h.gcov.html b/coverage-libs/asmjit/globals.h.gcov.html new file mode 100644 index 000000000000..84fc307383ab --- /dev/null +++ b/coverage-libs/asmjit/globals.h.gcov.html @@ -0,0 +1,447 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/globals.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - globals.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:2366.7 %
Date:2024-04-19 12:12:36Functions: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      194218 : 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      194050 : static ASMJIT_INLINE void releaseMemory(void* p) noexcept { ::free(p); }
+     271             : #else
+     272             : # error "[asmjit] You must provide either none or all of ASMJIT_CUSTOM_[ALLOC|REALLOC|FREE]"
+     273             : #endif
+     274             : 
+     275             : //! Cast designed to cast between function and void* pointers.
+     276             : template<typename Dst, typename Src>
+     277             : static ASMJIT_INLINE Dst ptr_cast(Src p) noexcept { return (Dst)p; }
+     278             : 
+     279             : } // Internal namespace
+     280             : 
+     281             : template<typename Func>
+     282             : static ASMJIT_INLINE Func ptr_as_func(void* func) noexcept { return Internal::ptr_cast<Func, void*>(func); }
+     283             : 
+     284             : template<typename Func>
+     285             : static ASMJIT_INLINE void* func_as_ptr(Func func) noexcept { return Internal::ptr_cast<void*, Func>(func); }
+     286             : 
+     287             : // ============================================================================
+     288             : // [asmjit::DebugUtils]
+     289             : // ============================================================================
+     290             : 
+     291             : namespace DebugUtils {
+     292             : 
+     293             : //! Returns the error `err` passed.
+     294             : //!
+     295             : //! Provided for debugging purposes. Putting a breakpoint inside `errored` can
+     296             : //! help with tracing the origin of any error reported / returned by AsmJit.
+     297             : static ASMJIT_INLINE Error errored(Error err) noexcept { return err; }
+     298             : 
+     299             : //! Get a printable version of `asmjit::Error` code.
+     300             : ASMJIT_API const char* errorAsString(Error err) noexcept;
+     301             : 
+     302             : //! Called to output debugging message(s).
+     303             : ASMJIT_API void debugOutput(const char* str) noexcept;
+     304             : 
+     305             : //! Called on assertion failure.
+     306             : //!
+     307             : //! \param file Source file name where it happened.
+     308             : //! \param line Line in the source file.
+     309             : //! \param msg Message to display.
+     310             : //!
+     311             : //! If you have problems with assertions put a breakpoint at assertionFailed()
+     312             : //! function (asmjit/base/globals.cpp) and check the call stack to locate the
+     313             : //! failing code.
+     314             : ASMJIT_API void ASMJIT_NORETURN assertionFailed(const char* file, int line, const char* msg) noexcept;
+     315             : 
+     316             : #if defined(ASMJIT_DEBUG)
+     317             : # define ASMJIT_ASSERT(exp)                                          \
+     318             :   do {                                                               \
+     319             :     if (ASMJIT_LIKELY(exp))                                          \
+     320             :       break;                                                         \
+     321             :     ::PLMD::asmjit::DebugUtils::assertionFailed(__FILE__, __LINE__, #exp); \
+     322             :   } while (0)
+     323             : # define ASMJIT_NOT_REACHED()                                        \
+     324             :   do {                                                               \
+     325             :     ::PLMD::asmjit::DebugUtils::assertionFailed(__FILE__, __LINE__,        \
+     326             :       "ASMJIT_NOT_REACHED has been reached");                        \
+     327             :     ASMJIT_ASSUME(0);                                                \
+     328             :   } while (0)
+     329             : #else
+     330             : # define ASMJIT_ASSERT(exp) ASMJIT_NOP
+     331             : # define ASMJIT_NOT_REACHED() ASMJIT_ASSUME(0)
+     332             : #endif // DEBUG
+     333             : 
+     334             : //! \internal
+     335             : //!
+     336             : //! Used by AsmJit to propagate a possible `Error` produced by `...` to the caller.
+     337             : #define ASMJIT_PROPAGATE(...)               \
+     338             :   do {                                      \
+     339             :     ::PLMD::asmjit::Error _err = __VA_ARGS__;     \
+     340             :     if (ASMJIT_UNLIKELY(_err))              \
+     341             :       return _err;                          \
+     342             :   } while (0)
+     343             : 
+     344             : } // DebugUtils namespace
+     345             : 
+     346             : // ============================================================================
+     347             : // [asmjit::Init / NoInit]
+     348             : // ============================================================================
+     349             : 
+     350             : #if !defined(ASMJIT_DOCGEN)
+     351             : struct _Init {};
+     352             : static const _Init Init = {};
+     353             : 
+     354             : struct _NoInit {};
+     355             : static const _NoInit NoInit = {};
+     356             : #endif // !ASMJIT_DOCGEN
+     357             : 
+     358             : //! \}
+     359             : 
+     360             : } // asmjit namespace
+     361             : } // namespace PLMD
+     362             : 
+     363             : // [Api-End]
+     364             : #include "./asmjit_apiend.h"
+     365             : 
+     366             : // [Guard]
+     367             : #endif // _ASMJIT_BASE_GLOBALS_H
+     368             : #pragma GCC diagnostic pop
+     369             : #endif // __PLUMED_HAS_ASMJIT
+     370             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/index-sort-f.html b/coverage-libs/asmjit/index-sort-f.html new file mode 100644 index 000000000000..bb8064455b1f --- /dev/null +++ b/coverage-libs/asmjit/index-sort-f.html @@ -0,0 +1,604 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjitHitTotalCoverage
Test:plumed test coverage (other modules)Lines:2260712431.7 %
Date:2024-04-19 12:12:36Functions:14035239.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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
globals.cpp +
0.0%
+
0.0 %0 / 90.0 %0 / 3
x86instimpl.cpp +
0.0%
+
0.0 %0 / 1700.0 %0 / 3
x86builder.cpp +
0.0%
+
0.0 %0 / 150.0 %0 / 5
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.9%10.9%
+
10.9 %186 / 170557.1 %4 / 7
vmem.cpp +
30.5%30.5%
+
30.5 %97 / 31857.1 %8 / 14
x86regalloc.cpp +
44.2%44.2%
+
44.2 %466 / 105558.6 %17 / 29
zone.cpp +
52.0%52.0%
+
52.0 %155 / 29863.6 %14 / 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
inst.h +
40.0%40.0%
+
40.0 %2 / 5-0 / 0
x86misc.h +
59.5%59.5%
+
59.5 %22 / 37-0 / 0
codeemitter.h +
81.8%81.8%
+
81.8 %9 / 11-0 / 0
func.h +
70.1%70.1%
+
70.1 %68 / 97-0 / 0
x86assembler.h +
100.0%
+
100.0 %2 / 2-0 / 0
moved_string.h +
22.2%22.2%
+
22.2 %6 / 27-0 / 0
x86emitter.h +
63.0%63.0%
+
63.0 %17 / 27-0 / 0
regalloc_p.h +
66.7%66.7%
+
66.7 %36 / 54-0 / 0
globals.h +
66.7%66.7%
+
66.7 %2 / 3-0 / 0
x86operand.h +
54.5%54.5%
+
54.5 %6 / 11-0 / 0
codecompiler.h +
64.1%64.1%
+
64.1 %41 / 64-0 / 0
logging.h +
0.0%
+
0.0 %0 / 5-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
cpuinfo.h +
54.5%54.5%
+
54.5 %6 / 11-0 / 0
codeholder.h +
78.0%78.0%
+
78.0 %32 / 41-0 / 0
runtime.h +
100.0%
+
100.0 %3 / 3-0 / 0
utils.h +
48.9%48.9%
+
48.9 %22 / 45-0 / 0
constpool.h +
0.0%
+
0.0 %0 / 31-0 / 0
x86regalloc_p.h +
69.4%69.4%
+
69.4 %34 / 49-0 / 0
codebuilder.h +
53.2%53.2%
+
53.2 %50 / 94-0 / 0
x86inst.h +
66.7%66.7%
+
66.7 %10 / 15-0 / 0
osutils.h +
100.0%
+
100.0 %5 / 5-0 / 0
operand.h +
54.4%54.4%
+
54.4 %49 / 90-0 / 0
arch.cpp +
62.5%62.5%
+
62.5 %25 / 40100.0 %2 / 2
zone.h +
80.6%80.6%
+
80.6 %75 / 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 000000000000..c3d4b49cf70f --- /dev/null +++ b/coverage-libs/asmjit/index-sort-l.html @@ -0,0 +1,604 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjitHitTotalCoverage
Test:plumed test coverage (other modules)Lines:2260712431.7 %
Date:2024-04-19 12:12:36Functions:14035239.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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.9%10.9%
+
10.9 %186 / 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.5%30.5%
+
30.5 %97 / 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
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
zone.cpp +
52.0%52.0%
+
52.0 %155 / 29863.6 %14 / 22
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 +
80.6%80.6%
+
80.6 %75 / 93100.0 %2 / 2
codeemitter.h +
81.8%81.8%
+
81.8 %9 / 11-0 / 0
osutils.cpp +
81.8%81.8%
+
81.8 %18 / 2280.0 %4 / 5
cpuinfo.cpp +
91.9%91.9%
+
91.9 %137 / 149100.0 %3 / 3
x86assembler.h +
100.0%
+
100.0 %2 / 2-0 / 0
runtime.h +
100.0%
+
100.0 %3 / 3-0 / 0
osutils.h +
100.0%
+
100.0 %5 / 5-0 / 0
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/index.html b/coverage-libs/asmjit/index.html new file mode 100644 index 000000000000..d4de4da051ec --- /dev/null +++ b/coverage-libs/asmjit/index.html @@ -0,0 +1,604 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjitHitTotalCoverage
Test:plumed test coverage (other modules)Lines:2260712431.7 %
Date:2024-04-19 12:12:36Functions:14035239.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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.5%30.5%
+
30.5 %97 / 31857.1 %8 / 14
x86assembler.cpp +
10.9%10.9%
+
10.9 %186 / 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 +
52.0%52.0%
+
52.0 %155 / 29863.6 %14 / 22
zone.h +
80.6%80.6%
+
80.6 %75 / 93100.0 %2 / 2
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/inst.cpp.func-sort-c.html b/coverage-libs/asmjit/inst.cpp.func-sort-c.html new file mode 100644 index 000000000000..c1a7bada0e52 --- /dev/null +++ b/coverage-libs/asmjit/inst.cpp.func-sort-c.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/inst.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - inst.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:060.0 %
Date:2024-04-19 12:12:36Functions:020.0 %
+
+ +
+ + + + + + + + + + + + + + +

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

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

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

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

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/inst.h.gcov.html b/coverage-libs/asmjit/inst.h.gcov.html new file mode 100644 index 000000000000..4047f1979108 --- /dev/null +++ b/coverage-libs/asmjit/inst.h.gcov.html @@ -0,0 +1,214 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/inst.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - inst.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:2540.0 %
Date:2024-04-19 12:12:36Functions: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      587564 :       : instId(0),
+      78             :         options(0),
+      79      587564 :         extraReg() {}
+      80             : 
+      81             :     explicit ASMJIT_INLINE Detail(uint32_t instId, uint32_t options = 0) noexcept
+      82             :       : instId(instId),
+      83             :         options(options),
+      84             :         extraReg() {}
+      85             : 
+      86             :     ASMJIT_INLINE Detail(uint32_t instId, uint32_t options, const RegOnly& reg) noexcept
+      87           0 :       : instId(instId),
+      88           0 :         options(options),
+      89           0 :         extraReg(reg) {}
+      90             : 
+      91             :     ASMJIT_INLINE Detail(uint32_t instId, uint32_t options, const Reg& reg) noexcept
+      92             :       : instId(instId),
+      93             :         options(options) { extraReg.init(reg); }
+      94             : 
+      95             :     // ------------------------------------------------------------------------
+      96             :     // [Accessors]
+      97             :     // ------------------------------------------------------------------------
+      98             : 
+      99             :     ASMJIT_INLINE bool hasExtraReg() const noexcept { return extraReg.isValid(); }
+     100             : 
+     101             :     // ------------------------------------------------------------------------
+     102             :     // [Members]
+     103             :     // ------------------------------------------------------------------------
+     104             : 
+     105             :     uint32_t instId;
+     106             :     uint32_t options;
+     107             :     RegOnly extraReg;
+     108             :   };
+     109             : 
+     110             :   // --------------------------------------------------------------------------
+     111             :   // [API]
+     112             :   // --------------------------------------------------------------------------
+     113             : 
+     114             : #if !defined(ASMJIT_DISABLE_VALIDATION)
+     115             :   //! Validate the given instruction.
+     116             :   ASMJIT_API static Error validate(uint32_t archType, const Detail& detail, const Operand_* operands, uint32_t count) noexcept;
+     117             : #endif // !ASMJIT_DISABLE_VALIDATION
+     118             : 
+     119             : #if !defined(ASMJIT_DISABLE_EXTENSIONS)
+     120             :   //! Check CPU features required to execute the given instruction.
+     121             :   ASMJIT_API static Error checkFeatures(uint32_t archType, const Detail& detail, const Operand_* operands, uint32_t count, CpuFeatures& out) noexcept;
+     122             : #endif // !defined(ASMJIT_DISABLE_EXTENSIONS)
+     123             : };
+     124             : 
+     125             : //! \}
+     126             : 
+     127             : } // asmjit namespace
+     128             : } // namespace PLMD
+     129             : 
+     130             : // [Api-End]
+     131             : #include "./asmjit_apiend.h"
+     132             : 
+     133             : // [Guard]
+     134             : #endif // _ASMJIT_BASE_INST_H
+     135             : #pragma GCC diagnostic pop
+     136             : #endif // __PLUMED_HAS_ASMJIT
+     137             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/logging.cpp.func-sort-c.html b/coverage-libs/asmjit/logging.cpp.func-sort-c.html new file mode 100644 index 000000000000..3adc5ef24111 --- /dev/null +++ b/coverage-libs/asmjit/logging.cpp.func-sort-c.html @@ -0,0 +1,173 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/logging.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - logging.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:01470.0 %
Date:2024-04-19 12:12:36Functions:0250.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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

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

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

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

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

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

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

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/moved_string.h.gcov.html b/coverage-libs/asmjit/moved_string.h.gcov.html new file mode 100644 index 000000000000..2026f266f358 --- /dev/null +++ b/coverage-libs/asmjit/moved_string.h.gcov.html @@ -0,0 +1,395 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/moved_string.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - moved_string.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:62722.2 %
Date:2024-04-19 12:12:36Functions: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       31895 :   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       31895 :   ASMJIT_INLINE StringBuilderTmp() noexcept : StringBuilder(NoInit) {
+     289       31895 :     _data = _embeddedData;
+     290       31895 :     _data[0] = 0;
+     291             : 
+     292       31895 :     _length = 0;
+     293       31895 :     _capacity = N;
+     294           0 :     _canFree = false;
+     295             :   }
+     296             : 
+     297             :   // --------------------------------------------------------------------------
+     298             :   // [Members]
+     299             :   // --------------------------------------------------------------------------
+     300             : 
+     301             :   //! Embedded data.
+     302             :   char _embeddedData[static_cast<size_t>(
+     303             :     N + 1 + sizeof(intptr_t)) & ~static_cast<size_t>(sizeof(intptr_t) - 1)];
+     304             : };
+     305             : 
+     306             : //! \}
+     307             : 
+     308             : } // asmjit namespace
+     309             : } // namespace PLMD
+     310             : 
+     311             : // [Api-End]
+     312             : #include "./asmjit_apiend.h"
+     313             : 
+     314             : // [Guard]
+     315             : #endif // _ASMJIT_BASE_STRING_H
+     316             : #pragma GCC diagnostic pop
+     317             : #endif // __PLUMED_HAS_ASMJIT
+     318             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/operand.h.func-sort-c.html b/coverage-libs/asmjit/operand.h.func-sort-c.html new file mode 100644 index 000000000000..0966642adfa4 --- /dev/null +++ b/coverage-libs/asmjit/operand.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/operand.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - operand.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:499054.4 %
Date:2024-04-19 12:12:36Functions:00-
+
+ +
+ + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/operand.h.gcov.html b/coverage-libs/asmjit/operand.h.gcov.html new file mode 100644 index 000000000000..decb4d09c434 --- /dev/null +++ b/coverage-libs/asmjit/operand.h.gcov.html @@ -0,0 +1,1676 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/operand.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - operand.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:499054.4 %
Date:2024-04-19 12:12:36Functions: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     1579131 :   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      378902 :   static ASMJIT_INLINE uint32_t packId(uint32_t id) noexcept { return id + kPackedIdMin; }
+     164             :   //! Convert a packed-id back to real-id.
+     165      210745 :   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     1073732 :   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         804 :   ASMJIT_INLINE void setSignature(uint32_t signature) noexcept { _signature = signature; }
+     270             : 
+     271      514876 :   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     3687997 :   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       91108 :     _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     1908572 :   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      693448 :   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      338826 :   ASMJIT_INLINE Operand() noexcept { reset(); }
+     445             :   //! Create a reference to `other` operand.
+     446       64594 :   ASMJIT_INLINE Operand(const Operand& other) noexcept { _init(other); }
+     447             :   //! Create a reference to `other` operand.
+     448      105652 :   explicit ASMJIT_INLINE Operand(const Operand_& other) noexcept { _init(other); }
+     449             :   //! Create a completely uninitialized operand (dangerous).
+     450       11446 :   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     1025624 :     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     2347035 :     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       31895 :   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      296924 :   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       14852 :   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     1749778 :     _signature = signature;
+     827     1749778 :     _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      826150 :   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      587564 :   ASMJIT_INLINE uint32_t getSignature() const noexcept { return _signature; }
+     852             :   //! Get register id or 0.
+     853      587564 :   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       91108 :     uint32_t signature = (baseType  << kSignatureMemBaseTypeShift ) |
+     943             :                          (indexType << kSignatureMemIndexTypeShift) |
+     944           0 :                          (size      << kSignatureSizeShift        ) ;
+     945             : 
+     946       91108 :     _init_packed_d0_d1(kOpMem | signature | flags, indexId);
+     947       91108 :     _mem.base = baseId;
+     948       91108 :     _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       91108 :   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      166330 :   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      166330 :   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      257438 :   ASMJIT_INLINE uint32_t getBaseId() const noexcept { return _mem.base; }
+    1019             :   //! Get id of the INDEX register.
+    1020      174273 :   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       91108 :     _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       91108 :   }
+    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      174273 :   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       91108 :     _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      116518 :     _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      116920 :   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      105072 : 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      315112 :   static ASMJIT_INLINE bool isValid(uint32_t typeId) noexcept { return typeId >= _kIntStart && typeId <= _kVec512End; }
+    1461       58237 :   static ASMJIT_INLINE bool isAbstract(uint32_t typeId) noexcept { return typeId >= kIntPtr && typeId <= kUIntPtr; }
+    1462       13428 :   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       12624 :   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      105652 :   static ASMJIT_INLINE bool isVec32(uint32_t typeId) noexcept { return typeId >= _kVec32Start && typeId <= _kVec32End; }
+    1473      105652 :   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      630224 :     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      105652 :     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       58237 :     return TypeId::isAbstract(typeId) ? typeId += deabstractDelta : typeId;
+    1511             :   }
+    1512             : };
+    1513             : 
+    1514             : //! TypeIdOf<> template allows to get a TypeId of a C++ type.
+    1515             : template<typename T> struct TypeIdOf {
+    1516             :   // Don't provide anything if not specialized.
+    1517             : };
+    1518             : template<typename T> struct TypeIdOf<T*> {
+    1519             :   enum { kTypeId = TypeId::kUIntPtr };
+    1520             : };
+    1521             : 
+    1522             : template<typename T>
+    1523             : struct TypeIdOfInt {
+    1524             :   enum {
+    1525             :     kSigned = int(~T(0) < T(0)),
+    1526             :     kTypeId = (sizeof(T) == 1) ? (int)(kSigned ? TypeId::kI8  : TypeId::kU8 ) :
+    1527             :               (sizeof(T) == 2) ? (int)(kSigned ? TypeId::kI16 : TypeId::kU16) :
+    1528             :               (sizeof(T) == 4) ? (int)(kSigned ? TypeId::kI32 : TypeId::kU32) :
+    1529             :               (sizeof(T) == 8) ? (int)(kSigned ? TypeId::kI64 : TypeId::kU64) : (int)TypeId::kVoid
+    1530             :   };
+    1531             : };
+    1532             : 
+    1533             : #define ASMJIT_DEFINE_TYPE_ID(T, TYPE_ID) \
+    1534             :   template<> \
+    1535             :   struct TypeIdOf<T> { enum { kTypeId = TYPE_ID}; }
+    1536             : 
+    1537             : ASMJIT_DEFINE_TYPE_ID(signed char       , TypeIdOfInt< signed char        >::kTypeId);
+    1538             : ASMJIT_DEFINE_TYPE_ID(unsigned char     , TypeIdOfInt< unsigned char      >::kTypeId);
+    1539             : ASMJIT_DEFINE_TYPE_ID(short             , TypeIdOfInt< short              >::kTypeId);
+    1540             : ASMJIT_DEFINE_TYPE_ID(unsigned short    , TypeIdOfInt< unsigned short     >::kTypeId);
+    1541             : ASMJIT_DEFINE_TYPE_ID(int               , TypeIdOfInt< int                >::kTypeId);
+    1542             : ASMJIT_DEFINE_TYPE_ID(unsigned int      , TypeIdOfInt< unsigned int       >::kTypeId);
+    1543             : ASMJIT_DEFINE_TYPE_ID(long              , TypeIdOfInt< long               >::kTypeId);
+    1544             : ASMJIT_DEFINE_TYPE_ID(unsigned long     , TypeIdOfInt< unsigned long      >::kTypeId);
+    1545             : #if ASMJIT_CC_MSC && !ASMJIT_CC_MSC_GE(16, 0, 0)
+    1546             : ASMJIT_DEFINE_TYPE_ID(__int64           , TypeIdOfInt< __int64            >::kTypeId);
+    1547             : ASMJIT_DEFINE_TYPE_ID(unsigned __int64  , TypeIdOfInt< unsigned __int64   >::kTypeId);
+    1548             : #else
+    1549             : ASMJIT_DEFINE_TYPE_ID(long long         , TypeIdOfInt< long long          >::kTypeId);
+    1550             : ASMJIT_DEFINE_TYPE_ID(unsigned long long, TypeIdOfInt< unsigned long long >::kTypeId);
+    1551             : #endif
+    1552             : #if ASMJIT_CC_HAS_NATIVE_CHAR
+    1553             : ASMJIT_DEFINE_TYPE_ID(char              , TypeIdOfInt< char               >::kTypeId);
+    1554             : #endif
+    1555             : #if ASMJIT_CC_HAS_NATIVE_CHAR16_T
+    1556             : ASMJIT_DEFINE_TYPE_ID(char16_t          , TypeIdOfInt< char16_t           >::kTypeId);
+    1557             : #endif
+    1558             : #if ASMJIT_CC_HAS_NATIVE_CHAR32_T
+    1559             : ASMJIT_DEFINE_TYPE_ID(char32_t          , TypeIdOfInt< char32_t           >::kTypeId);
+    1560             : #endif
+    1561             : #if ASMJIT_CC_HAS_NATIVE_WCHAR_T
+    1562             : ASMJIT_DEFINE_TYPE_ID(wchar_t           , TypeIdOfInt< wchar_t            >::kTypeId);
+    1563             : #endif
+    1564             : 
+    1565             : ASMJIT_DEFINE_TYPE_ID(void              , TypeId::kVoid);
+    1566             : ASMJIT_DEFINE_TYPE_ID(bool              , TypeId::kI8);
+    1567             : ASMJIT_DEFINE_TYPE_ID(float             , TypeId::kF32);
+    1568             : ASMJIT_DEFINE_TYPE_ID(double            , TypeId::kF64);
+    1569             : 
+    1570             : ASMJIT_DEFINE_TYPE_ID(TypeId::Int8      , TypeId::kI8);
+    1571             : ASMJIT_DEFINE_TYPE_ID(TypeId::UInt8     , TypeId::kU8);
+    1572             : ASMJIT_DEFINE_TYPE_ID(TypeId::Int16     , TypeId::kI16);
+    1573             : ASMJIT_DEFINE_TYPE_ID(TypeId::UInt16    , TypeId::kU16);
+    1574             : ASMJIT_DEFINE_TYPE_ID(TypeId::Int32     , TypeId::kI32);
+    1575             : ASMJIT_DEFINE_TYPE_ID(TypeId::UInt32    , TypeId::kU32);
+    1576             : ASMJIT_DEFINE_TYPE_ID(TypeId::Int64     , TypeId::kI64);
+    1577             : ASMJIT_DEFINE_TYPE_ID(TypeId::UInt64    , TypeId::kU64);
+    1578             : ASMJIT_DEFINE_TYPE_ID(TypeId::IntPtr    , TypeId::kIntPtr);
+    1579             : ASMJIT_DEFINE_TYPE_ID(TypeId::UIntPtr   , TypeId::kUIntPtr);
+    1580             : ASMJIT_DEFINE_TYPE_ID(TypeId::Float     , TypeId::kF32);
+    1581             : ASMJIT_DEFINE_TYPE_ID(TypeId::Double    , TypeId::kF64);
+    1582             : ASMJIT_DEFINE_TYPE_ID(TypeId::MmxReg    , TypeId::kMmx64);
+    1583             : ASMJIT_DEFINE_TYPE_ID(TypeId::Vec128    , TypeId::kI32x4);
+    1584             : ASMJIT_DEFINE_TYPE_ID(TypeId::Vec256    , TypeId::kI32x8);
+    1585             : ASMJIT_DEFINE_TYPE_ID(TypeId::Vec512    , TypeId::kI32x16);
+    1586             : 
+    1587             : //! \}
+    1588             : 
+    1589             : } // asmjit namespace
+    1590             : } // namespace PLMD
+    1591             : 
+    1592             : // [Api-End]
+    1593             : #include "./asmjit_apiend.h"
+    1594             : 
+    1595             : // [Guard]
+    1596             : #endif // _ASMJIT_BASE_OPERAND_H
+    1597             : #pragma GCC diagnostic pop
+    1598             : #endif // __PLUMED_HAS_ASMJIT
+    1599             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/osutils.cpp.func-sort-c.html b/coverage-libs/asmjit/osutils.cpp.func-sort-c.html new file mode 100644 index 000000000000..b36bac0bba53 --- /dev/null +++ b/coverage-libs/asmjit/osutils.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/osutils.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - osutils.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:182281.8 %
Date:2024-04-19 12:12:36Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit7OSUtils12getTickCountEv0
_ZN4PLMD6asmjit7OSUtils18allocVirtualMemoryEmPmj31895
_ZN4PLMD6asmjit7OSUtils20releaseVirtualMemoryEPvm31895
_ZN4PLMD6asmjit7OSUtils20getVirtualMemoryInfoEv31925
_ZN4PLMD6asmjitL19OSUtils_GetVMemInfoEv63820
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/osutils.cpp.func.html b/coverage-libs/asmjit/osutils.cpp.func.html new file mode 100644 index 000000000000..d00c71f0fc44 --- /dev/null +++ b/coverage-libs/asmjit/osutils.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/osutils.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - osutils.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:182281.8 %
Date:2024-04-19 12:12:36Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit7OSUtils12getTickCountEv0
_ZN4PLMD6asmjit7OSUtils18allocVirtualMemoryEmPmj31895
_ZN4PLMD6asmjit7OSUtils20getVirtualMemoryInfoEv31925
_ZN4PLMD6asmjit7OSUtils20releaseVirtualMemoryEPvm31895
_ZN4PLMD6asmjitL19OSUtils_GetVMemInfoEv63820
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/osutils.cpp.gcov.html b/coverage-libs/asmjit/osutils.cpp.gcov.html new file mode 100644 index 000000000000..a01444f8f873 --- /dev/null +++ b/coverage-libs/asmjit/osutils.cpp.gcov.html @@ -0,0 +1,331 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/osutils.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - osutils.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:182281.8 %
Date:2024-04-19 12:12:36Functions: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       63820 : static const VMemInfo& OSUtils_GetVMemInfo() noexcept {
+     140             :   static VMemInfo vmi;
+     141       63820 :   if (ASMJIT_UNLIKELY(!vmi.pageSize)) {
+     142         256 :     size_t pageSize = ::getpagesize();
+     143         256 :     vmi.pageSize = pageSize;
+     144         512 :     vmi.pageGranularity = std::max<size_t>(pageSize, 65536);
+     145             :   }
+     146       63820 :   return vmi;
+     147             : };
+     148             : 
+     149       31925 : VMemInfo OSUtils::getVirtualMemoryInfo() noexcept { return OSUtils_GetVMemInfo(); }
+     150             : 
+     151       31895 : void* OSUtils::allocVirtualMemory(size_t size, size_t* allocated, uint32_t flags) noexcept {
+     152       31895 :   const VMemInfo& vmi = OSUtils_GetVMemInfo();
+     153             : 
+     154       31895 :   size_t alignedSize = Utils::alignTo<size_t>(size, vmi.pageSize);
+     155             :   int protection = PROT_READ;
+     156             : 
+     157       31895 :   if (flags & kVMWritable  ) protection |= PROT_WRITE;
+     158       31895 :   if (flags & kVMExecutable) protection |= PROT_EXEC;
+     159             : 
+     160       31895 :   void* mbase = ::mmap(nullptr, alignedSize, protection, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+     161       31895 :   if (ASMJIT_UNLIKELY(mbase == MAP_FAILED)) return nullptr;
+     162             : 
+     163       31895 :   if (allocated) *allocated = alignedSize;
+     164             :   return mbase;
+     165             : }
+     166             : 
+     167       31895 : Error OSUtils::releaseVirtualMemory(void* p, size_t size) noexcept {
+     168       31895 :   if (ASMJIT_UNLIKELY(::munmap(p, size) != 0))
+     169             :     return DebugUtils::errored(kErrorInvalidState);
+     170             : 
+     171       31895 :   return kErrorOk;
+     172             : }
+     173             : #endif // ASMJIT_OS_POSIX
+     174             : 
+     175             : // ============================================================================
+     176             : // [asmjit::OSUtils - GetTickCount]
+     177             : // ============================================================================
+     178             : 
+     179             : #if ASMJIT_OS_WINDOWS
+     180             : static ASMJIT_INLINE uint32_t OSUtils_calcHiRes(const LARGE_INTEGER& now, double freq) noexcept {
+     181             :   return static_cast<uint32_t>(
+     182             :     (int64_t)(double(now.QuadPart) / freq) & 0xFFFFFFFF);
+     183             : }
+     184             : 
+     185             : uint32_t OSUtils::getTickCount() noexcept {
+     186             :   static volatile uint32_t _hiResTicks;
+     187             :   static volatile double _hiResFreq;
+     188             : 
+     189             :   do {
+     190             :     uint32_t hiResOk = _hiResTicks;
+     191             :     LARGE_INTEGER qpf, now;
+     192             : 
+     193             :     // If for whatever reason this fails, bail to `GetTickCount()`.
+     194             :     if (!::QueryPerformanceCounter(&now)) break;
+     195             : 
+     196             :     // Expected - if we ran through this at least once `hiResTicks` will be
+     197             :     // either 1 or 0xFFFFFFFF. If it's '1' then the Hi-Res counter is available
+     198             :     // and `QueryPerformanceCounter()` can be used.
+     199             :     if (hiResOk == 1) return OSUtils_calcHiRes(now, _hiResFreq);
+     200             : 
+     201             :     // Hi-Res counter is not available, bail to `GetTickCount()`.
+     202             :     if (hiResOk != 0) break;
+     203             : 
+     204             :     // Detect availability of Hi-Res counter, if not available, bail to `GetTickCount()`.
+     205             :     if (!::QueryPerformanceFrequency(&qpf)) {
+     206             :       _InterlockedCompareExchange((LONG*)&_hiResTicks, 0xFFFFFFFF, 0);
+     207             :       break;
+     208             :     }
+     209             : 
+     210             :     double freq = double(qpf.QuadPart) / 1000.0;
+     211             :     _hiResFreq = freq;
+     212             : 
+     213             :     _InterlockedCompareExchange((LONG*)&_hiResTicks, 1, 0);
+     214             :     return OSUtils_calcHiRes(now, freq);
+     215             :   } while (0);
+     216             : 
+     217             :   return ::GetTickCount();
+     218             : }
+     219             : #elif ASMJIT_OS_MAC
+     220             : uint32_t OSUtils::getTickCount() noexcept {
+     221             :   static mach_timebase_info_data_t _machTime;
+     222             : 
+     223             :   // See Apple's QA1398.
+     224             :   if (ASMJIT_UNLIKELY(_machTime.denom == 0) || mach_timebase_info(&_machTime) != KERN_SUCCESS)
+     225             :     return 0;
+     226             : 
+     227             :   // `mach_absolute_time()` returns nanoseconds, we want milliseconds.
+     228             :   uint64_t t = mach_absolute_time() / 1000000;
+     229             : 
+     230             :   t = t * _machTime.numer / _machTime.denom;
+     231             :   return static_cast<uint32_t>(t & 0xFFFFFFFFU);
+     232             : }
+     233             : #elif defined(_POSIX_MONOTONIC_CLOCK) && _POSIX_MONOTONIC_CLOCK >= 0
+     234           0 : uint32_t OSUtils::getTickCount() noexcept {
+     235             :   struct timespec ts;
+     236             : 
+     237           0 :   if (ASMJIT_UNLIKELY(clock_gettime(CLOCK_MONOTONIC, &ts) != 0))
+     238             :     return 0;
+     239             : 
+     240           0 :   uint64_t t = (uint64_t(ts.tv_sec ) * 1000) + (uint64_t(ts.tv_nsec) / 1000000);
+     241           0 :   return static_cast<uint32_t>(t & 0xFFFFFFFFU);
+     242             : }
+     243             : #else
+     244             : #error "[asmjit] OSUtils::getTickCount() is not implemented for your target OS."
+     245             : uint32_t OSUtils::getTickCount() noexcept { return 0; }
+     246             : #endif
+     247             : 
+     248             : } // asmjit namespace
+     249             : } // namespace PLMD
+     250             : 
+     251             : // [Api-End]
+     252             : #include "./asmjit_apiend.h"
+     253             : #pragma GCC diagnostic pop
+     254             : #endif // __PLUMED_HAS_ASMJIT
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/osutils.h.func-sort-c.html b/coverage-libs/asmjit/osutils.h.func-sort-c.html new file mode 100644 index 000000000000..716a1fe16b18 --- /dev/null +++ b/coverage-libs/asmjit/osutils.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/osutils.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - osutils.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:55100.0 %
Date:2024-04-19 12:12:36Functions:00-
+
+ +
+ + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/osutils.h.gcov.html b/coverage-libs/asmjit/osutils.h.gcov.html new file mode 100644 index 000000000000..04aa96fb0fb8 --- /dev/null +++ b/coverage-libs/asmjit/osutils.h.gcov.html @@ -0,0 +1,284 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/osutils.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - osutils.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:55100.0 %
Date:2024-04-19 12:12:36Functions: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       31925 :   ASMJIT_INLINE Lock() noexcept { pthread_mutex_init(&_handle, nullptr); }
+     153             :   //! Destroy the `Lock` instance.
+     154       31925 :   ASMJIT_INLINE ~Lock() noexcept { pthread_mutex_destroy(&_handle); }
+     155             : 
+     156             :   //! Lock.
+     157       31895 :   ASMJIT_INLINE void lock() noexcept { pthread_mutex_lock(&_handle); }
+     158             :   //! Unlock.
+     159       31895 :   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       31895 :   ASMJIT_INLINE ~AutoLock() noexcept { _target.unlock(); }
+     186             : 
+     187             :   // --------------------------------------------------------------------------
+     188             :   // [Members]
+     189             :   // --------------------------------------------------------------------------
+     190             : 
+     191             :   //! Reference to the `Lock`.
+     192             :   Lock& _target;
+     193             : };
+     194             : 
+     195             : //! \}
+     196             : 
+     197             : } // asmjit namespace
+     198             : } // namespace PLMD
+     199             : 
+     200             : // [Api-End]
+     201             : #include "./asmjit_apiend.h"
+     202             : 
+     203             : // [Guard]
+     204             : #endif // _ASMJIT_BASE_OSUTILS_H
+     205             : #pragma GCC diagnostic pop
+     206             : #endif // __PLUMED_HAS_ASMJIT
+     207             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/regalloc.cpp.func-sort-c.html b/coverage-libs/asmjit/regalloc.cpp.func-sort-c.html new file mode 100644 index 000000000000..7389106ad14d --- /dev/null +++ b/coverage-libs/asmjit/regalloc.cpp.func-sort-c.html @@ -0,0 +1,125 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/regalloc.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - regalloc.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:11424147.3 %
Date:2024-04-19 12:12:36Functions:91369.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit6RAPass13_newStackCellEjj0
_ZN4PLMD6asmjit6RAPass19formatInlineCommentERNS0_13StringBuilderEPNS0_6CBNodeE0
_ZN4PLMD6asmjit6RAPassD0Ev0
_ZN4PLMD6asmjit6RAPassD2Ev0
_ZN4PLMD6asmjit6RAPass16livenessAnalysisEv31895
_ZN4PLMD6asmjit6RAPass18resolveCellOffsetsEv31895
_ZN4PLMD6asmjit6RAPass21removeUnreachableCodeEv31895
_ZN4PLMD6asmjit6RAPass7cleanupEv31895
_ZN4PLMD6asmjit6RAPass7compileEPNS0_6CCFuncE31895
_ZN4PLMD6asmjit6RAPass7prepareEPNS0_6CCFuncE31895
_ZN4PLMD6asmjit6RAPass7processEPNS0_4ZoneE31895
_ZN4PLMD6asmjit6RAPassC2Ev31895
_ZN4PLMD6asmjit6RAPass11_newVarCellEPNS0_7VirtRegE39412
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/regalloc.cpp.func.html b/coverage-libs/asmjit/regalloc.cpp.func.html new file mode 100644 index 000000000000..12c453128461 --- /dev/null +++ b/coverage-libs/asmjit/regalloc.cpp.func.html @@ -0,0 +1,125 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/regalloc.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - regalloc.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:11424147.3 %
Date:2024-04-19 12:12:36Functions:91369.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit6RAPass11_newVarCellEPNS0_7VirtRegE39412
_ZN4PLMD6asmjit6RAPass13_newStackCellEjj0
_ZN4PLMD6asmjit6RAPass16livenessAnalysisEv31895
_ZN4PLMD6asmjit6RAPass18resolveCellOffsetsEv31895
_ZN4PLMD6asmjit6RAPass19formatInlineCommentERNS0_13StringBuilderEPNS0_6CBNodeE0
_ZN4PLMD6asmjit6RAPass21removeUnreachableCodeEv31895
_ZN4PLMD6asmjit6RAPass7cleanupEv31895
_ZN4PLMD6asmjit6RAPass7compileEPNS0_6CCFuncE31895
_ZN4PLMD6asmjit6RAPass7prepareEPNS0_6CCFuncE31895
_ZN4PLMD6asmjit6RAPass7processEPNS0_4ZoneE31895
_ZN4PLMD6asmjit6RAPassC2Ev31895
_ZN4PLMD6asmjit6RAPassD0Ev0
_ZN4PLMD6asmjit6RAPassD2Ev0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/regalloc.cpp.gcov.html b/coverage-libs/asmjit/regalloc.cpp.gcov.html new file mode 100644 index 000000000000..7175931faa59 --- /dev/null +++ b/coverage-libs/asmjit/regalloc.cpp.gcov.html @@ -0,0 +1,697 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/regalloc.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - regalloc.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:11424147.3 %
Date:2024-04-19 12:12:36Functions: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       31895 : RAPass::RAPass() noexcept :
+      51             :   CBPass("RA"),
+      52       31895 :   _varMapToVaListOffset(0) {}
+      53           0 : RAPass::~RAPass() noexcept {}
+      54             : 
+      55             : // ============================================================================
+      56             : // [asmjit::RAPass - Interface]
+      57             : // ============================================================================
+      58             : 
+      59       31895 : Error RAPass::process(Zone* zone) noexcept {
+      60       31895 :   _zone = zone;
+      61       31895 :   _heap.reset(zone);
+      62       31895 :   _emitComments = (cb()->getGlobalOptions() & CodeEmitter::kOptionLoggingEnabled) != 0;
+      63             : 
+      64             :   Error err = kErrorOk;
+      65             :   CBNode* node = cc()->getFirstNode();
+      66       31895 :   if (!node) return err;
+      67             : 
+      68             :   do {
+      69       31895 :     if (node->getType() == CBNode::kNodeFunc) {
+      70             :       CCFunc* func = static_cast<CCFunc*>(node);
+      71             :       node = func->getEnd();
+      72             : 
+      73       31895 :       err = compile(func);
+      74       31895 :       if (err) break;
+      75             :     }
+      76             : 
+      77             :     // Find a function by skipping all nodes that are not `kNodeFunc`.
+      78             :     do {
+      79             :       node = node->getNext();
+      80       31895 :     } while (node && node->getType() != CBNode::kNodeFunc);
+      81       31895 :   } while (node);
+      82             : 
+      83       31895 :   _heap.reset(nullptr);
+      84       31895 :   _zone = nullptr;
+      85       31895 :   return err;
+      86             : }
+      87             : 
+      88       31895 : Error RAPass::compile(CCFunc* func) noexcept {
+      89       31895 :   ASMJIT_PROPAGATE(prepare(func));
+      90             : 
+      91             :   Error err;
+      92             :   do {
+      93       31895 :     err = fetch();
+      94       31895 :     if (err) break;
+      95             : 
+      96       31895 :     err = removeUnreachableCode();
+      97       31895 :     if (err) break;
+      98             : 
+      99       31895 :     err = livenessAnalysis();
+     100       31895 :     if (err) break;
+     101             : 
+     102             : #if !defined(ASMJIT_DISABLE_LOGGING)
+     103       31895 :     if (cc()->getGlobalOptions() & CodeEmitter::kOptionLoggingEnabled) {
+     104           0 :       err = annotate();
+     105           0 :       if (err) break;
+     106             :     }
+     107             : #endif // !ASMJIT_DISABLE_LOGGING
+     108             : 
+     109       31895 :     err = translate();
+     110             :   } while (false);
+     111             : 
+     112       31895 :   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       31895 :   return err;
+     119             : }
+     120             : 
+     121       31895 : Error RAPass::prepare(CCFunc* func) noexcept {
+     122             :   CBNode* end = func->getEnd();
+     123             : 
+     124       31895 :   _func = func;
+     125       31895 :   _stop = end->getNext();
+     126             : 
+     127             :   _unreachableList.reset();
+     128             :   _returningList.reset();
+     129             :   _jccList.reset();
+     130             :   _contextVd.reset();
+     131             : 
+     132       31895 :   _memVarCells = nullptr;
+     133       31895 :   _memStackCells = nullptr;
+     134             : 
+     135       31895 :   _mem1ByteVarsUsed = 0;
+     136       31895 :   _mem2ByteVarsUsed = 0;
+     137       31895 :   _mem4ByteVarsUsed = 0;
+     138       31895 :   _mem8ByteVarsUsed = 0;
+     139       31895 :   _mem16ByteVarsUsed = 0;
+     140       31895 :   _mem32ByteVarsUsed = 0;
+     141       31895 :   _mem64ByteVarsUsed = 0;
+     142       31895 :   _memStackCellsUsed = 0;
+     143             : 
+     144       31895 :   _memMaxAlign = 0;
+     145       31895 :   _memVarTotal = 0;
+     146       31895 :   _memStackTotal = 0;
+     147       31895 :   _memAllTotal = 0;
+     148       31895 :   _annotationLength = 12;
+     149             : 
+     150       31895 :   return kErrorOk;
+     151             : }
+     152             : 
+     153       31895 : void RAPass::cleanup() noexcept {
+     154             :   VirtReg** virtArray = _contextVd.getData();
+     155             :   size_t virtCount = _contextVd.getLength();
+     156             : 
+     157      347007 :   for (size_t i = 0; i < virtCount; i++) {
+     158      315112 :     VirtReg* vreg = virtArray[i];
+     159      315112 :     vreg->_raId = kInvalidValue;
+     160             :     vreg->resetPhysId();
+     161             :   }
+     162             : 
+     163             :   _contextVd.reset();
+     164       31895 : }
+     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       39412 : RACell* RAPass::_newVarCell(VirtReg* vreg) {
+     188             :   ASMJIT_ASSERT(vreg->_memCell == nullptr);
+     189             : 
+     190             :   RACell* cell;
+     191       39412 :   uint32_t size = vreg->getSize();
+     192             : 
+     193       39412 :   if (vreg->isStack()) {
+     194           0 :     cell = _newStackCell(size, vreg->getAlignment());
+     195           0 :     if (ASMJIT_UNLIKELY(!cell)) return nullptr;
+     196             :   }
+     197             :   else {
+     198       39412 :     cell = static_cast<RACell*>(_zone->alloc(sizeof(RACell)));
+     199       39412 :     if (!cell) goto _NoMemory;
+     200             : 
+     201       39412 :     cell->next = _memVarCells;
+     202       39412 :     cell->offset = 0;
+     203       39412 :     cell->size = size;
+     204       39412 :     cell->alignment = size;
+     205             : 
+     206       39412 :     _memVarCells = cell;
+     207       39412 :     _memMaxAlign = std::max<uint32_t>(_memMaxAlign, size);
+     208       39412 :     _memVarTotal += size;
+     209             : 
+     210       39412 :     switch (size) {
+     211           0 :       case  1: _mem1ByteVarsUsed++ ; break;
+     212           0 :       case  2: _mem2ByteVarsUsed++ ; break;
+     213           0 :       case  4: _mem4ByteVarsUsed++ ; break;
+     214       39412 :       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       39412 :   vreg->_memCell = cell;
+     225       39412 :   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       31895 : Error RAPass::resolveCellOffsets() {
+     271       31895 :   RACell* varCell = _memVarCells;
+     272       31895 :   RACell* stackCell = _memStackCells;
+     273             : 
+     274             :   uint32_t pos64 = 0;
+     275       31895 :   uint32_t pos32 = pos64 + _mem64ByteVarsUsed * 64;
+     276       31895 :   uint32_t pos16 = pos32 + _mem32ByteVarsUsed * 32;
+     277       31895 :   uint32_t pos8  = pos16 + _mem16ByteVarsUsed * 16;
+     278       31895 :   uint32_t pos4  = pos8  + _mem8ByteVarsUsed  * 8 ;
+     279       31895 :   uint32_t pos2  = pos4  + _mem4ByteVarsUsed  * 4 ;
+     280       31895 :   uint32_t pos1  = pos2  + _mem2ByteVarsUsed  * 2 ;
+     281             : 
+     282             :   // Assign home slots.
+     283       71307 :   while (varCell) {
+     284       39412 :     uint32_t size = varCell->size;
+     285             :     uint32_t offset = 0;
+     286             : 
+     287       39412 :     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       39412 :       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       39412 :     varCell->offset = static_cast<int32_t>(offset);
+     301       39412 :     varCell = varCell->next;
+     302             :   }
+     303             : 
+     304             :   // Assign stack slots.
+     305       31895 :   uint32_t stackPos = pos1 + _mem1ByteVarsUsed;
+     306       31895 :   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       31895 :   _memAllTotal = stackPos;
+     319       31895 :   return kErrorOk;
+     320             : }
+     321             : 
+     322             : // ============================================================================
+     323             : // [asmjit::RAPass - RemoveUnreachableCode]
+     324             : // ============================================================================
+     325             : 
+     326       31895 : Error RAPass::removeUnreachableCode() {
+     327             :   ZoneList<CBNode*>::Link* link = _unreachableList.getFirst();
+     328             :   CBNode* stop = getStop();
+     329             : 
+     330       63790 :   while (link) {
+     331             :     CBNode* node = link->getValue();
+     332       31895 :     if (node && node->getPrev() && node != stop) {
+     333             :       // Locate all unreachable nodes.
+     334             :       CBNode* first = node;
+     335             :       do {
+     336       31895 :         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       31895 :       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       31895 :   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       31895 : Error RAPass::livenessAnalysis() {
+     385             :   uint32_t bLen = static_cast<uint32_t>(
+     386       31895 :     ((_contextVd.getLength() + RABits::kEntityBits - 1) / RABits::kEntityBits));
+     387             : 
+     388             :   // No variables.
+     389       31895 :   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       31895 :   size_t varMapToVaListOffset = _varMapToVaListOffset;
+     405             :   RABits* bCur = newBits(bLen);
+     406       31895 :   if (ASMJIT_UNLIKELY(!bCur)) goto NoMem;
+     407             : 
+     408             :   // Allocate bits for code visited first time.
+     409      489779 : Visit:
+     410             :   for (;;) {
+     411             :     wd = node->getPassData<RAData>();
+     412      489779 :     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      489779 :     if (!bTmp) goto NoMem;
+     421             : 
+     422             :     wd = node->getPassData<RAData>();
+     423      489779 :     wd->liveness = bTmp;
+     424             : 
+     425      489779 :     uint32_t tiedTotal = wd->tiedTotal;
+     426             :     TiedReg* tiedArray = reinterpret_cast<TiedReg*>(((uint8_t*)wd) + varMapToVaListOffset);
+     427             : 
+     428     1276332 :     for (uint32_t i = 0; i < tiedTotal; i++) {
+     429      786553 :       TiedReg* tied = &tiedArray[i];
+     430      786553 :       VirtReg* vreg = tied->vreg;
+     431             : 
+     432      786553 :       uint32_t flags = tied->flags;
+     433      786553 :       uint32_t raId = vreg->_raId;
+     434             : 
+     435      786553 :       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      489779 :     if (node->getType() == CBNode::kNodeLabel)
+     448           0 :       goto Target;
+     449             : 
+     450      489779 :     if (node == func)
+     451       31895 :       goto Done;
+     452             : 
+     453             :     ASMJIT_ASSERT(node->getPrev());
+     454             :     node = node->getPrev();
+     455      457884 :   }
+     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       31895 :   if (ltCur) {
+     540           0 :     node = ltCur->node;
+     541           0 :     from = ltCur->from;
+     542             : 
+     543           0 :     goto JumpNext;
+     544             :   }
+     545             : 
+     546             :   retPtr = retPtr->getNext();
+     547       31895 :   if (retPtr) {
+     548             :     node = retPtr->getValue();
+     549           0 :     goto Visit;
+     550             :   }
+     551             : 
+     552             :   return kErrorOk;
+     553             : 
+     554             : NoMem:
+     555             :   return DebugUtils::errored(kErrorNoHeapMemory);
+     556             : }
+     557             : 
+     558             : // ============================================================================
+     559             : // [asmjit::RAPass - Annotate]
+     560             : // ============================================================================
+     561             : 
+     562           0 : Error RAPass::formatInlineComment(StringBuilder& dst, CBNode* node) {
+     563             : #if !defined(ASMJIT_DISABLE_LOGGING)
+     564             :   RAData* wd = node->getPassData<RAData>();
+     565             : 
+     566           0 :   if (node->hasInlineComment())
+     567             :     dst.appendString(node->getInlineComment());
+     568             : 
+     569           0 :   if (wd && wd->liveness) {
+     570           0 :     if (dst.getLength() < _annotationLength)
+     571           0 :       dst.appendChars(' ', _annotationLength - dst.getLength());
+     572             : 
+     573           0 :     uint32_t vdCount = static_cast<uint32_t>(_contextVd.getLength());
+     574           0 :     size_t offset = dst.getLength() + 1;
+     575             : 
+     576             :     dst.appendChar('[');
+     577             :     dst.appendChars(' ', vdCount);
+     578             :     dst.appendChar(']');
+     579           0 :     RABits* liveness = wd->liveness;
+     580             : 
+     581             :     uint32_t i;
+     582           0 :     for (i = 0; i < vdCount; i++) {
+     583           0 :       if (liveness->getBit(i))
+     584           0 :         dst.getData()[offset + i] = '.';
+     585             :     }
+     586             : 
+     587           0 :     uint32_t tiedTotal = wd->tiedTotal;
+     588           0 :     TiedReg* tiedArray = reinterpret_cast<TiedReg*>(((uint8_t*)wd) + _varMapToVaListOffset);
+     589             : 
+     590           0 :     for (i = 0; i < tiedTotal; i++) {
+     591           0 :       TiedReg* tied = &tiedArray[i];
+     592           0 :       VirtReg* vreg = tied->vreg;
+     593           0 :       uint32_t flags = tied->flags;
+     594             : 
+     595             :       char c = 'u';
+     596           0 :       if ( (flags & TiedReg::kRAll) && !(flags & TiedReg::kWAll)) c = 'r';
+     597           0 :       if (!(flags & TiedReg::kRAll) &&  (flags & TiedReg::kWAll)) c = 'w';
+     598           0 :       if ( (flags & TiedReg::kRAll) &&  (flags & TiedReg::kWAll)) c = 'x';
+     599             :       // Uppercase if unused.
+     600           0 :       if ( (flags & TiedReg::kUnuse)) c -= 'a' - 'A';
+     601             : 
+     602             :       ASMJIT_ASSERT(offset + vreg->_raId < dst.getLength());
+     603           0 :       dst._data[offset + vreg->_raId] = c;
+     604             :     }
+     605             :   }
+     606             : #endif // !ASMJIT_DISABLE_LOGGING
+     607             : 
+     608           0 :   return kErrorOk;
+     609             : }
+     610             : 
+     611             : } // asmjit namespace
+     612             : } // namespace PLMD
+     613             : 
+     614             : // [Api-End]
+     615             : #include "./asmjit_apiend.h"
+     616             : 
+     617             : // [Guard]
+     618             : #endif // !ASMJIT_DISABLE_COMPILER
+     619             : #pragma GCC diagnostic pop
+     620             : #endif // __PLUMED_HAS_ASMJIT
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/regalloc_p.h.func-sort-c.html b/coverage-libs/asmjit/regalloc_p.h.func-sort-c.html new file mode 100644 index 000000000000..cd2fac8a714b --- /dev/null +++ b/coverage-libs/asmjit/regalloc_p.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/regalloc_p.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - regalloc_p.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:365466.7 %
Date:2024-04-19 12:12:36Functions:00-
+
+ +
+ + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/regalloc_p.h.gcov.html b/coverage-libs/asmjit/regalloc_p.h.gcov.html new file mode 100644 index 000000000000..2e2e53955bdd --- /dev/null +++ b/coverage-libs/asmjit/regalloc_p.h.gcov.html @@ -0,0 +1,674 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/regalloc_p.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - regalloc_p.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:365466.7 %
Date:2024-04-19 12:12:36Functions: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      786553 :     this->vreg = vreg;
+     101      786553 :     this->flags = flags;
+     102      786553 :     this->refCount = 0;
+     103      786553 :     this->inPhysId = Globals::kInvalidRegId;
+     104      786553 :     this->outPhysId = Globals::kInvalidRegId;
+     105      786553 :     this->reserved = 0;
+     106      786553 :     this->inRegs = inRegs;
+     107       12914 :     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       62990 :   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      365188 :   ASMJIT_INLINE uint32_t hasOutPhysId() const { return outPhysId != Globals::kInvalidRegId; }
+     118             : 
+     119             :   //! Set the input register index.
+     120      471441 :   ASMJIT_INLINE void setInPhysId(uint32_t index) { inPhysId = static_cast<uint8_t>(index); }
+     121             :   //! Set the output register index.
+     122      315112 :   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     2952093 :     return (data[index / kEntityBits] >> (index % kEntityBits)) & 1;
+     210             :   }
+     211             : 
+     212             :   ASMJIT_INLINE void setBit(uint32_t index) noexcept {
+     213      786553 :     data[index / kEntityBits] |= static_cast<uintptr_t>(1) << (index % kEntityBits);
+     214      471441 :   }
+     215             : 
+     216             :   ASMJIT_INLINE void delBit(uint32_t index) noexcept {
+     217      315112 :     data[index / kEntityBits] &= ~(static_cast<uintptr_t>(1) << (index % kEntityBits));
+     218      315112 :   }
+     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      553569 :     : liveness(nullptr),
+     323      553569 :       state(nullptr),
+     324      553569 :       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       63790 :   ASMJIT_INLINE CodeCompiler* cc() const noexcept { return static_cast<CodeCompiler*>(_cb); }
+     382             : 
+     383             :   //! Get function.
+     384       63790 :   ASMJIT_INLINE CCFunc* getFunc() const noexcept { return _func; }
+     385             :   //! Get stop node.
+     386       95685 :   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      786553 :     if (ASMJIT_LIKELY(vreg->_raId != kInvalidValue)) return kErrorOk;
+     416             : 
+     417      315112 :     uint32_t raId = static_cast<uint32_t>(_contextVd.getLength());
+     418      315112 :     ASMJIT_PROPAGATE(_contextVd.append(&_heap, vreg));
+     419             : 
+     420      315112 :     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       91108 :     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       31895 :       _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      489779 :       _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       31895 :     ZoneList<CBNode*>::Link* link = _zone->allocT<ZoneList<CBNode*>::Link>();
+     470       31895 :     if (!link) return DebugUtils::errored(kErrorNoHeapMemory);
+     471             : 
+     472             :     link->setValue(node);
+     473             :     _unreachableList.append(link);
+     474             : 
+     475       31895 :     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       31895 :     ZoneList<CBNode*>::Link* link = _zone->allocT<ZoneList<CBNode*>::Link>();
+     489       31895 :     if (!link) return DebugUtils::errored(kErrorNoHeapMemory);
+     490             : 
+     491             :     link->setValue(node);
+     492             :     _returningList.append(link);
+     493             : 
+     494       31895 :     return kErrorOk;
+     495             :   }
+     496             : 
+     497             :   //! Add jump-flow data to the jcc flow list.
+     498             :   ASMJIT_INLINE Error addJccNode(CBNode* node) {
+     499           0 :     ZoneList<CBNode*>::Link* link = _zone->allocT<ZoneList<CBNode*>::Link>();
+     500           0 :     if (!link) return DebugUtils::errored(kErrorNoHeapMemory);
+     501             : 
+     502             :     link->setValue(node);
+     503             :     _jccList.append(link);
+     504             : 
+     505           0 :     return kErrorOk;
+     506             :   }
+     507             : 
+     508             :   // --------------------------------------------------------------------------
+     509             :   // [Analyze]
+     510             :   // --------------------------------------------------------------------------
+     511             : 
+     512             :   //! Perform variable liveness analysis.
+     513             :   //!
+     514             :   //! Analysis phase iterates over nodes in reverse order and generates a bit
+     515             :   //! array describing variables that are alive at every node in the function.
+     516             :   //! When the analysis start all variables are assumed dead. When a read or
+     517             :   //! read/write operations of a variable is detected the variable becomes
+     518             :   //! alive; when only write operation is detected the variable becomes dead.
+     519             :   //!
+     520             :   //! When a label is found all jumps to that label are followed and analysis
+     521             :   //! repeats until all variables are resolved.
+     522             :   virtual Error livenessAnalysis();
+     523             : 
+     524             :   // --------------------------------------------------------------------------
+     525             :   // [Annotate]
+     526             :   // --------------------------------------------------------------------------
+     527             : 
+     528             :   virtual Error annotate() = 0;
+     529             :   virtual Error formatInlineComment(StringBuilder& dst, CBNode* node);
+     530             : 
+     531             :   // --------------------------------------------------------------------------
+     532             :   // [Translate]
+     533             :   // --------------------------------------------------------------------------
+     534             : 
+     535             :   //! Translate code by allocating registers and handling state changes.
+     536             :   virtual Error translate() = 0;
+     537             : 
+     538             :   // --------------------------------------------------------------------------
+     539             :   // [Members]
+     540             :   // --------------------------------------------------------------------------
+     541             : 
+     542             :   Zone* _zone;                           //!< Zone passed to `process()`.
+     543             :   ZoneHeap _heap;                        //!< ZoneHeap that uses `_zone`.
+     544             : 
+     545             :   CCFunc* _func;                         //!< Function being processed.
+     546             :   CBNode* _stop;                         //!< Stop node.
+     547             : 
+     548             :   //! \internal
+     549             :   //!
+     550             :   //! Offset (how many bytes to add) to `VarMap` to get `TiedReg` array. Used
+     551             :   //! by liveness analysis shared across all backends. This is needed because
+     552             :   //! `VarMap` is a base class for a specialized version that liveness analysis
+     553             :   //! doesn't use, it just needs `TiedReg` array.
+     554             :   uint32_t _varMapToVaListOffset;
+     555             : 
+     556             :   uint8_t _emitComments;                 //!< Whether to emit comments.
+     557             : 
+     558             :   ZoneList<CBNode*> _unreachableList;     //!< Unreachable nodes.
+     559             :   ZoneList<CBNode*> _returningList;       //!< Returning nodes.
+     560             :   ZoneList<CBNode*> _jccList;             //!< Jump nodes.
+     561             : 
+     562             :   ZoneVector<VirtReg*> _contextVd;       //!< All variables used by the current function.
+     563             :   RACell* _memVarCells;                  //!< Memory used to spill variables.
+     564             :   RACell* _memStackCells;                //!< Memory used to allocate memory on the stack.
+     565             : 
+     566             :   uint32_t _mem1ByteVarsUsed;            //!< Count of 1-byte cells.
+     567             :   uint32_t _mem2ByteVarsUsed;            //!< Count of 2-byte cells.
+     568             :   uint32_t _mem4ByteVarsUsed;            //!< Count of 4-byte cells.
+     569             :   uint32_t _mem8ByteVarsUsed;            //!< Count of 8-byte cells.
+     570             :   uint32_t _mem16ByteVarsUsed;           //!< Count of 16-byte cells.
+     571             :   uint32_t _mem32ByteVarsUsed;           //!< Count of 32-byte cells.
+     572             :   uint32_t _mem64ByteVarsUsed;           //!< Count of 64-byte cells.
+     573             :   uint32_t _memStackCellsUsed;           //!< Count of stack memory cells.
+     574             : 
+     575             :   uint32_t _memMaxAlign;                 //!< Maximum memory alignment used by the function.
+     576             :   uint32_t _memVarTotal;                 //!< Count of bytes used by variables.
+     577             :   uint32_t _memStackTotal;               //!< Count of bytes used by stack.
+     578             :   uint32_t _memAllTotal;                 //!< Count of bytes used by variables and stack after alignment.
+     579             : 
+     580             :   uint32_t _annotationLength;            //!< Default length of an annotated instruction.
+     581             :   RAState* _state;                       //!< Current RA state.
+     582             : };
+     583             : 
+     584             : //! \}
+     585             : 
+     586             : } // asmjit namespace
+     587             : } // namespace PLMD
+     588             : 
+     589             : // [Api-End]
+     590             : #include "./asmjit_apiend.h"
+     591             : 
+     592             : // [Guard]
+     593             : #endif // !ASMJIT_DISABLE_COMPILER
+     594             : #endif // _ASMJIT_BASE_REGALLOC_P_H
+     595             : #pragma GCC diagnostic pop
+     596             : #endif // __PLUMED_HAS_ASMJIT
+     597             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/runtime.cpp.func-sort-c.html b/coverage-libs/asmjit/runtime.cpp.func-sort-c.html new file mode 100644 index 000000000000..46b7053e849b --- /dev/null +++ b/coverage-libs/asmjit/runtime.cpp.func-sort-c.html @@ -0,0 +1,121 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/runtime.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - runtime.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:283873.7 %
Date:2024-04-19 12:12:36Functions:91275.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit10JitRuntime8_releaseEPv0
_ZN4PLMD6asmjit11HostRuntimeD0Ev0
_ZN4PLMD6asmjit7RuntimeD0Ev0
_ZN4PLMD6asmjit10JitRuntime4_addEPPvPNS0_10CodeHolderE31895
_ZN4PLMD6asmjit11HostRuntime5flushEPKvm31895
_ZN4PLMD6asmjit10JitRuntimeC2Ev31925
_ZN4PLMD6asmjit10JitRuntimeD0Ev31925
_ZN4PLMD6asmjit10JitRuntimeD2Ev31925
_ZN4PLMD6asmjit11HostRuntimeC2Ev31925
_ZN4PLMD6asmjit11HostRuntimeD2Ev31925
_ZN4PLMD6asmjit7RuntimeC2Ev31925
_ZN4PLMD6asmjit7RuntimeD2Ev31925
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/runtime.cpp.func.html b/coverage-libs/asmjit/runtime.cpp.func.html new file mode 100644 index 000000000000..72e2771a7d45 --- /dev/null +++ b/coverage-libs/asmjit/runtime.cpp.func.html @@ -0,0 +1,121 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/runtime.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - runtime.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:283873.7 %
Date:2024-04-19 12:12:36Functions:91275.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit10JitRuntime4_addEPPvPNS0_10CodeHolderE31895
_ZN4PLMD6asmjit10JitRuntime8_releaseEPv0
_ZN4PLMD6asmjit10JitRuntimeC2Ev31925
_ZN4PLMD6asmjit10JitRuntimeD0Ev31925
_ZN4PLMD6asmjit10JitRuntimeD2Ev31925
_ZN4PLMD6asmjit11HostRuntime5flushEPKvm31895
_ZN4PLMD6asmjit11HostRuntimeC2Ev31925
_ZN4PLMD6asmjit11HostRuntimeD0Ev0
_ZN4PLMD6asmjit11HostRuntimeD2Ev31925
_ZN4PLMD6asmjit7RuntimeC2Ev31925
_ZN4PLMD6asmjit7RuntimeD0Ev0
_ZN4PLMD6asmjit7RuntimeD2Ev31925
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/runtime.cpp.gcov.html b/coverage-libs/asmjit/runtime.cpp.gcov.html new file mode 100644 index 000000000000..abd5fa6c91b1 --- /dev/null +++ b/coverage-libs/asmjit/runtime.cpp.gcov.html @@ -0,0 +1,250 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/runtime.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - runtime.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:283873.7 %
Date:2024-04-19 12:12:36Functions: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       31925 : Runtime::Runtime() noexcept
+      93             :   : _codeInfo(),
+      94       31925 :     _runtimeType(kRuntimeNone),
+      95       31925 :     _allocType(VMemMgr::kAllocFreeable) {}
+      96       31925 : Runtime::~Runtime() noexcept {}
+      97             : 
+      98             : // ============================================================================
+      99             : // [asmjit::HostRuntime - Construction / Destruction]
+     100             : // ============================================================================
+     101             : 
+     102       31925 : HostRuntime::HostRuntime() noexcept {
+     103       31925 :   _runtimeType = kRuntimeJit;
+     104             : 
+     105             :   // Setup the CodeInfo of this Runtime.
+     106       31925 :   _codeInfo._archInfo       = CpuInfo::getHost().getArchInfo();
+     107       31925 :   _codeInfo._stackAlignment = static_cast<uint8_t>(hostDetectNaturalStackAlignment());
+     108       31925 :   _codeInfo._cdeclCallConv  = CallConv::kIdHostCDecl;
+     109       31925 :   _codeInfo._stdCallConv    = CallConv::kIdHostStdCall;
+     110       31925 :   _codeInfo._fastCallConv   = CallConv::kIdHostFastCall;
+     111       31925 : }
+     112       31925 : HostRuntime::~HostRuntime() noexcept {}
+     113             : 
+     114             : // ============================================================================
+     115             : // [asmjit::HostRuntime - Interface]
+     116             : // ============================================================================
+     117             : 
+     118       31895 : void HostRuntime::flush(const void* p, size_t size) noexcept {
+     119             :   hostFlushInstructionCache(p, size);
+     120       31895 : }
+     121             : 
+     122             : // ============================================================================
+     123             : // [asmjit::JitRuntime - Construction / Destruction]
+     124             : // ============================================================================
+     125             : 
+     126       31925 : JitRuntime::JitRuntime() noexcept {}
+     127       63850 : JitRuntime::~JitRuntime() noexcept {}
+     128             : 
+     129             : // ============================================================================
+     130             : // [asmjit::JitRuntime - Interface]
+     131             : // ============================================================================
+     132             : 
+     133       31895 : Error JitRuntime::_add(void** dst, CodeHolder* code) noexcept {
+     134       31895 :   size_t codeSize = code->getCodeSize();
+     135       31895 :   if (ASMJIT_UNLIKELY(codeSize == 0)) {
+     136           0 :     *dst = nullptr;
+     137           0 :     return DebugUtils::errored(kErrorNoCodeGenerated);
+     138             :   }
+     139             : 
+     140       31895 :   void* p = _memMgr.alloc(codeSize, getAllocType());
+     141       31895 :   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       31895 :   size_t relocSize = code->relocate(p);
+     148       31895 :   if (ASMJIT_UNLIKELY(relocSize == 0)) {
+     149           0 :     *dst = nullptr;
+     150           0 :     _memMgr.release(p);
+     151           0 :     return DebugUtils::errored(kErrorInvalidState);
+     152             :   }
+     153             : 
+     154       31895 :   if (relocSize < codeSize)
+     155           0 :     _memMgr.shrink(p, relocSize);
+     156             : 
+     157       31895 :   flush(p, relocSize);
+     158       31895 :   *dst = p;
+     159             : 
+     160       31895 :   return kErrorOk;
+     161             : }
+     162             : 
+     163           0 : Error JitRuntime::_release(void* p) noexcept {
+     164           0 :   return _memMgr.release(p);
+     165             : }
+     166             : 
+     167             : } // asmjit namespace
+     168             : } // namespace PLMD
+     169             : 
+     170             : // [Api-End]
+     171             : #include "./asmjit_apiend.h"
+     172             : #pragma GCC diagnostic pop
+     173             : #endif // __PLUMED_HAS_ASMJIT
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/runtime.h.func-sort-c.html b/coverage-libs/asmjit/runtime.h.func-sort-c.html new file mode 100644 index 000000000000..2f6049acff19 --- /dev/null +++ b/coverage-libs/asmjit/runtime.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/runtime.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - runtime.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:33100.0 %
Date:2024-04-19 12:12:36Functions:00-
+
+ +
+ + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/runtime.h.gcov.html b/coverage-libs/asmjit/runtime.h.gcov.html new file mode 100644 index 000000000000..83d7fb7798f0 --- /dev/null +++ b/coverage-libs/asmjit/runtime.h.gcov.html @@ -0,0 +1,304 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/runtime.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - runtime.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:33100.0 %
Date:2024-04-19 12:12:36Functions: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       31895 :   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       31895 :     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       31895 :   ASMJIT_INLINE uint32_t getAllocType() const noexcept { return _allocType; }
+     194             :   //! Set the type of allocation.
+     195             :   ASMJIT_INLINE void setAllocType(uint32_t allocType) noexcept { _allocType = allocType; }
+     196             : 
+     197             :   //! Get the virtual memory manager.
+     198             :   ASMJIT_INLINE VMemMgr* getMemMgr() const noexcept { return const_cast<VMemMgr*>(&_memMgr); }
+     199             : 
+     200             :   // --------------------------------------------------------------------------
+     201             :   // [Interface]
+     202             :   // --------------------------------------------------------------------------
+     203             : 
+     204             :   ASMJIT_API Error _add(void** dst, CodeHolder* code) noexcept override;
+     205             :   ASMJIT_API Error _release(void* p) noexcept override;
+     206             : 
+     207             :   // --------------------------------------------------------------------------
+     208             :   // [Members]
+     209             :   // --------------------------------------------------------------------------
+     210             : 
+     211             :   //! Virtual memory manager.
+     212             :   VMemMgr _memMgr;
+     213             : };
+     214             : 
+     215             : //! \}
+     216             : 
+     217             : } // asmjit namespace
+     218             : } // namespace PLMD
+     219             : 
+     220             : // [Api-End]
+     221             : #include "./asmjit_apiend.h"
+     222             : 
+     223             : // [Guard]
+     224             : #endif // _ASMJIT_BASE_RUNTIME_H
+     225             : #pragma GCC diagnostic pop
+     226             : #endif // __PLUMED_HAS_ASMJIT
+     227             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/string.cpp.func-sort-c.html b/coverage-libs/asmjit/string.cpp.func-sort-c.html new file mode 100644 index 000000000000..263398890255 --- /dev/null +++ b/coverage-libs/asmjit/string.cpp.func-sort-c.html @@ -0,0 +1,129 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/string.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - string.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:01380.0 %
Date:2024-04-19 12:12:36Functions:0140.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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

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

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

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

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/utils.h.gcov.html b/coverage-libs/asmjit/utils.h.gcov.html new file mode 100644 index 000000000000..7f2a651e98bf --- /dev/null +++ b/coverage-libs/asmjit/utils.h.gcov.html @@ -0,0 +1,1464 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/utils.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - utils.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:224548.9 %
Date:2024-04-19 12:12:36Functions: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      489779 :     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      619415 :     return ASMJIT_ARCH_LE ? (static_cast<uint64_t>(u1) << 32) + u0
+     146      378902 :                           : (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     1573106 :       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      228660 :     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        4588 :     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      115454 :       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      365188 :     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     2020922 :     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       76704 :     uint32_t overflow = static_cast<uint32_t>(
+     402       76704 :       -static_cast<int32_t>(x >= sizeof(uint32_t) * 8));
+     403             : 
+     404       76704 :     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       31895 :     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      416639 :     if (mask)
+     507      416639 :       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     2331776 :     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        6978 :     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      158710 :     ASMJIT_ASSUME_ALIGNED(p, Alignment > 1 ? Alignment : 1U);
+     961             :     if (ASMJIT_ARCH_UNALIGNED_32 || Alignment >= 4) {
+     962      158710 :       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     1088157 :       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      958965 :       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      921835 :       u64 |= val.u64;
+    1251             :     }
+    1252             :     else {
+    1253             :       u32[0] |= val.u32[0];
+    1254             :       u32[1] |= val.u32[1];
+    1255             :     }
+    1256             :     return *this;
+    1257             :   }
+    1258             : 
+    1259             :   // --------------------------------------------------------------------------
+    1260             :   // [Xor]
+    1261             :   // --------------------------------------------------------------------------
+    1262             : 
+    1263             :   ASMJIT_INLINE UInt64& xor_(uint64_t val) noexcept {
+    1264             :     u64 ^= val;
+    1265             :     return *this;
+    1266             :   }
+    1267             : 
+    1268             :   ASMJIT_INLINE UInt64& xor_(const UInt64& val) noexcept {
+    1269             :     if (ASMJIT_ARCH_64BIT) {
+    1270             :       u64 ^= val.u64;
+    1271             :     }
+    1272             :     else {
+    1273             :       u32[0] ^= val.u32[0];
+    1274             :       u32[1] ^= val.u32[1];
+    1275             :     }
+    1276             :     return *this;
+    1277             :   }
+    1278             : 
+    1279             :   // --------------------------------------------------------------------------
+    1280             :   // [Eq]
+    1281             :   // --------------------------------------------------------------------------
+    1282             : 
+    1283             :   ASMJIT_INLINE bool isZero() const noexcept {
+    1284             :     if (ASMJIT_ARCH_64BIT)
+    1285             :       return u64 == 0;
+    1286             :     else
+    1287             :       return (u32[0] | u32[1]) == 0;
+    1288             :   }
+    1289             : 
+    1290             :   ASMJIT_INLINE bool isNonZero() const noexcept {
+    1291             :     if (ASMJIT_ARCH_64BIT)
+    1292             :       return u64 != 0;
+    1293             :     else
+    1294             :       return (u32[0] | u32[1]) != 0;
+    1295             :   }
+    1296             : 
+    1297             :   ASMJIT_INLINE bool eq(uint64_t val) const noexcept {
+    1298             :     return u64 == val;
+    1299             :   }
+    1300             : 
+    1301             :   ASMJIT_INLINE bool eq(const UInt64& val) const noexcept {
+    1302             :     if (ASMJIT_ARCH_64BIT)
+    1303             :       return u64 == val.u64;
+    1304             :     else
+    1305             :       return u32[0] == val.u32[0] && u32[1] == val.u32[1];
+    1306             :   }
+    1307             : 
+    1308             :   // --------------------------------------------------------------------------
+    1309             :   // [Operator Overload]
+    1310             :   // --------------------------------------------------------------------------
+    1311             : 
+    1312             :   ASMJIT_INLINE UInt64& operator+=(uint64_t val) noexcept { return add(val); }
+    1313             :   ASMJIT_INLINE UInt64& operator+=(const UInt64& val) noexcept { return add(val); }
+    1314             : 
+    1315             :   ASMJIT_INLINE UInt64& operator-=(uint64_t val) noexcept { return sub(val); }
+    1316             :   ASMJIT_INLINE UInt64& operator-=(const UInt64& val) noexcept { return sub(val); }
+    1317             : 
+    1318             :   ASMJIT_INLINE UInt64& operator&=(uint64_t val) noexcept { return and_(val); }
+    1319             :   ASMJIT_INLINE UInt64& operator&=(const UInt64& val) noexcept { return and_(val); }
+    1320             : 
+    1321             :   ASMJIT_INLINE UInt64& operator|=(uint64_t val) noexcept { return or_(val); }
+    1322             :   ASMJIT_INLINE UInt64& operator|=(const UInt64& val) noexcept { return or_(val); }
+    1323             : 
+    1324             :   ASMJIT_INLINE UInt64& operator^=(uint64_t val) noexcept { return xor_(val); }
+    1325             :   ASMJIT_INLINE UInt64& operator^=(const UInt64& val) noexcept { return xor_(val); }
+    1326             : 
+    1327             :   ASMJIT_INLINE bool operator==(uint64_t val) const noexcept { return eq(val); }
+    1328             :   ASMJIT_INLINE bool operator==(const UInt64& val) const noexcept { return eq(val); }
+    1329             : 
+    1330             :   ASMJIT_INLINE bool operator!=(uint64_t val) const noexcept { return !eq(val); }
+    1331             :   ASMJIT_INLINE bool operator!=(const UInt64& val) const noexcept { return !eq(val); }
+    1332             : 
+    1333             :   ASMJIT_INLINE bool operator<(uint64_t val) const noexcept { return u64 < val; }
+    1334             :   ASMJIT_INLINE bool operator<(const UInt64& val) const noexcept { return u64 < val.u64; }
+    1335             : 
+    1336             :   ASMJIT_INLINE bool operator<=(uint64_t val) const noexcept { return u64 <= val; }
+    1337             :   ASMJIT_INLINE bool operator<=(const UInt64& val) const noexcept { return u64 <= val.u64; }
+    1338             : 
+    1339             :   ASMJIT_INLINE bool operator>(uint64_t val) const noexcept { return u64 > val; }
+    1340             :   ASMJIT_INLINE bool operator>(const UInt64& val) const noexcept { return u64 > val.u64; }
+    1341             : 
+    1342             :   ASMJIT_INLINE bool operator>=(uint64_t val) const noexcept { return u64 >= val; }
+    1343             :   ASMJIT_INLINE bool operator>=(const UInt64& val) const noexcept { return u64 >= val.u64; }
+    1344             : 
+    1345             :   // --------------------------------------------------------------------------
+    1346             :   // [Members]
+    1347             :   // --------------------------------------------------------------------------
+    1348             : 
+    1349             :   int8_t   i8[8];                        //!< 8-bit signed integer (8x).
+    1350             :   uint8_t  u8[8];                        //!< 8-bit unsigned integer (8x).
+    1351             : 
+    1352             :   int16_t  i16[4];                       //!< 16-bit signed integer (4x).
+    1353             :   uint16_t u16[4];                       //!< 16-bit unsigned integer (4x).
+    1354             : 
+    1355             :   int32_t  i32[2];                       //!< 32-bit signed integer (2x).
+    1356             :   uint32_t u32[2];                       //!< 32-bit unsigned integer (2x).
+    1357             : 
+    1358             :   int64_t  i64;                          //!< 64-bit signed integer.
+    1359             :   uint64_t u64;                          //!< 64-bit unsigned integer.
+    1360             : 
+    1361             :   float    f32[2];                       //!< 32-bit floating point (2x).
+    1362             :   double   f64;                          //!< 64-bit floating point.
+    1363             : 
+    1364             : #if ASMJIT_ARCH_LE
+    1365             :   struct { float    f32Lo, f32Hi; };
+    1366             :   struct { int32_t  i32Lo, i32Hi; };
+    1367             :   struct { uint32_t u32Lo, u32Hi; };
+    1368             : #else
+    1369             :   struct { float    f32Hi, f32Lo; };
+    1370             :   struct { int32_t  i32Hi, i32Lo; };
+    1371             :   struct { uint32_t u32Hi, u32Lo; };
+    1372             : #endif // ASMJIT_ARCH_LE
+    1373             : };
+    1374             : 
+    1375             : //! \}
+    1376             : 
+    1377             : } // asmjit namespace
+    1378             : } // namespace PLMD
+    1379             : 
+    1380             : // [Api-End]
+    1381             : #include "./asmjit_apiend.h"
+    1382             : 
+    1383             : // [Guard]
+    1384             : #endif // _ASMJIT_BASE_UTILS_H
+    1385             : #pragma GCC diagnostic pop
+    1386             : #endif // __PLUMED_HAS_ASMJIT
+    1387             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/vmem.cpp.func-sort-c.html b/coverage-libs/asmjit/vmem.cpp.func-sort-c.html new file mode 100644 index 000000000000..6ea24a54e5d2 --- /dev/null +++ b/coverage-libs/asmjit/vmem.cpp.func-sort-c.html @@ -0,0 +1,129 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/vmem.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - vmem.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:9731830.5 %
Date:2024-04-19 12:12:36Functions:81457.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit7VMemMgr5resetEv0
_ZN4PLMD6asmjit7VMemMgr6shrinkEPvm0
_ZN4PLMD6asmjit7VMemMgr7releaseEPv0
_ZN4PLMD6asmjitL17vMemMgrRemoveNodeEPNS0_7VMemMgrEPNS1_7MemNodeE0
_ZN4PLMD6asmjitL20vMemMgrFindNodeByPtrEPNS0_7VMemMgrEPh0
_ZN4PLMD6asmjitL21vMemMgrAllocPermanentEPNS0_7VMemMgrEm0
_ZN4PLMD6asmjit7VMemMgr5allocEmj31895
_ZN4PLMD6asmjitL17vMemMgrCreateNodeEPNS0_7VMemMgrEmm31895
_ZN4PLMD6asmjitL17vMemMgrInsertNodeEPNS0_7VMemMgrEPNS1_7MemNodeE31895
_ZN4PLMD6asmjitL20vMemMgrAllocFreeableEPNS0_7VMemMgrEm31895
_ZN4PLMD6asmjit7VMemMgrC2Ev31925
_ZN4PLMD6asmjit7VMemMgrD2Ev31925
_ZN4PLMD6asmjitL12vMemMgrResetEPNS0_7VMemMgrEb31925
_ZN4PLMD6asmjitL8_SetBitsEPmmm63790
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/vmem.cpp.func.html b/coverage-libs/asmjit/vmem.cpp.func.html new file mode 100644 index 000000000000..addca4ccf8d1 --- /dev/null +++ b/coverage-libs/asmjit/vmem.cpp.func.html @@ -0,0 +1,129 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/vmem.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - vmem.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:9731830.5 %
Date:2024-04-19 12:12:36Functions:81457.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit7VMemMgr5allocEmj31895
_ZN4PLMD6asmjit7VMemMgr5resetEv0
_ZN4PLMD6asmjit7VMemMgr6shrinkEPvm0
_ZN4PLMD6asmjit7VMemMgr7releaseEPv0
_ZN4PLMD6asmjit7VMemMgrC2Ev31925
_ZN4PLMD6asmjit7VMemMgrD2Ev31925
_ZN4PLMD6asmjitL12vMemMgrResetEPNS0_7VMemMgrEb31925
_ZN4PLMD6asmjitL17vMemMgrCreateNodeEPNS0_7VMemMgrEmm31895
_ZN4PLMD6asmjitL17vMemMgrInsertNodeEPNS0_7VMemMgrEPNS1_7MemNodeE31895
_ZN4PLMD6asmjitL17vMemMgrRemoveNodeEPNS0_7VMemMgrEPNS1_7MemNodeE0
_ZN4PLMD6asmjitL20vMemMgrAllocFreeableEPNS0_7VMemMgrEm31895
_ZN4PLMD6asmjitL20vMemMgrFindNodeByPtrEPNS0_7VMemMgrEPh0
_ZN4PLMD6asmjitL21vMemMgrAllocPermanentEPNS0_7VMemMgrEm0
_ZN4PLMD6asmjitL8_SetBitsEPmmm63790
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/vmem.cpp.gcov.html b/coverage-libs/asmjit/vmem.cpp.gcov.html new file mode 100644 index 000000000000..41286366da17 --- /dev/null +++ b/coverage-libs/asmjit/vmem.cpp.gcov.html @@ -0,0 +1,1180 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/vmem.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - vmem.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:9731830.5 %
Date:2024-04-19 12:12:36Functions: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       63790 : static void _SetBits(size_t* buf, size_t index, size_t len) noexcept {
+      94       63790 :   if (len == 0)
+      95             :     return;
+      96             : 
+      97       41833 :   size_t i = index / kBitsPerEntity; // size_t[]
+      98       41833 :   size_t j = index % kBitsPerEntity; // size_t[][] bit index
+      99             : 
+     100             :   // How many bytes process in the first group.
+     101       41833 :   size_t c = kBitsPerEntity - j;
+     102             :   if (c > len)
+     103             :     c = len;
+     104             : 
+     105             :   // Offset.
+     106       41833 :   buf += i;
+     107             : 
+     108       41833 :   *buf++ |= ((~(size_t)0) >> (kBitsPerEntity - c)) << j;
+     109       41833 :   len -= c;
+     110             : 
+     111       41833 :   while (len >= kBitsPerEntity) {
+     112           0 :     *buf++ = ~(size_t)0;
+     113           0 :     len -= kBitsPerEntity;
+     114             :   }
+     115             : 
+     116       41833 :   if (len)
+     117         112 :     *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       31895 :   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       31895 : 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       31895 :   if (!vmem) return nullptr;
+     297             : 
+     298       31895 :   size_t blocks = (vSize / density);
+     299       31895 :   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       31895 :   uint8_t* data = static_cast<uint8_t*>(Internal::allocMemory(bsize * 2));
+     303             : 
+     304             :   // Out of memory.
+     305       31895 :   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       31895 :   node->node[0] = nullptr;
+     314       31895 :   node->node[1] = nullptr;
+     315       31895 :   node->mem = vmem;
+     316       31895 :   node->red = 1;
+     317             : 
+     318             :   // Initialize MemNode data.
+     319       31895 :   node->prev = nullptr;
+     320       31895 :   node->next = nullptr;
+     321             : 
+     322       31895 :   node->size = vSize;
+     323       31895 :   node->used = 0;
+     324       31895 :   node->blocks = blocks;
+     325       31895 :   node->density = density;
+     326       31895 :   node->largestBlock = vSize;
+     327             : 
+     328             :   ::memset(data, 0, bsize * 2);
+     329       31895 :   node->baUsed = reinterpret_cast<size_t*>(data);
+     330       31895 :   node->baCont = reinterpret_cast<size_t*>(data + bsize);
+     331             : 
+     332       31895 :   return node;
+     333             : }
+     334             : 
+     335       31895 : static void vMemMgrInsertNode(VMemMgr* self, MemNode* node) noexcept {
+     336       31895 :   if (!self->_root) {
+     337             :     // Empty tree case.
+     338       31895 :     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       31895 :   self->_root->red = 0;
+     396             : 
+     397             :   // Link with others.
+     398       31895 :   node->prev = self->_last;
+     399             : 
+     400       31895 :   if (!self->_first) {
+     401       31895 :     self->_first = node;
+     402       31895 :     self->_last = node;
+     403       31895 :     self->_optimal = node;
+     404             :   }
+     405             :   else {
+     406             :     node->prev = self->_last;
+     407           0 :     self->_last->next = node;
+     408           0 :     self->_last = node;
+     409             :   }
+     410       31895 : }
+     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       31895 : 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       31895 :   if (vSize == 0)
+     595             :     return nullptr;
+     596             : 
+     597             :   AutoLock locked(self->_lock);
+     598       31895 :   MemNode* node = self->_optimal;
+     599       31895 :   minVSize = self->_blockSize;
+     600             : 
+     601             :   // Try to find memory block in existing nodes.
+     602       31895 :   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       31895 :     size_t blockSize = self->_blockSize;
+     673             :     if (blockSize < vSize) blockSize = vSize;
+     674             : 
+     675       31895 :     node = vMemMgrCreateNode(self, blockSize, self->_blockDensity);
+     676       31895 :     if (!node) return nullptr;
+     677             : 
+     678             :     // Update binary tree.
+     679       31895 :     vMemMgrInsertNode(self, node);
+     680             :     ASMJIT_ASSERT(vMemMgrCheckTree(self));
+     681             : 
+     682             :     // Alloc first node at start.
+     683             :     i = 0;
+     684       31895 :     need = (vSize + node->density - 1) / node->density;
+     685             : 
+     686             :     // Update statistics.
+     687       31895 :     self->_allocatedBytes += node->size;
+     688             :   }
+     689             : 
+     690       31895 : L_Found:
+     691             :   // Update bits.
+     692       31895 :   _SetBits(node->baUsed, i, need);
+     693       31895 :   _SetBits(node->baCont, i, need - 1);
+     694             : 
+     695             :   // Update statistics.
+     696             :   {
+     697       31895 :     size_t u = need * node->density;
+     698       31895 :     node->used += u;
+     699       31895 :     node->largestBlock = 0;
+     700       31895 :     self->_usedBytes += u;
+     701             :   }
+     702             : 
+     703             :   // And return pointer to allocated memory.
+     704       31895 :   uint8_t* result = node->mem + i * node->density;
+     705             :   ASMJIT_ASSERT(result >= node->mem && result <= node->mem + node->size - vSize);
+     706       31895 :   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       31925 : static void vMemMgrReset(VMemMgr* self, bool keepVirtualMemory) noexcept {
+     715       31925 :   MemNode* node = self->_first;
+     716             : 
+     717       63820 :   while (node) {
+     718       31895 :     MemNode* next = node->next;
+     719             : 
+     720       31895 :     if (!keepVirtualMemory)
+     721       31895 :       vMemMgrReleaseVMem(self, node->mem, node->size);
+     722             : 
+     723       31895 :     Internal::releaseMemory(node->baUsed);
+     724             :     Internal::releaseMemory(node);
+     725             : 
+     726             :     node = next;
+     727             :   }
+     728             : 
+     729       31925 :   self->_allocatedBytes = 0;
+     730       31925 :   self->_usedBytes = 0;
+     731             : 
+     732       31925 :   self->_root = nullptr;
+     733       31925 :   self->_first = nullptr;
+     734       31925 :   self->_last = nullptr;
+     735       31925 :   self->_optimal = nullptr;
+     736       31925 : }
+     737             : 
+     738             : // ============================================================================
+     739             : // [asmjit::VMemMgr - Construction / Destruction]
+     740             : // ============================================================================
+     741             : 
+     742             : #if !ASMJIT_OS_WINDOWS
+     743       31925 : VMemMgr::VMemMgr() noexcept {
+     744             : #else
+     745             : VMemMgr::VMemMgr(HANDLE hProcess) noexcept {
+     746             : #endif
+     747             : 
+     748       31925 :   VMemInfo vm = OSUtils::getVirtualMemoryInfo();
+     749             : 
+     750             : #if ASMJIT_OS_WINDOWS
+     751             :   _hProcess = hProcess ? hProcess : vm.hCurrentProcess;
+     752             : #endif // ASMJIT_OS_WINDOWS
+     753             : 
+     754       31925 :   _blockSize = vm.pageGranularity;
+     755       31925 :   _blockDensity = 64;
+     756             : 
+     757       31925 :   _allocatedBytes = 0;
+     758       31925 :   _usedBytes = 0;
+     759             : 
+     760       31925 :   _root = nullptr;
+     761       31925 :   _first = nullptr;
+     762       31925 :   _last = nullptr;
+     763       31925 :   _optimal = nullptr;
+     764             : 
+     765       31925 :   _permanent = nullptr;
+     766       31925 :   _keepVirtualMemory = false;
+     767       31925 : }
+     768             : 
+     769       31925 : VMemMgr::~VMemMgr() noexcept {
+     770             :   // Freeable memory cleanup - Also frees the virtual memory if configured to.
+     771       31925 :   vMemMgrReset(this, _keepVirtualMemory);
+     772             : 
+     773             :   // Permanent memory cleanup - Never frees the virtual memory.
+     774       31925 :   PermanentNode* node = _permanent;
+     775       31925 :   while (node) {
+     776           0 :     PermanentNode* prev = node->prev;
+     777             :     Internal::releaseMemory(node);
+     778             :     node = prev;
+     779             :   }
+     780       31925 : }
+     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       31895 : void* VMemMgr::alloc(size_t size, uint32_t type) noexcept {
+     795       31895 :   if (type == kAllocPermanent)
+     796           0 :     return vMemMgrAllocPermanent(this, size);
+     797             :   else
+     798       31895 :     return vMemMgrAllocFreeable(this, size);
+     799             : }
+     800             : 
+     801           0 : Error VMemMgr::release(void* p) noexcept {
+     802           0 :   if (!p) return kErrorOk;
+     803             : 
+     804             :   AutoLock locked(_lock);
+     805           0 :   MemNode* node = vMemMgrFindNodeByPtr(this, static_cast<uint8_t*>(p));
+     806           0 :   if (!node) return DebugUtils::errored(kErrorInvalidArgument);
+     807             : 
+     808           0 :   size_t offset = (size_t)((uint8_t*)p - (uint8_t*)node->mem);
+     809           0 :   size_t bitpos = M_DIV(offset, node->density);
+     810           0 :   size_t i = (bitpos / kBitsPerEntity);
+     811             : 
+     812           0 :   size_t* up = node->baUsed + i;  // Current ubits address.
+     813           0 :   size_t* cp = node->baCont + i;  // Current cbits address.
+     814           0 :   size_t ubits = *up;             // Current ubits[0] value.
+     815           0 :   size_t cbits = *cp;             // Current cbits[0] value.
+     816           0 :   size_t bit = (size_t)1 << (bitpos % kBitsPerEntity);
+     817             : 
+     818             :   size_t cont = 0;
+     819             :   bool stop;
+     820             : 
+     821             :   for (;;) {
+     822           0 :     stop = (cbits & bit) == 0;
+     823           0 :     ubits &= ~bit;
+     824           0 :     cbits &= ~bit;
+     825             : 
+     826           0 :     bit <<= 1;
+     827           0 :     cont++;
+     828             : 
+     829           0 :     if (stop || bit == 0) {
+     830           0 :       *up = ubits;
+     831           0 :       *cp = cbits;
+     832           0 :       if (stop)
+     833             :         break;
+     834             : 
+     835           0 :       ubits = *++up;
+     836           0 :       cbits = *++cp;
+     837             :       bit = 1;
+     838             :     }
+     839             :   }
+     840             : 
+     841             :   // If the freed block is fully allocated node then it's needed to
+     842             :   // update 'optimal' pointer in memory manager.
+     843           0 :   if (node->used == node->size) {
+     844           0 :     MemNode* cur = _optimal;
+     845             : 
+     846             :     do {
+     847           0 :       cur = cur->prev;
+     848           0 :       if (cur == node) {
+     849           0 :         _optimal = node;
+     850           0 :         break;
+     851             :       }
+     852           0 :     } while (cur);
+     853             :   }
+     854             : 
+     855             :   // Statistics.
+     856           0 :   cont *= node->density;
+     857           0 :   if (node->largestBlock < cont)
+     858           0 :     node->largestBlock = cont;
+     859             : 
+     860           0 :   node->used -= cont;
+     861           0 :   _usedBytes -= cont;
+     862             : 
+     863             :   // If page is empty, we can free it.
+     864           0 :   if (node->used == 0) {
+     865             :     // Free memory associated with node (this memory is not accessed
+     866             :     // anymore so it's safe).
+     867           0 :     vMemMgrReleaseVMem(this, node->mem, node->size);
+     868           0 :     Internal::releaseMemory(node->baUsed);
+     869             : 
+     870           0 :     node->baUsed = nullptr;
+     871           0 :     node->baCont = nullptr;
+     872             : 
+     873             :     // Statistics.
+     874           0 :     _allocatedBytes -= node->size;
+     875             : 
+     876             :     // Remove node. This function can return different node than
+     877             :     // passed into, but data is copied into previous node if needed.
+     878           0 :     Internal::releaseMemory(vMemMgrRemoveNode(this, node));
+     879             :     ASMJIT_ASSERT(vMemMgrCheckTree(this));
+     880             :   }
+     881             : 
+     882             :   return kErrorOk;
+     883             : }
+     884             : 
+     885           0 : Error VMemMgr::shrink(void* p, size_t used) noexcept {
+     886           0 :   if (!p) return kErrorOk;
+     887           0 :   if (used == 0)
+     888           0 :     return release(p);
+     889             : 
+     890             :   AutoLock locked(_lock);
+     891           0 :   MemNode* node = vMemMgrFindNodeByPtr(this, (uint8_t*)p);
+     892           0 :   if (!node) return DebugUtils::errored(kErrorInvalidArgument);
+     893             : 
+     894           0 :   size_t offset = (size_t)((uint8_t*)p - (uint8_t*)node->mem);
+     895           0 :   size_t bitpos = M_DIV(offset, node->density);
+     896           0 :   size_t i = (bitpos / kBitsPerEntity);
+     897             : 
+     898           0 :   size_t* up = node->baUsed + i;  // Current ubits address.
+     899           0 :   size_t* cp = node->baCont + i;  // Current cbits address.
+     900           0 :   size_t ubits = *up;             // Current ubits[0] value.
+     901           0 :   size_t cbits = *cp;             // Current cbits[0] value.
+     902           0 :   size_t bit = (size_t)1 << (bitpos % kBitsPerEntity);
+     903             : 
+     904             :   size_t cont = 0;
+     905           0 :   size_t usedBlocks = (used + node->density - 1) / node->density;
+     906             : 
+     907             :   bool stop;
+     908             : 
+     909             :   // Find the first block we can mark as free.
+     910             :   for (;;) {
+     911           0 :     stop = (cbits & bit) == 0;
+     912           0 :     if (stop)
+     913             :       return kErrorOk;
+     914             : 
+     915           0 :     if (++cont == usedBlocks)
+     916             :       break;
+     917             : 
+     918           0 :     bit <<= 1;
+     919           0 :     if (bit == 0) {
+     920           0 :       ubits = *++up;
+     921           0 :       cbits = *++cp;
+     922             :       bit = 1;
+     923             :     }
+     924             :   }
+     925             : 
+     926             :   // Free the tail blocks.
+     927             :   cont = ~(size_t)0;
+     928           0 :   goto _EnterFreeLoop;
+     929             : 
+     930             :   for (;;) {
+     931           0 :     stop = (cbits & bit) == 0;
+     932           0 :     ubits &= ~bit;
+     933             : 
+     934           0 : _EnterFreeLoop:
+     935           0 :     cbits &= ~bit;
+     936             : 
+     937           0 :     bit <<= 1;
+     938           0 :     cont++;
+     939             : 
+     940           0 :     if (stop || bit == 0) {
+     941           0 :       *up = ubits;
+     942           0 :       *cp = cbits;
+     943           0 :       if (stop)
+     944             :         break;
+     945             : 
+     946           0 :       ubits = *++up;
+     947           0 :       cbits = *++cp;
+     948             :       bit = 1;
+     949             :     }
+     950             :   }
+     951             : 
+     952             :   // Statistics.
+     953           0 :   cont *= node->density;
+     954           0 :   if (node->largestBlock < cont)
+     955           0 :     node->largestBlock = cont;
+     956             : 
+     957           0 :   node->used -= cont;
+     958           0 :   _usedBytes -= cont;
+     959             : 
+     960           0 :   return kErrorOk;
+     961             : }
+     962             : 
+     963             : // ============================================================================
+     964             : // [asmjit::VMem - Test]
+     965             : // ============================================================================
+     966             : 
+     967             : #if defined(ASMJIT_TEST)
+     968             : static void VMemTest_fill(void* a, void* b, int i) noexcept {
+     969             :   int pattern = rand() % 256;
+     970             :   *(int *)a = i;
+     971             :   *(int *)b = i;
+     972             :   ::memset((char*)a + sizeof(int), pattern, i - sizeof(int));
+     973             :   ::memset((char*)b + sizeof(int), pattern, i - sizeof(int));
+     974             : }
+     975             : 
+     976             : static void VMemTest_verify(void* a, void* b) noexcept {
+     977             :   int ai = *(int*)a;
+     978             :   int bi = *(int*)b;
+     979             : 
+     980             :   EXPECT(ai == bi,
+     981             :     "The length of 'a' (%d) and 'b' (%d) should be same", ai, bi);
+     982             : 
+     983             :   EXPECT(::memcmp(a, b, ai) == 0,
+     984             :     "Pattern (%p) doesn't match", a);
+     985             : }
+     986             : 
+     987             : static void VMemTest_stats(VMemMgr& memmgr) noexcept {
+     988             :   INFO("Used     : %u", static_cast<unsigned int>(memmgr.getUsedBytes()));
+     989             :   INFO("Allocated: %u", static_cast<unsigned int>(memmgr.getAllocatedBytes()));
+     990             : }
+     991             : 
+     992             : static void VMemTest_shuffle(void** a, void** b, size_t count) noexcept {
+     993             :   for (size_t i = 0; i < count; ++i) {
+     994             :     size_t si = (size_t)rand() % count;
+     995             : 
+     996             :     void* ta = a[i];
+     997             :     void* tb = b[i];
+     998             : 
+     999             :     a[i] = a[si];
+    1000             :     b[i] = b[si];
+    1001             : 
+    1002             :     a[si] = ta;
+    1003             :     b[si] = tb;
+    1004             :   }
+    1005             : }
+    1006             : 
+    1007             : UNIT(base_vmem) {
+    1008             :   VMemMgr memmgr;
+    1009             : 
+    1010             :   // Should be predictible.
+    1011             :   srand(100);
+    1012             : 
+    1013             :   int i;
+    1014             :   int kCount = 200000;
+    1015             : 
+    1016             :   INFO("Memory alloc/free test - %d allocations", static_cast<int>(kCount));
+    1017             : 
+    1018             :   void** a = (void**)Internal::allocMemory(sizeof(void*) * kCount);
+    1019             :   void** b = (void**)Internal::allocMemory(sizeof(void*) * kCount);
+    1020             : 
+    1021             :   EXPECT(a != nullptr && b != nullptr,
+    1022             :     "Couldn't allocate %u bytes on heap", kCount * 2);
+    1023             : 
+    1024             :   INFO("Allocating virtual memory...");
+    1025             :   for (i = 0; i < kCount; i++) {
+    1026             :     int r = (rand() % 1000) + 4;
+    1027             : 
+    1028             :     a[i] = memmgr.alloc(r);
+    1029             :     EXPECT(a[i] != nullptr,
+    1030             :       "Couldn't allocate %d bytes of virtual memory", r);
+    1031             :     ::memset(a[i], 0, r);
+    1032             :   }
+    1033             :   VMemTest_stats(memmgr);
+    1034             : 
+    1035             :   INFO("Freeing virtual memory...");
+    1036             :   for (i = 0; i < kCount; i++) {
+    1037             :     EXPECT(memmgr.release(a[i]) == kErrorOk,
+    1038             :       "Failed to free %p", b[i]);
+    1039             :   }
+    1040             :   VMemTest_stats(memmgr);
+    1041             : 
+    1042             :   INFO("Verified alloc/free test - %d allocations", static_cast<int>(kCount));
+    1043             :   for (i = 0; i < kCount; i++) {
+    1044             :     int r = (rand() % 1000) + 4;
+    1045             : 
+    1046             :     a[i] = memmgr.alloc(r);
+    1047             :     EXPECT(a[i] != nullptr,
+    1048             :       "Couldn't allocate %d bytes of virtual memory", r);
+    1049             : 
+    1050             :     b[i] = Internal::allocMemory(r);
+    1051             :     EXPECT(b[i] != nullptr,
+    1052             :       "Couldn't allocate %d bytes on heap", r);
+    1053             : 
+    1054             :     VMemTest_fill(a[i], b[i], r);
+    1055             :   }
+    1056             :   VMemTest_stats(memmgr);
+    1057             : 
+    1058             :   INFO("Shuffling...");
+    1059             :   VMemTest_shuffle(a, b, kCount);
+    1060             : 
+    1061             :   INFO("Verify and free...");
+    1062             :   for (i = 0; i < kCount / 2; i++) {
+    1063             :     VMemTest_verify(a[i], b[i]);
+    1064             :     EXPECT(memmgr.release(a[i]) == kErrorOk,
+    1065             :       "Failed to free %p", a[i]);
+    1066             :     Internal::releaseMemory(b[i]);
+    1067             :   }
+    1068             :   VMemTest_stats(memmgr);
+    1069             : 
+    1070             :   INFO("Alloc again");
+    1071             :   for (i = 0; i < kCount / 2; i++) {
+    1072             :     int r = (rand() % 1000) + 4;
+    1073             : 
+    1074             :     a[i] = memmgr.alloc(r);
+    1075             :     EXPECT(a[i] != nullptr,
+    1076             :       "Couldn't allocate %d bytes of virtual memory", r);
+    1077             : 
+    1078             :     b[i] = Internal::allocMemory(r);
+    1079             :     EXPECT(b[i] != nullptr,
+    1080             :       "Couldn't allocate %d bytes on heap");
+    1081             : 
+    1082             :     VMemTest_fill(a[i], b[i], r);
+    1083             :   }
+    1084             :   VMemTest_stats(memmgr);
+    1085             : 
+    1086             :   INFO("Verify and free...");
+    1087             :   for (i = 0; i < kCount; i++) {
+    1088             :     VMemTest_verify(a[i], b[i]);
+    1089             :     EXPECT(memmgr.release(a[i]) == kErrorOk,
+    1090             :       "Failed to free %p", a[i]);
+    1091             :     Internal::releaseMemory(b[i]);
+    1092             :   }
+    1093             :   VMemTest_stats(memmgr);
+    1094             : 
+    1095             :   Internal::releaseMemory(a);
+    1096             :   Internal::releaseMemory(b);
+    1097             : }
+    1098             : #endif // ASMJIT_TEST
+    1099             : 
+    1100             : } // asmjit namespace
+    1101             : } // namespace PLMD
+    1102             : #pragma GCC diagnostic pop
+    1103             : #endif // __PLUMED_HAS_ASMJIT
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86assembler.cpp.func-sort-c.html b/coverage-libs/asmjit/x86assembler.cpp.func-sort-c.html new file mode 100644 index 000000000000..171546898d25 --- /dev/null +++ b/coverage-libs/asmjit/x86assembler.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86assembler.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86assembler.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:186170510.9 %
Date:2024-04-19 12:12:36Functions:4757.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit12X86Assembler5alignEjj0
_ZN4PLMD6asmjit12X86Assembler8onDetachEPNS0_10CodeHolderE0
_ZN4PLMD6asmjit12X86AssemblerD0Ev0
_ZN4PLMD6asmjit12X86Assembler8onAttachEPNS0_10CodeHolderE31895
_ZN4PLMD6asmjit12X86AssemblerC2EPNS0_10CodeHolderE31895
_ZN4PLMD6asmjit12X86AssemblerD2Ev31895
_ZN4PLMD6asmjit12X86Assembler5_emitEjRKNS0_8Operand_ES4_S4_S4_587564
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86assembler.cpp.func.html b/coverage-libs/asmjit/x86assembler.cpp.func.html new file mode 100644 index 000000000000..ef1197dc6a88 --- /dev/null +++ b/coverage-libs/asmjit/x86assembler.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86assembler.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86assembler.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:186170510.9 %
Date:2024-04-19 12:12:36Functions:4757.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit12X86Assembler5_emitEjRKNS0_8Operand_ES4_S4_S4_587564
_ZN4PLMD6asmjit12X86Assembler5alignEjj0
_ZN4PLMD6asmjit12X86Assembler8onAttachEPNS0_10CodeHolderE31895
_ZN4PLMD6asmjit12X86Assembler8onDetachEPNS0_10CodeHolderE0
_ZN4PLMD6asmjit12X86AssemblerC2EPNS0_10CodeHolderE31895
_ZN4PLMD6asmjit12X86AssemblerD0Ev0
_ZN4PLMD6asmjit12X86AssemblerD2Ev31895
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86assembler.cpp.gcov.html b/coverage-libs/asmjit/x86assembler.cpp.gcov.html new file mode 100644 index 000000000000..d5c5115a9b92 --- /dev/null +++ b/coverage-libs/asmjit/x86assembler.cpp.gcov.html @@ -0,0 +1,4722 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86assembler.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86assembler.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:186170510.9 %
Date:2024-04-19 12:12:36Functions: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      587564 :   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      587564 :   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       31895 : X86Assembler::X86Assembler(CodeHolder* code) noexcept : Assembler() {
+     382       31895 :   if (code)
+     383       31895 :     code->attach(this);
+     384       31895 : }
+     385       31895 : X86Assembler::~X86Assembler() noexcept {}
+     386             : 
+     387             : // ============================================================================
+     388             : // [asmjit::X86Assembler - Events]
+     389             : // ============================================================================
+     390             : 
+     391       31895 : Error X86Assembler::onAttach(CodeHolder* code) noexcept {
+     392             :   uint32_t archType = code->getArchType();
+     393       31895 :   if (!ArchInfo::isX86Family(archType))
+     394             :     return DebugUtils::errored(kErrorInvalidArch);
+     395             : 
+     396       31895 :   ASMJIT_PROPAGATE(Base::onAttach(code));
+     397             : 
+     398       31895 :   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       31895 :     _nativeGpArray = x86OpData.gpq;
+     408             :   }
+     409             : 
+     410       31895 :   _nativeGpReg = _nativeGpArray[0];
+     411       31895 :   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      587564 : 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      587564 :   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      587564 :   uint8_t* cursor = _bufferPtr;
+     550      587564 :   uint32_t options = static_cast<uint32_t>(instId >= X86Inst::_kIdCount)       |
+     551      587564 :                      static_cast<uint32_t>((size_t)(_bufferEnd - cursor) < 16) |
+     552      587564 :                      getGlobalOptions() | getOptions();
+     553             : 
+     554      587564 :   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      587564 :   uint32_t isign3 = o0.getOp() + (o1.getOp() << 3) + (o2.getOp() << 6);
+     569             : 
+     570      587564 :   if (ASMJIT_UNLIKELY(options & kErrorsAndSpecialCases)) {
+     571             :     // Don't do anything if we are in error state.
+     572       31895 :     if (_lastError) return _lastError;
+     573             : 
+     574       31895 :     if (options & CodeEmitter::kOptionMaybeFailureCase) {
+     575             :       // Unknown instruction.
+     576       31895 :       if (ASMJIT_UNLIKELY(instId >= X86Inst::_kIdCount))
+     577           0 :         goto InvalidArgument;
+     578             : 
+     579             :       // Grow request, happens rarely.
+     580       31895 :       if ((size_t)(_bufferEnd - cursor) < 16) {
+     581       31895 :         err = _code->growBuffer(&_section->_buffer, 16);
+     582       31895 :         if (ASMJIT_UNLIKELY(err)) goto Failed;
+     583             : 
+     584       31895 :         cursor = _bufferPtr;
+     585       31895 :         options &= ~1;
+     586             :       }
+     587             :     }
+     588             : 
+     589             :     // Strict validation.
+     590             : #if !defined(ASMJIT_DISABLE_VALIDATION)
+     591       31895 :     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       31895 :     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       31895 :     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      587564 :   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        9176 :     case X86Inst::kEncodingX86Arith:
+     877        9176 :       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        9176 :       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        9176 :       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        9176 :       if (isign3 == ENC_OPS2(Reg, Imm)) {
+     944        9176 :         uint32_t size = o0.getSize();
+     945             : 
+     946             :         rbReg = o0.getId();
+     947             :         imVal = static_cast<const Imm&>(o1).getInt64();
+     948             : 
+     949        9176 :         if (size == 1) {
+     950           0 :           FIXUP_GPB(o0, rbReg);
+     951             :           imLen = 1;
+     952             :         }
+     953             :         else {
+     954        9176 :           if (size == 2) {
+     955             :             ADD_66H_P(1);
+     956             :           }
+     957        9176 :           else if (size == 4) {
+     958             :             // Sign extend so isInt8 returns the right result.
+     959             :             imVal = x86SignExtend32To64(imVal);
+     960             :           }
+     961        9176 :           else if (size == 8) {
+     962             :             // In 64-bit mode it's not possible to use 64-bit immediate.
+     963        9176 :             if (Utils::isUInt32(imVal)) {
+     964             :               // Zero-extend `and` by using a 32-bit GPD destination instead of a 64-bit GPQ.
+     965        9176 :               if (instId == X86Inst::kIdAnd)
+     966           0 :                 size = 4;
+     967        9176 :               else if (!Utils::isInt32(imVal))
+     968           0 :                 goto InvalidImmediate;
+     969             :             }
+     970        9176 :             ADD_REX_W_BY_SIZE(size);
+     971             :           }
+     972             : 
+     973       18352 :           imLen = std::min<uint32_t>(size, 4);
+     974        9176 :           if (Utils::isInt8(imVal) && !(options & X86Inst::kOptionLongForm))
+     975             :             imLen = 1;
+     976             :         }
+     977             : 
+     978             :         // Alternate Form - AL, AX, EAX, RAX.
+     979        9176 :         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        9176 :         opCode += size != 1 ? (imLen != 1 ? 1 : 3) : 0;
+     987        9176 :         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       12914 :     case X86Inst::kEncodingX86Call:
+    1063       12914 :       if (isign3 == ENC_OPS1(Reg)) {
+    1064             :         rbReg = o0.getId();
+    1065       12914 :         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      105474 :     case X86Inst::kEncodingX86Mov:
+    1399             :       // Reg <- Reg
+    1400      105474 :       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      105474 :       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      105474 :       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      105474 :       if (isign3 == ENC_OPS2(Reg, Imm)) {
+    1587             :         opReg = o0.getId();
+    1588      105474 :         imLen = o0.getSize();
+    1589             : 
+    1590      105474 :         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      105474 :           if (imLen == 8 && !(options & X86Inst::kOptionLongForm)) {
+    1603      105474 :             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      105474 :             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      105474 :           ADD_PREFIX_BY_SIZE(imLen);
+    1621      105474 :           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        7024 :     case X86Inst::kEncodingX86Push:
+    1710        7024 :       if (isign3 == ENC_OPS1(Reg)) {
+    1711        7024 :         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        7024 :           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        7024 :       if (isign3 == ENC_OPS1(Reg)) {
+    1741        7024 :         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       14048 : 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       14048 :           if (ASMJIT_UNLIKELY(o0.getSize() < 2))
+    1758           0 :             goto InvalidInstruction;
+    1759             : 
+    1760             :           opCode = commonData->getAltOpCode();
+    1761             :           opReg = o0.getId();
+    1762             : 
+    1763       14048 :           ADD_66H_P_BY_SIZE(o0.getSize());
+    1764       14048 :           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       31895 :     case X86Inst::kEncodingX86Ret:
+    1782       31895 :       if (isign3 == 0) {
+    1783             :         // 'ret' without immediate, change C2 to C3.
+    1784       31895 :         opCode++;
+    1785       31895 :         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      295712 :     case X86Inst::kEncodingExtMov:
+    2349             :       // GP|MMX|XMM <- GP|MMX|XMM
+    2350      295712 :       if (isign3 == ENC_OPS2(Reg, Reg)) {
+    2351             :         opReg = o0.getId();
+    2352             :         rbReg = o1.getId();
+    2353             : 
+    2354      121439 :         if (!(options & X86Inst::kOptionModMR) || !commonData->hasAltOpCode())
+    2355      121439 :           goto EmitX86R;
+    2356             : 
+    2357             :         opCode = commonData->getAltOpCode();
+    2358             :         Utils::swap(opReg, rbReg);
+    2359           0 :         goto EmitX86R;
+    2360             :       }
+    2361             : 
+    2362             :       // GP|MMX|XMM <- Mem
+    2363      174273 :       if (isign3 == ENC_OPS2(Reg, Mem)) {
+    2364             :         opReg = o0.getId();
+    2365             :         rmRel = &o1;
+    2366      134347 :         goto EmitX86M;
+    2367             :       }
+    2368             : 
+    2369             :       // The following instruction uses opCode[1].
+    2370             :       opCode = commonData->getAltOpCode();
+    2371             : 
+    2372             :       // Mem <- GP|MMX|XMM
+    2373       39926 :       if (isign3 == ENC_OPS2(Mem, Reg)) {
+    2374             :         opReg = o1.getId();
+    2375             :         rmRel = &o0;
+    2376       39926 :         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      116075 : CaseExtRm:
+    2551      116075 :       if (isign3 == ENC_OPS2(Reg, Reg)) {
+    2552             :         opReg = o0.getId();
+    2553             :         rbReg = o1.getId();
+    2554      116075 :         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        2270 :       if (isign3 == ENC_OPS3(Reg, Reg, Imm)) {
+    2645             :         opReg = o0.getId();
+    2646             :         rbReg = o1.getId();
+    2647        2270 :         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       31895 :   EMIT_PP(opCode);
+    3575             : 
+    3576             :   // Emit REX prefix (64-bit only).
+    3577             :   {
+    3578             :     uint32_t rex = x86ExtractREX(opCode, options);
+    3579       31895 :     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       31895 :   EMIT_MM_OP(opCode);
+    3588             : 
+    3589       31895 :   if (imLen != 0)
+    3590           0 :     goto EmitImm;
+    3591             :   else
+    3592       31895 :     goto EmitDone;
+    3593             : 
+    3594      119522 : EmitX86OpReg:
+    3595             :   // Emit mandatory instruction prefix.
+    3596      119522 :   EMIT_PP(opCode);
+    3597             : 
+    3598             :   // Emit REX prefix (64-bit only).
+    3599             :   {
+    3600             :     uint32_t rex = x86ExtractREX(opCode, options) |
+    3601      119522 :                    (opReg >> 3); // Rex.B (0x01).
+    3602      119522 :     if (rex) {
+    3603      105474 :       EMIT_BYTE(rex | kX86ByteRex);
+    3604      105474 :       if (options & X86Inst::_kOptionInvalidRex)
+    3605           0 :         goto InvalidRexPrefix;
+    3606      105474 :       opReg &= 0x7;
+    3607             :     }
+    3608             :   }
+    3609             : 
+    3610             :   // Emit instruction opcodes.
+    3611      119522 :   opCode += opReg;
+    3612      119522 :   EMIT_MM_OP(opCode);
+    3613             : 
+    3614      119522 :   if (imLen != 0)
+    3615      105474 :     goto EmitImm;
+    3616             :   else
+    3617       14048 :     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      261874 : EmitX86R:
+    3655             :   // Mandatory instruction prefix.
+    3656      261874 :   EMIT_PP(opCode);
+    3657             : 
+    3658             :   // Rex prefix (64-bit only).
+    3659             :   {
+    3660      261874 :     uint32_t rex = x86ExtractREX(opCode, options) |
+    3661      261874 :                    ((opReg & 0x08) >> 1) | // REX.R (0x04).
+    3662      261874 :                    ((rbReg       ) >> 3) ; // REX.B (0x01).
+    3663      261874 :     if (rex) {
+    3664       23934 :       if (options & X86Inst::_kOptionInvalidRex)
+    3665           0 :         goto InvalidRexPrefix;
+    3666       23934 :       EMIT_BYTE(rex | kX86ByteRex);
+    3667       23934 :       opReg &= 0x07;
+    3668       23934 :       rbReg &= 0x07;
+    3669             :     }
+    3670             :   }
+    3671             : 
+    3672             :   // Instruction opcodes.
+    3673      261874 :   EMIT_MM_OP(opCode);
+    3674             :   // ModR.
+    3675      261874 :   EMIT_BYTE(x86EncodeMod(3, opReg, rbReg));
+    3676             : 
+    3677      261874 :   if (imLen != 0)
+    3678       11446 :     goto EmitImm;
+    3679             :   else
+    3680      250428 :     goto EmitDone;
+    3681             : 
+    3682      174273 : EmitX86M:
+    3683             :   ASMJIT_ASSERT(rmRel != nullptr);
+    3684             :   ASMJIT_ASSERT(rmRel->getOp() == Operand::kOpMem);
+    3685      174273 :   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      174273 :   if (rmRel->as<X86Mem>().hasSegment())
+    3692           0 :     EMIT_BYTE(x86SegmentPrefix[rmRel->as<X86Mem>().getSegmentId()]);
+    3693             : 
+    3694             :   // Address-override prefix.
+    3695      174273 :   if (rmInfo & _getAddressOverrideMask())
+    3696           0 :     EMIT_BYTE(0x67);
+    3697             : 
+    3698             :   // Mandatory instruction prefix.
+    3699      174273 :   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      174273 :     rex  = (rbReg >> 3) & 0x01; // REX.B (0x01).
+    3709      174273 :     rex |= (rxReg >> 2) & 0x02; // REX.X (0x02).
+    3710      174273 :     rex |= (opReg >> 1) & 0x04; // REX.R (0x04).
+    3711             : 
+    3712      174273 :     rex &= rmInfo;
+    3713      174273 :     rex |= x86ExtractREX(opCode, options);
+    3714             : 
+    3715      174273 :     if (rex) {
+    3716       15564 :       if (options & X86Inst::_kOptionInvalidRex)
+    3717           0 :         goto InvalidRexPrefix;
+    3718       15564 :       EMIT_BYTE(rex | kX86ByteRex);
+    3719       15564 :       opReg &= 0x07;
+    3720             :     }
+    3721             :   }
+    3722             : 
+    3723             :   // Instruction opcodes.
+    3724      174273 :   EMIT_MM_OP(opCode);
+    3725             :   // ... Fall through ...
+    3726             : 
+    3727             :   // --------------------------------------------------------------------------
+    3728             :   // [Emit - MOD/SIB]
+    3729             :   // --------------------------------------------------------------------------
+    3730             : 
+    3731      174273 : EmitModSib:
+    3732      174273 :   if (!(rmInfo & (kX86MemInfo_Index | kX86MemInfo_67H_X86))) {
+    3733             :     // ==========|> [BASE + DISP8|DISP32].
+    3734      174273 :     if (rmInfo & kX86MemInfo_BaseGp) {
+    3735      174273 :       rbReg &= 0x7;
+    3736             :       relOffset = rmRel->as<X86Mem>().getOffsetLo32();
+    3737             : 
+    3738             :       uint32_t mod = x86EncodeMod(0, opReg, rbReg);
+    3739      174273 :       if (rbReg == X86Gp::kIdSp) {
+    3740             :         // [XSP|R12].
+    3741       91108 :         if (relOffset == 0) {
+    3742        9176 :           EMIT_BYTE(mod);
+    3743        9176 :           EMIT_BYTE(x86EncodeSib(0, 4, 4));
+    3744             :         }
+    3745             :         // [XSP|R12 + DISP8|DISP32].
+    3746             :         else {
+    3747       81932 :           uint32_t cdShift = (opCode & X86Inst::kOpCode_CDSHL_Mask) >> X86Inst::kOpCode_CDSHL_Shift;
+    3748       81932 :           int32_t cdOffset = relOffset >> cdShift;
+    3749             : 
+    3750       81932 :           if (Utils::isInt8(cdOffset) && relOffset == (cdOffset << cdShift)) {
+    3751       36872 :             EMIT_BYTE(mod + 0x40); // <- MOD(1, opReg, rbReg).
+    3752       36872 :             EMIT_BYTE(x86EncodeSib(0, 4, 4));
+    3753       36872 :             EMIT_BYTE(cdOffset & 0xFF);
+    3754             :           }
+    3755             :           else {
+    3756       45060 :             EMIT_BYTE(mod + 0x80); // <- MOD(2, opReg, rbReg).
+    3757       45060 :             EMIT_BYTE(x86EncodeSib(0, 4, 4));
+    3758       45060 :             EMIT_32(relOffset);
+    3759             :           }
+    3760             :         }
+    3761             :       }
+    3762       83165 :       else if (rbReg != X86Gp::kIdBp && relOffset == 0) {
+    3763             :         // [BASE].
+    3764       60263 :         EMIT_BYTE(mod);
+    3765             :       }
+    3766             :       else {
+    3767             :         // [BASE + DISP8|DISP32].
+    3768       22902 :         uint32_t cdShift = (opCode & X86Inst::kOpCode_CDSHL_Mask) >> X86Inst::kOpCode_CDSHL_Shift;
+    3769       22902 :         int32_t cdOffset = relOffset >> cdShift;
+    3770             : 
+    3771       22902 :         if (Utils::isInt8(cdOffset) && relOffset == (cdOffset << cdShift)) {
+    3772       14726 :           EMIT_BYTE(mod + 0x40);
+    3773       14726 :           EMIT_BYTE(cdOffset & 0xFF);
+    3774             :         }
+    3775             :         else {
+    3776        8176 :           EMIT_BYTE(mod + 0x80);
+    3777        8176 :           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      174273 :   if (imLen != 0)
+    4013           0 :     goto EmitImm;
+    4014             :   else
+    4015      174273 :     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      116920 :     uint32_t i = imLen;
+    4476      116920 :     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      116920 :     EMIT_BYTE(imm & 0xFFU); if (--i == 0) goto EmitDone;
+    4484      106506 :     imm >>= 8;
+    4485      106506 :     EMIT_BYTE(imm & 0xFFU); if (--i == 0) goto EmitDone;
+    4486      106506 :     imm >>= 8;
+    4487      106506 :     EMIT_BYTE(imm & 0xFFU); if (--i == 0) goto EmitDone;
+    4488      106506 :     imm >>= 8;
+    4489      106506 :     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      105474 :     imm >>= 8;
+    4496      105474 :     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      587564 : EmitDone:
+    4507             : #if !defined(ASMJIT_DISABLE_LOGGING)
+    4508             :   // Logging is a performance hit anyway, so make it the unlikely case.
+    4509      587564 :   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      587564 :   _bufferPtr = cursor;
+    4518      587564 :   return kErrorOk;
+    4519             : 
+    4520             :   // --------------------------------------------------------------------------
+    4521             :   // [Error Cases]
+    4522             :   // --------------------------------------------------------------------------
+    4523             : 
+    4524             : #define ERROR_HANDLER(ERROR)                \
+    4525             : ERROR:                                      \
+    4526             :   err = DebugUtils::errored(kError##ERROR); \
+    4527             :   goto Failed;
+    4528             : 
+    4529           0 : ERROR_HANDLER(NoHeapMemory)
+    4530           0 : ERROR_HANDLER(InvalidArgument)
+    4531           0 : ERROR_HANDLER(InvalidLabel)
+    4532           0 : ERROR_HANDLER(InvalidInstruction)
+    4533           0 : ERROR_HANDLER(InvalidLockPrefix)
+    4534           0 : ERROR_HANDLER(InvalidXAcquirePrefix)
+    4535           0 : ERROR_HANDLER(InvalidXReleasePrefix)
+    4536           0 : ERROR_HANDLER(InvalidRepPrefix)
+    4537           0 : ERROR_HANDLER(InvalidRexPrefix)
+    4538           0 : ERROR_HANDLER(InvalidBroadcast)
+    4539           0 : ERROR_HANDLER(InvalidEROrSAE)
+    4540           0 : ERROR_HANDLER(InvalidAddress)
+    4541           0 : ERROR_HANDLER(InvalidAddressIndex)
+    4542           0 : ERROR_HANDLER(InvalidAddress64Bit)
+    4543           0 : ERROR_HANDLER(InvalidDisplacement)
+    4544           0 : ERROR_HANDLER(InvalidSegment)
+    4545           0 : ERROR_HANDLER(InvalidImmediate)
+    4546           0 : ERROR_HANDLER(OperandSizeMismatch)
+    4547           0 : ERROR_HANDLER(AmbiguousOperandSize)
+    4548           0 : ERROR_HANDLER(NotConsecutiveRegs)
+    4549             : 
+    4550           0 : Failed:
+    4551           0 :   return _emitFailed(err, instId, options, o0, o1, o2, o3);
+    4552             : }
+    4553             : 
+    4554             : // ============================================================================
+    4555             : // [asmjit::X86Assembler - Align]
+    4556             : // ============================================================================
+    4557             : 
+    4558           0 : Error X86Assembler::align(uint32_t mode, uint32_t alignment) {
+    4559             : #if !defined(ASMJIT_DISABLE_LOGGING)
+    4560           0 :   if (_globalOptions & kOptionLoggingEnabled)
+    4561           0 :     _code->_logger->logf("%s.align %u\n", _code->_logger->getIndentation(), alignment);
+    4562             : #endif // !ASMJIT_DISABLE_LOGGING
+    4563             : 
+    4564           0 :   if (mode >= kAlignCount)
+    4565           0 :     return setLastError(DebugUtils::errored(kErrorInvalidArgument));
+    4566             : 
+    4567           0 :   if (alignment <= 1)
+    4568             :     return kErrorOk;
+    4569             : 
+    4570           0 :   if (!Utils::isPowerOf2(alignment) || alignment > Globals::kMaxAlignment)
+    4571           0 :     return setLastError(DebugUtils::errored(kErrorInvalidArgument));
+    4572             : 
+    4573           0 :   uint32_t i = static_cast<uint32_t>(Utils::alignDiff<size_t>(getOffset(), alignment));
+    4574           0 :   if (i == 0)
+    4575             :     return kErrorOk;
+    4576             : 
+    4577           0 :   if (getRemainingSpace() < i) {
+    4578           0 :     Error err = _code->growBuffer(&_section->_buffer, i);
+    4579           0 :     if (ASMJIT_UNLIKELY(err)) return setLastError(err);
+    4580             :   }
+    4581             : 
+    4582           0 :   uint8_t* cursor = _bufferPtr;
+    4583             :   uint8_t pattern = 0x00;
+    4584             : 
+    4585           0 :   switch (mode) {
+    4586           0 :     case kAlignCode: {
+    4587           0 :       if (_globalHints & kHintOptimizedAlign) {
+    4588             :         // Intel 64 and IA-32 Architectures Software Developer's Manual - Volume 2B (NOP).
+    4589             :         enum { kMaxNopSize = 9 };
+    4590             : 
+    4591             :         static const uint8_t nopData[kMaxNopSize][kMaxNopSize] = {
+    4592             :           { 0x90 },
+    4593             :           { 0x66, 0x90 },
+    4594             :           { 0x0F, 0x1F, 0x00 },
+    4595             :           { 0x0F, 0x1F, 0x40, 0x00 },
+    4596             :           { 0x0F, 0x1F, 0x44, 0x00, 0x00 },
+    4597             :           { 0x66, 0x0F, 0x1F, 0x44, 0x00, 0x00 },
+    4598             :           { 0x0F, 0x1F, 0x80, 0x00, 0x00, 0x00, 0x00 },
+    4599             :           { 0x0F, 0x1F, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00 },
+    4600             :           { 0x66, 0x0F, 0x1F, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00 }
+    4601             :         };
+    4602             : 
+    4603             :         do {
+    4604           0 :           uint32_t n = std::min<uint32_t>(i, kMaxNopSize);
+    4605           0 :           const uint8_t* src = nopData[n - 1];
+    4606             : 
+    4607           0 :           i -= n;
+    4608             :           do {
+    4609           0 :             EMIT_BYTE(*src++);
+    4610           0 :           } while (--n);
+    4611           0 :         } while (i);
+    4612             :       }
+    4613             : 
+    4614             :       pattern = 0x90;
+    4615             :       break;
+    4616             :     }
+    4617             : 
+    4618           0 :     case kAlignData:
+    4619             :       pattern = 0xCC;
+    4620           0 :       break;
+    4621             : 
+    4622             :     case kAlignZero:
+    4623             :       // Pattern already set to zero.
+    4624             :       break;
+    4625             :   }
+    4626             : 
+    4627           0 :   while (i) {
+    4628           0 :     EMIT_BYTE(pattern);
+    4629           0 :     i--;
+    4630             :   }
+    4631             : 
+    4632           0 :   _bufferPtr = cursor;
+    4633           0 :   return kErrorOk;
+    4634             : }
+    4635             : 
+    4636             : } // asmjit namespace
+    4637             : } // namespace PLMD
+    4638             : 
+    4639             : // [Api-End]
+    4640             : #include "./asmjit_apiend.h"
+    4641             : 
+    4642             : // [Guard]
+    4643             : #endif // ASMJIT_BUILD_X86
+    4644             : #pragma GCC diagnostic pop
+    4645             : #endif // __PLUMED_HAS_ASMJIT
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86assembler.h.func-sort-c.html b/coverage-libs/asmjit/x86assembler.h.func-sort-c.html new file mode 100644 index 000000000000..e77c04ad944c --- /dev/null +++ b/coverage-libs/asmjit/x86assembler.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86assembler.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86assembler.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:22100.0 %
Date:2024-04-19 12:12:36Functions:00-
+
+ +
+ + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86assembler.h.gcov.html b/coverage-libs/asmjit/x86assembler.h.gcov.html new file mode 100644 index 000000000000..dd63a437e96b --- /dev/null +++ b/coverage-libs/asmjit/x86assembler.h.gcov.html @@ -0,0 +1,202 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86assembler.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86assembler.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:22100.0 %
Date:2024-04-19 12:12:36Functions: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      174273 :   ASMJIT_INLINE uint32_t _getAddressOverrideMask() const noexcept { return _privateData; }
+      94       31895 :   ASMJIT_INLINE void _setAddressOverrideMask(uint32_t m) noexcept { _privateData = m; }
+      95             : 
+      96             :   // --------------------------------------------------------------------------
+      97             :   // [Events]
+      98             :   // --------------------------------------------------------------------------
+      99             : 
+     100             :   ASMJIT_API Error onAttach(CodeHolder* code) noexcept override;
+     101             :   ASMJIT_API Error onDetach(CodeHolder* code) noexcept override;
+     102             : 
+     103             :   // --------------------------------------------------------------------------
+     104             :   // [Code-Generation]
+     105             :   // --------------------------------------------------------------------------
+     106             : 
+     107             :   using CodeEmitter::_emit;
+     108             : 
+     109             :   ASMJIT_API Error _emit(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3) override;
+     110             :   ASMJIT_API Error align(uint32_t mode, uint32_t alignment) override;
+     111             : };
+     112             : 
+     113             : //! \}
+     114             : 
+     115             : } // asmjit namespace
+     116             : } // namespace PLMD
+     117             : 
+     118             : // [Api-End]
+     119             : #include "./asmjit_apiend.h"
+     120             : 
+     121             : // [Guard]
+     122             : #endif // _ASMJIT_X86_X86ASSEMBLER_H
+     123             : #pragma GCC diagnostic pop
+     124             : #endif // __PLUMED_HAS_ASMJIT
+     125             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86builder.cpp.func-sort-c.html b/coverage-libs/asmjit/x86builder.cpp.func-sort-c.html new file mode 100644 index 000000000000..1b9695188994 --- /dev/null +++ b/coverage-libs/asmjit/x86builder.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86builder.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86builder.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:0150.0 %
Date:2024-04-19 12:12:36Functions:050.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

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

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

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit11X86Compiler5_emitEjRKNS0_8Operand_ES4_S4_S4_S4_S4_0
_ZN4PLMD6asmjit11X86CompilerD0Ev0
_ZN4PLMD6asmjit11X86Compiler8finalizeEv31895
_ZN4PLMD6asmjit11X86Compiler8onAttachEPNS0_10CodeHolderE31895
_ZN4PLMD6asmjit11X86CompilerC2EPNS0_10CodeHolderE31895
_ZN4PLMD6asmjit11X86CompilerD2Ev31895
_ZN4PLMD6asmjit11X86Compiler5_emitEjRKNS0_8Operand_ES4_S4_S4_574650
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86compiler.cpp.func.html b/coverage-libs/asmjit/x86compiler.cpp.func.html new file mode 100644 index 000000000000..f83cc47e8b7c --- /dev/null +++ b/coverage-libs/asmjit/x86compiler.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86compiler.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86compiler.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:4815131.8 %
Date:2024-04-19 12:12:36Functions:5771.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit11X86Compiler5_emitEjRKNS0_8Operand_ES4_S4_S4_574650
_ZN4PLMD6asmjit11X86Compiler5_emitEjRKNS0_8Operand_ES4_S4_S4_S4_S4_0
_ZN4PLMD6asmjit11X86Compiler8finalizeEv31895
_ZN4PLMD6asmjit11X86Compiler8onAttachEPNS0_10CodeHolderE31895
_ZN4PLMD6asmjit11X86CompilerC2EPNS0_10CodeHolderE31895
_ZN4PLMD6asmjit11X86CompilerD0Ev0
_ZN4PLMD6asmjit11X86CompilerD2Ev31895
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86compiler.cpp.gcov.html b/coverage-libs/asmjit/x86compiler.cpp.gcov.html new file mode 100644 index 000000000000..f1a433177f04 --- /dev/null +++ b/coverage-libs/asmjit/x86compiler.cpp.gcov.html @@ -0,0 +1,479 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86compiler.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86compiler.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:4815131.8 %
Date:2024-04-19 12:12:36Functions: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       31895 : X86Compiler::X86Compiler(CodeHolder* code) noexcept : CodeCompiler() {
+      52       31895 :   if (code)
+      53       31895 :     code->attach(this);
+      54       31895 : }
+      55       31895 : X86Compiler::~X86Compiler() noexcept {}
+      56             : 
+      57             : // ============================================================================
+      58             : // [asmjit::X86Compiler - Events]
+      59             : // ============================================================================
+      60             : 
+      61       31895 : Error X86Compiler::onAttach(CodeHolder* code) noexcept {
+      62             :   uint32_t archType = code->getArchType();
+      63       31895 :   if (!ArchInfo::isX86Family(archType))
+      64             :     return DebugUtils::errored(kErrorInvalidArch);
+      65             : 
+      66       63790 :   ASMJIT_PROPAGATE(_cbPasses.willGrow(&_cbHeap, 1));
+      67       31895 :   ASMJIT_PROPAGATE(Base::onAttach(code));
+      68             : 
+      69       31895 :   if (archType == ArchInfo::kTypeX86)
+      70           0 :     _nativeGpArray = x86OpData.gpd;
+      71             :   else
+      72       31895 :     _nativeGpArray = x86OpData.gpq;
+      73       31895 :   _nativeGpReg = _nativeGpArray[0];
+      74             : 
+      75       63790 :   return addPassT<X86RAPass>();
+      76             : }
+      77             : 
+      78             : // ============================================================================
+      79             : // [asmjit::X86Compiler - Finalize]
+      80             : // ============================================================================
+      81             : 
+      82       31895 : Error X86Compiler::finalize() {
+      83       31895 :   if (_lastError) return _lastError;
+      84             : 
+      85             :   // Flush the global constant pool.
+      86       31895 :   if (_globalConstPool) {
+      87           0 :     addNode(_globalConstPool);
+      88           0 :     _globalConstPool = nullptr;
+      89             :   }
+      90             : 
+      91             :   Error err = kErrorOk;
+      92             :   ZoneVector<CBPass*>& passes = _cbPasses;
+      93             : 
+      94       63790 :   for (size_t i = 0, len = passes.getLength(); i < len; i++) {
+      95       31895 :     CBPass* pass = passes[i];
+      96       31895 :     err = pass->process(&_cbPassZone);
+      97       31895 :     _cbPassZone.reset();
+      98       31895 :     if (err) break;
+      99             :   }
+     100             : 
+     101       31895 :   _cbPassZone.reset();
+     102       31895 :   if (ASMJIT_UNLIKELY(err)) return setLastError(err);
+     103             : 
+     104             :   // TODO: There must be possibility to attach more assemblers, this is not so nice.
+     105       31895 :   if (_code->_cgAsm) {
+     106           0 :     return serialize(_code->_cgAsm);
+     107             :   }
+     108             :   else {
+     109       31895 :     X86Assembler a(_code);
+     110       31895 :     return serialize(&a);
+     111       31895 :   }
+     112             : }
+     113             : 
+     114             : // ============================================================================
+     115             : // [asmjit::X86Compiler - Inst]
+     116             : // ============================================================================
+     117             : 
+     118             : static ASMJIT_INLINE bool isJumpInst(uint32_t instId) noexcept {
+     119      574650 :   return (instId >= X86Inst::kIdJa   && instId <= X86Inst::kIdJz    ) ||
+     120      574650 :          (instId >= X86Inst::kIdLoop && instId <= X86Inst::kIdLoopne) ;
+     121             : }
+     122             : 
+     123      574650 : Error X86Compiler::_emit(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3) {
+     124      574650 :   uint32_t options = getOptions() | getGlobalOptions();
+     125             :   const char* inlineComment = getInlineComment();
+     126             : 
+     127      574650 :   uint32_t opCount = static_cast<uint32_t>(!o0.isNone()) +
+     128      574650 :                      static_cast<uint32_t>(!o1.isNone()) +
+     129      574650 :                      static_cast<uint32_t>(!o2.isNone()) +
+     130      574650 :                      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      574650 :   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      574650 :   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      574650 :     CBInst* node = _cbHeap.allocT<CBInst>(sizeof(CBInst) + opCount * sizeof(Operand));
+     229      574650 :     Operand* opArray = reinterpret_cast<Operand*>(reinterpret_cast<uint8_t*>(node) + sizeof(CBInst));
+     230             : 
+     231      574650 :     if (ASMJIT_UNLIKELY(!node))
+     232           0 :       return setLastError(DebugUtils::errored(kErrorNoHeapMemory));
+     233             : 
+     234      574650 :     if (opCount > 0) opArray[0].copyFrom(o0);
+     235      574650 :     if (opCount > 1) opArray[1].copyFrom(o1);
+     236      574650 :     if (opCount > 2) opArray[2].copyFrom(o2);
+     237      574650 :     if (opCount > 3) opArray[3].copyFrom(o3);
+     238             : 
+     239             :     node = new(node) CBInst(this, instId, options, opArray, opCount);
+     240      574650 :     node->_instDetail.extraReg = _extraReg;
+     241             :     _extraReg.reset();
+     242             : 
+     243      574650 :     if (inlineComment) {
+     244           0 :       inlineComment = static_cast<char*>(_cbDataZone.dup(inlineComment, ::strlen(inlineComment), true));
+     245             :       node->setInlineComment(inlineComment);
+     246             :     }
+     247             : 
+     248      574650 :     addNode(node);
+     249      574650 :     return kErrorOk;
+     250             :   }
+     251             : }
+     252             : 
+     253           0 : Error X86Compiler::_emit(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3, const Operand_& o4, const Operand_& o5) {
+     254           0 :   uint32_t options = getOptions() | getGlobalOptions();
+     255             :   const char* inlineComment = getInlineComment();
+     256             : 
+     257           0 :   uint32_t opCount = static_cast<uint32_t>(!o0.isNone()) +
+     258           0 :                      static_cast<uint32_t>(!o1.isNone()) +
+     259           0 :                      static_cast<uint32_t>(!o2.isNone()) +
+     260           0 :                      static_cast<uint32_t>(!o3.isNone()) ;
+     261             : 
+     262             :   // Count 5th and 6th operands.
+     263           0 :   if (!o4.isNone()) opCount = 5;
+     264           0 :   if (!o5.isNone()) opCount = 6;
+     265             : 
+     266             :   // Handle failure and rare cases first.
+     267             :   const uint32_t kErrorsAndSpecialCases = kOptionMaybeFailureCase | // CodeEmitter in error state.
+     268             :                                           kOptionStrictValidation ; // Strict validation.
+     269             : 
+     270           0 :   if (ASMJIT_UNLIKELY(options & kErrorsAndSpecialCases)) {
+     271             :     // Don't do anything if we are in error state.
+     272           0 :     if (_lastError) return _lastError;
+     273             : 
+     274             : #if !defined(ASMJIT_DISABLE_VALIDATION)
+     275             :     // Strict validation.
+     276           0 :     if (options & kOptionStrictValidation) {
+     277             :       Operand opArray[] = {
+     278             :         Operand(o0),
+     279             :         Operand(o1),
+     280             :         Operand(o2),
+     281             :         Operand(o3),
+     282             :         Operand(o4),
+     283             :         Operand(o5)
+     284             :       };
+     285             : 
+     286             :       Inst::Detail instDetail(instId, options, _extraReg);
+     287           0 :       Error err = Inst::validate(getArchType(), instDetail, opArray, opCount);
+     288             : 
+     289           0 :       if (err) {
+     290             : #if !defined(ASMJIT_DISABLE_LOGGING)
+     291             :         StringBuilderTmp<256> sb;
+     292           0 :         sb.appendString(DebugUtils::errorAsString(err));
+     293             :         sb.appendString(": ");
+     294           0 :         Logging::formatInstruction(sb, 0, this, getArchType(), instDetail, opArray, opCount);
+     295           0 :         return setLastError(err, sb.getData());
+     296             : #else
+     297             :         return setLastError(err);
+     298             : #endif
+     299             :       }
+     300             : 
+     301             :       // Clear it as it must be enabled explicitly on assembler side.
+     302           0 :       options &= ~kOptionStrictValidation;
+     303             :     }
+     304             : #endif // ASMJIT_DISABLE_VALIDATION
+     305             :   }
+     306             : 
+     307             :   resetOptions();
+     308             :   resetInlineComment();
+     309             : 
+     310             :   // decide between `CBInst` and `CBJump`.
+     311           0 :   if (isJumpInst(instId)) {
+     312           0 :     CBJump* node = _cbHeap.allocT<CBJump>(sizeof(CBJump) + opCount * sizeof(Operand));
+     313           0 :     Operand* opArray = reinterpret_cast<Operand*>(reinterpret_cast<uint8_t*>(node) + sizeof(CBJump));
+     314             : 
+     315           0 :     if (ASMJIT_UNLIKELY(!node))
+     316           0 :       return setLastError(DebugUtils::errored(kErrorNoHeapMemory));
+     317             : 
+     318           0 :     if (opCount > 0) opArray[0].copyFrom(o0);
+     319           0 :     if (opCount > 1) opArray[1].copyFrom(o1);
+     320           0 :     if (opCount > 2) opArray[2].copyFrom(o2);
+     321           0 :     if (opCount > 3) opArray[3].copyFrom(o3);
+     322           0 :     if (opCount > 4) opArray[4].copyFrom(o4);
+     323           0 :     if (opCount > 5) opArray[5].copyFrom(o5);
+     324             : 
+     325             :     new(node) CBJump(this, instId, options, opArray, opCount);
+     326           0 :     node->_instDetail.extraReg = _extraReg;
+     327             :     _extraReg.reset();
+     328             : 
+     329           0 :     CBLabel* jTarget = nullptr;
+     330           0 :     if (!(options & kOptionUnfollow)) {
+     331           0 :       if (opArray[0].isLabel()) {
+     332           0 :         Error err = getCBLabel(&jTarget, static_cast<Label&>(opArray[0]));
+     333           0 :         if (err) return setLastError(err);
+     334             :       }
+     335             :       else {
+     336           0 :         options |= kOptionUnfollow;
+     337             :       }
+     338             :     }
+     339             :     node->setOptions(options);
+     340             : 
+     341           0 :     node->orFlags(instId == X86Inst::kIdJmp ? CBNode::kFlagIsJmp | CBNode::kFlagIsTaken : CBNode::kFlagIsJcc);
+     342           0 :     node->_target = jTarget;
+     343           0 :     node->_jumpNext = nullptr;
+     344             : 
+     345           0 :     if (jTarget) {
+     346           0 :       node->_jumpNext = static_cast<CBJump*>(jTarget->_from);
+     347           0 :       jTarget->_from = node;
+     348             :       jTarget->addNumRefs();
+     349             :     }
+     350             : 
+     351             :     // The 'jmp' is always taken, conditional jump can contain hint, we detect it.
+     352           0 :     if (instId == X86Inst::kIdJmp)
+     353             :       node->orFlags(CBNode::kFlagIsTaken);
+     354           0 :     else if (options & X86Inst::kOptionTaken)
+     355             :       node->orFlags(CBNode::kFlagIsTaken);
+     356             : 
+     357           0 :     if (inlineComment) {
+     358           0 :       inlineComment = static_cast<char*>(_cbDataZone.dup(inlineComment, ::strlen(inlineComment), true));
+     359             :       node->setInlineComment(inlineComment);
+     360             :     }
+     361             : 
+     362           0 :     addNode(node);
+     363           0 :     return kErrorOk;
+     364             :   }
+     365             :   else {
+     366           0 :     CBInst* node = _cbHeap.allocT<CBInst>(sizeof(CBInst) + opCount * sizeof(Operand));
+     367           0 :     Operand* opArray = reinterpret_cast<Operand*>(reinterpret_cast<uint8_t*>(node) + sizeof(CBInst));
+     368             : 
+     369           0 :     if (ASMJIT_UNLIKELY(!node))
+     370           0 :       return setLastError(DebugUtils::errored(kErrorNoHeapMemory));
+     371             : 
+     372           0 :     if (opCount > 0) opArray[0].copyFrom(o0);
+     373           0 :     if (opCount > 1) opArray[1].copyFrom(o1);
+     374           0 :     if (opCount > 2) opArray[2].copyFrom(o2);
+     375           0 :     if (opCount > 3) opArray[3].copyFrom(o3);
+     376           0 :     if (opCount > 4) opArray[4].copyFrom(o4);
+     377           0 :     if (opCount > 5) opArray[5].copyFrom(o5);
+     378             : 
+     379             :     node = new(node) CBInst(this, instId, options, opArray, opCount);
+     380           0 :     node->_instDetail.extraReg = _extraReg;
+     381             :     _extraReg.reset();
+     382             : 
+     383           0 :     if (inlineComment) {
+     384           0 :       inlineComment = static_cast<char*>(_cbDataZone.dup(inlineComment, ::strlen(inlineComment), true));
+     385             :       node->setInlineComment(inlineComment);
+     386             :     }
+     387             : 
+     388           0 :     addNode(node);
+     389           0 :     return kErrorOk;
+     390             :   }
+     391             : }
+     392             : 
+     393             : } // asmjit namespace
+     394             : } // namespace PLMD
+     395             : 
+     396             : // [Api-End]
+     397             : #include "./asmjit_apiend.h"
+     398             : 
+     399             : // [Guard]
+     400             : #endif // ASMJIT_BUILD_X86 && !ASMJIT_DISABLE_COMPILER
+     401             : #pragma GCC diagnostic pop
+     402             : #endif // __PLUMED_HAS_ASMJIT
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86compiler.h.func-sort-c.html b/coverage-libs/asmjit/x86compiler.h.func-sort-c.html new file mode 100644 index 000000000000..8b6878e07ac8 --- /dev/null +++ b/coverage-libs/asmjit/x86compiler.h.func-sort-c.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86compiler.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86compiler.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:4666.7 %
Date:2024-04-19 12:12:36Functions:020.0 %
+
+ +
+ + + + + + + + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit11X86Compiler6newGpzEPKcz0
_ZN4PLMD6asmjit11X86Compiler6newRegEjPKcz0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86compiler.h.gcov.html b/coverage-libs/asmjit/x86compiler.h.gcov.html new file mode 100644 index 000000000000..b9837bd197f6 --- /dev/null +++ b/coverage-libs/asmjit/x86compiler.h.gcov.html @@ -0,0 +1,399 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86compiler.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86compiler.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:4666.7 %
Date:2024-04-19 12:12:36Functions: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      104670 :   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      210442 :   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       12914 :   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       31895 :   ASMJIT_INLINE CCFuncRet* ret(const X86Xmm& o0) { return addRet(o0, Operand()); }
+     305             :   //! \overload
+     306             :   ASMJIT_INLINE CCFuncRet* ret(const X86Xmm& o0, const X86Xmm& o1) { return addRet(o0, o1); }
+     307             : };
+     308             : 
+     309             : //! \}
+     310             : 
+     311             : } // asmjit namespace
+     312             : } // namespace PLMD
+     313             : 
+     314             : // [Api-End]
+     315             : #include "./asmjit_apiend.h"
+     316             : 
+     317             : // [Guard]
+     318             : #endif // !ASMJIT_DISABLE_COMPILER
+     319             : #endif // _ASMJIT_X86_X86COMPILER_H
+     320             : #pragma GCC diagnostic pop
+     321             : #endif // __PLUMED_HAS_ASMJIT
+     322             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86emitter.h.func-sort-c.html b/coverage-libs/asmjit/x86emitter.h.func-sort-c.html new file mode 100644 index 000000000000..674c14ba363f --- /dev/null +++ b/coverage-libs/asmjit/x86emitter.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86emitter.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86emitter.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:172763.0 %
Date:2024-04-19 12:12:36Functions:00-
+
+ +
+ + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86emitter.h.gcov.html b/coverage-libs/asmjit/x86emitter.h.gcov.html new file mode 100644 index 000000000000..df6edb8902c2 --- /dev/null +++ b/coverage-libs/asmjit/x86emitter.h.gcov.html @@ -0,0 +1,5226 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86emitter.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86emitter.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:172763.0 %
Date:2024-04-19 12:12:36Functions: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       95685 :     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        4588 :   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      104670 :   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        7024 :   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        7024 :   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        4588 :   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       25974 :   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        2270 :   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        2270 :   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       14746 :   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      106895 :   ASMJIT_INST_2x(movsd, Movsd, X86Xmm, X86Xmm)                                // SSE2
+    1166       82651 :   ASMJIT_INST_2x(movsd, Movsd, X86Xmm, X86Mem)                                // SSE2
+    1167         514 :   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       57365 :   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        2708 :   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        7540 :   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        5274 :   ASMJIT_INST_2x(xorps, Xorps, X86Xmm, X86Xmm)                                // SSE
+    1649             :   ASMJIT_INST_2x(xorps, Xorps, X86Xmm, X86Mem)                                // SSE
+    1650             : 
+    1651             :   // -------------------------------------------------------------------------
+    1652             :   // [3DNOW & GEODE]
+    1653             :   // -------------------------------------------------------------------------
+    1654             : 
+    1655             :   ASMJIT_INST_2x(pavgusb, Pavgusb, X86Mm, X86Mm)                              // 3DNOW
+    1656             :   ASMJIT_INST_2x(pavgusb, Pavgusb, X86Mm, X86Mem)                             // 3DNOW
+    1657             :   ASMJIT_INST_2x(pf2id, Pf2id, X86Mm, X86Mm)                                  // 3DNOW
+    1658             :   ASMJIT_INST_2x(pf2id, Pf2id, X86Mm, X86Mem)                                 // 3DNOW
+    1659             :   ASMJIT_INST_2x(pf2iw, Pf2iw, X86Mm, X86Mm)                                  // 3DNOW
+    1660             :   ASMJIT_INST_2x(pf2iw, Pf2iw, X86Mm, X86Mem)                                 // 3DNOW
+    1661             :   ASMJIT_INST_2x(pfacc, Pfacc, X86Mm, X86Mm)                                  // 3DNOW
+    1662             :   ASMJIT_INST_2x(pfacc, Pfacc, X86Mm, X86Mem)                                 // 3DNOW
+    1663             :   ASMJIT_INST_2x(pfadd, Pfadd, X86Mm, X86Mm)                                  // 3DNOW
+    1664             :   ASMJIT_INST_2x(pfadd, Pfadd, X86Mm, X86Mem)                                 // 3DNOW
+    1665             :   ASMJIT_INST_2x(pfcmpeq, Pfcmpeq, X86Mm, X86Mm)                              // 3DNOW
+    1666             :   ASMJIT_INST_2x(pfcmpeq, Pfcmpeq, X86Mm, X86Mem)                             // 3DNOW
+    1667             :   ASMJIT_INST_2x(pfcmpge, Pfcmpge, X86Mm, X86Mm)                              // 3DNOW
+    1668             :   ASMJIT_INST_2x(pfcmpge, Pfcmpge, X86Mm, X86Mem)                             // 3DNOW
+    1669             :   ASMJIT_INST_2x(pfcmpgt, Pfcmpgt, X86Mm, X86Mm)                              // 3DNOW
+    1670             :   ASMJIT_INST_2x(pfcmpgt, Pfcmpgt, X86Mm, X86Mem)                             // 3DNOW
+    1671             :   ASMJIT_INST_2x(pfmax, Pfmax, X86Mm, X86Mm)                                  // 3DNOW
+    1672             :   ASMJIT_INST_2x(pfmax, Pfmax, X86Mm, X86Mem)                                 // 3DNOW
+    1673             :   ASMJIT_INST_2x(pfmin, Pfmin, X86Mm, X86Mm)                                  // 3DNOW
+    1674             :   ASMJIT_INST_2x(pfmin, Pfmin, X86Mm, X86Mem)                                 // 3DNOW
+    1675             :   ASMJIT_INST_2x(pfmul, Pfmul, X86Mm, X86Mm)                                  // 3DNOW
+    1676             :   ASMJIT_INST_2x(pfmul, Pfmul, X86Mm, X86Mem)                                 // 3DNOW
+    1677             :   ASMJIT_INST_2x(pfnacc, Pfnacc, X86Mm, X86Mm)                                // 3DNOW
+    1678             :   ASMJIT_INST_2x(pfnacc, Pfnacc, X86Mm, X86Mem)                               // 3DNOW
+    1679             :   ASMJIT_INST_2x(pfpnacc, Pfpnacc, X86Mm, X86Mm)                              // 3DNOW
+    1680             :   ASMJIT_INST_2x(pfpnacc, Pfpnacc, X86Mm, X86Mem)                             // 3DNOW
+    1681             :   ASMJIT_INST_2x(pfrcp, Pfrcp, X86Mm, X86Mm)                                  // 3DNOW
+    1682             :   ASMJIT_INST_2x(pfrcp, Pfrcp, X86Mm, X86Mem)                                 // 3DNOW
+    1683             :   ASMJIT_INST_2x(pfrcpit1, Pfrcpit1, X86Mm, X86Mm)                            // 3DNOW
+    1684             :   ASMJIT_INST_2x(pfrcpit1, Pfrcpit1, X86Mm, X86Mem)                           // 3DNOW
+    1685             :   ASMJIT_INST_2x(pfrcpit2, Pfrcpit2, X86Mm, X86Mm)                            // 3DNOW
+    1686             :   ASMJIT_INST_2x(pfrcpit2, Pfrcpit2, X86Mm, X86Mem)                           // 3DNOW
+    1687             :   ASMJIT_INST_2x(pfrcpv, Pfrcpv, X86Mm, X86Mm)                                // GEODE
+    1688             :   ASMJIT_INST_2x(pfrcpv, Pfrcpv, X86Mm, X86Mem)                               // GEODE
+    1689             :   ASMJIT_INST_2x(pfrsqit1, Pfrsqit1, X86Mm, X86Mm)                            // 3DNOW
+    1690             :   ASMJIT_INST_2x(pfrsqit1, Pfrsqit1, X86Mm, X86Mem)                           // 3DNOW
+    1691             :   ASMJIT_INST_2x(pfrsqrt, Pfrsqrt, X86Mm, X86Mm)                              // 3DNOW
+    1692             :   ASMJIT_INST_2x(pfrsqrt, Pfrsqrt, X86Mm, X86Mem)                             // 3DNOW
+    1693             :   ASMJIT_INST_2x(pfrsqrtv, Pfrsqrtv, X86Mm, X86Mm)                            // GEODE
+    1694             :   ASMJIT_INST_2x(pfrsqrtv, Pfrsqrtv, X86Mm, X86Mem)                           // GEODE
+    1695             :   ASMJIT_INST_2x(pfsub, Pfsub, X86Mm, X86Mm)                                  // 3DNOW
+    1696             :   ASMJIT_INST_2x(pfsub, Pfsub, X86Mm, X86Mem)                                 // 3DNOW
+    1697             :   ASMJIT_INST_2x(pfsubr, Pfsubr, X86Mm, X86Mm)                                // 3DNOW
+    1698             :   ASMJIT_INST_2x(pfsubr, Pfsubr, X86Mm, X86Mem)                               // 3DNOW
+    1699             :   ASMJIT_INST_2x(pi2fd, Pi2fd, X86Mm, X86Mm)                                  // 3DNOW
+    1700             :   ASMJIT_INST_2x(pi2fd, Pi2fd, X86Mm, X86Mem)                                 // 3DNOW
+    1701             :   ASMJIT_INST_2x(pi2fw, Pi2fw, X86Mm, X86Mm)                                  // 3DNOW
+    1702             :   ASMJIT_INST_2x(pi2fw, Pi2fw, X86Mm, X86Mem)                                 // 3DNOW
+    1703             :   ASMJIT_INST_2x(pmulhrw, Pmulhrw, X86Mm, X86Mm)                              // 3DNOW
+    1704             :   ASMJIT_INST_2x(pmulhrw, Pmulhrw, X86Mm, X86Mem)                             // 3DNOW
+    1705             :   ASMJIT_INST_2x(pswapd, Pswapd, X86Mm, X86Mm)                                // 3DNOW
+    1706             :   ASMJIT_INST_2x(pswapd, Pswapd, X86Mm, X86Mem)                               // 3DNOW
+    1707             :   ASMJIT_INST_0x(femms, Femms)                                                // 3DNOW
+    1708             : 
+    1709             :   // --------------------------------------------------------------------------
+    1710             :   // [AESNI]
+    1711             :   // --------------------------------------------------------------------------
+    1712             : 
+    1713             :   ASMJIT_INST_2x(aesdec, Aesdec, X86Xmm, X86Xmm)                              // AESNI
+    1714             :   ASMJIT_INST_2x(aesdec, Aesdec, X86Xmm, X86Mem)                              // AESNI
+    1715             :   ASMJIT_INST_2x(aesdeclast, Aesdeclast, X86Xmm, X86Xmm)                      // AESNI
+    1716             :   ASMJIT_INST_2x(aesdeclast, Aesdeclast, X86Xmm, X86Mem)                      // AESNI
+    1717             :   ASMJIT_INST_2x(aesenc, Aesenc, X86Xmm, X86Xmm)                              // AESNI
+    1718             :   ASMJIT_INST_2x(aesenc, Aesenc, X86Xmm, X86Mem)                              // AESNI
+    1719             :   ASMJIT_INST_2x(aesenclast, Aesenclast, X86Xmm, X86Xmm)                      // AESNI
+    1720             :   ASMJIT_INST_2x(aesenclast, Aesenclast, X86Xmm, X86Mem)                      // AESNI
+    1721             :   ASMJIT_INST_2x(aesimc, Aesimc, X86Xmm, X86Xmm)                              // AESNI
+    1722             :   ASMJIT_INST_2x(aesimc, Aesimc, X86Xmm, X86Mem)                              // AESNI
+    1723             :   ASMJIT_INST_3i(aeskeygenassist, Aeskeygenassist, X86Xmm, X86Xmm, Imm)       // AESNI
+    1724             :   ASMJIT_INST_3i(aeskeygenassist, Aeskeygenassist, X86Xmm, X86Mem, Imm)       // AESNI
+    1725             : 
+    1726             :   // --------------------------------------------------------------------------
+    1727             :   // [SHA]
+    1728             :   // --------------------------------------------------------------------------
+    1729             : 
+    1730             :   ASMJIT_INST_2x(sha1msg1, Sha1msg1, X86Xmm, X86Xmm)                          // SHA
+    1731             :   ASMJIT_INST_2x(sha1msg1, Sha1msg1, X86Xmm, X86Mem)                          // SHA
+    1732             :   ASMJIT_INST_2x(sha1msg2, Sha1msg2, X86Xmm, X86Xmm)                          // SHA
+    1733             :   ASMJIT_INST_2x(sha1msg2, Sha1msg2, X86Xmm, X86Mem)                          // SHA
+    1734             :   ASMJIT_INST_2x(sha1nexte, Sha1nexte, X86Xmm, X86Xmm)                        // SHA
+    1735             :   ASMJIT_INST_2x(sha1nexte, Sha1nexte, X86Xmm, X86Mem)                        // SHA
+    1736             :   ASMJIT_INST_3i(sha1rnds4, Sha1rnds4, X86Xmm, X86Xmm, Imm)                   // SHA
+    1737             :   ASMJIT_INST_3i(sha1rnds4, Sha1rnds4, X86Xmm, X86Mem, Imm)                   // SHA
+    1738             :   ASMJIT_INST_2x(sha256msg1, Sha256msg1, X86Xmm, X86Xmm)                      // SHA
+    1739             :   ASMJIT_INST_2x(sha256msg1, Sha256msg1, X86Xmm, X86Mem)                      // SHA
+    1740             :   ASMJIT_INST_2x(sha256msg2, Sha256msg2, X86Xmm, X86Xmm)                      // SHA
+    1741             :   ASMJIT_INST_2x(sha256msg2, Sha256msg2, X86Xmm, X86Mem)                      // SHA
+    1742             :   ASMJIT_INST_3x(sha256rnds2, Sha256rnds2, X86Xmm, X86Xmm, XMM0)              // SHA [EXPLICIT]
+    1743             :   ASMJIT_INST_3x(sha256rnds2, Sha256rnds2, X86Xmm, X86Mem, XMM0)              // SHA [EXPLICIT]
+    1744             : 
+    1745             :   // --------------------------------------------------------------------------
+    1746             :   // [AVX...AVX512]
+    1747             :   // --------------------------------------------------------------------------
+    1748             : 
+    1749             :   ASMJIT_INST_3x(kaddb, Kaddb, X86KReg, X86KReg, X86KReg)                     // AVX512_DQ
+    1750             :   ASMJIT_INST_3x(kaddd, Kaddd, X86KReg, X86KReg, X86KReg)                     // AVX512_BW
+    1751             :   ASMJIT_INST_3x(kaddq, Kaddq, X86KReg, X86KReg, X86KReg)                     // AVX512_BW
+    1752             :   ASMJIT_INST_3x(kaddw, Kaddw, X86KReg, X86KReg, X86KReg)                     // AVX512_DQ
+    1753             :   ASMJIT_INST_3x(kandb, Kandb, X86KReg, X86KReg, X86KReg)                     // AVX512_DQ
+    1754             :   ASMJIT_INST_3x(kandd, Kandd, X86KReg, X86KReg, X86KReg)                     // AVX512_BW
+    1755             :   ASMJIT_INST_3x(kandnb, Kandnb, X86KReg, X86KReg, X86KReg)                   // AVX512_DQ
+    1756             :   ASMJIT_INST_3x(kandnd, Kandnd, X86KReg, X86KReg, X86KReg)                   // AVX512_BW
+    1757             :   ASMJIT_INST_3x(kandnq, Kandnq, X86KReg, X86KReg, X86KReg)                   // AVX512_BW
+    1758             :   ASMJIT_INST_3x(kandnw, Kandnw, X86KReg, X86KReg, X86KReg)                   // AVX512_F
+    1759             :   ASMJIT_INST_3x(kandq, Kandq, X86KReg, X86KReg, X86KReg)                     // AVX512_BW
+    1760             :   ASMJIT_INST_3x(kandw, Kandw, X86KReg, X86KReg, X86KReg)                     // AVX512_F
+    1761             :   ASMJIT_INST_2x(kmovb, Kmovb, X86KReg, X86KReg)                              // AVX512_DQ
+    1762             :   ASMJIT_INST_2x(kmovb, Kmovb, X86KReg, X86Mem)                               // AVX512_DQ
+    1763             :   ASMJIT_INST_2x(kmovb, Kmovb, X86KReg, X86Gp)                                // AVX512_DQ
+    1764             :   ASMJIT_INST_2x(kmovb, Kmovb, X86Mem, X86KReg)                               // AVX512_DQ
+    1765             :   ASMJIT_INST_2x(kmovb, Kmovb, X86Gp, X86KReg)                                // AVX512_DQ
+    1766             :   ASMJIT_INST_2x(kmovd, Kmovd, X86KReg, X86KReg)                              // AVX512_BW
+    1767             :   ASMJIT_INST_2x(kmovd, Kmovd, X86KReg, X86Mem)                               // AVX512_BW
+    1768             :   ASMJIT_INST_2x(kmovd, Kmovd, X86KReg, X86Gp)                                // AVX512_BW
+    1769             :   ASMJIT_INST_2x(kmovd, Kmovd, X86Mem, X86KReg)                               // AVX512_BW
+    1770             :   ASMJIT_INST_2x(kmovd, Kmovd, X86Gp, X86KReg)                                // AVX512_BW
+    1771             :   ASMJIT_INST_2x(kmovq, Kmovq, X86KReg, X86KReg)                              // AVX512_BW
+    1772             :   ASMJIT_INST_2x(kmovq, Kmovq, X86KReg, X86Mem)                               // AVX512_BW
+    1773             :   ASMJIT_INST_2x(kmovq, Kmovq, X86KReg, X86Gp)                                // AVX512_BW
+    1774             :   ASMJIT_INST_2x(kmovq, Kmovq, X86Mem, X86KReg)                               // AVX512_BW
+    1775             :   ASMJIT_INST_2x(kmovq, Kmovq, X86Gp, X86KReg)                                // AVX512_BW
+    1776             :   ASMJIT_INST_2x(kmovw, Kmovw, X86KReg, X86KReg)                              // AVX512_F
+    1777             :   ASMJIT_INST_2x(kmovw, Kmovw, X86KReg, X86Mem)                               // AVX512_F
+    1778             :   ASMJIT_INST_2x(kmovw, Kmovw, X86KReg, X86Gp)                                // AVX512_F
+    1779             :   ASMJIT_INST_2x(kmovw, Kmovw, X86Mem, X86KReg)                               // AVX512_F
+    1780             :   ASMJIT_INST_2x(kmovw, Kmovw, X86Gp, X86KReg)                                // AVX512_F
+    1781             :   ASMJIT_INST_2x(knotb, Knotb, X86KReg, X86KReg)                              // AVX512_DQ
+    1782             :   ASMJIT_INST_2x(knotd, Knotd, X86KReg, X86KReg)                              // AVX512_BW
+    1783             :   ASMJIT_INST_2x(knotq, Knotq, X86KReg, X86KReg)                              // AVX512_BW
+    1784             :   ASMJIT_INST_2x(knotw, Knotw, X86KReg, X86KReg)                              // AVX512_F
+    1785             :   ASMJIT_INST_3x(korb, Korb, X86KReg, X86KReg, X86KReg)                       // AVX512_DQ
+    1786             :   ASMJIT_INST_3x(kord, Kord, X86KReg, X86KReg, X86KReg)                       // AVX512_BW
+    1787             :   ASMJIT_INST_3x(korq, Korq, X86KReg, X86KReg, X86KReg)                       // AVX512_BW
+    1788             :   ASMJIT_INST_2x(kortestb, Kortestb, X86KReg, X86KReg)                        // AVX512_DQ
+    1789             :   ASMJIT_INST_2x(kortestd, Kortestd, X86KReg, X86KReg)                        // AVX512_BW
+    1790             :   ASMJIT_INST_2x(kortestq, Kortestq, X86KReg, X86KReg)                        // AVX512_BW
+    1791             :   ASMJIT_INST_2x(kortestw, Kortestw, X86KReg, X86KReg)                        // AVX512_F
+    1792             :   ASMJIT_INST_3x(korw, Korw, X86KReg, X86KReg, X86KReg)                       // AVX512_F
+    1793             :   ASMJIT_INST_3i(kshiftlb, Kshiftlb, X86KReg, X86KReg, Imm)                   // AVX512_DQ
+    1794             :   ASMJIT_INST_3i(kshiftld, Kshiftld, X86KReg, X86KReg, Imm)                   // AVX512_BW
+    1795             :   ASMJIT_INST_3i(kshiftlq, Kshiftlq, X86KReg, X86KReg, Imm)                   // AVX512_BW
+    1796             :   ASMJIT_INST_3i(kshiftlw, Kshiftlw, X86KReg, X86KReg, Imm)                   // AVX512_F
+    1797             :   ASMJIT_INST_3i(kshiftrb, Kshiftrb, X86KReg, X86KReg, Imm)                   // AVX512_DQ
+    1798             :   ASMJIT_INST_3i(kshiftrd, Kshiftrd, X86KReg, X86KReg, Imm)                   // AVX512_BW
+    1799             :   ASMJIT_INST_3i(kshiftrq, Kshiftrq, X86KReg, X86KReg, Imm)                   // AVX512_BW
+    1800             :   ASMJIT_INST_3i(kshiftrw, Kshiftrw, X86KReg, X86KReg, Imm)                   // AVX512_F
+    1801             :   ASMJIT_INST_2x(ktestb, Ktestb, X86KReg, X86KReg)                            // AVX512_DQ
+    1802             :   ASMJIT_INST_2x(ktestd, Ktestd, X86KReg, X86KReg)                            // AVX512_BW
+    1803             :   ASMJIT_INST_2x(ktestq, Ktestq, X86KReg, X86KReg)                            // AVX512_BW
+    1804             :   ASMJIT_INST_2x(ktestw, Ktestw, X86KReg, X86KReg)                            // AVX512_DQ
+    1805             :   ASMJIT_INST_3x(kunpckbw, Kunpckbw, X86KReg, X86KReg, X86KReg)               // AVX512_F
+    1806             :   ASMJIT_INST_3x(kunpckdq, Kunpckdq, X86KReg, X86KReg, X86KReg)               // AVX512_BW
+    1807             :   ASMJIT_INST_3x(kunpckwd, Kunpckwd, X86KReg, X86KReg, X86KReg)               // AVX512_BW
+    1808             :   ASMJIT_INST_3x(kxnorb, Kxnorb, X86KReg, X86KReg, X86KReg)                   // AVX512_DQ
+    1809             :   ASMJIT_INST_3x(kxnord, Kxnord, X86KReg, X86KReg, X86KReg)                   // AVX512_BW
+    1810             :   ASMJIT_INST_3x(kxnorq, Kxnorq, X86KReg, X86KReg, X86KReg)                   // AVX512_BW
+    1811             :   ASMJIT_INST_3x(kxnorw, Kxnorw, X86KReg, X86KReg, X86KReg)                   // AVX512_F
+    1812             :   ASMJIT_INST_3x(kxorb, Kxorb, X86KReg, X86KReg, X86KReg)                     // AVX512_DQ
+    1813             :   ASMJIT_INST_3x(kxord, Kxord, X86KReg, X86KReg, X86KReg)                     // AVX512_BW
+    1814             :   ASMJIT_INST_3x(kxorq, Kxorq, X86KReg, X86KReg, X86KReg)                     // AVX512_BW
+    1815             :   ASMJIT_INST_3x(kxorw, Kxorw, X86KReg, X86KReg, X86KReg)                     // AVX512_F
+    1816             :   ASMJIT_INST_6x(v4fmaddps, V4fmaddps, X86Zmm, X86Zmm, X86Zmm, X86Zmm, X86Zmm, X86Mem)   // AVX512_4FMAPS{kz}
+    1817             :   ASMJIT_INST_6x(v4fnmaddps, V4fnmaddps, X86Zmm, X86Zmm, X86Zmm, X86Zmm, X86Zmm, X86Mem) // AVX512_4FMAPS{kz}
+    1818             :   ASMJIT_INST_3x(vaddpd, Vaddpd, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|b64}-VL
+    1819             :   ASMJIT_INST_3x(vaddpd, Vaddpd, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|b64}-VL
+    1820             :   ASMJIT_INST_3x(vaddpd, Vaddpd, X86Ymm, X86Ymm, X86Ymm)                      // AVX  AVX512_F{kz|b64}-VL
+    1821             :   ASMJIT_INST_3x(vaddpd, Vaddpd, X86Ymm, X86Ymm, X86Mem)                      // AVX  AVX512_F{kz|b64}-VL
+    1822             :   ASMJIT_INST_3x(vaddpd, Vaddpd, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_F{kz|er|b64}
+    1823             :   ASMJIT_INST_3x(vaddpd, Vaddpd, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_F{kz|er|b64}
+    1824             :   ASMJIT_INST_3x(vaddps, Vaddps, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|b32}-VL
+    1825             :   ASMJIT_INST_3x(vaddps, Vaddps, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|b32}-VL
+    1826             :   ASMJIT_INST_3x(vaddps, Vaddps, X86Ymm, X86Ymm, X86Ymm)                      // AVX  AVX512_F{kz|b32}-VL
+    1827             :   ASMJIT_INST_3x(vaddps, Vaddps, X86Ymm, X86Ymm, X86Mem)                      // AVX  AVX512_F{kz|b32}-VL
+    1828             :   ASMJIT_INST_3x(vaddps, Vaddps, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_F{kz|er|b32}
+    1829             :   ASMJIT_INST_3x(vaddps, Vaddps, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_F{kz|er|b32}
+    1830             :   ASMJIT_INST_3x(vaddsd, Vaddsd, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|er}
+    1831             :   ASMJIT_INST_3x(vaddsd, Vaddsd, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|er}
+    1832             :   ASMJIT_INST_3x(vaddss, Vaddss, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|er}
+    1833             :   ASMJIT_INST_3x(vaddss, Vaddss, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|er}
+    1834             :   ASMJIT_INST_3x(vaddsubpd, Vaddsubpd, X86Xmm, X86Xmm, X86Xmm)                // AVX
+    1835             :   ASMJIT_INST_3x(vaddsubpd, Vaddsubpd, X86Xmm, X86Xmm, X86Mem)                // AVX
+    1836             :   ASMJIT_INST_3x(vaddsubpd, Vaddsubpd, X86Ymm, X86Ymm, X86Ymm)                // AVX
+    1837             :   ASMJIT_INST_3x(vaddsubpd, Vaddsubpd, X86Ymm, X86Ymm, X86Mem)                // AVX
+    1838             :   ASMJIT_INST_3x(vaddsubps, Vaddsubps, X86Xmm, X86Xmm, X86Xmm)                // AVX
+    1839             :   ASMJIT_INST_3x(vaddsubps, Vaddsubps, X86Xmm, X86Xmm, X86Mem)                // AVX
+    1840             :   ASMJIT_INST_3x(vaddsubps, Vaddsubps, X86Ymm, X86Ymm, X86Ymm)                // AVX
+    1841             :   ASMJIT_INST_3x(vaddsubps, Vaddsubps, X86Ymm, X86Ymm, X86Mem)                // AVX
+    1842             :   ASMJIT_INST_3x(vaesdec, Vaesdec, X86Xmm, X86Xmm, X86Xmm)                    // AVX
+    1843             :   ASMJIT_INST_3x(vaesdec, Vaesdec, X86Xmm, X86Xmm, X86Mem)                    // AVX
+    1844             :   ASMJIT_INST_3x(vaesdeclast, Vaesdeclast, X86Xmm, X86Xmm, X86Xmm)            // AVX
+    1845             :   ASMJIT_INST_3x(vaesdeclast, Vaesdeclast, X86Xmm, X86Xmm, X86Mem)            // AVX
+    1846             :   ASMJIT_INST_3x(vaesenc, Vaesenc, X86Xmm, X86Xmm, X86Xmm)                    // AVX
+    1847             :   ASMJIT_INST_3x(vaesenc, Vaesenc, X86Xmm, X86Xmm, X86Mem)                    // AVX
+    1848             :   ASMJIT_INST_3x(vaesenclast, Vaesenclast, X86Xmm, X86Xmm, X86Xmm)            // AVX
+    1849             :   ASMJIT_INST_3x(vaesenclast, Vaesenclast, X86Xmm, X86Xmm, X86Mem)            // AVX
+    1850             :   ASMJIT_INST_2x(vaesimc, Vaesimc, X86Xmm, X86Xmm)                            // AVX
+    1851             :   ASMJIT_INST_2x(vaesimc, Vaesimc, X86Xmm, X86Mem)                            // AVX
+    1852             :   ASMJIT_INST_3i(vaeskeygenassist, Vaeskeygenassist, X86Xmm, X86Xmm, Imm)     // AVX
+    1853             :   ASMJIT_INST_3i(vaeskeygenassist, Vaeskeygenassist, X86Xmm, X86Mem, Imm)     // AVX
+    1854             :   ASMJIT_INST_4i(valignd, Valignd, X86Xmm, X86Xmm, X86Xmm, Imm)               //      AVX512_F{kz|b32}-VL
+    1855             :   ASMJIT_INST_4i(valignd, Valignd, X86Xmm, X86Xmm, X86Mem, Imm)               //      AVX512_F{kz|b32}-VL
+    1856             :   ASMJIT_INST_4i(valignd, Valignd, X86Ymm, X86Ymm, X86Ymm, Imm)               //      AVX512_F{kz|b32}-VL
+    1857             :   ASMJIT_INST_4i(valignd, Valignd, X86Ymm, X86Ymm, X86Mem, Imm)               //      AVX512_F{kz|b32}-VL
+    1858             :   ASMJIT_INST_4i(valignd, Valignd, X86Zmm, X86Zmm, X86Zmm, Imm)               //      AVX512_F{kz|b32}
+    1859             :   ASMJIT_INST_4i(valignd, Valignd, X86Zmm, X86Zmm, X86Mem, Imm)               //      AVX512_F{kz|b32}
+    1860             :   ASMJIT_INST_4i(valignq, Valignq, X86Xmm, X86Xmm, X86Xmm, Imm)               //      AVX512_F{kz|b64}-VL
+    1861             :   ASMJIT_INST_4i(valignq, Valignq, X86Xmm, X86Xmm, X86Mem, Imm)               //      AVX512_F{kz|b64}-VL
+    1862             :   ASMJIT_INST_4i(valignq, Valignq, X86Ymm, X86Ymm, X86Ymm, Imm)               //      AVX512_F{kz|b64}-VL
+    1863             :   ASMJIT_INST_4i(valignq, Valignq, X86Ymm, X86Ymm, X86Mem, Imm)               //      AVX512_F{kz|b64}-VL
+    1864             :   ASMJIT_INST_4i(valignq, Valignq, X86Zmm, X86Zmm, X86Zmm, Imm)               //      AVX512_F{kz|b64}
+    1865             :   ASMJIT_INST_4i(valignq, Valignq, X86Zmm, X86Zmm, X86Mem, Imm)               //      AVX512_F{kz|b64}
+    1866             :   ASMJIT_INST_3x(vandnpd, Vandnpd, X86Xmm, X86Xmm, X86Xmm)                    // AVX  AVX512_DQ{kz|b64}-VL
+    1867             :   ASMJIT_INST_3x(vandnpd, Vandnpd, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_DQ{kz|b64}-VL
+    1868             :   ASMJIT_INST_3x(vandnpd, Vandnpd, X86Ymm, X86Ymm, X86Ymm)                    // AVX  AVX512_DQ{kz|b64}-VL
+    1869             :   ASMJIT_INST_3x(vandnpd, Vandnpd, X86Ymm, X86Ymm, X86Mem)                    // AVX  AVX512_DQ{kz|b64}-VL
+    1870             :   ASMJIT_INST_3x(vandnpd, Vandnpd, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_DQ{kz|b64}
+    1871             :   ASMJIT_INST_3x(vandnpd, Vandnpd, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_DQ{kz|b64}
+    1872             :   ASMJIT_INST_3x(vandnps, Vandnps, X86Xmm, X86Xmm, X86Xmm)                    // AVX  AVX512_DQ{kz|b32}-VL
+    1873             :   ASMJIT_INST_3x(vandnps, Vandnps, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_DQ{kz|b32}-VL
+    1874             :   ASMJIT_INST_3x(vandnps, Vandnps, X86Ymm, X86Ymm, X86Ymm)                    // AVX  AVX512_DQ{kz|b32}-VL
+    1875             :   ASMJIT_INST_3x(vandnps, Vandnps, X86Ymm, X86Ymm, X86Mem)                    // AVX  AVX512_DQ{kz|b32}-VL
+    1876             :   ASMJIT_INST_3x(vandnps, Vandnps, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_DQ{kz|b32}
+    1877             :   ASMJIT_INST_3x(vandnps, Vandnps, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_DQ{kz|b32}
+    1878             :   ASMJIT_INST_3x(vandpd, Vandpd, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_DQ{kz|b64}-VL
+    1879             :   ASMJIT_INST_3x(vandpd, Vandpd, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_DQ{kz|b64}-VL
+    1880             :   ASMJIT_INST_3x(vandpd, Vandpd, X86Ymm, X86Ymm, X86Ymm)                      // AVX  AVX512_DQ{kz|b64}-VL
+    1881             :   ASMJIT_INST_3x(vandpd, Vandpd, X86Ymm, X86Ymm, X86Mem)                      // AVX  AVX512_DQ{kz|b64}-VL
+    1882             :   ASMJIT_INST_3x(vandpd, Vandpd, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_DQ{kz|b64}
+    1883             :   ASMJIT_INST_3x(vandpd, Vandpd, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_DQ{kz|b64}
+    1884             :   ASMJIT_INST_3x(vandps, Vandps, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_DQ{kz|b32}-VL
+    1885             :   ASMJIT_INST_3x(vandps, Vandps, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_DQ{kz|b32}-VL
+    1886             :   ASMJIT_INST_3x(vandps, Vandps, X86Ymm, X86Ymm, X86Ymm)                      // AVX  AVX512_DQ{kz|b32}-VL
+    1887             :   ASMJIT_INST_3x(vandps, Vandps, X86Ymm, X86Ymm, X86Mem)                      // AVX  AVX512_DQ{kz|b32}-VL
+    1888             :   ASMJIT_INST_3x(vandps, Vandps, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_DQ{kz|b32}
+    1889             :   ASMJIT_INST_3x(vandps, Vandps, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_DQ{kz|b32}
+    1890             :   ASMJIT_INST_3x(vblendmb, Vblendmb, X86Xmm, X86Xmm, X86Xmm)                  //      AVX512_BW{kz}-VL
+    1891             :   ASMJIT_INST_3x(vblendmb, Vblendmb, X86Xmm, X86Xmm, X86Mem)                  //      AVX512_BW{kz}-VL
+    1892             :   ASMJIT_INST_3x(vblendmb, Vblendmb, X86Ymm, X86Ymm, X86Ymm)                  //      AVX512_BW{kz}-VL
+    1893             :   ASMJIT_INST_3x(vblendmb, Vblendmb, X86Ymm, X86Ymm, X86Mem)                  //      AVX512_BW{kz}-VL
+    1894             :   ASMJIT_INST_3x(vblendmb, Vblendmb, X86Zmm, X86Zmm, X86Zmm)                  //      AVX512_BW{kz}
+    1895             :   ASMJIT_INST_3x(vblendmb, Vblendmb, X86Zmm, X86Zmm, X86Mem)                  //      AVX512_BW{kz}
+    1896             :   ASMJIT_INST_3x(vblendmd, Vblendmd, X86Xmm, X86Xmm, X86Xmm)                  //      AVX512_F{kz|b32}-VL
+    1897             :   ASMJIT_INST_3x(vblendmd, Vblendmd, X86Xmm, X86Xmm, X86Mem)                  //      AVX512_F{kz|b32}-VL
+    1898             :   ASMJIT_INST_3x(vblendmd, Vblendmd, X86Ymm, X86Ymm, X86Ymm)                  //      AVX512_F{kz|b32}-VL
+    1899             :   ASMJIT_INST_3x(vblendmd, Vblendmd, X86Ymm, X86Ymm, X86Mem)                  //      AVX512_F{kz|b32}-VL
+    1900             :   ASMJIT_INST_3x(vblendmd, Vblendmd, X86Zmm, X86Zmm, X86Zmm)                  //      AVX512_F{kz|b32}
+    1901             :   ASMJIT_INST_3x(vblendmd, Vblendmd, X86Zmm, X86Zmm, X86Mem)                  //      AVX512_F{kz|b32}
+    1902             :   ASMJIT_INST_3x(vblendmpd, Vblendmpd, X86Xmm, X86Xmm, X86Xmm)                //      AVX512_F{kz|b64}-VL
+    1903             :   ASMJIT_INST_3x(vblendmpd, Vblendmpd, X86Xmm, X86Xmm, X86Mem)                //      AVX512_F{kz|b64}-VL
+    1904             :   ASMJIT_INST_3x(vblendmpd, Vblendmpd, X86Ymm, X86Ymm, X86Ymm)                //      AVX512_F{kz|b64}-VL
+    1905             :   ASMJIT_INST_3x(vblendmpd, Vblendmpd, X86Ymm, X86Ymm, X86Mem)                //      AVX512_F{kz|b64}-VL
+    1906             :   ASMJIT_INST_3x(vblendmpd, Vblendmpd, X86Zmm, X86Zmm, X86Zmm)                //      AVX512_F{kz|b64}
+    1907             :   ASMJIT_INST_3x(vblendmpd, Vblendmpd, X86Zmm, X86Zmm, X86Mem)                //      AVX512_F{kz|b64}
+    1908             :   ASMJIT_INST_3x(vblendmps, Vblendmps, X86Xmm, X86Xmm, X86Xmm)                //      AVX512_F{kz|b32}-VL
+    1909             :   ASMJIT_INST_3x(vblendmps, Vblendmps, X86Xmm, X86Xmm, X86Mem)                //      AVX512_F{kz|b32}-VL
+    1910             :   ASMJIT_INST_3x(vblendmps, Vblendmps, X86Ymm, X86Ymm, X86Ymm)                //      AVX512_F{kz|b32}-VL
+    1911             :   ASMJIT_INST_3x(vblendmps, Vblendmps, X86Ymm, X86Ymm, X86Mem)                //      AVX512_F{kz|b32}-VL
+    1912             :   ASMJIT_INST_3x(vblendmps, Vblendmps, X86Zmm, X86Zmm, X86Zmm)                //      AVX512_F{kz|b32}
+    1913             :   ASMJIT_INST_3x(vblendmps, Vblendmps, X86Zmm, X86Zmm, X86Mem)                //      AVX512_F{kz|b32}
+    1914             :   ASMJIT_INST_3x(vblendmq, Vblendmq, X86Xmm, X86Xmm, X86Xmm)                  //      AVX512_F{kz|b64}-VL
+    1915             :   ASMJIT_INST_3x(vblendmq, Vblendmq, X86Xmm, X86Xmm, X86Mem)                  //      AVX512_F{kz|b64}-VL
+    1916             :   ASMJIT_INST_3x(vblendmq, Vblendmq, X86Ymm, X86Ymm, X86Ymm)                  //      AVX512_F{kz|b64}-VL
+    1917             :   ASMJIT_INST_3x(vblendmq, Vblendmq, X86Ymm, X86Ymm, X86Mem)                  //      AVX512_F{kz|b64}-VL
+    1918             :   ASMJIT_INST_3x(vblendmq, Vblendmq, X86Zmm, X86Zmm, X86Zmm)                  //      AVX512_F{kz|b64}
+    1919             :   ASMJIT_INST_3x(vblendmq, Vblendmq, X86Zmm, X86Zmm, X86Mem)                  //      AVX512_F{kz|b64}
+    1920             :   ASMJIT_INST_3x(vblendmw, Vblendmw, X86Xmm, X86Xmm, X86Xmm)                  //      AVX512_BW{kz}-VL
+    1921             :   ASMJIT_INST_3x(vblendmw, Vblendmw, X86Xmm, X86Xmm, X86Mem)                  //      AVX512_BW{kz}-VL
+    1922             :   ASMJIT_INST_3x(vblendmw, Vblendmw, X86Ymm, X86Ymm, X86Ymm)                  //      AVX512_BW{kz}-VL
+    1923             :   ASMJIT_INST_3x(vblendmw, Vblendmw, X86Ymm, X86Ymm, X86Mem)                  //      AVX512_BW{kz}-VL
+    1924             :   ASMJIT_INST_3x(vblendmw, Vblendmw, X86Zmm, X86Zmm, X86Zmm)                  //      AVX512_BW{kz}
+    1925             :   ASMJIT_INST_3x(vblendmw, Vblendmw, X86Zmm, X86Zmm, X86Mem)                  //      AVX512_BW{kz}
+    1926             :   ASMJIT_INST_4i(vblendpd, Vblendpd, X86Xmm, X86Xmm, X86Xmm, Imm)             // AVX
+    1927             :   ASMJIT_INST_4i(vblendpd, Vblendpd, X86Xmm, X86Xmm, X86Mem, Imm)             // AVX
+    1928             :   ASMJIT_INST_4i(vblendpd, Vblendpd, X86Ymm, X86Ymm, X86Ymm, Imm)             // AVX
+    1929             :   ASMJIT_INST_4i(vblendpd, Vblendpd, X86Ymm, X86Ymm, X86Mem, Imm)             // AVX
+    1930             :   ASMJIT_INST_4i(vblendps, Vblendps, X86Xmm, X86Xmm, X86Xmm, Imm)             // AVX
+    1931             :   ASMJIT_INST_4i(vblendps, Vblendps, X86Xmm, X86Xmm, X86Mem, Imm)             // AVX
+    1932             :   ASMJIT_INST_4i(vblendps, Vblendps, X86Ymm, X86Ymm, X86Ymm, Imm)             // AVX
+    1933             :   ASMJIT_INST_4i(vblendps, Vblendps, X86Ymm, X86Ymm, X86Mem, Imm)             // AVX
+    1934             :   ASMJIT_INST_4x(vblendvpd, Vblendvpd, X86Xmm, X86Xmm, X86Xmm, X86Xmm)        // AVX
+    1935             :   ASMJIT_INST_4x(vblendvpd, Vblendvpd, X86Xmm, X86Xmm, X86Mem, X86Xmm)        // AVX
+    1936             :   ASMJIT_INST_4x(vblendvpd, Vblendvpd, X86Ymm, X86Ymm, X86Ymm, X86Ymm)        // AVX
+    1937             :   ASMJIT_INST_4x(vblendvpd, Vblendvpd, X86Ymm, X86Ymm, X86Mem, X86Ymm)        // AVX
+    1938             :   ASMJIT_INST_4x(vblendvps, Vblendvps, X86Xmm, X86Xmm, X86Xmm, X86Xmm)        // AVX
+    1939             :   ASMJIT_INST_4x(vblendvps, Vblendvps, X86Xmm, X86Xmm, X86Mem, X86Xmm)        // AVX
+    1940             :   ASMJIT_INST_4x(vblendvps, Vblendvps, X86Ymm, X86Ymm, X86Ymm, X86Ymm)        // AVX
+    1941             :   ASMJIT_INST_4x(vblendvps, Vblendvps, X86Ymm, X86Ymm, X86Mem, X86Ymm)        // AVX
+    1942             :   ASMJIT_INST_2x(vbroadcastf128, Vbroadcastf128, X86Ymm, X86Mem)              // AVX
+    1943             :   ASMJIT_INST_2x(vbroadcastf32x2, Vbroadcastf32x2, X86Ymm, X86Xmm)            //      AVX512_DQ{kz}-VL
+    1944             :   ASMJIT_INST_2x(vbroadcastf32x2, Vbroadcastf32x2, X86Ymm, X86Mem)            //      AVX512_DQ{kz}-VL
+    1945             :   ASMJIT_INST_2x(vbroadcastf32x2, Vbroadcastf32x2, X86Zmm, X86Xmm)            //      AVX512_DQ{kz}
+    1946             :   ASMJIT_INST_2x(vbroadcastf32x2, Vbroadcastf32x2, X86Zmm, X86Mem)            //      AVX512_DQ{kz}
+    1947             :   ASMJIT_INST_2x(vbroadcastf32x4, Vbroadcastf32x4, X86Ymm, X86Mem)            //      AVX512_F{kz}
+    1948             :   ASMJIT_INST_2x(vbroadcastf32x4, Vbroadcastf32x4, X86Zmm, X86Mem)            //      AVX512_F{kz}
+    1949             :   ASMJIT_INST_2x(vbroadcastf32x8, Vbroadcastf32x8, X86Zmm, X86Mem)            //      AVX512_DQ{kz}
+    1950             :   ASMJIT_INST_2x(vbroadcastf64x2, Vbroadcastf64x2, X86Ymm, X86Mem)            //      AVX512_DQ{kz}-VL
+    1951             :   ASMJIT_INST_2x(vbroadcastf64x2, Vbroadcastf64x2, X86Zmm, X86Mem)            //      AVX512_DQ{kz}
+    1952             :   ASMJIT_INST_2x(vbroadcastf64x4, Vbroadcastf64x4, X86Zmm, X86Mem)            //      AVX512_F{kz}
+    1953             :   ASMJIT_INST_2x(vbroadcasti128, Vbroadcasti128, X86Ymm, X86Mem)              // AVX2
+    1954             :   ASMJIT_INST_2x(vbroadcasti32x2, Vbroadcasti32x2, X86Xmm, X86Xmm)            //      AVX512_DQ{kz}-VL
+    1955             :   ASMJIT_INST_2x(vbroadcasti32x2, Vbroadcasti32x2, X86Xmm, X86Mem)            //      AVX512_DQ{kz}-VL
+    1956             :   ASMJIT_INST_2x(vbroadcasti32x2, Vbroadcasti32x2, X86Ymm, X86Xmm)            //      AVX512_DQ{kz}-VL
+    1957             :   ASMJIT_INST_2x(vbroadcasti32x2, Vbroadcasti32x2, X86Ymm, X86Mem)            //      AVX512_DQ{kz}-VL
+    1958             :   ASMJIT_INST_2x(vbroadcasti32x2, Vbroadcasti32x2, X86Zmm, X86Xmm)            //      AVX512_DQ{kz}
+    1959             :   ASMJIT_INST_2x(vbroadcasti32x2, Vbroadcasti32x2, X86Zmm, X86Mem)            //      AVX512_DQ{kz}
+    1960             :   ASMJIT_INST_2x(vbroadcasti32x4, Vbroadcasti32x4, X86Ymm, X86Xmm)            //      AVX512_F{kz}-VL
+    1961             :   ASMJIT_INST_2x(vbroadcasti32x4, Vbroadcasti32x4, X86Ymm, X86Mem)            //      AVX512_F{kz}-VL
+    1962             :   ASMJIT_INST_2x(vbroadcasti32x4, Vbroadcasti32x4, X86Zmm, X86Xmm)            //      AVX512_F{kz}
+    1963             :   ASMJIT_INST_2x(vbroadcasti32x4, Vbroadcasti32x4, X86Zmm, X86Mem)            //      AVX512_F{kz}
+    1964             :   ASMJIT_INST_2x(vbroadcasti32x8, Vbroadcasti32x8, X86Zmm, X86Xmm)            //      AVX512_DQ{kz}
+    1965             :   ASMJIT_INST_2x(vbroadcasti32x8, Vbroadcasti32x8, X86Zmm, X86Mem)            //      AVX512_DQ{kz}
+    1966             :   ASMJIT_INST_2x(vbroadcasti64x2, Vbroadcasti64x2, X86Ymm, X86Xmm)            //      AVX512_DQ{kz}-VL
+    1967             :   ASMJIT_INST_2x(vbroadcasti64x2, Vbroadcasti64x2, X86Ymm, X86Mem)            //      AVX512_DQ{kz}-VL
+    1968             :   ASMJIT_INST_2x(vbroadcasti64x2, Vbroadcasti64x2, X86Zmm, X86Xmm)            //      AVX512_DQ{kz}
+    1969             :   ASMJIT_INST_2x(vbroadcasti64x2, Vbroadcasti64x2, X86Zmm, X86Mem)            //      AVX512_DQ{kz}
+    1970             :   ASMJIT_INST_2x(vbroadcasti64x4, Vbroadcasti64x4, X86Zmm, X86Xmm)            //      AVX512_F{kz}
+    1971             :   ASMJIT_INST_2x(vbroadcasti64x4, Vbroadcasti64x4, X86Zmm, X86Mem)            //      AVX512_F{kz}
+    1972             :   ASMJIT_INST_2x(vbroadcastsd, Vbroadcastsd, X86Ymm, X86Mem)                  // AVX  AVX512_F{kz}-VL
+    1973             :   ASMJIT_INST_2x(vbroadcastsd, Vbroadcastsd, X86Ymm, X86Xmm)                  // AVX2 AVX512_F{kz}-VL
+    1974             :   ASMJIT_INST_2x(vbroadcastsd, Vbroadcastsd, X86Zmm, X86Xmm)                  //      AVX512_F{kz}
+    1975             :   ASMJIT_INST_2x(vbroadcastsd, Vbroadcastsd, X86Zmm, X86Mem)                  //      AVX512_F{kz}
+    1976             :   ASMJIT_INST_2x(vbroadcastss, Vbroadcastss, X86Xmm, X86Mem)                  // AVX  AVX512_F{kz}-VL
+    1977             :   ASMJIT_INST_2x(vbroadcastss, Vbroadcastss, X86Xmm, X86Xmm)                  // AVX2 AVX512_F{kz}-VL
+    1978             :   ASMJIT_INST_2x(vbroadcastss, Vbroadcastss, X86Ymm, X86Mem)                  // AVX  AVX512_F{kz}
+    1979             :   ASMJIT_INST_2x(vbroadcastss, Vbroadcastss, X86Ymm, X86Xmm)                  // AVX2 AVX512_F{kz}
+    1980             :   ASMJIT_INST_2x(vbroadcastss, Vbroadcastss, X86Zmm, X86Xmm)                  //      AVX512_F{kz}-VL
+    1981             :   ASMJIT_INST_2x(vbroadcastss, Vbroadcastss, X86Zmm, X86Mem)                  //      AVX512_F{kz}-VL
+    1982             :   ASMJIT_INST_4i(vcmppd, Vcmppd, X86Xmm, X86Xmm, X86Xmm, Imm)                 // AVX
+    1983             :   ASMJIT_INST_4i(vcmppd, Vcmppd, X86Xmm, X86Xmm, X86Mem, Imm)                 // AVX
+    1984             :   ASMJIT_INST_4i(vcmppd, Vcmppd, X86Ymm, X86Ymm, X86Ymm, Imm)                 // AVX
+    1985             :   ASMJIT_INST_4i(vcmppd, Vcmppd, X86Ymm, X86Ymm, X86Mem, Imm)                 // AVX
+    1986             :   ASMJIT_INST_4i(vcmppd, Vcmppd, X86KReg, X86Xmm, X86Xmm, Imm)                //      AVX512_F{kz|b64}-VL
+    1987             :   ASMJIT_INST_4i(vcmppd, Vcmppd, X86KReg, X86Xmm, X86Mem, Imm)                //      AVX512_F{kz|b64}-VL
+    1988             :   ASMJIT_INST_4i(vcmppd, Vcmppd, X86KReg, X86Ymm, X86Ymm, Imm)                //      AVX512_F{kz|b64}-VL
+    1989             :   ASMJIT_INST_4i(vcmppd, Vcmppd, X86KReg, X86Ymm, X86Mem, Imm)                //      AVX512_F{kz|b64}-VL
+    1990             :   ASMJIT_INST_4i(vcmppd, Vcmppd, X86KReg, X86Zmm, X86Zmm, Imm)                //      AVX512_F{kz|sae|b64}
+    1991             :   ASMJIT_INST_4i(vcmppd, Vcmppd, X86KReg, X86Zmm, X86Mem, Imm)                //      AVX512_F{kz|sae|b64}
+    1992             :   ASMJIT_INST_4i(vcmpps, Vcmpps, X86Xmm, X86Xmm, X86Xmm, Imm)                 // AVX
+    1993             :   ASMJIT_INST_4i(vcmpps, Vcmpps, X86Xmm, X86Xmm, X86Mem, Imm)                 // AVX
+    1994             :   ASMJIT_INST_4i(vcmpps, Vcmpps, X86Ymm, X86Ymm, X86Ymm, Imm)                 // AVX
+    1995             :   ASMJIT_INST_4i(vcmpps, Vcmpps, X86Ymm, X86Ymm, X86Mem, Imm)                 // AVX
+    1996             :   ASMJIT_INST_4i(vcmpps, Vcmpps, X86KReg, X86Xmm, X86Xmm, Imm)                //      AVX512_F{kz|b32}-VL
+    1997             :   ASMJIT_INST_4i(vcmpps, Vcmpps, X86KReg, X86Xmm, X86Mem, Imm)                //      AVX512_F{kz|b32}-VL
+    1998             :   ASMJIT_INST_4i(vcmpps, Vcmpps, X86KReg, X86Ymm, X86Ymm, Imm)                //      AVX512_F{kz|b32}-VL
+    1999             :   ASMJIT_INST_4i(vcmpps, Vcmpps, X86KReg, X86Ymm, X86Mem, Imm)                //      AVX512_F{kz|b32}-VL
+    2000             :   ASMJIT_INST_4i(vcmpps, Vcmpps, X86KReg, X86Zmm, X86Zmm, Imm)                //      AVX512_F{kz|sae|b32}
+    2001             :   ASMJIT_INST_4i(vcmpps, Vcmpps, X86KReg, X86Zmm, X86Mem, Imm)                //      AVX512_F{kz|sae|b32}
+    2002             :   ASMJIT_INST_4i(vcmpsd, Vcmpsd, X86Xmm, X86Xmm, X86Xmm, Imm)                 // AVX
+    2003             :   ASMJIT_INST_4i(vcmpsd, Vcmpsd, X86Xmm, X86Xmm, X86Mem, Imm)                 // AVX
+    2004             :   ASMJIT_INST_4i(vcmpsd, Vcmpsd, X86KReg, X86Xmm, X86Xmm, Imm)                //      AVX512_F{kz|sae}
+    2005             :   ASMJIT_INST_4i(vcmpsd, Vcmpsd, X86KReg, X86Xmm, X86Mem, Imm)                //      AVX512_F{kz|sae}
+    2006             :   ASMJIT_INST_4i(vcmpss, Vcmpss, X86Xmm, X86Xmm, X86Xmm, Imm)                 // AVX
+    2007             :   ASMJIT_INST_4i(vcmpss, Vcmpss, X86Xmm, X86Xmm, X86Mem, Imm)                 // AVX
+    2008             :   ASMJIT_INST_4i(vcmpss, Vcmpss, X86KReg, X86Xmm, X86Xmm, Imm)                //      AVX512_F{kz|sae}
+    2009             :   ASMJIT_INST_4i(vcmpss, Vcmpss, X86KReg, X86Xmm, X86Mem, Imm)                //      AVX512_F{kz|sae}
+    2010             :   ASMJIT_INST_2x(vcomisd, Vcomisd, X86Xmm, X86Xmm)                            // AVX  AVX512_F{sae}
+    2011             :   ASMJIT_INST_2x(vcomisd, Vcomisd, X86Xmm, X86Mem)                            // AVX  AVX512_F{sae}
+    2012             :   ASMJIT_INST_2x(vcomiss, Vcomiss, X86Xmm, X86Xmm)                            // AVX  AVX512_F{sae}
+    2013             :   ASMJIT_INST_2x(vcomiss, Vcomiss, X86Xmm, X86Mem)                            // AVX  AVX512_F{sae}
+    2014             :   ASMJIT_INST_2x(vcompresspd, Vcompresspd, X86Xmm, X86Xmm)                    //      AVX512_F{kz}-VL
+    2015             :   ASMJIT_INST_2x(vcompresspd, Vcompresspd, X86Mem, X86Xmm)                    //      AVX512_F{kz}-VL
+    2016             :   ASMJIT_INST_2x(vcompresspd, Vcompresspd, X86Ymm, X86Ymm)                    //      AVX512_F{kz}-VL
+    2017             :   ASMJIT_INST_2x(vcompresspd, Vcompresspd, X86Mem, X86Ymm)                    //      AVX512_F{kz}-VL
+    2018             :   ASMJIT_INST_2x(vcompresspd, Vcompresspd, X86Zmm, X86Zmm)                    //      AVX512_F{kz}
+    2019             :   ASMJIT_INST_2x(vcompresspd, Vcompresspd, X86Mem, X86Zmm)                    //      AVX512_F{kz}
+    2020             :   ASMJIT_INST_2x(vcompressps, Vcompressps, X86Xmm, X86Xmm)                    //      AVX512_F{kz}-VL
+    2021             :   ASMJIT_INST_2x(vcompressps, Vcompressps, X86Mem, X86Xmm)                    //      AVX512_F{kz}-VL
+    2022             :   ASMJIT_INST_2x(vcompressps, Vcompressps, X86Ymm, X86Ymm)                    //      AVX512_F{kz}-VL
+    2023             :   ASMJIT_INST_2x(vcompressps, Vcompressps, X86Mem, X86Ymm)                    //      AVX512_F{kz}-VL
+    2024             :   ASMJIT_INST_2x(vcompressps, Vcompressps, X86Zmm, X86Zmm)                    //      AVX512_F{kz}
+    2025             :   ASMJIT_INST_2x(vcompressps, Vcompressps, X86Mem, X86Zmm)                    //      AVX512_F{kz}
+    2026             :   ASMJIT_INST_2x(vcvtdq2pd, Vcvtdq2pd, X86Xmm, X86Xmm)                        // AVX  AVX512_F{kz|b32}-VL
+    2027             :   ASMJIT_INST_2x(vcvtdq2pd, Vcvtdq2pd, X86Xmm, X86Mem)                        // AVX  AVX512_F{kz|b32}-VL
+    2028             :   ASMJIT_INST_2x(vcvtdq2pd, Vcvtdq2pd, X86Ymm, X86Xmm)                        // AVX  AVX512_F{kz|b32}-VL
+    2029             :   ASMJIT_INST_2x(vcvtdq2pd, Vcvtdq2pd, X86Ymm, X86Mem)                        // AVX  AVX512_F{kz|b32}-VL
+    2030             :   ASMJIT_INST_2x(vcvtdq2pd, Vcvtdq2pd, X86Zmm, X86Ymm)                        //      AVX512_F{kz|b32}
+    2031             :   ASMJIT_INST_2x(vcvtdq2pd, Vcvtdq2pd, X86Zmm, X86Mem)                        //      AVX512_F{kz|b32}
+    2032             :   ASMJIT_INST_2x(vcvtdq2ps, Vcvtdq2ps, X86Xmm, X86Xmm)                        // AVX  AVX512_F{kz|b32}-VL
+    2033             :   ASMJIT_INST_2x(vcvtdq2ps, Vcvtdq2ps, X86Xmm, X86Mem)                        // AVX  AVX512_F{kz|b32}-VL
+    2034             :   ASMJIT_INST_2x(vcvtdq2ps, Vcvtdq2ps, X86Ymm, X86Ymm)                        // AVX  AVX512_F{kz|b32}-VL
+    2035             :   ASMJIT_INST_2x(vcvtdq2ps, Vcvtdq2ps, X86Ymm, X86Mem)                        // AVX  AVX512_F{kz|b32}-VL
+    2036             :   ASMJIT_INST_2x(vcvtdq2ps, Vcvtdq2ps, X86Zmm, X86Zmm)                        //      AVX512_F{kz|er|b32}
+    2037             :   ASMJIT_INST_2x(vcvtdq2ps, Vcvtdq2ps, X86Zmm, X86Mem)                        //      AVX512_F{kz|er|b32}
+    2038             :   ASMJIT_INST_2x(vcvtpd2dq, Vcvtpd2dq, X86Xmm, X86Xmm)                        // AVX  AVX512_F{kz|b64}-VL
+    2039             :   ASMJIT_INST_2x(vcvtpd2dq, Vcvtpd2dq, X86Xmm, X86Mem)                        // AVX  AVX512_F{kz|b64}-VL
+    2040             :   ASMJIT_INST_2x(vcvtpd2dq, Vcvtpd2dq, X86Xmm, X86Ymm)                        // AVX  AVX512_F{kz|b64}-VL
+    2041             :   ASMJIT_INST_2x(vcvtpd2dq, Vcvtpd2dq, X86Ymm, X86Zmm)                        //      AVX512_F{kz|er|b64}
+    2042             :   ASMJIT_INST_2x(vcvtpd2dq, Vcvtpd2dq, X86Ymm, X86Mem)                        //      AVX512_F{kz|er|b64}
+    2043             :   ASMJIT_INST_2x(vcvtpd2ps, Vcvtpd2ps, X86Xmm, X86Xmm)                        // AVX
+    2044             :   ASMJIT_INST_2x(vcvtpd2ps, Vcvtpd2ps, X86Xmm, X86Mem)                        // AVX
+    2045             :   ASMJIT_INST_2x(vcvtpd2ps, Vcvtpd2ps, X86Xmm, X86Ymm)                        // AVX
+    2046             :   ASMJIT_INST_2x(vcvtpd2qq, Vcvtpd2qq, X86Xmm, X86Xmm)                        //      AVX512_DQ{kz|b64}-VL
+    2047             :   ASMJIT_INST_2x(vcvtpd2qq, Vcvtpd2qq, X86Xmm, X86Mem)                        //      AVX512_DQ{kz|b64}-VL
+    2048             :   ASMJIT_INST_2x(vcvtpd2qq, Vcvtpd2qq, X86Ymm, X86Ymm)                        //      AVX512_DQ{kz|b64}-VL
+    2049             :   ASMJIT_INST_2x(vcvtpd2qq, Vcvtpd2qq, X86Ymm, X86Mem)                        //      AVX512_DQ{kz|b64}-VL
+    2050             :   ASMJIT_INST_2x(vcvtpd2qq, Vcvtpd2qq, X86Zmm, X86Zmm)                        //      AVX512_DQ{kz|er|b64}
+    2051             :   ASMJIT_INST_2x(vcvtpd2qq, Vcvtpd2qq, X86Zmm, X86Mem)                        //      AVX512_DQ{kz|er|b64}
+    2052             :   ASMJIT_INST_2x(vcvtpd2udq, Vcvtpd2udq, X86Xmm, X86Xmm)                      //      AVX512_F{kz|b64}-VL
+    2053             :   ASMJIT_INST_2x(vcvtpd2udq, Vcvtpd2udq, X86Xmm, X86Mem)                      //      AVX512_F{kz|b64}-VL
+    2054             :   ASMJIT_INST_2x(vcvtpd2udq, Vcvtpd2udq, X86Xmm, X86Ymm)                      //      AVX512_F{kz|b64}-VL
+    2055             :   ASMJIT_INST_2x(vcvtpd2udq, Vcvtpd2udq, X86Ymm, X86Zmm)                      //      AVX512_F{kz|er|b64}
+    2056             :   ASMJIT_INST_2x(vcvtpd2udq, Vcvtpd2udq, X86Ymm, X86Mem)                      //      AVX512_F{kz|er|b64}
+    2057             :   ASMJIT_INST_2x(vcvtpd2uqq, Vcvtpd2uqq, X86Xmm, X86Xmm)                      //      AVX512_DQ{kz|b64}-VL
+    2058             :   ASMJIT_INST_2x(vcvtpd2uqq, Vcvtpd2uqq, X86Xmm, X86Mem)                      //      AVX512_DQ{kz|b64}-VL
+    2059             :   ASMJIT_INST_2x(vcvtpd2uqq, Vcvtpd2uqq, X86Ymm, X86Ymm)                      //      AVX512_DQ{kz|b64}-VL
+    2060             :   ASMJIT_INST_2x(vcvtpd2uqq, Vcvtpd2uqq, X86Ymm, X86Mem)                      //      AVX512_DQ{kz|b64}-VL
+    2061             :   ASMJIT_INST_2x(vcvtpd2uqq, Vcvtpd2uqq, X86Zmm, X86Zmm)                      //      AVX512_DQ{kz|er|b64}
+    2062             :   ASMJIT_INST_2x(vcvtpd2uqq, Vcvtpd2uqq, X86Zmm, X86Mem)                      //      AVX512_DQ{kz|er|b64}
+    2063             :   ASMJIT_INST_2x(vcvtph2ps, Vcvtph2ps, X86Xmm, X86Xmm)                        // F16C AVX512_F{kz}-VL
+    2064             :   ASMJIT_INST_2x(vcvtph2ps, Vcvtph2ps, X86Xmm, X86Mem)                        // F16C AVX512_F{kz}-VL
+    2065             :   ASMJIT_INST_2x(vcvtph2ps, Vcvtph2ps, X86Ymm, X86Xmm)                        // F16C AVX512_F{kz}-VL
+    2066             :   ASMJIT_INST_2x(vcvtph2ps, Vcvtph2ps, X86Ymm, X86Mem)                        // F16C AVX512_F{kz}-VL
+    2067             :   ASMJIT_INST_2x(vcvtph2ps, Vcvtph2ps, X86Zmm, X86Ymm)                        //      AVX512_F{kz|sae}
+    2068             :   ASMJIT_INST_2x(vcvtph2ps, Vcvtph2ps, X86Zmm, X86Mem)                        //      AVX512_F{kz|sae}
+    2069             :   ASMJIT_INST_2x(vcvtps2dq, Vcvtps2dq, X86Xmm, X86Xmm)                        // AVX  AVX512_F{kz|b32}-VL
+    2070             :   ASMJIT_INST_2x(vcvtps2dq, Vcvtps2dq, X86Xmm, X86Mem)                        // AVX  AVX512_F{kz|b32}-VL
+    2071             :   ASMJIT_INST_2x(vcvtps2dq, Vcvtps2dq, X86Ymm, X86Ymm)                        // AVX  AVX512_F{kz|b32}-VL
+    2072             :   ASMJIT_INST_2x(vcvtps2dq, Vcvtps2dq, X86Ymm, X86Mem)                        // AVX  AVX512_F{kz|b32}-VL
+    2073             :   ASMJIT_INST_2x(vcvtps2dq, Vcvtps2dq, X86Zmm, X86Zmm)                        //      AVX512_F{kz|er|b32}
+    2074             :   ASMJIT_INST_2x(vcvtps2dq, Vcvtps2dq, X86Zmm, X86Mem)                        //      AVX512_F{kz|er|b32}
+    2075             :   ASMJIT_INST_2x(vcvtps2pd, Vcvtps2pd, X86Xmm, X86Xmm)                        // AVX  AVX512_F{kz|b32}-VL
+    2076             :   ASMJIT_INST_2x(vcvtps2pd, Vcvtps2pd, X86Xmm, X86Mem)                        // AVX  AVX512_F{kz|b32}-VL
+    2077             :   ASMJIT_INST_2x(vcvtps2pd, Vcvtps2pd, X86Ymm, X86Xmm)                        // AVX  AVX512_F{kz|b32}-VL
+    2078             :   ASMJIT_INST_2x(vcvtps2pd, Vcvtps2pd, X86Ymm, X86Mem)                        // AVX  AVX512_F{kz|b32}-VL
+    2079             :   ASMJIT_INST_2x(vcvtps2pd, Vcvtps2pd, X86Zmm, X86Ymm)                        //      AVX512_F{kz|er|b32}
+    2080             :   ASMJIT_INST_2x(vcvtps2pd, Vcvtps2pd, X86Zmm, X86Mem)                        //      AVX512_F{kz|er|b32}
+    2081             :   ASMJIT_INST_3i(vcvtps2ph, Vcvtps2ph, X86Xmm, X86Xmm, Imm)                   // F16C AVX512_F{kz}-VL
+    2082             :   ASMJIT_INST_3i(vcvtps2ph, Vcvtps2ph, X86Mem, X86Xmm, Imm)                   // F16C AVX512_F{kz}-VL
+    2083             :   ASMJIT_INST_3i(vcvtps2ph, Vcvtps2ph, X86Xmm, X86Ymm, Imm)                   // F16C AVX512_F{kz}-VL
+    2084             :   ASMJIT_INST_3i(vcvtps2ph, Vcvtps2ph, X86Mem, X86Ymm, Imm)                   // F16C AVX512_F{kz}-VL
+    2085             :   ASMJIT_INST_3i(vcvtps2ph, Vcvtps2ph, X86Ymm, X86Zmm, Imm)                   //      AVX512_F{kz|sae}
+    2086             :   ASMJIT_INST_3i(vcvtps2ph, Vcvtps2ph, X86Mem, X86Zmm, Imm)                   //      AVX512_F{kz|sae}
+    2087             :   ASMJIT_INST_2x(vcvtps2qq, Vcvtps2qq, X86Xmm, X86Xmm)                        //      AVX512_DQ{kz|b32}-VL
+    2088             :   ASMJIT_INST_2x(vcvtps2qq, Vcvtps2qq, X86Xmm, X86Mem)                        //      AVX512_DQ{kz|b32}-VL
+    2089             :   ASMJIT_INST_2x(vcvtps2qq, Vcvtps2qq, X86Ymm, X86Xmm)                        //      AVX512_DQ{kz|b32}-VL
+    2090             :   ASMJIT_INST_2x(vcvtps2qq, Vcvtps2qq, X86Ymm, X86Mem)                        //      AVX512_DQ{kz|b32}-VL
+    2091             :   ASMJIT_INST_2x(vcvtps2qq, Vcvtps2qq, X86Zmm, X86Ymm)                        //      AVX512_DQ{kz|er|b32}
+    2092             :   ASMJIT_INST_2x(vcvtps2qq, Vcvtps2qq, X86Zmm, X86Mem)                        //      AVX512_DQ{kz|er|b32}
+    2093             :   ASMJIT_INST_2x(vcvtps2udq, Vcvtps2udq, X86Xmm, X86Xmm)                      //      AVX512_F{kz|b32}-VL
+    2094             :   ASMJIT_INST_2x(vcvtps2udq, Vcvtps2udq, X86Xmm, X86Mem)                      //      AVX512_F{kz|b32}-VL
+    2095             :   ASMJIT_INST_2x(vcvtps2udq, Vcvtps2udq, X86Ymm, X86Ymm)                      //      AVX512_F{kz|b32}-VL
+    2096             :   ASMJIT_INST_2x(vcvtps2udq, Vcvtps2udq, X86Ymm, X86Mem)                      //      AVX512_F{kz|b32}-VL
+    2097             :   ASMJIT_INST_2x(vcvtps2udq, Vcvtps2udq, X86Zmm, X86Zmm)                      //      AVX512_F{kz|er|b32}
+    2098             :   ASMJIT_INST_2x(vcvtps2udq, Vcvtps2udq, X86Zmm, X86Mem)                      //      AVX512_F{kz|er|b32}
+    2099             :   ASMJIT_INST_2x(vcvtps2uqq, Vcvtps2uqq, X86Xmm, X86Xmm)                      //      AVX512_DQ{kz|b32}-VL
+    2100             :   ASMJIT_INST_2x(vcvtps2uqq, Vcvtps2uqq, X86Xmm, X86Mem)                      //      AVX512_DQ{kz|b32}-VL
+    2101             :   ASMJIT_INST_2x(vcvtps2uqq, Vcvtps2uqq, X86Ymm, X86Xmm)                      //      AVX512_DQ{kz|b32}-VL
+    2102             :   ASMJIT_INST_2x(vcvtps2uqq, Vcvtps2uqq, X86Ymm, X86Mem)                      //      AVX512_DQ{kz|b32}-VL
+    2103             :   ASMJIT_INST_2x(vcvtps2uqq, Vcvtps2uqq, X86Zmm, X86Ymm)                      //      AVX512_DQ{kz|er|b32}
+    2104             :   ASMJIT_INST_2x(vcvtps2uqq, Vcvtps2uqq, X86Zmm, X86Mem)                      //      AVX512_DQ{kz|er|b32}
+    2105             :   ASMJIT_INST_2x(vcvtqq2pd, Vcvtqq2pd, X86Xmm, X86Xmm)                        //      AVX512_DQ{kz|b64}-VL
+    2106             :   ASMJIT_INST_2x(vcvtqq2pd, Vcvtqq2pd, X86Xmm, X86Mem)                        //      AVX512_DQ{kz|b64}-VL
+    2107             :   ASMJIT_INST_2x(vcvtqq2pd, Vcvtqq2pd, X86Ymm, X86Ymm)                        //      AVX512_DQ{kz|b64}-VL
+    2108             :   ASMJIT_INST_2x(vcvtqq2pd, Vcvtqq2pd, X86Ymm, X86Mem)                        //      AVX512_DQ{kz|b64}-VL
+    2109             :   ASMJIT_INST_2x(vcvtqq2pd, Vcvtqq2pd, X86Zmm, X86Zmm)                        //      AVX512_DQ{kz|er|b64}
+    2110             :   ASMJIT_INST_2x(vcvtqq2pd, Vcvtqq2pd, X86Zmm, X86Mem)                        //      AVX512_DQ{kz|er|b64}
+    2111             :   ASMJIT_INST_2x(vcvtqq2ps, Vcvtqq2ps, X86Xmm, X86Xmm)                        //      AVX512_DQ{kz|b64}-VL
+    2112             :   ASMJIT_INST_2x(vcvtqq2ps, Vcvtqq2ps, X86Xmm, X86Mem)                        //      AVX512_DQ{kz|b64}-VL
+    2113             :   ASMJIT_INST_2x(vcvtqq2ps, Vcvtqq2ps, X86Xmm, X86Ymm)                        //      AVX512_DQ{kz|b64}-VL
+    2114             :   ASMJIT_INST_2x(vcvtqq2ps, Vcvtqq2ps, X86Ymm, X86Zmm)                        //      AVX512_DQ{kz|er|b64}
+    2115             :   ASMJIT_INST_2x(vcvtqq2ps, Vcvtqq2ps, X86Ymm, X86Mem)                        //      AVX512_DQ{kz|er|b64}
+    2116             :   ASMJIT_INST_2x(vcvtsd2si, Vcvtsd2si, X86Gp, X86Xmm)                         // AVX  AVX512_F{er}
+    2117             :   ASMJIT_INST_2x(vcvtsd2si, Vcvtsd2si, X86Gp, X86Mem)                         // AVX  AVX512_F{er}
+    2118             :   ASMJIT_INST_3x(vcvtsd2ss, Vcvtsd2ss, X86Xmm, X86Xmm, X86Xmm)                // AVX  AVX512_F{kz|er}
+    2119             :   ASMJIT_INST_3x(vcvtsd2ss, Vcvtsd2ss, X86Xmm, X86Xmm, X86Mem)                // AVX  AVX512_F{kz|er}
+    2120             :   ASMJIT_INST_2x(vcvtsd2usi, Vcvtsd2usi, X86Gp, X86Xmm)                       //      AVX512_F{er}
+    2121             :   ASMJIT_INST_2x(vcvtsd2usi, Vcvtsd2usi, X86Gp, X86Mem)                       //      AVX512_F{er}
+    2122             :   ASMJIT_INST_3x(vcvtsi2sd, Vcvtsi2sd, X86Xmm, X86Xmm, X86Gp)                 // AVX  AVX512_F{er}
+    2123             :   ASMJIT_INST_3x(vcvtsi2sd, Vcvtsi2sd, X86Xmm, X86Xmm, X86Mem)                // AVX  AVX512_F{er}
+    2124             :   ASMJIT_INST_3x(vcvtsi2ss, Vcvtsi2ss, X86Xmm, X86Xmm, X86Gp)                 // AVX  AVX512_F{er}
+    2125             :   ASMJIT_INST_3x(vcvtsi2ss, Vcvtsi2ss, X86Xmm, X86Xmm, X86Mem)                // AVX  AVX512_F{er}
+    2126             :   ASMJIT_INST_3x(vcvtss2sd, Vcvtss2sd, X86Xmm, X86Xmm, X86Xmm)                // AVX  AVX512_F{kz|sae}
+    2127             :   ASMJIT_INST_3x(vcvtss2sd, Vcvtss2sd, X86Xmm, X86Xmm, X86Mem)                // AVX  AVX512_F{kz|sae}
+    2128             :   ASMJIT_INST_2x(vcvtss2si, Vcvtss2si, X86Gp, X86Xmm)                         // AVX  AVX512_F{er}
+    2129             :   ASMJIT_INST_2x(vcvtss2si, Vcvtss2si, X86Gp, X86Mem)                         // AVX  AVX512_F{er}
+    2130             :   ASMJIT_INST_2x(vcvtss2usi, Vcvtss2usi, X86Gp, X86Xmm)                       //      AVX512_F{er}
+    2131             :   ASMJIT_INST_2x(vcvtss2usi, Vcvtss2usi, X86Gp, X86Mem)                       //      AVX512_F{er}
+    2132             :   ASMJIT_INST_2x(vcvttpd2dq, Vcvttpd2dq, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|b64}-VL
+    2133             :   ASMJIT_INST_2x(vcvttpd2dq, Vcvttpd2dq, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|b64}-VL
+    2134             :   ASMJIT_INST_2x(vcvttpd2dq, Vcvttpd2dq, X86Xmm, X86Ymm)                      // AVX  AVX512_F{kz|b64}-VL
+    2135             :   ASMJIT_INST_2x(vcvttpd2dq, Vcvttpd2dq, X86Ymm, X86Zmm)                      //      AVX512_F{kz|sae|b64}
+    2136             :   ASMJIT_INST_2x(vcvttpd2dq, Vcvttpd2dq, X86Ymm, X86Mem)                      //      AVX512_F{kz|sae|b64}
+    2137             :   ASMJIT_INST_2x(vcvttpd2qq, Vcvttpd2qq, X86Xmm, X86Xmm)                      //      AVX512_F{kz|b64}-VL
+    2138             :   ASMJIT_INST_2x(vcvttpd2qq, Vcvttpd2qq, X86Xmm, X86Mem)                      //      AVX512_F{kz|b64}-VL
+    2139             :   ASMJIT_INST_2x(vcvttpd2qq, Vcvttpd2qq, X86Ymm, X86Ymm)                      //      AVX512_F{kz|b64}-VL
+    2140             :   ASMJIT_INST_2x(vcvttpd2qq, Vcvttpd2qq, X86Ymm, X86Mem)                      //      AVX512_F{kz|b64}-VL
+    2141             :   ASMJIT_INST_2x(vcvttpd2qq, Vcvttpd2qq, X86Zmm, X86Zmm)                      //      AVX512_F{kz|sae|b64}
+    2142             :   ASMJIT_INST_2x(vcvttpd2qq, Vcvttpd2qq, X86Zmm, X86Mem)                      //      AVX512_F{kz|sae|b64}
+    2143             :   ASMJIT_INST_2x(vcvttpd2udq, Vcvttpd2udq, X86Xmm, X86Xmm)                    //      AVX512_F{kz|b64}-VL
+    2144             :   ASMJIT_INST_2x(vcvttpd2udq, Vcvttpd2udq, X86Xmm, X86Mem)                    //      AVX512_F{kz|b64}-VL
+    2145             :   ASMJIT_INST_2x(vcvttpd2udq, Vcvttpd2udq, X86Xmm, X86Ymm)                    //      AVX512_F{kz|b64}-VL
+    2146             :   ASMJIT_INST_2x(vcvttpd2udq, Vcvttpd2udq, X86Ymm, X86Zmm)                    //      AVX512_F{kz|sae|b64}
+    2147             :   ASMJIT_INST_2x(vcvttpd2udq, Vcvttpd2udq, X86Ymm, X86Mem)                    //      AVX512_F{kz|sae|b64}
+    2148             :   ASMJIT_INST_2x(vcvttpd2uqq, Vcvttpd2uqq, X86Xmm, X86Xmm)                    //      AVX512_DQ{kz|b64}-VL
+    2149             :   ASMJIT_INST_2x(vcvttpd2uqq, Vcvttpd2uqq, X86Xmm, X86Mem)                    //      AVX512_DQ{kz|b64}-VL
+    2150             :   ASMJIT_INST_2x(vcvttpd2uqq, Vcvttpd2uqq, X86Ymm, X86Ymm)                    //      AVX512_DQ{kz|b64}-VL
+    2151             :   ASMJIT_INST_2x(vcvttpd2uqq, Vcvttpd2uqq, X86Ymm, X86Mem)                    //      AVX512_DQ{kz|b64}-VL
+    2152             :   ASMJIT_INST_2x(vcvttpd2uqq, Vcvttpd2uqq, X86Zmm, X86Zmm)                    //      AVX512_DQ{kz|sae|b64}
+    2153             :   ASMJIT_INST_2x(vcvttpd2uqq, Vcvttpd2uqq, X86Zmm, X86Mem)                    //      AVX512_DQ{kz|sae|b64}
+    2154             :   ASMJIT_INST_2x(vcvttps2dq, Vcvttps2dq, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|b32}-VL
+    2155             :   ASMJIT_INST_2x(vcvttps2dq, Vcvttps2dq, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|b32}-VL
+    2156             :   ASMJIT_INST_2x(vcvttps2dq, Vcvttps2dq, X86Ymm, X86Ymm)                      // AVX  AVX512_F{kz|b32}-VL
+    2157             :   ASMJIT_INST_2x(vcvttps2dq, Vcvttps2dq, X86Ymm, X86Mem)                      // AVX  AVX512_F{kz|b32}-VL
+    2158             :   ASMJIT_INST_2x(vcvttps2dq, Vcvttps2dq, X86Zmm, X86Zmm)                      //      AVX512_F{kz|sae|b32}
+    2159             :   ASMJIT_INST_2x(vcvttps2dq, Vcvttps2dq, X86Zmm, X86Mem)                      //      AVX512_F{kz|sae|b32}
+    2160             :   ASMJIT_INST_2x(vcvttps2qq, Vcvttps2qq, X86Xmm, X86Xmm)                      //      AVX512_DQ{kz|b32}-VL
+    2161             :   ASMJIT_INST_2x(vcvttps2qq, Vcvttps2qq, X86Xmm, X86Mem)                      //      AVX512_DQ{kz|b32}-VL
+    2162             :   ASMJIT_INST_2x(vcvttps2qq, Vcvttps2qq, X86Ymm, X86Xmm)                      //      AVX512_DQ{kz|b32}-VL
+    2163             :   ASMJIT_INST_2x(vcvttps2qq, Vcvttps2qq, X86Ymm, X86Mem)                      //      AVX512_DQ{kz|b32}-VL
+    2164             :   ASMJIT_INST_2x(vcvttps2qq, Vcvttps2qq, X86Zmm, X86Ymm)                      //      AVX512_DQ{kz|sae|b32}
+    2165             :   ASMJIT_INST_2x(vcvttps2qq, Vcvttps2qq, X86Zmm, X86Mem)                      //      AVX512_DQ{kz|sae|b32}
+    2166             :   ASMJIT_INST_2x(vcvttps2udq, Vcvttps2udq, X86Xmm, X86Xmm)                    //      AVX512_F{kz|b32}-VL
+    2167             :   ASMJIT_INST_2x(vcvttps2udq, Vcvttps2udq, X86Xmm, X86Mem)                    //      AVX512_F{kz|b32}-VL
+    2168             :   ASMJIT_INST_2x(vcvttps2udq, Vcvttps2udq, X86Ymm, X86Ymm)                    //      AVX512_F{kz|b32}-VL
+    2169             :   ASMJIT_INST_2x(vcvttps2udq, Vcvttps2udq, X86Ymm, X86Mem)                    //      AVX512_F{kz|b32}-VL
+    2170             :   ASMJIT_INST_2x(vcvttps2udq, Vcvttps2udq, X86Zmm, X86Zmm)                    //      AVX512_F{kz|sae|b32}
+    2171             :   ASMJIT_INST_2x(vcvttps2udq, Vcvttps2udq, X86Zmm, X86Mem)                    //      AVX512_F{kz|sae|b32}
+    2172             :   ASMJIT_INST_2x(vcvttps2uqq, Vcvttps2uqq, X86Xmm, X86Xmm)                    //      AVX512_DQ{kz|b32}-VL
+    2173             :   ASMJIT_INST_2x(vcvttps2uqq, Vcvttps2uqq, X86Xmm, X86Mem)                    //      AVX512_DQ{kz|b32}-VL
+    2174             :   ASMJIT_INST_2x(vcvttps2uqq, Vcvttps2uqq, X86Ymm, X86Xmm)                    //      AVX512_DQ{kz|b32}-VL
+    2175             :   ASMJIT_INST_2x(vcvttps2uqq, Vcvttps2uqq, X86Ymm, X86Mem)                    //      AVX512_DQ{kz|b32}-VL
+    2176             :   ASMJIT_INST_2x(vcvttps2uqq, Vcvttps2uqq, X86Zmm, X86Ymm)                    //      AVX512_DQ{kz|sae|b32}
+    2177             :   ASMJIT_INST_2x(vcvttps2uqq, Vcvttps2uqq, X86Zmm, X86Mem)                    //      AVX512_DQ{kz|sae|b32}
+    2178             :   ASMJIT_INST_2x(vcvttsd2si, Vcvttsd2si, X86Gp, X86Xmm)                       // AVX  AVX512_F{sae}
+    2179             :   ASMJIT_INST_2x(vcvttsd2si, Vcvttsd2si, X86Gp, X86Mem)                       // AVX  AVX512_F{sae}
+    2180             :   ASMJIT_INST_2x(vcvttsd2usi, Vcvttsd2usi, X86Gp, X86Xmm)                     //      AVX512_F{sae}
+    2181             :   ASMJIT_INST_2x(vcvttsd2usi, Vcvttsd2usi, X86Gp, X86Mem)                     //      AVX512_F{sae}
+    2182             :   ASMJIT_INST_2x(vcvttss2si, Vcvttss2si, X86Gp, X86Xmm)                       // AVX  AVX512_F{sae}
+    2183             :   ASMJIT_INST_2x(vcvttss2si, Vcvttss2si, X86Gp, X86Mem)                       // AVX  AVX512_F{sae}
+    2184             :   ASMJIT_INST_2x(vcvttss2usi, Vcvttss2usi, X86Gp, X86Xmm)                     //      AVX512_F{sae}
+    2185             :   ASMJIT_INST_2x(vcvttss2usi, Vcvttss2usi, X86Gp, X86Mem)                     //      AVX512_F{sae}
+    2186             :   ASMJIT_INST_2x(vcvtudq2pd, Vcvtudq2pd, X86Xmm, X86Xmm)                      //      AVX512_F{kz|b32}-VL
+    2187             :   ASMJIT_INST_2x(vcvtudq2pd, Vcvtudq2pd, X86Xmm, X86Mem)                      //      AVX512_F{kz|b32}-VL
+    2188             :   ASMJIT_INST_2x(vcvtudq2pd, Vcvtudq2pd, X86Ymm, X86Xmm)                      //      AVX512_F{kz|b32}-VL
+    2189             :   ASMJIT_INST_2x(vcvtudq2pd, Vcvtudq2pd, X86Ymm, X86Mem)                      //      AVX512_F{kz|b32}-VL
+    2190             :   ASMJIT_INST_2x(vcvtudq2pd, Vcvtudq2pd, X86Zmm, X86Ymm)                      //      AVX512_F{kz|b32}
+    2191             :   ASMJIT_INST_2x(vcvtudq2pd, Vcvtudq2pd, X86Zmm, X86Mem)                      //      AVX512_F{kz|b32}
+    2192             :   ASMJIT_INST_2x(vcvtudq2ps, Vcvtudq2ps, X86Xmm, X86Xmm)                      //      AVX512_F{kz|b32}-VL
+    2193             :   ASMJIT_INST_2x(vcvtudq2ps, Vcvtudq2ps, X86Xmm, X86Mem)                      //      AVX512_F{kz|b32}-VL
+    2194             :   ASMJIT_INST_2x(vcvtudq2ps, Vcvtudq2ps, X86Ymm, X86Ymm)                      //      AVX512_F{kz|b32}-VL
+    2195             :   ASMJIT_INST_2x(vcvtudq2ps, Vcvtudq2ps, X86Ymm, X86Mem)                      //      AVX512_F{kz|b32}-VL
+    2196             :   ASMJIT_INST_2x(vcvtudq2ps, Vcvtudq2ps, X86Zmm, X86Zmm)                      //      AVX512_F{kz|er|b32}
+    2197             :   ASMJIT_INST_2x(vcvtudq2ps, Vcvtudq2ps, X86Zmm, X86Mem)                      //      AVX512_F{kz|er|b32}
+    2198             :   ASMJIT_INST_2x(vcvtuqq2pd, Vcvtuqq2pd, X86Xmm, X86Xmm)                      //      AVX512_DQ{kz|b64}-VL
+    2199             :   ASMJIT_INST_2x(vcvtuqq2pd, Vcvtuqq2pd, X86Xmm, X86Mem)                      //      AVX512_DQ{kz|b64}-VL
+    2200             :   ASMJIT_INST_2x(vcvtuqq2pd, Vcvtuqq2pd, X86Ymm, X86Ymm)                      //      AVX512_DQ{kz|b64}-VL
+    2201             :   ASMJIT_INST_2x(vcvtuqq2pd, Vcvtuqq2pd, X86Ymm, X86Mem)                      //      AVX512_DQ{kz|b64}-VL
+    2202             :   ASMJIT_INST_2x(vcvtuqq2pd, Vcvtuqq2pd, X86Zmm, X86Zmm)                      //      AVX512_DQ{kz|er|b64}
+    2203             :   ASMJIT_INST_2x(vcvtuqq2pd, Vcvtuqq2pd, X86Zmm, X86Mem)                      //      AVX512_DQ{kz|er|b64}
+    2204             :   ASMJIT_INST_2x(vcvtuqq2ps, Vcvtuqq2ps, X86Xmm, X86Xmm)                      //      AVX512_DQ{kz|b64}-VL
+    2205             :   ASMJIT_INST_2x(vcvtuqq2ps, Vcvtuqq2ps, X86Xmm, X86Mem)                      //      AVX512_DQ{kz|b64}-VL
+    2206             :   ASMJIT_INST_2x(vcvtuqq2ps, Vcvtuqq2ps, X86Xmm, X86Ymm)                      //      AVX512_DQ{kz|b64}-VL
+    2207             :   ASMJIT_INST_2x(vcvtuqq2ps, Vcvtuqq2ps, X86Ymm, X86Zmm)                      //      AVX512_DQ{kz|er|b64}
+    2208             :   ASMJIT_INST_2x(vcvtuqq2ps, Vcvtuqq2ps, X86Ymm, X86Mem)                      //      AVX512_DQ{kz|er|b64}
+    2209             :   ASMJIT_INST_3x(vcvtusi2sd, Vcvtusi2sd, X86Xmm, X86Xmm, X86Gp)               //      AVX512_F{er}
+    2210             :   ASMJIT_INST_3x(vcvtusi2sd, Vcvtusi2sd, X86Xmm, X86Xmm, X86Mem)              //      AVX512_F{er}
+    2211             :   ASMJIT_INST_3x(vcvtusi2ss, Vcvtusi2ss, X86Xmm, X86Xmm, X86Gp)               //      AVX512_F{er}
+    2212             :   ASMJIT_INST_3x(vcvtusi2ss, Vcvtusi2ss, X86Xmm, X86Xmm, X86Mem)              //      AVX512_F{er}
+    2213             :   ASMJIT_INST_4i(vdbpsadbw, Vdbpsadbw, X86Xmm, X86Xmm, X86Xmm, Imm)           //      AVX512_BW{kz}-VL
+    2214             :   ASMJIT_INST_4i(vdbpsadbw, Vdbpsadbw, X86Xmm, X86Xmm, X86Mem, Imm)           //      AVX512_BW{kz}-VL
+    2215             :   ASMJIT_INST_4i(vdbpsadbw, Vdbpsadbw, X86Ymm, X86Ymm, X86Ymm, Imm)           //      AVX512_BW{kz}-VL
+    2216             :   ASMJIT_INST_4i(vdbpsadbw, Vdbpsadbw, X86Ymm, X86Ymm, X86Mem, Imm)           //      AVX512_BW{kz}-VL
+    2217             :   ASMJIT_INST_4i(vdbpsadbw, Vdbpsadbw, X86Zmm, X86Zmm, X86Zmm, Imm)           //      AVX512_BW{kz}
+    2218             :   ASMJIT_INST_4i(vdbpsadbw, Vdbpsadbw, X86Zmm, X86Zmm, X86Mem, Imm)           //      AVX512_BW{kz}
+    2219             :   ASMJIT_INST_3x(vdivpd, Vdivpd, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|b64}-VL
+    2220             :   ASMJIT_INST_3x(vdivpd, Vdivpd, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|b64}-VL
+    2221             :   ASMJIT_INST_3x(vdivpd, Vdivpd, X86Ymm, X86Ymm, X86Ymm)                      // AVX  AVX512_F{kz|b64}-VL
+    2222             :   ASMJIT_INST_3x(vdivpd, Vdivpd, X86Ymm, X86Ymm, X86Mem)                      // AVX  AVX512_F{kz|b64}-VL
+    2223             :   ASMJIT_INST_3x(vdivpd, Vdivpd, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_F{kz|er|b64}
+    2224             :   ASMJIT_INST_3x(vdivpd, Vdivpd, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_F{kz|er|b64}
+    2225             :   ASMJIT_INST_3x(vdivps, Vdivps, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|b32}-VL
+    2226             :   ASMJIT_INST_3x(vdivps, Vdivps, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|b32}-VL
+    2227             :   ASMJIT_INST_3x(vdivps, Vdivps, X86Ymm, X86Ymm, X86Ymm)                      // AVX  AVX512_F{kz|b32}-VL
+    2228             :   ASMJIT_INST_3x(vdivps, Vdivps, X86Ymm, X86Ymm, X86Mem)                      // AVX  AVX512_F{kz|b32}-VL
+    2229             :   ASMJIT_INST_3x(vdivps, Vdivps, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_F{kz|er|b32}
+    2230             :   ASMJIT_INST_3x(vdivps, Vdivps, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_F{kz|er|b32}
+    2231             :   ASMJIT_INST_3x(vdivsd, Vdivsd, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|er}
+    2232             :   ASMJIT_INST_3x(vdivsd, Vdivsd, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|er}
+    2233             :   ASMJIT_INST_3x(vdivss, Vdivss, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|er}
+    2234             :   ASMJIT_INST_3x(vdivss, Vdivss, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|er}
+    2235             :   ASMJIT_INST_4i(vdppd, Vdppd, X86Xmm, X86Xmm, X86Xmm, Imm)                   // AVX
+    2236             :   ASMJIT_INST_4i(vdppd, Vdppd, X86Xmm, X86Xmm, X86Mem, Imm)                   // AVX
+    2237             :   ASMJIT_INST_4i(vdpps, Vdpps, X86Xmm, X86Xmm, X86Xmm, Imm)                   // AVX
+    2238             :   ASMJIT_INST_4i(vdpps, Vdpps, X86Xmm, X86Xmm, X86Mem, Imm)                   // AVX
+    2239             :   ASMJIT_INST_4i(vdpps, Vdpps, X86Ymm, X86Ymm, X86Ymm, Imm)                   // AVX
+    2240             :   ASMJIT_INST_4i(vdpps, Vdpps, X86Ymm, X86Ymm, X86Mem, Imm)                   // AVX
+    2241             :   ASMJIT_INST_2x(vexp2pd, Vexp2pd, X86Zmm, X86Zmm)                            //      AVX512_ER{kz|sae|b64}
+    2242             :   ASMJIT_INST_2x(vexp2pd, Vexp2pd, X86Zmm, X86Mem)                            //      AVX512_ER{kz|sae|b64}
+    2243             :   ASMJIT_INST_2x(vexp2ps, Vexp2ps, X86Zmm, X86Zmm)                            //      AVX512_ER{kz|sae|b32}
+    2244             :   ASMJIT_INST_2x(vexp2ps, Vexp2ps, X86Zmm, X86Mem)                            //      AVX512_ER{kz|sae|b32}
+    2245             :   ASMJIT_INST_2x(vexpandpd, Vexpandpd, X86Xmm, X86Xmm)                        //      AVX512_F{kz}-VL
+    2246             :   ASMJIT_INST_2x(vexpandpd, Vexpandpd, X86Xmm, X86Mem)                        //      AVX512_F{kz}-VL
+    2247             :   ASMJIT_INST_2x(vexpandpd, Vexpandpd, X86Ymm, X86Ymm)                        //      AVX512_F{kz}-VL
+    2248             :   ASMJIT_INST_2x(vexpandpd, Vexpandpd, X86Ymm, X86Mem)                        //      AVX512_F{kz}-VL
+    2249             :   ASMJIT_INST_2x(vexpandpd, Vexpandpd, X86Zmm, X86Zmm)                        //      AVX512_F{kz}
+    2250             :   ASMJIT_INST_2x(vexpandpd, Vexpandpd, X86Zmm, X86Mem)                        //      AVX512_F{kz}
+    2251             :   ASMJIT_INST_2x(vexpandps, Vexpandps, X86Xmm, X86Xmm)                        //      AVX512_F{kz}-VL
+    2252             :   ASMJIT_INST_2x(vexpandps, Vexpandps, X86Xmm, X86Mem)                        //      AVX512_F{kz}-VL
+    2253             :   ASMJIT_INST_2x(vexpandps, Vexpandps, X86Ymm, X86Ymm)                        //      AVX512_F{kz}-VL
+    2254             :   ASMJIT_INST_2x(vexpandps, Vexpandps, X86Ymm, X86Mem)                        //      AVX512_F{kz}-VL
+    2255             :   ASMJIT_INST_2x(vexpandps, Vexpandps, X86Zmm, X86Zmm)                        //      AVX512_F{kz}
+    2256             :   ASMJIT_INST_2x(vexpandps, Vexpandps, X86Zmm, X86Mem)                        //      AVX512_F{kz}
+    2257             :   ASMJIT_INST_3i(vextractf128, Vextractf128, X86Xmm, X86Ymm, Imm)             // AVX
+    2258             :   ASMJIT_INST_3i(vextractf128, Vextractf128, X86Mem, X86Ymm, Imm)             // AVX
+    2259             :   ASMJIT_INST_3i(vextractf32x4, Vextractf32x4, X86Xmm, X86Ymm, Imm)           //      AVX512_F{kz}-VL
+    2260             :   ASMJIT_INST_3i(vextractf32x4, Vextractf32x4, X86Mem, X86Ymm, Imm)           //      AVX512_F{kz}-VL
+    2261             :   ASMJIT_INST_3i(vextractf32x4, Vextractf32x4, X86Xmm, X86Zmm, Imm)           //      AVX512_F{kz}
+    2262             :   ASMJIT_INST_3i(vextractf32x4, Vextractf32x4, X86Mem, X86Zmm, Imm)           //      AVX512_F{kz}
+    2263             :   ASMJIT_INST_3i(vextractf32x8, Vextractf32x8, X86Ymm, X86Zmm, Imm)           //      AVX512_DQ{kz}
+    2264             :   ASMJIT_INST_3i(vextractf32x8, Vextractf32x8, X86Mem, X86Zmm, Imm)           //      AVX512_DQ{kz}
+    2265             :   ASMJIT_INST_3i(vextractf64x2, Vextractf64x2, X86Xmm, X86Ymm, Imm)           //      AVX512_DQ{kz}-VL
+    2266             :   ASMJIT_INST_3i(vextractf64x2, Vextractf64x2, X86Mem, X86Ymm, Imm)           //      AVX512_DQ{kz}-VL
+    2267             :   ASMJIT_INST_3i(vextractf64x2, Vextractf64x2, X86Xmm, X86Zmm, Imm)           //      AVX512_DQ{kz}
+    2268             :   ASMJIT_INST_3i(vextractf64x2, Vextractf64x2, X86Mem, X86Zmm, Imm)           //      AVX512_DQ{kz}
+    2269             :   ASMJIT_INST_3i(vextractf64x4, Vextractf64x4, X86Ymm, X86Zmm, Imm)           //      AVX512_F{kz}
+    2270             :   ASMJIT_INST_3i(vextractf64x4, Vextractf64x4, X86Mem, X86Zmm, Imm)           //      AVX512_F{kz}
+    2271             :   ASMJIT_INST_3i(vextracti128, Vextracti128, X86Xmm, X86Ymm, Imm)             // AVX2
+    2272             :   ASMJIT_INST_3i(vextracti128, Vextracti128, X86Mem, X86Ymm, Imm)             // AVX2
+    2273             :   ASMJIT_INST_3i(vextracti32x4, Vextracti32x4, X86Xmm, X86Ymm, Imm)           //      AVX512_F{kz}-VL
+    2274             :   ASMJIT_INST_3i(vextracti32x4, Vextracti32x4, X86Mem, X86Ymm, Imm)           //      AVX512_F{kz}-VL
+    2275             :   ASMJIT_INST_3i(vextracti32x4, Vextracti32x4, X86Xmm, X86Zmm, Imm)           //      AVX512_F{kz}
+    2276             :   ASMJIT_INST_3i(vextracti32x4, Vextracti32x4, X86Mem, X86Zmm, Imm)           //      AVX512_F{kz}
+    2277             :   ASMJIT_INST_3i(vextracti32x8, Vextracti32x8, X86Ymm, X86Zmm, Imm)           //      AVX512_DQ{kz}
+    2278             :   ASMJIT_INST_3i(vextracti32x8, Vextracti32x8, X86Mem, X86Zmm, Imm)           //      AVX512_DQ{kz}
+    2279             :   ASMJIT_INST_3i(vextracti64x2, Vextracti64x2, X86Xmm, X86Ymm, Imm)           //      AVX512_DQ{kz}-VL
+    2280             :   ASMJIT_INST_3i(vextracti64x2, Vextracti64x2, X86Mem, X86Ymm, Imm)           //      AVX512_DQ{kz}-VL
+    2281             :   ASMJIT_INST_3i(vextracti64x2, Vextracti64x2, X86Xmm, X86Zmm, Imm)           //      AVX512_DQ{kz}
+    2282             :   ASMJIT_INST_3i(vextracti64x2, Vextracti64x2, X86Mem, X86Zmm, Imm)           //      AVX512_DQ{kz}
+    2283             :   ASMJIT_INST_3i(vextracti64x4, Vextracti64x4, X86Ymm, X86Zmm, Imm)           //      AVX512_F{kz}
+    2284             :   ASMJIT_INST_3i(vextracti64x4, Vextracti64x4, X86Mem, X86Zmm, Imm)           //      AVX512_F{kz}
+    2285             :   ASMJIT_INST_3i(vextractps, Vextractps, X86Gp, X86Xmm, Imm)                  // AVX  AVX512_F
+    2286             :   ASMJIT_INST_3i(vextractps, Vextractps, X86Mem, X86Xmm, Imm)                 // AVX  AVX512_F
+    2287             :   ASMJIT_INST_4i(vfixupimmpd, Vfixupimmpd, X86Xmm, X86Xmm, X86Xmm, Imm)       //      AVX512_F{kz|b64}-VL
+    2288             :   ASMJIT_INST_4i(vfixupimmpd, Vfixupimmpd, X86Xmm, X86Xmm, X86Mem, Imm)       //      AVX512_F{kz|b64}-VL
+    2289             :   ASMJIT_INST_4i(vfixupimmpd, Vfixupimmpd, X86Ymm, X86Ymm, X86Ymm, Imm)       //      AVX512_F{kz|b64}-VL
+    2290             :   ASMJIT_INST_4i(vfixupimmpd, Vfixupimmpd, X86Ymm, X86Ymm, X86Mem, Imm)       //      AVX512_F{kz|b64}-VL
+    2291             :   ASMJIT_INST_4i(vfixupimmpd, Vfixupimmpd, X86Zmm, X86Zmm, X86Zmm, Imm)       //      AVX512_F{kz|sae|b64}
+    2292             :   ASMJIT_INST_4i(vfixupimmpd, Vfixupimmpd, X86Zmm, X86Zmm, X86Mem, Imm)       //      AVX512_F{kz|sae|b64}
+    2293             :   ASMJIT_INST_4i(vfixupimmps, Vfixupimmps, X86Xmm, X86Xmm, X86Xmm, Imm)       //      AVX512_F{kz|b32}-VL
+    2294             :   ASMJIT_INST_4i(vfixupimmps, Vfixupimmps, X86Xmm, X86Xmm, X86Mem, Imm)       //      AVX512_F{kz|b32}-VL
+    2295             :   ASMJIT_INST_4i(vfixupimmps, Vfixupimmps, X86Ymm, X86Ymm, X86Ymm, Imm)       //      AVX512_F{kz|b32}-VL
+    2296             :   ASMJIT_INST_4i(vfixupimmps, Vfixupimmps, X86Ymm, X86Ymm, X86Mem, Imm)       //      AVX512_F{kz|b32}-VL
+    2297             :   ASMJIT_INST_4i(vfixupimmps, Vfixupimmps, X86Zmm, X86Zmm, X86Zmm, Imm)       //      AVX512_F{kz|sae|b32}
+    2298             :   ASMJIT_INST_4i(vfixupimmps, Vfixupimmps, X86Zmm, X86Zmm, X86Mem, Imm)       //      AVX512_F{kz|sae|b32}
+    2299             :   ASMJIT_INST_4i(vfixupimmsd, Vfixupimmsd, X86Xmm, X86Xmm, X86Xmm, Imm)       //      AVX512_F{kz|sae}
+    2300             :   ASMJIT_INST_4i(vfixupimmsd, Vfixupimmsd, X86Xmm, X86Xmm, X86Mem, Imm)       //      AVX512_F{kz|sae}
+    2301             :   ASMJIT_INST_4i(vfixupimmss, Vfixupimmss, X86Xmm, X86Xmm, X86Xmm, Imm)       //      AVX512_F{kz|sae}
+    2302             :   ASMJIT_INST_4i(vfixupimmss, Vfixupimmss, X86Xmm, X86Xmm, X86Mem, Imm)       //      AVX512_F{kz|sae}
+    2303             :   ASMJIT_INST_3x(vfmadd132pd, Vfmadd132pd, X86Xmm, X86Xmm, X86Xmm)            // FMA  AVX512_F{kz|b64}-VL
+    2304             :   ASMJIT_INST_3x(vfmadd132pd, Vfmadd132pd, X86Xmm, X86Xmm, X86Mem)            // FMA  AVX512_F{kz|b64}-VL
+    2305             :   ASMJIT_INST_3x(vfmadd132pd, Vfmadd132pd, X86Ymm, X86Ymm, X86Ymm)            // FMA  AVX512_F{kz|b64}-VL
+    2306             :   ASMJIT_INST_3x(vfmadd132pd, Vfmadd132pd, X86Ymm, X86Ymm, X86Mem)            // FMA  AVX512_F{kz|b64}-VL
+    2307             :   ASMJIT_INST_3x(vfmadd132pd, Vfmadd132pd, X86Zmm, X86Zmm, X86Zmm)            // FMA  AVX512_F{kz|er|b64}
+    2308             :   ASMJIT_INST_3x(vfmadd132pd, Vfmadd132pd, X86Zmm, X86Zmm, X86Mem)            // FMA  AVX512_F{kz|er|b64}
+    2309             :   ASMJIT_INST_3x(vfmadd132ps, Vfmadd132ps, X86Xmm, X86Xmm, X86Xmm)            // FMA  AVX512_F{kz|b32}-VL
+    2310             :   ASMJIT_INST_3x(vfmadd132ps, Vfmadd132ps, X86Xmm, X86Xmm, X86Mem)            // FMA  AVX512_F{kz|b32}-VL
+    2311             :   ASMJIT_INST_3x(vfmadd132ps, Vfmadd132ps, X86Ymm, X86Ymm, X86Ymm)            // FMA  AVX512_F{kz|b32}-VL
+    2312             :   ASMJIT_INST_3x(vfmadd132ps, Vfmadd132ps, X86Ymm, X86Ymm, X86Mem)            // FMA  AVX512_F{kz|b32}-VL
+    2313             :   ASMJIT_INST_3x(vfmadd132ps, Vfmadd132ps, X86Zmm, X86Zmm, X86Zmm)            // FMA  AVX512_F{kz|er|b32}
+    2314             :   ASMJIT_INST_3x(vfmadd132ps, Vfmadd132ps, X86Zmm, X86Zmm, X86Mem)            // FMA  AVX512_F{kz|er|b32}
+    2315             :   ASMJIT_INST_3x(vfmadd132sd, Vfmadd132sd, X86Xmm, X86Xmm, X86Xmm)            // FMA  AVX512_F{kz|er}
+    2316             :   ASMJIT_INST_3x(vfmadd132sd, Vfmadd132sd, X86Xmm, X86Xmm, X86Mem)            // FMA  AVX512_F{kz|er}
+    2317             :   ASMJIT_INST_3x(vfmadd132ss, Vfmadd132ss, X86Xmm, X86Xmm, X86Xmm)            // FMA  AVX512_F{kz|er}
+    2318             :   ASMJIT_INST_3x(vfmadd132ss, Vfmadd132ss, X86Xmm, X86Xmm, X86Mem)            // FMA  AVX512_F{kz|er}
+    2319             :   ASMJIT_INST_3x(vfmadd213pd, Vfmadd213pd, X86Xmm, X86Xmm, X86Xmm)            // FMA  AVX512_F{kz|b64}-VL
+    2320             :   ASMJIT_INST_3x(vfmadd213pd, Vfmadd213pd, X86Xmm, X86Xmm, X86Mem)            // FMA  AVX512_F{kz|b64}-VL
+    2321             :   ASMJIT_INST_3x(vfmadd213pd, Vfmadd213pd, X86Ymm, X86Ymm, X86Ymm)            // FMA  AVX512_F{kz|b64}-VL
+    2322             :   ASMJIT_INST_3x(vfmadd213pd, Vfmadd213pd, X86Ymm, X86Ymm, X86Mem)            // FMA  AVX512_F{kz|b64}-VL
+    2323             :   ASMJIT_INST_3x(vfmadd213pd, Vfmadd213pd, X86Zmm, X86Zmm, X86Zmm)            // FMA  AVX512_F{kz|er|b64}
+    2324             :   ASMJIT_INST_3x(vfmadd213pd, Vfmadd213pd, X86Zmm, X86Zmm, X86Mem)            // FMA  AVX512_F{kz|er|b64}
+    2325             :   ASMJIT_INST_3x(vfmadd213ps, Vfmadd213ps, X86Xmm, X86Xmm, X86Xmm)            // FMA  AVX512_F{kz|b32}-VL
+    2326             :   ASMJIT_INST_3x(vfmadd213ps, Vfmadd213ps, X86Xmm, X86Xmm, X86Mem)            // FMA  AVX512_F{kz|b32}-VL
+    2327             :   ASMJIT_INST_3x(vfmadd213ps, Vfmadd213ps, X86Ymm, X86Ymm, X86Ymm)            // FMA  AVX512_F{kz|b32}-VL
+    2328             :   ASMJIT_INST_3x(vfmadd213ps, Vfmadd213ps, X86Ymm, X86Ymm, X86Mem)            // FMA  AVX512_F{kz|b32}-VL
+    2329             :   ASMJIT_INST_3x(vfmadd213ps, Vfmadd213ps, X86Zmm, X86Zmm, X86Zmm)            // FMA  AVX512_F{kz|er|b32}
+    2330             :   ASMJIT_INST_3x(vfmadd213ps, Vfmadd213ps, X86Zmm, X86Zmm, X86Mem)            // FMA  AVX512_F{kz|er|b32}
+    2331             :   ASMJIT_INST_3x(vfmadd213sd, Vfmadd213sd, X86Xmm, X86Xmm, X86Xmm)            // FMA  AVX512_F{kz|er}
+    2332             :   ASMJIT_INST_3x(vfmadd213sd, Vfmadd213sd, X86Xmm, X86Xmm, X86Mem)            // FMA  AVX512_F{kz|er}
+    2333             :   ASMJIT_INST_3x(vfmadd213ss, Vfmadd213ss, X86Xmm, X86Xmm, X86Xmm)            // FMA  AVX512_F{kz|er}
+    2334             :   ASMJIT_INST_3x(vfmadd213ss, Vfmadd213ss, X86Xmm, X86Xmm, X86Mem)            // FMA  AVX512_F{kz|er}
+    2335             :   ASMJIT_INST_3x(vfmadd231pd, Vfmadd231pd, X86Xmm, X86Xmm, X86Xmm)            // FMA  AVX512_F{kz|b64}-VL
+    2336             :   ASMJIT_INST_3x(vfmadd231pd, Vfmadd231pd, X86Xmm, X86Xmm, X86Mem)            // FMA  AVX512_F{kz|b64}-VL
+    2337             :   ASMJIT_INST_3x(vfmadd231pd, Vfmadd231pd, X86Ymm, X86Ymm, X86Ymm)            // FMA  AVX512_F{kz|b64}-VL
+    2338             :   ASMJIT_INST_3x(vfmadd231pd, Vfmadd231pd, X86Ymm, X86Ymm, X86Mem)            // FMA  AVX512_F{kz|b64}-VL
+    2339             :   ASMJIT_INST_3x(vfmadd231pd, Vfmadd231pd, X86Zmm, X86Zmm, X86Zmm)            // FMA  AVX512_F{kz|er|b64}
+    2340             :   ASMJIT_INST_3x(vfmadd231pd, Vfmadd231pd, X86Zmm, X86Zmm, X86Mem)            // FMA  AVX512_F{kz|er|b64}
+    2341             :   ASMJIT_INST_3x(vfmadd231ps, Vfmadd231ps, X86Xmm, X86Xmm, X86Xmm)            // FMA  AVX512_F{kz|b32}-VL
+    2342             :   ASMJIT_INST_3x(vfmadd231ps, Vfmadd231ps, X86Xmm, X86Xmm, X86Mem)            // FMA  AVX512_F{kz|b32}-VL
+    2343             :   ASMJIT_INST_3x(vfmadd231ps, Vfmadd231ps, X86Ymm, X86Ymm, X86Ymm)            // FMA  AVX512_F{kz|b32}-VL
+    2344             :   ASMJIT_INST_3x(vfmadd231ps, Vfmadd231ps, X86Ymm, X86Ymm, X86Mem)            // FMA  AVX512_F{kz|b32}-VL
+    2345             :   ASMJIT_INST_3x(vfmadd231ps, Vfmadd231ps, X86Zmm, X86Zmm, X86Zmm)            // FMA  AVX512_F{kz|er|b32}
+    2346             :   ASMJIT_INST_3x(vfmadd231ps, Vfmadd231ps, X86Zmm, X86Zmm, X86Mem)            // FMA  AVX512_F{kz|er|b32}
+    2347             :   ASMJIT_INST_3x(vfmadd231sd, Vfmadd231sd, X86Xmm, X86Xmm, X86Xmm)            // FMA  AVX512_F{kz|er}
+    2348             :   ASMJIT_INST_3x(vfmadd231sd, Vfmadd231sd, X86Xmm, X86Xmm, X86Mem)            // FMA  AVX512_F{kz|er}
+    2349             :   ASMJIT_INST_3x(vfmadd231ss, Vfmadd231ss, X86Xmm, X86Xmm, X86Xmm)            // FMA  AVX512_F{kz|er}
+    2350             :   ASMJIT_INST_3x(vfmadd231ss, Vfmadd231ss, X86Xmm, X86Xmm, X86Mem)            // FMA  AVX512_F{kz|er}
+    2351             :   ASMJIT_INST_3x(vfmaddsub132pd, Vfmaddsub132pd, X86Xmm, X86Xmm, X86Xmm)      // FMA  AVX512_F{kz|b64}-VL
+    2352             :   ASMJIT_INST_3x(vfmaddsub132pd, Vfmaddsub132pd, X86Xmm, X86Xmm, X86Mem)      // FMA  AVX512_F{kz|b64}-VL
+    2353             :   ASMJIT_INST_3x(vfmaddsub132pd, Vfmaddsub132pd, X86Ymm, X86Ymm, X86Ymm)      // FMA  AVX512_F{kz|b64}-VL
+    2354             :   ASMJIT_INST_3x(vfmaddsub132pd, Vfmaddsub132pd, X86Ymm, X86Ymm, X86Mem)      // FMA  AVX512_F{kz|b64}-VL
+    2355             :   ASMJIT_INST_3x(vfmaddsub132pd, Vfmaddsub132pd, X86Zmm, X86Zmm, X86Zmm)      // FMA  AVX512_F{kz|er|b64}
+    2356             :   ASMJIT_INST_3x(vfmaddsub132pd, Vfmaddsub132pd, X86Zmm, X86Zmm, X86Mem)      // FMA  AVX512_F{kz|er|b64}
+    2357             :   ASMJIT_INST_3x(vfmaddsub132ps, Vfmaddsub132ps, X86Xmm, X86Xmm, X86Xmm)      // FMA  AVX512_F{kz|b32}-VL
+    2358             :   ASMJIT_INST_3x(vfmaddsub132ps, Vfmaddsub132ps, X86Xmm, X86Xmm, X86Mem)      // FMA  AVX512_F{kz|b32}-VL
+    2359             :   ASMJIT_INST_3x(vfmaddsub132ps, Vfmaddsub132ps, X86Ymm, X86Ymm, X86Ymm)      // FMA  AVX512_F{kz|b32}-VL
+    2360             :   ASMJIT_INST_3x(vfmaddsub132ps, Vfmaddsub132ps, X86Ymm, X86Ymm, X86Mem)      // FMA  AVX512_F{kz|b32}-VL
+    2361             :   ASMJIT_INST_3x(vfmaddsub132ps, Vfmaddsub132ps, X86Zmm, X86Zmm, X86Zmm)      // FMA  AVX512_F{kz|er|b32}
+    2362             :   ASMJIT_INST_3x(vfmaddsub132ps, Vfmaddsub132ps, X86Zmm, X86Zmm, X86Mem)      // FMA  AVX512_F{kz|er|b32}
+    2363             :   ASMJIT_INST_3x(vfmaddsub213pd, Vfmaddsub213pd, X86Xmm, X86Xmm, X86Xmm)      // FMA  AVX512_F{kz|b64}-VL
+    2364             :   ASMJIT_INST_3x(vfmaddsub213pd, Vfmaddsub213pd, X86Xmm, X86Xmm, X86Mem)      // FMA  AVX512_F{kz|b64}-VL
+    2365             :   ASMJIT_INST_3x(vfmaddsub213pd, Vfmaddsub213pd, X86Ymm, X86Ymm, X86Ymm)      // FMA  AVX512_F{kz|b64}-VL
+    2366             :   ASMJIT_INST_3x(vfmaddsub213pd, Vfmaddsub213pd, X86Ymm, X86Ymm, X86Mem)      // FMA  AVX512_F{kz|b64}-VL
+    2367             :   ASMJIT_INST_3x(vfmaddsub213pd, Vfmaddsub213pd, X86Zmm, X86Zmm, X86Zmm)      // FMA  AVX512_F{kz|er|b64}
+    2368             :   ASMJIT_INST_3x(vfmaddsub213pd, Vfmaddsub213pd, X86Zmm, X86Zmm, X86Mem)      // FMA  AVX512_F{kz|er|b64}
+    2369             :   ASMJIT_INST_3x(vfmaddsub213ps, Vfmaddsub213ps, X86Xmm, X86Xmm, X86Xmm)      // FMA  AVX512_F{kz|b32}-VL
+    2370             :   ASMJIT_INST_3x(vfmaddsub213ps, Vfmaddsub213ps, X86Xmm, X86Xmm, X86Mem)      // FMA  AVX512_F{kz|b32}-VL
+    2371             :   ASMJIT_INST_3x(vfmaddsub213ps, Vfmaddsub213ps, X86Ymm, X86Ymm, X86Ymm)      // FMA  AVX512_F{kz|b32}-VL
+    2372             :   ASMJIT_INST_3x(vfmaddsub213ps, Vfmaddsub213ps, X86Ymm, X86Ymm, X86Mem)      // FMA  AVX512_F{kz|b32}-VL
+    2373             :   ASMJIT_INST_3x(vfmaddsub213ps, Vfmaddsub213ps, X86Zmm, X86Zmm, X86Zmm)      // FMA  AVX512_F{kz|er|b32}
+    2374             :   ASMJIT_INST_3x(vfmaddsub213ps, Vfmaddsub213ps, X86Zmm, X86Zmm, X86Mem)      // FMA  AVX512_F{kz|er|b32}
+    2375             :   ASMJIT_INST_3x(vfmaddsub231pd, Vfmaddsub231pd, X86Xmm, X86Xmm, X86Xmm)      // FMA  AVX512_F{kz|b64}-VL
+    2376             :   ASMJIT_INST_3x(vfmaddsub231pd, Vfmaddsub231pd, X86Xmm, X86Xmm, X86Mem)      // FMA  AVX512_F{kz|b64}-VL
+    2377             :   ASMJIT_INST_3x(vfmaddsub231pd, Vfmaddsub231pd, X86Ymm, X86Ymm, X86Ymm)      // FMA  AVX512_F{kz|b64}-VL
+    2378             :   ASMJIT_INST_3x(vfmaddsub231pd, Vfmaddsub231pd, X86Ymm, X86Ymm, X86Mem)      // FMA  AVX512_F{kz|b64}-VL
+    2379             :   ASMJIT_INST_3x(vfmaddsub231pd, Vfmaddsub231pd, X86Zmm, X86Zmm, X86Zmm)      // FMA  AVX512_F{kz|er|b64}
+    2380             :   ASMJIT_INST_3x(vfmaddsub231pd, Vfmaddsub231pd, X86Zmm, X86Zmm, X86Mem)      // FMA  AVX512_F{kz|er|b64}
+    2381             :   ASMJIT_INST_3x(vfmaddsub231ps, Vfmaddsub231ps, X86Xmm, X86Xmm, X86Xmm)      // FMA  AVX512_F{kz|b32}-VL
+    2382             :   ASMJIT_INST_3x(vfmaddsub231ps, Vfmaddsub231ps, X86Xmm, X86Xmm, X86Mem)      // FMA  AVX512_F{kz|b32}-VL
+    2383             :   ASMJIT_INST_3x(vfmaddsub231ps, Vfmaddsub231ps, X86Ymm, X86Ymm, X86Ymm)      // FMA  AVX512_F{kz|b32}-VL
+    2384             :   ASMJIT_INST_3x(vfmaddsub231ps, Vfmaddsub231ps, X86Ymm, X86Ymm, X86Mem)      // FMA  AVX512_F{kz|b32}-VL
+    2385             :   ASMJIT_INST_3x(vfmaddsub231ps, Vfmaddsub231ps, X86Zmm, X86Zmm, X86Zmm)      // FMA  AVX512_F{kz|er|b32}
+    2386             :   ASMJIT_INST_3x(vfmaddsub231ps, Vfmaddsub231ps, X86Zmm, X86Zmm, X86Mem)      // FMA  AVX512_F{kz|er|b32}
+    2387             :   ASMJIT_INST_3x(vfmsub132pd, Vfmsub132pd, X86Xmm, X86Xmm, X86Xmm)            // FMA  AVX512_F{kz|b64}-VL
+    2388             :   ASMJIT_INST_3x(vfmsub132pd, Vfmsub132pd, X86Xmm, X86Xmm, X86Mem)            // FMA  AVX512_F{kz|b64}-VL
+    2389             :   ASMJIT_INST_3x(vfmsub132pd, Vfmsub132pd, X86Ymm, X86Ymm, X86Ymm)            // FMA  AVX512_F{kz|b64}-VL
+    2390             :   ASMJIT_INST_3x(vfmsub132pd, Vfmsub132pd, X86Ymm, X86Ymm, X86Mem)            // FMA  AVX512_F{kz|b64}-VL
+    2391             :   ASMJIT_INST_3x(vfmsub132pd, Vfmsub132pd, X86Zmm, X86Zmm, X86Zmm)            // FMA  AVX512_F{kz|er|b64}
+    2392             :   ASMJIT_INST_3x(vfmsub132pd, Vfmsub132pd, X86Zmm, X86Zmm, X86Mem)            // FMA  AVX512_F{kz|er|b64}
+    2393             :   ASMJIT_INST_3x(vfmsub132ps, Vfmsub132ps, X86Xmm, X86Xmm, X86Xmm)            // FMA  AVX512_F{kz|b32}-VL
+    2394             :   ASMJIT_INST_3x(vfmsub132ps, Vfmsub132ps, X86Xmm, X86Xmm, X86Mem)            // FMA  AVX512_F{kz|b32}-VL
+    2395             :   ASMJIT_INST_3x(vfmsub132ps, Vfmsub132ps, X86Ymm, X86Ymm, X86Ymm)            // FMA  AVX512_F{kz|b32}-VL
+    2396             :   ASMJIT_INST_3x(vfmsub132ps, Vfmsub132ps, X86Ymm, X86Ymm, X86Mem)            // FMA  AVX512_F{kz|b32}-VL
+    2397             :   ASMJIT_INST_3x(vfmsub132ps, Vfmsub132ps, X86Zmm, X86Zmm, X86Zmm)            // FMA  AVX512_F{kz|er|b32}
+    2398             :   ASMJIT_INST_3x(vfmsub132ps, Vfmsub132ps, X86Zmm, X86Zmm, X86Mem)            // FMA  AVX512_F{kz|er|b32}
+    2399             :   ASMJIT_INST_3x(vfmsub132sd, Vfmsub132sd, X86Xmm, X86Xmm, X86Xmm)            // FMA  AVX512_F{kz|er}
+    2400             :   ASMJIT_INST_3x(vfmsub132sd, Vfmsub132sd, X86Xmm, X86Xmm, X86Mem)            // FMA  AVX512_F{kz|er}
+    2401             :   ASMJIT_INST_3x(vfmsub132ss, Vfmsub132ss, X86Xmm, X86Xmm, X86Xmm)            // FMA  AVX512_F{kz|er}
+    2402             :   ASMJIT_INST_3x(vfmsub132ss, Vfmsub132ss, X86Xmm, X86Xmm, X86Mem)            // FMA  AVX512_F{kz|er}
+    2403             :   ASMJIT_INST_3x(vfmsub213pd, Vfmsub213pd, X86Xmm, X86Xmm, X86Xmm)            // FMA  AVX512_F{kz|b64}-VL
+    2404             :   ASMJIT_INST_3x(vfmsub213pd, Vfmsub213pd, X86Xmm, X86Xmm, X86Mem)            // FMA  AVX512_F{kz|b64}-VL
+    2405             :   ASMJIT_INST_3x(vfmsub213pd, Vfmsub213pd, X86Ymm, X86Ymm, X86Ymm)            // FMA  AVX512_F{kz|b64}-VL
+    2406             :   ASMJIT_INST_3x(vfmsub213pd, Vfmsub213pd, X86Ymm, X86Ymm, X86Mem)            // FMA  AVX512_F{kz|b64}-VL
+    2407             :   ASMJIT_INST_3x(vfmsub213pd, Vfmsub213pd, X86Zmm, X86Zmm, X86Zmm)            // FMA  AVX512_F{kz|er|b64}
+    2408             :   ASMJIT_INST_3x(vfmsub213pd, Vfmsub213pd, X86Zmm, X86Zmm, X86Mem)            // FMA  AVX512_F{kz|er|b64}
+    2409             :   ASMJIT_INST_3x(vfmsub213ps, Vfmsub213ps, X86Xmm, X86Xmm, X86Xmm)            // FMA  AVX512_F{kz|b32}-VL
+    2410             :   ASMJIT_INST_3x(vfmsub213ps, Vfmsub213ps, X86Xmm, X86Xmm, X86Mem)            // FMA  AVX512_F{kz|b32}-VL
+    2411             :   ASMJIT_INST_3x(vfmsub213ps, Vfmsub213ps, X86Ymm, X86Ymm, X86Ymm)            // FMA  AVX512_F{kz|b32}-VL
+    2412             :   ASMJIT_INST_3x(vfmsub213ps, Vfmsub213ps, X86Ymm, X86Ymm, X86Mem)            // FMA  AVX512_F{kz|b32}-VL
+    2413             :   ASMJIT_INST_3x(vfmsub213ps, Vfmsub213ps, X86Zmm, X86Zmm, X86Zmm)            // FMA  AVX512_F{kz|er|b32}
+    2414             :   ASMJIT_INST_3x(vfmsub213ps, Vfmsub213ps, X86Zmm, X86Zmm, X86Mem)            // FMA  AVX512_F{kz|er|b32}
+    2415             :   ASMJIT_INST_3x(vfmsub213sd, Vfmsub213sd, X86Xmm, X86Xmm, X86Xmm)            // FMA  AVX512_F{kz|er}
+    2416             :   ASMJIT_INST_3x(vfmsub213sd, Vfmsub213sd, X86Xmm, X86Xmm, X86Mem)            // FMA  AVX512_F{kz|er}
+    2417             :   ASMJIT_INST_3x(vfmsub213ss, Vfmsub213ss, X86Xmm, X86Xmm, X86Xmm)            // FMA  AVX512_F{kz|er}
+    2418             :   ASMJIT_INST_3x(vfmsub213ss, Vfmsub213ss, X86Xmm, X86Xmm, X86Mem)            // FMA  AVX512_F{kz|er}
+    2419             :   ASMJIT_INST_3x(vfmsub231pd, Vfmsub231pd, X86Xmm, X86Xmm, X86Xmm)            // FMA  AVX512_F{kz|b64}-VL
+    2420             :   ASMJIT_INST_3x(vfmsub231pd, Vfmsub231pd, X86Xmm, X86Xmm, X86Mem)            // FMA  AVX512_F{kz|b64}-VL
+    2421             :   ASMJIT_INST_3x(vfmsub231pd, Vfmsub231pd, X86Ymm, X86Ymm, X86Ymm)            // FMA  AVX512_F{kz|b64}-VL
+    2422             :   ASMJIT_INST_3x(vfmsub231pd, Vfmsub231pd, X86Ymm, X86Ymm, X86Mem)            // FMA  AVX512_F{kz|b64}-VL
+    2423             :   ASMJIT_INST_3x(vfmsub231pd, Vfmsub231pd, X86Zmm, X86Zmm, X86Zmm)            // FMA  AVX512_F{kz|er|b64}
+    2424             :   ASMJIT_INST_3x(vfmsub231pd, Vfmsub231pd, X86Zmm, X86Zmm, X86Mem)            // FMA  AVX512_F{kz|er|b64}
+    2425             :   ASMJIT_INST_3x(vfmsub231ps, Vfmsub231ps, X86Xmm, X86Xmm, X86Xmm)            // FMA  AVX512_F{kz|b32}-VL
+    2426             :   ASMJIT_INST_3x(vfmsub231ps, Vfmsub231ps, X86Xmm, X86Xmm, X86Mem)            // FMA  AVX512_F{kz|b32}-VL
+    2427             :   ASMJIT_INST_3x(vfmsub231ps, Vfmsub231ps, X86Ymm, X86Ymm, X86Ymm)            // FMA  AVX512_F{kz|b32}-VL
+    2428             :   ASMJIT_INST_3x(vfmsub231ps, Vfmsub231ps, X86Ymm, X86Ymm, X86Mem)            // FMA  AVX512_F{kz|b32}-VL
+    2429             :   ASMJIT_INST_3x(vfmsub231ps, Vfmsub231ps, X86Zmm, X86Zmm, X86Zmm)            // FMA  AVX512_F{kz|er|b32}
+    2430             :   ASMJIT_INST_3x(vfmsub231ps, Vfmsub231ps, X86Zmm, X86Zmm, X86Mem)            // FMA  AVX512_F{kz|er|b32}
+    2431             :   ASMJIT_INST_3x(vfmsub231sd, Vfmsub231sd, X86Xmm, X86Xmm, X86Xmm)            // FMA  AVX512_F{kz|er}
+    2432             :   ASMJIT_INST_3x(vfmsub231sd, Vfmsub231sd, X86Xmm, X86Xmm, X86Mem)            // FMA  AVX512_F{kz|er}
+    2433             :   ASMJIT_INST_3x(vfmsub231ss, Vfmsub231ss, X86Xmm, X86Xmm, X86Xmm)            // FMA  AVX512_F{kz|er}
+    2434             :   ASMJIT_INST_3x(vfmsub231ss, Vfmsub231ss, X86Xmm, X86Xmm, X86Mem)            // FMA  AVX512_F{kz|er}
+    2435             :   ASMJIT_INST_3x(vfmsubadd132pd, Vfmsubadd132pd, X86Xmm, X86Xmm, X86Xmm)      // FMA  AVX512_F{kz|b64}-VL
+    2436             :   ASMJIT_INST_3x(vfmsubadd132pd, Vfmsubadd132pd, X86Xmm, X86Xmm, X86Mem)      // FMA  AVX512_F{kz|b64}-VL
+    2437             :   ASMJIT_INST_3x(vfmsubadd132pd, Vfmsubadd132pd, X86Ymm, X86Ymm, X86Ymm)      // FMA  AVX512_F{kz|b64}-VL
+    2438             :   ASMJIT_INST_3x(vfmsubadd132pd, Vfmsubadd132pd, X86Ymm, X86Ymm, X86Mem)      // FMA  AVX512_F{kz|b64}-VL
+    2439             :   ASMJIT_INST_3x(vfmsubadd132pd, Vfmsubadd132pd, X86Zmm, X86Zmm, X86Zmm)      // FMA  AVX512_F{kz|er|b64}
+    2440             :   ASMJIT_INST_3x(vfmsubadd132pd, Vfmsubadd132pd, X86Zmm, X86Zmm, X86Mem)      // FMA  AVX512_F{kz|er|b64}
+    2441             :   ASMJIT_INST_3x(vfmsubadd132ps, Vfmsubadd132ps, X86Xmm, X86Xmm, X86Xmm)      // FMA  AVX512_F{kz|b32}-VL
+    2442             :   ASMJIT_INST_3x(vfmsubadd132ps, Vfmsubadd132ps, X86Xmm, X86Xmm, X86Mem)      // FMA  AVX512_F{kz|b32}-VL
+    2443             :   ASMJIT_INST_3x(vfmsubadd132ps, Vfmsubadd132ps, X86Ymm, X86Ymm, X86Ymm)      // FMA  AVX512_F{kz|b32}-VL
+    2444             :   ASMJIT_INST_3x(vfmsubadd132ps, Vfmsubadd132ps, X86Ymm, X86Ymm, X86Mem)      // FMA  AVX512_F{kz|b32}-VL
+    2445             :   ASMJIT_INST_3x(vfmsubadd132ps, Vfmsubadd132ps, X86Zmm, X86Zmm, X86Zmm)      // FMA  AVX512_F{kz|er|b32}
+    2446             :   ASMJIT_INST_3x(vfmsubadd132ps, Vfmsubadd132ps, X86Zmm, X86Zmm, X86Mem)      // FMA  AVX512_F{kz|er|b32}
+    2447             :   ASMJIT_INST_3x(vfmsubadd213pd, Vfmsubadd213pd, X86Xmm, X86Xmm, X86Xmm)      // FMA  AVX512_F{kz|b64}-VL
+    2448             :   ASMJIT_INST_3x(vfmsubadd213pd, Vfmsubadd213pd, X86Xmm, X86Xmm, X86Mem)      // FMA  AVX512_F{kz|b64}-VL
+    2449             :   ASMJIT_INST_3x(vfmsubadd213pd, Vfmsubadd213pd, X86Ymm, X86Ymm, X86Ymm)      // FMA  AVX512_F{kz|b64}-VL
+    2450             :   ASMJIT_INST_3x(vfmsubadd213pd, Vfmsubadd213pd, X86Ymm, X86Ymm, X86Mem)      // FMA  AVX512_F{kz|b64}-VL
+    2451             :   ASMJIT_INST_3x(vfmsubadd213pd, Vfmsubadd213pd, X86Zmm, X86Zmm, X86Zmm)      // FMA  AVX512_F{kz|er|b64}
+    2452             :   ASMJIT_INST_3x(vfmsubadd213pd, Vfmsubadd213pd, X86Zmm, X86Zmm, X86Mem)      // FMA  AVX512_F{kz|er|b64}
+    2453             :   ASMJIT_INST_3x(vfmsubadd213ps, Vfmsubadd213ps, X86Xmm, X86Xmm, X86Xmm)      // FMA  AVX512_F{kz|b32}-VL
+    2454             :   ASMJIT_INST_3x(vfmsubadd213ps, Vfmsubadd213ps, X86Xmm, X86Xmm, X86Mem)      // FMA  AVX512_F{kz|b32}-VL
+    2455             :   ASMJIT_INST_3x(vfmsubadd213ps, Vfmsubadd213ps, X86Ymm, X86Ymm, X86Ymm)      // FMA  AVX512_F{kz|b32}-VL
+    2456             :   ASMJIT_INST_3x(vfmsubadd213ps, Vfmsubadd213ps, X86Ymm, X86Ymm, X86Mem)      // FMA  AVX512_F{kz|b32}-VL
+    2457             :   ASMJIT_INST_3x(vfmsubadd213ps, Vfmsubadd213ps, X86Zmm, X86Zmm, X86Zmm)      // FMA  AVX512_F{kz|er|b32}
+    2458             :   ASMJIT_INST_3x(vfmsubadd213ps, Vfmsubadd213ps, X86Zmm, X86Zmm, X86Mem)      // FMA  AVX512_F{kz|er|b32}
+    2459             :   ASMJIT_INST_3x(vfmsubadd231pd, Vfmsubadd231pd, X86Xmm, X86Xmm, X86Xmm)      // FMA  AVX512_F{kz|b64}-VL
+    2460             :   ASMJIT_INST_3x(vfmsubadd231pd, Vfmsubadd231pd, X86Xmm, X86Xmm, X86Mem)      // FMA  AVX512_F{kz|b64}-VL
+    2461             :   ASMJIT_INST_3x(vfmsubadd231pd, Vfmsubadd231pd, X86Ymm, X86Ymm, X86Ymm)      // FMA  AVX512_F{kz|b64}-VL
+    2462             :   ASMJIT_INST_3x(vfmsubadd231pd, Vfmsubadd231pd, X86Ymm, X86Ymm, X86Mem)      // FMA  AVX512_F{kz|b64}-VL
+    2463             :   ASMJIT_INST_3x(vfmsubadd231pd, Vfmsubadd231pd, X86Zmm, X86Zmm, X86Zmm)      // FMA  AVX512_F{kz|er|b64}
+    2464             :   ASMJIT_INST_3x(vfmsubadd231pd, Vfmsubadd231pd, X86Zmm, X86Zmm, X86Mem)      // FMA  AVX512_F{kz|er|b64}
+    2465             :   ASMJIT_INST_3x(vfmsubadd231ps, Vfmsubadd231ps, X86Xmm, X86Xmm, X86Xmm)      // FMA  AVX512_F{kz|b32}-VL
+    2466             :   ASMJIT_INST_3x(vfmsubadd231ps, Vfmsubadd231ps, X86Xmm, X86Xmm, X86Mem)      // FMA  AVX512_F{kz|b32}-VL
+    2467             :   ASMJIT_INST_3x(vfmsubadd231ps, Vfmsubadd231ps, X86Ymm, X86Ymm, X86Ymm)      // FMA  AVX512_F{kz|b32}-VL
+    2468             :   ASMJIT_INST_3x(vfmsubadd231ps, Vfmsubadd231ps, X86Ymm, X86Ymm, X86Mem)      // FMA  AVX512_F{kz|b32}-VL
+    2469             :   ASMJIT_INST_3x(vfmsubadd231ps, Vfmsubadd231ps, X86Zmm, X86Zmm, X86Zmm)      // FMA  AVX512_F{kz|er|b32}
+    2470             :   ASMJIT_INST_3x(vfmsubadd231ps, Vfmsubadd231ps, X86Zmm, X86Zmm, X86Mem)      // FMA  AVX512_F{kz|er|b32}
+    2471             :   ASMJIT_INST_3x(vfnmadd132pd, Vfnmadd132pd, X86Xmm, X86Xmm, X86Xmm)          // FMA  AVX512_F{kz|b64}-VL
+    2472             :   ASMJIT_INST_3x(vfnmadd132pd, Vfnmadd132pd, X86Xmm, X86Xmm, X86Mem)          // FMA  AVX512_F{kz|b64}-VL
+    2473             :   ASMJIT_INST_3x(vfnmadd132pd, Vfnmadd132pd, X86Ymm, X86Ymm, X86Ymm)          // FMA  AVX512_F{kz|b64}-VL
+    2474             :   ASMJIT_INST_3x(vfnmadd132pd, Vfnmadd132pd, X86Ymm, X86Ymm, X86Mem)          // FMA  AVX512_F{kz|b64}-VL
+    2475             :   ASMJIT_INST_3x(vfnmadd132pd, Vfnmadd132pd, X86Zmm, X86Zmm, X86Zmm)          // FMA  AVX512_F{kz|er|b64}
+    2476             :   ASMJIT_INST_3x(vfnmadd132pd, Vfnmadd132pd, X86Zmm, X86Zmm, X86Mem)          // FMA  AVX512_F{kz|er|b64}
+    2477             :   ASMJIT_INST_3x(vfnmadd132ps, Vfnmadd132ps, X86Xmm, X86Xmm, X86Xmm)          // FMA  AVX512_F{kz|b32}-VL
+    2478             :   ASMJIT_INST_3x(vfnmadd132ps, Vfnmadd132ps, X86Xmm, X86Xmm, X86Mem)          // FMA  AVX512_F{kz|b32}-VL
+    2479             :   ASMJIT_INST_3x(vfnmadd132ps, Vfnmadd132ps, X86Ymm, X86Ymm, X86Ymm)          // FMA  AVX512_F{kz|b32}-VL
+    2480             :   ASMJIT_INST_3x(vfnmadd132ps, Vfnmadd132ps, X86Ymm, X86Ymm, X86Mem)          // FMA  AVX512_F{kz|b32}-VL
+    2481             :   ASMJIT_INST_3x(vfnmadd132ps, Vfnmadd132ps, X86Zmm, X86Zmm, X86Zmm)          // FMA  AVX512_F{kz|er|b32}
+    2482             :   ASMJIT_INST_3x(vfnmadd132ps, Vfnmadd132ps, X86Zmm, X86Zmm, X86Mem)          // FMA  AVX512_F{kz|er|b32}
+    2483             :   ASMJIT_INST_3x(vfnmadd132sd, Vfnmadd132sd, X86Xmm, X86Xmm, X86Xmm)          // FMA  AVX512_F{kz|er}
+    2484             :   ASMJIT_INST_3x(vfnmadd132sd, Vfnmadd132sd, X86Xmm, X86Xmm, X86Mem)          // FMA  AVX512_F{kz|er}
+    2485             :   ASMJIT_INST_3x(vfnmadd132ss, Vfnmadd132ss, X86Xmm, X86Xmm, X86Xmm)          // FMA  AVX512_F{kz|er}
+    2486             :   ASMJIT_INST_3x(vfnmadd132ss, Vfnmadd132ss, X86Xmm, X86Xmm, X86Mem)          // FMA  AVX512_F{kz|er}
+    2487             :   ASMJIT_INST_3x(vfnmadd213pd, Vfnmadd213pd, X86Xmm, X86Xmm, X86Xmm)          // FMA  AVX512_F{kz|b64}-VL
+    2488             :   ASMJIT_INST_3x(vfnmadd213pd, Vfnmadd213pd, X86Xmm, X86Xmm, X86Mem)          // FMA  AVX512_F{kz|b64}-VL
+    2489             :   ASMJIT_INST_3x(vfnmadd213pd, Vfnmadd213pd, X86Ymm, X86Ymm, X86Ymm)          // FMA  AVX512_F{kz|b64}-VL
+    2490             :   ASMJIT_INST_3x(vfnmadd213pd, Vfnmadd213pd, X86Ymm, X86Ymm, X86Mem)          // FMA  AVX512_F{kz|b64}-VL
+    2491             :   ASMJIT_INST_3x(vfnmadd213pd, Vfnmadd213pd, X86Zmm, X86Zmm, X86Zmm)          // FMA  AVX512_F{kz|er|b64}
+    2492             :   ASMJIT_INST_3x(vfnmadd213pd, Vfnmadd213pd, X86Zmm, X86Zmm, X86Mem)          // FMA  AVX512_F{kz|er|b64}
+    2493             :   ASMJIT_INST_3x(vfnmadd213ps, Vfnmadd213ps, X86Xmm, X86Xmm, X86Xmm)          // FMA  AVX512_F{kz|b32}-VL
+    2494             :   ASMJIT_INST_3x(vfnmadd213ps, Vfnmadd213ps, X86Xmm, X86Xmm, X86Mem)          // FMA  AVX512_F{kz|b32}-VL
+    2495             :   ASMJIT_INST_3x(vfnmadd213ps, Vfnmadd213ps, X86Ymm, X86Ymm, X86Ymm)          // FMA  AVX512_F{kz|b32}-VL
+    2496             :   ASMJIT_INST_3x(vfnmadd213ps, Vfnmadd213ps, X86Ymm, X86Ymm, X86Mem)          // FMA  AVX512_F{kz|b32}-VL
+    2497             :   ASMJIT_INST_3x(vfnmadd213ps, Vfnmadd213ps, X86Zmm, X86Zmm, X86Zmm)          // FMA  AVX512_F{kz|er|b32}
+    2498             :   ASMJIT_INST_3x(vfnmadd213ps, Vfnmadd213ps, X86Zmm, X86Zmm, X86Mem)          // FMA  AVX512_F{kz|er|b32}
+    2499             :   ASMJIT_INST_3x(vfnmadd213sd, Vfnmadd213sd, X86Xmm, X86Xmm, X86Xmm)          // FMA  AVX512_F{kz|er}
+    2500             :   ASMJIT_INST_3x(vfnmadd213sd, Vfnmadd213sd, X86Xmm, X86Xmm, X86Mem)          // FMA  AVX512_F{kz|er}
+    2501             :   ASMJIT_INST_3x(vfnmadd213ss, Vfnmadd213ss, X86Xmm, X86Xmm, X86Xmm)          // FMA  AVX512_F{kz|er}
+    2502             :   ASMJIT_INST_3x(vfnmadd213ss, Vfnmadd213ss, X86Xmm, X86Xmm, X86Mem)          // FMA  AVX512_F{kz|er}
+    2503             :   ASMJIT_INST_3x(vfnmadd231pd, Vfnmadd231pd, X86Xmm, X86Xmm, X86Xmm)          // FMA  AVX512_F{kz|b64}-VL
+    2504             :   ASMJIT_INST_3x(vfnmadd231pd, Vfnmadd231pd, X86Xmm, X86Xmm, X86Mem)          // FMA  AVX512_F{kz|b64}-VL
+    2505             :   ASMJIT_INST_3x(vfnmadd231pd, Vfnmadd231pd, X86Ymm, X86Ymm, X86Ymm)          // FMA  AVX512_F{kz|b64}-VL
+    2506             :   ASMJIT_INST_3x(vfnmadd231pd, Vfnmadd231pd, X86Ymm, X86Ymm, X86Mem)          // FMA  AVX512_F{kz|b64}-VL
+    2507             :   ASMJIT_INST_3x(vfnmadd231pd, Vfnmadd231pd, X86Zmm, X86Zmm, X86Zmm)          // FMA  AVX512_F{kz|er|b64}
+    2508             :   ASMJIT_INST_3x(vfnmadd231pd, Vfnmadd231pd, X86Zmm, X86Zmm, X86Mem)          // FMA  AVX512_F{kz|er|b64}
+    2509             :   ASMJIT_INST_3x(vfnmadd231ps, Vfnmadd231ps, X86Xmm, X86Xmm, X86Xmm)          // FMA  AVX512_F{kz|b32}-VL
+    2510             :   ASMJIT_INST_3x(vfnmadd231ps, Vfnmadd231ps, X86Xmm, X86Xmm, X86Mem)          // FMA  AVX512_F{kz|b32}-VL
+    2511             :   ASMJIT_INST_3x(vfnmadd231ps, Vfnmadd231ps, X86Ymm, X86Ymm, X86Ymm)          // FMA  AVX512_F{kz|b32}-VL
+    2512             :   ASMJIT_INST_3x(vfnmadd231ps, Vfnmadd231ps, X86Ymm, X86Ymm, X86Mem)          // FMA  AVX512_F{kz|b32}-VL
+    2513             :   ASMJIT_INST_3x(vfnmadd231ps, Vfnmadd231ps, X86Zmm, X86Zmm, X86Zmm)          // FMA  AVX512_F{kz|er|b32}
+    2514             :   ASMJIT_INST_3x(vfnmadd231ps, Vfnmadd231ps, X86Zmm, X86Zmm, X86Mem)          // FMA  AVX512_F{kz|er|b32}
+    2515             :   ASMJIT_INST_3x(vfnmadd231sd, Vfnmadd231sd, X86Xmm, X86Xmm, X86Xmm)          // FMA  AVX512_F{kz|er}
+    2516             :   ASMJIT_INST_3x(vfnmadd231sd, Vfnmadd231sd, X86Xmm, X86Xmm, X86Mem)          // FMA  AVX512_F{kz|er}
+    2517             :   ASMJIT_INST_3x(vfnmadd231ss, Vfnmadd231ss, X86Xmm, X86Xmm, X86Xmm)          // FMA  AVX512_F{kz|er}
+    2518             :   ASMJIT_INST_3x(vfnmadd231ss, Vfnmadd231ss, X86Xmm, X86Xmm, X86Mem)          // FMA  AVX512_F{kz|er}
+    2519             :   ASMJIT_INST_3x(vfnmsub132pd, Vfnmsub132pd, X86Xmm, X86Xmm, X86Xmm)          // FMA  AVX512_F{kz|b64}-VL
+    2520             :   ASMJIT_INST_3x(vfnmsub132pd, Vfnmsub132pd, X86Xmm, X86Xmm, X86Mem)          // FMA  AVX512_F{kz|b64}-VL
+    2521             :   ASMJIT_INST_3x(vfnmsub132pd, Vfnmsub132pd, X86Ymm, X86Ymm, X86Ymm)          // FMA  AVX512_F{kz|b64}-VL
+    2522             :   ASMJIT_INST_3x(vfnmsub132pd, Vfnmsub132pd, X86Ymm, X86Ymm, X86Mem)          // FMA  AVX512_F{kz|b64}-VL
+    2523             :   ASMJIT_INST_3x(vfnmsub132pd, Vfnmsub132pd, X86Zmm, X86Zmm, X86Zmm)          // FMA  AVX512_F{kz|er|b64}
+    2524             :   ASMJIT_INST_3x(vfnmsub132pd, Vfnmsub132pd, X86Zmm, X86Zmm, X86Mem)          // FMA  AVX512_F{kz|er|b64}
+    2525             :   ASMJIT_INST_3x(vfnmsub132ps, Vfnmsub132ps, X86Xmm, X86Xmm, X86Xmm)          // FMA  AVX512_F{kz|b32}-VL
+    2526             :   ASMJIT_INST_3x(vfnmsub132ps, Vfnmsub132ps, X86Xmm, X86Xmm, X86Mem)          // FMA  AVX512_F{kz|b32}-VL
+    2527             :   ASMJIT_INST_3x(vfnmsub132ps, Vfnmsub132ps, X86Ymm, X86Ymm, X86Ymm)          // FMA  AVX512_F{kz|b32}-VL
+    2528             :   ASMJIT_INST_3x(vfnmsub132ps, Vfnmsub132ps, X86Ymm, X86Ymm, X86Mem)          // FMA  AVX512_F{kz|b32}-VL
+    2529             :   ASMJIT_INST_3x(vfnmsub132ps, Vfnmsub132ps, X86Zmm, X86Zmm, X86Zmm)          // FMA  AVX512_F{kz|er|b32}
+    2530             :   ASMJIT_INST_3x(vfnmsub132ps, Vfnmsub132ps, X86Zmm, X86Zmm, X86Mem)          // FMA  AVX512_F{kz|er|b32}
+    2531             :   ASMJIT_INST_3x(vfnmsub132sd, Vfnmsub132sd, X86Xmm, X86Xmm, X86Xmm)          // FMA  AVX512_F{kz|er}
+    2532             :   ASMJIT_INST_3x(vfnmsub132sd, Vfnmsub132sd, X86Xmm, X86Xmm, X86Mem)          // FMA  AVX512_F{kz|er}
+    2533             :   ASMJIT_INST_3x(vfnmsub132ss, Vfnmsub132ss, X86Xmm, X86Xmm, X86Xmm)          // FMA  AVX512_F{kz|er}
+    2534             :   ASMJIT_INST_3x(vfnmsub132ss, Vfnmsub132ss, X86Xmm, X86Xmm, X86Mem)          // FMA  AVX512_F{kz|er}
+    2535             :   ASMJIT_INST_3x(vfnmsub213pd, Vfnmsub213pd, X86Xmm, X86Xmm, X86Xmm)          // FMA  AVX512_F{kz|b64}-VL
+    2536             :   ASMJIT_INST_3x(vfnmsub213pd, Vfnmsub213pd, X86Xmm, X86Xmm, X86Mem)          // FMA  AVX512_F{kz|b64}-VL
+    2537             :   ASMJIT_INST_3x(vfnmsub213pd, Vfnmsub213pd, X86Ymm, X86Ymm, X86Ymm)          // FMA  AVX512_F{kz|b64}-VL
+    2538             :   ASMJIT_INST_3x(vfnmsub213pd, Vfnmsub213pd, X86Ymm, X86Ymm, X86Mem)          // FMA  AVX512_F{kz|b64}-VL
+    2539             :   ASMJIT_INST_3x(vfnmsub213pd, Vfnmsub213pd, X86Zmm, X86Zmm, X86Zmm)          // FMA  AVX512_F{kz|er|b64}
+    2540             :   ASMJIT_INST_3x(vfnmsub213pd, Vfnmsub213pd, X86Zmm, X86Zmm, X86Mem)          // FMA  AVX512_F{kz|er|b64}
+    2541             :   ASMJIT_INST_3x(vfnmsub213ps, Vfnmsub213ps, X86Xmm, X86Xmm, X86Xmm)          // FMA  AVX512_F{kz|b32}-VL
+    2542             :   ASMJIT_INST_3x(vfnmsub213ps, Vfnmsub213ps, X86Xmm, X86Xmm, X86Mem)          // FMA  AVX512_F{kz|b32}-VL
+    2543             :   ASMJIT_INST_3x(vfnmsub213ps, Vfnmsub213ps, X86Ymm, X86Ymm, X86Ymm)          // FMA  AVX512_F{kz|b32}-VL
+    2544             :   ASMJIT_INST_3x(vfnmsub213ps, Vfnmsub213ps, X86Ymm, X86Ymm, X86Mem)          // FMA  AVX512_F{kz|b32}-VL
+    2545             :   ASMJIT_INST_3x(vfnmsub213ps, Vfnmsub213ps, X86Zmm, X86Zmm, X86Zmm)          // FMA  AVX512_F{kz|er|b32}
+    2546             :   ASMJIT_INST_3x(vfnmsub213ps, Vfnmsub213ps, X86Zmm, X86Zmm, X86Mem)          // FMA  AVX512_F{kz|er|b32}
+    2547             :   ASMJIT_INST_3x(vfnmsub213sd, Vfnmsub213sd, X86Xmm, X86Xmm, X86Xmm)          // FMA  AVX512_F{kz|er}
+    2548             :   ASMJIT_INST_3x(vfnmsub213sd, Vfnmsub213sd, X86Xmm, X86Xmm, X86Mem)          // FMA  AVX512_F{kz|er}
+    2549             :   ASMJIT_INST_3x(vfnmsub213ss, Vfnmsub213ss, X86Xmm, X86Xmm, X86Xmm)          // FMA  AVX512_F{kz|er}
+    2550             :   ASMJIT_INST_3x(vfnmsub213ss, Vfnmsub213ss, X86Xmm, X86Xmm, X86Mem)          // FMA  AVX512_F{kz|er}
+    2551             :   ASMJIT_INST_3x(vfnmsub231pd, Vfnmsub231pd, X86Xmm, X86Xmm, X86Xmm)          // FMA  AVX512_F{kz|b64}-VL
+    2552             :   ASMJIT_INST_3x(vfnmsub231pd, Vfnmsub231pd, X86Xmm, X86Xmm, X86Mem)          // FMA  AVX512_F{kz|b64}-VL
+    2553             :   ASMJIT_INST_3x(vfnmsub231pd, Vfnmsub231pd, X86Ymm, X86Ymm, X86Ymm)          // FMA  AVX512_F{kz|b64}-VL
+    2554             :   ASMJIT_INST_3x(vfnmsub231pd, Vfnmsub231pd, X86Ymm, X86Ymm, X86Mem)          // FMA  AVX512_F{kz|b64}-VL
+    2555             :   ASMJIT_INST_3x(vfnmsub231pd, Vfnmsub231pd, X86Zmm, X86Zmm, X86Zmm)          // FMA  AVX512_F{kz|er|b64}
+    2556             :   ASMJIT_INST_3x(vfnmsub231pd, Vfnmsub231pd, X86Zmm, X86Zmm, X86Mem)          // FMA  AVX512_F{kz|er|b64}
+    2557             :   ASMJIT_INST_3x(vfnmsub231ps, Vfnmsub231ps, X86Xmm, X86Xmm, X86Xmm)          // FMA  AVX512_F{kz|b32}-VL
+    2558             :   ASMJIT_INST_3x(vfnmsub231ps, Vfnmsub231ps, X86Xmm, X86Xmm, X86Mem)          // FMA  AVX512_F{kz|b32}-VL
+    2559             :   ASMJIT_INST_3x(vfnmsub231ps, Vfnmsub231ps, X86Ymm, X86Ymm, X86Ymm)          // FMA  AVX512_F{kz|b32}-VL
+    2560             :   ASMJIT_INST_3x(vfnmsub231ps, Vfnmsub231ps, X86Ymm, X86Ymm, X86Mem)          // FMA  AVX512_F{kz|b32}-VL
+    2561             :   ASMJIT_INST_3x(vfnmsub231ps, Vfnmsub231ps, X86Zmm, X86Zmm, X86Zmm)          // FMA  AVX512_F{kz|er|b32}
+    2562             :   ASMJIT_INST_3x(vfnmsub231ps, Vfnmsub231ps, X86Zmm, X86Zmm, X86Mem)          // FMA  AVX512_F{kz|er|b32}
+    2563             :   ASMJIT_INST_3x(vfnmsub231sd, Vfnmsub231sd, X86Xmm, X86Xmm, X86Xmm)          // FMA  AVX512_F{kz|er}
+    2564             :   ASMJIT_INST_3x(vfnmsub231sd, Vfnmsub231sd, X86Xmm, X86Xmm, X86Mem)          // FMA  AVX512_F{kz|er}
+    2565             :   ASMJIT_INST_3x(vfnmsub231ss, Vfnmsub231ss, X86Xmm, X86Xmm, X86Xmm)          // FMA  AVX512_F{kz|er}
+    2566             :   ASMJIT_INST_3x(vfnmsub231ss, Vfnmsub231ss, X86Xmm, X86Xmm, X86Mem)          // FMA  AVX512_F{kz|er}
+    2567             :   ASMJIT_INST_3i(vfpclasspd, Vfpclasspd, X86KReg, X86Xmm, Imm)                //      AVX512_DQ{k|b64}-VL
+    2568             :   ASMJIT_INST_3i(vfpclasspd, Vfpclasspd, X86KReg, X86Mem, Imm)                //      AVX512_DQ{k|b64} AVX512_DQ{k|b64}-VL
+    2569             :   ASMJIT_INST_3i(vfpclasspd, Vfpclasspd, X86KReg, X86Ymm, Imm)                //      AVX512_DQ{k|b64}-VL
+    2570             :   ASMJIT_INST_3i(vfpclasspd, Vfpclasspd, X86KReg, X86Zmm, Imm)                //      AVX512_DQ{k|b64}
+    2571             :   ASMJIT_INST_3i(vfpclassps, Vfpclassps, X86KReg, X86Xmm, Imm)                //      AVX512_DQ{k|b32}-VL
+    2572             :   ASMJIT_INST_3i(vfpclassps, Vfpclassps, X86KReg, X86Mem, Imm)                //      AVX512_DQ{k|b32} AVX512_DQ{k|b32}-VL
+    2573             :   ASMJIT_INST_3i(vfpclassps, Vfpclassps, X86KReg, X86Ymm, Imm)                //      AVX512_DQ{k|b32}-VL
+    2574             :   ASMJIT_INST_3i(vfpclassps, Vfpclassps, X86KReg, X86Zmm, Imm)                //      AVX512_DQ{k|b32}
+    2575             :   ASMJIT_INST_3i(vfpclasssd, Vfpclasssd, X86KReg, X86Xmm, Imm)                //      AVX512_DQ{k}
+    2576             :   ASMJIT_INST_3i(vfpclasssd, Vfpclasssd, X86KReg, X86Mem, Imm)                //      AVX512_DQ{k}
+    2577             :   ASMJIT_INST_3i(vfpclassss, Vfpclassss, X86KReg, X86Xmm, Imm)                //      AVX512_DQ{k}
+    2578             :   ASMJIT_INST_3i(vfpclassss, Vfpclassss, X86KReg, X86Mem, Imm)                //      AVX512_DQ{k}
+    2579             :   ASMJIT_INST_3x(vgatherdpd, Vgatherdpd, X86Xmm, X86Mem, X86Xmm)              // AVX2
+    2580             :   ASMJIT_INST_3x(vgatherdpd, Vgatherdpd, X86Ymm, X86Mem, X86Ymm)              // AVX2
+    2581             :   ASMJIT_INST_2x(vgatherdpd, Vgatherdpd, X86Xmm, X86Mem)                      //      AVX512_F{k}-VL
+    2582             :   ASMJIT_INST_2x(vgatherdpd, Vgatherdpd, X86Ymm, X86Mem)                      //      AVX512_F{k}-VL
+    2583             :   ASMJIT_INST_2x(vgatherdpd, Vgatherdpd, X86Zmm, X86Mem)                      //      AVX512_F{k}
+    2584             :   ASMJIT_INST_3x(vgatherdps, Vgatherdps, X86Xmm, X86Mem, X86Xmm)              // AVX2
+    2585             :   ASMJIT_INST_3x(vgatherdps, Vgatherdps, X86Ymm, X86Mem, X86Ymm)              // AVX2
+    2586             :   ASMJIT_INST_2x(vgatherdps, Vgatherdps, X86Xmm, X86Mem)                      //      AVX512_F{k}-VL
+    2587             :   ASMJIT_INST_2x(vgatherdps, Vgatherdps, X86Ymm, X86Mem)                      //      AVX512_F{k}-VL
+    2588             :   ASMJIT_INST_2x(vgatherdps, Vgatherdps, X86Zmm, X86Mem)                      //      AVX512_F{k}
+    2589             :   ASMJIT_INST_1x(vgatherpf0dpd, Vgatherpf0dpd, X86Mem)                        //      AVX512_PF{k}
+    2590             :   ASMJIT_INST_1x(vgatherpf0dps, Vgatherpf0dps, X86Mem)                        //      AVX512_PF{k}
+    2591             :   ASMJIT_INST_1x(vgatherpf0qpd, Vgatherpf0qpd, X86Mem)                        //      AVX512_PF{k}
+    2592             :   ASMJIT_INST_1x(vgatherpf0qps, Vgatherpf0qps, X86Mem)                        //      AVX512_PF{k}
+    2593             :   ASMJIT_INST_1x(vgatherpf1dpd, Vgatherpf1dpd, X86Mem)                        //      AVX512_PF{k}
+    2594             :   ASMJIT_INST_1x(vgatherpf1dps, Vgatherpf1dps, X86Mem)                        //      AVX512_PF{k}
+    2595             :   ASMJIT_INST_1x(vgatherpf1qpd, Vgatherpf1qpd, X86Mem)                        //      AVX512_PF{k}
+    2596             :   ASMJIT_INST_1x(vgatherpf1qps, Vgatherpf1qps, X86Mem)                        //      AVX512_PF{k}
+    2597             :   ASMJIT_INST_3x(vgatherqpd, Vgatherqpd, X86Xmm, X86Mem, X86Xmm)              // AVX2
+    2598             :   ASMJIT_INST_3x(vgatherqpd, Vgatherqpd, X86Ymm, X86Mem, X86Ymm)              // AVX2
+    2599             :   ASMJIT_INST_2x(vgatherqpd, Vgatherqpd, X86Xmm, X86Mem)                      //      AVX512_F{k}-VL
+    2600             :   ASMJIT_INST_2x(vgatherqpd, Vgatherqpd, X86Ymm, X86Mem)                      //      AVX512_F{k}-VL
+    2601             :   ASMJIT_INST_2x(vgatherqpd, Vgatherqpd, X86Zmm, X86Mem)                      //      AVX512_F{k}
+    2602             :   ASMJIT_INST_3x(vgatherqps, Vgatherqps, X86Xmm, X86Mem, X86Xmm)              // AVX2
+    2603             :   ASMJIT_INST_2x(vgatherqps, Vgatherqps, X86Xmm, X86Mem)                      //      AVX512_F{k}-VL
+    2604             :   ASMJIT_INST_2x(vgatherqps, Vgatherqps, X86Ymm, X86Mem)                      //      AVX512_F{k}-VL
+    2605             :   ASMJIT_INST_2x(vgatherqps, Vgatherqps, X86Zmm, X86Mem)                      //      AVX512_F{k}
+    2606             :   ASMJIT_INST_2x(vgetexppd, Vgetexppd, X86Xmm, X86Xmm)                        //      AVX512_F{kz|b64}-VL
+    2607             :   ASMJIT_INST_2x(vgetexppd, Vgetexppd, X86Xmm, X86Mem)                        //      AVX512_F{kz|b64}-VL
+    2608             :   ASMJIT_INST_2x(vgetexppd, Vgetexppd, X86Ymm, X86Ymm)                        //      AVX512_F{kz|b64}-VL
+    2609             :   ASMJIT_INST_2x(vgetexppd, Vgetexppd, X86Ymm, X86Mem)                        //      AVX512_F{kz|b64}-VL
+    2610             :   ASMJIT_INST_2x(vgetexppd, Vgetexppd, X86Zmm, X86Zmm)                        //      AVX512_F{kz|sae|b64}
+    2611             :   ASMJIT_INST_2x(vgetexppd, Vgetexppd, X86Zmm, X86Mem)                        //      AVX512_F{kz|sae|b64}
+    2612             :   ASMJIT_INST_2x(vgetexpps, Vgetexpps, X86Xmm, X86Xmm)                        //      AVX512_F{kz|b32}-VL
+    2613             :   ASMJIT_INST_2x(vgetexpps, Vgetexpps, X86Xmm, X86Mem)                        //      AVX512_F{kz|b32}-VL
+    2614             :   ASMJIT_INST_2x(vgetexpps, Vgetexpps, X86Ymm, X86Ymm)                        //      AVX512_F{kz|b32}-VL
+    2615             :   ASMJIT_INST_2x(vgetexpps, Vgetexpps, X86Ymm, X86Mem)                        //      AVX512_F{kz|b32}-VL
+    2616             :   ASMJIT_INST_2x(vgetexpps, Vgetexpps, X86Zmm, X86Zmm)                        //      AVX512_F{kz|sae|b32}
+    2617             :   ASMJIT_INST_2x(vgetexpps, Vgetexpps, X86Zmm, X86Mem)                        //      AVX512_F{kz|sae|b32}
+    2618             :   ASMJIT_INST_2x(vgetexpsd, Vgetexpsd, X86Xmm, X86Xmm)                        //      AVX512_F{kz|sae}
+    2619             :   ASMJIT_INST_2x(vgetexpsd, Vgetexpsd, X86Xmm, X86Mem)                        //      AVX512_F{kz|sae}
+    2620             :   ASMJIT_INST_2x(vgetexpss, Vgetexpss, X86Xmm, X86Xmm)                        //      AVX512_F{kz|sae}
+    2621             :   ASMJIT_INST_2x(vgetexpss, Vgetexpss, X86Xmm, X86Mem)                        //      AVX512_F{kz|sae}
+    2622             :   ASMJIT_INST_3i(vgetmantpd, Vgetmantpd, X86Xmm, X86Xmm, Imm)                 //      AVX512_F{kz|b64}-VL
+    2623             :   ASMJIT_INST_3i(vgetmantpd, Vgetmantpd, X86Xmm, X86Mem, Imm)                 //      AVX512_F{kz|b64}-VL
+    2624             :   ASMJIT_INST_3i(vgetmantpd, Vgetmantpd, X86Ymm, X86Ymm, Imm)                 //      AVX512_F{kz|b64}-VL
+    2625             :   ASMJIT_INST_3i(vgetmantpd, Vgetmantpd, X86Ymm, X86Mem, Imm)                 //      AVX512_F{kz|b64}-VL
+    2626             :   ASMJIT_INST_3i(vgetmantpd, Vgetmantpd, X86Zmm, X86Zmm, Imm)                 //      AVX512_F{kz|sae|b64}
+    2627             :   ASMJIT_INST_3i(vgetmantpd, Vgetmantpd, X86Zmm, X86Mem, Imm)                 //      AVX512_F{kz|sae|b64}
+    2628             :   ASMJIT_INST_3i(vgetmantps, Vgetmantps, X86Xmm, X86Xmm, Imm)                 //      AVX512_F{kz|b32}-VL
+    2629             :   ASMJIT_INST_3i(vgetmantps, Vgetmantps, X86Xmm, X86Mem, Imm)                 //      AVX512_F{kz|b32}-VL
+    2630             :   ASMJIT_INST_3i(vgetmantps, Vgetmantps, X86Ymm, X86Ymm, Imm)                 //      AVX512_F{kz|b32}-VL
+    2631             :   ASMJIT_INST_3i(vgetmantps, Vgetmantps, X86Ymm, X86Mem, Imm)                 //      AVX512_F{kz|b32}-VL
+    2632             :   ASMJIT_INST_3i(vgetmantps, Vgetmantps, X86Zmm, X86Zmm, Imm)                 //      AVX512_F{kz|sae|b32}
+    2633             :   ASMJIT_INST_3i(vgetmantps, Vgetmantps, X86Zmm, X86Mem, Imm)                 //      AVX512_F{kz|sae|b32}
+    2634             :   ASMJIT_INST_3i(vgetmantsd, Vgetmantsd, X86Xmm, X86Xmm, Imm)                 //      AVX512_F{kz|sae}
+    2635             :   ASMJIT_INST_3i(vgetmantsd, Vgetmantsd, X86Xmm, X86Mem, Imm)                 //      AVX512_F{kz|sae}
+    2636             :   ASMJIT_INST_3i(vgetmantss, Vgetmantss, X86Xmm, X86Xmm, Imm)                 //      AVX512_F{kz|sae}
+    2637             :   ASMJIT_INST_3i(vgetmantss, Vgetmantss, X86Xmm, X86Mem, Imm)                 //      AVX512_F{kz|sae}
+    2638             :   ASMJIT_INST_3x(vhaddpd, Vhaddpd, X86Xmm, X86Xmm, X86Xmm)                    // AVX
+    2639             :   ASMJIT_INST_3x(vhaddpd, Vhaddpd, X86Xmm, X86Xmm, X86Mem)                    // AVX
+    2640             :   ASMJIT_INST_3x(vhaddpd, Vhaddpd, X86Ymm, X86Ymm, X86Ymm)                    // AVX
+    2641             :   ASMJIT_INST_3x(vhaddpd, Vhaddpd, X86Ymm, X86Ymm, X86Mem)                    // AVX
+    2642             :   ASMJIT_INST_3x(vhaddps, Vhaddps, X86Xmm, X86Xmm, X86Xmm)                    // AVX
+    2643             :   ASMJIT_INST_3x(vhaddps, Vhaddps, X86Xmm, X86Xmm, X86Mem)                    // AVX
+    2644             :   ASMJIT_INST_3x(vhaddps, Vhaddps, X86Ymm, X86Ymm, X86Ymm)                    // AVX
+    2645             :   ASMJIT_INST_3x(vhaddps, Vhaddps, X86Ymm, X86Ymm, X86Mem)                    // AVX
+    2646             :   ASMJIT_INST_3x(vhsubpd, Vhsubpd, X86Xmm, X86Xmm, X86Xmm)                    // AVX
+    2647             :   ASMJIT_INST_3x(vhsubpd, Vhsubpd, X86Xmm, X86Xmm, X86Mem)                    // AVX
+    2648             :   ASMJIT_INST_3x(vhsubpd, Vhsubpd, X86Ymm, X86Ymm, X86Ymm)                    // AVX
+    2649             :   ASMJIT_INST_3x(vhsubpd, Vhsubpd, X86Ymm, X86Ymm, X86Mem)                    // AVX
+    2650             :   ASMJIT_INST_3x(vhsubps, Vhsubps, X86Xmm, X86Xmm, X86Xmm)                    // AVX
+    2651             :   ASMJIT_INST_3x(vhsubps, Vhsubps, X86Xmm, X86Xmm, X86Mem)                    // AVX
+    2652             :   ASMJIT_INST_3x(vhsubps, Vhsubps, X86Ymm, X86Ymm, X86Ymm)                    // AVX
+    2653             :   ASMJIT_INST_3x(vhsubps, Vhsubps, X86Ymm, X86Ymm, X86Mem)                    // AVX
+    2654             :   ASMJIT_INST_4i(vinsertf128, Vinsertf128, X86Ymm, X86Ymm, X86Xmm, Imm)       // AVX
+    2655             :   ASMJIT_INST_4i(vinsertf128, Vinsertf128, X86Ymm, X86Ymm, X86Mem, Imm)       // AVX
+    2656             :   ASMJIT_INST_4i(vinsertf32x4, Vinsertf32x4, X86Ymm, X86Ymm, X86Xmm, Imm)     //      AVX512_F{kz}-VL
+    2657             :   ASMJIT_INST_4i(vinsertf32x4, Vinsertf32x4, X86Ymm, X86Ymm, X86Mem, Imm)     //      AVX512_F{kz}-VL
+    2658             :   ASMJIT_INST_4i(vinsertf32x4, Vinsertf32x4, X86Zmm, X86Zmm, X86Xmm, Imm)     //      AVX512_F{kz}
+    2659             :   ASMJIT_INST_4i(vinsertf32x4, Vinsertf32x4, X86Zmm, X86Zmm, X86Mem, Imm)     //      AVX512_F{kz}
+    2660             :   ASMJIT_INST_4i(vinsertf32x8, Vinsertf32x8, X86Zmm, X86Zmm, X86Ymm, Imm)     //      AVX512_DQ{kz}
+    2661             :   ASMJIT_INST_4i(vinsertf32x8, Vinsertf32x8, X86Zmm, X86Zmm, X86Mem, Imm)     //      AVX512_DQ{kz}
+    2662             :   ASMJIT_INST_4i(vinsertf64x2, Vinsertf64x2, X86Ymm, X86Ymm, X86Xmm, Imm)     //      AVX512_DQ{kz}-VL
+    2663             :   ASMJIT_INST_4i(vinsertf64x2, Vinsertf64x2, X86Ymm, X86Ymm, X86Mem, Imm)     //      AVX512_DQ{kz}-VL
+    2664             :   ASMJIT_INST_4i(vinsertf64x2, Vinsertf64x2, X86Zmm, X86Zmm, X86Xmm, Imm)     //      AVX512_DQ{kz}
+    2665             :   ASMJIT_INST_4i(vinsertf64x2, Vinsertf64x2, X86Zmm, X86Zmm, X86Mem, Imm)     //      AVX512_DQ{kz}
+    2666             :   ASMJIT_INST_4i(vinsertf64x4, Vinsertf64x4, X86Zmm, X86Zmm, X86Ymm, Imm)     //      AVX512_F{kz}
+    2667             :   ASMJIT_INST_4i(vinsertf64x4, Vinsertf64x4, X86Zmm, X86Zmm, X86Mem, Imm)     //      AVX512_F{kz}
+    2668             :   ASMJIT_INST_4i(vinserti128, Vinserti128, X86Ymm, X86Ymm, X86Xmm, Imm)       // AVX2
+    2669             :   ASMJIT_INST_4i(vinserti128, Vinserti128, X86Ymm, X86Ymm, X86Mem, Imm)       // AVX2
+    2670             :   ASMJIT_INST_4i(vinserti32x4, Vinserti32x4, X86Ymm, X86Ymm, X86Xmm, Imm)     //      AVX512_F{kz}-VL
+    2671             :   ASMJIT_INST_4i(vinserti32x4, Vinserti32x4, X86Ymm, X86Ymm, X86Mem, Imm)     //      AVX512_F{kz}-VL
+    2672             :   ASMJIT_INST_4i(vinserti32x4, Vinserti32x4, X86Zmm, X86Zmm, X86Xmm, Imm)     //      AVX512_F{kz}
+    2673             :   ASMJIT_INST_4i(vinserti32x4, Vinserti32x4, X86Zmm, X86Zmm, X86Mem, Imm)     //      AVX512_F{kz}
+    2674             :   ASMJIT_INST_4i(vinserti32x8, Vinserti32x8, X86Zmm, X86Zmm, X86Ymm, Imm)     //      AVX512_DQ{kz}
+    2675             :   ASMJIT_INST_4i(vinserti32x8, Vinserti32x8, X86Zmm, X86Zmm, X86Mem, Imm)     //      AVX512_DQ{kz}
+    2676             :   ASMJIT_INST_4i(vinserti64x2, Vinserti64x2, X86Ymm, X86Ymm, X86Xmm, Imm)     //      AVX512_DQ{kz}-VL
+    2677             :   ASMJIT_INST_4i(vinserti64x2, Vinserti64x2, X86Ymm, X86Ymm, X86Mem, Imm)     //      AVX512_DQ{kz}-VL
+    2678             :   ASMJIT_INST_4i(vinserti64x2, Vinserti64x2, X86Zmm, X86Zmm, X86Xmm, Imm)     //      AVX512_DQ{kz}
+    2679             :   ASMJIT_INST_4i(vinserti64x2, Vinserti64x2, X86Zmm, X86Zmm, X86Mem, Imm)     //      AVX512_DQ{kz}
+    2680             :   ASMJIT_INST_4i(vinserti64x4, Vinserti64x4, X86Zmm, X86Zmm, X86Ymm, Imm)     //      AVX512_F{kz}
+    2681             :   ASMJIT_INST_4i(vinserti64x4, Vinserti64x4, X86Zmm, X86Zmm, X86Mem, Imm)     //      AVX512_F{kz}
+    2682             :   ASMJIT_INST_4i(vinsertps, Vinsertps, X86Xmm, X86Xmm, X86Xmm, Imm)           // AVX  AVX512_F
+    2683             :   ASMJIT_INST_4i(vinsertps, Vinsertps, X86Xmm, X86Xmm, X86Mem, Imm)           // AVX  AVX512_F
+    2684             :   ASMJIT_INST_2x(vlddqu, Vlddqu, X86Xmm, X86Mem)                              // AVX
+    2685             :   ASMJIT_INST_2x(vlddqu, Vlddqu, X86Ymm, X86Mem)                              // AVX
+    2686             :   ASMJIT_INST_1x(vldmxcsr, Vldmxcsr, X86Mem)                                  // AVX
+    2687             :   ASMJIT_INST_3x(vmaskmovdqu, Vmaskmovdqu, X86Xmm, X86Xmm, DS_ZDI)            // AVX  [EXPLICIT]
+    2688             :   ASMJIT_INST_3x(vmaskmovpd, Vmaskmovpd, X86Mem, X86Xmm, X86Xmm)              // AVX
+    2689             :   ASMJIT_INST_3x(vmaskmovpd, Vmaskmovpd, X86Mem, X86Ymm, X86Ymm)              // AVX
+    2690             :   ASMJIT_INST_3x(vmaskmovpd, Vmaskmovpd, X86Xmm, X86Xmm, X86Mem)              // AVX
+    2691             :   ASMJIT_INST_3x(vmaskmovpd, Vmaskmovpd, X86Ymm, X86Ymm, X86Mem)              // AVX
+    2692             :   ASMJIT_INST_3x(vmaskmovps, Vmaskmovps, X86Mem, X86Xmm, X86Xmm)              // AVX
+    2693             :   ASMJIT_INST_3x(vmaskmovps, Vmaskmovps, X86Mem, X86Ymm, X86Ymm)              // AVX
+    2694             :   ASMJIT_INST_3x(vmaskmovps, Vmaskmovps, X86Xmm, X86Xmm, X86Mem)              // AVX
+    2695             :   ASMJIT_INST_3x(vmaskmovps, Vmaskmovps, X86Ymm, X86Ymm, X86Mem)              // AVX
+    2696             :   ASMJIT_INST_3x(vmaxpd, Vmaxpd, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|b64}-VL
+    2697             :   ASMJIT_INST_3x(vmaxpd, Vmaxpd, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|b64}-VL
+    2698             :   ASMJIT_INST_3x(vmaxpd, Vmaxpd, X86Ymm, X86Ymm, X86Ymm)                      // AVX  AVX512_F{kz|b64}-VL
+    2699             :   ASMJIT_INST_3x(vmaxpd, Vmaxpd, X86Ymm, X86Ymm, X86Mem)                      // AVX  AVX512_F{kz|b64}-VL
+    2700             :   ASMJIT_INST_3x(vmaxpd, Vmaxpd, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_F{kz|sae|b64}
+    2701             :   ASMJIT_INST_3x(vmaxpd, Vmaxpd, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_F{kz|sae|b64}
+    2702             :   ASMJIT_INST_3x(vmaxps, Vmaxps, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|b32}-VL
+    2703             :   ASMJIT_INST_3x(vmaxps, Vmaxps, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|b32}-VL
+    2704             :   ASMJIT_INST_3x(vmaxps, Vmaxps, X86Ymm, X86Ymm, X86Ymm)                      // AVX  AVX512_F{kz|b32}-VL
+    2705             :   ASMJIT_INST_3x(vmaxps, Vmaxps, X86Ymm, X86Ymm, X86Mem)                      // AVX  AVX512_F{kz|b32}-VL
+    2706             :   ASMJIT_INST_3x(vmaxps, Vmaxps, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_F{kz|sae|b32}
+    2707             :   ASMJIT_INST_3x(vmaxps, Vmaxps, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_F{kz|sae|b32}
+    2708             :   ASMJIT_INST_3x(vmaxsd, Vmaxsd, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|sae}-VL
+    2709             :   ASMJIT_INST_3x(vmaxsd, Vmaxsd, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|sae}-VL
+    2710             :   ASMJIT_INST_3x(vmaxss, Vmaxss, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|sae}-VL
+    2711             :   ASMJIT_INST_3x(vmaxss, Vmaxss, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|sae}-VL
+    2712             :   ASMJIT_INST_3x(vminpd, Vminpd, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|b64}-VL
+    2713             :   ASMJIT_INST_3x(vminpd, Vminpd, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|b64}-VL
+    2714             :   ASMJIT_INST_3x(vminpd, Vminpd, X86Ymm, X86Ymm, X86Ymm)                      // AVX  AVX512_F{kz|b64}-VL
+    2715             :   ASMJIT_INST_3x(vminpd, Vminpd, X86Ymm, X86Ymm, X86Mem)                      // AVX  AVX512_F{kz|b64}-VL
+    2716             :   ASMJIT_INST_3x(vminpd, Vminpd, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_F{kz|sae|b64}
+    2717             :   ASMJIT_INST_3x(vminpd, Vminpd, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_F{kz|sae|b64}
+    2718             :   ASMJIT_INST_3x(vminps, Vminps, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|b32}-VL
+    2719             :   ASMJIT_INST_3x(vminps, Vminps, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|b32}-VL
+    2720             :   ASMJIT_INST_3x(vminps, Vminps, X86Ymm, X86Ymm, X86Ymm)                      // AVX  AVX512_F{kz|b32}-VL
+    2721             :   ASMJIT_INST_3x(vminps, Vminps, X86Ymm, X86Ymm, X86Mem)                      // AVX  AVX512_F{kz|b32}-VL
+    2722             :   ASMJIT_INST_3x(vminps, Vminps, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_F{kz|sae|b32}
+    2723             :   ASMJIT_INST_3x(vminps, Vminps, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_F{kz|sae|b32}
+    2724             :   ASMJIT_INST_3x(vminsd, Vminsd, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|sae}-VL
+    2725             :   ASMJIT_INST_3x(vminsd, Vminsd, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|sae}-VL
+    2726             :   ASMJIT_INST_3x(vminss, Vminss, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|sae}-VL
+    2727             :   ASMJIT_INST_3x(vminss, Vminss, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|sae}-VL
+    2728             :   ASMJIT_INST_2x(vmovapd, Vmovapd, X86Xmm, X86Xmm)                            // AVX  AVX512_F{kz}-VL
+    2729             :   ASMJIT_INST_2x(vmovapd, Vmovapd, X86Xmm, X86Mem)                            // AVX  AVX512_F{kz}-VL
+    2730             :   ASMJIT_INST_2x(vmovapd, Vmovapd, X86Mem, X86Xmm)                            // AVX  AVX512_F{kz}-VL
+    2731             :   ASMJIT_INST_2x(vmovapd, Vmovapd, X86Ymm, X86Ymm)                            // AVX  AVX512_F{kz}-VL
+    2732             :   ASMJIT_INST_2x(vmovapd, Vmovapd, X86Ymm, X86Mem)                            // AVX  AVX512_F{kz}-VL
+    2733             :   ASMJIT_INST_2x(vmovapd, Vmovapd, X86Mem, X86Ymm)                            // AVX  AVX512_F{kz}-VL
+    2734             :   ASMJIT_INST_2x(vmovapd, Vmovapd, X86Zmm, X86Zmm)                            //      AVX512_F{kz}
+    2735             :   ASMJIT_INST_2x(vmovapd, Vmovapd, X86Zmm, X86Mem)                            //      AVX512_F{kz}
+    2736             :   ASMJIT_INST_2x(vmovapd, Vmovapd, X86Mem, X86Zmm)                            //      AVX512_F{kz}
+    2737             :   ASMJIT_INST_2x(vmovaps, Vmovaps, X86Xmm, X86Xmm)                            // AVX  AVX512_F{kz}-VL
+    2738             :   ASMJIT_INST_2x(vmovaps, Vmovaps, X86Xmm, X86Mem)                            // AVX  AVX512_F{kz}-VL
+    2739             :   ASMJIT_INST_2x(vmovaps, Vmovaps, X86Mem, X86Xmm)                            // AVX  AVX512_F{kz}-VL
+    2740             :   ASMJIT_INST_2x(vmovaps, Vmovaps, X86Ymm, X86Ymm)                            // AVX  AVX512_F{kz}-VL
+    2741             :   ASMJIT_INST_2x(vmovaps, Vmovaps, X86Ymm, X86Mem)                            // AVX  AVX512_F{kz}-VL
+    2742             :   ASMJIT_INST_2x(vmovaps, Vmovaps, X86Mem, X86Ymm)                            // AVX  AVX512_F{kz}-VL
+    2743             :   ASMJIT_INST_2x(vmovaps, Vmovaps, X86Zmm, X86Zmm)                            //      AVX512_F{kz}
+    2744             :   ASMJIT_INST_2x(vmovaps, Vmovaps, X86Zmm, X86Mem)                            //      AVX512_F{kz}
+    2745             :   ASMJIT_INST_2x(vmovaps, Vmovaps, X86Mem, X86Zmm)                            //      AVX512_F{kz}
+    2746             :   ASMJIT_INST_2x(vmovd, Vmovd, X86Gp, X86Xmm)                                 // AVX  AVX512_F
+    2747             :   ASMJIT_INST_2x(vmovd, Vmovd, X86Mem, X86Xmm)                                // AVX  AVX512_F
+    2748             :   ASMJIT_INST_2x(vmovd, Vmovd, X86Xmm, X86Gp)                                 // AVX  AVX512_F
+    2749             :   ASMJIT_INST_2x(vmovd, Vmovd, X86Xmm, X86Mem)                                // AVX  AVX512_F
+    2750             :   ASMJIT_INST_2x(vmovddup, Vmovddup, X86Xmm, X86Xmm)                          // AVX  AVX512_F{kz}-VL
+    2751             :   ASMJIT_INST_2x(vmovddup, Vmovddup, X86Xmm, X86Mem)                          // AVX  AVX512_F{kz}-VL
+    2752             :   ASMJIT_INST_2x(vmovddup, Vmovddup, X86Ymm, X86Ymm)                          // AVX  AVX512_F{kz}-VL
+    2753             :   ASMJIT_INST_2x(vmovddup, Vmovddup, X86Ymm, X86Mem)                          // AVX  AVX512_F{kz}-VL
+    2754             :   ASMJIT_INST_2x(vmovddup, Vmovddup, X86Zmm, X86Zmm)                          //      AVX512_F{kz}
+    2755             :   ASMJIT_INST_2x(vmovddup, Vmovddup, X86Zmm, X86Mem)                          //      AVX512_F{kz}
+    2756             :   ASMJIT_INST_2x(vmovdqa, Vmovdqa, X86Xmm, X86Xmm)                            // AVX
+    2757             :   ASMJIT_INST_2x(vmovdqa, Vmovdqa, X86Xmm, X86Mem)                            // AVX
+    2758             :   ASMJIT_INST_2x(vmovdqa, Vmovdqa, X86Mem, X86Xmm)                            // AVX
+    2759             :   ASMJIT_INST_2x(vmovdqa, Vmovdqa, X86Ymm, X86Ymm)                            // AVX
+    2760             :   ASMJIT_INST_2x(vmovdqa, Vmovdqa, X86Ymm, X86Mem)                            // AVX
+    2761             :   ASMJIT_INST_2x(vmovdqa, Vmovdqa, X86Mem, X86Ymm)                            // AVX
+    2762             :   ASMJIT_INST_2x(vmovdqa32, Vmovdqa32, X86Xmm, X86Xmm)                        //      AVX512_F{kz}-VL
+    2763             :   ASMJIT_INST_2x(vmovdqa32, Vmovdqa32, X86Xmm, X86Mem)                        //      AVX512_F{kz}-VL
+    2764             :   ASMJIT_INST_2x(vmovdqa32, Vmovdqa32, X86Mem, X86Xmm)                        //      AVX512_F{kz}-VL
+    2765             :   ASMJIT_INST_2x(vmovdqa32, Vmovdqa32, X86Ymm, X86Ymm)                        //      AVX512_F{kz}-VL
+    2766             :   ASMJIT_INST_2x(vmovdqa32, Vmovdqa32, X86Ymm, X86Mem)                        //      AVX512_F{kz}-VL
+    2767             :   ASMJIT_INST_2x(vmovdqa32, Vmovdqa32, X86Mem, X86Ymm)                        //      AVX512_F{kz}-VL
+    2768             :   ASMJIT_INST_2x(vmovdqa32, Vmovdqa32, X86Zmm, X86Zmm)                        //      AVX512_F{kz}
+    2769             :   ASMJIT_INST_2x(vmovdqa32, Vmovdqa32, X86Zmm, X86Mem)                        //      AVX512_F{kz}
+    2770             :   ASMJIT_INST_2x(vmovdqa32, Vmovdqa32, X86Mem, X86Zmm)                        //      AVX512_F{kz}
+    2771             :   ASMJIT_INST_2x(vmovdqa64, Vmovdqa64, X86Xmm, X86Xmm)                        //      AVX512_F{kz}-VL
+    2772             :   ASMJIT_INST_2x(vmovdqa64, Vmovdqa64, X86Xmm, X86Mem)                        //      AVX512_F{kz}-VL
+    2773             :   ASMJIT_INST_2x(vmovdqa64, Vmovdqa64, X86Mem, X86Xmm)                        //      AVX512_F{kz}-VL
+    2774             :   ASMJIT_INST_2x(vmovdqa64, Vmovdqa64, X86Ymm, X86Ymm)                        //      AVX512_F{kz}-VL
+    2775             :   ASMJIT_INST_2x(vmovdqa64, Vmovdqa64, X86Ymm, X86Mem)                        //      AVX512_F{kz}-VL
+    2776             :   ASMJIT_INST_2x(vmovdqa64, Vmovdqa64, X86Mem, X86Ymm)                        //      AVX512_F{kz}-VL
+    2777             :   ASMJIT_INST_2x(vmovdqa64, Vmovdqa64, X86Zmm, X86Zmm)                        //      AVX512_F{kz}
+    2778             :   ASMJIT_INST_2x(vmovdqa64, Vmovdqa64, X86Zmm, X86Mem)                        //      AVX512_F{kz}
+    2779             :   ASMJIT_INST_2x(vmovdqa64, Vmovdqa64, X86Mem, X86Zmm)                        //      AVX512_F{kz}
+    2780             :   ASMJIT_INST_2x(vmovdqu, Vmovdqu, X86Xmm, X86Xmm)                            // AVX
+    2781             :   ASMJIT_INST_2x(vmovdqu, Vmovdqu, X86Xmm, X86Mem)                            // AVX
+    2782             :   ASMJIT_INST_2x(vmovdqu, Vmovdqu, X86Mem, X86Xmm)                            // AVX
+    2783             :   ASMJIT_INST_2x(vmovdqu, Vmovdqu, X86Ymm, X86Ymm)                            // AVX
+    2784             :   ASMJIT_INST_2x(vmovdqu, Vmovdqu, X86Ymm, X86Mem)                            // AVX
+    2785             :   ASMJIT_INST_2x(vmovdqu, Vmovdqu, X86Mem, X86Ymm)                            // AVX
+    2786             :   ASMJIT_INST_2x(vmovdqu16, Vmovdqu16, X86Xmm, X86Xmm)                        //      AVX512_BW{kz}-VL
+    2787             :   ASMJIT_INST_2x(vmovdqu16, Vmovdqu16, X86Xmm, X86Mem)                        //      AVX512_BW{kz}-VL
+    2788             :   ASMJIT_INST_2x(vmovdqu16, Vmovdqu16, X86Mem, X86Xmm)                        //      AVX512_BW{kz}-VL
+    2789             :   ASMJIT_INST_2x(vmovdqu16, Vmovdqu16, X86Ymm, X86Ymm)                        //      AVX512_BW{kz}-VL
+    2790             :   ASMJIT_INST_2x(vmovdqu16, Vmovdqu16, X86Ymm, X86Mem)                        //      AVX512_BW{kz}-VL
+    2791             :   ASMJIT_INST_2x(vmovdqu16, Vmovdqu16, X86Mem, X86Ymm)                        //      AVX512_BW{kz}-VL
+    2792             :   ASMJIT_INST_2x(vmovdqu16, Vmovdqu16, X86Zmm, X86Zmm)                        //      AVX512_BW{kz}
+    2793             :   ASMJIT_INST_2x(vmovdqu16, Vmovdqu16, X86Zmm, X86Mem)                        //      AVX512_BW{kz}
+    2794             :   ASMJIT_INST_2x(vmovdqu16, Vmovdqu16, X86Mem, X86Zmm)                        //      AVX512_BW{kz}
+    2795             :   ASMJIT_INST_2x(vmovdqu32, Vmovdqu32, X86Xmm, X86Xmm)                        //      AVX512_F{kz}-VL
+    2796             :   ASMJIT_INST_2x(vmovdqu32, Vmovdqu32, X86Xmm, X86Mem)                        //      AVX512_F{kz}-VL
+    2797             :   ASMJIT_INST_2x(vmovdqu32, Vmovdqu32, X86Mem, X86Xmm)                        //      AVX512_F{kz}-VL
+    2798             :   ASMJIT_INST_2x(vmovdqu32, Vmovdqu32, X86Ymm, X86Ymm)                        //      AVX512_F{kz}-VL
+    2799             :   ASMJIT_INST_2x(vmovdqu32, Vmovdqu32, X86Ymm, X86Mem)                        //      AVX512_F{kz}-VL
+    2800             :   ASMJIT_INST_2x(vmovdqu32, Vmovdqu32, X86Mem, X86Ymm)                        //      AVX512_F{kz}-VL
+    2801             :   ASMJIT_INST_2x(vmovdqu32, Vmovdqu32, X86Zmm, X86Zmm)                        //      AVX512_F{kz}
+    2802             :   ASMJIT_INST_2x(vmovdqu32, Vmovdqu32, X86Zmm, X86Mem)                        //      AVX512_F{kz}
+    2803             :   ASMJIT_INST_2x(vmovdqu32, Vmovdqu32, X86Mem, X86Zmm)                        //      AVX512_F{kz}
+    2804             :   ASMJIT_INST_2x(vmovdqu64, Vmovdqu64, X86Xmm, X86Xmm)                        //      AVX512_F{kz}-VL
+    2805             :   ASMJIT_INST_2x(vmovdqu64, Vmovdqu64, X86Xmm, X86Mem)                        //      AVX512_F{kz}-VL
+    2806             :   ASMJIT_INST_2x(vmovdqu64, Vmovdqu64, X86Mem, X86Xmm)                        //      AVX512_F{kz}-VL
+    2807             :   ASMJIT_INST_2x(vmovdqu64, Vmovdqu64, X86Ymm, X86Ymm)                        //      AVX512_F{kz}-VL
+    2808             :   ASMJIT_INST_2x(vmovdqu64, Vmovdqu64, X86Ymm, X86Mem)                        //      AVX512_F{kz}-VL
+    2809             :   ASMJIT_INST_2x(vmovdqu64, Vmovdqu64, X86Mem, X86Ymm)                        //      AVX512_F{kz}-VL
+    2810             :   ASMJIT_INST_2x(vmovdqu64, Vmovdqu64, X86Zmm, X86Zmm)                        //      AVX512_F{kz}
+    2811             :   ASMJIT_INST_2x(vmovdqu64, Vmovdqu64, X86Zmm, X86Mem)                        //      AVX512_F{kz}
+    2812             :   ASMJIT_INST_2x(vmovdqu64, Vmovdqu64, X86Mem, X86Zmm)                        //      AVX512_F{kz}
+    2813             :   ASMJIT_INST_2x(vmovdqu8, Vmovdqu8, X86Xmm, X86Xmm)                          //      AVX512_BW{kz}-VL
+    2814             :   ASMJIT_INST_2x(vmovdqu8, Vmovdqu8, X86Xmm, X86Mem)                          //      AVX512_BW{kz}-VL
+    2815             :   ASMJIT_INST_2x(vmovdqu8, Vmovdqu8, X86Mem, X86Xmm)                          //      AVX512_BW{kz}-VL
+    2816             :   ASMJIT_INST_2x(vmovdqu8, Vmovdqu8, X86Ymm, X86Ymm)                          //      AVX512_BW{kz}-VL
+    2817             :   ASMJIT_INST_2x(vmovdqu8, Vmovdqu8, X86Ymm, X86Mem)                          //      AVX512_BW{kz}-VL
+    2818             :   ASMJIT_INST_2x(vmovdqu8, Vmovdqu8, X86Mem, X86Ymm)                          //      AVX512_BW{kz}-VL
+    2819             :   ASMJIT_INST_2x(vmovdqu8, Vmovdqu8, X86Zmm, X86Zmm)                          //      AVX512_BW{kz}
+    2820             :   ASMJIT_INST_2x(vmovdqu8, Vmovdqu8, X86Zmm, X86Mem)                          //      AVX512_BW{kz}
+    2821             :   ASMJIT_INST_2x(vmovdqu8, Vmovdqu8, X86Mem, X86Zmm)                          //      AVX512_BW{kz}
+    2822             :   ASMJIT_INST_3x(vmovhlps, Vmovhlps, X86Xmm, X86Xmm, X86Xmm)                  // AVX  AVX512_F
+    2823             :   ASMJIT_INST_2x(vmovhpd, Vmovhpd, X86Mem, X86Xmm)                            // AVX  AVX512_F
+    2824             :   ASMJIT_INST_3x(vmovhpd, Vmovhpd, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_F
+    2825             :   ASMJIT_INST_2x(vmovhps, Vmovhps, X86Mem, X86Xmm)                            // AVX  AVX512_F
+    2826             :   ASMJIT_INST_3x(vmovhps, Vmovhps, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_F
+    2827             :   ASMJIT_INST_3x(vmovlhps, Vmovlhps, X86Xmm, X86Xmm, X86Xmm)                  // AVX  AVX512_F
+    2828             :   ASMJIT_INST_2x(vmovlpd, Vmovlpd, X86Mem, X86Xmm)                            // AVX  AVX512_F
+    2829             :   ASMJIT_INST_3x(vmovlpd, Vmovlpd, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_F
+    2830             :   ASMJIT_INST_2x(vmovlps, Vmovlps, X86Mem, X86Xmm)                            // AVX  AVX512_F
+    2831             :   ASMJIT_INST_3x(vmovlps, Vmovlps, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_F
+    2832             :   ASMJIT_INST_2x(vmovmskpd, Vmovmskpd, X86Gp, X86Xmm)                         // AVX
+    2833             :   ASMJIT_INST_2x(vmovmskpd, Vmovmskpd, X86Gp, X86Ymm)                         // AVX
+    2834             :   ASMJIT_INST_2x(vmovmskps, Vmovmskps, X86Gp, X86Xmm)                         // AVX
+    2835             :   ASMJIT_INST_2x(vmovmskps, Vmovmskps, X86Gp, X86Ymm)                         // AVX
+    2836             :   ASMJIT_INST_2x(vmovntdq, Vmovntdq, X86Mem, X86Xmm)                          // AVX  AVX512_F-VL
+    2837             :   ASMJIT_INST_2x(vmovntdq, Vmovntdq, X86Mem, X86Ymm)                          // AVX  AVX512_F-VL
+    2838             :   ASMJIT_INST_2x(vmovntdq, Vmovntdq, X86Mem, X86Zmm)                          //      AVX512_F
+    2839             :   ASMJIT_INST_2x(vmovntdqa, Vmovntdqa, X86Xmm, X86Mem)                        // AVX  AVX512_F-VL
+    2840             :   ASMJIT_INST_2x(vmovntdqa, Vmovntdqa, X86Ymm, X86Mem)                        // AVX2 AVX512_F-VL
+    2841             :   ASMJIT_INST_2x(vmovntdqa, Vmovntdqa, X86Zmm, X86Mem)                        //      AVX512_F
+    2842             :   ASMJIT_INST_2x(vmovntpd, Vmovntpd, X86Mem, X86Xmm)                          // AVX  AVX512_F-VL
+    2843             :   ASMJIT_INST_2x(vmovntpd, Vmovntpd, X86Mem, X86Ymm)                          // AVX  AVX512_F-VL
+    2844             :   ASMJIT_INST_2x(vmovntpd, Vmovntpd, X86Mem, X86Zmm)                          //      AVX512_F
+    2845             :   ASMJIT_INST_2x(vmovntps, Vmovntps, X86Mem, X86Xmm)                          // AVX  AVX512_F-VL
+    2846             :   ASMJIT_INST_2x(vmovntps, Vmovntps, X86Mem, X86Ymm)                          // AVX  AVX512_F-VL
+    2847             :   ASMJIT_INST_2x(vmovntps, Vmovntps, X86Mem, X86Zmm)                          //      AVX512_F
+    2848             :   ASMJIT_INST_2x(vmovq, Vmovq, X86Gp, X86Xmm)                                 // AVX  AVX512_F
+    2849             :   ASMJIT_INST_2x(vmovq, Vmovq, X86Mem, X86Xmm)                                // AVX  AVX512_F
+    2850             :   ASMJIT_INST_2x(vmovq, Vmovq, X86Xmm, X86Mem)                                // AVX  AVX512_F
+    2851             :   ASMJIT_INST_2x(vmovq, Vmovq, X86Xmm, X86Gp)                                 // AVX  AVX512_F
+    2852             :   ASMJIT_INST_2x(vmovq, Vmovq, X86Xmm, X86Xmm)                                // AVX  AVX512_F
+    2853             :   ASMJIT_INST_2x(vmovsd, Vmovsd, X86Mem, X86Xmm)                              // AVX  AVX512_F
+    2854             :   ASMJIT_INST_2x(vmovsd, Vmovsd, X86Xmm, X86Mem)                              // AVX  AVX512_F{kz}
+    2855             :   ASMJIT_INST_3x(vmovsd, Vmovsd, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz}
+    2856             :   ASMJIT_INST_2x(vmovshdup, Vmovshdup, X86Xmm, X86Xmm)                        // AVX  AVX512_F{kz}-VL
+    2857             :   ASMJIT_INST_2x(vmovshdup, Vmovshdup, X86Xmm, X86Mem)                        // AVX  AVX512_F{kz}-VL
+    2858             :   ASMJIT_INST_2x(vmovshdup, Vmovshdup, X86Ymm, X86Ymm)                        // AVX  AVX512_F{kz}-VL
+    2859             :   ASMJIT_INST_2x(vmovshdup, Vmovshdup, X86Ymm, X86Mem)                        // AVX  AVX512_F{kz}-VL
+    2860             :   ASMJIT_INST_2x(vmovshdup, Vmovshdup, X86Zmm, X86Zmm)                        //      AVX512_F{kz}
+    2861             :   ASMJIT_INST_2x(vmovshdup, Vmovshdup, X86Zmm, X86Mem)                        //      AVX512_F{kz}
+    2862             :   ASMJIT_INST_2x(vmovsldup, Vmovsldup, X86Xmm, X86Xmm)                        // AVX  AVX512_F{kz}-VL
+    2863             :   ASMJIT_INST_2x(vmovsldup, Vmovsldup, X86Xmm, X86Mem)                        // AVX  AVX512_F{kz}-VL
+    2864             :   ASMJIT_INST_2x(vmovsldup, Vmovsldup, X86Ymm, X86Ymm)                        // AVX  AVX512_F{kz}-VL
+    2865             :   ASMJIT_INST_2x(vmovsldup, Vmovsldup, X86Ymm, X86Mem)                        // AVX  AVX512_F{kz}-VL
+    2866             :   ASMJIT_INST_2x(vmovsldup, Vmovsldup, X86Zmm, X86Zmm)                        //      AVX512_F{kz}
+    2867             :   ASMJIT_INST_2x(vmovsldup, Vmovsldup, X86Zmm, X86Mem)                        //      AVX512_F{kz}
+    2868             :   ASMJIT_INST_2x(vmovss, Vmovss, X86Mem, X86Xmm)                              // AVX  AVX512_F
+    2869             :   ASMJIT_INST_2x(vmovss, Vmovss, X86Xmm, X86Mem)                              // AVX  AVX512_F{kz}
+    2870             :   ASMJIT_INST_3x(vmovss, Vmovss, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz}
+    2871             :   ASMJIT_INST_2x(vmovupd, Vmovupd, X86Xmm, X86Xmm)                            // AVX  AVX512_F{kz}-VL
+    2872             :   ASMJIT_INST_2x(vmovupd, Vmovupd, X86Xmm, X86Mem)                            // AVX  AVX512_F{kz}-VL
+    2873             :   ASMJIT_INST_2x(vmovupd, Vmovupd, X86Mem, X86Xmm)                            // AVX  AVX512_F{kz}-VL
+    2874             :   ASMJIT_INST_2x(vmovupd, Vmovupd, X86Ymm, X86Ymm)                            // AVX  AVX512_F{kz}-VL
+    2875             :   ASMJIT_INST_2x(vmovupd, Vmovupd, X86Ymm, X86Mem)                            // AVX  AVX512_F{kz}-VL
+    2876             :   ASMJIT_INST_2x(vmovupd, Vmovupd, X86Mem, X86Ymm)                            // AVX  AVX512_F{kz}-VL
+    2877             :   ASMJIT_INST_2x(vmovupd, Vmovupd, X86Zmm, X86Zmm)                            //      AVX512_F{kz}
+    2878             :   ASMJIT_INST_2x(vmovupd, Vmovupd, X86Zmm, X86Mem)                            //      AVX512_F{kz}
+    2879             :   ASMJIT_INST_2x(vmovupd, Vmovupd, X86Mem, X86Zmm)                            //      AVX512_F{kz}
+    2880             :   ASMJIT_INST_2x(vmovups, Vmovups, X86Xmm, X86Xmm)                            // AVX  AVX512_F{kz}-VL
+    2881             :   ASMJIT_INST_2x(vmovups, Vmovups, X86Xmm, X86Mem)                            // AVX  AVX512_F{kz}-VL
+    2882             :   ASMJIT_INST_2x(vmovups, Vmovups, X86Mem, X86Xmm)                            // AVX  AVX512_F{kz}-VL
+    2883             :   ASMJIT_INST_2x(vmovups, Vmovups, X86Ymm, X86Ymm)                            // AVX  AVX512_F{kz}-VL
+    2884             :   ASMJIT_INST_2x(vmovups, Vmovups, X86Ymm, X86Mem)                            // AVX  AVX512_F{kz}-VL
+    2885             :   ASMJIT_INST_2x(vmovups, Vmovups, X86Mem, X86Ymm)                            // AVX  AVX512_F{kz}-VL
+    2886             :   ASMJIT_INST_2x(vmovups, Vmovups, X86Zmm, X86Zmm)                            //      AVX512_F{kz}
+    2887             :   ASMJIT_INST_2x(vmovups, Vmovups, X86Zmm, X86Mem)                            //      AVX512_F{kz}
+    2888             :   ASMJIT_INST_2x(vmovups, Vmovups, X86Mem, X86Zmm)                            //      AVX512_F{kz}
+    2889             :   ASMJIT_INST_4i(vmpsadbw, Vmpsadbw, X86Xmm, X86Xmm, X86Xmm, Imm)             // AVX
+    2890             :   ASMJIT_INST_4i(vmpsadbw, Vmpsadbw, X86Xmm, X86Xmm, X86Mem, Imm)             // AVX
+    2891             :   ASMJIT_INST_4i(vmpsadbw, Vmpsadbw, X86Ymm, X86Ymm, X86Ymm, Imm)             // AVX2
+    2892             :   ASMJIT_INST_4i(vmpsadbw, Vmpsadbw, X86Ymm, X86Ymm, X86Mem, Imm)             // AVX2
+    2893             :   ASMJIT_INST_3x(vmulpd, Vmulpd, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|b64}-VL
+    2894             :   ASMJIT_INST_3x(vmulpd, Vmulpd, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|b64}-VL
+    2895             :   ASMJIT_INST_3x(vmulpd, Vmulpd, X86Ymm, X86Ymm, X86Ymm)                      // AVX2 AVX512_F{kz|b64}-VL
+    2896             :   ASMJIT_INST_3x(vmulpd, Vmulpd, X86Ymm, X86Ymm, X86Mem)                      // AVX2 AVX512_F{kz|b64}-VL
+    2897             :   ASMJIT_INST_3x(vmulpd, Vmulpd, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_F{kz|er|b64}
+    2898             :   ASMJIT_INST_3x(vmulpd, Vmulpd, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_F{kz|er|b64}
+    2899             :   ASMJIT_INST_3x(vmulps, Vmulps, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|b32}-VL
+    2900             :   ASMJIT_INST_3x(vmulps, Vmulps, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|b32}-VL
+    2901             :   ASMJIT_INST_3x(vmulps, Vmulps, X86Ymm, X86Ymm, X86Ymm)                      // AVX2 AVX512_F{kz|b32}-VL
+    2902             :   ASMJIT_INST_3x(vmulps, Vmulps, X86Ymm, X86Ymm, X86Mem)                      // AVX2 AVX512_F{kz|b32}-VL
+    2903             :   ASMJIT_INST_3x(vmulps, Vmulps, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_F{kz|er|b32}
+    2904             :   ASMJIT_INST_3x(vmulps, Vmulps, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_F{kz|er|b32}
+    2905             :   ASMJIT_INST_3x(vmulsd, Vmulsd, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|er}
+    2906             :   ASMJIT_INST_3x(vmulsd, Vmulsd, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|er}
+    2907             :   ASMJIT_INST_3x(vmulss, Vmulss, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|er}
+    2908             :   ASMJIT_INST_3x(vmulss, Vmulss, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|er}
+    2909             :   ASMJIT_INST_3x(vorpd, Vorpd, X86Xmm, X86Xmm, X86Xmm)                        // AVX  AVX512_DQ{kz|b64}-VL
+    2910             :   ASMJIT_INST_3x(vorpd, Vorpd, X86Xmm, X86Xmm, X86Mem)                        // AVX  AVX512_DQ{kz|b64}-VL
+    2911             :   ASMJIT_INST_3x(vorpd, Vorpd, X86Ymm, X86Ymm, X86Ymm)                        // AVX  AVX512_DQ{kz|b64}-VL
+    2912             :   ASMJIT_INST_3x(vorpd, Vorpd, X86Ymm, X86Ymm, X86Mem)                        // AVX  AVX512_DQ{kz|b64}-VL
+    2913             :   ASMJIT_INST_3x(vorpd, Vorpd, X86Zmm, X86Zmm, X86Zmm)                        //      AVX512_DQ{kz|b64}
+    2914             :   ASMJIT_INST_3x(vorpd, Vorpd, X86Zmm, X86Zmm, X86Mem)                        //      AVX512_DQ{kz|b64}
+    2915             :   ASMJIT_INST_3x(vorps, Vorps, X86Xmm, X86Xmm, X86Xmm)                        // AVX  AVX512_F{kz|b32}-VL
+    2916             :   ASMJIT_INST_3x(vorps, Vorps, X86Xmm, X86Xmm, X86Mem)                        // AVX  AVX512_F{kz|b32}-VL
+    2917             :   ASMJIT_INST_3x(vorps, Vorps, X86Ymm, X86Ymm, X86Ymm)                        // AVX  AVX512_F{kz|b32}-VL
+    2918             :   ASMJIT_INST_3x(vorps, Vorps, X86Ymm, X86Ymm, X86Mem)                        // AVX  AVX512_F{kz|b32}-VL
+    2919             :   ASMJIT_INST_3x(vorps, Vorps, X86Zmm, X86Zmm, X86Zmm)                        //      AVX512_F{kz|b32}
+    2920             :   ASMJIT_INST_3x(vorps, Vorps, X86Zmm, X86Zmm, X86Mem)                        //      AVX512_F{kz|b32}
+    2921             :   ASMJIT_INST_6x(vp4dpwssd, Vp4dpwssd, X86Zmm, X86Zmm, X86Zmm, X86Zmm, X86Zmm, X86Mem)   // AVX512_4FMAPS{kz}
+    2922             :   ASMJIT_INST_6x(vp4dpwssds, Vp4dpwssds, X86Zmm, X86Zmm, X86Zmm, X86Zmm, X86Zmm, X86Mem) // AVX512_4FMAPS{kz}
+    2923             :   ASMJIT_INST_2x(vpabsb, Vpabsb, X86Xmm, X86Xmm)                              // AVX  AVX512_BW{kz}-VL
+    2924             :   ASMJIT_INST_2x(vpabsb, Vpabsb, X86Xmm, X86Mem)                              // AVX  AVX512_BW{kz}-VL
+    2925             :   ASMJIT_INST_2x(vpabsb, Vpabsb, X86Ymm, X86Ymm)                              // AVX2 AVX512_BW{kz}-VL
+    2926             :   ASMJIT_INST_2x(vpabsb, Vpabsb, X86Ymm, X86Mem)                              // AVX2 AVX512_BW{kz}-VL
+    2927             :   ASMJIT_INST_2x(vpabsb, Vpabsb, X86Zmm, X86Zmm)                              //      AVX512_BW{kz}
+    2928             :   ASMJIT_INST_2x(vpabsb, Vpabsb, X86Zmm, X86Mem)                              //      AVX512_BW{kz}
+    2929             :   ASMJIT_INST_2x(vpabsd, Vpabsd, X86Xmm, X86Xmm)                              // AVX  AVX512_F{kz}-VL
+    2930             :   ASMJIT_INST_2x(vpabsd, Vpabsd, X86Xmm, X86Mem)                              // AVX  AVX512_F{kz}-VL
+    2931             :   ASMJIT_INST_2x(vpabsd, Vpabsd, X86Ymm, X86Ymm)                              // AVX2 AVX512_F{kz}-VL
+    2932             :   ASMJIT_INST_2x(vpabsd, Vpabsd, X86Ymm, X86Mem)                              // AVX2 AVX512_F{kz}-VL
+    2933             :   ASMJIT_INST_2x(vpabsd, Vpabsd, X86Zmm, X86Zmm)                              //      AVX512_F{kz}
+    2934             :   ASMJIT_INST_2x(vpabsd, Vpabsd, X86Zmm, X86Mem)                              //      AVX512_F{kz}
+    2935             :   ASMJIT_INST_2x(vpabsq, Vpabsq, X86Xmm, X86Xmm)                              //      AVX512_F{kz}-VL
+    2936             :   ASMJIT_INST_2x(vpabsq, Vpabsq, X86Xmm, X86Mem)                              //      AVX512_F{kz}-VL
+    2937             :   ASMJIT_INST_2x(vpabsq, Vpabsq, X86Ymm, X86Ymm)                              //      AVX512_F{kz}-VL
+    2938             :   ASMJIT_INST_2x(vpabsq, Vpabsq, X86Ymm, X86Mem)                              //      AVX512_F{kz}-VL
+    2939             :   ASMJIT_INST_2x(vpabsq, Vpabsq, X86Zmm, X86Zmm)                              //      AVX512_F{kz}
+    2940             :   ASMJIT_INST_2x(vpabsq, Vpabsq, X86Zmm, X86Mem)                              //      AVX512_F{kz}
+    2941             :   ASMJIT_INST_2x(vpabsw, Vpabsw, X86Xmm, X86Xmm)                              // AVX  AVX512_BW{kz}-VL
+    2942             :   ASMJIT_INST_2x(vpabsw, Vpabsw, X86Xmm, X86Mem)                              // AVX  AVX512_BW{kz}-VL
+    2943             :   ASMJIT_INST_2x(vpabsw, Vpabsw, X86Ymm, X86Ymm)                              // AVX2 AVX512_BW{kz}-VL
+    2944             :   ASMJIT_INST_2x(vpabsw, Vpabsw, X86Ymm, X86Mem)                              // AVX2 AVX512_BW{kz}-VL
+    2945             :   ASMJIT_INST_2x(vpabsw, Vpabsw, X86Zmm, X86Zmm)                              //      AVX512_BW{kz}
+    2946             :   ASMJIT_INST_2x(vpabsw, Vpabsw, X86Zmm, X86Mem)                              //      AVX512_BW{kz}
+    2947             :   ASMJIT_INST_3x(vpackssdw, Vpackssdw, X86Xmm, X86Xmm, X86Xmm)                // AVX  AVX512_BW{kz|b32}-VL
+    2948             :   ASMJIT_INST_3x(vpackssdw, Vpackssdw, X86Xmm, X86Xmm, X86Mem)                // AVX  AVX512_BW{kz|b32}-VL
+    2949             :   ASMJIT_INST_3x(vpackssdw, Vpackssdw, X86Ymm, X86Ymm, X86Ymm)                // AVX2 AVX512_BW{kz|b32}-VL
+    2950             :   ASMJIT_INST_3x(vpackssdw, Vpackssdw, X86Ymm, X86Ymm, X86Mem)                // AVX2 AVX512_BW{kz|b32}-VL
+    2951             :   ASMJIT_INST_3x(vpackssdw, Vpackssdw, X86Zmm, X86Zmm, X86Zmm)                //      AVX512_BW{kz|b32}
+    2952             :   ASMJIT_INST_3x(vpackssdw, Vpackssdw, X86Zmm, X86Zmm, X86Mem)                //      AVX512_BW{kz|b32}
+    2953             :   ASMJIT_INST_3x(vpacksswb, Vpacksswb, X86Xmm, X86Xmm, X86Xmm)                // AVX  AVX512_BW{kz}-VL
+    2954             :   ASMJIT_INST_3x(vpacksswb, Vpacksswb, X86Xmm, X86Xmm, X86Mem)                // AVX  AVX512_BW{kz}-VL
+    2955             :   ASMJIT_INST_3x(vpacksswb, Vpacksswb, X86Ymm, X86Ymm, X86Ymm)                // AVX2 AVX512_BW{kz}-VL
+    2956             :   ASMJIT_INST_3x(vpacksswb, Vpacksswb, X86Ymm, X86Ymm, X86Mem)                // AVX2 AVX512_BW{kz}-VL
+    2957             :   ASMJIT_INST_3x(vpacksswb, Vpacksswb, X86Zmm, X86Zmm, X86Zmm)                //      AVX512_BW{kz}
+    2958             :   ASMJIT_INST_3x(vpacksswb, Vpacksswb, X86Zmm, X86Zmm, X86Mem)                //      AVX512_BW{kz}
+    2959             :   ASMJIT_INST_3x(vpackusdw, Vpackusdw, X86Xmm, X86Xmm, X86Xmm)                // AVX  AVX512_BW{kz|b32}-VL
+    2960             :   ASMJIT_INST_3x(vpackusdw, Vpackusdw, X86Xmm, X86Xmm, X86Mem)                // AVX  AVX512_BW{kz|b32}-VL
+    2961             :   ASMJIT_INST_3x(vpackusdw, Vpackusdw, X86Ymm, X86Ymm, X86Ymm)                // AVX2 AVX512_BW{kz|b32}-VL
+    2962             :   ASMJIT_INST_3x(vpackusdw, Vpackusdw, X86Ymm, X86Ymm, X86Mem)                // AVX2 AVX512_BW{kz|b32}-VL
+    2963             :   ASMJIT_INST_3x(vpackusdw, Vpackusdw, X86Zmm, X86Zmm, X86Zmm)                //      AVX512_BW{kz|b32}
+    2964             :   ASMJIT_INST_3x(vpackusdw, Vpackusdw, X86Zmm, X86Zmm, X86Mem)                //      AVX512_BW{kz|b32}
+    2965             :   ASMJIT_INST_3x(vpackuswb, Vpackuswb, X86Xmm, X86Xmm, X86Xmm)                // AVX  AVX512_BW{kz}-VL
+    2966             :   ASMJIT_INST_3x(vpackuswb, Vpackuswb, X86Xmm, X86Xmm, X86Mem)                // AVX  AVX512_BW{kz}-VL
+    2967             :   ASMJIT_INST_3x(vpackuswb, Vpackuswb, X86Ymm, X86Ymm, X86Ymm)                // AVX2 AVX512_BW{kz}-VL
+    2968             :   ASMJIT_INST_3x(vpackuswb, Vpackuswb, X86Ymm, X86Ymm, X86Mem)                // AVX2 AVX512_BW{kz}-VL
+    2969             :   ASMJIT_INST_3x(vpackuswb, Vpackuswb, X86Zmm, X86Zmm, X86Zmm)                //      AVX512_BW{kz}
+    2970             :   ASMJIT_INST_3x(vpackuswb, Vpackuswb, X86Zmm, X86Zmm, X86Mem)                //      AVX512_BW{kz}
+    2971             :   ASMJIT_INST_3x(vpaddb, Vpaddb, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_BW{kz}-VL
+    2972             :   ASMJIT_INST_3x(vpaddb, Vpaddb, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_BW{kz}-VL
+    2973             :   ASMJIT_INST_3x(vpaddb, Vpaddb, X86Ymm, X86Ymm, X86Ymm)                      // AVX2 AVX512_BW{kz}-VL
+    2974             :   ASMJIT_INST_3x(vpaddb, Vpaddb, X86Ymm, X86Ymm, X86Mem)                      // AVX2 AVX512_BW{kz}-VL
+    2975             :   ASMJIT_INST_3x(vpaddb, Vpaddb, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_BW{kz}
+    2976             :   ASMJIT_INST_3x(vpaddb, Vpaddb, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_BW{kz}
+    2977             :   ASMJIT_INST_3x(vpaddd, Vpaddd, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|b32}-VL
+    2978             :   ASMJIT_INST_3x(vpaddd, Vpaddd, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|b32}-VL
+    2979             :   ASMJIT_INST_3x(vpaddd, Vpaddd, X86Ymm, X86Ymm, X86Ymm)                      // AVX2 AVX512_F{kz|b32}-VL
+    2980             :   ASMJIT_INST_3x(vpaddd, Vpaddd, X86Ymm, X86Ymm, X86Mem)                      // AVX2 AVX512_F{kz|b32}-VL
+    2981             :   ASMJIT_INST_3x(vpaddd, Vpaddd, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_F{kz|b32}
+    2982             :   ASMJIT_INST_3x(vpaddd, Vpaddd, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_F{kz|b32}
+    2983             :   ASMJIT_INST_3x(vpaddq, Vpaddq, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|b64}-VL
+    2984             :   ASMJIT_INST_3x(vpaddq, Vpaddq, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|b64}-VL
+    2985             :   ASMJIT_INST_3x(vpaddq, Vpaddq, X86Ymm, X86Ymm, X86Ymm)                      // AVX2 AVX512_F{kz|b64}-VL
+    2986             :   ASMJIT_INST_3x(vpaddq, Vpaddq, X86Ymm, X86Ymm, X86Mem)                      // AVX2 AVX512_F{kz|b64}-VL
+    2987             :   ASMJIT_INST_3x(vpaddq, Vpaddq, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_F{kz|b64}
+    2988             :   ASMJIT_INST_3x(vpaddq, Vpaddq, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_F{kz|b64}
+    2989             :   ASMJIT_INST_3x(vpaddsb, Vpaddsb, X86Xmm, X86Xmm, X86Xmm)                    // AVX  AVX512_BW{kz}-VL
+    2990             :   ASMJIT_INST_3x(vpaddsb, Vpaddsb, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_BW{kz}-VL
+    2991             :   ASMJIT_INST_3x(vpaddsb, Vpaddsb, X86Ymm, X86Ymm, X86Ymm)                    // AVX2 AVX512_BW{kz}-VL
+    2992             :   ASMJIT_INST_3x(vpaddsb, Vpaddsb, X86Ymm, X86Ymm, X86Mem)                    // AVX2 AVX512_BW{kz}-VL
+    2993             :   ASMJIT_INST_3x(vpaddsb, Vpaddsb, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_BW{kz}
+    2994             :   ASMJIT_INST_3x(vpaddsb, Vpaddsb, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_BW{kz}
+    2995             :   ASMJIT_INST_3x(vpaddsw, Vpaddsw, X86Xmm, X86Xmm, X86Xmm)                    // AVX  AVX512_BW{kz}-VL
+    2996             :   ASMJIT_INST_3x(vpaddsw, Vpaddsw, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_BW{kz}-VL
+    2997             :   ASMJIT_INST_3x(vpaddsw, Vpaddsw, X86Ymm, X86Ymm, X86Ymm)                    // AVX2 AVX512_BW{kz}-VL
+    2998             :   ASMJIT_INST_3x(vpaddsw, Vpaddsw, X86Ymm, X86Ymm, X86Mem)                    // AVX2 AVX512_BW{kz}-VL
+    2999             :   ASMJIT_INST_3x(vpaddsw, Vpaddsw, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_BW{kz}
+    3000             :   ASMJIT_INST_3x(vpaddsw, Vpaddsw, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_BW{kz}
+    3001             :   ASMJIT_INST_3x(vpaddusb, Vpaddusb, X86Xmm, X86Xmm, X86Xmm)                  // AVX  AVX512_BW{kz}-VL
+    3002             :   ASMJIT_INST_3x(vpaddusb, Vpaddusb, X86Xmm, X86Xmm, X86Mem)                  // AVX  AVX512_BW{kz}-VL
+    3003             :   ASMJIT_INST_3x(vpaddusb, Vpaddusb, X86Ymm, X86Ymm, X86Ymm)                  // AVX2 AVX512_BW{kz}-VL
+    3004             :   ASMJIT_INST_3x(vpaddusb, Vpaddusb, X86Ymm, X86Ymm, X86Mem)                  // AVX2 AVX512_BW{kz}-VL
+    3005             :   ASMJIT_INST_3x(vpaddusb, Vpaddusb, X86Zmm, X86Zmm, X86Zmm)                  //      AVX512_BW{kz}
+    3006             :   ASMJIT_INST_3x(vpaddusb, Vpaddusb, X86Zmm, X86Zmm, X86Mem)                  //      AVX512_BW{kz}
+    3007             :   ASMJIT_INST_3x(vpaddusw, Vpaddusw, X86Xmm, X86Xmm, X86Xmm)                  // AVX  AVX512_BW{kz}-VL
+    3008             :   ASMJIT_INST_3x(vpaddusw, Vpaddusw, X86Xmm, X86Xmm, X86Mem)                  // AVX  AVX512_BW{kz}-VL
+    3009             :   ASMJIT_INST_3x(vpaddusw, Vpaddusw, X86Ymm, X86Ymm, X86Ymm)                  // AVX2 AVX512_BW{kz}-VL
+    3010             :   ASMJIT_INST_3x(vpaddusw, Vpaddusw, X86Ymm, X86Ymm, X86Mem)                  // AVX2 AVX512_BW{kz}-VL
+    3011             :   ASMJIT_INST_3x(vpaddusw, Vpaddusw, X86Zmm, X86Zmm, X86Zmm)                  //      AVX512_BW{kz}
+    3012             :   ASMJIT_INST_3x(vpaddusw, Vpaddusw, X86Zmm, X86Zmm, X86Mem)                  //      AVX512_BW{kz}
+    3013             :   ASMJIT_INST_3x(vpaddw, Vpaddw, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_BW{kz}-VL
+    3014             :   ASMJIT_INST_3x(vpaddw, Vpaddw, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_BW{kz}-VL
+    3015             :   ASMJIT_INST_3x(vpaddw, Vpaddw, X86Ymm, X86Ymm, X86Ymm)                      // AVX2 AVX512_BW{kz}-VL
+    3016             :   ASMJIT_INST_3x(vpaddw, Vpaddw, X86Ymm, X86Ymm, X86Mem)                      // AVX2 AVX512_BW{kz}-VL
+    3017             :   ASMJIT_INST_3x(vpaddw, Vpaddw, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_BW{kz}
+    3018             :   ASMJIT_INST_3x(vpaddw, Vpaddw, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_BW{kz}
+    3019             :   ASMJIT_INST_4i(vpalignr, Vpalignr, X86Xmm, X86Xmm, X86Xmm, Imm)             // AVX  AVX512_BW{kz}-VL
+    3020             :   ASMJIT_INST_4i(vpalignr, Vpalignr, X86Xmm, X86Xmm, X86Mem, Imm)             // AVX  AVX512_BW{kz}-VL
+    3021             :   ASMJIT_INST_4i(vpalignr, Vpalignr, X86Ymm, X86Ymm, X86Ymm, Imm)             // AVX2 AVX512_BW{kz}-VL
+    3022             :   ASMJIT_INST_4i(vpalignr, Vpalignr, X86Ymm, X86Ymm, X86Mem, Imm)             // AVX2 AVX512_BW{kz}-VL
+    3023             :   ASMJIT_INST_4i(vpalignr, Vpalignr, X86Zmm, X86Zmm, X86Zmm, Imm)             //      AVX512_BW{kz}
+    3024             :   ASMJIT_INST_4i(vpalignr, Vpalignr, X86Zmm, X86Zmm, X86Mem, Imm)             //      AVX512_BW{kz}
+    3025             :   ASMJIT_INST_3x(vpand, Vpand, X86Xmm, X86Xmm, X86Xmm)                        // AVX
+    3026             :   ASMJIT_INST_3x(vpand, Vpand, X86Xmm, X86Xmm, X86Mem)                        // AVX
+    3027             :   ASMJIT_INST_3x(vpand, Vpand, X86Ymm, X86Ymm, X86Ymm)                        // AVX2
+    3028             :   ASMJIT_INST_3x(vpand, Vpand, X86Ymm, X86Ymm, X86Mem)                        // AVX2
+    3029             :   ASMJIT_INST_3x(vpandd, Vpandd, X86Xmm, X86Xmm, X86Xmm)                      //      AVX512_F{kz|b32}-VL
+    3030             :   ASMJIT_INST_3x(vpandd, Vpandd, X86Xmm, X86Xmm, X86Mem)                      //      AVX512_F{kz|b32}-VL
+    3031             :   ASMJIT_INST_3x(vpandd, Vpandd, X86Ymm, X86Ymm, X86Ymm)                      //      AVX512_F{kz|b32}-VL
+    3032             :   ASMJIT_INST_3x(vpandd, Vpandd, X86Ymm, X86Ymm, X86Mem)                      //      AVX512_F{kz|b32}-VL
+    3033             :   ASMJIT_INST_3x(vpandd, Vpandd, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_F{kz|b32}
+    3034             :   ASMJIT_INST_3x(vpandd, Vpandd, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_F{kz|b32}
+    3035             :   ASMJIT_INST_3x(vpandn, Vpandn, X86Xmm, X86Xmm, X86Xmm)                      // AVX
+    3036             :   ASMJIT_INST_3x(vpandn, Vpandn, X86Xmm, X86Xmm, X86Mem)                      // AVX
+    3037             :   ASMJIT_INST_3x(vpandn, Vpandn, X86Ymm, X86Ymm, X86Ymm)                      // AVX2
+    3038             :   ASMJIT_INST_3x(vpandn, Vpandn, X86Ymm, X86Ymm, X86Mem)                      // AVX2
+    3039             :   ASMJIT_INST_3x(vpandnd, Vpandnd, X86Xmm, X86Xmm, X86Xmm)                    //      AVX512_F{kz|b32}-VL
+    3040             :   ASMJIT_INST_3x(vpandnd, Vpandnd, X86Xmm, X86Xmm, X86Mem)                    //      AVX512_F{kz|b32}-VL
+    3041             :   ASMJIT_INST_3x(vpandnd, Vpandnd, X86Ymm, X86Ymm, X86Ymm)                    //      AVX512_F{kz|b32}-VL
+    3042             :   ASMJIT_INST_3x(vpandnd, Vpandnd, X86Ymm, X86Ymm, X86Mem)                    //      AVX512_F{kz|b32}-VL
+    3043             :   ASMJIT_INST_3x(vpandnd, Vpandnd, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_F{kz|b32}
+    3044             :   ASMJIT_INST_3x(vpandnd, Vpandnd, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_F{kz|b32}
+    3045             :   ASMJIT_INST_3x(vpandnq, Vpandnq, X86Xmm, X86Xmm, X86Xmm)                    //      AVX512_F{kz|b64}-VL
+    3046             :   ASMJIT_INST_3x(vpandnq, Vpandnq, X86Xmm, X86Xmm, X86Mem)                    //      AVX512_F{kz|b64}-VL
+    3047             :   ASMJIT_INST_3x(vpandnq, Vpandnq, X86Ymm, X86Ymm, X86Ymm)                    //      AVX512_F{kz|b64}-VL
+    3048             :   ASMJIT_INST_3x(vpandnq, Vpandnq, X86Ymm, X86Ymm, X86Mem)                    //      AVX512_F{kz|b64}-VL
+    3049             :   ASMJIT_INST_3x(vpandnq, Vpandnq, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_F{kz|b64}
+    3050             :   ASMJIT_INST_3x(vpandnq, Vpandnq, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_F{kz|b64}
+    3051             :   ASMJIT_INST_3x(vpandq, Vpandq, X86Xmm, X86Xmm, X86Xmm)                      //      AVX512_F{kz|b64}-VL
+    3052             :   ASMJIT_INST_3x(vpandq, Vpandq, X86Xmm, X86Xmm, X86Mem)                      //      AVX512_F{kz|b64}-VL
+    3053             :   ASMJIT_INST_3x(vpandq, Vpandq, X86Ymm, X86Ymm, X86Ymm)                      //      AVX512_F{kz|b64}-VL
+    3054             :   ASMJIT_INST_3x(vpandq, Vpandq, X86Ymm, X86Ymm, X86Mem)                      //      AVX512_F{kz|b64}-VL
+    3055             :   ASMJIT_INST_3x(vpandq, Vpandq, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_F{kz|b64}
+    3056             :   ASMJIT_INST_3x(vpandq, Vpandq, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_F{kz|b64}
+    3057             :   ASMJIT_INST_3x(vpavgb, Vpavgb, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_BW{kz}-VL
+    3058             :   ASMJIT_INST_3x(vpavgb, Vpavgb, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_BW{kz}-VL
+    3059             :   ASMJIT_INST_3x(vpavgb, Vpavgb, X86Ymm, X86Ymm, X86Ymm)                      // AVX  AVX512_BW{kz}-VL
+    3060             :   ASMJIT_INST_3x(vpavgb, Vpavgb, X86Ymm, X86Ymm, X86Mem)                      // AVX  AVX512_BW{kz}-VL
+    3061             :   ASMJIT_INST_3x(vpavgb, Vpavgb, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_BW{kz}
+    3062             :   ASMJIT_INST_3x(vpavgb, Vpavgb, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_BW{kz}
+    3063             :   ASMJIT_INST_3x(vpavgw, Vpavgw, X86Xmm, X86Xmm, X86Xmm)                      // AVX2 AVX512_BW{kz}-VL
+    3064             :   ASMJIT_INST_3x(vpavgw, Vpavgw, X86Xmm, X86Xmm, X86Mem)                      // AVX2 AVX512_BW{kz}-VL
+    3065             :   ASMJIT_INST_3x(vpavgw, Vpavgw, X86Ymm, X86Ymm, X86Ymm)                      // AVX2 AVX512_BW{kz}-VL
+    3066             :   ASMJIT_INST_3x(vpavgw, Vpavgw, X86Ymm, X86Ymm, X86Mem)                      // AVX2 AVX512_BW{kz}-VL
+    3067             :   ASMJIT_INST_3x(vpavgw, Vpavgw, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_BW{kz}
+    3068             :   ASMJIT_INST_3x(vpavgw, Vpavgw, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_BW{kz}
+    3069             :   ASMJIT_INST_4i(vpblendd, Vpblendd, X86Xmm, X86Xmm, X86Xmm, Imm)             // AVX2
+    3070             :   ASMJIT_INST_4i(vpblendd, Vpblendd, X86Xmm, X86Xmm, X86Mem, Imm)             // AVX2
+    3071             :   ASMJIT_INST_4i(vpblendd, Vpblendd, X86Ymm, X86Ymm, X86Ymm, Imm)             // AVX2
+    3072             :   ASMJIT_INST_4i(vpblendd, Vpblendd, X86Ymm, X86Ymm, X86Mem, Imm)             // AVX2
+    3073             :   ASMJIT_INST_4x(vpblendvb, Vpblendvb, X86Xmm, X86Xmm, X86Xmm, X86Xmm)        // AVX
+    3074             :   ASMJIT_INST_4x(vpblendvb, Vpblendvb, X86Xmm, X86Xmm, X86Mem, X86Xmm)        // AVX
+    3075             :   ASMJIT_INST_4x(vpblendvb, Vpblendvb, X86Ymm, X86Ymm, X86Ymm, X86Ymm)        // AVX2
+    3076             :   ASMJIT_INST_4x(vpblendvb, Vpblendvb, X86Ymm, X86Ymm, X86Mem, X86Ymm)        // AVX2
+    3077             :   ASMJIT_INST_4i(vpblendw, Vpblendw, X86Xmm, X86Xmm, X86Xmm, Imm)             // AVX
+    3078             :   ASMJIT_INST_4i(vpblendw, Vpblendw, X86Xmm, X86Xmm, X86Mem, Imm)             // AVX
+    3079             :   ASMJIT_INST_4i(vpblendw, Vpblendw, X86Ymm, X86Ymm, X86Ymm, Imm)             // AVX2
+    3080             :   ASMJIT_INST_4i(vpblendw, Vpblendw, X86Ymm, X86Ymm, X86Mem, Imm)             // AVX2
+    3081             :   ASMJIT_INST_2x(vpbroadcastb, Vpbroadcastb, X86Xmm, X86Xmm)                  // AVX2 AVX512_BW{kz}-VL
+    3082             :   ASMJIT_INST_2x(vpbroadcastb, Vpbroadcastb, X86Xmm, X86Mem)                  // AVX2 AVX512_BW{kz}-VL
+    3083             :   ASMJIT_INST_2x(vpbroadcastb, Vpbroadcastb, X86Ymm, X86Xmm)                  // AVX2 AVX512_BW{kz}-VL
+    3084             :   ASMJIT_INST_2x(vpbroadcastb, Vpbroadcastb, X86Ymm, X86Mem)                  // AVX2 AVX512_BW{kz}-VL
+    3085             :   ASMJIT_INST_2x(vpbroadcastb, Vpbroadcastb, X86Xmm, X86Gp)                   //      AVX512_BW{kz}-VL
+    3086             :   ASMJIT_INST_2x(vpbroadcastb, Vpbroadcastb, X86Ymm, X86Gp)                   //      AVX512_BW{kz}-VL
+    3087             :   ASMJIT_INST_2x(vpbroadcastb, Vpbroadcastb, X86Zmm, X86Gp)                   //      AVX512_BW{kz}
+    3088             :   ASMJIT_INST_2x(vpbroadcastb, Vpbroadcastb, X86Zmm, X86Xmm)                  //      AVX512_BW{kz}
+    3089             :   ASMJIT_INST_2x(vpbroadcastb, Vpbroadcastb, X86Zmm, X86Mem)                  //      AVX512_BW{kz}
+    3090             :   ASMJIT_INST_2x(vpbroadcastd, Vpbroadcastd, X86Xmm, X86Xmm)                  // AVX2 AVX512_F{kz}-VL
+    3091             :   ASMJIT_INST_2x(vpbroadcastd, Vpbroadcastd, X86Xmm, X86Mem)                  // AVX2 AVX512_F{kz}-VL
+    3092             :   ASMJIT_INST_2x(vpbroadcastd, Vpbroadcastd, X86Ymm, X86Xmm)                  // AVX2 AVX512_F{kz}-VL
+    3093             :   ASMJIT_INST_2x(vpbroadcastd, Vpbroadcastd, X86Ymm, X86Mem)                  // AVX2 AVX512_F{kz}-VL
+    3094             :   ASMJIT_INST_2x(vpbroadcastd, Vpbroadcastd, X86Xmm, X86Gp)                   //      AVX512_F{kz}-VL
+    3095             :   ASMJIT_INST_2x(vpbroadcastd, Vpbroadcastd, X86Ymm, X86Gp)                   //      AVX512_F{kz}-VL
+    3096             :   ASMJIT_INST_2x(vpbroadcastd, Vpbroadcastd, X86Zmm, X86Gp)                   //      AVX512_F{kz}
+    3097             :   ASMJIT_INST_2x(vpbroadcastd, Vpbroadcastd, X86Zmm, X86Xmm)                  //      AVX512_F{kz}
+    3098             :   ASMJIT_INST_2x(vpbroadcastd, Vpbroadcastd, X86Zmm, X86Mem)                  //      AVX512_F{kz}
+    3099             :   ASMJIT_INST_2x(vpbroadcastmb2d, Vpbroadcastmb2d, X86Xmm, X86KReg)           //      AVX512_CD-VL
+    3100             :   ASMJIT_INST_2x(vpbroadcastmb2d, Vpbroadcastmb2d, X86Ymm, X86KReg)           //      AVX512_CD-VL
+    3101             :   ASMJIT_INST_2x(vpbroadcastmb2d, Vpbroadcastmb2d, X86Zmm, X86KReg)           //      AVX512_CD
+    3102             :   ASMJIT_INST_2x(vpbroadcastmb2q, Vpbroadcastmb2q, X86Xmm, X86KReg)           //      AVX512_CD-VL
+    3103             :   ASMJIT_INST_2x(vpbroadcastmb2q, Vpbroadcastmb2q, X86Ymm, X86KReg)           //      AVX512_CD-VL
+    3104             :   ASMJIT_INST_2x(vpbroadcastmb2q, Vpbroadcastmb2q, X86Zmm, X86KReg)           //      AVX512_CD
+    3105             :   ASMJIT_INST_2x(vpbroadcastq, Vpbroadcastq, X86Xmm, X86Xmm)                  // AVX2 AVX512_F{kz}-VL
+    3106             :   ASMJIT_INST_2x(vpbroadcastq, Vpbroadcastq, X86Xmm, X86Mem)                  // AVX2 AVX512_F{kz}-VL
+    3107             :   ASMJIT_INST_2x(vpbroadcastq, Vpbroadcastq, X86Ymm, X86Xmm)                  // AVX2 AVX512_F{kz}-VL
+    3108             :   ASMJIT_INST_2x(vpbroadcastq, Vpbroadcastq, X86Ymm, X86Mem)                  // AVX2 AVX512_F{kz}-VL
+    3109             :   ASMJIT_INST_2x(vpbroadcastq, Vpbroadcastq, X86Xmm, X86Gp)                   //      AVX512_F{kz}-VL
+    3110             :   ASMJIT_INST_2x(vpbroadcastq, Vpbroadcastq, X86Ymm, X86Gp)                   //      AVX512_F{kz}-VL
+    3111             :   ASMJIT_INST_2x(vpbroadcastq, Vpbroadcastq, X86Zmm, X86Gp)                   //      AVX512_F{kz}
+    3112             :   ASMJIT_INST_2x(vpbroadcastq, Vpbroadcastq, X86Zmm, X86Xmm)                  //      AVX512_F{kz}
+    3113             :   ASMJIT_INST_2x(vpbroadcastq, Vpbroadcastq, X86Zmm, X86Mem)                  //      AVX512_F{kz}
+    3114             :   ASMJIT_INST_2x(vpbroadcastw, Vpbroadcastw, X86Xmm, X86Xmm)                  // AVX2 AVX512_BW{kz}-VL
+    3115             :   ASMJIT_INST_2x(vpbroadcastw, Vpbroadcastw, X86Xmm, X86Mem)                  // AVX2 AVX512_BW{kz}-VL
+    3116             :   ASMJIT_INST_2x(vpbroadcastw, Vpbroadcastw, X86Ymm, X86Xmm)                  // AVX2 AVX512_BW{kz}-VL
+    3117             :   ASMJIT_INST_2x(vpbroadcastw, Vpbroadcastw, X86Ymm, X86Mem)                  // AVX2 AVX512_BW{kz}-VL
+    3118             :   ASMJIT_INST_2x(vpbroadcastw, Vpbroadcastw, X86Xmm, X86Gp)                   //      AVX512_BW{kz}-VL
+    3119             :   ASMJIT_INST_2x(vpbroadcastw, Vpbroadcastw, X86Ymm, X86Gp)                   //      AVX512_BW{kz}-VL
+    3120             :   ASMJIT_INST_2x(vpbroadcastw, Vpbroadcastw, X86Zmm, X86Gp)                   //      AVX512_BW{kz}
+    3121             :   ASMJIT_INST_2x(vpbroadcastw, Vpbroadcastw, X86Zmm, X86Xmm)                  //      AVX512_BW{kz}
+    3122             :   ASMJIT_INST_2x(vpbroadcastw, Vpbroadcastw, X86Zmm, X86Mem)                  //      AVX512_BW{kz}
+    3123             :   ASMJIT_INST_4i(vpclmulqdq, Vpclmulqdq, X86Xmm, X86Xmm, X86Xmm, Imm)         // AVX
+    3124             :   ASMJIT_INST_4i(vpclmulqdq, Vpclmulqdq, X86Xmm, X86Xmm, X86Mem, Imm)         // AVX
+    3125             :   ASMJIT_INST_4i(vpcmpb, Vpcmpb, X86KReg, X86Xmm, X86Xmm, Imm)                //      AVX512_BW{k}-VL
+    3126             :   ASMJIT_INST_4i(vpcmpb, Vpcmpb, X86KReg, X86Xmm, X86Mem, Imm)                //      AVX512_BW{k}-VL
+    3127             :   ASMJIT_INST_4i(vpcmpb, Vpcmpb, X86KReg, X86Ymm, X86Ymm, Imm)                //      AVX512_BW{k}-VL
+    3128             :   ASMJIT_INST_4i(vpcmpb, Vpcmpb, X86KReg, X86Ymm, X86Mem, Imm)                //      AVX512_BW{k}-VL
+    3129             :   ASMJIT_INST_4i(vpcmpb, Vpcmpb, X86KReg, X86Zmm, X86Zmm, Imm)                //      AVX512_BW{k}
+    3130             :   ASMJIT_INST_4i(vpcmpb, Vpcmpb, X86KReg, X86Zmm, X86Mem, Imm)                //      AVX512_BW{k}
+    3131             :   ASMJIT_INST_4i(vpcmpd, Vpcmpd, X86KReg, X86Xmm, X86Xmm, Imm)                //      AVX512_F{k|b32}-VL
+    3132             :   ASMJIT_INST_4i(vpcmpd, Vpcmpd, X86KReg, X86Xmm, X86Mem, Imm)                //      AVX512_F{k|b32}-VL
+    3133             :   ASMJIT_INST_4i(vpcmpd, Vpcmpd, X86KReg, X86Ymm, X86Ymm, Imm)                //      AVX512_F{k|b32}-VL
+    3134             :   ASMJIT_INST_4i(vpcmpd, Vpcmpd, X86KReg, X86Ymm, X86Mem, Imm)                //      AVX512_F{k|b32}-VL
+    3135             :   ASMJIT_INST_4i(vpcmpd, Vpcmpd, X86KReg, X86Zmm, X86Zmm, Imm)                //      AVX512_F{k|b32}
+    3136             :   ASMJIT_INST_4i(vpcmpd, Vpcmpd, X86KReg, X86Zmm, X86Mem, Imm)                //      AVX512_F{k|b32}
+    3137             :   ASMJIT_INST_3x(vpcmpeqb, Vpcmpeqb, X86Xmm, X86Xmm, X86Xmm)                  // AVX
+    3138             :   ASMJIT_INST_3x(vpcmpeqb, Vpcmpeqb, X86Xmm, X86Xmm, X86Mem)                  // AVX
+    3139             :   ASMJIT_INST_3x(vpcmpeqb, Vpcmpeqb, X86Ymm, X86Ymm, X86Ymm)                  // AVX2
+    3140             :   ASMJIT_INST_3x(vpcmpeqb, Vpcmpeqb, X86Ymm, X86Ymm, X86Mem)                  // AVX2
+    3141             :   ASMJIT_INST_3x(vpcmpeqb, Vpcmpeqb, X86KReg, X86Xmm, X86Xmm)                 //      AVX512_BW{k}-VL
+    3142             :   ASMJIT_INST_3x(vpcmpeqb, Vpcmpeqb, X86KReg, X86Xmm, X86Mem)                 //      AVX512_BW{k}-VL
+    3143             :   ASMJIT_INST_3x(vpcmpeqb, Vpcmpeqb, X86KReg, X86Ymm, X86Ymm)                 //      AVX512_BW{k}-VL
+    3144             :   ASMJIT_INST_3x(vpcmpeqb, Vpcmpeqb, X86KReg, X86Ymm, X86Mem)                 //      AVX512_BW{k}-VL
+    3145             :   ASMJIT_INST_3x(vpcmpeqb, Vpcmpeqb, X86KReg, X86Zmm, X86Zmm)                 //      AVX512_BW{k}
+    3146             :   ASMJIT_INST_3x(vpcmpeqb, Vpcmpeqb, X86KReg, X86Zmm, X86Mem)                 //      AVX512_BW{k}
+    3147             :   ASMJIT_INST_3x(vpcmpeqd, Vpcmpeqd, X86Xmm, X86Xmm, X86Xmm)                  // AVX
+    3148             :   ASMJIT_INST_3x(vpcmpeqd, Vpcmpeqd, X86Xmm, X86Xmm, X86Mem)                  // AVX
+    3149             :   ASMJIT_INST_3x(vpcmpeqd, Vpcmpeqd, X86Ymm, X86Ymm, X86Ymm)                  // AVX2
+    3150             :   ASMJIT_INST_3x(vpcmpeqd, Vpcmpeqd, X86Ymm, X86Ymm, X86Mem)                  // AVX2
+    3151             :   ASMJIT_INST_3x(vpcmpeqd, Vpcmpeqd, X86KReg, X86Xmm, X86Xmm)                 //      AVX512_F{k|b32}-VL
+    3152             :   ASMJIT_INST_3x(vpcmpeqd, Vpcmpeqd, X86KReg, X86Xmm, X86Mem)                 //      AVX512_F{k|b32}-VL
+    3153             :   ASMJIT_INST_3x(vpcmpeqd, Vpcmpeqd, X86KReg, X86Ymm, X86Ymm)                 //      AVX512_F{k|b32}-VL
+    3154             :   ASMJIT_INST_3x(vpcmpeqd, Vpcmpeqd, X86KReg, X86Ymm, X86Mem)                 //      AVX512_F{k|b32}-VL
+    3155             :   ASMJIT_INST_3x(vpcmpeqd, Vpcmpeqd, X86KReg, X86Zmm, X86Zmm)                 //      AVX512_F{k|b32}
+    3156             :   ASMJIT_INST_3x(vpcmpeqd, Vpcmpeqd, X86KReg, X86Zmm, X86Mem)                 //      AVX512_F{k|b32}
+    3157             :   ASMJIT_INST_3x(vpcmpeqq, Vpcmpeqq, X86Xmm, X86Xmm, X86Xmm)                  // AVX
+    3158             :   ASMJIT_INST_3x(vpcmpeqq, Vpcmpeqq, X86Xmm, X86Xmm, X86Mem)                  // AVX
+    3159             :   ASMJIT_INST_3x(vpcmpeqq, Vpcmpeqq, X86Ymm, X86Ymm, X86Ymm)                  // AVX2
+    3160             :   ASMJIT_INST_3x(vpcmpeqq, Vpcmpeqq, X86Ymm, X86Ymm, X86Mem)                  // AVX2
+    3161             :   ASMJIT_INST_3x(vpcmpeqq, Vpcmpeqq, X86KReg, X86Xmm, X86Xmm)                 //      AVX512_F{k|b64}-VL
+    3162             :   ASMJIT_INST_3x(vpcmpeqq, Vpcmpeqq, X86KReg, X86Xmm, X86Mem)                 //      AVX512_F{k|b64}-VL
+    3163             :   ASMJIT_INST_3x(vpcmpeqq, Vpcmpeqq, X86KReg, X86Ymm, X86Ymm)                 //      AVX512_F{k|b64}-VL
+    3164             :   ASMJIT_INST_3x(vpcmpeqq, Vpcmpeqq, X86KReg, X86Ymm, X86Mem)                 //      AVX512_F{k|b64}-VL
+    3165             :   ASMJIT_INST_3x(vpcmpeqq, Vpcmpeqq, X86KReg, X86Zmm, X86Zmm)                 //      AVX512_F{k|b64}
+    3166             :   ASMJIT_INST_3x(vpcmpeqq, Vpcmpeqq, X86KReg, X86Zmm, X86Mem)                 //      AVX512_F{k|b64}
+    3167             :   ASMJIT_INST_3x(vpcmpeqw, Vpcmpeqw, X86Xmm, X86Xmm, X86Xmm)                  // AVX
+    3168             :   ASMJIT_INST_3x(vpcmpeqw, Vpcmpeqw, X86Xmm, X86Xmm, X86Mem)                  // AVX
+    3169             :   ASMJIT_INST_3x(vpcmpeqw, Vpcmpeqw, X86Ymm, X86Ymm, X86Ymm)                  // AVX2
+    3170             :   ASMJIT_INST_3x(vpcmpeqw, Vpcmpeqw, X86Ymm, X86Ymm, X86Mem)                  // AVX2
+    3171             :   ASMJIT_INST_3x(vpcmpeqw, Vpcmpeqw, X86KReg, X86Xmm, X86Xmm)                 //      AVX512_BW{k}-VL
+    3172             :   ASMJIT_INST_3x(vpcmpeqw, Vpcmpeqw, X86KReg, X86Xmm, X86Mem)                 //      AVX512_BW{k}-VL
+    3173             :   ASMJIT_INST_3x(vpcmpeqw, Vpcmpeqw, X86KReg, X86Ymm, X86Ymm)                 //      AVX512_BW{k}-VL
+    3174             :   ASMJIT_INST_3x(vpcmpeqw, Vpcmpeqw, X86KReg, X86Ymm, X86Mem)                 //      AVX512_BW{k}-VL
+    3175             :   ASMJIT_INST_3x(vpcmpeqw, Vpcmpeqw, X86KReg, X86Zmm, X86Zmm)                 //      AVX512_BW{k}
+    3176             :   ASMJIT_INST_3x(vpcmpeqw, Vpcmpeqw, X86KReg, X86Zmm, X86Mem)                 //      AVX512_BW{k}
+    3177             :   ASMJIT_INST_6x(vpcmpestri, Vpcmpestri, X86Xmm, X86Xmm, Imm, ECX, EAX, EDX)  // AVX  [EXPLICIT]
+    3178             :   ASMJIT_INST_6x(vpcmpestri, Vpcmpestri, X86Xmm, X86Mem, Imm, ECX, EAX, EDX)  // AVX  [EXPLICIT]
+    3179             :   ASMJIT_INST_6x(vpcmpestrm, Vpcmpestrm, X86Xmm, X86Xmm, Imm, XMM0, EAX, EDX) // AVX  [EXPLICIT]
+    3180             :   ASMJIT_INST_6x(vpcmpestrm, Vpcmpestrm, X86Xmm, X86Mem, Imm, XMM0, EAX, EDX) // AVX  [EXPLICIT]
+    3181             :   ASMJIT_INST_3x(vpcmpgtb, Vpcmpgtb, X86Xmm, X86Xmm, X86Xmm)                  // AVX
+    3182             :   ASMJIT_INST_3x(vpcmpgtb, Vpcmpgtb, X86Xmm, X86Xmm, X86Mem)                  // AVX
+    3183             :   ASMJIT_INST_3x(vpcmpgtb, Vpcmpgtb, X86Ymm, X86Ymm, X86Ymm)                  // AVX2
+    3184             :   ASMJIT_INST_3x(vpcmpgtb, Vpcmpgtb, X86Ymm, X86Ymm, X86Mem)                  // AVX2
+    3185             :   ASMJIT_INST_3x(vpcmpgtb, Vpcmpgtb, X86KReg, X86Xmm, X86Xmm)                 //      AVX512_BW{k}-VL
+    3186             :   ASMJIT_INST_3x(vpcmpgtb, Vpcmpgtb, X86KReg, X86Xmm, X86Mem)                 //      AVX512_BW{k}-VL
+    3187             :   ASMJIT_INST_3x(vpcmpgtb, Vpcmpgtb, X86KReg, X86Ymm, X86Ymm)                 //      AVX512_BW{k}-VL
+    3188             :   ASMJIT_INST_3x(vpcmpgtb, Vpcmpgtb, X86KReg, X86Ymm, X86Mem)                 //      AVX512_BW{k}-VL
+    3189             :   ASMJIT_INST_3x(vpcmpgtb, Vpcmpgtb, X86KReg, X86Zmm, X86Zmm)                 //      AVX512_BW{k}
+    3190             :   ASMJIT_INST_3x(vpcmpgtb, Vpcmpgtb, X86KReg, X86Zmm, X86Mem)                 //      AVX512_BW{k}
+    3191             :   ASMJIT_INST_3x(vpcmpgtd, Vpcmpgtd, X86Xmm, X86Xmm, X86Xmm)                  // AVX
+    3192             :   ASMJIT_INST_3x(vpcmpgtd, Vpcmpgtd, X86Xmm, X86Xmm, X86Mem)                  // AVX
+    3193             :   ASMJIT_INST_3x(vpcmpgtd, Vpcmpgtd, X86Ymm, X86Ymm, X86Ymm)                  // AVX2
+    3194             :   ASMJIT_INST_3x(vpcmpgtd, Vpcmpgtd, X86Ymm, X86Ymm, X86Mem)                  // AVX2
+    3195             :   ASMJIT_INST_3x(vpcmpgtd, Vpcmpgtd, X86KReg, X86Xmm, X86Xmm)                 //      AVX512_F{k|b32}-VL
+    3196             :   ASMJIT_INST_3x(vpcmpgtd, Vpcmpgtd, X86KReg, X86Xmm, X86Mem)                 //      AVX512_F{k|b32}-VL
+    3197             :   ASMJIT_INST_3x(vpcmpgtd, Vpcmpgtd, X86KReg, X86Ymm, X86Ymm)                 //      AVX512_F{k|b32}-VL
+    3198             :   ASMJIT_INST_3x(vpcmpgtd, Vpcmpgtd, X86KReg, X86Ymm, X86Mem)                 //      AVX512_F{k|b32}-VL
+    3199             :   ASMJIT_INST_3x(vpcmpgtd, Vpcmpgtd, X86KReg, X86Zmm, X86Zmm)                 //      AVX512_F{k|b32}
+    3200             :   ASMJIT_INST_3x(vpcmpgtd, Vpcmpgtd, X86KReg, X86Zmm, X86Mem)                 //      AVX512_F{k|b32}
+    3201             :   ASMJIT_INST_3x(vpcmpgtq, Vpcmpgtq, X86Xmm, X86Xmm, X86Xmm)                  // AVX
+    3202             :   ASMJIT_INST_3x(vpcmpgtq, Vpcmpgtq, X86Xmm, X86Xmm, X86Mem)                  // AVX
+    3203             :   ASMJIT_INST_3x(vpcmpgtq, Vpcmpgtq, X86Ymm, X86Ymm, X86Ymm)                  // AVX2
+    3204             :   ASMJIT_INST_3x(vpcmpgtq, Vpcmpgtq, X86Ymm, X86Ymm, X86Mem)                  // AVX2
+    3205             :   ASMJIT_INST_3x(vpcmpgtq, Vpcmpgtq, X86KReg, X86Xmm, X86Xmm)                 //      AVX512_F{k|b64}-VL
+    3206             :   ASMJIT_INST_3x(vpcmpgtq, Vpcmpgtq, X86KReg, X86Xmm, X86Mem)                 //      AVX512_F{k|b64}-VL
+    3207             :   ASMJIT_INST_3x(vpcmpgtq, Vpcmpgtq, X86KReg, X86Ymm, X86Ymm)                 //      AVX512_F{k|b64}-VL
+    3208             :   ASMJIT_INST_3x(vpcmpgtq, Vpcmpgtq, X86KReg, X86Ymm, X86Mem)                 //      AVX512_F{k|b64}-VL
+    3209             :   ASMJIT_INST_3x(vpcmpgtq, Vpcmpgtq, X86KReg, X86Zmm, X86Zmm)                 //      AVX512_F{k|b64}
+    3210             :   ASMJIT_INST_3x(vpcmpgtq, Vpcmpgtq, X86KReg, X86Zmm, X86Mem)                 //      AVX512_F{k|b64}
+    3211             :   ASMJIT_INST_3x(vpcmpgtw, Vpcmpgtw, X86Xmm, X86Xmm, X86Xmm)                  // AVX
+    3212             :   ASMJIT_INST_3x(vpcmpgtw, Vpcmpgtw, X86Xmm, X86Xmm, X86Mem)                  // AVX
+    3213             :   ASMJIT_INST_3x(vpcmpgtw, Vpcmpgtw, X86Ymm, X86Ymm, X86Ymm)                  // AVX2
+    3214             :   ASMJIT_INST_3x(vpcmpgtw, Vpcmpgtw, X86Ymm, X86Ymm, X86Mem)                  // AVX2
+    3215             :   ASMJIT_INST_3x(vpcmpgtw, Vpcmpgtw, X86KReg, X86Xmm, X86Xmm)                 //      AVX512_BW{k}-VL
+    3216             :   ASMJIT_INST_3x(vpcmpgtw, Vpcmpgtw, X86KReg, X86Xmm, X86Mem)                 //      AVX512_BW{k}-VL
+    3217             :   ASMJIT_INST_3x(vpcmpgtw, Vpcmpgtw, X86KReg, X86Ymm, X86Ymm)                 //      AVX512_BW{k}-VL
+    3218             :   ASMJIT_INST_3x(vpcmpgtw, Vpcmpgtw, X86KReg, X86Ymm, X86Mem)                 //      AVX512_BW{k}-VL
+    3219             :   ASMJIT_INST_3x(vpcmpgtw, Vpcmpgtw, X86KReg, X86Zmm, X86Zmm)                 //      AVX512_BW{k}
+    3220             :   ASMJIT_INST_3x(vpcmpgtw, Vpcmpgtw, X86KReg, X86Zmm, X86Mem)                 //      AVX512_BW{k}
+    3221             :   ASMJIT_INST_4x(vpcmpistri, Vpcmpistri, X86Xmm, X86Xmm, Imm, ECX)            // AVX  [EXPLICIT]
+    3222             :   ASMJIT_INST_4x(vpcmpistri, Vpcmpistri, X86Xmm, X86Mem, Imm, ECX)            // AVX  [EXPLICIT]
+    3223             :   ASMJIT_INST_4x(vpcmpistrm, Vpcmpistrm, X86Xmm, X86Xmm, Imm, XMM0)           // AVX  [EXPLICIT]
+    3224             :   ASMJIT_INST_4x(vpcmpistrm, Vpcmpistrm, X86Xmm, X86Mem, Imm, XMM0)           // AVX  [EXPLICIT]
+    3225             :   ASMJIT_INST_4i(vpcmpq, Vpcmpq, X86KReg, X86Xmm, X86Xmm, Imm)                //      AVX512_F{k|b64}-VL
+    3226             :   ASMJIT_INST_4i(vpcmpq, Vpcmpq, X86KReg, X86Xmm, X86Mem, Imm)                //      AVX512_F{k|b64}-VL
+    3227             :   ASMJIT_INST_4i(vpcmpq, Vpcmpq, X86KReg, X86Ymm, X86Ymm, Imm)                //      AVX512_F{k|b64}-VL
+    3228             :   ASMJIT_INST_4i(vpcmpq, Vpcmpq, X86KReg, X86Ymm, X86Mem, Imm)                //      AVX512_F{k|b64}-VL
+    3229             :   ASMJIT_INST_4i(vpcmpq, Vpcmpq, X86KReg, X86Zmm, X86Zmm, Imm)                //      AVX512_F{k|b64}
+    3230             :   ASMJIT_INST_4i(vpcmpq, Vpcmpq, X86KReg, X86Zmm, X86Mem, Imm)                //      AVX512_F{k|b64}
+    3231             :   ASMJIT_INST_4i(vpcmpub, Vpcmpub, X86KReg, X86Xmm, X86Xmm, Imm)              //      AVX512_BW{k}-VL
+    3232             :   ASMJIT_INST_4i(vpcmpub, Vpcmpub, X86KReg, X86Xmm, X86Mem, Imm)              //      AVX512_BW{k}-VL
+    3233             :   ASMJIT_INST_4i(vpcmpub, Vpcmpub, X86KReg, X86Ymm, X86Ymm, Imm)              //      AVX512_BW{k}-VL
+    3234             :   ASMJIT_INST_4i(vpcmpub, Vpcmpub, X86KReg, X86Ymm, X86Mem, Imm)              //      AVX512_BW{k}-VL
+    3235             :   ASMJIT_INST_4i(vpcmpub, Vpcmpub, X86KReg, X86Zmm, X86Zmm, Imm)              //      AVX512_BW{k}
+    3236             :   ASMJIT_INST_4i(vpcmpub, Vpcmpub, X86KReg, X86Zmm, X86Mem, Imm)              //      AVX512_BW{k}
+    3237             :   ASMJIT_INST_4i(vpcmpud, Vpcmpud, X86KReg, X86Xmm, X86Xmm, Imm)              //      AVX512_F{k|b32}-VL
+    3238             :   ASMJIT_INST_4i(vpcmpud, Vpcmpud, X86KReg, X86Xmm, X86Mem, Imm)              //      AVX512_F{k|b32}-VL
+    3239             :   ASMJIT_INST_4i(vpcmpud, Vpcmpud, X86KReg, X86Ymm, X86Ymm, Imm)              //      AVX512_F{k|b32}-VL
+    3240             :   ASMJIT_INST_4i(vpcmpud, Vpcmpud, X86KReg, X86Ymm, X86Mem, Imm)              //      AVX512_F{k|b32}-VL
+    3241             :   ASMJIT_INST_4i(vpcmpud, Vpcmpud, X86KReg, X86Zmm, X86Zmm, Imm)              //      AVX512_F{k|b32}
+    3242             :   ASMJIT_INST_4i(vpcmpud, Vpcmpud, X86KReg, X86Zmm, X86Mem, Imm)              //      AVX512_F{k|b32}
+    3243             :   ASMJIT_INST_4i(vpcmpuq, Vpcmpuq, X86KReg, X86Xmm, X86Xmm, Imm)              //      AVX512_F{k|b64}-VL
+    3244             :   ASMJIT_INST_4i(vpcmpuq, Vpcmpuq, X86KReg, X86Xmm, X86Mem, Imm)              //      AVX512_F{k|b64}-VL
+    3245             :   ASMJIT_INST_4i(vpcmpuq, Vpcmpuq, X86KReg, X86Ymm, X86Ymm, Imm)              //      AVX512_F{k|b64}-VL
+    3246             :   ASMJIT_INST_4i(vpcmpuq, Vpcmpuq, X86KReg, X86Ymm, X86Mem, Imm)              //      AVX512_F{k|b64}-VL
+    3247             :   ASMJIT_INST_4i(vpcmpuq, Vpcmpuq, X86KReg, X86Zmm, X86Zmm, Imm)              //      AVX512_F{k|b64}
+    3248             :   ASMJIT_INST_4i(vpcmpuq, Vpcmpuq, X86KReg, X86Zmm, X86Mem, Imm)              //      AVX512_F{k|b64}
+    3249             :   ASMJIT_INST_4i(vpcmpuw, Vpcmpuw, X86KReg, X86Xmm, X86Xmm, Imm)              //      AVX512_BW{k|b64}-VL
+    3250             :   ASMJIT_INST_4i(vpcmpuw, Vpcmpuw, X86KReg, X86Xmm, X86Mem, Imm)              //      AVX512_BW{k|b64}-VL
+    3251             :   ASMJIT_INST_4i(vpcmpuw, Vpcmpuw, X86KReg, X86Ymm, X86Ymm, Imm)              //      AVX512_BW{k|b64}-VL
+    3252             :   ASMJIT_INST_4i(vpcmpuw, Vpcmpuw, X86KReg, X86Ymm, X86Mem, Imm)              //      AVX512_BW{k|b64}-VL
+    3253             :   ASMJIT_INST_4i(vpcmpuw, Vpcmpuw, X86KReg, X86Zmm, X86Zmm, Imm)              //      AVX512_BW{k|b64}
+    3254             :   ASMJIT_INST_4i(vpcmpuw, Vpcmpuw, X86KReg, X86Zmm, X86Mem, Imm)              //      AVX512_BW{k|b64}
+    3255             :   ASMJIT_INST_4i(vpcmpw, Vpcmpw, X86KReg, X86Xmm, X86Xmm, Imm)                //      AVX512_BW{k|b64}-VL
+    3256             :   ASMJIT_INST_4i(vpcmpw, Vpcmpw, X86KReg, X86Xmm, X86Mem, Imm)                //      AVX512_BW{k|b64}-VL
+    3257             :   ASMJIT_INST_4i(vpcmpw, Vpcmpw, X86KReg, X86Ymm, X86Ymm, Imm)                //      AVX512_BW{k|b64}-VL
+    3258             :   ASMJIT_INST_4i(vpcmpw, Vpcmpw, X86KReg, X86Ymm, X86Mem, Imm)                //      AVX512_BW{k|b64}-VL
+    3259             :   ASMJIT_INST_4i(vpcmpw, Vpcmpw, X86KReg, X86Zmm, X86Zmm, Imm)                //      AVX512_BW{k|b64}
+    3260             :   ASMJIT_INST_4i(vpcmpw, Vpcmpw, X86KReg, X86Zmm, X86Mem, Imm)                //      AVX512_BW{k|b64}
+    3261             :   ASMJIT_INST_2x(vpcompressd, Vpcompressd, X86Xmm, X86Xmm)                    //      AVX512_F{kz}-VL
+    3262             :   ASMJIT_INST_2x(vpcompressd, Vpcompressd, X86Mem, X86Xmm)                    //      AVX512_F{kz}-VL
+    3263             :   ASMJIT_INST_2x(vpcompressd, Vpcompressd, X86Ymm, X86Ymm)                    //      AVX512_F{kz}-VL
+    3264             :   ASMJIT_INST_2x(vpcompressd, Vpcompressd, X86Mem, X86Ymm)                    //      AVX512_F{kz}-VL
+    3265             :   ASMJIT_INST_2x(vpcompressd, Vpcompressd, X86Zmm, X86Zmm)                    //      AVX512_F{kz}
+    3266             :   ASMJIT_INST_2x(vpcompressd, Vpcompressd, X86Mem, X86Zmm)                    //      AVX512_F{kz}
+    3267             :   ASMJIT_INST_2x(vpcompressq, Vpcompressq, X86Xmm, X86Xmm)                    //      AVX512_F{kz}-VL
+    3268             :   ASMJIT_INST_2x(vpcompressq, Vpcompressq, X86Mem, X86Xmm)                    //      AVX512_F{kz}-VL
+    3269             :   ASMJIT_INST_2x(vpcompressq, Vpcompressq, X86Ymm, X86Ymm)                    //      AVX512_F{kz}-VL
+    3270             :   ASMJIT_INST_2x(vpcompressq, Vpcompressq, X86Mem, X86Ymm)                    //      AVX512_F{kz}-VL
+    3271             :   ASMJIT_INST_2x(vpcompressq, Vpcompressq, X86Zmm, X86Zmm)                    //      AVX512_F{kz}
+    3272             :   ASMJIT_INST_2x(vpcompressq, Vpcompressq, X86Mem, X86Zmm)                    //      AVX512_F{kz}
+    3273             :   ASMJIT_INST_2x(vpconflictd, Vpconflictd, X86Xmm, X86Xmm)                    //      AVX512_CD{kz|b32}-VL
+    3274             :   ASMJIT_INST_2x(vpconflictd, Vpconflictd, X86Xmm, X86Mem)                    //      AVX512_CD{kz|b32}-VL
+    3275             :   ASMJIT_INST_2x(vpconflictd, Vpconflictd, X86Ymm, X86Ymm)                    //      AVX512_CD{kz|b32}-VL
+    3276             :   ASMJIT_INST_2x(vpconflictd, Vpconflictd, X86Ymm, X86Mem)                    //      AVX512_CD{kz|b32}-VL
+    3277             :   ASMJIT_INST_2x(vpconflictd, Vpconflictd, X86Zmm, X86Zmm)                    //      AVX512_CD{kz|b32}
+    3278             :   ASMJIT_INST_2x(vpconflictd, Vpconflictd, X86Zmm, X86Mem)                    //      AVX512_CD{kz|b32}
+    3279             :   ASMJIT_INST_2x(vpconflictq, Vpconflictq, X86Xmm, X86Xmm)                    //      AVX512_CD{kz|b32}-VL
+    3280             :   ASMJIT_INST_2x(vpconflictq, Vpconflictq, X86Xmm, X86Mem)                    //      AVX512_CD{kz|b32}-VL
+    3281             :   ASMJIT_INST_2x(vpconflictq, Vpconflictq, X86Ymm, X86Ymm)                    //      AVX512_CD{kz|b32}-VL
+    3282             :   ASMJIT_INST_2x(vpconflictq, Vpconflictq, X86Ymm, X86Mem)                    //      AVX512_CD{kz|b32}-VL
+    3283             :   ASMJIT_INST_2x(vpconflictq, Vpconflictq, X86Zmm, X86Zmm)                    //      AVX512_CD{kz|b32}
+    3284             :   ASMJIT_INST_2x(vpconflictq, Vpconflictq, X86Zmm, X86Mem)                    //      AVX512_CD{kz|b32}
+    3285             :   ASMJIT_INST_4i(vperm2f128, Vperm2f128, X86Ymm, X86Ymm, X86Ymm, Imm)         // AVX
+    3286             :   ASMJIT_INST_4i(vperm2f128, Vperm2f128, X86Ymm, X86Ymm, X86Mem, Imm)         // AVX
+    3287             :   ASMJIT_INST_4i(vperm2i128, Vperm2i128, X86Ymm, X86Ymm, X86Ymm, Imm)         // AVX2
+    3288             :   ASMJIT_INST_4i(vperm2i128, Vperm2i128, X86Ymm, X86Ymm, X86Mem, Imm)         // AVX2
+    3289             :   ASMJIT_INST_3x(vpermb, Vpermb, X86Xmm, X86Xmm, X86Xmm)                      //      AVX512_VBMI{kz}-VL
+    3290             :   ASMJIT_INST_3x(vpermb, Vpermb, X86Xmm, X86Xmm, X86Mem)                      //      AVX512_VBMI{kz}-VL
+    3291             :   ASMJIT_INST_3x(vpermb, Vpermb, X86Ymm, X86Ymm, X86Ymm)                      //      AVX512_VBMI{kz}-VL
+    3292             :   ASMJIT_INST_3x(vpermb, Vpermb, X86Ymm, X86Ymm, X86Mem)                      //      AVX512_VBMI{kz}-VL
+    3293             :   ASMJIT_INST_3x(vpermb, Vpermb, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_VBMI{kz}
+    3294             :   ASMJIT_INST_3x(vpermb, Vpermb, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_VBMI{kz}
+    3295             :   ASMJIT_INST_3x(vpermd, Vpermd, X86Ymm, X86Ymm, X86Ymm)                      // AVX2 AVX512_F{kz|b32}-VL
+    3296             :   ASMJIT_INST_3x(vpermd, Vpermd, X86Ymm, X86Ymm, X86Mem)                      // AVX2 AVX512_F{kz|b32}-VL
+    3297             :   ASMJIT_INST_3x(vpermd, Vpermd, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_F{kz|b32}-VL
+    3298             :   ASMJIT_INST_3x(vpermd, Vpermd, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_F{kz|b32}-VL
+    3299             :   ASMJIT_INST_3x(vpermi2b, Vpermi2b, X86Xmm, X86Xmm, X86Xmm)                  //      AVX512_VBMI{kz}-VL
+    3300             :   ASMJIT_INST_3x(vpermi2b, Vpermi2b, X86Xmm, X86Xmm, X86Mem)                  //      AVX512_VBMI{kz}-VL
+    3301             :   ASMJIT_INST_3x(vpermi2b, Vpermi2b, X86Ymm, X86Ymm, X86Ymm)                  //      AVX512_VBMI{kz}-VL
+    3302             :   ASMJIT_INST_3x(vpermi2b, Vpermi2b, X86Ymm, X86Ymm, X86Mem)                  //      AVX512_VBMI{kz}-VL
+    3303             :   ASMJIT_INST_3x(vpermi2b, Vpermi2b, X86Zmm, X86Zmm, X86Zmm)                  //      AVX512_VBMI{kz}
+    3304             :   ASMJIT_INST_3x(vpermi2b, Vpermi2b, X86Zmm, X86Zmm, X86Mem)                  //      AVX512_VBMI{kz}
+    3305             :   ASMJIT_INST_3x(vpermi2d, Vpermi2d, X86Xmm, X86Xmm, X86Xmm)                  //      AVX512_F{kz|b32}-VL
+    3306             :   ASMJIT_INST_3x(vpermi2d, Vpermi2d, X86Xmm, X86Xmm, X86Mem)                  //      AVX512_F{kz|b32}-VL
+    3307             :   ASMJIT_INST_3x(vpermi2d, Vpermi2d, X86Ymm, X86Ymm, X86Ymm)                  //      AVX512_F{kz|b32}-VL
+    3308             :   ASMJIT_INST_3x(vpermi2d, Vpermi2d, X86Ymm, X86Ymm, X86Mem)                  //      AVX512_F{kz|b32}-VL
+    3309             :   ASMJIT_INST_3x(vpermi2d, Vpermi2d, X86Zmm, X86Zmm, X86Zmm)                  //      AVX512_F{kz|b32}
+    3310             :   ASMJIT_INST_3x(vpermi2d, Vpermi2d, X86Zmm, X86Zmm, X86Mem)                  //      AVX512_F{kz|b32}
+    3311             :   ASMJIT_INST_3x(vpermi2pd, Vpermi2pd, X86Xmm, X86Xmm, X86Xmm)                //      AVX512_F{kz|b64}-VL
+    3312             :   ASMJIT_INST_3x(vpermi2pd, Vpermi2pd, X86Xmm, X86Xmm, X86Mem)                //      AVX512_F{kz|b64}-VL
+    3313             :   ASMJIT_INST_3x(vpermi2pd, Vpermi2pd, X86Ymm, X86Ymm, X86Ymm)                //      AVX512_F{kz|b64}-VL
+    3314             :   ASMJIT_INST_3x(vpermi2pd, Vpermi2pd, X86Ymm, X86Ymm, X86Mem)                //      AVX512_F{kz|b64}-VL
+    3315             :   ASMJIT_INST_3x(vpermi2pd, Vpermi2pd, X86Zmm, X86Zmm, X86Zmm)                //      AVX512_F{kz|b64}
+    3316             :   ASMJIT_INST_3x(vpermi2pd, Vpermi2pd, X86Zmm, X86Zmm, X86Mem)                //      AVX512_F{kz|b64}
+    3317             :   ASMJIT_INST_3x(vpermi2ps, Vpermi2ps, X86Xmm, X86Xmm, X86Xmm)                //      AVX512_F{kz|b32}-VL
+    3318             :   ASMJIT_INST_3x(vpermi2ps, Vpermi2ps, X86Xmm, X86Xmm, X86Mem)                //      AVX512_F{kz|b32}-VL
+    3319             :   ASMJIT_INST_3x(vpermi2ps, Vpermi2ps, X86Ymm, X86Ymm, X86Ymm)                //      AVX512_F{kz|b32}-VL
+    3320             :   ASMJIT_INST_3x(vpermi2ps, Vpermi2ps, X86Ymm, X86Ymm, X86Mem)                //      AVX512_F{kz|b32}-VL
+    3321             :   ASMJIT_INST_3x(vpermi2ps, Vpermi2ps, X86Zmm, X86Zmm, X86Zmm)                //      AVX512_F{kz|b32}
+    3322             :   ASMJIT_INST_3x(vpermi2ps, Vpermi2ps, X86Zmm, X86Zmm, X86Mem)                //      AVX512_F{kz|b32}
+    3323             :   ASMJIT_INST_3x(vpermi2q, Vpermi2q, X86Xmm, X86Xmm, X86Xmm)                  //      AVX512_F{kz|b64}-VL
+    3324             :   ASMJIT_INST_3x(vpermi2q, Vpermi2q, X86Xmm, X86Xmm, X86Mem)                  //      AVX512_F{kz|b64}-VL
+    3325             :   ASMJIT_INST_3x(vpermi2q, Vpermi2q, X86Ymm, X86Ymm, X86Ymm)                  //      AVX512_F{kz|b64}-VL
+    3326             :   ASMJIT_INST_3x(vpermi2q, Vpermi2q, X86Ymm, X86Ymm, X86Mem)                  //      AVX512_F{kz|b64}-VL
+    3327             :   ASMJIT_INST_3x(vpermi2q, Vpermi2q, X86Zmm, X86Zmm, X86Zmm)                  //      AVX512_F{kz|b64}
+    3328             :   ASMJIT_INST_3x(vpermi2q, Vpermi2q, X86Zmm, X86Zmm, X86Mem)                  //      AVX512_F{kz|b64}
+    3329             :   ASMJIT_INST_3x(vpermi2w, Vpermi2w, X86Xmm, X86Xmm, X86Xmm)                  //      AVX512_BW{kz}-VL
+    3330             :   ASMJIT_INST_3x(vpermi2w, Vpermi2w, X86Xmm, X86Xmm, X86Mem)                  //      AVX512_BW{kz}-VL
+    3331             :   ASMJIT_INST_3x(vpermi2w, Vpermi2w, X86Ymm, X86Ymm, X86Ymm)                  //      AVX512_BW{kz}-VL
+    3332             :   ASMJIT_INST_3x(vpermi2w, Vpermi2w, X86Ymm, X86Ymm, X86Mem)                  //      AVX512_BW{kz}-VL
+    3333             :   ASMJIT_INST_3x(vpermi2w, Vpermi2w, X86Zmm, X86Zmm, X86Zmm)                  //      AVX512_BW{kz}
+    3334             :   ASMJIT_INST_3x(vpermi2w, Vpermi2w, X86Zmm, X86Zmm, X86Mem)                  //      AVX512_BW{kz}
+    3335             :   ASMJIT_INST_3x(vpermilpd, Vpermilpd, X86Xmm, X86Xmm, X86Xmm)                // AVX  AVX512_F{kz|b64}-VL
+    3336             :   ASMJIT_INST_3x(vpermilpd, Vpermilpd, X86Xmm, X86Xmm, X86Mem)                // AVX  AVX512_F{kz|b64}-VL
+    3337             :   ASMJIT_INST_3i(vpermilpd, Vpermilpd, X86Xmm, X86Xmm, Imm)                   // AVX  AVX512_F{kz|b64}-VL
+    3338             :   ASMJIT_INST_3i(vpermilpd, Vpermilpd, X86Xmm, X86Mem, Imm)                   // AVX  AVX512_F{kz|b64}-VL
+    3339             :   ASMJIT_INST_3x(vpermilpd, Vpermilpd, X86Ymm, X86Ymm, X86Ymm)                // AVX  AVX512_F{kz|b64}-VL
+    3340             :   ASMJIT_INST_3x(vpermilpd, Vpermilpd, X86Ymm, X86Ymm, X86Mem)                // AVX  AVX512_F{kz|b64}-VL
+    3341             :   ASMJIT_INST_3i(vpermilpd, Vpermilpd, X86Ymm, X86Ymm, Imm)                   // AVX  AVX512_F{kz|b64}-VL
+    3342             :   ASMJIT_INST_3i(vpermilpd, Vpermilpd, X86Ymm, X86Mem, Imm)                   // AVX  AVX512_F{kz|b64}-VL
+    3343             :   ASMJIT_INST_3x(vpermilpd, Vpermilpd, X86Zmm, X86Zmm, X86Zmm)                //      AVX512_F{kz|b64}
+    3344             :   ASMJIT_INST_3x(vpermilpd, Vpermilpd, X86Zmm, X86Zmm, X86Mem)                //      AVX512_F{kz|b64}
+    3345             :   ASMJIT_INST_3i(vpermilpd, Vpermilpd, X86Zmm, X86Zmm, Imm)                   //      AVX512_F{kz|b64}
+    3346             :   ASMJIT_INST_3i(vpermilpd, Vpermilpd, X86Zmm, X86Mem, Imm)                   //      AVX512_F{kz|b64}
+    3347             :   ASMJIT_INST_3x(vpermilps, Vpermilps, X86Xmm, X86Xmm, X86Xmm)                // AVX  AVX512_F{kz|b64}-VL
+    3348             :   ASMJIT_INST_3x(vpermilps, Vpermilps, X86Xmm, X86Xmm, X86Mem)                // AVX  AVX512_F{kz|b64}-VL
+    3349             :   ASMJIT_INST_3i(vpermilps, Vpermilps, X86Xmm, X86Xmm, Imm)                   // AVX  AVX512_F{kz|b64}-VL
+    3350             :   ASMJIT_INST_3i(vpermilps, Vpermilps, X86Xmm, X86Mem, Imm)                   // AVX  AVX512_F{kz|b64}-VL
+    3351             :   ASMJIT_INST_3x(vpermilps, Vpermilps, X86Ymm, X86Ymm, X86Ymm)                // AVX  AVX512_F{kz|b64}-VL
+    3352             :   ASMJIT_INST_3x(vpermilps, Vpermilps, X86Ymm, X86Ymm, X86Mem)                // AVX  AVX512_F{kz|b64}-VL
+    3353             :   ASMJIT_INST_3i(vpermilps, Vpermilps, X86Ymm, X86Ymm, Imm)                   // AVX  AVX512_F{kz|b64}-VL
+    3354             :   ASMJIT_INST_3i(vpermilps, Vpermilps, X86Ymm, X86Mem, Imm)                   // AVX  AVX512_F{kz|b64}-VL
+    3355             :   ASMJIT_INST_3x(vpermilps, Vpermilps, X86Zmm, X86Zmm, X86Zmm)                //      AVX512_F{kz|b64}
+    3356             :   ASMJIT_INST_3x(vpermilps, Vpermilps, X86Zmm, X86Zmm, X86Mem)                //      AVX512_F{kz|b64}
+    3357             :   ASMJIT_INST_3i(vpermilps, Vpermilps, X86Zmm, X86Zmm, Imm)                   //      AVX512_F{kz|b64}
+    3358             :   ASMJIT_INST_3i(vpermilps, Vpermilps, X86Zmm, X86Mem, Imm)                   //      AVX512_F{kz|b64}
+    3359             :   ASMJIT_INST_3i(vpermpd, Vpermpd, X86Ymm, X86Ymm, Imm)                       // AVX2
+    3360             :   ASMJIT_INST_3i(vpermpd, Vpermpd, X86Ymm, X86Mem, Imm)                       // AVX2
+    3361             :   ASMJIT_INST_3x(vpermps, Vpermps, X86Ymm, X86Ymm, X86Ymm)                    // AVX2
+    3362             :   ASMJIT_INST_3x(vpermps, Vpermps, X86Ymm, X86Ymm, X86Mem)                    // AVX2
+    3363             :   ASMJIT_INST_3i(vpermq, Vpermq, X86Ymm, X86Ymm, Imm)                         // AVX2 AVX512_F{kz|b64}-VL
+    3364             :   ASMJIT_INST_3i(vpermq, Vpermq, X86Ymm, X86Mem, Imm)                         // AVX2 AVX512_F{kz|b64}-VL
+    3365             :   ASMJIT_INST_3x(vpermq, Vpermq, X86Ymm, X86Ymm, X86Ymm)                      //      AVX512_F{kz|b64}-VL
+    3366             :   ASMJIT_INST_3x(vpermq, Vpermq, X86Ymm, X86Ymm, X86Mem)                      //      AVX512_F{kz|b64}-VL
+    3367             :   ASMJIT_INST_3x(vpermq, Vpermq, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_F{kz|b64}-VL
+    3368             :   ASMJIT_INST_3x(vpermq, Vpermq, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_F{kz|b64}-VL
+    3369             :   ASMJIT_INST_3i(vpermq, Vpermq, X86Zmm, X86Zmm, Imm)                         //      AVX512_F{kz|b64}-VL
+    3370             :   ASMJIT_INST_3i(vpermq, Vpermq, X86Zmm, X86Mem, Imm)                         //      AVX512_F{kz|b64}-VL
+    3371             :   ASMJIT_INST_3x(vpermt2b, Vpermt2b, X86Xmm, X86Xmm, X86Xmm)                  //      AVX512_VBMI{kz}-VL
+    3372             :   ASMJIT_INST_3x(vpermt2b, Vpermt2b, X86Xmm, X86Xmm, X86Mem)                  //      AVX512_VBMI{kz}-VL
+    3373             :   ASMJIT_INST_3x(vpermt2b, Vpermt2b, X86Ymm, X86Ymm, X86Ymm)                  //      AVX512_VBMI{kz}-VL
+    3374             :   ASMJIT_INST_3x(vpermt2b, Vpermt2b, X86Ymm, X86Ymm, X86Mem)                  //      AVX512_VBMI{kz}-VL
+    3375             :   ASMJIT_INST_3x(vpermt2b, Vpermt2b, X86Zmm, X86Zmm, X86Zmm)                  //      AVX512_VBMI{kz}
+    3376             :   ASMJIT_INST_3x(vpermt2b, Vpermt2b, X86Zmm, X86Zmm, X86Mem)                  //      AVX512_VBMI{kz}
+    3377             :   ASMJIT_INST_3x(vpermt2d, Vpermt2d, X86Xmm, X86Xmm, X86Xmm)                  //      AVX512_F{kz|b32}-VL
+    3378             :   ASMJIT_INST_3x(vpermt2d, Vpermt2d, X86Xmm, X86Xmm, X86Mem)                  //      AVX512_F{kz|b32}-VL
+    3379             :   ASMJIT_INST_3x(vpermt2d, Vpermt2d, X86Ymm, X86Ymm, X86Ymm)                  //      AVX512_F{kz|b32}-VL
+    3380             :   ASMJIT_INST_3x(vpermt2d, Vpermt2d, X86Ymm, X86Ymm, X86Mem)                  //      AVX512_F{kz|b32}-VL
+    3381             :   ASMJIT_INST_3x(vpermt2d, Vpermt2d, X86Zmm, X86Zmm, X86Zmm)                  //      AVX512_F{kz|b32}
+    3382             :   ASMJIT_INST_3x(vpermt2d, Vpermt2d, X86Zmm, X86Zmm, X86Mem)                  //      AVX512_F{kz|b32}
+    3383             :   ASMJIT_INST_3x(vpermt2pd, Vpermt2pd, X86Xmm, X86Xmm, X86Xmm)                //      AVX512_F{kz|b64}-VL
+    3384             :   ASMJIT_INST_3x(vpermt2pd, Vpermt2pd, X86Xmm, X86Xmm, X86Mem)                //      AVX512_F{kz|b64}-VL
+    3385             :   ASMJIT_INST_3x(vpermt2pd, Vpermt2pd, X86Ymm, X86Ymm, X86Ymm)                //      AVX512_F{kz|b64}-VL
+    3386             :   ASMJIT_INST_3x(vpermt2pd, Vpermt2pd, X86Ymm, X86Ymm, X86Mem)                //      AVX512_F{kz|b64}-VL
+    3387             :   ASMJIT_INST_3x(vpermt2pd, Vpermt2pd, X86Zmm, X86Zmm, X86Zmm)                //      AVX512_F{kz|b64}
+    3388             :   ASMJIT_INST_3x(vpermt2pd, Vpermt2pd, X86Zmm, X86Zmm, X86Mem)                //      AVX512_F{kz|b64}
+    3389             :   ASMJIT_INST_3x(vpermt2ps, Vpermt2ps, X86Xmm, X86Xmm, X86Xmm)                //      AVX512_F{kz|b32}-VL
+    3390             :   ASMJIT_INST_3x(vpermt2ps, Vpermt2ps, X86Xmm, X86Xmm, X86Mem)                //      AVX512_F{kz|b32}-VL
+    3391             :   ASMJIT_INST_3x(vpermt2ps, Vpermt2ps, X86Ymm, X86Ymm, X86Ymm)                //      AVX512_F{kz|b32}-VL
+    3392             :   ASMJIT_INST_3x(vpermt2ps, Vpermt2ps, X86Ymm, X86Ymm, X86Mem)                //      AVX512_F{kz|b32}-VL
+    3393             :   ASMJIT_INST_3x(vpermt2ps, Vpermt2ps, X86Zmm, X86Zmm, X86Zmm)                //      AVX512_F{kz|b32}
+    3394             :   ASMJIT_INST_3x(vpermt2ps, Vpermt2ps, X86Zmm, X86Zmm, X86Mem)                //      AVX512_F{kz|b32}
+    3395             :   ASMJIT_INST_3x(vpermt2q, Vpermt2q, X86Xmm, X86Xmm, X86Xmm)                  //      AVX512_F{kz|b64}-VL
+    3396             :   ASMJIT_INST_3x(vpermt2q, Vpermt2q, X86Xmm, X86Xmm, X86Mem)                  //      AVX512_F{kz|b64}-VL
+    3397             :   ASMJIT_INST_3x(vpermt2q, Vpermt2q, X86Ymm, X86Ymm, X86Ymm)                  //      AVX512_F{kz|b64}-VL
+    3398             :   ASMJIT_INST_3x(vpermt2q, Vpermt2q, X86Ymm, X86Ymm, X86Mem)                  //      AVX512_F{kz|b64}-VL
+    3399             :   ASMJIT_INST_3x(vpermt2q, Vpermt2q, X86Zmm, X86Zmm, X86Zmm)                  //      AVX512_F{kz|b64}
+    3400             :   ASMJIT_INST_3x(vpermt2q, Vpermt2q, X86Zmm, X86Zmm, X86Mem)                  //      AVX512_F{kz|b64}
+    3401             :   ASMJIT_INST_3x(vpermt2w, Vpermt2w, X86Xmm, X86Xmm, X86Xmm)                  //      AVX512_BW{kz}-VL
+    3402             :   ASMJIT_INST_3x(vpermt2w, Vpermt2w, X86Xmm, X86Xmm, X86Mem)                  //      AVX512_BW{kz}-VL
+    3403             :   ASMJIT_INST_3x(vpermt2w, Vpermt2w, X86Ymm, X86Ymm, X86Ymm)                  //      AVX512_BW{kz}-VL
+    3404             :   ASMJIT_INST_3x(vpermt2w, Vpermt2w, X86Ymm, X86Ymm, X86Mem)                  //      AVX512_BW{kz}-VL
+    3405             :   ASMJIT_INST_3x(vpermt2w, Vpermt2w, X86Zmm, X86Zmm, X86Zmm)                  //      AVX512_BW{kz}
+    3406             :   ASMJIT_INST_3x(vpermt2w, Vpermt2w, X86Zmm, X86Zmm, X86Mem)                  //      AVX512_BW{kz}
+    3407             :   ASMJIT_INST_3x(vpermw, Vpermw, X86Xmm, X86Xmm, X86Xmm)                      //      AVX512_BW{kz}-VL
+    3408             :   ASMJIT_INST_3x(vpermw, Vpermw, X86Xmm, X86Xmm, X86Mem)                      //      AVX512_BW{kz}-VL
+    3409             :   ASMJIT_INST_3x(vpermw, Vpermw, X86Ymm, X86Ymm, X86Ymm)                      //      AVX512_BW{kz}-VL
+    3410             :   ASMJIT_INST_3x(vpermw, Vpermw, X86Ymm, X86Ymm, X86Mem)                      //      AVX512_BW{kz}-VL
+    3411             :   ASMJIT_INST_3x(vpermw, Vpermw, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_BW{kz}
+    3412             :   ASMJIT_INST_3x(vpermw, Vpermw, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_BW{kz}
+    3413             :   ASMJIT_INST_2x(vpexpandd, Vpexpandd, X86Xmm, X86Xmm)                        //      AVX512_F{kz}-VL
+    3414             :   ASMJIT_INST_2x(vpexpandd, Vpexpandd, X86Xmm, X86Mem)                        //      AVX512_F{kz}-VL
+    3415             :   ASMJIT_INST_2x(vpexpandd, Vpexpandd, X86Ymm, X86Ymm)                        //      AVX512_F{kz}-VL
+    3416             :   ASMJIT_INST_2x(vpexpandd, Vpexpandd, X86Ymm, X86Mem)                        //      AVX512_F{kz}-VL
+    3417             :   ASMJIT_INST_2x(vpexpandd, Vpexpandd, X86Zmm, X86Zmm)                        //      AVX512_F{kz}
+    3418             :   ASMJIT_INST_2x(vpexpandd, Vpexpandd, X86Zmm, X86Mem)                        //      AVX512_F{kz}
+    3419             :   ASMJIT_INST_2x(vpexpandq, Vpexpandq, X86Xmm, X86Xmm)                        //      AVX512_F{kz}-VL
+    3420             :   ASMJIT_INST_2x(vpexpandq, Vpexpandq, X86Xmm, X86Mem)                        //      AVX512_F{kz}-VL
+    3421             :   ASMJIT_INST_2x(vpexpandq, Vpexpandq, X86Ymm, X86Ymm)                        //      AVX512_F{kz}-VL
+    3422             :   ASMJIT_INST_2x(vpexpandq, Vpexpandq, X86Ymm, X86Mem)                        //      AVX512_F{kz}-VL
+    3423             :   ASMJIT_INST_2x(vpexpandq, Vpexpandq, X86Zmm, X86Zmm)                        //      AVX512_F{kz}
+    3424             :   ASMJIT_INST_2x(vpexpandq, Vpexpandq, X86Zmm, X86Mem)                        //      AVX512_F{kz}
+    3425             :   ASMJIT_INST_3i(vpextrb, Vpextrb, X86Gp, X86Xmm, Imm)                        // AVX  AVX512_BW
+    3426             :   ASMJIT_INST_3i(vpextrb, Vpextrb, X86Mem, X86Xmm, Imm)                       // AVX  AVX512_BW
+    3427             :   ASMJIT_INST_3i(vpextrd, Vpextrd, X86Gp, X86Xmm, Imm)                        // AVX  AVX512_DQ
+    3428             :   ASMJIT_INST_3i(vpextrd, Vpextrd, X86Mem, X86Xmm, Imm)                       // AVX  AVX512_DQ
+    3429             :   ASMJIT_INST_3i(vpextrq, Vpextrq, X86Gp, X86Xmm, Imm)                        // AVX  AVX512_DQ
+    3430             :   ASMJIT_INST_3i(vpextrq, Vpextrq, X86Mem, X86Xmm, Imm)                       // AVX  AVX512_DQ
+    3431             :   ASMJIT_INST_3i(vpextrw, Vpextrw, X86Gp, X86Xmm, Imm)                        // AVX  AVX512_BW
+    3432             :   ASMJIT_INST_3i(vpextrw, Vpextrw, X86Mem, X86Xmm, Imm)                       // AVX  AVX512_BW
+    3433             :   ASMJIT_INST_3x(vpgatherdd, Vpgatherdd, X86Xmm, X86Mem, X86Xmm)              // AVX2
+    3434             :   ASMJIT_INST_3x(vpgatherdd, Vpgatherdd, X86Ymm, X86Mem, X86Ymm)              // AVX2
+    3435             :   ASMJIT_INST_2x(vpgatherdd, Vpgatherdd, X86Xmm, X86Mem)                      //      AVX512_F{k}-VL
+    3436             :   ASMJIT_INST_2x(vpgatherdd, Vpgatherdd, X86Ymm, X86Mem)                      //      AVX512_F{k}-VL
+    3437             :   ASMJIT_INST_2x(vpgatherdd, Vpgatherdd, X86Zmm, X86Mem)                      //      AVX512_F{k}
+    3438             :   ASMJIT_INST_3x(vpgatherdq, Vpgatherdq, X86Xmm, X86Mem, X86Xmm)              // AVX2
+    3439             :   ASMJIT_INST_3x(vpgatherdq, Vpgatherdq, X86Ymm, X86Mem, X86Ymm)              // AVX2
+    3440             :   ASMJIT_INST_2x(vpgatherdq, Vpgatherdq, X86Xmm, X86Mem)                      //      AVX512_F{k}-VL
+    3441             :   ASMJIT_INST_2x(vpgatherdq, Vpgatherdq, X86Ymm, X86Mem)                      //      AVX512_F{k}-VL
+    3442             :   ASMJIT_INST_2x(vpgatherdq, Vpgatherdq, X86Zmm, X86Mem)                      //      AVX512_F{k}
+    3443             :   ASMJIT_INST_3x(vpgatherqd, Vpgatherqd, X86Xmm, X86Mem, X86Xmm)              // AVX2
+    3444             :   ASMJIT_INST_2x(vpgatherqd, Vpgatherqd, X86Xmm, X86Mem)                      //      AVX512_F{k}-VL
+    3445             :   ASMJIT_INST_2x(vpgatherqd, Vpgatherqd, X86Ymm, X86Mem)                      //      AVX512_F{k}-VL
+    3446             :   ASMJIT_INST_2x(vpgatherqd, Vpgatherqd, X86Zmm, X86Mem)                      //      AVX512_F{k}
+    3447             :   ASMJIT_INST_3x(vpgatherqq, Vpgatherqq, X86Xmm, X86Mem, X86Xmm)              // AVX2
+    3448             :   ASMJIT_INST_3x(vpgatherqq, Vpgatherqq, X86Ymm, X86Mem, X86Ymm)              // AVX2
+    3449             :   ASMJIT_INST_2x(vpgatherqq, Vpgatherqq, X86Xmm, X86Mem)                      //      AVX512_F{k}-VL
+    3450             :   ASMJIT_INST_2x(vpgatherqq, Vpgatherqq, X86Ymm, X86Mem)                      //      AVX512_F{k}-VL
+    3451             :   ASMJIT_INST_2x(vpgatherqq, Vpgatherqq, X86Zmm, X86Mem)                      //      AVX512_F{k}
+    3452             :   ASMJIT_INST_3x(vphaddd, Vphaddd, X86Xmm, X86Xmm, X86Xmm)                    // AVX
+    3453             :   ASMJIT_INST_3x(vphaddd, Vphaddd, X86Xmm, X86Xmm, X86Mem)                    // AVX
+    3454             :   ASMJIT_INST_3x(vphaddd, Vphaddd, X86Ymm, X86Ymm, X86Ymm)                    // AVX2
+    3455             :   ASMJIT_INST_3x(vphaddd, Vphaddd, X86Ymm, X86Ymm, X86Mem)                    // AVX2
+    3456             :   ASMJIT_INST_3x(vphaddsw, Vphaddsw, X86Xmm, X86Xmm, X86Xmm)                  // AVX
+    3457             :   ASMJIT_INST_3x(vphaddsw, Vphaddsw, X86Xmm, X86Xmm, X86Mem)                  // AVX
+    3458             :   ASMJIT_INST_3x(vphaddsw, Vphaddsw, X86Ymm, X86Ymm, X86Ymm)                  // AVX2
+    3459             :   ASMJIT_INST_3x(vphaddsw, Vphaddsw, X86Ymm, X86Ymm, X86Mem)                  // AVX2
+    3460             :   ASMJIT_INST_3x(vphaddw, Vphaddw, X86Xmm, X86Xmm, X86Xmm)                    // AVX
+    3461             :   ASMJIT_INST_3x(vphaddw, Vphaddw, X86Xmm, X86Xmm, X86Mem)                    // AVX
+    3462             :   ASMJIT_INST_3x(vphaddw, Vphaddw, X86Ymm, X86Ymm, X86Ymm)                    // AVX2
+    3463             :   ASMJIT_INST_3x(vphaddw, Vphaddw, X86Ymm, X86Ymm, X86Mem)                    // AVX2
+    3464             :   ASMJIT_INST_2x(vphminposuw, Vphminposuw, X86Xmm, X86Xmm)                    // AVX
+    3465             :   ASMJIT_INST_2x(vphminposuw, Vphminposuw, X86Xmm, X86Mem)                    // AVX
+    3466             :   ASMJIT_INST_3x(vphsubd, Vphsubd, X86Xmm, X86Xmm, X86Xmm)                    // AVX
+    3467             :   ASMJIT_INST_3x(vphsubd, Vphsubd, X86Xmm, X86Xmm, X86Mem)                    // AVX
+    3468             :   ASMJIT_INST_3x(vphsubd, Vphsubd, X86Ymm, X86Ymm, X86Ymm)                    // AVX2
+    3469             :   ASMJIT_INST_3x(vphsubd, Vphsubd, X86Ymm, X86Ymm, X86Mem)                    // AVX2
+    3470             :   ASMJIT_INST_3x(vphsubsw, Vphsubsw, X86Xmm, X86Xmm, X86Xmm)                  // AVX
+    3471             :   ASMJIT_INST_3x(vphsubsw, Vphsubsw, X86Xmm, X86Xmm, X86Mem)                  // AVX
+    3472             :   ASMJIT_INST_3x(vphsubsw, Vphsubsw, X86Ymm, X86Ymm, X86Ymm)                  // AVX2
+    3473             :   ASMJIT_INST_3x(vphsubsw, Vphsubsw, X86Ymm, X86Ymm, X86Mem)                  // AVX2
+    3474             :   ASMJIT_INST_3x(vphsubw, Vphsubw, X86Xmm, X86Xmm, X86Xmm)                    // AVX
+    3475             :   ASMJIT_INST_3x(vphsubw, Vphsubw, X86Xmm, X86Xmm, X86Mem)                    // AVX
+    3476             :   ASMJIT_INST_3x(vphsubw, Vphsubw, X86Ymm, X86Ymm, X86Ymm)                    // AVX2
+    3477             :   ASMJIT_INST_3x(vphsubw, Vphsubw, X86Ymm, X86Ymm, X86Mem)                    // AVX2
+    3478             :   ASMJIT_INST_3i(vpinsrb, Vpinsrb, X86Xmm, X86Gp, Imm)                        // AVX
+    3479             :   ASMJIT_INST_3i(vpinsrb, Vpinsrb, X86Xmm, X86Mem, Imm)                       // AVX
+    3480             :   ASMJIT_INST_4i(vpinsrb, Vpinsrb, X86Xmm, X86Xmm, X86Gp, Imm)                //      AVX512_BW{kz}
+    3481             :   ASMJIT_INST_4i(vpinsrb, Vpinsrb, X86Xmm, X86Xmm, X86Mem, Imm)               //      AVX512_BW{kz}
+    3482             :   ASMJIT_INST_3i(vpinsrd, Vpinsrd, X86Xmm, X86Gp, Imm)                        // AVX
+    3483             :   ASMJIT_INST_3i(vpinsrd, Vpinsrd, X86Xmm, X86Mem, Imm)                       // AVX
+    3484             :   ASMJIT_INST_4i(vpinsrd, Vpinsrd, X86Xmm, X86Xmm, X86Gp, Imm)                //      AVX512_DQ{kz}
+    3485             :   ASMJIT_INST_4i(vpinsrd, Vpinsrd, X86Xmm, X86Xmm, X86Mem, Imm)               //      AVX512_DQ{kz}
+    3486             :   ASMJIT_INST_3i(vpinsrq, Vpinsrq, X86Xmm, X86Gp, Imm)                        // AVX
+    3487             :   ASMJIT_INST_3i(vpinsrq, Vpinsrq, X86Xmm, X86Mem, Imm)                       // AVX
+    3488             :   ASMJIT_INST_4i(vpinsrq, Vpinsrq, X86Xmm, X86Xmm, X86Gp, Imm)                //      AVX512_DQ{kz}
+    3489             :   ASMJIT_INST_4i(vpinsrq, Vpinsrq, X86Xmm, X86Xmm, X86Mem, Imm)               //      AVX512_DQ{kz}
+    3490             :   ASMJIT_INST_4i(vpinsrw, Vpinsrw, X86Xmm, X86Xmm, X86Gp, Imm)                // AVX  AVX512_BW{kz}
+    3491             :   ASMJIT_INST_4i(vpinsrw, Vpinsrw, X86Xmm, X86Xmm, X86Mem, Imm)               // AVX  AVX512_BW{kz}
+    3492             :   ASMJIT_INST_2x(vplzcntd, Vplzcntd, X86Xmm, X86Xmm)                          //      AVX512_CD{kz|b32}-VL
+    3493             :   ASMJIT_INST_2x(vplzcntd, Vplzcntd, X86Xmm, X86Mem)                          //      AVX512_CD{kz|b32}-VL
+    3494             :   ASMJIT_INST_2x(vplzcntd, Vplzcntd, X86Ymm, X86Ymm)                          //      AVX512_CD{kz|b32}-VL
+    3495             :   ASMJIT_INST_2x(vplzcntd, Vplzcntd, X86Ymm, X86Mem)                          //      AVX512_CD{kz|b32}-VL
+    3496             :   ASMJIT_INST_2x(vplzcntd, Vplzcntd, X86Zmm, X86Zmm)                          //      AVX512_CD{kz|b32}
+    3497             :   ASMJIT_INST_2x(vplzcntd, Vplzcntd, X86Zmm, X86Mem)                          //      AVX512_CD{kz|b32}
+    3498             :   ASMJIT_INST_2x(vplzcntq, Vplzcntq, X86Xmm, X86Xmm)                          //      AVX512_CD{kz|b64}-VL
+    3499             :   ASMJIT_INST_2x(vplzcntq, Vplzcntq, X86Xmm, X86Mem)                          //      AVX512_CD{kz|b64}-VL
+    3500             :   ASMJIT_INST_2x(vplzcntq, Vplzcntq, X86Ymm, X86Ymm)                          //      AVX512_CD{kz|b64}-VL
+    3501             :   ASMJIT_INST_2x(vplzcntq, Vplzcntq, X86Ymm, X86Mem)                          //      AVX512_CD{kz|b64}-VL
+    3502             :   ASMJIT_INST_2x(vplzcntq, Vplzcntq, X86Zmm, X86Zmm)                          //      AVX512_CD{kz|b64}
+    3503             :   ASMJIT_INST_2x(vplzcntq, Vplzcntq, X86Zmm, X86Mem)                          //      AVX512_CD{kz|b64}
+    3504             :   ASMJIT_INST_3x(vpmadd52huq, Vpmadd52huq, X86Xmm, X86Xmm, X86Xmm)            //      AVX512_IFMA{kz|b64}-VL
+    3505             :   ASMJIT_INST_3x(vpmadd52huq, Vpmadd52huq, X86Xmm, X86Xmm, X86Mem)            //      AVX512_IFMA{kz|b64}-VL
+    3506             :   ASMJIT_INST_3x(vpmadd52huq, Vpmadd52huq, X86Ymm, X86Ymm, X86Ymm)            //      AVX512_IFMA{kz|b64}-VL
+    3507             :   ASMJIT_INST_3x(vpmadd52huq, Vpmadd52huq, X86Ymm, X86Ymm, X86Mem)            //      AVX512_IFMA{kz|b64}-VL
+    3508             :   ASMJIT_INST_3x(vpmadd52huq, Vpmadd52huq, X86Zmm, X86Zmm, X86Zmm)            //      AVX512_IFMA{kz|b64}
+    3509             :   ASMJIT_INST_3x(vpmadd52huq, Vpmadd52huq, X86Zmm, X86Zmm, X86Mem)            //      AVX512_IFMA{kz|b64}
+    3510             :   ASMJIT_INST_3x(vpmadd52luq, Vpmadd52luq, X86Xmm, X86Xmm, X86Xmm)            //      AVX512_IFMA{kz|b64}-VL
+    3511             :   ASMJIT_INST_3x(vpmadd52luq, Vpmadd52luq, X86Xmm, X86Xmm, X86Mem)            //      AVX512_IFMA{kz|b64}-VL
+    3512             :   ASMJIT_INST_3x(vpmadd52luq, Vpmadd52luq, X86Ymm, X86Ymm, X86Ymm)            //      AVX512_IFMA{kz|b64}-VL
+    3513             :   ASMJIT_INST_3x(vpmadd52luq, Vpmadd52luq, X86Ymm, X86Ymm, X86Mem)            //      AVX512_IFMA{kz|b64}-VL
+    3514             :   ASMJIT_INST_3x(vpmadd52luq, Vpmadd52luq, X86Zmm, X86Zmm, X86Zmm)            //      AVX512_IFMA{kz|b64}
+    3515             :   ASMJIT_INST_3x(vpmadd52luq, Vpmadd52luq, X86Zmm, X86Zmm, X86Mem)            //      AVX512_IFMA{kz|b64}
+    3516             :   ASMJIT_INST_3x(vpmaddubsw, Vpmaddubsw, X86Xmm, X86Xmm, X86Xmm)              // AVX  AVX512_BW{kz}-VL
+    3517             :   ASMJIT_INST_3x(vpmaddubsw, Vpmaddubsw, X86Xmm, X86Xmm, X86Mem)              // AVX  AVX512_BW{kz}-VL
+    3518             :   ASMJIT_INST_3x(vpmaddubsw, Vpmaddubsw, X86Ymm, X86Ymm, X86Ymm)              // AVX2 AVX512_BW{kz}-VL
+    3519             :   ASMJIT_INST_3x(vpmaddubsw, Vpmaddubsw, X86Ymm, X86Ymm, X86Mem)              // AVX2 AVX512_BW{kz}-VL
+    3520             :   ASMJIT_INST_3x(vpmaddubsw, Vpmaddubsw, X86Zmm, X86Zmm, X86Zmm)              //      AVX512_BW{kz}
+    3521             :   ASMJIT_INST_3x(vpmaddubsw, Vpmaddubsw, X86Zmm, X86Zmm, X86Mem)              //      AVX512_BW{kz}
+    3522             :   ASMJIT_INST_3x(vpmaddwd, Vpmaddwd, X86Xmm, X86Xmm, X86Xmm)                  // AVX  AVX512_BW{kz}-VL
+    3523             :   ASMJIT_INST_3x(vpmaddwd, Vpmaddwd, X86Xmm, X86Xmm, X86Mem)                  // AVX  AVX512_BW{kz}-VL
+    3524             :   ASMJIT_INST_3x(vpmaddwd, Vpmaddwd, X86Ymm, X86Ymm, X86Ymm)                  // AVX2 AVX512_BW{kz}-VL
+    3525             :   ASMJIT_INST_3x(vpmaddwd, Vpmaddwd, X86Ymm, X86Ymm, X86Mem)                  // AVX2 AVX512_BW{kz}-VL
+    3526             :   ASMJIT_INST_3x(vpmaddwd, Vpmaddwd, X86Zmm, X86Zmm, X86Zmm)                  //      AVX512_BW{kz}
+    3527             :   ASMJIT_INST_3x(vpmaddwd, Vpmaddwd, X86Zmm, X86Zmm, X86Mem)                  //      AVX512_BW{kz}
+    3528             :   ASMJIT_INST_3x(vpmaskmovd, Vpmaskmovd, X86Mem, X86Xmm, X86Xmm)              // AVX2
+    3529             :   ASMJIT_INST_3x(vpmaskmovd, Vpmaskmovd, X86Mem, X86Ymm, X86Ymm)              // AVX2
+    3530             :   ASMJIT_INST_3x(vpmaskmovd, Vpmaskmovd, X86Xmm, X86Xmm, X86Mem)              // AVX2
+    3531             :   ASMJIT_INST_3x(vpmaskmovd, Vpmaskmovd, X86Ymm, X86Ymm, X86Mem)              // AVX2
+    3532             :   ASMJIT_INST_3x(vpmaskmovq, Vpmaskmovq, X86Mem, X86Xmm, X86Xmm)              // AVX2
+    3533             :   ASMJIT_INST_3x(vpmaskmovq, Vpmaskmovq, X86Mem, X86Ymm, X86Ymm)              // AVX2
+    3534             :   ASMJIT_INST_3x(vpmaskmovq, Vpmaskmovq, X86Xmm, X86Xmm, X86Mem)              // AVX2
+    3535             :   ASMJIT_INST_3x(vpmaskmovq, Vpmaskmovq, X86Ymm, X86Ymm, X86Mem)              // AVX2
+    3536             :   ASMJIT_INST_3x(vpmaxsb, Vpmaxsb, X86Xmm, X86Xmm, X86Xmm)                    // AVX  AVX512_BW{kz}-VL
+    3537             :   ASMJIT_INST_3x(vpmaxsb, Vpmaxsb, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_BW{kz}-VL
+    3538             :   ASMJIT_INST_3x(vpmaxsb, Vpmaxsb, X86Ymm, X86Ymm, X86Ymm)                    // AVX2 AVX512_BW{kz}-VL
+    3539             :   ASMJIT_INST_3x(vpmaxsb, Vpmaxsb, X86Ymm, X86Ymm, X86Mem)                    // AVX2 AVX512_BW{kz}-VL
+    3540             :   ASMJIT_INST_3x(vpmaxsb, Vpmaxsb, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_BW{kz}
+    3541             :   ASMJIT_INST_3x(vpmaxsb, Vpmaxsb, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_BW{kz}
+    3542             :   ASMJIT_INST_3x(vpmaxsd, Vpmaxsd, X86Xmm, X86Xmm, X86Xmm)                    // AVX  AVX512_F{kz|b32}-VL
+    3543             :   ASMJIT_INST_3x(vpmaxsd, Vpmaxsd, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_F{kz|b32}-VL
+    3544             :   ASMJIT_INST_3x(vpmaxsd, Vpmaxsd, X86Ymm, X86Ymm, X86Ymm)                    // AVX2 AVX512_F{kz|b32}-VL
+    3545             :   ASMJIT_INST_3x(vpmaxsd, Vpmaxsd, X86Ymm, X86Ymm, X86Mem)                    // AVX2 AVX512_F{kz|b32}-VL
+    3546             :   ASMJIT_INST_3x(vpmaxsd, Vpmaxsd, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_F{kz|b32}
+    3547             :   ASMJIT_INST_3x(vpmaxsd, Vpmaxsd, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_F{kz|b32}
+    3548             :   ASMJIT_INST_3x(vpmaxsq, Vpmaxsq, X86Xmm, X86Xmm, X86Xmm)                    //      AVX512_F{kz|b64}-VL
+    3549             :   ASMJIT_INST_3x(vpmaxsq, Vpmaxsq, X86Xmm, X86Xmm, X86Mem)                    //      AVX512_F{kz|b64}-VL
+    3550             :   ASMJIT_INST_3x(vpmaxsq, Vpmaxsq, X86Ymm, X86Ymm, X86Ymm)                    //      AVX512_F{kz|b64}-VL
+    3551             :   ASMJIT_INST_3x(vpmaxsq, Vpmaxsq, X86Ymm, X86Ymm, X86Mem)                    //      AVX512_F{kz|b64}-VL
+    3552             :   ASMJIT_INST_3x(vpmaxsq, Vpmaxsq, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_F{kz|b64}
+    3553             :   ASMJIT_INST_3x(vpmaxsq, Vpmaxsq, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_F{kz|b64}
+    3554             :   ASMJIT_INST_3x(vpmaxsw, Vpmaxsw, X86Xmm, X86Xmm, X86Xmm)                    // AVX  AVX512_BW{kz}-VL
+    3555             :   ASMJIT_INST_3x(vpmaxsw, Vpmaxsw, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_BW{kz}-VL
+    3556             :   ASMJIT_INST_3x(vpmaxsw, Vpmaxsw, X86Ymm, X86Ymm, X86Ymm)                    // AVX2 AVX512_BW{kz}-VL
+    3557             :   ASMJIT_INST_3x(vpmaxsw, Vpmaxsw, X86Ymm, X86Ymm, X86Mem)                    // AVX2 AVX512_BW{kz}-VL
+    3558             :   ASMJIT_INST_3x(vpmaxsw, Vpmaxsw, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_BW{kz}
+    3559             :   ASMJIT_INST_3x(vpmaxsw, Vpmaxsw, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_BW{kz}
+    3560             :   ASMJIT_INST_3x(vpmaxub, Vpmaxub, X86Xmm, X86Xmm, X86Xmm)                    // AVX  AVX512_BW{kz}-VL
+    3561             :   ASMJIT_INST_3x(vpmaxub, Vpmaxub, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_BW{kz}-VL
+    3562             :   ASMJIT_INST_3x(vpmaxub, Vpmaxub, X86Ymm, X86Ymm, X86Ymm)                    // AVX2 AVX512_BW{kz}-VL
+    3563             :   ASMJIT_INST_3x(vpmaxub, Vpmaxub, X86Ymm, X86Ymm, X86Mem)                    // AVX2 AVX512_BW{kz}-VL
+    3564             :   ASMJIT_INST_3x(vpmaxub, Vpmaxub, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_BW{kz}
+    3565             :   ASMJIT_INST_3x(vpmaxub, Vpmaxub, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_BW{kz}
+    3566             :   ASMJIT_INST_3x(vpmaxud, Vpmaxud, X86Xmm, X86Xmm, X86Xmm)                    // AVX  AVX512_F{kz|b32}-VL
+    3567             :   ASMJIT_INST_3x(vpmaxud, Vpmaxud, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_F{kz|b32}-VL
+    3568             :   ASMJIT_INST_3x(vpmaxud, Vpmaxud, X86Ymm, X86Ymm, X86Ymm)                    // AVX2 AVX512_F{kz|b32}-VL
+    3569             :   ASMJIT_INST_3x(vpmaxud, Vpmaxud, X86Ymm, X86Ymm, X86Mem)                    // AVX2 AVX512_F{kz|b32}-VL
+    3570             :   ASMJIT_INST_3x(vpmaxud, Vpmaxud, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_F{kz|b32}
+    3571             :   ASMJIT_INST_3x(vpmaxud, Vpmaxud, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_F{kz|b32}
+    3572             :   ASMJIT_INST_3x(vpmaxuq, Vpmaxuq, X86Xmm, X86Xmm, X86Xmm)                    //      AVX512_F{kz|b64}-VL
+    3573             :   ASMJIT_INST_3x(vpmaxuq, Vpmaxuq, X86Xmm, X86Xmm, X86Mem)                    //      AVX512_F{kz|b64}-VL
+    3574             :   ASMJIT_INST_3x(vpmaxuq, Vpmaxuq, X86Ymm, X86Ymm, X86Ymm)                    //      AVX512_F{kz|b64}-VL
+    3575             :   ASMJIT_INST_3x(vpmaxuq, Vpmaxuq, X86Ymm, X86Ymm, X86Mem)                    //      AVX512_F{kz|b64}-VL
+    3576             :   ASMJIT_INST_3x(vpmaxuq, Vpmaxuq, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_F{kz|b64}
+    3577             :   ASMJIT_INST_3x(vpmaxuq, Vpmaxuq, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_F{kz|b64}
+    3578             :   ASMJIT_INST_3x(vpmaxuw, Vpmaxuw, X86Xmm, X86Xmm, X86Xmm)                    // AVX  AVX512_BW{kz}-VL
+    3579             :   ASMJIT_INST_3x(vpmaxuw, Vpmaxuw, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_BW{kz}-VL
+    3580             :   ASMJIT_INST_3x(vpmaxuw, Vpmaxuw, X86Ymm, X86Ymm, X86Ymm)                    // AVX2 AVX512_BW{kz}-VL
+    3581             :   ASMJIT_INST_3x(vpmaxuw, Vpmaxuw, X86Ymm, X86Ymm, X86Mem)                    // AVX2 AVX512_BW{kz}-VL
+    3582             :   ASMJIT_INST_3x(vpmaxuw, Vpmaxuw, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_BW{kz}
+    3583             :   ASMJIT_INST_3x(vpmaxuw, Vpmaxuw, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_BW{kz}
+    3584             :   ASMJIT_INST_3x(vpminsb, Vpminsb, X86Xmm, X86Xmm, X86Xmm)                    // AVX  AVX512_BW{kz}-VL
+    3585             :   ASMJIT_INST_3x(vpminsb, Vpminsb, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_BW{kz}-VL
+    3586             :   ASMJIT_INST_3x(vpminsb, Vpminsb, X86Ymm, X86Ymm, X86Ymm)                    // AVX2 AVX512_BW{kz}-VL
+    3587             :   ASMJIT_INST_3x(vpminsb, Vpminsb, X86Ymm, X86Ymm, X86Mem)                    // AVX2 AVX512_BW{kz}-VL
+    3588             :   ASMJIT_INST_3x(vpminsb, Vpminsb, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_BW{kz}
+    3589             :   ASMJIT_INST_3x(vpminsb, Vpminsb, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_BW{kz}
+    3590             :   ASMJIT_INST_3x(vpminsd, Vpminsd, X86Xmm, X86Xmm, X86Xmm)                    // AVX  AVX512_F{kz|b32}-VL
+    3591             :   ASMJIT_INST_3x(vpminsd, Vpminsd, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_F{kz|b32}-VL
+    3592             :   ASMJIT_INST_3x(vpminsd, Vpminsd, X86Ymm, X86Ymm, X86Ymm)                    // AVX2 AVX512_F{kz|b32}-VL
+    3593             :   ASMJIT_INST_3x(vpminsd, Vpminsd, X86Ymm, X86Ymm, X86Mem)                    // AVX2 AVX512_F{kz|b32}-VL
+    3594             :   ASMJIT_INST_3x(vpminsd, Vpminsd, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_F{kz|b32}
+    3595             :   ASMJIT_INST_3x(vpminsd, Vpminsd, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_F{kz|b32}
+    3596             :   ASMJIT_INST_3x(vpminsq, Vpminsq, X86Xmm, X86Xmm, X86Xmm)                    //      AVX512_F{kz|b64}-VL
+    3597             :   ASMJIT_INST_3x(vpminsq, Vpminsq, X86Xmm, X86Xmm, X86Mem)                    //      AVX512_F{kz|b64}-VL
+    3598             :   ASMJIT_INST_3x(vpminsq, Vpminsq, X86Ymm, X86Ymm, X86Ymm)                    //      AVX512_F{kz|b64}-VL
+    3599             :   ASMJIT_INST_3x(vpminsq, Vpminsq, X86Ymm, X86Ymm, X86Mem)                    //      AVX512_F{kz|b64}-VL
+    3600             :   ASMJIT_INST_3x(vpminsq, Vpminsq, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_F{kz|b64}
+    3601             :   ASMJIT_INST_3x(vpminsq, Vpminsq, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_F{kz|b64}
+    3602             :   ASMJIT_INST_3x(vpminsw, Vpminsw, X86Xmm, X86Xmm, X86Xmm)                    // AVX  AVX512_BW{kz}-VL
+    3603             :   ASMJIT_INST_3x(vpminsw, Vpminsw, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_BW{kz}-VL
+    3604             :   ASMJIT_INST_3x(vpminsw, Vpminsw, X86Ymm, X86Ymm, X86Ymm)                    // AVX2 AVX512_BW{kz}-VL
+    3605             :   ASMJIT_INST_3x(vpminsw, Vpminsw, X86Ymm, X86Ymm, X86Mem)                    // AVX2 AVX512_BW{kz}-VL
+    3606             :   ASMJIT_INST_3x(vpminsw, Vpminsw, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_BW{kz}
+    3607             :   ASMJIT_INST_3x(vpminsw, Vpminsw, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_BW{kz}
+    3608             :   ASMJIT_INST_3x(vpminub, Vpminub, X86Xmm, X86Xmm, X86Xmm)                    // AVX  AVX512_BW{kz}-VL
+    3609             :   ASMJIT_INST_3x(vpminub, Vpminub, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_BW{kz}-VL
+    3610             :   ASMJIT_INST_3x(vpminub, Vpminub, X86Ymm, X86Ymm, X86Ymm)                    // AVX2 AVX512_BW{kz}-VL
+    3611             :   ASMJIT_INST_3x(vpminub, Vpminub, X86Ymm, X86Ymm, X86Mem)                    // AVX2 AVX512_BW{kz}-VL
+    3612             :   ASMJIT_INST_3x(vpminub, Vpminub, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_BW{kz}
+    3613             :   ASMJIT_INST_3x(vpminub, Vpminub, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_BW{kz}
+    3614             :   ASMJIT_INST_3x(vpminud, Vpminud, X86Xmm, X86Xmm, X86Xmm)                    // AVX  AVX512_F{kz|b32}-VL
+    3615             :   ASMJIT_INST_3x(vpminud, Vpminud, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_F{kz|b32}-VL
+    3616             :   ASMJIT_INST_3x(vpminud, Vpminud, X86Ymm, X86Ymm, X86Ymm)                    // AVX2 AVX512_F{kz|b32}-VL
+    3617             :   ASMJIT_INST_3x(vpminud, Vpminud, X86Ymm, X86Ymm, X86Mem)                    // AVX2 AVX512_F{kz|b32}-VL
+    3618             :   ASMJIT_INST_3x(vpminud, Vpminud, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_F{kz|b32}
+    3619             :   ASMJIT_INST_3x(vpminud, Vpminud, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_F{kz|b32}
+    3620             :   ASMJIT_INST_3x(vpminuq, Vpminuq, X86Xmm, X86Xmm, X86Xmm)                    //      AVX512_F{kz|b64}-VL
+    3621             :   ASMJIT_INST_3x(vpminuq, Vpminuq, X86Xmm, X86Xmm, X86Mem)                    //      AVX512_F{kz|b64}-VL
+    3622             :   ASMJIT_INST_3x(vpminuq, Vpminuq, X86Ymm, X86Ymm, X86Ymm)                    //      AVX512_F{kz|b64}-VL
+    3623             :   ASMJIT_INST_3x(vpminuq, Vpminuq, X86Ymm, X86Ymm, X86Mem)                    //      AVX512_F{kz|b64}-VL
+    3624             :   ASMJIT_INST_3x(vpminuq, Vpminuq, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_F{kz|b64}
+    3625             :   ASMJIT_INST_3x(vpminuq, Vpminuq, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_F{kz|b64}
+    3626             :   ASMJIT_INST_3x(vpminuw, Vpminuw, X86Xmm, X86Xmm, X86Xmm)                    // AVX  AVX512_BW{kz}-VL
+    3627             :   ASMJIT_INST_3x(vpminuw, Vpminuw, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_BW{kz}-VL
+    3628             :   ASMJIT_INST_3x(vpminuw, Vpminuw, X86Ymm, X86Ymm, X86Ymm)                    // AVX2 AVX512_BW{kz}-VL
+    3629             :   ASMJIT_INST_3x(vpminuw, Vpminuw, X86Ymm, X86Ymm, X86Mem)                    // AVX2 AVX512_BW{kz}-VL
+    3630             :   ASMJIT_INST_3x(vpminuw, Vpminuw, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_BW{kz}
+    3631             :   ASMJIT_INST_3x(vpminuw, Vpminuw, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_BW{kz}
+    3632             :   ASMJIT_INST_2x(vpmovb2m, Vpmovb2m, X86KReg, X86Xmm)                         //      AVX512_BW-VL
+    3633             :   ASMJIT_INST_2x(vpmovb2m, Vpmovb2m, X86KReg, X86Ymm)                         //      AVX512_BW-VL
+    3634             :   ASMJIT_INST_2x(vpmovb2m, Vpmovb2m, X86KReg, X86Zmm)                         //      AVX512_BW
+    3635             :   ASMJIT_INST_2x(vpmovd2m, Vpmovd2m, X86KReg, X86Xmm)                         //      AVX512_DQ-VL
+    3636             :   ASMJIT_INST_2x(vpmovd2m, Vpmovd2m, X86KReg, X86Ymm)                         //      AVX512_DQ-VL
+    3637             :   ASMJIT_INST_2x(vpmovd2m, Vpmovd2m, X86KReg, X86Zmm)                         //      AVX512_DQ
+    3638             :   ASMJIT_INST_2x(vpmovdb, Vpmovdb, X86Xmm, X86Xmm)                            //      AVX512_F{kz}-VL
+    3639             :   ASMJIT_INST_2x(vpmovdb, Vpmovdb, X86Mem, X86Xmm)                            //      AVX512_F{kz}-VL
+    3640             :   ASMJIT_INST_2x(vpmovdb, Vpmovdb, X86Xmm, X86Ymm)                            //      AVX512_F{kz}-VL
+    3641             :   ASMJIT_INST_2x(vpmovdb, Vpmovdb, X86Mem, X86Ymm)                            //      AVX512_F{kz}-VL
+    3642             :   ASMJIT_INST_2x(vpmovdb, Vpmovdb, X86Xmm, X86Zmm)                            //      AVX512_F{kz}
+    3643             :   ASMJIT_INST_2x(vpmovdb, Vpmovdb, X86Mem, X86Zmm)                            //      AVX512_F{kz}
+    3644             :   ASMJIT_INST_2x(vpmovdw, Vpmovdw, X86Xmm, X86Xmm)                            //      AVX512_F{kz}-VL
+    3645             :   ASMJIT_INST_2x(vpmovdw, Vpmovdw, X86Mem, X86Xmm)                            //      AVX512_F{kz}-VL
+    3646             :   ASMJIT_INST_2x(vpmovdw, Vpmovdw, X86Xmm, X86Ymm)                            //      AVX512_F{kz}-VL
+    3647             :   ASMJIT_INST_2x(vpmovdw, Vpmovdw, X86Mem, X86Ymm)                            //      AVX512_F{kz}-VL
+    3648             :   ASMJIT_INST_2x(vpmovdw, Vpmovdw, X86Ymm, X86Zmm)                            //      AVX512_F{kz}
+    3649             :   ASMJIT_INST_2x(vpmovdw, Vpmovdw, X86Mem, X86Zmm)                            //      AVX512_F{kz}
+    3650             :   ASMJIT_INST_2x(vpmovm2b, Vpmovm2b, X86Xmm, X86KReg)                         //      AVX512_BW-VL
+    3651             :   ASMJIT_INST_2x(vpmovm2b, Vpmovm2b, X86Ymm, X86KReg)                         //      AVX512_BW-VL
+    3652             :   ASMJIT_INST_2x(vpmovm2b, Vpmovm2b, X86Zmm, X86KReg)                         //      AVX512_BW
+    3653             :   ASMJIT_INST_2x(vpmovm2d, Vpmovm2d, X86Xmm, X86KReg)                         //      AVX512_DQ-VL
+    3654             :   ASMJIT_INST_2x(vpmovm2d, Vpmovm2d, X86Ymm, X86KReg)                         //      AVX512_DQ-VL
+    3655             :   ASMJIT_INST_2x(vpmovm2d, Vpmovm2d, X86Zmm, X86KReg)                         //      AVX512_DQ
+    3656             :   ASMJIT_INST_2x(vpmovm2q, Vpmovm2q, X86Xmm, X86KReg)                         //      AVX512_DQ-VL
+    3657             :   ASMJIT_INST_2x(vpmovm2q, Vpmovm2q, X86Ymm, X86KReg)                         //      AVX512_DQ-VL
+    3658             :   ASMJIT_INST_2x(vpmovm2q, Vpmovm2q, X86Zmm, X86KReg)                         //      AVX512_DQ
+    3659             :   ASMJIT_INST_2x(vpmovm2w, Vpmovm2w, X86Xmm, X86KReg)                         //      AVX512_BW-VL
+    3660             :   ASMJIT_INST_2x(vpmovm2w, Vpmovm2w, X86Ymm, X86KReg)                         //      AVX512_BW-VL
+    3661             :   ASMJIT_INST_2x(vpmovm2w, Vpmovm2w, X86Zmm, X86KReg)                         //      AVX512_BW
+    3662             :   ASMJIT_INST_2x(vpmovmskb, Vpmovmskb, X86Gp, X86Xmm)                         // AVX
+    3663             :   ASMJIT_INST_2x(vpmovmskb, Vpmovmskb, X86Gp, X86Ymm)                         // AVX2
+    3664             :   ASMJIT_INST_2x(vpmovq2m, Vpmovq2m, X86KReg, X86Xmm)                         //      AVX512_DQ-VL
+    3665             :   ASMJIT_INST_2x(vpmovq2m, Vpmovq2m, X86KReg, X86Ymm)                         //      AVX512_DQ-VL
+    3666             :   ASMJIT_INST_2x(vpmovq2m, Vpmovq2m, X86KReg, X86Zmm)                         //      AVX512_DQ
+    3667             :   ASMJIT_INST_2x(vpmovqb, Vpmovqb, X86Xmm, X86Xmm)                            //      AVX512_F{kz}-VL
+    3668             :   ASMJIT_INST_2x(vpmovqb, Vpmovqb, X86Mem, X86Xmm)                            //      AVX512_F{kz}-VL
+    3669             :   ASMJIT_INST_2x(vpmovqb, Vpmovqb, X86Xmm, X86Ymm)                            //      AVX512_F{kz}-VL
+    3670             :   ASMJIT_INST_2x(vpmovqb, Vpmovqb, X86Mem, X86Ymm)                            //      AVX512_F{kz}-VL
+    3671             :   ASMJIT_INST_2x(vpmovqb, Vpmovqb, X86Xmm, X86Zmm)                            //      AVX512_F{kz}
+    3672             :   ASMJIT_INST_2x(vpmovqb, Vpmovqb, X86Mem, X86Zmm)                            //      AVX512_F{kz}
+    3673             :   ASMJIT_INST_2x(vpmovqd, Vpmovqd, X86Xmm, X86Xmm)                            //      AVX512_F{kz}-VL
+    3674             :   ASMJIT_INST_2x(vpmovqd, Vpmovqd, X86Mem, X86Xmm)                            //      AVX512_F{kz}-VL
+    3675             :   ASMJIT_INST_2x(vpmovqd, Vpmovqd, X86Xmm, X86Ymm)                            //      AVX512_F{kz}-VL
+    3676             :   ASMJIT_INST_2x(vpmovqd, Vpmovqd, X86Mem, X86Ymm)                            //      AVX512_F{kz}-VL
+    3677             :   ASMJIT_INST_2x(vpmovqd, Vpmovqd, X86Ymm, X86Zmm)                            //      AVX512_F{kz}
+    3678             :   ASMJIT_INST_2x(vpmovqd, Vpmovqd, X86Mem, X86Zmm)                            //      AVX512_F{kz}
+    3679             :   ASMJIT_INST_2x(vpmovqw, Vpmovqw, X86Xmm, X86Xmm)                            //      AVX512_F{kz}-VL
+    3680             :   ASMJIT_INST_2x(vpmovqw, Vpmovqw, X86Mem, X86Xmm)                            //      AVX512_F{kz}-VL
+    3681             :   ASMJIT_INST_2x(vpmovqw, Vpmovqw, X86Xmm, X86Ymm)                            //      AVX512_F{kz}-VL
+    3682             :   ASMJIT_INST_2x(vpmovqw, Vpmovqw, X86Mem, X86Ymm)                            //      AVX512_F{kz}-VL
+    3683             :   ASMJIT_INST_2x(vpmovqw, Vpmovqw, X86Xmm, X86Zmm)                            //      AVX512_F{kz}
+    3684             :   ASMJIT_INST_2x(vpmovqw, Vpmovqw, X86Mem, X86Zmm)                            //      AVX512_F{kz}
+    3685             :   ASMJIT_INST_2x(vpmovsdb, Vpmovsdb, X86Xmm, X86Xmm)                          //      AVX512_F{kz}-VL
+    3686             :   ASMJIT_INST_2x(vpmovsdb, Vpmovsdb, X86Mem, X86Xmm)                          //      AVX512_F{kz}-VL
+    3687             :   ASMJIT_INST_2x(vpmovsdb, Vpmovsdb, X86Xmm, X86Ymm)                          //      AVX512_F{kz}-VL
+    3688             :   ASMJIT_INST_2x(vpmovsdb, Vpmovsdb, X86Mem, X86Ymm)                          //      AVX512_F{kz}-VL
+    3689             :   ASMJIT_INST_2x(vpmovsdb, Vpmovsdb, X86Xmm, X86Zmm)                          //      AVX512_F{kz}
+    3690             :   ASMJIT_INST_2x(vpmovsdb, Vpmovsdb, X86Mem, X86Zmm)                          //      AVX512_F{kz}
+    3691             :   ASMJIT_INST_2x(vpmovsdw, Vpmovsdw, X86Xmm, X86Xmm)                          //      AVX512_F{kz}-VL
+    3692             :   ASMJIT_INST_2x(vpmovsdw, Vpmovsdw, X86Mem, X86Xmm)                          //      AVX512_F{kz}-VL
+    3693             :   ASMJIT_INST_2x(vpmovsdw, Vpmovsdw, X86Xmm, X86Ymm)                          //      AVX512_F{kz}-VL
+    3694             :   ASMJIT_INST_2x(vpmovsdw, Vpmovsdw, X86Mem, X86Ymm)                          //      AVX512_F{kz}-VL
+    3695             :   ASMJIT_INST_2x(vpmovsdw, Vpmovsdw, X86Ymm, X86Zmm)                          //      AVX512_F{kz}
+    3696             :   ASMJIT_INST_2x(vpmovsdw, Vpmovsdw, X86Mem, X86Zmm)                          //      AVX512_F{kz}
+    3697             :   ASMJIT_INST_2x(vpmovsqb, Vpmovsqb, X86Xmm, X86Xmm)                          //      AVX512_F{kz}-VL
+    3698             :   ASMJIT_INST_2x(vpmovsqb, Vpmovsqb, X86Mem, X86Xmm)                          //      AVX512_F{kz}-VL
+    3699             :   ASMJIT_INST_2x(vpmovsqb, Vpmovsqb, X86Xmm, X86Ymm)                          //      AVX512_F{kz}-VL
+    3700             :   ASMJIT_INST_2x(vpmovsqb, Vpmovsqb, X86Mem, X86Ymm)                          //      AVX512_F{kz}-VL
+    3701             :   ASMJIT_INST_2x(vpmovsqb, Vpmovsqb, X86Xmm, X86Zmm)                          //      AVX512_F{kz}
+    3702             :   ASMJIT_INST_2x(vpmovsqb, Vpmovsqb, X86Mem, X86Zmm)                          //      AVX512_F{kz}
+    3703             :   ASMJIT_INST_2x(vpmovsqd, Vpmovsqd, X86Xmm, X86Xmm)                          //      AVX512_F{kz}-VL
+    3704             :   ASMJIT_INST_2x(vpmovsqd, Vpmovsqd, X86Mem, X86Xmm)                          //      AVX512_F{kz}-VL
+    3705             :   ASMJIT_INST_2x(vpmovsqd, Vpmovsqd, X86Xmm, X86Ymm)                          //      AVX512_F{kz}-VL
+    3706             :   ASMJIT_INST_2x(vpmovsqd, Vpmovsqd, X86Mem, X86Ymm)                          //      AVX512_F{kz}-VL
+    3707             :   ASMJIT_INST_2x(vpmovsqd, Vpmovsqd, X86Ymm, X86Zmm)                          //      AVX512_F{kz}
+    3708             :   ASMJIT_INST_2x(vpmovsqd, Vpmovsqd, X86Mem, X86Zmm)                          //      AVX512_F{kz}
+    3709             :   ASMJIT_INST_2x(vpmovsqw, Vpmovsqw, X86Xmm, X86Xmm)                          //      AVX512_F{kz}-VL
+    3710             :   ASMJIT_INST_2x(vpmovsqw, Vpmovsqw, X86Mem, X86Xmm)                          //      AVX512_F{kz}-VL
+    3711             :   ASMJIT_INST_2x(vpmovsqw, Vpmovsqw, X86Xmm, X86Ymm)                          //      AVX512_F{kz}-VL
+    3712             :   ASMJIT_INST_2x(vpmovsqw, Vpmovsqw, X86Mem, X86Ymm)                          //      AVX512_F{kz}-VL
+    3713             :   ASMJIT_INST_2x(vpmovsqw, Vpmovsqw, X86Xmm, X86Zmm)                          //      AVX512_F{kz}
+    3714             :   ASMJIT_INST_2x(vpmovsqw, Vpmovsqw, X86Mem, X86Zmm)                          //      AVX512_F{kz}
+    3715             :   ASMJIT_INST_2x(vpmovswb, Vpmovswb, X86Xmm, X86Xmm)                          //      AVX512_BW{kz}-VL
+    3716             :   ASMJIT_INST_2x(vpmovswb, Vpmovswb, X86Mem, X86Xmm)                          //      AVX512_BW{kz}-VL
+    3717             :   ASMJIT_INST_2x(vpmovswb, Vpmovswb, X86Xmm, X86Ymm)                          //      AVX512_BW{kz}-VL
+    3718             :   ASMJIT_INST_2x(vpmovswb, Vpmovswb, X86Mem, X86Ymm)                          //      AVX512_BW{kz}-VL
+    3719             :   ASMJIT_INST_2x(vpmovswb, Vpmovswb, X86Ymm, X86Zmm)                          //      AVX512_BW{kz}
+    3720             :   ASMJIT_INST_2x(vpmovswb, Vpmovswb, X86Mem, X86Zmm)                          //      AVX512_BW{kz}
+    3721             :   ASMJIT_INST_2x(vpmovsxbd, Vpmovsxbd, X86Xmm, X86Xmm)                        // AVX  AVX512_F{kz}-VL
+    3722             :   ASMJIT_INST_2x(vpmovsxbd, Vpmovsxbd, X86Xmm, X86Mem)                        // AVX  AVX512_F{kz}-VL
+    3723             :   ASMJIT_INST_2x(vpmovsxbd, Vpmovsxbd, X86Ymm, X86Xmm)                        // AVX2 AVX512_F{kz}-VL
+    3724             :   ASMJIT_INST_2x(vpmovsxbd, Vpmovsxbd, X86Ymm, X86Mem)                        // AVX2 AVX512_F{kz}-VL
+    3725             :   ASMJIT_INST_2x(vpmovsxbd, Vpmovsxbd, X86Zmm, X86Xmm)                        //      AVX512_F{kz}
+    3726             :   ASMJIT_INST_2x(vpmovsxbd, Vpmovsxbd, X86Zmm, X86Mem)                        //      AVX512_F{kz}
+    3727             :   ASMJIT_INST_2x(vpmovsxbq, Vpmovsxbq, X86Xmm, X86Xmm)                        // AVX  AVX512_F{kz}-VL
+    3728             :   ASMJIT_INST_2x(vpmovsxbq, Vpmovsxbq, X86Xmm, X86Mem)                        // AVX  AVX512_F{kz}-VL
+    3729             :   ASMJIT_INST_2x(vpmovsxbq, Vpmovsxbq, X86Ymm, X86Xmm)                        // AVX2 AVX512_F{kz}-VL
+    3730             :   ASMJIT_INST_2x(vpmovsxbq, Vpmovsxbq, X86Ymm, X86Mem)                        // AVX2 AVX512_F{kz}-VL
+    3731             :   ASMJIT_INST_2x(vpmovsxbq, Vpmovsxbq, X86Zmm, X86Xmm)                        //      AVX512_F{kz}
+    3732             :   ASMJIT_INST_2x(vpmovsxbq, Vpmovsxbq, X86Zmm, X86Mem)                        //      AVX512_F{kz}
+    3733             :   ASMJIT_INST_2x(vpmovsxbw, Vpmovsxbw, X86Xmm, X86Xmm)                        // AVX  AVX512_BW{kz}-VL
+    3734             :   ASMJIT_INST_2x(vpmovsxbw, Vpmovsxbw, X86Xmm, X86Mem)                        // AVX  AVX512_BW{kz}-VL
+    3735             :   ASMJIT_INST_2x(vpmovsxbw, Vpmovsxbw, X86Ymm, X86Xmm)                        // AVX2 AVX512_BW{kz}-VL
+    3736             :   ASMJIT_INST_2x(vpmovsxbw, Vpmovsxbw, X86Ymm, X86Mem)                        // AVX2 AVX512_BW{kz}-VL
+    3737             :   ASMJIT_INST_2x(vpmovsxbw, Vpmovsxbw, X86Zmm, X86Ymm)                        //      AVX512_BW{kz}
+    3738             :   ASMJIT_INST_2x(vpmovsxbw, Vpmovsxbw, X86Zmm, X86Mem)                        //      AVX512_BW{kz}
+    3739             :   ASMJIT_INST_2x(vpmovsxdq, Vpmovsxdq, X86Xmm, X86Xmm)                        // AVX  AVX512_F{kz}-VL
+    3740             :   ASMJIT_INST_2x(vpmovsxdq, Vpmovsxdq, X86Xmm, X86Mem)                        // AVX  AVX512_F{kz}-VL
+    3741             :   ASMJIT_INST_2x(vpmovsxdq, Vpmovsxdq, X86Ymm, X86Xmm)                        // AVX2 AVX512_F{kz}-VL
+    3742             :   ASMJIT_INST_2x(vpmovsxdq, Vpmovsxdq, X86Ymm, X86Mem)                        // AVX2 AVX512_F{kz}-VL
+    3743             :   ASMJIT_INST_2x(vpmovsxdq, Vpmovsxdq, X86Zmm, X86Xmm)                        //      AVX512_F{kz}
+    3744             :   ASMJIT_INST_2x(vpmovsxdq, Vpmovsxdq, X86Zmm, X86Mem)                        //      AVX512_F{kz}
+    3745             :   ASMJIT_INST_2x(vpmovsxwd, Vpmovsxwd, X86Xmm, X86Xmm)                        // AVX  AVX512_F{kz}-VL
+    3746             :   ASMJIT_INST_2x(vpmovsxwd, Vpmovsxwd, X86Xmm, X86Mem)                        // AVX  AVX512_F{kz}-VL
+    3747             :   ASMJIT_INST_2x(vpmovsxwd, Vpmovsxwd, X86Ymm, X86Xmm)                        // AVX2 AVX512_F{kz}-VL
+    3748             :   ASMJIT_INST_2x(vpmovsxwd, Vpmovsxwd, X86Ymm, X86Mem)                        // AVX2 AVX512_F{kz}-VL
+    3749             :   ASMJIT_INST_2x(vpmovsxwd, Vpmovsxwd, X86Zmm, X86Ymm)                        //      AVX512_F{kz}
+    3750             :   ASMJIT_INST_2x(vpmovsxwd, Vpmovsxwd, X86Zmm, X86Mem)                        //      AVX512_F{kz}
+    3751             :   ASMJIT_INST_2x(vpmovsxwq, Vpmovsxwq, X86Xmm, X86Xmm)                        // AVX  AVX512_F{kz}-VL
+    3752             :   ASMJIT_INST_2x(vpmovsxwq, Vpmovsxwq, X86Xmm, X86Mem)                        // AVX  AVX512_F{kz}-VL
+    3753             :   ASMJIT_INST_2x(vpmovsxwq, Vpmovsxwq, X86Ymm, X86Xmm)                        // AVX2 AVX512_F{kz}-VL
+    3754             :   ASMJIT_INST_2x(vpmovsxwq, Vpmovsxwq, X86Ymm, X86Mem)                        // AVX2 AVX512_F{kz}-VL
+    3755             :   ASMJIT_INST_2x(vpmovsxwq, Vpmovsxwq, X86Zmm, X86Xmm)                        //      AVX512_F{kz}
+    3756             :   ASMJIT_INST_2x(vpmovsxwq, Vpmovsxwq, X86Zmm, X86Mem)                        //      AVX512_F{kz}
+    3757             :   ASMJIT_INST_2x(vpmovusdb, Vpmovusdb, X86Xmm, X86Xmm)                        //      AVX512_F{kz}-VL
+    3758             :   ASMJIT_INST_2x(vpmovusdb, Vpmovusdb, X86Mem, X86Xmm)                        //      AVX512_F{kz}-VL
+    3759             :   ASMJIT_INST_2x(vpmovusdb, Vpmovusdb, X86Xmm, X86Ymm)                        //      AVX512_F{kz}-VL
+    3760             :   ASMJIT_INST_2x(vpmovusdb, Vpmovusdb, X86Mem, X86Ymm)                        //      AVX512_F{kz}-VL
+    3761             :   ASMJIT_INST_2x(vpmovusdb, Vpmovusdb, X86Xmm, X86Zmm)                        //      AVX512_F{kz}
+    3762             :   ASMJIT_INST_2x(vpmovusdb, Vpmovusdb, X86Mem, X86Zmm)                        //      AVX512_F{kz}
+    3763             :   ASMJIT_INST_2x(vpmovusdw, Vpmovusdw, X86Xmm, X86Xmm)                        //      AVX512_F{kz}-VL
+    3764             :   ASMJIT_INST_2x(vpmovusdw, Vpmovusdw, X86Mem, X86Xmm)                        //      AVX512_F{kz}-VL
+    3765             :   ASMJIT_INST_2x(vpmovusdw, Vpmovusdw, X86Xmm, X86Ymm)                        //      AVX512_F{kz}-VL
+    3766             :   ASMJIT_INST_2x(vpmovusdw, Vpmovusdw, X86Mem, X86Ymm)                        //      AVX512_F{kz}-VL
+    3767             :   ASMJIT_INST_2x(vpmovusdw, Vpmovusdw, X86Ymm, X86Zmm)                        //      AVX512_F{kz}
+    3768             :   ASMJIT_INST_2x(vpmovusdw, Vpmovusdw, X86Mem, X86Zmm)                        //      AVX512_F{kz}
+    3769             :   ASMJIT_INST_2x(vpmovusqb, Vpmovusqb, X86Xmm, X86Xmm)                        //      AVX512_F{kz}-VL
+    3770             :   ASMJIT_INST_2x(vpmovusqb, Vpmovusqb, X86Mem, X86Xmm)                        //      AVX512_F{kz}-VL
+    3771             :   ASMJIT_INST_2x(vpmovusqb, Vpmovusqb, X86Xmm, X86Ymm)                        //      AVX512_F{kz}-VL
+    3772             :   ASMJIT_INST_2x(vpmovusqb, Vpmovusqb, X86Mem, X86Ymm)                        //      AVX512_F{kz}-VL
+    3773             :   ASMJIT_INST_2x(vpmovusqb, Vpmovusqb, X86Xmm, X86Zmm)                        //      AVX512_F{kz}
+    3774             :   ASMJIT_INST_2x(vpmovusqb, Vpmovusqb, X86Mem, X86Zmm)                        //      AVX512_F{kz}
+    3775             :   ASMJIT_INST_2x(vpmovusqd, Vpmovusqd, X86Xmm, X86Xmm)                        //      AVX512_F{kz}-VL
+    3776             :   ASMJIT_INST_2x(vpmovusqd, Vpmovusqd, X86Mem, X86Xmm)                        //      AVX512_F{kz}-VL
+    3777             :   ASMJIT_INST_2x(vpmovusqd, Vpmovusqd, X86Xmm, X86Ymm)                        //      AVX512_F{kz}-VL
+    3778             :   ASMJIT_INST_2x(vpmovusqd, Vpmovusqd, X86Mem, X86Ymm)                        //      AVX512_F{kz}-VL
+    3779             :   ASMJIT_INST_2x(vpmovusqd, Vpmovusqd, X86Ymm, X86Zmm)                        //      AVX512_F{kz}
+    3780             :   ASMJIT_INST_2x(vpmovusqd, Vpmovusqd, X86Mem, X86Zmm)                        //      AVX512_F{kz}
+    3781             :   ASMJIT_INST_2x(vpmovusqw, Vpmovusqw, X86Xmm, X86Xmm)                        //      AVX512_F{kz}-VL
+    3782             :   ASMJIT_INST_2x(vpmovusqw, Vpmovusqw, X86Mem, X86Xmm)                        //      AVX512_F{kz}-VL
+    3783             :   ASMJIT_INST_2x(vpmovusqw, Vpmovusqw, X86Xmm, X86Ymm)                        //      AVX512_F{kz}-VL
+    3784             :   ASMJIT_INST_2x(vpmovusqw, Vpmovusqw, X86Mem, X86Ymm)                        //      AVX512_F{kz}-VL
+    3785             :   ASMJIT_INST_2x(vpmovusqw, Vpmovusqw, X86Xmm, X86Zmm)                        //      AVX512_F{kz}
+    3786             :   ASMJIT_INST_2x(vpmovusqw, Vpmovusqw, X86Mem, X86Zmm)                        //      AVX512_F{kz}
+    3787             :   ASMJIT_INST_2x(vpmovuswb, Vpmovuswb, X86Xmm, X86Xmm)                        //      AVX512_BW{kz}-VL
+    3788             :   ASMJIT_INST_2x(vpmovuswb, Vpmovuswb, X86Mem, X86Xmm)                        //      AVX512_BW{kz}-VL
+    3789             :   ASMJIT_INST_2x(vpmovuswb, Vpmovuswb, X86Xmm, X86Ymm)                        //      AVX512_BW{kz}-VL
+    3790             :   ASMJIT_INST_2x(vpmovuswb, Vpmovuswb, X86Mem, X86Ymm)                        //      AVX512_BW{kz}-VL
+    3791             :   ASMJIT_INST_2x(vpmovuswb, Vpmovuswb, X86Ymm, X86Zmm)                        //      AVX512_BW{kz}
+    3792             :   ASMJIT_INST_2x(vpmovuswb, Vpmovuswb, X86Mem, X86Zmm)                        //      AVX512_BW{kz}
+    3793             :   ASMJIT_INST_2x(vpmovw2m, Vpmovw2m, X86KReg, X86Xmm)                         //      AVX512_BW-VL
+    3794             :   ASMJIT_INST_2x(vpmovw2m, Vpmovw2m, X86KReg, X86Ymm)                         //      AVX512_BW-VL
+    3795             :   ASMJIT_INST_2x(vpmovw2m, Vpmovw2m, X86KReg, X86Zmm)                         //      AVX512_BW
+    3796             :   ASMJIT_INST_2x(vpmovwb, Vpmovwb, X86Xmm, X86Xmm)                            //      AVX512_BW{kz}-VL
+    3797             :   ASMJIT_INST_2x(vpmovwb, Vpmovwb, X86Mem, X86Xmm)                            //      AVX512_BW{kz}-VL
+    3798             :   ASMJIT_INST_2x(vpmovwb, Vpmovwb, X86Xmm, X86Ymm)                            //      AVX512_BW{kz}-VL
+    3799             :   ASMJIT_INST_2x(vpmovwb, Vpmovwb, X86Mem, X86Ymm)                            //      AVX512_BW{kz}-VL
+    3800             :   ASMJIT_INST_2x(vpmovwb, Vpmovwb, X86Ymm, X86Zmm)                            //      AVX512_BW{kz}
+    3801             :   ASMJIT_INST_2x(vpmovwb, Vpmovwb, X86Mem, X86Zmm)                            //      AVX512_BW{kz}
+    3802             :   ASMJIT_INST_2x(vpmovzxbd, Vpmovzxbd, X86Xmm, X86Xmm)                        // AVX  AVX512_F{kz}-VL
+    3803             :   ASMJIT_INST_2x(vpmovzxbd, Vpmovzxbd, X86Xmm, X86Mem)                        // AVX  AVX512_F{kz}-VL
+    3804             :   ASMJIT_INST_2x(vpmovzxbd, Vpmovzxbd, X86Ymm, X86Xmm)                        // AVX2 AVX512_F{kz}-VL
+    3805             :   ASMJIT_INST_2x(vpmovzxbd, Vpmovzxbd, X86Ymm, X86Mem)                        // AVX2 AVX512_F{kz}-VL
+    3806             :   ASMJIT_INST_2x(vpmovzxbd, Vpmovzxbd, X86Zmm, X86Xmm)                        //      AVX512_F{kz}
+    3807             :   ASMJIT_INST_2x(vpmovzxbd, Vpmovzxbd, X86Zmm, X86Mem)                        //      AVX512_F{kz}
+    3808             :   ASMJIT_INST_2x(vpmovzxbq, Vpmovzxbq, X86Xmm, X86Xmm)                        // AVX  AVX512_F{kz}-VL
+    3809             :   ASMJIT_INST_2x(vpmovzxbq, Vpmovzxbq, X86Xmm, X86Mem)                        // AVX  AVX512_F{kz}-VL
+    3810             :   ASMJIT_INST_2x(vpmovzxbq, Vpmovzxbq, X86Ymm, X86Xmm)                        // AVX2 AVX512_F{kz}-VL
+    3811             :   ASMJIT_INST_2x(vpmovzxbq, Vpmovzxbq, X86Ymm, X86Mem)                        // AVX2 AVX512_F{kz}-VL
+    3812             :   ASMJIT_INST_2x(vpmovzxbq, Vpmovzxbq, X86Zmm, X86Xmm)                        //      AVX512_F{kz}
+    3813             :   ASMJIT_INST_2x(vpmovzxbq, Vpmovzxbq, X86Zmm, X86Mem)                        //      AVX512_F{kz}
+    3814             :   ASMJIT_INST_2x(vpmovzxbw, Vpmovzxbw, X86Xmm, X86Xmm)                        // AVX  AVX512_BW{kz}-VL
+    3815             :   ASMJIT_INST_2x(vpmovzxbw, Vpmovzxbw, X86Xmm, X86Mem)                        // AVX  AVX512_BW{kz}-VL
+    3816             :   ASMJIT_INST_2x(vpmovzxbw, Vpmovzxbw, X86Ymm, X86Xmm)                        // AVX2 AVX512_BW{kz}-VL
+    3817             :   ASMJIT_INST_2x(vpmovzxbw, Vpmovzxbw, X86Ymm, X86Mem)                        // AVX2 AVX512_BW{kz}-VL
+    3818             :   ASMJIT_INST_2x(vpmovzxbw, Vpmovzxbw, X86Zmm, X86Ymm)                        //      AVX512_BW{kz}
+    3819             :   ASMJIT_INST_2x(vpmovzxbw, Vpmovzxbw, X86Zmm, X86Mem)                        //      AVX512_BW{kz}
+    3820             :   ASMJIT_INST_2x(vpmovzxdq, Vpmovzxdq, X86Xmm, X86Xmm)                        // AVX  AVX512_F{kz}-VL
+    3821             :   ASMJIT_INST_2x(vpmovzxdq, Vpmovzxdq, X86Xmm, X86Mem)                        // AVX  AVX512_F{kz}-VL
+    3822             :   ASMJIT_INST_2x(vpmovzxdq, Vpmovzxdq, X86Ymm, X86Xmm)                        // AVX2 AVX512_F{kz}-VL
+    3823             :   ASMJIT_INST_2x(vpmovzxdq, Vpmovzxdq, X86Ymm, X86Mem)                        // AVX2 AVX512_F{kz}-VL
+    3824             :   ASMJIT_INST_2x(vpmovzxdq, Vpmovzxdq, X86Zmm, X86Xmm)                        //      AVX512_F{kz}
+    3825             :   ASMJIT_INST_2x(vpmovzxdq, Vpmovzxdq, X86Zmm, X86Mem)                        //      AVX512_F{kz}
+    3826             :   ASMJIT_INST_2x(vpmovzxwd, Vpmovzxwd, X86Xmm, X86Xmm)                        // AVX  AVX512_F{kz}-VL
+    3827             :   ASMJIT_INST_2x(vpmovzxwd, Vpmovzxwd, X86Xmm, X86Mem)                        // AVX  AVX512_F{kz}-VL
+    3828             :   ASMJIT_INST_2x(vpmovzxwd, Vpmovzxwd, X86Ymm, X86Xmm)                        // AVX2 AVX512_F{kz}-VL
+    3829             :   ASMJIT_INST_2x(vpmovzxwd, Vpmovzxwd, X86Ymm, X86Mem)                        // AVX2 AVX512_F{kz}-VL
+    3830             :   ASMJIT_INST_2x(vpmovzxwd, Vpmovzxwd, X86Zmm, X86Ymm)                        //      AVX512_F{kz}
+    3831             :   ASMJIT_INST_2x(vpmovzxwd, Vpmovzxwd, X86Zmm, X86Mem)                        //      AVX512_F{kz}
+    3832             :   ASMJIT_INST_2x(vpmovzxwq, Vpmovzxwq, X86Xmm, X86Xmm)                        // AVX  AVX512_F{kz}-VL
+    3833             :   ASMJIT_INST_2x(vpmovzxwq, Vpmovzxwq, X86Xmm, X86Mem)                        // AVX  AVX512_F{kz}-VL
+    3834             :   ASMJIT_INST_2x(vpmovzxwq, Vpmovzxwq, X86Ymm, X86Xmm)                        // AVX2 AVX512_F{kz}-VL
+    3835             :   ASMJIT_INST_2x(vpmovzxwq, Vpmovzxwq, X86Ymm, X86Mem)                        // AVX2 AVX512_F{kz}-VL
+    3836             :   ASMJIT_INST_2x(vpmovzxwq, Vpmovzxwq, X86Zmm, X86Xmm)                        //      AVX512_F{kz}
+    3837             :   ASMJIT_INST_2x(vpmovzxwq, Vpmovzxwq, X86Zmm, X86Mem)                        //      AVX512_F{kz}
+    3838             :   ASMJIT_INST_3x(vpmuldq, Vpmuldq, X86Xmm, X86Xmm, X86Xmm)                    // AVX  AVX512_F{kz|b64}-VL
+    3839             :   ASMJIT_INST_3x(vpmuldq, Vpmuldq, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_F{kz|b64}-VL
+    3840             :   ASMJIT_INST_3x(vpmuldq, Vpmuldq, X86Ymm, X86Ymm, X86Ymm)                    // AVX2 AVX512_F{kz|b64}-VL
+    3841             :   ASMJIT_INST_3x(vpmuldq, Vpmuldq, X86Ymm, X86Ymm, X86Mem)                    // AVX2 AVX512_F{kz|b64}-VL
+    3842             :   ASMJIT_INST_3x(vpmuldq, Vpmuldq, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_F{kz|b64}
+    3843             :   ASMJIT_INST_3x(vpmuldq, Vpmuldq, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_F{kz|b64}
+    3844             :   ASMJIT_INST_3x(vpmulhrsw, Vpmulhrsw, X86Xmm, X86Xmm, X86Xmm)                // AVX  AVX512_BW{kz}-VL
+    3845             :   ASMJIT_INST_3x(vpmulhrsw, Vpmulhrsw, X86Xmm, X86Xmm, X86Mem)                // AVX  AVX512_BW{kz}-VL
+    3846             :   ASMJIT_INST_3x(vpmulhrsw, Vpmulhrsw, X86Ymm, X86Ymm, X86Ymm)                // AVX2 AVX512_BW{kz}-VL
+    3847             :   ASMJIT_INST_3x(vpmulhrsw, Vpmulhrsw, X86Ymm, X86Ymm, X86Mem)                // AVX2 AVX512_BW{kz}-VL
+    3848             :   ASMJIT_INST_3x(vpmulhrsw, Vpmulhrsw, X86Zmm, X86Zmm, X86Zmm)                //      AVX512_BW{kz}
+    3849             :   ASMJIT_INST_3x(vpmulhrsw, Vpmulhrsw, X86Zmm, X86Zmm, X86Mem)                //      AVX512_BW{kz}
+    3850             :   ASMJIT_INST_3x(vpmulhuw, Vpmulhuw, X86Xmm, X86Xmm, X86Xmm)                  // AVX  AVX512_BW{kz}-VL
+    3851             :   ASMJIT_INST_3x(vpmulhuw, Vpmulhuw, X86Xmm, X86Xmm, X86Mem)                  // AVX  AVX512_BW{kz}-VL
+    3852             :   ASMJIT_INST_3x(vpmulhuw, Vpmulhuw, X86Ymm, X86Ymm, X86Ymm)                  // AVX2 AVX512_BW{kz}-VL
+    3853             :   ASMJIT_INST_3x(vpmulhuw, Vpmulhuw, X86Ymm, X86Ymm, X86Mem)                  // AVX2 AVX512_BW{kz}-VL
+    3854             :   ASMJIT_INST_3x(vpmulhuw, Vpmulhuw, X86Zmm, X86Zmm, X86Zmm)                  //      AVX512_BW{kz}
+    3855             :   ASMJIT_INST_3x(vpmulhuw, Vpmulhuw, X86Zmm, X86Zmm, X86Mem)                  //      AVX512_BW{kz}
+    3856             :   ASMJIT_INST_3x(vpmulhw, Vpmulhw, X86Xmm, X86Xmm, X86Xmm)                    // AVX  AVX512_BW{kz}-VL
+    3857             :   ASMJIT_INST_3x(vpmulhw, Vpmulhw, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_BW{kz}-VL
+    3858             :   ASMJIT_INST_3x(vpmulhw, Vpmulhw, X86Ymm, X86Ymm, X86Ymm)                    // AVX2 AVX512_BW{kz}-VL
+    3859             :   ASMJIT_INST_3x(vpmulhw, Vpmulhw, X86Ymm, X86Ymm, X86Mem)                    // AVX2 AVX512_BW{kz}-VL
+    3860             :   ASMJIT_INST_3x(vpmulhw, Vpmulhw, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_BW{kz}
+    3861             :   ASMJIT_INST_3x(vpmulhw, Vpmulhw, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_BW{kz}
+    3862             :   ASMJIT_INST_3x(vpmulld, Vpmulld, X86Xmm, X86Xmm, X86Xmm)                    // AVX  AVX512_F{kz|b32}-VL
+    3863             :   ASMJIT_INST_3x(vpmulld, Vpmulld, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_F{kz|b32}-VL
+    3864             :   ASMJIT_INST_3x(vpmulld, Vpmulld, X86Ymm, X86Ymm, X86Ymm)                    // AVX2 AVX512_F{kz|b32}-VL
+    3865             :   ASMJIT_INST_3x(vpmulld, Vpmulld, X86Ymm, X86Ymm, X86Mem)                    // AVX2 AVX512_F{kz|b32}-VL
+    3866             :   ASMJIT_INST_3x(vpmulld, Vpmulld, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_F{kz|b32}
+    3867             :   ASMJIT_INST_3x(vpmulld, Vpmulld, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_F{kz|b32}
+    3868             :   ASMJIT_INST_3x(vpmullq, Vpmullq, X86Xmm, X86Xmm, X86Xmm)                    //      AVX512_DQ{kz|b64}-VL
+    3869             :   ASMJIT_INST_3x(vpmullq, Vpmullq, X86Xmm, X86Xmm, X86Mem)                    //      AVX512_DQ{kz|b64}-VL
+    3870             :   ASMJIT_INST_3x(vpmullq, Vpmullq, X86Ymm, X86Ymm, X86Ymm)                    //      AVX512_DQ{kz|b64}-VL
+    3871             :   ASMJIT_INST_3x(vpmullq, Vpmullq, X86Ymm, X86Ymm, X86Mem)                    //      AVX512_DQ{kz|b64}-VL
+    3872             :   ASMJIT_INST_3x(vpmullq, Vpmullq, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_DQ{kz|b64}
+    3873             :   ASMJIT_INST_3x(vpmullq, Vpmullq, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_DQ{kz|b64}
+    3874             :   ASMJIT_INST_3x(vpmullw, Vpmullw, X86Xmm, X86Xmm, X86Xmm)                    // AVX  AVX512_BW{kz}-VL
+    3875             :   ASMJIT_INST_3x(vpmullw, Vpmullw, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_BW{kz}-VL
+    3876             :   ASMJIT_INST_3x(vpmullw, Vpmullw, X86Ymm, X86Ymm, X86Ymm)                    // AVX2 AVX512_BW{kz}-VL
+    3877             :   ASMJIT_INST_3x(vpmullw, Vpmullw, X86Ymm, X86Ymm, X86Mem)                    // AVX2 AVX512_BW{kz}-VL
+    3878             :   ASMJIT_INST_3x(vpmullw, Vpmullw, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_BW{kz}
+    3879             :   ASMJIT_INST_3x(vpmullw, Vpmullw, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_BW{kz}
+    3880             :   ASMJIT_INST_3x(vpmultishiftqb, Vpmultishiftqb, X86Xmm, X86Xmm, X86Xmm)      //      AVX512_VBMI{kz|b64}-VL
+    3881             :   ASMJIT_INST_3x(vpmultishiftqb, Vpmultishiftqb, X86Xmm, X86Xmm, X86Mem)      //      AVX512_VBMI{kz|b64}-VL
+    3882             :   ASMJIT_INST_3x(vpmultishiftqb, Vpmultishiftqb, X86Ymm, X86Ymm, X86Ymm)      //      AVX512_VBMI{kz|b64}-VL
+    3883             :   ASMJIT_INST_3x(vpmultishiftqb, Vpmultishiftqb, X86Ymm, X86Ymm, X86Mem)      //      AVX512_VBMI{kz|b64}-VL
+    3884             :   ASMJIT_INST_3x(vpmultishiftqb, Vpmultishiftqb, X86Zmm, X86Zmm, X86Zmm)      //      AVX512_VBMI{kz|b64}
+    3885             :   ASMJIT_INST_3x(vpmultishiftqb, Vpmultishiftqb, X86Zmm, X86Zmm, X86Mem)      //      AVX512_VBMI{kz|b64}
+    3886             :   ASMJIT_INST_3x(vpmuludq, Vpmuludq, X86Xmm, X86Xmm, X86Xmm)                  // AVX  AVX512_F{kz|b64}-VL
+    3887             :   ASMJIT_INST_3x(vpmuludq, Vpmuludq, X86Xmm, X86Xmm, X86Mem)                  // AVX  AVX512_F{kz|b64}-VL
+    3888             :   ASMJIT_INST_3x(vpmuludq, Vpmuludq, X86Ymm, X86Ymm, X86Ymm)                  // AVX2 AVX512_F{kz|b64}-VL
+    3889             :   ASMJIT_INST_3x(vpmuludq, Vpmuludq, X86Ymm, X86Ymm, X86Mem)                  // AVX2 AVX512_F{kz|b64}-VL
+    3890             :   ASMJIT_INST_3x(vpmuludq, Vpmuludq, X86Zmm, X86Zmm, X86Zmm)                  //      AVX512_F{kz|b64}
+    3891             :   ASMJIT_INST_3x(vpmuludq, Vpmuludq, X86Zmm, X86Zmm, X86Mem)                  //      AVX512_F{kz|b64}
+    3892             :   ASMJIT_INST_2x(vpopcntd, Vpopcntd, X86Zmm, X86Zmm)                          //      AVX512_VPOPCNTDQ{kz|b32}
+    3893             :   ASMJIT_INST_2x(vpopcntd, Vpopcntd, X86Zmm, X86Mem)                          //      AVX512_VPOPCNTDQ{kz|b32}
+    3894             :   ASMJIT_INST_2x(vpopcntq, Vpopcntq, X86Zmm, X86Zmm)                          //      AVX512_VPOPCNTDQ{kz|b64}
+    3895             :   ASMJIT_INST_2x(vpopcntq, Vpopcntq, X86Zmm, X86Mem)                          //      AVX512_VPOPCNTDQ{kz|b64}
+    3896             :   ASMJIT_INST_3x(vpor, Vpor, X86Xmm, X86Xmm, X86Xmm)                          // AVX
+    3897             :   ASMJIT_INST_3x(vpor, Vpor, X86Xmm, X86Xmm, X86Mem)                          // AVX
+    3898             :   ASMJIT_INST_3x(vpor, Vpor, X86Ymm, X86Ymm, X86Ymm)                          // AVX2
+    3899             :   ASMJIT_INST_3x(vpor, Vpor, X86Ymm, X86Ymm, X86Mem)                          // AVX2
+    3900             :   ASMJIT_INST_3x(vpord, Vpord, X86Xmm, X86Xmm, X86Xmm)                        //      AVX512_F{kz|b32}-VL
+    3901             :   ASMJIT_INST_3x(vpord, Vpord, X86Xmm, X86Xmm, X86Mem)                        //      AVX512_F{kz|b32}-VL
+    3902             :   ASMJIT_INST_3x(vpord, Vpord, X86Ymm, X86Ymm, X86Ymm)                        //      AVX512_F{kz|b32}-VL
+    3903             :   ASMJIT_INST_3x(vpord, Vpord, X86Ymm, X86Ymm, X86Mem)                        //      AVX512_F{kz|b32}-VL
+    3904             :   ASMJIT_INST_3x(vpord, Vpord, X86Zmm, X86Zmm, X86Zmm)                        //      AVX512_F{kz|b32}
+    3905             :   ASMJIT_INST_3x(vpord, Vpord, X86Zmm, X86Zmm, X86Mem)                        //      AVX512_F{kz|b32}
+    3906             :   ASMJIT_INST_3x(vporq, Vporq, X86Xmm, X86Xmm, X86Xmm)                        //      AVX512_F{kz|b64}-VL
+    3907             :   ASMJIT_INST_3x(vporq, Vporq, X86Xmm, X86Xmm, X86Mem)                        //      AVX512_F{kz|b64}-VL
+    3908             :   ASMJIT_INST_3x(vporq, Vporq, X86Ymm, X86Ymm, X86Ymm)                        //      AVX512_F{kz|b64}-VL
+    3909             :   ASMJIT_INST_3x(vporq, Vporq, X86Ymm, X86Ymm, X86Mem)                        //      AVX512_F{kz|b64}-VL
+    3910             :   ASMJIT_INST_3x(vporq, Vporq, X86Zmm, X86Zmm, X86Zmm)                        //      AVX512_F{kz|b64}
+    3911             :   ASMJIT_INST_3x(vporq, Vporq, X86Zmm, X86Zmm, X86Mem)                        //      AVX512_F{kz|b64}
+    3912             :   ASMJIT_INST_3i(vprold, Vprold, X86Xmm, X86Xmm, Imm)                         //      AVX512_F{kz|b32}-VL
+    3913             :   ASMJIT_INST_3i(vprold, Vprold, X86Xmm, X86Mem, Imm)                         //      AVX512_F{kz|b32}-VL
+    3914             :   ASMJIT_INST_3i(vprold, Vprold, X86Ymm, X86Ymm, Imm)                         //      AVX512_F{kz|b32}-VL
+    3915             :   ASMJIT_INST_3i(vprold, Vprold, X86Ymm, X86Mem, Imm)                         //      AVX512_F{kz|b32}-VL
+    3916             :   ASMJIT_INST_3i(vprold, Vprold, X86Zmm, X86Zmm, Imm)                         //      AVX512_F{kz|b32}
+    3917             :   ASMJIT_INST_3i(vprold, Vprold, X86Zmm, X86Mem, Imm)                         //      AVX512_F{kz|b32}
+    3918             :   ASMJIT_INST_3i(vprolq, Vprolq, X86Xmm, X86Xmm, Imm)                         //      AVX512_F{kz|b64}-VL
+    3919             :   ASMJIT_INST_3i(vprolq, Vprolq, X86Xmm, X86Mem, Imm)                         //      AVX512_F{kz|b64}-VL
+    3920             :   ASMJIT_INST_3i(vprolq, Vprolq, X86Ymm, X86Ymm, Imm)                         //      AVX512_F{kz|b64}-VL
+    3921             :   ASMJIT_INST_3i(vprolq, Vprolq, X86Ymm, X86Mem, Imm)                         //      AVX512_F{kz|b64}-VL
+    3922             :   ASMJIT_INST_3i(vprolq, Vprolq, X86Zmm, X86Zmm, Imm)                         //      AVX512_F{kz|b64}
+    3923             :   ASMJIT_INST_3i(vprolq, Vprolq, X86Zmm, X86Mem, Imm)                         //      AVX512_F{kz|b64}
+    3924             :   ASMJIT_INST_3x(vprolvd, Vprolvd, X86Xmm, X86Xmm, X86Xmm)                    //      AVX512_F{kz|b32}-VL
+    3925             :   ASMJIT_INST_3x(vprolvd, Vprolvd, X86Xmm, X86Xmm, X86Mem)                    //      AVX512_F{kz|b32}-VL
+    3926             :   ASMJIT_INST_3x(vprolvd, Vprolvd, X86Ymm, X86Ymm, X86Ymm)                    //      AVX512_F{kz|b32}-VL
+    3927             :   ASMJIT_INST_3x(vprolvd, Vprolvd, X86Ymm, X86Ymm, X86Mem)                    //      AVX512_F{kz|b32}-VL
+    3928             :   ASMJIT_INST_3x(vprolvd, Vprolvd, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_F{kz|b32}
+    3929             :   ASMJIT_INST_3x(vprolvd, Vprolvd, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_F{kz|b32}
+    3930             :   ASMJIT_INST_3x(vprolvq, Vprolvq, X86Xmm, X86Xmm, X86Xmm)                    //      AVX512_F{kz|b64}-VL
+    3931             :   ASMJIT_INST_3x(vprolvq, Vprolvq, X86Xmm, X86Xmm, X86Mem)                    //      AVX512_F{kz|b64}-VL
+    3932             :   ASMJIT_INST_3x(vprolvq, Vprolvq, X86Ymm, X86Ymm, X86Ymm)                    //      AVX512_F{kz|b64}-VL
+    3933             :   ASMJIT_INST_3x(vprolvq, Vprolvq, X86Ymm, X86Ymm, X86Mem)                    //      AVX512_F{kz|b64}-VL
+    3934             :   ASMJIT_INST_3x(vprolvq, Vprolvq, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_F{kz|b64}
+    3935             :   ASMJIT_INST_3x(vprolvq, Vprolvq, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_F{kz|b64}
+    3936             :   ASMJIT_INST_3i(vprord, Vprord, X86Xmm, X86Xmm, Imm)                         //      AVX512_F{kz|b32}-VL
+    3937             :   ASMJIT_INST_3i(vprord, Vprord, X86Xmm, X86Mem, Imm)                         //      AVX512_F{kz|b32}-VL
+    3938             :   ASMJIT_INST_3i(vprord, Vprord, X86Ymm, X86Ymm, Imm)                         //      AVX512_F{kz|b32}-VL
+    3939             :   ASMJIT_INST_3i(vprord, Vprord, X86Ymm, X86Mem, Imm)                         //      AVX512_F{kz|b32}-VL
+    3940             :   ASMJIT_INST_3i(vprord, Vprord, X86Zmm, X86Zmm, Imm)                         //      AVX512_F{kz|b32}
+    3941             :   ASMJIT_INST_3i(vprord, Vprord, X86Zmm, X86Mem, Imm)                         //      AVX512_F{kz|b32}
+    3942             :   ASMJIT_INST_3i(vprorq, Vprorq, X86Xmm, X86Xmm, Imm)                         //      AVX512_F{kz|b64}-VL
+    3943             :   ASMJIT_INST_3i(vprorq, Vprorq, X86Xmm, X86Mem, Imm)                         //      AVX512_F{kz|b64}-VL
+    3944             :   ASMJIT_INST_3i(vprorq, Vprorq, X86Ymm, X86Ymm, Imm)                         //      AVX512_F{kz|b64}-VL
+    3945             :   ASMJIT_INST_3i(vprorq, Vprorq, X86Ymm, X86Mem, Imm)                         //      AVX512_F{kz|b64}-VL
+    3946             :   ASMJIT_INST_3i(vprorq, Vprorq, X86Zmm, X86Zmm, Imm)                         //      AVX512_F{kz|b64}
+    3947             :   ASMJIT_INST_3i(vprorq, Vprorq, X86Zmm, X86Mem, Imm)                         //      AVX512_F{kz|b64}
+    3948             :   ASMJIT_INST_3x(vprorvd, Vprorvd, X86Xmm, X86Xmm, X86Xmm)                    //      AVX512_F{kz|b32}-VL
+    3949             :   ASMJIT_INST_3x(vprorvd, Vprorvd, X86Xmm, X86Xmm, X86Mem)                    //      AVX512_F{kz|b32}-VL
+    3950             :   ASMJIT_INST_3x(vprorvd, Vprorvd, X86Ymm, X86Ymm, X86Ymm)                    //      AVX512_F{kz|b32}-VL
+    3951             :   ASMJIT_INST_3x(vprorvd, Vprorvd, X86Ymm, X86Ymm, X86Mem)                    //      AVX512_F{kz|b32}-VL
+    3952             :   ASMJIT_INST_3x(vprorvd, Vprorvd, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_F{kz|b32}
+    3953             :   ASMJIT_INST_3x(vprorvd, Vprorvd, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_F{kz|b32}
+    3954             :   ASMJIT_INST_3x(vprorvq, Vprorvq, X86Xmm, X86Xmm, X86Xmm)                    //      AVX512_F{kz|b64}-VL
+    3955             :   ASMJIT_INST_3x(vprorvq, Vprorvq, X86Xmm, X86Xmm, X86Mem)                    //      AVX512_F{kz|b64}-VL
+    3956             :   ASMJIT_INST_3x(vprorvq, Vprorvq, X86Ymm, X86Ymm, X86Ymm)                    //      AVX512_F{kz|b64}-VL
+    3957             :   ASMJIT_INST_3x(vprorvq, Vprorvq, X86Ymm, X86Ymm, X86Mem)                    //      AVX512_F{kz|b64}-VL
+    3958             :   ASMJIT_INST_3x(vprorvq, Vprorvq, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_F{kz|b64}
+    3959             :   ASMJIT_INST_3x(vprorvq, Vprorvq, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_F{kz|b64}
+    3960             :   ASMJIT_INST_3x(vpsadbw, Vpsadbw, X86Xmm, X86Xmm, X86Xmm)                    // AVX  AVX512_BW-VL
+    3961             :   ASMJIT_INST_3x(vpsadbw, Vpsadbw, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_BW-VL
+    3962             :   ASMJIT_INST_3x(vpsadbw, Vpsadbw, X86Ymm, X86Ymm, X86Ymm)                    // AVX2 AVX512_BW-VL
+    3963             :   ASMJIT_INST_3x(vpsadbw, Vpsadbw, X86Ymm, X86Ymm, X86Mem)                    // AVX2 AVX512_BW-VL
+    3964             :   ASMJIT_INST_3x(vpsadbw, Vpsadbw, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_BW
+    3965             :   ASMJIT_INST_3x(vpsadbw, Vpsadbw, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_BW
+    3966             :   ASMJIT_INST_2x(vpscatterdd, Vpscatterdd, X86Mem, X86Xmm)                    //      AVX512_F{k}-VL
+    3967             :   ASMJIT_INST_2x(vpscatterdd, Vpscatterdd, X86Mem, X86Ymm)                    //      AVX512_F{k}-VL
+    3968             :   ASMJIT_INST_2x(vpscatterdd, Vpscatterdd, X86Mem, X86Zmm)                    //      AVX512_F{k}
+    3969             :   ASMJIT_INST_2x(vpscatterdq, Vpscatterdq, X86Mem, X86Xmm)                    //      AVX512_F{k}-VL
+    3970             :   ASMJIT_INST_2x(vpscatterdq, Vpscatterdq, X86Mem, X86Ymm)                    //      AVX512_F{k}-VL
+    3971             :   ASMJIT_INST_2x(vpscatterdq, Vpscatterdq, X86Mem, X86Zmm)                    //      AVX512_F{k}
+    3972             :   ASMJIT_INST_2x(vpscatterqd, Vpscatterqd, X86Mem, X86Xmm)                    //      AVX512_F{k}-VL
+    3973             :   ASMJIT_INST_2x(vpscatterqd, Vpscatterqd, X86Mem, X86Ymm)                    //      AVX512_F{k}
+    3974             :   ASMJIT_INST_2x(vpscatterqq, Vpscatterqq, X86Mem, X86Xmm)                    //      AVX512_F{k}-VL
+    3975             :   ASMJIT_INST_2x(vpscatterqq, Vpscatterqq, X86Mem, X86Ymm)                    //      AVX512_F{k}-VL
+    3976             :   ASMJIT_INST_2x(vpscatterqq, Vpscatterqq, X86Mem, X86Zmm)                    //      AVX512_F{k}
+    3977             :   ASMJIT_INST_3x(vpshufb, Vpshufb, X86Xmm, X86Xmm, X86Xmm)                    // AVX  AVX512_BW{kz}-VL
+    3978             :   ASMJIT_INST_3x(vpshufb, Vpshufb, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_BW{kz}-VL
+    3979             :   ASMJIT_INST_3x(vpshufb, Vpshufb, X86Ymm, X86Ymm, X86Ymm)                    // AVX2 AVX512_BW{kz}-VL
+    3980             :   ASMJIT_INST_3x(vpshufb, Vpshufb, X86Ymm, X86Ymm, X86Mem)                    // AVX2 AVX512_BW{kz}-VL
+    3981             :   ASMJIT_INST_3x(vpshufb, Vpshufb, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_BW{kz}
+    3982             :   ASMJIT_INST_3x(vpshufb, Vpshufb, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_BW{kz}
+    3983             :   ASMJIT_INST_3i(vpshufd, Vpshufd, X86Xmm, X86Xmm, Imm)                       // AVX  AVX512_F{kz|b32}-VL
+    3984             :   ASMJIT_INST_3i(vpshufd, Vpshufd, X86Xmm, X86Mem, Imm)                       // AVX  AVX512_F{kz|b32}-VL
+    3985             :   ASMJIT_INST_3i(vpshufd, Vpshufd, X86Ymm, X86Ymm, Imm)                       // AVX2 AVX512_F{kz|b32}-VL
+    3986             :   ASMJIT_INST_3i(vpshufd, Vpshufd, X86Ymm, X86Mem, Imm)                       // AVX2 AVX512_F{kz|b32}-VL
+    3987             :   ASMJIT_INST_3i(vpshufd, Vpshufd, X86Zmm, X86Zmm, Imm)                       //      AVX512_F{kz|b32}
+    3988             :   ASMJIT_INST_3i(vpshufd, Vpshufd, X86Zmm, X86Mem, Imm)                       //      AVX512_F{kz|b32}
+    3989             :   ASMJIT_INST_3i(vpshufhw, Vpshufhw, X86Xmm, X86Xmm, Imm)                     // AVX  AVX512_BW{kz}-VL
+    3990             :   ASMJIT_INST_3i(vpshufhw, Vpshufhw, X86Xmm, X86Mem, Imm)                     // AVX  AVX512_BW{kz}-VL
+    3991             :   ASMJIT_INST_3i(vpshufhw, Vpshufhw, X86Ymm, X86Ymm, Imm)                     // AVX2 AVX512_BW{kz}-VL
+    3992             :   ASMJIT_INST_3i(vpshufhw, Vpshufhw, X86Ymm, X86Mem, Imm)                     // AVX2 AVX512_BW{kz}-VL
+    3993             :   ASMJIT_INST_3i(vpshufhw, Vpshufhw, X86Zmm, X86Zmm, Imm)                     //      AVX512_BW{kz}
+    3994             :   ASMJIT_INST_3i(vpshufhw, Vpshufhw, X86Zmm, X86Mem, Imm)                     //      AVX512_BW{kz}
+    3995             :   ASMJIT_INST_3i(vpshuflw, Vpshuflw, X86Xmm, X86Xmm, Imm)                     // AVX  AVX512_BW{kz}-VL
+    3996             :   ASMJIT_INST_3i(vpshuflw, Vpshuflw, X86Xmm, X86Mem, Imm)                     // AVX  AVX512_BW{kz}-VL
+    3997             :   ASMJIT_INST_3i(vpshuflw, Vpshuflw, X86Ymm, X86Ymm, Imm)                     // AVX2 AVX512_BW{kz}-VL
+    3998             :   ASMJIT_INST_3i(vpshuflw, Vpshuflw, X86Ymm, X86Mem, Imm)                     // AVX2 AVX512_BW{kz}-VL
+    3999             :   ASMJIT_INST_3i(vpshuflw, Vpshuflw, X86Zmm, X86Zmm, Imm)                     //      AVX512_BW{kz}
+    4000             :   ASMJIT_INST_3i(vpshuflw, Vpshuflw, X86Zmm, X86Mem, Imm)                     //      AVX512_BW{kz}
+    4001             :   ASMJIT_INST_3x(vpsignb, Vpsignb, X86Xmm, X86Xmm, X86Xmm)                    // AVX
+    4002             :   ASMJIT_INST_3x(vpsignb, Vpsignb, X86Xmm, X86Xmm, X86Mem)                    // AVX
+    4003             :   ASMJIT_INST_3x(vpsignb, Vpsignb, X86Ymm, X86Ymm, X86Ymm)                    // AVX2
+    4004             :   ASMJIT_INST_3x(vpsignb, Vpsignb, X86Ymm, X86Ymm, X86Mem)                    // AVX2
+    4005             :   ASMJIT_INST_3x(vpsignd, Vpsignd, X86Xmm, X86Xmm, X86Xmm)                    // AVX
+    4006             :   ASMJIT_INST_3x(vpsignd, Vpsignd, X86Xmm, X86Xmm, X86Mem)                    // AVX
+    4007             :   ASMJIT_INST_3x(vpsignd, Vpsignd, X86Ymm, X86Ymm, X86Ymm)                    // AVX2
+    4008             :   ASMJIT_INST_3x(vpsignd, Vpsignd, X86Ymm, X86Ymm, X86Mem)                    // AVX2
+    4009             :   ASMJIT_INST_3x(vpsignw, Vpsignw, X86Xmm, X86Xmm, X86Xmm)                    // AVX
+    4010             :   ASMJIT_INST_3x(vpsignw, Vpsignw, X86Xmm, X86Xmm, X86Mem)                    // AVX
+    4011             :   ASMJIT_INST_3x(vpsignw, Vpsignw, X86Ymm, X86Ymm, X86Ymm)                    // AVX2
+    4012             :   ASMJIT_INST_3x(vpsignw, Vpsignw, X86Ymm, X86Ymm, X86Mem)                    // AVX2
+    4013             :   ASMJIT_INST_3i(vpslld, Vpslld, X86Xmm, X86Xmm, Imm)                         // AVX  AVX512_F{kz|b32}-VL
+    4014             :   ASMJIT_INST_3x(vpslld, Vpslld, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz}-VL
+    4015             :   ASMJIT_INST_3x(vpslld, Vpslld, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz}-VL
+    4016             :   ASMJIT_INST_3i(vpslld, Vpslld, X86Ymm, X86Ymm, Imm)                         // AVX2 AVX512_F{kz|b32}-VL
+    4017             :   ASMJIT_INST_3x(vpslld, Vpslld, X86Ymm, X86Ymm, X86Xmm)                      // AVX2 AVX512_F{kz}-VL
+    4018             :   ASMJIT_INST_3x(vpslld, Vpslld, X86Ymm, X86Ymm, X86Mem)                      // AVX2 AVX512_F{kz}-VL
+    4019             :   ASMJIT_INST_3i(vpslld, Vpslld, X86Xmm, X86Mem, Imm)                         //      AVX512_F{kz|b32}-VL
+    4020             :   ASMJIT_INST_3i(vpslld, Vpslld, X86Ymm, X86Mem, Imm)                         //      AVX512_F{kz|b32}-VL
+    4021             :   ASMJIT_INST_3x(vpslld, Vpslld, X86Zmm, X86Zmm, X86Xmm)                      //      AVX512_F{kz}
+    4022             :   ASMJIT_INST_3x(vpslld, Vpslld, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_F{kz}
+    4023             :   ASMJIT_INST_3i(vpslld, Vpslld, X86Zmm, X86Zmm, Imm)                         //      AVX512_F{kz|b32}
+    4024             :   ASMJIT_INST_3i(vpslld, Vpslld, X86Zmm, X86Mem, Imm)                         //      AVX512_F{kz|b32}
+    4025             :   ASMJIT_INST_3i(vpslldq, Vpslldq, X86Xmm, X86Xmm, Imm)                       // AVX  AVX512_BW-VL
+    4026             :   ASMJIT_INST_3i(vpslldq, Vpslldq, X86Ymm, X86Ymm, Imm)                       // AVX2 AVX512_BW-VL
+    4027             :   ASMJIT_INST_3i(vpslldq, Vpslldq, X86Xmm, X86Mem, Imm)                       //      AVX512_BW-VL
+    4028             :   ASMJIT_INST_3i(vpslldq, Vpslldq, X86Ymm, X86Mem, Imm)                       //      AVX512_BW-VL
+    4029             :   ASMJIT_INST_3i(vpslldq, Vpslldq, X86Zmm, X86Zmm, Imm)                       //      AVX512_BW
+    4030             :   ASMJIT_INST_3i(vpslldq, Vpslldq, X86Zmm, X86Mem, Imm)                       //      AVX512_BW
+    4031             :   ASMJIT_INST_3i(vpsllq, Vpsllq, X86Xmm, X86Xmm, Imm)                         // AVX  AVX512_F{kz|b64}-VL
+    4032             :   ASMJIT_INST_3x(vpsllq, Vpsllq, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz}-VL
+    4033             :   ASMJIT_INST_3x(vpsllq, Vpsllq, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz}-VL
+    4034             :   ASMJIT_INST_3i(vpsllq, Vpsllq, X86Ymm, X86Ymm, Imm)                         // AVX2 AVX512_F{kz|b64}-VL
+    4035             :   ASMJIT_INST_3x(vpsllq, Vpsllq, X86Ymm, X86Ymm, X86Xmm)                      // AVX2 AVX512_F{kz}-VL
+    4036             :   ASMJIT_INST_3x(vpsllq, Vpsllq, X86Ymm, X86Ymm, X86Mem)                      // AVX2 AVX512_F{kz}-VL
+    4037             :   ASMJIT_INST_3i(vpsllq, Vpsllq, X86Xmm, X86Mem, Imm)                         //      AVX512_F{kz|b64}-VL
+    4038             :   ASMJIT_INST_3i(vpsllq, Vpsllq, X86Ymm, X86Mem, Imm)                         //      AVX512_F{kz|b64}-VL
+    4039             :   ASMJIT_INST_3x(vpsllq, Vpsllq, X86Zmm, X86Zmm, X86Xmm)                      //      AVX512_F{kz}
+    4040             :   ASMJIT_INST_3x(vpsllq, Vpsllq, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_F{kz}
+    4041             :   ASMJIT_INST_3i(vpsllq, Vpsllq, X86Zmm, X86Zmm, Imm)                         //      AVX512_F{kz|b64}
+    4042             :   ASMJIT_INST_3i(vpsllq, Vpsllq, X86Zmm, X86Mem, Imm)                         //      AVX512_F{kz|b64}
+    4043             :   ASMJIT_INST_3x(vpsllvd, Vpsllvd, X86Xmm, X86Xmm, X86Xmm)                    // AVX2 AVX512_F{kz|b32}-VL
+    4044             :   ASMJIT_INST_3x(vpsllvd, Vpsllvd, X86Xmm, X86Xmm, X86Mem)                    // AVX2 AVX512_F{kz|b32}-VL
+    4045             :   ASMJIT_INST_3x(vpsllvd, Vpsllvd, X86Ymm, X86Ymm, X86Ymm)                    // AVX2 AVX512_F{kz|b32}-VL
+    4046             :   ASMJIT_INST_3x(vpsllvd, Vpsllvd, X86Ymm, X86Ymm, X86Mem)                    // AVX2 AVX512_F{kz|b32}-VL
+    4047             :   ASMJIT_INST_3x(vpsllvd, Vpsllvd, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_F{kz|b32}
+    4048             :   ASMJIT_INST_3x(vpsllvd, Vpsllvd, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_F{kz|b32}
+    4049             :   ASMJIT_INST_3x(vpsllvq, Vpsllvq, X86Xmm, X86Xmm, X86Xmm)                    // AVX2 AVX512_F{kz|b64}-VL
+    4050             :   ASMJIT_INST_3x(vpsllvq, Vpsllvq, X86Xmm, X86Xmm, X86Mem)                    // AVX2 AVX512_F{kz|b64}-VL
+    4051             :   ASMJIT_INST_3x(vpsllvq, Vpsllvq, X86Ymm, X86Ymm, X86Ymm)                    // AVX2 AVX512_F{kz|b64}-VL
+    4052             :   ASMJIT_INST_3x(vpsllvq, Vpsllvq, X86Ymm, X86Ymm, X86Mem)                    // AVX2 AVX512_F{kz|b64}-VL
+    4053             :   ASMJIT_INST_3x(vpsllvq, Vpsllvq, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_F{kz|b64}
+    4054             :   ASMJIT_INST_3x(vpsllvq, Vpsllvq, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_F{kz|b64}
+    4055             :   ASMJIT_INST_3x(vpsllvw, Vpsllvw, X86Xmm, X86Xmm, X86Xmm)                    //      AVX512_BW{kz}-VL
+    4056             :   ASMJIT_INST_3x(vpsllvw, Vpsllvw, X86Xmm, X86Xmm, X86Mem)                    //      AVX512_BW{kz}-VL
+    4057             :   ASMJIT_INST_3x(vpsllvw, Vpsllvw, X86Ymm, X86Ymm, X86Ymm)                    //      AVX512_BW{kz}-VL
+    4058             :   ASMJIT_INST_3x(vpsllvw, Vpsllvw, X86Ymm, X86Ymm, X86Mem)                    //      AVX512_BW{kz}-VL
+    4059             :   ASMJIT_INST_3x(vpsllvw, Vpsllvw, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_BW{kz}
+    4060             :   ASMJIT_INST_3x(vpsllvw, Vpsllvw, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_BW{kz}
+    4061             :   ASMJIT_INST_3i(vpsllw, Vpsllw, X86Xmm, X86Xmm, Imm)                         // AVX  AVX512_BW{kz}-VL
+    4062             :   ASMJIT_INST_3x(vpsllw, Vpsllw, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_BW{kz}-VL
+    4063             :   ASMJIT_INST_3x(vpsllw, Vpsllw, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_BW{kz}-VL
+    4064             :   ASMJIT_INST_3i(vpsllw, Vpsllw, X86Ymm, X86Ymm, Imm)                         // AVX2 AVX512_BW{kz}-VL
+    4065             :   ASMJIT_INST_3x(vpsllw, Vpsllw, X86Ymm, X86Ymm, X86Xmm)                      // AVX2 AVX512_BW{kz}-VL
+    4066             :   ASMJIT_INST_3x(vpsllw, Vpsllw, X86Ymm, X86Ymm, X86Mem)                      // AVX2 AVX512_BW{kz}-VL
+    4067             :   ASMJIT_INST_3i(vpsllw, Vpsllw, X86Xmm, X86Mem, Imm)                         //      AVX512_BW{kz}-VL
+    4068             :   ASMJIT_INST_3i(vpsllw, Vpsllw, X86Ymm, X86Mem, Imm)                         //      AVX512_BW{kz}-VL
+    4069             :   ASMJIT_INST_3x(vpsllw, Vpsllw, X86Zmm, X86Zmm, X86Xmm)                      //      AVX512_BW{kz}
+    4070             :   ASMJIT_INST_3x(vpsllw, Vpsllw, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_BW{kz}
+    4071             :   ASMJIT_INST_3i(vpsllw, Vpsllw, X86Zmm, X86Zmm, Imm)                         //      AVX512_BW{kz}
+    4072             :   ASMJIT_INST_3i(vpsllw, Vpsllw, X86Zmm, X86Mem, Imm)                         //      AVX512_BW{kz}
+    4073             :   ASMJIT_INST_3i(vpsrad, Vpsrad, X86Xmm, X86Xmm, Imm)                         // AVX  AVX512_F{kz|b32}-VL
+    4074             :   ASMJIT_INST_3x(vpsrad, Vpsrad, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz}-VL
+    4075             :   ASMJIT_INST_3x(vpsrad, Vpsrad, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz}-VL
+    4076             :   ASMJIT_INST_3i(vpsrad, Vpsrad, X86Ymm, X86Ymm, Imm)                         // AVX2 AVX512_F{kz|b32}-VL
+    4077             :   ASMJIT_INST_3x(vpsrad, Vpsrad, X86Ymm, X86Ymm, X86Xmm)                      // AVX2 AVX512_F{kz}-VL
+    4078             :   ASMJIT_INST_3x(vpsrad, Vpsrad, X86Ymm, X86Ymm, X86Mem)                      // AVX2 AVX512_F{kz}-VL
+    4079             :   ASMJIT_INST_3i(vpsrad, Vpsrad, X86Xmm, X86Mem, Imm)                         //      AVX512_F{kz|b32}-VL
+    4080             :   ASMJIT_INST_3i(vpsrad, Vpsrad, X86Ymm, X86Mem, Imm)                         //      AVX512_F{kz|b32}-VL
+    4081             :   ASMJIT_INST_3x(vpsrad, Vpsrad, X86Zmm, X86Zmm, X86Xmm)                      //      AVX512_F{kz}
+    4082             :   ASMJIT_INST_3x(vpsrad, Vpsrad, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_F{kz}
+    4083             :   ASMJIT_INST_3i(vpsrad, Vpsrad, X86Zmm, X86Zmm, Imm)                         //      AVX512_F{kz|b32}
+    4084             :   ASMJIT_INST_3i(vpsrad, Vpsrad, X86Zmm, X86Mem, Imm)                         //      AVX512_F{kz|b32}
+    4085             :   ASMJIT_INST_3x(vpsraq, Vpsraq, X86Xmm, X86Xmm, X86Xmm)                      //      AVX512_F{kz}-VL
+    4086             :   ASMJIT_INST_3x(vpsraq, Vpsraq, X86Xmm, X86Xmm, X86Mem)                      //      AVX512_F{kz}-VL
+    4087             :   ASMJIT_INST_3i(vpsraq, Vpsraq, X86Xmm, X86Xmm, Imm)                         //      AVX512_F{kz|b64}-VL
+    4088             :   ASMJIT_INST_3i(vpsraq, Vpsraq, X86Xmm, X86Mem, Imm)                         //      AVX512_F{kz|b64}-VL
+    4089             :   ASMJIT_INST_3x(vpsraq, Vpsraq, X86Ymm, X86Ymm, X86Xmm)                      //      AVX512_F{kz}-VL
+    4090             :   ASMJIT_INST_3x(vpsraq, Vpsraq, X86Ymm, X86Ymm, X86Mem)                      //      AVX512_F{kz}-VL
+    4091             :   ASMJIT_INST_3i(vpsraq, Vpsraq, X86Ymm, X86Ymm, Imm)                         //      AVX512_F{kz|b64}-VL
+    4092             :   ASMJIT_INST_3i(vpsraq, Vpsraq, X86Ymm, X86Mem, Imm)                         //      AVX512_F{kz|b64}-VL
+    4093             :   ASMJIT_INST_3x(vpsraq, Vpsraq, X86Zmm, X86Zmm, X86Xmm)                      //      AVX512_F{kz}
+    4094             :   ASMJIT_INST_3x(vpsraq, Vpsraq, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_F{kz}
+    4095             :   ASMJIT_INST_3i(vpsraq, Vpsraq, X86Zmm, X86Zmm, Imm)                         //      AVX512_F{kz|b64}
+    4096             :   ASMJIT_INST_3i(vpsraq, Vpsraq, X86Zmm, X86Mem, Imm)                         //      AVX512_F{kz|b64}
+    4097             :   ASMJIT_INST_3x(vpsravd, Vpsravd, X86Xmm, X86Xmm, X86Xmm)                    // AVX2 AVX512_F{kz|b32}-VL
+    4098             :   ASMJIT_INST_3x(vpsravd, Vpsravd, X86Xmm, X86Xmm, X86Mem)                    // AVX2 AVX512_F{kz|b32}-VL
+    4099             :   ASMJIT_INST_3x(vpsravd, Vpsravd, X86Ymm, X86Ymm, X86Ymm)                    // AVX2 AVX512_F{kz|b32}-VL
+    4100             :   ASMJIT_INST_3x(vpsravd, Vpsravd, X86Ymm, X86Ymm, X86Mem)                    // AVX2 AVX512_F{kz|b32}-VL
+    4101             :   ASMJIT_INST_3x(vpsravd, Vpsravd, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_F{kz|b32}
+    4102             :   ASMJIT_INST_3x(vpsravd, Vpsravd, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_F{kz|b32}
+    4103             :   ASMJIT_INST_3x(vpsravq, Vpsravq, X86Xmm, X86Xmm, X86Xmm)                    //      AVX512_F{kz|b64}-VL
+    4104             :   ASMJIT_INST_3x(vpsravq, Vpsravq, X86Xmm, X86Xmm, X86Mem)                    //      AVX512_F{kz|b64}-VL
+    4105             :   ASMJIT_INST_3x(vpsravq, Vpsravq, X86Ymm, X86Ymm, X86Ymm)                    //      AVX512_F{kz|b64}-VL
+    4106             :   ASMJIT_INST_3x(vpsravq, Vpsravq, X86Ymm, X86Ymm, X86Mem)                    //      AVX512_F{kz|b64}-VL
+    4107             :   ASMJIT_INST_3x(vpsravq, Vpsravq, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_F{kz|b64}
+    4108             :   ASMJIT_INST_3x(vpsravq, Vpsravq, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_F{kz|b64}
+    4109             :   ASMJIT_INST_3x(vpsravw, Vpsravw, X86Xmm, X86Xmm, X86Xmm)                    //      AVX512_BW{kz}-VL
+    4110             :   ASMJIT_INST_3x(vpsravw, Vpsravw, X86Xmm, X86Xmm, X86Mem)                    //      AVX512_BW{kz}-VL
+    4111             :   ASMJIT_INST_3x(vpsravw, Vpsravw, X86Ymm, X86Ymm, X86Ymm)                    //      AVX512_BW{kz}-VL
+    4112             :   ASMJIT_INST_3x(vpsravw, Vpsravw, X86Ymm, X86Ymm, X86Mem)                    //      AVX512_BW{kz}-VL
+    4113             :   ASMJIT_INST_3x(vpsravw, Vpsravw, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_BW{kz}
+    4114             :   ASMJIT_INST_3x(vpsravw, Vpsravw, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_BW{kz}
+    4115             :   ASMJIT_INST_3i(vpsraw, Vpsraw, X86Xmm, X86Xmm, Imm)                         // AVX  AVX512_BW{kz}-VL
+    4116             :   ASMJIT_INST_3x(vpsraw, Vpsraw, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_BW{kz}-VL
+    4117             :   ASMJIT_INST_3x(vpsraw, Vpsraw, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_BW{kz}-VL
+    4118             :   ASMJIT_INST_3i(vpsraw, Vpsraw, X86Ymm, X86Ymm, Imm)                         // AVX2 AVX512_BW{kz}-VL
+    4119             :   ASMJIT_INST_3x(vpsraw, Vpsraw, X86Ymm, X86Ymm, X86Xmm)                      // AVX2 AVX512_BW{kz}-VL
+    4120             :   ASMJIT_INST_3x(vpsraw, Vpsraw, X86Ymm, X86Ymm, X86Mem)                      // AVX2 AVX512_BW{kz}-VL
+    4121             :   ASMJIT_INST_3i(vpsraw, Vpsraw, X86Xmm, X86Mem, Imm)                         //      AVX512_BW{kz}-VL
+    4122             :   ASMJIT_INST_3i(vpsraw, Vpsraw, X86Ymm, X86Mem, Imm)                         //      AVX512_BW{kz}-VL
+    4123             :   ASMJIT_INST_3x(vpsraw, Vpsraw, X86Zmm, X86Zmm, X86Xmm)                      //      AVX512_BW{kz}
+    4124             :   ASMJIT_INST_3x(vpsraw, Vpsraw, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_BW{kz}
+    4125             :   ASMJIT_INST_3i(vpsraw, Vpsraw, X86Zmm, X86Zmm, Imm)                         //      AVX512_BW{kz}
+    4126             :   ASMJIT_INST_3i(vpsraw, Vpsraw, X86Zmm, X86Mem, Imm)                         //      AVX512_BW{kz}
+    4127             :   ASMJIT_INST_3i(vpsrld, Vpsrld, X86Xmm, X86Xmm, Imm)                         // AVX  AVX512_F{kz|b32}-VL
+    4128             :   ASMJIT_INST_3x(vpsrld, Vpsrld, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz}-VL
+    4129             :   ASMJIT_INST_3x(vpsrld, Vpsrld, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz}-VL
+    4130             :   ASMJIT_INST_3i(vpsrld, Vpsrld, X86Ymm, X86Ymm, Imm)                         // AVX2 AVX512_F{kz|b32}-VL
+    4131             :   ASMJIT_INST_3x(vpsrld, Vpsrld, X86Ymm, X86Ymm, X86Xmm)                      // AVX2 AVX512_F{kz}-VL
+    4132             :   ASMJIT_INST_3x(vpsrld, Vpsrld, X86Ymm, X86Ymm, X86Mem)                      // AVX2 AVX512_F{kz}-VL
+    4133             :   ASMJIT_INST_3i(vpsrld, Vpsrld, X86Xmm, X86Mem, Imm)                         //      AVX512_F{kz|b32}-VL
+    4134             :   ASMJIT_INST_3i(vpsrld, Vpsrld, X86Ymm, X86Mem, Imm)                         //      AVX512_F{kz|b32}-VL
+    4135             :   ASMJIT_INST_3x(vpsrld, Vpsrld, X86Zmm, X86Zmm, X86Xmm)                      //      AVX512_F{kz}
+    4136             :   ASMJIT_INST_3x(vpsrld, Vpsrld, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_F{kz}
+    4137             :   ASMJIT_INST_3i(vpsrld, Vpsrld, X86Zmm, X86Zmm, Imm)                         //      AVX512_F{kz|b32}
+    4138             :   ASMJIT_INST_3i(vpsrld, Vpsrld, X86Zmm, X86Mem, Imm)                         //      AVX512_F{kz|b32}
+    4139             :   ASMJIT_INST_3i(vpsrldq, Vpsrldq, X86Xmm, X86Xmm, Imm)                       // AVX  AVX512_BW-VL
+    4140             :   ASMJIT_INST_3i(vpsrldq, Vpsrldq, X86Ymm, X86Ymm, Imm)                       // AVX2 AVX512_BW-VL
+    4141             :   ASMJIT_INST_3i(vpsrldq, Vpsrldq, X86Xmm, X86Mem, Imm)                       //      AVX512_BW-VL
+    4142             :   ASMJIT_INST_3i(vpsrldq, Vpsrldq, X86Ymm, X86Mem, Imm)                       //      AVX512_BW-VL
+    4143             :   ASMJIT_INST_3i(vpsrldq, Vpsrldq, X86Zmm, X86Zmm, Imm)                       //      AVX512_BW
+    4144             :   ASMJIT_INST_3i(vpsrldq, Vpsrldq, X86Zmm, X86Mem, Imm)                       //      AVX512_BW
+    4145             :   ASMJIT_INST_3i(vpsrlq, Vpsrlq, X86Xmm, X86Xmm, Imm)                         // AVX  AVX512_F{kz|b64}-VL
+    4146             :   ASMJIT_INST_3x(vpsrlq, Vpsrlq, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz}-VL
+    4147             :   ASMJIT_INST_3x(vpsrlq, Vpsrlq, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz}-VL
+    4148             :   ASMJIT_INST_3i(vpsrlq, Vpsrlq, X86Ymm, X86Ymm, Imm)                         // AVX2 AVX512_F{kz|b64}-VL
+    4149             :   ASMJIT_INST_3x(vpsrlq, Vpsrlq, X86Ymm, X86Ymm, X86Xmm)                      // AVX2 AVX512_F{kz}-VL
+    4150             :   ASMJIT_INST_3x(vpsrlq, Vpsrlq, X86Ymm, X86Ymm, X86Mem)                      // AVX2 AVX512_F{kz}-VL
+    4151             :   ASMJIT_INST_3i(vpsrlq, Vpsrlq, X86Xmm, X86Mem, Imm)                         //      AVX512_F{kz|b64}-VL
+    4152             :   ASMJIT_INST_3i(vpsrlq, Vpsrlq, X86Ymm, X86Mem, Imm)                         //      AVX512_F{kz|b64}-VL
+    4153             :   ASMJIT_INST_3x(vpsrlq, Vpsrlq, X86Zmm, X86Zmm, X86Xmm)                      //      AVX512_F{kz}
+    4154             :   ASMJIT_INST_3x(vpsrlq, Vpsrlq, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_F{kz}
+    4155             :   ASMJIT_INST_3i(vpsrlq, Vpsrlq, X86Zmm, X86Zmm, Imm)                         //      AVX512_F{kz|b64}
+    4156             :   ASMJIT_INST_3i(vpsrlq, Vpsrlq, X86Zmm, X86Mem, Imm)                         //      AVX512_F{kz|b64}
+    4157             :   ASMJIT_INST_3x(vpsrlvd, Vpsrlvd, X86Xmm, X86Xmm, X86Xmm)                    // AVX2 AVX512_F{kz|b32}-VL
+    4158             :   ASMJIT_INST_3x(vpsrlvd, Vpsrlvd, X86Xmm, X86Xmm, X86Mem)                    // AVX2 AVX512_F{kz|b32}-VL
+    4159             :   ASMJIT_INST_3x(vpsrlvd, Vpsrlvd, X86Ymm, X86Ymm, X86Ymm)                    // AVX2 AVX512_F{kz|b32}-VL
+    4160             :   ASMJIT_INST_3x(vpsrlvd, Vpsrlvd, X86Ymm, X86Ymm, X86Mem)                    // AVX2 AVX512_F{kz|b32}-VL
+    4161             :   ASMJIT_INST_3x(vpsrlvd, Vpsrlvd, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_F{kz|b32}
+    4162             :   ASMJIT_INST_3x(vpsrlvd, Vpsrlvd, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_F{kz|b32}
+    4163             :   ASMJIT_INST_3x(vpsrlvq, Vpsrlvq, X86Xmm, X86Xmm, X86Xmm)                    // AVX2 AVX512_F{kz|b64}-VL
+    4164             :   ASMJIT_INST_3x(vpsrlvq, Vpsrlvq, X86Xmm, X86Xmm, X86Mem)                    // AVX2 AVX512_F{kz|b64}-VL
+    4165             :   ASMJIT_INST_3x(vpsrlvq, Vpsrlvq, X86Ymm, X86Ymm, X86Ymm)                    // AVX2 AVX512_F{kz|b64}-VL
+    4166             :   ASMJIT_INST_3x(vpsrlvq, Vpsrlvq, X86Ymm, X86Ymm, X86Mem)                    // AVX2 AVX512_F{kz|b64}-VL
+    4167             :   ASMJIT_INST_3x(vpsrlvq, Vpsrlvq, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_F{kz|b64}
+    4168             :   ASMJIT_INST_3x(vpsrlvq, Vpsrlvq, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_F{kz|b64}
+    4169             :   ASMJIT_INST_3x(vpsrlvw, Vpsrlvw, X86Xmm, X86Xmm, X86Xmm)                    //      AVX512_BW{kz}-VL
+    4170             :   ASMJIT_INST_3x(vpsrlvw, Vpsrlvw, X86Xmm, X86Xmm, X86Mem)                    //      AVX512_BW{kz}-VL
+    4171             :   ASMJIT_INST_3x(vpsrlvw, Vpsrlvw, X86Ymm, X86Ymm, X86Ymm)                    //      AVX512_BW{kz}-VL
+    4172             :   ASMJIT_INST_3x(vpsrlvw, Vpsrlvw, X86Ymm, X86Ymm, X86Mem)                    //      AVX512_BW{kz}-VL
+    4173             :   ASMJIT_INST_3x(vpsrlvw, Vpsrlvw, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_BW{kz}
+    4174             :   ASMJIT_INST_3x(vpsrlvw, Vpsrlvw, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_BW{kz}
+    4175             :   ASMJIT_INST_3i(vpsrlw, Vpsrlw, X86Xmm, X86Xmm, Imm)                         // AVX  AVX512_BW{kz}-VL
+    4176             :   ASMJIT_INST_3x(vpsrlw, Vpsrlw, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_BW{kz}-VL
+    4177             :   ASMJIT_INST_3x(vpsrlw, Vpsrlw, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_BW{kz}-VL
+    4178             :   ASMJIT_INST_3i(vpsrlw, Vpsrlw, X86Ymm, X86Ymm, Imm)                         // AVX2 AVX512_BW{kz}-VL
+    4179             :   ASMJIT_INST_3x(vpsrlw, Vpsrlw, X86Ymm, X86Ymm, X86Xmm)                      // AVX2 AVX512_BW{kz}-VL
+    4180             :   ASMJIT_INST_3x(vpsrlw, Vpsrlw, X86Ymm, X86Ymm, X86Mem)                      // AVX2 AVX512_BW{kz}-VL
+    4181             :   ASMJIT_INST_3i(vpsrlw, Vpsrlw, X86Xmm, X86Mem, Imm)                         //      AVX512_BW{kz}-VL
+    4182             :   ASMJIT_INST_3i(vpsrlw, Vpsrlw, X86Ymm, X86Mem, Imm)                         //      AVX512_BW{kz}-VL
+    4183             :   ASMJIT_INST_3x(vpsrlw, Vpsrlw, X86Zmm, X86Zmm, X86Xmm)                      //      AVX512_BW{kz}
+    4184             :   ASMJIT_INST_3x(vpsrlw, Vpsrlw, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_BW{kz}
+    4185             :   ASMJIT_INST_3i(vpsrlw, Vpsrlw, X86Zmm, X86Zmm, Imm)                         //      AVX512_BW{kz}
+    4186             :   ASMJIT_INST_3i(vpsrlw, Vpsrlw, X86Zmm, X86Mem, Imm)                         //      AVX512_BW{kz}
+    4187             :   ASMJIT_INST_3x(vpsubb, Vpsubb, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_BW{kz}-VL
+    4188             :   ASMJIT_INST_3x(vpsubb, Vpsubb, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_BW{kz}-VL
+    4189             :   ASMJIT_INST_3x(vpsubb, Vpsubb, X86Ymm, X86Ymm, X86Ymm)                      // AVX2 AVX512_BW{kz}-VL
+    4190             :   ASMJIT_INST_3x(vpsubb, Vpsubb, X86Ymm, X86Ymm, X86Mem)                      // AVX2 AVX512_BW{kz}-VL
+    4191             :   ASMJIT_INST_3x(vpsubb, Vpsubb, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_BW{kz}
+    4192             :   ASMJIT_INST_3x(vpsubb, Vpsubb, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_BW{kz}
+    4193             :   ASMJIT_INST_3x(vpsubd, Vpsubd, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|b32}-VL
+    4194             :   ASMJIT_INST_3x(vpsubd, Vpsubd, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|b32}-VL
+    4195             :   ASMJIT_INST_3x(vpsubd, Vpsubd, X86Ymm, X86Ymm, X86Ymm)                      // AVX2 AVX512_F{kz|b32}-VL
+    4196             :   ASMJIT_INST_3x(vpsubd, Vpsubd, X86Ymm, X86Ymm, X86Mem)                      // AVX2 AVX512_F{kz|b32}-VL
+    4197             :   ASMJIT_INST_3x(vpsubd, Vpsubd, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_F{kz|b32}
+    4198             :   ASMJIT_INST_3x(vpsubd, Vpsubd, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_F{kz|b32}
+    4199             :   ASMJIT_INST_3x(vpsubq, Vpsubq, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|b64}-VL
+    4200             :   ASMJIT_INST_3x(vpsubq, Vpsubq, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|b64}-VL
+    4201             :   ASMJIT_INST_3x(vpsubq, Vpsubq, X86Ymm, X86Ymm, X86Ymm)                      // AVX2 AVX512_F{kz|b64}-VL
+    4202             :   ASMJIT_INST_3x(vpsubq, Vpsubq, X86Ymm, X86Ymm, X86Mem)                      // AVX2 AVX512_F{kz|b64}-VL
+    4203             :   ASMJIT_INST_3x(vpsubq, Vpsubq, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_F{kz|b64}
+    4204             :   ASMJIT_INST_3x(vpsubq, Vpsubq, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_F{kz|b64}
+    4205             :   ASMJIT_INST_3x(vpsubsb, Vpsubsb, X86Xmm, X86Xmm, X86Xmm)                    // AVX  AVX512_BW{kz}-VL
+    4206             :   ASMJIT_INST_3x(vpsubsb, Vpsubsb, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_BW{kz}-VL
+    4207             :   ASMJIT_INST_3x(vpsubsb, Vpsubsb, X86Ymm, X86Ymm, X86Ymm)                    // AVX2 AVX512_BW{kz}-VL
+    4208             :   ASMJIT_INST_3x(vpsubsb, Vpsubsb, X86Ymm, X86Ymm, X86Mem)                    // AVX2 AVX512_BW{kz}-VL
+    4209             :   ASMJIT_INST_3x(vpsubsb, Vpsubsb, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_BW{kz}
+    4210             :   ASMJIT_INST_3x(vpsubsb, Vpsubsb, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_BW{kz}
+    4211             :   ASMJIT_INST_3x(vpsubsw, Vpsubsw, X86Xmm, X86Xmm, X86Xmm)                    // AVX  AVX512_BW{kz}-VL
+    4212             :   ASMJIT_INST_3x(vpsubsw, Vpsubsw, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_BW{kz}-VL
+    4213             :   ASMJIT_INST_3x(vpsubsw, Vpsubsw, X86Ymm, X86Ymm, X86Ymm)                    // AVX2 AVX512_BW{kz}-VL
+    4214             :   ASMJIT_INST_3x(vpsubsw, Vpsubsw, X86Ymm, X86Ymm, X86Mem)                    // AVX2 AVX512_BW{kz}-VL
+    4215             :   ASMJIT_INST_3x(vpsubsw, Vpsubsw, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_BW{kz}
+    4216             :   ASMJIT_INST_3x(vpsubsw, Vpsubsw, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_BW{kz}
+    4217             :   ASMJIT_INST_3x(vpsubusb, Vpsubusb, X86Xmm, X86Xmm, X86Xmm)                  // AVX  AVX512_BW{kz}-VL
+    4218             :   ASMJIT_INST_3x(vpsubusb, Vpsubusb, X86Xmm, X86Xmm, X86Mem)                  // AVX  AVX512_BW{kz}-VL
+    4219             :   ASMJIT_INST_3x(vpsubusb, Vpsubusb, X86Ymm, X86Ymm, X86Ymm)                  // AVX2 AVX512_BW{kz}-VL
+    4220             :   ASMJIT_INST_3x(vpsubusb, Vpsubusb, X86Ymm, X86Ymm, X86Mem)                  // AVX2 AVX512_BW{kz}-VL
+    4221             :   ASMJIT_INST_3x(vpsubusb, Vpsubusb, X86Zmm, X86Zmm, X86Zmm)                  //      AVX512_BW{kz}
+    4222             :   ASMJIT_INST_3x(vpsubusb, Vpsubusb, X86Zmm, X86Zmm, X86Mem)                  //      AVX512_BW{kz}
+    4223             :   ASMJIT_INST_3x(vpsubusw, Vpsubusw, X86Xmm, X86Xmm, X86Xmm)                  // AVX  AVX512_BW{kz}-VL
+    4224             :   ASMJIT_INST_3x(vpsubusw, Vpsubusw, X86Xmm, X86Xmm, X86Mem)                  // AVX  AVX512_BW{kz}-VL
+    4225             :   ASMJIT_INST_3x(vpsubusw, Vpsubusw, X86Ymm, X86Ymm, X86Ymm)                  // AVX2 AVX512_BW{kz}-VL
+    4226             :   ASMJIT_INST_3x(vpsubusw, Vpsubusw, X86Ymm, X86Ymm, X86Mem)                  // AVX2 AVX512_BW{kz}-VL
+    4227             :   ASMJIT_INST_3x(vpsubusw, Vpsubusw, X86Zmm, X86Zmm, X86Zmm)                  //      AVX512_BW{kz}
+    4228             :   ASMJIT_INST_3x(vpsubusw, Vpsubusw, X86Zmm, X86Zmm, X86Mem)                  //      AVX512_BW{kz}
+    4229             :   ASMJIT_INST_3x(vpsubw, Vpsubw, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_BW{kz}-VL
+    4230             :   ASMJIT_INST_3x(vpsubw, Vpsubw, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_BW{kz}-VL
+    4231             :   ASMJIT_INST_3x(vpsubw, Vpsubw, X86Ymm, X86Ymm, X86Ymm)                      // AVX2 AVX512_BW{kz}-VL
+    4232             :   ASMJIT_INST_3x(vpsubw, Vpsubw, X86Ymm, X86Ymm, X86Mem)                      // AVX2 AVX512_BW{kz}-VL
+    4233             :   ASMJIT_INST_3x(vpsubw, Vpsubw, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_BW{kz}
+    4234             :   ASMJIT_INST_3x(vpsubw, Vpsubw, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_BW{kz}
+    4235             :   ASMJIT_INST_4i(vpternlogd, Vpternlogd, X86Xmm, X86Xmm, X86Xmm, Imm)         //      AVX512_F{kz|b32}-VL
+    4236             :   ASMJIT_INST_4i(vpternlogd, Vpternlogd, X86Xmm, X86Xmm, X86Mem, Imm)         //      AVX512_F{kz|b32}-VL
+    4237             :   ASMJIT_INST_4i(vpternlogd, Vpternlogd, X86Ymm, X86Ymm, X86Ymm, Imm)         //      AVX512_F{kz|b32}-VL
+    4238             :   ASMJIT_INST_4i(vpternlogd, Vpternlogd, X86Ymm, X86Ymm, X86Mem, Imm)         //      AVX512_F{kz|b32}-VL
+    4239             :   ASMJIT_INST_4i(vpternlogd, Vpternlogd, X86Zmm, X86Zmm, X86Zmm, Imm)         //      AVX512_F{kz|b32}
+    4240             :   ASMJIT_INST_4i(vpternlogd, Vpternlogd, X86Zmm, X86Zmm, X86Mem, Imm)         //      AVX512_F{kz|b32}
+    4241             :   ASMJIT_INST_4i(vpternlogq, Vpternlogq, X86Xmm, X86Xmm, X86Xmm, Imm)         //      AVX512_F{kz|b64}-VL
+    4242             :   ASMJIT_INST_4i(vpternlogq, Vpternlogq, X86Xmm, X86Xmm, X86Mem, Imm)         //      AVX512_F{kz|b64}-VL
+    4243             :   ASMJIT_INST_4i(vpternlogq, Vpternlogq, X86Ymm, X86Ymm, X86Ymm, Imm)         //      AVX512_F{kz|b64}-VL
+    4244             :   ASMJIT_INST_4i(vpternlogq, Vpternlogq, X86Ymm, X86Ymm, X86Mem, Imm)         //      AVX512_F{kz|b64}-VL
+    4245             :   ASMJIT_INST_4i(vpternlogq, Vpternlogq, X86Zmm, X86Zmm, X86Zmm, Imm)         //      AVX512_F{kz|b64}
+    4246             :   ASMJIT_INST_4i(vpternlogq, Vpternlogq, X86Zmm, X86Zmm, X86Mem, Imm)         //      AVX512_F{kz|b64}
+    4247             :   ASMJIT_INST_2x(vptest, Vptest, X86Xmm, X86Xmm)                              // AVX
+    4248             :   ASMJIT_INST_2x(vptest, Vptest, X86Xmm, X86Mem)                              // AVX
+    4249             :   ASMJIT_INST_2x(vptest, Vptest, X86Ymm, X86Ymm)                              // AVX
+    4250             :   ASMJIT_INST_2x(vptest, Vptest, X86Ymm, X86Mem)                              // AVX
+    4251             :   ASMJIT_INST_3x(vptestmb, Vptestmb, X86KReg, X86Xmm, X86Xmm)                 //      AVX512_BW{k}-VL
+    4252             :   ASMJIT_INST_3x(vptestmb, Vptestmb, X86KReg, X86Xmm, X86Mem)                 //      AVX512_BW{k}-VL
+    4253             :   ASMJIT_INST_3x(vptestmb, Vptestmb, X86KReg, X86Ymm, X86Ymm)                 //      AVX512_BW{k}-VL
+    4254             :   ASMJIT_INST_3x(vptestmb, Vptestmb, X86KReg, X86Ymm, X86Mem)                 //      AVX512_BW{k}-VL
+    4255             :   ASMJIT_INST_3x(vptestmb, Vptestmb, X86KReg, X86Zmm, X86Zmm)                 //      AVX512_BW{k}
+    4256             :   ASMJIT_INST_3x(vptestmb, Vptestmb, X86KReg, X86Zmm, X86Mem)                 //      AVX512_BW{k}
+    4257             :   ASMJIT_INST_3x(vptestmd, Vptestmd, X86KReg, X86Xmm, X86Xmm)                 //      AVX512_F{k|b32}-VL
+    4258             :   ASMJIT_INST_3x(vptestmd, Vptestmd, X86KReg, X86Xmm, X86Mem)                 //      AVX512_F{k|b32}-VL
+    4259             :   ASMJIT_INST_3x(vptestmd, Vptestmd, X86KReg, X86Ymm, X86Ymm)                 //      AVX512_F{k|b32}-VL
+    4260             :   ASMJIT_INST_3x(vptestmd, Vptestmd, X86KReg, X86Ymm, X86Mem)                 //      AVX512_F{k|b32}-VL
+    4261             :   ASMJIT_INST_3x(vptestmd, Vptestmd, X86KReg, X86Zmm, X86Zmm)                 //      AVX512_F{k|b32}
+    4262             :   ASMJIT_INST_3x(vptestmd, Vptestmd, X86KReg, X86Zmm, X86Mem)                 //      AVX512_F{k|b32}
+    4263             :   ASMJIT_INST_3x(vptestmq, Vptestmq, X86KReg, X86Xmm, X86Xmm)                 //      AVX512_F{k|b64}-VL
+    4264             :   ASMJIT_INST_3x(vptestmq, Vptestmq, X86KReg, X86Xmm, X86Mem)                 //      AVX512_F{k|b64}-VL
+    4265             :   ASMJIT_INST_3x(vptestmq, Vptestmq, X86KReg, X86Ymm, X86Ymm)                 //      AVX512_F{k|b64}-VL
+    4266             :   ASMJIT_INST_3x(vptestmq, Vptestmq, X86KReg, X86Ymm, X86Mem)                 //      AVX512_F{k|b64}-VL
+    4267             :   ASMJIT_INST_3x(vptestmq, Vptestmq, X86KReg, X86Zmm, X86Zmm)                 //      AVX512_F{k|b64}
+    4268             :   ASMJIT_INST_3x(vptestmq, Vptestmq, X86KReg, X86Zmm, X86Mem)                 //      AVX512_F{k|b64}
+    4269             :   ASMJIT_INST_3x(vptestmw, Vptestmw, X86KReg, X86Xmm, X86Xmm)                 //      AVX512_BW{k}-VL
+    4270             :   ASMJIT_INST_3x(vptestmw, Vptestmw, X86KReg, X86Xmm, X86Mem)                 //      AVX512_BW{k}-VL
+    4271             :   ASMJIT_INST_3x(vptestmw, Vptestmw, X86KReg, X86Ymm, X86Ymm)                 //      AVX512_BW{k}-VL
+    4272             :   ASMJIT_INST_3x(vptestmw, Vptestmw, X86KReg, X86Ymm, X86Mem)                 //      AVX512_BW{k}-VL
+    4273             :   ASMJIT_INST_3x(vptestmw, Vptestmw, X86KReg, X86Zmm, X86Zmm)                 //      AVX512_BW{k}
+    4274             :   ASMJIT_INST_3x(vptestmw, Vptestmw, X86KReg, X86Zmm, X86Mem)                 //      AVX512_BW{k}
+    4275             :   ASMJIT_INST_3x(vptestnmb, Vptestnmb, X86KReg, X86Xmm, X86Xmm)               //      AVX512_BW{k}-VL
+    4276             :   ASMJIT_INST_3x(vptestnmb, Vptestnmb, X86KReg, X86Xmm, X86Mem)               //      AVX512_BW{k}-VL
+    4277             :   ASMJIT_INST_3x(vptestnmb, Vptestnmb, X86KReg, X86Ymm, X86Ymm)               //      AVX512_BW{k}-VL
+    4278             :   ASMJIT_INST_3x(vptestnmb, Vptestnmb, X86KReg, X86Ymm, X86Mem)               //      AVX512_BW{k}-VL
+    4279             :   ASMJIT_INST_3x(vptestnmb, Vptestnmb, X86KReg, X86Zmm, X86Zmm)               //      AVX512_BW{k}
+    4280             :   ASMJIT_INST_3x(vptestnmb, Vptestnmb, X86KReg, X86Zmm, X86Mem)               //      AVX512_BW{k}
+    4281             :   ASMJIT_INST_3x(vptestnmd, Vptestnmd, X86KReg, X86Xmm, X86Xmm)               //      AVX512_F{k|b32}-VL
+    4282             :   ASMJIT_INST_3x(vptestnmd, Vptestnmd, X86KReg, X86Xmm, X86Mem)               //      AVX512_F{k|b32}-VL
+    4283             :   ASMJIT_INST_3x(vptestnmd, Vptestnmd, X86KReg, X86Ymm, X86Ymm)               //      AVX512_F{k|b32}-VL
+    4284             :   ASMJIT_INST_3x(vptestnmd, Vptestnmd, X86KReg, X86Ymm, X86Mem)               //      AVX512_F{k|b32}-VL
+    4285             :   ASMJIT_INST_3x(vptestnmd, Vptestnmd, X86KReg, X86Zmm, X86Zmm)               //      AVX512_F{k|b32}
+    4286             :   ASMJIT_INST_3x(vptestnmd, Vptestnmd, X86KReg, X86Zmm, X86Mem)               //      AVX512_F{k|b32}
+    4287             :   ASMJIT_INST_3x(vptestnmq, Vptestnmq, X86KReg, X86Xmm, X86Xmm)               //      AVX512_F{k|b64}-VL
+    4288             :   ASMJIT_INST_3x(vptestnmq, Vptestnmq, X86KReg, X86Xmm, X86Mem)               //      AVX512_F{k|b64}-VL
+    4289             :   ASMJIT_INST_3x(vptestnmq, Vptestnmq, X86KReg, X86Ymm, X86Ymm)               //      AVX512_F{k|b64}-VL
+    4290             :   ASMJIT_INST_3x(vptestnmq, Vptestnmq, X86KReg, X86Ymm, X86Mem)               //      AVX512_F{k|b64}-VL
+    4291             :   ASMJIT_INST_3x(vptestnmq, Vptestnmq, X86KReg, X86Zmm, X86Zmm)               //      AVX512_F{k|b64}
+    4292             :   ASMJIT_INST_3x(vptestnmq, Vptestnmq, X86KReg, X86Zmm, X86Mem)               //      AVX512_F{k|b64}
+    4293             :   ASMJIT_INST_3x(vptestnmw, Vptestnmw, X86KReg, X86Xmm, X86Xmm)               //      AVX512_BW{k}-VL
+    4294             :   ASMJIT_INST_3x(vptestnmw, Vptestnmw, X86KReg, X86Xmm, X86Mem)               //      AVX512_BW{k}-VL
+    4295             :   ASMJIT_INST_3x(vptestnmw, Vptestnmw, X86KReg, X86Ymm, X86Ymm)               //      AVX512_BW{k}-VL
+    4296             :   ASMJIT_INST_3x(vptestnmw, Vptestnmw, X86KReg, X86Ymm, X86Mem)               //      AVX512_BW{k}-VL
+    4297             :   ASMJIT_INST_3x(vptestnmw, Vptestnmw, X86KReg, X86Zmm, X86Zmm)               //      AVX512_BW{k}
+    4298             :   ASMJIT_INST_3x(vptestnmw, Vptestnmw, X86KReg, X86Zmm, X86Mem)               //      AVX512_BW{k}
+    4299             :   ASMJIT_INST_3x(vpunpckhbw, Vpunpckhbw, X86Xmm, X86Xmm, X86Xmm)              // AVX  AVX512_BW{kz}-VL
+    4300             :   ASMJIT_INST_3x(vpunpckhbw, Vpunpckhbw, X86Xmm, X86Xmm, X86Mem)              // AVX  AVX512_BW{kz}-VL
+    4301             :   ASMJIT_INST_3x(vpunpckhbw, Vpunpckhbw, X86Ymm, X86Ymm, X86Ymm)              // AVX2 AVX512_BW{kz}-VL
+    4302             :   ASMJIT_INST_3x(vpunpckhbw, Vpunpckhbw, X86Ymm, X86Ymm, X86Mem)              // AVX2 AVX512_BW{kz}-VL
+    4303             :   ASMJIT_INST_3x(vpunpckhbw, Vpunpckhbw, X86Zmm, X86Zmm, X86Zmm)              //      AVX512_BW{kz}
+    4304             :   ASMJIT_INST_3x(vpunpckhbw, Vpunpckhbw, X86Zmm, X86Zmm, X86Mem)              //      AVX512_BW{kz}
+    4305             :   ASMJIT_INST_3x(vpunpckhdq, Vpunpckhdq, X86Xmm, X86Xmm, X86Xmm)              // AVX  AVX512_F{kz|b32}-VL
+    4306             :   ASMJIT_INST_3x(vpunpckhdq, Vpunpckhdq, X86Xmm, X86Xmm, X86Mem)              // AVX  AVX512_F{kz|b32}-VL
+    4307             :   ASMJIT_INST_3x(vpunpckhdq, Vpunpckhdq, X86Ymm, X86Ymm, X86Ymm)              // AVX2 AVX512_F{kz|b32}-VL
+    4308             :   ASMJIT_INST_3x(vpunpckhdq, Vpunpckhdq, X86Ymm, X86Ymm, X86Mem)              // AVX2 AVX512_F{kz|b32}-VL
+    4309             :   ASMJIT_INST_3x(vpunpckhdq, Vpunpckhdq, X86Zmm, X86Zmm, X86Zmm)              //      AVX512_F{kz|b32}
+    4310             :   ASMJIT_INST_3x(vpunpckhdq, Vpunpckhdq, X86Zmm, X86Zmm, X86Mem)              //      AVX512_F{kz|b32}
+    4311             :   ASMJIT_INST_3x(vpunpckhqdq, Vpunpckhqdq, X86Xmm, X86Xmm, X86Xmm)            // AVX  AVX512_F{kz|b64}-VL
+    4312             :   ASMJIT_INST_3x(vpunpckhqdq, Vpunpckhqdq, X86Xmm, X86Xmm, X86Mem)            // AVX  AVX512_F{kz|b64}-VL
+    4313             :   ASMJIT_INST_3x(vpunpckhqdq, Vpunpckhqdq, X86Ymm, X86Ymm, X86Ymm)            // AVX2 AVX512_F{kz|b64}-VL
+    4314             :   ASMJIT_INST_3x(vpunpckhqdq, Vpunpckhqdq, X86Ymm, X86Ymm, X86Mem)            // AVX2 AVX512_F{kz|b64}-VL
+    4315             :   ASMJIT_INST_3x(vpunpckhqdq, Vpunpckhqdq, X86Zmm, X86Zmm, X86Zmm)            //      AVX512_F{kz|b64}
+    4316             :   ASMJIT_INST_3x(vpunpckhqdq, Vpunpckhqdq, X86Zmm, X86Zmm, X86Mem)            //      AVX512_F{kz|b64}
+    4317             :   ASMJIT_INST_3x(vpunpckhwd, Vpunpckhwd, X86Xmm, X86Xmm, X86Xmm)              // AVX  AVX512_BW{kz}-VL
+    4318             :   ASMJIT_INST_3x(vpunpckhwd, Vpunpckhwd, X86Xmm, X86Xmm, X86Mem)              // AVX  AVX512_BW{kz}-VL
+    4319             :   ASMJIT_INST_3x(vpunpckhwd, Vpunpckhwd, X86Ymm, X86Ymm, X86Ymm)              // AVX2 AVX512_BW{kz}-VL
+    4320             :   ASMJIT_INST_3x(vpunpckhwd, Vpunpckhwd, X86Ymm, X86Ymm, X86Mem)              // AVX2 AVX512_BW{kz}-VL
+    4321             :   ASMJIT_INST_3x(vpunpckhwd, Vpunpckhwd, X86Zmm, X86Zmm, X86Zmm)              //      AVX512_BW{kz}
+    4322             :   ASMJIT_INST_3x(vpunpckhwd, Vpunpckhwd, X86Zmm, X86Zmm, X86Mem)              //      AVX512_BW{kz}
+    4323             :   ASMJIT_INST_3x(vpunpcklbw, Vpunpcklbw, X86Xmm, X86Xmm, X86Xmm)              // AVX  AVX512_BW{kz}-VL
+    4324             :   ASMJIT_INST_3x(vpunpcklbw, Vpunpcklbw, X86Xmm, X86Xmm, X86Mem)              // AVX  AVX512_BW{kz}-VL
+    4325             :   ASMJIT_INST_3x(vpunpcklbw, Vpunpcklbw, X86Ymm, X86Ymm, X86Ymm)              // AVX2 AVX512_BW{kz}-VL
+    4326             :   ASMJIT_INST_3x(vpunpcklbw, Vpunpcklbw, X86Ymm, X86Ymm, X86Mem)              // AVX2 AVX512_BW{kz}-VL
+    4327             :   ASMJIT_INST_3x(vpunpcklbw, Vpunpcklbw, X86Zmm, X86Zmm, X86Zmm)              //      AVX512_BW{kz}
+    4328             :   ASMJIT_INST_3x(vpunpcklbw, Vpunpcklbw, X86Zmm, X86Zmm, X86Mem)              //      AVX512_BW{kz}
+    4329             :   ASMJIT_INST_3x(vpunpckldq, Vpunpckldq, X86Xmm, X86Xmm, X86Xmm)              // AVX  AVX512_F{kz|b32}-VL
+    4330             :   ASMJIT_INST_3x(vpunpckldq, Vpunpckldq, X86Xmm, X86Xmm, X86Mem)              // AVX  AVX512_F{kz|b32}-VL
+    4331             :   ASMJIT_INST_3x(vpunpckldq, Vpunpckldq, X86Ymm, X86Ymm, X86Ymm)              // AVX2 AVX512_F{kz|b32}-VL
+    4332             :   ASMJIT_INST_3x(vpunpckldq, Vpunpckldq, X86Ymm, X86Ymm, X86Mem)              // AVX2 AVX512_F{kz|b32}-VL
+    4333             :   ASMJIT_INST_3x(vpunpckldq, Vpunpckldq, X86Zmm, X86Zmm, X86Zmm)              //      AVX512_F{kz|b32}
+    4334             :   ASMJIT_INST_3x(vpunpckldq, Vpunpckldq, X86Zmm, X86Zmm, X86Mem)              //      AVX512_F{kz|b32}
+    4335             :   ASMJIT_INST_3x(vpunpcklqdq, Vpunpcklqdq, X86Xmm, X86Xmm, X86Xmm)            // AVX  AVX512_F{kz|b64}-VL
+    4336             :   ASMJIT_INST_3x(vpunpcklqdq, Vpunpcklqdq, X86Xmm, X86Xmm, X86Mem)            // AVX  AVX512_F{kz|b64}-VL
+    4337             :   ASMJIT_INST_3x(vpunpcklqdq, Vpunpcklqdq, X86Ymm, X86Ymm, X86Ymm)            // AVX2 AVX512_F{kz|b64}-VL
+    4338             :   ASMJIT_INST_3x(vpunpcklqdq, Vpunpcklqdq, X86Ymm, X86Ymm, X86Mem)            // AVX2 AVX512_F{kz|b64}-VL
+    4339             :   ASMJIT_INST_3x(vpunpcklqdq, Vpunpcklqdq, X86Zmm, X86Zmm, X86Zmm)            //      AVX512_F{kz|b64}
+    4340             :   ASMJIT_INST_3x(vpunpcklqdq, Vpunpcklqdq, X86Zmm, X86Zmm, X86Mem)            //      AVX512_F{kz|b64}
+    4341             :   ASMJIT_INST_3x(vpunpcklwd, Vpunpcklwd, X86Xmm, X86Xmm, X86Xmm)              // AVX  AVX512_BW{kz}-VL
+    4342             :   ASMJIT_INST_3x(vpunpcklwd, Vpunpcklwd, X86Xmm, X86Xmm, X86Mem)              // AVX  AVX512_BW{kz}-VL
+    4343             :   ASMJIT_INST_3x(vpunpcklwd, Vpunpcklwd, X86Ymm, X86Ymm, X86Ymm)              // AVX2 AVX512_BW{kz}-VL
+    4344             :   ASMJIT_INST_3x(vpunpcklwd, Vpunpcklwd, X86Ymm, X86Ymm, X86Mem)              // AVX2 AVX512_BW{kz}-VL
+    4345             :   ASMJIT_INST_3x(vpunpcklwd, Vpunpcklwd, X86Zmm, X86Zmm, X86Zmm)              //      AVX512_BW{kz}
+    4346             :   ASMJIT_INST_3x(vpunpcklwd, Vpunpcklwd, X86Zmm, X86Zmm, X86Mem)              //      AVX512_BW{kz}
+    4347             :   ASMJIT_INST_3x(vpxor, Vpxor, X86Xmm, X86Xmm, X86Xmm)                        // AVX
+    4348             :   ASMJIT_INST_3x(vpxor, Vpxor, X86Xmm, X86Xmm, X86Mem)                        // AVX
+    4349             :   ASMJIT_INST_3x(vpxor, Vpxor, X86Ymm, X86Ymm, X86Ymm)                        // AVX2
+    4350             :   ASMJIT_INST_3x(vpxor, Vpxor, X86Ymm, X86Ymm, X86Mem)                        // AVX2
+    4351             :   ASMJIT_INST_3x(vpxord, Vpxord, X86Xmm, X86Xmm, X86Xmm)                      //      AVX512_F{kz|b32}-VL
+    4352             :   ASMJIT_INST_3x(vpxord, Vpxord, X86Xmm, X86Xmm, X86Mem)                      //      AVX512_F{kz|b32}-VL
+    4353             :   ASMJIT_INST_3x(vpxord, Vpxord, X86Ymm, X86Ymm, X86Ymm)                      //      AVX512_F{kz|b32}-VL
+    4354             :   ASMJIT_INST_3x(vpxord, Vpxord, X86Ymm, X86Ymm, X86Mem)                      //      AVX512_F{kz|b32}-VL
+    4355             :   ASMJIT_INST_3x(vpxord, Vpxord, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_F{kz|b32}
+    4356             :   ASMJIT_INST_3x(vpxord, Vpxord, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_F{kz|b32}
+    4357             :   ASMJIT_INST_3x(vpxorq, Vpxorq, X86Xmm, X86Xmm, X86Xmm)                      //      AVX512_F{kz|b64}-VL
+    4358             :   ASMJIT_INST_3x(vpxorq, Vpxorq, X86Xmm, X86Xmm, X86Mem)                      //      AVX512_F{kz|b64}-VL
+    4359             :   ASMJIT_INST_3x(vpxorq, Vpxorq, X86Ymm, X86Ymm, X86Ymm)                      //      AVX512_F{kz|b64}-VL
+    4360             :   ASMJIT_INST_3x(vpxorq, Vpxorq, X86Ymm, X86Ymm, X86Mem)                      //      AVX512_F{kz|b64}-VL
+    4361             :   ASMJIT_INST_3x(vpxorq, Vpxorq, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_F{kz|b64}
+    4362             :   ASMJIT_INST_3x(vpxorq, Vpxorq, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_F{kz|b64}
+    4363             :   ASMJIT_INST_4i(vrangepd, Vrangepd, X86Xmm, X86Xmm, X86Xmm, Imm)             //      AVX512_DQ{kz|b64}-VL
+    4364             :   ASMJIT_INST_4i(vrangepd, Vrangepd, X86Xmm, X86Xmm, X86Mem, Imm)             //      AVX512_DQ{kz|b64}-VL
+    4365             :   ASMJIT_INST_4i(vrangepd, Vrangepd, X86Ymm, X86Ymm, X86Ymm, Imm)             //      AVX512_DQ{kz|b64}-VL
+    4366             :   ASMJIT_INST_4i(vrangepd, Vrangepd, X86Ymm, X86Ymm, X86Mem, Imm)             //      AVX512_DQ{kz|b64}-VL
+    4367             :   ASMJIT_INST_4i(vrangepd, Vrangepd, X86Zmm, X86Zmm, X86Zmm, Imm)             //      AVX512_DQ{kz|sae|b64}
+    4368             :   ASMJIT_INST_4i(vrangepd, Vrangepd, X86Zmm, X86Zmm, X86Mem, Imm)             //      AVX512_DQ{kz|sae|b64}
+    4369             :   ASMJIT_INST_4i(vrangeps, Vrangeps, X86Xmm, X86Xmm, X86Xmm, Imm)             //      AVX512_DQ{kz|b32}-VL
+    4370             :   ASMJIT_INST_4i(vrangeps, Vrangeps, X86Xmm, X86Xmm, X86Mem, Imm)             //      AVX512_DQ{kz|b32}-VL
+    4371             :   ASMJIT_INST_4i(vrangeps, Vrangeps, X86Ymm, X86Ymm, X86Ymm, Imm)             //      AVX512_DQ{kz|b32}-VL
+    4372             :   ASMJIT_INST_4i(vrangeps, Vrangeps, X86Ymm, X86Ymm, X86Mem, Imm)             //      AVX512_DQ{kz|b32}-VL
+    4373             :   ASMJIT_INST_4i(vrangeps, Vrangeps, X86Zmm, X86Zmm, X86Zmm, Imm)             //      AVX512_DQ{kz|sae|b32}
+    4374             :   ASMJIT_INST_4i(vrangeps, Vrangeps, X86Zmm, X86Zmm, X86Mem, Imm)             //      AVX512_DQ{kz|sae|b32}
+    4375             :   ASMJIT_INST_4i(vrangesd, Vrangesd, X86Xmm, X86Xmm, X86Xmm, Imm)             //      AVX512_DQ{kz|sae}
+    4376             :   ASMJIT_INST_4i(vrangesd, Vrangesd, X86Xmm, X86Xmm, X86Mem, Imm)             //      AVX512_DQ{kz|sae}
+    4377             :   ASMJIT_INST_4i(vrangess, Vrangess, X86Xmm, X86Xmm, X86Xmm, Imm)             //      AVX512_DQ{kz|sae}
+    4378             :   ASMJIT_INST_4i(vrangess, Vrangess, X86Xmm, X86Xmm, X86Mem, Imm)             //      AVX512_DQ{kz|sae}
+    4379             :   ASMJIT_INST_2x(vrcp14pd, Vrcp14pd, X86Xmm, X86Xmm)                          //      AVX512_F{kz|b64}-VL
+    4380             :   ASMJIT_INST_2x(vrcp14pd, Vrcp14pd, X86Xmm, X86Mem)                          //      AVX512_F{kz|b64}-VL
+    4381             :   ASMJIT_INST_2x(vrcp14pd, Vrcp14pd, X86Ymm, X86Ymm)                          //      AVX512_F{kz|b64}-VL
+    4382             :   ASMJIT_INST_2x(vrcp14pd, Vrcp14pd, X86Ymm, X86Mem)                          //      AVX512_F{kz|b64}-VL
+    4383             :   ASMJIT_INST_2x(vrcp14pd, Vrcp14pd, X86Zmm, X86Zmm)                          //      AVX512_F{kz|b64}
+    4384             :   ASMJIT_INST_2x(vrcp14pd, Vrcp14pd, X86Zmm, X86Mem)                          //      AVX512_F{kz|b64}
+    4385             :   ASMJIT_INST_2x(vrcp14ps, Vrcp14ps, X86Xmm, X86Xmm)                          //      AVX512_F{kz|b32}-VL
+    4386             :   ASMJIT_INST_2x(vrcp14ps, Vrcp14ps, X86Xmm, X86Mem)                          //      AVX512_F{kz|b32}-VL
+    4387             :   ASMJIT_INST_2x(vrcp14ps, Vrcp14ps, X86Ymm, X86Ymm)                          //      AVX512_F{kz|b32}-VL
+    4388             :   ASMJIT_INST_2x(vrcp14ps, Vrcp14ps, X86Ymm, X86Mem)                          //      AVX512_F{kz|b32}-VL
+    4389             :   ASMJIT_INST_2x(vrcp14ps, Vrcp14ps, X86Zmm, X86Zmm)                          //      AVX512_F{kz|b32}
+    4390             :   ASMJIT_INST_2x(vrcp14ps, Vrcp14ps, X86Zmm, X86Mem)                          //      AVX512_F{kz|b32}
+    4391             :   ASMJIT_INST_3x(vrcp14sd, Vrcp14sd, X86Xmm, X86Xmm, X86Xmm)                  //      AVX512_F{kz}
+    4392             :   ASMJIT_INST_3x(vrcp14sd, Vrcp14sd, X86Xmm, X86Xmm, X86Mem)                  //      AVX512_F{kz}
+    4393             :   ASMJIT_INST_3x(vrcp14ss, Vrcp14ss, X86Xmm, X86Xmm, X86Xmm)                  //      AVX512_F{kz}
+    4394             :   ASMJIT_INST_3x(vrcp14ss, Vrcp14ss, X86Xmm, X86Xmm, X86Mem)                  //      AVX512_F{kz}
+    4395             :   ASMJIT_INST_2x(vrcp28pd, Vrcp28pd, X86Zmm, X86Zmm)                          //      AVX512_ER{kz|sae|b64}
+    4396             :   ASMJIT_INST_2x(vrcp28pd, Vrcp28pd, X86Zmm, X86Mem)                          //      AVX512_ER{kz|sae|b64}
+    4397             :   ASMJIT_INST_2x(vrcp28ps, Vrcp28ps, X86Zmm, X86Zmm)                          //      AVX512_ER{kz|sae|b32}
+    4398             :   ASMJIT_INST_2x(vrcp28ps, Vrcp28ps, X86Zmm, X86Mem)                          //      AVX512_ER{kz|sae|b32}
+    4399             :   ASMJIT_INST_3x(vrcp28sd, Vrcp28sd, X86Xmm, X86Xmm, X86Xmm)                  //      AVX512_ER{kz|sae}
+    4400             :   ASMJIT_INST_3x(vrcp28sd, Vrcp28sd, X86Xmm, X86Xmm, X86Mem)                  //      AVX512_ER{kz|sae}
+    4401             :   ASMJIT_INST_3x(vrcp28ss, Vrcp28ss, X86Xmm, X86Xmm, X86Xmm)                  //      AVX512_ER{kz|sae}
+    4402             :   ASMJIT_INST_3x(vrcp28ss, Vrcp28ss, X86Xmm, X86Xmm, X86Mem)                  //      AVX512_ER{kz|sae}
+    4403             :   ASMJIT_INST_2x(vrcpps, Vrcpps, X86Xmm, X86Xmm)                              // AVX
+    4404             :   ASMJIT_INST_2x(vrcpps, Vrcpps, X86Xmm, X86Mem)                              // AVX
+    4405             :   ASMJIT_INST_2x(vrcpps, Vrcpps, X86Ymm, X86Ymm)                              // AVX
+    4406             :   ASMJIT_INST_2x(vrcpps, Vrcpps, X86Ymm, X86Mem)                              // AVX
+    4407             :   ASMJIT_INST_3x(vrcpss, Vrcpss, X86Xmm, X86Xmm, X86Xmm)                      // AVX
+    4408             :   ASMJIT_INST_3x(vrcpss, Vrcpss, X86Xmm, X86Xmm, X86Mem)                      // AVX
+    4409             :   ASMJIT_INST_3i(vreducepd, Vreducepd, X86Xmm, X86Xmm, Imm)                   //      AVX512_DQ{kz|b64}-VL
+    4410             :   ASMJIT_INST_3i(vreducepd, Vreducepd, X86Xmm, X86Mem, Imm)                   //      AVX512_DQ{kz|b64}-VL
+    4411             :   ASMJIT_INST_3i(vreducepd, Vreducepd, X86Ymm, X86Ymm, Imm)                   //      AVX512_DQ{kz|b64}-VL
+    4412             :   ASMJIT_INST_3i(vreducepd, Vreducepd, X86Ymm, X86Mem, Imm)                   //      AVX512_DQ{kz|b64}-VL
+    4413             :   ASMJIT_INST_3i(vreducepd, Vreducepd, X86Zmm, X86Zmm, Imm)                   //      AVX512_DQ{kz|b64}
+    4414             :   ASMJIT_INST_3i(vreducepd, Vreducepd, X86Zmm, X86Mem, Imm)                   //      AVX512_DQ{kz|b64}
+    4415             :   ASMJIT_INST_3i(vreduceps, Vreduceps, X86Xmm, X86Xmm, Imm)                   //      AVX512_DQ{kz|b32}-VL
+    4416             :   ASMJIT_INST_3i(vreduceps, Vreduceps, X86Xmm, X86Mem, Imm)                   //      AVX512_DQ{kz|b32}-VL
+    4417             :   ASMJIT_INST_3i(vreduceps, Vreduceps, X86Ymm, X86Ymm, Imm)                   //      AVX512_DQ{kz|b32}-VL
+    4418             :   ASMJIT_INST_3i(vreduceps, Vreduceps, X86Ymm, X86Mem, Imm)                   //      AVX512_DQ{kz|b32}-VL
+    4419             :   ASMJIT_INST_3i(vreduceps, Vreduceps, X86Zmm, X86Zmm, Imm)                   //      AVX512_DQ{kz|b32}
+    4420             :   ASMJIT_INST_3i(vreduceps, Vreduceps, X86Zmm, X86Mem, Imm)                   //      AVX512_DQ{kz|b32}
+    4421             :   ASMJIT_INST_4i(vreducesd, Vreducesd, X86Xmm, X86Xmm, X86Xmm, Imm)           //      AVX512_DQ{kz}
+    4422             :   ASMJIT_INST_4i(vreducesd, Vreducesd, X86Xmm, X86Xmm, X86Mem, Imm)           //      AVX512_DQ{kz}
+    4423             :   ASMJIT_INST_4i(vreducess, Vreducess, X86Xmm, X86Xmm, X86Xmm, Imm)           //      AVX512_DQ{kz}
+    4424             :   ASMJIT_INST_4i(vreducess, Vreducess, X86Xmm, X86Xmm, X86Mem, Imm)           //      AVX512_DQ{kz}
+    4425             :   ASMJIT_INST_3i(vrndscalepd, Vrndscalepd, X86Xmm, X86Xmm, Imm)               //      AVX512_F{kz|b64}-VL
+    4426             :   ASMJIT_INST_3i(vrndscalepd, Vrndscalepd, X86Xmm, X86Mem, Imm)               //      AVX512_F{kz|b64}-VL
+    4427             :   ASMJIT_INST_3i(vrndscalepd, Vrndscalepd, X86Ymm, X86Ymm, Imm)               //      AVX512_F{kz|b64}-VL
+    4428             :   ASMJIT_INST_3i(vrndscalepd, Vrndscalepd, X86Ymm, X86Mem, Imm)               //      AVX512_F{kz|b64}-VL
+    4429             :   ASMJIT_INST_3i(vrndscalepd, Vrndscalepd, X86Zmm, X86Zmm, Imm)               //      AVX512_F{kz|sae|b64}
+    4430             :   ASMJIT_INST_3i(vrndscalepd, Vrndscalepd, X86Zmm, X86Mem, Imm)               //      AVX512_F{kz|sae|b64}
+    4431             :   ASMJIT_INST_3i(vrndscaleps, Vrndscaleps, X86Xmm, X86Xmm, Imm)               //      AVX512_F{kz|b32}-VL
+    4432             :   ASMJIT_INST_3i(vrndscaleps, Vrndscaleps, X86Xmm, X86Mem, Imm)               //      AVX512_F{kz|b32}-VL
+    4433             :   ASMJIT_INST_3i(vrndscaleps, Vrndscaleps, X86Ymm, X86Ymm, Imm)               //      AVX512_F{kz|b32}-VL
+    4434             :   ASMJIT_INST_3i(vrndscaleps, Vrndscaleps, X86Ymm, X86Mem, Imm)               //      AVX512_F{kz|b32}-VL
+    4435             :   ASMJIT_INST_3i(vrndscaleps, Vrndscaleps, X86Zmm, X86Zmm, Imm)               //      AVX512_F{kz|sae|b32}
+    4436             :   ASMJIT_INST_3i(vrndscaleps, Vrndscaleps, X86Zmm, X86Mem, Imm)               //      AVX512_F{kz|sae|b32}
+    4437             :   ASMJIT_INST_4i(vrndscalesd, Vrndscalesd, X86Xmm, X86Xmm, X86Xmm, Imm)       //      AVX512_F{kz|sae}
+    4438             :   ASMJIT_INST_4i(vrndscalesd, Vrndscalesd, X86Xmm, X86Xmm, X86Mem, Imm)       //      AVX512_F{kz|sae}
+    4439             :   ASMJIT_INST_4i(vrndscaless, Vrndscaless, X86Xmm, X86Xmm, X86Xmm, Imm)       //      AVX512_F{kz|sae}
+    4440             :   ASMJIT_INST_4i(vrndscaless, Vrndscaless, X86Xmm, X86Xmm, X86Mem, Imm)       //      AVX512_F{kz|sae}
+    4441             :   ASMJIT_INST_3i(vroundpd, Vroundpd, X86Xmm, X86Xmm, Imm)                     // AVX
+    4442             :   ASMJIT_INST_3i(vroundpd, Vroundpd, X86Xmm, X86Mem, Imm)                     // AVX
+    4443             :   ASMJIT_INST_3i(vroundpd, Vroundpd, X86Ymm, X86Ymm, Imm)                     // AVX
+    4444             :   ASMJIT_INST_3i(vroundpd, Vroundpd, X86Ymm, X86Mem, Imm)                     // AVX
+    4445             :   ASMJIT_INST_3i(vroundps, Vroundps, X86Xmm, X86Xmm, Imm)                     // AVX
+    4446             :   ASMJIT_INST_3i(vroundps, Vroundps, X86Xmm, X86Mem, Imm)                     // AVX
+    4447             :   ASMJIT_INST_3i(vroundps, Vroundps, X86Ymm, X86Ymm, Imm)                     // AVX
+    4448             :   ASMJIT_INST_3i(vroundps, Vroundps, X86Ymm, X86Mem, Imm)                     // AVX
+    4449             :   ASMJIT_INST_4i(vroundsd, Vroundsd, X86Xmm, X86Xmm, X86Xmm, Imm)             // AVX
+    4450             :   ASMJIT_INST_4i(vroundsd, Vroundsd, X86Xmm, X86Xmm, X86Mem, Imm)             // AVX
+    4451             :   ASMJIT_INST_4i(vroundss, Vroundss, X86Xmm, X86Xmm, X86Xmm, Imm)             // AVX
+    4452             :   ASMJIT_INST_4i(vroundss, Vroundss, X86Xmm, X86Xmm, X86Mem, Imm)             // AVX
+    4453             :   ASMJIT_INST_2x(vrsqrt14pd, Vrsqrt14pd, X86Xmm, X86Xmm)                      //      AVX512_F{kz|b64}-VL
+    4454             :   ASMJIT_INST_2x(vrsqrt14pd, Vrsqrt14pd, X86Xmm, X86Mem)                      //      AVX512_F{kz|b64}-VL
+    4455             :   ASMJIT_INST_2x(vrsqrt14pd, Vrsqrt14pd, X86Ymm, X86Ymm)                      //      AVX512_F{kz|b64}-VL
+    4456             :   ASMJIT_INST_2x(vrsqrt14pd, Vrsqrt14pd, X86Ymm, X86Mem)                      //      AVX512_F{kz|b64}-VL
+    4457             :   ASMJIT_INST_2x(vrsqrt14pd, Vrsqrt14pd, X86Zmm, X86Zmm)                      //      AVX512_F{kz|b64}
+    4458             :   ASMJIT_INST_2x(vrsqrt14pd, Vrsqrt14pd, X86Zmm, X86Mem)                      //      AVX512_F{kz|b64}
+    4459             :   ASMJIT_INST_2x(vrsqrt14ps, Vrsqrt14ps, X86Xmm, X86Xmm)                      //      AVX512_F{kz|b32}-VL
+    4460             :   ASMJIT_INST_2x(vrsqrt14ps, Vrsqrt14ps, X86Xmm, X86Mem)                      //      AVX512_F{kz|b32}-VL
+    4461             :   ASMJIT_INST_2x(vrsqrt14ps, Vrsqrt14ps, X86Ymm, X86Ymm)                      //      AVX512_F{kz|b32}-VL
+    4462             :   ASMJIT_INST_2x(vrsqrt14ps, Vrsqrt14ps, X86Ymm, X86Mem)                      //      AVX512_F{kz|b32}-VL
+    4463             :   ASMJIT_INST_2x(vrsqrt14ps, Vrsqrt14ps, X86Zmm, X86Zmm)                      //      AVX512_F{kz|b32}
+    4464             :   ASMJIT_INST_2x(vrsqrt14ps, Vrsqrt14ps, X86Zmm, X86Mem)                      //      AVX512_F{kz|b32}
+    4465             :   ASMJIT_INST_3x(vrsqrt14sd, Vrsqrt14sd, X86Xmm, X86Xmm, X86Xmm)              //      AVX512_F{kz}
+    4466             :   ASMJIT_INST_3x(vrsqrt14sd, Vrsqrt14sd, X86Xmm, X86Xmm, X86Mem)              //      AVX512_F{kz}
+    4467             :   ASMJIT_INST_3x(vrsqrt14ss, Vrsqrt14ss, X86Xmm, X86Xmm, X86Xmm)              //      AVX512_F{kz}
+    4468             :   ASMJIT_INST_3x(vrsqrt14ss, Vrsqrt14ss, X86Xmm, X86Xmm, X86Mem)              //      AVX512_F{kz}
+    4469             :   ASMJIT_INST_2x(vrsqrt28pd, Vrsqrt28pd, X86Zmm, X86Zmm)                      //      AVX512_ER{kz|sae|b64}
+    4470             :   ASMJIT_INST_2x(vrsqrt28pd, Vrsqrt28pd, X86Zmm, X86Mem)                      //      AVX512_ER{kz|sae|b64}
+    4471             :   ASMJIT_INST_2x(vrsqrt28ps, Vrsqrt28ps, X86Zmm, X86Zmm)                      //      AVX512_ER{kz|sae|b32}
+    4472             :   ASMJIT_INST_2x(vrsqrt28ps, Vrsqrt28ps, X86Zmm, X86Mem)                      //      AVX512_ER{kz|sae|b32}
+    4473             :   ASMJIT_INST_3x(vrsqrt28sd, Vrsqrt28sd, X86Xmm, X86Xmm, X86Xmm)              //      AVX512_ER{kz|sae}
+    4474             :   ASMJIT_INST_3x(vrsqrt28sd, Vrsqrt28sd, X86Xmm, X86Xmm, X86Mem)              //      AVX512_ER{kz|sae}
+    4475             :   ASMJIT_INST_3x(vrsqrt28ss, Vrsqrt28ss, X86Xmm, X86Xmm, X86Xmm)              //      AVX512_ER{kz|sae}
+    4476             :   ASMJIT_INST_3x(vrsqrt28ss, Vrsqrt28ss, X86Xmm, X86Xmm, X86Mem)              //      AVX512_ER{kz|sae}
+    4477             :   ASMJIT_INST_2x(vrsqrtps, Vrsqrtps, X86Xmm, X86Xmm)                          // AVX
+    4478             :   ASMJIT_INST_2x(vrsqrtps, Vrsqrtps, X86Xmm, X86Mem)                          // AVX
+    4479             :   ASMJIT_INST_2x(vrsqrtps, Vrsqrtps, X86Ymm, X86Ymm)                          // AVX
+    4480             :   ASMJIT_INST_2x(vrsqrtps, Vrsqrtps, X86Ymm, X86Mem)                          // AVX
+    4481             :   ASMJIT_INST_3x(vrsqrtss, Vrsqrtss, X86Xmm, X86Xmm, X86Xmm)                  // AVX
+    4482             :   ASMJIT_INST_3x(vrsqrtss, Vrsqrtss, X86Xmm, X86Xmm, X86Mem)                  // AVX
+    4483             :   ASMJIT_INST_3x(vscalefpd, Vscalefpd, X86Xmm, X86Xmm, X86Xmm)                //      AVX512_F{kz|b64}-VL
+    4484             :   ASMJIT_INST_3x(vscalefpd, Vscalefpd, X86Xmm, X86Xmm, X86Mem)                //      AVX512_F{kz|b64}-VL
+    4485             :   ASMJIT_INST_3x(vscalefpd, Vscalefpd, X86Ymm, X86Ymm, X86Ymm)                //      AVX512_F{kz|b64}-VL
+    4486             :   ASMJIT_INST_3x(vscalefpd, Vscalefpd, X86Ymm, X86Ymm, X86Mem)                //      AVX512_F{kz|b64}-VL
+    4487             :   ASMJIT_INST_3x(vscalefpd, Vscalefpd, X86Zmm, X86Zmm, X86Zmm)                //      AVX512_F{kz|er|b64}
+    4488             :   ASMJIT_INST_3x(vscalefpd, Vscalefpd, X86Zmm, X86Zmm, X86Mem)                //      AVX512_F{kz|er|b64}
+    4489             :   ASMJIT_INST_3x(vscalefps, Vscalefps, X86Xmm, X86Xmm, X86Xmm)                //      AVX512_F{kz|b32}-VL
+    4490             :   ASMJIT_INST_3x(vscalefps, Vscalefps, X86Xmm, X86Xmm, X86Mem)                //      AVX512_F{kz|b32}-VL
+    4491             :   ASMJIT_INST_3x(vscalefps, Vscalefps, X86Ymm, X86Ymm, X86Ymm)                //      AVX512_F{kz|b32}-VL
+    4492             :   ASMJIT_INST_3x(vscalefps, Vscalefps, X86Ymm, X86Ymm, X86Mem)                //      AVX512_F{kz|b32}-VL
+    4493             :   ASMJIT_INST_3x(vscalefps, Vscalefps, X86Zmm, X86Zmm, X86Zmm)                //      AVX512_F{kz|er|b32}
+    4494             :   ASMJIT_INST_3x(vscalefps, Vscalefps, X86Zmm, X86Zmm, X86Mem)                //      AVX512_F{kz|er|b32}
+    4495             :   ASMJIT_INST_3x(vscalefsd, Vscalefsd, X86Xmm, X86Xmm, X86Xmm)                //      AVX512_F{kz|er}
+    4496             :   ASMJIT_INST_3x(vscalefsd, Vscalefsd, X86Xmm, X86Xmm, X86Mem)                //      AVX512_F{kz|er}
+    4497             :   ASMJIT_INST_3x(vscalefss, Vscalefss, X86Xmm, X86Xmm, X86Xmm)                //      AVX512_F{kz|er}
+    4498             :   ASMJIT_INST_3x(vscalefss, Vscalefss, X86Xmm, X86Xmm, X86Mem)                //      AVX512_F{kz|er}
+    4499             :   ASMJIT_INST_2x(vscatterdpd, Vscatterdpd, X86Mem, X86Xmm)                    //      AVX512_F{k}-VL
+    4500             :   ASMJIT_INST_2x(vscatterdpd, Vscatterdpd, X86Mem, X86Ymm)                    //      AVX512_F{k}-VL
+    4501             :   ASMJIT_INST_2x(vscatterdpd, Vscatterdpd, X86Mem, X86Zmm)                    //      AVX512_F{k}
+    4502             :   ASMJIT_INST_2x(vscatterdps, Vscatterdps, X86Mem, X86Xmm)                    //      AVX512_F{k}-VL
+    4503             :   ASMJIT_INST_2x(vscatterdps, Vscatterdps, X86Mem, X86Ymm)                    //      AVX512_F{k}-VL
+    4504             :   ASMJIT_INST_2x(vscatterdps, Vscatterdps, X86Mem, X86Zmm)                    //      AVX512_F{k}
+    4505             :   ASMJIT_INST_1x(vscatterpf0dpd, Vscatterpf0dpd, X86Mem)                      //      AVX512_PF{k}
+    4506             :   ASMJIT_INST_1x(vscatterpf0dps, Vscatterpf0dps, X86Mem)                      //      AVX512_PF{k}
+    4507             :   ASMJIT_INST_1x(vscatterpf0qpd, Vscatterpf0qpd, X86Mem)                      //      AVX512_PF{k}
+    4508             :   ASMJIT_INST_1x(vscatterpf0qps, Vscatterpf0qps, X86Mem)                      //      AVX512_PF{k}
+    4509             :   ASMJIT_INST_1x(vscatterpf1dpd, Vscatterpf1dpd, X86Mem)                      //      AVX512_PF{k}
+    4510             :   ASMJIT_INST_1x(vscatterpf1dps, Vscatterpf1dps, X86Mem)                      //      AVX512_PF{k}
+    4511             :   ASMJIT_INST_1x(vscatterpf1qpd, Vscatterpf1qpd, X86Mem)                      //      AVX512_PF{k}
+    4512             :   ASMJIT_INST_1x(vscatterpf1qps, Vscatterpf1qps, X86Mem)                      //      AVX512_PF{k}
+    4513             :   ASMJIT_INST_2x(vscatterqpd, Vscatterqpd, X86Mem, X86Xmm)                    //      AVX512_F{k}-VL
+    4514             :   ASMJIT_INST_2x(vscatterqpd, Vscatterqpd, X86Mem, X86Ymm)                    //      AVX512_F{k}-VL
+    4515             :   ASMJIT_INST_2x(vscatterqpd, Vscatterqpd, X86Mem, X86Zmm)                    //      AVX512_F{k}
+    4516             :   ASMJIT_INST_2x(vscatterqps, Vscatterqps, X86Mem, X86Xmm)                    //      AVX512_F{k}-VL
+    4517             :   ASMJIT_INST_2x(vscatterqps, Vscatterqps, X86Mem, X86Ymm)                    //      AVX512_F{k}
+    4518             :   ASMJIT_INST_4i(vshuff32x4, Vshuff32x4, X86Ymm, X86Ymm, X86Ymm, Imm)         //      AVX512_F{kz|b32}-VL
+    4519             :   ASMJIT_INST_4i(vshuff32x4, Vshuff32x4, X86Ymm, X86Ymm, X86Mem, Imm)         //      AVX512_F{kz|b32}-VL
+    4520             :   ASMJIT_INST_4i(vshuff32x4, Vshuff32x4, X86Zmm, X86Zmm, X86Zmm, Imm)         //      AVX512_F{kz|b32}
+    4521             :   ASMJIT_INST_4i(vshuff32x4, Vshuff32x4, X86Zmm, X86Zmm, X86Mem, Imm)         //      AVX512_F{kz|b32}
+    4522             :   ASMJIT_INST_4i(vshuff64x2, Vshuff64x2, X86Ymm, X86Ymm, X86Ymm, Imm)         //      AVX512_F{kz|b64}-VL
+    4523             :   ASMJIT_INST_4i(vshuff64x2, Vshuff64x2, X86Ymm, X86Ymm, X86Mem, Imm)         //      AVX512_F{kz|b64}-VL
+    4524             :   ASMJIT_INST_4i(vshuff64x2, Vshuff64x2, X86Zmm, X86Zmm, X86Zmm, Imm)         //      AVX512_F{kz|b64}
+    4525             :   ASMJIT_INST_4i(vshuff64x2, Vshuff64x2, X86Zmm, X86Zmm, X86Mem, Imm)         //      AVX512_F{kz|b64}
+    4526             :   ASMJIT_INST_4i(vshufi32x4, Vshufi32x4, X86Ymm, X86Ymm, X86Ymm, Imm)         //      AVX512_F{kz|b32}-VL
+    4527             :   ASMJIT_INST_4i(vshufi32x4, Vshufi32x4, X86Ymm, X86Ymm, X86Mem, Imm)         //      AVX512_F{kz|b32}-VL
+    4528             :   ASMJIT_INST_4i(vshufi32x4, Vshufi32x4, X86Zmm, X86Zmm, X86Zmm, Imm)         //      AVX512_F{kz|b32}
+    4529             :   ASMJIT_INST_4i(vshufi32x4, Vshufi32x4, X86Zmm, X86Zmm, X86Mem, Imm)         //      AVX512_F{kz|b32}
+    4530             :   ASMJIT_INST_4i(vshufi64x2, Vshufi64x2, X86Ymm, X86Ymm, X86Ymm, Imm)         //      AVX512_F{kz|b64}-VL
+    4531             :   ASMJIT_INST_4i(vshufi64x2, Vshufi64x2, X86Ymm, X86Ymm, X86Mem, Imm)         //      AVX512_F{kz|b64}-VL
+    4532             :   ASMJIT_INST_4i(vshufi64x2, Vshufi64x2, X86Zmm, X86Zmm, X86Zmm, Imm)         //      AVX512_F{kz|b64}
+    4533             :   ASMJIT_INST_4i(vshufi64x2, Vshufi64x2, X86Zmm, X86Zmm, X86Mem, Imm)         //      AVX512_F{kz|b64}
+    4534             :   ASMJIT_INST_4i(vshufpd, Vshufpd, X86Xmm, X86Xmm, X86Xmm, Imm)               // AVX  AVX512_F{kz|b32}-VL
+    4535             :   ASMJIT_INST_4i(vshufpd, Vshufpd, X86Xmm, X86Xmm, X86Mem, Imm)               // AVX  AVX512_F{kz|b32}-VL
+    4536             :   ASMJIT_INST_4i(vshufpd, Vshufpd, X86Ymm, X86Ymm, X86Ymm, Imm)               // AVX  AVX512_F{kz|b32}-VL
+    4537             :   ASMJIT_INST_4i(vshufpd, Vshufpd, X86Ymm, X86Ymm, X86Mem, Imm)               // AVX  AVX512_F{kz|b32}-VL
+    4538             :   ASMJIT_INST_4i(vshufpd, Vshufpd, X86Zmm, X86Zmm, X86Zmm, Imm)               //      AVX512_F{kz|b32}
+    4539             :   ASMJIT_INST_4i(vshufpd, Vshufpd, X86Zmm, X86Zmm, X86Mem, Imm)               //      AVX512_F{kz|b32}
+    4540             :   ASMJIT_INST_4i(vshufps, Vshufps, X86Xmm, X86Xmm, X86Xmm, Imm)               // AVX  AVX512_F{kz|b64}-VL
+    4541             :   ASMJIT_INST_4i(vshufps, Vshufps, X86Xmm, X86Xmm, X86Mem, Imm)               // AVX  AVX512_F{kz|b64}-VL
+    4542             :   ASMJIT_INST_4i(vshufps, Vshufps, X86Ymm, X86Ymm, X86Ymm, Imm)               // AVX  AVX512_F{kz|b64}-VL
+    4543             :   ASMJIT_INST_4i(vshufps, Vshufps, X86Ymm, X86Ymm, X86Mem, Imm)               // AVX  AVX512_F{kz|b64}-VL
+    4544             :   ASMJIT_INST_4i(vshufps, Vshufps, X86Zmm, X86Zmm, X86Zmm, Imm)               //      AVX512_F{kz|b64}
+    4545             :   ASMJIT_INST_4i(vshufps, Vshufps, X86Zmm, X86Zmm, X86Mem, Imm)               //      AVX512_F{kz|b64}
+    4546             :   ASMJIT_INST_2x(vsqrtpd, Vsqrtpd, X86Xmm, X86Xmm)                            // AVX  AVX512_F{kz|b64}-VL
+    4547             :   ASMJIT_INST_2x(vsqrtpd, Vsqrtpd, X86Xmm, X86Mem)                            // AVX  AVX512_F{kz|b64}-VL
+    4548             :   ASMJIT_INST_2x(vsqrtpd, Vsqrtpd, X86Ymm, X86Ymm)                            // AVX  AVX512_F{kz|b64}-VL
+    4549             :   ASMJIT_INST_2x(vsqrtpd, Vsqrtpd, X86Ymm, X86Mem)                            // AVX  AVX512_F{kz|b64}-VL
+    4550             :   ASMJIT_INST_2x(vsqrtpd, Vsqrtpd, X86Zmm, X86Zmm)                            //      AVX512_F{kz|er|b64}
+    4551             :   ASMJIT_INST_2x(vsqrtpd, Vsqrtpd, X86Zmm, X86Mem)                            //      AVX512_F{kz|er|b64}
+    4552             :   ASMJIT_INST_2x(vsqrtps, Vsqrtps, X86Xmm, X86Xmm)                            // AVX  AVX512_F{kz|b32}-VL
+    4553             :   ASMJIT_INST_2x(vsqrtps, Vsqrtps, X86Xmm, X86Mem)                            // AVX  AVX512_F{kz|b32}-VL
+    4554             :   ASMJIT_INST_2x(vsqrtps, Vsqrtps, X86Ymm, X86Ymm)                            // AVX  AVX512_F{kz|b32}-VL
+    4555             :   ASMJIT_INST_2x(vsqrtps, Vsqrtps, X86Ymm, X86Mem)                            // AVX  AVX512_F{kz|b32}-VL
+    4556             :   ASMJIT_INST_2x(vsqrtps, Vsqrtps, X86Zmm, X86Zmm)                            //      AVX512_F{kz|er|b32}
+    4557             :   ASMJIT_INST_2x(vsqrtps, Vsqrtps, X86Zmm, X86Mem)                            //      AVX512_F{kz|er|b32}
+    4558             :   ASMJIT_INST_3x(vsqrtsd, Vsqrtsd, X86Xmm, X86Xmm, X86Xmm)                    // AVX  AVX512_F{kz|er}
+    4559             :   ASMJIT_INST_3x(vsqrtsd, Vsqrtsd, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_F{kz|er}
+    4560             :   ASMJIT_INST_3x(vsqrtss, Vsqrtss, X86Xmm, X86Xmm, X86Xmm)                    // AVX  AVX512_F{kz|er}
+    4561             :   ASMJIT_INST_3x(vsqrtss, Vsqrtss, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_F{kz|er}
+    4562             :   ASMJIT_INST_1x(vstmxcsr, Vstmxcsr, X86Mem)                                  // AVX
+    4563             :   ASMJIT_INST_3x(vsubpd, Vsubpd, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|b64}-VL
+    4564             :   ASMJIT_INST_3x(vsubpd, Vsubpd, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|b64}-VL
+    4565             :   ASMJIT_INST_3x(vsubpd, Vsubpd, X86Ymm, X86Ymm, X86Ymm)                      // AVX2 AVX512_F{kz|b64}-VL
+    4566             :   ASMJIT_INST_3x(vsubpd, Vsubpd, X86Ymm, X86Ymm, X86Mem)                      // AVX2 AVX512_F{kz|b64}-VL
+    4567             :   ASMJIT_INST_3x(vsubpd, Vsubpd, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_F{kz|er|b64}
+    4568             :   ASMJIT_INST_3x(vsubpd, Vsubpd, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_F{kz|er|b64}
+    4569             :   ASMJIT_INST_3x(vsubps, Vsubps, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|b32}-VL
+    4570             :   ASMJIT_INST_3x(vsubps, Vsubps, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|b32}-VL
+    4571             :   ASMJIT_INST_3x(vsubps, Vsubps, X86Ymm, X86Ymm, X86Ymm)                      // AVX2 AVX512_F{kz|b32}-VL
+    4572             :   ASMJIT_INST_3x(vsubps, Vsubps, X86Ymm, X86Ymm, X86Mem)                      // AVX2 AVX512_F{kz|b32}-VL
+    4573             :   ASMJIT_INST_3x(vsubps, Vsubps, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_F{kz|er|b32}
+    4574             :   ASMJIT_INST_3x(vsubps, Vsubps, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_F{kz|er|b32}
+    4575             :   ASMJIT_INST_3x(vsubsd, Vsubsd, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|er}
+    4576             :   ASMJIT_INST_3x(vsubsd, Vsubsd, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|er}
+    4577             :   ASMJIT_INST_3x(vsubss, Vsubss, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|er}
+    4578             :   ASMJIT_INST_3x(vsubss, Vsubss, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|er}
+    4579             :   ASMJIT_INST_2x(vtestpd, Vtestpd, X86Xmm, X86Xmm)                            // AVX
+    4580             :   ASMJIT_INST_2x(vtestpd, Vtestpd, X86Xmm, X86Mem)                            // AVX
+    4581             :   ASMJIT_INST_2x(vtestpd, Vtestpd, X86Ymm, X86Ymm)                            // AVX
+    4582             :   ASMJIT_INST_2x(vtestpd, Vtestpd, X86Ymm, X86Mem)                            // AVX
+    4583             :   ASMJIT_INST_2x(vtestps, Vtestps, X86Xmm, X86Xmm)                            // AVX
+    4584             :   ASMJIT_INST_2x(vtestps, Vtestps, X86Xmm, X86Mem)                            // AVX
+    4585             :   ASMJIT_INST_2x(vtestps, Vtestps, X86Ymm, X86Ymm)                            // AVX
+    4586             :   ASMJIT_INST_2x(vtestps, Vtestps, X86Ymm, X86Mem)                            // AVX
+    4587             :   ASMJIT_INST_2x(vucomisd, Vucomisd, X86Xmm, X86Xmm)                          // AVX  AVX512_F{sae}
+    4588             :   ASMJIT_INST_2x(vucomisd, Vucomisd, X86Xmm, X86Mem)                          // AVX  AVX512_F{sae}
+    4589             :   ASMJIT_INST_2x(vucomiss, Vucomiss, X86Xmm, X86Xmm)                          // AVX  AVX512_F{sae}
+    4590             :   ASMJIT_INST_2x(vucomiss, Vucomiss, X86Xmm, X86Mem)                          // AVX  AVX512_F{sae}
+    4591             :   ASMJIT_INST_3x(vunpckhpd, Vunpckhpd, X86Xmm, X86Xmm, X86Xmm)                // AVX  AVX512_F{kz|b64}-VL
+    4592             :   ASMJIT_INST_3x(vunpckhpd, Vunpckhpd, X86Xmm, X86Xmm, X86Mem)                // AVX  AVX512_F{kz|b64}-VL
+    4593             :   ASMJIT_INST_3x(vunpckhpd, Vunpckhpd, X86Ymm, X86Ymm, X86Ymm)                // AVX  AVX512_F{kz|b64}-VL
+    4594             :   ASMJIT_INST_3x(vunpckhpd, Vunpckhpd, X86Ymm, X86Ymm, X86Mem)                // AVX  AVX512_F{kz|b64}-VL
+    4595             :   ASMJIT_INST_3x(vunpckhpd, Vunpckhpd, X86Zmm, X86Zmm, X86Zmm)                //      AVX512_F{kz|b64}
+    4596             :   ASMJIT_INST_3x(vunpckhpd, Vunpckhpd, X86Zmm, X86Zmm, X86Mem)                //      AVX512_F{kz|b64}
+    4597             :   ASMJIT_INST_3x(vunpckhps, Vunpckhps, X86Xmm, X86Xmm, X86Xmm)                // AVX  AVX512_F{kz|b32}-VL
+    4598             :   ASMJIT_INST_3x(vunpckhps, Vunpckhps, X86Xmm, X86Xmm, X86Mem)                // AVX  AVX512_F{kz|b32}-VL
+    4599             :   ASMJIT_INST_3x(vunpckhps, Vunpckhps, X86Ymm, X86Ymm, X86Ymm)                // AVX  AVX512_F{kz|b32}-VL
+    4600             :   ASMJIT_INST_3x(vunpckhps, Vunpckhps, X86Ymm, X86Ymm, X86Mem)                // AVX  AVX512_F{kz|b32}-VL
+    4601             :   ASMJIT_INST_3x(vunpckhps, Vunpckhps, X86Zmm, X86Zmm, X86Zmm)                //      AVX512_F{kz|b32}
+    4602             :   ASMJIT_INST_3x(vunpckhps, Vunpckhps, X86Zmm, X86Zmm, X86Mem)                //      AVX512_F{kz|b32}
+    4603             :   ASMJIT_INST_3x(vunpcklpd, Vunpcklpd, X86Xmm, X86Xmm, X86Xmm)                // AVX  AVX512_F{kz|b64}-VL
+    4604             :   ASMJIT_INST_3x(vunpcklpd, Vunpcklpd, X86Xmm, X86Xmm, X86Mem)                // AVX  AVX512_F{kz|b64}-VL
+    4605             :   ASMJIT_INST_3x(vunpcklpd, Vunpcklpd, X86Ymm, X86Ymm, X86Ymm)                // AVX  AVX512_F{kz|b64}-VL
+    4606             :   ASMJIT_INST_3x(vunpcklpd, Vunpcklpd, X86Ymm, X86Ymm, X86Mem)                // AVX  AVX512_F{kz|b64}-VL
+    4607             :   ASMJIT_INST_3x(vunpcklpd, Vunpcklpd, X86Zmm, X86Zmm, X86Zmm)                //      AVX512_F{kz|b64}
+    4608             :   ASMJIT_INST_3x(vunpcklpd, Vunpcklpd, X86Zmm, X86Zmm, X86Mem)                //      AVX512_F{kz|b64}
+    4609             :   ASMJIT_INST_3x(vunpcklps, Vunpcklps, X86Xmm, X86Xmm, X86Xmm)                // AVX  AVX512_F{kz|b32}-VL
+    4610             :   ASMJIT_INST_3x(vunpcklps, Vunpcklps, X86Xmm, X86Xmm, X86Mem)                // AVX  AVX512_F{kz|b32}-VL
+    4611             :   ASMJIT_INST_3x(vunpcklps, Vunpcklps, X86Ymm, X86Ymm, X86Ymm)                // AVX  AVX512_F{kz|b32}-VL
+    4612             :   ASMJIT_INST_3x(vunpcklps, Vunpcklps, X86Ymm, X86Ymm, X86Mem)                // AVX  AVX512_F{kz|b32}-VL
+    4613             :   ASMJIT_INST_3x(vunpcklps, Vunpcklps, X86Zmm, X86Zmm, X86Zmm)                //      AVX512_F{kz|b32}
+    4614             :   ASMJIT_INST_3x(vunpcklps, Vunpcklps, X86Zmm, X86Zmm, X86Mem)                //      AVX512_F{kz|b32}
+    4615             :   ASMJIT_INST_3x(vxorpd, Vxorpd, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_DQ{kz|b64}-VL
+    4616             :   ASMJIT_INST_3x(vxorpd, Vxorpd, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_DQ{kz|b64}-VL
+    4617             :   ASMJIT_INST_3x(vxorpd, Vxorpd, X86Ymm, X86Ymm, X86Ymm)                      // AVX  AVX512_DQ{kz|b64}-VL
+    4618             :   ASMJIT_INST_3x(vxorpd, Vxorpd, X86Ymm, X86Ymm, X86Mem)                      // AVX  AVX512_DQ{kz|b64}-VL
+    4619             :   ASMJIT_INST_3x(vxorpd, Vxorpd, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_DQ{kz|b64}
+    4620             :   ASMJIT_INST_3x(vxorpd, Vxorpd, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_DQ{kz|b64}
+    4621             :   ASMJIT_INST_3x(vxorps, Vxorps, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_DQ{kz|b32}-VL
+    4622             :   ASMJIT_INST_3x(vxorps, Vxorps, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_DQ{kz|b32}-VL
+    4623             :   ASMJIT_INST_3x(vxorps, Vxorps, X86Ymm, X86Ymm, X86Ymm)                      // AVX  AVX512_DQ{kz|b32}-VL
+    4624             :   ASMJIT_INST_3x(vxorps, Vxorps, X86Ymm, X86Ymm, X86Mem)                      // AVX  AVX512_DQ{kz|b32}-VL
+    4625             :   ASMJIT_INST_3x(vxorps, Vxorps, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_DQ{kz|b32}
+    4626             :   ASMJIT_INST_3x(vxorps, Vxorps, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_DQ{kz|b32}
+    4627             :   ASMJIT_INST_0x(vzeroall, Vzeroall)                                          // AVX
+    4628           0 :   ASMJIT_INST_0x(vzeroupper, Vzeroupper)                                      // AVX
+    4629             : 
+    4630             :   // --------------------------------------------------------------------------
+    4631             :   // [FMA4]
+    4632             :   // --------------------------------------------------------------------------
+    4633             : 
+    4634             :   ASMJIT_INST_4x(vfmaddpd, Vfmaddpd, X86Xmm, X86Xmm, X86Xmm, X86Xmm)          // FMA4
+    4635             :   ASMJIT_INST_4x(vfmaddpd, Vfmaddpd, X86Xmm, X86Xmm, X86Mem, X86Xmm)          // FMA4
+    4636             :   ASMJIT_INST_4x(vfmaddpd, Vfmaddpd, X86Xmm, X86Xmm, X86Xmm, X86Mem)          // FMA4
+    4637             :   ASMJIT_INST_4x(vfmaddpd, Vfmaddpd, X86Ymm, X86Ymm, X86Ymm, X86Ymm)          // FMA4
+    4638             :   ASMJIT_INST_4x(vfmaddpd, Vfmaddpd, X86Ymm, X86Ymm, X86Mem, X86Ymm)          // FMA4
+    4639             :   ASMJIT_INST_4x(vfmaddpd, Vfmaddpd, X86Ymm, X86Ymm, X86Ymm, X86Mem)          // FMA4
+    4640             :   ASMJIT_INST_4x(vfmaddps, Vfmaddps, X86Xmm, X86Xmm, X86Xmm, X86Xmm)          // FMA4
+    4641             :   ASMJIT_INST_4x(vfmaddps, Vfmaddps, X86Xmm, X86Xmm, X86Mem, X86Xmm)          // FMA4
+    4642             :   ASMJIT_INST_4x(vfmaddps, Vfmaddps, X86Xmm, X86Xmm, X86Xmm, X86Mem)          // FMA4
+    4643             :   ASMJIT_INST_4x(vfmaddps, Vfmaddps, X86Ymm, X86Ymm, X86Ymm, X86Ymm)          // FMA4
+    4644             :   ASMJIT_INST_4x(vfmaddps, Vfmaddps, X86Ymm, X86Ymm, X86Mem, X86Ymm)          // FMA4
+    4645             :   ASMJIT_INST_4x(vfmaddps, Vfmaddps, X86Ymm, X86Ymm, X86Ymm, X86Mem)          // FMA4
+    4646             :   ASMJIT_INST_4x(vfmaddsd, Vfmaddsd, X86Xmm, X86Xmm, X86Xmm, X86Xmm)          // FMA4
+    4647             :   ASMJIT_INST_4x(vfmaddsd, Vfmaddsd, X86Xmm, X86Xmm, X86Mem, X86Xmm)          // FMA4
+    4648             :   ASMJIT_INST_4x(vfmaddsd, Vfmaddsd, X86Xmm, X86Xmm, X86Xmm, X86Mem)          // FMA4
+    4649             :   ASMJIT_INST_4x(vfmaddss, Vfmaddss, X86Xmm, X86Xmm, X86Xmm, X86Xmm)          // FMA4
+    4650             :   ASMJIT_INST_4x(vfmaddss, Vfmaddss, X86Xmm, X86Xmm, X86Mem, X86Xmm)          // FMA4
+    4651             :   ASMJIT_INST_4x(vfmaddss, Vfmaddss, X86Xmm, X86Xmm, X86Xmm, X86Mem)          // FMA4
+    4652             :   ASMJIT_INST_4x(vfmaddsubpd, Vfmaddsubpd, X86Xmm, X86Xmm, X86Xmm, X86Xmm)    // FMA4
+    4653             :   ASMJIT_INST_4x(vfmaddsubpd, Vfmaddsubpd, X86Xmm, X86Xmm, X86Mem, X86Xmm)    // FMA4
+    4654             :   ASMJIT_INST_4x(vfmaddsubpd, Vfmaddsubpd, X86Xmm, X86Xmm, X86Xmm, X86Mem)    // FMA4
+    4655             :   ASMJIT_INST_4x(vfmaddsubpd, Vfmaddsubpd, X86Ymm, X86Ymm, X86Ymm, X86Ymm)    // FMA4
+    4656             :   ASMJIT_INST_4x(vfmaddsubpd, Vfmaddsubpd, X86Ymm, X86Ymm, X86Mem, X86Ymm)    // FMA4
+    4657             :   ASMJIT_INST_4x(vfmaddsubpd, Vfmaddsubpd, X86Ymm, X86Ymm, X86Ymm, X86Mem)    // FMA4
+    4658             :   ASMJIT_INST_4x(vfmaddsubps, Vfmaddsubps, X86Xmm, X86Xmm, X86Xmm, X86Xmm)    // FMA4
+    4659             :   ASMJIT_INST_4x(vfmaddsubps, Vfmaddsubps, X86Xmm, X86Xmm, X86Mem, X86Xmm)    // FMA4
+    4660             :   ASMJIT_INST_4x(vfmaddsubps, Vfmaddsubps, X86Xmm, X86Xmm, X86Xmm, X86Mem)    // FMA4
+    4661             :   ASMJIT_INST_4x(vfmaddsubps, Vfmaddsubps, X86Ymm, X86Ymm, X86Ymm, X86Ymm)    // FMA4
+    4662             :   ASMJIT_INST_4x(vfmaddsubps, Vfmaddsubps, X86Ymm, X86Ymm, X86Mem, X86Ymm)    // FMA4
+    4663             :   ASMJIT_INST_4x(vfmaddsubps, Vfmaddsubps, X86Ymm, X86Ymm, X86Ymm, X86Mem)    // FMA4
+    4664             :   ASMJIT_INST_4x(vfmsubaddpd, Vfmsubaddpd, X86Xmm, X86Xmm, X86Xmm, X86Xmm)    // FMA4
+    4665             :   ASMJIT_INST_4x(vfmsubaddpd, Vfmsubaddpd, X86Xmm, X86Xmm, X86Mem, X86Xmm)    // FMA4
+    4666             :   ASMJIT_INST_4x(vfmsubaddpd, Vfmsubaddpd, X86Xmm, X86Xmm, X86Xmm, X86Mem)    // FMA4
+    4667             :   ASMJIT_INST_4x(vfmsubaddpd, Vfmsubaddpd, X86Ymm, X86Ymm, X86Ymm, X86Ymm)    // FMA4
+    4668             :   ASMJIT_INST_4x(vfmsubaddpd, Vfmsubaddpd, X86Ymm, X86Ymm, X86Mem, X86Ymm)    // FMA4
+    4669             :   ASMJIT_INST_4x(vfmsubaddpd, Vfmsubaddpd, X86Ymm, X86Ymm, X86Ymm, X86Mem)    // FMA4
+    4670             :   ASMJIT_INST_4x(vfmsubaddps, Vfmsubaddps, X86Xmm, X86Xmm, X86Xmm, X86Xmm)    // FMA4
+    4671             :   ASMJIT_INST_4x(vfmsubaddps, Vfmsubaddps, X86Xmm, X86Xmm, X86Mem, X86Xmm)    // FMA4
+    4672             :   ASMJIT_INST_4x(vfmsubaddps, Vfmsubaddps, X86Xmm, X86Xmm, X86Xmm, X86Mem)    // FMA4
+    4673             :   ASMJIT_INST_4x(vfmsubaddps, Vfmsubaddps, X86Ymm, X86Ymm, X86Ymm, X86Ymm)    // FMA4
+    4674             :   ASMJIT_INST_4x(vfmsubaddps, Vfmsubaddps, X86Ymm, X86Ymm, X86Mem, X86Ymm)    // FMA4
+    4675             :   ASMJIT_INST_4x(vfmsubaddps, Vfmsubaddps, X86Ymm, X86Ymm, X86Ymm, X86Mem)    // FMA4
+    4676             :   ASMJIT_INST_4x(vfmsubpd, Vfmsubpd, X86Xmm, X86Xmm, X86Xmm, X86Xmm)          // FMA4
+    4677             :   ASMJIT_INST_4x(vfmsubpd, Vfmsubpd, X86Xmm, X86Xmm, X86Mem, X86Xmm)          // FMA4
+    4678             :   ASMJIT_INST_4x(vfmsubpd, Vfmsubpd, X86Xmm, X86Xmm, X86Xmm, X86Mem)          // FMA4
+    4679             :   ASMJIT_INST_4x(vfmsubpd, Vfmsubpd, X86Ymm, X86Ymm, X86Ymm, X86Ymm)          // FMA4
+    4680             :   ASMJIT_INST_4x(vfmsubpd, Vfmsubpd, X86Ymm, X86Ymm, X86Mem, X86Ymm)          // FMA4
+    4681             :   ASMJIT_INST_4x(vfmsubpd, Vfmsubpd, X86Ymm, X86Ymm, X86Ymm, X86Mem)          // FMA4
+    4682             :   ASMJIT_INST_4x(vfmsubps, Vfmsubps, X86Xmm, X86Xmm, X86Xmm, X86Xmm)          // FMA4
+    4683             :   ASMJIT_INST_4x(vfmsubps, Vfmsubps, X86Xmm, X86Xmm, X86Mem, X86Xmm)          // FMA4
+    4684             :   ASMJIT_INST_4x(vfmsubps, Vfmsubps, X86Xmm, X86Xmm, X86Xmm, X86Mem)          // FMA4
+    4685             :   ASMJIT_INST_4x(vfmsubps, Vfmsubps, X86Ymm, X86Ymm, X86Ymm, X86Ymm)          // FMA4
+    4686             :   ASMJIT_INST_4x(vfmsubps, Vfmsubps, X86Ymm, X86Ymm, X86Mem, X86Ymm)          // FMA4
+    4687             :   ASMJIT_INST_4x(vfmsubps, Vfmsubps, X86Ymm, X86Ymm, X86Ymm, X86Mem)          // FMA4
+    4688             :   ASMJIT_INST_4x(vfmsubsd, Vfmsubsd, X86Xmm, X86Xmm, X86Xmm, X86Xmm)          // FMA4
+    4689             :   ASMJIT_INST_4x(vfmsubsd, Vfmsubsd, X86Xmm, X86Xmm, X86Mem, X86Xmm)          // FMA4
+    4690             :   ASMJIT_INST_4x(vfmsubsd, Vfmsubsd, X86Xmm, X86Xmm, X86Xmm, X86Mem)          // FMA4
+    4691             :   ASMJIT_INST_4x(vfmsubss, Vfmsubss, X86Xmm, X86Xmm, X86Xmm, X86Xmm)          // FMA4
+    4692             :   ASMJIT_INST_4x(vfmsubss, Vfmsubss, X86Xmm, X86Xmm, X86Mem, X86Xmm)          // FMA4
+    4693             :   ASMJIT_INST_4x(vfmsubss, Vfmsubss, X86Xmm, X86Xmm, X86Xmm, X86Mem)          // FMA4
+    4694             :   ASMJIT_INST_4x(vfnmaddpd, Vfnmaddpd, X86Xmm, X86Xmm, X86Xmm, X86Xmm)        // FMA4
+    4695             :   ASMJIT_INST_4x(vfnmaddpd, Vfnmaddpd, X86Xmm, X86Xmm, X86Mem, X86Xmm)        // FMA4
+    4696             :   ASMJIT_INST_4x(vfnmaddpd, Vfnmaddpd, X86Xmm, X86Xmm, X86Xmm, X86Mem)        // FMA4
+    4697             :   ASMJIT_INST_4x(vfnmaddpd, Vfnmaddpd, X86Ymm, X86Ymm, X86Ymm, X86Ymm)        // FMA4
+    4698             :   ASMJIT_INST_4x(vfnmaddpd, Vfnmaddpd, X86Ymm, X86Ymm, X86Mem, X86Ymm)        // FMA4
+    4699             :   ASMJIT_INST_4x(vfnmaddpd, Vfnmaddpd, X86Ymm, X86Ymm, X86Ymm, X86Mem)        // FMA4
+    4700             :   ASMJIT_INST_4x(vfnmaddps, Vfnmaddps, X86Xmm, X86Xmm, X86Xmm, X86Xmm)        // FMA4
+    4701             :   ASMJIT_INST_4x(vfnmaddps, Vfnmaddps, X86Xmm, X86Xmm, X86Mem, X86Xmm)        // FMA4
+    4702             :   ASMJIT_INST_4x(vfnmaddps, Vfnmaddps, X86Xmm, X86Xmm, X86Xmm, X86Mem)        // FMA4
+    4703             :   ASMJIT_INST_4x(vfnmaddps, Vfnmaddps, X86Ymm, X86Ymm, X86Ymm, X86Ymm)        // FMA4
+    4704             :   ASMJIT_INST_4x(vfnmaddps, Vfnmaddps, X86Ymm, X86Ymm, X86Mem, X86Ymm)        // FMA4
+    4705             :   ASMJIT_INST_4x(vfnmaddps, Vfnmaddps, X86Ymm, X86Ymm, X86Ymm, X86Mem)        // FMA4
+    4706             :   ASMJIT_INST_4x(vfnmaddsd, Vfnmaddsd, X86Xmm, X86Xmm, X86Xmm, X86Xmm)        // FMA4
+    4707             :   ASMJIT_INST_4x(vfnmaddsd, Vfnmaddsd, X86Xmm, X86Xmm, X86Mem, X86Xmm)        // FMA4
+    4708             :   ASMJIT_INST_4x(vfnmaddsd, Vfnmaddsd, X86Xmm, X86Xmm, X86Xmm, X86Mem)        // FMA4
+    4709             :   ASMJIT_INST_4x(vfnmaddss, Vfnmaddss, X86Xmm, X86Xmm, X86Xmm, X86Xmm)        // FMA4
+    4710             :   ASMJIT_INST_4x(vfnmaddss, Vfnmaddss, X86Xmm, X86Xmm, X86Mem, X86Xmm)        // FMA4
+    4711             :   ASMJIT_INST_4x(vfnmaddss, Vfnmaddss, X86Xmm, X86Xmm, X86Xmm, X86Mem)        // FMA4
+    4712             :   ASMJIT_INST_4x(vfnmsubpd, Vfnmsubpd, X86Xmm, X86Xmm, X86Xmm, X86Xmm)        // FMA4
+    4713             :   ASMJIT_INST_4x(vfnmsubpd, Vfnmsubpd, X86Xmm, X86Xmm, X86Mem, X86Xmm)        // FMA4
+    4714             :   ASMJIT_INST_4x(vfnmsubpd, Vfnmsubpd, X86Xmm, X86Xmm, X86Xmm, X86Mem)        // FMA4
+    4715             :   ASMJIT_INST_4x(vfnmsubpd, Vfnmsubpd, X86Ymm, X86Ymm, X86Ymm, X86Ymm)        // FMA4
+    4716             :   ASMJIT_INST_4x(vfnmsubpd, Vfnmsubpd, X86Ymm, X86Ymm, X86Mem, X86Ymm)        // FMA4
+    4717             :   ASMJIT_INST_4x(vfnmsubpd, Vfnmsubpd, X86Ymm, X86Ymm, X86Ymm, X86Mem)        // FMA4
+    4718             :   ASMJIT_INST_4x(vfnmsubps, Vfnmsubps, X86Xmm, X86Xmm, X86Xmm, X86Xmm)        // FMA4
+    4719             :   ASMJIT_INST_4x(vfnmsubps, Vfnmsubps, X86Xmm, X86Xmm, X86Mem, X86Xmm)        // FMA4
+    4720             :   ASMJIT_INST_4x(vfnmsubps, Vfnmsubps, X86Xmm, X86Xmm, X86Xmm, X86Mem)        // FMA4
+    4721             :   ASMJIT_INST_4x(vfnmsubps, Vfnmsubps, X86Ymm, X86Ymm, X86Ymm, X86Ymm)        // FMA4
+    4722             :   ASMJIT_INST_4x(vfnmsubps, Vfnmsubps, X86Ymm, X86Ymm, X86Mem, X86Ymm)        // FMA4
+    4723             :   ASMJIT_INST_4x(vfnmsubps, Vfnmsubps, X86Ymm, X86Ymm, X86Ymm, X86Mem)        // FMA4
+    4724             :   ASMJIT_INST_4x(vfnmsubsd, Vfnmsubsd, X86Xmm, X86Xmm, X86Xmm, X86Xmm)        // FMA4
+    4725             :   ASMJIT_INST_4x(vfnmsubsd, Vfnmsubsd, X86Xmm, X86Xmm, X86Mem, X86Xmm)        // FMA4
+    4726             :   ASMJIT_INST_4x(vfnmsubsd, Vfnmsubsd, X86Xmm, X86Xmm, X86Xmm, X86Mem)        // FMA4
+    4727             :   ASMJIT_INST_4x(vfnmsubss, Vfnmsubss, X86Xmm, X86Xmm, X86Xmm, X86Xmm)        // FMA4
+    4728             :   ASMJIT_INST_4x(vfnmsubss, Vfnmsubss, X86Xmm, X86Xmm, X86Mem, X86Xmm)        // FMA4
+    4729             :   ASMJIT_INST_4x(vfnmsubss, Vfnmsubss, X86Xmm, X86Xmm, X86Xmm, X86Mem)        // FMA4
+    4730             : 
+    4731             :   // --------------------------------------------------------------------------
+    4732             :   // [XOP]
+    4733             :   // --------------------------------------------------------------------------
+    4734             : 
+    4735             :   ASMJIT_INST_2x(vfrczpd, Vfrczpd, X86Xmm, X86Xmm)                            // XOP
+    4736             :   ASMJIT_INST_2x(vfrczpd, Vfrczpd, X86Xmm, X86Mem)                            // XOP
+    4737             :   ASMJIT_INST_2x(vfrczpd, Vfrczpd, X86Ymm, X86Ymm)                            // XOP
+    4738             :   ASMJIT_INST_2x(vfrczpd, Vfrczpd, X86Ymm, X86Mem)                            // XOP
+    4739             :   ASMJIT_INST_2x(vfrczps, Vfrczps, X86Xmm, X86Xmm)                            // XOP
+    4740             :   ASMJIT_INST_2x(vfrczps, Vfrczps, X86Xmm, X86Mem)                            // XOP
+    4741             :   ASMJIT_INST_2x(vfrczps, Vfrczps, X86Ymm, X86Ymm)                            // XOP
+    4742             :   ASMJIT_INST_2x(vfrczps, Vfrczps, X86Ymm, X86Mem)                            // XOP
+    4743             :   ASMJIT_INST_2x(vfrczsd, Vfrczsd, X86Xmm, X86Xmm)                            // XOP
+    4744             :   ASMJIT_INST_2x(vfrczsd, Vfrczsd, X86Xmm, X86Mem)                            // XOP
+    4745             :   ASMJIT_INST_2x(vfrczss, Vfrczss, X86Xmm, X86Xmm)                            // XOP
+    4746             :   ASMJIT_INST_2x(vfrczss, Vfrczss, X86Xmm, X86Mem)                            // XOP
+    4747             :   ASMJIT_INST_4x(vpcmov, Vpcmov, X86Xmm, X86Xmm, X86Xmm, X86Xmm)              // XOP
+    4748             :   ASMJIT_INST_4x(vpcmov, Vpcmov, X86Xmm, X86Xmm, X86Mem, X86Xmm)              // XOP
+    4749             :   ASMJIT_INST_4x(vpcmov, Vpcmov, X86Xmm, X86Xmm, X86Xmm, X86Mem)              // XOP
+    4750             :   ASMJIT_INST_4x(vpcmov, Vpcmov, X86Ymm, X86Ymm, X86Ymm, X86Ymm)              // XOP
+    4751             :   ASMJIT_INST_4x(vpcmov, Vpcmov, X86Ymm, X86Ymm, X86Mem, X86Ymm)              // XOP
+    4752             :   ASMJIT_INST_4x(vpcmov, Vpcmov, X86Ymm, X86Ymm, X86Ymm, X86Mem)              // XOP
+    4753             :   ASMJIT_INST_4i(vpcomb, Vpcomb, X86Xmm, X86Xmm, X86Xmm, Imm)                 // XOP
+    4754             :   ASMJIT_INST_4i(vpcomb, Vpcomb, X86Xmm, X86Xmm, X86Mem, Imm)                 // XOP
+    4755             :   ASMJIT_INST_4i(vpcomd, Vpcomd, X86Xmm, X86Xmm, X86Xmm, Imm)                 // XOP
+    4756             :   ASMJIT_INST_4i(vpcomd, Vpcomd, X86Xmm, X86Xmm, X86Mem, Imm)                 // XOP
+    4757             :   ASMJIT_INST_4i(vpcomq, Vpcomq, X86Xmm, X86Xmm, X86Xmm, Imm)                 // XOP
+    4758             :   ASMJIT_INST_4i(vpcomq, Vpcomq, X86Xmm, X86Xmm, X86Mem, Imm)                 // XOP
+    4759             :   ASMJIT_INST_4i(vpcomw, Vpcomw, X86Xmm, X86Xmm, X86Xmm, Imm)                 // XOP
+    4760             :   ASMJIT_INST_4i(vpcomw, Vpcomw, X86Xmm, X86Xmm, X86Mem, Imm)                 // XOP
+    4761             :   ASMJIT_INST_4i(vpcomub, Vpcomub, X86Xmm, X86Xmm, X86Xmm, Imm)               // XOP
+    4762             :   ASMJIT_INST_4i(vpcomub, Vpcomub, X86Xmm, X86Xmm, X86Mem, Imm)               // XOP
+    4763             :   ASMJIT_INST_4i(vpcomud, Vpcomud, X86Xmm, X86Xmm, X86Xmm, Imm)               // XOP
+    4764             :   ASMJIT_INST_4i(vpcomud, Vpcomud, X86Xmm, X86Xmm, X86Mem, Imm)               // XOP
+    4765             :   ASMJIT_INST_4i(vpcomuq, Vpcomuq, X86Xmm, X86Xmm, X86Xmm, Imm)               // XOP
+    4766             :   ASMJIT_INST_4i(vpcomuq, Vpcomuq, X86Xmm, X86Xmm, X86Mem, Imm)               // XOP
+    4767             :   ASMJIT_INST_4i(vpcomuw, Vpcomuw, X86Xmm, X86Xmm, X86Xmm, Imm)               // XOP
+    4768             :   ASMJIT_INST_4i(vpcomuw, Vpcomuw, X86Xmm, X86Xmm, X86Mem, Imm)               // XOP
+    4769             :   ASMJIT_INST_5i(vpermil2pd, Vpermil2pd, X86Xmm, X86Xmm, X86Xmm, X86Xmm, Imm) // XOP
+    4770             :   ASMJIT_INST_5i(vpermil2pd, Vpermil2pd, X86Xmm, X86Xmm, X86Mem, X86Xmm, Imm) // XOP
+    4771             :   ASMJIT_INST_5i(vpermil2pd, Vpermil2pd, X86Xmm, X86Xmm, X86Xmm, X86Mem, Imm) // XOP
+    4772             :   ASMJIT_INST_5i(vpermil2pd, Vpermil2pd, X86Ymm, X86Ymm, X86Ymm, X86Ymm, Imm) // XOP
+    4773             :   ASMJIT_INST_5i(vpermil2pd, Vpermil2pd, X86Ymm, X86Ymm, X86Mem, X86Ymm, Imm) // XOP
+    4774             :   ASMJIT_INST_5i(vpermil2pd, Vpermil2pd, X86Ymm, X86Ymm, X86Ymm, X86Mem, Imm) // XOP
+    4775             :   ASMJIT_INST_5i(vpermil2ps, Vpermil2ps, X86Xmm, X86Xmm, X86Xmm, X86Xmm, Imm) // XOP
+    4776             :   ASMJIT_INST_5i(vpermil2ps, Vpermil2ps, X86Xmm, X86Xmm, X86Mem, X86Xmm, Imm) // XOP
+    4777             :   ASMJIT_INST_5i(vpermil2ps, Vpermil2ps, X86Xmm, X86Xmm, X86Xmm, X86Mem, Imm) // XOP
+    4778             :   ASMJIT_INST_5i(vpermil2ps, Vpermil2ps, X86Ymm, X86Ymm, X86Ymm, X86Ymm, Imm) // XOP
+    4779             :   ASMJIT_INST_5i(vpermil2ps, Vpermil2ps, X86Ymm, X86Ymm, X86Mem, X86Ymm, Imm) // XOP
+    4780             :   ASMJIT_INST_5i(vpermil2ps, Vpermil2ps, X86Ymm, X86Ymm, X86Ymm, X86Mem, Imm) // XOP
+    4781             :   ASMJIT_INST_2x(vphaddbd, Vphaddbd, X86Xmm, X86Xmm)                          // XOP
+    4782             :   ASMJIT_INST_2x(vphaddbd, Vphaddbd, X86Xmm, X86Mem)                          // XOP
+    4783             :   ASMJIT_INST_2x(vphaddbq, Vphaddbq, X86Xmm, X86Xmm)                          // XOP
+    4784             :   ASMJIT_INST_2x(vphaddbq, Vphaddbq, X86Xmm, X86Mem)                          // XOP
+    4785             :   ASMJIT_INST_2x(vphaddbw, Vphaddbw, X86Xmm, X86Xmm)                          // XOP
+    4786             :   ASMJIT_INST_2x(vphaddbw, Vphaddbw, X86Xmm, X86Mem)                          // XOP
+    4787             :   ASMJIT_INST_2x(vphadddq, Vphadddq, X86Xmm, X86Xmm)                          // XOP
+    4788             :   ASMJIT_INST_2x(vphadddq, Vphadddq, X86Xmm, X86Mem)                          // XOP
+    4789             :   ASMJIT_INST_2x(vphaddwd, Vphaddwd, X86Xmm, X86Xmm)                          // XOP
+    4790             :   ASMJIT_INST_2x(vphaddwd, Vphaddwd, X86Xmm, X86Mem)                          // XOP
+    4791             :   ASMJIT_INST_2x(vphaddwq, Vphaddwq, X86Xmm, X86Xmm)                          // XOP
+    4792             :   ASMJIT_INST_2x(vphaddwq, Vphaddwq, X86Xmm, X86Mem)                          // XOP
+    4793             :   ASMJIT_INST_2x(vphaddubd, Vphaddubd, X86Xmm, X86Xmm)                        // XOP
+    4794             :   ASMJIT_INST_2x(vphaddubd, Vphaddubd, X86Xmm, X86Mem)                        // XOP
+    4795             :   ASMJIT_INST_2x(vphaddubq, Vphaddubq, X86Xmm, X86Xmm)                        // XOP
+    4796             :   ASMJIT_INST_2x(vphaddubq, Vphaddubq, X86Xmm, X86Mem)                        // XOP
+    4797             :   ASMJIT_INST_2x(vphaddubw, Vphaddubw, X86Xmm, X86Xmm)                        // XOP
+    4798             :   ASMJIT_INST_2x(vphaddubw, Vphaddubw, X86Xmm, X86Mem)                        // XOP
+    4799             :   ASMJIT_INST_2x(vphaddudq, Vphaddudq, X86Xmm, X86Xmm)                        // XOP
+    4800             :   ASMJIT_INST_2x(vphaddudq, Vphaddudq, X86Xmm, X86Mem)                        // XOP
+    4801             :   ASMJIT_INST_2x(vphadduwd, Vphadduwd, X86Xmm, X86Xmm)                        // XOP
+    4802             :   ASMJIT_INST_2x(vphadduwd, Vphadduwd, X86Xmm, X86Mem)                        // XOP
+    4803             :   ASMJIT_INST_2x(vphadduwq, Vphadduwq, X86Xmm, X86Xmm)                        // XOP
+    4804             :   ASMJIT_INST_2x(vphadduwq, Vphadduwq, X86Xmm, X86Mem)                        // XOP
+    4805             :   ASMJIT_INST_2x(vphsubbw, Vphsubbw, X86Xmm, X86Xmm)                          // XOP
+    4806             :   ASMJIT_INST_2x(vphsubbw, Vphsubbw, X86Xmm, X86Mem)                          // XOP
+    4807             :   ASMJIT_INST_2x(vphsubdq, Vphsubdq, X86Xmm, X86Xmm)                          // XOP
+    4808             :   ASMJIT_INST_2x(vphsubdq, Vphsubdq, X86Xmm, X86Mem)                          // XOP
+    4809             :   ASMJIT_INST_2x(vphsubwd, Vphsubwd, X86Xmm, X86Xmm)                          // XOP
+    4810             :   ASMJIT_INST_2x(vphsubwd, Vphsubwd, X86Xmm, X86Mem)                          // XOP
+    4811             :   ASMJIT_INST_4x(vpmacsdd, Vpmacsdd, X86Xmm, X86Xmm, X86Xmm, X86Xmm)          // XOP
+    4812             :   ASMJIT_INST_4x(vpmacsdd, Vpmacsdd, X86Xmm, X86Xmm, X86Mem, X86Xmm)          // XOP
+    4813             :   ASMJIT_INST_4x(vpmacsdqh, Vpmacsdqh, X86Xmm, X86Xmm, X86Xmm, X86Xmm)        // XOP
+    4814             :   ASMJIT_INST_4x(vpmacsdqh, Vpmacsdqh, X86Xmm, X86Xmm, X86Mem, X86Xmm)        // XOP
+    4815             :   ASMJIT_INST_4x(vpmacsdql, Vpmacsdql, X86Xmm, X86Xmm, X86Xmm, X86Xmm)        // XOP
+    4816             :   ASMJIT_INST_4x(vpmacsdql, Vpmacsdql, X86Xmm, X86Xmm, X86Mem, X86Xmm)        // XOP
+    4817             :   ASMJIT_INST_4x(vpmacswd, Vpmacswd, X86Xmm, X86Xmm, X86Xmm, X86Xmm)          // XOP
+    4818             :   ASMJIT_INST_4x(vpmacswd, Vpmacswd, X86Xmm, X86Xmm, X86Mem, X86Xmm)          // XOP
+    4819             :   ASMJIT_INST_4x(vpmacsww, Vpmacsww, X86Xmm, X86Xmm, X86Xmm, X86Xmm)          // XOP
+    4820             :   ASMJIT_INST_4x(vpmacsww, Vpmacsww, X86Xmm, X86Xmm, X86Mem, X86Xmm)          // XOP
+    4821             :   ASMJIT_INST_4x(vpmacssdd, Vpmacssdd, X86Xmm, X86Xmm, X86Xmm, X86Xmm)        // XOP
+    4822             :   ASMJIT_INST_4x(vpmacssdd, Vpmacssdd, X86Xmm, X86Xmm, X86Mem, X86Xmm)        // XOP
+    4823             :   ASMJIT_INST_4x(vpmacssdqh, Vpmacssdqh, X86Xmm, X86Xmm, X86Xmm, X86Xmm)      // XOP
+    4824             :   ASMJIT_INST_4x(vpmacssdqh, Vpmacssdqh, X86Xmm, X86Xmm, X86Mem, X86Xmm)      // XOP
+    4825             :   ASMJIT_INST_4x(vpmacssdql, Vpmacssdql, X86Xmm, X86Xmm, X86Xmm, X86Xmm)      // XOP
+    4826             :   ASMJIT_INST_4x(vpmacssdql, Vpmacssdql, X86Xmm, X86Xmm, X86Mem, X86Xmm)      // XOP
+    4827             :   ASMJIT_INST_4x(vpmacsswd, Vpmacsswd, X86Xmm, X86Xmm, X86Xmm, X86Xmm)        // XOP
+    4828             :   ASMJIT_INST_4x(vpmacsswd, Vpmacsswd, X86Xmm, X86Xmm, X86Mem, X86Xmm)        // XOP
+    4829             :   ASMJIT_INST_4x(vpmacssww, Vpmacssww, X86Xmm, X86Xmm, X86Xmm, X86Xmm)        // XOP
+    4830             :   ASMJIT_INST_4x(vpmacssww, Vpmacssww, X86Xmm, X86Xmm, X86Mem, X86Xmm)        // XOP
+    4831             :   ASMJIT_INST_4x(vpmadcsswd, Vpmadcsswd, X86Xmm, X86Xmm, X86Xmm, X86Xmm)      // XOP
+    4832             :   ASMJIT_INST_4x(vpmadcsswd, Vpmadcsswd, X86Xmm, X86Xmm, X86Mem, X86Xmm)      // XOP
+    4833             :   ASMJIT_INST_4x(vpmadcswd, Vpmadcswd, X86Xmm, X86Xmm, X86Xmm, X86Xmm)        // XOP
+    4834             :   ASMJIT_INST_4x(vpmadcswd, Vpmadcswd, X86Xmm, X86Xmm, X86Mem, X86Xmm)        // XOP
+    4835             :   ASMJIT_INST_4x(vpperm, Vpperm, X86Xmm, X86Xmm, X86Xmm, X86Xmm)              // XOP
+    4836             :   ASMJIT_INST_4x(vpperm, Vpperm, X86Xmm, X86Xmm, X86Mem, X86Xmm)              // XOP
+    4837             :   ASMJIT_INST_4x(vpperm, Vpperm, X86Xmm, X86Xmm, X86Xmm, X86Mem)              // XOP
+    4838             :   ASMJIT_INST_3x(vprotb, Vprotb, X86Xmm, X86Xmm, X86Xmm)                      // XOP
+    4839             :   ASMJIT_INST_3x(vprotb, Vprotb, X86Xmm, X86Mem, X86Xmm)                      // XOP
+    4840             :   ASMJIT_INST_3x(vprotb, Vprotb, X86Xmm, X86Xmm, X86Mem)                      // XOP
+    4841             :   ASMJIT_INST_3i(vprotb, Vprotb, X86Xmm, X86Xmm, Imm)                         // XOP
+    4842             :   ASMJIT_INST_3i(vprotb, Vprotb, X86Xmm, X86Mem, Imm)                         // XOP
+    4843             :   ASMJIT_INST_3x(vprotd, Vprotd, X86Xmm, X86Xmm, X86Xmm)                      // XOP
+    4844             :   ASMJIT_INST_3x(vprotd, Vprotd, X86Xmm, X86Mem, X86Xmm)                      // XOP
+    4845             :   ASMJIT_INST_3x(vprotd, Vprotd, X86Xmm, X86Xmm, X86Mem)                      // XOP
+    4846             :   ASMJIT_INST_3i(vprotd, Vprotd, X86Xmm, X86Xmm, Imm)                         // XOP
+    4847             :   ASMJIT_INST_3i(vprotd, Vprotd, X86Xmm, X86Mem, Imm)                         // XOP
+    4848             :   ASMJIT_INST_3x(vprotq, Vprotq, X86Xmm, X86Xmm, X86Xmm)                      // XOP
+    4849             :   ASMJIT_INST_3x(vprotq, Vprotq, X86Xmm, X86Mem, X86Xmm)                      // XOP
+    4850             :   ASMJIT_INST_3x(vprotq, Vprotq, X86Xmm, X86Xmm, X86Mem)                      // XOP
+    4851             :   ASMJIT_INST_3i(vprotq, Vprotq, X86Xmm, X86Xmm, Imm)                         // XOP
+    4852             :   ASMJIT_INST_3i(vprotq, Vprotq, X86Xmm, X86Mem, Imm)                         // XOP
+    4853             :   ASMJIT_INST_3x(vprotw, Vprotw, X86Xmm, X86Xmm, X86Xmm)                      // XOP
+    4854             :   ASMJIT_INST_3x(vprotw, Vprotw, X86Xmm, X86Mem, X86Xmm)                      // XOP
+    4855             :   ASMJIT_INST_3x(vprotw, Vprotw, X86Xmm, X86Xmm, X86Mem)                      // XOP
+    4856             :   ASMJIT_INST_3i(vprotw, Vprotw, X86Xmm, X86Xmm, Imm)                         // XOP
+    4857             :   ASMJIT_INST_3i(vprotw, Vprotw, X86Xmm, X86Mem, Imm)                         // XOP
+    4858             :   ASMJIT_INST_3x(vpshab, Vpshab, X86Xmm, X86Xmm, X86Xmm)                      // XOP
+    4859             :   ASMJIT_INST_3x(vpshab, Vpshab, X86Xmm, X86Mem, X86Xmm)                      // XOP
+    4860             :   ASMJIT_INST_3x(vpshab, Vpshab, X86Xmm, X86Xmm, X86Mem)                      // XOP
+    4861             :   ASMJIT_INST_3x(vpshad, Vpshad, X86Xmm, X86Xmm, X86Xmm)                      // XOP
+    4862             :   ASMJIT_INST_3x(vpshad, Vpshad, X86Xmm, X86Mem, X86Xmm)                      // XOP
+    4863             :   ASMJIT_INST_3x(vpshad, Vpshad, X86Xmm, X86Xmm, X86Mem)                      // XOP
+    4864             :   ASMJIT_INST_3x(vpshaq, Vpshaq, X86Xmm, X86Xmm, X86Xmm)                      // XOP
+    4865             :   ASMJIT_INST_3x(vpshaq, Vpshaq, X86Xmm, X86Mem, X86Xmm)                      // XOP
+    4866             :   ASMJIT_INST_3x(vpshaq, Vpshaq, X86Xmm, X86Xmm, X86Mem)                      // XOP
+    4867             :   ASMJIT_INST_3x(vpshaw, Vpshaw, X86Xmm, X86Xmm, X86Xmm)                      // XOP
+    4868             :   ASMJIT_INST_3x(vpshaw, Vpshaw, X86Xmm, X86Mem, X86Xmm)                      // XOP
+    4869             :   ASMJIT_INST_3x(vpshaw, Vpshaw, X86Xmm, X86Xmm, X86Mem)                      // XOP
+    4870             :   ASMJIT_INST_3x(vpshlb, Vpshlb, X86Xmm, X86Xmm, X86Xmm)                      // XOP
+    4871             :   ASMJIT_INST_3x(vpshlb, Vpshlb, X86Xmm, X86Mem, X86Xmm)                      // XOP
+    4872             :   ASMJIT_INST_3x(vpshlb, Vpshlb, X86Xmm, X86Xmm, X86Mem)                      // XOP
+    4873             :   ASMJIT_INST_3x(vpshld, Vpshld, X86Xmm, X86Xmm, X86Xmm)                      // XOP
+    4874             :   ASMJIT_INST_3x(vpshld, Vpshld, X86Xmm, X86Mem, X86Xmm)                      // XOP
+    4875             :   ASMJIT_INST_3x(vpshld, Vpshld, X86Xmm, X86Xmm, X86Mem)                      // XOP
+    4876             :   ASMJIT_INST_3x(vpshlq, Vpshlq, X86Xmm, X86Xmm, X86Xmm)                      // XOP
+    4877             :   ASMJIT_INST_3x(vpshlq, Vpshlq, X86Xmm, X86Mem, X86Xmm)                      // XOP
+    4878             :   ASMJIT_INST_3x(vpshlq, Vpshlq, X86Xmm, X86Xmm, X86Mem)                      // XOP
+    4879             :   ASMJIT_INST_3x(vpshlw, Vpshlw, X86Xmm, X86Xmm, X86Xmm)                      // XOP
+    4880             :   ASMJIT_INST_3x(vpshlw, Vpshlw, X86Xmm, X86Mem, X86Xmm)                      // XOP
+    4881             :   ASMJIT_INST_3x(vpshlw, Vpshlw, X86Xmm, X86Xmm, X86Mem)                      // XOP
+    4882             : };
+    4883             : 
+    4884             : // ============================================================================
+    4885             : // [asmjit::X86EmitterImplicitT]
+    4886             : // ============================================================================
+    4887             : 
+    4888             : template<typename This>
+    4889             : struct X86EmitterImplicitT : public X86EmitterExplicitT<This> {
+    4890             :   // --------------------------------------------------------------------------
+    4891             :   // [Options]
+    4892             :   // --------------------------------------------------------------------------
+    4893             : 
+    4894             :   //! Use REP/REPZ prefix.
+    4895             :   ASMJIT_INLINE This& rep() noexcept { return X86EmitterExplicitT<This>::_addOptions(X86Inst::kOptionRep); }
+    4896             :   //! Use REPNZ prefix.
+    4897             :   ASMJIT_INLINE This& repnz() noexcept { return X86EmitterExplicitT<This>::_addOptions(X86Inst::kOptionRepnz); }
+    4898             : 
+    4899             :   //! Use REP/REPZ prefix.
+    4900             :   ASMJIT_INLINE This& repe() noexcept { return rep(); }
+    4901             :   //! Use REP/REPZ prefix.
+    4902             :   ASMJIT_INLINE This& repz() noexcept { return rep(); }
+    4903             :   //! Use REPNZ prefix.
+    4904             :   ASMJIT_INLINE This& repne() noexcept { return repnz(); }
+    4905             : 
+    4906             :   // --------------------------------------------------------------------------
+    4907             :   // [General Purpose and Non-SIMD Instructions]
+    4908             :   // --------------------------------------------------------------------------
+    4909             : 
+    4910             :   // TODO: xrstor and xsave don't have explicit variants yet.
+    4911             : 
+    4912             :   using X86EmitterExplicitT<This>::cbw;
+    4913             :   using X86EmitterExplicitT<This>::cdq;
+    4914             :   using X86EmitterExplicitT<This>::cdqe;
+    4915             :   using X86EmitterExplicitT<This>::clzero;
+    4916             :   using X86EmitterExplicitT<This>::cqo;
+    4917             :   using X86EmitterExplicitT<This>::cwd;
+    4918             :   using X86EmitterExplicitT<This>::cwde;
+    4919             :   using X86EmitterExplicitT<This>::cmpsd;
+    4920             :   using X86EmitterExplicitT<This>::cmpxchg;
+    4921             :   using X86EmitterExplicitT<This>::cmpxchg8b;
+    4922             :   using X86EmitterExplicitT<This>::cmpxchg16b;
+    4923             :   using X86EmitterExplicitT<This>::cpuid;
+    4924             :   using X86EmitterExplicitT<This>::div;
+    4925             :   using X86EmitterExplicitT<This>::idiv;
+    4926             :   using X86EmitterExplicitT<This>::imul;
+    4927             :   using X86EmitterExplicitT<This>::jecxz;
+    4928             :   using X86EmitterExplicitT<This>::lahf;
+    4929             :   using X86EmitterExplicitT<This>::mulx;
+    4930             :   using X86EmitterExplicitT<This>::movsd;
+    4931             :   using X86EmitterExplicitT<This>::mul;
+    4932             :   using X86EmitterExplicitT<This>::rdmsr;
+    4933             :   using X86EmitterExplicitT<This>::rdpmc;
+    4934             :   using X86EmitterExplicitT<This>::rdtsc;
+    4935             :   using X86EmitterExplicitT<This>::rdtscp;
+    4936             :   using X86EmitterExplicitT<This>::sahf;
+    4937             :   using X86EmitterExplicitT<This>::wrmsr;
+    4938             :   using X86EmitterExplicitT<This>::xgetbv;
+    4939             :   using X86EmitterExplicitT<This>::xsetbv;
+    4940             : 
+    4941             :   ASMJIT_INST_0x(cbw, Cbw)                                                    // ANY       [IMPLICIT] AX      <- Sign Extend AL
+    4942             :   ASMJIT_INST_0x(cdq, Cdq)                                                    // ANY       [IMPLICIT] EDX:EAX <- Sign Extend EAX
+    4943             :   ASMJIT_INST_0x(cdqe, Cdqe)                                                  // X64       [IMPLICIT] RAX     <- Sign Extend EAX
+    4944             :   ASMJIT_INST_0x(clzero, Clzero)                                              // CLZERO    [IMPLICIT]
+    4945             :   ASMJIT_INST_2x(cmpxchg, Cmpxchg, X86Gp, X86Gp)                              // I486      [IMPLICIT]
+    4946             :   ASMJIT_INST_2x(cmpxchg, Cmpxchg, X86Mem, X86Gp)                             // I486      [IMPLICIT]
+    4947             :   ASMJIT_INST_1x(cmpxchg16b, Cmpxchg16b, X86Mem)                              // CMPXCHG8B [IMPLICIT] m == RDX:RAX ? m <- RCX:RBX
+    4948             :   ASMJIT_INST_1x(cmpxchg8b, Cmpxchg8b, X86Mem)                                // CMPXCHG16B[IMPLICIT] m == EDX:EAX ? m <- ECX:EBX
+    4949             :   ASMJIT_INST_0x(cpuid, Cpuid)                                                // I486      [IMPLICIT] EAX:EBX:ECX:EDX  <- CPUID[EAX:ECX]
+    4950             :   ASMJIT_INST_0x(cqo, Cqo)                                                    // X64       [IMPLICIT] RDX:RAX <- Sign Extend RAX
+    4951             :   ASMJIT_INST_0x(cwd, Cwd)                                                    // ANY       [IMPLICIT] DX:AX   <- Sign Extend AX
+    4952             :   ASMJIT_INST_0x(cwde, Cwde)                                                  // ANY       [IMPLICIT] EAX     <- Sign Extend AX
+    4953             :   ASMJIT_INST_0x(daa, Daa)
+    4954             :   ASMJIT_INST_0x(das, Das)
+    4955             :   ASMJIT_INST_1x(div, Div, X86Gp)                                             // ANY       [IMPLICIT] {AH[Rem]: AL[Quot] <- AX / r8} {xDX[Rem]:xAX[Quot] <- DX:AX / r16|r32|r64}
+    4956             :   ASMJIT_INST_1x(div, Div, X86Mem)                                            // ANY       [IMPLICIT] {AH[Rem]: AL[Quot] <- AX / m8} {xDX[Rem]:xAX[Quot] <- DX:AX / m16|m32|m64}
+    4957             :   ASMJIT_INST_1x(idiv, Idiv, X86Gp)                                           // ANY       [IMPLICIT] {AH[Rem]: AL[Quot] <- AX / r8} {xDX[Rem]:xAX[Quot] <- DX:AX / r16|r32|r64}
+    4958             :   ASMJIT_INST_1x(idiv, Idiv, X86Mem)                                          // ANY       [IMPLICIT] {AH[Rem]: AL[Quot] <- AX / m8} {xDX[Rem]:xAX[Quot] <- DX:AX / m16|m32|m64}
+    4959             :   ASMJIT_INST_1x(imul, Imul, X86Gp)                                           // ANY       [IMPLICIT] {AX <- AL * r8} {xAX:xDX <- xAX * r16|r32|r64}
+    4960             :   ASMJIT_INST_1x(imul, Imul, X86Mem)                                          // ANY       [IMPLICIT] {AX <- AL * m8} {xAX:xDX <- xAX * m16|m32|m64}
+    4961             :   ASMJIT_INST_0x(iret, Iret)                                                  // ANY       [IMPLICIT]
+    4962             :   ASMJIT_INST_0x(iretd, Iretd)                                                // ANY       [IMPLICIT]
+    4963             :   ASMJIT_INST_0x(iretq, Iretq)                                                // X64       [IMPLICIT]
+    4964             :   ASMJIT_INST_0x(iretw, Iretw)                                                // ANY       [IMPLICIT]
+    4965             :   ASMJIT_INST_1x(jecxz, Jecxz, Label)                                         // ANY       [IMPLICIT] Short jump if CX/ECX/RCX is zero.
+    4966             :   ASMJIT_INST_1x(jecxz, Jecxz, Imm)                                           // ANY       [IMPLICIT] Short jump if CX/ECX/RCX is zero.
+    4967             :   ASMJIT_INST_1x(jecxz, Jecxz, uint64_t)                                      // ANY       [IMPLICIT] Short jump if CX/ECX/RCX is zero.
+    4968             :   ASMJIT_INST_0x(lahf, Lahf)                                                  // LAHFSAHF  [IMPLICIT] AH <- EFL
+    4969             :   ASMJIT_INST_1x(loop, Loop, Label)                                           // ANY       [IMPLICIT] Decrement xCX; short jump if xCX != 0.
+    4970             :   ASMJIT_INST_1x(loop, Loop, Imm)                                             // ANY       [IMPLICIT] Decrement xCX; short jump if xCX != 0.
+    4971             :   ASMJIT_INST_1x(loop, Loop, uint64_t)                                        // ANY       [IMPLICIT] Decrement xCX; short jump if xCX != 0.
+    4972             :   ASMJIT_INST_1x(loope, Loope, Label)                                         // ANY       [IMPLICIT] Decrement xCX; short jump if xCX != 0 && ZF == 1.
+    4973             :   ASMJIT_INST_1x(loope, Loope, Imm)                                           // ANY       [IMPLICIT] Decrement xCX; short jump if xCX != 0 && ZF == 1.
+    4974             :   ASMJIT_INST_1x(loope, Loope, uint64_t)                                      // ANY       [IMPLICIT] Decrement xCX; short jump if xCX != 0 && ZF == 1.
+    4975             :   ASMJIT_INST_1x(loopne, Loopne, Label)                                       // ANY       [IMPLICIT] Decrement xCX; short jump if xCX != 0 && ZF == 0.
+    4976             :   ASMJIT_INST_1x(loopne, Loopne, Imm)                                         // ANY       [IMPLICIT] Decrement xCX; short jump if xCX != 0 && ZF == 0.
+    4977             :   ASMJIT_INST_1x(loopne, Loopne, uint64_t)                                    // ANY       [IMPLICIT] Decrement xCX; short jump if xCX != 0 && ZF == 0.
+    4978             :   ASMJIT_INST_1x(mul, Mul, X86Gp)                                             // ANY       [IMPLICIT] {AX <- AL * r8} {xDX:xAX <- xAX * r16|r32|r64}
+    4979             :   ASMJIT_INST_1x(mul, Mul, X86Mem)                                            // ANY       [IMPLICIT] {AX <- AL * m8} {xDX:xAX <- xAX * m16|m32|m64}
+    4980             :   ASMJIT_INST_3x(mulx, Mulx, X86Gp, X86Gp, X86Gp)                             // BMI2      [IMPLICIT]
+    4981             :   ASMJIT_INST_3x(mulx, Mulx, X86Gp, X86Gp, X86Mem)                            // BMI2      [IMPLICIT]
+    4982             :   ASMJIT_INST_0x(rdmsr, Rdmsr)                                                // ANY       [IMPLICIT]
+    4983             :   ASMJIT_INST_0x(rdpmc, Rdpmc)                                                // ANY       [IMPLICIT]
+    4984             :   ASMJIT_INST_0x(rdtsc, Rdtsc)                                                // RDTSC     [IMPLICIT] EDX:EAX <- CNT
+    4985             :   ASMJIT_INST_0x(rdtscp, Rdtscp)                                              // RDTSCP    [IMPLICIT] EDX:EAX:EXC <- CNT
+    4986             :   ASMJIT_INST_0x(ret, Ret)
+    4987             :   ASMJIT_INST_1i(ret, Ret, Imm)
+    4988             :   ASMJIT_INST_0x(sahf, Sahf)                                                  // LAHFSAHF  [IMPLICIT] EFL <- AH
+    4989             :   ASMJIT_INST_0x(syscall, Syscall)                                            // X64       [IMPLICIT]
+    4990             :   ASMJIT_INST_0x(sysenter, Sysenter)                                          // X64       [IMPLICIT]
+    4991             :   ASMJIT_INST_0x(sysexit, Sysexit)                                            // X64       [IMPLICIT]
+    4992             :   ASMJIT_INST_0x(sysexit64, Sysexit64)                                        // X64       [IMPLICIT]
+    4993             :   ASMJIT_INST_0x(sysret, Sysret)                                              // X64       [IMPLICIT]
+    4994             :   ASMJIT_INST_0x(sysret64, Sysret64)                                          // X64       [IMPLICIT]
+    4995             :   ASMJIT_INST_0x(wrmsr, Wrmsr)                                                // ANY       [IMPLICIT]
+    4996             :   ASMJIT_INST_0x(xgetbv, Xgetbv)                                              // XSAVE     [IMPLICIT] EDX:EAX <- XCR[ECX]
+    4997             :   ASMJIT_INST_0x(xlatb, Xlatb)                                                // ANY       [IMPLICIT]
+    4998             :   ASMJIT_INST_1x(xrstor, Xrstor, X86Mem)                                      // XSAVE     [IMPLICIT]
+    4999             :   ASMJIT_INST_1x(xrstor64, Xrstor64, X86Mem)                                  // XSAVE+X64 [IMPLICIT]
+    5000             :   ASMJIT_INST_1x(xrstors, Xrstors, X86Mem)                                    // XSAVE     [IMPLICIT]
+    5001             :   ASMJIT_INST_1x(xrstors64, Xrstors64, X86Mem)                                // XSAVE+X64 [IMPLICIT]
+    5002             :   ASMJIT_INST_1x(xsave, Xsave, X86Mem)                                        // XSAVE     [IMPLICIT]
+    5003             :   ASMJIT_INST_1x(xsave64, Xsave64, X86Mem)                                    // XSAVE+X64 [IMPLICIT]
+    5004             :   ASMJIT_INST_1x(xsavec, Xsavec, X86Mem)                                      // XSAVE     [IMPLICIT]
+    5005             :   ASMJIT_INST_1x(xsavec64, Xsavec64, X86Mem)                                  // XSAVE+X64 [IMPLICIT]
+    5006             :   ASMJIT_INST_1x(xsaveopt, Xsaveopt, X86Mem)                                  // XSAVE     [IMPLICIT]
+    5007             :   ASMJIT_INST_1x(xsaveopt64, Xsaveopt64, X86Mem)                              // XSAVE+X64 [IMPLICIT]
+    5008             :   ASMJIT_INST_1x(xsaves, Xsaves, X86Mem)                                      // XSAVE     [IMPLICIT]
+    5009             :   ASMJIT_INST_1x(xsaves64, Xsaves64, X86Mem)                                  // XSAVE+X64 [IMPLICIT]
+    5010             :   ASMJIT_INST_0x(xsetbv, Xsetbv)                                              // XSAVE     [IMPLICIT] XCR[ECX] <- EDX:EAX
+    5011             : 
+    5012             :   // String instructions aliases.
+    5013             :   ASMJIT_INLINE Error cmpsb() { return ASMJIT_EMIT(X86Inst::kIdCmps, X86EmitterExplicitT<This>::ptr_zsi(0, 1), X86EmitterExplicitT<This>::ptr_zdi(0, 1)); }
+    5014             :   ASMJIT_INLINE Error cmpsd() { return ASMJIT_EMIT(X86Inst::kIdCmps, X86EmitterExplicitT<This>::ptr_zsi(0, 4), X86EmitterExplicitT<This>::ptr_zdi(0, 4)); }
+    5015             :   ASMJIT_INLINE Error cmpsq() { return ASMJIT_EMIT(X86Inst::kIdCmps, X86EmitterExplicitT<This>::ptr_zsi(0, 8), X86EmitterExplicitT<This>::ptr_zdi(0, 8)); }
+    5016             :   ASMJIT_INLINE Error cmpsw() { return ASMJIT_EMIT(X86Inst::kIdCmps, X86EmitterExplicitT<This>::ptr_zsi(0, 2), X86EmitterExplicitT<This>::ptr_zdi(0, 2)); }
+    5017             : 
+    5018             :   ASMJIT_INLINE Error lodsb() { return ASMJIT_EMIT(X86Inst::kIdLods, x86::al , X86EmitterExplicitT<This>::ptr_zdi(0, 1)); }
+    5019             :   ASMJIT_INLINE Error lodsd() { return ASMJIT_EMIT(X86Inst::kIdLods, x86::eax, X86EmitterExplicitT<This>::ptr_zdi(0, 4)); }
+    5020             :   ASMJIT_INLINE Error lodsq() { return ASMJIT_EMIT(X86Inst::kIdLods, x86::rax, X86EmitterExplicitT<This>::ptr_zdi(0, 8)); }
+    5021             :   ASMJIT_INLINE Error lodsw() { return ASMJIT_EMIT(X86Inst::kIdLods, x86::ax , X86EmitterExplicitT<This>::ptr_zdi(0, 2)); }
+    5022             : 
+    5023             :   ASMJIT_INLINE Error movsb() { return ASMJIT_EMIT(X86Inst::kIdMovs, X86EmitterExplicitT<This>::ptr_zdi(0, 1), X86EmitterExplicitT<This>::ptr_zsi(0, 1)); }
+    5024             :   ASMJIT_INLINE Error movsd() { return ASMJIT_EMIT(X86Inst::kIdMovs, X86EmitterExplicitT<This>::ptr_zdi(0, 4), X86EmitterExplicitT<This>::ptr_zsi(0, 4)); }
+    5025             :   ASMJIT_INLINE Error movsq() { return ASMJIT_EMIT(X86Inst::kIdMovs, X86EmitterExplicitT<This>::ptr_zdi(0, 8), X86EmitterExplicitT<This>::ptr_zsi(0, 8)); }
+    5026             :   ASMJIT_INLINE Error movsw() { return ASMJIT_EMIT(X86Inst::kIdMovs, X86EmitterExplicitT<This>::ptr_zdi(0, 2), X86EmitterExplicitT<This>::ptr_zsi(0, 2)); }
+    5027             : 
+    5028             :   ASMJIT_INLINE Error scasb() { return ASMJIT_EMIT(X86Inst::kIdScas, x86::al , X86EmitterExplicitT<This>::ptr_zdi(0, 1)); }
+    5029             :   ASMJIT_INLINE Error scasd() { return ASMJIT_EMIT(X86Inst::kIdScas, x86::eax, X86EmitterExplicitT<This>::ptr_zdi(0, 4)); }
+    5030             :   ASMJIT_INLINE Error scasq() { return ASMJIT_EMIT(X86Inst::kIdScas, x86::rax, X86EmitterExplicitT<This>::ptr_zdi(0, 8)); }
+    5031             :   ASMJIT_INLINE Error scasw() { return ASMJIT_EMIT(X86Inst::kIdScas, x86::ax , X86EmitterExplicitT<This>::ptr_zdi(0, 2)); }
+    5032             : 
+    5033             :   ASMJIT_INLINE Error stosb() { return ASMJIT_EMIT(X86Inst::kIdStos, X86EmitterExplicitT<This>::ptr_zdi(0, 1), x86::al ); }
+    5034             :   ASMJIT_INLINE Error stosd() { return ASMJIT_EMIT(X86Inst::kIdStos, X86EmitterExplicitT<This>::ptr_zdi(0, 4), x86::eax); }
+    5035             :   ASMJIT_INLINE Error stosq() { return ASMJIT_EMIT(X86Inst::kIdStos, X86EmitterExplicitT<This>::ptr_zdi(0, 8), x86::rax); }
+    5036             :   ASMJIT_INLINE Error stosw() { return ASMJIT_EMIT(X86Inst::kIdStos, X86EmitterExplicitT<This>::ptr_zdi(0, 2), x86::ax ); }
+    5037             : 
+    5038             :   // --------------------------------------------------------------------------
+    5039             :   // [MONITOR|MWAIT]
+    5040             :   // --------------------------------------------------------------------------
+    5041             : 
+    5042             :   ASMJIT_INST_0x(monitor, Monitor)
+    5043             :   ASMJIT_INST_0x(mwait, Mwait)
+    5044             : 
+    5045             :   // --------------------------------------------------------------------------
+    5046             :   // [MMX & SSE Instructions]
+    5047             :   // --------------------------------------------------------------------------
+    5048             : 
+    5049             :   using X86EmitterExplicitT<This>::blendvpd;
+    5050             :   using X86EmitterExplicitT<This>::blendvps;
+    5051             :   using X86EmitterExplicitT<This>::maskmovq;
+    5052             :   using X86EmitterExplicitT<This>::maskmovdqu;
+    5053             :   using X86EmitterExplicitT<This>::pblendvb;
+    5054             :   using X86EmitterExplicitT<This>::pcmpestri;
+    5055             :   using X86EmitterExplicitT<This>::pcmpestrm;
+    5056             :   using X86EmitterExplicitT<This>::pcmpistri;
+    5057             :   using X86EmitterExplicitT<This>::pcmpistrm;
+    5058             : 
+    5059             :   ASMJIT_INST_2x(blendvpd, Blendvpd, X86Xmm, X86Xmm)                          // SSE4_1 [IMPLICIT]
+    5060             :   ASMJIT_INST_2x(blendvpd, Blendvpd, X86Xmm, X86Mem)                          // SSE4_1 [IMPLICIT]
+    5061             :   ASMJIT_INST_2x(blendvps, Blendvps, X86Xmm, X86Xmm)                          // SSE4_1 [IMPLICIT]
+    5062             :   ASMJIT_INST_2x(blendvps, Blendvps, X86Xmm, X86Mem)                          // SSE4_1 [IMPLICIT]
+    5063             :   ASMJIT_INST_2x(pblendvb, Pblendvb, X86Xmm, X86Xmm)                          // SSE4_1 [IMPLICIT]
+    5064             :   ASMJIT_INST_2x(pblendvb, Pblendvb, X86Xmm, X86Mem)                          // SSE4_1 [IMPLICIT]
+    5065             :   ASMJIT_INST_2x(maskmovq, Maskmovq, X86Mm, X86Mm)                            // SSE    [IMPLICIT]
+    5066             :   ASMJIT_INST_2x(maskmovdqu, Maskmovdqu, X86Xmm, X86Xmm)                      // SSE2   [IMPLICIT]
+    5067             :   ASMJIT_INST_3i(pcmpestri, Pcmpestri, X86Xmm, X86Xmm, Imm)                   // SSE4_1 [IMPLICIT]
+    5068             :   ASMJIT_INST_3i(pcmpestri, Pcmpestri, X86Xmm, X86Mem, Imm)                   // SSE4_1 [IMPLICIT]
+    5069             :   ASMJIT_INST_3i(pcmpestrm, Pcmpestrm, X86Xmm, X86Xmm, Imm)                   // SSE4_1 [IMPLICIT]
+    5070             :   ASMJIT_INST_3i(pcmpestrm, Pcmpestrm, X86Xmm, X86Mem, Imm)                   // SSE4_1 [IMPLICIT]
+    5071             :   ASMJIT_INST_3i(pcmpistri, Pcmpistri, X86Xmm, X86Xmm, Imm)                   // SSE4_1 [IMPLICIT]
+    5072             :   ASMJIT_INST_3i(pcmpistri, Pcmpistri, X86Xmm, X86Mem, Imm)                   // SSE4_1 [IMPLICIT]
+    5073             :   ASMJIT_INST_3i(pcmpistrm, Pcmpistrm, X86Xmm, X86Xmm, Imm)                   // SSE4_1 [IMPLICIT]
+    5074             :   ASMJIT_INST_3i(pcmpistrm, Pcmpistrm, X86Xmm, X86Mem, Imm)                   // SSE4_1 [IMPLICIT]
+    5075             : 
+    5076             :   // --------------------------------------------------------------------------
+    5077             :   // [SHA]
+    5078             :   // --------------------------------------------------------------------------
+    5079             : 
+    5080             :   using X86EmitterExplicitT<This>::sha256rnds2;
+    5081             : 
+    5082             :   ASMJIT_INST_2x(sha256rnds2, Sha256rnds2, X86Xmm, X86Xmm)                    // SHA [IMPLICIT]
+    5083             :   ASMJIT_INST_2x(sha256rnds2, Sha256rnds2, X86Xmm, X86Mem)                    // SHA [IMPLICIT]
+    5084             : 
+    5085             :   // --------------------------------------------------------------------------
+    5086             :   // [AVX...AVX512]
+    5087             :   // --------------------------------------------------------------------------
+    5088             : 
+    5089             :   using X86EmitterExplicitT<This>::vmaskmovdqu;
+    5090             :   using X86EmitterExplicitT<This>::vpcmpestri;
+    5091             :   using X86EmitterExplicitT<This>::vpcmpestrm;
+    5092             :   using X86EmitterExplicitT<This>::vpcmpistri;
+    5093             :   using X86EmitterExplicitT<This>::vpcmpistrm;
+    5094             : 
+    5095             :   ASMJIT_INST_2x(vmaskmovdqu, Vmaskmovdqu, X86Xmm, X86Xmm)                    // AVX  [IMPLICIT]
+    5096             :   ASMJIT_INST_3i(vpcmpestri, Vpcmpestri, X86Xmm, X86Xmm, Imm)                 // AVX  [IMPLICIT]
+    5097             :   ASMJIT_INST_3i(vpcmpestri, Vpcmpestri, X86Xmm, X86Mem, Imm)                 // AVX  [IMPLICIT]
+    5098             :   ASMJIT_INST_3i(vpcmpestrm, Vpcmpestrm, X86Xmm, X86Xmm, Imm)                 // AVX  [IMPLICIT]
+    5099             :   ASMJIT_INST_3i(vpcmpestrm, Vpcmpestrm, X86Xmm, X86Mem, Imm)                 // AVX  [IMPLICIT]
+    5100             :   ASMJIT_INST_3i(vpcmpistri, Vpcmpistri, X86Xmm, X86Xmm, Imm)                 // AVX  [IMPLICIT]
+    5101             :   ASMJIT_INST_3i(vpcmpistri, Vpcmpistri, X86Xmm, X86Mem, Imm)                 // AVX  [IMPLICIT]
+    5102             :   ASMJIT_INST_3i(vpcmpistrm, Vpcmpistrm, X86Xmm, X86Xmm, Imm)                 // AVX  [IMPLICIT]
+    5103             :   ASMJIT_INST_3i(vpcmpistrm, Vpcmpistrm, X86Xmm, X86Mem, Imm)                 // AVX  [IMPLICIT]
+    5104             : };
+    5105             : 
+    5106             : #undef ASMJIT_INST_0x
+    5107             : #undef ASMJIT_INST_1x
+    5108             : #undef ASMJIT_INST_1i
+    5109             : #undef ASMJIT_INST_1c
+    5110             : #undef ASMJIT_INST_2x
+    5111             : #undef ASMJIT_INST_2i
+    5112             : #undef ASMJIT_INST_2c
+    5113             : #undef ASMJIT_INST_3x
+    5114             : #undef ASMJIT_INST_3i
+    5115             : #undef ASMJIT_INST_3ii
+    5116             : #undef ASMJIT_INST_4x
+    5117             : #undef ASMJIT_INST_4i
+    5118             : #undef ASMJIT_INST_4ii
+    5119             : #undef ASMJIT_INST_5x
+    5120             : #undef ASMJIT_INST_5i
+    5121             : #undef ASMJIT_INST_6x
+    5122             : #undef ASMJIT_EMIT
+    5123             : 
+    5124             : // ============================================================================
+    5125             : // [asmjit::X86Emitter]
+    5126             : // ============================================================================
+    5127             : 
+    5128             : //! X86/X64 emitter.
+    5129             : //!
+    5130             : //! NOTE: This class cannot be created, you can only cast to it and use it as
+    5131             : //! emitter that emits to either X86Assembler, X86Builder, or X86Compiler (use
+    5132             : //! with caution with X86Compiler as it expects virtual registers to be used).
+    5133             : class X86Emitter : public CodeEmitter, public X86EmitterImplicitT<X86Emitter> {
+    5134             :   ASMJIT_NONCONSTRUCTIBLE(X86Emitter)
+    5135             : };
+    5136             : 
+    5137             : //! \}
+    5138             : 
+    5139             : } // asmjit namespace
+    5140             : } // namespace PLMD
+    5141             : 
+    5142             : // [Api-End]
+    5143             : #include "./asmjit_apiend.h"
+    5144             : 
+    5145             : // [Guard]
+    5146             : #endif // _ASMJIT_X86_X86EMITTER_H
+    5147             : #pragma GCC diagnostic pop
+    5148             : #endif // __PLUMED_HAS_ASMJIT
+    5149             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86inst.cpp.func-sort-c.html b/coverage-libs/asmjit/x86inst.cpp.func-sort-c.html new file mode 100644 index 000000000000..be39ce1bc6f6 --- /dev/null +++ b/coverage-libs/asmjit/x86inst.cpp.func-sort-c.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86inst.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86inst.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:0240.0 %
Date:2024-04-19 12:12:36Functions:020.0 %
+
+ +
+ + + + + + + + + + + + + + +

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

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

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2008-2017, Petr Kobalicek
+       3             : 
+       4             : This software is provided 'as-is', without any express or implied
+       5             : warranty. In no event will the authors be held liable for any damages
+       6             : arising from the use of this software.
+       7             : 
+       8             : Permission is granted to anyone to use this software for any purpose,
+       9             : including commercial applications, and to alter it and redistribute it
+      10             : freely, subject to the following restrictions:
+      11             : 
+      12             : 1. The origin of this software must not be misrepresented; you must not
+      13             :    claim that you wrote the original software. If you use this software
+      14             :    in a product, an acknowledgment in the product documentation would be
+      15             :    appreciated but is not required.
+      16             : 2. Altered source versions must be plainly marked as such, and must not be
+      17             :    misrepresented as being the original software.
+      18             : 3. This notice may not be removed or altered from any source distribution.
+      19             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      20             : #ifdef __PLUMED_HAS_ASMJIT
+      21             : #pragma GCC diagnostic push
+      22             : #pragma GCC diagnostic ignored "-Wpedantic"
+      23             : // [AsmJit]
+      24             : // Complete x86/x64 JIT and Remote Assembler for C++.
+      25             : //
+      26             : // [License]
+      27             : // Zlib - See LICENSE.md file in the package.
+      28             : 
+      29             : // ----------------------------------------------------------------------------
+      30             : // IMPORTANT: AsmJit now uses an external instruction database to populate
+      31             : // static tables within this file. Perform the following steps to regenerate
+      32             : // all tables enclosed by ${...}:
+      33             : //
+      34             : //   1. Install node.js environment <https://nodejs.org>
+      35             : //   2. Go to asmjit/tools directory
+      36             : //   3. Install either asmdb package by executing `npm install asmdb` or get
+      37             : //      the latest asmdb from <https://github.com/asmjit/asmdb> and copy/link
+      38             : //      the `asmdb` directory to `asmjit/tools/asmdb`.
+      39             : //   4. Execute `node generate-x86.js`
+      40             : //
+      41             : // Instruction encoding and opcodes were added to the `x86inst.cpp` database
+      42             : // manually in the past and they are not updated by the script as they seem
+      43             : // consistent. However, everything else is updated including instruction
+      44             : // operands and tables required to validate them, instruction read/write
+      45             : // information (including registers and flags), and all indexes to all tables.
+      46             : // ----------------------------------------------------------------------------
+      47             : 
+      48             : // [Export]
+      49             : #define ASMJIT_EXPORTS
+      50             : 
+      51             : // [Guard]
+      52             : #include "./asmjit_build.h"
+      53             : #if defined(ASMJIT_BUILD_X86)
+      54             : 
+      55             : // [Dependencies]
+      56             : #include "./cpuinfo.h"
+      57             : #include "./utils.h"
+      58             : #include "./x86inst.h"
+      59             : #include "./x86operand.h"
+      60             : 
+      61             : // [Api-Begin]
+      62             : #include "./asmjit_apibegin.h"
+      63             : 
+      64             : namespace PLMD {
+      65             : namespace asmjit {
+      66             : 
+      67             : // ============================================================================
+      68             : // [Enums (Internal)]
+      69             : // ============================================================================
+      70             : 
+      71             : //! \internal
+      72             : enum ODATA_ {
+      73             :   // PREFIX.
+      74             :   ODATA_000000  = X86Inst::kOpCode_PP_00 | X86Inst::kOpCode_MM_00,
+      75             :   ODATA_000F00  = X86Inst::kOpCode_PP_00 | X86Inst::kOpCode_MM_0F,
+      76             :   ODATA_000F01  = X86Inst::kOpCode_PP_00 | X86Inst::kOpCode_MM_0F01,
+      77             :   ODATA_000F38  = X86Inst::kOpCode_PP_00 | X86Inst::kOpCode_MM_0F38,
+      78             :   ODATA_000F3A  = X86Inst::kOpCode_PP_00 | X86Inst::kOpCode_MM_0F3A,
+      79             :   ODATA_660000  = X86Inst::kOpCode_PP_66 | X86Inst::kOpCode_MM_00,
+      80             :   ODATA_660F00  = X86Inst::kOpCode_PP_66 | X86Inst::kOpCode_MM_0F,
+      81             :   ODATA_660F38  = X86Inst::kOpCode_PP_66 | X86Inst::kOpCode_MM_0F38,
+      82             :   ODATA_660F3A  = X86Inst::kOpCode_PP_66 | X86Inst::kOpCode_MM_0F3A,
+      83             :   ODATA_F20000  = X86Inst::kOpCode_PP_F2 | X86Inst::kOpCode_MM_00,
+      84             :   ODATA_F20F00  = X86Inst::kOpCode_PP_F2 | X86Inst::kOpCode_MM_0F,
+      85             :   ODATA_F20F38  = X86Inst::kOpCode_PP_F2 | X86Inst::kOpCode_MM_0F38,
+      86             :   ODATA_F20F3A  = X86Inst::kOpCode_PP_F2 | X86Inst::kOpCode_MM_0F3A,
+      87             :   ODATA_F30000  = X86Inst::kOpCode_PP_F3 | X86Inst::kOpCode_MM_00,
+      88             :   ODATA_F30F00  = X86Inst::kOpCode_PP_F3 | X86Inst::kOpCode_MM_0F,
+      89             :   ODATA_F30F38  = X86Inst::kOpCode_PP_F3 | X86Inst::kOpCode_MM_0F38,
+      90             :   ODATA_F30F3A  = X86Inst::kOpCode_PP_F3 | X86Inst::kOpCode_MM_0F3A,
+      91             :   ODATA_000F0F  = X86Inst::kOpCode_PP_00 | X86Inst::kOpCode_MM_0F, // 3DNOW, special case.
+      92             : 
+      93             :   ODATA_FPU_00  = X86Inst::kOpCode_PP_00,
+      94             :   ODATA_FPU_9B  = X86Inst::kOpCode_PP_9B,
+      95             : 
+      96             :   ODATA_XOP_M8  = X86Inst::kOpCode_MM_XOP08,
+      97             :   ODATA_XOP_M9  = X86Inst::kOpCode_MM_XOP09,
+      98             : 
+      99             :   ODATA_O__     = 0,
+     100             :   ODATA_O_0     = 0 << X86Inst::kOpCode_O_Shift,
+     101             :   ODATA_O_1     = 1 << X86Inst::kOpCode_O_Shift,
+     102             :   ODATA_O_2     = 2 << X86Inst::kOpCode_O_Shift,
+     103             :   ODATA_O_3     = 3 << X86Inst::kOpCode_O_Shift,
+     104             :   ODATA_O_4     = 4 << X86Inst::kOpCode_O_Shift,
+     105             :   ODATA_O_5     = 5 << X86Inst::kOpCode_O_Shift,
+     106             :   ODATA_O_6     = 6 << X86Inst::kOpCode_O_Shift,
+     107             :   ODATA_O_7     = 7 << X86Inst::kOpCode_O_Shift,
+     108             : 
+     109             :   // REX/VEX.
+     110             :   ODATA_LL__    = 0,                                  // L is unspecified.
+     111             :   ODATA_LL_x    = 0,                                  // L is based on operand(s).
+     112             :   ODATA_LL_I    = 0,                                  // L is ignored (LIG).
+     113             :   ODATA_LL_0    = 0,                                  // L has to be zero (L.128).
+     114             :   ODATA_LL_1    = X86Inst::kOpCode_LL_256,            // L has to be one (L.256).
+     115             :   ODATA_LL_2    = X86Inst::kOpCode_LL_512,            // L has to be two (L.512).
+     116             : 
+     117             :   ODATA_W__     = 0,                                  // W is unspecified.
+     118             :   ODATA_W_x     = 0,                                  // W is based on operand(s).
+     119             :   ODATA_W_I     = 0,                                  // W is ignored (WIG).
+     120             :   ODATA_W_0     = 0,                                  // W has to be zero (W0).
+     121             :   ODATA_W_1     = X86Inst::kOpCode_W,                 // W has to be one (W1).
+     122             : 
+     123             :   // EVEX.
+     124             :   ODATA_EvexW__ = 0,                                  // Not EVEX instruction.
+     125             :   ODATA_EvexW_x = 0,                                  // EVEX.W is based on operand(s).
+     126             :   ODATA_EvexW_I = 0,                                  // EVEX.W is ignored     (EVEX.WIG).
+     127             :   ODATA_EvexW_0 = 0,                                  // EVEX.W has to be zero (EVEX.W0).
+     128             :   ODATA_EvexW_1 = X86Inst::kOpCode_EW,                // EVEX.W has to be one  (EVEX.W1).
+     129             : 
+     130             :   ODATA_N__      = 0,                                 // Base element size not used.
+     131             :   ODATA_N_0      = 0 << X86Inst::kOpCode_CDSHL_Shift, // N << 0 (BYTE).
+     132             :   ODATA_N_1      = 1 << X86Inst::kOpCode_CDSHL_Shift, // N << 1 (WORD).
+     133             :   ODATA_N_2      = 2 << X86Inst::kOpCode_CDSHL_Shift, // N << 2 (DWORD).
+     134             :   ODATA_N_3      = 3 << X86Inst::kOpCode_CDSHL_Shift, // N << 3 (QWORD).
+     135             :   ODATA_N_4      = 4 << X86Inst::kOpCode_CDSHL_Shift, // N << 4 (OWORD).
+     136             :   ODATA_N_5      = 5 << X86Inst::kOpCode_CDSHL_Shift, // N << 5 (YWORD).
+     137             : 
+     138             :   ODATA_TT__     = 0,
+     139             :   ODATA_TT_FV    = X86Inst::kOpCode_CDTT_FV,
+     140             :   ODATA_TT_HV    = X86Inst::kOpCode_CDTT_HV,
+     141             :   ODATA_TT_FVM   = X86Inst::kOpCode_CDTT_FVM,
+     142             :   ODATA_TT_T1S   = X86Inst::kOpCode_CDTT_T1S,
+     143             :   ODATA_TT_T1F   = X86Inst::kOpCode_CDTT_T1F,
+     144             :   ODATA_TT_T1W   = X86Inst::kOpCode_CDTT_T1W,
+     145             :   ODATA_TT_T2    = X86Inst::kOpCode_CDTT_T2,
+     146             :   ODATA_TT_T4    = X86Inst::kOpCode_CDTT_T4,
+     147             :   ODATA_TT_T8    = X86Inst::kOpCode_CDTT_T8,
+     148             :   ODATA_TT_HVM   = X86Inst::kOpCode_CDTT_HVM,
+     149             :   ODATA_TT_OVM   = X86Inst::kOpCode_CDTT_OVM,
+     150             :   ODATA_TT_QVM   = X86Inst::kOpCode_CDTT_QVM,
+     151             :   ODATA_TT_128   = X86Inst::kOpCode_CDTT_128,
+     152             :   ODATA_TT_DUP   = X86Inst::kOpCode_CDTT_DUP,
+     153             :   ODATA_TT_T4X   = X86Inst::kOpCode_CDTT_T1_4X
+     154             : };
+     155             : 
+     156             : // ============================================================================
+     157             : // [asmjit::X86Inst]
+     158             : // ============================================================================
+     159             : 
+     160             : // Instruction opcode definitions:
+     161             : //   - `O` encodes X86|MMX|SSE instructions.
+     162             : //   - `V` encodes VEX|XOP|EVEX instructions.
+     163             : #define O_ENCODE(VEX, PREFIX, OPCODE, O, L, W, EvexW, N, TT) \
+     164             :   ((PREFIX) | (OPCODE) | (O) | (L) | (W) | (EvexW) | (N) | (TT) | \
+     165             :    (VEX && ((PREFIX) & X86Inst::kOpCode_MM_Mask) != X86Inst::kOpCode_MM_0F ? int(X86Inst::kOpCode_MM_ForceVex3) : 0))
+     166             : 
+     167             : #define O(PREFIX, OPCODE, O, LL, W, EvexW, N, TT) (O_ENCODE(0, ODATA_##PREFIX, 0x##OPCODE, ODATA_O_##O, ODATA_LL_##LL, ODATA_W_##W, ODATA_EvexW_##EvexW, ODATA_N_##N, ODATA_TT_##TT))
+     168             : #define V(PREFIX, OPCODE, O, LL, W, EvexW, N, TT) (O_ENCODE(1, ODATA_##PREFIX, 0x##OPCODE, ODATA_O_##O, ODATA_LL_##LL, ODATA_W_##W, ODATA_EvexW_##EvexW, ODATA_N_##N, ODATA_TT_##TT))
+     169             : 
+     170             : #define O_FPU(PREFIX, OPCODE, O) (ODATA_FPU_##PREFIX | (0x##OPCODE & 0xFFU) | ((0x##OPCODE >> 8) << X86Inst::kOpCode_FPU_2B_Shift) | ODATA_O_##O)
+     171             : 
+     172             : // Don't store `_nameDataIndex` if instruction names are disabled. Since some
+     173             : // APIs can use `_nameDataIndex` it's much safer if it's zero if it's not used.
+     174             : #if defined(ASMJIT_DISABLE_TEXT)
+     175             : # define NAME_DATA_INDEX(X) 0
+     176             : #else
+     177             : # define NAME_DATA_INDEX(X) X
+     178             : #endif
+     179             : 
+     180             : // Defines an X86/X64 instruction.
+     181             : #define INST(id, encoding, opcode0, opcode1, writeIndex, writeSize, nameDataIndex, commonDataIndex, operationDataIndex, seeToAvxDataIndex) { \
+     182             :   uint32_t(X86Inst::kEncoding##encoding),   \
+     183             :   uint32_t(NAME_DATA_INDEX(nameDataIndex)), \
+     184             :   uint32_t(commonDataIndex),                \
+     185             :   uint32_t(operationDataIndex),             \
+     186             :   uint32_t(seeToAvxDataIndex),              \
+     187             :   0,                                        \
+     188             :   opcode0                                   \
+     189             : }
+     190             : const X86Inst X86InstDB::instData[] = {
+     191             :   // <-----------------+--------------------+------------------+--------+------------------+--------+-------+-----+----+----+---+
+     192             :   //                   |                    |    Main OpCode   |#0 EVEX |Alternative OpCode|#1 EVEX | Write |     |    |    |Sse|
+     193             :   //    Instruction    |   Inst. Encoding   |                  +--------+                  +--------+---+---+NameX|ComX|OpnX|<->|
+     194             :   //                   |                    |#0:PP-MMM OP/O L|W|W|N|TT. |#1:PP-MMM OP/O L|W|W|N|TT. |Idx|Cnt|     |    |    |Avx|
+     195             :   // <-----------------+--------------------+------------------+--------+------------------+--------+---+---+-----+----+----+---+
+     196             :   // ${instData:Begin}
+     197             :   INST(None            , None               , 0                         , 0                         , 0 , 0 , 0   , 0  , 0  , 0 ),
+     198             :   INST(Aaa             , X86Op_xAX          , O(000000,37,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1   , 1  , 1  , 0 ),
+     199             :   INST(Aad             , X86I_xAX           , O(000000,D5,_,_,_,_,_,_  ), 0                         , 0 , 0 , 5   , 2  , 1  , 0 ),
+     200             :   INST(Aam             , X86I_xAX           , O(000000,D4,_,_,_,_,_,_  ), 0                         , 0 , 0 , 9   , 2  , 1  , 0 ),
+     201             :   INST(Aas             , X86Op_xAX          , O(000000,3F,_,_,_,_,_,_  ), 0                         , 0 , 0 , 13  , 1  , 1  , 0 ),
+     202             :   INST(Adc             , X86Arith           , O(000000,10,2,_,x,_,_,_  ), 0                         , 0 , 0 , 17  , 3  , 2  , 0 ),
+     203             :   INST(Adcx            , X86Rm              , O(660F38,F6,_,_,x,_,_,_  ), 0                         , 0 , 0 , 21  , 4  , 3  , 0 ),
+     204             :   INST(Add             , X86Arith           , O(000000,00,0,_,x,_,_,_  ), 0                         , 0 , 0 , 732 , 3  , 1  , 0 ),
+     205             :   INST(Addpd           , ExtRm              , O(660F00,58,_,_,_,_,_,_  ), 0                         , 0 , 0 , 4619, 5  , 4  , 1 ),
+     206             :   INST(Addps           , ExtRm              , O(000F00,58,_,_,_,_,_,_  ), 0                         , 0 , 0 , 4631, 5  , 5  , 1 ),
+     207             :   INST(Addsd           , ExtRm              , O(F20F00,58,_,_,_,_,_,_  ), 0                         , 0 , 0 , 4853, 6  , 4  , 1 ),
+     208             :   INST(Addss           , ExtRm              , O(F30F00,58,_,_,_,_,_,_  ), 0                         , 0 , 0 , 4863, 7  , 5  , 1 ),
+     209             :   INST(Addsubpd        , ExtRm              , O(660F00,D0,_,_,_,_,_,_  ), 0                         , 0 , 0 , 4358, 5  , 6  , 1 ),
+     210             :   INST(Addsubps        , ExtRm              , O(F20F00,D0,_,_,_,_,_,_  ), 0                         , 0 , 0 , 4370, 5  , 6  , 1 ),
+     211             :   INST(Adox            , X86Rm              , O(F30F38,F6,_,_,x,_,_,_  ), 0                         , 0 , 0 , 26  , 4  , 7  , 0 ),
+     212             :   INST(Aesdec          , ExtRm              , O(660F38,DE,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2854, 5  , 8  , 2 ),
+     213             :   INST(Aesdeclast      , ExtRm              , O(660F38,DF,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2862, 5  , 8  , 2 ),
+     214             :   INST(Aesenc          , ExtRm              , O(660F38,DC,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2874, 5  , 8  , 2 ),
+     215             :   INST(Aesenclast      , ExtRm              , O(660F38,DD,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2882, 5  , 8  , 2 ),
+     216             :   INST(Aesimc          , ExtRm              , O(660F38,DB,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2894, 8  , 8  , 3 ),
+     217             :   INST(Aeskeygenassist , ExtRmi             , O(660F3A,DF,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2902, 9  , 8  , 3 ),
+     218             :   INST(And             , X86Arith           , O(000000,20,4,_,x,_,_,_  ), 0                         , 0 , 0 , 2317, 10 , 1  , 0 ),
+     219             :   INST(Andn            , VexRvm_Wx          , V(000F38,F2,_,0,x,_,_,_  ), 0                         , 0 , 0 , 6150, 11 , 9  , 0 ),
+     220             :   INST(Andnpd          , ExtRm              , O(660F00,55,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2935, 5  , 4  , 2 ),
+     221             :   INST(Andnps          , ExtRm              , O(000F00,55,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2943, 5  , 5  , 2 ),
+     222             :   INST(Andpd           , ExtRm              , O(660F00,54,_,_,_,_,_,_  ), 0                         , 0 , 0 , 3872, 12 , 4  , 2 ),
+     223             :   INST(Andps           , ExtRm              , O(000F00,54,_,_,_,_,_,_  ), 0                         , 0 , 0 , 3882, 12 , 5  , 2 ),
+     224             :   INST(Arpl            , X86Mr_NoSize       , O(000000,63,_,_,_,_,_,_  ), 0                         , 0 , 0 , 31  , 13 , 10 , 0 ),
+     225             :   INST(Bextr           , VexRmv_Wx          , V(000F38,F7,_,0,x,_,_,_  ), 0                         , 0 , 0 , 36  , 14 , 9  , 0 ),
+     226             :   INST(Blcfill         , VexVm_Wx           , V(XOP_M9,01,1,0,x,_,_,_  ), 0                         , 0 , 0 , 42  , 15 , 11 , 0 ),
+     227             :   INST(Blci            , VexVm_Wx           , V(XOP_M9,02,6,0,x,_,_,_  ), 0                         , 0 , 0 , 50  , 15 , 11 , 0 ),
+     228             :   INST(Blcic           , VexVm_Wx           , V(XOP_M9,01,5,0,x,_,_,_  ), 0                         , 0 , 0 , 55  , 15 , 11 , 0 ),
+     229             :   INST(Blcmsk          , VexVm_Wx           , V(XOP_M9,02,1,0,x,_,_,_  ), 0                         , 0 , 0 , 61  , 15 , 11 , 0 ),
+     230             :   INST(Blcs            , VexVm_Wx           , V(XOP_M9,01,3,0,x,_,_,_  ), 0                         , 0 , 0 , 68  , 15 , 11 , 0 ),
+     231             :   INST(Blendpd         , ExtRmi             , O(660F3A,0D,_,_,_,_,_,_  ), 0                         , 0 , 0 , 3021, 16 , 12 , 4 ),
+     232             :   INST(Blendps         , ExtRmi             , O(660F3A,0C,_,_,_,_,_,_  ), 0                         , 0 , 0 , 3030, 16 , 12 , 4 ),
+     233             :   INST(Blendvpd        , ExtRm_XMM0         , O(660F38,15,_,_,_,_,_,_  ), 0                         , 0 , 0 , 3039, 17 , 12 , 5 ),
+     234             :   INST(Blendvps        , ExtRm_XMM0         , O(660F38,14,_,_,_,_,_,_  ), 0                         , 0 , 0 , 3049, 17 , 12 , 5 ),
+     235             :   INST(Blsfill         , VexVm_Wx           , V(XOP_M9,01,2,0,x,_,_,_  ), 0                         , 0 , 0 , 73  , 15 , 11 , 0 ),
+     236             :   INST(Blsi            , VexVm_Wx           , V(000F38,F3,3,0,x,_,_,_  ), 0                         , 0 , 0 , 81  , 15 , 9  , 0 ),
+     237             :   INST(Blsic           , VexVm_Wx           , V(XOP_M9,01,6,0,x,_,_,_  ), 0                         , 0 , 0 , 86  , 15 , 11 , 0 ),
+     238             :   INST(Blsmsk          , VexVm_Wx           , V(000F38,F3,2,0,x,_,_,_  ), 0                         , 0 , 0 , 92  , 15 , 9  , 0 ),
+     239             :   INST(Blsr            , VexVm_Wx           , V(000F38,F3,1,0,x,_,_,_  ), 0                         , 0 , 0 , 99  , 15 , 9  , 0 ),
+     240             :   INST(Bndcl           , X86Rm              , O(F30F00,1A,_,_,_,_,_,_  ), 0                         , 0 , 0 , 104 , 18 , 13 , 0 ),
+     241             :   INST(Bndcn           , X86Rm              , O(F20F00,1B,_,_,_,_,_,_  ), 0                         , 0 , 0 , 110 , 18 , 13 , 0 ),
+     242             :   INST(Bndcu           , X86Rm              , O(F20F00,1A,_,_,_,_,_,_  ), 0                         , 0 , 0 , 116 , 18 , 13 , 0 ),
+     243             :   INST(Bndldx          , X86Rm              , O(000F00,1A,_,_,_,_,_,_  ), 0                         , 0 , 0 , 122 , 19 , 13 , 0 ),
+     244             :   INST(Bndmk           , X86Rm              , O(F30F00,1B,_,_,_,_,_,_  ), 0                         , 0 , 0 , 129 , 20 , 13 , 0 ),
+     245             :   INST(Bndmov          , X86Bndmov          , O(660F00,1A,_,_,_,_,_,_  ), O(660F00,1B,_,_,_,_,_,_  ), 0 , 0 , 135 , 21 , 13 , 0 ),
+     246             :   INST(Bndstx          , X86Mr              , O(000F00,1B,_,_,_,_,_,_  ), 0                         , 0 , 0 , 142 , 22 , 13 , 0 ),
+     247             :   INST(Bound           , X86Rm              , O(000000,62,_,_,_,_,_,_  ), 0                         , 0 , 0 , 149 , 23 , 0  , 0 ),
+     248             :   INST(Bsf             , X86Rm              , O(000F00,BC,_,_,x,_,_,_  ), 0                         , 0 , 0 , 155 , 24 , 1  , 0 ),
+     249             :   INST(Bsr             , X86Rm              , O(000F00,BD,_,_,x,_,_,_  ), 0                         , 0 , 0 , 159 , 24 , 1  , 0 ),
+     250             :   INST(Bswap           , X86Bswap           , O(000F00,C8,_,_,x,_,_,_  ), 0                         , 0 , 0 , 163 , 25 , 0  , 0 ),
+     251             :   INST(Bt              , X86Bt              , O(000F00,A3,_,_,x,_,_,_  ), O(000F00,BA,4,_,x,_,_,_  ), 0 , 0 , 169 , 26 , 14 , 0 ),
+     252             :   INST(Btc             , X86Bt              , O(000F00,BB,_,_,x,_,_,_  ), O(000F00,BA,7,_,x,_,_,_  ), 0 , 0 , 172 , 27 , 14 , 0 ),
+     253             :   INST(Btr             , X86Bt              , O(000F00,B3,_,_,x,_,_,_  ), O(000F00,BA,6,_,x,_,_,_  ), 0 , 0 , 176 , 28 , 14 , 0 ),
+     254             :   INST(Bts             , X86Bt              , O(000F00,AB,_,_,x,_,_,_  ), O(000F00,BA,5,_,x,_,_,_  ), 0 , 0 , 180 , 29 , 14 , 0 ),
+     255             :   INST(Bzhi            , VexRmv_Wx          , V(000F38,F5,_,0,x,_,_,_  ), 0                         , 0 , 0 , 184 , 14 , 15 , 0 ),
+     256             :   INST(Call            , X86Call            , O(000000,FF,2,_,_,_,_,_  ), 0                         , 0 , 0 , 2713, 30 , 16 , 0 ),
+     257             :   INST(Cbw             , X86Op_xAX          , O(660000,98,_,_,_,_,_,_  ), 0                         , 0 , 0 , 189 , 31 , 0  , 0 ),
+     258             :   INST(Cdq             , X86Op_xDX_xAX      , O(000000,99,_,_,_,_,_,_  ), 0                         , 0 , 0 , 193 , 32 , 0  , 0 ),
+     259             :   INST(Cdqe            , X86Op_xAX          , O(000000,98,_,_,1,_,_,_  ), 0                         , 0 , 0 , 197 , 33 , 0  , 0 ),
+     260             :   INST(Clac            , X86Op              , O(000F01,CA,_,_,_,_,_,_  ), 0                         , 0 , 0 , 202 , 34 , 17 , 0 ),
+     261             :   INST(Clc             , X86Op              , O(000000,F8,_,_,_,_,_,_  ), 0                         , 0 , 0 , 207 , 34 , 18 , 0 ),
+     262             :   INST(Cld             , X86Op              , O(000000,FC,_,_,_,_,_,_  ), 0                         , 0 , 0 , 211 , 34 , 19 , 0 ),
+     263             :   INST(Clflush         , X86M_Only          , O(000F00,AE,7,_,_,_,_,_  ), 0                         , 0 , 0 , 215 , 35 , 20 , 0 ),
+     264             :   INST(Clflushopt      , X86M_Only          , O(660F00,AE,7,_,_,_,_,_  ), 0                         , 0 , 0 , 223 , 35 , 21 , 0 ),
+     265             :   INST(Cli             , X86Op              , O(000000,FA,_,_,_,_,_,_  ), 0                         , 0 , 0 , 234 , 34 , 22 , 0 ),
+     266             :   INST(Clts            , X86Op              , O(000F00,06,_,_,_,_,_,_  ), 0                         , 0 , 0 , 238 , 34 , 23 , 0 ),
+     267             :   INST(Clwb            , X86M_Only          , O(660F00,AE,6,_,_,_,_,_  ), 0                         , 0 , 0 , 243 , 35 , 24 , 0 ),
+     268             :   INST(Clzero          , X86Op_ZAX          , O(000F01,FC,_,_,_,_,_,_  ), 0                         , 0 , 0 , 248 , 36 , 25 , 0 ),
+     269             :   INST(Cmc             , X86Op              , O(000000,F5,_,_,_,_,_,_  ), 0                         , 0 , 0 , 255 , 34 , 26 , 0 ),
+     270             :   INST(Cmova           , X86Rm              , O(000F00,47,_,_,x,_,_,_  ), 0                         , 0 , 0 , 259 , 24 , 27 , 0 ),
+     271             :   INST(Cmovae          , X86Rm              , O(000F00,43,_,_,x,_,_,_  ), 0                         , 0 , 0 , 265 , 24 , 28 , 0 ),
+     272             :   INST(Cmovb           , X86Rm              , O(000F00,42,_,_,x,_,_,_  ), 0                         , 0 , 0 , 589 , 24 , 28 , 0 ),
+     273             :   INST(Cmovbe          , X86Rm              , O(000F00,46,_,_,x,_,_,_  ), 0                         , 0 , 0 , 596 , 24 , 27 , 0 ),
+     274             :   INST(Cmovc           , X86Rm              , O(000F00,42,_,_,x,_,_,_  ), 0                         , 0 , 0 , 272 , 24 , 28 , 0 ),
+     275             :   INST(Cmove           , X86Rm              , O(000F00,44,_,_,x,_,_,_  ), 0                         , 0 , 0 , 604 , 24 , 29 , 0 ),
+     276             :   INST(Cmovg           , X86Rm              , O(000F00,4F,_,_,x,_,_,_  ), 0                         , 0 , 0 , 278 , 24 , 30 , 0 ),
+     277             :   INST(Cmovge          , X86Rm              , O(000F00,4D,_,_,x,_,_,_  ), 0                         , 0 , 0 , 284 , 24 , 31 , 0 ),
+     278             :   INST(Cmovl           , X86Rm              , O(000F00,4C,_,_,x,_,_,_  ), 0                         , 0 , 0 , 291 , 24 , 31 , 0 ),
+     279             :   INST(Cmovle          , X86Rm              , O(000F00,4E,_,_,x,_,_,_  ), 0                         , 0 , 0 , 297 , 24 , 30 , 0 ),
+     280             :   INST(Cmovna          , X86Rm              , O(000F00,46,_,_,x,_,_,_  ), 0                         , 0 , 0 , 304 , 24 , 27 , 0 ),
+     281             :   INST(Cmovnae         , X86Rm              , O(000F00,42,_,_,x,_,_,_  ), 0                         , 0 , 0 , 311 , 24 , 28 , 0 ),
+     282             :   INST(Cmovnb          , X86Rm              , O(000F00,43,_,_,x,_,_,_  ), 0                         , 0 , 0 , 611 , 24 , 28 , 0 ),
+     283             :   INST(Cmovnbe         , X86Rm              , O(000F00,47,_,_,x,_,_,_  ), 0                         , 0 , 0 , 619 , 24 , 27 , 0 ),
+     284             :   INST(Cmovnc          , X86Rm              , O(000F00,43,_,_,x,_,_,_  ), 0                         , 0 , 0 , 319 , 24 , 28 , 0 ),
+     285             :   INST(Cmovne          , X86Rm              , O(000F00,45,_,_,x,_,_,_  ), 0                         , 0 , 0 , 628 , 24 , 29 , 0 ),
+     286             :   INST(Cmovng          , X86Rm              , O(000F00,4E,_,_,x,_,_,_  ), 0                         , 0 , 0 , 326 , 24 , 30 , 0 ),
+     287             :   INST(Cmovnge         , X86Rm              , O(000F00,4C,_,_,x,_,_,_  ), 0                         , 0 , 0 , 333 , 24 , 31 , 0 ),
+     288             :   INST(Cmovnl          , X86Rm              , O(000F00,4D,_,_,x,_,_,_  ), 0                         , 0 , 0 , 341 , 24 , 31 , 0 ),
+     289             :   INST(Cmovnle         , X86Rm              , O(000F00,4F,_,_,x,_,_,_  ), 0                         , 0 , 0 , 348 , 24 , 30 , 0 ),
+     290             :   INST(Cmovno          , X86Rm              , O(000F00,41,_,_,x,_,_,_  ), 0                         , 0 , 0 , 356 , 24 , 32 , 0 ),
+     291             :   INST(Cmovnp          , X86Rm              , O(000F00,4B,_,_,x,_,_,_  ), 0                         , 0 , 0 , 363 , 24 , 33 , 0 ),
+     292             :   INST(Cmovns          , X86Rm              , O(000F00,49,_,_,x,_,_,_  ), 0                         , 0 , 0 , 370 , 24 , 34 , 0 ),
+     293             :   INST(Cmovnz          , X86Rm              , O(000F00,45,_,_,x,_,_,_  ), 0                         , 0 , 0 , 377 , 24 , 29 , 0 ),
+     294             :   INST(Cmovo           , X86Rm              , O(000F00,40,_,_,x,_,_,_  ), 0                         , 0 , 0 , 384 , 24 , 32 , 0 ),
+     295             :   INST(Cmovp           , X86Rm              , O(000F00,4A,_,_,x,_,_,_  ), 0                         , 0 , 0 , 390 , 24 , 33 , 0 ),
+     296             :   INST(Cmovpe          , X86Rm              , O(000F00,4A,_,_,x,_,_,_  ), 0                         , 0 , 0 , 396 , 24 , 33 , 0 ),
+     297             :   INST(Cmovpo          , X86Rm              , O(000F00,4B,_,_,x,_,_,_  ), 0                         , 0 , 0 , 403 , 24 , 33 , 0 ),
+     298             :   INST(Cmovs           , X86Rm              , O(000F00,48,_,_,x,_,_,_  ), 0                         , 0 , 0 , 410 , 24 , 34 , 0 ),
+     299             :   INST(Cmovz           , X86Rm              , O(000F00,44,_,_,x,_,_,_  ), 0                         , 0 , 0 , 416 , 24 , 29 , 0 ),
+     300             :   INST(Cmp             , X86Arith           , O(000000,38,7,_,x,_,_,_  ), 0                         , 0 , 0 , 422 , 37 , 1  , 0 ),
+     301             :   INST(Cmppd           , ExtRmi             , O(660F00,C2,_,_,_,_,_,_  ), 0                         , 0 , 0 , 3275, 16 , 4  , 6 ),
+     302             :   INST(Cmpps           , ExtRmi             , O(000F00,C2,_,_,_,_,_,_  ), 0                         , 0 , 0 , 3282, 16 , 5  , 6 ),
+     303             :   INST(Cmps            , X86StrMm           , O(000000,A6,_,_,_,_,_,_  ), 0                         , 0 , 0 , 426 , 38 , 35 , 0 ),
+     304             :   INST(Cmpsd           , ExtRmi             , O(F20F00,C2,_,_,_,_,_,_  ), 0                         , 0 , 0 , 3289, 39 , 4  , 7 ),
+     305             :   INST(Cmpss           , ExtRmi             , O(F30F00,C2,_,_,_,_,_,_  ), 0                         , 0 , 0 , 3296, 40 , 5  , 7 ),
+     306             :   INST(Cmpxchg         , X86Cmpxchg         , O(000F00,B0,_,_,x,_,_,_  ), 0                         , 0 , 0 , 431 , 41 , 36 , 0 ),
+     307             :   INST(Cmpxchg16b      , X86M_Only          , O(000F00,C7,1,_,1,_,_,_  ), 0                         , 0 , 0 , 439 , 42 , 37 , 0 ),
+     308             :   INST(Cmpxchg8b       , X86M_Only          , O(000F00,C7,1,_,_,_,_,_  ), 0                         , 0 , 0 , 450 , 43 , 38 , 0 ),
+     309             :   INST(Comisd          , ExtRm              , O(660F00,2F,_,_,_,_,_,_  ), 0                         , 0 , 0 , 9371, 44 , 39 , 8 ),
+     310             :   INST(Comiss          , ExtRm              , O(000F00,2F,_,_,_,_,_,_  ), 0                         , 0 , 0 , 9380, 45 , 40 , 8 ),
+     311             :   INST(Cpuid           , X86Op              , O(000F00,A2,_,_,_,_,_,_  ), 0                         , 0 , 0 , 460 , 46 , 41 , 0 ),
+     312             :   INST(Cqo             , X86Op_xDX_xAX      , O(000000,99,_,_,1,_,_,_  ), 0                         , 0 , 0 , 466 , 47 , 0  , 0 ),
+     313             :   INST(Crc32           , X86Crc             , O(F20F38,F0,_,_,x,_,_,_  ), 0                         , 0 , 0 , 470 , 48 , 42 , 0 ),
+     314             :   INST(Cvtdq2pd        , ExtRm              , O(F30F00,E6,_,_,_,_,_,_  ), 0                         , 0 , 16, 3343, 49 , 4  , 9 ),
+     315             :   INST(Cvtdq2ps        , ExtRm              , O(000F00,5B,_,_,_,_,_,_  ), 0                         , 0 , 16, 3353, 50 , 4  , 9 ),
+     316             :   INST(Cvtpd2dq        , ExtRm              , O(F20F00,E6,_,_,_,_,_,_  ), 0                         , 0 , 16, 3363, 50 , 4  , 9 ),
+     317             :   INST(Cvtpd2pi        , ExtRm              , O(660F00,2D,_,_,_,_,_,_  ), 0                         , 0 , 8 , 476 , 51 , 4  , 0 ),
+     318             :   INST(Cvtpd2ps        , ExtRm              , O(660F00,5A,_,_,_,_,_,_  ), 0                         , 0 , 16, 3373, 50 , 4  , 10),
+     319             :   INST(Cvtpi2pd        , ExtRm              , O(660F00,2A,_,_,_,_,_,_  ), 0                         , 0 , 16, 485 , 52 , 4  , 0 ),
+     320             :   INST(Cvtpi2ps        , ExtRm              , O(000F00,2A,_,_,_,_,_,_  ), 0                         , 0 , 8 , 494 , 53 , 5  , 0 ),
+     321             :   INST(Cvtps2dq        , ExtRm              , O(660F00,5B,_,_,_,_,_,_  ), 0                         , 0 , 16, 3425, 50 , 4  , 8 ),
+     322             :   INST(Cvtps2pd        , ExtRm              , O(000F00,5A,_,_,_,_,_,_  ), 0                         , 0 , 16, 3435, 49 , 4  , 8 ),
+     323             :   INST(Cvtps2pi        , ExtRm              , O(000F00,2D,_,_,_,_,_,_  ), 0                         , 0 , 8 , 503 , 54 , 5  , 0 ),
+     324             :   INST(Cvtsd2si        , ExtRm_Wx           , O(F20F00,2D,_,_,x,_,_,_  ), 0                         , 0 , 8 , 3507, 55 , 4  , 11),
+     325             :   INST(Cvtsd2ss        , ExtRm              , O(F20F00,5A,_,_,_,_,_,_  ), 0                         , 0 , 4 , 3517, 56 , 4  , 12),
+     326             :   INST(Cvtsi2sd        , ExtRm_Wx           , O(F20F00,2A,_,_,x,_,_,_  ), 0                         , 0 , 8 , 3538, 57 , 4  , 13),
+     327             :   INST(Cvtsi2ss        , ExtRm_Wx           , O(F30F00,2A,_,_,x,_,_,_  ), 0                         , 0 , 4 , 3548, 58 , 5  , 13),
+     328             :   INST(Cvtss2sd        , ExtRm              , O(F30F00,5A,_,_,_,_,_,_  ), 0                         , 0 , 8 , 3558, 59 , 4  , 13),
+     329             :   INST(Cvtss2si        , ExtRm_Wx           , O(F30F00,2D,_,_,x,_,_,_  ), 0                         , 0 , 8 , 3568, 60 , 5  , 14),
+     330             :   INST(Cvttpd2dq       , ExtRm              , O(660F00,E6,_,_,_,_,_,_  ), 0                         , 0 , 16, 3589, 50 , 4  , 15),
+     331             :   INST(Cvttpd2pi       , ExtRm              , O(660F00,2C,_,_,_,_,_,_  ), 0                         , 0 , 8 , 512 , 51 , 4  , 0 ),
+     332             :   INST(Cvttps2dq       , ExtRm              , O(F30F00,5B,_,_,_,_,_,_  ), 0                         , 0 , 16, 3635, 50 , 4  , 16),
+     333             :   INST(Cvttps2pi       , ExtRm              , O(000F00,2C,_,_,_,_,_,_  ), 0                         , 0 , 8 , 522 , 54 , 5  , 0 ),
+     334             :   INST(Cvttsd2si       , ExtRm_Wx           , O(F20F00,2C,_,_,x,_,_,_  ), 0                         , 0 , 8 , 3681, 55 , 4  , 17),
+     335             :   INST(Cvttss2si       , ExtRm_Wx           , O(F30F00,2C,_,_,x,_,_,_  ), 0                         , 0 , 8 , 3704, 60 , 5  , 18),
+     336             :   INST(Cwd             , X86Op_xDX_xAX      , O(660000,99,_,_,_,_,_,_  ), 0                         , 0 , 0 , 532 , 61 , 0  , 0 ),
+     337             :   INST(Cwde            , X86Op_xAX          , O(000000,98,_,_,_,_,_,_  ), 0                         , 0 , 0 , 536 , 62 , 0  , 0 ),
+     338             :   INST(Daa             , X86Op              , O(000000,27,_,_,_,_,_,_  ), 0                         , 0 , 0 , 541 , 1  , 1  , 0 ),
+     339             :   INST(Das             , X86Op              , O(000000,2F,_,_,_,_,_,_  ), 0                         , 0 , 0 , 545 , 1  , 1  , 0 ),
+     340             :   INST(Dec             , X86IncDec          , O(000000,FE,1,_,x,_,_,_  ), O(000000,48,_,_,x,_,_,_  ), 0 , 0 , 2857, 63 , 43 , 0 ),
+     341             :   INST(Div             , X86M_GPB_MulDiv    , O(000000,F6,6,_,x,_,_,_  ), 0                         , 0 , 0 , 751 , 64 , 1  , 0 ),
+     342             :   INST(Divpd           , ExtRm              , O(660F00,5E,_,_,_,_,_,_  ), 0                         , 0 , 0 , 3803, 5  , 4  , 19),
+     343             :   INST(Divps           , ExtRm              , O(000F00,5E,_,_,_,_,_,_  ), 0                         , 0 , 0 , 3810, 5  , 5  , 19),
+     344             :   INST(Divsd           , ExtRm              , O(F20F00,5E,_,_,_,_,_,_  ), 0                         , 0 , 0 , 3817, 6  , 4  , 19),
+     345             :   INST(Divss           , ExtRm              , O(F30F00,5E,_,_,_,_,_,_  ), 0                         , 0 , 0 , 3824, 7  , 5  , 19),
+     346             :   INST(Dppd            , ExtRmi             , O(660F3A,41,_,_,_,_,_,_  ), 0                         , 0 , 0 , 3831, 16 , 12 , 19),
+     347             :   INST(Dpps            , ExtRmi             , O(660F3A,40,_,_,_,_,_,_  ), 0                         , 0 , 0 , 3837, 16 , 12 , 19),
+     348             :   INST(Emms            , X86Op              , O(000F00,77,_,_,_,_,_,_  ), 0                         , 0 , 0 , 719 , 65 , 44 , 0 ),
+     349             :   INST(Enter           , X86Enter           , O(000000,C8,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2721, 66 , 45 , 0 ),
+     350             :   INST(Extractps       , ExtExtract         , O(660F3A,17,_,_,_,_,_,_  ), 0                         , 0 , 8 , 4027, 67 , 12 , 20),
+     351             :   INST(Extrq           , ExtExtrq           , O(660F00,79,_,_,_,_,_,_  ), O(660F00,78,0,_,_,_,_,_  ), 0 , 0 , 6864, 68 , 46 , 0 ),
+     352             :   INST(F2xm1           , FpuOp              , O_FPU(00,D9F0,_)          , 0                         , 0 , 0 , 549 , 34 , 47 , 0 ),
+     353             :   INST(Fabs            , FpuOp              , O_FPU(00,D9E1,_)          , 0                         , 0 , 0 , 555 , 34 , 47 , 0 ),
+     354             :   INST(Fadd            , FpuArith           , O_FPU(00,C0C0,0)          , 0                         , 0 , 0 , 1957, 69 , 47 , 0 ),
+     355             :   INST(Faddp           , FpuRDef            , O_FPU(00,DEC0,_)          , 0                         , 0 , 0 , 560 , 70 , 47 , 0 ),
+     356             :   INST(Fbld            , X86M_Only          , O_FPU(00,00DF,4)          , 0                         , 0 , 0 , 566 , 71 , 47 , 0 ),
+     357             :   INST(Fbstp           , X86M_Only          , O_FPU(00,00DF,6)          , 0                         , 0 , 0 , 571 , 72 , 47 , 0 ),
+     358             :   INST(Fchs            , FpuOp              , O_FPU(00,D9E0,_)          , 0                         , 0 , 0 , 577 , 34 , 47 , 0 ),
+     359             :   INST(Fclex           , FpuOp              , O_FPU(9B,DBE2,_)          , 0                         , 0 , 0 , 582 , 34 , 47 , 0 ),
+     360             :   INST(Fcmovb          , FpuR               , O_FPU(00,DAC0,_)          , 0                         , 0 , 0 , 588 , 73 , 48 , 0 ),
+     361             :   INST(Fcmovbe         , FpuR               , O_FPU(00,DAD0,_)          , 0                         , 0 , 0 , 595 , 73 , 48 , 0 ),
+     362             :   INST(Fcmove          , FpuR               , O_FPU(00,DAC8,_)          , 0                         , 0 , 0 , 603 , 73 , 48 , 0 ),
+     363             :   INST(Fcmovnb         , FpuR               , O_FPU(00,DBC0,_)          , 0                         , 0 , 0 , 610 , 73 , 48 , 0 ),
+     364             :   INST(Fcmovnbe        , FpuR               , O_FPU(00,DBD0,_)          , 0                         , 0 , 0 , 618 , 73 , 48 , 0 ),
+     365             :   INST(Fcmovne         , FpuR               , O_FPU(00,DBC8,_)          , 0                         , 0 , 0 , 627 , 73 , 48 , 0 ),
+     366             :   INST(Fcmovnu         , FpuR               , O_FPU(00,DBD8,_)          , 0                         , 0 , 0 , 635 , 73 , 48 , 0 ),
+     367             :   INST(Fcmovu          , FpuR               , O_FPU(00,DAD8,_)          , 0                         , 0 , 0 , 643 , 73 , 48 , 0 ),
+     368             :   INST(Fcom            , FpuCom             , O_FPU(00,D0D0,2)          , 0                         , 0 , 0 , 650 , 74 , 47 , 0 ),
+     369             :   INST(Fcomi           , FpuR               , O_FPU(00,DBF0,_)          , 0                         , 0 , 0 , 655 , 75 , 49 , 0 ),
+     370             :   INST(Fcomip          , FpuR               , O_FPU(00,DFF0,_)          , 0                         , 0 , 0 , 661 , 75 , 49 , 0 ),
+     371             :   INST(Fcomp           , FpuCom             , O_FPU(00,D8D8,3)          , 0                         , 0 , 0 , 668 , 74 , 47 , 0 ),
+     372             :   INST(Fcompp          , FpuOp              , O_FPU(00,DED9,_)          , 0                         , 0 , 0 , 674 , 34 , 47 , 0 ),
+     373             :   INST(Fcos            , FpuOp              , O_FPU(00,D9FF,_)          , 0                         , 0 , 0 , 681 , 34 , 47 , 0 ),
+     374             :   INST(Fdecstp         , FpuOp              , O_FPU(00,D9F6,_)          , 0                         , 0 , 0 , 686 , 34 , 47 , 0 ),
+     375             :   INST(Fdiv            , FpuArith           , O_FPU(00,F0F8,6)          , 0                         , 0 , 0 , 694 , 69 , 47 , 0 ),
+     376             :   INST(Fdivp           , FpuRDef            , O_FPU(00,DEF8,_)          , 0                         , 0 , 0 , 699 , 70 , 47 , 0 ),
+     377             :   INST(Fdivr           , FpuArith           , O_FPU(00,F8F0,7)          , 0                         , 0 , 0 , 705 , 69 , 47 , 0 ),
+     378             :   INST(Fdivrp          , FpuRDef            , O_FPU(00,DEF0,_)          , 0                         , 0 , 0 , 711 , 70 , 47 , 0 ),
+     379             :   INST(Femms           , X86Op              , O(000F00,0E,_,_,_,_,_,_  ), 0                         , 0 , 0 , 718 , 34 , 50 , 0 ),
+     380             :   INST(Ffree           , FpuR               , O_FPU(00,DDC0,_)          , 0                         , 0 , 0 , 724 , 73 , 47 , 0 ),
+     381             :   INST(Fiadd           , FpuM               , O_FPU(00,00DA,0)          , 0                         , 0 , 0 , 730 , 76 , 47 , 0 ),
+     382             :   INST(Ficom           , FpuM               , O_FPU(00,00DA,2)          , 0                         , 0 , 0 , 736 , 76 , 47 , 0 ),
+     383             :   INST(Ficomp          , FpuM               , O_FPU(00,00DA,3)          , 0                         , 0 , 0 , 742 , 76 , 47 , 0 ),
+     384             :   INST(Fidiv           , FpuM               , O_FPU(00,00DA,6)          , 0                         , 0 , 0 , 749 , 76 , 47 , 0 ),
+     385             :   INST(Fidivr          , FpuM               , O_FPU(00,00DA,7)          , 0                         , 0 , 0 , 755 , 76 , 47 , 0 ),
+     386             :   INST(Fild            , FpuM               , O_FPU(00,00DB,0)          , O_FPU(00,00DF,5)          , 0 , 0 , 762 , 77 , 47 , 0 ),
+     387             :   INST(Fimul           , FpuM               , O_FPU(00,00DA,1)          , 0                         , 0 , 0 , 767 , 76 , 47 , 0 ),
+     388             :   INST(Fincstp         , FpuOp              , O_FPU(00,D9F7,_)          , 0                         , 0 , 0 , 773 , 34 , 47 , 0 ),
+     389             :   INST(Finit           , FpuOp              , O_FPU(9B,DBE3,_)          , 0                         , 0 , 0 , 781 , 34 , 47 , 0 ),
+     390             :   INST(Fist            , FpuM               , O_FPU(00,00DB,2)          , 0                         , 0 , 0 , 787 , 78 , 47 , 0 ),
+     391             :   INST(Fistp           , FpuM               , O_FPU(00,00DB,3)          , O_FPU(00,00DF,7)          , 0 , 0 , 792 , 79 , 47 , 0 ),
+     392             :   INST(Fisttp          , FpuM               , O_FPU(00,00DB,1)          , O_FPU(00,00DD,1)          , 0 , 0 , 798 , 80 , 51 , 0 ),
+     393             :   INST(Fisub           , FpuM               , O_FPU(00,00DA,4)          , 0                         , 0 , 0 , 805 , 76 , 47 , 0 ),
+     394             :   INST(Fisubr          , FpuM               , O_FPU(00,00DA,5)          , 0                         , 0 , 0 , 811 , 76 , 47 , 0 ),
+     395             :   INST(Fld             , FpuFldFst          , O_FPU(00,00D9,0)          , O_FPU(00,00DB,5)          , 0 , 0 , 818 , 81 , 47 , 0 ),
+     396             :   INST(Fld1            , FpuOp              , O_FPU(00,D9E8,_)          , 0                         , 0 , 0 , 822 , 34 , 47 , 0 ),
+     397             :   INST(Fldcw           , X86M_Only          , O_FPU(00,00D9,5)          , 0                         , 0 , 0 , 827 , 82 , 47 , 0 ),
+     398             :   INST(Fldenv          , X86M_Only          , O_FPU(00,00D9,4)          , 0                         , 0 , 0 , 833 , 35 , 47 , 0 ),
+     399             :   INST(Fldl2e          , FpuOp              , O_FPU(00,D9EA,_)          , 0                         , 0 , 0 , 840 , 34 , 47 , 0 ),
+     400             :   INST(Fldl2t          , FpuOp              , O_FPU(00,D9E9,_)          , 0                         , 0 , 0 , 847 , 34 , 47 , 0 ),
+     401             :   INST(Fldlg2          , FpuOp              , O_FPU(00,D9EC,_)          , 0                         , 0 , 0 , 854 , 34 , 47 , 0 ),
+     402             :   INST(Fldln2          , FpuOp              , O_FPU(00,D9ED,_)          , 0                         , 0 , 0 , 861 , 34 , 47 , 0 ),
+     403             :   INST(Fldpi           , FpuOp              , O_FPU(00,D9EB,_)          , 0                         , 0 , 0 , 868 , 34 , 47 , 0 ),
+     404             :   INST(Fldz            , FpuOp              , O_FPU(00,D9EE,_)          , 0                         , 0 , 0 , 874 , 34 , 47 , 0 ),
+     405             :   INST(Fmul            , FpuArith           , O_FPU(00,C8C8,1)          , 0                         , 0 , 0 , 1999, 83 , 47 , 0 ),
+     406             :   INST(Fmulp           , FpuRDef            , O_FPU(00,DEC8,_)          , 0                         , 0 , 0 , 879 , 70 , 47 , 0 ),
+     407             :   INST(Fnclex          , FpuOp              , O_FPU(00,DBE2,_)          , 0                         , 0 , 0 , 885 , 34 , 47 , 0 ),
+     408             :   INST(Fninit          , FpuOp              , O_FPU(00,DBE3,_)          , 0                         , 0 , 0 , 892 , 34 , 47 , 0 ),
+     409             :   INST(Fnop            , FpuOp              , O_FPU(00,D9D0,_)          , 0                         , 0 , 0 , 899 , 34 , 47 , 0 ),
+     410             :   INST(Fnsave          , X86M_Only          , O_FPU(00,00DD,6)          , 0                         , 0 , 0 , 904 , 84 , 47 , 0 ),
+     411             :   INST(Fnstcw          , X86M_Only          , O_FPU(00,00D9,7)          , 0                         , 0 , 0 , 911 , 85 , 47 , 0 ),
+     412             :   INST(Fnstenv         , X86M_Only          , O_FPU(00,00D9,6)          , 0                         , 0 , 0 , 918 , 84 , 47 , 0 ),
+     413             :   INST(Fnstsw          , FpuStsw            , O_FPU(00,00DD,7)          , O_FPU(00,DFE0,_)          , 0 , 0 , 926 , 86 , 47 , 0 ),
+     414             :   INST(Fpatan          , FpuOp              , O_FPU(00,D9F3,_)          , 0                         , 0 , 0 , 933 , 34 , 47 , 0 ),
+     415             :   INST(Fprem           , FpuOp              , O_FPU(00,D9F8,_)          , 0                         , 0 , 0 , 940 , 34 , 47 , 0 ),
+     416             :   INST(Fprem1          , FpuOp              , O_FPU(00,D9F5,_)          , 0                         , 0 , 0 , 946 , 34 , 47 , 0 ),
+     417             :   INST(Fptan           , FpuOp              , O_FPU(00,D9F2,_)          , 0                         , 0 , 0 , 953 , 34 , 47 , 0 ),
+     418             :   INST(Frndint         , FpuOp              , O_FPU(00,D9FC,_)          , 0                         , 0 , 0 , 959 , 34 , 47 , 0 ),
+     419             :   INST(Frstor          , X86M_Only          , O_FPU(00,00DD,4)          , 0                         , 0 , 0 , 967 , 35 , 47 , 0 ),
+     420             :   INST(Fsave           , X86M_Only          , O_FPU(9B,00DD,6)          , 0                         , 0 , 0 , 974 , 84 , 47 , 0 ),
+     421             :   INST(Fscale          , FpuOp              , O_FPU(00,D9FD,_)          , 0                         , 0 , 0 , 980 , 34 , 47 , 0 ),
+     422             :   INST(Fsin            , FpuOp              , O_FPU(00,D9FE,_)          , 0                         , 0 , 0 , 987 , 34 , 47 , 0 ),
+     423             :   INST(Fsincos         , FpuOp              , O_FPU(00,D9FB,_)          , 0                         , 0 , 0 , 992 , 34 , 47 , 0 ),
+     424             :   INST(Fsqrt           , FpuOp              , O_FPU(00,D9FA,_)          , 0                         , 0 , 0 , 1000, 34 , 47 , 0 ),
+     425             :   INST(Fst             , FpuFldFst          , O_FPU(00,00D9,2)          , 0                         , 0 , 0 , 1006, 87 , 47 , 0 ),
+     426             :   INST(Fstcw           , X86M_Only          , O_FPU(9B,00D9,7)          , 0                         , 0 , 0 , 1010, 85 , 47 , 0 ),
+     427             :   INST(Fstenv          , X86M_Only          , O_FPU(9B,00D9,6)          , 0                         , 0 , 0 , 1016, 84 , 47 , 0 ),
+     428             :   INST(Fstp            , FpuFldFst          , O_FPU(00,00D9,3)          , O(000000,DB,7,_,_,_,_,_  ), 0 , 0 , 1023, 88 , 47 , 0 ),
+     429             :   INST(Fstsw           , FpuStsw            , O_FPU(9B,00DD,7)          , O_FPU(9B,DFE0,_)          , 0 , 0 , 1028, 89 , 47 , 0 ),
+     430             :   INST(Fsub            , FpuArith           , O_FPU(00,E0E8,4)          , 0                         , 0 , 0 , 2077, 69 , 47 , 0 ),
+     431             :   INST(Fsubp           , FpuRDef            , O_FPU(00,DEE8,_)          , 0                         , 0 , 0 , 1034, 70 , 47 , 0 ),
+     432             :   INST(Fsubr           , FpuArith           , O_FPU(00,E8E0,5)          , 0                         , 0 , 0 , 2083, 69 , 47 , 0 ),
+     433             :   INST(Fsubrp          , FpuRDef            , O_FPU(00,DEE0,_)          , 0                         , 0 , 0 , 1040, 70 , 47 , 0 ),
+     434             :   INST(Ftst            , FpuOp              , O_FPU(00,D9E4,_)          , 0                         , 0 , 0 , 1047, 34 , 47 , 0 ),
+     435             :   INST(Fucom           , FpuRDef            , O_FPU(00,DDE0,_)          , 0                         , 0 , 0 , 1052, 90 , 47 , 0 ),
+     436             :   INST(Fucomi          , FpuR               , O_FPU(00,DBE8,_)          , 0                         , 0 , 0 , 1058, 75 , 49 , 0 ),
+     437             :   INST(Fucomip         , FpuR               , O_FPU(00,DFE8,_)          , 0                         , 0 , 0 , 1065, 75 , 49 , 0 ),
+     438             :   INST(Fucomp          , FpuRDef            , O_FPU(00,DDE8,_)          , 0                         , 0 , 0 , 1073, 90 , 47 , 0 ),
+     439             :   INST(Fucompp         , FpuOp              , O_FPU(00,DAE9,_)          , 0                         , 0 , 0 , 1080, 34 , 47 , 0 ),
+     440             :   INST(Fwait           , X86Op              , O_FPU(00,00DB,_)          , 0                         , 0 , 0 , 1088, 34 , 47 , 0 ),
+     441             :   INST(Fxam            , FpuOp              , O_FPU(00,D9E5,_)          , 0                         , 0 , 0 , 1094, 34 , 47 , 0 ),
+     442             :   INST(Fxch            , FpuR               , O_FPU(00,D9C8,_)          , 0                         , 0 , 0 , 1099, 70 , 47 , 0 ),
+     443             :   INST(Fxrstor         , X86M_Only          , O(000F00,AE,1,_,_,_,_,_  ), 0                         , 0 , 0 , 1104, 35 , 52 , 0 ),
+     444             :   INST(Fxrstor64       , X86M_Only          , O(000F00,AE,1,_,1,_,_,_  ), 0                         , 0 , 0 , 1112, 91 , 52 , 0 ),
+     445             :   INST(Fxsave          , X86M_Only          , O(000F00,AE,0,_,_,_,_,_  ), 0                         , 0 , 0 , 1122, 84 , 53 , 0 ),
+     446             :   INST(Fxsave64        , X86M_Only          , O(000F00,AE,0,_,1,_,_,_  ), 0                         , 0 , 0 , 1129, 92 , 53 , 0 ),
+     447             :   INST(Fxtract         , FpuOp              , O_FPU(00,D9F4,_)          , 0                         , 0 , 0 , 1138, 34 , 47 , 0 ),
+     448             :   INST(Fyl2x           , FpuOp              , O_FPU(00,D9F1,_)          , 0                         , 0 , 0 , 1146, 34 , 47 , 0 ),
+     449             :   INST(Fyl2xp1         , FpuOp              , O_FPU(00,D9F9,_)          , 0                         , 0 , 0 , 1152, 34 , 47 , 0 ),
+     450             :   INST(Haddpd          , ExtRm              , O(660F00,7C,_,_,_,_,_,_  ), 0                         , 0 , 0 , 5382, 5  , 6  , 21),
+     451             :   INST(Haddps          , ExtRm              , O(F20F00,7C,_,_,_,_,_,_  ), 0                         , 0 , 0 , 5390, 5  , 6  , 21),
+     452             :   INST(Hlt             , X86Op              , O(000000,F4,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1160, 34 , 23 , 0 ),
+     453             :   INST(Hsubpd          , ExtRm              , O(660F00,7D,_,_,_,_,_,_  ), 0                         , 0 , 0 , 5398, 5  , 6  , 22),
+     454             :   INST(Hsubps          , ExtRm              , O(F20F00,7D,_,_,_,_,_,_  ), 0                         , 0 , 0 , 5406, 5  , 6  , 22),
+     455             :   INST(Idiv            , X86M_GPB_MulDiv    , O(000000,F6,7,_,x,_,_,_  ), 0                         , 0 , 0 , 750 , 64 , 1  , 0 ),
+     456             :   INST(Imul            , X86Imul            , O(000000,F6,5,_,x,_,_,_  ), 0                         , 0 , 0 , 768 , 93 , 1  , 0 ),
+     457             :   INST(In              , X86In              , O(000000,EC,_,_,_,_,_,_  ), O(000000,E4,_,_,_,_,_,_  ), 0 , 0 , 9508, 94 , 45 , 0 ),
+     458             :   INST(Inc             , X86IncDec          , O(000000,FE,0,_,x,_,_,_  ), O(000000,40,_,_,x,_,_,_  ), 0 , 0 , 1164, 95 , 43 , 0 ),
+     459             :   INST(Ins             , X86Ins             , O(000000,6C,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1168, 96 , 45 , 0 ),
+     460             :   INST(Insertps        , ExtRmi             , O(660F3A,21,_,_,_,_,_,_  ), 0                         , 0 , 0 , 5542, 40 , 12 , 23),
+     461             :   INST(Insertq         , ExtInsertq         , O(F20F00,79,_,_,_,_,_,_  ), O(F20F00,78,_,_,_,_,_,_  ), 0 , 0 , 1172, 97 , 46 , 0 ),
+     462             :   INST(Int             , X86Int             , O(000000,CD,_,_,_,_,_,_  ), 0                         , 0 , 0 , 963 , 98 , 45 , 0 ),
+     463             :   INST(Int3            , X86Op              , O(000000,CC,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1180, 34 , 45 , 0 ),
+     464             :   INST(Into            , X86Op              , O(000000,CE,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1185, 99 , 54 , 0 ),
+     465             :   INST(Invd            , X86Op              , O(000F00,08,_,_,_,_,_,_  ), 0                         , 0 , 0 , 9463, 34 , 55 , 0 ),
+     466             :   INST(Invlpg          , X86M_Only          , O(000F00,01,7,_,_,_,_,_  ), 0                         , 0 , 0 , 1190, 35 , 55 , 0 ),
+     467             :   INST(Invpcid         , X86Rm_NoRexW       , O(660F38,82,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1197, 100, 55 , 0 ),
+     468             :   INST(Iret            , X86Op              , O(000000,CF,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1205, 34 , 16 , 0 ),
+     469             :   INST(Iretd           , X86Op              , O(000000,CF,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1210, 34 , 16 , 0 ),
+     470             :   INST(Iretq           , X86Op              , O(000000,CF,_,_,1,_,_,_  ), 0                         , 0 , 0 , 1216, 101, 16 , 0 ),
+     471             :   INST(Iretw           , X86Op              , O(660000,CF,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1222, 34 , 16 , 0 ),
+     472             :   INST(Ja              , X86Jcc             , O(000F00,87,_,_,_,_,_,_  ), O(000000,77,_,_,_,_,_,_  ), 0 , 0 , 1228, 102, 56 , 0 ),
+     473             :   INST(Jae             , X86Jcc             , O(000F00,83,_,_,_,_,_,_  ), O(000000,73,_,_,_,_,_,_  ), 0 , 0 , 1231, 103, 57 , 0 ),
+     474             :   INST(Jb              , X86Jcc             , O(000F00,82,_,_,_,_,_,_  ), O(000000,72,_,_,_,_,_,_  ), 0 , 0 , 1235, 104, 57 , 0 ),
+     475             :   INST(Jbe             , X86Jcc             , O(000F00,86,_,_,_,_,_,_  ), O(000000,76,_,_,_,_,_,_  ), 0 , 0 , 1238, 105, 56 , 0 ),
+     476             :   INST(Jc              , X86Jcc             , O(000F00,82,_,_,_,_,_,_  ), O(000000,72,_,_,_,_,_,_  ), 0 , 0 , 1242, 106, 57 , 0 ),
+     477             :   INST(Je              , X86Jcc             , O(000F00,84,_,_,_,_,_,_  ), O(000000,74,_,_,_,_,_,_  ), 0 , 0 , 1245, 107, 58 , 0 ),
+     478             :   INST(Jecxz           , X86JecxzLoop       , 0                         , O(000000,E3,_,_,_,_,_,_  ), 0 , 0 , 1248, 108, 45 , 0 ),
+     479             :   INST(Jg              , X86Jcc             , O(000F00,8F,_,_,_,_,_,_  ), O(000000,7F,_,_,_,_,_,_  ), 0 , 0 , 1254, 109, 59 , 0 ),
+     480             :   INST(Jge             , X86Jcc             , O(000F00,8D,_,_,_,_,_,_  ), O(000000,7D,_,_,_,_,_,_  ), 0 , 0 , 1257, 110, 60 , 0 ),
+     481             :   INST(Jl              , X86Jcc             , O(000F00,8C,_,_,_,_,_,_  ), O(000000,7C,_,_,_,_,_,_  ), 0 , 0 , 1261, 111, 60 , 0 ),
+     482             :   INST(Jle             , X86Jcc             , O(000F00,8E,_,_,_,_,_,_  ), O(000000,7E,_,_,_,_,_,_  ), 0 , 0 , 1264, 112, 59 , 0 ),
+     483             :   INST(Jmp             , X86Jmp             , O(000000,FF,4,_,_,_,_,_  ), O(000000,EB,_,_,_,_,_,_  ), 0 , 0 , 1268, 113, 45 , 0 ),
+     484             :   INST(Jna             , X86Jcc             , O(000F00,86,_,_,_,_,_,_  ), O(000000,76,_,_,_,_,_,_  ), 0 , 0 , 1272, 105, 56 , 0 ),
+     485             :   INST(Jnae            , X86Jcc             , O(000F00,82,_,_,_,_,_,_  ), O(000000,72,_,_,_,_,_,_  ), 0 , 0 , 1276, 104, 57 , 0 ),
+     486             :   INST(Jnb             , X86Jcc             , O(000F00,83,_,_,_,_,_,_  ), O(000000,73,_,_,_,_,_,_  ), 0 , 0 , 1281, 103, 57 , 0 ),
+     487             :   INST(Jnbe            , X86Jcc             , O(000F00,87,_,_,_,_,_,_  ), O(000000,77,_,_,_,_,_,_  ), 0 , 0 , 1285, 102, 56 , 0 ),
+     488             :   INST(Jnc             , X86Jcc             , O(000F00,83,_,_,_,_,_,_  ), O(000000,73,_,_,_,_,_,_  ), 0 , 0 , 1290, 114, 57 , 0 ),
+     489             :   INST(Jne             , X86Jcc             , O(000F00,85,_,_,_,_,_,_  ), O(000000,75,_,_,_,_,_,_  ), 0 , 0 , 1294, 115, 58 , 0 ),
+     490             :   INST(Jng             , X86Jcc             , O(000F00,8E,_,_,_,_,_,_  ), O(000000,7E,_,_,_,_,_,_  ), 0 , 0 , 1298, 112, 59 , 0 ),
+     491             :   INST(Jnge            , X86Jcc             , O(000F00,8C,_,_,_,_,_,_  ), O(000000,7C,_,_,_,_,_,_  ), 0 , 0 , 1302, 111, 60 , 0 ),
+     492             :   INST(Jnl             , X86Jcc             , O(000F00,8D,_,_,_,_,_,_  ), O(000000,7D,_,_,_,_,_,_  ), 0 , 0 , 1307, 110, 60 , 0 ),
+     493             :   INST(Jnle            , X86Jcc             , O(000F00,8F,_,_,_,_,_,_  ), O(000000,7F,_,_,_,_,_,_  ), 0 , 0 , 1311, 109, 59 , 0 ),
+     494             :   INST(Jno             , X86Jcc             , O(000F00,81,_,_,_,_,_,_  ), O(000000,71,_,_,_,_,_,_  ), 0 , 0 , 1316, 116, 54 , 0 ),
+     495             :   INST(Jnp             , X86Jcc             , O(000F00,8B,_,_,_,_,_,_  ), O(000000,7B,_,_,_,_,_,_  ), 0 , 0 , 1320, 117, 61 , 0 ),
+     496             :   INST(Jns             , X86Jcc             , O(000F00,89,_,_,_,_,_,_  ), O(000000,79,_,_,_,_,_,_  ), 0 , 0 , 1324, 118, 62 , 0 ),
+     497             :   INST(Jnz             , X86Jcc             , O(000F00,85,_,_,_,_,_,_  ), O(000000,75,_,_,_,_,_,_  ), 0 , 0 , 1328, 115, 58 , 0 ),
+     498             :   INST(Jo              , X86Jcc             , O(000F00,80,_,_,_,_,_,_  ), O(000000,70,_,_,_,_,_,_  ), 0 , 0 , 1332, 119, 54 , 0 ),
+     499             :   INST(Jp              , X86Jcc             , O(000F00,8A,_,_,_,_,_,_  ), O(000000,7A,_,_,_,_,_,_  ), 0 , 0 , 1335, 120, 61 , 0 ),
+     500             :   INST(Jpe             , X86Jcc             , O(000F00,8A,_,_,_,_,_,_  ), O(000000,7A,_,_,_,_,_,_  ), 0 , 0 , 1338, 120, 61 , 0 ),
+     501             :   INST(Jpo             , X86Jcc             , O(000F00,8B,_,_,_,_,_,_  ), O(000000,7B,_,_,_,_,_,_  ), 0 , 0 , 1342, 117, 61 , 0 ),
+     502             :   INST(Js              , X86Jcc             , O(000F00,88,_,_,_,_,_,_  ), O(000000,78,_,_,_,_,_,_  ), 0 , 0 , 1346, 121, 62 , 0 ),
+     503             :   INST(Jz              , X86Jcc             , O(000F00,84,_,_,_,_,_,_  ), O(000000,74,_,_,_,_,_,_  ), 0 , 0 , 1349, 107, 58 , 0 ),
+     504             :   INST(Kaddb           , VexRvm             , V(660F00,4A,_,1,0,_,_,_  ), 0                         , 0 , 0 , 1352, 122, 63 , 0 ),
+     505             :   INST(Kaddd           , VexRvm             , V(660F00,4A,_,1,1,_,_,_  ), 0                         , 0 , 0 , 1358, 122, 64 , 0 ),
+     506             :   INST(Kaddq           , VexRvm             , V(000F00,4A,_,1,1,_,_,_  ), 0                         , 0 , 0 , 1364, 122, 64 , 0 ),
+     507             :   INST(Kaddw           , VexRvm             , V(000F00,4A,_,1,0,_,_,_  ), 0                         , 0 , 0 , 1370, 122, 63 , 0 ),
+     508             :   INST(Kandb           , VexRvm             , V(660F00,41,_,1,0,_,_,_  ), 0                         , 0 , 0 , 1376, 122, 63 , 0 ),
+     509             :   INST(Kandd           , VexRvm             , V(660F00,41,_,1,1,_,_,_  ), 0                         , 0 , 0 , 1382, 122, 64 , 0 ),
+     510             :   INST(Kandnb          , VexRvm             , V(660F00,42,_,1,0,_,_,_  ), 0                         , 0 , 0 , 1388, 122, 63 , 0 ),
+     511             :   INST(Kandnd          , VexRvm             , V(660F00,42,_,1,1,_,_,_  ), 0                         , 0 , 0 , 1395, 122, 64 , 0 ),
+     512             :   INST(Kandnq          , VexRvm             , V(000F00,42,_,1,1,_,_,_  ), 0                         , 0 , 0 , 1402, 122, 64 , 0 ),
+     513             :   INST(Kandnw          , VexRvm             , V(000F00,42,_,1,0,_,_,_  ), 0                         , 0 , 0 , 1409, 122, 65 , 0 ),
+     514             :   INST(Kandq           , VexRvm             , V(000F00,41,_,1,1,_,_,_  ), 0                         , 0 , 0 , 1416, 122, 64 , 0 ),
+     515             :   INST(Kandw           , VexRvm             , V(000F00,41,_,1,0,_,_,_  ), 0                         , 0 , 0 , 1422, 122, 65 , 0 ),
+     516             :   INST(Kmovb           , VexKmov            , V(660F00,90,_,0,0,_,_,_  ), V(660F00,92,_,0,0,_,_,_  ), 0 , 0 , 1428, 123, 63 , 0 ),
+     517             :   INST(Kmovd           , VexKmov            , V(660F00,90,_,0,1,_,_,_  ), V(F20F00,92,_,0,0,_,_,_  ), 0 , 0 , 7344, 124, 64 , 0 ),
+     518             :   INST(Kmovq           , VexKmov            , V(000F00,90,_,0,1,_,_,_  ), V(F20F00,92,_,0,1,_,_,_  ), 0 , 0 , 7355, 125, 64 , 0 ),
+     519             :   INST(Kmovw           , VexKmov            , V(000F00,90,_,0,0,_,_,_  ), V(000F00,92,_,0,0,_,_,_  ), 0 , 0 , 1434, 126, 65 , 0 ),
+     520             :   INST(Knotb           , VexRm              , V(660F00,44,_,0,0,_,_,_  ), 0                         , 0 , 0 , 1440, 127, 63 , 0 ),
+     521             :   INST(Knotd           , VexRm              , V(660F00,44,_,0,1,_,_,_  ), 0                         , 0 , 0 , 1446, 127, 64 , 0 ),
+     522             :   INST(Knotq           , VexRm              , V(000F00,44,_,0,1,_,_,_  ), 0                         , 0 , 0 , 1452, 127, 64 , 0 ),
+     523             :   INST(Knotw           , VexRm              , V(000F00,44,_,0,0,_,_,_  ), 0                         , 0 , 0 , 1458, 127, 65 , 0 ),
+     524             :   INST(Korb            , VexRvm             , V(660F00,45,_,1,0,_,_,_  ), 0                         , 0 , 0 , 1464, 122, 63 , 0 ),
+     525             :   INST(Kord            , VexRvm             , V(660F00,45,_,1,1,_,_,_  ), 0                         , 0 , 0 , 1469, 122, 64 , 0 ),
+     526             :   INST(Korq            , VexRvm             , V(000F00,45,_,1,1,_,_,_  ), 0                         , 0 , 0 , 1474, 122, 64 , 0 ),
+     527             :   INST(Kortestb        , VexRm              , V(660F00,98,_,0,0,_,_,_  ), 0                         , 0 , 0 , 1479, 128, 66 , 0 ),
+     528             :   INST(Kortestd        , VexRm              , V(660F00,98,_,0,1,_,_,_  ), 0                         , 0 , 0 , 1488, 128, 67 , 0 ),
+     529             :   INST(Kortestq        , VexRm              , V(000F00,98,_,0,1,_,_,_  ), 0                         , 0 , 0 , 1497, 128, 67 , 0 ),
+     530             :   INST(Kortestw        , VexRm              , V(000F00,98,_,0,0,_,_,_  ), 0                         , 0 , 0 , 1506, 128, 68 , 0 ),
+     531             :   INST(Korw            , VexRvm             , V(000F00,45,_,1,0,_,_,_  ), 0                         , 0 , 0 , 1515, 122, 65 , 0 ),
+     532             :   INST(Kshiftlb        , VexRmi             , V(660F3A,32,_,0,0,_,_,_  ), 0                         , 0 , 0 , 1520, 129, 63 , 0 ),
+     533             :   INST(Kshiftld        , VexRmi             , V(660F3A,33,_,0,0,_,_,_  ), 0                         , 0 , 0 , 1529, 129, 64 , 0 ),
+     534             :   INST(Kshiftlq        , VexRmi             , V(660F3A,33,_,0,1,_,_,_  ), 0                         , 0 , 0 , 1538, 129, 64 , 0 ),
+     535             :   INST(Kshiftlw        , VexRmi             , V(660F3A,32,_,0,1,_,_,_  ), 0                         , 0 , 0 , 1547, 129, 65 , 0 ),
+     536             :   INST(Kshiftrb        , VexRmi             , V(660F3A,30,_,0,0,_,_,_  ), 0                         , 0 , 0 , 1556, 129, 63 , 0 ),
+     537             :   INST(Kshiftrd        , VexRmi             , V(660F3A,31,_,0,0,_,_,_  ), 0                         , 0 , 0 , 1565, 129, 64 , 0 ),
+     538             :   INST(Kshiftrq        , VexRmi             , V(660F3A,31,_,0,1,_,_,_  ), 0                         , 0 , 0 , 1574, 129, 64 , 0 ),
+     539             :   INST(Kshiftrw        , VexRmi             , V(660F3A,30,_,0,1,_,_,_  ), 0                         , 0 , 0 , 1583, 129, 65 , 0 ),
+     540             :   INST(Ktestb          , VexRm              , V(660F00,99,_,0,0,_,_,_  ), 0                         , 0 , 0 , 1592, 128, 66 , 0 ),
+     541             :   INST(Ktestd          , VexRm              , V(660F00,99,_,0,1,_,_,_  ), 0                         , 0 , 0 , 1599, 128, 67 , 0 ),
+     542             :   INST(Ktestq          , VexRm              , V(000F00,99,_,0,1,_,_,_  ), 0                         , 0 , 0 , 1606, 128, 67 , 0 ),
+     543             :   INST(Ktestw          , VexRm              , V(000F00,99,_,0,0,_,_,_  ), 0                         , 0 , 0 , 1613, 128, 66 , 0 ),
+     544             :   INST(Kunpckbw        , VexRvm             , V(660F00,4B,_,1,0,_,_,_  ), 0                         , 0 , 0 , 1620, 122, 65 , 0 ),
+     545             :   INST(Kunpckdq        , VexRvm             , V(000F00,4B,_,1,1,_,_,_  ), 0                         , 0 , 0 , 1629, 122, 64 , 0 ),
+     546             :   INST(Kunpckwd        , VexRvm             , V(000F00,4B,_,1,0,_,_,_  ), 0                         , 0 , 0 , 1638, 122, 64 , 0 ),
+     547             :   INST(Kxnorb          , VexRvm             , V(660F00,46,_,1,0,_,_,_  ), 0                         , 0 , 0 , 1647, 122, 63 , 0 ),
+     548             :   INST(Kxnord          , VexRvm             , V(660F00,46,_,1,1,_,_,_  ), 0                         , 0 , 0 , 1654, 122, 64 , 0 ),
+     549             :   INST(Kxnorq          , VexRvm             , V(000F00,46,_,1,1,_,_,_  ), 0                         , 0 , 0 , 1661, 122, 64 , 0 ),
+     550             :   INST(Kxnorw          , VexRvm             , V(000F00,46,_,1,0,_,_,_  ), 0                         , 0 , 0 , 1668, 122, 65 , 0 ),
+     551             :   INST(Kxorb           , VexRvm             , V(660F00,47,_,1,0,_,_,_  ), 0                         , 0 , 0 , 1675, 122, 63 , 0 ),
+     552             :   INST(Kxord           , VexRvm             , V(660F00,47,_,1,1,_,_,_  ), 0                         , 0 , 0 , 1681, 122, 64 , 0 ),
+     553             :   INST(Kxorq           , VexRvm             , V(000F00,47,_,1,1,_,_,_  ), 0                         , 0 , 0 , 1687, 122, 64 , 0 ),
+     554             :   INST(Kxorw           , VexRvm             , V(000F00,47,_,1,0,_,_,_  ), 0                         , 0 , 0 , 1693, 122, 65 , 0 ),
+     555             :   INST(Lahf            , X86Op              , O(000000,9F,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1699, 130, 69 , 0 ),
+     556             :   INST(Lar             , X86Rm              , O(000F00,02,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1704, 131, 70 , 0 ),
+     557             :   INST(Lddqu           , ExtRm              , O(F20F00,F0,_,_,_,_,_,_  ), 0                         , 0 , 16, 5552, 132, 6  , 24),
+     558             :   INST(Ldmxcsr         , X86M_Only          , O(000F00,AE,2,_,_,_,_,_  ), 0                         , 0 , 0 , 5559, 133, 5  , 0 ),
+     559             :   INST(Lds             , X86Rm              , O(000000,C5,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1708, 134, 45 , 0 ),
+     560             :   INST(Lea             , X86Lea             , O(000000,8D,_,_,x,_,_,_  ), 0                         , 0 , 0 , 1712, 135, 0  , 0 ),
+     561             :   INST(Leave           , X86Op              , O(000000,C9,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1716, 34 , 45 , 0 ),
+     562             :   INST(Les             , X86Rm              , O(000000,C4,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1722, 134, 45 , 0 ),
+     563             :   INST(Lfence          , X86Fence           , O(000F00,AE,5,_,_,_,_,_  ), 0                         , 0 , 0 , 1726, 34 , 71 , 0 ),
+     564             :   INST(Lfs             , X86Rm              , O(000F00,B4,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1733, 136, 45 , 0 ),
+     565             :   INST(Lgdt            , X86M_Only          , O(000F00,01,2,_,_,_,_,_  ), 0                         , 0 , 0 , 1737, 35 , 23 , 0 ),
+     566             :   INST(Lgs             , X86Rm              , O(000F00,B5,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1742, 136, 45 , 0 ),
+     567             :   INST(Lidt            , X86M_Only          , O(000F00,01,3,_,_,_,_,_  ), 0                         , 0 , 0 , 1746, 35 , 23 , 0 ),
+     568             :   INST(Lldt            , X86M               , O(000F00,00,2,_,_,_,_,_  ), 0                         , 0 , 0 , 1751, 137, 23 , 0 ),
+     569             :   INST(Lmsw            , X86M               , O(000F00,01,6,_,_,_,_,_  ), 0                         , 0 , 0 , 1756, 137, 23 , 0 ),
+     570             :   INST(Lods            , X86StrRm           , O(000000,AC,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1761, 138, 72 , 0 ),
+     571             :   INST(Loop            , X86JecxzLoop       , 0                         , O(000000,E2,_,_,_,_,_,_  ), 0 , 0 , 1766, 139, 45 , 0 ),
+     572             :   INST(Loope           , X86JecxzLoop       , 0                         , O(000000,E1,_,_,_,_,_,_  ), 0 , 0 , 1771, 140, 58 , 0 ),
+     573             :   INST(Loopne          , X86JecxzLoop       , 0                         , O(000000,E0,_,_,_,_,_,_  ), 0 , 0 , 1777, 141, 58 , 0 ),
+     574             :   INST(Lsl             , X86Rm              , O(000F00,03,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1784, 142, 70 , 0 ),
+     575             :   INST(Lss             , X86Rm              , O(000F00,B2,_,_,_,_,_,_  ), 0                         , 0 , 0 , 5959, 136, 45 , 0 ),
+     576             :   INST(Ltr             , X86M               , O(000F00,00,3,_,_,_,_,_  ), 0                         , 0 , 0 , 1788, 137, 23 , 0 ),
+     577             :   INST(Lzcnt           , X86Rm_Raw66H       , O(F30F00,BD,_,_,x,_,_,_  ), 0                         , 0 , 0 , 1792, 143, 73 , 0 ),
+     578             :   INST(Maskmovdqu      , ExtRm_ZDI          , O(660F00,57,_,_,_,_,_,_  ), 0                         , 0 , 0 , 5568, 144, 4  , 25),
+     579             :   INST(Maskmovq        , ExtRm_ZDI          , O(000F00,F7,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7352, 145, 74 , 0 ),
+     580             :   INST(Maxpd           , ExtRm              , O(660F00,5F,_,_,_,_,_,_  ), 0                         , 0 , 0 , 5602, 5  , 4  , 26),
+     581             :   INST(Maxps           , ExtRm              , O(000F00,5F,_,_,_,_,_,_  ), 0                         , 0 , 0 , 5609, 5  , 5  , 26),
+     582             :   INST(Maxsd           , ExtRm              , O(F20F00,5F,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7371, 6  , 4  , 26),
+     583             :   INST(Maxss           , ExtRm              , O(F30F00,5F,_,_,_,_,_,_  ), 0                         , 0 , 0 , 5623, 7  , 5  , 26),
+     584             :   INST(Mfence          , X86Fence           , O(000F00,AE,6,_,_,_,_,_  ), 0                         , 0 , 0 , 1798, 34 , 71 , 0 ),
+     585             :   INST(Minpd           , ExtRm              , O(660F00,5D,_,_,_,_,_,_  ), 0                         , 0 , 0 , 5630, 5  , 4  , 27),
+     586             :   INST(Minps           , ExtRm              , O(000F00,5D,_,_,_,_,_,_  ), 0                         , 0 , 0 , 5637, 5  , 5  , 27),
+     587             :   INST(Minsd           , ExtRm              , O(F20F00,5D,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7435, 6  , 4  , 27),
+     588             :   INST(Minss           , ExtRm              , O(F30F00,5D,_,_,_,_,_,_  ), 0                         , 0 , 0 , 5651, 7  , 5  , 27),
+     589             :   INST(Monitor         , X86Op              , O(000F01,C8,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1805, 146, 75 , 0 ),
+     590             :   INST(Mov             , X86Mov             , 0                         , 0                         , 0 , 0 , 138 , 147, 76 , 0 ),
+     591             :   INST(Movapd          , ExtMov             , O(660F00,28,_,_,_,_,_,_  ), O(660F00,29,_,_,_,_,_,_  ), 0 , 16, 5658, 148, 4  , 28),
+     592             :   INST(Movaps          , ExtMov             , O(000F00,28,_,_,_,_,_,_  ), O(000F00,29,_,_,_,_,_,_  ), 0 , 16, 5666, 149, 5  , 28),
+     593             :   INST(Movbe           , ExtMovbe           , O(000F38,F0,_,_,x,_,_,_  ), O(000F38,F1,_,_,x,_,_,_  ), 0 , 0 , 597 , 150, 77 , 0 ),
+     594             :   INST(Movd            , ExtMovd            , O(000F00,6E,_,_,_,_,_,_  ), O(000F00,7E,_,_,_,_,_,_  ), 0 , 16, 7345, 151, 78 , 29),
+     595             :   INST(Movddup         , ExtMov             , O(F20F00,12,_,_,_,_,_,_  ), 0                         , 0 , 16, 5680, 49 , 6  , 29),
+     596             :   INST(Movdq2q         , ExtMov             , O(F20F00,D6,_,_,_,_,_,_  ), 0                         , 0 , 8 , 1813, 152, 4  , 0 ),
+     597             :   INST(Movdqa          , ExtMov             , O(660F00,6F,_,_,_,_,_,_  ), O(660F00,7F,_,_,_,_,_,_  ), 0 , 16, 5689, 153, 4  , 30),
+     598             :   INST(Movdqu          , ExtMov             , O(F30F00,6F,_,_,_,_,_,_  ), O(F30F00,7F,_,_,_,_,_,_  ), 0 , 16, 5572, 154, 4  , 28),
+     599             :   INST(Movhlps         , ExtMov             , O(000F00,12,_,_,_,_,_,_  ), 0                         , 0 , 8 , 5764, 155, 5  , 31),
+     600             :   INST(Movhpd          , ExtMov             , O(660F00,16,_,_,_,_,_,_  ), O(660F00,17,_,_,_,_,_,_  ), 8 , 8 , 5773, 156, 4  , 32),
+     601             :   INST(Movhps          , ExtMov             , O(000F00,16,_,_,_,_,_,_  ), O(000F00,17,_,_,_,_,_,_  ), 8 , 8 , 5781, 157, 5  , 32),
+     602             :   INST(Movlhps         , ExtMov             , O(000F00,16,_,_,_,_,_,_  ), 0                         , 8 , 8 , 5789, 158, 5  , 31),
+     603             :   INST(Movlpd          , ExtMov             , O(660F00,12,_,_,_,_,_,_  ), O(660F00,13,_,_,_,_,_,_  ), 0 , 8 , 5798, 159, 4  , 32),
+     604             :   INST(Movlps          , ExtMov             , O(000F00,12,_,_,_,_,_,_  ), O(000F00,13,_,_,_,_,_,_  ), 0 , 8 , 5806, 160, 5  , 32),
+     605             :   INST(Movmskpd        , ExtMov             , O(660F00,50,_,_,_,_,_,_  ), 0                         , 0 , 8 , 5814, 161, 4  , 33),
+     606             :   INST(Movmskps        , ExtMov             , O(000F00,50,_,_,_,_,_,_  ), 0                         , 0 , 8 , 5824, 161, 5  , 33),
+     607             :   INST(Movntdq         , ExtMov             , 0                         , O(660F00,E7,_,_,_,_,_,_  ), 0 , 16, 5834, 162, 4  , 33),
+     608             :   INST(Movntdqa        , ExtMov             , O(660F38,2A,_,_,_,_,_,_  ), 0                         , 0 , 16, 5843, 132, 12 , 33),
+     609             :   INST(Movnti          , ExtMovnti          , O(000F00,C3,_,_,x,_,_,_  ), 0                         , 0 , 8 , 1821, 163, 4  , 0 ),
+     610             :   INST(Movntpd         , ExtMov             , 0                         , O(660F00,2B,_,_,_,_,_,_  ), 0 , 16, 5853, 164, 4  , 34),
+     611             :   INST(Movntps         , ExtMov             , 0                         , O(000F00,2B,_,_,_,_,_,_  ), 0 , 16, 5862, 165, 5  , 34),
+     612             :   INST(Movntq          , ExtMov             , 0                         , O(000F00,E7,_,_,_,_,_,_  ), 0 , 8 , 1828, 166, 74 , 0 ),
+     613             :   INST(Movntsd         , ExtMov             , 0                         , O(F20F00,2B,_,_,_,_,_,_  ), 0 , 8 , 1835, 167, 46 , 0 ),
+     614             :   INST(Movntss         , ExtMov             , 0                         , O(F30F00,2B,_,_,_,_,_,_  ), 0 , 4 , 1843, 168, 46 , 0 ),
+     615             :   INST(Movq            , ExtMovq            , O(000F00,6E,_,_,x,_,_,_  ), O(000F00,7E,_,_,x,_,_,_  ), 0 , 16, 7356, 169, 78 , 28),
+     616             :   INST(Movq2dq         , ExtRm              , O(F30F00,D6,_,_,_,_,_,_  ), 0                         , 0 , 16, 1851, 170, 4  , 0 ),
+     617             :   INST(Movs            , X86StrMm           , O(000000,A4,_,_,_,_,_,_  ), 0                         , 0 , 0 , 411 , 171, 72 , 0 ),
+     618             :   INST(Movsd           , ExtMov             , O(F20F00,10,_,_,_,_,_,_  ), O(F20F00,11,_,_,_,_,_,_  ), 0 , 8 , 5877, 172, 79 , 35),
+     619             :   INST(Movshdup        , ExtRm              , O(F30F00,16,_,_,_,_,_,_  ), 0                         , 0 , 16, 5884, 50 , 6  , 30),
+     620             :   INST(Movsldup        , ExtRm              , O(F30F00,12,_,_,_,_,_,_  ), 0                         , 0 , 16, 5894, 50 , 6  , 30),
+     621             :   INST(Movss           , ExtMov             , O(F30F00,10,_,_,_,_,_,_  ), O(F30F00,11,_,_,_,_,_,_  ), 0 , 4 , 5904, 173, 80 , 35),
+     622             :   INST(Movsx           , X86MovsxMovzx      , O(000F00,BE,_,_,x,_,_,_  ), 0                         , 0 , 0 , 1859, 174, 0  , 0 ),
+     623             :   INST(Movsxd          , X86Rm              , O(000000,63,_,_,1,_,_,_  ), 0                         , 0 , 0 , 1865, 175, 0  , 0 ),
+     624             :   INST(Movupd          , ExtMov             , O(660F00,10,_,_,_,_,_,_  ), O(660F00,11,_,_,_,_,_,_  ), 0 , 16, 5911, 176, 4  , 36),
+     625             :   INST(Movups          , ExtMov             , O(000F00,10,_,_,_,_,_,_  ), O(000F00,11,_,_,_,_,_,_  ), 0 , 16, 5919, 177, 5  , 36),
+     626             :   INST(Movzx           , X86MovsxMovzx      , O(000F00,B6,_,_,x,_,_,_  ), 0                         , 0 , 0 , 1872, 174, 0  , 0 ),
+     627             :   INST(Mpsadbw         , ExtRmi             , O(660F3A,42,_,_,_,_,_,_  ), 0                         , 0 , 0 , 5927, 16 , 12 , 37),
+     628             :   INST(Mul             , X86M_GPB_MulDiv    , O(000000,F6,4,_,x,_,_,_  ), 0                         , 0 , 0 , 769 , 178, 1  , 0 ),
+     629             :   INST(Mulpd           , ExtRm              , O(660F00,59,_,_,_,_,_,_  ), 0                         , 0 , 0 , 5936, 5  , 4  , 38),
+     630             :   INST(Mulps           , ExtRm              , O(000F00,59,_,_,_,_,_,_  ), 0                         , 0 , 0 , 5943, 5  , 5  , 38),
+     631             :   INST(Mulsd           , ExtRm              , O(F20F00,59,_,_,_,_,_,_  ), 0                         , 0 , 0 , 5950, 6  , 4  , 38),
+     632             :   INST(Mulss           , ExtRm              , O(F30F00,59,_,_,_,_,_,_  ), 0                         , 0 , 0 , 5957, 7  , 5  , 38),
+     633             :   INST(Mulx            , VexRvm_ZDX_Wx      , V(F20F38,F6,_,0,x,_,_,_  ), 0                         , 0 , 0 , 1878, 179, 81 , 0 ),
+     634             :   INST(Mwait           , X86Op              , O(000F01,C9,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1883, 180, 75 , 0 ),
+     635             :   INST(Neg             , X86M_GPB           , O(000000,F6,3,_,x,_,_,_  ), 0                         , 0 , 0 , 1889, 181, 1  , 0 ),
+     636             :   INST(Nop             , X86Op              , O(000000,90,_,_,_,_,_,_  ), 0                         , 0 , 0 , 900 , 182, 0  , 0 ),
+     637             :   INST(Not             , X86M_GPB           , O(000000,F6,2,_,x,_,_,_  ), 0                         , 0 , 0 , 1893, 181, 0  , 0 ),
+     638             :   INST(Or              , X86Arith           , O(000000,08,1,_,x,_,_,_  ), 0                         , 0 , 0 , 1109, 183, 1  , 0 ),
+     639             :   INST(Orpd            , ExtRm              , O(660F00,56,_,_,_,_,_,_  ), 0                         , 0 , 0 , 9429, 12 , 4  , 39),
+     640             :   INST(Orps            , ExtRm              , O(000F00,56,_,_,_,_,_,_  ), 0                         , 0 , 0 , 9436, 12 , 5  , 39),
+     641             :   INST(Out             , X86Out             , O(000000,EE,_,_,_,_,_,_  ), O(000000,E6,_,_,_,_,_,_  ), 0 , 0 , 1897, 184, 45 , 0 ),
+     642             :   INST(Outs            , X86Outs            , O(000000,6E,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1901, 185, 45 , 0 ),
+     643             :   INST(Pabsb           , ExtRm_P            , O(000F38,1C,_,_,_,_,_,_  ), 0                         , 0 , 0 , 5997, 186, 82 , 40),
+     644             :   INST(Pabsd           , ExtRm_P            , O(000F38,1E,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6004, 186, 82 , 40),
+     645             :   INST(Pabsw           , ExtRm_P            , O(000F38,1D,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6018, 186, 82 , 41),
+     646             :   INST(Packssdw        , ExtRm_P            , O(000F00,6B,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6025, 187, 78 , 42),
+     647             :   INST(Packsswb        , ExtRm_P            , O(000F00,63,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6035, 187, 78 , 42),
+     648             :   INST(Packusdw        , ExtRm              , O(660F38,2B,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6045, 5  , 12 , 42),
+     649             :   INST(Packuswb        , ExtRm_P            , O(000F00,67,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6055, 187, 78 , 42),
+     650             :   INST(Paddb           , ExtRm_P            , O(000F00,FC,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6065, 187, 78 , 42),
+     651             :   INST(Paddd           , ExtRm_P            , O(000F00,FE,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6072, 187, 78 , 42),
+     652             :   INST(Paddq           , ExtRm_P            , O(000F00,D4,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6079, 187, 4  , 42),
+     653             :   INST(Paddsb          , ExtRm_P            , O(000F00,EC,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6086, 187, 78 , 42),
+     654             :   INST(Paddsw          , ExtRm_P            , O(000F00,ED,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6094, 187, 78 , 42),
+     655             :   INST(Paddusb         , ExtRm_P            , O(000F00,DC,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6102, 187, 78 , 42),
+     656             :   INST(Paddusw         , ExtRm_P            , O(000F00,DD,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6111, 187, 78 , 42),
+     657             :   INST(Paddw           , ExtRm_P            , O(000F00,FD,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6120, 187, 78 , 42),
+     658             :   INST(Palignr         , ExtRmi_P           , O(000F3A,0F,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6127, 188, 6  , 42),
+     659             :   INST(Pand            , ExtRm_P            , O(000F00,DB,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6136, 189, 78 , 42),
+     660             :   INST(Pandn           , ExtRm_P            , O(000F00,DF,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6149, 190, 78 , 43),
+     661             :   INST(Pause           , X86Op              , O(F30000,90,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1906, 34 , 45 , 0 ),
+     662             :   INST(Pavgb           , ExtRm_P            , O(000F00,E0,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6179, 187, 83 , 44),
+     663             :   INST(Pavgusb         , Ext3dNow           , O(000F0F,BF,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1912, 191, 84 , 0 ),
+     664             :   INST(Pavgw           , ExtRm_P            , O(000F00,E3,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6186, 187, 83 , 45),
+     665             :   INST(Pblendvb        , ExtRm_XMM0         , O(660F38,10,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6202, 17 , 12 , 46),
+     666             :   INST(Pblendw         , ExtRmi             , O(660F3A,0E,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6212, 16 , 12 , 44),
+     667             :   INST(Pclmulqdq       , ExtRmi             , O(660F3A,44,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6305, 16 , 85 , 47),
+     668             :   INST(Pcmpeqb         , ExtRm_P            , O(000F00,74,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6337, 190, 78 , 48),
+     669             :   INST(Pcmpeqd         , ExtRm_P            , O(000F00,76,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6346, 190, 78 , 48),
+     670             :   INST(Pcmpeqq         , ExtRm              , O(660F38,29,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6355, 192, 12 , 48),
+     671             :   INST(Pcmpeqw         , ExtRm_P            , O(000F00,75,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6364, 190, 78 , 48),
+     672             :   INST(Pcmpestri       , ExtRmi             , O(660F3A,61,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6373, 193, 86 , 49),
+     673             :   INST(Pcmpestrm       , ExtRmi             , O(660F3A,60,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6384, 194, 86 , 49),
+     674             :   INST(Pcmpgtb         , ExtRm_P            , O(000F00,64,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6395, 190, 78 , 48),
+     675             :   INST(Pcmpgtd         , ExtRm_P            , O(000F00,66,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6404, 190, 78 , 48),
+     676             :   INST(Pcmpgtq         , ExtRm              , O(660F38,37,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6413, 192, 42 , 48),
+     677             :   INST(Pcmpgtw         , ExtRm_P            , O(000F00,65,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6422, 190, 78 , 48),
+     678             :   INST(Pcmpistri       , ExtRmi             , O(660F3A,63,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6431, 195, 86 , 49),
+     679             :   INST(Pcmpistrm       , ExtRmi             , O(660F3A,62,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6442, 196, 86 , 49),
+     680             :   INST(Pcommit         , X86Op_O            , O(660F00,AE,7,_,_,_,_,_  ), 0                         , 0 , 0 , 1920, 34 , 87 , 0 ),
+     681             :   INST(Pdep            , VexRvm_Wx          , V(F20F38,F5,_,0,x,_,_,_  ), 0                         , 0 , 0 , 1928, 11 , 81 , 0 ),
+     682             :   INST(Pext            , VexRvm_Wx          , V(F30F38,F5,_,0,x,_,_,_  ), 0                         , 0 , 0 , 1933, 11 , 81 , 0 ),
+     683             :   INST(Pextrb          , ExtExtract         , O(000F3A,14,_,_,_,_,_,_  ), 0                         , 0 , 8 , 6847, 197, 12 , 50),
+     684             :   INST(Pextrd          , ExtExtract         , O(000F3A,16,_,_,_,_,_,_  ), 0                         , 0 , 8 , 6855, 67 , 12 , 50),
+     685             :   INST(Pextrq          , ExtExtract         , O(000F3A,16,_,_,1,_,_,_  ), 0                         , 0 , 8 , 6863, 198, 12 , 50),
+     686             :   INST(Pextrw          , ExtPextrw          , O(000F00,C5,_,_,_,_,_,_  ), O(000F3A,15,_,_,_,_,_,_  ), 0 , 8 , 6871, 199, 88 , 50),
+     687             :   INST(Pf2id           , Ext3dNow           , O(000F0F,1D,_,_,_,_,_,_  ), 0                         , 0 , 8 , 1938, 200, 84 , 0 ),
+     688             :   INST(Pf2iw           , Ext3dNow           , O(000F0F,1C,_,_,_,_,_,_  ), 0                         , 0 , 8 , 1944, 200, 89 , 0 ),
+     689             :   INST(Pfacc           , Ext3dNow           , O(000F0F,AE,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1950, 191, 84 , 0 ),
+     690             :   INST(Pfadd           , Ext3dNow           , O(000F0F,9E,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1956, 191, 84 , 0 ),
+     691             :   INST(Pfcmpeq         , Ext3dNow           , O(000F0F,B0,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1962, 191, 84 , 0 ),
+     692             :   INST(Pfcmpge         , Ext3dNow           , O(000F0F,90,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1970, 191, 84 , 0 ),
+     693             :   INST(Pfcmpgt         , Ext3dNow           , O(000F0F,A0,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1978, 191, 84 , 0 ),
+     694             :   INST(Pfmax           , Ext3dNow           , O(000F0F,A4,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1986, 191, 84 , 0 ),
+     695             :   INST(Pfmin           , Ext3dNow           , O(000F0F,94,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1992, 191, 84 , 0 ),
+     696             :   INST(Pfmul           , Ext3dNow           , O(000F0F,B4,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1998, 191, 84 , 0 ),
+     697             :   INST(Pfnacc          , Ext3dNow           , O(000F0F,8A,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2004, 191, 89 , 0 ),
+     698             :   INST(Pfpnacc         , Ext3dNow           , O(000F0F,8E,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2011, 191, 89 , 0 ),
+     699             :   INST(Pfrcp           , Ext3dNow           , O(000F0F,96,_,_,_,_,_,_  ), 0                         , 0 , 8 , 2019, 200, 84 , 0 ),
+     700             :   INST(Pfrcpit1        , Ext3dNow           , O(000F0F,A6,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2025, 191, 84 , 0 ),
+     701             :   INST(Pfrcpit2        , Ext3dNow           , O(000F0F,B6,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2034, 191, 84 , 0 ),
+     702             :   INST(Pfrcpv          , Ext3dNow           , O(000F0F,86,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2043, 191, 90 , 0 ),
+     703             :   INST(Pfrsqit1        , Ext3dNow           , O(000F0F,A7,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2050, 201, 84 , 0 ),
+     704             :   INST(Pfrsqrt         , Ext3dNow           , O(000F0F,97,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2059, 201, 84 , 0 ),
+     705             :   INST(Pfrsqrtv        , Ext3dNow           , O(000F0F,87,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2067, 191, 90 , 0 ),
+     706             :   INST(Pfsub           , Ext3dNow           , O(000F0F,9A,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2076, 191, 84 , 0 ),
+     707             :   INST(Pfsubr          , Ext3dNow           , O(000F0F,AA,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2082, 191, 84 , 0 ),
+     708             :   INST(Phaddd          , ExtRm_P            , O(000F38,02,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6950, 187, 82 , 51),
+     709             :   INST(Phaddsw         , ExtRm_P            , O(000F38,03,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6967, 187, 82 , 52),
+     710             :   INST(Phaddw          , ExtRm_P            , O(000F38,01,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7036, 187, 82 , 53),
+     711             :   INST(Phminposuw      , ExtRm              , O(660F38,41,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7062, 5  , 12 , 54),
+     712             :   INST(Phsubd          , ExtRm_P            , O(000F38,06,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7083, 187, 82 , 55),
+     713             :   INST(Phsubsw         , ExtRm_P            , O(000F38,07,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7100, 187, 82 , 56),
+     714             :   INST(Phsubw          , ExtRm_P            , O(000F38,05,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7109, 187, 82 , 56),
+     715             :   INST(Pi2fd           , Ext3dNow           , O(000F0F,0D,_,_,_,_,_,_  ), 0                         , 0 , 8 , 2089, 200, 84 , 0 ),
+     716             :   INST(Pi2fw           , Ext3dNow           , O(000F0F,0C,_,_,_,_,_,_  ), 0                         , 0 , 8 , 2095, 200, 89 , 0 ),
+     717             :   INST(Pinsrb          , ExtRmi             , O(660F3A,20,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7126, 202, 12 , 57),
+     718             :   INST(Pinsrd          , ExtRmi             , O(660F3A,22,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7134, 203, 12 , 57),
+     719             :   INST(Pinsrq          , ExtRmi             , O(660F3A,22,_,_,1,_,_,_  ), 0                         , 0 , 0 , 7142, 204, 12 , 57),
+     720             :   INST(Pinsrw          , ExtRmi_P           , O(000F00,C4,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7150, 205, 83 , 55),
+     721             :   INST(Pmaddubsw       , ExtRm_P            , O(000F38,04,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7320, 187, 82 , 58),
+     722             :   INST(Pmaddwd         , ExtRm_P            , O(000F00,F5,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7331, 187, 78 , 58),
+     723             :   INST(Pmaxsb          , ExtRm              , O(660F38,3C,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7362, 12 , 12 , 59),
+     724             :   INST(Pmaxsd          , ExtRm              , O(660F38,3D,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7370, 12 , 12 , 59),
+     725             :   INST(Pmaxsw          , ExtRm_P            , O(000F00,EE,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7386, 189, 83 , 60),
+     726             :   INST(Pmaxub          , ExtRm_P            , O(000F00,DE,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7394, 189, 83 , 60),
+     727             :   INST(Pmaxud          , ExtRm              , O(660F38,3F,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7402, 12 , 12 , 60),
+     728             :   INST(Pmaxuw          , ExtRm              , O(660F38,3E,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7418, 12 , 12 , 61),
+     729             :   INST(Pminsb          , ExtRm              , O(660F38,38,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7426, 12 , 12 , 61),
+     730             :   INST(Pminsd          , ExtRm              , O(660F38,39,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7434, 12 , 12 , 61),
+     731             :   INST(Pminsw          , ExtRm_P            , O(000F00,EA,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7450, 189, 83 , 62),
+     732             :   INST(Pminub          , ExtRm_P            , O(000F00,DA,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7458, 189, 83 , 62),
+     733             :   INST(Pminud          , ExtRm              , O(660F38,3B,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7466, 12 , 12 , 62),
+     734             :   INST(Pminuw          , ExtRm              , O(660F38,3A,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7482, 12 , 12 , 63),
+     735             :   INST(Pmovmskb        , ExtRm_P            , O(000F00,D7,_,_,_,_,_,_  ), 0                         , 0 , 8 , 7560, 206, 83 , 64),
+     736             :   INST(Pmovsxbd        , ExtRm              , O(660F38,21,_,_,_,_,_,_  ), 0                         , 0 , 16, 7657, 207, 12 , 14),
+     737             :   INST(Pmovsxbq        , ExtRm              , O(660F38,22,_,_,_,_,_,_  ), 0                         , 0 , 16, 7667, 208, 12 , 14),
+     738             :   INST(Pmovsxbw        , ExtRm              , O(660F38,20,_,_,_,_,_,_  ), 0                         , 0 , 16, 7677, 49 , 12 , 14),
+     739             :   INST(Pmovsxdq        , ExtRm              , O(660F38,25,_,_,_,_,_,_  ), 0                         , 0 , 16, 7687, 49 , 12 , 14),
+     740             :   INST(Pmovsxwd        , ExtRm              , O(660F38,23,_,_,_,_,_,_  ), 0                         , 0 , 16, 7697, 49 , 12 , 14),
+     741             :   INST(Pmovsxwq        , ExtRm              , O(660F38,24,_,_,_,_,_,_  ), 0                         , 0 , 16, 7707, 207, 12 , 14),
+     742             :   INST(Pmovzxbd        , ExtRm              , O(660F38,31,_,_,_,_,_,_  ), 0                         , 0 , 16, 7794, 207, 12 , 65),
+     743             :   INST(Pmovzxbq        , ExtRm              , O(660F38,32,_,_,_,_,_,_  ), 0                         , 0 , 16, 7804, 208, 12 , 65),
+     744             :   INST(Pmovzxbw        , ExtRm              , O(660F38,30,_,_,_,_,_,_  ), 0                         , 0 , 16, 7814, 49 , 12 , 65),
+     745             :   INST(Pmovzxdq        , ExtRm              , O(660F38,35,_,_,_,_,_,_  ), 0                         , 0 , 16, 7824, 49 , 12 , 65),
+     746             :   INST(Pmovzxwd        , ExtRm              , O(660F38,33,_,_,_,_,_,_  ), 0                         , 0 , 16, 7834, 49 , 12 , 65),
+     747             :   INST(Pmovzxwq        , ExtRm              , O(660F38,34,_,_,_,_,_,_  ), 0                         , 0 , 16, 7844, 207, 12 , 65),
+     748             :   INST(Pmuldq          , ExtRm              , O(660F38,28,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7854, 5  , 12 , 19),
+     749             :   INST(Pmulhrsw        , ExtRm_P            , O(000F38,0B,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7862, 187, 82 , 19),
+     750             :   INST(Pmulhrw         , Ext3dNow           , O(000F0F,B7,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2101, 191, 84 , 0 ),
+     751             :   INST(Pmulhuw         , ExtRm_P            , O(000F00,E4,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7872, 187, 83 , 66),
+     752             :   INST(Pmulhw          , ExtRm_P            , O(000F00,E5,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7881, 187, 78 , 66),
+     753             :   INST(Pmulld          , ExtRm              , O(660F38,40,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7889, 5  , 12 , 66),
+     754             :   INST(Pmullw          , ExtRm_P            , O(000F00,D5,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7905, 187, 78 , 19),
+     755             :   INST(Pmuludq         , ExtRm_P            , O(000F00,F4,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7928, 187, 4  , 67),
+     756             :   INST(Pop             , X86Pop             , O(000000,8F,0,_,_,_,_,_  ), O(000000,58,_,_,_,_,_,_  ), 0 , 0 , 2109, 209, 45 , 0 ),
+     757             :   INST(Popa            , X86Op              , O(660000,61,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2113, 99 , 45 , 0 ),
+     758             :   INST(Popad           , X86Op              , O(000000,61,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2118, 99 , 45 , 0 ),
+     759             :   INST(Popcnt          , X86Rm_Raw66H       , O(F30F00,B8,_,_,x,_,_,_  ), 0                         , 0 , 0 , 2124, 143, 91 , 0 ),
+     760             :   INST(Popf            , X86Op              , O(660000,9D,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2131, 34 , 16 , 0 ),
+     761             :   INST(Popfd           , X86Op              , O(000000,9D,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2136, 99 , 16 , 0 ),
+     762             :   INST(Popfq           , X86Op              , O(000000,9D,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2142, 101, 16 , 0 ),
+     763             :   INST(Por             , ExtRm_P            , O(000F00,EB,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7955, 189, 78 , 68),
+     764             :   INST(Prefetch        , X86M_Only          , O(000F00,0D,0,_,_,_,_,_  ), 0                         , 0 , 0 , 2148, 35 , 92 , 0 ),
+     765             :   INST(Prefetchnta     , X86M_Only          , O(000F00,18,0,_,_,_,_,_  ), 0                         , 0 , 0 , 2157, 35 , 93 , 0 ),
+     766             :   INST(Prefetcht0      , X86M_Only          , O(000F00,18,1,_,_,_,_,_  ), 0                         , 0 , 0 , 2169, 35 , 93 , 0 ),
+     767             :   INST(Prefetcht1      , X86M_Only          , O(000F00,18,2,_,_,_,_,_  ), 0                         , 0 , 0 , 2180, 35 , 93 , 0 ),
+     768             :   INST(Prefetcht2      , X86M_Only          , O(000F00,18,3,_,_,_,_,_  ), 0                         , 0 , 0 , 2191, 35 , 93 , 0 ),
+     769             :   INST(Prefetchw       , X86M_Only          , O(000F00,0D,1,_,_,_,_,_  ), 0                         , 0 , 0 , 2202, 35 , 94 , 0 ),
+     770             :   INST(Prefetchwt1     , X86M_Only          , O(000F00,0D,2,_,_,_,_,_  ), 0                         , 0 , 0 , 2212, 35 , 95 , 0 ),
+     771             :   INST(Psadbw          , ExtRm_P            , O(000F00,F6,_,_,_,_,_,_  ), 0                         , 0 , 0 , 3795, 187, 83 , 69),
+     772             :   INST(Pshufb          , ExtRm_P            , O(000F38,00,_,_,_,_,_,_  ), 0                         , 0 , 0 , 8179, 187, 82 , 70),
+     773             :   INST(Pshufd          , ExtRmi             , O(660F00,70,_,_,_,_,_,_  ), 0                         , 0 , 16, 8187, 210, 4  , 71),
+     774             :   INST(Pshufhw         , ExtRmi             , O(F30F00,70,_,_,_,_,_,_  ), 0                         , 0 , 16, 8195, 210, 4  , 71),
+     775             :   INST(Pshuflw         , ExtRmi             , O(F20F00,70,_,_,_,_,_,_  ), 0                         , 0 , 16, 8204, 210, 4  , 71),
+     776             :   INST(Pshufw          , ExtRmi_P           , O(000F00,70,_,_,_,_,_,_  ), 0                         , 0 , 8 , 2224, 211, 74 , 0 ),
+     777             :   INST(Psignb          , ExtRm_P            , O(000F38,08,_,_,_,_,_,_  ), 0                         , 0 , 0 , 8213, 187, 82 , 72),
+     778             :   INST(Psignd          , ExtRm_P            , O(000F38,0A,_,_,_,_,_,_  ), 0                         , 0 , 0 , 8221, 187, 82 , 72),
+     779             :   INST(Psignw          , ExtRm_P            , O(000F38,09,_,_,_,_,_,_  ), 0                         , 0 , 0 , 8229, 187, 82 , 72),
+     780             :   INST(Pslld           , ExtRmRi_P          , O(000F00,F2,_,_,_,_,_,_  ), O(000F00,72,6,_,_,_,_,_  ), 0 , 0 , 8237, 212, 78 , 72),
+     781             :   INST(Pslldq          , ExtRmRi            , 0                         , O(660F00,73,7,_,_,_,_,_  ), 0 , 0 , 8244, 213, 4  , 72),
+     782             :   INST(Psllq           , ExtRmRi_P          , O(000F00,F3,_,_,_,_,_,_  ), O(000F00,73,6,_,_,_,_,_  ), 0 , 0 , 8252, 214, 78 , 72),
+     783             :   INST(Psllw           , ExtRmRi_P          , O(000F00,F1,_,_,_,_,_,_  ), O(000F00,71,6,_,_,_,_,_  ), 0 , 0 , 8283, 215, 78 , 73),
+     784             :   INST(Psrad           , ExtRmRi_P          , O(000F00,E2,_,_,_,_,_,_  ), O(000F00,72,4,_,_,_,_,_  ), 0 , 0 , 8290, 216, 78 , 73),
+     785             :   INST(Psraw           , ExtRmRi_P          , O(000F00,E1,_,_,_,_,_,_  ), O(000F00,71,4,_,_,_,_,_  ), 0 , 0 , 8328, 217, 78 , 74),
+     786             :   INST(Psrld           , ExtRmRi_P          , O(000F00,D2,_,_,_,_,_,_  ), O(000F00,72,2,_,_,_,_,_  ), 0 , 0 , 8335, 218, 78 , 74),
+     787             :   INST(Psrldq          , ExtRmRi            , 0                         , O(660F00,73,3,_,_,_,_,_  ), 0 , 0 , 8342, 219, 4  , 74),
+     788             :   INST(Psrlq           , ExtRmRi_P          , O(000F00,D3,_,_,_,_,_,_  ), O(000F00,73,2,_,_,_,_,_  ), 0 , 0 , 8350, 220, 78 , 74),
+     789             :   INST(Psrlw           , ExtRmRi_P          , O(000F00,D1,_,_,_,_,_,_  ), O(000F00,71,2,_,_,_,_,_  ), 0 , 0 , 8381, 221, 78 , 75),
+     790             :   INST(Psubb           , ExtRm_P            , O(000F00,F8,_,_,_,_,_,_  ), 0                         , 0 , 0 , 8388, 190, 78 , 75),
+     791             :   INST(Psubd           , ExtRm_P            , O(000F00,FA,_,_,_,_,_,_  ), 0                         , 0 , 0 , 8395, 190, 78 , 75),
+     792             :   INST(Psubq           , ExtRm_P            , O(000F00,FB,_,_,_,_,_,_  ), 0                         , 0 , 0 , 8402, 190, 4  , 75),
+     793             :   INST(Psubsb          , ExtRm_P            , O(000F00,E8,_,_,_,_,_,_  ), 0                         , 0 , 0 , 8409, 190, 78 , 75),
+     794             :   INST(Psubsw          , ExtRm_P            , O(000F00,E9,_,_,_,_,_,_  ), 0                         , 0 , 0 , 8417, 190, 78 , 75),
+     795             :   INST(Psubusb         , ExtRm_P            , O(000F00,D8,_,_,_,_,_,_  ), 0                         , 0 , 0 , 8425, 190, 78 , 75),
+     796             :   INST(Psubusw         , ExtRm_P            , O(000F00,D9,_,_,_,_,_,_  ), 0                         , 0 , 0 , 8434, 190, 78 , 75),
+     797             :   INST(Psubw           , ExtRm_P            , O(000F00,F9,_,_,_,_,_,_  ), 0                         , 0 , 0 , 8443, 190, 78 , 75),
+     798             :   INST(Pswapd          , Ext3dNow           , O(000F0F,BB,_,_,_,_,_,_  ), 0                         , 0 , 8 , 2231, 200, 89 , 0 ),
+     799             :   INST(Ptest           , ExtRm              , O(660F38,17,_,_,_,_,_,_  ), 0                         , 0 , 0 , 8472, 222, 96 , 76),
+     800             :   INST(Punpckhbw       , ExtRm_P            , O(000F00,68,_,_,_,_,_,_  ), 0                         , 0 , 0 , 8555, 187, 78 , 77),
+     801             :   INST(Punpckhdq       , ExtRm_P            , O(000F00,6A,_,_,_,_,_,_  ), 0                         , 0 , 0 , 8566, 187, 78 , 77),
+     802             :   INST(Punpckhqdq      , ExtRm              , O(660F00,6D,_,_,_,_,_,_  ), 0                         , 0 , 0 , 8577, 5  , 4  , 77),
+     803             :   INST(Punpckhwd       , ExtRm_P            , O(000F00,69,_,_,_,_,_,_  ), 0                         , 0 , 0 , 8589, 187, 78 , 77),
+     804             :   INST(Punpcklbw       , ExtRm_P            , O(000F00,60,_,_,_,_,_,_  ), 0                         , 0 , 0 , 8600, 187, 78 , 77),
+     805             :   INST(Punpckldq       , ExtRm_P            , O(000F00,62,_,_,_,_,_,_  ), 0                         , 0 , 0 , 8611, 187, 78 , 77),
+     806             :   INST(Punpcklqdq      , ExtRm              , O(660F00,6C,_,_,_,_,_,_  ), 0                         , 0 , 0 , 8622, 5  , 4  , 77),
+     807             :   INST(Punpcklwd       , ExtRm_P            , O(000F00,61,_,_,_,_,_,_  ), 0                         , 0 , 0 , 8634, 187, 78 , 77),
+     808             :   INST(Push            , X86Push            , O(000000,FF,6,_,_,_,_,_  ), O(000000,50,_,_,_,_,_,_  ), 0 , 0 , 2238, 223, 45 , 0 ),
+     809             :   INST(Pusha           , X86Op              , O(660000,60,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2243, 99 , 45 , 0 ),
+     810             :   INST(Pushad          , X86Op              , O(000000,60,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2249, 99 , 45 , 0 ),
+     811             :   INST(Pushf           , X86Op              , O(660000,9C,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2256, 34 , 45 , 0 ),
+     812             :   INST(Pushfd          , X86Op              , O(000000,9C,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2262, 99 , 45 , 0 ),
+     813             :   INST(Pushfq          , X86Op              , O(000000,9C,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2269, 101, 45 , 0 ),
+     814             :   INST(Pxor            , ExtRm_P            , O(000F00,EF,_,_,_,_,_,_  ), 0                         , 0 , 0 , 8645, 190, 78 , 78),
+     815             :   INST(Rcl             , X86Rot             , O(000000,D0,2,_,x,_,_,_  ), 0                         , 0 , 0 , 2276, 224, 97 , 0 ),
+     816             :   INST(Rcpps           , ExtRm              , O(000F00,53,_,_,_,_,_,_  ), 0                         , 0 , 16, 8773, 50 , 5  , 79),
+     817             :   INST(Rcpss           , ExtRm              , O(F30F00,53,_,_,_,_,_,_  ), 0                         , 0 , 4 , 8780, 225, 5  , 80),
+     818             :   INST(Rcr             , X86Rot             , O(000000,D0,3,_,x,_,_,_  ), 0                         , 0 , 0 , 2280, 224, 97 , 0 ),
+     819             :   INST(Rdfsbase        , X86M               , O(F30F00,AE,0,_,x,_,_,_  ), 0                         , 0 , 8 , 2284, 226, 98 , 0 ),
+     820             :   INST(Rdgsbase        , X86M               , O(F30F00,AE,1,_,x,_,_,_  ), 0                         , 0 , 8 , 2293, 226, 98 , 0 ),
+     821             :   INST(Rdmsr           , X86Op              , O(000F00,32,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2302, 227, 99 , 0 ),
+     822             :   INST(Rdpmc           , X86Op              , O(000F00,33,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2308, 227, 23 , 0 ),
+     823             :   INST(Rdrand          , X86M               , O(000F00,C7,6,_,x,_,_,_  ), 0                         , 0 , 8 , 2314, 228, 100, 0 ),
+     824             :   INST(Rdseed          , X86M               , O(000F00,C7,7,_,x,_,_,_  ), 0                         , 0 , 8 , 2321, 228, 101, 0 ),
+     825             :   INST(Rdtsc           , X86Op              , O(000F00,31,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2328, 229, 102, 0 ),
+     826             :   INST(Rdtscp          , X86Op              , O(000F01,F9,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2334, 230, 103, 0 ),
+     827             :   INST(Ret             , X86Ret             , O(000000,C2,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2748, 231, 45 , 0 ),
+     828             :   INST(Rol             , X86Rot             , O(000000,D0,0,_,x,_,_,_  ), 0                         , 0 , 0 , 2341, 224, 97 , 0 ),
+     829             :   INST(Ror             , X86Rot             , O(000000,D0,1,_,x,_,_,_  ), 0                         , 0 , 0 , 2345, 224, 97 , 0 ),
+     830             :   INST(Rorx            , VexRmi_Wx          , V(F20F3A,F0,_,0,x,_,_,_  ), 0                         , 0 , 0 , 2349, 232, 81 , 0 ),
+     831             :   INST(Roundpd         , ExtRmi             , O(660F3A,09,_,_,_,_,_,_  ), 0                         , 0 , 16, 8875, 210, 12 , 81),
+     832             :   INST(Roundps         , ExtRmi             , O(660F3A,08,_,_,_,_,_,_  ), 0                         , 0 , 16, 8884, 210, 12 , 81),
+     833             :   INST(Roundsd         , ExtRmi             , O(660F3A,0B,_,_,_,_,_,_  ), 0                         , 0 , 8 , 8893, 233, 12 , 82),
+     834             :   INST(Roundss         , ExtRmi             , O(660F3A,0A,_,_,_,_,_,_  ), 0                         , 0 , 4 , 8902, 234, 12 , 82),
+     835             :   INST(Rsm             , X86Op              , O(000F00,AA,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2354, 99 , 16 , 0 ),
+     836             :   INST(Rsqrtps         , ExtRm              , O(000F00,52,_,_,_,_,_,_  ), 0                         , 0 , 16, 8999, 50 , 5  , 3 ),
+     837             :   INST(Rsqrtss         , ExtRm              , O(F30F00,52,_,_,_,_,_,_  ), 0                         , 0 , 4 , 9008, 225, 5  , 2 ),
+     838             :   INST(Sahf            , X86Op              , O(000000,9E,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2358, 235, 104, 0 ),
+     839             :   INST(Sal             , X86Rot             , O(000000,D0,4,_,x,_,_,_  ), 0                         , 0 , 0 , 2363, 224, 1  , 0 ),
+     840             :   INST(Sar             , X86Rot             , O(000000,D0,7,_,x,_,_,_  ), 0                         , 0 , 0 , 2367, 224, 1  , 0 ),
+     841             :   INST(Sarx            , VexRmv_Wx          , V(F30F38,F7,_,0,x,_,_,_  ), 0                         , 0 , 0 , 2371, 14 , 81 , 0 ),
+     842             :   INST(Sbb             , X86Arith           , O(000000,18,3,_,x,_,_,_  ), 0                         , 0 , 0 , 2376, 3  , 2  , 0 ),
+     843             :   INST(Scas            , X86StrRm           , O(000000,AE,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2380, 236, 35 , 0 ),
+     844             :   INST(Seta            , X86Set             , O(000F00,97,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2385, 237, 105, 0 ),
+     845             :   INST(Setae           , X86Set             , O(000F00,93,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2390, 237, 106, 0 ),
+     846             :   INST(Setb            , X86Set             , O(000F00,92,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2396, 237, 106, 0 ),
+     847             :   INST(Setbe           , X86Set             , O(000F00,96,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2401, 237, 105, 0 ),
+     848             :   INST(Setc            , X86Set             , O(000F00,92,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2407, 237, 106, 0 ),
+     849             :   INST(Sete            , X86Set             , O(000F00,94,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2412, 237, 107, 0 ),
+     850             :   INST(Setg            , X86Set             , O(000F00,9F,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2417, 237, 108, 0 ),
+     851             :   INST(Setge           , X86Set             , O(000F00,9D,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2422, 237, 109, 0 ),
+     852             :   INST(Setl            , X86Set             , O(000F00,9C,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2428, 237, 109, 0 ),
+     853             :   INST(Setle           , X86Set             , O(000F00,9E,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2433, 237, 108, 0 ),
+     854             :   INST(Setna           , X86Set             , O(000F00,96,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2439, 237, 105, 0 ),
+     855             :   INST(Setnae          , X86Set             , O(000F00,92,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2445, 237, 106, 0 ),
+     856             :   INST(Setnb           , X86Set             , O(000F00,93,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2452, 237, 106, 0 ),
+     857             :   INST(Setnbe          , X86Set             , O(000F00,97,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2458, 237, 105, 0 ),
+     858             :   INST(Setnc           , X86Set             , O(000F00,93,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2465, 237, 106, 0 ),
+     859             :   INST(Setne           , X86Set             , O(000F00,95,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2471, 237, 107, 0 ),
+     860             :   INST(Setng           , X86Set             , O(000F00,9E,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2477, 237, 108, 0 ),
+     861             :   INST(Setnge          , X86Set             , O(000F00,9C,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2483, 237, 109, 0 ),
+     862             :   INST(Setnl           , X86Set             , O(000F00,9D,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2490, 237, 109, 0 ),
+     863             :   INST(Setnle          , X86Set             , O(000F00,9F,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2496, 237, 108, 0 ),
+     864             :   INST(Setno           , X86Set             , O(000F00,91,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2503, 237, 110, 0 ),
+     865             :   INST(Setnp           , X86Set             , O(000F00,9B,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2509, 237, 111, 0 ),
+     866             :   INST(Setns           , X86Set             , O(000F00,99,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2515, 237, 112, 0 ),
+     867             :   INST(Setnz           , X86Set             , O(000F00,95,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2521, 237, 107, 0 ),
+     868             :   INST(Seto            , X86Set             , O(000F00,90,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2527, 237, 110, 0 ),
+     869             :   INST(Setp            , X86Set             , O(000F00,9A,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2532, 237, 111, 0 ),
+     870             :   INST(Setpe           , X86Set             , O(000F00,9A,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2537, 237, 111, 0 ),
+     871             :   INST(Setpo           , X86Set             , O(000F00,9B,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2543, 237, 111, 0 ),
+     872             :   INST(Sets            , X86Set             , O(000F00,98,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2549, 237, 112, 0 ),
+     873             :   INST(Setz            , X86Set             , O(000F00,94,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2554, 237, 107, 0 ),
+     874             :   INST(Sfence          , X86Fence           , O(000F00,AE,7,_,_,_,_,_  ), 0                         , 0 , 0 , 2559, 34 , 113, 0 ),
+     875             :   INST(Sgdt            , X86M_Only          , O(000F00,01,0,_,_,_,_,_  ), 0                         , 0 , 0 , 2566, 84 , 45 , 0 ),
+     876             :   INST(Sha1msg1        , ExtRm              , O(000F38,C9,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2571, 5  , 114, 0 ),
+     877             :   INST(Sha1msg2        , ExtRm              , O(000F38,CA,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2580, 5  , 114, 0 ),
+     878             :   INST(Sha1nexte       , ExtRm              , O(000F38,C8,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2589, 5  , 114, 0 ),
+     879             :   INST(Sha1rnds4       , ExtRmi             , O(000F3A,CC,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2599, 16 , 114, 0 ),
+     880             :   INST(Sha256msg1      , ExtRm              , O(000F38,CC,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2609, 5  , 114, 0 ),
+     881             :   INST(Sha256msg2      , ExtRm              , O(000F38,CD,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2620, 5  , 114, 0 ),
+     882             :   INST(Sha256rnds2     , ExtRm_XMM0         , O(000F38,CB,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2631, 17 , 114, 0 ),
+     883             :   INST(Shl             , X86Rot             , O(000000,D0,4,_,x,_,_,_  ), 0                         , 0 , 0 , 2643, 224, 1  , 0 ),
+     884             :   INST(Shld            , X86ShldShrd        , O(000F00,A4,_,_,x,_,_,_  ), 0                         , 0 , 0 , 8159, 238, 1  , 0 ),
+     885             :   INST(Shlx            , VexRmv_Wx          , V(660F38,F7,_,0,x,_,_,_  ), 0                         , 0 , 0 , 2647, 14 , 81 , 0 ),
+     886             :   INST(Shr             , X86Rot             , O(000000,D0,5,_,x,_,_,_  ), 0                         , 0 , 0 , 2652, 224, 1  , 0 ),
+     887             :   INST(Shrd            , X86ShldShrd        , O(000F00,AC,_,_,x,_,_,_  ), 0                         , 0 , 0 , 2656, 238, 1  , 0 ),
+     888             :   INST(Shrx            , VexRmv_Wx          , V(F20F38,F7,_,0,x,_,_,_  ), 0                         , 0 , 0 , 2661, 14 , 81 , 0 ),
+     889             :   INST(Shufpd          , ExtRmi             , O(660F00,C6,_,_,_,_,_,_  ), 0                         , 0 , 0 , 9269, 16 , 4  , 83),
+     890             :   INST(Shufps          , ExtRmi             , O(000F00,C6,_,_,_,_,_,_  ), 0                         , 0 , 0 , 9277, 16 , 5  , 83),
+     891             :   INST(Sidt            , X86M_Only          , O(000F00,01,1,_,_,_,_,_  ), 0                         , 0 , 0 , 2666, 84 , 45 , 0 ),
+     892             :   INST(Sldt            , X86M               , O(000F00,00,0,_,_,_,_,_  ), 0                         , 0 , 0 , 2671, 239, 45 , 0 ),
+     893             :   INST(Smsw            , X86M               , O(000F00,01,4,_,_,_,_,_  ), 0                         , 0 , 0 , 2676, 239, 45 , 0 ),
+     894             :   INST(Sqrtpd          , ExtRm              , O(660F00,51,_,_,_,_,_,_  ), 0                         , 0 , 16, 9285, 50 , 4  , 84),
+     895             :   INST(Sqrtps          , ExtRm              , O(000F00,51,_,_,_,_,_,_  ), 0                         , 0 , 16, 9000, 50 , 5  , 84),
+     896             :   INST(Sqrtsd          , ExtRm              , O(F20F00,51,_,_,_,_,_,_  ), 0                         , 0 , 8 , 9301, 240, 4  , 85),
+     897             :   INST(Sqrtss          , ExtRm              , O(F30F00,51,_,_,_,_,_,_  ), 0                         , 0 , 4 , 9009, 225, 5  , 85),
+     898             :   INST(Stac            , X86Op              , O(000F01,CB,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2681, 34 , 17 , 0 ),
+     899             :   INST(Stc             , X86Op              , O(000000,F9,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2686, 34 , 18 , 0 ),
+     900             :   INST(Std             , X86Op              , O(000000,FD,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6242, 34 , 19 , 0 ),
+     901             :   INST(Sti             , X86Op              , O(000000,FB,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2690, 34 , 22 , 0 ),
+     902             :   INST(Stmxcsr         , X86M_Only          , O(000F00,AE,3,_,_,_,_,_  ), 0                         , 0 , 0 , 9317, 241, 5  , 0 ),
+     903             :   INST(Stos            , X86StrMr           , O(000000,AA,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2694, 242, 72 , 0 ),
+     904             :   INST(Str             , X86M               , O(000F00,00,1,_,_,_,_,_  ), 0                         , 0 , 0 , 2699, 239, 45 , 0 ),
+     905             :   INST(Sub             , X86Arith           , O(000000,28,5,_,x,_,_,_  ), 0                         , 0 , 0 , 807 , 243, 1  , 0 ),
+     906             :   INST(Subpd           , ExtRm              , O(660F00,5C,_,_,_,_,_,_  ), 0                         , 0 , 0 , 4361, 5  , 4  , 86),
+     907             :   INST(Subps           , ExtRm              , O(000F00,5C,_,_,_,_,_,_  ), 0                         , 0 , 0 , 4373, 5  , 5  , 86),
+     908             :   INST(Subsd           , ExtRm              , O(F20F00,5C,_,_,_,_,_,_  ), 0                         , 0 , 0 , 5049, 6  , 4  , 86),
+     909             :   INST(Subss           , ExtRm              , O(F30F00,5C,_,_,_,_,_,_  ), 0                         , 0 , 0 , 5059, 7  , 5  , 86),
+     910             :   INST(Swapgs          , X86Op              , O(000F01,F8,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2703, 101, 23 , 0 ),
+     911             :   INST(Syscall         , X86Op              , O(000F00,05,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2710, 101, 45 , 0 ),
+     912             :   INST(Sysenter        , X86Op              , O(000F00,34,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2718, 34 , 45 , 0 ),
+     913             :   INST(Sysexit         , X86Op              , O(000F00,35,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2727, 34 , 23 , 0 ),
+     914             :   INST(Sysexit64       , X86Op              , O(000F00,35,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2735, 34 , 23 , 0 ),
+     915             :   INST(Sysret          , X86Op              , O(000F00,07,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2745, 101, 23 , 0 ),
+     916             :   INST(Sysret64        , X86Op              , O(000F00,07,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2752, 101, 23 , 0 ),
+     917             :   INST(T1mskc          , VexVm_Wx           , V(XOP_M9,01,7,0,x,_,_,_  ), 0                         , 0 , 0 , 2761, 15 , 11 , 0 ),
+     918             :   INST(Test            , X86Test            , O(000000,84,_,_,x,_,_,_  ), O(000000,F6,_,_,x,_,_,_  ), 0 , 0 , 8473, 244, 1  , 0 ),
+     919             :   INST(Tzcnt           , X86Rm_Raw66H       , O(F30F00,BC,_,_,x,_,_,_  ), 0                         , 0 , 0 , 2768, 143, 9  , 0 ),
+     920             :   INST(Tzmsk           , VexVm_Wx           , V(XOP_M9,01,4,0,x,_,_,_  ), 0                         , 0 , 0 , 2774, 15 , 11 , 0 ),
+     921             :   INST(Ucomisd         , ExtRm              , O(660F00,2E,_,_,_,_,_,_  ), 0                         , 0 , 0 , 9370, 44 , 39 , 15),
+     922             :   INST(Ucomiss         , ExtRm              , O(000F00,2E,_,_,_,_,_,_  ), 0                         , 0 , 0 , 9379, 45 , 40 , 15),
+     923             :   INST(Ud2             , X86Op              , O(000F00,0B,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2780, 34 , 0  , 0 ),
+     924             :   INST(Unpckhpd        , ExtRm              , O(660F00,15,_,_,_,_,_,_  ), 0                         , 0 , 0 , 9388, 5  , 4  , 13),
+     925             :   INST(Unpckhps        , ExtRm              , O(000F00,15,_,_,_,_,_,_  ), 0                         , 0 , 0 , 9398, 5  , 5  , 13),
+     926             :   INST(Unpcklpd        , ExtRm              , O(660F00,14,_,_,_,_,_,_  ), 0                         , 0 , 0 , 9408, 5  , 4  , 13),
+     927             :   INST(Unpcklps        , ExtRm              , O(000F00,14,_,_,_,_,_,_  ), 0                         , 0 , 0 , 9418, 5  , 5  , 13),
+     928             :   INST(V4fmaddps       , VexRm_T1_4X        , V(F20F38,9A,_,2,_,0,2,T4X), 0                         , 0 , 0 , 2784, 245, 115, 0 ),
+     929             :   INST(V4fnmaddps      , VexRm_T1_4X        , V(F20F38,AA,_,2,_,0,2,T4X), 0                         , 0 , 0 , 2794, 245, 115, 0 ),
+     930             :   INST(Vaddpd          , VexRvm_Lx          , V(660F00,58,_,x,I,1,4,FV ), 0                         , 0 , 0 , 2805, 246, 116, 1 ),
+     931             :   INST(Vaddps          , VexRvm_Lx          , V(000F00,58,_,x,I,0,4,FV ), 0                         , 0 , 0 , 2812, 247, 116, 1 ),
+     932             :   INST(Vaddsd          , VexRvm             , V(F20F00,58,_,I,I,1,3,T1S), 0                         , 0 , 0 , 2819, 248, 117, 1 ),
+     933             :   INST(Vaddss          , VexRvm             , V(F30F00,58,_,I,I,0,2,T1S), 0                         , 0 , 0 , 2826, 249, 117, 1 ),
+     934             :   INST(Vaddsubpd       , VexRvm_Lx          , V(660F00,D0,_,x,I,_,_,_  ), 0                         , 0 , 0 , 2833, 250, 118, 1 ),
+     935             :   INST(Vaddsubps       , VexRvm_Lx          , V(F20F00,D0,_,x,I,_,_,_  ), 0                         , 0 , 0 , 2843, 250, 118, 1 ),
+     936             :   INST(Vaesdec         , VexRvm             , V(660F38,DE,_,0,I,_,_,_  ), 0                         , 0 , 0 , 2853, 251, 119, 2 ),
+     937             :   INST(Vaesdeclast     , VexRvm             , V(660F38,DF,_,0,I,_,_,_  ), 0                         , 0 , 0 , 2861, 251, 119, 2 ),
+     938             :   INST(Vaesenc         , VexRvm             , V(660F38,DC,_,0,I,_,_,_  ), 0                         , 0 , 0 , 2873, 251, 119, 2 ),
+     939             :   INST(Vaesenclast     , VexRvm             , V(660F38,DD,_,0,I,_,_,_  ), 0                         , 0 , 0 , 2881, 251, 119, 2 ),
+     940             :   INST(Vaesimc         , VexRm              , V(660F38,DB,_,0,I,_,_,_  ), 0                         , 0 , 0 , 2893, 252, 119, 3 ),
+     941             :   INST(Vaeskeygenassist, VexRmi             , V(660F3A,DF,_,0,I,_,_,_  ), 0                         , 0 , 0 , 2901, 253, 119, 3 ),
+     942             :   INST(Valignd         , VexRvmi_Lx         , V(660F3A,03,_,x,_,0,4,FV ), 0                         , 0 , 0 , 2918, 254, 120, 0 ),
+     943             :   INST(Valignq         , VexRvmi_Lx         , V(660F3A,03,_,x,_,1,4,FV ), 0                         , 0 , 0 , 2926, 255, 120, 0 ),
+     944             :   INST(Vandnpd         , VexRvm_Lx          , V(660F00,55,_,x,I,1,4,FV ), 0                         , 0 , 0 , 2934, 256, 121, 2 ),
+     945             :   INST(Vandnps         , VexRvm_Lx          , V(000F00,55,_,x,I,0,4,FV ), 0                         , 0 , 0 , 2942, 257, 121, 2 ),
+     946             :   INST(Vandpd          , VexRvm_Lx          , V(660F00,54,_,x,I,1,4,FV ), 0                         , 0 , 0 , 2950, 258, 121, 2 ),
+     947             :   INST(Vandps          , VexRvm_Lx          , V(000F00,54,_,x,I,0,4,FV ), 0                         , 0 , 0 , 2957, 259, 121, 2 ),
+     948             :   INST(Vblendmb        , VexRvm_Lx          , V(660F38,66,_,x,_,0,4,FVM), 0                         , 0 , 0 , 2964, 260, 122, 0 ),
+     949             :   INST(Vblendmd        , VexRvm_Lx          , V(660F38,64,_,x,_,0,4,FV ), 0                         , 0 , 0 , 2973, 261, 120, 0 ),
+     950             :   INST(Vblendmpd       , VexRvm_Lx          , V(660F38,65,_,x,_,1,4,FV ), 0                         , 0 , 0 , 2982, 262, 120, 0 ),
+     951             :   INST(Vblendmps       , VexRvm_Lx          , V(660F38,65,_,x,_,0,4,FV ), 0                         , 0 , 0 , 2992, 261, 120, 0 ),
+     952             :   INST(Vblendmq        , VexRvm_Lx          , V(660F38,64,_,x,_,1,4,FV ), 0                         , 0 , 0 , 3002, 262, 120, 0 ),
+     953             :   INST(Vblendmw        , VexRvm_Lx          , V(660F38,66,_,x,_,1,4,FVM), 0                         , 0 , 0 , 3011, 260, 122, 0 ),
+     954             :   INST(Vblendpd        , VexRvmi_Lx         , V(660F3A,0D,_,x,I,_,_,_  ), 0                         , 0 , 0 , 3020, 263, 118, 4 ),
+     955             :   INST(Vblendps        , VexRvmi_Lx         , V(660F3A,0C,_,x,I,_,_,_  ), 0                         , 0 , 0 , 3029, 263, 118, 4 ),
+     956             :   INST(Vblendvpd       , VexRvmr_Lx         , V(660F3A,4B,_,x,0,_,_,_  ), 0                         , 0 , 0 , 3038, 264, 118, 5 ),
+     957             :   INST(Vblendvps       , VexRvmr_Lx         , V(660F3A,4A,_,x,0,_,_,_  ), 0                         , 0 , 0 , 3048, 264, 118, 5 ),
+     958             :   INST(Vbroadcastf128  , VexRm              , V(660F38,1A,_,1,0,_,_,_  ), 0                         , 0 , 0 , 3058, 265, 118, 0 ),
+     959             :   INST(Vbroadcastf32x2 , VexRm_Lx           , V(660F38,19,_,x,_,0,3,T2 ), 0                         , 0 , 0 , 3073, 266, 123, 0 ),
+     960             :   INST(Vbroadcastf32x4 , VexRm_Lx           , V(660F38,1A,_,x,_,0,4,T4 ), 0                         , 0 , 0 , 3089, 267, 65 , 0 ),
+     961             :   INST(Vbroadcastf32x8 , VexRm              , V(660F38,1B,_,2,_,0,5,T8 ), 0                         , 0 , 0 , 3105, 268, 63 , 0 ),
+     962             :   INST(Vbroadcastf64x2 , VexRm_Lx           , V(660F38,1A,_,x,_,1,4,T2 ), 0                         , 0 , 0 , 3121, 267, 123, 0 ),
+     963             :   INST(Vbroadcastf64x4 , VexRm              , V(660F38,1B,_,2,_,1,5,T4 ), 0                         , 0 , 0 , 3137, 268, 65 , 0 ),
+     964             :   INST(Vbroadcasti128  , VexRm              , V(660F38,5A,_,1,0,_,_,_  ), 0                         , 0 , 0 , 3153, 265, 124, 0 ),
+     965             :   INST(Vbroadcasti32x2 , VexRm_Lx           , V(660F38,59,_,x,_,0,3,T2 ), 0                         , 0 , 0 , 3168, 269, 123, 0 ),
+     966             :   INST(Vbroadcasti32x4 , VexRm_Lx           , V(660F38,5A,_,x,_,0,4,T4 ), 0                         , 0 , 0 , 3184, 266, 120, 0 ),
+     967             :   INST(Vbroadcasti32x8 , VexRm              , V(660F38,5B,_,2,_,0,5,T8 ), 0                         , 0 , 0 , 3200, 270, 63 , 0 ),
+     968             :   INST(Vbroadcasti64x2 , VexRm_Lx           , V(660F38,5A,_,x,_,1,4,T2 ), 0                         , 0 , 0 , 3216, 266, 123, 0 ),
+     969             :   INST(Vbroadcasti64x4 , VexRm              , V(660F38,5B,_,2,_,1,5,T4 ), 0                         , 0 , 0 , 3232, 270, 65 , 0 ),
+     970             :   INST(Vbroadcastsd    , VexRm_Lx           , V(660F38,19,_,x,0,1,3,T1S), 0                         , 0 , 0 , 3248, 271, 125, 0 ),
+     971             :   INST(Vbroadcastss    , VexRm_Lx           , V(660F38,18,_,x,0,0,2,T1S), 0                         , 0 , 0 , 3261, 272, 125, 0 ),
+     972             :   INST(Vcmppd          , VexRvmi_Lx         , V(660F00,C2,_,x,I,1,4,FV ), 0                         , 0 , 0 , 3274, 273, 116, 6 ),
+     973             :   INST(Vcmpps          , VexRvmi_Lx         , V(000F00,C2,_,x,I,0,4,FV ), 0                         , 0 , 0 , 3281, 274, 116, 6 ),
+     974             :   INST(Vcmpsd          , VexRvmi            , V(F20F00,C2,_,I,I,1,3,T1S), 0                         , 0 , 0 , 3288, 275, 117, 7 ),
+     975             :   INST(Vcmpss          , VexRvmi            , V(F30F00,C2,_,I,I,0,2,T1S), 0                         , 0 , 0 , 3295, 276, 117, 7 ),
+     976             :   INST(Vcomisd         , VexRm              , V(660F00,2F,_,I,I,1,3,T1S), 0                         , 0 , 0 , 3302, 277, 126, 8 ),
+     977             :   INST(Vcomiss         , VexRm              , V(000F00,2F,_,I,I,0,2,T1S), 0                         , 0 , 0 , 3310, 278, 126, 8 ),
+     978             :   INST(Vcompresspd     , VexMr_Lx           , V(660F38,8A,_,x,_,1,3,T1S), 0                         , 0 , 0 , 3318, 279, 120, 0 ),
+     979             :   INST(Vcompressps     , VexMr_Lx           , V(660F38,8A,_,x,_,0,2,T1S), 0                         , 0 , 0 , 3330, 279, 120, 0 ),
+     980             :   INST(Vcvtdq2pd       , VexRm_Lx           , V(F30F00,E6,_,x,I,0,3,HV ), 0                         , 0 , 0 , 3342, 280, 116, 9 ),
+     981             :   INST(Vcvtdq2ps       , VexRm_Lx           , V(000F00,5B,_,x,I,0,4,FV ), 0                         , 0 , 0 , 3352, 281, 116, 9 ),
+     982             :   INST(Vcvtpd2dq       , VexRm_Lx           , V(F20F00,E6,_,x,I,1,4,FV ), 0                         , 0 , 0 , 3362, 282, 116, 9 ),
+     983             :   INST(Vcvtpd2ps       , VexRm_Lx           , V(660F00,5A,_,x,I,1,4,FV ), 0                         , 0 , 0 , 3372, 283, 116, 10),
+     984             :   INST(Vcvtpd2qq       , VexRm_Lx           , V(660F00,7B,_,x,_,1,4,FV ), 0                         , 0 , 0 , 3382, 284, 123, 0 ),
+     985             :   INST(Vcvtpd2udq      , VexRm_Lx           , V(000F00,79,_,x,_,1,4,FV ), 0                         , 0 , 0 , 3392, 285, 120, 0 ),
+     986             :   INST(Vcvtpd2uqq      , VexRm_Lx           , V(660F00,79,_,x,_,1,4,FV ), 0                         , 0 , 0 , 3403, 284, 123, 0 ),
+     987             :   INST(Vcvtph2ps       , VexRm_Lx           , V(660F38,13,_,x,0,0,3,HVM), 0                         , 0 , 0 , 3414, 286, 127, 0 ),
+     988             :   INST(Vcvtps2dq       , VexRm_Lx           , V(660F00,5B,_,x,I,0,4,FV ), 0                         , 0 , 0 , 3424, 281, 116, 8 ),
+     989             :   INST(Vcvtps2pd       , VexRm_Lx           , V(000F00,5A,_,x,I,0,4,HV ), 0                         , 0 , 0 , 3434, 287, 116, 8 ),
+     990             :   INST(Vcvtps2ph       , VexMri_Lx          , V(660F3A,1D,_,x,0,0,3,HVM), 0                         , 0 , 0 , 3444, 288, 127, 0 ),
+     991             :   INST(Vcvtps2qq       , VexRm_Lx           , V(660F00,7B,_,x,_,0,3,HV ), 0                         , 0 , 0 , 3454, 289, 123, 0 ),
+     992             :   INST(Vcvtps2udq      , VexRm_Lx           , V(000F00,79,_,x,_,0,4,FV ), 0                         , 0 , 0 , 3464, 290, 120, 0 ),
+     993             :   INST(Vcvtps2uqq      , VexRm_Lx           , V(660F00,79,_,x,_,0,3,HV ), 0                         , 0 , 0 , 3475, 289, 123, 0 ),
+     994             :   INST(Vcvtqq2pd       , VexRm_Lx           , V(F30F00,E6,_,x,_,1,4,FV ), 0                         , 0 , 0 , 3486, 284, 123, 0 ),
+     995             :   INST(Vcvtqq2ps       , VexRm_Lx           , V(000F00,5B,_,x,_,1,4,FV ), 0                         , 0 , 0 , 3496, 285, 123, 0 ),
+     996             :   INST(Vcvtsd2si       , VexRm_Wx           , V(F20F00,2D,_,I,x,x,3,T1F), 0                         , 0 , 0 , 3506, 291, 117, 11),
+     997             :   INST(Vcvtsd2ss       , VexRvm             , V(F20F00,5A,_,I,I,1,3,T1S), 0                         , 0 , 0 , 3516, 248, 117, 12),
+     998             :   INST(Vcvtsd2usi      , VexRm_Wx           , V(F20F00,79,_,I,_,x,3,T1F), 0                         , 0 , 0 , 3526, 292, 65 , 0 ),
+     999             :   INST(Vcvtsi2sd       , VexRvm_Wx          , V(F20F00,2A,_,I,x,x,2,T1W), 0                         , 0 , 0 , 3537, 293, 117, 13),
+    1000             :   INST(Vcvtsi2ss       , VexRvm_Wx          , V(F30F00,2A,_,I,x,x,2,T1W), 0                         , 0 , 0 , 3547, 293, 117, 13),
+    1001             :   INST(Vcvtss2sd       , VexRvm             , V(F30F00,5A,_,I,I,0,2,T1S), 0                         , 0 , 0 , 3557, 294, 117, 13),
+    1002             :   INST(Vcvtss2si       , VexRm_Wx           , V(F30F00,2D,_,I,x,x,2,T1F), 0                         , 0 , 0 , 3567, 295, 117, 14),
+    1003             :   INST(Vcvtss2usi      , VexRm_Wx           , V(F30F00,79,_,I,_,x,2,T1F), 0                         , 0 , 0 , 3577, 296, 65 , 0 ),
+    1004             :   INST(Vcvttpd2dq      , VexRm_Lx           , V(660F00,E6,_,x,I,1,4,FV ), 0                         , 0 , 0 , 3588, 297, 116, 15),
+    1005             :   INST(Vcvttpd2qq      , VexRm_Lx           , V(660F00,7A,_,x,_,1,4,FV ), 0                         , 0 , 0 , 3599, 298, 120, 0 ),
+    1006             :   INST(Vcvttpd2udq     , VexRm_Lx           , V(000F00,78,_,x,_,1,4,FV ), 0                         , 0 , 0 , 3610, 299, 120, 0 ),
+    1007             :   INST(Vcvttpd2uqq     , VexRm_Lx           , V(660F00,78,_,x,_,1,4,FV ), 0                         , 0 , 0 , 3622, 298, 123, 0 ),
+    1008             :   INST(Vcvttps2dq      , VexRm_Lx           , V(F30F00,5B,_,x,I,0,4,FV ), 0                         , 0 , 0 , 3634, 300, 116, 16),
+    1009             :   INST(Vcvttps2qq      , VexRm_Lx           , V(660F00,7A,_,x,_,0,3,HV ), 0                         , 0 , 0 , 3645, 301, 123, 0 ),
+    1010             :   INST(Vcvttps2udq     , VexRm_Lx           , V(000F00,78,_,x,_,0,4,FV ), 0                         , 0 , 0 , 3656, 302, 120, 0 ),
+    1011             :   INST(Vcvttps2uqq     , VexRm_Lx           , V(660F00,78,_,x,_,0,3,HV ), 0                         , 0 , 0 , 3668, 301, 123, 0 ),
+    1012             :   INST(Vcvttsd2si      , VexRm_Wx           , V(F20F00,2C,_,I,x,x,3,T1F), 0                         , 0 , 0 , 3680, 303, 117, 17),
+    1013             :   INST(Vcvttsd2usi     , VexRm_Wx           , V(F20F00,78,_,I,_,x,3,T1F), 0                         , 0 , 0 , 3691, 304, 65 , 0 ),
+    1014             :   INST(Vcvttss2si      , VexRm_Wx           , V(F30F00,2C,_,I,x,x,2,T1F), 0                         , 0 , 0 , 3703, 305, 117, 18),
+    1015             :   INST(Vcvttss2usi     , VexRm_Wx           , V(F30F00,78,_,I,_,x,2,T1F), 0                         , 0 , 0 , 3714, 306, 65 , 0 ),
+    1016             :   INST(Vcvtudq2pd      , VexRm_Lx           , V(F30F00,7A,_,x,_,0,3,HV ), 0                         , 0 , 0 , 3726, 307, 120, 0 ),
+    1017             :   INST(Vcvtudq2ps      , VexRm_Lx           , V(F20F00,7A,_,x,_,0,4,FV ), 0                         , 0 , 0 , 3737, 290, 120, 0 ),
+    1018             :   INST(Vcvtuqq2pd      , VexRm_Lx           , V(F30F00,7A,_,x,_,1,4,FV ), 0                         , 0 , 0 , 3748, 284, 123, 0 ),
+    1019             :   INST(Vcvtuqq2ps      , VexRm_Lx           , V(F20F00,7A,_,x,_,1,4,FV ), 0                         , 0 , 0 , 3759, 285, 123, 0 ),
+    1020             :   INST(Vcvtusi2sd      , VexRvm_Wx          , V(F20F00,7B,_,I,_,x,2,T1W), 0                         , 0 , 0 , 3770, 308, 65 , 0 ),
+    1021             :   INST(Vcvtusi2ss      , VexRvm_Wx          , V(F30F00,7B,_,I,_,x,2,T1W), 0                         , 0 , 0 , 3781, 308, 65 , 0 ),
+    1022             :   INST(Vdbpsadbw       , VexRvmi_Lx         , V(660F3A,42,_,x,_,0,4,FVM), 0                         , 0 , 0 , 3792, 309, 122, 0 ),
+    1023             :   INST(Vdivpd          , VexRvm_Lx          , V(660F00,5E,_,x,I,1,4,FV ), 0                         , 0 , 0 , 3802, 246, 116, 19),
+    1024             :   INST(Vdivps          , VexRvm_Lx          , V(000F00,5E,_,x,I,0,4,FV ), 0                         , 0 , 0 , 3809, 247, 116, 19),
+    1025             :   INST(Vdivsd          , VexRvm             , V(F20F00,5E,_,I,I,1,3,T1S), 0                         , 0 , 0 , 3816, 248, 117, 19),
+    1026             :   INST(Vdivss          , VexRvm             , V(F30F00,5E,_,I,I,0,2,T1S), 0                         , 0 , 0 , 3823, 249, 117, 19),
+    1027             :   INST(Vdppd           , VexRvmi_Lx         , V(660F3A,41,_,x,I,_,_,_  ), 0                         , 0 , 0 , 3830, 310, 118, 19),
+    1028             :   INST(Vdpps           , VexRvmi_Lx         , V(660F3A,40,_,x,I,_,_,_  ), 0                         , 0 , 0 , 3836, 263, 118, 19),
+    1029             :   INST(Verr            , X86M               , O(000F00,00,4,_,_,_,_,_  ), 0                         , 0 , 0 , 3842, 137, 70 , 0 ),
+    1030             :   INST(Verw            , X86M               , O(000F00,00,5,_,_,_,_,_  ), 0                         , 0 , 0 , 3847, 137, 70 , 0 ),
+    1031             :   INST(Vexp2pd         , VexRm              , V(660F38,C8,_,2,_,1,4,FV ), 0                         , 0 , 0 , 3852, 311, 128, 0 ),
+    1032             :   INST(Vexp2ps         , VexRm              , V(660F38,C8,_,2,_,0,4,FV ), 0                         , 0 , 0 , 3860, 312, 128, 0 ),
+    1033             :   INST(Vexpandpd       , VexRm_Lx           , V(660F38,88,_,x,_,1,3,T1S), 0                         , 0 , 0 , 3868, 313, 120, 0 ),
+    1034             :   INST(Vexpandps       , VexRm_Lx           , V(660F38,88,_,x,_,0,2,T1S), 0                         , 0 , 0 , 3878, 313, 120, 0 ),
+    1035             :   INST(Vextractf128    , VexMri             , V(660F3A,19,_,1,0,_,_,_  ), 0                         , 0 , 0 , 3888, 314, 118, 0 ),
+    1036             :   INST(Vextractf32x4   , VexMri_Lx          , V(660F3A,19,_,x,_,0,4,T4 ), 0                         , 0 , 0 , 3901, 315, 120, 0 ),
+    1037             :   INST(Vextractf32x8   , VexMri             , V(660F3A,1B,_,2,_,0,5,T8 ), 0                         , 0 , 0 , 3915, 316, 63 , 0 ),
+    1038             :   INST(Vextractf64x2   , VexMri_Lx          , V(660F3A,19,_,x,_,1,4,T2 ), 0                         , 0 , 0 , 3929, 315, 123, 0 ),
+    1039             :   INST(Vextractf64x4   , VexMri             , V(660F3A,1B,_,2,_,1,5,T4 ), 0                         , 0 , 0 , 3943, 316, 65 , 0 ),
+    1040             :   INST(Vextracti128    , VexMri             , V(660F3A,39,_,1,0,_,_,_  ), 0                         , 0 , 0 , 3957, 314, 124, 0 ),
+    1041             :   INST(Vextracti32x4   , VexMri_Lx          , V(660F3A,39,_,x,_,0,4,T4 ), 0                         , 0 , 0 , 3970, 315, 120, 0 ),
+    1042             :   INST(Vextracti32x8   , VexMri             , V(660F3A,3B,_,2,_,0,5,T8 ), 0                         , 0 , 0 , 3984, 316, 63 , 0 ),
+    1043             :   INST(Vextracti64x2   , VexMri_Lx          , V(660F3A,39,_,x,_,1,4,T2 ), 0                         , 0 , 0 , 3998, 315, 123, 0 ),
+    1044             :   INST(Vextracti64x4   , VexMri             , V(660F3A,3B,_,2,_,1,5,T4 ), 0                         , 0 , 0 , 4012, 316, 65 , 0 ),
+    1045             :   INST(Vextractps      , VexMri             , V(660F3A,17,_,0,I,I,2,T1S), 0                         , 0 , 0 , 4026, 317, 117, 20),
+    1046             :   INST(Vfixupimmpd     , VexRvmi_Lx         , V(660F3A,54,_,x,_,1,4,FV ), 0                         , 0 , 0 , 4037, 318, 120, 0 ),
+    1047             :   INST(Vfixupimmps     , VexRvmi_Lx         , V(660F3A,54,_,x,_,0,4,FV ), 0                         , 0 , 0 , 4049, 319, 120, 0 ),
+    1048             :   INST(Vfixupimmsd     , VexRvmi            , V(660F3A,55,_,I,_,1,3,T1S), 0                         , 0 , 0 , 4061, 320, 65 , 0 ),
+    1049             :   INST(Vfixupimmss     , VexRvmi            , V(660F3A,55,_,I,_,0,2,T1S), 0                         , 0 , 0 , 4073, 321, 65 , 0 ),
+    1050             :   INST(Vfmadd132pd     , VexRvm_Lx          , V(660F38,98,_,x,1,1,4,FV ), 0                         , 0 , 0 , 4085, 322, 129, 0 ),
+    1051             :   INST(Vfmadd132ps     , VexRvm_Lx          , V(660F38,98,_,x,0,0,4,FV ), 0                         , 0 , 0 , 4097, 323, 129, 0 ),
+    1052             :   INST(Vfmadd132sd     , VexRvm             , V(660F38,99,_,I,1,1,3,T1S), 0                         , 0 , 0 , 4109, 324, 130, 0 ),
+    1053             :   INST(Vfmadd132ss     , VexRvm             , V(660F38,99,_,I,0,0,2,T1S), 0                         , 0 , 0 , 4121, 325, 130, 0 ),
+    1054             :   INST(Vfmadd213pd     , VexRvm_Lx          , V(660F38,A8,_,x,1,1,4,FV ), 0                         , 0 , 0 , 4133, 322, 129, 0 ),
+    1055             :   INST(Vfmadd213ps     , VexRvm_Lx          , V(660F38,A8,_,x,0,0,4,FV ), 0                         , 0 , 0 , 4145, 323, 129, 0 ),
+    1056             :   INST(Vfmadd213sd     , VexRvm             , V(660F38,A9,_,I,1,1,3,T1S), 0                         , 0 , 0 , 4157, 324, 130, 0 ),
+    1057             :   INST(Vfmadd213ss     , VexRvm             , V(660F38,A9,_,I,0,0,2,T1S), 0                         , 0 , 0 , 4169, 325, 130, 0 ),
+    1058             :   INST(Vfmadd231pd     , VexRvm_Lx          , V(660F38,B8,_,x,1,1,4,FV ), 0                         , 0 , 0 , 4181, 322, 129, 0 ),
+    1059             :   INST(Vfmadd231ps     , VexRvm_Lx          , V(660F38,B8,_,x,0,0,4,FV ), 0                         , 0 , 0 , 4193, 323, 129, 0 ),
+    1060             :   INST(Vfmadd231sd     , VexRvm             , V(660F38,B9,_,I,1,1,3,T1S), 0                         , 0 , 0 , 4205, 324, 130, 0 ),
+    1061             :   INST(Vfmadd231ss     , VexRvm             , V(660F38,B9,_,I,0,0,2,T1S), 0                         , 0 , 0 , 4217, 325, 130, 0 ),
+    1062             :   INST(Vfmaddpd        , Fma4_Lx            , V(660F3A,69,_,x,x,_,_,_  ), 0                         , 0 , 0 , 4229, 326, 131, 0 ),
+    1063             :   INST(Vfmaddps        , Fma4_Lx            , V(660F3A,68,_,x,x,_,_,_  ), 0                         , 0 , 0 , 4238, 326, 131, 0 ),
+    1064             :   INST(Vfmaddsd        , Fma4               , V(660F3A,6B,_,0,x,_,_,_  ), 0                         , 0 , 0 , 4247, 327, 131, 0 ),
+    1065             :   INST(Vfmaddss        , Fma4               , V(660F3A,6A,_,0,x,_,_,_  ), 0                         , 0 , 0 , 4256, 328, 131, 0 ),
+    1066             :   INST(Vfmaddsub132pd  , VexRvm_Lx          , V(660F38,96,_,x,1,1,4,FV ), 0                         , 0 , 0 , 4265, 322, 129, 0 ),
+    1067             :   INST(Vfmaddsub132ps  , VexRvm_Lx          , V(660F38,96,_,x,0,0,4,FV ), 0                         , 0 , 0 , 4280, 323, 129, 0 ),
+    1068             :   INST(Vfmaddsub213pd  , VexRvm_Lx          , V(660F38,A6,_,x,1,1,4,FV ), 0                         , 0 , 0 , 4295, 322, 129, 0 ),
+    1069             :   INST(Vfmaddsub213ps  , VexRvm_Lx          , V(660F38,A6,_,x,0,0,4,FV ), 0                         , 0 , 0 , 4310, 323, 129, 0 ),
+    1070             :   INST(Vfmaddsub231pd  , VexRvm_Lx          , V(660F38,B6,_,x,1,1,4,FV ), 0                         , 0 , 0 , 4325, 322, 129, 0 ),
+    1071             :   INST(Vfmaddsub231ps  , VexRvm_Lx          , V(660F38,B6,_,x,0,0,4,FV ), 0                         , 0 , 0 , 4340, 323, 129, 0 ),
+    1072             :   INST(Vfmaddsubpd     , Fma4_Lx            , V(660F3A,5D,_,x,x,_,_,_  ), 0                         , 0 , 0 , 4355, 326, 131, 0 ),
+    1073             :   INST(Vfmaddsubps     , Fma4_Lx            , V(660F3A,5C,_,x,x,_,_,_  ), 0                         , 0 , 0 , 4367, 326, 131, 0 ),
+    1074             :   INST(Vfmsub132pd     , VexRvm_Lx          , V(660F38,9A,_,x,1,1,4,FV ), 0                         , 0 , 0 , 4379, 322, 129, 0 ),
+    1075             :   INST(Vfmsub132ps     , VexRvm_Lx          , V(660F38,9A,_,x,0,0,4,FV ), 0                         , 0 , 0 , 4391, 323, 129, 0 ),
+    1076             :   INST(Vfmsub132sd     , VexRvm             , V(660F38,9B,_,I,1,1,3,T1S), 0                         , 0 , 0 , 4403, 324, 130, 0 ),
+    1077             :   INST(Vfmsub132ss     , VexRvm             , V(660F38,9B,_,I,0,0,2,T1S), 0                         , 0 , 0 , 4415, 325, 130, 0 ),
+    1078             :   INST(Vfmsub213pd     , VexRvm_Lx          , V(660F38,AA,_,x,1,1,4,FV ), 0                         , 0 , 0 , 4427, 322, 129, 0 ),
+    1079             :   INST(Vfmsub213ps     , VexRvm_Lx          , V(660F38,AA,_,x,0,0,4,FV ), 0                         , 0 , 0 , 4439, 323, 129, 0 ),
+    1080             :   INST(Vfmsub213sd     , VexRvm             , V(660F38,AB,_,I,1,1,3,T1S), 0                         , 0 , 0 , 4451, 324, 130, 0 ),
+    1081             :   INST(Vfmsub213ss     , VexRvm             , V(660F38,AB,_,I,0,0,2,T1S), 0                         , 0 , 0 , 4463, 325, 130, 0 ),
+    1082             :   INST(Vfmsub231pd     , VexRvm_Lx          , V(660F38,BA,_,x,1,1,4,FV ), 0                         , 0 , 0 , 4475, 322, 129, 0 ),
+    1083             :   INST(Vfmsub231ps     , VexRvm_Lx          , V(660F38,BA,_,x,0,0,4,FV ), 0                         , 0 , 0 , 4487, 323, 129, 0 ),
+    1084             :   INST(Vfmsub231sd     , VexRvm             , V(660F38,BB,_,I,1,1,3,T1S), 0                         , 0 , 0 , 4499, 324, 130, 0 ),
+    1085             :   INST(Vfmsub231ss     , VexRvm             , V(660F38,BB,_,I,0,0,2,T1S), 0                         , 0 , 0 , 4511, 325, 130, 0 ),
+    1086             :   INST(Vfmsubadd132pd  , VexRvm_Lx          , V(660F38,97,_,x,1,1,4,FV ), 0                         , 0 , 0 , 4523, 322, 129, 0 ),
+    1087             :   INST(Vfmsubadd132ps  , VexRvm_Lx          , V(660F38,97,_,x,0,0,4,FV ), 0                         , 0 , 0 , 4538, 323, 129, 0 ),
+    1088             :   INST(Vfmsubadd213pd  , VexRvm_Lx          , V(660F38,A7,_,x,1,1,4,FV ), 0                         , 0 , 0 , 4553, 322, 129, 0 ),
+    1089             :   INST(Vfmsubadd213ps  , VexRvm_Lx          , V(660F38,A7,_,x,0,0,4,FV ), 0                         , 0 , 0 , 4568, 323, 129, 0 ),
+    1090             :   INST(Vfmsubadd231pd  , VexRvm_Lx          , V(660F38,B7,_,x,1,1,4,FV ), 0                         , 0 , 0 , 4583, 322, 129, 0 ),
+    1091             :   INST(Vfmsubadd231ps  , VexRvm_Lx          , V(660F38,B7,_,x,0,0,4,FV ), 0                         , 0 , 0 , 4598, 323, 129, 0 ),
+    1092             :   INST(Vfmsubaddpd     , Fma4_Lx            , V(660F3A,5F,_,x,x,_,_,_  ), 0                         , 0 , 0 , 4613, 326, 131, 0 ),
+    1093             :   INST(Vfmsubaddps     , Fma4_Lx            , V(660F3A,5E,_,x,x,_,_,_  ), 0                         , 0 , 0 , 4625, 326, 131, 0 ),
+    1094             :   INST(Vfmsubpd        , Fma4_Lx            , V(660F3A,6D,_,x,x,_,_,_  ), 0                         , 0 , 0 , 4637, 326, 131, 0 ),
+    1095             :   INST(Vfmsubps        , Fma4_Lx            , V(660F3A,6C,_,x,x,_,_,_  ), 0                         , 0 , 0 , 4646, 326, 131, 0 ),
+    1096             :   INST(Vfmsubsd        , Fma4               , V(660F3A,6F,_,0,x,_,_,_  ), 0                         , 0 , 0 , 4655, 327, 131, 0 ),
+    1097             :   INST(Vfmsubss        , Fma4               , V(660F3A,6E,_,0,x,_,_,_  ), 0                         , 0 , 0 , 4664, 328, 131, 0 ),
+    1098             :   INST(Vfnmadd132pd    , VexRvm_Lx          , V(660F38,9C,_,x,1,1,4,FV ), 0                         , 0 , 0 , 4673, 322, 129, 0 ),
+    1099             :   INST(Vfnmadd132ps    , VexRvm_Lx          , V(660F38,9C,_,x,0,0,4,FV ), 0                         , 0 , 0 , 4686, 323, 129, 0 ),
+    1100             :   INST(Vfnmadd132sd    , VexRvm             , V(660F38,9D,_,I,1,1,3,T1S), 0                         , 0 , 0 , 4699, 324, 130, 0 ),
+    1101             :   INST(Vfnmadd132ss    , VexRvm             , V(660F38,9D,_,I,0,0,2,T1S), 0                         , 0 , 0 , 4712, 325, 130, 0 ),
+    1102             :   INST(Vfnmadd213pd    , VexRvm_Lx          , V(660F38,AC,_,x,1,1,4,FV ), 0                         , 0 , 0 , 4725, 322, 129, 0 ),
+    1103             :   INST(Vfnmadd213ps    , VexRvm_Lx          , V(660F38,AC,_,x,0,0,4,FV ), 0                         , 0 , 0 , 4738, 323, 129, 0 ),
+    1104             :   INST(Vfnmadd213sd    , VexRvm             , V(660F38,AD,_,I,1,1,3,T1S), 0                         , 0 , 0 , 4751, 324, 130, 0 ),
+    1105             :   INST(Vfnmadd213ss    , VexRvm             , V(660F38,AD,_,I,0,0,2,T1S), 0                         , 0 , 0 , 4764, 325, 130, 0 ),
+    1106             :   INST(Vfnmadd231pd    , VexRvm_Lx          , V(660F38,BC,_,x,1,1,4,FV ), 0                         , 0 , 0 , 4777, 322, 129, 0 ),
+    1107             :   INST(Vfnmadd231ps    , VexRvm_Lx          , V(660F38,BC,_,x,0,0,4,FV ), 0                         , 0 , 0 , 4790, 323, 129, 0 ),
+    1108             :   INST(Vfnmadd231sd    , VexRvm             , V(660F38,BC,_,I,1,1,3,T1S), 0                         , 0 , 0 , 4803, 324, 130, 0 ),
+    1109             :   INST(Vfnmadd231ss    , VexRvm             , V(660F38,BC,_,I,0,0,2,T1S), 0                         , 0 , 0 , 4816, 325, 130, 0 ),
+    1110             :   INST(Vfnmaddpd       , Fma4_Lx            , V(660F3A,79,_,x,x,_,_,_  ), 0                         , 0 , 0 , 4829, 326, 131, 0 ),
+    1111             :   INST(Vfnmaddps       , Fma4_Lx            , V(660F3A,78,_,x,x,_,_,_  ), 0                         , 0 , 0 , 4839, 326, 131, 0 ),
+    1112             :   INST(Vfnmaddsd       , Fma4               , V(660F3A,7B,_,0,x,_,_,_  ), 0                         , 0 , 0 , 4849, 327, 131, 0 ),
+    1113             :   INST(Vfnmaddss       , Fma4               , V(660F3A,7A,_,0,x,_,_,_  ), 0                         , 0 , 0 , 4859, 328, 131, 0 ),
+    1114             :   INST(Vfnmsub132pd    , VexRvm_Lx          , V(660F38,9E,_,x,1,1,4,FV ), 0                         , 0 , 0 , 4869, 322, 129, 0 ),
+    1115             :   INST(Vfnmsub132ps    , VexRvm_Lx          , V(660F38,9E,_,x,0,0,4,FV ), 0                         , 0 , 0 , 4882, 323, 129, 0 ),
+    1116             :   INST(Vfnmsub132sd    , VexRvm             , V(660F38,9F,_,I,1,1,3,T1S), 0                         , 0 , 0 , 4895, 324, 130, 0 ),
+    1117             :   INST(Vfnmsub132ss    , VexRvm             , V(660F38,9F,_,I,0,0,2,T1S), 0                         , 0 , 0 , 4908, 325, 130, 0 ),
+    1118             :   INST(Vfnmsub213pd    , VexRvm_Lx          , V(660F38,AE,_,x,1,1,4,FV ), 0                         , 0 , 0 , 4921, 322, 129, 0 ),
+    1119             :   INST(Vfnmsub213ps    , VexRvm_Lx          , V(660F38,AE,_,x,0,0,4,FV ), 0                         , 0 , 0 , 4934, 323, 129, 0 ),
+    1120             :   INST(Vfnmsub213sd    , VexRvm             , V(660F38,AF,_,I,1,1,3,T1S), 0                         , 0 , 0 , 4947, 324, 130, 0 ),
+    1121             :   INST(Vfnmsub213ss    , VexRvm             , V(660F38,AF,_,I,0,0,2,T1S), 0                         , 0 , 0 , 4960, 325, 130, 0 ),
+    1122             :   INST(Vfnmsub231pd    , VexRvm_Lx          , V(660F38,BE,_,x,1,1,4,FV ), 0                         , 0 , 0 , 4973, 322, 129, 0 ),
+    1123             :   INST(Vfnmsub231ps    , VexRvm_Lx          , V(660F38,BE,_,x,0,0,4,FV ), 0                         , 0 , 0 , 4986, 323, 129, 0 ),
+    1124             :   INST(Vfnmsub231sd    , VexRvm             , V(660F38,BF,_,I,1,1,3,T1S), 0                         , 0 , 0 , 4999, 324, 130, 0 ),
+    1125             :   INST(Vfnmsub231ss    , VexRvm             , V(660F38,BF,_,I,0,0,2,T1S), 0                         , 0 , 0 , 5012, 325, 130, 0 ),
+    1126             :   INST(Vfnmsubpd       , Fma4_Lx            , V(660F3A,7D,_,x,x,_,_,_  ), 0                         , 0 , 0 , 5025, 326, 131, 0 ),
+    1127             :   INST(Vfnmsubps       , Fma4_Lx            , V(660F3A,7C,_,x,x,_,_,_  ), 0                         , 0 , 0 , 5035, 326, 131, 0 ),
+    1128             :   INST(Vfnmsubsd       , Fma4               , V(660F3A,7F,_,0,x,_,_,_  ), 0                         , 0 , 0 , 5045, 327, 131, 0 ),
+    1129             :   INST(Vfnmsubss       , Fma4               , V(660F3A,7E,_,0,x,_,_,_  ), 0                         , 0 , 0 , 5055, 328, 131, 0 ),
+    1130             :   INST(Vfpclasspd      , VexRmi_Lx          , V(660F3A,66,_,x,_,1,4,FV ), 0                         , 0 , 0 , 5065, 329, 123, 0 ),
+    1131             :   INST(Vfpclassps      , VexRmi_Lx          , V(660F3A,66,_,x,_,0,4,FV ), 0                         , 0 , 0 , 5076, 330, 123, 0 ),
+    1132             :   INST(Vfpclasssd      , VexRmi_Lx          , V(660F3A,67,_,I,_,1,3,T1S), 0                         , 0 , 0 , 5087, 331, 63 , 0 ),
+    1133             :   INST(Vfpclassss      , VexRmi_Lx          , V(660F3A,67,_,I,_,0,2,T1S), 0                         , 0 , 0 , 5098, 332, 63 , 0 ),
+    1134             :   INST(Vfrczpd         , VexRm_Lx           , V(XOP_M9,81,_,x,0,_,_,_  ), 0                         , 0 , 0 , 5109, 333, 132, 0 ),
+    1135             :   INST(Vfrczps         , VexRm_Lx           , V(XOP_M9,80,_,x,0,_,_,_  ), 0                         , 0 , 0 , 5117, 333, 132, 0 ),
+    1136             :   INST(Vfrczsd         , VexRm              , V(XOP_M9,83,_,0,0,_,_,_  ), 0                         , 0 , 0 , 5125, 334, 132, 0 ),
+    1137             :   INST(Vfrczss         , VexRm              , V(XOP_M9,82,_,0,0,_,_,_  ), 0                         , 0 , 0 , 5133, 335, 132, 0 ),
+    1138             :   INST(Vgatherdpd      , VexRmvRm_VM        , V(660F38,92,_,x,1,_,_,_  ), V(660F38,92,_,x,_,1,3,T1S), 0 , 0 , 5141, 336, 133, 0 ),
+    1139             :   INST(Vgatherdps      , VexRmvRm_VM        , V(660F38,92,_,x,0,_,_,_  ), V(660F38,92,_,x,_,0,2,T1S), 0 , 0 , 5152, 337, 133, 0 ),
+    1140             :   INST(Vgatherpf0dpd   , VexM_VM            , V(660F38,C6,1,2,_,1,3,T1S), 0                         , 0 , 0 , 5163, 338, 134, 0 ),
+    1141             :   INST(Vgatherpf0dps   , VexM_VM            , V(660F38,C6,1,2,_,0,2,T1S), 0                         , 0 , 0 , 5177, 339, 134, 0 ),
+    1142             :   INST(Vgatherpf0qpd   , VexM_VM            , V(660F38,C7,1,2,_,1,3,T1S), 0                         , 0 , 0 , 5191, 340, 134, 0 ),
+    1143             :   INST(Vgatherpf0qps   , VexM_VM            , V(660F38,C7,1,2,_,0,2,T1S), 0                         , 0 , 0 , 5205, 340, 134, 0 ),
+    1144             :   INST(Vgatherpf1dpd   , VexM_VM            , V(660F38,C6,2,2,_,1,3,T1S), 0                         , 0 , 0 , 5219, 338, 134, 0 ),
+    1145             :   INST(Vgatherpf1dps   , VexM_VM            , V(660F38,C6,2,2,_,0,2,T1S), 0                         , 0 , 0 , 5233, 339, 134, 0 ),
+    1146             :   INST(Vgatherpf1qpd   , VexM_VM            , V(660F38,C7,2,2,_,1,3,T1S), 0                         , 0 , 0 , 5247, 340, 134, 0 ),
+    1147             :   INST(Vgatherpf1qps   , VexM_VM            , V(660F38,C7,2,2,_,0,2,T1S), 0                         , 0 , 0 , 5261, 340, 134, 0 ),
+    1148             :   INST(Vgatherqpd      , VexRmvRm_VM        , V(660F38,93,_,x,1,_,_,_  ), V(660F38,93,_,x,_,1,3,T1S), 0 , 0 , 5275, 341, 133, 0 ),
+    1149             :   INST(Vgatherqps      , VexRmvRm_VM        , V(660F38,93,_,x,0,_,_,_  ), V(660F38,93,_,x,_,0,2,T1S), 0 , 0 , 5286, 342, 133, 0 ),
+    1150             :   INST(Vgetexppd       , VexRm_Lx           , V(660F38,42,_,x,_,1,4,FV ), 0                         , 0 , 0 , 5297, 298, 120, 0 ),
+    1151             :   INST(Vgetexpps       , VexRm_Lx           , V(660F38,42,_,x,_,0,4,FV ), 0                         , 0 , 0 , 5307, 302, 120, 0 ),
+    1152             :   INST(Vgetexpsd       , VexRm              , V(660F38,43,_,I,_,1,3,T1S), 0                         , 0 , 0 , 5317, 343, 65 , 0 ),
+    1153             :   INST(Vgetexpss       , VexRm              , V(660F38,43,_,I,_,0,2,T1S), 0                         , 0 , 0 , 5327, 344, 65 , 0 ),
+    1154             :   INST(Vgetmantpd      , VexRmi_Lx          , V(660F3A,26,_,x,_,1,4,FV ), 0                         , 0 , 0 , 5337, 345, 120, 0 ),
+    1155             :   INST(Vgetmantps      , VexRmi_Lx          , V(660F3A,26,_,x,_,0,4,FV ), 0                         , 0 , 0 , 5348, 346, 120, 0 ),
+    1156             :   INST(Vgetmantsd      , VexRmi             , V(660F3A,27,_,I,_,1,3,T1S), 0                         , 0 , 0 , 5359, 347, 65 , 0 ),
+    1157             :   INST(Vgetmantss      , VexRmi             , V(660F3A,27,_,I,_,0,2,T1S), 0                         , 0 , 0 , 5370, 348, 65 , 0 ),
+    1158             :   INST(Vhaddpd         , VexRvm_Lx          , V(660F00,7C,_,x,I,_,_,_  ), 0                         , 0 , 0 , 5381, 250, 118, 21),
+    1159             :   INST(Vhaddps         , VexRvm_Lx          , V(F20F00,7C,_,x,I,_,_,_  ), 0                         , 0 , 0 , 5389, 250, 118, 21),
+    1160             :   INST(Vhsubpd         , VexRvm_Lx          , V(660F00,7D,_,x,I,_,_,_  ), 0                         , 0 , 0 , 5397, 250, 118, 22),
+    1161             :   INST(Vhsubps         , VexRvm_Lx          , V(F20F00,7D,_,x,I,_,_,_  ), 0                         , 0 , 0 , 5405, 250, 118, 22),
+    1162             :   INST(Vinsertf128     , VexRvmi            , V(660F3A,18,_,1,0,_,_,_  ), 0                         , 0 , 0 , 5413, 349, 118, 0 ),
+    1163             :   INST(Vinsertf32x4    , VexRvmi_Lx         , V(660F3A,18,_,x,_,0,4,T4 ), 0                         , 0 , 0 , 5425, 350, 120, 0 ),
+    1164             :   INST(Vinsertf32x8    , VexRvmi            , V(660F3A,1A,_,2,_,0,5,T8 ), 0                         , 0 , 0 , 5438, 351, 63 , 0 ),
+    1165             :   INST(Vinsertf64x2    , VexRvmi_Lx         , V(660F3A,18,_,x,_,1,4,T2 ), 0                         , 0 , 0 , 5451, 350, 123, 0 ),
+    1166             :   INST(Vinsertf64x4    , VexRvmi            , V(660F3A,1A,_,2,_,1,5,T4 ), 0                         , 0 , 0 , 5464, 351, 65 , 0 ),
+    1167             :   INST(Vinserti128     , VexRvmi            , V(660F3A,38,_,1,0,_,_,_  ), 0                         , 0 , 0 , 5477, 349, 124, 0 ),
+    1168             :   INST(Vinserti32x4    , VexRvmi_Lx         , V(660F3A,38,_,x,_,0,4,T4 ), 0                         , 0 , 0 , 5489, 350, 120, 0 ),
+    1169             :   INST(Vinserti32x8    , VexRvmi            , V(660F3A,3A,_,2,_,0,5,T8 ), 0                         , 0 , 0 , 5502, 351, 63 , 0 ),
+    1170             :   INST(Vinserti64x2    , VexRvmi_Lx         , V(660F3A,38,_,x,_,1,4,T2 ), 0                         , 0 , 0 , 5515, 350, 123, 0 ),
+    1171             :   INST(Vinserti64x4    , VexRvmi            , V(660F3A,3A,_,2,_,1,5,T4 ), 0                         , 0 , 0 , 5528, 351, 65 , 0 ),
+    1172             :   INST(Vinsertps       , VexRvmi            , V(660F3A,21,_,0,I,0,2,T1S), 0                         , 0 , 0 , 5541, 352, 117, 23),
+    1173             :   INST(Vlddqu          , VexRm_Lx           , V(F20F00,F0,_,x,I,_,_,_  ), 0                         , 0 , 0 , 5551, 353, 118, 24),
+    1174             :   INST(Vldmxcsr        , VexM               , V(000F00,AE,2,0,I,_,_,_  ), 0                         , 0 , 0 , 5558, 354, 118, 0 ),
+    1175             :   INST(Vmaskmovdqu     , VexRm_ZDI          , V(660F00,F7,_,0,I,_,_,_  ), 0                         , 0 , 0 , 5567, 355, 118, 25),
+    1176             :   INST(Vmaskmovpd      , VexRvmMvr_Lx       , V(660F38,2D,_,x,0,_,_,_  ), V(660F38,2F,_,x,0,_,_,_  ), 0 , 0 , 5579, 356, 118, 0 ),
+    1177             :   INST(Vmaskmovps      , VexRvmMvr_Lx       , V(660F38,2C,_,x,0,_,_,_  ), V(660F38,2E,_,x,0,_,_,_  ), 0 , 0 , 5590, 357, 118, 0 ),
+    1178             :   INST(Vmaxpd          , VexRvm_Lx          , V(660F00,5F,_,x,I,1,4,FV ), 0                         , 0 , 0 , 5601, 358, 116, 26),
+    1179             :   INST(Vmaxps          , VexRvm_Lx          , V(000F00,5F,_,x,I,0,4,FV ), 0                         , 0 , 0 , 5608, 359, 116, 26),
+    1180             :   INST(Vmaxsd          , VexRvm             , V(F20F00,5F,_,I,I,1,3,T1S), 0                         , 0 , 0 , 5615, 360, 116, 26),
+    1181             :   INST(Vmaxss          , VexRvm             , V(F30F00,5F,_,I,I,0,2,T1S), 0                         , 0 , 0 , 5622, 294, 116, 26),
+    1182             :   INST(Vminpd          , VexRvm_Lx          , V(660F00,5D,_,x,I,1,4,FV ), 0                         , 0 , 0 , 5629, 358, 116, 27),
+    1183             :   INST(Vminps          , VexRvm_Lx          , V(000F00,5D,_,x,I,0,4,FV ), 0                         , 0 , 0 , 5636, 359, 116, 27),
+    1184             :   INST(Vminsd          , VexRvm             , V(F20F00,5D,_,I,I,1,3,T1S), 0                         , 0 , 0 , 5643, 360, 116, 27),
+    1185             :   INST(Vminss          , VexRvm             , V(F30F00,5D,_,I,I,0,2,T1S), 0                         , 0 , 0 , 5650, 294, 116, 27),
+    1186             :   INST(Vmovapd         , VexRmMr_Lx         , V(660F00,28,_,x,I,1,4,FVM), V(660F00,29,_,x,I,1,4,FVM), 0 , 0 , 5657, 361, 116, 28),
+    1187             :   INST(Vmovaps         , VexRmMr_Lx         , V(000F00,28,_,x,I,0,4,FVM), V(000F00,29,_,x,I,0,4,FVM), 0 , 0 , 5665, 362, 116, 28),
+    1188             :   INST(Vmovd           , VexMovdMovq        , V(660F00,6E,_,0,0,0,2,T1S), V(660F00,7E,_,0,0,0,2,T1S), 0 , 0 , 5673, 363, 117, 29),
+    1189             :   INST(Vmovddup        , VexRm_Lx           , V(F20F00,12,_,x,I,1,3,DUP), 0                         , 0 , 0 , 5679, 364, 116, 29),
+    1190             :   INST(Vmovdqa         , VexRmMr_Lx         , V(660F00,6F,_,x,I,_,_,_  ), V(660F00,7F,_,x,I,_,_,_  ), 0 , 0 , 5688, 365, 118, 30),
+    1191             :   INST(Vmovdqa32       , VexRmMr_Lx         , V(660F00,6F,_,x,_,0,4,FVM), V(660F00,7F,_,x,_,0,4,FVM), 0 , 0 , 5696, 366, 120, 0 ),
+    1192             :   INST(Vmovdqa64       , VexRmMr_Lx         , V(660F00,6F,_,x,_,1,4,FVM), V(660F00,7F,_,x,_,1,4,FVM), 0 , 0 , 5706, 367, 120, 0 ),
+    1193             :   INST(Vmovdqu         , VexRmMr_Lx         , V(F30F00,6F,_,x,I,_,_,_  ), V(F30F00,7F,_,x,I,_,_,_  ), 0 , 0 , 5716, 368, 118, 28),
+    1194             :   INST(Vmovdqu16       , VexRmMr_Lx         , V(F20F00,6F,_,x,_,1,4,FVM), V(F20F00,7F,_,x,_,1,4,FVM), 0 , 0 , 5724, 369, 122, 0 ),
+    1195             :   INST(Vmovdqu32       , VexRmMr_Lx         , V(F30F00,6F,_,x,_,0,4,FVM), V(F30F00,7F,_,x,_,0,4,FVM), 0 , 0 , 5734, 370, 120, 0 ),
+    1196             :   INST(Vmovdqu64       , VexRmMr_Lx         , V(F30F00,6F,_,x,_,1,4,FVM), V(F30F00,7F,_,x,_,1,4,FVM), 0 , 0 , 5744, 371, 120, 0 ),
+    1197             :   INST(Vmovdqu8        , VexRmMr_Lx         , V(F20F00,6F,_,x,_,0,4,FVM), V(F20F00,7F,_,x,_,0,4,FVM), 0 , 0 , 5754, 372, 122, 0 ),
+    1198             :   INST(Vmovhlps        , VexRvm             , V(000F00,12,_,0,I,0,_,_  ), 0                         , 0 , 0 , 5763, 373, 117, 31),
+    1199             :   INST(Vmovhpd         , VexRvmMr           , V(660F00,16,_,0,I,1,3,T1S), V(660F00,17,_,0,I,1,3,T1S), 0 , 0 , 5772, 374, 117, 32),
+    1200             :   INST(Vmovhps         , VexRvmMr           , V(000F00,16,_,0,I,0,3,T2 ), V(000F00,17,_,0,I,0,3,T2 ), 0 , 0 , 5780, 375, 117, 32),
+    1201             :   INST(Vmovlhps        , VexRvm             , V(000F00,16,_,0,I,0,_,_  ), 0                         , 0 , 0 , 5788, 373, 117, 31),
+    1202             :   INST(Vmovlpd         , VexRvmMr           , V(660F00,12,_,0,I,1,3,T1S), V(660F00,13,_,0,I,1,3,T1S), 0 , 0 , 5797, 376, 117, 32),
+    1203             :   INST(Vmovlps         , VexRvmMr           , V(000F00,12,_,0,I,0,3,T2 ), V(000F00,13,_,0,I,0,3,T2 ), 0 , 0 , 5805, 377, 117, 32),
+    1204             :   INST(Vmovmskpd       , VexRm_Lx           , V(660F00,50,_,x,I,_,_,_  ), 0                         , 0 , 0 , 5813, 378, 118, 33),
+    1205             :   INST(Vmovmskps       , VexRm_Lx           , V(000F00,50,_,x,I,_,_,_  ), 0                         , 0 , 0 , 5823, 378, 118, 33),
+    1206             :   INST(Vmovntdq        , VexMr_Lx           , V(660F00,E7,_,x,I,0,4,FVM), 0                         , 0 , 0 , 5833, 379, 116, 33),
+    1207             :   INST(Vmovntdqa       , VexRm_Lx           , V(660F38,2A,_,x,I,0,4,FVM), 0                         , 0 , 0 , 5842, 380, 125, 33),
+    1208             :   INST(Vmovntpd        , VexMr_Lx           , V(660F00,2B,_,x,I,1,4,FVM), 0                         , 0 , 0 , 5852, 379, 116, 34),
+    1209             :   INST(Vmovntps        , VexMr_Lx           , V(000F00,2B,_,x,I,0,4,FVM), 0                         , 0 , 0 , 5861, 379, 116, 34),
+    1210             :   INST(Vmovq           , VexMovdMovq        , V(660F00,6E,_,0,I,1,3,T1S), V(660F00,7E,_,0,I,1,3,T1S), 0 , 0 , 5870, 381, 117, 28),
+    1211             :   INST(Vmovsd          , VexMovssMovsd      , V(F20F00,10,_,I,I,1,3,T1S), V(F20F00,11,_,I,I,1,3,T1S), 0 , 0 , 5876, 382, 117, 35),
+    1212             :   INST(Vmovshdup       , VexRm_Lx           , V(F30F00,16,_,x,I,0,4,FVM), 0                         , 0 , 0 , 5883, 383, 116, 30),
+    1213             :   INST(Vmovsldup       , VexRm_Lx           , V(F30F00,12,_,x,I,0,4,FVM), 0                         , 0 , 0 , 5893, 383, 116, 30),
+    1214             :   INST(Vmovss          , VexMovssMovsd      , V(F30F00,10,_,I,I,0,2,T1S), V(F30F00,11,_,I,I,0,2,T1S), 0 , 0 , 5903, 384, 117, 35),
+    1215             :   INST(Vmovupd         , VexRmMr_Lx         , V(660F00,10,_,x,I,1,4,FVM), V(660F00,11,_,x,I,1,4,FVM), 0 , 0 , 5910, 385, 116, 36),
+    1216             :   INST(Vmovups         , VexRmMr_Lx         , V(000F00,10,_,x,I,0,4,FVM), V(000F00,11,_,x,I,0,4,FVM), 0 , 0 , 5918, 386, 116, 36),
+    1217             :   INST(Vmpsadbw        , VexRvmi_Lx         , V(660F3A,42,_,x,I,_,_,_  ), 0                         , 0 , 0 , 5926, 263, 135, 37),
+    1218             :   INST(Vmulpd          , VexRvm_Lx          , V(660F00,59,_,x,I,1,4,FV ), 0                         , 0 , 0 , 5935, 246, 116, 38),
+    1219             :   INST(Vmulps          , VexRvm_Lx          , V(000F00,59,_,x,I,0,4,FV ), 0                         , 0 , 0 , 5942, 247, 116, 38),
+    1220             :   INST(Vmulsd          , VexRvm_Lx          , V(F20F00,59,_,I,I,1,3,T1S), 0                         , 0 , 0 , 5949, 248, 117, 38),
+    1221             :   INST(Vmulss          , VexRvm_Lx          , V(F30F00,59,_,I,I,0,2,T1S), 0                         , 0 , 0 , 5956, 249, 117, 38),
+    1222             :   INST(Vorpd           , VexRvm_Lx          , V(660F00,56,_,x,I,1,4,FV ), 0                         , 0 , 0 , 5963, 258, 121, 39),
+    1223             :   INST(Vorps           , VexRvm_Lx          , V(000F00,56,_,x,I,0,4,FV ), 0                         , 0 , 0 , 5969, 259, 116, 39),
+    1224             :   INST(Vp4dpwssd       , VexRm_T1_4X        , V(F20F38,52,_,2,_,0,2,T4X), 0                         , 0 , 0 , 5975, 387, 136, 0 ),
+    1225             :   INST(Vp4dpwssds      , VexRm_T1_4X        , V(F20F38,53,_,2,_,0,2,T4X), 0                         , 0 , 0 , 5985, 387, 136, 0 ),
+    1226             :   INST(Vpabsb          , VexRm_Lx           , V(660F38,1C,_,x,I,_,4,FVM), 0                         , 0 , 0 , 5996, 383, 137, 40),
+    1227             :   INST(Vpabsd          , VexRm_Lx           , V(660F38,1E,_,x,I,0,4,FV ), 0                         , 0 , 0 , 6003, 383, 125, 40),
+    1228             :   INST(Vpabsq          , VexRm_Lx           , V(660F38,1F,_,x,_,1,4,FV ), 0                         , 0 , 0 , 6010, 313, 120, 0 ),
+    1229             :   INST(Vpabsw          , VexRm_Lx           , V(660F38,1D,_,x,I,_,4,FVM), 0                         , 0 , 0 , 6017, 383, 137, 41),
+    1230             :   INST(Vpackssdw       , VexRvm_Lx          , V(660F00,6B,_,x,I,0,4,FV ), 0                         , 0 , 0 , 6024, 257, 137, 42),
+    1231             :   INST(Vpacksswb       , VexRvm_Lx          , V(660F00,63,_,x,I,I,4,FVM), 0                         , 0 , 0 , 6034, 388, 137, 42),
+    1232             :   INST(Vpackusdw       , VexRvm_Lx          , V(660F38,2B,_,x,I,0,4,FV ), 0                         , 0 , 0 , 6044, 257, 137, 42),
+    1233             :   INST(Vpackuswb       , VexRvm_Lx          , V(660F00,67,_,x,I,I,4,FVM), 0                         , 0 , 0 , 6054, 388, 137, 42),
+    1234             :   INST(Vpaddb          , VexRvm_Lx          , V(660F00,FC,_,x,I,I,4,FVM), 0                         , 0 , 0 , 6064, 388, 137, 42),
+    1235             :   INST(Vpaddd          , VexRvm_Lx          , V(660F00,FE,_,x,I,0,4,FV ), 0                         , 0 , 0 , 6071, 257, 125, 42),
+    1236             :   INST(Vpaddq          , VexRvm_Lx          , V(660F00,D4,_,x,I,1,4,FV ), 0                         , 0 , 0 , 6078, 256, 125, 42),
+    1237             :   INST(Vpaddsb         , VexRvm_Lx          , V(660F00,EC,_,x,I,I,4,FVM), 0                         , 0 , 0 , 6085, 388, 137, 42),
+    1238             :   INST(Vpaddsw         , VexRvm_Lx          , V(660F00,ED,_,x,I,I,4,FVM), 0                         , 0 , 0 , 6093, 388, 137, 42),
+    1239             :   INST(Vpaddusb        , VexRvm_Lx          , V(660F00,DC,_,x,I,I,4,FVM), 0                         , 0 , 0 , 6101, 388, 137, 42),
+    1240             :   INST(Vpaddusw        , VexRvm_Lx          , V(660F00,DD,_,x,I,I,4,FVM), 0                         , 0 , 0 , 6110, 388, 137, 42),
+    1241             :   INST(Vpaddw          , VexRvm_Lx          , V(660F00,FD,_,x,I,I,4,FVM), 0                         , 0 , 0 , 6119, 388, 137, 42),
+    1242             :   INST(Vpalignr        , VexRvmi_Lx         , V(660F3A,0F,_,x,I,I,4,FVM), 0                         , 0 , 0 , 6126, 389, 137, 42),
+    1243             :   INST(Vpand           , VexRvm_Lx          , V(660F00,DB,_,x,I,_,_,_  ), 0                         , 0 , 0 , 6135, 390, 135, 42),
+    1244             :   INST(Vpandd          , VexRvm_Lx          , V(660F00,DB,_,x,_,0,4,FV ), 0                         , 0 , 0 , 6141, 391, 120, 0 ),
+    1245             :   INST(Vpandn          , VexRvm_Lx          , V(660F00,DF,_,x,I,_,_,_  ), 0                         , 0 , 0 , 6148, 392, 135, 43),
+    1246             :   INST(Vpandnd         , VexRvm_Lx          , V(660F00,DF,_,x,_,0,4,FV ), 0                         , 0 , 0 , 6155, 393, 120, 0 ),
+    1247             :   INST(Vpandnq         , VexRvm_Lx          , V(660F00,DF,_,x,_,1,4,FV ), 0                         , 0 , 0 , 6163, 394, 120, 0 ),
+    1248             :   INST(Vpandq          , VexRvm_Lx          , V(660F00,DB,_,x,_,1,4,FV ), 0                         , 0 , 0 , 6171, 395, 120, 0 ),
+    1249             :   INST(Vpavgb          , VexRvm_Lx          , V(660F00,E0,_,x,I,I,4,FVM), 0                         , 0 , 0 , 6178, 388, 137, 44),
+    1250             :   INST(Vpavgw          , VexRvm_Lx          , V(660F00,E3,_,x,I,I,4,FVM), 0                         , 0 , 0 , 6185, 388, 137, 45),
+    1251             :   INST(Vpblendd        , VexRvmi_Lx         , V(660F3A,02,_,x,0,_,_,_  ), 0                         , 0 , 0 , 6192, 263, 124, 0 ),
+    1252             :   INST(Vpblendvb       , VexRvmr            , V(660F3A,4C,_,x,0,_,_,_  ), 0                         , 0 , 0 , 6201, 264, 135, 46),
+    1253             :   INST(Vpblendw        , VexRvmi_Lx         , V(660F3A,0E,_,x,I,_,_,_  ), 0                         , 0 , 0 , 6211, 263, 135, 44),
+    1254             :   INST(Vpbroadcastb    , VexRm_Lx           , V(660F38,78,_,x,0,0,0,T1S), 0                         , 0 , 0 , 6220, 396, 138, 0 ),
+    1255             :   INST(Vpbroadcastd    , VexRm_Lx           , V(660F38,58,_,x,0,0,2,T1S), 0                         , 0 , 0 , 6233, 397, 133, 0 ),
+    1256             :   INST(Vpbroadcastmb2d , VexRm_Lx           , V(F30F38,3A,_,x,_,0,_,_  ), 0                         , 0 , 0 , 6246, 398, 139, 0 ),
+    1257             :   INST(Vpbroadcastmb2q , VexRm_Lx           , V(F30F38,2A,_,x,_,1,_,_  ), 0                         , 0 , 0 , 6262, 398, 139, 0 ),
+    1258             :   INST(Vpbroadcastq    , VexRm_Lx           , V(660F38,59,_,x,0,1,3,T1S), 0                         , 0 , 0 , 6278, 399, 133, 0 ),
+    1259             :   INST(Vpbroadcastw    , VexRm_Lx           , V(660F38,79,_,x,0,0,1,T1S), 0                         , 0 , 0 , 6291, 400, 138, 0 ),
+    1260             :   INST(Vpclmulqdq      , VexRvmi            , V(660F3A,44,_,0,I,_,_,_  ), 0                         , 0 , 0 , 6304, 310, 140, 47),
+    1261             :   INST(Vpcmov          , VexRvrmRvmr_Lx     , V(XOP_M8,A2,_,x,x,_,_,_  ), 0                         , 0 , 0 , 6315, 326, 132, 0 ),
+    1262             :   INST(Vpcmpb          , VexRvmi_Lx         , V(660F3A,3F,_,x,_,0,4,FVM), 0                         , 0 , 0 , 6322, 401, 122, 0 ),
+    1263             :   INST(Vpcmpd          , VexRvmi_Lx         , V(660F3A,1F,_,x,_,0,4,FV ), 0                         , 0 , 0 , 6329, 402, 120, 0 ),
+    1264             :   INST(Vpcmpeqb        , VexRvm_Lx          , V(660F00,74,_,x,I,I,4,FV ), 0                         , 0 , 0 , 6336, 403, 137, 48),
+    1265             :   INST(Vpcmpeqd        , VexRvm_Lx          , V(660F00,76,_,x,I,0,4,FVM), 0                         , 0 , 0 , 6345, 404, 125, 48),
+    1266             :   INST(Vpcmpeqq        , VexRvm_Lx          , V(660F38,29,_,x,I,1,4,FVM), 0                         , 0 , 0 , 6354, 405, 125, 48),
+    1267             :   INST(Vpcmpeqw        , VexRvm_Lx          , V(660F00,75,_,x,I,I,4,FV ), 0                         , 0 , 0 , 6363, 403, 137, 48),
+    1268             :   INST(Vpcmpestri      , VexRmi             , V(660F3A,61,_,0,I,_,_,_  ), 0                         , 0 , 0 , 6372, 406, 141, 49),
+    1269             :   INST(Vpcmpestrm      , VexRmi             , V(660F3A,60,_,0,I,_,_,_  ), 0                         , 0 , 0 , 6383, 407, 141, 49),
+    1270             :   INST(Vpcmpgtb        , VexRvm_Lx          , V(660F00,64,_,x,I,I,4,FV ), 0                         , 0 , 0 , 6394, 403, 137, 48),
+    1271             :   INST(Vpcmpgtd        , VexRvm_Lx          , V(660F00,66,_,x,I,0,4,FVM), 0                         , 0 , 0 , 6403, 404, 125, 48),
+    1272             :   INST(Vpcmpgtq        , VexRvm_Lx          , V(660F38,37,_,x,I,1,4,FVM), 0                         , 0 , 0 , 6412, 405, 125, 48),
+    1273             :   INST(Vpcmpgtw        , VexRvm_Lx          , V(660F00,65,_,x,I,I,4,FV ), 0                         , 0 , 0 , 6421, 403, 137, 48),
+    1274             :   INST(Vpcmpistri      , VexRmi             , V(660F3A,63,_,0,I,_,_,_  ), 0                         , 0 , 0 , 6430, 408, 141, 49),
+    1275             :   INST(Vpcmpistrm      , VexRmi             , V(660F3A,62,_,0,I,_,_,_  ), 0                         , 0 , 0 , 6441, 409, 141, 49),
+    1276             :   INST(Vpcmpq          , VexRvmi_Lx         , V(660F3A,1F,_,x,_,1,4,FV ), 0                         , 0 , 0 , 6452, 410, 120, 0 ),
+    1277             :   INST(Vpcmpub         , VexRvmi_Lx         , V(660F3A,3E,_,x,_,0,4,FVM), 0                         , 0 , 0 , 6459, 401, 122, 0 ),
+    1278             :   INST(Vpcmpud         , VexRvmi_Lx         , V(660F3A,1E,_,x,_,0,4,FV ), 0                         , 0 , 0 , 6467, 402, 120, 0 ),
+    1279             :   INST(Vpcmpuq         , VexRvmi_Lx         , V(660F3A,1E,_,x,_,1,4,FV ), 0                         , 0 , 0 , 6475, 410, 120, 0 ),
+    1280             :   INST(Vpcmpuw         , VexRvmi_Lx         , V(660F3A,3E,_,x,_,1,4,FVM), 0                         , 0 , 0 , 6483, 410, 122, 0 ),
+    1281             :   INST(Vpcmpw          , VexRvmi_Lx         , V(660F3A,3F,_,x,_,1,4,FVM), 0                         , 0 , 0 , 6491, 410, 122, 0 ),
+    1282             :   INST(Vpcomb          , VexRvmi            , V(XOP_M8,CC,_,0,0,_,_,_  ), 0                         , 0 , 0 , 6498, 310, 132, 0 ),
+    1283             :   INST(Vpcomd          , VexRvmi            , V(XOP_M8,CE,_,0,0,_,_,_  ), 0                         , 0 , 0 , 6505, 310, 132, 0 ),
+    1284             :   INST(Vpcompressd     , VexMr_Lx           , V(660F38,8B,_,x,_,0,2,T1S), 0                         , 0 , 0 , 6512, 279, 120, 0 ),
+    1285             :   INST(Vpcompressq     , VexMr_Lx           , V(660F38,8B,_,x,_,1,3,T1S), 0                         , 0 , 0 , 6524, 279, 120, 0 ),
+    1286             :   INST(Vpcomq          , VexRvmi            , V(XOP_M8,CF,_,0,0,_,_,_  ), 0                         , 0 , 0 , 6536, 310, 132, 0 ),
+    1287             :   INST(Vpcomub         , VexRvmi            , V(XOP_M8,EC,_,0,0,_,_,_  ), 0                         , 0 , 0 , 6543, 310, 132, 0 ),
+    1288             :   INST(Vpcomud         , VexRvmi            , V(XOP_M8,EE,_,0,0,_,_,_  ), 0                         , 0 , 0 , 6551, 310, 132, 0 ),
+    1289             :   INST(Vpcomuq         , VexRvmi            , V(XOP_M8,EF,_,0,0,_,_,_  ), 0                         , 0 , 0 , 6559, 310, 132, 0 ),
+    1290             :   INST(Vpcomuw         , VexRvmi            , V(XOP_M8,ED,_,0,0,_,_,_  ), 0                         , 0 , 0 , 6567, 310, 132, 0 ),
+    1291             :   INST(Vpcomw          , VexRvmi            , V(XOP_M8,CD,_,0,0,_,_,_  ), 0                         , 0 , 0 , 6575, 310, 132, 0 ),
+    1292             :   INST(Vpconflictd     , VexRm_Lx           , V(660F38,C4,_,x,_,0,4,FV ), 0                         , 0 , 0 , 6582, 411, 139, 0 ),
+    1293             :   INST(Vpconflictq     , VexRm_Lx           , V(660F38,C4,_,x,_,1,4,FV ), 0                         , 0 , 0 , 6594, 411, 139, 0 ),
+    1294             :   INST(Vperm2f128      , VexRvmi            , V(660F3A,06,_,1,0,_,_,_  ), 0                         , 0 , 0 , 6606, 412, 118, 0 ),
+    1295             :   INST(Vperm2i128      , VexRvmi            , V(660F3A,46,_,1,0,_,_,_  ), 0                         , 0 , 0 , 6617, 412, 124, 0 ),
+    1296             :   INST(Vpermb          , VexRvm_Lx          , V(660F38,8D,_,x,_,0,4,FVM), 0                         , 0 , 0 , 6628, 260, 142, 0 ),
+    1297             :   INST(Vpermd          , VexRvm_Lx          , V(660F38,36,_,x,0,0,4,FV ), 0                         , 0 , 0 , 6635, 413, 133, 0 ),
+    1298             :   INST(Vpermi2b        , VexRvm_Lx          , V(660F38,75,_,x,_,0,4,FVM), 0                         , 0 , 0 , 6642, 260, 142, 0 ),
+    1299             :   INST(Vpermi2d        , VexRvm_Lx          , V(660F38,76,_,x,_,0,4,FV ), 0                         , 0 , 0 , 6651, 414, 120, 0 ),
+    1300             :   INST(Vpermi2pd       , VexRvm_Lx          , V(660F38,77,_,x,_,1,4,FV ), 0                         , 0 , 0 , 6660, 262, 120, 0 ),
+    1301             :   INST(Vpermi2ps       , VexRvm_Lx          , V(660F38,77,_,x,_,0,4,FV ), 0                         , 0 , 0 , 6670, 261, 120, 0 ),
+    1302             :   INST(Vpermi2q        , VexRvm_Lx          , V(660F38,76,_,x,_,1,4,FV ), 0                         , 0 , 0 , 6680, 415, 120, 0 ),
+    1303             :   INST(Vpermi2w        , VexRvm_Lx          , V(660F38,75,_,x,_,1,4,FVM), 0                         , 0 , 0 , 6689, 416, 122, 0 ),
+    1304             :   INST(Vpermil2pd      , VexRvrmiRvmri_Lx   , V(660F3A,49,_,x,x,_,_,_  ), 0                         , 0 , 0 , 6698, 417, 132, 0 ),
+    1305             :   INST(Vpermil2ps      , VexRvrmiRvmri_Lx   , V(660F3A,48,_,x,x,_,_,_  ), 0                         , 0 , 0 , 6709, 417, 132, 0 ),
+    1306             :   INST(Vpermilpd       , VexRvmRmi_Lx       , V(660F38,0D,_,x,0,1,4,FV ), V(660F3A,05,_,x,0,1,4,FV ), 0 , 0 , 6720, 418, 116, 0 ),
+    1307             :   INST(Vpermilps       , VexRvmRmi_Lx       , V(660F38,0C,_,x,0,0,4,FV ), V(660F3A,04,_,x,0,0,4,FV ), 0 , 0 , 6730, 419, 116, 0 ),
+    1308             :   INST(Vpermpd         , VexRmi             , V(660F3A,01,_,1,1,_,_,_  ), 0                         , 0 , 0 , 6740, 420, 124, 0 ),
+    1309             :   INST(Vpermps         , VexRvm             , V(660F38,16,_,1,0,_,_,_  ), 0                         , 0 , 0 , 6748, 421, 124, 0 ),
+    1310             :   INST(Vpermq          , VexRvmRmi_Lx       , V(660F38,36,_,x,_,1,4,FV ), V(660F3A,00,_,x,1,1,4,FV ), 0 , 0 , 6756, 422, 133, 0 ),
+    1311             :   INST(Vpermt2b        , VexRvm_Lx          , V(660F38,7D,_,x,_,0,4,FVM), 0                         , 0 , 0 , 6763, 260, 142, 0 ),
+    1312             :   INST(Vpermt2d        , VexRvm_Lx          , V(660F38,7E,_,x,_,0,4,FV ), 0                         , 0 , 0 , 6772, 414, 120, 0 ),
+    1313             :   INST(Vpermt2pd       , VexRvm_Lx          , V(660F38,7F,_,x,_,1,4,FV ), 0                         , 0 , 0 , 6781, 415, 120, 0 ),
+    1314             :   INST(Vpermt2ps       , VexRvm_Lx          , V(660F38,7F,_,x,_,0,4,FV ), 0                         , 0 , 0 , 6791, 414, 120, 0 ),
+    1315             :   INST(Vpermt2q        , VexRvm_Lx          , V(660F38,7E,_,x,_,1,4,FV ), 0                         , 0 , 0 , 6801, 415, 120, 0 ),
+    1316             :   INST(Vpermt2w        , VexRvm_Lx          , V(660F38,7D,_,x,_,1,4,FVM), 0                         , 0 , 0 , 6810, 416, 122, 0 ),
+    1317             :   INST(Vpermw          , VexRvm_Lx          , V(660F38,8D,_,x,_,1,4,FVM), 0                         , 0 , 0 , 6819, 260, 122, 0 ),
+    1318             :   INST(Vpexpandd       , VexRm_Lx           , V(660F38,89,_,x,_,0,2,T1S), 0                         , 0 , 0 , 6826, 313, 120, 0 ),
+    1319             :   INST(Vpexpandq       , VexRm_Lx           , V(660F38,89,_,x,_,1,3,T1S), 0                         , 0 , 0 , 6836, 313, 120, 0 ),
+    1320             :   INST(Vpextrb         , VexMri             , V(660F3A,14,_,0,0,I,0,T1S), 0                         , 0 , 0 , 6846, 423, 143, 50),
+    1321             :   INST(Vpextrd         , VexMri             , V(660F3A,16,_,0,0,0,2,T1S), 0                         , 0 , 0 , 6854, 317, 144, 50),
+    1322             :   INST(Vpextrq         , VexMri             , V(660F3A,16,_,0,1,1,3,T1S), 0                         , 0 , 0 , 6862, 424, 144, 50),
+    1323             :   INST(Vpextrw         , VexMri             , V(660F3A,15,_,0,0,I,1,T1S), 0                         , 0 , 0 , 6870, 425, 143, 50),
+    1324             :   INST(Vpgatherdd      , VexRmvRm_VM        , V(660F38,90,_,x,0,_,_,_  ), V(660F38,90,_,x,_,0,2,T1S), 0 , 0 , 6878, 426, 133, 0 ),
+    1325             :   INST(Vpgatherdq      , VexRmvRm_VM        , V(660F38,90,_,x,1,_,_,_  ), V(660F38,90,_,x,_,1,3,T1S), 0 , 0 , 6889, 427, 133, 0 ),
+    1326             :   INST(Vpgatherqd      , VexRmvRm_VM        , V(660F38,91,_,x,0,_,_,_  ), V(660F38,91,_,x,_,0,2,T1S), 0 , 0 , 6900, 428, 133, 0 ),
+    1327             :   INST(Vpgatherqq      , VexRmvRm_VM        , V(660F38,91,_,x,1,_,_,_  ), V(660F38,91,_,x,_,1,3,T1S), 0 , 0 , 6911, 429, 133, 0 ),
+    1328             :   INST(Vphaddbd        , VexRm              , V(XOP_M9,C2,_,0,0,_,_,_  ), 0                         , 0 , 0 , 6922, 252, 132, 0 ),
+    1329             :   INST(Vphaddbq        , VexRm              , V(XOP_M9,C3,_,0,0,_,_,_  ), 0                         , 0 , 0 , 6931, 252, 132, 0 ),
+    1330             :   INST(Vphaddbw        , VexRm              , V(XOP_M9,C1,_,0,0,_,_,_  ), 0                         , 0 , 0 , 6940, 252, 132, 0 ),
+    1331             :   INST(Vphaddd         , VexRvm_Lx          , V(660F38,02,_,x,I,_,_,_  ), 0                         , 0 , 0 , 6949, 250, 135, 51),
+    1332             :   INST(Vphadddq        , VexRm              , V(XOP_M9,CB,_,0,0,_,_,_  ), 0                         , 0 , 0 , 6957, 252, 132, 0 ),
+    1333             :   INST(Vphaddsw        , VexRvm_Lx          , V(660F38,03,_,x,I,_,_,_  ), 0                         , 0 , 0 , 6966, 250, 135, 52),
+    1334             :   INST(Vphaddubd       , VexRm              , V(XOP_M9,D2,_,0,0,_,_,_  ), 0                         , 0 , 0 , 6975, 252, 132, 0 ),
+    1335             :   INST(Vphaddubq       , VexRm              , V(XOP_M9,D3,_,0,0,_,_,_  ), 0                         , 0 , 0 , 6985, 252, 132, 0 ),
+    1336             :   INST(Vphaddubw       , VexRm              , V(XOP_M9,D1,_,0,0,_,_,_  ), 0                         , 0 , 0 , 6995, 252, 132, 0 ),
+    1337             :   INST(Vphaddudq       , VexRm              , V(XOP_M9,DB,_,0,0,_,_,_  ), 0                         , 0 , 0 , 7005, 252, 132, 0 ),
+    1338             :   INST(Vphadduwd       , VexRm              , V(XOP_M9,D6,_,0,0,_,_,_  ), 0                         , 0 , 0 , 7015, 252, 132, 0 ),
+    1339             :   INST(Vphadduwq       , VexRm              , V(XOP_M9,D7,_,0,0,_,_,_  ), 0                         , 0 , 0 , 7025, 252, 132, 0 ),
+    1340             :   INST(Vphaddw         , VexRvm_Lx          , V(660F38,01,_,x,I,_,_,_  ), 0                         , 0 , 0 , 7035, 250, 135, 53),
+    1341             :   INST(Vphaddwd        , VexRm              , V(XOP_M9,C6,_,0,0,_,_,_  ), 0                         , 0 , 0 , 7043, 252, 132, 0 ),
+    1342             :   INST(Vphaddwq        , VexRm              , V(XOP_M9,C7,_,0,0,_,_,_  ), 0                         , 0 , 0 , 7052, 252, 132, 0 ),
+    1343             :   INST(Vphminposuw     , VexRm              , V(660F38,41,_,0,I,_,_,_  ), 0                         , 0 , 0 , 7061, 252, 118, 54),
+    1344             :   INST(Vphsubbw        , VexRm              , V(XOP_M9,E1,_,0,0,_,_,_  ), 0                         , 0 , 0 , 7073, 252, 132, 0 ),
+    1345             :   INST(Vphsubd         , VexRvm_Lx          , V(660F38,06,_,x,I,_,_,_  ), 0                         , 0 , 0 , 7082, 250, 135, 55),
+    1346             :   INST(Vphsubdq        , VexRm              , V(XOP_M9,E3,_,0,0,_,_,_  ), 0                         , 0 , 0 , 7090, 252, 132, 0 ),
+    1347             :   INST(Vphsubsw        , VexRvm_Lx          , V(660F38,07,_,x,I,_,_,_  ), 0                         , 0 , 0 , 7099, 250, 135, 56),
+    1348             :   INST(Vphsubw         , VexRvm_Lx          , V(660F38,05,_,x,I,_,_,_  ), 0                         , 0 , 0 , 7108, 250, 135, 56),
+    1349             :   INST(Vphsubwd        , VexRm              , V(XOP_M9,E2,_,0,0,_,_,_  ), 0                         , 0 , 0 , 7116, 252, 132, 0 ),
+    1350             :   INST(Vpinsrb         , VexRvmi            , V(660F3A,20,_,0,0,I,0,T1S), 0                         , 0 , 0 , 7125, 430, 143, 57),
+    1351             :   INST(Vpinsrd         , VexRvmi            , V(660F3A,22,_,0,0,0,2,T1S), 0                         , 0 , 0 , 7133, 431, 144, 57),
+    1352             :   INST(Vpinsrq         , VexRvmi            , V(660F3A,22,_,0,1,1,3,T1S), 0                         , 0 , 0 , 7141, 432, 144, 57),
+    1353             :   INST(Vpinsrw         , VexRvmi            , V(660F00,C4,_,0,0,I,1,T1S), 0                         , 0 , 0 , 7149, 433, 143, 55),
+    1354             :   INST(Vplzcntd        , VexRm_Lx           , V(660F38,44,_,x,_,0,4,FV ), 0                         , 0 , 0 , 7157, 411, 139, 0 ),
+    1355             :   INST(Vplzcntq        , VexRm_Lx           , V(660F38,44,_,x,_,1,4,FV ), 0                         , 0 , 0 , 7166, 434, 139, 0 ),
+    1356             :   INST(Vpmacsdd        , VexRvmr            , V(XOP_M8,9E,_,0,0,_,_,_  ), 0                         , 0 , 0 , 7175, 435, 132, 0 ),
+    1357             :   INST(Vpmacsdqh       , VexRvmr            , V(XOP_M8,9F,_,0,0,_,_,_  ), 0                         , 0 , 0 , 7184, 435, 132, 0 ),
+    1358             :   INST(Vpmacsdql       , VexRvmr            , V(XOP_M8,97,_,0,0,_,_,_  ), 0                         , 0 , 0 , 7194, 435, 132, 0 ),
+    1359             :   INST(Vpmacssdd       , VexRvmr            , V(XOP_M8,8E,_,0,0,_,_,_  ), 0                         , 0 , 0 , 7204, 435, 132, 0 ),
+    1360             :   INST(Vpmacssdqh      , VexRvmr            , V(XOP_M8,8F,_,0,0,_,_,_  ), 0                         , 0 , 0 , 7214, 435, 132, 0 ),
+    1361             :   INST(Vpmacssdql      , VexRvmr            , V(XOP_M8,87,_,0,0,_,_,_  ), 0                         , 0 , 0 , 7225, 435, 132, 0 ),
+    1362             :   INST(Vpmacsswd       , VexRvmr            , V(XOP_M8,86,_,0,0,_,_,_  ), 0                         , 0 , 0 , 7236, 435, 132, 0 ),
+    1363             :   INST(Vpmacssww       , VexRvmr            , V(XOP_M8,85,_,0,0,_,_,_  ), 0                         , 0 , 0 , 7246, 435, 132, 0 ),
+    1364             :   INST(Vpmacswd        , VexRvmr            , V(XOP_M8,96,_,0,0,_,_,_  ), 0                         , 0 , 0 , 7256, 435, 132, 0 ),
+    1365             :   INST(Vpmacsww        , VexRvmr            , V(XOP_M8,95,_,0,0,_,_,_  ), 0                         , 0 , 0 , 7265, 435, 132, 0 ),
+    1366             :   INST(Vpmadcsswd      , VexRvmr            , V(XOP_M8,A6,_,0,0,_,_,_  ), 0                         , 0 , 0 , 7274, 435, 132, 0 ),
+    1367             :   INST(Vpmadcswd       , VexRvmr            , V(XOP_M8,B6,_,0,0,_,_,_  ), 0                         , 0 , 0 , 7285, 435, 132, 0 ),
+    1368             :   INST(Vpmadd52huq     , VexRvm_Lx          , V(660F38,B5,_,x,_,1,4,FV ), 0                         , 0 , 0 , 7295, 262, 145, 0 ),
+    1369             :   INST(Vpmadd52luq     , VexRvm_Lx          , V(660F38,B4,_,x,_,1,4,FV ), 0                         , 0 , 0 , 7307, 262, 145, 0 ),
+    1370             :   INST(Vpmaddubsw      , VexRvm_Lx          , V(660F38,04,_,x,I,I,4,FVM), 0                         , 0 , 0 , 7319, 388, 137, 58),
+    1371             :   INST(Vpmaddwd        , VexRvm_Lx          , V(660F00,F5,_,x,I,I,4,FVM), 0                         , 0 , 0 , 7330, 388, 137, 58),
+    1372             :   INST(Vpmaskmovd      , VexRvmMvr_Lx       , V(660F38,8C,_,x,0,_,_,_  ), V(660F38,8E,_,x,0,_,_,_  ), 0 , 0 , 7339, 436, 124, 0 ),
+    1373             :   INST(Vpmaskmovq      , VexRvmMvr_Lx       , V(660F38,8C,_,x,1,_,_,_  ), V(660F38,8E,_,x,1,_,_,_  ), 0 , 0 , 7350, 437, 124, 0 ),
+    1374             :   INST(Vpmaxsb         , VexRvm_Lx          , V(660F38,3C,_,x,I,I,4,FVM), 0                         , 0 , 0 , 7361, 438, 137, 59),
+    1375             :   INST(Vpmaxsd         , VexRvm_Lx          , V(660F38,3D,_,x,I,0,4,FV ), 0                         , 0 , 0 , 7369, 259, 125, 59),
+    1376             :   INST(Vpmaxsq         , VexRvm_Lx          , V(660F38,3D,_,x,_,1,4,FV ), 0                         , 0 , 0 , 7377, 262, 120, 0 ),
+    1377             :   INST(Vpmaxsw         , VexRvm_Lx          , V(660F00,EE,_,x,I,I,4,FVM), 0                         , 0 , 0 , 7385, 438, 137, 60),
+    1378             :   INST(Vpmaxub         , VexRvm_Lx          , V(660F00,DE,_,x,I,I,4,FVM), 0                         , 0 , 0 , 7393, 438, 137, 60),
+    1379             :   INST(Vpmaxud         , VexRvm_Lx          , V(660F38,3F,_,x,I,0,4,FV ), 0                         , 0 , 0 , 7401, 259, 125, 60),
+    1380             :   INST(Vpmaxuq         , VexRvm_Lx          , V(660F38,3F,_,x,_,1,4,FV ), 0                         , 0 , 0 , 7409, 262, 120, 0 ),
+    1381             :   INST(Vpmaxuw         , VexRvm_Lx          , V(660F38,3E,_,x,I,I,4,FVM), 0                         , 0 , 0 , 7417, 438, 137, 61),
+    1382             :   INST(Vpminsb         , VexRvm_Lx          , V(660F38,38,_,x,I,I,4,FVM), 0                         , 0 , 0 , 7425, 438, 137, 61),
+    1383             :   INST(Vpminsd         , VexRvm_Lx          , V(660F38,39,_,x,I,0,4,FV ), 0                         , 0 , 0 , 7433, 259, 125, 61),
+    1384             :   INST(Vpminsq         , VexRvm_Lx          , V(660F38,39,_,x,_,1,4,FV ), 0                         , 0 , 0 , 7441, 262, 120, 0 ),
+    1385             :   INST(Vpminsw         , VexRvm_Lx          , V(660F00,EA,_,x,I,I,4,FVM), 0                         , 0 , 0 , 7449, 438, 137, 62),
+    1386             :   INST(Vpminub         , VexRvm_Lx          , V(660F00,DA,_,x,I,_,4,FVM), 0                         , 0 , 0 , 7457, 438, 137, 62),
+    1387             :   INST(Vpminud         , VexRvm_Lx          , V(660F38,3B,_,x,I,0,4,FV ), 0                         , 0 , 0 , 7465, 259, 125, 62),
+    1388             :   INST(Vpminuq         , VexRvm_Lx          , V(660F38,3B,_,x,_,1,4,FV ), 0                         , 0 , 0 , 7473, 262, 120, 0 ),
+    1389             :   INST(Vpminuw         , VexRvm_Lx          , V(660F38,3A,_,x,I,_,4,FVM), 0                         , 0 , 0 , 7481, 438, 137, 63),
+    1390             :   INST(Vpmovb2m        , VexRm_Lx           , V(F30F38,29,_,x,_,0,_,_  ), 0                         , 0 , 0 , 7489, 439, 122, 0 ),
+    1391             :   INST(Vpmovd2m        , VexRm_Lx           , V(F30F38,39,_,x,_,0,_,_  ), 0                         , 0 , 0 , 7498, 439, 123, 0 ),
+    1392             :   INST(Vpmovdb         , VexMr_Lx           , V(F30F38,31,_,x,_,0,2,QVM), 0                         , 0 , 0 , 7507, 440, 120, 0 ),
+    1393             :   INST(Vpmovdw         , VexMr_Lx           , V(F30F38,33,_,x,_,0,3,HVM), 0                         , 0 , 0 , 7515, 441, 120, 0 ),
+    1394             :   INST(Vpmovm2b        , VexRm_Lx           , V(F30F38,28,_,x,_,0,_,_  ), 0                         , 0 , 0 , 7523, 398, 122, 0 ),
+    1395             :   INST(Vpmovm2d        , VexRm_Lx           , V(F30F38,38,_,x,_,0,_,_  ), 0                         , 0 , 0 , 7532, 398, 123, 0 ),
+    1396             :   INST(Vpmovm2q        , VexRm_Lx           , V(F30F38,38,_,x,_,1,_,_  ), 0                         , 0 , 0 , 7541, 398, 123, 0 ),
+    1397             :   INST(Vpmovm2w        , VexRm_Lx           , V(F30F38,28,_,x,_,1,_,_  ), 0                         , 0 , 0 , 7550, 398, 122, 0 ),
+    1398             :   INST(Vpmovmskb       , VexRm_Lx           , V(660F00,D7,_,x,I,_,_,_  ), 0                         , 0 , 0 , 7559, 378, 135, 64),
+    1399             :   INST(Vpmovq2m        , VexRm_Lx           , V(F30F38,39,_,x,_,1,_,_  ), 0                         , 0 , 0 , 7569, 439, 123, 0 ),
+    1400             :   INST(Vpmovqb         , VexMr_Lx           , V(F30F38,32,_,x,_,0,1,OVM), 0                         , 0 , 0 , 7578, 442, 120, 0 ),
+    1401             :   INST(Vpmovqd         , VexMr_Lx           , V(F30F38,35,_,x,_,0,3,HVM), 0                         , 0 , 0 , 7586, 441, 120, 0 ),
+    1402             :   INST(Vpmovqw         , VexMr_Lx           , V(F30F38,34,_,x,_,0,2,QVM), 0                         , 0 , 0 , 7594, 440, 120, 0 ),
+    1403             :   INST(Vpmovsdb        , VexMr_Lx           , V(F30F38,21,_,x,_,0,2,QVM), 0                         , 0 , 0 , 7602, 440, 120, 0 ),
+    1404             :   INST(Vpmovsdw        , VexMr_Lx           , V(F30F38,23,_,x,_,0,3,HVM), 0                         , 0 , 0 , 7611, 441, 120, 0 ),
+    1405             :   INST(Vpmovsqb        , VexMr_Lx           , V(F30F38,22,_,x,_,0,1,OVM), 0                         , 0 , 0 , 7620, 442, 120, 0 ),
+    1406             :   INST(Vpmovsqd        , VexMr_Lx           , V(F30F38,25,_,x,_,0,3,HVM), 0                         , 0 , 0 , 7629, 441, 120, 0 ),
+    1407             :   INST(Vpmovsqw        , VexMr_Lx           , V(F30F38,24,_,x,_,0,2,QVM), 0                         , 0 , 0 , 7638, 440, 120, 0 ),
+    1408             :   INST(Vpmovswb        , VexMr_Lx           , V(F30F38,20,_,x,_,0,3,HVM), 0                         , 0 , 0 , 7647, 441, 122, 0 ),
+    1409             :   INST(Vpmovsxbd       , VexRm_Lx           , V(660F38,21,_,x,I,I,2,QVM), 0                         , 0 , 0 , 7656, 443, 125, 14),
+    1410             :   INST(Vpmovsxbq       , VexRm_Lx           , V(660F38,22,_,x,I,I,1,OVM), 0                         , 0 , 0 , 7666, 444, 125, 14),
+    1411             :   INST(Vpmovsxbw       , VexRm_Lx           , V(660F38,20,_,x,I,I,3,HVM), 0                         , 0 , 0 , 7676, 445, 137, 14),
+    1412             :   INST(Vpmovsxdq       , VexRm_Lx           , V(660F38,25,_,x,I,0,3,HVM), 0                         , 0 , 0 , 7686, 446, 125, 14),
+    1413             :   INST(Vpmovsxwd       , VexRm_Lx           , V(660F38,23,_,x,I,I,3,HVM), 0                         , 0 , 0 , 7696, 445, 125, 14),
+    1414             :   INST(Vpmovsxwq       , VexRm_Lx           , V(660F38,24,_,x,I,I,2,QVM), 0                         , 0 , 0 , 7706, 443, 125, 14),
+    1415             :   INST(Vpmovusdb       , VexMr_Lx           , V(F30F38,11,_,x,_,0,2,QVM), 0                         , 0 , 0 , 7716, 440, 120, 0 ),
+    1416             :   INST(Vpmovusdw       , VexMr_Lx           , V(F30F38,13,_,x,_,0,3,HVM), 0                         , 0 , 0 , 7726, 441, 120, 0 ),
+    1417             :   INST(Vpmovusqb       , VexMr_Lx           , V(F30F38,12,_,x,_,0,1,OVM), 0                         , 0 , 0 , 7736, 442, 120, 0 ),
+    1418             :   INST(Vpmovusqd       , VexMr_Lx           , V(F30F38,15,_,x,_,0,3,HVM), 0                         , 0 , 0 , 7746, 441, 120, 0 ),
+    1419             :   INST(Vpmovusqw       , VexMr_Lx           , V(F30F38,14,_,x,_,0,2,QVM), 0                         , 0 , 0 , 7756, 440, 120, 0 ),
+    1420             :   INST(Vpmovuswb       , VexMr_Lx           , V(F30F38,10,_,x,_,0,3,HVM), 0                         , 0 , 0 , 7766, 441, 122, 0 ),
+    1421             :   INST(Vpmovw2m        , VexRm_Lx           , V(F30F38,29,_,x,_,1,_,_  ), 0                         , 0 , 0 , 7776, 439, 122, 0 ),
+    1422             :   INST(Vpmovwb         , VexMr_Lx           , V(F30F38,30,_,x,_,0,3,HVM), 0                         , 0 , 0 , 7785, 441, 122, 0 ),
+    1423             :   INST(Vpmovzxbd       , VexRm_Lx           , V(660F38,31,_,x,I,I,2,QVM), 0                         , 0 , 0 , 7793, 443, 125, 65),
+    1424             :   INST(Vpmovzxbq       , VexRm_Lx           , V(660F38,32,_,x,I,I,1,OVM), 0                         , 0 , 0 , 7803, 444, 125, 65),
+    1425             :   INST(Vpmovzxbw       , VexRm_Lx           , V(660F38,30,_,x,I,I,3,HVM), 0                         , 0 , 0 , 7813, 445, 137, 65),
+    1426             :   INST(Vpmovzxdq       , VexRm_Lx           , V(660F38,35,_,x,I,0,3,HVM), 0                         , 0 , 0 , 7823, 446, 125, 65),
+    1427             :   INST(Vpmovzxwd       , VexRm_Lx           , V(660F38,33,_,x,I,I,3,HVM), 0                         , 0 , 0 , 7833, 445, 125, 65),
+    1428             :   INST(Vpmovzxwq       , VexRm_Lx           , V(660F38,34,_,x,I,I,2,QVM), 0                         , 0 , 0 , 7843, 443, 125, 65),
+    1429             :   INST(Vpmuldq         , VexRvm_Lx          , V(660F38,28,_,x,I,1,4,FV ), 0                         , 0 , 0 , 7853, 256, 125, 19),
+    1430             :   INST(Vpmulhrsw       , VexRvm_Lx          , V(660F38,0B,_,x,I,I,4,FVM), 0                         , 0 , 0 , 7861, 388, 137, 19),
+    1431             :   INST(Vpmulhuw        , VexRvm_Lx          , V(660F00,E4,_,x,I,I,4,FVM), 0                         , 0 , 0 , 7871, 388, 137, 66),
+    1432             :   INST(Vpmulhw         , VexRvm_Lx          , V(660F00,E5,_,x,I,I,4,FVM), 0                         , 0 , 0 , 7880, 388, 137, 66),
+    1433             :   INST(Vpmulld         , VexRvm_Lx          , V(660F38,40,_,x,I,0,4,FV ), 0                         , 0 , 0 , 7888, 257, 125, 66),
+    1434             :   INST(Vpmullq         , VexRvm_Lx          , V(660F38,40,_,x,_,1,4,FV ), 0                         , 0 , 0 , 7896, 262, 123, 0 ),
+    1435             :   INST(Vpmullw         , VexRvm_Lx          , V(660F00,D5,_,x,I,I,4,FVM), 0                         , 0 , 0 , 7904, 388, 137, 19),
+    1436             :   INST(Vpmultishiftqb  , VexRvm_Lx          , V(660F38,83,_,x,_,1,4,FV ), 0                         , 0 , 0 , 7912, 262, 142, 0 ),
+    1437             :   INST(Vpmuludq        , VexRvm_Lx          , V(660F00,F4,_,x,I,1,4,FV ), 0                         , 0 , 0 , 7927, 256, 125, 67),
+    1438             :   INST(Vpopcntd        , VexRm              , V(660F38,55,_,2,_,0,4,FVM), 0                         , 0 , 0 , 7936, 447, 146, 0 ),
+    1439             :   INST(Vpopcntq        , VexRm              , V(660F38,55,_,2,_,1,4,FVM), 0                         , 0 , 0 , 7945, 448, 146, 0 ),
+    1440             :   INST(Vpor            , VexRvm_Lx          , V(660F00,EB,_,x,I,_,_,_  ), 0                         , 0 , 0 , 7954, 390, 135, 68),
+    1441             :   INST(Vpord           , VexRvm_Lx          , V(660F00,EB,_,x,_,0,4,FV ), 0                         , 0 , 0 , 7959, 391, 120, 0 ),
+    1442             :   INST(Vporq           , VexRvm_Lx          , V(660F00,EB,_,x,_,1,4,FV ), 0                         , 0 , 0 , 7965, 395, 120, 0 ),
+    1443             :   INST(Vpperm          , VexRvrmRvmr        , V(XOP_M8,A3,_,0,x,_,_,_  ), 0                         , 0 , 0 , 7971, 449, 132, 0 ),
+    1444             :   INST(Vprold          , VexVmi_Lx          , V(660F00,72,1,x,_,0,4,FV ), 0                         , 0 , 0 , 7978, 450, 120, 0 ),
+    1445             :   INST(Vprolq          , VexVmi_Lx          , V(660F00,72,1,x,_,1,4,FV ), 0                         , 0 , 0 , 7985, 451, 120, 0 ),
+    1446             :   INST(Vprolvd         , VexRvm_Lx          , V(660F38,15,_,x,_,0,4,FV ), 0                         , 0 , 0 , 7992, 261, 120, 0 ),
+    1447             :   INST(Vprolvq         , VexRvm_Lx          , V(660F38,15,_,x,_,1,4,FV ), 0                         , 0 , 0 , 8000, 262, 120, 0 ),
+    1448             :   INST(Vprord          , VexVmi_Lx          , V(660F00,72,0,x,_,0,4,FV ), 0                         , 0 , 0 , 8008, 450, 120, 0 ),
+    1449             :   INST(Vprorq          , VexVmi_Lx          , V(660F00,72,0,x,_,1,4,FV ), 0                         , 0 , 0 , 8015, 451, 120, 0 ),
+    1450             :   INST(Vprorvd         , VexRvm_Lx          , V(660F38,14,_,x,_,0,4,FV ), 0                         , 0 , 0 , 8022, 261, 120, 0 ),
+    1451             :   INST(Vprorvq         , VexRvm_Lx          , V(660F38,14,_,x,_,1,4,FV ), 0                         , 0 , 0 , 8030, 262, 120, 0 ),
+    1452             :   INST(Vprotb          , VexRvmRmvRmi       , V(XOP_M9,90,_,0,x,_,_,_  ), V(XOP_M8,C0,_,0,x,_,_,_  ), 0 , 0 , 8038, 452, 132, 0 ),
+    1453             :   INST(Vprotd          , VexRvmRmvRmi       , V(XOP_M9,92,_,0,x,_,_,_  ), V(XOP_M8,C2,_,0,x,_,_,_  ), 0 , 0 , 8045, 453, 132, 0 ),
+    1454             :   INST(Vprotq          , VexRvmRmvRmi       , V(XOP_M9,93,_,0,x,_,_,_  ), V(XOP_M8,C3,_,0,x,_,_,_  ), 0 , 0 , 8052, 454, 132, 0 ),
+    1455             :   INST(Vprotw          , VexRvmRmvRmi       , V(XOP_M9,91,_,0,x,_,_,_  ), V(XOP_M8,C1,_,0,x,_,_,_  ), 0 , 0 , 8059, 455, 132, 0 ),
+    1456             :   INST(Vpsadbw         , VexRvm_Lx          , V(660F00,F6,_,x,I,I,4,FVM), 0                         , 0 , 0 , 8066, 456, 137, 69),
+    1457             :   INST(Vpscatterdd     , VexMr_VM           , V(660F38,A0,_,x,_,0,2,T1S), 0                         , 0 , 0 , 8074, 457, 120, 0 ),
+    1458             :   INST(Vpscatterdq     , VexMr_VM           , V(660F38,A0,_,x,_,1,3,T1S), 0                         , 0 , 0 , 8086, 457, 120, 0 ),
+    1459             :   INST(Vpscatterqd     , VexMr_VM           , V(660F38,A1,_,x,_,0,2,T1S), 0                         , 0 , 0 , 8098, 458, 120, 0 ),
+    1460             :   INST(Vpscatterqq     , VexMr_VM           , V(660F38,A1,_,x,_,1,3,T1S), 0                         , 0 , 0 , 8110, 459, 120, 0 ),
+    1461             :   INST(Vpshab          , VexRvmRmv          , V(XOP_M9,98,_,0,x,_,_,_  ), 0                         , 0 , 0 , 8122, 460, 132, 0 ),
+    1462             :   INST(Vpshad          , VexRvmRmv          , V(XOP_M9,9A,_,0,x,_,_,_  ), 0                         , 0 , 0 , 8129, 460, 132, 0 ),
+    1463             :   INST(Vpshaq          , VexRvmRmv          , V(XOP_M9,9B,_,0,x,_,_,_  ), 0                         , 0 , 0 , 8136, 460, 132, 0 ),
+    1464             :   INST(Vpshaw          , VexRvmRmv          , V(XOP_M9,99,_,0,x,_,_,_  ), 0                         , 0 , 0 , 8143, 460, 132, 0 ),
+    1465             :   INST(Vpshlb          , VexRvmRmv          , V(XOP_M9,94,_,0,x,_,_,_  ), 0                         , 0 , 0 , 8150, 460, 132, 0 ),
+    1466             :   INST(Vpshld          , VexRvmRmv          , V(XOP_M9,96,_,0,x,_,_,_  ), 0                         , 0 , 0 , 8157, 460, 132, 0 ),
+    1467             :   INST(Vpshlq          , VexRvmRmv          , V(XOP_M9,97,_,0,x,_,_,_  ), 0                         , 0 , 0 , 8164, 460, 132, 0 ),
+    1468             :   INST(Vpshlw          , VexRvmRmv          , V(XOP_M9,95,_,0,x,_,_,_  ), 0                         , 0 , 0 , 8171, 460, 132, 0 ),
+    1469             :   INST(Vpshufb         , VexRvm_Lx          , V(660F38,00,_,x,I,I,4,FVM), 0                         , 0 , 0 , 8178, 388, 137, 70),
+    1470             :   INST(Vpshufd         , VexRmi_Lx          , V(660F00,70,_,x,I,0,4,FV ), 0                         , 0 , 0 , 8186, 461, 125, 71),
+    1471             :   INST(Vpshufhw        , VexRmi_Lx          , V(F30F00,70,_,x,I,I,4,FVM), 0                         , 0 , 0 , 8194, 462, 137, 71),
+    1472             :   INST(Vpshuflw        , VexRmi_Lx          , V(F20F00,70,_,x,I,I,4,FVM), 0                         , 0 , 0 , 8203, 462, 137, 71),
+    1473             :   INST(Vpsignb         , VexRvm_Lx          , V(660F38,08,_,x,I,_,_,_  ), 0                         , 0 , 0 , 8212, 250, 135, 72),
+    1474             :   INST(Vpsignd         , VexRvm_Lx          , V(660F38,0A,_,x,I,_,_,_  ), 0                         , 0 , 0 , 8220, 250, 135, 72),
+    1475             :   INST(Vpsignw         , VexRvm_Lx          , V(660F38,09,_,x,I,_,_,_  ), 0                         , 0 , 0 , 8228, 250, 135, 72),
+    1476             :   INST(Vpslld          , VexRvmVmi_Lx       , V(660F00,F2,_,x,I,0,4,128), V(660F00,72,6,x,I,0,4,FV ), 0 , 0 , 8236, 463, 125, 72),
+    1477             :   INST(Vpslldq         , VexEvexVmi_Lx      , V(660F00,73,7,x,I,I,4,FVM), 0                         , 0 , 0 , 8243, 464, 137, 72),
+    1478             :   INST(Vpsllq          , VexRvmVmi_Lx       , V(660F00,F3,_,x,I,1,4,128), V(660F00,73,6,x,I,1,4,FV ), 0 , 0 , 8251, 465, 125, 72),
+    1479             :   INST(Vpsllvd         , VexRvm_Lx          , V(660F38,47,_,x,0,0,4,FV ), 0                         , 0 , 0 , 8258, 257, 133, 0 ),
+    1480             :   INST(Vpsllvq         , VexRvm_Lx          , V(660F38,47,_,x,1,1,4,FV ), 0                         , 0 , 0 , 8266, 256, 133, 0 ),
+    1481             :   INST(Vpsllvw         , VexRvm_Lx          , V(660F38,12,_,x,_,1,4,FVM), 0                         , 0 , 0 , 8274, 260, 122, 0 ),
+    1482             :   INST(Vpsllw          , VexRvmVmi_Lx       , V(660F00,F1,_,x,I,I,4,FVM), V(660F00,71,6,x,I,I,4,FVM), 0 , 0 , 8282, 466, 137, 73),
+    1483             :   INST(Vpsrad          , VexRvmVmi_Lx       , V(660F00,E2,_,x,I,0,4,128), V(660F00,72,4,x,I,0,4,FV ), 0 , 0 , 8289, 467, 125, 73),
+    1484             :   INST(Vpsraq          , VexRvmVmi_Lx       , V(660F00,E2,_,x,_,1,4,128), V(660F00,72,4,x,_,1,4,FV ), 0 , 0 , 8296, 468, 120, 0 ),
+    1485             :   INST(Vpsravd         , VexRvm_Lx          , V(660F38,46,_,x,0,0,4,FV ), 0                         , 0 , 0 , 8303, 257, 133, 0 ),
+    1486             :   INST(Vpsravq         , VexRvm_Lx          , V(660F38,46,_,x,_,1,4,FV ), 0                         , 0 , 0 , 8311, 262, 120, 0 ),
+    1487             :   INST(Vpsravw         , VexRvm_Lx          , V(660F38,11,_,x,_,1,4,FVM), 0                         , 0 , 0 , 8319, 260, 122, 0 ),
+    1488             :   INST(Vpsraw          , VexRvmVmi_Lx       , V(660F00,E1,_,x,I,I,4,128), V(660F00,71,4,x,I,I,4,FVM), 0 , 0 , 8327, 469, 137, 74),
+    1489             :   INST(Vpsrld          , VexRvmVmi_Lx       , V(660F00,D2,_,x,I,0,4,128), V(660F00,72,2,x,I,0,4,FV ), 0 , 0 , 8334, 470, 125, 74),
+    1490             :   INST(Vpsrldq         , VexEvexVmi_Lx      , V(660F00,73,3,x,I,I,4,FVM), 0                         , 0 , 0 , 8341, 464, 137, 74),
+    1491             :   INST(Vpsrlq          , VexRvmVmi_Lx       , V(660F00,D3,_,x,I,1,4,128), V(660F00,73,2,x,I,1,4,FV ), 0 , 0 , 8349, 471, 125, 74),
+    1492             :   INST(Vpsrlvd         , VexRvm_Lx          , V(660F38,45,_,x,0,0,4,FV ), 0                         , 0 , 0 , 8356, 257, 133, 0 ),
+    1493             :   INST(Vpsrlvq         , VexRvm_Lx          , V(660F38,45,_,x,1,1,4,FV ), 0                         , 0 , 0 , 8364, 256, 133, 0 ),
+    1494             :   INST(Vpsrlvw         , VexRvm_Lx          , V(660F38,10,_,x,_,1,4,FVM), 0                         , 0 , 0 , 8372, 260, 122, 0 ),
+    1495             :   INST(Vpsrlw          , VexRvmVmi_Lx       , V(660F00,D1,_,x,I,I,4,128), V(660F00,71,2,x,I,I,4,FVM), 0 , 0 , 8380, 472, 137, 75),
+    1496             :   INST(Vpsubb          , VexRvm_Lx          , V(660F00,F8,_,x,I,I,4,FVM), 0                         , 0 , 0 , 8387, 473, 137, 75),
+    1497             :   INST(Vpsubd          , VexRvm_Lx          , V(660F00,FA,_,x,I,0,4,FV ), 0                         , 0 , 0 , 8394, 474, 125, 75),
+    1498             :   INST(Vpsubq          , VexRvm_Lx          , V(660F00,FB,_,x,I,1,4,FV ), 0                         , 0 , 0 , 8401, 475, 125, 75),
+    1499             :   INST(Vpsubsb         , VexRvm_Lx          , V(660F00,E8,_,x,I,I,4,FVM), 0                         , 0 , 0 , 8408, 473, 137, 75),
+    1500             :   INST(Vpsubsw         , VexRvm_Lx          , V(660F00,E9,_,x,I,I,4,FVM), 0                         , 0 , 0 , 8416, 473, 137, 75),
+    1501             :   INST(Vpsubusb        , VexRvm_Lx          , V(660F00,D8,_,x,I,I,4,FVM), 0                         , 0 , 0 , 8424, 473, 137, 75),
+    1502             :   INST(Vpsubusw        , VexRvm_Lx          , V(660F00,D9,_,x,I,I,4,FVM), 0                         , 0 , 0 , 8433, 473, 137, 75),
+    1503             :   INST(Vpsubw          , VexRvm_Lx          , V(660F00,F9,_,x,I,I,4,FVM), 0                         , 0 , 0 , 8442, 473, 137, 75),
+    1504             :   INST(Vpternlogd      , VexRvmi_Lx         , V(660F3A,25,_,x,_,0,4,FV ), 0                         , 0 , 0 , 8449, 476, 120, 0 ),
+    1505             :   INST(Vpternlogq      , VexRvmi_Lx         , V(660F3A,25,_,x,_,1,4,FV ), 0                         , 0 , 0 , 8460, 477, 120, 0 ),
+    1506             :   INST(Vptest          , VexRm_Lx           , V(660F38,17,_,x,I,_,_,_  ), 0                         , 0 , 0 , 8471, 478, 141, 76),
+    1507             :   INST(Vptestmb        , VexRvm_Lx          , V(660F38,26,_,x,_,0,4,FVM), 0                         , 0 , 0 , 8478, 479, 122, 0 ),
+    1508             :   INST(Vptestmd        , VexRvm_Lx          , V(660F38,27,_,x,_,0,4,FV ), 0                         , 0 , 0 , 8487, 480, 120, 0 ),
+    1509             :   INST(Vptestmq        , VexRvm_Lx          , V(660F38,27,_,x,_,1,4,FV ), 0                         , 0 , 0 , 8496, 481, 120, 0 ),
+    1510             :   INST(Vptestmw        , VexRvm_Lx          , V(660F38,26,_,x,_,1,4,FVM), 0                         , 0 , 0 , 8505, 479, 122, 0 ),
+    1511             :   INST(Vptestnmb       , VexRvm_Lx          , V(F30F38,26,_,x,_,0,4,FVM), 0                         , 0 , 0 , 8514, 479, 122, 0 ),
+    1512             :   INST(Vptestnmd       , VexRvm_Lx          , V(F30F38,27,_,x,_,0,4,FV ), 0                         , 0 , 0 , 8524, 480, 120, 0 ),
+    1513             :   INST(Vptestnmq       , VexRvm_Lx          , V(F30F38,27,_,x,_,1,4,FV ), 0                         , 0 , 0 , 8534, 481, 120, 0 ),
+    1514             :   INST(Vptestnmw       , VexRvm_Lx          , V(F30F38,26,_,x,_,1,4,FVM), 0                         , 0 , 0 , 8544, 479, 122, 0 ),
+    1515             :   INST(Vpunpckhbw      , VexRvm_Lx          , V(660F00,68,_,x,I,I,4,FVM), 0                         , 0 , 0 , 8554, 388, 137, 77),
+    1516             :   INST(Vpunpckhdq      , VexRvm_Lx          , V(660F00,6A,_,x,I,0,4,FV ), 0                         , 0 , 0 , 8565, 257, 125, 77),
+    1517             :   INST(Vpunpckhqdq     , VexRvm_Lx          , V(660F00,6D,_,x,I,1,4,FV ), 0                         , 0 , 0 , 8576, 256, 125, 77),
+    1518             :   INST(Vpunpckhwd      , VexRvm_Lx          , V(660F00,69,_,x,I,I,4,FVM), 0                         , 0 , 0 , 8588, 388, 137, 77),
+    1519             :   INST(Vpunpcklbw      , VexRvm_Lx          , V(660F00,60,_,x,I,I,4,FVM), 0                         , 0 , 0 , 8599, 388, 137, 77),
+    1520             :   INST(Vpunpckldq      , VexRvm_Lx          , V(660F00,62,_,x,I,0,4,FV ), 0                         , 0 , 0 , 8610, 257, 125, 77),
+    1521             :   INST(Vpunpcklqdq     , VexRvm_Lx          , V(660F00,6C,_,x,I,1,4,FV ), 0                         , 0 , 0 , 8621, 256, 125, 77),
+    1522             :   INST(Vpunpcklwd      , VexRvm_Lx          , V(660F00,61,_,x,I,I,4,FVM), 0                         , 0 , 0 , 8633, 388, 137, 77),
+    1523             :   INST(Vpxor           , VexRvm_Lx          , V(660F00,EF,_,x,I,_,_,_  ), 0                         , 0 , 0 , 8644, 392, 135, 78),
+    1524             :   INST(Vpxord          , VexRvm_Lx          , V(660F00,EF,_,x,_,0,4,FV ), 0                         , 0 , 0 , 8650, 393, 120, 0 ),
+    1525             :   INST(Vpxorq          , VexRvm_Lx          , V(660F00,EF,_,x,_,1,4,FV ), 0                         , 0 , 0 , 8657, 394, 120, 0 ),
+    1526             :   INST(Vrangepd        , VexRvmi_Lx         , V(660F3A,50,_,x,_,1,4,FV ), 0                         , 0 , 0 , 8664, 482, 123, 0 ),
+    1527             :   INST(Vrangeps        , VexRvmi_Lx         , V(660F3A,50,_,x,_,0,4,FV ), 0                         , 0 , 0 , 8673, 483, 123, 0 ),
+    1528             :   INST(Vrangesd        , VexRvmi            , V(660F3A,51,_,I,_,1,3,T1S), 0                         , 0 , 0 , 8682, 484, 63 , 0 ),
+    1529             :   INST(Vrangess        , VexRvmi            , V(660F3A,51,_,I,_,0,2,T1S), 0                         , 0 , 0 , 8691, 485, 63 , 0 ),
+    1530             :   INST(Vrcp14pd        , VexRm_Lx           , V(660F38,4C,_,x,_,1,4,FV ), 0                         , 0 , 0 , 8700, 434, 120, 0 ),
+    1531             :   INST(Vrcp14ps        , VexRm_Lx           , V(660F38,4C,_,x,_,0,4,FV ), 0                         , 0 , 0 , 8709, 411, 120, 0 ),
+    1532             :   INST(Vrcp14sd        , VexRvm             , V(660F38,4D,_,I,_,1,3,T1S), 0                         , 0 , 0 , 8718, 486, 65 , 0 ),
+    1533             :   INST(Vrcp14ss        , VexRvm             , V(660F38,4D,_,I,_,0,2,T1S), 0                         , 0 , 0 , 8727, 487, 65 , 0 ),
+    1534             :   INST(Vrcp28pd        , VexRm              , V(660F38,CA,_,2,_,1,4,FV ), 0                         , 0 , 0 , 8736, 311, 128, 0 ),
+    1535             :   INST(Vrcp28ps        , VexRm              , V(660F38,CA,_,2,_,0,4,FV ), 0                         , 0 , 0 , 8745, 312, 128, 0 ),
+    1536             :   INST(Vrcp28sd        , VexRvm             , V(660F38,CB,_,I,_,1,3,T1S), 0                         , 0 , 0 , 8754, 488, 128, 0 ),
+    1537             :   INST(Vrcp28ss        , VexRvm             , V(660F38,CB,_,I,_,0,2,T1S), 0                         , 0 , 0 , 8763, 489, 128, 0 ),
+    1538             :   INST(Vrcpps          , VexRm_Lx           , V(000F00,53,_,x,I,_,_,_  ), 0                         , 0 , 0 , 8772, 333, 118, 79),
+    1539             :   INST(Vrcpss          , VexRvm             , V(F30F00,53,_,I,I,_,_,_  ), 0                         , 0 , 0 , 8779, 490, 118, 80),
+    1540             :   INST(Vreducepd       , VexRmi_Lx          , V(660F3A,56,_,x,_,1,4,FV ), 0                         , 0 , 0 , 8786, 451, 123, 0 ),
+    1541             :   INST(Vreduceps       , VexRmi_Lx          , V(660F3A,56,_,x,_,0,4,FV ), 0                         , 0 , 0 , 8796, 450, 123, 0 ),
+    1542             :   INST(Vreducesd       , VexRvmi            , V(660F3A,57,_,I,_,1,3,T1S), 0                         , 0 , 0 , 8806, 491, 63 , 0 ),
+    1543             :   INST(Vreducess       , VexRvmi            , V(660F3A,57,_,I,_,0,2,T1S), 0                         , 0 , 0 , 8816, 492, 63 , 0 ),
+    1544             :   INST(Vrndscalepd     , VexRmi_Lx          , V(660F3A,09,_,x,_,1,4,FV ), 0                         , 0 , 0 , 8826, 345, 120, 0 ),
+    1545             :   INST(Vrndscaleps     , VexRmi_Lx          , V(660F3A,08,_,x,_,0,4,FV ), 0                         , 0 , 0 , 8838, 346, 120, 0 ),
+    1546             :   INST(Vrndscalesd     , VexRvmi            , V(660F3A,0B,_,I,_,1,3,T1S), 0                         , 0 , 0 , 8850, 484, 65 , 0 ),
+    1547             :   INST(Vrndscaless     , VexRvmi            , V(660F3A,0A,_,I,_,0,2,T1S), 0                         , 0 , 0 , 8862, 485, 65 , 0 ),
+    1548             :   INST(Vroundpd        , VexRmi_Lx          , V(660F3A,09,_,x,I,_,_,_  ), 0                         , 0 , 0 , 8874, 493, 118, 81),
+    1549             :   INST(Vroundps        , VexRmi_Lx          , V(660F3A,08,_,x,I,_,_,_  ), 0                         , 0 , 0 , 8883, 493, 118, 81),
+    1550             :   INST(Vroundsd        , VexRvmi            , V(660F3A,0B,_,I,I,_,_,_  ), 0                         , 0 , 0 , 8892, 494, 118, 82),
+    1551             :   INST(Vroundss        , VexRvmi            , V(660F3A,0A,_,I,I,_,_,_  ), 0                         , 0 , 0 , 8901, 495, 118, 82),
+    1552             :   INST(Vrsqrt14pd      , VexRm_Lx           , V(660F38,4E,_,x,_,1,4,FV ), 0                         , 0 , 0 , 8910, 434, 120, 0 ),
+    1553             :   INST(Vrsqrt14ps      , VexRm_Lx           , V(660F38,4E,_,x,_,0,4,FV ), 0                         , 0 , 0 , 8921, 411, 120, 0 ),
+    1554             :   INST(Vrsqrt14sd      , VexRvm             , V(660F38,4F,_,I,_,1,3,T1S), 0                         , 0 , 0 , 8932, 486, 65 , 0 ),
+    1555             :   INST(Vrsqrt14ss      , VexRvm             , V(660F38,4F,_,I,_,0,2,T1S), 0                         , 0 , 0 , 8943, 487, 65 , 0 ),
+    1556             :   INST(Vrsqrt28pd      , VexRm              , V(660F38,CC,_,2,_,1,4,FV ), 0                         , 0 , 0 , 8954, 311, 128, 0 ),
+    1557             :   INST(Vrsqrt28ps      , VexRm              , V(660F38,CC,_,2,_,0,4,FV ), 0                         , 0 , 0 , 8965, 312, 128, 0 ),
+    1558             :   INST(Vrsqrt28sd      , VexRvm             , V(660F38,CD,_,I,_,1,3,T1S), 0                         , 0 , 0 , 8976, 488, 128, 0 ),
+    1559             :   INST(Vrsqrt28ss      , VexRvm             , V(660F38,CD,_,I,_,0,2,T1S), 0                         , 0 , 0 , 8987, 489, 128, 0 ),
+    1560             :   INST(Vrsqrtps        , VexRm_Lx           , V(000F00,52,_,x,I,_,_,_  ), 0                         , 0 , 0 , 8998, 333, 118, 3 ),
+    1561             :   INST(Vrsqrtss        , VexRvm             , V(F30F00,52,_,I,I,_,_,_  ), 0                         , 0 , 0 , 9007, 490, 118, 2 ),
+    1562             :   INST(Vscalefpd       , VexRvm_Lx          , V(660F38,2C,_,x,_,1,4,FV ), 0                         , 0 , 0 , 9016, 496, 120, 0 ),
+    1563             :   INST(Vscalefps       , VexRvm_Lx          , V(660F38,2C,_,x,_,0,4,FV ), 0                         , 0 , 0 , 9026, 497, 120, 0 ),
+    1564             :   INST(Vscalefsd       , VexRvm             , V(660F38,2D,_,I,_,1,3,T1S), 0                         , 0 , 0 , 9036, 498, 65 , 0 ),
+    1565             :   INST(Vscalefss       , VexRvm             , V(660F38,2D,_,I,_,0,2,T1S), 0                         , 0 , 0 , 9046, 499, 65 , 0 ),
+    1566             :   INST(Vscatterdpd     , VexMr_Lx           , V(660F38,A2,_,x,_,1,3,T1S), 0                         , 0 , 0 , 9056, 500, 120, 0 ),
+    1567             :   INST(Vscatterdps     , VexMr_Lx           , V(660F38,A2,_,x,_,0,2,T1S), 0                         , 0 , 0 , 9068, 457, 120, 0 ),
+    1568             :   INST(Vscatterpf0dpd  , VexM_VM            , V(660F38,C6,5,2,_,1,3,T1S), 0                         , 0 , 0 , 9080, 338, 134, 0 ),
+    1569             :   INST(Vscatterpf0dps  , VexM_VM            , V(660F38,C6,5,2,_,0,2,T1S), 0                         , 0 , 0 , 9095, 339, 134, 0 ),
+    1570             :   INST(Vscatterpf0qpd  , VexM_VM            , V(660F38,C7,5,2,_,1,3,T1S), 0                         , 0 , 0 , 9110, 340, 134, 0 ),
+    1571             :   INST(Vscatterpf0qps  , VexM_VM            , V(660F38,C7,5,2,_,0,2,T1S), 0                         , 0 , 0 , 9125, 340, 134, 0 ),
+    1572             :   INST(Vscatterpf1dpd  , VexM_VM            , V(660F38,C6,6,2,_,1,3,T1S), 0                         , 0 , 0 , 9140, 338, 134, 0 ),
+    1573             :   INST(Vscatterpf1dps  , VexM_VM            , V(660F38,C6,6,2,_,0,2,T1S), 0                         , 0 , 0 , 9155, 339, 134, 0 ),
+    1574             :   INST(Vscatterpf1qpd  , VexM_VM            , V(660F38,C7,6,2,_,1,3,T1S), 0                         , 0 , 0 , 9170, 340, 134, 0 ),
+    1575             :   INST(Vscatterpf1qps  , VexM_VM            , V(660F38,C7,6,2,_,0,2,T1S), 0                         , 0 , 0 , 9185, 340, 134, 0 ),
+    1576             :   INST(Vscatterqpd     , VexMr_Lx           , V(660F38,A3,_,x,_,1,3,T1S), 0                         , 0 , 0 , 9200, 459, 120, 0 ),
+    1577             :   INST(Vscatterqps     , VexMr_Lx           , V(660F38,A3,_,x,_,0,2,T1S), 0                         , 0 , 0 , 9212, 458, 120, 0 ),
+    1578             :   INST(Vshuff32x4      , VexRvmi_Lx         , V(660F3A,23,_,x,_,0,4,FV ), 0                         , 0 , 0 , 9224, 501, 120, 0 ),
+    1579             :   INST(Vshuff64x2      , VexRvmi_Lx         , V(660F3A,23,_,x,_,1,4,FV ), 0                         , 0 , 0 , 9235, 502, 120, 0 ),
+    1580             :   INST(Vshufi32x4      , VexRvmi_Lx         , V(660F3A,43,_,x,_,0,4,FV ), 0                         , 0 , 0 , 9246, 501, 120, 0 ),
+    1581             :   INST(Vshufi64x2      , VexRvmi_Lx         , V(660F3A,43,_,x,_,1,4,FV ), 0                         , 0 , 0 , 9257, 502, 120, 0 ),
+    1582             :   INST(Vshufpd         , VexRvmi_Lx         , V(660F00,C6,_,x,I,1,4,FV ), 0                         , 0 , 0 , 9268, 503, 116, 83),
+    1583             :   INST(Vshufps         , VexRvmi_Lx         , V(000F00,C6,_,x,I,0,4,FV ), 0                         , 0 , 0 , 9276, 504, 116, 83),
+    1584             :   INST(Vsqrtpd         , VexRm_Lx           , V(660F00,51,_,x,I,1,4,FV ), 0                         , 0 , 0 , 9284, 505, 116, 84),
+    1585             :   INST(Vsqrtps         , VexRm_Lx           , V(000F00,51,_,x,I,0,4,FV ), 0                         , 0 , 0 , 9292, 281, 116, 84),
+    1586             :   INST(Vsqrtsd         , VexRvm             , V(F20F00,51,_,I,I,1,3,T1S), 0                         , 0 , 0 , 9300, 248, 117, 85),
+    1587             :   INST(Vsqrtss         , VexRvm             , V(F30F00,51,_,I,I,0,2,T1S), 0                         , 0 , 0 , 9308, 249, 117, 85),
+    1588             :   INST(Vstmxcsr        , VexM               , V(000F00,AE,3,0,I,_,_,_  ), 0                         , 0 , 0 , 9316, 506, 118, 0 ),
+    1589             :   INST(Vsubpd          , VexRvm_Lx          , V(660F00,5C,_,x,I,1,4,FV ), 0                         , 0 , 0 , 9325, 246, 116, 86),
+    1590             :   INST(Vsubps          , VexRvm_Lx          , V(000F00,5C,_,x,I,0,4,FV ), 0                         , 0 , 0 , 9332, 247, 116, 86),
+    1591             :   INST(Vsubsd          , VexRvm             , V(F20F00,5C,_,I,I,1,3,T1S), 0                         , 0 , 0 , 9339, 248, 117, 86),
+    1592             :   INST(Vsubss          , VexRvm             , V(F30F00,5C,_,I,I,0,2,T1S), 0                         , 0 , 0 , 9346, 249, 117, 86),
+    1593             :   INST(Vtestpd         , VexRm_Lx           , V(660F38,0F,_,x,0,_,_,_  ), 0                         , 0 , 0 , 9353, 478, 141, 0 ),
+    1594             :   INST(Vtestps         , VexRm_Lx           , V(660F38,0E,_,x,0,_,_,_  ), 0                         , 0 , 0 , 9361, 478, 141, 0 ),
+    1595             :   INST(Vucomisd        , VexRm              , V(660F00,2E,_,I,I,1,3,T1S), 0                         , 0 , 0 , 9369, 277, 126, 15),
+    1596             :   INST(Vucomiss        , VexRm              , V(000F00,2E,_,I,I,0,2,T1S), 0                         , 0 , 0 , 9378, 278, 126, 15),
+    1597             :   INST(Vunpckhpd       , VexRvm_Lx          , V(660F00,15,_,x,I,1,4,FV ), 0                         , 0 , 0 , 9387, 256, 116, 13),
+    1598             :   INST(Vunpckhps       , VexRvm_Lx          , V(000F00,15,_,x,I,0,4,FV ), 0                         , 0 , 0 , 9397, 257, 116, 13),
+    1599             :   INST(Vunpcklpd       , VexRvm_Lx          , V(660F00,14,_,x,I,1,4,FV ), 0                         , 0 , 0 , 9407, 256, 116, 13),
+    1600             :   INST(Vunpcklps       , VexRvm_Lx          , V(000F00,14,_,x,I,0,4,FV ), 0                         , 0 , 0 , 9417, 257, 116, 13),
+    1601             :   INST(Vxorpd          , VexRvm_Lx          , V(660F00,57,_,x,I,1,4,FV ), 0                         , 0 , 0 , 9427, 475, 121, 87),
+    1602             :   INST(Vxorps          , VexRvm_Lx          , V(000F00,57,_,x,I,0,4,FV ), 0                         , 0 , 0 , 9434, 474, 121, 87),
+    1603             :   INST(Vzeroall        , VexOp              , V(000F00,77,_,1,I,_,_,_  ), 0                         , 0 , 0 , 9441, 507, 118, 0 ),
+    1604             :   INST(Vzeroupper      , VexOp              , V(000F00,77,_,0,I,_,_,_  ), 0                         , 0 , 0 , 9450, 507, 118, 0 ),
+    1605             :   INST(Wbinvd          , X86Op              , O(000F00,09,_,_,_,_,_,_  ), 0                         , 0 , 0 , 9461, 34 , 23 , 0 ),
+    1606             :   INST(Wrfsbase        , X86M               , O(F30F00,AE,2,_,x,_,_,_  ), 0                         , 0 , 0 , 9468, 508, 98 , 0 ),
+    1607             :   INST(Wrgsbase        , X86M               , O(F30F00,AE,3,_,x,_,_,_  ), 0                         , 0 , 0 , 9477, 508, 98 , 0 ),
+    1608             :   INST(Wrmsr           , X86Op              , O(000F00,30,_,_,_,_,_,_  ), 0                         , 0 , 0 , 9486, 509, 147, 0 ),
+    1609             :   INST(Xabort          , X86Op_O_I8         , O(000000,C6,7,_,_,_,_,_  ), 0                         , 0 , 0 , 9492, 98 , 148, 0 ),
+    1610             :   INST(Xadd            , X86Xadd            , O(000F00,C0,_,_,x,_,_,_  ), 0                         , 0 , 0 , 9499, 510, 36 , 0 ),
+    1611             :   INST(Xbegin          , X86JmpRel          , O(000000,C7,7,_,_,_,_,_  ), 0                         , 0 , 0 , 9504, 511, 148, 0 ),
+    1612             :   INST(Xchg            , X86Xchg            , O(000000,86,_,_,x,_,_,_  ), 0                         , 0 , 0 , 434 , 512, 0  , 0 ),
+    1613             :   INST(Xend            , X86Op              , O(000F01,D5,_,_,_,_,_,_  ), 0                         , 0 , 0 , 9511, 34 , 148, 0 ),
+    1614             :   INST(Xgetbv          , X86Op              , O(000F01,D0,_,_,_,_,_,_  ), 0                         , 0 , 0 , 9516, 227, 149, 0 ),
+    1615             :   INST(Xlatb           , X86Op              , O(000000,D7,_,_,_,_,_,_  ), 0                         , 0 , 0 , 9523, 34 , 45 , 0 ),
+    1616             :   INST(Xor             , X86Arith           , O(000000,30,6,_,x,_,_,_  ), 0                         , 0 , 0 , 8646, 243, 1  , 0 ),
+    1617             :   INST(Xorpd           , ExtRm              , O(660F00,57,_,_,_,_,_,_  ), 0                         , 0 , 0 , 9428, 192, 4  , 87),
+    1618             :   INST(Xorps           , ExtRm              , O(000F00,57,_,_,_,_,_,_  ), 0                         , 0 , 0 , 9435, 192, 5  , 87),
+    1619             :   INST(Xrstor          , X86M_Only          , O(000F00,AE,5,_,_,_,_,_  ), 0                         , 0 , 0 , 1105, 513, 149, 0 ),
+    1620             :   INST(Xrstor64        , X86M_Only          , O(000F00,AE,5,_,1,_,_,_  ), 0                         , 0 , 0 , 1113, 514, 149, 0 ),
+    1621             :   INST(Xrstors         , X86M_Only          , O(000F00,C7,3,_,_,_,_,_  ), 0                         , 0 , 0 , 9529, 513, 150, 0 ),
+    1622             :   INST(Xrstors64       , X86M_Only          , O(000F00,C7,3,_,1,_,_,_  ), 0                         , 0 , 0 , 9537, 514, 150, 0 ),
+    1623             :   INST(Xsave           , X86M_Only          , O(000F00,AE,4,_,_,_,_,_  ), 0                         , 0 , 0 , 1123, 515, 149, 0 ),
+    1624             :   INST(Xsave64         , X86M_Only          , O(000F00,AE,4,_,1,_,_,_  ), 0                         , 0 , 0 , 1130, 516, 149, 0 ),
+    1625             :   INST(Xsavec          , X86M_Only          , O(000F00,C7,4,_,_,_,_,_  ), 0                         , 0 , 0 , 9547, 515, 151, 0 ),
+    1626             :   INST(Xsavec64        , X86M_Only          , O(000F00,C7,4,_,1,_,_,_  ), 0                         , 0 , 0 , 9554, 516, 151, 0 ),
+    1627             :   INST(Xsaveopt        , X86M_Only          , O(000F00,AE,6,_,_,_,_,_  ), 0                         , 0 , 0 , 9563, 515, 152, 0 ),
+    1628             :   INST(Xsaveopt64      , X86M_Only          , O(000F00,AE,6,_,1,_,_,_  ), 0                         , 0 , 0 , 9572, 516, 152, 0 ),
+    1629             :   INST(Xsaves          , X86M_Only          , O(000F00,C7,5,_,_,_,_,_  ), 0                         , 0 , 0 , 9583, 515, 150, 0 ),
+    1630             :   INST(Xsaves64        , X86M_Only          , O(000F00,C7,5,_,1,_,_,_  ), 0                         , 0 , 0 , 9590, 516, 150, 0 ),
+    1631             :   INST(Xsetbv          , X86Op              , O(000F01,D1,_,_,_,_,_,_  ), 0                         , 0 , 0 , 9599, 509, 153, 0 ),
+    1632             :   INST(Xtest           , X86Op              , O(000F01,D6,_,_,_,_,_,_  ), 0                         , 0 , 0 , 9606, 34 , 154, 0 )
+    1633             :   // ${instData:End}
+    1634             : };
+    1635             : #undef NAME_DATA_INDEX
+    1636             : #undef INST
+    1637             : 
+    1638             : // ${altOpCodeData:Begin}
+    1639             : // ------------------- Automatically generated, do not edit -------------------
+    1640             : const uint32_t X86InstDB::altOpCodeData[] = {
+    1641             :   0                         , // #0
+    1642             :   O(660F00,1B,_,_,_,_,_,_  ), // #1
+    1643             :   O(000F00,BA,4,_,x,_,_,_  ), // #2
+    1644             :   O(000F00,BA,7,_,x,_,_,_  ), // #3
+    1645             :   O(000F00,BA,6,_,x,_,_,_  ), // #4
+    1646             :   O(000F00,BA,5,_,x,_,_,_  ), // #5
+    1647             :   O(000000,48,_,_,x,_,_,_  ), // #6
+    1648             :   O(660F00,78,0,_,_,_,_,_  ), // #7
+    1649             :   O_FPU(00,00DF,5)          , // #8
+    1650             :   O_FPU(00,00DF,7)          , // #9
+    1651             :   O_FPU(00,00DD,1)          , // #10
+    1652             :   O_FPU(00,00DB,5)          , // #11
+    1653             :   O_FPU(00,DFE0,_)          , // #12
+    1654             :   O(000000,DB,7,_,_,_,_,_  ), // #13
+    1655             :   O_FPU(9B,DFE0,_)          , // #14
+    1656             :   O(000000,E4,_,_,_,_,_,_  ), // #15
+    1657             :   O(000000,40,_,_,x,_,_,_  ), // #16
+    1658             :   O(F20F00,78,_,_,_,_,_,_  ), // #17
+    1659             :   O(000000,77,_,_,_,_,_,_  ), // #18
+    1660             :   O(000000,73,_,_,_,_,_,_  ), // #19
+    1661             :   O(000000,72,_,_,_,_,_,_  ), // #20
+    1662             :   O(000000,76,_,_,_,_,_,_  ), // #21
+    1663             :   O(000000,74,_,_,_,_,_,_  ), // #22
+    1664             :   O(000000,E3,_,_,_,_,_,_  ), // #23
+    1665             :   O(000000,7F,_,_,_,_,_,_  ), // #24
+    1666             :   O(000000,7D,_,_,_,_,_,_  ), // #25
+    1667             :   O(000000,7C,_,_,_,_,_,_  ), // #26
+    1668             :   O(000000,7E,_,_,_,_,_,_  ), // #27
+    1669             :   O(000000,EB,_,_,_,_,_,_  ), // #28
+    1670             :   O(000000,75,_,_,_,_,_,_  ), // #29
+    1671             :   O(000000,71,_,_,_,_,_,_  ), // #30
+    1672             :   O(000000,7B,_,_,_,_,_,_  ), // #31
+    1673             :   O(000000,79,_,_,_,_,_,_  ), // #32
+    1674             :   O(000000,70,_,_,_,_,_,_  ), // #33
+    1675             :   O(000000,7A,_,_,_,_,_,_  ), // #34
+    1676             :   O(000000,78,_,_,_,_,_,_  ), // #35
+    1677             :   V(660F00,92,_,0,0,_,_,_  ), // #36
+    1678             :   V(F20F00,92,_,0,0,_,_,_  ), // #37
+    1679             :   V(F20F00,92,_,0,1,_,_,_  ), // #38
+    1680             :   V(000F00,92,_,0,0,_,_,_  ), // #39
+    1681             :   O(000000,E2,_,_,_,_,_,_  ), // #40
+    1682             :   O(000000,E1,_,_,_,_,_,_  ), // #41
+    1683             :   O(000000,E0,_,_,_,_,_,_  ), // #42
+    1684             :   O(660F00,29,_,_,_,_,_,_  ), // #43
+    1685             :   O(000F00,29,_,_,_,_,_,_  ), // #44
+    1686             :   O(000F38,F1,_,_,x,_,_,_  ), // #45
+    1687             :   O(000F00,7E,_,_,_,_,_,_  ), // #46
+    1688             :   O(660F00,7F,_,_,_,_,_,_  ), // #47
+    1689             :   O(F30F00,7F,_,_,_,_,_,_  ), // #48
+    1690             :   O(660F00,17,_,_,_,_,_,_  ), // #49
+    1691             :   O(000F00,17,_,_,_,_,_,_  ), // #50
+    1692             :   O(660F00,13,_,_,_,_,_,_  ), // #51
+    1693             :   O(000F00,13,_,_,_,_,_,_  ), // #52
+    1694             :   O(660F00,E7,_,_,_,_,_,_  ), // #53
+    1695             :   O(660F00,2B,_,_,_,_,_,_  ), // #54
+    1696             :   O(000F00,2B,_,_,_,_,_,_  ), // #55
+    1697             :   O(000F00,E7,_,_,_,_,_,_  ), // #56
+    1698             :   O(F20F00,2B,_,_,_,_,_,_  ), // #57
+    1699             :   O(F30F00,2B,_,_,_,_,_,_  ), // #58
+    1700             :   O(000F00,7E,_,_,x,_,_,_  ), // #59
+    1701             :   O(F20F00,11,_,_,_,_,_,_  ), // #60
+    1702             :   O(F30F00,11,_,_,_,_,_,_  ), // #61
+    1703             :   O(660F00,11,_,_,_,_,_,_  ), // #62
+    1704             :   O(000F00,11,_,_,_,_,_,_  ), // #63
+    1705             :   O(000000,E6,_,_,_,_,_,_  ), // #64
+    1706             :   O(000F3A,15,_,_,_,_,_,_  ), // #65
+    1707             :   O(000000,58,_,_,_,_,_,_  ), // #66
+    1708             :   O(000F00,72,6,_,_,_,_,_  ), // #67
+    1709             :   O(660F00,73,7,_,_,_,_,_  ), // #68
+    1710             :   O(000F00,73,6,_,_,_,_,_  ), // #69
+    1711             :   O(000F00,71,6,_,_,_,_,_  ), // #70
+    1712             :   O(000F00,72,4,_,_,_,_,_  ), // #71
+    1713             :   O(000F00,71,4,_,_,_,_,_  ), // #72
+    1714             :   O(000F00,72,2,_,_,_,_,_  ), // #73
+    1715             :   O(660F00,73,3,_,_,_,_,_  ), // #74
+    1716             :   O(000F00,73,2,_,_,_,_,_  ), // #75
+    1717             :   O(000F00,71,2,_,_,_,_,_  ), // #76
+    1718             :   O(000000,50,_,_,_,_,_,_  ), // #77
+    1719             :   O(000000,F6,_,_,x,_,_,_  ), // #78
+    1720             :   V(660F38,92,_,x,_,1,3,T1S), // #79
+    1721             :   V(660F38,92,_,x,_,0,2,T1S), // #80
+    1722             :   V(660F38,93,_,x,_,1,3,T1S), // #81
+    1723             :   V(660F38,93,_,x,_,0,2,T1S), // #82
+    1724             :   V(660F38,2F,_,x,0,_,_,_  ), // #83
+    1725             :   V(660F38,2E,_,x,0,_,_,_  ), // #84
+    1726             :   V(660F00,29,_,x,I,1,4,FVM), // #85
+    1727             :   V(000F00,29,_,x,I,0,4,FVM), // #86
+    1728             :   V(660F00,7E,_,0,0,0,2,T1S), // #87
+    1729             :   V(660F00,7F,_,x,I,_,_,_  ), // #88
+    1730             :   V(660F00,7F,_,x,_,0,4,FVM), // #89
+    1731             :   V(660F00,7F,_,x,_,1,4,FVM), // #90
+    1732             :   V(F30F00,7F,_,x,I,_,_,_  ), // #91
+    1733             :   V(F20F00,7F,_,x,_,1,4,FVM), // #92
+    1734             :   V(F30F00,7F,_,x,_,0,4,FVM), // #93
+    1735             :   V(F30F00,7F,_,x,_,1,4,FVM), // #94
+    1736             :   V(F20F00,7F,_,x,_,0,4,FVM), // #95
+    1737             :   V(660F00,17,_,0,I,1,3,T1S), // #96
+    1738             :   V(000F00,17,_,0,I,0,3,T2 ), // #97
+    1739             :   V(660F00,13,_,0,I,1,3,T1S), // #98
+    1740             :   V(000F00,13,_,0,I,0,3,T2 ), // #99
+    1741             :   V(660F00,7E,_,0,I,1,3,T1S), // #100
+    1742             :   V(F20F00,11,_,I,I,1,3,T1S), // #101
+    1743             :   V(F30F00,11,_,I,I,0,2,T1S), // #102
+    1744             :   V(660F00,11,_,x,I,1,4,FVM), // #103
+    1745             :   V(000F00,11,_,x,I,0,4,FVM), // #104
+    1746             :   V(660F3A,05,_,x,0,1,4,FV ), // #105
+    1747             :   V(660F3A,04,_,x,0,0,4,FV ), // #106
+    1748             :   V(660F3A,00,_,x,1,1,4,FV ), // #107
+    1749             :   V(660F38,90,_,x,_,0,2,T1S), // #108
+    1750             :   V(660F38,90,_,x,_,1,3,T1S), // #109
+    1751             :   V(660F38,91,_,x,_,0,2,T1S), // #110
+    1752             :   V(660F38,91,_,x,_,1,3,T1S), // #111
+    1753             :   V(660F38,8E,_,x,0,_,_,_  ), // #112
+    1754             :   V(660F38,8E,_,x,1,_,_,_  ), // #113
+    1755             :   V(XOP_M8,C0,_,0,x,_,_,_  ), // #114
+    1756             :   V(XOP_M8,C2,_,0,x,_,_,_  ), // #115
+    1757             :   V(XOP_M8,C3,_,0,x,_,_,_  ), // #116
+    1758             :   V(XOP_M8,C1,_,0,x,_,_,_  ), // #117
+    1759             :   V(660F00,72,6,x,I,0,4,FV ), // #118
+    1760             :   V(660F00,73,6,x,I,1,4,FV ), // #119
+    1761             :   V(660F00,71,6,x,I,I,4,FVM), // #120
+    1762             :   V(660F00,72,4,x,I,0,4,FV ), // #121
+    1763             :   V(660F00,72,4,x,_,1,4,FV ), // #122
+    1764             :   V(660F00,71,4,x,I,I,4,FVM), // #123
+    1765             :   V(660F00,72,2,x,I,0,4,FV ), // #124
+    1766             :   V(660F00,73,2,x,I,1,4,FV ), // #125
+    1767             :   V(660F00,71,2,x,I,I,4,FVM)  // #126
+    1768             : };
+    1769             : // ----------------------------------------------------------------------------
+    1770             : // ${altOpCodeData:End}
+    1771             : 
+    1772             : #undef O_FPU
+    1773             : #undef O
+    1774             : #undef V
+    1775             : 
+    1776             : // ${commonData:Begin}
+    1777             : // ------------------- Automatically generated, do not edit -------------------
+    1778             : #define F(VAL) X86Inst::kFlag##VAL
+    1779             : #define JUMP_TYPE(VAL) Inst::kJumpType##VAL
+    1780             : #define SINGLE_REG(VAL) X86Inst::kSingleReg##VAL
+    1781             : const X86Inst::CommonData X86InstDB::commonData[] = {
+    1782             :   { F(UseR)                                               , 0  , 0  , 0  , 0  , 0 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #0
+    1783             :   { F(UseX)|F(FixedReg)                                   , 0  , 0  , 0  , 383, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #1
+    1784             :   { F(UseX)|F(FixedReg)                                   , 0  , 0  , 0  , 384, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #2
+    1785             :   { F(UseX)|F(Lock)|F(XAcquire)|F(XRelease)               , 0  , 0  , 0  , 15 , 12, JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #3
+    1786             :   { F(UseX)                                               , 0  , 0  , 0  , 25 , 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #4
+    1787             :   { F(UseX)|F(Vec)                                        , 0  , 0  , 0  , 336, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #5
+    1788             :   { F(UseX)|F(Vec)                                        , 0  , 0  , 0  , 385, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #6
+    1789             :   { F(UseX)|F(Vec)                                        , 0  , 0  , 0  , 386, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #7
+    1790             :   { F(UseW)|F(Vec)                                        , 0  , 0  , 0  , 87 , 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #8
+    1791             :   { F(UseW)|F(Vec)                                        , 0  , 0  , 0  , 94 , 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #9
+    1792             :   { F(UseX)|F(Lock)|F(XAcquire)|F(XRelease)               , 0  , 0  , 0  , 39 , 11, JUMP_TYPE(None)       , SINGLE_REG(RO)  , 0 }, // #10
+    1793             :   { F(UseW)|F(Vex)                                        , 0  , 0  , 0  , 273, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #11
+    1794             :   { F(UseX)|F(Vec)                                        , 0  , 0  , 0  , 336, 1 , JUMP_TYPE(None)       , SINGLE_REG(RO)  , 0 }, // #12
+    1795             :   { F(UseX)                                               , 0  , 0  , 0  , 387, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #13
+    1796             :   { F(UseW)|F(Vex)                                        , 0  , 0  , 0  , 275, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #14
+    1797             :   { F(UseW)|F(Vex)                                        , 0  , 0  , 0  , 184, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #15
+    1798             :   { F(UseX)|F(Vec)                                        , 0  , 0  , 0  , 338, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #16
+    1799             :   { F(UseX)|F(FixedReg)|F(Vec)                            , 0  , 0  , 0  , 388, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #17
+    1800             :   { F(UseR)                                               , 0  , 0  , 0  , 277, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #18
+    1801             :   { F(UseW)|F(Mib)                                        , 0  , 0  , 0  , 389, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #19
+    1802             :   { F(UseW)                                               , 0  , 0  , 0  , 390, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #20
+    1803             :   { F(UseW)                                               , 0  , 0  , 1  , 279, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #21
+    1804             :   { F(UseW)|F(Mib)                                        , 0  , 0  , 0  , 391, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #22
+    1805             :   { F(UseR)                                               , 0  , 0  , 0  , 281, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #23
+    1806             :   { F(UseX)                                               , 0  , 0  , 0  , 24 , 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #24
+    1807             :   { F(UseX)                                               , 0  , 0  , 0  , 392, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #25
+    1808             :   { F(UseR)                                               , 0  , 0  , 2  , 126, 4 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #26
+    1809             :   { F(UseX)|F(Lock)|F(XAcquire)|F(XRelease)               , 0  , 0  , 3  , 130, 4 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #27
+    1810             :   { F(UseX)|F(Lock)|F(XAcquire)|F(XRelease)               , 0  , 0  , 4  , 130, 4 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #28
+    1811             :   { F(UseX)|F(Lock)|F(XAcquire)|F(XRelease)               , 0  , 0  , 5  , 130, 4 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #29
+    1812             :   { F(UseR)                                               , 0  , 0  , 0  , 283, 2 , JUMP_TYPE(Call)       , SINGLE_REG(None), 0 }, // #30
+    1813             :   { F(UseX)|F(FixedReg)                                   , 0  , 0  , 0  , 393, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #31
+    1814             :   { F(UseW)|F(FixedReg)                                   , 0  , 0  , 0  , 394, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #32
+    1815             :   { F(UseX)|F(FixedReg)                                   , 0  , 0  , 0  , 395, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #33
+    1816             :   { F(UseR)                                               , 0  , 0  , 0  , 291, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #34
+    1817             :   { F(UseR)                                               , 0  , 0  , 0  , 396, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #35
+    1818             :   { F(UseR)|F(FixedRM)                                    , 0  , 0  , 0  , 397, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #36
+    1819             :   { F(UseR)                                               , 0  , 0  , 0  , 27 , 12, JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #37
+    1820             :   { F(UseX)|F(FixedRM)|F(Rep)|F(Repnz)                    , 0  , 0  , 0  , 398, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #38
+    1821             :   { F(UseX)|F(Vec)                                        , 0  , 0  , 0  , 399, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #39
+    1822             :   { F(UseX)|F(Vec)                                        , 0  , 0  , 0  , 400, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #40
+    1823             :   { F(UseX)|F(FixedReg)|F(Lock)|F(XAcquire)|F(XRelease)   , 0  , 0  , 0  , 134, 4 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #41
+    1824             :   { F(UseX)|F(FixedReg)|F(Lock)|F(XAcquire)|F(XRelease)   , 0  , 0  , 0  , 401, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #42
+    1825             :   { F(UseX)|F(FixedReg)|F(Lock)|F(XAcquire)|F(XRelease)   , 0  , 0  , 0  , 402, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #43
+    1826             :   { F(UseR)|F(Vec)                                        , 0  , 0  , 0  , 403, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #44
+    1827             :   { F(UseR)|F(Vec)                                        , 0  , 0  , 0  , 404, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #45
+    1828             :   { F(UseX)|F(FixedReg)                                   , 0  , 0  , 0  , 405, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #46
+    1829             :   { F(UseW)|F(FixedReg)                                   , 0  , 0  , 0  , 406, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #47
+    1830             :   { F(UseX)                                               , 0  , 0  , 0  , 285, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #48
+    1831             :   { F(UseW)|F(Vec)                                        , 0  , 16 , 0  , 85 , 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #49
+    1832             :   { F(UseW)|F(Vec)                                        , 0  , 16 , 0  , 87 , 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #50
+    1833             :   { F(UseW)|F(Mmx)|F(Vec)                                 , 0  , 8  , 0  , 407, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #51
+    1834             :   { F(UseW)|F(Mmx)|F(Vec)                                 , 0  , 16 , 0  , 408, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #52
+    1835             :   { F(UseW)|F(Mmx)|F(Vec)                                 , 0  , 8  , 0  , 408, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #53
+    1836             :   { F(UseW)|F(Mmx)|F(Vec)                                 , 0  , 8  , 0  , 409, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #54
+    1837             :   { F(UseW)|F(Vec)                                        , 0  , 8  , 0  , 410, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #55
+    1838             :   { F(UseW)|F(Vec)                                        , 0  , 4  , 0  , 85 , 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #56
+    1839             :   { F(UseW)|F(Vec)                                        , 0  , 8  , 0  , 411, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #57
+    1840             :   { F(UseW)|F(Vec)                                        , 0  , 4  , 0  , 411, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #58
+    1841             :   { F(UseW)|F(Vec)                                        , 0  , 8  , 0  , 255, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #59
+    1842             :   { F(UseW)|F(Vec)                                        , 0  , 8  , 0  , 412, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #60
+    1843             :   { F(UseW)|F(FixedReg)                                   , 0  , 0  , 0  , 413, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #61
+    1844             :   { F(UseX)|F(FixedReg)                                   , 0  , 0  , 0  , 414, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #62
+    1845             :   { F(UseX)|F(Lock)|F(XAcquire)|F(XRelease)               , 0  , 0  , 6  , 287, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #63
+    1846             :   { F(UseX)|F(FixedReg)                                   , 0  , 0  , 0  , 138, 4 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #64
+    1847             :   { F(UseR)|F(Mmx)                                        , 0  , 0  , 0  , 291, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #65
+    1848             :   { F(UseR)                                               , 0  , 0  , 0  , 415, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #66
+    1849             :   { F(UseW)|F(Vec)                                        , 0  , 8  , 0  , 416, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #67
+    1850             :   { F(UseX)|F(Vec)                                        , 0  , 0  , 7  , 289, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #68
+    1851             :   { F(UseA)|F(FixedReg)|F(FpuM32)|F(FpuM64)               , 0  , 0  , 0  , 174, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #69
+    1852             :   { F(UseX)                                               , 0  , 0  , 0  , 291, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #70
+    1853             :   { F(UseR)|F(FpuM80)                                     , 0  , 0  , 0  , 417, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #71
+    1854             :   { F(UseW)|F(FpuM80)                                     , 0  , 0  , 0  , 418, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #72
+    1855             :   { F(UseX)                                               , 0  , 0  , 0  , 292, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #73
+    1856             :   { F(UseR)|F(FpuM32)|F(FpuM64)                           , 0  , 0  , 0  , 293, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #74
+    1857             :   { F(UseR)                                               , 0  , 0  , 0  , 296, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #75
+    1858             :   { F(UseR)|F(FpuM16)|F(FpuM32)                           , 0  , 0  , 0  , 419, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #76
+    1859             :   { F(UseR)|F(FpuM16)|F(FpuM32)|F(FpuM64)                 , 0  , 0  , 8  , 420, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #77
+    1860             :   { F(UseW)|F(FpuM16)|F(FpuM32)                           , 0  , 0  , 0  , 421, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #78
+    1861             :   { F(UseW)|F(FpuM16)|F(FpuM32)|F(FpuM64)                 , 0  , 0  , 9  , 422, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #79
+    1862             :   { F(UseW)|F(FpuM16)|F(FpuM32)|F(FpuM64)                 , 0  , 0  , 10 , 422, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #80
+    1863             :   { F(UseR)|F(FpuM32)|F(FpuM64)|F(FpuM80)                 , 0  , 0  , 11 , 423, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #81
+    1864             :   { F(UseR)|F(FpuM16)                                     , 0  , 0  , 0  , 424, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #82
+    1865             :   { F(UseX)|F(FixedReg)|F(FpuM32)|F(FpuM64)               , 0  , 0  , 0  , 177, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #83
+    1866             :   { F(UseW)                                               , 0  , 0  , 0  , 425, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #84
+    1867             :   { F(UseW)|F(FpuM16)                                     , 0  , 0  , 0  , 426, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #85
+    1868             :   { F(UseW)|F(FixedReg)|F(FpuM16)                         , 0  , 0  , 12 , 427, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #86
+    1869             :   { F(UseW)|F(FpuM32)|F(FpuM64)                           , 0  , 0  , 0  , 428, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #87
+    1870             :   { F(UseW)|F(FpuM32)|F(FpuM64)|F(FpuM80)                 , 0  , 0  , 13 , 429, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #88
+    1871             :   { F(UseW)|F(FixedReg)|F(FpuM16)                         , 0  , 0  , 14 , 427, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #89
+    1872             :   { F(UseR)                                               , 0  , 0  , 0  , 295, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #90
+    1873             :   { F(UseR)                                               , 0  , 0  , 0  , 430, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #91
+    1874             :   { F(UseW)                                               , 0  , 0  , 0  , 431, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #92
+    1875             :   { F(UseA)|F(FixedReg)                                   , 0  , 0  , 0  , 50 , 10, JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #93
+    1876             :   { F(UseW)|F(FixedReg)                                   , 0  , 0  , 15 , 432, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #94
+    1877             :   { F(UseX)|F(Lock)|F(XAcquire)|F(XRelease)               , 0  , 0  , 16 , 287, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #95
+    1878             :   { F(UseW)|F(FixedRM)|F(Rep)|F(Repnz)                    , 0  , 0  , 0  , 433, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #96
+    1879             :   { F(UseX)|F(Vec)                                        , 0  , 0  , 17 , 297, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #97
+    1880             :   { F(UseR)                                               , 0  , 0  , 0  , 434, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #98
+    1881             :   { F(UseR)                                               , 0  , 0  , 0  , 435, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #99
+    1882             :   { F(UseR)                                               , 0  , 0  , 0  , 299, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #100
+    1883             :   { F(UseR)                                               , 0  , 0  , 0  , 436, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #101
+    1884             :   { F(UseR)                                               , 0  , 0  , 18 , 437, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #102
+    1885             :   { F(UseR)                                               , 0  , 0  , 19 , 437, 1 , JUMP_TYPE(Conditional), SINGLE_REG(None), 0 }, // #103
+    1886             :   { F(UseR)                                               , 0  , 0  , 20 , 437, 1 , JUMP_TYPE(Conditional), SINGLE_REG(None), 0 }, // #104
+    1887             :   { F(UseR)                                               , 0  , 0  , 21 , 437, 1 , JUMP_TYPE(Conditional), SINGLE_REG(None), 0 }, // #105
+    1888             :   { F(UseR)                                               , 0  , 0  , 20 , 438, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #106
+    1889             :   { F(UseR)                                               , 0  , 0  , 22 , 437, 1 , JUMP_TYPE(Conditional), SINGLE_REG(None), 0 }, // #107
+    1890             :   { F(UseR)|F(FixedReg)                                   , 0  , 0  , 23 , 301, 2 , JUMP_TYPE(Conditional), SINGLE_REG(None), 0 }, // #108
+    1891             :   { F(UseR)                                               , 0  , 0  , 24 , 437, 1 , JUMP_TYPE(Conditional), SINGLE_REG(None), 0 }, // #109
+    1892             :   { F(UseR)                                               , 0  , 0  , 25 , 437, 1 , JUMP_TYPE(Conditional), SINGLE_REG(None), 0 }, // #110
+    1893             :   { F(UseR)                                               , 0  , 0  , 26 , 437, 1 , JUMP_TYPE(Conditional), SINGLE_REG(None), 0 }, // #111
+    1894             :   { F(UseR)                                               , 0  , 0  , 27 , 437, 1 , JUMP_TYPE(Conditional), SINGLE_REG(None), 0 }, // #112
+    1895             :   { F(UseR)                                               , 0  , 0  , 28 , 303, 2 , JUMP_TYPE(Direct)     , SINGLE_REG(None), 0 }, // #113
+    1896             :   { F(UseR)                                               , 0  , 0  , 19 , 438, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #114
+    1897             :   { F(UseR)                                               , 0  , 0  , 29 , 437, 1 , JUMP_TYPE(Conditional), SINGLE_REG(None), 0 }, // #115
+    1898             :   { F(UseR)                                               , 0  , 0  , 30 , 437, 1 , JUMP_TYPE(Conditional), SINGLE_REG(None), 0 }, // #116
+    1899             :   { F(UseR)                                               , 0  , 0  , 31 , 437, 1 , JUMP_TYPE(Conditional), SINGLE_REG(None), 0 }, // #117
+    1900             :   { F(UseR)                                               , 0  , 0  , 32 , 437, 1 , JUMP_TYPE(Conditional), SINGLE_REG(None), 0 }, // #118
+    1901             :   { F(UseR)                                               , 0  , 0  , 33 , 437, 1 , JUMP_TYPE(Conditional), SINGLE_REG(None), 0 }, // #119
+    1902             :   { F(UseR)                                               , 0  , 0  , 34 , 437, 1 , JUMP_TYPE(Conditional), SINGLE_REG(None), 0 }, // #120
+    1903             :   { F(UseR)                                               , 0  , 0  , 35 , 437, 1 , JUMP_TYPE(Conditional), SINGLE_REG(None), 0 }, // #121
+    1904             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 439, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #122
+    1905             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 36 , 305, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #123
+    1906             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 37 , 307, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #124
+    1907             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 38 , 309, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #125
+    1908             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 39 , 311, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #126
+    1909             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 440, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #127
+    1910             :   { F(UseR)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 441, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #128
+    1911             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 442, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #129
+    1912             :   { F(UseW)|F(FixedReg)                                   , 0  , 0  , 0  , 443, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #130
+    1913             :   { F(UseW)                                               , 0  , 0  , 0  , 313, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #131
+    1914             :   { F(UseW)|F(Vec)                                        , 0  , 16 , 0  , 228, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #132
+    1915             :   { F(UseR)                                               , 0  , 0  , 0  , 444, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #133
+    1916             :   { F(UseX)                                               , 0  , 0  , 0  , 315, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #134
+    1917             :   { F(UseW)                                               , 0  , 0  , 0  , 445, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #135
+    1918             :   { F(UseX)                                               , 0  , 0  , 0  , 180, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #136
+    1919             :   { F(UseR)                                               , 0  , 0  , 0  , 446, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #137
+    1920             :   { F(UseW)|F(FixedRM)|F(Rep)|F(Repnz)                    , 0  , 0  , 0  , 447, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #138
+    1921             :   { F(UseX)|F(FixedReg)                                   , 0  , 0  , 40 , 317, 2 , JUMP_TYPE(Conditional), SINGLE_REG(None), 0 }, // #139
+    1922             :   { F(UseX)|F(FixedReg)                                   , 0  , 0  , 41 , 317, 2 , JUMP_TYPE(Conditional), SINGLE_REG(None), 0 }, // #140
+    1923             :   { F(UseX)|F(FixedReg)                                   , 0  , 0  , 42 , 317, 2 , JUMP_TYPE(Conditional), SINGLE_REG(None), 0 }, // #141
+    1924             :   { F(UseW)                                               , 0  , 0  , 0  , 319, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #142
+    1925             :   { F(UseW)                                               , 0  , 0  , 0  , 183, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #143
+    1926             :   { F(UseX)|F(FixedRM)|F(Vec)                             , 0  , 0  , 0  , 448, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #144
+    1927             :   { F(UseX)|F(FixedRM)|F(Mmx)                             , 0  , 0  , 0  , 449, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #145
+    1928             :   { F(UseR)|F(FixedRM)                                    , 0  , 0  , 0  , 450, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #146
+    1929             :   { F(UseW)|F(XRelease)                                   , 0  , 0  , 0  , 0  , 15, JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #147
+    1930             :   { F(UseW)|F(Vec)                                        , 0  , 16 , 43 , 87 , 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #148
+    1931             :   { F(UseW)|F(Vec)                                        , 0  , 16 , 44 , 87 , 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #149
+    1932             :   { F(UseW)                                               , 0  , 0  , 45 , 75 , 6 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #150
+    1933             :   { F(UseW)|F(Mmx)|F(Vec)                                 , 0  , 16 , 46 , 321, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #151
+    1934             :   { F(UseW)|F(Mmx)|F(Vec)                                 , 0  , 8  , 0  , 451, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #152
+    1935             :   { F(UseW)|F(Vec)                                        , 0  , 16 , 47 , 87 , 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #153
+    1936             :   { F(UseW)|F(Vec)                                        , 0  , 16 , 48 , 87 , 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #154
+    1937             :   { F(UseW)|F(Vec)                                        , 0  , 8  , 0  , 452, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #155
+    1938             :   { F(UseW)|F(Vec)                                        , 8  , 8  , 49 , 234, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #156
+    1939             :   { F(UseW)|F(Vec)                                        , 8  , 8  , 50 , 234, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #157
+    1940             :   { F(UseW)|F(Vec)                                        , 8  , 8  , 0  , 452, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #158
+    1941             :   { F(UseW)|F(Vec)                                        , 0  , 8  , 51 , 234, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #159
+    1942             :   { F(UseW)|F(Vec)                                        , 0  , 8  , 52 , 234, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #160
+    1943             :   { F(UseW)|F(Vec)                                        , 0  , 8  , 0  , 453, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #161
+    1944             :   { F(UseW)|F(Vec)                                        , 0  , 16 , 53 , 225, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #162
+    1945             :   { F(UseW)                                               , 0  , 8  , 0  , 79 , 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #163
+    1946             :   { F(UseW)|F(Vec)                                        , 0  , 16 , 54 , 225, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #164
+    1947             :   { F(UseW)|F(Vec)                                        , 0  , 16 , 55 , 225, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #165
+    1948             :   { F(UseW)|F(Mmx)                                        , 0  , 8  , 56 , 454, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #166
+    1949             :   { F(UseW)|F(Vec)                                        , 0  , 8  , 57 , 234, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #167
+    1950             :   { F(UseW)|F(Vec)                                        , 0  , 4  , 58 , 237, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #168
+    1951             :   { F(UseW)|F(Mmx)|F(Vec)                                 , 0  , 16 , 59 , 81 , 6 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #169
+    1952             :   { F(UseW)|F(Mmx)|F(Vec)                                 , 0  , 16 , 0  , 455, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #170
+    1953             :   { F(UseX)|F(FixedRM)|F(Rep)|F(Repnz)                    , 0  , 0  , 0  , 456, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #171
+    1954             :   { F(UseW)|F(Vec)                                        , 0  , 8  , 60 , 323, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #172
+    1955             :   { F(UseW)|F(Vec)                                        , 0  , 4  , 61 , 325, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #173
+    1956             :   { F(UseW)                                               , 0  , 0  , 0  , 327, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #174
+    1957             :   { F(UseW)                                               , 0  , 0  , 0  , 457, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #175
+    1958             :   { F(UseW)|F(Vec)                                        , 0  , 16 , 62 , 87 , 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #176
+    1959             :   { F(UseW)|F(Vec)                                        , 0  , 16 , 63 , 87 , 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #177
+    1960             :   { F(UseA)|F(FixedReg)                                   , 0  , 0  , 0  , 50 , 4 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #178
+    1961             :   { F(UseW)|F(FixedReg)|F(Vex)                            , 0  , 0  , 0  , 329, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #179
+    1962             :   { F(UseR)|F(FixedReg)                                   , 0  , 0  , 0  , 458, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #180
+    1963             :   { F(UseX)|F(Lock)|F(XAcquire)|F(XRelease)               , 0  , 0  , 0  , 288, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #181
+    1964             :   { F(UseR)                                               , 0  , 0  , 0  , 331, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #182
+    1965             :   { F(UseX)|F(Lock)|F(XAcquire)|F(XRelease)               , 0  , 0  , 0  , 15 , 12, JUMP_TYPE(None)       , SINGLE_REG(RO)  , 0 }, // #183
+    1966             :   { F(UseR)|F(FixedReg)                                   , 0  , 0  , 64 , 459, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #184
+    1967             :   { F(UseR)|F(FixedRM)|F(Rep)|F(Repnz)                    , 0  , 0  , 0  , 460, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #185
+    1968             :   { F(UseW)|F(Mmx)|F(Vec)                                 , 0  , 0  , 0  , 333, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #186
+    1969             :   { F(UseX)|F(Mmx)|F(Vec)                                 , 0  , 0  , 0  , 335, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #187
+    1970             :   { F(UseX)|F(Mmx)|F(Vec)                                 , 0  , 0  , 0  , 337, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #188
+    1971             :   { F(UseX)|F(Mmx)|F(Vec)                                 , 0  , 0  , 0  , 335, 2 , JUMP_TYPE(None)       , SINGLE_REG(RO)  , 0 }, // #189
+    1972             :   { F(UseX)|F(Mmx)|F(Vec)                                 , 0  , 0  , 0  , 335, 2 , JUMP_TYPE(None)       , SINGLE_REG(WO)  , 0 }, // #190
+    1973             :   { F(UseX)|F(Mmx)                                        , 0  , 0  , 0  , 335, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #191
+    1974             :   { F(UseX)|F(Vec)                                        , 0  , 0  , 0  , 336, 1 , JUMP_TYPE(None)       , SINGLE_REG(WO)  , 0 }, // #192
+    1975             :   { F(UseR)|F(FixedReg)|F(Vec)                            , 0  , 0  , 0  , 461, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #193
+    1976             :   { F(UseR)|F(FixedReg)|F(Vec)                            , 0  , 0  , 0  , 462, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #194
+    1977             :   { F(UseR)|F(FixedReg)|F(Vec)                            , 0  , 0  , 0  , 463, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #195
+    1978             :   { F(UseR)|F(FixedReg)|F(Vec)                            , 0  , 0  , 0  , 464, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #196
+    1979             :   { F(UseW)|F(Vec)                                        , 0  , 8  , 0  , 465, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #197
+    1980             :   { F(UseW)|F(Vec)                                        , 0  , 8  , 0  , 466, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #198
+    1981             :   { F(UseW)|F(Mmx)|F(Vec)                                 , 0  , 8  , 65 , 339, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #199
+    1982             :   { F(UseW)|F(Mmx)                                        , 0  , 8  , 0  , 333, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #200
+    1983             :   { F(UseW)|F(Mmx)                                        , 0  , 0  , 0  , 333, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #201
+    1984             :   { F(UseX)|F(Vec)                                        , 0  , 0  , 0  , 467, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #202
+    1985             :   { F(UseX)|F(Vec)                                        , 0  , 0  , 0  , 468, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #203
+    1986             :   { F(UseX)|F(Vec)                                        , 0  , 0  , 0  , 469, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #204
+    1987             :   { F(UseX)|F(Mmx)|F(Vec)                                 , 0  , 0  , 0  , 470, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #205
+    1988             :   { F(UseW)|F(Mmx)|F(Vec)                                 , 0  , 8  , 0  , 471, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #206
+    1989             :   { F(UseW)|F(Vec)                                        , 0  , 16 , 0  , 255, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #207
+    1990             :   { F(UseW)|F(Vec)                                        , 0  , 16 , 0  , 258, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #208
+    1991             :   { F(UseW)|F(FixedReg)                                   , 0  , 0  , 66 , 142, 4 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #209
+    1992             :   { F(UseW)|F(Vec)                                        , 0  , 16 , 0  , 94 , 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #210
+    1993             :   { F(UseW)|F(Mmx)                                        , 0  , 8  , 0  , 472, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #211
+    1994             :   { F(UseX)|F(Mmx)|F(Vec)                                 , 0  , 0  , 67 , 341, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #212
+    1995             :   { F(UseX)|F(Vec)                                        , 0  , 0  , 68 , 473, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #213
+    1996             :   { F(UseX)|F(Mmx)|F(Vec)                                 , 0  , 0  , 69 , 341, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #214
+    1997             :   { F(UseX)|F(Mmx)|F(Vec)                                 , 0  , 0  , 70 , 341, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #215
+    1998             :   { F(UseX)|F(Mmx)|F(Vec)                                 , 0  , 0  , 71 , 341, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #216
+    1999             :   { F(UseX)|F(Mmx)|F(Vec)                                 , 0  , 0  , 72 , 341, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #217
+    2000             :   { F(UseX)|F(Mmx)|F(Vec)                                 , 0  , 0  , 73 , 341, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #218
+    2001             :   { F(UseX)|F(Vec)                                        , 0  , 0  , 74 , 473, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #219
+    2002             :   { F(UseX)|F(Mmx)|F(Vec)                                 , 0  , 0  , 75 , 341, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #220
+    2003             :   { F(UseX)|F(Mmx)|F(Vec)                                 , 0  , 0  , 76 , 341, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #221
+    2004             :   { F(UseR)|F(Vec)                                        , 0  , 0  , 0  , 379, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #222
+    2005             :   { F(UseA)|F(FixedReg)                                   , 0  , 0  , 77 , 146, 4 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #223
+    2006             :   { F(UseX)|F(FixedReg)                                   , 0  , 0  , 0  , 474, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #224
+    2007             :   { F(UseW)|F(Vec)                                        , 0  , 4  , 0  , 255, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #225
+    2008             :   { F(UseW)                                               , 0  , 8  , 0  , 475, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #226
+    2009             :   { F(UseW)|F(FixedReg)                                   , 0  , 0  , 0  , 476, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #227
+    2010             :   { F(UseW)                                               , 0  , 8  , 0  , 477, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #228
+    2011             :   { F(UseW)|F(FixedReg)                                   , 0  , 0  , 0  , 478, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #229
+    2012             :   { F(UseW)|F(FixedReg)                                   , 0  , 0  , 0  , 479, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #230
+    2013             :   { F(UseR)                                               , 0  , 0  , 0  , 343, 2 , JUMP_TYPE(Return)     , SINGLE_REG(None), 0 }, // #231
+    2014             :   { F(UseW)|F(Vex)                                        , 0  , 0  , 0  , 345, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #232
+    2015             :   { F(UseW)|F(Vec)                                        , 0  , 8  , 0  , 480, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #233
+    2016             :   { F(UseW)|F(Vec)                                        , 0  , 4  , 0  , 481, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #234
+    2017             :   { F(UseR)|F(FixedReg)                                   , 0  , 0  , 0  , 482, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #235
+    2018             :   { F(UseR)|F(FixedRM)|F(Rep)|F(Repnz)                    , 0  , 0  , 0  , 483, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #236
+    2019             :   { F(UseW)                                               , 0  , 1  , 0  , 484, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #237
+    2020             :   { F(UseX)|F(FixedReg)                                   , 0  , 0  , 0  , 186, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #238
+    2021             :   { F(UseW)                                               , 0  , 0  , 0  , 485, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #239
+    2022             :   { F(UseW)|F(Vec)                                        , 0  , 8  , 0  , 85 , 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #240
+    2023             :   { F(UseW)                                               , 0  , 0  , 0  , 486, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #241
+    2024             :   { F(UseX)|F(FixedRM)|F(Rep)|F(Repnz)                    , 0  , 0  , 0  , 487, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #242
+    2025             :   { F(UseX)|F(Lock)|F(XAcquire)|F(XRelease)               , 0  , 0  , 0  , 15 , 12, JUMP_TYPE(None)       , SINGLE_REG(WO)  , 0 }, // #243
+    2026             :   { F(UseR)                                               , 0  , 0  , 78 , 68 , 7 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #244
+    2027             :   { F(UseX)|F(Vec)|F(Evex)|F(Avx512T4X)|F(Avx512KZ)       , 0  , 0  , 0  , 488, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #245
+    2028             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_ER_SAE_B64)  , 0  , 0  , 0  , 189, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #246
+    2029             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_ER_SAE_B32)  , 0  , 0  , 0  , 189, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #247
+    2030             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_ER_SAE)      , 0  , 0  , 0  , 489, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #248
+    2031             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_ER_SAE)      , 0  , 0  , 0  , 490, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #249
+    2032             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 189, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #250
+    2033             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 93 , 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #251
+    2034             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 87 , 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #252
+    2035             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 94 , 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #253
+    2036             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_B32)                , 0  , 0  , 0  , 192, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #254
+    2037             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_B64)                , 0  , 0  , 0  , 192, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #255
+    2038             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_B64)         , 0  , 0  , 0  , 189, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #256
+    2039             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_B32)         , 0  , 0  , 0  , 189, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #257
+    2040             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_B64)         , 0  , 0  , 0  , 189, 3 , JUMP_TYPE(None)       , SINGLE_REG(RO)  , 0 }, // #258
+    2041             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_B32)         , 0  , 0  , 0  , 189, 3 , JUMP_TYPE(None)       , SINGLE_REG(RO)  , 0 }, // #259
+    2042             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ)                    , 0  , 0  , 0  , 189, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #260
+    2043             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_B32)                , 0  , 0  , 0  , 189, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #261
+    2044             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_B64)                , 0  , 0  , 0  , 189, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #262
+    2045             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 192, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #263
+    2046             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 347, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #264
+    2047             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 491, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #265
+    2048             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ)                    , 0  , 0  , 0  , 492, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #266
+    2049             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ)                    , 0  , 0  , 0  , 493, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #267
+    2050             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ)                    , 0  , 0  , 0  , 494, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #268
+    2051             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ)                    , 0  , 0  , 0  , 495, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #269
+    2052             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ)                    , 0  , 0  , 0  , 260, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #270
+    2053             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 0  , 492, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #271
+    2054             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 0  , 363, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #272
+    2055             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_SAE_B64)     , 0  , 0  , 0  , 195, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #273
+    2056             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_SAE_B32)     , 0  , 0  , 0  , 195, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #274
+    2057             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_SAE)         , 0  , 0  , 0  , 496, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #275
+    2058             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_SAE)         , 0  , 0  , 0  , 497, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #276
+    2059             :   { F(UseR)|F(Vec)|F(Vex)|F(Evex)|F(Avx512SAE)            , 0  , 0  , 0  , 403, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #277
+    2060             :   { F(UseR)|F(Vec)|F(Vex)|F(Evex)|F(Avx512SAE)            , 0  , 0  , 0  , 404, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #278
+    2061             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ)                    , 0  , 0  , 0  , 198, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #279
+    2062             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_B32)         , 0  , 0  , 0  , 201, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #280
+    2063             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_ER_SAE_B32)  , 0  , 0  , 0  , 204, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #281
+    2064             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_ER_SAE_B64)  , 0  , 0  , 0  , 349, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #282
+    2065             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_ER_SAE_B64)  , 0  , 0  , 0  , 207, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #283
+    2066             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_ER_SAE_B64)         , 0  , 0  , 0  , 204, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #284
+    2067             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_ER_SAE_B64)         , 0  , 0  , 0  , 349, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #285
+    2068             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_SAE)         , 0  , 0  , 0  , 201, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #286
+    2069             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_ER_SAE_B32)  , 0  , 0  , 0  , 201, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #287
+    2070             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_SAE)         , 0  , 0  , 0  , 210, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #288
+    2071             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_ER_SAE_B32)         , 0  , 0  , 0  , 201, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #289
+    2072             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_ER_SAE_B32)         , 0  , 0  , 0  , 204, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #290
+    2073             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512ER_SAE)         , 0  , 0  , 0  , 410, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #291
+    2074             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512ER_SAE)                , 0  , 0  , 0  , 410, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #292
+    2075             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512ER_SAE)         , 0  , 0  , 0  , 498, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #293
+    2076             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_SAE)         , 0  , 0  , 0  , 490, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #294
+    2077             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512ER_SAE)         , 0  , 0  , 0  , 412, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #295
+    2078             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512ER_SAE)                , 0  , 0  , 0  , 412, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #296
+    2079             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_SAE_B64)     , 0  , 0  , 0  , 349, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #297
+    2080             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_SAE_B64)            , 0  , 0  , 0  , 204, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #298
+    2081             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_SAE_B64)            , 0  , 0  , 0  , 349, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #299
+    2082             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_SAE_B32)     , 0  , 0  , 0  , 204, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #300
+    2083             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_SAE_B32)            , 0  , 0  , 0  , 201, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #301
+    2084             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_SAE_B32)            , 0  , 0  , 0  , 204, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #302
+    2085             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512SAE)            , 0  , 0  , 0  , 410, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #303
+    2086             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512SAE)                   , 0  , 0  , 0  , 410, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #304
+    2087             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512SAE)            , 0  , 0  , 0  , 412, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #305
+    2088             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512SAE)                   , 0  , 0  , 0  , 412, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #306
+    2089             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_B32)                , 0  , 0  , 0  , 201, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #307
+    2090             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512ER_SAE)                , 0  , 0  , 0  , 498, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #308
+    2091             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ)                    , 0  , 0  , 0  , 192, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #309
+    2092             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 192, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #310
+    2093             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_SAE_B64)            , 0  , 0  , 0  , 91 , 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #311
+    2094             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_SAE_B32)            , 0  , 0  , 0  , 91 , 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #312
+    2095             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ)                    , 0  , 0  , 0  , 204, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #313
+    2096             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 211, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #314
+    2097             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ)                    , 0  , 0  , 0  , 499, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #315
+    2098             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ)                    , 0  , 0  , 0  , 212, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #316
+    2099             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)                         , 0  , 0  , 0  , 416, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #317
+    2100             :   { F(UseX)|F(Vec)|F(Evex)|F(Avx512KZ_SAE_B64)            , 0  , 0  , 0  , 213, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #318
+    2101             :   { F(UseX)|F(Vec)|F(Evex)|F(Avx512KZ_SAE_B32)            , 0  , 0  , 0  , 213, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #319
+    2102             :   { F(UseX)|F(Vec)|F(Evex)|F(Avx512KZ_SAE)                , 0  , 0  , 0  , 500, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #320
+    2103             :   { F(UseX)|F(Vec)|F(Evex)|F(Avx512KZ_SAE)                , 0  , 0  , 0  , 501, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #321
+    2104             :   { F(UseX)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_ER_SAE_B64)  , 0  , 0  , 0  , 216, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #322
+    2105             :   { F(UseX)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_ER_SAE_B32)  , 0  , 0  , 0  , 216, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #323
+    2106             :   { F(UseX)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_ER_SAE)      , 0  , 0  , 0  , 502, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #324
+    2107             :   { F(UseX)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_ER_SAE)      , 0  , 0  , 0  , 503, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #325
+    2108             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 150, 4 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #326
+    2109             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 351, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #327
+    2110             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 353, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #328
+    2111             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512K_B64)                 , 0  , 0  , 0  , 504, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #329
+    2112             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512K_B32)                 , 0  , 0  , 0  , 504, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #330
+    2113             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512K)                     , 0  , 0  , 0  , 505, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #331
+    2114             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512K)                     , 0  , 0  , 0  , 506, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #332
+    2115             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 204, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #333
+    2116             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 85 , 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #334
+    2117             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 255, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #335
+    2118             :   { F(UseX)|F(Vec)|F(Vsib)|F(Vex)|F(Evex)|F(Avx512K)      , 0  , 0  , 79 , 111, 5 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #336
+    2119             :   { F(UseX)|F(Vec)|F(Vsib)|F(Vex)|F(Evex)|F(Avx512K)      , 0  , 0  , 80 , 116, 5 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #337
+    2120             :   { F(UseR)|F(Vsib)|F(Evex)|F(Avx512K)                    , 0  , 0  , 0  , 507, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #338
+    2121             :   { F(UseR)|F(Vsib)|F(Evex)|F(Avx512K)                    , 0  , 0  , 0  , 508, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #339
+    2122             :   { F(UseR)|F(Vsib)|F(Evex)|F(Avx512K)                    , 0  , 0  , 0  , 509, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #340
+    2123             :   { F(UseX)|F(Vec)|F(Vsib)|F(Vex)|F(Evex)|F(Avx512K)      , 0  , 0  , 81 , 121, 5 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #341
+    2124             :   { F(UseX)|F(Vec)|F(Vsib)|F(Vex)|F(Evex)|F(Avx512K)      , 0  , 0  , 82 , 154, 4 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #342
+    2125             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_SAE)                , 0  , 0  , 0  , 85 , 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #343
+    2126             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_SAE)                , 0  , 0  , 0  , 255, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #344
+    2127             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_SAE_B64)            , 0  , 0  , 0  , 219, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #345
+    2128             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_SAE_B32)            , 0  , 0  , 0  , 219, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #346
+    2129             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_SAE)                , 0  , 0  , 0  , 480, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #347
+    2130             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_SAE)                , 0  , 0  , 0  , 481, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #348
+    2131             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 355, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #349
+    2132             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ)                    , 0  , 0  , 0  , 355, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #350
+    2133             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ)                    , 0  , 0  , 0  , 510, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #351
+    2134             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)                         , 0  , 0  , 0  , 511, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #352
+    2135             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 228, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #353
+    2136             :   { F(UseR)|F(Vex)                                        , 0  , 0  , 0  , 444, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #354
+    2137             :   { F(UseR)|F(FixedRM)|F(Vec)|F(Vex)                      , 0  , 0  , 0  , 512, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #355
+    2138             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 83 , 158, 4 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #356
+    2139             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 84 , 158, 4 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #357
+    2140             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_SAE_B64)     , 0  , 0  , 0  , 189, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #358
+    2141             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_SAE_B32)     , 0  , 0  , 0  , 189, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #359
+    2142             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_SAE)         , 0  , 0  , 0  , 489, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #360
+    2143             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 85 , 87 , 6 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #361
+    2144             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 86 , 87 , 6 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #362
+    2145             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)                         , 0  , 0  , 87 , 357, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #363
+    2146             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 0  , 222, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #364
+    2147             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 88 , 87 , 4 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #365
+    2148             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ)                    , 0  , 0  , 89 , 87 , 6 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #366
+    2149             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ)                    , 0  , 0  , 90 , 87 , 6 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #367
+    2150             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 91 , 87 , 4 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #368
+    2151             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ)                    , 0  , 0  , 92 , 87 , 6 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #369
+    2152             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ)                    , 0  , 0  , 93 , 87 , 6 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #370
+    2153             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ)                    , 0  , 0  , 94 , 87 , 6 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #371
+    2154             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ)                    , 0  , 0  , 95 , 87 , 6 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #372
+    2155             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)                         , 0  , 0  , 0  , 236, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #373
+    2156             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)                         , 0  , 0  , 96 , 359, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #374
+    2157             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)                         , 0  , 0  , 97 , 359, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #375
+    2158             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)                         , 0  , 0  , 98 , 359, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #376
+    2159             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)                         , 0  , 0  , 99 , 359, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #377
+    2160             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 513, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #378
+    2161             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)                         , 0  , 0  , 0  , 225, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #379
+    2162             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)                         , 0  , 0  , 0  , 228, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #380
+    2163             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)                         , 0  , 0  , 100, 231, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #381
+    2164             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 101, 234, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #382
+    2165             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 0  , 204, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #383
+    2166             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 102, 237, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #384
+    2167             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 103, 87 , 6 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #385
+    2168             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 104, 87 , 6 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #386
+    2169             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512T4X)|F(Avx512KZ)       , 0  , 0  , 0  , 514, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #387
+    2170             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 0  , 189, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #388
+    2171             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 0  , 192, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #389
+    2172             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 189, 2 , JUMP_TYPE(None)       , SINGLE_REG(RO)  , 0 }, // #390
+    2173             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_B32)                , 0  , 0  , 0  , 189, 3 , JUMP_TYPE(None)       , SINGLE_REG(RO)  , 0 }, // #391
+    2174             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 189, 2 , JUMP_TYPE(None)       , SINGLE_REG(WO)  , 0 }, // #392
+    2175             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_B32)                , 0  , 0  , 0  , 189, 3 , JUMP_TYPE(None)       , SINGLE_REG(WO)  , 0 }, // #393
+    2176             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_B64)                , 0  , 0  , 0  , 189, 3 , JUMP_TYPE(None)       , SINGLE_REG(WO)  , 0 }, // #394
+    2177             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_B64)                , 0  , 0  , 0  , 189, 3 , JUMP_TYPE(None)       , SINGLE_REG(RO)  , 0 }, // #395
+    2178             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 0  , 361, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #396
+    2179             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 0  , 363, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #397
+    2180             :   { F(UseW)|F(Vec)|F(Evex)                                , 0  , 0  , 0  , 515, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #398
+    2181             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 0  , 516, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #399
+    2182             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 0  , 365, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #400
+    2183             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512K)                     , 0  , 0  , 0  , 240, 3 , JUMP_TYPE(None)       , SINGLE_REG(WO)  , 0 }, // #401
+    2184             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512K_B32)                 , 0  , 0  , 0  , 240, 3 , JUMP_TYPE(None)       , SINGLE_REG(WO)  , 0 }, // #402
+    2185             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512K)              , 0  , 0  , 0  , 243, 3 , JUMP_TYPE(None)       , SINGLE_REG(WO)  , 0 }, // #403
+    2186             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512K_B32)          , 0  , 0  , 0  , 243, 3 , JUMP_TYPE(None)       , SINGLE_REG(WO)  , 0 }, // #404
+    2187             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512K_B64)          , 0  , 0  , 0  , 243, 3 , JUMP_TYPE(None)       , SINGLE_REG(WO)  , 0 }, // #405
+    2188             :   { F(UseR)|F(FixedReg)|F(Vec)|F(Vex)                     , 0  , 0  , 0  , 461, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #406
+    2189             :   { F(UseR)|F(FixedReg)|F(Vec)|F(Vex)                     , 0  , 0  , 0  , 462, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #407
+    2190             :   { F(UseR)|F(FixedReg)|F(Vec)|F(Vex)                     , 0  , 0  , 0  , 463, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #408
+    2191             :   { F(UseR)|F(FixedReg)|F(Vec)|F(Vex)                     , 0  , 0  , 0  , 464, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #409
+    2192             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512K_B64)                 , 0  , 0  , 0  , 240, 3 , JUMP_TYPE(None)       , SINGLE_REG(WO)  , 0 }, // #410
+    2193             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_B32)                , 0  , 0  , 0  , 204, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #411
+    2194             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 193, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #412
+    2195             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_B32)         , 0  , 0  , 0  , 167, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #413
+    2196             :   { F(UseX)|F(Vec)|F(Evex)|F(Avx512KZ_B32)                , 0  , 0  , 0  , 216, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #414
+    2197             :   { F(UseX)|F(Vec)|F(Evex)|F(Avx512KZ_B64)                , 0  , 0  , 0  , 216, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #415
+    2198             :   { F(UseX)|F(Vec)|F(Evex)|F(Avx512KZ)                    , 0  , 0  , 0  , 216, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #416
+    2199             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 162, 4 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #417
+    2200             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_B64)         , 0  , 0  , 105, 93 , 6 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #418
+    2201             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_B64)         , 0  , 0  , 106, 93 , 6 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #419
+    2202             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 96 , 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #420
+    2203             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 95 , 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #421
+    2204             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_B64)         , 0  , 0  , 107, 166, 4 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #422
+    2205             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)                         , 0  , 0  , 0  , 465, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #423
+    2206             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)                         , 0  , 0  , 0  , 466, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #424
+    2207             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)                         , 0  , 0  , 0  , 340, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #425
+    2208             :   { F(UseX)|F(Vec)|F(Vsib)|F(Vex)|F(Evex)|F(Avx512K)      , 0  , 0  , 108, 116, 5 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #426
+    2209             :   { F(UseX)|F(Vec)|F(Vsib)|F(Vex)|F(Evex)|F(Avx512K)      , 0  , 0  , 109, 111, 5 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #427
+    2210             :   { F(UseX)|F(Vec)|F(Vsib)|F(Vex)|F(Evex)|F(Avx512K)      , 0  , 0  , 110, 154, 4 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #428
+    2211             :   { F(UseX)|F(Vec)|F(Vsib)|F(Vex)|F(Evex)|F(Avx512K)      , 0  , 0  , 111, 121, 5 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #429
+    2212             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 0  , 367, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #430
+    2213             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 0  , 369, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #431
+    2214             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 0  , 371, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #432
+    2215             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 0  , 517, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #433
+    2216             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_B64)                , 0  , 0  , 0  , 204, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #434
+    2217             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 151, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #435
+    2218             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 112, 158, 4 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #436
+    2219             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 113, 158, 4 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #437
+    2220             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 0  , 189, 3 , JUMP_TYPE(None)       , SINGLE_REG(RO)  , 0 }, // #438
+    2221             :   { F(UseW)|F(Vec)|F(Evex)                                , 0  , 0  , 0  , 518, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #439
+    2222             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ)                    , 0  , 0  , 0  , 246, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #440
+    2223             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ)                    , 0  , 0  , 0  , 249, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #441
+    2224             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ)                    , 0  , 0  , 0  , 252, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #442
+    2225             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 0  , 255, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #443
+    2226             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 0  , 258, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #444
+    2227             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 0  , 201, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #445
+    2228             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 0  , 261, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #446
+    2229             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_B32)                , 0  , 0  , 0  , 91 , 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #447
+    2230             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_B64)                , 0  , 0  , 0  , 91 , 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #448
+    2231             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 150, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #449
+    2232             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_B32)                , 0  , 0  , 0  , 219, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #450
+    2233             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_B64)                , 0  , 0  , 0  , 219, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #451
+    2234             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 114, 373, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #452
+    2235             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 115, 373, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #453
+    2236             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 116, 373, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #454
+    2237             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 117, 373, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #455
+    2238             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)                         , 0  , 0  , 0  , 189, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #456
+    2239             :   { F(UseW)|F(Vec)|F(Vsib)|F(Evex)|F(Avx512K)             , 0  , 0  , 0  , 264, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #457
+    2240             :   { F(UseW)|F(Vec)|F(Vsib)|F(Evex)|F(Avx512K)             , 0  , 0  , 0  , 375, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #458
+    2241             :   { F(UseW)|F(Vec)|F(Vsib)|F(Evex)|F(Avx512K)             , 0  , 0  , 0  , 267, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #459
+    2242             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 377, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #460
+    2243             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_B32)         , 0  , 0  , 0  , 219, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #461
+    2244             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 0  , 219, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #462
+    2245             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_B32)         , 0  , 0  , 118, 99 , 6 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #463
+    2246             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)                         , 0  , 0  , 0  , 219, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #464
+    2247             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_B64)         , 0  , 0  , 119, 99 , 6 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #465
+    2248             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 120, 99 , 6 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #466
+    2249             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_B32)         , 0  , 0  , 121, 99 , 6 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #467
+    2250             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_B64)                , 0  , 0  , 122, 105, 6 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #468
+    2251             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 123, 99 , 6 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #469
+    2252             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_B32)         , 0  , 0  , 124, 99 , 6 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #470
+    2253             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_B64)         , 0  , 0  , 125, 99 , 6 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #471
+    2254             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 126, 99 , 6 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #472
+    2255             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 0  , 189, 3 , JUMP_TYPE(None)       , SINGLE_REG(WO)  , 0 }, // #473
+    2256             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_B32)         , 0  , 0  , 0  , 189, 3 , JUMP_TYPE(None)       , SINGLE_REG(WO)  , 0 }, // #474
+    2257             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_B64)         , 0  , 0  , 0  , 189, 3 , JUMP_TYPE(None)       , SINGLE_REG(WO)  , 0 }, // #475
+    2258             :   { F(UseX)|F(Vec)|F(Evex)|F(Avx512KZ_B32)                , 0  , 0  , 0  , 213, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #476
+    2259             :   { F(UseX)|F(Vec)|F(Evex)|F(Avx512KZ_B64)                , 0  , 0  , 0  , 213, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #477
+    2260             :   { F(UseR)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 379, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #478
+    2261             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512K)                     , 0  , 0  , 0  , 270, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #479
+    2262             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512K_B32)                 , 0  , 0  , 0  , 270, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #480
+    2263             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512K_B64)                 , 0  , 0  , 0  , 270, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #481
+    2264             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_SAE_B64)            , 0  , 0  , 0  , 192, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #482
+    2265             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_SAE_B32)            , 0  , 0  , 0  , 192, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #483
+    2266             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_SAE)                , 0  , 0  , 0  , 519, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #484
+    2267             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_SAE)                , 0  , 0  , 0  , 511, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #485
+    2268             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ)                    , 0  , 0  , 0  , 489, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #486
+    2269             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ)                    , 0  , 0  , 0  , 490, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #487
+    2270             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_SAE)                , 0  , 0  , 0  , 489, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #488
+    2271             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_SAE)                , 0  , 0  , 0  , 490, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #489
+    2272             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 490, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #490
+    2273             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ)                    , 0  , 0  , 0  , 519, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #491
+    2274             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ)                    , 0  , 0  , 0  , 511, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #492
+    2275             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 101, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #493
+    2276             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 519, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #494
+    2277             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 511, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #495
+    2278             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_ER_SAE_B64)         , 0  , 0  , 0  , 189, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #496
+    2279             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_ER_SAE_B32)         , 0  , 0  , 0  , 189, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #497
+    2280             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_ER_SAE)             , 0  , 0  , 0  , 489, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #498
+    2281             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_ER_SAE)             , 0  , 0  , 0  , 490, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #499
+    2282             :   { F(UseW)|F(Vec)|F(Vsib)|F(Evex)|F(Avx512K)             , 0  , 0  , 0  , 381, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #500
+    2283             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_B32)                , 0  , 0  , 0  , 193, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #501
+    2284             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_B64)                , 0  , 0  , 0  , 193, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #502
+    2285             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_B32)         , 0  , 0  , 0  , 192, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #503
+    2286             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_B64)         , 0  , 0  , 0  , 192, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #504
+    2287             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_ER_SAE_B64)  , 0  , 0  , 0  , 204, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #505
+    2288             :   { F(UseW)|F(Vex)                                        , 0  , 0  , 0  , 486, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #506
+    2289             :   { F(UseR)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 291, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #507
+    2290             :   { F(UseR)                                               , 0  , 0  , 0  , 520, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #508
+    2291             :   { F(UseR)|F(FixedReg)                                   , 0  , 0  , 0  , 521, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #509
+    2292             :   { F(UseX)|F(UseXX)|F(Lock)|F(XAcquire)|F(XRelease)      , 0  , 0  , 0  , 170, 4 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #510
+    2293             :   { F(UseR)                                               , 0  , 0  , 0  , 522, 1 , JUMP_TYPE(Conditional), SINGLE_REG(None), 0 }, // #511
+    2294             :   { F(UseX)|F(UseXX)|F(Lock)|F(XAcquire)                  , 0  , 0  , 0  , 60 , 8 , JUMP_TYPE(None)       , SINGLE_REG(RO)  , 0 }, // #512
+    2295             :   { F(UseR)|F(FixedReg)                                   , 0  , 0  , 0  , 523, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #513
+    2296             :   { F(UseR)|F(FixedReg)                                   , 0  , 0  , 0  , 524, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #514
+    2297             :   { F(UseW)|F(FixedReg)                                   , 0  , 0  , 0  , 525, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #515
+    2298             :   { F(UseW)|F(FixedReg)                                   , 0  , 0  , 0  , 526, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }  // #516
+    2299             : };
+    2300             : #undef SINGLE_REG
+    2301             : #undef JUMP_TYPE
+    2302             : #undef F
+    2303             : // ----------------------------------------------------------------------------
+    2304             : // ${commonData:End}
+    2305             : 
+    2306             : // ${operationData:Begin}
+    2307             : // ------------------- Automatically generated, do not edit -------------------
+    2308             : #define OP_FLAG(F) X86Inst::kOperation##F
+    2309             : #define FEATURE(F) CpuInfo::kX86Feature##F
+    2310             : #define SPECIAL(F) x86::kSpecialReg_##F
+    2311             : const X86Inst::OperationData X86InstDB::operationData[] = {
+    2312             :   { 0, { 0 }, 0, 0 }, // #0
+    2313             :   { 0, { 0 }, 0, SPECIAL(FLAGS_AF) | SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_PF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF) }, // #1
+    2314             :   { 0, { 0 }, SPECIAL(FLAGS_CF), SPECIAL(FLAGS_AF) | SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_PF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF) }, // #2
+    2315             :   { 0, { FEATURE(ADX) }, SPECIAL(FLAGS_CF), SPECIAL(FLAGS_CF) }, // #3
+    2316             :   { 0, { FEATURE(SSE2) }, 0, 0 }, // #4
+    2317             :   { 0, { FEATURE(SSE) }, 0, 0 }, // #5
+    2318             :   { 0, { FEATURE(SSE3) }, 0, 0 }, // #6
+    2319             :   { 0, { FEATURE(ADX) }, SPECIAL(FLAGS_OF), SPECIAL(FLAGS_OF) }, // #7
+    2320             :   { 0, { FEATURE(AESNI) }, 0, 0 }, // #8
+    2321             :   { 0, { FEATURE(BMI) }, 0, SPECIAL(FLAGS_AF) | SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_PF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF) }, // #9
+    2322             :   { 0, { 0 }, 0, SPECIAL(FLAGS_ZF) }, // #10
+    2323             :   { 0, { FEATURE(TBM) }, 0, 0 }, // #11
+    2324             :   { 0, { FEATURE(SSE4_1) }, 0, 0 }, // #12
+    2325             :   { 0, { FEATURE(MPX) }, 0, 0 }, // #13
+    2326             :   { 0, { 0 }, 0, SPECIAL(FLAGS_AF) | SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_PF) | SPECIAL(FLAGS_SF) }, // #14
+    2327             :   { 0, { FEATURE(BMI2) }, 0, SPECIAL(FLAGS_AF) | SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_PF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF) }, // #15
+    2328             :   { OP_FLAG(Volatile), { 0 }, 0, SPECIAL(FLAGS_AF) | SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_PF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF) }, // #16
+    2329             :   { OP_FLAG(Volatile), { FEATURE(SMAP) }, 0, SPECIAL(FLAGS_AC) }, // #17
+    2330             :   { 0, { 0 }, 0, SPECIAL(FLAGS_CF) }, // #18
+    2331             :   { 0, { 0 }, 0, SPECIAL(FLAGS_DF) }, // #19
+    2332             :   { OP_FLAG(Volatile), { FEATURE(CLFLUSH) }, 0, 0 }, // #20
+    2333             :   { OP_FLAG(Volatile), { FEATURE(CLFLUSHOPT) }, 0, 0 }, // #21
+    2334             :   { OP_FLAG(Volatile), { 0 }, 0, SPECIAL(FLAGS_IF) }, // #22
+    2335             :   { OP_FLAG(Volatile) | OP_FLAG(Privileged), { 0 }, 0, 0 }, // #23
+    2336             :   { OP_FLAG(Volatile), { FEATURE(CLWB) }, 0, 0 }, // #24
+    2337             :   { OP_FLAG(Volatile), { FEATURE(CLZERO) }, 0, 0 }, // #25
+    2338             :   { 0, { 0 }, SPECIAL(FLAGS_CF), SPECIAL(FLAGS_CF) }, // #26
+    2339             :   { 0, { FEATURE(CMOV) }, SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_ZF), 0 }, // #27
+    2340             :   { 0, { FEATURE(CMOV) }, SPECIAL(FLAGS_CF), 0 }, // #28
+    2341             :   { 0, { FEATURE(CMOV) }, SPECIAL(FLAGS_ZF), 0 }, // #29
+    2342             :   { 0, { FEATURE(CMOV) }, SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF), 0 }, // #30
+    2343             :   { 0, { FEATURE(CMOV) }, SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_SF), 0 }, // #31
+    2344             :   { 0, { FEATURE(CMOV) }, SPECIAL(FLAGS_OF), 0 }, // #32
+    2345             :   { 0, { FEATURE(CMOV) }, SPECIAL(FLAGS_PF), 0 }, // #33
+    2346             :   { 0, { FEATURE(CMOV) }, SPECIAL(FLAGS_SF), 0 }, // #34
+    2347             :   { 0, { 0 }, SPECIAL(FLAGS_DF), SPECIAL(FLAGS_AF) | SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_PF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF) }, // #35
+    2348             :   { 0, { FEATURE(I486) }, 0, SPECIAL(FLAGS_AF) | SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_PF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF) }, // #36
+    2349             :   { OP_FLAG(Volatile), { FEATURE(CMPXCHG16B) }, 0, SPECIAL(FLAGS_ZF) }, // #37
+    2350             :   { OP_FLAG(Volatile), { FEATURE(CMPXCHG8B) }, 0, SPECIAL(FLAGS_ZF) }, // #38
+    2351             :   { 0, { FEATURE(SSE2) }, 0, SPECIAL(FLAGS_AF) | SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_PF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF) }, // #39
+    2352             :   { 0, { FEATURE(SSE) }, 0, SPECIAL(FLAGS_AF) | SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_PF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF) }, // #40
+    2353             :   { OP_FLAG(Volatile), { FEATURE(I486) }, 0, 0 }, // #41
+    2354             :   { 0, { FEATURE(SSE4_2) }, 0, 0 }, // #42
+    2355             :   { 0, { 0 }, 0, SPECIAL(FLAGS_AF) | SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_PF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF) }, // #43
+    2356             :   { OP_FLAG(Volatile), { FEATURE(MMX) }, 0, 0 }, // #44
+    2357             :   { OP_FLAG(Volatile), { 0 }, 0, 0 }, // #45
+    2358             :   { 0, { FEATURE(SSE4A) }, 0, 0 }, // #46
+    2359             :   { 0, { 0 }, 0, SPECIAL(X87SW_C0) | SPECIAL(X87SW_C1) | SPECIAL(X87SW_C2) | SPECIAL(X87SW_C3) }, // #47
+    2360             :   { 0, { FEATURE(CMOV) }, 0, SPECIAL(X87SW_C0) | SPECIAL(X87SW_C1) | SPECIAL(X87SW_C2) | SPECIAL(X87SW_C3) }, // #48
+    2361             :   { 0, { 0 }, 0, SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_PF) | SPECIAL(FLAGS_ZF) | SPECIAL(X87SW_C1) }, // #49
+    2362             :   { OP_FLAG(Volatile), { FEATURE(3DNOW) }, 0, 0 }, // #50
+    2363             :   { 0, { FEATURE(SSE3) }, 0, SPECIAL(X87SW_C0) | SPECIAL(X87SW_C1) | SPECIAL(X87SW_C2) | SPECIAL(X87SW_C3) }, // #51
+    2364             :   { OP_FLAG(Volatile), { FEATURE(FXSR) }, 0, SPECIAL(X87SW_C0) | SPECIAL(X87SW_C1) | SPECIAL(X87SW_C2) | SPECIAL(X87SW_C3) }, // #52
+    2365             :   { OP_FLAG(Volatile), { FEATURE(FXSR) }, 0, 0 }, // #53
+    2366             :   { OP_FLAG(Volatile), { 0 }, SPECIAL(FLAGS_OF), 0 }, // #54
+    2367             :   { OP_FLAG(Volatile) | OP_FLAG(Privileged), { FEATURE(I486) }, 0, 0 }, // #55
+    2368             :   { OP_FLAG(Volatile), { 0 }, SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_ZF), 0 }, // #56
+    2369             :   { OP_FLAG(Volatile), { 0 }, SPECIAL(FLAGS_CF), 0 }, // #57
+    2370             :   { OP_FLAG(Volatile), { 0 }, SPECIAL(FLAGS_ZF), 0 }, // #58
+    2371             :   { OP_FLAG(Volatile), { 0 }, SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF), 0 }, // #59
+    2372             :   { OP_FLAG(Volatile), { 0 }, SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_SF), 0 }, // #60
+    2373             :   { OP_FLAG(Volatile), { 0 }, SPECIAL(FLAGS_PF), 0 }, // #61
+    2374             :   { OP_FLAG(Volatile), { 0 }, SPECIAL(FLAGS_SF), 0 }, // #62
+    2375             :   { 0, { FEATURE(AVX512_DQ) }, 0, 0 }, // #63
+    2376             :   { 0, { FEATURE(AVX512_BW) }, 0, 0 }, // #64
+    2377             :   { 0, { FEATURE(AVX512_F) }, 0, 0 }, // #65
+    2378             :   { 0, { FEATURE(AVX512_DQ) }, 0, SPECIAL(FLAGS_AF) | SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_PF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF) }, // #66
+    2379             :   { 0, { FEATURE(AVX512_BW) }, 0, SPECIAL(FLAGS_AF) | SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_PF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF) }, // #67
+    2380             :   { 0, { FEATURE(AVX512_F) }, 0, SPECIAL(FLAGS_AF) | SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_PF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF) }, // #68
+    2381             :   { OP_FLAG(Volatile), { FEATURE(LAHFSAHF) }, SPECIAL(FLAGS_AF) | SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_PF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF), 0 }, // #69
+    2382             :   { OP_FLAG(Volatile), { 0 }, 0, SPECIAL(FLAGS_ZF) }, // #70
+    2383             :   { OP_FLAG(Barrier) | OP_FLAG(Volatile), { FEATURE(SSE2) }, 0, 0 }, // #71
+    2384             :   { 0, { 0 }, SPECIAL(FLAGS_DF), 0 }, // #72
+    2385             :   { 0, { FEATURE(LZCNT) }, 0, SPECIAL(FLAGS_AF) | SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_PF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF) }, // #73
+    2386             :   { 0, { FEATURE(MMX2) }, 0, 0 }, // #74
+    2387             :   { OP_FLAG(Volatile) | OP_FLAG(Privileged), { FEATURE(MONITOR) }, 0, 0 }, // #75
+    2388             :   { OP_FLAG(MovCrDr), { 0 }, 0, 0 }, // #76
+    2389             :   { 0, { FEATURE(MOVBE) }, 0, 0 }, // #77
+    2390             :   { 0, { FEATURE(MMX), FEATURE(SSE2) }, 0, 0 }, // #78
+    2391             :   { OP_FLAG(MovSsSd), { FEATURE(SSE2) }, 0, 0 }, // #79
+    2392             :   { OP_FLAG(MovSsSd), { FEATURE(SSE) }, 0, 0 }, // #80
+    2393             :   { 0, { FEATURE(BMI2) }, 0, 0 }, // #81
+    2394             :   { 0, { FEATURE(SSSE3) }, 0, 0 }, // #82
+    2395             :   { 0, { FEATURE(MMX2), FEATURE(SSE2) }, 0, 0 }, // #83
+    2396             :   { 0, { FEATURE(3DNOW) }, 0, 0 }, // #84
+    2397             :   { 0, { FEATURE(PCLMULQDQ) }, 0, 0 }, // #85
+    2398             :   { 0, { FEATURE(SSE4_2) }, 0, SPECIAL(FLAGS_AF) | SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_PF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF) }, // #86
+    2399             :   { OP_FLAG(Volatile), { FEATURE(PCOMMIT) }, 0, 0 }, // #87
+    2400             :   { 0, { FEATURE(MMX2), FEATURE(SSE2), FEATURE(SSE4_1) }, 0, 0 }, // #88
+    2401             :   { 0, { FEATURE(3DNOW2) }, 0, 0 }, // #89
+    2402             :   { 0, { FEATURE(GEODE) }, 0, 0 }, // #90
+    2403             :   { 0, { FEATURE(POPCNT) }, 0, SPECIAL(FLAGS_AF) | SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_PF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF) }, // #91
+    2404             :   { OP_FLAG(Prefetch), { FEATURE(3DNOW) }, 0, 0 }, // #92
+    2405             :   { OP_FLAG(Prefetch), { FEATURE(MMX2) }, 0, 0 }, // #93
+    2406             :   { OP_FLAG(Prefetch), { FEATURE(PREFETCHW) }, 0, SPECIAL(FLAGS_AF) | SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_PF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF) }, // #94
+    2407             :   { OP_FLAG(Prefetch), { FEATURE(PREFETCHWT1) }, 0, SPECIAL(FLAGS_AF) | SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_PF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF) }, // #95
+    2408             :   { 0, { FEATURE(SSE4_1) }, 0, SPECIAL(FLAGS_AF) | SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_PF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF) }, // #96
+    2409             :   { 0, { 0 }, 0, SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_OF) }, // #97
+    2410             :   { OP_FLAG(Volatile), { FEATURE(FSGSBASE) }, 0, 0 }, // #98
+    2411             :   { OP_FLAG(Volatile) | OP_FLAG(Privileged), { FEATURE(MSR) }, SPECIAL(MSR), 0 }, // #99
+    2412             :   { OP_FLAG(Volatile), { FEATURE(RDRAND) }, 0, SPECIAL(FLAGS_AF) | SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_PF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF) }, // #100
+    2413             :   { OP_FLAG(Volatile), { FEATURE(RDSEED) }, 0, SPECIAL(FLAGS_AF) | SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_PF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF) }, // #101
+    2414             :   { OP_FLAG(Volatile), { FEATURE(RDTSC) }, 0, 0 }, // #102
+    2415             :   { OP_FLAG(Volatile), { FEATURE(RDTSCP) }, 0, 0 }, // #103
+    2416             :   { OP_FLAG(Volatile), { FEATURE(LAHFSAHF) }, 0, SPECIAL(FLAGS_AF) | SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_PF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF) }, // #104
+    2417             :   { 0, { 0 }, SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_ZF), 0 }, // #105
+    2418             :   { 0, { 0 }, SPECIAL(FLAGS_CF), 0 }, // #106
+    2419             :   { 0, { 0 }, SPECIAL(FLAGS_ZF), 0 }, // #107
+    2420             :   { 0, { 0 }, SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF), 0 }, // #108
+    2421             :   { 0, { 0 }, SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_SF), 0 }, // #109
+    2422             :   { 0, { 0 }, SPECIAL(FLAGS_OF), 0 }, // #110
+    2423             :   { 0, { 0 }, SPECIAL(FLAGS_PF), 0 }, // #111
+    2424             :   { 0, { 0 }, SPECIAL(FLAGS_SF), 0 }, // #112
+    2425             :   { OP_FLAG(Barrier) | OP_FLAG(Volatile), { FEATURE(MMX2) }, 0, 0 }, // #113
+    2426             :   { 0, { FEATURE(SHA) }, 0, 0 }, // #114
+    2427             :   { 0, { FEATURE(AVX512_4FMAPS) }, 0, 0 }, // #115
+    2428             :   { 0, { FEATURE(AVX), FEATURE(AVX512_F), FEATURE(AVX512_VL) }, 0, 0 }, // #116
+    2429             :   { 0, { FEATURE(AVX), FEATURE(AVX512_F) }, 0, 0 }, // #117
+    2430             :   { 0, { FEATURE(AVX) }, 0, 0 }, // #118
+    2431             :   { 0, { FEATURE(AESNI), FEATURE(AVX) }, 0, 0 }, // #119
+    2432             :   { 0, { FEATURE(AVX512_F), FEATURE(AVX512_VL) }, 0, 0 }, // #120
+    2433             :   { 0, { FEATURE(AVX), FEATURE(AVX512_DQ), FEATURE(AVX512_VL) }, 0, 0 }, // #121
+    2434             :   { 0, { FEATURE(AVX512_BW), FEATURE(AVX512_VL) }, 0, 0 }, // #122
+    2435             :   { 0, { FEATURE(AVX512_DQ), FEATURE(AVX512_VL) }, 0, 0 }, // #123
+    2436             :   { 0, { FEATURE(AVX2) }, 0, 0 }, // #124
+    2437             :   { 0, { FEATURE(AVX), FEATURE(AVX2), FEATURE(AVX512_F), FEATURE(AVX512_VL) }, 0, 0 }, // #125
+    2438             :   { 0, { FEATURE(AVX), FEATURE(AVX512_F) }, 0, SPECIAL(FLAGS_AF) | SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_PF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF) }, // #126
+    2439             :   { 0, { FEATURE(AVX512_F), FEATURE(AVX512_VL), FEATURE(F16C) }, 0, 0 }, // #127
+    2440             :   { 0, { FEATURE(AVX512_ERI) }, 0, 0 }, // #128
+    2441             :   { 0, { FEATURE(AVX512_F), FEATURE(AVX512_VL), FEATURE(FMA) }, 0, 0 }, // #129
+    2442             :   { 0, { FEATURE(AVX512_F), FEATURE(FMA) }, 0, 0 }, // #130
+    2443             :   { 0, { FEATURE(FMA4) }, 0, 0 }, // #131
+    2444             :   { 0, { FEATURE(XOP) }, 0, 0 }, // #132
+    2445             :   { 0, { FEATURE(AVX2), FEATURE(AVX512_F), FEATURE(AVX512_VL) }, 0, 0 }, // #133
+    2446             :   { 0, { FEATURE(AVX512_PFI) }, 0, 0 }, // #134
+    2447             :   { 0, { FEATURE(AVX), FEATURE(AVX2) }, 0, 0 }, // #135
+    2448             :   { 0, { FEATURE(AVX512_4VNNIW) }, 0, 0 }, // #136
+    2449             :   { 0, { FEATURE(AVX), FEATURE(AVX2), FEATURE(AVX512_BW), FEATURE(AVX512_VL) }, 0, 0 }, // #137
+    2450             :   { 0, { FEATURE(AVX2), FEATURE(AVX512_BW), FEATURE(AVX512_VL) }, 0, 0 }, // #138
+    2451             :   { 0, { FEATURE(AVX512_CDI), FEATURE(AVX512_VL) }, 0, 0 }, // #139
+    2452             :   { 0, { FEATURE(AVX), FEATURE(PCLMULQDQ) }, 0, 0 }, // #140
+    2453             :   { 0, { FEATURE(AVX) }, 0, SPECIAL(FLAGS_AF) | SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_PF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF) }, // #141
+    2454             :   { 0, { FEATURE(AVX512_VBMI), FEATURE(AVX512_VL) }, 0, 0 }, // #142
+    2455             :   { 0, { FEATURE(AVX), FEATURE(AVX512_BW) }, 0, 0 }, // #143
+    2456             :   { 0, { FEATURE(AVX), FEATURE(AVX512_DQ) }, 0, 0 }, // #144
+    2457             :   { 0, { FEATURE(AVX512_IFMA), FEATURE(AVX512_VL) }, 0, 0 }, // #145
+    2458             :   { 0, { FEATURE(AVX512_VPOPCNTDQ) }, 0, 0 }, // #146
+    2459             :   { OP_FLAG(Volatile) | OP_FLAG(Privileged), { FEATURE(MSR) }, 0, SPECIAL(MSR) }, // #147
+    2460             :   { OP_FLAG(Volatile), { FEATURE(RTM) }, 0, 0 }, // #148
+    2461             :   { OP_FLAG(Volatile), { FEATURE(XSAVE) }, SPECIAL(XCR), 0 }, // #149
+    2462             :   { OP_FLAG(Volatile), { FEATURE(XSAVES) }, SPECIAL(XCR), 0 }, // #150
+    2463             :   { OP_FLAG(Volatile), { FEATURE(XSAVEC) }, SPECIAL(XCR), 0 }, // #151
+    2464             :   { OP_FLAG(Volatile), { FEATURE(XSAVEOPT) }, SPECIAL(XCR), 0 }, // #152
+    2465             :   { OP_FLAG(Volatile) | OP_FLAG(Privileged), { FEATURE(XSAVE) }, 0, SPECIAL(XCR) }, // #153
+    2466             :   { OP_FLAG(Volatile), { FEATURE(TSX) }, 0, SPECIAL(FLAGS_AF) | SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_PF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF) }  // #154
+    2467             : };
+    2468             : #undef SPECIAL
+    2469             : #undef FEATURE
+    2470             : #undef OP_FLAG
+    2471             : // ----------------------------------------------------------------------------
+    2472             : // ${operationData:End}
+    2473             : 
+    2474             : // ${sseToAvxData:Begin}
+    2475             : // ------------------- Automatically generated, do not edit -------------------
+    2476             : const X86Inst::SseToAvxData X86InstDB::sseToAvxData[] = {
+    2477             :   { X86Inst::kSseToAvxNone     , 0    }, // #0
+    2478             :   { X86Inst::kSseToAvxExtend   , 725  }, // #1
+    2479             :   { X86Inst::kSseToAvxExtend   , 724  }, // #2
+    2480             :   { X86Inst::kSseToAvxMove     , 724  }, // #3
+    2481             :   { X86Inst::kSseToAvxExtend   , 723  }, // #4
+    2482             :   { X86Inst::kSseToAvxBlend    , 723  }, // #5
+    2483             :   { X86Inst::kSseToAvxExtend   , 671  }, // #6
+    2484             :   { X86Inst::kSseToAvxExtend   , 670  }, // #7
+    2485             :   { X86Inst::kSseToAvxMove     , 667  }, // #8
+    2486             :   { X86Inst::kSseToAvxMove     , 666  }, // #9
+    2487             :   { X86Inst::kSseToAvxMove     , 665  }, // #10
+    2488             :   { X86Inst::kSseToAvxMove     , 672  }, // #11
+    2489             :   { X86Inst::kSseToAvxExtend   , 672  }, // #12
+    2490             :   { X86Inst::kSseToAvxExtend   , 673  }, // #13
+    2491             :   { X86Inst::kSseToAvxMove     , 673  }, // #14
+    2492             :   { X86Inst::kSseToAvxMove     , 674  }, // #15
+    2493             :   { X86Inst::kSseToAvxMove     , 676  }, // #16
+    2494             :   { X86Inst::kSseToAvxMove     , 678  }, // #17
+    2495             :   { X86Inst::kSseToAvxMove     , 679  }, // #18
+    2496             :   { X86Inst::kSseToAvxExtend   , 681  }, // #19
+    2497             :   { X86Inst::kSseToAvxMove     , 695  }, // #20
+    2498             :   { X86Inst::kSseToAvxExtend   , 708  }, // #21
+    2499             :   { X86Inst::kSseToAvxExtend   , 707  }, // #22
+    2500             :   { X86Inst::kSseToAvxExtend   , 712  }, // #23
+    2501             :   { X86Inst::kSseToAvxMove     , 616  }, // #24
+    2502             :   { X86Inst::kSseToAvxMove     , 597  }, // #25
+    2503             :   { X86Inst::kSseToAvxExtend   , 598  }, // #26
+    2504             :   { X86Inst::kSseToAvxExtend   , 597  }, // #27
+    2505             :   { X86Inst::kSseToAvxMove     , 595  }, // #28
+    2506             :   { X86Inst::kSseToAvxMove     , 594  }, // #29
+    2507             :   { X86Inst::kSseToAvxMove     , 593  }, // #30
+    2508             :   { X86Inst::kSseToAvxExtend   , 599  }, // #31
+    2509             :   { X86Inst::kSseToAvxMoveIfMem, 599  }, // #32
+    2510             :   { X86Inst::kSseToAvxMove     , 599  }, // #33
+    2511             :   { X86Inst::kSseToAvxMove     , 598  }, // #34
+    2512             :   { X86Inst::kSseToAvxMoveIfMem, 593  }, // #35
+    2513             :   { X86Inst::kSseToAvxMove     , 591  }, // #36
+    2514             :   { X86Inst::kSseToAvxExtend   , 590  }, // #37
+    2515             :   { X86Inst::kSseToAvxExtend   , 589  }, // #38
+    2516             :   { X86Inst::kSseToAvxExtend   , 583  }, // #39
+    2517             :   { X86Inst::kSseToAvxMove     , 583  }, // #40
+    2518             :   { X86Inst::kSseToAvxMove     , 584  }, // #41
+    2519             :   { X86Inst::kSseToAvxExtend   , 584  }, // #42
+    2520             :   { X86Inst::kSseToAvxExtend   , 585  }, // #43
+    2521             :   { X86Inst::kSseToAvxExtend   , 587  }, // #44
+    2522             :   { X86Inst::kSseToAvxExtend   , 586  }, // #45
+    2523             :   { X86Inst::kSseToAvxBlend    , 587  }, // #46
+    2524             :   { X86Inst::kSseToAvxExtend   , 593  }, // #47
+    2525             :   { X86Inst::kSseToAvxExtend   , 596  }, // #48
+    2526             :   { X86Inst::kSseToAvxMove     , 596  }, // #49
+    2527             :   { X86Inst::kSseToAvxMove     , 637  }, // #50
+    2528             :   { X86Inst::kSseToAvxExtend   , 623  }, // #51
+    2529             :   { X86Inst::kSseToAvxExtend   , 624  }, // #52
+    2530             :   { X86Inst::kSseToAvxExtend   , 630  }, // #53
+    2531             :   { X86Inst::kSseToAvxMove     , 632  }, // #54
+    2532             :   { X86Inst::kSseToAvxExtend   , 633  }, // #55
+    2533             :   { X86Inst::kSseToAvxExtend   , 634  }, // #56
+    2534             :   { X86Inst::kSseToAvxMove     , 633  }, // #57
+    2535             :   { X86Inst::kSseToAvxExtend   , 649  }, // #58
+    2536             :   { X86Inst::kSseToAvxExtend   , 651  }, // #59
+    2537             :   { X86Inst::kSseToAvxExtend   , 652  }, // #60
+    2538             :   { X86Inst::kSseToAvxExtend   , 653  }, // #61
+    2539             :   { X86Inst::kSseToAvxExtend   , 654  }, // #62
+    2540             :   { X86Inst::kSseToAvxExtend   , 655  }, // #63
+    2541             :   { X86Inst::kSseToAvxMove     , 663  }, // #64
+    2542             :   { X86Inst::kSseToAvxMove     , 681  }, // #65
+    2543             :   { X86Inst::kSseToAvxExtend   , 680  }, // #66
+    2544             :   { X86Inst::kSseToAvxExtend   , 682  }, // #67
+    2545             :   { X86Inst::kSseToAvxExtend   , 677  }, // #68
+    2546             :   { X86Inst::kSseToAvxExtend   , 685  }, // #69
+    2547             :   { X86Inst::kSseToAvxExtend   , 697  }, // #70
+    2548             :   { X86Inst::kSseToAvxMove     , 697  }, // #71
+    2549             :   { X86Inst::kSseToAvxExtend   , 696  }, // #72
+    2550             :   { X86Inst::kSseToAvxExtend   , 699  }, // #73
+    2551             :   { X86Inst::kSseToAvxExtend   , 703  }, // #74
+    2552             :   { X86Inst::kSseToAvxExtend   , 706  }, // #75
+    2553             :   { X86Inst::kSseToAvxMove     , 707  }, // #76
+    2554             :   { X86Inst::kSseToAvxExtend   , 715  }, // #77
+    2555             :   { X86Inst::kSseToAvxExtend   , 709  }, // #78
+    2556             :   { X86Inst::kSseToAvxMove     , 722  }, // #79
+    2557             :   { X86Inst::kSseToAvxExtend   , 722  }, // #80
+    2558             :   { X86Inst::kSseToAvxMove     , 717  }, // #81
+    2559             :   { X86Inst::kSseToAvxExtend   , 717  }, // #82
+    2560             :   { X86Inst::kSseToAvxExtend   , 693  }, // #83
+    2561             :   { X86Inst::kSseToAvxMove     , 690  }, // #84
+    2562             :   { X86Inst::kSseToAvxExtend   , 690  }, // #85
+    2563             :   { X86Inst::kSseToAvxExtend   , 683  }, // #86
+    2564             :   { X86Inst::kSseToAvxExtend   , -16  }  // #87
+    2565             : };
+    2566             : // ----------------------------------------------------------------------------
+    2567             : // ${sseToAvxData:End}
+    2568             : 
+    2569             : // ============================================================================
+    2570             : // [asmjit::X86Inst - Id <-> Name]
+    2571             : // ============================================================================
+    2572             : 
+    2573             : #if !defined(ASMJIT_DISABLE_TEXT)
+    2574             : // ${nameData:Begin}
+    2575             : // ------------------- Automatically generated, do not edit -------------------
+    2576             : const char X86InstDB::nameData[] =
+    2577             :   "\0" "aaa\0" "aad\0" "aam\0" "aas\0" "adc\0" "adcx\0" "adox\0" "arpl\0"
+    2578             :   "bextr\0" "blcfill\0" "blci\0" "blcic\0" "blcmsk\0" "blcs\0" "blsfill\0"
+    2579             :   "blsi\0" "blsic\0" "blsmsk\0" "blsr\0" "bndcl\0" "bndcn\0" "bndcu\0"
+    2580             :   "bndldx\0" "bndmk\0" "bndmov\0" "bndstx\0" "bound\0" "bsf\0" "bsr\0"
+    2581             :   "bswap\0" "bt\0" "btc\0" "btr\0" "bts\0" "bzhi\0" "cbw\0" "cdq\0" "cdqe\0"
+    2582             :   "clac\0" "clc\0" "cld\0" "clflush\0" "clflushopt\0" "cli\0" "clts\0" "clwb\0"
+    2583             :   "clzero\0" "cmc\0" "cmova\0" "cmovae\0" "cmovc\0" "cmovg\0" "cmovge\0"
+    2584             :   "cmovl\0" "cmovle\0" "cmovna\0" "cmovnae\0" "cmovnc\0" "cmovng\0" "cmovnge\0"
+    2585             :   "cmovnl\0" "cmovnle\0" "cmovno\0" "cmovnp\0" "cmovns\0" "cmovnz\0" "cmovo\0"
+    2586             :   "cmovp\0" "cmovpe\0" "cmovpo\0" "cmovs\0" "cmovz\0" "cmp\0" "cmps\0"
+    2587             :   "cmpxchg\0" "cmpxchg16b\0" "cmpxchg8b\0" "cpuid\0" "cqo\0" "crc32\0"
+    2588             :   "cvtpd2pi\0" "cvtpi2pd\0" "cvtpi2ps\0" "cvtps2pi\0" "cvttpd2pi\0"
+    2589             :   "cvttps2pi\0" "cwd\0" "cwde\0" "daa\0" "das\0" "f2xm1\0" "fabs\0" "faddp\0"
+    2590             :   "fbld\0" "fbstp\0" "fchs\0" "fclex\0" "fcmovb\0" "fcmovbe\0" "fcmove\0"
+    2591             :   "fcmovnb\0" "fcmovnbe\0" "fcmovne\0" "fcmovnu\0" "fcmovu\0" "fcom\0"
+    2592             :   "fcomi\0" "fcomip\0" "fcomp\0" "fcompp\0" "fcos\0" "fdecstp\0" "fdiv\0"
+    2593             :   "fdivp\0" "fdivr\0" "fdivrp\0" "femms\0" "ffree\0" "fiadd\0" "ficom\0"
+    2594             :   "ficomp\0" "fidiv\0" "fidivr\0" "fild\0" "fimul\0" "fincstp\0" "finit\0"
+    2595             :   "fist\0" "fistp\0" "fisttp\0" "fisub\0" "fisubr\0" "fld\0" "fld1\0" "fldcw\0"
+    2596             :   "fldenv\0" "fldl2e\0" "fldl2t\0" "fldlg2\0" "fldln2\0" "fldpi\0" "fldz\0"
+    2597             :   "fmulp\0" "fnclex\0" "fninit\0" "fnop\0" "fnsave\0" "fnstcw\0" "fnstenv\0"
+    2598             :   "fnstsw\0" "fpatan\0" "fprem\0" "fprem1\0" "fptan\0" "frndint\0" "frstor\0"
+    2599             :   "fsave\0" "fscale\0" "fsin\0" "fsincos\0" "fsqrt\0" "fst\0" "fstcw\0"
+    2600             :   "fstenv\0" "fstp\0" "fstsw\0" "fsubp\0" "fsubrp\0" "ftst\0" "fucom\0"
+    2601             :   "fucomi\0" "fucomip\0" "fucomp\0" "fucompp\0" "fwait\0" "fxam\0" "fxch\0"
+    2602             :   "fxrstor\0" "fxrstor64\0" "fxsave\0" "fxsave64\0" "fxtract\0" "fyl2x\0"
+    2603             :   "fyl2xp1\0" "hlt\0" "inc\0" "ins\0" "insertq\0" "int3\0" "into\0" "invlpg\0"
+    2604             :   "invpcid\0" "iret\0" "iretd\0" "iretq\0" "iretw\0" "ja\0" "jae\0" "jb\0"
+    2605             :   "jbe\0" "jc\0" "je\0" "jecxz\0" "jg\0" "jge\0" "jl\0" "jle\0" "jmp\0" "jna\0"
+    2606             :   "jnae\0" "jnb\0" "jnbe\0" "jnc\0" "jne\0" "jng\0" "jnge\0" "jnl\0" "jnle\0"
+    2607             :   "jno\0" "jnp\0" "jns\0" "jnz\0" "jo\0" "jp\0" "jpe\0" "jpo\0" "js\0" "jz\0"
+    2608             :   "kaddb\0" "kaddd\0" "kaddq\0" "kaddw\0" "kandb\0" "kandd\0" "kandnb\0"
+    2609             :   "kandnd\0" "kandnq\0" "kandnw\0" "kandq\0" "kandw\0" "kmovb\0" "kmovw\0"
+    2610             :   "knotb\0" "knotd\0" "knotq\0" "knotw\0" "korb\0" "kord\0" "korq\0"
+    2611             :   "kortestb\0" "kortestd\0" "kortestq\0" "kortestw\0" "korw\0" "kshiftlb\0"
+    2612             :   "kshiftld\0" "kshiftlq\0" "kshiftlw\0" "kshiftrb\0" "kshiftrd\0" "kshiftrq\0"
+    2613             :   "kshiftrw\0" "ktestb\0" "ktestd\0" "ktestq\0" "ktestw\0" "kunpckbw\0"
+    2614             :   "kunpckdq\0" "kunpckwd\0" "kxnorb\0" "kxnord\0" "kxnorq\0" "kxnorw\0"
+    2615             :   "kxorb\0" "kxord\0" "kxorq\0" "kxorw\0" "lahf\0" "lar\0" "lds\0" "lea\0"
+    2616             :   "leave\0" "les\0" "lfence\0" "lfs\0" "lgdt\0" "lgs\0" "lidt\0" "lldt\0"
+    2617             :   "lmsw\0" "lods\0" "loop\0" "loope\0" "loopne\0" "lsl\0" "ltr\0" "lzcnt\0"
+    2618             :   "mfence\0" "monitor\0" "movdq2q\0" "movnti\0" "movntq\0" "movntsd\0"
+    2619             :   "movntss\0" "movq2dq\0" "movsx\0" "movsxd\0" "movzx\0" "mulx\0" "mwait\0"
+    2620             :   "neg\0" "not\0" "out\0" "outs\0" "pause\0" "pavgusb\0" "pcommit\0" "pdep\0"
+    2621             :   "pext\0" "pf2id\0" "pf2iw\0" "pfacc\0" "pfadd\0" "pfcmpeq\0" "pfcmpge\0"
+    2622             :   "pfcmpgt\0" "pfmax\0" "pfmin\0" "pfmul\0" "pfnacc\0" "pfpnacc\0" "pfrcp\0"
+    2623             :   "pfrcpit1\0" "pfrcpit2\0" "pfrcpv\0" "pfrsqit1\0" "pfrsqrt\0" "pfrsqrtv\0"
+    2624             :   "pfsub\0" "pfsubr\0" "pi2fd\0" "pi2fw\0" "pmulhrw\0" "pop\0" "popa\0"
+    2625             :   "popad\0" "popcnt\0" "popf\0" "popfd\0" "popfq\0" "prefetch\0"
+    2626             :   "prefetchnta\0" "prefetcht0\0" "prefetcht1\0" "prefetcht2\0" "prefetchw\0"
+    2627             :   "prefetchwt1\0" "pshufw\0" "pswapd\0" "push\0" "pusha\0" "pushad\0" "pushf\0"
+    2628             :   "pushfd\0" "pushfq\0" "rcl\0" "rcr\0" "rdfsbase\0" "rdgsbase\0" "rdmsr\0"
+    2629             :   "rdpmc\0" "rdrand\0" "rdseed\0" "rdtsc\0" "rdtscp\0" "rol\0" "ror\0" "rorx\0"
+    2630             :   "rsm\0" "sahf\0" "sal\0" "sar\0" "sarx\0" "sbb\0" "scas\0" "seta\0" "setae\0"
+    2631             :   "setb\0" "setbe\0" "setc\0" "sete\0" "setg\0" "setge\0" "setl\0" "setle\0"
+    2632             :   "setna\0" "setnae\0" "setnb\0" "setnbe\0" "setnc\0" "setne\0" "setng\0"
+    2633             :   "setnge\0" "setnl\0" "setnle\0" "setno\0" "setnp\0" "setns\0" "setnz\0"
+    2634             :   "seto\0" "setp\0" "setpe\0" "setpo\0" "sets\0" "setz\0" "sfence\0" "sgdt\0"
+    2635             :   "sha1msg1\0" "sha1msg2\0" "sha1nexte\0" "sha1rnds4\0" "sha256msg1\0"
+    2636             :   "sha256msg2\0" "sha256rnds2\0" "shl\0" "shlx\0" "shr\0" "shrd\0" "shrx\0"
+    2637             :   "sidt\0" "sldt\0" "smsw\0" "stac\0" "stc\0" "sti\0" "stos\0" "str\0"
+    2638             :   "swapgs\0" "syscall\0" "sysenter\0" "sysexit\0" "sysexit64\0" "sysret\0"
+    2639             :   "sysret64\0" "t1mskc\0" "tzcnt\0" "tzmsk\0" "ud2\0" "v4fmaddps\0"
+    2640             :   "v4fnmaddps\0" "vaddpd\0" "vaddps\0" "vaddsd\0" "vaddss\0" "vaddsubpd\0"
+    2641             :   "vaddsubps\0" "vaesdec\0" "vaesdeclast\0" "vaesenc\0" "vaesenclast\0"
+    2642             :   "vaesimc\0" "vaeskeygenassist\0" "valignd\0" "valignq\0" "vandnpd\0"
+    2643             :   "vandnps\0" "vandpd\0" "vandps\0" "vblendmb\0" "vblendmd\0" "vblendmpd\0"
+    2644             :   "vblendmps\0" "vblendmq\0" "vblendmw\0" "vblendpd\0" "vblendps\0"
+    2645             :   "vblendvpd\0" "vblendvps\0" "vbroadcastf128\0" "vbroadcastf32x2\0"
+    2646             :   "vbroadcastf32x4\0" "vbroadcastf32x8\0" "vbroadcastf64x2\0"
+    2647             :   "vbroadcastf64x4\0" "vbroadcasti128\0" "vbroadcasti32x2\0"
+    2648             :   "vbroadcasti32x4\0" "vbroadcasti32x8\0" "vbroadcasti64x2\0"
+    2649             :   "vbroadcasti64x4\0" "vbroadcastsd\0" "vbroadcastss\0" "vcmppd\0" "vcmpps\0"
+    2650             :   "vcmpsd\0" "vcmpss\0" "vcomisd\0" "vcomiss\0" "vcompresspd\0" "vcompressps\0"
+    2651             :   "vcvtdq2pd\0" "vcvtdq2ps\0" "vcvtpd2dq\0" "vcvtpd2ps\0" "vcvtpd2qq\0"
+    2652             :   "vcvtpd2udq\0" "vcvtpd2uqq\0" "vcvtph2ps\0" "vcvtps2dq\0" "vcvtps2pd\0"
+    2653             :   "vcvtps2ph\0" "vcvtps2qq\0" "vcvtps2udq\0" "vcvtps2uqq\0" "vcvtqq2pd\0"
+    2654             :   "vcvtqq2ps\0" "vcvtsd2si\0" "vcvtsd2ss\0" "vcvtsd2usi\0" "vcvtsi2sd\0"
+    2655             :   "vcvtsi2ss\0" "vcvtss2sd\0" "vcvtss2si\0" "vcvtss2usi\0" "vcvttpd2dq\0"
+    2656             :   "vcvttpd2qq\0" "vcvttpd2udq\0" "vcvttpd2uqq\0" "vcvttps2dq\0" "vcvttps2qq\0"
+    2657             :   "vcvttps2udq\0" "vcvttps2uqq\0" "vcvttsd2si\0" "vcvttsd2usi\0" "vcvttss2si\0"
+    2658             :   "vcvttss2usi\0" "vcvtudq2pd\0" "vcvtudq2ps\0" "vcvtuqq2pd\0" "vcvtuqq2ps\0"
+    2659             :   "vcvtusi2sd\0" "vcvtusi2ss\0" "vdbpsadbw\0" "vdivpd\0" "vdivps\0" "vdivsd\0"
+    2660             :   "vdivss\0" "vdppd\0" "vdpps\0" "verr\0" "verw\0" "vexp2pd\0" "vexp2ps\0"
+    2661             :   "vexpandpd\0" "vexpandps\0" "vextractf128\0" "vextractf32x4\0"
+    2662             :   "vextractf32x8\0" "vextractf64x2\0" "vextractf64x4\0" "vextracti128\0"
+    2663             :   "vextracti32x4\0" "vextracti32x8\0" "vextracti64x2\0" "vextracti64x4\0"
+    2664             :   "vextractps\0" "vfixupimmpd\0" "vfixupimmps\0" "vfixupimmsd\0"
+    2665             :   "vfixupimmss\0" "vfmadd132pd\0" "vfmadd132ps\0" "vfmadd132sd\0"
+    2666             :   "vfmadd132ss\0" "vfmadd213pd\0" "vfmadd213ps\0" "vfmadd213sd\0"
+    2667             :   "vfmadd213ss\0" "vfmadd231pd\0" "vfmadd231ps\0" "vfmadd231sd\0"
+    2668             :   "vfmadd231ss\0" "vfmaddpd\0" "vfmaddps\0" "vfmaddsd\0" "vfmaddss\0"
+    2669             :   "vfmaddsub132pd\0" "vfmaddsub132ps\0" "vfmaddsub213pd\0" "vfmaddsub213ps\0"
+    2670             :   "vfmaddsub231pd\0" "vfmaddsub231ps\0" "vfmaddsubpd\0" "vfmaddsubps\0"
+    2671             :   "vfmsub132pd\0" "vfmsub132ps\0" "vfmsub132sd\0" "vfmsub132ss\0"
+    2672             :   "vfmsub213pd\0" "vfmsub213ps\0" "vfmsub213sd\0" "vfmsub213ss\0"
+    2673             :   "vfmsub231pd\0" "vfmsub231ps\0" "vfmsub231sd\0" "vfmsub231ss\0"
+    2674             :   "vfmsubadd132pd\0" "vfmsubadd132ps\0" "vfmsubadd213pd\0" "vfmsubadd213ps\0"
+    2675             :   "vfmsubadd231pd\0" "vfmsubadd231ps\0" "vfmsubaddpd\0" "vfmsubaddps\0"
+    2676             :   "vfmsubpd\0" "vfmsubps\0" "vfmsubsd\0" "vfmsubss\0" "vfnmadd132pd\0"
+    2677             :   "vfnmadd132ps\0" "vfnmadd132sd\0" "vfnmadd132ss\0" "vfnmadd213pd\0"
+    2678             :   "vfnmadd213ps\0" "vfnmadd213sd\0" "vfnmadd213ss\0" "vfnmadd231pd\0"
+    2679             :   "vfnmadd231ps\0" "vfnmadd231sd\0" "vfnmadd231ss\0" "vfnmaddpd\0"
+    2680             :   "vfnmaddps\0" "vfnmaddsd\0" "vfnmaddss\0" "vfnmsub132pd\0" "vfnmsub132ps\0"
+    2681             :   "vfnmsub132sd\0" "vfnmsub132ss\0" "vfnmsub213pd\0" "vfnmsub213ps\0"
+    2682             :   "vfnmsub213sd\0" "vfnmsub213ss\0" "vfnmsub231pd\0" "vfnmsub231ps\0"
+    2683             :   "vfnmsub231sd\0" "vfnmsub231ss\0" "vfnmsubpd\0" "vfnmsubps\0" "vfnmsubsd\0"
+    2684             :   "vfnmsubss\0" "vfpclasspd\0" "vfpclassps\0" "vfpclasssd\0" "vfpclassss\0"
+    2685             :   "vfrczpd\0" "vfrczps\0" "vfrczsd\0" "vfrczss\0" "vgatherdpd\0" "vgatherdps\0"
+    2686             :   "vgatherpf0dpd\0" "vgatherpf0dps\0" "vgatherpf0qpd\0" "vgatherpf0qps\0"
+    2687             :   "vgatherpf1dpd\0" "vgatherpf1dps\0" "vgatherpf1qpd\0" "vgatherpf1qps\0"
+    2688             :   "vgatherqpd\0" "vgatherqps\0" "vgetexppd\0" "vgetexpps\0" "vgetexpsd\0"
+    2689             :   "vgetexpss\0" "vgetmantpd\0" "vgetmantps\0" "vgetmantsd\0" "vgetmantss\0"
+    2690             :   "vhaddpd\0" "vhaddps\0" "vhsubpd\0" "vhsubps\0" "vinsertf128\0"
+    2691             :   "vinsertf32x4\0" "vinsertf32x8\0" "vinsertf64x2\0" "vinsertf64x4\0"
+    2692             :   "vinserti128\0" "vinserti32x4\0" "vinserti32x8\0" "vinserti64x2\0"
+    2693             :   "vinserti64x4\0" "vinsertps\0" "vlddqu\0" "vldmxcsr\0" "vmaskmovdqu\0"
+    2694             :   "vmaskmovpd\0" "vmaskmovps\0" "vmaxpd\0" "vmaxps\0" "vmaxsd\0" "vmaxss\0"
+    2695             :   "vminpd\0" "vminps\0" "vminsd\0" "vminss\0" "vmovapd\0" "vmovaps\0" "vmovd\0"
+    2696             :   "vmovddup\0" "vmovdqa\0" "vmovdqa32\0" "vmovdqa64\0" "vmovdqu\0"
+    2697             :   "vmovdqu16\0" "vmovdqu32\0" "vmovdqu64\0" "vmovdqu8\0" "vmovhlps\0"
+    2698             :   "vmovhpd\0" "vmovhps\0" "vmovlhps\0" "vmovlpd\0" "vmovlps\0" "vmovmskpd\0"
+    2699             :   "vmovmskps\0" "vmovntdq\0" "vmovntdqa\0" "vmovntpd\0" "vmovntps\0" "vmovq\0"
+    2700             :   "vmovsd\0" "vmovshdup\0" "vmovsldup\0" "vmovss\0" "vmovupd\0" "vmovups\0"
+    2701             :   "vmpsadbw\0" "vmulpd\0" "vmulps\0" "vmulsd\0" "vmulss\0" "vorpd\0" "vorps\0"
+    2702             :   "vp4dpwssd\0" "vp4dpwssds\0" "vpabsb\0" "vpabsd\0" "vpabsq\0" "vpabsw\0"
+    2703             :   "vpackssdw\0" "vpacksswb\0" "vpackusdw\0" "vpackuswb\0" "vpaddb\0" "vpaddd\0"
+    2704             :   "vpaddq\0" "vpaddsb\0" "vpaddsw\0" "vpaddusb\0" "vpaddusw\0" "vpaddw\0"
+    2705             :   "vpalignr\0" "vpand\0" "vpandd\0" "vpandn\0" "vpandnd\0" "vpandnq\0"
+    2706             :   "vpandq\0" "vpavgb\0" "vpavgw\0" "vpblendd\0" "vpblendvb\0" "vpblendw\0"
+    2707             :   "vpbroadcastb\0" "vpbroadcastd\0" "vpbroadcastmb2d\0" "vpbroadcastmb2q\0"
+    2708             :   "vpbroadcastq\0" "vpbroadcastw\0" "vpclmulqdq\0" "vpcmov\0" "vpcmpb\0"
+    2709             :   "vpcmpd\0" "vpcmpeqb\0" "vpcmpeqd\0" "vpcmpeqq\0" "vpcmpeqw\0" "vpcmpestri\0"
+    2710             :   "vpcmpestrm\0" "vpcmpgtb\0" "vpcmpgtd\0" "vpcmpgtq\0" "vpcmpgtw\0"
+    2711             :   "vpcmpistri\0" "vpcmpistrm\0" "vpcmpq\0" "vpcmpub\0" "vpcmpud\0" "vpcmpuq\0"
+    2712             :   "vpcmpuw\0" "vpcmpw\0" "vpcomb\0" "vpcomd\0" "vpcompressd\0" "vpcompressq\0"
+    2713             :   "vpcomq\0" "vpcomub\0" "vpcomud\0" "vpcomuq\0" "vpcomuw\0" "vpcomw\0"
+    2714             :   "vpconflictd\0" "vpconflictq\0" "vperm2f128\0" "vperm2i128\0" "vpermb\0"
+    2715             :   "vpermd\0" "vpermi2b\0" "vpermi2d\0" "vpermi2pd\0" "vpermi2ps\0" "vpermi2q\0"
+    2716             :   "vpermi2w\0" "vpermil2pd\0" "vpermil2ps\0" "vpermilpd\0" "vpermilps\0"
+    2717             :   "vpermpd\0" "vpermps\0" "vpermq\0" "vpermt2b\0" "vpermt2d\0" "vpermt2pd\0"
+    2718             :   "vpermt2ps\0" "vpermt2q\0" "vpermt2w\0" "vpermw\0" "vpexpandd\0"
+    2719             :   "vpexpandq\0" "vpextrb\0" "vpextrd\0" "vpextrq\0" "vpextrw\0" "vpgatherdd\0"
+    2720             :   "vpgatherdq\0" "vpgatherqd\0" "vpgatherqq\0" "vphaddbd\0" "vphaddbq\0"
+    2721             :   "vphaddbw\0" "vphaddd\0" "vphadddq\0" "vphaddsw\0" "vphaddubd\0"
+    2722             :   "vphaddubq\0" "vphaddubw\0" "vphaddudq\0" "vphadduwd\0" "vphadduwq\0"
+    2723             :   "vphaddw\0" "vphaddwd\0" "vphaddwq\0" "vphminposuw\0" "vphsubbw\0"
+    2724             :   "vphsubd\0" "vphsubdq\0" "vphsubsw\0" "vphsubw\0" "vphsubwd\0" "vpinsrb\0"
+    2725             :   "vpinsrd\0" "vpinsrq\0" "vpinsrw\0" "vplzcntd\0" "vplzcntq\0" "vpmacsdd\0"
+    2726             :   "vpmacsdqh\0" "vpmacsdql\0" "vpmacssdd\0" "vpmacssdqh\0" "vpmacssdql\0"
+    2727             :   "vpmacsswd\0" "vpmacssww\0" "vpmacswd\0" "vpmacsww\0" "vpmadcsswd\0"
+    2728             :   "vpmadcswd\0" "vpmadd52huq\0" "vpmadd52luq\0" "vpmaddubsw\0" "vpmaddwd\0"
+    2729             :   "vpmaskmovd\0" "vpmaskmovq\0" "vpmaxsb\0" "vpmaxsd\0" "vpmaxsq\0" "vpmaxsw\0"
+    2730             :   "vpmaxub\0" "vpmaxud\0" "vpmaxuq\0" "vpmaxuw\0" "vpminsb\0" "vpminsd\0"
+    2731             :   "vpminsq\0" "vpminsw\0" "vpminub\0" "vpminud\0" "vpminuq\0" "vpminuw\0"
+    2732             :   "vpmovb2m\0" "vpmovd2m\0" "vpmovdb\0" "vpmovdw\0" "vpmovm2b\0" "vpmovm2d\0"
+    2733             :   "vpmovm2q\0" "vpmovm2w\0" "vpmovmskb\0" "vpmovq2m\0" "vpmovqb\0" "vpmovqd\0"
+    2734             :   "vpmovqw\0" "vpmovsdb\0" "vpmovsdw\0" "vpmovsqb\0" "vpmovsqd\0" "vpmovsqw\0"
+    2735             :   "vpmovswb\0" "vpmovsxbd\0" "vpmovsxbq\0" "vpmovsxbw\0" "vpmovsxdq\0"
+    2736             :   "vpmovsxwd\0" "vpmovsxwq\0" "vpmovusdb\0" "vpmovusdw\0" "vpmovusqb\0"
+    2737             :   "vpmovusqd\0" "vpmovusqw\0" "vpmovuswb\0" "vpmovw2m\0" "vpmovwb\0"
+    2738             :   "vpmovzxbd\0" "vpmovzxbq\0" "vpmovzxbw\0" "vpmovzxdq\0" "vpmovzxwd\0"
+    2739             :   "vpmovzxwq\0" "vpmuldq\0" "vpmulhrsw\0" "vpmulhuw\0" "vpmulhw\0" "vpmulld\0"
+    2740             :   "vpmullq\0" "vpmullw\0" "vpmultishiftqb\0" "vpmuludq\0" "vpopcntd\0"
+    2741             :   "vpopcntq\0" "vpor\0" "vpord\0" "vporq\0" "vpperm\0" "vprold\0" "vprolq\0"
+    2742             :   "vprolvd\0" "vprolvq\0" "vprord\0" "vprorq\0" "vprorvd\0" "vprorvq\0"
+    2743             :   "vprotb\0" "vprotd\0" "vprotq\0" "vprotw\0" "vpsadbw\0" "vpscatterdd\0"
+    2744             :   "vpscatterdq\0" "vpscatterqd\0" "vpscatterqq\0" "vpshab\0" "vpshad\0"
+    2745             :   "vpshaq\0" "vpshaw\0" "vpshlb\0" "vpshld\0" "vpshlq\0" "vpshlw\0" "vpshufb\0"
+    2746             :   "vpshufd\0" "vpshufhw\0" "vpshuflw\0" "vpsignb\0" "vpsignd\0" "vpsignw\0"
+    2747             :   "vpslld\0" "vpslldq\0" "vpsllq\0" "vpsllvd\0" "vpsllvq\0" "vpsllvw\0"
+    2748             :   "vpsllw\0" "vpsrad\0" "vpsraq\0" "vpsravd\0" "vpsravq\0" "vpsravw\0"
+    2749             :   "vpsraw\0" "vpsrld\0" "vpsrldq\0" "vpsrlq\0" "vpsrlvd\0" "vpsrlvq\0"
+    2750             :   "vpsrlvw\0" "vpsrlw\0" "vpsubb\0" "vpsubd\0" "vpsubq\0" "vpsubsb\0"
+    2751             :   "vpsubsw\0" "vpsubusb\0" "vpsubusw\0" "vpsubw\0" "vpternlogd\0"
+    2752             :   "vpternlogq\0" "vptest\0" "vptestmb\0" "vptestmd\0" "vptestmq\0" "vptestmw\0"
+    2753             :   "vptestnmb\0" "vptestnmd\0" "vptestnmq\0" "vptestnmw\0" "vpunpckhbw\0"
+    2754             :   "vpunpckhdq\0" "vpunpckhqdq\0" "vpunpckhwd\0" "vpunpcklbw\0" "vpunpckldq\0"
+    2755             :   "vpunpcklqdq\0" "vpunpcklwd\0" "vpxor\0" "vpxord\0" "vpxorq\0" "vrangepd\0"
+    2756             :   "vrangeps\0" "vrangesd\0" "vrangess\0" "vrcp14pd\0" "vrcp14ps\0" "vrcp14sd\0"
+    2757             :   "vrcp14ss\0" "vrcp28pd\0" "vrcp28ps\0" "vrcp28sd\0" "vrcp28ss\0" "vrcpps\0"
+    2758             :   "vrcpss\0" "vreducepd\0" "vreduceps\0" "vreducesd\0" "vreducess\0"
+    2759             :   "vrndscalepd\0" "vrndscaleps\0" "vrndscalesd\0" "vrndscaless\0" "vroundpd\0"
+    2760             :   "vroundps\0" "vroundsd\0" "vroundss\0" "vrsqrt14pd\0" "vrsqrt14ps\0"
+    2761             :   "vrsqrt14sd\0" "vrsqrt14ss\0" "vrsqrt28pd\0" "vrsqrt28ps\0" "vrsqrt28sd\0"
+    2762             :   "vrsqrt28ss\0" "vrsqrtps\0" "vrsqrtss\0" "vscalefpd\0" "vscalefps\0"
+    2763             :   "vscalefsd\0" "vscalefss\0" "vscatterdpd\0" "vscatterdps\0"
+    2764             :   "vscatterpf0dpd\0" "vscatterpf0dps\0" "vscatterpf0qpd\0" "vscatterpf0qps\0"
+    2765             :   "vscatterpf1dpd\0" "vscatterpf1dps\0" "vscatterpf1qpd\0" "vscatterpf1qps\0"
+    2766             :   "vscatterqpd\0" "vscatterqps\0" "vshuff32x4\0" "vshuff64x2\0" "vshufi32x4\0"
+    2767             :   "vshufi64x2\0" "vshufpd\0" "vshufps\0" "vsqrtpd\0" "vsqrtps\0" "vsqrtsd\0"
+    2768             :   "vsqrtss\0" "vstmxcsr\0" "vsubpd\0" "vsubps\0" "vsubsd\0" "vsubss\0"
+    2769             :   "vtestpd\0" "vtestps\0" "vucomisd\0" "vucomiss\0" "vunpckhpd\0" "vunpckhps\0"
+    2770             :   "vunpcklpd\0" "vunpcklps\0" "vxorpd\0" "vxorps\0" "vzeroall\0" "vzeroupper\0"
+    2771             :   "wbinvd\0" "wrfsbase\0" "wrgsbase\0" "wrmsr\0" "xabort\0" "xadd\0" "xbegin\0"
+    2772             :   "xend\0" "xgetbv\0" "xlatb\0" "xrstors\0" "xrstors64\0" "xsavec\0"
+    2773             :   "xsavec64\0" "xsaveopt\0" "xsaveopt64\0" "xsaves\0" "xsaves64\0" "xsetbv\0"
+    2774             :   "xtest";
+    2775             : 
+    2776             : enum {
+    2777             :   kX86InstMaxLength = 16
+    2778             : };
+    2779             : 
+    2780             : struct InstNameAZ {
+    2781             :   uint16_t start;
+    2782             :   uint16_t end;
+    2783             : };
+    2784             : 
+    2785             : static const InstNameAZ X86InstNameAZ[26] = {
+    2786             :   { X86Inst::kIdAaa       , X86Inst::kIdArpl       + 1 },
+    2787             :   { X86Inst::kIdBextr     , X86Inst::kIdBzhi       + 1 },
+    2788             :   { X86Inst::kIdCall      , X86Inst::kIdCwde       + 1 },
+    2789             :   { X86Inst::kIdDaa       , X86Inst::kIdDpps       + 1 },
+    2790             :   { X86Inst::kIdEmms      , X86Inst::kIdExtrq      + 1 },
+    2791             :   { X86Inst::kIdF2xm1     , X86Inst::kIdFyl2xp1    + 1 },
+    2792             :   { X86Inst::kIdNone      , X86Inst::kIdNone       + 1 },
+    2793             :   { X86Inst::kIdHaddpd    , X86Inst::kIdHsubps     + 1 },
+    2794             :   { X86Inst::kIdIdiv      , X86Inst::kIdIretw      + 1 },
+    2795             :   { X86Inst::kIdJa        , X86Inst::kIdJz         + 1 },
+    2796             :   { X86Inst::kIdKaddb     , X86Inst::kIdKxorw      + 1 },
+    2797             :   { X86Inst::kIdLahf      , X86Inst::kIdLzcnt      + 1 },
+    2798             :   { X86Inst::kIdMaskmovdqu, X86Inst::kIdMwait      + 1 },
+    2799             :   { X86Inst::kIdNeg       , X86Inst::kIdNot        + 1 },
+    2800             :   { X86Inst::kIdOr        , X86Inst::kIdOuts       + 1 },
+    2801             :   { X86Inst::kIdPabsb     , X86Inst::kIdPxor       + 1 },
+    2802             :   { X86Inst::kIdNone      , X86Inst::kIdNone       + 1 },
+    2803             :   { X86Inst::kIdRcl       , X86Inst::kIdRsqrtss    + 1 },
+    2804             :   { X86Inst::kIdSahf      , X86Inst::kIdSysret64   + 1 },
+    2805             :   { X86Inst::kIdT1mskc    , X86Inst::kIdTzmsk      + 1 },
+    2806             :   { X86Inst::kIdUcomisd   , X86Inst::kIdUnpcklps   + 1 },
+    2807             :   { X86Inst::kIdV4fmaddps , X86Inst::kIdVzeroupper + 1 },
+    2808             :   { X86Inst::kIdWbinvd    , X86Inst::kIdWrmsr      + 1 },
+    2809             :   { X86Inst::kIdXabort    , X86Inst::kIdXtest      + 1 },
+    2810             :   { X86Inst::kIdNone      , X86Inst::kIdNone       + 1 },
+    2811             :   { X86Inst::kIdNone      , X86Inst::kIdNone       + 1 }
+    2812             : };
+    2813             : // ----------------------------------------------------------------------------
+    2814             : // ${nameData:End}
+    2815             : 
+    2816           0 : uint32_t X86Inst::getIdByName(const char* name, size_t len) noexcept {
+    2817           0 :   if (ASMJIT_UNLIKELY(!name))
+    2818             :     return Inst::kIdNone;
+    2819             : 
+    2820           0 :   if (len == Globals::kInvalidIndex)
+    2821           0 :     len = ::strlen(name);
+    2822             : 
+    2823           0 :   if (ASMJIT_UNLIKELY(len == 0 || len > kX86InstMaxLength))
+    2824             :     return Inst::kIdNone;
+    2825             : 
+    2826           0 :   uint32_t prefix = static_cast<uint32_t>(name[0]) - 'a';
+    2827           0 :   if (ASMJIT_UNLIKELY(prefix > 'z' - 'a'))
+    2828             :     return Inst::kIdNone;
+    2829             : 
+    2830           0 :   uint32_t index = X86InstNameAZ[prefix].start;
+    2831           0 :   if (ASMJIT_UNLIKELY(!index))
+    2832             :     return Inst::kIdNone;
+    2833             : 
+    2834             :   const char* nameData = X86InstDB::nameData;
+    2835             :   const X86Inst* instData = X86InstDB::instData;
+    2836             : 
+    2837           0 :   const X86Inst* base = instData + index;
+    2838           0 :   const X86Inst* end  = instData + X86InstNameAZ[prefix].end;
+    2839             : 
+    2840           0 :   for (size_t lim = (size_t)(end - base); lim != 0; lim >>= 1) {
+    2841           0 :     const X86Inst* cur = base + (lim >> 1);
+    2842           0 :     int result = Utils::cmpInstName(nameData + cur[0].getNameDataIndex(), name, len);
+    2843             : 
+    2844           0 :     if (result < 0) {
+    2845           0 :       base = cur + 1;
+    2846           0 :       lim--;
+    2847           0 :       continue;
+    2848             :     }
+    2849             : 
+    2850           0 :     if (result > 0)
+    2851           0 :       continue;
+    2852             : 
+    2853           0 :     return static_cast<uint32_t>((size_t)(cur - instData));
+    2854             :   }
+    2855             : 
+    2856             :   return Inst::kIdNone;
+    2857             : }
+    2858             : 
+    2859           0 : const char* X86Inst::getNameById(uint32_t id) noexcept {
+    2860           0 :   if (ASMJIT_UNLIKELY(id >= X86Inst::_kIdCount))
+    2861             :     return nullptr;
+    2862           0 :   return X86Inst::getInst(id).getName();
+    2863             : }
+    2864             : #else
+    2865             : const char X86InstDB::nameData[] = "";
+    2866             : #endif // !ASMJIT_DISABLE_TEXT
+    2867             : 
+    2868             : // ============================================================================
+    2869             : // [asmjit::X86Inst - Validation]
+    2870             : // ============================================================================
+    2871             : 
+    2872             : #if !defined(ASMJIT_DISABLE_VALIDATION)
+    2873             : // ${signatureData:Begin}
+    2874             : // ------------------- Automatically generated, do not edit -------------------
+    2875             : #define FLAG(flag) X86Inst::kOp##flag
+    2876             : #define MEM(mem) X86Inst::kMemOp##mem
+    2877             : #define OSIGNATURE(flags, memFlags, extFlags, regId) \
+    2878             :   { uint32_t(flags), uint16_t(memFlags), uint8_t(extFlags), uint8_t(regId) }
+    2879             : const X86Inst::OSignature X86InstDB::oSignatureData[] = {
+    2880             :   OSIGNATURE(0, 0, 0, 0xFF),
+    2881             :   OSIGNATURE(FLAG(W) | FLAG(GpbLo) | FLAG(GpbHi) | FLAG(Mem), MEM(Any) | MEM(M8), 0, 0x00),
+    2882             :   OSIGNATURE(FLAG(R) | FLAG(GpbLo) | FLAG(GpbHi), 0, 0, 0x00),
+    2883             :   OSIGNATURE(FLAG(W) | FLAG(Gpw) | FLAG(Mem), MEM(Any) | MEM(M16), 0, 0x00),
+    2884             :   OSIGNATURE(FLAG(R) | FLAG(Gpw) | FLAG(Seg), 0, 0, 0x00),
+    2885             :   OSIGNATURE(FLAG(W) | FLAG(Gpd) | FLAG(Seg) | FLAG(Mem), MEM(Any) | MEM(M32), 0, 0x00),
+    2886             :   OSIGNATURE(FLAG(R) | FLAG(Gpd), 0, 0, 0x00),
+    2887             :   OSIGNATURE(FLAG(W) | FLAG(Gpq) | FLAG(Mem), MEM(Any) | MEM(M64), 0, 0x00),
+    2888             :   OSIGNATURE(FLAG(R) | FLAG(Gpq) | FLAG(Seg) | FLAG(I32), 0, 0, 0x00),
+    2889             :   OSIGNATURE(FLAG(W) | FLAG(GpbLo) | FLAG(GpbHi), 0, 0, 0x00),
+    2890             :   OSIGNATURE(FLAG(R) | FLAG(GpbLo) | FLAG(GpbHi) | FLAG(Mem) | FLAG(I8) | FLAG(U8), MEM(Any) | MEM(M8), 0, 0x00),
+    2891             :   OSIGNATURE(FLAG(W) | FLAG(Gpw) | FLAG(Seg), 0, 0, 0x00),
+    2892             :   OSIGNATURE(FLAG(R) | FLAG(Gpw) | FLAG(Mem), MEM(Any) | MEM(M16), 0, 0x00),
+    2893             :   OSIGNATURE(FLAG(W) | FLAG(Gpd), 0, 0, 0x00),
+    2894             :   OSIGNATURE(FLAG(R) | FLAG(Gpd) | FLAG(Seg) | FLAG(Mem) | FLAG(I32) | FLAG(U32), MEM(Any) | MEM(M32), 0, 0x00),
+    2895             :   OSIGNATURE(FLAG(W) | FLAG(Gpq) | FLAG(Seg), 0, 0, 0x00),
+    2896             :   OSIGNATURE(FLAG(R) | FLAG(Gpq) | FLAG(Mem), MEM(Any) | MEM(M64), 0, 0x00),
+    2897             :   OSIGNATURE(FLAG(W) | FLAG(Gpw) | FLAG(Mem), MEM(M16), 0, 0x00),
+    2898             :   OSIGNATURE(FLAG(R) | FLAG(I16) | FLAG(U16), 0, 0, 0x00),
+    2899             :   OSIGNATURE(FLAG(W) | FLAG(Gpq), 0, 0, 0x00),
+    2900             :   OSIGNATURE(FLAG(R) | FLAG(Cr) | FLAG(Dr) | FLAG(I64) | FLAG(U64), 0, 0, 0x00),
+    2901             :   OSIGNATURE(FLAG(W) | FLAG(GpbLo) | FLAG(GpbHi) | FLAG(Mem), MEM(M8), 0, 0x00),
+    2902             :   OSIGNATURE(FLAG(R) | FLAG(I8) | FLAG(U8), 0, 0, 0x00),
+    2903             :   OSIGNATURE(FLAG(W) | FLAG(Gpd) | FLAG(Mem), MEM(M32), 0, 0x00),
+    2904             :   OSIGNATURE(FLAG(R) | FLAG(I32) | FLAG(U32), 0, 0, 0x00),
+    2905             :   OSIGNATURE(FLAG(R) | FLAG(Cr) | FLAG(Dr), 0, 0, 0x00),
+    2906             :   OSIGNATURE(FLAG(W) | FLAG(Cr) | FLAG(Dr), 0, 0, 0x00),
+    2907             :   OSIGNATURE(FLAG(R) | FLAG(Gpq), 0, 0, 0x00),
+    2908             :   OSIGNATURE(FLAG(X) | FLAG(GpbLo) | FLAG(GpbHi) | FLAG(Mem), MEM(M8), 0, 0x00),
+    2909             :   OSIGNATURE(FLAG(X) | FLAG(Gpw) | FLAG(Mem), MEM(M16), 0, 0x00),
+    2910             :   OSIGNATURE(FLAG(X) | FLAG(Gpd) | FLAG(Mem), MEM(M32), 0, 0x00),
+    2911             :   OSIGNATURE(FLAG(X) | FLAG(Gpq) | FLAG(Mem), MEM(Any) | MEM(M64), 0, 0x00),
+    2912             :   OSIGNATURE(FLAG(R) | FLAG(Gpq) | FLAG(I32), 0, 0, 0x00),
+    2913             :   OSIGNATURE(FLAG(X) | FLAG(Gpw) | FLAG(Gpd) | FLAG(Gpq) | FLAG(Mem), MEM(Any) | MEM(M16) | MEM(M32) | MEM(M64), 0, 0x00),
+    2914             :   OSIGNATURE(FLAG(R) | FLAG(I8), 0, 0, 0x00),
+    2915             :   OSIGNATURE(FLAG(X) | FLAG(GpbLo) | FLAG(GpbHi) | FLAG(Mem), MEM(Any) | MEM(M8), 0, 0x00),
+    2916             :   OSIGNATURE(FLAG(X) | FLAG(Gpw) | FLAG(Mem), MEM(Any) | MEM(M16), 0, 0x00),
+    2917             :   OSIGNATURE(FLAG(R) | FLAG(Gpw), 0, 0, 0x00),
+    2918             :   OSIGNATURE(FLAG(X) | FLAG(Gpd) | FLAG(Mem), MEM(Any) | MEM(M32), 0, 0x00),
+    2919             :   OSIGNATURE(FLAG(X) | FLAG(GpbLo) | FLAG(GpbHi), 0, 0, 0x00),
+    2920             :   OSIGNATURE(FLAG(R) | FLAG(GpbLo) | FLAG(GpbHi) | FLAG(Mem), MEM(Any) | MEM(M8), 0, 0x00),
+    2921             :   OSIGNATURE(FLAG(X) | FLAG(Gpw), 0, 0, 0x00),
+    2922             :   OSIGNATURE(FLAG(X) | FLAG(Gpd), 0, 0, 0x00),
+    2923             :   OSIGNATURE(FLAG(R) | FLAG(Gpd) | FLAG(Mem), MEM(Any) | MEM(M32), 0, 0x00),
+    2924             :   OSIGNATURE(FLAG(X) | FLAG(Gpq), 0, 0, 0x00),
+    2925             :   OSIGNATURE(FLAG(R) | FLAG(GpbLo) | FLAG(GpbHi) | FLAG(Mem), MEM(M8), 0, 0x00),
+    2926             :   OSIGNATURE(FLAG(R) | FLAG(Gpw) | FLAG(Mem), MEM(M16), 0, 0x00),
+    2927             :   OSIGNATURE(FLAG(R) | FLAG(Gpd) | FLAG(Mem), MEM(M32), 0, 0x00),
+    2928             :   OSIGNATURE(FLAG(R) | FLAG(Gpw) | FLAG(Gpd) | FLAG(Gpq) | FLAG(Mem), MEM(Any) | MEM(M16) | MEM(M32) | MEM(M64), 0, 0x00),
+    2929             :   OSIGNATURE(FLAG(X) | FLAG(GpbLo) | FLAG(GpbHi) | FLAG(Gpw) | FLAG(Gpd) | FLAG(Gpq) | FLAG(Mem), MEM(Any) | MEM(M8) | MEM(M16) | MEM(M32) | MEM(M64), 0, 0x00),
+    2930             :   OSIGNATURE(FLAG(X) | FLAG(Implicit) | FLAG(Gpw), 0, 0, 0x01),
+    2931             :   OSIGNATURE(FLAG(W) | FLAG(Implicit) | FLAG(Gpw), 0, 0, 0x04),
+    2932             :   OSIGNATURE(FLAG(W) | FLAG(Implicit) | FLAG(Gpd), 0, 0, 0x04),
+    2933             :   OSIGNATURE(FLAG(X) | FLAG(Implicit) | FLAG(Gpd), 0, 0, 0x01),
+    2934             :   OSIGNATURE(FLAG(W) | FLAG(Implicit) | FLAG(Gpq), 0, 0, 0x04),
+    2935             :   OSIGNATURE(FLAG(X) | FLAG(Implicit) | FLAG(Gpq), 0, 0, 0x01),
+    2936             :   OSIGNATURE(FLAG(R) | FLAG(Gpw) | FLAG(Mem) | FLAG(I8) | FLAG(I16), MEM(Any) | MEM(M16), 0, 0x00),
+    2937             :   OSIGNATURE(FLAG(R) | FLAG(Gpd) | FLAG(Mem) | FLAG(I8) | FLAG(I32), MEM(Any) | MEM(M32), 0, 0x00),
+    2938             :   OSIGNATURE(FLAG(R) | FLAG(Gpq) | FLAG(Mem) | FLAG(I8) | FLAG(I32), MEM(Any) | MEM(M64), 0, 0x00),
+    2939             :   OSIGNATURE(FLAG(W) | FLAG(Gpw), 0, 0, 0x00),
+    2940             :   OSIGNATURE(FLAG(R) | FLAG(I8) | FLAG(I16) | FLAG(U16), 0, 0, 0x00),
+    2941             :   OSIGNATURE(FLAG(R) | FLAG(I8) | FLAG(I32) | FLAG(U32), 0, 0, 0x00),
+    2942             :   OSIGNATURE(FLAG(R) | FLAG(I8) | FLAG(I32), 0, 0, 0x00),
+    2943             :   OSIGNATURE(FLAG(R) | FLAG(Mem), MEM(Any) | MEM(M16), 0, 0x00),
+    2944             :   OSIGNATURE(FLAG(R) | FLAG(Mem), MEM(Any) | MEM(M32), 0, 0x00),
+    2945             :   OSIGNATURE(FLAG(R) | FLAG(Mem), MEM(Any) | MEM(M64), 0, 0x00),
+    2946             :   OSIGNATURE(FLAG(W) | FLAG(Mem), MEM(Any) | MEM(M16), 0, 0x00),
+    2947             :   OSIGNATURE(FLAG(W) | FLAG(Mem), MEM(Any) | MEM(M32), 0, 0x00),
+    2948             :   OSIGNATURE(FLAG(W) | FLAG(Mem), MEM(Any) | MEM(M64), 0, 0x00),
+    2949             :   OSIGNATURE(FLAG(W) | FLAG(Mm), 0, 0, 0x00),
+    2950             :   OSIGNATURE(FLAG(R) | FLAG(Gpq) | FLAG(Mm) | FLAG(Xmm) | FLAG(Mem), MEM(Any) | MEM(M64), 0, 0x00),
+    2951             :   OSIGNATURE(FLAG(W) | FLAG(Gpq) | FLAG(Mm) | FLAG(Xmm) | FLAG(Mem), MEM(Any) | MEM(M64), 0, 0x00),
+    2952             :   OSIGNATURE(FLAG(R) | FLAG(Mm), 0, 0, 0x00),
+    2953             :   OSIGNATURE(FLAG(R) | FLAG(Xmm), 0, 0, 0x00),
+    2954             :   OSIGNATURE(FLAG(W) | FLAG(Xmm), 0, 0, 0x00),
+    2955             :   OSIGNATURE(FLAG(R) | FLAG(Xmm) | FLAG(Mem), MEM(Any) | MEM(M64), 0, 0x00),
+    2956             :   OSIGNATURE(FLAG(W) | FLAG(Xmm) | FLAG(Mem), MEM(Any) | MEM(M64), 0, 0x00),
+    2957             :   OSIGNATURE(FLAG(R) | FLAG(Xmm) | FLAG(Mem), MEM(Any) | MEM(M128), 0, 0x00),
+    2958             :   OSIGNATURE(FLAG(W) | FLAG(Xmm) | FLAG(Mem), MEM(Any) | MEM(M128), 0, 0x00),
+    2959             :   OSIGNATURE(FLAG(W) | FLAG(Ymm), 0, 0, 0x00),
+    2960             :   OSIGNATURE(FLAG(R) | FLAG(Ymm) | FLAG(Mem), MEM(Any) | MEM(M256), 0, 0x00),
+    2961             :   OSIGNATURE(FLAG(W) | FLAG(Ymm) | FLAG(Mem), MEM(Any) | MEM(M256), 0, 0x00),
+    2962             :   OSIGNATURE(FLAG(R) | FLAG(Ymm), 0, 0, 0x00),
+    2963             :   OSIGNATURE(FLAG(W) | FLAG(Zmm), 0, 0, 0x00),
+    2964             :   OSIGNATURE(FLAG(R) | FLAG(Zmm) | FLAG(Mem), MEM(Any) | MEM(M512), 0, 0x00),
+    2965             :   OSIGNATURE(FLAG(W) | FLAG(Zmm) | FLAG(Mem), MEM(Any) | MEM(M512), 0, 0x00),
+    2966             :   OSIGNATURE(FLAG(R) | FLAG(Zmm), 0, 0, 0x00),
+    2967             :   OSIGNATURE(FLAG(R) | FLAG(U8), 0, 0, 0x00),
+    2968             :   OSIGNATURE(FLAG(R) | FLAG(Xmm) | FLAG(Mem) | FLAG(U8), MEM(Any) | MEM(M128), 0, 0x00),
+    2969             :   OSIGNATURE(FLAG(X) | FLAG(Xmm), 0, 0, 0x00),
+    2970             :   OSIGNATURE(FLAG(R) | FLAG(Vm), MEM(Vm32x), 0, 0x00),
+    2971             :   OSIGNATURE(FLAG(X) | FLAG(Ymm), 0, 0, 0x00),
+    2972             :   OSIGNATURE(FLAG(R) | FLAG(Vm), MEM(Vm32y), 0, 0x00),
+    2973             :   OSIGNATURE(FLAG(X) | FLAG(Zmm), 0, 0, 0x00),
+    2974             :   OSIGNATURE(FLAG(R) | FLAG(Vm), MEM(Vm32z), 0, 0x00),
+    2975             :   OSIGNATURE(FLAG(R) | FLAG(Vm), MEM(Vm64x), 0, 0x00),
+    2976             :   OSIGNATURE(FLAG(R) | FLAG(Vm), MEM(Vm64y), 0, 0x00),
+    2977             :   OSIGNATURE(FLAG(R) | FLAG(Vm), MEM(Vm64z), 0, 0x00),
+    2978             :   OSIGNATURE(FLAG(R) | FLAG(Gpq) | FLAG(U8), 0, 0, 0x00),
+    2979             :   OSIGNATURE(FLAG(R) | FLAG(Gpw) | FLAG(Gpd) | FLAG(Mem), MEM(M16) | MEM(M32), 0, 0x00),
+    2980             :   OSIGNATURE(FLAG(X) | FLAG(Gpw) | FLAG(Gpd) | FLAG(Mem), MEM(M16) | MEM(M32), 0, 0x00),
+    2981             :   OSIGNATURE(FLAG(R) | FLAG(Implicit) | FLAG(GpbLo), 0, 0, 0x01),
+    2982             :   OSIGNATURE(FLAG(R) | FLAG(Implicit) | FLAG(Gpw), 0, 0, 0x01),
+    2983             :   OSIGNATURE(FLAG(R) | FLAG(Implicit) | FLAG(Gpd), 0, 0, 0x01),
+    2984             :   OSIGNATURE(FLAG(R) | FLAG(Implicit) | FLAG(Gpq), 0, 0, 0x01),
+    2985             :   OSIGNATURE(FLAG(X) | FLAG(Implicit) | FLAG(Gpw), 0, 0, 0x04),
+    2986             :   OSIGNATURE(FLAG(X) | FLAG(Implicit) | FLAG(Gpd), 0, 0, 0x04),
+    2987             :   OSIGNATURE(FLAG(X) | FLAG(Implicit) | FLAG(Gpq), 0, 0, 0x04),
+    2988             :   OSIGNATURE(FLAG(W) | FLAG(Gpw) | FLAG(Gpq) | FLAG(Mem), MEM(Any) | MEM(M16) | MEM(M64), 0, 0x00),
+    2989             :   OSIGNATURE(FLAG(W) | FLAG(Seg), 0, 0, 0x1A),
+    2990             :   OSIGNATURE(FLAG(W) | FLAG(Seg), 0, 0, 0x60),
+    2991             :   OSIGNATURE(FLAG(R) | FLAG(Gpw) | FLAG(Gpq) | FLAG(Mem) | FLAG(I8) | FLAG(I16) | FLAG(I32), MEM(Any) | MEM(M16) | MEM(M64), 0, 0x00),
+    2992             :   OSIGNATURE(FLAG(R) | FLAG(Seg), 0, 0, 0x1E),
+    2993             :   OSIGNATURE(FLAG(R) | FLAG(Seg), 0, 0, 0x60),
+    2994             :   OSIGNATURE(FLAG(R) | FLAG(Vm), MEM(Vm64x) | MEM(Vm64y), 0, 0x00),
+    2995             :   OSIGNATURE(FLAG(W) | FLAG(Mem), MEM(Any) | MEM(M128), 0, 0x00),
+    2996             :   OSIGNATURE(FLAG(W) | FLAG(Mem), MEM(Any) | MEM(M256), 0, 0x00),
+    2997             :   OSIGNATURE(FLAG(R) | FLAG(Mem), MEM(Any) | MEM(M128), 0, 0x00),
+    2998             :   OSIGNATURE(FLAG(R) | FLAG(Mem), MEM(Any) | MEM(M256), 0, 0x00),
+    2999             :   OSIGNATURE(FLAG(R) | FLAG(U4), 0, 0, 0x00),
+    3000             :   OSIGNATURE(FLAG(R) | FLAG(Mem), MEM(M32) | MEM(M64), 0, 0x00),
+    3001             :   OSIGNATURE(FLAG(X) | FLAG(Fp), 0, 0, 0x01),
+    3002             :   OSIGNATURE(FLAG(R) | FLAG(Fp), 0, 0, 0x00),
+    3003             :   OSIGNATURE(FLAG(X) | FLAG(Fp), 0, 0, 0x00),
+    3004             :   OSIGNATURE(FLAG(R) | FLAG(Fp), 0, 0, 0x01),
+    3005             :   OSIGNATURE(FLAG(X) | FLAG(Mem), MEM(M32) | MEM(M64), 0, 0x00),
+    3006             :   OSIGNATURE(FLAG(R) | FLAG(Mem), MEM(Any) | MEM(M48), 0, 0x00),
+    3007             :   OSIGNATURE(FLAG(R) | FLAG(Mem), MEM(Any) | MEM(M80), 0, 0x00),
+    3008             :   OSIGNATURE(FLAG(R) | FLAG(GpbLo) | FLAG(U8), 0, 0, 0x02),
+    3009             :   OSIGNATURE(FLAG(W) | FLAG(K) | FLAG(Xmm), 0, 0, 0x00),
+    3010             :   OSIGNATURE(FLAG(W) | FLAG(K) | FLAG(Ymm), 0, 0, 0x00),
+    3011             :   OSIGNATURE(FLAG(W) | FLAG(K), 0, 0, 0x00),
+    3012             :   OSIGNATURE(FLAG(R) | FLAG(Xmm) | FLAG(Ymm) | FLAG(Mem), MEM(M64) | MEM(M128) | MEM(M256), 0, 0x00),
+    3013             :   OSIGNATURE(FLAG(R) | FLAG(Xmm) | FLAG(Mem), MEM(M128), 0, 0x00),
+    3014             :   OSIGNATURE(FLAG(R) | FLAG(Ymm) | FLAG(Mem), MEM(M256), 0, 0x00),
+    3015             :   OSIGNATURE(FLAG(W) | FLAG(Mem), MEM(Any) | MEM(M512), 0, 0x00),
+    3016             :   OSIGNATURE(FLAG(R) | FLAG(Mem), MEM(Any) | MEM(M512), 0, 0x00),
+    3017             :   OSIGNATURE(FLAG(R) | FLAG(Gpq) | FLAG(Xmm) | FLAG(Mem), MEM(Any) | MEM(M64), 0, 0x00),
+    3018             :   OSIGNATURE(FLAG(W) | FLAG(Xmm) | FLAG(Mem), MEM(Any) | MEM(M32), 0, 0x00),
+    3019             :   OSIGNATURE(FLAG(W) | FLAG(Xmm) | FLAG(Mem), MEM(Any) | MEM(M16), 0, 0x00),
+    3020             :   OSIGNATURE(FLAG(R) | FLAG(Xmm) | FLAG(Mem), MEM(Any) | MEM(M32), 0, 0x00),
+    3021             :   OSIGNATURE(FLAG(R) | FLAG(Xmm) | FLAG(Mem), MEM(Any) | MEM(M16), 0, 0x00),
+    3022             :   OSIGNATURE(FLAG(R) | FLAG(Xmm) | FLAG(Mem), MEM(Any) | MEM(M256), 0, 0x00),
+    3023             :   OSIGNATURE(FLAG(W) | FLAG(Vm), MEM(Vm32x), 0, 0x00),
+    3024             :   OSIGNATURE(FLAG(W) | FLAG(Vm), MEM(Vm32y), 0, 0x00),
+    3025             :   OSIGNATURE(FLAG(W) | FLAG(Vm), MEM(Vm32z), 0, 0x00),
+    3026             :   OSIGNATURE(FLAG(W) | FLAG(Vm), MEM(Vm64x), 0, 0x00),
+    3027             :   OSIGNATURE(FLAG(W) | FLAG(Vm), MEM(Vm64y), 0, 0x00),
+    3028             :   OSIGNATURE(FLAG(W) | FLAG(Vm), MEM(Vm64z), 0, 0x00),
+    3029             :   OSIGNATURE(FLAG(R) | FLAG(Bnd), 0, 0, 0x00),
+    3030             :   OSIGNATURE(FLAG(W) | FLAG(Bnd), 0, 0, 0x00),
+    3031             :   OSIGNATURE(FLAG(R) | FLAG(Bnd) | FLAG(Mem), MEM(Any), 0, 0x00),
+    3032             :   OSIGNATURE(FLAG(W) | FLAG(Bnd) | FLAG(Mem), MEM(Any), 0, 0x00),
+    3033             :   OSIGNATURE(FLAG(R) | FLAG(Gpq) | FLAG(Mem) | FLAG(I32) | FLAG(I64) | FLAG(Rel32), MEM(Any) | MEM(M64), 0, 0x00),
+    3034             :   OSIGNATURE(FLAG(R) | FLAG(GpbLo) | FLAG(GpbHi) | FLAG(Gpw) | FLAG(Gpd) | FLAG(Mem), MEM(M8) | MEM(M16) | MEM(M32), 0, 0x00),
+    3035             :   OSIGNATURE(FLAG(R) | FLAG(GpbLo) | FLAG(GpbHi) | FLAG(Gpq) | FLAG(Mem), MEM(M8) | MEM(M64), 0, 0x00),
+    3036             :   OSIGNATURE(FLAG(X) | FLAG(Gpw) | FLAG(Gpd), 0, 0, 0x00),
+    3037             :   OSIGNATURE(FLAG(R) | FLAG(Fp) | FLAG(Mem), MEM(M32) | MEM(M64), 0, 0x00),
+    3038             :   OSIGNATURE(FLAG(R) | FLAG(Implicit) | FLAG(Gpw) | FLAG(Gpd), 0, 0, 0x02),
+    3039             :   OSIGNATURE(FLAG(R) | FLAG(I32) | FLAG(I64) | FLAG(Rel8), 0, 0, 0x00),
+    3040             :   OSIGNATURE(FLAG(R) | FLAG(Implicit) | FLAG(Gpd) | FLAG(Gpq), 0, 0, 0x02),
+    3041             :   OSIGNATURE(FLAG(R) | FLAG(Gpq) | FLAG(Mem) | FLAG(I32) | FLAG(I64) | FLAG(Rel8) | FLAG(Rel32), MEM(Any) | MEM(M64), 0, 0x00),
+    3042             :   OSIGNATURE(FLAG(R) | FLAG(GpbLo) | FLAG(GpbHi) | FLAG(Gpw) | FLAG(Gpd) | FLAG(Gpq) | FLAG(K) | FLAG(Mem), MEM(Any) | MEM(M8), 0, 0x00),
+    3043             :   OSIGNATURE(FLAG(W) | FLAG(GpbLo) | FLAG(GpbHi) | FLAG(Gpw) | FLAG(Gpd) | FLAG(Gpq) | FLAG(Mem), MEM(Any) | MEM(M8), 0, 0x00),
+    3044             :   OSIGNATURE(FLAG(R) | FLAG(K), 0, 0, 0x00),
+    3045             :   OSIGNATURE(FLAG(R) | FLAG(Gpd) | FLAG(Gpq) | FLAG(K) | FLAG(Mem), MEM(Any) | MEM(M32), 0, 0x00),
+    3046             :   OSIGNATURE(FLAG(W) | FLAG(Gpd) | FLAG(Gpq) | FLAG(Mem), MEM(Any) | MEM(M32), 0, 0x00),
+    3047             :   OSIGNATURE(FLAG(R) | FLAG(Gpq) | FLAG(K) | FLAG(Mem), MEM(Any) | MEM(M64), 0, 0x00),
+    3048             :   OSIGNATURE(FLAG(R) | FLAG(Gpw) | FLAG(Gpd) | FLAG(Gpq) | FLAG(K) | FLAG(Mem), MEM(Any) | MEM(M16), 0, 0x00),
+    3049             :   OSIGNATURE(FLAG(W) | FLAG(Gpw) | FLAG(Gpd) | FLAG(Gpq) | FLAG(Mem), MEM(Any) | MEM(M16), 0, 0x00),
+    3050             :   OSIGNATURE(FLAG(R) | FLAG(Gpw) | FLAG(Gpd) | FLAG(Mem), MEM(Any) | MEM(M16), 0, 0x00),
+    3051             :   OSIGNATURE(FLAG(X) | FLAG(Implicit) | FLAG(Gpw) | FLAG(Gpd), 0, 0, 0x02),
+    3052             :   OSIGNATURE(FLAG(X) | FLAG(Implicit) | FLAG(Gpd) | FLAG(Gpq), 0, 0, 0x02),
+    3053             :   OSIGNATURE(FLAG(W) | FLAG(Gpd) | FLAG(Gpq), 0, 0, 0x00),
+    3054             :   OSIGNATURE(FLAG(W) | FLAG(Mm) | FLAG(Xmm), 0, 0, 0x00),
+    3055             :   OSIGNATURE(FLAG(R) | FLAG(Gpd) | FLAG(Gpq) | FLAG(Mem), MEM(Any) | MEM(M32), 0, 0x00),
+    3056             :   OSIGNATURE(FLAG(R) | FLAG(Mm) | FLAG(Xmm), 0, 0, 0x00),
+    3057             :   OSIGNATURE(FLAG(W) | FLAG(Gpw) | FLAG(Gpd) | FLAG(Gpq), 0, 0, 0x00),
+    3058             :   OSIGNATURE(FLAG(R) | FLAG(Implicit) | FLAG(Gpd), 0, 0, 0x04),
+    3059             :   OSIGNATURE(FLAG(R) | FLAG(Implicit) | FLAG(Gpq), 0, 0, 0x04),
+    3060             :   OSIGNATURE(FLAG(R) | FLAG(Mm) | FLAG(Mem), MEM(Any) | MEM(M64), 0, 0x00),
+    3061             :   OSIGNATURE(FLAG(X) | FLAG(Mm), 0, 0, 0x00),
+    3062             :   OSIGNATURE(FLAG(R) | FLAG(Mm) | FLAG(Mem) | FLAG(U8), MEM(Any) | MEM(M64), 0, 0x00),
+    3063             :   OSIGNATURE(FLAG(R) | FLAG(U16), 0, 0, 0x00),
+    3064             :   OSIGNATURE(FLAG(R) | FLAG(Xmm) | FLAG(Ymm) | FLAG(Mem), MEM(M128) | MEM(M256), 0, 0x00),
+    3065             :   OSIGNATURE(FLAG(W) | FLAG(Xmm) | FLAG(Ymm) | FLAG(Zmm), 0, 0, 0x00),
+    3066             :   OSIGNATURE(FLAG(R) | FLAG(Xmm) | FLAG(Mem), MEM(Any) | MEM(M8), 0, 0x00),
+    3067             :   OSIGNATURE(FLAG(R) | FLAG(Gpd) | FLAG(Gpq), 0, 0, 0x00),
+    3068             :   OSIGNATURE(FLAG(R) | FLAG(GpbLo) | FLAG(GpbHi) | FLAG(Gpw) | FLAG(Gpd) | FLAG(Gpq) | FLAG(Mem), MEM(Any) | MEM(M8), 0, 0x00),
+    3069             :   OSIGNATURE(FLAG(R) | FLAG(Xmm) | FLAG(U8), 0, 0, 0x00),
+    3070             :   OSIGNATURE(FLAG(W) | FLAG(Vm), MEM(Vm64x) | MEM(Vm64y), 0, 0x00),
+    3071             :   OSIGNATURE(FLAG(R) | FLAG(Xmm) | FLAG(Ymm), 0, 0, 0x00),
+    3072             :   OSIGNATURE(FLAG(R) | FLAG(Implicit) | FLAG(Xmm), 0, 0, 0x01),
+    3073             :   OSIGNATURE(FLAG(R) | FLAG(Mem), MEM(Mib), 0, 0x00),
+    3074             :   OSIGNATURE(FLAG(R) | FLAG(Mem), MEM(Any), 0, 0x00),
+    3075             :   OSIGNATURE(FLAG(W) | FLAG(Mem), MEM(Mib), 0, 0x00),
+    3076             :   OSIGNATURE(FLAG(X) | FLAG(Gpd) | FLAG(Gpq), 0, 0, 0x00),
+    3077             :   OSIGNATURE(FLAG(R) | FLAG(Implicit) | FLAG(Mem), MEM(BaseOnly) | MEM(Ds), 0, 0x01),
+    3078             :   OSIGNATURE(FLAG(X) | FLAG(Implicit) | FLAG(Mem), MEM(BaseOnly) | MEM(Ds), 0, 0x40),
+    3079             :   OSIGNATURE(FLAG(X) | FLAG(Implicit) | FLAG(Mem), MEM(BaseOnly) | MEM(Es), 0, 0x80),
+    3080             :   OSIGNATURE(FLAG(X) | FLAG(Mem), MEM(Any) | MEM(M128), 0, 0x00),
+    3081             :   OSIGNATURE(FLAG(R) | FLAG(Implicit) | FLAG(Gpq), 0, 0, 0x02),
+    3082             :   OSIGNATURE(FLAG(R) | FLAG(Implicit) | FLAG(Gpq), 0, 0, 0x08),
+    3083             :   OSIGNATURE(FLAG(X) | FLAG(Mem), MEM(Any) | MEM(M64), 0, 0x00),
+    3084             :   OSIGNATURE(FLAG(R) | FLAG(Implicit) | FLAG(Gpd), 0, 0, 0x02),
+    3085             :   OSIGNATURE(FLAG(R) | FLAG(Implicit) | FLAG(Gpd), 0, 0, 0x08),
+    3086             :   OSIGNATURE(FLAG(W) | FLAG(Implicit) | FLAG(Gpd), 0, 0, 0x08),
+    3087             :   OSIGNATURE(FLAG(X) | FLAG(Implicit) | FLAG(Gpd), 0, 0, 0x02),
+    3088             :   OSIGNATURE(FLAG(R) | FLAG(Gpd) | FLAG(Gpq) | FLAG(Mem), MEM(Any) | MEM(M32) | MEM(M64), 0, 0x00),
+    3089             :   OSIGNATURE(FLAG(W) | FLAG(Mem), MEM(Any) | MEM(M80), 0, 0x00),
+    3090             :   OSIGNATURE(FLAG(R) | FLAG(Mem), MEM(M16) | MEM(M32), 0, 0x00),
+    3091             :   OSIGNATURE(FLAG(R) | FLAG(Mem), MEM(M16) | MEM(M32) | MEM(M64), 0, 0x00),
+    3092             :   OSIGNATURE(FLAG(W) | FLAG(Mem), MEM(M16) | MEM(M32), 0, 0x00),
+    3093             :   OSIGNATURE(FLAG(W) | FLAG(Mem), MEM(M16) | MEM(M32) | MEM(M64), 0, 0x00),
+    3094             :   OSIGNATURE(FLAG(R) | FLAG(Fp) | FLAG(Mem), MEM(M32) | MEM(M64) | MEM(M80), 0, 0x00),
+    3095             :   OSIGNATURE(FLAG(W) | FLAG(Mem), MEM(Any), 0, 0x00),
+    3096             :   OSIGNATURE(FLAG(W) | FLAG(Gpw) | FLAG(Mem), MEM(Any) | MEM(M16), 0, 0x01),
+    3097             :   OSIGNATURE(FLAG(W) | FLAG(Fp) | FLAG(Mem), MEM(M32) | MEM(M64), 0, 0x00),
+    3098             :   OSIGNATURE(FLAG(W) | FLAG(Fp) | FLAG(Mem), MEM(M32) | MEM(M64) | MEM(M80), 0, 0x00),
+    3099             :   OSIGNATURE(FLAG(W) | FLAG(GpbLo) | FLAG(Gpw) | FLAG(Gpd), 0, 0, 0x01),
+    3100             :   OSIGNATURE(FLAG(R) | FLAG(Gpw) | FLAG(U8), 0, 0, 0x04),
+    3101             :   OSIGNATURE(FLAG(W) | FLAG(Mem), MEM(BaseOnly) | MEM(Es), 0, 0x80),
+    3102             :   OSIGNATURE(FLAG(R) | FLAG(Gpw), 0, 0, 0x04),
+    3103             :   OSIGNATURE(FLAG(R) | FLAG(I32) | FLAG(I64) | FLAG(Rel8) | FLAG(Rel32), 0, 0, 0x00),
+    3104             :   OSIGNATURE(FLAG(W) | FLAG(Implicit) | FLAG(GpbHi), 0, 0, 0x01),
+    3105             :   OSIGNATURE(FLAG(R) | FLAG(Mem), MEM(Any) | MEM(M8) | MEM(M16) | MEM(M32) | MEM(M48) | MEM(M64) | MEM(M80) | MEM(M128) | MEM(M256) | MEM(M512) | MEM(M1024), 0, 0x00),
+    3106             :   OSIGNATURE(FLAG(R) | FLAG(Gpw) | FLAG(Gpd) | FLAG(Gpq) | FLAG(Mem), MEM(Any) | MEM(M16), 0, 0x00),
+    3107             :   OSIGNATURE(FLAG(W) | FLAG(Implicit) | FLAG(GpbLo) | FLAG(Gpw) | FLAG(Gpd) | FLAG(Gpq), 0, 0, 0x01),
+    3108             :   OSIGNATURE(FLAG(R) | FLAG(Implicit) | FLAG(Mem), MEM(BaseOnly) | MEM(Ds), 0, 0x80),
+    3109             :   OSIGNATURE(FLAG(R) | FLAG(GpbLo) | FLAG(Gpw) | FLAG(Gpd), 0, 0, 0x01),
+    3110             :   OSIGNATURE(FLAG(R) | FLAG(Mem), MEM(BaseOnly) | MEM(Ds), 0, 0x40),
+    3111             :   OSIGNATURE(FLAG(W) | FLAG(Implicit) | FLAG(Gpd), 0, 0, 0x02),
+    3112             :   OSIGNATURE(FLAG(W) | FLAG(Implicit) | FLAG(Xmm), 0, 0, 0x01),
+    3113             :   OSIGNATURE(FLAG(X) | FLAG(Mm) | FLAG(Xmm), 0, 0, 0x00),
+    3114             :   OSIGNATURE(FLAG(W) | FLAG(Implicit) | FLAG(Gpd), 0, 0, 0x01),
+    3115             :   OSIGNATURE(FLAG(R) | FLAG(Implicit) | FLAG(GpbHi), 0, 0, 0x01),
+    3116             :   OSIGNATURE(FLAG(R) | FLAG(Implicit) | FLAG(GpbLo) | FLAG(Gpw) | FLAG(Gpd) | FLAG(Gpq), 0, 0, 0x01),
+    3117             :   OSIGNATURE(FLAG(W) | FLAG(Ymm) | FLAG(Zmm), 0, 0, 0x00),
+    3118             :   OSIGNATURE(FLAG(R) | FLAG(Ymm) | FLAG(Zmm), 0, 0, 0x00),
+    3119             :   OSIGNATURE(FLAG(R) | FLAG(Xmm) | FLAG(Ymm) | FLAG(Zmm) | FLAG(Mem), MEM(M128) | MEM(M256) | MEM(M512), 0, 0x00),
+    3120             :   OSIGNATURE(FLAG(R) | FLAG(Xmm) | FLAG(Ymm) | FLAG(Zmm), 0, 0, 0x00),
+    3121             :   OSIGNATURE(FLAG(R) | FLAG(I32) | FLAG(I64) | FLAG(Rel32), 0, 0, 0x00)
+    3122             : };
+    3123             : #undef OSIGNATURE
+    3124             : #undef MEM
+    3125             : #undef FLAG
+    3126             : 
+    3127             : #define ISIGNATURE(count, x86, x64, implicit, o0, o1, o2, o3, o4, o5) \
+    3128             :   { count, (x86 ? uint8_t(X86Inst::kArchMaskX86) : uint8_t(0)) |      \
+    3129             :            (x64 ? uint8_t(X86Inst::kArchMaskX64) : uint8_t(0)) ,      \
+    3130             :     implicit,                                                         \
+    3131             :     0,                                                                \
+    3132             :     { o0, o1, o2, o3, o4, o5 }                                        \
+    3133             :   }
+    3134             : const X86Inst::ISignature X86InstDB::iSignatureData[] = {
+    3135             :   ISIGNATURE(2, 1, 1, 0, 1  , 2  , 0  , 0  , 0  , 0  ), // #0   {W:r8lo|r8hi|m8|mem, R:r8lo|r8hi}
+    3136             :   ISIGNATURE(2, 1, 1, 0, 3  , 4  , 0  , 0  , 0  , 0  ), //      {W:r16|m16|mem, R:r16|sreg}
+    3137             :   ISIGNATURE(2, 1, 1, 0, 5  , 6  , 0  , 0  , 0  , 0  ), //      {W:r32|m32|mem|sreg, R:r32}
+    3138             :   ISIGNATURE(2, 0, 1, 0, 7  , 8  , 0  , 0  , 0  , 0  ), //      {W:r64|m64|mem, R:r64|sreg|i32}
+    3139             :   ISIGNATURE(2, 1, 1, 0, 9  , 10 , 0  , 0  , 0  , 0  ), //      {W:r8lo|r8hi, R:r8lo|r8hi|m8|mem|i8|u8}
+    3140             :   ISIGNATURE(2, 1, 1, 0, 11 , 12 , 0  , 0  , 0  , 0  ), //      {W:r16|sreg, R:r16|m16|mem}
+    3141             :   ISIGNATURE(2, 1, 1, 0, 13 , 14 , 0  , 0  , 0  , 0  ), //      {W:r32, R:r32|m32|mem|sreg|i32|u32}
+    3142             :   ISIGNATURE(2, 0, 1, 0, 15 , 16 , 0  , 0  , 0  , 0  ), //      {W:r64|sreg, R:r64|m64|mem}
+    3143             :   ISIGNATURE(2, 1, 1, 0, 17 , 18 , 0  , 0  , 0  , 0  ), //      {W:r16|m16, R:i16|u16}
+    3144             :   ISIGNATURE(2, 0, 1, 0, 19 , 20 , 0  , 0  , 0  , 0  ), //      {W:r64, R:i64|u64|creg|dreg}
+    3145             :   ISIGNATURE(2, 1, 1, 0, 21 , 22 , 0  , 0  , 0  , 0  ), //      {W:r8lo|r8hi|m8, R:i8|u8}
+    3146             :   ISIGNATURE(2, 1, 1, 0, 23 , 24 , 0  , 0  , 0  , 0  ), //      {W:r32|m32, R:i32|u32}
+    3147             :   ISIGNATURE(2, 1, 0, 0, 13 , 25 , 0  , 0  , 0  , 0  ), //      {W:r32, R:creg|dreg}
+    3148             :   ISIGNATURE(2, 1, 0, 0, 26 , 6  , 0  , 0  , 0  , 0  ), //      {W:creg|dreg, R:r32}
+    3149             :   ISIGNATURE(2, 0, 1, 0, 26 , 27 , 0  , 0  , 0  , 0  ), //      {W:creg|dreg, R:r64}
+    3150             :   ISIGNATURE(2, 1, 1, 0, 28 , 22 , 0  , 0  , 0  , 0  ), // #15  {X:r8lo|r8hi|m8, R:i8|u8}
+    3151             :   ISIGNATURE(2, 1, 1, 0, 29 , 18 , 0  , 0  , 0  , 0  ), //      {X:r16|m16, R:i16|u16}
+    3152             :   ISIGNATURE(2, 1, 1, 0, 30 , 24 , 0  , 0  , 0  , 0  ), //      {X:r32|m32, R:i32|u32}
+    3153             :   ISIGNATURE(2, 0, 1, 0, 31 , 32 , 0  , 0  , 0  , 0  ), //      {X:r64|m64|mem, R:i32|r64}
+    3154             :   ISIGNATURE(2, 1, 1, 0, 33 , 34 , 0  , 0  , 0  , 0  ), //      {X:r16|m16|r32|m32|r64|m64|mem, R:i8}
+    3155             :   ISIGNATURE(2, 1, 1, 0, 35 , 2  , 0  , 0  , 0  , 0  ), //      {X:r8lo|r8hi|m8|mem, R:r8lo|r8hi}
+    3156             :   ISIGNATURE(2, 1, 1, 0, 36 , 37 , 0  , 0  , 0  , 0  ), //      {X:r16|m16|mem, R:r16}
+    3157             :   ISIGNATURE(2, 1, 1, 0, 38 , 6  , 0  , 0  , 0  , 0  ), //      {X:r32|m32|mem, R:r32}
+    3158             :   ISIGNATURE(2, 1, 1, 0, 39 , 40 , 0  , 0  , 0  , 0  ), //      {X:r8lo|r8hi, R:r8lo|r8hi|m8|mem}
+    3159             :   ISIGNATURE(2, 1, 1, 0, 41 , 12 , 0  , 0  , 0  , 0  ), // #24  {X:r16, R:r16|m16|mem}
+    3160             :   ISIGNATURE(2, 1, 1, 0, 42 , 43 , 0  , 0  , 0  , 0  ), // #25  {X:r32, R:r32|m32|mem}
+    3161             :   ISIGNATURE(2, 0, 1, 0, 44 , 16 , 0  , 0  , 0  , 0  ), //      {X:r64, R:r64|m64|mem}
+    3162             :   ISIGNATURE(2, 1, 1, 0, 45 , 22 , 0  , 0  , 0  , 0  ), // #27  {R:r8lo|r8hi|m8, R:i8|u8}
+    3163             :   ISIGNATURE(2, 1, 1, 0, 46 , 18 , 0  , 0  , 0  , 0  ), //      {R:r16|m16, R:i16|u16}
+    3164             :   ISIGNATURE(2, 1, 1, 0, 47 , 24 , 0  , 0  , 0  , 0  ), //      {R:r32|m32, R:i32|u32}
+    3165             :   ISIGNATURE(2, 0, 1, 0, 16 , 32 , 0  , 0  , 0  , 0  ), //      {R:r64|m64|mem, R:i32|r64}
+    3166             :   ISIGNATURE(2, 1, 1, 0, 48 , 34 , 0  , 0  , 0  , 0  ), //      {R:r16|m16|r32|m32|r64|m64|mem, R:i8}
+    3167             :   ISIGNATURE(2, 1, 1, 0, 40 , 2  , 0  , 0  , 0  , 0  ), //      {R:r8lo|r8hi|m8|mem, R:r8lo|r8hi}
+    3168             :   ISIGNATURE(2, 1, 1, 0, 12 , 37 , 0  , 0  , 0  , 0  ), //      {R:r16|m16|mem, R:r16}
+    3169             :   ISIGNATURE(2, 1, 1, 0, 43 , 6  , 0  , 0  , 0  , 0  ), //      {R:r32|m32|mem, R:r32}
+    3170             :   ISIGNATURE(2, 1, 1, 0, 2  , 40 , 0  , 0  , 0  , 0  ), //      {R:r8lo|r8hi, R:r8lo|r8hi|m8|mem}
+    3171             :   ISIGNATURE(2, 1, 1, 0, 37 , 12 , 0  , 0  , 0  , 0  ), //      {R:r16, R:r16|m16|mem}
+    3172             :   ISIGNATURE(2, 1, 1, 0, 6  , 43 , 0  , 0  , 0  , 0  ), //      {R:r32, R:r32|m32|mem}
+    3173             :   ISIGNATURE(2, 0, 1, 0, 27 , 16 , 0  , 0  , 0  , 0  ), //      {R:r64, R:r64|m64|mem}
+    3174             :   ISIGNATURE(2, 1, 1, 0, 49 , 22 , 0  , 0  , 0  , 0  ), // #39  {X:r8lo|r8hi|m8|r16|m16|r32|m32|r64|m64|mem, R:i8|u8}
+    3175             :   ISIGNATURE(2, 1, 1, 0, 29 , 18 , 0  , 0  , 0  , 0  ), //      {X:r16|m16, R:i16|u16}
+    3176             :   ISIGNATURE(2, 1, 1, 0, 30 , 24 , 0  , 0  , 0  , 0  ), //      {X:r32|m32, R:i32|u32}
+    3177             :   ISIGNATURE(2, 0, 1, 0, 31 , 32 , 0  , 0  , 0  , 0  ), //      {X:r64|m64|mem, R:i32|r64}
+    3178             :   ISIGNATURE(2, 1, 1, 0, 35 , 2  , 0  , 0  , 0  , 0  ), //      {X:r8lo|r8hi|m8|mem, R:r8lo|r8hi}
+    3179             :   ISIGNATURE(2, 1, 1, 0, 36 , 37 , 0  , 0  , 0  , 0  ), //      {X:r16|m16|mem, R:r16}
+    3180             :   ISIGNATURE(2, 1, 1, 0, 38 , 6  , 0  , 0  , 0  , 0  ), //      {X:r32|m32|mem, R:r32}
+    3181             :   ISIGNATURE(2, 1, 1, 0, 39 , 40 , 0  , 0  , 0  , 0  ), //      {X:r8lo|r8hi, R:r8lo|r8hi|m8|mem}
+    3182             :   ISIGNATURE(2, 1, 1, 0, 41 , 12 , 0  , 0  , 0  , 0  ), //      {X:r16, R:r16|m16|mem}
+    3183             :   ISIGNATURE(2, 1, 1, 0, 42 , 43 , 0  , 0  , 0  , 0  ), //      {X:r32, R:r32|m32|mem}
+    3184             :   ISIGNATURE(2, 0, 1, 0, 44 , 16 , 0  , 0  , 0  , 0  ), //      {X:r64, R:r64|m64|mem}
+    3185             :   ISIGNATURE(2, 1, 1, 1, 50 , 40 , 0  , 0  , 0  , 0  ), // #50  {X:<ax>, R:r8lo|r8hi|m8|mem}
+    3186             :   ISIGNATURE(3, 1, 1, 2, 51 , 50 , 12 , 0  , 0  , 0  ), //      {W:<dx>, X:<ax>, R:r16|m16|mem}
+    3187             :   ISIGNATURE(3, 1, 1, 2, 52 , 53 , 43 , 0  , 0  , 0  ), //      {W:<edx>, X:<eax>, R:r32|m32|mem}
+    3188             :   ISIGNATURE(3, 0, 1, 2, 54 , 55 , 16 , 0  , 0  , 0  ), //      {W:<rdx>, X:<rax>, R:r64|m64|mem}
+    3189             :   ISIGNATURE(2, 1, 1, 0, 41 , 56 , 0  , 0  , 0  , 0  ), //      {X:r16, R:r16|m16|mem|i8|i16}
+    3190             :   ISIGNATURE(2, 1, 1, 0, 42 , 57 , 0  , 0  , 0  , 0  ), //      {X:r32, R:r32|m32|mem|i8|i32}
+    3191             :   ISIGNATURE(2, 0, 1, 0, 44 , 58 , 0  , 0  , 0  , 0  ), //      {X:r64, R:r64|m64|mem|i8|i32}
+    3192             :   ISIGNATURE(3, 1, 1, 0, 59 , 12 , 60 , 0  , 0  , 0  ), //      {W:r16, R:r16|m16|mem, R:i8|i16|u16}
+    3193             :   ISIGNATURE(3, 1, 1, 0, 13 , 43 , 61 , 0  , 0  , 0  ), //      {W:r32, R:r32|m32|mem, R:i8|i32|u32}
+    3194             :   ISIGNATURE(3, 0, 1, 0, 19 , 16 , 62 , 0  , 0  , 0  ), //      {W:r64, R:r64|m64|mem, R:i8|i32}
+    3195             :   ISIGNATURE(2, 1, 1, 0, 36 , 41 , 0  , 0  , 0  , 0  ), // #60  {X:r16|m16|mem, X:r16}
+    3196             :   ISIGNATURE(2, 1, 1, 0, 38 , 42 , 0  , 0  , 0  , 0  ), //      {X:r32|m32|mem, X:r32}
+    3197             :   ISIGNATURE(2, 0, 1, 0, 31 , 44 , 0  , 0  , 0  , 0  ), //      {X:r64|m64|mem, X:r64}
+    3198             :   ISIGNATURE(2, 1, 1, 0, 41 , 36 , 0  , 0  , 0  , 0  ), //      {X:r16, X:r16|m16|mem}
+    3199             :   ISIGNATURE(2, 1, 1, 0, 42 , 38 , 0  , 0  , 0  , 0  ), //      {X:r32, X:r32|m32|mem}
+    3200             :   ISIGNATURE(2, 0, 1, 0, 44 , 31 , 0  , 0  , 0  , 0  ), //      {X:r64, X:r64|m64|mem}
+    3201             :   ISIGNATURE(2, 1, 1, 0, 35 , 39 , 0  , 0  , 0  , 0  ), //      {X:r8lo|r8hi|m8|mem, X:r8lo|r8hi}
+    3202             :   ISIGNATURE(2, 1, 1, 0, 39 , 35 , 0  , 0  , 0  , 0  ), //      {X:r8lo|r8hi, X:r8lo|r8hi|m8|mem}
+    3203             :   ISIGNATURE(2, 1, 1, 0, 45 , 22 , 0  , 0  , 0  , 0  ), // #68  {R:r8lo|r8hi|m8, R:i8|u8}
+    3204             :   ISIGNATURE(2, 1, 1, 0, 46 , 18 , 0  , 0  , 0  , 0  ), //      {R:r16|m16, R:i16|u16}
+    3205             :   ISIGNATURE(2, 1, 1, 0, 47 , 24 , 0  , 0  , 0  , 0  ), //      {R:r32|m32, R:i32|u32}
+    3206             :   ISIGNATURE(2, 0, 1, 0, 16 , 32 , 0  , 0  , 0  , 0  ), //      {R:r64|m64|mem, R:i32|r64}
+    3207             :   ISIGNATURE(2, 1, 1, 0, 40 , 2  , 0  , 0  , 0  , 0  ), //      {R:r8lo|r8hi|m8|mem, R:r8lo|r8hi}
+    3208             :   ISIGNATURE(2, 1, 1, 0, 12 , 37 , 0  , 0  , 0  , 0  ), //      {R:r16|m16|mem, R:r16}
+    3209             :   ISIGNATURE(2, 1, 1, 0, 43 , 6  , 0  , 0  , 0  , 0  ), //      {R:r32|m32|mem, R:r32}
+    3210             :   ISIGNATURE(2, 1, 1, 0, 59 , 63 , 0  , 0  , 0  , 0  ), // #75  {W:r16, R:m16|mem}
+    3211             :   ISIGNATURE(2, 1, 1, 0, 13 , 64 , 0  , 0  , 0  , 0  ), //      {W:r32, R:m32|mem}
+    3212             :   ISIGNATURE(2, 0, 1, 0, 19 , 65 , 0  , 0  , 0  , 0  ), //      {W:r64, R:m64|mem}
+    3213             :   ISIGNATURE(2, 1, 1, 0, 66 , 37 , 0  , 0  , 0  , 0  ), //      {W:m16|mem, R:r16}
+    3214             :   ISIGNATURE(2, 1, 1, 0, 67 , 6  , 0  , 0  , 0  , 0  ), // #79  {W:m32|mem, R:r32}
+    3215             :   ISIGNATURE(2, 0, 1, 0, 68 , 27 , 0  , 0  , 0  , 0  ), //      {W:m64|mem, R:r64}
+    3216             :   ISIGNATURE(2, 1, 1, 0, 69 , 70 , 0  , 0  , 0  , 0  ), // #81  {W:mm, R:mm|m64|mem|r64|xmm}
+    3217             :   ISIGNATURE(2, 1, 1, 0, 71 , 72 , 0  , 0  , 0  , 0  ), //      {W:mm|m64|mem|r64|xmm, R:mm}
+    3218             :   ISIGNATURE(2, 0, 1, 0, 7  , 73 , 0  , 0  , 0  , 0  ), //      {W:r64|m64|mem, R:xmm}
+    3219             :   ISIGNATURE(2, 0, 1, 0, 74 , 16 , 0  , 0  , 0  , 0  ), //      {W:xmm, R:r64|m64|mem}
+    3220             :   ISIGNATURE(2, 1, 1, 0, 74 , 75 , 0  , 0  , 0  , 0  ), // #85  {W:xmm, R:xmm|m64|mem}
+    3221             :   ISIGNATURE(2, 1, 1, 0, 76 , 73 , 0  , 0  , 0  , 0  ), //      {W:xmm|m64|mem, R:xmm}
+    3222             :   ISIGNATURE(2, 1, 1, 0, 74 , 77 , 0  , 0  , 0  , 0  ), // #87  {W:xmm, R:xmm|m128|mem}
+    3223             :   ISIGNATURE(2, 1, 1, 0, 78 , 73 , 0  , 0  , 0  , 0  ), //      {W:xmm|m128|mem, R:xmm}
+    3224             :   ISIGNATURE(2, 1, 1, 0, 79 , 80 , 0  , 0  , 0  , 0  ), //      {W:ymm, R:ymm|m256|mem}
+    3225             :   ISIGNATURE(2, 1, 1, 0, 81 , 82 , 0  , 0  , 0  , 0  ), //      {W:ymm|m256|mem, R:ymm}
+    3226             :   ISIGNATURE(2, 1, 1, 0, 83 , 84 , 0  , 0  , 0  , 0  ), // #91  {W:zmm, R:zmm|m512|mem}
+    3227             :   ISIGNATURE(2, 1, 1, 0, 85 , 86 , 0  , 0  , 0  , 0  ), //      {W:zmm|m512|mem, R:zmm}
+    3228             :   ISIGNATURE(3, 1, 1, 0, 74 , 73 , 77 , 0  , 0  , 0  ), // #93  {W:xmm, R:xmm, R:xmm|m128|mem}
+    3229             :   ISIGNATURE(3, 1, 1, 0, 74 , 77 , 87 , 0  , 0  , 0  ), // #94  {W:xmm, R:xmm|m128|mem, R:u8}
+    3230             :   ISIGNATURE(3, 1, 1, 0, 79 , 82 , 80 , 0  , 0  , 0  ), // #95  {W:ymm, R:ymm, R:ymm|m256|mem}
+    3231             :   ISIGNATURE(3, 1, 1, 0, 79 , 80 , 87 , 0  , 0  , 0  ), // #96  {W:ymm, R:ymm|m256|mem, R:u8}
+    3232             :   ISIGNATURE(3, 1, 1, 0, 83 , 86 , 84 , 0  , 0  , 0  ), //      {W:zmm, R:zmm, R:zmm|m512|mem}
+    3233             :   ISIGNATURE(3, 1, 1, 0, 83 , 84 , 87 , 0  , 0  , 0  ), //      {W:zmm, R:zmm|m512|mem, R:u8}
+    3234             :   ISIGNATURE(3, 1, 1, 0, 74 , 73 , 88 , 0  , 0  , 0  ), // #99  {W:xmm, R:xmm, R:u8|xmm|m128|mem}
+    3235             :   ISIGNATURE(3, 1, 1, 0, 79 , 82 , 88 , 0  , 0  , 0  ), //      {W:ymm, R:ymm, R:u8|xmm|m128|mem}
+    3236             :   ISIGNATURE(3, 1, 1, 0, 74 , 77 , 87 , 0  , 0  , 0  ), // #101 {W:xmm, R:xmm|m128|mem, R:u8}
+    3237             :   ISIGNATURE(3, 1, 1, 0, 79 , 80 , 87 , 0  , 0  , 0  ), //      {W:ymm, R:ymm|m256|mem, R:u8}
+    3238             :   ISIGNATURE(3, 1, 1, 0, 83 , 86 , 77 , 0  , 0  , 0  ), //      {W:zmm, R:zmm, R:xmm|m128|mem}
+    3239             :   ISIGNATURE(3, 1, 1, 0, 83 , 84 , 87 , 0  , 0  , 0  ), //      {W:zmm, R:zmm|m512|mem, R:u8}
+    3240             :   ISIGNATURE(3, 1, 1, 0, 74 , 73 , 77 , 0  , 0  , 0  ), // #105 {W:xmm, R:xmm, R:xmm|m128|mem}
+    3241             :   ISIGNATURE(3, 1, 1, 0, 74 , 77 , 87 , 0  , 0  , 0  ), //      {W:xmm, R:xmm|m128|mem, R:u8}
+    3242             :   ISIGNATURE(3, 1, 1, 0, 79 , 82 , 77 , 0  , 0  , 0  ), //      {W:ymm, R:ymm, R:xmm|m128|mem}
+    3243             :   ISIGNATURE(3, 1, 1, 0, 79 , 80 , 87 , 0  , 0  , 0  ), //      {W:ymm, R:ymm|m256|mem, R:u8}
+    3244             :   ISIGNATURE(3, 1, 1, 0, 83 , 86 , 77 , 0  , 0  , 0  ), //      {W:zmm, R:zmm, R:xmm|m128|mem}
+    3245             :   ISIGNATURE(3, 1, 1, 0, 83 , 84 , 87 , 0  , 0  , 0  ), //      {W:zmm, R:zmm|m512|mem, R:u8}
+    3246             :   ISIGNATURE(3, 1, 1, 0, 89 , 90 , 89 , 0  , 0  , 0  ), // #111 {X:xmm, R:vm32x, X:xmm}
+    3247             :   ISIGNATURE(3, 1, 1, 0, 91 , 90 , 91 , 0  , 0  , 0  ), //      {X:ymm, R:vm32x, X:ymm}
+    3248             :   ISIGNATURE(2, 1, 1, 0, 89 , 90 , 0  , 0  , 0  , 0  ), //      {X:xmm, R:vm32x}
+    3249             :   ISIGNATURE(2, 1, 1, 0, 91 , 92 , 0  , 0  , 0  , 0  ), //      {X:ymm, R:vm32y}
+    3250             :   ISIGNATURE(2, 1, 1, 0, 93 , 94 , 0  , 0  , 0  , 0  ), //      {X:zmm, R:vm32z}
+    3251             :   ISIGNATURE(3, 1, 1, 0, 89 , 90 , 89 , 0  , 0  , 0  ), // #116 {X:xmm, R:vm32x, X:xmm}
+    3252             :   ISIGNATURE(3, 1, 1, 0, 91 , 92 , 91 , 0  , 0  , 0  ), //      {X:ymm, R:vm32y, X:ymm}
+    3253             :   ISIGNATURE(2, 1, 1, 0, 89 , 90 , 0  , 0  , 0  , 0  ), //      {X:xmm, R:vm32x}
+    3254             :   ISIGNATURE(2, 1, 1, 0, 91 , 92 , 0  , 0  , 0  , 0  ), //      {X:ymm, R:vm32y}
+    3255             :   ISIGNATURE(2, 1, 1, 0, 93 , 94 , 0  , 0  , 0  , 0  ), //      {X:zmm, R:vm32z}
+    3256             :   ISIGNATURE(3, 1, 1, 0, 89 , 95 , 89 , 0  , 0  , 0  ), // #121 {X:xmm, R:vm64x, X:xmm}
+    3257             :   ISIGNATURE(3, 1, 1, 0, 91 , 96 , 91 , 0  , 0  , 0  ), //      {X:ymm, R:vm64y, X:ymm}
+    3258             :   ISIGNATURE(2, 1, 1, 0, 89 , 95 , 0  , 0  , 0  , 0  ), //      {X:xmm, R:vm64x}
+    3259             :   ISIGNATURE(2, 1, 1, 0, 91 , 96 , 0  , 0  , 0  , 0  ), //      {X:ymm, R:vm64y}
+    3260             :   ISIGNATURE(2, 1, 1, 0, 93 , 97 , 0  , 0  , 0  , 0  ), //      {X:zmm, R:vm64z}
+    3261             :   ISIGNATURE(2, 1, 1, 0, 12 , 37 , 0  , 0  , 0  , 0  ), // #126 {R:r16|m16|mem, R:r16}
+    3262             :   ISIGNATURE(2, 1, 1, 0, 43 , 6  , 0  , 0  , 0  , 0  ), //      {R:r32|m32|mem, R:r32}
+    3263             :   ISIGNATURE(2, 0, 1, 0, 16 , 98 , 0  , 0  , 0  , 0  ), //      {R:r64|m64|mem, R:r64|u8}
+    3264             :   ISIGNATURE(2, 1, 1, 0, 99 , 87 , 0  , 0  , 0  , 0  ), //      {R:r16|m16|r32|m32, R:u8}
+    3265             :   ISIGNATURE(2, 1, 1, 0, 36 , 37 , 0  , 0  , 0  , 0  ), // #130 {X:r16|m16|mem, R:r16}
+    3266             :   ISIGNATURE(2, 1, 1, 0, 38 , 6  , 0  , 0  , 0  , 0  ), //      {X:r32|m32|mem, R:r32}
+    3267             :   ISIGNATURE(2, 0, 1, 0, 31 , 98 , 0  , 0  , 0  , 0  ), //      {X:r64|m64|mem, R:r64|u8}
+    3268             :   ISIGNATURE(2, 1, 1, 0, 100, 87 , 0  , 0  , 0  , 0  ), //      {X:r16|m16|r32|m32, R:u8}
+    3269             :   ISIGNATURE(3, 1, 1, 1, 35 , 2  , 101, 0  , 0  , 0  ), // #134 {X:r8lo|r8hi|m8|mem, R:r8lo|r8hi, R:<al>}
+    3270             :   ISIGNATURE(3, 1, 1, 1, 36 , 37 , 102, 0  , 0  , 0  ), //      {X:r16|m16|mem, R:r16, R:<ax>}
+    3271             :   ISIGNATURE(3, 1, 1, 1, 38 , 6  , 103, 0  , 0  , 0  ), //      {X:r32|m32|mem, R:r32, R:<eax>}
+    3272             :   ISIGNATURE(3, 0, 1, 1, 31 , 27 , 104, 0  , 0  , 0  ), //      {X:r64|m64|mem, R:r64, R:<rax>}
+    3273             :   ISIGNATURE(2, 1, 1, 1, 50 , 40 , 0  , 0  , 0  , 0  ), // #138 {X:<ax>, R:r8lo|r8hi|m8|mem}
+    3274             :   ISIGNATURE(3, 1, 1, 2, 105, 50 , 12 , 0  , 0  , 0  ), //      {X:<dx>, X:<ax>, R:r16|m16|mem}
+    3275             :   ISIGNATURE(3, 1, 1, 2, 106, 53 , 43 , 0  , 0  , 0  ), //      {X:<edx>, X:<eax>, R:r32|m32|mem}
+    3276             :   ISIGNATURE(3, 0, 1, 2, 107, 55 , 16 , 0  , 0  , 0  ), //      {X:<rdx>, X:<rax>, R:r64|m64|mem}
+    3277             :   ISIGNATURE(1, 1, 1, 0, 108, 0  , 0  , 0  , 0  , 0  ), // #142 {W:r16|m16|r64|m64|mem}
+    3278             :   ISIGNATURE(1, 1, 0, 0, 23 , 0  , 0  , 0  , 0  , 0  ), //      {W:r32|m32}
+    3279             :   ISIGNATURE(1, 1, 0, 0, 109, 0  , 0  , 0  , 0  , 0  ), //      {W:ds|es|ss}
+    3280             :   ISIGNATURE(1, 1, 1, 0, 110, 0  , 0  , 0  , 0  , 0  ), //      {W:fs|gs}
+    3281             :   ISIGNATURE(1, 1, 1, 0, 111, 0  , 0  , 0  , 0  , 0  ), // #146 {R:r16|m16|r64|m64|mem|i8|i16|i32}
+    3282             :   ISIGNATURE(1, 1, 0, 0, 47 , 0  , 0  , 0  , 0  , 0  ), //      {R:r32|m32}
+    3283             :   ISIGNATURE(1, 1, 0, 0, 112, 0  , 0  , 0  , 0  , 0  ), //      {R:cs|ss|ds|es}
+    3284             :   ISIGNATURE(1, 1, 1, 0, 113, 0  , 0  , 0  , 0  , 0  ), //      {R:fs|gs}
+    3285             :   ISIGNATURE(4, 1, 1, 0, 74 , 73 , 73 , 77 , 0  , 0  ), // #150 {W:xmm, R:xmm, R:xmm, R:xmm|m128|mem}
+    3286             :   ISIGNATURE(4, 1, 1, 0, 74 , 73 , 77 , 73 , 0  , 0  ), // #151 {W:xmm, R:xmm, R:xmm|m128|mem, R:xmm}
+    3287             :   ISIGNATURE(4, 1, 1, 0, 79 , 82 , 82 , 80 , 0  , 0  ), //      {W:ymm, R:ymm, R:ymm, R:ymm|m256|mem}
+    3288             :   ISIGNATURE(4, 1, 1, 0, 79 , 82 , 80 , 82 , 0  , 0  ), //      {W:ymm, R:ymm, R:ymm|m256|mem, R:ymm}
+    3289             :   ISIGNATURE(3, 1, 1, 0, 89 , 114, 89 , 0  , 0  , 0  ), // #154 {X:xmm, R:vm64x|vm64y, X:xmm}
+    3290             :   ISIGNATURE(2, 1, 1, 0, 89 , 95 , 0  , 0  , 0  , 0  ), //      {X:xmm, R:vm64x}
+    3291             :   ISIGNATURE(2, 1, 1, 0, 91 , 96 , 0  , 0  , 0  , 0  ), //      {X:ymm, R:vm64y}
+    3292             :   ISIGNATURE(2, 1, 1, 0, 93 , 97 , 0  , 0  , 0  , 0  ), //      {X:zmm, R:vm64z}
+    3293             :   ISIGNATURE(3, 1, 1, 0, 115, 73 , 73 , 0  , 0  , 0  ), // #158 {W:m128|mem, R:xmm, R:xmm}
+    3294             :   ISIGNATURE(3, 1, 1, 0, 116, 82 , 82 , 0  , 0  , 0  ), //      {W:m256|mem, R:ymm, R:ymm}
+    3295             :   ISIGNATURE(3, 1, 1, 0, 74 , 73 , 117, 0  , 0  , 0  ), //      {W:xmm, R:xmm, R:m128|mem}
+    3296             :   ISIGNATURE(3, 1, 1, 0, 79 , 82 , 118, 0  , 0  , 0  ), //      {W:ymm, R:ymm, R:m256|mem}
+    3297             :   ISIGNATURE(5, 1, 1, 0, 74 , 73 , 77 , 73 , 119, 0  ), // #162 {W:xmm, R:xmm, R:xmm|m128|mem, R:xmm, R:u4}
+    3298             :   ISIGNATURE(5, 1, 1, 0, 74 , 73 , 73 , 77 , 119, 0  ), //      {W:xmm, R:xmm, R:xmm, R:xmm|m128|mem, R:u4}
+    3299             :   ISIGNATURE(5, 1, 1, 0, 79 , 82 , 80 , 82 , 119, 0  ), //      {W:ymm, R:ymm, R:ymm|m256|mem, R:ymm, R:u4}
+    3300             :   ISIGNATURE(5, 1, 1, 0, 79 , 82 , 82 , 80 , 119, 0  ), //      {W:ymm, R:ymm, R:ymm, R:ymm|m256|mem, R:u4}
+    3301             :   ISIGNATURE(3, 1, 1, 0, 79 , 80 , 87 , 0  , 0  , 0  ), // #166 {W:ymm, R:ymm|m256|mem, R:u8}
+    3302             :   ISIGNATURE(3, 1, 1, 0, 79 , 82 , 80 , 0  , 0  , 0  ), // #167 {W:ymm, R:ymm, R:ymm|m256|mem}
+    3303             :   ISIGNATURE(3, 1, 1, 0, 83 , 86 , 84 , 0  , 0  , 0  ), //      {W:zmm, R:zmm, R:zmm|m512|mem}
+    3304             :   ISIGNATURE(3, 1, 1, 0, 83 , 84 , 87 , 0  , 0  , 0  ), //      {W:zmm, R:zmm|m512|mem, R:u8}
+    3305             :   ISIGNATURE(2, 1, 1, 0, 35 , 39 , 0  , 0  , 0  , 0  ), // #170 {X:r8lo|r8hi|m8|mem, X:r8lo|r8hi}
+    3306             :   ISIGNATURE(2, 1, 1, 0, 36 , 41 , 0  , 0  , 0  , 0  ), //      {X:r16|m16|mem, X:r16}
+    3307             :   ISIGNATURE(2, 1, 1, 0, 38 , 42 , 0  , 0  , 0  , 0  ), //      {X:r32|m32|mem, X:r32}
+    3308             :   ISIGNATURE(2, 0, 1, 0, 31 , 44 , 0  , 0  , 0  , 0  ), //      {X:r64|m64|mem, X:r64}
+    3309             :   ISIGNATURE(1, 1, 1, 0, 120, 0  , 0  , 0  , 0  , 0  ), // #174 {R:m32|m64}
+    3310             :   ISIGNATURE(2, 1, 1, 0, 121, 122, 0  , 0  , 0  , 0  ), //      {X:fp0, R:fp}
+    3311             :   ISIGNATURE(2, 1, 1, 0, 123, 124, 0  , 0  , 0  , 0  ), //      {X:fp, R:fp0}
+    3312             :   ISIGNATURE(1, 1, 1, 0, 125, 0  , 0  , 0  , 0  , 0  ), // #177 {X:m32|m64}
+    3313             :   ISIGNATURE(2, 1, 1, 0, 121, 122, 0  , 0  , 0  , 0  ), //      {X:fp0, R:fp}
+    3314             :   ISIGNATURE(2, 1, 1, 0, 123, 124, 0  , 0  , 0  , 0  ), //      {X:fp, R:fp0}
+    3315             :   ISIGNATURE(2, 1, 1, 0, 41 , 64 , 0  , 0  , 0  , 0  ), // #180 {X:r16, R:m32|mem}
+    3316             :   ISIGNATURE(2, 1, 1, 0, 42 , 126, 0  , 0  , 0  , 0  ), //      {X:r32, R:m48|mem}
+    3317             :   ISIGNATURE(2, 0, 1, 0, 44 , 127, 0  , 0  , 0  , 0  ), //      {X:r64, R:m80|mem}
+    3318             :   ISIGNATURE(2, 1, 1, 0, 59 , 12 , 0  , 0  , 0  , 0  ), // #183 {W:r16, R:r16|m16|mem}
+    3319             :   ISIGNATURE(2, 1, 1, 0, 13 , 43 , 0  , 0  , 0  , 0  ), // #184 {W:r32, R:r32|m32|mem}
+    3320             :   ISIGNATURE(2, 0, 1, 0, 19 , 16 , 0  , 0  , 0  , 0  ), //      {W:r64, R:r64|m64|mem}
+    3321             :   ISIGNATURE(3, 1, 1, 0, 36 , 37 , 128, 0  , 0  , 0  ), // #186 {X:r16|m16|mem, R:r16, R:u8|cl}
+    3322             :   ISIGNATURE(3, 1, 1, 0, 38 , 6  , 128, 0  , 0  , 0  ), //      {X:r32|m32|mem, R:r32, R:u8|cl}
+    3323             :   ISIGNATURE(3, 0, 1, 0, 31 , 27 , 128, 0  , 0  , 0  ), //      {X:r64|m64|mem, R:r64, R:u8|cl}
+    3324             :   ISIGNATURE(3, 1, 1, 0, 74 , 73 , 77 , 0  , 0  , 0  ), // #189 {W:xmm, R:xmm, R:xmm|m128|mem}
+    3325             :   ISIGNATURE(3, 1, 1, 0, 79 , 82 , 80 , 0  , 0  , 0  ), //      {W:ymm, R:ymm, R:ymm|m256|mem}
+    3326             :   ISIGNATURE(3, 1, 1, 0, 83 , 86 , 84 , 0  , 0  , 0  ), //      {W:zmm, R:zmm, R:zmm|m512|mem}
+    3327             :   ISIGNATURE(4, 1, 1, 0, 74 , 73 , 77 , 87 , 0  , 0  ), // #192 {W:xmm, R:xmm, R:xmm|m128|mem, R:u8}
+    3328             :   ISIGNATURE(4, 1, 1, 0, 79 , 82 , 80 , 87 , 0  , 0  ), // #193 {W:ymm, R:ymm, R:ymm|m256|mem, R:u8}
+    3329             :   ISIGNATURE(4, 1, 1, 0, 83 , 86 , 84 , 87 , 0  , 0  ), //      {W:zmm, R:zmm, R:zmm|m512|mem, R:u8}
+    3330             :   ISIGNATURE(4, 1, 1, 0, 129, 73 , 77 , 87 , 0  , 0  ), // #195 {W:xmm|k, R:xmm, R:xmm|m128|mem, R:u8}
+    3331             :   ISIGNATURE(4, 1, 1, 0, 130, 82 , 80 , 87 , 0  , 0  ), //      {W:ymm|k, R:ymm, R:ymm|m256|mem, R:u8}
+    3332             :   ISIGNATURE(4, 1, 1, 0, 131, 86 , 84 , 87 , 0  , 0  ), //      {W:k, R:zmm, R:zmm|m512|mem, R:u8}
+    3333             :   ISIGNATURE(2, 1, 1, 0, 78 , 73 , 0  , 0  , 0  , 0  ), // #198 {W:xmm|m128|mem, R:xmm}
+    3334             :   ISIGNATURE(2, 1, 1, 0, 81 , 82 , 0  , 0  , 0  , 0  ), //      {W:ymm|m256|mem, R:ymm}
+    3335             :   ISIGNATURE(2, 1, 1, 0, 85 , 86 , 0  , 0  , 0  , 0  ), //      {W:zmm|m512|mem, R:zmm}
+    3336             :   ISIGNATURE(2, 1, 1, 0, 74 , 75 , 0  , 0  , 0  , 0  ), // #201 {W:xmm, R:xmm|m64|mem}
+    3337             :   ISIGNATURE(2, 1, 1, 0, 79 , 77 , 0  , 0  , 0  , 0  ), //      {W:ymm, R:xmm|m128|mem}
+    3338             :   ISIGNATURE(2, 1, 1, 0, 83 , 80 , 0  , 0  , 0  , 0  ), //      {W:zmm, R:ymm|m256|mem}
+    3339             :   ISIGNATURE(2, 1, 1, 0, 74 , 77 , 0  , 0  , 0  , 0  ), // #204 {W:xmm, R:xmm|m128|mem}
+    3340             :   ISIGNATURE(2, 1, 1, 0, 79 , 80 , 0  , 0  , 0  , 0  ), //      {W:ymm, R:ymm|m256|mem}
+    3341             :   ISIGNATURE(2, 1, 1, 0, 83 , 84 , 0  , 0  , 0  , 0  ), //      {W:zmm, R:zmm|m512|mem}
+    3342             :   ISIGNATURE(2, 1, 1, 0, 74 , 132, 0  , 0  , 0  , 0  ), // #207 {W:xmm, R:xmm|m128|ymm|m256|m64}
+    3343             :   ISIGNATURE(2, 1, 1, 0, 79 , 133, 0  , 0  , 0  , 0  ), //      {W:ymm, R:xmm|m128}
+    3344             :   ISIGNATURE(2, 1, 1, 0, 83 , 134, 0  , 0  , 0  , 0  ), //      {W:zmm, R:ymm|m256}
+    3345             :   ISIGNATURE(3, 1, 1, 0, 76 , 73 , 87 , 0  , 0  , 0  ), // #210 {W:xmm|m64|mem, R:xmm, R:u8}
+    3346             :   ISIGNATURE(3, 1, 1, 0, 78 , 82 , 87 , 0  , 0  , 0  ), // #211 {W:xmm|m128|mem, R:ymm, R:u8}
+    3347             :   ISIGNATURE(3, 1, 1, 0, 81 , 86 , 87 , 0  , 0  , 0  ), // #212 {W:ymm|m256|mem, R:zmm, R:u8}
+    3348             :   ISIGNATURE(4, 1, 1, 0, 89 , 73 , 77 , 87 , 0  , 0  ), // #213 {X:xmm, R:xmm, R:xmm|m128|mem, R:u8}
+    3349             :   ISIGNATURE(4, 1, 1, 0, 91 , 82 , 80 , 87 , 0  , 0  ), //      {X:ymm, R:ymm, R:ymm|m256|mem, R:u8}
+    3350             :   ISIGNATURE(4, 1, 1, 0, 93 , 86 , 84 , 87 , 0  , 0  ), //      {X:zmm, R:zmm, R:zmm|m512|mem, R:u8}
+    3351             :   ISIGNATURE(3, 1, 1, 0, 89 , 73 , 77 , 0  , 0  , 0  ), // #216 {X:xmm, R:xmm, R:xmm|m128|mem}
+    3352             :   ISIGNATURE(3, 1, 1, 0, 91 , 82 , 80 , 0  , 0  , 0  ), //      {X:ymm, R:ymm, R:ymm|m256|mem}
+    3353             :   ISIGNATURE(3, 1, 1, 0, 93 , 86 , 84 , 0  , 0  , 0  ), //      {X:zmm, R:zmm, R:zmm|m512|mem}
+    3354             :   ISIGNATURE(3, 1, 1, 0, 74 , 77 , 87 , 0  , 0  , 0  ), // #219 {W:xmm, R:xmm|m128|mem, R:u8}
+    3355             :   ISIGNATURE(3, 1, 1, 0, 79 , 80 , 87 , 0  , 0  , 0  ), //      {W:ymm, R:ymm|m256|mem, R:u8}
+    3356             :   ISIGNATURE(3, 1, 1, 0, 83 , 84 , 87 , 0  , 0  , 0  ), //      {W:zmm, R:zmm|m512|mem, R:u8}
+    3357             :   ISIGNATURE(2, 1, 1, 0, 74 , 75 , 0  , 0  , 0  , 0  ), // #222 {W:xmm, R:xmm|m64|mem}
+    3358             :   ISIGNATURE(2, 1, 1, 0, 79 , 80 , 0  , 0  , 0  , 0  ), //      {W:ymm, R:ymm|m256|mem}
+    3359             :   ISIGNATURE(2, 1, 1, 0, 83 , 84 , 0  , 0  , 0  , 0  ), //      {W:zmm, R:zmm|m512|mem}
+    3360             :   ISIGNATURE(2, 1, 1, 0, 115, 73 , 0  , 0  , 0  , 0  ), // #225 {W:m128|mem, R:xmm}
+    3361             :   ISIGNATURE(2, 1, 1, 0, 116, 82 , 0  , 0  , 0  , 0  ), //      {W:m256|mem, R:ymm}
+    3362             :   ISIGNATURE(2, 1, 1, 0, 135, 86 , 0  , 0  , 0  , 0  ), //      {W:m512|mem, R:zmm}
+    3363             :   ISIGNATURE(2, 1, 1, 0, 74 , 117, 0  , 0  , 0  , 0  ), // #228 {W:xmm, R:m128|mem}
+    3364             :   ISIGNATURE(2, 1, 1, 0, 79 , 118, 0  , 0  , 0  , 0  ), //      {W:ymm, R:m256|mem}
+    3365             :   ISIGNATURE(2, 1, 1, 0, 83 , 136, 0  , 0  , 0  , 0  ), //      {W:zmm, R:m512|mem}
+    3366             :   ISIGNATURE(2, 0, 1, 0, 7  , 73 , 0  , 0  , 0  , 0  ), // #231 {W:r64|m64|mem, R:xmm}
+    3367             :   ISIGNATURE(2, 1, 1, 0, 74 , 137, 0  , 0  , 0  , 0  ), //      {W:xmm, R:xmm|m64|mem|r64}
+    3368             :   ISIGNATURE(2, 1, 1, 0, 76 , 73 , 0  , 0  , 0  , 0  ), //      {W:xmm|m64|mem, R:xmm}
+    3369             :   ISIGNATURE(2, 1, 1, 0, 68 , 73 , 0  , 0  , 0  , 0  ), // #234 {W:m64|mem, R:xmm}
+    3370             :   ISIGNATURE(2, 1, 1, 0, 74 , 65 , 0  , 0  , 0  , 0  ), //      {W:xmm, R:m64|mem}
+    3371             :   ISIGNATURE(3, 1, 1, 0, 74 , 73 , 73 , 0  , 0  , 0  ), // #236 {W:xmm, R:xmm, R:xmm}
+    3372             :   ISIGNATURE(2, 1, 1, 0, 67 , 73 , 0  , 0  , 0  , 0  ), // #237 {W:m32|mem, R:xmm}
+    3373             :   ISIGNATURE(2, 1, 1, 0, 74 , 64 , 0  , 0  , 0  , 0  ), //      {W:xmm, R:m32|mem}
+    3374             :   ISIGNATURE(3, 1, 1, 0, 74 , 73 , 73 , 0  , 0  , 0  ), //      {W:xmm, R:xmm, R:xmm}
+    3375             :   ISIGNATURE(4, 1, 1, 0, 131, 73 , 77 , 87 , 0  , 0  ), // #240 {W:k, R:xmm, R:xmm|m128|mem, R:u8}
+    3376             :   ISIGNATURE(4, 1, 1, 0, 131, 82 , 80 , 87 , 0  , 0  ), //      {W:k, R:ymm, R:ymm|m256|mem, R:u8}
+    3377             :   ISIGNATURE(4, 1, 1, 0, 131, 86 , 84 , 87 , 0  , 0  ), //      {W:k, R:zmm, R:zmm|m512|mem, R:u8}
+    3378             :   ISIGNATURE(3, 1, 1, 0, 129, 73 , 77 , 0  , 0  , 0  ), // #243 {W:xmm|k, R:xmm, R:xmm|m128|mem}
+    3379             :   ISIGNATURE(3, 1, 1, 0, 130, 82 , 80 , 0  , 0  , 0  ), //      {W:ymm|k, R:ymm, R:ymm|m256|mem}
+    3380             :   ISIGNATURE(3, 1, 1, 0, 131, 86 , 84 , 0  , 0  , 0  ), //      {W:k, R:zmm, R:zmm|m512|mem}
+    3381             :   ISIGNATURE(2, 1, 1, 0, 138, 73 , 0  , 0  , 0  , 0  ), // #246 {W:xmm|m32|mem, R:xmm}
+    3382             :   ISIGNATURE(2, 1, 1, 0, 76 , 82 , 0  , 0  , 0  , 0  ), //      {W:xmm|m64|mem, R:ymm}
+    3383             :   ISIGNATURE(2, 1, 1, 0, 78 , 86 , 0  , 0  , 0  , 0  ), //      {W:xmm|m128|mem, R:zmm}
+    3384             :   ISIGNATURE(2, 1, 1, 0, 76 , 73 , 0  , 0  , 0  , 0  ), // #249 {W:xmm|m64|mem, R:xmm}
+    3385             :   ISIGNATURE(2, 1, 1, 0, 78 , 82 , 0  , 0  , 0  , 0  ), //      {W:xmm|m128|mem, R:ymm}
+    3386             :   ISIGNATURE(2, 1, 1, 0, 81 , 86 , 0  , 0  , 0  , 0  ), //      {W:ymm|m256|mem, R:zmm}
+    3387             :   ISIGNATURE(2, 1, 1, 0, 139, 73 , 0  , 0  , 0  , 0  ), // #252 {W:xmm|m16|mem, R:xmm}
+    3388             :   ISIGNATURE(2, 1, 1, 0, 138, 82 , 0  , 0  , 0  , 0  ), //      {W:xmm|m32|mem, R:ymm}
+    3389             :   ISIGNATURE(2, 1, 1, 0, 76 , 86 , 0  , 0  , 0  , 0  ), //      {W:xmm|m64|mem, R:zmm}
+    3390             :   ISIGNATURE(2, 1, 1, 0, 74 , 140, 0  , 0  , 0  , 0  ), // #255 {W:xmm, R:xmm|m32|mem}
+    3391             :   ISIGNATURE(2, 1, 1, 0, 79 , 75 , 0  , 0  , 0  , 0  ), //      {W:ymm, R:xmm|m64|mem}
+    3392             :   ISIGNATURE(2, 1, 1, 0, 83 , 77 , 0  , 0  , 0  , 0  ), //      {W:zmm, R:xmm|m128|mem}
+    3393             :   ISIGNATURE(2, 1, 1, 0, 74 , 141, 0  , 0  , 0  , 0  ), // #258 {W:xmm, R:xmm|m16|mem}
+    3394             :   ISIGNATURE(2, 1, 1, 0, 79 , 140, 0  , 0  , 0  , 0  ), //      {W:ymm, R:xmm|m32|mem}
+    3395             :   ISIGNATURE(2, 1, 1, 0, 83 , 75 , 0  , 0  , 0  , 0  ), // #260 {W:zmm, R:xmm|m64|mem}
+    3396             :   ISIGNATURE(2, 1, 1, 0, 74 , 75 , 0  , 0  , 0  , 0  ), // #261 {W:xmm, R:xmm|m64|mem}
+    3397             :   ISIGNATURE(2, 1, 1, 0, 79 , 77 , 0  , 0  , 0  , 0  ), //      {W:ymm, R:xmm|m128|mem}
+    3398             :   ISIGNATURE(2, 1, 1, 0, 83 , 142, 0  , 0  , 0  , 0  ), //      {W:zmm, R:xmm|m256|mem}
+    3399             :   ISIGNATURE(2, 1, 1, 0, 143, 73 , 0  , 0  , 0  , 0  ), // #264 {W:vm32x, R:xmm}
+    3400             :   ISIGNATURE(2, 1, 1, 0, 144, 82 , 0  , 0  , 0  , 0  ), //      {W:vm32y, R:ymm}
+    3401             :   ISIGNATURE(2, 1, 1, 0, 145, 86 , 0  , 0  , 0  , 0  ), //      {W:vm32z, R:zmm}
+    3402             :   ISIGNATURE(2, 1, 1, 0, 146, 73 , 0  , 0  , 0  , 0  ), // #267 {W:vm64x, R:xmm}
+    3403             :   ISIGNATURE(2, 1, 1, 0, 147, 82 , 0  , 0  , 0  , 0  ), //      {W:vm64y, R:ymm}
+    3404             :   ISIGNATURE(2, 1, 1, 0, 148, 86 , 0  , 0  , 0  , 0  ), //      {W:vm64z, R:zmm}
+    3405             :   ISIGNATURE(3, 1, 1, 0, 131, 73 , 77 , 0  , 0  , 0  ), // #270 {W:k, R:xmm, R:xmm|m128|mem}
+    3406             :   ISIGNATURE(3, 1, 1, 0, 131, 82 , 80 , 0  , 0  , 0  ), //      {W:k, R:ymm, R:ymm|m256|mem}
+    3407             :   ISIGNATURE(3, 1, 1, 0, 131, 86 , 84 , 0  , 0  , 0  ), //      {W:k, R:zmm, R:zmm|m512|mem}
+    3408             :   ISIGNATURE(3, 1, 1, 0, 13 , 6  , 43 , 0  , 0  , 0  ), // #273 {W:r32, R:r32, R:r32|m32|mem}
+    3409             :   ISIGNATURE(3, 0, 1, 0, 19 , 27 , 16 , 0  , 0  , 0  ), //      {W:r64, R:r64, R:r64|m64|mem}
+    3410             :   ISIGNATURE(3, 1, 1, 0, 13 , 43 , 6  , 0  , 0  , 0  ), // #275 {W:r32, R:r32|m32|mem, R:r32}
+    3411             :   ISIGNATURE(3, 0, 1, 0, 19 , 16 , 27 , 0  , 0  , 0  ), //      {W:r64, R:r64|m64|mem, R:r64}
+    3412             :   ISIGNATURE(2, 1, 0, 0, 149, 43 , 0  , 0  , 0  , 0  ), // #277 {R:bnd, R:r32|m32|mem}
+    3413             :   ISIGNATURE(2, 0, 1, 0, 149, 16 , 0  , 0  , 0  , 0  ), //      {R:bnd, R:r64|m64|mem}
+    3414             :   ISIGNATURE(2, 1, 1, 0, 150, 151, 0  , 0  , 0  , 0  ), // #279 {W:bnd, R:bnd|mem}
+    3415             :   ISIGNATURE(2, 1, 1, 0, 152, 149, 0  , 0  , 0  , 0  ), //      {W:bnd|mem, R:bnd}
+    3416             :   ISIGNATURE(2, 1, 0, 0, 37 , 64 , 0  , 0  , 0  , 0  ), // #281 {R:r16, R:m32|mem}
+    3417             :   ISIGNATURE(2, 1, 0, 0, 6  , 65 , 0  , 0  , 0  , 0  ), //      {R:r32, R:m64|mem}
+    3418             :   ISIGNATURE(1, 1, 1, 0, 153, 0  , 0  , 0  , 0  , 0  ), // #283 {R:rel32|r64|m64|mem}
+    3419             :   ISIGNATURE(1, 1, 0, 0, 43 , 0  , 0  , 0  , 0  , 0  ), //      {R:r32|m32|mem}
+    3420             :   ISIGNATURE(2, 1, 1, 0, 42 , 154, 0  , 0  , 0  , 0  ), // #285 {X:r32, R:r8lo|r8hi|m8|r16|m16|r32|m32}
+    3421             :   ISIGNATURE(2, 0, 1, 0, 44 , 155, 0  , 0  , 0  , 0  ), //      {X:r64, R:r8lo|r8hi|m8|r64|m64}
+    3422             :   ISIGNATURE(1, 1, 0, 0, 156, 0  , 0  , 0  , 0  , 0  ), // #287 {X:r16|r32}
+    3423             :   ISIGNATURE(1, 1, 1, 0, 49 , 0  , 0  , 0  , 0  , 0  ), // #288 {X:r8lo|r8hi|m8|r16|m16|r32|m32|r64|m64|mem}
+    3424             :   ISIGNATURE(3, 1, 1, 0, 89 , 87 , 87 , 0  , 0  , 0  ), // #289 {X:xmm, R:u8, R:u8}
+    3425             :   ISIGNATURE(2, 1, 1, 0, 89 , 73 , 0  , 0  , 0  , 0  ), //      {X:xmm, R:xmm}
+    3426             :   ISIGNATURE(0, 1, 1, 0, 0  , 0  , 0  , 0  , 0  , 0  ), // #291 {}
+    3427             :   ISIGNATURE(1, 1, 1, 0, 123, 0  , 0  , 0  , 0  , 0  ), // #292 {X:fp}
+    3428             :   ISIGNATURE(0, 1, 1, 0, 0  , 0  , 0  , 0  , 0  , 0  ), // #293 {}
+    3429             :   ISIGNATURE(1, 1, 1, 0, 157, 0  , 0  , 0  , 0  , 0  ), //      {R:m32|m64|fp}
+    3430             :   ISIGNATURE(0, 1, 1, 0, 0  , 0  , 0  , 0  , 0  , 0  ), // #295 {}
+    3431             :   ISIGNATURE(1, 1, 1, 0, 122, 0  , 0  , 0  , 0  , 0  ), // #296 {R:fp}
+    3432             :   ISIGNATURE(2, 1, 1, 0, 89 , 73 , 0  , 0  , 0  , 0  ), // #297 {X:xmm, R:xmm}
+    3433             :   ISIGNATURE(4, 1, 1, 0, 89 , 73 , 87 , 87 , 0  , 0  ), //      {X:xmm, R:xmm, R:u8, R:u8}
+    3434             :   ISIGNATURE(2, 1, 0, 0, 6  , 117, 0  , 0  , 0  , 0  ), // #299 {R:r32, R:m128|mem}
+    3435             :   ISIGNATURE(2, 0, 1, 0, 27 , 117, 0  , 0  , 0  , 0  ), //      {R:r64, R:m128|mem}
+    3436             :   ISIGNATURE(2, 1, 0, 1, 158, 159, 0  , 0  , 0  , 0  ), // #301 {R:<cx|ecx>, R:rel8}
+    3437             :   ISIGNATURE(2, 0, 1, 1, 160, 159, 0  , 0  , 0  , 0  ), //      {R:<ecx|rcx>, R:rel8}
+    3438             :   ISIGNATURE(1, 1, 1, 0, 161, 0  , 0  , 0  , 0  , 0  ), // #303 {R:rel8|rel32|r64|m64|mem}
+    3439             :   ISIGNATURE(1, 1, 0, 0, 43 , 0  , 0  , 0  , 0  , 0  ), //      {R:r32|m32|mem}
+    3440             :   ISIGNATURE(2, 1, 1, 0, 131, 162, 0  , 0  , 0  , 0  ), // #305 {W:k, R:k|m8|mem|r32|r64|r8lo|r8hi|r16}
+    3441             :   ISIGNATURE(2, 1, 1, 0, 163, 164, 0  , 0  , 0  , 0  ), //      {W:m8|mem|r32|r64|r8lo|r8hi|r16, R:k}
+    3442             :   ISIGNATURE(2, 1, 1, 0, 131, 165, 0  , 0  , 0  , 0  ), // #307 {W:k, R:k|m32|mem|r32|r64}
+    3443             :   ISIGNATURE(2, 1, 1, 0, 166, 164, 0  , 0  , 0  , 0  ), //      {W:m32|mem|r32|r64, R:k}
+    3444             :   ISIGNATURE(2, 1, 1, 0, 131, 167, 0  , 0  , 0  , 0  ), // #309 {W:k, R:k|m64|mem|r64}
+    3445             :   ISIGNATURE(2, 1, 1, 0, 7  , 164, 0  , 0  , 0  , 0  ), //      {W:m64|mem|r64, R:k}
+    3446             :   ISIGNATURE(2, 1, 1, 0, 131, 168, 0  , 0  , 0  , 0  ), // #311 {W:k, R:k|m16|mem|r32|r64|r16}
+    3447             :   ISIGNATURE(2, 1, 1, 0, 169, 164, 0  , 0  , 0  , 0  ), //      {W:m16|mem|r32|r64|r16, R:k}
+    3448             :   ISIGNATURE(2, 1, 1, 0, 59 , 12 , 0  , 0  , 0  , 0  ), // #313 {W:r16, R:r16|m16|mem}
+    3449             :   ISIGNATURE(2, 1, 1, 0, 13 , 170, 0  , 0  , 0  , 0  ), //      {W:r32, R:r32|m16|mem|r16}
+    3450             :   ISIGNATURE(2, 1, 0, 0, 41 , 64 , 0  , 0  , 0  , 0  ), // #315 {X:r16, R:m32|mem}
+    3451             :   ISIGNATURE(2, 1, 0, 0, 42 , 126, 0  , 0  , 0  , 0  ), //      {X:r32, R:m48|mem}
+    3452             :   ISIGNATURE(2, 1, 0, 1, 171, 159, 0  , 0  , 0  , 0  ), // #317 {X:<cx|ecx>, R:rel8}
+    3453             :   ISIGNATURE(2, 0, 1, 1, 172, 159, 0  , 0  , 0  , 0  ), //      {X:<ecx|rcx>, R:rel8}
+    3454             :   ISIGNATURE(2, 1, 1, 0, 59 , 12 , 0  , 0  , 0  , 0  ), // #319 {W:r16, R:r16|m16|mem}
+    3455             :   ISIGNATURE(2, 1, 1, 0, 173, 170, 0  , 0  , 0  , 0  ), //      {W:r32|r64, R:r32|m16|mem|r16}
+    3456             :   ISIGNATURE(2, 1, 1, 0, 174, 175, 0  , 0  , 0  , 0  ), // #321 {W:mm|xmm, R:r32|m32|mem|r64}
+    3457             :   ISIGNATURE(2, 1, 1, 0, 166, 176, 0  , 0  , 0  , 0  ), //      {W:r32|m32|mem|r64, R:mm|xmm}
+    3458             :   ISIGNATURE(2, 1, 1, 0, 74 , 75 , 0  , 0  , 0  , 0  ), // #323 {W:xmm, R:xmm|m64|mem}
+    3459             :   ISIGNATURE(2, 1, 1, 0, 68 , 73 , 0  , 0  , 0  , 0  ), //      {W:m64|mem, R:xmm}
+    3460             :   ISIGNATURE(2, 1, 1, 0, 74 , 140, 0  , 0  , 0  , 0  ), // #325 {W:xmm, R:xmm|m32|mem}
+    3461             :   ISIGNATURE(2, 1, 1, 0, 67 , 73 , 0  , 0  , 0  , 0  ), //      {W:m32|mem, R:xmm}
+    3462             :   ISIGNATURE(2, 1, 1, 0, 177, 45 , 0  , 0  , 0  , 0  ), // #327 {W:r16|r32|r64, R:r8lo|r8hi|m8}
+    3463             :   ISIGNATURE(2, 1, 1, 0, 173, 46 , 0  , 0  , 0  , 0  ), //      {W:r32|r64, R:r16|m16}
+    3464             :   ISIGNATURE(4, 1, 1, 1, 13 , 13 , 43 , 178, 0  , 0  ), // #329 {W:r32, W:r32, R:r32|m32|mem, R:<edx>}
+    3465             :   ISIGNATURE(4, 0, 1, 1, 19 , 19 , 16 , 179, 0  , 0  ), //      {W:r64, W:r64, R:r64|m64|mem, R:<rdx>}
+    3466             :   ISIGNATURE(0, 1, 1, 0, 0  , 0  , 0  , 0  , 0  , 0  ), // #331 {}
+    3467             :   ISIGNATURE(1, 1, 1, 0, 99 , 0  , 0  , 0  , 0  , 0  ), //      {R:r16|m16|r32|m32}
+    3468             :   ISIGNATURE(2, 1, 1, 0, 69 , 180, 0  , 0  , 0  , 0  ), // #333 {W:mm, R:mm|m64|mem}
+    3469             :   ISIGNATURE(2, 1, 1, 0, 74 , 77 , 0  , 0  , 0  , 0  ), //      {W:xmm, R:xmm|m128|mem}
+    3470             :   ISIGNATURE(2, 1, 1, 0, 181, 180, 0  , 0  , 0  , 0  ), // #335 {X:mm, R:mm|m64|mem}
+    3471             :   ISIGNATURE(2, 1, 1, 0, 89 , 77 , 0  , 0  , 0  , 0  ), // #336 {X:xmm, R:xmm|m128|mem}
+    3472             :   ISIGNATURE(3, 1, 1, 0, 181, 180, 87 , 0  , 0  , 0  ), // #337 {X:mm, R:mm|m64|mem, R:u8}
+    3473             :   ISIGNATURE(3, 1, 1, 0, 89 , 77 , 87 , 0  , 0  , 0  ), // #338 {X:xmm, R:xmm|m128|mem, R:u8}
+    3474             :   ISIGNATURE(3, 1, 1, 0, 173, 72 , 87 , 0  , 0  , 0  ), // #339 {W:r32|r64, R:mm, R:u8}
+    3475             :   ISIGNATURE(3, 1, 1, 0, 169, 73 , 87 , 0  , 0  , 0  ), // #340 {W:r32|r64|m16|mem|r16, R:xmm, R:u8}
+    3476             :   ISIGNATURE(2, 1, 1, 0, 181, 182, 0  , 0  , 0  , 0  ), // #341 {X:mm, R:u8|mm|m64|mem}
+    3477             :   ISIGNATURE(2, 1, 1, 0, 89 , 88 , 0  , 0  , 0  , 0  ), //      {X:xmm, R:u8|xmm|m128|mem}
+    3478             :   ISIGNATURE(0, 1, 1, 0, 0  , 0  , 0  , 0  , 0  , 0  ), // #343 {}
+    3479             :   ISIGNATURE(1, 1, 1, 0, 183, 0  , 0  , 0  , 0  , 0  ), //      {R:u16}
+    3480             :   ISIGNATURE(3, 1, 1, 0, 13 , 43 , 87 , 0  , 0  , 0  ), // #345 {W:r32, R:r32|m32|mem, R:u8}
+    3481             :   ISIGNATURE(3, 0, 1, 0, 19 , 16 , 87 , 0  , 0  , 0  ), //      {W:r64, R:r64|m64|mem, R:u8}
+    3482             :   ISIGNATURE(4, 1, 1, 0, 74 , 73 , 77 , 73 , 0  , 0  ), // #347 {W:xmm, R:xmm, R:xmm|m128|mem, R:xmm}
+    3483             :   ISIGNATURE(4, 1, 1, 0, 79 , 82 , 80 , 82 , 0  , 0  ), //      {W:ymm, R:ymm, R:ymm|m256|mem, R:ymm}
+    3484             :   ISIGNATURE(2, 1, 1, 0, 74 , 184, 0  , 0  , 0  , 0  ), // #349 {W:xmm, R:xmm|m128|ymm|m256}
+    3485             :   ISIGNATURE(2, 1, 1, 0, 79 , 84 , 0  , 0  , 0  , 0  ), //      {W:ymm, R:zmm|m512|mem}
+    3486             :   ISIGNATURE(4, 1, 1, 0, 74 , 73 , 73 , 75 , 0  , 0  ), // #351 {W:xmm, R:xmm, R:xmm, R:xmm|m64|mem}
+    3487             :   ISIGNATURE(4, 1, 1, 0, 74 , 73 , 75 , 73 , 0  , 0  ), //      {W:xmm, R:xmm, R:xmm|m64|mem, R:xmm}
+    3488             :   ISIGNATURE(4, 1, 1, 0, 74 , 73 , 73 , 140, 0  , 0  ), // #353 {W:xmm, R:xmm, R:xmm, R:xmm|m32|mem}
+    3489             :   ISIGNATURE(4, 1, 1, 0, 74 , 73 , 140, 73 , 0  , 0  ), //      {W:xmm, R:xmm, R:xmm|m32|mem, R:xmm}
+    3490             :   ISIGNATURE(4, 1, 1, 0, 79 , 82 , 77 , 87 , 0  , 0  ), // #355 {W:ymm, R:ymm, R:xmm|m128|mem, R:u8}
+    3491             :   ISIGNATURE(4, 1, 1, 0, 83 , 86 , 77 , 87 , 0  , 0  ), //      {W:zmm, R:zmm, R:xmm|m128|mem, R:u8}
+    3492             :   ISIGNATURE(2, 1, 1, 0, 166, 73 , 0  , 0  , 0  , 0  ), // #357 {W:r32|m32|mem|r64, R:xmm}
+    3493             :   ISIGNATURE(2, 1, 1, 0, 74 , 175, 0  , 0  , 0  , 0  ), //      {W:xmm, R:r32|m32|mem|r64}
+    3494             :   ISIGNATURE(2, 1, 1, 0, 68 , 73 , 0  , 0  , 0  , 0  ), // #359 {W:m64|mem, R:xmm}
+    3495             :   ISIGNATURE(3, 1, 1, 0, 74 , 73 , 65 , 0  , 0  , 0  ), //      {W:xmm, R:xmm, R:m64|mem}
+    3496             :   ISIGNATURE(2, 1, 1, 0, 185, 186, 0  , 0  , 0  , 0  ), // #361 {W:xmm|ymm|zmm, R:xmm|m8|mem}
+    3497             :   ISIGNATURE(2, 1, 1, 0, 185, 187, 0  , 0  , 0  , 0  ), //      {W:xmm|ymm|zmm, R:r32|r64}
+    3498             :   ISIGNATURE(2, 1, 1, 0, 185, 140, 0  , 0  , 0  , 0  ), // #363 {W:xmm|ymm|zmm, R:xmm|m32|mem}
+    3499             :   ISIGNATURE(2, 1, 1, 0, 185, 187, 0  , 0  , 0  , 0  ), //      {W:xmm|ymm|zmm, R:r32|r64}
+    3500             :   ISIGNATURE(2, 1, 1, 0, 185, 141, 0  , 0  , 0  , 0  ), // #365 {W:xmm|ymm|zmm, R:xmm|m16|mem}
+    3501             :   ISIGNATURE(2, 1, 1, 0, 185, 187, 0  , 0  , 0  , 0  ), //      {W:xmm|ymm|zmm, R:r32|r64}
+    3502             :   ISIGNATURE(3, 1, 1, 0, 74 , 188, 87 , 0  , 0  , 0  ), // #367 {W:xmm, R:r32|m8|mem|r8lo|r8hi|r16|r64, R:u8}
+    3503             :   ISIGNATURE(4, 1, 1, 0, 74 , 73 , 188, 87 , 0  , 0  ), //      {W:xmm, R:xmm, R:r32|m8|mem|r8lo|r8hi|r16|r64, R:u8}
+    3504             :   ISIGNATURE(3, 1, 1, 0, 74 , 175, 87 , 0  , 0  , 0  ), // #369 {W:xmm, R:r32|m32|mem|r64, R:u8}
+    3505             :   ISIGNATURE(4, 1, 1, 0, 74 , 73 , 175, 87 , 0  , 0  ), //      {W:xmm, R:xmm, R:r32|m32|mem|r64, R:u8}
+    3506             :   ISIGNATURE(3, 0, 1, 0, 74 , 16 , 87 , 0  , 0  , 0  ), // #371 {W:xmm, R:r64|m64|mem, R:u8}
+    3507             :   ISIGNATURE(4, 0, 1, 0, 74 , 73 , 16 , 87 , 0  , 0  ), //      {W:xmm, R:xmm, R:r64|m64|mem, R:u8}
+    3508             :   ISIGNATURE(3, 1, 1, 0, 74 , 73 , 77 , 0  , 0  , 0  ), // #373 {W:xmm, R:xmm, R:xmm|m128|mem}
+    3509             :   ISIGNATURE(3, 1, 1, 0, 74 , 77 , 189, 0  , 0  , 0  ), //      {W:xmm, R:xmm|m128|mem, R:u8|xmm}
+    3510             :   ISIGNATURE(2, 1, 1, 0, 190, 73 , 0  , 0  , 0  , 0  ), // #375 {W:vm64x|vm64y, R:xmm}
+    3511             :   ISIGNATURE(2, 1, 1, 0, 148, 82 , 0  , 0  , 0  , 0  ), //      {W:vm64z, R:ymm}
+    3512             :   ISIGNATURE(3, 1, 1, 0, 74 , 73 , 77 , 0  , 0  , 0  ), // #377 {W:xmm, R:xmm, R:xmm|m128|mem}
+    3513             :   ISIGNATURE(3, 1, 1, 0, 74 , 77 , 73 , 0  , 0  , 0  ), //      {W:xmm, R:xmm|m128|mem, R:xmm}
+    3514             :   ISIGNATURE(2, 1, 1, 0, 73 , 77 , 0  , 0  , 0  , 0  ), // #379 {R:xmm, R:xmm|m128|mem}
+    3515             :   ISIGNATURE(2, 1, 1, 0, 82 , 80 , 0  , 0  , 0  , 0  ), //      {R:ymm, R:ymm|m256|mem}
+    3516             :   ISIGNATURE(2, 1, 1, 0, 143, 191, 0  , 0  , 0  , 0  ), // #381 {W:vm32x, R:xmm|ymm}
+    3517             :   ISIGNATURE(2, 1, 1, 0, 144, 86 , 0  , 0  , 0  , 0  ), //      {W:vm32y, R:zmm}
+    3518             :   ISIGNATURE(1, 1, 0, 1, 50 , 0  , 0  , 0  , 0  , 0  ), // #383 {X:<ax>}
+    3519             :   ISIGNATURE(2, 1, 0, 1, 50 , 87 , 0  , 0  , 0  , 0  ), // #384 {X:<ax>, R:u8}
+    3520             :   ISIGNATURE(2, 1, 1, 0, 89 , 75 , 0  , 0  , 0  , 0  ), // #385 {X:xmm, R:xmm|m64|mem}
+    3521             :   ISIGNATURE(2, 1, 1, 0, 89 , 140, 0  , 0  , 0  , 0  ), // #386 {X:xmm, R:xmm|m32|mem}
+    3522             :   ISIGNATURE(2, 1, 0, 0, 36 , 37 , 0  , 0  , 0  , 0  ), // #387 {X:r16|m16|mem, R:r16}
+    3523             :   ISIGNATURE(3, 1, 1, 1, 89 , 77 , 192, 0  , 0  , 0  ), // #388 {X:xmm, R:xmm|m128|mem, R:<xmm0>}
+    3524             :   ISIGNATURE(2, 1, 1, 0, 150, 193, 0  , 0  , 0  , 0  ), // #389 {W:bnd, R:mib}
+    3525             :   ISIGNATURE(2, 1, 1, 0, 150, 194, 0  , 0  , 0  , 0  ), // #390 {W:bnd, R:mem}
+    3526             :   ISIGNATURE(2, 1, 1, 0, 195, 149, 0  , 0  , 0  , 0  ), // #391 {W:mib, R:bnd}
+    3527             :   ISIGNATURE(1, 1, 1, 0, 196, 0  , 0  , 0  , 0  , 0  ), // #392 {X:r32|r64}
+    3528             :   ISIGNATURE(1, 1, 1, 1, 50 , 0  , 0  , 0  , 0  , 0  ), // #393 {X:<ax>}
+    3529             :   ISIGNATURE(2, 1, 1, 2, 52 , 103, 0  , 0  , 0  , 0  ), // #394 {W:<edx>, R:<eax>}
+    3530             :   ISIGNATURE(1, 0, 1, 1, 55 , 0  , 0  , 0  , 0  , 0  ), // #395 {X:<rax>}
+    3531             :   ISIGNATURE(1, 1, 1, 0, 194, 0  , 0  , 0  , 0  , 0  ), // #396 {R:mem}
+    3532             :   ISIGNATURE(1, 1, 1, 1, 197, 0  , 0  , 0  , 0  , 0  ), // #397 {R:<ds:[zax]>}
+    3533             :   ISIGNATURE(2, 1, 1, 2, 198, 199, 0  , 0  , 0  , 0  ), // #398 {X:<ds:[zsi]>, X:<es:[zdi]>}
+    3534             :   ISIGNATURE(3, 1, 1, 0, 89 , 75 , 87 , 0  , 0  , 0  ), // #399 {X:xmm, R:xmm|m64|mem, R:u8}
+    3535             :   ISIGNATURE(3, 1, 1, 0, 89 , 140, 87 , 0  , 0  , 0  ), // #400 {X:xmm, R:xmm|m32|mem, R:u8}
+    3536             :   ISIGNATURE(5, 0, 1, 4, 200, 107, 55 , 201, 202, 0  ), // #401 {X:m128|mem, X:<rdx>, X:<rax>, R:<rcx>, R:<rbx>}
+    3537             :   ISIGNATURE(5, 1, 1, 4, 203, 106, 53 , 204, 205, 0  ), // #402 {X:m64|mem, X:<edx>, X:<eax>, R:<ecx>, R:<ebx>}
+    3538             :   ISIGNATURE(2, 1, 1, 0, 73 , 75 , 0  , 0  , 0  , 0  ), // #403 {R:xmm, R:xmm|m64|mem}
+    3539             :   ISIGNATURE(2, 1, 1, 0, 73 , 140, 0  , 0  , 0  , 0  ), // #404 {R:xmm, R:xmm|m32|mem}
+    3540             :   ISIGNATURE(4, 1, 1, 4, 53 , 206, 207, 52 , 0  , 0  ), // #405 {X:<eax>, W:<ebx>, X:<ecx>, W:<edx>}
+    3541             :   ISIGNATURE(2, 0, 1, 2, 54 , 104, 0  , 0  , 0  , 0  ), // #406 {W:<rdx>, R:<rax>}
+    3542             :   ISIGNATURE(2, 1, 1, 0, 69 , 77 , 0  , 0  , 0  , 0  ), // #407 {W:mm, R:xmm|m128|mem}
+    3543             :   ISIGNATURE(2, 1, 1, 0, 74 , 180, 0  , 0  , 0  , 0  ), // #408 {W:xmm, R:mm|m64|mem}
+    3544             :   ISIGNATURE(2, 1, 1, 0, 69 , 75 , 0  , 0  , 0  , 0  ), // #409 {W:mm, R:xmm|m64|mem}
+    3545             :   ISIGNATURE(2, 1, 1, 0, 173, 75 , 0  , 0  , 0  , 0  ), // #410 {W:r32|r64, R:xmm|m64|mem}
+    3546             :   ISIGNATURE(2, 1, 1, 0, 74 , 208, 0  , 0  , 0  , 0  ), // #411 {W:xmm, R:r32|m32|mem|r64|m64}
+    3547             :   ISIGNATURE(2, 1, 1, 0, 173, 140, 0  , 0  , 0  , 0  ), // #412 {W:r32|r64, R:xmm|m32|mem}
+    3548             :   ISIGNATURE(2, 1, 1, 2, 51 , 102, 0  , 0  , 0  , 0  ), // #413 {W:<dx>, R:<ax>}
+    3549             :   ISIGNATURE(1, 1, 1, 1, 53 , 0  , 0  , 0  , 0  , 0  ), // #414 {X:<eax>}
+    3550             :   ISIGNATURE(2, 1, 1, 0, 183, 87 , 0  , 0  , 0  , 0  ), // #415 {R:u16, R:u8}
+    3551             :   ISIGNATURE(3, 1, 1, 0, 166, 73 , 87 , 0  , 0  , 0  ), // #416 {W:r32|m32|mem|r64, R:xmm, R:u8}
+    3552             :   ISIGNATURE(1, 1, 1, 0, 127, 0  , 0  , 0  , 0  , 0  ), // #417 {R:m80|mem}
+    3553             :   ISIGNATURE(1, 1, 1, 0, 209, 0  , 0  , 0  , 0  , 0  ), // #418 {W:m80|mem}
+    3554             :   ISIGNATURE(1, 1, 1, 0, 210, 0  , 0  , 0  , 0  , 0  ), // #419 {R:m16|m32}
+    3555             :   ISIGNATURE(1, 1, 1, 0, 211, 0  , 0  , 0  , 0  , 0  ), // #420 {R:m16|m32|m64}
+    3556             :   ISIGNATURE(1, 1, 1, 0, 212, 0  , 0  , 0  , 0  , 0  ), // #421 {W:m16|m32}
+    3557             :   ISIGNATURE(1, 1, 1, 0, 213, 0  , 0  , 0  , 0  , 0  ), // #422 {W:m16|m32|m64}
+    3558             :   ISIGNATURE(1, 1, 1, 0, 214, 0  , 0  , 0  , 0  , 0  ), // #423 {R:m32|m64|m80|fp}
+    3559             :   ISIGNATURE(1, 1, 1, 0, 63 , 0  , 0  , 0  , 0  , 0  ), // #424 {R:m16|mem}
+    3560             :   ISIGNATURE(1, 1, 1, 0, 215, 0  , 0  , 0  , 0  , 0  ), // #425 {W:mem}
+    3561             :   ISIGNATURE(1, 1, 1, 0, 66 , 0  , 0  , 0  , 0  , 0  ), // #426 {W:m16|mem}
+    3562             :   ISIGNATURE(1, 1, 1, 0, 216, 0  , 0  , 0  , 0  , 0  ), // #427 {W:ax|m16|mem}
+    3563             :   ISIGNATURE(1, 1, 1, 0, 217, 0  , 0  , 0  , 0  , 0  ), // #428 {W:m32|m64|fp}
+    3564             :   ISIGNATURE(1, 1, 1, 0, 218, 0  , 0  , 0  , 0  , 0  ), // #429 {W:m32|m64|m80|fp}
+    3565             :   ISIGNATURE(1, 0, 1, 0, 194, 0  , 0  , 0  , 0  , 0  ), // #430 {R:mem}
+    3566             :   ISIGNATURE(1, 0, 1, 0, 215, 0  , 0  , 0  , 0  , 0  ), // #431 {W:mem}
+    3567             :   ISIGNATURE(2, 1, 1, 0, 219, 220, 0  , 0  , 0  , 0  ), // #432 {W:al|ax|eax, R:u8|dx}
+    3568             :   ISIGNATURE(2, 1, 1, 0, 221, 222, 0  , 0  , 0  , 0  ), // #433 {W:es:[zdi], R:dx}
+    3569             :   ISIGNATURE(1, 1, 1, 0, 87 , 0  , 0  , 0  , 0  , 0  ), // #434 {R:u8}
+    3570             :   ISIGNATURE(0, 1, 0, 0, 0  , 0  , 0  , 0  , 0  , 0  ), // #435 {}
+    3571             :   ISIGNATURE(0, 0, 1, 0, 0  , 0  , 0  , 0  , 0  , 0  ), // #436 {}
+    3572             :   ISIGNATURE(1, 1, 1, 0, 223, 0  , 0  , 0  , 0  , 0  ), // #437 {R:rel8|rel32}
+    3573             :   ISIGNATURE(1, 1, 1, 0, 159, 0  , 0  , 0  , 0  , 0  ), // #438 {R:rel8}
+    3574             :   ISIGNATURE(3, 1, 1, 0, 131, 164, 164, 0  , 0  , 0  ), // #439 {W:k, R:k, R:k}
+    3575             :   ISIGNATURE(2, 1, 1, 0, 131, 164, 0  , 0  , 0  , 0  ), // #440 {W:k, R:k}
+    3576             :   ISIGNATURE(2, 1, 1, 0, 164, 164, 0  , 0  , 0  , 0  ), // #441 {R:k, R:k}
+    3577             :   ISIGNATURE(3, 1, 1, 0, 131, 164, 87 , 0  , 0  , 0  ), // #442 {W:k, R:k, R:u8}
+    3578             :   ISIGNATURE(1, 1, 1, 1, 224, 0  , 0  , 0  , 0  , 0  ), // #443 {W:<ah>}
+    3579             :   ISIGNATURE(1, 1, 1, 0, 64 , 0  , 0  , 0  , 0  , 0  ), // #444 {R:m32|mem}
+    3580             :   ISIGNATURE(2, 1, 1, 0, 177, 225, 0  , 0  , 0  , 0  ), // #445 {W:r16|r32|r64, R:mem|m8|m16|m32|m48|m64|m80|m128|m256|m512|m1024}
+    3581             :   ISIGNATURE(1, 1, 1, 0, 226, 0  , 0  , 0  , 0  , 0  ), // #446 {R:r16|m16|mem|r32|r64}
+    3582             :   ISIGNATURE(2, 1, 1, 2, 227, 198, 0  , 0  , 0  , 0  ), // #447 {W:<al|ax|eax|rax>, X:<ds:[zsi]>}
+    3583             :   ISIGNATURE(3, 1, 1, 1, 89 , 73 , 228, 0  , 0  , 0  ), // #448 {X:xmm, R:xmm, R:<ds:[zdi]>}
+    3584             :   ISIGNATURE(3, 1, 1, 1, 181, 72 , 228, 0  , 0  , 0  ), // #449 {X:mm, R:mm, R:<ds:[zdi]>}
+    3585             :   ISIGNATURE(3, 1, 1, 3, 197, 204, 178, 0  , 0  , 0  ), // #450 {R:<ds:[zax]>, R:<ecx>, R:<edx>}
+    3586             :   ISIGNATURE(2, 1, 1, 0, 69 , 73 , 0  , 0  , 0  , 0  ), // #451 {W:mm, R:xmm}
+    3587             :   ISIGNATURE(2, 1, 1, 0, 74 , 73 , 0  , 0  , 0  , 0  ), // #452 {W:xmm, R:xmm}
+    3588             :   ISIGNATURE(2, 1, 1, 0, 173, 73 , 0  , 0  , 0  , 0  ), // #453 {W:r32|r64, R:xmm}
+    3589             :   ISIGNATURE(2, 1, 1, 0, 68 , 72 , 0  , 0  , 0  , 0  ), // #454 {W:m64|mem, R:mm}
+    3590             :   ISIGNATURE(2, 1, 1, 0, 74 , 72 , 0  , 0  , 0  , 0  ), // #455 {W:xmm, R:mm}
+    3591             :   ISIGNATURE(2, 1, 1, 2, 199, 198, 0  , 0  , 0  , 0  ), // #456 {X:<es:[zdi]>, X:<ds:[zsi]>}
+    3592             :   ISIGNATURE(2, 0, 1, 0, 19 , 43 , 0  , 0  , 0  , 0  ), // #457 {W:r64, R:r32|m32|mem}
+    3593             :   ISIGNATURE(2, 1, 1, 2, 103, 204, 0  , 0  , 0  , 0  ), // #458 {R:<eax>, R:<ecx>}
+    3594             :   ISIGNATURE(2, 1, 1, 0, 220, 229, 0  , 0  , 0  , 0  ), // #459 {R:u8|dx, R:al|ax|eax}
+    3595             :   ISIGNATURE(2, 1, 1, 0, 222, 230, 0  , 0  , 0  , 0  ), // #460 {R:dx, R:ds:[zsi]}
+    3596             :   ISIGNATURE(6, 1, 1, 3, 73 , 77 , 87 , 231, 103, 178), // #461 {R:xmm, R:xmm|m128|mem, R:u8, W:<ecx>, R:<eax>, R:<edx>}
+    3597             :   ISIGNATURE(6, 1, 1, 3, 73 , 77 , 87 , 232, 103, 178), // #462 {R:xmm, R:xmm|m128|mem, R:u8, W:<xmm0>, R:<eax>, R:<edx>}
+    3598             :   ISIGNATURE(4, 1, 1, 1, 73 , 77 , 87 , 231, 0  , 0  ), // #463 {R:xmm, R:xmm|m128|mem, R:u8, W:<ecx>}
+    3599             :   ISIGNATURE(4, 1, 1, 1, 73 , 77 , 87 , 232, 0  , 0  ), // #464 {R:xmm, R:xmm|m128|mem, R:u8, W:<xmm0>}
+    3600             :   ISIGNATURE(3, 1, 1, 0, 163, 73 , 87 , 0  , 0  , 0  ), // #465 {W:r32|m8|mem|r8lo|r8hi|r16|r64, R:xmm, R:u8}
+    3601             :   ISIGNATURE(3, 0, 1, 0, 7  , 73 , 87 , 0  , 0  , 0  ), // #466 {W:r64|m64|mem, R:xmm, R:u8}
+    3602             :   ISIGNATURE(3, 1, 1, 0, 89 , 188, 87 , 0  , 0  , 0  ), // #467 {X:xmm, R:r32|m8|mem|r8lo|r8hi|r16|r64, R:u8}
+    3603             :   ISIGNATURE(3, 1, 1, 0, 89 , 175, 87 , 0  , 0  , 0  ), // #468 {X:xmm, R:r32|m32|mem|r64, R:u8}
+    3604             :   ISIGNATURE(3, 0, 1, 0, 89 , 16 , 87 , 0  , 0  , 0  ), // #469 {X:xmm, R:r64|m64|mem, R:u8}
+    3605             :   ISIGNATURE(3, 1, 1, 0, 233, 226, 87 , 0  , 0  , 0  ), // #470 {X:mm|xmm, R:r32|m16|mem|r16|r64, R:u8}
+    3606             :   ISIGNATURE(2, 1, 1, 0, 173, 176, 0  , 0  , 0  , 0  ), // #471 {W:r32|r64, R:mm|xmm}
+    3607             :   ISIGNATURE(3, 1, 1, 0, 69 , 180, 87 , 0  , 0  , 0  ), // #472 {W:mm, R:mm|m64|mem, R:u8}
+    3608             :   ISIGNATURE(2, 1, 1, 0, 89 , 87 , 0  , 0  , 0  , 0  ), // #473 {X:xmm, R:u8}
+    3609             :   ISIGNATURE(2, 1, 1, 0, 49 , 128, 0  , 0  , 0  , 0  ), // #474 {X:r8lo|r8hi|m8|r16|m16|r32|m32|r64|m64|mem, R:cl|u8}
+    3610             :   ISIGNATURE(1, 0, 1, 0, 173, 0  , 0  , 0  , 0  , 0  ), // #475 {W:r32|r64}
+    3611             :   ISIGNATURE(3, 1, 1, 3, 52 , 234, 204, 0  , 0  , 0  ), // #476 {W:<edx>, W:<eax>, R:<ecx>}
+    3612             :   ISIGNATURE(1, 1, 1, 0, 177, 0  , 0  , 0  , 0  , 0  ), // #477 {W:r16|r32|r64}
+    3613             :   ISIGNATURE(2, 1, 1, 2, 52 , 234, 0  , 0  , 0  , 0  ), // #478 {W:<edx>, W:<eax>}
+    3614             :   ISIGNATURE(3, 1, 1, 3, 52 , 234, 231, 0  , 0  , 0  ), // #479 {W:<edx>, W:<eax>, W:<ecx>}
+    3615             :   ISIGNATURE(3, 1, 1, 0, 74 , 75 , 87 , 0  , 0  , 0  ), // #480 {W:xmm, R:xmm|m64|mem, R:u8}
+    3616             :   ISIGNATURE(3, 1, 1, 0, 74 , 140, 87 , 0  , 0  , 0  ), // #481 {W:xmm, R:xmm|m32|mem, R:u8}
+    3617             :   ISIGNATURE(1, 1, 1, 1, 235, 0  , 0  , 0  , 0  , 0  ), // #482 {R:<ah>}
+    3618             :   ISIGNATURE(2, 1, 1, 2, 236, 199, 0  , 0  , 0  , 0  ), // #483 {R:<al|ax|eax|rax>, X:<es:[zdi]>}
+    3619             :   ISIGNATURE(1, 1, 1, 0, 1  , 0  , 0  , 0  , 0  , 0  ), // #484 {W:r8lo|r8hi|m8|mem}
+    3620             :   ISIGNATURE(1, 1, 1, 0, 169, 0  , 0  , 0  , 0  , 0  ), // #485 {W:r16|m16|mem|r32|r64}
+    3621             :   ISIGNATURE(1, 1, 1, 0, 67 , 0  , 0  , 0  , 0  , 0  ), // #486 {W:m32|mem}
+    3622             :   ISIGNATURE(2, 1, 1, 2, 199, 236, 0  , 0  , 0  , 0  ), // #487 {X:<es:[zdi]>, R:<al|ax|eax|rax>}
+    3623             :   ISIGNATURE(6, 1, 1, 0, 93 , 86 , 86 , 86 , 86 , 117), // #488 {X:zmm, R:zmm, R:zmm, R:zmm, R:zmm, R:m128|mem}
+    3624             :   ISIGNATURE(3, 1, 1, 0, 74 , 73 , 75 , 0  , 0  , 0  ), // #489 {W:xmm, R:xmm, R:xmm|m64|mem}
+    3625             :   ISIGNATURE(3, 1, 1, 0, 74 , 73 , 140, 0  , 0  , 0  ), // #490 {W:xmm, R:xmm, R:xmm|m32|mem}
+    3626             :   ISIGNATURE(2, 1, 1, 0, 79 , 117, 0  , 0  , 0  , 0  ), // #491 {W:ymm, R:m128|mem}
+    3627             :   ISIGNATURE(2, 1, 1, 0, 237, 75 , 0  , 0  , 0  , 0  ), // #492 {W:ymm|zmm, R:xmm|m64|mem}
+    3628             :   ISIGNATURE(2, 1, 1, 0, 237, 117, 0  , 0  , 0  , 0  ), // #493 {W:ymm|zmm, R:m128|mem}
+    3629             :   ISIGNATURE(2, 1, 1, 0, 83 , 118, 0  , 0  , 0  , 0  ), // #494 {W:zmm, R:m256|mem}
+    3630             :   ISIGNATURE(2, 1, 1, 0, 185, 75 , 0  , 0  , 0  , 0  ), // #495 {W:xmm|ymm|zmm, R:xmm|m64|mem}
+    3631             :   ISIGNATURE(4, 1, 1, 0, 129, 73 , 75 , 87 , 0  , 0  ), // #496 {W:xmm|k, R:xmm, R:xmm|m64|mem, R:u8}
+    3632             :   ISIGNATURE(4, 1, 1, 0, 129, 73 , 140, 87 , 0  , 0  ), // #497 {W:xmm|k, R:xmm, R:xmm|m32|mem, R:u8}
+    3633             :   ISIGNATURE(3, 1, 1, 0, 74 , 73 , 208, 0  , 0  , 0  ), // #498 {W:xmm, R:xmm, R:r32|m32|mem|r64|m64}
+    3634             :   ISIGNATURE(3, 1, 1, 0, 78 , 238, 87 , 0  , 0  , 0  ), // #499 {W:xmm|m128|mem, R:ymm|zmm, R:u8}
+    3635             :   ISIGNATURE(4, 1, 1, 0, 89 , 73 , 75 , 87 , 0  , 0  ), // #500 {X:xmm, R:xmm, R:xmm|m64|mem, R:u8}
+    3636             :   ISIGNATURE(4, 1, 1, 0, 89 , 73 , 140, 87 , 0  , 0  ), // #501 {X:xmm, R:xmm, R:xmm|m32|mem, R:u8}
+    3637             :   ISIGNATURE(3, 1, 1, 0, 89 , 73 , 75 , 0  , 0  , 0  ), // #502 {X:xmm, R:xmm, R:xmm|m64|mem}
+    3638             :   ISIGNATURE(3, 1, 1, 0, 89 , 73 , 140, 0  , 0  , 0  ), // #503 {X:xmm, R:xmm, R:xmm|m32|mem}
+    3639             :   ISIGNATURE(3, 1, 1, 0, 131, 239, 87 , 0  , 0  , 0  ), // #504 {W:k, R:xmm|m128|ymm|m256|zmm|m512, R:u8}
+    3640             :   ISIGNATURE(3, 1, 1, 0, 131, 75 , 87 , 0  , 0  , 0  ), // #505 {W:k, R:xmm|m64|mem, R:u8}
+    3641             :   ISIGNATURE(3, 1, 1, 0, 131, 140, 87 , 0  , 0  , 0  ), // #506 {W:k, R:xmm|m32|mem, R:u8}
+    3642             :   ISIGNATURE(1, 1, 1, 0, 92 , 0  , 0  , 0  , 0  , 0  ), // #507 {R:vm32y}
+    3643             :   ISIGNATURE(1, 1, 1, 0, 94 , 0  , 0  , 0  , 0  , 0  ), // #508 {R:vm32z}
+    3644             :   ISIGNATURE(1, 1, 1, 0, 97 , 0  , 0  , 0  , 0  , 0  ), // #509 {R:vm64z}
+    3645             :   ISIGNATURE(4, 1, 1, 0, 83 , 86 , 80 , 87 , 0  , 0  ), // #510 {W:zmm, R:zmm, R:ymm|m256|mem, R:u8}
+    3646             :   ISIGNATURE(4, 1, 1, 0, 74 , 73 , 140, 87 , 0  , 0  ), // #511 {W:xmm, R:xmm, R:xmm|m32|mem, R:u8}
+    3647             :   ISIGNATURE(3, 1, 1, 1, 73 , 73 , 228, 0  , 0  , 0  ), // #512 {R:xmm, R:xmm, R:<ds:[zdi]>}
+    3648             :   ISIGNATURE(2, 1, 1, 0, 173, 191, 0  , 0  , 0  , 0  ), // #513 {W:r32|r64, R:xmm|ymm}
+    3649             :   ISIGNATURE(6, 1, 1, 0, 83 , 86 , 86 , 86 , 86 , 117), // #514 {W:zmm, R:zmm, R:zmm, R:zmm, R:zmm, R:m128|mem}
+    3650             :   ISIGNATURE(2, 1, 1, 0, 185, 164, 0  , 0  , 0  , 0  ), // #515 {W:xmm|ymm|zmm, R:k}
+    3651             :   ISIGNATURE(2, 1, 1, 0, 185, 137, 0  , 0  , 0  , 0  ), // #516 {W:xmm|ymm|zmm, R:xmm|m64|mem|r64}
+    3652             :   ISIGNATURE(4, 1, 1, 0, 74 , 73 , 226, 87 , 0  , 0  ), // #517 {W:xmm, R:xmm, R:r32|m16|mem|r16|r64, R:u8}
+    3653             :   ISIGNATURE(2, 1, 1, 0, 131, 240, 0  , 0  , 0  , 0  ), // #518 {W:k, R:xmm|ymm|zmm}
+    3654             :   ISIGNATURE(4, 1, 1, 0, 74 , 73 , 75 , 87 , 0  , 0  ), // #519 {W:xmm, R:xmm, R:xmm|m64|mem, R:u8}
+    3655             :   ISIGNATURE(1, 0, 1, 0, 187, 0  , 0  , 0  , 0  , 0  ), // #520 {R:r32|r64}
+    3656             :   ISIGNATURE(3, 1, 1, 3, 178, 103, 204, 0  , 0  , 0  ), // #521 {R:<edx>, R:<eax>, R:<ecx>}
+    3657             :   ISIGNATURE(1, 1, 1, 0, 241, 0  , 0  , 0  , 0  , 0  ), // #522 {R:rel16|rel32}
+    3658             :   ISIGNATURE(3, 1, 1, 2, 194, 178, 103, 0  , 0  , 0  ), // #523 {R:mem, R:<edx>, R:<eax>}
+    3659             :   ISIGNATURE(3, 0, 1, 2, 194, 178, 103, 0  , 0  , 0  ), // #524 {R:mem, R:<edx>, R:<eax>}
+    3660             :   ISIGNATURE(3, 1, 1, 2, 215, 178, 103, 0  , 0  , 0  ), // #525 {W:mem, R:<edx>, R:<eax>}
+    3661             :   ISIGNATURE(3, 0, 1, 2, 215, 178, 103, 0  , 0  , 0  )  // #526 {W:mem, R:<edx>, R:<eax>}
+    3662             : };
+    3663             : #undef ISIGNATURE
+    3664             : // ----------------------------------------------------------------------------
+    3665             : // ${signatureData:End}
+    3666             : #endif // !ASMJIT_DISABLE_VALIDATION
+    3667             : 
+    3668             : // ============================================================================
+    3669             : // [asmjit::X86Inst - MiscData]
+    3670             : // ============================================================================
+    3671             : 
+    3672             : #define CC_TO_INST(inst) {               \
+    3673             :   inst##o, inst##no, inst##b , inst##ae, \
+    3674             :   inst##e, inst##ne, inst##be, inst##a , \
+    3675             :   inst##s, inst##ns, inst##pe, inst##po, \
+    3676             :   inst##l, inst##ge, inst##le, inst##g   \
+    3677             : }
+    3678             : 
+    3679             : const X86Inst::MiscData X86InstDB::miscData = {
+    3680             :   CC_TO_INST(X86Inst::kIdJ),
+    3681             :   CC_TO_INST(X86Inst::kIdSet),
+    3682             :   CC_TO_INST(X86Inst::kIdCmov),
+    3683             : 
+    3684             :   // ReversedCond[]:
+    3685             :   {
+    3686             :     x86::kCondO, x86::kCondNO, x86::kCondA , x86::kCondBE, // O|NO|B |AE
+    3687             :     x86::kCondE, x86::kCondNE, x86::kCondAE, x86::kCondB , // E|NE|BE|A
+    3688             :     x86::kCondS, x86::kCondNS, x86::kCondPE, x86::kCondPO, // S|NS|PE|PO
+    3689             :     x86::kCondG, x86::kCondLE, x86::kCondGE, x86::kCondL   // L|GE|LE|G
+    3690             :   }
+    3691             : };
+    3692             : 
+    3693             : #undef CC_TO_INST
+    3694             : 
+    3695             : // ============================================================================
+    3696             : // [asmjit::X86Inst - Test]
+    3697             : // ============================================================================
+    3698             : 
+    3699             : #if defined(ASMJIT_TEST)
+    3700             : UNIT(x86_inst_bits) {
+    3701             :   INFO("Checking validity of X86Inst enums");
+    3702             : 
+    3703             :   // Cross-validate prefixes.
+    3704             :   EXPECT(X86Inst::kOptionRex  == 0x80000000U, "REX prefix must be at 0x80000000");
+    3705             :   EXPECT(X86Inst::kOptionVex3 == 0x00000400U, "VEX3 prefix must be at 0x00000400");
+    3706             :   EXPECT(X86Inst::kOptionEvex == 0x00001000U, "EVEX prefix must be at 0x00001000");
+    3707             : 
+    3708             :   // These could be combined together to form a valid REX prefix, they must match.
+    3709             :   EXPECT(int(X86Inst::kOptionOpCodeB) == int(X86Inst::kOpCode_B));
+    3710             :   EXPECT(int(X86Inst::kOptionOpCodeX) == int(X86Inst::kOpCode_X));
+    3711             :   EXPECT(int(X86Inst::kOptionOpCodeR) == int(X86Inst::kOpCode_R));
+    3712             :   EXPECT(int(X86Inst::kOptionOpCodeW) == int(X86Inst::kOpCode_W));
+    3713             : 
+    3714             :   uint32_t rex_rb = (X86Inst::kOpCode_R >> X86Inst::kOpCode_REX_Shift) |
+    3715             :                     (X86Inst::kOpCode_B >> X86Inst::kOpCode_REX_Shift) | 0x40;
+    3716             :   uint32_t rex_rw = (X86Inst::kOpCode_R >> X86Inst::kOpCode_REX_Shift) |
+    3717             :                     (X86Inst::kOpCode_W >> X86Inst::kOpCode_REX_Shift) | 0x40;
+    3718             :   EXPECT(rex_rb == 0x45, "kOpCode_R|B must form a valid REX prefix 0x45 if combined with 0x40");
+    3719             :   EXPECT(rex_rw == 0x4C, "kOpCode_R|W must form a valid REX prefix 0x4C if combined with 0x40");
+    3720             : }
+    3721             : #endif // ASMJIT_TEST
+    3722             : 
+    3723             : #if defined(ASMJIT_TEST) && !defined(ASMJIT_DISABLE_TEXT)
+    3724             : UNIT(x86_inst_names) {
+    3725             :   // All known instructions should be matched.
+    3726             :   INFO("Matching all X86/X64 instructions");
+    3727             :   for (uint32_t a = 0; a < X86Inst::_kIdCount; a++) {
+    3728             :     uint32_t b = X86Inst::getIdByName(X86Inst::getInst(a).getName());
+    3729             :     EXPECT(a == b,
+    3730             :       "Should match existing instruction \"%s\" {id:%u} != \"%s\" {id:%u}",
+    3731             :         X86Inst::getInst(a).getName(), a,
+    3732             :         X86Inst::getInst(b).getName(), b);
+    3733             :   }
+    3734             : 
+    3735             :   // Everything else should return `Inst::kIdNone`.
+    3736             :   INFO("Trying to look-up instructions that don't exist");
+    3737             :   EXPECT(X86Inst::getIdByName(nullptr)  == Inst::kIdNone, "Should return Inst::kIdNone for null input");
+    3738             :   EXPECT(X86Inst::getIdByName("")       == Inst::kIdNone, "Should return Inst::kIdNone for empty string");
+    3739             :   EXPECT(X86Inst::getIdByName("_")      == Inst::kIdNone, "Should return Inst::kIdNone for unknown instruction");
+    3740             :   EXPECT(X86Inst::getIdByName("123xyz") == Inst::kIdNone, "Should return Inst::kIdNone for unknown instruction");
+    3741             : }
+    3742             : #endif // ASMJIT_TEST && !ASMJIT_DISABLE_TEXT
+    3743             : 
+    3744             : } // asmjit namespace
+    3745             : } // namespace PLMD
+    3746             : 
+    3747             : // [Api-End]
+    3748             : #include "./asmjit_apiend.h"
+    3749             : 
+    3750             : // [Guard]
+    3751             : #endif // ASMJIT_BUILD_X86
+    3752             : #pragma GCC diagnostic pop
+    3753             : #endif // __PLUMED_HAS_ASMJIT
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86inst.h.func-sort-c.html b/coverage-libs/asmjit/x86inst.h.func-sort-c.html new file mode 100644 index 000000000000..2dcfbe26cb98 --- /dev/null +++ b/coverage-libs/asmjit/x86inst.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86inst.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86inst.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:101566.7 %
Date:2024-04-19 12:12:36Functions:00-
+
+ +
+ + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86inst.h.gcov.html b/coverage-libs/asmjit/x86inst.h.gcov.html new file mode 100644 index 000000000000..1bd0f9ce73e3 --- /dev/null +++ b/coverage-libs/asmjit/x86inst.h.gcov.html @@ -0,0 +1,2624 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86inst.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86inst.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:101566.7 %
Date:2024-04-19 12:12:36Functions: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      412561 :     ASMJIT_INLINE uint32_t getFlags() const noexcept { return _flags; }
+    2157             :     //! Get if the instruction has a `flag`, see \ref X86Inst::Flags.
+    2158      947234 :     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      412561 :     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      296924 :     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       82651 :     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      587564 :   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      587564 :   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     1032534 : ASMJIT_INLINE const X86Inst::CommonData& X86Inst::getCommonData() const noexcept { return X86InstDB::commonData[_commonDataIndex]; }
+    2522       82651 : 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       53974 : ASMJIT_INLINE uint32_t X86Inst::CommonData::getAltOpCode() const noexcept { return X86InstDB::altOpCodeData[_altOpCodeIndex]; }
+    2525             : ASMJIT_INLINE const X86Inst::MiscData& X86Inst::getMiscData() noexcept { return X86InstDB::miscData; }
+    2526             : 
+    2527             : #if !defined(ASMJIT_DISABLE_VALIDATION)
+    2528             : ASMJIT_INLINE const X86Inst::ISignature* X86Inst::CommonData::getISignatureData() const noexcept { return X86InstDB::iSignatureData + _iSignatureIndex; }
+    2529             : ASMJIT_INLINE const X86Inst::ISignature* X86Inst::CommonData::getISignatureEnd() const noexcept { return X86InstDB::iSignatureData + _iSignatureIndex + _iSignatureCount; }
+    2530             : #else
+    2531             : ASMJIT_INLINE const X86Inst::ISignature* X86Inst::CommonData::getISignatureData() const noexcept { return static_cast<const X86Inst::ISignature*>(nullptr); }
+    2532             : ASMJIT_INLINE const X86Inst::ISignature* X86Inst::CommonData::getISignatureEnd() const noexcept { return static_cast<const X86Inst::ISignature*>(nullptr); }
+    2533             : #endif // ASMJIT_DISABLE_VALIDATION
+    2534             : 
+    2535             : //! \}
+    2536             : 
+    2537             : } // asmjit namespace
+    2538             : } // namespace PLMD
+    2539             : 
+    2540             : // [Api-End]
+    2541             : #include "./asmjit_apiend.h"
+    2542             : 
+    2543             : // [Guard]
+    2544             : #endif // _ASMJIT_X86_X86INST_H
+    2545             : #pragma GCC diagnostic pop
+    2546             : #endif // __PLUMED_HAS_ASMJIT
+    2547             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86instimpl.cpp.func-sort-c.html b/coverage-libs/asmjit/x86instimpl.cpp.func-sort-c.html new file mode 100644 index 000000000000..6c56bd5a7e5b --- /dev/null +++ b/coverage-libs/asmjit/x86instimpl.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86instimpl.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86instimpl.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:01700.0 %
Date:2024-04-19 12:12:36Functions:030.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

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

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

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit11X86Internal10emitEpilogEPNS0_10X86EmitterERKNS0_15FuncFrameLayoutE31895
_ZN4PLMD6asmjit11X86Internal10emitPrologEPNS0_10X86EmitterERKNS0_15FuncFrameLayoutE31895
_ZN4PLMD6asmjit11X86Internal11emitArgMoveEPNS0_10X86EmitterERKNS0_6X86RegEjRKNS0_8Operand_EjbPKc0
_ZN4PLMD6asmjit11X86Internal11emitRegMoveEPNS0_10X86EmitterERKNS0_8Operand_ES6_jbPKc105652
_ZN4PLMD6asmjit11X86Internal12initCallConvERNS0_8CallConvEj44809
_ZN4PLMD6asmjit11X86Internal14initFuncDetailERNS0_10FuncDetailERKNS0_13FuncSignatureEj44809
_ZN4PLMD6asmjit11X86Internal15argsToFrameInfoERKNS0_14FuncArgsMapperERNS0_13FuncFrameInfoE0
_ZN4PLMD6asmjit11X86Internal15initFrameLayoutERNS0_15FuncFrameLayoutERKNS0_10FuncDetailERKNS0_13FuncFrameInfoE31895
_ZN4PLMD6asmjit11X86Internal9allocArgsEPNS0_10X86EmitterERKNS0_15FuncFrameLayoutERKNS0_14FuncArgsMapperE0
_ZN4PLMD6asmjit18X86FuncArgsContext12initWorkDataERKNS0_14FuncArgsMapperEPKjb0
_ZN4PLMD6asmjit18X86FuncArgsContext16markDstRegsDirtyERNS0_13FuncFrameInfoE0
_ZN4PLMD6asmjit18X86FuncArgsContext16markRegsForSwapsERNS0_13FuncFrameInfoE0
_ZN4PLMD6asmjit18X86FuncArgsContext16markStackArgsRegERNS0_13FuncFrameInfoE0
_ZN4PLMD6asmjit18X86FuncArgsContextC2Ev0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86internal.cpp.gcov.html b/coverage-libs/asmjit/x86internal.cpp.gcov.html new file mode 100644 index 000000000000..c0433af07f25 --- /dev/null +++ b/coverage-libs/asmjit/x86internal.cpp.gcov.html @@ -0,0 +1,1459 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86internal.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86internal.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:11339428.7 %
Date:2024-04-19 12:12:36Functions: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       12624 :   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       44809 : 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       44809 :   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       44809 :   return kErrorOk;
+     414             : }
+     415             : 
+     416             : // ============================================================================
+     417             : // [asmjit::X86Internal - FuncDetail]
+     418             : // ============================================================================
+     419             : 
+     420       44809 : 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       44809 :   if (func.getRetCount() != 0) {
+     428             :     uint32_t typeId = func._rets[0].getTypeId();
+     429       44809 :     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       44809 :       case TypeId::kF32:
+     459             :       case TypeId::kF64: {
+     460       44809 :         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       44809 :   uint32_t stackBase = gpSize;
+     490       44809 :   uint32_t stackOffset = stackBase + cc._spillZoneSize;
+     491             : 
+     492       44809 :   if (cc.getAlgorithm() == CallConv::kAlgorithmDefault) {
+     493             :     uint32_t gpzPos = 0;
+     494             :     uint32_t vecPos = 0;
+     495             : 
+     496       58237 :     for (i = 0; i < argCount; i++) {
+     497             :       FuncDetail::Value& arg = func._args[i];
+     498             :       uint32_t typeId = arg.getTypeId();
+     499             : 
+     500       13428 :       if (TypeId::isInt(typeId)) {
+     501         804 :         uint32_t regId = gpzPos < CallConv::kNumRegArgsPerKind ? cc._passedOrder[X86Reg::kKindGp].id[gpzPos] : Globals::kInvalidRegId;
+     502         804 :         if (regId != Globals::kInvalidRegId) {
+     503             :           uint32_t regType = (typeId <= TypeId::kU32)
+     504         804 :             ? X86Reg::kRegGpd
+     505             :             : X86Reg::kRegGpq;
+     506             :           arg.assignToReg(regType, regId);
+     507             :           func.addUsedRegs(X86Reg::kKindGp, Utils::mask(regId));
+     508         804 :           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         804 :         continue;
+     516         804 :       }
+     517             : 
+     518       12624 :       if (TypeId::isFloat(typeId) || TypeId::isVec(typeId)) {
+     519       12624 :         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       12624 :         if (TypeId::isFloat(typeId) && !cc.hasFlag(CallConv::kFlagPassFloatsByVec))
+     523             :           regId = Globals::kInvalidRegId;
+     524             : 
+     525       12624 :         if (regId != Globals::kInvalidRegId) {
+     526             :           arg.initReg(typeId, x86VecTypeIdToRegType(typeId), regId);
+     527             :           func.addUsedRegs(X86Reg::kKindVec, Utils::mask(regId));
+     528       12624 :           vecPos++;
+     529             :         }
+     530             :         else {
+     531             :           int32_t size = TypeId::sizeOf(typeId);
+     532             :           arg.assignToStack(stackOffset);
+     533           0 :           stackOffset += size;
+     534             :         }
+     535       12624 :         continue;
+     536       12624 :       }
+     537             :     }
+     538             :   }
+     539             : 
+     540       44809 :   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       44809 :   func._argStackSize = stackOffset - stackBase;
+     583       44809 :   return kErrorOk;
+     584             : }
+     585             : 
+     586             : // ============================================================================
+     587             : // [asmjit::X86Internal - FrameLayout]
+     588             : // ============================================================================
+     589             : 
+     590       31895 : ASMJIT_FAVOR_SIZE Error X86Internal::initFrameLayout(FuncFrameLayout& layout, const FuncDetail& func, const FuncFrameInfo& ffi) noexcept {
+     591             :   layout.reset();
+     592             : 
+     593             :   uint32_t kind;
+     594       31895 :   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      159475 :   for (kind = 0; kind < Globals::kMaxVRegKinds; kind++)
+     598      127580 :     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       31895 :   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       31895 :   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       31895 :         ffi.getStackFrameAlignment(),
+     614       31895 :         ffi.getCallFrameAlignment()),
+     615       31895 :       func.getCallConv().getNaturalStackAlignment());
+     616       31895 :   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       31895 :   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       31895 :   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       31895 :   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       31895 :   if (dsa && stackArgsRegId == X86Gp::kIdSp)
+     637             :     stackArgsRegId = X86Gp::kIdBp;
+     638             : 
+     639       31895 :   if (stackArgsRegId != X86Gp::kIdSp)
+     640           0 :     layout._savedRegs[X86Reg::kKindGp] |= Utils::mask(stackArgsRegId) & func.getPreservedRegs(X86Gp::kKindGp);
+     641             : 
+     642       31895 :   layout._stackBaseRegId = X86Gp::kIdSp;
+     643       31895 :   layout._stackArgsRegId = static_cast<uint8_t>(stackArgsRegId);
+     644             : 
+     645             :   // Setup stack size used to save preserved registers.
+     646       31895 :   layout._gpStackSize  = Utils::bitCount(layout.getSavedRegs(X86Reg::kKindGp )) * gpSize;
+     647       31895 :   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       31895 :   v += ffi._callFrameSize;               // Count '_callFrameSize'  <- This is used to call functions.
+     652             :   v  = Utils::alignTo(v, stackAlignment);// Align to function's SA
+     653             : 
+     654       31895 :   layout._stackBaseOffset = v;           // Store '_stackBaseOffset'<- Function's own stack starts here..
+     655       31895 :   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       31895 :   if (stackAlignment >= 16 && layout._vecStackSize) {
+     662             :     v = Utils::alignTo(v, 16);           // Align '_vecStackOffset'.
+     663           0 :     layout._alignedVecSR = true;
+     664             :   }
+     665             : 
+     666       31895 :   layout._vecStackOffset = v;            // Store '_vecStackOffset' <- Functions VEC Save|Restore starts here.
+     667       31895 :   v += layout._vecStackSize;             // Count '_vecStackSize'   <- Functions VEC Save|Restore ends here.
+     668             : 
+     669       31895 :   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       31895 :   if (v || ffi.hasCalls())
+     684        6978 :     v += Utils::alignDiff(v + layout._gpStackSize + gpSize, stackAlignment);
+     685             : 
+     686       31895 :   layout._stackAdjustment = v;           // Store '_stackAdjustment'<- SA used by 'add zsp, SA' and 'sub zsp, SA'.
+     687       31895 :   layout._gpStackOffset = v;             // Store '_gpStackOffset'  <- Functions GP Save|Restore starts here.
+     688       31895 :   v += layout._gpStackSize;              // Count '_gpStackSize'    <- Functions GP Save|Restore ends here.
+     689             : 
+     690       31895 :   v += gpSize;                           // Count 'ReturnAddress'.
+     691       31895 :   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       31895 :   if (stackArgsRegId != X86Gp::kIdSp) {
+     699           0 :     if (ffi.hasPreservedFP())
+     700             :       stackArgsOffset = gpSize;
+     701             :     else
+     702             :       stackArgsOffset = layout._gpStackSize;
+     703             :   }
+     704       31895 :   layout._stackArgsOffset = stackArgsOffset;
+     705             : 
+     706             :   // If the function does dynamic stack adjustment then the stack-adjustment
+     707             :   // must be aligned.
+     708       31895 :   if (dsa)
+     709           0 :     layout._stackAdjustment = Utils::alignTo(layout._stackAdjustment, stackAlignment);
+     710             : 
+     711             :   // Initialize variables based on CallConv flags.
+     712       31895 :   if (func.hasFlag(CallConv::kFlagCalleePopsStack))
+     713           0 :     layout._calleeStackCleanup = static_cast<uint16_t>(func.getArgStackSize());
+     714             : 
+     715             :   // Initialize variables based on FFI flags.
+     716       31895 :   layout._mmxCleanup = ffi.hasMmxCleanup();
+     717       31895 :   layout._avxEnabled = ffi.isAvxEnabled();
+     718       31895 :   layout._avxCleanup = ffi.hasAvxCleanup();
+     719             : 
+     720       31895 :   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      105652 : 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      105652 :   if (dst.isMem()) { memFlags |= kDstMem; dst.as<X86Mem>().setSize(src.getSize()); }
+     765      105652 :   if (src.isMem()) { memFlags |= kSrcMem; src.as<X86Mem>().setSize(dst.getSize()); }
+     766             : 
+     767      105652 :   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      105652 :       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      105652 :       if (TypeId::isVec64(typeId) && memFlags) {
+     812       91108 :         if (elementTypeId == TypeId::kF64)
+     813       91108 :           instId = avxEnabled ? X86Inst::kIdVmovsd : X86Inst::kIdMovsd;
+     814             :         else
+     815           0 :           instId = avxEnabled ? X86Inst::kIdVmovq : X86Inst::kIdMovq;
+     816             :         break;
+     817             :       }
+     818             : 
+     819       14544 :       if (elementTypeId == TypeId::kF32)
+     820           0 :         instId = avxEnabled ? X86Inst::kIdVmovaps : X86Inst::kIdMovaps;
+     821       14544 :       else if (elementTypeId == TypeId::kF64)
+     822       14544 :         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      105652 :   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       31895 : 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       31895 :   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       31895 :   if (gpSaved) {
+    1067       34898 :     for (uint32_t i = gpSaved, regId = 0; i; i >>= 1, regId++) {
+    1068       27948 :       if (!(i & 0x1)) continue;
+    1069             :       gpReg.setId(regId);
+    1070        7024 :       ASMJIT_PROPAGATE(emitter->push(gpReg));
+    1071             :     }
+    1072             :   }
+    1073             : 
+    1074             :   // Emit: 'mov saReg, zsp'.
+    1075             :   uint32_t stackArgsRegId = layout.getStackArgsRegId();
+    1076       31895 :   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       31895 :   if (layout.hasDynamicAlignment())
+    1084           0 :     ASMJIT_PROPAGATE(emitter->and_(zsp, -static_cast<int32_t>(layout.getStackAlignment())));
+    1085             : 
+    1086             :   // Emit: 'sub zsp, StackAdjustment'.
+    1087       31895 :   if (layout.hasStackAdjustment())
+    1088        4588 :     ASMJIT_PROPAGATE(emitter->sub(zsp, layout.getStackAdjustment()));
+    1089             : 
+    1090             :   // Emit: 'mov [zsp + dsaSlot], saReg'.
+    1091       31895 :   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       31895 :   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       31895 : 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       31895 :   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       31895 :   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       31895 :   if (layout.hasMmxCleanup()) ASMJIT_PROPAGATE(emitter->emms());
+    1149       31895 :   if (layout.hasAvxCleanup()) ASMJIT_PROPAGATE(emitter->vzeroupper());
+    1150             : 
+    1151       31895 :   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       31895 :     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       31895 :     else if (layout.hasStackAdjustment()) {
+    1166             :       // Emit 'add zsp, StackAdjustment'.
+    1167        4588 :       ASMJIT_PROPAGATE(emitter->add(zsp, static_cast<int32_t>(layout.getStackAdjustment())));
+    1168             :     }
+    1169             :   }
+    1170             : 
+    1171             :   // Emit 'pop gp' sequence.
+    1172       31895 :   if (gpSaved) {
+    1173             :     i = gpSaved;
+    1174             :     regId = 16;
+    1175             : 
+    1176             :     do {
+    1177      111200 :       regId--;
+    1178      111200 :       if (i & 0x8000) {
+    1179             :         gpReg.setId(regId);
+    1180        7024 :         ASMJIT_PROPAGATE(emitter->pop(gpReg));
+    1181             :       }
+    1182      111200 :       i <<= 1;
+    1183      111200 :     } while (regId != 0);
+    1184             :   }
+    1185             : 
+    1186             :   // Emit 'pop zbp'.
+    1187       31895 :   if (layout.hasPreservedFP()) ASMJIT_PROPAGATE(emitter->pop(zbp));
+    1188             : 
+    1189             :   // Emit 'ret' or 'ret x'.
+    1190       31895 :   if (layout.hasCalleeStackCleanup())
+    1191           0 :     ASMJIT_PROPAGATE(emitter->emit(X86Inst::kIdRet, static_cast<int>(layout.getCalleeStackCleanup())));
+    1192             :   else
+    1193       31895 :     ASMJIT_PROPAGATE(emitter->emit(X86Inst::kIdRet));
+    1194             : 
+    1195             :   return kErrorOk;
+    1196             : }
+    1197             : 
+    1198             : // ============================================================================
+    1199             : // [asmjit::X86Internal - AllocArgs]
+    1200             : // ============================================================================
+    1201             : 
+    1202           0 : ASMJIT_FAVOR_SIZE Error X86Internal::allocArgs(X86Emitter* emitter, const FuncFrameLayout& layout, const FuncArgsMapper& args) {
+    1203             :   typedef X86FuncArgsContext::SrcArg SrcArg;
+    1204             :   typedef X86FuncArgsContext::DstArg DstArg;
+    1205             :   typedef X86FuncArgsContext::WorkData WorkData;
+    1206             :   enum { kMaxVRegKinds = Globals::kMaxVRegKinds };
+    1207             : 
+    1208             :   uint32_t i;
+    1209             :   const FuncDetail& func = *args.getFuncDetail();
+    1210             : 
+    1211           0 :   X86FuncArgsContext ctx;
+    1212           0 :   ASMJIT_PROPAGATE(ctx.initWorkData(args, layout._savedRegs, layout.hasPreservedFP()));
+    1213             : 
+    1214             :   // We must honor AVX if it's enabled.
+    1215             :   bool avxEnabled = layout.isAvxEnabled();
+    1216             : 
+    1217             :   // Free registers that can be used as temporaries and during shuffling.
+    1218             :   // We initialize them to match all workRegs (registers that can be used
+    1219             :   // by the function) except source regs, which are used to pass arguments.
+    1220             :   // Free registers are changed during shuffling - when an argument is moved
+    1221             :   // to the final register then the register itself is removed from freeRegs
+    1222             :   // (it can't be altered anymore during shuffling).
+    1223             :   uint32_t freeRegs[kMaxVRegKinds];
+    1224           0 :   for (i = 0; i < kMaxVRegKinds; i++)
+    1225           0 :     freeRegs[i] = ctx._workData[i].workRegs & ~ctx._workData[i].srcRegs;
+    1226             : 
+    1227             :   // This is an iterative process that runs until there is a work to do. When
+    1228             :   // one register is moved it can create space for another move. Such moves can
+    1229             :   // depend on each other so the algorithm may run multiple times before all
+    1230             :   // arguments are in place. This part does only register-to-register work,
+    1231             :   // arguments moved from stack-to-register area handled later.
+    1232             :   for (;;) {
+    1233             :     bool hasWork = false; // Do we have a work to do?
+    1234             :     bool didWork = false; // If we did something...
+    1235             : 
+    1236             :     uint32_t dstRegKind = kMaxVRegKinds;
+    1237             :     do {
+    1238           0 :       WorkData& wd = ctx._workData[--dstRegKind];
+    1239           0 :       if (wd.numOps > wd.numStackArgs) {
+    1240             :         hasWork = true;
+    1241             : 
+    1242             :         // Iterate over all destination regs and check if we can do something.
+    1243             :         // We always go from destination to source, never the opposite.
+    1244           0 :         uint32_t regsToDo = wd.dstRegs;
+    1245             :         do {
+    1246             :           // If there is a work to do there has to be at least one dstReg.
+    1247             :           ASMJIT_ASSERT(regsToDo != 0);
+    1248             :           uint32_t dstRegId = Utils::findFirstBit(regsToDo);
+    1249             :           uint32_t dstRegMask = Utils::mask(dstRegId);
+    1250             : 
+    1251           0 :           uint32_t argIndex = wd.argIndex[dstRegId];
+    1252           0 :           const DstArg& dstArg = args.getArg(argIndex);
+    1253             :           const SrcArg& srcArg = func.getArg(argIndex);
+    1254             : 
+    1255           0 :           if (srcArg.byReg()) {
+    1256           0 :             uint32_t srcRegType = srcArg.getRegType();
+    1257             :             uint32_t srcRegKind = X86Reg::kindOf(srcRegType);
+    1258             : 
+    1259           0 :             if (freeRegs[dstRegKind] & dstRegMask) {
+    1260             :               X86Reg dstReg(X86Reg::fromTypeAndId(dstArg.getRegType(), dstRegId));
+    1261             :               X86Reg srcReg(X86Reg::fromTypeAndId(srcRegType, srcArg.getRegId()));
+    1262             : 
+    1263           0 :               ASMJIT_PROPAGATE(
+    1264             :                 emitArgMove(emitter,
+    1265             :                   dstReg, dstArg.getTypeId(),
+    1266             :                   srcReg, srcArg.getTypeId(), avxEnabled));
+    1267           0 :               freeRegs[dstRegKind] ^= dstRegMask;                     // Make the DST reg occupied.
+    1268           0 :               freeRegs[srcRegKind] |= Utils::mask(srcArg.getRegId()); // Make the SRC reg free.
+    1269             : 
+    1270             :               ASMJIT_ASSERT(wd.numOps >= 1);
+    1271           0 :               wd.numOps--;
+    1272             :               didWork = true;
+    1273             :             }
+    1274             :             else {
+    1275             :               // Check if this is a swap operation.
+    1276           0 :               if (dstRegKind == srcRegKind) {
+    1277             :                 uint32_t srcRegId = srcArg.getRegId();
+    1278             : 
+    1279           0 :                 uint32_t otherIndex = wd.argIndex[srcRegId];
+    1280           0 :                 const DstArg& otherArg = args.getArg(otherIndex);
+    1281             : 
+    1282           0 :                 if (otherArg.getRegId() == srcRegId && X86Reg::kindOf(otherArg.getRegType()) == dstRegKind) {
+    1283             :                   // If this is GP reg it can be handled by 'xchg'.
+    1284           0 :                   if (dstRegKind == X86Reg::kKindGp) {
+    1285           0 :                     uint32_t highestType = std::max(dstArg.getRegType(), srcRegType);
+    1286             : 
+    1287           0 :                     X86Reg dstReg = x86::gpd(dstRegId);
+    1288           0 :                     X86Reg srcReg = x86::gpd(srcRegId);
+    1289             : 
+    1290           0 :                     if (highestType == X86Reg::kRegGpq) {
+    1291             :                       dstReg.setSignature(X86RegTraits<X86Reg::kRegGpq>::kSignature);
+    1292             :                       srcReg.setSignature(X86RegTraits<X86Reg::kRegGpq>::kSignature);
+    1293             :                     }
+    1294           0 :                     ASMJIT_PROPAGATE(emitter->emit(X86Inst::kIdXchg, dstReg, srcReg));
+    1295           0 :                     regsToDo &= ~Utils::mask(srcRegId);
+    1296           0 :                     freeRegs[dstRegKind] &= ~(Utils::mask(srcRegId) | dstRegMask);
+    1297             : 
+    1298             :                     ASMJIT_ASSERT(wd.numOps >= 2);
+    1299             :                     ASMJIT_ASSERT(wd.numSwaps >= 1);
+    1300           0 :                     wd.numOps-=2;
+    1301           0 :                     wd.numSwaps--;
+    1302             :                     didWork = true;
+    1303             :                   }
+    1304             :                 }
+    1305             :               }
+    1306             :             }
+    1307             :           }
+    1308             : 
+    1309             :           // Clear the reg in `regsToDo` and continue if there are more.
+    1310           0 :           regsToDo ^= dstRegMask;
+    1311           0 :         } while (regsToDo);
+    1312             :       }
+    1313           0 :     } while (dstRegKind);
+    1314             : 
+    1315           0 :     if (!hasWork)
+    1316             :       break;
+    1317             : 
+    1318           0 :     if (!didWork)
+    1319             :       return DebugUtils::errored(kErrorInvalidState);
+    1320             :   }
+    1321             : 
+    1322             :   // Load arguments passed by stack into registers. This is pretty simple and
+    1323             :   // it never requires multiple iterations like the previous phase.
+    1324           0 :   if (ctx._hasStackArgs) {
+    1325             :     // Base address of all arguments passed by stack.
+    1326             :     X86Mem saBase = x86::ptr(emitter->gpz(layout.getStackArgsRegId()), layout.getStackArgsOffset());
+    1327             : 
+    1328             :     uint32_t dstRegKind = kMaxVRegKinds;
+    1329             :     do {
+    1330           0 :       WorkData& wd = ctx._workData[--dstRegKind];
+    1331           0 :       if (wd.numStackArgs) {
+    1332             :         // Iterate over all destination regs and check if we can do something.
+    1333             :         // We always go from destination to source, never the opposite.
+    1334           0 :         uint32_t regsToDo = wd.dstRegs;
+    1335             :         do {
+    1336             :           // If there is a work to do there has to be at least one dstReg.
+    1337             :           ASMJIT_ASSERT(regsToDo != 0);
+    1338             :           ASMJIT_ASSERT(wd.numOps > 0);
+    1339             : 
+    1340             :           uint32_t dstRegId = Utils::findFirstBit(regsToDo);
+    1341             :           uint32_t dstRegMask = Utils::mask(dstRegId);
+    1342             : 
+    1343           0 :           uint32_t argIndex = wd.argIndex[dstRegId];
+    1344           0 :           const DstArg& dstArg = args.getArg(argIndex);
+    1345             :           const SrcArg& srcArg = func.getArg(argIndex);
+    1346             : 
+    1347             :           // Only arguments passed by stack should remain, also the destination
+    1348             :           // registers must be free now (otherwise the first part of the algorithm
+    1349             :           // failed). Ideally this should be assert, but it's much safer to enforce
+    1350             :           // this in release as well.
+    1351           0 :           if (!srcArg.byStack() || !(freeRegs[dstRegKind] & dstRegMask))
+    1352           0 :             return DebugUtils::errored(kErrorInvalidState);
+    1353             : 
+    1354             :           X86Reg dstReg = X86Reg::fromTypeAndId(dstArg.getRegType(), dstRegId);
+    1355             :           X86Mem srcMem = saBase.adjusted(srcArg.getStackOffset());
+    1356             : 
+    1357           0 :           ASMJIT_PROPAGATE(
+    1358             :             emitArgMove(emitter,
+    1359             :               dstReg, dstArg.getTypeId(),
+    1360             :               srcMem, srcArg.getTypeId(), avxEnabled));
+    1361             : 
+    1362           0 :           freeRegs[dstRegKind] ^= dstRegMask;
+    1363           0 :           regsToDo ^= dstRegMask;
+    1364           0 :           wd.numOps--;
+    1365           0 :         } while (regsToDo);
+    1366             :       }
+    1367           0 :     } while (dstRegKind);
+    1368             :   }
+    1369             : 
+    1370             :   return kErrorOk;
+    1371             : }
+    1372             : 
+    1373             : } // asmjit namespace
+    1374             : } // namespace PLMD
+    1375             : 
+    1376             : // [Api-End]
+    1377             : #include "./asmjit_apiend.h"
+    1378             : 
+    1379             : // [Guard]
+    1380             : #endif // ASMJIT_BUILD_X86
+    1381             : #pragma GCC diagnostic pop
+    1382             : #endif // __PLUMED_HAS_ASMJIT
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86logging.cpp.func-sort-c.html b/coverage-libs/asmjit/x86logging.cpp.func-sort-c.html new file mode 100644 index 000000000000..7fcbd39d0d38 --- /dev/null +++ b/coverage-libs/asmjit/x86logging.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86logging.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86logging.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:02030.0 %
Date:2024-04-19 12:12:36Functions:080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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

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

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

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

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86misc.h.gcov.html b/coverage-libs/asmjit/x86misc.h.gcov.html new file mode 100644 index 000000000000..984602e58edc --- /dev/null +++ b/coverage-libs/asmjit/x86misc.h.gcov.html @@ -0,0 +1,494 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86misc.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86misc.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:223759.5 %
Date:2024-04-19 12:12:36Functions: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     1533127 :   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     8228443 :     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     1573106 :     _packed += n << shift;
+     132      786553 :   }
+     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      489779 :     uint32_t x = static_cast<uint32_t>(count._regs[0]);
+     150      489779 :     uint32_t y = static_cast<uint32_t>(count._regs[1]) + x;
+     151      489779 :     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      716206 :     switch (kind) {
+     231     1261014 :       case X86Reg::kKindGp : return _gp;
+     232     3424599 :       case X86Reg::kKindVec: return _vec;
+     233      509540 :       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      213663 :       case X86Reg::kKindGp : _gp  = static_cast<uint16_t>(mask); break;
+     278       25828 :       case X86Reg::kKindMm : _mm  = static_cast<uint8_t >(mask); break;
+     279       12914 :       case X86Reg::kKindK  : _k   = static_cast<uint8_t >(mask); break;
+     280      379042 :       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      104670 :       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      253921 :       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      444970 :   }
+     344             : 
+     345             :   ASMJIT_INLINE void or_(uint32_t kind, uint32_t mask) noexcept {
+     346             :     ASMJIT_ASSERT(kind < Globals::kMaxVRegKinds);
+     347       31895 :     switch (kind) {
+     348      209340 :       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      553478 :       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       66240 :       case X86Reg::kKindVec: _vec ^= static_cast<uint32_t>(mask); break;
+     376             :     }
+     377             :   }
+     378             : 
+     379             :   ASMJIT_INLINE void xorGp(uint32_t mask) noexcept { xor_(X86Reg::kKindGp, mask); }
+     380             :   ASMJIT_INLINE void xorVec(uint32_t mask) noexcept { xor_(X86Reg::kKindVec, mask); }
+     381             :   ASMJIT_INLINE void xorMm(uint32_t mask) noexcept { xor_(X86Reg::kKindMm, mask); }
+     382             :   ASMJIT_INLINE void xorK(uint32_t mask) noexcept { xor_(X86Reg::kKindK, mask); }
+     383             : 
+     384             :   // --------------------------------------------------------------------------
+     385             :   // [Members]
+     386             :   // --------------------------------------------------------------------------
+     387             : 
+     388             :   union {
+     389             :     struct {
+     390             :       //! GP registers mask (16 bits).
+     391             :       uint16_t _gp;
+     392             :       //! MMX registers mask (8 bits).
+     393             :       uint8_t _mm;
+     394             :       //! K registers mask (8 bits).
+     395             :       uint8_t _k;
+     396             :       //! XMM|YMM|ZMM registers mask (32 bits).
+     397             :       uint32_t _vec;
+     398             :     };
+     399             : 
+     400             :     //! Packed masks.
+     401             :     UInt64 _packed;
+     402             :   };
+     403             : };
+     404             : 
+     405             : //! \}
+     406             : 
+     407             : } // asmjit namespace
+     408             : } // namespace PLMD
+     409             : 
+     410             : // [Api-End]
+     411             : #include "./asmjit_apiend.h"
+     412             : 
+     413             : // [Guard]
+     414             : #endif // _ASMJIT_X86_X86MISC_H
+     415             : #pragma GCC diagnostic pop
+     416             : #endif // __PLUMED_HAS_ASMJIT
+     417             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86operand.h.func-sort-c.html b/coverage-libs/asmjit/x86operand.h.func-sort-c.html new file mode 100644 index 000000000000..7627311cb1a6 --- /dev/null +++ b/coverage-libs/asmjit/x86operand.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86operand.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86operand.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:61154.5 %
Date:2024-04-19 12:12:36Functions:00-
+
+ +
+ + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86operand.h.gcov.html b/coverage-libs/asmjit/x86operand.h.gcov.html new file mode 100644 index 000000000000..f40f79340b81 --- /dev/null +++ b/coverage-libs/asmjit/x86operand.h.gcov.html @@ -0,0 +1,1210 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86operand.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86operand.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:61154.5 %
Date:2024-04-19 12:12:36Functions: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       83165 :     uint32_t signature = (base.getType()   << kSignatureMemBaseTypeShift ) |
+     126             :                          (size             << kSignatureSizeShift        ) ;
+     127             : 
+     128       83165 :     _init_packed_d0_d1(kOpMem | signature | flags, 0);
+     129       83165 :     _mem.base = base.getId();
+     130       83165 :     _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       31895 :   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      210442 : class X86Xmm : public X86Vec { ASMJIT_DEFINE_FINAL_REG(X86Xmm, X86Vec, X86RegTraits<kRegXmm>) };
+     613             : //! 256-bit YMM register (AVX+).
+     614             : class X86Ymm : public X86Vec { ASMJIT_DEFINE_FINAL_REG(X86Ymm, X86Vec, X86RegTraits<kRegYmm>) };
+     615             : //! 512-bit ZMM register (AVX512+).
+     616             : class X86Zmm : public X86Vec { ASMJIT_DEFINE_FINAL_REG(X86Zmm, X86Vec, X86RegTraits<kRegZmm>) };
+     617             : //! 128-bit BND register (BND+).
+     618             : class X86Bnd : public X86Reg { ASMJIT_DEFINE_FINAL_REG(X86Bnd, X86Reg, X86RegTraits<kRegBnd>) };
+     619             : //! 32-bit or 64-bit control register (X86/X64).
+     620             : class X86CReg : public X86Reg { ASMJIT_DEFINE_FINAL_REG(X86CReg, X86Reg, X86RegTraits<kRegCr>) };
+     621             : //! 32-bit or 64-bit debug register (X86/X64).
+     622             : class X86DReg : public X86Reg { ASMJIT_DEFINE_FINAL_REG(X86DReg, X86Reg, X86RegTraits<kRegDr>) };
+     623             : 
+     624             : ASMJIT_INLINE X86GpbLo X86Gp::r8() const noexcept { return X86GpbLo(getId()); }
+     625             : ASMJIT_INLINE X86GpbLo X86Gp::r8Lo() const noexcept { return X86GpbLo(getId()); }
+     626             : ASMJIT_INLINE X86GpbHi X86Gp::r8Hi() const noexcept { return X86GpbHi(getId()); }
+     627             : ASMJIT_INLINE X86Gpw X86Gp::r16() const noexcept { return X86Gpw(getId()); }
+     628             : ASMJIT_INLINE X86Gpd X86Gp::r32() const noexcept { return X86Gpd(getId()); }
+     629             : ASMJIT_INLINE X86Gpq X86Gp::r64() const noexcept { return X86Gpq(getId()); }
+     630             : ASMJIT_INLINE X86Xmm X86Vec::xmm() const noexcept { return X86Xmm(*this, getId()); }
+     631             : ASMJIT_INLINE X86Ymm X86Vec::ymm() const noexcept { return X86Ymm(*this, getId()); }
+     632             : ASMJIT_INLINE X86Zmm X86Vec::zmm() const noexcept { return X86Zmm(*this, getId()); }
+     633             : 
+     634             : ASMJIT_INLINE X86Seg X86Mem::getSegment() const noexcept { return X86Seg(getSegmentId()); }
+     635             : ASMJIT_INLINE void X86Mem::setSegment(const X86Seg& seg) noexcept { setSegmentId(seg.getId()); }
+     636             : 
+     637             : 
+     638             : ASMJIT_DEFINE_TYPE_ID(X86Gpb, TypeId::kI8);
+     639             : ASMJIT_DEFINE_TYPE_ID(X86Gpw, TypeId::kI16);
+     640             : ASMJIT_DEFINE_TYPE_ID(X86Gpd, TypeId::kI32);
+     641             : ASMJIT_DEFINE_TYPE_ID(X86Gpq, TypeId::kI64);
+     642             : ASMJIT_DEFINE_TYPE_ID(X86Mm , TypeId::kMmx64);
+     643             : ASMJIT_DEFINE_TYPE_ID(X86Xmm, TypeId::kI32x4);
+     644             : ASMJIT_DEFINE_TYPE_ID(X86Ymm, TypeId::kI32x8);
+     645             : ASMJIT_DEFINE_TYPE_ID(X86Zmm, TypeId::kI32x16);
+     646             : 
+     647             : // ============================================================================
+     648             : // [asmjit::X86OpData]
+     649             : // ============================================================================
+     650             : 
+     651             : struct X86OpData {
+     652             :   // --------------------------------------------------------------------------
+     653             :   // [Signatures]
+     654             :   // --------------------------------------------------------------------------
+     655             : 
+     656             :   //! Information about all architecture registers.
+     657             :   ArchRegs archRegs;
+     658             : 
+     659             :   // --------------------------------------------------------------------------
+     660             :   // [Operands]
+     661             :   // --------------------------------------------------------------------------
+     662             : 
+     663             :   // Prevent calling constructors of these registers when exporting.
+     664             : #if defined(ASMJIT_EXPORTS_X86_OPERAND)
+     665             : # define ASMJIT_X86_REG_DATA(REG) Operand_
+     666             : #else
+     667             : # define ASMJIT_X86_REG_DATA(REG) REG
+     668             : #endif
+     669             :   ASMJIT_X86_REG_DATA(X86Rip ) rip[1];
+     670             :   ASMJIT_X86_REG_DATA(X86Seg ) seg[7];
+     671             :   ASMJIT_X86_REG_DATA(X86Gp  ) gpbLo[16];
+     672             :   ASMJIT_X86_REG_DATA(X86Gp  ) gpbHi[4];
+     673             :   ASMJIT_X86_REG_DATA(X86Gp  ) gpw[16];
+     674             :   ASMJIT_X86_REG_DATA(X86Gp  ) gpd[16];
+     675             :   ASMJIT_X86_REG_DATA(X86Gp  ) gpq[16];
+     676             :   ASMJIT_X86_REG_DATA(X86Fp  ) fp[8];
+     677             :   ASMJIT_X86_REG_DATA(X86Mm  ) mm[8];
+     678             :   ASMJIT_X86_REG_DATA(X86KReg) k[8];
+     679             :   ASMJIT_X86_REG_DATA(X86Xmm ) xmm[32];
+     680             :   ASMJIT_X86_REG_DATA(X86Ymm ) ymm[32];
+     681             :   ASMJIT_X86_REG_DATA(X86Zmm ) zmm[32];
+     682             :   ASMJIT_X86_REG_DATA(X86Bnd ) bnd[4];
+     683             :   ASMJIT_X86_REG_DATA(X86CReg) cr[16];
+     684             :   ASMJIT_X86_REG_DATA(X86DReg) dr[16];
+     685             : #undef ASMJIT_X86_REG_DATA
+     686             : };
+     687             : ASMJIT_VARAPI const X86OpData x86OpData;
+     688             : 
+     689             : // ... X86Reg methods that require `x86OpData`.
+     690             : ASMJIT_INLINE uint32_t X86Reg::signatureOf(uint32_t rType) noexcept {
+     691             :   ASMJIT_ASSERT(rType <= Reg::kRegMax);
+     692             :   return x86OpData.archRegs.regInfo[rType].getSignature();
+     693             : }
+     694             : 
+     695             : ASMJIT_INLINE uint32_t X86Reg::kindOf(uint32_t rType) noexcept {
+     696             :   ASMJIT_ASSERT(rType <= Reg::kRegMax);
+     697             :   return x86OpData.archRegs.regInfo[rType].getKind();
+     698             : }
+     699             : 
+     700             : // ============================================================================
+     701             : // [asmjit::x86]
+     702             : // ============================================================================
+     703             : 
+     704             : namespace x86 {
+     705             : 
+     706             : // ============================================================================
+     707             : // [asmjit::x86 - Reg]
+     708             : // ============================================================================
+     709             : 
+     710             : #if !defined(ASMJIT_EXPORTS_X86_OPERAND)
+     711             : namespace {
+     712             : #define ASMJIT_X86_PHYS_REG(TYPE, NAME, PROPERTY) \
+     713             :   static const TYPE& NAME = x86OpData.PROPERTY
+     714             : 
+     715             : ASMJIT_X86_PHYS_REG(X86Rip , rip  , rip[0]);    //!< RIP register.
+     716             : ASMJIT_X86_PHYS_REG(X86Seg , es   , seg[1]);    //!< CS segment register.
+     717             : ASMJIT_X86_PHYS_REG(X86Seg , cs   , seg[2]);    //!< SS segment register.
+     718             : ASMJIT_X86_PHYS_REG(X86Seg , ss   , seg[3]);    //!< DS segment register.
+     719             : ASMJIT_X86_PHYS_REG(X86Seg , ds   , seg[4]);    //!< ES segment register.
+     720             : ASMJIT_X86_PHYS_REG(X86Seg , fs   , seg[5]);    //!< FS segment register.
+     721             : ASMJIT_X86_PHYS_REG(X86Seg , gs   , seg[6]);    //!< GS segment register.
+     722             : 
+     723             : ASMJIT_X86_PHYS_REG(X86Gp  , al   , gpbLo[0]);  //!< 8-bit low GPB register.
+     724             : ASMJIT_X86_PHYS_REG(X86Gp  , cl   , gpbLo[1]);  //!< 8-bit low GPB register.
+     725             : ASMJIT_X86_PHYS_REG(X86Gp  , dl   , gpbLo[2]);  //!< 8-bit low GPB register.
+     726             : ASMJIT_X86_PHYS_REG(X86Gp  , bl   , gpbLo[3]);  //!< 8-bit low GPB register.
+     727             : ASMJIT_X86_PHYS_REG(X86Gp  , spl  , gpbLo[4]);  //!< 8-bit low GPB register (X64).
+     728             : ASMJIT_X86_PHYS_REG(X86Gp  , bpl  , gpbLo[5]);  //!< 8-bit low GPB register (X64).
+     729             : ASMJIT_X86_PHYS_REG(X86Gp  , sil  , gpbLo[6]);  //!< 8-bit low GPB register (X64).
+     730             : ASMJIT_X86_PHYS_REG(X86Gp  , dil  , gpbLo[7]);  //!< 8-bit low GPB register (X64).
+     731             : ASMJIT_X86_PHYS_REG(X86Gp  , r8b  , gpbLo[8]);  //!< 8-bit low GPB register (X64).
+     732             : ASMJIT_X86_PHYS_REG(X86Gp  , r9b  , gpbLo[9]);  //!< 8-bit low GPB register (X64).
+     733             : ASMJIT_X86_PHYS_REG(X86Gp  , r10b , gpbLo[10]); //!< 8-bit low GPB register (X64).
+     734             : ASMJIT_X86_PHYS_REG(X86Gp  , r11b , gpbLo[11]); //!< 8-bit low GPB register (X64).
+     735             : ASMJIT_X86_PHYS_REG(X86Gp  , r12b , gpbLo[12]); //!< 8-bit low GPB register (X64).
+     736             : ASMJIT_X86_PHYS_REG(X86Gp  , r13b , gpbLo[13]); //!< 8-bit low GPB register (X64).
+     737             : ASMJIT_X86_PHYS_REG(X86Gp  , r14b , gpbLo[14]); //!< 8-bit low GPB register (X64).
+     738             : ASMJIT_X86_PHYS_REG(X86Gp  , r15b , gpbLo[15]); //!< 8-bit low GPB register (X64).
+     739             : 
+     740             : ASMJIT_X86_PHYS_REG(X86Gp  , ah   , gpbHi[0]);  //!< 8-bit high GPB register.
+     741             : ASMJIT_X86_PHYS_REG(X86Gp  , ch   , gpbHi[1]);  //!< 8-bit high GPB register.
+     742             : ASMJIT_X86_PHYS_REG(X86Gp  , dh   , gpbHi[2]);  //!< 8-bit high GPB register.
+     743             : ASMJIT_X86_PHYS_REG(X86Gp  , bh   , gpbHi[3]);  //!< 8-bit high GPB register.
+     744             : 
+     745             : ASMJIT_X86_PHYS_REG(X86Gp  , ax   , gpw[0]);    //!< 16-bit GPW register.
+     746             : ASMJIT_X86_PHYS_REG(X86Gp  , cx   , gpw[1]);    //!< 16-bit GPW register.
+     747             : ASMJIT_X86_PHYS_REG(X86Gp  , dx   , gpw[2]);    //!< 16-bit GPW register.
+     748             : ASMJIT_X86_PHYS_REG(X86Gp  , bx   , gpw[3]);    //!< 16-bit GPW register.
+     749             : ASMJIT_X86_PHYS_REG(X86Gp  , sp   , gpw[4]);    //!< 16-bit GPW register.
+     750             : ASMJIT_X86_PHYS_REG(X86Gp  , bp   , gpw[5]);    //!< 16-bit GPW register.
+     751             : ASMJIT_X86_PHYS_REG(X86Gp  , si   , gpw[6]);    //!< 16-bit GPW register.
+     752             : ASMJIT_X86_PHYS_REG(X86Gp  , di   , gpw[7]);    //!< 16-bit GPW register.
+     753             : ASMJIT_X86_PHYS_REG(X86Gp  , r8w  , gpw[8]);    //!< 16-bit GPW register (X64).
+     754             : ASMJIT_X86_PHYS_REG(X86Gp  , r9w  , gpw[9]);    //!< 16-bit GPW register (X64).
+     755             : ASMJIT_X86_PHYS_REG(X86Gp  , r10w , gpw[10]);   //!< 16-bit GPW register (X64).
+     756             : ASMJIT_X86_PHYS_REG(X86Gp  , r11w , gpw[11]);   //!< 16-bit GPW register (X64).
+     757             : ASMJIT_X86_PHYS_REG(X86Gp  , r12w , gpw[12]);   //!< 16-bit GPW register (X64).
+     758             : ASMJIT_X86_PHYS_REG(X86Gp  , r13w , gpw[13]);   //!< 16-bit GPW register (X64).
+     759             : ASMJIT_X86_PHYS_REG(X86Gp  , r14w , gpw[14]);   //!< 16-bit GPW register (X64).
+     760             : ASMJIT_X86_PHYS_REG(X86Gp  , r15w , gpw[15]);   //!< 16-bit GPW register (X64).
+     761             : 
+     762             : ASMJIT_X86_PHYS_REG(X86Gp  , eax  , gpd[0]);    //!< 32-bit GPD register.
+     763             : ASMJIT_X86_PHYS_REG(X86Gp  , ecx  , gpd[1]);    //!< 32-bit GPD register.
+     764             : ASMJIT_X86_PHYS_REG(X86Gp  , edx  , gpd[2]);    //!< 32-bit GPD register.
+     765             : ASMJIT_X86_PHYS_REG(X86Gp  , ebx  , gpd[3]);    //!< 32-bit GPD register.
+     766             : ASMJIT_X86_PHYS_REG(X86Gp  , esp  , gpd[4]);    //!< 32-bit GPD register.
+     767             : ASMJIT_X86_PHYS_REG(X86Gp  , ebp  , gpd[5]);    //!< 32-bit GPD register.
+     768             : ASMJIT_X86_PHYS_REG(X86Gp  , esi  , gpd[6]);    //!< 32-bit GPD register.
+     769             : ASMJIT_X86_PHYS_REG(X86Gp  , edi  , gpd[7]);    //!< 32-bit GPD register.
+     770             : ASMJIT_X86_PHYS_REG(X86Gp  , r8d  , gpd[8]);    //!< 32-bit GPD register (X64).
+     771             : ASMJIT_X86_PHYS_REG(X86Gp  , r9d  , gpd[9]);    //!< 32-bit GPD register (X64).
+     772             : ASMJIT_X86_PHYS_REG(X86Gp  , r10d , gpd[10]);   //!< 32-bit GPD register (X64).
+     773             : ASMJIT_X86_PHYS_REG(X86Gp  , r11d , gpd[11]);   //!< 32-bit GPD register (X64).
+     774             : ASMJIT_X86_PHYS_REG(X86Gp  , r12d , gpd[12]);   //!< 32-bit GPD register (X64).
+     775             : ASMJIT_X86_PHYS_REG(X86Gp  , r13d , gpd[13]);   //!< 32-bit GPD register (X64).
+     776             : ASMJIT_X86_PHYS_REG(X86Gp  , r14d , gpd[14]);   //!< 32-bit GPD register (X64).
+     777             : ASMJIT_X86_PHYS_REG(X86Gp  , r15d , gpd[15]);   //!< 32-bit GPD register (X64).
+     778             : 
+     779             : ASMJIT_X86_PHYS_REG(X86Gp  , rax  , gpq[0]);    //!< 64-bit GPQ register (X64).
+     780             : ASMJIT_X86_PHYS_REG(X86Gp  , rcx  , gpq[1]);    //!< 64-bit GPQ register (X64).
+     781             : ASMJIT_X86_PHYS_REG(X86Gp  , rdx  , gpq[2]);    //!< 64-bit GPQ register (X64).
+     782             : ASMJIT_X86_PHYS_REG(X86Gp  , rbx  , gpq[3]);    //!< 64-bit GPQ register (X64).
+     783             : ASMJIT_X86_PHYS_REG(X86Gp  , rsp  , gpq[4]);    //!< 64-bit GPQ register (X64).
+     784             : ASMJIT_X86_PHYS_REG(X86Gp  , rbp  , gpq[5]);    //!< 64-bit GPQ register (X64).
+     785             : ASMJIT_X86_PHYS_REG(X86Gp  , rsi  , gpq[6]);    //!< 64-bit GPQ register (X64).
+     786             : ASMJIT_X86_PHYS_REG(X86Gp  , rdi  , gpq[7]);    //!< 64-bit GPQ register (X64).
+     787             : ASMJIT_X86_PHYS_REG(X86Gp  , r8   , gpq[8]);    //!< 64-bit GPQ register (X64).
+     788             : ASMJIT_X86_PHYS_REG(X86Gp  , r9   , gpq[9]);    //!< 64-bit GPQ register (X64).
+     789             : ASMJIT_X86_PHYS_REG(X86Gp  , r10  , gpq[10]);   //!< 64-bit GPQ register (X64).
+     790             : ASMJIT_X86_PHYS_REG(X86Gp  , r11  , gpq[11]);   //!< 64-bit GPQ register (X64).
+     791             : ASMJIT_X86_PHYS_REG(X86Gp  , r12  , gpq[12]);   //!< 64-bit GPQ register (X64).
+     792             : ASMJIT_X86_PHYS_REG(X86Gp  , r13  , gpq[13]);   //!< 64-bit GPQ register (X64).
+     793             : ASMJIT_X86_PHYS_REG(X86Gp  , r14  , gpq[14]);   //!< 64-bit GPQ register (X64).
+     794             : ASMJIT_X86_PHYS_REG(X86Gp  , r15  , gpq[15]);   //!< 64-bit GPQ register (X64).
+     795             : 
+     796             : ASMJIT_X86_PHYS_REG(X86Fp  , fp0  , fp[0]);     //!< 80-bit FPU register.
+     797             : ASMJIT_X86_PHYS_REG(X86Fp  , fp1  , fp[1]);     //!< 80-bit FPU register.
+     798             : ASMJIT_X86_PHYS_REG(X86Fp  , fp2  , fp[2]);     //!< 80-bit FPU register.
+     799             : ASMJIT_X86_PHYS_REG(X86Fp  , fp3  , fp[3]);     //!< 80-bit FPU register.
+     800             : ASMJIT_X86_PHYS_REG(X86Fp  , fp4  , fp[4]);     //!< 80-bit FPU register.
+     801             : ASMJIT_X86_PHYS_REG(X86Fp  , fp5  , fp[5]);     //!< 80-bit FPU register.
+     802             : ASMJIT_X86_PHYS_REG(X86Fp  , fp6  , fp[6]);     //!< 80-bit FPU register.
+     803             : ASMJIT_X86_PHYS_REG(X86Fp  , fp7  , fp[7]);     //!< 80-bit FPU register.
+     804             : 
+     805             : ASMJIT_X86_PHYS_REG(X86Mm  , mm0  , mm[0]);     //!< 64-bit MMX register.
+     806             : ASMJIT_X86_PHYS_REG(X86Mm  , mm1  , mm[1]);     //!< 64-bit MMX register.
+     807             : ASMJIT_X86_PHYS_REG(X86Mm  , mm2  , mm[2]);     //!< 64-bit MMX register.
+     808             : ASMJIT_X86_PHYS_REG(X86Mm  , mm3  , mm[3]);     //!< 64-bit MMX register.
+     809             : ASMJIT_X86_PHYS_REG(X86Mm  , mm4  , mm[4]);     //!< 64-bit MMX register.
+     810             : ASMJIT_X86_PHYS_REG(X86Mm  , mm5  , mm[5]);     //!< 64-bit MMX register.
+     811             : ASMJIT_X86_PHYS_REG(X86Mm  , mm6  , mm[6]);     //!< 64-bit MMX register.
+     812             : ASMJIT_X86_PHYS_REG(X86Mm  , mm7  , mm[7]);     //!< 64-bit MMX register.
+     813             : 
+     814             : ASMJIT_X86_PHYS_REG(X86KReg, k0   , k[0]);      //!< 64-bit K register.
+     815             : ASMJIT_X86_PHYS_REG(X86KReg, k1   , k[1]);      //!< 64-bit K register.
+     816             : ASMJIT_X86_PHYS_REG(X86KReg, k2   , k[2]);      //!< 64-bit K register.
+     817             : ASMJIT_X86_PHYS_REG(X86KReg, k3   , k[3]);      //!< 64-bit K register.
+     818             : ASMJIT_X86_PHYS_REG(X86KReg, k4   , k[4]);      //!< 64-bit K register.
+     819             : ASMJIT_X86_PHYS_REG(X86KReg, k5   , k[5]);      //!< 64-bit K register.
+     820             : ASMJIT_X86_PHYS_REG(X86KReg, k6   , k[6]);      //!< 64-bit K register.
+     821             : ASMJIT_X86_PHYS_REG(X86KReg, k7   , k[7]);      //!< 64-bit K register.
+     822             : 
+     823             : ASMJIT_X86_PHYS_REG(X86Xmm , xmm0 , xmm[0]);    //!< 128-bit XMM register.
+     824             : ASMJIT_X86_PHYS_REG(X86Xmm , xmm1 , xmm[1]);    //!< 128-bit XMM register.
+     825             : ASMJIT_X86_PHYS_REG(X86Xmm , xmm2 , xmm[2]);    //!< 128-bit XMM register.
+     826             : ASMJIT_X86_PHYS_REG(X86Xmm , xmm3 , xmm[3]);    //!< 128-bit XMM register.
+     827             : ASMJIT_X86_PHYS_REG(X86Xmm , xmm4 , xmm[4]);    //!< 128-bit XMM register.
+     828             : ASMJIT_X86_PHYS_REG(X86Xmm , xmm5 , xmm[5]);    //!< 128-bit XMM register.
+     829             : ASMJIT_X86_PHYS_REG(X86Xmm , xmm6 , xmm[6]);    //!< 128-bit XMM register.
+     830             : ASMJIT_X86_PHYS_REG(X86Xmm , xmm7 , xmm[7]);    //!< 128-bit XMM register.
+     831             : ASMJIT_X86_PHYS_REG(X86Xmm , xmm8 , xmm[8]);    //!< 128-bit XMM register (X64).
+     832             : ASMJIT_X86_PHYS_REG(X86Xmm , xmm9 , xmm[9]);    //!< 128-bit XMM register (X64).
+     833             : ASMJIT_X86_PHYS_REG(X86Xmm , xmm10, xmm[10]);   //!< 128-bit XMM register (X64).
+     834             : ASMJIT_X86_PHYS_REG(X86Xmm , xmm11, xmm[11]);   //!< 128-bit XMM register (X64).
+     835             : ASMJIT_X86_PHYS_REG(X86Xmm , xmm12, xmm[12]);   //!< 128-bit XMM register (X64).
+     836             : ASMJIT_X86_PHYS_REG(X86Xmm , xmm13, xmm[13]);   //!< 128-bit XMM register (X64).
+     837             : ASMJIT_X86_PHYS_REG(X86Xmm , xmm14, xmm[14]);   //!< 128-bit XMM register (X64).
+     838             : ASMJIT_X86_PHYS_REG(X86Xmm , xmm15, xmm[15]);   //!< 128-bit XMM register (X64).
+     839             : ASMJIT_X86_PHYS_REG(X86Xmm , xmm16, xmm[16]);   //!< 128-bit XMM register (X64 & AVX512_VL+).
+     840             : ASMJIT_X86_PHYS_REG(X86Xmm , xmm17, xmm[17]);   //!< 128-bit XMM register (X64 & AVX512_VL+).
+     841             : ASMJIT_X86_PHYS_REG(X86Xmm , xmm18, xmm[18]);   //!< 128-bit XMM register (X64 & AVX512_VL+).
+     842             : ASMJIT_X86_PHYS_REG(X86Xmm , xmm19, xmm[19]);   //!< 128-bit XMM register (X64 & AVX512_VL+).
+     843             : ASMJIT_X86_PHYS_REG(X86Xmm , xmm20, xmm[20]);   //!< 128-bit XMM register (X64 & AVX512_VL+).
+     844             : ASMJIT_X86_PHYS_REG(X86Xmm , xmm21, xmm[21]);   //!< 128-bit XMM register (X64 & AVX512_VL+).
+     845             : ASMJIT_X86_PHYS_REG(X86Xmm , xmm22, xmm[22]);   //!< 128-bit XMM register (X64 & AVX512_VL+).
+     846             : ASMJIT_X86_PHYS_REG(X86Xmm , xmm23, xmm[23]);   //!< 128-bit XMM register (X64 & AVX512_VL+).
+     847             : ASMJIT_X86_PHYS_REG(X86Xmm , xmm24, xmm[24]);   //!< 128-bit XMM register (X64 & AVX512_VL+).
+     848             : ASMJIT_X86_PHYS_REG(X86Xmm , xmm25, xmm[25]);   //!< 128-bit XMM register (X64 & AVX512_VL+).
+     849             : ASMJIT_X86_PHYS_REG(X86Xmm , xmm26, xmm[26]);   //!< 128-bit XMM register (X64 & AVX512_VL+).
+     850             : ASMJIT_X86_PHYS_REG(X86Xmm , xmm27, xmm[27]);   //!< 128-bit XMM register (X64 & AVX512_VL+).
+     851             : ASMJIT_X86_PHYS_REG(X86Xmm , xmm28, xmm[28]);   //!< 128-bit XMM register (X64 & AVX512_VL+).
+     852             : ASMJIT_X86_PHYS_REG(X86Xmm , xmm29, xmm[29]);   //!< 128-bit XMM register (X64 & AVX512_VL+).
+     853             : ASMJIT_X86_PHYS_REG(X86Xmm , xmm30, xmm[30]);   //!< 128-bit XMM register (X64 & AVX512_VL+).
+     854             : ASMJIT_X86_PHYS_REG(X86Xmm , xmm31, xmm[31]);   //!< 128-bit XMM register (X64 & AVX512_VL+).
+     855             : 
+     856             : ASMJIT_X86_PHYS_REG(X86Ymm , ymm0 , ymm[0]);    //!< 256-bit YMM register.
+     857             : ASMJIT_X86_PHYS_REG(X86Ymm , ymm1 , ymm[1]);    //!< 256-bit YMM register.
+     858             : ASMJIT_X86_PHYS_REG(X86Ymm , ymm2 , ymm[2]);    //!< 256-bit YMM register.
+     859             : ASMJIT_X86_PHYS_REG(X86Ymm , ymm3 , ymm[3]);    //!< 256-bit YMM register.
+     860             : ASMJIT_X86_PHYS_REG(X86Ymm , ymm4 , ymm[4]);    //!< 256-bit YMM register.
+     861             : ASMJIT_X86_PHYS_REG(X86Ymm , ymm5 , ymm[5]);    //!< 256-bit YMM register.
+     862             : ASMJIT_X86_PHYS_REG(X86Ymm , ymm6 , ymm[6]);    //!< 256-bit YMM register.
+     863             : ASMJIT_X86_PHYS_REG(X86Ymm , ymm7 , ymm[7]);    //!< 256-bit YMM register.
+     864             : ASMJIT_X86_PHYS_REG(X86Ymm , ymm8 , ymm[8]);    //!< 256-bit YMM register (X64).
+     865             : ASMJIT_X86_PHYS_REG(X86Ymm , ymm9 , ymm[9]);    //!< 256-bit YMM register (X64).
+     866             : ASMJIT_X86_PHYS_REG(X86Ymm , ymm10, ymm[10]);   //!< 256-bit YMM register (X64).
+     867             : ASMJIT_X86_PHYS_REG(X86Ymm , ymm11, ymm[11]);   //!< 256-bit YMM register (X64).
+     868             : ASMJIT_X86_PHYS_REG(X86Ymm , ymm12, ymm[12]);   //!< 256-bit YMM register (X64).
+     869             : ASMJIT_X86_PHYS_REG(X86Ymm , ymm13, ymm[13]);   //!< 256-bit YMM register (X64).
+     870             : ASMJIT_X86_PHYS_REG(X86Ymm , ymm14, ymm[14]);   //!< 256-bit YMM register (X64).
+     871             : ASMJIT_X86_PHYS_REG(X86Ymm , ymm15, ymm[15]);   //!< 256-bit YMM register (X64).
+     872             : ASMJIT_X86_PHYS_REG(X86Ymm , ymm16, ymm[16]);   //!< 256-bit YMM register (X64 & AVX512_VL+).
+     873             : ASMJIT_X86_PHYS_REG(X86Ymm , ymm17, ymm[17]);   //!< 256-bit YMM register (X64 & AVX512_VL+).
+     874             : ASMJIT_X86_PHYS_REG(X86Ymm , ymm18, ymm[18]);   //!< 256-bit YMM register (X64 & AVX512_VL+).
+     875             : ASMJIT_X86_PHYS_REG(X86Ymm , ymm19, ymm[19]);   //!< 256-bit YMM register (X64 & AVX512_VL+).
+     876             : ASMJIT_X86_PHYS_REG(X86Ymm , ymm20, ymm[20]);   //!< 256-bit YMM register (X64 & AVX512_VL+).
+     877             : ASMJIT_X86_PHYS_REG(X86Ymm , ymm21, ymm[21]);   //!< 256-bit YMM register (X64 & AVX512_VL+).
+     878             : ASMJIT_X86_PHYS_REG(X86Ymm , ymm22, ymm[22]);   //!< 256-bit YMM register (X64 & AVX512_VL+).
+     879             : ASMJIT_X86_PHYS_REG(X86Ymm , ymm23, ymm[23]);   //!< 256-bit YMM register (X64 & AVX512_VL+).
+     880             : ASMJIT_X86_PHYS_REG(X86Ymm , ymm24, ymm[24]);   //!< 256-bit YMM register (X64 & AVX512_VL+).
+     881             : ASMJIT_X86_PHYS_REG(X86Ymm , ymm25, ymm[25]);   //!< 256-bit YMM register (X64 & AVX512_VL+).
+     882             : ASMJIT_X86_PHYS_REG(X86Ymm , ymm26, ymm[26]);   //!< 256-bit YMM register (X64 & AVX512_VL+).
+     883             : ASMJIT_X86_PHYS_REG(X86Ymm , ymm27, ymm[27]);   //!< 256-bit YMM register (X64 & AVX512_VL+).
+     884             : ASMJIT_X86_PHYS_REG(X86Ymm , ymm28, ymm[28]);   //!< 256-bit YMM register (X64 & AVX512_VL+).
+     885             : ASMJIT_X86_PHYS_REG(X86Ymm , ymm29, ymm[29]);   //!< 256-bit YMM register (X64 & AVX512_VL+).
+     886             : ASMJIT_X86_PHYS_REG(X86Ymm , ymm30, ymm[30]);   //!< 256-bit YMM register (X64 & AVX512_VL+).
+     887             : ASMJIT_X86_PHYS_REG(X86Ymm , ymm31, ymm[31]);   //!< 256-bit YMM register (X64 & AVX512_VL+).
+     888             : 
+     889             : ASMJIT_X86_PHYS_REG(X86Zmm , zmm0 , zmm[0]);    //!< 512-bit ZMM register.
+     890             : ASMJIT_X86_PHYS_REG(X86Zmm , zmm1 , zmm[1]);    //!< 512-bit ZMM register.
+     891             : ASMJIT_X86_PHYS_REG(X86Zmm , zmm2 , zmm[2]);    //!< 512-bit ZMM register.
+     892             : ASMJIT_X86_PHYS_REG(X86Zmm , zmm3 , zmm[3]);    //!< 512-bit ZMM register.
+     893             : ASMJIT_X86_PHYS_REG(X86Zmm , zmm4 , zmm[4]);    //!< 512-bit ZMM register.
+     894             : ASMJIT_X86_PHYS_REG(X86Zmm , zmm5 , zmm[5]);    //!< 512-bit ZMM register.
+     895             : ASMJIT_X86_PHYS_REG(X86Zmm , zmm6 , zmm[6]);    //!< 512-bit ZMM register.
+     896             : ASMJIT_X86_PHYS_REG(X86Zmm , zmm7 , zmm[7]);    //!< 512-bit ZMM register.
+     897             : ASMJIT_X86_PHYS_REG(X86Zmm , zmm8 , zmm[8]);    //!< 512-bit ZMM register (X64).
+     898             : ASMJIT_X86_PHYS_REG(X86Zmm , zmm9 , zmm[9]);    //!< 512-bit ZMM register (X64).
+     899             : ASMJIT_X86_PHYS_REG(X86Zmm , zmm10, zmm[10]);   //!< 512-bit ZMM register (X64).
+     900             : ASMJIT_X86_PHYS_REG(X86Zmm , zmm11, zmm[11]);   //!< 512-bit ZMM register (X64).
+     901             : ASMJIT_X86_PHYS_REG(X86Zmm , zmm12, zmm[12]);   //!< 512-bit ZMM register (X64).
+     902             : ASMJIT_X86_PHYS_REG(X86Zmm , zmm13, zmm[13]);   //!< 512-bit ZMM register (X64).
+     903             : ASMJIT_X86_PHYS_REG(X86Zmm , zmm14, zmm[14]);   //!< 512-bit ZMM register (X64).
+     904             : ASMJIT_X86_PHYS_REG(X86Zmm , zmm15, zmm[15]);   //!< 512-bit ZMM register (X64).
+     905             : ASMJIT_X86_PHYS_REG(X86Zmm , zmm16, zmm[16]);   //!< 512-bit ZMM register (X64 & AVX512_F+).
+     906             : ASMJIT_X86_PHYS_REG(X86Zmm , zmm17, zmm[17]);   //!< 512-bit ZMM register (X64 & AVX512_F+).
+     907             : ASMJIT_X86_PHYS_REG(X86Zmm , zmm18, zmm[18]);   //!< 512-bit ZMM register (X64 & AVX512_F+).
+     908             : ASMJIT_X86_PHYS_REG(X86Zmm , zmm19, zmm[19]);   //!< 512-bit ZMM register (X64 & AVX512_F+).
+     909             : ASMJIT_X86_PHYS_REG(X86Zmm , zmm20, zmm[20]);   //!< 512-bit ZMM register (X64 & AVX512_F+).
+     910             : ASMJIT_X86_PHYS_REG(X86Zmm , zmm21, zmm[21]);   //!< 512-bit ZMM register (X64 & AVX512_F+).
+     911             : ASMJIT_X86_PHYS_REG(X86Zmm , zmm22, zmm[22]);   //!< 512-bit ZMM register (X64 & AVX512_F+).
+     912             : ASMJIT_X86_PHYS_REG(X86Zmm , zmm23, zmm[23]);   //!< 512-bit ZMM register (X64 & AVX512_F+).
+     913             : ASMJIT_X86_PHYS_REG(X86Zmm , zmm24, zmm[24]);   //!< 512-bit ZMM register (X64 & AVX512_F+).
+     914             : ASMJIT_X86_PHYS_REG(X86Zmm , zmm25, zmm[25]);   //!< 512-bit ZMM register (X64 & AVX512_F+).
+     915             : ASMJIT_X86_PHYS_REG(X86Zmm , zmm26, zmm[26]);   //!< 512-bit ZMM register (X64 & AVX512_F+).
+     916             : ASMJIT_X86_PHYS_REG(X86Zmm , zmm27, zmm[27]);   //!< 512-bit ZMM register (X64 & AVX512_F+).
+     917             : ASMJIT_X86_PHYS_REG(X86Zmm , zmm28, zmm[28]);   //!< 512-bit ZMM register (X64 & AVX512_F+).
+     918             : ASMJIT_X86_PHYS_REG(X86Zmm , zmm29, zmm[29]);   //!< 512-bit ZMM register (X64 & AVX512_F+).
+     919             : ASMJIT_X86_PHYS_REG(X86Zmm , zmm30, zmm[30]);   //!< 512-bit ZMM register (X64 & AVX512_F+).
+     920             : ASMJIT_X86_PHYS_REG(X86Zmm , zmm31, zmm[31]);   //!< 512-bit ZMM register (X64 & AVX512_F+).
+     921             : 
+     922             : ASMJIT_X86_PHYS_REG(X86Bnd , bnd0 , bnd[0]);    //!< 128-bit bound register.
+     923             : ASMJIT_X86_PHYS_REG(X86Bnd , bnd1 , bnd[1]);    //!< 128-bit bound register.
+     924             : ASMJIT_X86_PHYS_REG(X86Bnd , bnd2 , bnd[2]);    //!< 128-bit bound register.
+     925             : ASMJIT_X86_PHYS_REG(X86Bnd , bnd3 , bnd[3]);    //!< 128-bit bound register.
+     926             : 
+     927             : ASMJIT_X86_PHYS_REG(X86CReg, cr0  , cr[0]);     //!< 32-bit or 64-bit control register.
+     928             : ASMJIT_X86_PHYS_REG(X86CReg, cr1  , cr[1]);     //!< 32-bit or 64-bit control register.
+     929             : ASMJIT_X86_PHYS_REG(X86CReg, cr2  , cr[2]);     //!< 32-bit or 64-bit control register.
+     930             : ASMJIT_X86_PHYS_REG(X86CReg, cr3  , cr[3]);     //!< 32-bit or 64-bit control register.
+     931             : ASMJIT_X86_PHYS_REG(X86CReg, cr4  , cr[4]);     //!< 32-bit or 64-bit control register.
+     932             : ASMJIT_X86_PHYS_REG(X86CReg, cr5  , cr[5]);     //!< 32-bit or 64-bit control register.
+     933             : ASMJIT_X86_PHYS_REG(X86CReg, cr6  , cr[6]);     //!< 32-bit or 64-bit control register.
+     934             : ASMJIT_X86_PHYS_REG(X86CReg, cr7  , cr[7]);     //!< 32-bit or 64-bit control register.
+     935             : ASMJIT_X86_PHYS_REG(X86CReg, cr8  , cr[8]);     //!< 32-bit or 64-bit control register.
+     936             : ASMJIT_X86_PHYS_REG(X86CReg, cr9  , cr[9]);     //!< 32-bit or 64-bit control register.
+     937             : ASMJIT_X86_PHYS_REG(X86CReg, cr10 , cr[10]);    //!< 32-bit or 64-bit control register.
+     938             : ASMJIT_X86_PHYS_REG(X86CReg, cr11 , cr[11]);    //!< 32-bit or 64-bit control register.
+     939             : ASMJIT_X86_PHYS_REG(X86CReg, cr12 , cr[12]);    //!< 32-bit or 64-bit control register.
+     940             : ASMJIT_X86_PHYS_REG(X86CReg, cr13 , cr[13]);    //!< 32-bit or 64-bit control register.
+     941             : ASMJIT_X86_PHYS_REG(X86CReg, cr14 , cr[14]);    //!< 32-bit or 64-bit control register.
+     942             : ASMJIT_X86_PHYS_REG(X86CReg, cr15 , cr[15]);    //!< 32-bit or 64-bit control register.
+     943             : 
+     944             : ASMJIT_X86_PHYS_REG(X86DReg, dr0  , dr[0]);     //!< 32-bit or 64-bit debug register.
+     945             : ASMJIT_X86_PHYS_REG(X86DReg, dr1  , dr[1]);     //!< 32-bit or 64-bit debug register.
+     946             : ASMJIT_X86_PHYS_REG(X86DReg, dr2  , dr[2]);     //!< 32-bit or 64-bit debug register.
+     947             : ASMJIT_X86_PHYS_REG(X86DReg, dr3  , dr[3]);     //!< 32-bit or 64-bit debug register.
+     948             : ASMJIT_X86_PHYS_REG(X86DReg, dr4  , dr[4]);     //!< 32-bit or 64-bit debug register.
+     949             : ASMJIT_X86_PHYS_REG(X86DReg, dr5  , dr[5]);     //!< 32-bit or 64-bit debug register.
+     950             : ASMJIT_X86_PHYS_REG(X86DReg, dr6  , dr[6]);     //!< 32-bit or 64-bit debug register.
+     951             : ASMJIT_X86_PHYS_REG(X86DReg, dr7  , dr[7]);     //!< 32-bit or 64-bit debug register.
+     952             : ASMJIT_X86_PHYS_REG(X86DReg, dr8  , dr[8]);     //!< 32-bit or 64-bit debug register.
+     953             : ASMJIT_X86_PHYS_REG(X86DReg, dr9  , dr[9]);     //!< 32-bit or 64-bit debug register.
+     954             : ASMJIT_X86_PHYS_REG(X86DReg, dr10 , dr[10]);    //!< 32-bit or 64-bit debug register.
+     955             : ASMJIT_X86_PHYS_REG(X86DReg, dr11 , dr[11]);    //!< 32-bit or 64-bit debug register.
+     956             : ASMJIT_X86_PHYS_REG(X86DReg, dr12 , dr[12]);    //!< 32-bit or 64-bit debug register.
+     957             : ASMJIT_X86_PHYS_REG(X86DReg, dr13 , dr[13]);    //!< 32-bit or 64-bit debug register.
+     958             : ASMJIT_X86_PHYS_REG(X86DReg, dr14 , dr[14]);    //!< 32-bit or 64-bit debug register.
+     959             : ASMJIT_X86_PHYS_REG(X86DReg, dr15 , dr[15]);    //!< 32-bit or 64-bit debug register.
+     960             : 
+     961             : #undef ASMJIT_X86_PHYS_REG
+     962             : } // anonymous namespace
+     963             : #endif // !ASMJIT_EXPORTS_X86_OPERAND
+     964             : 
+     965             : //! Create an 8-bit low GPB register operand.
+     966             : static ASMJIT_INLINE X86GpbLo gpb(uint32_t rId) noexcept { return X86GpbLo(rId); }
+     967             : //! Create an 8-bit low GPB register operand.
+     968             : static ASMJIT_INLINE X86GpbLo gpb_lo(uint32_t rId) noexcept { return X86GpbLo(rId); }
+     969             : //! Create an 8-bit high GPB register operand.
+     970             : static ASMJIT_INLINE X86GpbHi gpb_hi(uint32_t rId) noexcept { return X86GpbHi(rId); }
+     971             : //! Create a 16-bit GPW register operand.
+     972             : static ASMJIT_INLINE X86Gpw gpw(uint32_t rId) noexcept { return X86Gpw(rId); }
+     973             : //! Create a 32-bit GPD register operand.
+     974             : static ASMJIT_INLINE X86Gpd gpd(uint32_t rId) noexcept { return X86Gpd(rId); }
+     975             : //! Create a 64-bit GPQ register operand (X64).
+     976             : static ASMJIT_INLINE X86Gpq gpq(uint32_t rId) noexcept { return X86Gpq(rId); }
+     977             : //! Create an 80-bit Fp register operand.
+     978             : static ASMJIT_INLINE X86Fp fp(uint32_t rId) noexcept { return X86Fp(rId); }
+     979             : //! Create a 64-bit Mm register operand.
+     980             : static ASMJIT_INLINE X86Mm mm(uint32_t rId) noexcept { return X86Mm(rId); }
+     981             : //! Create a 64-bit K register operand.
+     982             : static ASMJIT_INLINE X86KReg k(uint32_t rId) noexcept { return X86KReg(rId); }
+     983             : //! Create a 128-bit XMM register operand.
+     984             : static ASMJIT_INLINE X86Xmm xmm(uint32_t rId) noexcept { return X86Xmm(rId); }
+     985             : //! Create a 256-bit YMM register operand.
+     986             : static ASMJIT_INLINE X86Ymm ymm(uint32_t rId) noexcept { return X86Ymm(rId); }
+     987             : //! Create a 512-bit ZMM register operand.
+     988             : static ASMJIT_INLINE X86Zmm zmm(uint32_t rId) noexcept { return X86Zmm(rId); }
+     989             : //! Create a 128-bit bound register operand.
+     990             : static ASMJIT_INLINE X86Bnd bnd(uint32_t rId) noexcept { return X86Bnd(rId); }
+     991             : //! Create a 32-bit or 64-bit control register operand.
+     992             : static ASMJIT_INLINE X86CReg cr(uint32_t rId) noexcept { return X86CReg(rId); }
+     993             : //! Create a 32-bit or 64-bit debug register operand.
+     994             : static ASMJIT_INLINE X86DReg dr(uint32_t rId) noexcept { return X86DReg(rId); }
+     995             : 
+     996             : // ============================================================================
+     997             : // [asmjit::x86 - Ptr (Reg)]
+     998             : // ============================================================================
+     999             : 
+    1000             : //! Create a `[base.reg + offset]` memory operand.
+    1001             : static ASMJIT_INLINE X86Mem ptr(const X86Gp& base, int32_t offset = 0, uint32_t size = 0) noexcept {
+    1002             :   return X86Mem(base, offset, size);
+    1003             : }
+    1004             : //! Create a `[base.reg + (index << shift) + offset]` memory operand (scalar index).
+    1005             : static ASMJIT_INLINE X86Mem ptr(const X86Gp& base, const X86Gp& index, uint32_t shift = 0, int32_t offset = 0, uint32_t size = 0) noexcept {
+    1006             :   return X86Mem(base, index, shift, offset, size);
+    1007             : }
+    1008             : //! Create a `[base.reg + (index << shift) + offset]` memory operand (vector index).
+    1009             : static ASMJIT_INLINE X86Mem ptr(const X86Gp& base, const X86Vec& index, uint32_t shift = 0, int32_t offset = 0, uint32_t size = 0) noexcept {
+    1010             :   return X86Mem(base, index, shift, offset, size);
+    1011             : }
+    1012             : 
+    1013             : //! Create a `[base + offset]` memory operand.
+    1014             : static ASMJIT_INLINE X86Mem ptr(const Label& base, int32_t offset = 0, uint32_t size = 0) noexcept {
+    1015             :   return X86Mem(base, offset, size);
+    1016             : }
+    1017             : //! Create a `[base + (index << shift) + offset]` memory operand.
+    1018             : static ASMJIT_INLINE X86Mem ptr(const Label& base, const X86Gp& index, uint32_t shift, int32_t offset = 0, uint32_t size = 0) noexcept {
+    1019             :   return X86Mem(base, index, shift, offset, size);
+    1020             : }
+    1021             : //! Create a `[base + (index << shift) + offset]` memory operand.
+    1022             : static ASMJIT_INLINE X86Mem ptr(const Label& base, const X86Vec& index, uint32_t shift, int32_t offset = 0, uint32_t size = 0) noexcept {
+    1023             :   return X86Mem(base, index, shift, offset, size);
+    1024             : }
+    1025             : 
+    1026             : //! Create `[rip + offset]` memory operand.
+    1027             : static ASMJIT_INLINE X86Mem ptr(const X86Rip& rip_, int32_t offset = 0, uint32_t size = 0) noexcept {
+    1028             :   return X86Mem(rip_, offset, size);
+    1029             : }
+    1030             : 
+    1031             : //! Create an `[base]` absolute memory operand.
+    1032             : static ASMJIT_INLINE X86Mem ptr(uint64_t base, uint32_t size = 0) noexcept {
+    1033             :   return X86Mem(base, size);
+    1034             : }
+    1035             : //! Create an `[abs + (index.reg << shift)]` absolute memory operand.
+    1036             : static ASMJIT_INLINE X86Mem ptr(uint64_t base, const X86Reg& index, uint32_t shift = 0, uint32_t size = 0) noexcept {
+    1037             :   return X86Mem(base, index, shift, size);
+    1038             : }
+    1039             : //! Create an `[abs + (index.reg << shift)]` absolute memory operand.
+    1040             : static ASMJIT_INLINE X86Mem ptr(uint64_t base, const X86Vec& index, uint32_t shift = 0, uint32_t size = 0) noexcept {
+    1041             :   return X86Mem(base, index, shift, size);
+    1042             : }
+    1043             : 
+    1044             : //! \internal
+    1045             : #define ASMJIT_X86_PTR_FN(FUNC, SIZE)                                                 \
+    1046             :   /*! Create a `[base + offset]` memory operand. */                                   \
+    1047             :   static ASMJIT_INLINE X86Mem FUNC(const X86Gp& base, int32_t offset = 0) noexcept {  \
+    1048             :     return X86Mem(base, offset, SIZE);                                                \
+    1049             :   }                                                                                   \
+    1050             :   /*! Create a `[base + (index << shift) + offset]` memory operand. */                \
+    1051             :   static ASMJIT_INLINE X86Mem FUNC(const X86Gp& base, const X86Gp& index, uint32_t shift = 0, int32_t offset = 0) noexcept { \
+    1052             :     return X86Mem(base, index, shift, offset, SIZE);                                  \
+    1053             :   }                                                                                   \
+    1054             :   /*! Create a `[base + (vec_index << shift) + offset]` memory operand. */            \
+    1055             :   static ASMJIT_INLINE X86Mem FUNC(const X86Gp& base, const X86Vec& index, uint32_t shift = 0, int32_t offset = 0) noexcept { \
+    1056             :     return X86Mem(base, index, shift, offset, SIZE);                                  \
+    1057             :   }                                                                                   \
+    1058             :   /*! Create a `[base + offset]` memory operand. */                                   \
+    1059             :   static ASMJIT_INLINE X86Mem FUNC(const Label& base, int32_t offset = 0) noexcept {  \
+    1060             :     return X86Mem(base, offset, SIZE);                                                \
+    1061             :   }                                                                                   \
+    1062             :   /*! Create a `[base + (index << shift) + offset]` memory operand. */                \
+    1063             :   static ASMJIT_INLINE X86Mem FUNC(const Label& base, const X86Gp& index, uint32_t shift, int32_t offset = 0) noexcept { \
+    1064             :     return X86Mem(base, index, shift, offset, SIZE);                                  \
+    1065             :   }                                                                                   \
+    1066             :   /*! Create a `[rip + offset]` memory operand. */                                    \
+    1067             :   static ASMJIT_INLINE X86Mem FUNC(const X86Rip& rip_, int32_t offset = 0) noexcept { \
+    1068             :     return X86Mem(rip_, offset, SIZE);                                                \
+    1069             :   }                                                                                   \
+    1070             :   /*! Create a `[base + offset]` memory operand. */                                   \
+    1071             :   static ASMJIT_INLINE X86Mem FUNC(uint64_t base) noexcept {                          \
+    1072             :     return X86Mem(base, SIZE);                                                        \
+    1073             :   }                                                                                   \
+    1074             :   /*! Create a `[base + (index << shift) + offset]` memory operand. */                \
+    1075             :   static ASMJIT_INLINE X86Mem FUNC(uint64_t base, const X86Gp& index, uint32_t shift = 0) noexcept { \
+    1076             :     return X86Mem(base, index, shift, SIZE);                                          \
+    1077             :   }                                                                                   \
+    1078             :   /*! Create a `[base + (vec_index << shift) + offset]` memory operand. */            \
+    1079             :   static ASMJIT_INLINE X86Mem FUNC(uint64_t base, const X86Vec& index, uint32_t shift = 0) noexcept { \
+    1080             :     return X86Mem(base, index, shift, SIZE, Mem::kSignatureMemAbs);                   \
+    1081             :   }                                                                                   \
+    1082             :   /*! Create a `[base + offset]` memory operand. */                                   \
+    1083             :   static ASMJIT_INLINE X86Mem FUNC##_abs(uint64_t base) noexcept {                    \
+    1084             :     return X86Mem(base, SIZE);                                                        \
+    1085             :   }                                                                                   \
+    1086             :   /*! Create a `[base + (index << shift) + offset]` memory operand. */                \
+    1087             :   static ASMJIT_INLINE X86Mem FUNC##_abs(uint64_t base, const X86Gp& index, uint32_t shift = 0) noexcept { \
+    1088             :     return X86Mem(base, index, shift, SIZE, Mem::kSignatureMemAbs);                   \
+    1089             :   }                                                                                   \
+    1090             :   /*! Create a `[base + (vec_index << shift) + offset]` memory operand. */            \
+    1091             :   static ASMJIT_INLINE X86Mem FUNC##_abs(uint64_t base, const X86Vec& index, uint32_t shift = 0) noexcept { \
+    1092             :     return X86Mem(base, index, shift, SIZE, Mem::kSignatureMemAbs);                   \
+    1093             :   }
+    1094             : 
+    1095             : // Define memory operand constructors that use platform independent naming.
+    1096             : ASMJIT_X86_PTR_FN(ptr_8, 1)
+    1097             : ASMJIT_X86_PTR_FN(ptr_16, 2)
+    1098             : ASMJIT_X86_PTR_FN(ptr_32, 4)
+    1099             : ASMJIT_X86_PTR_FN(ptr_48, 6)
+    1100             : ASMJIT_X86_PTR_FN(ptr_64, 8)
+    1101             : ASMJIT_X86_PTR_FN(ptr_80, 10)
+    1102             : ASMJIT_X86_PTR_FN(ptr_128, 16)
+    1103             : ASMJIT_X86_PTR_FN(ptr_256, 32)
+    1104             : ASMJIT_X86_PTR_FN(ptr_512, 64)
+    1105             : 
+    1106             : // Define memory operand constructors that use X86/X64 specific naming.
+    1107             : ASMJIT_X86_PTR_FN(byte_ptr, 1)
+    1108             : ASMJIT_X86_PTR_FN(word_ptr, 2)
+    1109             : ASMJIT_X86_PTR_FN(dword_ptr, 4)
+    1110             : ASMJIT_X86_PTR_FN(qword_ptr, 8)
+    1111             : ASMJIT_X86_PTR_FN(tword_ptr, 10)
+    1112             : ASMJIT_X86_PTR_FN(oword_ptr, 16)
+    1113             : ASMJIT_X86_PTR_FN(dqword_ptr, 16)
+    1114             : ASMJIT_X86_PTR_FN(yword_ptr, 32)
+    1115             : ASMJIT_X86_PTR_FN(zword_ptr, 64)
+    1116             : 
+    1117             : #undef ASMJIT_X86_PTR_FN
+    1118             : 
+    1119             : } // x86 namespace
+    1120             : 
+    1121             : //! \}
+    1122             : 
+    1123             : } // asmjit namespace
+    1124             : } // namespace PLMD
+    1125             : 
+    1126             : // [Api-End]
+    1127             : #include "./asmjit_apiend.h"
+    1128             : 
+    1129             : // [Guard]
+    1130             : #endif // _ASMJIT_X86_X86OPERAND_H
+    1131             : #pragma GCC diagnostic pop
+    1132             : #endif // __PLUMED_HAS_ASMJIT
+    1133             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86regalloc.cpp.func-sort-c.html b/coverage-libs/asmjit/x86regalloc.cpp.func-sort-c.html new file mode 100644 index 000000000000..ba7143f21d1e --- /dev/null +++ b/coverage-libs/asmjit/x86regalloc.cpp.func-sort-c.html @@ -0,0 +1,189 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86regalloc.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86regalloc.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:466105544.2 %
Date:2024-04-19 12:12:36Functions: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
_ZN4PLMD6asmjit9X86RAPass12emitImmToRegEjjPKNS0_3ImmE804
_ZN4PLMD6asmjitL30X86RAPass_prepareSingleVarInstEjPNS0_7TiedRegE5274
_ZN4PLMD6asmjit12X86CallAlloc3runEPNS0_10CCFuncCallE12914
_ZN4PLMD6asmjit9X86RAPass8emitMoveEPNS0_7VirtRegEjjPKc14544
_ZN4PLMD6asmjit9X86RAPass5fetchEv31895
_ZN4PLMD6asmjit9X86RAPass7prepareEPNS0_6CCFuncE31895
_ZN4PLMD6asmjit9X86RAPass7processEPNS0_4ZoneE31895
_ZN4PLMD6asmjit9X86RAPass9translateEv31895
_ZN4PLMD6asmjit9X86RAPassC2Ev31895
_ZN4PLMD6asmjitL22X86RAPass_patchFuncMemEPNS0_9X86RAPassEPNS0_6CCFuncEPNS0_6CBNodeERNS0_15FuncFrameLayoutE31895
_ZN4PLMD6asmjitL22X86RAPass_translateRetEPNS0_9X86RAPassEPNS0_9CCFuncRetEPNS0_7CBLabelE31895
_ZN4PLMD6asmjitL26X86RAPass_prepareFuncFrameEPNS0_9X86RAPassEPNS0_6CCFuncE31895
_ZN4PLMD6asmjitL30X86RAPass_assignStackArgsRegIdEPNS0_9X86RAPassEPNS0_6CCFuncE31895
_ZN4PLMD6asmjit9X86RAPass8emitSaveEPNS0_7VirtRegEjPKc39412
_ZN4PLMD6asmjit9X86RAPass8emitLoadEPNS0_7VirtRegEjPKc51696
_ZN4PLMD6asmjitL27X86RAPass_translateOperandsEPNS0_9X86RAPassEPNS0_8Operand_Ej425989
_ZN4PLMD6asmjit11X86VarAlloc3runEPNS0_6CBNodeE476865
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86regalloc.cpp.func.html b/coverage-libs/asmjit/x86regalloc.cpp.func.html new file mode 100644 index 000000000000..eb731f5af1e2 --- /dev/null +++ b/coverage-libs/asmjit/x86regalloc.cpp.func.html @@ -0,0 +1,189 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86regalloc.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86regalloc.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:466105544.2 %
Date:2024-04-19 12:12:36Functions:172958.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit11X86VarAlloc3runEPNS0_6CBNodeE476865
_ZN4PLMD6asmjit12X86CallAlloc3runEPNS0_10CCFuncCallE12914
_ZN4PLMD6asmjit9X86RAPass10emitSwapGpEPNS0_7VirtRegES3_jjPKc0
_ZN4PLMD6asmjit9X86RAPass11_checkStateEv0
_ZN4PLMD6asmjit9X86RAPass11switchStateEPNS0_7RAStateE0
_ZN4PLMD6asmjit9X86RAPass12emitImmToRegEjjPKNS0_3ImmE804
_ZN4PLMD6asmjit9X86RAPass14emitImmToStackEjPKNS0_6X86MemEPKNS0_3ImmE0
_ZN4PLMD6asmjit9X86RAPass14emitRegToStackEjPKNS0_6X86MemEjj0
_ZN4PLMD6asmjit9X86RAPass15intersectStatesEPNS0_7RAStateES3_0
_ZN4PLMD6asmjit9X86RAPass5fetchEv31895
_ZN4PLMD6asmjit9X86RAPass7prepareEPNS0_6CCFuncE31895
_ZN4PLMD6asmjit9X86RAPass7processEPNS0_4ZoneE31895
_ZN4PLMD6asmjit9X86RAPass8annotateEv0
_ZN4PLMD6asmjit9X86RAPass8emitLoadEPNS0_7VirtRegEjPKc51696
_ZN4PLMD6asmjit9X86RAPass8emitMoveEPNS0_7VirtRegEjjPKc14544
_ZN4PLMD6asmjit9X86RAPass8emitSaveEPNS0_7VirtRegEjPKc39412
_ZN4PLMD6asmjit9X86RAPass9loadStateEPNS0_7RAStateE0
_ZN4PLMD6asmjit9X86RAPass9saveStateEv0
_ZN4PLMD6asmjit9X86RAPass9translateEv31895
_ZN4PLMD6asmjit9X86RAPassC2Ev31895
_ZN4PLMD6asmjit9X86RAPassD0Ev0
_ZN4PLMD6asmjit9X86RAPassD2Ev0
_ZN4PLMD6asmjitL22X86RAPass_patchFuncMemEPNS0_9X86RAPassEPNS0_6CCFuncEPNS0_6CBNodeERNS0_15FuncFrameLayoutE31895
_ZN4PLMD6asmjitL22X86RAPass_translateRetEPNS0_9X86RAPassEPNS0_9CCFuncRetEPNS0_7CBLabelE31895
_ZN4PLMD6asmjitL23X86RAPass_translateJumpEPNS0_9X86RAPassEPNS0_6CBJumpEPNS0_7CBLabelE0
_ZN4PLMD6asmjitL26X86RAPass_prepareFuncFrameEPNS0_9X86RAPassEPNS0_6CCFuncE31895
_ZN4PLMD6asmjitL27X86RAPass_translateOperandsEPNS0_9X86RAPassEPNS0_8Operand_Ej425989
_ZN4PLMD6asmjitL30X86RAPass_assignStackArgsRegIdEPNS0_9X86RAPassEPNS0_6CCFuncE31895
_ZN4PLMD6asmjitL30X86RAPass_prepareSingleVarInstEjPNS0_7TiedRegE5274
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86regalloc.cpp.gcov.html b/coverage-libs/asmjit/x86regalloc.cpp.gcov.html new file mode 100644 index 000000000000..f046ed6cd4cb --- /dev/null +++ b/coverage-libs/asmjit/x86regalloc.cpp.gcov.html @@ -0,0 +1,4165 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86regalloc.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86regalloc.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:466105544.2 %
Date:2024-04-19 12:12:36Functions: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       31895 : X86RAPass::X86RAPass() noexcept : RAPass() {
+     200       31895 :   _state = &_x86State;
+     201       31895 :   _varMapToVaListOffset = ASMJIT_OFFSET_OF(X86RAData, tiedArray);
+     202       31895 : }
+     203           0 : X86RAPass::~X86RAPass() noexcept {}
+     204             : 
+     205             : // ============================================================================
+     206             : // [asmjit::X86RAPass - Interface]
+     207             : // ============================================================================
+     208             : 
+     209       31895 : Error X86RAPass::process(Zone* zone) noexcept {
+     210       31895 :   return Base::process(zone);
+     211             : }
+     212             : 
+     213       31895 : Error X86RAPass::prepare(CCFunc* func) noexcept {
+     214       31895 :   ASMJIT_PROPAGATE(Base::prepare(func));
+     215             : 
+     216             :   uint32_t archType = cc()->getArchType();
+     217       31895 :   _regCount._gp  = archType == ArchInfo::kTypeX86 ? 8 : 16;
+     218       31895 :   _regCount._mm  = 8;
+     219       31895 :   _regCount._k   = 8;
+     220       31895 :   _regCount._vec = archType == ArchInfo::kTypeX86 ? 8 : 16;
+     221             :   _zsp = cc()->zsp();
+     222             :   _zbp = cc()->zbp();
+     223             : 
+     224       31895 :   _gaRegs[X86Reg::kKindGp ] = Utils::bits(_regCount.getGp()) & ~Utils::mask(X86Gp::kIdSp);
+     225       31895 :   _gaRegs[X86Reg::kKindMm ] = Utils::bits(_regCount.getMm());
+     226       31895 :   _gaRegs[X86Reg::kKindK  ] = Utils::bits(_regCount.getK());
+     227       31895 :   _gaRegs[X86Reg::kKindVec] = Utils::bits(_regCount.getVec());
+     228             : 
+     229       31895 :   _x86State.reset(0);
+     230             :   _clobberedRegs.reset();
+     231             : 
+     232       31895 :   _avxEnabled = false;
+     233             : 
+     234       31895 :   _varBaseRegId = Globals::kInvalidRegId; // Used by patcher.
+     235       31895 :   _varBaseOffset = 0;                     // Used by patcher.
+     236             : 
+     237       31895 :   return kErrorOk;
+     238             : }
+     239             : 
+     240             : // ============================================================================
+     241             : // [asmjit::X86RAPass - Emit]
+     242             : // ============================================================================
+     243             : 
+     244       14544 : Error X86RAPass::emitMove(VirtReg* vReg, uint32_t dstId, uint32_t srcId, const char* reason) {
+     245             :   const char* comment = nullptr;
+     246       14544 :   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       14544 :   return X86Internal::emitRegMove(reinterpret_cast<X86Emitter*>(cc()), dst, src, vReg->getTypeId(), _avxEnabled, comment);
+     254             : }
+     255             : 
+     256       51696 : Error X86RAPass::emitLoad(VirtReg* vReg, uint32_t id, const char* reason) {
+     257             :   const char* comment = nullptr;
+     258       51696 :   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       51696 :   return X86Internal::emitRegMove(reinterpret_cast<X86Emitter*>(cc()), dst, src, vReg->getTypeId(), _avxEnabled, comment);
+     266             : }
+     267             : 
+     268       39412 : Error X86RAPass::emitSave(VirtReg* vReg, uint32_t id, const char* reason) {
+     269             :   const char* comment = nullptr;
+     270       39412 :   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       39412 :   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         804 : 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         804 :   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         804 :       if (imm.isUInt32())
+     327           0 :         goto Mov32Truncate;
+     328             : 
+     329             :       r0.setX86RegT<X86Reg::kRegGpq>(dstPhysId);
+     330         804 :       cc()->emit(X86Inst::kIdMov, r0, imm);
+     331         804 :       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         804 :   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        5274 : static void X86RAPass_prepareSingleVarInst(uint32_t instId, TiedReg* tr) {
+    1027        5274 :   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        5274 :     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        5274 :       tr->flags &= ~TiedReg::kRReg;
+    1041        5274 :       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        5274 : }
+    1053             : 
+    1054             : // ============================================================================
+    1055             : // [asmjit::X86RAPass - Helpers]
+    1056             : // ============================================================================
+    1057             : 
+    1058       31895 : 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       31895 :   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       31895 :     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       31895 :     uint32_t regs = passed & ~used;
+    1084             : 
+    1085             :     // Pick any other register if that didn't work out.
+    1086       31895 :     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       31895 : }
+    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       31895 : 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     2583495 :   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       31895 :   uint32_t* gaRegs = _gaRegs;
+    1275             : 
+    1276       31895 :   if (func->getFrameInfo().hasPreservedFP())
+    1277           0 :     gaRegs[X86Reg::kKindGp] &= ~Utils::mask(X86Gp::kIdBp);
+    1278             : 
+    1279             :   // Allowed index registers (GP/XMM/YMM).
+    1280       31895 :   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      457884 : _Do:
+    1381      489779 :     while (node_->hasPassData()) {
+    1382           0 : _NextGroup:
+    1383       31895 :       if (!jLink)
+    1384             :         jLink = _jccList.getFirst();
+    1385             :       else
+    1386             :         jLink = jLink->getNext();
+    1387             : 
+    1388       31895 :       if (!jLink) goto _Done;
+    1389             :       node_ = X86RAPass_getOppositeJccFlow(static_cast<CBJump*>(jLink->getValue()));
+    1390             :     }
+    1391             : 
+    1392      489779 :     position++;
+    1393             : 
+    1394             :     next = node_->getNext();
+    1395             :     node_->setPosition(position);
+    1396             : 
+    1397      489779 :     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      413075 :       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      413075 :         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      413075 :           if (commonData.isFpu())
+    1523             :             flags |= CBNode::kFlagIsFp;
+    1524             : 
+    1525      413075 :           if (commonData.hasFixedRM() && (special = X86SpecialInst_get(instId, opArray, opCount)) != nullptr)
+    1526           0 :             flags |= CBNode::kFlagIsSpecial;
+    1527             : 
+    1528     1241495 :           for (uint32_t i = 0; i < opCount; i++) {
+    1529      828420 :             Operand* op = &opArray[i];
+    1530             :             VirtReg* vreg;
+    1531             :             TiedReg* tied;
+    1532             : 
+    1533             :             if (op->isVirtReg()) {
+    1534             :               vreg = cc()->getVirtRegById(op->getId());
+    1535      638315 :               if (vreg->isFixed()) continue;
+    1536             : 
+    1537     1573554 :               RA_MERGE(vreg, tied, 0, gaRegs[vreg->getKind()] & gpAllowedMask);
+    1538      638315 :               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      638315 :               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      638315 :                 if (i == 0) {
+    1594             :                   // Read/Write is usually the combination of the first operand.
+    1595             :                   combinedFlags = inFlags | outFlags;
+    1596             : 
+    1597      412561 :                   if (node->getOptions() & CodeEmitter::kOptionOverwrite) {
+    1598             :                     // Manually forcing write-only.
+    1599             :                     combinedFlags = outFlags;
+    1600             :                   }
+    1601      412561 :                   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      296924 :                     if (opArray[1].isMem() && inst.getOperationData().isMovSsSd())
+    1609             :                       movSize = 16;
+    1610             : 
+    1611      296924 :                     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      104670 :                       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      104670 :                       if (movSize >= 4 || movSize >= regSize)
+    1624             :                         combinedFlags = outFlags;
+    1625             :                     }
+    1626      192254 :                     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      115637 :                   else if (commonData.isUseR()) {
+    1634             :                     // Comparison/Test instructions don't modify any operand.
+    1635             :                     combinedFlags = inFlags;
+    1636             :                   }
+    1637      115637 :                   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      225754 :                   if (commonData.isUseXX() || (instId == X86Inst::kIdImul && opCount == 3 && i == 1))
+    1651             :                     combinedFlags = inFlags | outFlags;
+    1652             :                 }
+    1653      638315 :                 tied->flags |= combinedFlags;
+    1654             :               }
+    1655             :             }
+    1656      190105 :             else if (op->isMem()) {
+    1657             :               X86Mem* m = static_cast<X86Mem*>(op);
+    1658             :               node->setMemOpIndex(i);
+    1659             : 
+    1660       83165 :               uint32_t specBase = special ? uint32_t(special[i].inReg) : uint32_t(Globals::kInvalidRegId);
+    1661             : 
+    1662       83165 :               if (m->hasBaseReg()) {
+    1663             :                 uint32_t id = m->getBaseId();
+    1664       83165 :                 if (cc()->isVirtRegValid(id)) {
+    1665             :                   vreg = cc()->getVirtRegById(id);
+    1666       83165 :                   if (!vreg->isStack() && !vreg->isFixed()) {
+    1667      166330 :                     RA_MERGE(vreg, tied, 0, gaRegs[vreg->getKind()] & gpAllowedMask);
+    1668       83165 :                     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       83165 :                       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       83165 :                         tied->flags |= TiedReg::kRReg;
+    1714             :                       }
+    1715             :                     }
+    1716             :                   }
+    1717             :                 }
+    1718             :               }
+    1719             : 
+    1720       83165 :               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      413075 :           if (tiedTotal) {
+    1738             :             // Handle instructions which result in zeros/ones or nop if used with the
+    1739             :             // same destination and source operand.
+    1740      418349 :             if (tiedTotal == 1 && opCount >= 2 && opArray[0].isVirtReg() && opArray[1].isVirtReg() && !node->hasMemOp())
+    1741        5274 :               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      413075 :           if (tiedCount.getVec() && commonData.hasFlag(X86Inst::kFlagVex | X86Inst::kFlagEvex))
+    1746           0 :             _avxEnabled = true;
+    1747             :         }
+    1748             : 
+    1749             :         const RegOnly& extraReg = node->getExtraReg();
+    1750      413075 :         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     1129281 :         RA_FINALIZE(node_);
+    1768             : 
+    1769             :         // Handle conditional/unconditional jump.
+    1770      413075 :         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       31895 :       case CBNode::kNodeFunc: {
+    1826             :         ASMJIT_ASSERT(node_ == func);
+    1827       31895 :         X86RAPass_assignStackArgsRegId(this, func);
+    1828             : 
+    1829             :         FuncDetail& fd = func->getDetail();
+    1830             :         TiedReg* tied;
+    1831             : 
+    1832             :         RA_DECLARE();
+    1833       31895 :         cc()->setCursor(node_);
+    1834             : 
+    1835             :         X86Gp saReg;
+    1836             :         uint32_t argCount = fd.getArgCount();
+    1837             : 
+    1838       31895 :         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       31895 :         if (!saReg.isValid())
+    1901             :           func->getFrameInfo().setStackArgsRegId(Globals::kInvalidRegId);
+    1902             : 
+    1903       31895 :         RA_FINALIZE(node_);
+    1904             :         next = node_->getNext();
+    1905       31895 :         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       31895 :       case CBNode::kNodeFuncExit: {
+    1923             :         CCFuncRet* node = static_cast<CCFuncRet*>(node_);
+    1924       31895 :         ASMJIT_PROPAGATE(addReturningNode(node));
+    1925             : 
+    1926             :         FuncDetail& fd = func->getDetail();
+    1927             :         RA_DECLARE();
+    1928             : 
+    1929       31895 :         if (fd.hasRet()) {
+    1930             :           const FuncDetail::Value& ret = fd.getRet(0);
+    1931             :           uint32_t retKind = X86Reg::kindOf(ret.getRegType());
+    1932             : 
+    1933       95685 :           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       63790 :               RA_MERGE(vreg, tied, 0, 0);
+    1939             : 
+    1940       31895 :               if (retKind == vreg->getKind()) {
+    1941       31895 :                 tied->flags |= TiedReg::kRReg;
+    1942       31895 :                 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       63790 :         RA_FINALIZE(node_);
+    1957             : 
+    1958       31895 :         if (!next->hasPassData())
+    1959       31895 :           ASMJIT_PROPAGATE(addUnreachableNode(next));
+    1960       31895 :         goto _NextGroup;
+    1961             :       }
+    1962             : 
+    1963             :       // ----------------------------------------------------------------------
+    1964             :       // [Func-Call]
+    1965             :       // ----------------------------------------------------------------------
+    1966             : 
+    1967       12914 :       case CBNode::kNodeFuncCall: {
+    1968             :         CCFuncCall* node = static_cast<CCFuncCall*>(node_);
+    1969             :         FuncDetail& fd = node->getDetail();
+    1970             : 
+    1971       12914 :         Operand_* target = node->_opArray;
+    1972       12914 :         Operand_* args = node->_args;
+    1973       12914 :         Operand_* rets = node->_ret;
+    1974             : 
+    1975             :         func->getFrameInfo().enableCalls();
+    1976       12914 :         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       12914 :         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       12914 :           RA_MERGE(vreg, tied, 0, 0);
+    1994             : 
+    1995       12914 :           tied->flags |= TiedReg::kRReg | TiedReg::kRCall;
+    1996       12914 :           if (tied->inRegs == 0)
+    1997       12914 :             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       26342 :         for (i = 0; i < argCount; i++) {
+    2030       13428 :           Operand_* op = &args[i];
+    2031         804 :           if (!op->isVirtReg()) continue;
+    2032             : 
+    2033             :           vreg = cc()->getVirtRegById(op->getId());
+    2034             :           const FuncDetail::Value& arg = fd.getArg(i);
+    2035             : 
+    2036       12624 :           if (arg.byReg()) {
+    2037       25248 :             RA_MERGE(vreg, tied, 0, 0);
+    2038             : 
+    2039             :             uint32_t argClass = X86Reg::kindOf(arg.getRegType());
+    2040             : 
+    2041       12624 :             if (vreg->getKind() == argClass) {
+    2042       12624 :               tied->inRegs |= Utils::mask(arg.getRegId());
+    2043       12624 :               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       38742 :         for (i = 0; i < 2; i++) {
+    2063       25828 :           Operand_* op = &rets[i];
+    2064       12914 :           if (!op->isVirtReg()) continue;
+    2065             : 
+    2066             :           const FuncDetail::Value& ret = fd.getRet(i);
+    2067       12914 :           if (ret.byReg()) {
+    2068             :             uint32_t retKind = X86Reg::kindOf(ret.getRegType());
+    2069             : 
+    2070             :             vreg = cc()->getVirtRegById(op->getId());
+    2071       38742 :             RA_MERGE(vreg, tied, 0, 0);
+    2072             : 
+    2073       12914 :             if (vreg->getKind() == retKind) {
+    2074             :               tied->setOutPhysId(ret.getRegId());
+    2075       12914 :               tied->flags |= TiedReg::kWReg | TiedReg::kWFunc;
+    2076             :             }
+    2077             :             else {
+    2078             :               // TODO: Function-call return value conversion.
+    2079             :             }
+    2080             :           }
+    2081             :         }
+    2082             : 
+    2083             :         // Init clobbered.
+    2084       12914 :         clobberedRegs.set(X86Reg::kKindGp , Utils::bits(_regCount.getGp())  & (fd.getPassedRegs(X86Reg::kKindGp ) | ~fd.getPreservedRegs(X86Reg::kKindGp )));
+    2085       12914 :         clobberedRegs.set(X86Reg::kKindMm , Utils::bits(_regCount.getMm())  & (fd.getPassedRegs(X86Reg::kKindMm ) | ~fd.getPreservedRegs(X86Reg::kKindMm )));
+    2086       12914 :         clobberedRegs.set(X86Reg::kKindK  , Utils::bits(_regCount.getK())   & (fd.getPassedRegs(X86Reg::kKindK  ) | ~fd.getPreservedRegs(X86Reg::kKindK  )));
+    2087       12914 :         clobberedRegs.set(X86Reg::kKindVec, Utils::bits(_regCount.getVec()) & (fd.getPassedRegs(X86Reg::kKindVec) | ~fd.getPreservedRegs(X86Reg::kKindVec)));
+    2088             : 
+    2089       51366 :         RA_FINALIZE(node_);
+    2090             :         break;
+    2091             :       }
+    2092             :     }
+    2093             : 
+    2094             :     node_ = next;
+    2095      457884 :   } while (node_ != stop);
+    2096             : 
+    2097       31895 : _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       31895 :   if (!node_->hasPassData()) {
+    2102             :     CBLabel* fExit = func->getExitNode();
+    2103       31895 :     RA_POPULATE(fExit);
+    2104       31895 :     fExit->setPosition(++position);
+    2105             : 
+    2106       31895 :     RA_POPULATE(node_);
+    2107       31895 :     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       31895 :   ASMJIT_INLINE X86BaseAlloc(X86RAPass* context) {
+    2171       31895 :     _context = context;
+    2172       31895 :     _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       93506 :   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     4429310 :   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      337400 :   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      489779 :   _node = node;
+    2262      489779 :   _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      489779 :   _cc->_setCursor(node->getPrev());
+    2268             : 
+    2269             :   // Setup the lists of variables.
+    2270             :   {
+    2271             :     TiedReg* tied = raData->getTiedArray();
+    2272      489779 :     _tiedArray[X86Reg::kKindGp ] = tied;
+    2273      489779 :     _tiedArray[X86Reg::kKindMm ] = tied + raData->getTiedStart(X86Reg::kKindMm );
+    2274      489779 :     _tiedArray[X86Reg::kKindK  ] = tied + raData->getTiedStart(X86Reg::kKindK  );
+    2275      489779 :     _tiedArray[X86Reg::kKindVec] = tied + raData->getTiedStart(X86Reg::kKindVec);
+    2276             :   }
+    2277             : 
+    2278             :   // Setup counters.
+    2279      489779 :   _tiedTotal = raData->tiedTotal;
+    2280      489779 :   _tiedCount = raData->tiedCount;
+    2281             :   _tiedDone.reset();
+    2282             : 
+    2283             :   // Connect VREG->TIED.
+    2284     1276332 :   for (uint32_t i = 0; i < _tiedTotal; i++) {
+    2285      786553 :     TiedReg* tied = &_tiedArray[0][i];
+    2286      786553 :     VirtReg* vreg = tied->vreg;
+    2287      786553 :     vreg->_tied = tied;
+    2288             :   }
+    2289             : }
+    2290             : 
+    2291             : ASMJIT_INLINE void X86BaseAlloc::cleanup() {
+    2292             :   // Disconnect VREG->TIED.
+    2293     1244437 :   for (uint32_t i = 0; i < _tiedTotal; i++) {
+    2294      786553 :     TiedReg* tied = &_tiedArray[0][i];
+    2295      786553 :     VirtReg* vreg = tied->vreg;
+    2296      786553 :     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     1193071 :   for (uint32_t i = 0; i < tiedCount; i++) {
+    2315      748101 :     TiedReg* tied = &tiedArray[i];
+    2316      748101 :     if ((tied->flags & checkFlags) == TiedReg::kWReg)
+    2317      302198 :       _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     1244437 :   for (uint32_t i = 0; i < tiedCount; i++) {
+    2327      786553 :     TiedReg* tied = &tiedArray[i];
+    2328      786553 :     if (tied->flags & TiedReg::kUnuse)
+    2329      283217 :       _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       31895 :   ASMJIT_INLINE X86VarAlloc(X86RAPass* context) : X86BaseAlloc(context) {}
+    2346       31895 :   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      476865 : 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      476865 :   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      444970 :     if (node_->getType() == CBNode::kNodeInst) {
+    2445             :       CBInst* node = static_cast<CBInst*>(node_);
+    2446      413075 :       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      413075 :       ASMJIT_PROPAGATE(X86RAPass_translateOperands(_context, node->getOpArray(), node->getOpCount()));
+    2452             :     }
+    2453       31895 :     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      444970 :     _context->_clobberedRegs.or_(_willAlloc);
+    2505             :   }
+    2506             : 
+    2507             :   // Update clobbered mask.
+    2508      476865 :   _context->_clobberedRegs.or_(raData->clobberedRegs);
+    2509             : 
+    2510             :   // Unuse.
+    2511      476865 :   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      476865 :   _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      632805 :   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     1276236 :   for (i = 0; i < tiedCount; i++) {
+    2557      748101 :     TiedReg* tied = &tiedArray[i];
+    2558      748101 :     VirtReg* vreg = tied->vreg;
+    2559             : 
+    2560      748101 :     uint32_t vaFlags = tied->flags;
+    2561             :     uint32_t physId = vreg->getPhysId();
+    2562      748101 :     uint32_t regMask = (physId != Globals::kInvalidRegId) ? Utils::mask(physId) : 0;
+    2563             : 
+    2564      748101 :     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      748101 :       uint32_t mandatoryRegs = tied->inRegs;
+    2573      748101 :       uint32_t allocableRegs = tied->allocableRegs;
+    2574             : 
+    2575      748101 :       if (regMask != 0) {
+    2576             :         // Special path for planning output-only registers.
+    2577      395235 :         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      395235 :           if ((mandatoryRegs | allocableRegs) & regMask) {
+    2601             :             tied->setInPhysId(physId);
+    2602      382913 :             tied->flags |= TiedReg::kRDone;
+    2603             : 
+    2604      382913 :             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      363340 :               tied->inRegs |= regMask;
+    2611      363340 :               willAlloc |= regMask;
+    2612             :             }
+    2613             : 
+    2614             :             addTiedDone(C);
+    2615      382913 :             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      365188 :       willFree |= regMask;
+    2632      365188 :       continue;
+    2633      365188 :     }
+    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      528135 :   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     1276236 :   for (i = 0; i < tiedCount; i++) {
+    2655      748101 :     TiedReg* tied = &tiedArray[i];
+    2656      748101 :     VirtReg* vreg = tied->vreg;
+    2657      748101 :     uint32_t vaFlags = tied->flags;
+    2658             : 
+    2659      748101 :     if ((vaFlags & TiedReg::kXReg) != 0) {
+    2660      748101 :       if ((vaFlags & TiedReg::kXReg) == TiedReg::kWReg) {
+    2661      302198 :         if (vaFlags & TiedReg::kWDone)
+    2662           0 :           continue;
+    2663             : 
+    2664             :         // Skip all registers that have assigned outPhysId. Spill if occupied.
+    2665      302198 :         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      445903 :         if (vaFlags & TiedReg::kRDone)
+    2673      382913 :           continue;
+    2674             : 
+    2675             :         // We skip all registers that have assigned inPhysId, indicates that
+    2676             :         // the register to allocate in is known.
+    2677       62990 :         if (tied->hasInPhysId()) {
+    2678           0 :           uint32_t inRegs = tied->inRegs;
+    2679           0 :           willSpill |= occupied & inRegs;
+    2680           0 :           continue;
+    2681           0 :         }
+    2682             :       }
+    2683             : 
+    2684      365188 :       uint32_t m = tied->inRegs;
+    2685      365188 :       if (tied->hasOutPhysId())
+    2686           0 :         m |= Utils::mask(tied->outPhysId);
+    2687             : 
+    2688      365188 :       m = tied->allocableRegs & ~(willAlloc ^ m);
+    2689             :       m = guessAlloc<C>(vreg, m);
+    2690             :       ASMJIT_ASSERT(m != 0);
+    2691             : 
+    2692      365188 :       uint32_t candidateRegs = m & ~occupied;
+    2693             :       uint32_t homeMask = vreg->getHomeMask();
+    2694             : 
+    2695             :       uint32_t physId;
+    2696             :       uint32_t regMask;
+    2697             : 
+    2698      365188 :       if (candidateRegs == 0) {
+    2699       15478 :         candidateRegs = m & occupied & ~state->_modified.get(C);
+    2700       15478 :         if (candidateRegs == 0)
+    2701             :           candidateRegs = m;
+    2702             :       }
+    2703      365188 :       if (candidateRegs & homeMask) candidateRegs &= homeMask;
+    2704             : 
+    2705             :       physId = Utils::findFirstBit(candidateRegs);
+    2706             :       regMask = Utils::mask(physId);
+    2707             : 
+    2708      365188 :       if ((vaFlags & TiedReg::kXReg) == TiedReg::kWReg) {
+    2709             :         tied->setOutPhysId(physId);
+    2710             :       }
+    2711             :       else {
+    2712             :         tied->setInPhysId(physId);
+    2713       62990 :         tied->inRegs = regMask;
+    2714             :       }
+    2715             : 
+    2716      365188 :       willAlloc |= regMask;
+    2717      365188 :       willSpill |= regMask & occupied;
+    2718             :       willFree  &=~regMask;
+    2719      365188 :       occupied  |= regMask;
+    2720             : 
+    2721      365188 :       continue;
+    2722      365188 :     }
+    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      444970 :   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       15478 :     uint32_t bitIndex = Utils::findFirstBit(m) + 1;
+    2751             : 
+    2752       15478 :     i += bitIndex;
+    2753       15478 :     m >>= bitIndex;
+    2754             : 
+    2755       15478 :     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       15478 :     _context->spill<C>(vreg);
+    2778       15478 :   } while (m != 0);
+    2779             : }
+    2780             : 
+    2781             : template<int C>
+    2782             : ASMJIT_INLINE void X86VarAlloc::alloc() {
+    2783      549640 :   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      406840 :   do {
+    2793             :     didWork = false;
+    2794     1003113 :     for (i = 0; i < tiedCount; i++) {
+    2795      596273 :       TiedReg* aTied = &tiedArray[i];
+    2796      596273 :       VirtReg* aVReg = aTied->vreg;
+    2797             : 
+    2798      596273 :       if ((aTied->flags & (TiedReg::kRReg | TiedReg::kRDone)) != TiedReg::kRReg)
+    2799      533283 :         continue;
+    2800             : 
+    2801             :       uint32_t aPhysId = aVReg->getPhysId();
+    2802       62990 :       uint32_t bPhysId = aTied->inPhysId;
+    2803             : 
+    2804             :       // Shouldn't be the same.
+    2805             :       ASMJIT_ASSERT(aPhysId != bPhysId);
+    2806             : 
+    2807       62990 :       VirtReg* bVReg = getState()->getListByKind(C)[bPhysId];
+    2808       62990 :       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       62990 :       else if (aPhysId != Globals::kInvalidRegId) {
+    2831             :         _context->move<C>(aVReg, bPhysId);
+    2832             : 
+    2833       12322 :         aTied->flags |= TiedReg::kRDone;
+    2834             :         addTiedDone(C);
+    2835             : 
+    2836             :         didWork = true;
+    2837       12322 :         continue;
+    2838             :       }
+    2839             :       else {
+    2840             :         _context->alloc<C>(aVReg, bPhysId);
+    2841             : 
+    2842       50668 :         aTied->flags |= TiedReg::kRDone;
+    2843             :         addTiedDone(C);
+    2844             : 
+    2845             :         didWork = true;
+    2846       50668 :         continue;
+    2847             :       }
+    2848             :     }
+    2849             :   } while (didWork);
+    2850             : 
+    2851             :   // Alloc 'out' regs.
+    2852      826549 :   for (i = 0; i < tiedCount; i++) {
+    2853      482699 :     TiedReg* tied = &tiedArray[i];
+    2854      482699 :     VirtReg* vreg = tied->vreg;
+    2855             : 
+    2856      482699 :     if ((tied->flags & (TiedReg::kXReg | TiedReg::kWDone)) != TiedReg::kWReg)
+    2857      180501 :       continue;
+    2858             : 
+    2859      302198 :     uint32_t physId = tied->outPhysId;
+    2860             :     ASMJIT_ASSERT(physId != Globals::kInvalidRegId);
+    2861             : 
+    2862      302198 :     if (vreg->getPhysId() != physId) {
+    2863             :       ASMJIT_ASSERT(getState()->getListByKind(C)[physId] == nullptr);
+    2864      302198 :       _context->attach<C>(vreg, physId, false);
+    2865             :     }
+    2866             : 
+    2867      302198 :     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      352866 :   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      352866 :   CBNode* node = _node;
+    2891     2201255 :   for (i = 0; i < maxLookAhead; i++) {
+    2892             :     X86RAData* raData = node->getPassData<X86RAData>();
+    2893     2197435 :     RABits* liveness = raData ? raData->liveness : static_cast<RABits*>(nullptr);
+    2894             : 
+    2895             :     // If the variable becomes dead it doesn't make sense to continue.
+    2896     2197435 :     if (liveness && !liveness->getBit(raId)) break;
+    2897             : 
+    2898             :     // Stop on `CBSentinel` and `CCFuncRet`.
+    2899     1932570 :     if (node->hasFlag(CBNode::kFlagIsRet)) break;
+    2900             : 
+    2901             :     // Stop on conditional jump, we don't follow them.
+    2902     1932570 :     if (node->hasFlag(CBNode::kFlagIsJcc)) break;
+    2903             : 
+    2904             :     // Advance on non-conditional jump.
+    2905     1932570 :     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     1932570 :     if (raData) {
+    2916             :       TiedReg* tied = raData->findTiedByKind(C, vreg);
+    2917             :       uint32_t mask;
+    2918             : 
+    2919     1932570 :       if (tied) {
+    2920             :         // If the variable is overwritten it doesn't make sense to continue.
+    2921      402701 :         if ((tied->flags & TiedReg::kRAll) == 0)
+    2922             :           break;
+    2923             : 
+    2924      402701 :         mask = tied->allocableRegs;
+    2925      402701 :         if (mask != 0) {
+    2926      402701 :           allocableRegs &= mask;
+    2927      402701 :           if (allocableRegs == 0) break;
+    2928             :           safeRegs = allocableRegs;
+    2929             :         }
+    2930             : 
+    2931      388157 :         mask = tied->inRegs;
+    2932      388157 :         if (mask != 0) {
+    2933       26533 :           allocableRegs &= mask;
+    2934       26533 :           if (allocableRegs == 0) break;
+    2935             :           safeRegs = allocableRegs;
+    2936       26533 :           break;
+    2937             :         }
+    2938             : 
+    2939      361624 :         allocableRegs &= ~(raData->outRegs.get(C) | raData->clobberedRegs.get(C));
+    2940      361624 :         if (allocableRegs == 0) break;
+    2941             :       }
+    2942             :       else {
+    2943     1529869 :         allocableRegs &= ~(raData->inRegs.get(C) | raData->outRegs.get(C) | raData->clobberedRegs.get(C));
+    2944     1529869 :         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     1193071 :   for (uint32_t i = 0; i < tiedCount; i++) {
+    2971      748101 :     TiedReg* tied = &tiedArray[i];
+    2972             : 
+    2973      748101 :     if (tied->flags & TiedReg::kWReg) {
+    2974      412561 :       VirtReg* vreg = tied->vreg;
+    2975             : 
+    2976             :       uint32_t physId = vreg->getPhysId();
+    2977             :       uint32_t regMask = Utils::mask(physId);
+    2978             : 
+    2979             :       vreg->setModified(true);
+    2980      412561 :       _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       31895 :   ASMJIT_INLINE X86CallAlloc(X86RAPass* context) : X86BaseAlloc(context) {}
+    2998       31895 :   ASMJIT_INLINE ~X86CallAlloc() {}
+    2999             : 
+    3000             :   // --------------------------------------------------------------------------
+    3001             :   // [Accessors]
+    3002             :   // --------------------------------------------------------------------------
+    3003             : 
+    3004             :   //! Get the node.
+    3005       12914 :   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       12914 : 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       12914 :   ASMJIT_PROPAGATE(X86RAPass_translateOperands(_context, node->getOpArray(), node->getOpCount()));
+    3129             : 
+    3130             :   // To emit instructions after call.
+    3131       12914 :   _cc->_setCursor(node);
+    3132             : 
+    3133             :   // If the callee pops stack it has to be manually adjusted back.
+    3134             :   FuncDetail& fd = node->getDetail();
+    3135       12914 :   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       38742 :   uint32_t clobbered = _raData->clobberedRegs.get(C);
+    3185             : 
+    3186             :   uint32_t willAlloc = _willAlloc.get(C);
+    3187       38742 :   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       77194 :   for (i = 0; i < tiedCount; i++) {
+    3196       38452 :     TiedReg* tied = &tiedArray[i];
+    3197       38452 :     VirtReg* vreg = tied->vreg;
+    3198             : 
+    3199       38452 :     uint32_t vaFlags = tied->flags;
+    3200             :     uint32_t physId = vreg->getPhysId();
+    3201       38452 :     uint32_t regMask = (physId != Globals::kInvalidRegId) ? Utils::mask(physId) : 0;
+    3202             : 
+    3203       38452 :     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       25538 :       uint32_t inRegs = tied->inRegs;
+    3209             : 
+    3210       25538 :       if (inRegs == 0) {
+    3211       12914 :         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       25538 :       if ((regMask & inRegs) != 0 || ((regMask & ~clobbered) != 0 && (vaFlags & TiedReg::kUnuse) == 0)) {
+    3218             :         tied->setInPhysId(physId);
+    3219       22288 :         tied->flags |= TiedReg::kRDone;
+    3220             :         addTiedDone(C);
+    3221             :       }
+    3222             :       else {
+    3223        3250 :         willFree |= regMask;
+    3224             :       }
+    3225             :     }
+    3226             :     else {
+    3227             :       // Memory access - if variable is allocated it has to be freed.
+    3228       12914 :       if (regMask != 0) {
+    3229           0 :         willFree |= regMask;
+    3230             :       }
+    3231             :       else {
+    3232       12914 :         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       38742 :   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       77194 :   for (i = 0; i < tiedCount; i++) {
+    3247       38452 :     TiedReg* tied = &tiedArray[i];
+    3248       12914 :     VirtReg* vreg = tied->vreg;
+    3249             : 
+    3250       38452 :     uint32_t vaFlags = tied->flags;
+    3251       38452 :     if ((vaFlags & TiedReg::kRDone) != 0 || (vaFlags & TiedReg::kRReg) == 0)
+    3252       35202 :       continue;
+    3253             : 
+    3254             :     // All registers except Gp used by call itself must have inPhysId.
+    3255        3250 :     uint32_t m = tied->inRegs;
+    3256           0 :     if (C != X86Reg::kKindGp || m) {
+    3257             :       ASMJIT_ASSERT(m != 0);
+    3258             :       tied->setInPhysId(Utils::findFirstBit(m));
+    3259        3250 :       willSpill |= occupied & m;
+    3260        3250 :       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       12914 :   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         828 :     uint32_t bitIndex = Utils::findFirstBit(m) + 1;
+    3313             : 
+    3314         828 :     i += bitIndex;
+    3315         828 :     m >>= bitIndex;
+    3316             : 
+    3317         828 :     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         828 :     _context->spill<C>(vreg);
+    3333         828 :   } while (m != 0);
+    3334             : }
+    3335             : 
+    3336             : template<int C>
+    3337             : ASMJIT_INLINE void X86CallAlloc::alloc() {
+    3338       12914 :   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        6496 :   do {
+    3347             :     didWork = false;
+    3348       19548 :     for (i = 0; i < tiedCount; i++) {
+    3349       13052 :       TiedReg* aTied = &tiedArray[i];
+    3350       13052 :       VirtReg* aVReg = aTied->vreg;
+    3351       13052 :       if ((aTied->flags & (TiedReg::kRReg | TiedReg::kRDone)) != TiedReg::kRReg) continue;
+    3352             : 
+    3353             :       uint32_t sPhysId = aVReg->getPhysId();
+    3354        3254 :       uint32_t bPhysId = aTied->inPhysId;
+    3355             : 
+    3356             :       // Shouldn't be the same.
+    3357             :       ASMJIT_ASSERT(sPhysId != bPhysId);
+    3358             : 
+    3359        3254 :       VirtReg* bVReg = getState()->getListByKind(C)[bPhysId];
+    3360        3254 :       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        3250 :       else if (sPhysId != Globals::kInvalidRegId) {
+    3384             :         _context->move<C>(aVReg, bPhysId);
+    3385        2222 :         _context->_clobberedRegs.or_(C, Utils::mask(bPhysId));
+    3386             : 
+    3387        2222 :         aTied->flags |= TiedReg::kRDone;
+    3388             :         addTiedDone(C);
+    3389             : 
+    3390             :         didWork = true;
+    3391        2222 :         continue;
+    3392             :       }
+    3393             :       else {
+    3394             :         _context->alloc<C>(aVReg, bPhysId);
+    3395        1028 :         _context->_clobberedRegs.or_(C, Utils::mask(bPhysId));
+    3396             : 
+    3397        1028 :         aTied->flags |= TiedReg::kRDone;
+    3398             :         addTiedDone(C);
+    3399             : 
+    3400             :         didWork = true;
+    3401        1028 :         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       12914 :   Operand_* args = node->_args;
+    3417             : 
+    3418       26342 :   for (uint32_t i = 0; i < argCount; i++) {
+    3419       13428 :     Operand_& op = args[i];
+    3420       13428 :     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         804 :     if (arg.byReg()) {
+    3427         804 :       _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       51366 :   for (uint32_t i = 0; i < tiedCount; i++) {
+    3446       38452 :     TiedReg* tied = &tiedArray[i];
+    3447       38452 :     if ((tied->flags & TiedReg::kRReg) == 0) continue;
+    3448             : 
+    3449       25538 :     uint32_t inRegs = tied->inRegs;
+    3450       25538 :     if (!inRegs) continue;
+    3451             : 
+    3452       12624 :     VirtReg* vreg = tied->vreg;
+    3453             :     uint32_t physId = vreg->getPhysId();
+    3454             : 
+    3455             :     ASMJIT_ASSERT(physId != Globals::kInvalidRegId);
+    3456             : 
+    3457       12624 :     inRegs &= ~Utils::mask(physId);
+    3458       12624 :     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       38742 :   uint32_t affected = _raData->clobberedRegs.get(C) & state->_occupied.get(C) & state->_modified.get(C);
+    3551             : 
+    3552       55192 :   for (i = 0; affected != 0; i++, affected >>= 1) {
+    3553       42278 :     if (affected & 0x1) {
+    3554       33974 :       VirtReg* vreg = sVars[i];
+    3555             :       ASMJIT_ASSERT(vreg != nullptr);
+    3556             :       ASMJIT_ASSERT(vreg->isModified());
+    3557             : 
+    3558       33974 :       TiedReg* tied = vreg->_tied;
+    3559       33974 :       if (!tied || (tied->flags & (TiedReg::kWReg | TiedReg::kUnuse)) == 0)
+    3560       23678 :         _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       38742 :   uint32_t affected = _raData->clobberedRegs.get(C) & state->_occupied.get(C);
+    3576             : 
+    3577       74660 :   for (i = 0; affected != 0; i++, affected >>= 1) {
+    3578       61746 :     if (affected & 0x1) {
+    3579       46702 :       VirtReg* vreg = sVars[i];
+    3580             :       ASMJIT_ASSERT(vreg != nullptr);
+    3581             : 
+    3582       46702 :       TiedReg* tied = vreg->_tied;
+    3583             :       uint32_t vdState = VirtReg::kStateNone;
+    3584             : 
+    3585       46702 :       if (!vreg->isModified() || (tied && (tied->flags & (TiedReg::kWAll | TiedReg::kUnuse)) != 0))
+    3586             :         vdState = VirtReg::kStateMem;
+    3587       46702 :       _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       12914 :   Operand_* rets = node->_ret;
+    3600             : 
+    3601       38742 :   for (uint32_t i = 0; i < 2; i++) {
+    3602       25828 :     const FuncDetail::Value& ret = fd.getRet(i);
+    3603       25828 :     Operand_* op = &rets[i];
+    3604             : 
+    3605       25828 :     if (!ret.byReg() || !op->isVirtReg())
+    3606       12914 :       continue;
+    3607             : 
+    3608       12914 :     VirtReg* vreg = _cc->getVirtRegById(op->getId());
+    3609             :     uint32_t regId = ret.getRegId();
+    3610             : 
+    3611       12914 :     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       12914 :         if (X86Reg::kindOf(ret.getRegType()) == X86Reg::kKindVec) {
+    3624       12914 :           _context->unuse<X86Reg::kKindVec>(vreg);
+    3625       12914 :           _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      425989 : static Error X86RAPass_translateOperands(X86RAPass* self, Operand_* opArray, uint32_t opCount) {
+    3648             :   X86Compiler* cc = self->cc();
+    3649             : 
+    3650             :   // Translate variables into registers.
+    3651     1267323 :   for (uint32_t i = 0; i < opCount; i++) {
+    3652      841334 :     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      651229 :       op->_reg.id = vreg->getPhysId();
+    3658             :     }
+    3659      190105 :     else if (op->isMem()) {
+    3660             :       X86Mem* m = static_cast<X86Mem*>(op);
+    3661             : 
+    3662       83165 :       if (m->hasBaseReg() && cc->isVirtRegValid(m->getBaseId())) {
+    3663             :         VirtReg* vreg = cc->getVirtRegById(m->getBaseId());
+    3664             : 
+    3665       83165 :         if (m->isRegHome()) {
+    3666           0 :           self->getVarCell(vreg);
+    3667             :         }
+    3668             :         else {
+    3669             :           ASMJIT_ASSERT(vreg->getPhysId() != Globals::kInvalidRegId);
+    3670       83165 :           op->_mem.base = vreg->getPhysId();
+    3671             :         }
+    3672             :       }
+    3673             : 
+    3674       83165 :       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      425989 :   return kErrorOk;
+    3682             : }
+    3683             : 
+    3684             : // ============================================================================
+    3685             : // [asmjit::X86RAPass - TranslatePrologEpilog]
+    3686             : // ============================================================================
+    3687             : 
+    3688             : //! \internal
+    3689       31895 : 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       31895 :   ffi.setStackFrameSize(self->_memAllTotal);
+    3702       31895 :   ffi.setStackFrameAlignment(self->_memMaxAlign);
+    3703             : 
+    3704       31895 :   return kErrorOk;
+    3705             : }
+    3706             : 
+    3707             : //! \internal
+    3708       31895 : 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      660025 :     if (node->getType() == CBNode::kNodeInst) {
+    3714             :       CBInst* iNode = static_cast<CBInst*>(node);
+    3715             : 
+    3716      519531 :       if (iNode->hasMemOp()) {
+    3717             :         X86Mem* m = iNode->getMemOp<X86Mem>();
+    3718             : 
+    3719      174273 :         if (m->isArgHome()) {
+    3720             :           m->addOffsetLo32(layout.getStackArgsOffset());
+    3721             :           m->clearArgHome();
+    3722             :         }
+    3723             : 
+    3724      174273 :         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       91108 :           m->_setBase(cc->_nativeGpReg.getType(), self->_varBaseRegId);
+    3732       91108 :           m->addOffsetLo32(self->_varBaseOffset + cell->offset);
+    3733             :           m->clearRegHome();
+    3734             :         }
+    3735             :       }
+    3736             :     }
+    3737             : 
+    3738             :     node = node->getNext();
+    3739      660025 :   } while (node != stop);
+    3740             : 
+    3741       31895 :   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       31895 : 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       31895 :   if (raData) {
+    3793       31895 :     TiedReg* tiedArray = raData->tiedArray;
+    3794       31895 :     uint32_t tiedTotal = raData->tiedTotal;
+    3795             : 
+    3796       63790 :     for (uint32_t i = 0; i < tiedTotal; i++) {
+    3797       31895 :       TiedReg* tied = &tiedArray[i];
+    3798       31895 :       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       31895 :   while (node) {
+    3814       31895 :     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       31895 :       case CBNode::kNodeLabel:
+    3818       31895 :         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       31895 : 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      489779 :     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       31895 :       if (!jLink) {
+    3884       31895 :         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      489779 :     node_->_flags |= CBNode::kFlagIsTranslated;
+    3910             : 
+    3911      489779 :     if (node_->hasPassData()) {
+    3912      489779 :       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      457884 :           if (!node_->isJcc()) {
+    3945             :             X86RAData* raData = node_->getPassData<X86RAData>();
+    3946             :             RABits* liveness;
+    3947             : 
+    3948      457884 :             if (raData && next && next->hasPassData() && (liveness = next->getPassData<RAData>()->liveness)) {
+    3949      457884 :               TiedReg* tiedArray = raData->tiedArray;
+    3950      457884 :               uint32_t tiedTotal = raData->tiedTotal;
+    3951             : 
+    3952     1212542 :               for (uint32_t i = 0; i < tiedTotal; i++) {
+    3953      754658 :                 TiedReg* tied = &tiedArray[i];
+    3954      754658 :                 VirtReg* vreg = tied->vreg;
+    3955             : 
+    3956      754658 :                 if (!liveness->getBit(vreg->_raId) && !vreg->isFixed())
+    3957      283217 :                   tied->flags |= TiedReg::kUnuse;
+    3958             :               }
+    3959             :             }
+    3960             :           }
+    3961             : 
+    3962      457884 :           if (node_->getType() == CBNode::kNodeFuncCall) {
+    3963       12914 :             ASMJIT_PROPAGATE(cAlloc.run(static_cast<CCFuncCall*>(node_)));
+    3964             :             break;
+    3965             :           }
+    3966             :           ASMJIT_FALLTHROUGH;
+    3967             : 
+    3968             :         case CBNode::kNodeHint:
+    3969             :         case CBNode::kNodeFuncExit: {
+    3970      476865 :           ASMJIT_PROPAGATE(vAlloc.run(node_));
+    3971             : 
+    3972             :           // Handle conditional/unconditional jump.
+    3973      476865 :           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      476865 :           else if (node_->isRet()) {
+    4031       31895 :             ASMJIT_PROPAGATE(
+    4032             :               X86RAPass_translateRet(this, static_cast<CCFuncRet*>(node_), func->getExitNode()));
+    4033       31895 :             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      457884 :     if (next == stop)
+    4052           0 :       goto _NextGroup;
+    4053             :     node_ = next;
+    4054             :   }
+    4055             : 
+    4056             : _Done:
+    4057             :   {
+    4058       31895 :     ASMJIT_PROPAGATE(resolveCellOffsets());
+    4059       31895 :     ASMJIT_PROPAGATE(X86RAPass_prepareFuncFrame(this, func));
+    4060             : 
+    4061             :     FuncFrameLayout layout;
+    4062       31895 :     ASMJIT_PROPAGATE(layout.init(func->getDetail(), func->getFrameInfo()));
+    4063             : 
+    4064       31895 :     _varBaseRegId = layout._stackBaseRegId;
+    4065       31895 :     _varBaseOffset = layout._stackBaseOffset;
+    4066             : 
+    4067       31895 :     ASMJIT_PROPAGATE(X86RAPass_patchFuncMem(this, func, stop, layout));
+    4068             : 
+    4069             :     cc->_setCursor(func);
+    4070       31895 :     ASMJIT_PROPAGATE(FuncUtils::emitProlog(this->cc(), layout));
+    4071             : 
+    4072             :     cc->_setCursor(func->getExitNode());
+    4073       31895 :     ASMJIT_PROPAGATE(FuncUtils::emitEpilog(this->cc(), layout));
+    4074             :   }
+    4075             : 
+    4076       31895 :   return kErrorOk;
+    4077             : }
+    4078             : 
+    4079             : } // asmjit namespace
+    4080             : } // namespace PLMD
+    4081             : 
+    4082             : // [Api-End]
+    4083             : #include "./asmjit_apiend.h"
+    4084             : 
+    4085             : // [Guard]
+    4086             : #endif // ASMJIT_BUILD_X86 && !ASMJIT_DISABLE_COMPILER
+    4087             : #pragma GCC diagnostic pop
+    4088             : #endif // __PLUMED_HAS_ASMJIT
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86regalloc_p.h.func-sort-c.html b/coverage-libs/asmjit/x86regalloc_p.h.func-sort-c.html new file mode 100644 index 000000000000..6d82bf64c23b --- /dev/null +++ b/coverage-libs/asmjit/x86regalloc_p.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86regalloc_p.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86regalloc_p.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:344969.4 %
Date:2024-04-19 12:12:36Functions:00-
+
+ +
+ + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86regalloc_p.h.gcov.html b/coverage-libs/asmjit/x86regalloc_p.h.gcov.html new file mode 100644 index 000000000000..a0556294c4e2 --- /dev/null +++ b/coverage-libs/asmjit/x86regalloc_p.h.gcov.html @@ -0,0 +1,811 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86regalloc_p.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86regalloc_p.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:344969.4 %
Date:2024-04-19 12:12:36Functions: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     1107138 :   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      489779 :     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     1932570 :     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      786553 :     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     4240348 :     for (uint32_t i = 0; i < tiedCount; i++)
+     131     2710479 :       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       25828 :       case X86Reg::kKindGp : return _listGp;
+     237       25828 :       case X86Reg::kKindMm : return _listMm;
+     238      108094 :       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     1579432 :   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      553569 :     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      315112 :     _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      315112 :   }
+     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      334913 :     _x86State.getListByKind(C)[physId] = nullptr;
+     415             :     _x86State._occupied.andNot(C, regMask);
+     416             :     _x86State._modified.andNot(C, regMask);
+     417             : 
+     418             :     ASMJIT_X86_CHECK_STATE
+     419      334913 :   }
+     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       14544 :     uint32_t bothRegMask = newRegMask ^ oldRegMask;
+     437             : 
+     438             :     vreg->setPhysId(newPhysId);
+     439             : 
+     440       14544 :     _x86State.getListByKind(C)[oldPhysId] = nullptr;
+     441       14544 :     _x86State.getListByKind(C)[newPhysId] = vreg;
+     442             : 
+     443             :     _x86State._occupied.xor_(C, bothRegMask);
+     444       14544 :     _x86State._modified.xor_(C, bothRegMask & -static_cast<int32_t>(vreg->isModified()));
+     445             : 
+     446             :     ASMJIT_X86_CHECK_STATE
+     447       14544 :   }
+     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       23678 :     emitSave(vreg, physId, "Save");
+     483             :     vreg->setModified(false);
+     484             :     _x86State._modified.andNot(C, regMask);
+     485             : 
+     486             :     ASMJIT_X86_CHECK_STATE
+     487       23678 :   }
+     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       14544 :     if (newPhysId != oldPhysId) {
+     505       14544 :       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       51696 :     if (oldState != VirtReg::kStateReg) {
+     560       51696 :       if (oldState == VirtReg::kStateMem)
+     561       51696 :         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       51696 :     _x86State.getListByKind(C)[physId] = vreg;
+     580             :     _x86State._occupied.xor_(C, regMask);
+     581       51696 :     _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       16306 :     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       16306 :     if (vreg->isModified())
+     603       15734 :       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      645031 :     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       91108 :     (void)getVarCell(vreg);
+     667             :     return X86Mem(Init,
+     668             :       cc()->_nativeGpReg.getType(), vreg->getId(),
+     669             :       Reg::kRegNone, kInvalidValue,
+     670             :       0, 0, Mem::kSignatureMemRegHomeFlag);
+     671             :   }
+     672             : 
+     673             :   // --------------------------------------------------------------------------
+     674             :   // [Fetch]
+     675             :   // --------------------------------------------------------------------------
+     676             : 
+     677             :   virtual Error fetch() override;
+     678             : 
+     679             :   // --------------------------------------------------------------------------
+     680             :   // [Annotate]
+     681             :   // --------------------------------------------------------------------------
+     682             : 
+     683             :   virtual Error annotate() override;
+     684             : 
+     685             :   // --------------------------------------------------------------------------
+     686             :   // [Translate]
+     687             :   // --------------------------------------------------------------------------
+     688             : 
+     689             :   virtual Error translate() override;
+     690             : 
+     691             :   // --------------------------------------------------------------------------
+     692             :   // [Members]
+     693             :   // --------------------------------------------------------------------------
+     694             : 
+     695             :   //! Count of X86/X64 registers.
+     696             :   X86RegCount _regCount;
+     697             :   //! X86/X64 stack-pointer (esp or rsp).
+     698             :   X86Gp _zsp;
+     699             :   //! X86/X64 frame-pointer (ebp or rbp).
+     700             :   X86Gp _zbp;
+     701             : 
+     702             :   //! X86/X64 specific compiler state, linked to `_state`.
+     703             :   X86RAState _x86State;
+     704             :   //! Clobbered registers (for the whole function).
+     705             :   X86RegMask _clobberedRegs;
+     706             : 
+     707             :   //! Global allocable registers mask.
+     708             :   uint32_t _gaRegs[Globals::kMaxVRegKinds];
+     709             : 
+     710             :   bool _avxEnabled;
+     711             : 
+     712             :   //! Function variables base pointer (register).
+     713             :   uint8_t _varBaseRegId;
+     714             :   //! Function variables base offset.
+     715             :   int32_t _varBaseOffset;
+     716             : 
+     717             :   //! Temporary string builder used for logging.
+     718             :   StringBuilderTmp<256> _stringBuilder;
+     719             : };
+     720             : 
+     721             : //! \}
+     722             : 
+     723             : } // asmjit namespace
+     724             : } // namespace PLMD
+     725             : 
+     726             : // [Api-End]
+     727             : #include "./asmjit_apiend.h"
+     728             : 
+     729             : // [Guard]
+     730             : #endif // !ASMJIT_DISABLE_COMPILER
+     731             : #endif // _ASMJIT_X86_X86REGALLOC_P_H
+     732             : #pragma GCC diagnostic pop
+     733             : #endif // __PLUMED_HAS_ASMJIT
+     734             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/zone.cpp.func-sort-c.html b/coverage-libs/asmjit/zone.cpp.func-sort-c.html new file mode 100644 index 000000000000..eb9780f12af3 --- /dev/null +++ b/coverage-libs/asmjit/zone.cpp.func-sort-c.html @@ -0,0 +1,161 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/zone.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - zone.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:15529852.0 %
Date:2024-04-19 12:12:36Functions:142263.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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
_ZN4PLMD6asmjitL24ZoneHash_getClosestPrimeEj0
_ZN4PLMD6asmjit8ZoneHeap15_releaseDynamicEPvm168
_ZN4PLMD6asmjit12ZoneHashBase5resetEPNS0_8ZoneHeapE63790
_ZN4PLMD6asmjit14ZoneVectorBase7_resizeEPNS0_8ZoneHeapEmm63790
_ZN4PLMD6asmjit8ZoneHeap12_allocZeroedEmRm63790
_ZN4PLMD6asmjit4Zone6_allocEm129148
_ZN4PLMD6asmjit8ZoneHeap5resetEPNS0_4ZoneE159475
_ZN4PLMD6asmjit4ZoneC2Ejj191370
_ZN4PLMD6asmjit4ZoneD2Ev191370
_ZN4PLMD6asmjit14ZoneVectorBase5_growEPNS0_8ZoneHeapEmm266938
_ZN4PLMD6asmjit14ZoneVectorBase8_reserveEPNS0_8ZoneHeapEmm266938
_ZN4PLMD6asmjit4Zone5resetEb287055
_ZN4PLMD6asmjit4Zone11allocZeroedEm378902
_ZN4PLMD6asmjit4Zone3dupEPKvmb489779
_ZN4PLMD6asmjit8ZoneHeap6_allocEmRm1058786
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/zone.cpp.func.html b/coverage-libs/asmjit/zone.cpp.func.html new file mode 100644 index 000000000000..1802f5d91b8c --- /dev/null +++ b/coverage-libs/asmjit/zone.cpp.func.html @@ -0,0 +1,161 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/zone.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - zone.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:15529852.0 %
Date:2024-04-19 12:12:36Functions:142263.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit12ZoneHashBase4_delEPNS0_12ZoneHashNodeE0
_ZN4PLMD6asmjit12ZoneHashBase4_putEPNS0_12ZoneHashNodeE0
_ZN4PLMD6asmjit12ZoneHashBase5resetEPNS0_8ZoneHeapE63790
_ZN4PLMD6asmjit12ZoneHashBase7_rehashEj0
_ZN4PLMD6asmjit13ZoneBitVector4fillEmmb0
_ZN4PLMD6asmjit13ZoneBitVector7_appendEPNS0_8ZoneHeapEb0
_ZN4PLMD6asmjit13ZoneBitVector7_resizeEPNS0_8ZoneHeapEmmb0
_ZN4PLMD6asmjit14ZoneVectorBase5_growEPNS0_8ZoneHeapEmm266938
_ZN4PLMD6asmjit14ZoneVectorBase7_resizeEPNS0_8ZoneHeapEmm63790
_ZN4PLMD6asmjit14ZoneVectorBase8_reserveEPNS0_8ZoneHeapEmm266938
_ZN4PLMD6asmjit4Zone11allocZeroedEm378902
_ZN4PLMD6asmjit4Zone3dupEPKvmb489779
_ZN4PLMD6asmjit4Zone5resetEb287055
_ZN4PLMD6asmjit4Zone6_allocEm129148
_ZN4PLMD6asmjit4Zone7sformatEPKcz0
_ZN4PLMD6asmjit4ZoneC2Ejj191370
_ZN4PLMD6asmjit4ZoneD2Ev191370
_ZN4PLMD6asmjit8ZoneHeap12_allocZeroedEmRm63790
_ZN4PLMD6asmjit8ZoneHeap15_releaseDynamicEPvm168
_ZN4PLMD6asmjit8ZoneHeap5resetEPNS0_4ZoneE159475
_ZN4PLMD6asmjit8ZoneHeap6_allocEmRm1058786
_ZN4PLMD6asmjitL24ZoneHash_getClosestPrimeEj0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/zone.cpp.gcov.html b/coverage-libs/asmjit/zone.cpp.gcov.html new file mode 100644 index 000000000000..2ec9255534c9 --- /dev/null +++ b/coverage-libs/asmjit/zone.cpp.gcov.html @@ -0,0 +1,936 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/zone.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - zone.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:15529852.0 %
Date:2024-04-19 12:12:36Functions:142263.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             : // [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      191370 :   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      191370 : Zone::Zone(uint32_t blockSize, uint32_t blockAlignment) noexcept
+      64      191370 :   : _ptr(nullptr),
+      65      191370 :     _end(nullptr),
+      66      191370 :     _block(const_cast<Zone::Block*>(&Zone_zeroBlock)),
+      67      191370 :     _blockSize(blockSize),
+      68      191370 :     _blockAlignmentShift(Zone_getAlignmentOffsetFromAlignment(blockAlignment)) {}
+      69             : 
+      70      191370 : Zone::~Zone() noexcept {
+      71      191370 :   reset(true);
+      72      191370 : }
+      73             : 
+      74             : // ============================================================================
+      75             : // [asmjit::Zone - Reset]
+      76             : // ============================================================================
+      77             : 
+      78      287055 : void Zone::reset(bool releaseMemory) noexcept {
+      79      287055 :   Block* cur = _block;
+      80             : 
+      81             :   // Can't be altered.
+      82      287055 :   if (cur == &Zone_zeroBlock)
+      83             :     return;
+      84             : 
+      85      191370 :   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      127580 :     Block* next = cur->next;
+      89             :     do {
+      90      128824 :       Block* prev = cur->prev;
+      91             :       Internal::releaseMemory(cur);
+      92             :       cur = prev;
+      93      128824 :     } while (cur);
+      94             : 
+      95             :     cur = next;
+      96      127904 :     while (cur) {
+      97         324 :       next = cur->next;
+      98             :       Internal::releaseMemory(cur);
+      99             :       cur = next;
+     100             :     }
+     101             : 
+     102      127580 :     _ptr = nullptr;
+     103      127580 :     _end = nullptr;
+     104      127580 :     _block = const_cast<Zone::Block*>(&Zone_zeroBlock);
+     105             :   }
+     106             :   else {
+     107       64114 :     while (cur->prev)
+     108             :       cur = cur->prev;
+     109             : 
+     110       63790 :     _ptr = cur->data;
+     111       63790 :     _end = _ptr + cur->size;
+     112       63790 :     _block = cur;
+     113             :   }
+     114             : }
+     115             : 
+     116             : // ============================================================================
+     117             : // [asmjit::Zone - Alloc]
+     118             : // ============================================================================
+     119             : 
+     120      129148 : void* Zone::_alloc(size_t size) noexcept {
+     121      129148 :   Block* curBlock = _block;
+     122             :   uint8_t* p;
+     123             : 
+     124      129148 :   size_t blockSize = std::max<size_t>(_blockSize, size);
+     125      129148 :   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      129148 :   Block* next = curBlock->next;
+     136      129148 :   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      129148 :   if (ASMJIT_UNLIKELY(blockSize > (~static_cast<size_t>(0) - sizeof(Block) - blockAlignment)))
+     148             :     return nullptr;
+     149             : 
+     150      129148 :   blockSize += blockAlignment;
+     151      129148 :   Block* newBlock = static_cast<Block*>(Internal::allocMemory(sizeof(Block) + blockSize));
+     152             : 
+     153      129148 :   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      129148 :   p = Utils::alignTo(newBlock->data, blockAlignment);
+     160      129148 :   newBlock->prev = nullptr;
+     161      129148 :   newBlock->next = nullptr;
+     162      129148 :   newBlock->size = blockSize;
+     163             : 
+     164      129148 :   if (curBlock != &Zone_zeroBlock) {
+     165        1568 :     newBlock->prev = curBlock;
+     166        1568 :     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        1568 :     if (next) {
+     172           0 :       newBlock->next = next;
+     173           0 :       next->prev = newBlock;
+     174             :     }
+     175             :   }
+     176             : 
+     177      129148 :   _block = newBlock;
+     178      129148 :   _ptr = p + size;
+     179      129148 :   _end = newBlock->data + blockSize;
+     180             : 
+     181      129148 :   return static_cast<void*>(p);
+     182             : }
+     183             : 
+     184      378902 : void* Zone::allocZeroed(size_t size) noexcept {
+     185             :   void* p = alloc(size);
+     186      378902 :   if (ASMJIT_UNLIKELY(!p)) return p;
+     187      378902 :   return ::memset(p, 0, size);
+     188             : }
+     189             : 
+     190      489779 : void* Zone::dup(const void* data, size_t size, bool nullTerminate) noexcept {
+     191      489779 :   if (ASMJIT_UNLIKELY(!data || !size)) return nullptr;
+     192             : 
+     193             :   ASMJIT_ASSERT(size != IntTraits<size_t>::maxValue());
+     194      489779 :   uint8_t* m = allocT<uint8_t>(size + nullTerminate);
+     195      489779 :   if (ASMJIT_UNLIKELY(!m)) return nullptr;
+     196             : 
+     197             :   ::memcpy(m, data, size);
+     198      489779 :   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      159475 : void ZoneHeap::reset(Zone* zone) noexcept {
+     238             :   // Free dynamic blocks.
+     239      159475 :   DynamicBlock* block = _dynamicBlocks;
+     240      160587 :   while (block) {
+     241        1112 :     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      159475 :   _zone = zone;
+     249      159475 : }
+     250             : 
+     251             : // ============================================================================
+     252             : // [asmjit::ZoneHeap - Alloc / Release]
+     253             : // ============================================================================
+     254             : 
+     255     1058786 : 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     1057506 :     uint8_t* p = reinterpret_cast<uint8_t*>(_slots[slot]);
+     263     1057506 :     size = allocatedSize;
+     264             : 
+     265     1057506 :     if (p) {
+     266        9349 :       _slots[slot] = reinterpret_cast<Slot*>(p)->next;
+     267             :       //printf("ALLOCATED %p of size %d (SLOT %d)\n", p, int(size), slot);
+     268        9349 :       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     1048157 :     Zone* zone = _zone;
+     275             :     p = Utils::alignTo(zone->getCursor(), kBlockAlignment);
+     276     1048157 :     size_t remain = (p <= zone->getEnd()) ? (size_t)(zone->getEnd() - p) : size_t(0);
+     277             : 
+     278     1048157 :     if (ASMJIT_LIKELY(remain >= size)) {
+     279      983911 :       zone->setCursor(p + size);
+     280             :       //printf("ALLOCATED %p of size %d (SLOT %d)\n", p, int(size), slot);
+     281      983911 :       return p;
+     282             :     }
+     283             :     else {
+     284             :       // Distribute the remaining memory to suitable slots.
+     285       64246 :       if (remain >= kLoGranularity) {
+     286             :         do {
+     287         376 :           size_t distSize = std::min<size_t>(remain, kLoMaxSize);
+     288         376 :           uint32_t distSlot = static_cast<uint32_t>((distSize - kLoGranularity) / kLoGranularity);
+     289             :           ASMJIT_ASSERT(distSlot < kLoCount);
+     290             : 
+     291         376 :           reinterpret_cast<Slot*>(p)->next = _slots[distSlot];
+     292         376 :           _slots[distSlot] = reinterpret_cast<Slot*>(p);
+     293             : 
+     294         376 :           p += distSize;
+     295         376 :           remain -= distSize;
+     296         376 :         } while (remain >= kLoGranularity);
+     297             :         zone->setCursor(p);
+     298             :       }
+     299             : 
+     300       64246 :       p = static_cast<uint8_t*>(zone->_alloc(size));
+     301       64246 :       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        1280 :     if (ASMJIT_UNLIKELY(overhead >= ~static_cast<size_t>(0) - size))
+     316             :       return nullptr;
+     317             : 
+     318        1280 :     void* p = Internal::allocMemory(size + overhead);
+     319        1280 :     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        1280 :     DynamicBlock* next = _dynamicBlocks;
+     327             : 
+     328        1280 :     if (next)
+     329         168 :       next->prev = block;
+     330             : 
+     331        1280 :     block->prev = nullptr;
+     332        1280 :     block->next = next;
+     333        1280 :     _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        1280 :     p = Utils::alignTo(static_cast<uint8_t*>(p) + sizeof(DynamicBlock) + sizeof(DynamicBlock*), kBlockAlignment);
+     338        1280 :     reinterpret_cast<DynamicBlock**>(p)[-1] = block;
+     339             : 
+     340        1280 :     allocatedSize = size;
+     341             :     //printf("ALLOCATED DYNAMIC %p of size %d\n", p, int(size));
+     342        1280 :     return p;
+     343             :   }
+     344             : }
+     345             : 
+     346       63790 : void* ZoneHeap::_allocZeroed(size_t size, size_t& allocatedSize) noexcept {
+     347             :   ASMJIT_ASSERT(isInitialized());
+     348             : 
+     349       63790 :   void* p = _alloc(size, allocatedSize);
+     350       63790 :   if (ASMJIT_UNLIKELY(!p)) return p;
+     351       63790 :   return ::memset(p, 0, allocatedSize);
+     352             : }
+     353             : 
+     354         168 : 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         168 :   DynamicBlock* block = reinterpret_cast<DynamicBlock**>(p)[-1];
+     360             :   ASMJIT_ASSERT(ZoneHeap_hasDynamicBlock(this, block));
+     361             : 
+     362             :   // Unlink and free.
+     363         168 :   DynamicBlock* prev = block->prev;
+     364         168 :   DynamicBlock* next = block->next;
+     365             : 
+     366         168 :   if (prev)
+     367         168 :     prev->next = next;
+     368             :   else
+     369           0 :     _dynamicBlocks = next;
+     370             : 
+     371         168 :   if (next)
+     372           0 :     next->prev = prev;
+     373             : 
+     374             :   Internal::releaseMemory(block);
+     375         168 : }
+     376             : 
+     377             : // ============================================================================
+     378             : // [asmjit::ZoneVectorBase - Helpers]
+     379             : // ============================================================================
+     380             : 
+     381      266938 : Error ZoneVectorBase::_grow(ZoneHeap* heap, size_t sizeOfT, size_t n) noexcept {
+     382      266938 :   size_t threshold = Globals::kAllocThreshold / sizeOfT;
+     383      266938 :   size_t capacity = _capacity;
+     384      266938 :   size_t after = _length;
+     385             : 
+     386      266938 :   if (ASMJIT_UNLIKELY(IntTraits<size_t>::maxValue() - n < after))
+     387             :     return DebugUtils::errored(kErrorNoHeapMemory);
+     388             : 
+     389      266938 :   after += n;
+     390      266938 :   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      266938 :   if (capacity < 4)
+     398             :     capacity = 4;
+     399       75568 :   else if (capacity < 8)
+     400             :     capacity = 8;
+     401       23712 :   else if (capacity < 16)
+     402             :     capacity = 16;
+     403        5680 :   else if (capacity < 64)
+     404             :     capacity = 64;
+     405             :   else if (capacity < 256)
+     406             :     capacity = 256;
+     407             : 
+     408      267106 :   while (capacity < after) {
+     409         168 :     if (capacity < threshold)
+     410         168 :       capacity *= 2;
+     411             :     else
+     412           0 :       capacity += threshold;
+     413             :   }
+     414             : 
+     415      266938 :   return _reserve(heap, sizeOfT, capacity);
+     416             : }
+     417             : 
+     418      266938 : Error ZoneVectorBase::_reserve(ZoneHeap* heap, size_t sizeOfT, size_t n) noexcept {
+     419      266938 :   size_t oldCapacity = _capacity;
+     420      266938 :   if (oldCapacity >= n) return kErrorOk;
+     421             : 
+     422      266938 :   size_t nBytes = n * sizeOfT;
+     423      266938 :   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      266938 :   if (ASMJIT_UNLIKELY(!newData))
+     430             :     return DebugUtils::errored(kErrorNoHeapMemory);
+     431             : 
+     432      266938 :   void* oldData = _data;
+     433      266938 :   if (_length)
+     434       75568 :     ::memcpy(newData, oldData, _length * sizeOfT);
+     435             : 
+     436      266938 :   if (oldData)
+     437       75568 :     heap->release(oldData, oldCapacity * sizeOfT);
+     438             : 
+     439      266938 :   _capacity = allocatedBytes / sizeOfT;
+     440             :   ASMJIT_ASSERT(_capacity >= n);
+     441             : 
+     442      266938 :   _data = newData;
+     443      266938 :   return kErrorOk;
+     444             : }
+     445             : 
+     446       63790 : Error ZoneVectorBase::_resize(ZoneHeap* heap, size_t sizeOfT, size_t n) noexcept {
+     447       63790 :   size_t length = _length;
+     448       63790 :   if (_capacity < n) {
+     449       31895 :     ASMJIT_PROPAGATE(_grow(heap, sizeOfT, n - length));
+     450             :     ASMJIT_ASSERT(_capacity >= n);
+     451             :   }
+     452             : 
+     453       63790 :   if (length < n)
+     454       63790 :     ::memset(static_cast<uint8_t*>(_data) + length * sizeOfT, 0, (n - length) * sizeOfT);
+     455             : 
+     456       63790 :   _length = n;
+     457       63790 :   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       63790 : void ZoneHashBase::reset(ZoneHeap* heap) noexcept {
+     678       63790 :   ZoneHashNode** oldData = _data;
+     679       63790 :   if (oldData != _embedded)
+     680           0 :     _heap->release(oldData, _bucketsCount * sizeof(ZoneHashNode*));
+     681             : 
+     682       63790 :   _heap = heap;
+     683       63790 :   _size = 0;
+     684       63790 :   _bucketsCount = 1;
+     685       63790 :   _bucketsGrow = 1;
+     686       63790 :   _data = _embedded;
+     687       63790 :   _embedded[0] = nullptr;
+     688       63790 : }
+     689             : 
+     690             : // ============================================================================
+     691             : // [asmjit::ZoneHashBase - Rehash]
+     692             : // ============================================================================
+     693             : 
+     694           0 : void ZoneHashBase::_rehash(uint32_t newCount) noexcept {
+     695             :   ASMJIT_ASSERT(isInitialized());
+     696             : 
+     697           0 :   ZoneHashNode** oldData = _data;
+     698             :   ZoneHashNode** newData = reinterpret_cast<ZoneHashNode**>(
+     699           0 :     _heap->allocZeroed(static_cast<size_t>(newCount) * sizeof(ZoneHashNode*)));
+     700             : 
+     701             :   // We can still store nodes into the table, but it will degrade.
+     702           0 :   if (ASMJIT_UNLIKELY(newData == nullptr))
+     703             :     return;
+     704             : 
+     705             :   uint32_t i;
+     706           0 :   uint32_t oldCount = _bucketsCount;
+     707             : 
+     708           0 :   for (i = 0; i < oldCount; i++) {
+     709           0 :     ZoneHashNode* node = oldData[i];
+     710           0 :     while (node) {
+     711           0 :       ZoneHashNode* next = node->_hashNext;
+     712           0 :       uint32_t hMod = node->_hVal % newCount;
+     713             : 
+     714           0 :       node->_hashNext = newData[hMod];
+     715           0 :       newData[hMod] = node;
+     716             : 
+     717             :       node = next;
+     718             :     }
+     719             :   }
+     720             : 
+     721             :   // 90% is the maximum occupancy, can't overflow since the maximum capacity
+     722             :   // is limited to the last prime number stored in the prime table.
+     723           0 :   if (oldData != _embedded)
+     724           0 :     _heap->release(oldData, _bucketsCount * sizeof(ZoneHashNode*));
+     725             : 
+     726           0 :   _bucketsCount = newCount;
+     727           0 :   _bucketsGrow = newCount * 9 / 10;
+     728             : 
+     729           0 :   _data = newData;
+     730             : }
+     731             : 
+     732             : // ============================================================================
+     733             : // [asmjit::ZoneHashBase - Ops]
+     734             : // ============================================================================
+     735             : 
+     736           0 : ZoneHashNode* ZoneHashBase::_put(ZoneHashNode* node) noexcept {
+     737           0 :   uint32_t hMod = node->_hVal % _bucketsCount;
+     738           0 :   ZoneHashNode* next = _data[hMod];
+     739             : 
+     740           0 :   node->_hashNext = next;
+     741           0 :   _data[hMod] = node;
+     742             : 
+     743           0 :   if (++_size >= _bucketsGrow && next) {
+     744           0 :     uint32_t newCapacity = ZoneHash_getClosestPrime(_bucketsCount);
+     745           0 :     if (newCapacity != _bucketsCount)
+     746           0 :       _rehash(newCapacity);
+     747             :   }
+     748             : 
+     749           0 :   return node;
+     750             : }
+     751             : 
+     752           0 : ZoneHashNode* ZoneHashBase::_del(ZoneHashNode* node) noexcept {
+     753           0 :   uint32_t hMod = node->_hVal % _bucketsCount;
+     754             : 
+     755           0 :   ZoneHashNode** pPrev = &_data[hMod];
+     756           0 :   ZoneHashNode* p = *pPrev;
+     757             : 
+     758           0 :   while (p) {
+     759           0 :     if (p == node) {
+     760           0 :       *pPrev = p->_hashNext;
+     761           0 :       return node;
+     762             :     }
+     763             : 
+     764           0 :     pPrev = &p->_hashNext;
+     765           0 :     p = *pPrev;
+     766             :   }
+     767             : 
+     768             :   return nullptr;
+     769             : }
+     770             : 
+     771             : // ============================================================================
+     772             : // [asmjit::Zone - Test]
+     773             : // ============================================================================
+     774             : 
+     775             : #if defined(ASMJIT_TEST)
+     776             : UNIT(base_zonevector) {
+     777             :   Zone zone(8096 - Zone::kZoneOverhead);
+     778             :   ZoneHeap heap(&zone);
+     779             : 
+     780             :   int i;
+     781             :   int kMax = 100000;
+     782             : 
+     783             :   ZoneVector<int> vec;
+     784             : 
+     785             :   INFO("ZoneVector<int> basic tests");
+     786             :   EXPECT(vec.append(&heap, 0) == kErrorOk);
+     787             :   EXPECT(vec.isEmpty() == false);
+     788             :   EXPECT(vec.getLength() == 1);
+     789             :   EXPECT(vec.getCapacity() >= 1);
+     790             :   EXPECT(vec.indexOf(0) == 0);
+     791             :   EXPECT(vec.indexOf(-11) == Globals::kInvalidIndex);
+     792             : 
+     793             :   vec.clear();
+     794             :   EXPECT(vec.isEmpty());
+     795             :   EXPECT(vec.getLength() == 0);
+     796             :   EXPECT(vec.indexOf(0) == Globals::kInvalidIndex);
+     797             : 
+     798             :   for (i = 0; i < kMax; i++) {
+     799             :     EXPECT(vec.append(&heap, i) == kErrorOk);
+     800             :   }
+     801             :   EXPECT(vec.isEmpty() == false);
+     802             :   EXPECT(vec.getLength() == static_cast<size_t>(kMax));
+     803             :   EXPECT(vec.indexOf(kMax - 1) == static_cast<size_t>(kMax - 1));
+     804             : }
+     805             : 
+     806             : UNIT(base_ZoneBitVector) {
+     807             :   Zone zone(8096 - Zone::kZoneOverhead);
+     808             :   ZoneHeap heap(&zone);
+     809             : 
+     810             :   size_t i, count;
+     811             :   size_t kMaxCount = 100;
+     812             : 
+     813             :   ZoneBitVector vec;
+     814             :   EXPECT(vec.isEmpty());
+     815             :   EXPECT(vec.getLength() == 0);
+     816             : 
+     817             :   INFO("ZoneBitVector::resize()");
+     818             :   for (count = 1; count < kMaxCount; count++) {
+     819             :     vec.clear();
+     820             :     EXPECT(vec.resize(&heap, count, false) == kErrorOk);
+     821             :     EXPECT(vec.getLength() == count);
+     822             : 
+     823             :     for (i = 0; i < count; i++)
+     824             :       EXPECT(vec.getAt(i) == false);
+     825             : 
+     826             :     vec.clear();
+     827             :     EXPECT(vec.resize(&heap, count, true) == kErrorOk);
+     828             :     EXPECT(vec.getLength() == count);
+     829             : 
+     830             :     for (i = 0; i < count; i++)
+     831             :       EXPECT(vec.getAt(i) == true);
+     832             :   }
+     833             : 
+     834             :   INFO("ZoneBitVector::fill()");
+     835             :   for (count = 1; count < kMaxCount; count += 2) {
+     836             :     vec.clear();
+     837             :     EXPECT(vec.resize(&heap, count) == kErrorOk);
+     838             :     EXPECT(vec.getLength() == count);
+     839             : 
+     840             :     for (i = 0; i < (count + 1) / 2; i++) {
+     841             :       bool value = static_cast<bool>(i & 1);
+     842             :       EXPECT(vec.fill(i, count - i, value) == kErrorOk);
+     843             :     }
+     844             : 
+     845             :     for (i = 0; i < count; i++) {
+     846             :       EXPECT(vec.getAt(i) == static_cast<bool>(i & 1));
+     847             :     }
+     848             :   }
+     849             : }
+     850             : 
+     851             : #endif // ASMJIT_TEST
+     852             : 
+     853             : } // asmjit namespace
+     854             : } // namespace PLMD
+     855             : 
+     856             : // [Api-End]
+     857             : #include "./asmjit_apiend.h"
+     858             : #pragma GCC diagnostic pop
+     859             : #endif // __PLUMED_HAS_ASMJIT
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/zone.h.func-sort-c.html b/coverage-libs/asmjit/zone.h.func-sort-c.html new file mode 100644 index 000000000000..922ab11d0b71 --- /dev/null +++ b/coverage-libs/asmjit/zone.h.func-sort-c.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/zone.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - zone.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:759380.6 %
Date:2024-04-19 12:12:36Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit10ZoneVectorIPNS0_6CBPassEE6appendEPNS0_8ZoneHeapERKS3_31895
_ZN4PLMD6asmjit10ZoneVectorIPNS0_7VirtRegEE6appendEPNS0_8ZoneHeapERKS3_315112
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/zone.h.func.html b/coverage-libs/asmjit/zone.h.func.html new file mode 100644 index 000000000000..3eee27075f1f --- /dev/null +++ b/coverage-libs/asmjit/zone.h.func.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/zone.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - zone.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:759380.6 %
Date:2024-04-19 12:12:36Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit10ZoneVectorIPNS0_6CBPassEE6appendEPNS0_8ZoneHeapERKS3_31895
_ZN4PLMD6asmjit10ZoneVectorIPNS0_7VirtRegEE6appendEPNS0_8ZoneHeapERKS3_315112
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/zone.h.gcov.html b/coverage-libs/asmjit/zone.h.gcov.html new file mode 100644 index 000000000000..1363d17a97f3 --- /dev/null +++ b/coverage-libs/asmjit/zone.h.gcov.html @@ -0,0 +1,1234 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/zone.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - zone.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:759380.6 %
Date:2024-04-19 12:12:36Functions: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      129148 :   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     1048157 :   ASMJIT_INLINE uint8_t* getCursor() noexcept { return _ptr; }
+     125             :   //! Get the end of the current zone block, only useful if you use `getCursor()`.
+     126     1048157 :   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      983911 :     _ptr = p;
+     134         357 :   }
+     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     1557347 :     uint8_t* ptr = _ptr;
+     174     1557347 :     size_t remainingBytes = (size_t)(_end - ptr);
+     175             : 
+     176     1557347 :     if (ASMJIT_UNLIKELY(remainingBytes < size))
+     177       64902 :       return _alloc(size);
+     178             : 
+     179     1492445 :     _ptr += size;
+     180             :     ASMJIT_ASSERT(_ptr <= _end);
+     181             : 
+     182     1492445 :     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      347007 :     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       31895 :   ASMJIT_INLINE ZoneHeap() noexcept {
+     326             :     ::memset(this, 0, sizeof(*this));
+     327             :   }
+     328             :   //! Create a new `ZoneHeap` initialized to use `zone`.
+     329       63790 :   explicit ASMJIT_INLINE ZoneHeap(Zone* zone) noexcept {
+     330             :     ::memset(this, 0, sizeof(*this));
+     331       63790 :     _zone = zone;
+     332             :   }
+     333             :   //! Destroy the `ZoneHeap`.
+     334       63790 :   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       75568 :     if (size > kHiMaxSize)
+     372             :       return false;
+     373             : 
+     374       75400 :     if (size <= kLoMaxSize)
+     375       74288 :       slot = static_cast<uint32_t>((size - 1) / kLoGranularity);
+     376             :     else
+     377        1112 :       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     1058786 :     if (size > kHiMaxSize)
+     386             :       return false;
+     387             : 
+     388     1057506 :     if (size <= kLoMaxSize) {
+     389     1008297 :       slot = static_cast<uint32_t>((size - 1) / kLoGranularity);
+     390     1008297 :       allocatedSize = Utils::alignTo(size, kLoGranularity);
+     391             :     }
+     392             :     else {
+     393       49209 :       slot = static_cast<uint32_t>((size - kLoMaxSize - 1) / kHiGranularity) + kLoCount;
+     394       49209 :       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      728058 :     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      266938 :     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       63790 :     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       75400 :       static_cast<Slot*>(p)->next = static_cast<Slot*>(_slots[slot]);
+     465       75400 :       _slots[slot] = static_cast<Slot*>(p);
+     466             :     }
+     467             :     else {
+     468         168 :       _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       63790 :     ASMJIT_INLINE Link* getNext() const noexcept { return _next; }
+     499             :     //! Get value.
+     500       31895 :     ASMJIT_INLINE T getValue() const noexcept { return _value; }
+     501             :     //! Set value to `value`.
+     502       63790 :     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       31895 :   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      127580 :   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       31895 :     _first = nullptr;
+     555       31895 :     _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       63790 :     link->_next = nullptr;
+     566       63790 :     if (!_first)
+     567       63790 :       _first = link;
+     568             :     else
+     569           0 :       _last->_next = link;
+     570       63790 :     _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      127580 :     : _data(nullptr),
+     598      127580 :       _length(0),
+     599      127580 :       _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     1019819 :   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       95685 :     _data = nullptr;
+     622       95685 :     _length = 0;
+     623       95685 :     _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      191370 :   ASMJIT_INLINE T* getData() noexcept { return static_cast<T*>(_data); }
+     686             :   //! \overload
+     687     1757823 :   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      347007 :   Error append(ZoneHeap* heap, const T& item) noexcept {
+     722      347007 :     if (ASMJIT_UNLIKELY(_length == _capacity))
+     723       69679 :       ASMJIT_PROPAGATE(grow(heap, 1));
+     724             : 
+     725      347007 :     ::memcpy(static_cast<T*>(_data) + _length, &item, sizeof(T));
+     726             : 
+     727      347007 :     _length++;
+     728      347007 :     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      410797 :     ::memcpy(static_cast<T*>(_data) + _length, &item, sizeof(T));
+     767      378902 :     _length++;
+     768       31895 :   }
+     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      127580 :     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     1694033 :     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      235043 :   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       63790 :   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      442692 :     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       31895 :   ASMJIT_INLINE ZoneHashBase(ZoneHeap* heap) noexcept {
+    1068       31895 :     _heap = heap;
+    1069       31895 :     _size = 0;
+    1070       31895 :     _bucketsCount = 1;
+    1071       31895 :     _bucketsGrow = 1;
+    1072       31895 :     _data = _embedded;
+    1073       31895 :     _embedded[0] = nullptr;
+    1074             :   }
+    1075       31895 :   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       31895 :   ASMJIT_INLINE ~ZoneHash() noexcept {}
+    1130             : 
+    1131             :   template<typename Key>
+    1132             :   ASMJIT_INLINE Node* get(const Key& key) const noexcept {
+    1133           0 :     uint32_t hMod = key.hVal % _bucketsCount;
+    1134           0 :     Node* node = static_cast<Node*>(_data[hMod]);
+    1135             : 
+    1136           0 :     while (node && !key.matches(node))
+    1137           0 :       node = static_cast<Node*>(node->_hashNext);
+    1138             :     return node;
+    1139             :   }
+    1140             : 
+    1141           0 :   ASMJIT_INLINE Node* put(Node* node) noexcept { return static_cast<Node*>(_put(node)); }
+    1142             :   ASMJIT_INLINE Node* del(Node* node) noexcept { return static_cast<Node*>(_del(node)); }
+    1143             : };
+    1144             : 
+    1145             : //! \}
+    1146             : 
+    1147             : } // asmjit namespace
+    1148             : } // namespace PLMD
+    1149             : 
+    1150             : // [Api-End]
+    1151             : #include "./asmjit_apiend.h"
+    1152             : 
+    1153             : // [Guard]
+    1154             : #endif // _ASMJIT_BASE_ZONE_H
+    1155             : #pragma GCC diagnostic pop
+    1156             : #endif // __PLUMED_HAS_ASMJIT
+    1157             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/blas/blas.cpp.func-sort-c.html b/coverage-libs/blas/blas.cpp.func-sort-c.html new file mode 100644 index 000000000000..f15867d33ac1 --- /dev/null +++ b/coverage-libs/blas/blas.cpp.func-sort-c.html @@ -0,0 +1,217 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - blas/blas.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - blas - blas.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:406160525.3 %
Date:2024-04-19 12:12:36Functions: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
_ZN4PLMD4blas5drot_EPiPdS1_S2_S1_S2_S2_360
_ZN4PLMD4blas6dtrmm_EPKcS2_S2_S2_PiS3_PdS4_S3_S4_S3_411
_ZN4PLMD4blas6dgemm_EPKcS2_PiS3_S3_PdS4_S3_S4_S3_S4_S4_S3_504
_ZN4PLMD4blas6dswap_EPiPdS1_S2_S1_5610
_ZN4PLMD4blas7idamax_EPiPdS1_33025
_ZN4PLMD4blas6dtrmv_EPKcS2_S2_PiPdS3_S4_S3_36253
_ZN4PLMD4blas6dsyr2_EPKcPiPdS4_S3_S4_S3_S4_S3_1212317
_ZN4PLMD4blas6dsymv_EPKcPiPdS4_S3_S4_S3_S4_S4_S3_1212830
_ZN4PLMD4blas5ddot_EPiPdS1_S2_S1_1212831
_ZN4PLMD4blas6dnrm2_EPiPdS1_1224260
_ZN4PLMD4blas5dger_EPiS1_PdS2_S1_S2_S1_S2_S1_1234902
_ZN4PLMD4blas6dgemv_EPKcPiS3_PdS4_S3_S4_S3_S4_S4_S3_1246470
_ZN4PLMD4blas6daxpy_EPiPdS2_S1_S2_S1_1499402
_ZN4PLMD4blas6dscal_EPiPdS2_S1_2080508
_ZN4PLMD4blas6dcopy_EPiPdS1_S2_S1_4343802
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/blas/blas.cpp.func.html b/coverage-libs/blas/blas.cpp.func.html new file mode 100644 index 000000000000..028ba5c5a31e --- /dev/null +++ b/coverage-libs/blas/blas.cpp.func.html @@ -0,0 +1,217 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - blas/blas.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - blas - blas.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:406160525.3 %
Date:2024-04-19 12:12:36Functions:173647.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4blas5ddot_EPiPdS1_S2_S1_1212831
_ZN4PLMD4blas5dger_EPiS1_PdS2_S1_S2_S1_S2_S1_1234902
_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_1499402
_ZN4PLMD4blas6dcopy_EPiPdS1_S2_S1_4343802
_ZN4PLMD4blas6dgemm_EPKcS2_PiS3_S3_PdS4_S3_S4_S3_S4_S4_S3_504
_ZN4PLMD4blas6dgemv_EPKcPiS3_PdS4_S3_S4_S3_S4_S4_S3_1246470
_ZN4PLMD4blas6dnrm2_EPiPdS1_1224260
_ZN4PLMD4blas6dscal_EPiPdS2_S1_2080508
_ZN4PLMD4blas6dswap_EPiPdS1_S2_S1_5610
_ZN4PLMD4blas6dsymv_EPKcPiPdS4_S3_S4_S3_S4_S4_S3_1212830
_ZN4PLMD4blas6dsyr2_EPKcPiPdS4_S3_S4_S3_S4_S3_1212317
_ZN4PLMD4blas6dtrmm_EPKcS2_S2_S2_PiS3_PdS4_S3_S4_S3_411
_ZN4PLMD4blas6dtrmv_EPKcS2_S2_PiPdS3_S4_S3_36253
_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_33025
_ZN4PLMD4blas7isamax_EPiPfS1_0
_ZN4PLMD4blas7ssyr2k_EPKcS2_PiS3_PfS4_S3_S4_S3_S4_S4_S3_0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/blas/blas.cpp.gcov.html b/coverage-libs/blas/blas.cpp.gcov.html new file mode 100644 index 000000000000..72936cdaa525 --- /dev/null +++ b/coverage-libs/blas/blas.cpp.gcov.html @@ -0,0 +1,3767 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - blas/blas.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - blas - blas.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:406160525.3 %
Date:2024-04-19 12:12:36Functions: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     1499402 : 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     1499402 :   int n=*n_arg;
+      97     1499402 :   double da=*da_arg;
+      98     1499402 :   int incx = *incx_arg;
+      99     1499402 :   int incy = *incy_arg;
+     100             : 
+     101     1499402 :   if (n<=0)
+     102             :     return;
+     103             : 
+     104     1499402 :   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     8571584 :     for(i=0;i<(n-4);i+=4) {
+     122     7072182 :       dy[i]   += da*dx[i];
+     123     7072182 :       dy[i+1] += da*dx[i+1];
+     124     7072182 :       dy[i+2] += da*dx[i+2];
+     125     7072182 :       dy[i+3] += da*dx[i+3];
+     126             :     }
+     127             :     /* continue with current value of i */
+     128     5256998 :     for(;i<n;i++)
+     129     3757596 :       dy[i]   += da*dx[i];
+     130             :   }
+     131             : }
+     132             : }
+     133             : }
+     134             : #include "blas.h"
+     135             : 
+     136             : namespace PLMD{
+     137             : namespace blas{
+     138             : void
+     139     4343802 : 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     4343802 :     int n= *n__;
+     148     4343802 :     int incx = *incx__;
+     149     4343802 :     int incy = *incy__;
+     150             :     
+     151             : 
+     152     4343802 :     if(incx!=1 || incy!=1) {
+     153             :         ix = 0;
+     154             :         iy = 0;
+     155        5884 :         if(incx<0)
+     156           0 :             ix = (1-n)*(incx);
+     157        5884 :         if(incy<0)
+     158           0 :             iy = (1-n)*(incy);
+     159             :         
+     160     1156404 :         for(i=0;i<n;i++,ix+=incx,iy+=incy) 
+     161     1150520 :             dy[iy] = dx[ix];
+     162             :         
+     163             :         return;
+     164             :         
+     165             :     } else {
+     166             :         
+     167             :         /* unroll */
+     168             :         
+     169     4445039 :         for(i=0;i<(n-8);i+=8) {
+     170      107121 :             dy[i]   = dx[i];
+     171      107121 :             dy[i+1] = dx[i+1];
+     172      107121 :             dy[i+2] = dx[i+2];
+     173      107121 :             dy[i+3] = dx[i+3];
+     174      107121 :             dy[i+4] = dx[i+4];
+     175      107121 :             dy[i+5] = dx[i+5];
+     176      107121 :             dy[i+6] = dx[i+6];
+     177      107121 :             dy[i+7] = dx[i+7];
+     178             :         }
+     179             :         /* continue with current value of i */
+     180    18006177 :         for(;i<n;i++)
+     181    13668259 :             dy[i] = dx[i];
+     182             :     }
+     183             : }
+     184             : }
+     185             : }
+     186             : #include "blas.h"
+     187             : 
+     188             : namespace PLMD{
+     189             : namespace blas{
+     190             : double
+     191     1212831 : 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     1212831 :     int n=*n_arg;
+     199     1212831 :     int incx = *incx_arg;
+     200     1212831 :     int incy = *incy_arg;
+     201             :     double t1;
+     202             :     
+     203     1212831 :     if(n<=0)
+     204             :         return 0.0;
+     205             :     
+     206             :     t1 = 0.0;
+     207             :     
+     208     1212831 :     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     1212831 :         m = n%5;
+     224             :         
+     225     4243659 :         for(i=0;i<m;i++)
+     226     3030828 :             t1 += dx[i] * dy[i];
+     227             :         
+     228             :         /* unroll */
+     229     1249152 :         for(i=m;i<n;i+=5) 
+     230       36321 :             t1  =  t1 + dx[i] * dy[i]   
+     231       36321 :                 +    dx[i+1] * dy[i+1] 
+     232       36321 :                 +    dx[i+2] * dy[i+2] 
+     233       36321 :                 +    dx[i+3] * dy[i+3]   
+     234       36321 :                 +    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         504 : 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         504 :   const char tra=std::toupper(*transa);
+     268         504 :   const char trb=std::toupper(*transb);
+     269             :   double temp;
+     270             :   int i,j,l;
+     271             : 
+     272         504 :   int m = *m__;
+     273         504 :   int n = *n__;
+     274         504 :   int k = *k__;
+     275         504 :   int lda = *lda__;
+     276         504 :   int ldb = *ldb__;
+     277         504 :   int ldc = *ldc__;
+     278             :   
+     279         504 :   double alpha = *alpha__;
+     280         504 :   double beta  = *beta__;
+     281             :   
+     282         504 :   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         455 :   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         455 :   if(trb=='N') {
+     300         346 :     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        2098 :       for(j=0;j<n;j++) {
+     321      579738 :         for(i=0;i<m;i++) {
+     322             :           temp = 0.0;
+     323   125807406 :           for(l=0;l<k;l++) 
+     324   125229696 :             temp += a[i*(lda)+l] * b[j*(ldb)+l];
+     325      577710 :           if(std::abs(beta)<PLUMED_GMX_DOUBLE_MIN)
+     326           0 :             c[j*(ldc)+i] = alpha * temp;
+     327             :           else
+     328      577710 :             c[j*(ldc)+i] = alpha * temp + beta * c[j*(ldc)+i];
+     329             :         }
+     330             :       }
+     331             :     }
+     332             :   } else {
+     333             :     /* transpose B */
+     334         109 :     if(tra=='N') {
+     335             : 
+     336             :       /* transpose B, but not A */
+     337             : 
+     338       23285 :       for(j=0;j<n;j++) {
+     339       23176 :         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       23176 :         } 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      831190 :         for(l=0;l<k;l++) {
+     347      808014 :           if( std::abs(b[ l*(ldb) + j ])>PLUMED_GMX_DOUBLE_MIN) {
+     348      701310 :             temp = alpha * b[ l*(ldb) + j ];
+     349   207288274 :             for(i=0;i<m;i++)
+     350   206586964 :               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     1246470 : 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     1246470 :   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     1246470 :   int m = *m__;
+     401     1246470 :   int n = *n__;
+     402     1246470 :   double alpha = *alpha__;
+     403     1246470 :   double beta = *beta__;
+     404     1246470 :   int incx = *incx__;
+     405     1246470 :   int incy = *incy__;
+     406     1246470 :   int lda = *lda__;
+     407             :   
+     408     1246470 :   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     1246278 :   if(ch=='N') {
+     412             :     lenx = n;
+     413             :     leny = m;
+     414             :   } else {
+     415             :     lenx = m;
+     416             :     leny = n;
+     417             :   }
+     418             :   
+     419     1246278 :    if(incx>0)
+     420             :     kx = 1;
+     421             :   else
+     422           0 :     kx = 1 - (lenx -1)*(incx);
+     423             : 
+     424     1246278 :   if(incy>0)
+     425             :     ky = 1;
+     426             :   else
+     427           0 :     ky = 1 - (leny -1)*(incy);
+     428             :  
+     429     1246278 :   if(std::abs(beta-1.0)>PLUMED_GMX_DOUBLE_EPS) {
+     430     1224788 :     if(incy==1) {
+     431     1224788 :       if(std::abs(beta)<PLUMED_GMX_DOUBLE_MIN)
+     432     3246324 :         for(i=0;i<leny;i++)
+     433     2021536 :           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     1246278 :   if(std::abs(alpha)<PLUMED_GMX_DOUBLE_MIN)
+     450             :     return;
+     451             :   
+     452     1246278 :   if(ch=='N') {
+     453             :     jx = kx;
+     454       25782 :     if(incy==1) {
+     455      507312 :       for(j=1;j<=n;j++,jx+=incx) 
+     456      481914 :         if(std::abs(x[jx-1])>PLUMED_GMX_DOUBLE_MIN) {
+     457      481914 :           temp = alpha * x[jx-1];
+     458    63089969 :           for(i=1;i<=m;i++)
+     459    62608055 :             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     1220496 :     if(incx==1) {
+     475     3148028 :       for(j=1;j<=n;j++,jy+=incy) {
+     476             :         temp = 0.0;
+     477    62061861 :         for(i=1;i<=m;i++)
+     478    60133573 :           temp += a[(j-1)*(lda)+(i-1)] * x[i-1];
+     479     1928288 :         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     1234902 : 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     1234902 :     int m = *m__;
+     521     1234902 :     int n = *n__;
+     522     1234902 :     int incx = *incx__;
+     523     1234902 :     int incy = *incy__;
+     524     1234902 :     int lda = *lda__;
+     525     1234902 :     double alpha = *alpha__;
+     526             :     
+     527     1234902 :     if(m<=0 || n<=0 || std::abs(alpha)<PLUMED_GMX_DOUBLE_MIN)
+     528             :         return;
+     529             :     
+     530     1234902 :     if(incy>0)
+     531             :         jy = 0;
+     532             :     else
+     533           0 :         jy = incy * (1 - n);
+     534             :     
+     535     1234902 :     if(incx==1) {
+     536     2935394 :         for(j=0;j<n;j++,jy+=incy)
+     537     1700492 :             if(std::abs(y[jy])>PLUMED_GMX_DOUBLE_MIN) {
+     538     1700482 :                 temp = alpha * y[jy];
+     539     8457968 :                 for(i=0;i<m;i++)
+     540     6757486 :                     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     1224260 : 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     1224260 :     int n = *n__;
+     578     1224260 :     int incx = *incx__;
+     579             :     
+     580     1224260 :     if(n<1 || incx<1)
+     581             :         return 0;
+     582     1224260 :     else if (n==1) {
+     583      605873 :         t = x[0];
+     584      605873 :         if(t>=0)
+     585             :             return t;
+     586             :         else 
+     587      454249 :             return -t;
+     588             :     }
+     589             :     
+     590             :     scale = 0.0;
+     591             :     ssq   = 1.0;
+     592             :     
+     593      618387 :     max_ix = 1+(n-1)*(incx);
+     594     3154849 :     for(ix=1;ix<=max_ix;ix+=incx) {
+     595     2536462 :         t = x[ix-1];
+     596     2536462 :         if(std::abs(t)>PLUMED_GMX_DOUBLE_MIN) {
+     597     2534273 :             absxi = (t>=0) ? t : (-t);
+     598     2534273 :             if(scale<absxi) {
+     599      893323 :                 t = scale/absxi;
+     600      893323 :                 t = t*t;
+     601      893323 :                 ssq = ssq*t + 1.0;
+     602             :                 scale = absxi;
+     603             :             } else {
+     604     1640950 :                 t = absxi/scale;
+     605     1640950 :                 ssq += t*t;
+     606             :             }
+     607             :         }
+     608             :     }
+     609      618387 :     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     2080508 : PLUMED_BLAS_F77_FUNC(dscal,DSCAL)(int  *    n__,
+     674             :                       double *   fact__,
+     675             :                       double *   dx,
+     676             :                       int    *   incx__)
+     677             : {
+     678             :     int nincx,i;
+     679             : 
+     680     2080508 :     int n = *n__;
+     681     2080508 :     double fact = *fact__;
+     682     2080508 :     int incx = *incx__;
+     683             :     
+     684     2080508 :     if(n<=0 || incx<=0)
+     685             :         return;
+     686             :     
+     687     2063997 :     if(incx==1) {
+     688             :         /* Unrool factor 5 */
+     689     2247018 :         for(i=0;i<(n-5);i+=5) {
+     690      185904 :             dx[i]   *= fact;
+     691      185904 :             dx[i+1] *= fact;
+     692      185904 :             dx[i+2] *= fact;
+     693      185904 :             dx[i+3] *= fact;
+     694      185904 :             dx[i+4] *= fact;
+     695             :         }    
+     696             :         /* continue with current value of i */
+     697     7117064 :         for(;i<n;i++)
+     698     5055950 :             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        5610 : 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        5610 :   int n = *n__;
+     728        5610 :   int incx = *incx__;
+     729        5610 :   int incy = *incy__;
+     730             :   
+     731        5610 :   if(n<=0)
+     732             :     return;
+     733             : 
+     734        5610 :   if(incx==1 && incy==1) {
+     735       75761 :     for(i=0;i<(n-3);i+=3) {
+     736       72777 :       d1      = dx[i];
+     737       72777 :       d2      = dx[i+1];
+     738       72777 :       d3      = dx[i+2];
+     739       72777 :       dx[i]   = dy[i];
+     740       72777 :       dx[i+1] = dy[i+1];
+     741       72777 :       dx[i+2] = dy[i+2];
+     742       72777 :       dy[i]   = d1;
+     743       72777 :       dy[i+1] = d2;
+     744       72777 :       dy[i+2] = d3;
+     745             :     }
+     746             :     /* continue with last i value */
+     747        8589 :     for(;i<n;i++) {
+     748        5605 :       d1      = dx[i];
+     749        5605 :       dx[i]   = dy[i];
+     750        5605 :       dy[i]   = d1;
+     751             :     }
+     752             : 
+     753             :   } else {
+     754             :     ix = 0;
+     755             :     iy = 0;
+     756        2626 :     if(incx<0)
+     757           0 :       ix = incx * (1 - n);
+     758        2626 :     if(incy<0)
+     759           0 :       iy = incy * (1 - n);
+     760             : 
+     761      195121 :     for(i=0;i<n;i++,ix+=incx,iy+=incy) {
+     762      192495 :       d1     = dx[ix];
+     763      192495 :       dx[ix] = dy[iy];
+     764      192495 :       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     1212830 : 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     1212830 :     const char ch=std::toupper(*uplo);
+     793             :     int kx,ky,i,j,ix,iy,jx,jy;
+     794             :     double temp1,temp2;
+     795             :     
+     796     1212830 :     int n = *n__;
+     797     1212830 :     int lda = *lda__;
+     798     1212830 :     int incx = *incx__;
+     799     1212830 :     int incy = *incy__;
+     800     1212830 :     double alpha = *alpha__;
+     801     1212830 :     double beta  = *beta__;
+     802             :     
+     803     1212830 :     if(n<=0 || incx==0 || incy==0)
+     804             :         return;
+     805             :     
+     806     1212830 :     if(incx>0)
+     807             :         kx = 1;
+     808             :     else
+     809           0 :         kx = 1 - (n -1)*(incx);
+     810             :     
+     811     1212830 :     if(incy>0)
+     812             :         ky = 1;
+     813             :     else
+     814           0 :         ky = 1 - (n -1)*(incy);
+     815             :     
+     816     1212830 :     if(std::abs(beta-1.0)>PLUMED_GMX_DOUBLE_EPS) {
+     817     1212830 :         if(incy==1) {
+     818     1212830 :             if(std::abs(beta)<PLUMED_GMX_DOUBLE_MIN) 
+     819     4425258 :                 for(i=1;i<=n;i++)
+     820     3212428 :                     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     1212830 :         if(std::abs(alpha)<PLUMED_GMX_DOUBLE_MIN) 
+     841             :             return;
+     842             :         
+     843     1212830 :         if(ch=='U') {
+     844     1212830 :             if(incx==1 && incy==1) {
+     845     4425258 :                 for(j=1;j<=n;j++) {
+     846     3212428 :                     temp1 = alpha * x[j-1];
+     847             :                     temp2 = 0.0;
+     848    29667836 :                     for(i=1;i<j;i++) {
+     849    26455408 :                         y[i-1] += temp1*a[(j-1)*(lda)+(i-1)];
+     850    26455408 :                         temp2 += a[(j-1)*(lda)+(i-1)] * x[i-1];
+     851             :                     }
+     852     3212428 :                     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     1212317 : 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     1212317 :     const char ch=std::toupper(*uplo);
+     936             :     
+     937     1212317 :     int n = *n__;
+     938     1212317 :     int lda = *lda__;
+     939     1212317 :     int incx = *incx__;
+     940     1212317 :     int incy = *incy__;
+     941     1212317 :     float alpha = *alpha__;
+     942             :     
+     943             :     
+     944     1212317 :     if(n<=0 || std::abs(alpha)<PLUMED_GMX_DOUBLE_MIN || incx==0 || incy==0 ||
+     945     1212317 :        (ch != 'U' && ch != 'L'))
+     946             :         return;
+     947             :     
+     948             :     jx = jy = kx = ky = 0;
+     949             :     
+     950             :     /* init start points for non-unit increments */
+     951     1212317 :     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     1212317 :     if(ch == 'U') {
+     966             :         /* Data in upper part of A */
+     967     1212317 :         if(incx==1 && incy==1) {
+     968             :             /* Unit increments for both x and y */
+     969     4282806 :             for(j=1;j<=n;j++) {
+     970     3070489 :                 if( std::abs(x[j-1])>PLUMED_GMX_DOUBLE_MIN  || std::abs(y[j-1])>PLUMED_GMX_DOUBLE_MIN ) {
+     971     3070487 :                     temp1 = alpha * y[j-1];
+     972     3070487 :                     temp2 = alpha * x[j-1];
+     973     9857027 :                     for(i=1;i<=j;i++)
+     974     6786540 :                         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         411 : 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         411 :     int m = *m__;
+    1207         411 :     int n = *n__;
+    1208         411 :     int lda = *lda__;
+    1209         411 :     int ldb = *ldb__;
+    1210         411 :     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         411 :     a_offset = 1 + a_dim1;
+    1220         411 :     a -= a_offset;
+    1221             :     b_dim1 = ldb;
+    1222         411 :     b_offset = 1 + b_dim1;
+    1223         411 :     b -= b_offset;
+    1224             : 
+    1225             :     /* Function Body */
+    1226         411 :     lside = (*side=='L' || *side=='l');
+    1227             : 
+    1228         411 :     nounit = (*diag=='N' || *diag=='n');
+    1229         411 :     upper = (*uplo=='U' || *uplo=='u');
+    1230             : 
+    1231         411 :     if (n == 0) {
+    1232             :         return;
+    1233             :     }
+    1234         411 :     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         411 :     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         411 :         if (*transa=='N' || *transa=='n') {
+    1320             : 
+    1321         137 :             if (upper) {
+    1322        2376 :                 for (j = n; j >= 1; --j) {
+    1323             :                     temp = alpha;
+    1324        2287 :                     if (nounit) {
+    1325           0 :                         temp *= a[j + j * a_dim1];
+    1326             :                     }
+    1327             :                     i__1 = m;
+    1328      630793 :                     for (i__ = 1; i__ <= i__1; ++i__) {
+    1329      628506 :                         b[i__ + j * b_dim1] = temp * b[i__ + j * b_dim1];
+    1330             :                     }
+    1331             :                     i__1 = j - 1;
+    1332       36173 :                     for (k = 1; k <= i__1; ++k) {
+    1333       33886 :                         if (std::abs(a[k + j * a_dim1])>PLUMED_GMX_DOUBLE_MIN) {
+    1334       33254 :                             temp = alpha * a[k + j * a_dim1];
+    1335             :                             i__2 = m;
+    1336     9535918 :                             for (i__ = 1; i__ <= i__2; ++i__) {
+    1337     9502664 :                                 b[i__ + j * b_dim1] += temp * b[i__ + k * 
+    1338     9502664 :                                         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         274 :             if (upper) {
+    1370             :                 i__1 = n;
+    1371        4471 :                 for (k = 1; k <= i__1; ++k) {
+    1372             :                     i__2 = k - 1;
+    1373       67533 :                     for (j = 1; j <= i__2; ++j) {
+    1374       63239 :                         if (std::abs(a[j + k * a_dim1])>PLUMED_GMX_DOUBLE_MIN) {
+    1375       62486 :                             temp = alpha * a[j + k * a_dim1];
+    1376             :                             i__3 = m;
+    1377    17678442 :                             for (i__ = 1; i__ <= i__3; ++i__) {
+    1378    17615956 :                                 b[i__ + j * b_dim1] += temp * b[i__ + k * 
+    1379    17615956 :                                         b_dim1];
+    1380             :                             }
+    1381             :                         }
+    1382             :                     }
+    1383             :                     temp = alpha;
+    1384        4294 :                     if (nounit) {
+    1385        2007 :                         temp *= a[k + k * a_dim1];
+    1386             :                     }
+    1387        4294 :                     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        2529 :                 for (k = n; k >= 1; --k) {
+    1396             :                     i__1 = n;
+    1397       38369 :                     for (j = k + 1; j <= i__1; ++j) {
+    1398       35937 :                         if (std::abs(a[j + k * a_dim1])>PLUMED_GMX_DOUBLE_MIN) {
+    1399       34810 :                             temp = alpha * a[j + k * a_dim1];
+    1400             :                             i__2 = m;
+    1401     9565722 :                             for (i__ = 1; i__ <= i__2; ++i__) {
+    1402     9530912 :                                 b[i__ + j * b_dim1] += temp * b[i__ + k * 
+    1403     9530912 :                                         b_dim1];
+    1404             :                             }
+    1405             :                         }
+    1406             :                     }
+    1407             :                     temp = alpha;
+    1408        2432 :                     if (nounit) {
+    1409        1356 :                         temp *= a[k + k * a_dim1];
+    1410             :                     }
+    1411        2432 :                     if (std::abs(temp-1.0)>PLUMED_GMX_DOUBLE_EPS) {
+    1412             :                         i__1 = m;
+    1413      364346 :                         for (i__ = 1; i__ <= i__1; ++i__) {
+    1414      362990 :                             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       36253 : 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       36253 :     int n = *n__;
+    1453       36253 :     int lda = *lda__;
+    1454       36253 :     int incx = *incx__;
+    1455             :     
+    1456             :     a_dim1 = lda;
+    1457       36253 :     a_offset = 1 + a_dim1;
+    1458       36253 :     a -= a_offset;
+    1459       36253 :     --x;
+    1460             : 
+    1461       36253 :     if (n == 0) {
+    1462             :         return;
+    1463             :     }
+    1464             : 
+    1465       19658 :     nounit = (*diag=='n' || *diag=='N');
+    1466             : 
+    1467       19658 :     if (incx <= 0) {
+    1468           0 :         kx = 1 - (n - 1) * incx;
+    1469             :     } else {
+    1470             :         kx = 1;
+    1471             :     }
+    1472             : 
+    1473       19658 :     if (*trans=='N' || *trans=='n') {
+    1474             : 
+    1475       19658 :         if (*uplo=='U' || *uplo=='u') {
+    1476       18407 :             if (incx == 1) {
+    1477             :                 i__1 = n;
+    1478       64159 :                 for (j = 1; j <= i__1; ++j) {
+    1479       45752 :                     if (std::abs(x[j])>PLUMED_GMX_DOUBLE_MIN) {
+    1480             :                         temp = x[j];
+    1481             :                         i__2 = j - 1;
+    1482      335151 :                         for (i__ = 1; i__ <= i__2; ++i__) {
+    1483      289615 :                             x[i__] += temp * a[i__ + j * a_dim1];
+    1484             :                         }
+    1485       45536 :                         if (nounit) {
+    1486       45536 :                             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        1251 :             if (incx == 1) {
+    1511       20575 :                 for (j = n; j >= 1; --j) {
+    1512       19324 :                     if (std::abs(x[j])>PLUMED_GMX_DOUBLE_MIN) {
+    1513             :                         temp = x[j];
+    1514             :                         i__1 = j + 1;
+    1515      208252 :                         for (i__ = n; i__ >= i__1; --i__) {
+    1516      188928 :                             x[i__] += temp * a[i__ + j * a_dim1];
+    1517             :                         }
+    1518       19324 :                         if (nounit) {
+    1519       19324 :                             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       33025 : 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       33025 :   int n    = *n__;
+    1825       33025 :   int incx = *incx__;
+    1826             :   
+    1827       33025 :   if(n<1 || incx<=0)
+    1828             :     return -1;
+    1829             : 
+    1830       33025 :   if(n==1)
+    1831             :     return 1;
+    1832             : 
+    1833       16514 :   dmax = std::abs(dx[0]);
+    1834             :   idxmax = 1;
+    1835             : 
+    1836       16514 :   if(incx==1) {
+    1837       33034 :     for(i=1;i<n;i++) {
+    1838       16520 :       tmp = std::abs(dx[i]);
+    1839       16520 :       if(tmp>dmax) {
+    1840             :         dmax = tmp;
+    1841           6 :         idxmax = i+1;
+    1842             :       }
+    1843             :     }
+    1844             :   } else {
+    1845             :     /* Non-unit increments */
+    1846             :     ix = incx; /* this is really 0 + an increment */
+    1847           0 :     for(i=1;i<n;i++,ix+=incx) {
+    1848           0 :       tmp = std::abs(dx[ix]);
+    1849           0 :       if(tmp>dmax) {
+    1850             :         dmax = tmp;
+    1851           0 :         idxmax = ix+1;
+    1852             :       }
+    1853             :     }    
+    1854             :   }
+    1855             :   return idxmax;
+    1856             : }
+    1857             : }
+    1858             : }
+    1859             : #include <cmath>
+    1860             : #include "blas.h"
+    1861             : 
+    1862             : namespace PLMD{
+    1863             : namespace blas{
+    1864             : int
+    1865           0 : PLUMED_BLAS_F77_FUNC(isamax,ISAMAX)(int *n__,
+    1866             :        float *dx,
+    1867             :        int *incx__)
+    1868             : {
+    1869             :   int i,ix,idxmax;
+    1870             :   float dmax,tmp;
+    1871             : 
+    1872           0 :   int n    = *n__;
+    1873           0 :   int incx = *incx__;
+    1874             :   
+    1875           0 :   if(n<1 || incx<=0)
+    1876             :     return -1;
+    1877             : 
+    1878           0 :   if(n==1)
+    1879             :     return 1;
+    1880             : 
+    1881           0 :   dmax = std::abs(dx[0]);
+    1882             :   idxmax = 1;
+    1883             : 
+    1884           0 :   if(incx==1) {
+    1885           0 :     for(i=1;i<n;i++) {
+    1886           0 :       tmp = std::abs(dx[i]);
+    1887           0 :       if(tmp>dmax) {
+    1888             :         dmax = tmp;
+    1889           0 :         idxmax = i+1;
+    1890             :       }
+    1891             :     }
+    1892             :   } else {
+    1893             :     /* Non-unit increments */
+    1894             :     ix = incx; /* this is really 0 + an increment */
+    1895           0 :     for(i=1;i<n;i++,ix+=incx) {
+    1896           0 :       tmp = std::abs(dx[ix]);
+    1897           0 :       if(tmp>dmax) {
+    1898             :         dmax = tmp;
+    1899           0 :         idxmax = ix+1;
+    1900             :       }
+    1901             :     }    
+    1902             :   }
+    1903             :   return idxmax;
+    1904             : }
+    1905             : }
+    1906             : }
+    1907             : #include <cmath>
+    1908             : #include "blas.h"
+    1909             : 
+    1910             : namespace PLMD{
+    1911             : namespace blas{
+    1912             : float
+    1913           0 : PLUMED_BLAS_F77_FUNC(sasum,SASUM)(int *n__, 
+    1914             :        float *dx, 
+    1915             :        int *incx__)
+    1916             : {
+    1917             :     int i__1, i__2;
+    1918             :     
+    1919             :     int i__, m, mp1;
+    1920             :     float dtemp;
+    1921             :     int nincx;
+    1922             :     
+    1923           0 :     int n = *n__;
+    1924           0 :     int incx = *incx__;
+    1925             :     
+    1926             :     
+    1927           0 :     --dx;
+    1928             :     
+    1929             :     dtemp = 0.;
+    1930           0 :     if (n <= 0 || incx <= 0) {
+    1931             :         return 0.0;
+    1932             :     }
+    1933           0 :     if (incx != 1) {
+    1934           0 :         nincx = n * incx;
+    1935             :         i__1 = nincx;
+    1936             :         i__2 = incx;
+    1937           0 :         for (i__ = 1; i__2 < 0 ? i__ >= i__1 : i__ <= i__1; i__ += i__2) {
+    1938           0 :             dtemp += std::abs(dx[i__]);
+    1939             :         }
+    1940             :         return dtemp;
+    1941             :     }
+    1942             :     
+    1943           0 :     m = n % 6;
+    1944           0 :     if (m != 0) {
+    1945             :         i__2 = m;
+    1946           0 :         for (i__ = 1; i__ <= i__2; ++i__) {
+    1947           0 :             dtemp += std::abs(dx[i__]);
+    1948             :         }
+    1949           0 :         if (n < 6) {
+    1950             :             return dtemp;
+    1951             :         }
+    1952             :     }
+    1953           0 :     mp1 = m + 1;
+    1954             :     i__2 = n;
+    1955           0 :     for (i__ = mp1; i__ <= i__2; i__ += 6) {
+    1956           0 :         dtemp = dtemp + std::abs(dx[i__]) + std::abs(dx[i__ + 1]) + 
+    1957           0 :         std::abs(dx[i__ + 2]) + std::abs(dx[i__+ 3]) + std::abs(dx[i__ + 4]) +
+    1958           0 :         std::abs(dx[i__ + 5]);
+    1959             :     }
+    1960             :     return dtemp;
+    1961             : }
+    1962             : 
+    1963             : 
+    1964             : }
+    1965             : }
+    1966             : #include "blas.h"
+    1967             : 
+    1968             : 
+    1969             : namespace PLMD{
+    1970             : namespace blas{
+    1971             : void
+    1972           0 : PLUMED_BLAS_F77_FUNC(saxpy,SAXPY)(int   *   n_arg,
+    1973             :                       float *   da_arg,
+    1974             :                       float *   dx,
+    1975             :                       int *      incx_arg,
+    1976             :                       float *   dy,
+    1977             :                       int *      incy_arg)
+    1978             : {
+    1979             :   int i,ix,iy;
+    1980           0 :   int n=*n_arg;
+    1981           0 :   float da=*da_arg;
+    1982           0 :   int incx = *incx_arg;
+    1983           0 :   int incy = *incy_arg;
+    1984             : 
+    1985           0 :   if (n<=0)
+    1986             :     return;
+    1987             : 
+    1988           0 :   if(incx!=1 || incy!=1) {
+    1989             :     ix = 0;
+    1990             :     iy = 0;
+    1991           0 :     if(incx<0)
+    1992           0 :       ix = (1-n)*incx;
+    1993           0 :     if(incy<0)
+    1994           0 :       iy = (1-n)*incy;
+    1995             :     
+    1996           0 :     for(i=0;i<n;i++,ix+=incx,iy+=incy) 
+    1997           0 :       dy[iy] += da*dx[ix];
+    1998             : 
+    1999             :     return;
+    2000             : 
+    2001             :   } else {
+    2002             : 
+    2003             :     /* unroll */
+    2004             :     
+    2005           0 :     for(i=0;i<(n-4);i+=4) {
+    2006           0 :       dy[i]   += da*dx[i];
+    2007           0 :       dy[i+1] += da*dx[i+1];
+    2008           0 :       dy[i+2] += da*dx[i+2];
+    2009           0 :       dy[i+3] += da*dx[i+3];
+    2010             :     }
+    2011             :     /* continue with current value of i */
+    2012           0 :     for(;i<n;i++)
+    2013           0 :       dy[i]   += da*dx[i];
+    2014             :   }
+    2015             : }
+    2016             : }
+    2017             : }
+    2018             : #include "blas.h"
+    2019             : 
+    2020             : namespace PLMD{
+    2021             : namespace blas{
+    2022             : void
+    2023           0 : PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(int *n__,
+    2024             :                       float *dx,
+    2025             :                       int *incx__,
+    2026             :                       float *dy,
+    2027             :                       int *incy__)
+    2028             : {
+    2029             :     int i,ix,iy;
+    2030             : 
+    2031           0 :     int n= *n__;
+    2032           0 :     int incx = *incx__;
+    2033           0 :     int incy = *incy__;
+    2034             :     
+    2035           0 :     if(incx!=1 || incy!=1) 
+    2036             :     {
+    2037             :         ix = 0;
+    2038             :         iy = 0;
+    2039           0 :         if(incx<0)
+    2040           0 :             ix = (1-n)*(incx);
+    2041           0 :         if(incy<0)
+    2042           0 :             iy = (1-n)*(incy);
+    2043             :         
+    2044           0 :         for(i=0;i<n;i++,ix+=incx,iy+=incy) 
+    2045           0 :             dy[iy] = dx[ix];
+    2046             :         
+    2047             :         return;
+    2048             :         
+    2049             :     } else {
+    2050             :         
+    2051             :         /* unroll */
+    2052             :         
+    2053           0 :         for(i=0;i<(n-8);i+=8) {
+    2054           0 :             dy[i]   = dx[i];
+    2055           0 :             dy[i+1] = dx[i+1];
+    2056           0 :             dy[i+2] = dx[i+2];
+    2057           0 :             dy[i+3] = dx[i+3];
+    2058           0 :             dy[i+4] = dx[i+4];
+    2059           0 :             dy[i+5] = dx[i+5];
+    2060           0 :             dy[i+6] = dx[i+6];
+    2061           0 :             dy[i+7] = dx[i+7];
+    2062             :         }
+    2063             :         /* continue with current value of i */
+    2064           0 :         for(;i<n;i++)
+    2065           0 :             dy[i] = dx[i];
+    2066             :     }
+    2067             : }
+    2068             : }
+    2069             : }
+    2070             : #include "blas.h"
+    2071             : 
+    2072             : 
+    2073             : namespace PLMD{
+    2074             : namespace blas{
+    2075             : float
+    2076           1 : PLUMED_BLAS_F77_FUNC(sdot,SDOT)(int *n_arg,
+    2077             :                     float *dx,
+    2078             :                     int *incx_arg,
+    2079             :                     float *dy,
+    2080             :                     int *incy_arg)
+    2081             : {
+    2082             :     int i,ix,iy,m;
+    2083           1 :     int n=*n_arg;
+    2084           1 :     int incx = *incx_arg;
+    2085           1 :     int incy = *incy_arg;
+    2086             :     float t1;
+    2087             :     
+    2088           1 :     if(n<=0)
+    2089             :         return 0.0;
+    2090             :     
+    2091             :     t1 = 0.0;
+    2092             :     
+    2093           1 :     if(incx!=1 || incy!=1) {
+    2094             :         ix = 0;
+    2095             :         iy = 0;
+    2096           0 :         if(incx<0)
+    2097           0 :             ix = (1-n)*incx;
+    2098           0 :         if(incy<0)
+    2099           0 :             iy = (1-n)*incy;
+    2100             :         
+    2101           0 :         for(i=0;i<n;i++,ix+=incx,iy+=incy) 
+    2102           0 :             t1 += dx[ix] * dy[iy];
+    2103             :         
+    2104             :         return t1;
+    2105             :         
+    2106             :     } else {
+    2107             :         
+    2108           1 :         m = n%5;
+    2109             :         
+    2110           1 :         for(i=0;i<m;i++)
+    2111           0 :             t1 += dx[i] * dy[i];
+    2112             :         
+    2113             :         /* unroll */
+    2114           2 :         for(i=m;i<n;i+=5) 
+    2115           1 :             t1  =  t1 + dx[i] * dy[i]   
+    2116           1 :                 +    dx[i+1] * dy[i+1] 
+    2117           1 :                 +    dx[i+2] * dy[i+2] 
+    2118           1 :                 +    dx[i+3] * dy[i+3]   
+    2119           1 :                 +    dx[i+4] * dy[i+4];   
+    2120             :         
+    2121             :         return t1;
+    2122             :     }
+    2123             : }
+    2124             : 
+    2125             : 
+    2126             : }
+    2127             : }
+    2128             : #include <cctype>
+    2129             : #include <cmath>
+    2130             : 
+    2131             : #include "real.h"
+    2132             : #include "blas.h"
+    2133             : 
+    2134             : namespace PLMD{
+    2135             : namespace blas{
+    2136             : void
+    2137           0 : PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)(const char *transa,
+    2138             :        const char *transb,
+    2139             :        int *m__,
+    2140             :        int *n__,
+    2141             :        int *k__,
+    2142             :        float *alpha__,
+    2143             :        float *a,
+    2144             :        int *lda__,
+    2145             :        float *b,
+    2146             :        int *ldb__,
+    2147             :        float *beta__,
+    2148             :        float *c,
+    2149             :        int *ldc__)
+    2150             : {
+    2151           0 :   const char tra=std::toupper(*transa);
+    2152           0 :   const char trb=std::toupper(*transb);
+    2153             :   float temp;
+    2154             :   int i,j,l;
+    2155             : 
+    2156           0 :   int m   = *m__;
+    2157           0 :   int n   = *n__;
+    2158           0 :   int k   = *k__;
+    2159           0 :   int lda = *lda__;
+    2160           0 :   int ldb = *ldb__;
+    2161           0 :   int ldc = *ldc__;
+    2162             :   
+    2163           0 :   float alpha = *alpha__;
+    2164           0 :   float beta  = *beta__;
+    2165             :   
+    2166           0 :   if(m==0 || n==0 || (( std::abs(alpha)<PLUMED_GMX_FLOAT_MIN || k==0) && std::abs(beta-1.0)<PLUMED_GMX_FLOAT_EPS))
+    2167             :     return;
+    2168             : 
+    2169           0 :   if(std::abs(alpha)<PLUMED_GMX_FLOAT_MIN) {
+    2170           0 :     if(std::abs(beta)<PLUMED_GMX_FLOAT_MIN) {
+    2171           0 :       for(j=0;j<n;j++)
+    2172           0 :         for(i=0;i<m;i++)
+    2173           0 :           c[j*(ldc)+i] = 0.0;
+    2174             :     } else {
+    2175             :       /* nonzero beta */
+    2176           0 :       for(j=0;j<n;j++)
+    2177           0 :         for(i=0;i<m;i++)
+    2178           0 :           c[j*(ldc)+i] *= beta;
+    2179             :     }
+    2180           0 :     return;
+    2181             :   }
+    2182             : 
+    2183           0 :   if(trb=='N') {
+    2184           0 :     if(tra=='N') {
+    2185             :       
+    2186           0 :       for(j=0;j<n;j++) {
+    2187           0 :         if(std::abs(beta)<PLUMED_GMX_FLOAT_MIN) {
+    2188           0 :           for(i=0;i<m;i++)
+    2189           0 :             c[j*(ldc)+i] = 0.0;
+    2190           0 :         } else if(std::abs(beta-1.0)>PLUMED_GMX_FLOAT_EPS) {
+    2191           0 :           for(i=0;i<m;i++)
+    2192           0 :             c[j*(ldc)+i] *= beta;
+    2193             :         } 
+    2194           0 :         for(l=0;l<k;l++) {
+    2195           0 :           if( std::abs(b[ j*(ldb) + l ])>PLUMED_GMX_FLOAT_MIN) {
+    2196           0 :             temp = alpha * b[ j*(ldb) + l ];
+    2197           0 :             for(i=0;i<m;i++)
+    2198           0 :               c[j*(ldc)+i] += temp * a[l*(lda)+i]; 
+    2199             :           }
+    2200             :         }
+    2201             :       }
+    2202             :     } else {
+    2203             :       /* transpose A, but not B */
+    2204           0 :       for(j=0;j<n;j++) {
+    2205           0 :         for(i=0;i<m;i++) {
+    2206             :           temp = 0.0;
+    2207           0 :           for(l=0;l<k;l++) 
+    2208           0 :             temp += a[i*(lda)+l] * b[j*(ldb)+l];
+    2209           0 :           if(std::abs(beta)<PLUMED_GMX_FLOAT_MIN)
+    2210           0 :             c[j*(ldc)+i] = alpha * temp;
+    2211             :           else
+    2212           0 :             c[j*(ldc)+i] = alpha * temp + beta * c[j*(ldc)+i];
+    2213             :         }
+    2214             :       }
+    2215             :     }
+    2216             :   } else {
+    2217             :     /* transpose B */
+    2218           0 :     if(tra=='N') {
+    2219             : 
+    2220             :       /* transpose B, but not A */
+    2221             : 
+    2222           0 :       for(j=0;j<n;j++) {
+    2223           0 :         if(std::abs(beta)<PLUMED_GMX_FLOAT_MIN) {
+    2224           0 :           for(i=0;i<m;i++)
+    2225           0 :             c[j*(ldc)+i] = 0.0;
+    2226           0 :         } else if(std::abs(beta-1.0)>PLUMED_GMX_FLOAT_EPS) {
+    2227           0 :           for(i=0;i<m;i++)
+    2228           0 :             c[j*(ldc)+i] *= beta;
+    2229             :         } 
+    2230           0 :         for(l=0;l<k;l++) {
+    2231           0 :           if( std::abs(b[ l*(ldb) + j ])>PLUMED_GMX_FLOAT_MIN) {
+    2232           0 :             temp = alpha * b[ l*(ldb) + j ];
+    2233           0 :             for(i=0;i<m;i++)
+    2234           0 :               c[j*(ldc)+i] += temp * a[l*(lda)+i]; 
+    2235             :           }
+    2236             :         }
+    2237             :       }
+    2238             :  
+    2239             :     } else {
+    2240             :       /* Transpose both A and B */
+    2241           0 :        for(j=0;j<n;j++) {
+    2242           0 :         for(i=0;i<m;i++) {
+    2243             :           temp = 0.0;
+    2244           0 :           for(l=0;l<k;l++) 
+    2245           0 :             temp += a[i*(lda)+l] * b[l*(ldb)+j];
+    2246           0 :           if(std::abs(beta)<PLUMED_GMX_FLOAT_MIN)
+    2247           0 :             c[j*(ldc)+i] = alpha * temp;
+    2248             :           else
+    2249           0 :             c[j*(ldc)+i] = alpha * temp + beta * c[j*(ldc)+i];
+    2250             :         }
+    2251             :        }
+    2252             :     }
+    2253             :   }
+    2254             : }
+    2255             : }
+    2256             : }
+    2257             : #include <cctype>
+    2258             : #include <cmath>
+    2259             : 
+    2260             : #include "real.h"
+    2261             : #include "blas.h"
+    2262             : 
+    2263             : namespace PLMD{
+    2264             : namespace blas{
+    2265             : void
+    2266           0 : PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)(const char *trans, 
+    2267             :                       int *m__,
+    2268             :                       int *n__,
+    2269             :                       float *alpha__,
+    2270             :                       float *a,
+    2271             :                       int *lda__,
+    2272             :                       float *x,
+    2273             :                       int *incx__,
+    2274             :                       float *beta__,
+    2275             :                       float *y,
+    2276             :                       int *incy__)
+    2277             : {
+    2278           0 :   const char ch=std::toupper(*trans);
+    2279             :   int lenx,leny,kx,ky;
+    2280             :   int i,j,jx,jy,ix,iy;
+    2281             :   float temp;
+    2282             : 
+    2283           0 :   int m = *m__;
+    2284           0 :   int n = *n__;
+    2285           0 :   float alpha = *alpha__;
+    2286           0 :   float beta = *beta__;
+    2287           0 :   int incx = *incx__;
+    2288           0 :   int incy = *incy__;
+    2289           0 :   int lda = *lda__;
+    2290             :   
+    2291           0 :   if(n<=0 || m<=0 || (std::abs(alpha)<PLUMED_GMX_FLOAT_MIN && std::abs(beta-1.0)<PLUMED_GMX_FLOAT_EPS))
+    2292             :     return;
+    2293             : 
+    2294           0 :   if(ch=='N') {
+    2295             :     lenx = n;
+    2296             :     leny = m;
+    2297             :   } else {
+    2298             :     lenx = m;
+    2299             :     leny = n;
+    2300             :   }
+    2301             :   
+    2302           0 :    if(incx>0)
+    2303             :     kx = 1;
+    2304             :   else
+    2305           0 :     kx = 1 - (lenx -1)*(incx);
+    2306             : 
+    2307           0 :   if(incy>0)
+    2308             :     ky = 1;
+    2309             :   else
+    2310           0 :     ky = 1 - (leny -1)*(incy);
+    2311             :  
+    2312           0 :   if(std::abs(beta-1.0)>PLUMED_GMX_FLOAT_EPS) {
+    2313           0 :     if(incy==1) {
+    2314           0 :       if(std::abs(beta)<PLUMED_GMX_FLOAT_MIN)
+    2315           0 :         for(i=0;i<leny;i++)
+    2316           0 :           y[i] = 0.0;
+    2317             :       else
+    2318           0 :         for(i=0;i<leny;i++)
+    2319           0 :           y[i] *= beta;
+    2320             :     } else {
+    2321             :       /* non-unit incr. */
+    2322             :       iy = ky;
+    2323           0 :       if(std::abs(beta)<PLUMED_GMX_FLOAT_MIN) 
+    2324           0 :         for(i=0;i<leny;i++,iy+=incy)
+    2325           0 :           y[iy] = 0.0;
+    2326             :       else
+    2327           0 :         for(i=0;i<leny;i++,iy+=incy)
+    2328           0 :           y[iy] *= beta;
+    2329             :     }
+    2330             :   }
+    2331             :   
+    2332           0 :   if(std::abs(alpha)<PLUMED_GMX_FLOAT_MIN)
+    2333             :     return;
+    2334             :   
+    2335           0 :   if(ch=='N') {
+    2336             :     jx = kx;
+    2337           0 :     if(incy==1) {
+    2338           0 :       for(j=1;j<=n;j++,jx+=incx) 
+    2339           0 :         if( std::abs(x[jx-1])>PLUMED_GMX_FLOAT_MIN) {
+    2340           0 :           temp = alpha * x[jx-1];
+    2341           0 :           for(i=1;i<=m;i++)
+    2342           0 :             y[i-1] += temp * a[(j-1)*(lda)+(i-1)];
+    2343             :         }
+    2344             :     } else {
+    2345             :       /* non-unit y incr. */
+    2346           0 :       for(j=1;j<=n;j++,jx+=incx) 
+    2347           0 :         if( std::abs(x[jx-1])>PLUMED_GMX_FLOAT_MIN) {
+    2348           0 :           temp = alpha * x[jx-1];
+    2349             :           iy = ky;
+    2350           0 :           for(i=1;i<=m;i++,iy+=incy)
+    2351           0 :             y[iy-1] += temp * a[(j-1)*(lda)+(i-1)];
+    2352             :         }
+    2353             :     }
+    2354             :   } else {
+    2355             :     /* transpose */
+    2356             :     jy = ky;
+    2357           0 :     if(incx==1) {
+    2358           0 :       for(j=1;j<=n;j++,jy+=incy) {
+    2359             :         temp = 0.0;
+    2360           0 :         for(i=1;i<=m;i++)
+    2361           0 :           temp += a[(j-1)*(lda)+(i-1)] * x[i-1];
+    2362           0 :         y[jy-1] += alpha * temp;
+    2363             :       }
+    2364             :     } else {
+    2365             :       /* non-unit y incr. */
+    2366           0 :       for(j=1;j<=n;j++,jy+=incy) {
+    2367             :         temp = 0.0;
+    2368             :         ix = kx;
+    2369           0 :         for(i=1;i<=m;i++,ix+=incx)
+    2370           0 :           temp += a[(j-1)*(lda)+(i-1)] * x[ix-1];
+    2371           0 :         y[jy-1] += alpha * temp;
+    2372             :       }
+    2373             :     }
+    2374             :   }
+    2375             : } 
+    2376             :    
+    2377             : }
+    2378             : }
+    2379             : #include <cmath>
+    2380             : 
+    2381             : #include "real.h"
+    2382             : #include "blas.h"
+    2383             : 
+    2384             : namespace PLMD{
+    2385             : namespace blas{
+    2386             : void
+    2387           0 : PLUMED_BLAS_F77_FUNC(sger,SGER)(int *m__,
+    2388             :                     int *n__,
+    2389             :                     float *alpha__,
+    2390             :                     float *x,
+    2391             :                     int *incx__,
+    2392             :                     float *y,
+    2393             :                     int *incy__,
+    2394             :                     float *a,
+    2395             :                     int *lda__)
+    2396             : {
+    2397             :     int ix,kx,jy;
+    2398             :     int i,j;
+    2399             :     float temp;
+    2400             :     
+    2401           0 :     int m = *m__;
+    2402           0 :     int n = *n__;
+    2403           0 :     int incx = *incx__;
+    2404           0 :     int incy = *incy__;
+    2405           0 :     int lda = *lda__;
+    2406           0 :     float alpha = *alpha__;
+    2407             :     
+    2408           0 :     if(m<=0 || n<=0 || std::abs(alpha)<PLUMED_GMX_FLOAT_MIN)
+    2409             :         return;
+    2410             :     
+    2411           0 :     if(incy>0)
+    2412             :         jy = 0;
+    2413             :     else
+    2414           0 :         jy = incy * (1 - n);
+    2415             :     
+    2416           0 :     if(incx==1) {
+    2417           0 :         for(j=0;j<n;j++,jy+=incy)
+    2418           0 :             if(std::abs(y[jy])>PLUMED_GMX_FLOAT_MIN) {
+    2419           0 :                 temp = alpha * y[jy];
+    2420           0 :                 for(i=0;i<m;i++)
+    2421           0 :                     a[j*(lda)+i] += temp*x[i];
+    2422             :             }
+    2423             :     } else {
+    2424             :         /* non-unit incx */
+    2425           0 :         if(incx>0) 
+    2426             :             kx = 0;
+    2427             :         else
+    2428           0 :             kx = incx * (1 - m);
+    2429             :         
+    2430           0 :         for(j=0;j<n;j++,jy+=incy) {
+    2431           0 :             if(std::abs(y[jy])>PLUMED_GMX_FLOAT_MIN) {
+    2432           0 :                 temp = alpha * y[jy];
+    2433             :                 ix = kx;
+    2434           0 :                 for(i=0;i<m;i++,ix+=incx)
+    2435           0 :                     a[j*(lda)+i] += temp*x[ix];
+    2436             :             }
+    2437             :         }
+    2438             :     }
+    2439             :         return;
+    2440             : }
+    2441             : }
+    2442             : }
+    2443             : #include <cmath>
+    2444             : 
+    2445             : 
+    2446             : #include "real.h"
+    2447             : #include "blas.h"
+    2448             : 
+    2449             : namespace PLMD{
+    2450             : namespace blas{
+    2451             : float
+    2452           0 : PLUMED_BLAS_F77_FUNC(snrm2,SNRM2)(int  *     n__,
+    2453             :                       float *    x,
+    2454             :                       int    *    incx__)
+    2455             : {
+    2456             :     int ix,max_ix;
+    2457             :     float ssq,scale,absxi,t;
+    2458             :     
+    2459           0 :     int n = *n__;
+    2460           0 :     int incx = *incx__;
+    2461             :     
+    2462           0 :     if(n<1 || incx<1)
+    2463             :         return 0;
+    2464           0 :     else if (n==1) {
+    2465           0 :         t = x[0];
+    2466           0 :         if(t>=0)
+    2467             :             return t;
+    2468             :         else 
+    2469           0 :             return -t;
+    2470             :     }
+    2471             :     
+    2472             :     scale = 0.0;
+    2473             :     ssq   = 1.0;
+    2474             :     
+    2475           0 :     max_ix = 1+(n-1)*(incx);
+    2476           0 :     for(ix=1;ix<=max_ix;ix+=incx) {
+    2477           0 :         t = x[ix-1];
+    2478           0 :         if(std::abs(t)>PLUMED_GMX_FLOAT_MIN) {
+    2479           0 :             absxi = (t>=0) ? t : (-t);
+    2480           0 :             if(scale<absxi) {
+    2481           0 :                 t = scale/absxi;
+    2482           0 :                 t = t*t;
+    2483           0 :                 ssq = ssq*t + 1.0;
+    2484             :                 scale = absxi;
+    2485             :             } else {
+    2486           0 :                 t = absxi/scale;
+    2487           0 :                 ssq += t*t;
+    2488             :             }
+    2489             :         }
+    2490             :     }
+    2491           0 :     return scale*std::sqrt(ssq);
+    2492             :     
+    2493             : }
+    2494             : 
+    2495             : 
+    2496             :  
+    2497             : }
+    2498             : }
+    2499             : #include "blas.h"
+    2500             : 
+    2501             : namespace PLMD{
+    2502             : namespace blas{
+    2503             : void
+    2504           0 : PLUMED_BLAS_F77_FUNC(srot,SROT)(int *n__,
+    2505             :                     float *dx,
+    2506             :                     int *incx__,
+    2507             :                     float *dy,
+    2508             :                     int *incy__,
+    2509             :                     float *c__,
+    2510             :                     float *s__)
+    2511             : {
+    2512             :   int i,ix,iy;
+    2513             :   float dtemp;
+    2514             : 
+    2515           0 :   int n = *n__;
+    2516           0 :   int incx = *incx__;
+    2517           0 :   int incy = *incy__;
+    2518           0 :   float c = *c__;
+    2519           0 :   float s = *s__;
+    2520             :   
+    2521           0 :   if(incx!=1 || incy!=1) {
+    2522             :     ix = 0;
+    2523             :     iy = 0;
+    2524           0 :     if(incx<0)
+    2525           0 :       ix = (1-n)*(incx);
+    2526           0 :     if(incy<0)
+    2527           0 :       iy = (1-n)*(incy);
+    2528             :     
+    2529           0 :     for(i=0;i<n;i++,ix+=incx,iy+=incy) {
+    2530           0 :       dtemp  = (c) * dx[ix] + (s) * dy[iy];
+    2531           0 :       dy[iy] = (c) * dy[iy] - (s) * dx[ix];
+    2532           0 :       dx[ix] = dtemp;
+    2533             :     }
+    2534             : 
+    2535             :     return;
+    2536             : 
+    2537             :   } else {
+    2538             : 
+    2539             :     /* unit increments */   
+    2540           0 :     for(i=0;i<n;i++) {
+    2541           0 :       dtemp = (c) * dx[i] + (s) * dy[i];
+    2542           0 :       dy[i] = (c) * dy[i] - (s) * dx[i];
+    2543           0 :       dx[i] = dtemp;      
+    2544             :     }
+    2545             : 
+    2546             :   }
+    2547             : }
+    2548             : }
+    2549             : }
+    2550             : #include "blas.h"
+    2551             : 
+    2552             : namespace PLMD{
+    2553             : namespace blas{
+    2554             : void 
+    2555           0 : PLUMED_BLAS_F77_FUNC(sscal,SSCAL)(int  *n__,
+    2556             :                       float *fact__,
+    2557             :                       float *dx,
+    2558             :                       int   *incx__)
+    2559             : {
+    2560             :     int nincx,i;
+    2561             : 
+    2562           0 :     int n = *n__;
+    2563           0 :     float fact = *fact__;
+    2564           0 :     int incx = *incx__;
+    2565             :     
+    2566           0 :     if(n<=0 || incx<=0)
+    2567             :         return;
+    2568             :     
+    2569           0 :     if(incx==1) {
+    2570             :         /* Unrool factor 5 */
+    2571           0 :         for(i=0;i<(n-5);i+=5) {
+    2572           0 :             dx[i]   *= fact;
+    2573           0 :             dx[i+1] *= fact;
+    2574           0 :             dx[i+2] *= fact;
+    2575           0 :             dx[i+3] *= fact;
+    2576           0 :             dx[i+4] *= fact;
+    2577             :         }    
+    2578             :         /* continue with current value of i */
+    2579           0 :         for(;i<n;i++)
+    2580           0 :             dx[i]   *= fact;
+    2581             :         
+    2582             :         return;
+    2583             :     } else {
+    2584             :         /* inc != 1 */
+    2585           0 :         nincx = n * (incx);
+    2586           0 :         for (i=0;i<nincx;i+=incx)
+    2587           0 :             dx[i] *= fact;
+    2588             :         
+    2589             :         return;
+    2590             :     } 
+    2591             :     
+    2592             : }
+    2593             : }
+    2594             : }
+    2595             : #include "blas.h"
+    2596             : 
+    2597             : namespace PLMD{
+    2598             : namespace blas{
+    2599             : void
+    2600           0 : PLUMED_BLAS_F77_FUNC(sswap,SSWAP)(int *n__,
+    2601             :                       float *dx,
+    2602             :                       int *incx__,
+    2603             :                       float *dy,
+    2604             :                       int *incy__)
+    2605             : {
+    2606             :   int i,ix,iy;
+    2607             :   float d1,d2,d3;
+    2608             : 
+    2609           0 :   int n = *n__;
+    2610           0 :   int incx = *incx__;
+    2611           0 :   int incy = *incy__;
+    2612             :   
+    2613           0 :   if(n<=0)
+    2614             :     return;
+    2615             : 
+    2616           0 :   if(incx==1 && incy==1) {
+    2617           0 :     for(i=0;i<(n-3);i+=3) {
+    2618           0 :       d1      = dx[i];
+    2619           0 :       d2      = dx[i+1];
+    2620           0 :       d3      = dx[i+2];
+    2621           0 :       dx[i]   = dy[i];
+    2622           0 :       dx[i+1] = dy[i+1];
+    2623           0 :       dx[i+2] = dy[i+2];
+    2624           0 :       dy[i]   = d1;
+    2625           0 :       dy[i+1] = d2;
+    2626           0 :       dy[i+2] = d3;
+    2627             :     }
+    2628             :     /* continue with last i value */
+    2629           0 :     for(;i<n;i++) {
+    2630           0 :       d1      = dx[i];
+    2631           0 :       dx[i]   = dy[i];
+    2632           0 :       dy[i]   = d1;
+    2633             :     }
+    2634             : 
+    2635             :   } else {
+    2636             :     ix = 0;
+    2637             :     iy = 0;
+    2638           0 :     if(incx<0)
+    2639           0 :       ix = incx * (1 - n);
+    2640           0 :     if(incy<0)
+    2641           0 :       iy = incy * (1 - n);
+    2642             : 
+    2643           0 :     for(i=0;i<n;i++,ix+=incx,iy+=incy) {
+    2644           0 :       d1     = dx[ix];
+    2645           0 :       dx[ix] = dy[iy];
+    2646           0 :       dy[iy] = d1;
+    2647             :     }
+    2648             :   }
+    2649             :   return;
+    2650             : }
+    2651             :  
+    2652             : }
+    2653             : }
+    2654             : #include <cctype>
+    2655             : #include <cmath>
+    2656             : 
+    2657             : #include "real.h"
+    2658             : #include "blas.h"
+    2659             : 
+    2660             : namespace PLMD{
+    2661             : namespace blas{
+    2662             : void
+    2663           0 : PLUMED_BLAS_F77_FUNC(ssymv,SSYMV)(const char *uplo,
+    2664             :                       int *n__,
+    2665             :                       float *alpha__,
+    2666             :                       float *a,
+    2667             :                       int *lda__,
+    2668             :                       float *x,
+    2669             :                       int *incx__,
+    2670             :                       float *beta__,
+    2671             :                       float *y,
+    2672             :                       int *incy__)
+    2673             : {
+    2674           0 :     const char ch=std::toupper(*uplo);
+    2675             :     int kx,ky,i,j,ix,iy,jx,jy;
+    2676             :     float temp1,temp2;
+    2677             :     
+    2678           0 :     int n = *n__;
+    2679           0 :     int lda = *lda__;
+    2680           0 :     int incx = *incx__;
+    2681           0 :     int incy = *incy__;
+    2682           0 :     float alpha = *alpha__;
+    2683           0 :     float beta  = *beta__;
+    2684             :     
+    2685           0 :     if(n<=0 || incx==0 || incy==0)
+    2686             :         return;
+    2687             :     
+    2688           0 :     if(incx>0)
+    2689             :         kx = 1;
+    2690             :     else
+    2691           0 :         kx = 1 - (n -1)*(incx);
+    2692             :     
+    2693           0 :     if(incy>0)
+    2694             :         ky = 1;
+    2695             :     else
+    2696           0 :         ky = 1 - (n -1)*(incy);
+    2697             :     
+    2698           0 :     if(std::abs(beta-1.0)>PLUMED_GMX_FLOAT_EPS) {
+    2699           0 :         if(incy==1) {
+    2700           0 :             if(std::abs(beta)<PLUMED_GMX_FLOAT_MIN) 
+    2701           0 :                 for(i=1;i<=n;i++)
+    2702           0 :                     y[i-1] = 0.0;
+    2703             :             else
+    2704           0 :                 for(i=1;i<=n;i++)
+    2705           0 :                     y[i-1] *= beta;
+    2706             :         } else {
+    2707             :             /* non-unit incr. */
+    2708             :             iy = ky;
+    2709           0 :             if(std::abs(beta)<PLUMED_GMX_FLOAT_MIN) 
+    2710           0 :                 for(i=1;i<=n;i++) {
+    2711           0 :                     y[iy-1] = 0.0;
+    2712           0 :                     iy += incy;
+    2713             :                 }
+    2714             :                     else
+    2715           0 :                         for(i=1;i<=n;i++) {
+    2716           0 :                             y[iy-1] *= beta;
+    2717           0 :                             iy += incy;
+    2718             :                         }
+    2719             :         }
+    2720             :     }
+    2721             :         
+    2722           0 :         if(std::abs(alpha)<PLUMED_GMX_FLOAT_MIN) 
+    2723             :             return;
+    2724             :         
+    2725           0 :         if(ch=='U') {
+    2726           0 :             if(incx==1 && incy==1) {
+    2727           0 :                 for(j=1;j<=n;j++) {
+    2728           0 :                     temp1 = alpha * x[j-1];
+    2729             :                     temp2 = 0.0;
+    2730           0 :                     for(i=1;i<j;i++) {
+    2731           0 :                         y[i-1] += temp1*a[(j-1)*(lda)+(i-1)];
+    2732           0 :                         temp2 += a[(j-1)*(lda)+(i-1)] * x[i-1];
+    2733             :                     }
+    2734           0 :                     y[j-1] += temp1*a[(j-1)*(lda)+(j-1)] + alpha *temp2;
+    2735             :                 }
+    2736             :             } else {
+    2737             :                 /* non-unit incr. */
+    2738             :                 jx = kx;
+    2739             :                 jy = ky;
+    2740           0 :                 for(j=1;j<=n;j++) {
+    2741           0 :                     temp1 = alpha * x[jx-1];
+    2742             :                     temp2 = 0.0;
+    2743             :                     ix = kx;
+    2744             :                     iy = ky;
+    2745           0 :                     for(i=1;i<j;i++) {
+    2746           0 :                         y[iy-1] += temp1 * a[(j-1)*(lda)+(i-1)];
+    2747           0 :                         temp2 += a[(j-1)*(lda)+(i-1)] * x[ix-1];
+    2748           0 :                         ix += incx;
+    2749           0 :                         iy += incy;
+    2750             :                     }
+    2751           0 :                     y[jy-1] += temp1*a[(j-1)*(lda)+(j-1)] + alpha*temp2;
+    2752           0 :                     jx += incx;
+    2753           0 :                     jy += incy;
+    2754             :                 }
+    2755             :             }
+    2756             :         } else {
+    2757             :             /* lower */
+    2758           0 :             if(incx==1 && incy==1) {
+    2759           0 :                 for(j=1;j<=n;j++) {
+    2760           0 :                     temp1 = alpha * x[j-1];
+    2761             :                     temp2 = 0.0;
+    2762           0 :                     y[j-1] += temp1 * a[(j-1)*(lda)+(j-1)];
+    2763           0 :                     for(i=j+1;i<=n;i++) {
+    2764           0 :                         y[i-1] += temp1*a[(j-1)*(lda)+(i-1)];
+    2765           0 :                         temp2 += a[(j-1)*(lda)+(i-1)] * x[i-1];
+    2766             :                     }
+    2767           0 :                     y[j-1] += alpha *temp2;
+    2768             :                 }
+    2769             :             } else {
+    2770             :                 /* non-unit incr. */
+    2771             :                 jx = kx;
+    2772             :                 jy = ky;
+    2773           0 :                 for(j=1;j<=n;j++) {
+    2774           0 :                     temp1 = alpha * x[jx-1];
+    2775             :                     temp2 = 0.0;
+    2776           0 :                     y[jy-1] += temp1 * a[(j-1)*(lda)+(j-1)];
+    2777             :                     ix = jx;
+    2778             :                     iy = jy;
+    2779           0 :                     for(i=j+1;i<=n;i++) {
+    2780           0 :                         ix += incx;
+    2781           0 :                         iy += incy;
+    2782           0 :                         y[iy-1] += temp1 * a[(j-1)*(lda)+(i-1)];
+    2783           0 :                         temp2 += a[(j-1)*(lda)+(i-1)] * x[ix-1];
+    2784             :                     }
+    2785           0 :                     y[jy-1] += alpha*temp2;
+    2786           0 :                     jx += incx;
+    2787           0 :                     jy += incy;
+    2788             :                 }
+    2789             :             }
+    2790             :         }
+    2791             :         return;
+    2792             : }    
+    2793             : }
+    2794             : }
+    2795             : #include <cctype>
+    2796             : #include <cmath>
+    2797             : 
+    2798             : #include "real.h"
+    2799             : #include "blas.h"
+    2800             : 
+    2801             : namespace PLMD{
+    2802             : namespace blas{
+    2803             : void
+    2804           0 : PLUMED_BLAS_F77_FUNC(ssyr2,SSYR2)(const char *    uplo,
+    2805             :                       int *     n__,
+    2806             :                       float *  alpha__,
+    2807             :                       float *  x,
+    2808             :                       int *     incx__,
+    2809             :                       float *  y,
+    2810             :                       int *     incy__,
+    2811             :                       float *  a,
+    2812             :                       int *     lda__)
+    2813             : {
+    2814             :     int kx,ky,ix,iy,jx,jy,j,i;
+    2815             :     float temp1,temp2;
+    2816           0 :     const char ch=std::toupper(*uplo);
+    2817             :     
+    2818           0 :     int n = *n__;
+    2819           0 :     int lda = *lda__;
+    2820           0 :     int incx = *incx__;
+    2821           0 :     int incy = *incy__;
+    2822           0 :     float alpha = *alpha__;
+    2823             :     
+    2824           0 :     if(n<=0 || std::abs(alpha)<PLUMED_GMX_FLOAT_MIN || incx==0 || incy==0 ||
+    2825           0 :        (ch != 'U' && ch != 'L'))
+    2826             :         return;
+    2827             :     
+    2828             :     jx = jy = kx = ky = 0;
+    2829             :     
+    2830             :     /* init start points for non-unit increments */
+    2831           0 :     if(incx!=1 || incy!=1) {
+    2832           0 :         if(incx>0)
+    2833             :             kx = 1;
+    2834             :         else
+    2835           0 :             kx = 1 - (n - 1)*(incx);
+    2836           0 :         if(incy>0)
+    2837             :             ky = 1;
+    2838             :         else
+    2839           0 :             ky = 1 - (n - 1)*(incy);
+    2840             :         
+    2841             :         jx = kx;
+    2842             :         jy = ky;
+    2843             :     }
+    2844             :     
+    2845           0 :     if(ch == 'U') {
+    2846             :         /* Data in upper part of A */
+    2847           0 :         if(incx==1 && incy==1) {
+    2848             :             /* Unit increments for both x and y */
+    2849           0 :             for(j=1;j<=n;j++) {
+    2850           0 :                 if( std::abs(x[j-1])>PLUMED_GMX_FLOAT_MIN  || std::abs(y[j-1])>PLUMED_GMX_FLOAT_MIN ) {
+    2851           0 :                     temp1 = alpha * y[j-1];
+    2852           0 :                     temp2 = alpha * x[j-1];
+    2853           0 :                     for(i=1;i<=j;i++)
+    2854           0 :                         a[(j-1)*(lda)+(i-1)] += x[i-1]*temp1 + y[i-1]*temp2;
+    2855             :                 }
+    2856             :             }
+    2857             :         } else {
+    2858             :             
+    2859             :             /* non-unit increments */
+    2860           0 :             for(j=1;j<=n;j++) {
+    2861             :                 
+    2862           0 :                 if( std::abs(x[jx-1])>PLUMED_GMX_FLOAT_MIN || std::abs(y[jy-1])>PLUMED_GMX_FLOAT_MIN ) {
+    2863           0 :                     temp1 = alpha * y[jy-1];
+    2864           0 :                     temp2 = alpha * x[jx-1];
+    2865             :                     ix = kx;
+    2866             :                     iy = ky;
+    2867           0 :                     for(i=1;i<=j;i++) {
+    2868           0 :                         a[(j-1)*(lda)+(i-1)] += x[ix-1]*temp1 + y[iy-1]*temp2;
+    2869           0 :                         ix += incx;
+    2870           0 :                         iy += incy;
+    2871             :                     }
+    2872             :                 }
+    2873           0 :                 jx += incx;
+    2874           0 :                 jy += incy;
+    2875             :             }
+    2876             :         }
+    2877             :     } else {
+    2878             :         /* Data in lower part of A */
+    2879           0 :         if(incx==1 && incy==1) {
+    2880             :             /* Unit increments for both x and y */
+    2881           0 :             for(j=1;j<=n;j++) {
+    2882           0 :                 if( std::abs(x[j-1])>PLUMED_GMX_FLOAT_MIN  || std::abs(y[j-1])>PLUMED_GMX_FLOAT_MIN ) {
+    2883           0 :                     temp1 = alpha * y[j-1];
+    2884           0 :                     temp2 = alpha * x[j-1];
+    2885           0 :                     for(i=j;i<=n;i++)
+    2886           0 :                         a[(j-1)*(lda)+(i-1)] += x[i-1]*temp1 + y[i-1]*temp2;
+    2887             :                 }
+    2888             :             }
+    2889             :         } else {
+    2890             :             
+    2891             :             /* non-unit increments */
+    2892           0 :             for(j=1;j<=n;j++) {
+    2893             :                 
+    2894           0 :                 if( std::abs(x[jx-1])>PLUMED_GMX_FLOAT_MIN || std::abs(y[jy-1])>PLUMED_GMX_FLOAT_MIN ) {
+    2895           0 :                     temp1 = alpha * y[jy-1];
+    2896           0 :                     temp2 = alpha * x[jx-1];
+    2897             :                     ix = jx;
+    2898             :                     iy = jy;
+    2899           0 :                     for(i=j;i<=n;i++) {
+    2900           0 :                         a[(j-1)*(lda)+(i-1)] += x[ix-1]*temp1 + y[iy-1]*temp2;
+    2901           0 :                         ix += incx;
+    2902           0 :                         iy += incy;
+    2903             :                     }
+    2904             :                 }
+    2905           0 :                 jx += incx;
+    2906           0 :                 jy += incy;
+    2907             :             }
+    2908             :         }
+    2909             :     }
+    2910             :     
+    2911             :     return;
+    2912             : }
+    2913             : }
+    2914             : }
+    2915             : #include <cctype>
+    2916             : #include <cmath>
+    2917             : 
+    2918             : #include "real.h"
+    2919             : #include "blas.h"
+    2920             : 
+    2921             : namespace PLMD{
+    2922             : namespace blas{
+    2923             : void
+    2924           0 : PLUMED_BLAS_F77_FUNC(ssyr2k,SSYR2K)(const char *uplo, 
+    2925             :                         const char *trans,
+    2926             :                         int *n__,
+    2927             :                         int *k__,
+    2928             :                         float *alpha__,
+    2929             :                         float *a,
+    2930             :                         int *lda__,
+    2931             :                         float *b,
+    2932             :                         int *ldb__,
+    2933             :                         float *beta__,
+    2934             :                         float *c,
+    2935             :                         int *ldc__)
+    2936             : {
+    2937             :   char ch1,ch2;
+    2938             :   int i,j,l;
+    2939             :   float temp1,temp2;
+    2940             : 
+    2941           0 :   int n = *n__;
+    2942           0 :   int k = *k__;
+    2943           0 :   int lda = *lda__;
+    2944           0 :   int ldb = *ldb__;
+    2945           0 :   int ldc = *ldc__;
+    2946             :   
+    2947           0 :   float alpha = *alpha__;
+    2948           0 :   float beta  = *beta__;
+    2949             :   
+    2950           0 :   ch1 = std::toupper(*uplo);
+    2951           0 :   ch2 = std::toupper(*trans);
+    2952             : 
+    2953           0 :   if(n==0 || ( ( std::abs(alpha)<PLUMED_GMX_FLOAT_MIN || k==0 ) && std::abs(beta-1.0)<PLUMED_GMX_FLOAT_EPS))
+    2954             :     return;
+    2955             : 
+    2956           0 :   if(std::abs(alpha)<PLUMED_GMX_FLOAT_MIN) {
+    2957           0 :     if(ch1=='U') {
+    2958           0 :       if(std::abs(beta)<PLUMED_GMX_FLOAT_MIN) 
+    2959           0 :         for(j=1;j<=n;j++) 
+    2960           0 :           for(i=1;i<=j;i++)
+    2961           0 :             c[(j-1)*(ldc)+(i-1)] = 0.0;
+    2962             :       else
+    2963           0 :         for(j=1;j<=n;j++) 
+    2964           0 :           for(i=1;i<=j;i++)
+    2965           0 :             c[(j-1)*(ldc)+(i-1)] *= beta;
+    2966             :     } else {
+    2967             :       /* lower */
+    2968           0 :       if(std::abs(beta)<PLUMED_GMX_FLOAT_MIN) 
+    2969           0 :         for(j=1;j<=n;j++) 
+    2970           0 :           for(i=j;i<=n;i++)
+    2971           0 :             c[(j-1)*(ldc)+(i-1)] = 0.0;
+    2972             :       else
+    2973           0 :         for(j=1;j<=n;j++) 
+    2974           0 :           for(i=j;i<=n;i++)
+    2975           0 :             c[(j-1)*(ldc)+(i-1)] *= beta;
+    2976             :     }
+    2977           0 :     return;
+    2978             :   }
+    2979             : 
+    2980           0 :   if(ch2=='N') {
+    2981           0 :     if(ch1=='U') {
+    2982           0 :       for(j=1;j<=n;j++) {
+    2983           0 :         if(std::abs(beta)<PLUMED_GMX_FLOAT_MIN)
+    2984           0 :           for(i=1;i<=j;i++)
+    2985           0 :              c[(j-1)*(ldc)+(i-1)] = 0.0;
+    2986           0 :         else if(std::abs(beta-1.0)>PLUMED_GMX_FLOAT_EPS)
+    2987           0 :           for(i=1;i<=j;i++)
+    2988           0 :             c[(j-1)*(ldc)+(i-1)] *= beta;
+    2989           0 :         for(l=1;l<=k;l++) {
+    2990           0 :           if( std::abs(a[(l-1)*(lda)+(j-1)])>PLUMED_GMX_FLOAT_MIN ||
+    2991           0 :               std::abs(b[(l-1)*(ldb)+(j-1)])>PLUMED_GMX_FLOAT_MIN) {
+    2992           0 :             temp1 = alpha * b[(l-1)*(ldb)+(j-1)];
+    2993           0 :             temp2 = alpha * a[(l-1)*(lda)+(j-1)];
+    2994           0 :             for(i=1;i<=j;i++)
+    2995           0 :               c[(j-1)*(ldc)+(i-1)] += 
+    2996           0 :                 a[(l-1)*(lda)+(i-1)] * temp1 + 
+    2997           0 :                 b[(l-1)*(ldb)+(i-1)] * temp2;
+    2998             :           }
+    2999             :         }
+    3000             :       }
+    3001             :     } else {
+    3002             :       /* lower */
+    3003           0 :       for(j=1;j<=n;j++) {
+    3004           0 :         if(std::abs(beta)<PLUMED_GMX_FLOAT_MIN)
+    3005           0 :           for(i=j;i<=n;i++)
+    3006           0 :             c[(j-1)*(ldc)+(i-1)] = 0.0;
+    3007           0 :         else if(std::abs(beta-1.0)>PLUMED_GMX_FLOAT_EPS)
+    3008           0 :           for(i=j;i<=n;i++)
+    3009           0 :             c[(j-1)*(ldc)+(i-1)] *= beta;
+    3010           0 :         for(l=1;l<=k;l++) {
+    3011           0 :           if( std::abs(a[(l-1)*(lda)+(j-1)])>PLUMED_GMX_FLOAT_MIN ||
+    3012           0 :               std::abs(b[(l-1)*(ldb)+(j-1)])>PLUMED_GMX_FLOAT_MIN) {
+    3013           0 :             temp1 = alpha * b[(l-1)*(ldb)+(j-1)];
+    3014           0 :             temp2 = alpha * a[(l-1)*(lda)+(j-1)];
+    3015           0 :             for(i=j;i<=n;i++)
+    3016           0 :               c[(j-1)*(ldc)+(i-1)] += 
+    3017           0 :                 a[(l-1)*(lda)+(i-1)] * temp1 + 
+    3018           0 :                 b[(l-1)*(ldb)+(i-1)] * temp2;
+    3019             :           }
+    3020             :         }
+    3021             :       }
+    3022             :     }
+    3023             :   } else {
+    3024             :     /* transpose */
+    3025           0 :     if(ch1=='U') {
+    3026           0 :       for(j=1;j<=n;j++) 
+    3027           0 :         for(i=1;i<=j;i++) {
+    3028             :           temp1 = 0.0;
+    3029             :           temp2 = 0.0;
+    3030           0 :           for (l=1;l<=k;l++) {
+    3031           0 :              temp1 += a[(i-1)*(lda)+(l-1)] * b[(j-1)*(ldb)+(l-1)];
+    3032           0 :              temp2 += b[(i-1)*(ldb)+(l-1)] * a[(j-1)*(lda)+(l-1)];
+    3033             :           }
+    3034           0 :           if(std::abs(beta)<PLUMED_GMX_FLOAT_MIN)
+    3035           0 :             c[(j-1)*(ldc)+(i-1)] = alpha * (temp1 + temp2);
+    3036             :           else
+    3037           0 :             c[(j-1)*(ldc)+(i-1)] = beta * c[(j-1)*(ldc)+(i-1)] +
+    3038           0 :               alpha * (temp1 + temp2);
+    3039             :         }
+    3040             :     } else {
+    3041             :       /* lower */
+    3042           0 :       for(j=1;j<=n;j++) 
+    3043           0 :         for(i=j;i<=n;i++) {
+    3044             :           temp1 = 0.0;
+    3045             :           temp2 = 0.0;
+    3046           0 :           for (l=1;l<=k;l++) {
+    3047           0 :              temp1 += a[(i-1)*(lda)+(l-1)] * b[(j-1)*(ldb)+(l-1)];
+    3048           0 :              temp2 += b[(i-1)*(ldb)+(l-1)] * a[(j-1)*(lda)+(l-1)];
+    3049             :           }
+    3050           0 :           if(std::abs(beta)<PLUMED_GMX_FLOAT_MIN)
+    3051           0 :             c[(j-1)*(ldc)+(i-1)] = alpha * (temp1 + temp2);
+    3052             :           else
+    3053           0 :             c[(j-1)*(ldc)+(i-1)] = beta * c[(j-1)*(ldc)+(i-1)] +
+    3054           0 :               alpha * (temp1 + temp2);
+    3055             :         }
+    3056             :     }
+    3057             :   }
+    3058             :   return;
+    3059             : }
+    3060             : }
+    3061             : }
+    3062             : #include <cmath>
+    3063             : 
+    3064             : #include "real.h"
+    3065             : #include "blas.h"
+    3066             : 
+    3067             : namespace PLMD{
+    3068             : namespace blas{
+    3069             : void 
+    3070           0 : PLUMED_BLAS_F77_FUNC(strmm,STRMM)(const char *side, 
+    3071             :                       const char *uplo, 
+    3072             :                       const char *transa, 
+    3073             :                       const char *diag, 
+    3074             :                       int *m__, 
+    3075             :                       int *n__, 
+    3076             :                       float *alpha__, 
+    3077             :                       float *a, 
+    3078             :                       int *lda__, 
+    3079             :                       float *b, 
+    3080             :                       int *ldb__)
+    3081             : {
+    3082             :     int a_dim1, a_offset, b_dim1, b_offset, i__1, i__2, i__3;
+    3083             :     
+    3084           0 :     int m = *m__;
+    3085           0 :     int n = *n__;
+    3086           0 :     int lda = *lda__;
+    3087           0 :     int ldb = *ldb__;
+    3088           0 :     float alpha = *alpha__;
+    3089             :     
+    3090             :     /* Local variables */
+    3091             :     int i__, j, k;
+    3092             :     float temp;
+    3093             :     int lside;
+    3094             :     int upper;
+    3095             :     int nounit;
+    3096             :     a_dim1 = lda;
+    3097           0 :     a_offset = 1 + a_dim1;
+    3098           0 :     a -= a_offset;
+    3099             :     b_dim1 = ldb;
+    3100           0 :     b_offset = 1 + b_dim1;
+    3101           0 :     b -= b_offset;
+    3102             : 
+    3103             :     /* Function Body */
+    3104           0 :     lside = (*side=='L' || *side=='l');
+    3105             : 
+    3106           0 :     nounit = (*diag=='N' || *diag=='n');
+    3107           0 :     upper = (*uplo=='U' || *uplo=='u');
+    3108             : 
+    3109           0 :     if (n == 0) {
+    3110             :         return;
+    3111             :     }
+    3112           0 :     if (std::abs(alpha)<PLUMED_GMX_FLOAT_MIN) {
+    3113             :         i__1 = n;
+    3114           0 :         for (j = 1; j <= i__1; ++j) {
+    3115             :             i__2 = m;
+    3116           0 :             for (i__ = 1; i__ <= i__2; ++i__) {
+    3117           0 :                 b[i__ + j * b_dim1] = 0.;
+    3118             :             }
+    3119             :         }
+    3120             :         return;
+    3121             :     }
+    3122           0 :     if (lside) {
+    3123           0 :         if (*transa=='N' || *transa=='n') {
+    3124           0 :             if (upper) {
+    3125             :                 i__1 = n;
+    3126           0 :                 for (j = 1; j <= i__1; ++j) {
+    3127             :                     i__2 = m;
+    3128           0 :                     for (k = 1; k <= i__2; ++k) {
+    3129           0 :                         if ( std::abs(b[k + j * b_dim1])>PLUMED_GMX_FLOAT_MIN) {
+    3130           0 :                             temp = alpha * b[k + j * b_dim1];
+    3131             :                             i__3 = k - 1;
+    3132           0 :                             for (i__ = 1; i__ <= i__3; ++i__) {
+    3133           0 :                                 b[i__ + j * b_dim1] += temp * a[i__ + k * 
+    3134           0 :                                         a_dim1];
+    3135             :                             }
+    3136           0 :                             if (nounit) {
+    3137           0 :                                 temp *= a[k + k * a_dim1];
+    3138             :                             }
+    3139           0 :                             b[k + j * b_dim1] = temp;
+    3140             :                         }
+    3141             :                     }
+    3142             :                 }
+    3143             :             } else {
+    3144             :                 i__1 = n;
+    3145           0 :                 for (j = 1; j <= i__1; ++j) {
+    3146           0 :                     for (k = m; k >= 1; --k) {
+    3147           0 :                         if (std::abs(b[k + j * b_dim1])>PLUMED_GMX_FLOAT_MIN) {
+    3148           0 :                             temp = alpha * b[k + j * b_dim1];
+    3149           0 :                             b[k + j * b_dim1] = temp;
+    3150           0 :                             if (nounit) {
+    3151           0 :                                 b[k + j * b_dim1] *= a[k + k * a_dim1];
+    3152             :                             }
+    3153             :                             i__2 = m;
+    3154           0 :                             for (i__ = k + 1; i__ <= i__2; ++i__) {
+    3155           0 :                                 b[i__ + j * b_dim1] += temp * a[i__ + k * 
+    3156           0 :                                         a_dim1];
+    3157             :                             }
+    3158             :                         }
+    3159             :                     }
+    3160             :                 }
+    3161             :             }
+    3162             :         } else {
+    3163             : 
+    3164           0 :             if (upper) {
+    3165             :                 i__1 = n;
+    3166           0 :                 for (j = 1; j <= i__1; ++j) {
+    3167           0 :                     for (i__ = m; i__ >= 1; --i__) {
+    3168           0 :                         temp = b[i__ + j * b_dim1];
+    3169           0 :                         if (nounit) {
+    3170           0 :                             temp *= a[i__ + i__ * a_dim1];
+    3171             :                         }
+    3172             :                         i__2 = i__ - 1;
+    3173           0 :                         for (k = 1; k <= i__2; ++k) {
+    3174           0 :                             temp += a[k + i__ * a_dim1] * b[k + j * b_dim1];
+    3175             :                         }
+    3176           0 :                         b[i__ + j * b_dim1] = alpha * temp;
+    3177             :                     }
+    3178             :                 }
+    3179             :             } else {
+    3180             :                 i__1 = n;
+    3181           0 :                 for (j = 1; j <= i__1; ++j) {
+    3182             :                     i__2 = m;
+    3183           0 :                     for (i__ = 1; i__ <= i__2; ++i__) {
+    3184           0 :                         temp = b[i__ + j * b_dim1];
+    3185           0 :                         if (nounit) {
+    3186           0 :                             temp *= a[i__ + i__ * a_dim1];
+    3187             :                         }
+    3188             :                         i__3 = m;
+    3189           0 :                         for (k = i__ + 1; k <= i__3; ++k) {
+    3190           0 :                             temp += a[k + i__ * a_dim1] * b[k + j * b_dim1];
+    3191             :                         }
+    3192           0 :                         b[i__ + j * b_dim1] = alpha * temp;
+    3193             :                     }
+    3194             :                 }
+    3195             :             }
+    3196             :         }
+    3197             :     } else {
+    3198           0 :         if (*transa=='N' || *transa=='n') {
+    3199             : 
+    3200           0 :             if (upper) {
+    3201           0 :                 for (j = n; j >= 1; --j) {
+    3202             :                     temp = alpha;
+    3203           0 :                     if (nounit) {
+    3204           0 :                         temp *= a[j + j * a_dim1];
+    3205             :                     }
+    3206             :                     i__1 = m;
+    3207           0 :                     for (i__ = 1; i__ <= i__1; ++i__) {
+    3208           0 :                         b[i__ + j * b_dim1] = temp * b[i__ + j * b_dim1];
+    3209             :                     }
+    3210             :                     i__1 = j - 1;
+    3211           0 :                     for (k = 1; k <= i__1; ++k) {
+    3212           0 :                         if ( std::abs(a[k + j * a_dim1])>PLUMED_GMX_FLOAT_MIN) {
+    3213           0 :                             temp = alpha * a[k + j * a_dim1];
+    3214             :                             i__2 = m;
+    3215           0 :                             for (i__ = 1; i__ <= i__2; ++i__) {
+    3216           0 :                                 b[i__ + j * b_dim1] += temp * b[i__ + k * 
+    3217           0 :                                         b_dim1];
+    3218             :                             }
+    3219             :                         }
+    3220             :                     }
+    3221             :                 }
+    3222             :             } else {
+    3223             :                 i__1 = n;
+    3224           0 :                 for (j = 1; j <= i__1; ++j) {
+    3225             :                     temp = alpha;
+    3226           0 :                     if (nounit) {
+    3227           0 :                         temp *= a[j + j * a_dim1];
+    3228             :                     }
+    3229             :                     i__2 = m;
+    3230           0 :                     for (i__ = 1; i__ <= i__2; ++i__) {
+    3231           0 :                         b[i__ + j * b_dim1] = temp * b[i__ + j * b_dim1];
+    3232             :                     }
+    3233             :                     i__2 = n;
+    3234           0 :                     for (k = j + 1; k <= i__2; ++k) {
+    3235           0 :                         if ( std::abs(a[k + j * a_dim1])>PLUMED_GMX_FLOAT_MIN) {
+    3236           0 :                             temp = alpha * a[k + j * a_dim1];
+    3237             :                             i__3 = m;
+    3238           0 :                             for (i__ = 1; i__ <= i__3; ++i__) {
+    3239           0 :                                 b[i__ + j * b_dim1] += temp * b[i__ + k * 
+    3240           0 :                                         b_dim1];
+    3241             :                             }
+    3242             :                         }
+    3243             :                     }
+    3244             :                 }
+    3245             :             }
+    3246             :         } else {
+    3247             : 
+    3248           0 :             if (upper) {
+    3249             :                 i__1 = n;
+    3250           0 :                 for (k = 1; k <= i__1; ++k) {
+    3251             :                     i__2 = k - 1;
+    3252           0 :                     for (j = 1; j <= i__2; ++j) {
+    3253           0 :                         if ( std::abs(a[j + k * a_dim1])>PLUMED_GMX_FLOAT_MIN ) {
+    3254           0 :                             temp = alpha * a[j + k * a_dim1];
+    3255             :                             i__3 = m;
+    3256           0 :                             for (i__ = 1; i__ <= i__3; ++i__) {
+    3257           0 :                                 b[i__ + j * b_dim1] += temp * b[i__ + k * 
+    3258           0 :                                         b_dim1];
+    3259             :                             }
+    3260             :                         }
+    3261             :                     }
+    3262             :                     temp = alpha;
+    3263           0 :                     if (nounit) {
+    3264           0 :                         temp *= a[k + k * a_dim1];
+    3265             :                     }
+    3266           0 :                     if ( std::abs(temp-1.0)>PLUMED_GMX_FLOAT_EPS) {
+    3267             :                         i__2 = m;
+    3268           0 :                         for (i__ = 1; i__ <= i__2; ++i__) {
+    3269           0 :                             b[i__ + k * b_dim1] = temp * b[i__ + k * b_dim1];
+    3270             :                         }
+    3271             :                     }
+    3272             :                 }
+    3273             :             } else {
+    3274           0 :                 for (k = n; k >= 1; --k) {
+    3275             :                     i__1 = n;
+    3276           0 :                     for (j = k + 1; j <= i__1; ++j) {
+    3277           0 :                         if ( std::abs(a[j + k * a_dim1])>PLUMED_GMX_FLOAT_MIN) {
+    3278           0 :                             temp = alpha * a[j + k * a_dim1];
+    3279             :                             i__2 = m;
+    3280           0 :                             for (i__ = 1; i__ <= i__2; ++i__) {
+    3281           0 :                                 b[i__ + j * b_dim1] += temp * b[i__ + k * 
+    3282           0 :                                         b_dim1];
+    3283             :                             }
+    3284             :                         }
+    3285             :                     }
+    3286             :                     temp = alpha;
+    3287           0 :                     if (nounit) {
+    3288           0 :                         temp *= a[k + k * a_dim1];
+    3289             :                     }
+    3290           0 :                     if ( std::abs(temp-1.0)>PLUMED_GMX_FLOAT_EPS) {
+    3291             :                         i__1 = m;
+    3292           0 :                         for (i__ = 1; i__ <= i__1; ++i__) {
+    3293           0 :                             b[i__ + k * b_dim1] = temp * b[i__ + k * b_dim1];
+    3294             :                         }
+    3295             :                     }
+    3296             :                 }
+    3297             :             }
+    3298             :         }
+    3299             :     }
+    3300             : 
+    3301             :     return;
+    3302             : 
+    3303             : }
+    3304             : 
+    3305             : 
+    3306             : }
+    3307             : }
+    3308             : #include <cmath>
+    3309             : 
+    3310             : #include "real.h"
+    3311             : #include "blas.h"
+    3312             : 
+    3313             : namespace PLMD{
+    3314             : namespace blas{
+    3315             : void 
+    3316           0 : PLUMED_BLAS_F77_FUNC(strmv,STRMV)(const char *uplo, 
+    3317             :                       const char *trans,
+    3318             :                       const char *diag, 
+    3319             :                       int *n__, 
+    3320             :                       float *a, 
+    3321             :                       int *lda__, 
+    3322             :                       float *x, 
+    3323             :                       int *incx__)
+    3324             : {
+    3325             :     int a_dim1, a_offset, i__1, i__2;
+    3326             : 
+    3327             :     int i__, j, ix, jx, kx;
+    3328             :     float temp;
+    3329             :     int nounit;
+    3330             :     
+    3331           0 :     int n = *n__;
+    3332           0 :     int lda = *lda__;
+    3333           0 :     int incx = *incx__;
+    3334             :     
+    3335             :     a_dim1 = lda;
+    3336           0 :     a_offset = 1 + a_dim1;
+    3337           0 :     a -= a_offset;
+    3338           0 :     --x;
+    3339             : 
+    3340           0 :     if (n == 0) {
+    3341             :         return;
+    3342             :     }
+    3343             : 
+    3344           0 :     nounit = (*diag=='n' || *diag=='N');
+    3345             : 
+    3346           0 :     if (incx <= 0) {
+    3347           0 :         kx = 1 - (n - 1) * incx;
+    3348             :     } else {
+    3349             :         kx = 1;
+    3350             :     }
+    3351             : 
+    3352           0 :     if (*trans=='N' || *trans=='n') {
+    3353             : 
+    3354           0 :         if (*uplo=='U' || *uplo=='u') {
+    3355           0 :             if (incx == 1) {
+    3356             :                 i__1 = n;
+    3357           0 :                 for (j = 1; j <= i__1; ++j) {
+    3358           0 :                     if (std::abs(x[j])>PLUMED_GMX_FLOAT_MIN) {
+    3359             :                         temp = x[j];
+    3360             :                         i__2 = j - 1;
+    3361           0 :                         for (i__ = 1; i__ <= i__2; ++i__) {
+    3362           0 :                             x[i__] += temp * a[i__ + j * a_dim1];
+    3363             :                         }
+    3364           0 :                         if (nounit) {
+    3365           0 :                             x[j] *= a[j + j * a_dim1];
+    3366             :                         }
+    3367             :                     }
+    3368             :                 }
+    3369             :             } else {
+    3370             :                 jx = kx;
+    3371             :                 i__1 = n;
+    3372           0 :                 for (j = 1; j <= i__1; ++j) {
+    3373           0 :                     if (std::abs(x[jx])>PLUMED_GMX_FLOAT_MIN) {
+    3374             :                         temp = x[jx];
+    3375             :                         ix = kx;
+    3376             :                         i__2 = j - 1;
+    3377           0 :                         for (i__ = 1; i__ <= i__2; ++i__) {
+    3378           0 :                             x[ix] += temp * a[i__ + j * a_dim1];
+    3379           0 :                             ix += incx;
+    3380             :                         }
+    3381           0 :                         if (nounit) {
+    3382           0 :                             x[jx] *= a[j + j * a_dim1];
+    3383             :                         }
+    3384             :                     }
+    3385           0 :                     jx += incx;
+    3386             :                 }
+    3387             :             }
+    3388             :         } else {
+    3389           0 :             if (incx == 1) {
+    3390           0 :                 for (j = n; j >= 1; --j) {
+    3391           0 :                     if (std::abs(x[j])>PLUMED_GMX_FLOAT_MIN) {
+    3392             :                         temp = x[j];
+    3393             :                         i__1 = j + 1;
+    3394           0 :                         for (i__ = n; i__ >= i__1; --i__) {
+    3395           0 :                             x[i__] += temp * a[i__ + j * a_dim1];
+    3396             :                         }
+    3397           0 :                         if (nounit) {
+    3398           0 :                             x[j] *= a[j + j * a_dim1];
+    3399             :                         }
+    3400             :                     }
+    3401             :                 }
+    3402             :             } else {
+    3403           0 :                 kx += (n - 1) * incx;
+    3404             :                 jx = kx;
+    3405           0 :                 for (j = n; j >= 1; --j) {
+    3406           0 :                     if (std::abs(x[jx])>PLUMED_GMX_FLOAT_MIN) {
+    3407             :                         temp = x[jx];
+    3408             :                         ix = kx;
+    3409             :                         i__1 = j + 1;
+    3410           0 :                         for (i__ = n; i__ >= i__1; --i__) {
+    3411           0 :                             x[ix] += temp * a[i__ + j * a_dim1];
+    3412           0 :                             ix -= incx;
+    3413             :                         }
+    3414           0 :                         if (nounit) {
+    3415           0 :                             x[jx] *= a[j + j * a_dim1];
+    3416             :                         }
+    3417             :                     }
+    3418           0 :                     jx -= incx;
+    3419             :                 }
+    3420             :             }
+    3421             :         }
+    3422             :     } else {
+    3423             : 
+    3424           0 :         if (*uplo=='U' || *uplo=='u') {
+    3425           0 :             if (incx == 1) {
+    3426           0 :                 for (j = n; j >= 1; --j) {
+    3427           0 :                     temp = x[j];
+    3428           0 :                     if (nounit) {
+    3429           0 :                         temp *= a[j + j * a_dim1];
+    3430             :                     }
+    3431           0 :                     for (i__ = j - 1; i__ >= 1; --i__) {
+    3432           0 :                         temp += a[i__ + j * a_dim1] * x[i__];
+    3433             :                     }
+    3434           0 :                     x[j] = temp;
+    3435             :                 }
+    3436             :             } else {
+    3437           0 :                 jx = kx + (n - 1) * incx;
+    3438           0 :                 for (j = n; j >= 1; --j) {
+    3439           0 :                     temp = x[jx];
+    3440             :                     ix = jx;
+    3441           0 :                     if (nounit) {
+    3442           0 :                         temp *= a[j + j * a_dim1];
+    3443             :                     }
+    3444           0 :                     for (i__ = j - 1; i__ >= 1; --i__) {
+    3445           0 :                         ix -= incx;
+    3446           0 :                         temp += a[i__ + j * a_dim1] * x[ix];
+    3447             :                     }
+    3448           0 :                     x[jx] = temp;
+    3449           0 :                     jx -= incx;
+    3450             :                 }
+    3451             :             }
+    3452             :         } else {
+    3453           0 :             if (incx == 1) {
+    3454             :                 i__1 = n;
+    3455           0 :                 for (j = 1; j <= i__1; ++j) {
+    3456           0 :                     temp = x[j];
+    3457           0 :                     if (nounit) {
+    3458           0 :                         temp *= a[j + j * a_dim1];
+    3459             :                     }
+    3460             :                     i__2 = n;
+    3461           0 :                     for (i__ = j + 1; i__ <= i__2; ++i__) {
+    3462           0 :                         temp += a[i__ + j * a_dim1] * x[i__];
+    3463             :                     }
+    3464           0 :                     x[j] = temp;
+    3465             :                 }
+    3466             :             } else {
+    3467             :                 jx = kx;
+    3468             :                 i__1 = n;
+    3469           0 :                 for (j = 1; j <= i__1; ++j) {
+    3470           0 :                     temp = x[jx];
+    3471             :                     ix = jx;
+    3472           0 :                     if (nounit) {
+    3473           0 :                         temp *= a[j + j * a_dim1];
+    3474             :                     }
+    3475             :                     i__2 = n;
+    3476           0 :                     for (i__ = j + 1; i__ <= i__2; ++i__) {
+    3477           0 :                         ix += incx;
+    3478           0 :                         temp += a[i__ + j * a_dim1] * x[ix];
+    3479             :                     }
+    3480           0 :                     x[jx] = temp;
+    3481           0 :                     jx += incx;
+    3482             :                 }
+    3483             :             }
+    3484             :         }
+    3485             :     }
+    3486             : 
+    3487             :     return;
+    3488             : 
+    3489             : }
+    3490             : 
+    3491             : 
+    3492             : }
+    3493             : }
+    3494             : #include <cctype>
+    3495             : #include <cmath>
+    3496             : 
+    3497             : #include "real.h"
+    3498             : #include "blas.h"
+    3499             : 
+    3500             : namespace PLMD{
+    3501             : namespace blas{
+    3502             : void
+    3503           0 : PLUMED_BLAS_F77_FUNC(strsm,STRSM)(const char * side,
+    3504             :                       const char * uplo,
+    3505             :                       const char * transa,
+    3506             :                       const char * diag,
+    3507             :                       int *  m__,
+    3508             :                       int *  n__,
+    3509             :                       float *alpha__,
+    3510             :                       float *a,
+    3511             :                       int *  lda__,
+    3512             :                       float *b,
+    3513             :                       int *  ldb__)
+    3514             : {
+    3515           0 :   const char xside  = std::toupper(*side);
+    3516           0 :   const char xuplo  = std::toupper(*uplo);
+    3517           0 :   const char xtrans = std::toupper(*transa);
+    3518           0 :   const char xdiag  = std::toupper(*diag);
+    3519             :   int i,j,k;
+    3520             :   float temp;
+    3521             : 
+    3522           0 :   int m = *m__;
+    3523           0 :   int n = *n__;
+    3524           0 :   int lda = *lda__;
+    3525           0 :   int ldb = *ldb__;
+    3526           0 :   float alpha = *alpha__;
+    3527             :   
+    3528           0 :   if(n<=0)
+    3529             :     return;
+    3530             : 
+    3531             :   
+    3532           0 :   if(std::abs(alpha)<PLUMED_GMX_FLOAT_MIN) { 
+    3533           0 :     for(j=0;j<n;j++)
+    3534           0 :       for(i=0;i<m;i++)
+    3535           0 :         b[j*(ldb)+i] = 0.0;
+    3536             :     return;
+    3537             :   }
+    3538             : 
+    3539           0 :   if(xside=='L') {
+    3540             :     /* left side */
+    3541           0 :     if(xtrans=='N') {
+    3542             :       /* No transpose */
+    3543           0 :       if(xuplo=='U') {
+    3544             :         /* upper */
+    3545           0 :         for(j=0;j<n;j++) {
+    3546           0 :           if(std::abs(alpha-1.0)>PLUMED_GMX_FLOAT_EPS) {
+    3547           0 :             for(i=0;i<m;i++)
+    3548           0 :               b[j*(ldb)+i] *= alpha;
+    3549             :           }
+    3550           0 :           for(k=m-1;k>=0;k--) {
+    3551           0 :             if( std::abs(b[j*(ldb)+k])>PLUMED_GMX_FLOAT_MIN) {
+    3552           0 :               if(xdiag=='N')
+    3553           0 :                 b[j*(ldb)+k] /= a[k*(lda)+k];
+    3554           0 :               for(i=0;i<k;i++)
+    3555           0 :                 b[j*(ldb)+i] -= b[j*(ldb)+k]*a[k*(lda)+i];
+    3556             :             }
+    3557             :           }
+    3558             :         }
+    3559             :       } else {
+    3560             :         /* lower */
+    3561           0 :         for(j=0;j<n;j++) {
+    3562           0 :           if(std::abs(alpha-1.0)>PLUMED_GMX_FLOAT_EPS)
+    3563           0 :             for(i=0;i<m;i++)
+    3564           0 :               b[j*(ldb)+i] *= alpha;
+    3565           0 :           for(k=0;k<m;k++) {
+    3566           0 :             if( std::abs(b[j*(ldb)+k])>PLUMED_GMX_FLOAT_MIN) {
+    3567           0 :               if(xdiag=='N')
+    3568           0 :                 b[j*(ldb)+k] /= a[k*(lda)+k];
+    3569           0 :               for(i=k+1;i<m;i++)
+    3570           0 :                 b[j*(ldb)+i] -= b[j*(ldb)+k]*a[k*(lda)+i];
+    3571             :             }
+    3572             :           }
+    3573             :         }
+    3574             :       }
+    3575             :     } else {
+    3576             :       /* Transpose */
+    3577           0 :       if(xuplo=='U') {
+    3578             :         /* upper */
+    3579           0 :         for(j=0;j<n;j++) {
+    3580           0 :           for(i=0;i<m;i++) {
+    3581           0 :             temp = alpha * b[j*(ldb)+i];
+    3582           0 :             for(k=0;k<i;k++)
+    3583           0 :               temp -= a[i*(lda)+k] * b[j*(ldb)+k];
+    3584           0 :             if(xdiag=='N')
+    3585           0 :                 temp /= a[i*(lda)+i];
+    3586           0 :             b[j*(ldb)+i] = temp;
+    3587             :           }
+    3588             :         }
+    3589             :       } else {
+    3590             :         /* lower */
+    3591           0 :         for(j=0;j<n;j++) {
+    3592           0 :           for(i=m-1;i>=0;i--) {
+    3593           0 :             temp = alpha * b[j*(ldb)+i];
+    3594           0 :             for(k=i+1;k<m;k++)
+    3595           0 :               temp -= a[i*(lda)+k] * b[j*(ldb)+k];
+    3596           0 :             if(xdiag=='N')
+    3597           0 :                 temp /= a[i*(lda)+i];
+    3598           0 :             b[j*(ldb)+i] = temp;
+    3599             :           }
+    3600             :         }
+    3601             :       }
+    3602             :     }
+    3603             :   } else {
+    3604             :     /* right side */
+    3605           0 :     if(xtrans=='N') {
+    3606             :       /* No transpose */
+    3607           0 :       if(xuplo=='U') {
+    3608             :         /* upper */
+    3609           0 :         for(j=0;j<n;j++) {
+    3610           0 :           if(std::abs(alpha-1.0)>PLUMED_GMX_FLOAT_EPS)
+    3611           0 :             for(i=0;i<m;i++)
+    3612           0 :               b[j*(ldb)+i] *= alpha;
+    3613           0 :           for(k=0;k<j;k++) {
+    3614           0 :             if( std::abs(a[j*(lda)+k])>PLUMED_GMX_FLOAT_MIN) {
+    3615           0 :               for(i=0;i<m;i++)
+    3616           0 :                 b[j*(ldb)+i] -= a[j*(lda)+k]*b[k*(ldb)+i];
+    3617             :             }
+    3618             :           }
+    3619           0 :           if(xdiag=='N') {
+    3620           0 :             temp = 1.0/a[j*(lda)+j];
+    3621           0 :             for(i=0;i<m;i++)
+    3622           0 :               b[j*(ldb)+i] *= temp;
+    3623             :           }
+    3624             :         }
+    3625             :       } else {
+    3626             :         /* lower */
+    3627           0 :         for(j=n-1;j>=0;j--) {
+    3628           0 :           if(std::abs(alpha-1.0)>PLUMED_GMX_FLOAT_EPS)
+    3629           0 :             for(i=0;i<m;i++)
+    3630           0 :               b[j*(ldb)+i] *= alpha;
+    3631           0 :           for(k=j+1;k<n;k++) {
+    3632           0 :             if( std::abs(a[j*(lda)+k])>PLUMED_GMX_FLOAT_MIN ) {
+    3633           0 :               for(i=0;i<m;i++)
+    3634           0 :                 b[j*(ldb)+i] -= a[j*(lda)+k]*b[k*(ldb)+i];
+    3635             :             }
+    3636             :           }
+    3637           0 :           if(xdiag=='N') {
+    3638           0 :             temp = 1.0/a[j*(lda)+j];
+    3639           0 :             for(i=0;i<m;i++)
+    3640           0 :               b[j*(ldb)+i] *= temp;
+    3641             :           }
+    3642             :         }
+    3643             :       }
+    3644             :     } else {
+    3645             :       /* Transpose */
+    3646           0 :       if(xuplo=='U') {
+    3647             :         /* upper */
+    3648           0 :         for(k=n-1;k>=0;k--) {
+    3649           0 :           if(xdiag=='N') {
+    3650           0 :             temp = 1.0/a[k*(lda)+k];
+    3651           0 :             for(i=0;i<m;i++)
+    3652           0 :               b[k*(ldb)+i] *= temp;
+    3653             :           }
+    3654           0 :           for(j=0;j<k;j++) {
+    3655           0 :             if( std::abs(a[k*(lda)+j])>PLUMED_GMX_FLOAT_MIN) {
+    3656             :               temp = a[k*(lda)+j];
+    3657           0 :               for(i=0;i<m;i++)
+    3658           0 :                 b[j*(ldb)+i] -= temp * b[k*(ldb)+i];
+    3659             :             }
+    3660             :           }
+    3661           0 :           if(std::abs(alpha-1.0)>PLUMED_GMX_FLOAT_EPS)
+    3662           0 :             for(i=0;i<m;i++)
+    3663           0 :               b[k*(ldb)+i] *= alpha;
+    3664             :         }
+    3665             :       } else {
+    3666             :         /* lower */
+    3667           0 :         for(k=0;k<n;k++) {
+    3668           0 :           if(xdiag=='N') {
+    3669           0 :             temp = 1.0/a[k*(lda)+k];
+    3670           0 :             for(i=0;i<m;i++)
+    3671           0 :               b[k*(ldb)+i] *= temp;
+    3672             :           }
+    3673           0 :           for(j=k+1;j<n;j++) {
+    3674           0 :             if( std::abs(a[k*(lda)+j])>PLUMED_GMX_FLOAT_MIN) {
+    3675             :               temp = a[k*(lda)+j];
+    3676           0 :               for(i=0;i<m;i++)
+    3677           0 :                 b[j*(ldb)+i] -= temp * b[k*(ldb)+i];
+    3678             :             }
+    3679             :           }
+    3680           0 :           if(std::abs(alpha-1.0)>PLUMED_GMX_FLOAT_EPS)
+    3681           0 :             for(i=0;i<m;i++)
+    3682           0 :               b[k*(ldb)+i] *= alpha;
+    3683             :         }
+    3684             :       }      
+    3685             :     }
+    3686             :   }    
+    3687             : }
+    3688             : }
+    3689             : }
+    3690             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/blas/index-sort-f.html b/coverage-libs/blas/index-sort-f.html new file mode 100644 index 000000000000..111aade0860c --- /dev/null +++ b/coverage-libs/blas/index-sort-f.html @@ -0,0 +1,94 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - blas + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - blasHitTotalCoverage
Test:plumed test coverage (other modules)Lines:406160525.3 %
Date:2024-04-19 12:12:36Functions:173647.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
blas.cpp +
25.3%25.3%
+
25.3 %406 / 160547.2 %17 / 36
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/blas/index-sort-l.html b/coverage-libs/blas/index-sort-l.html new file mode 100644 index 000000000000..a4077e85fbaf --- /dev/null +++ b/coverage-libs/blas/index-sort-l.html @@ -0,0 +1,94 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - blas + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - blasHitTotalCoverage
Test:plumed test coverage (other modules)Lines:406160525.3 %
Date:2024-04-19 12:12:36Functions:173647.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
blas.cpp +
25.3%25.3%
+
25.3 %406 / 160547.2 %17 / 36
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/blas/index.html b/coverage-libs/blas/index.html new file mode 100644 index 000000000000..661e3f01eceb --- /dev/null +++ b/coverage-libs/blas/index.html @@ -0,0 +1,94 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - blas + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - blasHitTotalCoverage
Test:plumed test coverage (other modules)Lines:406160525.3 %
Date:2024-04-19 12:12:36Functions:173647.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

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

Directory Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
lapack +
25.3%25.3%
+
25.3 %3849 / 1522635.9 %65 / 181
asmjit +
31.7%31.7%
+
31.7 %2260 / 712439.8 %140 / 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.3%25.3%
+
25.3 %406 / 160547.2 %17 / 36
lepton +
89.9%89.9%
+
89.9 %1609 / 178992.5 %396 / 428
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/index-sort-l.html b/coverage-libs/index-sort-l.html new file mode 100644 index 000000000000..5e126bf530b3 --- /dev/null +++ b/coverage-libs/index-sort-l.html @@ -0,0 +1,144 @@ + + + + + + + + LCOV - plumed test coverage (other modules) + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top levelHitTotalCoverage
Test:plumed test coverage (other modules)Lines:95482901432.9 %
Date:2024-04-19 12:12:36Functions:717121459.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Directory Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
blas +
25.3%25.3%
+
25.3 %406 / 160547.2 %17 / 36
lapack +
25.3%25.3%
+
25.3 %3849 / 1522635.9 %65 / 181
asmjit +
31.7%31.7%
+
31.7 %2260 / 712439.8 %140 / 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.9%89.9%
+
89.9 %1609 / 178992.5 %396 / 428
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/index.html b/coverage-libs/index.html new file mode 100644 index 000000000000..d86023d8f576 --- /dev/null +++ b/coverage-libs/index.html @@ -0,0 +1,144 @@ + + + + + + + + LCOV - plumed test coverage (other modules) + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top levelHitTotalCoverage
Test:plumed test coverage (other modules)Lines:95482901432.9 %
Date:2024-04-19 12:12:36Functions:717121459.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Directory Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
asmjit +
31.7%31.7%
+
31.7 %2260 / 712439.8 %140 / 352
blas +
25.3%25.3%
+
25.3 %406 / 160547.2 %17 / 36
lapack +
25.3%25.3%
+
25.3 %3849 / 1522635.9 %65 / 181
lepton +
89.9%89.9%
+
89.9 %1609 / 178992.5 %396 / 428
molfile +
40.9%40.9%
+
40.9 %861 / 210445.2 %56 / 124
xdrfile +
48.3%48.3%
+
48.3 %563 / 116646.2 %43 / 93
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lapack/index-sort-f.html b/coverage-libs/lapack/index-sort-f.html new file mode 100644 index 000000000000..886a8459a0f0 --- /dev/null +++ b/coverage-libs/lapack/index-sort-f.html @@ -0,0 +1,94 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - lapack + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lapackHitTotalCoverage
Test:plumed test coverage (other modules)Lines:38491522625.3 %
Date:2024-04-19 12:12:36Functions:6518135.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
lapack.cpp +
25.3%25.3%
+
25.3 %3849 / 1522635.9 %65 / 181
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lapack/index-sort-l.html b/coverage-libs/lapack/index-sort-l.html new file mode 100644 index 000000000000..9955309520e4 --- /dev/null +++ b/coverage-libs/lapack/index-sort-l.html @@ -0,0 +1,94 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - lapack + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lapackHitTotalCoverage
Test:plumed test coverage (other modules)Lines:38491522625.3 %
Date:2024-04-19 12:12:36Functions:6518135.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
lapack.cpp +
25.3%25.3%
+
25.3 %3849 / 1522635.9 %65 / 181
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lapack/index.html b/coverage-libs/lapack/index.html new file mode 100644 index 000000000000..8731530b32b1 --- /dev/null +++ b/coverage-libs/lapack/index.html @@ -0,0 +1,94 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - lapack + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lapackHitTotalCoverage
Test:plumed test coverage (other modules)Lines:38491522625.3 %
Date:2024-04-19 12:12:36Functions:6518135.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
lapack.cpp +
25.3%25.3%
+
25.3 %3849 / 1522635.9 %65 / 181
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lapack/lapack.cpp.func-sort-c.html b/coverage-libs/lapack/lapack.cpp.func-sort-c.html new file mode 100644 index 000000000000..ee03507145a4 --- /dev/null +++ b/coverage-libs/lapack/lapack.cpp.func-sort-c.html @@ -0,0 +1,797 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - lapack/lapack.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lapack - lapack.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:38491522625.3 %
Date:2024-04-19 12:12:36Functions:6518135.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6lapack6dlae2_EPdS1_S1_S1_S1_0
_ZN4PLMD6lapack6slae2_EPfS1_S1_S1_S1_0
_ZN4PLMD6lapack6slarf_EPKcPiS3_PfS3_S4_S4_S3_S4_0
_ZN4PLMD6lapack6slas2_EPfS1_S1_S1_S1_0
_ZN4PLMD6lapack6slasr_EPKcS2_S2_PiS3_PfS4_S4_S3_0
_ZN4PLMD6lapack7dgelq2_EPiS1_PdS1_S2_S2_S1_0
_ZN4PLMD6lapack7dgelqf_EPiS1_PdS1_S2_S2_S1_S1_0
_ZN4PLMD6lapack7dgetrs_EPKcPiS3_PdS3_S3_S4_S3_S3_0
_ZN4PLMD6lapack7dlaebz_EPiS1_S1_S1_S1_S1_PdS2_S2_S2_S2_S2_S1_S2_S2_S1_S1_S2_S1_S1_0
_ZN4PLMD6lapack7dlaev2_EPdS1_S1_S1_S1_S1_S1_0
_ZN4PLMD6lapack7dlagtf_EPiPdS2_S2_S2_S2_S2_S1_S1_0
_ZN4PLMD6lapack7dlagts_EPiS1_PdS2_S2_S2_S1_S2_S2_S1_0
_ZN4PLMD6lapack7dlarnv_EPiS1_S1_Pd0
_ZN4PLMD6lapack7dlaruv_EPiS1_Pd0
_ZN4PLMD6lapack7dlasd5_EPiPdS2_S2_S2_S2_S2_0
_ZN4PLMD6lapack7dlasd6_EPiS1_S1_S1_PdS2_S2_S2_S2_S1_S1_S1_S1_S1_S2_S1_S2_S2_S2_S2_S1_S2_S2_S2_S1_S1_0
_ZN4PLMD6lapack7dlasd7_EPiS1_S1_S1_S1_PdS2_S2_S2_S2_S2_S2_S2_S2_S2_S1_S1_S1_S1_S1_S1_S1_S2_S1_S2_S2_S1_0
_ZN4PLMD6lapack7dlasd8_EPiS1_PdS2_S2_S2_S2_S2_S1_S2_S2_S1_0
_ZN4PLMD6lapack7dlasda_EPiS1_S1_S1_PdS2_S2_S1_S2_S1_S2_S2_S2_S2_S1_S1_S1_S1_S2_S2_S2_S2_S1_S1_0
_ZN4PLMD6lapack7dlasq1_EPiPdS2_S2_S1_0
_ZN4PLMD6lapack7dlasq6_EPiS1_PdS1_S2_S2_S2_S2_S2_S2_0
_ZN4PLMD6lapack7dlassq_EPiPdS1_S2_S2_0
_ZN4PLMD6lapack7dlaswp_EPiPdS1_S1_S1_S1_S1_0
_ZN4PLMD6lapack7dorgbr_EPKcPiS3_S3_PdS3_S4_S4_S3_S3_0
_ZN4PLMD6lapack7dorgl2_EPiS1_S1_PdS1_S2_S2_S1_0
_ZN4PLMD6lapack7dorglq_EPiS1_S1_PdS1_S2_S2_S1_S1_0
_ZN4PLMD6lapack7dstebz_EPKcS2_PiPdS4_S3_S3_S4_S4_S4_S3_S3_S4_S3_S3_S4_S3_S3_0
_ZN4PLMD6lapack7dstein_EPiPdS2_S1_S2_S1_S1_S2_S1_S2_S1_S1_S1_0
_ZN4PLMD6lapack7dsteqr_EPKcPiPdS4_S4_S3_S4_S3_0
_ZN4PLMD6lapack7dsterf_EPiPdS2_S1_0
_ZN4PLMD6lapack7dstevr_EPKcS2_PiPdS4_S4_S4_S3_S3_S4_S3_S4_S4_S3_S3_S4_S3_S3_S3_S3_0
_ZN4PLMD6lapack7sbdsdc_EPKcS2_PiPfS4_S4_S3_S4_S3_S4_S3_S4_S3_S3_0
_ZN4PLMD6lapack7sbdsqr_EPKcPiS3_S3_S3_PfS4_S4_S3_S4_S3_S4_S3_S4_S3_0
_ZN4PLMD6lapack7sgebd2_EPiS1_PfS1_S2_S2_S2_S2_S2_S1_0
_ZN4PLMD6lapack7sgebrd_EPiS1_PfS1_S2_S2_S2_S2_S2_S1_S1_0
_ZN4PLMD6lapack7sgelq2_EPiS1_PfS1_S2_S2_S1_0
_ZN4PLMD6lapack7sgelqf_EPiS1_PfS1_S2_S2_S1_S1_0
_ZN4PLMD6lapack7sgeqr2_EPiS1_PfS1_S2_S2_S1_0
_ZN4PLMD6lapack7sgeqrf_EPiS1_PfS1_S2_S2_S1_S1_0
_ZN4PLMD6lapack7sgesdd_EPKcPiS3_PfS3_S4_S4_S3_S4_S3_S4_S3_S3_S3_0
_ZN4PLMD6lapack7sgetf2_EPiS1_PfS1_S1_S1_0
_ZN4PLMD6lapack7sgetrf_EPiS1_PfS1_S1_S1_0
_ZN4PLMD6lapack7sgetri_EPiPfS1_S1_S2_S1_S1_0
_ZN4PLMD6lapack7sgetrs_EPKcPiS3_PfS3_S3_S4_S3_S3_0
_ZN4PLMD6lapack7slabrd_EPiS1_S1_PfS1_S2_S2_S2_S2_S2_S1_S2_S1_0
_ZN4PLMD6lapack7slacpy_EPKcPiS3_PfS3_S4_S3_0
_ZN4PLMD6lapack7slaebz_EPiS1_S1_S1_S1_S1_PfS2_S2_S2_S2_S2_S1_S2_S2_S1_S1_S2_S1_S1_0
_ZN4PLMD6lapack7slaed6_EPiS1_PfS2_S2_S2_S2_S1_0
_ZN4PLMD6lapack7slaev2_EPfS1_S1_S1_S1_S1_S1_0
_ZN4PLMD6lapack7slagtf_EPiPfS2_S2_S2_S2_S2_S1_S1_0
_ZN4PLMD6lapack7slagts_EPiS1_PfS2_S2_S2_S1_S2_S2_S1_0
_ZN4PLMD6lapack7slamrg_EPiS1_PfS1_S1_S1_0
_ZN4PLMD6lapack7slange_EPKcPiS3_PfS3_S4_0
_ZN4PLMD6lapack7slanst_EPKcPiPfS4_0
_ZN4PLMD6lapack7slansy_EPKcS2_PiPfS3_S4_0
_ZN4PLMD6lapack7slarfb_EPKcS2_S2_S2_PiS3_S3_PfS3_S4_S3_S4_S3_S4_S3_0
_ZN4PLMD6lapack7slarfg_EPiPfS2_S1_S2_0
_ZN4PLMD6lapack7slarft_EPKcS2_PiS3_PfS3_S4_S4_S3_0
_ZN4PLMD6lapack7slarnv_EPiS1_S1_Pf0
_ZN4PLMD6lapack7slartg_EPfS1_S1_S1_S1_0
_ZN4PLMD6lapack7slaruv_EPiS1_Pf0
_ZN4PLMD6lapack7slascl_EPKcPiS3_PfS4_S3_S3_S4_S3_S3_0
_ZN4PLMD6lapack7slasd0_EPiS1_PfS2_S2_S1_S2_S1_S1_S1_S2_S1_0
_ZN4PLMD6lapack7slasd1_EPiS1_S1_PfS2_S2_S2_S1_S2_S1_S1_S1_S2_S1_0
_ZN4PLMD6lapack7slasd2_EPiS1_S1_S1_PfS2_S2_S2_S2_S1_S2_S1_S2_S2_S1_S2_S1_S1_S1_S1_S1_S1_S1_0
_ZN4PLMD6lapack7slasd3_EPiS1_S1_S1_PfS2_S1_S2_S2_S1_S2_S1_S2_S1_S2_S1_S1_S1_S2_S1_0
_ZN4PLMD6lapack7slasd4_EPiS1_PfS2_S2_S2_S2_S2_S1_0
_ZN4PLMD6lapack7slasd5_EPiPfS2_S2_S2_S2_S2_0
_ZN4PLMD6lapack7slasd6_EPiS1_S1_S1_PfS2_S2_S2_S2_S1_S1_S1_S1_S1_S2_S1_S2_S2_S2_S2_S1_S2_S2_S2_S1_S1_0
_ZN4PLMD6lapack7slasd7_EPiS1_S1_S1_S1_PfS2_S2_S2_S2_S2_S2_S2_S2_S2_S1_S1_S1_S1_S1_S1_S1_S2_S1_S2_S2_S1_0
_ZN4PLMD6lapack7slasd8_EPiS1_PfS2_S2_S2_S2_S2_S1_S2_S2_S1_0
_ZN4PLMD6lapack7slasda_EPiS1_S1_S1_PfS2_S2_S1_S2_S1_S2_S2_S2_S2_S1_S1_S1_S1_S2_S2_S2_S2_S1_S1_0
_ZN4PLMD6lapack7slasdq_EPKcPiS3_S3_S3_S3_PfS4_S4_S3_S4_S3_S4_S3_S4_S3_0
_ZN4PLMD6lapack7slasdt_EPiS1_S1_S1_S1_S1_S1_0
_ZN4PLMD6lapack7slaset_EPKcPiS3_PfS4_S4_S3_0
_ZN4PLMD6lapack7slasq1_EPiPfS2_S2_S1_0
_ZN4PLMD6lapack7slasq2_EPiPfS1_0
_ZN4PLMD6lapack7slasq3_EPiS1_PfS1_S2_S2_S2_S2_S1_S1_S1_S1_0
_ZN4PLMD6lapack7slasq4_EPiS1_PfS1_S1_S2_S2_S2_S2_S2_S2_S2_S1_0
_ZN4PLMD6lapack7slasq5_EPiS1_PfS1_S2_S2_S2_S2_S2_S2_S2_S1_0
_ZN4PLMD6lapack7slasq6_EPiS1_PfS1_S2_S2_S2_S2_S2_S2_0
_ZN4PLMD6lapack7slasrt_EPKcPiPfS3_0
_ZN4PLMD6lapack7slassq_EPiPfS1_S2_S2_0
_ZN4PLMD6lapack7slasv2_EPfS1_S1_S1_S1_S1_S1_S1_S1_0
_ZN4PLMD6lapack7slaswp_EPiPfS1_S1_S1_S1_S1_0
_ZN4PLMD6lapack7slatrd_EPKcPiS3_PfS3_S4_S4_S4_S3_0
_ZN4PLMD6lapack7sorg2r_EPiS1_S1_PfS1_S2_S2_S1_0
_ZN4PLMD6lapack7sorgbr_EPKcPiS3_S3_PfS3_S4_S4_S3_S3_0
_ZN4PLMD6lapack7sorgl2_EPiS1_S1_PfS1_S2_S2_S1_0
_ZN4PLMD6lapack7sorglq_EPiS1_S1_PfS1_S2_S2_S1_S1_0
_ZN4PLMD6lapack7sorgqr_EPiS1_S1_PfS1_S2_S2_S1_S1_0
_ZN4PLMD6lapack7sorm2l_EPKcS2_PiS3_S3_PfS3_S4_S4_S3_S4_S3_0
_ZN4PLMD6lapack7sorm2r_EPKcS2_PiS3_S3_PfS3_S4_S4_S3_S4_S3_0
_ZN4PLMD6lapack7sormbr_EPKcS2_S2_PiS3_S3_PfS3_S4_S4_S3_S4_S3_S3_0
_ZN4PLMD6lapack7sorml2_EPKcS2_PiS3_S3_PfS3_S4_S4_S3_S4_S3_0
_ZN4PLMD6lapack7sormlq_EPKcS2_PiS3_S3_PfS3_S4_S4_S3_S4_S3_S3_0
_ZN4PLMD6lapack7sormql_EPKcS2_PiS3_S3_PfS3_S4_S4_S3_S4_S3_S3_0
_ZN4PLMD6lapack7sormqr_EPKcS2_PiS3_S3_PfS3_S4_S4_S3_S4_S3_S3_0
_ZN4PLMD6lapack7sormtr_EPKcS2_S2_PiS3_PfS3_S4_S4_S3_S4_S3_S3_0
_ZN4PLMD6lapack7sstebz_EPKcS2_PiPfS4_S3_S3_S4_S4_S4_S3_S3_S4_S3_S3_S4_S3_S3_0
_ZN4PLMD6lapack7sstegr_EPKcS2_PiPfS4_S4_S4_S3_S3_S4_S3_S4_S4_S3_S3_S4_S3_S3_S3_S3_0
_ZN4PLMD6lapack7sstein_EPiPfS2_S1_S2_S1_S1_S2_S1_S2_S1_S1_S1_0
_ZN4PLMD6lapack7ssteqr_EPKcPiPfS4_S4_S3_S4_S3_0
_ZN4PLMD6lapack7ssterf_EPiPfS2_S1_0
_ZN4PLMD6lapack7sstevr_EPKcS2_PiPfS4_S4_S4_S3_S3_S4_S3_S4_S4_S3_S3_S4_S3_S3_S3_S3_0
_ZN4PLMD6lapack7ssyevr_EPKcS2_S2_PiPfS3_S4_S4_S3_S3_S4_S3_S4_S4_S3_S3_S4_S3_S3_S3_S3_0
_ZN4PLMD6lapack7ssytd2_EPKcPiPfS3_S4_S4_S4_S3_0
_ZN4PLMD6lapack7ssytrd_EPKcPiPfS3_S4_S4_S4_S4_S3_S3_0
_ZN4PLMD6lapack7strti2_EPKcS2_PiPfS3_S3_0
_ZN4PLMD6lapack7strtri_EPKcS2_PiPfS3_S3_0
_ZN4PLMD6lapack8slar1vx_EPiS1_S1_PfS2_S2_S2_S2_S2_S2_S2_S2_S2_S1_S1_S2_0
_ZN4PLMD6lapack8slarrbx_EPiPfS2_S2_S2_S1_S1_S2_S2_S1_S2_S2_S2_S2_S1_S1_0
_ZN4PLMD6lapack8slarrex_EPKcPiPfS4_S3_S3_S4_S4_S4_S3_S3_S3_S4_S3_S3_S4_S4_S3_S3_0
_ZN4PLMD6lapack8slarrfx_EPiPfS2_S2_S2_S1_S1_S2_S2_S2_S2_S2_S1_0
_ZN4PLMD6lapack8slarrvx_EPiPfS2_S1_S1_S2_S1_S1_S2_S2_S2_S1_S1_S2_S1_S1_0
_ZN4PLMD6lapack8slasrt2_EPKcPiPfS3_S3_0
_ZN4PLMD6lapack7dgeqr2_EPiS1_PdS1_S2_S2_S1_1
_ZN4PLMD6lapack7dgeqrf_EPiS1_PdS1_S2_S2_S1_S1_1
_ZN4PLMD6lapack7dorg2r_EPiS1_S1_PdS1_S2_S2_S1_1
_ZN4PLMD6lapack7dorgqr_EPiS1_S1_PdS1_S2_S2_S1_S1_1
_ZN4PLMD6lapack7slapy2_EPfS1_1
_ZN4PLMD6lapack8dlasrt2_EPKcPiPdS3_S3_9
_ZN4PLMD6lapack8ilasrt2_EPKcPiS3_S3_S3_9
_ZN4PLMD6lapack7dlabrd_EPiS1_S1_PdS1_S2_S2_S2_S2_S2_S1_S2_S1_12
_ZN4PLMD6lapack7dlatrd_EPKcPiS3_PdS3_S4_S4_S4_S3_19
_ZN4PLMD6lapack7dlasd0_EPiS1_PdS2_S2_S1_S2_S1_S1_S1_S2_S1_29
_ZN4PLMD6lapack7dlasdt_EPiS1_S1_S1_S1_S1_S1_29
_ZN4PLMD6lapack7dlacpy_EPKcPiS3_PdS3_S4_S3_54
_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_76
_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
_ZN4PLMD6lapack7dlamrg_EPiS1_PdS1_S1_S1_118
_ZN4PLMD6lapack7dlarfb_EPKcS2_S2_S2_PiS3_S3_PdS3_S4_S3_S4_S3_S4_S3_137
_ZN4PLMD6lapack7dlarft_EPKcS2_PiS3_PdS3_S4_S4_S3_137
_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
_ZN4PLMD6lapack7dgetf2_EPiS1_PdS1_S1_S1_16511
_ZN4PLMD6lapack7dgetrf_EPiS1_PdS1_S1_S1_16511
_ZN4PLMD6lapack7dtrti2_EPKcS2_PiPdS3_S3_16511
_ZN4PLMD6lapack7dtrtri_EPKcS2_PiPdS3_S3_16511
_ZN4PLMD6lapack7dgetri_EPiPdS1_S1_S2_S1_S1_33022
_ZN4PLMD6lapack7dlartg_EPdS1_S1_S1_S1_90519
_ZN4PLMD6lapack7dlasrt_EPKcPiPdS3_606108
_ZN4PLMD6lapack7dorm2l_EPKcS2_PiS3_S3_PdS3_S4_S4_S3_S4_S3_619030
_ZN4PLMD6lapack7dlasq2_EPiPdS1_619039
_ZN4PLMD6lapack7dlansy_EPKcS2_PiPdS3_S4_619040
_ZN4PLMD6lapack7dormql_EPKcS2_PiS3_S3_PdS3_S4_S4_S3_S4_S3_S3_619040
_ZN4PLMD6lapack7dormtr_EPKcS2_S2_PiS3_PdS3_S4_S4_S3_S4_S3_S3_619040
_ZN4PLMD6lapack7dstegr_EPKcS2_PiPdS4_S4_S4_S3_S3_S4_S3_S4_S4_S3_S3_S4_S3_S3_S3_S3_619040
_ZN4PLMD6lapack7dsytd2_EPKcPiPdS3_S4_S4_S4_S3_619040
_ZN4PLMD6lapack7dsytrd_EPKcPiPdS3_S4_S4_S4_S4_S3_S3_619040
_ZN4PLMD6lapack8dlarrex_EPKcPiPdS4_S3_S3_S4_S4_S4_S3_S3_S3_S4_S3_S3_S4_S4_S3_S3_619040
_ZN4PLMD6lapack8dlarrvx_EPiPdS2_S1_S1_S2_S1_S1_S2_S2_S2_S1_S1_S2_S1_S1_619040
_ZN4PLMD6lapack7dlanst_EPKcPiPdS4_619069
_ZN4PLMD6lapack8dlarrbx_EPiPdS2_S2_S2_S1_S1_S2_S2_S1_S2_S2_S2_S2_S1_S1_619115
_ZN4PLMD6lapack7dlaset_EPKcPiS3_PdS4_S4_S3_619558
_ZN4PLMD6lapack7dsyevr_EPKcS2_S2_PiPdS3_S4_S4_S3_S3_S4_S3_S4_S4_S3_S3_S4_S3_S3_S3_S3_633679
_ZN4PLMD6lapack8dlar1vx_EPiS1_S1_PdS2_S2_S2_S2_S2_S2_S2_S2_S2_S1_S1_S2_812986
_ZN4PLMD6lapack7dlapy2_EPdS1_1217658
_ZN4PLMD6lapack7dlarfg_EPiPdS2_S1_S2_1836931
_ZN4PLMD6lapack6dlarf_EPKcPiS3_PdS3_S4_S4_S3_S4_1837793
_ZN4PLMD6lapack7dlasq4_EPiS1_PdS1_S1_S2_S2_S2_S2_S2_S2_S2_S1_13698500
_ZN4PLMD6lapack7dlasq5_EPiS1_PdS1_S2_S2_S2_S2_S2_S2_S2_S1_13698509
_ZN4PLMD6lapack7dlasq3_EPiS1_PdS1_S2_S2_S2_S2_S1_S1_S1_S1_14304426
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lapack/lapack.cpp.func.html b/coverage-libs/lapack/lapack.cpp.func.html new file mode 100644 index 000000000000..3bc5aadd9680 --- /dev/null +++ b/coverage-libs/lapack/lapack.cpp.func.html @@ -0,0 +1,797 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - lapack/lapack.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lapack - lapack.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:38491522625.3 %
Date:2024-04-19 12:12:36Functions: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_1837793
_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_16511
_ZN4PLMD6lapack7dgetrf_EPiS1_PdS1_S1_S1_16511
_ZN4PLMD6lapack7dgetri_EPiPdS1_S1_S2_S1_S1_33022
_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_619069
_ZN4PLMD6lapack7dlansy_EPKcS2_PiPdS3_S4_619040
_ZN4PLMD6lapack7dlapy2_EPdS1_1217658
_ZN4PLMD6lapack7dlarfb_EPKcS2_S2_S2_PiS3_S3_PdS3_S4_S3_S4_S3_S4_S3_137
_ZN4PLMD6lapack7dlarfg_EPiPdS2_S1_S2_1836931
_ZN4PLMD6lapack7dlarft_EPKcS2_PiS3_PdS3_S4_S4_S3_137
_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_619558
_ZN4PLMD6lapack7dlasq1_EPiPdS2_S2_S1_0
_ZN4PLMD6lapack7dlasq2_EPiPdS1_619039
_ZN4PLMD6lapack7dlasq3_EPiS1_PdS1_S2_S2_S2_S2_S1_S1_S1_S1_14304426
_ZN4PLMD6lapack7dlasq4_EPiS1_PdS1_S1_S2_S2_S2_S2_S2_S2_S2_S1_13698500
_ZN4PLMD6lapack7dlasq5_EPiS1_PdS1_S2_S2_S2_S2_S2_S2_S2_S1_13698509
_ZN4PLMD6lapack7dlasq6_EPiS1_PdS1_S2_S2_S2_S2_S2_S2_0
_ZN4PLMD6lapack7dlasrt_EPKcPiPdS3_606108
_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_619030
_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_619040
_ZN4PLMD6lapack7dormqr_EPKcS2_PiS3_S3_PdS3_S4_S4_S3_S4_S3_S3_96
_ZN4PLMD6lapack7dormtr_EPKcS2_S2_PiS3_PdS3_S4_S4_S3_S4_S3_S3_619040
_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_619040
_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_633679
_ZN4PLMD6lapack7dsytd2_EPKcPiPdS3_S4_S4_S4_S3_619040
_ZN4PLMD6lapack7dsytrd_EPKcPiPdS3_S4_S4_S4_S4_S3_S3_619040
_ZN4PLMD6lapack7dtrti2_EPKcS2_PiPdS3_S3_16511
_ZN4PLMD6lapack7dtrtri_EPKcS2_PiPdS3_S3_16511
_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_812986
_ZN4PLMD6lapack8dlarrbx_EPiPdS2_S2_S2_S1_S1_S2_S2_S1_S2_S2_S2_S2_S1_S1_619115
_ZN4PLMD6lapack8dlarrex_EPKcPiPdS4_S3_S3_S4_S4_S4_S3_S3_S3_S4_S3_S3_S4_S4_S3_S3_619040
_ZN4PLMD6lapack8dlarrfx_EPiPdS2_S2_S2_S1_S1_S2_S2_S2_S2_S2_S1_76
_ZN4PLMD6lapack8dlarrvx_EPiPdS2_S1_S1_S2_S1_S1_S2_S2_S2_S1_S1_S2_S1_S1_619040
_ZN4PLMD6lapack8dlasrt2_EPKcPiPdS3_S3_9
_ZN4PLMD6lapack8ilasrt2_EPKcPiS3_S3_S3_9
_ZN4PLMD6lapack8slar1vx_EPiS1_S1_PfS2_S2_S2_S2_S2_S2_S2_S2_S2_S1_S1_S2_0
_ZN4PLMD6lapack8slarrbx_EPiPfS2_S2_S2_S1_S1_S2_S2_S1_S2_S2_S2_S2_S1_S1_0
_ZN4PLMD6lapack8slarrex_EPKcPiPfS4_S3_S3_S4_S4_S4_S3_S3_S3_S4_S3_S3_S4_S4_S3_S3_0
_ZN4PLMD6lapack8slarrfx_EPiPfS2_S2_S2_S1_S1_S2_S2_S2_S2_S2_S1_0
_ZN4PLMD6lapack8slarrvx_EPiPfS2_S1_S1_S2_S1_S1_S2_S2_S2_S1_S1_S2_S1_S1_0
_ZN4PLMD6lapack8slasrt2_EPKcPiPfS3_S3_0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lapack/lapack.cpp.gcov.html b/coverage-libs/lapack/lapack.cpp.gcov.html new file mode 100644 index 000000000000..ffa4cc9f2092 --- /dev/null +++ b/coverage-libs/lapack/lapack.cpp.gcov.html @@ -0,0 +1,31100 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - lapack/lapack.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lapack - lapack.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:38491522625.3 %
Date:2024-04-19 12:12:36Functions: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       16511 : 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       16511 :   minusone = -1.0;
+    1838             : 
+    1839       16511 :   if(*m<=0 || *n<=0)
+    1840             :     return;
+    1841             : 
+    1842             :   k = (*m < *n) ? *m : *n;
+    1843       49536 :   for(j=1;j<=k;j++) {
+    1844       33025 :     t1 = *m-j+1;
+    1845       33025 :     t2 = 1;
+    1846       33025 :     jp = j - 1 + PLUMED_BLAS_F77_FUNC(idamax,IDAMAX)(&t1,&(a[(j-1)*(*lda)+(j-1)]),&t2);
+    1847       33025 :     ipiv[j-1] = jp;
+    1848       33025 :     if( std::abs(a[(j-1)*(*lda)+(jp-1)])>PLUMED_GMX_DOUBLE_MIN ) {
+    1849       33025 :       if(jp != j)
+    1850           3 :         PLUMED_BLAS_F77_FUNC(dswap,DSWAP)(n,&(a[ j-1 ]),lda,&(a[ jp-1 ]),lda);
+    1851             :       
+    1852       33025 :       if(j<*m) {
+    1853       16514 :         t1 = *m-j;
+    1854       16514 :         t2 = 1;
+    1855       16514 :         tmp = 1.0/a[(j-1)*(*lda)+(j-1)];
+    1856       16514 :         PLUMED_BLAS_F77_FUNC(dscal,DSCAL)(&t1,&tmp,&(a[(j-1)*(*lda)+(j)]),&t2);
+    1857             :       }
+    1858             :     } else {
+    1859           0 :       *info = j;
+    1860             :     }
+    1861             : 
+    1862       33025 :     if(j<k) {
+    1863       16514 :       t1 = *m-j;
+    1864       16514 :       t2 = *n-j;
+    1865       16514 :       t3 = 1;
+    1866       16514 :       PLUMED_BLAS_F77_FUNC(dger,DGER)(&t1,&t2,&minusone,&(a[(j-1)*(*lda)+(j)]),&t3,
+    1867       16514 :             &(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       16511 : 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       16511 :   double minusone = -1.0;
+    1894       16511 :   double one = 1.0;
+    1895             : 
+    1896       16511 :   if(*m<=0 || *n<=0)
+    1897           0 :     return;
+    1898             : 
+    1899       16511 :   *info = 0;
+    1900             : 
+    1901       16511 :   mindim = (*m < *n) ? *m : *n;
+    1902             : 
+    1903       16511 :   if(DGETRF_BLOCKSIZE>=mindim) {
+    1904             : 
+    1905             :     /* unblocked code */
+    1906       16511 :     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       33022 : 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       33022 :     int c__1 = 1;
+    1982       33022 :     double c_b20 = -1.;
+    1983       33022 :     double c_b22 = 1.;
+    1984             : 
+    1985       33022 :     a_dim1 = *lda;
+    1986       33022 :     a_offset = 1 + a_dim1;
+    1987       33022 :     a -= a_offset;
+    1988             :     --ipiv;
+    1989       33022 :     --work;
+    1990             : 
+    1991       33022 :     *info = 0;
+    1992             :     nb = DGETRI_BLOCKSIZE;
+    1993       33022 :     lwkopt = *n * nb;
+    1994       33022 :     work[1] = (double) lwkopt;
+    1995             : 
+    1996       33022 :     if (*n < 0) {
+    1997           0 :         *info = -1;
+    1998       33022 :     } else if (*lda < (*n)) {
+    1999           0 :         *info = -3;
+    2000       33022 :     } else if (*lwork < (*n) && *lwork!=-1) {
+    2001           0 :         *info = -6;
+    2002             :     }
+    2003       33022 :     if (*info != 0) {
+    2004             :         i__1 = -(*info);
+    2005             :         return;
+    2006       33022 :     } else if (*lwork == -1) {
+    2007             :         return;
+    2008             :     }
+    2009             : 
+    2010       16511 :     if (*n == 0) {
+    2011             :         return;
+    2012             :     }
+    2013             : 
+    2014       16511 :     PLUMED_BLAS_F77_FUNC(dtrtri,DTRTRI)("Upper", "Non-unit", n, &a[a_offset], lda, info);
+    2015       16511 :     if (*info > 0) {
+    2016             :         return;
+    2017             :     }
+    2018             : 
+    2019             :     nbmin = 2;
+    2020       16511 :     ldwork = *n;
+    2021       16511 :     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       16511 :     if (nb < nbmin || nb >= *n) {
+    2033             : 
+    2034       49536 :         for (j = *n; j >= 1; --j) {
+    2035             : 
+    2036       33025 :             i__1 = *n;
+    2037       49545 :             for (i__ = j + 1; i__ <= i__1; ++i__) {
+    2038       16520 :                 work[i__] = a[i__ + j * a_dim1];
+    2039       16520 :                 a[i__ + j * a_dim1] = 0.;
+    2040             :             }
+    2041             : 
+    2042       33025 :             if (j < *n) {
+    2043       16514 :                 i__1 = *n - j;
+    2044       16514 :                 PLUMED_BLAS_F77_FUNC(dgemv,DGEMV)("No transpose", n, &i__1, &c_b20, &a[(j + 1) * a_dim1 
+    2045       16514 :                         + 1], lda, &work[j + 1], &c__1, &c_b22, &a[j * a_dim1 
+    2046       16514 :                         + 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       33025 :     for (j = *n - 1; j >= 1; --j) {
+    2078       16514 :         jp = ipiv[j];
+    2079       16514 :         if (jp != j) {
+    2080           3 :             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       16511 :     work[1] = (double) iws;
+    2085       16511 :     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        2780 :     for (niter = iter; niter <= 20; ++niter) {
+    2948        2780 :         if (*orgati) {
+    2949        1435 :             temp1 = dscale[1] - *tau;
+    2950        1435 :             temp2 = dscale[2] - *tau;
+    2951             :         } else {
+    2952        1345 :             temp1 = dscale[0] - *tau;
+    2953        1345 :             temp2 = dscale[1] - *tau;
+    2954             :         }
+    2955        2780 :         a = (temp1 + temp2) * f - temp1 * temp2 * df;
+    2956        2780 :         b = temp1 * temp2 * f;
+    2957        2780 :         c__ = f - (temp1 + temp2) * df + temp1 * temp2 * ddf;
+    2958        2780 :         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        2780 :         temp = (r__1>r__2) ? r__1 : r__2;
+    2960        2780 :         a /= temp;
+    2961        2780 :         b /= temp;
+    2962        2780 :         c__ /= temp;
+    2963        2780 :         if (c__ == 0.f) {
+    2964           0 :             eta = b / a;
+    2965        2780 :         } 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        2734 :             eta = b * 2.f / (a +  std::sqrt((r__1 = a * a - b * 4.f * c__, std::abs( r__1))));
+    2969             :         }
+    2970        2780 :         if (f * eta >= 0.f) {
+    2971           0 :             eta = -f / df;
+    2972             :         }
+    2973        2780 :         temp = eta + *tau;
+    2974        2780 :         if (*orgati) {
+    2975        1435 :             if (eta > 0.f && temp >= dscale[2]) {
+    2976           0 :                 eta = (dscale[2] - *tau) / 2.f;
+    2977             :             }
+    2978             : 
+    2979        1435 :             if (eta < 0.f && temp <= dscale[1]) {
+    2980           0 :                 eta = (dscale[1] - *tau) / 2.f;
+    2981             :             }
+    2982             :         } else {
+    2983        1345 :             if (eta > 0.f && temp >= dscale[1]) {
+    2984           0 :                 eta = (dscale[1] - *tau) / 2.f;
+    2985             :             }
+    2986        1345 :             if (eta < 0.f && temp <= dscale[0]) {
+    2987           0 :                 eta = (dscale[0] - *tau) / 2.f;
+    2988             :             }
+    2989             :         }
+    2990        2780 :         *tau += eta;
+    2991             :         fc = 0.f;
+    2992             :         erretm = 0.f;
+    2993             :         df = 0.f;
+    2994             :         ddf = 0.f;
+    2995       11120 :         for (i__ = 1; i__ <= 3; ++i__) {
+    2996        8340 :             temp = 1.f / (dscale[i__ - 1] - *tau);
+    2997        8340 :             temp1 = zscale[i__ - 1] * temp;
+    2998        8340 :             temp2 = temp1 * temp;
+    2999        8340 :             temp3 = temp2 * temp;
+    3000        8340 :             temp4 = temp1 / dscale[i__ - 1];
+    3001        8340 :             fc += temp4;
+    3002        8340 :             erretm += std::abs(temp4);
+    3003        8340 :             df += temp2;
+    3004        8340 :             ddf += temp3;
+    3005             :         }
+    3006        2780 :         f = *finit + *tau * fc;
+    3007        2780 :         erretm = (std::abs(*finit) + std::abs(*tau) * erretm) * 8.f + std::abs(*tau) * df;
+    3008        2780 :         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      619069 : PLUMED_BLAS_F77_FUNC(dlanst,DLANST)(const char *norm,
+    3626             :         int *n,
+    3627             :         double *d,
+    3628             :         double *e)
+    3629             : {
+    3630      619069 :   const char ch=std::toupper(*norm);
+    3631             :   double dtemp,max,val,scale,sum;
+    3632             :   int i,j;
+    3633             : 
+    3634             : 
+    3635      619069 :   if(*n<=0)
+    3636             :     return 0.0;
+    3637             :   
+    3638      619069 :   switch(ch) {
+    3639      619069 :   case 'M':
+    3640      619069 :     max = std::abs(d[*n-1]);
+    3641     2452401 :       for(i=0;i<(*n-1);i++) {
+    3642     1833332 :         dtemp = std::abs(d[i]);
+    3643     1833332 :         if(dtemp>max)
+    3644             :           max = dtemp;
+    3645     1833332 :         dtemp = std::abs(e[i]);
+    3646     1833332 :         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      619040 : 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      619040 :     int c__1 = 1;
+    3711             : 
+    3712             :     /* Local variables */
+    3713             :     int i__, j;
+    3714             :     double sum, absa, scale;
+    3715             :     double value =0.0;
+    3716             : 
+    3717      619040 :     a_dim1 = *lda;
+    3718      619040 :     a_offset = 1 + a_dim1;
+    3719      619040 :     a -= a_offset;
+    3720      619040 :     --work;
+    3721             : 
+    3722      619040 :     if (*n == 0) {
+    3723             :         value = 0.;
+    3724      619040 :     } else if (*norm=='M' || *norm=='m') {
+    3725             : 
+    3726             :         value = 0.;
+    3727      619040 :         if (*uplo=='U' || *uplo=='u') {
+    3728      619040 :             i__1 = *n;
+    3729     3070017 :             for (j = 1; j <= i__1; ++j) {
+    3730             :                 i__2 = j;
+    3731     8734692 :                 for (i__ = 1; i__ <= i__2; ++i__) {
+    3732             :                   d__2 = value;
+    3733     6283715 :                   d__3 = std::abs(a[i__ + j * a_dim1]);
+    3734     6283715 :                   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      619040 :     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     1217658 : PLUMED_BLAS_F77_FUNC(dlapy2,DLAPY2)(double * x, double * y)
+    3827             : {
+    3828             :   double xabs,yabs;
+    3829             :   double w,z;
+    3830             : 
+    3831     1217658 :   xabs = std::abs(*x);
+    3832     1217658 :   yabs = std::abs(*y);
+    3833             :   
+    3834     1217658 :   if(xabs>yabs) {
+    3835             :     w = xabs;
+    3836             :     z = yabs;
+    3837             :   } else {
+    3838             :     w = yabs;
+    3839             :     z = xabs;
+    3840             :   }
+    3841             : 
+    3842     1217658 :   if( std::abs(z)<PLUMED_GMX_DOUBLE_MIN) 
+    3843             :     return w;
+    3844             :   else {
+    3845     1217658 :     z = z/w;
+    3846     1217658 :     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      812986 : 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      812986 :     --work;
+    3894             :     --isuppz;
+    3895      812986 :     --z__;
+    3896      812986 :     --gersch;
+    3897      812986 :     --lld;
+    3898      812986 :     --ld;
+    3899      812986 :     --l;
+    3900      812986 :     --d__;
+    3901             : 
+    3902             :     /* Function Body */
+    3903             :     eps = PLUMED_GMX_DOUBLE_EPS;
+    3904      812986 :     if (*r__ == 0) {
+    3905             : 
+    3906      811524 :         r1 = *b1;
+    3907      811524 :         r2 = *bn;
+    3908             :         i__1 = *bn;
+    3909     1839398 :         for (i__ = *b1; i__ <= i__1; ++i__) {
+    3910     1839398 :             if (*eval >= gersch[(i__ << 1) - 1] && *eval <= gersch[i__ * 2]) {
+    3911             :                 r1 = i__;
+    3912      811524 :                 goto L20;
+    3913             :             }
+    3914             :         }
+    3915           0 :         goto L40;
+    3916             : L20:
+    3917             :         i__1 = *b1;
+    3918     1983170 :         for (i__ = *bn; i__ >= i__1; --i__) {
+    3919     1983170 :             if (*eval >= gersch[(i__ << 1) - 1] && *eval <= gersch[i__ * 2]) {
+    3920             :                 r2 = i__;
+    3921      811524 :                 goto L40;
+    3922             :             }
+    3923             :         }
+    3924             :     } else {
+    3925             :         r1 = *r__;
+    3926             :         r2 = *r__;
+    3927             :     }
+    3928             : 
+    3929      812986 : L40:
+    3930      812986 :     indumn = *n;
+    3931      812986 :     inds = (*n << 1) + 1;
+    3932      812986 :     indp = *n * 3 + 1;
+    3933             :     sawnan = 0;
+    3934             : 
+    3935      812986 :     if (*b1 == 1) {
+    3936      812986 :         work[inds] = 0.;
+    3937             :     } else {
+    3938           0 :         work[inds] = lld[*b1 - 1];
+    3939             :     }
+    3940      812986 :     s = work[inds] - *sigma;
+    3941             :     i__1 = r2 - 1;
+    3942     2445910 :     for (i__ = *b1; i__ <= i__1; ++i__) {
+    3943     1632924 :         dplus = d__[i__] + s;
+    3944     1632924 :         work[i__] = ld[i__] / dplus;
+    3945     1632924 :         work[inds + i__] = s * work[i__] * l[i__];
+    3946     1632924 :         s = work[inds + i__] - *sigma;
+    3947             :     }
+    3948             : 
+    3949      812986 :     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      812986 :     work[indp + *bn - 1] = d__[*bn] - *sigma;
+    3974             :     i__1 = r1;
+    3975     2709265 :     for (i__ = *bn - 1; i__ >= i__1; --i__) {
+    3976     1896279 :         dminus = lld[i__] + work[indp + i__];
+    3977     1896279 :         tmp = d__[i__] / dminus;
+    3978     1896279 :         work[indumn + i__] = l[i__] * tmp;
+    3979     1896279 :         work[indp + i__ - 1] = work[indp + i__] * tmp - *sigma;
+    3980             :     }
+    3981      812986 :     tmp = work[indp + r1 - 1];
+    3982      812986 :     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      812986 :     *mingma = work[inds + r1 - 1] + work[indp + r1 - 1];
+    4006      812986 :     if (std::abs(*mingma)<PLUMED_GMX_DOUBLE_MIN) {
+    4007       71533 :         *mingma = eps * work[inds + r1 - 1];
+    4008             :     }
+    4009      812986 :     *r__ = r1;
+    4010             :     i__1 = r2 - 1;
+    4011     1324314 :     for (i__ = r1; i__ <= i__1; ++i__) {
+    4012      511328 :         tmp = work[inds + i__] + work[indp + i__];
+    4013      511328 :         if (std::abs(tmp)<PLUMED_GMX_DOUBLE_MIN) {
+    4014       36050 :             tmp = eps * work[inds + i__];
+    4015             :         }
+    4016      511328 :         if (std::abs(tmp) < std::abs(*mingma)) {
+    4017      105363 :             *mingma = tmp;
+    4018      105363 :             *r__ = i__ + 1;
+    4019             :         }
+    4020             :     }
+    4021             : 
+    4022      812986 :     isuppz[1] = *b1;
+    4023      812986 :     isuppz[2] = *bn;
+    4024      812986 :     z__[*r__] = 1.;
+    4025      812986 :     *ztz = 1.;
+    4026      812986 :     if (! sawnan) {
+    4027      812986 :         from = *r__ - 1;
+    4028      812986 :         i__1 = *r__ - 32;
+    4029      812986 :         to = (i__1>(*b1)) ? i__1 : (*b1);
+    4030             : L120:
+    4031     1507113 :         if (from >= *b1) {
+    4032             :             i__1 = to;
+    4033     1819018 :             for (i__ = from; i__ >= i__1; --i__) {
+    4034     1123694 :                 z__[i__] = -(work[i__] * z__[i__ + 1]);
+    4035     1123694 :                 *ztz += z__[i__] * z__[i__];
+    4036             :             }
+    4037      695324 :             if (std::abs(z__[to]) <= eps && std::abs(z__[to + 1]) <= eps) {
+    4038        1197 :                 isuppz[1] = to + 2;
+    4039             :             } else {
+    4040      694127 :                 from = to - 1;
+    4041      694127 :                 i__1 = to - 32;
+    4042      694127 :                 to = (i__1>*b1) ? i__1 : *b1;
+    4043      694127 :                 goto L120;
+    4044             :             }
+    4045             :         }
+    4046      812986 :         from = *r__ + 1;
+    4047      812986 :         i__1 = *r__ + 32;
+    4048      812986 :         to = (i__1<*bn) ? i__1 : *bn;
+    4049             : L140:
+    4050     1554512 :         if (from <= *bn) {
+    4051             :             i__1 = to;
+    4052     2494022 :             for (i__ = from; i__ <= i__1; ++i__) {
+    4053     1752441 :                 z__[i__] = -(work[indumn + i__ - 1] * z__[i__ - 1]);
+    4054     1752441 :                 *ztz += z__[i__] * z__[i__];
+    4055             :             }
+    4056      741581 :             if (std::abs(z__[to]) <= eps && std::abs(z__[to - 1]) <= eps) {
+    4057          55 :                 isuppz[2] = to - 2;
+    4058             :             } else {
+    4059      741526 :                 from = to + 1;
+    4060      741526 :                 i__1 = to + 32;
+    4061      741526 :                 to = (i__1<*bn) ? i__1 : *bn;
+    4062      741526 :                 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      812986 :     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     1837793 : 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     1837793 :   const char ch=std::toupper(*side);
+    4126     1837793 :   double one = 1.0;
+    4127     1837793 :   double zero = 0.0;
+    4128     1837793 :   double minustau = -(*tau);
+    4129     1837793 :   int i1 = 1;
+    4130             : 
+    4131             : 
+    4132     1837793 :   if(ch=='L') {
+    4133     1834212 :     if(std::abs(*tau)>PLUMED_GMX_DOUBLE_MIN) {
+    4134     1214986 :       PLUMED_BLAS_F77_FUNC(dgemv,DGEMV)("T",m,n,&one,c,ldc,v,incv,&zero,work,&i1);
+    4135     1214986 :       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     1837793 :   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         137 : 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         137 :     int c__1 = 1;
+    4178         137 :     double one = 1.0;
+    4179         137 :     double minusone = -1.0;
+    4180             : 
+    4181         137 :     v_dim1 = *ldv;
+    4182         137 :     v_offset = 1 + v_dim1;
+    4183         137 :     v -= v_offset;
+    4184             :     t_dim1 = *ldt;
+    4185             :     t_offset = 1 + t_dim1;
+    4186             :     t -= t_offset;
+    4187         137 :     c_dim1 = *ldc;
+    4188         137 :     c_offset = 1 + c_dim1;
+    4189         137 :     c__ -= c_offset;
+    4190         137 :     work_dim1 = *ldwork;
+    4191         137 :     work_offset = 1 + work_dim1;
+    4192         137 :     work -= work_offset;
+    4193             : 
+    4194         137 :     if (*m <= 0 || *n <= 0) {
+    4195             :         return;
+    4196             :     }
+    4197         137 :     if (*trans=='N' || *trans=='n') {
+    4198          97 :       *(unsigned char *)transt = 'T';
+    4199             :     } else {
+    4200          40 :         *(unsigned char *)transt = 'N';
+    4201             :     }
+    4202             :     
+    4203         137 :     if (*storev=='C' || *storev=='c') {
+    4204             : 
+    4205          97 :         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          49 :           if (*side=='l' || *side=='L') {
+    4289          49 :                 i__1 = *k;
+    4290        1405 :                 for (j = 1; j <= i__1; ++j) {
+    4291        1356 :                     PLUMED_BLAS_F77_FUNC(dcopy,DCOPY)(n, &c__[*m - *k + j + c_dim1], ldc, &work[j * 
+    4292        1356 :                             work_dim1 + 1], &c__1);
+    4293             :                 }
+    4294             : 
+    4295          49 :                 PLUMED_BLAS_F77_FUNC(dtrmm,DTRMM)("Right", "Upper", "No transpose", "Unit", n, k, &one,
+    4296          49 :                          &v[*m - *k + 1 + v_dim1], ldv, &work[work_offset], 
+    4297             :                         ldwork);
+    4298          49 :                 if (*m > *k) {
+    4299          39 :                     i__1 = *m - *k;
+    4300          39 :                     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          49 :                 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          49 :                 if (*m > *k) {
+    4309             : 
+    4310          39 :                     i__1 = *m - *k;
+    4311          39 :                     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          49 :                 PLUMED_BLAS_F77_FUNC(dtrmm,DTRMM)("Right", "Upper", "Transpose", "Unit", n, k, &one, &
+    4318          49 :                         v[*m - *k + 1 + v_dim1], ldv, &work[work_offset], 
+    4319             :                         ldwork);
+    4320             : 
+    4321          49 :                 i__1 = *k;
+    4322        1405 :                 for (j = 1; j <= i__1; ++j) {
+    4323        1356 :                     i__2 = *n;
+    4324      364346 :                     for (i__ = 1; i__ <= i__2; ++i__) {
+    4325      362990 :                         c__[*m - *k + j + i__ * c_dim1] -= work[i__ + j * 
+    4326      362990 :                                 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     1836931 : 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     1836931 :   if(*n<=1) {
+    4573      619232 :     *tau = 0;
+    4574      619232 :     return;
+    4575             :   }
+    4576             : 
+    4577     1217699 :   ti1 = *n-1;
+    4578             : 
+    4579     1217699 :   xnorm = PLUMED_BLAS_F77_FUNC(dnrm2,DNRM2)(&ti1,x,incx);
+    4580             : 
+    4581     1217699 :   if(std::abs(xnorm)<PLUMED_GMX_DOUBLE_MIN) {
+    4582          68 :     *tau = 0.0;
+    4583             :   } else {
+    4584             : 
+    4585     1217631 :     t = PLUMED_BLAS_F77_FUNC(dlapy2,DLAPY2)(alpha,&xnorm);
+    4586             : 
+    4587     1217631 :     if(*alpha<0)
+    4588             :       beta = t;
+    4589             :     else
+    4590      491415 :       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     1217631 :     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     1217631 :       *tau = (beta-*alpha)/beta;
+    4631     1217631 :       ti1= *n-1;
+    4632     1217631 :       t = 1.0/(*alpha-beta);
+    4633     1217631 :       PLUMED_BLAS_F77_FUNC(dscal,DSCAL)(&ti1,&t,x,incx);
+    4634     1217631 :       *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         137 : 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         137 :     int c__1 = 1;
+    4671         137 :     double zero = 0.0;
+    4672             : 
+    4673         137 :     v_dim1 = *ldv;
+    4674         137 :     v_offset = 1 + v_dim1;
+    4675         137 :     v -= v_offset;
+    4676         137 :     --tau;
+    4677         137 :     t_dim1 = *ldt;
+    4678         137 :     t_offset = 1 + t_dim1;
+    4679         137 :     t -= t_offset;
+    4680             : 
+    4681         137 :     if (*n == 0) {
+    4682             :         return;
+    4683             :     }
+    4684             : 
+    4685         137 :     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        1405 :         for (i__ = *k; i__ >= 1; --i__) {
+    4726        1356 :             if (std::abs(tau[i__])<PLUMED_GMX_DOUBLE_MIN) {
+    4727             : 
+    4728          58 :                 i__1 = *k;
+    4729        1027 :                 for (j = i__; j <= i__1; ++j) {
+    4730         969 :                     t[j + i__ * t_dim1] = 0.;
+    4731             :                 }
+    4732             :             } else {
+    4733             : 
+    4734        1298 :                 if (i__ < *k) {
+    4735        1251 :                     if (*storev=='C' || *storev=='c') {
+    4736        1251 :                         vii = v[*n - *k + i__ + i__ * v_dim1];
+    4737        1251 :                         v[*n - *k + i__ + i__ * v_dim1] = 1.;
+    4738             : 
+    4739        1251 :                         i__1 = *n - *k + i__;
+    4740        1251 :                         i__2 = *k - i__;
+    4741        1251 :                         d__1 = -tau[i__];
+    4742        1251 :                         PLUMED_BLAS_F77_FUNC(dgemv,DGEMV)("Transpose", &i__1, &i__2, &d__1, &v[(i__ + 1) 
+    4743        1251 :                                 * v_dim1 + 1], ldv, &v[i__ * v_dim1 + 1], &
+    4744        1251 :                                 c__1, &zero, &t[i__ + 1 + i__ * t_dim1], &
+    4745             :                                 c__1);
+    4746        1251 :                         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        1251 :                     i__1 = *k - i__;
+    4761        1251 :                     PLUMED_BLAS_F77_FUNC(dtrmv,DTRMV)("Lower", "No transpose", "Non-unit", &i__1, &t[i__ 
+    4762        1251 :                             + 1 + (i__ + 1) * t_dim1], ldt, &t[i__ + 1 + i__ *
+    4763        1251 :                              t_dim1], &c__1)
+    4764             :                             ;
+    4765             :                 }
+    4766        1298 :                 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      619115 : 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      619115 :     --iwork;
+    4881      619115 :     --work;
+    4882      619115 :     --werr;
+    4883      619115 :     --wgap;
+    4884      619115 :     --w;
+    4885      619115 :     --lld;
+    4886             :     --ld;
+    4887             :     --l;
+    4888      619115 :     --d__;
+    4889             : 
+    4890      619115 :     *info = 0;
+    4891      619115 :     i__1 = *n << 1;
+    4892     5576827 :     for (i__ = 1; i__ <= i__1; ++i__) {
+    4893     4957712 :         iwork[i__] = 0;
+    4894             :     }
+    4895      619115 :     i1 = *ifirst;
+    4896             :     i2 = *ifirst;
+    4897             :     prev = 0;
+    4898      619115 :     i__1 = *ilast;
+    4899     1239102 :     for (i__ = *ifirst; i__ <= i__1; ++i__) {
+    4900      619987 :         k = i__ << 1;
+    4901      619987 :         iwork[k - 1] = 1;
+    4902             :         i2 = i__;
+    4903             :     }
+    4904             : 
+    4905             :     i__ = i1;
+    4906             :     nint = 0;
+    4907     1239102 : L30:
+    4908     1239102 :     if (i__ <= i2) {
+    4909      619987 :         ii = i__ - *offset;
+    4910      619987 :         if (iwork[(i__ << 1) - 1] == 1) {
+    4911             :             fac = 1.;
+    4912      619987 :             left = w[ii] - werr[ii];
+    4913             : 
+    4914             : 
+    4915      620094 : L40:
+    4916      620094 :             if (i__ > i1 && left <= right) {
+    4917             :                 left = right;
+    4918           0 :                 cnt = i__ - 1;
+    4919             :             } else {
+    4920      620094 :                 s = -left;
+    4921             :                 cnt = 0;
+    4922      620094 :                 i__1 = *n - 1;
+    4923     2885588 :                 for (j = 1; j <= i__1; ++j) {
+    4924     2265494 :                     dplus = d__[j] + s;
+    4925     2265494 :                     s = s * lld[j] / dplus - left;
+    4926     2265494 :                     if (dplus < 0.) {
+    4927      222332 :                         ++cnt;
+    4928             :                     }
+    4929             :                 }
+    4930      620094 :                 dplus = d__[*n] + s;
+    4931      620094 :                 if (dplus < 0.) {
+    4932         105 :                     ++cnt;
+    4933             :                 }
+    4934      620094 :         if (std::isnan(s)) {
+    4935             : 
+    4936             :                     cnt = 0;
+    4937             :                     s = -left;
+    4938             :                     i__1 = *n - 1;
+    4939           8 :                     for (j = 1; j <= i__1; ++j) {
+    4940           6 :                         dplus = d__[j] + s;
+    4941           6 :                         if (dplus < 0.) {
+    4942           2 :                             ++cnt;
+    4943             :                         }
+    4944           6 :                         tmp = lld[j] / dplus;
+    4945           6 :                         if (std::abs(tmp)<PLUMED_GMX_DOUBLE_MIN) {
+    4946           2 :                             s = lld[j] - left;
+    4947             :                         } else {
+    4948           4 :                             s = s * tmp - left;
+    4949             :                         }
+    4950             :                     }
+    4951           2 :                     dplus = d__[*n] + s;
+    4952           2 :                     if (dplus < 0.) {
+    4953           0 :                         ++cnt;
+    4954             :                     }
+    4955             :                 }
+    4956      620094 :                 if (cnt > i__ - 1) {
+    4957         107 :                     left -= werr[ii] * fac;
+    4958         107 :                     fac *= 2.;
+    4959         107 :                     goto L40;
+    4960             :                 }
+    4961             :             }
+    4962      619987 :             nleft = cnt + 1;
+    4963             :             i1 = (i1<nleft) ? i1 : nleft;
+    4964             :             fac = 1.;
+    4965      619987 :             right = w[ii] + werr[ii];
+    4966      620021 : L60:
+    4967      620021 :             s = -right;
+    4968             :             cnt = 0;
+    4969      620021 :             i__1 = *n - 1;
+    4970     2853602 :             for (j = 1; j <= i__1; ++j) {
+    4971     2233581 :                 dplus = d__[j] + s;
+    4972     2233581 :                 s = s * lld[j] / dplus - right;
+    4973     2233581 :                 if (dplus < 0.) {
+    4974     2031195 :                     ++cnt;
+    4975             :                 }
+    4976             :             }
+    4977      620021 :             dplus = d__[*n] + s;
+    4978      620021 :             if (dplus < 0.) {
+    4979      619983 :                 ++cnt;
+    4980             :             }
+    4981      620021 :             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      620021 :             if (cnt < i__) {
+    5004          34 :                 right += werr[ii] * fac;
+    5005          34 :                 fac *= 2.;
+    5006          34 :                 goto L60;
+    5007             :             }
+    5008             :             cnt = (cnt<i2) ? cnt : i2;
+    5009      619987 :             ++nint;
+    5010      619987 :             k = nleft << 1;
+    5011      619987 :             work[k - 1] = left;
+    5012      619987 :             work[k] = right;
+    5013      619987 :             i__ = cnt + 1;
+    5014      619987 :             iwork[k - 1] = i__;
+    5015      619987 :             iwork[k] = cnt;
+    5016      619987 :             if (prev != nleft - 1) {
+    5017          76 :                 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      619987 :         goto L30;
+    5028             :     }
+    5029      619115 :     if (i__ <= *n && iwork[(i__ << 1) - 1] != -1) {
+    5030      524846 :         work[(i__ << 1) - 1] = work[prev * 2];
+    5031             :     }
+    5032             : 
+    5033       94269 : L80:
+    5034    31855385 :     prev = i1 - 1;
+    5035             :     olnint = nint;
+    5036             :     i__ = i1;
+    5037             :     i__1 = olnint;
+    5038    63712378 :     for (p = 1; p <= i__1; ++p) {
+    5039    31856993 :         k = i__ << 1;
+    5040    31856993 :         left = work[k - 1];
+    5041    31856993 :         right = work[k];
+    5042    31856993 :         next = iwork[k - 1];
+    5043    31856993 :         nright = iwork[k];
+    5044    31856993 :         mid = (left + right) * .5;
+    5045    31856993 :         width = right - mid;
+    5046             :         d__1 = std::abs(left);
+    5047             :         d__2 = std::abs(right);
+    5048    31856993 :         tmp = (d__1>d__2) ? d__1 : d__2;
+    5049             : 
+    5050             :         gap = 0.;
+    5051    31856993 :         if (i__ == nright) {
+    5052    31572060 :             if (prev > 0 && next <= *n) {
+    5053        2539 :                 d__1 = left - work[k - 2], d__2 = work[k + 1] - right;
+    5054        2539 :                 gap = (d__1<d__2) ? d__1 : d__2;
+    5055    31569521 :             } else if (prev > 0) {
+    5056     4806251 :                 gap = left - work[k - 2];
+    5057    26763270 :             } else if (next <= *n) {
+    5058    26763270 :                 gap = work[k + 1] - right;
+    5059             :             }
+    5060             :         }
+    5061    31856993 :         d__1 = *rtol1 * gap, d__2 = *rtol2 * tmp;
+    5062    35855702 :         if (width < ((d__1>d__2) ? d__1 : d__2)) {
+    5063      619987 :             --nint;
+    5064      619987 :             iwork[k - 1] = 0;
+    5065             :             kk = k;
+    5066             :             i__2 = nright;
+    5067      619987 :             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      619987 :             if (i1 == i__) {
+    5075             :                 i1 = next;
+    5076             :             } else {
+    5077         835 :                 iwork[(prev << 1) - 1] = next;
+    5078             :             }
+    5079             :             i__ = next;
+    5080      619987 :             continue;
+    5081             :         }
+    5082             :         prev = i__;
+    5083             : 
+    5084    31237006 :         s = -mid;
+    5085             :         cnt = 0;
+    5086    31237006 :         i__2 = *n - 1;
+    5087   124252590 :         for (j = 1; j <= i__2; ++j) {
+    5088    93015584 :             dplus = d__[j] + s;
+    5089    93015584 :             s = s * lld[j] / dplus - mid;
+    5090    93015584 :             if (dplus < 0.) {
+    5091    17780891 :                 ++cnt;
+    5092             :             }
+    5093             :         }
+    5094    31237006 :         dplus = d__[*n] + s;
+    5095    31237006 :         if (dplus < 0.) {
+    5096    13673892 :             ++cnt;
+    5097             :         }
+    5098    31237006 :         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    31237006 :         i__2 = i__ - 1, i__3 = (nright<cnt) ? nright : cnt;
+    5120             :         cnt = (i__2>i__3) ? i__2 : i__3;
+    5121    31237006 :         if (cnt == i__ - 1) {
+    5122    15062349 :             work[k - 1] = mid;
+    5123    16174657 :         } else if (cnt == nright) {
+    5124    15928515 :             work[k] = mid;
+    5125             :         } else {
+    5126      246142 :             iwork[k] = cnt;
+    5127      246142 :             ++cnt;
+    5128      246142 :             iwork[k - 1] = cnt;
+    5129      246142 :             kk = cnt << 1;
+    5130      246142 :             iwork[kk - 1] = next;
+    5131      246142 :             iwork[kk] = nright;
+    5132      246142 :             work[k] = mid;
+    5133      246142 :             work[kk - 1] = mid;
+    5134      246142 :             work[kk] = right;
+    5135             :             prev = cnt;
+    5136      246142 :             if (cnt - 1 > i__) {
+    5137       36425 :                 work[kk - 2] = mid;
+    5138             :             }
+    5139      246142 :             if (cnt > *ifirst && cnt <= *ilast) {
+    5140           0 :                 ++nint;
+    5141      246142 :             } else if (cnt <= *ifirst) {
+    5142             :                 i1 = cnt;
+    5143             :             }
+    5144             :         }
+    5145             :         i__ = next;
+    5146             :     }
+    5147    31855385 :     if (nint > 0) {
+    5148    31236270 :         goto L80;
+    5149             :     }
+    5150      619115 :     i__1 = *ilast;
+    5151     1239102 :     for (i__ = *ifirst; i__ <= i__1; ++i__) {
+    5152      619987 :         k = i__ << 1;
+    5153      619987 :         ii = i__ - *offset;
+    5154      619987 :         if (iwork[k - 1] != -1) {
+    5155      619987 :             w[ii] = (work[k - 1] + work[k]) * .5;
+    5156      619987 :             werr[ii] = work[k] - w[ii];
+    5157      619987 :             if (i__ != *ilast) {
+    5158         872 :                 wgap[ii] = work[k + 1] - work[k];
+    5159             :             }
+    5160             :         }
+    5161             :     }
+    5162             : 
+    5163      619115 :     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      619040 : 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      619040 :     int c__1 = 1;
+    5207      619040 :     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      619040 :     --iwork;
+    5224      619040 :     --work;
+    5225      619040 :     --gersch;
+    5226      619040 :     --indexw;
+    5227      619040 :     --iblock;
+    5228      619040 :     --w;
+    5229      619040 :     --isplit;
+    5230      619040 :     --e;
+    5231      619040 :     --d__;
+    5232             : 
+    5233             :     sigma = 0;
+    5234             :     irange = 0;
+    5235             :     sgndef = 0;
+    5236             :     maxcnt = 0;
+    5237             : 
+    5238      619040 :     *info = 0;
+    5239             : 
+    5240      619040 :     if (*range=='A' || *range=='a')
+    5241             :         irange = 1;
+    5242      559803 :     else if (*range=='V' || *range=='v')
+    5243             :         irange = 2;
+    5244      559803 :     else if (*range=='I' || *range=='i')
+    5245             :         irange = 3;
+    5246             :     
+    5247             : 
+    5248      619040 :     *m = 0;
+    5249             :     eps = PLUMED_GMX_DOUBLE_EPS;
+    5250             : 
+    5251      619040 :     *nsplit = 1;
+    5252      619040 :     i__1 = *n - 1;
+    5253     2450977 :     for (i__ = 1; i__ <= i__1; ++i__) {
+    5254     1831937 :         if (std::abs(e[i__]) <= *tol) {
+    5255         468 :             isplit[*nsplit] = i__;
+    5256         468 :             ++(*nsplit);
+    5257             :         }
+    5258             :     }
+    5259      619040 :     isplit[*nsplit] = *n;
+    5260             : 
+    5261             :     ibegin = 1;
+    5262      619040 :     i__1 = *nsplit;
+    5263     1238548 :     for (jblk = 1; jblk <= i__1; ++jblk) {
+    5264      619508 :         iend = isplit[jblk];
+    5265      619508 :         if (ibegin == iend) {
+    5266         469 :             ++(*m);
+    5267         469 :             w[*m] = d__[ibegin];
+    5268         469 :             iblock[*m] = jblk;
+    5269         469 :             indexw[*m] = 1;
+    5270         469 :             e[iend] = 0.;
+    5271         469 :             ibegin = iend + 1;
+    5272         469 :             goto L170;
+    5273             :         }
+    5274      619039 :         in = iend - ibegin + 1;
+    5275             : 
+    5276      619039 :         gl = d__[ibegin] - std::abs(e[ibegin]);
+    5277      619039 :         gu = d__[ibegin] + std::abs(e[ibegin]);
+    5278      619039 :         gersch[(ibegin << 1) - 1] = gl;
+    5279      619039 :         gersch[ibegin * 2] = gu;
+    5280      619039 :         gersch[(iend << 1) - 1] = d__[iend] - std::abs(e[iend - 1]);
+    5281      619039 :         gersch[iend * 2] = d__[iend] + std::abs(e[iend - 1]);
+    5282      619039 :         d__1 = gersch[(iend << 1) - 1];
+    5283      619039 :         gl = (d__1<gl) ? d__1 : gl;
+    5284             :         d__1 = gersch[iend * 2];
+    5285      619039 :         gu = (d__1>gu) ? d__1 : gu;
+    5286      619039 :         i__2 = iend - 1;
+    5287     1831469 :         for (i__ = ibegin + 1; i__ <= i__2; ++i__) {
+    5288     1212430 :             offd = std::abs(e[i__ - 1]) + std::abs(e[i__]);
+    5289     1212430 :             gersch[(i__ << 1) - 1] = d__[i__] - offd;
+    5290             :             d__1 = gersch[(i__ << 1) - 1];
+    5291     1212430 :             gl = (d__1<gl) ? d__1 : gl;
+    5292     1212430 :             gersch[i__ * 2] = d__[i__] + offd;
+    5293             :             d__1 = gersch[i__ * 2];
+    5294     1212430 :             gu = (d__1>gu) ? d__1 : gu;
+    5295             :         }
+    5296             :         d__1 = std::abs(gl), d__2 = std::abs(gu);
+    5297      619039 :         nrm = (d__1>d__2) ? d__1 : d__2;
+    5298             : 
+    5299      619039 :         width = gu - gl;
+    5300             :         i__2 = iend - 1;
+    5301     2450508 :         for (i__ = ibegin; i__ <= i__2; ++i__) {
+    5302     1831469 :             work[i__] = e[i__] * e[i__];
+    5303             :         }
+    5304     1857117 :         for (j = 1; j <= 2; ++j) {
+    5305     1238078 :             if (j == 1) {
+    5306      619039 :                 tau = gl + width * .25;
+    5307             :             } else {
+    5308      619039 :                 tau = gu - width * .25;
+    5309             :             }
+    5310     1238078 :             tmp = d__[ibegin] - tau;
+    5311     1238078 :             if (tmp < 0.) {
+    5312      653991 :                 cnt = 1;
+    5313             :             } else {
+    5314      584087 :                 cnt = 0;
+    5315             :             }
+    5316     1238078 :             i__2 = iend;
+    5317     4901016 :             for (i__ = ibegin + 1; i__ <= i__2; ++i__) {
+    5318     3662938 :                 tmp = d__[i__] - tau - work[i__ - 1] / tmp;
+    5319     3662938 :                 if (tmp < 0.) {
+    5320     1710004 :                     ++cnt;
+    5321             :                 }
+    5322             :             }
+    5323     1238078 :             if (cnt == 0) {
+    5324             :                 gl = tau;
+    5325     1238078 :             } else if (cnt == in) {
+    5326             :                 gu = tau;
+    5327             :             }
+    5328     1238078 :             if (j == 1) {
+    5329             :                 maxcnt = cnt;
+    5330             :                 sigma = gl;
+    5331             :                 sgndef = 1.;
+    5332             :             } else {
+    5333      619039 :                 if (in - cnt > maxcnt) {
+    5334             :                     sigma = gu;
+    5335             :                     sgndef = -1.;
+    5336             :                 }
+    5337             :             }
+    5338             :         }
+    5339             : 
+    5340      619039 :         work[in * 3] = 1.;
+    5341             :         delta = eps;
+    5342      619039 :         tau = sgndef * nrm;
+    5343      619039 : L60:
+    5344      619039 :         sigma -= delta * tau;
+    5345      619039 :         work[1] = d__[ibegin] - sigma;
+    5346             :         j = ibegin;
+    5347      619039 :         i__2 = in - 1;
+    5348     2450508 :         for (i__ = 1; i__ <= i__2; ++i__) {
+    5349     1831469 :             work[(in << 1) + i__] = 1. / work[i__];
+    5350     1831469 :             tmp = e[j] * work[(in << 1) + i__];
+    5351     1831469 :             work[i__ + 1] = d__[j + 1] - sigma - tmp * e[j];
+    5352     1831469 :             work[in + i__] = tmp;
+    5353     1831469 :             ++j;
+    5354             :         }
+    5355     3069547 :         for (i__ = in; i__ >= 1; --i__) {
+    5356     2450508 :             tmp = sgndef * work[i__];
+    5357     2450508 :         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      619039 :         PLUMED_BLAS_F77_FUNC(dcopy,DCOPY)(&in, &work[1], &c__1, &d__[ibegin], &c__1);
+    5364      619039 :         i__2 = in - 1;
+    5365      619039 :         PLUMED_BLAS_F77_FUNC(dcopy,DCOPY)(&i__2, &work[in + 1], &c__1, &e[ibegin], &c__1);
+    5366      619039 :         i__2 = in - 1;
+    5367     2450508 :         for (i__ = 1; i__ <= i__2; ++i__) {
+    5368     1831469 :             work[in * 3 + i__] = work[i__] * work[in + i__];
+    5369     1831469 :             work[(in << 2) + i__] = work[in * 3 + i__] * work[in + i__];
+    5370             :         }
+    5371      619039 :         if (sgndef > 0.) {
+    5372      524770 :             cnt = 1;
+    5373      524770 :             work[1] = (gl + gu) / 2. - sigma;
+    5374      524770 :             work[in + 1] = 0.;
+    5375      524770 :             work[(in << 1) + 1] = (gu - gl) / 2.;
+    5376             :         } else {
+    5377       94269 :             cnt = in;
+    5378       94269 :             work[in] = (gl + gu) / 2. - sigma;
+    5379       94269 :             work[in * 2] = 0.;
+    5380       94269 :             work[in * 3] = (gu - gl) / 2.;
+    5381             :         }
+    5382      619039 :         rtol = eps * 4.;
+    5383      619039 :         PLUMED_BLAS_F77_FUNC(dlarrbx,DLARRBX)(&in, &d__[ibegin], &e[ibegin], &work[in * 3 + 1], &work[(in <<
+    5384      619039 :                  2) + 1], &cnt, &cnt, &rtol, &rtol, &c__0, &work[1], &work[in 
+    5385      619039 :                 + 1], &work[(in << 1) + 1], &work[in * 5 + 1], &iwork[1], &
+    5386             :                 iinfo);
+    5387      619039 :         if (sgndef > 0.) {
+    5388      524770 :             tau = work[1] - work[(in << 1) + 1];
+    5389             :         } else {
+    5390       94269 :             tau = work[in] + work[in * 3];
+    5391             :         }
+    5392             : 
+    5393      619039 :         work[in * 3] = 1.;
+    5394             :         delta = eps * 2.;
+    5395      619039 : L100:
+    5396      619039 :         tau *= 1. - delta;
+    5397             : 
+    5398      619039 :         s = -tau;
+    5399             :         j = ibegin;
+    5400      619039 :         i__2 = in - 1;
+    5401     2450508 :         for (i__ = 1; i__ <= i__2; ++i__) {
+    5402     1831469 :             work[i__] = d__[j] + s;
+    5403     1831469 :             work[(in << 1) + i__] = 1. / work[i__];
+    5404     1831469 :             work[in + i__] = e[j] * d__[j] * work[(in << 1) + i__];
+    5405     1831469 :             s = s * work[in + i__] * e[j] - tau;
+    5406     1831469 :             ++j;
+    5407             :         }
+    5408      619039 :         work[in] = d__[iend] + s;
+    5409             : 
+    5410     3069547 :         for (i__ = in; i__ >= 1; --i__) {
+    5411     2450508 :             tmp = sgndef * work[i__];
+    5412     2450508 :             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      619039 :         sigma += tau;
+    5419      619039 :         PLUMED_BLAS_F77_FUNC(dcopy,DCOPY)(&in, &work[1], &c__1, &d__[ibegin], &c__1);
+    5420      619039 :         i__2 = in - 1;
+    5421      619039 :         PLUMED_BLAS_F77_FUNC(dcopy,DCOPY)(&i__2, &work[in + 1], &c__1, &e[ibegin], &c__1);
+    5422      619039 :         e[iend] = sigma;
+    5423      619039 :         tmp = (double) in * 4. * eps * (std::abs(sigma) + std::abs(tau));
+    5424             :         i__2 = iend;
+    5425     3069547 :         for (i__ = ibegin; i__ <= i__2; ++i__) {
+    5426     2450508 :             gersch[(i__ << 1) - 1] = gersch[(i__ << 1) - 1] - sigma - tmp;
+    5427     2450508 :             gersch[i__ * 2] = gersch[i__ * 2] - sigma + tmp;
+    5428             :         }
+    5429             : 
+    5430             :         j = ibegin;
+    5431      619039 :         i__2 = in - 1;
+    5432     2450508 :         for (i__ = 1; i__ <= i__2; ++i__) {
+    5433     1831469 :             work[(i__ << 1) - 1] = std::abs(d__[j]);
+    5434     1831469 :             work[i__ * 2] = e[j] * e[j] * work[(i__ << 1) - 1];
+    5435     1831469 :             ++j;
+    5436             :         }
+    5437      619039 :         work[(in << 1) - 1] = std::abs(d__[iend]);
+    5438             : 
+    5439      619039 :         PLUMED_BLAS_F77_FUNC(dlasq2,DLASQ2)(&in, &work[1], info);
+    5440      619039 :         if (*info != 0) {
+    5441             :             return;
+    5442             :         }
+    5443             : 
+    5444      619039 :         if (sgndef > 0.) {
+    5445      524770 :             i__2 = in;
+    5446     2598442 :             for (i__ = 1; i__ <= i__2; ++i__) {
+    5447     2073672 :                 ++(*m);
+    5448     2073672 :                 w[*m] = work[in - i__ + 1];
+    5449     2073672 :                 iblock[*m] = jblk;
+    5450     2073672 :                 indexw[*m] = i__;
+    5451             :             }
+    5452             :         } else {
+    5453       94269 :             i__2 = in;
+    5454      471105 :             for (i__ = 1; i__ <= i__2; ++i__) {
+    5455      376836 :                 ++(*m);
+    5456      376836 :                 w[*m] = -work[i__];
+    5457      376836 :                 iblock[*m] = jblk;
+    5458      376836 :                 indexw[*m] = i__;
+    5459             :             }
+    5460             :         }
+    5461      619039 :         ibegin = iend + 1;
+    5462      619508 : L170:
+    5463             :         ;
+    5464             :     }
+    5465      619040 :     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      619040 :     } else if (irange == 3) {
+    5485      559803 :         *m = *iu - *il + 1;
+    5486      559803 :         if (*nsplit == 1) {
+    5487             :             i__1 = *m;
+    5488     1134787 :             for (i__ = 1; i__ <= i__1; ++i__) {
+    5489      574993 :                 w[i__] = w[*il + i__ - 1];
+    5490      574993 :                 indexw[i__] = *il + i__ - 1;
+    5491             :             }
+    5492             :         } else {
+    5493             :             ibegin = 1;
+    5494             :             i__1 = *nsplit;
+    5495         447 :             for (i__ = 1; i__ <= i__1; ++i__) {
+    5496         438 :                 iend = isplit[i__];
+    5497         438 :                 i__2 = iend;
+    5498         962 :                 for (j = ibegin; j <= i__2; ++j) {
+    5499         524 :                     work[j] = w[j] + e[iend];
+    5500             :                 }
+    5501         438 :                 ibegin = iend + 1;
+    5502             :             }
+    5503           9 :             i__1 = *n;
+    5504         533 :             for (i__ = 1; i__ <= i__1; ++i__) {
+    5505         524 :                 iwork[i__] = i__;
+    5506         524 :                 iwork[*n + i__] = iblock[i__];
+    5507             :             }
+    5508           9 :             PLUMED_BLAS_F77_FUNC(dlasrt2,DLASRT2)("I", n, &work[1], &iwork[1], &iinfo);
+    5509           9 :             i__1 = *m;
+    5510         527 :             for (i__ = 1; i__ <= i__1; ++i__) {
+    5511         518 :                 itmp = iwork[*il + i__ - 1];
+    5512         518 :                 work[i__] = w[itmp];
+    5513         518 :                 iblock[i__] = iwork[*n + itmp];
+    5514             :             }
+    5515           9 :             i__1 = *m;
+    5516         527 :             for (i__ = 1; i__ <= i__1; ++i__) {
+    5517         518 :                 iwork[*n + i__] = iwork[*il + i__ - 1];
+    5518         518 :                 iwork[i__] = i__;
+    5519             :             }
+    5520           9 :             PLUMED_BLAS_F77_FUNC(ilasrt2,ILASRT2)("I", m, &iblock[1], &iwork[1], &iinfo);
+    5521             :             j = 1;
+    5522           9 :             itmp = iblock[j];
+    5523           9 :             cnt = iwork[*n + iwork[j]];
+    5524           9 :             if (itmp == 1) {
+    5525             :                 ibegin = 1;
+    5526             :             } else {
+    5527           0 :                 ibegin = isplit[itmp - 1] + 1;
+    5528             :             }
+    5529           9 :             i__1 = *m;
+    5530         527 :             for (i__ = 1; i__ <= i__1; ++i__) {
+    5531         518 :                 w[i__] = work[iwork[i__]];
+    5532         518 :                 if (iblock[i__] != itmp || i__ == *m) {
+    5533         435 :                     if (iblock[i__] == itmp) {
+    5534           8 :                         till = *m;
+    5535             :                     } else {
+    5536         427 :                         till = i__ - 1;
+    5537             :                     }
+    5538         435 :                     i__2 = till - j + 1;
+    5539         435 :                     PLUMED_BLAS_F77_FUNC(dlasrt,DLASRT)("I", &i__2, &w[j], &iinfo);
+    5540         435 :                     cnt = cnt - ibegin + 1;
+    5541         435 :                     i__2 = till;
+    5542         952 :                     for (k = j; k <= i__2; ++k) {
+    5543         517 :                         indexw[k] = cnt + k - j;
+    5544             :                     }
+    5545             :                     j = i__;
+    5546         435 :                     itmp = iblock[j];
+    5547         435 :                     cnt = iwork[*n + iwork[j]];
+    5548         435 :                     ibegin = isplit[itmp - 1] + 1;
+    5549         435 :                     if (i__ == *m && till < *m) {
+    5550           1 :                         indexw[*m] = cnt - ibegin + 1;
+    5551             :                     }
+    5552             :                 } else {
+    5553          83 :                     i__2 = cnt, i__3 = iwork[*n + iwork[i__]];
+    5554          83 :                     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          76 : 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          76 :     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          76 :     --work;
+    5602          76 :     --lplus;
+    5603          76 :     --dplus;
+    5604          76 :     --w;
+    5605             :     --lld;
+    5606          76 :     --ld;
+    5607          76 :     --l;
+    5608          76 :     --d__;
+    5609          76 :     *info = 0;
+    5610             :     eps = PLUMED_GMX_DOUBLE_EPS;
+    5611          76 :     *sigma = w[*ifirst];
+    5612             :     delta = eps * 2.;
+    5613             : 
+    5614          76 : L10:
+    5615          76 :     s = -(*sigma);
+    5616          76 :     dplus[1] = d__[1] + s;
+    5617             :     dmax1 = std::abs(dplus[1]);
+    5618          76 :     i__1 = *n - 1;
+    5619       28348 :     for (i__ = 1; i__ <= i__1; ++i__) {
+    5620       28272 :         lplus[i__] = ld[i__] / dplus[i__];
+    5621       28272 :         s = s * lplus[i__] * l[i__] - *sigma;
+    5622       28272 :         dplus[i__ + 1] = d__[i__ + 1] + s;
+    5623             :         d__2 = dmax1, d__3 = std::abs(dplus[i__ + 1]);
+    5624       28272 :         dmax1 = (d__2>d__3) ? d__2 : d__3;
+    5625             :     }
+    5626          76 :     if (std::isnan(dmax1)) {
+    5627           0 :         *sigma -= std::abs(*sigma) * delta;
+    5628           0 :         delta *= 2.;
+    5629           0 :         goto L10;
+    5630             :     }
+    5631             : 
+    5632          76 :     tmp = w[*ilast];
+    5633             :     delta = eps * 2.;
+    5634          76 : L30:
+    5635          76 :     s = -tmp;
+    5636          76 :     work[1] = d__[1] + s;
+    5637             :     dmax2 = std::abs(work[1]);
+    5638          76 :     i__1 = *n - 1;
+    5639       28348 :     for (i__ = 1; i__ <= i__1; ++i__) {
+    5640       28272 :         work[*n + i__] = ld[i__] / work[i__];
+    5641       28272 :         s = s * work[*n + i__] * l[i__] - tmp;
+    5642       28272 :         work[i__ + 1] = d__[i__ + 1] + s;
+    5643             :         d__2 = dmax2, d__3 = std::abs(work[i__ + 1]);
+    5644       28272 :         dmax2 = (d__2>d__3) ? d__2 : d__3;
+    5645             :     }
+    5646          76 :     if (std::isnan(dmax2)) {
+    5647           0 :         tmp += std::abs(tmp) * delta;
+    5648           0 :         delta *= 2.;
+    5649           0 :         goto L30;
+    5650             :     }
+    5651          76 :     if (dmax2 < dmax1) {
+    5652          42 :         *sigma = tmp;
+    5653          42 :         PLUMED_BLAS_F77_FUNC(dcopy,DCOPY)(n, &work[1], &i1, &dplus[1], &i1);
+    5654          42 :         i__1 = *n - 1;
+    5655          42 :         PLUMED_BLAS_F77_FUNC(dcopy,DCOPY)(&i__1, &work[*n + 1], &i1, &lplus[1], &i1);
+    5656             :     }
+    5657             : 
+    5658          76 :     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      619040 : 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      619040 :     double c_b5 = 0.;
+    5696      619040 :     int c__1 = 1;
+    5697      619040 :     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      619040 :     --d__;
+    5732      619040 :     --l;
+    5733             :     --isplit;
+    5734      619040 :     --w;
+    5735      619040 :     --iblock;
+    5736      619040 :     --indexw;
+    5737             :     --gersch;
+    5738      619040 :     z_dim1 = *ldz;
+    5739      619040 :     z_offset = 1 + z_dim1;
+    5740      619040 :     z__ -= z_offset;
+    5741      619040 :     --isuppz;
+    5742      619040 :     --work;
+    5743      619040 :     --iwork;
+    5744             : 
+    5745      619040 :     inderr = *n;
+    5746      619040 :     indld = *n << 1;
+    5747      619040 :     indlld = *n * 3;
+    5748      619040 :     indgap = *n << 2;
+    5749      619040 :     indwrk = *n * 5 + 1;
+    5750             : 
+    5751             :     iindr = *n;
+    5752             :     iindc1 = *n << 1;
+    5753             :     iindc2 = *n * 3;
+    5754      619040 :     iindwk = (*n << 2) + 1;
+    5755             : 
+    5756             :     eps = PLUMED_GMX_DOUBLE_EPS;
+    5757             : 
+    5758             :     i__1 = *n << 1;
+    5759     5520994 :     for (i__ = 1; i__ <= i__1; ++i__) {
+    5760     4901954 :         iwork[i__] = 0;
+    5761             :     }
+    5762      619040 :     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      619040 :     i__1 = iblock[*m];
+    5768     1238546 :     for (jblk = 1; jblk <= i__1; ++jblk) {
+    5769      619506 :         iend = isplit[jblk];
+    5770             : 
+    5771      619506 :         wend = wbegin - 1;
+    5772     1431499 : L171:
+    5773     1431499 :         if (wend < *m) {
+    5774      812459 :             if (iblock[wend + 1] == jblk) {
+    5775      811993 :                 ++wend;
+    5776      811993 :                 goto L171;
+    5777             :             }
+    5778             :         }
+    5779      619506 :         if (wend < wbegin) {
+    5780           0 :             ibegin = iend + 1;
+    5781           0 :             continue;
+    5782             :         }
+    5783             : 
+    5784      619506 :         if (ibegin == iend) {
+    5785         469 :             z__[ibegin + wbegin * z_dim1] = 1.;
+    5786         469 :             isuppz[(wbegin << 1) - 1] = ibegin;
+    5787         469 :             isuppz[wbegin * 2] = ibegin;
+    5788         469 :             ibegin = iend + 1;
+    5789         469 :             wbegin = wend + 1;
+    5790         469 :             continue;
+    5791             :         }
+    5792      619037 :         oldien = ibegin - 1;
+    5793      619037 :         in = iend - oldien;
+    5794      619037 :         d__1 = .001, d__2 = 1. / (double) in;
+    5795      619037 :         reltol = (d__1<d__2) ? d__1 : d__2;
+    5796      619037 :         im = wend - wbegin + 1;
+    5797      619037 :         PLUMED_BLAS_F77_FUNC(dcopy,DCOPY)(&im, &w[wbegin], &c__1, &work[1], &c__1);
+    5798      619037 :         i__2 = im - 1;
+    5799      811524 :         for (i__ = 1; i__ <= i__2; ++i__) {
+    5800      192487 :             work[inderr + i__] = eps * std::abs(work[i__]);
+    5801      192487 :             work[indgap + i__] = work[i__ + 1] - work[i__];
+    5802             :         }
+    5803      619037 :         work[inderr + im] = eps * std::abs(work[im]);
+    5804      619037 :         d__2 = std::abs(work[im]);
+    5805      619037 :         work[indgap + im] = (d__2>eps) ? d__2 : eps;
+    5806             :         ndone = 0;
+    5807             : 
+    5808             :         ndepth = 0;
+    5809             :         parity = 1;
+    5810             :         nclus = 1;
+    5811      619037 :         iwork[iindc1 + 1] = 1;
+    5812      619037 :         iwork[iindc1 + 2] = im;
+    5813             : 
+    5814     1238085 : L40:
+    5815     1238085 :         if (ndone < im) {
+    5816             :             oldncl = nclus;
+    5817             :             nclus = 0;
+    5818      619048 :             parity = 1 - parity;
+    5819      619048 :             if (parity == 0) {
+    5820             :                 oldcls = iindc1;
+    5821             :                 newcls = iindc2;
+    5822             :             } else {
+    5823             :                 oldcls = iindc2;
+    5824             :                 newcls = iindc1;
+    5825             :             }
+    5826             :             i__2 = oldncl;
+    5827     1238161 :             for (i__ = 1; i__ <= i__2; ++i__) {
+    5828             : 
+    5829      619113 :                 j = oldcls + (i__ << 1);
+    5830      619113 :                 oldfst = iwork[j - 1];
+    5831      619113 :                 oldlst = iwork[j];
+    5832      619113 :                 if (ndepth > 0) {
+    5833          76 :                     j = wbegin + oldfst - 1;
+    5834          76 :                     PLUMED_BLAS_F77_FUNC(dcopy,DCOPY)(&in, &z__[ibegin + j * z_dim1], &c__1, &d__[ibegin]
+    5835             :                             , &c__1);
+    5836          76 :                     i__3 = in - 1;
+    5837          76 :                     PLUMED_BLAS_F77_FUNC(dcopy,DCOPY)(&i__3, &z__[ibegin + (j + 1) * z_dim1], &c__1, &l[
+    5838             :                             ibegin], &c__1);
+    5839          76 :                     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      619113 :                 i__3 = in - 1;
+    5844     2478852 :                 for (j = 1; j <= i__3; ++j) {
+    5845     1859739 :                     tmp = d__[k] * l[k];
+    5846     1859739 :                     work[indld + j] = tmp;
+    5847     1859739 :                     work[indlld + j] = tmp * l[k];
+    5848     1859739 :                     ++k;
+    5849             :                 }
+    5850      619113 :                 if (ndepth > 0) {
+    5851             : 
+    5852          76 :                     p = indexw[wbegin - 1 + oldfst];
+    5853          76 :                     q = indexw[wbegin - 1 + oldlst];
+    5854          76 :                     d__1 = eps * 4.;
+    5855          76 :                     i__3 = p - oldfst;
+    5856          76 :                     PLUMED_BLAS_F77_FUNC(dlarrbx,DLARRBX)(&in, &d__[ibegin], &l[ibegin], &work[indld + 1], &
+    5857          76 :                             work[indlld + 1], &p, &q, &reltol, &d__1, &i__3, &
+    5858          76 :                             work[1], &work[indgap + 1], &work[inderr + 1], &
+    5859          76 :                             work[indwrk + in], &iwork[iindwk], &iinfo);
+    5860             :                 }
+    5861      619113 :                 newfrs = oldfst;
+    5862      619113 :                 i__3 = oldlst;
+    5863     1431585 :                 for (j = oldfst; j <= i__3; ++j) {
+    5864      812472 :                     if (j == oldlst || work[indgap + j] >= 
+    5865      193359 :                         reltol * std::abs(work[j])) {
+    5866      811600 :                         newlst = j;
+    5867             :                     } else {
+    5868             : 
+    5869         872 :                         relgap = work[indgap + j] / std::abs(work[j]);
+    5870         872 :                         if (j == newfrs) {
+    5871             :                             minrgp = relgap;
+    5872             :                         } else {
+    5873         796 :                             minrgp = (minrgp<relgap) ? minrgp : relgap;
+    5874             :                         }
+    5875         872 :                         continue;
+    5876             :                     }
+    5877      811600 :                     newsiz = newlst - newfrs + 1;
+    5878      811600 :                     newftt = wbegin + newfrs - 1;
+    5879      811600 :                     nomgs = newsiz == 1 || newsiz > 1 || minrgp < mgstol;
+    5880      811600 :                     if (newsiz > 1 && nomgs) {
+    5881             : 
+    5882          76 :                         PLUMED_BLAS_F77_FUNC(dlarrfx,DLARRFX)(&in, &d__[ibegin], &l[ibegin], &work[indld + 
+    5883          76 :                                 1], &work[indlld + 1], &newfrs, &newlst, &
+    5884          76 :                                 work[1], &sigma, &z__[ibegin + newftt * 
+    5885          76 :                                 z_dim1], &z__[ibegin + (newftt + 1) * z_dim1],
+    5886          76 :                                  &work[indwrk], info);
+    5887          76 :                         if (*info == 0) {
+    5888          76 :                             tmp = eps * std::abs(sigma);
+    5889          76 :                             i__4 = newlst;
+    5890        1024 :                             for (k = newfrs; k <= i__4; ++k) {
+    5891         948 :                                 work[k] -= sigma;
+    5892         948 :                                 d__1 = work[indgap + k];
+    5893         948 :                                 work[indgap + k] = (d__1>tmp) ? d__1 : tmp;
+    5894         948 :                                 work[inderr + k] += tmp;
+    5895             :                             }
+    5896          76 :                             ++nclus;
+    5897          76 :                             k = newcls + (nclus << 1);
+    5898          76 :                             iwork[k - 1] = newfrs;
+    5899          76 :                             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     1623048 :                         for (k = newfrs; k <= i__4; ++k) {
+    5935             :                             iter = 0;
+    5936      812986 : L90:
+    5937      812986 :                             lambda = work[k];
+    5938             : 
+    5939      812986 :                             PLUMED_BLAS_F77_FUNC(dlar1vx,DLAR1VX)(&in, &c__1, &in, &lambda, &d__[ibegin], &
+    5940      812986 :                                     l[ibegin], &work[indld + 1], &work[indlld 
+    5941      812986 :                                     + 1], &w[wbegin + k - 1], &gersch[(oldien 
+    5942      812986 :                                     << 1) + 1], &z__[ibegin + ktot * z_dim1], 
+    5943      812986 :                                     &ztz, &mingma, &iwork[iindr + ktot], &
+    5944      812986 :                                     isuppz[(ktot << 1) - 1], &work[indwrk]);
+    5945      812986 :                             tmp = 1. / ztz;
+    5946      812986 :                             nrminv =  std::sqrt(tmp);
+    5947      812986 :                             resid = std::abs(mingma) * nrminv;
+    5948      812986 :                             rqcorr = mingma * tmp;
+    5949      812986 :                             if (k == in) {
+    5950       72739 :                                 gap = work[indgap + k - 1];
+    5951      740247 :                             } else if (k == 1) {
+    5952      619568 :                                 gap = work[indgap + k];
+    5953             :                             } else {
+    5954      120679 :                                 d__1 = work[indgap + k - 1], d__2 = work[
+    5955      120679 :                                         indgap + k];
+    5956      120679 :                                 gap = (d__1<d__2) ? d__1 : d__2;
+    5957             :                             }
+    5958      812986 :                             ++iter;
+    5959      812986 :                             if (resid > *tol * gap && std::abs(rqcorr) > eps * 4. *
+    5960       44121 :                                      std::abs(lambda)) {
+    5961        1479 :                                 work[k] = lambda + rqcorr;
+    5962        1479 :                                 if (iter < 8) {
+    5963        1462 :                                     goto L90;
+    5964             :                                 }
+    5965             :                             }
+    5966      811524 :                             iwork[ktot] = 1;
+    5967      811524 :                             if (newsiz == 1) {
+    5968      811524 :                                 ++ndone;
+    5969             :                             }
+    5970      811524 :                             zfrom = isuppz[(ktot << 1) - 1];
+    5971      811524 :                             zto = isuppz[ktot * 2];
+    5972      811524 :                             i__5 = zto - zfrom + 1;
+    5973      811524 :                             PLUMED_BLAS_F77_FUNC(dscal,DSCAL)(&i__5, &nrminv, &z__[ibegin + zfrom - 1 + 
+    5974      811524 :                                     ktot * z_dim1], &c__1);
+    5975      811524 :                             ++ktot;
+    5976             :                         }
+    5977      811524 :                         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      811600 :                     newfrs = j + 1;
+    6010             :                 }
+    6011             :             }
+    6012      619048 :             ++ndepth;
+    6013      619048 :             goto L40;
+    6014             :         }
+    6015      619037 :         j = wbegin << 1;
+    6016             :         i__2 = wend;
+    6017     1430561 :         for (i__ = wbegin; i__ <= i__2; ++i__) {
+    6018      811524 :             isuppz[j - 1] += oldien;
+    6019      811524 :             isuppz[j] += oldien;
+    6020      811524 :             j += 2;
+    6021             : 
+    6022             :         }
+    6023      619037 :         ibegin = iend + 1;
+    6024      619037 :         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          24 :                 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          24 :                 eta = b / a;
+    7674        2819 :             } else if (a <= 0.) {
+    7675           0 :                 eta = (a -  std::sqrt(std::abs(a * a - b * 4. * c__))) / (c__ * 2.);
+    7676             :             } else {
+    7677        2819 :                 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        1664 :             sg2lb = (sg2lb > tau) ? sg2lb : tau;
+    7778             :         } else {
+    7779        1521 :             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        9407 :         for (niter = iter; niter <= 20; ++niter) {
+    7796             : 
+    7797        9407 :             if (std::abs(w) <= eps * erretm) {
+    7798        3185 :                 goto L240;
+    7799             :             }
+    7800             : 
+    7801        6222 :             if (! swtch3) {
+    7802        5177 :                 dtipsq = work[ip1] * delta[ip1];
+    7803        5177 :                 dtisq = work[*i__] * delta[*i__];
+    7804        5177 :                 if (! swtch) {
+    7805        5070 :                     if (orgati) {
+    7806        2626 :                         d__1 = z__[*i__] / dtisq;
+    7807        2626 :                         c__ = w - dtipsq * dw + delsq * (d__1 * d__1);
+    7808             :                     } else {
+    7809        2444 :                         d__1 = z__[ip1] / dtipsq;
+    7810        2444 :                         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        5177 :                 a = (dtipsq + dtisq) * w - dtipsq * dtisq * dw;
+    7822        5177 :                 b = dtipsq * dtisq * w;
+    7823        5177 :                 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        5177 :                 } else if (a <= 0.) {
+    7839           0 :                   eta = (a -  std::sqrt(std::abs(a * a - b * 4. * c__))) / (c__ * 2.);
+    7840             :                 } else {
+    7841        5177 :                   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        6222 :             if (w * eta >= 0.) {
+    7889           0 :                 eta = -w / dw;
+    7890             :             }
+    7891        6222 :             if (orgati) {
+    7892        3228 :                 temp1 = work[*i__] * delta[*i__];
+    7893        3228 :                 temp = eta - temp1;
+    7894             :             } else {
+    7895        2994 :                 temp1 = work[ip1] * delta[ip1];
+    7896        2994 :                 temp = eta - temp1;
+    7897             :             }
+    7898        6222 :             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        6222 :             tau += eta;
+    7907        6222 :             eta /= *sigma +  std::sqrt(*sigma * *sigma + eta);
+    7908             : 
+    7909        6222 :             *sigma += eta;
+    7910        6222 :             i__1 = *n;
+    7911      819534 :             for (j = 1; j <= i__1; ++j) {
+    7912      813312 :                 work[j] += eta;
+    7913      813312 :                 delta[j] -= eta;
+    7914             :             }
+    7915             : 
+    7916             :             prew = w;
+    7917             : 
+    7918             :             dpsi = 0.;
+    7919             :             psi = 0.;
+    7920             :             erretm = 0.;
+    7921             :             i__1 = iim1;
+    7922      391983 :             for (j = 1; j <= i__1; ++j) {
+    7923      385761 :                 temp = z__[j] / (work[j] * delta[j]);
+    7924      385761 :                 psi += z__[j] * temp;
+    7925      385761 :                 dpsi += temp * temp;
+    7926      385761 :                 erretm += psi;
+    7927             :             }
+    7928             :             erretm = std::abs(erretm);
+    7929             : 
+    7930             :             dphi = 0.;
+    7931             :             phi = 0.;
+    7932             :             i__1 = iip1;
+    7933      427551 :             for (j = *n; j >= i__1; --j) {
+    7934      421329 :                 temp = z__[j] / (work[j] * delta[j]);
+    7935      421329 :                 phi += z__[j] * temp;
+    7936      421329 :                 dphi += temp * temp;
+    7937      421329 :                 erretm += phi;
+    7938             :             }
+    7939             : 
+    7940        6222 :             temp = z__[ii] / (work[ii] * delta[ii]);
+    7941        6222 :             dw = dpsi + dphi + temp * temp;
+    7942        6222 :             temp = z__[ii] * temp;
+    7943        6222 :             w = rhoinv + phi + psi + temp;
+    7944        6222 :             erretm = (phi - psi) * 8. + erretm + rhoinv * 2. + std::abs(temp) * 3. 
+    7945        6222 :                     + std::abs(tau) * dw;
+    7946        6222 :             if (w * prew > 0. && std::abs(w) > std::abs(prew) / 10.) {
+    7947           2 :                 swtch = ! swtch;
+    7948             :             }
+    7949             : 
+    7950        6222 :             if (w <= 0.) {
+    7951        3292 :                 sg2lb = (sg2lb > tau) ? sg2lb : tau;
+    7952             :             } else {
+    7953        2930 :                 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      619558 : 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      619558 :   const char ch=std::toupper(*uplo);
+    9107             : 
+    9108      619558 :   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      619558 :   } 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     1439391 :     for(j=0;j<*n;j++) {
+    9122     5345626 :       for(i=0;i<*m;i++)
+    9123     4525792 :         a[j*(*lda)+i] = *alpha;
+    9124             :     }    
+    9125             :   }
+    9126             : 
+    9127      619558 :   k = (*m < *n) ? *m : *n;
+    9128     1439393 :   for(i=0;i<k;i++)
+    9129      819835 :     a[i*(*lda)+i] = *beta;
+    9130      619558 : }
+    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      619039 : 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      619039 :     --z__;
+    9265             : 
+    9266      619039 :     *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      619039 :     if (*n < 0) {
+    9277           0 :         *info = -1;
+    9278           0 :         return;
+    9279      619039 :     } else if (*n == 0) {
+    9280             :         return;
+    9281      619039 :     } else if (*n == 1) {
+    9282             : 
+    9283           0 :         if (z__[1] < 0.) {
+    9284           0 :             *info = -201;
+    9285             :         }
+    9286           0 :         return;
+    9287      619039 :     } else if (*n == 2) {
+    9288             : 
+    9289       13366 :         if (z__[2] < 0. || z__[3] < 0.) {
+    9290           0 :             *info = -2;
+    9291           0 :             return;
+    9292       13366 :         } else if (z__[3] > z__[1]) {
+    9293             :             d__ = z__[3];
+    9294           0 :             z__[3] = z__[1];
+    9295           0 :             z__[1] = d__;
+    9296             :         }
+    9297       13366 :         z__[5] = z__[1] + z__[2] + z__[3];
+    9298       13366 :         if (z__[2] > z__[3] * tol2) {
+    9299       13366 :             t = (z__[1] - z__[3] + z__[2]) * .5;
+    9300       13366 :             s = z__[3] * (z__[2] / t);
+    9301       13366 :             if (s <= t) {
+    9302       13366 :                 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       13366 :             t = z__[1] + (s + z__[2]);
+    9307       13366 :             z__[3] *= z__[1] / t;
+    9308       13366 :             z__[1] = t;
+    9309             :         }
+    9310       13366 :         z__[2] = z__[3];
+    9311       13366 :         z__[6] = z__[2] + z__[1];
+    9312       13366 :         return;
+    9313             :     }
+    9314      605673 :     z__[*n * 2] = 0.;
+    9315      605673 :     emin = z__[2];
+    9316      605673 :     qmax = 0.;
+    9317             :     zmax = 0.;
+    9318             :     d__ = 0.;
+    9319             :     e = 0.;
+    9320             : 
+    9321      605673 :     i__1 = 2*(*n - 1);
+    9322     2423776 :     for (k = 1; k <= i__1; k += 2) {
+    9323     1818103 :         if (z__[k] < 0.) {
+    9324           0 :             *info = -(k + 200);
+    9325           0 :             return;
+    9326     1818103 :         } else if (z__[k + 1] < 0.) {
+    9327           0 :             *info = -(k + 201);
+    9328           0 :             return;
+    9329             :         }
+    9330     1818103 :         d__ += z__[k];
+    9331     1818103 :         e += z__[k + 1];
+    9332     1818103 :         d__1 = qmax, d__2 = z__[k];
+    9333     1818103 :         qmax = (d__1>d__2) ? d__1 : d__2;
+    9334             :         d__1 = emin, d__2 = z__[k + 1];
+    9335     1818103 :         emin = (d__1<d__2) ? d__1 : d__2;
+    9336     1818103 :         d__1 = (qmax>zmax) ? qmax : zmax;
+    9337             :         d__2 = z__[k + 1];
+    9338     1818103 :         zmax = (d__1>d__2) ? d__1 : d__2;
+    9339             :     }
+    9340      605673 :     if (z__[(*n << 1) - 1] < 0.) {
+    9341           0 :         *info = -((*n << 1) + 199);
+    9342           0 :         return;
+    9343             :     }
+    9344      605673 :     d__ += z__[(*n << 1) - 1];
+    9345      605673 :     d__1 = qmax, d__2 = z__[(*n << 1) - 1];
+    9346      605717 :     qmax = (d__1>d__2) ? d__1 : d__2;
+    9347             : 
+    9348      605673 :     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      605673 :     trace = d__ + e;
+    9359             : 
+    9360      605673 :     if (std::abs(trace)<PLUMED_GMX_DOUBLE_MIN) {
+    9361           0 :         z__[(*n << 1) - 1] = 0.;
+    9362           0 :         return;
+    9363             :     }
+    9364             : 
+    9365      605673 :     ieee = 1;
+    9366      605673 :     posinf = one/zero;
+    9367      605673 :     if(posinf<=1.0)
+    9368           0 :       ieee = 0;
+    9369             :     neginf = -one/zero;
+    9370      605673 :     if(neginf>=0.0)
+    9371           0 :       ieee = 0;
+    9372      605673 :     negzro = one/(neginf+one);
+    9373      605673 :     if(std::abs(negzro)>PLUMED_GMX_DOUBLE_MIN)
+    9374           0 :       ieee = 0;
+    9375      605673 :     neginf = one/negzro;
+    9376      605673 :     if(neginf>=0)
+    9377           0 :       ieee = 0;
+    9378      605673 :     newzro = negzro + zero;
+    9379      605673 :     if(std::abs(newzro-zero)>PLUMED_GMX_DOUBLE_MIN)
+    9380           0 :       ieee = 0;
+    9381      605673 :     posinf = one /newzro;
+    9382      605673 :     if(posinf<=one)
+    9383           0 :       ieee = 0;
+    9384      605673 :     neginf = neginf*posinf;
+    9385      605673 :     if(neginf>=zero)
+    9386           0 :       ieee = 0;
+    9387      605673 :     posinf = posinf*posinf;
+    9388      605673 :     if(posinf<=1.0)
+    9389           0 :       ieee = 0;
+    9390             : 
+    9391     3029449 :     for (k = *n << 1; k >= 2; k += -2) {
+    9392     2423776 :         z__[k * 2] = 0.;
+    9393     2423776 :         z__[(k << 1) - 1] = z__[k];
+    9394     2423776 :         z__[(k << 1) - 2] = 0.;
+    9395     2423776 :         z__[(k << 1) - 3] = z__[k - 1];
+    9396             :     }
+    9397             : 
+    9398      605673 :     i0 = 1;
+    9399      605673 :     n0 = *n;
+    9400             : 
+    9401      605673 :     if (z__[(i0 << 2) - 3] * 1.5 < z__[(n0 << 2) - 3]) {
+    9402         739 :         ipn4 = 4*(i0 + n0);
+    9403         739 :         i__1 = 2*(i0 + n0 - 1);
+    9404        2216 :         for (i4 = i0 << 2; i4 <= i__1; i4 += 4) {
+    9405        1477 :             temp = z__[i4 - 3];
+    9406        1477 :             z__[i4 - 3] = z__[ipn4 - i4 - 3];
+    9407        1477 :             z__[ipn4 - i4 - 3] = temp;
+    9408        1477 :             temp = z__[i4 - 1];
+    9409        1477 :             z__[i4 - 1] = z__[ipn4 - i4 - 5];
+    9410        1477 :             z__[ipn4 - i4 - 5] = temp;
+    9411             :         }
+    9412             :     }
+    9413             : 
+    9414      605673 :     pp = 0;
+    9415             : 
+    9416     1817019 :     for (k = 1; k <= 2; ++k) {
+    9417             : 
+    9418     1211346 :         d__ = z__[(n0 << 2) + pp - 3];
+    9419     1211346 :         i__1 = (i0 << 2) + pp;
+    9420     4847552 :         for (i4 = 4*(n0 - 1) + pp; i4 >= i__1; i4 += -4) {
+    9421     3636206 :             if (z__[i4 - 1] <= tol2 * d__) {
+    9422          33 :                 z__[i4 - 1] = -0.;
+    9423          33 :                 d__ = z__[i4 - 3];
+    9424             :             } else {
+    9425     3636173 :                 d__ = z__[i4 - 3] * (d__ / (d__ + z__[i4 - 1]));
+    9426             :             }
+    9427             :         }
+    9428             : 
+    9429     1211346 :         emin = z__[(i0 << 2) + pp + 1];
+    9430     1211346 :         d__ = z__[(i0 << 2) + pp - 3];
+    9431             :         i__1 = 4*(n0 - 1) + pp;
+    9432     4847552 :         for (i4 = (i0 << 2) + pp; i4 <= i__1; i4 += 4) {
+    9433     3636206 :             z__[i4 - (pp << 1) - 2] = d__ + z__[i4 - 1];
+    9434     3636206 :             if (z__[i4 - 1] <= tol2 * d__) {
+    9435         124 :                 z__[i4 - 1] = -0.;
+    9436         124 :                 z__[i4 - (pp << 1) - 2] = d__;
+    9437         124 :                 z__[i4 - (pp << 1)] = 0.;
+    9438         124 :                 d__ = z__[i4 + 1];
+    9439     3636082 :             } else if (safmin * z__[i4 + 1] < z__[i4 - (pp << 1) - 2] && 
+    9440     3636082 :                     safmin * z__[i4 - (pp << 1) - 2] < z__[i4 + 1]) {
+    9441     3636082 :                 temp = z__[i4 + 1] / z__[i4 - (pp << 1) - 2];
+    9442     3636082 :                 z__[i4 - (pp << 1)] = z__[i4 - 1] * temp;
+    9443     3636082 :                 d__ *= temp;
+    9444             :             } else {
+    9445           0 :                 z__[i4 - (pp << 1)] = z__[i4 + 1] * (z__[i4 - 1] / z__[i4 - (
+    9446             :                         pp << 1) - 2]);
+    9447           0 :                 d__ = z__[i4 + 1] * (d__ / z__[i4 - (pp << 1) - 2]);
+    9448             :             }
+    9449     3636206 :             d__1 = emin, d__2 = z__[i4 - (pp << 1)];
+    9450     3636206 :             emin = (d__1<d__2) ? d__1 : d__2;
+    9451             :         }
+    9452     1211346 :         z__[(n0 << 2) - pp - 2] = d__;
+    9453             : 
+    9454             : 
+    9455     1211346 :         qmax = z__[(i0 << 2) - pp - 2];
+    9456     1211346 :         i__1 = (n0 << 2) - pp - 2;
+    9457     4847552 :         for (i4 = (i0 << 2) - pp + 2; i4 <= i__1; i4 += 4) {
+    9458     3636206 :             d__1 = qmax, d__2 = z__[i4];
+    9459     4862796 :             qmax = (d__1>d__2) ? d__1 : d__2;
+    9460             :         }
+    9461             : 
+    9462     1211346 :         pp = 1 - pp;
+    9463             :     }
+    9464             : 
+    9465      605673 :     iter = 2;
+    9466      605673 :     nfail = 0;
+    9467      605673 :     ndiv = 2*(n0 - i0);
+    9468             : 
+    9469      605673 :     i__1 = *n + 1;
+    9470     1211599 :     for (iwhila = 1; iwhila <= i__1; ++iwhila) {
+    9471     1211599 :         if (n0 < 1) {
+    9472      605673 :             goto L170;
+    9473             :         }
+    9474             : 
+    9475      605926 :         desig = 0.;
+    9476      605926 :         if (n0 == *n) {
+    9477      605673 :             sigma = 0.;
+    9478             :         } else {
+    9479         253 :             sigma = -z__[(n0 << 2) - 1];
+    9480             :         }
+    9481      605926 :         if (sigma < 0.) {
+    9482           0 :             *info = 1;
+    9483           0 :             return;
+    9484             :         }
+    9485             : 
+    9486             :         emax = 0.;
+    9487      605926 :         if (n0 > i0) {
+    9488      605673 :             emin = std::abs(z__[(n0 << 2) - 5]);
+    9489             :         } else {
+    9490             :             emin = 0.;
+    9491             :         }
+    9492      605926 :         qmin = z__[(n0 << 2) - 3];
+    9493      605926 :         qmax = qmin;
+    9494     2429096 :         for (i4 = n0 << 2; i4 >= 8; i4 += -4) {
+    9495     1823354 :             if (z__[i4 - 5] <= 0.) {
+    9496         184 :                 goto L100;
+    9497             :             }
+    9498     1823170 :             if (qmin >= emax * 4.) {
+    9499     1214434 :                 d__1 = qmin, d__2 = z__[i4 - 3];
+    9500     1214434 :                 qmin = (d__1<d__2) ? d__1 : d__2;
+    9501             :                 d__1 = emax, d__2 = z__[i4 - 5];
+    9502     1214434 :                 emax = (d__1>d__2) ? d__1 : d__2;
+    9503             :             }
+    9504     1823170 :             d__1 = qmax, d__2 = z__[i4 - 7] + z__[i4 - 5];
+    9505     1823170 :             qmax = (d__1>d__2) ? d__1 : d__2;
+    9506             :             d__1 = emin, d__2 = z__[i4 - 5];
+    9507     1823170 :             emin = (d__1<d__2) ? d__1 : d__2;
+    9508             :         }
+    9509             :         i4 = 4;
+    9510             : 
+    9511      605926 : L100:
+    9512      605926 :         i0 = i4 / 4;
+    9513      605926 :         pp = 0;
+    9514             : 
+    9515      605926 :         if (n0 - i0 > 1) {
+    9516      605788 :             dee = z__[(i0 << 2) - 3];
+    9517             :             deemin = dee;
+    9518             :             kmin = i0;
+    9519      605788 :             i__2 = (n0 << 2) - 3;
+    9520     3034741 :             for (i4 = (i0 << 2) - 3; i4 <= i__2; i4 += 4) {
+    9521     2428953 :                 dee = z__[i4] * (dee / (dee + z__[i4 - 2]));
+    9522     2428953 :                 if (dee <= deemin) {
+    9523             :                     deemin = dee;
+    9524     1313195 :                     kmin = (i4 + 3) / 4;
+    9525             :                 }
+    9526             :             }
+    9527      605788 :             if (2*(kmin - i0) < n0 - kmin && deemin <= z__[(n0 << 2) - 3] * 
+    9528             :                     .5) {
+    9529        7917 :                 ipn4 = 4*(i0 + n0);
+    9530        7917 :                 pp = 2;
+    9531        7917 :                 i__2 = 2*(i0 + n0 - 1);
+    9532       25581 :                 for (i4 = i0 << 2; i4 <= i__2; i4 += 4) {
+    9533       17664 :                     temp = z__[i4 - 3];
+    9534       17664 :                     z__[i4 - 3] = z__[ipn4 - i4 - 3];
+    9535       17664 :                     z__[ipn4 - i4 - 3] = temp;
+    9536       17664 :                     temp = z__[i4 - 2];
+    9537       17664 :                     z__[i4 - 2] = z__[ipn4 - i4 - 2];
+    9538       17664 :                     z__[ipn4 - i4 - 2] = temp;
+    9539       17664 :                     temp = z__[i4 - 1];
+    9540       17664 :                     z__[i4 - 1] = z__[ipn4 - i4 - 5];
+    9541       17664 :                     z__[ipn4 - i4 - 5] = temp;
+    9542       17664 :                     temp = z__[i4];
+    9543       17664 :                     z__[i4] = z__[ipn4 - i4 - 4];
+    9544       17664 :                     z__[ipn4 - i4 - 4] = temp;
+    9545             :                 }
+    9546             :             }
+    9547             :         }
+    9548             : 
+    9549             : 
+    9550      605926 :         d__1 = 0., d__2 = qmin -  std::sqrt(qmin) * 2. * std::sqrt(emax);
+    9551      605926 :         dmin__ = -((d__1>d__2) ? d__1 : d__2);
+    9552             : 
+    9553      605926 :         nbig = (n0 - i0 + 1) * 30;
+    9554             :         i__2 = nbig;
+    9555    14910352 :         for (iwhilb = 1; iwhilb <= i__2; ++iwhilb) {
+    9556    14910352 :             if (i0 > n0) {
+    9557      605926 :                 goto L150;
+    9558             :             }
+    9559             : 
+    9560    14304426 :             PLUMED_BLAS_F77_FUNC(dlasq3,DLASQ3)(&i0, &n0, &z__[1], &pp, &dmin__, &sigma, &desig, &qmax, &
+    9561             :                     nfail, &iter, &ndiv, &ieee);
+    9562             : 
+    9563    14304426 :             pp = 1 - pp;
+    9564             : 
+    9565    14304426 :             if (pp == 0 && n0 - i0 >= 3) {
+    9566      183875 :                 if (z__[n0 * 4] <= tol2 * qmax || z__[(n0 << 2) - 1] <= tol2 *
+    9567             :                          sigma) {
+    9568         522 :                     splt = i0 - 1;
+    9569         522 :                     qmax = z__[(i0 << 2) - 3];
+    9570         522 :                     emin = z__[(i0 << 2) - 1];
+    9571         522 :                     oldemn = z__[i0 * 4];
+    9572         522 :                     i__3 = 4*(n0 - 3);
+    9573       43166 :                     for (i4 = i0 << 2; i4 <= i__3; i4 += 4) {
+    9574       42644 :                         if (z__[i4] <= tol2 * z__[i4 - 3] || z__[i4 - 1] <= 
+    9575       42574 :                                 tol2 * sigma) {
+    9576         162 :                             z__[i4 - 1] = -sigma;
+    9577         162 :                             splt = i4 / 4;
+    9578         162 :                             qmax = 0.;
+    9579         162 :                             emin = z__[i4 + 3];
+    9580         162 :                             oldemn = z__[i4 + 4];
+    9581             :                         } else {
+    9582       42482 :                             d__1 = qmax, d__2 = z__[i4 + 1];
+    9583       42482 :                             qmax = (d__1>d__2) ? d__1 : d__2;
+    9584             :                             d__1 = emin, d__2 = z__[i4 - 1];
+    9585       42482 :                             emin = (d__1<d__2) ? d__1 : d__2;
+    9586             :                             d__1 = oldemn, d__2 = z__[i4];
+    9587       42482 :                             oldemn = (d__1<d__2) ? d__1 : d__2;
+    9588             :                         }
+    9589             :                     }
+    9590         522 :                     z__[(n0 << 2) - 1] = emin;
+    9591         522 :                     z__[n0 * 4] = oldemn;
+    9592         522 :                     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      605673 :     i__1 = *n;
+    9611     2423776 :     for (k = 2; k <= i__1; ++k) {
+    9612     1818103 :         z__[k] = z__[(k << 2) - 3];
+    9613             :     }
+    9614             : 
+    9615      605673 :     PLUMED_BLAS_F77_FUNC(dlasrt,DLASRT)("D", n, &z__[1], &iinfo);
+    9616             : 
+    9617             :     e = 0.;
+    9618     3029449 :     for (k = *n; k >= 1; --k) {
+    9619     2423776 :         e += z__[k];
+    9620             :     }
+    9621             : 
+    9622             : 
+    9623      605673 :     z__[(*n << 1) + 1] = trace;
+    9624      605673 :     z__[(*n << 1) + 2] = e;
+    9625      605673 :     z__[(*n << 1) + 3] = (double) iter;
+    9626      605673 :     i__1 = *n;
+    9627      605673 :     z__[(*n << 1) + 4] = (double) ndiv / (double) (i__1 * i__1);
+    9628      605673 :     z__[(*n << 1) + 5] = nfail * 100. / (double) iter;
+    9629             : 
+    9630      605673 :     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    14304426 : 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    14304426 :     int ttype = 0;
+    9664    14304426 :     double dmin1 = 0.;
+    9665    14304426 :     double dmin2 = 0.;
+    9666    14304426 :     double dn = 0.;
+    9667    14304426 :     double dn1 = 0.;
+    9668    14304426 :     double dn2 = 0.;
+    9669    14304426 :     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    14304426 :     --z__;
+    9679             : 
+    9680    14304426 :     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     1817817 : L10:
+    9688             : 
+    9689    16122243 :     if (*n0 < *i0) {
+    9690             :         return;
+    9691             :     }
+    9692    15516317 :     if (*n0 == *i0) {
+    9693         202 :         goto L20;
+    9694             :     }
+    9695    15516115 :     nn = (*n0 << 2) + *pp;
+    9696    15516115 :     if (*n0 == *i0 + 1) {
+    9697      605724 :         goto L40;
+    9698             :     }
+    9699             : 
+    9700    14910391 :     if (z__[nn - 5] > tol2 * (*sigma + z__[nn - 3]) && z__[nn - (*pp << 1) - 
+    9701    13698735 :             4] > tol2 * z__[nn - 7]) {
+    9702    13698735 :         goto L30;
+    9703             :     }
+    9704             : 
+    9705     1211656 : L20:
+    9706             : 
+    9707     1211858 :     z__[(*n0 << 2) - 3] = z__[(*n0 << 2) + *pp - 3] + *sigma;
+    9708     1211858 :     --(*n0);
+    9709     1211858 :     goto L10;
+    9710             : 
+    9711             : L30:
+    9712             : 
+    9713    13698735 :     if (z__[nn - 9] > tol2 * *sigma && z__[nn - (*pp << 1) - 8] > tol2 * z__[
+    9714    13698500 :             nn - 11]) {
+    9715    13698500 :         goto L50;
+    9716             :     }
+    9717             : 
+    9718         235 : L40:
+    9719             : 
+    9720      605959 :     if (z__[nn - 3] > z__[nn - 7]) {
+    9721             :         s = z__[nn - 3];
+    9722       21644 :         z__[nn - 3] = z__[nn - 7];
+    9723       21644 :         z__[nn - 7] = s;
+    9724             :     }
+    9725      605959 :     if (z__[nn - 5] > z__[nn - 3] * tol2) {
+    9726      605957 :         t = (z__[nn - 7] - z__[nn - 3] + z__[nn - 5]) * .5;
+    9727      605957 :         s = z__[nn - 3] * (z__[nn - 5] / t);
+    9728      605957 :         if (s <= t) {
+    9729      588432 :             s = z__[nn - 3] * (z__[nn - 5] / (t * ( std::sqrt(s / t + 1.) + 1.)));
+    9730             :         } else {
+    9731       17525 :             s = z__[nn - 3] * (z__[nn - 5] / (t +  std::sqrt(t) * std::sqrt(t + s)));
+    9732             :         }
+    9733      605957 :         t = z__[nn - 7] + (s + z__[nn - 5]);
+    9734      605957 :         z__[nn - 3] *= z__[nn - 7] / t;
+    9735      605957 :         z__[nn - 7] = t;
+    9736             :     }
+    9737      605959 :     z__[(*n0 << 2) - 7] = z__[nn - 7] + *sigma;
+    9738      605959 :     z__[(*n0 << 2) - 3] = z__[nn - 3] + *sigma;
+    9739      605959 :     *n0 += -2;
+    9740      605959 :     goto L10;
+    9741             : 
+    9742             : L50:
+    9743    13698500 :     if (*pp == 2) {
+    9744        7917 :         *pp = 0;
+    9745             :     }
+    9746             : 
+    9747    13698500 :     if (*dmin__ <= 0. || *n0 < n0in) {
+    9748     1211878 :         if (z__[(*i0 << 2) + *pp - 3] * 1.5 < z__[(*n0 << 2) + *pp - 3]) {
+    9749      320038 :             ipn4 = 4*(*i0 + *n0);
+    9750      320038 :             i__1 = 2*(*i0 + *n0 - 1);
+    9751      649896 :             for (j4 = *i0 << 2; j4 <= i__1; j4 += 4) {
+    9752      329858 :                 temp = z__[j4 - 3];
+    9753      329858 :                 z__[j4 - 3] = z__[ipn4 - j4 - 3];
+    9754      329858 :                 z__[ipn4 - j4 - 3] = temp;
+    9755      329858 :                 temp = z__[j4 - 2];
+    9756      329858 :                 z__[j4 - 2] = z__[ipn4 - j4 - 2];
+    9757      329858 :                 z__[ipn4 - j4 - 2] = temp;
+    9758      329858 :                 temp = z__[j4 - 1];
+    9759      329858 :                 z__[j4 - 1] = z__[ipn4 - j4 - 5];
+    9760      329858 :                 z__[ipn4 - j4 - 5] = temp;
+    9761      329858 :                 temp = z__[j4];
+    9762      329858 :                 z__[j4] = z__[ipn4 - j4 - 4];
+    9763      329858 :                 z__[ipn4 - j4 - 4] = temp;
+    9764             :             }
+    9765      320038 :             if (*n0 - *i0 <= 4) {
+    9766      319941 :                 z__[(*n0 << 2) + *pp - 1] = z__[(*i0 << 2) + *pp - 1];
+    9767      319941 :                 z__[(*n0 << 2) - *pp] = z__[(*i0 << 2) - *pp];
+    9768             :             }
+    9769      320038 :             d__1 = dmin2, d__2 = z__[(*n0 << 2) + *pp - 1];
+    9770      320038 :             dmin2 = ((d__1<d__2) ? d__1 : d__2);
+    9771      320038 :             d__1 = z__[(*n0 << 2) + *pp - 1], d__2 = z__[(*i0 << 2) + *pp - 1]
+    9772      320038 :                     , d__1 = ((d__1<d__2) ? d__1 : d__2), d__2 = z__[(*i0 << 2) + *pp + 3];
+    9773      320038 :             z__[(*n0 << 2) + *pp - 1] = ((d__1<d__2) ? d__1 : d__2);
+    9774      320038 :             d__1 = z__[(*n0 << 2) - *pp], d__2 = z__[(*i0 << 2) - *pp], d__1 =
+    9775      320038 :                      ((d__1<d__2) ? d__1 : d__2), d__2 = z__[(*i0 << 2) - *pp + 4];
+    9776      320038 :             z__[(*n0 << 2) - *pp] = ((d__1<d__2) ? d__1 : d__2);
+    9777      320038 :             d__1 = *qmax;
+    9778      320038 :             d__2 = z__[(*i0 << 2) + *pp - 3];
+    9779      320038 :             d__1 = (d__1>d__2) ? d__1 : d__2;
+    9780      320038 :             d__2 = z__[(*i0 << 2) + *pp + 1];
+    9781      320038 :             *qmax = ((d__1>d__2) ? d__1 : d__2);
+    9782      320038 :             *dmin__ = -0.;
+    9783             :         }
+    9784             :     }
+    9785             : 
+    9786             : 
+    9787    13698500 :     PLUMED_BLAS_F77_FUNC(dlasq4,DLASQ4)(i0, n0, &z__[1], pp, &n0in, dmin__, &dmin1, &dmin2, &dn, &dn1, &
+    9788             :             dn2, &tau, &ttype);
+    9789             : 
+    9790    13698509 : L70:
+    9791             : 
+    9792    13698509 :     PLUMED_BLAS_F77_FUNC(dlasq5,DLASQ5)(i0, n0, &z__[1], pp, &tau, dmin__, &dmin1, &dmin2, &dn, &dn1, &
+    9793             :             dn2, ieee);
+    9794             : 
+    9795    13698509 :     *ndiv += *n0 - *i0 + 2;
+    9796    13698509 :     ++(*iter);
+    9797             : 
+    9798    13698509 :     if (*dmin__ >= 0. && dmin1 > 0.) {
+    9799             : 
+    9800    13698500 :         goto L90;
+    9801             : 
+    9802           9 :     } else if (*dmin__ < 0. && dmin1 > 0. && z__[4*(*n0 - 1) - *pp] < tol *
+    9803          13 :              (*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           9 :     } else if (*dmin__ < 0.) {
+    9809             : 
+    9810           9 :         ++(*nfail);
+    9811           9 :         if (ttype < -22) {
+    9812             : 
+    9813           0 :             tau = 0.;
+    9814           9 :         } else if (dmin1 > 0.) {
+    9815             : 
+    9816           4 :             tau = (tau + *dmin__) * (1. - eps * 2.);
+    9817           4 :             ttype += -11;
+    9818             :         } else {
+    9819             : 
+    9820           5 :             tau *= .25;
+    9821           5 :             ttype += -12;
+    9822             :         }
+    9823           9 :         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    13698500 : L90:
+    9837    13698500 :     if (tau < *sigma) {
+    9838    11882309 :         *desig += tau;
+    9839    11882309 :         t = *sigma + *desig;
+    9840    11882309 :         *desig -= t - *sigma;
+    9841             :     } else {
+    9842     1816191 :         t = *sigma + tau;
+    9843     1816191 :         *desig = *sigma - (t - tau) + *desig;
+    9844             :     }
+    9845    13698500 :     *sigma = t;
+    9846             : 
+    9847    13698500 :     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    13698500 : 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    13698500 :     if (*dmin__ <= 0.) {
+    9885      917935 :         *tau = -(*dmin__);
+    9886      917935 :         *ttype = -1;
+    9887      917935 :         return;
+    9888             :     }
+    9889             : 
+    9890             :     s = 0.0;
+    9891             : 
+    9892    12780565 :     nn = (*n0 << 2) + *pp;
+    9893    12780565 :     if (*n0in == *n0) {
+    9894             : 
+    9895    12486622 :         if ( std::abs(*dmin__ - *dn)<PLUMED_GMX_DOUBLE_EPS*std::abs(*dmin__ + *dn) ||
+    9896    12486622 :          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    12486622 :         } 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    12486622 :             if (*ttype == -6) {
+   10023             :                 g += (1. - g) * .333;
+   10024    12486622 :             } else if (*ttype == -18) {
+   10025             :                 g = .083250000000000005;
+   10026             :             } else {
+   10027             :                 g = .25;
+   10028             :             }
+   10029    12486622 :             s = g * *dmin__;
+   10030    12486622 :             *ttype = -6;
+   10031             :         }
+   10032             : 
+   10033      293943 :     } else if (*n0in == *n0 + 1) {
+   10034             : 
+   10035      293788 :         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      293788 :             s = *dmin1 * .25;
+   10076      293788 :             if (std::abs(*dmin1 - *dn1)<PLUMED_GMX_DOUBLE_EPS*std::abs(*dmin1 + *dn1)) {
+   10077           0 :                 s = *dmin1 * .5;
+   10078             :             }
+   10079      293788 :             *ttype = -9;
+   10080             :         }
+   10081             : 
+   10082         155 :     } else if (*n0in == *n0 + 2) {
+   10083             : 
+   10084         154 :         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         154 :             s = *dmin2 * .25;
+   10122         154 :             *ttype = -11;
+   10123             :         }
+   10124           1 :     } else if (*n0in > *n0 + 2) {
+   10125             : 
+   10126             :         s = 0.;
+   10127           1 :         *ttype = -12;
+   10128             :     }
+   10129             : 
+   10130    12780565 :     *tau = s;
+   10131    12780565 :     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    13698509 : 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    13698509 :     --z__;
+   10167             : 
+   10168    13698509 :     if (*n0 - *i0 - 1 <= 0) {
+   10169             :         return;
+   10170             :     }
+   10171             : 
+   10172    13698509 :     j4 = (*i0 << 2) + *pp - 3;
+   10173    13698509 :     emin = z__[j4 + 4];
+   10174    13698509 :     d__ = z__[j4] - *tau;
+   10175    13698509 :     *dmin__ = d__;
+   10176    13698509 :     *dmin1 = -z__[j4];
+   10177             : 
+   10178    13698509 :     if (*ieee) {
+   10179             : 
+   10180    13698509 :         if (*pp == 0) {
+   10181     7008148 :             i__1 = 4*(*n0 - 3);
+   10182     8350602 :             for (j4 = *i0 << 2; j4 <= i__1; j4 += 4) {
+   10183     1342454 :                 z__[j4 - 2] = d__ + z__[j4 - 1];
+   10184     1342454 :                 temp = z__[j4 + 1] / z__[j4 - 2];
+   10185     1342454 :                 d__ = d__ * temp - *tau;
+   10186     1342454 :                 if(d__<*dmin__)
+   10187      352199 :                   *dmin__ = d__;
+   10188     1342454 :                 z__[j4] = z__[j4 - 1] * temp;
+   10189             :                 d__1 = z__[j4];
+   10190     1342454 :                 if(d__1<emin)
+   10191             :                   emin = d__1;
+   10192             :             }
+   10193             :         } else {
+   10194     6690361 :             i__1 = 4*(*n0 - 3);
+   10195     7602951 :             for (j4 = *i0 << 2; j4 <= i__1; j4 += 4) {
+   10196      912590 :                 z__[j4 - 3] = d__ + z__[j4];
+   10197      912590 :                 temp = z__[j4 + 2] / z__[j4 - 3];
+   10198      912590 :                 d__ = d__ * temp - *tau;
+   10199      912590 :                 if(d__<*dmin__)
+   10200      258200 :                   *dmin__ = d__;
+   10201      912590 :                 z__[j4 - 1] = z__[j4] * temp;
+   10202             :                 d__1 = z__[j4 - 1];
+   10203      912590 :                 if(d__1<emin)
+   10204             :                   emin = d__1;
+   10205             :             }
+   10206             :         }
+   10207             : 
+   10208    13698509 :         *dnm2 = d__;
+   10209    13698509 :         *dmin2 = *dmin__;
+   10210    13698509 :         j4 = 4*(*n0 - 2) - *pp;
+   10211    13698509 :         j4p2 = j4 + (*pp << 1) - 1;
+   10212    13698509 :         z__[j4 - 2] = *dnm2 + z__[j4p2];
+   10213    13698509 :         z__[j4] = z__[j4p2 + 2] * (z__[j4p2] / z__[j4 - 2]);
+   10214    13698509 :         *dnm1 = z__[j4p2 + 2] * (*dnm2 / z__[j4 - 2]) - *tau;
+   10215    13698509 :         if(*dnm1<*dmin__)
+   10216    10893523 :           *dmin__ = *dnm1;
+   10217             : 
+   10218    13698509 :         *dmin1 = *dmin__;
+   10219    13698509 :         j4 += 4;
+   10220    13698509 :         j4p2 = j4 + (*pp << 1) - 1;
+   10221    13698509 :         z__[j4 - 2] = *dnm1 + z__[j4p2];
+   10222    13698509 :         z__[j4] = z__[j4p2 + 2] * (z__[j4p2] / z__[j4 - 2]);
+   10223    13698509 :         *dn = z__[j4p2 + 2] * (*dnm1 / z__[j4 - 2]) - *tau;
+   10224    13698509 :         if(*dn<*dmin__)
+   10225    13082131 :           *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    13698509 :     z__[j4 + 2] = *dn;
+   10291    13698509 :     z__[(*n0 << 2) - *pp] = emin;
+   10292    13698509 :     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      606108 : 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      606108 :     --d__;
+   10717             : 
+   10718      606108 :     *info = 0;
+   10719             :     dir = -1;
+   10720      606108 :     if (*id=='D' || *id=='d') 
+   10721             :         dir = 0;
+   10722         435 :     else if (*id=='I' || *id=='i') 
+   10723             :         dir = 1;
+   10724             :    
+   10725             :     if (dir == -1) {
+   10726           0 :         *info = -1;
+   10727      606108 :     } else if (*n < 0) {
+   10728           0 :         *info = -2;
+   10729             :     }
+   10730      606108 :     if (*info != 0) {
+   10731             :         return;
+   10732             :     }
+   10733      606108 :     if (*n <= 1) {
+   10734             :         return;
+   10735             :     }
+   10736             : 
+   10737             :     stkpnt = 1;
+   10738      605683 :     stack[0] = 1;
+   10739      605683 :     stack[1] = *n;
+   10740      605801 : L10:
+   10741      605801 :     start = stack[(stkpnt << 1) - 2];
+   10742      605801 :     endd = stack[(stkpnt << 1) - 1];
+   10743      605801 :     --stkpnt;
+   10744      605801 :     if (endd - start <= 20 && endd - start > 0) {
+   10745             : 
+   10746             : 
+   10747      605742 :         if (dir == 0) {
+   10748             : 
+   10749             :             i__1 = endd;
+   10750     2423776 :             for (i__ = start + 1; i__ <= i__1; ++i__) {
+   10751             :                 i__2 = start + 1;
+   10752     1818047 :                 for (j = i__; j >= i__2; --j) {
+   10753     1818047 :                     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     1818047 :                         goto L30;
+   10759             :                     }
+   10760             :                 }
+   10761     1818047 : L30:
+   10762             :                 ;
+   10763             :             }
+   10764             : 
+   10765             :         } else {
+   10766             : 
+   10767             :             i__1 = endd;
+   10768          92 :             for (i__ = start + 1; i__ <= i__1; ++i__) {
+   10769             :                 i__2 = start + 1;
+   10770          79 :                 for (j = i__; j >= i__2; --j) {
+   10771          79 :                     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          79 :                         goto L50;
+   10777             :                     }
+   10778             :                 }
+   10779          79 : 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      605801 :     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           9 : 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           9 :     --key;
+   10916           9 :     --d__;
+   10917             : 
+   10918           9 :     *info = 0;
+   10919             :     dir = -1;
+   10920           9 :     if (*id=='D' || *id=='d')
+   10921             :         dir = 0;
+   10922           9 :     else if (*id=='I' || *id=='i')
+   10923             :         dir = 1;
+   10924             :     
+   10925             :     if (dir == -1) {
+   10926           0 :         *info = -1;
+   10927           9 :     } else if (*n < 0) {
+   10928           0 :         *info = -2;
+   10929             :     }
+   10930           9 :     if (*info != 0) {
+   10931             :         return;
+   10932             :     }
+   10933             : 
+   10934           9 :     if (*n <= 1) {
+   10935             :         return;
+   10936             :     }
+   10937             : 
+   10938             :     stkpnt = 1;
+   10939           9 :     stack[0] = 1;
+   10940           9 :     stack[1] = *n;
+   10941           9 : L10:
+   10942           9 :     start = stack[(stkpnt << 1) - 2];
+   10943           9 :     endd = stack[(stkpnt << 1) - 1];
+   10944           9 :     --stkpnt;
+   10945           9 :     if (endd - start > 0) {
+   10946             : 
+   10947           9 :         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         524 :             for (i__ = start + 1; i__ <= i__1; ++i__) {
+   10970             :                 i__2 = start + 1;
+   10971        9047 :                 for (j = i__; j >= i__2; --j) {
+   10972        8989 :                     if (d__[j] < d__[j - 1]) {
+   10973             :                         dmnmx = d__[j];
+   10974        8532 :                         d__[j] = d__[j - 1];
+   10975        8532 :                         d__[j - 1] = dmnmx;
+   10976        8532 :                         tmpkey = key[j];
+   10977        8532 :                         key[j] = key[j - 1];
+   10978        8532 :                         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           9 :     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      619030 : 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      619030 :     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      619030 :     a_dim1 = *lda;
+   12074      619030 :     a_offset = 1 + a_dim1;
+   12075      619030 :     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      619030 :     *info = 0;
+   12084      619030 :     left = (*side=='L' || *side=='l');
+   12085      619030 :     notran = (*trans=='N' || *trans=='n');
+   12086             : 
+   12087      619030 :     if (left) {
+   12088      619030 :         nq = *m;
+   12089             :     } else {
+   12090           0 :         nq = *n;
+   12091             :     }
+   12092             :     if (*info != 0) {
+   12093             :         return;
+   12094             :     }
+   12095             : 
+   12096      619030 :     if (*m == 0 || *n == 0 || *k == 0) {
+   12097             :         return;
+   12098             :     }
+   12099             : 
+   12100      619030 :     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      619030 :     if (left) {
+   12111      619030 :         ni = *n;
+   12112             :     } else {
+   12113           0 :         mi = *m;
+   12114             :     }
+   12115             : 
+   12116             :     i__1 = i2;
+   12117             :     i__2 = i3;
+   12118     2449611 :     for (i__ = i1; i__2 < 0 ? i__ >= i__1 : i__ <= i__1; i__ += i__2) {
+   12119     1830581 :         if (left) {
+   12120             : 
+   12121     1830581 :             mi = *m - *k + i__;
+   12122             :         } else {
+   12123             : 
+   12124           0 :             ni = *n - *k + i__;
+   12125             :         }
+   12126             : 
+   12127     1830581 :         aii = a[nq - *k + i__ + i__ * a_dim1];
+   12128     1830581 :         a[nq - *k + i__ + i__ * a_dim1] = 1.;
+   12129     1830581 :         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     1830581 :         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      619040 : 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      619040 :     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      619040 :     a_dim1 = *lda;
+   12607      619040 :     a_offset = 1 + a_dim1;
+   12608      619040 :     a -= a_offset;
+   12609             :     --tau;
+   12610             :     c_dim1 = *ldc;
+   12611             :     c_offset = 1 + c_dim1;
+   12612             :     c__ -= c_offset;
+   12613             :     --work;
+   12614             : 
+   12615      619040 :     *info = 0;
+   12616      619040 :     left = (*side=='L' || *side=='l');
+   12617      619040 :     notran = (*trans=='N' || *trans=='n');
+   12618      619040 :     lquery = *lwork == -1;
+   12619             : 
+   12620      619040 :     if (left) {
+   12621      619040 :         nq = *m;
+   12622      619040 :         nw = *n;
+   12623             :     } else {
+   12624           0 :         nq = *n;
+   12625           0 :         nw = *m;
+   12626             :     }
+   12627             : 
+   12628             :     nb = DORMQL_BLOCKSIZE;
+   12629      619040 :     lwkopt = nw * nb;
+   12630      619040 :     work[1] = (double) lwkopt;
+   12631             :     
+   12632      619040 :     if (*info != 0) {
+   12633             :         return;
+   12634      619040 :     } else if (lquery) {
+   12635             :         return;
+   12636             :     }
+   12637             : 
+   12638      619040 :     if (*m == 0 || *n == 0 || *k == 0) {
+   12639           0 :         work[1] = 1.;
+   12640           0 :         return;
+   12641             :     }
+   12642             : 
+   12643             :     nbmin = 2;
+   12644      619040 :     ldwork = nw;
+   12645      619040 :     if (nb > 1 && nb < *k) {
+   12646             :         iws = nw * nb;
+   12647          10 :         if (*lwork < iws) {
+   12648           0 :             nb = *lwork / ldwork;
+   12649             :             nbmin = DORMQL_MINBLOCKSIZE;
+   12650             :         }
+   12651             :     }
+   12652             : 
+   12653      619040 :     if (nb < nbmin || nb >= *k) {
+   12654             : 
+   12655      619030 :         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          10 :         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          10 :         if (left) {
+   12670          10 :             ni = *n;
+   12671             :         } else {
+   12672           0 :             mi = *m;
+   12673             :         }
+   12674             : 
+   12675             :         i__1 = i2;
+   12676             :         i__2 = i3;
+   12677          59 :         for (i__ = i1; i__2 < 0 ? i__ >= i__1 : i__ <= i__1; i__ += i__2) {
+   12678          49 :             i__4 = nb, i__5 = *k - i__ + 1;
+   12679          49 :             ib = (i__4<i__5) ? i__4 : i__5;
+   12680             : 
+   12681          49 :             i__4 = nq - *k + i__ + ib - 1;
+   12682          49 :             PLUMED_BLAS_F77_FUNC(dlarft,DLARFT)("Backward", "Columnwise", &i__4, &ib, &a[i__ * a_dim1 + 1]
+   12683          49 :                     , lda, &tau[i__], t, &c__65);
+   12684          49 :             if (left) {
+   12685             : 
+   12686          49 :                 mi = *m - *k + i__ + ib - 1;
+   12687             :             } else {
+   12688             : 
+   12689           0 :                 ni = *n - *k + i__ + ib - 1;
+   12690             :             }
+   12691             : 
+   12692          49 :             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      619040 :     work[1] = (double) lwkopt;
+   12698      619040 :     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      619040 : 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      619040 :     a_dim1 = *lda;
+   12877      619040 :     a_offset = 1 + a_dim1;
+   12878      619040 :     a -= a_offset;
+   12879             :     --tau;
+   12880      619040 :     c_dim1 = *ldc;
+   12881      619040 :     c_offset = 1 + c_dim1;
+   12882      619040 :     c__ -= c_offset;
+   12883             :     --work;
+   12884             : 
+   12885      619040 :     *info = 0;
+   12886      619040 :     left = (*side=='L' || *side=='l');
+   12887      619040 :     upper = (*uplo=='U' || *uplo=='u');
+   12888      619040 :     lquery = *lwork == -1;
+   12889             : 
+   12890      619040 :     if (left) {
+   12891      619040 :         nq = *m;
+   12892      619040 :         nw = *n;
+   12893             :     } else {
+   12894           0 :         nq = *n;
+   12895           0 :         nw = *m;
+   12896             :     }
+   12897             : 
+   12898             : 
+   12899             :     nb = DORMQL_BLOCKSIZE;
+   12900      619040 :     lwkopt = nw * nb;
+   12901      619040 :     work[1] = (double) lwkopt;
+   12902             :     
+   12903      619040 :     if (*info != 0) {
+   12904             :         i__2 = -(*info);
+   12905             :         return;
+   12906      619040 :     } else if (lquery) {
+   12907             :         return;
+   12908             :     }
+   12909             : 
+   12910      619040 :     if (*m == 0 || *n == 0 || nq == 1) {
+   12911           0 :         work[1] = 1.;
+   12912           0 :         return;
+   12913             :     }
+   12914             : 
+   12915      619040 :     if (left) {
+   12916      619040 :         mi = *m - 1;
+   12917      619040 :         ni = *n;
+   12918             :     } else {
+   12919           0 :         mi = *m;
+   12920           0 :         ni = *n - 1;
+   12921             :     }
+   12922             : 
+   12923      619040 :     if (upper) {
+   12924      619040 :         i__2 = nq - 1;
+   12925      619040 :         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      619040 :     work[1] = (double) lwkopt;
+   12940      619040 :     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      619040 : 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      619040 :     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      619040 :     --w;
+   13492      619040 :     z_dim1 = *ldz;
+   13493      619040 :     z_offset = 1 + z_dim1;
+   13494      619040 :     z__ -= z_offset;
+   13495      619040 :     --isuppz;
+   13496      619040 :     --work;
+   13497      619040 :     --iwork;
+   13498             : 
+   13499      619040 :     wantz = (*jobz=='V' || *jobz=='v');
+   13500      619040 :     alleig = (*range=='A' || *range=='a');
+   13501      619040 :     valeig = (*range=='V' || *range=='v');
+   13502      619040 :     indeig = (*range=='I' || *range=='i');
+   13503             : 
+   13504      619040 :     lquery = *lwork == -1 || *liwork == -1;
+   13505      619040 :     lwmin = *n * 17;
+   13506      619040 :     liwmin = *n * 10;
+   13507             : 
+   13508      619040 :     *info = 0;
+   13509      619040 :     if (! (wantz || (*jobz=='N' || *jobz=='n'))) {
+   13510           0 :         *info = -1;
+   13511      619040 :     } else if (! (alleig || valeig || indeig)) {
+   13512           0 :         *info = -2;
+   13513      619040 :     } else if (*n < 0) {
+   13514           0 :         *info = -3;
+   13515      619040 :     } else if (valeig && *n > 0 && *vu <= *vl) {
+   13516           0 :         *info = -7;
+   13517      619040 :     } else if (indeig && (*il < 1 || *il > *n)) {
+   13518           0 :         *info = -8;
+   13519      619040 :     } else if (indeig && (*iu < *il || *iu > *n)) {
+   13520           0 :         *info = -9;
+   13521      619040 :     } else if (*ldz < 1 || (wantz && *ldz < *n)) {
+   13522           0 :         *info = -14;
+   13523      619040 :     } else if (*lwork < lwmin && ! lquery) {
+   13524           0 :         *info = -17;
+   13525      619040 :     } else if (*liwork < liwmin && ! lquery) {
+   13526           0 :         *info = -19;
+   13527             :     }
+   13528      619040 :     if (*info == 0) {
+   13529      619040 :         work[1] = (double) lwmin;
+   13530      619040 :         iwork[1] = liwmin;
+   13531             :     }
+   13532             : 
+   13533      619040 :     if (*info != 0) {
+   13534             :         i__1 = -(*info);
+   13535             :         return;
+   13536      619040 :     } else if (lquery) {
+   13537             :         return;
+   13538             :     }
+   13539             : 
+   13540      619040 :     *m = 0;
+   13541      619040 :     if (*n == 0) {
+   13542             :         return;
+   13543             :     }
+   13544             : 
+   13545      619040 :     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      619040 :     d__1 =  std::sqrt(bignum), d__2 = 1. / std::sqrt(sqrt(safmin));
+   13568             :     rmax = (d__1<d__2) ? d__1 : d__2;
+   13569      619040 :     scale = 1.;
+   13570      619040 :     tnrm = PLUMED_BLAS_F77_FUNC(dlanst,DLANST)("M", n, &d__[1], &e[1]);
+   13571      619040 :     if (tnrm > 0. && tnrm < rmin) {
+   13572           0 :         scale = rmin / tnrm;
+   13573      619040 :     } else if (tnrm > rmax) {
+   13574           0 :         scale = rmax / tnrm;
+   13575             :     }
+   13576      619040 :     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      619040 :     indwrk = (*n << 1) + 1;
+   13584             : 
+   13585             :     iinspl = 1;
+   13586      619040 :     iindbl = *n + 1;
+   13587             :     iindw = (*n << 1) + 1;
+   13588      619040 :     iindwk = *n * 3 + 1;
+   13589             : 
+   13590      619040 :     thresh = eps * tnrm;
+   13591      619040 :     PLUMED_BLAS_F77_FUNC(dlarrex,DLARREX)(range, n, vl, vu, il, iu, &d__[1], &e[1], &thresh, &nsplit, &
+   13592      619040 :             iwork[iinspl], m, &w[1], &iwork[iindbl], &iwork[iindw], &work[
+   13593      619040 :             indgrs], &work[indwrk], &iwork[iindwk], &iinfo);
+   13594             :     
+   13595      619040 :     if (iinfo != 0) {
+   13596           0 :         *info = 1;
+   13597           0 :         return;
+   13598             :     }
+   13599             : 
+   13600      619040 :     if (wantz) {
+   13601      619040 :         d__1 = *abstol, d__2 = (double) (*n) * eps;
+   13602      619040 :         tol = (d__1>d__2) ? d__1 : d__2;
+   13603      619040 :         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      619040 :         if (iinfo != 0) {
+   13607           0 :             *info = 2;
+   13608           0 :             return;
+   13609             :         }
+   13610             :     }
+   13611             : 
+   13612      619040 :     i__1 = *m;
+   13613     1431033 :     for (j = 1; j <= i__1; ++j) {
+   13614      811993 :         itmp = iwork[iindbl + j - 1];
+   13615      811993 :         w[j] += e[iwork[iinspl + itmp - 1]];
+   13616             :     } 
+   13617             : 
+   13618      619040 :     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      619040 :     if (nsplit > 1) {
+   13623          36 :         i__1 = *m - 1;
+   13624         626 :         for (j = 1; j <= i__1; ++j) {
+   13625             :             i__ = 0;
+   13626         590 :             tmp = w[j];
+   13627         590 :             i__2 = *m;
+   13628       21422 :             for (jj = j + 1; jj <= i__2; ++jj) {
+   13629       20832 :                 if (w[jj] < tmp) {
+   13630             :                     i__ = jj;
+   13631             :                     tmp = w[jj];
+   13632             :                 }
+   13633             :             }
+   13634         590 :             if (i__ != 0) {
+   13635         358 :                 w[i__] = w[j];
+   13636         358 :                 w[j] = tmp;
+   13637         358 :                 if (wantz) {
+   13638         358 :                     PLUMED_BLAS_F77_FUNC(dswap,DSWAP)(n, &z__[i__ * z_dim1 + 1], &c__1, &z__[j * z_dim1 
+   13639         358 :                             + 1], &c__1);
+   13640         358 :                     itmp = isuppz[(i__ << 1) - 1];
+   13641         358 :                     isuppz[(i__ << 1) - 1] = isuppz[(j << 1) - 1];
+   13642         358 :                     isuppz[(j << 1) - 1] = itmp;
+   13643         358 :                     itmp = isuppz[i__ * 2];
+   13644         358 :                     isuppz[i__ * 2] = isuppz[j * 2];
+   13645         358 :                     isuppz[j * 2] = itmp;
+   13646             :                 }
+   13647             :             }
+   13648             :         }
+   13649             :     }
+   13650             : 
+   13651      619040 :     work[1] = (double) lwmin;
+   13652      619040 :     iwork[1] = liwmin;
+   13653      619040 :     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      633679 : 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      633679 :     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      633679 :     a_dim1 = *lda;
+   14769      633679 :     a_offset = 1 + a_dim1;
+   14770      633679 :     a -= a_offset;
+   14771      633679 :     --w;
+   14772      633679 :     z_dim1 = *ldz;
+   14773      633679 :     z_offset = 1 + z_dim1;
+   14774      633679 :     z__ -= z_offset;
+   14775             :     --isuppz;
+   14776      633679 :     --work;
+   14777      633679 :     --iwork;
+   14778             : 
+   14779      633679 :     lower = (*uplo=='L' || *uplo=='l');
+   14780      633679 :     wantz = (*jobz=='V' || *jobz=='v');
+   14781      633679 :     alleig = (*range=='A' || *range=='a');
+   14782      633679 :     valeig = (*range=='V' || *range=='v');
+   14783      633679 :     indeig = (*range=='I' || *range=='i');
+   14784             : 
+   14785             :     indibl = 0;
+   14786      633679 :     lquery = *lwork == -1 || *liwork == -1;
+   14787             : 
+   14788             :     i__1 = 1;
+   14789      633679 :     i__2 = *n * 26;
+   14790             : 
+   14791      633679 :     if(*n>0) 
+   14792             :       lwmin = *n * 26;
+   14793             :     else
+   14794             :       lwmin = 1;
+   14795             : 
+   14796      633679 :     if(*n>0) 
+   14797      633679 :       liwmin = *n * 10;
+   14798             :     else
+   14799             :       liwmin = 1;
+   14800             : 
+   14801      633679 :     *info = 0;
+   14802      633679 :     if (! (wantz || (*jobz=='N' || *jobz=='n'))) {
+   14803           0 :         *info = -1;
+   14804      633679 :     } else if (! (alleig || valeig || indeig)) {
+   14805           0 :         *info = -2;
+   14806      633679 :     } else if (! (lower || (*uplo=='U' || *uplo=='u'))) {
+   14807           0 :         *info = -3;
+   14808      633679 :     } else if (*n < 0) {
+   14809           0 :         *info = -4;
+   14810      633679 :     } else if (*lda < ((*n>1) ? *n : 1) ) {
+   14811           0 :         *info = -6;
+   14812             :     } else {
+   14813      633679 :         if (valeig) {
+   14814           0 :             if (*n > 0 && *vu <= *vl) {
+   14815           0 :                 *info = -8;
+   14816             :             }
+   14817      633679 :         } else if (indeig) {
+   14818      574442 :           if (*il < 1 || *il > ((*n>1) ? *n : 1)) {
+   14819           0 :                 *info = -9;
+   14820      574442 :             } else if (*iu < ((*n<*il) ? *n : *il) || *iu > *n) {
+   14821           0 :                 *info = -10;
+   14822             :             }
+   14823             :         }
+   14824             :     }
+   14825      633679 :     if (*info == 0) {
+   14826      633679 :       if (*ldz < 1 || (wantz && *ldz < *n)) {
+   14827           0 :             *info = -15;
+   14828      633679 :         } else if (*lwork < lwmin && ! lquery) {
+   14829           0 :             *info = -18;
+   14830      633679 :         } else if (*liwork < liwmin && ! lquery) {
+   14831           0 :             *info = -20;
+   14832             :         }
+   14833             :     }
+   14834             : 
+   14835      633679 :     if (*info == 0) {
+   14836             :       nb = 32;
+   14837             :       /* Computing MAX */
+   14838      633679 :       i__1 = (nb + 1) * *n;
+   14839             :       lwkopt = (i__1>lwmin) ? i__1 : lwmin;
+   14840      633679 :       work[1] = (double) lwkopt;
+   14841      633679 :       iwork[1] = liwmin;
+   14842             :     } else 
+   14843             :       return;
+   14844             : 
+   14845      633679 :     if (lquery) 
+   14846             :         return;
+   14847             :     
+   14848      619622 :     *m = 0;
+   14849      619622 :     if (*n == 0) {
+   14850           0 :         work[1] = 1.;
+   14851           0 :         return;
+   14852             :     }
+   14853             : 
+   14854      619622 :     if (*n == 1) {
+   14855         582 :         work[1] = 7.;
+   14856         582 :         if (alleig || indeig) {
+   14857         582 :             *m = 1;
+   14858         582 :             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         582 :         if (wantz) {
+   14866         582 :             z__[z_dim1 + 1] = 1.;
+   14867             :         }
+   14868         582 :         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      619040 :     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      619040 :     anrm = PLUMED_BLAS_F77_FUNC(dlansy,DLANSY)("M", uplo, n, &a[a_offset], lda, &work[1]);
+   14883      619040 :     if (anrm > 0. && anrm < rmin) {
+   14884             :         iscale = 1;
+   14885           0 :         sigma = rmin / anrm;
+   14886      619040 :     } 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      619040 :     inde = indtau + *n;
+   14908      619040 :     indd = inde + *n;
+   14909      619040 :     indee = indd + *n;
+   14910      619040 :     inddd = indee + *n;
+   14911      619040 :     indifl = inddd + *n;
+   14912      619040 :     indwk = indifl + *n;
+   14913      619040 :     llwork = *lwork - indwk + 1;
+   14914      619040 :     PLUMED_BLAS_F77_FUNC(dsytrd,DSYTRD)(uplo, n, &a[a_offset], lda, &work[indd], &work[inde], &work[
+   14915      619040 :             indtau], &work[indwk], &llwork, &iinfo);
+   14916             : 
+   14917      619040 :     i__1 = *n - 1;
+   14918      619040 :     PLUMED_BLAS_F77_FUNC(dcopy,DCOPY)(&i__1, &work[inde], &c__1, &work[indee], &c__1);
+   14919      619040 :     PLUMED_BLAS_F77_FUNC(dcopy,DCOPY)(n, &work[indd], &c__1, &work[inddd], &c__1);
+   14920             : 
+   14921      619040 :     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      619040 :     if (wantz && *info == 0) {
+   14925             :       indwkn = inde;
+   14926      619040 :       llwrkn = *lwork - indwkn + 1;
+   14927      619040 :       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      619040 :     if (*info != 0) 
+   14932             :       return;
+   14933             : 
+   14934      619040 :     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      619040 :     if (wantz) {
+   14945      619040 :         i__1 = *m - 1;
+   14946             :         
+   14947      811993 :         for (j = 1; j <= i__1; ++j) {
+   14948             :             i__ = 0;
+   14949      192953 :             tmp1 = w[j];
+   14950      192953 :             i__2 = *m;
+   14951      747723 :             for (jj = j + 1; jj <= i__2; ++jj) {
+   14952      554770 :                 if (w[jj] < tmp1) {
+   14953             :                     i__ = jj;
+   14954             :                     tmp1 = w[jj];
+   14955             :                 }
+   14956             :             }
+   14957             : 
+   14958      192953 :             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      619040 :     work[1] = (double) lwkopt;
+   14971      619040 :     iwork[1] = liwmin;
+   14972      619040 :     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      619040 : 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      619040 :   const char ch=std::toupper(*uplo);
+   15003             : 
+   15004      619040 :   zero = 0.0;
+   15005      619040 :   minusone = -1.0;
+   15006             : 
+   15007      619040 :   if(*n<=0)
+   15008             :     return;
+   15009             : 
+   15010      619040 :   if(ch=='U') {
+   15011     2450464 :     for(i=*n-1;i>=1;i--) {
+   15012             : 
+   15013     1831424 :       ti1 = 1;
+   15014     1831424 :       PLUMED_BLAS_F77_FUNC(dlarfg,DLARFG)(&i,&(a[i*(*lda)+(i-1)]),&(a[i*(*lda)+0]),&ti1,&taui);
+   15015     1831424 :       e[i-1] = a[i*(*lda) + (i-1)];
+   15016     1831424 :       if(std::abs(taui)>PLUMED_GMX_DOUBLE_MIN) {
+   15017     1212317 :         a[i*(*lda)+(i-1)] = 1.0;
+   15018             :       
+   15019     1212317 :         ti1 = 1;
+   15020     1212317 :         PLUMED_BLAS_F77_FUNC(dsymv,DSYMV)("U",&i,&taui,a,lda,&(a[i*(*lda)+0]),&ti1,&zero,tau,&ti1);
+   15021             : 
+   15022     1212317 :         tmp = PLUMED_BLAS_F77_FUNC(ddot,DDOT)(&i,tau,&ti1,&(a[i*(*lda)+0]),&ti1);
+   15023             : 
+   15024     1212317 :         alpha = -0.5*taui*tmp;
+   15025             : 
+   15026     1212317 :         PLUMED_BLAS_F77_FUNC(daxpy,DAXPY)(&i,&alpha,&(a[i*(*lda)+0]),&ti1,tau,&ti1);
+   15027             : 
+   15028     1212317 :         PLUMED_BLAS_F77_FUNC(dsyr2,DSYR2)("U",&i,&minusone,&(a[i*(*lda)+0]),&ti1,tau,&ti1,a,lda);
+   15029             : 
+   15030     1212317 :         a[i*(*lda)+(i-1)] = e[i-1]; 
+   15031             : 
+   15032             :       }
+   15033     1831424 :       d[i] = a[i*(*lda)+i];
+   15034     1831424 :       tau[i-1] = taui;
+   15035             :     }
+   15036      619040 :     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      619040 : 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      619040 :     double c_b22 = -1.;
+   15103      619040 :     double c_b23 = 1.;
+   15104             : 
+   15105             : 
+   15106             :     /* Parameter adjustments */
+   15107      619040 :     a_dim1 = *lda;
+   15108      619040 :     a_offset = 1 + a_dim1;
+   15109      619040 :     a -= a_offset;
+   15110      619040 :     --d__;
+   15111      619040 :     --e;
+   15112      619040 :     --tau;
+   15113             :     --work;
+   15114             : 
+   15115             :     /* Function Body */
+   15116      619040 :     *info = 0;
+   15117      619040 :     upper = (*uplo=='U' || *uplo=='u');
+   15118      619040 :     lquery = (*lwork == -1);
+   15119             : 
+   15120      619040 :     if (! upper && ! (*uplo=='L' || *uplo=='l')) {
+   15121           0 :         *info = -1;
+   15122      619040 :     } else if (*n < 0) {
+   15123           0 :         *info = -2;
+   15124      619040 :     } else if (*lda < ((1>*n) ? 1 : *n)) {
+   15125           0 :         *info = -4;
+   15126      619040 :     } else if (*lwork < 1 && ! lquery) {
+   15127           0 :         *info = -9;
+   15128             :     }
+   15129             : 
+   15130      619040 :     if (*info == 0) {
+   15131             : 
+   15132      619040 :       nb = DSYTRD_BLOCKSIZE;
+   15133      619040 :       lwkopt = *n * nb;
+   15134      619040 :       work[1] = (double) lwkopt;
+   15135             :     } else
+   15136             :       return;
+   15137             : 
+   15138      619040 :     if (lquery) 
+   15139             :       return;
+   15140             :   
+   15141      619040 :     if (*n == 0) {
+   15142           0 :         work[1] = 1.;
+   15143           0 :         return;
+   15144             :     }
+   15145             : 
+   15146             :     nx = *n;
+   15147      619040 :     if (nb > 1 && nb < *n) {
+   15148             : 
+   15149             :         nx = DSYTRD_CROSSOVER;
+   15150          10 :         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      619030 :         nb = 1;
+   15168             :     }
+   15169             : 
+   15170      619040 :     if (upper) {
+   15171             : 
+   15172      619040 :         kk = *n - (*n - nx + nb - 1) / nb * nb;
+   15173      619040 :         i__1 = kk + 1;
+   15174             :         i__2 = -nb;
+   15175      619059 :         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      619040 :         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      619040 :     work[1] = (double) lwkopt;
+   15229      619040 :     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       16511 : 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       16511 :     int c__1 = 1;
+   15258             : 
+   15259             : 
+   15260       16511 :     a_dim1 = *lda;
+   15261       16511 :     a_offset = 1 + a_dim1;
+   15262       16511 :     a -= a_offset;
+   15263             : 
+   15264       16511 :     *info = 0;
+   15265       16511 :     upper = (*uplo=='U' || *uplo=='u');
+   15266       16511 :     nounit = (*diag=='N' || *diag=='n');
+   15267             : 
+   15268             :     if (*info != 0) {
+   15269             :         i__1 = -(*info);
+   15270             :         return;
+   15271             :     }
+   15272             : 
+   15273       16511 :     if (upper) {
+   15274             : 
+   15275       16511 :         i__1 = *n;
+   15276       49536 :         for (j = 1; j <= i__1; ++j) {
+   15277       33025 :             if (nounit) {
+   15278       33025 :                 a[j + j * a_dim1] = 1. / a[j + j * a_dim1];
+   15279       33025 :                 ajj = -a[j + j * a_dim1];
+   15280             :             } else {
+   15281           0 :                 ajj = -1.;
+   15282             :             }
+   15283             : 
+   15284       33025 :             i__2 = j - 1;
+   15285       33025 :             PLUMED_BLAS_F77_FUNC(dtrmv,DTRMV)("Upper", "No transpose", diag, &i__2, &a[a_offset], lda, &
+   15286       33025 :                     a[j * a_dim1 + 1], &c__1);
+   15287       33025 :             i__2 = j - 1;
+   15288       33025 :             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       16511 : 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       16511 :     double c_b18 = 1.;
+   15335       16511 :     double c_b22 = -1.;
+   15336             : 
+   15337             :     int upper;
+   15338             :     int nounit;
+   15339             : 
+   15340       16511 :     a_dim1 = *lda;
+   15341       16511 :     a_offset = 1 + a_dim1;
+   15342       16511 :     a -= a_offset;
+   15343             : 
+   15344       16511 :     *info = 0;
+   15345       16511 :     upper = (*uplo=='U' || *uplo=='u');
+   15346       16511 :     nounit = (*diag=='N' || *diag=='n');
+   15347             : 
+   15348             :     if (*info != 0) {
+   15349             :         i__1 = -(*info);
+   15350             :         return;
+   15351             :     }
+   15352             : 
+   15353       16511 :     if (*n == 0) {
+   15354             :         return;
+   15355             :     }
+   15356             : 
+   15357       16511 :     if (nounit) {
+   15358       16511 :         i__1 = *n;
+   15359       49536 :         for (*info = 1; *info <= i__1; ++(*info)) {
+   15360       33025 :             if (std::abs(a[*info + *info * a_dim1])<PLUMED_GMX_DOUBLE_MIN) {
+   15361             :                 return;
+   15362             :             }
+   15363             :         }
+   15364       16511 :         *info = 0;
+   15365             :     }
+   15366             : 
+   15367             :     nb = DTRTRI_BLOCKSIZE;
+   15368       16511 :     if (nb <= 1 || nb >= *n) {
+   15369             : 
+   15370       16511 :         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           9 : 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           9 :     --key;
+   15439           9 :     --d__;
+   15440             : 
+   15441           9 :     *info = 0;
+   15442             :     dir = -1;
+   15443           9 :     if (*id=='D' || *id=='d') 
+   15444             :         dir = 0;
+   15445           9 :     else if (*id=='I' || *id=='i') 
+   15446             :         dir = 1;
+   15447             :     
+   15448             :     if (dir == -1) {
+   15449           0 :         *info = -1;
+   15450           9 :     } else if (*n < 0) {
+   15451           0 :         *info = -2;
+   15452             :     }
+   15453           9 :     if (*info != 0) {
+   15454             :         return;
+   15455             :     }
+   15456             : 
+   15457           9 :     if (*n <= 1) {
+   15458             :         return;
+   15459             :     }
+   15460             : 
+   15461             :     stkpnt = 1;
+   15462           7 :     stack[0] = 1;
+   15463           7 :     stack[1] = *n;
+   15464           7 : L10:
+   15465           7 :     start = stack[(stkpnt << 1) - 2];
+   15466           7 :     endd = stack[(stkpnt << 1) - 1];
+   15467           7 :     --stkpnt;
+   15468           7 :     if (endd - start > 0) {
+   15469             : 
+   15470           7 :         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         516 :             for (i__ = start + 1; i__ <= i__1; ++i__) {
+   15495             :                 i__2 = start + 1;
+   15496        9039 :                 for (j = i__; j >= i__2; --j) {
+   15497        8981 :                     if (d__[j] < d__[j - 1]) {
+   15498             :                         dmnmx = d__[j];
+   15499        8530 :                         d__[j] = d__[j - 1];
+   15500        8530 :                         d__[j - 1] = dmnmx;
+   15501        8530 :                         tmpkey = key[j];
+   15502        8530 :                         key[j] = key[j - 1];
+   15503        8530 :                         key[j - 1] = tmpkey;
+   15504             :                     } else {
+   15505         451 :                         goto L50;
+   15506             :                     }
+   15507             :                 }
+   15508         509 : 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           7 :     if (stkpnt > 0) {
+   15619           0 :         goto L10;
+   15620             :     }
+   15621             : 
+   15622             : 
+   15623             :     return;
+   15624             : }
+   15625             : }
+   15626             : }
+   15627             : #include <cctype>
+   15628             : #include <cmath>
+   15629             : #include "blas/blas.h"
+   15630             : #include "lapack.h"
+   15631             : #include "lapack_limits.h"
+   15632             : 
+   15633             : #include "real.h"
+   15634             : 
+   15635             : #include "blas/blas.h"
+   15636             : namespace PLMD{
+   15637             : namespace lapack{
+   15638             : using namespace blas;
+   15639             : void
+   15640           0 : PLUMED_BLAS_F77_FUNC(sbdsdc,SBDSDC)(const char *uplo, 
+   15641             :         const char *compq, 
+   15642             :         int *n,
+   15643             :         float *d__, 
+   15644             :         float *e, 
+   15645             :         float *u, 
+   15646             :         int *ldu,
+   15647             :         float *vt, 
+   15648             :         int *ldvt,
+   15649             :         float *q,
+   15650             :         int *iq,
+   15651             :         float *work, 
+   15652             :         int *iwork, 
+   15653             :         int *info)
+   15654             : {
+   15655             :     int u_dim1, u_offset, vt_dim1, vt_offset, i__1, i__2;
+   15656             :     int i__, j, k;
+   15657             :     float p, r__;
+   15658             :     int z__, ic, ii, kk;
+   15659             :     float cs;
+   15660             :     int is, iu;
+   15661             :     float sn;
+   15662             :     int nm1;
+   15663             :     float eps;
+   15664             :     int ivt, difl, difr, ierr, perm, mlvl, sqre;
+   15665             :     int poles, iuplo, nsize, start;
+   15666             :     int givcol;
+   15667             :     int icompq;
+   15668             :     float orgnrm;
+   15669             :     int givnum, givptr, qstart, smlsiz, wstart, smlszp;
+   15670           0 :     float zero = 0.0;
+   15671           0 :     float one = 1.0;
+   15672           0 :     int c_0 = 0;
+   15673           0 :     int c_1 = 1;
+   15674             : 
+   15675           0 :     --d__;
+   15676           0 :     --e;
+   15677           0 :     u_dim1 = *ldu;
+   15678           0 :     u_offset = 1 + u_dim1;
+   15679           0 :     u -= u_offset;
+   15680           0 :     vt_dim1 = *ldvt;
+   15681           0 :     vt_offset = 1 + vt_dim1;
+   15682           0 :     vt -= vt_offset;
+   15683           0 :     --q;
+   15684           0 :     --iq;
+   15685           0 :     --work;
+   15686             :     --iwork;
+   15687             : 
+   15688             :     k = iu = z__ = ic = is = ivt = difl = difr = perm = 0;
+   15689             :     poles = givnum = givptr = givcol = 0;
+   15690             :     
+   15691           0 :     smlsiz = DBDSDC_SMALLSIZE;
+   15692           0 :     *info = 0;
+   15693             : 
+   15694           0 :     iuplo = (*uplo=='U' || *uplo=='u') ? 1 : 2;
+   15695             : 
+   15696           0 :     switch(*compq) {
+   15697           0 :     case 'n':
+   15698             :     case 'N':
+   15699           0 :       icompq = 0;
+   15700           0 :       break;
+   15701           0 :     case 'p':
+   15702             :     case 'P':
+   15703           0 :       icompq = 1;
+   15704           0 :       break;
+   15705           0 :     case 'i':
+   15706             :     case 'I':
+   15707           0 :       icompq = 2;
+   15708           0 :       break;
+   15709             :     default:
+   15710             :       return;
+   15711             :     }
+   15712             : 
+   15713           0 :     if (*n <= 0) 
+   15714             :         return;
+   15715             :     
+   15716           0 :     if (*n == 1) {
+   15717           0 :         if (icompq == 1) {
+   15718           0 :           q[1] = (d__[1]>0) ? 1.0 : -1.0;
+   15719           0 :           q[smlsiz * *n + 1] = 1.;
+   15720           0 :         } else if (icompq == 2) {
+   15721           0 :           u[u_dim1 + 1] = (d__[1]>0) ? 1.0 : -1.0;
+   15722           0 :           vt[vt_dim1 + 1] = 1.;
+   15723             :         }
+   15724           0 :         d__[1] = std::abs(d__[1]);
+   15725           0 :         return;
+   15726             :     }
+   15727           0 :     nm1 = *n - 1;
+   15728             :     wstart = 1;
+   15729             :     qstart = 3;
+   15730           0 :     if (icompq == 1) {
+   15731           0 :         PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(n, &d__[1], &c_1, &q[1], &c_1);
+   15732           0 :         i__1 = *n - 1;
+   15733           0 :         PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&i__1, &e[1], &c_1, &q[*n + 1], &c_1);
+   15734             :     }
+   15735           0 :     if (iuplo == 2) {
+   15736             :         qstart = 5;
+   15737           0 :         wstart = (*n << 1) - 1;
+   15738           0 :         i__1 = *n - 1;
+   15739           0 :         for (i__ = 1; i__ <= i__1; ++i__) {
+   15740           0 :             PLUMED_BLAS_F77_FUNC(slartg,SLARTG)(&d__[i__], &e[i__], &cs, &sn, &r__);
+   15741           0 :             d__[i__] = r__;
+   15742           0 :             e[i__] = sn * d__[i__ + 1];
+   15743           0 :             d__[i__ + 1] = cs * d__[i__ + 1];
+   15744           0 :             if (icompq == 1) {
+   15745           0 :                 q[i__ + (*n << 1)] = cs;
+   15746           0 :                 q[i__ + *n * 3] = sn;
+   15747           0 :             } else if (icompq == 2) {
+   15748           0 :                 work[i__] = cs;
+   15749           0 :                 work[nm1 + i__] = -sn;
+   15750             :             }
+   15751             :         }
+   15752             :     }
+   15753           0 :     if (icompq == 0) {
+   15754           0 :       PLUMED_BLAS_F77_FUNC(slasdq,SLASDQ)("U",&c_0,n,&c_0,&c_0,&c_0,&d__[1],&e[1],&vt[vt_offset],ldvt,
+   15755           0 :               &u[u_offset], ldu, &u[u_offset], ldu, &work[wstart], info);
+   15756           0 :         goto L40;
+   15757             :     }
+   15758           0 :     if (*n <= smlsiz) {
+   15759           0 :         if (icompq == 2) {
+   15760           0 :             PLUMED_BLAS_F77_FUNC(slaset,SLASET)("A", n, n, &zero, &one, &u[u_offset], ldu);
+   15761           0 :             PLUMED_BLAS_F77_FUNC(slaset,SLASET)("A", n, n, &zero, &one, &vt[vt_offset], ldvt);
+   15762           0 :             PLUMED_BLAS_F77_FUNC(slasdq,SLASDQ)("U",&c_0,n,n,n,&c_0,&d__[1],&e[1],&vt[vt_offset],ldvt,
+   15763           0 :                     &u[u_offset],ldu,&u[u_offset],ldu,&work[wstart],info);
+   15764           0 :         } else if (icompq == 1) {
+   15765             :             iu = 1;
+   15766           0 :             ivt = iu + *n;
+   15767           0 :             PLUMED_BLAS_F77_FUNC(slaset,SLASET)("A", n, n, &zero, &one, &q[iu + (qstart - 1) * *n], n);
+   15768           0 :             PLUMED_BLAS_F77_FUNC(slaset,SLASET)("A", n, n, &zero, &one, &q[ivt + (qstart - 1) * *n], n);
+   15769           0 :             PLUMED_BLAS_F77_FUNC(slasdq,SLASDQ)("U", &c_0, n, n, n, &c_0, &d__[1], &e[1], 
+   15770           0 :                     &q[ivt + (qstart - 1) * *n], n, &q[iu + (qstart - 1) * *n], 
+   15771           0 :                     n, &q[iu + (qstart - 1) * *n], n, &work[wstart], info);
+   15772             :         }
+   15773           0 :         goto L40;
+   15774             :     }
+   15775             : 
+   15776           0 :     if (icompq == 2) {
+   15777           0 :         PLUMED_BLAS_F77_FUNC(slaset,SLASET)("A", n, n, &zero, &one, &u[u_offset], ldu);
+   15778           0 :         PLUMED_BLAS_F77_FUNC(slaset,SLASET)("A", n, n, &zero, &one, &vt[vt_offset], ldvt);
+   15779             :     }
+   15780             : 
+   15781           0 :     orgnrm = PLUMED_BLAS_F77_FUNC(slanst,SLANST)("M", n, &d__[1], &e[1]);
+   15782           0 :     if ( std::abs(orgnrm)<PLUMED_GMX_FLOAT_MIN) {
+   15783             :         return;
+   15784             :     }
+   15785           0 :     PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G", &c_0, &c_0, &orgnrm, &one, n, &c_1, &d__[1], n, &ierr);
+   15786           0 :     PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G", &c_0, &c_0, &orgnrm, &one, &nm1, &c_1, &e[1], &nm1, &ierr);
+   15787             : 
+   15788             :     eps = PLUMED_GMX_FLOAT_EPS;
+   15789             : 
+   15790           0 :     mlvl = (int) (std::log((float) (*n) / (float) (smlsiz + 1)) / std::log(2.)) + 1;
+   15791             :     smlszp = smlsiz + 1;
+   15792             : 
+   15793           0 :     if (icompq == 1) {
+   15794             :         iu = 1;
+   15795             :         ivt = smlsiz + 1;
+   15796           0 :         difl = ivt + smlszp;
+   15797           0 :         difr = difl + mlvl;
+   15798           0 :         z__ = difr + (mlvl << 1);
+   15799           0 :         ic = z__ + mlvl;
+   15800           0 :         is = ic + 1;
+   15801           0 :         poles = is + 1;
+   15802           0 :         givnum = poles + (mlvl << 1);
+   15803             : 
+   15804             :         k = 1;
+   15805             :         givptr = 2;
+   15806             :         perm = 3;
+   15807           0 :         givcol = perm + mlvl;
+   15808             :     }
+   15809             : 
+   15810           0 :     i__1 = *n;
+   15811           0 :     for (i__ = 1; i__ <= i__1; ++i__) {
+   15812           0 :         if (std::abs(d__[i__]) < eps) 
+   15813           0 :             d__[i__] = (d__[i__]>0) ? eps : -eps;
+   15814             :     }
+   15815             : 
+   15816             :     start = 1;
+   15817           0 :     sqre = 0;
+   15818             : 
+   15819           0 :     i__1 = nm1;
+   15820           0 :     for (i__ = 1; i__ <= i__1; ++i__) {
+   15821           0 :         if (std::abs(e[i__]) < eps || i__ == nm1) {
+   15822           0 :             if (i__ < nm1) {
+   15823           0 :                 nsize = i__ - start + 1;
+   15824           0 :             } else if (std::abs(e[i__]) >= eps) {
+   15825           0 :                 nsize = *n - start + 1;
+   15826             :             } else {
+   15827           0 :                 nsize = i__ - start + 1;
+   15828           0 :                 if (icompq == 2) {
+   15829           0 :                     u[*n + *n * u_dim1] = (d__[*n]>0) ? 1.0 : -1.0; 
+   15830           0 :                     vt[*n + *n * vt_dim1] = 1.;
+   15831           0 :                 } else if (icompq == 1) {
+   15832           0 :                     q[*n + (qstart - 1) * *n] = (d__[*n]>0) ? 1.0 : -1.0; 
+   15833           0 :                     q[*n + (smlsiz + qstart - 1) * *n] = 1.;
+   15834             :                 }
+   15835           0 :                 d__[*n] = std::abs(d__[*n]);
+   15836             :             }
+   15837           0 :             if (icompq == 2) {
+   15838           0 :                 PLUMED_BLAS_F77_FUNC(slasd0,SLASD0)(&nsize, &sqre, &d__[start], &e[start], 
+   15839           0 :                         &u[start + start * u_dim1], ldu, 
+   15840           0 :                         &vt[start + start * vt_dim1], 
+   15841           0 :                         ldvt, &smlsiz, &iwork[1], &work[wstart], info);
+   15842             :             } else {
+   15843           0 :                 PLUMED_BLAS_F77_FUNC(slasda,SLASDA)(&icompq, &smlsiz, &nsize, &sqre, &d__[start], 
+   15844           0 :                         &e[start], &q[start + (iu + qstart - 2) * *n], n, 
+   15845           0 :                         &q[start + (ivt + qstart - 2) * *n], &iq[start + k * *n],
+   15846           0 :                         &q[start + (difl + qstart - 2) * *n], 
+   15847           0 :                         &q[start + (difr + qstart - 2) * *n], 
+   15848           0 :                         &q[start + (z__ + qstart - 2) * *n], 
+   15849           0 :                         &q[start + (poles + qstart - 2) * *n], 
+   15850           0 :                         &iq[start + givptr * *n], &iq[start + givcol * *n], n, 
+   15851           0 :                         &iq[start + perm * *n], 
+   15852           0 :                         &q[start + (givnum + qstart - 2) * *n], 
+   15853           0 :                         &q[start + (ic + qstart - 2) * *n], 
+   15854           0 :                         &q[start + (is + qstart - 2) * *n], &work[wstart], 
+   15855             :                         &iwork[1], info);
+   15856           0 :                 if (*info != 0) {
+   15857             :                     return;
+   15858             :                 }
+   15859             :             }
+   15860           0 :             start = i__ + 1;
+   15861             :         }
+   15862             :     }
+   15863           0 :     PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G", &c_0, &c_0, &one, &orgnrm, n, &c_1, &d__[1], n, &ierr);
+   15864           0 : L40:
+   15865           0 :     i__1 = *n;
+   15866           0 :     for (ii = 2; ii <= i__1; ++ii) {
+   15867           0 :         i__ = ii - 1;
+   15868             :         kk = i__;
+   15869           0 :         p = d__[i__];
+   15870           0 :         i__2 = *n;
+   15871           0 :         for (j = ii; j <= i__2; ++j) {
+   15872           0 :             if (d__[j] > p) {
+   15873             :                 kk = j;
+   15874             :                 p = d__[j];
+   15875             :             }
+   15876             :         }
+   15877           0 :         if (kk != i__) {
+   15878           0 :             d__[kk] = d__[i__];
+   15879           0 :             d__[i__] = p;
+   15880           0 :             if (icompq == 1) {
+   15881           0 :                 iq[i__] = kk;
+   15882           0 :             } else if (icompq == 2) {
+   15883           0 :                 PLUMED_BLAS_F77_FUNC(sswap,SSWAP)(n, &u[i__ * u_dim1 + 1],&c_1,&u[kk*u_dim1+1],&c_1);
+   15884           0 :                 PLUMED_BLAS_F77_FUNC(sswap,SSWAP)(n, &vt[i__ + vt_dim1], ldvt, &vt[kk + vt_dim1], ldvt);
+   15885             :             }
+   15886           0 :         } else if (icompq == 1) {
+   15887           0 :             iq[i__] = i__;
+   15888             :         }
+   15889             :     }
+   15890           0 :     if (icompq == 1) {
+   15891           0 :         if (iuplo == 1) {
+   15892           0 :             iq[*n] = 1;
+   15893             :         } else {
+   15894           0 :             iq[*n] = 0;
+   15895             :         }
+   15896             :     }
+   15897           0 :     if (iuplo == 2 && icompq == 2) {
+   15898           0 :         PLUMED_BLAS_F77_FUNC(slasr,SLASR)("L", "V", "B", n, n, &work[1], &work[*n], &u[u_offset], ldu);
+   15899             :     }
+   15900             : 
+   15901             :     return;
+   15902             : }
+   15903             : }
+   15904             : }
+   15905             : #include <cctype>
+   15906             : #include <cmath>
+   15907             : 
+   15908             : #include "blas/blas.h"
+   15909             : #include "lapack.h"
+   15910             : 
+   15911             : #include "real.h"
+   15912             : 
+   15913             : #include "blas/blas.h"
+   15914             : namespace PLMD{
+   15915             : namespace lapack{
+   15916             : using namespace blas;
+   15917             : void 
+   15918           0 : PLUMED_BLAS_F77_FUNC(sbdsqr,SBDSQR)(const char *uplo,
+   15919             :                         int *n,
+   15920             :                         int *ncvt,
+   15921             :                         int *nru, 
+   15922             :                         int *ncc, 
+   15923             :                         float *d__,
+   15924             :                         float *e,
+   15925             :                         float *vt, 
+   15926             :                         int *ldvt,
+   15927             :                         float *u, 
+   15928             :                         int *ldu,
+   15929             :                         float *c__, 
+   15930             :                         int *ldc,
+   15931             :                         float *work,
+   15932             :                         int *info)
+   15933             : {
+   15934           0 :     const char xuplo = std::toupper(*uplo);
+   15935             :     int c_dim1, c_offset, u_dim1, u_offset, vt_dim1, vt_offset, i__1, 
+   15936             :             i__2;
+   15937             :     float r__1, r__2, r__3, r__4;
+   15938             :     float c_b15 = -.125;
+   15939             : 
+   15940           0 :     int c__1 = 1;
+   15941             :     float c_b49 = 1.f;
+   15942           0 :     float c_b72 = -1.f;
+   15943             : 
+   15944             :     float f, g, h__;
+   15945             :     int i__, j, m;
+   15946             :     float r__, cs;
+   15947             :     int ll;
+   15948             :     float sn, mu;
+   15949             :     int nm1, nm12, nm13, lll;
+   15950             :     float eps, sll, tol, abse;
+   15951             :     int idir;
+   15952             :     float abss;
+   15953             :     int oldm;
+   15954             :     float cosl;
+   15955             :     int isub, iter;
+   15956             :     float unfl, sinl, cosr, smin, smax, sinr;
+   15957             :     float oldcs;
+   15958             :     int oldll;
+   15959           0 :     float shift, sigmn, oldsn = 0.;
+   15960             :     int maxit;
+   15961             :     float sminl;
+   15962             :     float sigmx;
+   15963             :     int lower;
+   15964             :     float sminoa;
+   15965             :     float thresh;
+   15966             :     int rotate;
+   15967             :     float tolmul;
+   15968             :     int itmp1,itmp2;
+   15969             :     
+   15970           0 :     --d__;
+   15971           0 :     --e;
+   15972           0 :     vt_dim1 = *ldvt;
+   15973           0 :     vt_offset = 1 + vt_dim1;
+   15974           0 :     vt -= vt_offset;
+   15975           0 :     u_dim1 = *ldu;
+   15976           0 :     u_offset = 1 + u_dim1;
+   15977           0 :     u -= u_offset;
+   15978           0 :     c_dim1 = *ldc;
+   15979           0 :     c_offset = 1 + c_dim1;
+   15980           0 :     c__ -= c_offset;
+   15981           0 :     --work;
+   15982             : 
+   15983           0 :     *info = 0;
+   15984             :     
+   15985           0 :     itmp1 = (*n > 1) ? *n : 1;
+   15986           0 :     itmp2 = (*nru > 1) ? *nru : 1;
+   15987             :     
+   15988             :     lower = (xuplo == 'L');
+   15989           0 :     if ( (xuplo!='U') && !lower) {
+   15990           0 :         *info = -1;
+   15991           0 :     } else if (*n < 0) {
+   15992           0 :         *info = -2;
+   15993           0 :     } else if (*ncvt < 0) {
+   15994           0 :         *info = -3;
+   15995           0 :     } else if (*nru < 0) {
+   15996           0 :         *info = -4;
+   15997           0 :     } else if (*ncc < 0) {
+   15998           0 :         *info = -5;
+   15999           0 :     } else if ( ((*ncvt == 0) && (*ldvt < 1)) || ((*ncvt > 0) && (*ldvt < itmp1)) ) {
+   16000           0 :         *info = -9;
+   16001           0 :     } else if (*ldu < itmp2) {
+   16002           0 :         *info = -11;
+   16003           0 :     } else if ( ((*ncc == 0) && (*ldc < 1)) || ((*ncc > 0) && (*ldc < itmp1))) {
+   16004           0 :         *info = -13;
+   16005             :     }
+   16006           0 :     if (*info != 0) {
+   16007             :         return;
+   16008             :     }
+   16009           0 :     if (*n == 0) {
+   16010             :         return;
+   16011             :     }
+   16012           0 :     if (*n == 1) {
+   16013           0 :         goto L160;
+   16014             :     }
+   16015             : 
+   16016           0 :     rotate = *ncvt > 0 || *nru > 0 || *ncc > 0;
+   16017             : 
+   16018             :     if (! rotate) {
+   16019           0 :         PLUMED_BLAS_F77_FUNC(slasq1,SLASQ1)(n, &d__[1], &e[1], &work[1], info);
+   16020           0 :         return;
+   16021             :     }
+   16022             : 
+   16023           0 :     nm1 = *n - 1;
+   16024           0 :     nm12 = nm1 + nm1;
+   16025           0 :     nm13 = nm12 + nm1;
+   16026             :     idir = 0;
+   16027             : 
+   16028             :     eps = PLUMED_GMX_FLOAT_EPS;
+   16029             :     unfl = PLUMED_GMX_FLOAT_MIN/PLUMED_GMX_FLOAT_EPS;
+   16030             : 
+   16031           0 :     if (lower) {
+   16032           0 :         i__1 = *n - 1;
+   16033           0 :         for (i__ = 1; i__ <= i__1; ++i__) {
+   16034           0 :             PLUMED_BLAS_F77_FUNC(slartg,SLARTG)(&d__[i__], &e[i__], &cs, &sn, &r__);
+   16035           0 :             d__[i__] = r__;
+   16036           0 :             e[i__] = sn * d__[i__ + 1];
+   16037           0 :             d__[i__ + 1] = cs * d__[i__ + 1];
+   16038           0 :             work[i__] = cs;
+   16039           0 :             work[nm1 + i__] = sn;
+   16040             :         }
+   16041             : 
+   16042           0 :         if (*nru > 0) {
+   16043           0 :             PLUMED_BLAS_F77_FUNC(slasr,SLASR)("R", "V", "F", nru, n, &work[1], &work[*n], &u[u_offset], 
+   16044             :                     ldu);
+   16045             :         }
+   16046           0 :         if (*ncc > 0) {
+   16047           0 :             PLUMED_BLAS_F77_FUNC(slasr,SLASR)("L", "V", "F", n, ncc, &work[1], &work[*n], &c__[c_offset],
+   16048             :                      ldc);
+   16049             :         }
+   16050             :     }
+   16051             : 
+   16052             :     r__3 = 100.f, r__4 = std::pow(static_cast<float>(PLUMED_GMX_FLOAT_EPS),c_b15);
+   16053           0 :     r__1 = 10.f, r__2 = (r__3<r__4) ? r__3 : r__4;
+   16054             :     tolmul = (r__1>r__2) ? r__1 : r__2;
+   16055             :     tol = tolmul * eps;
+   16056             :     smax = 0.f;
+   16057           0 :     i__1 = *n;
+   16058           0 :     for (i__ = 1; i__ <= i__1; ++i__) {
+   16059           0 :         r__2 = smax, r__3 = (r__1 = d__[i__], std::abs(r__1));
+   16060           0 :         smax = (r__2>r__3) ? r__2 : r__3;
+   16061             :     }
+   16062           0 :     i__1 = *n - 1;
+   16063           0 :     for (i__ = 1; i__ <= i__1; ++i__) {
+   16064           0 :         r__2 = smax, r__3 = (r__1 = e[i__], std::abs(r__1));
+   16065           0 :         smax = (r__2>r__3) ? r__2 : r__3;
+   16066             :     }
+   16067             :     sminl = 0.f;
+   16068             :     if (tol >= 0.f) {
+   16069           0 :         sminoa = std::abs(d__[1]);
+   16070           0 :         if (sminoa == 0.f) {
+   16071           0 :             goto L50;
+   16072             :         }
+   16073             :         mu = sminoa;
+   16074           0 :         i__1 = *n;
+   16075           0 :         for (i__ = 2; i__ <= i__1; ++i__) {
+   16076           0 :             mu = (r__2 = d__[i__], std::abs(r__2)) * (mu / (mu + (r__1 = e[i__ - 
+   16077           0 :                     1], std::abs(r__1))));
+   16078           0 :             sminoa = (sminoa<mu) ? sminoa : mu;
+   16079           0 :             if (sminoa == 0.f) {
+   16080           0 :                 goto L50;
+   16081             :             }
+   16082             :         }
+   16083           0 : L50:
+   16084           0 :         sminoa /=  std::sqrt((float) (*n));
+   16085           0 :         r__1 = tol * sminoa, r__2 = *n * 6 * *n * unfl;
+   16086           0 :         thresh = (r__1>r__2) ? r__1 : r__2;
+   16087             :     } else {
+   16088             :         r__1 = std::abs(tol) * smax, r__2 = *n * 6 * *n * unfl;
+   16089             :         thresh = (r__1>r__2) ? r__1 : r__2;
+   16090             :     }
+   16091             :     maxit = *n * 6 * *n;
+   16092             :     iter = 0;
+   16093             :     oldll = -1;
+   16094             :     oldm = -1;
+   16095             :     m = *n;
+   16096             : 
+   16097           0 : L60:
+   16098             : 
+   16099           0 :     if (m <= 1) {
+   16100           0 :         goto L160;
+   16101             :     }
+   16102           0 :     if (iter > maxit) {
+   16103           0 :         goto L200;
+   16104             :     }
+   16105             : 
+   16106             :     if (tol < 0.f && (r__1 = d__[m], std::abs(r__1)) <= thresh) {
+   16107             :         d__[m] = 0.f;
+   16108             :     }
+   16109           0 :     smax = (r__1 = d__[m], std::abs(r__1));
+   16110             :     smin = smax;
+   16111           0 :     i__1 = m - 1;
+   16112           0 :     for (lll = 1; lll <= i__1; ++lll) {
+   16113           0 :         ll = m - lll;
+   16114           0 :         abss = (r__1 = d__[ll], std::abs(r__1));
+   16115           0 :         abse = (r__1 = e[ll], std::abs(r__1));
+   16116             :         if (tol < 0.f && abss <= thresh) {
+   16117             :             d__[ll] = 0.f;
+   16118             :         }
+   16119           0 :         if (abse <= thresh) {
+   16120           0 :             goto L80;
+   16121             :         }
+   16122           0 :         smin = (smin<abss) ? smin : abss;
+   16123           0 :         r__1 = (smax>abss) ? smax : abss;
+   16124           0 :         smax = (r__1>abse) ? r__1 : abse;
+   16125             :     }
+   16126             :     ll = 0;
+   16127           0 :     goto L90;
+   16128             : L80:
+   16129           0 :     e[ll] = 0.f;
+   16130           0 :     if (ll == m - 1) {
+   16131             :         --m;
+   16132           0 :         goto L60;
+   16133             :     }
+   16134           0 : L90:
+   16135           0 :     ++ll;
+   16136           0 :     if (ll == m - 1) {
+   16137           0 :         PLUMED_BLAS_F77_FUNC(slasv2,SLASV2)(&d__[m - 1], &e[m - 1], &d__[m], &sigmn, &sigmx, &sinr, &cosr,
+   16138             :                  &sinl, &cosl);
+   16139           0 :         d__[m - 1] = sigmx;
+   16140           0 :         e[m - 1] = 0.f;
+   16141           0 :         d__[m] = sigmn;
+   16142           0 :         if (*ncvt > 0) {
+   16143           0 :             PLUMED_BLAS_F77_FUNC(srot,SROT)(ncvt, &vt[m - 1 + vt_dim1], ldvt, &vt[m + vt_dim1], ldvt, &
+   16144             :                     cosr, &sinr);
+   16145             :         }
+   16146           0 :         if (*nru > 0) {
+   16147           0 :             PLUMED_BLAS_F77_FUNC(srot,SROT)(nru, &u[(m - 1) * u_dim1 + 1], &c__1, &u[m * u_dim1 + 1], &
+   16148             :                     c__1, &cosl, &sinl);
+   16149             :         }
+   16150           0 :         if (*ncc > 0) {
+   16151           0 :             PLUMED_BLAS_F77_FUNC(srot,SROT)(ncc, &c__[m - 1 + c_dim1], ldc, &c__[m + c_dim1], ldc, &
+   16152             :                     cosl, &sinl);
+   16153             :         }
+   16154           0 :         m += -2;
+   16155           0 :         goto L60;
+   16156             :     }
+   16157           0 :     if (ll > oldm || m < oldll) {
+   16158           0 :         if ((r__1 = d__[ll], std::abs(r__1)) >= (r__2 = d__[m], std::abs(r__2))) {
+   16159             :             idir = 1;
+   16160             :         } else {
+   16161             :             idir = 2;
+   16162             :         }
+   16163             :     }
+   16164           0 :     if (idir == 1) {
+   16165             : 
+   16166           0 :         if( (std::abs(e[m-1]) <= std::abs(tol) * std::abs(d__[m])) ||
+   16167             :             (tol<0.0 && std::abs(e[m-1])<=thresh)) {
+   16168           0 :             e[m - 1] = 0.f;
+   16169           0 :             goto L60;
+   16170             :         }
+   16171             :         if (tol >= 0.f) {
+   16172           0 :             mu = (r__1 = d__[ll], std::abs(r__1));
+   16173             :             sminl = mu;
+   16174             :             i__1 = m - 1;
+   16175           0 :             for (lll = ll; lll <= i__1; ++lll) {
+   16176           0 :                 if ((r__1 = e[lll], std::abs(r__1)) <= tol * mu) {
+   16177           0 :                     e[lll] = 0.f;
+   16178           0 :                     goto L60;
+   16179             :                 }
+   16180           0 :                 mu = (r__2 = d__[lll + 1], std::abs(r__2)) * (mu / (mu + (r__1 = 
+   16181             :                         e[lll], std::abs(r__1))));
+   16182           0 :                 sminl = (sminl<mu) ? sminl : mu;
+   16183             :             }
+   16184             :         }
+   16185             :     } else {
+   16186           0 :         if( (std::abs(e[ll]) <= std::abs(tol)*std::abs(d__[ll])) ||
+   16187             :             (tol<0.0 && std::abs(e[ll])<=thresh)) {
+   16188           0 :             e[ll] = 0.f;
+   16189           0 :             goto L60;
+   16190             :         }
+   16191             :         if (tol >= 0.f) {
+   16192           0 :             mu = (r__1 = d__[m], std::abs(r__1));
+   16193             :             sminl = mu;
+   16194           0 :             i__1 = ll;
+   16195           0 :             for (lll = m - 1; lll >= i__1; --lll) {
+   16196           0 :                 if ((r__1 = e[lll], std::abs(r__1)) <= tol * mu) {
+   16197           0 :                     e[lll] = 0.f;
+   16198           0 :                     goto L60;
+   16199             :                 }
+   16200           0 :                 mu = (r__2 = d__[lll], std::abs(r__2)) * (mu / (mu + (r__1 = e[
+   16201             :                         lll], std::abs(r__1))));
+   16202           0 :                 sminl = (sminl<mu) ? sminl : mu;
+   16203             :             }
+   16204             :         }
+   16205             :     }
+   16206             :     oldll = ll;
+   16207             :     oldm = m;
+   16208             : 
+   16209           0 :     r__1 = eps, r__2 = tol * .01f;
+   16210           0 :     if (tol >= 0.f && *n * tol * (sminl / smax) <= ((r__1>r__2) ? r__1 : r__2)) {
+   16211           0 :         shift = 0.f;
+   16212             :     } else {
+   16213           0 :         if (idir == 1) {
+   16214           0 :             sll = (r__1 = d__[ll], std::abs(r__1));
+   16215           0 :             PLUMED_BLAS_F77_FUNC(slas2,SLAS2)(&d__[m - 1], &e[m - 1], &d__[m], &shift, &r__);
+   16216             :         } else {
+   16217           0 :             sll = (r__1 = d__[m], std::abs(r__1));
+   16218           0 :             PLUMED_BLAS_F77_FUNC(slas2,SLAS2)(&d__[ll], &e[ll], &d__[ll + 1], &shift, &r__);
+   16219             :         }
+   16220           0 :         if (sll > 0.f) {
+   16221           0 :             r__1 = shift / sll;
+   16222           0 :             if (r__1 * r__1 < eps) {
+   16223           0 :                 shift = 0.f;
+   16224             :             }
+   16225             :         }
+   16226             :     }
+   16227           0 :     iter = iter + m - ll;
+   16228           0 :     if (shift == 0.f) {
+   16229           0 :         if (idir == 1) {
+   16230           0 :             cs = 1.f;
+   16231           0 :             oldcs = 1.f;
+   16232           0 :             i__1 = m - 1;
+   16233           0 :             for (i__ = ll; i__ <= i__1; ++i__) {
+   16234           0 :                 r__1 = d__[i__] * cs;
+   16235           0 :                 PLUMED_BLAS_F77_FUNC(slartg,SLARTG)(&r__1, &e[i__], &cs, &sn, &r__);
+   16236           0 :                 if (i__ > ll) {
+   16237           0 :                     e[i__ - 1] = oldsn * r__;
+   16238             :                 }
+   16239           0 :                 r__1 = oldcs * r__;
+   16240           0 :                 r__2 = d__[i__ + 1] * sn;
+   16241           0 :                 PLUMED_BLAS_F77_FUNC(slartg,SLARTG)(&r__1, &r__2, &oldcs, &oldsn, &d__[i__]);
+   16242           0 :                 work[i__ - ll + 1] = cs;
+   16243           0 :                 work[i__ - ll + 1 + nm1] = sn;
+   16244           0 :                 work[i__ - ll + 1 + nm12] = oldcs;
+   16245           0 :                 work[i__ - ll + 1 + nm13] = oldsn;
+   16246             :             }
+   16247           0 :             h__ = d__[m] * cs;
+   16248           0 :             d__[m] = h__ * oldcs;
+   16249           0 :             e[m - 1] = h__ * oldsn;
+   16250           0 :             if (*ncvt > 0) {
+   16251           0 :                 i__1 = m - ll + 1;
+   16252           0 :                 PLUMED_BLAS_F77_FUNC(slasr,SLASR)("L", "V", "F", &i__1, ncvt, &work[1], &work[*n], &vt[
+   16253           0 :                         ll + vt_dim1], ldvt);
+   16254             :             }
+   16255           0 :             if (*nru > 0) {
+   16256           0 :                 i__1 = m - ll + 1;
+   16257           0 :                 PLUMED_BLAS_F77_FUNC(slasr,SLASR)("R", "V", "F", nru, &i__1, &work[nm12 + 1], &work[nm13 
+   16258           0 :                         + 1], &u[ll * u_dim1 + 1], ldu);
+   16259             :             }
+   16260           0 :             if (*ncc > 0) {
+   16261           0 :                 i__1 = m - ll + 1;
+   16262           0 :                 PLUMED_BLAS_F77_FUNC(slasr,SLASR)("L", "V", "F", &i__1, ncc, &work[nm12 + 1], &work[nm13 
+   16263           0 :                         + 1], &c__[ll + c_dim1], ldc);
+   16264             :             }
+   16265           0 :             if ((r__1 = e[m - 1], std::abs(r__1)) <= thresh) {
+   16266           0 :                 e[m - 1] = 0.f;
+   16267             :             }
+   16268             :         } else {
+   16269           0 :             cs = 1.f;
+   16270           0 :             oldcs = 1.f;
+   16271           0 :             i__1 = ll + 1;
+   16272           0 :             for (i__ = m; i__ >= i__1; --i__) {
+   16273           0 :                 r__1 = d__[i__] * cs;
+   16274           0 :                 PLUMED_BLAS_F77_FUNC(slartg,SLARTG)(&r__1, &e[i__ - 1], &cs, &sn, &r__);
+   16275           0 :                 if (i__ < m) {
+   16276           0 :                     e[i__] = oldsn * r__;
+   16277             :                 }
+   16278           0 :                 r__1 = oldcs * r__;
+   16279           0 :                 r__2 = d__[i__ - 1] * sn;
+   16280           0 :                 PLUMED_BLAS_F77_FUNC(slartg,SLARTG)(&r__1, &r__2, &oldcs, &oldsn, &d__[i__]);
+   16281           0 :                 work[i__ - ll] = cs;
+   16282           0 :                 work[i__ - ll + nm1] = -sn;
+   16283           0 :                 work[i__ - ll + nm12] = oldcs;
+   16284           0 :                 work[i__ - ll + nm13] = -oldsn;
+   16285             :             }
+   16286           0 :             h__ = d__[ll] * cs;
+   16287           0 :             d__[ll] = h__ * oldcs;
+   16288           0 :             e[ll] = h__ * oldsn;
+   16289           0 :             if (*ncvt > 0) {
+   16290           0 :                 i__1 = m - ll + 1;
+   16291           0 :                 PLUMED_BLAS_F77_FUNC(slasr,SLASR)("L", "V", "B", &i__1, ncvt, &work[nm12 + 1], &work[
+   16292           0 :                         nm13 + 1], &vt[ll + vt_dim1], ldvt);
+   16293             :             }
+   16294           0 :             if (*nru > 0) {
+   16295           0 :                 i__1 = m - ll + 1;
+   16296           0 :                 PLUMED_BLAS_F77_FUNC(slasr,SLASR)("R", "V", "B", nru, &i__1, &work[1], &work[*n], &u[ll *
+   16297           0 :                          u_dim1 + 1], ldu);
+   16298             :             }
+   16299           0 :             if (*ncc > 0) {
+   16300           0 :                 i__1 = m - ll + 1;
+   16301           0 :                 PLUMED_BLAS_F77_FUNC(slasr,SLASR)("L", "V", "B", &i__1, ncc, &work[1], &work[*n], &c__[
+   16302           0 :                         ll + c_dim1], ldc);
+   16303             :             }
+   16304           0 :             if ((r__1 = e[ll], std::abs(r__1)) <= thresh) {
+   16305           0 :                 e[ll] = 0.f;
+   16306             :             }
+   16307             :         }
+   16308             :     } else {
+   16309             : 
+   16310           0 :         if (idir == 1) {
+   16311           0 :             f = ((r__1 = d__[ll], std::abs(r__1)) - shift) * ( ((d__[ll] > 0) ? c_b49 : -c_b49) + shift / d__[ll]);
+   16312           0 :             g = e[ll];
+   16313           0 :             i__1 = m - 1;
+   16314           0 :             for (i__ = ll; i__ <= i__1; ++i__) {
+   16315           0 :                 PLUMED_BLAS_F77_FUNC(slartg,SLARTG)(&f, &g, &cosr, &sinr, &r__);
+   16316           0 :                 if (i__ > ll) {
+   16317           0 :                     e[i__ - 1] = r__;
+   16318             :                 }
+   16319           0 :                 f = cosr * d__[i__] + sinr * e[i__];
+   16320           0 :                 e[i__] = cosr * e[i__] - sinr * d__[i__];
+   16321           0 :                 g = sinr * d__[i__ + 1];
+   16322           0 :                 d__[i__ + 1] = cosr * d__[i__ + 1];
+   16323           0 :                 PLUMED_BLAS_F77_FUNC(slartg,SLARTG)(&f, &g, &cosl, &sinl, &r__);
+   16324           0 :                 d__[i__] = r__;
+   16325           0 :                 f = cosl * e[i__] + sinl * d__[i__ + 1];
+   16326           0 :                 d__[i__ + 1] = cosl * d__[i__ + 1] - sinl * e[i__];
+   16327           0 :                 if (i__ < m - 1) {
+   16328           0 :                     g = sinl * e[i__ + 1];
+   16329           0 :                     e[i__ + 1] = cosl * e[i__ + 1];
+   16330             :                 }
+   16331           0 :                 work[i__ - ll + 1] = cosr;
+   16332           0 :                 work[i__ - ll + 1 + nm1] = sinr;
+   16333           0 :                 work[i__ - ll + 1 + nm12] = cosl;
+   16334           0 :                 work[i__ - ll + 1 + nm13] = sinl;
+   16335             :             }
+   16336           0 :             e[m - 1] = f;
+   16337             : 
+   16338           0 :             if (*ncvt > 0) {
+   16339           0 :                 i__1 = m - ll + 1;
+   16340           0 :                 PLUMED_BLAS_F77_FUNC(slasr,SLASR)("L", "V", "F", &i__1, ncvt, &work[1], &work[*n], &vt[
+   16341           0 :                         ll + vt_dim1], ldvt);
+   16342             :             }
+   16343           0 :             if (*nru > 0) {
+   16344           0 :                 i__1 = m - ll + 1;
+   16345           0 :                 PLUMED_BLAS_F77_FUNC(slasr,SLASR)("R", "V", "F", nru, &i__1, &work[nm12 + 1], &work[nm13 
+   16346           0 :                         + 1], &u[ll * u_dim1 + 1], ldu);
+   16347             :             }
+   16348           0 :             if (*ncc > 0) {
+   16349           0 :                 i__1 = m - ll + 1;
+   16350           0 :                 PLUMED_BLAS_F77_FUNC(slasr,SLASR)("L", "V", "F", &i__1, ncc, &work[nm12 + 1], &work[nm13 
+   16351           0 :                         + 1], &c__[ll + c_dim1], ldc);
+   16352             :             }
+   16353           0 :             if ((r__1 = e[m - 1], std::abs(r__1)) <= thresh) {
+   16354           0 :                 e[m - 1] = 0.f;
+   16355             :             }
+   16356             :         } else {
+   16357             : 
+   16358           0 :             f = ((r__1 = d__[m], std::abs(r__1)) - shift) * ( ((d__[m] > 0) ? c_b49 : -c_b49) + shift / d__[m]);
+   16359           0 :             g = e[m - 1];
+   16360           0 :             i__1 = ll + 1;
+   16361           0 :             for (i__ = m; i__ >= i__1; --i__) {
+   16362           0 :                 PLUMED_BLAS_F77_FUNC(slartg,SLARTG)(&f, &g, &cosr, &sinr, &r__);
+   16363           0 :                 if (i__ < m) {
+   16364           0 :                     e[i__] = r__;
+   16365             :                 }
+   16366           0 :                 f = cosr * d__[i__] + sinr * e[i__ - 1];
+   16367           0 :                 e[i__ - 1] = cosr * e[i__ - 1] - sinr * d__[i__];
+   16368           0 :                 g = sinr * d__[i__ - 1];
+   16369           0 :                 d__[i__ - 1] = cosr * d__[i__ - 1];
+   16370           0 :                 PLUMED_BLAS_F77_FUNC(slartg,SLARTG)(&f, &g, &cosl, &sinl, &r__);
+   16371           0 :                 d__[i__] = r__;
+   16372           0 :                 f = cosl * e[i__ - 1] + sinl * d__[i__ - 1];
+   16373           0 :                 d__[i__ - 1] = cosl * d__[i__ - 1] - sinl * e[i__ - 1];
+   16374           0 :                 if (i__ > ll + 1) {
+   16375           0 :                     g = sinl * e[i__ - 2];
+   16376           0 :                     e[i__ - 2] = cosl * e[i__ - 2];
+   16377             :                 }
+   16378           0 :                 work[i__ - ll] = cosr;
+   16379           0 :                 work[i__ - ll + nm1] = -sinr;
+   16380           0 :                 work[i__ - ll + nm12] = cosl;
+   16381           0 :                 work[i__ - ll + nm13] = -sinl;
+   16382             :             }
+   16383           0 :             e[ll] = f;
+   16384             : 
+   16385           0 :             if ((r__1 = e[ll], std::abs(r__1)) <= thresh) {
+   16386           0 :                 e[ll] = 0.f;
+   16387             :             }
+   16388           0 :             if (*ncvt > 0) {
+   16389           0 :                 i__1 = m - ll + 1;
+   16390           0 :                 PLUMED_BLAS_F77_FUNC(slasr,SLASR)("L", "V", "B", &i__1, ncvt, &work[nm12 + 1], &work[
+   16391           0 :                         nm13 + 1], &vt[ll + vt_dim1], ldvt);
+   16392             :             }
+   16393           0 :             if (*nru > 0) {
+   16394           0 :                 i__1 = m - ll + 1;
+   16395           0 :                 PLUMED_BLAS_F77_FUNC(slasr,SLASR)("R", "V", "B", nru, &i__1, &work[1], &work[*n], &u[ll *
+   16396           0 :                          u_dim1 + 1], ldu);
+   16397             :             }
+   16398           0 :             if (*ncc > 0) {
+   16399           0 :                 i__1 = m - ll + 1;
+   16400           0 :                 PLUMED_BLAS_F77_FUNC(slasr,SLASR)("L", "V", "B", &i__1, ncc, &work[1], &work[*n], &c__[
+   16401           0 :                         ll + c_dim1], ldc);
+   16402             :             }
+   16403             :         }
+   16404             :     }
+   16405             : 
+   16406           0 :     goto L60;
+   16407             : 
+   16408           0 : L160:
+   16409           0 :     i__1 = *n;
+   16410           0 :     for (i__ = 1; i__ <= i__1; ++i__) {
+   16411           0 :         if (d__[i__] < 0.f) {
+   16412           0 :             d__[i__] = -d__[i__];
+   16413             : 
+   16414           0 :             if (*ncvt > 0) {
+   16415           0 :                 PLUMED_BLAS_F77_FUNC(sscal,SSCAL)(ncvt, &c_b72, &vt[i__ + vt_dim1], ldvt);
+   16416             :             }
+   16417             :         }
+   16418             :     }
+   16419             : 
+   16420           0 :     i__1 = *n - 1;
+   16421           0 :     for (i__ = 1; i__ <= i__1; ++i__) {
+   16422             : 
+   16423             :         isub = 1;
+   16424           0 :         smin = d__[1];
+   16425           0 :         i__2 = *n + 1 - i__;
+   16426           0 :         for (j = 2; j <= i__2; ++j) {
+   16427           0 :             if (d__[j] <= smin) {
+   16428             :                 isub = j;
+   16429             :                 smin = d__[j];
+   16430             :             }
+   16431             :         }
+   16432           0 :         if (isub != *n + 1 - i__) {
+   16433           0 :             d__[isub] = d__[*n + 1 - i__];
+   16434           0 :             d__[*n + 1 - i__] = smin;
+   16435           0 :             if (*ncvt > 0) {
+   16436           0 :                 PLUMED_BLAS_F77_FUNC(sswap,SSWAP)(ncvt, &vt[isub + vt_dim1], ldvt, &vt[*n + 1 - i__ + 
+   16437           0 :                         vt_dim1], ldvt);
+   16438             :             }
+   16439           0 :             if (*nru > 0) {
+   16440           0 :                 PLUMED_BLAS_F77_FUNC(sswap,SSWAP)(nru, &u[isub * u_dim1 + 1], &c__1, &u[(*n + 1 - i__) * 
+   16441           0 :                         u_dim1 + 1], &c__1);
+   16442             :             }
+   16443           0 :             if (*ncc > 0) {
+   16444           0 :                 PLUMED_BLAS_F77_FUNC(sswap,SSWAP)(ncc, &c__[isub + c_dim1], ldc, &c__[*n + 1 - i__ + 
+   16445           0 :                         c_dim1], ldc);
+   16446             :             }
+   16447             :         }
+   16448             :     }
+   16449           0 :     goto L220;
+   16450             : 
+   16451             : L200:
+   16452           0 :     *info = 0;
+   16453           0 :     i__1 = *n - 1;
+   16454           0 :     for (i__ = 1; i__ <= i__1; ++i__) {
+   16455           0 :         if (e[i__] != 0.f) {
+   16456           0 :             ++(*info);
+   16457             :         }
+   16458             :     }
+   16459           0 : L220:
+   16460             :     return;
+   16461             : 
+   16462             : }
+   16463             : 
+   16464             : 
+   16465             : }
+   16466             : }
+   16467             : #include "lapack.h"
+   16468             : 
+   16469             : #include "blas/blas.h"
+   16470             : namespace PLMD{
+   16471             : namespace lapack{
+   16472             : using namespace blas;
+   16473             : void
+   16474           0 : PLUMED_BLAS_F77_FUNC(sgebd2,SGEBD2)(int *m,
+   16475             :         int *n,
+   16476             :         float *a,
+   16477             :         int *lda,
+   16478             :         float *d,
+   16479             :         float *e,
+   16480             :         float *tauq,
+   16481             :         float *taup,
+   16482             :         float *work,
+   16483             :         int *info)
+   16484             : {
+   16485             : 
+   16486             :   int i,i1,i2,i3;
+   16487             : 
+   16488           0 :     *info = 0;
+   16489             : 
+   16490           0 :   if(*m>=*n) {
+   16491             :     /* reduce to upper bidiag. form */
+   16492           0 :     for(i=0;i<*n;i++) {
+   16493           0 :       i1 = *m - i;
+   16494           0 :       i2 = ( (i+1) < (*m-1)) ? (i+1) : (*m-1);
+   16495           0 :       i3 = 1;
+   16496           0 :       PLUMED_BLAS_F77_FUNC(slarfg,SLARFG)(&i1,&(a[i*(*lda)+i]),&(a[i*(*lda)+i2]),&i3,&(tauq[i]));
+   16497           0 :       d[i] = a[i*(*lda)+i];
+   16498           0 :       a[i*(*lda)+i] = 1.0;
+   16499           0 :       i2 = *n - i - 1;
+   16500           0 :       PLUMED_BLAS_F77_FUNC(slarf,SLARF)("L",&i1,&i2,&(a[i*(*lda)+i]),&i3,&(tauq[i]),&(a[(i+1)*(*lda)+i]),lda,work);
+   16501           0 :       a[i*(*lda)+i] = d[i];
+   16502             : 
+   16503           0 :       if(i<(*n-1)) {
+   16504             : 
+   16505           0 :         i1 = *n - i -1;
+   16506           0 :         i2 = ( (i+2) < (*n-1)) ? (i+2) : (*n-1); 
+   16507           0 :         PLUMED_BLAS_F77_FUNC(slarfg,SLARFG)(&i1,&(a[(i+1)*(*lda)+i]),&(a[i2*(*lda)+i]),lda,&(taup[i]));
+   16508             : 
+   16509           0 :         e[i] = a[(i+1)*(*lda)+i];
+   16510           0 :         a[(i+1)*(*lda)+i] = 1.0;
+   16511             : 
+   16512           0 :         i1 = *m - i - 1;
+   16513           0 :         i2 = *n - i - 1;
+   16514           0 :         PLUMED_BLAS_F77_FUNC(slarf,SLARF)("R",&i1,&i2,&(a[(i+1)*(*lda)+i]),lda,&(taup[i]),&(a[(i+1)*(*lda)+i+1]),lda,work);
+   16515           0 :         a[(i+1)*(*lda)+i] = e[i];
+   16516             :       } else
+   16517           0 :         taup[i] = 0.0;
+   16518             :     }
+   16519             :   } else {
+   16520             :     /* reduce to lower bidiag. form */
+   16521           0 :     for(i=0;i<*m;i++) {
+   16522           0 :       i1 = *n - i;
+   16523           0 :       i2 = ( (i+1) < (*n-1)) ? (i+1) : (*n-1);
+   16524           0 :       PLUMED_BLAS_F77_FUNC(slarfg,SLARFG)(&i1,&(a[i*(*lda)+i]),&(a[i2*(*lda)+i]),lda,&(taup[i]));
+   16525           0 :       d[i] = a[i*(*lda)+i];
+   16526           0 :       a[i*(*lda)+i] = 1.0;
+   16527             : 
+   16528           0 :       i2 = *m - i - 1;
+   16529           0 :       i3 = ( (i+1) < (*m-1)) ? (i+1) : (*m-1);
+   16530           0 :       PLUMED_BLAS_F77_FUNC(slarf,SLARF)("R",&i2,&i1,&(a[i*(*lda)+i]),lda,&(taup[i]),&(a[(i)*(*lda)+i3]),lda,work);
+   16531           0 :       a[i*(*lda)+i] = d[i];
+   16532             : 
+   16533           0 :       if(i<(*m-1)) {
+   16534             : 
+   16535           0 :         i1 = *m - i - 1;
+   16536           0 :         i2 = ( (i+2) < (*m-1)) ? (i+2) : (*m-1);
+   16537           0 :         i3 = 1;
+   16538           0 :         PLUMED_BLAS_F77_FUNC(slarfg,SLARFG)(&i1,&(a[(i)*(*lda)+i+1]),&(a[i*(*lda)+i2]),&i3,&(tauq[i]));
+   16539             : 
+   16540           0 :         e[i] = a[(i)*(*lda)+i+1];
+   16541           0 :         a[(i)*(*lda)+i+1] = 1.0;
+   16542             : 
+   16543           0 :         i1 = *m - i - 1;
+   16544           0 :         i2 = *n - i - 1;
+   16545           0 :         i3 = 1;
+   16546           0 :         PLUMED_BLAS_F77_FUNC(slarf,SLARF)("L",&i1,&i2,&(a[(i)*(*lda)+i+1]),&i3,&(tauq[i]),&(a[(i+1)*(*lda)+i+1]),lda,work);
+   16547           0 :         a[(i)*(*lda)+i+1] = e[i];
+   16548             :       } else
+   16549           0 :         tauq[i] = 0.0;
+   16550             :     }
+   16551             :   }
+   16552           0 :   return;
+   16553             : }
+   16554             : }
+   16555             : }
+   16556             : #include "lapack.h"
+   16557             : #include "blas/blas.h"
+   16558             : #include "lapack_limits.h"
+   16559             : 
+   16560             : 
+   16561             : #include "blas/blas.h"
+   16562             : namespace PLMD{
+   16563             : namespace lapack{
+   16564             : using namespace blas;
+   16565             : void
+   16566           0 : PLUMED_BLAS_F77_FUNC(sgebrd,SGEBRD)(int *m, 
+   16567             :         int *n, 
+   16568             :         float *a, 
+   16569             :         int *lda, 
+   16570             :         float *d__, 
+   16571             :         float *e,
+   16572             :         float *tauq, 
+   16573             :         float *taup,
+   16574             :         float *work, 
+   16575             :         int *lwork,
+   16576             :         int *info)
+   16577             : {
+   16578             :     /* System generated locals */
+   16579             :     int a_dim1, a_offset, i_1, i_2, i_3, i_4;
+   16580             : 
+   16581             :     /* Local variables */
+   16582             :     int i_, j, nx,nb;
+   16583             :     float ws;
+   16584             :     int nbmin, iinfo, minmn;
+   16585             :     int ldwrkx, ldwrky;
+   16586           0 :     float one = 1.0;
+   16587           0 :     float minusone = -1.0;
+   16588             : 
+   16589           0 :     a_dim1 = *lda;
+   16590           0 :     a_offset = 1 + a_dim1;
+   16591           0 :     a -= a_offset;
+   16592           0 :     --d__;
+   16593           0 :     --e;
+   16594           0 :     --tauq;
+   16595           0 :     --taup;
+   16596           0 :     --work;
+   16597             : 
+   16598           0 :     nb = DGEBRD_BLOCKSIZE;
+   16599           0 :     *info = 0;
+   16600           0 :     if (*lwork==-1) {
+   16601           0 :       work[1] = (float) ( (*m + *n) * nb);
+   16602           0 :       return;
+   16603             :     }
+   16604           0 :     minmn = (*m < *n) ? *m : *n;
+   16605           0 :     if (minmn == 0) {
+   16606           0 :       work[1] = 1.;
+   16607           0 :       return;
+   16608             :     }
+   16609             : 
+   16610           0 :     ws = (*m > *n) ? *m : *n;
+   16611           0 :     ldwrkx = *m;
+   16612           0 :     ldwrky = *n;
+   16613             : 
+   16614           0 :     if (nb > 1 && nb < minmn) {
+   16615             :         nx = DGEBRD_CROSSOVER;
+   16616           0 :         if (nx < minmn) {
+   16617           0 :             ws = (float) ((*m + *n) * nb);
+   16618           0 :             if ((float) (*lwork) < ws) {
+   16619             :               nbmin = DGEBRD_MINBLOCKSIZE;
+   16620           0 :                 if (*lwork >= (*m + *n) * nbmin) {
+   16621           0 :                     nb = *lwork / (*m + *n);
+   16622             :                 } else {
+   16623           0 :                     nb = 1;
+   16624             :                     nx = minmn;
+   16625             :                 }
+   16626             :             }
+   16627             :         }
+   16628             :     } else {
+   16629             :         nx = minmn;
+   16630             :     }
+   16631             : 
+   16632           0 :     i_1 = minmn - nx;
+   16633           0 :     i_2 = nb;
+   16634           0 :     for (i_ = 1; i_2 < 0 ? i_ >= i_1 : i_ <= i_1; i_ += i_2) {
+   16635             : 
+   16636           0 :         i_3 = *m - i_ + 1;
+   16637           0 :         i_4 = *n - i_ + 1;
+   16638           0 :         PLUMED_BLAS_F77_FUNC(slabrd,SLABRD)(&i_3, &i_4, &nb, &a[i_ + i_ * a_dim1], lda, &d__[i_], 
+   16639           0 :                 &e[i_], &tauq[i_], &taup[i_], &work[1], &ldwrkx, 
+   16640           0 :                 &work[ldwrkx * nb + 1], &ldwrky);
+   16641             : 
+   16642           0 :         i_3 = *m - i_ - nb + 1;
+   16643           0 :         i_4 = *n - i_ - nb + 1;
+   16644           0 :         PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("N", "T", &i_3, &i_4, &nb, &minusone, 
+   16645           0 :                &a[i_ + nb + i_ * a_dim1], lda, &work[ldwrkx * nb + nb + 1],
+   16646           0 :                &ldwrky, &one, &a[i_ + nb + (i_ + nb) * a_dim1], lda);
+   16647           0 :         i_3 = *m - i_ - nb + 1;
+   16648           0 :         i_4 = *n - i_ - nb + 1;
+   16649           0 :         PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("N", "N", &i_3, &i_4, &nb, &minusone, &work[nb + 1], &ldwrkx,
+   16650           0 :                &a[i_ + (i_ + nb) * a_dim1], lda, &one, 
+   16651           0 :                &a[i_ + nb + (i_ + nb) * a_dim1], lda);
+   16652             : 
+   16653           0 :         if (*m >= *n) {
+   16654           0 :             i_3 = i_ + nb - 1;
+   16655           0 :             for (j = i_; j <= i_3; ++j) {
+   16656           0 :                 a[j + j * a_dim1] = d__[j];
+   16657           0 :                 a[j + (j + 1) * a_dim1] = e[j];
+   16658             :             }
+   16659             :         } else {
+   16660           0 :             i_3 = i_ + nb - 1;
+   16661           0 :             for (j = i_; j <= i_3; ++j) {
+   16662           0 :                 a[j + j * a_dim1] = d__[j];
+   16663           0 :                 a[j + 1 + j * a_dim1] = e[j];
+   16664             :             }
+   16665             :         }
+   16666             :     }
+   16667             : 
+   16668           0 :     i_2 = *m - i_ + 1;
+   16669           0 :     i_1 = *n - i_ + 1;
+   16670           0 :     PLUMED_BLAS_F77_FUNC(sgebd2,SGEBD2)(&i_2, &i_1, &a[i_ + i_ * a_dim1], lda, &d__[i_], &e[i_], &
+   16671           0 :             tauq[i_], &taup[i_], &work[1], &iinfo);
+   16672           0 :     work[1] = ws;
+   16673           0 :     return;
+   16674             : 
+   16675             : }
+   16676             : }
+   16677             : }
+   16678             : #include "lapack.h"
+   16679             : 
+   16680             : #include "blas/blas.h"
+   16681             : namespace PLMD{
+   16682             : namespace lapack{
+   16683             : using namespace blas;
+   16684             : void 
+   16685           0 : PLUMED_BLAS_F77_FUNC(sgelq2,SGELQ2)(int *m, 
+   16686             :                         int *n, 
+   16687             :                         float *a,
+   16688             :                         int *lda, 
+   16689             :                         float *tau, 
+   16690             :                         float *work, 
+   16691             :                         int *info)
+   16692             : {
+   16693             :     /* System generated locals */
+   16694             :     int a_dim1, a_offset, i__1, i__2, i__3, i__4;
+   16695             : 
+   16696             :     /* Local variables */
+   16697             :     int i__, k;
+   16698             :     float aii;
+   16699             : 
+   16700           0 :     a_dim1 = *lda;
+   16701           0 :     a_offset = 1 + a_dim1;
+   16702           0 :     a -= a_offset;
+   16703           0 :     --tau;
+   16704             :     --work;
+   16705             : 
+   16706           0 :     *info = 0;
+   16707             :     
+   16708           0 :     i__4 = (*m > 1) ? *m : 1;
+   16709             :     
+   16710           0 :     if (*m < 0) {
+   16711           0 :         *info = -1;
+   16712           0 :     } else if (*n < 0) {
+   16713           0 :         *info = -2;
+   16714           0 :     } else if (*lda < i__4) {
+   16715           0 :         *info = -4;
+   16716             :     }
+   16717           0 :     if (*info != 0) {
+   16718             :         return;
+   16719             :     }
+   16720             : 
+   16721             :     
+   16722           0 :     k = (*m < *n ) ? *m : *n;
+   16723             :     i__1 = k;
+   16724           0 :     for (i__ = 1; i__ <= i__1; ++i__) {
+   16725           0 :         i__2 = *n - i__ + 1;
+   16726           0 :         i__3 = i__ + 1;
+   16727             :     i__4 = (i__3 < *n) ? i__3 : *n;
+   16728           0 :         PLUMED_BLAS_F77_FUNC(slarfg,SLARFG)(&i__2, &a[i__ + i__ * a_dim1], &a[i__ + i__4 * a_dim1],
+   16729           0 :             lda, &tau[i__]);
+   16730           0 :         if (i__ < *m) {
+   16731           0 :             aii = a[i__ + i__ * a_dim1];
+   16732           0 :             a[i__ + i__ * a_dim1] = 1.f;
+   16733           0 :             i__2 = *m - i__;
+   16734           0 :             i__3 = *n - i__ + 1;
+   16735           0 :             PLUMED_BLAS_F77_FUNC(slarf,SLARF)("R", &i__2, &i__3, &a[i__ + i__ * a_dim1], lda, 
+   16736           0 :                &tau[i__], &a[i__ + 1 + i__ * a_dim1], lda, &work[1]);
+   16737           0 :             a[i__ + i__ * a_dim1] = aii;
+   16738             :         }
+   16739             :     }
+   16740             :     return;
+   16741             : }
+   16742             : 
+   16743             : 
+   16744             : }
+   16745             : }
+   16746             : #include <cmath>
+   16747             : #include "lapack.h"
+   16748             : #include "lapack_limits.h"
+   16749             : 
+   16750             : 
+   16751             : 
+   16752             : #include "blas/blas.h"
+   16753             : namespace PLMD{
+   16754             : namespace lapack{
+   16755             : using namespace blas;
+   16756             : void
+   16757           0 : PLUMED_BLAS_F77_FUNC(sgelqf,SGELQF)(int *m,
+   16758             :         int *n, 
+   16759             :         float *a, 
+   16760             :         int *lda, 
+   16761             :         float *tau,
+   16762             :         float *work, 
+   16763             :         int *lwork, 
+   16764             :         int *info)
+   16765             : {
+   16766             :     int a_dim1, a_offset, i__1, i__2, i__3, i__4;
+   16767             : 
+   16768             :     int i__, k, ib, nb, nx, iws, nbmin, iinfo;
+   16769             :     int ldwork, lwkopt;
+   16770             : 
+   16771           0 :     a_dim1 = *lda;
+   16772           0 :     a_offset = 1 + a_dim1;
+   16773           0 :     a -= a_offset;
+   16774           0 :     --tau;
+   16775             :     --work;
+   16776             : 
+   16777           0 :     *info = 0;
+   16778             :     nb = DGELQF_BLOCKSIZE;
+   16779           0 :     lwkopt = *m * nb;
+   16780           0 :     work[1] = (float) lwkopt;
+   16781             : 
+   16782           0 :     if (*lwork==-1) {
+   16783             :         return;
+   16784             :     }
+   16785             : 
+   16786           0 :     k =(*m < *n) ? *m : *n;
+   16787           0 :     if (k == 0) {
+   16788           0 :         work[1] = 1.;
+   16789           0 :         return;
+   16790             :     }
+   16791             : 
+   16792             :     nbmin = 2;
+   16793             :     nx = 0;
+   16794             :     iws = *m;
+   16795           0 :     if (nb > 1 && nb < k) {
+   16796             :         nx = DGELQF_CROSSOVER;
+   16797           0 :         if (nx < k) {
+   16798           0 :             ldwork = *m;
+   16799           0 :             iws = ldwork * nb;
+   16800           0 :             if (*lwork < iws) {
+   16801             : 
+   16802           0 :                 nb = *lwork / ldwork;
+   16803             :                 nbmin = DGELQF_MINBLOCKSIZE;
+   16804             :             }
+   16805             :         }
+   16806             :     }
+   16807             : 
+   16808           0 :     if (nb >= nbmin && nb < k && nx < k) {
+   16809             : 
+   16810           0 :         i__1 = k - nx;
+   16811           0 :         i__2 = nb;
+   16812           0 :         for (i__ = 1; i__2 < 0 ? i__ >= i__1 : i__ <= i__1; i__ += i__2) {
+   16813           0 :             i__3 = k - i__ + 1;
+   16814           0 :             ib = (i__3 < nb) ? i__3 : nb;
+   16815             : 
+   16816           0 :             i__3 = *n - i__ + 1;
+   16817           0 :             PLUMED_BLAS_F77_FUNC(sgelq2,SGELQ2)(&ib, &i__3, &a[i__ + i__ * a_dim1], lda, &tau[i__], &work[
+   16818             :                     1], &iinfo);
+   16819           0 :             if (i__ + ib <= *m) {
+   16820             : 
+   16821           0 :                 i__3 = *n - i__ + 1;
+   16822           0 :                 PLUMED_BLAS_F77_FUNC(slarft,SLARFT)("Forward", "Rowwise", &i__3, &ib, &a[i__ + i__ * 
+   16823             :                         a_dim1], lda, &tau[i__], &work[1], &ldwork);
+   16824             : 
+   16825           0 :                 i__3 = *m - i__ - ib + 1;
+   16826           0 :                 i__4 = *n - i__ + 1;
+   16827           0 :                 PLUMED_BLAS_F77_FUNC(slarfb,SLARFB)("Right", "No transpose", "Forward", "Rowwise", &i__3, 
+   16828             :                         &i__4, &ib, &a[i__ + i__ * a_dim1], lda, &work[1], &
+   16829           0 :                         ldwork, &a[i__ + ib + i__ * a_dim1], lda, &work[ib + 
+   16830           0 :                         1], &ldwork);
+   16831             :             }
+   16832             :         }
+   16833             :     } else {
+   16834             :         i__ = 1;
+   16835             :     }
+   16836             : 
+   16837           0 :     if (i__ <= k) {
+   16838           0 :         i__2 = *m - i__ + 1;
+   16839           0 :         i__1 = *n - i__ + 1;
+   16840           0 :         PLUMED_BLAS_F77_FUNC(sgelq2,SGELQ2)(&i__2, &i__1, &a[i__ + i__ * a_dim1], lda, &tau[i__], &work[1]
+   16841             :                 , &iinfo);
+   16842             :     }
+   16843             : 
+   16844           0 :     work[1] = (float) iws;
+   16845           0 :     return;
+   16846             : 
+   16847             : }
+   16848             : }
+   16849             : }
+   16850             : #include "lapack.h"
+   16851             : 
+   16852             : 
+   16853             : #include "blas/blas.h"
+   16854             : namespace PLMD{
+   16855             : namespace lapack{
+   16856             : using namespace blas;
+   16857             : void
+   16858           0 : PLUMED_BLAS_F77_FUNC(sgeqr2,SGEQR2)(int *m,
+   16859             :         int *n,
+   16860             :         float *a,
+   16861             :         int *lda,
+   16862             :         float *tau,
+   16863             :         float *work,
+   16864             :         int *info)
+   16865             : {
+   16866           0 :   int k = (*m < *n) ? *m : *n;
+   16867             :   int i,i1,i2,i3;
+   16868             :   float aii;
+   16869             : 
+   16870           0 :   *info = 0;
+   16871             :   
+   16872           0 :   for(i=0;i<k;i++) {
+   16873           0 :     i1 = *m - i;
+   16874           0 :     i2 = ( (i+1) < (*m-1) ) ? (i+1) : (*m-1);
+   16875           0 :     i3 = 1;
+   16876           0 :     PLUMED_BLAS_F77_FUNC(slarfg,SLARFG)(&i1,&(a[i*(*lda)+i]),&(a[i*(*lda)+i2]),&i3,&(tau[i]));
+   16877           0 :     if(i<(*n-1)) {
+   16878           0 :       aii = a[i*(*lda)+i];
+   16879           0 :       a[i*(*lda)+i] = 1.0;
+   16880           0 :       i2 = *n - i - 1;
+   16881           0 :       PLUMED_BLAS_F77_FUNC(slarf,SLARF)("L",&i1,&i2,&(a[i*(*lda)+i]),&i3,&(tau[i]),
+   16882           0 :              &(a[(i+1)*(*lda)+i]),lda,work);
+   16883           0 :       a[i*(*lda)+i] = aii;
+   16884             :     }
+   16885             :   }
+   16886           0 :   return;
+   16887             : }
+   16888             : }
+   16889             : }
+   16890             : #include "lapack.h"
+   16891             : #include "lapack_limits.h"
+   16892             : 
+   16893             : #include "blas/blas.h"
+   16894             : namespace PLMD{
+   16895             : namespace lapack{
+   16896             : using namespace blas;
+   16897             : void 
+   16898           0 : PLUMED_BLAS_F77_FUNC(sgeqrf,SGEQRF)(int *m, 
+   16899             :         int *n, 
+   16900             :         float *a, 
+   16901             :         int *lda, 
+   16902             :         float *tau,
+   16903             :         float *work, 
+   16904             :         int *lwork, 
+   16905             :         int *info)
+   16906             : {
+   16907             :     int a_dim1, a_offset, i__1, i__2, i__3, i__4;
+   16908             : 
+   16909             :     int i__, k, ib, nb, nx, iws, nbmin, iinfo;
+   16910             :     int ldwork, lwkopt;
+   16911             : 
+   16912           0 :     a_dim1 = *lda;
+   16913           0 :     a_offset = 1 + a_dim1;
+   16914           0 :     a -= a_offset;
+   16915           0 :     --tau;
+   16916             :     --work;
+   16917             : 
+   16918           0 :     *info = 0;
+   16919             :     nb = DGEQRF_BLOCKSIZE;
+   16920           0 :     lwkopt = *n * nb;
+   16921           0 :     work[1] = (float) lwkopt;
+   16922           0 :         if (*lwork==-1)
+   16923             :         return;
+   16924             :     
+   16925             : 
+   16926           0 :     k = (*m < *n) ? *m : *n;
+   16927           0 :     if (k == 0) {
+   16928           0 :         work[1] = 1.;
+   16929           0 :         return;
+   16930             :     }
+   16931             : 
+   16932             :     nbmin = 2;
+   16933             :     nx = 0;
+   16934             :     iws = *n;
+   16935           0 :     if (nb > 1 && nb < k) {
+   16936             :         
+   16937             :       nx = DGEQRF_CROSSOVER;
+   16938           0 :         if (nx < k) {
+   16939             : 
+   16940           0 :             ldwork = *n;
+   16941           0 :             iws = ldwork * nb;
+   16942           0 :             if (*lwork < iws) {
+   16943             : 
+   16944           0 :                 nb = *lwork / ldwork;
+   16945             :                 nbmin = DGEQRF_MINBLOCKSIZE;
+   16946             :             }
+   16947             :         }
+   16948             :     }
+   16949             : 
+   16950           0 :     if (nb >= nbmin && nb < k && nx < k) {
+   16951           0 :         i__1 = k - nx;
+   16952           0 :         i__2 = nb;
+   16953           0 :         for (i__ = 1; i__2 < 0 ? i__ >= i__1 : i__ <= i__1; i__ += i__2) {
+   16954             : 
+   16955           0 :             i__3 = k - i__ + 1;
+   16956           0 :             ib = (i__3 < nb) ? i__3 : nb;
+   16957             : 
+   16958           0 :             i__3 = *m - i__ + 1;
+   16959           0 :             PLUMED_BLAS_F77_FUNC(sgeqr2,SGEQR2)(&i__3, &ib, &a[i__ + i__ * a_dim1], lda, &tau[i__], &work[
+   16960             :                     1], &iinfo);
+   16961           0 :             if (i__ + ib <= *n) {
+   16962             : 
+   16963           0 :                 i__3 = *m - i__ + 1;
+   16964           0 :                 PLUMED_BLAS_F77_FUNC(slarft,SLARFT)("Forward", "Columnwise", &i__3, &ib, &a[i__ + i__ * 
+   16965             :                         a_dim1], lda, &tau[i__], &work[1], &ldwork);
+   16966             : 
+   16967           0 :                 i__3 = *m - i__ + 1;
+   16968           0 :                 i__4 = *n - i__ - ib + 1;
+   16969           0 :                 PLUMED_BLAS_F77_FUNC(slarfb,SLARFB)("Left", "Transpose", "Forward", "Columnwise", &i__3, &
+   16970             :                         i__4, &ib, &a[i__ + i__ * a_dim1], lda, &work[1], &
+   16971           0 :                         ldwork, &a[i__ + (i__ + ib) * a_dim1], lda, &work[ib 
+   16972           0 :                         + 1], &ldwork);
+   16973             :             }
+   16974             :         }
+   16975             :     } else {
+   16976             :         i__ = 1;
+   16977             :     }
+   16978             : 
+   16979           0 :     if (i__ <= k) {
+   16980           0 :         i__2 = *m - i__ + 1;
+   16981           0 :         i__1 = *n - i__ + 1;
+   16982           0 :         PLUMED_BLAS_F77_FUNC(sgeqr2,SGEQR2)(&i__2, &i__1, &a[i__ + i__ * a_dim1], lda, &tau[i__], &work[1]
+   16983             :                 , &iinfo);
+   16984             :     }
+   16985             : 
+   16986           0 :     work[1] = (float) iws;
+   16987           0 :     return;
+   16988             : 
+   16989             : } 
+   16990             : 
+   16991             : }
+   16992             : }
+   16993             : #include <cmath>
+   16994             : #include "real.h"
+   16995             : 
+   16996             : 
+   16997             : #include "blas/blas.h"
+   16998             : #include "lapack.h"
+   16999             : #include "lapack_limits.h"
+   17000             : 
+   17001             : #include "blas/blas.h"
+   17002             : namespace PLMD{
+   17003             : namespace lapack{
+   17004             : using namespace blas;
+   17005             : void
+   17006           0 : PLUMED_BLAS_F77_FUNC(sgesdd,SGESDD)(const char *jobz, 
+   17007             :                         int *m, 
+   17008             :                         int *n, 
+   17009             :                         float *a, 
+   17010             :                         int *lda, 
+   17011             :                         float *s,
+   17012             :                         float *u, 
+   17013             :                         int *ldu, 
+   17014             :                         float *vt, 
+   17015             :                         int *ldvt, 
+   17016             :                         float *work,
+   17017             :                         int *lwork, 
+   17018             :                         int *iwork, 
+   17019             :                         int *info)
+   17020             : {
+   17021             :     int a_dim1, a_offset, u_dim1, u_offset, vt_dim1, vt_offset, i__1, i__2;
+   17022             : 
+   17023             :     int ie, iu;
+   17024             :     float dum[1], eps;
+   17025             :     int ivt, iscl;
+   17026             :     float anrm;
+   17027             :     int idum[1], ierr, itau;
+   17028             :     int minmn, wrkbl, itaup, itauq, mnthr;
+   17029             :     int nwork;
+   17030             :     int wntqn;
+   17031             :     int bdspac;
+   17032             :     float bignum;
+   17033             :     int ldwrku, maxwrk, ldwkvt;
+   17034             :     float smlnum,minval, safemin;
+   17035             :     int lquery;
+   17036           0 :     int c__0 = 0;
+   17037           0 :     int c__1 = 1;
+   17038           0 :     float zero = 0.0;
+   17039           0 :     float one = 1.0;
+   17040             : 
+   17041             : 
+   17042           0 :     a_dim1 = *lda;
+   17043           0 :     a_offset = 1 + a_dim1;
+   17044           0 :     a -= a_offset;
+   17045             :     --s;
+   17046           0 :     u_dim1 = *ldu;
+   17047           0 :     u_offset = 1 + u_dim1;
+   17048           0 :     u -= u_offset;
+   17049           0 :     vt_dim1 = *ldvt;
+   17050           0 :     vt_offset = 1 + vt_dim1;
+   17051           0 :     vt -= vt_offset;
+   17052           0 :     --work;
+   17053             :     --iwork;
+   17054             : 
+   17055           0 :     *info = 0;
+   17056           0 :     minmn = (*m < *n) ? *m : *n;
+   17057           0 :     mnthr = (int) (minmn * 11. / 6.);
+   17058           0 :     wntqn = (*jobz=='o' || *jobz=='O');
+   17059             : 
+   17060             :     maxwrk = 1;
+   17061           0 :     lquery = *lwork == -1;
+   17062             : 
+   17063           0 :     if (*info == 0 && *m > 0 && *n > 0) {
+   17064           0 :         if (*m >= *n) {
+   17065             : 
+   17066           0 :             if (wntqn) {
+   17067           0 :                 bdspac = *n * 7;
+   17068             :             } else {
+   17069           0 :                 bdspac = *n * 3 * *n + (*n << 2);
+   17070             :             }
+   17071           0 :             if (*m >= mnthr) {
+   17072           0 :                 if (wntqn) {
+   17073             : 
+   17074           0 :                     wrkbl = *n * 67;
+   17075           0 :                     i__1 = wrkbl, i__2 = bdspac + *n;
+   17076             :                     maxwrk = (i__1 > i__2) ? i__1 : i__2;
+   17077             :                 } else {
+   17078             : 
+   17079           0 :                     wrkbl = *n * 67;
+   17080           0 :                     i__1 = wrkbl, i__2 = *n + (*m << 5);
+   17081             :                     wrkbl = (i__1 > i__2) ? i__1 : i__2;
+   17082           0 :                     i__1 = wrkbl, i__2 = bdspac + *n * 3;
+   17083             :                     wrkbl = (i__1 > i__2) ? i__1 : i__2;
+   17084           0 :                     maxwrk = wrkbl + *n * *n;
+   17085             :                 }
+   17086             :             } else {
+   17087             : 
+   17088           0 :                 wrkbl = *n * 3 + (*m + *n*32);
+   17089           0 :                 if (wntqn) {
+   17090           0 :                     i__1 = wrkbl, i__2 = bdspac + *n * 3;
+   17091             :                     maxwrk = (i__1 > i__2) ? i__1 : i__2;
+   17092             :                 } else {
+   17093           0 :                     i__1 = maxwrk, i__2 = bdspac + *n * 3;
+   17094             :                     maxwrk = (i__1 > i__2) ? i__1 : i__2;
+   17095             :                 }
+   17096             :             }
+   17097             :         } else {
+   17098             : 
+   17099           0 :             if (wntqn) {
+   17100           0 :                 bdspac = *m * 7;
+   17101             :             } else {
+   17102           0 :                 bdspac = *m * 3 * *m + (*m*4);
+   17103             :             }
+   17104           0 :             if (*n >= mnthr) {
+   17105           0 :                 if (wntqn) {
+   17106             : 
+   17107           0 :                     wrkbl = *m * 67;
+   17108           0 :                     i__1 = wrkbl, i__2 = bdspac + *m;
+   17109             :                     maxwrk = (i__1 > i__2) ? i__1 : i__2;
+   17110             :                 } else {
+   17111             : 
+   17112           0 :                     wrkbl = *m * 67;
+   17113           0 :                     i__1 = wrkbl, i__2 = *m + (*n*32);
+   17114             :                     wrkbl = (i__1 > i__2) ? i__1 : i__2;
+   17115             : 
+   17116           0 :                     i__1 = wrkbl, i__2 = bdspac + *m * 3;
+   17117             :                     wrkbl = (i__1 > i__2) ? i__1 : i__2;
+   17118           0 :                     maxwrk = wrkbl + *m * *m;
+   17119             :                 }
+   17120             :             } else {
+   17121           0 :                 wrkbl = *m * 3 + (*m + *n*32);
+   17122           0 :                 if (wntqn) {
+   17123           0 :                     i__1 = wrkbl, i__2 = bdspac + *m * 3;
+   17124             :                     maxwrk = (i__1 > i__2) ? i__1 : i__2;
+   17125             :                 } else {
+   17126           0 :                     i__1 = wrkbl, i__2 = bdspac + *m * 3;
+   17127             :                     maxwrk = (i__1 > i__2) ? i__1 : i__2;
+   17128             :                 }
+   17129             :             }
+   17130             :         }
+   17131           0 :         work[1] = (float) maxwrk;
+   17132             :     }
+   17133             :     
+   17134           0 :     if( lquery != 0)
+   17135             :     {
+   17136             :         return;
+   17137             :     }
+   17138             :     
+   17139           0 :     if (*m == 0 || *n == 0) {
+   17140           0 :         if (*lwork >= 1) {
+   17141           0 :             work[1] = 1.;
+   17142             :         }
+   17143           0 :         return;
+   17144             :     }
+   17145             :     eps = PLUMED_GMX_FLOAT_EPS;
+   17146             :     minval = PLUMED_GMX_FLOAT_MIN;
+   17147             :     safemin = minval / eps;
+   17148           0 :     smlnum =  std::sqrt(safemin) / eps;
+   17149             : 
+   17150             : 
+   17151           0 :     bignum = 1. / smlnum;
+   17152             : 
+   17153             : 
+   17154           0 :     anrm = PLUMED_BLAS_F77_FUNC(slange,SLANGE)("M", m, n, &a[a_offset], lda, dum);
+   17155             :     iscl = 0;
+   17156           0 :     if (anrm > 0. && anrm < smlnum) {
+   17157             :         iscl = 1;
+   17158           0 :         PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G",&c__0,&c__0,&anrm,&smlnum,m,n,&a[a_offset],lda,&ierr);
+   17159           0 :     } else if (anrm > bignum) {
+   17160             :         iscl = 1;
+   17161           0 :         PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G",&c__0,&c__0,&anrm,&bignum,m,n,&a[a_offset],lda,&ierr);
+   17162             :     }
+   17163             : 
+   17164           0 :     if (*m >= *n) {
+   17165           0 :         if (*m >= mnthr) {
+   17166             : 
+   17167           0 :             if (wntqn) {
+   17168             : 
+   17169             :                 itau = 1;
+   17170           0 :                 nwork = itau + *n;
+   17171             : 
+   17172           0 :                 i__1 = *lwork - nwork + 1;
+   17173           0 :                 PLUMED_BLAS_F77_FUNC(sgeqrf,SGEQRF)(m, n, &a[a_offset], lda, &work[itau], &work[nwork], &
+   17174             :                         i__1, &ierr);
+   17175             : 
+   17176           0 :                 i__1 = *n - 1;
+   17177           0 :                 i__2 = *n - 1;
+   17178           0 :                 PLUMED_BLAS_F77_FUNC(slaset,SLASET)("L", &i__1, &i__2, &zero, &zero, &a[a_dim1 + 2], 
+   17179             :                         lda);
+   17180             :                 ie = 1;
+   17181           0 :                 itauq = ie + *n;
+   17182           0 :                 itaup = itauq + *n;
+   17183           0 :                 nwork = itaup + *n;
+   17184             : 
+   17185           0 :                 i__1 = *lwork - nwork + 1;
+   17186           0 :                 PLUMED_BLAS_F77_FUNC(sgebrd,SGEBRD)(n, n, &a[a_offset], lda, &s[1], &work[ie], &work[
+   17187           0 :                         itauq], &work[itaup], &work[nwork], &i__1, &ierr);
+   17188           0 :                 nwork = ie + *n;
+   17189             : 
+   17190           0 :                 PLUMED_BLAS_F77_FUNC(sbdsdc,SBDSDC)("U", "N", n, &s[1], &work[ie], dum, &c__1, dum, &c__1,
+   17191           0 :                          dum, idum, &work[nwork], &iwork[1], info);
+   17192             : 
+   17193             :             } else {
+   17194             :                 iu = 1;
+   17195             : 
+   17196           0 :                 ldwrku = *n;
+   17197           0 :                 itau = iu + ldwrku * *n;
+   17198           0 :                 nwork = itau + *n;
+   17199             : 
+   17200           0 :                 i__1 = *lwork - nwork + 1;
+   17201           0 :                 PLUMED_BLAS_F77_FUNC(sgeqrf,SGEQRF)(m, n, &a[a_offset], lda, &work[itau], &work[nwork], &
+   17202             :                         i__1, &ierr);
+   17203           0 :                 PLUMED_BLAS_F77_FUNC(slacpy,SLACPY)("L", m, n, &a[a_offset], lda, &u[u_offset], ldu);
+   17204             : 
+   17205           0 :                 i__1 = *lwork - nwork + 1;
+   17206           0 :                 PLUMED_BLAS_F77_FUNC(sorgqr,SORGQR)(m, m, n, &u[u_offset], ldu, &work[itau], &work[nwork],
+   17207             :                          &i__1, &ierr);
+   17208             : 
+   17209           0 :                 i__1 = *n - 1;
+   17210           0 :                 i__2 = *n - 1;
+   17211           0 :                 PLUMED_BLAS_F77_FUNC(slaset,SLASET)("L", &i__1, &i__2, &zero, &zero, &a[a_dim1 + 2], 
+   17212             :                         lda);
+   17213             :                 ie = itau;
+   17214           0 :                 itauq = ie + *n;
+   17215           0 :                 itaup = itauq + *n;
+   17216           0 :                 nwork = itaup + *n;
+   17217             : 
+   17218           0 :                 i__1 = *lwork - nwork + 1;
+   17219           0 :                 PLUMED_BLAS_F77_FUNC(sgebrd,SGEBRD)(n, n, &a[a_offset], lda, &s[1], &work[ie], &work[
+   17220           0 :                         itauq], &work[itaup], &work[nwork], &i__1, &ierr);
+   17221             : 
+   17222           0 :                 PLUMED_BLAS_F77_FUNC(sbdsdc,SBDSDC)("U", "I", n, &s[1], &work[ie], &work[iu], n, &vt[
+   17223             :                         vt_offset], ldvt, dum, idum, &work[nwork], &iwork[1], 
+   17224             :                         info);
+   17225             : 
+   17226           0 :                 i__1 = *lwork - nwork + 1;
+   17227           0 :                 PLUMED_BLAS_F77_FUNC(sormbr,SORMBR)("Q", "L", "N", n, n, n, &a[a_offset], lda, &work[
+   17228             :                         itauq], &work[iu], &ldwrku, &work[nwork], &i__1, &
+   17229             :                         ierr);
+   17230           0 :                 i__1 = *lwork - nwork + 1;
+   17231           0 :                 PLUMED_BLAS_F77_FUNC(sormbr,SORMBR)("P", "R", "T", n, n, n, &a[a_offset], lda, &work[
+   17232             :                         itaup], &vt[vt_offset], ldvt, &work[nwork], &i__1, &
+   17233             :                         ierr);
+   17234             : 
+   17235           0 :                 PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("N", "N", m, n, n, &one, &u[u_offset], ldu, &work[iu]
+   17236             :                         , &ldwrku, &zero, &a[a_offset], lda);
+   17237             : 
+   17238           0 :                 PLUMED_BLAS_F77_FUNC(slacpy,SLACPY)("F", m, n, &a[a_offset], lda, &u[u_offset], ldu);
+   17239             : 
+   17240             :             }
+   17241             : 
+   17242             :         } else {
+   17243             :             ie = 1;
+   17244           0 :             itauq = ie + *n;
+   17245           0 :             itaup = itauq + *n;
+   17246           0 :             nwork = itaup + *n;
+   17247             : 
+   17248           0 :             i__1 = *lwork - nwork + 1;
+   17249           0 :             PLUMED_BLAS_F77_FUNC(sgebrd,SGEBRD)(m, n, &a[a_offset], lda, &s[1], &work[ie], &work[itauq], &
+   17250           0 :                     work[itaup], &work[nwork], &i__1, &ierr);
+   17251           0 :             if (wntqn) {
+   17252             : 
+   17253           0 :                 PLUMED_BLAS_F77_FUNC(sbdsdc,SBDSDC)("U", "N", n, &s[1], &work[ie], dum, &c__1, dum, &c__1,
+   17254             :                          dum, idum, &work[nwork], &iwork[1], info);
+   17255             :             } else {
+   17256             : 
+   17257           0 :                 PLUMED_BLAS_F77_FUNC(slaset,SLASET)("F", m, m, &zero, &zero, &u[u_offset], ldu);
+   17258           0 :                 PLUMED_BLAS_F77_FUNC(sbdsdc,SBDSDC)("U", "I", n, &s[1], &work[ie], &u[u_offset], ldu, &vt[
+   17259             :                         vt_offset], ldvt, dum, idum, &work[nwork], &iwork[1], 
+   17260             :                         info);
+   17261             : 
+   17262           0 :                 i__1 = *m - *n;
+   17263           0 :                 i__2 = *m - *n;
+   17264           0 :                 PLUMED_BLAS_F77_FUNC(slaset,SLASET)("F", &i__1, &i__2, &zero, &one, &u[*n + 1 + (*n + 
+   17265           0 :                         1) * u_dim1], ldu);
+   17266             : 
+   17267           0 :                 i__1 = *lwork - nwork + 1;
+   17268           0 :                 PLUMED_BLAS_F77_FUNC(sormbr,SORMBR)("Q", "L", "N", m, m, n, &a[a_offset], lda, &work[
+   17269             :                         itauq], &u[u_offset], ldu, &work[nwork], &i__1, &ierr);
+   17270           0 :                 i__1 = *lwork - nwork + 1;
+   17271           0 :                 PLUMED_BLAS_F77_FUNC(sormbr,SORMBR)("P", "R", "T", n, n, m, &a[a_offset], lda, &work[
+   17272             :                         itaup], &vt[vt_offset],ldvt,&work[nwork],&i__1,&ierr);
+   17273             :             }
+   17274             : 
+   17275             :         }
+   17276             : 
+   17277             :     } else {
+   17278             : 
+   17279           0 :         if (*n >= mnthr) {
+   17280             : 
+   17281           0 :             if (wntqn) {
+   17282             : 
+   17283             :                 itau = 1;
+   17284           0 :                 nwork = itau + *m;
+   17285             : 
+   17286           0 :                 i__1 = *lwork - nwork + 1;
+   17287           0 :                 PLUMED_BLAS_F77_FUNC(sgelqf,SGELQF)(m, n, &a[a_offset], lda, &work[itau], &work[nwork], &
+   17288             :                         i__1, &ierr);
+   17289             : 
+   17290           0 :                 i__1 = *m - 1;
+   17291           0 :                 i__2 = *m - 1;
+   17292           0 :                 PLUMED_BLAS_F77_FUNC(slaset,SLASET)("U", &i__1, &i__2, &zero, &zero, &a[(a_dim1*2) + 
+   17293           0 :                         1], lda);
+   17294             :                 ie = 1;
+   17295           0 :                 itauq = ie + *m;
+   17296           0 :                 itaup = itauq + *m;
+   17297           0 :                 nwork = itaup + *m;
+   17298             : 
+   17299           0 :                 i__1 = *lwork - nwork + 1;
+   17300           0 :                 PLUMED_BLAS_F77_FUNC(sgebrd,SGEBRD)(m, m, &a[a_offset], lda, &s[1], &work[ie], &work[
+   17301           0 :                         itauq], &work[itaup], &work[nwork], &i__1, &ierr);
+   17302           0 :                 nwork = ie + *m;
+   17303             : 
+   17304           0 :                 PLUMED_BLAS_F77_FUNC(sbdsdc,SBDSDC)("U", "N", m, &s[1], &work[ie], dum, &c__1, dum, &c__1,
+   17305           0 :                          dum, idum, &work[nwork], &iwork[1], info);
+   17306             : 
+   17307             :             } else {
+   17308             : 
+   17309             :                 ivt = 1;
+   17310             : 
+   17311           0 :                 ldwkvt = *m;
+   17312           0 :                 itau = ivt + ldwkvt * *m;
+   17313           0 :                 nwork = itau + *m;
+   17314             : 
+   17315           0 :                 i__1 = *lwork - nwork + 1;
+   17316           0 :                 PLUMED_BLAS_F77_FUNC(sgelqf,SGELQF)(m, n, &a[a_offset], lda, &work[itau], &work[nwork], &
+   17317             :                         i__1, &ierr);
+   17318           0 :                 PLUMED_BLAS_F77_FUNC(slacpy,SLACPY)("U", m, n, &a[a_offset], lda, &vt[vt_offset], ldvt);
+   17319             : 
+   17320           0 :                 i__1 = *lwork - nwork + 1;
+   17321           0 :                 PLUMED_BLAS_F77_FUNC(sorglq,SORGLQ)(n, n, m, &vt[vt_offset], ldvt, &work[itau], &work[
+   17322             :                         nwork], &i__1, &ierr);
+   17323             : 
+   17324           0 :                 i__1 = *m - 1;
+   17325           0 :                 i__2 = *m - 1;
+   17326           0 :                 PLUMED_BLAS_F77_FUNC(slaset,SLASET)("U", &i__1, &i__2, &zero, &zero, &a[(a_dim1*2) + 
+   17327           0 :                         1], lda);
+   17328             :                 ie = itau;
+   17329           0 :                 itauq = ie + *m;
+   17330           0 :                 itaup = itauq + *m;
+   17331           0 :                 nwork = itaup + *m;
+   17332             : 
+   17333           0 :                 i__1 = *lwork - nwork + 1;
+   17334           0 :                 PLUMED_BLAS_F77_FUNC(sgebrd,SGEBRD)(m, m, &a[a_offset], lda, &s[1], &work[ie], &work[
+   17335           0 :                         itauq], &work[itaup], &work[nwork], &i__1, &ierr);
+   17336             : 
+   17337           0 :                 PLUMED_BLAS_F77_FUNC(sbdsdc,SBDSDC)("U", "I", m, &s[1], &work[ie], &u[u_offset], ldu, &
+   17338             :                         work[ivt], &ldwkvt, dum, idum, &work[nwork], &iwork[1]
+   17339             :                         , info);
+   17340             : 
+   17341           0 :                 i__1 = *lwork - nwork + 1;
+   17342           0 :                 PLUMED_BLAS_F77_FUNC(sormbr,SORMBR)("Q", "L", "N", m, m, m, &a[a_offset], lda, &work[
+   17343             :                         itauq], &u[u_offset], ldu, &work[nwork], &i__1, &ierr);
+   17344           0 :                 i__1 = *lwork - nwork + 1;
+   17345           0 :                 PLUMED_BLAS_F77_FUNC(sormbr,SORMBR)("P", "R", "T", m, m, m, &a[a_offset], lda, &work[
+   17346             :                         itaup], &work[ivt], &ldwkvt, &work[nwork], &i__1, &
+   17347             :                         ierr);
+   17348             : 
+   17349           0 :                 PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("N", "N", m, n, m, &one, &work[ivt], &ldwkvt, &vt[
+   17350             :                         vt_offset], ldvt, &zero, &a[a_offset], lda);
+   17351             : 
+   17352           0 :                 PLUMED_BLAS_F77_FUNC(slacpy,SLACPY)("F", m, n, &a[a_offset], lda, &vt[vt_offset], ldvt);
+   17353             : 
+   17354             :             }
+   17355             : 
+   17356             :         } else {
+   17357             : 
+   17358             :             ie = 1;
+   17359           0 :             itauq = ie + *m;
+   17360           0 :             itaup = itauq + *m;
+   17361           0 :             nwork = itaup + *m;
+   17362             : 
+   17363           0 :             i__1 = *lwork - nwork + 1;
+   17364           0 :             PLUMED_BLAS_F77_FUNC(sgebrd,SGEBRD)(m, n, &a[a_offset], lda, &s[1], &work[ie], &work[itauq], &
+   17365           0 :                     work[itaup], &work[nwork], &i__1, &ierr);
+   17366           0 :             if (wntqn) {
+   17367             : 
+   17368           0 :                 PLUMED_BLAS_F77_FUNC(sbdsdc,SBDSDC)("L", "N", m, &s[1], &work[ie], dum, &c__1, dum, &c__1,
+   17369             :                          dum, idum, &work[nwork], &iwork[1], info);
+   17370             :             } else {
+   17371           0 :                 PLUMED_BLAS_F77_FUNC(slaset,SLASET)("F", n, n, &zero, &zero, &vt[vt_offset], ldvt);
+   17372           0 :                 PLUMED_BLAS_F77_FUNC(sbdsdc,SBDSDC)("L", "I", m, &s[1], &work[ie], &u[u_offset], ldu, &vt[
+   17373             :                         vt_offset], ldvt, dum, idum, &work[nwork], &iwork[1], 
+   17374             :                         info);
+   17375             : 
+   17376           0 :                 i__1 = *n - *m;
+   17377           0 :                 i__2 = *n - *m;
+   17378           0 :                 PLUMED_BLAS_F77_FUNC(slaset,SLASET)("F", &i__1, &i__2, &zero, &one, &vt[*m + 1 + (*m + 
+   17379           0 :                         1) * vt_dim1], ldvt);
+   17380             : 
+   17381           0 :                 i__1 = *lwork - nwork + 1;
+   17382           0 :                 PLUMED_BLAS_F77_FUNC(sormbr,SORMBR)("Q", "L", "N", m, m, n, &a[a_offset], lda, &work[
+   17383             :                         itauq], &u[u_offset], ldu, &work[nwork], &i__1, &ierr);
+   17384           0 :                 i__1 = *lwork - nwork + 1;
+   17385           0 :                 PLUMED_BLAS_F77_FUNC(sormbr,SORMBR)("P", "R", "T", n, n, m, &a[a_offset], lda, &work[
+   17386             :                         itaup], &vt[vt_offset], ldvt, &work[nwork], &i__1, &
+   17387             :                         ierr);
+   17388             :             }
+   17389             : 
+   17390             :         }
+   17391             : 
+   17392             :     }
+   17393             : 
+   17394           0 :     if (iscl == 1) {
+   17395           0 :         if (anrm > bignum) {
+   17396           0 :             PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G", &c__0, &c__0, &bignum, &anrm, &minmn, &c__1, &s[1], &
+   17397             :                     minmn, &ierr);
+   17398             :         }
+   17399           0 :         if (anrm < smlnum) {
+   17400           0 :             PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G", &c__0, &c__0, &smlnum, &anrm, &minmn, &c__1, &s[1], &
+   17401             :                     minmn, &ierr);
+   17402             :         }
+   17403             :     }
+   17404             : 
+   17405           0 :     work[1] = (float) maxwrk;
+   17406             : 
+   17407           0 :     return;
+   17408             : 
+   17409             : }
+   17410             : 
+   17411             : 
+   17412             : }
+   17413             : }
+   17414             : #include <cmath>
+   17415             : #include "real.h"
+   17416             : 
+   17417             : #include "blas/blas.h"
+   17418             : #include "lapack.h"
+   17419             : 
+   17420             : 
+   17421             : #include "blas/blas.h"
+   17422             : namespace PLMD{
+   17423             : namespace lapack{
+   17424             : using namespace blas;
+   17425             : void
+   17426           0 : PLUMED_BLAS_F77_FUNC(sgetf2,SGETF2)(int *m,
+   17427             :         int *n,
+   17428             :         float *a,
+   17429             :         int *lda,
+   17430             :         int *ipiv,
+   17431             :         int *info)
+   17432             : {
+   17433             :   int j,jp,k,t1,t2,t3;
+   17434             :   float minusone;
+   17435             :   float tmp;
+   17436             : 
+   17437           0 :   minusone = -1.0;
+   17438             : 
+   17439           0 :   if(*m<=0 || *n<=0)
+   17440             :     return;
+   17441             : 
+   17442             :   k = (*m < *n) ? *m : *n;
+   17443           0 :   for(j=1;j<=k;j++) {
+   17444           0 :     t1 = *m-j+1;
+   17445           0 :     t2 = 1;
+   17446           0 :     jp = j - 1 + PLUMED_BLAS_F77_FUNC(isamax,ISAMAX)(&t1,&(a[(j-1)*(*lda)+(j-1)]),&t2);
+   17447           0 :     ipiv[j-1] = jp;
+   17448           0 :     if( std::abs(a[(j-1)*(*lda)+(jp-1)])>PLUMED_GMX_FLOAT_MIN ) {
+   17449           0 :       if(jp != j)
+   17450           0 :         PLUMED_BLAS_F77_FUNC(sswap,SSWAP)(n,&(a[ j-1 ]),lda,&(a[ jp-1 ]),lda);
+   17451             :       
+   17452           0 :       if(j<*m) {
+   17453           0 :         t1 = *m-j;
+   17454           0 :         t2 = 1;
+   17455           0 :         tmp = 1.0/a[(j-1)*(*lda)+(j-1)];
+   17456           0 :         PLUMED_BLAS_F77_FUNC(sscal,SSCAL)(&t1,&tmp,&(a[(j-1)*(*lda)+(j)]),&t2);
+   17457             :       }
+   17458             :     } else {
+   17459           0 :       *info = j;
+   17460             :     }
+   17461             : 
+   17462           0 :     if(j<k) {
+   17463           0 :       t1 = *m-j;
+   17464           0 :       t2 = *n-j;
+   17465           0 :       t3 = 1;
+   17466           0 :       PLUMED_BLAS_F77_FUNC(sger,SGER)(&t1,&t2,&minusone,&(a[(j-1)*(*lda)+(j)]),&t3,
+   17467           0 :             &(a[(j)*(*lda)+(j-1)]),lda, &(a[(j)*(*lda)+(j)]),lda);
+   17468             :     }
+   17469             :   }
+   17470             :   return;
+   17471             : }
+   17472             : }
+   17473             : }
+   17474             : #include "blas/blas.h"
+   17475             : #include "lapack.h"
+   17476             : #include "lapack_limits.h"
+   17477             : 
+   17478             : #include "blas/blas.h"
+   17479             : namespace PLMD{
+   17480             : namespace lapack{
+   17481             : using namespace blas;
+   17482             : void
+   17483           0 : PLUMED_BLAS_F77_FUNC(sgetrf,SGETRF)(int *m,
+   17484             :         int *n,
+   17485             :         float *a,
+   17486             :         int *lda,
+   17487             :         int *ipiv,
+   17488             :         int *info)
+   17489             : {
+   17490             :   int mindim,jb;
+   17491             :   int i,j,k,l;
+   17492             :   int iinfo;
+   17493           0 :   float minusone = -1.0;
+   17494           0 :   float one = 1.0;
+   17495             : 
+   17496           0 :   if(*m<=0 || *n<=0)
+   17497           0 :     return;
+   17498             : 
+   17499           0 :   *info = 0;
+   17500             : 
+   17501           0 :   mindim = (*m < *n) ? *m : *n;
+   17502             : 
+   17503           0 :   if(DGETRF_BLOCKSIZE>=mindim) {
+   17504             : 
+   17505             :     /* unblocked code */
+   17506           0 :     PLUMED_BLAS_F77_FUNC(sgetf2,SGETF2)(m,n,a,lda,ipiv,info);
+   17507             : 
+   17508             :   } else {
+   17509             : 
+   17510             :     /* blocked case */
+   17511             : 
+   17512           0 :     for(j=1;j<=mindim;j+=DGETRF_BLOCKSIZE) {
+   17513           0 :       jb = ( DGETRF_BLOCKSIZE < (mindim-j+1)) ? DGETRF_BLOCKSIZE : (mindim-j+1);
+   17514             :       /* factor diag. and subdiag blocks and test for singularity */
+   17515           0 :       k = *m-j+1;
+   17516           0 :       PLUMED_BLAS_F77_FUNC(sgetf2,SGETF2)(&k,&jb,&(a[(j-1)*(*lda)+(j-1)]),lda,&(ipiv[j-1]),&iinfo);
+   17517             :       
+   17518           0 :       if(*info==0 && iinfo>0)
+   17519           0 :         *info = iinfo + j - 1;
+   17520             : 
+   17521             :       /* adjust pivot indices */
+   17522           0 :       k = (*m < (j+jb-1)) ? *m : (j+jb-1);
+   17523           0 :       for(i=j;i<=k;i++)
+   17524           0 :         ipiv[i-1] += j - 1;
+   17525             : 
+   17526             :       /* Apply to columns 1 throughj j-1 */
+   17527           0 :       k = j - 1;
+   17528           0 :       i = j + jb - 1;
+   17529           0 :       l = 1;
+   17530           0 :       PLUMED_BLAS_F77_FUNC(slaswp,SLASWP)(&k,a,lda,&j,&i,ipiv,&l);
+   17531           0 :       if((j+jb)<=*n) {
+   17532             :         /* Apply to cols. j+jb through n */
+   17533           0 :         k = *n-j-jb+1;
+   17534           0 :         i = j+jb-1;
+   17535           0 :         l = 1;
+   17536           0 :         PLUMED_BLAS_F77_FUNC(slaswp,SLASWP)(&k,&(a[(j+jb-1)*(*lda)+0]),lda,&j,&i,ipiv,&l);
+   17537             :         /* Compute block row of U */
+   17538           0 :         k = *n-j-jb+1;
+   17539           0 :         PLUMED_BLAS_F77_FUNC(strsm,STRSM)("Left","Lower","No transpose","Unit",&jb,&k,&one,
+   17540           0 :                &(a[(j-1)*(*lda)+(j-1)]),lda,&(a[(j+jb-1)*(*lda)+(j-1)]),lda);
+   17541             : 
+   17542           0 :         if((j+jb)<=*m) {
+   17543             :           /* Update trailing submatrix */
+   17544           0 :           k = *m-j-jb+1;
+   17545           0 :           i = *n-j-jb+1;
+   17546           0 :           PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("No transpose","No transpose",&k,&i,&jb,&minusone,
+   17547           0 :                  &(a[(j-1)*(*lda)+(j+jb-1)]),lda,
+   17548           0 :                  &(a[(j+jb-1)*(*lda)+(j-1)]),lda,&one,
+   17549           0 :                  &(a[(j+jb-1)*(*lda)+(j+jb-1)]),lda);
+   17550             :         }
+   17551             : 
+   17552             :       }
+   17553             :     }
+   17554             :   }
+   17555             : }
+   17556             : }
+   17557             : }
+   17558             : #include "blas/blas.h"
+   17559             : #include "lapack.h"
+   17560             : #include "lapack_limits.h"
+   17561             : 
+   17562             : #include "blas/blas.h"
+   17563             : namespace PLMD{
+   17564             : namespace lapack{
+   17565             : using namespace blas;
+   17566             : void
+   17567           0 : PLUMED_BLAS_F77_FUNC(sgetri,SGETRI)(int *n, 
+   17568             :         float *a, 
+   17569             :         int *lda, 
+   17570             :         int *ipiv, 
+   17571             :         float *work, 
+   17572             :         int *lwork, 
+   17573             :         int *info)
+   17574             : {
+   17575             :     int a_dim1, a_offset, i__1, i__2, i__3;
+   17576             : 
+   17577             :     int i__, j, jb, nb, jj, jp, nn, iws;
+   17578             :     int nbmin;
+   17579             :     int ldwork;
+   17580             :     int lwkopt;
+   17581           0 :     int c__1 = 1;
+   17582           0 :     float c_b20 = -1.;
+   17583           0 :     float c_b22 = 1.;
+   17584             : 
+   17585           0 :     a_dim1 = *lda;
+   17586           0 :     a_offset = 1 + a_dim1;
+   17587           0 :     a -= a_offset;
+   17588             :     --ipiv;
+   17589           0 :     --work;
+   17590             : 
+   17591           0 :     *info = 0;
+   17592             :     nb = DGETRI_BLOCKSIZE;
+   17593           0 :     lwkopt = *n * nb;
+   17594           0 :     work[1] = (float) lwkopt;
+   17595             : 
+   17596           0 :     if (*n < 0) {
+   17597           0 :         *info = -1;
+   17598           0 :     } else if (*lda < (*n)) {
+   17599           0 :         *info = -3;
+   17600           0 :     } else if (*lwork < (*n) && *lwork!=-1) {
+   17601           0 :         *info = -6;
+   17602             :     }
+   17603           0 :     if (*info != 0) {
+   17604             :         i__1 = -(*info);
+   17605             :         return;
+   17606           0 :     } else if (*lwork == -1) {
+   17607             :         return;
+   17608             :     }
+   17609             : 
+   17610           0 :     if (*n == 0) {
+   17611             :         return;
+   17612             :     }
+   17613             : 
+   17614           0 :     PLUMED_BLAS_F77_FUNC(strtri,STRTRI)("Upper", "Non-unit", n, &a[a_offset], lda, info);
+   17615           0 :     if (*info > 0) {
+   17616             :         return;
+   17617             :     }
+   17618             : 
+   17619             :     nbmin = 2;
+   17620           0 :     ldwork = *n;
+   17621           0 :     if (nb > 1 && nb < *n) {
+   17622           0 :         i__1 = ldwork * nb;
+   17623           0 :         iws = (i__1>1) ? i__1 : 1;
+   17624           0 :         if (*lwork < iws) {
+   17625           0 :             nb = *lwork / ldwork;
+   17626             :             nbmin = DGETRI_MINBLOCKSIZE;
+   17627             :         }
+   17628             :     } else {
+   17629             :         iws = *n;
+   17630             :     }
+   17631             : 
+   17632           0 :     if (nb < nbmin || nb >= *n) {
+   17633             : 
+   17634           0 :         for (j = *n; j >= 1; --j) {
+   17635             : 
+   17636           0 :             i__1 = *n;
+   17637           0 :             for (i__ = j + 1; i__ <= i__1; ++i__) {
+   17638           0 :                 work[i__] = a[i__ + j * a_dim1];
+   17639           0 :                 a[i__ + j * a_dim1] = 0.;
+   17640             :             }
+   17641             : 
+   17642           0 :             if (j < *n) {
+   17643           0 :                 i__1 = *n - j;
+   17644           0 :                 PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("No transpose", n, &i__1, &c_b20, &a[(j + 1) * a_dim1 
+   17645           0 :                         + 1], lda, &work[j + 1], &c__1, &c_b22, &a[j * a_dim1 
+   17646           0 :                         + 1], &c__1);
+   17647             :             }
+   17648             :         }
+   17649             :     } else {
+   17650             : 
+   17651           0 :         nn = (*n - 1) / nb * nb + 1;
+   17652           0 :         i__1 = -nb;
+   17653           0 :         for (j = nn; i__1 < 0 ? j >= 1 : j <= 1; j += i__1) {
+   17654           0 :             i__2 = nb, i__3 = *n - j + 1;
+   17655           0 :             jb = (i__2<i__3) ? i__2 : i__3;
+   17656             : 
+   17657           0 :             i__2 = j + jb - 1;
+   17658           0 :             for (jj = j; jj <= i__2; ++jj) {
+   17659           0 :                 i__3 = *n;
+   17660           0 :                 for (i__ = jj + 1; i__ <= i__3; ++i__) {
+   17661           0 :                     work[i__ + (jj - j) * ldwork] = a[i__ + jj * a_dim1];
+   17662           0 :                     a[i__ + jj * a_dim1] = 0.;
+   17663             :                 }
+   17664             :             }
+   17665             : 
+   17666           0 :             if (j + jb <= *n) {
+   17667           0 :                 i__2 = *n - j - jb + 1;
+   17668           0 :                 PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("No transpose", "No transpose", n, &jb, &i__2, &c_b20, 
+   17669           0 :                         &a[(j + jb) * a_dim1 + 1], lda, &work[j + jb], &
+   17670           0 :                         ldwork, &c_b22, &a[j * a_dim1 + 1], lda);
+   17671             :             }
+   17672           0 :             PLUMED_BLAS_F77_FUNC(strsm,STRSM)("Right", "Lower", "No transpose", "Unit", n, &jb, &c_b22, &
+   17673           0 :                     work[j], &ldwork, &a[j * a_dim1 + 1], lda);
+   17674             :         }
+   17675             :     }
+   17676             : 
+   17677           0 :     for (j = *n - 1; j >= 1; --j) {
+   17678           0 :         jp = ipiv[j];
+   17679           0 :         if (jp != j) {
+   17680           0 :             PLUMED_BLAS_F77_FUNC(sswap,SSWAP)(n, &a[j * a_dim1 + 1], &c__1, &a[jp * a_dim1 + 1], &c__1);
+   17681             :         }
+   17682             :     }
+   17683             : 
+   17684           0 :     work[1] = (float) iws;
+   17685           0 :     return;
+   17686             : 
+   17687             : }
+   17688             : 
+   17689             : 
+   17690             : }
+   17691             : }
+   17692             : #include "blas/blas.h"
+   17693             : #include "lapack.h"
+   17694             : 
+   17695             : #include "blas/blas.h"
+   17696             : namespace PLMD{
+   17697             : namespace lapack{
+   17698             : using namespace blas;
+   17699             : void
+   17700           0 : PLUMED_BLAS_F77_FUNC(sgetrs,SGETRS)(const char *trans, 
+   17701             :         int *n, 
+   17702             :         int *nrhs, 
+   17703             :         float *a, 
+   17704             :         int *lda, 
+   17705             :         int *ipiv,
+   17706             :         float *b, 
+   17707             :         int *ldb, 
+   17708             :         int *info)
+   17709             : {
+   17710             :     int a_dim1, a_offset, b_dim1, b_offset;
+   17711             :     int notran;
+   17712           0 :     int c__1 = 1;
+   17713           0 :     int c_n1 = -1;
+   17714           0 :     float one = 1.0;
+   17715             : 
+   17716             :     a_dim1 = *lda;
+   17717             :     a_offset = 1 + a_dim1;
+   17718             :     a -= a_offset;
+   17719             :     --ipiv;
+   17720             :     b_dim1 = *ldb;
+   17721             :     b_offset = 1 + b_dim1;
+   17722             :     b -= b_offset;
+   17723             : 
+   17724           0 :     *info = 0;
+   17725           0 :     notran = (*trans=='N' || *trans=='n');
+   17726             : 
+   17727           0 :     if (*n <= 0 || *nrhs <= 0) 
+   17728             :         return;
+   17729             : 
+   17730           0 :     if (notran) {
+   17731           0 :         PLUMED_BLAS_F77_FUNC(slaswp,SLASWP)(nrhs, &b[b_offset], ldb, &c__1, n, &ipiv[1], &c__1);
+   17732           0 :         PLUMED_BLAS_F77_FUNC(strsm,STRSM)("Left", "Lower", "No transpose", "Unit", n, nrhs, &one, 
+   17733             :                &a[a_offset], lda, &b[b_offset], ldb);
+   17734             : 
+   17735           0 :         PLUMED_BLAS_F77_FUNC(strsm,STRSM)("Left", "Upper", "No transpose", "Non-unit", n, nrhs, &one, 
+   17736             :                &a[a_offset], lda, &b[b_offset], ldb);
+   17737             :     } else {
+   17738           0 :         PLUMED_BLAS_F77_FUNC(strsm,STRSM)("Left", "Upper", "Transpose", "Non-unit", n, nrhs, &one, 
+   17739             :                &a[a_offset], lda, &b[b_offset], ldb);
+   17740           0 :         PLUMED_BLAS_F77_FUNC(strsm,STRSM)("Left", "Lower", "Transpose", "Unit", n, nrhs, &one, 
+   17741             :                &a[a_offset], lda, &b[b_offset], ldb);
+   17742             : 
+   17743           0 :         PLUMED_BLAS_F77_FUNC(slaswp,SLASWP)(nrhs, &b[b_offset], ldb, &c__1, n, &ipiv[1], &c_n1);
+   17744             :     }
+   17745             : 
+   17746             :     return;
+   17747             : 
+   17748             : } 
+   17749             : }
+   17750             : }
+   17751             : #include <cmath>
+   17752             : #include "blas/blas.h"
+   17753             : #include "lapack.h"
+   17754             : 
+   17755             : 
+   17756             : #include "blas/blas.h"
+   17757             : namespace PLMD{
+   17758             : namespace lapack{
+   17759             : using namespace blas;
+   17760             : void 
+   17761           0 : PLUMED_BLAS_F77_FUNC(slabrd,SLABRD)(int *m, 
+   17762             :         int *n, 
+   17763             :         int *nb,
+   17764             :         float *a, 
+   17765             :         int *lda, 
+   17766             :         float *d__,
+   17767             :         float *e,
+   17768             :         float *tauq, 
+   17769             :         float *taup,
+   17770             :         float *x,
+   17771             :         int *ldx,
+   17772             :         float *y,
+   17773             :         int *ldy)
+   17774             : {
+   17775             :     int a_dim1, a_offset, x_dim1, x_offset, y_dim1, y_offset;
+   17776             :     int i__1, i__2, i__3;
+   17777           0 :     float one = 1.0;
+   17778           0 :     float minusone = -1.0;
+   17779           0 :     float zero = 0.0;
+   17780           0 :     int c__1 = 1;
+   17781             :     int i__;
+   17782             : 
+   17783           0 :     a_dim1 = *lda;
+   17784           0 :     a_offset = 1 + a_dim1;
+   17785           0 :     a -= a_offset;
+   17786           0 :     --d__;
+   17787           0 :     --e;
+   17788           0 :     --tauq;
+   17789           0 :     --taup;
+   17790           0 :     x_dim1 = *ldx;
+   17791           0 :     x_offset = 1 + x_dim1;
+   17792           0 :     x -= x_offset;
+   17793           0 :     y_dim1 = *ldy;
+   17794           0 :     y_offset = 1 + y_dim1;
+   17795           0 :     y -= y_offset;
+   17796             : 
+   17797           0 :     if (*m <= 0 || *n <= 0) {
+   17798             :         return;
+   17799             :     }
+   17800             : 
+   17801           0 :     if (*m >= *n) {
+   17802             : 
+   17803           0 :         i__1 = *nb;
+   17804           0 :         for (i__ = 1; i__ <= i__1; ++i__) {
+   17805             : 
+   17806           0 :             i__2 = *m - i__ + 1;
+   17807           0 :             i__3 = i__ - 1;
+   17808           0 :             PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("No transpose", &i__2, &i__3, &minusone, &a[i__ + a_dim1], lda,
+   17809           0 :                      &y[i__ + y_dim1], ldy, &one, &a[i__ + i__ * a_dim1], &c__1);
+   17810           0 :             i__2 = *m - i__ + 1;
+   17811           0 :             i__3 = i__ - 1;
+   17812           0 :             PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("No transpose", &i__2, &i__3, &minusone, &x[i__ + x_dim1], ldx,
+   17813           0 :                    &a[i__*a_dim1+1],&c__1,&one,&a[i__+i__*a_dim1],&c__1);
+   17814             : 
+   17815           0 :             i__2 = *m - i__ + 1;
+   17816           0 :             i__3 = i__ + 1;
+   17817           0 :             if(*m<i__3)
+   17818           0 :               i__3 = *m;
+   17819           0 :             PLUMED_BLAS_F77_FUNC(slarfg,SLARFG)(&i__2, &a[i__ + i__ * a_dim1], &a[i__3 + i__ * a_dim1], 
+   17820           0 :                     &c__1, &tauq[i__]);
+   17821           0 :             d__[i__] = a[i__ + i__ * a_dim1];
+   17822           0 :             if (i__ < *n) {
+   17823           0 :                 a[i__ + i__ * a_dim1] = 1.;
+   17824             : 
+   17825           0 :                 i__2 = *m - i__ + 1;
+   17826           0 :                 i__3 = *n - i__;
+   17827           0 :                 PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("Transpose", &i__2, &i__3, &one, &a[i__ + (i__ + 1) * 
+   17828           0 :                         a_dim1], lda, &a[i__ + i__ * a_dim1], &c__1, &zero, &
+   17829           0 :                         y[i__ + 1 + i__ * y_dim1], &c__1);
+   17830           0 :                 i__2 = *m - i__ + 1;
+   17831           0 :                 i__3 = i__ - 1;
+   17832           0 :                 PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("Transpose", &i__2, &i__3, &one, &a[i__ + a_dim1], 
+   17833           0 :                         lda, &a[i__ + i__ * a_dim1], &c__1, &zero, &y[i__ * 
+   17834           0 :                         y_dim1 + 1], &c__1);
+   17835           0 :                 i__2 = *n - i__;
+   17836           0 :                 i__3 = i__ - 1;
+   17837           0 :                 PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("No transpose", &i__2, &i__3, &minusone, &y[i__ + 1 + 
+   17838           0 :                         y_dim1], ldy, &y[i__ * y_dim1 + 1], &c__1, &one, &y[
+   17839           0 :                         i__ + 1 + i__ * y_dim1], &c__1);
+   17840           0 :                 i__2 = *m - i__ + 1;
+   17841           0 :                 i__3 = i__ - 1;
+   17842           0 :                 PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("Transpose", &i__2, &i__3, &one, &x[i__ + x_dim1], 
+   17843           0 :                         ldx, &a[i__ + i__ * a_dim1], &c__1, &zero, &y[i__ * 
+   17844           0 :                         y_dim1 + 1], &c__1);
+   17845           0 :                 i__2 = i__ - 1;
+   17846           0 :                 i__3 = *n - i__;
+   17847           0 :                 PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("Transpose", &i__2, &i__3, &minusone, &a[(i__ + 1) * 
+   17848           0 :                         a_dim1 + 1], lda, &y[i__ * y_dim1 + 1], &c__1, &one, 
+   17849           0 :                         &y[i__ + 1 + i__ * y_dim1], &c__1);
+   17850           0 :                 i__2 = *n - i__;
+   17851           0 :                 PLUMED_BLAS_F77_FUNC(sscal,SSCAL)(&i__2, &tauq[i__], &y[i__ + 1 + i__ * y_dim1], &c__1);
+   17852             : 
+   17853           0 :                 i__2 = *n - i__;
+   17854           0 :                 PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("No transpose", &i__2, &i__, &minusone, &y[i__ + 1 + 
+   17855           0 :                         y_dim1], ldy, &a[i__ + a_dim1], lda, &one, &a[i__ + (
+   17856           0 :                         i__ + 1) * a_dim1], lda);
+   17857           0 :                 i__2 = i__ - 1;
+   17858           0 :                 i__3 = *n - i__;
+   17859           0 :                 PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("Transpose", &i__2, &i__3, &minusone, &a[(i__ + 1) * 
+   17860           0 :                         a_dim1 + 1], lda, &x[i__ + x_dim1], ldx, &one, &a[
+   17861           0 :                         i__ + (i__ + 1) * a_dim1], lda);
+   17862             : 
+   17863           0 :                 i__2 = *n - i__;
+   17864           0 :                 i__3 = i__ + 2;
+   17865           0 :                 if(*n<i__3)
+   17866           0 :                   i__3 = *n;
+   17867           0 :                 PLUMED_BLAS_F77_FUNC(slarfg,SLARFG)(&i__2, &a[i__ + (i__ + 1) * a_dim1], 
+   17868           0 :                         &a[i__ + i__3 * a_dim1], lda, &taup[i__]);
+   17869           0 :                 e[i__] = a[i__ + (i__ + 1) * a_dim1];
+   17870           0 :                 a[i__ + (i__ + 1) * a_dim1] = 1.;
+   17871             : 
+   17872           0 :                 i__2 = *m - i__;
+   17873           0 :                 i__3 = *n - i__;
+   17874           0 :                 PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("No transpose", &i__2, &i__3, &one, &a[i__ + 1 + (i__ 
+   17875           0 :                         + 1) * a_dim1], lda, &a[i__ + (i__ + 1) * a_dim1], 
+   17876           0 :                         lda, &zero, &x[i__ + 1 + i__ * x_dim1], &c__1);
+   17877           0 :                 i__2 = *n - i__;
+   17878           0 :                 PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("Transpose", &i__2, &i__, &one, &y[i__ + 1 + y_dim1], 
+   17879           0 :                         ldy, &a[i__ + (i__ + 1) * a_dim1], lda, &zero, &x[
+   17880           0 :                         i__ * x_dim1 + 1], &c__1);
+   17881           0 :                 i__2 = *m - i__;
+   17882           0 :                 PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("No transpose", &i__2, &i__, &minusone, &a[i__ + 1 + 
+   17883           0 :                         a_dim1], lda, &x[i__ * x_dim1 + 1], &c__1, &one, &x[
+   17884           0 :                         i__ + 1 + i__ * x_dim1], &c__1);
+   17885           0 :                 i__2 = i__ - 1;
+   17886           0 :                 i__3 = *n - i__;
+   17887           0 :                 PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("No transpose", &i__2, &i__3, &one, &a[(i__ + 1) * 
+   17888           0 :                         a_dim1 + 1], lda, &a[i__ + (i__ + 1) * a_dim1], lda, &
+   17889           0 :                         zero, &x[i__ * x_dim1 + 1], &c__1);
+   17890           0 :                 i__2 = *m - i__;
+   17891           0 :                 i__3 = i__ - 1;
+   17892           0 :                 PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("No transpose", &i__2, &i__3, &minusone, &x[i__ + 1 + 
+   17893           0 :                         x_dim1], ldx, &x[i__ * x_dim1 + 1], &c__1, &one, &x[
+   17894           0 :                         i__ + 1 + i__ * x_dim1], &c__1);
+   17895           0 :                 i__2 = *m - i__;
+   17896           0 :                 PLUMED_BLAS_F77_FUNC(sscal,SSCAL)(&i__2, &taup[i__], &x[i__ + 1 + i__ * x_dim1], &c__1);
+   17897             :             }
+   17898             :         }
+   17899             :     } else {
+   17900             : 
+   17901           0 :         i__1 = *nb;
+   17902           0 :         for (i__ = 1; i__ <= i__1; ++i__) {
+   17903             : 
+   17904           0 :             i__2 = *n - i__ + 1;
+   17905           0 :             i__3 = i__ - 1;
+   17906           0 :             PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("No transpose", &i__2, &i__3, &minusone, &y[i__ + y_dim1], ldy,
+   17907           0 :                      &a[i__ + a_dim1], lda, &one, &a[i__ + i__ * a_dim1],lda);
+   17908           0 :             i__2 = i__ - 1;
+   17909           0 :             i__3 = *n - i__ + 1;
+   17910           0 :             PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("Transpose", &i__2, &i__3, &minusone, &a[i__ * a_dim1 + 1], 
+   17911           0 :                     lda, &x[i__ + x_dim1], ldx, &one,&a[i__+i__*a_dim1],lda);
+   17912             : 
+   17913           0 :             i__2 = *n - i__ + 1;
+   17914           0 :             i__3 = i__ + 1;
+   17915           0 :             if(*n<i__3)
+   17916           0 :               i__3 = *n;
+   17917           0 :             PLUMED_BLAS_F77_FUNC(slarfg,SLARFG)(&i__2, &a[i__ + i__ * a_dim1], 
+   17918           0 :                     &a[i__ + i__3 * a_dim1], lda, &taup[i__]);
+   17919           0 :             d__[i__] = a[i__ + i__ * a_dim1];
+   17920           0 :             if (i__ < *m) {
+   17921           0 :                 a[i__ + i__ * a_dim1] = 1.;
+   17922             : 
+   17923           0 :                 i__2 = *m - i__;
+   17924           0 :                 i__3 = *n - i__ + 1;
+   17925           0 :                 PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("No transpose",&i__2,&i__3,&one,&a[i__+1+i__*a_dim1], 
+   17926             :                        lda, &a[i__ + i__ * a_dim1], lda, &zero, 
+   17927           0 :                        &x[i__ + 1 + i__ * x_dim1], &c__1);
+   17928           0 :                 i__2 = *n - i__ + 1;
+   17929           0 :                 i__3 = i__ - 1;
+   17930           0 :                 PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("Transpose", &i__2, &i__3, &one, &y[i__ + y_dim1], 
+   17931           0 :                         ldy, &a[i__ + i__ * a_dim1], lda, &zero, &x[i__ * 
+   17932           0 :                         x_dim1 + 1], &c__1);
+   17933           0 :                 i__2 = *m - i__;
+   17934           0 :                 i__3 = i__ - 1;
+   17935           0 :                 PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("No transpose", &i__2, &i__3, &minusone, &a[i__ + 1 + 
+   17936           0 :                         a_dim1], lda, &x[i__ * x_dim1 + 1], &c__1, &one, &x[
+   17937           0 :                         i__ + 1 + i__ * x_dim1], &c__1);
+   17938           0 :                 i__2 = i__ - 1;
+   17939           0 :                 i__3 = *n - i__ + 1;
+   17940           0 :                 PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("No transpose", &i__2, &i__3, &one, &a[i__ * a_dim1 + 
+   17941           0 :                         1], lda, &a[i__ + i__ * a_dim1], lda, &zero, &x[i__ *
+   17942           0 :                          x_dim1 + 1], &c__1);
+   17943           0 :                 i__2 = *m - i__;
+   17944           0 :                 i__3 = i__ - 1;
+   17945           0 :                 PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("No transpose", &i__2, &i__3, &minusone, &x[i__ + 1 + 
+   17946           0 :                         x_dim1], ldx, &x[i__ * x_dim1 + 1], &c__1, &one, &x[
+   17947           0 :                         i__ + 1 + i__ * x_dim1], &c__1);
+   17948           0 :                 i__2 = *m - i__;
+   17949           0 :                 PLUMED_BLAS_F77_FUNC(sscal,SSCAL)(&i__2, &taup[i__], &x[i__ + 1 + i__ * x_dim1], &c__1);
+   17950             : 
+   17951           0 :                 i__2 = *m - i__;
+   17952           0 :                 i__3 = i__ - 1;
+   17953           0 :                 PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("No transpose", &i__2, &i__3, &minusone, &a[i__ + 1 + 
+   17954           0 :                         a_dim1], lda, &y[i__ + y_dim1], ldy, &one, &a[i__ + 
+   17955           0 :                         1 + i__ * a_dim1], &c__1);
+   17956           0 :                 i__2 = *m - i__;
+   17957           0 :                 PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("No transpose", &i__2, &i__, &minusone, &x[i__ + 1 + 
+   17958           0 :                         x_dim1], ldx, &a[i__ * a_dim1 + 1], &c__1, &one, &a[
+   17959           0 :                         i__ + 1 + i__ * a_dim1], &c__1);
+   17960             : 
+   17961           0 :                 i__2 = *m - i__;
+   17962           0 :                 i__3 = i__ + 2;
+   17963           0 :                 if(*m<i__3)
+   17964           0 :                   i__3 = *m;
+   17965           0 :                 PLUMED_BLAS_F77_FUNC(slarfg,SLARFG)(&i__2, &a[i__ + 1 + i__ * a_dim1], 
+   17966           0 :                         &a[i__3 + i__ * a_dim1], &c__1, &tauq[i__]);
+   17967           0 :                 e[i__] = a[i__ + 1 + i__ * a_dim1];
+   17968           0 :                 a[i__ + 1 + i__ * a_dim1] = 1.;
+   17969             : 
+   17970           0 :                 i__2 = *m - i__;
+   17971           0 :                 i__3 = *n - i__;
+   17972           0 :                 PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("Transpose", &i__2, &i__3, &one, &a[i__ + 1 + (i__ + 
+   17973           0 :                         1) * a_dim1], lda, &a[i__ + 1 + i__ * a_dim1], &c__1, 
+   17974           0 :                         &zero, &y[i__ + 1 + i__ * y_dim1], &c__1);
+   17975           0 :                 i__2 = *m - i__;
+   17976           0 :                 i__3 = i__ - 1;
+   17977           0 :                 PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("Transpose", &i__2, &i__3, &one, &a[i__ + 1 + a_dim1],
+   17978           0 :                          lda, &a[i__ + 1 + i__ * a_dim1], &c__1, &zero, &y[
+   17979           0 :                         i__ * y_dim1 + 1], &c__1);
+   17980           0 :                 i__2 = *n - i__;
+   17981           0 :                 i__3 = i__ - 1;
+   17982           0 :                 PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("No transpose", &i__2, &i__3, &minusone, &y[i__ + 1 + 
+   17983           0 :                         y_dim1], ldy, &y[i__ * y_dim1 + 1], &c__1, &one, &y[
+   17984           0 :                         i__ + 1 + i__ * y_dim1], &c__1);
+   17985           0 :                 i__2 = *m - i__;
+   17986           0 :                 PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("Transpose", &i__2, &i__, &one, &x[i__ + 1 + x_dim1], 
+   17987           0 :                         ldx, &a[i__ + 1 + i__ * a_dim1], &c__1, &zero, &y[
+   17988           0 :                         i__ * y_dim1 + 1], &c__1);
+   17989           0 :                 i__2 = *n - i__;
+   17990           0 :                 PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("Transpose", &i__, &i__2, &minusone, &a[(i__ + 1) * a_dim1 
+   17991           0 :                         + 1], lda, &y[i__ * y_dim1 + 1], &c__1, &one, &y[i__ 
+   17992           0 :                         + 1 + i__ * y_dim1], &c__1);
+   17993           0 :                 i__2 = *n - i__;
+   17994           0 :                 PLUMED_BLAS_F77_FUNC(sscal,SSCAL)(&i__2, &tauq[i__], &y[i__ + 1 + i__ * y_dim1], &c__1);
+   17995             :             }
+   17996             :         }
+   17997             :     }
+   17998             :     return;
+   17999             : } 
+   18000             : 
+   18001             : }
+   18002             : }
+   18003             : #include <cctype>
+   18004             : #include "lapack.h"
+   18005             : 
+   18006             : /* LAPACK */
+   18007             : #include "blas/blas.h"
+   18008             : namespace PLMD{
+   18009             : namespace lapack{
+   18010             : using namespace blas;
+   18011             : void
+   18012           0 : PLUMED_BLAS_F77_FUNC(slacpy,SLACPY)(const char *uplo,
+   18013             :         int *m,
+   18014             :         int *n,
+   18015             :         float *a,
+   18016             :         int *lda,
+   18017             :         float *b,
+   18018             :         int *ldb)
+   18019             : {
+   18020             :   int i,j,minjm;
+   18021           0 :   const char ch=std::toupper(*uplo);
+   18022             : 
+   18023           0 :   if(ch=='U') {
+   18024           0 :     for(j=0;j<*n;j++) {
+   18025           0 :       minjm = (j < (*m-1)) ? j : (*m-1);
+   18026           0 :       for(i=0;i<=minjm;i++)
+   18027           0 :         b[j*(*ldb)+i] = a[j*(*lda)+i];
+   18028             :     }
+   18029           0 :   } else if(ch=='L') {
+   18030           0 :     for(j=0;j<*n;j++) {
+   18031           0 :       for(i=j;i<*m;i++)
+   18032           0 :         b[j*(*ldb)+i] = a[j*(*lda)+i];
+   18033             :     }
+   18034             :   } else {
+   18035           0 :     for(j=0;j<*n;j++) {
+   18036           0 :       for(i=0;i<*m;i++)
+   18037           0 :         b[j*(*ldb)+i] = a[j*(*lda)+i];
+   18038             :     }    
+   18039             :   }
+   18040           0 : }
+   18041             : }
+   18042             : }
+   18043             : #include <cmath>
+   18044             : #include "lapack.h"
+   18045             : 
+   18046             : 
+   18047             : #include "blas/blas.h"
+   18048             : namespace PLMD{
+   18049             : namespace lapack{
+   18050             : using namespace blas;
+   18051             : void
+   18052           0 : PLUMED_BLAS_F77_FUNC(slae2,SLAE2)(float *a, 
+   18053             :        float *b,
+   18054             :        float *c__, 
+   18055             :        float *rt1, 
+   18056             :        float *rt2)
+   18057             : {
+   18058             :     float d__1;
+   18059             :     float ab, df, tb, sm, rt, adf, acmn, acmx;
+   18060             : 
+   18061             : 
+   18062           0 :     sm = *a + *c__;
+   18063           0 :     df = *a - *c__;
+   18064             :     adf = std::abs(df);
+   18065           0 :     tb = *b + *b;
+   18066             :     ab = std::abs(tb);
+   18067           0 :     if (std::abs(*a) > std::abs(*c__)) {
+   18068             :         acmx = *a;
+   18069             :         acmn = *c__;
+   18070             :     } else {
+   18071             :         acmx = *c__;
+   18072             :         acmn = *a;
+   18073             :     }
+   18074           0 :     if (adf > ab) {
+   18075           0 :         d__1 = ab / adf;
+   18076           0 :         rt = adf *  std::sqrt(d__1 * d__1 + 1.);
+   18077           0 :     } else if (adf < ab) {
+   18078           0 :         d__1 = adf / ab;
+   18079           0 :         rt = ab *  std::sqrt(d__1 * d__1 + 1.);
+   18080             :     } else {
+   18081             : 
+   18082           0 :         rt = ab *  std::sqrt(2.);
+   18083             :     }
+   18084           0 :     if (sm < 0.) {
+   18085           0 :         *rt1 = (sm - rt) * .5;
+   18086           0 :         *rt2 = acmx / *rt1 * acmn - *b / *rt1 * *b;
+   18087           0 :     } else if (sm > 0.) {
+   18088           0 :         *rt1 = (sm + rt) * .5;
+   18089           0 :         *rt2 = acmx / *rt1 * acmn - *b / *rt1 * *b;
+   18090             :     } else {
+   18091           0 :         *rt1 = rt * .5;
+   18092           0 :         *rt2 = rt * -.5;
+   18093             :     }
+   18094           0 :     return;
+   18095             : 
+   18096             : }
+   18097             : 
+   18098             : 
+   18099             : }
+   18100             : }
+   18101             : #include <cmath>
+   18102             : #include "lapack.h"
+   18103             : 
+   18104             : #include "blas/blas.h"
+   18105             : namespace PLMD{
+   18106             : namespace lapack{
+   18107             : using namespace blas;
+   18108             : void
+   18109           0 : PLUMED_BLAS_F77_FUNC(slaebz,SLAEBZ)(int *ijob,
+   18110             :         int *nitmax,
+   18111             :         int *n, 
+   18112             :         int *mmax,
+   18113             :         int *minp,
+   18114             :         int *nbmin,
+   18115             :         float *abstol, 
+   18116             :         float *reltol, 
+   18117             :         float *pivmin, 
+   18118             :         float *d__,
+   18119             :         float *e,
+   18120             :         float *e2, 
+   18121             :         int *nval,
+   18122             :         float *ab, 
+   18123             :         float *c__, 
+   18124             :         int *mout, 
+   18125             :         int *nab,
+   18126             :         float *work,
+   18127             :         int *iwork, 
+   18128             :         int *info)
+   18129             : {
+   18130             :     int nab_dim1, nab_offset, ab_dim1, ab_offset, i__1, i__2, i__3, i__4, 
+   18131             :             i__5, i__6;
+   18132             :     float d__1, d__2, d__3, d__4;
+   18133             : 
+   18134             :     int j, kf, ji, kl, jp, jit;
+   18135             :     float tmp1, tmp2;
+   18136             :     int itmp1, itmp2, kfnew, klnew;
+   18137             : 
+   18138           0 :     nab_dim1 = *mmax;
+   18139           0 :     nab_offset = 1 + nab_dim1;
+   18140           0 :     nab -= nab_offset;
+   18141             :     ab_dim1 = *mmax;
+   18142             :     ab_offset = 1 + ab_dim1;
+   18143           0 :     ab -= ab_offset;
+   18144           0 :     --d__;
+   18145             :     --e;
+   18146           0 :     --e2;
+   18147           0 :     --nval;
+   18148           0 :     --c__;
+   18149           0 :     --work;
+   18150           0 :     --iwork;
+   18151             : 
+   18152           0 :     *info = 0;
+   18153           0 :     if (*ijob < 1 || *ijob > 3) {
+   18154           0 :         *info = -1;
+   18155           0 :         return;
+   18156             :     }
+   18157             : 
+   18158           0 :     if (*ijob == 1) {
+   18159             : 
+   18160           0 :         *mout = 0;
+   18161             : 
+   18162           0 :         i__1 = *minp;
+   18163           0 :         for (ji = 1; ji <= i__1; ++ji) {
+   18164           0 :             for (jp = 1; jp <= 2; ++jp) {
+   18165           0 :                 tmp1 = d__[1] - ab[ji + jp * ab_dim1];
+   18166           0 :                 if (std::abs(tmp1) < *pivmin) {
+   18167           0 :                     tmp1 = -(*pivmin);
+   18168             :                 }
+   18169           0 :                 nab[ji + jp * nab_dim1] = 0;
+   18170           0 :                 if (tmp1 <= 0.) {
+   18171           0 :                     nab[ji + jp * nab_dim1] = 1;
+   18172             :                 }
+   18173             : 
+   18174           0 :                 i__2 = *n;
+   18175           0 :                 for (j = 2; j <= i__2; ++j) {
+   18176           0 :                     tmp1 = d__[j] - e2[j - 1] / tmp1 - ab[ji + jp * ab_dim1];
+   18177           0 :                     if (std::abs(tmp1) < *pivmin) {
+   18178           0 :                         tmp1 = -(*pivmin);
+   18179             :                     }
+   18180           0 :                     if (tmp1 <= 0.) {
+   18181           0 :                         ++nab[ji + jp * nab_dim1];
+   18182             :                     }
+   18183             :                 }
+   18184             :             }
+   18185           0 :             *mout = *mout + nab[ji + (nab_dim1 << 1)] - nab[ji + nab_dim1];
+   18186             :         }
+   18187             :         return;
+   18188             :     }
+   18189             : 
+   18190             :     kf = 1;
+   18191           0 :     kl = *minp;
+   18192             : 
+   18193           0 :     if (*ijob == 2) {
+   18194             :         i__1 = *minp;
+   18195           0 :         for (ji = 1; ji <= i__1; ++ji) {
+   18196           0 :             c__[ji] = (ab[ji + ab_dim1] + ab[ji + (ab_dim1 << 1)]) * .5;
+   18197             :         }
+   18198             :     }
+   18199             : 
+   18200           0 :     i__1 = *nitmax;
+   18201           0 :     for (jit = 1; jit <= i__1; ++jit) {
+   18202             : 
+   18203           0 :         if (kl - kf + 1 >= *nbmin && *nbmin > 0) {
+   18204             : 
+   18205             :             i__2 = kl;
+   18206           0 :             for (ji = kf; ji <= i__2; ++ji) {
+   18207             : 
+   18208           0 :                 work[ji] = d__[1] - c__[ji];
+   18209           0 :                 iwork[ji] = 0;
+   18210           0 :                 if (work[ji] <= *pivmin) {
+   18211           0 :                     iwork[ji] = 1;
+   18212           0 :                     d__1 = work[ji], d__2 = -(*pivmin);
+   18213           0 :                     work[ji] = (d__1<d__2) ? d__1 : d__2;
+   18214             :                 }
+   18215             : 
+   18216           0 :                 i__3 = *n;
+   18217           0 :                 for (j = 2; j <= i__3; ++j) {
+   18218           0 :                     work[ji] = d__[j] - e2[j - 1] / work[ji] - c__[ji];
+   18219           0 :                     if (work[ji] <= *pivmin) {
+   18220           0 :                         ++iwork[ji];
+   18221           0 :                         d__1 = work[ji], d__2 = -(*pivmin);
+   18222           0 :                         work[ji] = (d__1<d__2) ? d__1 : d__2;
+   18223             :                     }
+   18224             :                 }
+   18225             :             }
+   18226             : 
+   18227           0 :             if (*ijob <= 2) {
+   18228             : 
+   18229             :                 klnew = kl;
+   18230             :                 i__2 = kl;
+   18231           0 :                 for (ji = kf; ji <= i__2; ++ji) {
+   18232             : 
+   18233           0 :                   i__5 = nab[ji + nab_dim1];
+   18234           0 :                   i__6 = iwork[ji];
+   18235           0 :                   i__3 = nab[ji + (nab_dim1 << 1)];
+   18236             :                   i__4 = (i__5>i__6) ? i__5 : i__6;
+   18237           0 :                     iwork[ji] = (i__3<i__4) ? i__3 : i__4;
+   18238             : 
+   18239           0 :                     if (iwork[ji] == nab[ji + (nab_dim1 << 1)]) {
+   18240             : 
+   18241           0 :                         ab[ji + (ab_dim1 << 1)] = c__[ji];
+   18242             : 
+   18243           0 :                     } else if (iwork[ji] == nab[ji + nab_dim1]) {
+   18244             : 
+   18245           0 :                         ab[ji + ab_dim1] = c__[ji];
+   18246             :                     } else {
+   18247           0 :                         ++klnew;
+   18248           0 :                         if (klnew <= *mmax) {
+   18249             : 
+   18250           0 :                             ab[klnew + (ab_dim1 << 1)] = ab[ji + (ab_dim1 << 
+   18251           0 :                                     1)];
+   18252           0 :                             nab[klnew + (nab_dim1 << 1)] = nab[ji + (nab_dim1 
+   18253           0 :                                     << 1)];
+   18254           0 :                             ab[klnew + ab_dim1] = c__[ji];
+   18255           0 :                             nab[klnew + nab_dim1] = iwork[ji];
+   18256           0 :                             ab[ji + (ab_dim1 << 1)] = c__[ji];
+   18257           0 :                             nab[ji + (nab_dim1 << 1)] = iwork[ji];
+   18258             :                         } else {
+   18259           0 :                             *info = *mmax + 1;
+   18260             :                         }
+   18261             :                     }
+   18262             :                 }
+   18263           0 :                 if (*info != 0) {
+   18264             :                     return;
+   18265             :                 }
+   18266             :                 kl = klnew;
+   18267             :             } else {
+   18268             : 
+   18269             :                 i__2 = kl;
+   18270           0 :                 for (ji = kf; ji <= i__2; ++ji) {
+   18271           0 :                     if (iwork[ji] <= nval[ji]) {
+   18272           0 :                         ab[ji + ab_dim1] = c__[ji];
+   18273           0 :                         nab[ji + nab_dim1] = iwork[ji];
+   18274             :                     }
+   18275           0 :                     if (iwork[ji] >= nval[ji]) {
+   18276           0 :                         ab[ji + (ab_dim1 << 1)] = c__[ji];
+   18277           0 :                         nab[ji + (nab_dim1 << 1)] = iwork[ji];
+   18278             :                     }
+   18279             :                 }
+   18280             :             }
+   18281             : 
+   18282             :         } else {
+   18283             : 
+   18284             :             klnew = kl;
+   18285             :             i__2 = kl;
+   18286           0 :             for (ji = kf; ji <= i__2; ++ji) {
+   18287             : 
+   18288           0 :                 tmp1 = c__[ji];
+   18289           0 :                 tmp2 = d__[1] - tmp1;
+   18290             :                 itmp1 = 0;
+   18291           0 :                 if (tmp2 <= *pivmin) {
+   18292             :                     itmp1 = 1;
+   18293           0 :                     d__1 = tmp2, d__2 = -(*pivmin);
+   18294           0 :                     tmp2 = (d__1<d__2) ? d__1 : d__2;
+   18295             :                 }
+   18296             : 
+   18297           0 :                 i__3 = *n;
+   18298           0 :                 for (j = 2; j <= i__3; ++j) {
+   18299           0 :                     tmp2 = d__[j] - e2[j - 1] / tmp2 - tmp1;
+   18300           0 :                     if (tmp2 <= *pivmin) {
+   18301           0 :                         ++itmp1;
+   18302           0 :                         d__1 = tmp2, d__2 = -(*pivmin);
+   18303           0 :                         tmp2 = (d__1<d__2) ? d__1 : d__2;
+   18304             :                     }
+   18305             :                 }
+   18306             : 
+   18307           0 :                 if (*ijob <= 2) {
+   18308             : 
+   18309           0 :                     i__5 = nab[ji + nab_dim1];
+   18310           0 :                     i__3 = nab[ji + (nab_dim1 << 1)];
+   18311             :                     i__4 = (i__5>itmp1) ? i__5 : itmp1;
+   18312             :                     itmp1 = (i__3<i__4) ? i__3 : i__4;
+   18313             : 
+   18314           0 :                     if (itmp1 == nab[ji + (nab_dim1 << 1)]) {
+   18315             : 
+   18316           0 :                         ab[ji + (ab_dim1 << 1)] = tmp1;
+   18317             : 
+   18318           0 :                     } else if (itmp1 == nab[ji + nab_dim1]) {
+   18319             : 
+   18320           0 :                         ab[ji + ab_dim1] = tmp1;
+   18321           0 :                     } else if (klnew < *mmax) {
+   18322             : 
+   18323           0 :                         ++klnew;
+   18324           0 :                         ab[klnew + (ab_dim1 << 1)] = ab[ji + (ab_dim1 << 1)];
+   18325           0 :                         nab[klnew + (nab_dim1 << 1)] = nab[ji + (nab_dim1 << 
+   18326           0 :                                 1)];
+   18327           0 :                         ab[klnew + ab_dim1] = tmp1;
+   18328           0 :                         nab[klnew + nab_dim1] = itmp1;
+   18329           0 :                         ab[ji + (ab_dim1 << 1)] = tmp1;
+   18330           0 :                         nab[ji + (nab_dim1 << 1)] = itmp1;
+   18331             :                     } else {
+   18332           0 :                         *info = *mmax + 1;
+   18333           0 :                         return;
+   18334             :                     }
+   18335             :                 } else {
+   18336             : 
+   18337           0 :                     if (itmp1 <= nval[ji]) {
+   18338           0 :                         ab[ji + ab_dim1] = tmp1;
+   18339           0 :                         nab[ji + nab_dim1] = itmp1;
+   18340             :                     }
+   18341           0 :                     if (itmp1 >= nval[ji]) {
+   18342           0 :                         ab[ji + (ab_dim1 << 1)] = tmp1;
+   18343           0 :                         nab[ji + (nab_dim1 << 1)] = itmp1;
+   18344             :                     }
+   18345             :                 }
+   18346             :             }
+   18347             :             kl = klnew;
+   18348             : 
+   18349             :         }
+   18350             : 
+   18351             :         kfnew = kf;
+   18352             :         i__2 = kl;
+   18353           0 :         for (ji = kf; ji <= i__2; ++ji) {
+   18354           0 :             tmp1 = std::abs(ab[ji + (ab_dim1 << 1)] - ab[ji + ab_dim1]);
+   18355             :             d__3 = std::abs(ab[ji + (ab_dim1 << 1)]);
+   18356             :             d__4 = std::abs(ab[ji + ab_dim1]);
+   18357           0 :             tmp2 = (d__3>d__4) ? d__3 : d__4;
+   18358           0 :             d__1 = (*abstol>*pivmin) ? *abstol : *pivmin;
+   18359           0 :             d__2 = *reltol * tmp2;
+   18360           0 :             if (tmp1 < ((d__1>d__2) ? d__1 : d__2) || nab[ji + nab_dim1] >= nab[ji + (
+   18361           0 :                     nab_dim1 << 1)]) {
+   18362             : 
+   18363           0 :                 if (ji > kfnew) {
+   18364             :                     tmp1 = ab[ji + ab_dim1];
+   18365             :                     tmp2 = ab[ji + (ab_dim1 << 1)];
+   18366           0 :                     itmp1 = nab[ji + nab_dim1];
+   18367           0 :                     itmp2 = nab[ji + (nab_dim1 << 1)];
+   18368           0 :                     ab[ji + ab_dim1] = ab[kfnew + ab_dim1];
+   18369           0 :                     ab[ji + (ab_dim1 << 1)] = ab[kfnew + (ab_dim1 << 1)];
+   18370           0 :                     nab[ji + nab_dim1] = nab[kfnew + nab_dim1];
+   18371           0 :                     nab[ji + (nab_dim1 << 1)] = nab[kfnew + (nab_dim1 << 1)];
+   18372           0 :                     ab[kfnew + ab_dim1] = tmp1;
+   18373           0 :                     ab[kfnew + (ab_dim1 << 1)] = tmp2;
+   18374           0 :                     nab[kfnew + nab_dim1] = itmp1;
+   18375           0 :                     nab[kfnew + (nab_dim1 << 1)] = itmp2;
+   18376           0 :                     if (*ijob == 3) {
+   18377           0 :                         itmp1 = nval[ji];
+   18378           0 :                         nval[ji] = nval[kfnew];
+   18379           0 :                         nval[kfnew] = itmp1;
+   18380             :                     }
+   18381             :                 }
+   18382           0 :                 ++kfnew;
+   18383             :             }
+   18384             :         }
+   18385             :         kf = kfnew;
+   18386             : 
+   18387             :         i__2 = kl;
+   18388           0 :         for (ji = kf; ji <= i__2; ++ji) {
+   18389           0 :             c__[ji] = (ab[ji + ab_dim1] + ab[ji + (ab_dim1 << 1)]) * .5;
+   18390             :         }
+   18391             : 
+   18392           0 :         if (kf > kl) {
+   18393             :             break;
+   18394             :         }
+   18395             :     }
+   18396             : 
+   18397           0 :     i__1 = kl + 1 - kf;
+   18398           0 :     if(i__1>0)
+   18399           0 :       *info = i__1;
+   18400             : 
+   18401           0 :     *mout = kl;
+   18402             : 
+   18403           0 :     return;
+   18404             : 
+   18405             : }
+   18406             : 
+   18407             : 
+   18408             : }
+   18409             : }
+   18410             : #include <cmath>
+   18411             : 
+   18412             : #include "lapack.h"
+   18413             : 
+   18414             : #include "real.h"
+   18415             : 
+   18416             : #include "blas/blas.h"
+   18417             : namespace PLMD{
+   18418             : namespace lapack{
+   18419             : using namespace blas;
+   18420             : void
+   18421           0 : PLUMED_BLAS_F77_FUNC(slaed6,SLAED6)(int *kniter, 
+   18422             :                         int *orgati, 
+   18423             :                         float *rho, 
+   18424             :                         float *d__,
+   18425             :                         float *z__, 
+   18426             :                         float *finit, 
+   18427             :                         float *tau, 
+   18428             :                         int *info)
+   18429             : {
+   18430             :     int i__1;
+   18431             :     float r__1, r__2, r__3, r__4;
+   18432             : 
+   18433             :     float a, b, c__, f;
+   18434             :     int i__;
+   18435             :     float fc, df, ddf, eta, eps, base;
+   18436             :     int iter;
+   18437             :     float temp, temp1, temp2, temp3, temp4;
+   18438             :     int scale;
+   18439             :     int niter;
+   18440             :     float small1, small2, sminv1, sminv2, dscale[3], sclfac;
+   18441             :     float zscale[3], erretm;
+   18442             :     float safemin;
+   18443             :     float sclinv = 0;
+   18444             :     
+   18445           0 :     --z__;
+   18446           0 :     --d__;
+   18447             : 
+   18448           0 :     *info = 0;
+   18449             : 
+   18450             :     niter = 1;
+   18451           0 :     *tau = 0.f;
+   18452           0 :     if (*kniter == 2) {
+   18453           0 :         if (*orgati) {
+   18454           0 :             temp = (d__[3] - d__[2]) / 2.f;
+   18455           0 :             c__ = *rho + z__[1] / (d__[1] - d__[2] - temp);
+   18456           0 :             a = c__ * (d__[2] + d__[3]) + z__[2] + z__[3];
+   18457           0 :             b = c__ * d__[2] * d__[3] + z__[2] * d__[3] + z__[3] * d__[2];
+   18458             :         } else {
+   18459           0 :             temp = (d__[1] - d__[2]) / 2.f;
+   18460           0 :             c__ = *rho + z__[3] / (d__[3] - d__[2] - temp);
+   18461           0 :             a = c__ * (d__[1] + d__[2]) + z__[1] + z__[2];
+   18462           0 :             b = c__ * d__[1] * d__[2] + z__[1] * d__[2] + z__[2] * d__[1];
+   18463             :         }
+   18464           0 :         r__1 = std::abs(a), r__2 = std::abs(b), r__1 = ((r__1>r__2)? r__1:r__2), r__2 = std::abs(c__);
+   18465           0 :         temp = (r__1>r__2) ? r__1 : r__2;
+   18466           0 :         a /= temp;
+   18467           0 :         b /= temp;
+   18468           0 :         c__ /= temp;
+   18469           0 :         if (c__ == 0.f) {
+   18470           0 :             *tau = b / a;
+   18471           0 :         } else if (a <= 0.f) {
+   18472           0 :             *tau = (a -  std::sqrt((r__1 = a * a - b * 4.f * c__, std::abs(r__1)))) / (
+   18473           0 :                     c__ * 2.f);
+   18474             :         } else {
+   18475           0 :             *tau = b * 2.f / (a +  std::sqrt((r__1 = a * a - b * 4.f * c__, std::abs(r__1))));
+   18476             :         }
+   18477             : 
+   18478           0 :         temp = *rho + z__[1] / (d__[1] - *tau) + z__[2] / (d__[2] - *tau) + 
+   18479           0 :                 z__[3] / (d__[3] - *tau);
+   18480           0 :         if (std::abs(*finit) <= std::abs(temp)) {
+   18481           0 :             *tau = 0.f;
+   18482             :         }
+   18483             :     }
+   18484             : 
+   18485             :     eps = PLUMED_GMX_FLOAT_EPS;
+   18486             :     base = 2;
+   18487             :     safemin = PLUMED_GMX_FLOAT_MIN*(1.0+PLUMED_GMX_FLOAT_EPS);
+   18488             :     i__1 = static_cast<int>(std::log(safemin) / std::log(base) / 3.f);
+   18489             :     small1 = std::pow(base, static_cast<float>(i__1));
+   18490             :     sminv1 = 1.f / small1;
+   18491             :     small2 = small1 * small1;
+   18492             :     sminv2 = sminv1 * sminv1;
+   18493             : 
+   18494           0 :     if (*orgati) {
+   18495           0 :         r__3 = (r__1 = d__[2] - *tau, std::abs(r__1)), r__4 = (r__2 = d__[3] - *
+   18496             :                 tau, std::abs(r__2));
+   18497           0 :         temp = (r__3<r__4) ? r__3 : r__4;
+   18498             :     } else {
+   18499           0 :         r__3 = (r__1 = d__[1] - *tau, std::abs(r__1)), r__4 = (r__2 = d__[2] - *
+   18500             :                 tau, std::abs(r__2));
+   18501           0 :         temp = (r__3<r__4) ? r__3 : r__4;
+   18502             :     }
+   18503             :     scale = 0;
+   18504           0 :     if (temp <= small1) {
+   18505             :         scale = 1;
+   18506           0 :         if (temp <= small2) {
+   18507             : 
+   18508             :             sclfac = sminv2;
+   18509             :             sclinv = small2;
+   18510             :         } else {
+   18511             : 
+   18512             :             sclfac = sminv1;
+   18513             :             sclinv = small1;
+   18514             : 
+   18515             :         }
+   18516             : 
+   18517           0 :         for (i__ = 1; i__ <= 3; ++i__) {
+   18518           0 :             dscale[i__ - 1] = d__[i__] * sclfac;
+   18519           0 :             zscale[i__ - 1] = z__[i__] * sclfac;
+   18520             :         }
+   18521           0 :         *tau *= sclfac;
+   18522             :     } else {
+   18523             : 
+   18524           0 :         for (i__ = 1; i__ <= 3; ++i__) {
+   18525           0 :             dscale[i__ - 1] = d__[i__];
+   18526           0 :             zscale[i__ - 1] = z__[i__];
+   18527             :         }
+   18528             :     }
+   18529             :     fc = 0.f;
+   18530             :     df = 0.f;
+   18531             :     ddf = 0.f;
+   18532           0 :     for (i__ = 1; i__ <= 3; ++i__) {
+   18533           0 :         temp = 1.f / (dscale[i__ - 1] - *tau);
+   18534           0 :         temp1 = zscale[i__ - 1] * temp;
+   18535           0 :         temp2 = temp1 * temp;
+   18536           0 :         temp3 = temp2 * temp;
+   18537           0 :         fc += temp1 / dscale[i__ - 1];
+   18538           0 :         df += temp2;
+   18539           0 :         ddf += temp3;
+   18540             :     }
+   18541           0 :     f = *finit + *tau * fc;
+   18542             : 
+   18543           0 :     if (std::abs(f) <= 0.f) {
+   18544           0 :         goto L60;
+   18545             :     }
+   18546             :     iter = niter + 1;
+   18547           0 :     for (niter = iter; niter <= 20; ++niter) {
+   18548           0 :         if (*orgati) {
+   18549           0 :             temp1 = dscale[1] - *tau;
+   18550           0 :             temp2 = dscale[2] - *tau;
+   18551             :         } else {
+   18552           0 :             temp1 = dscale[0] - *tau;
+   18553           0 :             temp2 = dscale[1] - *tau;
+   18554             :         }
+   18555           0 :         a = (temp1 + temp2) * f - temp1 * temp2 * df;
+   18556           0 :         b = temp1 * temp2 * f;
+   18557           0 :         c__ = f - (temp1 + temp2) * df + temp1 * temp2 * ddf;
+   18558           0 :         r__1 = std::abs(a), r__2 = std::abs(b), r__1 = ((r__1>r__2)? r__1:r__2), r__2 = std::abs(c__);
+   18559           0 :         temp = (r__1>r__2) ? r__1 : r__2;
+   18560           0 :         a /= temp;
+   18561           0 :         b /= temp;
+   18562           0 :         c__ /= temp;
+   18563           0 :         if (c__ == 0.f) {
+   18564           0 :             eta = b / a;
+   18565           0 :         } else if (a <= 0.f) {
+   18566           0 :             eta = (a -  std::sqrt((r__1 = a * a - b * 4.f * c__, std::abs(r__1)))) / ( c__ * 2.f);
+   18567             :         } else {
+   18568           0 :             eta = b * 2.f / (a +  std::sqrt((r__1 = a * a - b * 4.f * c__, std::abs( r__1))));
+   18569             :         }
+   18570           0 :         if (f * eta >= 0.f) {
+   18571           0 :             eta = -f / df;
+   18572             :         }
+   18573           0 :         temp = eta + *tau;
+   18574           0 :         if (*orgati) {
+   18575           0 :             if (eta > 0.f && temp >= dscale[2]) {
+   18576           0 :                 eta = (dscale[2] - *tau) / 2.f;
+   18577             :             }
+   18578             : 
+   18579           0 :             if (eta < 0.f && temp <= dscale[1]) {
+   18580           0 :                 eta = (dscale[1] - *tau) / 2.f;
+   18581             :             }
+   18582             :         } else {
+   18583           0 :             if (eta > 0.f && temp >= dscale[1]) {
+   18584           0 :                 eta = (dscale[1] - *tau) / 2.f;
+   18585             :             }
+   18586           0 :             if (eta < 0.f && temp <= dscale[0]) {
+   18587           0 :                 eta = (dscale[0] - *tau) / 2.f;
+   18588             :             }
+   18589             :         }
+   18590           0 :         *tau += eta;
+   18591             :         fc = 0.f;
+   18592             :         erretm = 0.f;
+   18593             :         df = 0.f;
+   18594             :         ddf = 0.f;
+   18595           0 :         for (i__ = 1; i__ <= 3; ++i__) {
+   18596           0 :             temp = 1.f / (dscale[i__ - 1] - *tau);
+   18597           0 :             temp1 = zscale[i__ - 1] * temp;
+   18598           0 :             temp2 = temp1 * temp;
+   18599           0 :             temp3 = temp2 * temp;
+   18600           0 :             temp4 = temp1 / dscale[i__ - 1];
+   18601           0 :             fc += temp4;
+   18602           0 :             erretm += std::abs(temp4);
+   18603           0 :             df += temp2;
+   18604           0 :             ddf += temp3;
+   18605             :         }
+   18606           0 :         f = *finit + *tau * fc;
+   18607           0 :         erretm = (std::abs(*finit) + std::abs(*tau) * erretm) * 8.f + std::abs(*tau) * df;
+   18608           0 :         if (std::abs(f) <= eps * erretm) {
+   18609           0 :             goto L60;
+   18610             :         }
+   18611             :     }
+   18612           0 :     *info = 1;
+   18613           0 : L60:
+   18614           0 :     if (scale) {
+   18615           0 :         *tau *= sclinv;
+   18616             :     }
+   18617           0 :     return;
+   18618             : } 
+   18619             : 
+   18620             : 
+   18621             : }
+   18622             : }
+   18623             : #include <cmath>
+   18624             : #include "real.h"
+   18625             : 
+   18626             : #include "lapack.h"
+   18627             : 
+   18628             : 
+   18629             : #include "blas/blas.h"
+   18630             : namespace PLMD{
+   18631             : namespace lapack{
+   18632             : using namespace blas;
+   18633             : void
+   18634           0 : PLUMED_BLAS_F77_FUNC(slaev2,SLAEV2)(float *   a, 
+   18635             :         float *   b, 
+   18636             :         float *   c__, 
+   18637             :         float *   rt1, 
+   18638             :         float *   rt2, 
+   18639             :         float *   cs1, 
+   18640             :         float *   sn1)
+   18641             : {
+   18642             :     float d__1;
+   18643             : 
+   18644             :     float ab, df, cs, ct, tb, sm, tn, rt, adf, acs;
+   18645             :     int sgn1, sgn2;
+   18646             :     float acmn, acmx;
+   18647             : 
+   18648           0 :     sm = *a + *c__;
+   18649           0 :     df = *a - *c__;
+   18650             :     adf = std::abs(df);
+   18651           0 :     tb = *b + *b;
+   18652             :     ab = std::abs(tb);
+   18653           0 :     if (std::abs(*a) > std::abs(*c__)) {
+   18654             :         acmx = *a;
+   18655             :         acmn = *c__;
+   18656             :     } else {
+   18657             :         acmx = *c__;
+   18658             :         acmn = *a;
+   18659             :     }
+   18660           0 :     if (adf > ab) {
+   18661           0 :         d__1 = ab / adf;
+   18662           0 :         rt = adf *  std::sqrt(d__1 * d__1 + 1.);
+   18663           0 :     } else if (adf < ab) {
+   18664           0 :         d__1 = adf / ab;
+   18665           0 :         rt = ab *  std::sqrt(d__1 * d__1 + 1.);
+   18666             :     } else {
+   18667             : 
+   18668           0 :         rt = ab *  std::sqrt(2.);
+   18669             :     }
+   18670           0 :     if (sm < 0.) {
+   18671           0 :         *rt1 = (sm - rt) * .5;
+   18672             :         sgn1 = -1;
+   18673             : 
+   18674           0 :         *rt2 = acmx / *rt1 * acmn - *b / *rt1 * *b;
+   18675           0 :     } else if (sm > 0.) {
+   18676           0 :         *rt1 = (sm + rt) * .5;
+   18677             :         sgn1 = 1;
+   18678           0 :         *rt2 = acmx / *rt1 * acmn - *b / *rt1 * *b;
+   18679             :     } else {
+   18680           0 :         *rt1 = rt * .5;
+   18681           0 :         *rt2 = rt * -.5;
+   18682             :         sgn1 = 1;
+   18683             :     }
+   18684           0 :     if (df >= 0.) {
+   18685           0 :         cs = df + rt;
+   18686             :         sgn2 = 1;
+   18687             :     } else {
+   18688           0 :         cs = df - rt;
+   18689             :         sgn2 = -1;
+   18690             :     }
+   18691             :     acs = std::abs(cs);
+   18692           0 :     if (acs > ab) {
+   18693           0 :         ct = -tb / cs;
+   18694           0 :         *sn1 = 1. /  std::sqrt(ct * ct + 1.);
+   18695           0 :         *cs1 = ct * *sn1;
+   18696             :     } else {
+   18697           0 :         if (std::abs(ab)<PLUMED_GMX_FLOAT_MIN) {
+   18698           0 :             *cs1 = 1.;
+   18699           0 :             *sn1 = 0.;
+   18700             :         } else {
+   18701           0 :             tn = -cs / tb;
+   18702           0 :             *cs1 = 1. /  std::sqrt(tn * tn + 1.);
+   18703           0 :             *sn1 = tn * *cs1;
+   18704             :         }
+   18705             :     }
+   18706           0 :     if (sgn1 == sgn2) {
+   18707           0 :         tn = *cs1;
+   18708           0 :         *cs1 = -(*sn1);
+   18709           0 :         *sn1 = tn;
+   18710             :     }
+   18711           0 :     return;
+   18712             : 
+   18713             : }
+   18714             : 
+   18715             : 
+   18716             : }
+   18717             : }
+   18718             : #include <cmath>
+   18719             : #include "real.h"
+   18720             : 
+   18721             : #include "lapack.h"
+   18722             : #include "lapack_limits.h"
+   18723             : 
+   18724             : 
+   18725             : 
+   18726             : #include "blas/blas.h"
+   18727             : namespace PLMD{
+   18728             : namespace lapack{
+   18729             : using namespace blas;
+   18730             : void
+   18731           0 : PLUMED_BLAS_F77_FUNC(slagtf,SLAGTF)(int *n, 
+   18732             :         float *a, 
+   18733             :         float *lambda, 
+   18734             :         float *b, 
+   18735             :         float *c__, 
+   18736             :         float *tol, 
+   18737             :         float *d__, 
+   18738             :         int *in, 
+   18739             :         int *info)
+   18740             : {
+   18741             :     int i__1;
+   18742             : 
+   18743             :     int k;
+   18744             :     float tl, eps, piv1, piv2, temp, mult, scale1, scale2;
+   18745             : 
+   18746           0 :     --in;
+   18747           0 :     --d__;
+   18748           0 :     --c__;
+   18749           0 :     --b;
+   18750           0 :     --a;
+   18751             : 
+   18752           0 :     *info = 0;
+   18753           0 :     if (*n < 0) {
+   18754           0 :         *info = -1;
+   18755           0 :         return;
+   18756             :     }
+   18757             : 
+   18758           0 :     if (*n == 0) 
+   18759             :         return;
+   18760             :     
+   18761           0 :     a[1] -= *lambda;
+   18762           0 :     in[*n] = 0;
+   18763           0 :     if (*n == 1) {
+   18764           0 :         if (std::abs(a[1])<PLUMED_GMX_FLOAT_MIN) {
+   18765           0 :             in[1] = 1;
+   18766             :         }
+   18767           0 :         return;
+   18768             :     }
+   18769             : 
+   18770             :     eps = PLUMED_GMX_FLOAT_EPS;
+   18771             : 
+   18772           0 :     tl = (*tol>eps) ? *tol : eps;
+   18773           0 :     scale1 = std::abs(a[1]) + std::abs(b[1]);
+   18774             :     i__1 = *n - 1;
+   18775           0 :     for (k = 1; k <= i__1; ++k) {
+   18776           0 :         a[k + 1] -= *lambda;
+   18777           0 :         scale2 = std::abs(c__[k]) + std::abs(a[k + 1]);
+   18778           0 :         if (k < *n - 1) {
+   18779           0 :             scale2 += std::abs(b[k + 1]);
+   18780             :         }
+   18781           0 :         if (std::abs(a[k])<PLUMED_GMX_FLOAT_MIN) {
+   18782             :             piv1 = 0.;
+   18783             :         } else {
+   18784           0 :             piv1 = std::abs(a[k]) / scale1;
+   18785             :         }
+   18786           0 :         if (std::abs(c__[k])<PLUMED_GMX_FLOAT_MIN) {
+   18787           0 :             in[k] = 0;
+   18788             :             piv2 = 0.;
+   18789             :             scale1 = scale2;
+   18790           0 :             if (k < *n - 1) {
+   18791           0 :                 d__[k] = 0.;
+   18792             :             }
+   18793             :         } else {
+   18794           0 :             piv2 = std::abs(c__[k]) / scale2;
+   18795           0 :             if (piv2 <= piv1) {
+   18796           0 :                 in[k] = 0;
+   18797             :                 scale1 = scale2;
+   18798           0 :                 c__[k] /= a[k];
+   18799           0 :                 a[k + 1] -= c__[k] * b[k];
+   18800           0 :                 if (k < *n - 1) {
+   18801           0 :                     d__[k] = 0.;
+   18802             :                 }
+   18803             :             } else {
+   18804           0 :                 in[k] = 1;
+   18805           0 :                 mult = a[k] / c__[k];
+   18806           0 :                 a[k] = c__[k];
+   18807           0 :                 temp = a[k + 1];
+   18808           0 :                 a[k + 1] = b[k] - mult * temp;
+   18809           0 :                 if (k < *n - 1) {
+   18810           0 :                     d__[k] = b[k + 1];
+   18811           0 :                     b[k + 1] = -mult * d__[k];
+   18812             :                 }
+   18813           0 :                 b[k] = temp;
+   18814           0 :                 c__[k] = mult;
+   18815             :             }
+   18816             :         }
+   18817           0 :         if (((piv1>piv2) ? piv1 : piv2) <= tl && in[*n] == 0) {
+   18818           0 :             in[*n] = k;
+   18819             :         }
+   18820             :     }
+   18821           0 :     if (std::abs(a[*n]) <= scale1 * tl && in[*n] == 0) {
+   18822           0 :         in[*n] = *n;
+   18823             :     }
+   18824             : 
+   18825             :     return;
+   18826             : 
+   18827             : }
+   18828             : 
+   18829             : 
+   18830             : }
+   18831             : }
+   18832             : #include <stdlib.h>
+   18833             : #include <cmath>
+   18834             : #include "real.h"
+   18835             : 
+   18836             : #include "lapack.h"
+   18837             : #include "lapack_limits.h"
+   18838             : 
+   18839             : 
+   18840             : #include "blas/blas.h"
+   18841             : namespace PLMD{
+   18842             : namespace lapack{
+   18843             : using namespace blas;
+   18844             : void
+   18845           0 : PLUMED_BLAS_F77_FUNC(slagts,SLAGTS)(int *job, 
+   18846             :         int *n, 
+   18847             :         float *a, 
+   18848             :         float *b, 
+   18849             :         float *c__, 
+   18850             :         float *d__, 
+   18851             :         int *in, 
+   18852             :         float *y, 
+   18853             :         float *tol, 
+   18854             :         int *info)
+   18855             : {
+   18856             :     int i__1;
+   18857             :     float d__1, d__2, d__4, d__5;
+   18858             : 
+   18859             :     int k;
+   18860             :     float ak, eps, temp, pert, absak, sfmin;
+   18861             :     float bignum,minval;
+   18862           0 :     --y;
+   18863           0 :     --in;
+   18864           0 :     --d__;
+   18865           0 :     --c__;
+   18866           0 :     --b;
+   18867           0 :     --a;
+   18868             : 
+   18869           0 :     *info = 0;
+   18870           0 :     if (abs(*job) > 2 || *job == 0) {
+   18871           0 :         *info = -1;
+   18872           0 :     } else if (*n < 0) {
+   18873           0 :         *info = -2;
+   18874             :     }
+   18875           0 :     if (*info != 0) {
+   18876             :         return;
+   18877             :     }
+   18878             : 
+   18879           0 :     if (*n == 0) {
+   18880             :         return;
+   18881             :     }
+   18882             :     eps = PLUMED_GMX_FLOAT_EPS;
+   18883             :     minval = PLUMED_GMX_FLOAT_MIN;
+   18884             :     sfmin = minval / eps;
+   18885             : 
+   18886             :     bignum = 1. / sfmin;
+   18887             : 
+   18888           0 :     if (*job < 0) {
+   18889           0 :         if (*tol <= 0.) {
+   18890           0 :             *tol = std::abs(a[1]);
+   18891           0 :             if (*n > 1) {
+   18892             :                 d__1 = *tol;
+   18893           0 :                 d__2 = std::abs(a[2]);
+   18894           0 :                 d__1 = (d__1>d__2) ? d__1 : d__2;
+   18895           0 :                 d__2 = std::abs(b[1]);
+   18896           0 :                 *tol = (d__1>d__2) ? d__1 : d__2;
+   18897             :             }
+   18898           0 :             i__1 = *n;
+   18899           0 :             for (k = 3; k <= i__1; ++k) {
+   18900           0 :               d__4 = *tol;
+   18901           0 :               d__5 = std::abs(a[k]);
+   18902           0 :               d__4 = (d__4>d__5) ? d__4 : d__5;
+   18903           0 :               d__5 = std::abs(b[k - 1]);
+   18904           0 :               d__4 = (d__4>d__5) ? d__4 : d__5;
+   18905           0 :               d__5 = std::abs(d__[k - 2]);
+   18906           0 :               *tol = (d__4>d__5) ? d__4 : d__5;
+   18907             :             }
+   18908           0 :             *tol *= eps;
+   18909           0 :             if (std::abs(*tol)<PLUMED_GMX_FLOAT_MIN) {
+   18910           0 :                 *tol = eps;
+   18911             :             }
+   18912             :         }
+   18913             :     }
+   18914             : 
+   18915           0 :     if (1 == abs(*job)) {
+   18916           0 :         i__1 = *n;
+   18917           0 :         for (k = 2; k <= i__1; ++k) {
+   18918           0 :             if (in[k - 1] == 0) {
+   18919           0 :                 y[k] -= c__[k - 1] * y[k - 1];
+   18920             :             } else {
+   18921           0 :                 temp = y[k - 1];
+   18922           0 :                 y[k - 1] = y[k];
+   18923           0 :                 y[k] = temp - c__[k - 1] * y[k];
+   18924             :             }
+   18925             :         }
+   18926           0 :         if (*job == 1) {
+   18927           0 :             for (k = *n; k >= 1; --k) {
+   18928           0 :                 if (k <= *n - 2) {
+   18929           0 :                     temp = y[k] - b[k] * y[k + 1] - d__[k] * y[k + 2];
+   18930           0 :                 } else if (k == *n - 1) {
+   18931           0 :                     temp = y[k] - b[k] * y[k + 1];
+   18932             :                 } else {
+   18933           0 :                     temp = y[k];
+   18934             :                 }
+   18935           0 :                 ak = a[k];
+   18936             :                 absak = std::abs(ak);
+   18937           0 :                 if (absak < 1.) {
+   18938           0 :                     if (absak < sfmin) {
+   18939           0 :                         if (std::abs(absak)<PLUMED_GMX_FLOAT_MIN || std::abs(temp) * sfmin > absak) {
+   18940           0 :                             *info = k;
+   18941           0 :                             return;
+   18942             :                         } else {
+   18943           0 :                             temp *= bignum;
+   18944           0 :                             ak *= bignum;
+   18945             :                         }
+   18946           0 :                     } else if (std::abs(temp) > absak * bignum) {
+   18947           0 :                         *info = k;
+   18948           0 :                         return;
+   18949             :                     }
+   18950             :                 }
+   18951           0 :                 y[k] = temp / ak;
+   18952             :             }
+   18953             :         } else {
+   18954           0 :             for (k = *n; k >= 1; --k) {
+   18955           0 :                 if (k + 2 <= *n) {
+   18956           0 :                     temp = y[k] - b[k] * y[k + 1] - d__[k] * y[k + 2];
+   18957           0 :                 } else if (k + 1 == *n) {
+   18958           0 :                     temp = y[k] - b[k] * y[k + 1];
+   18959             :                 } else {
+   18960           0 :                     temp = y[k];
+   18961             :                 }
+   18962           0 :                 ak = a[k];
+   18963             : 
+   18964           0 :                 pert = *tol;
+   18965           0 :                 if(ak<0)
+   18966           0 :                   pert *= -1.0;
+   18967           0 : L40:
+   18968             :                 absak = std::abs(ak);
+   18969           0 :                 if (absak < 1.) {
+   18970           0 :                     if (absak < sfmin) {
+   18971           0 :                         if (std::abs(absak)<PLUMED_GMX_FLOAT_MIN || std::abs(temp) * sfmin > absak) {
+   18972           0 :                             ak += pert;
+   18973           0 :                             pert *= 2;
+   18974           0 :                             goto L40;
+   18975             :                         } else {
+   18976           0 :                             temp *= bignum;
+   18977           0 :                             ak *= bignum;
+   18978             :                         }
+   18979           0 :                     } else if (std::abs(temp) > absak * bignum) {
+   18980           0 :                         ak += pert;
+   18981           0 :                         pert *= 2;
+   18982           0 :                         goto L40;
+   18983             :                     }
+   18984             :                 }
+   18985           0 :                 y[k] = temp / ak;
+   18986             :             }
+   18987             :         }
+   18988             :     } else {
+   18989             : 
+   18990           0 :         if (*job == 2) {
+   18991           0 :             i__1 = *n;
+   18992           0 :             for (k = 1; k <= i__1; ++k) {
+   18993           0 :                 if (k >= 3) {
+   18994           0 :                     temp = y[k] - b[k - 1] * y[k - 1] - d__[k - 2] * y[k - 2];
+   18995           0 :                 } else if (k == 2) {
+   18996           0 :                     temp = y[k] - b[k - 1] * y[k - 1];
+   18997             :                 } else {
+   18998           0 :                     temp = y[k];
+   18999             :                 }
+   19000           0 :                 ak = a[k];
+   19001             :                 absak = std::abs(ak);
+   19002           0 :                 if (absak < 1.) {
+   19003           0 :                     if (absak < sfmin) {
+   19004           0 :                         if (std::abs(absak)<PLUMED_GMX_FLOAT_MIN || std::abs(temp) * sfmin > absak) {
+   19005           0 :                             *info = k;
+   19006           0 :                             return;
+   19007             :                         } else {
+   19008           0 :                             temp *= bignum;
+   19009           0 :                             ak *= bignum;
+   19010             :                         }
+   19011           0 :                     } else if (std::abs(temp) > absak * bignum) {
+   19012           0 :                         *info = k;
+   19013           0 :                         return;
+   19014             :                     }
+   19015             :                 }
+   19016           0 :                 y[k] = temp / ak;
+   19017             :             }
+   19018             :         } else {
+   19019           0 :             i__1 = *n;
+   19020           0 :             for (k = 1; k <= i__1; ++k) {
+   19021           0 :                 if (k >= 3) {
+   19022           0 :                     temp = y[k] - b[k - 1] * y[k - 1] - d__[k - 2] * y[k - 2];
+   19023           0 :                 } else if (k == 2) {
+   19024           0 :                     temp = y[k] - b[k - 1] * y[k - 1];
+   19025             :                 } else {
+   19026           0 :                     temp = y[k];
+   19027             :                 }
+   19028           0 :                 ak = a[k];
+   19029             : 
+   19030           0 :                 pert = *tol;
+   19031           0 :                 if(ak<0)
+   19032           0 :                   pert *= -1.0;
+   19033             : 
+   19034           0 : L70:
+   19035             :                 absak = std::abs(ak);
+   19036           0 :                 if (absak < 1.) {
+   19037           0 :                     if (absak < sfmin) {
+   19038           0 :                         if (std::abs(absak)<PLUMED_GMX_FLOAT_MIN || std::abs(temp) * sfmin > absak) {
+   19039           0 :                             ak += pert;
+   19040           0 :                             pert *= 2;
+   19041           0 :                             goto L70;
+   19042             :                         } else {
+   19043           0 :                             temp *= bignum;
+   19044           0 :                             ak *= bignum;
+   19045             :                         }
+   19046           0 :                     } else if (std::abs(temp) > absak * bignum) {
+   19047           0 :                         ak += pert;
+   19048           0 :                         pert *= 2;
+   19049           0 :                         goto L70;
+   19050             :                     }
+   19051             :                 }
+   19052           0 :                 y[k] = temp / ak;
+   19053             :             }
+   19054             :         }
+   19055             : 
+   19056           0 :         for (k = *n; k >= 2; --k) {
+   19057           0 :             if (in[k - 1] == 0) {
+   19058           0 :                 y[k - 1] -= c__[k - 1] * y[k];
+   19059             :             } else {
+   19060           0 :                 temp = y[k - 1];
+   19061           0 :                 y[k - 1] = y[k];
+   19062           0 :                 y[k] = temp - c__[k - 1] * y[k];
+   19063             :             }
+   19064             :         }
+   19065             :     }
+   19066             : 
+   19067             :     return;
+   19068             : }
+   19069             : 
+   19070             : 
+   19071             : }
+   19072             : }
+   19073             : #include "lapack.h"
+   19074             : 
+   19075             : 
+   19076             : /* LAPACK */
+   19077             : 
+   19078             : 
+   19079             : #include "blas/blas.h"
+   19080             : namespace PLMD{
+   19081             : namespace lapack{
+   19082             : using namespace blas;
+   19083             : void
+   19084           0 : PLUMED_BLAS_F77_FUNC(slamrg,SLAMRG)(int *n1,
+   19085             :                         int *n2,
+   19086             :                         float *a,
+   19087             :                         int *dtrd1,
+   19088             :                         int *dtrd2,
+   19089             :                         int *index)
+   19090             : {
+   19091           0 :   int n1sv = *n1;
+   19092           0 :   int n2sv = *n2;
+   19093             :   int i,ind1,ind2;
+   19094             : 
+   19095           0 :   if(*dtrd1>0)
+   19096             :     ind1 = 0;
+   19097             :   else
+   19098           0 :     ind1 = *n1-1;
+   19099             : 
+   19100           0 :   if(*dtrd2>0)
+   19101             :     ind2 = *n1;
+   19102             :   else
+   19103           0 :     ind2 = *n1+*n2-1;
+   19104             : 
+   19105             :   i = 0;
+   19106             :   
+   19107           0 :   while(n1sv>0 && n2sv>0) {
+   19108           0 :     if(a[ind1]<=a[ind2]) {
+   19109           0 :       index[i] = ind1 + 1;
+   19110           0 :       i++;
+   19111           0 :       ind1 += *dtrd1;
+   19112           0 :       n1sv--;
+   19113             :     } else {
+   19114           0 :       index[i] = ind2 + 1;
+   19115           0 :       i++;
+   19116           0 :       ind2 += *dtrd2;
+   19117           0 :       n2sv--;
+   19118             :     }
+   19119             :   }
+   19120             : 
+   19121           0 :   if(n1sv==0) {
+   19122           0 :     for(n1sv=1;n1sv<=n2sv;n1sv++) {
+   19123           0 :       index[i] = ind2 + 1;
+   19124           0 :       i++;
+   19125           0 :       ind2 += *dtrd2;
+   19126             :     } 
+   19127             :   } else {
+   19128           0 :     for(n2sv=1;n2sv<=n1sv;n2sv++) {
+   19129           0 :       index[i] = ind1 + 1;
+   19130           0 :       i++;
+   19131           0 :       ind1 += *dtrd1;
+   19132             :     } 
+   19133             :   }
+   19134           0 :   return;
+   19135             : }
+   19136             : }
+   19137             : }
+   19138             : #include <cctype>
+   19139             : #include <cmath>
+   19140             : 
+   19141             : #include "lapack.h"
+   19142             : 
+   19143             : 
+   19144             : #include "blas/blas.h"
+   19145             : namespace PLMD{
+   19146             : namespace lapack{
+   19147             : using namespace blas;
+   19148             : float
+   19149           0 : PLUMED_BLAS_F77_FUNC(slange,SLANGE)(const char *norm,
+   19150             :         int *m,
+   19151             :         int *n,
+   19152             :         float *a,
+   19153             :         int *lda,
+   19154             :         float *work)
+   19155             : {
+   19156           0 :   const char ch=std::toupper(*norm);
+   19157             :   float dtemp,sum,max,val,scale;
+   19158             :   int i,j;
+   19159             : 
+   19160           0 :   switch(ch) {
+   19161             :   case 'M':
+   19162             :     max = 0.0;
+   19163           0 :     for(j=0;j<*n;j++)
+   19164           0 :       for(i=0;i<*m;i++) {
+   19165           0 :         dtemp = std::abs(a[j*(*lda)+i]);
+   19166           0 :         if(dtemp>max)
+   19167             :           max = dtemp;
+   19168             :       }
+   19169             :     val = max;
+   19170             :     break;
+   19171             : 
+   19172             :   case 'O':
+   19173             :   case '1':
+   19174             :     max = 0.0;
+   19175           0 :     for(j=0;j<*n;j++) {
+   19176           0 :       sum = 0.0;
+   19177           0 :       for(i=0;i<*m;i++) 
+   19178           0 :         sum += std::abs(a[j*(*lda)+i]);
+   19179           0 :       if(sum>max)
+   19180             :         max = sum;
+   19181             :     }
+   19182             :     val = max;
+   19183             :     break;
+   19184             : 
+   19185           0 :   case 'I':
+   19186           0 :     for(i=0;i<*m;i++)
+   19187           0 :       work[i] = 0.0;
+   19188           0 :     for(j=0;j<*n;j++)
+   19189           0 :       for(i=0;i<*m;i++)
+   19190           0 :         work[i] += std::abs(a[j*(*lda)+i]);
+   19191             :     max = 0;
+   19192           0 :     for(i=0;i<*m;i++)
+   19193           0 :       if(work[i]>max)
+   19194             :         max=work[i];
+   19195             :     val = max;
+   19196             :     break;
+   19197             : 
+   19198           0 :   case 'F':
+   19199             :   case 'E':
+   19200           0 :     scale = 0.0;
+   19201           0 :     sum   = 1.0;
+   19202           0 :     i = 1;
+   19203           0 :     for(j=0;j<*n;j++) 
+   19204           0 :       PLUMED_BLAS_F77_FUNC(slassq,SLASSQ)(m,&(a[j*(*lda)+0]),&i,&scale,&sum);
+   19205           0 :     val = scale* std::sqrt(sum);
+   19206           0 :     break;
+   19207             : 
+   19208             :   default:
+   19209             :     val = 0.0;
+   19210             :     break;
+   19211             :   }
+   19212           0 :   return val;
+   19213             : }
+   19214             : }
+   19215             : }
+   19216             : #include <cctype>
+   19217             : #include <cmath>
+   19218             : 
+   19219             : #include "lapack.h"
+   19220             : 
+   19221             : 
+   19222             : #include "blas/blas.h"
+   19223             : namespace PLMD{
+   19224             : namespace lapack{
+   19225             : using namespace blas;
+   19226             : float
+   19227           0 : PLUMED_BLAS_F77_FUNC(slanst,SLANST)(const char *norm,
+   19228             :         int *n,
+   19229             :         float *d,
+   19230             :         float *e)
+   19231             : {
+   19232           0 :   const char ch=std::toupper(*norm);
+   19233             :   float dtemp,max,val,scale,sum;
+   19234             :   int i,j;
+   19235             : 
+   19236             : 
+   19237           0 :   if(*n<=0)
+   19238             :     return 0.0;
+   19239             :   
+   19240           0 :   switch(ch) {
+   19241           0 :   case 'M':
+   19242           0 :     max = std::abs(d[*n-1]);
+   19243           0 :       for(i=0;i<(*n-1);i++) {
+   19244           0 :         dtemp = std::abs(d[i]);
+   19245           0 :         if(dtemp>max)
+   19246             :           max = dtemp;
+   19247           0 :         dtemp = std::abs(e[i]);
+   19248           0 :         if(dtemp>max)
+   19249             :           max = dtemp;
+   19250             :       }
+   19251             :     val = max;
+   19252             :     break;
+   19253             :     
+   19254           0 :   case 'O':
+   19255             :   case '1':
+   19256             :   case 'I':
+   19257             : 
+   19258           0 :     if(*n==1)
+   19259           0 :       val = std::abs(d[0]);
+   19260             :     else {
+   19261           0 :       max = std::abs(d[0]) + std::abs(e[0]);
+   19262           0 :       dtemp = std::abs(e[*n-2]) + std::abs(d[*n-1]);
+   19263           0 :       if(dtemp>max)
+   19264             :         max = dtemp;
+   19265           0 :       for(i=1;i<(*n-1);i++) {
+   19266           0 :         dtemp = std::abs(d[i]) + std::abs(e[i]) + std::abs(e[i-1]);
+   19267           0 :         if(dtemp>max)
+   19268             :           max = dtemp;
+   19269             :       }
+   19270             :       val = max;
+   19271             :     }
+   19272             :     break;
+   19273             : 
+   19274           0 :   case 'F':
+   19275             :   case 'E':
+   19276           0 :     scale = 0.0;
+   19277           0 :     sum   = 1.0;
+   19278           0 :     i = *n-1;
+   19279           0 :     j = 1;
+   19280           0 :     if(*n>1) {
+   19281           0 :       PLUMED_BLAS_F77_FUNC(slassq,SLASSQ)(&i,e,&j,&scale,&sum);
+   19282           0 :       sum *= 2;
+   19283             :     }
+   19284           0 :     PLUMED_BLAS_F77_FUNC(slassq,SLASSQ)(n,d,&j,&scale,&sum);
+   19285           0 :     val = scale *  std::sqrt(sum);
+   19286           0 :     break;
+   19287             :     
+   19288             :   default:
+   19289             :     val = 0.0;
+   19290             :     break;
+   19291             :   }
+   19292             :   return val;
+   19293             : }
+   19294             : }
+   19295             : }
+   19296             : #include <cmath>
+   19297             : 
+   19298             : 
+   19299             : #include "lapack.h"
+   19300             : 
+   19301             : #include "blas/blas.h"
+   19302             : namespace PLMD{
+   19303             : namespace lapack{
+   19304             : using namespace blas;
+   19305             : float 
+   19306           0 : PLUMED_BLAS_F77_FUNC(slansy,SLANSY)(const char *norm, const char *uplo, int *n, float *a, int 
+   19307             :         *lda, float *work)
+   19308             : {
+   19309             :     /* System generated locals */
+   19310             :     int a_dim1, a_offset, i__1, i__2;
+   19311             :     float ret_val, d__1, d__2, d__3;
+   19312           0 :     int c__1 = 1;
+   19313             : 
+   19314             :     /* Local variables */
+   19315             :     int i__, j;
+   19316             :     float sum, absa, scale;
+   19317             :     float value =0.0;
+   19318             : 
+   19319           0 :     a_dim1 = *lda;
+   19320           0 :     a_offset = 1 + a_dim1;
+   19321           0 :     a -= a_offset;
+   19322           0 :     --work;
+   19323             : 
+   19324           0 :     if (*n == 0) {
+   19325             :         value = 0.;
+   19326           0 :     } else if (*norm=='M' || *norm=='m') {
+   19327             : 
+   19328             :         value = 0.;
+   19329           0 :         if (*uplo=='U' || *uplo=='u') {
+   19330           0 :             i__1 = *n;
+   19331           0 :             for (j = 1; j <= i__1; ++j) {
+   19332             :                 i__2 = j;
+   19333           0 :                 for (i__ = 1; i__ <= i__2; ++i__) {
+   19334             :                   d__2 = value;
+   19335           0 :                   d__3 = std::abs(a[i__ + j * a_dim1]);
+   19336           0 :                   value = (d__2>d__3) ? d__2 : d__3;
+   19337             :                 }
+   19338             :             }
+   19339             :         } else {
+   19340           0 :             i__1 = *n;
+   19341           0 :             for (j = 1; j <= i__1; ++j) {
+   19342             :                 i__2 = *n;
+   19343           0 :                 for (i__ = j; i__ <= i__2; ++i__) {
+   19344             :                   d__2 = value;
+   19345           0 :                   d__3 = std::abs(a[i__ + j * a_dim1]);
+   19346           0 :                     value =  (d__2>d__3) ? d__2 : d__3;
+   19347             :                 }
+   19348             :             }
+   19349             :         }
+   19350           0 :     } else if (*norm=='I' || *norm=='i' || *norm=='O' || *norm=='o' || *norm=='1') {
+   19351             : 
+   19352             :         value = 0.;
+   19353           0 :         if (*uplo=='U' || *uplo=='u') {
+   19354           0 :             i__1 = *n;
+   19355           0 :             for (j = 1; j <= i__1; ++j) {
+   19356           0 :                 sum = 0.;
+   19357           0 :                 i__2 = j - 1;
+   19358           0 :                 for (i__ = 1; i__ <= i__2; ++i__) {
+   19359           0 :                     absa = std::abs(a[i__ + j * a_dim1]);
+   19360           0 :                     sum += absa;
+   19361           0 :                     work[i__] += absa;
+   19362             :                 }
+   19363           0 :                 work[j] = sum + std::abs(a[j + j * a_dim1]);
+   19364             :             }
+   19365           0 :             i__1 = *n;
+   19366           0 :             for (i__ = 1; i__ <= i__1; ++i__) {
+   19367           0 :                 d__1 = value, d__2 = work[i__];
+   19368           0 :                 value =  (d__1>d__2) ? d__1 : d__2;
+   19369             :             }
+   19370             :         } else {
+   19371             :             i__1 = *n;
+   19372           0 :             for (i__ = 1; i__ <= i__1; ++i__) {
+   19373           0 :                 work[i__] = 0.;
+   19374             :             }
+   19375           0 :             i__1 = *n;
+   19376           0 :             for (j = 1; j <= i__1; ++j) {
+   19377           0 :                 sum = work[j] + std::abs(a[j + j * a_dim1]);
+   19378           0 :                 i__2 = *n;
+   19379           0 :                 for (i__ = j + 1; i__ <= i__2; ++i__) {
+   19380           0 :                     absa = std::abs(a[i__ + j * a_dim1]);
+   19381           0 :                     sum += absa;
+   19382           0 :                     work[i__] += absa;
+   19383             :                 }
+   19384           0 :                 if(sum>value)
+   19385             :                   value = sum;
+   19386             :             }
+   19387             :         }
+   19388             :     } else if (*norm=='F' || *norm=='f' || *norm=='E' || *norm=='e') {
+   19389             : 
+   19390           0 :         scale = 0.;
+   19391           0 :         sum = 1.;
+   19392           0 :         if (*uplo=='U' || *uplo=='u') {
+   19393           0 :             i__1 = *n;
+   19394           0 :             for (j = 2; j <= i__1; ++j) {
+   19395           0 :                 i__2 = j - 1;
+   19396           0 :                 PLUMED_BLAS_F77_FUNC(slassq,SLASSQ)(&i__2, &a[j * a_dim1 + 1], &c__1, &scale, &sum);
+   19397             :             }
+   19398             :         } else {
+   19399           0 :             i__1 = *n - 1;
+   19400           0 :             for (j = 1; j <= i__1; ++j) {
+   19401           0 :                 i__2 = *n - j;
+   19402           0 :                 PLUMED_BLAS_F77_FUNC(slassq,SLASSQ)(&i__2, &a[j + 1 + j * a_dim1], &c__1, &scale, &sum);
+   19403             :             }
+   19404             :         }
+   19405           0 :         sum *= 2;
+   19406           0 :         i__1 = *lda + 1;
+   19407           0 :         PLUMED_BLAS_F77_FUNC(slassq,SLASSQ)(n, &a[a_offset], &i__1, &scale, &sum);
+   19408           0 :         value = scale *  std::sqrt(sum);
+   19409             :     }
+   19410             : 
+   19411             :     ret_val = value;
+   19412           0 :     return ret_val;
+   19413             : }
+   19414             : 
+   19415             : 
+   19416             : }
+   19417             : }
+   19418             : #include <cmath>
+   19419             : #include "lapack.h"
+   19420             : 
+   19421             : #include "real.h"
+   19422             : 
+   19423             : #include "blas/blas.h"
+   19424             : namespace PLMD{
+   19425             : namespace lapack{
+   19426             : using namespace blas;
+   19427             : float
+   19428           1 : PLUMED_BLAS_F77_FUNC(slapy2,SLAPY2)(float * x, float * y)
+   19429             : {
+   19430             :   float xabs,yabs;
+   19431             :   float w,z;
+   19432             : 
+   19433           1 :   xabs = std::abs(*x);
+   19434           1 :   yabs = std::abs(*y);
+   19435             :   
+   19436           1 :   if(xabs>yabs) {
+   19437             :     w = xabs;
+   19438             :     z = yabs;
+   19439             :   } else {
+   19440             :     w = yabs;
+   19441             :     z = xabs;
+   19442             :   }
+   19443             : 
+   19444           1 :   if( std::abs(z)<PLUMED_GMX_FLOAT_MIN) 
+   19445             :     return w;
+   19446             :   else {
+   19447           1 :     z = z/w;
+   19448           1 :     return w* std::sqrt(1.0+z*z);
+   19449             :   }
+   19450             : }
+   19451             :   
+   19452             : }
+   19453             : }
+   19454             : #include <cmath>
+   19455             : 
+   19456             : #include "real.h"
+   19457             : 
+   19458             : #include "lapack.h"
+   19459             : #include "lapack_limits.h"
+   19460             : #include "blas/blas.h"
+   19461             : namespace PLMD{
+   19462             : namespace lapack{
+   19463             : using namespace blas;
+   19464             : 
+   19465           0 : void PLUMED_BLAS_F77_FUNC(slar1vx,SLAR1VX)(int *n, 
+   19466             :               int *b1, 
+   19467             :               int *bn,
+   19468             :               float *sigma, 
+   19469             :               float *d__, 
+   19470             :               float *l, 
+   19471             :               float *ld, 
+   19472             :               float *lld, 
+   19473             :               float *eval, 
+   19474             :               float *gersch, 
+   19475             :               float *z__, 
+   19476             :               float *ztz, 
+   19477             :               float *mingma, 
+   19478             :               int *r__, 
+   19479             :               int *isuppz, 
+   19480             :               float *work)
+   19481             : {
+   19482             :     int i__1;
+   19483             : 
+   19484             :     int i__, j;
+   19485             :     float s;
+   19486             :     int r1, r2;
+   19487             :     int to;
+   19488             :     float eps, tmp;
+   19489             :     int indp, inds, from;
+   19490             :     float dplus;
+   19491             :     int sawnan;
+   19492             :     int indumn;
+   19493             :     float dminus;
+   19494             : 
+   19495           0 :     --work;
+   19496             :     --isuppz;
+   19497           0 :     --z__;
+   19498           0 :     --gersch;
+   19499           0 :     --lld;
+   19500           0 :     --ld;
+   19501           0 :     --l;
+   19502           0 :     --d__;
+   19503             : 
+   19504             :     /* Function Body */
+   19505             :     eps = PLUMED_GMX_FLOAT_EPS;
+   19506           0 :     if (*r__ == 0) {
+   19507             : 
+   19508           0 :         r1 = *b1;
+   19509           0 :         r2 = *bn;
+   19510             :         i__1 = *bn;
+   19511           0 :         for (i__ = *b1; i__ <= i__1; ++i__) {
+   19512           0 :             if (*eval >= gersch[(i__ << 1) - 1] && *eval <= gersch[i__ * 2]) {
+   19513             :                 r1 = i__;
+   19514           0 :                 goto L20;
+   19515             :             }
+   19516             :         }
+   19517           0 :         goto L40;
+   19518             : L20:
+   19519             :         i__1 = *b1;
+   19520           0 :         for (i__ = *bn; i__ >= i__1; --i__) {
+   19521           0 :             if (*eval >= gersch[(i__ << 1) - 1] && *eval <= gersch[i__ * 2]) {
+   19522             :                 r2 = i__;
+   19523           0 :                 goto L40;
+   19524             :             }
+   19525             :         }
+   19526             :     } else {
+   19527             :         r1 = *r__;
+   19528             :         r2 = *r__;
+   19529             :     }
+   19530             : 
+   19531           0 : L40:
+   19532           0 :     indumn = *n;
+   19533           0 :     inds = (*n << 1) + 1;
+   19534           0 :     indp = *n * 3 + 1;
+   19535             :     sawnan = 0;
+   19536             : 
+   19537           0 :     if (*b1 == 1) {
+   19538           0 :         work[inds] = 0.;
+   19539             :     } else {
+   19540           0 :         work[inds] = lld[*b1 - 1];
+   19541             :     }
+   19542           0 :     s = work[inds] - *sigma;
+   19543             :     i__1 = r2 - 1;
+   19544           0 :     for (i__ = *b1; i__ <= i__1; ++i__) {
+   19545           0 :         dplus = d__[i__] + s;
+   19546           0 :         work[i__] = ld[i__] / dplus;
+   19547           0 :         work[inds + i__] = s * work[i__] * l[i__];
+   19548           0 :         s = work[inds + i__] - *sigma;
+   19549             :     }
+   19550             : 
+   19551           0 :     if (std::isnan(s)) {
+   19552             : 
+   19553             :         sawnan = 1;
+   19554           0 :         j = *b1 + 1;
+   19555           0 : L60:
+   19556           0 :     if (!std::isnan(work[inds + j])) {
+   19557           0 :             ++j;
+   19558           0 :             goto L60;
+   19559             :         }
+   19560           0 :         work[inds + j] = lld[j];
+   19561           0 :         s = work[inds + j] - *sigma;
+   19562             :         i__1 = r2 - 1;
+   19563           0 :         for (i__ = j + 1; i__ <= i__1; ++i__) {
+   19564           0 :             dplus = d__[i__] + s;
+   19565           0 :             work[i__] = ld[i__] / dplus;
+   19566           0 :             if (std::abs(work[i__])<PLUMED_GMX_FLOAT_MIN) {
+   19567           0 :                 work[inds + i__] = lld[i__];
+   19568             :             } else {
+   19569           0 :                 work[inds + i__] = s * work[i__] * l[i__];
+   19570             :             }
+   19571           0 :             s = work[inds + i__] - *sigma;
+   19572             :         }
+   19573             :     }
+   19574             : 
+   19575           0 :     work[indp + *bn - 1] = d__[*bn] - *sigma;
+   19576             :     i__1 = r1;
+   19577           0 :     for (i__ = *bn - 1; i__ >= i__1; --i__) {
+   19578           0 :         dminus = lld[i__] + work[indp + i__];
+   19579           0 :         tmp = d__[i__] / dminus;
+   19580           0 :         work[indumn + i__] = l[i__] * tmp;
+   19581           0 :         work[indp + i__ - 1] = work[indp + i__] * tmp - *sigma;
+   19582             :     }
+   19583           0 :     tmp = work[indp + r1 - 1];
+   19584           0 :     if (std::isnan(tmp)) {
+   19585             : 
+   19586             :         sawnan = 1;
+   19587           0 :         j = *bn - 3;
+   19588           0 : L90:
+   19589           0 :     if (!std::isnan(work[indp + j])) {
+   19590           0 :             --j;
+   19591           0 :             goto L90;
+   19592             :         }
+   19593           0 :         work[indp + j] = d__[j + 1] - *sigma;
+   19594             :         i__1 = r1;
+   19595           0 :         for (i__ = j; i__ >= i__1; --i__) {
+   19596           0 :             dminus = lld[i__] + work[indp + i__];
+   19597           0 :             tmp = d__[i__] / dminus;
+   19598           0 :             work[indumn + i__] = l[i__] * tmp;
+   19599           0 :             if (std::abs(tmp)<PLUMED_GMX_FLOAT_MIN) {
+   19600           0 :                 work[indp + i__ - 1] = d__[i__] - *sigma;
+   19601             :             } else {
+   19602           0 :                 work[indp + i__ - 1] = work[indp + i__] * tmp - *sigma;
+   19603             :             }
+   19604             :         }
+   19605             :     }
+   19606             : 
+   19607           0 :     *mingma = work[inds + r1 - 1] + work[indp + r1 - 1];
+   19608           0 :     if (std::abs(*mingma)<PLUMED_GMX_FLOAT_MIN) {
+   19609           0 :         *mingma = eps * work[inds + r1 - 1];
+   19610             :     }
+   19611           0 :     *r__ = r1;
+   19612             :     i__1 = r2 - 1;
+   19613           0 :     for (i__ = r1; i__ <= i__1; ++i__) {
+   19614           0 :         tmp = work[inds + i__] + work[indp + i__];
+   19615           0 :         if (std::abs(tmp)<PLUMED_GMX_FLOAT_MIN) {
+   19616           0 :             tmp = eps * work[inds + i__];
+   19617             :         }
+   19618           0 :         if (std::abs(tmp) < std::abs(*mingma)) {
+   19619           0 :             *mingma = tmp;
+   19620           0 :             *r__ = i__ + 1;
+   19621             :         }
+   19622             :     }
+   19623             : 
+   19624           0 :     isuppz[1] = *b1;
+   19625           0 :     isuppz[2] = *bn;
+   19626           0 :     z__[*r__] = 1.;
+   19627           0 :     *ztz = 1.;
+   19628           0 :     if (! sawnan) {
+   19629           0 :         from = *r__ - 1;
+   19630           0 :         i__1 = *r__ - 32;
+   19631           0 :         to = (i__1>(*b1)) ? i__1 : (*b1);
+   19632             : L120:
+   19633           0 :         if (from >= *b1) {
+   19634             :             i__1 = to;
+   19635           0 :             for (i__ = from; i__ >= i__1; --i__) {
+   19636           0 :                 z__[i__] = -(work[i__] * z__[i__ + 1]);
+   19637           0 :                 *ztz += z__[i__] * z__[i__];
+   19638             :             }
+   19639           0 :             if (std::abs(z__[to]) <= eps && std::abs(z__[to + 1]) <= eps) {
+   19640           0 :                 isuppz[1] = to + 2;
+   19641             :             } else {
+   19642           0 :                 from = to - 1;
+   19643           0 :                 i__1 = to - 32;
+   19644           0 :                 to = (i__1>*b1) ? i__1 : *b1;
+   19645           0 :                 goto L120;
+   19646             :             }
+   19647             :         }
+   19648           0 :         from = *r__ + 1;
+   19649           0 :         i__1 = *r__ + 32;
+   19650           0 :         to = (i__1<*bn) ? i__1 : *bn;
+   19651             : L140:
+   19652           0 :         if (from <= *bn) {
+   19653             :             i__1 = to;
+   19654           0 :             for (i__ = from; i__ <= i__1; ++i__) {
+   19655           0 :                 z__[i__] = -(work[indumn + i__ - 1] * z__[i__ - 1]);
+   19656           0 :                 *ztz += z__[i__] * z__[i__];
+   19657             :             }
+   19658           0 :             if (std::abs(z__[to]) <= eps && std::abs(z__[to - 1]) <= eps) {
+   19659           0 :                 isuppz[2] = to - 2;
+   19660             :             } else {
+   19661           0 :                 from = to + 1;
+   19662           0 :                 i__1 = to + 32;
+   19663           0 :                 to = (i__1<*bn) ? i__1 : *bn;
+   19664           0 :                 goto L140;
+   19665             :             }
+   19666             :         }
+   19667             :     } else {
+   19668           0 :         i__1 = *b1;
+   19669           0 :         for (i__ = *r__ - 1; i__ >= i__1; --i__) {
+   19670           0 :             if (std::abs(z__[i__ + 1])<PLUMED_GMX_FLOAT_MIN) {
+   19671           0 :                 z__[i__] = -(ld[i__ + 1] / ld[i__]) * z__[i__ + 2];
+   19672             :             } else {
+   19673           0 :                 z__[i__] = -(work[i__] * z__[i__ + 1]);
+   19674             :             }
+   19675           0 :             if (std::abs(z__[i__]) <= eps && std::abs(z__[i__ + 1]) <= eps) {
+   19676           0 :                 isuppz[1] = i__ + 2;
+   19677           0 :                 goto L170;
+   19678             :             }
+   19679           0 :             *ztz += z__[i__] * z__[i__];
+   19680             :         }
+   19681           0 : L170:
+   19682           0 :         i__1 = *bn - 1;
+   19683           0 :         for (i__ = *r__; i__ <= i__1; ++i__) {
+   19684           0 :             if (std::abs(z__[i__])<PLUMED_GMX_FLOAT_MIN) {
+   19685           0 :                 z__[i__ + 1] = -(ld[i__ - 1] / ld[i__]) * z__[i__ - 1];
+   19686             :             } else {
+   19687           0 :                 z__[i__ + 1] = -(work[indumn + i__] * z__[i__]);
+   19688             :             }
+   19689           0 :             if (std::abs(z__[i__]) <= eps && std::abs(z__[i__ + 1]) <= eps) {
+   19690           0 :                 isuppz[2] = i__ - 1;
+   19691           0 :                 break;
+   19692             :             }
+   19693           0 :             *ztz += z__[i__ + 1] * z__[i__ + 1];
+   19694             :         }
+   19695             :     }
+   19696             : 
+   19697           0 :     return;
+   19698             : 
+   19699             : }
+   19700             : 
+   19701             : 
+   19702             : }
+   19703             : }
+   19704             : #include <cctype>
+   19705             : #include <cmath>
+   19706             : 
+   19707             : #include "blas/blas.h"
+   19708             : #include "lapack.h"
+   19709             : 
+   19710             : #include "real.h"
+   19711             : 
+   19712             : #include "blas/blas.h"
+   19713             : namespace PLMD{
+   19714             : namespace lapack{
+   19715             : using namespace blas;
+   19716             : void
+   19717           0 : PLUMED_BLAS_F77_FUNC(slarf,SLARF)(const char *side,
+   19718             :        int *m,
+   19719             :        int *n,
+   19720             :        float *v,
+   19721             :        int *incv,
+   19722             :        float *tau,
+   19723             :        float *c,
+   19724             :        int *ldc,
+   19725             :        float *work)
+   19726             : {
+   19727           0 :   const char ch=std::toupper(*side);
+   19728           0 :   float one = 1.0;
+   19729           0 :   float zero = 0.0;
+   19730           0 :   float minustau = -(*tau);
+   19731           0 :   int i1 = 1;
+   19732             : 
+   19733             : 
+   19734           0 :   if(ch=='L') {
+   19735           0 :     if(std::abs(*tau)>PLUMED_GMX_FLOAT_MIN) {
+   19736           0 :       PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("T",m,n,&one,c,ldc,v,incv,&zero,work,&i1);
+   19737           0 :       PLUMED_BLAS_F77_FUNC(sger,SGER)(m,n,&minustau,v,incv,work,&i1,c,ldc);
+   19738             :     }
+   19739             :   } else {
+   19740           0 :     if(std::abs(*tau)>PLUMED_GMX_FLOAT_MIN) {
+   19741           0 :       PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("N",m,n,&one,c,ldc,v,incv,&zero,work,&i1);
+   19742           0 :       PLUMED_BLAS_F77_FUNC(sger,SGER)(m,n,&minustau,work,&i1,v,incv,c,ldc);
+   19743             :     }
+   19744             :   }
+   19745           0 :   return;
+   19746             : }
+   19747             : }
+   19748             : }
+   19749             : #include "blas/blas.h"
+   19750             : #include "lapack.h"
+   19751             : 
+   19752             : 
+   19753             : #include "blas/blas.h"
+   19754             : namespace PLMD{
+   19755             : namespace lapack{
+   19756             : using namespace blas;
+   19757             : void 
+   19758           0 : PLUMED_BLAS_F77_FUNC(slarfb,SLARFB)(const char *side, 
+   19759             :         const char *trans, 
+   19760             :         const char *direct, 
+   19761             :         const char *storev, 
+   19762             :         int *m, 
+   19763             :         int *n, 
+   19764             :         int *k, 
+   19765             :         float *v, 
+   19766             :         int *ldv, 
+   19767             :         float *t, 
+   19768             :         int *ldt, 
+   19769             :         float *c__,
+   19770             :         int *ldc, 
+   19771             :         float *work, 
+   19772             :         int *ldwork)
+   19773             : {
+   19774             :     int c_dim1, c_offset, t_dim1, t_offset, v_dim1, v_offset, work_dim1, 
+   19775             :             work_offset, i__1, i__2;
+   19776             : 
+   19777             :     int i__, j;
+   19778             :     char transt[1];
+   19779           0 :     int c__1 = 1;
+   19780           0 :     float one = 1.0;
+   19781           0 :     float minusone = -1.0;
+   19782             : 
+   19783           0 :     v_dim1 = *ldv;
+   19784           0 :     v_offset = 1 + v_dim1;
+   19785           0 :     v -= v_offset;
+   19786             :     t_dim1 = *ldt;
+   19787             :     t_offset = 1 + t_dim1;
+   19788             :     t -= t_offset;
+   19789           0 :     c_dim1 = *ldc;
+   19790           0 :     c_offset = 1 + c_dim1;
+   19791           0 :     c__ -= c_offset;
+   19792           0 :     work_dim1 = *ldwork;
+   19793           0 :     work_offset = 1 + work_dim1;
+   19794           0 :     work -= work_offset;
+   19795             : 
+   19796           0 :     if (*m <= 0 || *n <= 0) {
+   19797             :         return;
+   19798             :     }
+   19799           0 :     if (*trans=='N' || *trans=='n') {
+   19800           0 :       *(unsigned char *)transt = 'T';
+   19801             :     } else {
+   19802           0 :         *(unsigned char *)transt = 'N';
+   19803             :     }
+   19804             :     
+   19805           0 :     if (*storev=='C' || *storev=='c') {
+   19806             : 
+   19807           0 :         if (*direct=='F' || *direct=='f') {
+   19808           0 :           if (*side=='l' || *side=='L') {
+   19809             : 
+   19810           0 :                 i__1 = *k;
+   19811           0 :                 for (j = 1; j <= i__1; ++j) {
+   19812           0 :                     PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(n, &c__[j + c_dim1], ldc, &work[j * work_dim1 + 1],
+   19813             :                              &c__1);
+   19814             :                 }
+   19815             : 
+   19816           0 :                 PLUMED_BLAS_F77_FUNC(strmm,STRMM)("Right", "Lower", "No transpose", "Unit", n, k, &one,
+   19817             :                          &v[v_offset], ldv, &work[work_offset], ldwork);
+   19818           0 :                 if (*m > *k) {
+   19819             : 
+   19820           0 :                     i__1 = *m - *k;
+   19821           0 :                     PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("Transpose", "No transpose", n, k, &i__1, &one, &
+   19822           0 :                             c__[*k + 1 + c_dim1], ldc, &v[*k + 1 + v_dim1], 
+   19823             :                             ldv, &one, &work[work_offset], ldwork);
+   19824             :                 }
+   19825             : 
+   19826           0 :                 PLUMED_BLAS_F77_FUNC(strmm,STRMM)("Right", "Upper", transt, "Non-unit", n, k, &one, &t[
+   19827             :                         t_offset], ldt, &work[work_offset], ldwork);
+   19828             : 
+   19829           0 :                 if (*m > *k) {
+   19830           0 :                     i__1 = *m - *k;
+   19831           0 :                     PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("No transpose", "Transpose", &i__1, n, k, &minusone, &
+   19832           0 :                             v[*k + 1 + v_dim1], ldv, &work[work_offset], 
+   19833           0 :                             ldwork, &one, &c__[*k + 1 + c_dim1], ldc);
+   19834             :                 }
+   19835             : 
+   19836           0 :                 PLUMED_BLAS_F77_FUNC(strmm,STRMM)("Right", "Lower", "Transpose", "Unit", n, k, &one, &
+   19837             :                         v[v_offset], ldv, &work[work_offset], ldwork);
+   19838             : 
+   19839           0 :                 i__1 = *k;
+   19840           0 :                 for (j = 1; j <= i__1; ++j) {
+   19841           0 :                     i__2 = *n;
+   19842           0 :                     for (i__ = 1; i__ <= i__2; ++i__) {
+   19843           0 :                         c__[j + i__ * c_dim1] -= work[i__ + j * work_dim1];
+   19844             :                     }
+   19845             :                 }
+   19846             : 
+   19847           0 :             } else if (*side=='r' || *side=='R') {
+   19848             : 
+   19849           0 :                 i__1 = *k;
+   19850           0 :                 for (j = 1; j <= i__1; ++j) {
+   19851           0 :                     PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(m, &c__[j * c_dim1 + 1], &c__1, &work[j * 
+   19852           0 :                             work_dim1 + 1], &c__1);
+   19853             :                 }
+   19854             : 
+   19855           0 :                 PLUMED_BLAS_F77_FUNC(strmm,STRMM)("Right", "Lower", "No transpose", "Unit", m, k, &one,
+   19856             :                          &v[v_offset], ldv, &work[work_offset], ldwork);
+   19857           0 :                 if (*n > *k) {
+   19858             : 
+   19859           0 :                     i__1 = *n - *k;
+   19860           0 :                     PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("No transpose", "No transpose", m, k, &i__1, &
+   19861           0 :                             one, &c__[(*k + 1) * c_dim1 + 1], ldc, &v[*k + 
+   19862           0 :                             1 + v_dim1], ldv, &one, &work[work_offset], 
+   19863             :                             ldwork);
+   19864             :                 }
+   19865             : 
+   19866           0 :                 PLUMED_BLAS_F77_FUNC(strmm,STRMM)("Right", "Upper", trans, "Non-unit", m, k, &one, &t[
+   19867             :                         t_offset], ldt, &work[work_offset], ldwork);
+   19868             : 
+   19869           0 :                 if (*n > *k) {
+   19870           0 :                     i__1 = *n - *k;
+   19871           0 :                     PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("No transpose", "Transpose", m, &i__1, k, &minusone, &
+   19872           0 :                             work[work_offset], ldwork, &v[*k + 1 + v_dim1], 
+   19873           0 :                             ldv, &one, &c__[(*k + 1) * c_dim1 + 1], ldc);
+   19874             :                 }
+   19875             : 
+   19876           0 :                 PLUMED_BLAS_F77_FUNC(strmm,STRMM)("Right", "Lower", "Transpose", "Unit", m, k, &one, &
+   19877             :                         v[v_offset], ldv, &work[work_offset], ldwork);
+   19878             : 
+   19879           0 :                 i__1 = *k;
+   19880           0 :                 for (j = 1; j <= i__1; ++j) {
+   19881           0 :                     i__2 = *m;
+   19882           0 :                     for (i__ = 1; i__ <= i__2; ++i__) {
+   19883           0 :                         c__[i__ + j * c_dim1] -= work[i__ + j * work_dim1];
+   19884             :                     }
+   19885             :                 }
+   19886             :             }
+   19887             : 
+   19888             :         } else {
+   19889             : 
+   19890           0 :           if (*side=='l' || *side=='L') {
+   19891           0 :                 i__1 = *k;
+   19892           0 :                 for (j = 1; j <= i__1; ++j) {
+   19893           0 :                     PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(n, &c__[*m - *k + j + c_dim1], ldc, &work[j * 
+   19894           0 :                             work_dim1 + 1], &c__1);
+   19895             :                 }
+   19896             : 
+   19897           0 :                 PLUMED_BLAS_F77_FUNC(strmm,STRMM)("Right", "Upper", "No transpose", "Unit", n, k, &one,
+   19898           0 :                          &v[*m - *k + 1 + v_dim1], ldv, &work[work_offset], 
+   19899             :                         ldwork);
+   19900           0 :                 if (*m > *k) {
+   19901           0 :                     i__1 = *m - *k;
+   19902           0 :                     PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("Transpose", "No transpose", n, k, &i__1, &one, &
+   19903             :                             c__[c_offset], ldc, &v[v_offset], ldv, &one, &
+   19904             :                             work[work_offset], ldwork);
+   19905             :                 }
+   19906             : 
+   19907           0 :                 PLUMED_BLAS_F77_FUNC(strmm,STRMM)("Right", "Lower", transt, "Non-unit", n, k, &one, &t[
+   19908             :                         t_offset], ldt, &work[work_offset], ldwork);
+   19909             : 
+   19910           0 :                 if (*m > *k) {
+   19911             : 
+   19912           0 :                     i__1 = *m - *k;
+   19913           0 :                     PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("No transpose", "Transpose", &i__1, n, k, &minusone, &
+   19914             :                             v[v_offset], ldv, &work[work_offset], ldwork, &
+   19915             :                             one, &c__[c_offset], ldc)
+   19916             :                             ;
+   19917             :                 }
+   19918             : 
+   19919           0 :                 PLUMED_BLAS_F77_FUNC(strmm,STRMM)("Right", "Upper", "Transpose", "Unit", n, k, &one, &
+   19920           0 :                         v[*m - *k + 1 + v_dim1], ldv, &work[work_offset], 
+   19921             :                         ldwork);
+   19922             : 
+   19923           0 :                 i__1 = *k;
+   19924           0 :                 for (j = 1; j <= i__1; ++j) {
+   19925           0 :                     i__2 = *n;
+   19926           0 :                     for (i__ = 1; i__ <= i__2; ++i__) {
+   19927           0 :                         c__[*m - *k + j + i__ * c_dim1] -= work[i__ + j * 
+   19928           0 :                                 work_dim1];
+   19929             :                     }
+   19930             :                 }
+   19931             : 
+   19932           0 :             } else if (*side=='r' || *side=='R') {
+   19933           0 :                 i__1 = *k;
+   19934           0 :                 for (j = 1; j <= i__1; ++j) {
+   19935           0 :                     PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(m, &c__[(*n - *k + j) * c_dim1 + 1], &c__1, &work[
+   19936           0 :                             j * work_dim1 + 1], &c__1);
+   19937             :                 }
+   19938             : 
+   19939           0 :                 PLUMED_BLAS_F77_FUNC(strmm,STRMM)("Right", "Upper", "No transpose", "Unit", m, k, &one,
+   19940           0 :                          &v[*n - *k + 1 + v_dim1], ldv, &work[work_offset], 
+   19941             :                         ldwork);
+   19942           0 :                 if (*n > *k) {
+   19943           0 :                     i__1 = *n - *k;
+   19944           0 :                     PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("No transpose", "No transpose", m, k, &i__1, &
+   19945             :                             one, &c__[c_offset], ldc, &v[v_offset], ldv, &
+   19946             :                             one, &work[work_offset], ldwork);
+   19947             :                 }
+   19948           0 :                 PLUMED_BLAS_F77_FUNC(strmm,STRMM)("Right", "Lower", trans, "Non-unit", m, k, &one, &t[
+   19949             :                         t_offset], ldt, &work[work_offset], ldwork);
+   19950           0 :                 if (*n > *k) {
+   19951           0 :                     i__1 = *n - *k;
+   19952           0 :                     PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("No transpose", "Transpose", m, &i__1, k, &minusone, &
+   19953             :                             work[work_offset], ldwork, &v[v_offset], ldv, &
+   19954             :                             one, &c__[c_offset], ldc)
+   19955             :                             ;
+   19956             :                 }
+   19957           0 :                 PLUMED_BLAS_F77_FUNC(strmm,STRMM)("Right", "Upper", "Transpose", "Unit", m, k, &one, &
+   19958           0 :                         v[*n - *k + 1 + v_dim1], ldv, &work[work_offset], 
+   19959             :                         ldwork);
+   19960           0 :                 i__1 = *k;
+   19961           0 :                 for (j = 1; j <= i__1; ++j) {
+   19962           0 :                     i__2 = *m;
+   19963           0 :                     for (i__ = 1; i__ <= i__2; ++i__) {
+   19964           0 :                         c__[i__ + (*n - *k + j) * c_dim1] -= work[i__ + j * 
+   19965           0 :                                 work_dim1];
+   19966             :                     }
+   19967             :                 }
+   19968             :             }
+   19969             :         }
+   19970             : 
+   19971           0 :     } else  if (*storev=='r' || *storev=='R') {
+   19972           0 :       if (*direct=='F' || *direct=='f') {
+   19973           0 :           if (*side=='l' || *side=='L') {
+   19974           0 :                 i__1 = *k;
+   19975           0 :                 for (j = 1; j <= i__1; ++j) {
+   19976           0 :                     PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(n, &c__[j + c_dim1], ldc, &work[j * work_dim1 + 1],
+   19977             :                              &c__1);
+   19978             :                 }
+   19979           0 :                 PLUMED_BLAS_F77_FUNC(strmm,STRMM)("Right", "Upper", "Transpose", "Unit", n, k, &one, &
+   19980             :                         v[v_offset], ldv, &work[work_offset], ldwork);
+   19981           0 :                 if (*m > *k) {
+   19982           0 :                     i__1 = *m - *k;
+   19983           0 :                     PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("Transpose", "Transpose", n, k, &i__1, &one, &
+   19984           0 :                             c__[*k + 1 + c_dim1], ldc, &v[(*k + 1) * v_dim1 + 
+   19985           0 :                             1], ldv, &one, &work[work_offset], ldwork);
+   19986             :                 }
+   19987             : 
+   19988           0 :                 PLUMED_BLAS_F77_FUNC(strmm,STRMM)("Right", "Upper", transt, "Non-unit", n, k, &one, &t[
+   19989             :                         t_offset], ldt, &work[work_offset], ldwork);
+   19990           0 :                 if (*m > *k) {
+   19991             : 
+   19992           0 :                     i__1 = *m - *k;
+   19993           0 :                     PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("Transpose", "Transpose", &i__1, n, k, &minusone, &v[(
+   19994           0 :                             *k + 1) * v_dim1 + 1], ldv, &work[work_offset], 
+   19995           0 :                             ldwork, &one, &c__[*k + 1 + c_dim1], ldc);
+   19996             :                 }
+   19997             : 
+   19998           0 :                 PLUMED_BLAS_F77_FUNC(strmm,STRMM)("Right", "Upper", "No transpose", "Unit", n, k, &one,
+   19999             :                          &v[v_offset], ldv, &work[work_offset], ldwork);
+   20000             : 
+   20001           0 :                 i__1 = *k;
+   20002           0 :                 for (j = 1; j <= i__1; ++j) {
+   20003           0 :                     i__2 = *n;
+   20004           0 :                     for (i__ = 1; i__ <= i__2; ++i__) {
+   20005           0 :                         c__[j + i__ * c_dim1] -= work[i__ + j * work_dim1];
+   20006             :                     }
+   20007             :                 }
+   20008             : 
+   20009           0 :             } else if (*side=='r' || *side=='R') {
+   20010             : 
+   20011           0 :                 i__1 = *k;
+   20012           0 :                 for (j = 1; j <= i__1; ++j) {
+   20013           0 :                     PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(m, &c__[j * c_dim1 + 1], &c__1, &work[j * 
+   20014           0 :                             work_dim1 + 1], &c__1);
+   20015             :                 }
+   20016             : 
+   20017           0 :                 PLUMED_BLAS_F77_FUNC(strmm,STRMM)("Right", "Upper", "Transpose", "Unit", m, k, &one, &
+   20018             :                         v[v_offset], ldv, &work[work_offset], ldwork);
+   20019           0 :                 if (*n > *k) {
+   20020             : 
+   20021           0 :                     i__1 = *n - *k;
+   20022           0 :                     PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("No transpose", "Transpose", m, k, &i__1, &one, &
+   20023           0 :                             c__[(*k + 1) * c_dim1 + 1], ldc, &v[(*k + 1) * 
+   20024           0 :                             v_dim1 + 1], ldv, &one, &work[work_offset], 
+   20025             :                             ldwork);
+   20026             :                 }
+   20027             : 
+   20028           0 :                 PLUMED_BLAS_F77_FUNC(strmm,STRMM)("Right", "Upper", trans, "Non-unit", m, k, &one, &t[
+   20029             :                         t_offset], ldt, &work[work_offset], ldwork);
+   20030             : 
+   20031           0 :                 if (*n > *k) {
+   20032             : 
+   20033           0 :                     i__1 = *n - *k;
+   20034           0 :                     PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("No transpose", "No transpose", m, &i__1, k, &
+   20035           0 :                             minusone, &work[work_offset], ldwork, &v[(*k + 1) * 
+   20036           0 :                             v_dim1 + 1], ldv, &one, &c__[(*k + 1) * c_dim1 
+   20037           0 :                             + 1], ldc);
+   20038             :                 }
+   20039           0 :                 PLUMED_BLAS_F77_FUNC(strmm,STRMM)("Right", "Upper", "No transpose", "Unit", m, k, &one,
+   20040             :                          &v[v_offset], ldv, &work[work_offset], ldwork);
+   20041           0 :                 i__1 = *k;
+   20042           0 :                 for (j = 1; j <= i__1; ++j) {
+   20043           0 :                     i__2 = *m;
+   20044           0 :                     for (i__ = 1; i__ <= i__2; ++i__) {
+   20045           0 :                         c__[i__ + j * c_dim1] -= work[i__ + j * work_dim1];
+   20046             :                     }
+   20047             :                 }
+   20048             : 
+   20049             :             }
+   20050             : 
+   20051             :         } else {
+   20052             : 
+   20053           0 :             if (*side=='l' || *side=='L') {
+   20054             : 
+   20055           0 :                 i__1 = *k;
+   20056           0 :                 for (j = 1; j <= i__1; ++j) {
+   20057           0 :                     PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(n, &c__[*m - *k + j + c_dim1], ldc, &work[j * 
+   20058           0 :                             work_dim1 + 1], &c__1);
+   20059             :                 }
+   20060             : 
+   20061           0 :                 PLUMED_BLAS_F77_FUNC(strmm,STRMM)("Right", "Lower", "Transpose", "Unit", n, k, &one, &
+   20062           0 :                         v[(*m - *k + 1) * v_dim1 + 1], ldv, &work[work_offset]
+   20063             :                         , ldwork);
+   20064           0 :                 if (*m > *k) {
+   20065             : 
+   20066           0 :                     i__1 = *m - *k;
+   20067           0 :                     PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("Transpose", "Transpose", n, k, &i__1, &one, &
+   20068             :                             c__[c_offset], ldc, &v[v_offset], ldv, &one, &
+   20069             :                             work[work_offset], ldwork);
+   20070             :                 }
+   20071             : 
+   20072           0 :                 PLUMED_BLAS_F77_FUNC(strmm,STRMM)("Right", "Lower", transt, "Non-unit", n, k, &one, &t[
+   20073             :                         t_offset], ldt, &work[work_offset], ldwork);
+   20074             : 
+   20075           0 :                 if (*m > *k) {
+   20076             : 
+   20077           0 :                     i__1 = *m - *k;
+   20078           0 :                     PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("Transpose", "Transpose", &i__1, n, k, &minusone, &v[
+   20079             :                             v_offset], ldv, &work[work_offset], ldwork, &
+   20080             :                             one, &c__[c_offset], ldc);
+   20081             :                 }
+   20082             : 
+   20083           0 :                 PLUMED_BLAS_F77_FUNC(strmm,STRMM)("Right", "Lower", "No transpose", "Unit", n, k, &one,
+   20084           0 :                          &v[(*m - *k + 1) * v_dim1 + 1], ldv, &work[
+   20085             :                         work_offset], ldwork);
+   20086             : 
+   20087           0 :                 i__1 = *k;
+   20088           0 :                 for (j = 1; j <= i__1; ++j) {
+   20089           0 :                     i__2 = *n;
+   20090           0 :                     for (i__ = 1; i__ <= i__2; ++i__) {
+   20091           0 :                         c__[*m - *k + j + i__ * c_dim1] -= work[i__ + j * 
+   20092           0 :                                 work_dim1];
+   20093             :                     }
+   20094             :                 }
+   20095             : 
+   20096           0 :             } else if (*side=='r' || *side=='R') {
+   20097             : 
+   20098           0 :                 i__1 = *k;
+   20099           0 :                 for (j = 1; j <= i__1; ++j) {
+   20100           0 :                     PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(m, &c__[(*n - *k + j) * c_dim1 + 1], &c__1, &work[
+   20101           0 :                             j * work_dim1 + 1], &c__1);
+   20102             :                 }
+   20103             : 
+   20104           0 :                 PLUMED_BLAS_F77_FUNC(strmm,STRMM)("Right", "Lower", "Transpose", "Unit", m, k, &one, &
+   20105           0 :                         v[(*n - *k + 1) * v_dim1 + 1], ldv, &work[work_offset]
+   20106             :                         , ldwork);
+   20107           0 :                 if (*n > *k) {
+   20108             : 
+   20109           0 :                     i__1 = *n - *k;
+   20110           0 :                     PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("No transpose", "Transpose", m, k, &i__1, &one, &
+   20111             :                             c__[c_offset], ldc, &v[v_offset], ldv, &one, &
+   20112             :                             work[work_offset], ldwork);
+   20113             :                 }
+   20114             : 
+   20115           0 :                 PLUMED_BLAS_F77_FUNC(strmm,STRMM)("Right", "Lower", trans, "Non-unit", m, k, &one, &t[
+   20116             :                         t_offset], ldt, &work[work_offset], ldwork);
+   20117             : 
+   20118           0 :                 if (*n > *k) {
+   20119             : 
+   20120           0 :                     i__1 = *n - *k;
+   20121           0 :                     PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("No transpose", "No transpose", m, &i__1, k, &
+   20122             :                             minusone, &work[work_offset], ldwork, &v[v_offset], 
+   20123             :                             ldv, &one, &c__[c_offset], ldc);
+   20124             :                 }
+   20125             : 
+   20126           0 :                 PLUMED_BLAS_F77_FUNC(strmm,STRMM)("Right", "Lower", "No transpose", "Unit", m, k, &one,
+   20127           0 :                          &v[(*n - *k + 1) * v_dim1 + 1], ldv, &work[
+   20128             :                         work_offset], ldwork);
+   20129             : 
+   20130           0 :                 i__1 = *k;
+   20131           0 :                 for (j = 1; j <= i__1; ++j) {
+   20132           0 :                     i__2 = *m;
+   20133           0 :                     for (i__ = 1; i__ <= i__2; ++i__) {
+   20134           0 :                         c__[i__ + (*n - *k + j) * c_dim1] -= work[i__ + j * 
+   20135           0 :                                 work_dim1];
+   20136             :                     }
+   20137             :                 }
+   20138             : 
+   20139             :             }
+   20140             : 
+   20141             :         }
+   20142             :     }
+   20143             : 
+   20144             :     return;
+   20145             : 
+   20146             : 
+   20147             : }
+   20148             : 
+   20149             : }
+   20150             : }
+   20151             : #include <cmath>
+   20152             : #include "real.h"
+   20153             : 
+   20154             : #include "blas/blas.h"
+   20155             : #include "lapack.h"
+   20156             : #include "lapack_limits.h"
+   20157             : 
+   20158             : 
+   20159             : #include "blas/blas.h"
+   20160             : namespace PLMD{
+   20161             : namespace lapack{
+   20162             : using namespace blas;
+   20163             : void
+   20164           0 : PLUMED_BLAS_F77_FUNC(slarfg,SLARFG)(int   *n,
+   20165             :                         float *alpha,
+   20166             :                         float *x,
+   20167             :                         int    *incx,
+   20168             :                         float *tau)
+   20169             : {
+   20170             :   float xnorm,t;
+   20171             :   int    ti1,knt,j;
+   20172             :   float minval,safmin,rsafmn,beta;
+   20173             : 
+   20174           0 :   if(*n<=1) {
+   20175           0 :     *tau = 0;
+   20176           0 :     return;
+   20177             :   }
+   20178             : 
+   20179           0 :   ti1 = *n-1;
+   20180             : 
+   20181           0 :   xnorm = PLUMED_BLAS_F77_FUNC(snrm2,SNRM2)(&ti1,x,incx);
+   20182             : 
+   20183           0 :   if(std::abs(xnorm)<PLUMED_GMX_FLOAT_MIN) {
+   20184           0 :     *tau = 0.0;
+   20185             :   } else {
+   20186             : 
+   20187           0 :     t = PLUMED_BLAS_F77_FUNC(slapy2,SLAPY2)(alpha,&xnorm);
+   20188             : 
+   20189           0 :     if(*alpha<0)
+   20190             :       beta = t;
+   20191             :     else
+   20192           0 :       beta = -t;
+   20193             : 
+   20194             :     minval = PLUMED_GMX_FLOAT_MIN;
+   20195             :     
+   20196             :     safmin = minval*(1.0+PLUMED_GMX_FLOAT_EPS) / PLUMED_GMX_FLOAT_EPS;
+   20197             : 
+   20198             :         
+   20199           0 :     if(std::abs(beta)<safmin) {
+   20200             : 
+   20201             :       knt = 0;
+   20202           0 :       rsafmn = 1.0 / safmin;
+   20203             :       
+   20204           0 :       while(std::abs(beta)<safmin) {
+   20205           0 :         knt++;
+   20206           0 :         ti1 = *n-1;
+   20207           0 :         PLUMED_BLAS_F77_FUNC(sscal,SSCAL)(&ti1,&rsafmn,x,incx);
+   20208           0 :         beta *= rsafmn;
+   20209           0 :         *alpha *= rsafmn;
+   20210             :       }
+   20211             :       
+   20212             :       /* safmin <= beta <= 1 now */
+   20213           0 :       ti1 = *n-1;
+   20214           0 :       xnorm = PLUMED_BLAS_F77_FUNC(snrm2,SNRM2)(&ti1,x,incx);
+   20215           0 :       t = PLUMED_BLAS_F77_FUNC(slapy2,SLAPY2)(alpha,&xnorm);
+   20216             :       
+   20217           0 :       if(*alpha<0)
+   20218             :         beta = t;
+   20219             :       else
+   20220           0 :         beta = -t;
+   20221             :       
+   20222           0 :       *tau = (beta-*alpha)/beta;
+   20223             : 
+   20224           0 :       ti1= *n-1;
+   20225           0 :       t = 1.0/(*alpha-beta);
+   20226           0 :       PLUMED_BLAS_F77_FUNC(sscal,SSCAL)(&ti1,&t,x,incx);
+   20227             :    
+   20228           0 :       *alpha = beta;
+   20229           0 :       for(j=0;j<knt;j++)
+   20230           0 :         *alpha *= safmin;
+   20231             :     } else {
+   20232           0 :       *tau = (beta-*alpha)/beta;
+   20233           0 :       ti1= *n-1;
+   20234           0 :       t = 1.0/(*alpha-beta);
+   20235           0 :       PLUMED_BLAS_F77_FUNC(sscal,SSCAL)(&ti1,&t,x,incx);
+   20236           0 :       *alpha = beta;
+   20237             :     }
+   20238             :   }
+   20239             :    
+   20240             :   return;
+   20241             : }
+   20242             : }
+   20243             : }
+   20244             : #include <cmath>
+   20245             : #include "real.h"
+   20246             : 
+   20247             : #include "blas/blas.h"
+   20248             : #include "lapack.h"
+   20249             : 
+   20250             : #include "blas/blas.h"
+   20251             : namespace PLMD{
+   20252             : namespace lapack{
+   20253             : using namespace blas;
+   20254             : void 
+   20255           0 : PLUMED_BLAS_F77_FUNC(slarft,SLARFT)(const char *direct, 
+   20256             :         const char *storev, 
+   20257             :         int *n, 
+   20258             :         int *k, 
+   20259             :         float *v, 
+   20260             :         int *ldv, 
+   20261             :         float *tau, 
+   20262             :         float *t, 
+   20263             :         int *ldt)
+   20264             : {
+   20265             :     /* System generated locals */
+   20266             :     int t_dim1, t_offset, v_dim1, v_offset, i__1, i__2, i__3;
+   20267             :     float d__1;
+   20268             : 
+   20269             :     /* Local variables */
+   20270             :     int i__, j;
+   20271             :     float vii;
+   20272           0 :     int c__1 = 1;
+   20273           0 :     float zero = 0.0;
+   20274             : 
+   20275           0 :     v_dim1 = *ldv;
+   20276           0 :     v_offset = 1 + v_dim1;
+   20277           0 :     v -= v_offset;
+   20278           0 :     --tau;
+   20279           0 :     t_dim1 = *ldt;
+   20280           0 :     t_offset = 1 + t_dim1;
+   20281           0 :     t -= t_offset;
+   20282             : 
+   20283           0 :     if (*n == 0) {
+   20284             :         return;
+   20285             :     }
+   20286             : 
+   20287           0 :     if (*direct=='F' || *direct=='f') {
+   20288           0 :         i__1 = *k;
+   20289           0 :         for (i__ = 1; i__ <= i__1; ++i__) {
+   20290           0 :             if (std::abs(tau[i__])<PLUMED_GMX_FLOAT_MIN) {
+   20291             : 
+   20292           0 :                 i__2 = i__;
+   20293           0 :                 for (j = 1; j <= i__2; ++j) {
+   20294           0 :                     t[j + i__ * t_dim1] = 0.;
+   20295             :                 }
+   20296             :             } else {
+   20297             : 
+   20298           0 :                 vii = v[i__ + i__ * v_dim1];
+   20299           0 :                 v[i__ + i__ * v_dim1] = 1.;
+   20300           0 :                 if (*storev=='C' || *storev=='c') {
+   20301             : 
+   20302           0 :                     i__2 = *n - i__ + 1;
+   20303           0 :                     i__3 = i__ - 1;
+   20304           0 :                     d__1 = -tau[i__];
+   20305           0 :                     PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("Transpose", &i__2, &i__3, &d__1, &v[i__ + v_dim1],
+   20306             :                              ldv, &v[i__ + i__ * v_dim1], &c__1, &zero, &t[
+   20307           0 :                             i__ * t_dim1 + 1], &c__1);
+   20308             :                 } else {
+   20309             : 
+   20310           0 :                     i__2 = i__ - 1;
+   20311           0 :                     i__3 = *n - i__ + 1;
+   20312           0 :                     d__1 = -tau[i__];
+   20313           0 :                     PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("No transpose", &i__2, &i__3, &d__1, &v[i__ * 
+   20314           0 :                             v_dim1 + 1], ldv, &v[i__ + i__ * v_dim1], ldv, &
+   20315           0 :                             zero, &t[i__ * t_dim1 + 1], &c__1);
+   20316             :                 }
+   20317           0 :                 v[i__ + i__ * v_dim1] = vii;
+   20318             : 
+   20319             : 
+   20320           0 :                 i__2 = i__ - 1;
+   20321           0 :                 PLUMED_BLAS_F77_FUNC(strmv,STRMV)("Upper", "No transpose", "Non-unit", &i__2, &t[
+   20322           0 :                         t_offset], ldt, &t[i__ * t_dim1 + 1], &c__1);
+   20323           0 :                 t[i__ + i__ * t_dim1] = tau[i__];
+   20324             :             }
+   20325             :         }
+   20326             :     } else {
+   20327           0 :         for (i__ = *k; i__ >= 1; --i__) {
+   20328           0 :             if (std::abs(tau[i__])<PLUMED_GMX_FLOAT_MIN) {
+   20329             : 
+   20330           0 :                 i__1 = *k;
+   20331           0 :                 for (j = i__; j <= i__1; ++j) {
+   20332           0 :                     t[j + i__ * t_dim1] = 0.;
+   20333             :                 }
+   20334             :             } else {
+   20335             : 
+   20336           0 :                 if (i__ < *k) {
+   20337           0 :                     if (*storev=='C' || *storev=='c') {
+   20338           0 :                         vii = v[*n - *k + i__ + i__ * v_dim1];
+   20339           0 :                         v[*n - *k + i__ + i__ * v_dim1] = 1.;
+   20340             : 
+   20341           0 :                         i__1 = *n - *k + i__;
+   20342           0 :                         i__2 = *k - i__;
+   20343           0 :                         d__1 = -tau[i__];
+   20344           0 :                         PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("Transpose", &i__1, &i__2, &d__1, &v[(i__ + 1) 
+   20345           0 :                                 * v_dim1 + 1], ldv, &v[i__ * v_dim1 + 1], &
+   20346           0 :                                 c__1, &zero, &t[i__ + 1 + i__ * t_dim1], &
+   20347             :                                 c__1);
+   20348           0 :                         v[*n - *k + i__ + i__ * v_dim1] = vii;
+   20349             :                     } else {
+   20350           0 :                         vii = v[i__ + (*n - *k + i__) * v_dim1];
+   20351           0 :                         v[i__ + (*n - *k + i__) * v_dim1] = 1.;
+   20352             : 
+   20353           0 :                         i__1 = *k - i__;
+   20354           0 :                         i__2 = *n - *k + i__;
+   20355           0 :                         d__1 = -tau[i__];
+   20356           0 :                         PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("No transpose", &i__1, &i__2, &d__1, &v[i__ + 
+   20357           0 :                                 1 + v_dim1], ldv, &v[i__ + v_dim1], ldv, &
+   20358           0 :                                 zero, &t[i__ + 1 + i__ * t_dim1], &c__1);
+   20359           0 :                         v[i__ + (*n - *k + i__) * v_dim1] = vii;
+   20360             :                     }
+   20361             : 
+   20362           0 :                     i__1 = *k - i__;
+   20363           0 :                     PLUMED_BLAS_F77_FUNC(strmv,STRMV)("Lower", "No transpose", "Non-unit", &i__1, &t[i__ 
+   20364           0 :                             + 1 + (i__ + 1) * t_dim1], ldt, &t[i__ + 1 + i__ *
+   20365           0 :                              t_dim1], &c__1)
+   20366             :                             ;
+   20367             :                 }
+   20368           0 :                 t[i__ + i__ * t_dim1] = tau[i__];
+   20369             :             }
+   20370             :         }
+   20371             :     }
+   20372             :     return;
+   20373             : 
+   20374             : 
+   20375             : }
+   20376             : }
+   20377             : }
+   20378             : #include <cmath>
+   20379             : #include "lapack.h"
+   20380             : 
+   20381             : #include "blas/blas.h"
+   20382             : namespace PLMD{
+   20383             : namespace lapack{
+   20384             : using namespace blas;
+   20385             : void
+   20386           0 : PLUMED_BLAS_F77_FUNC(slarnv,SLARNV)(int *idist, 
+   20387             :         int *iseed, 
+   20388             :         int *n, 
+   20389             :         float *x)
+   20390             : {
+   20391             :     int i__1, i__2, i__3;
+   20392             : 
+   20393             :     int i__;
+   20394             :     float u[128];
+   20395             :     int il, iv, il2;
+   20396             : 
+   20397           0 :     --x;
+   20398             :     --iseed;
+   20399             : 
+   20400           0 :     i__1 = *n;
+   20401           0 :     for (iv = 1; iv <= i__1; iv += 64) {
+   20402           0 :         i__2 = 64, i__3 = *n - iv + 1;
+   20403             :         il = (i__2<i__3) ? i__2 : i__3;
+   20404           0 :         if (*idist == 3) {
+   20405           0 :             il2 = il << 1;
+   20406             :         } else {
+   20407           0 :             il2 = il;
+   20408             :         }
+   20409             : 
+   20410           0 :         PLUMED_BLAS_F77_FUNC(slaruv,SLARUV)(&iseed[1], &il2, u);
+   20411             : 
+   20412           0 :         if (*idist == 1) {
+   20413             : 
+   20414             :             i__2 = il;
+   20415           0 :             for (i__ = 1; i__ <= i__2; ++i__) {
+   20416           0 :                 x[iv + i__ - 1] = u[i__ - 1];
+   20417             :             }
+   20418           0 :         } else if (*idist == 2) {
+   20419             : 
+   20420             :             i__2 = il;
+   20421           0 :             for (i__ = 1; i__ <= i__2; ++i__) {
+   20422           0 :                 x[iv + i__ - 1] = u[i__ - 1] * 2. - 1.;
+   20423             :             }
+   20424           0 :         } else if (*idist == 3) {
+   20425             : 
+   20426             :             i__2 = il;
+   20427           0 :             for (i__ = 1; i__ <= i__2; ++i__) {
+   20428           0 :                 x[iv + i__ - 1] =  std::sqrt(std::log(u[(i__ << 1) - 2]) * -2.) * 
+   20429           0 :                   std::cos(u[(i__ << 1) - 1] * (float)6.2831853071795864769252867663);
+   20430             :             }
+   20431             :         }
+   20432             :     }
+   20433           0 :     return;
+   20434             : 
+   20435             : }
+   20436             : }
+   20437             : }
+   20438             : #include <cmath>
+   20439             : 
+   20440             : #include "real.h"
+   20441             : 
+   20442             : #include "lapack.h"
+   20443             : #include "lapack_limits.h"
+   20444             : 
+   20445             : #include "blas/blas.h"
+   20446             : namespace PLMD{
+   20447             : namespace lapack{
+   20448             : using namespace blas;
+   20449             : void
+   20450           0 : PLUMED_BLAS_F77_FUNC(slarrbx,SLARRBX)(int *n, 
+   20451             :          float *d__, 
+   20452             :          float *l, 
+   20453             :          float *ld, 
+   20454             :          float *lld, 
+   20455             :          int *ifirst, 
+   20456             :          int *ilast, 
+   20457             :          float *rtol1, 
+   20458             :          float *rtol2, 
+   20459             :          int *offset, 
+   20460             :          float *w, 
+   20461             :          float *wgap, 
+   20462             :          float *werr, 
+   20463             :          float *work,
+   20464             :          int *iwork, 
+   20465             :          int *info)
+   20466             : {
+   20467             :     int i__1, i__2, i__3;
+   20468             :     float d__1, d__2;
+   20469             : 
+   20470             :     int i__, j, k, p;
+   20471             :     float s;
+   20472             :     int i1, i2, ii, kk;
+   20473             :     float fac, gap, mid;
+   20474             :     int cnt;
+   20475             :     float tmp, left;
+   20476             :     int nint, prev, next, nleft;
+   20477             :     float right, width, dplus;
+   20478             :     int nright, olnint;
+   20479             :     k = 0;
+   20480             :     right = 0.0;
+   20481             : 
+   20482           0 :     --iwork;
+   20483           0 :     --work;
+   20484           0 :     --werr;
+   20485           0 :     --wgap;
+   20486           0 :     --w;
+   20487           0 :     --lld;
+   20488             :     --ld;
+   20489             :     --l;
+   20490           0 :     --d__;
+   20491             : 
+   20492           0 :     *info = 0;
+   20493           0 :     i__1 = *n << 1;
+   20494           0 :     for (i__ = 1; i__ <= i__1; ++i__) {
+   20495           0 :         iwork[i__] = 0;
+   20496             :     }
+   20497           0 :     i1 = *ifirst;
+   20498             :     i2 = *ifirst;
+   20499             :     prev = 0;
+   20500           0 :     i__1 = *ilast;
+   20501           0 :     for (i__ = *ifirst; i__ <= i__1; ++i__) {
+   20502           0 :         k = i__ << 1;
+   20503           0 :         iwork[k - 1] = 1;
+   20504             :         i2 = i__;
+   20505             :     }
+   20506             : 
+   20507             :     i__ = i1;
+   20508             :     nint = 0;
+   20509           0 : L30:
+   20510           0 :     if (i__ <= i2) {
+   20511           0 :         ii = i__ - *offset;
+   20512           0 :         if (iwork[(i__ << 1) - 1] == 1) {
+   20513             :             fac = 1.;
+   20514           0 :             left = w[ii] - werr[ii];
+   20515             : 
+   20516             : 
+   20517           0 : L40:
+   20518           0 :             if (i__ > i1 && left <= right) {
+   20519             :                 left = right;
+   20520           0 :                 cnt = i__ - 1;
+   20521             :             } else {
+   20522           0 :                 s = -left;
+   20523             :                 cnt = 0;
+   20524           0 :                 i__1 = *n - 1;
+   20525           0 :                 for (j = 1; j <= i__1; ++j) {
+   20526           0 :                     dplus = d__[j] + s;
+   20527           0 :                     s = s * lld[j] / dplus - left;
+   20528           0 :                     if (dplus < 0.) {
+   20529           0 :                         ++cnt;
+   20530             :                     }
+   20531             :                 }
+   20532           0 :                 dplus = d__[*n] + s;
+   20533           0 :                 if (dplus < 0.) {
+   20534           0 :                     ++cnt;
+   20535             :                 }
+   20536           0 :                 if (std::isnan(s)) {
+   20537             : 
+   20538             :                     cnt = 0;
+   20539             :                     s = -left;
+   20540             :                     i__1 = *n - 1;
+   20541           0 :                     for (j = 1; j <= i__1; ++j) {
+   20542           0 :                         dplus = d__[j] + s;
+   20543           0 :                         if (dplus < 0.) {
+   20544           0 :                             ++cnt;
+   20545             :                         }
+   20546           0 :                         tmp = lld[j] / dplus;
+   20547           0 :                         if (std::abs(tmp)<PLUMED_GMX_FLOAT_MIN) {
+   20548           0 :                             s = lld[j] - left;
+   20549             :                         } else {
+   20550           0 :                             s = s * tmp - left;
+   20551             :                         }
+   20552             :                     }
+   20553           0 :                     dplus = d__[*n] + s;
+   20554           0 :                     if (dplus < 0.) {
+   20555           0 :                         ++cnt;
+   20556             :                     }
+   20557             :                 }
+   20558           0 :                 if (cnt > i__ - 1) {
+   20559           0 :                     left -= werr[ii] * fac;
+   20560           0 :                     fac *= 2.;
+   20561           0 :                     goto L40;
+   20562             :                 }
+   20563             :             }
+   20564           0 :             nleft = cnt + 1;
+   20565             :             i1 = (i1<nleft) ? i1 : nleft;
+   20566             :             fac = 1.;
+   20567           0 :             right = w[ii] + werr[ii];
+   20568           0 : L60:
+   20569           0 :             s = -right;
+   20570             :             cnt = 0;
+   20571           0 :             i__1 = *n - 1;
+   20572           0 :             for (j = 1; j <= i__1; ++j) {
+   20573           0 :                 dplus = d__[j] + s;
+   20574           0 :                 s = s * lld[j] / dplus - right;
+   20575           0 :                 if (dplus < 0.) {
+   20576           0 :                     ++cnt;
+   20577             :                 }
+   20578             :             }
+   20579           0 :             dplus = d__[*n] + s;
+   20580           0 :             if (dplus < 0.) {
+   20581           0 :                 ++cnt;
+   20582             :             }
+   20583           0 :             if (std::isnan(s)) {
+   20584             : 
+   20585             :                 cnt = 0;
+   20586             :                 s = -right;
+   20587             :                 i__1 = *n - 1;
+   20588           0 :                 for (j = 1; j <= i__1; ++j) {
+   20589           0 :                     dplus = d__[j] + s;
+   20590           0 :                     if (dplus < 0.) {
+   20591           0 :                         ++cnt;
+   20592             :                     }
+   20593           0 :                     tmp = lld[j] / dplus;
+   20594           0 :                     if (std::abs(tmp)<PLUMED_GMX_FLOAT_MIN) {
+   20595           0 :                         s = lld[j] - right;
+   20596             :                     } else {
+   20597           0 :                         s = s * tmp - right;
+   20598             :                     }
+   20599             :                 }
+   20600           0 :                 dplus = d__[*n] + s;
+   20601           0 :                 if (dplus < 0.) {
+   20602           0 :                     ++cnt;
+   20603             :                 }
+   20604             :             }
+   20605           0 :             if (cnt < i__) {
+   20606           0 :                 right += werr[ii] * fac;
+   20607           0 :                 fac *= 2.;
+   20608           0 :                 goto L60;
+   20609             :             }
+   20610             :             cnt = (cnt<i2) ? cnt : i2;
+   20611           0 :             ++nint;
+   20612           0 :             k = nleft << 1;
+   20613           0 :             work[k - 1] = left;
+   20614           0 :             work[k] = right;
+   20615           0 :             i__ = cnt + 1;
+   20616           0 :             iwork[k - 1] = i__;
+   20617           0 :             iwork[k] = cnt;
+   20618           0 :             if (prev != nleft - 1) {
+   20619           0 :                 work[k - 2] = left;
+   20620             :             }
+   20621             :             prev = nleft;
+   20622             :         } else {
+   20623           0 :             right = work[i__ * 2];
+   20624             : 
+   20625           0 :             ++iwork[k - 1];
+   20626             :             prev = i__;
+   20627           0 :             ++i__;
+   20628             :         }
+   20629           0 :         goto L30;
+   20630             :     }
+   20631           0 :     if (i__ <= *n && iwork[(i__ << 1) - 1] != -1) {
+   20632           0 :         work[(i__ << 1) - 1] = work[prev * 2];
+   20633             :     }
+   20634             : 
+   20635           0 : L80:
+   20636           0 :     prev = i1 - 1;
+   20637             :     olnint = nint;
+   20638             :     i__ = i1;
+   20639             :     i__1 = olnint;
+   20640           0 :     for (p = 1; p <= i__1; ++p) {
+   20641           0 :         k = i__ << 1;
+   20642           0 :         left = work[k - 1];
+   20643           0 :         right = work[k];
+   20644           0 :         next = iwork[k - 1];
+   20645           0 :         nright = iwork[k];
+   20646           0 :         mid = (left + right) * .5;
+   20647           0 :         width = right - mid;
+   20648             :         d__1 = std::abs(left);
+   20649             :         d__2 = std::abs(right);
+   20650           0 :         tmp = (d__1>d__2) ? d__1 : d__2;
+   20651             : 
+   20652             :         gap = 0.;
+   20653           0 :         if (i__ == nright) {
+   20654           0 :             if (prev > 0 && next <= *n) {
+   20655           0 :                 d__1 = left - work[k - 2], d__2 = work[k + 1] - right;
+   20656           0 :                 gap = (d__1<d__2) ? d__1 : d__2;
+   20657           0 :             } else if (prev > 0) {
+   20658           0 :                 gap = left - work[k - 2];
+   20659           0 :             } else if (next <= *n) {
+   20660           0 :                 gap = work[k + 1] - right;
+   20661             :             }
+   20662             :         }
+   20663           0 :         d__1 = *rtol1 * gap, d__2 = *rtol2 * tmp;
+   20664           0 :         if (width < ((d__1>d__2) ? d__1 : d__2)) {
+   20665           0 :             --nint;
+   20666           0 :             iwork[k - 1] = 0;
+   20667             :             kk = k;
+   20668             :             i__2 = nright;
+   20669           0 :             for (j = i__ + 1; j <= i__2; ++j) {
+   20670           0 :                 kk += 2;
+   20671           0 :                 iwork[kk - 1] = 0;
+   20672           0 :                 work[kk - 1] = left;
+   20673           0 :                 work[kk] = right;
+   20674           0 :                 wgap[j - 1 - *offset] = 0.;
+   20675             :             }
+   20676           0 :             if (i1 == i__) {
+   20677             :                 i1 = next;
+   20678             :             } else {
+   20679           0 :                 iwork[(prev << 1) - 1] = next;
+   20680             :             }
+   20681             :             i__ = next;
+   20682           0 :             continue;
+   20683             :         }
+   20684             :         prev = i__;
+   20685             : 
+   20686           0 :         s = -mid;
+   20687             :         cnt = 0;
+   20688           0 :         i__2 = *n - 1;
+   20689           0 :         for (j = 1; j <= i__2; ++j) {
+   20690           0 :             dplus = d__[j] + s;
+   20691           0 :             s = s * lld[j] / dplus - mid;
+   20692           0 :             if (dplus < 0.) {
+   20693           0 :                 ++cnt;
+   20694             :             }
+   20695             :         }
+   20696           0 :         dplus = d__[*n] + s;
+   20697           0 :         if (dplus < 0.) {
+   20698           0 :             ++cnt;
+   20699             :         }
+   20700           0 :         if (std::isnan(s)) {
+   20701             :             cnt = 0;
+   20702             :             s = -mid;
+   20703             :             i__2 = *n - 1;
+   20704           0 :             for (j = 1; j <= i__2; ++j) {
+   20705           0 :                 dplus = d__[j] + s;
+   20706           0 :                 if (dplus < 0.) {
+   20707           0 :                     ++cnt;
+   20708             :                 }
+   20709           0 :                 tmp = lld[j] / dplus;
+   20710           0 :                 if (std::abs(tmp)<PLUMED_GMX_FLOAT_MIN) {
+   20711           0 :                     s = lld[j] - mid;
+   20712             :                 } else {
+   20713           0 :                     s = s * tmp - mid;
+   20714             :                 }
+   20715             :             }
+   20716           0 :             dplus = d__[*n] + s;
+   20717           0 :             if (dplus < 0.) {
+   20718           0 :                 ++cnt;
+   20719             :             }
+   20720             :         }
+   20721           0 :         i__2 = i__ - 1, i__3 = (nright<cnt) ? nright : cnt;
+   20722             :         cnt = (i__2>i__3) ? i__2 : i__3;
+   20723           0 :         if (cnt == i__ - 1) {
+   20724           0 :             work[k - 1] = mid;
+   20725           0 :         } else if (cnt == nright) {
+   20726           0 :             work[k] = mid;
+   20727             :         } else {
+   20728           0 :             iwork[k] = cnt;
+   20729           0 :             ++cnt;
+   20730           0 :             iwork[k - 1] = cnt;
+   20731           0 :             kk = cnt << 1;
+   20732           0 :             iwork[kk - 1] = next;
+   20733           0 :             iwork[kk] = nright;
+   20734           0 :             work[k] = mid;
+   20735           0 :             work[kk - 1] = mid;
+   20736           0 :             work[kk] = right;
+   20737             :             prev = cnt;
+   20738           0 :             if (cnt - 1 > i__) {
+   20739           0 :                 work[kk - 2] = mid;
+   20740             :             }
+   20741           0 :             if (cnt > *ifirst && cnt <= *ilast) {
+   20742           0 :                 ++nint;
+   20743           0 :             } else if (cnt <= *ifirst) {
+   20744             :                 i1 = cnt;
+   20745             :             }
+   20746             :         }
+   20747             :         i__ = next;
+   20748             :     }
+   20749           0 :     if (nint > 0) {
+   20750           0 :         goto L80;
+   20751             :     }
+   20752           0 :     i__1 = *ilast;
+   20753           0 :     for (i__ = *ifirst; i__ <= i__1; ++i__) {
+   20754           0 :         k = i__ << 1;
+   20755           0 :         ii = i__ - *offset;
+   20756           0 :         if (iwork[k - 1] != -1) {
+   20757           0 :             w[ii] = (work[k - 1] + work[k]) * .5;
+   20758           0 :             werr[ii] = work[k] - w[ii];
+   20759           0 :             if (i__ != *ilast) {
+   20760           0 :                 wgap[ii] = work[k + 1] - work[k];
+   20761             :             }
+   20762             :         }
+   20763             :     }
+   20764             : 
+   20765           0 :     return;
+   20766             : 
+   20767             : } 
+   20768             : }
+   20769             : }
+   20770             : #include <cctype>
+   20771             : #include <cmath>
+   20772             : 
+   20773             : #include "real.h"
+   20774             : 
+   20775             : #include "blas/blas.h"
+   20776             : #include "lapack.h"
+   20777             : #include "lapack_limits.h"
+   20778             : 
+   20779             : 
+   20780             : 
+   20781             : #include "blas/blas.h"
+   20782             : namespace PLMD{
+   20783             : namespace lapack{
+   20784             : using namespace blas;
+   20785             : void
+   20786           0 : PLUMED_BLAS_F77_FUNC(slarrex,SLARREX)(const char *range,
+   20787             :          int *n, 
+   20788             :          float *vl, 
+   20789             :          float *vu, 
+   20790             :          int *il, 
+   20791             :          int *iu, 
+   20792             :          float *d__, 
+   20793             :          float *e, 
+   20794             :          float *tol, 
+   20795             :          int *nsplit, 
+   20796             :          int *isplit, 
+   20797             :          int *m, 
+   20798             :          float *w, 
+   20799             :          int *iblock, 
+   20800             :          int *indexw, 
+   20801             :          float *gersch, 
+   20802             :          float *work,
+   20803             :          int *iwork, 
+   20804             :          int *info)
+   20805             : {
+   20806             :     int i__1, i__2, i__3;
+   20807             :     float d__1, d__2;
+   20808           0 :     int c__1 = 1;
+   20809           0 :     int c__0 = 0;
+   20810             : 
+   20811             :     int i__, j, k;
+   20812             :     float s, gl;
+   20813             :     int in;
+   20814             :     float gu;
+   20815             :     int cnt;
+   20816             :     float eps, tau, nrm, tmp, vvl, vvu, offd;
+   20817             :     int iend, jblk, till, itmp;
+   20818             :     float rtol, delta, sigma;
+   20819             :     int iinfo;
+   20820             :     float width;
+   20821             :     int ibegin;
+   20822             :     int irange;
+   20823             :     float sgndef;
+   20824             :     int maxcnt;
+   20825           0 :     --iwork;
+   20826           0 :     --work;
+   20827           0 :     --gersch;
+   20828           0 :     --indexw;
+   20829           0 :     --iblock;
+   20830           0 :     --w;
+   20831           0 :     --isplit;
+   20832           0 :     --e;
+   20833           0 :     --d__;
+   20834             : 
+   20835             :     sigma = 0;
+   20836             :     irange = 0;
+   20837             :     sgndef = 0;
+   20838             :     maxcnt = 0;
+   20839             : 
+   20840           0 :     *info = 0;
+   20841             : 
+   20842           0 :     if (*range=='A' || *range=='a')
+   20843             :         irange = 1;
+   20844           0 :     else if (*range=='V' || *range=='v')
+   20845             :         irange = 2;
+   20846           0 :     else if (*range=='I' || *range=='i')
+   20847             :         irange = 3;
+   20848             :     
+   20849             : 
+   20850           0 :     *m = 0;
+   20851             :     eps = PLUMED_GMX_FLOAT_EPS;
+   20852             : 
+   20853           0 :     *nsplit = 1;
+   20854           0 :     i__1 = *n - 1;
+   20855           0 :     for (i__ = 1; i__ <= i__1; ++i__) {
+   20856           0 :         if (std::abs(e[i__]) <= *tol) {
+   20857           0 :             isplit[*nsplit] = i__;
+   20858           0 :             ++(*nsplit);
+   20859             :         }
+   20860             :     }
+   20861           0 :     isplit[*nsplit] = *n;
+   20862             : 
+   20863             :     ibegin = 1;
+   20864           0 :     i__1 = *nsplit;
+   20865           0 :     for (jblk = 1; jblk <= i__1; ++jblk) {
+   20866           0 :         iend = isplit[jblk];
+   20867           0 :         if (ibegin == iend) {
+   20868           0 :             ++(*m);
+   20869           0 :             w[*m] = d__[ibegin];
+   20870           0 :             iblock[*m] = jblk;
+   20871           0 :             indexw[*m] = 1;
+   20872           0 :             e[iend] = 0.;
+   20873           0 :             ibegin = iend + 1;
+   20874           0 :             goto L170;
+   20875             :         }
+   20876           0 :         in = iend - ibegin + 1;
+   20877             : 
+   20878           0 :         gl = d__[ibegin] - std::abs(e[ibegin]);
+   20879           0 :         gu = d__[ibegin] + std::abs(e[ibegin]);
+   20880           0 :         gersch[(ibegin << 1) - 1] = gl;
+   20881           0 :         gersch[ibegin * 2] = gu;
+   20882           0 :         gersch[(iend << 1) - 1] = d__[iend] - std::abs(e[iend - 1]);
+   20883           0 :         gersch[iend * 2] = d__[iend] + std::abs(e[iend - 1]);
+   20884           0 :         d__1 = gersch[(iend << 1) - 1];
+   20885           0 :         gl = (d__1<gl) ? d__1 : gl;
+   20886             :         d__1 = gersch[iend * 2];
+   20887           0 :         gu = (d__1>gu) ? d__1 : gu;
+   20888           0 :         i__2 = iend - 1;
+   20889           0 :         for (i__ = ibegin + 1; i__ <= i__2; ++i__) {
+   20890           0 :             offd = std::abs(e[i__ - 1]) + std::abs(e[i__]);
+   20891           0 :             gersch[(i__ << 1) - 1] = d__[i__] - offd;
+   20892             :             d__1 = gersch[(i__ << 1) - 1];
+   20893           0 :             gl = (d__1<gl) ? d__1 : gl;
+   20894           0 :             gersch[i__ * 2] = d__[i__] + offd;
+   20895             :             d__1 = gersch[i__ * 2];
+   20896           0 :             gu = (d__1>gu) ? d__1 : gu;
+   20897             :         }
+   20898             :         d__1 = std::abs(gl), d__2 = std::abs(gu);
+   20899           0 :         nrm = (d__1>d__2) ? d__1 : d__2;
+   20900             : 
+   20901           0 :         width = gu - gl;
+   20902             :         i__2 = iend - 1;
+   20903           0 :         for (i__ = ibegin; i__ <= i__2; ++i__) {
+   20904           0 :             work[i__] = e[i__] * e[i__];
+   20905             :         }
+   20906           0 :         for (j = 1; j <= 2; ++j) {
+   20907           0 :             if (j == 1) {
+   20908           0 :                 tau = gl + width * .25;
+   20909             :             } else {
+   20910           0 :                 tau = gu - width * .25;
+   20911             :             }
+   20912           0 :             tmp = d__[ibegin] - tau;
+   20913           0 :             if (tmp < 0.) {
+   20914           0 :                 cnt = 1;
+   20915             :             } else {
+   20916           0 :                 cnt = 0;
+   20917             :             }
+   20918           0 :             i__2 = iend;
+   20919           0 :             for (i__ = ibegin + 1; i__ <= i__2; ++i__) {
+   20920           0 :                 tmp = d__[i__] - tau - work[i__ - 1] / tmp;
+   20921           0 :                 if (tmp < 0.) {
+   20922           0 :                     ++cnt;
+   20923             :                 }
+   20924             :             }
+   20925           0 :             if (cnt == 0) {
+   20926             :                 gl = tau;
+   20927           0 :             } else if (cnt == in) {
+   20928             :                 gu = tau;
+   20929             :             }
+   20930           0 :             if (j == 1) {
+   20931             :                 maxcnt = cnt;
+   20932             :                 sigma = gl;
+   20933             :                 sgndef = 1.;
+   20934             :             } else {
+   20935           0 :                 if (in - cnt > maxcnt) {
+   20936             :                     sigma = gu;
+   20937             :                     sgndef = -1.;
+   20938             :                 }
+   20939             :             }
+   20940             :         }
+   20941             : 
+   20942           0 :         work[in * 3] = 1.;
+   20943             :         delta = eps;
+   20944           0 :         tau = sgndef * nrm;
+   20945           0 : L60:
+   20946           0 :         sigma -= delta * tau;
+   20947           0 :         work[1] = d__[ibegin] - sigma;
+   20948             :         j = ibegin;
+   20949           0 :         i__2 = in - 1;
+   20950           0 :         for (i__ = 1; i__ <= i__2; ++i__) {
+   20951           0 :             work[(in << 1) + i__] = 1. / work[i__];
+   20952           0 :             tmp = e[j] * work[(in << 1) + i__];
+   20953           0 :             work[i__ + 1] = d__[j + 1] - sigma - tmp * e[j];
+   20954           0 :             work[in + i__] = tmp;
+   20955           0 :             ++j;
+   20956             :         }
+   20957           0 :         for (i__ = in; i__ >= 1; --i__) {
+   20958           0 :             tmp = sgndef * work[i__];
+   20959           0 :             if (tmp < 0. || std::abs(work[(in << 1) + i__])<PLUMED_GMX_FLOAT_MIN || std::isnan(tmp)) {
+   20960           0 :                 delta *= 2.;
+   20961           0 :                 goto L60;
+   20962             :             }
+   20963             :         }
+   20964             : 
+   20965           0 :         PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&in, &work[1], &c__1, &d__[ibegin], &c__1);
+   20966           0 :         i__2 = in - 1;
+   20967           0 :         PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&i__2, &work[in + 1], &c__1, &e[ibegin], &c__1);
+   20968           0 :         i__2 = in - 1;
+   20969           0 :         for (i__ = 1; i__ <= i__2; ++i__) {
+   20970           0 :             work[in * 3 + i__] = work[i__] * work[in + i__];
+   20971           0 :             work[(in << 2) + i__] = work[in * 3 + i__] * work[in + i__];
+   20972             :         }
+   20973           0 :         if (sgndef > 0.) {
+   20974           0 :             cnt = 1;
+   20975           0 :             work[1] = (gl + gu) / 2. - sigma;
+   20976           0 :             work[in + 1] = 0.;
+   20977           0 :             work[(in << 1) + 1] = (gu - gl) / 2.;
+   20978             :         } else {
+   20979           0 :             cnt = in;
+   20980           0 :             work[in] = (gl + gu) / 2. - sigma;
+   20981           0 :             work[in * 2] = 0.;
+   20982           0 :             work[in * 3] = (gu - gl) / 2.;
+   20983             :         }
+   20984           0 :         rtol = eps * 4.;
+   20985           0 :         PLUMED_BLAS_F77_FUNC(slarrbx,SLARRBX)(&in, &d__[ibegin], &e[ibegin], &work[in * 3 + 1], &work[(in <<
+   20986           0 :                  2) + 1], &cnt, &cnt, &rtol, &rtol, &c__0, &work[1], &work[in 
+   20987           0 :                 + 1], &work[(in << 1) + 1], &work[in * 5 + 1], &iwork[1], &
+   20988             :                 iinfo);
+   20989           0 :         if (sgndef > 0.) {
+   20990           0 :             tau = work[1] - work[(in << 1) + 1];
+   20991             :         } else {
+   20992           0 :             tau = work[in] + work[in * 3];
+   20993             :         }
+   20994             : 
+   20995           0 :         work[in * 3] = 1.;
+   20996             :         delta = eps * 2.;
+   20997           0 : L100:
+   20998           0 :         tau *= 1. - delta;
+   20999             : 
+   21000           0 :         s = -tau;
+   21001             :         j = ibegin;
+   21002           0 :         i__2 = in - 1;
+   21003           0 :         for (i__ = 1; i__ <= i__2; ++i__) {
+   21004           0 :             work[i__] = d__[j] + s;
+   21005           0 :             work[(in << 1) + i__] = 1. / work[i__];
+   21006           0 :             work[in + i__] = e[j] * d__[j] * work[(in << 1) + i__];
+   21007           0 :             s = s * work[in + i__] * e[j] - tau;
+   21008           0 :             ++j;
+   21009             :         }
+   21010           0 :         work[in] = d__[iend] + s;
+   21011             : 
+   21012           0 :         for (i__ = in; i__ >= 1; --i__) {
+   21013           0 :             tmp = sgndef * work[i__];
+   21014           0 :             if (tmp < 0. || std::abs(work[(in << 1) + i__])<PLUMED_GMX_FLOAT_MIN || std::isnan(tmp)) {
+   21015           0 :                 delta *= 2.;
+   21016           0 :                 goto L100;
+   21017             :             }
+   21018             :         }
+   21019             : 
+   21020           0 :         sigma += tau;
+   21021           0 :         PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&in, &work[1], &c__1, &d__[ibegin], &c__1);
+   21022           0 :         i__2 = in - 1;
+   21023           0 :         PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&i__2, &work[in + 1], &c__1, &e[ibegin], &c__1);
+   21024           0 :         e[iend] = sigma;
+   21025           0 :         tmp = (float) in * 4. * eps * (std::abs(sigma) + std::abs(tau));
+   21026             :         i__2 = iend;
+   21027           0 :         for (i__ = ibegin; i__ <= i__2; ++i__) {
+   21028           0 :             gersch[(i__ << 1) - 1] = gersch[(i__ << 1) - 1] - sigma - tmp;
+   21029           0 :             gersch[i__ * 2] = gersch[i__ * 2] - sigma + tmp;
+   21030             :         }
+   21031             : 
+   21032             :         j = ibegin;
+   21033           0 :         i__2 = in - 1;
+   21034           0 :         for (i__ = 1; i__ <= i__2; ++i__) {
+   21035           0 :             work[(i__ << 1) - 1] = std::abs(d__[j]);
+   21036           0 :             work[i__ * 2] = e[j] * e[j] * work[(i__ << 1) - 1];
+   21037           0 :             ++j;
+   21038             :         }
+   21039           0 :         work[(in << 1) - 1] = std::abs(d__[iend]);
+   21040             : 
+   21041           0 :         PLUMED_BLAS_F77_FUNC(slasq2,SLASQ2)(&in, &work[1], info);
+   21042           0 :         if (*info != 0) {
+   21043             :             return;
+   21044             :         }
+   21045             : 
+   21046           0 :         if (sgndef > 0.) {
+   21047           0 :             i__2 = in;
+   21048           0 :             for (i__ = 1; i__ <= i__2; ++i__) {
+   21049           0 :                 ++(*m);
+   21050           0 :                 w[*m] = work[in - i__ + 1];
+   21051           0 :                 iblock[*m] = jblk;
+   21052           0 :                 indexw[*m] = i__;
+   21053             :             }
+   21054             :         } else {
+   21055           0 :             i__2 = in;
+   21056           0 :             for (i__ = 1; i__ <= i__2; ++i__) {
+   21057           0 :                 ++(*m);
+   21058           0 :                 w[*m] = -work[i__];
+   21059           0 :                 iblock[*m] = jblk;
+   21060           0 :                 indexw[*m] = i__;
+   21061             :             }
+   21062             :         }
+   21063           0 :         ibegin = iend + 1;
+   21064           0 : L170:
+   21065             :         ;
+   21066             :     }
+   21067           0 :     if (irange == 2) {
+   21068           0 :         *m = 0;
+   21069             :         ibegin = 1;
+   21070           0 :         i__1 = *nsplit;
+   21071           0 :         for (i__ = 1; i__ <= i__1; ++i__) {
+   21072           0 :             iend = isplit[i__];
+   21073           0 :             vvl = *vl - e[iend];
+   21074           0 :             vvu = *vu - e[iend];
+   21075           0 :             i__2 = iend;
+   21076           0 :             for (j = ibegin; j <= i__2; ++j) {
+   21077           0 :                 if (vvl <= w[j] && w[j] <= vvu) {
+   21078           0 :                     ++(*m);
+   21079           0 :                     w[*m] = w[j];
+   21080           0 :                     iblock[*m] = i__;
+   21081           0 :                     indexw[*m] = j - ibegin + 1;
+   21082             :                 }
+   21083             :             }
+   21084           0 :             ibegin = iend + 1;
+   21085             :         }
+   21086           0 :     } else if (irange == 3) {
+   21087           0 :         *m = *iu - *il + 1;
+   21088           0 :         if (*nsplit == 1) {
+   21089             :             i__1 = *m;
+   21090           0 :             for (i__ = 1; i__ <= i__1; ++i__) {
+   21091           0 :                 w[i__] = w[*il + i__ - 1];
+   21092           0 :                 indexw[i__] = *il + i__ - 1;
+   21093             :             }
+   21094             :         } else {
+   21095             :             ibegin = 1;
+   21096             :             i__1 = *nsplit;
+   21097           0 :             for (i__ = 1; i__ <= i__1; ++i__) {
+   21098           0 :                 iend = isplit[i__];
+   21099           0 :                 i__2 = iend;
+   21100           0 :                 for (j = ibegin; j <= i__2; ++j) {
+   21101           0 :                     work[j] = w[j] + e[iend];
+   21102             :                 }
+   21103           0 :                 ibegin = iend + 1;
+   21104             :             }
+   21105           0 :             i__1 = *n;
+   21106           0 :             for (i__ = 1; i__ <= i__1; ++i__) {
+   21107           0 :                 iwork[i__] = i__;
+   21108           0 :                 iwork[*n + i__] = iblock[i__];
+   21109             :             }
+   21110           0 :             PLUMED_BLAS_F77_FUNC(slasrt2,SLASRT2)("I", n, &work[1], &iwork[1], &iinfo);
+   21111           0 :             i__1 = *m;
+   21112           0 :             for (i__ = 1; i__ <= i__1; ++i__) {
+   21113           0 :                 itmp = iwork[*il + i__ - 1];
+   21114           0 :                 work[i__] = w[itmp];
+   21115           0 :                 iblock[i__] = iwork[*n + itmp];
+   21116             :             }
+   21117           0 :             i__1 = *m;
+   21118           0 :             for (i__ = 1; i__ <= i__1; ++i__) {
+   21119           0 :                 iwork[*n + i__] = iwork[*il + i__ - 1];
+   21120           0 :                 iwork[i__] = i__;
+   21121             :             }
+   21122           0 :             PLUMED_BLAS_F77_FUNC(ilasrt2,ILASRT2)("I", m, &iblock[1], &iwork[1], &iinfo);
+   21123             :             j = 1;
+   21124           0 :             itmp = iblock[j];
+   21125           0 :             cnt = iwork[*n + iwork[j]];
+   21126           0 :             if (itmp == 1) {
+   21127             :                 ibegin = 1;
+   21128             :             } else {
+   21129           0 :                 ibegin = isplit[itmp - 1] + 1;
+   21130             :             }
+   21131           0 :             i__1 = *m;
+   21132           0 :             for (i__ = 1; i__ <= i__1; ++i__) {
+   21133           0 :                 w[i__] = work[iwork[i__]];
+   21134           0 :                 if (iblock[i__] != itmp || i__ == *m) {
+   21135           0 :                     if (iblock[i__] == itmp) {
+   21136           0 :                         till = *m;
+   21137             :                     } else {
+   21138           0 :                         till = i__ - 1;
+   21139             :                     }
+   21140           0 :                     i__2 = till - j + 1;
+   21141           0 :                     PLUMED_BLAS_F77_FUNC(slasrt,SLASRT)("I", &i__2, &w[j], &iinfo);
+   21142           0 :                     cnt = cnt - ibegin + 1;
+   21143           0 :                     i__2 = till;
+   21144           0 :                     for (k = j; k <= i__2; ++k) {
+   21145           0 :                         indexw[k] = cnt + k - j;
+   21146             :                     }
+   21147             :                     j = i__;
+   21148           0 :                     itmp = iblock[j];
+   21149           0 :                     cnt = iwork[*n + iwork[j]];
+   21150           0 :                     ibegin = isplit[itmp - 1] + 1;
+   21151           0 :                     if (i__ == *m && till < *m) {
+   21152           0 :                         indexw[*m] = cnt - ibegin + 1;
+   21153             :                     }
+   21154             :                 } else {
+   21155           0 :                     i__2 = cnt, i__3 = iwork[*n + iwork[i__]];
+   21156           0 :                     cnt = (i__2<i__3) ? i__2 : i__3;
+   21157             :                 }
+   21158             :             }
+   21159             :         }
+   21160             :     }
+   21161             : 
+   21162             :     return;
+   21163             : 
+   21164             : }
+   21165             : 
+   21166             : 
+   21167             : }
+   21168             : }
+   21169             : #include <cmath>
+   21170             : 
+   21171             : #include "real.h"
+   21172             : 
+   21173             : #include "blas/blas.h"
+   21174             : #include "lapack.h"
+   21175             : #include "lapack_limits.h"
+   21176             : 
+   21177             : 
+   21178             : #include "blas/blas.h"
+   21179             : namespace PLMD{
+   21180             : namespace lapack{
+   21181             : using namespace blas;
+   21182             : void
+   21183           0 : PLUMED_BLAS_F77_FUNC(slarrfx,SLARRFX)(int *n, 
+   21184             :         float *d__, 
+   21185             :         float *l, 
+   21186             :         float *ld, 
+   21187             :         float *lld, 
+   21188             :         int *ifirst, 
+   21189             :         int *ilast, 
+   21190             :         float *w, 
+   21191             :         float *sigma, 
+   21192             :         float *dplus, 
+   21193             :         float *lplus, 
+   21194             :         float *work,
+   21195             :         int *info)
+   21196             : {
+   21197           0 :     int i1 = 1;
+   21198             :     int i__1;
+   21199             :     float d__2, d__3;
+   21200             : 
+   21201             :     int i__;
+   21202             :     float s, eps, tmp, dmax1, dmax2, delta;
+   21203           0 :     --work;
+   21204           0 :     --lplus;
+   21205           0 :     --dplus;
+   21206           0 :     --w;
+   21207             :     --lld;
+   21208           0 :     --ld;
+   21209           0 :     --l;
+   21210           0 :     --d__;
+   21211           0 :     *info = 0;
+   21212             :     eps = PLUMED_GMX_FLOAT_EPS;
+   21213           0 :     *sigma = w[*ifirst];
+   21214             :     delta = eps * 2.;
+   21215             : 
+   21216           0 : L10:
+   21217           0 :     s = -(*sigma);
+   21218           0 :     dplus[1] = d__[1] + s;
+   21219             :     dmax1 = std::abs(dplus[1]);
+   21220           0 :     i__1 = *n - 1;
+   21221           0 :     for (i__ = 1; i__ <= i__1; ++i__) {
+   21222           0 :         lplus[i__] = ld[i__] / dplus[i__];
+   21223           0 :         s = s * lplus[i__] * l[i__] - *sigma;
+   21224           0 :         dplus[i__ + 1] = d__[i__ + 1] + s;
+   21225             :         d__2 = dmax1, d__3 = std::abs(dplus[i__ + 1]);
+   21226           0 :         dmax1 = (d__2>d__3) ? d__2 : d__3;
+   21227             :     }
+   21228           0 :     if (std::isnan(dmax1)) {
+   21229           0 :         *sigma -= std::abs(*sigma) * delta;
+   21230           0 :         delta *= 2.;
+   21231           0 :         goto L10;
+   21232             :     }
+   21233             : 
+   21234           0 :     tmp = w[*ilast];
+   21235             :     delta = eps * 2.;
+   21236           0 : L30:
+   21237           0 :     s = -tmp;
+   21238           0 :     work[1] = d__[1] + s;
+   21239             :     dmax2 = std::abs(work[1]);
+   21240           0 :     i__1 = *n - 1;
+   21241           0 :     for (i__ = 1; i__ <= i__1; ++i__) {
+   21242           0 :         work[*n + i__] = ld[i__] / work[i__];
+   21243           0 :         s = s * work[*n + i__] * l[i__] - tmp;
+   21244           0 :         work[i__ + 1] = d__[i__ + 1] + s;
+   21245             :         d__2 = dmax2, d__3 = std::abs(work[i__ + 1]);
+   21246           0 :         dmax2 = (d__2>d__3) ? d__2 : d__3;
+   21247             :     }
+   21248           0 :     if (std::isnan(dmax2)) {
+   21249           0 :         tmp += std::abs(tmp) * delta;
+   21250           0 :         delta *= 2.;
+   21251           0 :         goto L30;
+   21252             :     }
+   21253           0 :     if (dmax2 < dmax1) {
+   21254           0 :         *sigma = tmp;
+   21255           0 :         PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(n, &work[1], &i1, &dplus[1], &i1);
+   21256           0 :         i__1 = *n - 1;
+   21257           0 :         PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&i__1, &work[*n + 1], &i1, &lplus[1], &i1);
+   21258             :     }
+   21259             : 
+   21260           0 :     return;
+   21261             : }
+   21262             : }
+   21263             : }
+   21264             : #include <cmath>
+   21265             : 
+   21266             : #include "real.h"
+   21267             : 
+   21268             : #include "blas/blas.h"
+   21269             : #include "lapack.h"
+   21270             : #include "lapack_limits.h"
+   21271             : 
+   21272             : 
+   21273             : #include "blas/blas.h"
+   21274             : namespace PLMD{
+   21275             : namespace lapack{
+   21276             : using namespace blas;
+   21277             : void
+   21278           0 : PLUMED_BLAS_F77_FUNC(slarrvx,SLARRVX)(int *n, 
+   21279             :         float *d__, 
+   21280             :         float *l, 
+   21281             :         int *isplit,
+   21282             :         int *m, 
+   21283             :         float *w,
+   21284             :         int *iblock, 
+   21285             :         int *indexw, 
+   21286             :         float *gersch, 
+   21287             :         float *tol, 
+   21288             :         float *z__, 
+   21289             :         int *ldz, 
+   21290             :         int *isuppz, 
+   21291             :         float *work, 
+   21292             :         int *iwork, 
+   21293             :         int *info)
+   21294             : {
+   21295             :     int z_dim1, z_offset, i__1, i__2, i__3, i__4, i__5, i__6;
+   21296             :     float d__1, d__2;
+   21297           0 :     float c_b5 = 0.;
+   21298           0 :     int c__1 = 1;
+   21299           0 :     int c__2 = 2;
+   21300             : 
+   21301             :     int i__, j, k, p, q;
+   21302             :     int im, in;
+   21303             :     float gap, eps, tmp;
+   21304             :     int zto;
+   21305             :     float ztz;
+   21306             :     int iend, jblk;
+   21307             :     int wend, iter, temp[1], ktot;
+   21308             :     int itmp1, itmp2;
+   21309             :     int indld;
+   21310             :     float sigma;
+   21311             :     int ndone, iinfo, iindr;
+   21312             :     float resid;
+   21313             :     int nomgs;
+   21314             :     int nclus;
+   21315             :     int zfrom, iindc1, iindc2;
+   21316             :     float lambda;
+   21317             :     int ibegin;
+   21318             :     int indgap, indlld;
+   21319             :     float mingma;
+   21320             :     int oldien, oldncl, wbegin;
+   21321             :     float relgap;
+   21322             :     int oldcls;
+   21323             :     int ndepth, inderr, iindwk;
+   21324             :     int newcls, oldfst;
+   21325             :     float minrgp=0.0;
+   21326             :     int indwrk, oldlst;
+   21327             :     float reltol;
+   21328             :     int newfrs, newftt, parity;
+   21329             :     float mgstol, nrminv, rqcorr;
+   21330             :     int newlst, newsiz;
+   21331             : 
+   21332             : 
+   21333           0 :     --d__;
+   21334           0 :     --l;
+   21335             :     --isplit;
+   21336           0 :     --w;
+   21337           0 :     --iblock;
+   21338           0 :     --indexw;
+   21339             :     --gersch;
+   21340           0 :     z_dim1 = *ldz;
+   21341           0 :     z_offset = 1 + z_dim1;
+   21342           0 :     z__ -= z_offset;
+   21343           0 :     --isuppz;
+   21344           0 :     --work;
+   21345           0 :     --iwork;
+   21346             : 
+   21347           0 :     inderr = *n;
+   21348           0 :     indld = *n << 1;
+   21349           0 :     indlld = *n * 3;
+   21350           0 :     indgap = *n << 2;
+   21351           0 :     indwrk = *n * 5 + 1;
+   21352             : 
+   21353             :     iindr = *n;
+   21354             :     iindc1 = *n << 1;
+   21355             :     iindc2 = *n * 3;
+   21356           0 :     iindwk = (*n << 2) + 1;
+   21357             : 
+   21358             :     eps = PLUMED_GMX_FLOAT_EPS;
+   21359             : 
+   21360             :     i__1 = *n << 1;
+   21361           0 :     for (i__ = 1; i__ <= i__1; ++i__) {
+   21362           0 :         iwork[i__] = 0;
+   21363             :     }
+   21364           0 :     PLUMED_BLAS_F77_FUNC(slaset,SLASET)("Full", n, m, &c_b5, &c_b5, &z__[z_offset], ldz);
+   21365             :     mgstol = eps * 100.;
+   21366             : 
+   21367             :     ibegin = 1;
+   21368             :     wbegin = 1;
+   21369           0 :     i__1 = iblock[*m];
+   21370           0 :     for (jblk = 1; jblk <= i__1; ++jblk) {
+   21371           0 :         iend = isplit[jblk];
+   21372             : 
+   21373           0 :         wend = wbegin - 1;
+   21374           0 : L171:
+   21375           0 :         if (wend < *m) {
+   21376           0 :             if (iblock[wend + 1] == jblk) {
+   21377           0 :                 ++wend;
+   21378           0 :                 goto L171;
+   21379             :             }
+   21380             :         }
+   21381           0 :         if (wend < wbegin) {
+   21382           0 :             ibegin = iend + 1;
+   21383           0 :             continue;
+   21384             :         }
+   21385             : 
+   21386           0 :         if (ibegin == iend) {
+   21387           0 :             z__[ibegin + wbegin * z_dim1] = 1.;
+   21388           0 :             isuppz[(wbegin << 1) - 1] = ibegin;
+   21389           0 :             isuppz[wbegin * 2] = ibegin;
+   21390           0 :             ibegin = iend + 1;
+   21391           0 :             wbegin = wend + 1;
+   21392           0 :             continue;
+   21393             :         }
+   21394           0 :         oldien = ibegin - 1;
+   21395           0 :         in = iend - oldien;
+   21396           0 :         d__1 = .001, d__2 = 1. / (float) in;
+   21397           0 :         reltol = (d__1<d__2) ? d__1 : d__2;
+   21398           0 :         im = wend - wbegin + 1;
+   21399           0 :         PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&im, &w[wbegin], &c__1, &work[1], &c__1);
+   21400           0 :         i__2 = im - 1;
+   21401           0 :         for (i__ = 1; i__ <= i__2; ++i__) {
+   21402           0 :             work[inderr + i__] = eps * std::abs(work[i__]);
+   21403           0 :             work[indgap + i__] = work[i__ + 1] - work[i__];
+   21404             :         }
+   21405           0 :         work[inderr + im] = eps * std::abs(work[im]);
+   21406           0 :         d__2 = std::abs(work[im]);
+   21407           0 :         work[indgap + im] = (d__2>eps) ? d__2 : eps;
+   21408             :         ndone = 0;
+   21409             : 
+   21410             :         ndepth = 0;
+   21411             :         parity = 1;
+   21412             :         nclus = 1;
+   21413           0 :         iwork[iindc1 + 1] = 1;
+   21414           0 :         iwork[iindc1 + 2] = im;
+   21415             : 
+   21416           0 : L40:
+   21417           0 :         if (ndone < im) {
+   21418             :             oldncl = nclus;
+   21419             :             nclus = 0;
+   21420           0 :             parity = 1 - parity;
+   21421           0 :             if (parity == 0) {
+   21422             :                 oldcls = iindc1;
+   21423             :                 newcls = iindc2;
+   21424             :             } else {
+   21425             :                 oldcls = iindc2;
+   21426             :                 newcls = iindc1;
+   21427             :             }
+   21428             :             i__2 = oldncl;
+   21429           0 :             for (i__ = 1; i__ <= i__2; ++i__) {
+   21430             : 
+   21431           0 :                 j = oldcls + (i__ << 1);
+   21432           0 :                 oldfst = iwork[j - 1];
+   21433           0 :                 oldlst = iwork[j];
+   21434           0 :                 if (ndepth > 0) {
+   21435           0 :                     j = wbegin + oldfst - 1;
+   21436           0 :                     PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&in, &z__[ibegin + j * z_dim1], &c__1, &d__[ibegin]
+   21437             :                             , &c__1);
+   21438           0 :                     i__3 = in - 1;
+   21439           0 :                     PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&i__3, &z__[ibegin + (j + 1) * z_dim1], &c__1, &l[
+   21440             :                             ibegin], &c__1);
+   21441           0 :                     PLUMED_BLAS_F77_FUNC(slaset,SLASET)("Full", &in, &c__2, &c_b5, &c_b5, &z__[ibegin + j 
+   21442             :                             * z_dim1], ldz);
+   21443             :                 }
+   21444             :                 k = ibegin;
+   21445           0 :                 i__3 = in - 1;
+   21446           0 :                 for (j = 1; j <= i__3; ++j) {
+   21447           0 :                     tmp = d__[k] * l[k];
+   21448           0 :                     work[indld + j] = tmp;
+   21449           0 :                     work[indlld + j] = tmp * l[k];
+   21450           0 :                     ++k;
+   21451             :                 }
+   21452           0 :                 if (ndepth > 0) {
+   21453             : 
+   21454           0 :                     p = indexw[wbegin - 1 + oldfst];
+   21455           0 :                     q = indexw[wbegin - 1 + oldlst];
+   21456           0 :                     d__1 = eps * 4.;
+   21457           0 :                     i__3 = p - oldfst;
+   21458           0 :                     PLUMED_BLAS_F77_FUNC(slarrbx,SLARRBX)(&in, &d__[ibegin], &l[ibegin], &work[indld + 1], &
+   21459           0 :                             work[indlld + 1], &p, &q, &reltol, &d__1, &i__3, &
+   21460           0 :                             work[1], &work[indgap + 1], &work[inderr + 1], &
+   21461           0 :                             work[indwrk + in], &iwork[iindwk], &iinfo);
+   21462             :                 }
+   21463           0 :                 newfrs = oldfst;
+   21464           0 :                 i__3 = oldlst;
+   21465           0 :                 for (j = oldfst; j <= i__3; ++j) {
+   21466           0 :                     if (j == oldlst || work[indgap + j] >= 
+   21467           0 :                         reltol * std::abs(work[j])) {
+   21468           0 :                         newlst = j;
+   21469             :                     } else {
+   21470             : 
+   21471           0 :                         relgap = work[indgap + j] / std::abs(work[j]);
+   21472           0 :                         if (j == newfrs) {
+   21473             :                             minrgp = relgap;
+   21474             :                         } else {
+   21475           0 :                             minrgp = (minrgp<relgap) ? minrgp : relgap;
+   21476             :                         }
+   21477           0 :                         continue;
+   21478             :                     }
+   21479           0 :                     newsiz = newlst - newfrs + 1;
+   21480           0 :                     newftt = wbegin + newfrs - 1;
+   21481           0 :                     nomgs = newsiz == 1 || newsiz > 1 || minrgp < mgstol;
+   21482           0 :                     if (newsiz > 1 && nomgs) {
+   21483             : 
+   21484           0 :                         PLUMED_BLAS_F77_FUNC(slarrfx,SLARRFX)(&in, &d__[ibegin], &l[ibegin], &work[indld + 
+   21485           0 :                                 1], &work[indlld + 1], &newfrs, &newlst, &
+   21486           0 :                                 work[1], &sigma, &z__[ibegin + newftt * 
+   21487           0 :                                 z_dim1], &z__[ibegin + (newftt + 1) * z_dim1],
+   21488           0 :                                  &work[indwrk], info);
+   21489           0 :                         if (*info == 0) {
+   21490           0 :                             tmp = eps * std::abs(sigma);
+   21491           0 :                             i__4 = newlst;
+   21492           0 :                             for (k = newfrs; k <= i__4; ++k) {
+   21493           0 :                                 work[k] -= sigma;
+   21494           0 :                                 d__1 = work[indgap + k];
+   21495           0 :                                 work[indgap + k] = (d__1>tmp) ? d__1 : tmp;
+   21496           0 :                                 work[inderr + k] += tmp;
+   21497             :                             }
+   21498           0 :                             ++nclus;
+   21499           0 :                             k = newcls + (nclus << 1);
+   21500           0 :                             iwork[k - 1] = newfrs;
+   21501           0 :                             iwork[k] = newlst;
+   21502             :                         } else {
+   21503           0 :                             *info = 0;
+   21504           0 :                             if (minrgp < mgstol) {
+   21505             : 
+   21506           0 :                                 work[indwrk] = d__[ibegin];
+   21507           0 :                                 i__4 = in - 1;
+   21508           0 :                                 for (k = 1; k <= i__4; ++k) {
+   21509           0 :                                     work[indwrk + k] = d__[ibegin + k] + work[
+   21510           0 :                                             indlld + k];
+   21511             :                                 }
+   21512           0 :                                 i__4 = newsiz;
+   21513           0 :                                 for (k = 1; k <= i__4; ++k) {
+   21514           0 :                                     iwork[iindwk + k - 1] = 1;
+   21515             :                                 }
+   21516           0 :                                 i__4 = newlst;
+   21517           0 :                                 for (k = newfrs; k <= i__4; ++k) {
+   21518           0 :                                     isuppz[2*(oldien + k) - 1] = 1;
+   21519           0 :                                     isuppz[(oldien + k) * 2] = in;
+   21520             :                                 }
+   21521           0 :                                 temp[0] = in;
+   21522           0 :                                 PLUMED_BLAS_F77_FUNC(sstein,SSTEIN)(&in, &work[indwrk], &work[indld + 1], 
+   21523           0 :                                         &newsiz, &work[newfrs], &iwork[iindwk]
+   21524             :                                         , temp, &z__[ibegin + newftt * z_dim1]
+   21525           0 :                                         , ldz, &work[indwrk + in], &iwork[
+   21526           0 :                                         iindwk + in], &iwork[iindwk + (in*2)], &iinfo);
+   21527           0 :                                 if (iinfo != 0) {
+   21528           0 :                                     *info = 2;
+   21529           0 :                                     return;
+   21530             :                                 }
+   21531           0 :                                 ndone += newsiz;
+   21532             :                             }
+   21533             :                         }
+   21534             :                     } else {
+   21535             :                         ktot = newftt;
+   21536             :                         i__4 = newlst;
+   21537           0 :                         for (k = newfrs; k <= i__4; ++k) {
+   21538             :                             iter = 0;
+   21539           0 : L90:
+   21540           0 :                             lambda = work[k];
+   21541             : 
+   21542           0 :                             PLUMED_BLAS_F77_FUNC(slar1vx,SLAR1VX)(&in, &c__1, &in, &lambda, &d__[ibegin], &
+   21543           0 :                                     l[ibegin], &work[indld + 1], &work[indlld 
+   21544           0 :                                     + 1], &w[wbegin + k - 1], &gersch[(oldien 
+   21545           0 :                                     << 1) + 1], &z__[ibegin + ktot * z_dim1], 
+   21546           0 :                                     &ztz, &mingma, &iwork[iindr + ktot], &
+   21547           0 :                                     isuppz[(ktot << 1) - 1], &work[indwrk]);
+   21548           0 :                             tmp = 1. / ztz;
+   21549           0 :                             nrminv =  std::sqrt(tmp);
+   21550           0 :                             resid = std::abs(mingma) * nrminv;
+   21551           0 :                             rqcorr = mingma * tmp;
+   21552           0 :                             if (k == in) {
+   21553           0 :                                 gap = work[indgap + k - 1];
+   21554           0 :                             } else if (k == 1) {
+   21555           0 :                                 gap = work[indgap + k];
+   21556             :                             } else {
+   21557           0 :                                 d__1 = work[indgap + k - 1], d__2 = work[
+   21558           0 :                                         indgap + k];
+   21559           0 :                                 gap = (d__1<d__2) ? d__1 : d__2;
+   21560             :                             }
+   21561           0 :                             ++iter;
+   21562           0 :                             if (resid > *tol * gap && std::abs(rqcorr) > eps * 4. *
+   21563           0 :                                      std::abs(lambda)) {
+   21564           0 :                                 work[k] = lambda + rqcorr;
+   21565           0 :                                 if (iter < 8) {
+   21566           0 :                                     goto L90;
+   21567             :                                 }
+   21568             :                             }
+   21569           0 :                             iwork[ktot] = 1;
+   21570           0 :                             if (newsiz == 1) {
+   21571           0 :                                 ++ndone;
+   21572             :                             }
+   21573           0 :                             zfrom = isuppz[(ktot << 1) - 1];
+   21574           0 :                             zto = isuppz[ktot * 2];
+   21575           0 :                             i__5 = zto - zfrom + 1;
+   21576           0 :                             PLUMED_BLAS_F77_FUNC(sscal,SSCAL)(&i__5, &nrminv, &z__[ibegin + zfrom - 1 + 
+   21577           0 :                                     ktot * z_dim1], &c__1);
+   21578           0 :                             ++ktot;
+   21579             :                         }
+   21580           0 :                         if (newsiz > 1) {
+   21581           0 :                             itmp1 = isuppz[(newftt << 1) - 1];
+   21582           0 :                             itmp2 = isuppz[newftt * 2];
+   21583           0 :                             ktot = oldien + newlst;
+   21584             :                             i__4 = ktot;
+   21585           0 :                             for (p = newftt + 1; p <= i__4; ++p) {
+   21586           0 :                                 i__5 = p - 1;
+   21587           0 :                                 for (q = newftt; q <= i__5; ++q) {
+   21588           0 :                                     tmp = -PLUMED_BLAS_F77_FUNC(sdot,SDOT)(&in, &z__[ibegin + p * 
+   21589           0 :                                             z_dim1], &c__1, &z__[ibegin + q * 
+   21590           0 :                                             z_dim1], &c__1);
+   21591           0 :                                     PLUMED_BLAS_F77_FUNC(saxpy,SAXPY)(&in, &tmp, &z__[ibegin + q * 
+   21592           0 :                                             z_dim1], &c__1, &z__[ibegin + p * 
+   21593           0 :                                             z_dim1], &c__1);
+   21594             :                                 }
+   21595           0 :                                 tmp = 1. / PLUMED_BLAS_F77_FUNC(snrm2,SNRM2)(&in, &z__[ibegin + p * 
+   21596           0 :                                         z_dim1], &c__1);
+   21597           0 :                                 PLUMED_BLAS_F77_FUNC(sscal,SSCAL)(&in, &tmp, &z__[ibegin + p * z_dim1], &
+   21598             :                                         c__1);
+   21599           0 :                                 i__5 = itmp1, i__6 = isuppz[(p << 1) - 1];
+   21600             :                                 itmp1 = (i__5<i__6) ? i__5 : i__6;
+   21601           0 :                                 i__5 = itmp2, i__6 = isuppz[p * 2];
+   21602             :                                 itmp2 = (i__5>i__6) ? i__5 : i__6;
+   21603             :                             }
+   21604             :                             i__4 = ktot;
+   21605           0 :                             for (p = newftt; p <= i__4; ++p) {
+   21606           0 :                                 isuppz[(p << 1) - 1] = itmp1;
+   21607           0 :                                 isuppz[p * 2] = itmp2;
+   21608             :                             }
+   21609           0 :                             ndone += newsiz;
+   21610             :                         }
+   21611             :                     }
+   21612           0 :                     newfrs = j + 1;
+   21613             :                 }
+   21614             :             }
+   21615           0 :             ++ndepth;
+   21616           0 :             goto L40;
+   21617             :         }
+   21618           0 :         j = wbegin << 1;
+   21619             :         i__2 = wend;
+   21620           0 :         for (i__ = wbegin; i__ <= i__2; ++i__) {
+   21621           0 :             isuppz[j - 1] += oldien;
+   21622           0 :             isuppz[j] += oldien;
+   21623           0 :             j += 2;
+   21624             : 
+   21625             :         }
+   21626           0 :         ibegin = iend + 1;
+   21627           0 :         wbegin = wend + 1;
+   21628             :     }
+   21629             : 
+   21630             :     return;
+   21631             : 
+   21632             : } 
+   21633             : }
+   21634             : }
+   21635             : #include <cmath>
+   21636             : #include "lapack.h"
+   21637             : #include "lapack_limits.h"
+   21638             : 
+   21639             : #include "real.h"
+   21640             : 
+   21641             : #include "blas/blas.h"
+   21642             : namespace PLMD{
+   21643             : namespace lapack{
+   21644             : using namespace blas;
+   21645             : void
+   21646           0 : PLUMED_BLAS_F77_FUNC(slartg,SLARTG)(float *f,
+   21647             :         float *g,
+   21648             :         float *cs,
+   21649             :         float *sn,
+   21650             :         float *r)
+   21651             : {
+   21652             :   float minval,safemin, safemin2, safemx2, eps;
+   21653             :   float f1,g1,f1a,g1a,scale;
+   21654             :   int i,n,count;
+   21655             : 
+   21656             :   eps = PLUMED_GMX_FLOAT_EPS;
+   21657             :   minval = PLUMED_GMX_FLOAT_MIN;
+   21658             :   safemin = minval*(1.0+eps);
+   21659             :   n = static_cast<int>(0.5*std::log( safemin/eps ) / std::log(2.0));
+   21660             :   safemin2 = std::pow(static_cast<float>(2.0),static_cast<float>(n));
+   21661             : 
+   21662             :   safemx2 = 1.0 / safemin2;
+   21663             : 
+   21664           0 :   if(std::abs(*g)<PLUMED_GMX_FLOAT_MIN) {
+   21665           0 :     *cs = 1.0;
+   21666           0 :     *sn = 0.0;
+   21667           0 :     *r = *f;
+   21668           0 :   } else if (std::abs(*f)<PLUMED_GMX_FLOAT_MIN) {
+   21669           0 :     *cs = 0.0;
+   21670           0 :     *sn = 1.0;
+   21671           0 :     *r = *g;
+   21672             :   } else {
+   21673             :     f1 = *f;
+   21674             :     g1 = *g;
+   21675             :     f1a = std::abs(f1);
+   21676             :     g1a = std::abs(g1);
+   21677           0 :     scale = (f1a > g1a) ? f1a : g1a;
+   21678           0 :     if(scale >= safemx2) {
+   21679             :       count = 0;
+   21680           0 :       while(scale >= safemx2) {
+   21681           0 :         count++;
+   21682           0 :         f1 *= safemin2;
+   21683           0 :         g1 *= safemin2;
+   21684             :         f1a = std::abs(f1);
+   21685             :         g1a = std::abs(g1);
+   21686           0 :         scale = (f1a > g1a) ? f1a : g1a;
+   21687             :       }
+   21688           0 :       *r =  std::sqrt(f1*f1 + g1*g1);
+   21689           0 :       *cs = f1 / *r;
+   21690           0 :       *sn = g1 / *r;
+   21691           0 :       for(i=0;i<count;i++)
+   21692           0 :         *r *= safemx2;
+   21693           0 :     } else if (scale<=safemin2) {
+   21694             :       count = 0;
+   21695           0 :       while(scale <= safemin2) {
+   21696           0 :         count++;
+   21697           0 :         f1 *= safemx2;
+   21698           0 :         g1 *= safemx2;
+   21699             :         f1a = std::abs(f1);
+   21700             :         g1a = std::abs(g1);
+   21701           0 :         scale = (f1a > g1a) ? f1a : g1a;
+   21702             :       }
+   21703           0 :       *r =  std::sqrt(f1*f1 + g1*g1);
+   21704           0 :       *cs = f1 / *r;
+   21705           0 :       *sn = g1 / *r;
+   21706           0 :       for(i=0;i<count;i++)
+   21707           0 :         *r *= safemin2;
+   21708             :     } else {
+   21709           0 :       *r =  std::sqrt(f1*f1 + g1*g1);
+   21710           0 :       *cs = f1 / *r;
+   21711           0 :       *sn = g1 / *r;
+   21712             :     }
+   21713           0 :     if(std::abs(*f)>std::abs(*g) && *cs<0.0) {
+   21714           0 :       *cs *= -1.0;
+   21715           0 :       *sn *= -1.0;
+   21716           0 :       *r  *= -1.0;
+   21717             :     }
+   21718             :   }
+   21719           0 :   return;
+   21720             : }
+   21721             :       
+   21722             : }
+   21723             : }
+   21724             : #include <cmath>
+   21725             : #include "lapack.h"
+   21726             : 
+   21727             : #include "blas/blas.h"
+   21728             : namespace PLMD{
+   21729             : namespace lapack{
+   21730             : using namespace blas;
+   21731             : void
+   21732           0 : PLUMED_BLAS_F77_FUNC(slaruv,SLARUV)(int *iseed, int *n, float *x)
+   21733             : {
+   21734             :   const int
+   21735           0 :     mm[512] = {
+   21736             :       494,2637,255,2008,1253,
+   21737             :       3344,4084,1739,3143,3468,688,1657,1238,3166,1292,3422,1270,2016,
+   21738             :       154,2862,697,1706,491,931,1444,444,3577,3944,2184,1661,3482,657,
+   21739             :       3023,3618,1267,1828,164,3798,3087,2400,2870,3876,1905,1593,1797,
+   21740             :       1234,3460,328,2861,1950,617,2070,3331,769,1558,2412,2800,189,287,
+   21741             :       2045,1227,2838,209,2770,3654,3993,192,2253,3491,2889,2857,2094,
+   21742             :       1818,688,1407,634,3231,815,3524,1914,516,164,303,2144,3480,119,
+   21743             :       3357,837,2826,2332,2089,3780,1700,3712,150,2000,3375,1621,3090,
+   21744             :       3765,1149,3146,33,3082,2741,359,3316,1749,185,2784,2202,2199,1364,
+   21745             :       1244,2020,3160,2785,2772,1217,1822,1245,2252,3904,2774,997,2573,
+   21746             :       1148,545,322,789,1440,752,2859,123,1848,643,2405,2638,2344,46,
+   21747             :       3814,913,3649,339,3808,822,2832,3078,3633,2970,637,2249,2081,4019,
+   21748             :       1478,242,481,2075,4058,622,3376,812,234,641,4005,1122,3135,2640,
+   21749             :       2302,40,1832,2247,2034,2637,1287,1691,496,1597,2394,2584,1843,336,
+   21750             :       1472,2407,433,2096,1761,2810,566,442,41,1238,1086,603,840,3168,
+   21751             :       1499,1084,3438,2408,1589,2391,288,26,512,1456,171,1677,2657,2270,
+   21752             :       2587,2961,1970,1817,676,1410,3723,2803,3185,184,663,499,3784,1631,
+   21753             :       1925,3912,1398,1349,1441,2224,2411,1907,3192,2786,382,37,759,2948,
+   21754             :       1862,3802,2423,2051,2295,1332,1832,2405,3638,3661,327,3660,716,
+   21755             :       1842,3987,1368,1848,2366,2508,3754,1766,3572,2893,307,1297,3966,
+   21756             :       758,2598,3406,2922,1038,2934,2091,2451,1580,1958,2055,1507,1078,
+   21757             :       3273,17,854,2916,3971,2889,3831,2621,1541,893,736,3992,787,2125,
+   21758             :       2364,2460,257,1574,3912,1216,3248,3401,2124,2762,149,2245,166,466,
+   21759             :       4018,1399,190,2879,153,2320,18,712,2159,2318,2091,3443,1510,449,
+   21760             :       1956,2201,3137,3399,1321,2271,3667,2703,629,2365,2431,1113,3922,
+   21761             :       2554,184,2099,3228,4012,1921,3452,3901,572,3309,3171,817,3039,
+   21762             :       1696,1256,3715,2077,3019,1497,1101,717,51,981,1978,1813,3881,76,
+   21763             :       3846,3694,1682,124,1660,3997,479,1141,886,3514,1301,3604,1888,
+   21764             :       1836,1990,2058,692,1194,20,3285,2046,2107,3508,3525,3801,2549,
+   21765             :       1145,2253,305,3301,1065,3133,2913,3285,1241,1197,3729,2501,1673,
+   21766             :       541,2753,949,2361,1165,4081,2725,3305,3069,3617,3733,409,2157,
+   21767             :       1361,3973,1865,2525,1409,3445,3577,77,3761,2149,1449,3005,225,85,
+   21768             :       3673,3117,3089,1349,2057,413,65,1845,697,3085,3441,1573,3689,2941,
+   21769             :       929,533,2841,4077,721,2821,2249,2397,2817,245,1913,1997,3121,997,
+   21770             :       1833,2877,1633,981,2009,941,2449,197,2441,285,1473,2741,3129,909,
+   21771             :       2801,421,4073,2813,2337,1429,1177,1901,81,1669,2633,2269,129,1141,
+   21772             :       249,3917,2481,3941,2217,2749,3041,1877,345,2861,1809,3141,2825,
+   21773             :       157,2881,3637,1465,2829,2161,3365,361,2685,3745,2325,3609,3821,
+   21774             :       3537,517,3017,2141,1537 
+   21775             :     };
+   21776             : 
+   21777             :     int i__1;
+   21778             : 
+   21779             :     int i__, i1, i2, i3, i4, it1, it2, it3, it4;
+   21780             : 
+   21781             : 
+   21782             :     --iseed;
+   21783             :     --x;
+   21784             : 
+   21785             :     it1 = it2 = it3 = it4 = 0;
+   21786             : 
+   21787           0 :     i1 = iseed[1];
+   21788           0 :     i2 = iseed[2];
+   21789           0 :     i3 = iseed[3];
+   21790           0 :     i4 = iseed[4];
+   21791             : 
+   21792           0 :     i__1 = (*n<128) ? *n : 128;
+   21793           0 :     for (i__ = 1; i__ <= i__1; ++i__) {
+   21794             : 
+   21795           0 :         it4 = i4 * mm[i__ + 383];
+   21796           0 :         it3 = it4 / 4096;
+   21797           0 :         it4 -= it3 << 12;
+   21798           0 :         it3 = it3 + i3 * mm[i__ + 383] + i4 * mm[i__ + 255];
+   21799           0 :         it2 = it3 / 4096;
+   21800           0 :         it3 -= it2 << 12;
+   21801           0 :         it2 = it2 + i2 * mm[i__ + 383] + i3 * mm[i__ + 255] + 
+   21802           0 :           i4 * mm[i__ + 127];
+   21803           0 :         it1 = it2 / 4096;
+   21804           0 :         it2 -= it1 << 12;
+   21805           0 :         it1 = it1 + i1 * mm[i__ + 383] + i2 * mm[i__ + 255] + 
+   21806           0 :           i3 * mm[i__ + 127] + i4 * mm[i__ - 1];
+   21807           0 :         it1 %= 4096;
+   21808             : 
+   21809           0 :         x[i__] = ((float) it1 + ((float) it2 + ((float) it3 + (
+   21810           0 :                 float) it4 * 2.44140625e-4) * 2.44140625e-4) * 
+   21811           0 :                 2.44140625e-4) * 2.44140625e-4;
+   21812             :     }
+   21813             : 
+   21814           0 :     iseed[1] = it1;
+   21815           0 :     iseed[2] = it2;
+   21816           0 :     iseed[3] = it3;
+   21817           0 :     iseed[4] = it4;
+   21818           0 :     return;
+   21819             : 
+   21820             : } 
+   21821             : }
+   21822             : }
+   21823             : #include <cmath>
+   21824             : #include "real.h"
+   21825             : 
+   21826             : #include "lapack.h"
+   21827             : 
+   21828             : #include "blas/blas.h"
+   21829             : namespace PLMD{
+   21830             : namespace lapack{
+   21831             : using namespace blas;
+   21832             : void
+   21833           0 : PLUMED_BLAS_F77_FUNC(slas2,SLAS2)(float *f,
+   21834             :        float *g,
+   21835             :        float *h,
+   21836             :        float *ssmin,
+   21837             :        float *ssmax)
+   21838             : {
+   21839           0 :   float fa = std::abs(*f);
+   21840           0 :   float ga = std::abs(*g);
+   21841           0 :   float ha = std::abs(*h);
+   21842             :   float fhmin,fhmax,tmax,tmin,tmp1,tmp2;
+   21843             :   float as,at,au,c;
+   21844             : 
+   21845           0 :   fhmin = (fa<ha) ? fa : ha;
+   21846           0 :   fhmax = (fa>ha) ? fa : ha;
+   21847             :   
+   21848           0 :   if(std::abs(fhmin)<PLUMED_GMX_FLOAT_MIN) {
+   21849           0 :     *ssmin = 0.0;
+   21850           0 :     if(std::abs(fhmax)<PLUMED_GMX_FLOAT_MIN) 
+   21851           0 :       *ssmax = ga;
+   21852             :     else {
+   21853           0 :       tmax = (fhmax>ga) ? fhmax : ga;
+   21854           0 :       tmin = (fhmax<ga) ? fhmax : ga;
+   21855           0 :       tmp1 = tmin / tmax;
+   21856           0 :       tmp1 = tmp1 * tmp1;
+   21857           0 :       *ssmax = tmax* std::sqrt(1.0 + tmp1);
+   21858             :     }
+   21859             :   } else {
+   21860           0 :     if(ga<fhmax) {
+   21861           0 :       as = 1.0 + fhmin / fhmax;
+   21862           0 :       at = (fhmax-fhmin) / fhmax;
+   21863           0 :       au = (ga/fhmax);
+   21864           0 :       au = au * au;
+   21865           0 :       c = 2.0 / (  std::sqrt(as*as+au) + std::sqrt(at*at+au) );
+   21866           0 :       *ssmin = fhmin * c;
+   21867           0 :       *ssmax = fhmax / c;
+   21868             :     } else {
+   21869           0 :       au = fhmax / ga;
+   21870           0 :       if(std::abs(au)<PLUMED_GMX_FLOAT_MIN) {
+   21871           0 :         *ssmin = (fhmin*fhmax)/ga;
+   21872           0 :         *ssmax = ga;
+   21873             :       } else {
+   21874           0 :         as = 1.0 + fhmin / fhmax;
+   21875           0 :         at = (fhmax-fhmin)/fhmax;
+   21876           0 :         tmp1 = as*au;
+   21877           0 :         tmp2 = at*au;
+   21878           0 :         c = 1.0 / (  std::sqrt(1.0+tmp1*tmp1) + std::sqrt(1.0+tmp2*tmp2));
+   21879           0 :         *ssmin = (fhmin*c)*au;
+   21880           0 :         *ssmin = *ssmin + *ssmin;
+   21881           0 :         *ssmax = ga / (c+c);
+   21882             :       }
+   21883             :     }
+   21884             :   }
+   21885           0 :   return;
+   21886             : }
+   21887             : }
+   21888             : }
+   21889             : #include <cctype>
+   21890             : #include <cmath>
+   21891             : #include "real.h"
+   21892             : 
+   21893             : #include "lapack.h"
+   21894             : #include "lapack_limits.h"
+   21895             : 
+   21896             : 
+   21897             : #include "blas/blas.h"
+   21898             : namespace PLMD{
+   21899             : namespace lapack{
+   21900             : using namespace blas;
+   21901             : void
+   21902           0 : PLUMED_BLAS_F77_FUNC(slascl,SLASCL)(const char *type,
+   21903             :                         int *kl,
+   21904             :                         int *ku,
+   21905             :                         float *cfrom,
+   21906             :                         float *cto,
+   21907             :                         int *m,
+   21908             :                         int *n,
+   21909             :                         float *a,
+   21910             :                         int *lda,
+   21911             :                         int *info)
+   21912             : {
+   21913           0 :   const char ch=std::toupper(*type);
+   21914             :   int i,j,k,l,k1,k2,k3,k4;
+   21915             :   int done=0;
+   21916             :   float minval,smlnum,bignum;
+   21917             :   float cfromc, ctoc, cfrom1, cto1, mul;
+   21918             : 
+   21919           0 :   if(*n<=0 || *m<=0)
+   21920             :     return;
+   21921             : 
+   21922             :   minval = PLUMED_GMX_FLOAT_MIN;
+   21923             :   smlnum = minval / PLUMED_GMX_FLOAT_EPS;
+   21924             :   bignum = 1.0 / smlnum;
+   21925             : 
+   21926           0 :   cfromc = *cfrom;
+   21927           0 :   ctoc   = *cto;
+   21928             : 
+   21929           0 :   while(!done) {
+   21930             :     
+   21931           0 :     cfrom1 = cfromc * smlnum;
+   21932           0 :     cto1   = ctoc / bignum;
+   21933             : 
+   21934           0 :     if(std::abs(cfrom1)>std::abs(ctoc) && std::abs(ctoc)>PLUMED_GMX_FLOAT_MIN) {
+   21935             :       mul = smlnum;
+   21936             :       done = 0;
+   21937             :       cfromc = cfrom1;
+   21938           0 :     } else if(std::abs(cto1)>std::abs(cfromc)) {
+   21939             :       mul = bignum;
+   21940             :       done = 0;
+   21941             :       ctoc = cto1;
+   21942             :     } else {
+   21943           0 :       mul = ctoc / cfromc;
+   21944             :       done = 1;
+   21945             :     }
+   21946             : 
+   21947           0 :     switch(ch) {
+   21948             :     case 'G': 
+   21949             :       /* Full matrix */
+   21950           0 :       for(j=0;j<*n;j++)
+   21951           0 :         for(i=0;i<*m;i++)
+   21952           0 :           a[j*(*lda)+i] *= mul;
+   21953             :       break;
+   21954             : 
+   21955             :     case 'L': 
+   21956             :       /* Lower triangular matrix */
+   21957           0 :       for(j=0;j<*n;j++)
+   21958           0 :         for(i=j;i<*m;i++)
+   21959           0 :           a[j*(*lda)+i] *= mul;
+   21960             :       break;
+   21961             : 
+   21962             :     case 'U': 
+   21963             :       /* Upper triangular matrix */
+   21964           0 :       for(j=0;j<*n;j++) {
+   21965           0 :         k = (j < (*m-1)) ? j : (*m-1);
+   21966           0 :         for(i=0;i<=k;i++)
+   21967           0 :           a[j*(*lda)+i] *= mul;
+   21968             :       }
+   21969             :       break;
+   21970             : 
+   21971             :     case 'H': 
+   21972             :       /* Upper Hessenberg matrix */
+   21973           0 :       for(j=0;j<*n;j++) {
+   21974           0 :         k = ((j+1) < (*m-1)) ? (j+1) : (*m-1);
+   21975           0 :         for(i=0;i<=k;i++)
+   21976           0 :           a[j*(*lda)+i] *= mul;
+   21977             :       }
+   21978             :       break;
+   21979             : 
+   21980           0 :     case 'B': 
+   21981             :       /* Symmetric band matrix, lower bandwidth KL, upper KU,
+   21982             :        * only the lower half stored.
+   21983             :        */
+   21984           0 :       k3 = *kl;
+   21985           0 :       k4 = *n - 1;
+   21986           0 :       for(j=0;j<*n;j++) {
+   21987           0 :         k = (k3 < (k4-j)) ? k3 : (k4-j);
+   21988           0 :         for(i=0;i<=k;i++)
+   21989           0 :           a[j*(*lda)+i] *= mul;
+   21990             :       }
+   21991             :       break;
+   21992             : 
+   21993           0 :     case 'Q': 
+   21994             :       /* Symmetric band matrix, lower bandwidth KL, upper KU,
+   21995             :        * only the upper half stored.
+   21996             :        */
+   21997           0 :       k1 = *ku;
+   21998             :       k3 = *ku;
+   21999           0 :       for(j=0;j<*n;j++) {
+   22000           0 :         k = ((k1-j) > 0) ? (k1-j) : 0;
+   22001           0 :         for(i=k;i<=k3;i++)
+   22002           0 :           a[j*(*lda)+i] *= mul;
+   22003             :       }
+   22004             :       break;
+   22005             : 
+   22006           0 :     case 'Z': 
+   22007             :       /* Band matrix, lower bandwidth KL, upper KU. */
+   22008             : 
+   22009           0 :       k1 = *kl + *ku;
+   22010             :       k2 = *kl;
+   22011           0 :       k3 = 2*(*kl) + *ku;
+   22012           0 :       k4 = *kl + *ku - 1 + *m;
+   22013           0 :       for(j=0;j<*n;j++) {
+   22014           0 :         k = ((k1-j) > k2) ? (k1-j) : k2;
+   22015           0 :         l = (k3 < (k4-j)) ? k3 : (k4-j);
+   22016           0 :         for(i=k;i<=l;i++)
+   22017           0 :           a[j*(*lda)+i] *= mul;
+   22018             :       }
+   22019             :       break;
+   22020             : 
+   22021           0 :     default:
+   22022           0 :       *info = -1;
+   22023           0 :       return;
+   22024             :     }
+   22025             :   } /* finished */
+   22026             : 
+   22027           0 :   *info = 0;
+   22028           0 :   return;
+   22029             : }
+   22030             : }
+   22031             : }
+   22032             : #include "lapack.h"
+   22033             : 
+   22034             : #include "blas/blas.h"
+   22035             : namespace PLMD{
+   22036             : namespace lapack{
+   22037             : using namespace blas;
+   22038             : void 
+   22039           0 : PLUMED_BLAS_F77_FUNC(slasd0,SLASD0)(int *n, 
+   22040             :         int *sqre, 
+   22041             :         float *d__, 
+   22042             :         float *e, 
+   22043             :         float *u, 
+   22044             :         int *ldu, 
+   22045             :         float *vt, 
+   22046             :         int *ldvt,
+   22047             :         int *smlsiz, 
+   22048             :         int *iwork,
+   22049             :         float *work, 
+   22050             :         int *info)
+   22051             : {
+   22052             :     int u_dim1, u_offset, vt_dim1, vt_offset, i__1, i__2;
+   22053             : 
+   22054             :     int i__, j, m, i1, ic, lf, nd, ll, nl, nr, im1, ncc, nlf, nrf, 
+   22055             :             iwk, lvl, ndb1, nlp1, nrp1;
+   22056             :     float beta;
+   22057             :     int idxq, nlvl;
+   22058             :     float alpha;
+   22059             :     int inode, ndiml, idxqc, ndimr, itemp, sqrei;
+   22060           0 :     int c__0 = 0;
+   22061             : 
+   22062             : 
+   22063           0 :     --d__;
+   22064           0 :     --e;
+   22065           0 :     u_dim1 = *ldu;
+   22066           0 :     u_offset = 1 + u_dim1;
+   22067           0 :     u -= u_offset;
+   22068           0 :     vt_dim1 = *ldvt;
+   22069           0 :     vt_offset = 1 + vt_dim1;
+   22070           0 :     vt -= vt_offset;
+   22071           0 :     --iwork;
+   22072             :     --work;
+   22073             : 
+   22074           0 :     *info = 0;
+   22075             : 
+   22076           0 :     if (*n < 0) {
+   22077           0 :         *info = -1;
+   22078           0 :     } else if (*sqre < 0 || *sqre > 1) {
+   22079           0 :         *info = -2;
+   22080             :     }
+   22081             : 
+   22082           0 :     m = *n + *sqre;
+   22083             : 
+   22084           0 :     if (*ldu < *n) {
+   22085           0 :         *info = -6;
+   22086           0 :     } else if (*ldvt < m) {
+   22087           0 :         *info = -8;
+   22088           0 :     } else if (*smlsiz < 3) {
+   22089           0 :         *info = -9;
+   22090             :     }
+   22091           0 :     if (*info != 0) {
+   22092             :         return;
+   22093             :     }
+   22094             : 
+   22095           0 :     if (*n <= *smlsiz) {
+   22096           0 :         PLUMED_BLAS_F77_FUNC(slasdq,SLASDQ)("U", sqre, n, &m, n, &c__0, &d__[1], &e[1], &vt[vt_offset], 
+   22097             :                 ldvt, &u[u_offset], ldu, &u[u_offset], ldu, &work[1], info);
+   22098           0 :         return;
+   22099             :     }
+   22100             : 
+   22101             :     inode = 1;
+   22102           0 :     ndiml = inode + *n;
+   22103           0 :     ndimr = ndiml + *n;
+   22104           0 :     idxq = ndimr + *n;
+   22105           0 :     iwk = idxq + *n;
+   22106           0 :     PLUMED_BLAS_F77_FUNC(slasdt,SLASDT)(n, &nlvl, &nd, &iwork[inode], &iwork[ndiml], &iwork[ndimr], 
+   22107             :             smlsiz);
+   22108             : 
+   22109           0 :     ndb1 = (nd + 1) / 2;
+   22110           0 :     ncc = 0;
+   22111             :     i__1 = nd;
+   22112           0 :     for (i__ = ndb1; i__ <= i__1; ++i__) {
+   22113             : 
+   22114           0 :         i1 = i__ - 1;
+   22115           0 :         ic = iwork[inode + i1];
+   22116           0 :         nl = iwork[ndiml + i1];
+   22117           0 :         nlp1 = nl + 1;
+   22118           0 :         nr = iwork[ndimr + i1];
+   22119           0 :         nrp1 = nr + 1;
+   22120           0 :         nlf = ic - nl;
+   22121           0 :         nrf = ic + 1;
+   22122           0 :         sqrei = 1;
+   22123           0 :         PLUMED_BLAS_F77_FUNC(slasdq,SLASDQ)("U", &sqrei, &nl, &nlp1, &nl, &ncc, &d__[nlf], &e[nlf], &vt[
+   22124           0 :                 nlf + nlf * vt_dim1], ldvt, &u[nlf + nlf * u_dim1], ldu, &u[
+   22125           0 :                 nlf + nlf * u_dim1], ldu, &work[1], info);
+   22126           0 :         if (*info != 0) {
+   22127             :             return;
+   22128             :         }
+   22129           0 :         itemp = idxq + nlf - 2;
+   22130           0 :         i__2 = nl;
+   22131           0 :         for (j = 1; j <= i__2; ++j) {
+   22132           0 :             iwork[itemp + j] = j;
+   22133             :         }
+   22134           0 :         if (i__ == nd) {
+   22135           0 :             sqrei = *sqre;
+   22136             :         } else {
+   22137           0 :             sqrei = 1;
+   22138             :         }
+   22139           0 :         nrp1 = nr + sqrei;
+   22140           0 :         PLUMED_BLAS_F77_FUNC(slasdq,SLASDQ)("U", &sqrei, &nr, &nrp1, &nr, &ncc, &d__[nrf], &e[nrf], &vt[
+   22141           0 :                 nrf + nrf * vt_dim1], ldvt, &u[nrf + nrf * u_dim1], ldu, &u[
+   22142           0 :                 nrf + nrf * u_dim1], ldu, &work[1], info);
+   22143           0 :         if (*info != 0) {
+   22144             :             return;
+   22145             :         }
+   22146           0 :         itemp = idxq + ic;
+   22147           0 :         i__2 = nr;
+   22148           0 :         for (j = 1; j <= i__2; ++j) {
+   22149           0 :             iwork[itemp + j - 1] = j;
+   22150             :         }
+   22151             :     }
+   22152             : 
+   22153           0 :     for (lvl = nlvl; lvl >= 1; --lvl) {
+   22154             : 
+   22155           0 :         if (lvl == 1) {
+   22156             :             lf = 1;
+   22157             :             ll = 1;
+   22158             :         } else {
+   22159           0 :             i__1 = lvl - 1;
+   22160           0 :             lf = (1 << i__1);
+   22161           0 :             ll = (lf << 1) - 1;
+   22162             :         }
+   22163             :         i__1 = ll;
+   22164           0 :         for (i__ = lf; i__ <= i__1; ++i__) {
+   22165           0 :             im1 = i__ - 1;
+   22166           0 :             ic = iwork[inode + im1];
+   22167           0 :             nl = iwork[ndiml + im1];
+   22168           0 :             nr = iwork[ndimr + im1];
+   22169           0 :             nlf = ic - nl;
+   22170           0 :             if (*sqre == 0 && i__ == ll) {
+   22171           0 :                 sqrei = *sqre;
+   22172             :             } else {
+   22173           0 :                 sqrei = 1;
+   22174             :             }
+   22175           0 :             idxqc = idxq + nlf - 1;
+   22176           0 :             alpha = d__[ic];
+   22177           0 :             beta = e[ic];
+   22178           0 :             PLUMED_BLAS_F77_FUNC(slasd1,SLASD1)(&nl, &nr, &sqrei, &d__[nlf], &alpha, &beta, &u[nlf + nlf *
+   22179           0 :                      u_dim1], ldu, &vt[nlf + nlf * vt_dim1], ldvt, &iwork[
+   22180           0 :                     idxqc], &iwork[iwk], &work[1], info);
+   22181           0 :             if (*info != 0) {
+   22182             :                 return;
+   22183             :             }
+   22184             :         }
+   22185             :     }
+   22186             : 
+   22187             :     return;
+   22188             : 
+   22189             : }
+   22190             : }
+   22191             : }
+   22192             : #include <cmath>
+   22193             : #include "lapack.h"
+   22194             : 
+   22195             : #include "blas/blas.h"
+   22196             : namespace PLMD{
+   22197             : namespace lapack{
+   22198             : using namespace blas;
+   22199             : void 
+   22200           0 : PLUMED_BLAS_F77_FUNC(slasd1,SLASD1)(int *nl, 
+   22201             :         int *nr, 
+   22202             :         int *sqre, 
+   22203             :         float *d__, 
+   22204             :         float *alpha, 
+   22205             :         float *beta, 
+   22206             :         float *u, 
+   22207             :         int *ldu, 
+   22208             :         float *vt, 
+   22209             :         int *ldvt, 
+   22210             :         int *idxq, 
+   22211             :         int *iwork, 
+   22212             :         float *work, 
+   22213             :         int *info)
+   22214             : {
+   22215             :     int u_dim1, u_offset, vt_dim1, vt_offset, i__1;
+   22216             :     float d__1, d__2;
+   22217             : 
+   22218             :     int i__, k, m, n, n1, n2, iq, iz, iu2, ldq, idx, ldu2, ivt2, 
+   22219             :             idxc, idxp, ldvt2;
+   22220             :     int isigma;
+   22221             :     float orgnrm;
+   22222             :     int coltyp;
+   22223           0 :     int c__0 = 0;
+   22224           0 :     float one = 1.0;
+   22225           0 :     int c__1 = 1;
+   22226           0 :     int c_n1 = -1;
+   22227             : 
+   22228           0 :     --d__;
+   22229             :     u_dim1 = *ldu;
+   22230             :     u_offset = 1 + u_dim1;
+   22231             :     u -= u_offset;
+   22232             :     vt_dim1 = *ldvt;
+   22233             :     vt_offset = 1 + vt_dim1;
+   22234             :     vt -= vt_offset;
+   22235             :     --idxq;
+   22236           0 :     --iwork;
+   22237           0 :     --work;
+   22238             : 
+   22239           0 :     *info = 0;
+   22240             : 
+   22241           0 :     if (*nl < 1) {
+   22242           0 :         *info = -1;
+   22243           0 :     } else if (*nr < 1) {
+   22244           0 :         *info = -2;
+   22245           0 :     } else if (*sqre < 0 || *sqre > 1) {
+   22246           0 :         *info = -3;
+   22247             :     }
+   22248           0 :     if (*info != 0) {
+   22249             :         return;
+   22250             :     }
+   22251             : 
+   22252           0 :     n = *nl + *nr + 1;
+   22253           0 :     m = n + *sqre;
+   22254             : 
+   22255             : 
+   22256           0 :     ldu2 = n;
+   22257           0 :     ldvt2 = m;
+   22258             : 
+   22259             :     iz = 1;
+   22260           0 :     isigma = iz + m;
+   22261           0 :     iu2 = isigma + n;
+   22262           0 :     ivt2 = iu2 + ldu2 * n;
+   22263           0 :     iq = ivt2 + ldvt2 * m;
+   22264             : 
+   22265             :     idx = 1;
+   22266           0 :     idxc = idx + n;
+   22267           0 :     coltyp = idxc + n;
+   22268           0 :     idxp = coltyp + n;
+   22269             : 
+   22270           0 :     d__1 = std::abs(*alpha);
+   22271           0 :     d__2 = std::abs(*beta);
+   22272           0 :     orgnrm = (d__1>d__2) ? d__1 : d__2;
+   22273           0 :     d__[*nl + 1] = 0.;
+   22274             :     i__1 = n;
+   22275           0 :     for (i__ = 1; i__ <= i__1; ++i__) {
+   22276           0 :         if (std::abs(d__[i__]) > orgnrm) {
+   22277           0 :             orgnrm = std::abs(d__[i__]);
+   22278             :         }
+   22279             :     }
+   22280           0 :     PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G", &c__0, &c__0, &orgnrm, &one, &n, &c__1, &d__[1], &n, info);
+   22281           0 :     *alpha /= orgnrm;
+   22282           0 :     *beta /= orgnrm;
+   22283             : 
+   22284           0 :     PLUMED_BLAS_F77_FUNC(slasd2,SLASD2)(nl, nr, sqre, &k, &d__[1], &work[iz], alpha, beta, &u[u_offset], 
+   22285           0 :             ldu, &vt[vt_offset], ldvt, &work[isigma], &work[iu2], &ldu2, &
+   22286           0 :             work[ivt2], &ldvt2, &iwork[idxp], &iwork[idx], &iwork[idxc], &
+   22287           0 :             idxq[1], &iwork[coltyp], info);
+   22288             : 
+   22289           0 :     ldq = k;
+   22290           0 :     PLUMED_BLAS_F77_FUNC(slasd3,SLASD3)(nl, nr, sqre, &k, &d__[1], &work[iq], &ldq, &work[isigma], &u[
+   22291             :             u_offset], ldu, &work[iu2], &ldu2, &vt[vt_offset], ldvt, &work[
+   22292             :             ivt2], &ldvt2, &iwork[idxc], &iwork[coltyp], &work[iz], info);
+   22293           0 :     if (*info != 0) {
+   22294             :         return;
+   22295             :     }
+   22296           0 :     PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G", &c__0, &c__0, &one, &orgnrm, &n, &c__1, &d__[1], &n, info);
+   22297             : 
+   22298           0 :     n1 = k;
+   22299           0 :     n2 = n - k;
+   22300           0 :     PLUMED_BLAS_F77_FUNC(slamrg,SLAMRG)(&n1, &n2, &d__[1], &c__1, &c_n1, &idxq[1]);
+   22301             : 
+   22302             :     return;
+   22303             : 
+   22304             : }
+   22305             : }
+   22306             : }
+   22307             : #include <cmath>
+   22308             : #include "blas/blas.h"
+   22309             : #include "lapack.h"
+   22310             : #include "lapack_limits.h"
+   22311             : 
+   22312             : #include "real.h"
+   22313             : 
+   22314             : #include "blas/blas.h"
+   22315             : namespace PLMD{
+   22316             : namespace lapack{
+   22317             : using namespace blas;
+   22318             : void 
+   22319           0 : PLUMED_BLAS_F77_FUNC(slasd2,SLASD2)(int *nl, 
+   22320             :                         int *nr, 
+   22321             :                         int *sqre, 
+   22322             :                         int *k, 
+   22323             :                         float *d__, 
+   22324             :                         float *z__, 
+   22325             :                         float *alpha, 
+   22326             :                         float *beta, 
+   22327             :                         float *u, 
+   22328             :                         int *ldu, 
+   22329             :                         float *vt, 
+   22330             :                         int *ldvt, 
+   22331             :                         float *dsigma, 
+   22332             :                         float *u2, 
+   22333             :                         int *ldu2, 
+   22334             :                         float *vt2, 
+   22335             :                         int *ldvt2, 
+   22336             :                         int *idxp, 
+   22337             :                         int *idx, 
+   22338             :                         int *idxc, 
+   22339             :                         int *idxq, 
+   22340             :                         int *coltyp, 
+   22341             :                         int *info)
+   22342             : {
+   22343             :     int u_dim1, u_offset, u2_dim1, u2_offset, vt_dim1, vt_offset;
+   22344             :     int vt2_dim1, vt2_offset, i__1;
+   22345             :     float d__1, d__2;
+   22346             : 
+   22347             :     float c__;
+   22348             :     int i__, j, m, n;
+   22349             :     float s;
+   22350             :     int k2;
+   22351             :     float z1;
+   22352             :     int ct, jp;
+   22353             :     float eps, tau, tol;
+   22354             :     int psm[4], nlp1, nlp2, idxi, idxj;
+   22355             :     int ctot[4], idxjp;
+   22356             :     int jprev = 0;
+   22357             :     float hlftol;
+   22358           0 :     float zero = 0.0;
+   22359           0 :     int c__1 = 1;
+   22360             : 
+   22361             : 
+   22362           0 :     --d__;
+   22363           0 :     --z__;
+   22364           0 :     u_dim1 = *ldu;
+   22365           0 :     u_offset = 1 + u_dim1;
+   22366           0 :     u -= u_offset;
+   22367           0 :     vt_dim1 = *ldvt;
+   22368           0 :     vt_offset = 1 + vt_dim1;
+   22369           0 :     vt -= vt_offset;
+   22370           0 :     --dsigma;
+   22371           0 :     u2_dim1 = *ldu2;
+   22372           0 :     u2_offset = 1 + u2_dim1;
+   22373           0 :     u2 -= u2_offset;
+   22374           0 :     vt2_dim1 = *ldvt2;
+   22375           0 :     vt2_offset = 1 + vt2_dim1;
+   22376           0 :     vt2 -= vt2_offset;
+   22377           0 :     --idxp;
+   22378           0 :     --idx;
+   22379           0 :     --idxc;
+   22380           0 :     --idxq;
+   22381           0 :     --coltyp;
+   22382             : 
+   22383           0 :     *info = 0;
+   22384             : 
+   22385           0 :     n = *nl + *nr + 1;
+   22386           0 :     m = n + *sqre;
+   22387             : 
+   22388           0 :     nlp1 = *nl + 1;
+   22389           0 :     nlp2 = *nl + 2;
+   22390             : 
+   22391           0 :     z1 = *alpha * vt[nlp1 + nlp1 * vt_dim1];
+   22392           0 :     z__[1] = z1;
+   22393           0 :     for (i__ = *nl; i__ >= 1; --i__) {
+   22394           0 :         z__[i__ + 1] = *alpha * vt[i__ + nlp1 * vt_dim1];
+   22395           0 :         d__[i__ + 1] = d__[i__];
+   22396           0 :         idxq[i__ + 1] = idxq[i__] + 1;
+   22397             :     }
+   22398             : 
+   22399             :     i__1 = m;
+   22400           0 :     for (i__ = nlp2; i__ <= i__1; ++i__) {
+   22401           0 :         z__[i__] = *beta * vt[i__ + nlp2 * vt_dim1];
+   22402             :     }
+   22403             : 
+   22404             :     i__1 = nlp1;
+   22405           0 :     for (i__ = 2; i__ <= i__1; ++i__) {
+   22406           0 :         coltyp[i__] = 1;
+   22407             :     }
+   22408           0 :     i__1 = n;
+   22409           0 :     for (i__ = nlp2; i__ <= i__1; ++i__) {
+   22410           0 :         coltyp[i__] = 2;
+   22411             :     }
+   22412             : 
+   22413             :     i__1 = n;
+   22414           0 :     for (i__ = nlp2; i__ <= i__1; ++i__) {
+   22415           0 :         idxq[i__] += nlp1;
+   22416             :     }
+   22417             : 
+   22418             :     i__1 = n;
+   22419           0 :     for (i__ = 2; i__ <= i__1; ++i__) {
+   22420           0 :         dsigma[i__] = d__[idxq[i__]];
+   22421           0 :         u2[i__ + u2_dim1] = z__[idxq[i__]];
+   22422           0 :         idxc[i__] = coltyp[idxq[i__]];
+   22423             :     }
+   22424             : 
+   22425           0 :     PLUMED_BLAS_F77_FUNC(slamrg,SLAMRG)(nl, nr, &dsigma[2], &c__1, &c__1, &idx[2]);
+   22426             : 
+   22427           0 :     i__1 = n;
+   22428           0 :     for (i__ = 2; i__ <= i__1; ++i__) {
+   22429           0 :         idxi = idx[i__] + 1;
+   22430           0 :         d__[i__] = dsigma[idxi];
+   22431           0 :         z__[i__] = u2[idxi + u2_dim1];
+   22432           0 :         coltyp[i__] = idxc[idxi];
+   22433             :     }
+   22434             : 
+   22435             :     eps = PLUMED_GMX_FLOAT_EPS;
+   22436           0 :     d__1 = std::abs(*alpha), d__2 = std::abs(*beta);
+   22437           0 :     tol = (d__1 > d__2) ? d__1 : d__2;
+   22438           0 :     d__2 = std::abs(d__[n]);
+   22439           0 :     tol = eps * 8. * ((d__2 > tol) ? d__2 : tol);
+   22440             : 
+   22441           0 :     *k = 1;
+   22442           0 :     k2 = n + 1;
+   22443             :     i__1 = n;
+   22444           0 :     for (j = 2; j <= i__1; ++j) {
+   22445           0 :         if (std::abs(z__[j]) <= tol) {
+   22446             : 
+   22447           0 :             --k2;
+   22448           0 :             idxp[k2] = j;
+   22449           0 :             coltyp[j] = 4;
+   22450           0 :             if (j == n) {
+   22451           0 :                 goto L120;
+   22452             :             }
+   22453             :         } else {
+   22454             :             jprev = j;
+   22455           0 :             goto L90;
+   22456             :         }
+   22457             :     }
+   22458           0 : L90:
+   22459             :     j = jprev;
+   22460           0 : L100:
+   22461           0 :     ++j;
+   22462           0 :     if (j > n) {
+   22463           0 :         goto L110;
+   22464             :     }
+   22465           0 :     if (std::abs(z__[j]) <= tol) {
+   22466             : 
+   22467           0 :         --k2;
+   22468           0 :         idxp[k2] = j;
+   22469           0 :         coltyp[j] = 4;
+   22470             :     } else {
+   22471             : 
+   22472           0 :         if (std::abs(d__[j] - d__[jprev]) <= tol) {
+   22473             : 
+   22474           0 :             s = z__[jprev];
+   22475           0 :             c__ = z__[j];
+   22476             : 
+   22477           0 :             tau = PLUMED_BLAS_F77_FUNC(slapy2,SLAPY2)(&c__, &s);
+   22478           0 :             c__ /= tau;
+   22479           0 :             s = -s / tau;
+   22480           0 :             z__[j] = tau;
+   22481           0 :             z__[jprev] = 0.;
+   22482             : 
+   22483           0 :             idxjp = idxq[idx[jprev] + 1];
+   22484           0 :             idxj = idxq[idx[j] + 1];
+   22485           0 :             if (idxjp <= nlp1) {
+   22486           0 :                 --idxjp;
+   22487             :             }
+   22488           0 :             if (idxj <= nlp1) {
+   22489           0 :                 --idxj;
+   22490             :             }
+   22491           0 :             PLUMED_BLAS_F77_FUNC(srot,SROT)(&n, &u[idxjp * u_dim1 + 1], &c__1, &u[idxj * u_dim1 + 1], &
+   22492             :                     c__1, &c__, &s);
+   22493           0 :             PLUMED_BLAS_F77_FUNC(srot,SROT)(&m, &vt[idxjp + vt_dim1], ldvt, &vt[idxj + vt_dim1], ldvt, &
+   22494             :                     c__, &s);
+   22495           0 :             if (coltyp[j] != coltyp[jprev]) {
+   22496           0 :                 coltyp[j] = 3;
+   22497             :             }
+   22498           0 :             coltyp[jprev] = 4;
+   22499           0 :             --k2;
+   22500           0 :             idxp[k2] = jprev;
+   22501             :             jprev = j;
+   22502             :         } else {
+   22503           0 :             ++(*k);
+   22504           0 :             u2[*k + u2_dim1] = z__[jprev];
+   22505           0 :             dsigma[*k] = d__[jprev];
+   22506           0 :             idxp[*k] = jprev;
+   22507             :             jprev = j;
+   22508             :         }
+   22509             :     }
+   22510           0 :     goto L100;
+   22511             : L110:
+   22512             : 
+   22513           0 :     ++(*k);
+   22514           0 :     u2[*k + u2_dim1] = z__[jprev];
+   22515           0 :     dsigma[*k] = d__[jprev];
+   22516           0 :     idxp[*k] = jprev;
+   22517             : 
+   22518             : L120:
+   22519             : 
+   22520           0 :     for (j = 1; j <= 4; ++j) {
+   22521           0 :         ctot[j - 1] = 0;
+   22522             :     }
+   22523           0 :     i__1 = n;
+   22524           0 :     for (j = 2; j <= i__1; ++j) {
+   22525           0 :         ct = coltyp[j];
+   22526           0 :         ++ctot[ct - 1];
+   22527             :     }
+   22528             : 
+   22529           0 :     psm[0] = 2;
+   22530           0 :     psm[1] = ctot[0] + 2;
+   22531           0 :     psm[2] = psm[1] + ctot[1];
+   22532           0 :     psm[3] = psm[2] + ctot[2];
+   22533             : 
+   22534             :     i__1 = n;
+   22535           0 :     for (j = 2; j <= i__1; ++j) {
+   22536           0 :         jp = idxp[j];
+   22537           0 :         ct = coltyp[jp];
+   22538           0 :         idxc[psm[ct - 1]] = j;
+   22539           0 :         ++psm[ct - 1];
+   22540             :     }
+   22541             : 
+   22542             :     i__1 = n;
+   22543           0 :     for (j = 2; j <= i__1; ++j) {
+   22544           0 :         jp = idxp[j];
+   22545           0 :         dsigma[j] = d__[jp];
+   22546           0 :         idxj = idxq[idx[idxp[idxc[j]]] + 1];
+   22547           0 :         if (idxj <= nlp1) {
+   22548           0 :             --idxj;
+   22549             :         }
+   22550           0 :         PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&n, &u[idxj * u_dim1 + 1], &c__1, &u2[j * u2_dim1 + 1], &c__1);
+   22551           0 :         PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&m, &vt[idxj + vt_dim1], ldvt, &vt2[j + vt2_dim1], ldvt2);
+   22552             :     }
+   22553             : 
+   22554           0 :     dsigma[1] = 0.;
+   22555           0 :     hlftol = tol / 2.;
+   22556           0 :     if (std::abs(dsigma[2]) <= hlftol) {
+   22557           0 :         dsigma[2] = hlftol;
+   22558             :     }
+   22559           0 :     if (m > n) {
+   22560           0 :         z__[1] = PLUMED_BLAS_F77_FUNC(slapy2,SLAPY2)(&z1, &z__[m]);
+   22561           0 :         if (z__[1] <= tol) {
+   22562           0 :             c__ = 1.;
+   22563           0 :             s = 0.;
+   22564           0 :             z__[1] = tol;
+   22565             :         } else {
+   22566           0 :             c__ = z1 / z__[1];
+   22567           0 :             s = z__[m] / z__[1];
+   22568             :         }
+   22569             :     } else {
+   22570           0 :         if (std::abs(z1) <= tol) {
+   22571           0 :             z__[1] = tol;
+   22572             :         } else {
+   22573           0 :             z__[1] = z1;
+   22574             :         }
+   22575             :     }
+   22576             : 
+   22577           0 :     i__1 = *k - 1;
+   22578           0 :     PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&i__1, &u2[u2_dim1 + 2], &c__1, &z__[2], &c__1);
+   22579             : 
+   22580           0 :     PLUMED_BLAS_F77_FUNC(slaset,SLASET)("A", &n, &c__1, &zero, &zero, &u2[u2_offset], ldu2);
+   22581           0 :     u2[nlp1 + u2_dim1] = 1.;
+   22582           0 :     if (m > n) {
+   22583             :         i__1 = nlp1;
+   22584           0 :         for (i__ = 1; i__ <= i__1; ++i__) {
+   22585           0 :             vt[m + i__ * vt_dim1] = -s * vt[nlp1 + i__ * vt_dim1];
+   22586           0 :             vt2[i__ * vt2_dim1 + 1] = c__ * vt[nlp1 + i__ * vt_dim1];
+   22587             :         }
+   22588           0 :         i__1 = m;
+   22589           0 :         for (i__ = nlp2; i__ <= i__1; ++i__) {
+   22590           0 :             vt2[i__ * vt2_dim1 + 1] = s * vt[m + i__ * vt_dim1];
+   22591           0 :             vt[m + i__ * vt_dim1] = c__ * vt[m + i__ * vt_dim1];
+   22592             :         }
+   22593             :     } else {
+   22594           0 :         PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&m, &vt[nlp1 + vt_dim1], ldvt, &vt2[vt2_dim1 + 1], ldvt2);
+   22595             :     }
+   22596           0 :     if (m > n) {
+   22597           0 :         PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&m, &vt[m + vt_dim1], ldvt, &vt2[m + vt2_dim1], ldvt2);
+   22598             :     }
+   22599             : 
+   22600           0 :     if (n > *k) {
+   22601           0 :         i__1 = n - *k;
+   22602           0 :         PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&i__1, &dsigma[*k + 1], &c__1, &d__[*k + 1], &c__1);
+   22603           0 :         i__1 = n - *k;
+   22604           0 :         PLUMED_BLAS_F77_FUNC(slacpy,SLACPY)("A", &n, &i__1, &u2[(*k + 1) * u2_dim1 + 1], ldu2, &u[(*k + 1)
+   22605           0 :                  * u_dim1 + 1], ldu);
+   22606           0 :         i__1 = n - *k;
+   22607           0 :         PLUMED_BLAS_F77_FUNC(slacpy,SLACPY)("A", &i__1, &m, &vt2[*k + 1 + vt2_dim1], ldvt2, &vt[*k + 1 + 
+   22608           0 :                 vt_dim1], ldvt);
+   22609             :     }
+   22610           0 :     for (j = 1; j <= 4; ++j) {
+   22611           0 :         coltyp[j] = ctot[j - 1];
+   22612             :     }
+   22613             : 
+   22614           0 :     return;
+   22615             : 
+   22616             : }
+   22617             : 
+   22618             : 
+   22619             : }
+   22620             : }
+   22621             : #include <cmath>
+   22622             : #include "blas/blas.h"
+   22623             : #include "lapack.h"
+   22624             : 
+   22625             : #include "blas/blas.h"
+   22626             : namespace PLMD{
+   22627             : namespace lapack{
+   22628             : using namespace blas;
+   22629             : void 
+   22630           0 : PLUMED_BLAS_F77_FUNC(slasd3,SLASD3)(int *nl, 
+   22631             :         int *nr,
+   22632             :         int *sqre, 
+   22633             :         int *k, 
+   22634             :         float *d__, 
+   22635             :         float *q, 
+   22636             :         int *ldq, 
+   22637             :         float *dsigma, 
+   22638             :         float *u, 
+   22639             :         int *ldu, 
+   22640             :         float *u2, 
+   22641             :         int *ldu2, 
+   22642             :         float *vt, 
+   22643             :         int *ldvt, 
+   22644             :         float *vt2, 
+   22645             :         int *ldvt2, 
+   22646             :         int *idxc, 
+   22647             :         int *ctot, 
+   22648             :         float *z__, 
+   22649             :         int *info)
+   22650             : {
+   22651             :     int q_dim1, q_offset, u_dim1, u_offset, u2_dim1, u2_offset, vt_dim1, 
+   22652             :             vt_offset, vt2_dim1, vt2_offset, i__1, i__2;
+   22653             :     float d__2;
+   22654             : 
+   22655             :     int i__, j, m, n, jc;
+   22656             :     float rho;
+   22657             :     int nlp1, nlp2, nrp1;
+   22658             :     float temp;
+   22659             :     int ctemp;
+   22660             :     int ktemp;
+   22661           0 :     int c__1 = 1;
+   22662           0 :     int c__0 = 0;
+   22663           0 :     float zero = 0.0;
+   22664           0 :     float one = 1.0;
+   22665             : 
+   22666             :     --d__;
+   22667           0 :     q_dim1 = *ldq;
+   22668           0 :     q_offset = 1 + q_dim1;
+   22669           0 :     q -= q_offset;
+   22670           0 :     --dsigma;
+   22671           0 :     u_dim1 = *ldu;
+   22672           0 :     u_offset = 1 + u_dim1;
+   22673           0 :     u -= u_offset;
+   22674           0 :     u2_dim1 = *ldu2;
+   22675           0 :     u2_offset = 1 + u2_dim1;
+   22676           0 :     u2 -= u2_offset;
+   22677           0 :     vt_dim1 = *ldvt;
+   22678           0 :     vt_offset = 1 + vt_dim1;
+   22679           0 :     vt -= vt_offset;
+   22680           0 :     vt2_dim1 = *ldvt2;
+   22681           0 :     vt2_offset = 1 + vt2_dim1;
+   22682           0 :     vt2 -= vt2_offset;
+   22683           0 :     --idxc;
+   22684             :     --ctot;
+   22685           0 :     --z__;
+   22686             : 
+   22687             :     /* Function Body */
+   22688           0 :     *info = 0;
+   22689             : 
+   22690           0 :     if (*nl < 1) {
+   22691           0 :         *info = -1;
+   22692           0 :     } else if (*nr < 1) {
+   22693           0 :         *info = -2;
+   22694           0 :     } else if (*sqre != 1 && *sqre != 0) {
+   22695           0 :         *info = -3;
+   22696             :     }
+   22697             : 
+   22698           0 :     n = *nl + *nr + 1;
+   22699           0 :     m = n + *sqre;
+   22700           0 :     nlp1 = *nl + 1;
+   22701           0 :     nlp2 = *nl + 2;
+   22702             : 
+   22703           0 :     if (*k == 1) {
+   22704           0 :         d__[1] = std::abs(z__[1]);
+   22705           0 :         PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&m, &vt2[vt2_dim1 + 1], ldvt2, &vt[vt_dim1 + 1], ldvt);
+   22706           0 :         if (z__[1] > 0.) {
+   22707           0 :             PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&n, &u2[u2_dim1 + 1], &c__1, &u[u_dim1 + 1], &c__1);
+   22708             :         } else {
+   22709           0 :             i__1 = n;
+   22710           0 :             for (i__ = 1; i__ <= i__1; ++i__) {
+   22711           0 :                 u[i__ + u_dim1] = -u2[i__ + u2_dim1];
+   22712             :             }
+   22713             :         }
+   22714           0 :         return;
+   22715             :     }
+   22716             : 
+   22717           0 :     PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(k, &z__[1], &c__1, &q[q_offset], &c__1);
+   22718             : 
+   22719           0 :     rho = PLUMED_BLAS_F77_FUNC(snrm2,SNRM2)(k, &z__[1], &c__1);
+   22720           0 :     PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G", &c__0, &c__0, &rho, &one, k, &c__1, &z__[1], k, info);
+   22721           0 :     rho *= rho;
+   22722             : 
+   22723             : 
+   22724           0 :     i__1 = *k;
+   22725           0 :     for (j = 1; j <= i__1; ++j) {
+   22726           0 :         PLUMED_BLAS_F77_FUNC(slasd4,SLASD4)(k, &j, &dsigma[1], &z__[1], &u[j * u_dim1 + 1], &rho, &d__[j],
+   22727           0 :                  &vt[j * vt_dim1 + 1], info);
+   22728             : 
+   22729           0 :         if (*info != 0) {
+   22730             :             return;
+   22731             :         }
+   22732             :     }
+   22733             : 
+   22734           0 :     i__1 = *k;
+   22735           0 :     for (i__ = 1; i__ <= i__1; ++i__) {
+   22736           0 :         z__[i__] = u[i__ + *k * u_dim1] * vt[i__ + *k * vt_dim1];
+   22737             :         i__2 = i__ - 1;
+   22738           0 :         for (j = 1; j <= i__2; ++j) {
+   22739           0 :             z__[i__] *= u[i__ + j * u_dim1] * vt[i__ + j * vt_dim1] / (dsigma[
+   22740           0 :                     i__] - dsigma[j]) / (dsigma[i__] + dsigma[j]);
+   22741             :         }
+   22742           0 :         i__2 = *k - 1;
+   22743           0 :         for (j = i__; j <= i__2; ++j) {
+   22744           0 :             z__[i__] *= u[i__ + j * u_dim1] * vt[i__ + j * vt_dim1] / (dsigma[
+   22745           0 :                     i__] - dsigma[j + 1]) / (dsigma[i__] + dsigma[j + 1]);
+   22746             :         }
+   22747           0 :         d__2 =  std::sqrt(std::abs(z__[i__]));
+   22748           0 :         z__[i__] = (q[i__ + q_dim1] > 0) ? d__2 : -d__2;
+   22749             :     }
+   22750             : 
+   22751           0 :     i__1 = *k;
+   22752           0 :     for (i__ = 1; i__ <= i__1; ++i__) {
+   22753           0 :         vt[i__ * vt_dim1 + 1] = z__[1] / u[i__ * u_dim1 + 1] / vt[i__ * 
+   22754           0 :                 vt_dim1 + 1];
+   22755           0 :         u[i__ * u_dim1 + 1] = -1.;
+   22756           0 :         i__2 = *k;
+   22757           0 :         for (j = 2; j <= i__2; ++j) {
+   22758           0 :             vt[j + i__ * vt_dim1] = z__[j] / u[j + i__ * u_dim1] / vt[j + i__ 
+   22759           0 :                     * vt_dim1];
+   22760           0 :             u[j + i__ * u_dim1] = dsigma[j] * vt[j + i__ * vt_dim1];
+   22761             :         }
+   22762           0 :         temp = PLUMED_BLAS_F77_FUNC(snrm2,SNRM2)(k, &u[i__ * u_dim1 + 1], &c__1);
+   22763           0 :         q[i__ * q_dim1 + 1] = u[i__ * u_dim1 + 1] / temp;
+   22764           0 :         i__2 = *k;
+   22765           0 :         for (j = 2; j <= i__2; ++j) {
+   22766           0 :             jc = idxc[j];
+   22767           0 :             q[j + i__ * q_dim1] = u[jc + i__ * u_dim1] / temp;
+   22768             :         }
+   22769             :     }
+   22770             : 
+   22771           0 :     if (*k == 2) {
+   22772           0 :         PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("N", "N", &n, k, k, &one, &u2[u2_offset], ldu2, &q[q_offset],
+   22773             :                  ldq, &zero, &u[u_offset], ldu);
+   22774           0 :         goto L100;
+   22775             :     }
+   22776           0 :     if (ctot[1] > 0) {
+   22777           0 :         PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("N", "N", nl, k, &ctot[1], &one, &u2[(u2_dim1 << 1) + 1], 
+   22778           0 :                 ldu2, &q[q_dim1 + 2], ldq, &zero, &u[u_dim1 + 1], ldu);
+   22779           0 :         if (ctot[3] > 0) {
+   22780           0 :             ktemp = ctot[1] + 2 + ctot[2];
+   22781           0 :             PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("N", "N", nl, k, &ctot[3], &one, &u2[ktemp * u2_dim1 + 1]
+   22782           0 :                     , ldu2, &q[ktemp + q_dim1], ldq, &one, &u[u_dim1 + 1], 
+   22783             :                     ldu);
+   22784             :         }
+   22785           0 :     } else if (ctot[3] > 0) {
+   22786           0 :         ktemp = ctot[1] + 2 + ctot[2];
+   22787           0 :         PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("N", "N", nl, k, &ctot[3], &one, &u2[ktemp * u2_dim1 + 1], 
+   22788           0 :                 ldu2, &q[ktemp + q_dim1], ldq, &zero, &u[u_dim1 + 1], ldu);
+   22789             :     } else {
+   22790           0 :         PLUMED_BLAS_F77_FUNC(slacpy,SLACPY)("F", nl, k, &u2[u2_offset], ldu2, &u[u_offset], ldu);
+   22791             :     }
+   22792           0 :     PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(k, &q[q_dim1 + 1], ldq, &u[nlp1 + u_dim1], ldu);
+   22793           0 :     ktemp = ctot[1] + 2;
+   22794           0 :     ctemp = ctot[2] + ctot[3];
+   22795           0 :     PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("N", "N", nr, k, &ctemp, &one, &u2[nlp2 + ktemp * u2_dim1], ldu2,
+   22796           0 :              &q[ktemp + q_dim1], ldq, &zero, &u[nlp2 + u_dim1], ldu);
+   22797             : 
+   22798           0 : L100:
+   22799           0 :     i__1 = *k;
+   22800           0 :     for (i__ = 1; i__ <= i__1; ++i__) {
+   22801           0 :         temp = PLUMED_BLAS_F77_FUNC(snrm2,SNRM2)(k, &vt[i__ * vt_dim1 + 1], &c__1);
+   22802           0 :         q[i__ + q_dim1] = vt[i__ * vt_dim1 + 1] / temp;
+   22803           0 :         i__2 = *k;
+   22804           0 :         for (j = 2; j <= i__2; ++j) {
+   22805           0 :             jc = idxc[j];
+   22806           0 :             q[i__ + j * q_dim1] = vt[jc + i__ * vt_dim1] / temp;
+   22807             :         }
+   22808             :     }
+   22809             : 
+   22810           0 :     if (*k == 2) {
+   22811           0 :         PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("N", "N", k, &m, k, &one, &q[q_offset], ldq, &vt2[vt2_offset]
+   22812             :                 , ldvt2, &zero, &vt[vt_offset], ldvt);
+   22813           0 :         return;
+   22814             :     }
+   22815           0 :     ktemp = ctot[1] + 1;
+   22816           0 :     PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("N", "N", k, &nlp1, &ktemp, &one, &q[q_dim1 + 1], ldq, &vt2[
+   22817           0 :             vt2_dim1 + 1], ldvt2, &zero, &vt[vt_dim1 + 1], ldvt);
+   22818           0 :     ktemp = ctot[1] + 2 + ctot[2];
+   22819           0 :     if (ktemp <= *ldvt2) {
+   22820           0 :         PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("N", "N", k, &nlp1, &ctot[3], &one, &q[ktemp * q_dim1 + 1], 
+   22821           0 :                 ldq, &vt2[ktemp + vt2_dim1], ldvt2, &one, &vt[vt_dim1 + 1], 
+   22822             :                 ldvt);
+   22823             :     }
+   22824             : 
+   22825           0 :     ktemp = ctot[1] + 1;
+   22826           0 :     nrp1 = *nr + *sqre;
+   22827           0 :     if (ktemp > 1) {
+   22828           0 :         i__1 = *k;
+   22829           0 :         for (i__ = 1; i__ <= i__1; ++i__) {
+   22830           0 :             q[i__ + ktemp * q_dim1] = q[i__ + q_dim1];
+   22831             :         }
+   22832           0 :         i__1 = m;
+   22833           0 :         for (i__ = nlp2; i__ <= i__1; ++i__) {
+   22834           0 :             vt2[ktemp + i__ * vt2_dim1] = vt2[i__ * vt2_dim1 + 1];
+   22835             :         }
+   22836             :     }
+   22837           0 :     ctemp = ctot[2] + 1 + ctot[3];
+   22838           0 :     PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("N", "N", k, &nrp1, &ctemp, &one, &q[ktemp * q_dim1 + 1], ldq, &
+   22839           0 :             vt2[ktemp + nlp2 * vt2_dim1], ldvt2, &zero, &vt[nlp2 * vt_dim1 + 
+   22840           0 :             1], ldvt);
+   22841             : 
+   22842             :     return;
+   22843             : 
+   22844             : 
+   22845             : }
+   22846             : 
+   22847             : 
+   22848             : }
+   22849             : }
+   22850             : #include <cmath>
+   22851             : #include "lapack.h"
+   22852             : #include "lapack_limits.h"
+   22853             : 
+   22854             : #include "real.h"
+   22855             : 
+   22856             : #include "blas/blas.h"
+   22857             : namespace PLMD{
+   22858             : namespace lapack{
+   22859             : using namespace blas;
+   22860             : void 
+   22861           0 : PLUMED_BLAS_F77_FUNC(slasd4,SLASD4)(int *n, 
+   22862             :         int *i__, 
+   22863             :         float *d__, 
+   22864             :         float *z__, 
+   22865             :         float *delta, 
+   22866             :         float *rho, 
+   22867             :         float *sigma, 
+   22868             :         float *work, 
+   22869             :         int *info)
+   22870             : {
+   22871             :     int i__1;
+   22872             :     float d__1;
+   22873             : 
+   22874             :     float a, b, c__;
+   22875             :     int j;
+   22876             :     float w, dd[3];
+   22877             :     int ii;
+   22878             :     float dw, zz[3];
+   22879             :     int ip1;
+   22880             :     float eta, phi, eps, tau, psi;
+   22881             :     int iim1, iip1;
+   22882             :     float dphi, dpsi;
+   22883             :     int iter;
+   22884             :     float temp, prew, sg2lb, sg2ub, temp1, temp2, dtiim, delsq, 
+   22885             :             dtiip;
+   22886             :     int niter;
+   22887             :     float dtisq;
+   22888             :     int swtch;
+   22889             :     float dtnsq;
+   22890             :     float delsq2, dtnsq1;
+   22891             :     int swtch3;
+   22892             :     int orgati;
+   22893             :     float erretm, dtipsq, rhoinv;
+   22894             : 
+   22895           0 :     --work;
+   22896           0 :     --delta;
+   22897           0 :     --z__;
+   22898           0 :     --d__;
+   22899             : 
+   22900           0 :     *info = 0;
+   22901           0 :     if (*n == 1) {
+   22902             : 
+   22903           0 :         *sigma =  std::sqrt(d__[1] * d__[1] + *rho * z__[1] * z__[1]);
+   22904           0 :         delta[1] = 1.;
+   22905           0 :         work[1] = 1.;
+   22906           0 :         return;
+   22907             :     }
+   22908           0 :     if (*n == 2) {
+   22909           0 :         PLUMED_BLAS_F77_FUNC(slasd5,SLASD5)(i__, &d__[1], &z__[1], &delta[1], rho, sigma, &work[1]);
+   22910           0 :         return;
+   22911             :     }
+   22912             : 
+   22913             :     eps = PLUMED_GMX_FLOAT_EPS;
+   22914           0 :     rhoinv = 1. / *rho;
+   22915             : 
+   22916           0 :     if (*i__ == *n) {
+   22917             : 
+   22918           0 :         ii = *n - 1;
+   22919           0 :         niter = 1;
+   22920             : 
+   22921           0 :         temp = *rho / 2.;
+   22922             : 
+   22923           0 :         temp1 = temp / (d__[*n] +  std::sqrt(d__[*n] * d__[*n] + temp));
+   22924           0 :         i__1 = *n;
+   22925           0 :         for (j = 1; j <= i__1; ++j) {
+   22926           0 :             work[j] = d__[j] + d__[*n] + temp1;
+   22927           0 :             delta[j] = d__[j] - d__[*n] - temp1;
+   22928             :         }
+   22929             : 
+   22930             :         psi = 0.;
+   22931           0 :         i__1 = *n - 2;
+   22932           0 :         for (j = 1; j <= i__1; ++j) {
+   22933           0 :             psi += z__[j] * z__[j] / (delta[j] * work[j]);
+   22934             :         }
+   22935             : 
+   22936           0 :         c__ = rhoinv + psi;
+   22937           0 :         w = c__ + z__[ii] * z__[ii] / (delta[ii] * work[ii]) + z__[*n] * z__[*
+   22938           0 :                 n] / (delta[*n] * work[*n]);
+   22939             : 
+   22940           0 :         if (w <= 0.) {
+   22941           0 :             temp1 =  std::sqrt(d__[*n] * d__[*n] + *rho);
+   22942           0 :             temp = z__[*n - 1] * z__[*n - 1] / ((d__[*n - 1] + temp1) * (d__[*
+   22943           0 :                     n] - d__[*n - 1] + *rho / (d__[*n] + temp1))) + z__[*n] * 
+   22944           0 :                     z__[*n] / *rho;
+   22945             : 
+   22946           0 :             if (c__ <= temp) {
+   22947             :                 tau = *rho;
+   22948             :             } else {
+   22949           0 :                 delsq = (d__[*n] - d__[*n - 1]) * (d__[*n] + d__[*n - 1]);
+   22950           0 :                 a = -c__ * delsq + z__[*n - 1] * z__[*n - 1] + z__[*n] * z__[*
+   22951             :                         n];
+   22952           0 :                 b = z__[*n] * z__[*n] * delsq;
+   22953           0 :                 if (a < 0.) {
+   22954           0 :                     tau = b * 2. / ( std::sqrt(a * a + b * 4. * c__) - a);
+   22955             :                 } else {
+   22956           0 :                     tau = (a +  std::sqrt(a * a + b * 4. * c__)) / (c__ * 2.);
+   22957             :                 }
+   22958             :             }
+   22959             : 
+   22960             :         } else {
+   22961           0 :             delsq = (d__[*n] - d__[*n - 1]) * (d__[*n] + d__[*n - 1]);
+   22962           0 :             a = -c__ * delsq + z__[*n - 1] * z__[*n - 1] + z__[*n] * z__[*n];
+   22963           0 :             b = z__[*n] * z__[*n] * delsq;
+   22964             : 
+   22965           0 :             if (a < 0.) {
+   22966           0 :                 tau = b * 2. / ( std::sqrt(a * a + b * 4. * c__) - a);
+   22967             :             } else {
+   22968           0 :                 tau = (a +  std::sqrt(a * a + b * 4. * c__)) / (c__ * 2.);
+   22969             :             }
+   22970             : 
+   22971             :         }
+   22972             : 
+   22973           0 :         eta = tau / (d__[*n] +  std::sqrt(d__[*n] * d__[*n] + tau));
+   22974             : 
+   22975           0 :         *sigma = d__[*n] + eta;
+   22976           0 :         i__1 = *n;
+   22977           0 :         for (j = 1; j <= i__1; ++j) {
+   22978           0 :             delta[j] = d__[j] - d__[*i__] - eta;
+   22979           0 :             work[j] = d__[j] + d__[*i__] + eta;
+   22980             :         }
+   22981             : 
+   22982             :         dpsi = 0.;
+   22983             :         psi = 0.;
+   22984             :         erretm = 0.;
+   22985             :         i__1 = ii;
+   22986           0 :         for (j = 1; j <= i__1; ++j) {
+   22987           0 :             temp = z__[j] / (delta[j] * work[j]);
+   22988           0 :             psi += z__[j] * temp;
+   22989           0 :             dpsi += temp * temp;
+   22990           0 :             erretm += psi;
+   22991             :         }
+   22992             :         erretm = std::abs(erretm);
+   22993             : 
+   22994           0 :         temp = z__[*n] / (delta[*n] * work[*n]);
+   22995           0 :         phi = z__[*n] * temp;
+   22996           0 :         dphi = temp * temp;
+   22997           0 :         erretm = (-phi - psi) * 8. + erretm - phi + rhoinv + std::abs(tau) * (dpsi 
+   22998           0 :                 + dphi);
+   22999             : 
+   23000           0 :         w = rhoinv + phi + psi;
+   23001             : 
+   23002           0 :         if (std::abs(w) <= eps * erretm) {
+   23003           0 :             goto L240;
+   23004             :         }
+   23005             : 
+   23006           0 :         ++niter;
+   23007           0 :         dtnsq1 = work[*n - 1] * delta[*n - 1];
+   23008             :         dtnsq = work[*n] * delta[*n];
+   23009           0 :         c__ = w - dtnsq1 * dpsi - dtnsq * dphi;
+   23010           0 :         a = (dtnsq + dtnsq1) * w - dtnsq * dtnsq1 * (dpsi + dphi);
+   23011           0 :         b = dtnsq * dtnsq1 * w;
+   23012           0 :         if (c__ < 0.) {
+   23013           0 :             c__ = std::abs(c__);
+   23014             :         }
+   23015           0 :         if ( std::abs(c__)<PLUMED_GMX_FLOAT_MIN) {
+   23016           0 :             eta = *rho - *sigma * *sigma;
+   23017           0 :         } else if (a >= 0.) {
+   23018           0 :             eta = (a +  std::sqrt(std::abs(a * a - b * 4. * c__))) / (c__  * 2.);
+   23019             :         } else {
+   23020           0 :           eta = b * 2. / (a -  std::sqrt(std::abs(a * a - b * 4. * c__)));
+   23021             :         }
+   23022             : 
+   23023           0 :         if (w * eta > 0.) {
+   23024           0 :             eta = -w / (dpsi + dphi);
+   23025             :         }
+   23026           0 :         temp = eta - dtnsq;
+   23027           0 :         if (temp > *rho) {
+   23028           0 :             eta = *rho + dtnsq;
+   23029             :         }
+   23030             : 
+   23031           0 :         tau += eta;
+   23032           0 :         eta /= *sigma +  std::sqrt(eta + *sigma * *sigma);
+   23033           0 :         i__1 = *n;
+   23034           0 :         for (j = 1; j <= i__1; ++j) {
+   23035           0 :             delta[j] -= eta;
+   23036           0 :             work[j] += eta;
+   23037             :         }
+   23038             : 
+   23039           0 :         *sigma += eta;
+   23040             : 
+   23041             :         dpsi = 0.;
+   23042             :         psi = 0.;
+   23043             :         erretm = 0.;
+   23044             :         i__1 = ii;
+   23045           0 :         for (j = 1; j <= i__1; ++j) {
+   23046           0 :             temp = z__[j] / (work[j] * delta[j]);
+   23047           0 :             psi += z__[j] * temp;
+   23048           0 :             dpsi += temp * temp;
+   23049           0 :             erretm += psi;
+   23050             :         }
+   23051             :         erretm = std::abs(erretm);
+   23052             : 
+   23053           0 :         temp = z__[*n] / (work[*n] * delta[*n]);
+   23054           0 :         phi = z__[*n] * temp;
+   23055           0 :         dphi = temp * temp;
+   23056           0 :         erretm = (-phi - psi) * 8. + erretm - phi + rhoinv + std::abs(tau) * (dpsi 
+   23057           0 :                 + dphi);
+   23058             : 
+   23059           0 :         w = rhoinv + phi + psi;
+   23060             : 
+   23061             :         iter = niter + 1;
+   23062             : 
+   23063           0 :         for (niter = iter; niter <= 20; ++niter) {
+   23064             : 
+   23065           0 :             if (std::abs(w) <= eps * erretm) {
+   23066           0 :                 goto L240;
+   23067             :             }
+   23068           0 :             dtnsq1 = work[*n - 1] * delta[*n - 1];
+   23069           0 :             dtnsq = work[*n] * delta[*n];
+   23070           0 :             c__ = w - dtnsq1 * dpsi - dtnsq * dphi;
+   23071           0 :             a = (dtnsq + dtnsq1) * w - dtnsq1 * dtnsq * (dpsi + dphi);
+   23072           0 :             b = dtnsq1 * dtnsq * w;
+   23073           0 :             if (a >= 0.) {
+   23074           0 :                 eta = (a +  std::sqrt(std::abs(a * a - b * 4. * c__))) / (c__ * 2.);
+   23075             :             } else {
+   23076           0 :               eta = b * 2. / (a -  std::sqrt(std::abs(a * a - b * 4. * c__)));
+   23077             :             }
+   23078             : 
+   23079           0 :             if (w * eta > 0.) {
+   23080           0 :                 eta = -w / (dpsi + dphi);
+   23081             :             }
+   23082           0 :             temp = eta - dtnsq;
+   23083           0 :             if (temp <= 0.) {
+   23084           0 :                 eta /= 2.;
+   23085             :             }
+   23086             : 
+   23087           0 :             tau += eta;
+   23088           0 :             eta /= *sigma +  std::sqrt(eta + *sigma * *sigma);
+   23089           0 :             i__1 = *n;
+   23090           0 :             for (j = 1; j <= i__1; ++j) {
+   23091           0 :                 delta[j] -= eta;
+   23092           0 :                 work[j] += eta;
+   23093             :             }
+   23094             : 
+   23095           0 :             *sigma += eta;
+   23096             : 
+   23097             :             dpsi = 0.;
+   23098             :             psi = 0.;
+   23099             :             erretm = 0.;
+   23100             :             i__1 = ii;
+   23101           0 :             for (j = 1; j <= i__1; ++j) {
+   23102           0 :                 temp = z__[j] / (work[j] * delta[j]);
+   23103           0 :                 psi += z__[j] * temp;
+   23104           0 :                 dpsi += temp * temp;
+   23105           0 :                 erretm += psi;
+   23106             :             }
+   23107             :             erretm = std::abs(erretm);
+   23108             : 
+   23109           0 :             temp = z__[*n] / (work[*n] * delta[*n]);
+   23110           0 :             phi = z__[*n] * temp;
+   23111           0 :             dphi = temp * temp;
+   23112           0 :             erretm = (-phi - psi) * 8. + erretm - phi + rhoinv + std::abs(tau) * (
+   23113           0 :                     dpsi + dphi);
+   23114             : 
+   23115           0 :             w = rhoinv + phi + psi;
+   23116             :         }
+   23117             : 
+   23118           0 :         *info = 1;
+   23119           0 :         goto L240;
+   23120             : 
+   23121             :     } else {
+   23122             : 
+   23123           0 :         niter = 1;
+   23124           0 :         ip1 = *i__ + 1;
+   23125             : 
+   23126           0 :         delsq = (d__[ip1] - d__[*i__]) * (d__[ip1] + d__[*i__]);
+   23127           0 :         delsq2 = delsq / 2.;
+   23128           0 :         temp = delsq2 / (d__[*i__] +  std::sqrt(d__[*i__] * d__[*i__] + delsq2));
+   23129           0 :         i__1 = *n;
+   23130           0 :         for (j = 1; j <= i__1; ++j) {
+   23131           0 :             work[j] = d__[j] + d__[*i__] + temp;
+   23132           0 :             delta[j] = d__[j] - d__[*i__] - temp;
+   23133             :         }
+   23134             : 
+   23135             :         psi = 0.;
+   23136           0 :         i__1 = *i__ - 1;
+   23137           0 :         for (j = 1; j <= i__1; ++j) {
+   23138           0 :             psi += z__[j] * z__[j] / (work[j] * delta[j]);
+   23139             :         }
+   23140             : 
+   23141             :         phi = 0.;
+   23142           0 :         i__1 = *i__ + 2;
+   23143           0 :         for (j = *n; j >= i__1; --j) {
+   23144           0 :             phi += z__[j] * z__[j] / (work[j] * delta[j]);
+   23145             :         }
+   23146           0 :         c__ = rhoinv + psi + phi;
+   23147           0 :         w = c__ + z__[*i__] * z__[*i__] / (work[*i__] * delta[*i__]) + z__[
+   23148           0 :                 ip1] * z__[ip1] / (work[ip1] * delta[ip1]);
+   23149             : 
+   23150           0 :         if (w > 0.) {
+   23151             : 
+   23152           0 :             orgati = 1;
+   23153             :             sg2lb = 0.;
+   23154             :             sg2ub = delsq2;
+   23155           0 :             a = c__ * delsq + z__[*i__] * z__[*i__] + z__[ip1] * z__[ip1];
+   23156           0 :             b = z__[*i__] * z__[*i__] * delsq;
+   23157           0 :             if (a > 0.) {
+   23158           0 :                 tau = b * 2. / (a +  std::sqrt(std::abs(a * a - b * 4. * c__)));
+   23159             :             } else {
+   23160           0 :                 tau = (a -  std::sqrt(std::abs(a * a - b * 4. * c__))) / (c__ * 2.);
+   23161             :             }
+   23162           0 :             eta = tau / (d__[*i__] +  std::sqrt(d__[*i__] * d__[*i__] + tau));
+   23163             :         } else {
+   23164             : 
+   23165           0 :             orgati = 0;
+   23166           0 :             sg2lb = -delsq2;
+   23167             :             sg2ub = 0.;
+   23168           0 :             a = c__ * delsq - z__[*i__] * z__[*i__] - z__[ip1] * z__[ip1];
+   23169           0 :             b = z__[ip1] * z__[ip1] * delsq;
+   23170           0 :             if (a < 0.) {
+   23171           0 :                 tau = b * 2. / (a -  std::sqrt(std::abs(a * a + b * 4. * c__)));
+   23172             :             } else {
+   23173           0 :                 tau = -(a +  std::sqrt(std::abs(a * a + b * 4. * c__))) /       (c__ * 2.);
+   23174             :             }
+   23175           0 :             eta = tau / (d__[ip1] +  std::sqrt(std::abs(d__[ip1] * d__[ip1] + tau)));
+   23176             :         }
+   23177             : 
+   23178           0 :         if (orgati) {
+   23179           0 :             ii = *i__;
+   23180           0 :             *sigma = d__[*i__] + eta;
+   23181           0 :             i__1 = *n;
+   23182           0 :             for (j = 1; j <= i__1; ++j) {
+   23183           0 :                 work[j] = d__[j] + d__[*i__] + eta;
+   23184           0 :                 delta[j] = d__[j] - d__[*i__] - eta;
+   23185             :             }
+   23186             :         } else {
+   23187           0 :             ii = *i__ + 1;
+   23188           0 :             *sigma = d__[ip1] + eta;
+   23189           0 :             i__1 = *n;
+   23190           0 :             for (j = 1; j <= i__1; ++j) {
+   23191           0 :                 work[j] = d__[j] + d__[ip1] + eta;
+   23192           0 :                 delta[j] = d__[j] - d__[ip1] - eta;
+   23193             :             }
+   23194             :         }
+   23195           0 :         iim1 = ii - 1;
+   23196           0 :         iip1 = ii + 1;
+   23197             : 
+   23198             :         dpsi = 0.;
+   23199             :         psi = 0.;
+   23200             :         erretm = 0.;
+   23201             :         i__1 = iim1;
+   23202           0 :         for (j = 1; j <= i__1; ++j) {
+   23203           0 :             temp = z__[j] / (work[j] * delta[j]);
+   23204           0 :             psi += z__[j] * temp;
+   23205           0 :             dpsi += temp * temp;
+   23206           0 :             erretm += psi;
+   23207             :         }
+   23208             :         erretm = std::abs(erretm);
+   23209             : 
+   23210             :         dphi = 0.;
+   23211             :         phi = 0.;
+   23212             :         i__1 = iip1;
+   23213           0 :         for (j = *n; j >= i__1; --j) {
+   23214           0 :             temp = z__[j] / (work[j] * delta[j]);
+   23215           0 :             phi += z__[j] * temp;
+   23216           0 :             dphi += temp * temp;
+   23217           0 :             erretm += phi;
+   23218             :         }
+   23219             : 
+   23220           0 :         w = rhoinv + phi + psi;
+   23221             : 
+   23222             :         swtch3 = 0;
+   23223           0 :         if (orgati) {
+   23224           0 :             if (w < 0.) {
+   23225             :                 swtch3 = 1;
+   23226             :             }
+   23227             :         } else {
+   23228           0 :             if (w > 0.) {
+   23229             :                 swtch3 = 1;
+   23230             :             }
+   23231             :         }
+   23232           0 :         if (ii == 1 || ii == *n) {
+   23233             :             swtch3 = 0;
+   23234             :         }
+   23235             : 
+   23236           0 :         temp = z__[ii] / (work[ii] * delta[ii]);
+   23237           0 :         dw = dpsi + dphi + temp * temp;
+   23238           0 :         temp = z__[ii] * temp;
+   23239           0 :         w += temp;
+   23240           0 :         erretm = (phi - psi) * 8. + erretm + rhoinv * 2. + std::abs(temp) * 3. + 
+   23241           0 :                 std::abs(tau) * dw;
+   23242             : 
+   23243           0 :         if (std::abs(w) <= eps * erretm) {
+   23244           0 :             goto L240;
+   23245             :         }
+   23246             : 
+   23247           0 :         if (w <= 0.) {
+   23248           0 :             sg2lb = (sg2lb > tau) ? sg2lb : tau;
+   23249             :         } else {
+   23250           0 :             sg2ub = (sg2ub < tau) ? sg2ub : tau;
+   23251             :         }
+   23252             : 
+   23253           0 :         ++niter;
+   23254           0 :         if (! swtch3) {
+   23255           0 :             dtipsq = work[ip1] * delta[ip1];
+   23256           0 :             dtisq = work[*i__] * delta[*i__];
+   23257           0 :             if (orgati) {
+   23258           0 :                 d__1 = z__[*i__] / dtisq;
+   23259           0 :                 c__ = w - dtipsq * dw + delsq * (d__1 * d__1);
+   23260             :             } else {
+   23261           0 :                 d__1 = z__[ip1] / dtipsq;
+   23262           0 :                 c__ = w - dtisq * dw - delsq * (d__1 * d__1);
+   23263             :             }
+   23264           0 :             a = (dtipsq + dtisq) * w - dtipsq * dtisq * dw;
+   23265           0 :             b = dtipsq * dtisq * w;
+   23266           0 :             if ( std::abs(c__)<PLUMED_GMX_FLOAT_MIN) {
+   23267           0 :                 if ( std::abs(a)<PLUMED_GMX_FLOAT_MIN) {
+   23268           0 :                     if (orgati) {
+   23269           0 :                         a = z__[*i__] * z__[*i__] + dtipsq * dtipsq * (dpsi + 
+   23270             :                                 dphi);
+   23271             :                     } else {
+   23272           0 :                         a = z__[ip1] * z__[ip1] + dtisq * dtisq * (dpsi + 
+   23273             :                                 dphi);
+   23274             :                     }
+   23275             :                 }
+   23276           0 :                 eta = b / a;
+   23277           0 :             } else if (a <= 0.) {
+   23278           0 :                 eta = (a -  std::sqrt(std::abs(a * a - b * 4. * c__))) / (c__ * 2.);
+   23279             :             } else {
+   23280           0 :                 eta = b * 2. / (a +  std::sqrt(std::abs(a * a - b * 4. * c__)));
+   23281             :             }
+   23282             :         } else {
+   23283             : 
+   23284           0 :             dtiim = work[iim1] * delta[iim1];
+   23285           0 :             dtiip = work[iip1] * delta[iip1];
+   23286           0 :             temp = rhoinv + psi + phi;
+   23287           0 :             if (orgati) {
+   23288           0 :                 temp1 = z__[iim1] / dtiim;
+   23289           0 :                 temp1 *= temp1;
+   23290           0 :                 c__ = temp - dtiip * (dpsi + dphi) - (d__[iim1] - d__[iip1]) *
+   23291           0 :                          (d__[iim1] + d__[iip1]) * temp1;
+   23292           0 :                 zz[0] = z__[iim1] * z__[iim1];
+   23293           0 :                 if (dpsi < temp1) {
+   23294           0 :                     zz[2] = dtiip * dtiip * dphi;
+   23295             :                 } else {
+   23296           0 :                     zz[2] = dtiip * dtiip * (dpsi - temp1 + dphi);
+   23297             :                 }
+   23298             :             } else {
+   23299           0 :                 temp1 = z__[iip1] / dtiip;
+   23300           0 :                 temp1 *= temp1;
+   23301           0 :                 c__ = temp - dtiim * (dpsi + dphi) - (d__[iip1] - d__[iim1]) *
+   23302           0 :                          (d__[iim1] + d__[iip1]) * temp1;
+   23303           0 :                 if (dphi < temp1) {
+   23304           0 :                     zz[0] = dtiim * dtiim * dpsi;
+   23305             :                 } else {
+   23306           0 :                     zz[0] = dtiim * dtiim * (dpsi + (dphi - temp1));
+   23307             :                 }
+   23308           0 :                 zz[2] = z__[iip1] * z__[iip1];
+   23309             :             }
+   23310           0 :             zz[1] = z__[ii] * z__[ii];
+   23311           0 :             dd[0] = dtiim;
+   23312           0 :             dd[1] = delta[ii] * work[ii];
+   23313           0 :             dd[2] = dtiip;
+   23314           0 :             PLUMED_BLAS_F77_FUNC(slaed6,SLAED6)(&niter, &orgati, &c__, dd, zz, &w, &eta, info);
+   23315           0 :             if (*info != 0) {
+   23316           0 :                 goto L240;
+   23317             :             }
+   23318             :         }
+   23319             : 
+   23320           0 :         if (w * eta >= 0.) {
+   23321           0 :             eta = -w / dw;
+   23322             :         }
+   23323           0 :         if (orgati) {
+   23324           0 :             temp1 = work[*i__] * delta[*i__];
+   23325           0 :             temp = eta - temp1;
+   23326             :         } else {
+   23327           0 :             temp1 = work[ip1] * delta[ip1];
+   23328           0 :             temp = eta - temp1;
+   23329             :         }
+   23330           0 :         if (temp > sg2ub || temp < sg2lb) {
+   23331           0 :             if (w < 0.) {
+   23332           0 :                 eta = (sg2ub - tau) / 2.;
+   23333             :             } else {
+   23334           0 :                 eta = (sg2lb - tau) / 2.;
+   23335             :             }
+   23336             :         }
+   23337             : 
+   23338           0 :         tau += eta;
+   23339           0 :         eta /= *sigma +  std::sqrt(*sigma * *sigma + eta);
+   23340             : 
+   23341             :         prew = w;
+   23342             : 
+   23343           0 :         *sigma += eta;
+   23344           0 :         i__1 = *n;
+   23345           0 :         for (j = 1; j <= i__1; ++j) {
+   23346           0 :             work[j] += eta;
+   23347           0 :             delta[j] -= eta;
+   23348             :         }
+   23349             : 
+   23350             :         dpsi = 0.;
+   23351             :         psi = 0.;
+   23352             :         erretm = 0.;
+   23353             :         i__1 = iim1;
+   23354           0 :         for (j = 1; j <= i__1; ++j) {
+   23355           0 :             temp = z__[j] / (work[j] * delta[j]);
+   23356           0 :             psi += z__[j] * temp;
+   23357           0 :             dpsi += temp * temp;
+   23358           0 :             erretm += psi;
+   23359             :         }
+   23360             :         erretm = std::abs(erretm);
+   23361             : 
+   23362             :         dphi = 0.;
+   23363             :         phi = 0.;
+   23364             :         i__1 = iip1;
+   23365           0 :         for (j = *n; j >= i__1; --j) {
+   23366           0 :             temp = z__[j] / (work[j] * delta[j]);
+   23367           0 :             phi += z__[j] * temp;
+   23368           0 :             dphi += temp * temp;
+   23369           0 :             erretm += phi;
+   23370             :         }
+   23371             : 
+   23372           0 :         temp = z__[ii] / (work[ii] * delta[ii]);
+   23373           0 :         dw = dpsi + dphi + temp * temp;
+   23374           0 :         temp = z__[ii] * temp;
+   23375           0 :         w = rhoinv + phi + psi + temp;
+   23376           0 :         erretm = (phi - psi) * 8. + erretm + rhoinv * 2. + std::abs(temp) * 3. + 
+   23377           0 :                 std::abs(tau) * dw;
+   23378             : 
+   23379           0 :         if (w <= 0.) {
+   23380           0 :             sg2lb = (sg2lb > tau) ? sg2lb : tau;
+   23381             :         } else {
+   23382           0 :             sg2ub = (sg2ub < tau) ? sg2ub : tau;
+   23383             :         }
+   23384             : 
+   23385             :         swtch = 0;
+   23386           0 :         if (orgati) {
+   23387           0 :             if (-w > std::abs(prew) / 10.) {
+   23388             :                 swtch = 1;
+   23389             :             }
+   23390             :         } else {
+   23391           0 :             if (w > std::abs(prew) / 10.) {
+   23392             :                 swtch = 1;
+   23393             :             }
+   23394             :         }
+   23395             : 
+   23396           0 :         iter = niter + 1;
+   23397             : 
+   23398           0 :         for (niter = iter; niter <= 20; ++niter) {
+   23399             : 
+   23400           0 :             if (std::abs(w) <= eps * erretm) {
+   23401           0 :                 goto L240;
+   23402             :             }
+   23403             : 
+   23404           0 :             if (! swtch3) {
+   23405           0 :                 dtipsq = work[ip1] * delta[ip1];
+   23406           0 :                 dtisq = work[*i__] * delta[*i__];
+   23407           0 :                 if (! swtch) {
+   23408           0 :                     if (orgati) {
+   23409           0 :                         d__1 = z__[*i__] / dtisq;
+   23410           0 :                         c__ = w - dtipsq * dw + delsq * (d__1 * d__1);
+   23411             :                     } else {
+   23412           0 :                         d__1 = z__[ip1] / dtipsq;
+   23413           0 :                         c__ = w - dtisq * dw - delsq * (d__1 * d__1);
+   23414             :                     }
+   23415             :                 } else {
+   23416           0 :                     temp = z__[ii] / (work[ii] * delta[ii]);
+   23417           0 :                     if (orgati) {
+   23418           0 :                         dpsi += temp * temp;
+   23419             :                     } else {
+   23420           0 :                         dphi += temp * temp;
+   23421             :                     }
+   23422           0 :                     c__ = w - dtisq * dpsi - dtipsq * dphi;
+   23423             :                 }
+   23424           0 :                 a = (dtipsq + dtisq) * w - dtipsq * dtisq * dw;
+   23425           0 :                 b = dtipsq * dtisq * w;
+   23426           0 :                 if (std::abs(c__)<PLUMED_GMX_FLOAT_MIN) {
+   23427           0 :                     if (std::abs(a)<PLUMED_GMX_FLOAT_MIN) {
+   23428           0 :                         if (! swtch) {
+   23429           0 :                             if (orgati) {
+   23430           0 :                                 a = z__[*i__] * z__[*i__] + dtipsq * dtipsq * 
+   23431           0 :                                         (dpsi + dphi);
+   23432             :                             } else {
+   23433           0 :                                 a = z__[ip1] * z__[ip1] + dtisq * dtisq * (
+   23434           0 :                                         dpsi + dphi);
+   23435             :                             }
+   23436             :                         } else {
+   23437           0 :                             a = dtisq * dtisq * dpsi + dtipsq * dtipsq * dphi;
+   23438             :                         }
+   23439             :                     }
+   23440           0 :                     eta = b / a;
+   23441           0 :                 } else if (a <= 0.) {
+   23442           0 :                   eta = (a -  std::sqrt(std::abs(a * a - b * 4. * c__))) / (c__ * 2.);
+   23443             :                 } else {
+   23444           0 :                   eta = b * 2. / (a +  std::sqrt(std::abs(a * a - b * 4. * c__)));
+   23445             :                 }
+   23446             :             } else {
+   23447             : 
+   23448           0 :                 dtiim = work[iim1] * delta[iim1];
+   23449           0 :                 dtiip = work[iip1] * delta[iip1];
+   23450           0 :                 temp = rhoinv + psi + phi;
+   23451           0 :                 if (swtch) {
+   23452           0 :                     c__ = temp - dtiim * dpsi - dtiip * dphi;
+   23453           0 :                     zz[0] = dtiim * dtiim * dpsi;
+   23454           0 :                     zz[2] = dtiip * dtiip * dphi;
+   23455             :                 } else {
+   23456           0 :                     if (orgati) {
+   23457           0 :                         temp1 = z__[iim1] / dtiim;
+   23458           0 :                         temp1 *= temp1;
+   23459           0 :                         temp2 = (d__[iim1] - d__[iip1]) * (d__[iim1] + d__[
+   23460             :                                 iip1]) * temp1;
+   23461           0 :                         c__ = temp - dtiip * (dpsi + dphi) - temp2;
+   23462           0 :                         zz[0] = z__[iim1] * z__[iim1];
+   23463           0 :                         if (dpsi < temp1) {
+   23464           0 :                             zz[2] = dtiip * dtiip * dphi;
+   23465             :                         } else {
+   23466           0 :                             zz[2] = dtiip * dtiip * (dpsi - temp1 + dphi);
+   23467             :                         }
+   23468             :                     } else {
+   23469           0 :                         temp1 = z__[iip1] / dtiip;
+   23470           0 :                         temp1 *= temp1;
+   23471           0 :                         temp2 = (d__[iip1] - d__[iim1]) * (d__[iim1] + d__[
+   23472             :                                 iip1]) * temp1;
+   23473           0 :                         c__ = temp - dtiim * (dpsi + dphi) - temp2;
+   23474           0 :                         if (dphi < temp1) {
+   23475           0 :                             zz[0] = dtiim * dtiim * dpsi;
+   23476             :                         } else {
+   23477           0 :                             zz[0] = dtiim * dtiim * (dpsi + (dphi - temp1));
+   23478             :                         }
+   23479           0 :                         zz[2] = z__[iip1] * z__[iip1];
+   23480             :                     }
+   23481             :                 }
+   23482           0 :                 dd[0] = dtiim;
+   23483           0 :                 dd[1] = delta[ii] * work[ii];
+   23484           0 :                 dd[2] = dtiip;
+   23485           0 :                 PLUMED_BLAS_F77_FUNC(slaed6,SLAED6)(&niter, &orgati, &c__, dd, zz, &w, &eta, info);
+   23486           0 :                 if (*info != 0) {
+   23487           0 :                     goto L240;
+   23488             :                 }
+   23489             :             }
+   23490             : 
+   23491           0 :             if (w * eta >= 0.) {
+   23492           0 :                 eta = -w / dw;
+   23493             :             }
+   23494           0 :             if (orgati) {
+   23495           0 :                 temp1 = work[*i__] * delta[*i__];
+   23496           0 :                 temp = eta - temp1;
+   23497             :             } else {
+   23498           0 :                 temp1 = work[ip1] * delta[ip1];
+   23499           0 :                 temp = eta - temp1;
+   23500             :             }
+   23501           0 :             if (temp > sg2ub || temp < sg2lb) {
+   23502           0 :                 if (w < 0.) {
+   23503           0 :                     eta = (sg2ub - tau) / 2.;
+   23504             :                 } else {
+   23505           0 :                     eta = (sg2lb - tau) / 2.;
+   23506             :                 }
+   23507             :             }
+   23508             : 
+   23509           0 :             tau += eta;
+   23510           0 :             eta /= *sigma +  std::sqrt(*sigma * *sigma + eta);
+   23511             : 
+   23512           0 :             *sigma += eta;
+   23513           0 :             i__1 = *n;
+   23514           0 :             for (j = 1; j <= i__1; ++j) {
+   23515           0 :                 work[j] += eta;
+   23516           0 :                 delta[j] -= eta;
+   23517             :             }
+   23518             : 
+   23519             :             prew = w;
+   23520             : 
+   23521             :             dpsi = 0.;
+   23522             :             psi = 0.;
+   23523             :             erretm = 0.;
+   23524             :             i__1 = iim1;
+   23525           0 :             for (j = 1; j <= i__1; ++j) {
+   23526           0 :                 temp = z__[j] / (work[j] * delta[j]);
+   23527           0 :                 psi += z__[j] * temp;
+   23528           0 :                 dpsi += temp * temp;
+   23529           0 :                 erretm += psi;
+   23530             :             }
+   23531             :             erretm = std::abs(erretm);
+   23532             : 
+   23533             :             dphi = 0.;
+   23534             :             phi = 0.;
+   23535             :             i__1 = iip1;
+   23536           0 :             for (j = *n; j >= i__1; --j) {
+   23537           0 :                 temp = z__[j] / (work[j] * delta[j]);
+   23538           0 :                 phi += z__[j] * temp;
+   23539           0 :                 dphi += temp * temp;
+   23540           0 :                 erretm += phi;
+   23541             :             }
+   23542             : 
+   23543           0 :             temp = z__[ii] / (work[ii] * delta[ii]);
+   23544           0 :             dw = dpsi + dphi + temp * temp;
+   23545           0 :             temp = z__[ii] * temp;
+   23546           0 :             w = rhoinv + phi + psi + temp;
+   23547           0 :             erretm = (phi - psi) * 8. + erretm + rhoinv * 2. + std::abs(temp) * 3. 
+   23548           0 :                     + std::abs(tau) * dw;
+   23549           0 :             if (w * prew > 0. && std::abs(w) > std::abs(prew) / 10.) {
+   23550           0 :                 swtch = ! swtch;
+   23551             :             }
+   23552             : 
+   23553           0 :             if (w <= 0.) {
+   23554           0 :                 sg2lb = (sg2lb > tau) ? sg2lb : tau;
+   23555             :             } else {
+   23556           0 :                 sg2ub = (sg2ub < tau) ? sg2ub : tau;
+   23557             :             }
+   23558             :         }
+   23559             : 
+   23560           0 :         *info = 1;
+   23561             : 
+   23562             :     }
+   23563             : 
+   23564           0 : L240:
+   23565             :     return;
+   23566             : 
+   23567             : } 
+   23568             : }
+   23569             : }
+   23570             : #include <cmath>
+   23571             : #include "lapack.h"
+   23572             : 
+   23573             : #include "blas/blas.h"
+   23574             : namespace PLMD{
+   23575             : namespace lapack{
+   23576             : using namespace blas;
+   23577             : void 
+   23578           0 : PLUMED_BLAS_F77_FUNC(slasd5,SLASD5)(int *i__, 
+   23579             :         float *d__, 
+   23580             :         float *z__, 
+   23581             :         float *delta, 
+   23582             :         float *rho, 
+   23583             :         float *dsigma, 
+   23584             :         float *work)
+   23585             : {
+   23586             :     float b, c__, w, del, tau, delsq;
+   23587             : 
+   23588             :     --work;
+   23589             :     --delta;
+   23590             :     --z__;
+   23591             :     --d__;
+   23592             : 
+   23593           0 :     del = d__[2] - d__[1];
+   23594           0 :     delsq = del * (d__[2] + d__[1]);
+   23595           0 :     if (*i__ == 1) {
+   23596           0 :         w = *rho * 4. * (z__[2] * z__[2] / (d__[1] + d__[2] * 3.) - z__[1] * 
+   23597           0 :                 z__[1] / (d__[1] * 3. + d__[2])) / del + 1.;
+   23598           0 :         if (w > 0.) {
+   23599           0 :             b = delsq + *rho * (z__[1] * z__[1] + z__[2] * z__[2]);
+   23600           0 :             c__ = *rho * z__[1] * z__[1] * delsq;
+   23601             : 
+   23602           0 :             tau = c__ * 2. / (b +  std::sqrt(std::abs(b * b - c__ * 4.)));
+   23603             : 
+   23604           0 :             tau /= d__[1] +  std::sqrt(d__[1] * d__[1] + tau);
+   23605           0 :             *dsigma = d__[1] + tau;
+   23606           0 :             delta[1] = -tau;
+   23607           0 :             delta[2] = del - tau;
+   23608           0 :             work[1] = d__[1] * 2. + tau;
+   23609           0 :             work[2] = d__[1] + tau + d__[2];
+   23610             :         } else {
+   23611           0 :             b = -delsq + *rho * (z__[1] * z__[1] + z__[2] * z__[2]);
+   23612           0 :             c__ = *rho * z__[2] * z__[2] * delsq;
+   23613             : 
+   23614           0 :             if (b > 0.) {
+   23615           0 :                 tau = c__ * -2. / (b +  std::sqrt(b * b + c__ * 4.));
+   23616             :             } else {
+   23617           0 :                 tau = (b -  std::sqrt(b * b + c__ * 4.)) / 2.;
+   23618             :             }
+   23619             : 
+   23620           0 :             tau /= d__[2] +  std::sqrt(std::abs(d__[2] * d__[2] + tau));
+   23621           0 :             *dsigma = d__[2] + tau;
+   23622           0 :             delta[1] = -(del + tau);
+   23623           0 :             delta[2] = -tau;
+   23624           0 :             work[1] = d__[1] + tau + d__[2];
+   23625           0 :             work[2] = d__[2] * 2. + tau;
+   23626             :         }
+   23627             :     } else {
+   23628             : 
+   23629           0 :         b = -delsq + *rho * (z__[1] * z__[1] + z__[2] * z__[2]);
+   23630           0 :         c__ = *rho * z__[2] * z__[2] * delsq;
+   23631             : 
+   23632           0 :         if (b > 0.) {
+   23633           0 :             tau = (b +  std::sqrt(b * b + c__ * 4.)) / 2.;
+   23634             :         } else {
+   23635           0 :             tau = c__ * 2. / (-b +  std::sqrt(b * b + c__ * 4.));
+   23636             :         }
+   23637           0 :         tau /= d__[2] +  std::sqrt(d__[2] * d__[2] + tau);
+   23638           0 :         *dsigma = d__[2] + tau;
+   23639           0 :         delta[1] = -(del + tau);
+   23640           0 :         delta[2] = -tau;
+   23641           0 :         work[1] = d__[1] + tau + d__[2];
+   23642           0 :         work[2] = d__[2] * 2. + tau;
+   23643             :     }
+   23644           0 :     return;
+   23645             : 
+   23646             : } 
+   23647             : }
+   23648             : }
+   23649             : #include <cmath>
+   23650             : #include "blas/blas.h"
+   23651             : #include "lapack.h"
+   23652             : 
+   23653             : #include "blas/blas.h"
+   23654             : namespace PLMD{
+   23655             : namespace lapack{
+   23656             : using namespace blas;
+   23657             : void 
+   23658           0 : PLUMED_BLAS_F77_FUNC(slasd6,SLASD6)(int *icompq, 
+   23659             :         int *nl, 
+   23660             :         int *nr, 
+   23661             :         int *sqre, 
+   23662             :         float *d__, 
+   23663             :         float *vf, 
+   23664             :         float *vl, 
+   23665             :         float *alpha, 
+   23666             :         float *beta, 
+   23667             :         int *idxq, 
+   23668             :         int *perm, 
+   23669             :         int *givptr, 
+   23670             :         int *givcol, 
+   23671             :         int *ldgcol, 
+   23672             :         float *givnum,
+   23673             :         int *ldgnum, 
+   23674             :         float *poles, 
+   23675             :         float *difl, 
+   23676             :         float *difr, 
+   23677             :         float *z__, 
+   23678             :         int *k, 
+   23679             :         float *c__, 
+   23680             :         float *s, 
+   23681             :         float *work, 
+   23682             :         int *iwork, 
+   23683             :         int *info)
+   23684             : {
+   23685             :     int givcol_dim1, givcol_offset, givnum_dim1, givnum_offset, 
+   23686             :             poles_dim1, poles_offset, i__1;
+   23687             :     float d__1, d__2;
+   23688             : 
+   23689             :     int i__, m, n, n1, n2, iw, idx, idxc, idxp, ivfw, ivlw;
+   23690             :     int isigma;
+   23691             :     float orgnrm;
+   23692           0 :     int c__0 = 0;
+   23693           0 :     float one = 1.0;
+   23694           0 :     int c__1 = 1;
+   23695           0 :     int c_n1 = -1;
+   23696             : 
+   23697           0 :     --d__;
+   23698             :     --vf;
+   23699             :     --vl;
+   23700             :     --idxq;
+   23701             :     --perm;
+   23702             :     givcol_dim1 = *ldgcol;
+   23703             :     givcol_offset = 1 + givcol_dim1;
+   23704             :     givcol -= givcol_offset;
+   23705           0 :     poles_dim1 = *ldgnum;
+   23706           0 :     poles_offset = 1 + poles_dim1;
+   23707           0 :     poles -= poles_offset;
+   23708             :     givnum_dim1 = *ldgnum;
+   23709             :     givnum_offset = 1 + givnum_dim1;
+   23710             :     givnum -= givnum_offset;
+   23711             :     --difl;
+   23712             :     --difr;
+   23713             :     --z__;
+   23714           0 :     --work;
+   23715             :     --iwork;
+   23716             : 
+   23717           0 :     *info = 0;
+   23718           0 :     n = *nl + *nr + 1;
+   23719           0 :     m = n + *sqre;
+   23720             : 
+   23721             :     isigma = 1;
+   23722           0 :     iw = isigma + n;
+   23723           0 :     ivfw = iw + m;
+   23724           0 :     ivlw = ivfw + m;
+   23725             : 
+   23726             :     idx = 1;
+   23727             :     idxc = idx + n;
+   23728           0 :     idxp = idxc + n;
+   23729             : 
+   23730           0 :     d__1 = std::abs(*alpha); 
+   23731           0 :     d__2 = std::abs(*beta);
+   23732           0 :     orgnrm = (d__1 > d__2) ? d__1 : d__2;
+   23733           0 :     d__[*nl + 1] = 0.;
+   23734             :     i__1 = n;
+   23735           0 :     for (i__ = 1; i__ <= i__1; ++i__) {
+   23736           0 :       d__1 = std::abs(d__[i__]);
+   23737           0 :         if (d__1 > orgnrm)
+   23738           0 :             orgnrm = d__1;
+   23739             :     }
+   23740           0 :     PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G", &c__0, &c__0, &orgnrm, &one, &n, &c__1, &d__[1], &n, info);
+   23741           0 :     *alpha /= orgnrm;
+   23742           0 :     *beta /= orgnrm;
+   23743             : 
+   23744           0 :     PLUMED_BLAS_F77_FUNC(slasd7,SLASD7)(icompq, nl, nr, sqre, k, &d__[1], &z__[1], &work[iw], &vf[1], &
+   23745           0 :             work[ivfw], &vl[1], &work[ivlw], alpha, beta, &work[isigma], &
+   23746           0 :             iwork[idx], &iwork[idxp], &idxq[1], &perm[1], givptr, &givcol[
+   23747             :             givcol_offset], ldgcol, &givnum[givnum_offset], ldgnum, c__, s, 
+   23748             :             info);
+   23749             : 
+   23750           0 :     PLUMED_BLAS_F77_FUNC(slasd8,SLASD8)(icompq, k, &d__[1], &z__[1], &vf[1], &vl[1], &difl[1], &difr[1], 
+   23751             :             ldgnum, &work[isigma], &work[iw], info);
+   23752             : 
+   23753           0 :     if (*icompq == 1) {
+   23754           0 :         PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(k, &d__[1], &c__1, &poles[poles_dim1 + 1], &c__1);
+   23755           0 :         PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(k, &work[isigma], &c__1, &poles[(poles_dim1 << 1) + 1], &c__1);
+   23756             :     }
+   23757             : 
+   23758           0 :     PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G", &c__0, &c__0, &one, &orgnrm, &n, &c__1, &d__[1], &n, info);
+   23759             : 
+   23760           0 :     n1 = *k;
+   23761           0 :     n2 = n - *k;
+   23762           0 :     PLUMED_BLAS_F77_FUNC(slamrg,SLAMRG)(&n1, &n2, &d__[1], &c__1, &c_n1, &idxq[1]);
+   23763             : 
+   23764           0 :     return;
+   23765             : 
+   23766             : }
+   23767             : 
+   23768             : 
+   23769             : }
+   23770             : }
+   23771             : #include <cmath>
+   23772             : #include "real.h"
+   23773             : 
+   23774             : #include "blas/blas.h"
+   23775             : #include "lapack.h"
+   23776             : #include "lapack_limits.h"
+   23777             : 
+   23778             : #include "blas/blas.h"
+   23779             : namespace PLMD{
+   23780             : namespace lapack{
+   23781             : using namespace blas;
+   23782             : void 
+   23783           0 : PLUMED_BLAS_F77_FUNC(slasd7,SLASD7)(int *icompq, 
+   23784             :         int *nl, 
+   23785             :         int *nr, 
+   23786             :         int *sqre, 
+   23787             :         int *k, 
+   23788             :         float *d__, 
+   23789             :         float *z__, 
+   23790             :         float *zw, 
+   23791             :         float *vf, 
+   23792             :         float *vfw,
+   23793             :         float *vl, 
+   23794             :         float *vlw,
+   23795             :         float *alpha, 
+   23796             :         float *beta,
+   23797             :         float *dsigma, 
+   23798             :         int *idx, 
+   23799             :         int *idxp,
+   23800             :         int *idxq, 
+   23801             :         int *perm, 
+   23802             :         int *givptr,
+   23803             :         int *givcol, 
+   23804             :         int *ldgcol, 
+   23805             :         float *givnum,
+   23806             :         int *ldgnum, 
+   23807             :         float *c__, 
+   23808             :         float *s, 
+   23809             :         int *info)
+   23810             : {
+   23811             :     int givcol_dim1, givcol_offset, givnum_dim1, givnum_offset, i__1;
+   23812             :     float d__1, d__2;
+   23813             : 
+   23814             :     int i__, j, m, n, k2;
+   23815             :     float z1;
+   23816             :     int jp;
+   23817             :     float eps, tau, tol;
+   23818             :     int nlp1, nlp2, idxi, idxj;
+   23819             :     int idxjp;
+   23820             :     int jprev = 0;
+   23821             :     float hlftol;
+   23822           0 :     int c__1 = 1;
+   23823             : 
+   23824           0 :     --d__;
+   23825           0 :     --z__;
+   23826           0 :     --zw;
+   23827           0 :     --vf;
+   23828           0 :     --vfw;
+   23829           0 :     --vl;
+   23830           0 :     --vlw;
+   23831           0 :     --dsigma;
+   23832           0 :     --idx;
+   23833           0 :     --idxp;
+   23834           0 :     --idxq;
+   23835           0 :     --perm;
+   23836           0 :     givcol_dim1 = *ldgcol;
+   23837           0 :     givcol_offset = 1 + givcol_dim1;
+   23838           0 :     givcol -= givcol_offset;
+   23839           0 :     givnum_dim1 = *ldgnum;
+   23840           0 :     givnum_offset = 1 + givnum_dim1;
+   23841           0 :     givnum -= givnum_offset;
+   23842             : 
+   23843           0 :     *info = 0;
+   23844           0 :     n = *nl + *nr + 1;
+   23845           0 :     m = n + *sqre;
+   23846             : 
+   23847           0 :     nlp1 = *nl + 1;
+   23848           0 :     nlp2 = *nl + 2;
+   23849           0 :     if (*icompq == 1) {
+   23850           0 :         *givptr = 0;
+   23851             :     }
+   23852             : 
+   23853           0 :     z1 = *alpha * vl[nlp1];
+   23854           0 :     vl[nlp1] = 0.;
+   23855           0 :     tau = vf[nlp1];
+   23856           0 :     for (i__ = *nl; i__ >= 1; --i__) {
+   23857           0 :         z__[i__ + 1] = *alpha * vl[i__];
+   23858           0 :         vl[i__] = 0.;
+   23859           0 :         vf[i__ + 1] = vf[i__];
+   23860           0 :         d__[i__ + 1] = d__[i__];
+   23861           0 :         idxq[i__ + 1] = idxq[i__] + 1;
+   23862             :     }
+   23863           0 :     vf[1] = tau;
+   23864             : 
+   23865             :     i__1 = m;
+   23866           0 :     for (i__ = nlp2; i__ <= i__1; ++i__) {
+   23867           0 :         z__[i__] = *beta * vf[i__];
+   23868           0 :         vf[i__] = 0.;
+   23869             :     }
+   23870           0 :     i__1 = n;
+   23871           0 :     for (i__ = nlp2; i__ <= i__1; ++i__) {
+   23872           0 :         idxq[i__] += nlp1;
+   23873             :     }
+   23874             : 
+   23875             :     i__1 = n;
+   23876           0 :     for (i__ = 2; i__ <= i__1; ++i__) {
+   23877           0 :         dsigma[i__] = d__[idxq[i__]];
+   23878           0 :         zw[i__] = z__[idxq[i__]];
+   23879           0 :         vfw[i__] = vf[idxq[i__]];
+   23880           0 :         vlw[i__] = vl[idxq[i__]];
+   23881             :     }
+   23882             : 
+   23883           0 :     PLUMED_BLAS_F77_FUNC(slamrg,SLAMRG)(nl, nr, &dsigma[2], &c__1, &c__1, &idx[2]);
+   23884             : 
+   23885           0 :     i__1 = n;
+   23886           0 :     for (i__ = 2; i__ <= i__1; ++i__) {
+   23887           0 :         idxi = idx[i__] + 1;
+   23888           0 :         d__[i__] = dsigma[idxi];
+   23889           0 :         z__[i__] = zw[idxi];
+   23890           0 :         vf[i__] = vfw[idxi];
+   23891           0 :         vl[i__] = vlw[idxi];
+   23892             :     }
+   23893             : 
+   23894             :     eps = PLUMED_GMX_FLOAT_EPS;
+   23895             : 
+   23896           0 :     d__1 = std::abs(*alpha);
+   23897           0 :     d__2 = std::abs(*beta);
+   23898           0 :     tol = (d__1>d__2) ? d__1 : d__2;
+   23899           0 :     d__2 = std::abs(d__[n]);
+   23900           0 :     tol = eps * 64. * ((d__2>tol) ? d__2 : tol);
+   23901             : 
+   23902           0 :     *k = 1;
+   23903           0 :     k2 = n + 1;
+   23904             :     i__1 = n;
+   23905           0 :     for (j = 2; j <= i__1; ++j) {
+   23906           0 :         if (std::abs(z__[j]) <= tol) {
+   23907             : 
+   23908           0 :             --k2;
+   23909           0 :             idxp[k2] = j;
+   23910           0 :             if (j == n) {
+   23911           0 :                 goto L100;
+   23912             :             }
+   23913             :         } else {
+   23914             :             jprev = j;
+   23915           0 :             goto L70;
+   23916             :         }
+   23917             :     }
+   23918           0 : L70:
+   23919             :     j = jprev;
+   23920           0 : L80:
+   23921           0 :     ++j;
+   23922           0 :     if (j > n) {
+   23923           0 :         goto L90;
+   23924             :     }
+   23925           0 :     if (std::abs(z__[j]) <= tol) {
+   23926             : 
+   23927           0 :         --k2;
+   23928           0 :         idxp[k2] = j;
+   23929             :     } else {
+   23930             : 
+   23931           0 :         if (std::abs(d__[j] - d__[jprev]) <= tol) {
+   23932             : 
+   23933           0 :             *s = z__[jprev];
+   23934           0 :             *c__ = z__[j];
+   23935             : 
+   23936           0 :             tau = PLUMED_BLAS_F77_FUNC(slapy2,SLAPY2)(c__, s);
+   23937           0 :             z__[j] = tau;
+   23938           0 :             z__[jprev] = 0.;
+   23939           0 :             *c__ /= tau;
+   23940           0 :             *s = -(*s) / tau;
+   23941             : 
+   23942             : 
+   23943           0 :             if (*icompq == 1) {
+   23944           0 :                 ++(*givptr);
+   23945           0 :                 idxjp = idxq[idx[jprev] + 1];
+   23946           0 :                 idxj = idxq[idx[j] + 1];
+   23947           0 :                 if (idxjp <= nlp1) {
+   23948           0 :                     --idxjp;
+   23949             :                 }
+   23950           0 :                 if (idxj <= nlp1) {
+   23951           0 :                     --idxj;
+   23952             :                 }
+   23953           0 :                 givcol[*givptr + (givcol_dim1 << 1)] = idxjp;
+   23954           0 :                 givcol[*givptr + givcol_dim1] = idxj;
+   23955           0 :                 givnum[*givptr + (givnum_dim1 << 1)] = *c__;
+   23956           0 :                 givnum[*givptr + givnum_dim1] = *s;
+   23957             :             }
+   23958           0 :             PLUMED_BLAS_F77_FUNC(srot,SROT)(&c__1, &vf[jprev], &c__1, &vf[j], &c__1, c__, s);
+   23959           0 :             PLUMED_BLAS_F77_FUNC(srot,SROT)(&c__1, &vl[jprev], &c__1, &vl[j], &c__1, c__, s);
+   23960           0 :             --k2;
+   23961           0 :             idxp[k2] = jprev;
+   23962             :             jprev = j;
+   23963             :         } else {
+   23964           0 :             ++(*k);
+   23965           0 :             zw[*k] = z__[jprev];
+   23966           0 :             dsigma[*k] = d__[jprev];
+   23967           0 :             idxp[*k] = jprev;
+   23968             :             jprev = j;
+   23969             :         }
+   23970             :     }
+   23971           0 :     goto L80;
+   23972             : L90:
+   23973             : 
+   23974           0 :     ++(*k);
+   23975           0 :     zw[*k] = z__[jprev];
+   23976           0 :     dsigma[*k] = d__[jprev];
+   23977           0 :     idxp[*k] = jprev;
+   23978             : 
+   23979           0 : L100:
+   23980             : 
+   23981           0 :     i__1 = n;
+   23982           0 :     for (j = 2; j <= i__1; ++j) {
+   23983           0 :         jp = idxp[j];
+   23984           0 :         dsigma[j] = d__[jp];
+   23985           0 :         vfw[j] = vf[jp];
+   23986           0 :         vlw[j] = vl[jp];
+   23987             :     }
+   23988           0 :     if (*icompq == 1) {
+   23989             :         i__1 = n;
+   23990           0 :         for (j = 2; j <= i__1; ++j) {
+   23991           0 :             jp = idxp[j];
+   23992           0 :             perm[j] = idxq[idx[jp] + 1];
+   23993           0 :             if (perm[j] <= nlp1) {
+   23994           0 :                 --perm[j];
+   23995             :             }
+   23996             :         }
+   23997             :     }
+   23998           0 :     i__1 = n - *k;
+   23999           0 :     PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&i__1, &dsigma[*k + 1], &c__1, &d__[*k + 1], &c__1);
+   24000             : 
+   24001           0 :     dsigma[1] = 0.;
+   24002           0 :     hlftol = tol / 2.;
+   24003           0 :     if (std::abs(dsigma[2]) <= hlftol) {
+   24004           0 :         dsigma[2] = hlftol;
+   24005             :     }
+   24006           0 :     if (m > n) {
+   24007           0 :         z__[1] = PLUMED_BLAS_F77_FUNC(slapy2,SLAPY2)(&z1, &z__[m]);
+   24008           0 :         if (z__[1] <= tol) {
+   24009           0 :             *c__ = 1.;
+   24010           0 :             *s = 0.;
+   24011           0 :             z__[1] = tol;
+   24012             :         } else {
+   24013           0 :             *c__ = z1 / z__[1];
+   24014           0 :             *s = -z__[m] / z__[1];
+   24015             :         }
+   24016           0 :         PLUMED_BLAS_F77_FUNC(srot,SROT)(&c__1, &vf[m], &c__1, &vf[1], &c__1, c__, s);
+   24017           0 :         PLUMED_BLAS_F77_FUNC(srot,SROT)(&c__1, &vl[m], &c__1, &vl[1], &c__1, c__, s);
+   24018             :     } else {
+   24019           0 :         if (std::abs(z1) <= tol) {
+   24020           0 :             z__[1] = tol;
+   24021             :         } else {
+   24022           0 :             z__[1] = z1;
+   24023             :         }
+   24024             :     }
+   24025             : 
+   24026           0 :     i__1 = *k - 1;
+   24027           0 :     PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&i__1, &zw[2], &c__1, &z__[2], &c__1);
+   24028           0 :     i__1 = n - 1;
+   24029           0 :     PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&i__1, &vfw[2], &c__1, &vf[2], &c__1);
+   24030           0 :     i__1 = n - 1;
+   24031           0 :     PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&i__1, &vlw[2], &c__1, &vl[2], &c__1);
+   24032             : 
+   24033           0 :     return;
+   24034             : 
+   24035             : }
+   24036             : 
+   24037             : 
+   24038             : }
+   24039             : }
+   24040             : #include <cmath>
+   24041             : #include "blas/blas.h"
+   24042             : #include "lapack.h"
+   24043             : 
+   24044             : #include "blas/blas.h"
+   24045             : namespace PLMD{
+   24046             : namespace lapack{
+   24047             : using namespace blas;
+   24048             : void 
+   24049           0 : PLUMED_BLAS_F77_FUNC(slasd8,SLASD8)(int *icompq, 
+   24050             :         int *k, 
+   24051             :         float *d__, 
+   24052             :         float *z__, 
+   24053             :         float *vf, 
+   24054             :         float *vl, 
+   24055             :         float *difl, 
+   24056             :         float *difr, 
+   24057             :         int *lddifr, 
+   24058             :         float *dsigma, 
+   24059             :         float *work, 
+   24060             :         int *info)
+   24061             : {
+   24062             :     int difr_dim1, difr_offset, i__1, i__2;
+   24063             :     float d__2;
+   24064             : 
+   24065             :     int i__, j;
+   24066             :     float dj, rho;
+   24067             :     int iwk1, iwk2, iwk3;
+   24068             :     float temp;
+   24069             :     int iwk2i, iwk3i;
+   24070             :     float diflj, difrj, dsigj;
+   24071             :     float dsigjp;
+   24072           0 :     int c__1 = 1;
+   24073           0 :     int c__0 = 0;
+   24074           0 :     float one = 1.;
+   24075             : 
+   24076             :     /* avoid warnings on high gcc optimization levels */
+   24077             :     difrj = dsigjp = 0;
+   24078             : 
+   24079           0 :      --d__;
+   24080           0 :     --z__;
+   24081             :     --vf;
+   24082             :     --vl;
+   24083           0 :     --difl;
+   24084           0 :     difr_dim1 = *lddifr;
+   24085           0 :     difr_offset = 1 + difr_dim1;
+   24086           0 :     difr -= difr_offset;
+   24087           0 :     --dsigma;
+   24088           0 :     --work;
+   24089             : 
+   24090           0 :     *info = 0;
+   24091             : 
+   24092           0 :     if (*k == 1) {
+   24093           0 :         d__[1] = std::abs(z__[1]);
+   24094           0 :         difl[1] = d__[1];
+   24095           0 :         if (*icompq == 1) {
+   24096           0 :             difl[2] = 1.;
+   24097           0 :             difr[(difr_dim1 << 1) + 1] = 1.;
+   24098             :         }
+   24099           0 :         return;
+   24100             :     }
+   24101             : 
+   24102             :     iwk1 = 1;
+   24103           0 :     iwk2 = iwk1 + *k;
+   24104           0 :     iwk3 = iwk2 + *k;
+   24105             :     iwk2i = iwk2 - 1;
+   24106           0 :     iwk3i = iwk3 - 1;
+   24107             : 
+   24108           0 :     rho = PLUMED_BLAS_F77_FUNC(snrm2,SNRM2)(k, &z__[1], &c__1);
+   24109           0 :     PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G", &c__0, &c__0, &rho, &one, k, &c__1, &z__[1], k, info);
+   24110           0 :     rho *= rho;
+   24111             : 
+   24112           0 :     PLUMED_BLAS_F77_FUNC(slaset,SLASET)("A", k, &c__1, &one, &one, &work[iwk3], k);
+   24113             : 
+   24114           0 :     i__1 = *k;
+   24115           0 :     for (j = 1; j <= i__1; ++j) {
+   24116           0 :         PLUMED_BLAS_F77_FUNC(slasd4,SLASD4)(k, &j, &dsigma[1], &z__[1], &work[iwk1], &rho, &d__[j], &work[
+   24117           0 :                 iwk2], info);
+   24118             : 
+   24119           0 :         if (*info != 0) {
+   24120             :             return;
+   24121             :         }
+   24122           0 :         work[iwk3i + j] = work[iwk3i + j] * work[j] * work[iwk2i + j];
+   24123           0 :         difl[j] = -work[j];
+   24124           0 :         difr[j + difr_dim1] = -work[j + 1];
+   24125             :         i__2 = j - 1;
+   24126           0 :         for (i__ = 1; i__ <= i__2; ++i__) {
+   24127           0 :             work[iwk3i + i__] = work[iwk3i + i__] * work[i__] * work[iwk2i + 
+   24128           0 :                     i__] / (dsigma[i__] - dsigma[j]) / (dsigma[i__] + dsigma[
+   24129             :                     j]);
+   24130             :         }
+   24131           0 :         i__2 = *k;
+   24132           0 :         for (i__ = j + 1; i__ <= i__2; ++i__) {
+   24133           0 :             work[iwk3i + i__] = work[iwk3i + i__] * work[i__] * work[iwk2i + 
+   24134           0 :                     i__] / (dsigma[i__] - dsigma[j]) / (dsigma[i__] + dsigma[
+   24135             :                     j]);
+   24136             :         }
+   24137             :     }
+   24138             : 
+   24139           0 :     i__1 = *k;
+   24140           0 :     for (i__ = 1; i__ <= i__1; ++i__) {
+   24141           0 :         d__2 =  std::sqrt(std::abs(work[iwk3i + i__]));
+   24142           0 :         z__[i__] = (z__[i__] > 0) ? d__2 : -d__2;
+   24143             :     }
+   24144             : 
+   24145           0 :     i__1 = *k;
+   24146           0 :     for (j = 1; j <= i__1; ++j) {
+   24147           0 :         diflj = difl[j];
+   24148           0 :         dj = d__[j];
+   24149           0 :         dsigj = -dsigma[j];
+   24150           0 :         if (j < *k) {
+   24151           0 :             difrj = -difr[j + difr_dim1];
+   24152           0 :             dsigjp = -dsigma[j + 1];
+   24153             :         }
+   24154           0 :         work[j] = -z__[j] / diflj / (dsigma[j] + dj);
+   24155             :         i__2 = j - 1;
+   24156           0 :         for (i__ = 1; i__ <= i__2; ++i__) {
+   24157           0 :           work[i__] = z__[i__] / (dsigma[i__] + dsigj - diflj) / ( dsigma[i__] + dj);
+   24158             :         }
+   24159           0 :         i__2 = *k;
+   24160           0 :         for (i__ = j + 1; i__ <= i__2; ++i__) {
+   24161           0 :             work[i__] = z__[i__] / (dsigma[i__] + dsigjp - difrj) / (dsigma[i__] + dj);
+   24162             :         }
+   24163           0 :         temp = PLUMED_BLAS_F77_FUNC(snrm2,SNRM2)(k, &work[1], &c__1);
+   24164           0 :         work[iwk2i + j] = PLUMED_BLAS_F77_FUNC(sdot,SDOT)(k, &work[1], &c__1, &vf[1], &c__1) / temp;
+   24165           0 :         work[iwk3i + j] = PLUMED_BLAS_F77_FUNC(sdot,SDOT)(k, &work[1], &c__1, &vl[1], &c__1) / temp;
+   24166           0 :         if (*icompq == 1) {
+   24167           0 :             difr[j + (difr_dim1 << 1)] = temp;
+   24168             :         }
+   24169             :     }
+   24170             : 
+   24171           0 :     PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(k, &work[iwk2], &c__1, &vf[1], &c__1);
+   24172           0 :     PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(k, &work[iwk3], &c__1, &vl[1], &c__1);
+   24173             : 
+   24174             :     return;
+   24175             : 
+   24176             : } 
+   24177             : }
+   24178             : }
+   24179             : #include "blas/blas.h"
+   24180             : #include "lapack.h"
+   24181             : 
+   24182             : #include "blas/blas.h"
+   24183             : namespace PLMD{
+   24184             : namespace lapack{
+   24185             : using namespace blas;
+   24186             : void 
+   24187           0 : PLUMED_BLAS_F77_FUNC(slasda,SLASDA)(int *icompq, 
+   24188             :         int *smlsiz, 
+   24189             :         int *n, 
+   24190             :         int *sqre, 
+   24191             :         float *d__, 
+   24192             :         float *e, 
+   24193             :         float *u, 
+   24194             :         int *ldu, 
+   24195             :         float *vt, 
+   24196             :         int *k, 
+   24197             :         float *difl, 
+   24198             :         float *difr, 
+   24199             :         float *z__, 
+   24200             :         float *poles, 
+   24201             :         int *givptr, 
+   24202             :         int *givcol, 
+   24203             :         int *ldgcol, 
+   24204             :         int *perm, 
+   24205             :         float *givnum, 
+   24206             :         float *c__, 
+   24207             :         float *s, 
+   24208             :         float *work, 
+   24209             :         int *iwork, 
+   24210             :         int *info)
+   24211             : {
+   24212             :     int givcol_dim1, givcol_offset, perm_dim1, perm_offset, difl_dim1, 
+   24213             :             difl_offset, difr_dim1, difr_offset, givnum_dim1, givnum_offset, 
+   24214             :             poles_dim1, poles_offset, u_dim1, u_offset, vt_dim1, vt_offset, 
+   24215             :             z_dim1, z_offset, i__1, i__2;
+   24216             : 
+   24217             :     int i__, j, m, i1, ic, lf, nd, ll, nl, vf, nr, vl, im1, ncc, 
+   24218             :             nlf, nrf, vfi, iwk, vli, lvl, nru, ndb1, nlp1, lvl2, nrp1;
+   24219             :     float beta;
+   24220             :     int idxq, nlvl;
+   24221             :     float alpha;
+   24222             :     int inode, ndiml, ndimr, idxqi, itemp;
+   24223             :     int sqrei;
+   24224             :     int nwork1, nwork2;
+   24225             :     int smlszp;
+   24226           0 :     int c__0 = 0;
+   24227           0 :     float zero = 0.0;
+   24228           0 :     float one = 1.;
+   24229           0 :     int c__1 = 1;
+   24230           0 :     --d__;
+   24231           0 :     --e;
+   24232           0 :     givnum_dim1 = *ldu;
+   24233           0 :     givnum_offset = 1 + givnum_dim1;
+   24234           0 :     givnum -= givnum_offset;
+   24235             :     poles_dim1 = *ldu;
+   24236             :     poles_offset = 1 + poles_dim1;
+   24237             :     poles -= poles_offset;
+   24238             :     z_dim1 = *ldu;
+   24239             :     z_offset = 1 + z_dim1;
+   24240             :     z__ -= z_offset;
+   24241             :     difr_dim1 = *ldu;
+   24242             :     difr_offset = 1 + difr_dim1;
+   24243             :     difr -= difr_offset;
+   24244             :     difl_dim1 = *ldu;
+   24245             :     difl_offset = 1 + difl_dim1;
+   24246             :     difl -= difl_offset;
+   24247             :     vt_dim1 = *ldu;
+   24248             :     vt_offset = 1 + vt_dim1;
+   24249           0 :     vt -= vt_offset;
+   24250             :     u_dim1 = *ldu;
+   24251             :     u_offset = 1 + u_dim1;
+   24252           0 :     u -= u_offset;
+   24253             :     --k;
+   24254             :     --givptr;
+   24255           0 :     perm_dim1 = *ldgcol;
+   24256           0 :     perm_offset = 1 + perm_dim1;
+   24257           0 :     perm -= perm_offset;
+   24258             :     givcol_dim1 = *ldgcol;
+   24259             :     givcol_offset = 1 + givcol_dim1;
+   24260             :     givcol -= givcol_offset;
+   24261             :     --c__;
+   24262             :     --s;
+   24263           0 :     --work;
+   24264           0 :     --iwork;
+   24265           0 :     *info = 0;
+   24266             : 
+   24267           0 :     m = *n + *sqre;
+   24268             : 
+   24269           0 :     if (*n <= *smlsiz) {
+   24270           0 :         if (*icompq == 0) {
+   24271           0 :             PLUMED_BLAS_F77_FUNC(slasdq,SLASDQ)("U", sqre, n, &c__0, &c__0, &c__0, &d__[1], &e[1], &vt[
+   24272             :                     vt_offset], ldu, &u[u_offset], ldu, &u[u_offset], ldu, &
+   24273             :                     work[1], info);
+   24274             :         } else {
+   24275           0 :             PLUMED_BLAS_F77_FUNC(slasdq,SLASDQ)("U", sqre, n, &m, n, &c__0, &d__[1], &e[1], &vt[vt_offset]
+   24276             :                     , ldu, &u[u_offset], ldu, &u[u_offset], ldu, &work[1], 
+   24277             :                     info);
+   24278             :         }
+   24279           0 :         return;
+   24280             :     }
+   24281             : 
+   24282             :     inode = 1;
+   24283           0 :     ndiml = inode + *n;
+   24284           0 :     ndimr = ndiml + *n;
+   24285           0 :     idxq = ndimr + *n;
+   24286           0 :     iwk = idxq + *n;
+   24287             : 
+   24288           0 :     ncc = 0;
+   24289           0 :     nru = 0;
+   24290             : 
+   24291           0 :     smlszp = *smlsiz + 1;
+   24292             :     vf = 1;
+   24293           0 :     vl = vf + m;
+   24294           0 :     nwork1 = vl + m;
+   24295           0 :     nwork2 = nwork1 + smlszp * smlszp;
+   24296             : 
+   24297           0 :     PLUMED_BLAS_F77_FUNC(slasdt,SLASDT)(n, &nlvl, &nd, &iwork[inode], &iwork[ndiml], &iwork[ndimr], 
+   24298             :             smlsiz);
+   24299             : 
+   24300           0 :     ndb1 = (nd + 1) / 2;
+   24301             :     i__1 = nd;
+   24302           0 :     for (i__ = ndb1; i__ <= i__1; ++i__) {
+   24303           0 :         i1 = i__ - 1;
+   24304           0 :         ic = iwork[inode + i1];
+   24305           0 :         nl = iwork[ndiml + i1];
+   24306           0 :         nlp1 = nl + 1;
+   24307           0 :         nr = iwork[ndimr + i1];
+   24308           0 :         nlf = ic - nl;
+   24309           0 :         nrf = ic + 1;
+   24310           0 :         idxqi = idxq + nlf - 2;
+   24311             :         vfi = vf + nlf - 1;
+   24312           0 :         vli = vl + nlf - 1;
+   24313           0 :         sqrei = 1;
+   24314           0 :         if (*icompq == 0) {
+   24315           0 :             PLUMED_BLAS_F77_FUNC(slaset,SLASET)("A", &nlp1, &nlp1, &zero, &one, &work[nwork1], &smlszp);
+   24316           0 :             PLUMED_BLAS_F77_FUNC(slasdq,SLASDQ)("U", &sqrei, &nl, &nlp1, &nru, &ncc, &d__[nlf], &e[nlf], &
+   24317             :                     work[nwork1], &smlszp, &work[nwork2], &nl, &work[nwork2], 
+   24318           0 :                     &nl, &work[nwork2], info);
+   24319           0 :             itemp = nwork1 + nl * smlszp;
+   24320           0 :             PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&nlp1, &work[nwork1], &c__1, &work[vfi], &c__1);
+   24321           0 :             PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&nlp1, &work[itemp], &c__1, &work[vli], &c__1);
+   24322             :         } else {
+   24323           0 :             PLUMED_BLAS_F77_FUNC(slaset,SLASET)("A", &nl, &nl, &zero, &one, &u[nlf + u_dim1], ldu);
+   24324           0 :             PLUMED_BLAS_F77_FUNC(slaset,SLASET)("A", &nlp1, &nlp1, &zero, &one, &vt[nlf + vt_dim1], 
+   24325             :                     ldu);
+   24326           0 :             PLUMED_BLAS_F77_FUNC(slasdq,SLASDQ)("U", &sqrei, &nl, &nlp1, &nl, &ncc, &d__[nlf], &e[nlf], &
+   24327             :                     vt[nlf + vt_dim1], ldu, &u[nlf + u_dim1], ldu, &u[nlf + 
+   24328           0 :                     u_dim1], ldu, &work[nwork1], info);
+   24329           0 :             PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&nlp1, &vt[nlf + vt_dim1], &c__1, &work[vfi], &c__1);
+   24330           0 :             PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&nlp1, &vt[nlf + nlp1 * vt_dim1], &c__1, &work[vli], &c__1)
+   24331             :                     ;
+   24332             :         }
+   24333           0 :         if (*info != 0) {
+   24334             :             return;
+   24335             :         }
+   24336           0 :         i__2 = nl;
+   24337           0 :         for (j = 1; j <= i__2; ++j) {
+   24338           0 :             iwork[idxqi + j] = j;
+   24339             :         }
+   24340           0 :         if (i__ == nd && *sqre == 0) {
+   24341           0 :             sqrei = 0;
+   24342             :         } else {
+   24343           0 :             sqrei = 1;
+   24344             :         }
+   24345           0 :         idxqi += nlp1;
+   24346           0 :         vfi += nlp1;
+   24347           0 :         vli += nlp1;
+   24348           0 :         nrp1 = nr + sqrei;
+   24349           0 :         if (*icompq == 0) {
+   24350           0 :             PLUMED_BLAS_F77_FUNC(slaset,SLASET)("A", &nrp1, &nrp1, &zero, &one, &work[nwork1], &smlszp);
+   24351           0 :             PLUMED_BLAS_F77_FUNC(slasdq,SLASDQ)("U", &sqrei, &nr, &nrp1, &nru, &ncc, &d__[nrf], &e[nrf], &
+   24352             :                     work[nwork1], &smlszp, &work[nwork2], &nr, &work[nwork2], 
+   24353           0 :                     &nr, &work[nwork2], info);
+   24354           0 :             itemp = nwork1 + (nrp1 - 1) * smlszp;
+   24355           0 :             PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&nrp1, &work[nwork1], &c__1, &work[vfi], &c__1);
+   24356           0 :             PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&nrp1, &work[itemp], &c__1, &work[vli], &c__1);
+   24357             :         } else {
+   24358           0 :             PLUMED_BLAS_F77_FUNC(slaset,SLASET)("A", &nr, &nr, &zero, &one, &u[nrf + u_dim1], ldu);
+   24359           0 :             PLUMED_BLAS_F77_FUNC(slaset,SLASET)("A", &nrp1, &nrp1, &zero, &one, &vt[nrf + vt_dim1], 
+   24360             :                     ldu);
+   24361           0 :             PLUMED_BLAS_F77_FUNC(slasdq,SLASDQ)("U", &sqrei, &nr, &nrp1, &nr, &ncc, &d__[nrf], &e[nrf], &
+   24362             :                     vt[nrf + vt_dim1], ldu, &u[nrf + u_dim1], ldu, &u[nrf + 
+   24363           0 :                     u_dim1], ldu, &work[nwork1], info);
+   24364           0 :             PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&nrp1, &vt[nrf + vt_dim1], &c__1, &work[vfi], &c__1);
+   24365           0 :             PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&nrp1, &vt[nrf + nrp1 * vt_dim1], &c__1, &work[vli], &c__1)
+   24366             :                     ;
+   24367             :         }
+   24368           0 :         if (*info != 0) {
+   24369             :             return;
+   24370             :         }
+   24371           0 :         i__2 = nr;
+   24372           0 :         for (j = 1; j <= i__2; ++j) {
+   24373           0 :             iwork[idxqi + j] = j;
+   24374             :         }
+   24375             :     }
+   24376             : 
+   24377           0 :     j = (1 << nlvl);
+   24378             : 
+   24379           0 :     for (lvl = nlvl; lvl >= 1; --lvl) {
+   24380           0 :         lvl2 = (lvl << 1) - 1;
+   24381             : 
+   24382           0 :         if (lvl == 1) {
+   24383             :             lf = 1;
+   24384             :             ll = 1;
+   24385             :         } else {
+   24386           0 :             lf = (1 << (lvl-1));
+   24387           0 :             ll = (lf << 1) - 1;
+   24388             :         }
+   24389             :         i__1 = ll;
+   24390           0 :         for (i__ = lf; i__ <= i__1; ++i__) {
+   24391           0 :             im1 = i__ - 1;
+   24392           0 :             ic = iwork[inode + im1];
+   24393           0 :             nl = iwork[ndiml + im1];
+   24394           0 :             nr = iwork[ndimr + im1];
+   24395           0 :             nlf = ic - nl;
+   24396           0 :             if (i__ == ll) {
+   24397           0 :                 sqrei = *sqre;
+   24398             :             } else {
+   24399           0 :                 sqrei = 1;
+   24400             :             }
+   24401             :             vfi = vf + nlf - 1;
+   24402           0 :             vli = vl + nlf - 1;
+   24403           0 :             idxqi = idxq + nlf - 1;
+   24404           0 :             alpha = d__[ic];
+   24405           0 :             beta = e[ic];
+   24406           0 :             if (*icompq == 0) {
+   24407           0 :                 PLUMED_BLAS_F77_FUNC(slasd6,SLASD6)(icompq, &nl, &nr, &sqrei, &d__[nlf], &work[vfi], &
+   24408           0 :                         work[vli], &alpha, &beta, &iwork[idxqi], &perm[
+   24409             :                         perm_offset], &givptr[1], &givcol[givcol_offset], 
+   24410             :                         ldgcol, &givnum[givnum_offset], ldu, &poles[
+   24411             :                         poles_offset], &difl[difl_offset], &difr[difr_offset],
+   24412           0 :                          &z__[z_offset], &k[1], &c__[1], &s[1], &work[nwork1],
+   24413           0 :                          &iwork[iwk], info);
+   24414             :             } else {
+   24415           0 :                 --j;
+   24416           0 :                 PLUMED_BLAS_F77_FUNC(slasd6,SLASD6)(icompq, &nl, &nr, &sqrei, &d__[nlf], &work[vfi], &
+   24417           0 :                         work[vli], &alpha, &beta, &iwork[idxqi], &perm[nlf + 
+   24418           0 :                         lvl * perm_dim1], &givptr[j], &givcol[nlf + lvl2 * 
+   24419             :                         givcol_dim1], ldgcol, &givnum[nlf + lvl2 * 
+   24420             :                         givnum_dim1], ldu, &poles[nlf + lvl2 * poles_dim1], &
+   24421           0 :                         difl[nlf + lvl * difl_dim1], &difr[nlf + lvl2 * 
+   24422           0 :                         difr_dim1], &z__[nlf + lvl * z_dim1], &k[j], &c__[j], 
+   24423           0 :                         &s[j], &work[nwork1], &iwork[iwk], info);
+   24424             :             }
+   24425           0 :             if (*info != 0) {
+   24426             :                 return;
+   24427             :             }
+   24428             :         }
+   24429             :     }
+   24430             : 
+   24431             :     return;
+   24432             : 
+   24433             : }
+   24434             : 
+   24435             : 
+   24436             : }
+   24437             : }
+   24438             : #include <cctype>
+   24439             : 
+   24440             : #include "blas/blas.h"
+   24441             : #include "lapack.h"
+   24442             : 
+   24443             : 
+   24444             : #include "blas/blas.h"
+   24445             : namespace PLMD{
+   24446             : namespace lapack{
+   24447             : using namespace blas;
+   24448             : void 
+   24449           0 : PLUMED_BLAS_F77_FUNC(slasdq,SLASDQ)(const char *uplo,
+   24450             :                         int *sqre,
+   24451             :                         int *n,
+   24452             :                         int *ncvt,
+   24453             :                         int *nru,
+   24454             :                         int *ncc,
+   24455             :                         float *d__,
+   24456             :                         float *e, 
+   24457             :                         float *vt, 
+   24458             :                         int *ldvt, 
+   24459             :                         float *u,
+   24460             :                         int *ldu, 
+   24461             :                         float *c__,
+   24462             :                         int *ldc,
+   24463             :                         float *work, 
+   24464             :                         int *info)
+   24465             : {
+   24466           0 :     const char xuplo=std::toupper(*uplo);
+   24467             :     int c_dim1, c_offset, u_dim1, u_offset, vt_dim1, vt_offset, i__1, 
+   24468             :             i__2;
+   24469           0 :     int c__1 = 1;
+   24470             :     int itmp1,itmp2;
+   24471             :     int i__, j;
+   24472             :     float r__, cs, sn;
+   24473             :     int np1, isub;
+   24474             :     float smin;
+   24475             :     int sqre1;
+   24476             :     int iuplo;
+   24477             :     int rotate;
+   24478             : 
+   24479           0 :     --d__;
+   24480           0 :     --e;
+   24481           0 :     vt_dim1 = *ldvt;
+   24482           0 :     vt_offset = 1 + vt_dim1;
+   24483           0 :     vt -= vt_offset;
+   24484           0 :     u_dim1 = *ldu;
+   24485           0 :     u_offset = 1 + u_dim1;
+   24486           0 :     u -= u_offset;
+   24487           0 :     c_dim1 = *ldc;
+   24488           0 :     c_offset = 1 + c_dim1;
+   24489           0 :     c__ -= c_offset;
+   24490           0 :     --work;
+   24491             : 
+   24492           0 :     *info = 0;
+   24493             :     iuplo = 0;
+   24494           0 :     if (xuplo == 'U') {
+   24495             :         iuplo = 1;
+   24496             :     }
+   24497           0 :     if (xuplo == 'L') {
+   24498             :         iuplo = 2;
+   24499             :     }
+   24500             :     
+   24501           0 :     itmp1 = (*n > 1) ? *n : 1;
+   24502           0 :     itmp2 = (*nru > 1) ? *nru : 1;
+   24503           0 :     if (iuplo == 0) {
+   24504           0 :         *info = -1;
+   24505           0 :     } else if (*sqre < 0 || *sqre > 1) {
+   24506           0 :         *info = -2;
+   24507           0 :     } else if (*n < 0) {
+   24508           0 :         *info = -3;
+   24509           0 :     } else if (*ncvt < 0) {
+   24510           0 :         *info = -4;
+   24511           0 :     } else if (*nru < 0) {
+   24512           0 :         *info = -5;
+   24513           0 :     } else if (*ncc < 0) {
+   24514           0 :         *info = -6;
+   24515           0 :     } else if ( (*ncvt == 0 && *ldvt < 1) || (*ncvt > 0 && *ldvt < itmp1)) {
+   24516           0 :         *info = -10;
+   24517           0 :     } else if (*ldu < itmp2) {
+   24518           0 :         *info = -12;
+   24519           0 :     } else if ((*ncc == 0 && *ldc < 1) || (*ncc > 0 && *ldc < itmp1)) {
+   24520           0 :         *info = -14;
+   24521             :     }
+   24522           0 :     if (*info != 0) {
+   24523             :         return;
+   24524             :     }
+   24525           0 :     if (*n == 0) {
+   24526             :         return;
+   24527             :     }
+   24528             : 
+   24529           0 :     rotate = *ncvt > 0 || *nru > 0 || *ncc > 0;
+   24530           0 :     np1 = *n + 1;
+   24531           0 :     sqre1 = *sqre;
+   24532             : 
+   24533           0 :     if (iuplo == 1 && sqre1 == 1) {
+   24534             :         i__1 = *n - 1;
+   24535           0 :         for (i__ = 1; i__ <= i__1; ++i__) {
+   24536           0 :             PLUMED_BLAS_F77_FUNC(slartg,SLARTG)(&d__[i__], &e[i__], &cs, &sn, &r__);
+   24537           0 :             d__[i__] = r__;
+   24538           0 :             e[i__] = sn * d__[i__ + 1];
+   24539           0 :             d__[i__ + 1] = cs * d__[i__ + 1];
+   24540           0 :             if (rotate) {
+   24541           0 :                 work[i__] = cs;
+   24542           0 :                 work[*n + i__] = sn;
+   24543             :             }
+   24544             :         }
+   24545           0 :         PLUMED_BLAS_F77_FUNC(slartg,SLARTG)(&d__[*n], &e[*n], &cs, &sn, &r__);
+   24546           0 :         d__[*n] = r__;
+   24547           0 :         e[*n] = 0.f;
+   24548           0 :         if (rotate) {
+   24549           0 :             work[*n] = cs;
+   24550           0 :             work[*n + *n] = sn;
+   24551             :         }
+   24552             :         iuplo = 2;
+   24553             :         sqre1 = 0;
+   24554             : 
+   24555           0 :         if (*ncvt > 0) {
+   24556           0 :             PLUMED_BLAS_F77_FUNC(slasr,SLASR)("L", "V", "F", &np1, ncvt, &work[1], &work[np1], &vt[
+   24557             :                     vt_offset], ldvt);
+   24558             :         }
+   24559             :     }
+   24560           0 :     if (iuplo == 2) {
+   24561           0 :         i__1 = *n - 1;
+   24562           0 :         for (i__ = 1; i__ <= i__1; ++i__) {
+   24563           0 :             PLUMED_BLAS_F77_FUNC(slartg,SLARTG)(&d__[i__], &e[i__], &cs, &sn, &r__);
+   24564           0 :             d__[i__] = r__;
+   24565           0 :             e[i__] = sn * d__[i__ + 1];
+   24566           0 :             d__[i__ + 1] = cs * d__[i__ + 1];
+   24567           0 :             if (rotate) {
+   24568           0 :                 work[i__] = cs;
+   24569           0 :                 work[*n + i__] = sn;
+   24570             :             }
+   24571             :         }
+   24572             : 
+   24573           0 :         if (sqre1 == 1) {
+   24574           0 :             PLUMED_BLAS_F77_FUNC(slartg,SLARTG)(&d__[*n], &e[*n], &cs, &sn, &r__);
+   24575           0 :             d__[*n] = r__;
+   24576           0 :             if (rotate) {
+   24577           0 :                 work[*n] = cs;
+   24578           0 :                 work[*n + *n] = sn;
+   24579             :             }
+   24580             :         }
+   24581           0 :         if (*nru > 0) {
+   24582           0 :             if (sqre1 == 0) {
+   24583           0 :                 PLUMED_BLAS_F77_FUNC(slasr,SLASR)("R", "V", "F", nru, n, &work[1], &work[np1], &u[
+   24584             :                         u_offset], ldu);
+   24585             :             } else {
+   24586           0 :                 PLUMED_BLAS_F77_FUNC(slasr,SLASR)("R", "V", "F", nru, &np1, &work[1], &work[np1], &u[
+   24587             :                         u_offset], ldu);
+   24588             :             }
+   24589             :         }
+   24590           0 :         if (*ncc > 0) {
+   24591           0 :             if (sqre1 == 0) {
+   24592           0 :                 PLUMED_BLAS_F77_FUNC(slasr,SLASR)("L", "V", "F", n, ncc, &work[1], &work[np1], &c__[
+   24593             :                         c_offset], ldc);
+   24594             :             } else {
+   24595           0 :                 PLUMED_BLAS_F77_FUNC(slasr,SLASR)("L", "V", "F", &np1, ncc, &work[1], &work[np1], &c__[
+   24596             :                         c_offset], ldc);
+   24597             :             }
+   24598             :         }
+   24599             :     }
+   24600             : 
+   24601           0 :     PLUMED_BLAS_F77_FUNC(sbdsqr,SBDSQR)("U", n, ncvt, nru, ncc, &d__[1], &e[1], &vt[vt_offset], ldvt, &u[
+   24602             :             u_offset], ldu, &c__[c_offset], ldc, &work[1], info);
+   24603             : 
+   24604           0 :     i__1 = *n;
+   24605           0 :     for (i__ = 1; i__ <= i__1; ++i__) {
+   24606             : 
+   24607             :         isub = i__;
+   24608           0 :         smin = d__[i__];
+   24609           0 :         i__2 = *n;
+   24610           0 :         for (j = i__ + 1; j <= i__2; ++j) {
+   24611           0 :             if (d__[j] < smin) {
+   24612             :                 isub = j;
+   24613             :                 smin = d__[j];
+   24614             :             }
+   24615             :         }
+   24616           0 :         if (isub != i__) {
+   24617           0 :             d__[isub] = d__[i__];
+   24618           0 :             d__[i__] = smin;
+   24619           0 :             if (*ncvt > 0) {
+   24620           0 :                 PLUMED_BLAS_F77_FUNC(sswap,SSWAP)(ncvt, &vt[isub + vt_dim1], ldvt, &vt[i__ + vt_dim1], 
+   24621             :                         ldvt);
+   24622             :             }
+   24623           0 :             if (*nru > 0) {
+   24624           0 :                 PLUMED_BLAS_F77_FUNC(sswap,SSWAP)(nru, &u[isub * u_dim1 + 1], &c__1, &u[i__ * u_dim1 + 1]
+   24625             :                         , &c__1);
+   24626             :             }
+   24627           0 :             if (*ncc > 0) {
+   24628           0 :                 PLUMED_BLAS_F77_FUNC(sswap,SSWAP)(ncc, &c__[isub + c_dim1], ldc, &c__[i__ + c_dim1], ldc)
+   24629             :                         ;
+   24630             :             }
+   24631             :         }
+   24632             :     }
+   24633             : 
+   24634             :     return;
+   24635             : }
+   24636             : 
+   24637             : 
+   24638             : }
+   24639             : }
+   24640             : #include <cmath>
+   24641             : #include "lapack.h"
+   24642             : 
+   24643             : #include "blas/blas.h"
+   24644             : namespace PLMD{
+   24645             : namespace lapack{
+   24646             : using namespace blas;
+   24647             : void
+   24648           0 : PLUMED_BLAS_F77_FUNC(slasdt,SLASDT)(int *n,
+   24649             :         int *lvl,
+   24650             :         int *nd,
+   24651             :         int *inode,
+   24652             :         int *ndiml,
+   24653             :         int *ndimr,
+   24654             :         int *msub)
+   24655             : {
+   24656           0 :   int maxn = (*n > 1) ? *n : 1;
+   24657             :   float temp;
+   24658             :   int i,il,ir,llst,nlvl,ncrnt;
+   24659             : 
+   24660           0 :   temp = std::log( ((float) maxn) / ((float)(*msub+1))) / std::log(2.0);
+   24661             :   
+   24662           0 :   *lvl = 1 + (int) temp;
+   24663             : 
+   24664           0 :   i = *n / 2;
+   24665           0 :   inode[0] = i + 1;
+   24666           0 :   ndiml[0] = i;
+   24667           0 :   ndimr[0] = *n - i - 1;
+   24668             :   il = -1;
+   24669             :   ir = 0;
+   24670             :   llst = 1;
+   24671             : 
+   24672           0 :   for(nlvl=1;nlvl<*lvl;nlvl++) {
+   24673           0 :     for(i=0;i<llst;i++) {
+   24674           0 :       il += 2;
+   24675           0 :       ir += 2;
+   24676           0 :       ncrnt = llst + i - 1;
+   24677           0 :       ndiml[il] = ndiml[ncrnt] / 2;
+   24678           0 :       ndimr[il] = ndiml[ncrnt] - ndiml[il] - 1;
+   24679           0 :       inode[il] = inode[ncrnt] - ndimr[il] - 1;
+   24680           0 :       ndiml[ir] = ndimr[ncrnt] / 2;
+   24681           0 :       ndimr[ir] = ndimr[ncrnt] - ndiml[ir] - 1;
+   24682           0 :       inode[ir] = inode[ncrnt] + ndiml[ir] + 1;
+   24683             :     }
+   24684           0 :     llst *= 2;
+   24685             :   }
+   24686           0 :   *nd = llst*2 - 1;
+   24687           0 :   return;
+   24688             : }
+   24689             : }
+   24690             : }
+   24691             : #include <cctype>
+   24692             : #include "lapack.h"
+   24693             : 
+   24694             : 
+   24695             : #include "blas/blas.h"
+   24696             : namespace PLMD{
+   24697             : namespace lapack{
+   24698             : using namespace blas;
+   24699             : void
+   24700           0 : PLUMED_BLAS_F77_FUNC(slaset,SLASET)(const char *uplo,
+   24701             :         int *m,
+   24702             :         int *n,
+   24703             :         float *alpha,
+   24704             :         float *beta,
+   24705             :         float *a,
+   24706             :         int *lda)
+   24707             : {
+   24708             :   int i,j,k;
+   24709           0 :   const char ch=std::toupper(*uplo);
+   24710             : 
+   24711           0 :   if(ch=='U') {
+   24712           0 :     for(j=1;j<*n;j++) {
+   24713           0 :       k = (j < *m) ? j : *m;
+   24714           0 :       for(i=0;i<k;i++)
+   24715           0 :         a[j*(*lda)+i] = *alpha;
+   24716             :     }
+   24717           0 :   } else if(ch=='L') {
+   24718           0 :     k = (*m < *n) ? *m : *n;
+   24719           0 :     for(j=0;j<k;j++) {
+   24720           0 :       for(i=j+1;i<*m;i++)
+   24721           0 :         a[j*(*lda)+i] = *alpha;
+   24722             :     }
+   24723             :   } else {
+   24724           0 :     for(j=0;j<*n;j++) {
+   24725           0 :       for(i=0;i<*m;i++)
+   24726           0 :         a[j*(*lda)+i] = *alpha;
+   24727             :     }    
+   24728             :   }
+   24729             : 
+   24730           0 :   k = (*m < *n) ? *m : *n;
+   24731           0 :   for(i=0;i<k;i++)
+   24732           0 :     a[i*(*lda)+i] = *beta;
+   24733           0 : }
+   24734             : }
+   24735             : }
+   24736             : #include <cmath>
+   24737             : #include "blas/blas.h"
+   24738             : #include "lapack.h"
+   24739             : #include "lapack_limits.h"
+   24740             : 
+   24741             : #include "real.h"
+   24742             : 
+   24743             : #include "blas/blas.h"
+   24744             : namespace PLMD{
+   24745             : namespace lapack{
+   24746             : using namespace blas;
+   24747             : void
+   24748           0 : PLUMED_BLAS_F77_FUNC(slasq1,SLASQ1)(int *n,
+   24749             :         float *d,
+   24750             :         float *e,
+   24751             :         float *work,
+   24752             :         int *info)
+   24753             : {
+   24754           0 :   float sigmx = 0.0;
+   24755             :   int i,j,k,iinfo;
+   24756             :   float minval,safemin;
+   24757             :   float dtemp,scale;
+   24758             :   float eps;
+   24759             : 
+   24760             :   eps = PLUMED_GMX_FLOAT_EPS;
+   24761             :   minval = PLUMED_GMX_FLOAT_MIN;
+   24762             :   safemin = minval*(1.0+PLUMED_GMX_FLOAT_EPS);
+   24763           0 :   *info = 0;
+   24764             : 
+   24765           0 :   if(*n<0) {
+   24766           0 :     *info = -2;
+   24767           0 :     return;
+   24768             :   }
+   24769             :   
+   24770           0 :   for(i=0;i<*n-1;i++) {
+   24771           0 :     d[i] = std::abs(d[i]);
+   24772           0 :     dtemp = std::abs(e[i]);
+   24773           0 :     if(dtemp>sigmx)
+   24774           0 :       sigmx=dtemp;
+   24775             :   }
+   24776           0 :   d[*n-1] = std::abs(d[*n-1]);
+   24777             :   
+   24778           0 :   if(std::abs(sigmx)<PLUMED_GMX_FLOAT_MIN) {
+   24779           0 :     PLUMED_BLAS_F77_FUNC(slasrt,SLASRT)("D",n,d,&iinfo);
+   24780           0 :     return;
+   24781             :   }
+   24782             : 
+   24783           0 :   for(i=0;i<*n;i++) {
+   24784           0 :     if(d[i]>sigmx)
+   24785           0 :       sigmx=d[i];
+   24786             :   }
+   24787             : 
+   24788             :   /* Copy d and e into work (z format) and scale.
+   24789             :    * Squaring input data makes scaling by a power of the
+   24790             :    * radix pointless.
+   24791             :    */
+   24792           0 :   scale =  std::sqrt(eps/safemin);
+   24793           0 :   i = 1;
+   24794           0 :   j = 2;
+   24795           0 :   PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(n,d,&i,work,&j);
+   24796           0 :   k = *n-1;
+   24797           0 :   PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&k,e,&i,work+1,&j);
+   24798           0 :   i = 0;
+   24799           0 :   j = 2*(*n)-1;
+   24800           0 :   k = 1;
+   24801           0 :   PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G",&i,&i,&sigmx,&scale,&j,&k,work,&j,&iinfo);
+   24802             : 
+   24803             : 
+   24804             :   /* Compute q and e elements */
+   24805           0 :   for(i=0;i<2*(*n)-1;i++)
+   24806           0 :     work[i] = work[i]*work[i];
+   24807             : 
+   24808           0 :   work[2*(*n)-1] = 0.0;
+   24809             : 
+   24810           0 :   PLUMED_BLAS_F77_FUNC(slasq2,SLASQ2)(n,work,info);
+   24811             : 
+   24812           0 :   j = 0;
+   24813           0 :   k = 1;
+   24814           0 :   if(*info==0) {
+   24815           0 :     for(i=0;i<*n;i++)
+   24816           0 :       d[i]= std::sqrt(work[i]);
+   24817           0 :     PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G",&j,&j,&scale,&sigmx,n,&k,d,n,&iinfo);
+   24818             :   }
+   24819             :   return;
+   24820             : }
+   24821             : }
+   24822             : }
+   24823             : #include <cmath>
+   24824             : #include "lapack.h"
+   24825             : #include "lapack_limits.h"
+   24826             : 
+   24827             : #include "real.h"
+   24828             : 
+   24829             : #ifdef _MSC_VER
+   24830             : #pragma warning(disable: 4723) /*division by zero - is used on purpose here*/
+   24831             : #endif
+   24832             : 
+   24833             : #include "blas/blas.h"
+   24834             : namespace PLMD{
+   24835             : namespace lapack{
+   24836             : using namespace blas;
+   24837             : void 
+   24838           0 : PLUMED_BLAS_F77_FUNC(slasq2,SLASQ2)(int *n, 
+   24839             :                         float *z__, 
+   24840             :                         int *info)
+   24841             : {
+   24842             :     int i__1, i__2, i__3;
+   24843             :     float d__1, d__2;
+   24844             : 
+   24845             :     float d__, e;
+   24846             :     int k;
+   24847             :     float s, t;
+   24848             :     int i0, i4, n0, pp;
+   24849             :     float dee, eps, tol;
+   24850             :     int ipn4;
+   24851             :     float tol2;
+   24852             :     int ieee;
+   24853             :     int nbig;
+   24854             :     float dmin__, emin, emax;
+   24855             :     int kmin, ndiv, iter;
+   24856             :     float qmin, temp, qmax, zmax;
+   24857             :     int splt, nfail;
+   24858             :     float desig, trace, sigma;
+   24859             :     int iinfo;
+   24860             :     float deemin;
+   24861             :     int iwhila, iwhilb;
+   24862             :     float oldemn, safmin, minval;
+   24863             :     float posinf,neginf,negzro,newzro;
+   24864             :     float zero = 0.0;
+   24865             :     float one = 1.0;
+   24866             : 
+   24867           0 :     --z__;
+   24868             : 
+   24869           0 :     *info = 0;
+   24870             :     eps = PLUMED_GMX_FLOAT_EPS;
+   24871             :     minval = PLUMED_GMX_FLOAT_MIN;
+   24872             :     safmin = minval*(1.0+eps);
+   24873             : 
+   24874             :     tol = eps * 100.;
+   24875             : 
+   24876             :     d__1 = tol;
+   24877             :     tol2 = d__1 * d__1;
+   24878             : 
+   24879           0 :     if (*n < 0) {
+   24880           0 :         *info = -1;
+   24881           0 :         return;
+   24882           0 :     } else if (*n == 0) {
+   24883             :         return;
+   24884           0 :     } else if (*n == 1) {
+   24885             : 
+   24886           0 :         if (z__[1] < 0.) {
+   24887           0 :             *info = -201;
+   24888             :         }
+   24889           0 :         return;
+   24890           0 :     } else if (*n == 2) {
+   24891             : 
+   24892           0 :         if (z__[2] < 0. || z__[3] < 0.) {
+   24893           0 :             *info = -2;
+   24894           0 :             return;
+   24895           0 :         } else if (z__[3] > z__[1]) {
+   24896             :             d__ = z__[3];
+   24897           0 :             z__[3] = z__[1];
+   24898           0 :             z__[1] = d__;
+   24899             :         }
+   24900           0 :         z__[5] = z__[1] + z__[2] + z__[3];
+   24901           0 :         if (z__[2] > z__[3] * tol2) {
+   24902           0 :             t = (z__[1] - z__[3] + z__[2]) * .5;
+   24903           0 :             s = z__[3] * (z__[2] / t);
+   24904           0 :             if (s <= t) {
+   24905           0 :                 s = z__[3] * (z__[2] / (t * ( std::sqrt(s / t + 1.) + 1.)));
+   24906             :             } else {
+   24907           0 :                 s = z__[3] * (z__[2] / (t +  std::sqrt(t) * std::sqrt(t + s)));
+   24908             :             }
+   24909           0 :             t = z__[1] + (s + z__[2]);
+   24910           0 :             z__[3] *= z__[1] / t;
+   24911           0 :             z__[1] = t;
+   24912             :         }
+   24913           0 :         z__[2] = z__[3];
+   24914           0 :         z__[6] = z__[2] + z__[1];
+   24915           0 :         return;
+   24916             :     }
+   24917           0 :     z__[*n * 2] = 0.;
+   24918           0 :     emin = z__[2];
+   24919           0 :     qmax = 0.;
+   24920             :     zmax = 0.;
+   24921             :     d__ = 0.;
+   24922             :     e = 0.;
+   24923             : 
+   24924           0 :     i__1 = 2*(*n - 1);
+   24925           0 :     for (k = 1; k <= i__1; k += 2) {
+   24926           0 :         if (z__[k] < 0.) {
+   24927           0 :             *info = -(k + 200);
+   24928           0 :             return;
+   24929           0 :         } else if (z__[k + 1] < 0.) {
+   24930           0 :             *info = -(k + 201);
+   24931           0 :             return;
+   24932             :         }
+   24933           0 :         d__ += z__[k];
+   24934           0 :         e += z__[k + 1];
+   24935           0 :         d__1 = qmax, d__2 = z__[k];
+   24936           0 :         qmax = (d__1>d__2) ? d__1 : d__2;
+   24937             :         d__1 = emin, d__2 = z__[k + 1];
+   24938           0 :         emin = (d__1<d__2) ? d__1 : d__2;
+   24939           0 :         d__1 = (qmax>zmax) ? qmax : zmax;
+   24940             :         d__2 = z__[k + 1];
+   24941           0 :         zmax = (d__1>d__2) ? d__1 : d__2;
+   24942             :     }
+   24943           0 :     if (z__[(*n << 1) - 1] < 0.) {
+   24944           0 :         *info = -((*n << 1) + 199);
+   24945           0 :         return;
+   24946             :     }
+   24947           0 :     d__ += z__[(*n << 1) - 1];
+   24948           0 :     d__1 = qmax, d__2 = z__[(*n << 1) - 1];
+   24949           0 :     qmax = (d__1>d__2) ? d__1 : d__2;
+   24950             : 
+   24951           0 :     if (std::abs(e)<PLUMED_GMX_FLOAT_MIN) {
+   24952             :         i__1 = *n;
+   24953           0 :         for (k = 2; k <= i__1; ++k) {
+   24954           0 :             z__[k] = z__[(k << 1) - 1];
+   24955             :         }
+   24956           0 :         PLUMED_BLAS_F77_FUNC(slasrt,SLASRT)("D", n, &z__[1], &iinfo);
+   24957           0 :         z__[(*n << 1) - 1] = d__;
+   24958           0 :         return;
+   24959             :     }
+   24960             : 
+   24961           0 :     trace = d__ + e;
+   24962             : 
+   24963           0 :     if (std::abs(trace)<PLUMED_GMX_FLOAT_MIN) {
+   24964           0 :         z__[(*n << 1) - 1] = 0.;
+   24965           0 :         return;
+   24966             :     }
+   24967             : 
+   24968           0 :     ieee = 1;
+   24969           0 :     posinf = one/zero;
+   24970           0 :     if(posinf<=1.0)
+   24971           0 :       ieee = 0;
+   24972             :     neginf = -one/zero;
+   24973           0 :     if(neginf>=0.0)
+   24974           0 :       ieee = 0;
+   24975           0 :     negzro = one/(neginf+one);
+   24976           0 :     if(std::abs(negzro)>PLUMED_GMX_FLOAT_MIN)
+   24977           0 :       ieee = 0;
+   24978           0 :     neginf = one/negzro;
+   24979           0 :     if(neginf>=0)
+   24980           0 :       ieee = 0;
+   24981           0 :     newzro = negzro + zero;
+   24982           0 :     if(std::abs(newzro-zero)>PLUMED_GMX_FLOAT_MIN)
+   24983           0 :       ieee = 0;
+   24984           0 :     posinf = one /newzro;
+   24985           0 :     if(posinf<=one)
+   24986           0 :       ieee = 0;
+   24987           0 :     neginf = neginf*posinf;
+   24988           0 :     if(neginf>=zero)
+   24989           0 :       ieee = 0;
+   24990           0 :     posinf = posinf*posinf;
+   24991           0 :     if(posinf<=1.0)
+   24992           0 :       ieee = 0;
+   24993             : 
+   24994           0 :     for (k = *n << 1; k >= 2; k += -2) {
+   24995           0 :         z__[k * 2] = 0.;
+   24996           0 :         z__[(k << 1) - 1] = z__[k];
+   24997           0 :         z__[(k << 1) - 2] = 0.;
+   24998           0 :         z__[(k << 1) - 3] = z__[k - 1];
+   24999             :     }
+   25000             : 
+   25001           0 :     i0 = 1;
+   25002           0 :     n0 = *n;
+   25003             : 
+   25004           0 :     if (z__[(i0 << 2) - 3] * 1.5 < z__[(n0 << 2) - 3]) {
+   25005           0 :         ipn4 = 4*(i0 + n0);
+   25006           0 :         i__1 = 2*(i0 + n0 - 1);
+   25007           0 :         for (i4 = i0 << 2; i4 <= i__1; i4 += 4) {
+   25008           0 :             temp = z__[i4 - 3];
+   25009           0 :             z__[i4 - 3] = z__[ipn4 - i4 - 3];
+   25010           0 :             z__[ipn4 - i4 - 3] = temp;
+   25011           0 :             temp = z__[i4 - 1];
+   25012           0 :             z__[i4 - 1] = z__[ipn4 - i4 - 5];
+   25013           0 :             z__[ipn4 - i4 - 5] = temp;
+   25014             :         }
+   25015             :     }
+   25016             : 
+   25017           0 :     pp = 0;
+   25018             : 
+   25019           0 :     for (k = 1; k <= 2; ++k) {
+   25020             : 
+   25021           0 :         d__ = z__[(n0 << 2) + pp - 3];
+   25022           0 :         i__1 = (i0 << 2) + pp;
+   25023           0 :         for (i4 = 4*(n0 - 1) + pp; i4 >= i__1; i4 += -4) {
+   25024           0 :             if (z__[i4 - 1] <= tol2 * d__) {
+   25025           0 :                 z__[i4 - 1] = -0.;
+   25026           0 :                 d__ = z__[i4 - 3];
+   25027             :             } else {
+   25028           0 :                 d__ = z__[i4 - 3] * (d__ / (d__ + z__[i4 - 1]));
+   25029             :             }
+   25030             :         }
+   25031             : 
+   25032           0 :         emin = z__[(i0 << 2) + pp + 1];
+   25033           0 :         d__ = z__[(i0 << 2) + pp - 3];
+   25034             :         i__1 = 4*(n0 - 1) + pp;
+   25035           0 :         for (i4 = (i0 << 2) + pp; i4 <= i__1; i4 += 4) {
+   25036           0 :             z__[i4 - (pp << 1) - 2] = d__ + z__[i4 - 1];
+   25037           0 :             if (z__[i4 - 1] <= tol2 * d__) {
+   25038           0 :                 z__[i4 - 1] = -0.;
+   25039           0 :                 z__[i4 - (pp << 1) - 2] = d__;
+   25040           0 :                 z__[i4 - (pp << 1)] = 0.;
+   25041           0 :                 d__ = z__[i4 + 1];
+   25042           0 :             } else if (safmin * z__[i4 + 1] < z__[i4 - (pp << 1) - 2] && 
+   25043           0 :                     safmin * z__[i4 - (pp << 1) - 2] < z__[i4 + 1]) {
+   25044           0 :                 temp = z__[i4 + 1] / z__[i4 - (pp << 1) - 2];
+   25045           0 :                 z__[i4 - (pp << 1)] = z__[i4 - 1] * temp;
+   25046           0 :                 d__ *= temp;
+   25047             :             } else {
+   25048           0 :                 z__[i4 - (pp << 1)] = z__[i4 + 1] * (z__[i4 - 1] / z__[i4 - (
+   25049             :                         pp << 1) - 2]);
+   25050           0 :                 d__ = z__[i4 + 1] * (d__ / z__[i4 - (pp << 1) - 2]);
+   25051             :             }
+   25052           0 :             d__1 = emin, d__2 = z__[i4 - (pp << 1)];
+   25053           0 :             emin = (d__1<d__2) ? d__1 : d__2;
+   25054             :         }
+   25055           0 :         z__[(n0 << 2) - pp - 2] = d__;
+   25056             : 
+   25057             : 
+   25058           0 :         qmax = z__[(i0 << 2) - pp - 2];
+   25059           0 :         i__1 = (n0 << 2) - pp - 2;
+   25060           0 :         for (i4 = (i0 << 2) - pp + 2; i4 <= i__1; i4 += 4) {
+   25061           0 :             d__1 = qmax, d__2 = z__[i4];
+   25062           0 :             qmax = (d__1>d__2) ? d__1 : d__2;
+   25063             :         }
+   25064             : 
+   25065           0 :         pp = 1 - pp;
+   25066             :     }
+   25067             : 
+   25068           0 :     iter = 2;
+   25069           0 :     nfail = 0;
+   25070           0 :     ndiv = 2*(n0 - i0);
+   25071             : 
+   25072           0 :     i__1 = *n + 1;
+   25073           0 :     for (iwhila = 1; iwhila <= i__1; ++iwhila) {
+   25074           0 :         if (n0 < 1) {
+   25075           0 :             goto L170;
+   25076             :         }
+   25077             : 
+   25078           0 :         desig = 0.;
+   25079           0 :         if (n0 == *n) {
+   25080           0 :             sigma = 0.;
+   25081             :         } else {
+   25082           0 :             sigma = -z__[(n0 << 2) - 1];
+   25083             :         }
+   25084           0 :         if (sigma < 0.) {
+   25085           0 :             *info = 1;
+   25086           0 :             return;
+   25087             :         }
+   25088             : 
+   25089             :         emax = 0.;
+   25090           0 :         if (n0 > i0) {
+   25091           0 :             emin = std::abs(z__[(n0 << 2) - 5]);
+   25092             :         } else {
+   25093             :             emin = 0.;
+   25094             :         }
+   25095           0 :         qmin = z__[(n0 << 2) - 3];
+   25096           0 :         qmax = qmin;
+   25097           0 :         for (i4 = n0 << 2; i4 >= 8; i4 += -4) {
+   25098           0 :             if (z__[i4 - 5] <= 0.) {
+   25099           0 :                 goto L100;
+   25100             :             }
+   25101           0 :             if (qmin >= emax * 4.) {
+   25102           0 :                 d__1 = qmin, d__2 = z__[i4 - 3];
+   25103           0 :                 qmin = (d__1<d__2) ? d__1 : d__2;
+   25104             :                 d__1 = emax, d__2 = z__[i4 - 5];
+   25105           0 :                 emax = (d__1>d__2) ? d__1 : d__2;
+   25106             :             }
+   25107           0 :             d__1 = qmax, d__2 = z__[i4 - 7] + z__[i4 - 5];
+   25108           0 :             qmax = (d__1>d__2) ? d__1 : d__2;
+   25109             :             d__1 = emin, d__2 = z__[i4 - 5];
+   25110           0 :             emin = (d__1<d__2) ? d__1 : d__2;
+   25111             :         }
+   25112             :         i4 = 4;
+   25113             : 
+   25114           0 : L100:
+   25115           0 :         i0 = i4 / 4;
+   25116           0 :         pp = 0;
+   25117             : 
+   25118           0 :         if (n0 - i0 > 1) {
+   25119           0 :             dee = z__[(i0 << 2) - 3];
+   25120             :             deemin = dee;
+   25121             :             kmin = i0;
+   25122           0 :             i__2 = (n0 << 2) - 3;
+   25123           0 :             for (i4 = (i0 << 2) - 3; i4 <= i__2; i4 += 4) {
+   25124           0 :                 dee = z__[i4] * (dee / (dee + z__[i4 - 2]));
+   25125           0 :                 if (dee <= deemin) {
+   25126             :                     deemin = dee;
+   25127           0 :                     kmin = (i4 + 3) / 4;
+   25128             :                 }
+   25129             :             }
+   25130           0 :             if (2*(kmin - i0) < n0 - kmin && deemin <= z__[(n0 << 2) - 3] * 
+   25131             :                     .5) {
+   25132           0 :                 ipn4 = 4*(i0 + n0);
+   25133           0 :                 pp = 2;
+   25134           0 :                 i__2 = 2*(i0 + n0 - 1);
+   25135           0 :                 for (i4 = i0 << 2; i4 <= i__2; i4 += 4) {
+   25136           0 :                     temp = z__[i4 - 3];
+   25137           0 :                     z__[i4 - 3] = z__[ipn4 - i4 - 3];
+   25138           0 :                     z__[ipn4 - i4 - 3] = temp;
+   25139           0 :                     temp = z__[i4 - 2];
+   25140           0 :                     z__[i4 - 2] = z__[ipn4 - i4 - 2];
+   25141           0 :                     z__[ipn4 - i4 - 2] = temp;
+   25142           0 :                     temp = z__[i4 - 1];
+   25143           0 :                     z__[i4 - 1] = z__[ipn4 - i4 - 5];
+   25144           0 :                     z__[ipn4 - i4 - 5] = temp;
+   25145           0 :                     temp = z__[i4];
+   25146           0 :                     z__[i4] = z__[ipn4 - i4 - 4];
+   25147           0 :                     z__[ipn4 - i4 - 4] = temp;
+   25148             :                 }
+   25149             :             }
+   25150             :         }
+   25151             : 
+   25152             : 
+   25153           0 :         d__1 = 0., d__2 = qmin -  std::sqrt(qmin) * 2. * std::sqrt(emax);
+   25154           0 :         dmin__ = -((d__1>d__2) ? d__1 : d__2);
+   25155             : 
+   25156           0 :         nbig = (n0 - i0 + 1) * 30;
+   25157             :         i__2 = nbig;
+   25158           0 :         for (iwhilb = 1; iwhilb <= i__2; ++iwhilb) {
+   25159           0 :             if (i0 > n0) {
+   25160           0 :                 goto L150;
+   25161             :             }
+   25162             : 
+   25163           0 :             PLUMED_BLAS_F77_FUNC(slasq3,SLASQ3)(&i0, &n0, &z__[1], &pp, &dmin__, &sigma, &desig, &qmax, &
+   25164             :                     nfail, &iter, &ndiv, &ieee);
+   25165             : 
+   25166           0 :             pp = 1 - pp;
+   25167             : 
+   25168           0 :             if (pp == 0 && n0 - i0 >= 3) {
+   25169           0 :                 if (z__[n0 * 4] <= tol2 * qmax || z__[(n0 << 2) - 1] <= tol2 *
+   25170             :                          sigma) {
+   25171           0 :                     splt = i0 - 1;
+   25172           0 :                     qmax = z__[(i0 << 2) - 3];
+   25173           0 :                     emin = z__[(i0 << 2) - 1];
+   25174           0 :                     oldemn = z__[i0 * 4];
+   25175           0 :                     i__3 = 4*(n0 - 3);
+   25176           0 :                     for (i4 = i0 << 2; i4 <= i__3; i4 += 4) {
+   25177           0 :                         if (z__[i4] <= tol2 * z__[i4 - 3] || z__[i4 - 1] <= 
+   25178           0 :                                 tol2 * sigma) {
+   25179           0 :                             z__[i4 - 1] = -sigma;
+   25180           0 :                             splt = i4 / 4;
+   25181           0 :                             qmax = 0.;
+   25182           0 :                             emin = z__[i4 + 3];
+   25183           0 :                             oldemn = z__[i4 + 4];
+   25184             :                         } else {
+   25185           0 :                             d__1 = qmax, d__2 = z__[i4 + 1];
+   25186           0 :                             qmax = (d__1>d__2) ? d__1 : d__2;
+   25187             :                             d__1 = emin, d__2 = z__[i4 - 1];
+   25188           0 :                             emin = (d__1<d__2) ? d__1 : d__2;
+   25189             :                             d__1 = oldemn, d__2 = z__[i4];
+   25190           0 :                             oldemn = (d__1<d__2) ? d__1 : d__2;
+   25191             :                         }
+   25192             :                     }
+   25193           0 :                     z__[(n0 << 2) - 1] = emin;
+   25194           0 :                     z__[n0 * 4] = oldemn;
+   25195           0 :                     i0 = splt + 1;
+   25196             :                 }
+   25197             :             }
+   25198             :         }
+   25199             : 
+   25200           0 :         *info = 2;
+   25201           0 :         return;
+   25202             : 
+   25203             : L150:
+   25204             :         ;
+   25205             :     }
+   25206             : 
+   25207           0 :     *info = 3;
+   25208           0 :     return;
+   25209             : 
+   25210             : 
+   25211             : L170:
+   25212             : 
+   25213           0 :     i__1 = *n;
+   25214           0 :     for (k = 2; k <= i__1; ++k) {
+   25215           0 :         z__[k] = z__[(k << 2) - 3];
+   25216             :     }
+   25217             : 
+   25218           0 :     PLUMED_BLAS_F77_FUNC(slasrt,SLASRT)("D", n, &z__[1], &iinfo);
+   25219             : 
+   25220             :     e = 0.;
+   25221           0 :     for (k = *n; k >= 1; --k) {
+   25222           0 :         e += z__[k];
+   25223             :     }
+   25224             : 
+   25225             : 
+   25226           0 :     z__[(*n << 1) + 1] = trace;
+   25227           0 :     z__[(*n << 1) + 2] = e;
+   25228           0 :     z__[(*n << 1) + 3] = (float) iter;
+   25229           0 :     i__1 = *n;
+   25230           0 :     z__[(*n << 1) + 4] = (float) ndiv / (float) (i__1 * i__1);
+   25231           0 :     z__[(*n << 1) + 5] = nfail * 100. / (float) iter;
+   25232             : 
+   25233           0 :     return;
+   25234             : 
+   25235             : }
+   25236             : 
+   25237             : 
+   25238             : 
+   25239             : }
+   25240             : }
+   25241             : #include <cmath>
+   25242             : #include "real.h"
+   25243             : 
+   25244             : #include "lapack.h"
+   25245             : #include "lapack_limits.h"
+   25246             : 
+   25247             : #include "blas/blas.h"
+   25248             : namespace PLMD{
+   25249             : namespace lapack{
+   25250             : using namespace blas;
+   25251             : void
+   25252           0 : PLUMED_BLAS_F77_FUNC(slasq3,SLASQ3)(int *i0, 
+   25253             :                         int *n0, 
+   25254             :                         float *z__, 
+   25255             :                         int *pp, 
+   25256             :                         float *dmin__, 
+   25257             :                         float *sigma,
+   25258             :                         float *desig,
+   25259             :                         float *qmax, 
+   25260             :                         int *nfail, 
+   25261             :                         int *iter, 
+   25262             :                         int *ndiv, 
+   25263             :         int *ieee)
+   25264             : {
+   25265             : 
+   25266           0 :     int ttype = 0;
+   25267           0 :     float dmin1 = 0.;
+   25268           0 :     float dmin2 = 0.;
+   25269           0 :     float dn = 0.;
+   25270           0 :     float dn1 = 0.;
+   25271           0 :     float dn2 = 0.;
+   25272           0 :     float tau = 0.;
+   25273             : 
+   25274             :     int i__1;
+   25275             :     float d__1, d__2;
+   25276             :     float s, t;
+   25277             :     int j4, nn;
+   25278             :     float eps, tol;
+   25279             :     int n0in, ipn4;
+   25280             :     float tol2, temp;
+   25281           0 :     --z__;
+   25282             : 
+   25283           0 :     n0in = *n0;
+   25284             :     eps = PLUMED_GMX_FLOAT_EPS;
+   25285             :     tol = eps * 100.;
+   25286             :     d__1 = tol;
+   25287             :     tol2 = d__1 * d__1;
+   25288             : 
+   25289             : 
+   25290           0 : L10:
+   25291             : 
+   25292           0 :     if (*n0 < *i0) {
+   25293             :         return;
+   25294             :     }
+   25295           0 :     if (*n0 == *i0) {
+   25296           0 :         goto L20;
+   25297             :     }
+   25298           0 :     nn = (*n0 << 2) + *pp;
+   25299           0 :     if (*n0 == *i0 + 1) {
+   25300           0 :         goto L40;
+   25301             :     }
+   25302             : 
+   25303           0 :     if (z__[nn - 5] > tol2 * (*sigma + z__[nn - 3]) && z__[nn - (*pp << 1) - 
+   25304           0 :             4] > tol2 * z__[nn - 7]) {
+   25305           0 :         goto L30;
+   25306             :     }
+   25307             : 
+   25308           0 : L20:
+   25309             : 
+   25310           0 :     z__[(*n0 << 2) - 3] = z__[(*n0 << 2) + *pp - 3] + *sigma;
+   25311           0 :     --(*n0);
+   25312           0 :     goto L10;
+   25313             : 
+   25314             : L30:
+   25315             : 
+   25316           0 :     if (z__[nn - 9] > tol2 * *sigma && z__[nn - (*pp << 1) - 8] > tol2 * z__[
+   25317           0 :             nn - 11]) {
+   25318           0 :         goto L50;
+   25319             :     }
+   25320             : 
+   25321           0 : L40:
+   25322             : 
+   25323           0 :     if (z__[nn - 3] > z__[nn - 7]) {
+   25324             :         s = z__[nn - 3];
+   25325           0 :         z__[nn - 3] = z__[nn - 7];
+   25326           0 :         z__[nn - 7] = s;
+   25327             :     }
+   25328           0 :     if (z__[nn - 5] > z__[nn - 3] * tol2) {
+   25329           0 :         t = (z__[nn - 7] - z__[nn - 3] + z__[nn - 5]) * .5;
+   25330           0 :         s = z__[nn - 3] * (z__[nn - 5] / t);
+   25331           0 :         if (s <= t) {
+   25332           0 :             s = z__[nn - 3] * (z__[nn - 5] / (t * ( std::sqrt(s / t + 1.) + 1.)));
+   25333             :         } else {
+   25334           0 :             s = z__[nn - 3] * (z__[nn - 5] / (t +  std::sqrt(t) * std::sqrt(t + s)));
+   25335             :         }
+   25336           0 :         t = z__[nn - 7] + (s + z__[nn - 5]);
+   25337           0 :         z__[nn - 3] *= z__[nn - 7] / t;
+   25338           0 :         z__[nn - 7] = t;
+   25339             :     }
+   25340           0 :     z__[(*n0 << 2) - 7] = z__[nn - 7] + *sigma;
+   25341           0 :     z__[(*n0 << 2) - 3] = z__[nn - 3] + *sigma;
+   25342           0 :     *n0 += -2;
+   25343           0 :     goto L10;
+   25344             : 
+   25345             : L50:
+   25346           0 :     if (*pp == 2) {
+   25347           0 :         *pp = 0;
+   25348             :     }
+   25349             : 
+   25350           0 :     if (*dmin__ <= 0. || *n0 < n0in) {
+   25351           0 :         if (z__[(*i0 << 2) + *pp - 3] * 1.5 < z__[(*n0 << 2) + *pp - 3]) {
+   25352           0 :             ipn4 = 4*(*i0 + *n0);
+   25353           0 :             i__1 = 2*(*i0 + *n0 - 1);
+   25354           0 :             for (j4 = *i0 << 2; j4 <= i__1; j4 += 4) {
+   25355           0 :                 temp = z__[j4 - 3];
+   25356           0 :                 z__[j4 - 3] = z__[ipn4 - j4 - 3];
+   25357           0 :                 z__[ipn4 - j4 - 3] = temp;
+   25358           0 :                 temp = z__[j4 - 2];
+   25359           0 :                 z__[j4 - 2] = z__[ipn4 - j4 - 2];
+   25360           0 :                 z__[ipn4 - j4 - 2] = temp;
+   25361           0 :                 temp = z__[j4 - 1];
+   25362           0 :                 z__[j4 - 1] = z__[ipn4 - j4 - 5];
+   25363           0 :                 z__[ipn4 - j4 - 5] = temp;
+   25364           0 :                 temp = z__[j4];
+   25365           0 :                 z__[j4] = z__[ipn4 - j4 - 4];
+   25366           0 :                 z__[ipn4 - j4 - 4] = temp;
+   25367             :             }
+   25368           0 :             if (*n0 - *i0 <= 4) {
+   25369           0 :                 z__[(*n0 << 2) + *pp - 1] = z__[(*i0 << 2) + *pp - 1];
+   25370           0 :                 z__[(*n0 << 2) - *pp] = z__[(*i0 << 2) - *pp];
+   25371             :             }
+   25372           0 :             d__1 = dmin2, d__2 = z__[(*n0 << 2) + *pp - 1];
+   25373           0 :             dmin2 = ((d__1<d__2) ? d__1 : d__2);
+   25374           0 :             d__1 = z__[(*n0 << 2) + *pp - 1], d__2 = z__[(*i0 << 2) + *pp - 1]
+   25375           0 :                     , d__1 = ((d__1<d__2) ? d__1 : d__2), d__2 = z__[(*i0 << 2) + *pp + 3];
+   25376           0 :             z__[(*n0 << 2) + *pp - 1] = ((d__1<d__2) ? d__1 : d__2);
+   25377           0 :             d__1 = z__[(*n0 << 2) - *pp], d__2 = z__[(*i0 << 2) - *pp], d__1 =
+   25378           0 :                      ((d__1<d__2) ? d__1 : d__2), d__2 = z__[(*i0 << 2) - *pp + 4];
+   25379           0 :             z__[(*n0 << 2) - *pp] = ((d__1<d__2) ? d__1 : d__2);
+   25380           0 :             d__1 = *qmax;
+   25381           0 :             d__2 = z__[(*i0 << 2) + *pp - 3];
+   25382           0 :             d__1 = (d__1>d__2) ? d__1 : d__2;
+   25383           0 :             d__2 = z__[(*i0 << 2) + *pp + 1];
+   25384           0 :             *qmax = ((d__1>d__2) ? d__1 : d__2);
+   25385           0 :             *dmin__ = -0.;
+   25386             :         }
+   25387             :     }
+   25388             : 
+   25389             : 
+   25390           0 :     PLUMED_BLAS_F77_FUNC(slasq4,SLASQ4)(i0, n0, &z__[1], pp, &n0in, dmin__, &dmin1, &dmin2, &dn, &dn1, &
+   25391             :             dn2, &tau, &ttype);
+   25392             : 
+   25393           0 : L70:
+   25394             : 
+   25395           0 :     PLUMED_BLAS_F77_FUNC(slasq5,SLASQ5)(i0, n0, &z__[1], pp, &tau, dmin__, &dmin1, &dmin2, &dn, &dn1, &
+   25396             :             dn2, ieee);
+   25397             : 
+   25398           0 :     *ndiv += *n0 - *i0 + 2;
+   25399           0 :     ++(*iter);
+   25400             : 
+   25401           0 :     if (*dmin__ >= 0. && dmin1 > 0.) {
+   25402             : 
+   25403           0 :         goto L90;
+   25404             : 
+   25405           0 :     } else if (*dmin__ < 0. && dmin1 > 0. && z__[4*(*n0 - 1) - *pp] < tol *
+   25406           0 :              (*sigma + dn1) && std::abs(dn) < tol * *sigma) {
+   25407             : 
+   25408           0 :         z__[4*(*n0 - 1) - *pp + 2] = 0.;
+   25409           0 :         *dmin__ = 0.;
+   25410           0 :         goto L90;
+   25411           0 :     } else if (*dmin__ < 0.) {
+   25412             : 
+   25413           0 :         ++(*nfail);
+   25414           0 :         if (ttype < -22) {
+   25415             : 
+   25416           0 :             tau = 0.;
+   25417           0 :         } else if (dmin1 > 0.) {
+   25418             : 
+   25419           0 :             tau = (tau + *dmin__) * (1. - eps * 2.);
+   25420           0 :             ttype += -11;
+   25421             :         } else {
+   25422             : 
+   25423           0 :             tau *= .25;
+   25424           0 :             ttype += -12;
+   25425             :         }
+   25426           0 :         goto L70;
+   25427             :     }
+   25428             :     else {
+   25429             :         
+   25430           0 :         goto L80;
+   25431             :     }
+   25432             : 
+   25433             : L80:
+   25434           0 :     PLUMED_BLAS_F77_FUNC(slasq6,SLASQ6)(i0, n0, &z__[1], pp, dmin__, &dmin1, &dmin2, &dn, &dn1, &dn2);
+   25435           0 :     *ndiv += *n0 - *i0 + 2;
+   25436           0 :     ++(*iter);
+   25437           0 :     tau = 0.;
+   25438             : 
+   25439           0 : L90:
+   25440           0 :     if (tau < *sigma) {
+   25441           0 :         *desig += tau;
+   25442           0 :         t = *sigma + *desig;
+   25443           0 :         *desig -= t - *sigma;
+   25444             :     } else {
+   25445           0 :         t = *sigma + tau;
+   25446           0 :         *desig = *sigma - (t - tau) + *desig;
+   25447             :     }
+   25448           0 :     *sigma = t;
+   25449             : 
+   25450           0 :     return;
+   25451             : }
+   25452             : }
+   25453             : }
+   25454             : #include <cmath>
+   25455             : #include "real.h"
+   25456             : 
+   25457             : #include "lapack.h"
+   25458             : 
+   25459             : #include "blas/blas.h"
+   25460             : namespace PLMD{
+   25461             : namespace lapack{
+   25462             : using namespace blas;
+   25463             : void 
+   25464           0 : PLUMED_BLAS_F77_FUNC(slasq4,SLASQ4)(int *i0, 
+   25465             :         int *n0, 
+   25466             :         float *z__, 
+   25467             :         int *pp, 
+   25468             :         int *n0in, 
+   25469             :         float *dmin__, 
+   25470             :         float *dmin1, 
+   25471             :         float *dmin2, 
+   25472             :         float *dn, 
+   25473             :         float *dn1, 
+   25474             :         float *dn2, 
+   25475             :         float *tau, 
+   25476             :         int *ttype)
+   25477             : {
+   25478             :     float g = 0.;
+   25479             :     int i__1;
+   25480             :     float d__1, d__2;
+   25481             : 
+   25482             :     float s, a2, b1, b2;
+   25483             :     int i4, nn, np;
+   25484             :     float gam, gap1, gap2;
+   25485             : 
+   25486             : 
+   25487           0 :     if (*dmin__ <= 0.) {
+   25488           0 :         *tau = -(*dmin__);
+   25489           0 :         *ttype = -1;
+   25490           0 :         return;
+   25491             :     }
+   25492             : 
+   25493             :     s = 0.0;
+   25494             : 
+   25495           0 :     nn = (*n0 << 2) + *pp;
+   25496           0 :     if (*n0in == *n0) {
+   25497             : 
+   25498           0 :         if ( std::abs(*dmin__ - *dn)<PLUMED_GMX_FLOAT_EPS*std::abs(*dmin__ + *dn) ||
+   25499           0 :          std::abs(*dmin__ - *dn1)<PLUMED_GMX_FLOAT_EPS*std::abs(*dmin__ + *dn1)) {
+   25500             : 
+   25501           0 :             b1 =  std::sqrt(z__[nn - 3]) * std::sqrt(z__[nn - 5]);
+   25502           0 :             b2 =  std::sqrt(z__[nn - 7]) * std::sqrt(z__[nn - 9]);
+   25503           0 :             a2 = z__[nn - 7] + z__[nn - 5];
+   25504             : 
+   25505           0 :         if ( std::abs(*dmin__ - *dn)<PLUMED_GMX_FLOAT_EPS*std::abs(*dmin__ + *dn) &&
+   25506           0 :              std::abs(*dmin1 - *dn1)<PLUMED_GMX_FLOAT_EPS*std::abs(*dmin1 + *dn1)) {
+   25507             : 
+   25508           0 :             gap2 = *dmin2 - a2 - *dmin2 * .25;
+   25509           0 :                 if (gap2 > 0. && gap2 > b2) {
+   25510           0 :                     gap1 = a2 - *dn - b2 / gap2 * b2;
+   25511             :                 } else {
+   25512           0 :                     gap1 = a2 - *dn - (b1 + b2);
+   25513             :                 }
+   25514           0 :                 if (gap1 > 0. && gap1 > b1) {
+   25515           0 :                     d__1 = *dn - b1 / gap1 * b1, d__2 = *dmin__ * .5;
+   25516           0 :                     s = (d__1>d__2) ? d__1 : d__2;
+   25517           0 :                     *ttype = -2;
+   25518             :                 } else {
+   25519             :                     s = 0.;
+   25520           0 :                     if (*dn > b1) {
+   25521           0 :                         s = *dn - b1;
+   25522             :                     }
+   25523           0 :                     if (a2 > b1 + b2) {
+   25524           0 :                         d__1 = s, d__2 = a2 - (b1 + b2);
+   25525           0 :                         s = (d__1<d__2) ? d__1 : d__2;
+   25526             :                     }
+   25527           0 :                     d__1 = s, d__2 = *dmin__ * .333;
+   25528           0 :                     s = (d__1>d__2) ? d__1 : d__2;
+   25529           0 :                     *ttype = -3;
+   25530             :                 }
+   25531             :             } else {
+   25532             : 
+   25533             : 
+   25534           0 :                 *ttype = -4;
+   25535           0 :                 s = *dmin__ * .25;
+   25536           0 :                 if (std::abs(*dmin__ - *dn)<PLUMED_GMX_FLOAT_EPS*std::abs(*dmin__ + *dn)) {
+   25537             :                     gam = *dn;
+   25538             :                     a2 = 0.;
+   25539           0 :                     if (z__[nn - 5] > z__[nn - 7]) {
+   25540             :                         return;
+   25541             :                     }
+   25542           0 :                     b2 = z__[nn - 5] / z__[nn - 7];
+   25543           0 :                     np = nn - 9;
+   25544             :                 } else {
+   25545           0 :                     np = nn - (*pp << 1);
+   25546           0 :                     gam = *dn1;
+   25547           0 :                     if (z__[np - 4] > z__[np - 2]) {
+   25548             :                         return;
+   25549             :                     }
+   25550           0 :                     a2 = z__[np - 4] / z__[np - 2];
+   25551           0 :                     if (z__[nn - 9] > z__[nn - 11]) {
+   25552             :                         return;
+   25553             :                     }
+   25554           0 :                     b2 = z__[nn - 9] / z__[nn - 11];
+   25555           0 :                     np = nn - 13;
+   25556             :                 }
+   25557             : 
+   25558             : 
+   25559           0 :                 a2 += b2;
+   25560           0 :                 i__1 = (*i0 << 2) - 1 + *pp;
+   25561           0 :                 for (i4 = np; i4 >= i__1; i4 += -4) {
+   25562           0 :                     if (std::abs(b2)<PLUMED_GMX_FLOAT_MIN) {
+   25563           0 :                         goto L20;
+   25564             :                     }
+   25565             :                     b1 = b2;
+   25566           0 :                     if (z__[i4] > z__[i4 - 2]) {
+   25567             :                         return;
+   25568             :                     }
+   25569           0 :                     b2 *= z__[i4] / z__[i4 - 2];
+   25570           0 :                     a2 += b2;
+   25571           0 :                     if (((b2>b1) ? b2 : b1) * 100. < a2 || .563 < a2) {
+   25572           0 :                         goto L20;
+   25573             :                     }
+   25574             :                 }
+   25575           0 : L20:
+   25576           0 :                 a2 *= 1.05;
+   25577             : 
+   25578             : 
+   25579           0 :                 if (a2 < .563) {
+   25580           0 :                     s = gam * (1. -  std::sqrt(a2)) / (a2 + 1.);
+   25581             :                 }
+   25582             :             }
+   25583           0 :         } else if (std::abs(*dmin__ - *dn2)<PLUMED_GMX_FLOAT_EPS*std::abs(*dmin__ + *dn2)) {
+   25584             : 
+   25585           0 :             *ttype = -5;
+   25586           0 :             s = *dmin__ * .25;
+   25587             : 
+   25588           0 :             np = nn - (*pp << 1);
+   25589           0 :             b1 = z__[np - 2];
+   25590           0 :             b2 = z__[np - 6];
+   25591           0 :             gam = *dn2;
+   25592           0 :             if (z__[np - 8] > b2 || z__[np - 4] > b1) {
+   25593             :                 return;
+   25594             :             }
+   25595           0 :             a2 = z__[np - 8] / b2 * (z__[np - 4] / b1 + 1.);
+   25596             : 
+   25597             : 
+   25598           0 :             if (*n0 - *i0 > 2) {
+   25599           0 :                 b2 = z__[nn - 13] / z__[nn - 15];
+   25600           0 :                 a2 += b2;
+   25601           0 :                 i__1 = (*i0 << 2) - 1 + *pp;
+   25602           0 :                 for (i4 = nn - 17; i4 >= i__1; i4 += -4) {
+   25603           0 :                     if (std::abs(b2)<PLUMED_GMX_FLOAT_MIN) {
+   25604           0 :                         goto L40;
+   25605             :                     }
+   25606             :                     b1 = b2;
+   25607           0 :                     if (z__[i4] > z__[i4 - 2]) {
+   25608             :                         return;
+   25609             :                     }
+   25610           0 :                     b2 *= z__[i4] / z__[i4 - 2];
+   25611           0 :                     a2 += b2;
+   25612           0 :                     if (((b2>b1) ? b2 : b1) * 100. < a2 || .563 < a2) {
+   25613           0 :                         goto L40;
+   25614             :                     }
+   25615             :                 }
+   25616           0 : L40:
+   25617           0 :                 a2 *= 1.05;
+   25618             :             }
+   25619             : 
+   25620           0 :             if (a2 < .563) {
+   25621           0 :                 s = gam * (1. -  std::sqrt(a2)) / (a2 + 1.);
+   25622             :             }
+   25623             :         } else {
+   25624             : 
+   25625           0 :             if (*ttype == -6) {
+   25626             :                 g += (1. - g) * .333;
+   25627           0 :             } else if (*ttype == -18) {
+   25628             :                 g = .083250000000000005;
+   25629             :             } else {
+   25630             :                 g = .25;
+   25631             :             }
+   25632           0 :             s = g * *dmin__;
+   25633           0 :             *ttype = -6;
+   25634             :         }
+   25635             : 
+   25636           0 :     } else if (*n0in == *n0 + 1) {
+   25637             : 
+   25638           0 :         if ( std::abs(*dmin1 - *dn1)<PLUMED_GMX_FLOAT_EPS*std::abs(*dmin1 + *dn1) &&
+   25639           0 :              std::abs(*dmin2 - *dn2)<PLUMED_GMX_FLOAT_EPS*std::abs(*dmin2 + *dn2)) {
+   25640             : 
+   25641           0 :             *ttype = -7;
+   25642           0 :             s = *dmin1 * .333;
+   25643           0 :             if (z__[nn - 5] > z__[nn - 7]) {
+   25644             :                 return;
+   25645             :             }
+   25646           0 :             b1 = z__[nn - 5] / z__[nn - 7];
+   25647             :             b2 = b1;
+   25648           0 :             if (std::abs(b2)<PLUMED_GMX_FLOAT_MIN) {
+   25649           0 :                 goto L60;
+   25650             :             }
+   25651           0 :             i__1 = (*i0 << 2) - 1 + *pp;
+   25652           0 :             for (i4 = (*n0 << 2) - 9 + *pp; i4 >= i__1; i4 += -4) {
+   25653             :                 a2 = b1;
+   25654           0 :                 if (z__[i4] > z__[i4 - 2]) {
+   25655             :                     return;
+   25656             :                 }
+   25657           0 :                 b1 *= z__[i4] / z__[i4 - 2];
+   25658           0 :                 b2 += b1;
+   25659           0 :                 if (((a2>b1) ? a2 : b1) * 100. < b2) {
+   25660           0 :                     goto L60;
+   25661             :                 }
+   25662             :             }
+   25663           0 : L60:
+   25664           0 :             b2 =  std::sqrt(b2 * 1.05);
+   25665             :             d__1 = b2;
+   25666           0 :             a2 = *dmin1 / (d__1 * d__1 + 1.);
+   25667           0 :             gap2 = *dmin2 * .5 - a2;
+   25668           0 :             if (gap2 > 0. && gap2 > b2 * a2) {
+   25669           0 :                 d__1 = s, d__2 = a2 * (1. - a2 * 1.01 * (b2 / gap2) * b2);
+   25670           0 :                 s = (d__1>d__2) ? d__1 : d__2;
+   25671             :             } else {
+   25672           0 :                 d__1 = s, d__2 = a2 * (1. - b2 * 1.01);
+   25673           0 :                 s = (d__1>d__2) ? d__1 : d__2;
+   25674           0 :                 *ttype = -8;
+   25675             :             }
+   25676             :         } else {
+   25677             : 
+   25678           0 :             s = *dmin1 * .25;
+   25679           0 :             if (std::abs(*dmin1 - *dn1)<PLUMED_GMX_FLOAT_EPS*std::abs(*dmin1 + *dn1)) {
+   25680           0 :                 s = *dmin1 * .5;
+   25681             :             }
+   25682           0 :             *ttype = -9;
+   25683             :         }
+   25684             : 
+   25685           0 :     } else if (*n0in == *n0 + 2) {
+   25686             : 
+   25687           0 :         if (std::abs(*dmin2 - *dn2)<PLUMED_GMX_FLOAT_EPS*std::abs(*dmin2 + *dn2) &&
+   25688           0 :         z__[nn - 5] * 2. < z__[nn - 7]) {
+   25689           0 :             *ttype = -10;
+   25690           0 :             s = *dmin2 * .333;
+   25691           0 :             if (z__[nn - 5] > z__[nn - 7]) {
+   25692             :                 return;
+   25693             :             }
+   25694           0 :             b1 = z__[nn - 5] / z__[nn - 7];
+   25695             :             b2 = b1;
+   25696           0 :             if (std::abs(b2)<PLUMED_GMX_FLOAT_MIN) {
+   25697           0 :                 goto L80;
+   25698             :             }
+   25699           0 :             i__1 = (*i0 << 2) - 1 + *pp;
+   25700           0 :             for (i4 = (*n0 << 2) - 9 + *pp; i4 >= i__1; i4 += -4) {
+   25701           0 :                 if (z__[i4] > z__[i4 - 2]) {
+   25702             :                     return;
+   25703             :                 }
+   25704           0 :                 b1 *= z__[i4] / z__[i4 - 2];
+   25705           0 :                 b2 += b1;
+   25706           0 :                 if (b1 * 100. < b2) {
+   25707           0 :                     goto L80;
+   25708             :                 }
+   25709             :             }
+   25710           0 : L80:
+   25711           0 :             b2 =  std::sqrt(b2 * 1.05);
+   25712             :             d__1 = b2;
+   25713           0 :             a2 = *dmin2 / (d__1 * d__1 + 1.);
+   25714           0 :             gap2 = z__[nn - 7] + z__[nn - 9] -  std::sqrt(z__[nn - 11]) * std::sqrt(z__[
+   25715             :                     nn - 9]) - a2;
+   25716           0 :             if (gap2 > 0. && gap2 > b2 * a2) {
+   25717           0 :                 d__1 = s, d__2 = a2 * (1. - a2 * 1.01 * (b2 / gap2) * b2);
+   25718           0 :                 s = (d__1>d__2) ? d__1 : d__2;
+   25719             :             } else {
+   25720           0 :                 d__1 = s, d__2 = a2 * (1. - b2 * 1.01);
+   25721           0 :                 s = (d__1>d__2) ? d__1 : d__2;
+   25722             :             }
+   25723             :         } else {
+   25724           0 :             s = *dmin2 * .25;
+   25725           0 :             *ttype = -11;
+   25726             :         }
+   25727           0 :     } else if (*n0in > *n0 + 2) {
+   25728             : 
+   25729             :         s = 0.;
+   25730           0 :         *ttype = -12;
+   25731             :     }
+   25732             : 
+   25733           0 :     *tau = s;
+   25734           0 :     return;
+   25735             : 
+   25736             : }
+   25737             : 
+   25738             : 
+   25739             : }
+   25740             : }
+   25741             : #include <cmath>
+   25742             : #include "lapack.h"
+   25743             : 
+   25744             : #include "blas/blas.h"
+   25745             : namespace PLMD{
+   25746             : namespace lapack{
+   25747             : using namespace blas;
+   25748             : void
+   25749           0 : PLUMED_BLAS_F77_FUNC(slasq5,SLASQ5)(int *i0, 
+   25750             :         int *n0,
+   25751             :         float *z__, 
+   25752             :         int *pp, 
+   25753             :         float *tau,
+   25754             :         float *dmin__, 
+   25755             :         float *dmin1, 
+   25756             :         float *dmin2, 
+   25757             :         float *dn,
+   25758             :         float *dnm1, 
+   25759             :         float *dnm2,
+   25760             :         int *ieee)
+   25761             : {
+   25762             :     int i__1;
+   25763             :     float d__1, d__2;
+   25764             : 
+   25765             :     float d__;
+   25766             :     int j4, j4p2;
+   25767             :     float emin, temp;
+   25768             : 
+   25769           0 :     --z__;
+   25770             : 
+   25771           0 :     if (*n0 - *i0 - 1 <= 0) {
+   25772             :         return;
+   25773             :     }
+   25774             : 
+   25775           0 :     j4 = (*i0 << 2) + *pp - 3;
+   25776           0 :     emin = z__[j4 + 4];
+   25777           0 :     d__ = z__[j4] - *tau;
+   25778           0 :     *dmin__ = d__;
+   25779           0 :     *dmin1 = -z__[j4];
+   25780             : 
+   25781           0 :     if (*ieee) {
+   25782             : 
+   25783           0 :         if (*pp == 0) {
+   25784           0 :             i__1 = 4*(*n0 - 3);
+   25785           0 :             for (j4 = *i0 << 2; j4 <= i__1; j4 += 4) {
+   25786           0 :                 z__[j4 - 2] = d__ + z__[j4 - 1];
+   25787           0 :                 temp = z__[j4 + 1] / z__[j4 - 2];
+   25788           0 :                 d__ = d__ * temp - *tau;
+   25789           0 :                 if(d__<*dmin__)
+   25790           0 :                   *dmin__ = d__;
+   25791           0 :                 z__[j4] = z__[j4 - 1] * temp;
+   25792             :                 d__1 = z__[j4];
+   25793           0 :                 if(d__1<emin)
+   25794             :                   emin = d__1;
+   25795             :             }
+   25796             :         } else {
+   25797           0 :             i__1 = 4*(*n0 - 3);
+   25798           0 :             for (j4 = *i0 << 2; j4 <= i__1; j4 += 4) {
+   25799           0 :                 z__[j4 - 3] = d__ + z__[j4];
+   25800           0 :                 temp = z__[j4 + 2] / z__[j4 - 3];
+   25801           0 :                 d__ = d__ * temp - *tau;
+   25802           0 :                 if(d__<*dmin__)
+   25803           0 :                   *dmin__ = d__;
+   25804           0 :                 z__[j4 - 1] = z__[j4] * temp;
+   25805             :                 d__1 = z__[j4 - 1];
+   25806           0 :                 if(d__1<emin)
+   25807             :                   emin = d__1;
+   25808             :             }
+   25809             :         }
+   25810             : 
+   25811           0 :         *dnm2 = d__;
+   25812           0 :         *dmin2 = *dmin__;
+   25813           0 :         j4 = 4*(*n0 - 2) - *pp;
+   25814           0 :         j4p2 = j4 + (*pp << 1) - 1;
+   25815           0 :         z__[j4 - 2] = *dnm2 + z__[j4p2];
+   25816           0 :         z__[j4] = z__[j4p2 + 2] * (z__[j4p2] / z__[j4 - 2]);
+   25817           0 :         *dnm1 = z__[j4p2 + 2] * (*dnm2 / z__[j4 - 2]) - *tau;
+   25818           0 :         if(*dnm1<*dmin__)
+   25819           0 :           *dmin__ = *dnm1;
+   25820             : 
+   25821           0 :         *dmin1 = *dmin__;
+   25822           0 :         j4 += 4;
+   25823           0 :         j4p2 = j4 + (*pp << 1) - 1;
+   25824           0 :         z__[j4 - 2] = *dnm1 + z__[j4p2];
+   25825           0 :         z__[j4] = z__[j4p2 + 2] * (z__[j4p2] / z__[j4 - 2]);
+   25826           0 :         *dn = z__[j4p2 + 2] * (*dnm1 / z__[j4 - 2]) - *tau;
+   25827           0 :         if(*dn<*dmin__)
+   25828           0 :           *dmin__ = *dn;
+   25829             : 
+   25830             :     } else {
+   25831             : 
+   25832           0 :         if (*pp == 0) {
+   25833           0 :             i__1 = 4*(*n0 - 3);
+   25834           0 :             for (j4 = *i0 << 2; j4 <= i__1; j4 += 4) {
+   25835           0 :                 z__[j4 - 2] = d__ + z__[j4 - 1];
+   25836           0 :                 if (d__ < 0.) {
+   25837             :                     return;
+   25838             :                 } else {
+   25839           0 :                     z__[j4] = z__[j4 + 1] * (z__[j4 - 1] / z__[j4 - 2]);
+   25840           0 :                     d__ = z__[j4 + 1] * (d__ / z__[j4 - 2]) - *tau;
+   25841             :                 }
+   25842           0 :                 if(d__<*dmin__)
+   25843           0 :                   *dmin__ = d__;
+   25844           0 :                 d__1 = emin, d__2 = z__[j4];
+   25845           0 :                 emin = (d__1<d__2) ? d__1 : d__2;
+   25846             :             }
+   25847             :         } else {
+   25848           0 :             i__1 = 4*(*n0 - 3);
+   25849           0 :             for (j4 = *i0 << 2; j4 <= i__1; j4 += 4) {
+   25850           0 :                 z__[j4 - 3] = d__ + z__[j4];
+   25851           0 :                 if (d__ < 0.) {
+   25852             :                     return;
+   25853             :                 } else {
+   25854           0 :                     z__[j4 - 1] = z__[j4 + 2] * (z__[j4] / z__[j4 - 3]);
+   25855           0 :                     d__ = z__[j4 + 2] * (d__ / z__[j4 - 3]) - *tau;
+   25856             :                 }
+   25857           0 :                 if(d__<*dmin__)
+   25858           0 :                   *dmin__ = d__;
+   25859           0 :                 d__1 = emin, d__2 = z__[j4 - 1];
+   25860           0 :                 emin = (d__1<d__2) ? d__1 : d__2;
+   25861             :             }
+   25862             :         }
+   25863             : 
+   25864           0 :         *dnm2 = d__;
+   25865           0 :         *dmin2 = *dmin__;
+   25866           0 :         j4 = 4*(*n0 - 2) - *pp;
+   25867           0 :         j4p2 = j4 + (*pp << 1) - 1;
+   25868           0 :         z__[j4 - 2] = *dnm2 + z__[j4p2];
+   25869           0 :         if (*dnm2 < 0.) {
+   25870             :             return;
+   25871             :         } else {
+   25872           0 :             z__[j4] = z__[j4p2 + 2] * (z__[j4p2] / z__[j4 - 2]);
+   25873           0 :             *dnm1 = z__[j4p2 + 2] * (*dnm2 / z__[j4 - 2]) - *tau;
+   25874             :         }
+   25875           0 :         if(*dnm1<*dmin__)
+   25876           0 :           *dmin__ = *dnm1;
+   25877             : 
+   25878           0 :         *dmin1 = *dmin__;
+   25879           0 :         j4 += 4;
+   25880           0 :         j4p2 = j4 + (*pp << 1) - 1;
+   25881           0 :         z__[j4 - 2] = *dnm1 + z__[j4p2];
+   25882           0 :         if (*dnm1 < 0.) {
+   25883             :             return;
+   25884             :         } else {
+   25885           0 :             z__[j4] = z__[j4p2 + 2] * (z__[j4p2] / z__[j4 - 2]);
+   25886           0 :             *dn = z__[j4p2 + 2] * (*dnm1 / z__[j4 - 2]) - *tau;
+   25887             :         }
+   25888           0 :         if(*dn<*dmin__)
+   25889           0 :           *dmin__ = *dn;
+   25890             : 
+   25891             :     }
+   25892             : 
+   25893           0 :     z__[j4 + 2] = *dn;
+   25894           0 :     z__[(*n0 << 2) - *pp] = emin;
+   25895           0 :     return;
+   25896             : 
+   25897             : }
+   25898             : 
+   25899             : }
+   25900             : }
+   25901             : #include <cmath>
+   25902             : #include "lapack.h"
+   25903             : #include "lapack_limits.h"
+   25904             : 
+   25905             : #include "real.h"
+   25906             : 
+   25907             : #include "blas/blas.h"
+   25908             : namespace PLMD{
+   25909             : namespace lapack{
+   25910             : using namespace blas;
+   25911             : void 
+   25912           0 : PLUMED_BLAS_F77_FUNC(slasq6,SLASQ6)(int *i0, 
+   25913             :         int *n0, 
+   25914             :         float *z__, 
+   25915             :         int *pp, 
+   25916             :         float *dmin__, 
+   25917             :         float *dmin1, 
+   25918             :         float *dmin2,
+   25919             :         float *dn, 
+   25920             :         float *dnm1, 
+   25921             :         float *dnm2)
+   25922             : {
+   25923             :     int i__1;
+   25924             :     float d__1, d__2;
+   25925             : 
+   25926             :     /* Local variables */
+   25927             :     float d__;
+   25928             :     int j4, j4p2;
+   25929             :     float emin, temp;
+   25930             :     const float safemin = PLUMED_GMX_FLOAT_MIN*(1.0+PLUMED_GMX_FLOAT_EPS);
+   25931             : 
+   25932           0 :     --z__;
+   25933             : 
+   25934           0 :     if (*n0 - *i0 - 1 <= 0) {
+   25935             :         return;
+   25936             :     }
+   25937             : 
+   25938           0 :     j4 = (*i0 << 2) + *pp - 3;
+   25939           0 :     emin = z__[j4 + 4];
+   25940           0 :     d__ = z__[j4];
+   25941           0 :     *dmin__ = d__;
+   25942             : 
+   25943           0 :     if (*pp == 0) {
+   25944           0 :         i__1 = 4*(*n0 - 3);
+   25945           0 :         for (j4 = *i0*4; j4 <= i__1; j4 += 4) {
+   25946           0 :             z__[j4 - 2] = d__ + z__[j4 - 1];
+   25947           0 :             if (std::abs(z__[j4 - 2])<PLUMED_GMX_FLOAT_MIN) {
+   25948           0 :                 z__[j4] = 0.;
+   25949           0 :                 d__ = z__[j4 + 1];
+   25950           0 :                 *dmin__ = d__;
+   25951             :                 emin = 0.;
+   25952           0 :             } else if (safemin * z__[j4 + 1] < z__[j4 - 2] && safemin * z__[j4 
+   25953             :                     - 2] < z__[j4 + 1]) {
+   25954           0 :                 temp = z__[j4 + 1] / z__[j4 - 2];
+   25955           0 :                 z__[j4] = z__[j4 - 1] * temp;
+   25956           0 :                 d__ *= temp;
+   25957             :             } else {
+   25958           0 :                 z__[j4] = z__[j4 + 1] * (z__[j4 - 1] / z__[j4 - 2]);
+   25959           0 :                 d__ = z__[j4 + 1] * (d__ / z__[j4 - 2]);
+   25960             :             }
+   25961           0 :             if(d__<*dmin__)
+   25962           0 :               *dmin__ = d__;
+   25963             : 
+   25964           0 :             d__1 = emin, d__2 = z__[j4];
+   25965           0 :             emin = (d__1<d__2) ? d__1 : d__2;
+   25966             :         }
+   25967             :     } else {
+   25968           0 :         i__1 = 4*(*n0 - 3);
+   25969           0 :         for (j4 = *i0 << 2; j4 <= i__1; j4 += 4) {
+   25970           0 :             z__[j4 - 3] = d__ + z__[j4];
+   25971           0 :             if (std::abs(z__[j4 - 3])<PLUMED_GMX_FLOAT_MIN) {
+   25972           0 :                 z__[j4 - 1] = 0.;
+   25973           0 :                 d__ = z__[j4 + 2];
+   25974           0 :                 *dmin__ = d__;
+   25975             :                 emin = 0.;
+   25976           0 :             } else if (safemin * z__[j4 + 2] < z__[j4 - 3] && safemin * z__[j4 
+   25977             :                     - 3] < z__[j4 + 2]) {
+   25978           0 :                 temp = z__[j4 + 2] / z__[j4 - 3];
+   25979           0 :                 z__[j4 - 1] = z__[j4] * temp;
+   25980           0 :                 d__ *= temp;
+   25981             :             } else {
+   25982           0 :                 z__[j4 - 1] = z__[j4 + 2] * (z__[j4] / z__[j4 - 3]);
+   25983           0 :                 d__ = z__[j4 + 2] * (d__ / z__[j4 - 3]);
+   25984             :             }
+   25985           0 :             if(d__<*dmin__)
+   25986           0 :               *dmin__ = d__;
+   25987           0 :             d__1 = emin, d__2 = z__[j4 - 1];
+   25988           0 :             emin = (d__1<d__2) ? d__1 : d__2;
+   25989             :         }
+   25990             :     }
+   25991             : 
+   25992           0 :     *dnm2 = d__;
+   25993           0 :     *dmin2 = *dmin__;
+   25994           0 :     j4 = 4*(*n0 - 2) - *pp;
+   25995           0 :     j4p2 = j4 + (*pp << 1) - 1;
+   25996           0 :     z__[j4 - 2] = *dnm2 + z__[j4p2];
+   25997           0 :     if (std::abs(z__[j4 - 2])<PLUMED_GMX_FLOAT_MIN) {
+   25998           0 :         z__[j4] = 0.;
+   25999           0 :         *dnm1 = z__[j4p2 + 2];
+   26000           0 :         *dmin__ = *dnm1;
+   26001             :         emin = 0.;
+   26002           0 :     } else if (safemin * z__[j4p2 + 2] < z__[j4 - 2] && safemin * z__[j4 - 2] < 
+   26003             :             z__[j4p2 + 2]) {
+   26004           0 :         temp = z__[j4p2 + 2] / z__[j4 - 2];
+   26005           0 :         z__[j4] = z__[j4p2] * temp;
+   26006           0 :         *dnm1 = *dnm2 * temp;
+   26007             :     } else {
+   26008           0 :         z__[j4] = z__[j4p2 + 2] * (z__[j4p2] / z__[j4 - 2]);
+   26009           0 :         *dnm1 = z__[j4p2 + 2] * (*dnm2 / z__[j4 - 2]);
+   26010             :     }
+   26011           0 :     if(*dnm1<*dmin__)
+   26012           0 :       *dmin__ = *dnm1;
+   26013             : 
+   26014           0 :     *dmin1 = *dmin__;
+   26015           0 :     j4 += 4;
+   26016           0 :     j4p2 = j4 + (*pp << 1) - 1;
+   26017           0 :     z__[j4 - 2] = *dnm1 + z__[j4p2];
+   26018           0 :     if (std::abs(z__[j4 - 2])<PLUMED_GMX_FLOAT_MIN) {
+   26019           0 :         z__[j4] = 0.;
+   26020           0 :         *dn = z__[j4p2 + 2];
+   26021           0 :         *dmin__ = *dn;
+   26022             :         emin = 0.;
+   26023           0 :     } else if (safemin * z__[j4p2 + 2] < z__[j4 - 2] && safemin * z__[j4 - 2] < 
+   26024             :             z__[j4p2 + 2]) {
+   26025           0 :         temp = z__[j4p2 + 2] / z__[j4 - 2];
+   26026           0 :         z__[j4] = z__[j4p2] * temp;
+   26027           0 :         *dn = *dnm1 * temp;
+   26028             :     } else {
+   26029           0 :         z__[j4] = z__[j4p2 + 2] * (z__[j4p2] / z__[j4 - 2]);
+   26030           0 :         *dn = z__[j4p2 + 2] * (*dnm1 / z__[j4 - 2]);
+   26031             :     }
+   26032           0 :     if(*dn<*dmin__)
+   26033           0 :       *dmin__ = *dn;
+   26034             : 
+   26035           0 :     z__[j4 + 2] = *dn;
+   26036           0 :     z__[(*n0 << 2) - *pp] = emin;
+   26037           0 :     return;
+   26038             : 
+   26039             : 
+   26040             : } 
+   26041             : }
+   26042             : }
+   26043             : #include <cmath>
+   26044             : 
+   26045             : #include "real.h"
+   26046             : #include "lapack.h"
+   26047             : 
+   26048             : #include "blas/blas.h"
+   26049             : namespace PLMD{
+   26050             : namespace lapack{
+   26051             : using namespace blas;
+   26052             : void 
+   26053           0 : PLUMED_BLAS_F77_FUNC(slasr,SLASR)(const char *side, 
+   26054             :        const char *pivot, 
+   26055             :        const char *direct, 
+   26056             :        int *m,
+   26057             :        int *n, 
+   26058             :        float *c__, 
+   26059             :        float *s, 
+   26060             :        float *a, 
+   26061             :        int *lda)
+   26062             : {
+   26063             :     /* System generated locals */
+   26064             :     int a_dim1, a_offset, i__1, i__2;
+   26065             : 
+   26066             :     /* Local variables */
+   26067             :     int i__, j;
+   26068             :     float temp;
+   26069             :     float ctemp, stemp;
+   26070             : 
+   26071           0 :     --c__;
+   26072           0 :     --s;
+   26073           0 :     a_dim1 = *lda;
+   26074           0 :     a_offset = 1 + a_dim1;
+   26075           0 :     a -= a_offset;
+   26076             : 
+   26077             :     /* Function Body */
+   26078             : 
+   26079           0 :     if (*m == 0 || *n == 0) {
+   26080             :         return;
+   26081             :     }
+   26082           0 :     if (*side=='L' || *side=='l') {
+   26083             : 
+   26084           0 :         if (*pivot=='V' || *pivot=='v') {
+   26085           0 :             if (*direct=='F' || *direct=='f') {
+   26086             :                 i__1 = *m - 1;
+   26087           0 :                 for (j = 1; j <= i__1; ++j) {
+   26088           0 :                     ctemp = c__[j];
+   26089           0 :                     stemp = s[j];
+   26090           0 :                     if (std::abs(ctemp-1.0)>PLUMED_GMX_FLOAT_EPS || std::abs(stemp)>PLUMED_GMX_FLOAT_MIN) {
+   26091           0 :                         i__2 = *n;
+   26092           0 :                         for (i__ = 1; i__ <= i__2; ++i__) {
+   26093           0 :                             temp = a[j + 1 + i__ * a_dim1];
+   26094           0 :                             a[j + 1 + i__ * a_dim1] = ctemp * temp - stemp * 
+   26095           0 :                                     a[j + i__ * a_dim1];
+   26096           0 :                             a[j + i__ * a_dim1] = stemp * temp + ctemp * a[j 
+   26097           0 :                                     + i__ * a_dim1];
+   26098             :                         }
+   26099             :                     }
+   26100             :                 }
+   26101           0 :             } else if (*direct=='B' || *direct=='b') {
+   26102           0 :                 for (j = *m - 1; j >= 1; --j) {
+   26103           0 :                     ctemp = c__[j];
+   26104           0 :                     stemp = s[j];
+   26105           0 :                     if (std::abs(ctemp-1.0)>PLUMED_GMX_FLOAT_EPS || std::abs(stemp)>PLUMED_GMX_FLOAT_MIN) {
+   26106           0 :                         i__1 = *n;
+   26107           0 :                         for (i__ = 1; i__ <= i__1; ++i__) {
+   26108           0 :                             temp = a[j + 1 + i__ * a_dim1];
+   26109           0 :                             a[j + 1 + i__ * a_dim1] = ctemp * temp - stemp * 
+   26110           0 :                                     a[j + i__ * a_dim1];
+   26111           0 :                             a[j + i__ * a_dim1] = stemp * temp + ctemp * a[j 
+   26112           0 :                                     + i__ * a_dim1];
+   26113             :                         }
+   26114             :                     }
+   26115             :                 }
+   26116             :             }
+   26117           0 :         } else if (*pivot=='T' || *pivot=='t') {
+   26118           0 :             if (*direct=='F' || *direct=='f') {
+   26119             :                 i__1 = *m;
+   26120           0 :                 for (j = 2; j <= i__1; ++j) {
+   26121           0 :                     ctemp = c__[j - 1];
+   26122           0 :                     stemp = s[j - 1];
+   26123           0 :                     if (std::abs(ctemp-1.0)>PLUMED_GMX_FLOAT_EPS || std::abs(stemp)>PLUMED_GMX_FLOAT_MIN) {
+   26124           0 :                         i__2 = *n;
+   26125           0 :                         for (i__ = 1; i__ <= i__2; ++i__) {
+   26126           0 :                             temp = a[j + i__ * a_dim1];
+   26127           0 :                             a[j + i__ * a_dim1] = ctemp * temp - stemp * a[
+   26128           0 :                                     i__ * a_dim1 + 1];
+   26129           0 :                             a[i__ * a_dim1 + 1] = stemp * temp + ctemp * a[
+   26130           0 :                                     i__ * a_dim1 + 1];
+   26131             :                         }
+   26132             :                     }
+   26133             :                 }
+   26134           0 :             } else if (*direct=='B' || *direct=='b') {
+   26135           0 :                 for (j = *m; j >= 2; --j) {
+   26136           0 :                     ctemp = c__[j - 1];
+   26137           0 :                     stemp = s[j - 1];
+   26138           0 :                     if (std::abs(ctemp-1.0)>PLUMED_GMX_FLOAT_EPS || std::abs(stemp)>PLUMED_GMX_FLOAT_MIN) {
+   26139           0 :                         i__1 = *n;
+   26140           0 :                         for (i__ = 1; i__ <= i__1; ++i__) {
+   26141           0 :                             temp = a[j + i__ * a_dim1];
+   26142           0 :                             a[j + i__ * a_dim1] = ctemp * temp - stemp * a[
+   26143           0 :                                     i__ * a_dim1 + 1];
+   26144           0 :                             a[i__ * a_dim1 + 1] = stemp * temp + ctemp * a[
+   26145           0 :                                     i__ * a_dim1 + 1];
+   26146             :                         }
+   26147             :                     }
+   26148             :                 }
+   26149             :             }
+   26150           0 :         } else if (*pivot=='B' || *pivot=='b') {
+   26151           0 :             if (*direct=='F' || *direct=='f') {
+   26152             :                 i__1 = *m - 1;
+   26153           0 :                 for (j = 1; j <= i__1; ++j) {
+   26154           0 :                     ctemp = c__[j];
+   26155           0 :                     stemp = s[j];
+   26156           0 :                     if (std::abs(ctemp-1.0)>PLUMED_GMX_FLOAT_EPS || std::abs(stemp)>PLUMED_GMX_FLOAT_MIN) {
+   26157           0 :                         i__2 = *n;
+   26158           0 :                         for (i__ = 1; i__ <= i__2; ++i__) {
+   26159           0 :                             temp = a[j + i__ * a_dim1];
+   26160           0 :                             a[j + i__ * a_dim1] = stemp * a[*m + i__ * a_dim1]
+   26161           0 :                                      + ctemp * temp;
+   26162           0 :                             a[*m + i__ * a_dim1] = ctemp * a[*m + i__ * 
+   26163           0 :                                     a_dim1] - stemp * temp;
+   26164             :                         }
+   26165             :                     }
+   26166             :                 }
+   26167           0 :             } else if (*direct=='B' || *direct=='b') {
+   26168           0 :                 for (j = *m - 1; j >= 1; --j) {
+   26169           0 :                     ctemp = c__[j];
+   26170           0 :                     stemp = s[j];
+   26171           0 :                     if (std::abs(ctemp-1.0)>PLUMED_GMX_FLOAT_EPS || std::abs(stemp)>PLUMED_GMX_FLOAT_MIN) {
+   26172           0 :                         i__1 = *n;
+   26173           0 :                         for (i__ = 1; i__ <= i__1; ++i__) {
+   26174           0 :                             temp = a[j + i__ * a_dim1];
+   26175           0 :                             a[j + i__ * a_dim1] = stemp * a[*m + i__ * a_dim1]
+   26176           0 :                                      + ctemp * temp;
+   26177           0 :                             a[*m + i__ * a_dim1] = ctemp * a[*m + i__ * 
+   26178           0 :                                     a_dim1] - stemp * temp;
+   26179             :                         }
+   26180             :                     }
+   26181             :                 }
+   26182             :             }
+   26183             :         }
+   26184           0 :     } else if (*side=='R' || *side=='r') {
+   26185             : 
+   26186           0 :         if (*pivot=='V' || *pivot=='v') {
+   26187           0 :             if (*direct=='F' || *direct=='f') {
+   26188             :                 i__1 = *n - 1;
+   26189           0 :                 for (j = 1; j <= i__1; ++j) {
+   26190           0 :                     ctemp = c__[j];
+   26191           0 :                     stemp = s[j];
+   26192           0 :                     if (std::abs(ctemp-1.0)>PLUMED_GMX_FLOAT_EPS || std::abs(stemp)>PLUMED_GMX_FLOAT_MIN) {
+   26193           0 :                         i__2 = *m;
+   26194           0 :                         for (i__ = 1; i__ <= i__2; ++i__) {
+   26195           0 :                             temp = a[i__ + (j + 1) * a_dim1];
+   26196           0 :                             a[i__ + (j + 1) * a_dim1] = ctemp * temp - stemp *
+   26197           0 :                                      a[i__ + j * a_dim1];
+   26198           0 :                             a[i__ + j * a_dim1] = stemp * temp + ctemp * a[
+   26199           0 :                                     i__ + j * a_dim1];
+   26200             :                         }
+   26201             :                     }
+   26202             :                 }
+   26203           0 :             } else if (*direct=='B' || *direct=='b') {
+   26204           0 :                 for (j = *n - 1; j >= 1; --j) {
+   26205           0 :                     ctemp = c__[j];
+   26206           0 :                     stemp = s[j];
+   26207           0 :                     if (std::abs(ctemp-1.0)>PLUMED_GMX_FLOAT_EPS || std::abs(stemp)>PLUMED_GMX_FLOAT_MIN) {
+   26208           0 :                         i__1 = *m;
+   26209           0 :                         for (i__ = 1; i__ <= i__1; ++i__) {
+   26210           0 :                             temp = a[i__ + (j + 1) * a_dim1];
+   26211           0 :                             a[i__ + (j + 1) * a_dim1] = ctemp * temp - stemp *
+   26212           0 :                                      a[i__ + j * a_dim1];
+   26213           0 :                             a[i__ + j * a_dim1] = stemp * temp + ctemp * a[
+   26214           0 :                                     i__ + j * a_dim1];
+   26215             :                         }
+   26216             :                     }
+   26217             :                 }
+   26218             :             }
+   26219           0 :         } else if (*pivot=='T' || *pivot=='t') {
+   26220           0 :             if (*direct=='F' || *direct=='f') {
+   26221             :                 i__1 = *n;
+   26222           0 :                 for (j = 2; j <= i__1; ++j) {
+   26223           0 :                     ctemp = c__[j - 1];
+   26224           0 :                     stemp = s[j - 1];
+   26225           0 :                     if (std::abs(ctemp-1.0)>PLUMED_GMX_FLOAT_EPS || std::abs(stemp)>PLUMED_GMX_FLOAT_MIN) {
+   26226           0 :                         i__2 = *m;
+   26227           0 :                         for (i__ = 1; i__ <= i__2; ++i__) {
+   26228           0 :                             temp = a[i__ + j * a_dim1];
+   26229           0 :                             a[i__ + j * a_dim1] = ctemp * temp - stemp * a[
+   26230           0 :                                     i__ + a_dim1];
+   26231           0 :                             a[i__ + a_dim1] = stemp * temp + ctemp * a[i__ + 
+   26232           0 :                                     a_dim1];
+   26233             :                         }
+   26234             :                     }
+   26235             :                 }
+   26236           0 :             } else if (*direct=='B' || *direct=='b') {
+   26237           0 :                 for (j = *n; j >= 2; --j) {
+   26238           0 :                     ctemp = c__[j - 1];
+   26239           0 :                     stemp = s[j - 1];
+   26240           0 :                     if (std::abs(ctemp-1.0)>PLUMED_GMX_FLOAT_EPS || std::abs(stemp)>PLUMED_GMX_FLOAT_MIN) {
+   26241           0 :                         i__1 = *m;
+   26242           0 :                         for (i__ = 1; i__ <= i__1; ++i__) {
+   26243           0 :                             temp = a[i__ + j * a_dim1];
+   26244           0 :                             a[i__ + j * a_dim1] = ctemp * temp - stemp * a[
+   26245           0 :                                     i__ + a_dim1];
+   26246           0 :                             a[i__ + a_dim1] = stemp * temp + ctemp * a[i__ + 
+   26247           0 :                                     a_dim1];
+   26248             :                         }
+   26249             :                     }
+   26250             :                 }
+   26251             :             }
+   26252           0 :         } else if (*pivot=='B' || *pivot=='b') {
+   26253           0 :             if (*direct=='F' || *direct=='f') {
+   26254             :                 i__1 = *n - 1;
+   26255           0 :                 for (j = 1; j <= i__1; ++j) {
+   26256           0 :                     ctemp = c__[j];
+   26257           0 :                     stemp = s[j];
+   26258           0 :                     if (std::abs(ctemp-1.0)>PLUMED_GMX_FLOAT_EPS || std::abs(stemp)>PLUMED_GMX_FLOAT_MIN) {
+   26259           0 :                         i__2 = *m;
+   26260           0 :                         for (i__ = 1; i__ <= i__2; ++i__) {
+   26261           0 :                             temp = a[i__ + j * a_dim1];
+   26262           0 :                             a[i__ + j * a_dim1] = stemp * a[i__ + *n * a_dim1]
+   26263           0 :                                      + ctemp * temp;
+   26264           0 :                             a[i__ + *n * a_dim1] = ctemp * a[i__ + *n * 
+   26265           0 :                                     a_dim1] - stemp * temp;
+   26266             :                         }
+   26267             :                     }
+   26268             :                 }
+   26269           0 :             } else if (*direct=='B' || *direct=='b') {
+   26270           0 :                 for (j = *n - 1; j >= 1; --j) {
+   26271           0 :                     ctemp = c__[j];
+   26272           0 :                     stemp = s[j];
+   26273           0 :                     if (std::abs(ctemp-1.0)>PLUMED_GMX_FLOAT_EPS || std::abs(stemp)>PLUMED_GMX_FLOAT_MIN) {
+   26274           0 :                         i__1 = *m;
+   26275           0 :                         for (i__ = 1; i__ <= i__1; ++i__) {
+   26276           0 :                             temp = a[i__ + j * a_dim1];
+   26277           0 :                             a[i__ + j * a_dim1] = stemp * a[i__ + *n * a_dim1]
+   26278           0 :                                      + ctemp * temp;
+   26279           0 :                             a[i__ + *n * a_dim1] = ctemp * a[i__ + *n * 
+   26280           0 :                                     a_dim1] - stemp * temp;
+   26281             :                         }
+   26282             :                     }
+   26283             :                 }
+   26284             :             }
+   26285             :         }
+   26286             :     }
+   26287             : 
+   26288             :     return;
+   26289             : 
+   26290             : }
+   26291             : 
+   26292             : 
+   26293             : }
+   26294             : }
+   26295             : #include "lapack.h"
+   26296             : 
+   26297             : #include "blas/blas.h"
+   26298             : namespace PLMD{
+   26299             : namespace lapack{
+   26300             : using namespace blas;
+   26301             : void 
+   26302           0 : PLUMED_BLAS_F77_FUNC(slasrt,SLASRT)(const char *id, 
+   26303             :         int *n, 
+   26304             :         float *d__, 
+   26305             :         int *info)
+   26306             : {
+   26307             :     int i__1, i__2;
+   26308             : 
+   26309             :     int i__, j;
+   26310             :     float d1, d2, d3;
+   26311             :     int dir;
+   26312             :     float tmp;
+   26313             :     int endd;
+   26314             :     int stack[64];
+   26315             :     float dmnmx;
+   26316             :     int start;
+   26317             :     int stkpnt;
+   26318             : 
+   26319           0 :     --d__;
+   26320             : 
+   26321           0 :     *info = 0;
+   26322             :     dir = -1;
+   26323           0 :     if (*id=='D' || *id=='d') 
+   26324             :         dir = 0;
+   26325           0 :     else if (*id=='I' || *id=='i') 
+   26326             :         dir = 1;
+   26327             :    
+   26328             :     if (dir == -1) {
+   26329           0 :         *info = -1;
+   26330           0 :     } else if (*n < 0) {
+   26331           0 :         *info = -2;
+   26332             :     }
+   26333           0 :     if (*info != 0) {
+   26334             :         return;
+   26335             :     }
+   26336           0 :     if (*n <= 1) {
+   26337             :         return;
+   26338             :     }
+   26339             : 
+   26340             :     stkpnt = 1;
+   26341           0 :     stack[0] = 1;
+   26342           0 :     stack[1] = *n;
+   26343           0 : L10:
+   26344           0 :     start = stack[(stkpnt << 1) - 2];
+   26345           0 :     endd = stack[(stkpnt << 1) - 1];
+   26346           0 :     --stkpnt;
+   26347           0 :     if (endd - start <= 20 && endd - start > 0) {
+   26348             : 
+   26349             : 
+   26350           0 :         if (dir == 0) {
+   26351             : 
+   26352             :             i__1 = endd;
+   26353           0 :             for (i__ = start + 1; i__ <= i__1; ++i__) {
+   26354             :                 i__2 = start + 1;
+   26355           0 :                 for (j = i__; j >= i__2; --j) {
+   26356           0 :                     if (d__[j] > d__[j - 1]) {
+   26357             :                         dmnmx = d__[j];
+   26358           0 :                         d__[j] = d__[j - 1];
+   26359           0 :                         d__[j - 1] = dmnmx;
+   26360             :                     } else {
+   26361           0 :                         goto L30;
+   26362             :                     }
+   26363             :                 }
+   26364           0 : L30:
+   26365             :                 ;
+   26366             :             }
+   26367             : 
+   26368             :         } else {
+   26369             : 
+   26370             :             i__1 = endd;
+   26371           0 :             for (i__ = start + 1; i__ <= i__1; ++i__) {
+   26372             :                 i__2 = start + 1;
+   26373           0 :                 for (j = i__; j >= i__2; --j) {
+   26374           0 :                     if (d__[j] < d__[j - 1]) {
+   26375             :                         dmnmx = d__[j];
+   26376           0 :                         d__[j] = d__[j - 1];
+   26377           0 :                         d__[j - 1] = dmnmx;
+   26378             :                     } else {
+   26379           0 :                         goto L50;
+   26380             :                     }
+   26381             :                 }
+   26382           0 : L50:
+   26383             :                 ;
+   26384             :             }
+   26385             : 
+   26386             :         }
+   26387             : 
+   26388           0 :     } else if (endd - start > 20) {
+   26389             : 
+   26390           0 :         d1 = d__[start];
+   26391           0 :         d2 = d__[endd];
+   26392           0 :         i__ = (start + endd) / 2;
+   26393           0 :         d3 = d__[i__];
+   26394           0 :         if (d1 < d2) {
+   26395           0 :             if (d3 < d1) {
+   26396             :                 dmnmx = d1;
+   26397           0 :             } else if (d3 < d2) {
+   26398             :                 dmnmx = d3;
+   26399             :             } else {
+   26400             :                 dmnmx = d2;
+   26401             :             }
+   26402             :         } else {
+   26403           0 :             if (d3 < d2) {
+   26404             :                 dmnmx = d2;
+   26405           0 :             } else if (d3 < d1) {
+   26406             :                 dmnmx = d3;
+   26407             :             } else {
+   26408             :                 dmnmx = d1;
+   26409             :             }
+   26410             :         }
+   26411             : 
+   26412           0 :         if (dir == 0) {
+   26413             : 
+   26414           0 :             i__ = start - 1;
+   26415           0 :             j = endd + 1;
+   26416           0 : L60:
+   26417           0 : L70:
+   26418           0 :             --j;
+   26419           0 :             if (d__[j] < dmnmx) {
+   26420           0 :                 goto L70;
+   26421             :             }
+   26422           0 : L80:
+   26423           0 :             ++i__;
+   26424           0 :             if (d__[i__] > dmnmx) {
+   26425           0 :                 goto L80;
+   26426             :             }
+   26427           0 :             if (i__ < j) {
+   26428             :                 tmp = d__[i__];
+   26429           0 :                 d__[i__] = d__[j];
+   26430           0 :                 d__[j] = tmp;
+   26431           0 :                 goto L60;
+   26432             :             }
+   26433           0 :             if (j - start > endd - j - 1) {
+   26434             :                 ++stkpnt;
+   26435             :                 stack[(stkpnt << 1) - 2] = start;
+   26436           0 :                 stack[(stkpnt << 1) - 1] = j;
+   26437           0 :                 ++stkpnt;
+   26438           0 :                 stack[(stkpnt << 1) - 2] = j + 1;
+   26439           0 :                 stack[(stkpnt << 1) - 1] = endd;
+   26440             :             } else {
+   26441             :                 ++stkpnt;
+   26442           0 :                 stack[(stkpnt << 1) - 2] = j + 1;
+   26443           0 :                 stack[(stkpnt << 1) - 1] = endd;
+   26444           0 :                 ++stkpnt;
+   26445           0 :                 stack[(stkpnt << 1) - 2] = start;
+   26446           0 :                 stack[(stkpnt << 1) - 1] = j;
+   26447             :             }
+   26448             :         } else {
+   26449             : 
+   26450           0 :             i__ = start - 1;
+   26451           0 :             j = endd + 1;
+   26452           0 : L90:
+   26453           0 : L100:
+   26454           0 :             --j;
+   26455           0 :             if (d__[j] > dmnmx) {
+   26456           0 :                 goto L100;
+   26457             :             }
+   26458           0 : L110:
+   26459           0 :             ++i__;
+   26460           0 :             if (d__[i__] < dmnmx) {
+   26461           0 :                 goto L110;
+   26462             :             }
+   26463           0 :             if (i__ < j) {
+   26464             :                 tmp = d__[i__];
+   26465           0 :                 d__[i__] = d__[j];
+   26466           0 :                 d__[j] = tmp;
+   26467           0 :                 goto L90;
+   26468             :             }
+   26469           0 :             if (j - start > endd - j - 1) {
+   26470             :                 ++stkpnt;
+   26471             :                 stack[(stkpnt << 1) - 2] = start;
+   26472           0 :                 stack[(stkpnt << 1) - 1] = j;
+   26473           0 :                 ++stkpnt;
+   26474           0 :                 stack[(stkpnt << 1) - 2] = j + 1;
+   26475           0 :                 stack[(stkpnt << 1) - 1] = endd;
+   26476             :             } else {
+   26477             :                 ++stkpnt;
+   26478           0 :                 stack[(stkpnt << 1) - 2] = j + 1;
+   26479           0 :                 stack[(stkpnt << 1) - 1] = endd;
+   26480           0 :                 ++stkpnt;
+   26481           0 :                 stack[(stkpnt << 1) - 2] = start;
+   26482           0 :                 stack[(stkpnt << 1) - 1] = j;
+   26483             :             }
+   26484             :         }
+   26485             :     }
+   26486           0 :     if (stkpnt > 0) {
+   26487           0 :         goto L10;
+   26488             :     }
+   26489             :     return;
+   26490             : 
+   26491             : }
+   26492             : }
+   26493             : }
+   26494             : #include "lapack.h"
+   26495             : #include "blas/blas.h"
+   26496             : namespace PLMD{
+   26497             : namespace lapack{
+   26498             : using namespace blas;
+   26499             : 
+   26500           0 : void PLUMED_BLAS_F77_FUNC(slasrt2,SLASRT2)(const char *id, 
+   26501             :               int *n, 
+   26502             :               float *d__, 
+   26503             :               int * key, 
+   26504             :               int *info)
+   26505             : {
+   26506             :     int i__1, i__2;
+   26507             : 
+   26508             :     int i__, j;
+   26509             :     float d1, d2, d3;
+   26510             :     int dir;
+   26511             :     float tmp;
+   26512             :     int endd;
+   26513             :     int stack[64];
+   26514             :     float dmnmx;
+   26515             :     int start;
+   26516             :     int tmpkey, stkpnt;
+   26517             : 
+   26518           0 :     --key;
+   26519           0 :     --d__;
+   26520             : 
+   26521           0 :     *info = 0;
+   26522             :     dir = -1;
+   26523           0 :     if (*id=='D' || *id=='d')
+   26524             :         dir = 0;
+   26525           0 :     else if (*id=='I' || *id=='i')
+   26526             :         dir = 1;
+   26527             :     
+   26528             :     if (dir == -1) {
+   26529           0 :         *info = -1;
+   26530           0 :     } else if (*n < 0) {
+   26531           0 :         *info = -2;
+   26532             :     }
+   26533           0 :     if (*info != 0) {
+   26534             :         return;
+   26535             :     }
+   26536             : 
+   26537           0 :     if (*n <= 1) {
+   26538             :         return;
+   26539             :     }
+   26540             : 
+   26541             :     stkpnt = 1;
+   26542           0 :     stack[0] = 1;
+   26543           0 :     stack[1] = *n;
+   26544           0 : L10:
+   26545           0 :     start = stack[(stkpnt << 1) - 2];
+   26546           0 :     endd = stack[(stkpnt << 1) - 1];
+   26547           0 :     --stkpnt;
+   26548           0 :     if (endd - start > 0) {
+   26549             : 
+   26550           0 :         if (dir == 0) {
+   26551             : 
+   26552             :             i__1 = endd;
+   26553           0 :             for (i__ = start + 1; i__ <= i__1; ++i__) {
+   26554             :                 i__2 = start + 1;
+   26555           0 :                 for (j = i__; j >= i__2; --j) {
+   26556           0 :                     if (d__[j] > d__[j - 1]) {
+   26557             :                         dmnmx = d__[j];
+   26558           0 :                         d__[j] = d__[j - 1];
+   26559           0 :                         d__[j - 1] = dmnmx;
+   26560           0 :                         tmpkey = key[j];
+   26561           0 :                         key[j] = key[j - 1];
+   26562           0 :                         key[j - 1] = tmpkey;
+   26563             :                     } else {
+   26564             :                         break;
+   26565             :                     }
+   26566             :                 }
+   26567             :             }
+   26568             : 
+   26569             :         } else {
+   26570             : 
+   26571             :             i__1 = endd;
+   26572           0 :             for (i__ = start + 1; i__ <= i__1; ++i__) {
+   26573             :                 i__2 = start + 1;
+   26574           0 :                 for (j = i__; j >= i__2; --j) {
+   26575           0 :                     if (d__[j] < d__[j - 1]) {
+   26576             :                         dmnmx = d__[j];
+   26577           0 :                         d__[j] = d__[j - 1];
+   26578           0 :                         d__[j - 1] = dmnmx;
+   26579           0 :                         tmpkey = key[j];
+   26580           0 :                         key[j] = key[j - 1];
+   26581           0 :                         key[j - 1] = tmpkey;
+   26582             :                     } else {
+   26583             :                         break;
+   26584             :                     }
+   26585             :                 }
+   26586             :             }
+   26587             : 
+   26588             :         }
+   26589             : 
+   26590           0 :     } else if (endd - start > 20) {
+   26591             : 
+   26592           0 :         d1 = d__[start];
+   26593           0 :         d2 = d__[endd];
+   26594           0 :         i__ = (start + endd) / 2;
+   26595           0 :         d3 = d__[i__];
+   26596           0 :         if (d1 < d2) {
+   26597           0 :             if (d3 < d1) {
+   26598             :                 dmnmx = d1;
+   26599           0 :             } else if (d3 < d2) {
+   26600             :                 dmnmx = d3;
+   26601             :             } else {
+   26602             :                 dmnmx = d2;
+   26603             :             }
+   26604             :         } else {
+   26605           0 :             if (d3 < d2) {
+   26606             :                 dmnmx = d2;
+   26607           0 :             } else if (d3 < d1) {
+   26608             :                 dmnmx = d3;
+   26609             :             } else {
+   26610             :                 dmnmx = d1;
+   26611             :             }
+   26612             :         }
+   26613             : 
+   26614           0 :         if (dir == 0) {
+   26615             : 
+   26616           0 :             i__ = start - 1;
+   26617           0 :             j = endd + 1;
+   26618           0 : L60:
+   26619           0 : L70:
+   26620           0 :             --j;
+   26621           0 :             if (d__[j] < dmnmx) {
+   26622           0 :                 goto L70;
+   26623             :             }
+   26624           0 : L80:
+   26625           0 :             ++i__;
+   26626           0 :             if (d__[i__] > dmnmx) {
+   26627           0 :                 goto L80;
+   26628             :             }
+   26629           0 :             if (i__ < j) {
+   26630             :                 tmp = d__[i__];
+   26631           0 :                 d__[i__] = d__[j];
+   26632           0 :                 d__[j] = tmp;
+   26633           0 :                 tmpkey = key[j];
+   26634           0 :                 key[j] = key[i__];
+   26635           0 :                 key[i__] = tmpkey;
+   26636           0 :                 goto L60;
+   26637             :             }
+   26638           0 :             if (j - start > endd - j - 1) {
+   26639             :                 ++stkpnt;
+   26640             :                 stack[(stkpnt << 1) - 2] = start;
+   26641           0 :                 stack[(stkpnt << 1) - 1] = j;
+   26642           0 :                 ++stkpnt;
+   26643           0 :                 stack[(stkpnt << 1) - 2] = j + 1;
+   26644           0 :                 stack[(stkpnt << 1) - 1] = endd;
+   26645             :             } else {
+   26646             :                 ++stkpnt;
+   26647           0 :                 stack[(stkpnt << 1) - 2] = j + 1;
+   26648           0 :                 stack[(stkpnt << 1) - 1] = endd;
+   26649           0 :                 ++stkpnt;
+   26650           0 :                 stack[(stkpnt << 1) - 2] = start;
+   26651           0 :                 stack[(stkpnt << 1) - 1] = j;
+   26652             :             }
+   26653             :         } else {
+   26654             : 
+   26655           0 :             i__ = start - 1;
+   26656           0 :             j = endd + 1;
+   26657           0 : L90:
+   26658           0 : L100:
+   26659           0 :             --j;
+   26660           0 :             if (d__[j] > dmnmx) {
+   26661           0 :                 goto L100;
+   26662             :             }
+   26663           0 : L110:
+   26664           0 :             ++i__;
+   26665           0 :             if (d__[i__] < dmnmx) {
+   26666           0 :                 goto L110;
+   26667             :             }
+   26668           0 :             if (i__ < j) {
+   26669             :                 tmp = d__[i__];
+   26670           0 :                 d__[i__] = d__[j];
+   26671           0 :                 d__[j] = tmp;
+   26672           0 :                 tmpkey = key[j];
+   26673           0 :                 key[j] = key[i__];
+   26674           0 :                 key[i__] = tmpkey;
+   26675           0 :                 goto L90;
+   26676             :             }
+   26677           0 :             if (j - start > endd - j - 1) {
+   26678             :                 ++stkpnt;
+   26679             :                 stack[(stkpnt << 1) - 2] = start;
+   26680           0 :                 stack[(stkpnt << 1) - 1] = j;
+   26681           0 :                 ++stkpnt;
+   26682           0 :                 stack[(stkpnt << 1) - 2] = j + 1;
+   26683           0 :                 stack[(stkpnt << 1) - 1] = endd;
+   26684             :             } else {
+   26685             :                 ++stkpnt;
+   26686           0 :                 stack[(stkpnt << 1) - 2] = j + 1;
+   26687           0 :                 stack[(stkpnt << 1) - 1] = endd;
+   26688           0 :                 ++stkpnt;
+   26689           0 :                 stack[(stkpnt << 1) - 2] = start;
+   26690           0 :                 stack[(stkpnt << 1) - 1] = j;
+   26691             :             }
+   26692             :         }
+   26693             :     }
+   26694           0 :     if (stkpnt > 0) {
+   26695           0 :         goto L10;
+   26696             :     }
+   26697             : 
+   26698             :     return;
+   26699             : }
+   26700             : }
+   26701             : }
+   26702             : #include <cmath>
+   26703             : #include "real.h"
+   26704             : #include "lapack.h"
+   26705             : 
+   26706             : #include "blas/blas.h"
+   26707             : namespace PLMD{
+   26708             : namespace lapack{
+   26709             : using namespace blas;
+   26710             : void
+   26711           0 : PLUMED_BLAS_F77_FUNC(slassq,SLASSQ)(int *n,
+   26712             :                         float *x,
+   26713             :                         int *incx,
+   26714             :                         float *scale,
+   26715             :                         float *sumsq)
+   26716             : {
+   26717             :   int ix;
+   26718             :   float absxi,t;
+   26719             : 
+   26720           0 :   if(*n>0) {
+   26721           0 :     for(ix=0;ix<=(*n-1)*(*incx);ix+=*incx) {
+   26722           0 :       if(std::abs(x[ix])>PLUMED_GMX_FLOAT_MIN) {
+   26723             :         absxi = std::abs(x[ix]);
+   26724           0 :         if(*scale<absxi) {
+   26725           0 :           t = *scale/absxi;
+   26726           0 :           t = t*t;
+   26727           0 :           *sumsq = 1.0 + (*sumsq)*t;
+   26728           0 :           *scale = absxi;
+   26729             :         } else {
+   26730           0 :           t = absxi/(*scale);
+   26731           0 :           *sumsq += t*t;
+   26732             :         }
+   26733             :       }
+   26734             :     }
+   26735             :   }
+   26736           0 :   return;
+   26737             : }
+   26738             : }
+   26739             : }
+   26740             : #include <cmath>
+   26741             : #include "lapack.h"
+   26742             : #include "lapack_limits.h"
+   26743             : 
+   26744             : #include "real.h"
+   26745             : 
+   26746             : #include "blas/blas.h"
+   26747             : namespace PLMD{
+   26748             : namespace lapack{
+   26749             : using namespace blas;
+   26750             : void 
+   26751           0 : PLUMED_BLAS_F77_FUNC(slasv2,SLASV2)(float *f, 
+   26752             :                         float *g, 
+   26753             :                         float *h__, 
+   26754             :                         float *ssmin, 
+   26755             :                         float *ssmax, 
+   26756             :                         float *snr, 
+   26757             :                         float *csr, 
+   26758             :                         float *snl, 
+   26759             :                         float *csl)
+   26760             : {
+   26761             :     float d__1;
+   26762             : 
+   26763             :     float a, d__, l, m, r__, s, t, fa, ga, ha, ft, gt, ht, mm, tt,
+   26764             :              clt, crt, slt, srt;
+   26765             :     int pmax;
+   26766             :     float temp;
+   26767             :     int swap;
+   26768             :     float tsign=1.0;
+   26769             :     int gasmal;
+   26770             : 
+   26771           0 :     ft = *f;
+   26772             :     fa = std::abs(ft);
+   26773           0 :     ht = *h__;
+   26774             :     ha = std::abs(*h__);
+   26775             : 
+   26776             :     pmax = 1;
+   26777             :     swap = ha > fa;
+   26778           0 :     if (swap) {
+   26779             :         pmax = 3;
+   26780             :         temp = ft;
+   26781             :         ft = ht;
+   26782             :         ht = temp;
+   26783             :         temp = fa;
+   26784             :         fa = ha;
+   26785             :         ha = temp;
+   26786             : 
+   26787             :     }
+   26788           0 :     gt = *g;
+   26789             :     ga = std::abs(gt);
+   26790           0 :     if (std::abs(ga)<PLUMED_GMX_FLOAT_MIN) {
+   26791             : 
+   26792           0 :         *ssmin = ha;
+   26793           0 :         *ssmax = fa;
+   26794             :         clt = 1.;
+   26795             :         crt = 1.;
+   26796             :         slt = 0.;
+   26797             :         srt = 0.;
+   26798             :     } else {
+   26799             :         gasmal = 1;
+   26800           0 :         if (ga > fa) {
+   26801             :             pmax = 2;
+   26802           0 :             if (fa / ga < PLUMED_GMX_FLOAT_EPS) {
+   26803             : 
+   26804             :                 gasmal = 0;
+   26805           0 :                 *ssmax = ga;
+   26806           0 :                 if (ha > 1.) {
+   26807           0 :                     *ssmin = fa / (ga / ha);
+   26808             :                 } else {
+   26809           0 :                     *ssmin = fa / ga * ha;
+   26810             :                 }
+   26811             :                 clt = 1.;
+   26812           0 :                 slt = ht / gt;
+   26813             :                 srt = 1.;
+   26814           0 :                 crt = ft / gt;
+   26815             :             }
+   26816             :         }
+   26817           0 :         if (gasmal) {
+   26818             : 
+   26819           0 :             d__ = fa - ha;
+   26820           0 :             if ( std::abs( fa - d__ )<PLUMED_GMX_FLOAT_EPS*std::abs( fa + d__ )) {
+   26821             :                 l = 1.;
+   26822             :             } else {
+   26823           0 :                 l = d__ / fa;
+   26824             :             }
+   26825             : 
+   26826           0 :             m = gt / ft;
+   26827           0 :             t = 2. - l;
+   26828             : 
+   26829           0 :             mm = m * m;
+   26830           0 :             tt = t * t;
+   26831           0 :             s =  std::sqrt(tt + mm);
+   26832             : 
+   26833           0 :             if ( std::abs(l)<PLUMED_GMX_FLOAT_MIN) {
+   26834             :                 r__ = std::abs(m);
+   26835             :             } else {
+   26836           0 :                 r__ =  std::sqrt(l * l + mm);
+   26837             :             }
+   26838           0 :             a = (s + r__) * .5;
+   26839             : 
+   26840           0 :             *ssmin = ha / a;
+   26841           0 :             *ssmax = fa * a;
+   26842           0 :             if ( std::abs(mm)<PLUMED_GMX_FLOAT_MIN) {
+   26843             : 
+   26844           0 :                 if (std::abs(l)<PLUMED_GMX_FLOAT_MIN) {
+   26845           0 :                     t = ( (ft>0) ? 2.0 : -2.0) * ( (gt>0) ? 1.0 : -1.0);
+   26846             :                 } else {
+   26847           0 :                     t = gt / ( (ft>0) ? d__ : -d__) + m / t;
+   26848             :                 }
+   26849             :             } else {
+   26850           0 :                 t = (m / (s + t) + m / (r__ + l)) * (a + 1.);
+   26851             :             }
+   26852           0 :             l =  std::sqrt(t * t + 4.);
+   26853           0 :             crt = 2. / l;
+   26854           0 :             srt = t / l;
+   26855           0 :             clt = (crt + srt * m) / a;
+   26856           0 :             slt = ht / ft * srt / a;
+   26857             :         }
+   26858             :     }
+   26859           0 :     if (swap) {
+   26860           0 :         *csl = srt;
+   26861           0 :         *snl = crt;
+   26862           0 :         *csr = slt;
+   26863           0 :         *snr = clt;
+   26864             :     } else {
+   26865           0 :         *csl = clt;
+   26866           0 :         *snl = slt;
+   26867           0 :         *csr = crt;
+   26868           0 :         *snr = srt;
+   26869             :     }
+   26870             : 
+   26871           0 :     if (pmax == 1) {
+   26872           0 :         tsign = ( (*csr>0) ? 1.0 : -1.0) * ( (*csl>0) ? 1.0 : -1.0) * ( (*f>0) ? 1.0 : -1.0);
+   26873             :     }
+   26874           0 :     if (pmax == 2) {
+   26875           0 :         tsign = ( (*snr>0) ? 1.0 : -1.0) * ( (*csl>0) ? 1.0 : -1.0) * ( (*g>0) ? 1.0 : -1.0);
+   26876             :     }
+   26877           0 :     if (pmax == 3) {
+   26878           0 :         tsign = ( (*snr>0) ? 1.0 : -1.0) * ( (*snl>0) ? 1.0 : -1.0) * ( (*h__>0) ? 1.0 : -1.0);
+   26879             :     }
+   26880           0 :     if(tsign<0)
+   26881           0 :       *ssmax *= -1.0;
+   26882           0 :     d__1 = tsign * ( (*f>0) ? 1.0 : -1.0) * ( (*h__>0) ? 1.0 : -1.0);
+   26883           0 :     if(d__1<0)
+   26884           0 :       *ssmin *= -1.0;
+   26885           0 :     return;
+   26886             : 
+   26887             : }
+   26888             : }
+   26889             : }
+   26890             : #include "lapack.h"
+   26891             : 
+   26892             : /* LAPACK */
+   26893             : #include "blas/blas.h"
+   26894             : namespace PLMD{
+   26895             : namespace lapack{
+   26896             : using namespace blas;
+   26897             : void
+   26898           0 : PLUMED_BLAS_F77_FUNC(slaswp,SLASWP)(int *n,
+   26899             :         float *a,
+   26900             :         int *lda,
+   26901             :         int *k1,
+   26902             :         int *k2,
+   26903             :         int *ipiv,
+   26904             :         int *incx)
+   26905             : {
+   26906             :   int ix0,i1,i2,inc,n32;
+   26907             :   int ix,i,j,ip,k;
+   26908             :   float temp;
+   26909             : 
+   26910           0 :   if(*incx>0) {
+   26911           0 :     ix0 = *k1 - 1;
+   26912             :     i1 = *k1 - 1;
+   26913           0 :     i2 = *k2;
+   26914             :     inc = 1;
+   26915           0 :   } else if(*incx<0) {
+   26916           0 :     ix0 = *incx * (1- *k2);
+   26917           0 :     i1 = *k2 - 1;
+   26918           0 :     i2 = *k1;
+   26919             :     inc = -1;
+   26920             :   } else
+   26921             :     return;
+   26922             : 
+   26923           0 :   n32 = *n / 32;
+   26924             :   
+   26925           0 :   n32 *= 32;
+   26926             : 
+   26927             : 
+   26928           0 :   if(n32!=0) {
+   26929           0 :     for(j=0;j<n32;j+=32) {
+   26930             :       ix = ix0;
+   26931           0 :       for(i=i1;i<i2;i+=inc,ix+=*incx) {
+   26932           0 :         ip = ipiv[ix] - 1;
+   26933           0 :         if(ip != i) {
+   26934           0 :           for(k=j;k<j+32;k++) {
+   26935           0 :             temp = a[(k)*(*lda)+i];
+   26936           0 :             a[(k)*(*lda)+i] = a[(k)*(*lda)+ip];
+   26937           0 :             a[(k)*(*lda)+ip] = temp;
+   26938             :           }
+   26939             :         }
+   26940             :       }
+   26941             :     }
+   26942             :   }
+   26943           0 :   if(n32!=*n) {
+   26944             :     ix = ix0;
+   26945           0 :     for(i=i1;i<i2;i+=inc,ix+=*incx) {
+   26946           0 :       ip = ipiv[ix] - 1;
+   26947           0 :       if(ip != i) {
+   26948           0 :         for(k=n32;k<*n;k++) {
+   26949           0 :             temp = a[(k)*(*lda)+i];
+   26950           0 :             a[(k)*(*lda)+i] = a[(k)*(*lda)+ip];
+   26951           0 :             a[(k)*(*lda)+ip] = temp;
+   26952             :         }
+   26953             :       }
+   26954             :     }
+   26955             :   }
+   26956             :   return;
+   26957             : }
+   26958             : }
+   26959             : }
+   26960             : #include <cctype>
+   26961             : #include "blas/blas.h"
+   26962             : #include "lapack.h"
+   26963             : #include "lapack_limits.h"
+   26964             : 
+   26965             : 
+   26966             : #include "blas/blas.h"
+   26967             : namespace PLMD{
+   26968             : namespace lapack{
+   26969             : using namespace blas;
+   26970             : void
+   26971           0 : PLUMED_BLAS_F77_FUNC(slatrd,SLATRD)(const char *  uplo,
+   26972             :        int  *   n,
+   26973             :        int  *   nb,
+   26974             :        float * a,
+   26975             :        int *    lda,
+   26976             :        float * e,
+   26977             :        float * tau,
+   26978             :        float * w,
+   26979             :        int *    ldw)
+   26980             : {
+   26981             :   int i,iw;
+   26982             :   int ti1,ti2,ti3;
+   26983             :   float one,zero,minusone,alpha;
+   26984           0 :   const char ch=std::toupper(*uplo);
+   26985             : 
+   26986           0 :   one=1.0;
+   26987           0 :   minusone=-1.0;
+   26988           0 :   zero=0.0;
+   26989             : 
+   26990           0 :   if(*n<=0)
+   26991             :     return;
+   26992             : 
+   26993           0 :   if(ch=='U') {
+   26994           0 :     for(i=*n;i>=(*n-*nb+1);i--) {
+   26995           0 :       iw = i -*n + *nb;
+   26996             :       
+   26997           0 :       if(i<*n) {
+   26998           0 :         ti1 = *n-i;
+   26999           0 :         ti2 = 1;
+   27000             :         /* BLAS */
+   27001           0 :         PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("N",&i,&ti1,&minusone, &(a[ i*(*lda) + 0]),lda,&(w[iw*(*ldw)+(i-1)]),
+   27002           0 :                ldw,&one, &(a[ (i-1)*(*lda) + 0]), &ti2);
+   27003             :         /* BLAS */
+   27004           0 :         PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("N",&i,&ti1,&minusone, &(w[ iw*(*ldw) + 0]),ldw,&(a[i*(*lda)+(i-1)]),
+   27005           0 :                lda,&one, &(a[ (i-1)*(*lda) + 0]), &ti2);
+   27006             :       }
+   27007             : 
+   27008           0 :       if(i>1) {
+   27009             :         /*  Generate elementary reflector H(i) to annihilate
+   27010             :          *              A(1:i-2,i) 
+   27011             :          */
+   27012           0 :         ti1 = i-1;
+   27013           0 :         ti2 = 1;
+   27014             : 
+   27015             :         /* LAPACK */
+   27016           0 :         PLUMED_BLAS_F77_FUNC(slarfg,SLARFG)(&ti1,&(a[(i-1)*(*lda)+(i-2)]),&(a[(i-1)*(*lda)+0]),&ti2,&(tau[i-2]));
+   27017             :       
+   27018           0 :         e[i-2] = a[(i-1)*(*lda)+(i-2)];
+   27019           0 :         a[(i-1)*(*lda)+(i-2)] = 1.0;
+   27020             : 
+   27021             :         /* Compute W(1:i-1,i) */
+   27022           0 :         ti1 = i-1;
+   27023           0 :         ti2 = 1;
+   27024             : 
+   27025             :         /* BLAS */
+   27026           0 :         PLUMED_BLAS_F77_FUNC(ssymv,SSYMV)("U",&ti1,&one,a,lda,&(a[(i-1)*(*lda)+0]),&ti2,&zero,
+   27027           0 :                &(w[(iw-1)*(*ldw)+0]),&ti2);
+   27028           0 :         if(i<*n) {
+   27029           0 :           ti1 = i-1;
+   27030           0 :           ti2 = *n-i;
+   27031           0 :           ti3 = 1;
+   27032             :           /* BLAS */
+   27033           0 :           PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("T",&ti1,&ti2,&one,&(w[iw*(*ldw)+0]),ldw,&(a[(i-1)*(*lda)+0]),&ti3,
+   27034           0 :                  &zero,&(w[(iw-1)*(*ldw)+i]),&ti3);
+   27035             :         
+   27036             :           /* BLAS */
+   27037           0 :           PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("N",&ti1,&ti2,&minusone,&(a[i*(*lda)+0]),lda,&(w[(iw-1)*(*ldw)+i]),&ti3,
+   27038           0 :                  &one,&(w[(iw-1)*(*ldw)+0]),&ti3);
+   27039             :         
+   27040             :           /* BLAS */
+   27041           0 :           PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("T",&ti1,&ti2,&one,&(a[i*(*lda)+0]),lda,&(a[(i-1)*(*lda)+0]),&ti3,
+   27042           0 :                  &zero,&(w[(iw-1)*(*ldw)+i]),&ti3);
+   27043             :         
+   27044             :           /* BLAS */
+   27045           0 :           PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("N",&ti1,&ti2,&minusone,&(w[iw*(*ldw)+0]),ldw,&(w[(iw-1)*(*ldw)+i]),&ti3,
+   27046           0 :                  &one,&(w[(iw-1)*(*ldw)+0]),&ti3);
+   27047             :         }
+   27048             :       
+   27049           0 :         ti1 = i-1;
+   27050           0 :         ti2 = 1;
+   27051             :         /* BLAS */
+   27052           0 :         PLUMED_BLAS_F77_FUNC(sscal,SSCAL)(&ti1,&(tau[i-2]),&(w[(iw-1)*(*ldw)+0]),&ti2);
+   27053             :       
+   27054           0 :         alpha = -0.5*tau[i-2]*PLUMED_BLAS_F77_FUNC(sdot,SDOT)(&ti1,&(w[(iw-1)*(*ldw)+0]),&ti2,
+   27055           0 :                                     &(a[(i-1)*(*lda)+0]),&ti2);
+   27056             :       
+   27057             :         /* BLAS */
+   27058           0 :         PLUMED_BLAS_F77_FUNC(saxpy,SAXPY)(&ti1,&alpha,&(a[(i-1)*(*lda)+0]),&ti2,&(w[(iw-1)*(*ldw)+0]),&ti2);
+   27059             : 
+   27060             :       }
+   27061             :     }
+   27062             :   } else {
+   27063             :     /* lower */
+   27064           0 :     for(i=1;i<=*nb;i++) {
+   27065             : 
+   27066           0 :       ti1 = *n-i+1;
+   27067           0 :       ti2 = i-1;
+   27068           0 :       ti3 = 1;
+   27069             :       /* BLAS */
+   27070           0 :       PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("N",&ti1,&ti2,&minusone, &(a[ i-1 ]),lda,&(w[ i-1 ]),
+   27071           0 :                ldw,&one, &(a[ (i-1)*(*lda) + (i-1)]), &ti3);
+   27072             :       /* BLAS */
+   27073           0 :       PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("N",&ti1,&ti2,&minusone, &(w[ i-1 ]),ldw,&(a[ i-1 ]),
+   27074           0 :                lda,&one, &(a[ (i-1)*(*lda) + (i-1)]), &ti3);
+   27075             : 
+   27076           0 :       if(i<*n) {
+   27077           0 :         ti1 = *n - i;
+   27078           0 :         ti2 = (*n < i+2 ) ? *n : (i+2);
+   27079           0 :         ti3 = 1;
+   27080             :         /* LAPACK */
+   27081           0 :         PLUMED_BLAS_F77_FUNC(slarfg,SLARFG)(&ti1,&(a[(i-1)*(*lda)+(i)]),&(a[(i-1)*(*lda)+(ti2-1)]),&ti3,&(tau[i-1]));
+   27082           0 :         e[i-1] = a[(i-1)*(*lda)+(i)];
+   27083           0 :         a[(i-1)*(*lda)+(i)] = 1.0;
+   27084             :         
+   27085           0 :         ti1 = *n - i;
+   27086           0 :         ti2 = 1;
+   27087           0 :         PLUMED_BLAS_F77_FUNC(ssymv,SSYMV)("L",&ti1,&one,&(a[i*(*lda)+i]),lda,&(a[(i-1)*(*lda)+i]),&ti2,
+   27088           0 :                &zero,&(w[(i-1)*(*ldw)+i]),&ti2);
+   27089           0 :         ti1 = *n - i;
+   27090           0 :         ti2 = i-1;
+   27091           0 :         ti3 = 1;
+   27092             :         /* BLAS */
+   27093           0 :         PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("T",&ti1,&ti2,&one,&(w[ i ]),ldw,&(a[(i-1)*(*lda)+i]),&ti3,
+   27094           0 :                &zero,&(w[(i-1)*(*ldw)+0]),&ti3);
+   27095             :         
+   27096             :         /* BLAS */
+   27097           0 :         PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("N",&ti1,&ti2,&minusone,&(a[ i ]),lda,&(w[(i-1)*(*ldw)+0]),&ti3,
+   27098           0 :                &one,&(w[(i-1)*(*ldw)+i]),&ti3);
+   27099             :         
+   27100             :         /* BLAS */
+   27101           0 :         PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("T",&ti1,&ti2,&one,&(a[ i ]),lda,&(a[(i-1)*(*lda)+i]),&ti3,
+   27102           0 :                &zero,&(w[(i-1)*(*ldw)+0]),&ti3);
+   27103             :         
+   27104             :         /* BLAS */
+   27105           0 :         PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("N",&ti1,&ti2,&minusone,&(w[ i ]),ldw,&(w[(i-1)*(*ldw)+0]),&ti3,
+   27106           0 :                &one,&(w[(i-1)*(*ldw)+i]),&ti3);
+   27107             : 
+   27108           0 :         PLUMED_BLAS_F77_FUNC(sscal,SSCAL)(&ti1,&(tau[i-1]),&(w[(i-1)*(*ldw)+i]),&ti3);
+   27109           0 :         alpha = -0.5*tau[i-1]*PLUMED_BLAS_F77_FUNC(sdot,SDOT)(&ti1,&(w[(i-1)*(*ldw)+i]),&ti3,
+   27110           0 :                                    &(a[(i-1)*(*lda)+i]),&ti3);
+   27111             :         
+   27112           0 :         PLUMED_BLAS_F77_FUNC(saxpy,SAXPY)(&ti1,&alpha,&(a[(i-1)*(*lda)+i]),&ti3,&(w[(i-1)*(*ldw)+i]),&ti3);
+   27113             :       }
+   27114             :     }
+   27115             :   }
+   27116             :   return;
+   27117             : }
+   27118             :         
+   27119             : 
+   27120             : 
+   27121             :   
+   27122             : }
+   27123             : }
+   27124             : #include <cmath>
+   27125             : 
+   27126             : #include "blas/blas.h"
+   27127             : #include "lapack.h"
+   27128             : 
+   27129             : #include "blas/blas.h"
+   27130             : namespace PLMD{
+   27131             : namespace lapack{
+   27132             : using namespace blas;
+   27133             : void 
+   27134           0 : PLUMED_BLAS_F77_FUNC(sorg2r,SORG2R)(int *m, 
+   27135             :                         int *n,
+   27136             :                         int *k, 
+   27137             :                         float *a, 
+   27138             :                         int *lda,
+   27139             :                         float *tau,
+   27140             :                         float *work,
+   27141             :                         int *info)
+   27142             : {
+   27143             :     int a_dim1, a_offset, i__1, i__2;
+   27144             :     float r__1;
+   27145           0 :     int c__1 = 1;
+   27146             : 
+   27147             :     int i__, j, l;
+   27148             : 
+   27149           0 :     a_dim1 = *lda;
+   27150           0 :     a_offset = 1 + a_dim1;
+   27151           0 :     a -= a_offset;
+   27152           0 :     --tau;
+   27153             :     --work;
+   27154             : 
+   27155           0 :     *info = 0;
+   27156             : 
+   27157           0 :     if (*n <= 0) {
+   27158             :         return;
+   27159             :     }
+   27160             : 
+   27161           0 :     i__1 = *n;
+   27162           0 :     for (j = *k + 1; j <= i__1; ++j) {
+   27163           0 :         i__2 = *m;
+   27164           0 :         for (l = 1; l <= i__2; ++l) {
+   27165           0 :             a[l + j * a_dim1] = 0.0;
+   27166             :         }
+   27167           0 :         a[j + j * a_dim1] = 1.0;
+   27168             :     }
+   27169           0 :     for (i__ = *k; i__ >= 1; --i__) {
+   27170           0 :         if (i__ < *n) {
+   27171           0 :             a[i__ + i__ * a_dim1] = 1.0;
+   27172           0 :             i__1 = *m - i__ + 1;
+   27173           0 :             i__2 = *n - i__;
+   27174           0 :             PLUMED_BLAS_F77_FUNC(slarf,SLARF)("L", &i__1, &i__2, &a[i__ + i__ * a_dim1], &c__1, 
+   27175           0 :                               &tau[i__], &a[i__ + (i__ + 1) * a_dim1], lda, &work[1]);
+   27176             :         }
+   27177           0 :         if (i__ < *m) {
+   27178           0 :             i__1 = *m - i__;
+   27179           0 :             r__1 = -tau[i__];
+   27180           0 :             PLUMED_BLAS_F77_FUNC(sscal,SSCAL)(&i__1, &r__1, &a[i__ + 1 + i__ * a_dim1], &c__1);
+   27181             :         }
+   27182           0 :         a[i__ + i__ * a_dim1] = 1.0 - tau[i__];
+   27183           0 :         i__1 = i__ - 1;
+   27184           0 :         for (l = 1; l <= i__1; ++l) {
+   27185           0 :             a[l + i__ * a_dim1] = 0.0;
+   27186             :         }
+   27187             :     }
+   27188             :     return;
+   27189             : 
+   27190             : }
+   27191             : 
+   27192             : 
+   27193             : }
+   27194             : }
+   27195             : #include "lapack.h"
+   27196             : #include "lapack_limits.h"
+   27197             : 
+   27198             : #include "blas/blas.h"
+   27199             : namespace PLMD{
+   27200             : namespace lapack{
+   27201             : using namespace blas;
+   27202             : void
+   27203           0 : PLUMED_BLAS_F77_FUNC(sorgbr,SORGBR)(const char *vect,
+   27204             :         int *m,
+   27205             :         int *n,
+   27206             :         int *k,
+   27207             :         float *a,
+   27208             :         int *lda,
+   27209             :         float *tau,
+   27210             :         float *work,
+   27211             :         int *lwork,
+   27212             :         int *info)
+   27213             : {
+   27214             :   int wantq,iinfo,j,i,i1,wrksz;
+   27215           0 :   int mn = (*m < *n) ? *m : *n;
+   27216             : 
+   27217           0 :   wantq = (*vect=='Q' || *vect=='q');
+   27218             : 
+   27219           0 :   *info = 0;
+   27220           0 :   wrksz = mn*DORGBR_BLOCKSIZE;
+   27221           0 :   if(*lwork==-1) {
+   27222           0 :     work[0] = wrksz;
+   27223           0 :     return;
+   27224             :   }
+   27225             :   
+   27226           0 :   if(*m==0 || *n==0)
+   27227             :     return;
+   27228             : 
+   27229           0 :   if(wantq) {
+   27230           0 :     if(*m>=*k)
+   27231           0 :       PLUMED_BLAS_F77_FUNC(sorgqr,SORGQR)(m,n,k,a,lda,tau,work,lwork,&iinfo);
+   27232             :     else {
+   27233           0 :       for(j=*m;j>=2;j--) {
+   27234           0 :         a[(j-1)*(*lda)+0] = 0.0;
+   27235           0 :         for(i=j+1;i<=*m;i++)
+   27236           0 :           a[(j-1)*(*lda)+(i-1)] = a[(j-2)*(*lda)+(i-1)]; 
+   27237             :       }
+   27238           0 :       a[0] = 1.0;
+   27239           0 :       for(i=2;i<=*m;i++)
+   27240           0 :         a[i-1] = 0.0;
+   27241           0 :       if(*m>1) {
+   27242           0 :         i1 = *m-1;
+   27243           0 :         PLUMED_BLAS_F77_FUNC(sorgqr,SORGQR)(&i1,&i1,&i1,&(a[*lda+1]),lda,tau,work,lwork,&iinfo);
+   27244             :       }
+   27245             :     }
+   27246             :   } else {
+   27247           0 :     if(*k<*n)
+   27248           0 :       PLUMED_BLAS_F77_FUNC(sorglq,SORGLQ)(m,n,k,a,lda,tau,work,lwork,&iinfo);
+   27249             :     else {
+   27250           0 :       a[0] = 1.0;
+   27251           0 :       for(i=2;i<=*m;i++)
+   27252           0 :         a[i-1] = 0.0;
+   27253           0 :       for(j=2;j<=*n;j++) {
+   27254           0 :         for(i=j-1;i>=2;i--)
+   27255           0 :           a[(j-1)*(*lda)+(i-1)] = a[(j-1)*(*lda)+(i-2)]; 
+   27256           0 :         a[(j-1)*(*lda)+0] = 0.0;
+   27257             :       }
+   27258           0 :       if(*n>1) {
+   27259           0 :         i1 = *n-1;
+   27260           0 :         PLUMED_BLAS_F77_FUNC(sorglq,SORGLQ)(&i1,&i1,&i1,&(a[*lda+1]),lda,tau,work,lwork,&iinfo);
+   27261             :       }
+   27262             :     }
+   27263             :   }
+   27264           0 :   work[0] = wrksz;
+   27265           0 :   return;
+   27266             : }
+   27267             :  
+   27268             : }
+   27269             : }
+   27270             : #include "blas/blas.h"
+   27271             : #include "lapack.h"
+   27272             : 
+   27273             : #include "blas/blas.h"
+   27274             : namespace PLMD{
+   27275             : namespace lapack{
+   27276             : using namespace blas;
+   27277             : void
+   27278           0 : PLUMED_BLAS_F77_FUNC(sorgl2,SORGL2)(int *m,
+   27279             :                         int *n, 
+   27280             :                         int *k, 
+   27281             :                         float *a, 
+   27282             :                         int *lda, 
+   27283             :                         float *tau, 
+   27284             :                         float *work, 
+   27285             :                         int *info)
+   27286             : {
+   27287             :     int a_dim1, a_offset, i__1, i__2;
+   27288             :     float r__1;
+   27289             : 
+   27290             :     int i__, j, l;
+   27291             : 
+   27292           0 :     a_dim1 = *lda;
+   27293           0 :     a_offset = 1 + a_dim1;
+   27294           0 :     a -= a_offset;
+   27295           0 :     --tau;
+   27296             :     --work;
+   27297             : 
+   27298           0 :     i__ = (*m > 1) ? *m : 1;
+   27299             :     
+   27300           0 :     *info = 0;
+   27301           0 :     if (*m < 0) {
+   27302           0 :         *info = -1;
+   27303           0 :     } else if (*n < *m) {
+   27304           0 :         *info = -2;
+   27305           0 :     } else if (*k < 0 || *k > *m) {
+   27306           0 :         *info = -3;
+   27307           0 :     } else if (*lda < i__) {
+   27308           0 :         *info = -5;
+   27309             :     }
+   27310           0 :     if (*info != 0) {
+   27311             :         return;
+   27312             :     }
+   27313           0 :     if (*m <= 0) {
+   27314             :         return;
+   27315             :     }
+   27316             : 
+   27317           0 :     if (*k < *m) {
+   27318           0 :         i__1 = *n;
+   27319           0 :         for (j = 1; j <= i__1; ++j) {
+   27320           0 :             i__2 = *m;
+   27321           0 :             for (l = *k + 1; l <= i__2; ++l) {
+   27322           0 :                 a[l + j * a_dim1] = 0.0;
+   27323             :             }
+   27324           0 :             if (j > *k && j <= *m) {
+   27325           0 :                 a[j + j * a_dim1] = 1.0;
+   27326             :             }
+   27327             :         }
+   27328             :     }
+   27329             : 
+   27330           0 :     for (i__ = *k; i__ >= 1; --i__) {
+   27331           0 :         if (i__ < *n) {
+   27332           0 :             if (i__ < *m) {
+   27333           0 :                 a[i__ + i__ * a_dim1] = 1.0;
+   27334           0 :                 i__1 = *m - i__;
+   27335           0 :                 i__2 = *n - i__ + 1;
+   27336           0 :                 PLUMED_BLAS_F77_FUNC(slarf,SLARF)("R", &i__1, &i__2, &a[i__ + i__ * a_dim1], lda, 
+   27337           0 :                &tau[i__], &a[i__ + 1 + i__ * a_dim1], lda, &work[1]);
+   27338             :             }
+   27339           0 :             i__1 = *n - i__;
+   27340           0 :             r__1 = -tau[i__];
+   27341           0 :             PLUMED_BLAS_F77_FUNC(sscal,SSCAL)(&i__1, &r__1, &a[i__ + (i__ + 1) * a_dim1], lda);
+   27342             :         }
+   27343           0 :         a[i__ + i__ * a_dim1] = 1.0 - tau[i__];
+   27344           0 :         i__1 = i__ - 1;
+   27345           0 :         for (l = 1; l <= i__1; ++l) {
+   27346           0 :             a[i__ + l * a_dim1] = 0.0;
+   27347             :         }
+   27348             :     }
+   27349             :     return;
+   27350             : 
+   27351             : }
+   27352             : 
+   27353             : 
+   27354             : 
+   27355             : }
+   27356             : }
+   27357             : #include "lapack.h"
+   27358             : 
+   27359             : #define SORGLQ_BLOCKSIZE    32
+   27360             : #define SORGLQ_MINBLOCKSIZE 2
+   27361             : #define SORGLQ_CROSSOVER    128
+   27362             : 
+   27363             : 
+   27364             : #include "blas/blas.h"
+   27365             : namespace PLMD{
+   27366             : namespace lapack{
+   27367             : using namespace blas;
+   27368             : void 
+   27369           0 : PLUMED_BLAS_F77_FUNC(sorglq,SORGLQ)(int *m, 
+   27370             :         int *n, 
+   27371             :         int *k, 
+   27372             :         float *a, 
+   27373             :         int *lda, 
+   27374             :         float *tau, 
+   27375             :         float *work, 
+   27376             :         int *lwork, 
+   27377             :         int *info)
+   27378             : {
+   27379             :     int a_dim1, a_offset, i__1, i__2, i__3;
+   27380             : 
+   27381             :     int i__, j, l, ib, nb, ki, kk, nx, iws, nbmin, iinfo;
+   27382             : 
+   27383             :     int ldwork, lwkopt;
+   27384             :     int lquery;
+   27385             :     
+   27386           0 :     a_dim1 = *lda;
+   27387           0 :     a_offset = 1 + a_dim1;
+   27388           0 :     a -= a_offset;
+   27389           0 :     --tau;
+   27390             :     --work;
+   27391             : 
+   27392           0 :     *info = 0;
+   27393             :     ki = 0;
+   27394             :     nb = SORGLQ_BLOCKSIZE;
+   27395           0 :     lwkopt = (*m) * nb;
+   27396           0 :     work[1] = (float) lwkopt;
+   27397           0 :     lquery = *lwork == -1;
+   27398           0 :     if (*m < 0) {
+   27399           0 :         *info = -1;
+   27400           0 :     } else if (*n < *m) {
+   27401           0 :         *info = -2;
+   27402           0 :     } else if (*k < 0 || *k > *m) {
+   27403           0 :         *info = -3;
+   27404           0 :     } else if (*lda < (*m)) {
+   27405           0 :         *info = -5;
+   27406           0 :     } else if (*lwork < (*m) && ! lquery) {
+   27407           0 :         *info = -8;
+   27408             :     }
+   27409           0 :     if (*info != 0) {
+   27410             :         i__1 = -(*info);
+   27411             :         return;
+   27412           0 :     } else if (lquery) {
+   27413             :         return;
+   27414             :     }
+   27415             : 
+   27416           0 :     if (*m <= 0) {
+   27417           0 :         work[1] = 1.;
+   27418           0 :         return;
+   27419             :     }
+   27420             : 
+   27421             :     nbmin = 2;
+   27422             :     nx = 0;
+   27423             :     iws = *m;
+   27424           0 :     if (nb > 1 && nb < *k) {
+   27425             : 
+   27426             :         nx = SORGLQ_CROSSOVER;
+   27427           0 :         if (nx < *k) {
+   27428             : 
+   27429           0 :             ldwork = *m;
+   27430           0 :             iws = ldwork * nb;
+   27431           0 :             if (*lwork < iws) {
+   27432             : 
+   27433           0 :                 nb = *lwork / ldwork;
+   27434             :                 nbmin = SORGLQ_MINBLOCKSIZE;
+   27435             :             }
+   27436             :         }
+   27437             :     }
+   27438             : 
+   27439           0 :     if (nb >= nbmin && nb < *k && nx < *k) {
+   27440             : 
+   27441           0 :         ki = (*k - nx - 1) / nb * nb;
+   27442           0 :         i__1 = *k, i__2 = ki + nb;
+   27443             :         kk = (i__1<i__2) ? i__1 : i__2;
+   27444             : 
+   27445           0 :         i__1 = kk;
+   27446           0 :         for (j = 1; j <= i__1; ++j) {
+   27447           0 :             i__2 = *m;
+   27448           0 :             for (i__ = kk + 1; i__ <= i__2; ++i__) {
+   27449           0 :                 a[i__ + j * a_dim1] = 0.;
+   27450             :             }
+   27451             :         }
+   27452             :     } else {
+   27453             :         kk = 0;
+   27454             :     }
+   27455           0 :     if (kk < *m) {
+   27456           0 :         i__1 = *m - kk;
+   27457           0 :         i__2 = *n - kk;
+   27458           0 :         i__3 = *k - kk;
+   27459           0 :         PLUMED_BLAS_F77_FUNC(sorgl2,SORGL2)(&i__1, &i__2, &i__3, &a[kk + 1 + (kk + 1) * a_dim1], lda, &
+   27460           0 :                 tau[kk + 1], &work[1], &iinfo);
+   27461             :     }
+   27462             : 
+   27463           0 :     if (kk > 0) {
+   27464             : 
+   27465           0 :         i__1 = -nb;
+   27466           0 :         for (i__ = ki + 1; i__1 < 0 ? i__ >= 1 : i__ <= 1; i__ += i__1) {
+   27467           0 :             i__2 = nb, i__3 = *k - i__ + 1;
+   27468           0 :             ib = (i__2<i__3) ? i__2 : i__3;
+   27469           0 :             if (i__ + ib <= *m) {
+   27470             : 
+   27471           0 :                 i__2 = *n - i__ + 1;
+   27472           0 :                 PLUMED_BLAS_F77_FUNC(slarft,SLARFT)("Forward", "Rowwise", &i__2, &ib, &a[i__ + i__ * 
+   27473           0 :                         a_dim1], lda, &tau[i__], &work[1], &ldwork);
+   27474             : 
+   27475           0 :                 i__2 = *m - i__ - ib + 1;
+   27476           0 :                 i__3 = *n - i__ + 1;
+   27477           0 :                 PLUMED_BLAS_F77_FUNC(slarfb,SLARFB)("Right", "Transpose", "Forward", "Rowwise", &i__2, &
+   27478             :                         i__3, &ib, &a[i__ + i__ * a_dim1], lda, &work[1], &
+   27479           0 :                         ldwork, &a[i__ + ib + i__ * a_dim1], lda, &work[ib + 
+   27480           0 :                         1], &ldwork);
+   27481             :             }
+   27482             : 
+   27483           0 :             i__2 = *n - i__ + 1;
+   27484           0 :             PLUMED_BLAS_F77_FUNC(sorgl2,SORGL2)(&ib, &i__2, &ib, &a[i__ + i__ * a_dim1], lda, &tau[i__], &
+   27485             :                     work[1], &iinfo);
+   27486             : 
+   27487           0 :             i__2 = i__ - 1;
+   27488           0 :             for (j = 1; j <= i__2; ++j) {
+   27489           0 :                 i__3 = i__ + ib - 1;
+   27490           0 :                 for (l = i__; l <= i__3; ++l) {
+   27491           0 :                     a[l + j * a_dim1] = 0.;
+   27492             :                 }
+   27493             :             }
+   27494             :         }
+   27495             :     }
+   27496             : 
+   27497           0 :     work[1] = (float) iws;
+   27498           0 :     return;
+   27499             : 
+   27500             : }
+   27501             : 
+   27502             : 
+   27503             : }
+   27504             : }
+   27505             : #include "lapack.h"
+   27506             : #include "lapack_limits.h"
+   27507             : 
+   27508             : 
+   27509             : #include "blas/blas.h"
+   27510             : namespace PLMD{
+   27511             : namespace lapack{
+   27512             : using namespace blas;
+   27513             : void 
+   27514           0 : PLUMED_BLAS_F77_FUNC(sorgqr,SORGQR)(int *m, 
+   27515             :         int *n, 
+   27516             :         int *k, 
+   27517             :         float *a, 
+   27518             :         int *lda, 
+   27519             :         float *tau, 
+   27520             :         float *work, 
+   27521             :         int *lwork, 
+   27522             :         int *info)
+   27523             : {
+   27524             :     int a_dim1, a_offset, i__1, i__2, i__3;
+   27525             : 
+   27526             :     int i__, j, l, ib, nb, ki, kk, nx, iws, nbmin, iinfo;
+   27527             :     int ldwork, lwkopt;
+   27528             :     int lquery;
+   27529             :  
+   27530           0 :     a_dim1 = *lda;
+   27531           0 :     a_offset = 1 + a_dim1;
+   27532           0 :     a -= a_offset;
+   27533           0 :     --tau;
+   27534             :     --work;
+   27535             : 
+   27536             :     ki = 0;
+   27537           0 :     *info = 0;
+   27538             :     nb = DORGQR_BLOCKSIZE;
+   27539           0 :     lwkopt = (*n) * nb;
+   27540           0 :     work[1] = (float) lwkopt;
+   27541           0 :     lquery = *lwork == -1;
+   27542           0 :     if (*m < 0) {
+   27543           0 :         *info = -1;
+   27544           0 :     } else if (*n < 0 || *n > *m) {
+   27545           0 :         *info = -2;
+   27546           0 :     } else if (*k < 0 || *k > *n) {
+   27547           0 :         *info = -3;
+   27548           0 :     } else if (*lda < (*m)) {
+   27549           0 :         *info = -5;
+   27550           0 :     } else if (*lwork < (*n) && ! lquery) {
+   27551           0 :         *info = -8;
+   27552             :     }
+   27553           0 :     if (*info != 0) {
+   27554             :         i__1 = -(*info);
+   27555             :         return;
+   27556           0 :     } else if (lquery) {
+   27557             :         return;
+   27558             :     }
+   27559             : 
+   27560           0 :     if (*n <= 0) {
+   27561           0 :         work[1] = 1.;
+   27562           0 :         return;
+   27563             :     }
+   27564             : 
+   27565             :     nbmin = 2;
+   27566             :     nx = 0;
+   27567             :     iws = *n;
+   27568           0 :     if (nb > 1 && nb < *k) {
+   27569             : 
+   27570             :         nx = DORGQR_CROSSOVER;
+   27571           0 :         if (nx < *k) {
+   27572             : 
+   27573           0 :             ldwork = *n;
+   27574           0 :             iws = ldwork * nb;
+   27575           0 :             if (*lwork < iws) {
+   27576             : 
+   27577           0 :                 nb = *lwork / ldwork;
+   27578             :                 nbmin = DORGQR_MINBLOCKSIZE;
+   27579             :             }
+   27580             :         }
+   27581             :     }
+   27582             : 
+   27583           0 :     if (nb >= nbmin && nb < *k && nx < *k) {
+   27584             : 
+   27585           0 :         ki = (*k - nx - 1) / nb * nb;
+   27586           0 :         i__1 = *k, i__2 = ki + nb;
+   27587             :         kk = (i__1<i__2) ? i__1 : i__2;
+   27588             : 
+   27589           0 :         i__1 = *n;
+   27590           0 :         for (j = kk + 1; j <= i__1; ++j) {
+   27591           0 :             i__2 = kk;
+   27592           0 :             for (i__ = 1; i__ <= i__2; ++i__) {
+   27593           0 :                 a[i__ + j * a_dim1] = 0.;
+   27594             :             }
+   27595             :         }
+   27596             :     } else {
+   27597             :         kk = 0;
+   27598             :     }
+   27599             : 
+   27600           0 :     if (kk < *n) {
+   27601           0 :         i__1 = *m - kk;
+   27602           0 :         i__2 = *n - kk;
+   27603           0 :         i__3 = *k - kk;
+   27604           0 :         PLUMED_BLAS_F77_FUNC(sorg2r,SORG2R)(&i__1, &i__2, &i__3, &a[kk + 1 + (kk + 1) * a_dim1], lda, &
+   27605           0 :                 tau[kk + 1], &work[1], &iinfo);
+   27606             :     }
+   27607             : 
+   27608           0 :     if (kk > 0) {
+   27609             : 
+   27610           0 :         i__1 = -nb;
+   27611           0 :         for (i__ = ki + 1; i__1 < 0 ? i__ >= 1 : i__ <= 1; i__ += i__1) {
+   27612           0 :             i__2 = nb, i__3 = *k - i__ + 1;
+   27613           0 :             ib = (i__2<i__3) ? i__2 : i__3;
+   27614           0 :             if (i__ + ib <= *n) {
+   27615             : 
+   27616           0 :                 i__2 = *m - i__ + 1;
+   27617           0 :                 PLUMED_BLAS_F77_FUNC(slarft,SLARFT)("Forward", "Columnwise", &i__2, &ib, &a[i__ + i__ * 
+   27618           0 :                         a_dim1], lda, &tau[i__], &work[1], &ldwork);
+   27619             : 
+   27620           0 :                 i__2 = *m - i__ + 1;
+   27621           0 :                 i__3 = *n - i__ - ib + 1;
+   27622           0 :                 PLUMED_BLAS_F77_FUNC(slarfb,SLARFB)("Left", "No transpose", "Forward", "Columnwise", &
+   27623             :                         i__2, &i__3, &ib, &a[i__ + i__ * a_dim1], lda, &work[
+   27624           0 :                         1], &ldwork, &a[i__ + (i__ + ib) * a_dim1], lda, &
+   27625           0 :                         work[ib + 1], &ldwork);
+   27626             :             }
+   27627             : 
+   27628           0 :             i__2 = *m - i__ + 1;
+   27629           0 :             PLUMED_BLAS_F77_FUNC(sorg2r,SORG2R)(&i__2, &ib, &ib, &a[i__ + i__ * a_dim1], lda, &tau[i__], &
+   27630             :                     work[1], &iinfo);
+   27631             : 
+   27632           0 :             i__2 = i__ + ib - 1;
+   27633           0 :             for (j = i__; j <= i__2; ++j) {
+   27634           0 :                 i__3 = i__ - 1;
+   27635           0 :                 for (l = 1; l <= i__3; ++l) {
+   27636           0 :                     a[l + j * a_dim1] = 0.;
+   27637             :                 }
+   27638             :             }
+   27639             :         }
+   27640             :     }
+   27641             : 
+   27642           0 :     work[1] = (float) iws;
+   27643           0 :     return;
+   27644             : 
+   27645             : } 
+   27646             : }
+   27647             : }
+   27648             : #include "lapack.h"
+   27649             : 
+   27650             : #include "blas/blas.h"
+   27651             : namespace PLMD{
+   27652             : namespace lapack{
+   27653             : using namespace blas;
+   27654             : void
+   27655           0 : PLUMED_BLAS_F77_FUNC(sorm2l,SORM2L)(const char *side, 
+   27656             :         const char *trans, 
+   27657             :         int *m, 
+   27658             :         int *n, 
+   27659             :         int *k, 
+   27660             :         float *a,
+   27661             :         int *lda, 
+   27662             :         float *tau,
+   27663             :         float *c__,
+   27664             :         int *ldc, 
+   27665             :         float *work, 
+   27666             :         int *info)
+   27667             : {
+   27668             :     int a_dim1, a_offset, c_dim1, c_offset, i__1, i__2;
+   27669           0 :     int c__1 = 1;
+   27670             : 
+   27671             :     int i__, i1, i2, i3, mi, ni, nq;
+   27672             :     float aii;
+   27673             :     int left;
+   27674             :     int notran;
+   27675             : 
+   27676           0 :     a_dim1 = *lda;
+   27677           0 :     a_offset = 1 + a_dim1;
+   27678           0 :     a -= a_offset;
+   27679             :     --tau;
+   27680             :     c_dim1 = *ldc;
+   27681             :     c_offset = 1 + c_dim1;
+   27682             :     c__ -= c_offset;
+   27683             :     --work;
+   27684             : 
+   27685             :     /* Function Body */
+   27686           0 :     *info = 0;
+   27687           0 :     left = (*side=='L' || *side=='l');
+   27688           0 :     notran = (*trans=='N' || *trans=='n');
+   27689             : 
+   27690           0 :     if (left) {
+   27691           0 :         nq = *m;
+   27692             :     } else {
+   27693           0 :         nq = *n;
+   27694             :     }
+   27695             :     if (*info != 0) {
+   27696             :         return;
+   27697             :     }
+   27698             : 
+   27699           0 :     if (*m == 0 || *n == 0 || *k == 0) {
+   27700             :         return;
+   27701             :     }
+   27702             : 
+   27703           0 :     if ((left && notran) || (! left && ! notran)) {
+   27704             :         i1 = 1;
+   27705             :         i2 = *k;
+   27706             :         i3 = 1;
+   27707             :     } else {
+   27708             :         i1 = *k;
+   27709             :         i2 = 1;
+   27710             :         i3 = -1;
+   27711             :     }
+   27712             : 
+   27713           0 :     if (left) {
+   27714           0 :         ni = *n;
+   27715             :     } else {
+   27716           0 :         mi = *m;
+   27717             :     }
+   27718             : 
+   27719             :     i__1 = i2;
+   27720             :     i__2 = i3;
+   27721           0 :     for (i__ = i1; i__2 < 0 ? i__ >= i__1 : i__ <= i__1; i__ += i__2) {
+   27722           0 :         if (left) {
+   27723             : 
+   27724           0 :             mi = *m - *k + i__;
+   27725             :         } else {
+   27726             : 
+   27727           0 :             ni = *n - *k + i__;
+   27728             :         }
+   27729             : 
+   27730           0 :         aii = a[nq - *k + i__ + i__ * a_dim1];
+   27731           0 :         a[nq - *k + i__ + i__ * a_dim1] = 1.;
+   27732           0 :         PLUMED_BLAS_F77_FUNC(slarf,SLARF)(side, &mi, &ni, &a[i__ * a_dim1 + 1], &c__1, &tau[i__], &c__[
+   27733             :                 c_offset], ldc, &work[1]);
+   27734           0 :         a[nq - *k + i__ + i__ * a_dim1] = aii;
+   27735             :     }
+   27736             :     return;
+   27737             : }
+   27738             : }
+   27739             : }
+   27740             : #include "lapack.h"
+   27741             : 
+   27742             : #include "blas/blas.h"
+   27743             : namespace PLMD{
+   27744             : namespace lapack{
+   27745             : using namespace blas;
+   27746             : void 
+   27747           0 : PLUMED_BLAS_F77_FUNC(sorm2r,SORM2R)(const char *side, 
+   27748             :         const char *trans, 
+   27749             :         int *m, 
+   27750             :         int *n, 
+   27751             :         int *k, 
+   27752             :         float *a, 
+   27753             :         int *lda, 
+   27754             :         float *tau, 
+   27755             :         float *c__, 
+   27756             :         int *ldc, 
+   27757             :         float *work, 
+   27758             :         int *info)
+   27759             : {
+   27760             :     int a_dim1, a_offset, c_dim1, c_offset, i__1, i__2;
+   27761             : 
+   27762             :     int i__, i1, i2, i3, ic, jc, mi, ni;
+   27763             :     float aii;
+   27764             :     int left;
+   27765             :     int notran;
+   27766           0 :     int c__1 = 1;
+   27767             : 
+   27768           0 :     a_dim1 = *lda;
+   27769           0 :     a_offset = 1 + a_dim1;
+   27770           0 :     a -= a_offset;
+   27771             :     --tau;
+   27772           0 :     c_dim1 = *ldc;
+   27773           0 :     c_offset = 1 + c_dim1;
+   27774           0 :     c__ -= c_offset;
+   27775             :     --work;
+   27776           0 :     *info = 0;
+   27777           0 :     left = (*side=='L' || *side=='l');
+   27778           0 :     notran = (*trans=='N' || *trans=='n');
+   27779             : 
+   27780             :     ic = jc = 0;
+   27781             : 
+   27782           0 :     if (*m <= 0 || *n <= 0 || *k <= 0) {
+   27783             :         return;
+   27784             :     }
+   27785             : 
+   27786           0 :     if ((left && !notran) || (!left && notran)) {
+   27787             :         i1 = 1;
+   27788             :         i2 = *k;
+   27789             :         i3 = 1;
+   27790             :     } else {
+   27791             :         i1 = *k;
+   27792             :         i2 = 1;
+   27793             :         i3 = -1;
+   27794             :     }
+   27795             : 
+   27796           0 :     if (left) {
+   27797           0 :         ni = *n;
+   27798             :         jc = 1;
+   27799             :     } else {
+   27800           0 :         mi = *m;
+   27801             :         ic = 1;
+   27802             :     }
+   27803             : 
+   27804             :     i__1 = i2;
+   27805             :     i__2 = i3;
+   27806           0 :     for (i__ = i1; i__2 < 0 ? i__ >= i__1 : i__ <= i__1; i__ += i__2) {
+   27807           0 :         if (left) {
+   27808             : 
+   27809           0 :             mi = *m - i__ + 1;
+   27810             :             ic = i__;
+   27811             :         } else {
+   27812             : 
+   27813           0 :             ni = *n - i__ + 1;
+   27814             :             jc = i__;
+   27815             :         }
+   27816             : 
+   27817             : 
+   27818           0 :         aii = a[i__ + i__ * a_dim1];
+   27819           0 :         a[i__ + i__ * a_dim1] = 1.;
+   27820           0 :         PLUMED_BLAS_F77_FUNC(slarf,SLARF)(side, &mi, &ni, &a[i__ + i__ * a_dim1], &c__1, &tau[i__], &c__[
+   27821           0 :                 ic + jc * c_dim1], ldc, &work[1]);
+   27822           0 :         a[i__ + i__ * a_dim1] = aii;
+   27823             :     }
+   27824             :     return;
+   27825             : 
+   27826             : } 
+   27827             : }
+   27828             : }
+   27829             : #include "lapack.h"
+   27830             : #include "lapack_limits.h"
+   27831             : 
+   27832             : #include "blas/blas.h"
+   27833             : namespace PLMD{
+   27834             : namespace lapack{
+   27835             : using namespace blas;
+   27836             : void 
+   27837           0 : PLUMED_BLAS_F77_FUNC(sormbr,SORMBR)(const char *vect, 
+   27838             :         const char *side, 
+   27839             :         const char *trans, 
+   27840             :         int *m, 
+   27841             :         int *n, 
+   27842             :         int *k, 
+   27843             :         float *a, 
+   27844             :         int *lda, 
+   27845             :         float *tau, 
+   27846             :         float *c__, 
+   27847             :         int *ldc, 
+   27848             :         float *work, 
+   27849             :         int *lwork, 
+   27850             :         int *info)
+   27851             : {
+   27852             :     int a_dim1, a_offset, c_dim1, c_offset, i__1;
+   27853             :  
+   27854             : 
+   27855             :     int i1, i2, nb, mi, ni, nq, nw;
+   27856             :     int left;
+   27857             :     int iinfo;
+   27858             :     int notran;
+   27859             :     int applyq;
+   27860             :     char transt[1];
+   27861             :     int lwkopt;
+   27862             :     int lquery;
+   27863             : 
+   27864           0 :     a_dim1 = *lda;
+   27865           0 :     a_offset = 1 + a_dim1;
+   27866           0 :     a -= a_offset;
+   27867             :     --tau;
+   27868           0 :     c_dim1 = *ldc;
+   27869           0 :     c_offset = 1 + c_dim1;
+   27870           0 :     c__ -= c_offset;
+   27871             :     --work;
+   27872           0 :     *info = 0;
+   27873           0 :     applyq = (*vect=='Q' || *vect=='q');
+   27874           0 :     left = (*side=='L' || *side=='l');
+   27875           0 :     notran = (*trans=='N' || *trans=='n');
+   27876           0 :     lquery = *lwork == -1;
+   27877             : 
+   27878           0 :     if (left) {
+   27879           0 :         nq = *m;
+   27880           0 :         nw = *n;
+   27881             :     } else {
+   27882           0 :         nq = *n;
+   27883           0 :         nw = *m;
+   27884             :     }
+   27885             : 
+   27886             :     nb = DORMQR_BLOCKSIZE;
+   27887           0 :     lwkopt = nw * nb;
+   27888           0 :     work[1] = (float) lwkopt;
+   27889             :     
+   27890           0 :     if (*info != 0) {
+   27891             :         i__1 = -(*info);
+   27892             :         return;
+   27893           0 :     } else if (lquery) {
+   27894             :         return;
+   27895             :     }
+   27896             : 
+   27897           0 :     work[1] = 1.;
+   27898           0 :     if (*m == 0 || *n == 0) {
+   27899             :         return;
+   27900             :     }
+   27901             : 
+   27902           0 :     if (applyq) {
+   27903             : 
+   27904           0 :         if (nq >= *k) {
+   27905             : 
+   27906           0 :             PLUMED_BLAS_F77_FUNC(sormqr,SORMQR)(side, trans, m, n, k, &a[a_offset], lda, &tau[1], &c__[
+   27907             :                     c_offset], ldc, &work[1], lwork, &iinfo);
+   27908           0 :         } else if (nq > 1) {
+   27909             : 
+   27910           0 :             if (left) {
+   27911           0 :                 mi = *m - 1;
+   27912           0 :                 ni = *n;
+   27913             :                 i1 = 2;
+   27914             :                 i2 = 1;
+   27915             :             } else {
+   27916           0 :                 mi = *m;
+   27917           0 :                 ni = *n - 1;
+   27918             :                 i1 = 1;
+   27919             :                 i2 = 2;
+   27920             :             }
+   27921           0 :             i__1 = nq - 1;
+   27922           0 :             PLUMED_BLAS_F77_FUNC(sormqr,SORMQR)(side, trans, &mi, &ni, &i__1, &a[a_dim1 + 2], lda, &tau[1]
+   27923           0 :                     , &c__[i1 + i2 * c_dim1], ldc, &work[1], lwork, &iinfo);
+   27924             :         }
+   27925             :     } else {
+   27926             : 
+   27927           0 :         if (notran) {
+   27928           0 :             *(unsigned char *)transt = 'T';
+   27929             :         } else {
+   27930           0 :             *(unsigned char *)transt = 'N';
+   27931             :         }
+   27932           0 :         if (nq > *k) {
+   27933             : 
+   27934           0 :             PLUMED_BLAS_F77_FUNC(sormlq,SORMLQ)(side, transt, m, n, k, &a[a_offset], lda, &tau[1], &c__[
+   27935             :                     c_offset], ldc, &work[1], lwork, &iinfo);
+   27936           0 :         } else if (nq > 1) {
+   27937             : 
+   27938           0 :             if (left) {
+   27939           0 :                 mi = *m - 1;
+   27940           0 :                 ni = *n;
+   27941             :                 i1 = 2;
+   27942             :                 i2 = 1;
+   27943             :             } else {
+   27944           0 :                 mi = *m;
+   27945           0 :                 ni = *n - 1;
+   27946             :                 i1 = 1;
+   27947             :                 i2 = 2;
+   27948             :             }
+   27949           0 :             i__1 = nq - 1;
+   27950           0 :             PLUMED_BLAS_F77_FUNC(sormlq,SORMLQ)(side, transt, &mi, &ni, &i__1, &a[(a_dim1 << 1) + 1], lda,
+   27951           0 :                      &tau[1], &c__[i1 + i2 * c_dim1], ldc, &work[1], lwork, &
+   27952             :                     iinfo);
+   27953             :         }
+   27954             :     }
+   27955           0 :     work[1] = (float) lwkopt;
+   27956           0 :     return;
+   27957             : 
+   27958             : 
+   27959             : }
+   27960             : 
+   27961             : 
+   27962             : }
+   27963             : }
+   27964             : #include <cctype>
+   27965             : #include "real.h"
+   27966             : #include "lapack.h"
+   27967             : 
+   27968             : #include "blas/blas.h"
+   27969             : namespace PLMD{
+   27970             : namespace lapack{
+   27971             : using namespace blas;
+   27972             : void
+   27973           0 : PLUMED_BLAS_F77_FUNC(sorml2,SORML2)(const char *side,
+   27974             :                         const char *trans,
+   27975             :                         int *m,
+   27976             :                         int *n,
+   27977             :                         int *k,
+   27978             :                         float *a,
+   27979             :                         int *lda,
+   27980             :                         float *tau,
+   27981             :                         float *c,
+   27982             :                         int *ldc,
+   27983             :                         float *work,
+   27984             :                         int *info)
+   27985             : {
+   27986           0 :   const char xside=std::toupper(*side);
+   27987           0 :   const char xtrans=std::toupper(*trans);
+   27988             :   int i,i1,i2,i3,ni,mi,ic,jc;
+   27989             :   float aii;
+   27990             : 
+   27991           0 :   if(*m<=0 || *n<=0 || *k<=0)
+   27992             :     return;
+   27993             : 
+   27994             :   ic = jc = 0;
+   27995             : 
+   27996           0 :   if((xside=='L' && xtrans=='N') || (xside!='L' && xtrans!='N')) {
+   27997             :     i1 = 0;
+   27998             :     i2 = *k;
+   27999             :     i3 = 1;
+   28000             :   } else {
+   28001           0 :     i1 = *k-1;
+   28002             :     i2 = -1;
+   28003             :     i3 = -1;
+   28004             :   }
+   28005             :   
+   28006           0 :   if(xside=='L') {
+   28007           0 :     ni = *n;
+   28008             :     jc = 0;
+   28009             :   } else {
+   28010           0 :     mi = *m;
+   28011             :     ic = 0;
+   28012             :   }
+   28013             : 
+   28014           0 :   for(i=i1;i!=i2;i+=i3) {
+   28015           0 :     if(xside=='L') {
+   28016           0 :       mi = *m - i;
+   28017             :       ic = i;
+   28018             :     } else {
+   28019           0 :       ni = *n - i;
+   28020             :       jc = i;
+   28021             :     }
+   28022           0 :     aii = a[i*(*lda)+i];
+   28023           0 :     a[i*(*lda)+i] = 1.0;
+   28024           0 :     PLUMED_BLAS_F77_FUNC(slarf,SLARF)(side,&mi,&ni,&(a[i*(*lda)+i]),lda,tau+i,
+   28025           0 :            &(c[jc*(*ldc)+ic]),ldc,work);
+   28026           0 :     a[i*(*lda)+i] = aii;
+   28027             :   }
+   28028             :   return;
+   28029             : }
+   28030             :              
+   28031             : }
+   28032             : }
+   28033             : #include "lapack.h"
+   28034             : #include "lapack_limits.h"
+   28035             : 
+   28036             : 
+   28037             : #include "blas/blas.h"
+   28038             : namespace PLMD{
+   28039             : namespace lapack{
+   28040             : using namespace blas;
+   28041             : void 
+   28042           0 : PLUMED_BLAS_F77_FUNC(sormlq,SORMLQ)(const char *side, 
+   28043             :         const char *trans,
+   28044             :         int *m, 
+   28045             :         int *n, 
+   28046             :         int *k,
+   28047             :         float *a,
+   28048             :         int *lda, 
+   28049             :         float *tau, 
+   28050             :         float *c__, 
+   28051             :         int *ldc, 
+   28052             :         float *work, 
+   28053             :         int *lwork, 
+   28054             :         int *info)
+   28055             : {
+   28056             :     int a_dim1, a_offset, c_dim1, c_offset, i__1, i__2, i__4, 
+   28057             :             i__5;
+   28058             :   
+   28059             : 
+   28060             :     int i__;
+   28061             :     float t[4160]       /* was [65][64] */;
+   28062             :     int i1, i2, i3, ib, ic, jc, nb, mi, ni, nq, nw, iws;
+   28063             :     int left;
+   28064             :     int nbmin, iinfo;
+   28065             :     int notran;
+   28066             :     int ldwork;
+   28067             :     char transt[1];
+   28068             :     int lwkopt;
+   28069             :     int lquery;
+   28070           0 :     int ldt = 65;
+   28071             : 
+   28072           0 :     a_dim1 = *lda;
+   28073           0 :     a_offset = 1 + a_dim1;
+   28074           0 :     a -= a_offset;
+   28075             :     --tau;
+   28076           0 :     c_dim1 = *ldc;
+   28077           0 :     c_offset = 1 + c_dim1;
+   28078           0 :     c__ -= c_offset;
+   28079             :     --work;
+   28080             : 
+   28081             :     ic = jc = 0;
+   28082             : 
+   28083           0 :     *info = 0;
+   28084           0 :     left = (*side=='L' || *side=='l');
+   28085           0 :     notran = (*trans=='N' || *trans=='n');
+   28086           0 :     lquery = *lwork == -1;
+   28087             : 
+   28088           0 :     if (left) {
+   28089           0 :         nq = *m;
+   28090           0 :         nw = *n;
+   28091             :     } else {
+   28092           0 :         nq = *n;
+   28093           0 :         nw = *m;
+   28094             :     }
+   28095             : 
+   28096             :     nb = DORMLQ_BLOCKSIZE;
+   28097           0 :     lwkopt = nw * nb;
+   28098           0 :     work[1] = (float) lwkopt;
+   28099             :     
+   28100           0 :     if (*info != 0) {
+   28101             :         return;
+   28102           0 :     } else if (lquery) {
+   28103             :         return;
+   28104             :     }
+   28105             : 
+   28106           0 :     if (*m == 0 || *n == 0 || *k == 0) {
+   28107           0 :         work[1] = 1.;
+   28108           0 :         return;
+   28109             :     }
+   28110             : 
+   28111             :     nbmin = 2;
+   28112           0 :     ldwork = nw;
+   28113           0 :     if (nb > 1 && nb < *k) {
+   28114             :         iws = nw * nb;
+   28115           0 :         if (*lwork < iws) {
+   28116           0 :             nb = *lwork / ldwork;
+   28117             :             nbmin = DORMLQ_MINBLOCKSIZE;
+   28118             :         }
+   28119             :     }
+   28120             : 
+   28121           0 :     if (nb < nbmin || nb >= *k) {
+   28122             : 
+   28123             : 
+   28124           0 :         PLUMED_BLAS_F77_FUNC(sorml2,SORML2)(side, trans, m, n, k, &a[a_offset], lda, &tau[1], &c__[
+   28125             :                 c_offset], ldc, &work[1], &iinfo);
+   28126             :     } else {
+   28127             : 
+   28128           0 :         if ((left && notran) || (!left && !notran)) {
+   28129             :             i1 = 1;
+   28130             :             i2 = *k;
+   28131             :             i3 = nb;
+   28132             :         } else {
+   28133           0 :             i1 = (*k - 1) / nb * nb + 1;
+   28134             :             i2 = 1;
+   28135           0 :             i3 = -nb;
+   28136             :         }
+   28137             : 
+   28138           0 :         if (left) {
+   28139           0 :             ni = *n;
+   28140             :             jc = 1;
+   28141             :         } else {
+   28142           0 :             mi = *m;
+   28143             :             ic = 1;
+   28144             :         }
+   28145             : 
+   28146           0 :         if (notran) {
+   28147           0 :             *(unsigned char *)transt = 'T';
+   28148             :         } else {
+   28149           0 :             *(unsigned char *)transt = 'N';
+   28150             :         }
+   28151             : 
+   28152             :         i__1 = i2;
+   28153             :         i__2 = i3;
+   28154           0 :         for (i__ = i1; i__2 < 0 ? i__ >= i__1 : i__ <= i__1; i__ += i__2) {
+   28155           0 :             i__4 = nb, i__5 = *k - i__ + 1;
+   28156           0 :             ib = (i__4<i__5) ? i__4 : i__5;
+   28157             : 
+   28158           0 :             i__4 = nq - i__ + 1;
+   28159           0 :             PLUMED_BLAS_F77_FUNC(slarft,SLARFT)("Forward", "Rowwise", &i__4, &ib, &a[i__ + i__ * a_dim1], 
+   28160           0 :                     lda, &tau[i__], t, &ldt);
+   28161           0 :             if (left) {
+   28162             : 
+   28163           0 :                 mi = *m - i__ + 1;
+   28164             :                 ic = i__;
+   28165             :             } else {
+   28166             : 
+   28167           0 :                 ni = *n - i__ + 1;
+   28168             :                 jc = i__;
+   28169             :             }
+   28170             : 
+   28171           0 :             PLUMED_BLAS_F77_FUNC(slarfb,SLARFB)(side, transt, "Forward", "Rowwise", &mi, &ni, &ib, &a[i__ 
+   28172           0 :                     + i__ * a_dim1], lda, t, &ldt, &c__[ic + jc * c_dim1], 
+   28173             :                     ldc, &work[1], &ldwork);
+   28174             :         }
+   28175             :     }
+   28176           0 :     work[1] = (float) lwkopt;
+   28177           0 :     return;
+   28178             : 
+   28179             : }
+   28180             : 
+   28181             : 
+   28182             : }
+   28183             : }
+   28184             : #include "lapack.h"
+   28185             : #include "lapack_limits.h"
+   28186             : 
+   28187             : #include "blas/blas.h"
+   28188             : namespace PLMD{
+   28189             : namespace lapack{
+   28190             : using namespace blas;
+   28191             : void
+   28192           0 : PLUMED_BLAS_F77_FUNC(sormql,SORMQL)(const char *side, const char *trans, int *m, int *n, 
+   28193             :         int *k, float *a, int *lda, float *tau, float *
+   28194             :         c__, int *ldc, float *work, int *lwork, int *info)
+   28195             : {
+   28196             :     int a_dim1, a_offset, c_dim1, c_offset, i__1, i__2, i__4, i__5;
+   28197           0 :     int c__65 = 65;
+   28198             : 
+   28199             :     int i__;
+   28200             :     float t[4160];
+   28201             :     int i1, i2, i3, ib, nb, mi, ni, nq, nw, iws;
+   28202             :     int left;
+   28203             :     int nbmin, iinfo;
+   28204             :     int notran;
+   28205             :     int ldwork, lwkopt;
+   28206             :     int lquery;
+   28207             : 
+   28208             : 
+   28209           0 :     a_dim1 = *lda;
+   28210           0 :     a_offset = 1 + a_dim1;
+   28211           0 :     a -= a_offset;
+   28212             :     --tau;
+   28213             :     c_dim1 = *ldc;
+   28214             :     c_offset = 1 + c_dim1;
+   28215             :     c__ -= c_offset;
+   28216             :     --work;
+   28217             : 
+   28218           0 :     *info = 0;
+   28219           0 :     left = (*side=='L' || *side=='l');
+   28220           0 :     notran = (*trans=='N' || *trans=='n');
+   28221           0 :     lquery = *lwork == -1;
+   28222             : 
+   28223           0 :     if (left) {
+   28224           0 :         nq = *m;
+   28225           0 :         nw = *n;
+   28226             :     } else {
+   28227           0 :         nq = *n;
+   28228           0 :         nw = *m;
+   28229             :     }
+   28230             : 
+   28231             :     nb = DORMQL_BLOCKSIZE;
+   28232           0 :     lwkopt = nw * nb;
+   28233           0 :     work[1] = (float) lwkopt;
+   28234             :     
+   28235           0 :     if (*info != 0) {
+   28236             :         return;
+   28237           0 :     } else if (lquery) {
+   28238             :         return;
+   28239             :     }
+   28240             : 
+   28241           0 :     if (*m == 0 || *n == 0 || *k == 0) {
+   28242           0 :         work[1] = 1.;
+   28243           0 :         return;
+   28244             :     }
+   28245             : 
+   28246             :     nbmin = 2;
+   28247           0 :     ldwork = nw;
+   28248           0 :     if (nb > 1 && nb < *k) {
+   28249             :         iws = nw * nb;
+   28250           0 :         if (*lwork < iws) {
+   28251           0 :             nb = *lwork / ldwork;
+   28252             :             nbmin = DORMQL_MINBLOCKSIZE;
+   28253             :         }
+   28254             :     }
+   28255             : 
+   28256           0 :     if (nb < nbmin || nb >= *k) {
+   28257             : 
+   28258           0 :         PLUMED_BLAS_F77_FUNC(sorm2l,SORM2L)(side, trans, m, n, k, &a[a_offset], lda, &tau[1], &c__[
+   28259             :                 c_offset], ldc, &work[1], &iinfo);
+   28260             :     } else {
+   28261             : 
+   28262           0 :         if ((left && notran) || (! left && ! notran)) {
+   28263             :             i1 = 1;
+   28264             :             i2 = *k;
+   28265             :             i3 = nb;
+   28266             :         } else {
+   28267           0 :             i1 = (*k - 1) / nb * nb + 1;
+   28268             :             i2 = 1;
+   28269           0 :             i3 = -nb;
+   28270             :         }
+   28271             : 
+   28272           0 :         if (left) {
+   28273           0 :             ni = *n;
+   28274             :         } else {
+   28275           0 :             mi = *m;
+   28276             :         }
+   28277             : 
+   28278             :         i__1 = i2;
+   28279             :         i__2 = i3;
+   28280           0 :         for (i__ = i1; i__2 < 0 ? i__ >= i__1 : i__ <= i__1; i__ += i__2) {
+   28281           0 :             i__4 = nb, i__5 = *k - i__ + 1;
+   28282           0 :             ib = (i__4<i__5) ? i__4 : i__5;
+   28283             : 
+   28284           0 :             i__4 = nq - *k + i__ + ib - 1;
+   28285           0 :             PLUMED_BLAS_F77_FUNC(slarft,SLARFT)("Backward", "Columnwise", &i__4, &ib, &a[i__ * a_dim1 + 1]
+   28286           0 :                     , lda, &tau[i__], t, &c__65);
+   28287           0 :             if (left) {
+   28288             : 
+   28289           0 :                 mi = *m - *k + i__ + ib - 1;
+   28290             :             } else {
+   28291             : 
+   28292           0 :                 ni = *n - *k + i__ + ib - 1;
+   28293             :             }
+   28294             : 
+   28295           0 :             PLUMED_BLAS_F77_FUNC(slarfb,SLARFB)(side, trans, "Backward", "Columnwise", &mi, &ni, &ib, &a[
+   28296             :                     i__ * a_dim1 + 1], lda, t, &c__65, &c__[c_offset], ldc, &
+   28297             :                     work[1], &ldwork);
+   28298             :         }
+   28299             :     }
+   28300           0 :     work[1] = (float) lwkopt;
+   28301           0 :     return;
+   28302             : 
+   28303             : }
+   28304             : 
+   28305             : 
+   28306             : }
+   28307             : }
+   28308             : #include "lapack.h"
+   28309             : #include "lapack_limits.h"
+   28310             : 
+   28311             : #include "blas/blas.h"
+   28312             : namespace PLMD{
+   28313             : namespace lapack{
+   28314             : using namespace blas;
+   28315             : void 
+   28316           0 : PLUMED_BLAS_F77_FUNC(sormqr,SORMQR)(const char *side, 
+   28317             :         const char *trans, 
+   28318             :         int *m, 
+   28319             :         int *n, 
+   28320             :         int *k, 
+   28321             :         float *a, 
+   28322             :         int *lda, 
+   28323             :         float *tau, 
+   28324             :         float *c__, 
+   28325             :         int *ldc, 
+   28326             :         float *work, 
+   28327             :         int *lwork, 
+   28328             :         int *info)
+   28329             : {
+   28330             :    int a_dim1, a_offset, c_dim1, c_offset, i__1, i__2, i__4, i__5;
+   28331             : 
+   28332             :     int i__;
+   28333             :     float t[4160];
+   28334             :     int i1, i2, i3, ib, ic, jc, nb, mi, ni, nq, nw, iws;
+   28335             :     int left;
+   28336             :     int nbmin, iinfo;
+   28337             :     int notran;
+   28338             :     int ldwork, lwkopt;
+   28339             :     int lquery;
+   28340           0 :     int ldt = 65;
+   28341             : 
+   28342           0 :     a_dim1 = *lda;
+   28343           0 :     a_offset = 1 + a_dim1;
+   28344           0 :     a -= a_offset;
+   28345             :     --tau;
+   28346           0 :     c_dim1 = *ldc;
+   28347           0 :     c_offset = 1 + c_dim1;
+   28348           0 :     c__ -= c_offset;
+   28349             :     --work;
+   28350             : 
+   28351           0 :     *info = 0;
+   28352           0 :     left = (*side=='L' || *side=='l');
+   28353           0 :     notran = (*trans=='N' || *trans=='n');
+   28354           0 :     lquery = *lwork == -1;
+   28355             : 
+   28356           0 :     if (left) {
+   28357           0 :         nq = *m;
+   28358           0 :         nw = *n;
+   28359             :     } else {
+   28360           0 :         nq = *n;
+   28361           0 :         nw = *m;
+   28362             :     }
+   28363             : 
+   28364             :      ic = jc = 0;
+   28365             :      nb = DORMQR_BLOCKSIZE;
+   28366           0 :      lwkopt = nw * nb;
+   28367           0 :      work[1] = (float) lwkopt;
+   28368             : 
+   28369           0 :     if (*info != 0) {
+   28370             :         return;
+   28371           0 :     } else if (lquery) {
+   28372             :       return;
+   28373             :     }
+   28374             : 
+   28375           0 :     if (*m == 0 || *n == 0 || *k == 0) {
+   28376           0 :         work[1] = 1.;
+   28377           0 :         return;
+   28378             :     }
+   28379             : 
+   28380             :     nbmin = 2;
+   28381           0 :     ldwork = nw;
+   28382           0 :     if (nb > 1 && nb < *k) {
+   28383             :         iws = nw * nb;
+   28384           0 :         if (*lwork < iws) {
+   28385           0 :             nb = *lwork / ldwork;
+   28386             :             nbmin = DORMQR_MINBLOCKSIZE;
+   28387             :         }
+   28388             :     }
+   28389             : 
+   28390           0 :     if (nb < nbmin || nb >= *k) {
+   28391             : 
+   28392           0 :         PLUMED_BLAS_F77_FUNC(sorm2r,SORM2R)(side, trans, m, n, k, &a[a_offset], lda, &tau[1], &c__[
+   28393             :                 c_offset], ldc, &work[1], &iinfo);
+   28394             :     } else {
+   28395             : 
+   28396           0 :         if ((left && !notran) || (!left && notran)) {
+   28397             :             i1 = 1;
+   28398             :             i2 = *k;
+   28399             :             i3 = nb;
+   28400             :         } else {
+   28401           0 :             i1 = (*k - 1) / nb * nb + 1;
+   28402             :             i2 = 1;
+   28403           0 :             i3 = -nb;
+   28404             :         }
+   28405             : 
+   28406           0 :         if (left) {
+   28407           0 :             ni = *n;
+   28408             :             jc = 1;
+   28409             :         } else {
+   28410           0 :             mi = *m;
+   28411             :             ic = 1;
+   28412             :         }
+   28413             : 
+   28414             :         i__1 = i2;
+   28415             :         i__2 = i3;
+   28416           0 :         for (i__ = i1; i__2 < 0 ? i__ >= i__1 : i__ <= i__1; i__ += i__2) {
+   28417           0 :             i__4 = nb, i__5 = *k - i__ + 1;
+   28418           0 :             ib = (i__4<i__5) ? i__4 : i__5;
+   28419             : 
+   28420           0 :             i__4 = nq - i__ + 1;
+   28421           0 :             PLUMED_BLAS_F77_FUNC(slarft,SLARFT)("Forward", "Columnwise", &i__4, &ib, &a[i__ + i__ * 
+   28422           0 :                     a_dim1], lda, &tau[i__], t, &ldt);
+   28423           0 :             if (left) {
+   28424             : 
+   28425           0 :                 mi = *m - i__ + 1;
+   28426             :                 ic = i__;
+   28427             :             } else {
+   28428           0 :                 ni = *n - i__ + 1;
+   28429             :                 jc = i__;
+   28430             :             }
+   28431             : 
+   28432           0 :             PLUMED_BLAS_F77_FUNC(slarfb,SLARFB)(side, trans, "Forward", "Columnwise", &mi, &ni, &ib, &a[
+   28433           0 :                     i__ + i__ * a_dim1], lda, t, &ldt, &c__[ic + jc * 
+   28434             :                     c_dim1], ldc, &work[1], &ldwork);
+   28435             :         }
+   28436             :     }
+   28437           0 :     work[1] = (float) lwkopt;
+   28438           0 :     return;
+   28439             : 
+   28440             : 
+   28441             : }
+   28442             : 
+   28443             : 
+   28444             : }
+   28445             : }
+   28446             : #include "lapack.h"
+   28447             : #include "lapack_limits.h"
+   28448             : 
+   28449             : 
+   28450             : #include "blas/blas.h"
+   28451             : namespace PLMD{
+   28452             : namespace lapack{
+   28453             : using namespace blas;
+   28454             : void
+   28455           0 : PLUMED_BLAS_F77_FUNC(sormtr,SORMTR)(const char *side, 
+   28456             :         const char *uplo,
+   28457             :         const char *trans, 
+   28458             :         int *m, 
+   28459             :         int *n,
+   28460             :         float *a, 
+   28461             :         int *lda, 
+   28462             :         float *tau, 
+   28463             :         float *c__, 
+   28464             :         int *ldc,
+   28465             :         float *work, 
+   28466             :         int *lwork, 
+   28467             :         int *info)
+   28468             : {
+   28469             :     int a_dim1, a_offset, c_dim1, c_offset, i__2;
+   28470             : 
+   28471             :     int i1, i2, nb, mi, ni, nq, nw;
+   28472             :     int left;
+   28473             :     int iinfo;
+   28474             :     int upper;
+   28475             :     int lwkopt;
+   28476             :     int lquery;
+   28477             : 
+   28478             : 
+   28479           0 :     a_dim1 = *lda;
+   28480           0 :     a_offset = 1 + a_dim1;
+   28481           0 :     a -= a_offset;
+   28482             :     --tau;
+   28483           0 :     c_dim1 = *ldc;
+   28484           0 :     c_offset = 1 + c_dim1;
+   28485           0 :     c__ -= c_offset;
+   28486             :     --work;
+   28487             : 
+   28488           0 :     *info = 0;
+   28489           0 :     left = (*side=='L' || *side=='l');
+   28490           0 :     upper = (*uplo=='U' || *uplo=='u');
+   28491           0 :     lquery = *lwork == -1;
+   28492             : 
+   28493           0 :     if (left) {
+   28494           0 :         nq = *m;
+   28495           0 :         nw = *n;
+   28496             :     } else {
+   28497           0 :         nq = *n;
+   28498           0 :         nw = *m;
+   28499             :     }
+   28500             : 
+   28501             : 
+   28502             :     nb = DORMQL_BLOCKSIZE;
+   28503           0 :     lwkopt = nw * nb;
+   28504           0 :     work[1] = (float) lwkopt;
+   28505             :     
+   28506           0 :     if (*info != 0) {
+   28507             :         i__2 = -(*info);
+   28508             :         return;
+   28509           0 :     } else if (lquery) {
+   28510             :         return;
+   28511             :     }
+   28512             : 
+   28513           0 :     if (*m == 0 || *n == 0 || nq == 1) {
+   28514           0 :         work[1] = 1.;
+   28515           0 :         return;
+   28516             :     }
+   28517             : 
+   28518           0 :     if (left) {
+   28519           0 :         mi = *m - 1;
+   28520           0 :         ni = *n;
+   28521             :     } else {
+   28522           0 :         mi = *m;
+   28523           0 :         ni = *n - 1;
+   28524             :     }
+   28525             : 
+   28526           0 :     if (upper) {
+   28527           0 :         i__2 = nq - 1;
+   28528           0 :         PLUMED_BLAS_F77_FUNC(sormql,SORMQL)(side, trans, &mi, &ni, &i__2, &a[(a_dim1 << 1) + 1], lda, &
+   28529             :                 tau[1], &c__[c_offset], ldc, &work[1], lwork, &iinfo);
+   28530             :     } else {
+   28531           0 :         if (left) {
+   28532             :             i1 = 2;
+   28533             :             i2 = 1;
+   28534             :         } else {
+   28535             :             i1 = 1;
+   28536             :             i2 = 2;
+   28537             :         }
+   28538           0 :         i__2 = nq - 1;
+   28539           0 :         PLUMED_BLAS_F77_FUNC(sormqr,SORMQR)(side, trans, &mi, &ni, &i__2, &a[a_dim1 + 2], lda, &tau[1], &
+   28540           0 :                 c__[i1 + i2 * c_dim1], ldc, &work[1], lwork, &iinfo);
+   28541             :     }
+   28542           0 :     work[1] = (float) lwkopt;
+   28543           0 :     return;
+   28544             : 
+   28545             : }
+   28546             : 
+   28547             : 
+   28548             : }
+   28549             : }
+   28550             : #include <cmath>
+   28551             : #include "lapack.h"
+   28552             : #include "lapack_limits.h"
+   28553             : 
+   28554             : #include "real.h"
+   28555             : 
+   28556             : #include "blas/blas.h"
+   28557             : namespace PLMD{
+   28558             : namespace lapack{
+   28559             : using namespace blas;
+   28560             : void
+   28561           0 : PLUMED_BLAS_F77_FUNC(sstebz,SSTEBZ)(const char *range, 
+   28562             :                         const char *order,
+   28563             :                         int *n,
+   28564             :                         float *vl, 
+   28565             :                         float *vu, 
+   28566             :                         int *il,
+   28567             :                         int *iu,
+   28568             :                         float *abstol, 
+   28569             :                         float *d__,
+   28570             :                         float *e,
+   28571             :                         int *m, 
+   28572             :                         int *nsplit, 
+   28573             :                         float *w,
+   28574             :                         int *iblock,
+   28575             :                         int *isplit,
+   28576             :                         float *work, 
+   28577             :                         int *iwork, 
+   28578             :                         int *info)
+   28579             : {
+   28580             :     int i__1, i__2, i__3;
+   28581             :     float d__1, d__2, d__3, d__4, d__5;
+   28582           0 :     int c__1 = 1;
+   28583           0 :     int c__3 = 3;
+   28584           0 :     int c__2 = 2;
+   28585           0 :     int c__0 = 0;
+   28586             : 
+   28587             :     int j, ib, jb, ie, je, nb;
+   28588             :     float gl;
+   28589             :     int im, in;
+   28590             :     float gu;
+   28591             :     int iw;
+   28592             :     float wl, wu;
+   28593             :     int nwl;
+   28594             :     float ulp, wlu, wul;
+   28595             :     int nwu;
+   28596             :     float tmp1, tmp2;
+   28597             :     int iend, ioff, iout, itmp1, jdisc;
+   28598             :     int iinfo;
+   28599             :     float atoli;
+   28600             :     int iwoff;
+   28601             :     float bnorm;
+   28602             :     int itmax;
+   28603             :     float wkill, rtoli, tnorm;
+   28604             :     int ibegin;
+   28605             :     int irange, idiscl;
+   28606             :     int idumma[1];
+   28607             :     int idiscu, iorder;
+   28608             :     int ncnvrg;
+   28609             :     float pivmin;
+   28610             :     int toofew;
+   28611             :     const float safemn = PLUMED_GMX_FLOAT_MIN*(1.0+PLUMED_GMX_FLOAT_EPS);
+   28612             : 
+   28613           0 :     --iwork;
+   28614           0 :     --work;
+   28615           0 :     --isplit;
+   28616           0 :     --iblock;
+   28617           0 :     --w;
+   28618           0 :     --e;
+   28619           0 :     --d__;
+   28620             : 
+   28621           0 :     *info = 0;
+   28622             : 
+   28623           0 :     if (*range=='A' || *range=='a') {
+   28624             :         irange = 1;
+   28625           0 :     } else if (*range=='V' || *range=='v') {
+   28626             :         irange = 2;
+   28627             :     } else if (*range=='I' || *range=='i') {
+   28628             :         irange = 3;
+   28629             :     } else {
+   28630             :         irange = 0;
+   28631             :     }
+   28632             : 
+   28633           0 :     if (*order=='B' || *order=='b') {
+   28634             :         iorder = 2;
+   28635           0 :     } else if (*order=='E' || *order=='e') {
+   28636             :         iorder = 1;
+   28637             :     } else {
+   28638             :         iorder = 0;
+   28639             :     }
+   28640             : 
+   28641           0 :     if (irange <= 0) {
+   28642           0 :         *info = -1;
+   28643           0 :     } else if (iorder <= 0) {
+   28644           0 :         *info = -2;
+   28645           0 :     } else if (*n < 0) {
+   28646           0 :         *info = -3;
+   28647           0 :     } else if (irange == 2) {
+   28648           0 :         if (*vl >= *vu) {
+   28649           0 :             *info = -5;
+   28650             :         }
+   28651           0 :     } else if (irange == 3 && (*il < 1 || *il > (*n))) {
+   28652           0 :         *info = -6;
+   28653           0 :     } else if (irange == 3 && (*iu < ((*n<*il) ? *n : *il) || *iu > *n)) {
+   28654           0 :         *info = -7;
+   28655             :     }
+   28656             : 
+   28657           0 :     if (*info != 0) {
+   28658             :         return;
+   28659             :     }
+   28660             : 
+   28661           0 :     *info = 0;
+   28662             :     ncnvrg = 0;
+   28663             :     toofew = 0;
+   28664             : 
+   28665           0 :     *m = 0;
+   28666           0 :     if (*n == 0) {
+   28667             :         return;
+   28668             :     }
+   28669             : 
+   28670           0 :     if (irange == 3 && *il == 1 && *iu == *n) {
+   28671             :         irange = 1;
+   28672             :     }
+   28673             : 
+   28674             :     ulp = 2*PLUMED_GMX_FLOAT_EPS;
+   28675           0 :     rtoli = ulp * 2.;
+   28676             :     nb = DSTEBZ_BLOCKSIZE;
+   28677             :     // cppcheck-suppress knownConditionTrueFalse
+   28678             :     if (nb <= 1) {
+   28679           0 :         nb = 0;
+   28680             :     }
+   28681             : 
+   28682           0 :     if (*n == 1) {
+   28683           0 :         *nsplit = 1;
+   28684           0 :         isplit[1] = 1;
+   28685           0 :         if (irange == 2 && (*vl >= d__[1] || *vu < d__[1])) {
+   28686           0 :             *m = 0;
+   28687             :         } else {
+   28688           0 :             w[1] = d__[1];
+   28689           0 :             iblock[1] = 1;
+   28690           0 :             *m = 1;
+   28691             :         }
+   28692           0 :         return;
+   28693             :     }
+   28694             : 
+   28695           0 :     *nsplit = 1;
+   28696           0 :     work[*n] = 0.;
+   28697           0 :     pivmin = 1.;
+   28698           0 :     i__1 = *n;
+   28699           0 :     for (j = 2; j <= i__1; ++j) {
+   28700           0 :         d__1 = e[j - 1];
+   28701           0 :         tmp1 = d__1 * d__1;
+   28702             :         d__2 = ulp;
+   28703           0 :         if (std::abs(d__[j] * d__[j - 1]) * (d__2 * d__2) + safemn 
+   28704             :                 > tmp1) {
+   28705           0 :             isplit[*nsplit] = j - 1;
+   28706           0 :             ++(*nsplit);
+   28707           0 :             work[j - 1] = 0.;
+   28708             :         } else {
+   28709           0 :             work[j - 1] = tmp1;
+   28710           0 :             pivmin = (pivmin>tmp1) ? pivmin : tmp1;
+   28711             :         }
+   28712             :     }
+   28713           0 :     isplit[*nsplit] = *n;
+   28714           0 :     pivmin *= safemn;
+   28715             : 
+   28716           0 :     if (irange == 3) {
+   28717             : 
+   28718           0 :         gu = d__[1];
+   28719             :         gl = d__[1];
+   28720             :         tmp1 = 0.;
+   28721             : 
+   28722             :         i__1 = *n - 1;
+   28723           0 :         for (j = 1; j <= i__1; ++j) {
+   28724           0 :             tmp2 =  std::sqrt(work[j]);
+   28725           0 :             d__1 = gu, d__2 = d__[j] + tmp1 + tmp2;
+   28726           0 :             gu = (d__1>d__2) ? d__1 : d__2;
+   28727           0 :             d__1 = gl, d__2 = d__[j] - tmp1 - tmp2;
+   28728           0 :             gl = (d__1<d__2) ? d__1 : d__2;
+   28729             :             tmp1 = tmp2;
+   28730             :         }
+   28731             : 
+   28732           0 :         d__1 = gu, d__2 = d__[*n] + tmp1;
+   28733           0 :         gu = (d__1>d__2) ? d__1 : d__2;
+   28734           0 :         d__1 = gl, d__2 = d__[*n] - tmp1;
+   28735           0 :         gl = (d__1<d__2) ? d__1 : d__2;
+   28736             :         d__1 = std::abs(gl);
+   28737             :         d__2 = std::abs(gu);
+   28738           0 :         tnorm = (d__1>d__2) ? d__1 : d__2;
+   28739           0 :         gl = gl - tnorm * 2. * ulp * *n - pivmin * 4.;
+   28740           0 :         gu = gu + tnorm * 2. * ulp * *n + pivmin * 2.;
+   28741             : 
+   28742           0 :         itmax = (int) ((std::log(tnorm + pivmin) - std::log(pivmin)) / std::log(2.)) + 2;
+   28743           0 :         if (*abstol <= 0.) {
+   28744           0 :             atoli = ulp * tnorm;
+   28745             :         } else {
+   28746           0 :             atoli = *abstol;
+   28747             :         }
+   28748             : 
+   28749           0 :         work[*n + 1] = gl;
+   28750           0 :         work[*n + 2] = gl;
+   28751           0 :         work[*n + 3] = gu;
+   28752           0 :         work[*n + 4] = gu;
+   28753           0 :         work[*n + 5] = gl;
+   28754           0 :         work[*n + 6] = gu;
+   28755           0 :         iwork[1] = -1;
+   28756           0 :         iwork[2] = -1;
+   28757           0 :         iwork[3] = *n + 1;
+   28758           0 :         iwork[4] = *n + 1;
+   28759           0 :         iwork[5] = *il - 1;
+   28760           0 :         iwork[6] = *iu;
+   28761             : 
+   28762           0 :         PLUMED_BLAS_F77_FUNC(slaebz,SLAEBZ)(&c__3, &itmax, n, &c__2, &c__2, &nb, &atoli, &rtoli, &pivmin, 
+   28763           0 :                 &d__[1], &e[1], &work[1], &iwork[5], &work[*n + 1], &work[*n 
+   28764           0 :                 + 5], &iout, &iwork[1], &w[1], &iblock[1], &iinfo);
+   28765             : 
+   28766           0 :         if (iwork[6] == *iu) {
+   28767           0 :             wl = work[*n + 1];
+   28768           0 :             wlu = work[*n + 3];
+   28769           0 :             nwl = iwork[1];
+   28770           0 :             wu = work[*n + 4];
+   28771           0 :             wul = work[*n + 2];
+   28772           0 :             nwu = iwork[4];
+   28773             :         } else {
+   28774           0 :             wl = work[*n + 2];
+   28775           0 :             wlu = work[*n + 4];
+   28776           0 :             nwl = iwork[2];
+   28777           0 :             wu = work[*n + 3];
+   28778           0 :             wul = work[*n + 1];
+   28779           0 :             nwu = iwork[3];
+   28780             :         }
+   28781             : 
+   28782           0 :         if (nwl < 0 || nwl >= *n || nwu < 1 || nwu > *n) {
+   28783           0 :             *info = 4;
+   28784           0 :             return;
+   28785             :         }
+   28786             :     } else {
+   28787             : 
+   28788             : 
+   28789             :       /* avoid warnings for high gcc optimization */
+   28790             :       wlu = wul = 1.0;
+   28791             : 
+   28792           0 :         d__3 = std::abs(d__[1]) + std::abs(e[1]);
+   28793           0 :         d__4 = std::abs(d__[*n]) + std::abs(e[*n - 1]);
+   28794           0 :         tnorm = (d__3>d__4) ? d__3 : d__4;
+   28795             : 
+   28796             :         i__1 = *n - 1;
+   28797           0 :         for (j = 2; j <= i__1; ++j) {
+   28798             :             d__4 = tnorm;
+   28799           0 :             d__5 = std::abs(d__[j]) + std::abs(e[j - 1]) + std::abs(e[j]);
+   28800           0 :             tnorm = (d__4>d__5) ? d__4 : d__5;
+   28801             :         }
+   28802             : 
+   28803           0 :         if (*abstol <= 0.) {
+   28804           0 :             atoli = ulp * tnorm;
+   28805             :         } else {
+   28806           0 :             atoli = *abstol;
+   28807             :         }
+   28808             : 
+   28809           0 :         if (irange == 2) {
+   28810           0 :             wl = *vl;
+   28811           0 :             wu = *vu;
+   28812             :         } else {
+   28813             :             wl = 0.;
+   28814             :             wu = 0.;
+   28815             :         }
+   28816             :     }
+   28817             : 
+   28818           0 :     *m = 0;
+   28819             :     iend = 0;
+   28820           0 :     *info = 0;
+   28821             :     nwl = 0;
+   28822             :     nwu = 0;
+   28823             : 
+   28824           0 :     i__1 = *nsplit;
+   28825           0 :     for (jb = 1; jb <= i__1; ++jb) {
+   28826             :         ioff = iend;
+   28827           0 :         ibegin = ioff + 1;
+   28828           0 :         iend = isplit[jb];
+   28829           0 :         in = iend - ioff;
+   28830             : 
+   28831           0 :         if (in == 1) {
+   28832             : 
+   28833           0 :             if (irange == 1 || wl >= d__[ibegin] - pivmin) {
+   28834           0 :                 ++nwl;
+   28835             :             }
+   28836           0 :             if (irange == 1 || wu >= d__[ibegin] - pivmin) {
+   28837           0 :                 ++nwu;
+   28838             :             }
+   28839           0 :             if (irange == 1 || ((wl < d__[ibegin] - pivmin) && (wu >= d__[ibegin] - pivmin))) {
+   28840           0 :                 ++(*m);
+   28841           0 :                 w[*m] = d__[ibegin];
+   28842           0 :                 iblock[*m] = jb;
+   28843             :             }
+   28844             :         } else {
+   28845             : 
+   28846           0 :             gu = d__[ibegin];
+   28847             :             gl = d__[ibegin];
+   28848             :             tmp1 = 0.;
+   28849             : 
+   28850             :             i__2 = iend - 1;
+   28851           0 :             for (j = ibegin; j <= i__2; ++j) {
+   28852           0 :                 tmp2 = std::abs(e[j]);
+   28853           0 :                 d__1 = gu, d__2 = d__[j] + tmp1 + tmp2;
+   28854           0 :                 gu = (d__1>d__2) ? d__1 : d__2;
+   28855           0 :                 d__1 = gl, d__2 = d__[j] - tmp1 - tmp2;
+   28856           0 :                 gl = (d__1<d__2) ? d__1 : d__2;
+   28857             :                 tmp1 = tmp2;
+   28858             :             }
+   28859             : 
+   28860           0 :             d__1 = gu, d__2 = d__[iend] + tmp1;
+   28861           0 :             gu = (d__1>d__2) ? d__1 : d__2;
+   28862           0 :             d__1 = gl, d__2 = d__[iend] - tmp1;
+   28863           0 :             gl = (d__1<d__2) ? d__1 : d__2;
+   28864             :             d__1 = std::abs(gl);
+   28865             :             d__2 = std::abs(gu);
+   28866           0 :             bnorm = (d__1>d__2) ? d__1 : d__2;
+   28867           0 :             gl = gl - bnorm * 2. * ulp * in - pivmin * 2.;
+   28868           0 :             gu = gu + bnorm * 2. * ulp * in + pivmin * 2.;
+   28869             : 
+   28870           0 :             if (*abstol <= 0.) {
+   28871             :                 d__1 = std::abs(gl);
+   28872             :                 d__2 = std::abs(gu);
+   28873           0 :                 atoli = ulp * ((d__1>d__2) ? d__1 : d__2);
+   28874             :             } else {
+   28875           0 :                 atoli = *abstol;
+   28876             :             }
+   28877             : 
+   28878           0 :             if (irange > 1) {
+   28879           0 :                 if (gu < wl) {
+   28880           0 :                     nwl += in;
+   28881           0 :                     nwu += in;
+   28882             :                 }
+   28883             :                 gl = (gl>wl) ? gl : wl;
+   28884             :                 gu = (gu<wu) ? gu : wu;
+   28885             :                 if (gl >= gu) {
+   28886             :                 }
+   28887           0 :                 continue;
+   28888             :             }
+   28889             : 
+   28890           0 :             work[*n + 1] = gl;
+   28891           0 :             work[*n + in + 1] = gu;
+   28892           0 :             PLUMED_BLAS_F77_FUNC(slaebz,SLAEBZ)(&c__1, &c__0, &in, &in, &c__1, &nb, &atoli, &rtoli, &
+   28893             :                     pivmin, &d__[ibegin], &e[ibegin], &work[ibegin], idumma, &
+   28894           0 :                     work[*n + 1], &work[*n + (in << 1) + 1], &im, &iwork[1], &
+   28895           0 :                     w[*m + 1], &iblock[*m + 1], &iinfo);
+   28896             : 
+   28897           0 :             nwl += iwork[1];
+   28898           0 :             nwu += iwork[in + 1];
+   28899           0 :             iwoff = *m - iwork[1];
+   28900             : 
+   28901           0 :             itmax = (int) ((log(gu - gl + pivmin) - log(pivmin)) / log(2.)
+   28902           0 :                     ) + 2;
+   28903           0 :             PLUMED_BLAS_F77_FUNC(slaebz,SLAEBZ)(&c__2, &itmax, &in, &in, &c__1, &nb, &atoli, &rtoli, &
+   28904             :                     pivmin, &d__[ibegin], &e[ibegin], &work[ibegin], idumma, &
+   28905           0 :                     work[*n + 1], &work[*n + (in << 1) + 1], &iout, &iwork[1],
+   28906           0 :                      &w[*m + 1], &iblock[*m + 1], &iinfo);
+   28907             : 
+   28908           0 :             i__2 = iout;
+   28909           0 :             for (j = 1; j <= i__2; ++j) {
+   28910           0 :                 tmp1 = (work[j + *n] + work[j + in + *n]) * .5;
+   28911             : 
+   28912           0 :                 if (j > iout - iinfo) {
+   28913             :                     ncnvrg = 1;
+   28914           0 :                     ib = -jb;
+   28915             :                 } else {
+   28916             :                     ib = jb;
+   28917             :                 }
+   28918           0 :                 i__3 = iwork[j + in] + iwoff;
+   28919           0 :                 for (je = iwork[j] + 1 + iwoff; je <= i__3; ++je) {
+   28920           0 :                     w[je] = tmp1;
+   28921           0 :                     iblock[je] = ib;
+   28922             :                 }
+   28923             :             }
+   28924             : 
+   28925           0 :             *m += im;
+   28926             :         }
+   28927             :     }
+   28928             : 
+   28929           0 :     if (irange == 3) {
+   28930           0 :         im = 0;
+   28931           0 :         idiscl = *il - 1 - nwl;
+   28932           0 :         idiscu = nwu - *iu;
+   28933             : 
+   28934           0 :         if (idiscl > 0 || idiscu > 0) {
+   28935           0 :             i__1 = *m;
+   28936           0 :             for (je = 1; je <= i__1; ++je) {
+   28937           0 :                 if (w[je] <= wlu && idiscl > 0) {
+   28938           0 :                     --idiscl;
+   28939           0 :                 } else if (w[je] >= wul && idiscu > 0) {
+   28940           0 :                     --idiscu;
+   28941             :                 } else {
+   28942           0 :                     ++im;
+   28943           0 :                     w[im] = w[je];
+   28944           0 :                     iblock[im] = iblock[je];
+   28945             :                 }
+   28946             :             }
+   28947           0 :             *m = im;
+   28948             :         }
+   28949           0 :         if (idiscl > 0 || idiscu > 0) {
+   28950             : 
+   28951           0 :             if (idiscl > 0) {
+   28952             :                 wkill = wu;
+   28953             :                 i__1 = idiscl;
+   28954           0 :                 for (jdisc = 1; jdisc <= i__1; ++jdisc) {
+   28955             :                     iw = 0;
+   28956           0 :                     i__2 = *m;
+   28957           0 :                     for (je = 1; je <= i__2; ++je) {
+   28958           0 :                         if (iblock[je] != 0 && (w[je] < wkill || iw == 0)) {
+   28959             :                             iw = je;
+   28960             :                             wkill = w[je];
+   28961             :                         }
+   28962             :                     }
+   28963           0 :                     iblock[iw] = 0;
+   28964             :                 }
+   28965             :             }
+   28966           0 :             if (idiscu > 0) {
+   28967             : 
+   28968             :                 wkill = wl;
+   28969             :                 i__1 = idiscu;
+   28970           0 :                 for (jdisc = 1; jdisc <= i__1; ++jdisc) {
+   28971             :                     iw = 0;
+   28972           0 :                     i__2 = *m;
+   28973           0 :                     for (je = 1; je <= i__2; ++je) {
+   28974           0 :                         if (iblock[je] != 0 && (w[je] > wkill || iw == 0)) {
+   28975             :                             iw = je;
+   28976             :                             wkill = w[je];
+   28977             :                         }
+   28978             :                     }
+   28979           0 :                     iblock[iw] = 0;
+   28980             :                 }
+   28981             :             }
+   28982           0 :             im = 0;
+   28983           0 :             i__1 = *m;
+   28984           0 :             for (je = 1; je <= i__1; ++je) {
+   28985           0 :                 if (iblock[je] != 0) {
+   28986           0 :                     ++im;
+   28987           0 :                     w[im] = w[je];
+   28988           0 :                     iblock[im] = iblock[je];
+   28989             :                 }
+   28990             :             }
+   28991           0 :             *m = im;
+   28992             :         }
+   28993           0 :         if (idiscl < 0 || idiscu < 0) {
+   28994             :             toofew = 1;
+   28995             :         }
+   28996             :     }
+   28997             : 
+   28998           0 :     if (iorder == 1 && *nsplit > 1) {
+   28999           0 :         i__1 = *m - 1;
+   29000           0 :         for (je = 1; je <= i__1; ++je) {
+   29001             :             ie = 0;
+   29002           0 :             tmp1 = w[je];
+   29003           0 :             i__2 = *m;
+   29004           0 :             for (j = je + 1; j <= i__2; ++j) {
+   29005           0 :                 if (w[j] < tmp1) {
+   29006             :                     ie = j;
+   29007             :                     tmp1 = w[j];
+   29008             :                 }
+   29009             :             }
+   29010             : 
+   29011           0 :             if (ie != 0) {
+   29012           0 :                 itmp1 = iblock[ie];
+   29013           0 :                 w[ie] = w[je];
+   29014           0 :                 iblock[ie] = iblock[je];
+   29015           0 :                 w[je] = tmp1;
+   29016           0 :                 iblock[je] = itmp1;
+   29017             :             }
+   29018             :         }
+   29019             :     }
+   29020             : 
+   29021           0 :     *info = 0;
+   29022           0 :     if (ncnvrg) {
+   29023           0 :         ++(*info);
+   29024             :     }
+   29025           0 :     if (toofew) {
+   29026           0 :         *info += 2;
+   29027             :     }
+   29028             :     return;
+   29029             : 
+   29030             : }
+   29031             : 
+   29032             : 
+   29033             : }
+   29034             : }
+   29035             : #include <cmath>
+   29036             : #include "blas/blas.h"
+   29037             : #include "lapack.h"
+   29038             : #include "lapack_limits.h"
+   29039             : 
+   29040             : #include "real.h"
+   29041             : 
+   29042             : #include "blas/blas.h"
+   29043             : namespace PLMD{
+   29044             : namespace lapack{
+   29045             : using namespace blas;
+   29046             : void
+   29047           0 : PLUMED_BLAS_F77_FUNC(sstegr,SSTEGR)(const char *jobz, 
+   29048             :         const char *range, 
+   29049             :         int *n, 
+   29050             :         float *d__, 
+   29051             :         float *e, 
+   29052             :         float *vl, 
+   29053             :         float *vu, 
+   29054             :         int *il, 
+   29055             :         int *iu, 
+   29056             :         float *abstol, 
+   29057             :         int *m, 
+   29058             :         float *w, 
+   29059             :         float *z__, 
+   29060             :         int *ldz, 
+   29061             :         int *isuppz,
+   29062             :         float *work, 
+   29063             :         int *lwork, 
+   29064             :         int *iwork, 
+   29065             :         int *liwork, 
+   29066             :         int *info)
+   29067             : {
+   29068             :     int z_dim1, z_offset, i__1, i__2;
+   29069             :     float d__1, d__2;
+   29070           0 :     int c__1 = 1;
+   29071             : 
+   29072             :     int i__, j;
+   29073             :     int jj;
+   29074             :     float eps, tol, tmp, rmin, rmax;
+   29075             :     int itmp;
+   29076             :     float tnrm;
+   29077             :     float scale;
+   29078             :     int iinfo, iindw;
+   29079             :     int lwmin;
+   29080             :     int wantz;
+   29081             :     int iindbl;
+   29082             :     int valeig,alleig,indeig;
+   29083             :     float safmin,minval;
+   29084             :     float bignum;
+   29085             :     int iindwk, indgrs;
+   29086             :     float thresh;
+   29087             :     int iinspl, indwrk, liwmin, nsplit;
+   29088             :     float smlnum;
+   29089             :     int lquery;
+   29090             : 
+   29091             : 
+   29092             :     --d__;
+   29093             :     --e;
+   29094           0 :     --w;
+   29095           0 :     z_dim1 = *ldz;
+   29096           0 :     z_offset = 1 + z_dim1;
+   29097           0 :     z__ -= z_offset;
+   29098           0 :     --isuppz;
+   29099           0 :     --work;
+   29100           0 :     --iwork;
+   29101             : 
+   29102           0 :     wantz = (*jobz=='V' || *jobz=='v');
+   29103           0 :     alleig = (*range=='A' || *range=='a');
+   29104           0 :     valeig = (*range=='V' || *range=='v');
+   29105           0 :     indeig = (*range=='I' || *range=='i');
+   29106             : 
+   29107           0 :     lquery = *lwork == -1 || *liwork == -1;
+   29108           0 :     lwmin = *n * 17;
+   29109           0 :     liwmin = *n * 10;
+   29110             : 
+   29111           0 :     *info = 0;
+   29112           0 :     if (! (wantz || (*jobz=='N' || *jobz=='n'))) {
+   29113           0 :         *info = -1;
+   29114           0 :     } else if (! (alleig || valeig || indeig)) {
+   29115           0 :         *info = -2;
+   29116           0 :     } else if (*n < 0) {
+   29117           0 :         *info = -3;
+   29118           0 :     } else if (valeig && *n > 0 && *vu <= *vl) {
+   29119           0 :         *info = -7;
+   29120           0 :     } else if (indeig && (*il < 1 || *il > *n)) {
+   29121           0 :         *info = -8;
+   29122           0 :     } else if (indeig && (*iu < *il || *iu > *n)) {
+   29123           0 :         *info = -9;
+   29124           0 :     } else if (*ldz < 1 || (wantz && *ldz < *n)) {
+   29125           0 :         *info = -14;
+   29126           0 :     } else if (*lwork < lwmin && ! lquery) {
+   29127           0 :         *info = -17;
+   29128           0 :     } else if (*liwork < liwmin && ! lquery) {
+   29129           0 :         *info = -19;
+   29130             :     }
+   29131           0 :     if (*info == 0) {
+   29132           0 :         work[1] = (float) lwmin;
+   29133           0 :         iwork[1] = liwmin;
+   29134             :     }
+   29135             : 
+   29136           0 :     if (*info != 0) {
+   29137             :         i__1 = -(*info);
+   29138             :         return;
+   29139           0 :     } else if (lquery) {
+   29140             :         return;
+   29141             :     }
+   29142             : 
+   29143           0 :     *m = 0;
+   29144           0 :     if (*n == 0) {
+   29145             :         return;
+   29146             :     }
+   29147             : 
+   29148           0 :     if (*n == 1) {
+   29149           0 :         if (alleig || indeig) {
+   29150           0 :             *m = 1;
+   29151           0 :             w[1] = d__[1];
+   29152             :         } else {
+   29153           0 :             if (*vl < d__[1] && *vu >= d__[1]) {
+   29154           0 :                 *m = 1;
+   29155           0 :                 w[1] = d__[1];
+   29156             :             }
+   29157             :         }
+   29158           0 :         if (wantz) {
+   29159           0 :             z__[z_dim1 + 1] = 1.;
+   29160             :         }
+   29161           0 :         return;
+   29162             :     }
+   29163             : 
+   29164             :     minval = PLUMED_GMX_FLOAT_MIN;
+   29165             :     safmin = minval*(1.0+PLUMED_GMX_FLOAT_EPS);
+   29166             :     eps = PLUMED_GMX_FLOAT_EPS;
+   29167             :     smlnum = safmin / eps;
+   29168             :     bignum = 1. / smlnum;
+   29169             :     rmin =  std::sqrt(smlnum);
+   29170           0 :     d__1 =  std::sqrt(bignum), d__2 = 1. / std::sqrt(sqrt(safmin));
+   29171             :     rmax = (d__1<d__2) ? d__1 : d__2;
+   29172           0 :     scale = 1.;
+   29173           0 :     tnrm = PLUMED_BLAS_F77_FUNC(slanst,SLANST)("M", n, &d__[1], &e[1]);
+   29174           0 :     if (tnrm > 0. && tnrm < rmin) {
+   29175           0 :         scale = rmin / tnrm;
+   29176           0 :     } else if (tnrm > rmax) {
+   29177           0 :         scale = rmax / tnrm;
+   29178             :     }
+   29179           0 :     if ( std::abs(scale-1.0)>PLUMED_GMX_FLOAT_EPS) {
+   29180           0 :         PLUMED_BLAS_F77_FUNC(sscal,SSCAL)(n, &scale, &d__[1], &c__1);
+   29181           0 :         i__1 = *n - 1;
+   29182           0 :         PLUMED_BLAS_F77_FUNC(sscal,SSCAL)(&i__1, &scale, &e[1], &c__1);
+   29183           0 :         tnrm *= scale;
+   29184             :     }
+   29185             :     indgrs = 1;
+   29186           0 :     indwrk = (*n << 1) + 1;
+   29187             : 
+   29188             :     iinspl = 1;
+   29189           0 :     iindbl = *n + 1;
+   29190             :     iindw = (*n << 1) + 1;
+   29191           0 :     iindwk = *n * 3 + 1;
+   29192             : 
+   29193           0 :     thresh = eps * tnrm;
+   29194           0 :     PLUMED_BLAS_F77_FUNC(slarrex,SLARREX)(range, n, vl, vu, il, iu, &d__[1], &e[1], &thresh, &nsplit, &
+   29195           0 :             iwork[iinspl], m, &w[1], &iwork[iindbl], &iwork[iindw], &work[
+   29196           0 :             indgrs], &work[indwrk], &iwork[iindwk], &iinfo);
+   29197             :     
+   29198           0 :     if (iinfo != 0) {
+   29199           0 :         *info = 1;
+   29200           0 :         return;
+   29201             :     }
+   29202             : 
+   29203           0 :     if (wantz) {
+   29204           0 :         d__1 = *abstol, d__2 = (float) (*n) * eps;
+   29205           0 :         tol = (d__1>d__2) ? d__1 : d__2;
+   29206           0 :         PLUMED_BLAS_F77_FUNC(slarrvx,SLARRVX)(n, &d__[1], &e[1], &iwork[iinspl], m, &w[1], &iwork[iindbl], &
+   29207             :                 iwork[iindw], &work[indgrs], &tol, &z__[z_offset], ldz, &
+   29208             :                 isuppz[1], &work[indwrk], &iwork[iindwk], &iinfo);
+   29209           0 :         if (iinfo != 0) {
+   29210           0 :             *info = 2;
+   29211           0 :             return;
+   29212             :         }
+   29213             :     }
+   29214             : 
+   29215           0 :     i__1 = *m;
+   29216           0 :     for (j = 1; j <= i__1; ++j) {
+   29217           0 :         itmp = iwork[iindbl + j - 1];
+   29218           0 :         w[j] += e[iwork[iinspl + itmp - 1]];
+   29219             :     } 
+   29220             : 
+   29221           0 :     if (std::abs(scale-1.0)>PLUMED_GMX_FLOAT_EPS) {
+   29222           0 :         d__1 = 1. / scale;
+   29223           0 :         PLUMED_BLAS_F77_FUNC(sscal,SSCAL)(m, &d__1, &w[1], &c__1);
+   29224             :     }
+   29225           0 :     if (nsplit > 1) {
+   29226           0 :         i__1 = *m - 1;
+   29227           0 :         for (j = 1; j <= i__1; ++j) {
+   29228             :             i__ = 0;
+   29229           0 :             tmp = w[j];
+   29230           0 :             i__2 = *m;
+   29231           0 :             for (jj = j + 1; jj <= i__2; ++jj) {
+   29232           0 :                 if (w[jj] < tmp) {
+   29233             :                     i__ = jj;
+   29234             :                     tmp = w[jj];
+   29235             :                 }
+   29236             :             }
+   29237           0 :             if (i__ != 0) {
+   29238           0 :                 w[i__] = w[j];
+   29239           0 :                 w[j] = tmp;
+   29240           0 :                 if (wantz) {
+   29241           0 :                     PLUMED_BLAS_F77_FUNC(sswap,SSWAP)(n, &z__[i__ * z_dim1 + 1], &c__1, &z__[j * z_dim1 
+   29242           0 :                             + 1], &c__1);
+   29243           0 :                     itmp = isuppz[(i__ << 1) - 1];
+   29244           0 :                     isuppz[(i__ << 1) - 1] = isuppz[(j << 1) - 1];
+   29245           0 :                     isuppz[(j << 1) - 1] = itmp;
+   29246           0 :                     itmp = isuppz[i__ * 2];
+   29247           0 :                     isuppz[i__ * 2] = isuppz[j * 2];
+   29248           0 :                     isuppz[j * 2] = itmp;
+   29249             :                 }
+   29250             :             }
+   29251             :         }
+   29252             :     }
+   29253             : 
+   29254           0 :     work[1] = (float) lwmin;
+   29255           0 :     iwork[1] = liwmin;
+   29256           0 :     return;
+   29257             : 
+   29258             : } 
+   29259             : }
+   29260             : }
+   29261             : #include <cmath>
+   29262             : #include "blas/blas.h"
+   29263             : #include "lapack.h"
+   29264             : #include "lapack_limits.h"
+   29265             : 
+   29266             : #include "real.h"
+   29267             : 
+   29268             : #include "blas/blas.h"
+   29269             : namespace PLMD{
+   29270             : namespace lapack{
+   29271             : using namespace blas;
+   29272             : void
+   29273           0 : PLUMED_BLAS_F77_FUNC(sstein,SSTEIN)(int *n, 
+   29274             :         float *d__, 
+   29275             :         float *e, 
+   29276             :         int *m, 
+   29277             :         float *w, 
+   29278             :         int *iblock,
+   29279             :         int *isplit, 
+   29280             :         float *z__,
+   29281             :         int *ldz, 
+   29282             :         float *work,
+   29283             :         int *iwork, 
+   29284             :         int *ifail,
+   29285             :         int *info)
+   29286             : {
+   29287             :     int z_dim1, z_offset, i__1, i__2, i__3;
+   29288             :     float d__2, d__3, d__4, d__5;
+   29289             : 
+   29290             :     int i__, j, b1, j1, bn;
+   29291             :     float xj, scl, eps, sep, nrm, tol;
+   29292             :     int its;
+   29293             :     float xjm, ztr, eps1;
+   29294             :     int jblk, nblk;
+   29295             :     int jmax;
+   29296             : 
+   29297             :     int iseed[4], gpind, iinfo;
+   29298             :     float ortol;
+   29299             :     int indrv1, indrv2, indrv3, indrv4, indrv5;
+   29300             :     int nrmchk;
+   29301             :     int blksiz;
+   29302             :     float onenrm, dtpcrt, pertol;
+   29303           0 :     int c__2 = 2;
+   29304           0 :     int c__1 = 1;
+   29305           0 :     int c_n1 = -1;
+   29306             : 
+   29307           0 :     --d__;
+   29308           0 :     --e;
+   29309           0 :     --w;
+   29310           0 :     --iblock;
+   29311           0 :     --isplit;
+   29312           0 :     z_dim1 = *ldz;
+   29313           0 :     z_offset = 1 + z_dim1;
+   29314           0 :     z__ -= z_offset;
+   29315           0 :     --work;
+   29316             :     --iwork;
+   29317           0 :     --ifail;
+   29318             : 
+   29319           0 :     *info = 0;
+   29320             : 
+   29321             :     xjm = 0.0;
+   29322           0 :     i__1 = *m;
+   29323           0 :     for (i__ = 1; i__ <= i__1; ++i__) {
+   29324           0 :         ifail[i__] = 0;
+   29325             :     }
+   29326             : 
+   29327           0 :     if (*n < 0) {
+   29328           0 :         *info = -1;
+   29329           0 :     } else if (*m < 0 || *m > *n) {
+   29330           0 :         *info = -4;
+   29331           0 :     } else if (*ldz < (*n)) {
+   29332           0 :         *info = -9;
+   29333             :     } else {
+   29334             :         i__1 = *m;
+   29335           0 :         for (j = 2; j <= i__1; ++j) {
+   29336           0 :             if (iblock[j] < iblock[j - 1]) {
+   29337           0 :                 *info = -6;
+   29338           0 :                 break;
+   29339             :             }
+   29340           0 :             if (iblock[j] == iblock[j - 1] && w[j] < w[j - 1]) {
+   29341           0 :                 *info = -5;
+   29342           0 :                 break;
+   29343             :             }
+   29344             :         }
+   29345             :     }
+   29346             : 
+   29347           0 :     if (*info != 0) {
+   29348             :         return;
+   29349             :     }
+   29350             : 
+   29351           0 :     if (*n == 0 || *m == 0) {
+   29352             :         return;
+   29353           0 :     } else if (*n == 1) {
+   29354           0 :         z__[z_dim1 + 1] = 1.;
+   29355           0 :         return;
+   29356             :     }
+   29357             : 
+   29358             :     eps = PLUMED_GMX_FLOAT_EPS;
+   29359             : 
+   29360           0 :     for (i__ = 1; i__ <= 4; ++i__) {
+   29361           0 :         iseed[i__ - 1] = 1;
+   29362             :     }
+   29363             : 
+   29364             :     indrv1 = 0;
+   29365             :     indrv2 = indrv1 + *n;
+   29366           0 :     indrv3 = indrv2 + *n;
+   29367           0 :     indrv4 = indrv3 + *n;
+   29368           0 :     indrv5 = indrv4 + *n;
+   29369             : 
+   29370             :     j1 = 1;
+   29371           0 :     i__1 = iblock[*m];
+   29372           0 :     for (nblk = 1; nblk <= i__1; ++nblk) {
+   29373             : 
+   29374           0 :         if (nblk == 1) {
+   29375             :             b1 = 1;
+   29376             :         } else {
+   29377           0 :             b1 = isplit[nblk - 1] + 1;
+   29378             :         }
+   29379           0 :         bn = isplit[nblk];
+   29380           0 :         blksiz = bn - b1 + 1;
+   29381           0 :         if (blksiz == 1) {
+   29382           0 :             continue;
+   29383             :         }
+   29384             :         gpind = b1;
+   29385             : 
+   29386           0 :         onenrm = std::abs(d__[b1]) + std::abs(e[b1]);
+   29387             :         d__3 = onenrm;
+   29388           0 :         d__4 = std::abs(d__[bn]) + std::abs(e[bn - 1]);
+   29389           0 :         onenrm = (d__3>d__4) ? d__3 : d__4;
+   29390             :         i__2 = bn - 1;
+   29391           0 :         for (i__ = b1 + 1; i__ <= i__2; ++i__) {
+   29392             :           d__4 = onenrm;
+   29393           0 :           d__5 = std::abs(d__[i__]) + std::abs(e[i__ - 1]) + std::abs(e[i__]);
+   29394           0 :             onenrm = (d__4>d__5) ? d__4 : d__5;
+   29395             :         }
+   29396           0 :         ortol = onenrm * .001;
+   29397             : 
+   29398           0 :         dtpcrt =  std::sqrt(.1 / blksiz);
+   29399             : 
+   29400             :         jblk = 0;
+   29401           0 :         i__2 = *m;
+   29402           0 :         for (j = j1; j <= i__2; ++j) {
+   29403           0 :             if (iblock[j] != nblk) {
+   29404             :                 j1 = j;
+   29405             :                 break;
+   29406             :             }
+   29407           0 :             ++jblk;
+   29408           0 :             xj = w[j];
+   29409             : 
+   29410           0 :             if (blksiz == 1) {
+   29411           0 :                 work[indrv1 + 1] = 1.;
+   29412           0 :                 goto L120;
+   29413             :             }
+   29414             : 
+   29415           0 :             if (jblk > 1) {
+   29416           0 :                 eps1 = std::abs(eps * xj);
+   29417           0 :                 pertol = eps1 * 10.;
+   29418           0 :                 sep = xj - xjm;
+   29419           0 :                 if (sep < pertol) {
+   29420           0 :                     xj = xjm + pertol;
+   29421             :                 }
+   29422             :             }
+   29423             : 
+   29424             :             its = 0;
+   29425             :             nrmchk = 0;
+   29426             : 
+   29427           0 :             PLUMED_BLAS_F77_FUNC(slarnv,SLARNV)(&c__2, iseed, &blksiz, &work[indrv1 + 1]);
+   29428             : 
+   29429           0 :             PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&blksiz, &d__[b1], &c__1, &work[indrv4 + 1], &c__1);
+   29430           0 :             i__3 = blksiz - 1;
+   29431           0 :             PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&i__3, &e[b1], &c__1, &work[indrv2 + 2], &c__1);
+   29432           0 :             i__3 = blksiz - 1;
+   29433           0 :             PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&i__3, &e[b1], &c__1, &work[indrv3 + 1], &c__1);
+   29434             : 
+   29435           0 :             tol = 0.;
+   29436           0 :             PLUMED_BLAS_F77_FUNC(slagtf,SLAGTF)(&blksiz, &work[indrv4 + 1], &xj, &work[indrv2 + 2], &work[
+   29437           0 :                     indrv3 + 1], &tol, &work[indrv5 + 1], &iwork[1], &iinfo);
+   29438             : 
+   29439           0 : L70:
+   29440           0 :             ++its;
+   29441           0 :             if (its > 5) {
+   29442           0 :                 goto L100;
+   29443             :             }
+   29444             : 
+   29445             :             d__2 = eps;
+   29446           0 :             d__3 = std::abs(work[indrv4 + blksiz]);
+   29447           0 :             scl = blksiz * onenrm * ((d__2>d__3) ? d__2 : d__3) / PLUMED_BLAS_F77_FUNC(sasum,SASUM)(&blksiz, &work[
+   29448             :                     indrv1 + 1], &c__1);
+   29449           0 :             PLUMED_BLAS_F77_FUNC(sscal,SSCAL)(&blksiz, &scl, &work[indrv1 + 1], &c__1);
+   29450             : 
+   29451           0 :             PLUMED_BLAS_F77_FUNC(slagts,SLAGTS)(&c_n1, &blksiz, &work[indrv4 + 1], &work[indrv2 + 2], &
+   29452             :                     work[indrv3 + 1], &work[indrv5 + 1], &iwork[1], &work[
+   29453             :                     indrv1 + 1], &tol, &iinfo);
+   29454             : 
+   29455           0 :             if (jblk == 1) {
+   29456           0 :                 goto L90;
+   29457             :             }
+   29458           0 :             if (std::abs(xj - xjm) > ortol) {
+   29459             :                 gpind = j;
+   29460             :             }
+   29461           0 :             if (gpind != j) {
+   29462           0 :                 i__3 = j - 1;
+   29463           0 :                 for (i__ = gpind; i__ <= i__3; ++i__) {
+   29464           0 :                     ztr = -PLUMED_BLAS_F77_FUNC(sdot,SDOT)(&blksiz, &work[indrv1 + 1], &c__1, &z__[b1 + 
+   29465           0 :                             i__ * z_dim1], &c__1);
+   29466           0 :                     PLUMED_BLAS_F77_FUNC(saxpy,SAXPY)(&blksiz, &ztr, &z__[b1 + i__ * z_dim1], &c__1, &
+   29467             :                             work[indrv1 + 1], &c__1);
+   29468             :                 }
+   29469             :             }
+   29470             : 
+   29471           0 : L90:
+   29472           0 :             jmax = PLUMED_BLAS_F77_FUNC(isamax,ISAMAX)(&blksiz, &work[indrv1 + 1], &c__1);
+   29473           0 :             nrm = std::abs(work[indrv1 + jmax]);
+   29474             : 
+   29475           0 :             if (nrm < dtpcrt) {
+   29476           0 :                 goto L70;
+   29477             :             }
+   29478           0 :             ++nrmchk;
+   29479           0 :             if (nrmchk < 3) {
+   29480           0 :                 goto L70;
+   29481             :             }
+   29482             : 
+   29483           0 :             goto L110;
+   29484             : 
+   29485             : L100:
+   29486           0 :             ++(*info);
+   29487           0 :             ifail[*info] = j;
+   29488             : 
+   29489           0 : L110:
+   29490           0 :             scl = 1. / PLUMED_BLAS_F77_FUNC(snrm2,SNRM2)(&blksiz, &work[indrv1 + 1], &c__1);
+   29491           0 :             jmax = PLUMED_BLAS_F77_FUNC(isamax,ISAMAX)(&blksiz, &work[indrv1 + 1], &c__1);
+   29492           0 :             if (work[indrv1 + jmax] < 0.) {
+   29493           0 :                 scl = -scl;
+   29494             :             }
+   29495           0 :             PLUMED_BLAS_F77_FUNC(sscal,SSCAL)(&blksiz, &scl, &work[indrv1 + 1], &c__1);
+   29496           0 : L120:
+   29497           0 :             i__3 = *n;
+   29498           0 :             for (i__ = 1; i__ <= i__3; ++i__) {
+   29499           0 :                 z__[i__ + j * z_dim1] = 0.;
+   29500             :             }
+   29501           0 :             i__3 = blksiz;
+   29502           0 :             for (i__ = 1; i__ <= i__3; ++i__) {
+   29503           0 :                 z__[b1 + i__ - 1 + j * z_dim1] = work[indrv1 + i__];
+   29504             :             }
+   29505             : 
+   29506           0 :             xjm = xj;
+   29507             :         }
+   29508             :     }
+   29509             : 
+   29510             :     return;
+   29511             : 
+   29512             : }
+   29513             : 
+   29514             : 
+   29515             : }
+   29516             : }
+   29517             : #include <cmath>
+   29518             : #include "real.h"
+   29519             : 
+   29520             : #include "blas/blas.h"
+   29521             : #include "lapack.h"
+   29522             : #include "lapack_limits.h"
+   29523             : 
+   29524             : #include "blas/blas.h"
+   29525             : namespace PLMD{
+   29526             : namespace lapack{
+   29527             : using namespace blas;
+   29528             : void
+   29529           0 : PLUMED_BLAS_F77_FUNC(ssteqr,SSTEQR)(const char *    compz, 
+   29530             :                         int *     n, 
+   29531             :                         float *  d__, 
+   29532             :                         float *  e, 
+   29533             :                         float *  z__, 
+   29534             :                         int *     ldz, 
+   29535             :                         float *  work, 
+   29536             :                         int *     info)
+   29537             : {
+   29538           0 :     float c_b9 = 0.;
+   29539           0 :     float c_b10 = 1.;
+   29540           0 :     int c__0 = 0;
+   29541           0 :     int c__1 = 1;
+   29542           0 :     int c__2 = 2;
+   29543             :     int z_dim1, z_offset, i__1, i__2;
+   29544             :     float d__1, d__2;
+   29545             : 
+   29546             :     float b, c__, f, g;
+   29547             :     int i__, j, k, l, m;
+   29548             :     float p, r__, s;
+   29549             :     int l1, ii, mm, lm1, mm1, nm1;
+   29550             :     float rt1, rt2, eps;
+   29551             :     int lsv;
+   29552             :     float tst, eps2;
+   29553             :     int lend, jtot;
+   29554             :     float anorm;
+   29555             :     int lendm1, lendp1;
+   29556             :     int iscale;
+   29557             :     float safmin,minval;
+   29558             :     float safmax;
+   29559             :     int lendsv;
+   29560             :     float ssfmin;
+   29561             :     int nmaxit, icompz;
+   29562             :     float ssfmax;
+   29563             : 
+   29564             : 
+   29565           0 :     --d__;
+   29566           0 :     --e;
+   29567           0 :     z_dim1 = *ldz;
+   29568           0 :     z_offset = 1 + z_dim1;
+   29569           0 :     z__ -= z_offset;
+   29570           0 :     --work;
+   29571             : 
+   29572           0 :     *info = 0;
+   29573             : 
+   29574           0 :     if (*compz=='N' || *compz=='n') {
+   29575             :         icompz = 0;
+   29576           0 :     } else if (*compz=='V' || *compz=='v') {
+   29577             :         icompz = 1;
+   29578             :     } else if (*compz=='I' || *compz=='i') {
+   29579             :         icompz = 2;
+   29580             :     } else {
+   29581             :         icompz = -1;
+   29582             :     }
+   29583             :     if (icompz < 0) {
+   29584           0 :         *info = -1;
+   29585           0 :     } else if (*n < 0) {
+   29586           0 :         *info = -2;
+   29587           0 :     } else if (*ldz < 1 || (icompz > 0 && *ldz < ((*n>1) ? *n : 1))) {
+   29588           0 :         *info = -6;
+   29589             :     }
+   29590           0 :     if (*info != 0) {
+   29591             :         return;
+   29592             :     }
+   29593             : 
+   29594             : 
+   29595           0 :     if (*n == 0) {
+   29596             :         return;
+   29597             :     }
+   29598             : 
+   29599           0 :     if (*n == 1) {
+   29600           0 :         if (icompz == 2) {
+   29601           0 :             z__[z_dim1 + 1] = 1.;
+   29602             :         }
+   29603           0 :         return;
+   29604             :     }
+   29605             : 
+   29606             :     eps = PLUMED_GMX_FLOAT_EPS;
+   29607             :     d__1 = eps;
+   29608             :     eps2 = d__1 * d__1;
+   29609             :     minval = PLUMED_GMX_FLOAT_MIN;
+   29610             :     safmin = minval*(1.0+PLUMED_GMX_FLOAT_EPS);
+   29611             : 
+   29612             :     safmax = 1. / safmin;
+   29613           0 :     ssfmax =  std::sqrt(safmax) / 3.;
+   29614           0 :     ssfmin =  std::sqrt(safmin) / eps2;
+   29615             : 
+   29616           0 :     if (icompz == 2) {
+   29617           0 :         PLUMED_BLAS_F77_FUNC(slaset,SLASET)("Full", n, n, &c_b9, &c_b10, &z__[z_offset], ldz);
+   29618             :     }
+   29619             : 
+   29620           0 :     nmaxit = *n * 30;
+   29621             :     jtot = 0;
+   29622             : 
+   29623             :     l1 = 1;
+   29624           0 :     nm1 = *n - 1;
+   29625             : 
+   29626           0 : L10:
+   29627           0 :     if (l1 > *n) {
+   29628           0 :         goto L160;
+   29629             :     }
+   29630           0 :     if (l1 > 1) {
+   29631           0 :         e[l1 - 1] = 0.;
+   29632             :     }
+   29633           0 :     if (l1 <= nm1) {
+   29634           0 :         i__1 = nm1;
+   29635           0 :         for (m = l1; m <= i__1; ++m) {
+   29636           0 :             tst = std::abs(e[m]);
+   29637           0 :             if (std::abs(tst)<PLUMED_GMX_FLOAT_MIN) {
+   29638           0 :                 goto L30;
+   29639             :             }
+   29640           0 :             if (tst <=  std::sqrt(std::abs(d__[m])) * std::sqrt(std::abs(d__[m + 1])) * eps) {
+   29641           0 :                 e[m] = 0.;
+   29642           0 :                 goto L30;
+   29643             :             }
+   29644             :         }
+   29645             :     }
+   29646           0 :     m = *n;
+   29647             : 
+   29648           0 : L30:
+   29649             :     l = l1;
+   29650             :     lsv = l;
+   29651             :     lend = m;
+   29652             :     lendsv = lend;
+   29653           0 :     l1 = m + 1;
+   29654           0 :     if (lend == l) {
+   29655           0 :         goto L10;
+   29656             :     }
+   29657             : 
+   29658           0 :     i__1 = lend - l + 1;
+   29659           0 :     anorm = PLUMED_BLAS_F77_FUNC(slanst,SLANST)("I", &i__1, &d__[l], &e[l]);
+   29660             :     iscale = 0;
+   29661           0 :     if (std::abs(anorm)<PLUMED_GMX_FLOAT_MIN) {
+   29662           0 :         goto L10;
+   29663             :     }
+   29664           0 :     if (anorm > ssfmax) {
+   29665             :         iscale = 1;
+   29666           0 :         i__1 = lend - l + 1;
+   29667           0 :         PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G", &c__0, &c__0, &anorm, &ssfmax, &i__1, &c__1, &d__[l], n, 
+   29668             :                 info);
+   29669           0 :         i__1 = lend - l;
+   29670           0 :         PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G", &c__0, &c__0, &anorm, &ssfmax, &i__1, &c__1, &e[l], n, 
+   29671             :                 info);
+   29672           0 :     } else if (anorm < ssfmin) {
+   29673             :         iscale = 2;
+   29674           0 :         i__1 = lend - l + 1;
+   29675           0 :         PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G", &c__0, &c__0, &anorm, &ssfmin, &i__1, &c__1, &d__[l], n, 
+   29676             :                 info);
+   29677           0 :         i__1 = lend - l;
+   29678           0 :         PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G", &c__0, &c__0, &anorm, &ssfmin, &i__1, &c__1, &e[l], n, 
+   29679             :                 info);
+   29680             :     }
+   29681             : 
+   29682           0 :     if (std::abs(d__[lend]) < std::abs(d__[l])) {
+   29683             :         lend = lsv;
+   29684             :         l = lendsv;
+   29685             :     }
+   29686             : 
+   29687           0 :     if (lend > l) {
+   29688             : 
+   29689           0 : L40:
+   29690           0 :         if (l != lend) {
+   29691           0 :             lendm1 = lend - 1;
+   29692           0 :             i__1 = lendm1;
+   29693           0 :             for (m = l; m <= i__1; ++m) {
+   29694           0 :                 d__2 = std::abs(e[m]);
+   29695           0 :                 tst = d__2 * d__2;
+   29696           0 :                 if (tst <= eps2 * std::abs(d__[m]) * std::abs(d__[m+ 1]) + safmin) {
+   29697           0 :                     goto L60;
+   29698             :                 }
+   29699             :             }
+   29700             :         }
+   29701             : 
+   29702             :         m = lend;
+   29703             : 
+   29704           0 : L60:
+   29705           0 :         if (m < lend) {
+   29706           0 :             e[m] = 0.;
+   29707             :         }
+   29708           0 :         p = d__[l];
+   29709           0 :         if (m == l) {
+   29710           0 :             goto L80;
+   29711             :         }
+   29712             : 
+   29713           0 :         if (m == l + 1) {
+   29714           0 :             if (icompz > 0) {
+   29715           0 :                 PLUMED_BLAS_F77_FUNC(slaev2,SLAEV2)(&d__[l], &e[l], &d__[l + 1], &rt1, &rt2, &c__, &s);
+   29716           0 :                 work[l] = c__;
+   29717           0 :                 work[*n - 1 + l] = s;
+   29718           0 :                 PLUMED_BLAS_F77_FUNC(slasr,SLASR)("R", "V", "B", n, &c__2, &work[l], &work[*n - 1 + l], &
+   29719           0 :                         z__[l * z_dim1 + 1], ldz);
+   29720             :             } else {
+   29721           0 :                 PLUMED_BLAS_F77_FUNC(slae2,SLAE2)(&d__[l], &e[l], &d__[l + 1], &rt1, &rt2);
+   29722             :             }
+   29723           0 :             d__[l] = rt1;
+   29724           0 :             d__[l + 1] = rt2;
+   29725           0 :             e[l] = 0.;
+   29726           0 :             l += 2;
+   29727           0 :             if (l <= lend) {
+   29728           0 :                 goto L40;
+   29729             :             }
+   29730           0 :             goto L140;
+   29731             :         }
+   29732             : 
+   29733           0 :         if (jtot == nmaxit) {
+   29734           0 :             goto L140;
+   29735             :         }
+   29736           0 :         ++jtot;
+   29737             : 
+   29738           0 :         g = (d__[l + 1] - p) / (e[l] * 2.);
+   29739           0 :         r__ = PLUMED_BLAS_F77_FUNC(slapy2,SLAPY2)(&g, &c_b10);
+   29740           0 :         g = d__[m] - p + e[l] / (g + ( (g>0) ? r__ : -r__ ) );
+   29741             : 
+   29742           0 :         s = 1.;
+   29743           0 :         c__ = 1.;
+   29744             :         p = 0.;
+   29745             : 
+   29746           0 :         mm1 = m - 1;
+   29747           0 :         i__1 = l;
+   29748           0 :         for (i__ = mm1; i__ >= i__1; --i__) {
+   29749           0 :             f = s * e[i__];
+   29750           0 :             b = c__ * e[i__];
+   29751           0 :             PLUMED_BLAS_F77_FUNC(slartg,SLARTG)(&g, &f, &c__, &s, &r__);
+   29752           0 :             if (i__ != m - 1) {
+   29753           0 :                 e[i__ + 1] = r__;
+   29754             :             }
+   29755           0 :             g = d__[i__ + 1] - p;
+   29756           0 :             r__ = (d__[i__] - g) * s + c__ * 2. * b;
+   29757           0 :             p = s * r__;
+   29758           0 :             d__[i__ + 1] = g + p;
+   29759           0 :             g = c__ * r__ - b;
+   29760             : 
+   29761           0 :             if (icompz > 0) {
+   29762           0 :                 work[i__] = c__;
+   29763           0 :                 work[*n - 1 + i__] = -s;
+   29764             :             }
+   29765             :         }
+   29766             : 
+   29767           0 :         if (icompz > 0) {
+   29768           0 :             mm = m - l + 1;
+   29769           0 :             PLUMED_BLAS_F77_FUNC(slasr,SLASR)("R", "V", "B", n, &mm, &work[l], &work[*n - 1 + l], &z__[l 
+   29770           0 :                     * z_dim1 + 1], ldz);
+   29771             :         }
+   29772             : 
+   29773           0 :         d__[l] -= p;
+   29774           0 :         e[l] = g;
+   29775           0 :         goto L40;
+   29776             : 
+   29777             : L80:
+   29778             :         d__[l] = p;
+   29779             : 
+   29780           0 :         ++l;
+   29781           0 :         if (l <= lend) {
+   29782           0 :             goto L40;
+   29783             :         }
+   29784           0 :         goto L140;
+   29785             : 
+   29786             :     } else {
+   29787             : 
+   29788           0 : L90:
+   29789           0 :         if (l != lend) {
+   29790           0 :             lendp1 = lend + 1;
+   29791           0 :             i__1 = lendp1;
+   29792           0 :             for (m = l; m >= i__1; --m) {
+   29793           0 :                 d__2 = std::abs(e[m - 1]);
+   29794           0 :                 tst = d__2 * d__2;
+   29795           0 :                 if (tst <= eps2 * std::abs(d__[m]) * std::abs(d__[m- 1]) + safmin) {
+   29796           0 :                     goto L110;
+   29797             :                 }
+   29798             :             }
+   29799             :         }
+   29800             : 
+   29801             :         m = lend;
+   29802             : 
+   29803           0 : L110:
+   29804           0 :         if (m > lend) {
+   29805           0 :             e[m - 1] = 0.;
+   29806             :         }
+   29807           0 :         p = d__[l];
+   29808           0 :         if (m == l) {
+   29809           0 :             goto L130;
+   29810             :         }
+   29811           0 :         if (m == l - 1) {
+   29812           0 :             if (icompz > 0) {
+   29813           0 :                 PLUMED_BLAS_F77_FUNC(slaev2,SLAEV2)(&d__[l - 1], &e[l - 1], &d__[l], &rt1, &rt2, &c__, &s)
+   29814             :                         ;
+   29815           0 :                 work[m] = c__;
+   29816           0 :                 work[*n - 1 + m] = s;
+   29817           0 :                 PLUMED_BLAS_F77_FUNC(slasr,SLASR)("R", "V", "F", n, &c__2, &work[m], &work[*n - 1 + m], &
+   29818           0 :                         z__[(l - 1) * z_dim1 + 1], ldz);
+   29819             :             } else {
+   29820           0 :                 PLUMED_BLAS_F77_FUNC(slae2,SLAE2)(&d__[l - 1], &e[l - 1], &d__[l], &rt1, &rt2);
+   29821             :             }
+   29822           0 :             d__[l - 1] = rt1;
+   29823           0 :             d__[l] = rt2;
+   29824           0 :             e[l - 1] = 0.;
+   29825           0 :             l += -2;
+   29826           0 :             if (l >= lend) {
+   29827           0 :                 goto L90;
+   29828             :             }
+   29829           0 :             goto L140;
+   29830             :         }
+   29831             : 
+   29832           0 :         if (jtot == nmaxit) {
+   29833           0 :             goto L140;
+   29834             :         }
+   29835           0 :         ++jtot;
+   29836             : 
+   29837           0 :         g = (d__[l - 1] - p) / (e[l - 1] * 2.);
+   29838           0 :         r__ = PLUMED_BLAS_F77_FUNC(slapy2,SLAPY2)(&g, &c_b10);
+   29839           0 :         g = d__[m] - p + e[l - 1] / (g + ( (g>0) ? r__ : -r__ ));
+   29840             : 
+   29841           0 :         s = 1.;
+   29842           0 :         c__ = 1.;
+   29843             :         p = 0.;
+   29844             : 
+   29845             :         lm1 = l - 1;
+   29846           0 :         i__1 = lm1;
+   29847           0 :         for (i__ = m; i__ <= i__1; ++i__) {
+   29848           0 :             f = s * e[i__];
+   29849           0 :             b = c__ * e[i__];
+   29850           0 :             PLUMED_BLAS_F77_FUNC(slartg,SLARTG)(&g, &f, &c__, &s, &r__);
+   29851           0 :             if (i__ != m) {
+   29852           0 :                 e[i__ - 1] = r__;
+   29853             :             }
+   29854           0 :             g = d__[i__] - p;
+   29855           0 :             r__ = (d__[i__ + 1] - g) * s + c__ * 2. * b;
+   29856           0 :             p = s * r__;
+   29857           0 :             d__[i__] = g + p;
+   29858           0 :             g = c__ * r__ - b;
+   29859             : 
+   29860           0 :             if (icompz > 0) {
+   29861           0 :                 work[i__] = c__;
+   29862           0 :                 work[*n - 1 + i__] = s;
+   29863             :             }
+   29864             :         }
+   29865             : 
+   29866           0 :         if (icompz > 0) {
+   29867           0 :             mm = l - m + 1;
+   29868           0 :             PLUMED_BLAS_F77_FUNC(slasr,SLASR)("R", "V", "F", n, &mm, &work[m], &work[*n - 1 + m], &z__[m 
+   29869           0 :                     * z_dim1 + 1], ldz);
+   29870             :         }
+   29871             : 
+   29872           0 :         d__[l] -= p;
+   29873           0 :         e[lm1] = g;
+   29874           0 :         goto L90;
+   29875             : 
+   29876             : L130:
+   29877             :         d__[l] = p;
+   29878             : 
+   29879           0 :         --l;
+   29880           0 :         if (l >= lend) {
+   29881           0 :             goto L90;
+   29882             :         }
+   29883           0 :         goto L140;
+   29884             : 
+   29885             :     }
+   29886             : 
+   29887           0 : L140:
+   29888           0 :     if (iscale == 1) {
+   29889           0 :         i__1 = lendsv - lsv + 1;
+   29890           0 :         PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G", &c__0, &c__0, &ssfmax, &anorm, &i__1, &c__1, &d__[lsv], 
+   29891             :                 n, info);
+   29892           0 :         i__1 = lendsv - lsv;
+   29893           0 :         PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G", &c__0, &c__0, &ssfmax, &anorm, &i__1, &c__1, &e[lsv], n, 
+   29894             :                 info);
+   29895           0 :     } else if (iscale == 2) {
+   29896           0 :         i__1 = lendsv - lsv + 1;
+   29897           0 :         PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G", &c__0, &c__0, &ssfmin, &anorm, &i__1, &c__1, &d__[lsv], 
+   29898             :                 n, info);
+   29899           0 :         i__1 = lendsv - lsv;
+   29900           0 :         PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G", &c__0, &c__0, &ssfmin, &anorm, &i__1, &c__1, &e[lsv], n, 
+   29901             :                 info);
+   29902             :     }
+   29903             : 
+   29904           0 :     if (jtot < nmaxit) {
+   29905           0 :         goto L10;
+   29906             :     }
+   29907           0 :     i__1 = *n - 1;
+   29908           0 :     for (i__ = 1; i__ <= i__1; ++i__) {
+   29909           0 :         if (std::abs(e[i__])>PLUMED_GMX_FLOAT_MIN) {
+   29910           0 :             ++(*info);
+   29911             :         }
+   29912             :     }
+   29913           0 :     goto L190;
+   29914             : 
+   29915             : L160:
+   29916           0 :     if (icompz == 0) {
+   29917             : 
+   29918           0 :         PLUMED_BLAS_F77_FUNC(slasrt,SLASRT)("I", n, &d__[1], info);
+   29919             : 
+   29920             :     } else {
+   29921             : 
+   29922           0 :         i__1 = *n;
+   29923           0 :         for (ii = 2; ii <= i__1; ++ii) {
+   29924           0 :             i__ = ii - 1;
+   29925             :             k = i__;
+   29926           0 :             p = d__[i__];
+   29927           0 :             i__2 = *n;
+   29928           0 :             for (j = ii; j <= i__2; ++j) {
+   29929           0 :                 if (d__[j] < p) {
+   29930             :                     k = j;
+   29931             :                     p = d__[j];
+   29932             :                 }
+   29933             :             }
+   29934           0 :             if (k != i__) {
+   29935           0 :                 d__[k] = d__[i__];
+   29936           0 :                 d__[i__] = p;
+   29937           0 :                 PLUMED_BLAS_F77_FUNC(sswap,SSWAP)(n, &z__[i__ * z_dim1 + 1], &c__1, &z__[k * z_dim1 + 1],
+   29938             :                          &c__1);
+   29939             :             }
+   29940             :         }
+   29941             :     }
+   29942             : 
+   29943           0 : L190:
+   29944             :     return;
+   29945             : }
+   29946             : 
+   29947             : 
+   29948             : }
+   29949             : }
+   29950             : #include <cmath>
+   29951             : #include "lapack.h"
+   29952             : #include "lapack_limits.h"
+   29953             : 
+   29954             : #include "real.h"
+   29955             : 
+   29956             : #include "blas/blas.h"
+   29957             : namespace PLMD{
+   29958             : namespace lapack{
+   29959             : using namespace blas;
+   29960             : void
+   29961           0 : PLUMED_BLAS_F77_FUNC(ssterf,SSTERF)(int *n, 
+   29962             :         float *d__, 
+   29963             :         float *e, 
+   29964             :         int *info)
+   29965             : {
+   29966             :     int i__1;
+   29967             :     float d__1;
+   29968             : 
+   29969             :     float c__;
+   29970             :     int i__, l, m;
+   29971             :     float p, r__, s;
+   29972             :     int l1;
+   29973             :     float bb, rt1, rt2, eps, rte;
+   29974             :     int lsv;
+   29975             :     float eps2, oldc;
+   29976             :     int lend, jtot;
+   29977             :     float gamma, alpha, sigma, anorm;
+   29978             :       int iscale;
+   29979             :     float oldgam;
+   29980             :     float safmax;
+   29981             :     int lendsv;
+   29982             :     float ssfmin;
+   29983             :     int nmaxit;
+   29984             :     float ssfmax;
+   29985           0 :     int c__0 = 0;
+   29986           0 :     int c__1 = 1;
+   29987           0 :     float c_b32 = 1.;
+   29988             :     const float safmin = PLUMED_GMX_FLOAT_MIN*(1.0+PLUMED_GMX_FLOAT_EPS);
+   29989             : 
+   29990           0 :     --e;
+   29991           0 :     --d__;
+   29992             : 
+   29993           0 :     *info = 0;
+   29994             : 
+   29995           0 :     if (*n < 0) {
+   29996           0 :         *info = -1;
+   29997             :         i__1 = -(*info);
+   29998           0 :         return;
+   29999             :     }
+   30000           0 :     if (*n <= 1) {
+   30001             :         return;
+   30002             :     }
+   30003             : 
+   30004             :     eps = PLUMED_GMX_FLOAT_EPS;
+   30005             :     d__1 = eps;
+   30006             :     eps2 = d__1 * d__1;
+   30007             :     safmax = 1. / safmin;
+   30008           0 :     ssfmax =  std::sqrt(safmax) / 3.;
+   30009           0 :     ssfmin =  std::sqrt(safmin) / eps2;
+   30010             : 
+   30011           0 :     nmaxit = *n * 30;
+   30012           0 :     sigma = 0.;
+   30013             :     jtot = 0;
+   30014             : 
+   30015             :     l1 = 1;
+   30016             : 
+   30017           0 : L10:
+   30018           0 :     if (l1 > *n) {
+   30019           0 :       PLUMED_BLAS_F77_FUNC(slasrt,SLASRT)("I", n, &d__[1], info);
+   30020           0 :       return;
+   30021             :     }
+   30022           0 :     if (l1 > 1) {
+   30023           0 :         e[l1 - 1] = 0.;
+   30024             :     }
+   30025           0 :     i__1 = *n - 1;
+   30026           0 :     for (m = l1; m <= i__1; ++m) {
+   30027           0 :         if (std::abs(e[m]) <=  std::sqrt(std::abs(d__[m])) * 
+   30028           0 :                  std::sqrt(std::abs(d__[m + 1])) * eps) {
+   30029           0 :             e[m] = 0.;
+   30030           0 :             goto L30;
+   30031             :         }
+   30032             :     }
+   30033           0 :     m = *n;
+   30034             : 
+   30035           0 : L30:
+   30036             :     l = l1;
+   30037             :     lsv = l;
+   30038             :     lend = m;
+   30039             :     lendsv = lend;
+   30040           0 :     l1 = m + 1;
+   30041           0 :     if (lend == l) {
+   30042           0 :         goto L10;
+   30043             :     }
+   30044             : 
+   30045           0 :     i__1 = lend - l + 1;
+   30046           0 :     anorm = PLUMED_BLAS_F77_FUNC(slanst,SLANST)("I", &i__1, &d__[l], &e[l]);
+   30047             :     iscale = 0;
+   30048           0 :     if (anorm > ssfmax) {
+   30049             :         iscale = 1;
+   30050           0 :         i__1 = lend - l + 1;
+   30051           0 :         PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G", &c__0, &c__0, &anorm, &ssfmax, &i__1, &c__1, &d__[l], n, 
+   30052             :                 info);
+   30053           0 :         i__1 = lend - l;
+   30054           0 :         PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G", &c__0, &c__0, &anorm, &ssfmax, &i__1, &c__1, &e[l], n, 
+   30055             :                 info);
+   30056           0 :     } else if (anorm < ssfmin) {
+   30057             :         iscale = 2;
+   30058           0 :         i__1 = lend - l + 1;
+   30059           0 :         PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G", &c__0, &c__0, &anorm, &ssfmin, &i__1, &c__1, &d__[l], n, 
+   30060             :                 info);
+   30061           0 :         i__1 = lend - l;
+   30062           0 :         PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G", &c__0, &c__0, &anorm, &ssfmin, &i__1, &c__1, &e[l], n, 
+   30063             :                 info);
+   30064             :     }
+   30065             : 
+   30066           0 :     i__1 = lend - 1;
+   30067           0 :     for (i__ = l; i__ <= i__1; ++i__) {
+   30068           0 :         d__1 = e[i__];
+   30069           0 :         e[i__] = d__1 * d__1;
+   30070             :     }
+   30071             : 
+   30072           0 :     if (std::abs(d__[lend]) < std::abs(d__[l])) {
+   30073             :         lend = lsv;
+   30074             :         l = lendsv;
+   30075             :     }
+   30076             : 
+   30077           0 :     if (lend >= l) {
+   30078             : 
+   30079           0 : L50:
+   30080           0 :         if (l != lend) {
+   30081           0 :             i__1 = lend - 1;
+   30082           0 :             for (m = l; m <= i__1; ++m) {
+   30083           0 :                 if (std::abs(e[m]) <= eps2 * std::abs(d__[m] * d__[m + 1])) {
+   30084           0 :                     goto L70;
+   30085             :                 }
+   30086             :             }
+   30087             :         }
+   30088             :         m = lend;
+   30089             : 
+   30090           0 : L70:
+   30091           0 :         if (m < lend) {
+   30092           0 :             e[m] = 0.;
+   30093             :         }
+   30094           0 :         p = d__[l];
+   30095           0 :         if (m == l) {
+   30096           0 :             goto L90;
+   30097             :         }
+   30098           0 :         if (m == l + 1) {
+   30099           0 :             rte =  std::sqrt(e[l]);
+   30100           0 :             PLUMED_BLAS_F77_FUNC(slae2,SLAE2)(&d__[l], &rte, &d__[l + 1], &rt1, &rt2);
+   30101           0 :             d__[l] = rt1;
+   30102           0 :             d__[l + 1] = rt2;
+   30103           0 :             e[l] = 0.;
+   30104           0 :             l += 2;
+   30105           0 :             if (l <= lend) {
+   30106           0 :                 goto L50;
+   30107             :             }
+   30108           0 :             goto L150;
+   30109             :         }
+   30110             : 
+   30111           0 :         if (jtot == nmaxit) {
+   30112           0 :             goto L150;
+   30113             :         }
+   30114           0 :         ++jtot;
+   30115             : 
+   30116           0 :         rte =  std::sqrt(e[l]);
+   30117           0 :         sigma = (d__[l + 1] - p) / (rte * 2.);
+   30118           0 :         r__ = PLUMED_BLAS_F77_FUNC(slapy2,SLAPY2)(&sigma, &c_b32);
+   30119           0 :         sigma = p - rte / (sigma + ( (sigma>0) ? r__ : -r__));
+   30120             : 
+   30121             :         c__ = 1.;
+   30122             :         s = 0.;
+   30123           0 :         gamma = d__[m] - sigma;
+   30124           0 :         p = gamma * gamma;
+   30125             : 
+   30126           0 :         i__1 = l;
+   30127           0 :         for (i__ = m - 1; i__ >= i__1; --i__) {
+   30128           0 :             bb = e[i__];
+   30129           0 :             r__ = p + bb;
+   30130           0 :             if (i__ != m - 1) {
+   30131           0 :                 e[i__ + 1] = s * r__;
+   30132             :             }
+   30133             :             oldc = c__;
+   30134           0 :             c__ = p / r__;
+   30135           0 :             s = bb / r__;
+   30136             :             oldgam = gamma;
+   30137           0 :             alpha = d__[i__];
+   30138           0 :             gamma = c__ * (alpha - sigma) - s * oldgam;
+   30139           0 :             d__[i__ + 1] = oldgam + (alpha - gamma);
+   30140           0 :             if (std::abs(c__)>PLUMED_GMX_FLOAT_MIN) {
+   30141           0 :                 p = gamma * gamma / c__;
+   30142             :             } else {
+   30143           0 :                 p = oldc * bb;
+   30144             :             }
+   30145             :         }
+   30146             : 
+   30147           0 :         e[l] = s * p;
+   30148           0 :         d__[l] = sigma + gamma;
+   30149           0 :         goto L50;
+   30150             : 
+   30151             : L90:
+   30152             :         d__[l] = p;
+   30153             : 
+   30154           0 :         ++l;
+   30155           0 :         if (l <= lend) {
+   30156           0 :             goto L50;
+   30157             :         }
+   30158           0 :         goto L150;
+   30159             : 
+   30160             :     } else {
+   30161             : 
+   30162           0 : L100:
+   30163           0 :         i__1 = lend + 1;
+   30164           0 :         for (m = l; m >= i__1; --m) {
+   30165           0 :             if (std::abs(e[m - 1]) <= eps2 * std::abs(d__[m] * d__[m - 1])) {
+   30166           0 :                 goto L120;
+   30167             :             }
+   30168             :         }
+   30169             :         m = lend;
+   30170             : 
+   30171           0 : L120:
+   30172           0 :         if (m > lend) {
+   30173           0 :             e[m - 1] = 0.;
+   30174             :         }
+   30175           0 :         p = d__[l];
+   30176           0 :         if (m == l) {
+   30177           0 :             goto L140;
+   30178             :         }
+   30179             : 
+   30180           0 :         if (m == l - 1) {
+   30181           0 :             rte =  std::sqrt(e[l - 1]);
+   30182           0 :             PLUMED_BLAS_F77_FUNC(slae2,SLAE2)(&d__[l], &rte, &d__[l - 1], &rt1, &rt2);
+   30183           0 :             d__[l] = rt1;
+   30184           0 :             d__[l - 1] = rt2;
+   30185           0 :             e[l - 1] = 0.;
+   30186           0 :             l += -2;
+   30187           0 :             if (l >= lend) {
+   30188           0 :                 goto L100;
+   30189             :             }
+   30190           0 :             goto L150;
+   30191             :         }
+   30192             : 
+   30193           0 :         if (jtot == nmaxit) {
+   30194           0 :             goto L150;
+   30195             :         }
+   30196           0 :         ++jtot;
+   30197             : 
+   30198           0 :         rte =  std::sqrt(e[l - 1]);
+   30199           0 :         sigma = (d__[l - 1] - p) / (rte * 2.);
+   30200           0 :         r__ = PLUMED_BLAS_F77_FUNC(slapy2,SLAPY2)(&sigma, &c_b32);
+   30201           0 :         sigma = p - rte / (sigma + ( (sigma>0) ? r__ : -r__));
+   30202             : 
+   30203             :         c__ = 1.;
+   30204             :         s = 0.;
+   30205           0 :         gamma = d__[m] - sigma;
+   30206           0 :         p = gamma * gamma;
+   30207             : 
+   30208           0 :         i__1 = l - 1;
+   30209           0 :         for (i__ = m; i__ <= i__1; ++i__) {
+   30210           0 :             bb = e[i__];
+   30211           0 :             r__ = p + bb;
+   30212           0 :             if (i__ != m) {
+   30213           0 :                 e[i__ - 1] = s * r__;
+   30214             :             }
+   30215             :             oldc = c__;
+   30216           0 :             c__ = p / r__;
+   30217           0 :             s = bb / r__;
+   30218             :             oldgam = gamma;
+   30219           0 :             alpha = d__[i__ + 1];
+   30220           0 :             gamma = c__ * (alpha - sigma) - s * oldgam;
+   30221           0 :             d__[i__] = oldgam + (alpha - gamma);
+   30222           0 :             if (std::abs(c__)>PLUMED_GMX_FLOAT_MIN) {
+   30223           0 :                 p = gamma * gamma / c__;
+   30224             :             } else {
+   30225           0 :                 p = oldc * bb;
+   30226             :             }
+   30227             :         }
+   30228             : 
+   30229           0 :         e[l - 1] = s * p;
+   30230           0 :         d__[l] = sigma + gamma;
+   30231           0 :         goto L100;
+   30232             : 
+   30233             : L140:
+   30234             :         d__[l] = p;
+   30235             : 
+   30236           0 :         --l;
+   30237           0 :         if (l >= lend) {
+   30238           0 :             goto L100;
+   30239             :         }
+   30240           0 :         goto L150;
+   30241             : 
+   30242             :     }
+   30243             : 
+   30244           0 : L150:
+   30245           0 :     if (iscale == 1) {
+   30246           0 :         i__1 = lendsv - lsv + 1;
+   30247           0 :         PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G", &c__0, &c__0, &ssfmax, &anorm, &i__1, &c__1, &d__[lsv], 
+   30248             :                 n, info);
+   30249             :     }
+   30250           0 :     if (iscale == 2) {
+   30251           0 :         i__1 = lendsv - lsv + 1;
+   30252           0 :         PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G", &c__0, &c__0, &ssfmin, &anorm, &i__1, &c__1, &d__[lsv], 
+   30253             :                 n, info);
+   30254             :     }
+   30255             : 
+   30256           0 :     if (jtot < nmaxit) {
+   30257           0 :         goto L10;
+   30258             :     }
+   30259           0 :     i__1 = *n - 1;
+   30260           0 :     for (i__ = 1; i__ <= i__1; ++i__) {
+   30261           0 :         if (std::abs(e[i__])>PLUMED_GMX_FLOAT_MIN) {
+   30262           0 :             ++(*info);
+   30263             :         }
+   30264             :     }
+   30265             :     return;
+   30266             : }
+   30267             : 
+   30268             : 
+   30269             : }
+   30270             : }
+   30271             : #include "lapack.h"
+   30272             : 
+   30273             : 
+   30274             : /* Normally, SSTEVR is the LAPACK wrapper which calls one
+   30275             :  * of the eigenvalue methods. However, our code includes a
+   30276             :  * version of SSTEGR which is never than LAPACK 3.0 and can
+   30277             :  * handle requests for a subset of eigenvalues/vectors too,
+   30278             :  * and it should not need to call SSTEIN.
+   30279             :  * Just in case somebody has a faster version in their lapack
+   30280             :  * library we still call the driver routine, but in our own
+   30281             :  * case this is just a wrapper to sstegr.
+   30282             :  */
+   30283             : #include "blas/blas.h"
+   30284             : namespace PLMD{
+   30285             : namespace lapack{
+   30286             : using namespace blas;
+   30287             : void
+   30288           0 : PLUMED_BLAS_F77_FUNC(sstevr,SSTEVR)(const char *jobz, 
+   30289             :                         const char *range,
+   30290             :                         int *n,
+   30291             :                         float *d,
+   30292             :                         float *e,
+   30293             :                         float *vl, 
+   30294             :                         float *vu,
+   30295             :                         int *il, 
+   30296             :                         int *iu, 
+   30297             :                         float *abstol,
+   30298             :                         int *m,
+   30299             :                         float *w, 
+   30300             :                         float *z,
+   30301             :                         int *ldz,
+   30302             :                         int *isuppz, 
+   30303             :                         float *work, 
+   30304             :                         int *lwork, 
+   30305             :                         int *iwork,
+   30306             :                         int *liwork, 
+   30307             :                         int *info)
+   30308             : {
+   30309           0 :   PLUMED_BLAS_F77_FUNC(sstegr,SSTEGR)(jobz, range, n, d, e, vl, vu, il, iu, abstol, m, w,
+   30310             :           z, ldz, isuppz, work, lwork, iwork, liwork, info);
+   30311             :   
+   30312             : 
+   30313           0 :     return;
+   30314             : 
+   30315             : }
+   30316             : 
+   30317             : 
+   30318             : }
+   30319             : }
+   30320             : #include <cmath>
+   30321             : 
+   30322             : #include "real.h"
+   30323             : 
+   30324             : #include "blas/blas.h"
+   30325             : #include "lapack.h"
+   30326             : #include "lapack_limits.h"
+   30327             : 
+   30328             : #include "blas/blas.h"
+   30329             : namespace PLMD{
+   30330             : namespace lapack{
+   30331             : using namespace blas;
+   30332             : void
+   30333           0 : PLUMED_BLAS_F77_FUNC(ssyevr,SSYEVR)(const char *jobz, const char *range, const char *uplo, int *n, 
+   30334             :         float *a, int *lda, float *vl, float *vu, int *
+   30335             :         il, int *iu, float *abstol, int *m, float *w, 
+   30336             :         float *z__, int *ldz, int *isuppz, float *work, 
+   30337             :         int *lwork, int *iwork, int *liwork, int *info)
+   30338             : {
+   30339             :     /* System generated locals */
+   30340             :     int a_dim1, a_offset, z_dim1, z_offset, i__1, i__2;
+   30341             :     float d__1, d__2;
+   30342             : 
+   30343             :     /* Local variables */
+   30344           0 :     int c__1 = 1;
+   30345             :     int i__, j, nb, jj;
+   30346             :     float eps, tmp1;
+   30347             :     int indd, inde;
+   30348             :     float anrm;
+   30349             :     int imax;
+   30350             :     float rmin, rmax;
+   30351             :     int itmp1, inddd, indee;
+   30352             :     float sigma;
+   30353             :     int iinfo;
+   30354             :     int indwk;
+   30355             :     int lwmin;
+   30356             :     int lower, wantz;
+   30357             :     int alleig, indeig;
+   30358             :     int iscale, indibl, indifl;
+   30359             :     int valeig;
+   30360             :     float safmin,minval;
+   30361             :     float bignum;
+   30362             :     int indtau;
+   30363             :     int indwkn;
+   30364             :     int liwmin;
+   30365             :     int llwrkn, llwork;
+   30366             :     float smlnum;
+   30367             :     int lwkopt;
+   30368             :     int lquery;
+   30369             :     
+   30370             :     /* Parameter adjustments */
+   30371           0 :     a_dim1 = *lda;
+   30372           0 :     a_offset = 1 + a_dim1;
+   30373           0 :     a -= a_offset;
+   30374           0 :     --w;
+   30375           0 :     z_dim1 = *ldz;
+   30376           0 :     z_offset = 1 + z_dim1;
+   30377           0 :     z__ -= z_offset;
+   30378             :     --isuppz;
+   30379           0 :     --work;
+   30380           0 :     --iwork;
+   30381             : 
+   30382           0 :     lower = (*uplo=='L' || *uplo=='l');
+   30383           0 :     wantz = (*jobz=='V' || *jobz=='v');
+   30384           0 :     alleig = (*range=='A' || *range=='a');
+   30385           0 :     valeig = (*range=='V' || *range=='v');
+   30386           0 :     indeig = (*range=='I' || *range=='i');
+   30387             : 
+   30388             :     indibl = 0;
+   30389           0 :     lquery = *lwork == -1 || *liwork == -1;
+   30390             : 
+   30391             :     i__1 = 1;
+   30392           0 :     i__2 = *n * 26;
+   30393             : 
+   30394           0 :     if(*n>0) 
+   30395             :       lwmin = *n * 26;
+   30396             :     else
+   30397             :       lwmin = 1;
+   30398             : 
+   30399           0 :     if(*n>0) 
+   30400           0 :       liwmin = *n * 10;
+   30401             :     else
+   30402             :       liwmin = 1;
+   30403             : 
+   30404           0 :     *info = 0;
+   30405           0 :     if (! (wantz || (*jobz=='N' || *jobz=='n'))) {
+   30406           0 :         *info = -1;
+   30407           0 :     } else if (! (alleig || valeig || indeig)) {
+   30408           0 :         *info = -2;
+   30409           0 :     } else if (! (lower || (*uplo=='U' || *uplo=='u'))) {
+   30410           0 :         *info = -3;
+   30411           0 :     } else if (*n < 0) {
+   30412           0 :         *info = -4;
+   30413           0 :     } else if (*lda < ((*n>1) ? *n : 1) ) {
+   30414           0 :         *info = -6;
+   30415             :     } else {
+   30416           0 :         if (valeig) {
+   30417           0 :             if (*n > 0 && *vu <= *vl) {
+   30418           0 :                 *info = -8;
+   30419             :             }
+   30420           0 :         } else if (indeig) {
+   30421           0 :           if (*il < 1 || *il > ((*n>1) ? *n : 1)) {
+   30422           0 :                 *info = -9;
+   30423           0 :             } else if (*iu < ((*n<*il) ? *n : *il) || *iu > *n) {
+   30424           0 :                 *info = -10;
+   30425             :             }
+   30426             :         }
+   30427             :     }
+   30428           0 :     if (*info == 0) {
+   30429           0 :       if (*ldz < 1 || (wantz && *ldz < *n)) {
+   30430           0 :             *info = -15;
+   30431           0 :         } else if (*lwork < lwmin && ! lquery) {
+   30432           0 :             *info = -18;
+   30433           0 :         } else if (*liwork < liwmin && ! lquery) {
+   30434           0 :             *info = -20;
+   30435             :         }
+   30436             :     }
+   30437             : 
+   30438           0 :     if (*info == 0) {
+   30439             :       nb = 32;
+   30440             :       /* Computing MAX */
+   30441           0 :       i__1 = (nb + 1) * *n;
+   30442             :       lwkopt = (i__1>lwmin) ? i__1 : lwmin;
+   30443           0 :       work[1] = (float) lwkopt;
+   30444           0 :       iwork[1] = liwmin;
+   30445             :     } else 
+   30446             :       return;
+   30447             : 
+   30448           0 :     if (lquery) 
+   30449             :         return;
+   30450             :     
+   30451           0 :     *m = 0;
+   30452           0 :     if (*n == 0) {
+   30453           0 :         work[1] = 1.;
+   30454           0 :         return;
+   30455             :     }
+   30456             : 
+   30457           0 :     if (*n == 1) {
+   30458           0 :         work[1] = 7.;
+   30459           0 :         if (alleig || indeig) {
+   30460           0 :             *m = 1;
+   30461           0 :             w[1] = a[a_dim1 + 1];
+   30462             :         } else {
+   30463           0 :             if (*vl < a[a_dim1 + 1] && *vu >= a[a_dim1 + 1]) {
+   30464           0 :                 *m = 1;
+   30465           0 :                 w[1] = a[a_dim1 + 1];
+   30466             :             }
+   30467             :         }
+   30468           0 :         if (wantz) {
+   30469           0 :             z__[z_dim1 + 1] = 1.;
+   30470             :         }
+   30471           0 :         return;
+   30472             :     }
+   30473             :     minval = PLUMED_GMX_FLOAT_MIN;
+   30474             :     safmin = minval*(1.0+PLUMED_GMX_FLOAT_EPS);
+   30475             :     eps = PLUMED_GMX_FLOAT_EPS;
+   30476             : 
+   30477             :     smlnum = safmin / eps;
+   30478             :     bignum = 1. / smlnum;
+   30479             :     rmin =  std::sqrt(smlnum);
+   30480             : 
+   30481           0 :     d__1 =  std::sqrt(bignum), d__2 = 1. / std::sqrt(sqrt(safmin));
+   30482             :     rmax = (d__1<d__2) ? d__1 : d__2;
+   30483             : 
+   30484             :     iscale = 0;
+   30485           0 :     anrm = PLUMED_BLAS_F77_FUNC(slansy,SLANSY)("M", uplo, n, &a[a_offset], lda, &work[1]);
+   30486           0 :     if (anrm > 0. && anrm < rmin) {
+   30487             :         iscale = 1;
+   30488           0 :         sigma = rmin / anrm;
+   30489           0 :     } else if (anrm > rmax) {
+   30490             :         iscale = 1;
+   30491           0 :         sigma = rmax / anrm; 
+   30492             :     }
+   30493             :     if (iscale == 1) {
+   30494           0 :         if (lower) {
+   30495           0 :             i__1 = *n;
+   30496           0 :             for (j = 1; j <= i__1; ++j) {
+   30497           0 :                 i__2 = *n - j + 1;
+   30498           0 :                 PLUMED_BLAS_F77_FUNC(sscal,SSCAL)(&i__2, &sigma, &a[j + j * a_dim1], &c__1);
+   30499             :             }
+   30500             :         } else {
+   30501           0 :             i__1 = *n;
+   30502           0 :             for (j = 1; j <= i__1; ++j) {
+   30503           0 :                 PLUMED_BLAS_F77_FUNC(sscal,SSCAL)(&j, &sigma, &a[j * a_dim1 + 1], &c__1);
+   30504             : 
+   30505             :             }
+   30506             :         }
+   30507             :     }
+   30508             : 
+   30509             :     indtau = 1;
+   30510           0 :     inde = indtau + *n;
+   30511           0 :     indd = inde + *n;
+   30512           0 :     indee = indd + *n;
+   30513           0 :     inddd = indee + *n;
+   30514           0 :     indifl = inddd + *n;
+   30515           0 :     indwk = indifl + *n;
+   30516           0 :     llwork = *lwork - indwk + 1;
+   30517           0 :     PLUMED_BLAS_F77_FUNC(ssytrd,SSYTRD)(uplo, n, &a[a_offset], lda, &work[indd], &work[inde], &work[
+   30518           0 :             indtau], &work[indwk], &llwork, &iinfo);
+   30519             : 
+   30520           0 :     i__1 = *n - 1;
+   30521           0 :     PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&i__1, &work[inde], &c__1, &work[indee], &c__1);
+   30522           0 :     PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(n, &work[indd], &c__1, &work[inddd], &c__1);
+   30523             : 
+   30524           0 :     PLUMED_BLAS_F77_FUNC(sstegr,SSTEGR)(jobz, range, n, &work[inddd], &work[indee], vl, vu, il, iu, 
+   30525             :             abstol, m, &w[1], &z__[z_offset], ldz, &isuppz[1], 
+   30526             :             &work[indwk], lwork, &iwork[1], liwork, info);
+   30527           0 :     if (wantz && *info == 0) {
+   30528             :       indwkn = inde;
+   30529           0 :       llwrkn = *lwork - indwkn + 1;
+   30530           0 :       PLUMED_BLAS_F77_FUNC(sormtr,SORMTR)("L", uplo, "N", n, m, &a[a_offset], lda, &work[indtau]
+   30531             :               , &z__[z_offset], ldz, &work[indwkn], &llwrkn, &iinfo);
+   30532             :     }
+   30533             : 
+   30534           0 :     if (*info != 0) 
+   30535             :       return;
+   30536             : 
+   30537           0 :     if (iscale == 1) {
+   30538             :         if (*info == 0) {
+   30539           0 :             imax = *m;
+   30540             :         } else {
+   30541             :             imax = *info - 1;
+   30542             :         }
+   30543           0 :         d__1 = 1. / sigma;
+   30544           0 :         PLUMED_BLAS_F77_FUNC(sscal,SSCAL)(&imax, &d__1, &w[1], &c__1);
+   30545             :     }
+   30546             : 
+   30547           0 :     if (wantz) {
+   30548           0 :         i__1 = *m - 1;
+   30549             :         
+   30550           0 :         for (j = 1; j <= i__1; ++j) {
+   30551             :             i__ = 0;
+   30552           0 :             tmp1 = w[j];
+   30553           0 :             i__2 = *m;
+   30554           0 :             for (jj = j + 1; jj <= i__2; ++jj) {
+   30555           0 :                 if (w[jj] < tmp1) {
+   30556             :                     i__ = jj;
+   30557             :                     tmp1 = w[jj];
+   30558             :                 }
+   30559             :             }
+   30560             : 
+   30561           0 :             if (i__ != 0) {
+   30562           0 :                 itmp1 = iwork[indibl + i__ - 1];
+   30563           0 :                 w[i__] = w[j];
+   30564           0 :                 iwork[indibl + i__ - 1] = iwork[indibl + j - 1];
+   30565           0 :                 w[j] = tmp1;
+   30566           0 :                 iwork[indibl + j - 1] = itmp1;
+   30567           0 :                 PLUMED_BLAS_F77_FUNC(sswap,SSWAP)(n, &z__[i__ * z_dim1 + 1], &c__1, &z__[j * z_dim1 + 1],
+   30568             :                          &c__1);
+   30569             :             }
+   30570             :         }
+   30571             :     }
+   30572             : 
+   30573           0 :     work[1] = (float) lwkopt;
+   30574           0 :     iwork[1] = liwmin;
+   30575           0 :     return;
+   30576             : 
+   30577             : }
+   30578             : }
+   30579             : }
+   30580             : #include <cctype>
+   30581             : #include <cmath>
+   30582             : 
+   30583             : #include "real.h"
+   30584             : 
+   30585             : #include "blas/blas.h"
+   30586             : #include "lapack.h"
+   30587             : 
+   30588             : #include "blas/blas.h"
+   30589             : namespace PLMD{
+   30590             : namespace lapack{
+   30591             : using namespace blas;
+   30592             : void
+   30593           0 : PLUMED_BLAS_F77_FUNC(ssytd2,SSYTD2)(const char *    uplo,
+   30594             :         int *     n,
+   30595             :         float *  a,
+   30596             :         int *     lda,
+   30597             :         float *  d,
+   30598             :         float *  e,
+   30599             :         float *  tau,
+   30600             :     int *     info)
+   30601             : {
+   30602             :   float minusone,zero;
+   30603             :   float taui,alpha,tmp;
+   30604             :   int ti1,ti2,ti3,i;
+   30605           0 :   const char ch=std::toupper(*uplo);
+   30606             : 
+   30607           0 :   zero = 0.0;
+   30608           0 :   minusone = -1.0;
+   30609             : 
+   30610           0 :   if(*n<=0)
+   30611             :     return;
+   30612             : 
+   30613           0 :   if(ch=='U') {
+   30614           0 :     for(i=*n-1;i>=1;i--) {
+   30615             : 
+   30616           0 :       ti1 = 1;
+   30617           0 :       PLUMED_BLAS_F77_FUNC(slarfg,SLARFG)(&i,&(a[i*(*lda)+(i-1)]),&(a[i*(*lda)+0]),&ti1,&taui);
+   30618           0 :       e[i-1] = a[i*(*lda) + (i-1)];
+   30619           0 :       if(std::abs(taui)>PLUMED_GMX_FLOAT_MIN) {
+   30620           0 :         a[i*(*lda)+(i-1)] = 1.0;
+   30621             :       
+   30622           0 :         ti1 = 1;
+   30623           0 :         PLUMED_BLAS_F77_FUNC(ssymv,SSYMV)("U",&i,&taui,a,lda,&(a[i*(*lda)+0]),&ti1,&zero,tau,&ti1);
+   30624             : 
+   30625           0 :         tmp = PLUMED_BLAS_F77_FUNC(sdot,SDOT)(&i,tau,&ti1,&(a[i*(*lda)+0]),&ti1);
+   30626             : 
+   30627           0 :         alpha = -0.5*taui*tmp;
+   30628             : 
+   30629           0 :         PLUMED_BLAS_F77_FUNC(saxpy,SAXPY)(&i,&alpha,&(a[i*(*lda)+0]),&ti1,tau,&ti1);
+   30630             : 
+   30631           0 :         PLUMED_BLAS_F77_FUNC(ssyr2,SSYR2)("U",&i,&minusone,&(a[i*(*lda)+0]),&ti1,tau,&ti1,a,lda);
+   30632             : 
+   30633           0 :         a[i*(*lda)+(i-1)] = e[i-1]; 
+   30634             : 
+   30635             :       }
+   30636           0 :       d[i] = a[i*(*lda)+i];
+   30637           0 :       tau[i-1] = taui;
+   30638             :     }
+   30639           0 :     d[0] = a[0];
+   30640             :     
+   30641             :   } else {
+   30642             :     /* lower */
+   30643             : 
+   30644           0 :     for(i=1;i<*n;i++) {
+   30645             : 
+   30646           0 :       ti1 = *n - i;
+   30647           0 :       ti2 = ( *n < i+2) ? *n : i+2;
+   30648           0 :       ti3 = 1;
+   30649           0 :       PLUMED_BLAS_F77_FUNC(slarfg,SLARFG)(&ti1,&(a[(i-1)*(*lda)+(i)]),&(a[(i-1)*(*lda)+ti2-1]),&ti3,&taui);
+   30650             : 
+   30651           0 :       e[i-1] = a[(i-1)*(*lda) + (i)];
+   30652             : 
+   30653           0 :       if(std::abs(taui)>PLUMED_GMX_FLOAT_MIN) {
+   30654           0 :         a[(i-1)*(*lda)+(i)] = 1.0;
+   30655             :       
+   30656           0 :         ti1 = *n - i;
+   30657           0 :         ti2 = 1;
+   30658           0 :         PLUMED_BLAS_F77_FUNC(ssymv,SSYMV)(uplo,&ti1,&taui,&(a[i*(*lda)+i]),lda,&(a[(i-1)*(*lda)+i]),
+   30659             :                &ti2,&zero,&(tau[i-1]),&ti2);
+   30660             :         
+   30661           0 :         tmp = PLUMED_BLAS_F77_FUNC(sdot,SDOT)(&ti1,&(tau[i-1]),&ti2,&(a[(i-1)*(*lda)+i]),&ti2);
+   30662             : 
+   30663           0 :         alpha = -0.5*taui*tmp;
+   30664             : 
+   30665           0 :         PLUMED_BLAS_F77_FUNC(saxpy,SAXPY)(&ti1,&alpha,&(a[(i-1)*(*lda)+i]),&ti2,&(tau[i-1]),&ti2);
+   30666             : 
+   30667           0 :         PLUMED_BLAS_F77_FUNC(ssyr2,SSYR2)(uplo,&ti1,&minusone,&(a[(i-1)*(*lda)+i]),&ti2,&(tau[i-1]),&ti2,
+   30668           0 :                &(a[(i)*(*lda)+i]),lda);
+   30669             : 
+   30670           0 :         a[(i-1)*(*lda)+(i)] = e[i-1]; 
+   30671             : 
+   30672             :       }
+   30673           0 :       d[i-1] = a[(i-1)*(*lda)+i-1];
+   30674           0 :       tau[i-1] = taui;
+   30675             :     }
+   30676           0 :     d[*n-1] = a[(*n-1)*(*lda)+(*n-1)];
+   30677             :  
+   30678             :   }
+   30679             :   return;
+   30680             : }
+   30681             : }
+   30682             : }
+   30683             : #include "blas/blas.h"
+   30684             : #include "lapack.h"
+   30685             : #include "lapack_limits.h"
+   30686             : 
+   30687             : #include "blas/blas.h"
+   30688             : namespace PLMD{
+   30689             : namespace lapack{
+   30690             : using namespace blas;
+   30691             : void
+   30692           0 : PLUMED_BLAS_F77_FUNC(ssytrd,SSYTRD)(const char *uplo, int *n, float *a, int *
+   30693             :         lda, float *d__, float *e, float *tau, float *
+   30694             :         work, int *lwork, int *info)
+   30695             : {
+   30696             :     /* System generated locals */
+   30697             :     int a_dim1, a_offset, i__1, i__2, i__3;
+   30698             : 
+   30699             :     /* Local variables */
+   30700             :     int i__, j, nb, kk, nx, iws;
+   30701             :     int nbmin, iinfo;
+   30702             :     int upper;
+   30703             :     int ldwork, lwkopt;
+   30704             :     int lquery;
+   30705           0 :     float c_b22 = -1.;
+   30706           0 :     float c_b23 = 1.;
+   30707             : 
+   30708             : 
+   30709             :     /* Parameter adjustments */
+   30710           0 :     a_dim1 = *lda;
+   30711           0 :     a_offset = 1 + a_dim1;
+   30712           0 :     a -= a_offset;
+   30713           0 :     --d__;
+   30714           0 :     --e;
+   30715           0 :     --tau;
+   30716             :     --work;
+   30717             : 
+   30718             :     /* Function Body */
+   30719           0 :     *info = 0;
+   30720           0 :     upper = (*uplo=='U' || *uplo=='u');
+   30721           0 :     lquery = (*lwork == -1);
+   30722             : 
+   30723           0 :     if (! upper && ! (*uplo=='L' || *uplo=='l')) {
+   30724           0 :         *info = -1;
+   30725           0 :     } else if (*n < 0) {
+   30726           0 :         *info = -2;
+   30727           0 :     } else if (*lda < ((1>*n) ? 1 : *n)) {
+   30728           0 :         *info = -4;
+   30729           0 :     } else if (*lwork < 1 && ! lquery) {
+   30730           0 :         *info = -9;
+   30731             :     }
+   30732             : 
+   30733           0 :     if (*info == 0) {
+   30734             : 
+   30735           0 :       nb = DSYTRD_BLOCKSIZE;
+   30736           0 :       lwkopt = *n * nb;
+   30737           0 :       work[1] = (float) lwkopt;
+   30738             :     } else
+   30739             :       return;
+   30740             : 
+   30741           0 :     if (lquery) 
+   30742             :       return;
+   30743             :   
+   30744           0 :     if (*n == 0) {
+   30745           0 :         work[1] = 1.;
+   30746           0 :         return;
+   30747             :     }
+   30748             : 
+   30749             :     nx = *n;
+   30750           0 :     if (nb > 1 && nb < *n) {
+   30751             : 
+   30752             :         nx = DSYTRD_CROSSOVER;
+   30753           0 :         if (nx < *n) {
+   30754             : 
+   30755           0 :             ldwork = *n;
+   30756           0 :             iws = ldwork * nb;
+   30757           0 :             if (*lwork < iws) {
+   30758             : 
+   30759           0 :                 i__1 = *lwork / ldwork;
+   30760           0 :                 nb = (i__1>1) ? i__1 : 1;
+   30761             :                 nbmin = DSYTRD_MINBLOCKSIZE;
+   30762           0 :                 if (nb < nbmin) {
+   30763             :                     nx = *n;
+   30764             :                 }
+   30765             :             }
+   30766             :         } else {
+   30767             :             nx = *n;
+   30768             :         }
+   30769             :     } else {
+   30770           0 :         nb = 1;
+   30771             :     }
+   30772             : 
+   30773           0 :     if (upper) {
+   30774             : 
+   30775           0 :         kk = *n - (*n - nx + nb - 1) / nb * nb;
+   30776           0 :         i__1 = kk + 1;
+   30777             :         i__2 = -nb;
+   30778           0 :         for (i__ = *n - nb + 1; i__2 < 0 ? i__ >= i__1 : i__ <= i__1; i__ += 
+   30779             :                 i__2) {
+   30780             : 
+   30781           0 :             i__3 = i__ + nb - 1;
+   30782           0 :             PLUMED_BLAS_F77_FUNC(slatrd,SLATRD)(uplo, &i__3, &nb, &a[a_offset], lda, &e[1], &tau[1], &
+   30783             :                     work[1], &ldwork);
+   30784             : 
+   30785           0 :             i__3 = i__ - 1;
+   30786           0 :             PLUMED_BLAS_F77_FUNC(ssyr2k,SSYR2K)(uplo, "No transpose", &i__3, &nb, &c_b22, &a[i__ * a_dim1 
+   30787           0 :                     + 1], lda, &work[1], &ldwork, &c_b23, &a[a_offset], lda);
+   30788             : 
+   30789           0 :             i__3 = i__ + nb - 1;
+   30790           0 :             for (j = i__; j <= i__3; ++j) {
+   30791           0 :                 a[j - 1 + j * a_dim1] = e[j - 1];
+   30792           0 :                 d__[j] = a[j + j * a_dim1];
+   30793             : 
+   30794             :             }
+   30795             : 
+   30796             :         }
+   30797             : 
+   30798           0 :         PLUMED_BLAS_F77_FUNC(ssytd2,SSYTD2)(uplo, &kk, &a[a_offset], lda, &d__[1], &e[1], &tau[1], &iinfo);
+   30799             :     } else {
+   30800             : 
+   30801           0 :         i__2 = *n - nx;
+   30802           0 :         i__1 = nb;
+   30803           0 :         for (i__ = 1; i__1 < 0 ? i__ >= i__2 : i__ <= i__2; i__ += i__1) {
+   30804             : 
+   30805             : 
+   30806           0 :             i__3 = *n - i__ + 1;
+   30807           0 :             PLUMED_BLAS_F77_FUNC(slatrd,SLATRD)(uplo, &i__3, &nb, &a[i__ + i__ * a_dim1], lda, &e[i__], &
+   30808           0 :                     tau[i__], &work[1], &ldwork);
+   30809             : 
+   30810           0 :             i__3 = *n - i__ - nb + 1;
+   30811           0 :             PLUMED_BLAS_F77_FUNC(ssyr2k,SSYR2K)(uplo, "No transpose", &i__3, &nb, &c_b22, &a[i__ + nb + 
+   30812           0 :                     i__ * a_dim1], lda, &work[nb + 1], &ldwork, &c_b23, &a[
+   30813           0 :                     i__ + nb + (i__ + nb) * a_dim1], lda);
+   30814             : 
+   30815             : 
+   30816           0 :             i__3 = i__ + nb - 1;
+   30817           0 :             for (j = i__; j <= i__3; ++j) {
+   30818           0 :                 a[j + 1 + j * a_dim1] = e[j];
+   30819           0 :                 d__[j] = a[j + j * a_dim1];
+   30820             : 
+   30821             :             }
+   30822             : 
+   30823             :         }
+   30824             : 
+   30825             : 
+   30826           0 :         i__1 = *n - i__ + 1;
+   30827           0 :         PLUMED_BLAS_F77_FUNC(ssytd2,SSYTD2)(uplo, &i__1, &a[i__ + i__ * a_dim1], lda, &d__[i__], &e[i__], 
+   30828           0 :                 &tau[i__], &iinfo);
+   30829             :     }
+   30830             : 
+   30831           0 :     work[1] = (float) lwkopt;
+   30832           0 :     return;
+   30833             : 
+   30834             : }
+   30835             : 
+   30836             : 
+   30837             : }
+   30838             : }
+   30839             : #include "blas/blas.h"
+   30840             : #include "lapack.h"
+   30841             : #include "lapack_limits.h"
+   30842             : 
+   30843             : #include "blas/blas.h"
+   30844             : namespace PLMD{
+   30845             : namespace lapack{
+   30846             : using namespace blas;
+   30847             : void
+   30848           0 : PLUMED_BLAS_F77_FUNC(strti2,STRTI2)(const char *uplo,
+   30849             :         const char *diag, 
+   30850             :         int *n, 
+   30851             :         float *a,
+   30852             :         int *lda,
+   30853             :         int *info)
+   30854             : {
+   30855             :     int a_dim1, a_offset, i__1, i__2;
+   30856             : 
+   30857             :     int j;
+   30858             :     float ajj;
+   30859             :     int upper, nounit;
+   30860           0 :     int c__1 = 1;
+   30861             : 
+   30862             : 
+   30863           0 :     a_dim1 = *lda;
+   30864           0 :     a_offset = 1 + a_dim1;
+   30865           0 :     a -= a_offset;
+   30866             : 
+   30867           0 :     *info = 0;
+   30868           0 :     upper = (*uplo=='U' || *uplo=='u');
+   30869           0 :     nounit = (*diag=='N' || *diag=='n');
+   30870             : 
+   30871             :     if (*info != 0) {
+   30872             :         i__1 = -(*info);
+   30873             :         return;
+   30874             :     }
+   30875             : 
+   30876           0 :     if (upper) {
+   30877             : 
+   30878           0 :         i__1 = *n;
+   30879           0 :         for (j = 1; j <= i__1; ++j) {
+   30880           0 :             if (nounit) {
+   30881           0 :                 a[j + j * a_dim1] = 1. / a[j + j * a_dim1];
+   30882           0 :                 ajj = -a[j + j * a_dim1];
+   30883             :             } else {
+   30884           0 :                 ajj = -1.;
+   30885             :             }
+   30886             : 
+   30887           0 :             i__2 = j - 1;
+   30888           0 :             PLUMED_BLAS_F77_FUNC(strmv,STRMV)("Upper", "No transpose", diag, &i__2, &a[a_offset], lda, &
+   30889           0 :                     a[j * a_dim1 + 1], &c__1);
+   30890           0 :             i__2 = j - 1;
+   30891           0 :             PLUMED_BLAS_F77_FUNC(sscal,SSCAL)(&i__2, &ajj, &a[j * a_dim1 + 1], &c__1);
+   30892             :         }
+   30893             :     } else {
+   30894             : 
+   30895           0 :         for (j = *n; j >= 1; --j) {
+   30896           0 :             if (nounit) {
+   30897           0 :                 a[j + j * a_dim1] = 1. / a[j + j * a_dim1];
+   30898           0 :                 ajj = -a[j + j * a_dim1];
+   30899             :             } else {
+   30900           0 :                 ajj = -1.;
+   30901             :             }
+   30902           0 :             if (j < *n) {
+   30903             : 
+   30904           0 :                 i__1 = *n - j;
+   30905           0 :                 PLUMED_BLAS_F77_FUNC(strmv,STRMV)("Lower", "No transpose", diag, &i__1, &a[j + 1 + (j + 
+   30906           0 :                         1) * a_dim1], lda, &a[j + 1 + j * a_dim1], &c__1);
+   30907           0 :                 i__1 = *n - j;
+   30908           0 :                 PLUMED_BLAS_F77_FUNC(sscal,SSCAL)(&i__1, &ajj, &a[j + 1 + j * a_dim1], &c__1);
+   30909             :             }
+   30910             :         }
+   30911             :     }
+   30912             :     return;
+   30913             : }
+   30914             : }
+   30915             : }
+   30916             : #include <cmath>
+   30917             : #include "blas/blas.h"
+   30918             : #include "lapack.h"
+   30919             : #include "lapack_limits.h"
+   30920             : 
+   30921             : #include "real.h"
+   30922             : 
+   30923             : #include "blas/blas.h"
+   30924             : namespace PLMD{
+   30925             : namespace lapack{
+   30926             : using namespace blas;
+   30927             : void
+   30928           0 : PLUMED_BLAS_F77_FUNC(strtri,STRTRI)(const char *uplo,
+   30929             :         const char *diag, 
+   30930             :         int *n,
+   30931             :         float *a, 
+   30932             :         int *lda,
+   30933             :         int *info)
+   30934             : {
+   30935             :     int a_dim1, a_offset, i__1, i__3, i__4, i__5;
+   30936             :     int j, jb, nb, nn;
+   30937           0 :     float c_b18 = 1.;
+   30938           0 :     float c_b22 = -1.;
+   30939             : 
+   30940             :     int upper;
+   30941             :     int nounit;
+   30942             : 
+   30943           0 :     a_dim1 = *lda;
+   30944           0 :     a_offset = 1 + a_dim1;
+   30945           0 :     a -= a_offset;
+   30946             : 
+   30947           0 :     *info = 0;
+   30948           0 :     upper = (*uplo=='U' || *uplo=='u');
+   30949           0 :     nounit = (*diag=='N' || *diag=='n');
+   30950             : 
+   30951             :     if (*info != 0) {
+   30952             :         i__1 = -(*info);
+   30953             :         return;
+   30954             :     }
+   30955             : 
+   30956           0 :     if (*n == 0) {
+   30957             :         return;
+   30958             :     }
+   30959             : 
+   30960           0 :     if (nounit) {
+   30961           0 :         i__1 = *n;
+   30962           0 :         for (*info = 1; *info <= i__1; ++(*info)) {
+   30963           0 :             if (std::abs(a[*info + *info * a_dim1])<PLUMED_GMX_FLOAT_MIN) {
+   30964             :                 return;
+   30965             :             }
+   30966             :         }
+   30967           0 :         *info = 0;
+   30968             :     }
+   30969             : 
+   30970             :     nb = DTRTRI_BLOCKSIZE;
+   30971           0 :     if (nb <= 1 || nb >= *n) {
+   30972             : 
+   30973           0 :         PLUMED_BLAS_F77_FUNC(strti2,STRTI2)(uplo, diag, n, &a[a_offset], lda, info);
+   30974             :     } else {
+   30975             : 
+   30976           0 :         if (upper) {
+   30977             : 
+   30978           0 :             i__1 = *n;
+   30979             :             i__3 = nb;
+   30980           0 :             for (j = 1; i__3 < 0 ? j >= i__1 : j <= i__1; j += i__3) {
+   30981           0 :                 i__4 = nb, i__5 = *n - j + 1;
+   30982           0 :                 jb = (i__4<i__5) ? i__4 : i__5;
+   30983             : 
+   30984           0 :                 i__4 = j - 1;
+   30985           0 :                 PLUMED_BLAS_F77_FUNC(strmm,STRMM)("Left", "Upper", "No transpose", diag, &i__4, &jb, &
+   30986           0 :                         c_b18, &a[a_offset], lda, &a[j * a_dim1 + 1], lda);
+   30987           0 :                 i__4 = j - 1;
+   30988           0 :                 PLUMED_BLAS_F77_FUNC(strsm,STRSM)("Right", "Upper", "No transpose", diag, &i__4, &jb, &
+   30989           0 :                         c_b22, &a[j + j * a_dim1], lda, &a[j * a_dim1 + 1], 
+   30990             :                         lda);
+   30991             : 
+   30992           0 :                 PLUMED_BLAS_F77_FUNC(strti2,STRTI2)("Upper", diag, &jb, &a[j + j * a_dim1], lda, info);
+   30993             :             }
+   30994             :         } else {
+   30995             : 
+   30996           0 :             nn = (*n - 1) / nb * nb + 1;
+   30997             :             i__3 = -nb;
+   30998           0 :             for (j = nn; i__3 < 0 ? j >= 1 : j <= 1; j += i__3) {
+   30999           0 :                 i__1 = nb, i__4 = *n - j + 1;
+   31000           0 :                 jb = (i__1<i__4) ? i__1 : i__4;
+   31001           0 :                 if (j + jb <= *n) {
+   31002             : 
+   31003           0 :                     i__1 = *n - j - jb + 1;
+   31004           0 :                     PLUMED_BLAS_F77_FUNC(strmm,STRMM)("Left", "Lower", "No transpose", diag, &i__1, &jb, 
+   31005           0 :                             &c_b18, &a[j + jb + (j + jb) * a_dim1], lda, &a[j 
+   31006           0 :                             + jb + j * a_dim1], lda);
+   31007           0 :                     i__1 = *n - j - jb + 1;
+   31008           0 :                     PLUMED_BLAS_F77_FUNC(strsm,STRSM)("Right", "Lower", "No transpose", diag, &i__1, &jb,
+   31009           0 :                              &c_b22, &a[j + j * a_dim1], lda, &a[j + jb + j * 
+   31010           0 :                             a_dim1], lda);
+   31011             :                 }
+   31012             : 
+   31013           0 :                 PLUMED_BLAS_F77_FUNC(strti2,STRTI2)("Lower", diag, &jb, &a[j + j * a_dim1], lda, info);
+   31014             :             }
+   31015             :         }
+   31016             :     }
+   31017             :     return;
+   31018             : }
+   31019             : 
+   31020             : 
+   31021             : }
+   31022             : }
+   31023             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lepton/CompiledExpression.cpp.func-sort-c.html b/coverage-libs/lepton/CompiledExpression.cpp.func-sort-c.html new file mode 100644 index 000000000000..3da4731f66be --- /dev/null +++ b/coverage-libs/lepton/CompiledExpression.cpp.func-sort-c.html @@ -0,0 +1,149 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - lepton/CompiledExpression.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - CompiledExpression.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:22723198.3 %
Date:2024-04-19 12:12:36Functions:1919100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6lepton18CompiledExpressionC2ERKS1_88
_ZN4PLMDL18generateTwoArgCallERNS_6asmjit11X86CompilerERNS0_6X86XmmES4_S4_PFdddE112
_ZZN4PLMD6lepton9useAsmJitEvENKUlvE_clEv257
_ZNK4PLMD6lepton18CompiledExpression12getVariablesB5cxx11Ev3283
_ZN4PLMDL21generateSingleArgCallERNS_6asmjit11X86CompilerERNS0_6X86XmmES4_PFddE12400
_ZN4PLMD6lepton18CompiledExpressionC2ERKNS0_16ParsedExpressionE16230
_ZN4PLMD6lepton18CompiledExpressionC2Ev16255
_ZN4PLMD6lepton18CompiledExpression20setVariableLocationsERSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPdSt4lessIS8_ESaISt4pairIKS8_S9_EEE16313
_ZN4PLMD6lepton18CompiledExpressionaSERKS1_16313
_ZN4PLMD6lepton18CompiledExpression15generateJitCodeEv31895
_ZN4PLMD6lepton16AsmJitRuntimePtrC2Ev32573
_ZN4PLMD6lepton16AsmJitRuntimePtrD2Ev32573
_ZN4PLMD6lepton18CompiledExpressionD2Ev32573
_ZN4PLMD6lepton18CompiledExpression20getVariableReferenceERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE74388
_ZN4PLMD6lepton9useAsmJitEv81889
_ZN4PLMD6lepton18CompiledExpression17compileExpressionERKNS0_18ExpressionTreeNodeERSt6vectorISt4pairIS2_iESaIS7_EE102620
_ZN4PLMD6lepton18CompiledExpression13findTempIndexERKNS0_18ExpressionTreeNodeERSt6vectorISt4pairIS2_iESaIS7_EE189010
_ZN4PLMDL17evaluateOperationEPNS_6lepton9OperationEPd11049185
_ZNK4PLMD6lepton18CompiledExpression8evaluateEv68467867
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lepton/CompiledExpression.cpp.func.html b/coverage-libs/lepton/CompiledExpression.cpp.func.html new file mode 100644 index 000000000000..dafebf1cb754 --- /dev/null +++ b/coverage-libs/lepton/CompiledExpression.cpp.func.html @@ -0,0 +1,149 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - lepton/CompiledExpression.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - CompiledExpression.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:22723198.3 %
Date:2024-04-19 12:12:36Functions:1919100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6lepton16AsmJitRuntimePtrC2Ev32573
_ZN4PLMD6lepton16AsmJitRuntimePtrD2Ev32573
_ZN4PLMD6lepton18CompiledExpression13findTempIndexERKNS0_18ExpressionTreeNodeERSt6vectorISt4pairIS2_iESaIS7_EE189010
_ZN4PLMD6lepton18CompiledExpression15generateJitCodeEv31895
_ZN4PLMD6lepton18CompiledExpression17compileExpressionERKNS0_18ExpressionTreeNodeERSt6vectorISt4pairIS2_iESaIS7_EE102620
_ZN4PLMD6lepton18CompiledExpression20getVariableReferenceERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE74388
_ZN4PLMD6lepton18CompiledExpression20setVariableLocationsERSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPdSt4lessIS8_ESaISt4pairIKS8_S9_EEE16313
_ZN4PLMD6lepton18CompiledExpressionC2ERKNS0_16ParsedExpressionE16230
_ZN4PLMD6lepton18CompiledExpressionC2ERKS1_88
_ZN4PLMD6lepton18CompiledExpressionC2Ev16255
_ZN4PLMD6lepton18CompiledExpressionD2Ev32573
_ZN4PLMD6lepton18CompiledExpressionaSERKS1_16313
_ZN4PLMD6lepton9useAsmJitEv81889
_ZN4PLMDL17evaluateOperationEPNS_6lepton9OperationEPd11049185
_ZN4PLMDL18generateTwoArgCallERNS_6asmjit11X86CompilerERNS0_6X86XmmES4_S4_PFdddE112
_ZN4PLMDL21generateSingleArgCallERNS_6asmjit11X86CompilerERNS0_6X86XmmES4_PFddE12400
_ZNK4PLMD6lepton18CompiledExpression12getVariablesB5cxx11Ev3283
_ZNK4PLMD6lepton18CompiledExpression8evaluateEv68467867
_ZZN4PLMD6lepton9useAsmJitEvENKUlvE_clEv257
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lepton/CompiledExpression.cpp.gcov.html b/coverage-libs/lepton/CompiledExpression.cpp.gcov.html new file mode 100644 index 000000000000..e0263eadf90d --- /dev/null +++ b/coverage-libs/lepton/CompiledExpression.cpp.gcov.html @@ -0,0 +1,586 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - lepton/CompiledExpression.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - CompiledExpression.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:22723198.3 %
Date:2024-04-19 12:12:36Functions:1919100.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) 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       81889 : bool lepton::useAsmJit() {
+      80             : #ifdef __PLUMED_HAS_ASMJIT
+      81         257 :   static const bool use=[](){
+      82         257 :     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       81889 :   }();
+      90       81889 :   return use;
+      91             : #else
+      92             :   return false;
+      93             : #endif
+      94             : }
+      95             : 
+      96       32573 : AsmJitRuntimePtr::AsmJitRuntimePtr()
+      97             : #ifdef __PLUMED_HAS_ASMJIT
+      98       32573 :   : ptr(useAsmJit()?new asmjit::JitRuntime:nullptr)
+      99             : #endif
+     100       32573 : {}
+     101             : 
+     102       32573 : AsmJitRuntimePtr::~AsmJitRuntimePtr()
+     103             : {
+     104             : #ifdef __PLUMED_HAS_ASMJIT
+     105       32573 :   if(useAsmJit()) delete static_cast<asmjit::JitRuntime*>(ptr);
+     106             : #endif
+     107       32573 : }
+     108             : 
+     109       16255 : CompiledExpression::CompiledExpression() : jitCode(NULL) {
+     110       16255 : }
+     111             : 
+     112       16230 : CompiledExpression::CompiledExpression(const ParsedExpression& expression) : jitCode(NULL) {
+     113       16230 :     ParsedExpression expr = expression.optimize(); // Just in case it wasn't already optimized.
+     114             :     vector<pair<ExpressionTreeNode, int> > temps;
+     115       16230 :     compileExpression(expr.getRootNode(), temps);
+     116             :     int maxArguments = 1;
+     117       80492 :     for (int i = 0; i < (int) operation.size(); i++)
+     118       64262 :         if (operation[i]->getNumArguments() > maxArguments)
+     119       10173 :             maxArguments = operation[i]->getNumArguments();
+     120       16230 :     argValues.resize(maxArguments);
+     121             : #ifdef __PLUMED_HAS_ASMJIT
+     122       16230 :     if(useAsmJit()) generateJitCode();
+     123             : #endif
+     124       32460 : }
+     125             : 
+     126       32573 : CompiledExpression::~CompiledExpression() {
+     127      161668 :     for (int i = 0; i < (int) operation.size(); i++)
+     128      129095 :         if (operation[i] != NULL)
+     129      129095 :             delete operation[i];
+     130       65146 : }
+     131             : 
+     132          88 : CompiledExpression::CompiledExpression(const CompiledExpression& expression) : jitCode(NULL) {
+     133          88 :     *this = expression;
+     134          88 : }
+     135             : 
+     136       16313 : CompiledExpression& CompiledExpression::operator=(const CompiledExpression& expression) {
+     137       16313 :     arguments = expression.arguments;
+     138       16313 :     target = expression.target;
+     139             :     variableIndices = expression.variableIndices;
+     140             :     variableNames = expression.variableNames;
+     141       16313 :     workspace.resize(expression.workspace.size());
+     142       16313 :     argValues.resize(expression.argValues.size());
+     143       16313 :     operation.resize(expression.operation.size());
+     144       81146 :     for (int i = 0; i < (int) operation.size(); i++)
+     145       64833 :         operation[i] = expression.operation[i]->clone();
+     146       16313 :     setVariableLocations(variablePointers);
+     147       16313 :     return *this;
+     148             : }
+     149             : 
+     150      102620 : void CompiledExpression::compileExpression(const ExpressionTreeNode& node, vector<pair<ExpressionTreeNode, int> >& temps) {
+     151      102620 :     if (findTempIndex(node, temps) != -1)
+     152       15581 :         return; // We have already processed a node identical to this one.
+     153             :     
+     154             :     // Process the child nodes.
+     155             :     
+     156             :     vector<int> args;
+     157      173429 :     for (int i = 0; i < node.getChildren().size(); i++) {
+     158       86390 :         compileExpression(node.getChildren()[i], temps);
+     159       86390 :         args.push_back(findTempIndex(node.getChildren()[i], temps));
+     160             :     }
+     161             :     
+     162             :     // Process this node.
+     163             :     
+     164       87039 :     if (node.getOperation().getId() == Operation::VARIABLE) {
+     165       22777 :         variableIndices[node.getOperation().getName()] = (int) workspace.size();
+     166       45554 :         variableNames.insert(node.getOperation().getName());
+     167             :     }
+     168             :     else {
+     169       64262 :         int stepIndex = (int) arguments.size();
+     170       64262 :         arguments.push_back(vector<int>());
+     171       64262 :         target.push_back((int) workspace.size());
+     172       64262 :         operation.push_back(node.getOperation().clone());
+     173       64262 :         if (args.size() == 0)
+     174        2272 :             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       86390 :             for (int i = 1; i < args.size(); i++)
+     180       24400 :                 if (args[i] != args[i-1]+1)
+     181             :                     sequential = false;
+     182       61990 :             if (sequential)
+     183       47474 :                 arguments[stepIndex].push_back(args[0]);
+     184             :             else
+     185       14516 :                 arguments[stepIndex] = args;
+     186             :         }
+     187             :     }
+     188       87039 :     temps.push_back(make_pair(node, (int) workspace.size()));
+     189       87039 :     workspace.push_back(0.0);
+     190             : }
+     191             : 
+     192      189010 : int CompiledExpression::findTempIndex(const ExpressionTreeNode& node, vector<pair<ExpressionTreeNode, int> >& temps) {
+     193     3630752 :     for (int i = 0; i < (int) temps.size(); i++)
+     194     3543713 :         if (temps[i].first == node)
+     195             :             return i;
+     196             :     return -1;
+     197             : }
+     198             : 
+     199        3283 : const set<string>& CompiledExpression::getVariables() const {
+     200        3283 :     return variableNames;
+     201             : }
+     202             : 
+     203       74388 : double& CompiledExpression::getVariableReference(const string& name) {
+     204             :     map<string, double*>::iterator pointer = variablePointers.find(name);
+     205       74388 :     if (pointer != variablePointers.end())
+     206           0 :         return *pointer->second;
+     207             :     map<string, int>::iterator index = variableIndices.find(name);
+     208       74388 :     if (index == variableIndices.end())
+     209       12398 :         throw Exception("getVariableReference: Unknown variable '"+name+"'");
+     210       68189 :     return workspace[index->second];
+     211             : }
+     212             : 
+     213       16313 : void CompiledExpression::setVariableLocations(map<string, double*>& variableLocations) {
+     214             :   variablePointers = variableLocations;
+     215       16313 :   static const bool asmjit=useAsmJit();
+     216       16313 :   if(asmjit) {
+     217             : #ifdef __PLUMED_HAS_ASMJIT
+     218             :     // Rebuild the JIT code.
+     219             :     
+     220       15989 :     if (workspace.size() > 0)
+     221       15989 :         generateJitCode();
+     222             : #endif
+     223             :   } else {
+     224             :     // Make a list of all variables we will need to copy before evaluating the expression.
+     225             :     
+     226         324 :     variablesToCopy.clear();
+     227         584 :     for (map<string, int>::const_iterator iter = variableIndices.begin(); iter != variableIndices.end(); ++iter) {
+     228         260 :         map<string, double*>::iterator pointer = variablePointers.find(iter->first);
+     229         260 :         if (pointer != variablePointers.end())
+     230           0 :             variablesToCopy.push_back(make_pair(&workspace[iter->second], pointer->second));
+     231             :     }
+     232             :   }
+     233       16313 : }
+     234             : 
+     235    68467867 : double CompiledExpression::evaluate() const {
+     236    68467867 :     static const bool asmjit=useAsmJit();
+     237             : #ifdef __PLUMED_HAS_ASMJIT
+     238    68467867 :     if(asmjit) return ((double (*)()) jitCode)();
+     239             : #endif
+     240       16443 :     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       49474 :     for (int step = 0; step < operation.size(); step++) {
+     246             :         const vector<int>& args = arguments[step];
+     247       33031 :         if (args.size() == 1)
+     248       30198 :             workspace[target[step]] = operation[step]->evaluate(&workspace[args[0]], dummyVariables);
+     249             :         else {
+     250        8905 :             for (int i = 0; i < args.size(); i++)
+     251        6072 :                 argValues[i] = workspace[args[i]];
+     252        2833 :             workspace[target[step]] = operation[step]->evaluate(&argValues[0], dummyVariables);
+     253             :         }
+     254             :     }
+     255       16443 :     return workspace[workspace.size()-1];
+     256             : }
+     257             : 
+     258             : #ifdef __PLUMED_HAS_ASMJIT
+     259    11049185 : static double evaluateOperation(Operation* op, double* args) {
+     260    11049185 :     static map<string, double> dummyVariables;
+     261    11049185 :     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       31895 : void CompiledExpression::generateJitCode() {
+     268       31895 :     CodeHolder code;
+     269             :     auto & runtime(*static_cast<asmjit::JitRuntime*>(runtimeptr.get()));
+     270       31895 :     code.init(runtime.getCodeInfo());
+     271       31895 :     X86Compiler c(&code);
+     272       31895 :     c.addFunc(FuncSignature0<double>());
+     273       31895 :     vector<X86Xmm> workspaceVar(workspace.size());
+     274      204803 :     for (int i = 0; i < (int) workspaceVar.size(); i++)
+     275      172908 :         workspaceVar[i] = c.newXmmSd();
+     276             :     X86Gp argsPointer = c.newIntPtr();
+     277       31895 :     c.mov(argsPointer, imm_ptr(&argValues[0]));
+     278             :     
+     279             :     // Load the arguments into variables.
+     280             :     
+     281       77012 :     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       90234 :         c.mov(variablePointer, imm_ptr(&getVariableReference(index->first)));
+     285       45117 :         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       31895 :     vector<int> operationConstantIndex(operation.size(), -1);
+     291      159686 :     for (int step = 0; step < (int) operation.size(); step++) {
+     292             :         // Find the constant value (if any) used by this operation.
+     293             :         
+     294      127791 :         Operation& op = *operation[step];
+     295             :         double value;
+     296      127791 :         if (op.getId() == Operation::CONSTANT)
+     297        4274 :             value = dynamic_cast<Operation::Constant&>(op).getValue();
+     298      123517 :         else if (op.getId() == Operation::ADD_CONSTANT)
+     299        7096 :             value = dynamic_cast<Operation::AddConstant&>(op).getValue();
+     300      116421 :         else if (op.getId() == Operation::MULTIPLY_CONSTANT)
+     301       27402 :             value = dynamic_cast<Operation::MultiplyConstant&>(op).getValue();
+     302       89019 :         else if (op.getId() == Operation::RECIPROCAL)
+     303        2890 :             value = 1.0;
+     304       86129 :         else if (op.getId() == Operation::STEP)
+     305        1246 :             value = 1.0;
+     306       84883 :         else if (op.getId() == Operation::DELTA)
+     307        1012 :             value = 1.0/0.0;
+     308       83871 :         else if (op.getId() == Operation::NANDELTA)
+     309          12 :             value = std::numeric_limits<double>::quiet_NaN();
+     310             :         else
+     311       83859 :             continue;
+     312             :         
+     313             :         // See if we already have a variable for this constant.
+     314             :         
+     315      500830 :         for (int i = 0; i < (int) constants.size(); i++)
+     316      463296 :             if (value == constants[i]) {
+     317        6398 :                 operationConstantIndex[step] = i;
+     318        6398 :                 break;
+     319             :             }
+     320       43932 :         if (operationConstantIndex[step] == -1) {
+     321       37534 :             operationConstantIndex[step] = constants.size();
+     322       37534 :             constants.push_back(value);
+     323             :         }
+     324             :     }
+     325             :     
+     326             :     // Load constants into variables.
+     327             :     
+     328       31895 :     vector<X86Xmm> constantVar(constants.size());
+     329       31895 :     if (constants.size() > 0) {
+     330             :         X86Gp constantsPointer = c.newIntPtr();
+     331       14744 :         c.mov(constantsPointer, imm_ptr(&constants[0]));
+     332       52278 :         for (int i = 0; i < (int) constants.size(); i++) {
+     333       37534 :             constantVar[i] = c.newXmmSd();
+     334       37534 :             c.movsd(constantVar[i], x86::ptr(constantsPointer, 8*i, 0));
+     335             :         }
+     336             :     }
+     337             :     
+     338             :     // Evaluate the operations.
+     339             :     
+     340      159686 :     for (int step = 0; step < (int) operation.size(); step++) {
+     341      127791 :         Operation& op = *operation[step];
+     342      127791 :         vector<int> args = arguments[step];
+     343      127791 :         if (args.size() == 1) {
+     344             :             // One or more sequential arguments.  Fill out the list.
+     345             :             
+     346      118361 :             for (int i = 1; i < op.getNumArguments(); i++)
+     347       19614 :                 args.push_back(args[0]+i);
+     348             :         }
+     349             :         
+     350             :         // Generate instructions to execute this operation.
+     351             :         
+     352      127791 :         switch (op.getId()) {
+     353        4274 :             case Operation::CONSTANT:
+     354        4274 :                 c.movsd(workspaceVar[target[step]], constantVar[operationConstantIndex[step]]);
+     355      127389 :                 break;
+     356             :             case Operation::ADD:
+     357       18878 :                 c.movsd(workspaceVar[target[step]], workspaceVar[args[0]]);
+     358       18878 :                 c.addsd(workspaceVar[target[step]], workspaceVar[args[1]]);
+     359             :                 break;
+     360             :             case Operation::SUBTRACT:
+     361        4536 :                 c.movsd(workspaceVar[target[step]], workspaceVar[args[0]]);
+     362        4536 :                 c.subsd(workspaceVar[target[step]], workspaceVar[args[1]]);
+     363             :                 break;
+     364             :             case Operation::MULTIPLY:
+     365       13180 :                 c.movsd(workspaceVar[target[step]], workspaceVar[args[0]]);
+     366       13180 :                 c.mulsd(workspaceVar[target[step]], workspaceVar[args[1]]);
+     367             :                 break;
+     368             :             case Operation::DIVIDE:
+     369       11856 :                 c.movsd(workspaceVar[target[step]], workspaceVar[args[0]]);
+     370       11856 :                 c.divsd(workspaceVar[target[step]], workspaceVar[args[1]]);
+     371             :                 break;
+     372             :             case Operation::POWER:
+     373           8 :                 generateTwoArgCall(c, workspaceVar[target[step]], workspaceVar[args[0]], workspaceVar[args[1]], pow);
+     374             :                 break;
+     375        3004 :             case Operation::NEGATE:
+     376        3004 :                 c.xorps(workspaceVar[target[step]], workspaceVar[target[step]]);
+     377        3004 :                 c.subsd(workspaceVar[target[step]], workspaceVar[args[0]]);
+     378             :                 break;
+     379             :             case Operation::SQRT:
+     380        2708 :                 c.sqrtsd(workspaceVar[target[step]], workspaceVar[args[0]]);
+     381             :                 break;
+     382             :             case Operation::EXP:
+     383        7164 :                 generateSingleArgCall(c, workspaceVar[target[step]], workspaceVar[args[0]], exp);
+     384             :                 break;
+     385             :             case Operation::LOG:
+     386        1476 :                 generateSingleArgCall(c, workspaceVar[target[step]], workspaceVar[args[0]], log);
+     387             :                 break;
+     388             :             case Operation::SIN:
+     389        1450 :                 generateSingleArgCall(c, workspaceVar[target[step]], workspaceVar[args[0]], sin);
+     390             :                 break;
+     391             :             case Operation::COS:
+     392        2142 :                 generateSingleArgCall(c, workspaceVar[target[step]], workspaceVar[args[0]], cos);
+     393             :                 break;
+     394             :             case Operation::TAN:
+     395           8 :                 generateSingleArgCall(c, workspaceVar[target[step]], workspaceVar[args[0]], tan);
+     396             :                 break;
+     397             :             case Operation::ASIN:
+     398           4 :                 generateSingleArgCall(c, workspaceVar[target[step]], workspaceVar[args[0]], asin);
+     399             :                 break;
+     400             :             case Operation::ACOS:
+     401          24 :                 generateSingleArgCall(c, workspaceVar[target[step]], workspaceVar[args[0]], acos);
+     402             :                 break;
+     403             :             case Operation::ATAN:
+     404           4 :                 generateSingleArgCall(c, workspaceVar[target[step]], workspaceVar[args[0]], atan);
+     405             :                 break;
+     406             :             case Operation::ATAN2:
+     407         104 :                 generateTwoArgCall(c, workspaceVar[target[step]], workspaceVar[args[0]], workspaceVar[args[1]], atan2);
+     408             :                 break;
+     409             :             case Operation::SINH:
+     410           8 :                 generateSingleArgCall(c, workspaceVar[target[step]], workspaceVar[args[0]], sinh);
+     411             :                 break;
+     412             :             case Operation::COSH:
+     413           8 :                 generateSingleArgCall(c, workspaceVar[target[step]], workspaceVar[args[0]], cosh);
+     414             :                 break;
+     415             :             case Operation::TANH:
+     416          56 :                 generateSingleArgCall(c, workspaceVar[target[step]], workspaceVar[args[0]], tanh);
+     417             :                 break;
+     418             :             case Operation::ASINH:
+     419           4 :                 generateSingleArgCall(c, workspaceVar[target[step]], workspaceVar[args[0]], asinh);
+     420             :                 break;
+     421             :             case Operation::ACOSH:
+     422           4 :                 generateSingleArgCall(c, workspaceVar[target[step]], workspaceVar[args[0]], acosh);
+     423             :                 break;
+     424             :             case Operation::ATANH:
+     425           4 :                 generateSingleArgCall(c, workspaceVar[target[step]], workspaceVar[args[0]], atanh);
+     426             :                 break;
+     427        1246 :             case Operation::STEP:
+     428        1246 :                 c.xorps(workspaceVar[target[step]], workspaceVar[target[step]]);
+     429        1246 :                 c.cmpsd(workspaceVar[target[step]], workspaceVar[args[0]], imm(18)); // Comparison mode is _CMP_LE_OQ = 18
+     430        1246 :                 c.andps(workspaceVar[target[step]], constantVar[operationConstantIndex[step]]);
+     431             :                 break;
+     432        1012 :             case Operation::DELTA:
+     433        1012 :                 c.xorps(workspaceVar[target[step]], workspaceVar[target[step]]);
+     434        1012 :                 c.cmpsd(workspaceVar[target[step]], workspaceVar[args[0]], imm(16)); // Comparison mode is _CMP_EQ_OS = 16
+     435        1012 :                 c.andps(workspaceVar[target[step]], constantVar[operationConstantIndex[step]]);
+     436             :                 break;
+     437          12 :             case Operation::NANDELTA:
+     438          12 :                 c.xorps(workspaceVar[target[step]], workspaceVar[target[step]]);
+     439          12 :                 c.cmpsd(workspaceVar[target[step]], workspaceVar[args[0]], imm(16)); // Comparison mode is _CMP_EQ_OS = 16
+     440          12 :                 c.andps(workspaceVar[target[step]], constantVar[operationConstantIndex[step]]);
+     441             :                 break;
+     442             :             case Operation::SQUARE:
+     443       16585 :                 c.movsd(workspaceVar[target[step]], workspaceVar[args[0]]);
+     444       16585 :                 c.mulsd(workspaceVar[target[step]], workspaceVar[args[0]]);
+     445             :                 break;
+     446             :             case Operation::CUBE:
+     447         198 :                 c.movsd(workspaceVar[target[step]], workspaceVar[args[0]]);
+     448         198 :                 c.mulsd(workspaceVar[target[step]], workspaceVar[args[0]]);
+     449         198 :                 c.mulsd(workspaceVar[target[step]], workspaceVar[args[0]]);
+     450             :                 break;
+     451        2890 :             case Operation::RECIPROCAL:
+     452        2890 :                 c.movsd(workspaceVar[target[step]], constantVar[operationConstantIndex[step]]);
+     453        2890 :                 c.divsd(workspaceVar[target[step]], workspaceVar[args[0]]);
+     454             :                 break;
+     455             :             case Operation::ADD_CONSTANT:
+     456        7096 :                 c.movsd(workspaceVar[target[step]], workspaceVar[args[0]]);
+     457        7096 :                 c.addsd(workspaceVar[target[step]], constantVar[operationConstantIndex[step]]);
+     458             :                 break;
+     459             :             case Operation::MULTIPLY_CONSTANT:
+     460       27402 :                 c.movsd(workspaceVar[target[step]], workspaceVar[args[0]]);
+     461       27402 :                 c.mulsd(workspaceVar[target[step]], constantVar[operationConstantIndex[step]]);
+     462             :                 break;
+     463             :             case Operation::ABS:
+     464          36 :                 generateSingleArgCall(c, workspaceVar[target[step]], workspaceVar[args[0]], fabs);
+     465             :                 break;
+     466             :             case Operation::FLOOR:
+     467           4 :                 generateSingleArgCall(c, workspaceVar[target[step]], workspaceVar[args[0]], floor);
+     468             :                 break;
+     469             :             case Operation::CEIL:
+     470           4 :                 generateSingleArgCall(c, workspaceVar[target[step]], workspaceVar[args[0]], ceil);
+     471             :                 break;
+     472             :             default:
+     473             :                 // Just invoke evaluateOperation().
+     474             :                 
+     475         916 :                 for (int i = 0; i < (int) args.size(); i++)
+     476         514 :                     c.movsd(x86::ptr(argsPointer, 8*i, 0), workspaceVar[args[i]]);
+     477             :                 X86Gp fn = c.newIntPtr();
+     478         402 :                 c.mov(fn, imm_ptr((void*) evaluateOperation));
+     479         402 :                 CCFuncCall* call = c.call(fn, FuncSignature2<double, Operation*, double*>());
+     480         402 :                 call->setArg(0, imm_ptr(&op));
+     481         402 :                 call->setArg(1, imm_ptr(&argValues[0]));
+     482         402 :                 call->setRet(0, workspaceVar[target[step]]);
+     483             :         }
+     484             :     }
+     485       31895 :     c.ret(workspaceVar[workspace.size()-1]);
+     486       31895 :     c.endFunc();
+     487       31895 :     c.finalize();
+     488       31895 :     runtime.add(&jitCode, &code);
+     489       31895 : }
+     490             : 
+     491       12400 : void generateSingleArgCall(X86Compiler& c, X86Xmm& dest, X86Xmm& arg, double (*function)(double)) {
+     492             :     X86Gp fn = c.newIntPtr();
+     493       12400 :     c.mov(fn, imm_ptr((void*) function));
+     494       12400 :     CCFuncCall* call = c.call(fn, FuncSignature1<double, double>());
+     495             :     call->setArg(0, arg);
+     496             :     call->setRet(0, dest);
+     497       12400 : }
+     498             : 
+     499         112 : void generateTwoArgCall(X86Compiler& c, X86Xmm& dest, X86Xmm& arg1, X86Xmm& arg2, double (*function)(double, double)) {
+     500             :     X86Gp fn = c.newIntPtr();
+     501         112 :     c.mov(fn, imm_ptr((void*) function));
+     502         224 :     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         112 : }
+     507             : 
+     508             : #endif
+     509             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lepton/CompiledExpression.h.func-sort-c.html b/coverage-libs/lepton/CompiledExpression.h.func-sort-c.html new file mode 100644 index 000000000000..d1965612e315 --- /dev/null +++ b/coverage-libs/lepton/CompiledExpression.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - lepton/CompiledExpression.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - CompiledExpression.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:11100.0 %
Date:2024-04-19 12:12:36Functions:00-
+
+ +
+ + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lepton/CompiledExpression.h.gcov.html b/coverage-libs/lepton/CompiledExpression.h.gcov.html new file mode 100644 index 000000000000..83b36c311d77 --- /dev/null +++ b/coverage-libs/lepton/CompiledExpression.h.gcov.html @@ -0,0 +1,241 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - lepton/CompiledExpression.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - CompiledExpression.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:11100.0 %
Date:2024-04-19 12:12:36Functions: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       31895 :     return ptr;
+      98             :   }
+      99             : };
+     100             : 
+     101             : class Operation;
+     102             : class ParsedExpression;
+     103             : 
+     104             : /**
+     105             :  * A CompiledExpression is a highly optimized representation of an expression for cases when you want to evaluate
+     106             :  * it many times as quickly as possible.  You should treat it as an opaque object; none of the internal representation
+     107             :  * is visible.
+     108             :  * 
+     109             :  * A CompiledExpression is created by calling createCompiledExpression() on a ParsedExpression.
+     110             :  * 
+     111             :  * WARNING: CompiledExpression is NOT thread safe.  You should never access a CompiledExpression from two threads at
+     112             :  * the same time.
+     113             :  */
+     114             : 
+     115             : class LEPTON_EXPORT CompiledExpression {
+     116             : public:
+     117             :     CompiledExpression();
+     118             :     CompiledExpression(const CompiledExpression& expression);
+     119             :     ~CompiledExpression();
+     120             :     CompiledExpression& operator=(const CompiledExpression& expression);
+     121             :     /**
+     122             :      * Get the names of all variables used by this expression.
+     123             :      */
+     124             :     const std::set<std::string>& getVariables() const;
+     125             :     /**
+     126             :      * Get a reference to the memory location where the value of a particular variable is stored.  This can be used
+     127             :      * to set the value of the variable before calling evaluate().
+     128             :      */
+     129             :     double& getVariableReference(const std::string& name);
+     130             :     /**
+     131             :      * You can optionally specify the memory locations from which the values of variables should be read.
+     132             :      * This is useful, for example, when several expressions all use the same variable.  You can then set
+     133             :      * the value of that variable in one place, and it will be seen by all of them.
+     134             :      */
+     135             :     void setVariableLocations(std::map<std::string, double*>& variableLocations);
+     136             :     /**
+     137             :      * Evaluate the expression.  The values of all variables should have been set before calling this.
+     138             :      */
+     139             :     double evaluate() const;
+     140             : private:
+     141             :     friend class ParsedExpression;
+     142             :     CompiledExpression(const ParsedExpression& expression);
+     143             :     void compileExpression(const ExpressionTreeNode& node, std::vector<std::pair<ExpressionTreeNode, int> >& temps);
+     144             :     int findTempIndex(const ExpressionTreeNode& node, std::vector<std::pair<ExpressionTreeNode, int> >& temps);
+     145             :     std::map<std::string, double*> variablePointers;
+     146             :     std::vector<std::pair<double*, double*> > variablesToCopy;
+     147             :     std::vector<std::vector<int> > arguments;
+     148             :     std::vector<int> target;
+     149             :     std::vector<Operation*> operation;
+     150             :     std::map<std::string, int> variableIndices;
+     151             :     std::set<std::string> variableNames;
+     152             :     mutable std::vector<double> workspace;
+     153             :     mutable std::vector<double> argValues;
+     154             :     std::map<std::string, double> dummyVariables;
+     155             :     void* jitCode;
+     156             :     void generateJitCode();
+     157             :     std::vector<double> constants;
+     158             :     AsmJitRuntimePtr runtimeptr;
+     159             : };
+     160             : 
+     161             : } // namespace lepton
+     162             : } // namespace PLMD
+     163             : 
+     164             : #endif /*LEPTON_COMPILED_EXPRESSION_H_*/
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lepton/Exception.h.func-sort-c.html b/coverage-libs/lepton/Exception.h.func-sort-c.html new file mode 100644 index 000000000000..fe0d8147379b --- /dev/null +++ b/coverage-libs/lepton/Exception.h.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - lepton/Exception.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - Exception.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:66100.0 %
Date:2024-04-19 12:12:36Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6lepton9ExceptionD0Ev0
_ZNK4PLMD6lepton9Exception4whatEv14
_ZN4PLMD6lepton9ExceptionC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE6248
_ZN4PLMD6lepton9ExceptionD2Ev6248
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lepton/Exception.h.func.html b/coverage-libs/lepton/Exception.h.func.html new file mode 100644 index 000000000000..7389a0bbc99a --- /dev/null +++ b/coverage-libs/lepton/Exception.h.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - lepton/Exception.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - Exception.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:66100.0 %
Date:2024-04-19 12:12:36Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6lepton9ExceptionC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE6248
_ZN4PLMD6lepton9ExceptionD0Ev0
_ZN4PLMD6lepton9ExceptionD2Ev6248
_ZNK4PLMD6lepton9Exception4whatEv14
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lepton/Exception.h.gcov.html b/coverage-libs/lepton/Exception.h.gcov.html new file mode 100644 index 000000000000..309fb2098502 --- /dev/null +++ b/coverage-libs/lepton/Exception.h.gcov.html @@ -0,0 +1,170 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - lepton/Exception.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - Exception.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:66100.0 %
Date:2024-04-19 12:12:36Functions: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        6248 :     Exception(const std::string& message) : message(message) {
+      80        6248 :     }
+      81        6248 :     ~Exception() throw() {
+      82        6248 :     }
+      83          14 :     const char* what() const throw() {
+      84          14 :         return message.c_str();
+      85             :     }
+      86             : private:
+      87             :     std::string message;
+      88             : };
+      89             : 
+      90             : } // namespace lepton
+      91             : } // namespace PLMD
+      92             : 
+      93             : #endif /*LEPTON_EXCEPTION_H_*/
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lepton/ExpressionProgram.cpp.func-sort-c.html b/coverage-libs/lepton/ExpressionProgram.cpp.func-sort-c.html new file mode 100644 index 000000000000..0aac37a5bd27 --- /dev/null +++ b/coverage-libs/lepton/ExpressionProgram.cpp.func-sort-c.html @@ -0,0 +1,121 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - lepton/ExpressionProgram.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - ExpressionProgram.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:0520.0 %
Date:2024-04-19 12:12:36Functions:0120.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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

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

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6lepton18ExpressionTreeNodeC2EPNS0_9OperationERKS1_31596
_ZN4PLMD6lepton18ExpressionTreeNodeC2EPNS0_9OperationERKS1_S5_55459
_ZN4PLMD6lepton18ExpressionTreeNodeC2EOS1_298421
_ZN4PLMD6lepton18ExpressionTreeNodeaSERKS1_506662
_ZN4PLMD6lepton18ExpressionTreeNodeC2EPNS0_9OperationERKSt6vectorIS1_SaIS1_EE509277
_ZNK4PLMD6lepton18ExpressionTreeNode10assignTagsERSt6vectorIPKS1_SaIS4_EE723538
_ZN4PLMD6lepton18ExpressionTreeNodeC2EPNS0_9OperationE2090849
_ZN4PLMD6lepton18ExpressionTreeNodeaSEOS1_2716790
_ZN4PLMD6lepton18ExpressionTreeNodeC2Ev3087983
_ZNK4PLMD6lepton18ExpressionTreeNodeeqERKS1_4765307
_ZNK4PLMD6lepton18ExpressionTreeNodeneERKS1_5523660
_ZN4PLMD6lepton18ExpressionTreeNodeC2ERKS1_15318898
_ZN4PLMD6lepton18ExpressionTreeNodeD2Ev21392483
_ZNK4PLMD6lepton18ExpressionTreeNode12getOperationEv36261896
_ZNK4PLMD6lepton18ExpressionTreeNode11getChildrenEv66522501
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lepton/ExpressionTreeNode.cpp.func.html b/coverage-libs/lepton/ExpressionTreeNode.cpp.func.html new file mode 100644 index 000000000000..05d509cf5568 --- /dev/null +++ b/coverage-libs/lepton/ExpressionTreeNode.cpp.func.html @@ -0,0 +1,133 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - lepton/ExpressionTreeNode.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - ExpressionTreeNode.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:687294.4 %
Date:2024-04-19 12:12:36Functions:1515100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6lepton18ExpressionTreeNodeC2EOS1_298421
_ZN4PLMD6lepton18ExpressionTreeNodeC2EPNS0_9OperationE2090849
_ZN4PLMD6lepton18ExpressionTreeNodeC2EPNS0_9OperationERKS1_31596
_ZN4PLMD6lepton18ExpressionTreeNodeC2EPNS0_9OperationERKS1_S5_55459
_ZN4PLMD6lepton18ExpressionTreeNodeC2EPNS0_9OperationERKSt6vectorIS1_SaIS1_EE509277
_ZN4PLMD6lepton18ExpressionTreeNodeC2ERKS1_15318898
_ZN4PLMD6lepton18ExpressionTreeNodeC2Ev3087983
_ZN4PLMD6lepton18ExpressionTreeNodeD2Ev21392483
_ZN4PLMD6lepton18ExpressionTreeNodeaSEOS1_2716790
_ZN4PLMD6lepton18ExpressionTreeNodeaSERKS1_506662
_ZNK4PLMD6lepton18ExpressionTreeNode10assignTagsERSt6vectorIPKS1_SaIS4_EE723538
_ZNK4PLMD6lepton18ExpressionTreeNode11getChildrenEv66522501
_ZNK4PLMD6lepton18ExpressionTreeNode12getOperationEv36261896
_ZNK4PLMD6lepton18ExpressionTreeNodeeqERKS1_4765307
_ZNK4PLMD6lepton18ExpressionTreeNodeneERKS1_5523660
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lepton/ExpressionTreeNode.cpp.gcov.html b/coverage-libs/lepton/ExpressionTreeNode.cpp.gcov.html new file mode 100644 index 000000000000..60cf6d3db368 --- /dev/null +++ b/coverage-libs/lepton/ExpressionTreeNode.cpp.gcov.html @@ -0,0 +1,264 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - lepton/ExpressionTreeNode.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - ExpressionTreeNode.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:687294.4 %
Date:2024-04-19 12:12:36Functions: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      509277 : ExpressionTreeNode::ExpressionTreeNode(Operation* operation, const vector<ExpressionTreeNode>& children) : operation(operation), children(children) {
+      74      509277 :     if (operation->getNumArguments() != children.size())
+      75           0 :         throw Exception("wrong number of arguments to function: "+operation->getName());
+      76      509277 : }
+      77             : 
+      78       55459 : ExpressionTreeNode::ExpressionTreeNode(Operation* operation, const ExpressionTreeNode& child1, const ExpressionTreeNode& child2) : operation(operation) {
+      79       55459 :     children.push_back(child1);
+      80       55459 :     children.push_back(child2);
+      81       55459 :     if (operation->getNumArguments() != children.size())
+      82           0 :         throw Exception("wrong number of arguments to function: "+operation->getName());
+      83       55459 : }
+      84             : 
+      85       31596 : ExpressionTreeNode::ExpressionTreeNode(Operation* operation, const ExpressionTreeNode& child) : operation(operation) {
+      86       31596 :     children.push_back(child);
+      87       31596 :     if (operation->getNumArguments() != children.size())
+      88           0 :         throw Exception("wrong number of arguments to function: "+operation->getName());
+      89       31596 : }
+      90             : 
+      91     2090849 : ExpressionTreeNode::ExpressionTreeNode(Operation* operation) : operation(operation) {
+      92     2090849 :     if (operation->getNumArguments() != children.size())
+      93           0 :         throw Exception("wrong number of arguments to function: "+operation->getName());
+      94     2090849 : }
+      95             : 
+      96    15318898 : ExpressionTreeNode::ExpressionTreeNode(const ExpressionTreeNode& node) : operation(node.operation == NULL ? NULL : node.operation->clone()), children(node.getChildren()) {
+      97    15318898 : }
+      98             : 
+      99      298421 : ExpressionTreeNode::ExpressionTreeNode(ExpressionTreeNode&& node) : operation(node.operation), children(move(node.children)) {
+     100      298421 :     node.operation = NULL;
+     101             :     node.children.clear();
+     102      298421 : }
+     103             : 
+     104     3087983 : ExpressionTreeNode::ExpressionTreeNode() : operation(NULL) {
+     105     3087983 : }
+     106             : 
+     107    21392483 : ExpressionTreeNode::~ExpressionTreeNode() {
+     108    21392483 :     if (operation != NULL)
+     109    18377042 :         delete operation;
+     110    21392483 : }
+     111             : 
+     112     5523660 : bool ExpressionTreeNode::operator!=(const ExpressionTreeNode& node) const {
+     113     5523660 :     if (node.getOperation() != getOperation())
+     114             :         return true;
+     115     1595781 :     if (getOperation().isSymmetric() && getChildren().size() == 2) {
+     116      570241 :         if (getChildren()[0] == node.getChildren()[0] && getChildren()[1] == node.getChildren()[1])
+     117             :             return false;
+     118      442929 :         if (getChildren()[0] == node.getChildren()[1] && getChildren()[1] == node.getChildren()[0])
+     119             :             return false;
+     120      442929 :         return true;
+     121             :     }
+     122     1478383 :     for (int i = 0; i < (int) getChildren().size(); i++)
+     123      758353 :         if (getChildren()[i] != node.getChildren()[i])
+     124             :             return true;
+     125             :     return false;
+     126             : }
+     127             : 
+     128     4765307 : bool ExpressionTreeNode::operator==(const ExpressionTreeNode& node) const {
+     129     4765307 :     return !(*this != node);
+     130             : }
+     131             : 
+     132      506662 : ExpressionTreeNode& ExpressionTreeNode::operator=(const ExpressionTreeNode& node) {
+     133      506662 :     if (operation != NULL)
+     134       62450 :         delete operation;
+     135      506662 :     operation = node.getOperation().clone();
+     136      506662 :     children = node.getChildren();
+     137      506662 :     return *this;
+     138             : }
+     139             : 
+     140     2716790 : ExpressionTreeNode& ExpressionTreeNode::operator=(ExpressionTreeNode&& node) {
+     141     2716790 :     if (operation != NULL)
+     142       73249 :         delete operation;
+     143     2716790 :     operation = node.operation;
+     144     2716790 :     children = move(node.children);
+     145     2716790 :     node.operation = NULL;
+     146             :     node.children.clear();
+     147     2716790 :     return *this;
+     148             : }
+     149             : 
+     150    36261896 : const Operation& ExpressionTreeNode::getOperation() const {
+     151    36261896 :     return *operation;
+     152             : }
+     153             : 
+     154    66522501 : const vector<ExpressionTreeNode>& ExpressionTreeNode::getChildren() const {
+     155    66522501 :     return children;
+     156             : }
+     157             : 
+     158      723538 : 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      723538 :     int numTags = examples.size();
+     164     1386800 :     for (const ExpressionTreeNode& child : getChildren())
+     165      663262 :         child.assignTags(examples);
+     166      723538 :     if (numTags == examples.size()) {
+     167             :         // All the children matched existing tags, so possibly this node does too.
+     168             :         
+     169    17668919 :         for (int i = 0; i < examples.size(); i++) {
+     170    17501876 :             const ExpressionTreeNode& example = *examples[i];
+     171    17501876 :             bool matches = (getChildren().size() == example.getChildren().size() && getOperation() == example.getOperation());
+     172    19165073 :             for (int j = 0; matches && j < getChildren().size(); j++)
+     173     1663197 :                 if (getChildren()[j].tag != example.getChildren()[j].tag)
+     174             :                     matches = false;
+     175    17501876 :             if (matches) {
+     176      299900 :                 tag = i;
+     177      299900 :                 return;
+     178             :             }
+     179             :         }
+     180             :     }
+     181             :     
+     182             :     // This node does not match any previous node, so assign a new tag.
+     183             :     
+     184      423638 :     tag = examples.size();
+     185      423638 :     examples.push_back(this);
+     186             : }
+     187             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lepton/Operation.cpp.func-sort-c.html b/coverage-libs/lepton/Operation.cpp.func-sort-c.html new file mode 100644 index 000000000000..8441588d5d4b --- /dev/null +++ b/coverage-libs/lepton/Operation.cpp.func-sort-c.html @@ -0,0 +1,301 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - lepton/Operation.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - Operation.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:27231586.3 %
Date:2024-04-19 12:12:36Functions: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
_ZNK4PLMD6lepton9Operation3Sec13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZNK4PLMD6lepton9Operation3Tan13differentiateERKSt6vectorINS0_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
_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
_ZNK4PLMD6lepton9Operation3Max13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE4
_ZNK4PLMD6lepton9Operation3Min13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE4
_ZNK4PLMD6lepton9Operation4Acos13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE9
_ZNK4PLMD6lepton9Operation4Tanh13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE9
_ZNK4PLMD6lepton9Operation6Select13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE12
_ZNK4PLMD6lepton9Operation5Atan213differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE53
_ZNK4PLMD6lepton9Operation3Sin13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE121
_ZNK4PLMD6lepton9Operation3Erf8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE204
_ZNK4PLMD6lepton9Operation4Erfc8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE204
_ZNK4PLMD6lepton9Operation4Step13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE253
_ZNK4PLMD6lepton9Operation3Cos13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE296
_ZNK4PLMD6lepton9Operation3Log13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE334
_ZNK4PLMD6lepton9Operation4Sqrt13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE384
_ZNK4PLMD6lepton9Operation3Exp13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1296
_ZNK4PLMD6lepton9Operation5Power13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1387
_ZNK4PLMD6lepton9Operation6Negate13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1695
_ZNK4PLMD6lepton9Operation8Subtract13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2097
_ZNK4PLMD6lepton9Operation6Divide13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3176
_ZNK4PLMD6lepton9Operation3Add13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3480
_ZNK4PLMD6lepton9Operation8Constant13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE5808
_ZNK4PLMD6lepton9Operation8Multiply13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE6642
_ZNK4PLMD6lepton9Operation8Variable13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE9931
_ZN4PLMDL6isZeroERKNS_6lepton18ExpressionTreeNodeE34161
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lepton/Operation.cpp.func.html b/coverage-libs/lepton/Operation.cpp.func.html new file mode 100644 index 000000000000..580d226afd9d --- /dev/null +++ b/coverage-libs/lepton/Operation.cpp.func.html @@ -0,0 +1,301 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - lepton/Operation.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - Operation.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:27231586.3 %
Date:2024-04-19 12:12:36Functions:535793.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMDL6isZeroERKNS_6lepton18ExpressionTreeNodeE34161
_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_traitsIcESaIcEEE3480
_ZNK4PLMD6lepton9Operation3Cos13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE296
_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_dEEE204
_ZNK4PLMD6lepton9Operation3Exp13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1296
_ZNK4PLMD6lepton9Operation3Log13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE334
_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_traitsIcESaIcEEE121
_ZNK4PLMD6lepton9Operation3Tan13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZNK4PLMD6lepton9Operation4Acos13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE9
_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_dEEE204
_ZNK4PLMD6lepton9Operation4Sech13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZNK4PLMD6lepton9Operation4Sinh13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZNK4PLMD6lepton9Operation4Sqrt13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE384
_ZNK4PLMD6lepton9Operation4Step13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE253
_ZNK4PLMD6lepton9Operation4Tanh13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE9
_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_traitsIcESaIcEEE53
_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_traitsIcESaIcEEE1387
_ZNK4PLMD6lepton9Operation6Custom13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZNK4PLMD6lepton9Operation6Divide13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3176
_ZNK4PLMD6lepton9Operation6Negate13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1695
_ZNK4PLMD6lepton9Operation6Select13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE12
_ZNK4PLMD6lepton9Operation6Square13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZNK4PLMD6lepton9Operation8Constant13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE5808
_ZNK4PLMD6lepton9Operation8Multiply13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE6642
_ZNK4PLMD6lepton9Operation8Nandelta13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZNK4PLMD6lepton9Operation8Subtract13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2097
_ZNK4PLMD6lepton9Operation8Variable13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE9931
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lepton/Operation.cpp.gcov.html b/coverage-libs/lepton/Operation.cpp.gcov.html new file mode 100644 index 000000000000..52af7d30012f --- /dev/null +++ b/coverage-libs/lepton/Operation.cpp.gcov.html @@ -0,0 +1,747 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - lepton/Operation.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - Operation.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:27231586.3 %
Date:2024-04-19 12:12:36Functions: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       34161 : static bool isZero(const ExpressionTreeNode& node) {
+      74       34161 :     if (node.getOperation().getId() != Operation::CONSTANT)
+      75             :         return false;
+      76       23026 :     return dynamic_cast<const Operation::Constant&>(node.getOperation()).getValue() == 0.0;
+      77             : }
+      78             : 
+      79         204 : double Operation::Erf::evaluate(double* args, const map<string, double>& variables) const {
+      80         204 :     return erf(args[0]);
+      81             : }
+      82             : 
+      83         204 : double Operation::Erfc::evaluate(double* args, const map<string, double>& variables) const {
+      84         204 :     return erfc(args[0]);
+      85             : }
+      86             : 
+      87        5808 : ExpressionTreeNode Operation::Constant::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+      88        5808 :     return ExpressionTreeNode(new Operation::Constant(0.0));
+      89             : }
+      90             : 
+      91        9931 : ExpressionTreeNode Operation::Variable::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+      92        9931 :     if (variable == name)
+      93        5021 :         return ExpressionTreeNode(new Operation::Constant(1.0));
+      94        4910 :     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        3480 : ExpressionTreeNode Operation::Add::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     120        3480 :     if (isZero(childDerivs[0]))
+     121         802 :         return childDerivs[1];
+     122        2678 :     if (isZero(childDerivs[1]))
+     123         835 :         return childDerivs[0];
+     124        1843 :     return ExpressionTreeNode(new Operation::Add(), childDerivs[0], childDerivs[1]);
+     125             : }
+     126             : 
+     127        2097 : ExpressionTreeNode Operation::Subtract::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     128        2097 :     if (isZero(childDerivs[0])) {
+     129        1389 :         if (isZero(childDerivs[1]))
+     130        1090 :             return ExpressionTreeNode(new Operation::Constant(0.0));
+     131         299 :         return ExpressionTreeNode(new Operation::Negate(), childDerivs[1]);
+     132             :     }
+     133         708 :     if (isZero(childDerivs[1]))
+     134         509 :         return childDerivs[0];
+     135         199 :     return ExpressionTreeNode(new Operation::Subtract(), childDerivs[0], childDerivs[1]);
+     136             : }
+     137             : 
+     138        6642 : ExpressionTreeNode Operation::Multiply::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     139        6642 :     if (isZero(childDerivs[0])) {
+     140        4521 :         if (isZero(childDerivs[1]))
+     141        2343 :             return ExpressionTreeNode(new Operation::Constant(0.0));
+     142        2178 :         return ExpressionTreeNode(new Operation::Multiply(), children[0], childDerivs[1]);
+     143             :     }
+     144        2121 :     if (isZero(childDerivs[1]))
+     145        1146 :         return ExpressionTreeNode(new Operation::Multiply(), children[1], childDerivs[0]);
+     146         975 :     return ExpressionTreeNode(new Operation::Add(),
+     147        1950 :                               ExpressionTreeNode(new Operation::Multiply(), children[0], childDerivs[1]),
+     148        2925 :                               ExpressionTreeNode(new Operation::Multiply(), children[1], childDerivs[0]));
+     149             : }
+     150             : 
+     151        3176 : ExpressionTreeNode Operation::Divide::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     152        3176 :     ExpressionTreeNode subexp;
+     153        3176 :     if (isZero(childDerivs[0])) {
+     154        1270 :         if (isZero(childDerivs[1]))
+     155         230 :             return ExpressionTreeNode(new Operation::Constant(0.0));
+     156        1040 :         subexp = ExpressionTreeNode(new Operation::Negate(), ExpressionTreeNode(new Operation::Multiply(), children[0], childDerivs[1]));
+     157             :     }
+     158        1906 :     else if (isZero(childDerivs[1]))
+     159        1876 :         subexp = ExpressionTreeNode(new Operation::Multiply(), children[1], childDerivs[0]);
+     160             :     else
+     161          60 :         subexp = ExpressionTreeNode(new Operation::Subtract(),
+     162          60 :                                                  ExpressionTreeNode(new Operation::Multiply(), children[1], childDerivs[0]),
+     163          90 :                                                  ExpressionTreeNode(new Operation::Multiply(), children[0], childDerivs[1]));
+     164        2946 :     return ExpressionTreeNode(new Operation::Divide(), subexp, ExpressionTreeNode(new Operation::Square(), children[1]));
+     165        3176 : }
+     166             : 
+     167        1387 : ExpressionTreeNode Operation::Power::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     168        1387 :     return ExpressionTreeNode(new Operation::Add(),
+     169        2774 :                               ExpressionTreeNode(new Operation::Multiply(),
+     170        2774 :                                                  ExpressionTreeNode(new Operation::Multiply(),
+     171             :                                                                     children[1],
+     172        2774 :                                                                     ExpressionTreeNode(new Operation::Power(),
+     173        2774 :                                                                                        children[0], ExpressionTreeNode(new Operation::AddConstant(-1.0), children[1]))),
+     174             :                                                  childDerivs[0]),
+     175        2774 :                               ExpressionTreeNode(new Operation::Multiply(),
+     176        2774 :                                                  ExpressionTreeNode(new Operation::Multiply(),
+     177        2774 :                                                                     ExpressionTreeNode(new Operation::Log(), children[0]),
+     178        2774 :                                                                     ExpressionTreeNode(new Operation::Power(), children[0], children[1])),
+     179        2774 :                                                  childDerivs[1]));
+     180             : }
+     181             : 
+     182        1695 : ExpressionTreeNode Operation::Negate::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     183        1695 :     if (isZero(childDerivs[0]))
+     184         826 :         return ExpressionTreeNode(new Operation::Constant(0.0));
+     185         869 :     return ExpressionTreeNode(new Operation::Negate(), childDerivs[0]);
+     186             : }
+     187             : 
+     188         384 : ExpressionTreeNode Operation::Sqrt::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     189         384 :     if (isZero(childDerivs[0]))
+     190          36 :         return ExpressionTreeNode(new Operation::Constant(0.0));
+     191         348 :     return ExpressionTreeNode(new Operation::Multiply(),
+     192         696 :                               ExpressionTreeNode(new Operation::MultiplyConstant(0.5),
+     193         696 :                                                  ExpressionTreeNode(new Operation::Reciprocal(),
+     194         696 :                                                                     ExpressionTreeNode(new Operation::Sqrt(), children[0]))),
+     195         348 :                               childDerivs[0]);
+     196             : }
+     197             : 
+     198        1296 : ExpressionTreeNode Operation::Exp::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     199        1296 :     if (isZero(childDerivs[0]))
+     200         116 :         return ExpressionTreeNode(new Operation::Constant(0.0));
+     201        1180 :     return ExpressionTreeNode(new Operation::Multiply(),
+     202        2360 :                               ExpressionTreeNode(new Operation::Exp(), children[0]),
+     203        1180 :                               childDerivs[0]);
+     204             : }
+     205             : 
+     206         334 : ExpressionTreeNode Operation::Log::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     207         334 :     if (isZero(childDerivs[0]))
+     208          84 :         return ExpressionTreeNode(new Operation::Constant(0.0));
+     209         250 :     return ExpressionTreeNode(new Operation::Multiply(),
+     210         500 :                               ExpressionTreeNode(new Operation::Reciprocal(), children[0]),
+     211         250 :                               childDerivs[0]);
+     212             : }
+     213             : 
+     214         121 : ExpressionTreeNode Operation::Sin::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     215         121 :     if (isZero(childDerivs[0]))
+     216          30 :         return ExpressionTreeNode(new Operation::Constant(0.0));
+     217          91 :     return ExpressionTreeNode(new Operation::Multiply(),
+     218         182 :                               ExpressionTreeNode(new Operation::Cos(), children[0]),
+     219          91 :                               childDerivs[0]);
+     220             : }
+     221             : 
+     222         296 : ExpressionTreeNode Operation::Cos::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     223         296 :     if (isZero(childDerivs[0]))
+     224          52 :         return ExpressionTreeNode(new Operation::Constant(0.0));
+     225         244 :     return ExpressionTreeNode(new Operation::Multiply(),
+     226         488 :                               ExpressionTreeNode(new Operation::Negate(),
+     227         488 :                                                  ExpressionTreeNode(new Operation::Sin(), children[0])),
+     228         244 :                               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           9 : ExpressionTreeNode Operation::Acos::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     284           9 :     if (isZero(childDerivs[0]))
+     285           0 :         return ExpressionTreeNode(new Operation::Constant(0.0));
+     286           9 :     return ExpressionTreeNode(new Operation::Multiply(),
+     287          18 :                               ExpressionTreeNode(new Operation::Negate(),
+     288          18 :                                                  ExpressionTreeNode(new Operation::Reciprocal(),
+     289          18 :                                                                     ExpressionTreeNode(new Operation::Sqrt(),
+     290          18 :                                                                                        ExpressionTreeNode(new Operation::Subtract(),
+     291          18 :                                                                                                           ExpressionTreeNode(new Operation::Constant(1.0)),
+     292          18 :                                                                                                           ExpressionTreeNode(new Operation::Square(), children[0]))))),
+     293           9 :                               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          53 : ExpressionTreeNode Operation::Atan2::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     307          53 :     return ExpressionTreeNode(new Operation::Divide(),
+     308         106 :                               ExpressionTreeNode(new Operation::Subtract(),
+     309         106 :                                                  ExpressionTreeNode(new Operation::Multiply(), children[1], childDerivs[0]),
+     310         106 :                                                  ExpressionTreeNode(new Operation::Multiply(), children[0], childDerivs[1])),
+     311         106 :                               ExpressionTreeNode(new Operation::Add(),
+     312         106 :                                                  ExpressionTreeNode(new Operation::Square(), children[0]),
+     313         159 :                                                  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           9 : ExpressionTreeNode Operation::Tanh::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     335           9 :     if (isZero(childDerivs[0]))
+     336           3 :         return ExpressionTreeNode(new Operation::Constant(0.0));
+     337           6 :     return ExpressionTreeNode(new Operation::Multiply(),
+     338          12 :                               ExpressionTreeNode(new Operation::Subtract(),
+     339          12 :                                                  ExpressionTreeNode(new Operation::Constant(1.0)),
+     340          12 :                                                  ExpressionTreeNode(new Operation::Square(),
+     341          12 :                                                                     ExpressionTreeNode(new Operation::Tanh(), children[0]))),
+     342           6 :                               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         253 : ExpressionTreeNode Operation::Step::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     370         253 :     return ExpressionTreeNode(new Operation::Delta(),children[0]);
+     371             : }
+     372             : 
+     373           2 : ExpressionTreeNode Operation::Delta::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     374           2 :     return ExpressionTreeNode(new Operation::Nandelta(), children[0]);
+     375             : }
+     376             : 
+     377           2 : ExpressionTreeNode Operation::Nandelta::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     378           2 :     return ExpressionTreeNode(new Operation::Nandelta(), children[0]);
+     379             : }
+     380             : 
+     381           2 : ExpressionTreeNode Operation::Square::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     382           2 :     if (isZero(childDerivs[0]))
+     383           0 :         return ExpressionTreeNode(new Operation::Constant(0.0));
+     384           2 :     return ExpressionTreeNode(new Operation::Multiply(),
+     385           4 :                               ExpressionTreeNode(new Operation::MultiplyConstant(2.0),
+     386             :                                                  children[0]),
+     387           2 :                               childDerivs[0]);
+     388             : }
+     389             : 
+     390           2 : ExpressionTreeNode Operation::Cube::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     391           2 :     if (isZero(childDerivs[0]))
+     392           0 :         return ExpressionTreeNode(new Operation::Constant(0.0));
+     393           2 :     return ExpressionTreeNode(new Operation::Multiply(),
+     394           4 :                               ExpressionTreeNode(new Operation::MultiplyConstant(3.0),
+     395           4 :                                                  ExpressionTreeNode(new Operation::Square(), children[0])),
+     396           2 :                               childDerivs[0]);
+     397             : }
+     398             : 
+     399           2 : ExpressionTreeNode Operation::Reciprocal::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     400           2 :     if (isZero(childDerivs[0]))
+     401           0 :         return ExpressionTreeNode(new Operation::Constant(0.0));
+     402           2 :     return ExpressionTreeNode(new Operation::Multiply(),
+     403           4 :                               ExpressionTreeNode(new Operation::Negate(),
+     404           4 :                                                  ExpressionTreeNode(new Operation::Reciprocal(),
+     405           4 :                                                                     ExpressionTreeNode(new Operation::Square(), children[0]))),
+     406           2 :                               childDerivs[0]);
+     407             : }
+     408             : 
+     409           0 : ExpressionTreeNode Operation::AddConstant::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     410           0 :     return childDerivs[0];
+     411             : }
+     412             : 
+     413           0 : ExpressionTreeNode Operation::MultiplyConstant::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     414           0 :     if (isZero(childDerivs[0]))
+     415           0 :         return ExpressionTreeNode(new Operation::Constant(0.0));
+     416           0 :     return ExpressionTreeNode(new Operation::MultiplyConstant(value),
+     417           0 :                               childDerivs[0]);
+     418             : }
+     419             : 
+     420           0 : ExpressionTreeNode Operation::PowerConstant::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     421           0 :     if (isZero(childDerivs[0]))
+     422           0 :         return ExpressionTreeNode(new Operation::Constant(0.0));
+     423           0 :     return ExpressionTreeNode(new Operation::Multiply(),
+     424           0 :                               ExpressionTreeNode(new Operation::MultiplyConstant(value),
+     425           0 :                                                  ExpressionTreeNode(new Operation::PowerConstant(value-1),
+     426             :                                                                     children[0])),
+     427           0 :                               childDerivs[0]);
+     428             : }
+     429             : 
+     430           4 : ExpressionTreeNode Operation::Min::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     431           4 :     ExpressionTreeNode step(new Operation::Step(),
+     432           8 :                             ExpressionTreeNode(new Operation::Subtract(), children[0], children[1]));
+     433          20 :     return ExpressionTreeNode(new Operation::Select(), {step, childDerivs[1], childDerivs[0]});
+     434           4 : }
+     435             : 
+     436           4 : ExpressionTreeNode Operation::Max::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     437           4 :     ExpressionTreeNode step(new Operation::Step(),
+     438           8 :                             ExpressionTreeNode(new Operation::Subtract(), children[0], children[1]));
+     439          20 :     return ExpressionTreeNode(new Operation::Select(), {step, childDerivs[0], childDerivs[1]});
+     440           4 : }
+     441             : 
+     442           3 : ExpressionTreeNode Operation::Abs::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     443           3 :     if (isZero(childDerivs[0]))
+     444           0 :         return ExpressionTreeNode(new Operation::Constant(0.0));
+     445           3 :     ExpressionTreeNode step(new Operation::Step(), children[0]);
+     446           3 :     return ExpressionTreeNode(new Operation::Multiply(),
+     447             :                               childDerivs[0],
+     448           6 :                               ExpressionTreeNode(new Operation::AddConstant(-1),
+     449           9 :                                                  ExpressionTreeNode(new Operation::MultiplyConstant(2), step)));
+     450           3 : }
+     451             : 
+     452           2 : ExpressionTreeNode Operation::Floor::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     453           2 :     return ExpressionTreeNode(new Operation::Constant(0.0));
+     454             : }
+     455             : 
+     456           2 : ExpressionTreeNode Operation::Ceil::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     457           2 :     return ExpressionTreeNode(new Operation::Constant(0.0));
+     458             : }
+     459             : 
+     460          12 : ExpressionTreeNode Operation::Select::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     461             :     vector<ExpressionTreeNode> derivChildren;
+     462          12 :     derivChildren.push_back(children[0]);
+     463          12 :     derivChildren.push_back(childDerivs[1]);
+     464          12 :     derivChildren.push_back(childDerivs[2]);
+     465          24 :     return ExpressionTreeNode(new Operation::Select(), derivChildren);
+     466          12 : }
+     467             : 
+     468             : #define LEPTON_CONST(x) ExpressionTreeNode(new Operation::Constant(x))
+     469             : #define LEPTON_OP1(name,x) ExpressionTreeNode(new Operation::name(),x)
+     470             : #define LEPTON_OP2(name,x,y) ExpressionTreeNode(new Operation::name(),x,y)
+     471             : #define LEPTON_ADD_CONST(x,y) ExpressionTreeNode(new Operation::AddConstant(x),y)
+     472             : 
+     473           2 : ExpressionTreeNode Operation::Acot::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     474             :     return
+     475           2 :       LEPTON_OP2(Multiply,
+     476             :         LEPTON_OP1(Negate,
+     477             :           LEPTON_OP1(Reciprocal,
+     478             :             LEPTON_ADD_CONST(1.0,
+     479             :               LEPTON_OP1(Square,children[0])
+     480             :             )
+     481             :           )
+     482             :         ),
+     483             :         childDerivs[0]
+     484             :       );
+     485             : }
+     486             : 
+     487           2 : ExpressionTreeNode Operation::Asec::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     488             :     return
+     489           2 :       LEPTON_OP2(Multiply,
+     490             :         LEPTON_OP1(Reciprocal,
+     491             :           LEPTON_OP2(Multiply,
+     492             :             LEPTON_OP1(Abs,children[0]),
+     493             :             LEPTON_OP1(Sqrt,
+     494             :               LEPTON_OP2(Subtract,
+     495             :                 LEPTON_OP1(Square,children[0]),
+     496             :                 LEPTON_CONST(1.0)
+     497             :               )
+     498             :             )
+     499             :           )
+     500             :         ),
+     501             :         childDerivs[0]
+     502             :       );
+     503             : }
+     504             : 
+     505           2 : ExpressionTreeNode Operation::Acsc::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     506             :     return
+     507           2 :     LEPTON_OP2(Multiply,
+     508             :       LEPTON_OP1(Negate,
+     509             :         LEPTON_OP1(Reciprocal,
+     510             :           LEPTON_OP2(Multiply,
+     511             :             LEPTON_OP1(Abs,children[0]),
+     512             :             LEPTON_OP1(Sqrt,
+     513             :               LEPTON_OP2(Subtract,
+     514             :                 LEPTON_OP1(Square,children[0]),
+     515             :                 LEPTON_CONST(1.0)
+     516             :               )
+     517             :             )
+     518             :           )
+     519             :         )
+     520             :       ),
+     521             :       childDerivs[0]
+     522             :     );
+     523             : }
+     524             : 
+     525           2 : ExpressionTreeNode Operation::Coth::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     526             :     return
+     527           2 :     LEPTON_OP2(Multiply,
+     528             :       LEPTON_OP2(Subtract,
+     529             :         LEPTON_CONST(1.0),
+     530             :         LEPTON_OP1(Square,
+     531             :           LEPTON_OP1(Coth,children[0])
+     532             :         )
+     533             :       ),
+     534             :       childDerivs[0]
+     535             :     );
+     536             : }
+     537             : 
+     538           2 : ExpressionTreeNode Operation::Sech::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     539             :     return
+     540           2 :     LEPTON_OP2(Multiply,
+     541             :       LEPTON_OP1(Negate,
+     542             :         LEPTON_OP2(Multiply,
+     543             :           LEPTON_OP1(Tanh,children[0]),
+     544             :           LEPTON_OP1(Sech,children[0])
+     545             :         )
+     546             :       ),
+     547             :       childDerivs[0]
+     548             :     );
+     549             : }
+     550             : 
+     551           2 : ExpressionTreeNode Operation::Csch::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     552             :     return
+     553           2 :     LEPTON_OP2(Multiply,
+     554             :       LEPTON_OP1(Negate,
+     555             :         LEPTON_OP2(Multiply,
+     556             :           LEPTON_OP1(Coth,children[0]),
+     557             :           LEPTON_OP1(Csch,children[0])
+     558             :         )
+     559             :       ),
+     560             :       childDerivs[0]
+     561             :     );
+     562             : }
+     563             : 
+     564           2 : ExpressionTreeNode Operation::Acosh::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     565             :     return
+     566           2 :     LEPTON_OP2(Multiply,
+     567             :       LEPTON_OP1(Reciprocal,
+     568             :         LEPTON_OP1(Sqrt,
+     569             :           LEPTON_OP2(Subtract,
+     570             :             LEPTON_OP1(Square,children[0]),
+     571             :             LEPTON_CONST(1.0)
+     572             :           )
+     573             :         )
+     574             :       ),
+     575             :       childDerivs[0]
+     576             :     );
+     577             : }
+     578             : 
+     579           2 : ExpressionTreeNode Operation::Atanh::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     580             :     return
+     581           2 :     LEPTON_OP2(Multiply,
+     582             :       LEPTON_OP1(Reciprocal,
+     583             :         LEPTON_OP2(Subtract,
+     584             :           LEPTON_CONST(1.0),
+     585             :           LEPTON_OP1(Square,children[0])
+     586             :         )
+     587             :       ),
+     588             :       childDerivs[0]
+     589             :     );
+     590             : }
+     591             : 
+     592           2 : ExpressionTreeNode Operation::Asinh::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     593             :     return
+     594           2 :     LEPTON_OP2(Multiply,
+     595             :       LEPTON_OP1(Reciprocal,
+     596             :         LEPTON_OP1(Sqrt,
+     597             :           LEPTON_ADD_CONST(1.0,
+     598             :             LEPTON_OP1(Square,children[0])
+     599             :           )
+     600             :         )
+     601             :       ),
+     602             :       childDerivs[0]
+     603             :     );
+     604             : }
+     605             : 
+     606           2 : ExpressionTreeNode Operation::Acoth::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     607             :     return
+     608           2 :     LEPTON_OP2(Multiply,
+     609             :       LEPTON_OP1(Reciprocal,
+     610             :         LEPTON_OP2(Subtract,
+     611             :           LEPTON_CONST(1.0),
+     612             :           LEPTON_OP1(Square,children[0])
+     613             :         )
+     614             :       ),
+     615             :       childDerivs[0]
+     616             :     );
+     617             : }
+     618             : 
+     619           2 : ExpressionTreeNode Operation::Asech::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     620             :     return
+     621           2 :     LEPTON_OP2(Multiply,
+     622             :       LEPTON_OP1(Negate,
+     623             :         LEPTON_OP1(Reciprocal,
+     624             :           LEPTON_OP2(Multiply,
+     625             :             children[0],
+     626             :             LEPTON_OP2(Multiply,
+     627             :               LEPTON_ADD_CONST(1.0,
+     628             :                 children[0]
+     629             :               ),
+     630             :               LEPTON_OP1(Sqrt,
+     631             :                 LEPTON_OP2(Divide,
+     632             :                   LEPTON_OP2(Subtract,
+     633             :                     LEPTON_CONST(1.0),
+     634             :                     children[0]
+     635             :                   ),
+     636             :                   LEPTON_ADD_CONST(1.0,
+     637             :                     children[0]
+     638             :                   )
+     639             :                 )
+     640             :               )
+     641             :             )
+     642             :           )
+     643             :         )
+     644             :       ),
+     645             :       childDerivs[0]
+     646             :     );
+     647             : }
+     648             : 
+     649           2 : ExpressionTreeNode Operation::Acsch::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     650             :     return
+     651           2 :     LEPTON_OP2(Multiply,
+     652             :       LEPTON_OP1(Negate,
+     653             :         LEPTON_OP1(Reciprocal,
+     654             :           LEPTON_OP2(Multiply,
+     655             :             LEPTON_OP1(Square,children[0]),
+     656             :             LEPTON_OP1(Sqrt,
+     657             :               LEPTON_ADD_CONST(1.0,
+     658             :                 LEPTON_OP1(Reciprocal,
+     659             :                   LEPTON_OP1(Square,children[0])
+     660             :                 )
+     661             :               )
+     662             :             )
+     663             :           )
+     664             :         )
+     665             :       ),
+     666             :       childDerivs[0]
+     667             :     );
+     668             : }
+     669             : 
+     670             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lepton/Operation.h.func-sort-c.html b/coverage-libs/lepton/Operation.h.func-sort-c.html new file mode 100644 index 000000000000..8a2bdbb3e223 --- /dev/null +++ b/coverage-libs/lepton/Operation.h.func-sort-c.html @@ -0,0 +1,1233 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - lepton/Operation.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - Operation.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:53055695.3 %
Date:2024-04-19 12:12:36Functions: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
_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
_ZNK4PLMD6lepton9Operation8Nandelta7getNameB5cxx11Ev6
_ZNK4PLMD6lepton9Operation4Acos7getNameB5cxx11Ev7
_ZNK4PLMD6lepton9Operation4Tanh7getNameB5cxx11Ev13
_ZNK4PLMD6lepton9Operation3Abs7getNameB5cxx11Ev18
_ZNK4PLMD6lepton9Operation6Select7getNameB5cxx11Ev24
_ZNK4PLMD6lepton9Operation3Erf15getNumArgumentsEv26
_ZNK4PLMD6lepton9Operation4Acot15getNumArgumentsEv26
_ZNK4PLMD6lepton9Operation4Acsc15getNumArgumentsEv26
_ZNK4PLMD6lepton9Operation4Asec15getNumArgumentsEv26
_ZNK4PLMD6lepton9Operation4Ceil15getNumArgumentsEv26
_ZNK4PLMD6lepton9Operation4Erfc15getNumArgumentsEv26
_ZNK4PLMD6lepton9Operation5Acosh15getNumArgumentsEv26
_ZNK4PLMD6lepton9Operation5Acoth15getNumArgumentsEv26
_ZNK4PLMD6lepton9Operation5Acsch15getNumArgumentsEv26
_ZNK4PLMD6lepton9Operation5Asech15getNumArgumentsEv26
_ZNK4PLMD6lepton9Operation5Asinh15getNumArgumentsEv26
_ZNK4PLMD6lepton9Operation5Atanh15getNumArgumentsEv26
_ZNK4PLMD6lepton9Operation5Floor15getNumArgumentsEv26
_ZNK4PLMD6lepton9Operation4Asin15getNumArgumentsEv28
_ZNK4PLMD6lepton9Operation4Atan15getNumArgumentsEv28
_ZNK4PLMD6lepton9Operation5Atan27getNameB5cxx11Ev30
_ZNK4PLMD6lepton9Operation8Variable8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE30
_ZNK4PLMD6lepton9Operation3Erf5cloneEv46
_ZNK4PLMD6lepton9Operation4Acot5cloneEv46
_ZNK4PLMD6lepton9Operation4Acsc5cloneEv46
_ZNK4PLMD6lepton9Operation4Asec5cloneEv46
_ZNK4PLMD6lepton9Operation4Ceil5cloneEv46
_ZNK4PLMD6lepton9Operation4Erfc5cloneEv46
_ZNK4PLMD6lepton9Operation5Acosh5cloneEv46
_ZNK4PLMD6lepton9Operation5Acoth5cloneEv46
_ZNK4PLMD6lepton9Operation5Acsch5cloneEv46
_ZNK4PLMD6lepton9Operation5Asech5cloneEv46
_ZNK4PLMD6lepton9Operation5Asinh5cloneEv46
_ZNK4PLMD6lepton9Operation5Atanh5cloneEv46
_ZNK4PLMD6lepton9Operation5Floor5cloneEv46
_ZNK4PLMD6lepton9Operation4Asin5cloneEv50
_ZNK4PLMD6lepton9Operation4Atan5cloneEv50
_ZNK4PLMD6lepton9Operation4Cube7getNameB5cxx11Ev50
_ZNK4PLMD6lepton9Operation3Cot15getNumArgumentsEv52
_ZNK4PLMD6lepton9Operation3Tan15getNumArgumentsEv52
_ZNK4PLMD6lepton9Operation4Cosh15getNumArgumentsEv52
_ZNK4PLMD6lepton9Operation4Csch15getNumArgumentsEv52
_ZNK4PLMD6lepton9Operation4Sech15getNumArgumentsEv52
_ZNK4PLMD6lepton9Operation4Sinh15getNumArgumentsEv52
_ZNK4PLMD6lepton9Operation13PowerConstant7getNameB5cxx11Ev68
_ZNK4PLMD6lepton9Operation3Erf5getIdEv68
_ZNK4PLMD6lepton9Operation3Max15getNumArgumentsEv68
_ZNK4PLMD6lepton9Operation3Min15getNumArgumentsEv68
_ZNK4PLMD6lepton9Operation4Acot5getIdEv68
_ZNK4PLMD6lepton9Operation4Acsc5getIdEv68
_ZNK4PLMD6lepton9Operation4Asec5getIdEv68
_ZNK4PLMD6lepton9Operation4Ceil5getIdEv68
_ZNK4PLMD6lepton9Operation4Erfc5getIdEv68
_ZNK4PLMD6lepton9Operation5Acosh5getIdEv68
_ZNK4PLMD6lepton9Operation5Acoth5getIdEv68
_ZNK4PLMD6lepton9Operation5Acsch5getIdEv68
_ZNK4PLMD6lepton9Operation5Asech5getIdEv68
_ZNK4PLMD6lepton9Operation5Asinh5getIdEv68
_ZNK4PLMD6lepton9Operation5Atanh5getIdEv68
_ZNK4PLMD6lepton9Operation5Floor5getIdEv68
_ZNK4PLMD6lepton9Operation4Asin5getIdEv74
_ZNK4PLMD6lepton9Operation4Atan5getIdEv74
_ZNK4PLMD6lepton9Operation8Nandelta15getNumArgumentsEv74
_ZNK4PLMD6lepton9Operation3Csc15getNumArgumentsEv78
_ZNK4PLMD6lepton9Operation3Sec15getNumArgumentsEv78
_ZNK4PLMD6lepton9Operation4Coth15getNumArgumentsEv78
_ZNK4PLMD6lepton9Operation3Max5cloneEv92
_ZNK4PLMD6lepton9Operation3Min5cloneEv92
_ZNK4PLMD6lepton9Operation4Acos8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE102
_ZNK4PLMD6lepton9Operation4Asin8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE102
_ZNK4PLMD6lepton9Operation4Atan8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE102
_ZNK4PLMD6lepton9Operation4Ceil8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE102
_ZNK4PLMD6lepton9Operation5Acosh8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE102
_ZNK4PLMD6lepton9Operation5Asinh8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE102
_ZNK4PLMD6lepton9Operation5Atanh8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE102
_ZNK4PLMD6lepton9Operation5Floor8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE102
_ZNK4PLMD6lepton9Operation4Acos15getNumArgumentsEv105
_ZNK4PLMD6lepton9Operation3Log8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE109
_ZNK4PLMD6lepton9Operation4Cosh5cloneEv110
_ZNK4PLMD6lepton9Operation4Sinh5cloneEv110
_ZNK4PLMD6lepton9Operation13PowerConstant15isInfixOperatorEv136
_ZNK4PLMD6lepton9Operation3Max5getIdEv136
_ZNK4PLMD6lepton9Operation3Min5getIdEv136
_ZNK4PLMD6lepton9Operation8Nandelta5cloneEv138
_ZNK4PLMD6lepton9Operation4Cosh5getIdEv144
_ZNK4PLMD6lepton9Operation4Sinh5getIdEv144
_ZNK4PLMD6lepton9Operation3Tan5cloneEv146
_ZNK4PLMD6lepton9Operation4Acos5cloneEv167
_ZNK4PLMD6lepton9Operation3Cot5cloneEv190
_ZNK4PLMD6lepton9Operation4Csch5cloneEv190
_ZNK4PLMD6lepton9Operation4Sech5cloneEv190
_ZNK4PLMD6lepton9Operation3Abs15getNumArgumentsEv200
_ZNK4PLMD6lepton9Operation3Tan8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE203
_ZNK4PLMD6lepton9Operation4Cosh8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE203
_ZNK4PLMD6lepton9Operation4Sinh8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE203
_ZNK4PLMD6lepton9Operation5Delta8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE203
_ZNK4PLMD6lepton9Operation4Acot8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE204
_ZNK4PLMD6lepton9Operation4Acsc8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE204
_ZNK4PLMD6lepton9Operation4Asec8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE204
_ZNK4PLMD6lepton9Operation4Cube8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE204
_ZNK4PLMD6lepton9Operation5Acoth8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE204
_ZNK4PLMD6lepton9Operation5Acsch8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE204
_ZNK4PLMD6lepton9Operation5Asech8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE204
_ZNK4PLMD6lepton9Operation8Nandelta5getIdEv204
_ZNK4PLMD6lepton9Operation3Cos8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE205
_ZNK4PLMD6lepton9Operation5Power8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE205
_ZNK4PLMD6lepton9Operation3Sin8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE207
_ZNK4PLMD6lepton9Operation3Tan5getIdEv224
_ZNK4PLMD6lepton9Operation3Cot5getIdEv236
_ZNK4PLMD6lepton9Operation4Csch5getIdEv236
_ZNK4PLMD6lepton9Operation4Sech5getIdEv236
_ZNK4PLMD6lepton9Operation5Delta7getNameB5cxx11Ev248
_ZNK4PLMD6lepton9Operation4Tanh15getNumArgumentsEv251
_ZNK4PLMD6lepton9Operation3Sec5cloneEv256
_ZNK4PLMD6lepton9Operation4Tanh8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE304
_ZNK4PLMD6lepton9Operation8Nandelta8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE304
_ZNK4PLMD6lepton9Operation4Acos5getIdEv324
_ZNK4PLMD6lepton9Operation3Csc5cloneEv336
_ZNK4PLMD6lepton9Operation3Sec5getIdEv340
_ZNK4PLMD6lepton9Operation4Coth5cloneEv340
_ZNK4PLMD6lepton9Operation3Csc5getIdEv362
_ZNK4PLMD6lepton9Operation3Log7getNameB5cxx11Ev370
_ZNK4PLMD6lepton9Operation4Coth5getIdEv370
_ZNK4PLMD6lepton9Operation3Cot8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE406
_ZNK4PLMD6lepton9Operation3Exp8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE406
_ZNK4PLMD6lepton9Operation4Csch8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE406
_ZNK4PLMD6lepton9Operation4Sech8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE406
_ZNK4PLMD6lepton9Operation3Max8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE408
_ZNK4PLMD6lepton9Operation3Min8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE408
_ZNK4PLMD6lepton9Operation5Atan28evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE408
_ZNK4PLMD6lepton9Operation3Add8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE424
_ZNK4PLMD6lepton9Operation6Select15getNumArgumentsEv424
_ZNK4PLMD6lepton9Operation4Step7getNameB5cxx11Ev431
_ZNK4PLMD6lepton9Operation3Abs8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE507
_ZNK4PLMD6lepton9Operation6Select5cloneEv592
_ZNK4PLMD6lepton9Operation4Step8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE607
_ZNK4PLMD6lepton9Operation3Csc8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE608
_ZNK4PLMD6lepton9Operation3Sec8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE608
_ZNK4PLMD6lepton9Operation4Coth8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE608
_ZNK4PLMD6lepton9Operation5Atan215getNumArgumentsEv633
_ZNK4PLMD6lepton9Operation4Cube15getNumArgumentsEv676
_ZNK4PLMD6lepton9Operation4Sqrt7getNameB5cxx11Ev730
_ZNK4PLMD6lepton9Operation10Reciprocal7getNameB5cxx11Ev735
_ZNK4PLMD6lepton9Operation13PowerConstant15getNumArgumentsEv748
_ZNK4PLMD6lepton9Operation6Negate7getNameB5cxx11Ev769
_ZNK4PLMD6lepton9Operation6Divide8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE805
_ZNK4PLMD6lepton9Operation3Sin7getNameB5cxx11Ev844
_ZNK4PLMD6lepton9Operation6Select5getIdEv852
_ZNK4PLMD6lepton9Operation3Abs5getIdEv1092
_ZNK4PLMD6lepton9Operation4Sqrt8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE1116
_ZNK4PLMD6lepton9Operation3Abs5cloneEv1152
_ZNK4PLMD6lepton9Operation3Cos7getNameB5cxx11Ev1257
_ZNK4PLMD6lepton9Operation13PowerConstantneERKS1_1263
_ZNK4PLMD6lepton9Operation5Atan25cloneEv1270
_ZNK4PLMD6lepton9Operation8Constant7getNameB5cxx11Ev1305
_ZNK4PLMD6lepton9Operation8Subtract8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE1324
_ZNK4PLMD6lepton9Operation8Subtract15isInfixOperatorEv1359
_ZNK4PLMD6lepton9Operation8Subtract7getNameB5cxx11Ev1359
_ZNK4PLMD6lepton9Operation4Tanh5getIdEv1793
_ZNK4PLMD6lepton9Operation5Atan25getIdEv1878
_ZNK4PLMD6lepton9Operation10Reciprocal8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE2122
_ZNK4PLMD6lepton9Operation3Exp7getNameB5cxx11Ev2230
_ZNK4PLMD6lepton9Operation4Tanh5cloneEv2237
_ZNK4PLMD6lepton9Operation6Select8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE2444
_ZNK4PLMD6lepton9Operation16MultiplyConstant8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE2634
_ZNK4PLMD6lepton9Operation4Cube5cloneEv2804
_ZNK4PLMD6lepton9Operation6Negate8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE2809
_ZNK4PLMD6lepton9Operation11AddConstant8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE2886
_ZNK4PLMD6lepton9Operation6Divide15isInfixOperatorEv2979
_ZNK4PLMD6lepton9Operation6Divide7getNameB5cxx11Ev2979
_ZNK4PLMD6lepton9Operation8Multiply15isInfixOperatorEv3290
_ZNK4PLMD6lepton9Operation8Multiply7getNameB5cxx11Ev3290
_ZNK4PLMD6lepton9Operation8Multiply8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE3436
_ZNK4PLMD6lepton9Operation6Square8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE3707
_ZNK4PLMD6lepton9Operation5Delta15getNumArgumentsEv3899
_ZNK4PLMD6lepton9Operation13PowerConstant5cloneEv3942
_ZNK4PLMD6lepton9Operation13PowerConstant5getIdEv3962
_ZNK4PLMD6lepton9Operation11AddConstant7getNameB5cxx11Ev4396
_ZNK4PLMD6lepton9Operation4Cube5getIdEv5073
_ZNK4PLMD6lepton9Operation4Step15getNumArgumentsEv5084
_ZNK4PLMD6lepton9Operation3Add15isInfixOperatorEv6109
_ZNK4PLMD6lepton9Operation3Add7getNameB5cxx11Ev6109
_ZNK4PLMD6lepton9Operation3Sin15getNumArgumentsEv6254
_ZNK4PLMD6lepton9Operation6Square7getNameB5cxx11Ev6511
_ZNK4PLMD6lepton9Operation16MultiplyConstant7getNameB5cxx11Ev8267
_ZNK4PLMD6lepton9Operation3Cos15getNumArgumentsEv9974
_ZNK4PLMD6lepton9Operation4Sqrt15getNumArgumentsEv10658
_ZNK4PLMD6lepton9Operation10Reciprocal15getNumArgumentsEv10835
_ZNK4PLMD6lepton9Operation3Log15getNumArgumentsEv11843
_ZNK4PLMD6lepton9Operation5Power15getNumArgumentsEv17607
_ZNK4PLMD6lepton9Operation5Delta5cloneEv25363
_ZNK4PLMD6lepton9Operation11AddConstant15getNumArgumentsEv26556
_ZNK4PLMD6lepton9Operation3Exp15getNumArgumentsEv29973
_ZNK4PLMD6lepton9Operation6Negate15getNumArgumentsEv32313
_ZNK4PLMD6lepton9Operation10Reciprocal5cloneEv36101
_ZNK4PLMD6lepton9Operation8Subtract15getNumArgumentsEv37035
_ZNK4PLMD6lepton9Operation10Reciprocal5getIdEv43570
_ZNK4PLMD6lepton9Operation4Step5cloneEv48060
_ZNK4PLMD6lepton9Operation4Sqrt5cloneEv50086
_ZNK4PLMD6lepton9Operation4Sqrt5getIdEv54186
_ZNK4PLMD6lepton9Operation6Square15getNumArgumentsEv60258
_ZNK4PLMD6lepton9Operation6Divide15getNumArgumentsEv61421
_ZNK4PLMD6lepton9Operation8Multiply11isSymmetricEv64917
_ZNK4PLMD6lepton9Operation3Sin5cloneEv75470
_ZNK4PLMD6lepton9Operation3Add15getNumArgumentsEv78933
_ZNK4PLMD6lepton9Operation3Sin5getIdEv87302
_ZNK4PLMD6lepton9Operation16MultiplyConstant15getNumArgumentsEv90963
_ZNK4PLMD6lepton9Operation8Variable7getNameB5cxx11Ev97282
_ZNK4PLMD6lepton9Operation15isInfixOperatorEv98008
_ZNK4PLMD6lepton9Operation8Variable15getNumArgumentsEv99060
_ZNK4PLMD6lepton9Operation3Cos5getIdEv113672
_ZNK4PLMD6lepton9Operation3Cos5cloneEv114441
_ZNK4PLMD6lepton9Operation8Multiply15getNumArgumentsEv125102
_ZNK4PLMD6lepton9Operation5Delta5getIdEv126045
_ZNK4PLMD6lepton9Operation4Step5getIdEv163299
_ZNK4PLMD6lepton9Operation3Log5cloneEv180781
_ZNK4PLMD6lepton9Operation3Log5getIdEv196275
_ZNK4PLMD6lepton9Operation8Constant5getIdEv234190
_ZNK4PLMD6lepton9Operation6Divide5cloneEv240435
_ZNK4PLMD6lepton9Operation6Negate5getIdEv341834
_ZNK4PLMD6lepton9Operation3Exp5cloneEv354615
_ZNK4PLMD6lepton9Operation11AddConstant5getIdEv419615
_ZNK4PLMD6lepton9Operation6Negate5cloneEv446847
_ZNK4PLMD6lepton9Operation3Add11isSymmetricEv505324
_ZNK4PLMD6lepton9Operation8Variable5getIdEv507201
_ZNK4PLMD6lepton9Operation5Power5cloneEv560226
_ZNK4PLMD6lepton9Operation6Divide5getIdEv706365
_ZNK4PLMD6lepton9Operation11AddConstant5cloneEv790083
_ZNK4PLMD6lepton9Operation8Subtract5cloneEv823687
_ZNK4PLMD6lepton9Operation6Square5cloneEv840634
_ZNK4PLMD6lepton9Operation8VariableneERKS1_894592
_ZNK4PLMD6lepton9Operation16MultiplyConstant5cloneEv930349
_ZNK4PLMD6lepton9Operation16MultiplyConstant5getIdEv941021
_ZNK4PLMD6lepton9Operation11AddConstantneERKS1_982730
_ZNK4PLMD6lepton9Operation11isSymmetricEv1025540
_ZNK4PLMD6lepton9Operation3Exp5getIdEv1165561
_ZNK4PLMD6lepton9Operation3Add5cloneEv1369320
_ZNK4PLMD6lepton9Operation8ConstantneERKS1_1376663
_ZNK4PLMD6lepton9Operation8Multiply5cloneEv1556652
_ZNK4PLMD6lepton9Operation5Power5getIdEv1589945
_ZNK4PLMD6lepton9Operation8Subtract5getIdEv1760229
_ZNK4PLMD6lepton9Operation16MultiplyConstantneERKS1_2020749
_ZNK4PLMD6lepton9Operation8Constant8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE2039226
_ZNK4PLMD6lepton9Operation6Square5getIdEv2041465
_ZNK4PLMD6lepton9Operation8Constant15getNumArgumentsEv2158022
_ZNK4PLMD6lepton9Operation8Variable5cloneEv3187608
_ZNK4PLMD6lepton9Operation8Multiply5getIdEv4227499
_ZNK4PLMD6lepton9Operation3Add5getIdEv4691333
_ZNK4PLMD6lepton9Operation8Constant5cloneEv4812756
_ZNK4PLMD6lepton9OperationeqERKS1_8266347
_ZNK4PLMD6lepton9OperationneERKS1_8514010
_ZNK4PLMD6lepton9Operation13PowerConstant8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE11045323
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lepton/Operation.h.func.html b/coverage-libs/lepton/Operation.h.func.html new file mode 100644 index 000000000000..ce7178ff629b --- /dev/null +++ b/coverage-libs/lepton/Operation.h.func.html @@ -0,0 +1,1233 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - lepton/Operation.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - Operation.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:53055695.3 %
Date:2024-04-19 12:12:36Functions:28029096.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6lepton9Operation6CustomC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPNS0_14CustomFunctionE0
_ZN4PLMD6lepton9Operation6CustomC2ERKS2_i0
_ZN4PLMD6lepton9Operation6CustomD0Ev0
_ZN4PLMD6lepton9Operation6CustomD2Ev0
_ZNK4PLMD6lepton9Operation10Reciprocal15getNumArgumentsEv10835
_ZNK4PLMD6lepton9Operation10Reciprocal5cloneEv36101
_ZNK4PLMD6lepton9Operation10Reciprocal5getIdEv43570
_ZNK4PLMD6lepton9Operation10Reciprocal7getNameB5cxx11Ev735
_ZNK4PLMD6lepton9Operation10Reciprocal8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE2122
_ZNK4PLMD6lepton9Operation11AddConstant15getNumArgumentsEv26556
_ZNK4PLMD6lepton9Operation11AddConstant5cloneEv790083
_ZNK4PLMD6lepton9Operation11AddConstant5getIdEv419615
_ZNK4PLMD6lepton9Operation11AddConstant7getNameB5cxx11Ev4396
_ZNK4PLMD6lepton9Operation11AddConstant8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE2886
_ZNK4PLMD6lepton9Operation11AddConstantneERKS1_982730
_ZNK4PLMD6lepton9Operation11isSymmetricEv1025540
_ZNK4PLMD6lepton9Operation13PowerConstant15getNumArgumentsEv748
_ZNK4PLMD6lepton9Operation13PowerConstant15isInfixOperatorEv136
_ZNK4PLMD6lepton9Operation13PowerConstant5cloneEv3942
_ZNK4PLMD6lepton9Operation13PowerConstant5getIdEv3962
_ZNK4PLMD6lepton9Operation13PowerConstant7getNameB5cxx11Ev68
_ZNK4PLMD6lepton9Operation13PowerConstant8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE11045323
_ZNK4PLMD6lepton9Operation13PowerConstantneERKS1_1263
_ZNK4PLMD6lepton9Operation15isInfixOperatorEv98008
_ZNK4PLMD6lepton9Operation16MultiplyConstant15getNumArgumentsEv90963
_ZNK4PLMD6lepton9Operation16MultiplyConstant5cloneEv930349
_ZNK4PLMD6lepton9Operation16MultiplyConstant5getIdEv941021
_ZNK4PLMD6lepton9Operation16MultiplyConstant7getNameB5cxx11Ev8267
_ZNK4PLMD6lepton9Operation16MultiplyConstant8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE2634
_ZNK4PLMD6lepton9Operation16MultiplyConstantneERKS1_2020749
_ZNK4PLMD6lepton9Operation3Abs15getNumArgumentsEv200
_ZNK4PLMD6lepton9Operation3Abs5cloneEv1152
_ZNK4PLMD6lepton9Operation3Abs5getIdEv1092
_ZNK4PLMD6lepton9Operation3Abs7getNameB5cxx11Ev18
_ZNK4PLMD6lepton9Operation3Abs8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE507
_ZNK4PLMD6lepton9Operation3Add11isSymmetricEv505324
_ZNK4PLMD6lepton9Operation3Add15getNumArgumentsEv78933
_ZNK4PLMD6lepton9Operation3Add15isInfixOperatorEv6109
_ZNK4PLMD6lepton9Operation3Add5cloneEv1369320
_ZNK4PLMD6lepton9Operation3Add5getIdEv4691333
_ZNK4PLMD6lepton9Operation3Add7getNameB5cxx11Ev6109
_ZNK4PLMD6lepton9Operation3Add8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE424
_ZNK4PLMD6lepton9Operation3Cos15getNumArgumentsEv9974
_ZNK4PLMD6lepton9Operation3Cos5cloneEv114441
_ZNK4PLMD6lepton9Operation3Cos5getIdEv113672
_ZNK4PLMD6lepton9Operation3Cos7getNameB5cxx11Ev1257
_ZNK4PLMD6lepton9Operation3Cos8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE205
_ZNK4PLMD6lepton9Operation3Cot15getNumArgumentsEv52
_ZNK4PLMD6lepton9Operation3Cot5cloneEv190
_ZNK4PLMD6lepton9Operation3Cot5getIdEv236
_ZNK4PLMD6lepton9Operation3Cot7getNameB5cxx11Ev4
_ZNK4PLMD6lepton9Operation3Cot8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE406
_ZNK4PLMD6lepton9Operation3Csc15getNumArgumentsEv78
_ZNK4PLMD6lepton9Operation3Csc5cloneEv336
_ZNK4PLMD6lepton9Operation3Csc5getIdEv362
_ZNK4PLMD6lepton9Operation3Csc7getNameB5cxx11Ev6
_ZNK4PLMD6lepton9Operation3Csc8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE608
_ZNK4PLMD6lepton9Operation3Erf15getNumArgumentsEv26
_ZNK4PLMD6lepton9Operation3Erf5cloneEv46
_ZNK4PLMD6lepton9Operation3Erf5getIdEv68
_ZNK4PLMD6lepton9Operation3Erf7getNameB5cxx11Ev2
_ZNK4PLMD6lepton9Operation3Exp15getNumArgumentsEv29973
_ZNK4PLMD6lepton9Operation3Exp5cloneEv354615
_ZNK4PLMD6lepton9Operation3Exp5getIdEv1165561
_ZNK4PLMD6lepton9Operation3Exp7getNameB5cxx11Ev2230
_ZNK4PLMD6lepton9Operation3Exp8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE406
_ZNK4PLMD6lepton9Operation3Log15getNumArgumentsEv11843
_ZNK4PLMD6lepton9Operation3Log5cloneEv180781
_ZNK4PLMD6lepton9Operation3Log5getIdEv196275
_ZNK4PLMD6lepton9Operation3Log7getNameB5cxx11Ev370
_ZNK4PLMD6lepton9Operation3Log8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE109
_ZNK4PLMD6lepton9Operation3Max15getNumArgumentsEv68
_ZNK4PLMD6lepton9Operation3Max5cloneEv92
_ZNK4PLMD6lepton9Operation3Max5getIdEv136
_ZNK4PLMD6lepton9Operation3Max7getNameB5cxx11Ev4
_ZNK4PLMD6lepton9Operation3Max8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE408
_ZNK4PLMD6lepton9Operation3Min15getNumArgumentsEv68
_ZNK4PLMD6lepton9Operation3Min5cloneEv92
_ZNK4PLMD6lepton9Operation3Min5getIdEv136
_ZNK4PLMD6lepton9Operation3Min7getNameB5cxx11Ev4
_ZNK4PLMD6lepton9Operation3Min8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE408
_ZNK4PLMD6lepton9Operation3Sec15getNumArgumentsEv78
_ZNK4PLMD6lepton9Operation3Sec5cloneEv256
_ZNK4PLMD6lepton9Operation3Sec5getIdEv340
_ZNK4PLMD6lepton9Operation3Sec7getNameB5cxx11Ev6
_ZNK4PLMD6lepton9Operation3Sec8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE608
_ZNK4PLMD6lepton9Operation3Sin15getNumArgumentsEv6254
_ZNK4PLMD6lepton9Operation3Sin5cloneEv75470
_ZNK4PLMD6lepton9Operation3Sin5getIdEv87302
_ZNK4PLMD6lepton9Operation3Sin7getNameB5cxx11Ev844
_ZNK4PLMD6lepton9Operation3Sin8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE207
_ZNK4PLMD6lepton9Operation3Tan15getNumArgumentsEv52
_ZNK4PLMD6lepton9Operation3Tan5cloneEv146
_ZNK4PLMD6lepton9Operation3Tan5getIdEv224
_ZNK4PLMD6lepton9Operation3Tan7getNameB5cxx11Ev4
_ZNK4PLMD6lepton9Operation3Tan8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE203
_ZNK4PLMD6lepton9Operation4Acos15getNumArgumentsEv105
_ZNK4PLMD6lepton9Operation4Acos5cloneEv167
_ZNK4PLMD6lepton9Operation4Acos5getIdEv324
_ZNK4PLMD6lepton9Operation4Acos7getNameB5cxx11Ev7
_ZNK4PLMD6lepton9Operation4Acos8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE102
_ZNK4PLMD6lepton9Operation4Acot15getNumArgumentsEv26
_ZNK4PLMD6lepton9Operation4Acot5cloneEv46
_ZNK4PLMD6lepton9Operation4Acot5getIdEv68
_ZNK4PLMD6lepton9Operation4Acot7getNameB5cxx11Ev2
_ZNK4PLMD6lepton9Operation4Acot8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE204
_ZNK4PLMD6lepton9Operation4Acsc15getNumArgumentsEv26
_ZNK4PLMD6lepton9Operation4Acsc5cloneEv46
_ZNK4PLMD6lepton9Operation4Acsc5getIdEv68
_ZNK4PLMD6lepton9Operation4Acsc7getNameB5cxx11Ev2
_ZNK4PLMD6lepton9Operation4Acsc8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE204
_ZNK4PLMD6lepton9Operation4Asec15getNumArgumentsEv26
_ZNK4PLMD6lepton9Operation4Asec5cloneEv46
_ZNK4PLMD6lepton9Operation4Asec5getIdEv68
_ZNK4PLMD6lepton9Operation4Asec7getNameB5cxx11Ev2
_ZNK4PLMD6lepton9Operation4Asec8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE204
_ZNK4PLMD6lepton9Operation4Asin15getNumArgumentsEv28
_ZNK4PLMD6lepton9Operation4Asin5cloneEv50
_ZNK4PLMD6lepton9Operation4Asin5getIdEv74
_ZNK4PLMD6lepton9Operation4Asin7getNameB5cxx11Ev2
_ZNK4PLMD6lepton9Operation4Asin8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE102
_ZNK4PLMD6lepton9Operation4Atan15getNumArgumentsEv28
_ZNK4PLMD6lepton9Operation4Atan5cloneEv50
_ZNK4PLMD6lepton9Operation4Atan5getIdEv74
_ZNK4PLMD6lepton9Operation4Atan7getNameB5cxx11Ev2
_ZNK4PLMD6lepton9Operation4Atan8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE102
_ZNK4PLMD6lepton9Operation4Ceil15getNumArgumentsEv26
_ZNK4PLMD6lepton9Operation4Ceil5cloneEv46
_ZNK4PLMD6lepton9Operation4Ceil5getIdEv68
_ZNK4PLMD6lepton9Operation4Ceil7getNameB5cxx11Ev2
_ZNK4PLMD6lepton9Operation4Ceil8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE102
_ZNK4PLMD6lepton9Operation4Cosh15getNumArgumentsEv52
_ZNK4PLMD6lepton9Operation4Cosh5cloneEv110
_ZNK4PLMD6lepton9Operation4Cosh5getIdEv144
_ZNK4PLMD6lepton9Operation4Cosh7getNameB5cxx11Ev4
_ZNK4PLMD6lepton9Operation4Cosh8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE203
_ZNK4PLMD6lepton9Operation4Coth15getNumArgumentsEv78
_ZNK4PLMD6lepton9Operation4Coth5cloneEv340
_ZNK4PLMD6lepton9Operation4Coth5getIdEv370
_ZNK4PLMD6lepton9Operation4Coth7getNameB5cxx11Ev6
_ZNK4PLMD6lepton9Operation4Coth8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE608
_ZNK4PLMD6lepton9Operation4Csch15getNumArgumentsEv52
_ZNK4PLMD6lepton9Operation4Csch5cloneEv190
_ZNK4PLMD6lepton9Operation4Csch5getIdEv236
_ZNK4PLMD6lepton9Operation4Csch7getNameB5cxx11Ev4
_ZNK4PLMD6lepton9Operation4Csch8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE406
_ZNK4PLMD6lepton9Operation4Cube15getNumArgumentsEv676
_ZNK4PLMD6lepton9Operation4Cube5cloneEv2804
_ZNK4PLMD6lepton9Operation4Cube5getIdEv5073
_ZNK4PLMD6lepton9Operation4Cube7getNameB5cxx11Ev50
_ZNK4PLMD6lepton9Operation4Cube8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE204
_ZNK4PLMD6lepton9Operation4Erfc15getNumArgumentsEv26
_ZNK4PLMD6lepton9Operation4Erfc5cloneEv46
_ZNK4PLMD6lepton9Operation4Erfc5getIdEv68
_ZNK4PLMD6lepton9Operation4Erfc7getNameB5cxx11Ev2
_ZNK4PLMD6lepton9Operation4Sech15getNumArgumentsEv52
_ZNK4PLMD6lepton9Operation4Sech5cloneEv190
_ZNK4PLMD6lepton9Operation4Sech5getIdEv236
_ZNK4PLMD6lepton9Operation4Sech7getNameB5cxx11Ev4
_ZNK4PLMD6lepton9Operation4Sech8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE406
_ZNK4PLMD6lepton9Operation4Sinh15getNumArgumentsEv52
_ZNK4PLMD6lepton9Operation4Sinh5cloneEv110
_ZNK4PLMD6lepton9Operation4Sinh5getIdEv144
_ZNK4PLMD6lepton9Operation4Sinh7getNameB5cxx11Ev4
_ZNK4PLMD6lepton9Operation4Sinh8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE203
_ZNK4PLMD6lepton9Operation4Sqrt15getNumArgumentsEv10658
_ZNK4PLMD6lepton9Operation4Sqrt5cloneEv50086
_ZNK4PLMD6lepton9Operation4Sqrt5getIdEv54186
_ZNK4PLMD6lepton9Operation4Sqrt7getNameB5cxx11Ev730
_ZNK4PLMD6lepton9Operation4Sqrt8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE1116
_ZNK4PLMD6lepton9Operation4Step15getNumArgumentsEv5084
_ZNK4PLMD6lepton9Operation4Step5cloneEv48060
_ZNK4PLMD6lepton9Operation4Step5getIdEv163299
_ZNK4PLMD6lepton9Operation4Step7getNameB5cxx11Ev431
_ZNK4PLMD6lepton9Operation4Step8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE607
_ZNK4PLMD6lepton9Operation4Tanh15getNumArgumentsEv251
_ZNK4PLMD6lepton9Operation4Tanh5cloneEv2237
_ZNK4PLMD6lepton9Operation4Tanh5getIdEv1793
_ZNK4PLMD6lepton9Operation4Tanh7getNameB5cxx11Ev13
_ZNK4PLMD6lepton9Operation4Tanh8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE304
_ZNK4PLMD6lepton9Operation5Acosh15getNumArgumentsEv26
_ZNK4PLMD6lepton9Operation5Acosh5cloneEv46
_ZNK4PLMD6lepton9Operation5Acosh5getIdEv68
_ZNK4PLMD6lepton9Operation5Acosh7getNameB5cxx11Ev2
_ZNK4PLMD6lepton9Operation5Acosh8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE102
_ZNK4PLMD6lepton9Operation5Acoth15getNumArgumentsEv26
_ZNK4PLMD6lepton9Operation5Acoth5cloneEv46
_ZNK4PLMD6lepton9Operation5Acoth5getIdEv68
_ZNK4PLMD6lepton9Operation5Acoth7getNameB5cxx11Ev2
_ZNK4PLMD6lepton9Operation5Acoth8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE204
_ZNK4PLMD6lepton9Operation5Acsch15getNumArgumentsEv26
_ZNK4PLMD6lepton9Operation5Acsch5cloneEv46
_ZNK4PLMD6lepton9Operation5Acsch5getIdEv68
_ZNK4PLMD6lepton9Operation5Acsch7getNameB5cxx11Ev2
_ZNK4PLMD6lepton9Operation5Acsch8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE204
_ZNK4PLMD6lepton9Operation5Asech15getNumArgumentsEv26
_ZNK4PLMD6lepton9Operation5Asech5cloneEv46
_ZNK4PLMD6lepton9Operation5Asech5getIdEv68
_ZNK4PLMD6lepton9Operation5Asech7getNameB5cxx11Ev2
_ZNK4PLMD6lepton9Operation5Asech8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE204
_ZNK4PLMD6lepton9Operation5Asinh15getNumArgumentsEv26
_ZNK4PLMD6lepton9Operation5Asinh5cloneEv46
_ZNK4PLMD6lepton9Operation5Asinh5getIdEv68
_ZNK4PLMD6lepton9Operation5Asinh7getNameB5cxx11Ev2
_ZNK4PLMD6lepton9Operation5Asinh8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE102
_ZNK4PLMD6lepton9Operation5Atan215getNumArgumentsEv633
_ZNK4PLMD6lepton9Operation5Atan25cloneEv1270
_ZNK4PLMD6lepton9Operation5Atan25getIdEv1878
_ZNK4PLMD6lepton9Operation5Atan27getNameB5cxx11Ev30
_ZNK4PLMD6lepton9Operation5Atan28evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE408
_ZNK4PLMD6lepton9Operation5Atanh15getNumArgumentsEv26
_ZNK4PLMD6lepton9Operation5Atanh5cloneEv46
_ZNK4PLMD6lepton9Operation5Atanh5getIdEv68
_ZNK4PLMD6lepton9Operation5Atanh7getNameB5cxx11Ev2
_ZNK4PLMD6lepton9Operation5Atanh8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE102
_ZNK4PLMD6lepton9Operation5Delta15getNumArgumentsEv3899
_ZNK4PLMD6lepton9Operation5Delta5cloneEv25363
_ZNK4PLMD6lepton9Operation5Delta5getIdEv126045
_ZNK4PLMD6lepton9Operation5Delta7getNameB5cxx11Ev248
_ZNK4PLMD6lepton9Operation5Delta8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE203
_ZNK4PLMD6lepton9Operation5Floor15getNumArgumentsEv26
_ZNK4PLMD6lepton9Operation5Floor5cloneEv46
_ZNK4PLMD6lepton9Operation5Floor5getIdEv68
_ZNK4PLMD6lepton9Operation5Floor7getNameB5cxx11Ev2
_ZNK4PLMD6lepton9Operation5Floor8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE102
_ZNK4PLMD6lepton9Operation5Power15getNumArgumentsEv17607
_ZNK4PLMD6lepton9Operation5Power15isInfixOperatorEv4
_ZNK4PLMD6lepton9Operation5Power5cloneEv560226
_ZNK4PLMD6lepton9Operation5Power5getIdEv1589945
_ZNK4PLMD6lepton9Operation5Power7getNameB5cxx11Ev4
_ZNK4PLMD6lepton9Operation5Power8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE205
_ZNK4PLMD6lepton9Operation6Custom15getNumArgumentsEv0
_ZNK4PLMD6lepton9Operation6Custom5cloneEv0
_ZNK4PLMD6lepton9Operation6Custom5getIdEv0
_ZNK4PLMD6lepton9Operation6Custom7getNameB5cxx11Ev0
_ZNK4PLMD6lepton9Operation6Custom8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE0
_ZNK4PLMD6lepton9Operation6CustomneERKS1_0
_ZNK4PLMD6lepton9Operation6Divide15getNumArgumentsEv61421
_ZNK4PLMD6lepton9Operation6Divide15isInfixOperatorEv2979
_ZNK4PLMD6lepton9Operation6Divide5cloneEv240435
_ZNK4PLMD6lepton9Operation6Divide5getIdEv706365
_ZNK4PLMD6lepton9Operation6Divide7getNameB5cxx11Ev2979
_ZNK4PLMD6lepton9Operation6Divide8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE805
_ZNK4PLMD6lepton9Operation6Negate15getNumArgumentsEv32313
_ZNK4PLMD6lepton9Operation6Negate5cloneEv446847
_ZNK4PLMD6lepton9Operation6Negate5getIdEv341834
_ZNK4PLMD6lepton9Operation6Negate7getNameB5cxx11Ev769
_ZNK4PLMD6lepton9Operation6Negate8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE2809
_ZNK4PLMD6lepton9Operation6Select15getNumArgumentsEv424
_ZNK4PLMD6lepton9Operation6Select5cloneEv592
_ZNK4PLMD6lepton9Operation6Select5getIdEv852
_ZNK4PLMD6lepton9Operation6Select7getNameB5cxx11Ev24
_ZNK4PLMD6lepton9Operation6Select8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE2444
_ZNK4PLMD6lepton9Operation6Square15getNumArgumentsEv60258
_ZNK4PLMD6lepton9Operation6Square5cloneEv840634
_ZNK4PLMD6lepton9Operation6Square5getIdEv2041465
_ZNK4PLMD6lepton9Operation6Square7getNameB5cxx11Ev6511
_ZNK4PLMD6lepton9Operation6Square8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE3707
_ZNK4PLMD6lepton9Operation8Constant15getNumArgumentsEv2158022
_ZNK4PLMD6lepton9Operation8Constant5cloneEv4812756
_ZNK4PLMD6lepton9Operation8Constant5getIdEv234190
_ZNK4PLMD6lepton9Operation8Constant7getNameB5cxx11Ev1305
_ZNK4PLMD6lepton9Operation8Constant8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE2039226
_ZNK4PLMD6lepton9Operation8ConstantneERKS1_1376663
_ZNK4PLMD6lepton9Operation8Multiply11isSymmetricEv64917
_ZNK4PLMD6lepton9Operation8Multiply15getNumArgumentsEv125102
_ZNK4PLMD6lepton9Operation8Multiply15isInfixOperatorEv3290
_ZNK4PLMD6lepton9Operation8Multiply5cloneEv1556652
_ZNK4PLMD6lepton9Operation8Multiply5getIdEv4227499
_ZNK4PLMD6lepton9Operation8Multiply7getNameB5cxx11Ev3290
_ZNK4PLMD6lepton9Operation8Multiply8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE3436
_ZNK4PLMD6lepton9Operation8Nandelta15getNumArgumentsEv74
_ZNK4PLMD6lepton9Operation8Nandelta5cloneEv138
_ZNK4PLMD6lepton9Operation8Nandelta5getIdEv204
_ZNK4PLMD6lepton9Operation8Nandelta7getNameB5cxx11Ev6
_ZNK4PLMD6lepton9Operation8Nandelta8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE304
_ZNK4PLMD6lepton9Operation8Subtract15getNumArgumentsEv37035
_ZNK4PLMD6lepton9Operation8Subtract15isInfixOperatorEv1359
_ZNK4PLMD6lepton9Operation8Subtract5cloneEv823687
_ZNK4PLMD6lepton9Operation8Subtract5getIdEv1760229
_ZNK4PLMD6lepton9Operation8Subtract7getNameB5cxx11Ev1359
_ZNK4PLMD6lepton9Operation8Subtract8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE1324
_ZNK4PLMD6lepton9Operation8Variable15getNumArgumentsEv99060
_ZNK4PLMD6lepton9Operation8Variable5cloneEv3187608
_ZNK4PLMD6lepton9Operation8Variable5getIdEv507201
_ZNK4PLMD6lepton9Operation8Variable7getNameB5cxx11Ev97282
_ZNK4PLMD6lepton9Operation8Variable8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE30
_ZNK4PLMD6lepton9Operation8VariableneERKS1_894592
_ZNK4PLMD6lepton9OperationeqERKS1_8266347
_ZNK4PLMD6lepton9OperationneERKS1_8514010
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lepton/Operation.h.gcov.html b/coverage-libs/lepton/Operation.h.gcov.html new file mode 100644 index 000000000000..30bba7026ae7 --- /dev/null +++ b/coverage-libs/lepton/Operation.h.gcov.html @@ -0,0 +1,1379 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - lepton/Operation.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - Operation.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:53055695.3 %
Date:2024-04-19 12:12:36Functions: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       98008 :     virtual bool isInfixOperator() const {
+     139       98008 :         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     1025540 :     virtual bool isSymmetric() const {
+     146     1025540 :         return false;
+     147             :     }
+     148     8514010 :     virtual bool operator!=(const Operation& op) const {
+     149     8514010 :         return op.getId() != getId();
+     150             :     }
+     151     8266347 :     virtual bool operator==(const Operation& op) const {
+     152     8266347 :         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     2069856 :     Constant(double value) : value(value) {
+     213             :     }
+     214        1305 :     std::string getName() const {
+     215        1305 :         std::stringstream name;
+     216        1305 :         name << value;
+     217        1305 :         return name.str();
+     218        1305 :     }
+     219      234190 :     Id getId() const {
+     220      234190 :         return CONSTANT;
+     221             :     }
+     222     2158022 :     int getNumArguments() const {
+     223     2158022 :         return 0;
+     224             :     }
+     225     4812756 :     Operation* clone() const {
+     226     4812756 :         return new Constant(value);
+     227             :     }
+     228     2039226 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+     229     2039226 :         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       57228 :         return value;
+     234             :     }
+     235     1376663 :     bool operator!=(const Operation& op) const {
+     236     1376663 :         const Constant* o = dynamic_cast<const Constant*>(&op);
+     237     1376663 :         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     3208601 :     Variable(const std::string& name) : name(name) {
+     246     3208601 :     }
+     247       97282 :     std::string getName() const {
+     248       97282 :         return name;
+     249             :     }
+     250      507201 :     Id getId() const {
+     251      507201 :         return VARIABLE;
+     252             :     }
+     253       99060 :     int getNumArguments() const {
+     254       99060 :         return 0;
+     255             :     }
+     256     3187608 :     Operation* clone() const {
+     257     6375216 :         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      894592 :     bool operator!=(const Operation& op) const {
+     267      894592 :         const Variable* o = dynamic_cast<const Variable*>(&op);
+     268      894592 :         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        9139 :     Add() {
+     327             :     }
+     328        6109 :     std::string getName() const {
+     329        6109 :         return "+";
+     330             :     }
+     331     4691333 :     Id getId() const {
+     332     4691333 :         return ADD;
+     333             :     }
+     334       78933 :     int getNumArguments() const {
+     335       78933 :         return 2;
+     336             :     }
+     337     1369320 :     Operation* clone() const {
+     338     1369320 :         return new Add();
+     339             :     }
+     340         424 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+     341         424 :         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        6109 :     bool isInfixOperator() const {
+     345        6109 :         return true;
+     346             :     }
+     347      505324 :     bool isSymmetric() const {
+     348      505324 :         return true;
+     349             :     }
+     350             : };
+     351             : 
+     352             : class LEPTON_EXPORT Operation::Subtract : public Operation {
+     353             : public:
+     354        4750 :     Subtract() {
+     355             :     }
+     356        1359 :     std::string getName() const {
+     357        1359 :         return "-";
+     358             :     }
+     359     1760229 :     Id getId() const {
+     360     1760229 :         return SUBTRACT;
+     361             :     }
+     362       37035 :     int getNumArguments() const {
+     363       37035 :         return 2;
+     364             :     }
+     365      823687 :     Operation* clone() const {
+     366      823687 :         return new Subtract();
+     367             :     }
+     368        1324 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+     369        1324 :         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        1359 :     bool isInfixOperator() const {
+     373        1359 :         return true;
+     374             :     }
+     375             : };
+     376             : 
+     377             : class LEPTON_EXPORT Operation::Multiply : public Operation {
+     378             : public:
+     379       27246 :     Multiply() {
+     380             :     }
+     381        3290 :     std::string getName() const {
+     382        3290 :         return "*";
+     383             :     }
+     384     4227499 :     Id getId() const {
+     385     4227499 :         return MULTIPLY;
+     386             :     }
+     387      125102 :     int getNumArguments() const {
+     388      125102 :         return 2;
+     389             :     }
+     390     1556652 :     Operation* clone() const {
+     391     1556652 :         return new Multiply();
+     392             :     }
+     393        3436 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+     394        3436 :         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        3290 :     bool isInfixOperator() const {
+     398        3290 :         return true;
+     399             :     }
+     400       64917 :     bool isSymmetric() const {
+     401       64917 :         return true;
+     402             :     }
+     403             : };
+     404             : 
+     405             : class LEPTON_EXPORT Operation::Divide : public Operation {
+     406             : public:
+     407        8764 :     Divide() {
+     408             :     }
+     409        2979 :     std::string getName() const {
+     410        2979 :         return "/";
+     411             :     }
+     412      706365 :     Id getId() const {
+     413      706365 :         return DIVIDE;
+     414             :     }
+     415       61421 :     int getNumArguments() const {
+     416       61421 :         return 2;
+     417             :     }
+     418      240435 :     Operation* clone() const {
+     419      240435 :         return new Divide();
+     420             :     }
+     421         805 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+     422         805 :         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        2979 :     bool isInfixOperator() const {
+     426        2979 :         return true;
+     427             :     }
+     428             : };
+     429             : 
+     430             : class LEPTON_EXPORT Operation::Power : public Operation {
+     431             : public:
+     432        5560 :     Power() {
+     433             :     }
+     434           4 :     std::string getName() const {
+     435           4 :         return "^";
+     436             :     }
+     437     1589945 :     Id getId() const {
+     438     1589945 :         return POWER;
+     439             :     }
+     440       17607 :     int getNumArguments() const {
+     441       17607 :         return 2;
+     442             :     }
+     443      560226 :     Operation* clone() const {
+     444      560226 :         return new Power();
+     445             :     }
+     446         205 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+     447         205 :         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        6049 :     Negate() {
+     458             :     }
+     459         769 :     std::string getName() const {
+     460         769 :         return "-";
+     461             :     }
+     462      341834 :     Id getId() const {
+     463      341834 :         return NEGATE;
+     464             :     }
+     465       32313 :     int getNumArguments() const {
+     466       32313 :         return 1;
+     467             :     }
+     468      446847 :     Operation* clone() const {
+     469      446847 :         return new Negate();
+     470             :     }
+     471        2809 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+     472        2809 :         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        1060 :     Sqrt() {
+     480             :     }
+     481         730 :     std::string getName() const {
+     482         730 :         return "sqrt";
+     483             :     }
+     484       54186 :     Id getId() const {
+     485       54186 :         return SQRT;
+     486             :     }
+     487       10658 :     int getNumArguments() const {
+     488       10658 :         return 1;
+     489             :     }
+     490       50086 :     Operation* clone() const {
+     491       50086 :         return new Sqrt();
+     492             :     }
+     493        1116 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+     494        1116 :         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        2986 :     Exp() {
+     502             :     }
+     503        2230 :     std::string getName() const {
+     504        2230 :         return "exp";
+     505             :     }
+     506     1165561 :     Id getId() const {
+     507     1165561 :         return EXP;
+     508             :     }
+     509       29973 :     int getNumArguments() const {
+     510       29973 :         return 1;
+     511             :     }
+     512      354615 :     Operation* clone() const {
+     513      354615 :         return new Exp();
+     514             :     }
+     515         406 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+     516         406 :         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        1956 :     Log() {
+     524             :     }
+     525         370 :     std::string getName() const {
+     526         370 :         return "log";
+     527             :     }
+     528      196275 :     Id getId() const {
+     529      196275 :         return LOG;
+     530             :     }
+     531       11843 :     int getNumArguments() const {
+     532       11843 :         return 1;
+     533             :     }
+     534      180781 :     Operation* clone() const {
+     535      180781 :         return new Log();
+     536             :     }
+     537         109 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+     538         109 :         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         463 :     Sin() {
+     546             :     }
+     547         844 :     std::string getName() const {
+     548         844 :         return "sin";
+     549             :     }
+     550       87302 :     Id getId() const {
+     551       87302 :         return SIN;
+     552             :     }
+     553        6254 :     int getNumArguments() const {
+     554        6254 :         return 1;
+     555             :     }
+     556       75470 :     Operation* clone() const {
+     557       75470 :         return new Sin();
+     558             :     }
+     559         207 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+     560         207 :         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        1500 :     Cos() {
+     568             :     }
+     569        1257 :     std::string getName() const {
+     570        1257 :         return "cos";
+     571             :     }
+     572      113672 :     Id getId() const {
+     573      113672 :         return COS;
+     574             :     }
+     575        9974 :     int getNumArguments() const {
+     576        9974 :         return 1;
+     577             :     }
+     578      114441 :     Operation* clone() const {
+     579      114441 :         return new Cos();
+     580             :     }
+     581         205 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+     582         205 :         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         340 :     Id getId() const {
+     595         340 :         return SEC;
+     596             :     }
+     597          78 :     int getNumArguments() const {
+     598          78 :         return 1;
+     599             :     }
+     600         256 :     Operation* clone() const {
+     601         256 :         return new Sec();
+     602             :     }
+     603         608 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+     604         608 :         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         362 :     Id getId() const {
+     617         362 :         return CSC;
+     618             :     }
+     619          78 :     int getNumArguments() const {
+     620          78 :         return 1;
+     621             :     }
+     622         336 :     Operation* clone() const {
+     623         336 :         return new Csc();
+     624             :     }
+     625         608 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+     626         608 :         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         224 :     Id getId() const {
+     639         224 :         return TAN;
+     640             :     }
+     641          52 :     int getNumArguments() const {
+     642          52 :         return 1;
+     643             :     }
+     644         146 :     Operation* clone() const {
+     645         146 :         return new Tan();
+     646             :     }
+     647         203 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+     648         203 :         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         236 :     Id getId() const {
+     661         236 :         return COT;
+     662             :     }
+     663          52 :     int getNumArguments() const {
+     664          52 :         return 1;
+     665             :     }
+     666         190 :     Operation* clone() const {
+     667         190 :         return new Cot();
+     668             :     }
+     669         406 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+     670         406 :         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          54 :     Asin() {
+     678             :     }
+     679           2 :     std::string getName() const {
+     680           2 :         return "asin";
+     681             :     }
+     682          74 :     Id getId() const {
+     683          74 :         return ASIN;
+     684             :     }
+     685          28 :     int getNumArguments() const {
+     686          28 :         return 1;
+     687             :     }
+     688          50 :     Operation* clone() const {
+     689          50 :         return new Asin();
+     690             :     }
+     691         102 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+     692         102 :         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         183 :     Acos() {
+     700             :     }
+     701           7 :     std::string getName() const {
+     702           7 :         return "acos";
+     703             :     }
+     704         324 :     Id getId() const {
+     705         324 :         return ACOS;
+     706             :     }
+     707         105 :     int getNumArguments() const {
+     708         105 :         return 1;
+     709             :     }
+     710         167 :     Operation* clone() const {
+     711         167 :         return new Acos();
+     712             :     }
+     713         102 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+     714         102 :         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          54 :     Atan() {
+     722             :     }
+     723           2 :     std::string getName() const {
+     724           2 :         return "atan";
+     725             :     }
+     726          74 :     Id getId() const {
+     727          74 :         return ATAN;
+     728             :     }
+     729          28 :     int getNumArguments() const {
+     730          28 :         return 1;
+     731             :     }
+     732          50 :     Operation* clone() const {
+     733          50 :         return new Atan();
+     734             :     }
+     735         102 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+     736         102 :         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        1353 :     Atan2() {
+     744             :     }
+     745          30 :     std::string getName() const {
+     746          30 :         return "atan2";
+     747             :     }
+     748        1878 :     Id getId() const {
+     749        1878 :         return ATAN2;
+     750             :     }
+     751         633 :     int getNumArguments() const {
+     752         633 :         return 2;
+     753             :     }
+     754        1270 :     Operation* clone() const {
+     755        1270 :         return new Atan2();
+     756             :     }
+     757         408 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+     758         408 :         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         144 :     Id getId() const {
+     771         144 :         return SINH;
+     772             :     }
+     773          52 :     int getNumArguments() const {
+     774          52 :         return 1;
+     775             :     }
+     776         110 :     Operation* clone() const {
+     777         110 :         return new Sinh();
+     778             :     }
+     779         203 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+     780         203 :         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         144 :     Id getId() const {
+     793         144 :         return COSH;
+     794             :     }
+     795          52 :     int getNumArguments() const {
+     796          52 :         return 1;
+     797             :     }
+     798         110 :     Operation* clone() const {
+     799         110 :         return new Cosh();
+     800             :     }
+     801         203 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+     802         203 :         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          23 :     Tanh() {
+     810             :     }
+     811          13 :     std::string getName() const {
+     812          13 :         return "tanh";
+     813             :     }
+     814        1793 :     Id getId() const {
+     815        1793 :         return TANH;
+     816             :     }
+     817         251 :     int getNumArguments() const {
+     818         251 :         return 1;
+     819             :     }
+     820        2237 :     Operation* clone() const {
+     821        2237 :         return new Tanh();
+     822             :     }
+     823         304 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+     824         304 :         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          50 :     Erf() {
+     832             :     }
+     833           2 :     std::string getName() const {
+     834           2 :         return "erf";
+     835             :     }
+     836          68 :     Id getId() const {
+     837          68 :         return ERF;
+     838             :     }
+     839          26 :     int getNumArguments() const {
+     840          26 :         return 1;
+     841             :     }
+     842          46 :     Operation* clone() const {
+     843          46 :         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          50 :     Erfc() {
+     852             :     }
+     853           2 :     std::string getName() const {
+     854           2 :         return "erfc";
+     855             :     }
+     856          68 :     Id getId() const {
+     857          68 :         return ERFC;
+     858             :     }
+     859          26 :     int getNumArguments() const {
+     860          26 :         return 1;
+     861             :     }
+     862          46 :     Operation* clone() const {
+     863          46 :         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         393 :     Step() {
+     872             :     }
+     873         431 :     std::string getName() const {
+     874         431 :         return "step";
+     875             :     }
+     876      163299 :     Id getId() const {
+     877      163299 :         return STEP;
+     878             :     }
+     879        5084 :     int getNumArguments() const {
+     880        5084 :         return 1;
+     881             :     }
+     882       48060 :     Operation* clone() const {
+     883       48060 :         return new Step();
+     884             :     }
+     885         607 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+     886         607 :         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         257 :     Delta() {
+     894             :     }
+     895         248 :     std::string getName() const {
+     896         248 :         return "delta";
+     897             :     }
+     898      126045 :     Id getId() const {
+     899      126045 :         return DELTA;
+     900             :     }
+     901        3899 :     int getNumArguments() const {
+     902        3899 :         return 1;
+     903             :     }
+     904       25363 :     Operation* clone() const {
+     905       25363 :         return new Delta();
+     906             :     }
+     907         203 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+     908         203 :         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         204 :     Id getId() const {
+     921         204 :         return NANDELTA;
+     922             :     }
+     923          74 :     int getNumArguments() const {
+     924          74 :         return 1;
+     925             :     }
+     926         138 :     Operation* clone() const {
+     927         138 :         return new Nandelta();
+     928             :     }
+     929         304 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+     930         304 :         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        5368 :     Square() {
+     938             :     }
+     939        6511 :     std::string getName() const {
+     940        6511 :         return "square";
+     941             :     }
+     942     2041465 :     Id getId() const {
+     943     2041465 :         return SQUARE;
+     944             :     }
+     945       60258 :     int getNumArguments() const {
+     946       60258 :         return 1;
+     947             :     }
+     948      840634 :     Operation* clone() const {
+     949      840634 :         return new Square();
+     950             :     }
+     951        3707 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+     952        3707 :         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        2948 :     Cube() {
+     960             :     }
+     961          50 :     std::string getName() const {
+     962          50 :         return "cube";
+     963             :     }
+     964        5073 :     Id getId() const {
+     965        5073 :         return CUBE;
+     966             :     }
+     967         676 :     int getNumArguments() const {
+     968         676 :         return 1;
+     969             :     }
+     970        2804 :     Operation* clone() const {
+     971        2804 :         return new Cube();
+     972             :     }
+     973         204 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+     974         204 :         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         867 :     Reciprocal() {
+     982             :     }
+     983         735 :     std::string getName() const {
+     984         735 :         return "recip";
+     985             :     }
+     986       43570 :     Id getId() const {
+     987       43570 :         return RECIPROCAL;
+     988             :     }
+     989       10835 :     int getNumArguments() const {
+     990       10835 :         return 1;
+     991             :     }
+     992       36101 :     Operation* clone() const {
+     993       36101 :         return new Reciprocal();
+     994             :     }
+     995        2122 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+     996        2122 :         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        3200 :     AddConstant(double value) : value(value) {
+    1004             :     }
+    1005        4396 :     std::string getName() const {
+    1006        4396 :         std::stringstream name;
+    1007        4396 :         name << value << "+";
+    1008        4396 :         return name.str();
+    1009        4396 :     }
+    1010      419615 :     Id getId() const {
+    1011      419615 :         return ADD_CONSTANT;
+    1012             :     }
+    1013       26556 :     int getNumArguments() const {
+    1014       26556 :         return 1;
+    1015             :     }
+    1016      790083 :     Operation* clone() const {
+    1017      790083 :         return new AddConstant(value);
+    1018             :     }
+    1019        2886 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+    1020        2886 :         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        7096 :         return value;
+    1025             :     }
+    1026      982730 :     bool operator!=(const Operation& op) const {
+    1027      982730 :         const AddConstant* o = dynamic_cast<const AddConstant*>(&op);
+    1028      982730 :         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       12275 :     MultiplyConstant(double value) : value(value) {
+    1037             :     }
+    1038        8267 :     std::string getName() const {
+    1039        8267 :         std::stringstream name;
+    1040        8267 :         name << value << "*";
+    1041        8267 :         return name.str();
+    1042        8267 :     }
+    1043      941021 :     Id getId() const {
+    1044      941021 :         return MULTIPLY_CONSTANT;
+    1045             :     }
+    1046       90963 :     int getNumArguments() const {
+    1047       90963 :         return 1;
+    1048             :     }
+    1049      930349 :     Operation* clone() const {
+    1050      930349 :         return new MultiplyConstant(value);
+    1051             :     }
+    1052        2634 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+    1053        2634 :         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       31795 :         return value;
+    1058             :     }
+    1059     2020749 :     bool operator!=(const Operation& op) const {
+    1060     2020749 :         const MultiplyConstant* o = dynamic_cast<const MultiplyConstant*>(&op);
+    1061     2020749 :         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        4055 :     PowerConstant(double value) : value(value) {
+    1070        4055 :         intValue = (int) value;
+    1071         113 :         isIntPower = (intValue == value);
+    1072             :     }
+    1073          68 :     std::string getName() const {
+    1074          68 :         std::stringstream name;
+    1075          68 :         name << "^" << value;
+    1076          68 :         return name.str();
+    1077          68 :     }
+    1078        3962 :     Id getId() const {
+    1079        3962 :         return POWER_CONSTANT;
+    1080             :     }
+    1081         748 :     int getNumArguments() const {
+    1082         748 :         return 1;
+    1083             :     }
+    1084        3942 :     Operation* clone() const {
+    1085        3942 :         return new PowerConstant(value);
+    1086             :     }
+    1087    11045323 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+    1088    11045323 :         if (isIntPower) {
+    1089             :             // Integer powers can be computed much more quickly by repeated multiplication.
+    1090             :             
+    1091    11041104 :             int exponent = intValue;
+    1092    11041104 :             double base = args[0];
+    1093    11041104 :             if (exponent < 0) {
+    1094         804 :                 exponent = -exponent;
+    1095         804 :                 base = 1.0/base;
+    1096             :             }
+    1097             :             double result = 1.0;
+    1098    44166323 :             while (exponent != 0) {
+    1099    33125219 :                 if ((exponent&1) == 1)
+    1100    23777800 :                     result *= base;
+    1101    33125219 :                 base *= base;
+    1102    33125219 :                 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        1263 :     bool operator!=(const Operation& op) const {
+    1114        1263 :         const PowerConstant* o = dynamic_cast<const PowerConstant*>(&op);
+    1115        1263 :         return (o == NULL || o->value != value);
+    1116             :     }
+    1117         136 :     bool isInfixOperator() const {
+    1118         136 :         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         100 :     Min() {
+    1129             :     }
+    1130           4 :     std::string getName() const {
+    1131           4 :         return "min";
+    1132             :     }
+    1133         136 :     Id getId() const {
+    1134         136 :         return MIN;
+    1135             :     }
+    1136          68 :     int getNumArguments() const {
+    1137          68 :         return 2;
+    1138             :     }
+    1139          92 :     Operation* clone() const {
+    1140          92 :         return new Min();
+    1141             :     }
+    1142         408 :     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         408 :         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         100 :     Max() {
+    1152             :     }
+    1153           4 :     std::string getName() const {
+    1154           4 :         return "max";
+    1155             :     }
+    1156         136 :     Id getId() const {
+    1157         136 :         return MAX;
+    1158             :     }
+    1159          68 :     int getNumArguments() const {
+    1160          68 :         return 2;
+    1161             :     }
+    1162          92 :     Operation* clone() const {
+    1163          92 :         return new Max();
+    1164             :     }
+    1165         408 :     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         408 :         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        1092 :     Id getId() const {
+    1180        1092 :         return ABS;
+    1181             :     }
+    1182         200 :     int getNumArguments() const {
+    1183         200 :         return 1;
+    1184             :     }
+    1185        1152 :     Operation* clone() const {
+    1186        1152 :         return new Abs();
+    1187             :     }
+    1188         507 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+    1189         507 :         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          50 :     Floor() {
+    1198             :     }
+    1199           2 :     std::string getName() const {
+    1200           2 :         return "floor";
+    1201             :     }
+    1202          68 :     Id getId() const {
+    1203          68 :         return FLOOR;
+    1204             :     }
+    1205          26 :     int getNumArguments() const {
+    1206          26 :         return 1;
+    1207             :     }
+    1208          46 :     Operation* clone() const {
+    1209          46 :         return new Floor();
+    1210             :     }
+    1211         102 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+    1212         102 :         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          50 :     Ceil() {
+    1220             :     }
+    1221           2 :     std::string getName() const {
+    1222           2 :         return "ceil";
+    1223             :     }
+    1224          68 :     Id getId() const {
+    1225          68 :         return CEIL;
+    1226             :     }
+    1227          26 :     int getNumArguments() const {
+    1228          26 :         return 1;
+    1229             :     }
+    1230          46 :     Operation* clone() const {
+    1231          46 :         return new Ceil();
+    1232             :     }
+    1233         102 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+    1234         102 :         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         852 :     Id getId() const {
+    1247         852 :         return SELECT;
+    1248             :     }
+    1249         424 :     int getNumArguments() const {
+    1250         424 :         return 3;
+    1251             :     }
+    1252         592 :     Operation* clone() const {
+    1253         592 :         return new Select();
+    1254             :     }
+    1255        2444 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+    1256        2444 :         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         350 : LEPTON_CLASS_OPERATION(Acot,acot,ACOT,1,std::atan(1.0/args[0]));
+    1285         350 : LEPTON_CLASS_OPERATION(Asec,asec,ASEC,1,std::acos(1.0/args[0]));
+    1286         350 : LEPTON_CLASS_OPERATION(Acsc,acsc,ACSC,1,std::asin(1.0/args[0]));
+    1287        1410 : LEPTON_CLASS_OPERATION(Coth,coth,ACOT,1,1.0/std::tanh(args[0]));
+    1288         894 : LEPTON_CLASS_OPERATION(Sech,sech,SECH,1,1.0/std::cosh(args[0]));
+    1289         894 : LEPTON_CLASS_OPERATION(Csch,csch,CSCH,1,1.0/std::sinh(args[0]));
+    1290             : 
+    1291         248 : LEPTON_CLASS_OPERATION(Asinh,asinh,ASINH,1,std::asinh(args[0]));
+    1292         248 : LEPTON_CLASS_OPERATION(Acosh,acosh,ACOSH,1,std::acosh(args[0]));
+    1293         248 : LEPTON_CLASS_OPERATION(Atanh,atanh,ATANH,1,std::atanh(args[0]));
+    1294             : 
+    1295         350 : LEPTON_CLASS_OPERATION(Acoth,acoth,ACOTH,1,0.5*std::log((args[0]+1.0)/(args[0]-1.0)));
+    1296         350 : 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         350 : LEPTON_CLASS_OPERATION(Acsch,acsch,ACSCH,1,std::log(1.0/args[0]+std::sqrt(1.0/(args[0]*args[0])+1.0)));
+    1298             : 
+    1299             : } // namespace lepton
+    1300             : } // namespace PLMD
+    1301             : 
+    1302             : #endif /*LEPTON_OPERATION_H_*/
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lepton/ParsedExpression.cpp.func-sort-c.html b/coverage-libs/lepton/ParsedExpression.cpp.func-sort-c.html new file mode 100644 index 000000000000..5c1078ab4220 --- /dev/null +++ b/coverage-libs/lepton/ParsedExpression.cpp.func-sort-c.html @@ -0,0 +1,157 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - lepton/ParsedExpression.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - ParsedExpression.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:23025789.5 %
Date:2024-04-19 12:12:36Functions: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_traitsIcESaIcEEE5040
_ZN4PLMD6leptonlsERSoRKNS0_16ParsedExpressionE8161
_ZNK4PLMD6lepton16ParsedExpression8optimizeERKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessIS8_ESaISt4pairIKS8_dEEE8199
_ZNK4PLMD6lepton16ParsedExpression24createCompiledExpressionEv16230
_ZNK4PLMD6lepton16ParsedExpression8optimizeEv16230
_ZN4PLMD6lepton16ParsedExpression16getConstantValueERKNS0_18ExpressionTreeNodeE29928
_ZN4PLMD6lepton16ParsedExpression13differentiateERKNS0_18ExpressionTreeNodeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt3mapIiS2_St4lessIiESaISt4pairIKiS2_EEE43220
_ZN4PLMD6leptonlsERSoRKNS0_18ExpressionTreeNodeE62813
_ZN4PLMD6lepton16ParsedExpression20preevaluateVariablesERKNS0_18ExpressionTreeNodeERKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISB_ESaISt4pairIKSB_dEEE178064
_ZN4PLMD6lepton16ParsedExpression34precalculateConstantSubexpressionsERKNS0_18ExpressionTreeNodeERSt3mapIiS2_St4lessIiESaISt4pairIKiS2_EEE209410
_ZN4PLMD6lepton16ParsedExpression27substituteSimplerExpressionERKNS0_18ExpressionTreeNodeERSt3mapIiS2_St4lessIiESaISt4pairIKiS2_EEE217749
_ZN4PLMD6lepton16ParsedExpression10isConstantERKNS0_18ExpressionTreeNodeE238243
_ZNK4PLMD6lepton16ParsedExpression8evaluateERKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessIS8_ESaISt4pairIKS8_dEEE2008077
_ZN4PLMD6lepton16ParsedExpression8evaluateERKNS0_18ExpressionTreeNodeERKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISB_ESaISt4pairIKSB_dEEE2036659
_ZN4PLMD6lepton16ParsedExpressionC2ERKNS0_18ExpressionTreeNodeE2045745
_ZNK4PLMD6lepton16ParsedExpression11getRootNodeEv2066977
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lepton/ParsedExpression.cpp.func.html b/coverage-libs/lepton/ParsedExpression.cpp.func.html new file mode 100644 index 000000000000..3bf996ecc44e --- /dev/null +++ b/coverage-libs/lepton/ParsedExpression.cpp.func.html @@ -0,0 +1,157 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - lepton/ParsedExpression.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - ParsedExpression.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:23025789.5 %
Date:2024-04-19 12:12:36Functions:162176.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6lepton16ParsedExpression10isConstantERKNS0_18ExpressionTreeNodeE238243
_ZN4PLMD6lepton16ParsedExpression13differentiateERKNS0_18ExpressionTreeNodeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt3mapIiS2_St4lessIiESaISt4pairIKiS2_EEE43220
_ZN4PLMD6lepton16ParsedExpression16getConstantValueERKNS0_18ExpressionTreeNodeE29928
_ZN4PLMD6lepton16ParsedExpression19renameNodeVariablesERKNS0_18ExpressionTreeNodeERKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESB_St4lessISB_ESaISt4pairIKSB_SB_EEE0
_ZN4PLMD6lepton16ParsedExpression20preevaluateVariablesERKNS0_18ExpressionTreeNodeERKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISB_ESaISt4pairIKSB_dEEE178064
_ZN4PLMD6lepton16ParsedExpression27substituteSimplerExpressionERKNS0_18ExpressionTreeNodeERSt3mapIiS2_St4lessIiESaISt4pairIKiS2_EEE217749
_ZN4PLMD6lepton16ParsedExpression34precalculateConstantSubexpressionsERKNS0_18ExpressionTreeNodeERSt3mapIiS2_St4lessIiESaISt4pairIKiS2_EEE209410
_ZN4PLMD6lepton16ParsedExpression8evaluateERKNS0_18ExpressionTreeNodeERKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISB_ESaISt4pairIKSB_dEEE2036659
_ZN4PLMD6lepton16ParsedExpressionC2ERKNS0_18ExpressionTreeNodeE2045745
_ZN4PLMD6lepton16ParsedExpressionC2Ev0
_ZN4PLMD6leptonlsERSoRKNS0_16ParsedExpressionE8161
_ZN4PLMD6leptonlsERSoRKNS0_18ExpressionTreeNodeE62813
_ZNK4PLMD6lepton16ParsedExpression11getRootNodeEv2066977
_ZNK4PLMD6lepton16ParsedExpression13createProgramEv0
_ZNK4PLMD6lepton16ParsedExpression13differentiateERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE5040
_ZNK4PLMD6lepton16ParsedExpression15renameVariablesERKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_St4lessIS8_ESaISt4pairIKS8_S8_EEE0
_ZNK4PLMD6lepton16ParsedExpression24createCompiledExpressionEv16230
_ZNK4PLMD6lepton16ParsedExpression8evaluateERKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessIS8_ESaISt4pairIKS8_dEEE2008077
_ZNK4PLMD6lepton16ParsedExpression8evaluateEv0
_ZNK4PLMD6lepton16ParsedExpression8optimizeERKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessIS8_ESaISt4pairIKS8_dEEE8199
_ZNK4PLMD6lepton16ParsedExpression8optimizeEv16230
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lepton/ParsedExpression.cpp.gcov.html b/coverage-libs/lepton/ParsedExpression.cpp.gcov.html new file mode 100644 index 000000000000..b002150bb7c0 --- /dev/null +++ b/coverage-libs/lepton/ParsedExpression.cpp.gcov.html @@ -0,0 +1,528 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - lepton/ParsedExpression.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - ParsedExpression.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:23025789.5 %
Date:2024-04-19 12:12:36Functions: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     2045745 : ParsedExpression::ParsedExpression(const ExpressionTreeNode& rootNode) : rootNode(rootNode) {
+      79     2045745 : }
+      80             : 
+      81     2066977 : const ExpressionTreeNode& ParsedExpression::getRootNode() const {
+      82     2066977 :     if (&rootNode.getOperation() == NULL)
+      83           0 :         throw Exception("Illegal call to an initialized ParsedExpression");
+      84     2066977 :     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     2036659 : double ParsedExpression::evaluate(const ExpressionTreeNode& node, const map<string, double>& variables) {
+      96     2036659 :     int numArgs = (int) node.getChildren().size();
+      97     4068417 :     vector<double> args(max(numArgs, 1));
+      98     2044226 :     for (int i = 0; i < numArgs; i++)
+      99        7572 :         args[i] = evaluate(node.getChildren()[i], variables);
+     100     4073286 :     return node.getOperation().evaluate(&args[0], variables);
+     101             : }
+     102             : 
+     103       16230 : ParsedExpression ParsedExpression::optimize() const {
+     104       16230 :     ExpressionTreeNode result = getRootNode();
+     105             :     vector<const ExpressionTreeNode*> examples;
+     106       16230 :     result.assignTags(examples);
+     107             :     map<int, ExpressionTreeNode> nodeCache;
+     108       16230 :     result = precalculateConstantSubexpressions(result, nodeCache);
+     109             :     while (true) {
+     110             :         examples.clear();
+     111       16230 :         result.assignTags(examples);
+     112             :         nodeCache.clear();
+     113       16230 :         ExpressionTreeNode simplified = substituteSimplerExpression(result, nodeCache);
+     114       16230 :         if (simplified == result)
+     115             :             break;
+     116           0 :         result = simplified;
+     117       16230 :     }
+     118       32460 :     return ParsedExpression(result);
+     119       16230 : }
+     120             : 
+     121        8199 : ParsedExpression ParsedExpression::optimize(const map<string, double>& variables) const {
+     122        8199 :     ExpressionTreeNode result = preevaluateVariables(getRootNode(), variables);
+     123             :     vector<const ExpressionTreeNode*> examples;
+     124        8199 :     result.assignTags(examples);
+     125             :     map<int, ExpressionTreeNode> nodeCache;
+     126        8199 :     result = precalculateConstantSubexpressions(result, nodeCache);
+     127             :     while (true) {
+     128             :         examples.clear();
+     129       14577 :         result.assignTags(examples);
+     130             :         nodeCache.clear();
+     131       14577 :         ExpressionTreeNode simplified = substituteSimplerExpression(result, nodeCache);
+     132       14577 :         if (simplified == result)
+     133             :             break;
+     134        6378 :         result = simplified;
+     135       14577 :     }
+     136       16398 :     return ParsedExpression(result);
+     137        8199 : }
+     138             : 
+     139      178064 : ExpressionTreeNode ParsedExpression::preevaluateVariables(const ExpressionTreeNode& node, const map<string, double>& variables) {
+     140      178064 :     if (node.getOperation().getId() == Operation::VARIABLE) {
+     141       31045 :         const Operation::Variable& var = dynamic_cast<const Operation::Variable&>(node.getOperation());
+     142       62090 :         map<string, double>::const_iterator iter = variables.find(var.getName());
+     143       31045 :         if (iter == variables.end())
+     144       29649 :             return node;
+     145        1396 :         return ExpressionTreeNode(new Operation::Constant(iter->second));
+     146             :     }
+     147      147019 :     vector<ExpressionTreeNode> children(node.getChildren().size());
+     148      316884 :     for (int i = 0; i < (int) children.size(); i++)
+     149      169865 :         children[i] = preevaluateVariables(node.getChildren()[i], variables);
+     150      147019 :     return ExpressionTreeNode(node.getOperation().clone(), children);
+     151      147019 : }
+     152             : 
+     153      209410 : ExpressionTreeNode ParsedExpression::precalculateConstantSubexpressions(const ExpressionTreeNode& node, map<int, ExpressionTreeNode>& nodeCache) {
+     154      209410 :     auto cached = nodeCache.find(node.tag);
+     155      209410 :     if (cached != nodeCache.end())
+     156       40573 :         return cached->second;
+     157      168837 :     vector<ExpressionTreeNode> children(node.getChildren().size());
+     158      353818 :     for (int i = 0; i < (int) children.size(); i++)
+     159      184981 :         children[i] = precalculateConstantSubexpressions(node.getChildren()[i], nodeCache);
+     160      168837 :     ExpressionTreeNode result = ExpressionTreeNode(node.getOperation().clone(), children);
+     161      168837 :     if (node.getOperation().getId() == Operation::VARIABLE || node.getOperation().getId() == Operation::CUSTOM) {
+     162       34310 :         nodeCache[node.tag] = result;
+     163       34310 :         return result;
+     164             :     }
+     165      150770 :     for (int i = 0; i < (int) children.size(); i++)
+     166      129760 :         if (children[i].getOperation().getId() != Operation::CONSTANT) {
+     167      113517 :             nodeCache[node.tag] = result;
+     168      113517 :             return result;
+     169             :         }
+     170       21010 :     result = ExpressionTreeNode(new Operation::Constant(evaluate(result, map<string, double>())));
+     171       21010 :     nodeCache[node.tag] = result;
+     172       21010 :     return result;
+     173      168837 : }
+     174             : 
+     175      217749 : ExpressionTreeNode ParsedExpression::substituteSimplerExpression(const ExpressionTreeNode& node, map<int, ExpressionTreeNode>& nodeCache) {
+     176      217749 :     vector<ExpressionTreeNode> children(node.getChildren().size());
+     177      456068 :     for (int i = 0; i < (int) children.size(); i++) {
+     178      238319 :         const ExpressionTreeNode& child = node.getChildren()[i];
+     179      238319 :         auto cached = nodeCache.find(child.tag);
+     180      238319 :         if (cached == nodeCache.end()) {
+     181      186942 :             children[i] = substituteSimplerExpression(child, nodeCache);
+     182      186942 :             nodeCache[child.tag] = children[i];
+     183             :         }
+     184             :         else
+     185       51377 :             children[i] = cached->second;
+     186             :     }
+     187             :     
+     188             :     // Collect some info on constant expressions in children
+     189      217749 :     bool first_const = children.size() > 0 && isConstant(children[0]); // is first child constant?
+     190      217749 :     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      217749 :     if (first_const)
+     193       11234 :         first = getConstantValue(children[0]);
+     194      217749 :     if (second_const)
+     195       18694 :         second = getConstantValue(children[1]);
+     196             : 
+     197      217749 :     switch (node.getOperation().getId()) {
+     198       25305 :         case Operation::ADD:
+     199             :         {
+     200       25305 :             if (first_const) {
+     201        1768 :                 if (first == 0.0) { // Add 0
+     202        1673 :                     return children[1];
+     203             :                 } else { // Add a constant
+     204          95 :                     return ExpressionTreeNode(new Operation::AddConstant(first), children[1]);
+     205             :                 }
+     206             :             }
+     207       23537 :             if (second_const) {
+     208        1331 :                 if (second == 0.0) { // Add 0
+     209        1066 :                     return children[0];
+     210             :                 } else { // Add a constant
+     211         265 :                     return ExpressionTreeNode(new Operation::AddConstant(second), children[0]);
+     212             :                 }
+     213             :             }
+     214       22206 :             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       22204 :             if (children[0].getOperation().getId() == Operation::NEGATE) // (-a)+b = b-a
+     217          23 :                 return ExpressionTreeNode(new Operation::Subtract(), children[1], children[0].getChildren()[0]);
+     218             :             break;
+     219             :         }
+     220             :         case Operation::SUBTRACT:
+     221             :         {
+     222        6345 :             if (children[0] == children[1])
+     223           2 :                 return ExpressionTreeNode(new Operation::Constant(0.0)); // Subtracting anything from itself is 0
+     224        6343 :             if (first_const) {
+     225        1673 :                 if (first == 0.0) // Subtract from 0
+     226          28 :                     return ExpressionTreeNode(new Operation::Negate(), children[1]);
+     227             :             }
+     228        6315 :             if (second_const) {
+     229        1681 :                 if (second == 0.0) { // Subtract 0
+     230         243 :                     return children[0];
+     231             :                 } else { // Subtract a constant
+     232        1438 :                     return ExpressionTreeNode(new Operation::AddConstant(-second), children[0]);
+     233             :                 }
+     234             :             }
+     235        4634 :             if (children[1].getOperation().getId() == Operation::NEGATE) // a-(-b) = a+b
+     236           3 :                 return ExpressionTreeNode(new Operation::Add(), children[0], children[1].getChildren()[0]);
+     237             :             break;
+     238             :         }
+     239       31408 :         case Operation::MULTIPLY:
+     240             :         {   
+     241       31408 :             if ((first_const && first == 0.0) || (second_const && second == 0.0)) // Multiply by 0
+     242        3169 :                 return ExpressionTreeNode(new Operation::Constant(0.0));
+     243       28239 :             if (first_const && first == 1.0) // Multiply by 1
+     244          30 :                 return children[1];
+     245       28209 :             if (second_const && second == 1.0) // Multiply by 1
+     246        4265 :                 return children[0];
+     247       23944 :             if (first_const) { // Multiply by a constant
+     248        5971 :                 if (children[1].getOperation().getId() == Operation::MULTIPLY_CONSTANT) // Combine two multiplies into a single one
+     249         791 :                     return ExpressionTreeNode(new Operation::MultiplyConstant(first*dynamic_cast<const Operation::MultiplyConstant*>(&children[1].getOperation())->getValue()), children[1].getChildren()[0]);
+     250        5180 :                 return ExpressionTreeNode(new Operation::MultiplyConstant(first), children[1]);
+     251             :             }
+     252       17973 :             if (second_const) { // Multiply by a constant
+     253        1396 :                 if (children[0].getOperation().getId() == Operation::MULTIPLY_CONSTANT) // Combine two multiplies into a single one
+     254         292 :                     return ExpressionTreeNode(new Operation::MultiplyConstant(second*dynamic_cast<const Operation::MultiplyConstant*>(&children[0].getOperation())->getValue()), children[0].getChildren()[0]);
+     255        1104 :                 return ExpressionTreeNode(new Operation::MultiplyConstant(second), children[0]);
+     256             :             }
+     257       16577 :             if (children[0].getOperation().getId() == Operation::NEGATE && children[1].getOperation().getId() == Operation::NEGATE) // The two negations cancel
+     258           2 :                 return ExpressionTreeNode(new Operation::Multiply(), children[0].getChildren()[0], children[1].getChildren()[0]);
+     259       16575 :             if (children[0].getOperation().getId() == Operation::NEGATE && children[1].getOperation().getId() == Operation::MULTIPLY_CONSTANT) // Negate the constant
+     260           2 :                 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       16573 :             if (children[1].getOperation().getId() == Operation::NEGATE && children[0].getOperation().getId() == Operation::MULTIPLY_CONSTANT) // Negate the constant
+     262         201 :                 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       16372 :             if (children[0].getOperation().getId() == Operation::NEGATE) // Pull the negation out so it can possibly be optimized further
+     264         104 :                 return ExpressionTreeNode(new Operation::Negate(), ExpressionTreeNode(new Operation::Multiply(), children[0].getChildren()[0], children[1]));
+     265       16268 :             if (children[1].getOperation().getId() == Operation::NEGATE) // Pull the negation out so it can possibly be optimized further
+     266          10 :                 return ExpressionTreeNode(new Operation::Negate(), ExpressionTreeNode(new Operation::Multiply(), children[0], children[1].getChildren()[0]));
+     267       16258 :             if (children[1].getOperation().getId() == Operation::RECIPROCAL) // a*(1/b) = a/b
+     268          89 :                 return ExpressionTreeNode(new Operation::Divide(), children[0], children[1].getChildren()[0]);
+     269       16169 :             if (children[0].getOperation().getId() == Operation::RECIPROCAL) // (1/a)*b = b/a
+     270          32 :                 return ExpressionTreeNode(new Operation::Divide(), children[1], children[0].getChildren()[0]);
+     271       16137 :             if (children[0] == children[1])
+     272         587 :                 return ExpressionTreeNode(new Operation::Square(), children[0]); // x*x = square(x)
+     273       15550 :             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       15548 :             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       13624 :             if (children[0] == children[1])
+     282           2 :                 return ExpressionTreeNode(new Operation::Constant(1.0)); // Dividing anything from itself is 0
+     283       13622 :             if (first_const && first == 0.0) // 0 divided by something
+     284         212 :                 return ExpressionTreeNode(new Operation::Constant(0.0));
+     285       13410 :             if (first_const && first == 1.0) // 1 divided by something
+     286         230 :                 return ExpressionTreeNode(new Operation::Reciprocal(), children[1]);
+     287       13180 :             if (second_const && second == 1.0) // Divide by 1
+     288          11 :                 return children[0];
+     289       13169 :             if (second_const) {
+     290        2012 :                 if (children[0].getOperation().getId() == Operation::MULTIPLY_CONSTANT) // Combine a multiply and a divide into one multiply
+     291         769 :                     return ExpressionTreeNode(new Operation::MultiplyConstant(dynamic_cast<const Operation::MultiplyConstant*>(&children[0].getOperation())->getValue()/second), children[0].getChildren()[0]);
+     292        1243 :                 return ExpressionTreeNode(new Operation::MultiplyConstant(1.0/second), children[0]); // Replace a divide with a multiply
+     293             :             }
+     294       11157 :             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       11157 :             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       11157 :             if (children[0].getOperation().getId() == Operation::NEGATE) // Pull the negation out so it can possibly be optimized further
+     299         718 :                 return ExpressionTreeNode(new Operation::Negate(), ExpressionTreeNode(new Operation::Divide(), children[0].getChildren()[0], children[1]));
+     300       10439 :             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       10439 :             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        3222 :         case Operation::POWER:
+     307             :         {
+     308        3222 :             if (first_const && first == 0.0) // 0 to any power is 0
+     309           6 :                 return ExpressionTreeNode(new Operation::Constant(0.0));
+     310        3216 :             if (first_const && first == 1.0) // 1 to any power is 1
+     311           6 :                 return ExpressionTreeNode(new Operation::Constant(1.0));
+     312        3210 :             if (second_const) { // Constant exponent
+     313        3194 :                 if (second == 0.0) // x^0 = 1
+     314           4 :                     return ExpressionTreeNode(new Operation::Constant(1.0));
+     315        3190 :                 if (second == 1.0) // x^1 = x
+     316        1258 :                     return children[0];
+     317        1932 :                 if (second == -1.0) // x^-1 = recip(x)
+     318           0 :                     return ExpressionTreeNode(new Operation::Reciprocal(), children[0]);
+     319        1932 :                 if (second == 2.0) // x^2 = square(x)
+     320        1674 :                     return ExpressionTreeNode(new Operation::Square(), children[0]);
+     321         258 :                 if (second == 3.0) // x^3 = cube(x)
+     322         138 :                     return ExpressionTreeNode(new Operation::Cube(), children[0]);
+     323         120 :                 if (second == 0.5) // x^0.5 = sqrt(x)
+     324           7 :                     return ExpressionTreeNode(new Operation::Sqrt(), children[0]);
+     325             :                 // Constant power
+     326         113 :                 return ExpressionTreeNode(new Operation::PowerConstant(second), children[0]);
+     327             :             }
+     328             :             break;
+     329             :         }
+     330             :         case Operation::NEGATE:
+     331             :         {
+     332        6844 :             if (children[0].getOperation().getId() == Operation::MULTIPLY_CONSTANT) // Combine a multiply and a negate into a single multiply
+     333         626 :                 return ExpressionTreeNode(new Operation::MultiplyConstant(-dynamic_cast<const Operation::MultiplyConstant*>(&children[0].getOperation())->getValue()), children[0].getChildren()[0]);
+     334        6218 :             if (first_const) // Negate a constant
+     335         208 :                 return ExpressionTreeNode(new Operation::Constant(-first));
+     336        6010 :             if (children[0].getOperation().getId() == Operation::NEGATE) // The two negations cancel
+     337           8 :                 return children[0].getChildren()[0];
+     338             :             break;
+     339             :         }
+     340             :         case Operation::MULTIPLY_CONSTANT:
+     341             :         {
+     342       24886 :             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       24886 :             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       24886 :             if (children[0].getOperation().getId() == Operation::NEGATE) // Combine a multiply and a negate into a single multiply
+     347        1712 :                 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        2622 :             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       18578 :             if (children[0].getOperation().getId() == Operation::SQRT) // square(sqrt(x)) = x
+     358          45 :                 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      188055 :     return ExpressionTreeNode(node.getOperation().clone(), children);
+     369      217749 : }
+     370             : 
+     371        5040 : ParsedExpression ParsedExpression::differentiate(const string& variable) const {
+     372             :     vector<const ExpressionTreeNode*> examples;
+     373        5040 :     getRootNode().assignTags(examples);
+     374             :     map<int, ExpressionTreeNode> nodeCache;
+     375       10080 :     return differentiate(getRootNode(), variable, nodeCache);
+     376             : }
+     377             : 
+     378       43220 : ExpressionTreeNode ParsedExpression::differentiate(const ExpressionTreeNode& node, const string& variable, map<int, ExpressionTreeNode>& nodeCache) {
+     379       43220 :     auto cached = nodeCache.find(node.tag);
+     380       43220 :     if (cached != nodeCache.end())
+     381        6168 :         return cached->second;
+     382       37052 :     vector<ExpressionTreeNode> childDerivs(node.getChildren().size());
+     383       75232 :     for (int i = 0; i < (int) childDerivs.size(); i++)
+     384       38180 :         childDerivs[i] = differentiate(node.getChildren()[i], variable, nodeCache);
+     385       37052 :     ExpressionTreeNode result = node.getOperation().differentiate(node.getChildren(), childDerivs, variable);
+     386       37052 :     nodeCache[node.tag] = result;
+     387       37052 :     return result;
+     388       37052 : }
+     389             : 
+     390      238243 : bool ParsedExpression::isConstant(const ExpressionTreeNode& node) {
+     391      238243 :     return (node.getOperation().getId() == Operation::CONSTANT);
+     392             : }
+     393             : 
+     394       29928 : double ParsedExpression::getConstantValue(const ExpressionTreeNode& node) {
+     395       29928 :     if (node.getOperation().getId() != Operation::CONSTANT) {
+     396           0 :         throw Exception("getConstantValue called on a non-constant ExpressionNode");
+     397             :     }
+     398       29928 :     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       16230 : CompiledExpression ParsedExpression::createCompiledExpression() const {
+     406       16230 :     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       62813 : ostream& lepton::operator<<(ostream& out, const ExpressionTreeNode& node) {
+     426       62813 :     if (node.getOperation().isInfixOperator() && node.getChildren().size() == 2) {
+     427       41223 :         out << "(" << node.getChildren()[0] << ")" << node.getOperation().getName() << "(" << node.getChildren()[1] << ")";
+     428             :     }
+     429       49072 :     else if (node.getOperation().isInfixOperator() && node.getChildren().size() == 1) {
+     430         136 :         out << "(" << node.getChildren()[0] << ")" << node.getOperation().getName();
+     431             :     }
+     432             :     else {
+     433       49004 :         out << node.getOperation().getName();
+     434       49004 :         if (node.getChildren().size() > 0) {
+     435       27016 :             out << "(";
+     436       54118 :             for (int i = 0; i < (int) node.getChildren().size(); i++) {
+     437       27102 :                 if (i > 0)
+     438          86 :                     out << ", ";
+     439       27102 :                 out << node.getChildren()[i];
+     440             :             }
+     441       27016 :             out << ")";
+     442             :         }
+     443             :     }
+     444       62813 :     return out;
+     445             : }
+     446             : 
+     447        8161 : ostream& lepton::operator<<(ostream& out, const ParsedExpression& exp) {
+     448        8161 :     out << exp.getRootNode();
+     449        8161 :     return out;
+     450             : }
+     451             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lepton/ParsedExpression.h.func-sort-c.html b/coverage-libs/lepton/ParsedExpression.h.func-sort-c.html new file mode 100644 index 000000000000..a079947f5a4d --- /dev/null +++ b/coverage-libs/lepton/ParsedExpression.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - lepton/ParsedExpression.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - ParsedExpression.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:11100.0 %
Date:2024-04-19 12:12:36Functions:00-
+
+ +
+ + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lepton/ParsedExpression.h.gcov.html b/coverage-libs/lepton/ParsedExpression.h.gcov.html new file mode 100644 index 000000000000..8598d35988ca --- /dev/null +++ b/coverage-libs/lepton/ParsedExpression.h.gcov.html @@ -0,0 +1,242 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - lepton/ParsedExpression.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - ParsedExpression.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:11100.0 %
Date:2024-04-19 12:12:36Functions: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     2040687 : class LEPTON_EXPORT ParsedExpression {
+      84             : public:
+      85             :     /**
+      86             :      * Create an uninitialized ParsedExpression.  This exists so that ParsedExpressions can be put in STL containers.
+      87             :      * Doing anything with it will produce an exception.
+      88             :      */
+      89             :     ParsedExpression();
+      90             :     /**
+      91             :      * Create a ParsedExpression.  Normally you will not call this directly.  Instead, use the Parser class
+      92             :      * to parse expression.
+      93             :      */
+      94             :     ParsedExpression(const ExpressionTreeNode& rootNode);
+      95             :     /**
+      96             :      * Get the root node of the expression's abstract syntax tree.
+      97             :      */
+      98             :     const ExpressionTreeNode& getRootNode() const;
+      99             :     /**
+     100             :      * Evaluate the expression.  If the expression involves any variables, this method will throw an exception.
+     101             :      */
+     102             :     double evaluate() const;
+     103             :     /**
+     104             :      * Evaluate the expression.
+     105             :      *
+     106             :      * @param variables    a map specifying the values of all variables that appear in the expression.  If any
+     107             :      *                     variable appears in the expression but is not included in this map, an exception
+     108             :      *                     will be thrown.
+     109             :      */
+     110             :     double evaluate(const std::map<std::string, double>& variables) const;
+     111             :     /**
+     112             :      * Create a new ParsedExpression which produces the same result as this one, but is faster to evaluate.
+     113             :      */
+     114             :     ParsedExpression optimize() const;
+     115             :     /**
+     116             :      * Create a new ParsedExpression which produces the same result as this one, but is faster to evaluate.
+     117             :      *
+     118             :      * @param variables    a map specifying values for a subset of variables that appear in the expression.
+     119             :      *                     All occurrences of these variables in the expression are replaced with the values
+     120             :      *                     specified.
+     121             :      */
+     122             :     ParsedExpression optimize(const std::map<std::string, double>& variables) const;
+     123             :     /**
+     124             :      * Create a new ParsedExpression which is the analytic derivative of this expression with respect to a
+     125             :      * particular variable.
+     126             :      *
+     127             :      * @param variable     the variable with respect to which the derivate should be taken
+     128             :      */
+     129             :     ParsedExpression differentiate(const std::string& variable) const;
+     130             :     /**
+     131             :      * Create an ExpressionProgram that represents the same calculation as this expression.
+     132             :      */
+     133             :     ExpressionProgram createProgram() const;
+     134             :     /**
+     135             :      * Create a CompiledExpression that represents the same calculation as this expression.
+     136             :      */
+     137             :     CompiledExpression createCompiledExpression() const;
+     138             :     /**
+     139             :      * Create a new ParsedExpression which is identical to this one, except that the names of some
+     140             :      * variables have been changed.
+     141             :      *
+     142             :      * @param replacements    a map whose keys are the names of variables, and whose values are the
+     143             :      *                        new names to replace them with
+     144             :      */
+     145             :     ParsedExpression renameVariables(const std::map<std::string, std::string>& replacements) const;
+     146             : private:
+     147             :     static double evaluate(const ExpressionTreeNode& node, const std::map<std::string, double>& variables);
+     148             :     static ExpressionTreeNode preevaluateVariables(const ExpressionTreeNode& node, const std::map<std::string, double>& variables);
+     149             :     static ExpressionTreeNode precalculateConstantSubexpressions(const ExpressionTreeNode& node, std::map<int, ExpressionTreeNode>& nodeCache);
+     150             :     static ExpressionTreeNode substituteSimplerExpression(const ExpressionTreeNode& node, std::map<int, ExpressionTreeNode>& nodeCache);
+     151             :     static ExpressionTreeNode differentiate(const ExpressionTreeNode& node, const std::string& variable, std::map<int, ExpressionTreeNode>& nodeCache);
+     152             :     static bool isConstant(const ExpressionTreeNode& node);
+     153             :     static double getConstantValue(const ExpressionTreeNode& node);
+     154             :     static ExpressionTreeNode renameNodeVariables(const ExpressionTreeNode& node, const std::map<std::string, std::string>& replacements);
+     155             :     ExpressionTreeNode rootNode;
+     156             : };
+     157             : 
+     158             : LEPTON_EXPORT std::ostream& operator<<(std::ostream& out, const ExpressionTreeNode& node);
+     159             : 
+     160             : LEPTON_EXPORT std::ostream& operator<<(std::ostream& out, const ParsedExpression& exp);
+     161             : 
+     162             : } // namespace lepton
+     163             : } // namespace PLMD
+     164             : 
+     165             : #endif /*LEPTON_PARSED_EXPRESSION_H_*/
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lepton/Parser.cpp.func-sort-c.html b/coverage-libs/lepton/Parser.cpp.func-sort-c.html new file mode 100644 index 000000000000..8c5c2d80af96 --- /dev/null +++ b/coverage-libs/lepton/Parser.cpp.func-sort-c.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - lepton/Parser.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - Parser.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:27429891.9 %
Date:2024-04-19 12:12:36Functions: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_clEv193
_ZN4PLMD6lepton6Parser20getFunctionOperationERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt3mapIS7_PNS0_14CustomFunctionESt4lessIS7_ESaISt4pairIS8_SC_EEE5346
_ZN4PLMD6lepton6Parser20getOperatorOperationERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE27810
_ZN4PLMD6lepton9ConstantsB5cxx11Ev2016266
_ZN4PLMD6lepton6Parser5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2016289
_ZN4PLMD6lepton6Parser5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt3mapIS7_PNS0_14CustomFunctionESt4lessIS7_ESaISt4pairIS8_SC_EEE2016289
_ZN4PLMD6lepton6Parser8tokenizeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2016293
_ZN4PLMD6lepton6Parser15parsePrecedenceERKSt6vectorINS0_10ParseTokenESaIS3_EERiRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPNS0_14CustomFunctionESt4lessISF_ESaISt4pairIKSF_SH_EEERKS9_ISF_NS0_18ExpressionTreeNodeESJ_SaISK_ISL_SR_EEEi2060627
_ZN4PLMD6lepton6Parser12getNextTokenERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEi2102296
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lepton/Parser.cpp.func.html b/coverage-libs/lepton/Parser.cpp.func.html new file mode 100644 index 000000000000..97a2329f0d9f --- /dev/null +++ b/coverage-libs/lepton/Parser.cpp.func.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - lepton/Parser.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - Parser.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:27429891.9 %
Date:2024-04-19 12:12:36Functions:1010100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6lepton6Parser12getNextTokenERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEi2102296
_ZN4PLMD6lepton6Parser15parsePrecedenceERKSt6vectorINS0_10ParseTokenESaIS3_EERiRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPNS0_14CustomFunctionESt4lessISF_ESaISt4pairIKSF_SH_EEERKS9_ISF_NS0_18ExpressionTreeNodeESJ_SaISK_ISL_SR_EEEi2060627
_ZN4PLMD6lepton6Parser20getFunctionOperationERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt3mapIS7_PNS0_14CustomFunctionESt4lessIS7_ESaISt4pairIS8_SC_EEE5346
_ZN4PLMD6lepton6Parser20getOperatorOperationERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE27810
_ZN4PLMD6lepton6Parser4trimERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE8
_ZN4PLMD6lepton6Parser5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2016289
_ZN4PLMD6lepton6Parser5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt3mapIS7_PNS0_14CustomFunctionESt4lessIS7_ESaISt4pairIS8_SC_EEE2016289
_ZN4PLMD6lepton6Parser8tokenizeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2016293
_ZN4PLMD6lepton9ConstantsB5cxx11Ev2016266
_ZZN4PLMD6lepton6Parser20getFunctionOperationERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt3mapIS7_PNS0_14CustomFunctionESt4lessIS7_ESaISt4pairIS8_SC_EEEENKUlvE_clEv193
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lepton/Parser.cpp.gcov.html b/coverage-libs/lepton/Parser.cpp.gcov.html new file mode 100644 index 000000000000..f6d7beced047 --- /dev/null +++ b/coverage-libs/lepton/Parser.cpp.gcov.html @@ -0,0 +1,585 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - lepton/Parser.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - Parser.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:27429891.9 %
Date:2024-04-19 12:12:36Functions: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     2016266 : 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     2019335 :   };
+     101     2016266 :   return constants;
+     102             : }
+     103             : 
+     104             : }
+     105             : 
+     106             : 
+     107     6553531 : class lepton::ParseToken {
+     108             : public:
+     109             :     enum Type {Number, Operator, Variable, Function, LeftParen, RightParen, Comma, Whitespace};
+     110             : 
+     111     2102296 :     ParseToken(string text, Type type) : text(text), type(type) {
+     112             :     }
+     113             :     const string& getText() const {
+     114          13 :         return text;
+     115             :     }
+     116             :     Type getType() const {
+     117       70693 :         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     2102296 : ParseToken Parser::getNextToken(const string& expression, int start) {
+     138     2102296 :     char c = expression[start];
+     139     2102296 :     if (c == '(')
+     140       16650 :         return ParseToken("(", ParseToken::LeftParen);
+     141     2093971 :     if (c == ')')
+     142       27342 :         return ParseToken(")", ParseToken::RightParen);
+     143     2080300 :     if (c == ',')
+     144         294 :         return ParseToken(",", ParseToken::Comma);
+     145     2080153 :     if (Operators.find(c) != string::npos)
+     146       30516 :         return ParseToken(string(1, c), ParseToken::Operator);
+     147     2049637 :     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     2049609 :     if (c == '.' || Digits.find(c) != string::npos) {
+     157             :         // A number
+     158             : 
+     159     2023253 :         bool foundDecimal = (c == '.');
+     160             :         bool foundExp = false;
+     161             :         int pos;
+     162    20147982 :         for (pos = start+1; pos < (int) expression.size(); pos++) {
+     163    18139303 :             c = expression[pos];
+     164    18139303 :             if (Digits.find(c) != string::npos)
+     165    16108589 :                 continue;
+     166     2030714 :             if (c == '.' && !foundDecimal) {
+     167             :                 foundDecimal = true;
+     168     2015954 :                 continue;
+     169             :             }
+     170       14760 :             if ((c == 'e' || c == 'E') && !foundExp) {
+     171             :                 foundExp = true;
+     172         186 :                 if (pos < (int) expression.size()-1 && (expression[pos+1] == '-' || expression[pos+1] == '+'))
+     173             :                     pos++;
+     174         186 :                 continue;
+     175             :             }
+     176             :             break;
+     177             :         }
+     178     4046506 :         return ParseToken(expression.substr(start, pos-start), ParseToken::Number);
+     179             :     }
+     180             : 
+     181             :     // A variable, function, or left parenthesis
+     182             : 
+     183       67032 :     for (int pos = start; pos < (int) expression.size(); pos++) {
+     184       62739 :         c = expression[pos];
+     185       62739 :         if (c == '(')
+     186       10692 :             return ParseToken(expression.substr(start, pos-start+1), ParseToken::Function);
+     187       57393 :         if (Operators.find(c) != string::npos || c == ',' || c == ')' || isspace(c))
+     188       33434 :             return ParseToken(expression.substr(start, pos-start), ParseToken::Variable);
+     189             :     }
+     190        8586 :     return ParseToken(expression.substr(start, string::npos), ParseToken::Variable);
+     191             : }
+     192             : 
+     193     2016293 : vector<ParseToken> Parser::tokenize(const string& expression) {
+     194             :     vector<ParseToken> tokens;
+     195             :     int pos = 0;
+     196     4118589 :     while (pos < (int) expression.size()) {
+     197     2102296 :         ParseToken token = getNextToken(expression, pos);
+     198     2102296 :         if (token.getType() != ParseToken::Whitespace)
+     199     2102268 :             tokens.push_back(token);
+     200     2102296 :         pos += (int) token.getText().size();
+     201             :     }
+     202     2016293 :     return tokens;
+     203           0 : }
+     204             : 
+     205     2016289 : ParsedExpression Parser::parse(const string& expression) {
+     206     4032565 :     return parse(expression, map<string, CustomFunction*>());
+     207             : }
+     208             : 
+     209     2016289 : ParsedExpression Parser::parse(const string& expression, const map<string, CustomFunction*>& customFunctions) {
+     210             :     try {
+     211             :         // First split the expression into subexpressions.
+     212             : 
+     213     2016289 :         string primaryExpression = expression;
+     214             :         vector<string> subexpressions;
+     215             :         while (true) {
+     216             :             string::size_type pos = primaryExpression.find_last_of(';');
+     217     2016293 :             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     2016293 :         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          21 :             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     2016289 :         vector<ParseToken> tokens = tokenize(primaryExpression);
+     245     2016289 :         int pos = 0;
+     246     2016289 :         ExpressionTreeNode result = parsePrecedence(tokens, pos, customFunctions, subexpDefs, 0);
+     247     2016289 :         if (pos != tokens.size())
+     248          26 :             throw Exception("unexpected text at end of expression: "+tokens[pos].getText());
+     249     4032552 :         return ParsedExpression(result);
+     250     4032591 :     }
+     251          13 :     catch (Exception& ex) {
+     252          26 :         throw Exception("Parse error in expression \""+expression+"\": "+ex.what());
+     253          13 :     }
+     254             : }
+     255             : 
+     256     2060627 : ExpressionTreeNode Parser::parsePrecedence(const vector<ParseToken>& tokens, int& pos, const map<string, CustomFunction*>& customFunctions,
+     257             :             const map<string, ExpressionTreeNode>& subexpressionDefs, int precedence) {
+     258     2060627 :     if (pos == tokens.size())
+     259           0 :         throw Exception("unexpected end of expression");
+     260             : 
+     261             :     // Parse the next value (number, variable, function, parenthesized expression)
+     262             : 
+     263             :     ParseToken token = tokens[pos];
+     264     2060627 :     ExpressionTreeNode result;
+     265     2060627 :     if (token.getType() == ParseToken::Number) {
+     266             :         double value;
+     267     4046506 :         stringstream(token.getText()) >> value;
+     268     2023253 :         result = ExpressionTreeNode(new Operation::Constant(value));
+     269     2023253 :         pos++;
+     270             :     }
+     271       37374 :     else if (token.getType() == ParseToken::Variable) {
+     272             :         map<string, ExpressionTreeNode>::const_iterator subexp = subexpressionDefs.find(token.getText());
+     273       20997 :         if (subexp == subexpressionDefs.end()) {
+     274       20993 :             Operation* op = new Operation::Variable(token.getText());
+     275       20993 :             result = ExpressionTreeNode(op);
+     276             :         }
+     277             :         else
+     278           4 :             result = subexp->second;
+     279       20997 :         pos++;
+     280             :     }
+     281       16377 :     else if (token.getType() == ParseToken::LeftParen) {
+     282        8325 :         pos++;
+     283        8325 :         result = parsePrecedence(tokens, pos, customFunctions, subexpressionDefs, 0);
+     284        8325 :         if (pos == tokens.size() || tokens[pos].getType() != ParseToken::RightParen)
+     285           0 :             throw Exception("unbalanced parentheses");
+     286        8325 :         pos++;
+     287             :     }
+     288        8052 :     else if (token.getType() == ParseToken::Function) {
+     289        5346 :         pos++;
+     290             :         vector<ExpressionTreeNode> args;
+     291             :         bool moreArgs;
+     292        5493 :         do {
+     293       10986 :             args.push_back(parsePrecedence(tokens, pos, customFunctions, subexpressionDefs, 0));
+     294        5493 :             moreArgs = (pos < (int) tokens.size() && tokens[pos].getType() == ParseToken::Comma);
+     295             :             if (moreArgs)
+     296         147 :                 pos++;
+     297             :         } while (moreArgs);
+     298        5346 :         if (pos == tokens.size() || tokens[pos].getType() != ParseToken::RightParen)
+     299           0 :             throw Exception("unbalanced parentheses");
+     300        5346 :         pos++;
+     301        5346 :         Operation* op = getFunctionOperation(token.getText(), customFunctions);
+     302             :         try {
+     303        5346 :             result = ExpressionTreeNode(op, args);
+     304             :         }
+     305           0 :         catch (...) {
+     306           0 :             delete op;
+     307           0 :             throw;
+     308           0 :         }
+     309        5346 :     }
+     310        5412 :     else if (token.getType() == ParseToken::Operator && token.getText() == "-") {
+     311        2706 :         pos++;
+     312        2706 :         ExpressionTreeNode toNegate = parsePrecedence(tokens, pos, customFunctions, subexpressionDefs, 2);
+     313        2706 :         result = ExpressionTreeNode(new Operation::Negate(), toNegate);
+     314        2706 :     }
+     315             :     else
+     316           0 :         throw Exception("unexpected token: "+token.getText());
+     317             : 
+     318             :     // Now deal with the next binary operator.
+     319             : 
+     320     2088437 :     while (pos < (int) tokens.size() && tokens[pos].getType() == ParseToken::Operator) {
+     321             :         token = tokens[pos];
+     322       38098 :         int opIndex = (int) Operators.find(token.getText());
+     323       38098 :         int opPrecedence = Precedence[opIndex];
+     324       38098 :         if (opPrecedence < precedence)
+     325       10288 :             return result;
+     326       27810 :         pos++;
+     327       27810 :         ExpressionTreeNode arg = parsePrecedence(tokens, pos, customFunctions, subexpressionDefs, LeftAssociative[opIndex] ? opPrecedence+1 : opPrecedence);
+     328       27810 :         Operation* op = getOperatorOperation(token.getText());
+     329             :         try {
+     330       27810 :             result = ExpressionTreeNode(op, result, arg);
+     331             :         }
+     332           0 :         catch (...) {
+     333           0 :             delete op;
+     334           0 :             throw;
+     335           0 :         }
+     336       27810 :     }
+     337             :     return result;
+     338           0 : }
+     339             : 
+     340       27810 : Operation* Parser::getOperatorOperation(const std::string& name) {
+     341       27810 :     switch (OperationId[Operators.find(name)]) {
+     342        4878 :         case Operation::ADD:
+     343        4878 :             return new Operation::Add();
+     344        4404 :         case Operation::SUBTRACT:
+     345        4404 :             return new Operation::Subtract();
+     346       10818 :         case Operation::MULTIPLY:
+     347       10818 :             return new Operation::Multiply();
+     348        4924 :         case Operation::DIVIDE:
+     349        4924 :             return new Operation::Divide();
+     350        2786 :         case Operation::POWER:
+     351        2786 :             return new Operation::Power();
+     352           0 :         default:
+     353           0 :             throw Exception("unknown operator");
+     354             :     }
+     355             : }
+     356             : 
+     357        5346 : Operation* Parser::getFunctionOperation(const std::string& name, const map<string, CustomFunction*>& customFunctions) {
+     358             : 
+     359         193 :     const static map<string, Operation::Id> opMap = []() {
+     360             :         map<string, Operation::Id> opMap;
+     361         193 :         opMap["sqrt"] = Operation::SQRT;
+     362         193 :         opMap["exp"] = Operation::EXP;
+     363         193 :         opMap["log"] = Operation::LOG;
+     364         193 :         opMap["sin"] = Operation::SIN;
+     365         193 :         opMap["cos"] = Operation::COS;
+     366         193 :         opMap["sec"] = Operation::SEC;
+     367         193 :         opMap["csc"] = Operation::CSC;
+     368         193 :         opMap["tan"] = Operation::TAN;
+     369         193 :         opMap["cot"] = Operation::COT;
+     370         193 :         opMap["asin"] = Operation::ASIN;
+     371         193 :         opMap["acos"] = Operation::ACOS;
+     372         193 :         opMap["atan"] = Operation::ATAN;
+     373         193 :         opMap["atan2"] = Operation::ATAN2;
+     374         193 :         opMap["sinh"] = Operation::SINH;
+     375         193 :         opMap["cosh"] = Operation::COSH;
+     376         193 :         opMap["tanh"] = Operation::TANH;
+     377         193 :         opMap["erf"] = Operation::ERF;
+     378         193 :         opMap["erfc"] = Operation::ERFC;
+     379         193 :         opMap["step"] = Operation::STEP;
+     380         193 :         opMap["delta"] = Operation::DELTA;
+     381         193 :         opMap["nandelta"] = Operation::NANDELTA;
+     382         193 :         opMap["square"] = Operation::SQUARE;
+     383         193 :         opMap["cube"] = Operation::CUBE;
+     384         193 :         opMap["recip"] = Operation::RECIPROCAL;
+     385         193 :         opMap["min"] = Operation::MIN;
+     386         193 :         opMap["max"] = Operation::MAX;
+     387         193 :         opMap["abs"] = Operation::ABS;
+     388         193 :         opMap["floor"] = Operation::FLOOR;
+     389         193 :         opMap["ceil"] = Operation::CEIL;
+     390         193 :         opMap["select"] = Operation::SELECT;
+     391         193 :         opMap["acot"] = Operation::ACOT;
+     392         193 :         opMap["asec"] = Operation::ASEC;
+     393         193 :         opMap["acsc"] = Operation::ACSC;
+     394         193 :         opMap["coth"] = Operation::COTH;
+     395         193 :         opMap["sech"] = Operation::SECH;
+     396         193 :         opMap["csch"] = Operation::CSCH;
+     397         193 :         opMap["asinh"] = Operation::ASINH;
+     398         193 :         opMap["acosh"] = Operation::ACOSH;
+     399         193 :         opMap["atanh"] = Operation::ATANH;
+     400         193 :         opMap["acoth"] = Operation::ACOTH;
+     401         193 :         opMap["asech"] = Operation::ASECH;
+     402         193 :         opMap["acsch"] = Operation::ACSCH;
+     403         193 :         opMap["atan2"] = Operation::ATAN2;
+     404         193 :         return opMap;
+     405        5346 :     }();
+     406        5346 :     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        5346 :     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        5346 :     if (iter == opMap.end())
+     418           0 :         throw Exception("unknown function: "+trimmed);
+     419        5346 :     switch (iter->second) {
+     420         682 :         case Operation::SQRT:
+     421         682 :             return new Operation::Sqrt();
+     422        1802 :         case Operation::EXP:
+     423        1802 :             return new Operation::Exp();
+     424         569 :         case Operation::LOG:
+     425         569 :             return new Operation::Log();
+     426         219 :         case Operation::SIN:
+     427         219 :             return new Operation::Sin();
+     428        1409 :         case Operation::COS:
+     429        1409 :             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          16 :         case Operation::ACOS:
+     441          16 :             return new Operation::Acos();
+     442           4 :         case Operation::ATAN:
+     443           4 :             return new Operation::Atan();
+     444          83 :         case Operation::ATAN2:
+     445          83 :             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          15 :         case Operation::TANH:
+     451          15 :             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         382 :         case Operation::STEP:
+     457         382 :             return new Operation::Step();
+     458           4 :         case Operation::DELTA:
+     459           4 :             return new Operation::Delta();
+     460           4 :         case Operation::NANDELTA:
+     461           4 :             return new Operation::Nandelta();
+     462           4 :         case Operation::SQUARE:
+     463           4 :             return new Operation::Square();
+     464           4 :         case Operation::CUBE:
+     465           4 :             return new Operation::Cube();
+     466           4 :         case Operation::RECIPROCAL:
+     467           4 :             return new Operation::Reciprocal();
+     468           8 :         case Operation::MIN:
+     469           8 :             return new Operation::Min();
+     470           8 :         case Operation::MAX:
+     471           8 :             return new Operation::Max();
+     472          13 :         case Operation::ABS:
+     473          13 :             return new Operation::Abs();
+     474           4 :         case Operation::FLOOR:
+     475           4 :             return new Operation::Floor();
+     476           4 :         case Operation::CEIL:
+     477           4 :             return new Operation::Ceil();
+     478          24 :         case Operation::SELECT:
+     479          24 :             return new Operation::Select();
+     480           4 :         case Operation::ACOT:
+     481           4 :             return new Operation::Acot();
+     482           4 :         case Operation::ASEC:
+     483           4 :             return new Operation::Asec();
+     484           4 :         case Operation::ACSC:
+     485           4 :             return new Operation::Acsc();
+     486           4 :         case Operation::COTH:
+     487           4 :             return new Operation::Coth();
+     488           4 :         case Operation::SECH:
+     489           4 :             return new Operation::Sech();
+     490           4 :         case Operation::CSCH:
+     491           4 :             return new Operation::Csch();
+     492           4 :         case Operation::ASINH:
+     493           4 :             return new Operation::Asinh();
+     494           4 :         case Operation::ACOSH:
+     495           4 :             return new Operation::Acosh();
+     496           4 :         case Operation::ATANH:
+     497           4 :             return new Operation::Atanh();
+     498           4 :         case Operation::ACOTH:
+     499           4 :             return new Operation::Acoth();
+     500           4 :         case Operation::ASECH:
+     501           4 :             return new Operation::Asech();
+     502           4 :         case Operation::ACSCH:
+     503           4 :             return new Operation::Acsch();
+     504           0 :         default:
+     505           0 :             throw Exception("unknown function");
+     506             :     }
+     507             : }
+     508             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lepton/index-sort-f.html b/coverage-libs/lepton/index-sort-f.html new file mode 100644 index 000000000000..912e8b4a339e --- /dev/null +++ b/coverage-libs/lepton/index-sort-f.html @@ -0,0 +1,184 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - lepton + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - leptonHitTotalCoverage
Test:plumed test coverage (other modules)Lines:1609178989.9 %
Date:2024-04-19 12:12:36Functions:39642892.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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 +
89.5%89.5%
+
89.5 %230 / 25776.2 %16 / 21
Operation.cpp +
86.3%86.3%
+
86.3 %272 / 31593.0 %53 / 57
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 +
91.9%91.9%
+
91.9 %274 / 298100.0 %10 / 10
ExpressionTreeNode.cpp +
94.4%94.4%
+
94.4 %68 / 72100.0 %15 / 15
CompiledExpression.cpp +
98.3%98.3%
+
98.3 %227 / 231100.0 %19 / 19
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lepton/index-sort-l.html b/coverage-libs/lepton/index-sort-l.html new file mode 100644 index 000000000000..b90aadf0c5b7 --- /dev/null +++ b/coverage-libs/lepton/index-sort-l.html @@ -0,0 +1,184 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - lepton + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - leptonHitTotalCoverage
Test:plumed test coverage (other modules)Lines:1609178989.9 %
Date:2024-04-19 12:12:36Functions:39642892.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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 +
86.3%86.3%
+
86.3 %272 / 31593.0 %53 / 57
ParsedExpression.cpp +
89.5%89.5%
+
89.5 %230 / 25776.2 %16 / 21
Parser.cpp +
91.9%91.9%
+
91.9 %274 / 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 +
98.3%98.3%
+
98.3 %227 / 231100.0 %19 / 19
ParsedExpression.h +
100.0%
+
100.0 %1 / 1-0 / 0
CompiledExpression.h +
100.0%
+
100.0 %1 / 1-0 / 0
Exception.h +
100.0%
+
100.0 %6 / 675.0 %3 / 4
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lepton/index.html b/coverage-libs/lepton/index.html new file mode 100644 index 000000000000..a77fac3dcad0 --- /dev/null +++ b/coverage-libs/lepton/index.html @@ -0,0 +1,184 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - lepton + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - leptonHitTotalCoverage
Test:plumed test coverage (other modules)Lines:1609178989.9 %
Date:2024-04-19 12:12:36Functions:39642892.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
CompiledExpression.cpp +
98.3%98.3%
+
98.3 %227 / 231100.0 %19 / 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 +
86.3%86.3%
+
86.3 %272 / 31593.0 %53 / 57
Operation.h +
95.3%95.3%
+
95.3 %530 / 55696.6 %280 / 290
ParsedExpression.cpp +
89.5%89.5%
+
89.5 %230 / 25776.2 %16 / 21
ParsedExpression.h +
100.0%
+
100.0 %1 / 1-0 / 0
Parser.cpp +
91.9%91.9%
+
91.9 %274 / 298100.0 %10 / 10
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/molfile/Gromacs.h.func-sort-c.html b/coverage-libs/molfile/Gromacs.h.func-sort-c.html new file mode 100644 index 000000000000..f8ed07e3a9b1 --- /dev/null +++ b/coverage-libs/molfile/Gromacs.h.func-sort-c.html @@ -0,0 +1,217 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - molfile/Gromacs.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - molfile - Gromacs.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:34275045.6 %
Date:2024-04-19 12:12:36Functions: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_fileE207
_ZN4PLMD7molfileL10mdio_errnoEv207
_ZN4PLMD7molfileL11mdio_headerEPNS0_7md_fileEPNS0_9md_headerE207
_ZN4PLMD7molfileL9mdio_openEPKcii207
_ZN4PLMD7molfileL7trx_intEPNS0_7md_fileEPi2485
_ZN4PLMD7molfileL14xtc_sizeofintsEiPj10116
_ZN4PLMD7molfileL8xtc_dataEPNS0_7md_fileEPci10116
_ZN4PLMD7molfileL12xtc_3dfcoordEPNS0_7md_fileEPfPiS3_18197
_ZN4PLMD7molfileL11mdio_tsfreeEPNS0_5md_tsEi18347
_ZN4PLMD7molfileL12mdio_readboxEPNS0_6md_boxEPfS3_S3_18347
_ZN4PLMD7molfileL12xtc_timestepEPNS0_7md_fileEPNS0_5md_tsE18399
_ZN4PLMD7molfileL13mdio_timestepEPNS0_7md_fileEPNS0_5md_tsE18554
_ZN4PLMD7molfileL7xtc_intEPNS0_7md_fileEPi154322
_ZN4PLMD7molfileL9xtc_floatEPNS0_7md_fileEPf216329
_ZN4PLMD7molfileL11trx_rvectorEPNS0_7md_fileEPf486150
_ZN4PLMD7molfileL8trx_realEPNS0_7md_fileEPf1458760
_ZN4PLMD7molfileL13mdio_seterrorEi2373501
_ZN4PLMD7molfileL15xtc_receiveintsEPiiiPjS1_4097130
_ZN4PLMD7molfileL15xtc_receivebitsEPii18283863
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/molfile/Gromacs.h.func.html b/coverage-libs/molfile/Gromacs.h.func.html new file mode 100644 index 000000000000..c7a2a90c5055 --- /dev/null +++ b/coverage-libs/molfile/Gromacs.h.func.html @@ -0,0 +1,217 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - molfile/Gromacs.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - molfile - Gromacs.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:34275045.6 %
Date:2024-04-19 12:12:36Functions:223661.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7molfileL10g96_headerEPNS0_7md_fileEPciPf0
_ZN4PLMD7molfileL10gro_headerEPNS0_7md_fileEPciPfPii0
_ZN4PLMD7molfileL10mdio_closeEPNS0_7md_fileE207
_ZN4PLMD7molfileL10mdio_errnoEv207
_ZN4PLMD7molfileL10trx_headerEPNS0_7md_fileEi160
_ZN4PLMD7molfileL10trx_stringEPNS0_7md_fileEPci155
_ZN4PLMD7molfileL11mdio_errmsgEi0
_ZN4PLMD7molfileL11mdio_headerEPNS0_7md_fileEPNS0_9md_headerE207
_ZN4PLMD7molfileL11mdio_tsfreeEPNS0_5md_tsEi18347
_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_18347
_ZN4PLMD7molfileL12put_trx_realEPNS0_7md_fileEf0
_ZN4PLMD7molfileL12trx_timestepEPNS0_7md_fileEPNS0_5md_tsE155
_ZN4PLMD7molfileL12xtc_3dfcoordEPNS0_7md_fileEPfPiS3_18197
_ZN4PLMD7molfileL12xtc_timestepEPNS0_7md_fileEPNS0_5md_tsE18399
_ZN4PLMD7molfileL13mdio_readlineEPNS0_7md_fileEPcii0
_ZN4PLMD7molfileL13mdio_seterrorEi2373501
_ZN4PLMD7molfileL13mdio_timestepEPNS0_7md_fileEPNS0_5md_tsE18554
_ZN4PLMD7molfileL13xtc_sizeofintEi0
_ZN4PLMD7molfileL14g96_countatomsEPNS0_7md_fileE0
_ZN4PLMD7molfileL14put_trx_stringEPNS0_7md_fileEPKc0
_ZN4PLMD7molfileL14xtc_sizeofintsEiPj10116
_ZN4PLMD7molfileL15xtc_receivebitsEPii18283863
_ZN4PLMD7molfileL15xtc_receiveintsEPiiiPjS1_4097130
_ZN4PLMD7molfileL7g96_recEPNS0_7md_fileEPNS0_7md_atomE0
_ZN4PLMD7molfileL7gro_recEPNS0_7md_fileEPNS0_7md_atomE0
_ZN4PLMD7molfileL7trx_intEPNS0_7md_fileEPi2485
_ZN4PLMD7molfileL7xtc_intEPNS0_7md_fileEPi154322
_ZN4PLMD7molfileL8trx_realEPNS0_7md_fileEPf1458760
_ZN4PLMD7molfileL8xtc_dataEPNS0_7md_fileEPci10116
_ZN4PLMD7molfileL9mdio_openEPKcii207
_ZN4PLMD7molfileL9xtc_floatEPNS0_7md_fileEPf216329
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/molfile/Gromacs.h.gcov.html b/coverage-libs/molfile/Gromacs.h.gcov.html new file mode 100644 index 000000000000..da5b2979c255 --- /dev/null +++ b/coverage-libs/molfile/Gromacs.h.gcov.html @@ -0,0 +1,2090 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - molfile/Gromacs.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - molfile - Gromacs.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:34275045.6 %
Date:2024-04-19 12:12:36Functions: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         207 : md_file *mdio_open(const char *fn, const int fmt, const int rw) {
+     329             :         md_file *mf;
+     330             : 
+     331         207 :         if (!fn) {
+     332           0 :                 mdio_seterror(MDIO_BADPARAMS);
+     333           0 :                 return NULL;
+     334             :         }
+     335             : 
+     336             :         // Allocate memory
+     337         207 :         mf = (md_file *) malloc(sizeof(md_file));
+     338         207 :         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         207 :         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         207 :                 mf->fmt = fmt;
+     375             :         }
+     376             : 
+     377             :         // Differentiate between binary and ascii files. Also,
+     378             :         // .trX files need a header information structure allocated.
+     379         207 :         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         207 :         case MDFMT_XTC:  /* fallthrough */
+     399             :                 // Finally, open the file
+     400         207 :         if (rw)
+     401           0 :             mf->f = fopen(fn, "wb");
+     402             :         else
+     403         207 :             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         207 :         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         207 :         mdio_seterror(MDIO_SUCCESS);
+     422         207 :         return mf;
+     423             : }
+     424             : 
+     425             : 
+     426             : // Closes a molecular dynamics file.
+     427         207 : static int mdio_close(md_file *mf) {
+     428         207 :         if (!mf) return mdio_seterror(MDIO_BADPARAMS);
+     429             : 
+     430         207 :         if (fclose(mf->f) == EOF) return mdio_seterror(MDIO_CANTCLOSE);
+     431             : 
+     432             :         // Free the dynamically allocated memory
+     433         207 :         if (mf->trx) free(mf->trx);
+     434         207 :         free(mf);
+     435         207 :         return mdio_seterror(MDIO_SUCCESS);
+     436             : }
+     437             : 
+     438             : 
+     439             : // Returns the last error code reported by any of the mdio functions
+     440         207 : static int mdio_errno(void) {
+     441         207 :         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     2373501 : static int mdio_seterror(int code) {
+     455     2373501 :         mdio_errcode = code;
+     456     2373501 :         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       18347 : static int mdio_tsfree(md_ts *ts, int holderror) {
+     522       18347 :         if (!ts) {
+     523           0 :                 if (holderror) return -1;
+     524           0 :                 else return mdio_seterror(MDIO_BADPARAMS);
+     525             :         }
+     526             : 
+     527       18347 :         if (ts->pos && ts->natoms > 0) free(ts->pos);
+     528             : 
+     529       18347 :   if (ts->box) free(ts->box);
+     530             : 
+     531       18347 :         if (holderror) return -1;
+     532       18347 :         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       18347 : static int mdio_readbox(md_box *box, float *x, float *y, float *z) {
+     540             :   float A, B, C;
+     541             : 
+     542       18347 :   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       18347 :   A = sqrt( x[0]*x[0] + x[1]*x[1] + x[2]*x[2] ) * ANGS_PER_NM;
+     548       18347 :   B = sqrt( y[0]*y[0] + y[1]*y[1] + y[2]*y[2] ) * ANGS_PER_NM;
+     549       18347 :   C = sqrt( z[0]*z[0] + z[1]*z[1] + z[2]*z[2] ) * ANGS_PER_NM;
+     550       18347 :   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       18347 :     box->A = A;
+     556       18347 :     box->B = B;
+     557       18347 :     box->C = C;
+     558             :   
+     559             :     // gamma, beta, alpha are the angles between the x & y, x & z, y & z
+     560             :     // vectors, respectively
+     561       18347 :     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       18347 :     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       18347 :     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       18347 :   return mdio_seterror(MDIO_SUCCESS);
+     566             : }
+     567             : 
+     568             : 
+     569             : // Reads the header of a file (format independent)
+     570         207 : static int mdio_header(md_file *mf, md_header *mdh) {
+     571             :         int n;
+     572         207 :         if (!mf || !mdh) return mdio_seterror(MDIO_BADPARAMS);
+     573         207 :         if (!mf->f) return mdio_seterror(MDIO_BADPARAMS);
+     574             : 
+     575         207 :         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         202 :                 if (xtc_int(mf, &n) < 0) return -1;
+     600         202 :                 if (n != XTC_MAGIC) return mdio_seterror(MDIO_BADFORMAT);
+     601             : 
+     602             :                 // Get number of atoms
+     603         202 :                 if (xtc_int(mf, &n) < 0) return -1;
+     604         202 :                 mdh->natoms = n;
+     605         202 :                 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       18554 : static int mdio_timestep(md_file *mf, md_ts *ts) {
+     616       18554 :         if (!mf || !ts) return mdio_seterror(MDIO_BADPARAMS);
+     617       18554 :         if (!mf->f) return mdio_seterror(MDIO_BADPARAMS);
+     618             : 
+     619       18554 :         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       18399 :         case MDFMT_XTC:
+     631       18399 :                 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      154322 : static int xtc_int(md_file *mf, int *i) {
+    1561             :         unsigned char c[4];
+    1562             : 
+    1563      154322 :         if (!mf) return mdio_seterror(MDIO_BADPARAMS);
+    1564             :         // sanity check.
+    1565             :         if (sizeof(int) != 4) return mdio_seterror(MDIO_SIZEERROR);
+    1566             : 
+    1567      154322 :         if (fread(c, 1, 4, mf->f) != 4) {
+    1568         202 :                 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      154120 :         if (i) *i = c[3] + (c[2] << 8) + (c[1] << 16) + (c[0] << 24);
+    1574      154120 :         return mdio_seterror(MDIO_SUCCESS);
+    1575             : }
+    1576             : 
+    1577             : 
+    1578             : // xtc_float() - reads a float from an xtc file
+    1579      216329 : static int xtc_float(md_file *mf, float *f) {
+    1580             :         unsigned char c[4];
+    1581             :         int i;
+    1582             : 
+    1583      216329 :         if (!mf) return mdio_seterror(MDIO_BADPARAMS);
+    1584             : 
+    1585      216329 :         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      216329 :         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      216329 :                 i = c[3] + (c[2] << 8) + (c[1] << 16) + (c[0] << 24);
+    1596             :                 memcpy(f, &i, 4);
+    1597             :         }
+    1598      216329 :         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       10116 : static int xtc_data(md_file *mf, char *buf, int len) {
+    1605       10116 :         if (!mf || len < 1) return mdio_seterror(MDIO_BADPARAMS);
+    1606       10116 :   size_t slen = (size_t)len;
+    1607       10116 :         if (buf) {
+    1608       20232 :                 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       10116 :                 if (len % 4) {
+    1614        7822 :                         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       18399 : static int xtc_timestep(md_file *mf, md_ts *ts) {
+    1637             :         int n;
+    1638             :         float f, x[3], y[3], z[3];
+    1639             : 
+    1640       18399 :         int size = 0; // explicitly initialized to zero.
+    1641             :         float precision;
+    1642             : 
+    1643       18399 :         if (!mf || !ts) return mdio_seterror(MDIO_BADPARAMS);
+    1644       18399 :         if (!mf->f) return mdio_seterror(MDIO_BADPARAMS);
+    1645       18399 :         if (mf->fmt != MDFMT_XTC) return mdio_seterror(MDIO_WRONGFORMAT);
+    1646             : 
+    1647             :         // Check magic number
+    1648       18399 :         if (xtc_int(mf, &n) < 0) return -1;
+    1649       18197 :         if (n != XTC_MAGIC) return mdio_seterror(MDIO_BADFORMAT);
+    1650             : 
+    1651             :         // Get number of atoms
+    1652       18197 :         if (xtc_int(mf, &n) < 0) return -1;
+    1653       18197 :         ts->natoms = n;
+    1654             : 
+    1655             :         // Get the simulation step
+    1656       18197 :         if (xtc_int(mf, &n) < 0) return -1;
+    1657       18197 :         ts->step = n;
+    1658             : 
+    1659             :         // Get the time value
+    1660       18197 :         if (xtc_float(mf, &f) < 0) return -1;
+    1661       18197 :         ts->time = f;
+    1662             : 
+    1663             :         // Read the basis vectors of the box
+    1664       36394 :   if ( (xtc_float(mf, &x[0]) < 0) ||
+    1665       36394 :        (xtc_float(mf, &x[1]) < 0) ||
+    1666       36394 :        (xtc_float(mf, &x[2]) < 0) ||
+    1667       36394 :        (xtc_float(mf, &y[0]) < 0) ||
+    1668       36394 :        (xtc_float(mf, &y[1]) < 0) ||
+    1669       36394 :        (xtc_float(mf, &y[2]) < 0) ||
+    1670       36394 :        (xtc_float(mf, &z[0]) < 0) ||
+    1671       54591 :        (xtc_float(mf, &z[1]) < 0) ||
+    1672       18197 :        (xtc_float(mf, &z[2]) < 0) )
+    1673           0 :     return -1;
+    1674             :   // Allocate the box and convert the vectors.
+    1675       18197 :   ts->box = (md_box *) malloc(sizeof(md_box));
+    1676       18197 :   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       18197 :         ts->pos = (float *) malloc(sizeof(float) * 3 * ts->natoms);
+    1683       18197 :         if (!ts->pos) return mdio_seterror(MDIO_BADMALLOC);
+    1684       18197 :         n = xtc_3dfcoord(mf, ts->pos, &size, &precision);
+    1685       18197 :         if (n < 0) return -1;
+    1686             : 
+    1687             :         /* Now we're left with the job of scaling... */
+    1688    12333830 :         for (n = 0; n < ts->natoms * 3; n++)
+    1689    12315633 :                 ts->pos[n] *= ANGS_PER_NM;
+    1690             : 
+    1691       18197 :         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       10116 : 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       10116 :         bytes[0] = 1;
+    1738             :         nbits = 0;
+    1739       40464 :         for (i=0; i < nints; i++) {  
+    1740             :                 tmp = 0;
+    1741       91342 :                 for (bytecnt = 0; bytecnt < nbytes; bytecnt++) {
+    1742       60994 :                         tmp = bytes[bytecnt] * sizes[i] + tmp;
+    1743       60994 :                         bytes[bytecnt] = tmp & 0xff;
+    1744       60994 :                         tmp >>= 8;
+    1745             :                 }
+    1746       63674 :                 while (tmp != 0) {
+    1747       33326 :                         bytes[bytecnt++] = tmp & 0xff;
+    1748       33326 :                         tmp >>= 8;
+    1749             :                 }
+    1750             :                 nbytes = bytecnt;
+    1751             :         }
+    1752             :         num = 1;
+    1753       10116 :         nbytes--;
+    1754       45539 :         while (bytes[nbytes] >= num) {
+    1755       35423 :                 nbits++;
+    1756       35423 :                 num *= 2;
+    1757             :         }
+    1758       10116 :         return nbits + nbytes * 8;
+    1759             : }
+    1760             : 
+    1761             : // reads bits from a buffer.    
+    1762    18283863 : static int xtc_receivebits(int *buf, int nbits) {
+    1763             :         int cnt, num; 
+    1764             :         unsigned int lastbits, lastbyte;
+    1765             :         unsigned char * cbuf;
+    1766    18283863 :         int mask = (1 << nbits) -1;
+    1767             : 
+    1768    18283863 :         cbuf = ((unsigned char *)buf) + 3 * sizeof(*buf);
+    1769    18283863 :         cnt = buf[0];
+    1770    18283863 :         lastbits = (unsigned int) buf[1];
+    1771    18283863 :         lastbyte = (unsigned int) buf[2];
+    1772             : 
+    1773             :         num = 0;
+    1774    31162017 :         while (nbits >= 8) {
+    1775    12878154 :                 lastbyte = ( lastbyte << 8 ) | cbuf[cnt++];
+    1776    12878154 :                 num |=  (lastbyte >> lastbits) << (nbits - 8);
+    1777             :                 nbits -=8;
+    1778             :         }
+    1779    18283863 :         if (nbits > 0) {
+    1780     5405709 :                 if (lastbits < (unsigned int)nbits) {
+    1781     2552182 :                         lastbits += 8;
+    1782     2552182 :                         lastbyte = (lastbyte << 8) | cbuf[cnt++];
+    1783             :                 }
+    1784     5405709 :                 lastbits -= nbits;
+    1785     5405709 :                 num |= (lastbyte >> lastbits) & ((1 << nbits) -1);
+    1786             :         }
+    1787    18283863 :         num &= mask;
+    1788    18283863 :         buf[0] = cnt;
+    1789    18283863 :         buf[1] = lastbits;
+    1790    18283863 :         buf[2] = lastbyte;
+    1791    18283863 :         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     4097130 : 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     4097130 :         bytes[1] = bytes[2] = bytes[3] = 0;
+    1802             :         nbytes = 0;
+    1803    16607556 :         while (nbits > 8) {
+    1804    12510426 :                 bytes[nbytes++] = xtc_receivebits(buf, 8);
+    1805    12510426 :                 nbits -= 8;
+    1806             :         }
+    1807     4097130 :         if (nbits > 0) {
+    1808     4097130 :                 bytes[nbytes++] = xtc_receivebits(buf, nbits);
+    1809             :         }
+    1810    12291390 :         for (i = nints-1; i > 0; i--) {
+    1811             :                 num = 0;
+    1812    41409372 :                 for (j = nbytes-1; j >=0; j--) {
+    1813    33215112 :                         num = (num << 8) | bytes[j];
+    1814    33215112 :                         p = num / sizes[i];
+    1815    33215112 :                         bytes[j] = p;
+    1816    33215112 :                         num = num - p * sizes[i];
+    1817             :                 }
+    1818     8194260 :                 nums[i] = num;
+    1819             :         }
+    1820     4097130 :         nums[0] = bytes[0] | (bytes[1] << 8) | (bytes[2] << 16) | (bytes[3] << 24);
+    1821     4097130 : }
+    1822             : 
+    1823             : // function that actually reads and writes compressed coordinates    
+    1824       18197 : 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       18197 :         if (xtc_int(mf, &lsize) < 0) return -1;
+    1847             : 
+    1848       18197 :         if (*size != 0 && lsize != *size) return mdio_seterror(MDIO_BADFORMAT);
+    1849             : 
+    1850       18197 :         *size = lsize;
+    1851       18197 :         size3 = *size * 3;
+    1852       18197 :         if (*size <= 9) {
+    1853       16162 :                 for (i = 0; i < *size; i++) {
+    1854        8081 :                         if (xtc_float(mf, fp + (3 * i)) < 0) return -1;
+    1855        8081 :                         if (xtc_float(mf, fp + (3 * i) + 1) < 0) return -1;
+    1856        8081 :                         if (xtc_float(mf, fp + (3 * i) + 2) < 0) return -1;
+    1857             :                 }
+    1858             :                 return *size;
+    1859             :         }
+    1860       10116 :         xtc_float(mf, precision);
+    1861       10116 :         if (ip == NULL) {
+    1862         121 :                 ip = (int *)malloc(size3 * sizeof(*ip));
+    1863         121 :                 if (ip == NULL) return mdio_seterror(MDIO_BADMALLOC);
+    1864         121 :                 bufsize = (int) (size3 * 1.2);
+    1865         121 :                 buf = (int *)malloc(bufsize * sizeof(*buf));
+    1866         121 :                 if (buf == NULL) return mdio_seterror(MDIO_BADMALLOC);
+    1867         121 :                 oldsize = *size;
+    1868        9995 :         } 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       10116 :         buf[0] = buf[1] = buf[2] = 0;
+    1877             : 
+    1878       10116 :         xtc_int(mf, &(minint[0]));
+    1879       10116 :         xtc_int(mf, &(minint[1]));
+    1880       10116 :         xtc_int(mf, &(minint[2]));
+    1881             : 
+    1882       10116 :         xtc_int(mf, &(maxint[0]));
+    1883       10116 :         xtc_int(mf, &(maxint[1]));
+    1884       10116 :         xtc_int(mf, &(maxint[2]));
+    1885             :                 
+    1886       10116 :         sizeint[0] = maxint[0] - minint[0]+1;
+    1887       10116 :         sizeint[1] = maxint[1] - minint[1]+1;
+    1888       10116 :         sizeint[2] = maxint[2] - minint[2]+1;
+    1889             :         
+    1890             :         /* check if one of the sizes is to big to be multiplied */
+    1891       10116 :         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       10116 :                 bitsize = xtc_sizeofints(3, sizeint);
+    1898             :         }
+    1899             : 
+    1900       10116 :         xtc_int(mf, &smallidx);
+    1901       10116 :         smaller = xtc_magicints[FIRSTIDX > smallidx - 1 ? FIRSTIDX : smallidx - 1] / 2;
+    1902       10116 :         small = xtc_magicints[smallidx] / 2;
+    1903       10116 :         sizesmall[0] = sizesmall[1] = sizesmall[2] = xtc_magicints[smallidx];
+    1904             : 
+    1905             :         /* check for zero values that would yield corrupted data */
+    1906       10116 :         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       10116 :         if (xtc_int(mf, &(buf[0])) < 0) return -1;
+    1914             : 
+    1915       10116 :         if (xtc_data(mf, (char *) &buf[3], (int) buf[0]) < 0) return -1;
+    1916             : 
+    1917       10116 :         buf[0] = buf[1] = buf[2] = 0;
+    1918             : 
+    1919             :         lfp = fp;
+    1920       10116 :         inv_precision = 1.0f / (*precision);
+    1921             :         run = 0;
+    1922             :         i = 0;
+    1923       10116 :         lip = ip;
+    1924     1314957 :         while (i < lsize) {
+    1925     1304841 :                 thiscoord = (int *)(lip) + i * 3;
+    1926             : 
+    1927     1304841 :                 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     1304841 :                         xtc_receiveints(buf, 3, bitsize, sizeint, thiscoord);
+    1933             :                 }
+    1934             : 
+    1935     1304841 :                 i++;
+    1936     1304841 :                 thiscoord[0] += minint[0];
+    1937     1304841 :                 thiscoord[1] += minint[1];
+    1938     1304841 :                 thiscoord[2] += minint[2];
+    1939             : 
+    1940             :                 prevcoord[0] = thiscoord[0];
+    1941             :                 prevcoord[1] = thiscoord[1];
+    1942             :                 prevcoord[2] = thiscoord[2];
+    1943             :  
+    1944             : 
+    1945     1304841 :                 flag = xtc_receivebits(buf, 1);
+    1946             :                 is_smaller = 0;
+    1947     1304841 :                 if (flag == 1) {
+    1948      371466 :                         run = xtc_receivebits(buf, 5);
+    1949      371466 :                         is_smaller = run % 3;
+    1950      371466 :                         run -= is_smaller;
+    1951      371466 :                         is_smaller--;
+    1952             :                 }
+    1953     1304841 :                 if (run > 0) {
+    1954      784712 :                         thiscoord += 3;
+    1955     3577001 :                         for (k = 0; k < run; k+=3) {
+    1956     2792289 :                                 xtc_receiveints(buf, 3, smallidx, sizesmall, thiscoord);
+    1957     2792289 :                                 i++;
+    1958     2792289 :                                 thiscoord[0] += prevcoord[0] - small;
+    1959     2792289 :                                 thiscoord[1] += prevcoord[1] - small;
+    1960     2792289 :                                 thiscoord[2] += prevcoord[2] - small;
+    1961     2792289 :                                 if (k == 0) {
+    1962             :                                         /* interchange first with second atom for better
+    1963             :                                          * compression of water molecules
+    1964             :                                          */
+    1965      784712 :                                         tmp = thiscoord[0]; thiscoord[0] = prevcoord[0];
+    1966             :                                         prevcoord[0] = tmp;
+    1967      784712 :                                         tmp = thiscoord[1]; thiscoord[1] = prevcoord[1];
+    1968             :                                         prevcoord[1] = tmp;
+    1969      784712 :                                         tmp = thiscoord[2]; thiscoord[2] = prevcoord[2];
+    1970             :                                         prevcoord[2] = tmp;
+    1971      784712 :                                         *lfp++ = prevcoord[0] * inv_precision;
+    1972      784712 :                                         *lfp++ = prevcoord[1] * inv_precision;
+    1973      784712 :                                         *lfp++ = prevcoord[2] * inv_precision;
+    1974             : 
+    1975      784712 :                                         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     2792289 :                                 *lfp++ = thiscoord[0] * inv_precision;
+    1986     2792289 :                                 *lfp++ = thiscoord[1] * inv_precision;
+    1987     2792289 :                                 *lfp++ = thiscoord[2] * inv_precision;
+    1988             :                         }
+    1989             :                 } else {
+    1990      520129 :                         *lfp++ = thiscoord[0] * inv_precision;
+    1991      520129 :                         *lfp++ = thiscoord[1] * inv_precision;
+    1992      520129 :                         *lfp++ = thiscoord[2] * inv_precision;          
+    1993             :                 }
+    1994     1304841 :                 smallidx += is_smaller;
+    1995     1304841 :                 if (is_smaller < 0) {
+    1996             :                         small = smaller;
+    1997       81743 :                         if (smallidx > FIRSTIDX) {
+    1998       81743 :                                 smaller = xtc_magicints[smallidx - 1] /2;
+    1999             :                         } else {
+    2000             :                                 smaller = 0;
+    2001             :                         }
+    2002     1223098 :                 } else if (is_smaller > 0) {
+    2003             :                         smaller = small;
+    2004      147588 :                         small = xtc_magicints[smallidx] / 2;
+    2005             :                 }
+    2006     1304841 :                 sizesmall[0] = sizesmall[1] = sizesmall[2] = xtc_magicints[smallidx] ;
+    2007             :         }
+    2008             :         return 1;
+    2009             : }
+    2010             : }
+    2011             : }
+    2012             : #endif
+    2013             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/molfile/crdplugin.cpp.func-sort-c.html b/coverage-libs/molfile/crdplugin.cpp.func-sort-c.html new file mode 100644 index 000000000000..8f2307a84a13 --- /dev/null +++ b/coverage-libs/molfile/crdplugin.cpp.func-sort-c.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - molfile/crdplugin.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - molfile - crdplugin.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:558564.7 %
Date:2024-04-19 12:12:36Functions: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_initEv10176
_ZN4PLMD7molfile26molfile_crdplugin_registerEPvPFiS1_PNS0_11vmdplugin_tEE10176
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/molfile/crdplugin.cpp.func.html b/coverage-libs/molfile/crdplugin.cpp.func.html new file mode 100644 index 000000000000..fa84655659eb --- /dev/null +++ b/coverage-libs/molfile/crdplugin.cpp.func.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - molfile/crdplugin.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - molfile - crdplugin.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:558564.7 %
Date:2024-04-19 12:12:36Functions:5955.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7molfile22molfile_dcdplugin_finiEv0
_ZN4PLMD7molfile22molfile_dcdplugin_initEv10176
_ZN4PLMD7molfile26molfile_dcdplugin_registerEPvPFiS1_PNS0_11vmdplugin_tEE10176
_ZN4PLMD7molfileL12read_dcdstepEiiPfS1_S1_S1_iiPiS1_ii21
_ZN4PLMD7molfileL12skip_dcdstepEiiii0
_ZN4PLMD7molfileL13open_dcd_readEPKcS2_Pi1
_ZN4PLMD7molfileL13write_dcdstepEiiiiPKfS2_S2_PKdi0
_ZN4PLMD7molfileL14close_dcd_readEPiPf1
_ZN4PLMD7molfileL14open_dcd_writeEPKcS2_i0
_ZN4PLMD7molfileL14print_dcderrorEPKci0
_ZN4PLMD7molfileL14read_dcdheaderEiPiS1_S1_S1_PdS1_PS1_PPfS1_S1_1
_ZN4PLMD7molfileL14write_timestepEPvPKNS0_18molfile_timestep_tE0
_ZN4PLMD7molfileL15close_file_readEPv1
_ZN4PLMD7molfileL15write_dcdheaderEiPKciiidii0
_ZN4PLMD7molfileL16close_file_writeEPv0
_ZN4PLMD7molfileL16read_charmm_4dimEiii21
_ZN4PLMD7molfileL16read_fixed_atomsEiiiPKiiPKfPfS5_i0
_ZN4PLMD7molfileL18read_next_timestepEPviPNS0_18molfile_timestep_tE22
_ZN4PLMD7molfileL22read_charmm_extrablockEiiiPf21
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/molfile/dcdplugin.cpp.gcov.html b/coverage-libs/molfile/dcdplugin.cpp.gcov.html new file mode 100644 index 000000000000..1c82315d7ca2 --- /dev/null +++ b/coverage-libs/molfile/dcdplugin.cpp.gcov.html @@ -0,0 +1,1394 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - molfile/dcdplugin.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - molfile - dcdplugin.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:20146143.6 %
Date:2024-04-19 12:12:36Functions: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       10176 : VMDPLUGIN_API int VMDPLUGIN_init() {
+    1218             :   memset(&plugin, 0, sizeof(molfile_plugin_t));
+    1219       10176 :   plugin.abiversion = vmdplugin_ABIVERSION;
+    1220       10176 :   plugin.type = MOLFILE_PLUGIN_TYPE;
+    1221       10176 :   plugin.name = "dcd";
+    1222       10176 :   plugin.prettyname = "CHARMM,NAMD,XPLOR DCD Trajectory";
+    1223       10176 :   plugin.author = "Axel Kohlmeyer, Justin Gullingsrud, John Stone";
+    1224       10176 :   plugin.majorv = 1;
+    1225       10176 :   plugin.minorv = 18;
+    1226       10176 :   plugin.is_reentrant = VMDPLUGIN_THREADSAFE;
+    1227       10176 :   plugin.filename_extension = "dcd";
+    1228       10176 :   plugin.open_file_read = open_dcd_read;
+    1229       10176 :   plugin.read_next_timestep = read_next_timestep;
+    1230       10176 :   plugin.close_file_read = close_file_read;
+    1231       10176 :   plugin.open_file_write = open_dcd_write;
+    1232       10176 :   plugin.write_timestep = write_timestep;
+    1233       10176 :   plugin.close_file_write = close_file_write;
+    1234       10176 :   return VMDPLUGIN_SUCCESS;
+    1235             : }
+    1236             : 
+    1237       10176 : VMDPLUGIN_API int VMDPLUGIN_register(void *v, vmdplugin_register_cb cb) {
+    1238       10176 :   (*cb)(v, (vmdplugin_t *)&plugin);
+    1239       10176 :   return VMDPLUGIN_SUCCESS;
+    1240             : }
+    1241             : 
+    1242           0 : VMDPLUGIN_API int VMDPLUGIN_fini() {
+    1243           0 :   return VMDPLUGIN_SUCCESS;
+    1244             : }
+    1245             : 
+    1246             : }
+    1247             : }
+    1248             : 
+    1249             :   
+    1250             : #ifdef TEST_DCDPLUGIN
+    1251             : 
+    1252             : #include <sys/time.h>
+    1253             : 
+    1254             : /* get the time of day from the system clock, and store it (in seconds) */
+    1255             : double time_of_day(void) {
+    1256             : #if defined(_MSC_VER)
+    1257             :   double t;
+    1258             : 
+    1259             :   t = GetTickCount();
+    1260             :   t = t / 1000.0;
+    1261             : 
+    1262             :   return t;
+    1263             : #else
+    1264             :   struct timeval tm;
+    1265             :   struct timezone tz;
+    1266             : 
+    1267             :   gettimeofday(&tm, &tz);
+    1268             :   return((double)(tm.tv_sec) + (double)(tm.tv_usec)/1000000.0);
+    1269             : #endif
+    1270             : }
+    1271             : 
+    1272             : int main(int argc, char *argv[]) {
+    1273             :   molfile_timestep_t timestep;
+    1274             :   void *v;
+    1275             :   dcdhandle *dcd;
+    1276             :   int i, natoms;
+    1277             :   float sizeMB =0.0, totalMB = 0.0;
+    1278             :   double starttime, endtime, totaltime = 0.0;
+    1279             : 
+    1280             :   while (--argc) {
+    1281             :     ++argv; 
+    1282             :     natoms = 0;
+    1283             :     v = open_dcd_read(*argv, "dcd", &natoms);
+    1284             :     if (!v) {
+    1285             :       fprintf(stderr, "main) open_dcd_read failed for file %s\n", *argv);
+    1286             :       return 1;
+    1287             :     }
+    1288             :     dcd = (dcdhandle *)v;
+    1289             :     sizeMB = ((natoms * 3.0) * dcd->nsets * 4.0) / (1024.0 * 1024.0);
+    1290             :     totalMB += sizeMB; 
+    1291             :     printf("main) file: %s\n", *argv);
+    1292             :     printf("  %d atoms, %d frames, size: %6.1fMB\n", natoms, dcd->nsets, sizeMB);
+    1293             : 
+    1294             :     starttime = time_of_day();
+    1295             :     timestep.coords = (float *)malloc(3*sizeof(float)*natoms);
+    1296             :     for (i=0; i<dcd->nsets; i++) {
+    1297             :       int rc = read_next_timestep(v, natoms, &timestep);
+    1298             :       if (rc) {
+    1299             :         fprintf(stderr, "error in read_next_timestep on frame %d\n", i);
+    1300             :         return 1;
+    1301             :       }
+    1302             :     }
+    1303             :     endtime = time_of_day();
+    1304             :     close_file_read(v);
+    1305             :     totaltime += endtime - starttime;
+    1306             :     printf("  Time: %5.1f seconds\n", endtime - starttime);
+    1307             :     printf("  Speed: %5.1f MB/sec, %5.1f timesteps/sec\n", sizeMB / (endtime - starttime), (dcd->nsets / (endtime - starttime)));
+    1308             :   }
+    1309             :   printf("Overall Size: %6.1f MB\n", totalMB);
+    1310             :   printf("Overall Time: %6.1f seconds\n", totaltime);
+    1311             :   printf("Overall Speed: %5.1f MB/sec\n", totalMB / totaltime);
+    1312             :   return 0;
+    1313             : }
+    1314             :       
+    1315             : #endif
+    1316             : 
+    1317             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/molfile/endianswap.h.func-sort-c.html b/coverage-libs/molfile/endianswap.h.func-sort-c.html new file mode 100644 index 000000000000..0a08f674049b --- /dev/null +++ b/coverage-libs/molfile/endianswap.h.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - molfile/endianswap.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - molfile - endianswap.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:64812.5 %
Date:2024-04-19 12:12:36Functions:1425.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

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

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

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

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

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

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7molfile26molfile_gromacsplugin_finiEv0
_ZN4PLMD7molfile26molfile_gromacsplugin_initEv10176
_ZN4PLMD7molfile30molfile_gromacsplugin_registerEPvPFiS1_PNS0_11vmdplugin_tEE10176
_ZN4PLMD7molfileL13open_g96_readEPKcS2_Pi0
_ZN4PLMD7molfileL13open_gro_readEPKcS2_Pi0
_ZN4PLMD7molfileL13open_trr_readEPKcS2_Pi207
_ZN4PLMD7molfileL14close_g96_readEPv0
_ZN4PLMD7molfileL14close_gro_readEPv0
_ZN4PLMD7molfileL14close_trr_readEPv207
_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_tE18554
_ZN4PLMD7molfileL18read_g96_structureEPvPiPNS0_14molfile_atom_tE0
_ZN4PLMD7molfileL18read_gro_structureEPvPiPNS0_14molfile_atom_tE0
_ZN4PLMD7molfileL18write_gro_timestepEPvPKNS0_18molfile_timestep_tE0
_ZN4PLMD7molfileL18write_trr_timestepEPvPKNS0_18molfile_timestep_tE0
_ZN4PLMD7molfileL19write_gro_structureEPviPKNS0_14molfile_atom_tE0
_ZN4PLMD7molfileL26read_gro_molecule_metadataEPvPPNS0_18molfile_metadata_tE0
_ZN4PLMD7molfileL27convert_vmd_box_for_writingEPKNS0_18molfile_timestep_tEPfS4_S4_0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/molfile/gromacsplugin.cpp.gcov.html b/coverage-libs/molfile/gromacsplugin.cpp.gcov.html new file mode 100644 index 000000000000..74a5b81a5ee2 --- /dev/null +++ b/coverage-libs/molfile/gromacsplugin.cpp.gcov.html @@ -0,0 +1,937 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - molfile/gromacsplugin.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - molfile - gromacsplugin.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:10736029.7 %
Date:2024-04-19 12:12:36Functions: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         207 : 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         207 :     if (!strcmp(filetype, "trr"))
+     485             :       format = MDFMT_TRR;
+     486         202 :     else if (!strcmp(filetype, "trj"))
+     487             :       format = MDFMT_TRJ;
+     488         202 :     else if (!strcmp(filetype, "xtc"))
+     489             :       format = MDFMT_XTC;
+     490             :     else
+     491             :       return NULL;
+     492             : 
+     493         207 :     mf = mdio_open(filename, format);
+     494         207 :     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         207 :     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         207 :     *natoms = mdh.natoms;
+     506         207 :     gmx = new gmxdata;
+     507             :     memset(gmx,0,sizeof(gmxdata));
+     508         207 :     gmx->mf = mf;
+     509         207 :     gmx->natoms = mdh.natoms;
+     510         207 :     return gmx;
+     511             : }
+     512             : 
+     513       18554 : 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       18554 :   mdts.natoms = natoms;
+     518             : 
+     519       18554 :   if (mdio_timestep(gmx->mf, &mdts) < 0) {
+     520         207 :     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       18347 :   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       18347 :   if (ts) {
+     536       18347 :     if (mdts.pos) 
+     537       18347 :       memcpy(ts->coords, mdts.pos, 3 * sizeof(float) * gmx->natoms);
+     538             :     else 
+     539             :       printf("gromacsplugin) Warning: skipping empty timestep!\n");
+     540             : 
+     541       18347 :     if (mdts.box) {
+     542       18347 :       ts->A = mdts.box->A;
+     543       18347 :       ts->B = mdts.box->B;
+     544       18347 :       ts->C = mdts.box->C;
+     545       18347 :       ts->alpha = mdts.box->alpha;
+     546       18347 :       ts->beta = mdts.box->beta;
+     547       18347 :       ts->gamma = mdts.box->gamma;
+     548             :     }
+     549             :   }
+     550       18347 :   mdio_tsfree(&mdts);
+     551       18347 :   return MOLFILE_SUCCESS;
+     552             : }
+     553             : 
+     554         207 : static void close_trr_read(void *v) {
+     555             :   gmxdata *gmx = (gmxdata *)v;
+     556         207 :   mdio_close(gmx->mf);
+     557         207 :   delete gmx;
+     558         207 : }
+     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       10176 : VMDPLUGIN_API int VMDPLUGIN_init() {
+     684             :   // GRO plugin init
+     685             :   memset(&gro_plugin, 0, sizeof(molfile_plugin_t));
+     686       10176 :   gro_plugin.abiversion = vmdplugin_ABIVERSION;
+     687       10176 :   gro_plugin.type = MOLFILE_PLUGIN_TYPE;
+     688       10176 :   gro_plugin.name = "gro";
+     689       10176 :   gro_plugin.prettyname = "Gromacs GRO";
+     690       10176 :   gro_plugin.author = "David Norris, Justin Gullingsrud, Magnus Lundborg";
+     691       10176 :   gro_plugin.majorv = GROMACS_PLUGIN_MAJOR_VERSION;
+     692       10176 :   gro_plugin.minorv = GROMACS_PLUGIN_MINOR_VERSION;
+     693             :   gro_plugin.is_reentrant = VMDPLUGIN_THREADUNSAFE;
+     694       10176 :   gro_plugin.filename_extension = "gro";
+     695       10176 :   gro_plugin.open_file_read = open_gro_read;
+     696       10176 :   gro_plugin.read_structure = read_gro_structure;
+     697       10176 :   gro_plugin.read_next_timestep = read_gro_timestep;
+     698       10176 :   gro_plugin.close_file_read = close_gro_read;
+     699       10176 :   gro_plugin.open_file_write = open_gro_write;
+     700       10176 :   gro_plugin.write_structure = write_gro_structure;
+     701       10176 :   gro_plugin.write_timestep = write_gro_timestep;
+     702       10176 :   gro_plugin.close_file_write = close_gro_write;
+     703       10176 :   gro_plugin.read_molecule_metadata = read_gro_molecule_metadata;
+     704             : 
+     705             :   // G96 plugin init
+     706             :   memset(&g96_plugin, 0, sizeof(molfile_plugin_t));
+     707       10176 :   g96_plugin.abiversion = vmdplugin_ABIVERSION;
+     708       10176 :   g96_plugin.type = MOLFILE_PLUGIN_TYPE;
+     709       10176 :   g96_plugin.name = "g96";
+     710       10176 :   g96_plugin.prettyname = "Gromacs g96";
+     711       10176 :   g96_plugin.author = "David Norris, Justin Gullingsrud";
+     712       10176 :   g96_plugin.majorv = GROMACS_PLUGIN_MAJOR_VERSION;
+     713       10176 :   g96_plugin.minorv = GROMACS_PLUGIN_MINOR_VERSION;
+     714             :   g96_plugin.is_reentrant = VMDPLUGIN_THREADUNSAFE;
+     715       10176 :   g96_plugin.filename_extension = "g96";
+     716       10176 :   g96_plugin.open_file_read = open_g96_read;
+     717       10176 :   g96_plugin.read_structure = read_g96_structure;
+     718       10176 :   g96_plugin.read_next_timestep = read_g96_timestep;
+     719       10176 :   g96_plugin.close_file_read = close_g96_read;
+     720             : 
+     721             :   // TRR plugin
+     722             :   memset(&trr_plugin, 0, sizeof(molfile_plugin_t));
+     723       10176 :   trr_plugin.abiversion = vmdplugin_ABIVERSION;
+     724       10176 :   trr_plugin.type = MOLFILE_PLUGIN_TYPE;
+     725       10176 :   trr_plugin.name = "trr";
+     726       10176 :   trr_plugin.prettyname = "Gromacs TRR Trajectory";
+     727       10176 :   trr_plugin.author = "David Norris, Justin Gullingsrud, Axel Kohlmeyer";
+     728       10176 :   trr_plugin.majorv = GROMACS_PLUGIN_MAJOR_VERSION;
+     729       10176 :   trr_plugin.minorv = GROMACS_PLUGIN_MINOR_VERSION;
+     730             :   trr_plugin.is_reentrant = VMDPLUGIN_THREADUNSAFE;
+     731       10176 :   trr_plugin.filename_extension = "trr";
+     732       10176 :   trr_plugin.open_file_read = open_trr_read;
+     733       10176 :   trr_plugin.read_next_timestep = read_trr_timestep;
+     734       10176 :   trr_plugin.close_file_read = close_trr_read;
+     735       10176 :   trr_plugin.open_file_write = open_trr_write;
+     736       10176 :   trr_plugin.write_timestep = write_trr_timestep;
+     737       10176 :   trr_plugin.close_file_write = close_trr_write;
+     738             : 
+     739             :   // XTC plugin 
+     740             :   memset(&xtc_plugin, 0, sizeof(molfile_plugin_t));
+     741       10176 :   xtc_plugin.abiversion = vmdplugin_ABIVERSION;
+     742       10176 :   xtc_plugin.type = MOLFILE_PLUGIN_TYPE;
+     743       10176 :   xtc_plugin.name = "xtc";
+     744       10176 :   xtc_plugin.prettyname = "Gromacs XTC Compressed Trajectory";
+     745       10176 :   xtc_plugin.author = "David Norris, Justin Gullingsrud";
+     746       10176 :   xtc_plugin.majorv = GROMACS_PLUGIN_MAJOR_VERSION;
+     747       10176 :   xtc_plugin.minorv = GROMACS_PLUGIN_MINOR_VERSION;
+     748             :   xtc_plugin.is_reentrant = VMDPLUGIN_THREADUNSAFE;
+     749       10176 :   xtc_plugin.filename_extension = "xtc";
+     750       10176 :   xtc_plugin.open_file_read = open_trr_read;
+     751       10176 :   xtc_plugin.read_next_timestep = read_trr_timestep;
+     752       10176 :   xtc_plugin.close_file_read = close_trr_read;
+     753             : 
+     754             :   // TRJ plugin
+     755             :   memset(&trj_plugin, 0, sizeof(molfile_plugin_t));
+     756       10176 :   trj_plugin.abiversion = vmdplugin_ABIVERSION;
+     757       10176 :   trj_plugin.type = MOLFILE_PLUGIN_TYPE;
+     758       10176 :   trj_plugin.name = "trj";
+     759       10176 :   trj_plugin.prettyname = "Gromacs TRJ Trajectory";
+     760       10176 :   trj_plugin.author = "David Norris, Justin Gullingsrud";
+     761       10176 :   trj_plugin.majorv = GROMACS_PLUGIN_MAJOR_VERSION;
+     762       10176 :   trj_plugin.minorv = GROMACS_PLUGIN_MINOR_VERSION;
+     763             :   trj_plugin.is_reentrant = VMDPLUGIN_THREADUNSAFE;
+     764       10176 :   trj_plugin.filename_extension = "trj";
+     765       10176 :   trj_plugin.open_file_read = open_trr_read;
+     766       10176 :   trj_plugin.read_next_timestep = read_trr_timestep;
+     767       10176 :   trj_plugin.close_file_read = close_trr_read;
+     768             : 
+     769       10176 :   return 0;
+     770             : }
+     771             : 
+     772       10176 : VMDPLUGIN_API int VMDPLUGIN_register(void *v, vmdplugin_register_cb cb) {
+     773       10176 :   (*cb)(v, (vmdplugin_t *)&gro_plugin);
+     774       10176 :   (*cb)(v, (vmdplugin_t *)&g96_plugin);
+     775       10176 :   (*cb)(v, (vmdplugin_t *)&trr_plugin);
+     776       10176 :   (*cb)(v, (vmdplugin_t *)&trj_plugin);
+     777       10176 :   (*cb)(v, (vmdplugin_t *)&xtc_plugin);
+     778       10176 :   return 0;
+     779             : }
+     780             : 
+     781           0 : VMDPLUGIN_API int VMDPLUGIN_fini() {
+     782           0 :   return 0;
+     783             : }
+     784             : 
+     785             : }
+     786             : }
+     787             : 
+     788             : 
+     789             : #ifdef TEST_G96_PLUGIN
+     790             : 
+     791             : int main(int argc, char *argv[]) {
+     792             :   int natoms;
+     793             : 
+     794             :   molfile_timestep_t timestep;
+     795             :   void *v;
+     796             :   int i;
+     797             : 
+     798             :   if (argc < 2) return 1;
+     799             :   while (--argc) {
+     800             :     ++argv;
+     801             :     v = open_g96_read(*argv, "g96", &natoms);
+     802             :     if (!v) {
+     803             :       fprintf(stderr, "open_g96_read failed for file %s\n", *argv);
+     804             :       return 1;
+     805             :     }
+     806             :     timestep.coords = (float *)malloc(3*sizeof(float)*natoms);
+     807             :     i = 0;
+     808             :     while(!read_g96_timestep(v, natoms, &timestep)) {
+     809             :       ++i;
+     810             :     }
+     811             :     fprintf(stderr, "ended read_g96_timestep on step %d\n", i);
+     812             :     free(timestep.coords);
+     813             :     close_g96_read(v);
+     814             :   }
+     815             :   return 0;
+     816             : }
+     817             : 
+     818             : #endif
+     819             : 
+     820             : #ifdef TEST_TRR_PLUGIN
+     821             : 
+     822             : int main(int argc, char *argv[]) {
+     823             :   int natoms;
+     824             : 
+     825             :   molfile_timestep_t timestep;
+     826             :   void *v, *w;
+     827             :   int i;
+     828             : 
+     829             :   if (argc != 3) return 1;
+     830             :   v = open_trr_read(argv[1], "trr", &natoms);
+     831             :   if (!v) {
+     832             :     fprintf(stderr, "open_trr_read failed for file %s\n", argv[1]);
+     833             :     return 1;
+     834             :   }
+     835             :   timestep.coords = (float *)malloc(3*sizeof(float)*natoms);
+     836             :   w = open_trr_write(argv[2], "trr", natoms);
+     837             :   if (!w) {
+     838             :     fprintf(stderr, "open_trr_write failed for file %s\n", argv[2]);
+     839             :     return 1;
+     840             :   }
+     841             : 
+     842             :   i = 0;
+     843             :   while(!read_trr_timestep(v, natoms, &timestep)) {
+     844             :     ++i;
+     845             :     if (write_trr_timestep(w, &timestep)) {
+     846             :       fprintf(stderr, "write error\n");
+     847             :       return 1;
+     848             :     }
+     849             :   }
+     850             : 
+     851             :   fprintf(stderr, "ended read_trr_timestep on step %d\n", i);
+     852             :   free(timestep.coords);
+     853             :   close_trr_read(v);
+     854             :   close_trr_write(w);
+     855             :   return 0;
+     856             : }
+     857             : 
+     858             : #endif
+     859             : 
+     860             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/molfile/index-sort-f.html b/coverage-libs/molfile/index-sort-f.html new file mode 100644 index 000000000000..8780cf525543 --- /dev/null +++ b/coverage-libs/molfile/index-sort-f.html @@ -0,0 +1,174 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - molfile + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - molfileHitTotalCoverage
Test:plumed test coverage (other modules)Lines:861210440.9 %
Date:2024-04-19 12:12:36Functions:5612445.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7xdrfile15read_xtc_natomsEPcPi2
_ZN4PLMD7xdrfile8read_xtcEPNS0_7XDRFILEEiPiPfPA3_fS6_S4_30
_ZN4PLMD7xdrfile9write_xtcEPNS0_7XDRFILEEiifPA3_fS4_f72
_ZN4PLMD7xdrfileL10xtc_headerEPNS0_7XDRFILEEPiS3_Pfi104
_ZN4PLMD7xdrfileL9xtc_coordEPNS0_7XDRFILEEPiPA3_fS5_Pfi100
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/xdrfile/xdrfile_xtc.cpp.gcov.html b/coverage-libs/xdrfile/xdrfile_xtc.cpp.gcov.html new file mode 100644 index 000000000000..7c8fdc5bb642 --- /dev/null +++ b/coverage-libs/xdrfile/xdrfile_xtc.cpp.gcov.html @@ -0,0 +1,242 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - xdrfile/xdrfile_xtc.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - xdrfile - xdrfile_xtc.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:273381.8 %
Date:2024-04-19 12:12:36Functions: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/ActionWithMatrix.cpp.func-sort-c.html b/coverage/adjmat/ActionWithMatrix.cpp.func-sort-c.html new file mode 100644 index 000000000000..89fb5e57f3ba --- /dev/null +++ b/coverage/adjmat/ActionWithMatrix.cpp.func-sort-c.html @@ -0,0 +1,161 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/ActionWithMatrix.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - ActionWithMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:132132100.0 %
Date:2024-04-19 12:12:35Functions:192286.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat16ActionWithMatrixC1ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat16ActionWithMatrixD0Ev0
_ZN4PLMD6adjmat16ActionWithMatrixD1Ev0
_ZNK4PLMD6adjmat16ActionWithMatrix31getAllActionLabelsInMatrixChainERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EE16
_ZNK4PLMD6adjmat16ActionWithMatrix21getFirstMatrixInChainEv1253
_ZN4PLMD6adjmat16ActionWithMatrixC2ERKNS_13ActionOptionsE1458
_ZN4PLMD6adjmat16ActionWithMatrixD2Ev1458
_ZN4PLMD6adjmat16ActionWithMatrix16registerKeywordsERNS_8KeywordsE1527
_ZN4PLMD6adjmat16ActionWithMatrix16finishChainBuildEPNS_16ActionWithVectorE3296
_ZN4PLMD6adjmat16ActionWithMatrix15gatherProcessesERSt6vectorIdSaIdEE17475
_ZN4PLMD6adjmat16ActionWithMatrix13gatherThreadsERKjS3_RKSt6vectorIdSaIdEERS6_RNS_10MultiValueE19969
_ZN4PLMD6adjmat16ActionWithMatrix23updateAllNeighbourListsEv30962
_ZN4PLMD6adjmat16ActionWithMatrix24getTotalMatrixBookeepingERj30962
_ZN4PLMD6adjmat16ActionWithMatrix37transferNonZeroMatrixElementsToValuesERjRKSt6vectorIjSaIjEE30962
_ZN4PLMD6adjmat16ActionWithMatrix9calculateEv31003
_ZN4PLMD6adjmat16ActionWithMatrix23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSA_SA_SA_55927
_ZNK4PLMD6adjmat16ActionWithMatrix25gatherForcesOnStoredValueEPKNS_5ValueERKjRKNS_10MultiValueERSt6vectorIdSaIdEE210505
_ZNK4PLMD6adjmat16ActionWithMatrix17gatherStoredValueERKjS3_RKNS_10MultiValueES3_RSt6vectorIdSaIdEE387780
_ZNK4PLMD6adjmat16ActionWithMatrix17checkForTaskForceERKjPKNS_5ValueE721141
_ZNK4PLMD6adjmat16ActionWithMatrix11performTaskERKjRNS_10MultiValueE1378263
_ZNK4PLMD6adjmat16ActionWithMatrix19clearMatrixElementsERNS_10MultiValueE88127811
_ZNK4PLMD6adjmat16ActionWithMatrix7runTaskERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjjRNS_10MultiValueE88127811
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ActionWithMatrix.cpp.func.html b/coverage/adjmat/ActionWithMatrix.cpp.func.html new file mode 100644 index 000000000000..31f3094d8b53 --- /dev/null +++ b/coverage/adjmat/ActionWithMatrix.cpp.func.html @@ -0,0 +1,161 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/ActionWithMatrix.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - ActionWithMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:132132100.0 %
Date:2024-04-19 12:12:35Functions:192286.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat16ActionWithMatrix13gatherThreadsERKjS3_RKSt6vectorIdSaIdEERS6_RNS_10MultiValueE19969
_ZN4PLMD6adjmat16ActionWithMatrix15gatherProcessesERSt6vectorIdSaIdEE17475
_ZN4PLMD6adjmat16ActionWithMatrix16finishChainBuildEPNS_16ActionWithVectorE3296
_ZN4PLMD6adjmat16ActionWithMatrix16registerKeywordsERNS_8KeywordsE1527
_ZN4PLMD6adjmat16ActionWithMatrix23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSA_SA_SA_55927
_ZN4PLMD6adjmat16ActionWithMatrix23updateAllNeighbourListsEv30962
_ZN4PLMD6adjmat16ActionWithMatrix24getTotalMatrixBookeepingERj30962
_ZN4PLMD6adjmat16ActionWithMatrix37transferNonZeroMatrixElementsToValuesERjRKSt6vectorIjSaIjEE30962
_ZN4PLMD6adjmat16ActionWithMatrix9calculateEv31003
_ZN4PLMD6adjmat16ActionWithMatrixC1ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat16ActionWithMatrixC2ERKNS_13ActionOptionsE1458
_ZN4PLMD6adjmat16ActionWithMatrixD0Ev0
_ZN4PLMD6adjmat16ActionWithMatrixD1Ev0
_ZN4PLMD6adjmat16ActionWithMatrixD2Ev1458
_ZNK4PLMD6adjmat16ActionWithMatrix11performTaskERKjRNS_10MultiValueE1378263
_ZNK4PLMD6adjmat16ActionWithMatrix17checkForTaskForceERKjPKNS_5ValueE721141
_ZNK4PLMD6adjmat16ActionWithMatrix17gatherStoredValueERKjS3_RKNS_10MultiValueES3_RSt6vectorIdSaIdEE387780
_ZNK4PLMD6adjmat16ActionWithMatrix19clearMatrixElementsERNS_10MultiValueE88127811
_ZNK4PLMD6adjmat16ActionWithMatrix21getFirstMatrixInChainEv1253
_ZNK4PLMD6adjmat16ActionWithMatrix25gatherForcesOnStoredValueEPKNS_5ValueERKjRKNS_10MultiValueERSt6vectorIdSaIdEE210505
_ZNK4PLMD6adjmat16ActionWithMatrix31getAllActionLabelsInMatrixChainERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EE16
_ZNK4PLMD6adjmat16ActionWithMatrix7runTaskERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjjRNS_10MultiValueE88127811
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ActionWithMatrix.cpp.gcov.html b/coverage/adjmat/ActionWithMatrix.cpp.gcov.html new file mode 100644 index 000000000000..ee76570a6a65 --- /dev/null +++ b/coverage/adjmat/ActionWithMatrix.cpp.gcov.html @@ -0,0 +1,312 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/ActionWithMatrix.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - ActionWithMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:132132100.0 %
Date:2024-04-19 12:12:35Functions:192286.4 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "ActionWithMatrix.h"
+      23             : 
+      24             : namespace PLMD {
+      25             : namespace adjmat {
+      26             : 
+      27        1527 : void ActionWithMatrix::registerKeywords( Keywords& keys ) {
+      28        1527 :   ActionWithVector::registerKeywords( keys ); keys.use("ARG");
+      29        1527 : }
+      30             : 
+      31        1458 : ActionWithMatrix::ActionWithMatrix(const ActionOptions&ao):
+      32             :   Action(ao),
+      33             :   ActionWithVector(ao),
+      34        1458 :   next_action_in_chain(NULL),
+      35        1458 :   matrix_to_do_before(NULL),
+      36        1458 :   matrix_to_do_after(NULL)
+      37             : {
+      38        1458 : }
+      39             : 
+      40        1458 : ActionWithMatrix::~ActionWithMatrix() {
+      41        1458 :   if( matrix_to_do_before ) { matrix_to_do_before->matrix_to_do_after=NULL; matrix_to_do_before->next_action_in_chain=NULL; }
+      42        1458 : }
+      43             : 
+      44          16 : void ActionWithMatrix::getAllActionLabelsInMatrixChain( std::vector<std::string>& mylabels ) const {
+      45             :   bool found=false;
+      46          24 :   for(unsigned i=0; i<mylabels.size(); ++i) {
+      47           8 :     if( getLabel()==mylabels[i] ) { found=true; }
+      48             :   }
+      49          16 :   if( !found ) mylabels.push_back( getLabel() );
+      50          16 :   if( matrix_to_do_after ) matrix_to_do_after->getAllActionLabelsInMatrixChain( mylabels );
+      51          16 : }
+      52             : 
+      53       55927 : void ActionWithMatrix::setupStreamedComponents( const std::string& headstr, unsigned& nquants, unsigned& nmat, unsigned& maxcol, unsigned& nbookeeping ) {
+      54       55927 :   ActionWithVector::setupStreamedComponents( headstr, nquants, nmat, maxcol, nbookeeping );
+      55             : 
+      56      121726 :   for(int i=0; i<getNumberOfComponents(); ++i) {
+      57       65799 :     Value* myval=getPntrToComponent(i);
+      58       65799 :     if( myval->getRank()!=2 || myval->hasDerivatives() ) continue;
+      59       35382 :     myval->setPositionInMatrixStash(nmat); nmat++;
+      60       35382 :     if( !myval->valueIsStored() ) continue;
+      61        7787 :     if( myval->getShape()[1]>maxcol ) maxcol=myval->getShape()[1];
+      62             :     myval->setMatrixBookeepingStart(nbookeeping);
+      63        7787 :     nbookeeping += myval->getShape()[0]*( 1 + myval->getNumberOfColumns() );
+      64             :   }
+      65       55927 : }
+      66             : 
+      67        3296 : void ActionWithMatrix::finishChainBuild( ActionWithVector* act ) {
+      68        3296 :   ActionWithMatrix* am=dynamic_cast<ActionWithMatrix*>(act); if( !am || act==this ) return;
+      69             :   // Build the list that contains everything we are going to loop over in getTotalMatrixBookeepgin and updateAllNeighbourLists
+      70        2253 :   if( next_action_in_chain ) next_action_in_chain->finishChainBuild( act );
+      71             :   else {
+      72         880 :     next_action_in_chain=am;
+      73             :     // Build the list of things we are going to loop over in runTask
+      74         880 :     if( am->isAdjacencyMatrix() || act->getName()=="VSTACK" ) return ;
+      75         821 :     plumed_massert( !matrix_to_do_after, "cannot add " + act->getLabel() + " in " + getLabel() + " as have already added " + matrix_to_do_after->getLabel() );
+      76         821 :     matrix_to_do_after=am; am->matrix_to_do_before=this;
+      77             :   }
+      78             : }
+      79             : 
+      80        1253 : const ActionWithMatrix* ActionWithMatrix::getFirstMatrixInChain() const {
+      81        1253 :   if( !actionInChain() ) return this;
+      82         409 :   return matrix_to_do_before->getFirstMatrixInChain();
+      83             : }
+      84             : 
+      85       30962 : void ActionWithMatrix::getTotalMatrixBookeeping( unsigned& nbookeeping ) {
+      86       67905 :   for(int i=0; i<getNumberOfComponents(); ++i) {
+      87       36943 :     Value* myval=getPntrToComponent(i);
+      88       36943 :     if( myval->getRank()!=2 || myval->hasDerivatives() || !myval->valueIsStored() ) continue;
+      89        4775 :     myval->reshapeMatrixStore( getNumberOfColumns() );
+      90        4775 :     nbookeeping += myval->getShape()[0]*( 1 + myval->getNumberOfColumns() );
+      91             :   }
+      92       30962 :   if( next_action_in_chain ) next_action_in_chain->getTotalMatrixBookeeping( nbookeeping );
+      93       30962 : }
+      94             : 
+      95       31003 : void ActionWithMatrix::calculate() {
+      96       31003 :   if( actionInChain() ) return ;
+      97             :   // Update all the neighbour lists
+      98       17475 :   updateAllNeighbourLists();
+      99             :   // Setup the matrix indices
+     100       17475 :   unsigned nbookeeping=0; getTotalMatrixBookeeping( nbookeeping );
+     101       17475 :   if( matrix_bookeeping.size()!=nbookeeping ) matrix_bookeeping.resize( nbookeeping );
+     102             :   std::fill( matrix_bookeeping.begin(), matrix_bookeeping.end(), 0 );
+     103             :   // And run all the tasks
+     104       17475 :   runAllTasks();
+     105             : }
+     106             : 
+     107       30962 : void ActionWithMatrix::updateAllNeighbourLists() {
+     108       30962 :   updateNeighbourList();
+     109       30962 :   if( next_action_in_chain ) next_action_in_chain->updateAllNeighbourLists();
+     110       30962 : }
+     111             : 
+     112     1378263 : void ActionWithMatrix::performTask( const unsigned& task_index, MultiValue& myvals ) const {
+     113             :   std::vector<unsigned> & indices( myvals.getIndices() );
+     114     1378263 :   if( matrix_to_do_before ) {
+     115             :     plumed_dbg_assert( myvals.inVectorCall() );
+     116      714734 :     runEndOfRowJobs( task_index, indices, myvals );
+     117      714734 :     return;
+     118             :   }
+     119      663529 :   setupForTask( task_index, indices, myvals );
+     120             : 
+     121             :   // Now loop over the row of the matrix
+     122             :   unsigned ntwo_atoms = myvals.getSplitIndex();
+     123    29786304 :   for(unsigned i=1; i<ntwo_atoms; ++i) {
+     124             :     // This does everything in the stream that is done with single matrix elements
+     125    29122775 :     runTask( getLabel(), task_index, indices[i], myvals );
+     126             :     // Now clear only elements that are not accumulated over whole row
+     127    29122775 :     clearMatrixElements( myvals );
+     128             :   }
+     129             :   // This updates the jobs that need to be completed when we get to the end of a row of the matrix
+     130      663529 :   runEndOfRowJobs( task_index, indices, myvals );
+     131             : }
+     132             : 
+     133    88127811 : void ActionWithMatrix::runTask( const std::string& controller, const unsigned& current, const unsigned colno, MultiValue& myvals ) const {
+     134    88127811 :   double outval=0; myvals.setTaskIndex(current); myvals.setSecondTaskIndex( colno );
+     135    88127811 :   if( isActive() ) performTask( controller, current, colno, myvals );
+     136    88127811 :   bool hasval = !isAdjacencyMatrix();
+     137   181276313 :   for(int i=0; i<getNumberOfComponents(); ++i) {
+     138   149933202 :     if( fabs(myvals.get( getConstPntrToComponent(i)->getPositionInStream()) )>0 ) { hasval=true; break; }
+     139             :   }
+     140             : 
+     141    88127811 :   if( hasval ) {
+     142   273246963 :     for(int i=0; i<getNumberOfComponents(); ++i) {
+     143   192234105 :       const Value* myval=getConstPntrToComponent(i);
+     144   192234105 :       if( myval->getRank()!=2 || myval->hasDerivatives() || !myval->valueIsStored() ) continue;
+     145    14157640 :       unsigned matindex = myval->getPositionInMatrixStash(), matbook_start = myval->getMatrixBookeepingStart(), col_stash_index = colno;
+     146    14157640 :       if( colno>=myval->getShape()[0] ) col_stash_index = colno - myval->getShape()[0];
+     147    14157640 :       unsigned rowstart = matbook_start+current*(1+myval->getNumberOfColumns());
+     148    14157640 :       if( myval->forcesWereAdded() ) {
+     149     1551066 :         unsigned sind = myval->getPositionInStream(), find = myvals.getMatrixBookeeping()[rowstart];
+     150     1551066 :         double fforce = myval->getForce( myvals.getTaskIndex()*myval->getNumberOfColumns() + find );
+     151     1551066 :         if( getNumberOfColumns()>=myval->getShape()[1] ) fforce = myval->getForce( myvals.getTaskIndex()*myval->getShape()[1] + col_stash_index );
+     152    36043741 :         for(unsigned j=0; j<myvals.getNumberActive(sind); ++j) {
+     153    34492675 :           unsigned kindex = myvals.getActiveIndex(sind,j); myvals.addMatrixForce( matindex, kindex, fforce*myvals.getDerivative(sind,kindex ) );
+     154             :         }
+     155             :       }
+     156    14157640 :       double finalval = myvals.get( myval->getPositionInStream() );
+     157    14157640 :       if( fabs(finalval)>0 ) myvals.stashMatrixElement( matindex, rowstart, col_stash_index, finalval );
+     158             :     }
+     159             :   }
+     160    88127811 :   if( matrix_to_do_after ) matrix_to_do_after->runTask( controller, current, colno, myvals );
+     161    88127811 : }
+     162             : 
+     163       19969 : void ActionWithMatrix::gatherThreads( const unsigned& nt, const unsigned& bufsize, const std::vector<double>& omp_buffer, std::vector<double>& buffer, MultiValue& myvals ) {
+     164       19969 :   ActionWithVector::gatherThreads( nt, bufsize, omp_buffer, buffer, myvals );
+     165    64702649 :   for(unsigned i=0; i<matrix_bookeeping.size(); ++i) matrix_bookeeping[i] += myvals.getMatrixBookeeping()[i];
+     166       19969 : }
+     167             : 
+     168       17475 : void ActionWithMatrix::gatherProcesses( std::vector<double>& buffer ) {
+     169       17475 :   ActionWithVector::gatherProcesses( buffer );
+     170       17475 :   if( matrix_bookeeping.size()>0 && !runInSerial() ) comm.Sum( matrix_bookeeping );
+     171       17475 :   unsigned nval=0; transferNonZeroMatrixElementsToValues( nval, matrix_bookeeping );
+     172       17475 : }
+     173             : 
+     174       30962 : void ActionWithMatrix::transferNonZeroMatrixElementsToValues( unsigned& nval, const std::vector<unsigned>& matbook ) {
+     175       67905 :   for(int i=0; i<getNumberOfComponents(); ++i) {
+     176       36943 :     Value* myval=getPntrToComponent(i);
+     177       36943 :     if( myval->getRank()!=2 || myval->hasDerivatives() || !myval->valueIsStored() || getNumberOfColumns()>=myval->getShape()[1] ) continue;
+     178          99 :     unsigned nelements = myval->getShape()[0]*( 1 + myval->getNumberOfColumns() );
+     179     5060331 :     for(unsigned j=0; j<nelements; ++j) myval->setMatrixBookeepingElement( j, matbook[nval+j] );
+     180          99 :     nval += nelements;
+     181             :   }
+     182       30962 :   if( next_action_in_chain ) next_action_in_chain->transferNonZeroMatrixElementsToValues( nval, matbook );
+     183       30962 : }
+     184             : 
+     185      387780 : void ActionWithMatrix::gatherStoredValue( const unsigned& valindex, const unsigned& code, const MultiValue& myvals,
+     186             :     const unsigned& bufstart, std::vector<double>& buffer ) const {
+     187      387780 :   if( getConstPntrToComponent(valindex)->getRank()==1 ) { ActionWithVector::gatherStoredValue( valindex, code, myvals, bufstart, buffer ); return; }
+     188      228028 :   const Value* myval=getConstPntrToComponent(valindex);
+     189             :   unsigned ncols = myval->getNumberOfColumns(), matind = myval->getPositionInMatrixStash();
+     190      228028 :   unsigned matbook_start = myval->getMatrixBookeepingStart(), vindex = bufstart + code*myval->getNumberOfColumns();
+     191      228028 :   const std::vector<unsigned> & matbook( myvals.getMatrixBookeeping() ); unsigned nelements = matbook[matbook_start+code*(1+ncols)];
+     192      228028 :   if( ncols>=myval->getShape()[1] ) {
+     193             :     // In this case we store the full matrix
+     194     6458861 :     for(unsigned j=0; j<nelements; ++j) {
+     195     6265374 :       unsigned jind = matbook[matbook_start+code*(1+ncols)+1+j];
+     196             :       plumed_dbg_massert( vindex+j<buffer.size(), "failing in " + getLabel() + " on value " + myval->getName() );
+     197     6265374 :       buffer[vindex + jind] += myvals.getStashedMatrixElement( matind, jind );
+     198             :     }
+     199             :   } else {
+     200             :     // This is for storing sparse matrices when we can
+     201      656601 :     for(unsigned j=0; j<nelements; ++j) {
+     202      622060 :       unsigned jind = matbook[matbook_start+code*(1+ncols)+1+j];
+     203             :       plumed_dbg_massert( vindex+j<buffer.size(), "failing in " + getLabel() + " on value " + myval->getName() );
+     204      622060 :       buffer[vindex + j] += myvals.getStashedMatrixElement( matind, jind );
+     205             :     }
+     206             :   }
+     207             : }
+     208             : 
+     209      721141 : bool ActionWithMatrix::checkForTaskForce( const unsigned& itask, const Value* myval ) const {
+     210      721141 :   if( myval->getRank()<2 ) return ActionWithVector::checkForTaskForce( itask, myval );
+     211      479889 :   unsigned nelements = myval->getRowLength(itask), startr = itask*myval->getNumberOfColumns();
+     212    10439083 :   for(unsigned j=0; j<nelements; ++j ) {
+     213    10051254 :     if( fabs( myval->getForce( startr + j ) )>epsilon ) return true;
+     214             :   }
+     215             :   return false;
+     216             : }
+     217             : 
+     218      210505 : void ActionWithMatrix::gatherForcesOnStoredValue( const Value* myval, const unsigned& itask, const MultiValue& myvals, std::vector<double>& forces ) const {
+     219      210505 :   if( myval->getRank()==1 ) { ActionWithVector::gatherForcesOnStoredValue( myval, itask, myvals, forces ); return; }
+     220             :   unsigned matind = myval->getPositionInMatrixStash();
+     221   842701414 :   for(unsigned j=0; j<forces.size(); ++j) forces[j] += myvals.getStashedMatrixForce( matind, j );
+     222             : }
+     223             : 
+     224    88127811 : void ActionWithMatrix::clearMatrixElements( MultiValue& myvals ) const {
+     225    88127811 :   if( isActive() ) {
+     226   297282803 :     for(int i=0; i<getNumberOfComponents(); ++i) {
+     227   210231454 :       const Value* myval=getConstPntrToComponent(i);
+     228   210231454 :       if( myval->getRank()==2 && !myval->hasDerivatives() ) myvals.clearDerivatives( myval->getPositionInStream() );
+     229             :     }
+     230             :   }
+     231    88127811 :   if( matrix_to_do_after ) matrix_to_do_after->clearMatrixElements( myvals );
+     232    88127811 : }
+     233             : 
+     234             : }
+     235             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ActionWithMatrix.h.func-sort-c.html b/coverage/adjmat/ActionWithMatrix.h.func-sort-c.html new file mode 100644 index 000000000000..110ef6b0fc8a --- /dev/null +++ b/coverage/adjmat/ActionWithMatrix.h.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/ActionWithMatrix.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - ActionWithMatrix.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2727100.0 %
Date:2024-04-19 12:12:35Functions:66100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat16ActionWithMatrix19updateNeighbourListEv19266
_ZNK4PLMD6adjmat16ActionWithMatrix29addDerivativeOnMatrixArgumentERKbRKjS5_S5_S5_RKdRNS_10MultiValueE56805054
_ZNK4PLMD6adjmat16ActionWithMatrix29addDerivativeOnVectorArgumentERKbRKjS5_S5_RKdRNS_10MultiValueE65113141
_ZNK4PLMD6adjmat16ActionWithMatrix17isAdjacencyMatrixEv66883420
_ZNK4PLMD6adjmat16ActionWithMatrix26getElementOfMatrixArgumentERKjS3_S3_RKNS_10MultiValueE114128669
_ZNK4PLMD6adjmat16ActionWithMatrix18getArgumentElementERKjS3_RKNS_10MultiValueE135978472
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ActionWithMatrix.h.func.html b/coverage/adjmat/ActionWithMatrix.h.func.html new file mode 100644 index 000000000000..4e6fee58ce38 --- /dev/null +++ b/coverage/adjmat/ActionWithMatrix.h.func.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/ActionWithMatrix.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - ActionWithMatrix.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2727100.0 %
Date:2024-04-19 12:12:35Functions:66100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat16ActionWithMatrix19updateNeighbourListEv19266
_ZNK4PLMD6adjmat16ActionWithMatrix17isAdjacencyMatrixEv66883420
_ZNK4PLMD6adjmat16ActionWithMatrix18getArgumentElementERKjS3_RKNS_10MultiValueE135978472
_ZNK4PLMD6adjmat16ActionWithMatrix26getElementOfMatrixArgumentERKjS3_S3_RKNS_10MultiValueE114128669
_ZNK4PLMD6adjmat16ActionWithMatrix29addDerivativeOnMatrixArgumentERKbRKjS5_S5_S5_RKdRNS_10MultiValueE56805054
_ZNK4PLMD6adjmat16ActionWithMatrix29addDerivativeOnVectorArgumentERKbRKjS5_S5_RKdRNS_10MultiValueE65113141
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ActionWithMatrix.h.gcov.html b/coverage/adjmat/ActionWithMatrix.h.gcov.html new file mode 100644 index 000000000000..d217a5814fc4 --- /dev/null +++ b/coverage/adjmat/ActionWithMatrix.h.gcov.html @@ -0,0 +1,227 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/ActionWithMatrix.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - ActionWithMatrix.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2727100.0 %
Date:2024-04-19 12:12:35Functions:66100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_adjmat_ActionWithMatrix_h
+      23             : #define __PLUMED_adjmat_ActionWithMatrix_h
+      24             : 
+      25             : #include "core/ActionWithVector.h"
+      26             : 
+      27             : namespace PLMD {
+      28             : namespace adjmat {
+      29             : 
+      30             : class ActionWithMatrix : public ActionWithVector {
+      31             : private:
+      32             :   ActionWithMatrix* next_action_in_chain;
+      33             :   ActionWithMatrix* matrix_to_do_before;
+      34             :   ActionWithMatrix* matrix_to_do_after;
+      35             : /// This holds the bookeeping arrays for sparse matrices
+      36             :   std::vector<unsigned> matrix_bookeeping;
+      37             : /// Update all the neighbour lists in the chain
+      38             :   void updateAllNeighbourLists();
+      39             : /// This is used to clear up the matrix elements
+      40             :   void clearMatrixElements( MultiValue& myvals ) const ;
+      41             : /// This is used to find the total amount of space we need for storing matrix elements
+      42             :   void getTotalMatrixBookeeping( unsigned& stashsize );
+      43             : /// This transfers the non-zero elements to the Value
+      44             :   void transferNonZeroMatrixElementsToValues( unsigned& nval, const std::vector<unsigned>& matbook );
+      45             : /// This does the calculation of a particular matrix element
+      46             :   void runTask( const std::string& controller, const unsigned& current, const unsigned colno, MultiValue& myvals ) const ;
+      47             : protected:
+      48             : /// Does the matrix chain continue on from this action
+      49             :   bool matrixChainContinues() const ;
+      50             : /// This returns the jelem th element of argument ic
+      51             :   double getArgumentElement( const unsigned& ic, const unsigned& jelem, const MultiValue& myvals ) const ;
+      52             : /// This returns an element of a matrix that is passed an argument
+      53             :   double getElementOfMatrixArgument( const unsigned& imat, const unsigned& irow, const unsigned& jcol, const MultiValue& myvals ) const ;
+      54             : /// Add derivatives given the derivative wrt to the input vector element as input
+      55             :   void addDerivativeOnVectorArgument( const bool& inchain, const unsigned& ival, const unsigned& jarg, const unsigned& jelem, const double& der, MultiValue& myvals ) const ;
+      56             : /// Add derivatives given the derative wrt to the input matrix element as input
+      57             :   void addDerivativeOnMatrixArgument( const bool& inchain, const unsigned& ival, const unsigned& jarg, const unsigned& irow, const unsigned& jcol, const double& der, MultiValue& myvals ) const ;
+      58             : public:
+      59             :   static void registerKeywords( Keywords& keys );
+      60             :   explicit ActionWithMatrix(const ActionOptions&);
+      61             :   virtual ~ActionWithMatrix();
+      62             : ///
+      63    66883420 :   virtual bool isAdjacencyMatrix() const { return false; }
+      64             : ///
+      65             :   void getAllActionLabelsInMatrixChain( std::vector<std::string>& mylabels ) const override ;
+      66             : /// Get the first matrix in this chain
+      67             :   const ActionWithMatrix* getFirstMatrixInChain() const ;
+      68             : ///
+      69             :   void finishChainBuild( ActionWithVector* act );
+      70             : /// This should return the number of columns to help with sparse storage of matrices
+      71             :   virtual unsigned getNumberOfColumns() const = 0;
+      72             : /// This requires some thought
+      73             :   void setupStreamedComponents( const std::string& headstr, unsigned& nquants, unsigned& nmat, unsigned& maxcol, unsigned& nbookeeping ) override;
+      74             : //// This does some setup before we run over the row of the matrix
+      75             :   virtual void setupForTask( const unsigned& task_index, std::vector<unsigned>& indices, MultiValue& myvals ) const = 0;
+      76             : /// Run over one row of the matrix
+      77             :   void performTask( const unsigned& task_index, MultiValue& myvals ) const override ;
+      78             : /// Gather a row of the matrix
+      79             :   void gatherStoredValue( const unsigned& valindex, const unsigned& code, const MultiValue& myvals, const unsigned& bufstart, std::vector<double>& buffer ) const override;
+      80             : /// Gather all the data from the threads
+      81             :   void gatherThreads( const unsigned& nt, const unsigned& bufsize, const std::vector<double>& omp_buffer, std::vector<double>& buffer, MultiValue& myvals ) override ;
+      82             : /// Gather all the data from the MPI processes
+      83             :   void gatherProcesses( std::vector<double>& buffer ) override;
+      84             : /// This is the virtual that will do the calculation of the task for a particular matrix element
+      85             :   virtual void performTask( const std::string& controller, const unsigned& index1, const unsigned& index2, MultiValue& myvals ) const = 0;
+      86             : /// This is the jobs that need to be done when we have run all the jobs in a row of the matrix
+      87             :   virtual void runEndOfRowJobs( const unsigned& ival, const std::vector<unsigned> & indices, MultiValue& myvals ) const = 0;
+      88             : /// This is overwritten in Adjacency matrix where we have a neighbour list
+      89       19266 :   virtual void updateNeighbourList() {}
+      90             : /// Run the calculation
+      91             :   virtual void calculate() override;
+      92             : /// Check if there are forces we need to account for on this task
+      93             :   bool checkForTaskForce( const unsigned& itask, const Value* myval ) const override ;
+      94             : /// This gathers the force on a particular value
+      95             :   void gatherForcesOnStoredValue( const Value* myval, const unsigned& itask, const MultiValue& myvals, std::vector<double>& forces ) const override;
+      96             : };
+      97             : 
+      98             : inline
+      99             : bool ActionWithMatrix::matrixChainContinues() const {
+     100      552731 :   return matrix_to_do_after!=NULL;
+     101             : }
+     102             : 
+     103             : inline
+     104   135978472 : double ActionWithMatrix::getArgumentElement( const unsigned& ic, const unsigned& jelem, const MultiValue& myvals ) const {
+     105   135978472 :   if( !getPntrToArgument(ic)->valueHasBeenSet() ) return myvals.get( getPntrToArgument(ic)->getPositionInStream() );
+     106   134706597 :   return getPntrToArgument(ic)->get( jelem );
+     107             : }
+     108             : 
+     109             : inline
+     110   114128669 : double ActionWithMatrix::getElementOfMatrixArgument( const unsigned& imat, const unsigned& irow, const unsigned& jcol, const MultiValue& myvals ) const {
+     111             :   plumed_dbg_assert( imat<getNumberOfArguments() && getPntrToArgument(imat)->getRank()==2 && !getPntrToArgument(imat)->hasDerivatives() );
+     112   114128669 :   if( !getPntrToArgument(imat)->valueHasBeenSet() ) return myvals.get( getPntrToArgument(imat)->getPositionInStream() );
+     113    31610552 :   return getArgumentElement( imat, irow*getPntrToArgument(imat)->getShape()[1] + jcol, myvals );
+     114             : }
+     115             : 
+     116             : inline
+     117    65113141 : void ActionWithMatrix::addDerivativeOnVectorArgument( const bool& inchain, const unsigned& ival, const unsigned& jarg, const unsigned& jelem, const double& der, MultiValue& myvals ) const {
+     118             :   plumed_dbg_massert( jarg<getNumberOfArguments() && getPntrToArgument(jarg)->getRank()<2, "failing in action " + getName() + " with label " + getLabel() );
+     119    65113141 :   unsigned ostrn = getConstPntrToComponent(ival)->getPositionInStream(), vstart=arg_deriv_starts[jarg];
+     120    65113141 :   if( !inchain ) {
+     121    64256694 :     myvals.addDerivative( ostrn, vstart + jelem, der ); myvals.updateIndex( ostrn, vstart + jelem );
+     122             :   } else {
+     123             :     unsigned istrn = getPntrToArgument(jarg)->getPositionInStream();
+     124    81995412 :     for(unsigned k=0; k<myvals.getNumberActive(istrn); ++k) {
+     125    81138965 :       unsigned kind=myvals.getActiveIndex(istrn,k);
+     126    81138965 :       myvals.addDerivative( ostrn, arg_deriv_starts[jarg] + kind, der*myvals.getDerivative( istrn, kind ) );
+     127    81138965 :       myvals.updateIndex( ostrn, arg_deriv_starts[jarg] + kind );
+     128             :     }
+     129             :   }
+     130    65113141 : }
+     131             : 
+     132             : inline
+     133    56805054 : void ActionWithMatrix::addDerivativeOnMatrixArgument( const bool& inchain, const unsigned& ival, const unsigned& jarg, const unsigned& irow, const unsigned& jcol, const double& der, MultiValue& myvals ) const {
+     134             :   plumed_dbg_assert( jarg<getNumberOfArguments() && getPntrToArgument(jarg)->getRank()==2 && !getPntrToArgument(jarg)->hasDerivatives() );
+     135    56805054 :   unsigned ostrn = getConstPntrToComponent(ival)->getPositionInStream(), vstart=arg_deriv_starts[jarg];
+     136    56805054 :   if( !inchain ) {
+     137     2243240 :     unsigned dloc = vstart + irow*getPntrToArgument(jarg)->getShape()[1] + jcol;
+     138     2243240 :     myvals.addDerivative( ostrn, dloc, der ); myvals.updateIndex( ostrn, dloc );
+     139             :   } else {
+     140             :     unsigned istrn = getPntrToArgument(jarg)->getPositionInStream();
+     141   353992585 :     for(unsigned k=0; k<myvals.getNumberActive(istrn); ++k) {
+     142   299430771 :       unsigned kind=myvals.getActiveIndex(istrn,k);
+     143   299430771 :       myvals.addDerivative( ostrn, kind, der*myvals.getDerivative( istrn, kind ) );
+     144             :     }
+     145             :   }
+     146    56805054 : }
+     147             : 
+     148             : }
+     149             : }
+     150             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/AdjacencyMatrixBase.cpp.func-sort-c.html b/coverage/adjmat/AdjacencyMatrixBase.cpp.func-sort-c.html new file mode 100644 index 000000000000..65dee752f6be --- /dev/null +++ b/coverage/adjmat/AdjacencyMatrixBase.cpp.func-sort-c.html @@ -0,0 +1,129 @@ + + + + + + + + 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:211211100.0 %
Date:2024-04-19 12:12:35Functions:131492.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat19AdjacencyMatrixBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat19AdjacencyMatrixBase19setupThirdAtomBlockERKSt6vectorINS_10AtomNumberESaIS3_EERS5_24
_ZN4PLMD6adjmat19AdjacencyMatrixBase26getAdditionalTasksRequiredEPNS_16ActionWithVectorERSt6vectorIjSaIjEE216
_ZN4PLMD6adjmat19AdjacencyMatrixBase17setLinkCellCutoffERKbRKdd324
_ZN4PLMD6adjmat19AdjacencyMatrixBaseC2ERKNS_13ActionOptionsE324
_ZN4PLMD6adjmat19AdjacencyMatrixBase16registerKeywordsERNS_8KeywordsE353
_ZN4PLMD6adjmat19AdjacencyMatrixBase22getNumberOfDerivativesEv11081
_ZN4PLMD6adjmat19AdjacencyMatrixBase7prepareEv11700
_ZN4PLMD6adjmat19AdjacencyMatrixBase19updateNeighbourListEv11750
_ZNK4PLMD6adjmat19AdjacencyMatrixBase18getNumberOfColumnsEv284222
_ZNK4PLMD6adjmat19AdjacencyMatrixBase12setupForTaskERKjRSt6vectorIjSaIjEERNS_10MultiValueE405876
_ZNK4PLMD6adjmat19AdjacencyMatrixBase15runEndOfRowJobsERKjRKSt6vectorIjSaIjEERNS_10MultiValueE405876
_ZNK4PLMD6adjmat19AdjacencyMatrixBase18retrieveNeighboursERKjRSt6vectorIjSaIjEE409666
_ZNK4PLMD6adjmat19AdjacencyMatrixBase11performTaskERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjSB_RNS_10MultiValueE21245263
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/AdjacencyMatrixBase.cpp.func.html b/coverage/adjmat/AdjacencyMatrixBase.cpp.func.html new file mode 100644 index 000000000000..bae0d364abff --- /dev/null +++ b/coverage/adjmat/AdjacencyMatrixBase.cpp.func.html @@ -0,0 +1,129 @@ + + + + + + + + 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:211211100.0 %
Date:2024-04-19 12:12:35Functions:131492.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat19AdjacencyMatrixBase16registerKeywordsERNS_8KeywordsE353
_ZN4PLMD6adjmat19AdjacencyMatrixBase17setLinkCellCutoffERKbRKdd324
_ZN4PLMD6adjmat19AdjacencyMatrixBase19setupThirdAtomBlockERKSt6vectorINS_10AtomNumberESaIS3_EERS5_24
_ZN4PLMD6adjmat19AdjacencyMatrixBase19updateNeighbourListEv11750
_ZN4PLMD6adjmat19AdjacencyMatrixBase22getNumberOfDerivativesEv11081
_ZN4PLMD6adjmat19AdjacencyMatrixBase26getAdditionalTasksRequiredEPNS_16ActionWithVectorERSt6vectorIjSaIjEE216
_ZN4PLMD6adjmat19AdjacencyMatrixBase7prepareEv11700
_ZN4PLMD6adjmat19AdjacencyMatrixBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat19AdjacencyMatrixBaseC2ERKNS_13ActionOptionsE324
_ZNK4PLMD6adjmat19AdjacencyMatrixBase11performTaskERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjSB_RNS_10MultiValueE21245263
_ZNK4PLMD6adjmat19AdjacencyMatrixBase12setupForTaskERKjRSt6vectorIjSaIjEERNS_10MultiValueE405876
_ZNK4PLMD6adjmat19AdjacencyMatrixBase15runEndOfRowJobsERKjRKSt6vectorIjSaIjEERNS_10MultiValueE405876
_ZNK4PLMD6adjmat19AdjacencyMatrixBase18getNumberOfColumnsEv284222
_ZNK4PLMD6adjmat19AdjacencyMatrixBase18retrieveNeighboursERKjRSt6vectorIjSaIjEE409666
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/AdjacencyMatrixBase.cpp.gcov.html b/coverage/adjmat/AdjacencyMatrixBase.cpp.gcov.html new file mode 100644 index 000000000000..801cc191c9e1 --- /dev/null +++ b/coverage/adjmat/AdjacencyMatrixBase.cpp.gcov.html @@ -0,0 +1,470 @@ + + + + + + + + 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:211211100.0 %
Date:2024-04-19 12:12:35Functions:131492.9 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2020 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received 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 "core/PlumedMain.h"
+      24             : #include "tools/Communicator.h"
+      25             : #include "tools/OpenMP.h"
+      26             : 
+      27             : namespace PLMD {
+      28             : namespace adjmat {
+      29             : 
+      30         353 : void AdjacencyMatrixBase::registerKeywords( Keywords& keys ) {
+      31         353 :   ActionWithMatrix::registerKeywords( keys ); keys.remove("ARG");
+      32         706 :   keys.add("atoms","GROUP","the atoms for which you would like to calculate the adjacency matrix");
+      33         706 :   keys.add("atoms","GROUPA","");
+      34         706 :   keys.add("atoms","GROUPB","");
+      35         706 :   keys.add("atoms-2","ATOMS","the atoms for which you would like to calculate the adjacency matrix. This is a depracated syntax that is equivalent to GROUP.  You are strongly recommened to use GROUP instead of ATOMS.");
+      36         706 :   keys.reserve("atoms","GROUPC","");
+      37         706 :   keys.addFlag("COMPONENTS",false,"also calculate the components of the vector connecting the atoms in the contact matrix");
+      38         706 :   keys.addFlag("NOPBC",false,"don't use pbc");
+      39         706 :   keys.add("compulsory","NL_CUTOFF","0.0","The cutoff for the neighbor list.  A value of 0 means we are not using a neighbor list");
+      40         706 :   keys.add("compulsory","NL_STRIDE","1","The frequency with which we are updating the atoms in the neighbor list");
+      41         706 :   keys.addOutputComponent("w","COMPONENTS","the weight of the connection");
+      42         706 :   keys.addOutputComponent("x","COMPONENTS","the projection of the bond on the x axis");
+      43         706 :   keys.addOutputComponent("y","COMPONENTS","the projection of the bond on the y axis");
+      44         706 :   keys.addOutputComponent("z","COMPONENTS","the projection of the bond on the z axis");
+      45         353 : }
+      46             : 
+      47         324 : AdjacencyMatrixBase::AdjacencyMatrixBase(const ActionOptions& ao):
+      48             :   Action(ao),
+      49             :   ActionWithMatrix(ao),
+      50         324 :   read_one_group(false),
+      51         324 :   neighbour_list_updated(false),
+      52         324 :   linkcells(comm),
+      53         324 :   threecells(comm),
+      54         648 :   natoms_per_list(0)
+      55             : {
+      56         648 :   std::vector<unsigned> shape(2); std::vector<AtomNumber> t; parseAtomList("GROUP", t );
+      57         324 :   if( t.size()==0 ) {
+      58         272 :     parseAtomList("ATOMS", t);
+      59         136 :     if( t.size()>0 ) warning("using depracated syntax for contact matrix.  You are strongly recommended to use GROUP instead of ATOMS");
+      60             :   }
+      61             : 
+      62         324 :   if( t.size()==0 ) {
+      63         272 :     std::vector<AtomNumber> ta; parseAtomList("GROUPA",ta);
+      64         272 :     std::vector<AtomNumber> tb; parseAtomList("GROUPB",tb);
+      65         136 :     if( ta.size()==0 || tb.size()==0 ) error("no atoms have been specified in input");
+      66             : 
+      67             :     // Create list of tasks
+      68         136 :     log.printf("  atoms in GROUPA ");
+      69        2270 :     for(unsigned i=0; i<ta.size(); ++i) { log.printf("%d ", ta[i].serial()); t.push_back(ta[i]); }
+      70         136 :     log.printf("\n");
+      71         136 :     log.printf("  atoms in GROUPB "); ablocks.resize( tb.size() ); unsigned n=0;
+      72       13747 :     for(unsigned i=0; i<tb.size(); ++i) {
+      73       13611 :       log.printf("%d ", tb[i].serial());
+      74       13611 :       ablocks[i]=ta.size()+n; t.push_back(tb[i]); n++;
+      75             :     }
+      76         136 :     log.printf("\n"); shape[0]=ta.size(); shape[1]=tb.size();
+      77             :   } else {
+      78             :     // Create list of tasks
+      79         188 :     log.printf("  atoms in GROUP "); ablocks.resize( t.size() );
+      80      112634 :     for(unsigned i=0; i<t.size(); ++i) { log.printf("%d ", t[i].serial()); ablocks[i]=i; }
+      81         188 :     log.printf("\n"); shape[0]=shape[1]=t.size(); read_one_group=true;
+      82             :   }
+      83         648 :   if( keywords.exists("GROUPC") ) {
+      84          12 :     std::vector<AtomNumber> tc; parseAtomList("GROUPC",tc);
+      85           6 :     if( tc.size()==0 ) error("no atoms in GROUPC specified");
+      86           6 :     log.printf("  atoms in GROUPC "); setupThirdAtomBlock( tc, t );
+      87         636 :   } else if( keywords.exists("BRIDGING_ATOMS") ) {
+      88          16 :     std::vector<AtomNumber> tc; parseAtomList("BRIDGING_ATOMS",tc);
+      89           8 :     if( tc.size()==0 ) error("no BRIDGING_ATOMS specified");
+      90           8 :     log.printf("  bridging atoms are "); setupThirdAtomBlock( tc, t );
+      91         620 :   } else if( keywords.exists("HYDROGENS") ) {
+      92           4 :     std::vector<AtomNumber> tc; parseAtomList("HYDROGENS",tc);
+      93           2 :     if( tc.size()==0 ) error("no HYDROGEN atoms specified");
+      94           2 :     log.printf("  hydrogen atoms are "); setupThirdAtomBlock( tc, t );
+      95         616 :   } else if( keywords.exists("BACKGROUND_ATOMS") ) {
+      96          16 :     std::vector<AtomNumber> tc; parseAtomList("BACKGROUND_ATOMS",tc);
+      97           8 :     if( tc.size()==0 ) error("no ATOMS atoms specified");
+      98           8 :     log.printf("  atoms for background density are "); setupThirdAtomBlock( tc, t );
+      99             :   }
+     100             :   // Request the atoms from the ActionAtomistic
+     101         648 :   requestAtoms( t ); parseFlag("COMPONENTS",components); parseFlag("NOPBC",nopbc);
+     102         324 :   if( !components ) { addValue( shape ); setNotPeriodic(); }
+     103         243 :   else { addComponent( "w", shape ); componentIsNotPeriodic("w"); }
+     104         324 :   getPntrToComponent(0)->setDerivativeIsZeroWhenValueIsZero();
+     105             :   // Stuff for neighbor list
+     106         648 :   parse("NL_CUTOFF",nl_cut); nl_cut2=nl_cut*nl_cut; parse("NL_STRIDE",nl_stride);
+     107         324 :   if( nl_cut==0 && nl_stride>1 ) error("NL_CUTOFF must be set if NL_STRIDE is set greater than 1");
+     108         324 :   if( nl_cut>0 ) log.printf("  using neighbor list with cutoff %f.  List is updated every %u steps.\n",nl_cut,nl_stride);
+     109             : 
+     110         324 :   if( components ) {
+     111         162 :     addComponent( "x", shape ); componentIsNotPeriodic("x");
+     112         162 :     addComponent( "y", shape ); componentIsNotPeriodic("y");
+     113         243 :     addComponent( "z", shape ); componentIsNotPeriodic("z");
+     114             :   }
+     115         648 :   log<<"  Bibliography "<<plumed.cite("Tribello, Giberti, Sosso, Salvalaglio and Parrinello, J. Chem. Theory Comput. 13, 1317 (2017)")<<"\n";
+     116         324 : }
+     117             : 
+     118       11081 : unsigned AdjacencyMatrixBase::getNumberOfDerivatives() {
+     119       11081 :   return 3*getNumberOfAtoms() + 9;
+     120             : }
+     121             : 
+     122          24 : void AdjacencyMatrixBase::setupThirdAtomBlock( const std::vector<AtomNumber>& tc, std::vector<AtomNumber>& t ) {
+     123          24 :   threeblocks.resize( tc.size() ); unsigned base=t.size();
+     124       53168 :   for(unsigned i=0; i<tc.size(); ++i) { log.printf("%d ", tc[i].serial()); t.push_back(tc[i]); threeblocks[i]=base+i; }
+     125          24 :   log.printf("\n");
+     126          24 : }
+     127             : 
+     128         324 : void AdjacencyMatrixBase::setLinkCellCutoff( const bool& symmetric, const double& lcut, double tcut ) {
+     129         324 :   if( read_one_group && symmetric ) getPntrToComponent(0)->setSymmetric( true );
+     130         324 :   if( nl_cut>0 && lcut>nl_cut ) error("D_MAX for switching functions should be shorter than neighbor list cutoff");
+     131             : 
+     132         324 :   if( tcut<0 ) tcut=lcut;
+     133         324 :   if( nl_cut>0 ) linkcells.setCutoff( nl_cut ); else linkcells.setCutoff( lcut );
+     134         324 :   if( linkcells.getCutoff()<std::numeric_limits<double>::max() ) log.printf("  set link cell cutoff to %f \n", linkcells.getCutoff() );
+     135         324 :   threecells.setCutoff( tcut );
+     136         324 : }
+     137             : 
+     138       11700 : void AdjacencyMatrixBase::prepare() {
+     139       11700 :   ActionWithVector::prepare(); neighbour_list_updated=false;
+     140       11700 : }
+     141             : 
+     142       11750 : void AdjacencyMatrixBase::updateNeighbourList() {
+     143       11750 :   neighbour_list_updated=true;
+     144             :   // Build link cells here so that this is done in stream if it needed in stream
+     145       11750 :   if( getStep()%nl_stride==0 ) {
+     146             :     // Build the link cells
+     147       11750 :     std::vector<Vector> ltmp_pos( ablocks.size() );
+     148     1194628 :     for(unsigned i=0; i<ablocks.size(); ++i) ltmp_pos[i]=ActionAtomistic::getPosition( ablocks[i] );
+     149       11750 :     linkcells.buildCellLists( ltmp_pos, ablocks, getPbc() );
+     150             :     // This ensures the link cell does not get too big.  We find the cell that contains the maximum number of atoms and multiply this by 27.
+     151             :     // In this way we ensure that the neighbour list doesn't get too big.  Also this number should always be large enough
+     152       11750 :     natoms_per_list = 27*linkcells.getMaxInCell();
+     153       11750 :     nlist.resize( getConstPntrToComponent(0)->getShape()[0]*( 2 + natoms_per_list ) );
+     154             :     // Set the number of neighbors to zero for all ranks
+     155       11750 :     nlist.assign(nlist.size(),0);
+     156             :     // Now get stuff to do parallel implementation
+     157       11750 :     unsigned stride=comm.Get_size(); unsigned rank=comm.Get_rank();
+     158       11750 :     if( runInSerial() ) { stride=1; rank=0; }
+     159       11750 :     unsigned nt=OpenMP::getNumThreads();
+     160       11750 :     if( nt*stride*10>getConstPntrToComponent(0)->getShape()[0] ) nt=getConstPntrToComponent(0)->getShape()[0]/stride/10;
+     161             :     if( nt==0 ) nt=1;
+     162             :     // Create a vector from the input set of tasks
+     163       11750 :     std::vector<unsigned> & pTaskList( getListOfActiveTasks(this) );
+     164             : 
+     165       11750 :     #pragma omp parallel num_threads(nt)
+     166             :     {
+     167             :       // Get the number of tasks we have to deal with
+     168             :       unsigned ntasks=getConstPntrToComponent(0)->getShape()[0];
+     169             :       if( nl_stride==1 ) ntasks=pTaskList.size();
+     170             :       // Build a tempory nlist so we can do omp parallelism
+     171             :       std::vector<unsigned> omp_nlist;
+     172             :       if( nt>1 ) omp_nlist.resize( nlist.size(), 0 );
+     173             :       // Now run over all atoms and construct the link cells
+     174             :       std::vector<Vector> t_atoms( 1+ablocks.size() );
+     175             :       std::vector<unsigned> indices( 1+ablocks.size() ), cells_required( linkcells.getNumberOfCells() );
+     176             :       #pragma omp for nowait
+     177             :       for(unsigned i=rank; i<ntasks; i+=stride) {
+     178             :         // Retrieve cells required from link cells - for matrix blocks
+     179             :         unsigned ncells_required=0;
+     180             :         linkcells.addRequiredCells( linkcells.findMyCell( ActionAtomistic::getPosition(pTaskList[i]) ), ncells_required, cells_required );
+     181             :         // Now get the indices of the atoms in the link cells positions
+     182             :         unsigned natoms=1; indices[0]=pTaskList[i];
+     183             :         linkcells.retrieveAtomsInCells( ncells_required, cells_required, natoms, indices );
+     184             :         if( nl_stride==1 ) {
+     185             :           if( nt>1 ) omp_nlist[indices[0]]=0; else nlist[indices[0]] = 0;
+     186             :           unsigned lstart = getConstPntrToComponent(0)->getShape()[0] + indices[0]*(1+natoms_per_list);
+     187             :           for(unsigned j=0; j<natoms; ++j) {
+     188             :             if( nt>1 ) { omp_nlist[ lstart + omp_nlist[indices[0]] ] = indices[j]; omp_nlist[indices[0]]++; }
+     189             :             else { nlist[ lstart + nlist[indices[0]] ] = indices[j]; nlist[indices[0]]++; }
+     190             :           }
+     191             :         } else {
+     192             :           // Get the positions of all the atoms in the link cells relative to the central atom
+     193             :           for(unsigned j=0; j<natoms; ++j) t_atoms[j] = ActionAtomistic::getPosition(indices[j]) - ActionAtomistic::getPosition(indices[0]);
+     194             :           if( !nopbc ) pbcApply( t_atoms, natoms );
+     195             :           // Now construct the neighbor list
+     196             :           if( nt>1 ) omp_nlist[indices[0]] = 0; else nlist[indices[0]] = 0;
+     197             :           unsigned lstart = getConstPntrToComponent(0)->getShape()[0] + indices[0]*(1+natoms_per_list);
+     198             :           for(unsigned j=0; j<natoms; ++j) {
+     199             :             double d2;
+     200             :             if ( (d2=t_atoms[j][0]*t_atoms[j][0])<nl_cut2 &&
+     201             :                  (d2+=t_atoms[j][1]*t_atoms[j][1])<nl_cut2 &&
+     202             :                  (d2+=t_atoms[j][2]*t_atoms[j][2])<nl_cut2 ) {
+     203             :               if( nt>1 ) { omp_nlist[ lstart + omp_nlist[indices[0]] ] = indices[j]; omp_nlist[indices[0]]++; }
+     204             :               else { nlist[ lstart + nlist[indices[0]] ] = indices[j]; nlist[indices[0]]++; }
+     205             :             }
+     206             :           }
+     207             : 
+     208             :         }
+     209             :       }
+     210             :       // Gather OMP stuff
+     211             :       #pragma omp critical
+     212             :       if(nt>1) {
+     213             :         for(unsigned i=0; i<ntasks; ++i) nlist[pTaskList[i]]+=omp_nlist[pTaskList[i]];
+     214             :         for(unsigned i=0; i<ntasks; ++i) {
+     215             :           unsigned lstart = getConstPntrToComponent(0)->getShape()[0] + pTaskList[i]*(1+natoms_per_list);
+     216             :           for(unsigned j=0; j<omp_nlist[pTaskList[i]]; ++j) nlist[ lstart + j ] += omp_nlist[ lstart + j ];
+     217             :         }
+     218             :       }
+     219             :     }
+     220             :     // MPI gather
+     221       11750 :     if( !runInSerial() ) comm.Sum( nlist );
+     222             :   }
+     223       11750 :   if( threeblocks.size()>0 ) {
+     224          89 :     std::vector<Vector> ltmp_pos2( threeblocks.size() );
+     225       66184 :     for(unsigned i=0; i<threeblocks.size(); ++i) {
+     226       66095 :       ltmp_pos2[i]=ActionAtomistic::getPosition( threeblocks[i] );
+     227             :     }
+     228          89 :     threecells.buildCellLists( ltmp_pos2, threeblocks, getPbc() );
+     229             :   }
+     230       11750 : }
+     231             : 
+     232         216 : void AdjacencyMatrixBase::getAdditionalTasksRequired( ActionWithVector* action, std::vector<unsigned>& atasks ) {
+     233         216 :   if( action==this ) return;
+     234             :   // Update the neighbour list
+     235          54 :   updateNeighbourList();
+     236             : 
+     237          54 :   unsigned nactive = atasks.size();
+     238          54 :   std::vector<unsigned> indlist( 1 + ablocks.size() + threeblocks.size() );
+     239        3844 :   for(unsigned i=0; i<nactive; ++i) {
+     240        3790 :     unsigned num = retrieveNeighbours( atasks[i], indlist );
+     241      269574 :     for(unsigned j=0; j<num; ++j) {
+     242             :       bool found=false;
+     243    67587417 :       for(unsigned k=0; k<atasks.size(); ++k ) {
+     244    67573541 :         if( indlist[j]==atasks[k] ) { found=true; break; }
+     245             :       }
+     246      265784 :       if( !found ) atasks.push_back( indlist[j] );
+     247             :     }
+     248             :   }
+     249             : }
+     250             : 
+     251      284222 : unsigned AdjacencyMatrixBase::getNumberOfColumns() const {
+     252      284222 :   unsigned maxcol=nlist[0];
+     253    41320716 :   for(unsigned i=1; i<getConstPntrToComponent(0)->getShape()[0]; ++i) {
+     254    41036494 :     if( nlist[i]>maxcol ) maxcol = nlist[i];
+     255             :   }
+     256             :   // This triggers appropriate storage of symmetric matrices which can only have
+     257             :   // a maximumum of shape[1]-1 non-zero elements
+     258      284222 :   return maxcol;
+     259             : }
+     260             : 
+     261      409666 : unsigned AdjacencyMatrixBase::retrieveNeighbours( const unsigned& current, std::vector<unsigned> & indices ) const {
+     262      409666 :   unsigned natoms=nlist[current]; indices[0]=current;
+     263      409666 :   unsigned lstart = getConstPntrToComponent(0)->getShape()[0] + current*(1+natoms_per_list); plumed_dbg_assert( nlist[lstart]==current );
+     264    21916923 :   for(unsigned i=1; i<nlist[current]; ++i) { indices[i] = nlist[ lstart + i ]; }
+     265      409666 :   return natoms;
+     266             : }
+     267             : 
+     268      405876 : void AdjacencyMatrixBase::setupForTask( const unsigned& current, std::vector<unsigned> & indices, MultiValue& myvals ) const {
+     269             :   // Now retrieve bookeeping arrays
+     270      405876 :   if( indices.size()!=(1+ablocks.size()+threeblocks.size()) ) indices.resize( 1+ablocks.size()+threeblocks.size() );
+     271             : 
+     272             :   // Now get the positions
+     273      405876 :   unsigned natoms=retrieveNeighbours( current, indices );
+     274             :   unsigned ntwo_atoms=natoms; myvals.setSplitIndex( ntwo_atoms );
+     275             : 
+     276             :   // Now retrieve everything for the third atoms
+     277      405876 :   if( threeblocks.size()>0 ) {
+     278         920 :     unsigned ncells_required=0; std::vector<unsigned> cells_required( threecells.getNumberOfCells() );
+     279         920 :     threecells.addRequiredCells( threecells.findMyCell( ActionAtomistic::getPosition(current) ), ncells_required, cells_required );
+     280         920 :     threecells.retrieveAtomsInCells( ncells_required, cells_required, natoms, indices );
+     281             :   }
+     282      405876 :   myvals.setNumberOfIndices( natoms );
+     283             : 
+     284             : // Apply periodic boundary conditions to atom positions
+     285      405876 :   std::vector<std::vector<Vector> > & t_atoms( myvals.getFirstAtomDerivativeVector() ); if( t_atoms.size()!=1 ) t_atoms.resize(1);
+     286      405876 :   if( t_atoms[0].size()<getNumberOfAtoms() ) t_atoms[0].resize( getNumberOfAtoms() );
+     287    26226247 :   for(unsigned i=0; i<natoms; ++i) t_atoms[0][i] = ActionAtomistic::getPosition(indices[i]) - ActionAtomistic::getPosition(current);
+     288      405876 :   if( !nopbc ) pbcApply( t_atoms[0], natoms );
+     289             :   // And collect atom position data
+     290             :   std::vector<Vector> & atoms( myvals.getAtomVector() );
+     291      405876 :   if( atoms.size()<getNumberOfAtoms() ) atoms.resize( getNumberOfAtoms() );
+     292    26226247 :   for(unsigned i=0; i<natoms; ++i) atoms[ indices[i] ] = t_atoms[0][i];
+     293      405876 : }
+     294             : 
+     295    21245263 : void AdjacencyMatrixBase::performTask( const std::string& controller, const unsigned& index1, const unsigned& index2, MultiValue& myvals ) const {
+     296    21245263 :   Vector zero; zero.zero(); plumed_dbg_assert( index2<myvals.getAtomVector().size() );
+     297    21245263 :   double weight = calculateWeight( zero, myvals.getAtomVector()[index2], myvals.getNumberOfIndices()-myvals.getSplitIndex(), myvals );
+     298    21245263 :   if( fabs(weight)<epsilon ) return;
+     299             : 
+     300    14130310 :   unsigned w_ind = getConstPntrToComponent(0)->getPositionInStream(); myvals.setValue( w_ind, weight );
+     301    14130310 :   if( !doNotCalculateDerivatives() ) {
+     302             :     // Update dynamic list indices for central atom
+     303     6759016 :     myvals.updateIndex( w_ind, 3*index1+0 ); myvals.updateIndex( w_ind, 3*index1+1 ); myvals.updateIndex( w_ind, 3*index1+2 );
+     304             :     // Update dynamic list indices for atom forming this bond
+     305     6759016 :     myvals.updateIndex( w_ind, 3*index2+0 ); myvals.updateIndex( w_ind, 3*index2+1 ); myvals.updateIndex( w_ind, 3*index2+2 );
+     306             :     // Now look after all the atoms in the third block
+     307             :     std::vector<unsigned> & indices( myvals.getIndices() );
+     308     6872649 :     for(unsigned i=myvals.getSplitIndex(); i<myvals.getNumberOfIndices(); ++i) {
+     309      113633 :       myvals.updateIndex( w_ind, 3*indices[i]+0 ); myvals.updateIndex( w_ind, 3*indices[i]+1 ); myvals.updateIndex( w_ind, 3*indices[i]+2 );
+     310             :     }
+     311             :     // Update dynamic list indices for virial
+     312    67590160 :     unsigned base = 3*getNumberOfAtoms(); for(unsigned j=0; j<9; ++j) myvals.updateIndex( w_ind, base+j );
+     313             :     // And the indices for the derivatives of the row of the matrix
+     314     6759016 :     unsigned nmat = getConstPntrToComponent(0)->getPositionInMatrixStash(), nmat_ind = myvals.getNumberOfMatrixRowDerivatives( nmat );
+     315             :     std::vector<unsigned>& matrix_indices( myvals.getMatrixRowDerivativeIndices( nmat ) );
+     316     6759016 :     matrix_indices[nmat_ind+0]=3*index2+0; matrix_indices[nmat_ind+1]=3*index2+1; matrix_indices[nmat_ind+2]=3*index2+2;
+     317     6759016 :     myvals.setNumberOfMatrixRowDerivatives( nmat, nmat_ind+3 );
+     318             :   }
+     319             : 
+     320             :   // Calculate the components if we need them
+     321    14130310 :   if( components ) {
+     322     2415123 :     unsigned x_index = getConstPntrToComponent(1)->getPositionInStream();
+     323     2415123 :     unsigned y_index = getConstPntrToComponent(2)->getPositionInStream();
+     324     2415123 :     unsigned z_index = getConstPntrToComponent(3)->getPositionInStream();
+     325     2415123 :     Vector atom = myvals.getAtomVector()[index2];
+     326     2415123 :     myvals.setValue( x_index, atom[0] ); myvals.setValue( y_index, atom[1] ); myvals.setValue( z_index, atom[2] );
+     327     2415123 :     if( !doNotCalculateDerivatives() ) {
+     328     1625864 :       myvals.addDerivative( x_index, 3*index1+0, -1 ); myvals.addDerivative( x_index, 3*index2+0, +1 );
+     329     1625864 :       myvals.addDerivative( x_index, 3*index1+1, 0 ); myvals.addDerivative( x_index, 3*index2+1, 0 );
+     330     1625864 :       myvals.addDerivative( x_index, 3*index1+2, 0 ); myvals.addDerivative( x_index, 3*index2+2, 0 );
+     331     1625864 :       myvals.addDerivative( y_index, 3*index1+0, 0 ); myvals.addDerivative( y_index, 3*index2+0, 0 );
+     332     1625864 :       myvals.addDerivative( y_index, 3*index1+1, -1 ); myvals.addDerivative( y_index, 3*index2+1, +1 );
+     333     1625864 :       myvals.addDerivative( y_index, 3*index1+2, 0 ); myvals.addDerivative( y_index, 3*index2+2, 0 );
+     334     1625864 :       myvals.addDerivative( z_index, 3*index1+0, 0 ); myvals.addDerivative( z_index, 3*index2+0, 0 );
+     335     1625864 :       myvals.addDerivative( z_index, 3*index1+1, 0 ); myvals.addDerivative( z_index, 3*index2+1, 0 );
+     336     1625864 :       myvals.addDerivative( z_index, 3*index1+2, -1 ); myvals.addDerivative( z_index, 3*index2+2, +1 );
+     337     6503456 :       for(unsigned k=0; k<3; ++k) {
+     338             :         // Update dynamic lists for central atom
+     339     4877592 :         myvals.updateIndex( x_index, 3*index1+k ); myvals.updateIndex( y_index, 3*index1+k ); myvals.updateIndex( z_index, 3*index1+k );
+     340             :         // Update dynamic lists for bonded atom
+     341     4877592 :         myvals.updateIndex( x_index, 3*index2+k ); myvals.updateIndex( y_index, 3*index2+k ); myvals.updateIndex( z_index, 3*index2+k );
+     342             :       }
+     343             :       // Add derivatives of virial
+     344     1625864 :       unsigned base = 3*getNumberOfAtoms();
+     345             :       // Virial for x
+     346     1625864 :       myvals.addDerivative( x_index, base+0, -atom[0] ); myvals.addDerivative( x_index, base+3, -atom[1] ); myvals.addDerivative( x_index, base+6, -atom[2] );
+     347     1625864 :       myvals.addDerivative( x_index, base+1, 0 ); myvals.addDerivative( x_index, base+4, 0 ); myvals.addDerivative( x_index, base+7, 0 );
+     348     1625864 :       myvals.addDerivative( x_index, base+2, 0 ); myvals.addDerivative( x_index, base+5, 0 ); myvals.addDerivative( x_index, base+8, 0 );
+     349             :       // Virial for y
+     350     1625864 :       myvals.addDerivative( y_index, base+0, 0 ); myvals.addDerivative( y_index, base+3, 0 ); myvals.addDerivative( y_index, base+6, 0 );
+     351     1625864 :       myvals.addDerivative( y_index, base+1, -atom[0] ); myvals.addDerivative( y_index, base+4, -atom[1] ); myvals.addDerivative( y_index, base+7, -atom[2] );
+     352     1625864 :       myvals.addDerivative( y_index, base+2, 0 ); myvals.addDerivative( y_index, base+5, 0 ); myvals.addDerivative( y_index, base+8, 0 );
+     353             :       // Virial for z
+     354     1625864 :       myvals.addDerivative( z_index, base+0, 0 ); myvals.addDerivative( z_index, base+3, 0 ); myvals.addDerivative( z_index, base+6, 0 );
+     355     1625864 :       myvals.addDerivative( z_index, base+1, 0 ); myvals.addDerivative( z_index, base+4, 0 ); myvals.addDerivative( z_index, base+7, 0 );
+     356     1625864 :       myvals.addDerivative( z_index, base+2, -atom[0] ); myvals.addDerivative( z_index, base+5, -atom[1] ); myvals.addDerivative( z_index, base+8, -atom[2] );
+     357    16258640 :       for(unsigned k=0; k<9; ++k) { myvals.updateIndex( x_index, base+k ); myvals.updateIndex( y_index, base+k ); myvals.updateIndex( z_index, base+k ); }
+     358     6503456 :       for(unsigned k=1; k<4; ++k) {
+     359     4877592 :         unsigned nmat = getConstPntrToComponent(k)->getPositionInMatrixStash(), nmat_ind = myvals.getNumberOfMatrixRowDerivatives( nmat );
+     360             :         std::vector<unsigned>& matrix_indices( myvals.getMatrixRowDerivativeIndices( nmat ) );
+     361     4877592 :         matrix_indices[nmat_ind+0]=3*index2+0; matrix_indices[nmat_ind+1]=3*index2+1; matrix_indices[nmat_ind+2]=3*index2+2;
+     362     4877592 :         myvals.setNumberOfMatrixRowDerivatives( nmat, nmat_ind+3 );
+     363             :       }
+     364             :     }
+     365             :   }
+     366             : }
+     367             : 
+     368      405876 : void AdjacencyMatrixBase::runEndOfRowJobs( const unsigned& ind, const std::vector<unsigned> & indices, MultiValue& myvals ) const {
+     369      405876 :   if( doNotCalculateDerivatives() ) return;
+     370             : 
+     371      737807 :   for(int k=0; k<getNumberOfComponents(); ++k) {
+     372      411298 :     unsigned nmat = getConstPntrToComponent(k)->getPositionInMatrixStash(), nmat_ind = myvals.getNumberOfMatrixRowDerivatives( nmat );
+     373             :     std::vector<unsigned>& matrix_indices( myvals.getMatrixRowDerivativeIndices( nmat ) );
+     374      411298 :     plumed_assert( nmat_ind<matrix_indices.size() );
+     375      411298 :     matrix_indices[nmat_ind+0]=3*ind+0;
+     376      411298 :     matrix_indices[nmat_ind+1]=3*ind+1;
+     377      411298 :     matrix_indices[nmat_ind+2]=3*ind+2;
+     378      411298 :     nmat_ind+=3;
+     379      423041 :     for(unsigned i=myvals.getSplitIndex(); i<myvals.getNumberOfIndices(); ++i) {
+     380       11743 :       matrix_indices[nmat_ind+0]=3*indices[i]+0;
+     381       11743 :       matrix_indices[nmat_ind+1]=3*indices[i]+1;
+     382       11743 :       matrix_indices[nmat_ind+2]=3*indices[i]+2;
+     383       11743 :       nmat_ind+=3;
+     384             :     }
+     385      411298 :     unsigned virbase = 3*getNumberOfAtoms();
+     386     4112980 :     for(unsigned i=0; i<9; ++i) matrix_indices[nmat_ind+i]=virbase+i;
+     387      411298 :     nmat_ind+=9; plumed_dbg_massert( nmat_ind<=3*getNumberOfAtoms() + 9, "found too many derivatives in " + getLabel() );
+     388             :     myvals.setNumberOfMatrixRowDerivatives( nmat, nmat_ind );
+     389             :   }
+     390             : }
+     391             : 
+     392             : }
+     393             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/AdjacencyMatrixBase.h.func-sort-c.html b/coverage/adjmat/AdjacencyMatrixBase.h.func-sort-c.html new file mode 100644 index 000000000000..17ada0141862 --- /dev/null +++ b/coverage/adjmat/AdjacencyMatrixBase.h.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + 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:3030100.0 %
Date:2024-04-19 12:12:35Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD6adjmat19AdjacencyMatrixBase23addThirdAtomDerivativesERKjRKNS_13VectorGenericILj3EEERNS_10MultiValueE131645
_ZNK4PLMD6adjmat19AdjacencyMatrixBase17addBoxDerivativesERKNS_13TensorGenericILj3ELj3EEERNS_10MultiValueE13445623
_ZNK4PLMD6adjmat19AdjacencyMatrixBase17isAdjacencyMatrixEv21245271
_ZNK4PLMD6adjmat19AdjacencyMatrixBase18addAtomDerivativesERKjRKNS_13VectorGenericILj3EEERNS_10MultiValueE26891246
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/AdjacencyMatrixBase.h.func.html b/coverage/adjmat/AdjacencyMatrixBase.h.func.html new file mode 100644 index 000000000000..9ed673d9177a --- /dev/null +++ b/coverage/adjmat/AdjacencyMatrixBase.h.func.html @@ -0,0 +1,89 @@ + + + + + + + + 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:3030100.0 %
Date:2024-04-19 12:12:35Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD6adjmat19AdjacencyMatrixBase17addBoxDerivativesERKNS_13TensorGenericILj3ELj3EEERNS_10MultiValueE13445623
_ZNK4PLMD6adjmat19AdjacencyMatrixBase17isAdjacencyMatrixEv21245271
_ZNK4PLMD6adjmat19AdjacencyMatrixBase18addAtomDerivativesERKjRKNS_13VectorGenericILj3EEERNS_10MultiValueE26891246
_ZNK4PLMD6adjmat19AdjacencyMatrixBase23addThirdAtomDerivativesERKjRKNS_13VectorGenericILj3EEERNS_10MultiValueE131645
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/AdjacencyMatrixBase.h.gcov.html b/coverage/adjmat/AdjacencyMatrixBase.h.gcov.html new file mode 100644 index 000000000000..6e43eb3352c3 --- /dev/null +++ b/coverage/adjmat/AdjacencyMatrixBase.h.gcov.html @@ -0,0 +1,190 @@ + + + + + + + + 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:3030100.0 %
Date:2024-04-19 12:12:35Functions:44100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2020 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a 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 <vector>
+      26             : #include "ActionWithMatrix.h"
+      27             : #include "tools/LinkCells.h"
+      28             : 
+      29             : namespace PLMD {
+      30             : namespace adjmat {
+      31             : 
+      32             : class AdjacencyMatrixBase : public ActionWithMatrix {
+      33             : private:
+      34             :   bool nopbc, components, read_one_group;
+      35             :   bool neighbour_list_updated;
+      36             :   LinkCells linkcells, threecells;
+      37             :   std::vector<unsigned> ablocks, threeblocks;
+      38             :   double nl_cut, nl_cut2;
+      39             :   unsigned nl_stride;
+      40             :   unsigned natoms_per_list;
+      41             :   std::vector<unsigned> nlist;
+      42             :   void setupThirdAtomBlock( const std::vector<AtomNumber>& tc, std::vector<AtomNumber>& t );
+      43             : protected:
+      44             :   Vector getPosition( const unsigned& indno, MultiValue& myvals ) const ;
+      45             :   void addAtomDerivatives( const unsigned& indno, const Vector& der, MultiValue& myvals ) const ;
+      46             :   void addThirdAtomDerivatives( const unsigned& indno, const Vector& der, MultiValue& myvals ) const ;
+      47             :   void setLinkCellCutoff( const bool& symmetric, const double& lcut, double tcut=-1.0 );
+      48             :   void addBoxDerivatives( const Tensor& vir, MultiValue& myvals ) const ;
+      49             : public:
+      50             :   static void registerKeywords( Keywords& keys );
+      51             :   explicit AdjacencyMatrixBase(const ActionOptions&);
+      52    21245271 :   bool isAdjacencyMatrix() const override { return true; }
+      53             :   unsigned getNumberOfDerivatives() override ;
+      54             :   unsigned getNumberOfColumns() const override;
+      55             :   void prepare() override;
+      56             :   void getAdditionalTasksRequired( ActionWithVector* action, std::vector<unsigned>& atasks ) override ;
+      57             :   void setupForTask( const unsigned& current, std::vector<unsigned> & indices, MultiValue& myvals ) const override;
+      58             :   // void setupCurrentTaskList() override;
+      59             :   void updateNeighbourList() override ;
+      60             :   unsigned retrieveNeighbours( const unsigned& current, std::vector<unsigned> & indices ) const ;
+      61             :   void performTask( const std::string& controller, const unsigned& index1, const unsigned& index2, MultiValue& myvals ) const override ;
+      62             :   virtual double calculateWeight( const Vector& pos1, const Vector& pos2, const unsigned& natoms, MultiValue& myvals ) const = 0;
+      63             :   void runEndOfRowJobs( const unsigned& ival, const std::vector<unsigned> & indices, MultiValue& myvals ) const override ;
+      64             : };
+      65             : 
+      66             : inline
+      67             : Vector AdjacencyMatrixBase::getPosition( const unsigned& indno, MultiValue& myvals ) const {
+      68   238830408 :   unsigned index = myvals.getIndices()[ indno + myvals.getSplitIndex() ];
+      69   238830408 :   return myvals.getAtomVector()[index];
+      70             : }
+      71             : 
+      72             : inline
+      73    26891246 : void AdjacencyMatrixBase::addAtomDerivatives( const unsigned& indno, const Vector& der, MultiValue& myvals ) const {
+      74    26891246 :   if( doNotCalculateDerivatives() ) return;
+      75             :   plumed_dbg_assert( indno<2 ); unsigned index = myvals.getTaskIndex();
+      76    12728180 :   if( indno==1 ) index = myvals.getSecondTaskIndex();
+      77    12728180 :   unsigned w_index = getConstPntrToComponent(0)->getPositionInStream();
+      78    12728180 :   myvals.addDerivative( w_index, 3*index+0, der[0] );
+      79    12728180 :   myvals.addDerivative( w_index, 3*index+1, der[1] );
+      80    12728180 :   myvals.addDerivative( w_index, 3*index+2, der[2] );
+      81             : }
+      82             : 
+      83             : inline
+      84      131645 : void AdjacencyMatrixBase::addThirdAtomDerivatives( const unsigned& indno, const Vector& der, MultiValue& myvals ) const {
+      85      131645 :   if( doNotCalculateDerivatives() ) return;
+      86      113597 :   unsigned index = myvals.getIndices()[ indno + myvals.getSplitIndex() ];
+      87      113597 :   unsigned w_index = getConstPntrToComponent(0)->getPositionInStream();
+      88      113597 :   myvals.addDerivative( w_index, 3*index+0, der[0] );
+      89      113597 :   myvals.addDerivative( w_index, 3*index+1, der[1] );
+      90      113597 :   myvals.addDerivative( w_index, 3*index+2, der[2] );
+      91             : }
+      92             : 
+      93             : inline
+      94    13445623 : void AdjacencyMatrixBase::addBoxDerivatives( const Tensor& vir, MultiValue& myvals ) const {
+      95    13445623 :   if( doNotCalculateDerivatives() ) return;
+      96     6364090 :   unsigned nbase = 3*getNumberOfAtoms();
+      97     6364090 :   unsigned w_index = getConstPntrToComponent(0)->getPositionInStream();
+      98     6364090 :   myvals.addDerivative( w_index, nbase+0, vir(0,0) );
+      99     6364090 :   myvals.addDerivative( w_index, nbase+1, vir(0,1) );
+     100     6364090 :   myvals.addDerivative( w_index, nbase+2, vir(0,2) );
+     101     6364090 :   myvals.addDerivative( w_index, nbase+3, vir(1,0) );
+     102     6364090 :   myvals.addDerivative( w_index, nbase+4, vir(1,1) );
+     103     6364090 :   myvals.addDerivative( w_index, nbase+5, vir(1,2) );
+     104     6364090 :   myvals.addDerivative( w_index, nbase+6, vir(2,0) );
+     105     6364090 :   myvals.addDerivative( w_index, nbase+7, vir(2,1) );
+     106     6364090 :   myvals.addDerivative( w_index, nbase+8, vir(2,2) );
+     107             : }
+     108             : 
+     109             : 
+     110             : }
+     111             : }
+     112             : 
+     113             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/Bridge.cpp.func-sort-c.html b/coverage/adjmat/Bridge.cpp.func-sort-c.html new file mode 100644 index 000000000000..af634b4122d5 --- /dev/null +++ b/coverage/adjmat/Bridge.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/Bridge.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - Bridge.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1919100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat6BridgeC2ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat6BridgeC1ERKNS_13ActionOptionsE8
_ZN4PLMD6adjmat6Bridge16registerKeywordsERNS_8KeywordsE10
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/Bridge.cpp.func.html b/coverage/adjmat/Bridge.cpp.func.html new file mode 100644 index 000000000000..51deb7c3437a --- /dev/null +++ b/coverage/adjmat/Bridge.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/Bridge.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - Bridge.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1919100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat6Bridge16registerKeywordsERNS_8KeywordsE10
_ZN4PLMD6adjmat6BridgeC1ERKNS_13ActionOptionsE8
_ZN4PLMD6adjmat6BridgeC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/Bridge.cpp.gcov.html b/coverage/adjmat/Bridge.cpp.gcov.html new file mode 100644 index 000000000000..2ea36f5c6a46 --- /dev/null +++ b/coverage/adjmat/Bridge.cpp.gcov.html @@ -0,0 +1,152 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/Bridge.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - Bridge.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1919100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2018 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received 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             : //+PLUMEDOC MCOLVAR BRIDGE
+      26             : /*
+      27             : Calculate a matrix with elements equal to one if there is a bridging atom between the two atoms
+      28             : 
+      29             : \par Examples
+      30             : 
+      31             : */
+      32             : //+ENDPLUMEDOC
+      33             : 
+      34             : namespace PLMD {
+      35             : namespace adjmat {
+      36             : 
+      37             : class Bridge : public ActionShortcut {
+      38             : public:
+      39             :   static void registerKeywords(Keywords& keys);
+      40             :   explicit Bridge(const ActionOptions&);
+      41             : };
+      42             : 
+      43             : PLUMED_REGISTER_ACTION(Bridge,"BRIDGE")
+      44             : 
+      45          10 : void Bridge::registerKeywords(Keywords& keys) {
+      46          10 :   ActionShortcut::registerKeywords(keys);
+      47          20 :   keys.add("atoms","GROUP","the atoms for which you would like to calculate the adjacency matrix");
+      48          20 :   keys.add("atoms","GROUPA","");
+      49          20 :   keys.add("atoms","GROUPB","");
+      50          20 :   keys.add("atoms","BRIDGING_ATOMS","The list of atoms that can form the bridge between the two interesting parts "
+      51             :            "of the structure.");
+      52          20 :   keys.add("optional","SWITCH","The parameters of the two \\ref switchingfunction in the above formula");
+      53          20 :   keys.add("optional","SWITCHA","The \\ref switchingfunction on the distance between bridging atoms and the atoms in "
+      54             :            "group A");
+      55          20 :   keys.add("optional","SWITCHB","The \\ref switchingfunction on the distance between the bridging atoms and the atoms in "
+      56             :            "group B");
+      57          20 :   keys.needsAction("BRIDGE_MATRIX"); keys.needsAction("SUM");
+      58          10 : }
+      59             : 
+      60           8 : Bridge::Bridge(const ActionOptions& ao):
+      61             :   Action(ao),
+      62           8 :   ActionShortcut(ao)
+      63             : {
+      64             :   // Need to read in switch
+      65          24 :   std::string s_inp, sfinput; parse("SWITCH",sfinput); if( sfinput.length()>0 ) s_inp += "SWITCH={" + sfinput +"} ";
+      66          16 :   std::string sfinputa; parse("SWITCHA",sfinputa); if( sfinputa.length()>0 ) s_inp += "SWITCHA={" + sfinputa +"} ";
+      67          16 :   std::string sfinputb; parse("SWITCHB",sfinputb); if( sfinputb.length()>0 ) s_inp += "SWITCHB={" + sfinputb +"} ";
+      68             :   // Create the matrix object
+      69          16 :   readInputLine( getShortcutLabel() + "_mat: BRIDGE_MATRIX " + s_inp + convertInputLineToString() );
+      70             :   // Add all the elements of the matrix together
+      71          16 :   readInputLine( getShortcutLabel() + ": SUM ARG=" + getShortcutLabel() + "_mat PERIODIC=NO");
+      72           8 : }
+      73             : 
+      74             : }
+      75             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/BridgeMatrix.cpp.func-sort-c.html b/coverage/adjmat/BridgeMatrix.cpp.func-sort-c.html new file mode 100644 index 000000000000..f6ee5839dde0 --- /dev/null +++ b/coverage/adjmat/BridgeMatrix.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/BridgeMatrix.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - BridgeMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:334278.6 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat12BridgeMatrixC2ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat12BridgeMatrixC1ERKNS_13ActionOptionsE8
_ZN4PLMD6adjmat12BridgeMatrix16registerKeywordsERNS_8KeywordsE10
_ZNK4PLMD6adjmat12BridgeMatrix15calculateWeightERKNS_13VectorGenericILj3EEES5_RKjRNS_10MultiValueE537
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/BridgeMatrix.cpp.func.html b/coverage/adjmat/BridgeMatrix.cpp.func.html new file mode 100644 index 000000000000..63cfc324c36e --- /dev/null +++ b/coverage/adjmat/BridgeMatrix.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/BridgeMatrix.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - BridgeMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:334278.6 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat12BridgeMatrix16registerKeywordsERNS_8KeywordsE10
_ZN4PLMD6adjmat12BridgeMatrixC1ERKNS_13ActionOptionsE8
_ZN4PLMD6adjmat12BridgeMatrixC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6adjmat12BridgeMatrix15calculateWeightERKNS_13VectorGenericILj3EEES5_RKjRNS_10MultiValueE537
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/BridgeMatrix.cpp.gcov.html b/coverage/adjmat/BridgeMatrix.cpp.gcov.html new file mode 100644 index 000000000000..ebf7dfd312ed --- /dev/null +++ b/coverage/adjmat/BridgeMatrix.cpp.gcov.html @@ -0,0 +1,213 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/BridgeMatrix.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - BridgeMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:334278.6 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2020 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received 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 "tools/SwitchingFunction.h"
+      24             : #include "core/ActionRegister.h"
+      25             : 
+      26             : #include <string>
+      27             : #include <cmath>
+      28             : 
+      29             : namespace PLMD {
+      30             : namespace adjmat {
+      31             : 
+      32             : //+PLUMEDOC MCOLVAR BRIDGE_MATRIX
+      33             : /*
+      34             : Calculate the number of atoms that bridge two parts of a structure
+      35             : 
+      36             : This quantity calculates:
+      37             : 
+      38             : \f[
+      39             :  f(x) = \sum_{ijk} s_A(r_{ij})s_B(r_{ik})
+      40             : \f]
+      41             : 
+      42             : where the sum over \f$i\f$ is over all the ``bridging atoms" and
+      43             : \f$s_A\f$ and \f$s_B\f$ are \ref switchingfunction.
+      44             : 
+      45             : \par Examples
+      46             : 
+      47             : The following example instructs plumed to calculate the number of water molecules
+      48             : that are bridging between atoms 1-10 and atoms 11-20 and to print the value
+      49             : to a file
+      50             : 
+      51             : \plumedfile
+      52             : w1: BRIDGE BRIDGING_ATOMS=100-200 GROUPA=1-10 GROUPB=11-20 SWITCH={RATIONAL R_0=0.2}
+      53             : PRINT ARG=w1 FILE=colvar
+      54             : \endplumedfile
+      55             : 
+      56             : */
+      57             : //+ENDPLUMEDOC
+      58             : 
+      59             : class BridgeMatrix : public AdjacencyMatrixBase {
+      60             : private:
+      61             :   Vector dij, dik;
+      62             :   SwitchingFunction sf1;
+      63             :   SwitchingFunction sf2;
+      64             : public:
+      65             :   static void registerKeywords( Keywords& keys );
+      66             :   explicit BridgeMatrix(const ActionOptions&);
+      67             : // active methods:
+      68             :   double calculateWeight( const Vector& pos1, const Vector& pos2, const unsigned& natoms, MultiValue& myvals ) const override;
+      69             : };
+      70             : 
+      71             : PLUMED_REGISTER_ACTION(BridgeMatrix,"BRIDGE_MATRIX")
+      72             : 
+      73          10 : void BridgeMatrix::registerKeywords( Keywords& keys ) {
+      74          10 :   AdjacencyMatrixBase::registerKeywords( keys );
+      75          20 :   keys.add("atoms","BRIDGING_ATOMS","The list of atoms that can form the bridge between the two interesting parts "
+      76             :            "of the structure.");
+      77          20 :   keys.add("optional","SWITCH","The parameters of the two \\ref switchingfunction in the above formula");
+      78          20 :   keys.add("optional","SWITCHA","The \\ref switchingfunction on the distance between bridging atoms and the atoms in "
+      79             :            "group A");
+      80          20 :   keys.add("optional","SWITCHB","The \\ref switchingfunction on the distance between the bridging atoms and the atoms in "
+      81             :            "group B");
+      82          10 : }
+      83             : 
+      84           8 : BridgeMatrix::BridgeMatrix(const ActionOptions&ao):
+      85             :   Action(ao),
+      86           8 :   AdjacencyMatrixBase(ao)
+      87             : {
+      88          16 :   bool oneswitch; std::string sfinput,errors; parse("SWITCH",sfinput);
+      89           8 :   if( sfinput.length()>0 ) {
+      90           8 :     sf1.set(sfinput,errors); oneswitch=true;
+      91           8 :     if( errors.length()!=0 ) error("problem reading SWITCH keyword : " + errors );
+      92           8 :     sf2.set(sfinput,errors);
+      93           8 :     if( errors.length()!=0 ) error("problem reading SWITCH keyword : " + errors );
+      94             :   } else {
+      95           0 :     parse("SWITCHA",sfinput);
+      96           0 :     if(sfinput.length()>0) {
+      97           0 :       sf1.set(sfinput,errors); oneswitch=false;
+      98           0 :       if( errors.length()!=0 ) error("problem reading SWITCHA keyword : " + errors );
+      99           0 :       sfinput.clear(); parse("SWITCHB",sfinput);
+     100           0 :       if(sfinput.length()==0) error("found SWITCHA keyword without SWITCHB");
+     101           0 :       sf2.set(sfinput,errors);
+     102           0 :       if( errors.length()!=0 ) error("problem reading SWITCHB keyword : " + errors );
+     103             :     } else {
+     104           0 :       error("missing definition of switching functions");
+     105             :     }
+     106             :   }
+     107           8 :   log.printf("  distance between bridging atoms and atoms in GROUPA must be less than %s\n",sf1.description().c_str());
+     108           8 :   log.printf("  distance between bridging atoms and atoms in GROUPB must be less than %s\n",sf2.description().c_str());
+     109             : 
+     110             :   // Setup link cells
+     111           8 :   setLinkCellCutoff( oneswitch, sf1.get_dmax() + sf2.get_dmax() );
+     112             : 
+     113             :   // And check everything has been read in correctly
+     114           8 :   checkRead();
+     115           8 : }
+     116             : 
+     117         537 : double BridgeMatrix::calculateWeight( const Vector& pos1, const Vector& pos2, const unsigned& natoms, MultiValue& myvals ) const {
+     118         537 :   double tot=0; if( pos2.modulo2()<epsilon ) return 0.0;
+     119       21359 :   for(unsigned i=0; i<natoms; ++i) {
+     120       20822 :     Vector dij= getPosition(i,myvals); double dijm = dij.modulo2();
+     121       20822 :     double dw1, w1=sf1.calculateSqr( dijm, dw1 ); if( dijm<epsilon ) { w1=0.0; dw1=0.0; }
+     122       20822 :     Vector dik=pbcDistance( getPosition(i,myvals), pos2 ); double dikm=dik.modulo2();
+     123       20822 :     double dw2, w2=sf2.calculateSqr( dikm, dw2 ); if( dikm<epsilon ) { w2=0.0; dw2=0.0; }
+     124             : 
+     125       20822 :     tot += w1*w2;
+     126             :     // And finish the calculation
+     127       20822 :     addAtomDerivatives( 0,  -w2*dw1*dij, myvals );
+     128       20822 :     addAtomDerivatives( 1,  w1*dw2*dik, myvals );
+     129       20822 :     addThirdAtomDerivatives( i, -w1*dw2*dik+w2*dw1*dij, myvals );
+     130       20822 :     addBoxDerivatives( w1*(-dw2)*Tensor(dik,dik)+w2*(-dw1)*Tensor(dij,dij), myvals );
+     131             :   }
+     132         537 :   return tot;
+     133             : }
+     134             : 
+     135             : }
+     136             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ContactMatrix.cpp.func-sort-c.html b/coverage/adjmat/ContactMatrix.cpp.func-sort-c.html new file mode 100644 index 000000000000..af762380942c --- /dev/null +++ b/coverage/adjmat/ContactMatrix.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + 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:3232100.0 %
Date:2024-04-19 12:12:35Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat13ContactMatrixC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6adjmat13ContactMatrix12writeInGraphB5cxx11Ev8
_ZN4PLMD6adjmat13ContactMatrixC1ERKNS_13ActionOptionsE208
_ZN4PLMD6adjmat13ContactMatrix16registerKeywordsERNS_8KeywordsE210
_ZNK4PLMD6adjmat13ContactMatrix15calculateWeightERKNS_13VectorGenericILj3EEES5_RKjRNS_10MultiValueE15298242
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ContactMatrix.cpp.func.html b/coverage/adjmat/ContactMatrix.cpp.func.html new file mode 100644 index 000000000000..9c5b5e41b066 --- /dev/null +++ b/coverage/adjmat/ContactMatrix.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + 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:3232100.0 %
Date:2024-04-19 12:12:35Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat13ContactMatrix16registerKeywordsERNS_8KeywordsE210
_ZN4PLMD6adjmat13ContactMatrixC1ERKNS_13ActionOptionsE208
_ZN4PLMD6adjmat13ContactMatrixC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6adjmat13ContactMatrix12writeInGraphB5cxx11Ev8
_ZNK4PLMD6adjmat13ContactMatrix15calculateWeightERKNS_13VectorGenericILj3EEES5_RKjRNS_10MultiValueE15298242
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ContactMatrix.cpp.gcov.html b/coverage/adjmat/ContactMatrix.cpp.gcov.html new file mode 100644 index 000000000000..19c27aa267ba --- /dev/null +++ b/coverage/adjmat/ContactMatrix.cpp.gcov.html @@ -0,0 +1,201 @@ + + + + + + + + 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:3232100.0 %
Date:2024-04-19 12:12:35Functions:4580.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "AdjacencyMatrixBase.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "tools/SwitchingFunction.h"
+      25             : #include "tools/Matrix.h"
+      26             : 
+      27             : //+PLUMEDOC MATRIX CONTACT_MATRIX_PROPER
+      28             : /*
+      29             : Adjacency matrix in which two atoms are adjacent if they are within a certain cutoff.
+      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.  These matrices can then be further
+      34             : analyzed using a number of other algorithms as is detailed in \cite tribello-clustering.
+      35             : 
+      36             : For this action the elements of the contact matrix are calculated using:
+      37             : 
+      38             : \f[
+      39             :  a_{ij} = \sigma( |\mathbf{r}_{ij}| )
+      40             : \f]
+      41             : 
+      42             : 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.
+      43             : 
+      44             : \par Examples
+      45             : 
+      46             : 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
+      47             : 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.
+      48             : The final quantity output in the colvar file is thus the average coordination number.
+      49             : 
+      50             : \plumedfile
+      51             : mat: CONTACT_MATRIX ATOMS=1-6 SWITCH={EXP D_0=0.2 R_0=0.1 D_MAX=0.66}
+      52             : COLUMNSUMS MATRIX=mat MEAN LABEL=csums
+      53             : PRINT ARG=csums.* FILE=colvar
+      54             : \endplumedfile
+      55             : 
+      56             : */
+      57             : //+ENDPLUMEDOC
+      58             : 
+      59             : 
+      60             : namespace PLMD {
+      61             : namespace adjmat {
+      62             : 
+      63             : class ContactMatrix : public AdjacencyMatrixBase {
+      64             : private:
+      65             : /// switching function
+      66             :   SwitchingFunction switchingFunction;
+      67             : public:
+      68             : /// Create manual
+      69             :   static void registerKeywords( Keywords& keys );
+      70             : /// Constructor
+      71             :   explicit ContactMatrix(const ActionOptions&);
+      72             : /// This does nothing
+      73             :   double calculateWeight( const Vector& pos1, const Vector& pos2, const unsigned& natoms, MultiValue& myvals ) const override;
+      74             : /// Override this so we write the graph properly
+      75           8 :   std::string writeInGraph() const override { return "CONTACT_MATRIX"; }
+      76             : };
+      77             : 
+      78             : PLUMED_REGISTER_ACTION(ContactMatrix,"CONTACT_MATRIX_PROPER")
+      79             : 
+      80         210 : void ContactMatrix::registerKeywords( Keywords& keys ) {
+      81         210 :   AdjacencyMatrixBase::registerKeywords( keys );
+      82         420 :   keys.add("compulsory","NN","6","The n parameter of the switching function ");
+      83         420 :   keys.add("compulsory","MM","0","The m parameter of the switching function; 0 implies 2*NN");
+      84         420 :   keys.add("compulsory","D_0","0.0","The d_0 parameter of the switching function");
+      85         420 :   keys.add("compulsory","R_0","The r_0 parameter of the switching function");
+      86         420 :   keys.add("optional","SWITCH","This keyword is used if you want to employ an alternative to the continuous swiching function defined above. "
+      87             :            "The following provides information on the \\ref switchingfunction that are available. "
+      88             :            "When this keyword is present you no longer need the NN, MM, D_0 and R_0 keywords.");
+      89         210 : }
+      90             : 
+      91         208 : ContactMatrix::ContactMatrix( const ActionOptions& ao ):
+      92             :   Action(ao),
+      93         208 :   AdjacencyMatrixBase(ao)
+      94             : {
+      95         416 :   std::string errors, input; parse("SWITCH",input);
+      96         208 :   if( input.length()>0 ) {
+      97         181 :     switchingFunction.set( input, errors );
+      98         181 :     if( errors.length()!=0 ) error("problem reading switching function description " + errors);
+      99             :   } else {
+     100          27 :     double r_0=-1.0, d_0; int nn, mm;
+     101          54 :     parse("NN",nn); parse("MM",mm);
+     102          54 :     parse("R_0",r_0); parse("D_0",d_0);
+     103          27 :     if( r_0<0.0 ) error("you must set a value for R_0");
+     104          27 :     switchingFunction.set(nn,mm,r_0,d_0);
+     105             :   }
+     106             :   // And set the link cell cutoff
+     107         208 :   log.printf("  switching function cutoff is %s \n",switchingFunction.description().c_str() );
+     108         208 :   setLinkCellCutoff( true, switchingFunction.get_dmax() );
+     109         208 : }
+     110             : 
+     111    15298242 : double ContactMatrix::calculateWeight( const Vector& pos1, const Vector& pos2, const unsigned& natoms, MultiValue& myvals ) const {
+     112    15298242 :   Vector distance = pos2; double mod2 = distance.modulo2();
+     113    15298242 :   if( mod2<epsilon ) return 0.0;  // Atoms can't be bonded to themselves
+     114    15296728 :   double dfunc, val = switchingFunction.calculateSqr( mod2, dfunc );
+     115    15296728 :   if( val<epsilon ) return 0.0;
+     116     8264002 :   addAtomDerivatives( 0, (-dfunc)*distance, myvals );
+     117     8264002 :   addAtomDerivatives( 1, (+dfunc)*distance, myvals );
+     118     8264002 :   addBoxDerivatives( (-dfunc)*Tensor(distance,distance), myvals );
+     119     8264002 :   return val;
+     120             : }
+     121             : 
+     122             : }
+     123             : }
+     124             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ContactMatrixShortcut.cpp.func-sort-c.html b/coverage/adjmat/ContactMatrixShortcut.cpp.func-sort-c.html new file mode 100644 index 000000000000..e488ba28467c --- /dev/null +++ b/coverage/adjmat/ContactMatrixShortcut.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/ContactMatrixShortcut.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - ContactMatrixShortcut.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:455188.2 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat21ContactMatrixShortcutC2ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat21ContactMatrixShortcutC1ERKNS_13ActionOptionsE206
_ZN4PLMD6adjmat21ContactMatrixShortcut16registerKeywordsERNS_8KeywordsE208
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ContactMatrixShortcut.cpp.func.html b/coverage/adjmat/ContactMatrixShortcut.cpp.func.html new file mode 100644 index 000000000000..795d1f1b08a8 --- /dev/null +++ b/coverage/adjmat/ContactMatrixShortcut.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/ContactMatrixShortcut.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - ContactMatrixShortcut.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:455188.2 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat21ContactMatrixShortcut16registerKeywordsERNS_8KeywordsE208
_ZN4PLMD6adjmat21ContactMatrixShortcutC1ERKNS_13ActionOptionsE206
_ZN4PLMD6adjmat21ContactMatrixShortcutC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ContactMatrixShortcut.cpp.gcov.html b/coverage/adjmat/ContactMatrixShortcut.cpp.gcov.html new file mode 100644 index 000000000000..248ebfbd6475 --- /dev/null +++ b/coverage/adjmat/ContactMatrixShortcut.cpp.gcov.html @@ -0,0 +1,215 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/ContactMatrixShortcut.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - ContactMatrixShortcut.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:455188.2 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2020 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionShortcut.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "core/PlumedMain.h"
+      25             : #include "core/ActionSet.h"
+      26             : #include "core/Group.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             : namespace PLMD {
+      61             : namespace adjmat {
+      62             : 
+      63             : class ContactMatrixShortcut : public ActionShortcut {
+      64             : public:
+      65             :   static void registerKeywords(Keywords& keys);
+      66             :   explicit ContactMatrixShortcut(const ActionOptions&);
+      67             : };
+      68             : 
+      69             : PLUMED_REGISTER_ACTION(ContactMatrixShortcut,"CONTACT_MATRIX")
+      70             : 
+      71         208 : void ContactMatrixShortcut::registerKeywords(Keywords& keys) {
+      72         208 :   ActionShortcut::registerKeywords( keys );
+      73         416 :   keys.add("atoms","GROUPA","");
+      74         416 :   keys.add("atoms","GROUPB","");
+      75         416 :   keys.add("atoms-2","ATOMS","the atoms for which you would like to calculate the adjacency matrix (basically equivalent to GROUP)");
+      76         416 :   keys.add("numbered","GROUP","specifies the list of atoms that should be assumed indistinguishable");
+      77         416 :   keys.add("compulsory","NN","6","The n parameter of the switching function ");
+      78         416 :   keys.add("compulsory","MM","0","The m parameter of the switching function; 0 implies 2*NN");
+      79         416 :   keys.add("compulsory","D_0","0.0","The d_0 parameter of the switching function");
+      80         416 :   keys.add("compulsory","R_0","The r_0 parameter of the switching function");
+      81         416 :   keys.add("numbered","SWITCH","specify the switching function to use between two sets of indistinguishable atoms");
+      82         416 :   keys.add("compulsory","NL_CUTOFF","0.0","The cutoff for the neighbor list.  A value of 0 means we are not using a neighbor list");
+      83         416 :   keys.add("compulsory","NL_STRIDE","1","The frequency with which we are updating the atoms in the neighbor list");
+      84         416 :   keys.addFlag("COMPONENTS",false,"also calculate the components of the vector connecting the atoms in the contact matrix");
+      85         416 :   keys.addFlag("NOPBC",false,"don't use pbc");
+      86         624 :   keys.addActionNameSuffix("_PROPER"); keys.needsAction("TRANSPOSE"); keys.needsAction("CONCATENATE");
+      87         208 : }
+      88             : 
+      89         206 : ContactMatrixShortcut::ContactMatrixShortcut(const ActionOptions& ao):
+      90             :   Action(ao),
+      91         206 :   ActionShortcut(ao)
+      92             : {
+      93         206 :   std::vector<std::string> grp_str; std::string atomsstr="";
+      94         412 :   std::vector<std::string> atomsvec; parseVector("ATOMS",atomsvec);
+      95         206 :   if( atomsvec.size()>0 )  {
+      96           0 :     for(unsigned i=0; i<atomsvec.size(); ++i) {
+      97           0 :       Group* gg = plumed.getActionSet().selectWithLabel<Group*>( atomsvec[i] );
+      98           0 :       if( gg ) grp_str.push_back( atomsvec[i] );
+      99             :     }
+     100           0 :     if( grp_str.size()!=atomsvec.size() ) {
+     101           0 :       grp_str.resize(0);
+     102           0 :       atomsstr = " ATOMS=" + atomsvec[0]; for(unsigned i=1; i<atomsvec.size(); ++i) atomsstr += "," + atomsvec[i];
+     103             :     }
+     104             :   } else {
+     105             :     std::string grp_inpt;
+     106           2 :     for(unsigned i=1;; ++i) {
+     107         416 :       if( !parseNumbered("GROUP",i,grp_inpt) ) break;
+     108           2 :       grp_str.push_back( grp_inpt );
+     109             :     }
+     110             :   }
+     111         206 :   if( grp_str.size()>9 ) error("cannot handle more than 9 groups");
+     112         411 :   if( grp_str.size()==0 )  { readInputLine( getShortcutLabel() + ": CONTACT_MATRIX_PROPER " + atomsstr + " " + convertInputLineToString() ); return; }
+     113             : 
+     114           3 :   for(unsigned i=0; i<grp_str.size(); ++i) {
+     115           4 :     std::string sw_str, num; Tools::convert( i+1, num ); parseNumbered("SWITCH", (i+1)*10 + 1 + i,  sw_str );
+     116           2 :     if( sw_str.length()==0 ) error("missing SWITCH" + num + num + " keyword");
+     117           4 :     readInputLine( getShortcutLabel() + num +  num + ": CONTACT_MATRIX_PROPER GROUP=" + grp_str[i] + " SWITCH={" + sw_str + "}" );
+     118           3 :     for(unsigned j=0; j<i; ++j) {
+     119           2 :       std::string sw_str2, jnum; Tools::convert( j+1, jnum ); parseNumbered("SWITCH", (j+1)*10 + 1 + i, sw_str2);
+     120           1 :       if( sw_str2.length()==0 ) error("missing SWITCH" + jnum + num + " keyword");
+     121           2 :       readInputLine( getShortcutLabel() + jnum + num + ": CONTACT_MATRIX_PROPER GROUPA=" + grp_str[j] + " GROUPB=" + grp_str[i] + " SWITCH={" + sw_str2 +"}");
+     122           2 :       readInputLine( getShortcutLabel() + num +  jnum + ": TRANSPOSE ARG=" + getShortcutLabel() + jnum + num );
+     123             :     }
+     124             :   }
+     125           1 :   std::string join_matrices = getShortcutLabel() + ": CONCATENATE";
+     126           3 :   for(unsigned i=0; i<grp_str.size(); ++i) {
+     127           2 :     std::string inum; Tools::convert(i+1,inum);
+     128           6 :     for(unsigned j=0; j<grp_str.size(); ++j) {
+     129           4 :       std::string jnum; Tools::convert(j+1,jnum);
+     130           5 :       if( i>j ) join_matrices += " MATRIX" + inum + jnum + "=" + getShortcutLabel() + inum +  jnum;
+     131           6 :       else join_matrices += " MATRIX" + inum + jnum + "=" + getShortcutLabel() + inum +  jnum;
+     132             :     }
+     133             :   }
+     134           1 :   readInputLine( join_matrices );
+     135         412 : }
+     136             : 
+     137             : }
+     138             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/CovarianceMatrix.cpp.func-sort-c.html b/coverage/adjmat/CovarianceMatrix.cpp.func-sort-c.html new file mode 100644 index 000000000000..ec4fe5b26943 --- /dev/null +++ b/coverage/adjmat/CovarianceMatrix.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/CovarianceMatrix.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - CovarianceMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2626100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat16CovarianceMatrixC2ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat16CovarianceMatrixC1ERKNS_13ActionOptionsE4
_ZN4PLMD6adjmat16CovarianceMatrix16registerKeywordsERNS_8KeywordsE6
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/CovarianceMatrix.cpp.func.html b/coverage/adjmat/CovarianceMatrix.cpp.func.html new file mode 100644 index 000000000000..7bbb6a40a376 --- /dev/null +++ b/coverage/adjmat/CovarianceMatrix.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/CovarianceMatrix.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - CovarianceMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2626100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat16CovarianceMatrix16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD6adjmat16CovarianceMatrixC1ERKNS_13ActionOptionsE4
_ZN4PLMD6adjmat16CovarianceMatrixC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/CovarianceMatrix.cpp.gcov.html b/coverage/adjmat/CovarianceMatrix.cpp.gcov.html new file mode 100644 index 000000000000..21652b3b6f41 --- /dev/null +++ b/coverage/adjmat/CovarianceMatrix.cpp.gcov.html @@ -0,0 +1,163 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/CovarianceMatrix.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - CovarianceMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2626100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2017-2019 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received 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/ActionShortcut.h"
+      24             : 
+      25             : //+PLUMEDOC REWEIGHTING COVARIANCE_MATRIX
+      26             : /*
+      27             : Calculate a covariance matix
+      28             : 
+      29             : \par Examples
+      30             : 
+      31             : */
+      32             : //+ENDPLUMEDOC
+      33             : 
+      34             : namespace PLMD {
+      35             : namespace adjmat {
+      36             : 
+      37             : class CovarianceMatrix : public ActionShortcut {
+      38             : public:
+      39             :   static void registerKeywords(Keywords&);
+      40             :   explicit CovarianceMatrix(const ActionOptions&ao);
+      41             : };
+      42             : 
+      43             : PLUMED_REGISTER_ACTION(CovarianceMatrix,"COVARIANCE_MATRIX")
+      44             : 
+      45           6 : void CovarianceMatrix::registerKeywords(Keywords& keys ) {
+      46           6 :   ActionShortcut::registerKeywords( keys );
+      47          12 :   keys.add("numbered","ARG","the vectors of data from which we are calculating the covariance");
+      48          12 :   keys.add("compulsory","WEIGHTS","this keyword takes the label of an action that calculates a vector of values.  The elements of this vector "
+      49             :            "are used as weights for the input data points.");
+      50          12 :   keys.addFlag("UNORMALIZED",false,"do not divide by the sum of the weights");
+      51          24 :   keys.needsAction("SUM"); keys.needsAction("CUSTOM"); keys.needsAction("VSTACK"); keys.needsAction("TRANSPOSE");
+      52          18 :   keys.needsAction("ONES"); keys.needsAction("OUTER_PRODUCT"); keys.needsAction("MATRIX_PRODUCT");
+      53           6 : }
+      54             : 
+      55           4 : CovarianceMatrix::CovarianceMatrix(const ActionOptions&ao):
+      56             :   Action(ao),
+      57           4 :   ActionShortcut(ao)
+      58             : {
+      59           8 :   std::vector<std::string> args; parseVector("ARG",args);
+      60           4 :   unsigned nargs=args.size(); std::string argstr="ARG=" + args[0];
+      61          12 :   for(unsigned i=1; i<args.size(); ++i) argstr += "," + args[i];
+      62             : 
+      63           8 :   bool unorm; parseFlag("UNORMALIZED",unorm); std::string wstr; parse("WEIGHTS",wstr);
+      64           4 :   if( !unorm ) {
+      65             :     // Normalize the weights
+      66           8 :     readInputLine( getShortcutLabel() + "_wsum: SUM ARG=" + wstr + " PERIODIC=NO");
+      67           8 :     readInputLine( getShortcutLabel() + "_weights: CUSTOM ARG=" + wstr + "," + getShortcutLabel() + "_wsum FUNC=x/y PERIODIC=NO");
+      68           8 :     wstr = getShortcutLabel() + "_weights";
+      69             :   }
+      70             :   // Make a stack of all the data
+      71           8 :   readInputLine( getShortcutLabel() + "_stack: VSTACK " + argstr );
+      72             :   // And calculate the covariance matrix by first transposing the stack
+      73           8 :   readInputLine( getShortcutLabel() + "_stackT: TRANSPOSE ARG=" + getShortcutLabel() + "_stack");
+      74             :   // Create a matrix that holds all the weights
+      75           4 :   std::string str_nargs; Tools::convert( nargs, str_nargs );
+      76           8 :   readInputLine( getShortcutLabel() + "_ones: ONES SIZE=" + str_nargs );
+      77             :   // Now create a matrix that holds all the weights
+      78           8 :   readInputLine( getShortcutLabel() + "_matweights: OUTER_PRODUCT ARG=" + getShortcutLabel() + "_ones," + wstr );
+      79             :   // And multiply the weights by the transpose to get the weighted transpose
+      80           8 :   readInputLine( getShortcutLabel() + "_wT: CUSTOM ARG=" + getShortcutLabel() + "_matweights," + getShortcutLabel() + "_stackT FUNC=x*y PERIODIC=NO");
+      81             :   // And now calculate the covariance by doing a suitable matrix product
+      82           8 :   readInputLine( getShortcutLabel() + ": MATRIX_PRODUCT ARG=" + getShortcutLabel() + "_wT," + getShortcutLabel() + "_stack");
+      83           4 : }
+      84             : 
+      85             : }
+      86             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/Determinent.cpp.func-sort-c.html b/coverage/adjmat/Determinent.cpp.func-sort-c.html new file mode 100644 index 000000000000..91fc0f05f9e7 --- /dev/null +++ b/coverage/adjmat/Determinent.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/Determinent.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - Determinent.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:41040.0 %
Date:2024-04-19 12:12:35Functions:1333.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat11DeterminantC1ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat11DeterminantC2ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat11Determinant16registerKeywordsERNS_8KeywordsE2
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/Determinent.cpp.func.html b/coverage/adjmat/Determinent.cpp.func.html new file mode 100644 index 000000000000..2ccd548c50fc --- /dev/null +++ b/coverage/adjmat/Determinent.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/Determinent.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - Determinent.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:41040.0 %
Date:2024-04-19 12:12:35Functions:1333.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat11Determinant16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD6adjmat11DeterminantC1ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat11DeterminantC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/Determinent.cpp.gcov.html b/coverage/adjmat/Determinent.cpp.gcov.html new file mode 100644 index 000000000000..f99102aded99 --- /dev/null +++ b/coverage/adjmat/Determinent.cpp.gcov.html @@ -0,0 +1,139 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/Determinent.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - Determinent.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:41040.0 %
Date:2024-04-19 12:12:35Functions:1333.3 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2020 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received 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/ActionShortcut.h"
+      24             : 
+      25             : //+PLUMEDOC MCOLVAR DETERMINANT
+      26             : /*
+      27             : Calculate the determinant of a matrix
+      28             : 
+      29             : \par Examples
+      30             : 
+      31             : */
+      32             : //+ENDPLUMEDOC
+      33             : 
+      34             : namespace PLMD {
+      35             : namespace adjmat {
+      36             : 
+      37             : class Determinant : public ActionShortcut {
+      38             : public:
+      39             :   static void registerKeywords( Keywords& keys );
+      40             :   explicit Determinant(const ActionOptions&ao);
+      41             : };
+      42             : 
+      43             : PLUMED_REGISTER_ACTION(Determinant,"DETERMINANT")
+      44             : 
+      45           2 : void Determinant::registerKeywords( Keywords& keys ) {
+      46           2 :   ActionShortcut::registerKeywords(keys);
+      47           4 :   keys.add("compulsory","ARG","The matrix that we are calculating the determinant for");
+      48           2 : }
+      49             : 
+      50           0 : Determinant::Determinant( const ActionOptions& ao):
+      51             :   Action(ao),
+      52           0 :   ActionShortcut(ao)
+      53             : {
+      54           0 :   std::string arg; parse("ARG",arg);
+      55             :   // Compose a vector from the args
+      56           0 :   readInputLine( getShortcutLabel() + "_diag: DIAGONALIZE ARG=" + arg + " VECTORS=all");
+      57             :   // Not sure about the regexp here - check with matrix with more than 10 rows
+      58           0 :   readInputLine( getShortcutLabel() + ": PRODUCT ARG=(" + getShortcutLabel() + "_diag\.vals-[0-9])");
+      59           0 : }
+      60             : 
+      61             : }
+      62             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/DiagonalizeMatrix.cpp.func-sort-c.html b/coverage/adjmat/DiagonalizeMatrix.cpp.func-sort-c.html new file mode 100644 index 000000000000..c600be05963e --- /dev/null +++ b/coverage/adjmat/DiagonalizeMatrix.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/DiagonalizeMatrix.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - DiagonalizeMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:5757100.0 %
Date:2024-04-19 12:12:35Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat17DiagonalizeMatrixC2ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat17DiagonalizeMatrixC1ERKNS_13ActionOptionsE22
_ZN4PLMD6adjmat17DiagonalizeMatrix16registerKeywordsERNS_8KeywordsE24
_ZN4PLMD6adjmat17DiagonalizeMatrix9calculateEv122
_ZN4PLMD6adjmat17DiagonalizeMatrix7prepareEv124
_ZN4PLMD6adjmat17DiagonalizeMatrix22getNumberOfDerivativesEv276
_ZNK4PLMD6adjmat17DiagonalizeMatrix23getForceOnMatrixElementERKjS3_12495
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/DiagonalizeMatrix.cpp.func.html b/coverage/adjmat/DiagonalizeMatrix.cpp.func.html new file mode 100644 index 000000000000..e4e2b9d2225e --- /dev/null +++ b/coverage/adjmat/DiagonalizeMatrix.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/DiagonalizeMatrix.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - DiagonalizeMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:5757100.0 %
Date:2024-04-19 12:12:35Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat17DiagonalizeMatrix16registerKeywordsERNS_8KeywordsE24
_ZN4PLMD6adjmat17DiagonalizeMatrix22getNumberOfDerivativesEv276
_ZN4PLMD6adjmat17DiagonalizeMatrix7prepareEv124
_ZN4PLMD6adjmat17DiagonalizeMatrix9calculateEv122
_ZN4PLMD6adjmat17DiagonalizeMatrixC1ERKNS_13ActionOptionsE22
_ZN4PLMD6adjmat17DiagonalizeMatrixC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6adjmat17DiagonalizeMatrix23getForceOnMatrixElementERKjS3_12495
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/DiagonalizeMatrix.cpp.gcov.html b/coverage/adjmat/DiagonalizeMatrix.cpp.gcov.html new file mode 100644 index 000000000000..b616b9d1a898 --- /dev/null +++ b/coverage/adjmat/DiagonalizeMatrix.cpp.gcov.html @@ -0,0 +1,230 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/DiagonalizeMatrix.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - DiagonalizeMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:5757100.0 %
Date:2024-04-19 12:12:35Functions:6785.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2014-2017 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "MatrixOperationBase.h"
+      23             : #include "core/ActionRegister.h"
+      24             : 
+      25             : //+PLUMEDOC ANALYSIS DIAGONALIZE
+      26             : /*
+      27             : Calculate the eigenvalues and eigenvectors of a square matrix
+      28             : 
+      29             : \par Examples
+      30             : 
+      31             : */
+      32             : //+ENDPLUMEDOC
+      33             : 
+      34             : namespace PLMD {
+      35             : namespace adjmat {
+      36             : 
+      37             : class DiagonalizeMatrix : public MatrixOperationBase {
+      38             : private:
+      39             :   std::vector<unsigned> desired_vectors;
+      40             :   Matrix<double> mymatrix;
+      41             :   std::vector<double> eigvals;
+      42             :   Matrix<double> eigvecs;
+      43             : public:
+      44             :   static void registerKeywords( Keywords& keys );
+      45             : /// Constructor
+      46             :   explicit DiagonalizeMatrix(const ActionOptions&);
+      47             : /// This is required to set the number of derivatives for the eigenvalues
+      48         276 :   unsigned getNumberOfDerivatives() override { return getPntrToArgument(0)->getNumberOfValues(); }
+      49             : ///
+      50             :   void prepare() override ;
+      51             : ///
+      52             :   void calculate() override ;
+      53             : ///
+      54             :   double getForceOnMatrixElement( const unsigned& jrow, const unsigned& krow ) const override;
+      55             : };
+      56             : 
+      57             : PLUMED_REGISTER_ACTION(DiagonalizeMatrix,"DIAGONALIZE")
+      58             : 
+      59          24 : void DiagonalizeMatrix::registerKeywords( Keywords& keys ) {
+      60          24 :   MatrixOperationBase::registerKeywords( keys );
+      61          48 :   keys.add("compulsory","VECTORS","all","the eigenvalues and vectors that you would like to calculate.  1=largest, 2=second largest and so on");
+      62          48 :   keys.addOutputComponent("vals","default","the eigevalues of the input matrix");
+      63          48 :   keys.addOutputComponent("vecs","default","the eigenvectors of the input matrix");
+      64          24 : }
+      65             : 
+      66          22 : DiagonalizeMatrix::DiagonalizeMatrix(const ActionOptions& ao):
+      67             :   Action(ao),
+      68          22 :   MatrixOperationBase(ao)
+      69             : {
+      70          22 :   if( getPntrToArgument(0)->getShape()[0]!=getPntrToArgument(0)->getShape()[1] ) error("input matrix should be square");
+      71             : 
+      72          44 :   std::vector<std::string> eigv; parseVector("VECTORS",eigv);
+      73          22 :   if( eigv.size()>1 ) {
+      74          10 :     Tools::interpretRanges(eigv); desired_vectors.resize( eigv.size() );
+      75          30 :     for(unsigned i=0; i<eigv.size(); ++i) Tools::convert( eigv[i], desired_vectors[i] );
+      76             :   } else  {
+      77          12 :     if( eigv.size()==0 ) error("missing input to VECTORS keyword");
+      78             :     unsigned ivec;
+      79          12 :     if( eigv[0]=="all" ) {
+      80           7 :       desired_vectors.resize( getPntrToArgument(0)->getShape()[0] );
+      81          21 :       for(unsigned i=0; i<desired_vectors.size(); ++i) desired_vectors[i] = i + 1;
+      82             :     } else {
+      83           5 :       Tools::convert( eigv[0], ivec );
+      84           5 :       desired_vectors.resize(1); desired_vectors[0]=ivec;
+      85             :     }
+      86             :   }
+      87             : 
+      88          22 :   std::string num; std::vector<unsigned> eval_shape(0);
+      89          22 :   std::vector<unsigned> evec_shape(1); evec_shape[0] = getPntrToArgument(0)->getShape()[0];
+      90          61 :   for(unsigned i=0; i<desired_vectors.size(); ++i) {
+      91          39 :     Tools::convert( desired_vectors[i], num );
+      92          78 :     addComponent( "vals-" + num, eval_shape ); componentIsNotPeriodic( "vals-" + num );
+      93          78 :     addComponent( "vecs-" + num, evec_shape ); componentIsNotPeriodic( "vecs-" + num );
+      94             :     // Make sure eigenvalues are always stored
+      95          39 :     getPntrToComponent( 2*i+1 )->buildDataStore();
+      96             :   }
+      97             : 
+      98          22 :   std::vector<unsigned> eigvecs_shape(2); eigvecs_shape[0]=eigvecs_shape[1]=getPntrToArgument(0)->getShape()[0];
+      99          22 :   mymatrix.resize( eigvecs_shape[0], eigvecs_shape[1] ); eigvals.resize( eigvecs_shape[0] ); eigvecs.resize( eigvecs_shape[0], eigvecs_shape[1] );
+     100          22 : }
+     101             : 
+     102         124 : void DiagonalizeMatrix::prepare() {
+     103         124 :   std::vector<unsigned> shape(1); shape[0]=getPntrToArgument(0)->getShape()[0];
+     104         303 :   for(unsigned i=0; i<desired_vectors.size(); ++i) {
+     105         179 :     if( getPntrToComponent( 2*i+1 )->getShape()[0]!=shape[0] ) getPntrToComponent( 2*i+1 )->setShape( shape );
+     106             :   }
+     107             : 
+     108         124 : }
+     109             : 
+     110         122 : void DiagonalizeMatrix::calculate() {
+     111         122 :   if( getPntrToArgument(0)->getShape()[0]==0 ) return ;
+     112             :   // Resize stuff that might need resizing
+     113             :   unsigned nvals=getPntrToArgument(0)->getShape()[0];
+     114         127 :   if( eigvals.size()!=nvals ) { mymatrix.resize( nvals, nvals ); eigvals.resize( nvals ); eigvecs.resize( nvals, nvals ); }
+     115             : 
+     116             :   // Retrieve the matrix from input
+     117         122 :   retrieveFullMatrix( mymatrix );
+     118             :   // Now diagonalize the matrix
+     119         122 :   diagMat( mymatrix, eigvals, eigvecs );
+     120             :   // And set the eigenvalues and eigenvectors
+     121         297 :   for(unsigned i=0; i<desired_vectors.size(); ++i) {
+     122         175 :     getPntrToComponent(2*i)->set( eigvals[ mymatrix.ncols()-desired_vectors[i]] );
+     123         175 :     Value* evec_out = getPntrToComponent(2*i+1); unsigned vreq = mymatrix.ncols()-desired_vectors[i];
+     124        4526 :     for(unsigned j=0; j<mymatrix.ncols(); ++j) evec_out->set( j, eigvecs( vreq, j ) );
+     125             :   }
+     126             : }
+     127             : 
+     128       12495 : double DiagonalizeMatrix::getForceOnMatrixElement( const unsigned& jrow, const unsigned& kcol ) const {
+     129             :   double ff = 0;
+     130       31654 :   for(unsigned i=0; i<desired_vectors.size(); ++i) {
+     131             :     // Deal with forces on eigenvalues
+     132       19159 :     if( getConstPntrToComponent(2*i)->forcesWereAdded() ) {
+     133        8330 :       unsigned ncol = mymatrix.ncols()-desired_vectors[i];
+     134        8330 :       ff += getConstPntrToComponent(2*i)->getForce(0)*eigvecs(ncol,jrow)*eigvecs(ncol,kcol);
+     135             :     }
+     136             :     // And forces on eigenvectors
+     137       19159 :     if( !getConstPntrToComponent(2*i+1)->forcesWereAdded() ) continue;
+     138             : 
+     139        7497 :     unsigned ncol = mymatrix.ncols()-desired_vectors[i];
+     140      106624 :     for(unsigned n=0; n<mymatrix.nrows(); ++n) {
+     141             :       double tmp2 = 0;
+     142     1446088 :       for(unsigned m=0; m<mymatrix.nrows(); ++m) {
+     143     1346961 :         if( m==ncol ) continue;
+     144     1247834 :         tmp2 += eigvecs(m,n)*eigvecs(m,jrow)*eigvecs(ncol,kcol) / (eigvals[ncol]-eigvals[m]);
+     145             :       }
+     146       99127 :       ff += getConstPntrToComponent(2*i+1)->getForce(n) * tmp2;
+     147             :     }
+     148             :   }
+     149       12495 :   return ff;
+     150             : }
+     151             : 
+     152             : }
+     153             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/DistanceMatrix.cpp.func-sort-c.html b/coverage/adjmat/DistanceMatrix.cpp.func-sort-c.html new file mode 100644 index 000000000000..23365646333b --- /dev/null +++ b/coverage/adjmat/DistanceMatrix.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/DistanceMatrix.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - DistanceMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2121100.0 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat14DistanceMatrixC2ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat14DistanceMatrixC1ERKNS_13ActionOptionsE92
_ZN4PLMD6adjmat14DistanceMatrix16registerKeywordsERNS_8KeywordsE94
_ZNK4PLMD6adjmat14DistanceMatrix15calculateWeightERKNS_13VectorGenericILj3EEES5_RKjRNS_10MultiValueE5857010
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/DistanceMatrix.cpp.func.html b/coverage/adjmat/DistanceMatrix.cpp.func.html new file mode 100644 index 000000000000..47b4d06048d1 --- /dev/null +++ b/coverage/adjmat/DistanceMatrix.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/DistanceMatrix.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - DistanceMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2121100.0 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat14DistanceMatrix16registerKeywordsERNS_8KeywordsE94
_ZN4PLMD6adjmat14DistanceMatrixC1ERKNS_13ActionOptionsE92
_ZN4PLMD6adjmat14DistanceMatrixC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6adjmat14DistanceMatrix15calculateWeightERKNS_13VectorGenericILj3EEES5_RKjRNS_10MultiValueE5857010
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/DistanceMatrix.cpp.gcov.html b/coverage/adjmat/DistanceMatrix.cpp.gcov.html new file mode 100644 index 000000000000..16976251c071 --- /dev/null +++ b/coverage/adjmat/DistanceMatrix.cpp.gcov.html @@ -0,0 +1,164 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/DistanceMatrix.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - DistanceMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2121100.0 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2017 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received 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 "core/ActionRegister.h"
+      24             : #include "tools/SwitchingFunction.h"
+      25             : #include "tools/Matrix.h"
+      26             : 
+      27             : //+PLUMEDOC MATRIX DISTANCE_MATRIX
+      28             : /*
+      29             : Calculate a matrix of distances
+      30             : 
+      31             : \par Examples
+      32             : 
+      33             : */
+      34             : //+ENDPLUMEDOC
+      35             : 
+      36             : 
+      37             : namespace PLMD {
+      38             : namespace adjmat {
+      39             : 
+      40             : class DistanceMatrix : public AdjacencyMatrixBase {
+      41             : private:
+      42             :   double cutoff;
+      43             : public:
+      44             : /// Create manual
+      45             :   static void registerKeywords( Keywords& keys );
+      46             : /// Constructor
+      47             :   explicit DistanceMatrix(const ActionOptions&);
+      48             : /// This does nothing
+      49             :   double calculateWeight( const Vector& pos1, const Vector& pos2, const unsigned& natoms, MultiValue& myvals ) const ;
+      50             : };
+      51             : 
+      52             : PLUMED_REGISTER_ACTION(DistanceMatrix,"DISTANCE_MATRIX")
+      53             : 
+      54          94 : void DistanceMatrix::registerKeywords( Keywords& keys ) {
+      55          94 :   AdjacencyMatrixBase::registerKeywords( keys );
+      56         188 :   keys.add("compulsory","CUTOFF","-1","ignore distances that have a value larger than this cutoff");
+      57          94 : }
+      58             : 
+      59          92 : DistanceMatrix::DistanceMatrix( const ActionOptions& ao ):
+      60             :   Action(ao),
+      61          92 :   AdjacencyMatrixBase(ao)
+      62             : {
+      63             :   // And set the link cell cutoff
+      64          92 :   log.printf("  weight is distance between atoms \n");
+      65          92 :   parse("CUTOFF",cutoff);
+      66          92 :   if( cutoff<0 ) {
+      67           5 :     setLinkCellCutoff( true, std::numeric_limits<double>::max() );
+      68             :   } else {
+      69          87 :     log.printf("  ignoring distances that are larger than %f \n", cutoff);
+      70          87 :     setLinkCellCutoff( true, cutoff );
+      71             :   }
+      72          92 : }
+      73             : 
+      74     5857010 : double DistanceMatrix::calculateWeight( const Vector& pos1, const Vector& pos2, const unsigned& natoms, MultiValue& myvals ) const {
+      75     5857010 :   Vector distance = pos2; double mod = distance.modulo();
+      76     5857010 :   if( cutoff<0 || mod<cutoff ) {
+      77     5157580 :     double invd = 1.0/mod;
+      78     5157580 :     addAtomDerivatives( 0, (-invd)*distance, myvals );
+      79     5157580 :     addAtomDerivatives( 1, (+invd)*distance, myvals );
+      80     5157580 :     addBoxDerivatives( (-invd)*Tensor(distance,distance), myvals );
+      81             :   }
+      82     5857010 :   return mod;
+      83             : }
+      84             : 
+      85             : }
+      86             : }
+      87             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/FunctionOfMatrix.h.func-sort-c.html b/coverage/adjmat/FunctionOfMatrix.h.func-sort-c.html new file mode 100644 index 000000000000..ff1278762e62 --- /dev/null +++ b/coverage/adjmat/FunctionOfMatrix.h.func-sort-c.html @@ -0,0 +1,505 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/FunctionOfMatrix.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - FunctionOfMatrix.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:19120792.3 %
Date:2024-04-19 12:12:35Functions:8510878.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat16FunctionOfMatrixINS_8function8LessThanEE17turnOnDerivativesEv0
_ZN4PLMD6adjmat16FunctionOfMatrixINS_8function8LessThanEE22getNumberOfDerivativesEv0
_ZN4PLMD6adjmat16FunctionOfMatrixINS_8function8MoreThanEE17turnOnDerivativesEv0
_ZN4PLMD6adjmat16FunctionOfMatrixINS_8function8MoreThanEE22getNumberOfDerivativesEv0
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_7symfunc17SphericalHarmonicEE12setupForTaskERKjRSt6vectorIjSaIjEERNS_10MultiValueE0
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_7symfunc17SphericalHarmonicEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_7symfunc17SphericalHarmonicEE18getNumberOfColumnsEv0
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_7symfunc19CylindricalHarmonicEE12setupForTaskERKjRSt6vectorIjSaIjEERNS_10MultiValueE0
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_7symfunc19CylindricalHarmonicEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_7symfunc7FccubicEE12setupForTaskERKjRSt6vectorIjSaIjEERNS_10MultiValueE0
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_7symfunc7FccubicEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_7symfunc7FccubicEE18getNumberOfColumnsEv0
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_8function3SumEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_8function3SumEE18getNumberOfColumnsEv0
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_8function6CustomEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_8function7BetweenEE12setupForTaskERKjRSt6vectorIjSaIjEERNS_10MultiValueE0
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_8function7BetweenEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_8function7BetweenEE18getNumberOfColumnsEv0
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_8function7CombineEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_8function8LessThanEE12setupForTaskERKjRSt6vectorIjSaIjEERNS_10MultiValueE0
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_8function8LessThanEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_8function8LessThanEE18getNumberOfColumnsEv0
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_8function8MoreThanEE12writeInGraphB5cxx11Ev0
_ZN4PLMD6adjmat16FunctionOfMatrixINS_8function7BetweenEE26getValueShapeFromArgumentsEv1
_ZN4PLMD6adjmat16FunctionOfMatrixINS_8function7BetweenEEC1ERKNS_13ActionOptionsE1
_ZN4PLMD6adjmat16FunctionOfMatrixINS_8function8LessThanEE26getValueShapeFromArgumentsEv1
_ZN4PLMD6adjmat16FunctionOfMatrixINS_8function8LessThanEEC1ERKNS_13ActionOptionsE1
_ZN4PLMD6adjmat16FunctionOfMatrixINS_7symfunc19CylindricalHarmonicEE26getValueShapeFromArgumentsEv2
_ZN4PLMD6adjmat16FunctionOfMatrixINS_7symfunc19CylindricalHarmonicEEC1ERKNS_13ActionOptionsE2
_ZN4PLMD6adjmat16FunctionOfMatrixINS_8function7BetweenEE17turnOnDerivativesEv2
_ZN4PLMD6adjmat16FunctionOfMatrixINS_8function7BetweenEE22getNumberOfDerivativesEv2
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_8function7CombineEE18getNumberOfColumnsEv2
_ZN4PLMD6adjmat16FunctionOfMatrixINS_8function7BetweenEE16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD6adjmat16FunctionOfMatrixINS_8function8LessThanEE16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD6adjmat16FunctionOfMatrixINS_7symfunc19CylindricalHarmonicEE16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD6adjmat16FunctionOfMatrixINS_7symfunc19CylindricalHarmonicEE17turnOnDerivativesEv4
_ZN4PLMD6adjmat16FunctionOfMatrixINS_7symfunc7FccubicEE26getValueShapeFromArgumentsEv5
_ZN4PLMD6adjmat16FunctionOfMatrixINS_7symfunc7FccubicEEC1ERKNS_13ActionOptionsE5
_ZN4PLMD6adjmat16FunctionOfMatrixINS_8function7BetweenEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSD_SD_SD_5
_ZN4PLMD6adjmat16FunctionOfMatrixINS_8function7BetweenEE7prepareEv5
_ZN4PLMD6adjmat16FunctionOfMatrixINS_8function8LessThanEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSD_SD_SD_5
_ZN4PLMD6adjmat16FunctionOfMatrixINS_8function8LessThanEE7prepareEv5
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_8function7CombineEE12setupForTaskERKjRSt6vectorIjSaIjEERNS_10MultiValueE5
_ZN4PLMD6adjmat16FunctionOfMatrixINS_8function8MoreThanEE26getValueShapeFromArgumentsEv6
_ZN4PLMD6adjmat16FunctionOfMatrixINS_8function8MoreThanEEC1ERKNS_13ActionOptionsE6
_ZN4PLMD6adjmat16FunctionOfMatrixINS_7symfunc7FccubicEE16registerKeywordsERNS_8KeywordsE7
_ZN4PLMD6adjmat16FunctionOfMatrixINS_7symfunc19CylindricalHarmonicEE22getNumberOfDerivativesEv8
_ZN4PLMD6adjmat16FunctionOfMatrixINS_8function8MoreThanEE16registerKeywordsERNS_8KeywordsE8
_ZN4PLMD6adjmat16FunctionOfMatrixINS_7symfunc19CylindricalHarmonicEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSD_SD_SD_10
_ZN4PLMD6adjmat16FunctionOfMatrixINS_7symfunc19CylindricalHarmonicEE7prepareEv10
_ZN4PLMD6adjmat16FunctionOfMatrixINS_7symfunc7FccubicEE7prepareEv12
_ZN4PLMD6adjmat16FunctionOfMatrixINS_8function8MoreThanEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSD_SD_SD_12
_ZN4PLMD6adjmat16FunctionOfMatrixINS_8function8MoreThanEE7prepareEv13
_ZN4PLMD6adjmat16FunctionOfMatrixINS_7symfunc7FccubicEE17turnOnDerivativesEv14
_ZN4PLMD6adjmat16FunctionOfMatrixINS_7symfunc7FccubicEE22getNumberOfDerivativesEv14
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_8function8MoreThanEE18getNumberOfColumnsEv14
_ZN4PLMD6adjmat16FunctionOfMatrixINS_7symfunc7FccubicEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSD_SD_SD_17
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_7symfunc19CylindricalHarmonicEE18getNumberOfColumnsEv20
_ZN4PLMD6adjmat16FunctionOfMatrixINS_8function7CombineEE26getValueShapeFromArgumentsEv26
_ZN4PLMD6adjmat16FunctionOfMatrixINS_8function7CombineEEC1ERKNS_13ActionOptionsE26
_ZN4PLMD6adjmat16FunctionOfMatrixINS_8function7CombineEE16registerKeywordsERNS_8KeywordsE28
_ZN4PLMD6adjmat16FunctionOfMatrixINS_8function7CombineEE17turnOnDerivativesEv30
_ZN4PLMD6adjmat16FunctionOfMatrixINS_8function7CombineEE22getNumberOfDerivativesEv30
_ZN4PLMD6adjmat16FunctionOfMatrixINS_7symfunc17SphericalHarmonicEE26getValueShapeFromArgumentsEv41
_ZN4PLMD6adjmat16FunctionOfMatrixINS_7symfunc17SphericalHarmonicEEC1ERKNS_13ActionOptionsE41
_ZN4PLMD6adjmat16FunctionOfMatrixINS_8function3SumEE26getValueShapeFromArgumentsEv41
_ZN4PLMD6adjmat16FunctionOfMatrixINS_8function3SumEEC1ERKNS_13ActionOptionsE41
_ZN4PLMD6adjmat16FunctionOfMatrixINS_7symfunc17SphericalHarmonicEE16registerKeywordsERNS_8KeywordsE43
_ZN4PLMD6adjmat16FunctionOfMatrixINS_8function3SumEE16registerKeywordsERNS_8KeywordsE43
_ZN4PLMD6adjmat16FunctionOfMatrixINS_8function3SumEE17turnOnDerivativesEv44
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_8function3SumEE12setupForTaskERKjRSt6vectorIjSaIjEERNS_10MultiValueE51
_ZN4PLMD6adjmat16FunctionOfMatrixINS_7symfunc17SphericalHarmonicEE7prepareEv114
_ZN4PLMD6adjmat16FunctionOfMatrixINS_8function7CombineEE7prepareEv165
_ZN4PLMD6adjmat16FunctionOfMatrixINS_8function7CombineEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSD_SD_SD_170
_ZN4PLMD6adjmat16FunctionOfMatrixINS_7symfunc17SphericalHarmonicEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSD_SD_SD_188
_ZN4PLMD6adjmat16FunctionOfMatrixINS_8function3SumEE7prepareEv189
_ZN4PLMD6adjmat16FunctionOfMatrixINS_8function3SumEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSD_SD_SD_195
_ZN4PLMD6adjmat16FunctionOfMatrixINS_8function3SumEE22getNumberOfDerivativesEv233
_ZN4PLMD6adjmat16FunctionOfMatrixINS_8function6CustomEE26getValueShapeFromArgumentsEv369
_ZN4PLMD6adjmat16FunctionOfMatrixINS_8function6CustomEEC1ERKNS_13ActionOptionsE369
_ZN4PLMD6adjmat16FunctionOfMatrixINS_8function6CustomEE16registerKeywordsERNS_8KeywordsE373
_ZN4PLMD6adjmat16FunctionOfMatrixINS_8function6CustomEE17turnOnDerivativesEv398
_ZN4PLMD6adjmat16FunctionOfMatrixINS_8function6CustomEE22getNumberOfDerivativesEv398
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_8function7BetweenEE15runEndOfRowJobsERKjRKSt6vectorIjSaIjEERNS_10MultiValueE495
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_8function8LessThanEE15runEndOfRowJobsERKjRKSt6vectorIjSaIjEERNS_10MultiValueE495
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_8function8MoreThanEE12setupForTaskERKjRSt6vectorIjSaIjEERNS_10MultiValueE750
_ZN4PLMD6adjmat16FunctionOfMatrixINS_7symfunc17SphericalHarmonicEE17turnOnDerivativesEv1429
_ZN4PLMD6adjmat16FunctionOfMatrixINS_8function6CustomEE7prepareEv1716
_ZN4PLMD6adjmat16FunctionOfMatrixINS_8function6CustomEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSD_SD_SD_1923
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_8function8MoreThanEE15runEndOfRowJobsERKjRKSt6vectorIjSaIjEERNS_10MultiValueE1995
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_8function6CustomEE12setupForTaskERKjRSt6vectorIjSaIjEERNS_10MultiValueE3403
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_7symfunc19CylindricalHarmonicEE15runEndOfRowJobsERKjRKSt6vectorIjSaIjEERNS_10MultiValueE4000
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_8function3SumEE15runEndOfRowJobsERKjRKSt6vectorIjSaIjEERNS_10MultiValueE8109
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_8function7CombineEE15runEndOfRowJobsERKjRKSt6vectorIjSaIjEERNS_10MultiValueE20398
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_7symfunc7FccubicEE15runEndOfRowJobsERKjRKSt6vectorIjSaIjEERNS_10MultiValueE26068
_ZN4PLMD6adjmat16FunctionOfMatrixINS_7symfunc17SphericalHarmonicEE22getNumberOfDerivativesEv29726
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_7symfunc17SphericalHarmonicEE15runEndOfRowJobsERKjRKSt6vectorIjSaIjEERNS_10MultiValueE30666
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_8function7BetweenEE11performTaskERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjSE_RNS_10MultiValueE48510
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_8function8LessThanEE11performTaskERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjSE_RNS_10MultiValueE48510
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_8function6CustomEE15runEndOfRowJobsERKjRKSt6vectorIjSaIjEERNS_10MultiValueE134163
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_8function6CustomEE18getNumberOfColumnsEv281808
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_8function8MoreThanEE11performTaskERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjSE_RNS_10MultiValueE503510
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_8function3SumEE11performTaskERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjSE_RNS_10MultiValueE606751
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_7symfunc19CylindricalHarmonicEE11performTaskERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjSE_RNS_10MultiValueE943610
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_7symfunc17SphericalHarmonicEE11performTaskERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjSE_RNS_10MultiValueE1742755
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_7symfunc7FccubicEE11performTaskERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjSE_RNS_10MultiValueE2486314
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_8function7CombineEE11performTaskERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjSE_RNS_10MultiValueE3980129
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_8function6CustomEE11performTaskERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjSE_RNS_10MultiValueE17568562
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/FunctionOfMatrix.h.func.html b/coverage/adjmat/FunctionOfMatrix.h.func.html new file mode 100644 index 000000000000..e82ce9cdb2cf --- /dev/null +++ b/coverage/adjmat/FunctionOfMatrix.h.func.html @@ -0,0 +1,505 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/FunctionOfMatrix.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - FunctionOfMatrix.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:19120792.3 %
Date:2024-04-19 12:12:35Functions:8510878.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat16FunctionOfMatrixINS_7symfunc17SphericalHarmonicEE16registerKeywordsERNS_8KeywordsE43
_ZN4PLMD6adjmat16FunctionOfMatrixINS_7symfunc17SphericalHarmonicEE17turnOnDerivativesEv1429
_ZN4PLMD6adjmat16FunctionOfMatrixINS_7symfunc17SphericalHarmonicEE22getNumberOfDerivativesEv29726
_ZN4PLMD6adjmat16FunctionOfMatrixINS_7symfunc17SphericalHarmonicEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSD_SD_SD_188
_ZN4PLMD6adjmat16FunctionOfMatrixINS_7symfunc17SphericalHarmonicEE26getValueShapeFromArgumentsEv41
_ZN4PLMD6adjmat16FunctionOfMatrixINS_7symfunc17SphericalHarmonicEE7prepareEv114
_ZN4PLMD6adjmat16FunctionOfMatrixINS_7symfunc17SphericalHarmonicEEC1ERKNS_13ActionOptionsE41
_ZN4PLMD6adjmat16FunctionOfMatrixINS_7symfunc19CylindricalHarmonicEE16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD6adjmat16FunctionOfMatrixINS_7symfunc19CylindricalHarmonicEE17turnOnDerivativesEv4
_ZN4PLMD6adjmat16FunctionOfMatrixINS_7symfunc19CylindricalHarmonicEE22getNumberOfDerivativesEv8
_ZN4PLMD6adjmat16FunctionOfMatrixINS_7symfunc19CylindricalHarmonicEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSD_SD_SD_10
_ZN4PLMD6adjmat16FunctionOfMatrixINS_7symfunc19CylindricalHarmonicEE26getValueShapeFromArgumentsEv2
_ZN4PLMD6adjmat16FunctionOfMatrixINS_7symfunc19CylindricalHarmonicEE7prepareEv10
_ZN4PLMD6adjmat16FunctionOfMatrixINS_7symfunc19CylindricalHarmonicEEC1ERKNS_13ActionOptionsE2
_ZN4PLMD6adjmat16FunctionOfMatrixINS_7symfunc7FccubicEE16registerKeywordsERNS_8KeywordsE7
_ZN4PLMD6adjmat16FunctionOfMatrixINS_7symfunc7FccubicEE17turnOnDerivativesEv14
_ZN4PLMD6adjmat16FunctionOfMatrixINS_7symfunc7FccubicEE22getNumberOfDerivativesEv14
_ZN4PLMD6adjmat16FunctionOfMatrixINS_7symfunc7FccubicEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSD_SD_SD_17
_ZN4PLMD6adjmat16FunctionOfMatrixINS_7symfunc7FccubicEE26getValueShapeFromArgumentsEv5
_ZN4PLMD6adjmat16FunctionOfMatrixINS_7symfunc7FccubicEE7prepareEv12
_ZN4PLMD6adjmat16FunctionOfMatrixINS_7symfunc7FccubicEEC1ERKNS_13ActionOptionsE5
_ZN4PLMD6adjmat16FunctionOfMatrixINS_8function3SumEE16registerKeywordsERNS_8KeywordsE43
_ZN4PLMD6adjmat16FunctionOfMatrixINS_8function3SumEE17turnOnDerivativesEv44
_ZN4PLMD6adjmat16FunctionOfMatrixINS_8function3SumEE22getNumberOfDerivativesEv233
_ZN4PLMD6adjmat16FunctionOfMatrixINS_8function3SumEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSD_SD_SD_195
_ZN4PLMD6adjmat16FunctionOfMatrixINS_8function3SumEE26getValueShapeFromArgumentsEv41
_ZN4PLMD6adjmat16FunctionOfMatrixINS_8function3SumEE7prepareEv189
_ZN4PLMD6adjmat16FunctionOfMatrixINS_8function3SumEEC1ERKNS_13ActionOptionsE41
_ZN4PLMD6adjmat16FunctionOfMatrixINS_8function6CustomEE16registerKeywordsERNS_8KeywordsE373
_ZN4PLMD6adjmat16FunctionOfMatrixINS_8function6CustomEE17turnOnDerivativesEv398
_ZN4PLMD6adjmat16FunctionOfMatrixINS_8function6CustomEE22getNumberOfDerivativesEv398
_ZN4PLMD6adjmat16FunctionOfMatrixINS_8function6CustomEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSD_SD_SD_1923
_ZN4PLMD6adjmat16FunctionOfMatrixINS_8function6CustomEE26getValueShapeFromArgumentsEv369
_ZN4PLMD6adjmat16FunctionOfMatrixINS_8function6CustomEE7prepareEv1716
_ZN4PLMD6adjmat16FunctionOfMatrixINS_8function6CustomEEC1ERKNS_13ActionOptionsE369
_ZN4PLMD6adjmat16FunctionOfMatrixINS_8function7BetweenEE16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD6adjmat16FunctionOfMatrixINS_8function7BetweenEE17turnOnDerivativesEv2
_ZN4PLMD6adjmat16FunctionOfMatrixINS_8function7BetweenEE22getNumberOfDerivativesEv2
_ZN4PLMD6adjmat16FunctionOfMatrixINS_8function7BetweenEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSD_SD_SD_5
_ZN4PLMD6adjmat16FunctionOfMatrixINS_8function7BetweenEE26getValueShapeFromArgumentsEv1
_ZN4PLMD6adjmat16FunctionOfMatrixINS_8function7BetweenEE7prepareEv5
_ZN4PLMD6adjmat16FunctionOfMatrixINS_8function7BetweenEEC1ERKNS_13ActionOptionsE1
_ZN4PLMD6adjmat16FunctionOfMatrixINS_8function7CombineEE16registerKeywordsERNS_8KeywordsE28
_ZN4PLMD6adjmat16FunctionOfMatrixINS_8function7CombineEE17turnOnDerivativesEv30
_ZN4PLMD6adjmat16FunctionOfMatrixINS_8function7CombineEE22getNumberOfDerivativesEv30
_ZN4PLMD6adjmat16FunctionOfMatrixINS_8function7CombineEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSD_SD_SD_170
_ZN4PLMD6adjmat16FunctionOfMatrixINS_8function7CombineEE26getValueShapeFromArgumentsEv26
_ZN4PLMD6adjmat16FunctionOfMatrixINS_8function7CombineEE7prepareEv165
_ZN4PLMD6adjmat16FunctionOfMatrixINS_8function7CombineEEC1ERKNS_13ActionOptionsE26
_ZN4PLMD6adjmat16FunctionOfMatrixINS_8function8LessThanEE16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD6adjmat16FunctionOfMatrixINS_8function8LessThanEE17turnOnDerivativesEv0
_ZN4PLMD6adjmat16FunctionOfMatrixINS_8function8LessThanEE22getNumberOfDerivativesEv0
_ZN4PLMD6adjmat16FunctionOfMatrixINS_8function8LessThanEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSD_SD_SD_5
_ZN4PLMD6adjmat16FunctionOfMatrixINS_8function8LessThanEE26getValueShapeFromArgumentsEv1
_ZN4PLMD6adjmat16FunctionOfMatrixINS_8function8LessThanEE7prepareEv5
_ZN4PLMD6adjmat16FunctionOfMatrixINS_8function8LessThanEEC1ERKNS_13ActionOptionsE1
_ZN4PLMD6adjmat16FunctionOfMatrixINS_8function8MoreThanEE16registerKeywordsERNS_8KeywordsE8
_ZN4PLMD6adjmat16FunctionOfMatrixINS_8function8MoreThanEE17turnOnDerivativesEv0
_ZN4PLMD6adjmat16FunctionOfMatrixINS_8function8MoreThanEE22getNumberOfDerivativesEv0
_ZN4PLMD6adjmat16FunctionOfMatrixINS_8function8MoreThanEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSD_SD_SD_12
_ZN4PLMD6adjmat16FunctionOfMatrixINS_8function8MoreThanEE26getValueShapeFromArgumentsEv6
_ZN4PLMD6adjmat16FunctionOfMatrixINS_8function8MoreThanEE7prepareEv13
_ZN4PLMD6adjmat16FunctionOfMatrixINS_8function8MoreThanEEC1ERKNS_13ActionOptionsE6
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_7symfunc17SphericalHarmonicEE11performTaskERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjSE_RNS_10MultiValueE1742755
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_7symfunc17SphericalHarmonicEE12setupForTaskERKjRSt6vectorIjSaIjEERNS_10MultiValueE0
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_7symfunc17SphericalHarmonicEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_7symfunc17SphericalHarmonicEE15runEndOfRowJobsERKjRKSt6vectorIjSaIjEERNS_10MultiValueE30666
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_7symfunc17SphericalHarmonicEE18getNumberOfColumnsEv0
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_7symfunc19CylindricalHarmonicEE11performTaskERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjSE_RNS_10MultiValueE943610
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_7symfunc19CylindricalHarmonicEE12setupForTaskERKjRSt6vectorIjSaIjEERNS_10MultiValueE0
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_7symfunc19CylindricalHarmonicEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_7symfunc19CylindricalHarmonicEE15runEndOfRowJobsERKjRKSt6vectorIjSaIjEERNS_10MultiValueE4000
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_7symfunc19CylindricalHarmonicEE18getNumberOfColumnsEv20
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_7symfunc7FccubicEE11performTaskERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjSE_RNS_10MultiValueE2486314
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_7symfunc7FccubicEE12setupForTaskERKjRSt6vectorIjSaIjEERNS_10MultiValueE0
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_7symfunc7FccubicEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_7symfunc7FccubicEE15runEndOfRowJobsERKjRKSt6vectorIjSaIjEERNS_10MultiValueE26068
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_7symfunc7FccubicEE18getNumberOfColumnsEv0
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_8function3SumEE11performTaskERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjSE_RNS_10MultiValueE606751
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_8function3SumEE12setupForTaskERKjRSt6vectorIjSaIjEERNS_10MultiValueE51
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_8function3SumEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_8function3SumEE15runEndOfRowJobsERKjRKSt6vectorIjSaIjEERNS_10MultiValueE8109
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_8function3SumEE18getNumberOfColumnsEv0
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_8function6CustomEE11performTaskERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjSE_RNS_10MultiValueE17568562
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_8function6CustomEE12setupForTaskERKjRSt6vectorIjSaIjEERNS_10MultiValueE3403
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_8function6CustomEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_8function6CustomEE15runEndOfRowJobsERKjRKSt6vectorIjSaIjEERNS_10MultiValueE134163
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_8function6CustomEE18getNumberOfColumnsEv281808
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_8function7BetweenEE11performTaskERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjSE_RNS_10MultiValueE48510
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_8function7BetweenEE12setupForTaskERKjRSt6vectorIjSaIjEERNS_10MultiValueE0
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_8function7BetweenEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_8function7BetweenEE15runEndOfRowJobsERKjRKSt6vectorIjSaIjEERNS_10MultiValueE495
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_8function7BetweenEE18getNumberOfColumnsEv0
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_8function7CombineEE11performTaskERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjSE_RNS_10MultiValueE3980129
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_8function7CombineEE12setupForTaskERKjRSt6vectorIjSaIjEERNS_10MultiValueE5
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_8function7CombineEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_8function7CombineEE15runEndOfRowJobsERKjRKSt6vectorIjSaIjEERNS_10MultiValueE20398
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_8function7CombineEE18getNumberOfColumnsEv2
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_8function8LessThanEE11performTaskERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjSE_RNS_10MultiValueE48510
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_8function8LessThanEE12setupForTaskERKjRSt6vectorIjSaIjEERNS_10MultiValueE0
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_8function8LessThanEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_8function8LessThanEE15runEndOfRowJobsERKjRKSt6vectorIjSaIjEERNS_10MultiValueE495
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_8function8LessThanEE18getNumberOfColumnsEv0
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_8function8MoreThanEE11performTaskERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjSE_RNS_10MultiValueE503510
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_8function8MoreThanEE12setupForTaskERKjRSt6vectorIjSaIjEERNS_10MultiValueE750
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_8function8MoreThanEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_8function8MoreThanEE15runEndOfRowJobsERKjRKSt6vectorIjSaIjEERNS_10MultiValueE1995
_ZNK4PLMD6adjmat16FunctionOfMatrixINS_8function8MoreThanEE18getNumberOfColumnsEv14
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/FunctionOfMatrix.h.gcov.html b/coverage/adjmat/FunctionOfMatrix.h.gcov.html new file mode 100644 index 000000000000..e47167f8d178 --- /dev/null +++ b/coverage/adjmat/FunctionOfMatrix.h.gcov.html @@ -0,0 +1,514 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/FunctionOfMatrix.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - FunctionOfMatrix.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:19120792.3 %
Date:2024-04-19 12:12:35Functions:8510878.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2020 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a 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_FunctionOfMatrix_h
+      23             : #define __PLUMED_adjmat_FunctionOfMatrix_h
+      24             : 
+      25             : #include "ActionWithMatrix.h"
+      26             : #include "AdjacencyMatrixBase.h"
+      27             : #include "function/FunctionOfVector.h"
+      28             : #include "function/Sum.h"
+      29             : #include "tools/Matrix.h"
+      30             : 
+      31             : namespace PLMD {
+      32             : namespace adjmat {
+      33             : 
+      34             : template <class T>
+      35             : class FunctionOfMatrix : public ActionWithMatrix {
+      36             : private:
+      37             : /// Is this the first step of the calculation
+      38             :   bool firststep;
+      39             : /// The function that is being computed
+      40             :   T myfunc;
+      41             : /// The number of derivatives for this action
+      42             :   unsigned nderivatives;
+      43             : /// A vector that tells us if we have stored the input value
+      44             :   std::vector<bool> stored_arguments;
+      45             : /// Switch off updating the arguments for this action
+      46             :   std::vector<bool> update_arguments;
+      47             : /// The list of actiosn in this chain
+      48             :   std::vector<std::string> actionsLabelsInChain;
+      49             : /// Get the shape of the output matrix
+      50             :   std::vector<unsigned> getValueShapeFromArguments();
+      51             : public:
+      52             :   static void registerKeywords(Keywords&);
+      53             :   explicit FunctionOfMatrix(const ActionOptions&);
+      54             : /// Get the label to write in the graph
+      55           0 :   std::string writeInGraph() const override { return myfunc.getGraphInfo( getName() ); }
+      56             : /// Make sure the derivatives are turned on
+      57             :   void turnOnDerivatives() override;
+      58             : /// Get the number of derivatives for this action
+      59             :   unsigned getNumberOfDerivatives() override ;
+      60             : /// Resize the matrices
+      61             :   void prepare() override ;
+      62             : /// This gets the number of columns
+      63             :   unsigned getNumberOfColumns() const override ;
+      64             : /// This checks for tasks in the parent class
+      65             : //  void buildTaskListFromArgumentRequests( const unsigned& ntasks, bool& reduce, std::set<AtomNumber>& otasks ) override ;
+      66             : /// This ensures that we create some bookeeping stuff during the first step
+      67             :   void setupStreamedComponents( const std::string& headstr, unsigned& nquants, unsigned& nmat, unsigned& maxcol, unsigned& nbookeeping ) override ;
+      68             : /// This sets up for the task
+      69             :   void setupForTask( const unsigned& task_index, std::vector<unsigned>& indices, MultiValue& myvals ) const ;
+      70             : /// Calculate the full matrix
+      71             :   void performTask( const std::string& controller, const unsigned& index1, const unsigned& index2, MultiValue& myvals ) const override ;
+      72             : /// This updates the indices for the matrix
+      73             : //  void updateCentralMatrixIndex( const unsigned& ind, const std::vector<unsigned>& indices, MultiValue& myvals ) const override ;
+      74             :   void runEndOfRowJobs( const unsigned& ind, const std::vector<unsigned> & indices, MultiValue& myvals ) const override ;
+      75             : };
+      76             : 
+      77             : template <class T>
+      78         512 : void FunctionOfMatrix<T>::registerKeywords(Keywords& keys ) {
+      79         512 :   ActionWithMatrix::registerKeywords(keys); keys.use("ARG");
+      80        1024 :   keys.add("hidden","NO_ACTION_LOG","suppresses printing from action on the log");
+      81        1024 :   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");
+      82         512 :   T tfunc; tfunc.registerKeywords( keys );
+      83         512 : }
+      84             : 
+      85             : template <class T>
+      86         492 : FunctionOfMatrix<T>::FunctionOfMatrix(const ActionOptions&ao):
+      87             :   Action(ao),
+      88             :   ActionWithMatrix(ao),
+      89         492 :   firststep(true)
+      90             : {
+      91         449 :   if( myfunc.getArgStart()>0 ) error("this has not beeen implemented -- if you are interested email gareth.tribello@gmail.com");
+      92             :   // Get the shape of the output
+      93         492 :   std::vector<unsigned> shape( getValueShapeFromArguments() );
+      94             :   // Check if the output matrix is symmetric
+      95         492 :   bool symmetric=true; unsigned argstart=myfunc.getArgStart();
+      96        1496 :   for(unsigned i=argstart; i<getNumberOfArguments(); ++i) {
+      97        1004 :     if( getPntrToArgument(i)->getRank()==2 ) {
+      98         939 :       if( !getPntrToArgument(i)->isSymmetric() ) { symmetric=false;  }
+      99             :     }
+     100             :   }
+     101             :   // Read the input and do some checks
+     102         492 :   myfunc.read( this );
+     103             :   // Setup to do this in chain if possible
+     104         492 :   if( myfunc.doWithTasks() ) done_in_chain=true;
+     105             :   // Check we are not calculating a sum
+     106          41 :   if( myfunc.zeroRank() ) shape.resize(0);
+     107             :   // Get the names of the components
+     108         492 :   std::vector<std::string> components( keywords.getOutputComponents() );
+     109             :   // Create the values to hold the output
+     110          41 :   std::vector<std::string> str_ind( myfunc.getComponentsPerLabel() );
+     111          41 :   if( components.size()==0 && myfunc.zeroRank() && str_ind.size()==0 ) {
+     112          41 :     addValueWithDerivatives( shape );
+     113           0 :   } else if( components.size()==0 && myfunc.zeroRank() ) {
+     114             :     for(unsigned j=0; j<str_ind.size(); ++j) addComponentWithDerivatives( str_ind[j], shape );
+     115         451 :   } else if( components.size()==0 && str_ind.size()==0 ) {
+     116         408 :     addValue( shape ); getPntrToComponent(0)->setSymmetric( symmetric );
+     117          43 :   } else if ( components.size()==0 ) {
+     118           0 :     for(unsigned j=0; j<str_ind.size(); ++j) { addComponent( str_ind[j], shape ); getPntrToComponent(j)->setSymmetric( symmetric ); }
+     119             :   } else {
+     120         129 :     for(unsigned i=0; i<components.size(); ++i) {
+     121          82 :       if( str_ind.size()>0 ) {
+     122         752 :         for(unsigned j=0; j<str_ind.size(); ++j) { addComponent( components[i] + str_ind[j], shape ); getPntrToComponent(i*str_ind.size()+j)->setSymmetric( symmetric ); }
+     123           4 :       } else if( components[i].find_first_of("_")!=std::string::npos ) {
+     124           0 :         if( getNumberOfArguments()-argstart==1 ) { addValue( shape ); getPntrToComponent(0)->setSymmetric( symmetric ); }
+     125             :         else {
+     126           0 :           for(unsigned j=argstart; j<getNumberOfArguments(); ++j) {
+     127           0 :             addComponent( getPntrToArgument(j)->getName() + components[i], shape );
+     128           0 :             getPntrToComponent(i*(getNumberOfArguments()-argstart)+j-argstart)->setSymmetric( symmetric );
+     129             :           }
+     130             :         }
+     131           4 :       } else { addComponent( components[i], shape ); getPntrToComponent(i)->setSymmetric( symmetric ); }
+     132             :     }
+     133             :   }
+     134             :   // Check if this is a timeseries
+     135             :   // for(unsigned i=argstart; i<getNumberOfArguments();++i) {
+     136             :   //   if( getPntrToArgument(i)->isTimeSeries() ) {
+     137             :   //       for(unsigned i=0; i<getNumberOfComponents(); ++i) getPntrToOutput(i)->makeHistoryDependent();
+     138             :   //       break;
+     139             :   //   }
+     140             :   // }
+     141             :   // Check if this can be sped up
+     142         369 :   if( myfunc.getDerivativeZeroIfValueIsZero() )  {
+     143         172 :     for(int i=0; i<getNumberOfComponents(); ++i) getPntrToComponent(i)->setDerivativeIsZeroWhenValueIsZero();
+     144             :   }
+     145             :   // Set the periodicities of the output components
+     146         492 :   myfunc.setPeriodicityForOutputs( this );
+     147             :   // We can't do this with if we are dividing a stack by some a product v.v^T product as we need to store the vector
+     148             :   // In order to do this type of calculation.  There should be a neater fix than this but I can't see it.
+     149             :   bool foundneigh=false; const ActionWithMatrix* chainstart = NULL;
+     150        1491 :   for(unsigned i=argstart; i<getNumberOfArguments(); ++i) {
+     151        1198 :     if( getPntrToArgument(i)->isConstant() && getNumberOfArguments()>1 ) continue ;
+     152         923 :     std::string argname=(getPntrToArgument(i)->getPntrToAction())->getName();
+     153         923 :     if( argname=="NEIGHBORS" ) { foundneigh=true; break; }
+     154         920 :     ActionWithVector* av=dynamic_cast<ActionWithVector*>( getPntrToArgument(i)->getPntrToAction() );
+     155         920 :     if( !av ) done_in_chain=false;
+     156         920 :     if( getPntrToArgument(i)->getRank()==0 ) {
+     157           0 :       function::FunctionOfVector<function::Sum>* as = dynamic_cast<function::FunctionOfVector<function::Sum>*>( getPntrToArgument(i)->getPntrToAction() );
+     158           0 :       if(as) done_in_chain=false;
+     159         920 :     } else if( getPntrToArgument(i)->ignoreStoredValue( getLabel() ) ) {
+     160             :       // This option deals with the case when you have two adjacency matrices, A_ij and B_ij, multiplied together.  This cannot be done in the chain as the rows
+     161             :       // of the two adjacency matrix are run over separately.  The value A_ij is thus not available when B_ij is calculated.
+     162         844 :       ActionWithMatrix* am = dynamic_cast<ActionWithMatrix*>( getPntrToArgument(i)->getPntrToAction() );
+     163         844 :       plumed_assert( am ); const ActionWithMatrix* thischain = am->getFirstMatrixInChain();
+     164         844 :       const AdjacencyMatrixBase* aa=dynamic_cast<const AdjacencyMatrixBase*>( thischain ); if( !aa && thischain->getName()!="VSTACK" ) continue;
+     165         648 :       if( !chainstart ) chainstart = thischain;
+     166         311 :       else if( thischain!=chainstart ) done_in_chain=false;
+     167             :     }
+     168             :   }
+     169             :   // If we are working with neighbors we trick PLUMED into storing ALL the components of the other arguments
+     170             :   // in this way we can ensure that the function of the neighbours matrix is in a chain starting from the
+     171             :   // Neighbours matrix action.
+     172             :   if( foundneigh ) {
+     173           9 :     for(unsigned i=argstart; i<getNumberOfArguments(); ++i) {
+     174           6 :       ActionWithValue* av=getPntrToArgument(i)->getPntrToAction();
+     175           6 :       if( av->getName()!="NEIGHBORS" ) {
+     176           8 :         for(int i=0; i<av->getNumberOfComponents(); ++i) (av->copyOutput(i))->buildDataStore();
+     177             :       }
+     178             :     }
+     179             :   }
+     180             :   // Now setup the action in the chain if we can
+     181         492 :   nderivatives = buildArgumentStore(myfunc.getArgStart());
+     182         984 : }
+     183             : 
+     184             : template <class T>
+     185        1921 : void FunctionOfMatrix<T>::turnOnDerivatives() {
+     186        1921 :   if( !myfunc.derivativesImplemented() ) error("derivatives have not been implemended for " + getName() );
+     187        1921 :   ActionWithValue::turnOnDerivatives(); myfunc.setup(this);
+     188        1921 : }
+     189             : 
+     190             : template <class T>
+     191       30411 : unsigned FunctionOfMatrix<T>::getNumberOfDerivatives() {
+     192       30411 :   return nderivatives;
+     193             : }
+     194             : 
+     195             : template <class T>
+     196        2229 : void FunctionOfMatrix<T>::prepare() {
+     197        2229 :   unsigned argstart = myfunc.getArgStart(); std::vector<unsigned> shape(2);
+     198        2229 :   for(unsigned i=argstart; i<getNumberOfArguments(); ++i) {
+     199        2229 :     if( getPntrToArgument(i)->getRank()==2 ) {
+     200        2229 :       shape[0] = getPntrToArgument(i)->getShape()[0];
+     201        2229 :       shape[1] = getPntrToArgument(i)->getShape()[1];
+     202        2229 :       break;
+     203             :     }
+     204             :   }
+     205        6682 :   for(unsigned i=0; i<getNumberOfComponents(); ++i) {
+     206        4453 :     Value* myval = getPntrToComponent(i);
+     207        4453 :     if( myval->getRank()==2 && (myval->getShape()[0]!=shape[0] || myval->getShape()[1]!=shape[1]) ) {
+     208          18 :       myval->setShape(shape); if( myval->valueIsStored() ) myval->reshapeMatrixStore( shape[1] );
+     209             :     }
+     210             :   }
+     211        2229 :   ActionWithVector::prepare();
+     212        2229 : }
+     213             : 
+     214             : template <class T>
+     215      281844 : unsigned FunctionOfMatrix<T>::getNumberOfColumns() const {
+     216      281844 :   if( getConstPntrToComponent(0)->getRank()==2 ) {
+     217             :     unsigned argstart=myfunc.getArgStart();
+     218      281844 :     for(unsigned i=argstart; i<getNumberOfArguments(); ++i) {
+     219      281844 :       if( getPntrToArgument(i)->getRank()==2 ) {
+     220      281844 :         ActionWithMatrix* am=dynamic_cast<ActionWithMatrix*>( getPntrToArgument(i)->getPntrToAction() );
+     221      281844 :         if( am ) return am->getNumberOfColumns();
+     222        2238 :         return getPntrToArgument(i)->getShape()[1];
+     223             :       }
+     224             :     }
+     225             :   }
+     226           0 :   plumed_error(); return 0;
+     227             : }
+     228             : 
+     229             : template <class T>
+     230        4209 : void FunctionOfMatrix<T>::setupForTask( const unsigned& task_index, std::vector<unsigned>& indices, MultiValue& myvals ) const {
+     231       11667 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) plumed_assert( getPntrToArgument(i)->getRank()==2 );
+     232        4209 :   unsigned start_n = getPntrToArgument(0)->getShape()[0], size_v = getPntrToArgument(0)->getShape()[1];
+     233        4209 :   if( indices.size()!=size_v+1 ) indices.resize( size_v+1 );
+     234      642613 :   for(unsigned i=0; i<size_v; ++i) indices[i+1] = start_n + i;
+     235             :   myvals.setSplitIndex( size_v + 1 );
+     236        4209 : }
+     237             : 
+     238             : // template <class T>
+     239             : // void FunctionOfMatrix<T>::buildTaskListFromArgumentRequests( const unsigned& ntasks, bool& reduce, std::set<AtomNumber>& otasks ) {
+     240             : //   // Check if this is the first element in a chain
+     241             : //   if( actionInChain() ) return;
+     242             : //   // If it is computed outside a chain get the tassks the daughter chain needs
+     243             : //   propegateTaskListsForValue( 0, ntasks, reduce, otasks );
+     244             : // }
+     245             : 
+     246             : template <class T>
+     247        2525 : void FunctionOfMatrix<T>::setupStreamedComponents( const std::string& headstr, unsigned& nquants, unsigned& nmat, unsigned& maxcol, unsigned& nbookeeping ) {
+     248        2525 :   if( firststep ) {
+     249         489 :     stored_arguments.resize( getNumberOfArguments() );
+     250         489 :     update_arguments.resize( getNumberOfArguments(), true );
+     251         489 :     std::string control = getFirstActionInChain()->getLabel();
+     252        1484 :     for(unsigned i=0; i<stored_arguments.size(); ++i) {
+     253         995 :       stored_arguments[i] = !getPntrToArgument(i)->ignoreStoredValue( control );
+     254         995 :       if( !stored_arguments[i] ) update_arguments[i] = true;
+     255         164 :       else update_arguments[i] = !argumentDependsOn( headstr, this, getPntrToArgument(i) );
+     256             :     }
+     257         489 :     firststep=false;
+     258             :   }
+     259        2525 :   ActionWithMatrix::setupStreamedComponents( headstr, nquants, nmat, maxcol, nbookeeping );
+     260        2525 : }
+     261             : 
+     262             : template <class T>
+     263    27928651 : void FunctionOfMatrix<T>::performTask( const std::string& controller, const unsigned& index1, const unsigned& index2, MultiValue& myvals ) const {
+     264    27928651 :   unsigned argstart=myfunc.getArgStart(); std::vector<double> args( getNumberOfArguments() - argstart );
+     265    27928651 :   unsigned ind2 = index2;
+     266    27928651 :   if( getConstPntrToComponent(0)->getRank()==2 && index2>=getConstPntrToComponent(0)->getShape()[0] ) ind2 = index2 - getConstPntrToComponent(0)->getShape()[0];
+     267    24292268 :   else if( index2>=getPntrToArgument(0)->getShape()[0] ) ind2 = index2 - getPntrToArgument(0)->getShape()[0];
+     268    27928651 :   if( actionInChain() ) {
+     269    85619946 :     for(unsigned i=argstart; i<getNumberOfArguments(); ++i) {
+     270    58329699 :       if( getPntrToArgument(i)->getRank()==0 ) args[i-argstart] = getPntrToArgument(i)->get();
+     271    58193979 :       else if( !getPntrToArgument(i)->valueHasBeenSet() ) args[i-argstart] = myvals.get( getPntrToArgument(i)->getPositionInStream() );
+     272     1188593 :       else args[i-argstart] = getPntrToArgument(i)->get( getPntrToArgument(i)->getShape()[1]*index1 + ind2 );
+     273             :     }
+     274             :   } else {
+     275     1727072 :     for(unsigned i=argstart; i<getNumberOfArguments(); ++i) {
+     276     1088668 :       if( getPntrToArgument(i)->getRank()==2 ) args[i-argstart]=getPntrToArgument(i)->get( getPntrToArgument(i)->getShape()[1]*index1 + ind2 );
+     277           0 :       else args[i-argstart] = getPntrToArgument(i)->get();
+     278             :     }
+     279             :   }
+     280             :   // Calculate the function and its derivatives
+     281    27928651 :   std::vector<double> vals( getNumberOfComponents() ); Matrix<double> derivatives( getNumberOfComponents(), getNumberOfArguments()-argstart );
+     282    27928651 :   myfunc.calc( this, args, vals, derivatives );
+     283             :   // And set the values
+     284    99634355 :   for(unsigned i=0; i<vals.size(); ++i) myvals.addValue( getConstPntrToComponent(i)->getPositionInStream(), vals[i] );
+     285             :   // Return if we are not computing derivatives
+     286    27928651 :   if( doNotCalculateDerivatives() ) return;
+     287             : 
+     288     5399619 :   if( actionInChain() ) {
+     289    33385311 :     for(int i=0; i<getNumberOfComponents(); ++i) {
+     290    27990552 :       unsigned ostrn=getConstPntrToComponent(i)->getPositionInStream();
+     291   131996523 :       for(unsigned j=argstart; j<getNumberOfArguments(); ++j) {
+     292   104005971 :         if( getPntrToArgument(j)->getRank()==2 ) {
+     293   103890411 :           unsigned istrn = getPntrToArgument(j)->getPositionInStream();
+     294   103890411 :           if( stored_arguments[j] ) {
+     295      395048 :             unsigned task_index = getPntrToArgument(i)->getShape()[1]*index1 + ind2;
+     296      395048 :             myvals.clearDerivatives(istrn); myvals.addDerivative( istrn, task_index, 1.0 ); myvals.updateIndex( istrn, task_index );
+     297             :           }
+     298   470717695 :           for(unsigned k=0; k<myvals.getNumberActive(istrn); ++k) {
+     299   366827284 :             unsigned kind=myvals.getActiveIndex(istrn,k);
+     300   366827284 :             myvals.addDerivative( ostrn, arg_deriv_starts[j] + kind, derivatives(i,j)*myvals.getDerivative( istrn, kind ) );
+     301             :           }
+     302             :         }
+     303             :       }
+     304             :     }
+     305             :     // If we are computing a matrix we need to update the indices here so that derivatives are calcualted correctly in functions of these
+     306     5394759 :     if( getConstPntrToComponent(0)->getRank()==2 ) {
+     307    32784527 :       for(int i=0; i<getNumberOfComponents(); ++i) {
+     308    27690160 :         unsigned ostrn=getConstPntrToComponent(i)->getPositionInStream();
+     309   131395739 :         for(unsigned j=argstart; j<getNumberOfArguments(); ++j) {
+     310   103705579 :           if( !update_arguments[j] || getPntrToArgument(j)->getRank()==0 ) continue ;
+     311             :           // Ensure we only store one lot of derivative indices
+     312             :           bool found=false;
+     313   105009550 :           for(unsigned k=0; k<j; ++k) {
+     314    76601003 :             if( arg_deriv_starts[k]==arg_deriv_starts[j] ) { found=true; break; }
+     315             :           }
+     316   103589995 :           if( found ) continue;
+     317             :           unsigned istrn = getPntrToArgument(j)->getPositionInStream();
+     318   138447375 :           for(unsigned k=0; k<myvals.getNumberActive(istrn); ++k) {
+     319   110038828 :             unsigned kind=myvals.getActiveIndex(istrn,k);
+     320   110038828 :             myvals.updateIndex( ostrn, arg_deriv_starts[j] + kind );
+     321             :           }
+     322             :         }
+     323             :       }
+     324             :     }
+     325             :   } else {
+     326        4860 :     unsigned base=0; ind2 = index2;
+     327        4860 :     for(unsigned j=argstart; j<getNumberOfArguments(); ++j) {
+     328        4860 :       if( getPntrToArgument(j)->getRank()!=2 ) continue ;
+     329        4860 :       if( index2>=getPntrToArgument(j)->getShape()[0] ) ind2 = index2 - getPntrToArgument(j)->getShape()[0];
+     330             :       break;
+     331             :     }
+     332       13965 :     for(unsigned j=argstart; j<getNumberOfArguments(); ++j) {
+     333        9105 :       if( getPntrToArgument(j)->getRank()==2 ) {
+     334       18210 :         for(int i=0; i<getNumberOfComponents(); ++i) {
+     335        9105 :           unsigned ostrn=getConstPntrToComponent(i)->getPositionInStream();
+     336        9105 :           unsigned myind = base + getPntrToArgument(j)->getShape()[1]*index1 + ind2;
+     337        9105 :           myvals.addDerivative( ostrn, myind, derivatives(i,j) );
+     338        9105 :           myvals.updateIndex( ostrn, myind );
+     339             :         }
+     340             :       } else {
+     341           0 :         for(int i=0; i<getNumberOfComponents(); ++i) {
+     342           0 :           unsigned ostrn=getConstPntrToComponent(i)->getPositionInStream();
+     343           0 :           myvals.addDerivative( ostrn, base, derivatives(i,j) );
+     344           0 :           myvals.updateIndex( ostrn, base );
+     345             :         }
+     346             :       }
+     347        9105 :       base += getPntrToArgument(j)->getNumberOfValues();
+     348             :     }
+     349             :   }
+     350             : }
+     351             : 
+     352             : template <class T>
+     353      226389 : void FunctionOfMatrix<T>::runEndOfRowJobs( const unsigned& ind, const std::vector<unsigned> & indices, MultiValue& myvals ) const {
+     354      226389 :   if( doNotCalculateDerivatives() ) return;
+     355             : 
+     356             :   unsigned argstart=myfunc.getArgStart();
+     357       71237 :   if( actionInChain() && getConstPntrToComponent(0)->getRank()==2 ) {
+     358             :     // This is triggered if we are outputting a matrix
+     359      624578 :     for(int vv=0; vv<getNumberOfComponents(); ++vv) {
+     360      558183 :       unsigned nmat = getConstPntrToComponent(vv)->getPositionInMatrixStash();
+     361             :       std::vector<unsigned>& mat_indices( myvals.getMatrixRowDerivativeIndices( nmat ) ); unsigned ntot_mat=0;
+     362      558183 :       if( mat_indices.size()<nderivatives ) mat_indices.resize( nderivatives );
+     363     2701544 :       for(unsigned i=argstart; i<getNumberOfArguments(); ++i) {
+     364     2143361 :         if( !update_arguments[i] || getPntrToArgument(i)->getRank()==0 ) continue ;
+     365             :         // Ensure we only store one lot of derivative indices
+     366             :         bool found=false;
+     367     2168017 :         for(unsigned j=0; j<i; ++j) {
+     368     1591516 :           if( arg_deriv_starts[j]==arg_deriv_starts[i] ) { found=true; break; }
+     369             :         }
+     370     2142277 :         if( found ) continue;
+     371             : 
+     372      576501 :         if( stored_arguments[i] ) {
+     373       15483 :           unsigned tbase = getPntrToArgument(i)->getShape()[1]*ind;
+     374      410507 :           for(unsigned k=1; k<indices.size(); ++k) {
+     375      395024 :             unsigned ind2 = indices[k] - getConstPntrToComponent(0)->getShape()[0];
+     376      395024 :             mat_indices[ntot_mat + k - 1] = arg_deriv_starts[i] + tbase + ind2;
+     377             :           }
+     378       15483 :           ntot_mat += indices.size()-1;
+     379             :         } else {
+     380             :           unsigned istrn = getPntrToArgument(i)->getPositionInMatrixStash();
+     381             :           std::vector<unsigned>& imat_indices( myvals.getMatrixRowDerivativeIndices( istrn ) );
+     382    31848426 :           for(unsigned k=0; k<myvals.getNumberOfMatrixRowDerivatives( istrn ); ++k) mat_indices[ntot_mat + k] = arg_deriv_starts[i] + imat_indices[k];
+     383      561018 :           ntot_mat += myvals.getNumberOfMatrixRowDerivatives( istrn );
+     384             :         }
+     385             :       }
+     386             :       myvals.setNumberOfMatrixRowDerivatives( nmat, ntot_mat );
+     387             :     }
+     388        4842 :   } else if( actionInChain() ) {
+     389             :     // This is triggered if we are calculating a single scalar in the function
+     390        8822 :     for(unsigned i=argstart; i<getNumberOfArguments(); ++i) {
+     391             :       bool found=false;
+     392        4411 :       for(unsigned j=0; j<i; ++j) {
+     393           0 :         if( arg_deriv_starts[j]==arg_deriv_starts[i] ) { found=true; break; }
+     394             :       }
+     395        4411 :       if( found ) continue;
+     396             :       unsigned istrn = getPntrToArgument(i)->getPositionInMatrixStash();
+     397             :       std::vector<unsigned>& mat_indices( myvals.getMatrixRowDerivativeIndices( istrn ) );
+     398      926766 :       for(unsigned k=0; k<myvals.getNumberOfMatrixRowDerivatives( istrn ); ++k) {
+     399     1844710 :         for(int j=0; j<getNumberOfComponents(); ++j) {
+     400      922355 :           unsigned ostrn = getConstPntrToComponent(j)->getPositionInStream();
+     401      922355 :           myvals.updateIndex( ostrn, arg_deriv_starts[i] + mat_indices[k] );
+     402             :         }
+     403             :       }
+     404             :     }
+     405         431 :   } else if( getConstPntrToComponent(0)->getRank()==2 ) {
+     406         760 :     for(int vv=0; vv<getNumberOfComponents(); ++vv) {
+     407         380 :       unsigned nmat = getConstPntrToComponent(vv)->getPositionInMatrixStash();
+     408             :       std::vector<unsigned>& mat_indices( myvals.getMatrixRowDerivativeIndices( nmat ) ); unsigned ntot_mat=0;
+     409         380 :       if( mat_indices.size()<nderivatives ) mat_indices.resize( nderivatives ); unsigned matderbase = 0;
+     410         986 :       for(unsigned i=argstart; i<getNumberOfArguments(); ++i) {
+     411         606 :         if( getPntrToArgument(i)->getRank()==0 ) continue ;
+     412         606 :         unsigned ss = getPntrToArgument(i)->getShape()[1]; unsigned tbase = matderbase + ss*myvals.getTaskIndex();
+     413        9558 :         for(unsigned k=0; k<ss; ++k) mat_indices[ntot_mat + k] = tbase + k;
+     414         606 :         ntot_mat += ss; matderbase += getPntrToArgument(i)->getNumberOfValues();
+     415             :       }
+     416             :       myvals.setNumberOfMatrixRowDerivatives( nmat, ntot_mat );
+     417             :     }
+     418             :   }
+     419             : }
+     420             : 
+     421             : template <class T>
+     422         492 : std::vector<unsigned> FunctionOfMatrix<T>::getValueShapeFromArguments() {
+     423         492 :   unsigned argstart=myfunc.getArgStart(); std::vector<unsigned> shape(2); shape[0]=shape[1]=0;
+     424        1496 :   for(unsigned i=argstart; i<getNumberOfArguments(); ++i) {
+     425        1004 :     plumed_assert( getPntrToArgument(i)->getRank()==2 || getPntrToArgument(i)->getRank()==0 );
+     426        1004 :     if( getPntrToArgument(i)->getRank()==2 ) {
+     427         939 :       if( shape[0]>0 && (getPntrToArgument(i)->getShape()[0]!=shape[0] || getPntrToArgument(i)->getShape()[1]!=shape[1]) ) error("all matrices input should have the same shape");
+     428         939 :       else if( shape[0]==0 ) { shape[0]=getPntrToArgument(i)->getShape()[0]; shape[1]=getPntrToArgument(i)->getShape()[1]; }
+     429         939 :       plumed_assert( !getPntrToArgument(i)->hasDerivatives() );
+     430             :     }
+     431             :   }
+     432         492 :   myfunc.setPrefactor( this, 1.0 ); return shape;
+     433             : }
+     434             : 
+     435             : }
+     436             : }
+     437             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/HbondMatrix.cpp.func-sort-c.html b/coverage/adjmat/HbondMatrix.cpp.func-sort-c.html new file mode 100644 index 000000000000..0bd9ac0dabe2 --- /dev/null +++ b/coverage/adjmat/HbondMatrix.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + 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:4141100.0 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat11HbondMatrixC2ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat11HbondMatrixC1ERKNS_13ActionOptionsE2
_ZN4PLMD6adjmat11HbondMatrix16registerKeywordsERNS_8KeywordsE4
_ZNK4PLMD6adjmat11HbondMatrix15calculateWeightERKNS_13VectorGenericILj3EEES5_RKjRNS_10MultiValueE4038
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/HbondMatrix.cpp.func.html b/coverage/adjmat/HbondMatrix.cpp.func.html new file mode 100644 index 000000000000..ebd22e3e02f9 --- /dev/null +++ b/coverage/adjmat/HbondMatrix.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + 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:4141100.0 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat11HbondMatrix16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD6adjmat11HbondMatrixC1ERKNS_13ActionOptionsE2
_ZN4PLMD6adjmat11HbondMatrixC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6adjmat11HbondMatrix15calculateWeightERKNS_13VectorGenericILj3EEES5_RKjRNS_10MultiValueE4038
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/HbondMatrix.cpp.gcov.html b/coverage/adjmat/HbondMatrix.cpp.gcov.html new file mode 100644 index 000000000000..254aa3d450e3 --- /dev/null +++ b/coverage/adjmat/HbondMatrix.cpp.gcov.html @@ -0,0 +1,237 @@ + + + + + + + + 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:4141100.0 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2020 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received 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 "tools/SwitchingFunction.h"
+      24             : #include "tools/Angle.h"
+      25             : #include "core/ActionRegister.h"
+      26             : 
+      27             : #include <string>
+      28             : #include <cmath>
+      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             : namespace PLMD {
+      81             : namespace adjmat {
+      82             : 
+      83             : class HbondMatrix : public AdjacencyMatrixBase {
+      84             : private:
+      85             :   SwitchingFunction distanceOOSwitch;
+      86             :   SwitchingFunction distanceOHSwitch;
+      87             :   SwitchingFunction angleSwitch;
+      88             : public:
+      89             :   static void registerKeywords( Keywords& keys );
+      90             :   explicit HbondMatrix(const ActionOptions&);
+      91             : // active methods:
+      92             :   double calculateWeight( const Vector& pos1, const Vector& pos2, const unsigned& natoms, MultiValue& myvals ) const override ;
+      93             : };
+      94             : 
+      95             : PLUMED_REGISTER_ACTION(HbondMatrix,"HBOND_MATRIX")
+      96             : 
+      97           4 : void HbondMatrix::registerKeywords( Keywords& keys ) {
+      98           4 :   AdjacencyMatrixBase::registerKeywords( keys );
+      99           8 :   keys.add("atoms","HYDROGENS","The list of atoms that can form the bridge between the two interesting parts "
+     100             :            "of the structure.");
+     101           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");
+     102           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 "
+     103             :            "considered a hydrogen bond");
+     104           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 "
+     105             :            "the vector connecting the donor atom to the hydrogen must be in order for it considered to be a hydrogen bond");
+     106           4 : }
+     107             : 
+     108           2 : HbondMatrix::HbondMatrix(const ActionOptions&ao):
+     109             :   Action(ao),
+     110           2 :   AdjacencyMatrixBase(ao)
+     111             : {
+     112           4 :   std::string sfinput,errors; parse("SWITCH",sfinput);
+     113           2 :   if( sfinput.length()==0 ) error("could not find SWITCH keyword");
+     114           2 :   distanceOOSwitch.set(sfinput,errors);
+     115           2 :   if( errors.length()!=0 ) error("problem reading SWITCH keyword : " + errors );
+     116             : 
+     117           4 :   std::string hsfinput; parse("HSWITCH",hsfinput);
+     118           2 :   if( hsfinput.length()==0 ) error("could not find HSWITCH keyword");
+     119           2 :   distanceOHSwitch.set(hsfinput,errors);
+     120           2 :   if( errors.length()!=0 ) error("problem reading HSWITCH keyword : " + errors );
+     121             : 
+     122           4 :   std::string asfinput; parse("ASWITCH",asfinput);
+     123           2 :   if( asfinput.length()==0 ) error("could not find SWITCH keyword");
+     124           2 :   angleSwitch.set(asfinput,errors);
+     125           2 :   if( errors.length()!=0 ) error("problem reading SWITCH keyword : " + errors );
+     126             : 
+     127             :   // Setup link cells
+     128           2 :   setLinkCellCutoff( false, distanceOOSwitch.get_dmax() );
+     129             : 
+     130             :   // And check everything has been read in correctly
+     131           2 :   checkRead();
+     132           2 : }
+     133             : 
+     134        4038 : double HbondMatrix::calculateWeight( const Vector& pos1, const Vector& pos2, const unsigned& natoms, MultiValue& myvals ) const {
+     135        4038 :   Vector ood = pos2; double ood_l = ood.modulo2(); // acceptor - donor
+     136        4038 :   if( ood_l<epsilon) return 0;
+     137        4038 :   double ood_df, ood_sw=distanceOOSwitch.calculateSqr( ood_l, ood_df );
+     138             : 
+     139             :   double value=0;
+     140      520170 :   for(unsigned i=0; i<natoms; ++i) {
+     141      516132 :     Vector ohd=getPosition(i,myvals); double ohd_l=ohd.modulo2();
+     142      516132 :     double ohd_df, ohd_sw=distanceOHSwitch.calculateSqr( ohd_l, ohd_df );
+     143             : 
+     144      516132 :     Angle a; Vector ood_adf, ohd_adf; double angle=a.compute( ood, ohd, ood_adf, ohd_adf );
+     145      516132 :     double angle_df, angle_sw=angleSwitch.calculate( angle, angle_df );
+     146      516132 :     value += ood_sw*ohd_sw*angle_sw;
+     147             : 
+     148      516132 :     if( !doNotCalculateDerivatives() ) {
+     149          36 :       addAtomDerivatives( 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), myvals );
+     150          36 :       addAtomDerivatives( 1, angle_sw*ohd_sw*(+ood_df)*ood + ood_sw*ohd_sw*angle_df*angle*ood_adf, myvals );
+     151          36 :       addThirdAtomDerivatives( i, angle_sw*ood_sw*(+ohd_df)*ohd + ood_sw*ohd_sw*angle_df*angle*ohd_adf, myvals );
+     152          72 :       addBoxDerivatives( angle_sw*ohd_sw*(-ood_df)*Tensor(ood,ood) + angle_sw*ood_sw*(-ohd_df)*Tensor(ohd,ohd) -
+     153         108 :                          ood_sw*ohd_sw*angle_df*angle*(Tensor(ood,ood_adf)+Tensor(ohd,ohd_adf)), myvals );
+     154             :     }
+     155             :   }
+     156        4038 :   return value;
+     157             : }
+     158             : 
+     159             : }
+     160             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/InvertMatrix.cpp.func-sort-c.html b/coverage/adjmat/InvertMatrix.cpp.func-sort-c.html new file mode 100644 index 000000000000..0f1e45cdbbf7 --- /dev/null +++ b/coverage/adjmat/InvertMatrix.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/InvertMatrix.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - InvertMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:222684.6 %
Date:2024-04-19 12:12:35Functions:4757.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat12InvertMatrix5applyEv0
_ZN4PLMD6adjmat12InvertMatrixC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6adjmat12InvertMatrix23getForceOnMatrixElementERKjS3_0
_ZN4PLMD6adjmat12InvertMatrix22getNumberOfDerivativesEv6
_ZN4PLMD6adjmat12InvertMatrix9calculateEv9
_ZN4PLMD6adjmat12InvertMatrixC1ERKNS_13ActionOptionsE9
_ZN4PLMD6adjmat12InvertMatrix16registerKeywordsERNS_8KeywordsE11
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/InvertMatrix.cpp.func.html b/coverage/adjmat/InvertMatrix.cpp.func.html new file mode 100644 index 000000000000..0658ba8a7413 --- /dev/null +++ b/coverage/adjmat/InvertMatrix.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/InvertMatrix.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - InvertMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:222684.6 %
Date:2024-04-19 12:12:35Functions:4757.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat12InvertMatrix16registerKeywordsERNS_8KeywordsE11
_ZN4PLMD6adjmat12InvertMatrix22getNumberOfDerivativesEv6
_ZN4PLMD6adjmat12InvertMatrix5applyEv0
_ZN4PLMD6adjmat12InvertMatrix9calculateEv9
_ZN4PLMD6adjmat12InvertMatrixC1ERKNS_13ActionOptionsE9
_ZN4PLMD6adjmat12InvertMatrixC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6adjmat12InvertMatrix23getForceOnMatrixElementERKjS3_0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/InvertMatrix.cpp.gcov.html b/coverage/adjmat/InvertMatrix.cpp.gcov.html new file mode 100644 index 000000000000..be4c8196c9b0 --- /dev/null +++ b/coverage/adjmat/InvertMatrix.cpp.gcov.html @@ -0,0 +1,176 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/InvertMatrix.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - InvertMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:222684.6 %
Date:2024-04-19 12:12:35Functions:4757.1 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2014-2017 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "MatrixOperationBase.h"
+      23             : #include "core/ActionSetup.h"
+      24             : #include "core/ActionRegister.h"
+      25             : 
+      26             : //+PLUMEDOC MCOLVAR INVERT_MATRIX
+      27             : /*
+      28             : Calculate the inverse of the input matrix
+      29             : 
+      30             : \par Examples
+      31             : 
+      32             : */
+      33             : //+ENDPLUMEDOC
+      34             : 
+      35             : namespace PLMD {
+      36             : namespace adjmat {
+      37             : 
+      38             : class InvertMatrix : public MatrixOperationBase {
+      39             : private:
+      40             :   bool input_is_constant;
+      41             :   Matrix<double> mymatrix;
+      42             :   Matrix<double> inverse;
+      43             : public:
+      44             :   static void registerKeywords( Keywords& keys );
+      45             : /// Constructor
+      46             :   explicit InvertMatrix(const ActionOptions&);
+      47             : ///
+      48           6 :   unsigned getNumberOfDerivatives() override { return 0; }
+      49             : /// Do the calculation
+      50             :   void calculate() override;
+      51             : ///
+      52             :   void apply() override;
+      53           0 :   double getForceOnMatrixElement( const unsigned& jrow, const unsigned& krow ) const override { plumed_error(); }
+      54             : };
+      55             : 
+      56             : PLUMED_REGISTER_ACTION(InvertMatrix,"INVERT_MATRIX")
+      57             : 
+      58          11 : void InvertMatrix::registerKeywords( Keywords& keys ) {
+      59          11 :   MatrixOperationBase::registerKeywords( keys );
+      60          11 : }
+      61             : 
+      62           9 : InvertMatrix::InvertMatrix(const ActionOptions& ao):
+      63             :   Action(ao),
+      64             :   MatrixOperationBase(ao),
+      65           9 :   input_is_constant(false)
+      66             : {
+      67           9 :   if( getPntrToArgument(0)->getShape()[0]!=getPntrToArgument(0)->getShape()[1] ) error("input matrix should be square");
+      68             : 
+      69           9 :   ActionSetup* as = dynamic_cast<ActionSetup*>( getPntrToArgument(0)->getPntrToAction() );
+      70           9 :   if(as) input_is_constant=true;
+      71             : 
+      72           9 :   std::vector<unsigned> shape(2); shape[0]=shape[1]=getPntrToArgument(0)->getShape()[0]; addValue( shape );
+      73           9 :   setNotPeriodic(); getPntrToComponent(0)->buildDataStore(); getPntrToComponent(0)->reshapeMatrixStore( shape[1] );
+      74           9 :   mymatrix.resize( shape[0], shape[1] ); inverse.resize( shape[0], shape[1] );
+      75           9 : }
+      76             : 
+      77           9 : void InvertMatrix::calculate() {
+      78             :   // Retrieve the matrix from input
+      79           9 :   retrieveFullMatrix( mymatrix );
+      80             :   // Now invert the matrix
+      81           9 :   Invert( mymatrix, inverse );
+      82             :   // And set the inverse
+      83           9 :   unsigned k = 0; Value* myval=getPntrToComponent(0);
+      84          30 :   for(unsigned i=0; i<mymatrix.nrows(); ++i) {
+      85          78 :     for(unsigned j=0; j<mymatrix.ncols(); ++j) {
+      86          57 :       myval->set( k, inverse(i,j) ); k++;
+      87             :     }
+      88             :   }
+      89             : 
+      90           9 :   if( !doNotCalculateDerivatives() && !input_is_constant ) error("derivatives of inverse matrix have not been implemented");
+      91           9 : }
+      92             : 
+      93           0 : void InvertMatrix::apply() {
+      94           0 :   if( doNotCalculateDerivatives() || input_is_constant ) return;
+      95           0 :   error("derivatives of inverse matrix have not been implemented");
+      96             : }
+      97             : 
+      98             : }
+      99             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/MatrixOperationBase.cpp.func-sort-c.html b/coverage/adjmat/MatrixOperationBase.cpp.func-sort-c.html new file mode 100644 index 000000000000..2f7d1996d778 --- /dev/null +++ b/coverage/adjmat/MatrixOperationBase.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/MatrixOperationBase.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - MatrixOperationBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:283190.3 %
Date:2024-04-19 12:12:35Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat19MatrixOperationBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat19MatrixOperationBase18retrieveFullMatrixERNS_6MatrixIdEE131
_ZN4PLMD6adjmat19MatrixOperationBaseC2ERKNS_13ActionOptionsE211
_ZN4PLMD6adjmat19MatrixOperationBase16registerKeywordsERNS_8KeywordsE221
_ZN4PLMD6adjmat19MatrixOperationBase5applyEv1448
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/MatrixOperationBase.cpp.func.html b/coverage/adjmat/MatrixOperationBase.cpp.func.html new file mode 100644 index 000000000000..e4cf4c8e03b6 --- /dev/null +++ b/coverage/adjmat/MatrixOperationBase.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/MatrixOperationBase.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - MatrixOperationBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:283190.3 %
Date:2024-04-19 12:12:35Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat19MatrixOperationBase16registerKeywordsERNS_8KeywordsE221
_ZN4PLMD6adjmat19MatrixOperationBase18retrieveFullMatrixERNS_6MatrixIdEE131
_ZN4PLMD6adjmat19MatrixOperationBase5applyEv1448
_ZN4PLMD6adjmat19MatrixOperationBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat19MatrixOperationBaseC2ERKNS_13ActionOptionsE211
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/MatrixOperationBase.cpp.gcov.html b/coverage/adjmat/MatrixOperationBase.cpp.gcov.html new file mode 100644 index 000000000000..0c05ab4f2c72 --- /dev/null +++ b/coverage/adjmat/MatrixOperationBase.cpp.gcov.html @@ -0,0 +1,159 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/MatrixOperationBase.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - MatrixOperationBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:283190.3 %
Date:2024-04-19 12:12:35Functions: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 "MatrixOperationBase.h"
+      23             : 
+      24             : namespace PLMD {
+      25             : namespace adjmat {
+      26             : 
+      27         221 : void MatrixOperationBase::registerKeywords( Keywords& keys ) {
+      28         221 :   Action::registerKeywords( keys ); ActionWithArguments::registerKeywords( keys ); ActionWithValue::registerKeywords( keys );
+      29         442 :   keys.use("ARG"); keys.remove("NUMERICAL_DERIVATIVES");
+      30         442 :   keys.add("optional","MATRIX","the input matrix (can use ARG instead)");
+      31         221 : }
+      32             : 
+      33         211 : MatrixOperationBase::MatrixOperationBase(const ActionOptions&ao):
+      34             :   Action(ao),
+      35             :   ActionWithArguments(ao),
+      36         211 :   ActionWithValue(ao)
+      37             : {
+      38         211 :   if( getNumberOfArguments()==0 ) {
+      39           0 :     std::vector<Value*> args; parseArgumentList("MATRIX",args); requestArguments(args);
+      40             :   }
+      41         211 :   if( getNumberOfArguments()!=1 ) error("should only be one argument to this action");
+      42         211 :   if( getPntrToArgument(0)->getRank()!=2 || getPntrToArgument(0)->hasDerivatives() ) {
+      43          17 :     if( getName()=="TRANSPOSE" ) {
+      44          17 :       if (getPntrToArgument(0)->getRank()!=1 || getPntrToArgument(0)->hasDerivatives() ) error("input to this argument should be a matrix or vector");
+      45           0 :     } else error("input to this argument should be a matrix");
+      46             :   }
+      47         211 :   getPntrToArgument(0)->buildDataStore();
+      48         211 : }
+      49             : 
+      50         131 : void MatrixOperationBase::retrieveFullMatrix( Matrix<double>& mymatrix ) {
+      51         131 :   if( mymatrix.nrows()!=getPntrToArgument(0)->getShape()[0] || mymatrix.nrows()!=getPntrToArgument(0)->getShape()[1] ) {
+      52           0 :     mymatrix.resize( getPntrToArgument(0)->getShape()[0], getPntrToArgument(0)->getShape()[1] );
+      53             :   }
+      54         131 :   unsigned nedge; getPntrToArgument(0)->retrieveEdgeList( nedge, pairs, vals  ); mymatrix=0;
+      55             :   bool symmetric = getPntrToArgument(0)->isSymmetric();
+      56      373270 :   for(unsigned i=0; i<nedge; ++i ) {
+      57      373139 :     mymatrix( pairs[i].first, pairs[i].second ) = vals[i];
+      58      373139 :     if( symmetric ) mymatrix( pairs[i].second, pairs[i].first ) = vals[i];
+      59             :   }
+      60         131 : }
+      61             : 
+      62             : 
+      63        1448 : void MatrixOperationBase::apply() {
+      64        1448 :   if( doNotCalculateDerivatives() ) return;
+      65             : 
+      66             :   bool forces=false;
+      67        1546 :   for(int i=0; i<getNumberOfComponents(); ++i) {
+      68        1546 :     if( getPntrToComponent(i)->forcesWereAdded() ) { forces=true; break; }
+      69             :   }
+      70        1444 :   if( !forces ) return;
+      71             : 
+      72             :   Value* mat = getPntrToArgument(0);
+      73             :   unsigned ncols=mat->getNumberOfColumns();
+      74      147286 :   for(unsigned i=0; i<mat->getShape()[0]; ++i) {
+      75             :     unsigned ncol = mat->getRowLength(i);
+      76     4282909 :     for(unsigned j=0; j<ncol; ++j) mat->addForce( i*ncols+j, getForceOnMatrixElement( i, mat->getRowIndex(i,j) ), false );
+      77             :   }
+      78             : }
+      79             : 
+      80             : 
+      81             : }
+      82             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/MatrixTimesMatrix.cpp.func-sort-c.html b/coverage/adjmat/MatrixTimesMatrix.cpp.func-sort-c.html new file mode 100644 index 000000000000..ba9d816e7ea1 --- /dev/null +++ b/coverage/adjmat/MatrixTimesMatrix.cpp.func-sort-c.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/MatrixTimesMatrix.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - MatrixTimesMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:637188.7 %
Date:2024-04-19 12:12:35Functions:81080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat17MatrixTimesMatrix26getAdditionalTasksRequiredEPNS_16ActionWithVectorERSt6vectorIjSaIjEE0
_ZN4PLMD6adjmat17MatrixTimesMatrixC2ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat17MatrixTimesMatrixC1ERKNS_13ActionOptionsE57
_ZN4PLMD6adjmat17MatrixTimesMatrix16registerKeywordsERNS_8KeywordsE61
_ZN4PLMD6adjmat17MatrixTimesMatrix22getNumberOfDerivativesEv65
_ZN4PLMD6adjmat17MatrixTimesMatrix7prepareEv172
_ZNK4PLMD6adjmat17MatrixTimesMatrix18getNumberOfColumnsEv1297
_ZNK4PLMD6adjmat17MatrixTimesMatrix12setupForTaskERKjRSt6vectorIjSaIjEERNS_10MultiValueE3233
_ZNK4PLMD6adjmat17MatrixTimesMatrix15runEndOfRowJobsERKjRKSt6vectorIjSaIjEERNS_10MultiValueE8116
_ZNK4PLMD6adjmat17MatrixTimesMatrix11performTaskERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjSB_RNS_10MultiValueE926514
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/MatrixTimesMatrix.cpp.func.html b/coverage/adjmat/MatrixTimesMatrix.cpp.func.html new file mode 100644 index 000000000000..edff365becc9 --- /dev/null +++ b/coverage/adjmat/MatrixTimesMatrix.cpp.func.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/MatrixTimesMatrix.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - MatrixTimesMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:637188.7 %
Date:2024-04-19 12:12:35Functions:81080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat17MatrixTimesMatrix16registerKeywordsERNS_8KeywordsE61
_ZN4PLMD6adjmat17MatrixTimesMatrix22getNumberOfDerivativesEv65
_ZN4PLMD6adjmat17MatrixTimesMatrix26getAdditionalTasksRequiredEPNS_16ActionWithVectorERSt6vectorIjSaIjEE0
_ZN4PLMD6adjmat17MatrixTimesMatrix7prepareEv172
_ZN4PLMD6adjmat17MatrixTimesMatrixC1ERKNS_13ActionOptionsE57
_ZN4PLMD6adjmat17MatrixTimesMatrixC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6adjmat17MatrixTimesMatrix11performTaskERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjSB_RNS_10MultiValueE926514
_ZNK4PLMD6adjmat17MatrixTimesMatrix12setupForTaskERKjRSt6vectorIjSaIjEERNS_10MultiValueE3233
_ZNK4PLMD6adjmat17MatrixTimesMatrix15runEndOfRowJobsERKjRKSt6vectorIjSaIjEERNS_10MultiValueE8116
_ZNK4PLMD6adjmat17MatrixTimesMatrix18getNumberOfColumnsEv1297
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/MatrixTimesMatrix.cpp.gcov.html b/coverage/adjmat/MatrixTimesMatrix.cpp.gcov.html new file mode 100644 index 000000000000..9f460dfbb35b --- /dev/null +++ b/coverage/adjmat/MatrixTimesMatrix.cpp.gcov.html @@ -0,0 +1,245 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/MatrixTimesMatrix.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - MatrixTimesMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:637188.7 %
Date:2024-04-19 12:12:35Functions:81080.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "ActionWithMatrix.h"
+      23             : #include "core/ActionRegister.h"
+      24             : 
+      25             : //+PLUMEDOC MCOLVAR MATRIX_PRODUCT
+      26             : /*
+      27             : Calculate the product of two matrices
+      28             : 
+      29             : \par Examples
+      30             : 
+      31             : */
+      32             : //+ENDPLUMEDOC
+      33             : 
+      34             : //+PLUMEDOC ANALYSIS DISSIMILARITIES
+      35             : /*
+      36             : Calculate the matrix of dissimilarities between a trajectory of atomic configurations.
+      37             : 
+      38             : \par Examples
+      39             : 
+      40             : */
+      41             : //+ENDPLUMEDOC
+      42             : 
+      43             : namespace PLMD {
+      44             : namespace adjmat {
+      45             : 
+      46             : class MatrixTimesMatrix : public ActionWithMatrix {
+      47             : private:
+      48             :   bool squared;
+      49             :   unsigned nderivatives;
+      50             :   bool stored_matrix1, stored_matrix2;
+      51             : public:
+      52             :   static void registerKeywords( Keywords& keys );
+      53             :   explicit MatrixTimesMatrix(const ActionOptions&);
+      54             :   void prepare() override ;
+      55             :   unsigned getNumberOfDerivatives();
+      56        1297 :   unsigned getNumberOfColumns() const override { return getConstPntrToComponent(0)->getShape()[1]; }
+      57             :   void getAdditionalTasksRequired( ActionWithVector* action, std::vector<unsigned>& atasks ) override ;
+      58             :   void setupForTask( const unsigned& task_index, std::vector<unsigned>& indices, MultiValue& myvals ) const ;
+      59             :   void performTask( const std::string& controller, const unsigned& index1, const unsigned& index2, MultiValue& myvals ) const override;
+      60             :   void runEndOfRowJobs( const unsigned& ival, const std::vector<unsigned> & indices, MultiValue& myvals ) const override ;
+      61             : };
+      62             : 
+      63             : PLUMED_REGISTER_ACTION(MatrixTimesMatrix,"MATRIX_PRODUCT")
+      64             : PLUMED_REGISTER_ACTION(MatrixTimesMatrix,"DISSIMILARITIES")
+      65             : 
+      66          61 : void MatrixTimesMatrix::registerKeywords( Keywords& keys ) {
+      67          61 :   ActionWithMatrix::registerKeywords(keys); keys.use("ARG");
+      68         122 :   keys.addFlag("SQUARED",false,"calculate the squares of the dissimilarities (this option cannot be used with MATRIX_PRODUCT)");
+      69          61 : }
+      70             : 
+      71          57 : MatrixTimesMatrix::MatrixTimesMatrix(const ActionOptions&ao):
+      72             :   Action(ao),
+      73          57 :   ActionWithMatrix(ao)
+      74             : {
+      75          57 :   if( getNumberOfArguments()!=2 ) error("should be two arguments to this action, a matrix and a vector");
+      76          57 :   if( getPntrToArgument(0)->getRank()!=2 || getPntrToArgument(0)->hasDerivatives() ) error("first argument to this action should be a matrix");
+      77          57 :   if( getPntrToArgument(1)->getRank()!=2 || getPntrToArgument(1)->hasDerivatives() ) error("second argument to this action should be a matrix");
+      78          57 :   if( getPntrToArgument(0)->getShape()[1]!=getPntrToArgument(1)->getShape()[0] ) error("number of columns in first matrix does not equal number of rows in second matrix");
+      79          57 :   std::vector<unsigned> shape(2); shape[0]=getPntrToArgument(0)->getShape()[0]; shape[1]=getPntrToArgument(1)->getShape()[1];
+      80          57 :   addValue( shape ); setNotPeriodic(); nderivatives = buildArgumentStore(0);
+      81          57 :   std::string headstr=getFirstActionInChain()->getLabel();
+      82          57 :   stored_matrix1 = getPntrToArgument(0)->ignoreStoredValue( headstr );
+      83          57 :   stored_matrix2 = getPntrToArgument(1)->ignoreStoredValue( headstr );
+      84          57 :   if( getName()=="DISSIMILARITIES" ) {
+      85          12 :     parseFlag("SQUARED",squared);
+      86          12 :     if( squared ) log.printf("  calculating the squares of the dissimilarities \n");
+      87          45 :   } else squared=true;
+      88          57 : }
+      89             : 
+      90          65 : unsigned MatrixTimesMatrix::getNumberOfDerivatives() {
+      91          65 :   return nderivatives;
+      92             : }
+      93             : 
+      94         172 : void MatrixTimesMatrix::prepare() {
+      95         172 :   Value* myval = getPntrToComponent(0);
+      96         172 :   if( myval->getShape()[0]==getPntrToArgument(0)->getShape()[0] && myval->getShape()[1]==getPntrToArgument(1)->getShape()[1] ) return;
+      97          17 :   std::vector<unsigned> shape(2); shape[0]=getPntrToArgument(0)->getShape()[0]; shape[1]=getPntrToArgument(1)->getShape()[1];
+      98          17 :   myval->setShape(shape); if( myval->valueIsStored() ) myval->reshapeMatrixStore( shape[1] );
+      99             : }
+     100             : 
+     101           0 : void MatrixTimesMatrix::getAdditionalTasksRequired( ActionWithVector* action, std::vector<unsigned>& atasks ) {
+     102             : 
+     103           0 :   ActionWithMatrix* adj=dynamic_cast<ActionWithMatrix*>( getPntrToArgument(0)->getPntrToAction() );
+     104           0 :   if( !adj->isAdjacencyMatrix() ) return;
+     105           0 :   adj->retrieveAtoms(); adj->getAdditionalTasksRequired( action, atasks );
+     106             : }
+     107             : 
+     108        3233 : void MatrixTimesMatrix::setupForTask( const unsigned& task_index, std::vector<unsigned>& indices, MultiValue& myvals ) const {
+     109        3233 :   unsigned start_n = getPntrToArgument(0)->getShape()[0], size_v = getPntrToArgument(1)->getShape()[1];
+     110        3233 :   if( indices.size()!=size_v+1 ) indices.resize( size_v+1 );
+     111      560857 :   for(unsigned i=0; i<size_v; ++i) indices[i+1] = start_n + i;
+     112             :   myvals.setSplitIndex( size_v + 1 );
+     113        3233 : }
+     114             : 
+     115      926514 : void MatrixTimesMatrix::performTask( const std::string& controller, const unsigned& index1, const unsigned& index2, MultiValue& myvals ) const {
+     116      926514 :   unsigned ostrn = getConstPntrToComponent(0)->getPositionInStream(), ind2=index2;
+     117      926514 :   if( index2>=getPntrToArgument(0)->getShape()[0] ) ind2 = index2 - getPntrToArgument(0)->getShape()[0];
+     118             : 
+     119             :   Value* myarg = getPntrToArgument(0);
+     120             :   unsigned nmult=myarg->getRowLength(index1); double matval=0;
+     121      926514 :   std::vector<double>  dvec1(nmult), dvec2(nmult);
+     122    12593462 :   for(unsigned i=0; i<nmult; ++i) {
+     123    11666948 :     unsigned kind = myarg->getRowIndex( index1, i );
+     124    11666948 :     double val1 = getElementOfMatrixArgument( 0, index1, kind, myvals );
+     125    11666948 :     double val2 = getElementOfMatrixArgument( 1, kind, ind2, myvals );
+     126    11666948 :     if( getName()=="DISSIMILARITIES" ) {
+     127     1637093 :       double tmp = getPntrToArgument(0)->difference(val2, val1); matval += tmp*tmp;
+     128     1637093 :       if( !squared ) {
+     129    10575108 :         dvec1[i] = 2*tmp; dvec2[i] = -2*tmp; continue;
+     130     1636330 :       } else { val2 = -2*tmp; val1 = 2*tmp; }
+     131    10029855 :     } else matval+= val1*val2;
+     132             : 
+     133    11666185 :     if( doNotCalculateDerivatives() ) continue;
+     134             : 
+     135     1091840 :     addDerivativeOnMatrixArgument( stored_matrix1, 0, 0, index1, kind, val2, myvals );
+     136     1091840 :     addDerivativeOnMatrixArgument( stored_matrix2, 0, 1, kind, ind2, val1, myvals );
+     137             :   }
+     138             :   // And add this part of the product
+     139      926514 :   if( !squared ) matval = sqrt(matval);
+     140      926514 :   myvals.addValue( ostrn, matval );
+     141      926514 :   if( squared || doNotCalculateDerivatives() ) return;
+     142             : 
+     143           0 :   for(unsigned i=0; i<nmult; ++i) {
+     144           0 :     unsigned kind = myarg->getRowIndex( index1, i );
+     145           0 :     addDerivativeOnMatrixArgument( stored_matrix1, 0, 0, index1, kind, dvec1[i]/(2*matval), myvals );
+     146           0 :     addDerivativeOnMatrixArgument( stored_matrix2, 0, 1, kind, ind2, dvec2[i]/(2*matval), myvals );
+     147             :   }
+     148             : }
+     149             : 
+     150        8116 : void MatrixTimesMatrix::runEndOfRowJobs( const unsigned& ival, const std::vector<unsigned> & indices, MultiValue& myvals ) const {
+     151        8116 :   if( doNotCalculateDerivatives() || !matrixChainContinues() ) return ;
+     152             : 
+     153        1734 :   unsigned mat1s = ival*getPntrToArgument(0)->getShape()[1];
+     154        1734 :   unsigned nmult = getPntrToArgument(0)->getShape()[1], ss = getPntrToArgument(1)->getShape()[1];
+     155        1734 :   unsigned nmat = getConstPntrToComponent(0)->getPositionInMatrixStash(), nmat_ind = myvals.getNumberOfMatrixRowDerivatives( nmat );
+     156             :   std::vector<unsigned>& matrix_indices( myvals.getMatrixRowDerivativeIndices( nmat ) ); unsigned ntwo_atoms = myvals.getSplitIndex();
+     157       21092 :   for(unsigned j=0; j<nmult; ++j) {
+     158       19358 :     matrix_indices[nmat_ind] = mat1s + j; nmat_ind++;
+     159     1098372 :     for(unsigned i=1; i<ntwo_atoms; ++i) {
+     160     1079014 :       unsigned ind2 = indices[i]; if( ind2>=getPntrToArgument(0)->getShape()[0] ) ind2 = indices[i] - getPntrToArgument(0)->getShape()[0];
+     161     1079014 :       matrix_indices[nmat_ind] = arg_deriv_starts[1] + j*ss + ind2; nmat_ind++;
+     162             :     }
+     163             :   }
+     164             :   myvals.setNumberOfMatrixRowDerivatives( nmat, nmat_ind );
+     165             : }
+     166             : 
+     167             : }
+     168             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/MatrixTimesVector.cpp.func-sort-c.html b/coverage/adjmat/MatrixTimesVector.cpp.func-sort-c.html new file mode 100644 index 000000000000..2470c618a178 --- /dev/null +++ b/coverage/adjmat/MatrixTimesVector.cpp.func-sort-c.html @@ -0,0 +1,117 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/MatrixTimesVector.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - MatrixTimesVector.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:909396.8 %
Date:2024-04-19 12:12:35Functions:91181.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat17MatrixTimesVectorC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6adjmat17MatrixTimesVector18getNumberOfColumnsEv0
_ZN4PLMD6adjmat17MatrixTimesVectorC1ERKNS_13ActionOptionsE348
_ZN4PLMD6adjmat17MatrixTimesVector16registerKeywordsERNS_8KeywordsE350
_ZN4PLMD6adjmat17MatrixTimesVector12isInSubChainERj2142
_ZNK4PLMD6adjmat17MatrixTimesVector12setupForTaskERKjRSt6vectorIjSaIjEERNS_10MultiValueE6574
_ZN4PLMD6adjmat17MatrixTimesVector7prepareEv13575
_ZN4PLMD6adjmat17MatrixTimesVector22getNumberOfDerivativesEv31643
_ZNK4PLMD6adjmat17MatrixTimesVector23updateAdditionalIndicesERKjRNS_10MultiValueE372677
_ZNK4PLMD6adjmat17MatrixTimesVector15runEndOfRowJobsERKjRKSt6vectorIjSaIjEERNS_10MultiValueE472445
_ZNK4PLMD6adjmat17MatrixTimesVector11performTaskERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjSB_RNS_10MultiValueE23970940
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/MatrixTimesVector.cpp.func.html b/coverage/adjmat/MatrixTimesVector.cpp.func.html new file mode 100644 index 000000000000..0f73e6f659b2 --- /dev/null +++ b/coverage/adjmat/MatrixTimesVector.cpp.func.html @@ -0,0 +1,117 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/MatrixTimesVector.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - MatrixTimesVector.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:909396.8 %
Date:2024-04-19 12:12:35Functions:91181.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat17MatrixTimesVector12isInSubChainERj2142
_ZN4PLMD6adjmat17MatrixTimesVector16registerKeywordsERNS_8KeywordsE350
_ZN4PLMD6adjmat17MatrixTimesVector22getNumberOfDerivativesEv31643
_ZN4PLMD6adjmat17MatrixTimesVector7prepareEv13575
_ZN4PLMD6adjmat17MatrixTimesVectorC1ERKNS_13ActionOptionsE348
_ZN4PLMD6adjmat17MatrixTimesVectorC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6adjmat17MatrixTimesVector11performTaskERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjSB_RNS_10MultiValueE23970940
_ZNK4PLMD6adjmat17MatrixTimesVector12setupForTaskERKjRSt6vectorIjSaIjEERNS_10MultiValueE6574
_ZNK4PLMD6adjmat17MatrixTimesVector15runEndOfRowJobsERKjRKSt6vectorIjSaIjEERNS_10MultiValueE472445
_ZNK4PLMD6adjmat17MatrixTimesVector18getNumberOfColumnsEv0
_ZNK4PLMD6adjmat17MatrixTimesVector23updateAdditionalIndicesERKjRNS_10MultiValueE372677
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/MatrixTimesVector.cpp.gcov.html b/coverage/adjmat/MatrixTimesVector.cpp.gcov.html new file mode 100644 index 000000000000..fb13d172ede9 --- /dev/null +++ b/coverage/adjmat/MatrixTimesVector.cpp.gcov.html @@ -0,0 +1,271 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/MatrixTimesVector.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - MatrixTimesVector.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:909396.8 %
Date:2024-04-19 12:12:35Functions:91181.8 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "ActionWithMatrix.h"
+      23             : #include "core/ActionRegister.h"
+      24             : 
+      25             : //+PLUMEDOC MCOLVAR MATRIX_VECTOR_PRODUCT
+      26             : /*
+      27             : Calculate the product of the matrix and the vector
+      28             : 
+      29             : \par Examples
+      30             : 
+      31             : */
+      32             : //+ENDPLUMEDOC
+      33             : 
+      34             : namespace PLMD {
+      35             : namespace adjmat {
+      36             : 
+      37             : class MatrixTimesVector : public ActionWithMatrix {
+      38             : private:
+      39             :   unsigned nderivatives;
+      40             :   std::vector<bool> stored_arg;
+      41             : public:
+      42             :   static void registerKeywords( Keywords& keys );
+      43             :   explicit MatrixTimesVector(const ActionOptions&);
+      44           0 :   unsigned getNumberOfColumns() const override { plumed_error(); }
+      45             :   unsigned getNumberOfDerivatives();
+      46             :   void prepare() override ;
+      47        2142 :   bool isInSubChain( unsigned& nder ) override { nder = arg_deriv_starts[0]; return true; }
+      48             :   void setupForTask( const unsigned& task_index, std::vector<unsigned>& indices, MultiValue& myvals ) const ;
+      49             :   void performTask( const std::string& controller, const unsigned& index1, const unsigned& index2, MultiValue& myvals ) const override;
+      50             :   void runEndOfRowJobs( const unsigned& ind, const std::vector<unsigned> & indices, MultiValue& myvals ) const override ;
+      51             :   void updateAdditionalIndices( const unsigned& ostrn, MultiValue& myvals ) const override ;
+      52             : };
+      53             : 
+      54             : PLUMED_REGISTER_ACTION(MatrixTimesVector,"MATRIX_VECTOR_PRODUCT")
+      55             : 
+      56         350 : void MatrixTimesVector::registerKeywords( Keywords& keys ) {
+      57         350 :   ActionWithMatrix::registerKeywords(keys); keys.use("ARG");
+      58         350 :   ActionWithValue::useCustomisableComponents(keys);
+      59         350 : }
+      60             : 
+      61         348 : MatrixTimesVector::MatrixTimesVector(const ActionOptions&ao):
+      62             :   Action(ao),
+      63         348 :   ActionWithMatrix(ao)
+      64             : {
+      65         348 :   if( getNumberOfArguments()<2 ) error("Not enough arguments specified");
+      66             :   unsigned nvectors=0, nmatrices=0;
+      67        1858 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+      68        1510 :     if( getPntrToArgument(i)->hasDerivatives() ) error("arguments should be vectors or matrices");
+      69        1510 :     if( getPntrToArgument(i)->getRank()<=1 ) nvectors++;
+      70        1510 :     if( getPntrToArgument(i)->getRank()==2 ) nmatrices++;
+      71             :   }
+      72             : 
+      73         348 :   std::vector<unsigned> shape(1); shape[0]=getPntrToArgument(0)->getShape()[0];
+      74         348 :   if( nvectors==1 ) {
+      75         339 :     unsigned n = getNumberOfArguments()-1;
+      76        1307 :     for(unsigned i=0; i<n; ++i) {
+      77         968 :       if( getPntrToArgument(i)->getRank()!=2 || getPntrToArgument(i)->hasDerivatives() ) error("all arguments other than last argument should be matrices");
+      78         968 :       if( getPntrToArgument(n)->getRank()==0 ) {
+      79           1 :         if( getPntrToArgument(i)->getShape()[1]!=1 ) error("number of columns in input matrix does not equal number of elements in vector");
+      80         967 :       } else if( getPntrToArgument(i)->getShape()[1]!=getPntrToArgument(n)->getShape()[0] ) error("number of columns in input matrix does not equal number of elements in vector");
+      81             :     }
+      82         339 :     if( getPntrToArgument(n)->getRank()>0 ) {
+      83         338 :       if( getPntrToArgument(n)->getRank()!=1 || getPntrToArgument(n)->hasDerivatives() ) error("last argument to this action should be a vector");
+      84             :     }
+      85         339 :     getPntrToArgument(n)->buildDataStore();
+      86             : 
+      87         339 :     ActionWithVector* av=dynamic_cast<ActionWithVector*>( getPntrToArgument(0)->getPntrToAction() );
+      88         339 :     if( av ) done_in_chain=canBeAfterInChain( av );
+      89             : 
+      90         339 :     if( getNumberOfArguments()==2 ) {
+      91         298 :       addValue( shape ); setNotPeriodic();
+      92             :     } else {
+      93         711 :       for(unsigned i=0; i<getNumberOfArguments()-1; ++i) {
+      94         670 :         std::string name = getPntrToArgument(i)->getName();
+      95        1340 :         if( name.find_first_of(".")!=std::string::npos ) { std::size_t dot=name.find_first_of("."); name = name.substr(dot+1); }
+      96         670 :         addComponent( name, shape ); componentIsNotPeriodic( name );
+      97             :       }
+      98             :     }
+      99           9 :   } else if( nmatrices==1 ) {
+     100           9 :     if( getPntrToArgument(0)->getRank()!=2 || getPntrToArgument(0)->hasDerivatives() ) error("first argument to this action should be a matrix");
+     101         203 :     for(unsigned i=1; i<getNumberOfArguments(); ++i) {
+     102         194 :       if( getPntrToArgument(i)->getRank()>1 || getPntrToArgument(i)->hasDerivatives() ) error("all arguments other than first argument should be vectors");
+     103         194 :       if( getPntrToArgument(i)->getRank()==0 ) {
+     104           0 :         if( getPntrToArgument(0)->getShape()[1]!=1 ) error("number of columns in input matrix does not equal number of elements in vector");
+     105         194 :       } else if( getPntrToArgument(0)->getShape()[1]!=getPntrToArgument(i)->getShape()[0] ) error("number of columns in input matrix does not equal number of elements in vector");
+     106         194 :       getPntrToArgument(i)->buildDataStore();
+     107             :     }
+     108             : 
+     109           9 :     ActionWithVector* av=dynamic_cast<ActionWithVector*>( getPntrToArgument(0)->getPntrToAction() );
+     110           9 :     if( av ) done_in_chain=canBeAfterInChain( av );
+     111             : 
+     112         203 :     for(unsigned i=1; i<getNumberOfArguments(); ++i) {
+     113         194 :       std::string name = getPntrToArgument(i)->getName();
+     114         194 :       if( name.find_first_of(".")!=std::string::npos ) { std::size_t dot=name.find_first_of("."); name = name.substr(dot+1); }
+     115         194 :       addComponent( name, shape ); componentIsNotPeriodic( name );
+     116             :     }
+     117           0 :   } else error("You should either have one vector or one matrix in input");
+     118             : 
+     119         348 :   nderivatives = buildArgumentStore(0);
+     120         348 :   std::string headstr=getFirstActionInChain()->getLabel(); stored_arg.resize( getNumberOfArguments() );
+     121        1858 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) stored_arg[i] = getPntrToArgument(i)->ignoreStoredValue( headstr );
+     122         348 : }
+     123             : 
+     124       31643 : unsigned MatrixTimesVector::getNumberOfDerivatives() {
+     125       31643 :   return nderivatives;
+     126             : }
+     127             : 
+     128       13575 : void MatrixTimesVector::prepare() {
+     129       13575 :   ActionWithVector::prepare(); Value* myval = getPntrToComponent(0);
+     130       13575 :   if( myval->getShape()[0]==getPntrToArgument(0)->getShape()[0] ) return;
+     131          10 :   std::vector<unsigned> shape(1); shape[0] = getPntrToArgument(0)->getShape()[0]; myval->setShape(shape);
+     132             : }
+     133             : 
+     134        6574 : void MatrixTimesVector::setupForTask( const unsigned& task_index, std::vector<unsigned>& indices, MultiValue& myvals ) const {
+     135        6574 :   unsigned start_n = getPntrToArgument(0)->getShape()[0], size_v = getPntrToArgument(0)->getShape()[1];
+     136        6574 :   if( indices.size()!=size_v+1 ) indices.resize( size_v + 1 );
+     137      842762 :   for(unsigned i=0; i<size_v; ++i) indices[i+1] = start_n + i;
+     138             :   myvals.setSplitIndex( size_v + 1 );
+     139        6574 : }
+     140             : 
+     141    23970940 : void MatrixTimesVector::performTask( const std::string& controller, const unsigned& index1, const unsigned& index2, MultiValue& myvals ) const {
+     142    23970940 :   unsigned ind2 = index2; if( index2>=getPntrToArgument(0)->getShape()[0] ) ind2 = index2 - getPntrToArgument(0)->getShape()[0];
+     143    23970940 :   if( getPntrToArgument(1)->getRank()==1 ) {
+     144    59478810 :     for(unsigned i=0; i<getNumberOfArguments()-1; ++i) {
+     145    37250650 :       unsigned ostrn = getConstPntrToComponent(i)->getPositionInStream();
+     146    37250650 :       double matval = getElementOfMatrixArgument( 0, index1, ind2, myvals ), vecval=getArgumentElement( i+1, ind2, myvals );
+     147             :       // And add this part of the product
+     148    37250650 :       myvals.addValue( ostrn, matval*vecval );
+     149             :       // Now lets work out the derivatives
+     150    37250650 :       if( doNotCalculateDerivatives() ) continue;
+     151    25812992 :       addDerivativeOnMatrixArgument( stored_arg[0], i, 0, index1, ind2, vecval, myvals ); addDerivativeOnVectorArgument( stored_arg[i+1], i, i+1, ind2, matval, myvals );
+     152             :     }
+     153             :   } else {
+     154     1742780 :     unsigned n=getNumberOfArguments()-1;
+     155    46319003 :     for(unsigned i=0; i<getNumberOfArguments()-1; ++i) {
+     156    44576223 :       unsigned ostrn = getConstPntrToComponent(i)->getPositionInStream();
+     157    44576223 :       double matval = getElementOfMatrixArgument( i, index1, ind2, myvals ), vecval=getArgumentElement( n, ind2, myvals );
+     158             :       // And add this part of the product
+     159    44576223 :       myvals.addValue( ostrn, matval*vecval );
+     160             :       // Now lets work out the derivatives
+     161    44576223 :       if( doNotCalculateDerivatives() ) continue;
+     162    22699122 :       addDerivativeOnMatrixArgument( stored_arg[i], i, i, index1, ind2, vecval, myvals ); addDerivativeOnVectorArgument( stored_arg[n], i, n, ind2, matval, myvals );
+     163             :     }
+     164             :   }
+     165    23970940 : }
+     166             : 
+     167      472445 : void MatrixTimesVector::runEndOfRowJobs( const unsigned& ind, const std::vector<unsigned> & indices, MultiValue& myvals ) const {
+     168      472445 :   if( doNotCalculateDerivatives() || !actionInChain() ) return ;
+     169             : 
+     170      358714 :   if( getPntrToArgument(1)->getRank()==1 ) {
+     171             :     unsigned istrn = getPntrToArgument(0)->getPositionInMatrixStash();
+     172             :     std::vector<unsigned>& mat_indices( myvals.getMatrixRowDerivativeIndices( istrn ) );
+     173     1010565 :     for(unsigned j=0; j<getNumberOfComponents(); ++j) {
+     174      671975 :       unsigned ostrn = getConstPntrToComponent(j)->getPositionInStream();
+     175    40971258 :       for(unsigned i=0; i<myvals.getNumberOfMatrixRowDerivatives(istrn); ++i) myvals.updateIndex( ostrn, mat_indices[i] );
+     176             :     }
+     177             :   } else {
+     178      530036 :     for(unsigned j=0; j<getNumberOfComponents(); ++j) {
+     179             :       unsigned istrn = getPntrToArgument(j)->getPositionInMatrixStash();
+     180      509912 :       unsigned ostrn = getConstPntrToComponent(j)->getPositionInStream();
+     181             :       std::vector<unsigned>& mat_indices( myvals.getMatrixRowDerivativeIndices( istrn ) );
+     182    17456348 :       for(unsigned i=0; i<myvals.getNumberOfMatrixRowDerivatives(istrn); ++i) myvals.updateIndex( ostrn, mat_indices[i] );
+     183             :     }
+     184             :   }
+     185             : }
+     186             : 
+     187      372677 : void MatrixTimesVector::updateAdditionalIndices( const unsigned& ostrn, MultiValue& myvals ) const {
+     188      372677 :   unsigned n = getNumberOfArguments()-1; if( getPntrToArgument(1)->getRank()==1 ) n = 1;
+     189      372677 :   unsigned nvals = getPntrToArgument(n)->getNumberOfValues();
+     190  1387754027 :   for(unsigned i=0; i<nvals; ++i) myvals.updateIndex( ostrn, arg_deriv_starts[n] + i );
+     191      372677 : }
+     192             : 
+     193             : }
+     194             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/Neighbors.cpp.func-sort-c.html b/coverage/adjmat/Neighbors.cpp.func-sort-c.html new file mode 100644 index 000000000000..4e67bbb35acb --- /dev/null +++ b/coverage/adjmat/Neighbors.cpp.func-sort-c.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/Neighbors.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - Neighbors.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:495884.5 %
Date:2024-04-19 12:12:35Functions:61060.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat9Neighbors17canBeAfterInChainEPNS_16ActionWithVectorE0
_ZN4PLMD6adjmat9Neighbors17turnOnDerivativesEv0
_ZN4PLMD6adjmat9Neighbors22getNumberOfDerivativesEv0
_ZN4PLMD6adjmat9NeighborsC2ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat9NeighborsC1ERKNS_13ActionOptionsE3
_ZN4PLMD6adjmat9Neighbors16registerKeywordsERNS_8KeywordsE5
_ZNK4PLMD6adjmat9Neighbors18getNumberOfColumnsEv8
_ZNK4PLMD6adjmat9Neighbors12setupForTaskERKjRSt6vectorIjSaIjEERNS_10MultiValueE2512
_ZNK4PLMD6adjmat9Neighbors15runEndOfRowJobsERKjRKSt6vectorIjSaIjEERNS_10MultiValueE2512
_ZNK4PLMD6adjmat9Neighbors11performTaskERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjSB_RNS_10MultiValueE14048
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/Neighbors.cpp.func.html b/coverage/adjmat/Neighbors.cpp.func.html new file mode 100644 index 000000000000..c0be92dc8087 --- /dev/null +++ b/coverage/adjmat/Neighbors.cpp.func.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/Neighbors.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - Neighbors.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:495884.5 %
Date:2024-04-19 12:12:35Functions:61060.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat9Neighbors16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD6adjmat9Neighbors17canBeAfterInChainEPNS_16ActionWithVectorE0
_ZN4PLMD6adjmat9Neighbors17turnOnDerivativesEv0
_ZN4PLMD6adjmat9Neighbors22getNumberOfDerivativesEv0
_ZN4PLMD6adjmat9NeighborsC1ERKNS_13ActionOptionsE3
_ZN4PLMD6adjmat9NeighborsC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6adjmat9Neighbors11performTaskERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjSB_RNS_10MultiValueE14048
_ZNK4PLMD6adjmat9Neighbors12setupForTaskERKjRSt6vectorIjSaIjEERNS_10MultiValueE2512
_ZNK4PLMD6adjmat9Neighbors15runEndOfRowJobsERKjRKSt6vectorIjSaIjEERNS_10MultiValueE2512
_ZNK4PLMD6adjmat9Neighbors18getNumberOfColumnsEv8
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/Neighbors.cpp.gcov.html b/coverage/adjmat/Neighbors.cpp.gcov.html new file mode 100644 index 000000000000..8104e335fa3b --- /dev/null +++ b/coverage/adjmat/Neighbors.cpp.gcov.html @@ -0,0 +1,213 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/Neighbors.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - Neighbors.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:495884.5 %
Date:2024-04-19 12:12:35Functions:61060.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2017 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "ActionWithMatrix.h"
+      23             : #include "core/ActionRegister.h"
+      24             : 
+      25             : //+PLUMEDOC MCOLVAR NEIGHBORS
+      26             : /*
+      27             : Build a matrix with ones in for the N nearest neighbours of an atom
+      28             : 
+      29             : \par Examples
+      30             : 
+      31             : */
+      32             : //+ENDPLUMEDOC
+      33             : 
+      34             : namespace PLMD {
+      35             : namespace adjmat {
+      36             : 
+      37             : class Neighbors : public ActionWithMatrix {
+      38             :   bool lowest;
+      39             :   unsigned number;
+      40             : public:
+      41             :   static void registerKeywords( Keywords& keys );
+      42             :   explicit Neighbors(const ActionOptions&);
+      43             :   unsigned getNumberOfDerivatives() override;
+      44           8 :   unsigned getNumberOfColumns() const override { return number; }
+      45           0 :   bool canBeAfterInChain( ActionWithVector* av ) { return av->getLabel()!=(getPntrToArgument(0)->getPntrToAction())->getLabel(); }
+      46             :   void setupForTask( const unsigned& task_index, std::vector<unsigned>& indices, MultiValue& myvals ) const ;
+      47             :   void performTask( const std::string& controller, const unsigned& index1, const unsigned& index2, MultiValue& myvals ) const override;
+      48        2512 :   void runEndOfRowJobs( const unsigned& ival, const std::vector<unsigned> & indices, MultiValue& myvals ) const override {}
+      49             :   void turnOnDerivatives() override ;
+      50             : };
+      51             : 
+      52             : PLUMED_REGISTER_ACTION(Neighbors,"NEIGHBORS")
+      53             : 
+      54           5 : void Neighbors::registerKeywords( Keywords& keys ) {
+      55           5 :   ActionWithMatrix::registerKeywords( keys ); keys.use("ARG");
+      56          10 :   keys.add("compulsory","NLOWEST","0","in each row of the output matrix set the elements that correspond to the n lowest elements in each row of the input matrix equal to one");
+      57          10 :   keys.add("compulsory","NHIGHEST","0","in each row of the output matrix set the elements that correspond to the n highest elements in each row of the input matrix equal to one");
+      58           5 : }
+      59             : 
+      60           3 : Neighbors::Neighbors(const ActionOptions&ao):
+      61             :   Action(ao),
+      62           3 :   ActionWithMatrix(ao)
+      63             : {
+      64           3 :   if( getNumberOfArguments()!=1 ) error("found wrong number of arguments in input");
+      65           3 :   if( getPntrToArgument(0)->getRank()!=2 ) error("input argument should be a matrix");
+      66           3 :   getPntrToArgument(0)->buildDataStore();
+      67             : 
+      68           3 :   unsigned nlow; parse("NLOWEST",nlow);
+      69           3 :   unsigned nhigh; parse("NHIGHEST",nhigh);
+      70           3 :   if( nlow==0 && nhigh==0 ) error("missing NLOWEST or NHIGHEST keyword one of these two keywords must be set in input");
+      71           3 :   if( nlow>0 && nhigh>0 ) error("should only be one of NLOWEST or NHIGHEST set in input");
+      72           3 :   if( nlow>0 ) {
+      73           3 :     number=nlow; lowest=true;
+      74           3 :     log.printf("  output matrix will have non-zero values for elements that correpsond to the %d lowest elements in each row of the input matrix\n",number);
+      75             :   }
+      76           3 :   if( nhigh>0 ) {
+      77           0 :     number=nhigh; lowest=false;
+      78           0 :     log.printf("  output matrix will have non-zero values for elements that correpsond to the %d highest elements in each row of the input matrix\n",number);
+      79             :   }
+      80             : 
+      81             :   // And get the shape
+      82           3 :   std::vector<unsigned> shape( getPntrToArgument(0)->getShape() );
+      83           3 :   addValue( shape ); setNotPeriodic();
+      84           3 :   checkRead();
+      85           3 : }
+      86             : 
+      87           0 : void Neighbors::turnOnDerivatives() {
+      88           0 :   ActionWithValue::turnOnDerivatives();
+      89           0 :   warning("think about whether your symmetry functions are continuous. If the symmetry function can be calculated from distances only then you can use NEIGHBORS. If you calculate angles between vectors or use the vectors directly then the symmetry function computed using NEIGHBORS is not continuous.  It does not make sense to use such CVs when biasing");
+      90           0 : }
+      91             : 
+      92           0 : unsigned Neighbors::getNumberOfDerivatives() {
+      93           0 :   return 0;
+      94             : }
+      95             : 
+      96        2512 : void Neighbors::setupForTask( const unsigned& task_index, std::vector<unsigned>& indices, MultiValue& myvals ) const {
+      97        2512 :   const Value* wval = getPntrToArgument(0); unsigned nbonds = wval->getRowLength( task_index ), ncols = wval->getShape()[1];
+      98        2512 :   if( indices.size()!=1+number ) indices.resize( 1 + number );
+      99        2512 :   myvals.setSplitIndex(1+number);
+     100             : 
+     101             :   unsigned nind=0;
+     102      180890 :   for(unsigned i=0; i<nbonds; ++i) {
+     103      178378 :     unsigned ipos = ncols*task_index + wval->getRowIndex( task_index, i );
+     104      178378 :     double weighti = wval->get( ipos );
+     105      178378 :     if( weighti<epsilon ) continue ;
+     106      177866 :     nind++;
+     107             :   }
+     108        2512 :   if( number>nind ) plumed_merror("not enough matrix elements were stored");
+     109             : 
+     110             :   // Now build vectors for doing sorting
+     111        2512 :   std::vector<std::pair<double,unsigned> > rows( nind ); unsigned n=0;
+     112      180890 :   for(unsigned i=0; i<nbonds; ++i) {
+     113             :     unsigned iind = wval->getRowIndex( task_index, i );
+     114      178378 :     unsigned ipos = ncols*task_index + iind;
+     115      178378 :     double weighti = wval->get( ipos );
+     116      178378 :     if( weighti<epsilon ) continue ;
+     117      177866 :     rows[n].first=weighti; rows[n].second=iind; n++;
+     118             :   }
+     119             : 
+     120             :   // Now do the sort and clear all the stored values ready for recompute
+     121        2512 :   std::sort( rows.begin(), rows.end() );
+     122             :   // This is to make this action consistent with what in other matrix actions
+     123        2512 :   unsigned start_n = getPntrToArgument(0)->getShape()[0];
+     124             :   // And setup the lowest indices, which are the ones we need to calculate
+     125       16560 :   for(unsigned i=0; i<number; ++i) {
+     126       14048 :     indices[i+1] = start_n + rows[nind-1-i].second;
+     127       14048 :     if( lowest ) indices[i+1] = start_n + rows[i].second;
+     128             :   }
+     129        2512 : }
+     130             : 
+     131       14048 : void Neighbors::performTask( const std::string& controller, const unsigned& index1, const unsigned& index2, MultiValue& myvals ) const {
+     132       14048 :   myvals.addValue( getConstPntrToComponent(0)->getPositionInStream(), 1.0 );
+     133       14048 : }
+     134             : 
+     135             : }
+     136             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/OuterProduct.cpp.func-sort-c.html b/coverage/adjmat/OuterProduct.cpp.func-sort-c.html new file mode 100644 index 000000000000..8e0d710d7441 --- /dev/null +++ b/coverage/adjmat/OuterProduct.cpp.func-sort-c.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/OuterProduct.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - OuterProduct.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:717594.7 %
Date:2024-04-19 12:12:35Functions:8988.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat12OuterProductC2ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat12OuterProductC1ERKNS_13ActionOptionsE77
_ZN4PLMD6adjmat12OuterProduct16registerKeywordsERNS_8KeywordsE79
_ZN4PLMD6adjmat12OuterProduct22getNumberOfDerivativesEv96
_ZN4PLMD6adjmat12OuterProduct7prepareEv158
_ZNK4PLMD6adjmat12OuterProduct18getNumberOfColumnsEv2298
_ZNK4PLMD6adjmat12OuterProduct12setupForTaskERKjRSt6vectorIjSaIjEERNS_10MultiValueE27151
_ZNK4PLMD6adjmat12OuterProduct15runEndOfRowJobsERKjRKSt6vectorIjSaIjEERNS_10MultiValueE39963
_ZNK4PLMD6adjmat12OuterProduct11performTaskERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjSB_RNS_10MultiValueE6874326
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/OuterProduct.cpp.func.html b/coverage/adjmat/OuterProduct.cpp.func.html new file mode 100644 index 000000000000..d75491da2ea2 --- /dev/null +++ b/coverage/adjmat/OuterProduct.cpp.func.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/OuterProduct.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - OuterProduct.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:717594.7 %
Date:2024-04-19 12:12:35Functions:8988.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat12OuterProduct16registerKeywordsERNS_8KeywordsE79
_ZN4PLMD6adjmat12OuterProduct22getNumberOfDerivativesEv96
_ZN4PLMD6adjmat12OuterProduct7prepareEv158
_ZN4PLMD6adjmat12OuterProductC1ERKNS_13ActionOptionsE77
_ZN4PLMD6adjmat12OuterProductC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6adjmat12OuterProduct11performTaskERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjSB_RNS_10MultiValueE6874326
_ZNK4PLMD6adjmat12OuterProduct12setupForTaskERKjRSt6vectorIjSaIjEERNS_10MultiValueE27151
_ZNK4PLMD6adjmat12OuterProduct15runEndOfRowJobsERKjRKSt6vectorIjSaIjEERNS_10MultiValueE39963
_ZNK4PLMD6adjmat12OuterProduct18getNumberOfColumnsEv2298
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/OuterProduct.cpp.gcov.html b/coverage/adjmat/OuterProduct.cpp.gcov.html new file mode 100644 index 000000000000..551c4a1a758a --- /dev/null +++ b/coverage/adjmat/OuterProduct.cpp.gcov.html @@ -0,0 +1,237 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/OuterProduct.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - OuterProduct.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:717594.7 %
Date:2024-04-19 12:12:35Functions: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 "ActionWithMatrix.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "tools/LeptonCall.h"
+      25             : 
+      26             : //+PLUMEDOC COLVAR OUTER_PRODUCT
+      27             : /*
+      28             : Calculate the outer product matrix of two vectors
+      29             : 
+      30             : \par Examples
+      31             : 
+      32             : */
+      33             : //+ENDPLUMEDOC
+      34             : 
+      35             : namespace PLMD {
+      36             : namespace adjmat {
+      37             : 
+      38             : class OuterProduct : public ActionWithMatrix {
+      39             : private:
+      40             :   bool domin, domax, diagzero;
+      41             :   LeptonCall function;
+      42             :   unsigned nderivatives;
+      43             :   bool stored_vector1, stored_vector2;
+      44             : public:
+      45             :   static void registerKeywords( Keywords& keys );
+      46             :   explicit OuterProduct(const ActionOptions&);
+      47             :   unsigned getNumberOfDerivatives();
+      48             :   void prepare() override ;
+      49        2298 :   unsigned getNumberOfColumns() const override { return getConstPntrToComponent(0)->getShape()[1]; }
+      50             :   void setupForTask( const unsigned& task_index, std::vector<unsigned>& indices, MultiValue& myvals ) const ;
+      51             :   void performTask( const std::string& controller, const unsigned& index1, const unsigned& index2, MultiValue& myvals ) const override;
+      52             :   void runEndOfRowJobs( const unsigned& ival, const std::vector<unsigned> & indices, MultiValue& myvals ) const override ;
+      53             : };
+      54             : 
+      55             : PLUMED_REGISTER_ACTION(OuterProduct,"OUTER_PRODUCT")
+      56             : 
+      57          79 : void OuterProduct::registerKeywords( Keywords& keys ) {
+      58          79 :   ActionWithMatrix::registerKeywords(keys); keys.use("ARG");
+      59         158 :   keys.add("compulsory","FUNC","x*y","the function of the input vectors that should be put in the elements of the outer product");
+      60         158 :   keys.addFlag("ELEMENTS_ON_DIAGONAL_ARE_ZERO",false,"set all diagonal elements to zero");
+      61          79 : }
+      62             : 
+      63          77 : OuterProduct::OuterProduct(const ActionOptions&ao):
+      64             :   Action(ao),
+      65             :   ActionWithMatrix(ao),
+      66          77 :   domin(false),
+      67          77 :   domax(false)
+      68             : {
+      69          77 :   if( getNumberOfArguments()!=2 ) error("should be two arguments to this action, a matrix and a vector");
+      70          77 :   if( getPntrToArgument(0)->getRank()!=1 || getPntrToArgument(0)->hasDerivatives() ) error("first argument to this action should be a vector");
+      71          77 :   if( getPntrToArgument(1)->getRank()!=1 || getPntrToArgument(1)->hasDerivatives() ) error("first argument to this action should be a vector");
+      72             : 
+      73         154 :   std::string func; parse("FUNC",func);
+      74          77 :   if( func=="min") {
+      75           0 :     domin=true;
+      76           0 :     log.printf("  taking minimum of two input vectors \n");
+      77          77 :   } else if( func=="max" ) {
+      78           2 :     domax=true;
+      79           2 :     log.printf("  taking maximum of two input vectors \n");
+      80             :   } else {
+      81          75 :     log.printf("  with function : %s \n", func.c_str() );
+      82          75 :     std::vector<std::string> var(2); var[0]="x"; var[1]="y";
+      83          75 :     function.set( func, var, this );
+      84          75 :   }
+      85          77 :   parseFlag("ELEMENTS_ON_DIAGONAL_ARE_ZERO",diagzero);
+      86          77 :   if( diagzero ) log.printf("  setting diagonal elements equal to zero\n");
+      87             : 
+      88          77 :   std::vector<unsigned> shape(2); shape[0]=getPntrToArgument(0)->getShape()[0]; shape[1]=getPntrToArgument(1)->getShape()[0];
+      89          77 :   addValue( shape ); setNotPeriodic(); nderivatives = buildArgumentStore(0);
+      90          77 :   std::string headstr=getFirstActionInChain()->getLabel();
+      91          77 :   stored_vector1 = getPntrToArgument(0)->ignoreStoredValue( headstr );
+      92          77 :   stored_vector2 = getPntrToArgument(1)->ignoreStoredValue( headstr );
+      93          77 :   if( getPntrToArgument(0)->isDerivativeZeroWhenValueIsZero() || getPntrToArgument(1)->isDerivativeZeroWhenValueIsZero() ) getPntrToComponent(0)->setDerivativeIsZeroWhenValueIsZero();
+      94          77 : }
+      95             : 
+      96          96 : unsigned OuterProduct::getNumberOfDerivatives() {
+      97          96 :   return nderivatives;
+      98             : }
+      99             : 
+     100         158 : void OuterProduct::prepare() {
+     101         158 :   ActionWithVector::prepare(); Value* myval=getPntrToComponent(0);
+     102         158 :   if( myval->getShape()[0]==getPntrToArgument(0)->getShape()[0] && myval->getShape()[1]==getPntrToArgument(1)->getShape()[0] ) return;
+     103          17 :   std::vector<unsigned> shape(2); shape[0] = getPntrToArgument(0)->getShape()[0]; shape[1] = getPntrToArgument(1)->getShape()[0];
+     104          17 :   myval->setShape( shape );
+     105             : }
+     106             : 
+     107       27151 : void OuterProduct::setupForTask( const unsigned& task_index, std::vector<unsigned>& indices, MultiValue& myvals ) const {
+     108       27151 :   unsigned start_n = getPntrToArgument(0)->getShape()[0], size_v = getPntrToArgument(1)->getShape()[0];
+     109       27151 :   if( diagzero ) {
+     110         990 :     if( indices.size()!=size_v ) indices.resize( size_v );
+     111             :     unsigned k=1;
+     112       99000 :     for(unsigned i=0; i<size_v; ++i) {
+     113       98010 :       if( task_index==i ) continue ;
+     114       97020 :       indices[k] = size_v + i; k++;
+     115             :     }
+     116             :     myvals.setSplitIndex( size_v );
+     117             :   } else {
+     118       26161 :     if( indices.size()!=size_v+1 ) indices.resize( size_v+1 );
+     119     1690193 :     for(unsigned i=0; i<size_v; ++i) indices[i+1] = start_n + i;
+     120             :     myvals.setSplitIndex( size_v + 1 );
+     121             :   }
+     122       27151 : }
+     123             : 
+     124     6874326 : void OuterProduct::performTask( const std::string& controller, const unsigned& index1, const unsigned& index2, MultiValue& myvals ) const {
+     125     6874326 :   unsigned ostrn = getConstPntrToComponent(0)->getPositionInStream(), ind2=index2;
+     126     6874326 :   if( index2>=getPntrToArgument(0)->getShape()[0] ) ind2 = index2 - getPntrToArgument(0)->getShape()[0];
+     127    13385626 :   if( diagzero && index1==ind2 ) return;
+     128             : 
+     129     6874326 :   double fval; unsigned jarg = 0, kelem = index1; bool jstore=stored_vector1;
+     130     6874326 :   std::vector<double> args(2);
+     131     6874326 :   args[0] = getArgumentElement( 0, index1, myvals );
+     132     6874326 :   args[1] = getArgumentElement( 1, ind2, myvals );
+     133     6874326 :   if( domin ) {
+     134           0 :     fval=args[0]; if( args[1]<args[0] ) { fval=args[1]; jarg=1; kelem=ind2; jstore=stored_vector2; }
+     135     6874326 :   } else if( domax ) {
+     136      315192 :     fval=args[0]; if( args[1]>args[0] ) { fval=args[1]; jarg=1; kelem=ind2; jstore=stored_vector2; }
+     137     6559134 :   } else { fval=function.evaluate( args ); }
+     138             : 
+     139     6874326 :   myvals.addValue( ostrn, fval );
+     140     6874326 :   if( doNotCalculateDerivatives() ) return ;
+     141             : 
+     142      366326 :   if( domin || domax ) {
+     143           0 :     addDerivativeOnVectorArgument( jstore, 0, jarg, kelem, 1.0, myvals );
+     144             :   } else {
+     145      366326 :     addDerivativeOnVectorArgument( stored_vector1, 0, 0, index1, function.evaluateDeriv( 0, args ), myvals );
+     146      366326 :     addDerivativeOnVectorArgument( stored_vector2, 0, 1, ind2, function.evaluateDeriv( 1, args ), myvals );
+     147             :   }
+     148      366326 :   if( doNotCalculateDerivatives() || !matrixChainContinues() ) return ;
+     149      363026 :   unsigned nmat = getConstPntrToComponent(0)->getPositionInMatrixStash(), nmat_ind = myvals.getNumberOfMatrixRowDerivatives( nmat );
+     150      363026 :   myvals.getMatrixRowDerivativeIndices( nmat )[nmat_ind] = arg_deriv_starts[1] + ind2; myvals.setNumberOfMatrixRowDerivatives( nmat, nmat_ind+1 );
+     151             : }
+     152             : 
+     153       39963 : void OuterProduct::runEndOfRowJobs( const unsigned& ival, const std::vector<unsigned> & indices, MultiValue& myvals ) const {
+     154       39963 :   if( doNotCalculateDerivatives() || !matrixChainContinues() ) return ;
+     155       11402 :   unsigned nmat = getConstPntrToComponent(0)->getPositionInMatrixStash(), nmat_ind = myvals.getNumberOfMatrixRowDerivatives( nmat );
+     156       11402 :   myvals.getMatrixRowDerivativeIndices( nmat )[nmat_ind] = ival; myvals.setNumberOfMatrixRowDerivatives( nmat, nmat_ind+1 );
+     157             : }
+     158             : 
+     159             : }
+     160             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/Sprint.cpp.func-sort-c.html b/coverage/adjmat/Sprint.cpp.func-sort-c.html new file mode 100644 index 000000000000..3d42463b50c4 --- /dev/null +++ b/coverage/adjmat/Sprint.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + 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:3838100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat6SprintC2ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat6SprintC1ERKNS_13ActionOptionsE1
_ZN4PLMD6adjmat6Sprint16registerKeywordsERNS_8KeywordsE3
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/Sprint.cpp.func.html b/coverage/adjmat/Sprint.cpp.func.html new file mode 100644 index 000000000000..b4e1c3be67fc --- /dev/null +++ b/coverage/adjmat/Sprint.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + 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:3838100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat6Sprint16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD6adjmat6SprintC1ERKNS_13ActionOptionsE1
_ZN4PLMD6adjmat6SprintC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/Sprint.cpp.gcov.html b/coverage/adjmat/Sprint.cpp.gcov.html new file mode 100644 index 000000000000..763e1f83f444 --- /dev/null +++ b/coverage/adjmat/Sprint.cpp.gcov.html @@ -0,0 +1,220 @@ + + + + + + + + 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:3838100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2020 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionShortcut.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "core/ActionWithValue.h"
+      25             : #include "core/PlumedMain.h"
+      26             : #include "core/ActionSet.h"
+      27             : 
+      28             : //+PLUMEDOC MATRIXF SPRINT
+      29             : /*
+      30             : Calculate SPRINT topological variables from an adjacency matrix.
+      31             : 
+      32             : The SPRINT topological variables are calculated from the largest eigenvalue, \f$\lambda\f$ of
+      33             : an \f$n\times n\f$ adjacency matrix and its corresponding eigenvector, \f$\mathbf{V}\f$, using:
+      34             : 
+      35             : \f[
+      36             : s_i = \sqrt{n} \lambda v_i
+      37             : \f]
+      38             : 
+      39             : You can use different quantities to measure whether or not two given atoms/molecules are
+      40             : adjacent or not in the adjacency matrix.  The simplest measure of adjacency is is whether
+      41             : two atoms/molecules are within some cutoff of each other.  Further complexity can be added by
+      42             : insisting that two molecules are adjacent if they are within a certain distance of each
+      43             : other and if they have similar orientations.
+      44             : 
+      45             : \par Examples
+      46             : 
+      47             : This example input calculates the 7 SPRINT coordinates for a 7 atom cluster of Lennard-Jones
+      48             : atoms and prints their values to a file.  In this input the SPRINT coordinates are calculated
+      49             : in the manner described in ?? so two atoms are adjacent if they are within a cutoff:
+      50             : 
+      51             : \plumedfile
+      52             : DENSITY SPECIES=1-7 LABEL=d1
+      53             : CONTACT_MATRIX ATOMS=d1 SWITCH={RATIONAL R_0=0.1} LABEL=mat
+      54             : SPRINT MATRIX=mat LABEL=ss
+      55             : PRINT ARG=ss.* FILE=colvar
+      56             : \endplumedfile
+      57             : 
+      58             : This example input calculates the 14 SPRINT coordinates for a molecule composed of 7 hydrogen and
+      59             : 7 carbon atoms.  Once again two atoms are adjacent if they are within a cutoff:
+      60             : 
+      61             : \plumedfile
+      62             : DENSITY SPECIES=1-7 LABEL=c
+      63             : DENSITY SPECIES=8-14 LABEL=h
+      64             : 
+      65             : CONTACT_MATRIX ...
+      66             :   ATOMS=c,h
+      67             :   SWITCH11={RATIONAL R_0=2.6 NN=6 MM=12}
+      68             :   SWITCH12={RATIONAL R_0=2.2 NN=6 MM=12}
+      69             :   SWITCH22={RATIONAL R_0=2.2 NN=6 MM=12}
+      70             :   LABEL=mat
+      71             : ... CONTACT_MATRIX
+      72             : 
+      73             : SPRINT MATRIX=mat LABEL=ss
+      74             : 
+      75             : PRINT ARG=ss.* FILE=colvar
+      76             : \endplumedfile
+      77             : 
+      78             : */
+      79             : //+ENDPLUMEDOC
+      80             : 
+      81             : namespace PLMD {
+      82             : namespace adjmat {
+      83             : 
+      84             : class Sprint : public ActionShortcut {
+      85             : public:
+      86             :   static void registerKeywords(Keywords& keys);
+      87             :   explicit Sprint(const ActionOptions&);
+      88             : };
+      89             : 
+      90             : PLUMED_REGISTER_ACTION(Sprint,"SPRINT")
+      91             : 
+      92           3 : void Sprint::registerKeywords(Keywords& keys) {
+      93           3 :   ActionShortcut::registerKeywords( keys );
+      94           6 :   keys.add("optional","MATRIX","the matrix that you would like to perform SPRINT on");
+      95           6 :   keys.add("numbered","GROUP","specifies the list of atoms that should be assumed indistinguishable");
+      96           6 :   keys.add("numbered","SWITCH","specify the switching function to use between two sets of indistinguishable atoms");
+      97           9 :   keys.needsAction("CONTACT_MATRIX"); keys.needsAction("DIAGONALIZE"); keys.needsAction("CUSTOM");
+      98           9 :   keys.needsAction("SELECT_COMPONENTS"); keys.needsAction("SORT"); keys.needsAction("COMBINE");
+      99           6 :   keys.addOutputComponent("coord","default","the sprint coordinates");
+     100           3 : }
+     101             : 
+     102           1 : Sprint::Sprint(const ActionOptions& ao):
+     103             :   Action(ao),
+     104           1 :   ActionShortcut(ao)
+     105             : {
+     106           2 :   std::string matinp; parse("MATRIX",matinp);
+     107           1 :   if( matinp.length()==0 ) {
+     108           2 :     readInputLine( getShortcutLabel() + "_jmat: CONTACT_MATRIX " + convertInputLineToString() );
+     109           2 :     matinp = getShortcutLabel() + "_jmat";
+     110             :   }
+     111           1 :   std::vector<unsigned> nin_group; unsigned ntot_atoms=0;
+     112           1 :   for(unsigned i=1;; ++i) {
+     113           3 :     std::string inum; Tools::convert( i, inum );
+     114           6 :     ActionWithValue* av = plumed.getActionSet().selectWithLabel<ActionWithValue*>( matinp + inum + inum );
+     115           3 :     if( !av ) break ;
+     116           2 :     unsigned natoms = (av->copyOutput(0))->getShape()[0]; nin_group.push_back( natoms ); ntot_atoms += natoms;
+     117           2 :   }
+     118             : 
+     119             :   // Diagonalization
+     120           2 :   readInputLine( getShortcutLabel() + "_diag: DIAGONALIZE ARG=" + matinp + " VECTORS=1");
+     121             :   // Compute sprint coordinates as product of eigenvalue and eigenvector times square root of number of atoms in all groups
+     122           1 :   std::string str_natoms; Tools::convert( ntot_atoms, str_natoms );
+     123           3 :   readInputLine( getShortcutLabel() + "_sp: CUSTOM ARG=" + getShortcutLabel() + "_diag.vals-1," + getShortcutLabel() +
+     124           2 :                  "_diag.vecs-1 FUNC=sqrt(" + str_natoms + ")*x*y PERIODIC=NO");
+     125             :   // Sort sprint coordinates for each group of atoms
+     126           1 :   unsigned k=0, kk=0;
+     127           3 :   for(unsigned j=0; j<nin_group.size(); ++j) {
+     128           2 :     std::string jnum, knum; Tools::convert( j+1, jnum ); Tools::convert(k+1, knum); k++;
+     129           4 :     std::string sort_act = getShortcutLabel() + "_selection" + jnum + ": SELECT_COMPONENTS ARG=" + getShortcutLabel() + "_sp COMPONENTS=" + knum;
+     130          14 :     for(unsigned n=1; n<nin_group[j]; ++n) {
+     131          24 :       Tools::convert( k+1, knum ); sort_act += ","+ knum; k++;
+     132             :     }
+     133           2 :     readInputLine( sort_act );
+     134           4 :     readInputLine( getShortcutLabel() + jnum + ": SORT ARG=" + getShortcutLabel() + "_selection" + jnum );
+     135          16 :     for(unsigned n=0; n<nin_group[j]; ++n) {
+     136          14 :       std::string knum, nnum; Tools::convert( kk, knum ); Tools::convert( n+1, nnum ); kk++;
+     137          28 :       readInputLine( getShortcutLabel() + "_coord-" + knum + ": COMBINE ARG=" + getShortcutLabel() + jnum + "." + nnum + " PERIODIC=NO" );
+     138             :     }
+     139             :   }
+     140           1 : }
+     141             : 
+     142             : }
+     143             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/TopologyMatrix.cpp.func-sort-c.html b/coverage/adjmat/TopologyMatrix.cpp.func-sort-c.html new file mode 100644 index 000000000000..5dba41e6b9b7 --- /dev/null +++ b/coverage/adjmat/TopologyMatrix.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + 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:140140100.0 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat14TopologyMatrixC2ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat14TopologyMatrixC1ERKNS_13ActionOptionsE8
_ZN4PLMD6adjmat14TopologyMatrix16registerKeywordsERNS_8KeywordsE10
_ZNK4PLMD6adjmat14TopologyMatrix15calculateWeightERKNS_13VectorGenericILj3EEES5_RKjRNS_10MultiValueE69150
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/TopologyMatrix.cpp.func.html b/coverage/adjmat/TopologyMatrix.cpp.func.html new file mode 100644 index 000000000000..6ff1e305207a --- /dev/null +++ b/coverage/adjmat/TopologyMatrix.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + 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:140140100.0 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat14TopologyMatrix16registerKeywordsERNS_8KeywordsE10
_ZN4PLMD6adjmat14TopologyMatrixC1ERKNS_13ActionOptionsE8
_ZN4PLMD6adjmat14TopologyMatrixC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6adjmat14TopologyMatrix15calculateWeightERKNS_13VectorGenericILj3EEES5_RKjRNS_10MultiValueE69150
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/TopologyMatrix.cpp.gcov.html b/coverage/adjmat/TopologyMatrix.cpp.gcov.html new file mode 100644 index 000000000000..bcf9dac856dc --- /dev/null +++ b/coverage/adjmat/TopologyMatrix.cpp.gcov.html @@ -0,0 +1,347 @@ + + + + + + + + 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:140140100.0 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2020 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received 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 "tools/SwitchingFunction.h"
+      24             : #include "tools/HistogramBead.h"
+      25             : #include "core/ActionRegister.h"
+      26             : 
+      27             : #include <string>
+      28             : #include <cmath>
+      29             : 
+      30             : //+PLUMEDOC MATRIX TOPOLOGY_MATRIX
+      31             : /*
+      32             : Adjacency matrix in which two atoms are adjacent if they are connected topologically
+      33             : 
+      34             : \par Examples
+      35             : 
+      36             : 
+      37             : */
+      38             : //+ENDPLUMEDOC
+      39             : 
+      40             : namespace PLMD {
+      41             : namespace adjmat {
+      42             : 
+      43             : class TopologyMatrix : public AdjacencyMatrixBase {
+      44             : private:
+      45             : /// The width to use for the kernel density estimation and the
+      46             : /// sizes of the bins to be used in kernel density estimation
+      47             :   double sigma;
+      48             :   std::string kerneltype;
+      49             : /// The maximum number of bins that will be used
+      50             : /// This is calculated based on the dmax of the switching functions
+      51             :   unsigned maxbins;
+      52             : /// The volume of the cells
+      53             :   double cell_volume;
+      54             : /// switching function
+      55             :   SwitchingFunction switchingFunction;
+      56             :   SwitchingFunction cylinder_sw;
+      57             :   SwitchingFunction low_sf;
+      58             :   double binw_mat;
+      59             :   SwitchingFunction threshold_switch;
+      60             : public:
+      61             :   static void registerKeywords( Keywords& keys );
+      62             :   explicit TopologyMatrix(const ActionOptions&);
+      63             : // active methods:
+      64             :   double calculateWeight( const Vector& pos1, const Vector& pos2, const unsigned& natoms, MultiValue& myvals ) const override;
+      65             : };
+      66             : 
+      67             : PLUMED_REGISTER_ACTION(TopologyMatrix,"TOPOLOGY_MATRIX")
+      68             : 
+      69          10 : void TopologyMatrix::registerKeywords( Keywords& keys ) {
+      70          10 :   AdjacencyMatrixBase::registerKeywords( keys );
+      71          20 :   keys.add("atoms","BACKGROUND_ATOMS","the list of atoms that should be considered as part of the background density");
+      72          20 :   keys.add("compulsory","SWITCH","This keyword is used if you want to employ an alternative to the continuous swiching function defined above. "
+      73             :            "The following provides information on the \\ref switchingfunction that are available. "
+      74             :            "When this keyword is present you no longer need the NN, MM, D_0 and R_0 keywords.");
+      75          20 :   keys.add("compulsory","RADIUS","");
+      76          20 :   keys.add("compulsory","CYLINDER_SWITCH","a switching function on ( r_ij . r_ik - 1 )/r_ij");
+      77          20 :   keys.add("compulsory","BIN_SIZE","the size to use for the bins");
+      78          20 :   keys.add("compulsory","DENSITY_THRESHOLD","");
+      79          20 :   keys.add("compulsory","SIGMA","the width of the function to be used for kernel density estimation");
+      80          20 :   keys.add("compulsory","KERNEL","gaussian","the type of kernel function to be used");
+      81          10 : }
+      82             : 
+      83           8 : TopologyMatrix::TopologyMatrix(const ActionOptions&ao):
+      84             :   Action(ao),
+      85           8 :   AdjacencyMatrixBase(ao)
+      86             : {
+      87          16 :   std::string sfinput,errors; parse("SWITCH",sfinput);
+      88           8 :   if( sfinput.length()==0 ) error("could not find SWITCH keyword");
+      89           8 :   switchingFunction.set(sfinput,errors);
+      90           8 :   if( errors.length()!=0 ) error("problem reading SWITCH keyword : " + errors );
+      91             : 
+      92          16 :   std::string hsfinput; parse("CYLINDER_SWITCH",hsfinput);
+      93           8 :   if( hsfinput.length()==0 ) error("could not find CYLINDER_SWITCH keyword");
+      94           8 :   low_sf.set(hsfinput,errors);
+      95           8 :   if( errors.length()!=0 ) error("problem reading CYLINDER_SWITCH keyword : " + errors );
+      96             : 
+      97          16 :   std::string asfinput; parse("RADIUS",asfinput);
+      98           8 :   if( asfinput.length()==0 ) error("could not find RADIUS keyword");
+      99           8 :   cylinder_sw.set(asfinput,errors);
+     100           8 :   if( errors.length()!=0 ) error("problem reading RADIUS keyword : " + errors );
+     101             : 
+     102          16 :   std::string tsfinput; parse("DENSITY_THRESHOLD",tsfinput);
+     103           8 :   if( tsfinput.length()==0 ) error("could not find DENSITY_THRESHOLD keyword");
+     104           8 :   threshold_switch.set(tsfinput,errors);
+     105           8 :   if( errors.length()!=0 ) error("problem reading DENSITY_THRESHOLD keyword : " + errors );
+     106             :   // Read in stuff for grid
+     107          24 :   parse("SIGMA",sigma); parse("KERNEL",kerneltype); parse("BIN_SIZE",binw_mat);
+     108             : 
+     109             :   // Set the link cell cutoff
+     110           8 :   setLinkCellCutoff( true, switchingFunction.get_dmax(), std::numeric_limits<double>::max() );
+     111             :   // Set the number of bins
+     112           8 :   maxbins = std::floor( switchingFunction.get_dmax() / binw_mat ) + 1;
+     113             :   // Set the cell volume
+     114           8 :   double r=cylinder_sw.get_d0() + cylinder_sw.get_r0();
+     115           8 :   cell_volume=binw_mat*pi*r*r;
+     116             : 
+     117             :   // And check everything has been read in correctly
+     118           8 :   checkRead();
+     119           8 : }
+     120             : 
+     121       69150 : double TopologyMatrix::calculateWeight( const Vector& pos1, const Vector& pos2, const unsigned& natoms, MultiValue& myvals ) const {
+     122             :   // Compute switching function on distance between atoms
+     123       69150 :   Vector distance = pbcDistance( pos1, pos2 ); double len2 = distance.modulo2();
+     124       69150 :   if( len2>switchingFunction.get_dmax2() ) return 0.0;
+     125       26332 :   double dfuncl, sw = switchingFunction.calculateSqr( len2, dfuncl );
+     126             : 
+     127             :   // Now run through all sea atoms
+     128       26332 :   HistogramBead bead; bead.isNotPeriodic(); bead.setKernelType( kerneltype );
+     129       26332 :   Vector g1derivf,g2derivf,lderivf; Tensor vir; double binlength = maxbins * binw_mat;
+     130       26332 :   MultiValue tvals( maxbins, myvals.getNumberOfDerivatives() );
+     131   236742358 :   for(unsigned i=0; i<natoms; ++i) {
+     132             :     // Position of sea atom (this will be the origin)
+     133             :     Vector d2 = getPosition(i,myvals);
+     134             :     // Vector connecting sea atom and first in bond taking pbc into account
+     135             :     Vector d20 = pbcDistance( d2, pos1 );
+     136             :     // Vector connecting sea atom and second in bond taking pbc into account
+     137             :     Vector d21 = pbcDistance( d2, pos2 );
+     138             :     // Now length of bond modulus and so on -- no pbc here as we want sea atom in middle
+     139   236716026 :     Vector d1 = delta( d20, d21 ); double d1_len = d1.modulo(); d1 = d1 / d1_len;
+     140             :     // Switching function on distance between nodes
+     141   371343234 :     if( d1_len>switchingFunction.get_dmax() ) continue ;
+     142             :     // Ensure that the center of the bins are on the center of the bond connecting the two atoms
+     143   183588938 :     double start2atom = 0.5*(binlength-d1_len); Vector dstart = d20 - start2atom*d1;
+     144             :     // Now calculate projection of axis of cylinder
+     145   183588938 :     double proj=dotProduct(-dstart,d1);
+     146             :     // Calculate length of vector connecting start of cylinder to first atom
+     147             :     // And now work out projection on vector connecting start and end of cylinder
+     148   183588938 :     double proj_between = proj - start2atom;
+     149             :     // This tells us if we are outside the end of the cylinder
+     150   183588938 :     double excess = proj_between - d1_len;
+     151             :     // Return if we are outside of the cylinder as calculated based on excess
+     152   183588938 :     if( excess>low_sf.get_dmax() || -proj_between>low_sf.get_dmax() ) continue;
+     153             :     // Calculate the excess swiching functions
+     154    48961730 :     double edf1, eval1 = low_sf.calculate( excess, edf1 );
+     155    48961730 :     double edf2, eval2 = low_sf.calculate( -proj_between, edf2 );
+     156             :     // Calculate the projection on the perpendicular distance from the center of the tube
+     157    48961730 :     double cm = dstart.modulo2() - proj*proj;
+     158             : 
+     159             :     // Now calculate the density in the cylinder
+     160    48961730 :     if( cm>0 && cm<cylinder_sw.get_dmax2() ) {
+     161      288350 :       double dfuncr, val = cylinder_sw.calculateSqr( cm, dfuncr );
+     162      288350 :       Vector dc1, dc2, dc3, dd1, dd2, dd3, de1, de2, de3;
+     163      288350 :       if( !doNotCalculateDerivatives() ) {
+     164       28284 :         Tensor d1_a1;
+     165             :         // Derivative of director connecting atom1 - atom2 wrt the position of atom 1
+     166       28284 :         d1_a1(0,0) = ( -(d1[1]*d1[1]+d1[2]*d1[2])/d1_len );   // dx/dx
+     167       28284 :         d1_a1(0,1) = (  d1[0]*d1[1]/d1_len );                 // dx/dy
+     168       28284 :         d1_a1(0,2) = (  d1[0]*d1[2]/d1_len );                 // dx/dz
+     169       28284 :         d1_a1(1,0) = (  d1[1]*d1[0]/d1_len );                 // dy/dx
+     170       28284 :         d1_a1(1,1) = ( -(d1[0]*d1[0]+d1[2]*d1[2])/d1_len );   // dy/dy
+     171       28284 :         d1_a1(1,2) = (  d1[1]*d1[2]/d1_len );
+     172       28284 :         d1_a1(2,0) = (  d1[2]*d1[0]/d1_len );
+     173       28284 :         d1_a1(2,1) = (  d1[2]*d1[1]/d1_len );
+     174       28284 :         d1_a1(2,2) = ( -(d1[1]*d1[1]+d1[0]*d1[0])/d1_len );
+     175             : 
+     176             :         // Calculate derivatives of dot product
+     177       28284 :         dd1 = matmul(-dstart, d1_a1) - 0.5*d1;
+     178       28284 :         dd2 = matmul(-dstart, -d1_a1) - 0.5*d1;
+     179       28284 :         dd3 = d1;
+     180             : 
+     181             :         // Calculate derivatives of cross product
+     182       28284 :         Vector der( -0.5*binlength*matmul( d1_a1,dstart ) );
+     183       28284 :         dc1 = dfuncr*( 0.5*dstart + der - proj*dd1 );
+     184       28284 :         dc2 = dfuncr*( 0.5*dstart - der - proj*dd2 );
+     185       28284 :         dc3 = dfuncr*( -dstart - proj*dd3 );
+     186             : 
+     187             :         // Calculate derivatives of excess
+     188       28284 :         de1 = eval2*edf1*excess*(dd1 + 0.5*d1 ) + eval1*edf2*proj_between*(dd1 - 0.5*d1);
+     189       28284 :         de2 = eval2*edf1*excess*(dd2 - 0.5*d1 ) + eval1*edf2*proj_between*(dd2 + 0.5*d1);
+     190       28284 :         de3 = ( eval2*edf1*excess + eval1*edf2*proj_between )*dd3;
+     191             :       }
+     192     2225914 :       for(unsigned bin=0; bin<maxbins; ++bin) {
+     193     1937564 :         bead.set( bin*binw_mat, (bin+1)*binw_mat, sigma );
+     194     1937564 :         if( proj<(bin*binw_mat-bead.getCutoff()) || proj>binw_mat*(bin+1)+bead.getCutoff() ) continue;
+     195      386996 :         double der, contr=bead.calculateWithCutoff( proj, der ) / cell_volume; der /= cell_volume;
+     196      386996 :         tvals.addValue( bin, contr*val*eval1*eval2 );
+     197             : 
+     198      386996 :         if( !doNotCalculateDerivatives() ) {
+     199       38132 :           g1derivf=contr*eval1*eval2*dc1 + val*eval1*eval2*der*dd1 + contr*val*de1;
+     200       38132 :           tvals.addDerivative( bin, 3*myvals.getTaskIndex()+0, g1derivf[0] );
+     201       38132 :           tvals.addDerivative( bin, 3*myvals.getTaskIndex()+1, g1derivf[1] );
+     202       38132 :           tvals.addDerivative( bin, 3*myvals.getTaskIndex()+2, g1derivf[2] );
+     203       38132 :           g2derivf=contr*eval1*eval2*dc2 + val*eval1*eval2*der*dd2 + contr*val*de2;
+     204       38132 :           tvals.addDerivative( bin, 3*myvals.getSecondTaskIndex()+0, g2derivf[0] );
+     205       38132 :           tvals.addDerivative( bin, 3*myvals.getSecondTaskIndex()+1, g2derivf[1] );
+     206       38132 :           tvals.addDerivative( bin, 3*myvals.getSecondTaskIndex()+2, g2derivf[2] );
+     207       38132 :           lderivf=contr*eval1*eval2*dc3 + val*eval1*eval2*der*dd3 + contr*val*de3;
+     208       38132 :           unsigned tindex = myvals.getIndices()[ i + myvals.getSplitIndex() ];
+     209       38132 :           tvals.addDerivative( bin, 3*tindex+0, lderivf[0] );
+     210       38132 :           tvals.addDerivative( bin, 3*tindex+1, lderivf[1] );
+     211       38132 :           tvals.addDerivative( bin, 3*tindex+2, lderivf[2] );
+     212             :           // Virial
+     213       38132 :           vir = - Tensor( d20, g1derivf ) - Tensor( d21, g2derivf );
+     214       38132 :           unsigned nbase = 3*getNumberOfAtoms();
+     215       38132 :           tvals.addDerivative( bin, nbase+0, vir(0,0) );
+     216       38132 :           tvals.addDerivative( bin, nbase+1, vir(0,1) );
+     217       38132 :           tvals.addDerivative( bin, nbase+2, vir(0,2) );
+     218       38132 :           tvals.addDerivative( bin, nbase+3, vir(1,0) );
+     219       38132 :           tvals.addDerivative( bin, nbase+4, vir(1,1) );
+     220       38132 :           tvals.addDerivative( bin, nbase+5, vir(1,2) );
+     221       38132 :           tvals.addDerivative( bin, nbase+6, vir(2,0) );
+     222       38132 :           tvals.addDerivative( bin, nbase+7, vir(2,1) );
+     223       38132 :           tvals.addDerivative( bin, nbase+8, vir(2,2) );
+     224             :         }
+     225             :       }
+     226             :     }
+     227             :   }
+     228             :   // Find maximum density
+     229             :   double max = tvals.get(0); unsigned vout = 0;
+     230      305488 :   for(unsigned i=1; i<maxbins; ++i) {
+     231      279156 :     if( tvals.get(i)>max ) { max=tvals.get(i); vout=i; }
+     232             :   }
+     233             :   // Transform the density
+     234       26332 :   double df, tsw = threshold_switch.calculate( max, df );
+     235       26332 :   if( fabs(sw*tsw)<epsilon ) return 0;
+     236             : 
+     237        3516 :   if( !doNotCalculateDerivatives() ) {
+     238         942 :     Vector ader; Tensor vir; Vector ddd = tsw*dfuncl*distance;
+     239         942 :     ader[0] = tvals.getDerivative( vout, 3*myvals.getTaskIndex()+0 );
+     240         942 :     ader[1] = tvals.getDerivative( vout, 3*myvals.getTaskIndex()+1 );
+     241         942 :     ader[2] = tvals.getDerivative( vout, 3*myvals.getTaskIndex()+2 );
+     242         942 :     addAtomDerivatives( 0, sw*df*max*ader - ddd, myvals );
+     243         942 :     ader[0] = tvals.getDerivative( vout, 3*myvals.getSecondTaskIndex()+0 );
+     244         942 :     ader[1] = tvals.getDerivative( vout, 3*myvals.getSecondTaskIndex()+1 );
+     245         942 :     ader[2] = tvals.getDerivative( vout, 3*myvals.getSecondTaskIndex()+2 );
+     246         942 :     addAtomDerivatives( 1, sw*df*max*ader + ddd, myvals );
+     247      109488 :     for(unsigned i=0; i<natoms; ++i) {
+     248      108546 :       unsigned tindex = myvals.getIndices()[ i + myvals.getSplitIndex() ];
+     249      108546 :       ader[0] = tvals.getDerivative( vout, 3*tindex+0 );
+     250      108546 :       ader[1] = tvals.getDerivative( vout, 3*tindex+1 );
+     251      108546 :       ader[2] = tvals.getDerivative( vout, 3*tindex+2 );
+     252      108546 :       addThirdAtomDerivatives( i, sw*df*max*ader, myvals );
+     253             :     }
+     254         942 :     unsigned nbase = 3*getNumberOfAtoms(); Tensor vird(ddd,distance);
+     255         942 :     vir(0,0) = sw*df*max*tvals.getDerivative( vout, nbase+0 ) - vird(0,0);
+     256         942 :     vir(0,1) = sw*df*max*tvals.getDerivative( vout, nbase+1 ) - vird(0,1);
+     257         942 :     vir(0,2) = sw*df*max*tvals.getDerivative( vout, nbase+2 ) - vird(0,2);
+     258         942 :     vir(1,0) = sw*df*max*tvals.getDerivative( vout, nbase+3 ) - vird(1,0);
+     259         942 :     vir(1,1) = sw*df*max*tvals.getDerivative( vout, nbase+4 ) - vird(1,1);
+     260         942 :     vir(1,2) = sw*df*max*tvals.getDerivative( vout, nbase+5 ) - vird(1,2);
+     261         942 :     vir(2,0) = sw*df*max*tvals.getDerivative( vout, nbase+6 ) - vird(2,0);
+     262         942 :     vir(2,1) = sw*df*max*tvals.getDerivative( vout, nbase+7 ) - vird(2,1);
+     263         942 :     vir(2,2) = sw*df*max*tvals.getDerivative( vout, nbase+8 ) - vird(2,2);
+     264         942 :     addBoxDerivatives( vir, myvals );
+     265             :   }
+     266             :   return sw*tsw;
+     267       26332 : }
+     268             : 
+     269             : }
+     270             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/TorsionsMatrix.cpp.func-sort-c.html b/coverage/adjmat/TorsionsMatrix.cpp.func-sort-c.html new file mode 100644 index 000000000000..1c3bd896363d --- /dev/null +++ b/coverage/adjmat/TorsionsMatrix.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/TorsionsMatrix.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - TorsionsMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:717298.6 %
Date:2024-04-19 12:12:35Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat14TorsionsMatrixC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6adjmat14TorsionsMatrix18getNumberOfColumnsEv0
_ZNK4PLMD6adjmat14TorsionsMatrix12setupForTaskERKjRSt6vectorIjSaIjEERNS_10MultiValueE2
_ZN4PLMD6adjmat14TorsionsMatrixC1ERKNS_13ActionOptionsE7
_ZN4PLMD6adjmat14TorsionsMatrix16registerKeywordsERNS_8KeywordsE9
_ZN4PLMD6adjmat14TorsionsMatrix22getNumberOfDerivativesEv10
_ZNK4PLMD6adjmat14TorsionsMatrix15runEndOfRowJobsERKjRKSt6vectorIjSaIjEERNS_10MultiValueE5366
_ZNK4PLMD6adjmat14TorsionsMatrix11performTaskERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjSB_RNS_10MultiValueE1240496
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/TorsionsMatrix.cpp.func.html b/coverage/adjmat/TorsionsMatrix.cpp.func.html new file mode 100644 index 000000000000..d913d02eb5d2 --- /dev/null +++ b/coverage/adjmat/TorsionsMatrix.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/TorsionsMatrix.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - TorsionsMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:717298.6 %
Date:2024-04-19 12:12:35Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat14TorsionsMatrix16registerKeywordsERNS_8KeywordsE9
_ZN4PLMD6adjmat14TorsionsMatrix22getNumberOfDerivativesEv10
_ZN4PLMD6adjmat14TorsionsMatrixC1ERKNS_13ActionOptionsE7
_ZN4PLMD6adjmat14TorsionsMatrixC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6adjmat14TorsionsMatrix11performTaskERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjSB_RNS_10MultiValueE1240496
_ZNK4PLMD6adjmat14TorsionsMatrix12setupForTaskERKjRSt6vectorIjSaIjEERNS_10MultiValueE2
_ZNK4PLMD6adjmat14TorsionsMatrix15runEndOfRowJobsERKjRKSt6vectorIjSaIjEERNS_10MultiValueE5366
_ZNK4PLMD6adjmat14TorsionsMatrix18getNumberOfColumnsEv0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/TorsionsMatrix.cpp.gcov.html b/coverage/adjmat/TorsionsMatrix.cpp.gcov.html new file mode 100644 index 000000000000..cc486eb9be00 --- /dev/null +++ b/coverage/adjmat/TorsionsMatrix.cpp.gcov.html @@ -0,0 +1,237 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/TorsionsMatrix.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - TorsionsMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:717298.6 %
Date:2024-04-19 12:12:35Functions:6875.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 "ActionWithMatrix.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "tools/Torsion.h"
+      25             : 
+      26             : //+PLUMEDOC MCOLVAR TORSIONS_MATRIX
+      27             : /*
+      28             : Calculate the matrix of torsions between two vectors of molecules
+      29             : 
+      30             : \par Examples
+      31             : 
+      32             : */
+      33             : //+ENDPLUMEDOC
+      34             : 
+      35             : namespace PLMD {
+      36             : namespace adjmat {
+      37             : 
+      38             : class TorsionsMatrix : public ActionWithMatrix {
+      39             : private:
+      40             :   unsigned nderivatives;
+      41             :   bool stored_matrix1, stored_matrix2;
+      42             : public:
+      43             :   static void registerKeywords( Keywords& keys );
+      44             :   explicit TorsionsMatrix(const ActionOptions&);
+      45             :   unsigned getNumberOfDerivatives();
+      46           0 :   unsigned getNumberOfColumns() const override { return getConstPntrToComponent(0)->getShape()[1]; }
+      47             :   void setupForTask( const unsigned& task_index, std::vector<unsigned>& indices, MultiValue& myvals ) const ;
+      48             :   void performTask( const std::string& controller, const unsigned& index1, const unsigned& index2, MultiValue& myvals ) const override;
+      49             :   void runEndOfRowJobs( const unsigned& ival, const std::vector<unsigned> & indices, MultiValue& myvals ) const override ;
+      50             : };
+      51             : 
+      52             : PLUMED_REGISTER_ACTION(TorsionsMatrix,"TORSIONS_MATRIX")
+      53             : 
+      54           9 : void TorsionsMatrix::registerKeywords( Keywords& keys ) {
+      55           9 :   ActionWithMatrix::registerKeywords(keys); keys.use("ARG");
+      56          18 :   keys.add("atoms","POSITIONS1","the positions to use for the molecules specified using the first argument");
+      57          18 :   keys.add("atoms","POSITIONS2","the positions to use for the molecules specified using the second argument");
+      58           9 : }
+      59             : 
+      60           7 : TorsionsMatrix::TorsionsMatrix(const ActionOptions&ao):
+      61             :   Action(ao),
+      62           7 :   ActionWithMatrix(ao)
+      63             : {
+      64           7 :   if( getNumberOfArguments()!=2 ) error("should be two arguments to this action, a matrix and a vector");
+      65           7 :   if( getPntrToArgument(0)->getRank()!=2 || getPntrToArgument(0)->hasDerivatives() ) error("first argument to this action should be a matrix");
+      66           7 :   if( getPntrToArgument(1)->getRank()!=2 || getPntrToArgument(1)->hasDerivatives() ) error("second argument to this action should be a matrix");
+      67           7 :   if( getPntrToArgument(0)->getShape()[1]!=3 || getPntrToArgument(1)->getShape()[0]!=3 ) error("number of columns in first matrix and number of rows in second matrix should equal 3");
+      68             : 
+      69          14 :   std::vector<AtomNumber> atoms_a; parseAtomList("POSITIONS1", atoms_a );
+      70           7 :   if( atoms_a.size()!=getPntrToArgument(0)->getShape()[0] ) error("mismatch between number of atoms specified using POSITIONS1 and number of arguments in vector input");
+      71           7 :   log.printf("  using positions of these atoms for vectors in first matrix \n");
+      72         933 :   for(unsigned int i=0; i<atoms_a.size(); ++i) {
+      73         926 :     if ( (i+1) % 25 == 0 ) log.printf("  \n");
+      74         926 :     log.printf("  %d", atoms_a[i].serial());
+      75             :   }
+      76          14 :   log.printf("\n"); std::vector<AtomNumber> atoms_b; parseAtomList("POSITIONS2", atoms_b );
+      77           7 :   if( atoms_b.size()!=getPntrToArgument(1)->getShape()[1] ) error("mismatch between number of atoms specified using POSITIONS2 and number of arguments in vector input");
+      78           7 :   log.printf("  using positions of these atoms for vectors in second matrix \n");
+      79        1225 :   for(unsigned i=0; i<atoms_b.size(); ++i) {
+      80        1218 :     if ( (i+1) % 25 == 0 ) log.printf("  \n");
+      81        1218 :     log.printf("  %d", atoms_b[i].serial()); atoms_a.push_back( atoms_b[i] );
+      82             :   }
+      83           7 :   log.printf("\n"); requestAtoms( atoms_a, false );
+      84             : 
+      85           7 :   std::vector<unsigned> shape(2); shape[0]=getPntrToArgument(0)->getShape()[0]; shape[1]=getPntrToArgument(1)->getShape()[1];
+      86          14 :   addValue( shape ); setPeriodic("-pi","pi"); nderivatives = buildArgumentStore(0) + 3*getNumberOfAtoms() + 9;
+      87           7 :   std::string headstr=getFirstActionInChain()->getLabel();
+      88           7 :   stored_matrix1 = getPntrToArgument(0)->ignoreStoredValue( headstr );
+      89           7 :   stored_matrix2 = getPntrToArgument(1)->ignoreStoredValue( headstr );
+      90           7 : }
+      91             : 
+      92          10 : unsigned TorsionsMatrix::getNumberOfDerivatives() {
+      93          10 :   return nderivatives;
+      94             : }
+      95             : 
+      96           2 : void TorsionsMatrix::setupForTask( const unsigned& task_index, std::vector<unsigned>& indices, MultiValue& myvals ) const {
+      97           2 :   unsigned start_n = getPntrToArgument(0)->getShape()[0], size_v = getPntrToArgument(1)->getShape()[1];
+      98           2 :   if( indices.size()!=size_v+1 ) indices.resize( size_v+1 );
+      99           6 :   for(unsigned i=0; i<size_v; ++i) indices[i+1] = start_n + i;
+     100             :   myvals.setSplitIndex( size_v + 1 );
+     101           2 : }
+     102             : 
+     103     1240496 : void TorsionsMatrix::performTask( const std::string& controller, const unsigned& index1, const unsigned& index2, MultiValue& myvals ) const {
+     104     1240496 :   unsigned ostrn = getConstPntrToComponent(0)->getPositionInStream(), ind2=index2;
+     105     1240496 :   if( index2>=getPntrToArgument(0)->getShape()[0] ) ind2 = index2 - getPntrToArgument(0)->getShape()[0];
+     106             : 
+     107     1240496 :   Vector v1, v2, dv1, dv2, dconn;
+     108             :   // Compute the distance connecting the two centers
+     109     1240496 :   Vector conn=pbcDistance( getPosition(index1), getPosition(index2) );
+     110     2479668 :   if( conn.modulo2()<epsilon ) return;
+     111             : 
+     112             :   // Get the two vectors
+     113     4961624 :   for(unsigned i=0; i<3; ++i) {
+     114     3721218 :     v1[i] = getElementOfMatrixArgument( 0, index1, i, myvals );
+     115     3721218 :     v2[i] = getElementOfMatrixArgument( 1, i, ind2, myvals );
+     116             :   }
+     117             :   // Evaluate angle
+     118     1240406 :   Torsion t; double angle = t.compute( v1, conn, v2, dv1, dconn, dv2 );
+     119     1240406 :   myvals.addValue( ostrn, angle );
+     120             : 
+     121     1240406 :   if( doNotCalculateDerivatives() ) return;
+     122             : 
+     123             :   // Add the derivatives on the matrices
+     124        4936 :   for(unsigned i=0; i<3; ++i) {
+     125        3702 :     addDerivativeOnMatrixArgument( stored_matrix1, 0, 0, index1, i, dv1[i], myvals );
+     126        3702 :     addDerivativeOnMatrixArgument( stored_matrix2, 0, 1, i, ind2, dv2[i], myvals );
+     127             :   }
+     128             :   // And derivatives on positions
+     129        1234 :   unsigned narg_derivatives = getPntrToArgument(0)->getNumberOfValues() + getPntrToArgument(1)->getNumberOfValues();
+     130        4936 :   for(unsigned i=0; i<3; ++i) {
+     131        3702 :     myvals.addDerivative( ostrn, narg_derivatives + 3*index1+i, -dconn[i] ); myvals.addDerivative( ostrn, narg_derivatives + 3*index2+i, dconn[i] );
+     132        3702 :     myvals.updateIndex( ostrn, narg_derivatives + 3*index1+i ); myvals.updateIndex( ostrn, narg_derivatives + 3*index2+i );
+     133             :   }
+     134             :   //And virial
+     135        1234 :   Tensor vir( -extProduct( conn, dconn ) ); unsigned virbase = narg_derivatives + 3*getNumberOfAtoms();
+     136       16042 :   for(unsigned i=0; i<3; ++i) for(unsigned j=0; j<3; ++j ) { myvals.addDerivative( ostrn, virbase+3*i+j, vir(i,j) ); myvals.updateIndex( ostrn, virbase+3*i+j ); }
+     137             : }
+     138             : 
+     139        5366 : void TorsionsMatrix::runEndOfRowJobs( const unsigned& ival, const std::vector<unsigned> & indices, MultiValue& myvals ) const {
+     140        5366 :   if( doNotCalculateDerivatives() || !matrixChainContinues() ) return ;
+     141             : 
+     142         178 :   unsigned mat1s = 3*ival, ss = getPntrToArgument(1)->getShape()[1];
+     143         178 :   unsigned nmat = getConstPntrToComponent(0)->getPositionInMatrixStash(), nmat_ind = myvals.getNumberOfMatrixRowDerivatives( nmat );
+     144         178 :   unsigned narg_derivatives = getPntrToArgument(0)->getNumberOfValues() + getPntrToArgument(1)->getNumberOfValues();
+     145             :   std::vector<unsigned>& matrix_indices( myvals.getMatrixRowDerivativeIndices( nmat ) ); unsigned ntwo_atoms = myvals.getSplitIndex();
+     146         712 :   for(unsigned j=0; j<3; ++j) {
+     147         534 :     matrix_indices[nmat_ind] = mat1s + j; nmat_ind++;
+     148         534 :     matrix_indices[nmat_ind] = narg_derivatives + mat1s + j; nmat_ind++;
+     149        4242 :     for(unsigned i=1; i<ntwo_atoms; ++i) {
+     150        3708 :       unsigned ind2 = indices[i]; if( ind2>=getPntrToArgument(0)->getShape()[0] ) ind2 = indices[i] - getPntrToArgument(0)->getShape()[0];
+     151        3708 :       matrix_indices[nmat_ind] = arg_deriv_starts[1] + j*ss + ind2; nmat_ind++;
+     152        3708 :       matrix_indices[nmat_ind] = narg_derivatives + 3*indices[i] + j; nmat_ind++;
+     153             :     }
+     154             :   }
+     155        1780 :   unsigned base = narg_derivatives + 3*getNumberOfAtoms(); for(unsigned j=0; j<9; ++j) { matrix_indices[nmat_ind] = base + j; nmat_ind++; }
+     156             :   myvals.setNumberOfMatrixRowDerivatives( nmat, nmat_ind );
+     157             : }
+     158             : 
+     159             : }
+     160             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/TransposeMatrix.cpp.func-sort-c.html b/coverage/adjmat/TransposeMatrix.cpp.func-sort-c.html new file mode 100644 index 000000000000..77074aec73aa --- /dev/null +++ b/coverage/adjmat/TransposeMatrix.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/TransposeMatrix.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - TransposeMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:475388.7 %
Date:2024-04-19 12:12:35Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat15TransposeMatrixC2ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat15TransposeMatrixC1ERKNS_13ActionOptionsE162
_ZN4PLMD6adjmat15TransposeMatrix16registerKeywordsERNS_8KeywordsE164
_ZN4PLMD6adjmat15TransposeMatrix22getNumberOfDerivativesEv256
_ZN4PLMD6adjmat15TransposeMatrix5applyEv4144
_ZN4PLMD6adjmat15TransposeMatrix9calculateEv4225
_ZN4PLMD6adjmat15TransposeMatrix7prepareEv4821
_ZNK4PLMD6adjmat15TransposeMatrix23getForceOnMatrixElementERKjS3_4124572
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/TransposeMatrix.cpp.func.html b/coverage/adjmat/TransposeMatrix.cpp.func.html new file mode 100644 index 000000000000..956fcd9c0cf6 --- /dev/null +++ b/coverage/adjmat/TransposeMatrix.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/TransposeMatrix.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - TransposeMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:475388.7 %
Date:2024-04-19 12:12:35Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat15TransposeMatrix16registerKeywordsERNS_8KeywordsE164
_ZN4PLMD6adjmat15TransposeMatrix22getNumberOfDerivativesEv256
_ZN4PLMD6adjmat15TransposeMatrix5applyEv4144
_ZN4PLMD6adjmat15TransposeMatrix7prepareEv4821
_ZN4PLMD6adjmat15TransposeMatrix9calculateEv4225
_ZN4PLMD6adjmat15TransposeMatrixC1ERKNS_13ActionOptionsE162
_ZN4PLMD6adjmat15TransposeMatrixC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6adjmat15TransposeMatrix23getForceOnMatrixElementERKjS3_4124572
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/TransposeMatrix.cpp.gcov.html b/coverage/adjmat/TransposeMatrix.cpp.gcov.html new file mode 100644 index 000000000000..b4795a4d2a5f --- /dev/null +++ b/coverage/adjmat/TransposeMatrix.cpp.gcov.html @@ -0,0 +1,209 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/TransposeMatrix.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - TransposeMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:475388.7 %
Date:2024-04-19 12:12:35Functions:7887.5 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2014-2017 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "MatrixOperationBase.h"
+      23             : #include "core/ActionRegister.h"
+      24             : 
+      25             : //+PLUMEDOC MCOLVAR TRANSPOSE
+      26             : /*
+      27             : Calculate the transpose of a matrix
+      28             : 
+      29             : \par Examples
+      30             : 
+      31             : */
+      32             : //+ENDPLUMEDOC
+      33             : 
+      34             : namespace PLMD {
+      35             : namespace adjmat {
+      36             : 
+      37             : class TransposeMatrix : public MatrixOperationBase {
+      38             : public:
+      39             :   static void registerKeywords( Keywords& keys );
+      40             : /// Constructor
+      41             :   explicit TransposeMatrix(const ActionOptions&);
+      42             : ///
+      43         256 :   unsigned getNumberOfDerivatives() override { return 0; }
+      44             : ///
+      45             :   void prepare() override ;
+      46             : ///
+      47             :   void calculate() override ;
+      48             : ///
+      49             :   void apply() override ;
+      50             : ///
+      51             :   double getForceOnMatrixElement( const unsigned& jrow, const unsigned& krow ) const override;
+      52             : };
+      53             : 
+      54             : PLUMED_REGISTER_ACTION(TransposeMatrix,"TRANSPOSE")
+      55             : 
+      56         164 : void TransposeMatrix::registerKeywords( Keywords& keys ) {
+      57         164 :   MatrixOperationBase::registerKeywords( keys );
+      58         164 : }
+      59             : 
+      60         162 : TransposeMatrix::TransposeMatrix(const ActionOptions& ao):
+      61             :   Action(ao),
+      62         162 :   MatrixOperationBase(ao)
+      63             : {
+      64         162 :   if( getPntrToArgument(0)->isSymmetric() ) error("input matrix is symmetric.  Transposing will achieve nothing!");
+      65             :   std::vector<unsigned> shape;
+      66         162 :   if( getPntrToArgument(0)->getRank()==0 ) error("transposing a scalar?");
+      67         162 :   else if( getPntrToArgument(0)->getRank()==1 ) { shape.resize(2); shape[0]=1; shape[1]=getPntrToArgument(0)->getShape()[0]; }
+      68         145 :   else if( getPntrToArgument(0)->getShape()[0]==1 ) { shape.resize(1); shape[0] = getPntrToArgument(0)->getShape()[1]; }
+      69          84 :   else { shape.resize(2); shape[0]=getPntrToArgument(0)->getShape()[1]; shape[1]=getPntrToArgument(0)->getShape()[0]; }
+      70         162 :   addValue( shape ); setNotPeriodic(); getPntrToComponent(0)->buildDataStore();
+      71         162 :   if( shape.size()==2 ) getPntrToComponent(0)->reshapeMatrixStore( shape[1] );
+      72         162 : }
+      73             : 
+      74        4821 : void TransposeMatrix::prepare() {
+      75        4821 :   Value* myval = getPntrToComponent(0); Value* myarg = getPntrToArgument(0);
+      76        4821 :   if( myarg->getRank()==1 ) {
+      77         586 :     if( myval->getShape()[0]!=1 || myval->getShape()[1]!=myarg->getShape()[0] ) {
+      78           6 :       std::vector<unsigned> shape(2); shape[0] = 1; shape[1] = myarg->getShape()[0];
+      79           6 :       myval->setShape( shape ); myval->reshapeMatrixStore( shape[1] );
+      80             :     }
+      81        4235 :   } else if( myarg->getShape()[0]==1 ) {
+      82        2392 :     if( myval->getShape()[0]!=myarg->getShape()[1] ) { std::vector<unsigned> shape(1); shape[0] = myarg->getShape()[1]; myval->setShape( shape ); }
+      83        1843 :   } else if( myarg->getShape()[0]!=myval->getShape()[1] || myarg->getShape()[1]!=myval->getShape()[0] ) {
+      84          19 :     std::vector<unsigned> shape(2); shape[0] = myarg->getShape()[1]; shape[1] = myarg->getShape()[0];
+      85          19 :     myval->setShape( shape ); myval->reshapeMatrixStore( shape[1] );
+      86             :   }
+      87        4821 : }
+      88             : 
+      89        4225 : void TransposeMatrix::calculate() {
+      90             :   // Retrieve the non-zero pairs
+      91        4225 :   Value* myarg=getPntrToArgument(0); Value* myval=getPntrToComponent(0);
+      92        4225 :   if( myarg->getRank()<=1 || myval->getRank()==1 ) {
+      93        2389 :     if( myarg->getRank()<=1 && myval->getShape()[1]!=myarg->getShape()[0] ) {
+      94           0 :       std::vector<unsigned> shape( 2 ); shape[0] = 1; shape[1] = myarg->getShape()[0];
+      95           0 :       myval->setShape( shape ); myval->reshapeMatrixStore( shape[1] );
+      96        2389 :     } else if( myval->getRank()==1 && myval->getShape()[0]!=myarg->getShape()[1] ) {
+      97           0 :       std::vector<unsigned> shape( 1 ); shape[0] = myarg->getShape()[1];
+      98           0 :       myval->setShape( shape );
+      99             :     }
+     100        2389 :     unsigned nv=myarg->getNumberOfValues();
+     101       49015 :     for(unsigned i=0; i<nv; ++i) myval->set( i, myarg->get(i) );
+     102             :   } else {
+     103        1836 :     if( myarg->getShape()[0]!=myval->getShape()[1] || myarg->getShape()[1]!=myval->getShape()[0] ) {
+     104           0 :       std::vector<unsigned> shape( 2 ); shape[0] = myarg->getShape()[1]; shape[1] = myarg->getShape()[0];
+     105           0 :       myval->setShape( shape ); myval->reshapeMatrixStore( shape[1] );
+     106             :     }
+     107             :     std::vector<double> vals; std::vector<std::pair<unsigned,unsigned> > pairs;
+     108        1836 :     std::vector<unsigned> shape( myval->getShape() ); unsigned nedge=0; myarg->retrieveEdgeList( nedge, pairs, vals );
+     109     2758860 :     for(unsigned i=0; i<nedge; ++i) myval->set( pairs[i].second*shape[1] + pairs[i].first, vals[i] );
+     110             :   }
+     111        4225 : }
+     112             : 
+     113        4144 : void TransposeMatrix::apply() {
+     114        4144 :   if( doNotCalculateDerivatives() ) return;
+     115             : 
+     116             :   // Apply force on the matrix
+     117        1930 :   if( getPntrToComponent(0)->forcesWereAdded() ) {
+     118        1930 :     Value* myarg=getPntrToArgument(0); Value* myval=getPntrToComponent(0);
+     119        1930 :     if( myarg->getRank()<=1 || myval->getRank()==1 ) {
+     120         588 :       unsigned nv=myarg->getNumberOfValues();
+     121        2408 :       for(unsigned i=0; i<nv; ++i) myarg->addForce( i, myval->getForce(i) );
+     122        1342 :     } else MatrixOperationBase::apply();
+     123             :   }
+     124             : }
+     125             : 
+     126     4124572 : double TransposeMatrix::getForceOnMatrixElement( const unsigned& jrow, const unsigned& kcol ) const {
+     127     4124572 :   return getConstPntrToComponent(0)->getForce(kcol*getConstPntrToComponent(0)->getShape()[1]+jrow);
+     128             : }
+     129             : 
+     130             : 
+     131             : }
+     132             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/VStack.cpp.func-sort-c.html b/coverage/adjmat/VStack.cpp.func-sort-c.html new file mode 100644 index 000000000000..0e3655d04da2 --- /dev/null +++ b/coverage/adjmat/VStack.cpp.func-sort-c.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/VStack.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - VStack.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:6969100.0 %
Date:2024-04-19 12:12:35Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat6VStackC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6adjmat6VStack21getMatrixColumnTitlesERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EE18
_ZN4PLMD6adjmat6VStackC1ERKNS_13ActionOptionsE134
_ZN4PLMD6adjmat6VStack16registerKeywordsERNS_8KeywordsE136
_ZN4PLMD6adjmat6VStack22getNumberOfDerivativesEv294
_ZN4PLMD6adjmat6VStack7prepareEv3092
_ZNK4PLMD6adjmat6VStack12setupForTaskERKjRSt6vectorIjSaIjEERNS_10MultiValueE212918
_ZNK4PLMD6adjmat6VStack15runEndOfRowJobsERKjRKSt6vectorIjSaIjEERNS_10MultiValueE212918
_ZNK4PLMD6adjmat6VStack18getNumberOfColumnsEv1270493
_ZNK4PLMD6adjmat6VStack11performTaskERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjSB_RNS_10MultiValueE4070147
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/VStack.cpp.func.html b/coverage/adjmat/VStack.cpp.func.html new file mode 100644 index 000000000000..cd2c25210dca --- /dev/null +++ b/coverage/adjmat/VStack.cpp.func.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/VStack.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - VStack.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:6969100.0 %
Date:2024-04-19 12:12:35Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat6VStack16registerKeywordsERNS_8KeywordsE136
_ZN4PLMD6adjmat6VStack22getNumberOfDerivativesEv294
_ZN4PLMD6adjmat6VStack7prepareEv3092
_ZN4PLMD6adjmat6VStackC1ERKNS_13ActionOptionsE134
_ZN4PLMD6adjmat6VStackC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6adjmat6VStack11performTaskERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjSB_RNS_10MultiValueE4070147
_ZNK4PLMD6adjmat6VStack12setupForTaskERKjRSt6vectorIjSaIjEERNS_10MultiValueE212918
_ZNK4PLMD6adjmat6VStack15runEndOfRowJobsERKjRKSt6vectorIjSaIjEERNS_10MultiValueE212918
_ZNK4PLMD6adjmat6VStack18getNumberOfColumnsEv1270493
_ZNK4PLMD6adjmat6VStack21getMatrixColumnTitlesERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EE18
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/VStack.cpp.gcov.html b/coverage/adjmat/VStack.cpp.gcov.html new file mode 100644 index 000000000000..143cce93ec37 --- /dev/null +++ b/coverage/adjmat/VStack.cpp.gcov.html @@ -0,0 +1,238 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/VStack.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - VStack.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:6969100.0 %
Date:2024-04-19 12:12:35Functions:91090.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2014-2017 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "ActionWithMatrix.h"
+      23             : #include "core/ActionRegister.h"
+      24             : 
+      25             : //+PLUMEDOC MCOLVAR VSTACK
+      26             : /*
+      27             : Create a matrix by stacking vectors together
+      28             : 
+      29             : \par Examples
+      30             : 
+      31             : */
+      32             : //+ENDPLUMEDOC
+      33             : 
+      34             : namespace PLMD {
+      35             : namespace adjmat {
+      36             : 
+      37             : class VStack : public ActionWithMatrix {
+      38             : private:
+      39             :   std::vector<bool> stored;
+      40             : public:
+      41             :   static void registerKeywords( Keywords& keys );
+      42             : /// Constructor
+      43             :   explicit VStack(const ActionOptions&);
+      44             : /// Get the number of derivatives
+      45         294 :   unsigned getNumberOfDerivatives() override { return 0; }
+      46             : ///
+      47             :   void prepare() override ;
+      48             : ///
+      49     1270493 :   unsigned getNumberOfColumns() const override { return getNumberOfArguments(); }
+      50             : ///
+      51             :   void setupForTask( const unsigned& task_index, std::vector<unsigned>& indices, MultiValue& myvals ) const override ;
+      52             : ///
+      53             :   void performTask( const std::string& controller, const unsigned& index1, const unsigned& index2, MultiValue& myvals ) const override ;
+      54             : ///
+      55             :   void runEndOfRowJobs( const unsigned& ival, const std::vector<unsigned> & indices, MultiValue& myvals ) const override ;
+      56             : ///
+      57             :   void getMatrixColumnTitles( std::vector<std::string>& argnames ) const override ;
+      58             : };
+      59             : 
+      60             : PLUMED_REGISTER_ACTION(VStack,"VSTACK")
+      61             : 
+      62         136 : void VStack::registerKeywords( Keywords& keys ) {
+      63         136 :   ActionWithMatrix::registerKeywords( keys ); keys.use("ARG");
+      64         136 : }
+      65             : 
+      66         134 : VStack::VStack(const ActionOptions& ao):
+      67             :   Action(ao),
+      68         134 :   ActionWithMatrix(ao)
+      69             : {
+      70         134 :   if( getNumberOfArguments()==0 ) error("no arguments were specificed");
+      71         134 :   if( getPntrToArgument(0)->getRank()>1 ) error("all arguments should be vectors");
+      72             :   unsigned nvals=1; bool periodic=false; std::string smin, smax;
+      73         134 :   if( getPntrToArgument(0)->getRank()==1 ) nvals = getPntrToArgument(0)->getShape()[0];
+      74         134 :   if( getPntrToArgument(0)->isPeriodic() ) { periodic=true; getPntrToArgument(0)->getDomain( smin, smax ); }
+      75             : 
+      76        1213 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+      77        1079 :     if( getPntrToArgument(i)->getRank()>1 || (getPntrToArgument(i)->getRank()==1 && getPntrToArgument(i)->hasDerivatives()) ) error("all arguments should be vectors");
+      78        1079 :     if( getPntrToArgument(i)->getRank()==0 ) {
+      79          41 :       if( nvals!=1 ) error("all input vector should have same number of elements");
+      80        1038 :     } else if( getPntrToArgument(i)->getShape()[0]!=nvals ) error("all input vector should have same number of elements");
+      81        1079 :     if( periodic ) {
+      82          51 :       if( !getPntrToArgument(i)->isPeriodic() ) error("one argument is periodic but " + getPntrToArgument(i)->getName() + " is not periodic");
+      83          51 :       std::string tmin, tmax; getPntrToArgument(i)->getDomain( tmin, tmax );
+      84          51 :       if( tmin!=smin || tmax!=smax ) error("domain of argument " + getPntrToArgument(i)->getName() + " is different from domain for all other arguments");
+      85        1028 :     } else if( getPntrToArgument(i)->isPeriodic() ) error("one argument is not periodic but " + getPntrToArgument(i)->getName() + " is periodic");
+      86             :   }
+      87             :   // And create a value to hold the matrix
+      88         134 :   std::vector<unsigned> shape(2); shape[0]=nvals; shape[1]=getNumberOfArguments(); addValue( shape );
+      89         134 :   if( periodic ) setPeriodic( smin, smax ); else setNotPeriodic();
+      90             :   // And store this value
+      91         134 :   getPntrToComponent(0)->buildDataStore(); getPntrToComponent(0)->reshapeMatrixStore( shape[1] );
+      92             :   // Setup everything so we can build the store
+      93         134 :   done_in_chain=true; ActionWithVector* av=dynamic_cast<ActionWithVector*>( getPntrToArgument(0)->getPntrToAction() );
+      94         134 :   if( av ) {
+      95          98 :     const ActionWithVector* head0 = av->getFirstActionInChain();
+      96         993 :     for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+      97         926 :       ActionWithVector* avv=dynamic_cast<ActionWithVector*>( getPntrToArgument(i)->getPntrToAction() );
+      98         926 :       if( !avv ) continue;
+      99         922 :       if( head0!=avv->getFirstActionInChain() ) { done_in_chain=false; break; }
+     100             :     }
+     101          36 :   } else done_in_chain=false;
+     102         134 :   unsigned nder = buildArgumentStore(0);
+     103             :   // This checks which values have been stored
+     104         134 :   stored.resize( getNumberOfArguments() ); std::string headstr=getFirstActionInChain()->getLabel();
+     105        1213 :   for(unsigned i=0; i<stored.size(); ++i) stored[i] = getPntrToArgument(i)->ignoreStoredValue( headstr );
+     106         134 : }
+     107             : 
+     108          18 : void VStack::getMatrixColumnTitles( std::vector<std::string>& argnames ) const {
+     109          45 :   for(unsigned j=0; j<getNumberOfArguments(); ++j) {
+     110          27 :     if( (getPntrToArgument(j)->getPntrToAction())->getName()=="COLLECT" ) {
+     111          17 :       ActionWithArguments* aa = dynamic_cast<ActionWithArguments*>( getPntrToArgument(j)->getPntrToAction() );
+     112          17 :       plumed_assert( aa && aa->getNumberOfArguments()==1 ); argnames.push_back( (aa->getPntrToArgument(0))->getName() );
+     113          10 :     } else argnames.push_back( getPntrToArgument(j)->getName() );
+     114             :   }
+     115          18 : }
+     116             : 
+     117        3092 : void VStack::prepare() {
+     118        3092 :   ActionWithVector::prepare();
+     119        3092 :   if( getPntrToArgument(0)->getRank()==0 || getPntrToArgument(0)->getShape()[0]==getPntrToComponent(0)->getShape()[0] ) return ;
+     120          14 :   std::vector<unsigned> shape(2); shape[0] = getPntrToArgument(0)->getShape()[0]; shape[1] = getNumberOfArguments();
+     121          14 :   getPntrToComponent(0)->setShape(shape); getPntrToComponent(0)->reshapeMatrixStore( shape[1] );
+     122             : }
+     123             : 
+     124      212918 : void VStack::setupForTask( const unsigned& task_index, std::vector<unsigned>& indices, MultiValue& myvals ) const {
+     125      212918 :   unsigned nargs = getNumberOfArguments(); unsigned nvals = getConstPntrToComponent(0)->getShape()[0];
+     126      212918 :   if( indices.size()!=nargs+1 ) indices.resize( nargs+1 );
+     127     4283065 :   for(unsigned i=0; i<nargs; ++i) indices[i+1] = nvals + i;
+     128             :   myvals.setSplitIndex( nargs + 1 );
+     129      212918 : }
+     130             : 
+     131     4070147 : void VStack::performTask( const std::string& controller, const unsigned& index1, const unsigned& index2, MultiValue& myvals ) const {
+     132     4070147 :   unsigned ind2 = index2; if( index2>=getConstPntrToComponent(0)->getShape()[0] ) ind2 = index2 - getConstPntrToComponent(0)->getShape()[0];
+     133     4070147 :   myvals.addValue( getConstPntrToComponent(0)->getPositionInStream(), getArgumentElement( ind2, index1, myvals ) );
+     134             : 
+     135     4070147 :   if( doNotCalculateDerivatives() ) return;
+     136     3692599 :   addDerivativeOnVectorArgument( stored[ind2], 0, ind2, index1, 1.0, myvals );
+     137             : }
+     138             : 
+     139      212918 : void VStack::runEndOfRowJobs( const unsigned& ival, const std::vector<unsigned> & indices, MultiValue& myvals ) const {
+     140      212918 :   if( doNotCalculateDerivatives() || !matrixChainContinues() ) return ;
+     141             : 
+     142           3 :   unsigned nmat = getConstPntrToComponent(0)->getPositionInMatrixStash(), nmat_ind = myvals.getNumberOfMatrixRowDerivatives( nmat );
+     143             :   std::vector<unsigned>& matrix_indices( myvals.getMatrixRowDerivativeIndices( nmat ) );
+     144           3 :   plumed_assert( nmat_ind<matrix_indices.size() );
+     145          12 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     146           9 :     bool found=false; ActionWithValue* iav = getPntrToArgument(i)->getPntrToAction();
+     147           9 :     for(unsigned j=0; j<i; ++j) {
+     148           6 :       if( iav==getPntrToArgument(j)->getPntrToAction() ) { found=true; break; }
+     149             :     }
+     150           9 :     if( found ) continue ;
+     151             : 
+     152             :     unsigned istrn = getPntrToArgument(i)->getPositionInStream();
+     153          48 :     for(unsigned k=0; k<myvals.getNumberActive(istrn); ++k) {
+     154          45 :       matrix_indices[nmat_ind] = myvals.getActiveIndex(istrn,k); nmat_ind++;
+     155             :     }
+     156             :   }
+     157             :   myvals.setNumberOfMatrixRowDerivatives( nmat, nmat_ind );
+     158             : }
+     159             : 
+     160             : }
+     161             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/Voronoi.cpp.func-sort-c.html b/coverage/adjmat/Voronoi.cpp.func-sort-c.html new file mode 100644 index 000000000000..3bf22c3b512f --- /dev/null +++ b/coverage/adjmat/Voronoi.cpp.func-sort-c.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/Voronoi.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - Voronoi.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:252792.6 %
Date:2024-04-19 12:12:35Functions:71070.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat7Voronoi22getNumberOfDerivativesEv0
_ZN4PLMD6adjmat7VoronoiC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6adjmat7Voronoi11performTaskERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjSB_RNS_10MultiValueE0
_ZN4PLMD6adjmat7Voronoi7prepareEv6
_ZN4PLMD6adjmat7VoronoiC1ERKNS_13ActionOptionsE6
_ZN4PLMD6adjmat7Voronoi16registerKeywordsERNS_8KeywordsE8
_ZNK4PLMD6adjmat7Voronoi18getNumberOfColumnsEv12
_ZNK4PLMD6adjmat7Voronoi12setupForTaskERKjRSt6vectorIjSaIjEERNS_10MultiValueE1036
_ZNK4PLMD6adjmat7Voronoi15runEndOfRowJobsERKjRKSt6vectorIjSaIjEERNS_10MultiValueE1036
_ZNK4PLMD6adjmat7Voronoi17gatherStoredValueERKjS3_RKNS_10MultiValueES3_RSt6vectorIdSaIdEE1036
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/Voronoi.cpp.func.html b/coverage/adjmat/Voronoi.cpp.func.html new file mode 100644 index 000000000000..b60c9c11a64e --- /dev/null +++ b/coverage/adjmat/Voronoi.cpp.func.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/Voronoi.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - Voronoi.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:252792.6 %
Date:2024-04-19 12:12:35Functions:71070.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat7Voronoi16registerKeywordsERNS_8KeywordsE8
_ZN4PLMD6adjmat7Voronoi22getNumberOfDerivativesEv0
_ZN4PLMD6adjmat7Voronoi7prepareEv6
_ZN4PLMD6adjmat7VoronoiC1ERKNS_13ActionOptionsE6
_ZN4PLMD6adjmat7VoronoiC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6adjmat7Voronoi11performTaskERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjSB_RNS_10MultiValueE0
_ZNK4PLMD6adjmat7Voronoi12setupForTaskERKjRSt6vectorIjSaIjEERNS_10MultiValueE1036
_ZNK4PLMD6adjmat7Voronoi15runEndOfRowJobsERKjRKSt6vectorIjSaIjEERNS_10MultiValueE1036
_ZNK4PLMD6adjmat7Voronoi17gatherStoredValueERKjS3_RKNS_10MultiValueES3_RSt6vectorIdSaIdEE1036
_ZNK4PLMD6adjmat7Voronoi18getNumberOfColumnsEv12
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/Voronoi.cpp.gcov.html b/coverage/adjmat/Voronoi.cpp.gcov.html new file mode 100644 index 000000000000..2719770065c6 --- /dev/null +++ b/coverage/adjmat/Voronoi.cpp.gcov.html @@ -0,0 +1,162 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/Voronoi.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - Voronoi.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:252792.6 %
Date:2024-04-19 12:12:35Functions:71070.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 "ActionWithMatrix.h"
+      23             : #include "core/ActionRegister.h"
+      24             : 
+      25             : //+PLUMEDOC MCOLVAR VORONOI
+      26             : /*
+      27             : Do a voronoi analysis
+      28             : 
+      29             : \par Examples
+      30             : 
+      31             : */
+      32             : //+ENDPLUMEDOC
+      33             : 
+      34             : namespace PLMD {
+      35             : namespace adjmat {
+      36             : 
+      37             : class Voronoi : public ActionWithMatrix {
+      38             : public:
+      39             :   static void registerKeywords( Keywords& keys );
+      40             :   explicit Voronoi(const ActionOptions&);
+      41             :   void prepare() override ;
+      42           0 :   unsigned getNumberOfDerivatives() override { return 0; }
+      43          12 :   unsigned getNumberOfColumns() const override { return getConstPntrToComponent(0)->getShape()[1]; }
+      44        1036 :   void setupForTask( const unsigned& task_index, std::vector<unsigned>& indices, MultiValue& myvals ) const override {}
+      45           0 :   void performTask( const std::string& controller, const unsigned& index1, const unsigned& index2, MultiValue& myvals ) const override {}
+      46        1036 :   void runEndOfRowJobs( const unsigned& ival, const std::vector<unsigned> & indices, MultiValue& myvals ) const override {}
+      47             :   void gatherStoredValue( const unsigned& valindex, const unsigned& code, const MultiValue& myvals,
+      48             :                           const unsigned& bufstart, std::vector<double>& buffer ) const override ;
+      49             : };
+      50             : 
+      51             : PLUMED_REGISTER_ACTION(Voronoi,"VORONOI")
+      52             : 
+      53           8 : void Voronoi::registerKeywords( Keywords& keys ) {
+      54           8 :   ActionWithMatrix::registerKeywords(keys); keys.use("ARG");
+      55           8 : }
+      56             : 
+      57           6 : Voronoi::Voronoi(const ActionOptions&ao):
+      58             :   Action(ao),
+      59           6 :   ActionWithMatrix(ao)
+      60             : {
+      61           6 :   if( getNumberOfArguments()!=1 ) error("should be one arguments to this action, a matrix");
+      62           6 :   if( getPntrToArgument(0)->getRank()!=2 || getPntrToArgument(0)->hasDerivatives() ) error("argument to this action should be a matrix");
+      63           6 :   if( getPntrToArgument(0)->getShape()[1]>getPntrToArgument(0)->getShape()[0] ) warning("would expect number of columns in matrix to exceed number of rows");
+      64           6 :   getPntrToArgument(0)->buildDataStore(); std::vector<unsigned> shape( getPntrToArgument(0)->getShape() );
+      65           6 :   addValue( shape ); setNotPeriodic(); getPntrToComponent(0)->buildDataStore();
+      66           6 : }
+      67             : 
+      68           6 : void Voronoi::prepare() {
+      69           6 :   Value* myval = getPntrToComponent(0);
+      70           6 :   if( myval->getShape()[0]==getPntrToArgument(0)->getShape()[0] && myval->getShape()[1]==getPntrToArgument(0)->getShape()[1] ) return;
+      71           6 :   std::vector<unsigned> shape( getPntrToArgument(0)->getShape() ); myval->setShape(shape);
+      72             : }
+      73             : 
+      74        1036 : void Voronoi::gatherStoredValue( const unsigned& valindex, const unsigned& code, const MultiValue& myvals,
+      75             :                                  const unsigned& bufstart, std::vector<double>& buffer ) const {
+      76        1036 :   Value* arg0 = getPntrToArgument(0); unsigned nv = 0; std::size_t cc=code; double minmax = arg0->get( cc*arg0->getShape()[1] );
+      77      251175 :   for(unsigned i=0; i<arg0->getShape()[1]; ++i) {
+      78      250139 :     double value = arg0->get( code*arg0->getShape()[1] + i );
+      79      250139 :     if( value<minmax ) { minmax = value; nv = i; }
+      80             :   }
+      81        1036 :   buffer[bufstart + code*arg0->getShape()[1] + nv] = 1;
+      82        1036 : }
+      83             : 
+      84             : }
+      85             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/index-sort-f.html b/coverage/adjmat/index-sort-f.html new file mode 100644 index 000000000000..75c791732502 --- /dev/null +++ b/coverage/adjmat/index-sort-f.html @@ -0,0 +1,344 @@ + + + + + + + + LCOV - plumed test coverage - adjmat + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmatHitTotalCoverage
Test:plumed test coverageLines:1582165995.4 %
Date:2024-04-19 12:12:35Functions:22628579.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Determinent.cpp +
40.0%40.0%
+
40.0 %4 / 1033.3 %1 / 3
InvertMatrix.cpp +
84.6%84.6%
+
84.6 %22 / 2657.1 %4 / 7
Neighbors.cpp +
84.5%84.5%
+
84.5 %49 / 5860.0 %6 / 10
Sprint.cpp +
100.0%
+
100.0 %38 / 3866.7 %2 / 3
ContactMatrixShortcut.cpp +
88.2%88.2%
+
88.2 %45 / 5166.7 %2 / 3
CovarianceMatrix.cpp +
100.0%
+
100.0 %26 / 2666.7 %2 / 3
Bridge.cpp +
100.0%
+
100.0 %19 / 1966.7 %2 / 3
Voronoi.cpp +
92.6%92.6%
+
92.6 %25 / 2770.0 %7 / 10
DistanceMatrix.cpp +
100.0%
+
100.0 %21 / 2175.0 %3 / 4
HbondMatrix.cpp +
100.0%
+
100.0 %41 / 4175.0 %3 / 4
BridgeMatrix.cpp +
78.6%78.6%
+
78.6 %33 / 4275.0 %3 / 4
TopologyMatrix.cpp +
100.0%
+
100.0 %140 / 14075.0 %3 / 4
TorsionsMatrix.cpp +
98.6%98.6%
+
98.6 %71 / 7275.0 %6 / 8
FunctionOfMatrix.h +
92.3%92.3%
+
92.3 %191 / 20778.7 %85 / 108
MatrixOperationBase.cpp +
90.3%90.3%
+
90.3 %28 / 3180.0 %4 / 5
ContactMatrix.cpp +
100.0%
+
100.0 %32 / 3280.0 %4 / 5
MatrixTimesMatrix.cpp +
88.7%88.7%
+
88.7 %63 / 7180.0 %8 / 10
MatrixTimesVector.cpp +
96.8%96.8%
+
96.8 %90 / 9381.8 %9 / 11
DiagonalizeMatrix.cpp +
100.0%
+
100.0 %57 / 5785.7 %6 / 7
ActionWithMatrix.cpp +
100.0%
+
100.0 %132 / 13286.4 %19 / 22
TransposeMatrix.cpp +
88.7%88.7%
+
88.7 %47 / 5387.5 %7 / 8
OuterProduct.cpp +
94.7%94.7%
+
94.7 %71 / 7588.9 %8 / 9
VStack.cpp +
100.0%
+
100.0 %69 / 6990.0 %9 / 10
AdjacencyMatrixBase.cpp +
100.0%
+
100.0 %211 / 21192.9 %13 / 14
AdjacencyMatrixBase.h +
100.0%
+
100.0 %30 / 30100.0 %4 / 4
ActionWithMatrix.h +
100.0%
+
100.0 %27 / 27100.0 %6 / 6
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/index-sort-l.html b/coverage/adjmat/index-sort-l.html new file mode 100644 index 000000000000..a2e1bef40725 --- /dev/null +++ b/coverage/adjmat/index-sort-l.html @@ -0,0 +1,344 @@ + + + + + + + + LCOV - plumed test coverage - adjmat + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmatHitTotalCoverage
Test:plumed test coverageLines:1582165995.4 %
Date:2024-04-19 12:12:35Functions:22628579.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Determinent.cpp +
40.0%40.0%
+
40.0 %4 / 1033.3 %1 / 3
BridgeMatrix.cpp +
78.6%78.6%
+
78.6 %33 / 4275.0 %3 / 4
Neighbors.cpp +
84.5%84.5%
+
84.5 %49 / 5860.0 %6 / 10
InvertMatrix.cpp +
84.6%84.6%
+
84.6 %22 / 2657.1 %4 / 7
ContactMatrixShortcut.cpp +
88.2%88.2%
+
88.2 %45 / 5166.7 %2 / 3
TransposeMatrix.cpp +
88.7%88.7%
+
88.7 %47 / 5387.5 %7 / 8
MatrixTimesMatrix.cpp +
88.7%88.7%
+
88.7 %63 / 7180.0 %8 / 10
MatrixOperationBase.cpp +
90.3%90.3%
+
90.3 %28 / 3180.0 %4 / 5
FunctionOfMatrix.h +
92.3%92.3%
+
92.3 %191 / 20778.7 %85 / 108
Voronoi.cpp +
92.6%92.6%
+
92.6 %25 / 2770.0 %7 / 10
OuterProduct.cpp +
94.7%94.7%
+
94.7 %71 / 7588.9 %8 / 9
MatrixTimesVector.cpp +
96.8%96.8%
+
96.8 %90 / 9381.8 %9 / 11
TorsionsMatrix.cpp +
98.6%98.6%
+
98.6 %71 / 7275.0 %6 / 8
Bridge.cpp +
100.0%
+
100.0 %19 / 1966.7 %2 / 3
DistanceMatrix.cpp +
100.0%
+
100.0 %21 / 2175.0 %3 / 4
CovarianceMatrix.cpp +
100.0%
+
100.0 %26 / 2666.7 %2 / 3
ActionWithMatrix.h +
100.0%
+
100.0 %27 / 27100.0 %6 / 6
AdjacencyMatrixBase.h +
100.0%
+
100.0 %30 / 30100.0 %4 / 4
ContactMatrix.cpp +
100.0%
+
100.0 %32 / 3280.0 %4 / 5
Sprint.cpp +
100.0%
+
100.0 %38 / 3866.7 %2 / 3
HbondMatrix.cpp +
100.0%
+
100.0 %41 / 4175.0 %3 / 4
DiagonalizeMatrix.cpp +
100.0%
+
100.0 %57 / 5785.7 %6 / 7
VStack.cpp +
100.0%
+
100.0 %69 / 6990.0 %9 / 10
ActionWithMatrix.cpp +
100.0%
+
100.0 %132 / 13286.4 %19 / 22
TopologyMatrix.cpp +
100.0%
+
100.0 %140 / 14075.0 %3 / 4
AdjacencyMatrixBase.cpp +
100.0%
+
100.0 %211 / 21192.9 %13 / 14
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/index.html b/coverage/adjmat/index.html new file mode 100644 index 000000000000..8b584967e886 --- /dev/null +++ b/coverage/adjmat/index.html @@ -0,0 +1,344 @@ + + + + + + + + LCOV - plumed test coverage - adjmat + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmatHitTotalCoverage
Test:plumed test coverageLines:1582165995.4 %
Date:2024-04-19 12:12:35Functions:22628579.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
ActionWithMatrix.cpp +
100.0%
+
100.0 %132 / 13286.4 %19 / 22
ActionWithMatrix.h +
100.0%
+
100.0 %27 / 27100.0 %6 / 6
AdjacencyMatrixBase.cpp +
100.0%
+
100.0 %211 / 21192.9 %13 / 14
AdjacencyMatrixBase.h +
100.0%
+
100.0 %30 / 30100.0 %4 / 4
Bridge.cpp +
100.0%
+
100.0 %19 / 1966.7 %2 / 3
BridgeMatrix.cpp +
78.6%78.6%
+
78.6 %33 / 4275.0 %3 / 4
ContactMatrix.cpp +
100.0%
+
100.0 %32 / 3280.0 %4 / 5
ContactMatrixShortcut.cpp +
88.2%88.2%
+
88.2 %45 / 5166.7 %2 / 3
CovarianceMatrix.cpp +
100.0%
+
100.0 %26 / 2666.7 %2 / 3
Determinent.cpp +
40.0%40.0%
+
40.0 %4 / 1033.3 %1 / 3
DiagonalizeMatrix.cpp +
100.0%
+
100.0 %57 / 5785.7 %6 / 7
DistanceMatrix.cpp +
100.0%
+
100.0 %21 / 2175.0 %3 / 4
FunctionOfMatrix.h +
92.3%92.3%
+
92.3 %191 / 20778.7 %85 / 108
HbondMatrix.cpp +
100.0%
+
100.0 %41 / 4175.0 %3 / 4
InvertMatrix.cpp +
84.6%84.6%
+
84.6 %22 / 2657.1 %4 / 7
MatrixOperationBase.cpp +
90.3%90.3%
+
90.3 %28 / 3180.0 %4 / 5
MatrixTimesMatrix.cpp +
88.7%88.7%
+
88.7 %63 / 7180.0 %8 / 10
MatrixTimesVector.cpp +
96.8%96.8%
+
96.8 %90 / 9381.8 %9 / 11
Neighbors.cpp +
84.5%84.5%
+
84.5 %49 / 5860.0 %6 / 10
OuterProduct.cpp +
94.7%94.7%
+
94.7 %71 / 7588.9 %8 / 9
Sprint.cpp +
100.0%
+
100.0 %38 / 3866.7 %2 / 3
TopologyMatrix.cpp +
100.0%
+
100.0 %140 / 14075.0 %3 / 4
TorsionsMatrix.cpp +
98.6%98.6%
+
98.6 %71 / 7275.0 %6 / 8
TransposeMatrix.cpp +
88.7%88.7%
+
88.7 %47 / 5387.5 %7 / 8
VStack.cpp +
100.0%
+
100.0 %69 / 6990.0 %9 / 10
Voronoi.cpp +
92.6%92.6%
+
92.6 %25 / 2770.0 %7 / 10
+
+
+ + + + +
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/Accumulate.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - Accumulate.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:384095.0 %
Date:2024-04-19 12:12:35Functions:8988.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis10AccumulateC2ERKNS_13ActionOptionsE0
_ZN4PLMD8analysis10Accumulate22getNumberOfDerivativesEv36
_ZN4PLMD8analysis10AccumulateC1ERKNS_13ActionOptionsE63
_ZN4PLMD8analysis10Accumulate16registerKeywordsERNS_8KeywordsE65
_ZN4PLMD8analysis10Accumulate23calculateConstantValuesERKb126
_ZN4PLMD8analysis10Accumulate6updateEv2324
_ZN4PLMD8analysis10Accumulate5applyEv2328
_ZN4PLMD8analysis10Accumulate9calculateEv2328
_ZN4PLMD8analysis10Accumulate17calculateOnUpdateEv4778
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/Accumulate.cpp.func.html b/coverage/analysis/Accumulate.cpp.func.html new file mode 100644 index 000000000000..996685e94990 --- /dev/null +++ b/coverage/analysis/Accumulate.cpp.func.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - analysis/Accumulate.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - Accumulate.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:384095.0 %
Date:2024-04-19 12:12:35Functions:8988.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis10Accumulate16registerKeywordsERNS_8KeywordsE65
_ZN4PLMD8analysis10Accumulate17calculateOnUpdateEv4778
_ZN4PLMD8analysis10Accumulate22getNumberOfDerivativesEv36
_ZN4PLMD8analysis10Accumulate23calculateConstantValuesERKb126
_ZN4PLMD8analysis10Accumulate5applyEv2328
_ZN4PLMD8analysis10Accumulate6updateEv2324
_ZN4PLMD8analysis10Accumulate9calculateEv2328
_ZN4PLMD8analysis10AccumulateC1ERKNS_13ActionOptionsE63
_ZN4PLMD8analysis10AccumulateC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/Accumulate.cpp.gcov.html b/coverage/analysis/Accumulate.cpp.gcov.html new file mode 100644 index 000000000000..4cb05cab8bf1 --- /dev/null +++ b/coverage/analysis/Accumulate.cpp.gcov.html @@ -0,0 +1,197 @@ + + + + + + + + LCOV - plumed test coverage - analysis/Accumulate.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - Accumulate.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:384095.0 %
Date:2024-04-19 12:12:35Functions: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/ActionWithValue.h"
+      23             : #include "core/ActionWithArguments.h"
+      24             : #include "core/ActionPilot.h"
+      25             : #include "core/ActionRegister.h"
+      26             : #include "core/PlumedMain.h"
+      27             : #include "core/ActionSet.h"
+      28             : #include "gridtools/ActionWithGrid.h"
+      29             : 
+      30             : //+PLUMEDOC GRIDCALC ACCUMULATE
+      31             : /*
+      32             : Sum the elements of this value over the course of the trajectory
+      33             : 
+      34             : \par Examples
+      35             : 
+      36             : */
+      37             : //+ENDPLUMEDOC
+      38             : 
+      39             : namespace PLMD {
+      40             : namespace analysis {
+      41             : 
+      42             : class Accumulate :
+      43             :   public ActionWithValue,
+      44             :   public ActionWithArguments,
+      45             :   public ActionPilot
+      46             : {
+      47             : private:
+      48             :   bool clearnextstep;
+      49             :   unsigned clearstride;
+      50             : public:
+      51             :   static void registerKeywords( Keywords& keys );
+      52             :   Accumulate( const ActionOptions& );
+      53             :   unsigned getNumberOfDerivatives();
+      54        4778 :   bool calculateOnUpdate() override { return false; }
+      55         126 :   bool calculateConstantValues( const bool& have_atoms ) override { return false; }
+      56        2328 :   void calculate() override {}
+      57        2328 :   void apply() override {}
+      58             :   void update() override ;
+      59             : };
+      60             : 
+      61             : PLUMED_REGISTER_ACTION(Accumulate,"ACCUMULATE")
+      62             : 
+      63          65 : void Accumulate::registerKeywords( Keywords& keys ) {
+      64          65 :   Action::registerKeywords( keys ); ActionWithValue::registerKeywords( keys );
+      65          65 :   ActionWithArguments::registerKeywords( keys ); ActionPilot::registerKeywords( keys );
+      66         195 :   keys.use("ARG"); keys.use("UPDATE_FROM"); keys.use("UPDATE_UNTIL");
+      67         130 :   keys.add("compulsory","STRIDE","1","the frequency with which the data should be collected and added to the quantity being averaged");
+      68         130 :   keys.add("compulsory","CLEAR","0","the frequency with which to clear all the accumulated data.  The default value "
+      69             :            "of 0 implies that all the data will be used and that the grid will never be cleared");
+      70          65 : }
+      71             : 
+      72          63 : Accumulate::Accumulate( const ActionOptions& ao ):
+      73             :   Action(ao),
+      74             :   ActionWithValue(ao),
+      75             :   ActionWithArguments(ao),
+      76             :   ActionPilot(ao),
+      77          63 :   clearnextstep(true)
+      78             : {
+      79          63 :   if( getNumberOfArguments()!=1 ) error("there should only be one argument to this action");
+      80          63 :   if( !getPntrToArgument(0)->hasDerivatives() && getPntrToArgument(0)->getRank()!=0 ) error("input to the accumulate action should be a scalar or a grid");
+      81             : 
+      82          63 :   parse("CLEAR",clearstride);
+      83          63 :   if( clearstride>0 ) {
+      84          11 :     if( clearstride%getStride()!=0 ) error("CLEAR parameter must be a multiple of STRIDE");
+      85          11 :     log.printf("  clearing average every %u steps \n",clearstride);
+      86             :   }
+      87          63 :   std::vector<unsigned> shape( getPntrToArgument(0)->getShape() );
+      88          63 :   addValueWithDerivatives( shape ); setNotPeriodic();
+      89          63 :   if( getPntrToArgument(0)->isPeriodic() ) error("you cannot accumulate a periodic quantity");
+      90          63 : }
+      91             : 
+      92          36 : unsigned Accumulate::getNumberOfDerivatives() {
+      93          36 :   if( getPntrToArgument(0)->getRank()>0 ) return getPntrToArgument(0)->getNumberOfGridDerivatives();
+      94           0 :   return getPntrToArgument(0)->getNumberOfDerivatives();
+      95             : }
+      96             : 
+      97        2324 : void Accumulate::update() {
+      98        2324 :   if( clearnextstep ) {
+      99         140 :     if( getPntrToComponent(0)->getNumberOfValues()!=getPntrToArgument(0)->getNumberOfValues() ) {
+     100           0 :       getPntrToComponent(0)->setShape( getPntrToArgument(0)->getShape() );
+     101             :     }
+     102          70 :     clearnextstep=false; getPntrToComponent(0)->set(0,0.0); getPntrToComponent(0)->clearDerivatives(true);
+     103             :   }
+     104        2324 :   if( getStep()==0 ) return;
+     105             : 
+     106        2262 :   Value* myarg=getPntrToArgument(0); Value* myout = getPntrToComponent(0);
+     107        2262 :   if( getPntrToArgument(0)->getRank()>0 ) {
+     108         118 :     unsigned nvals = myarg->getNumberOfValues(), nder = myarg->getNumberOfGridDerivatives();
+     109      270581 :     for(unsigned i=0; i<nvals; ++i) {
+     110      270463 :       myout->set( i, myout->get(i) + myarg->get(i) );
+     111     1353300 :       for(unsigned j=0; j<nder; ++j) myout->addGridDerivatives( i, j, myarg->getGridDerivative( i, j ) );
+     112             :     }
+     113        2144 :   } else getPntrToComponent(0)->add( getPntrToArgument(0)->get() );
+     114             : 
+     115             :   // Clear if required
+     116        2262 :   if( clearstride>0 && getStep()%clearstride==0 ) clearnextstep=true;
+     117             : }
+     118             : 
+     119             : }
+     120             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/Average.cpp.func-sort-c.html b/coverage/analysis/Average.cpp.func-sort-c.html new file mode 100644 index 000000000000..4fd54c3463b7 --- /dev/null +++ b/coverage/analysis/Average.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + 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:3030100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis7AverageC2ERKNS_13ActionOptionsE0
_ZN4PLMD8analysis7AverageC1ERKNS_13ActionOptionsE4
_ZN4PLMD8analysis7Average16registerKeywordsERNS_8KeywordsE6
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/Average.cpp.func.html b/coverage/analysis/Average.cpp.func.html new file mode 100644 index 000000000000..6bc1473ef50a --- /dev/null +++ b/coverage/analysis/Average.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + 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:3030100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis7Average16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD8analysis7AverageC1ERKNS_13ActionOptionsE4
_ZN4PLMD8analysis7AverageC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/Average.cpp.gcov.html b/coverage/analysis/Average.cpp.gcov.html new file mode 100644 index 000000000000..d23d1d7d17e4 --- /dev/null +++ b/coverage/analysis/Average.cpp.gcov.html @@ -0,0 +1,218 @@ + + + + + + + + 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:3030100.0 %
Date:2024-04-19 12:12:35Functions: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 "core/ActionShortcut.h"
+      23             : #include "core/ActionWithArguments.h"
+      24             : #include "core/PlumedMain.h"
+      25             : #include "core/ActionRegister.h"
+      26             : 
+      27             : //+PLUMEDOC GRIDCALC AVERAGE
+      28             : /*
+      29             : Calculate the ensemble average of a collective variable
+      30             : 
+      31             : The ensemble average for a non-periodic, collective variable, \f$s\f$ is given by the following expression:
+      32             : 
+      33             : \f[
+      34             : \langle s \rangle = \frac{ \sum_{t'=0}^t w(t') s(t') }{ \sum_{t'=0}^t w(t') }
+      35             : \f]
+      36             : 
+      37             : Here the sum runs over a the trajectory and \f$s(t')\f$ is used to denote the value of the collective variable
+      38             : at time \f$t'\f$.  The final quantity evaluated is a weighted
+      39             : average as the weights, \f$w(t')\f$, allow us to negate the effect any bias might have on the region of phase space
+      40             : sampled by the system.  This is discussed in the section of the manual on \ref Analysis.
+      41             : 
+      42             : 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:
+      43             : 
+      44             : \f[
+      45             : \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]
+      46             : \f]
+      47             : 
+      48             : \par Examples
+      49             : 
+      50             : The following example calculates the ensemble average for the distance between atoms 1 and 2
+      51             : and output this to a file called COLVAR.  In this example it is assumed that no bias is acting
+      52             : on the system and that the weights, \f$w(t')\f$ in the formulas above can thus all be set equal
+      53             : to one.
+      54             : 
+      55             : \plumedfile
+      56             : d1: DISTANCE ATOMS=1,2
+      57             : d1a: AVERAGE ARG=d1
+      58             : PRINT ARG=d1a FILE=colvar STRIDE=100
+      59             : \endplumedfile
+      60             : 
+      61             : The following example calculates the ensemble average for the torsional angle involving atoms 1, 2, 3 and 4.
+      62             : At variance with the previous example this quantity is periodic so the second formula in the above introduction
+      63             : is used to calculate the average.  Furthermore, by using the CLEAR keyword we have specified that block averages
+      64             : are to be calculated.  Consequently, after 100 steps all the information acquired thus far in the simulation is
+      65             : forgotten and the process of averaging is begun again.  The quantities output in the colvar file are thus the
+      66             : block averages taken over the first 100 frames of the trajectory, the block average over the second 100 frames
+      67             : of trajectory and so on.
+      68             : 
+      69             : \plumedfile
+      70             : t1: TORSION ATOMS=1,2,3,4
+      71             : t1a: AVERAGE ARG=t1 CLEAR=100
+      72             : PRINT ARG=t1a FILE=colvar STRIDE=100
+      73             : \endplumedfile
+      74             : 
+      75             : This third example incorporates a bias.  Notice that the effect the bias has on the ensemble average is removed by taking
+      76             : advantage of the \ref REWEIGHT_BIAS method.  The final ensemble averages output to the file are thus block ensemble averages for the
+      77             : unbiased canonical ensemble at a temperature of 300 K.
+      78             : 
+      79             : \plumedfile
+      80             : t1: TORSION ATOMS=1,2,3,4
+      81             : RESTRAINT ARG=t1 AT=pi KAPPA=100.
+      82             : ww: REWEIGHT_BIAS TEMP=300
+      83             : t1a: AVERAGE ARG=t1 LOGWEIGHTS=ww CLEAR=100
+      84             : PRINT ARG=t1a FILE=colvar STRIDE=100
+      85             : \endplumedfile
+      86             : 
+      87             : */
+      88             : //+ENDPLUMEDOC
+      89             : 
+      90             : namespace PLMD {
+      91             : namespace analysis {
+      92             : 
+      93             : class Average : public ActionShortcut {
+      94             : public:
+      95             :   static void registerKeywords( Keywords& keys );
+      96             :   explicit Average( const ActionOptions& );
+      97             : };
+      98             : 
+      99             : PLUMED_REGISTER_ACTION(Average,"AVERAGE")
+     100             : 
+     101           6 : void Average::registerKeywords( Keywords& keys ) {
+     102           6 :   ActionShortcut::registerKeywords( keys );
+     103          12 :   keys.add("compulsory","ARG","the quantity that is being averaged");
+     104          12 :   keys.add("optional","LOGWEIGHTS","the logarithm of the quantity to use as the weights when calculating averages");
+     105          12 :   keys.add("compulsory","STRIDE","1","the frequency with which to store data for averaging");
+     106          12 :   keys.add("compulsory","CLEAR","0","the frequency with whihc to clear the data that is being averaged");
+     107          24 :   keys.needsAction("COMBINE"); keys.needsAction("CUSTOM"); keys.needsAction("ONES"); keys.needsAction("ACCUMULATE");
+     108           6 : }
+     109             : 
+     110           4 : Average::Average( const ActionOptions& ao ):
+     111             :   Action(ao),
+     112           4 :   ActionShortcut(ao)
+     113             : {
+     114             : 
+     115          16 :   std::string lw; parse("LOGWEIGHTS",lw); std::string stride, clearstride; parse("STRIDE",stride); parse("CLEAR",clearstride);
+     116           4 :   if( lw.length()>0 ) {
+     117           2 :     readInputLine( getShortcutLabel() + "_wsum: COMBINE ARG=" + lw + " PERIODIC=NO");
+     118           2 :     readInputLine( getShortcutLabel() + "_weight: CUSTOM ARG=" + getShortcutLabel() + "_wsum FUNC=exp(x) PERIODIC=NO");
+     119           6 :   } else readInputLine( getShortcutLabel() + "_weight: ONES SIZE=1" );
+     120             : 
+     121           8 :   std::vector<std::string> arg; parseVector("ARG",arg);
+     122           4 :   if( arg.size()!=1 ) error("should only be one argument to this action");
+     123           4 :   std::vector<Value*> vals; ActionWithArguments::interpretArgumentList( arg, plumed.getActionSet(), this, vals );
+     124             : 
+     125           8 :   readInputLine( getShortcutLabel() + "_denom: ACCUMULATE ARG=" + getShortcutLabel() + "_weight STRIDE=" + stride + " CLEAR=" + clearstride );
+     126           4 :   if( vals[0]->isPeriodic() ) {
+     127           2 :     std::string lbound, ubound, pfactor; vals[0]->getDomain( lbound, ubound ); pfactor = "((" + ubound + "-" + lbound + ")/(pi+pi))";
+     128           2 :     readInputLine( getShortcutLabel() + "_sin: CUSTOM ARG=" + arg[0] + "," + getShortcutLabel() + "_weight FUNC=y*sin((x-" + lbound + ")/" + pfactor + ") PERIODIC=NO");
+     129           2 :     readInputLine( getShortcutLabel() + "_cos: CUSTOM ARG=" + arg[0] + "," + getShortcutLabel() + "_weight FUNC=y*cos((x-" + lbound + ")/" + pfactor + ") PERIODIC=NO");
+     130           2 :     readInputLine( getShortcutLabel() + "_sinsum: ACCUMULATE ARG=" + getShortcutLabel() + "_sin STRIDE=" + stride + " CLEAR=" + clearstride );
+     131           2 :     readInputLine( getShortcutLabel() + "_cossum: ACCUMULATE ARG=" + getShortcutLabel() + "_cos STRIDE=" + stride + " CLEAR=" + clearstride );
+     132           2 :     readInputLine( getShortcutLabel() + ": CUSTOM ARG=" + getShortcutLabel() + "_sinsum," + getShortcutLabel() + "_cossum," + getShortcutLabel() + "_denom FUNC=" + lbound + "+" + pfactor + "*atan2(x/z,y/z) PERIODIC=" + lbound +"," + ubound);
+     133             :   } else {
+     134           6 :     readInputLine( getShortcutLabel() + "_prod: CUSTOM ARG=" + arg[0] + "," + getShortcutLabel() + "_weight FUNC=x*y PERIODIC=NO");
+     135           6 :     readInputLine( getShortcutLabel() + "_numer: ACCUMULATE ARG=" + getShortcutLabel() + "_prod STRIDE=" + stride + " CLEAR=" + clearstride  );
+     136           6 :     readInputLine( getShortcutLabel() + ": CUSTOM ARG=" + getShortcutLabel() + "_numer," + getShortcutLabel() + "_denom FUNC=x/y PERIODIC=NO");
+     137             :   }
+     138           8 : }
+     139             : 
+     140             : }
+     141             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/Collect.cpp.func-sort-c.html b/coverage/analysis/Collect.cpp.func-sort-c.html new file mode 100644 index 000000000000..c14a27b4142f --- /dev/null +++ b/coverage/analysis/Collect.cpp.func-sort-c.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - analysis/Collect.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - Collect.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:515396.2 %
Date:2024-04-19 12:12:35Functions:7977.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis7Collect22getNumberOfDerivativesEv0
_ZN4PLMD8analysis7CollectC2ERKNS_13ActionOptionsE0
_ZN4PLMD8analysis7CollectC1ERKNS_13ActionOptionsE92
_ZN4PLMD8analysis7Collect16registerKeywordsERNS_8KeywordsE94
_ZN4PLMD8analysis7Collect23calculateConstantValuesERKb180
_ZN4PLMD8analysis7Collect5applyEv17687
_ZN4PLMD8analysis7Collect6updateEv17687
_ZN4PLMD8analysis7Collect9calculateEv17687
_ZN4PLMD8analysis7Collect17calculateOnUpdateEv35558
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/Collect.cpp.func.html b/coverage/analysis/Collect.cpp.func.html new file mode 100644 index 000000000000..39626b06ca41 --- /dev/null +++ b/coverage/analysis/Collect.cpp.func.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - analysis/Collect.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - Collect.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:515396.2 %
Date:2024-04-19 12:12:35Functions:7977.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis7Collect16registerKeywordsERNS_8KeywordsE94
_ZN4PLMD8analysis7Collect17calculateOnUpdateEv35558
_ZN4PLMD8analysis7Collect22getNumberOfDerivativesEv0
_ZN4PLMD8analysis7Collect23calculateConstantValuesERKb180
_ZN4PLMD8analysis7Collect5applyEv17687
_ZN4PLMD8analysis7Collect6updateEv17687
_ZN4PLMD8analysis7Collect9calculateEv17687
_ZN4PLMD8analysis7CollectC1ERKNS_13ActionOptionsE92
_ZN4PLMD8analysis7CollectC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/Collect.cpp.gcov.html b/coverage/analysis/Collect.cpp.gcov.html new file mode 100644 index 000000000000..4d29a2570681 --- /dev/null +++ b/coverage/analysis/Collect.cpp.gcov.html @@ -0,0 +1,211 @@ + + + + + + + + LCOV - plumed test coverage - analysis/Collect.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - Collect.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:515396.2 %
Date:2024-04-19 12:12:35Functions: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/ActionWithValue.h"
+      23             : #include "core/ActionWithArguments.h"
+      24             : #include "core/ActionPilot.h"
+      25             : #include "core/ActionRegister.h"
+      26             : #include "core/PlumedMain.h"
+      27             : #include "core/ActionSet.h"
+      28             : #include "gridtools/ActionWithGrid.h"
+      29             : 
+      30             : //+PLUMEDOC ANALYSIS COLLECT
+      31             : /*
+      32             : Collect data from the trajectory for later analysis
+      33             : 
+      34             : \par Examples
+      35             : 
+      36             : */
+      37             : //+ENDPLUMEDOC
+      38             : 
+      39             : namespace PLMD {
+      40             : namespace analysis {
+      41             : 
+      42             : class Collect :
+      43             :   public ActionWithValue,
+      44             :   public ActionWithArguments,
+      45             :   public ActionPilot
+      46             : {
+      47             : private:
+      48             :   bool usefirstconf;
+      49             :   unsigned clearstride;
+      50             : public:
+      51             :   static void registerKeywords( Keywords& keys );
+      52             :   Collect( const ActionOptions& );
+      53             :   unsigned getNumberOfDerivatives();
+      54       35558 :   bool calculateOnUpdate() override { return false; }
+      55         180 :   bool calculateConstantValues( const bool& have_atoms ) override { return false; }
+      56       17687 :   void calculate() override {}
+      57       17687 :   void apply() override {}
+      58             :   void update() override ;
+      59             : };
+      60             : 
+      61             : PLUMED_REGISTER_ACTION(Collect,"COLLECT")
+      62             : 
+      63          94 : void Collect::registerKeywords( Keywords& keys ) {
+      64          94 :   Action::registerKeywords( keys ); ActionWithValue::registerKeywords( keys );
+      65          94 :   ActionWithArguments::registerKeywords( keys ); ActionPilot::registerKeywords( keys );
+      66         282 :   keys.use("ARG"); keys.use("UPDATE_FROM"); keys.use("UPDATE_UNTIL");
+      67         188 :   keys.add("compulsory","STRIDE","1","the frequency with which the data should be collected and added to the quantity being averaged");
+      68         188 :   keys.add("compulsory","CLEAR","0","the frequency with which to clear all the accumulated data.  The default value "
+      69             :            "of 0 implies that all the data will be used and that the grid will never be cleared");
+      70         188 :   keys.add("compulsory","TYPE","required if you are collecting an object with rank>0. Shoudl be vector/matrix and determines how data is stored");
+      71          94 : }
+      72             : 
+      73          92 : Collect::Collect( const ActionOptions& ao ):
+      74             :   Action(ao),
+      75             :   ActionWithValue(ao),
+      76             :   ActionWithArguments(ao),
+      77             :   ActionPilot(ao),
+      78          92 :   usefirstconf(false)
+      79             : {
+      80          92 :   if( getNumberOfArguments()!=1 ) error("there should only be one argument to this action");
+      81          92 :   if( getPntrToArgument(0)->getRank()>0 && getPntrToArgument(0)->hasDerivatives() ) error("input to the collect argument cannot be a grid");
+      82             : 
+      83          92 :   std::string type="vector";
+      84          92 :   if( getPntrToArgument(0)->getNumberOfValues()!=1 ) {
+      85          60 :     parse("TYPE",type); if( type!="vector" && type!="matrix" ) error("invalid type specified.  Should be vector/matrix");
+      86             :   }
+      87          92 :   if( type=="vector" ) log.printf("  adding %d elements to stored vector each time we collect\n", getPntrToArgument(0)->getNumberOfValues() );
+      88          12 :   else log.printf("  constructing matrix with rows of length %d from input data\n", getPntrToArgument(0)->getNumberOfValues() );
+      89             : 
+      90          92 :   parse("CLEAR",clearstride); unsigned nvals=0;
+      91          92 :   if( clearstride==getStride() ) {
+      92           6 :     nvals=1; usefirstconf=(getStride()==0);
+      93          86 :   } else if( clearstride>0 ) {
+      94          15 :     if( clearstride%getStride()!=0 ) error("CLEAR parameter must be a multiple of STRIDE");
+      95          15 :     log.printf("  clearing collected data every %u steps \n",clearstride);
+      96          15 :     nvals=(clearstride/getStride());
+      97             :   }
+      98             : 
+      99          92 :   std::vector<unsigned> shape(1); shape[0]=nvals; getPntrToArgument(0)->buildDataStore();
+     100          92 :   if( type=="matrix" ) { shape.resize(2); shape[1] = getPntrToArgument(0)->getNumberOfValues(); }
+     101          92 :   if( type=="vector" ) { shape[0] = nvals*getPntrToArgument(0)->getNumberOfValues(); }
+     102          92 :   addValue( shape ); if( shape.size()==2 ) getPntrToComponent(0)->reshapeMatrixStore( shape[1] );
+     103          92 :   if( getPntrToArgument(0)->isPeriodic() ) {
+     104          15 :     std::string min, max; getPntrToArgument(0)->getDomain( min, max );
+     105          15 :     setPeriodic( min, max );
+     106          77 :   } else setNotPeriodic();
+     107          92 : }
+     108             : 
+     109           0 : unsigned Collect::getNumberOfDerivatives() {
+     110           0 :   return 0;
+     111             : }
+     112             : 
+     113       17687 : void Collect::update() {
+     114       17687 :   if( getStep()==0 || (!onStep() && !usefirstconf) ) return ;
+     115       17016 :   usefirstconf=false;
+     116             : 
+     117             :   Value* myin=getPntrToArgument(0);
+     118       17016 :   Value* myout=getPntrToComponent(0);
+     119       17016 :   unsigned nargs=myin->getNumberOfValues();
+     120       17016 :   if( clearstride==getStride() ) {
+     121         339 :     for(unsigned i=0; i<nargs; ++i) myout->set( i, myin->get(i) );
+     122       17010 :   } else if( clearstride>0 ) {
+     123        1125 :     unsigned step = getStep() - clearstride*std::floor( getStep() / clearstride );
+     124        1125 :     if( getStep()%clearstride==0 ) step = step + clearstride;
+     125        1125 :     unsigned base = (step/getStride()-1)*nargs;
+     126        2250 :     for(unsigned i=0; i<nargs; ++i) myout->set( base+i, myin->get(i) );
+     127             :   } else {
+     128       90800 :     for(unsigned i=0; i<nargs; ++i) myout->push_back( myin->get(i) );
+     129       15885 :     if( myout->getRank()==2 ) myout->reshapeMatrixStore( nargs );
+     130             :   }
+     131             : }
+     132             : 
+     133             : }
+     134             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/CollectFrames.cpp.func-sort-c.html b/coverage/analysis/CollectFrames.cpp.func-sort-c.html new file mode 100644 index 000000000000..ebe8356b9618 --- /dev/null +++ b/coverage/analysis/CollectFrames.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - analysis/CollectFrames.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - CollectFrames.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:606296.8 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis13CollectFramesC2ERKNS_13ActionOptionsE0
_ZN4PLMD8analysis13CollectFramesC1ERKNS_13ActionOptionsE19
_ZN4PLMD8analysis13CollectFrames16registerKeywordsERNS_8KeywordsE31
_ZN4PLMD8analysis13CollectFrames15fixArgumentNameERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE48
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/CollectFrames.cpp.func.html b/coverage/analysis/CollectFrames.cpp.func.html new file mode 100644 index 000000000000..6ba77393ef7b --- /dev/null +++ b/coverage/analysis/CollectFrames.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - analysis/CollectFrames.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - CollectFrames.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:606296.8 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis13CollectFrames15fixArgumentNameERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE48
_ZN4PLMD8analysis13CollectFrames16registerKeywordsERNS_8KeywordsE31
_ZN4PLMD8analysis13CollectFramesC1ERKNS_13ActionOptionsE19
_ZN4PLMD8analysis13CollectFramesC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/CollectFrames.cpp.gcov.html b/coverage/analysis/CollectFrames.cpp.gcov.html new file mode 100644 index 000000000000..83cc3d0ffc11 --- /dev/null +++ b/coverage/analysis/CollectFrames.cpp.gcov.html @@ -0,0 +1,219 @@ + + + + + + + + LCOV - plumed test coverage - analysis/CollectFrames.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - CollectFrames.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:606296.8 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionShortcut.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "core/ActionWithArguments.h"
+      25             : #include "core/PlumedMain.h"
+      26             : #include "core/ActionSet.h"
+      27             : 
+      28             : //+PLUMEDOC ANALYSIS COLLECT_FRAMES
+      29             : /*
+      30             : This allows you to convert a trajectory and a dissimilarity matrix into a dissimilarity object
+      31             : 
+      32             : \par Examples
+      33             : 
+      34             : */
+      35             : //+ENDPLUMEDOC
+      36             : 
+      37             : namespace PLMD {
+      38             : namespace analysis {
+      39             : 
+      40             : class CollectFrames : public ActionShortcut {
+      41             : private:
+      42             :   std::string fixArgumentName( const std::string& argin );
+      43             : public:
+      44             :   static void registerKeywords( Keywords& keys );
+      45             :   explicit CollectFrames( const ActionOptions& ao );
+      46             : };
+      47             : 
+      48             : PLUMED_REGISTER_ACTION(CollectFrames,"COLLECT_FRAMES")
+      49             : 
+      50          31 : void CollectFrames::registerKeywords( Keywords& keys ) {
+      51          31 :   ActionShortcut::registerKeywords( keys );
+      52          62 :   keys.add("compulsory","STRIDE","1","the frequency with which data should be stored for analysis.  By default data is collected on every step");
+      53          62 :   keys.add("compulsory","CLEAR","0","the frequency with which data should all be deleted and restarted");
+      54          62 :   keys.add("compulsory","ALIGN","OPTIMAL","if storing atoms how would you like the alignment to be done can be SIMPLE/OPTIMAL");
+      55          62 :   keys.add("optional","ARG","the arguments you would like to collect");
+      56          62 :   keys.add("optional","ATOMS","list of atomic positions that you would like to collect and store for later analysis");
+      57          62 :   keys.add("optional","LOGWEIGHTS","list of actions that calculates log weights that should be used to weight configurations when calculating averages");
+      58          62 :   keys.addOutputComponent("data","default","the data that is being collected by this action");
+      59          62 :   keys.addOutputComponent("logweights","default","the logarithms of the weights of the data points");
+      60         124 :   keys.needsAction("POSITION"); keys.needsAction("CONCATENATE"); keys.needsAction("MEAN"); keys.needsAction("CUSTOM");
+      61         124 :   keys.needsAction("CONCATENATE"); keys.needsAction("COLLECT"); keys.needsAction("TRANSPOSE"); keys.needsAction("RMSD_VECTOR");
+      62          93 :   keys.needsAction("COMBINE"); keys.needsAction("VSTACK"); keys.needsAction("CONSTANT");
+      63          31 : }
+      64             : 
+      65          48 : std::string CollectFrames::fixArgumentName( const std::string& argin ) {
+      66          48 :   std::string argout = argin; std::size_t dot=argin.find(".");
+      67          52 :   if( dot!=std::string::npos ) argout = argin.substr(0,dot) + "_" + argin.substr(dot+1);
+      68          48 :   return argout;
+      69             : }
+      70             : 
+      71          19 : CollectFrames::CollectFrames( const ActionOptions& ao ):
+      72             :   Action(ao),
+      73          19 :   ActionShortcut(ao)
+      74             : {
+      75          57 :   std::string stride, clearstride; parse("STRIDE",stride); parse("CLEAR",clearstride);
+      76          38 :   std::vector<std::string> argn; parseVector("ARG",argn); std::vector<Value*> theargs;
+      77          19 :   ActionWithArguments::interpretArgumentList( argn, plumed.getActionSet(), this, theargs );
+      78          38 :   std::string indices; parse("ATOMS",indices);
+      79          19 :   if( theargs.size()==0 && indices.length()==0 ) error("no arguments or atoms were specified for collection");
+      80             : 
+      81             :   // Create the values to collect the atomic positions
+      82          19 :   if( indices.length()>0 ) {
+      83             :     // Collect reference position
+      84          12 :     readInputLine( getShortcutLabel() + "_getposx: POSITION ATOMS=" + indices ); std::string align; parse("ALIGN",align);
+      85          12 :     readInputLine( getShortcutLabel() + "_getpos: CONCATENATE ARG=" + getShortcutLabel() + "_getposx.x," + getShortcutLabel() + "_getposx.y," + getShortcutLabel() + "_getposx.z");
+      86             :     // Find atomic center
+      87          12 :     readInputLine( getShortcutLabel() + "_cposx: MEAN ARG=" + getShortcutLabel() + "_getposx.x PERIODIC=NO");
+      88          12 :     readInputLine( getShortcutLabel() + "_cposy: MEAN ARG=" + getShortcutLabel() + "_getposx.y PERIODIC=NO");
+      89          12 :     readInputLine( getShortcutLabel() + "_cposz: MEAN ARG=" + getShortcutLabel() + "_getposx.z PERIODIC=NO");
+      90             :     // Subtract atomimc center
+      91          12 :     readInputLine( getShortcutLabel() + "_refx: CUSTOM ARG=" + getShortcutLabel() + "_getposx.x," + getShortcutLabel() + "_cposx FUNC=x-y PERIODIC=NO");
+      92          12 :     readInputLine( getShortcutLabel() + "_refy: CUSTOM ARG=" + getShortcutLabel() + "_getposx.y," + getShortcutLabel() + "_cposy FUNC=x-y PERIODIC=NO");
+      93          12 :     readInputLine( getShortcutLabel() + "_refz: CUSTOM ARG=" + getShortcutLabel() + "_getposx.z," + getShortcutLabel() + "_cposz FUNC=x-y PERIODIC=NO");
+      94          12 :     readInputLine( getShortcutLabel() + "_ref: CONCATENATE ARG=" + getShortcutLabel() + "_refx," + getShortcutLabel() + "_refy," + getShortcutLabel() + "_refz");
+      95             :     // Store the reference position in a collect action
+      96          12 :     readInputLine( getShortcutLabel() + "_refpos: COLLECT TYPE=matrix ARG=" + getShortcutLabel() + "_ref STRIDE=" + clearstride + " CLEAR=" + clearstride );
+      97          12 :     readInputLine( getShortcutLabel() + "_refposT: TRANSPOSE ARG=" + getShortcutLabel() + "_refpos");
+      98             :     // Calculate the RMSD between the instaneous position and the reference position
+      99          12 :     readInputLine( getShortcutLabel() + "_rmsd: RMSD_VECTOR ARG=" + getShortcutLabel() + "_getpos," + getShortcutLabel() + "_refpos DISPLACEMENT SQUARED TYPE=" + align );
+     100             :     // Add the reference position to the RMSD displacement
+     101          12 :     readInputLine( getShortcutLabel() + "_fpos: COMBINE ARG=" + getShortcutLabel() + "_refposT," + getShortcutLabel() + "_rmsd.disp PERIODIC=NO");
+     102             :     // Store the reference data
+     103           6 :     std::string suffix = "_atomdata"; if( theargs.size()==0 ) suffix = "_data";
+     104          12 :     readInputLine( getShortcutLabel() + suffix + ": COLLECT TYPE=matrix ARG=" + getShortcutLabel() + "_fpos STRIDE=" + stride + " CLEAR=" + clearstride );
+     105             :   }
+     106             : 
+     107             :   // Create all the collect actions for arguments
+     108          43 :   for(unsigned i=0; i<theargs.size(); ++i) {
+     109          24 :     if( theargs[i]->getNumberOfValues()!=theargs[0]->getNumberOfValues() ) error("mismatch between number of arguments calculated by each collected argument");
+     110          48 :     readInputLine( getShortcutLabel() + "_" + fixArgumentName( theargs[i]->getName() ) + ": COLLECT ARG=" + theargs[i]->getName() + " STRIDE=" + stride + " CLEAR=" + clearstride );
+     111             :   }
+     112             :   // Make a list of collect actions
+     113          19 :   if( theargs.size()>0 ) {
+     114          26 :     std::string allcol = getShortcutLabel() + "_" + fixArgumentName( theargs[0]->getName() );
+     115          24 :     for(unsigned i=1; i<theargs.size(); ++i) allcol += "," + getShortcutLabel() + "_" + fixArgumentName( theargs[i]->getName() );
+     116             :     // And transfer everything to a matrix
+     117          13 :     std::string suffix = "_argdata"; if( indices.length()==0 ) suffix = "_data";
+     118          26 :     readInputLine( getShortcutLabel() + suffix + ": VSTACK ARG=" + allcol );
+     119             :   }
+     120             :   // Merge all the collected data together into a single matrix
+     121          19 :   if( theargs.size()>0 && indices.length()>0 ) readInputLine( getShortcutLabel() + "_data: CONCATENATE MATRIX11=" + getShortcutLabel() + "_atomdata MATRIX12=" + getShortcutLabel() + "_argdata");
+     122             : 
+     123             :   // Now get the logweights
+     124          38 :   std::vector<std::string> logw; parseVector("LOGWEIGHTS",logw); std::vector<Value*> thew;
+     125          19 :   if( logw.size()>0 ) ActionWithArguments::interpretArgumentList( logw, plumed.getActionSet(), this, thew );
+     126          19 :   if( logw.size()>1 ) error("maximum of one argument should be specified for logweights");
+     127             : 
+     128          19 :   if( logw.size()==0 ) {
+     129          19 :     std::string zeros="0"; if( theargs.size()>0 ) { for(unsigned i=1; i<theargs[0]->getNumberOfValues(); ++i) zeros += ",0"; }
+     130          38 :     readInputLine( getShortcutLabel() + "_cweight: CONSTANT VALUE=" + zeros );
+     131          38 :     readInputLine( getShortcutLabel() + "_logweights: COLLECT ARG=" + getShortcutLabel() + "_cweight STRIDE=" + stride + " CLEAR=" + clearstride );
+     132             :   } else {
+     133           0 :     if( theargs[0]->getNumberOfValues()!=thew[0]->getNumberOfValues() ) error("mismatch between number of weights and number of collected arguments");
+     134           0 :     readInputLine( getShortcutLabel() + "_logweights: COLLECT ARG=" + thew[0]->getName() + " STRIDE=" + stride + " CLEAR=" + clearstride );
+     135             :   }
+     136             :   // And finally create a value that contains as many ones as there are data points (this is used if we want to do Classical MDS
+     137          19 :   readInputLine( getShortcutLabel() + "_one: CONSTANT VALUE=1");
+     138          38 :   readInputLine( getShortcutLabel() + "_ones: COLLECT ARG=" + getShortcutLabel() + "_one STRIDE=" + stride + " CLEAR=" + clearstride );
+     139          57 : }
+     140             : 
+     141             : }
+     142             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/Committor.cpp.func-sort-c.html b/coverage/analysis/Committor.cpp.func-sort-c.html new file mode 100644 index 000000000000..251a17bc6e0f --- /dev/null +++ b/coverage/analysis/Committor.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - analysis/Committor.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - Committor.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:7373100.0 %
Date:2024-04-19 12:12:35Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

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

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

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis10CreateMask22getNumberOfDerivativesEv0
_ZN4PLMD8analysis10CreateMaskC2ERKNS_13ActionOptionsE0
_ZN4PLMD8analysis10CreateMask5applyEv6
_ZN4PLMD8analysis10CreateMaskC1ERKNS_13ActionOptionsE15
_ZN4PLMD8analysis10CreateMask16registerKeywordsERNS_8KeywordsE17
_ZN4PLMD8analysis10CreateMask9calculateEv21
_ZN4PLMD8analysis10CreateMask7prepareEv25
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/CreateMask.cpp.func.html b/coverage/analysis/CreateMask.cpp.func.html new file mode 100644 index 000000000000..f5a342bdd946 --- /dev/null +++ b/coverage/analysis/CreateMask.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - analysis/CreateMask.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - CreateMask.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:505394.3 %
Date:2024-04-19 12:12:35Functions:5771.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis10CreateMask16registerKeywordsERNS_8KeywordsE17
_ZN4PLMD8analysis10CreateMask22getNumberOfDerivativesEv0
_ZN4PLMD8analysis10CreateMask5applyEv6
_ZN4PLMD8analysis10CreateMask7prepareEv25
_ZN4PLMD8analysis10CreateMask9calculateEv21
_ZN4PLMD8analysis10CreateMaskC1ERKNS_13ActionOptionsE15
_ZN4PLMD8analysis10CreateMaskC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/CreateMask.cpp.gcov.html b/coverage/analysis/CreateMask.cpp.gcov.html new file mode 100644 index 000000000000..923ee09bac01 --- /dev/null +++ b/coverage/analysis/CreateMask.cpp.gcov.html @@ -0,0 +1,203 @@ + + + + + + + + LCOV - plumed test coverage - analysis/CreateMask.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - CreateMask.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:505394.3 %
Date:2024-04-19 12:12:35Functions:5771.4 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2020 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received 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/ActionWithArguments.h"
+      24             : #include "core/ActionRegister.h"
+      25             : #include "tools/Random.h"
+      26             : 
+      27             : namespace PLMD {
+      28             : namespace analysis {
+      29             : 
+      30             : //+PLUMEDOC DIMRED CREATE_MASK
+      31             : /*
+      32             : Create a mask vector to use for landmark selection
+      33             : 
+      34             : \par Examples
+      35             : 
+      36             : */
+      37             : //+ENDPLUMEDOC
+      38             : 
+      39             : class CreateMask :
+      40             :   public ActionWithValue,
+      41             :   public ActionWithArguments {
+      42             : private:
+      43             :   Random r;
+      44             :   unsigned nzeros;
+      45             :   enum {nomask,stride,random} type;
+      46             : public:
+      47             :   static void registerKeywords( Keywords& keys );
+      48             :   CreateMask( const ActionOptions& );
+      49           0 :   unsigned getNumberOfDerivatives() override { return 0; }
+      50             :   void prepare() override ;
+      51             :   void calculate() override ;
+      52           6 :   void apply() override {}
+      53             : };
+      54             : 
+      55             : PLUMED_REGISTER_ACTION(CreateMask,"CREATE_MASK")
+      56             : 
+      57          17 : void CreateMask::registerKeywords( Keywords& keys ) {
+      58          17 :   Action::registerKeywords( keys ); ActionWithValue::registerKeywords( keys );
+      59          17 :   ActionWithArguments::registerKeywords( keys ); keys.use("ARG");
+      60          34 :   keys.add("compulsory","TYPE","the way the zeros are supposed to be set");
+      61          34 :   keys.add("compulsory","NZEROS","the number of zeros that you want to put in the mask");
+      62          34 :   keys.add("optional","SEED","the seed to use for the random number generator");
+      63          17 : }
+      64             : 
+      65             : 
+      66          15 : CreateMask::CreateMask( const ActionOptions& ao ) :
+      67             :   Action(ao),
+      68             :   ActionWithValue(ao),
+      69             :   ActionWithArguments(ao),
+      70          15 :   nzeros(0)
+      71             : {
+      72          15 :   if( getNumberOfArguments()!=1 ) error("should only be one argument to this action");
+      73          15 :   if( getPntrToArgument(0)->getRank()!=1 ) error("argument should be a vector");
+      74          39 :   std::string stype; parse("TYPE",stype); if( stype!="nomask" ) parse("NZEROS",nzeros);
+      75             : 
+      76          15 :   if( stype=="nomask" ) {
+      77           6 :     type=nomask; log.printf("  setting all points in output mask to zero \n");
+      78           9 :   } else if( stype=="stride" ) {
+      79           8 :     type=stride; log.printf("  setting every %d equally spaced points in output mask to zero \n", nzeros );
+      80           1 :   } else if( stype=="random" ) {
+      81           2 :     unsigned seed=230623; parse("SEED",seed); r.setSeed(-seed); getPntrToArgument(0)->buildDataStore();
+      82           1 :     type=random; log.printf("  choosing %d points to set to non-zero in mask in accordance with input weights \n", nzeros );
+      83           0 :   } else error( stype + " is not a valid way input for TYPE");
+      84          15 :   std::vector<unsigned> shape(1); shape[0] = getPntrToArgument(0)->getShape()[0];
+      85          15 :   addValue( shape ); setNotPeriodic(); getPntrToComponent(0)->buildDataStore();
+      86          53 :   for(unsigned i=0; i<shape[0]; ++i) getPntrToComponent(0)->set( i, 1.0 );
+      87          15 : }
+      88             : 
+      89          25 : void CreateMask::prepare() {
+      90          25 :   Value* out=getPntrToComponent(0); Value* arg=getPntrToArgument(0);
+      91          25 :   if( out->getShape()[0]!=arg->getShape()[0] ) {
+      92          11 :     std::vector<unsigned> shape(1); shape[0] = arg->getShape()[0]; out->setShape( shape );
+      93             :   }
+      94          25 :   if( type!=nomask ) {
+      95         325 :     for(unsigned i=nzeros; i<out->getShape()[0]; ++i) out->set( i, 1 );
+      96             :   }
+      97          25 : }
+      98             : 
+      99          21 : void CreateMask::calculate() {
+     100          21 :   Value* out=getPntrToComponent(0); Value* arg=getPntrToArgument(0);
+     101          21 :   unsigned ns = arg->getShape()[0];
+     102        1171 :   for(unsigned i=0; i<ns; ++i) out->set( i, 1.0 );
+     103             : 
+     104          21 :   if( type==stride ) {
+     105          11 :     std::size_t ss = int( std::floor( ns / nzeros ) );
+     106         300 :     for(unsigned i=0; i<nzeros; ++i) out->set( i*ss, 0.0 );
+     107          10 :   } else if( type==random ) {
+     108          20 :     for(unsigned i=0; i<nzeros; ++i ) {
+     109             :       double totweights = 0;
+     110         112 :       for(unsigned j=0; j<ns; ++j) {
+     111          96 :         if( out->get(j)>0 ) totweights += arg->get(j);
+     112             :       }
+     113          16 :       double rr = r.U01()*totweights; double accum=0;
+     114          55 :       for(unsigned j=0; j<ns; ++j) {
+     115          55 :         if( out->get(j)>0 ) accum += arg->get(j);
+     116          55 :         if( accum<rr ) continue;
+     117          16 :         out->set( j, 0 ); break;
+     118             :       }
+     119             :     }
+     120           6 :   } else if( type==nomask ) {
+     121         555 :     for(unsigned i=0; i<ns; ++i) out->set( i, 0.0 );
+     122           0 :   } else error("invalid mask creation type");
+     123          21 : }
+     124             : 
+     125             : }
+     126             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/FarthestPointSampling.cpp.func-sort-c.html b/coverage/analysis/FarthestPointSampling.cpp.func-sort-c.html new file mode 100644 index 000000000000..8092fedbd432 --- /dev/null +++ b/coverage/analysis/FarthestPointSampling.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + 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:374092.5 %
Date:2024-04-19 12:12:35Functions:4850.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis21FarthestPointSampling22getNumberOfDerivativesEv0
_ZN4PLMD8analysis21FarthestPointSampling5applyEv0
_ZN4PLMD8analysis21FarthestPointSamplingC2ERKNS_13ActionOptionsE0
_ZNK4PLMD8analysis21FarthestPointSampling23getForceOnMatrixElementERKjS3_0
_ZN4PLMD8analysis21FarthestPointSampling7prepareEv1
_ZN4PLMD8analysis21FarthestPointSampling9calculateEv1
_ZN4PLMD8analysis21FarthestPointSamplingC1ERKNS_13ActionOptionsE1
_ZN4PLMD8analysis21FarthestPointSampling16registerKeywordsERNS_8KeywordsE3
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/FarthestPointSampling.cpp.func.html b/coverage/analysis/FarthestPointSampling.cpp.func.html new file mode 100644 index 000000000000..5547e7aba6ee --- /dev/null +++ b/coverage/analysis/FarthestPointSampling.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + 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:374092.5 %
Date:2024-04-19 12:12:35Functions:4850.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis21FarthestPointSampling16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD8analysis21FarthestPointSampling22getNumberOfDerivativesEv0
_ZN4PLMD8analysis21FarthestPointSampling5applyEv0
_ZN4PLMD8analysis21FarthestPointSampling7prepareEv1
_ZN4PLMD8analysis21FarthestPointSampling9calculateEv1
_ZN4PLMD8analysis21FarthestPointSamplingC1ERKNS_13ActionOptionsE1
_ZN4PLMD8analysis21FarthestPointSamplingC2ERKNS_13ActionOptionsE0
_ZNK4PLMD8analysis21FarthestPointSampling23getForceOnMatrixElementERKjS3_0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/FarthestPointSampling.cpp.gcov.html b/coverage/analysis/FarthestPointSampling.cpp.gcov.html new file mode 100644 index 000000000000..58d01ee8624d --- /dev/null +++ b/coverage/analysis/FarthestPointSampling.cpp.gcov.html @@ -0,0 +1,188 @@ + + + + + + + + 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:374092.5 %
Date:2024-04-19 12:12:35Functions:4850.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "adjmat/MatrixOperationBase.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "tools/Random.h"
+      25             : 
+      26             : //+PLUMEDOC LANDMARKS FARTHEST_POINT_SAMPLING
+      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 adjmat::MatrixOperationBase {
+      39             : private:
+      40             :   unsigned seed;
+      41             :   unsigned nlandmarks;
+      42             : public:
+      43             :   static void registerKeywords( Keywords& keys );
+      44             :   explicit FarthestPointSampling( const ActionOptions& ao );
+      45           0 :   unsigned getNumberOfDerivatives() override { return 0; }
+      46             :   void prepare() override ;
+      47             :   void calculate() override ;
+      48           0 :   void apply() override {}
+      49           0 :   double getForceOnMatrixElement( const unsigned& jrow, const unsigned& krow ) const { plumed_merror("this should not be called"); }
+      50             : };
+      51             : 
+      52             : PLUMED_REGISTER_ACTION(FarthestPointSampling,"FARTHEST_POINT_SAMPLING")
+      53             : 
+      54           3 : void FarthestPointSampling::registerKeywords( Keywords& keys ) {
+      55           3 :   adjmat::MatrixOperationBase::registerKeywords( keys );
+      56           6 :   keys.add("compulsory","NZEROS","the number of landmark points that you want to select");
+      57           6 :   keys.add("compulsory","SEED","1234","a random number seed");
+      58           3 : }
+      59             : 
+      60           1 : FarthestPointSampling::FarthestPointSampling( const ActionOptions& ao ):
+      61             :   Action(ao),
+      62           1 :   MatrixOperationBase(ao)
+      63             : {
+      64           1 :   if( getPntrToArgument(0)->getShape()[0]!=getPntrToArgument(0)->getShape()[1] ) error("input to this argument should be a square matrix of dissimilarities");
+      65           2 :   parse("NZEROS",nlandmarks); parse("SEED",seed);
+      66           1 :   log.printf("  selecting %d landmark points \n", nlandmarks );
+      67             : 
+      68           1 :   std::vector<unsigned> shape(1); shape[0] = getPntrToArgument(0)->getShape()[0];
+      69           1 :   addValue( shape ); setNotPeriodic(); getPntrToComponent(0)->buildDataStore();
+      70           1 : }
+      71             : 
+      72           1 : void FarthestPointSampling::prepare() {
+      73           1 :   Value* myval = getPntrToComponent(0);
+      74           1 :   if( myval->getShape()[0]!=getPntrToArgument(0)->getShape()[0] ) {
+      75           1 :     std::vector<unsigned> shape(1); shape[0] = getPntrToArgument(0)->getShape()[0]; myval->setShape(shape);
+      76             :   }
+      77           4 :   for(unsigned i=0; i<nlandmarks; ++i) myval->set( i, 0.0 );
+      78          11 :   for(unsigned i=nlandmarks; i<myval->getShape()[0]; ++i) myval->set( i, 1.0 );
+      79           1 : }
+      80             : 
+      81           1 : void FarthestPointSampling::calculate() {
+      82           1 :   Value* myval=getPntrToComponent(0); unsigned npoints = getPntrToArgument(0)->getShape()[0];
+      83          14 :   for(unsigned i=0; i<npoints; ++i) myval->set( i, 1.0 );
+      84           1 :   std::vector<unsigned> landmarks( nlandmarks );
+      85             : 
+      86             :   // Select first point at random
+      87           1 :   Random random; random.setSeed(-seed); double rand=random.RandU01();
+      88           1 :   landmarks[0] = std::floor( npoints*rand ); myval->set( landmarks[0], 0 );
+      89             : 
+      90             :   // Now find distance to all other points (N.B. We can use squared distances here for speed)
+      91           1 :   Matrix<double> distances( nlandmarks, npoints ); Value* myarg = getPntrToArgument(0);
+      92          14 :   for(unsigned i=0; i<npoints; ++i) distances(0,i) = myarg->get( landmarks[0]*npoints + i );
+      93             : 
+      94             :   // Now find all other landmarks
+      95           3 :   for(unsigned i=1; i<nlandmarks; ++i) {
+      96             :     // Find point that has the largest minimum distance from the landmarks selected thus far
+      97             :     double maxd=0;
+      98          28 :     for(unsigned j=0; j<npoints; ++j) {
+      99          26 :       double mind=distances(0,j);
+     100          39 :       for(unsigned k=1; k<i; ++k) {
+     101          13 :         if( distances(k,j)<mind ) { mind=distances(k,j); }
+     102             :       }
+     103          26 :       if( mind>maxd ) { maxd=mind; landmarks[i]=j; }
+     104             :     }
+     105           2 :     myval->set( landmarks[i], 0 );
+     106          28 :     for(unsigned k=0; k<npoints; ++k) distances(i,k) = myarg->get( landmarks[i]*npoints + k );
+     107             :   }
+     108           1 : }
+     109             : 
+     110             : }
+     111             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/GatherReplicas.cpp.func-sort-c.html b/coverage/analysis/GatherReplicas.cpp.func-sort-c.html new file mode 100644 index 000000000000..93708c54471c --- /dev/null +++ b/coverage/analysis/GatherReplicas.cpp.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - analysis/GatherReplicas.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - GatherReplicas.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:344085.0 %
Date:2024-04-19 12:12:35Functions:4666.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis14GatherReplicas22getNumberOfDerivativesEv0
_ZN4PLMD8analysis14GatherReplicasC2ERKNS_13ActionOptionsE0
_ZN4PLMD8analysis14GatherReplicasC1ERKNS_13ActionOptionsE12
_ZN4PLMD8analysis14GatherReplicas16registerKeywordsERNS_8KeywordsE14
_ZN4PLMD8analysis14GatherReplicas5applyEv4224
_ZN4PLMD8analysis14GatherReplicas9calculateEv4224
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/GatherReplicas.cpp.func.html b/coverage/analysis/GatherReplicas.cpp.func.html new file mode 100644 index 000000000000..e502999a3200 --- /dev/null +++ b/coverage/analysis/GatherReplicas.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - analysis/GatherReplicas.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - GatherReplicas.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:344085.0 %
Date:2024-04-19 12:12:35Functions:4666.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis14GatherReplicas16registerKeywordsERNS_8KeywordsE14
_ZN4PLMD8analysis14GatherReplicas22getNumberOfDerivativesEv0
_ZN4PLMD8analysis14GatherReplicas5applyEv4224
_ZN4PLMD8analysis14GatherReplicas9calculateEv4224
_ZN4PLMD8analysis14GatherReplicasC1ERKNS_13ActionOptionsE12
_ZN4PLMD8analysis14GatherReplicasC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/GatherReplicas.cpp.gcov.html b/coverage/analysis/GatherReplicas.cpp.gcov.html new file mode 100644 index 000000000000..f63b2c432bd1 --- /dev/null +++ b/coverage/analysis/GatherReplicas.cpp.gcov.html @@ -0,0 +1,191 @@ + + + + + + + + LCOV - plumed test coverage - analysis/GatherReplicas.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - GatherReplicas.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:344085.0 %
Date:2024-04-19 12:12:35Functions:4666.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2017 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received 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/ActionWithArguments.h"
+      24             : #include "core/ActionRegister.h"
+      25             : #include "tools/Communicator.h"
+      26             : 
+      27             : //+PLUMEDOC ANALYSIS GATHER_REPLICAS
+      28             : /*
+      29             : Create a vector that contains the copies of the input quantities from all replicas
+      30             : 
+      31             : \par Examples
+      32             : 
+      33             : 
+      34             : */
+      35             : //+ENDPLUMEDOC
+      36             : 
+      37             : namespace PLMD {
+      38             : namespace analysis {
+      39             : 
+      40             : class GatherReplicas :
+      41             :   public ActionWithValue,
+      42             :   public ActionWithArguments {
+      43             : private:
+      44             :   unsigned nreplicas;
+      45             : public:
+      46             :   static void registerKeywords( Keywords& keys );
+      47             :   explicit GatherReplicas( const ActionOptions& );
+      48             :   unsigned getNumberOfDerivatives();
+      49             :   void calculate();
+      50             :   void apply();
+      51             : };
+      52             : 
+      53             : PLUMED_REGISTER_ACTION(GatherReplicas,"GATHER_REPLICAS")
+      54             : 
+      55          14 : void GatherReplicas::registerKeywords( Keywords& keys ) {
+      56          14 :   Action::registerKeywords( keys ); ActionWithValue::registerKeywords( keys ); ActionWithArguments::registerKeywords( keys );
+      57          42 :   keys.remove("ARG"); keys.add("compulsory","ARG","the argument from the various replicas that you would like to gather");
+      58          28 :   keys.addOutputComponent("rep","default","the input arguments for each of the replicas");
+      59          14 : }
+      60             : 
+      61          12 : GatherReplicas::GatherReplicas( const ActionOptions& ao ):
+      62             :   Action(ao),
+      63             :   ActionWithValue(ao),
+      64          12 :   ActionWithArguments(ao)
+      65             : {
+      66          12 :   if( getNumberOfArguments()!=1 ) error("you can only gather one argument at a time with GatherReplicas");
+      67             : 
+      68          12 :   std::vector<unsigned> shape( getPntrToArgument(0)->getShape() );
+      69          12 :   std::string min, max; nreplicas=multi_sim_comm.Get_size(); bool periodic=false;
+      70          12 :   if( getPntrToArgument(0)->isPeriodic() ) { periodic=true; getPntrToArgument(0)->getDomain( min, max ); }
+      71             : 
+      72          84 :   for(unsigned i=0; i<nreplicas; ++i) {
+      73          72 :     std::string num; Tools::convert( i+1, num);
+      74         144 :     if( getPntrToArgument(0)->hasDerivatives() ) addComponentWithDerivatives( "rep-" + num, shape );
+      75           0 :     else addComponent( "rep-" + num, shape );
+      76          72 :     if( periodic ) componentIsPeriodic( "rep-" + num, min, max );
+      77         144 :     else componentIsNotPeriodic( "rep-" + num );
+      78             :   }
+      79          12 : }
+      80             : 
+      81           0 : unsigned GatherReplicas::getNumberOfDerivatives() {
+      82           0 :   return getPntrToArgument(0)->getNumberOfDerivatives();
+      83             : }
+      84             : 
+      85        4224 : void GatherReplicas::calculate() {
+      86             :   Value* myarg = getPntrToArgument(0);
+      87        4224 :   unsigned nvals = myarg->getNumberOfValues(), nder = myarg->getNumberOfDerivatives();
+      88        4224 :   std::vector<double> dval( nvals*(1+nder) ), datap(nreplicas*nvals*(1+nder) );
+      89        8448 :   for(unsigned i=0; i<nvals; ++i) {
+      90        4224 :     dval[i*(1+nder)] = myarg->get(i);
+      91        8448 :     if( myarg->getRank()==0 ) { for(unsigned j=0; j<nder; ++j) dval[i*(1+nder)+1+j] = myarg->getDerivative(j); }
+      92           0 :     else if( myarg->hasDerivatives() ) { for(unsigned j=0; j<nder; ++j) dval[i*(1+nder)+1+j] = myarg->getGridDerivative( i, j ); }
+      93             :   }
+      94        4224 :   if(comm.Get_rank()==0) multi_sim_comm.Allgather(dval,datap);
+      95             : 
+      96       29568 :   for(unsigned k=0; k<nreplicas; k++) {
+      97       25344 :     Value* myout = getPntrToComponent(k);
+      98       25344 :     if( myout->getNumberOfDerivatives()!=myarg->getNumberOfDerivatives() ) myout->resizeDerivatives( myarg->getNumberOfDerivatives() );
+      99       25344 :     unsigned sstart=k*nvals*(1+nder);
+     100       50688 :     for(unsigned i=0; i<nvals; ++i) {
+     101       25344 :       myout->set( i, datap[sstart+i*(1+nder)] );
+     102       50688 :       if( myarg->getRank()==0 ) { for(unsigned j=0; j<nder; ++j) myout->setDerivative( j, dval[i*(1+nder)+1+j] ); }
+     103           0 :       else if( myarg->hasDerivatives() ) { for(unsigned j=0; j<nder; ++j) myout->addGridDerivatives( i, j, dval[i*(1+nder)+1+j] ); }
+     104             :     }
+     105             :   }
+     106        4224 : }
+     107             : 
+     108        4224 : void GatherReplicas::apply() {
+     109        4224 :   if( doNotCalculateDerivatives() ) return;
+     110           0 :   error("apply has not been implemented for GatherReplicas");
+     111             : }
+     112             : 
+     113             : }
+     114             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/Histogram.cpp.func-sort-c.html b/coverage/analysis/Histogram.cpp.func-sort-c.html new file mode 100644 index 000000000000..9332fff090d1 --- /dev/null +++ b/coverage/analysis/Histogram.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + 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:4242100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis9HistogramC2ERKNS_13ActionOptionsE0
_ZN4PLMD8analysis9HistogramC1ERKNS_13ActionOptionsE22
_ZN4PLMD8analysis9Histogram16registerKeywordsERNS_8KeywordsE29
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/Histogram.cpp.func.html b/coverage/analysis/Histogram.cpp.func.html new file mode 100644 index 000000000000..409a30c37712 --- /dev/null +++ b/coverage/analysis/Histogram.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + 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:4242100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis9Histogram16registerKeywordsERNS_8KeywordsE29
_ZN4PLMD8analysis9HistogramC1ERKNS_13ActionOptionsE22
_ZN4PLMD8analysis9HistogramC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/Histogram.cpp.gcov.html b/coverage/analysis/Histogram.cpp.gcov.html new file mode 100644 index 000000000000..22f1540207d6 --- /dev/null +++ b/coverage/analysis/Histogram.cpp.gcov.html @@ -0,0 +1,340 @@ + + + + + + + + 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:4242100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionRegister.h"
+      23             : #include "core/ActionShortcut.h"
+      24             : #include "core/ActionWithValue.h"
+      25             : #include "core/ActionWithArguments.h"
+      26             : #include "core/PlumedMain.h"
+      27             : #include "core/ActionSet.h"
+      28             : 
+      29             : //+PLUMEDOC GRIDCALC HISTOGRAM
+      30             : /*
+      31             : Accumulate the average probability density along a few CVs from a trajectory.
+      32             : 
+      33             : When using this method it is supposed that you have some collective variable \f$\zeta\f$ that
+      34             : gives a reasonable description of some physical or chemical phenomenon.  As an example of what we
+      35             : mean by this suppose you wish to examine the following SN2 reaction:
+      36             : 
+      37             : \f[
+      38             :  \textrm{OH}^- + \textrm{CH}_3Cl  \rightarrow \textrm{CH}_3OH + \textrm{Cl}^-
+      39             : \f]
+      40             : 
+      41             : The distance between the chlorine atom and the carbon is an excellent collective variable, \f$\zeta\f$,
+      42             : in this case because this distance is short for the reactant, \f$\textrm{CH}_3Cl\f$, because the carbon
+      43             : and chlorine are chemically bonded, and because it is long for the product state when these two atoms are
+      44             : not chemically bonded.  We thus might want to accumulate the probability density, \f$P(\zeta)\f$, as a function of this distance
+      45             : as this will provide us with information about the overall likelihood of the reaction.   Furthermore, the
+      46             : free energy, \f$F(\zeta)\f$, is related to this probability density via:
+      47             : 
+      48             : \f[
+      49             : F(\zeta) = - k_B T \ln P(\zeta)
+      50             : \f]
+      51             : 
+      52             : Accumulating these probability densities is precisely what this Action can be used to do.  Furthermore, the conversion
+      53             : of the histogram to the free energy can be achieved by using the method \ref CONVERT_TO_FES.
+      54             : 
+      55             : We calculate histograms within PLUMED using a method known as kernel density estimation, which you can read more about here:
+      56             : 
+      57             : https://en.wikipedia.org/wiki/Kernel_density_estimation
+      58             : 
+      59             : 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$,
+      60             : centered at the current value, \f$\zeta(t)\f$, of this quantity is generated with a bandwidth \f$\sigma\f$, which
+      61             : is set by the user.  These kernels are then used to accumulate the ensemble average for the probability density:
+      62             : 
+      63             : \f[
+      64             : \langle P(\zeta) \rangle = \frac{ \sum_{t'=0}^t w(t') K(\zeta-\zeta(t'),\sigma) }{ \sum_{t'=0}^t w(t') }
+      65             : \f]
+      66             : 
+      67             : Here the sums run over a portion of the trajectory specified by the user.  The final quantity evaluated is a weighted
+      68             : average as the weights, \f$w(t')\f$, allow us to negate the effect any bias might have on the region of phase space
+      69             : sampled by the system.  This is discussed in the section of the manual on \ref Analysis.
+      70             : 
+      71             : A discrete analogue of kernel density estimation can also be used.  In this analogue the kernels in the above formula
+      72             : are replaced by Dirac delta functions.   When this method is used the final function calculated is no longer a probability
+      73             : density - it is instead a probability mass function as each element of the function tells you the value of an integral
+      74             : between two points on your grid rather than the value of a (continuous) function on a grid.
+      75             : 
+      76             : Additional material and examples can be also found in the tutorials \ref lugano-1.
+      77             : 
+      78             : \par A note on block averaging and errors
+      79             : 
+      80             : Some particularly important
+      81             : 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.
+      82             : The technique for estimating error bars that is known as block averaging is introduced in this tutorial.  The essence of this technique is that
+      83             : 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
+      84             : the set of \f$N\f$ block averages that are obtained from this technique then the final error bar is calculated as:
+      85             : 
+      86             : \f[
+      87             : \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
+      88             : \f]
+      89             : 
+      90             : 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
+      91             : 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:
+      92             : 
+      93             : \f[
+      94             : \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 }
+      95             : \f]
+      96             : 
+      97             : where \f$W_i\f$ is the sum of all the weights for the \f$i\f$th block of data.
+      98             : 
+      99             : If we wish to calculate a normalized histogram we must calculate ensemble averages from our biased simulation using:
+     100             : \f[
+     101             :  \langle H(x) \rangle = \frac{\sum_{t=1}^M w_t K( x - x_t,\sigma) }{\sum_{t=1}^M w_t}
+     102             : \f]
+     103             : 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
+     104             : 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
+     105             : normalized histogram at point \f$x\f$.  The following ensemble average will be calculated if you use the NORMALIZATION=true option in HISTOGRAM.
+     106             : 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
+     107             : above.
+     108             : 
+     109             : 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:
+     110             : \f[
+     111             : \langle H(x) \rangle = \frac{1}{M} \sum_{t=1}^M w_t K( x - x_t,\sigma)
+     112             : \f]
+     113             : instead of the expression above.  As such this is what is done by default in HISTOGRAM or if the NORMALIZATION=ndata option is used.
+     114             : When the histogram is calculated in this second way the first of the two formula above can be used when calculating error bars from
+     115             : block averages.
+     116             : 
+     117             : \par Examples
+     118             : 
+     119             : The following input monitors two torsional angles during a simulation
+     120             : and outputs a continuous histogram as a function of them at the end of the simulation.
+     121             : \plumedfile
+     122             : TORSION ATOMS=1,2,3,4 LABEL=r1
+     123             : TORSION ATOMS=2,3,4,5 LABEL=r2
+     124             : HISTOGRAM ...
+     125             :   ARG=r1,r2
+     126             :   GRID_MIN=-3.14,-3.14
+     127             :   GRID_MAX=3.14,3.14
+     128             :   GRID_BIN=200,200
+     129             :   BANDWIDTH=0.05,0.05
+     130             :   LABEL=hh
+     131             : ... HISTOGRAM
+     132             : 
+     133             : DUMPGRID GRID=hh FILE=histo
+     134             : \endplumedfile
+     135             : 
+     136             : The following input monitors two torsional angles during a simulation
+     137             : and outputs a discrete histogram as a function of them at the end of the simulation.
+     138             : \plumedfile
+     139             : TORSION ATOMS=1,2,3,4 LABEL=r1
+     140             : TORSION ATOMS=2,3,4,5 LABEL=r2
+     141             : HISTOGRAM ...
+     142             :   ARG=r1,r2
+     143             :   KERNEL=DISCRETE
+     144             :   GRID_MIN=-3.14,-3.14
+     145             :   GRID_MAX=3.14,3.14
+     146             :   GRID_BIN=200,200
+     147             :   LABEL=hh
+     148             : ... HISTOGRAM
+     149             : 
+     150             : DUMPGRID GRID=hh FILE=histo
+     151             : \endplumedfile
+     152             : 
+     153             : The following input monitors two torsional angles during a simulation
+     154             : and outputs the histogram accumulated thus far every 100000 steps.
+     155             : \plumedfile
+     156             : TORSION ATOMS=1,2,3,4 LABEL=r1
+     157             : TORSION ATOMS=2,3,4,5 LABEL=r2
+     158             : HISTOGRAM ...
+     159             :   ARG=r1,r2
+     160             :   GRID_MIN=-3.14,-3.14
+     161             :   GRID_MAX=3.14,3.14
+     162             :   GRID_BIN=200,200
+     163             :   BANDWIDTH=0.05,0.05
+     164             :   LABEL=hh
+     165             : ... HISTOGRAM
+     166             : 
+     167             : DUMPGRID GRID=hh FILE=histo STRIDE=100000
+     168             : \endplumedfile
+     169             : 
+     170             : The following input monitors two torsional angles during a simulation
+     171             : and outputs a separate histogram for each 100000 steps worth of trajectory.
+     172             : Notice how the CLEAR keyword is used here and how it is not used in the
+     173             : previous example.
+     174             : 
+     175             : \plumedfile
+     176             : TORSION ATOMS=1,2,3,4 LABEL=r1
+     177             : TORSION ATOMS=2,3,4,5 LABEL=r2
+     178             : HISTOGRAM ...
+     179             :   ARG=r1,r2 CLEAR=100000
+     180             :   GRID_MIN=-3.14,-3.14
+     181             :   GRID_MAX=3.14,3.14
+     182             :   GRID_BIN=200,200
+     183             :   BANDWIDTH=0.05,0.05
+     184             :   LABEL=hh
+     185             : ... HISTOGRAM
+     186             : 
+     187             : DUMPGRID GRID=hh FILE=histo STRIDE=100000
+     188             : \endplumedfile
+     189             : 
+     190             : */
+     191             : //+ENDPLUMEDOC
+     192             : 
+     193             : namespace PLMD {
+     194             : namespace analysis {
+     195             : 
+     196             : class Histogram : public ActionShortcut {
+     197             : public:
+     198             :   static void registerKeywords( Keywords& keys );
+     199             :   explicit Histogram( const ActionOptions& );
+     200             : };
+     201             : 
+     202             : PLUMED_REGISTER_ACTION(Histogram,"HISTOGRAM")
+     203             : 
+     204          29 : void Histogram::registerKeywords( Keywords& keys ) {
+     205          58 :   ActionShortcut::registerKeywords( keys ); keys.use("UPDATE_FROM"); keys.use("UPDATE_UNTIL");
+     206          58 :   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");
+     207          58 :   keys.add("optional","ARG","the quantity that is being averaged");
+     208          58 :   keys.add("optional","DATA","an alternative to the ARG keyword");
+     209          58 :   keys.add("compulsory","GRID_MIN","auto","the lower bounds for the grid");
+     210          58 :   keys.add("compulsory","GRID_MAX","auto","the upper bounds for the grid");
+     211          58 :   keys.add("optional","BANDWIDTH","the bandwidths for kernel density esimtation");
+     212          58 :   keys.add("compulsory","KERNEL","GAUSSIAN","the kernel function you are using.  More details on  the kernels available "
+     213             :            "in plumed plumed can be found in \\ref kernelfunctions.");
+     214          58 :   keys.add("optional","GRID_BIN","the number of bins for the grid");
+     215          58 :   keys.add("optional","GRID_SPACING","the approximate grid spacing (to be used as an alternative or together with GRID_BIN)");
+     216          58 :   keys.add("optional","LOGWEIGHTS","the logarithm of the quantity to use as the weights when calculating averages");
+     217          58 :   keys.add("compulsory","STRIDE","1","the frequency with which to store data for averaging");
+     218          58 :   keys.add("compulsory","CLEAR","0","the frequency with whihc to clear the data that is being averaged");
+     219          87 :   keys.needsAction("COMBINE"); keys.needsAction("CUSTOM"); keys.needsAction("ONES");
+     220          58 :   keys.needsAction("KDE"); keys.needsAction("ACCUMULATE");
+     221          29 : }
+     222             : 
+     223          22 : Histogram::Histogram( const ActionOptions& ao ):
+     224             :   Action(ao),
+     225          22 :   ActionShortcut(ao)
+     226             : {
+     227          44 :   std::string normflag; parse("NORMALIZATION",normflag);
+     228          88 :   std::string lw; parse("LOGWEIGHTS",lw); std::string stride, clearstride; parse("STRIDE",stride); parse("CLEAR",clearstride);
+     229          28 :   if( lw.length()>0 && normflag!="ndata" ) {
+     230          12 :     readInputLine( getShortcutLabel() + "_wsum: COMBINE ARG=" + lw + " PERIODIC=NO");
+     231          12 :     readInputLine( getShortcutLabel() + "_weight: CUSTOM ARG=" + getShortcutLabel() + "_wsum FUNC=exp(x) PERIODIC=NO");
+     232          32 :   } else readInputLine( getShortcutLabel() + "_weight: ONES SIZE=1" );
+     233             : 
+     234          44 :   std::vector<std::string> arglist; parseVector("ARG",arglist); if( arglist.size()==0 ) parseVector("DATA",arglist);
+     235          22 :   if( arglist.size()==0 ) error("arguments have not been specified use ARG");
+     236          22 :   std::vector<Value*> theargs; ActionWithArguments::interpretArgumentList( arglist, plumed.getActionSet(), this, theargs );
+     237          22 :   plumed_assert( theargs.size()>0 ); std::string argstr=theargs[0]->getName();
+     238          33 :   for(unsigned i=1; i<theargs.size(); ++i) argstr += "," + theargs[i]->getName();
+     239          22 :   std::string strnum; Tools::convert( theargs[0]->getNumberOfValues(), strnum );
+     240          22 :   if( theargs[0]->getNumberOfValues()==1 ) {
+     241             :     // Create the KDE object
+     242          38 :     readInputLine( getShortcutLabel() + "_kde: KDE ARG=" + argstr + " " + convertInputLineToString() );
+     243             :   } else {
+     244             :     // Create the KDE object
+     245           6 :     readInputLine( getShortcutLabel() + "_kde_u: KDE ARG=" + argstr + " " + convertInputLineToString() );
+     246             :     // Normalise the KDE object
+     247           6 :     readInputLine( getShortcutLabel() + "_kde: CUSTOM ARG=" + getShortcutLabel() + "_kde_u PERIODIC=NO FUNC=x/" + strnum );
+     248             :   }
+     249             :   // Now get the quantity to accumulate
+     250          44 :   readInputLine( getShortcutLabel() + "_kdep: CUSTOM ARG=" + getShortcutLabel() + "_kde," + getShortcutLabel() + "_weight FUNC=x*y PERIODIC=NO");
+     251             :   // And accumulate the average
+     252          22 :   if( normflag=="false" ) {
+     253          14 :     readInputLine( getShortcutLabel() + ": ACCUMULATE ARG=" + getShortcutLabel() + "_kdep STRIDE=" + stride + " CLEAR=" + clearstride + " " + getUpdateLimits() );
+     254             :   } else {
+     255          30 :     readInputLine( getShortcutLabel() + "_u: ACCUMULATE ARG=" + getShortcutLabel() + "_kdep STRIDE=" + stride + " CLEAR=" + clearstride + " " + getUpdateLimits() );
+     256          30 :     readInputLine( getShortcutLabel() + "_nsum: ACCUMULATE ARG=" + getShortcutLabel() + "_weight STRIDE=" + stride + " CLEAR=" + clearstride + " " + getUpdateLimits() );
+     257             :     // And divide by the total weight
+     258          30 :     readInputLine( getShortcutLabel() + ": CUSTOM ARG=" + getShortcutLabel() + "_u," + getShortcutLabel() + "_nsum FUNC=x/y PERIODIC=NO");
+     259             :   }
+     260          44 : }
+     261             : 
+     262             : }
+     263             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/LandmarkSelection.cpp.func-sort-c.html b/coverage/analysis/LandmarkSelection.cpp.func-sort-c.html new file mode 100644 index 000000000000..5e63ba6d81c8 --- /dev/null +++ b/coverage/analysis/LandmarkSelection.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - analysis/LandmarkSelection.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - LandmarkSelection.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:6868100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis17LandmarkSelectionC2ERKNS_13ActionOptionsE0
_ZN4PLMD8analysis17LandmarkSelectionC1ERKNS_13ActionOptionsE8
_ZN4PLMD8analysis17LandmarkSelection16registerKeywordsERNS_8KeywordsE17
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/LandmarkSelection.cpp.func.html b/coverage/analysis/LandmarkSelection.cpp.func.html new file mode 100644 index 000000000000..b44f08c891c3 --- /dev/null +++ b/coverage/analysis/LandmarkSelection.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - analysis/LandmarkSelection.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - LandmarkSelection.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:6868100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis17LandmarkSelection16registerKeywordsERNS_8KeywordsE17
_ZN4PLMD8analysis17LandmarkSelectionC1ERKNS_13ActionOptionsE8
_ZN4PLMD8analysis17LandmarkSelectionC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/LandmarkSelection.cpp.gcov.html b/coverage/analysis/LandmarkSelection.cpp.gcov.html new file mode 100644 index 000000000000..65436420adde --- /dev/null +++ b/coverage/analysis/LandmarkSelection.cpp.gcov.html @@ -0,0 +1,236 @@ + + + + + + + + LCOV - plumed test coverage - analysis/LandmarkSelection.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - LandmarkSelection.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:6868100.0 %
Date:2024-04-19 12:12:35Functions:2366.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/ActionShortcut.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "core/ActionWithValue.h"
+      25             : #include "core/ActionPilot.h"
+      26             : #include "core/PlumedMain.h"
+      27             : #include "core/ActionSet.h"
+      28             : 
+      29             : //+PLUMEDOC LANDMARKS LANDMARK_SELECT_STRIDE
+      30             : /*
+      31             : Select every ith frame from the stored data
+      32             : 
+      33             : \par Examples
+      34             : 
+      35             : */
+      36             : //+ENDPLUMEDOC
+      37             : 
+      38             : //+PLUMEDOC LANDMARKS LANDMARK_SELECT_RANDOM
+      39             : /*
+      40             : Select a random set of landmarks from a large set of configurations.
+      41             : 
+      42             : \par Examples
+      43             : 
+      44             : */
+      45             : //+ENDPLUMEDOC
+      46             : 
+      47             : //+PLUMEDOC LANDMARKS LANDMARK_SELECT_FPS
+      48             : /*
+      49             : Select a of landmarks from a large set of configurations using farthest point sampling.
+      50             : 
+      51             : \par Examples
+      52             : 
+      53             : */
+      54             : //+ENDPLUMEDOC
+      55             : 
+      56             : namespace PLMD {
+      57             : namespace analysis {
+      58             : 
+      59             : class LandmarkSelection : public ActionShortcut {
+      60             : public:
+      61             :   static void registerKeywords( Keywords& keys );
+      62             :   explicit LandmarkSelection( const ActionOptions& ao );
+      63             : };
+      64             : 
+      65             : PLUMED_REGISTER_ACTION(LandmarkSelection,"LANDMARK_SELECT_STRIDE")
+      66             : PLUMED_REGISTER_ACTION(LandmarkSelection,"LANDMARK_SELECT_RANDOM")
+      67             : PLUMED_REGISTER_ACTION(LandmarkSelection,"LANDMARK_SELECT_FPS")
+      68             : 
+      69          17 : void LandmarkSelection::registerKeywords( Keywords& keys ) {
+      70          17 :   ActionShortcut::registerKeywords( keys );
+      71          34 :   keys.add("optional","ARG","the COLLECT_FRAMES action that you used to get the data");
+      72          34 :   keys.add("optional","DISSIMILARITIES","the matrix of dissimilarities if this is not provided the squared dissimilarities are calculated");
+      73          34 :   keys.add("compulsory","NLANDMARKS","the numbe rof landmarks you would like to create");
+      74          34 :   keys.add("optional","SEED","a random number seed");
+      75          34 :   keys.addFlag("NOVORONOI",false,"do not do a Voronoi analysis of the data to determine weights of final points");
+      76          34 :   keys.addFlag("NODISSIMILARITIES",false,"do not calculate the dissimilarities");
+      77          34 :   keys.addOutputComponent("data","ARG","the data that is being collected by this action");
+      78          34 :   keys.addOutputComponent("logweights","ARG","the logarithms of the weights of the data points");
+      79          34 :   keys.addOutputComponent("rectdissims","DISSIMILARITIES","a rectangular matrix containing the distances between the landmark points and the rest of the points");
+      80          34 :   keys.addOutputComponent("sqrdissims","DISSIMILARITIES","a square matrix containing the distances between each pair of landmark points");
+      81          51 :   keys.needsAction("LOGSUMEXP"); keys.needsAction("TRANSPOSE"); keys.needsAction("DISSIMILARITIES");
+      82          51 :   keys.needsAction("ONES"); keys.needsAction("CREATE_MASK"); keys.needsAction("FARTHEST_POINT_SAMPLING");
+      83          51 :   keys.needsAction("SELECT_WITH_MASK"); keys.needsAction("COMBINE"); keys.needsAction("VORONOI");
+      84          34 :   keys.needsAction("MATRIX_PRODUCT"); keys.needsAction("CUSTOM");
+      85          17 : }
+      86             : 
+      87           8 : LandmarkSelection::LandmarkSelection( const ActionOptions& ao ):
+      88             :   Action(ao),
+      89           8 :   ActionShortcut(ao)
+      90             : {
+      91          16 :   std::string nlandmarks; parse("NLANDMARKS",nlandmarks); bool novoronoi; parseFlag("NOVORONOI",novoronoi);
+      92             : 
+      93          16 :   bool nodissims; parseFlag("NODISSIMILARITIES",nodissims);
+      94          24 :   std::string argn, dissims; parse("ARG",argn); parse("DISSIMILARITIES",dissims);
+      95           8 :   if( argn.length()>0 ) {
+      96           7 :     ActionShortcut* as = plumed.getActionSet().getShortcutActionWithLabel( argn );
+      97           7 :     if( !as || as->getName()!="COLLECT_FRAMES" ) error("found no COLLECT_FRAMES action with label " + argn );
+      98             :     // Get the weights
+      99          14 :     readInputLine( getShortcutLabel() + "_allweights: LOGSUMEXP ARG=" + argn + "_logweights");
+     100             :   }
+     101           8 :   if( dissims.length()>0 ) {
+     102           4 :     ActionWithValue* ds = plumed.getActionSet().selectWithLabel<ActionWithValue*>( dissims );
+     103           4 :     if( (ds->copyOutput(0))->getRank()!=2 ) error("input for dissimilarities shoudl be a matrix");
+     104             :     // Calculate the dissimilarities if the user didn't specify them
+     105           4 :   } else if( !nodissims ) {
+     106           2 :     readInputLine( getShortcutLabel() + "_" + argn + "_dataT: TRANSPOSE ARG=" + argn + "_data"); dissims = getShortcutLabel() + "_dissims";
+     107           2 :     readInputLine( getShortcutLabel() + "_dissims: DISSIMILARITIES SQUARED ARG=" + argn + "_data," + getShortcutLabel() + "_" + argn + "_dataT");
+     108             :   }
+     109             :   // This deals with a corner case whereby users have a matrix of dissimilarities but no corresponding coordinates for these frames
+     110           8 :   if( argn.length()==0 && dissims.size()>0 ) {
+     111           1 :     ActionWithValue* ds = plumed.getActionSet().selectWithLabel<ActionWithValue*>( dissims );
+     112           1 :     if( ds->getName()!="CONSTANT" || (ds->copyOutput(0))->getRank()!=2 ) error("set ARG as well as DISSIMILARITIES");
+     113           1 :     std::string size; Tools::convert(  (ds->copyOutput(0))->getShape()[0], size );
+     114           2 :     readInputLine( getShortcutLabel() + "_allweights: ONES SIZE=" + size );
+     115             :   }
+     116             : 
+     117           8 :   if( getName()=="LANDMARK_SELECT_STRIDE" ) {
+     118          12 :     readInputLine( getShortcutLabel() + "_mask: CREATE_MASK ARG=" + getShortcutLabel() + "_allweights TYPE=stride NZEROS=" + nlandmarks );
+     119           2 :   } else if( getName()=="LANDMARK_SELECT_RANDOM" ) {
+     120           1 :     if( argn.length()==0 ) error("must set COLLECT_FRAMES object for landmark selection using ARG keyword");
+     121           3 :     std::string seed; parse("SEED",seed); if( seed.length()>0 ) seed = " SEED=" + seed;
+     122           2 :     readInputLine( getShortcutLabel() + "_mask: CREATE_MASK ARG=" + getShortcutLabel() + "_allweights TYPE=random NZEROS=" + nlandmarks + seed );
+     123           1 :   } else if( getName()=="LANDMARK_SELECT_FPS" ) {
+     124           1 :     if( dissims.length()==0 ) error("dissimiarities must be defined to use FPS sampling");
+     125           2 :     std::string seed; parse("SEED",seed); if( seed.length()>0 ) seed = " SEED=" + seed;
+     126           2 :     readInputLine( getShortcutLabel() + "_mask: FARTHEST_POINT_SAMPLING ARG=" + dissims + " NZEROS=" + nlandmarks + seed );
+     127             :   }
+     128             : 
+     129          15 :   if( argn.length()>0 ) readInputLine( getShortcutLabel() + "_data: SELECT_WITH_MASK ARG=" + argn + "_data ROW_MASK=" + getShortcutLabel() + "_mask");
+     130             : 
+     131           8 :   unsigned nland; Tools::convert( nlandmarks, nland );
+     132           8 :   if( dissims.length()>0 ) {
+     133           5 :     ActionWithValue* ds = plumed.getActionSet().selectWithLabel<ActionWithValue*>( dissims );
+     134           5 :     if( (ds->copyOutput(0))->getShape()[0]==nland ) {
+     135           1 :       if( !novoronoi ) { warning("cannot use voronoi procedure to give weights as not all distances between points are known"); novoronoi=true; }
+     136           2 :       readInputLine( getShortcutLabel() + "_sqrdissims: COMBINE ARG=" + dissims + " PERIODIC=NO");
+     137             :     } else {
+     138           8 :       readInputLine( getShortcutLabel() + "_rmask: CREATE_MASK ARG=" + getShortcutLabel() + "_allweights TYPE=nomask");
+     139           8 :       readInputLine( getShortcutLabel() + "_rectdissims: SELECT_WITH_MASK ARG=" + dissims + " COLUMN_MASK=" + getShortcutLabel() + "_mask ROW_MASK=" + getShortcutLabel() + "_rmask");
+     140           8 :       readInputLine( getShortcutLabel() + "_sqrdissims: SELECT_WITH_MASK ARG=" + dissims + " ROW_MASK=" + getShortcutLabel() + "_mask COLUMN_MASK=" + getShortcutLabel() + "_mask");
+     141             :     }
+     142             :   }
+     143             : 
+     144           8 :   if( !novoronoi && argn.length()>0 && dissims.length()>0 ) {
+     145           6 :     readInputLine( getShortcutLabel() + "_voronoi: VORONOI ARG=" + getShortcutLabel() + "_rectdissims");
+     146           6 :     readInputLine( getShortcutLabel() + "_allweightsT: TRANSPOSE ARG=" + getShortcutLabel() + "_allweights");
+     147           6 :     readInputLine( getShortcutLabel() + "_weightsT: MATRIX_PRODUCT ARG=" + getShortcutLabel() + "_allweightsT," + getShortcutLabel() + "_voronoi");
+     148           6 :     readInputLine( getShortcutLabel() + "_weights: TRANSPOSE ARG=" + getShortcutLabel() + "_weightsT");
+     149           6 :     readInputLine( getShortcutLabel() + "_logweights: CUSTOM ARG=" + getShortcutLabel() + "_weights FUNC=log(x) PERIODIC=NO");
+     150           5 :   } else if( argn.length()>0 ) {
+     151           4 :     if( !novoronoi ) warning("cannot use voronoi procedure to give weights to landmark points as DISSIMILARITIES was not set");
+     152           8 :     readInputLine( getShortcutLabel() + "_logweights: SELECT_WITH_MASK ARG=" + argn + "_logweights MASK=" + getShortcutLabel() + "_mask");
+     153             :   }
+     154             :   // Create the vector of ones that is needed by Classical MDS
+     155          15 :   if( argn.length()>0 ) readInputLine( getShortcutLabel() + "_ones: SELECT_WITH_MASK ARG=" + argn + "_ones MASK=" + getShortcutLabel() + "_mask");
+     156           8 : }
+     157             : 
+     158             : }
+     159             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/LogSumExp.cpp.func-sort-c.html b/coverage/analysis/LogSumExp.cpp.func-sort-c.html new file mode 100644 index 000000000000..7d9d3ffb6030 --- /dev/null +++ b/coverage/analysis/LogSumExp.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - analysis/LogSumExp.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - LogSumExp.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1515100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis9LogSumExpC2ERKNS_13ActionOptionsE0
_ZN4PLMD8analysis9LogSumExpC1ERKNS_13ActionOptionsE9
_ZN4PLMD8analysis9LogSumExp16registerKeywordsERNS_8KeywordsE11
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/LogSumExp.cpp.func.html b/coverage/analysis/LogSumExp.cpp.func.html new file mode 100644 index 000000000000..b7024466b390 --- /dev/null +++ b/coverage/analysis/LogSumExp.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - analysis/LogSumExp.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - LogSumExp.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1515100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis9LogSumExp16registerKeywordsERNS_8KeywordsE11
_ZN4PLMD8analysis9LogSumExpC1ERKNS_13ActionOptionsE9
_ZN4PLMD8analysis9LogSumExpC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/LogSumExp.cpp.gcov.html b/coverage/analysis/LogSumExp.cpp.gcov.html new file mode 100644 index 000000000000..f3b99c35958e --- /dev/null +++ b/coverage/analysis/LogSumExp.cpp.gcov.html @@ -0,0 +1,153 @@ + + + + + + + + LCOV - plumed test coverage - analysis/LogSumExp.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - LogSumExp.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1515100.0 %
Date:2024-04-19 12:12:35Functions:2366.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/ActionShortcut.h"
+      23             : #include "core/ActionRegister.h"
+      24             : 
+      25             : //+PLUMEDOC ANALYSIS LOGSUMEXP
+      26             : /*
+      27             : This action takes the exponential of a vector of logarithms and divides each element of the vector by the sum of the exponentials.
+      28             : 
+      29             : The log-exp-sum trick is used here
+      30             : 
+      31             : \par Examples
+      32             : 
+      33             : */
+      34             : //+ENDPLUMEDOC
+      35             : 
+      36             : namespace PLMD {
+      37             : namespace analysis {
+      38             : 
+      39             : class LogSumExp : public ActionShortcut {
+      40             : private:
+      41             :   std::string fixArgumentName( const std::string& argin );
+      42             : public:
+      43             :   static void registerKeywords( Keywords& keys );
+      44             :   explicit LogSumExp( const ActionOptions& ao );
+      45             : };
+      46             : 
+      47             : PLUMED_REGISTER_ACTION(LogSumExp,"LOGSUMEXP")
+      48             : 
+      49          11 : void LogSumExp::registerKeywords( Keywords& keys ) {
+      50          11 :   ActionShortcut::registerKeywords( keys );
+      51          22 :   keys.add("compulsory","ARG","the vector of logweights that you would like to normalise using the logsumexp trick");
+      52          33 :   keys.needsAction("HIGHEST"); keys.needsAction("CUSTOM"); keys.needsAction("SUM");
+      53          11 : }
+      54             : 
+      55             : 
+      56           9 : LogSumExp::LogSumExp( const ActionOptions& ao ):
+      57             :   Action(ao),
+      58           9 :   ActionShortcut(ao)
+      59             : {
+      60             :   // Find the argument name
+      61           9 :   std::string argn; parse("ARG",argn);
+      62             :   // Find the maximum weight
+      63          18 :   readInputLine( getShortcutLabel() + "_maxlogweight: HIGHEST ARG=" + argn );
+      64          18 :   readInputLine( getShortcutLabel() + "_maxweight: CUSTOM ARG=" + getShortcutLabel() + "_maxlogweight FUNC=exp(x) PERIODIC=NO");
+      65             :   // Calculate the maximum
+      66          18 :   readInputLine( getShortcutLabel() + "_shiftw: CUSTOM ARG=" + argn + "," + getShortcutLabel() + "_maxlogweight FUNC=exp(x-y) PERIODIC=NO");
+      67             :   // compute the sum of all the exponentials
+      68          18 :   readInputLine( getShortcutLabel() + "_sumw: SUM ARG=" + getShortcutLabel() + "_shiftw PERIODIC=NO");
+      69             :   // and the logsum
+      70          18 :   readInputLine( getShortcutLabel() + "_logsum: CUSTOM ARG=" + getShortcutLabel() + "_sumw," + getShortcutLabel() + "_maxlogweight FUNC=y+log(x) PERIODIC=NO");
+      71             :   // And the final weights
+      72          18 :   readInputLine( getShortcutLabel() + ": CUSTOM ARG=" + argn + "," +  getShortcutLabel() + "_logsum FUNC=exp(x-y) PERIODIC=NO");
+      73           9 : }
+      74             : 
+      75             : }
+      76             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/Wham.cpp.func-sort-c.html b/coverage/analysis/Wham.cpp.func-sort-c.html new file mode 100644 index 000000000000..e14254479649 --- /dev/null +++ b/coverage/analysis/Wham.cpp.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - analysis/Wham.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - Wham.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:434693.5 %
Date:2024-04-19 12:12:35Functions:3650.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis4Wham22getNumberOfDerivativesEv0
_ZN4PLMD8analysis4Wham5applyEv0
_ZN4PLMD8analysis4WhamC2ERKNS_13ActionOptionsE0
_ZN4PLMD8analysis4Wham9calculateEv12
_ZN4PLMD8analysis4WhamC1ERKNS_13ActionOptionsE12
_ZN4PLMD8analysis4Wham16registerKeywordsERNS_8KeywordsE14
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/Wham.cpp.func.html b/coverage/analysis/Wham.cpp.func.html new file mode 100644 index 000000000000..4980fa7e30b0 --- /dev/null +++ b/coverage/analysis/Wham.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - analysis/Wham.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - Wham.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:434693.5 %
Date:2024-04-19 12:12:35Functions:3650.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis4Wham16registerKeywordsERNS_8KeywordsE14
_ZN4PLMD8analysis4Wham22getNumberOfDerivativesEv0
_ZN4PLMD8analysis4Wham5applyEv0
_ZN4PLMD8analysis4Wham9calculateEv12
_ZN4PLMD8analysis4WhamC1ERKNS_13ActionOptionsE12
_ZN4PLMD8analysis4WhamC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/Wham.cpp.gcov.html b/coverage/analysis/Wham.cpp.gcov.html new file mode 100644 index 000000000000..117ec790a0ea --- /dev/null +++ b/coverage/analysis/Wham.cpp.gcov.html @@ -0,0 +1,247 @@ + + + + + + + + LCOV - plumed test coverage - analysis/Wham.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - Wham.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:434693.5 %
Date:2024-04-19 12:12:35Functions:3650.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2017-2020 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received 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/ActionWithValue.h"
+      24             : #include "core/ActionWithArguments.h"
+      25             : #include "core/PlumedMain.h"
+      26             : #include "tools/Communicator.h"
+      27             : 
+      28             : //+PLUMEDOC REWEIGHTING WHAM
+      29             : /*
+      30             : Calculate the weights for configurations using the weighted histogram analysis method.
+      31             : 
+      32             : 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
+      33             : the set of configurations during the \f$N\f$ trajectories that we ran using the product of multinomial distributions shown below:
+      34             : \f[
+      35             : P( \vec{T} ) \propto \prod_{j=1}^M \prod_{k=1}^N (c_k w_{kj} p_j)^{t_{kj}}
+      36             : \label{eqn:wham1}
+      37             : \f]
+      38             : 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
+      39             : \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
+      40             : having a set of CV values that lie within the range for the \f$j\f$th bin.
+      41             : 
+      42             : 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.
+      43             : 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:
+      44             : \f[
+      45             : w_{kj} =
+      46             : \f]
+      47             : 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
+      48             : 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
+      49             : 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.
+      50             : 
+      51             : 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.
+      52             : 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
+      53             : 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
+      54             : we actually chose to minimize
+      55             : \f[
+      56             : \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)
+      57             : \f]
+      58             : After some manipulations the following (WHAM) equations emerge:
+      59             : \f[
+      60             : \begin{aligned}
+      61             : p_j & \propto \frac{\sum_{k=1}^N t_{kj}}{\sum_k c_k w_{kj}} \\
+      62             : c_k & =\frac{1}{\sum_{j=1}^M w_{kj} p_j}
+      63             : \end{aligned}
+      64             : \f]
+      65             : 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
+      66             : 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.
+      67             : 
+      68             : 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.
+      69             : 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.
+      70             : This observation is important as it is the basis of the binless formulation of WHAM that is implemented within PLUMED.
+      71             : 
+      72             : \par Examples
+      73             : 
+      74             : */
+      75             : //+ENDPLUMEDOC
+      76             : 
+      77             : namespace PLMD {
+      78             : namespace analysis {
+      79             : 
+      80             : class Wham :
+      81             :   public ActionWithValue,
+      82             :   public ActionWithArguments {
+      83             : private:
+      84             :   double thresh, simtemp;
+      85             :   unsigned nreplicas;
+      86             :   unsigned maxiter;
+      87             : public:
+      88             :   static void registerKeywords(Keywords&);
+      89             :   explicit Wham(const ActionOptions&ao);
+      90           0 :   unsigned getNumberOfDerivatives() { return 0; }
+      91             :   void calculate() override ;
+      92           0 :   void apply() override {}
+      93             : };
+      94             : 
+      95             : PLUMED_REGISTER_ACTION(Wham,"WHAM")
+      96             : 
+      97          14 : void Wham::registerKeywords(Keywords& keys ) {
+      98          14 :   Action::registerKeywords( keys ); ActionWithValue::registerKeywords( keys );
+      99          14 :   ActionWithArguments::registerKeywords( keys ); keys.remove("ARG");
+     100          28 :   keys.add("compulsory","ARG","the stored values for the bias");
+     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          28 :   keys.add("optional","TEMP","the system temperature.  This is not required if your MD code passes this quantity to PLUMED");
+     104          14 :   keys.remove("NUMERICAL_DERIVATIVES");
+     105          14 : }
+     106             : 
+     107          12 : Wham::Wham(const ActionOptions&ao):
+     108             :   Action(ao),
+     109             :   ActionWithValue(ao),
+     110          12 :   ActionWithArguments(ao)
+     111             : {
+     112             :   // Read in the temperature
+     113          12 :   simtemp=getkBT();
+     114          12 :   if(simtemp==0) error("The MD engine does not pass the temperature to plumed so you have to specify it using TEMP");
+     115             :   // Now read in parameters of WHAM
+     116          24 :   parse("MAXITER",maxiter); parse("WHAMTOL",thresh);
+     117          12 :   if(comm.Get_rank()==0) nreplicas=multi_sim_comm.Get_size();
+     118          12 :   comm.Bcast(nreplicas,0); addValue( getPntrToArgument(0)->getShape() ); setNotPeriodic();
+     119          12 : }
+     120             : 
+     121          12 : void Wham::calculate() {
+     122             :   // Retrieve the values that were stored for the biase
+     123          12 :   std::vector<double> stored_biases( getPntrToArgument(0)->getNumberOfValues() );
+     124       25284 :   for(unsigned i=0; i<stored_biases.size(); ++i) stored_biases[i] = getPntrToArgument(0)->get(i);
+     125             :   // Get the minimum value of the bias
+     126          12 :   double minv = *min_element(std::begin(stored_biases), std::end(stored_biases));
+     127             :   // Resize final weights array
+     128          12 :   plumed_assert( stored_biases.size()%nreplicas==0 );
+     129          12 :   std::vector<double> final_weights( stored_biases.size() / nreplicas, 1.0 );
+     130          12 :   if( getPntrToComponent(0)->getNumberOfValues()!=final_weights.size() ) {
+     131          12 :     std::vector<unsigned> shape(1); shape[0]=final_weights.size(); getPntrToComponent(0)->setShape( shape );
+     132             :   }
+     133             :   // Offset and exponential of the bias
+     134          12 :   std::vector<double> expv( stored_biases.size() );
+     135       25284 :   for(unsigned i=0; i<expv.size(); ++i) expv[i] = exp( (-stored_biases[i]+minv) / simtemp );
+     136             :   // Initialize Z
+     137          12 :   std::vector<double> Z( nreplicas, 1.0 ), oldZ( nreplicas );
+     138             :   // Now the iterative loop to calculate the WHAM weights
+     139        4584 :   for(unsigned iter=0; iter<maxiter; ++iter) {
+     140             :     // Store Z
+     141       32088 :     for(unsigned j=0; j<Z.size(); ++j) oldZ[j]=Z[j];
+     142             :     // Recompute weights
+     143             :     double norm=0;
+     144     1613568 :     for(unsigned j=0; j<final_weights.size(); ++j) {
+     145             :       double ew=0;
+     146    11262888 :       for(unsigned k=0; k<Z.size(); ++k) ew += expv[j*Z.size()+k]  / Z[k];
+     147     1608984 :       final_weights[j] = 1.0 / ew; norm += final_weights[j];
+     148             :     }
+     149             :     // Normalize weights
+     150     1613568 :     for(unsigned j=0; j<final_weights.size(); ++j) final_weights[j] /= norm;
+     151             :     // Recompute Z
+     152       32088 :     for(unsigned j=0; j<Z.size(); ++j) Z[j] = 0.0;
+     153     1613568 :     for(unsigned j=0; j<final_weights.size(); ++j) {
+     154    11262888 :       for(unsigned k=0; k<Z.size(); ++k) Z[k] += final_weights[j]*expv[j*Z.size()+k];
+     155             :     }
+     156             :     // Normalize Z and compute change in Z
+     157       32088 :     double change=0; norm=0; for(unsigned k=0; k<Z.size(); ++k) norm+=Z[k];
+     158       32088 :     for(unsigned k=0; k<Z.size(); ++k) {
+     159       27504 :       Z[k] /= norm; double d = std::log( Z[k] / oldZ[k] ); change += d*d;
+     160             :     }
+     161        4584 :     if( change<thresh ) {
+     162        4224 :       for(unsigned j=0; j<final_weights.size(); ++j) getPntrToComponent(0)->set( j, final_weights[j] );
+     163          12 :       return;
+     164             :     }
+     165             :   }
+     166           0 :   error("Too many iterations in WHAM" );
+     167             : }
+     168             : 
+     169             : }
+     170             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/WhamHistogram.cpp.func-sort-c.html b/coverage/analysis/WhamHistogram.cpp.func-sort-c.html new file mode 100644 index 000000000000..f2c255ba02f3 --- /dev/null +++ b/coverage/analysis/WhamHistogram.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - analysis/WhamHistogram.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - WhamHistogram.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3434100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis13WhamHistogram16registerKeywordsERNS_8KeywordsE8
_ZN4PLMD8analysis13WhamHistogramC1ERKNS_13ActionOptionsE6
_ZN4PLMD8analysis13WhamHistogramC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/WhamHistogram.cpp.gcov.html b/coverage/analysis/WhamHistogram.cpp.gcov.html new file mode 100644 index 000000000000..cc0f093b781d --- /dev/null +++ b/coverage/analysis/WhamHistogram.cpp.gcov.html @@ -0,0 +1,211 @@ + + + + + + + + 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:3434100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ + + + + + + + +

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

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

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

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

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Wham.cpp +
93.5%93.5%
+
93.5 %43 / 4650.0 %3 / 6
FarthestPointSampling.cpp +
92.5%92.5%
+
92.5 %37 / 4050.0 %4 / 8
WhamWeights.cpp +
100.0%
+
100.0 %22 / 2266.7 %2 / 3
Histogram.cpp +
100.0%
+
100.0 %42 / 4266.7 %2 / 3
LogSumExp.cpp +
100.0%
+
100.0 %15 / 1566.7 %2 / 3
WhamHistogram.cpp +
100.0%
+
100.0 %34 / 3466.7 %2 / 3
LandmarkSelection.cpp +
100.0%
+
100.0 %68 / 6866.7 %2 / 3
Average.cpp +
100.0%
+
100.0 %30 / 3066.7 %2 / 3
GatherReplicas.cpp +
85.0%85.0%
+
85.0 %34 / 4066.7 %4 / 6
CreateMask.cpp +
94.3%94.3%
+
94.3 %50 / 5371.4 %5 / 7
CollectFrames.cpp +
96.8%96.8%
+
96.8 %60 / 6275.0 %3 / 4
Collect.cpp +
96.2%96.2%
+
96.2 %51 / 5377.8 %7 / 9
Committor.cpp +
100.0%
+
100.0 %73 / 7380.0 %4 / 5
Accumulate.cpp +
95.0%95.0%
+
95.0 %38 / 4088.9 %8 / 9
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/index-sort-l.html b/coverage/analysis/index-sort-l.html new file mode 100644 index 000000000000..a28f5d644f2f --- /dev/null +++ b/coverage/analysis/index-sort-l.html @@ -0,0 +1,224 @@ + + + + + + + + LCOV - plumed test coverage - analysis + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysisHitTotalCoverage
Test:plumed test coverageLines:59761896.6 %
Date:2024-04-19 12:12:35Functions:507269.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
GatherReplicas.cpp +
85.0%85.0%
+
85.0 %34 / 4066.7 %4 / 6
FarthestPointSampling.cpp +
92.5%92.5%
+
92.5 %37 / 4050.0 %4 / 8
Wham.cpp +
93.5%93.5%
+
93.5 %43 / 4650.0 %3 / 6
CreateMask.cpp +
94.3%94.3%
+
94.3 %50 / 5371.4 %5 / 7
Accumulate.cpp +
95.0%95.0%
+
95.0 %38 / 4088.9 %8 / 9
Collect.cpp +
96.2%96.2%
+
96.2 %51 / 5377.8 %7 / 9
CollectFrames.cpp +
96.8%96.8%
+
96.8 %60 / 6275.0 %3 / 4
LogSumExp.cpp +
100.0%
+
100.0 %15 / 1566.7 %2 / 3
WhamWeights.cpp +
100.0%
+
100.0 %22 / 2266.7 %2 / 3
Average.cpp +
100.0%
+
100.0 %30 / 3066.7 %2 / 3
WhamHistogram.cpp +
100.0%
+
100.0 %34 / 3466.7 %2 / 3
Histogram.cpp +
100.0%
+
100.0 %42 / 4266.7 %2 / 3
LandmarkSelection.cpp +
100.0%
+
100.0 %68 / 6866.7 %2 / 3
Committor.cpp +
100.0%
+
100.0 %73 / 7380.0 %4 / 5
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/index.html b/coverage/analysis/index.html new file mode 100644 index 000000000000..957fee675a13 --- /dev/null +++ b/coverage/analysis/index.html @@ -0,0 +1,224 @@ + + + + + + + + LCOV - plumed test coverage - analysis + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysisHitTotalCoverage
Test:plumed test coverageLines:59761896.6 %
Date:2024-04-19 12:12:35Functions:507269.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Accumulate.cpp +
95.0%95.0%
+
95.0 %38 / 4088.9 %8 / 9
Average.cpp +
100.0%
+
100.0 %30 / 3066.7 %2 / 3
Collect.cpp +
96.2%96.2%
+
96.2 %51 / 5377.8 %7 / 9
CollectFrames.cpp +
96.8%96.8%
+
96.8 %60 / 6275.0 %3 / 4
Committor.cpp +
100.0%
+
100.0 %73 / 7380.0 %4 / 5
CreateMask.cpp +
94.3%94.3%
+
94.3 %50 / 5371.4 %5 / 7
FarthestPointSampling.cpp +
92.5%92.5%
+
92.5 %37 / 4050.0 %4 / 8
GatherReplicas.cpp +
85.0%85.0%
+
85.0 %34 / 4066.7 %4 / 6
Histogram.cpp +
100.0%
+
100.0 %42 / 4266.7 %2 / 3
LandmarkSelection.cpp +
100.0%
+
100.0 %68 / 6866.7 %2 / 3
LogSumExp.cpp +
100.0%
+
100.0 %15 / 1566.7 %2 / 3
Wham.cpp +
93.5%93.5%
+
93.5 %43 / 4650.0 %3 / 6
WhamHistogram.cpp +
100.0%
+
100.0 %34 / 3466.7 %2 / 3
WhamWeights.cpp +
100.0%
+
100.0 %22 / 2266.7 %2 / 3
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/annfunc/ANN.cpp.func-sort-c.html b/coverage/annfunc/ANN.cpp.func-sort-c.html new file mode 100644 index 000000000000..d4e794e931c7 --- /dev/null +++ b/coverage/annfunc/ANN.cpp.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - annfunc/ANN.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - annfunc - ANN.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:13313797.1 %
Date:2024-04-19 12:12:35Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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

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

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

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

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

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

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

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

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias4BiasC1ERKNS_13ActionOptionsE0
_ZN4PLMD4bias4BiasC2ERKNS_13ActionOptionsE872
_ZN4PLMD4bias4Bias16registerKeywordsERNS_8KeywordsE923
_ZN4PLMD4bias4Bias5applyEv99118
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/Bias.cpp.func.html b/coverage/bias/Bias.cpp.func.html new file mode 100644 index 000000000000..8200165d8a9b --- /dev/null +++ b/coverage/bias/Bias.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - bias/Bias.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - Bias.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3737100.0 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias4Bias16registerKeywordsERNS_8KeywordsE923
_ZN4PLMD4bias4Bias5applyEv99118
_ZN4PLMD4bias4BiasC1ERKNS_13ActionOptionsE0
_ZN4PLMD4bias4BiasC2ERKNS_13ActionOptionsE872
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/Bias.cpp.gcov.html b/coverage/bias/Bias.cpp.gcov.html new file mode 100644 index 000000000000..a335e2fb2f48 --- /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-04-19 12:12:35Functions: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         872 : Bias::Bias(const ActionOptions&ao):
+      29             :   Action(ao),
+      30             :   ActionPilot(ao),
+      31             :   ActionWithValue(ao),
+      32             :   ActionWithArguments(ao),
+      33         872 :   outputForces(getNumberOfArguments(),0.0)
+      34             : {
+      35        1744 :   addComponentWithDerivatives("bias");
+      36         872 :   componentIsNotPeriodic("bias");
+      37         872 :   valueBias=getPntrToComponent("bias");
+      38             : 
+      39         872 :   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        4924 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+      44        4052 :     (getPntrToArgument(i)->getPntrToAction())->turnOnDerivatives();
+      45             :   }
+      46             : 
+      47         872 :   ActionWithValue::turnOnDerivatives();
+      48         872 : }
+      49             : 
+      50         923 : void Bias::registerKeywords( Keywords& keys ) {
+      51         923 :   Action::registerKeywords(keys);
+      52         923 :   ActionPilot::registerKeywords(keys);
+      53         923 :   ActionWithValue::registerKeywords(keys);
+      54         923 :   ActionWithArguments::registerKeywords(keys);
+      55        1846 :   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         923 :   componentsAreNotOptional(keys);
+      57        1846 :   keys.addOutputComponent("bias","default","the instantaneous value of the bias potential");
+      58         923 : }
+      59             : 
+      60       99118 : void Bias::apply() {
+      61       99118 :   const unsigned noa=getNumberOfArguments();
+      62       99118 :   const unsigned ncp=getNumberOfComponents();
+      63             : 
+      64       99118 :   if(onStep()) {
+      65       99118 :     double gstr = static_cast<double>(getStride());
+      66      273333 :     for(unsigned i=0; i<noa; ++i) {
+      67      174215 :       getPntrToArgument(i)->addForce(gstr*outputForces[i]);
+      68             :     }
+      69             :   }
+      70             : 
+      71       99118 :   f.assign(noa,0.0);
+      72       99118 :   forces.resize(noa);
+      73             : 
+      74             :   bool at_least_one_forced=false;
+      75      467604 :   for(unsigned i=0; i<ncp; ++i) {
+      76      368486 :     if(getPntrToComponent(i)->applyForce(forces)) {
+      77             :       at_least_one_forced=true;
+      78         913 :       for(unsigned j=0; j<noa; j++) f[j]+=forces[j];
+      79             :     }
+      80             :   }
+      81             : 
+      82       99118 :   if(at_least_one_forced && !onStep()) error("you are biasing a bias with an inconsistent STRIDE");
+      83             : 
+      84       99959 :   if(at_least_one_forced) for(unsigned i=0; i<noa; ++i) {
+      85         559 :       getPntrToArgument(i)->addForce(f[i]);
+      86             :     }
+      87             : 
+      88       99118 : }
+      89             : 
+      90             : }
+      91             : }
+      92             : 
+      93             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/Bias.h.func-sort-c.html b/coverage/bias/Bias.h.func-sort-c.html new file mode 100644 index 000000000000..512adc2df5a3 --- /dev/null +++ b/coverage/bias/Bias.h.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - bias/Bias.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - Bias.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:99100.0 %
Date:2024-04-19 12:12:35Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias4Bias22getNumberOfDerivativesEv978
_ZN4PLMD4bias4Bias7setBiasEd98858
_ZN4PLMD4bias4Bias14setOutputForceEid173217
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/Bias.h.func.html b/coverage/bias/Bias.h.func.html new file mode 100644 index 000000000000..00f8350215bc --- /dev/null +++ b/coverage/bias/Bias.h.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - bias/Bias.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - Bias.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:99100.0 %
Date:2024-04-19 12:12:35Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias4Bias14setOutputForceEid173217
_ZN4PLMD4bias4Bias22getNumberOfDerivativesEv978
_ZN4PLMD4bias4Bias7setBiasEd98858
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/Bias.h.gcov.html b/coverage/bias/Bias.h.gcov.html new file mode 100644 index 000000000000..b85300f8436d --- /dev/null +++ b/coverage/bias/Bias.h.gcov.html @@ -0,0 +1,160 @@ + + + + + + + + LCOV - plumed test coverage - bias/Bias.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - Bias.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:99100.0 %
Date:2024-04-19 12:12:35Functions:33100.0 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias9BiasValueC2ERKNS_13ActionOptionsE0
_ZN4PLMD4bias9BiasValueC1ERKNS_13ActionOptionsE204
_ZN4PLMD4bias9BiasValue16registerKeywordsERNS_8KeywordsE206
_ZN4PLMD4bias9BiasValue9calculateEv34866
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/BiasValue.cpp.func.html b/coverage/bias/BiasValue.cpp.func.html new file mode 100644 index 000000000000..5ecbdeffb50e --- /dev/null +++ b/coverage/bias/BiasValue.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - bias/BiasValue.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - BiasValue.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2020100.0 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias9BiasValue16registerKeywordsERNS_8KeywordsE206
_ZN4PLMD4bias9BiasValue9calculateEv34866
_ZN4PLMD4bias9BiasValueC1ERKNS_13ActionOptionsE204
_ZN4PLMD4bias9BiasValueC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/BiasValue.cpp.gcov.html b/coverage/bias/BiasValue.cpp.gcov.html new file mode 100644 index 000000000000..897ac7a6d4ce --- /dev/null +++ b/coverage/bias/BiasValue.cpp.gcov.html @@ -0,0 +1,194 @@ + + + + + + + + LCOV - plumed test coverage - bias/BiasValue.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - BiasValue.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2020100.0 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ + + + + + + + +

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias5MetaD11addGaussianERKNS1_8GaussianE5931
_ZN4PLMD4bias5MetaD11scanOneHillEPNS_5IFileERSt6vectorINS_5ValueESaIS5_EERS4_IdSaIdEESB_RdRb8881
_ZN4PLMD4bias5MetaD11updateNlistEv4
_ZN4PLMD4bias5MetaD12temperHeightERdRKNS1_14TemperingSpecsEd60
_ZN4PLMD4bias5MetaD13readGaussiansEPNS_5IFileE6034
_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_2408333
_ZN4PLMD4bias5MetaD6updateEv6239
_ZN4PLMD4bias5MetaD7getBiasERKSt6vectorIdSaIdEE285
_ZN4PLMD4bias5MetaD8GaussianC2EbdRKSt6vectorIdSaIdEES7_5931
_ZN4PLMD4bias5MetaD9calculateEv8435
_ZN4PLMD4bias5MetaD9getHeightERKSt6vectorIdSaIdEE2736
_ZN4PLMD4bias5MetaDC1ERKNS_13ActionOptionsE157
_ZN4PLMD4bias5MetaDC2ERKNS_13ActionOptionsE0
_ZNK4PLMD4bias5MetaD19checkNeedsGradientsEv8435
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/MetaD.cpp.gcov.html b/coverage/bias/MetaD.cpp.gcov.html new file mode 100644 index 000000000000..fb65ed1f0d37 --- /dev/null +++ b/coverage/bias/MetaD.cpp.gcov.html @@ -0,0 +1,2381 @@ + + + + + + + + LCOV - plumed test coverage - bias/MetaD.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - MetaD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:950107788.2 %
Date:2024-04-19 12:12:35Functions:262892.9 %
+
+ + + + + + + + +

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

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias15MovingRestraint16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD4bias15MovingRestraint9calculateEv566
_ZN4PLMD4bias15MovingRestraintC1ERKNS_13ActionOptionsE4
_ZN4PLMD4bias15MovingRestraintC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/MovingRestraint.cpp.gcov.html b/coverage/bias/MovingRestraint.cpp.gcov.html new file mode 100644 index 000000000000..7183378a1518 --- /dev/null +++ b/coverage/bias/MovingRestraint.cpp.gcov.html @@ -0,0 +1,357 @@ + + + + + + + + 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:109109100.0 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ + + + + + + + +

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

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

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

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias9RestraintC2ERKNS_13ActionOptionsE0
_ZN4PLMD4bias9RestraintC1ERKNS_13ActionOptionsE203
_ZN4PLMD4bias9Restraint16registerKeywordsERNS_8KeywordsE205
_ZN4PLMD4bias9Restraint9calculateEv4799
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/Restraint.cpp.func.html b/coverage/bias/Restraint.cpp.func.html new file mode 100644 index 000000000000..8e03e60e4c3d --- /dev/null +++ b/coverage/bias/Restraint.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - bias/Restraint.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - Restraint.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4141100.0 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias9Restraint16registerKeywordsERNS_8KeywordsE205
_ZN4PLMD4bias9Restraint9calculateEv4799
_ZN4PLMD4bias9RestraintC1ERKNS_13ActionOptionsE203
_ZN4PLMD4bias9RestraintC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/Restraint.cpp.gcov.html b/coverage/bias/Restraint.cpp.gcov.html new file mode 100644 index 000000000000..7b39ec6372a6 --- /dev/null +++ b/coverage/bias/Restraint.cpp.gcov.html @@ -0,0 +1,213 @@ + + + + + + + + LCOV - plumed test coverage - bias/Restraint.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - Restraint.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4141100.0 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias17RestraintShortcutC2ERKNS_13ActionOptionsE0
_ZN4PLMD4bias17RestraintShortcutC1ERKNS_13ActionOptionsE207
_ZN4PLMD4bias17RestraintShortcut16registerKeywordsERNS_8KeywordsE236
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/RestraintShortcut.cpp.func.html b/coverage/bias/RestraintShortcut.cpp.func.html new file mode 100644 index 000000000000..09fca98c5128 --- /dev/null +++ b/coverage/bias/RestraintShortcut.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - bias/RestraintShortcut.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - RestraintShortcut.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:454893.8 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias17RestraintShortcut16registerKeywordsERNS_8KeywordsE236
_ZN4PLMD4bias17RestraintShortcutC1ERKNS_13ActionOptionsE207
_ZN4PLMD4bias17RestraintShortcutC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/RestraintShortcut.cpp.gcov.html b/coverage/bias/RestraintShortcut.cpp.gcov.html new file mode 100644 index 000000000000..7f256cb36fbb --- /dev/null +++ b/coverage/bias/RestraintShortcut.cpp.gcov.html @@ -0,0 +1,186 @@ + + + + + + + + LCOV - plumed test coverage - bias/RestraintShortcut.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - RestraintShortcut.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:454893.8 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2020 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received 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/ActionShortcut.h"
+      24             : #include "core/PlumedMain.h"
+      25             : #include "core/ActionSet.h"
+      26             : #include "core/ActionWithArguments.h"
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace bias {
+      30             : 
+      31             : class RestraintShortcut : public ActionShortcut {
+      32             : public:
+      33             :   static void registerKeywords(Keywords& keys);
+      34             :   explicit RestraintShortcut(const ActionOptions&);
+      35             : };
+      36             : 
+      37             : PLUMED_REGISTER_ACTION(RestraintShortcut,"RESTRAINT")
+      38             : 
+      39         236 : void RestraintShortcut::registerKeywords(Keywords& keys) {
+      40         236 :   ActionShortcut::registerKeywords( keys );
+      41         472 :   keys.add("numbered","ARG","the arguments on which the bias is acting");
+      42         472 :   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");
+      43         472 :   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");
+      44         472 :   keys.add("compulsory","AT","the position of the restraint");
+      45         472 :   keys.add("hidden","STRIDE","1","the frequency with which the forces due to the bias should be calculated.  This can be used to correctly set up multistep algorithms");
+      46         472 :   keys.addOutputComponent("bias","default","the instantaneous value of the bias potential");
+      47         472 :   keys.addOutputComponent("force2","default","the instantaneous value of the squared force due to this bias potential");
+      48        1180 :   keys.addActionNameSuffix("_SCALAR"); keys.needsAction("COMBINE"); keys.needsAction("SUM"); keys.needsAction("CUSTOM"); keys.needsAction("BIASVALUE");
+      49         236 : }
+      50             : 
+      51         207 : RestraintShortcut::RestraintShortcut(const ActionOptions&ao):
+      52             :   Action(ao),
+      53         207 :   ActionShortcut(ao)
+      54             : {
+      55             :   // Read in the args
+      56         414 :   std::vector<std::string> args; parseVector("ARG",args);
+      57         207 :   if( args.size()==0 ) error("found no input arguments");
+      58         207 :   std::vector<Value*> vals; ActionWithArguments::interpretArgumentList( args, plumed.getActionSet(), this, vals );
+      59         204 :   if( vals.size()==0 ) error("found no input arguments");
+      60             : 
+      61             :   // Find the rank
+      62         204 :   unsigned rank=vals[0]->getRank();
+      63         458 :   for(unsigned i=0; i<vals.size(); ++i) {
+      64         254 :     if( vals[i]->getRank()>0 && vals[i]->hasDerivatives() ) error("argument should not be function on grid");
+      65         257 :     if( vals[i]->getRank()!=rank ) error("all arguments should have same rank");
+      66             :   }
+      67         204 :   if( rank==0 ) {
+      68         253 :     std::string allargs=args[0]; for(unsigned i=1; i<args.size(); ++i) allargs += "," + args[i];
+      69         406 :     readInputLine( getShortcutLabel() + ": RESTRAINT_SCALAR ARG=" + allargs + " " + convertInputLineToString() );
+      70             :     return;
+      71             :   }
+      72             : 
+      73           2 :   std::string stride; parse("STRIDE",stride);
+      74           2 :   std::vector<std::string> at; parseVector("AT",at);
+      75           2 :   std::vector<std::string> slope(at.size()); parseVector("SLOPE",slope);
+      76           2 :   std::vector<std::string> kappa(at.size()); parseVector("KAPPA",kappa);
+      77             : 
+      78             :   std::string biasargs, forceargs; bool non_constant_force=false;
+      79           2 :   for(unsigned i=0; i<args.size(); ++i) {
+      80           1 :     std::string argn; std::size_t dot=args[i].find_first_of(".");
+      81           1 :     if(dot!=std::string::npos) argn = args[i].substr(0,dot) + "_" + args[i].substr(dot+1);
+      82             :     else argn = args[i];
+      83           2 :     readInputLine( getShortcutLabel() + "_cv_" + argn + ": COMBINE PERIODIC=NO ARG=" + args[i] + " PARAMETERS=" + at[i] );
+      84           1 :     double kap; Tools::convert(  kappa[i], kap );
+      85           1 :     if( fabs(kap)>0 ) {
+      86             :       non_constant_force = true;
+      87           2 :       readInputLine( getShortcutLabel() + "_harm_" + argn + ": CUSTOM PERIODIC=NO FUNC=0.5*" + kappa[i] + "*x^2 ARG=" + getShortcutLabel() + "_cv_" + argn );
+      88           2 :       readInputLine( getShortcutLabel() + "_kap_" + argn + ": SUM PERIODIC=NO ARG=" + getShortcutLabel() + "_harm_" + argn );
+      89           2 :       readInputLine( getShortcutLabel() + "_f2_" + argn + ": CUSTOM PERIODIC=NO FUNC=" + kappa[i] + "*2*x+" + slope[i] + "*" + slope[i] + " ARG=" + getShortcutLabel() + "_harm_" + argn );
+      90           2 :       if( i==0 ) biasargs = "ARG=" + getShortcutLabel() + "_kap_" + argn; else biasargs += "," + getShortcutLabel() + "_kap_" + argn;
+      91           2 :       if( i==0 ) forceargs = "ARG=" + getShortcutLabel() + "_f2_" + argn; else forceargs += "," + getShortcutLabel() + "_f2_" + argn;
+      92             :     }
+      93           1 :     double slo; Tools::convert( slope[i], slo );
+      94           1 :     if( fabs(slo)>0 ) {
+      95           0 :       readInputLine( getShortcutLabel() + "_linear_" + argn + ": CUSTOM PERIODIC=NO FUNC=" + slope[i] + "*x ARG=" + getShortcutLabel() + "_cv_" + argn );
+      96           0 :       readInputLine( getShortcutLabel() + "_slope_" + argn + ": SUM PERIODIC=NO ARG=" + getShortcutLabel() + "_linear_" + argn );
+      97           0 :       if( biasargs.length()==0 ) biasargs = "ARG=" + getShortcutLabel() + "_slope_" + argn; else biasargs += "," + getShortcutLabel() + "_slope_" + argn;
+      98             :     }
+      99             :   }
+     100             :   // This is the bias
+     101           2 :   readInputLine( getShortcutLabel() + "_bias: COMBINE PERIODIC=NO " + biasargs );
+     102           2 :   readInputLine( getShortcutLabel() + ": BIASVALUE ARG=" + getShortcutLabel() + "_bias STRIDE=" + stride );
+     103           2 :   if( non_constant_force ) readInputLine( getShortcutLabel() + "_force2: COMBINE PERIODIC=NO " + forceargs );
+     104         214 : }
+     105             : 
+     106             : }
+     107             : 
+     108             : 
+     109             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/ReweightBase.cpp.func-sort-c.html b/coverage/bias/ReweightBase.cpp.func-sort-c.html new file mode 100644 index 000000000000..8f9684894d74 --- /dev/null +++ b/coverage/bias/ReweightBase.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - bias/ReweightBase.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - ReweightBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1818100.0 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias12ReweightBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD4bias12ReweightBaseC2ERKNS_13ActionOptionsE8
_ZN4PLMD4bias12ReweightBase16registerKeywordsERNS_8KeywordsE14
_ZN4PLMD4bias12ReweightBase9calculateEv2008
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/ReweightBase.cpp.func.html b/coverage/bias/ReweightBase.cpp.func.html new file mode 100644 index 000000000000..8ab72ef82d48 --- /dev/null +++ b/coverage/bias/ReweightBase.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - bias/ReweightBase.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - ReweightBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1818100.0 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias12ReweightBase16registerKeywordsERNS_8KeywordsE14
_ZN4PLMD4bias12ReweightBase9calculateEv2008
_ZN4PLMD4bias12ReweightBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD4bias12ReweightBaseC2ERKNS_13ActionOptionsE8
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/ReweightBase.cpp.gcov.html b/coverage/bias/ReweightBase.cpp.gcov.html new file mode 100644 index 000000000000..1c629676c8e3 --- /dev/null +++ b/coverage/bias/ReweightBase.cpp.gcov.html @@ -0,0 +1,130 @@ + + + + + + + + LCOV - plumed test coverage - bias/ReweightBase.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - ReweightBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1818100.0 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias12ReweightBase16calculateWeightsERKj0
_ZN4PLMD4bias12ReweightBase22getNumberOfDerivativesEv0
_ZN4PLMD4bias12ReweightBase9clearDataEv0
_ZNK4PLMD4bias12ReweightBase17buildsWeightStoreEv0
_ZNK4PLMD4bias12ReweightBase9getWeightERKj0
_ZN4PLMD4bias12ReweightBase5applyEv2008
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/ReweightBase.h.func.html b/coverage/bias/ReweightBase.h.func.html new file mode 100644 index 000000000000..ce0186adbe7b --- /dev/null +++ b/coverage/bias/ReweightBase.h.func.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - bias/ReweightBase.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - ReweightBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1616.7 %
Date:2024-04-19 12:12:35Functions:1616.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias12ReweightBase16calculateWeightsERKj0
_ZN4PLMD4bias12ReweightBase22getNumberOfDerivativesEv0
_ZN4PLMD4bias12ReweightBase5applyEv2008
_ZN4PLMD4bias12ReweightBase9clearDataEv0
_ZNK4PLMD4bias12ReweightBase17buildsWeightStoreEv0
_ZNK4PLMD4bias12ReweightBase9getWeightERKj0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/ReweightBase.h.gcov.html b/coverage/bias/ReweightBase.h.gcov.html new file mode 100644 index 000000000000..0e857ad9c086 --- /dev/null +++ b/coverage/bias/ReweightBase.h.gcov.html @@ -0,0 +1,130 @@ + + + + + + + + LCOV - plumed test coverage - bias/ReweightBase.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - ReweightBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1616.7 %
Date:2024-04-19 12:12:35Functions:1616.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_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           0 :   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        2008 :   void apply() override {}
+      49             : };
+      50             : 
+      51             : }
+      52             : }
+      53             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/ReweightBias.cpp.func-sort-c.html b/coverage/bias/ReweightBias.cpp.func-sort-c.html new file mode 100644 index 000000000000..a0066188c55e --- /dev/null +++ b/coverage/bias/ReweightBias.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - bias/ReweightBias.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - ReweightBias.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1010100.0 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

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

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

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

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

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

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

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

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

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias6UWallsC2ERKNS_13ActionOptionsE0
_ZN4PLMD4bias6UWallsC1ERKNS_13ActionOptionsE10
_ZN4PLMD4bias6UWalls16registerKeywordsERNS_8KeywordsE12
_ZN4PLMD4bias6UWalls9calculateEv14015
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/UWalls.cpp.func.html b/coverage/bias/UWalls.cpp.func.html new file mode 100644 index 000000000000..31e0e697a23b --- /dev/null +++ b/coverage/bias/UWalls.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - bias/UWalls.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - UWalls.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:5656100.0 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias6UWalls16registerKeywordsERNS_8KeywordsE12
_ZN4PLMD4bias6UWalls9calculateEv14015
_ZN4PLMD4bias6UWallsC1ERKNS_13ActionOptionsE10
_ZN4PLMD4bias6UWallsC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/UWalls.cpp.gcov.html b/coverage/bias/UWalls.cpp.gcov.html new file mode 100644 index 000000000000..d734f1be4be2 --- /dev/null +++ b/coverage/bias/UWalls.cpp.gcov.html @@ -0,0 +1,234 @@ + + + + + + + + LCOV - plumed test coverage - bias/UWalls.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - UWalls.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:5656100.0 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias5WallsC2ERKNS_13ActionOptionsE0
_ZN4PLMD4bias5WallsC1ERKNS_13ActionOptionsE13
_ZN4PLMD4bias5Walls16registerKeywordsERNS_8KeywordsE26
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/Walls.cpp.func.html b/coverage/bias/Walls.cpp.func.html new file mode 100644 index 000000000000..3b154b4bc886 --- /dev/null +++ b/coverage/bias/Walls.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - bias/Walls.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - Walls.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:535989.8 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias5Walls16registerKeywordsERNS_8KeywordsE26
_ZN4PLMD4bias5WallsC1ERKNS_13ActionOptionsE13
_ZN4PLMD4bias5WallsC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/Walls.cpp.gcov.html b/coverage/bias/Walls.cpp.gcov.html new file mode 100644 index 000000000000..d005b1f5dc42 --- /dev/null +++ b/coverage/bias/Walls.cpp.gcov.html @@ -0,0 +1,196 @@ + + + + + + + + LCOV - plumed test coverage - bias/Walls.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - Walls.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:535989.8 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2020 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received 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/ActionWithArguments.h"
+      24             : #include "core/PlumedMain.h"
+      25             : #include "core/ActionSet.h"
+      26             : #include "core/ActionRegister.h"
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace bias {
+      30             : 
+      31             : class Walls : public ActionShortcut {
+      32             : public:
+      33             :   explicit Walls(const ActionOptions&);
+      34             :   static void registerKeywords(Keywords& keys);
+      35             : };
+      36             : 
+      37             : PLUMED_REGISTER_ACTION(Walls,"UPPER_WALLS")
+      38             : PLUMED_REGISTER_ACTION(Walls,"LOWER_WALLS")
+      39             : 
+      40          26 : void Walls::registerKeywords(Keywords& keys) {
+      41          26 :   ActionShortcut::registerKeywords(keys);
+      42          52 :   keys.add("numbered","ARG","the arguments on which the bias is acting");
+      43          52 :   keys.add("compulsory","AT","the positions of the wall. The a_i in the expression for a wall.");
+      44          52 :   keys.add("compulsory","KAPPA","the force constant for the wall.  The k_i in the expression for a wall.");
+      45          52 :   keys.add("compulsory","OFFSET","0.0","the offset for the start of the wall.  The o_i in the expression for a wall.");
+      46          52 :   keys.add("compulsory","EXP","2.0","the powers for the walls.  The e_i in the expression for a wall.");
+      47          52 :   keys.add("compulsory","EPS","1.0","the values for s_i in the expression for a wall");
+      48          52 :   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");
+      49          52 :   keys.addOutputComponent("bias","default","the instantaneous value of the bias potential");
+      50          52 :   keys.addOutputComponent("force2","default","the instantaneous value of the squared force due to this bias potential");
+      51          78 :   keys.addActionNameSuffix("_SCALAR"); keys.needsAction("COMBINE"); keys.needsAction("CUSTOM");
+      52          78 :   keys.needsAction("SUM"); keys.needsAction("COMBINE"); keys.needsAction("BIASVALUE");
+      53          26 : }
+      54             : 
+      55          13 : Walls::Walls(const ActionOptions&ao):
+      56             :   Action(ao),
+      57          13 :   ActionShortcut(ao)
+      58             : {
+      59             :   // Read the arguments
+      60          26 :   std::vector<std::string> args; parseVector("ARG",args);
+      61          13 :   if( args.size()==0 ) error("found no input arguments");
+      62          13 :   std::string allargs=args[0]; for(unsigned i=1; i<args.size(); ++i) allargs += "," + args[i];
+      63          13 :   std::vector<Value*> vals; ActionWithArguments::interpretArgumentList( args, plumed.getActionSet(), this, vals );
+      64          13 :   if( vals.size()==0 ) error("found no input arguments");
+      65             : 
+      66             :   // Find the rank
+      67          13 :   unsigned rank=vals[0]->getRank();
+      68          26 :   for(unsigned i=0; i<vals.size(); ++i) {
+      69          13 :     if( vals[i]->getRank()>0 && vals[i]->hasDerivatives() ) error("argument should not be function on grid");
+      70          13 :     if( vals[i]->getRank()!=rank ) error("all arguments should have same rank");
+      71             :   }
+      72          13 :   if( rank==0 ) {
+      73          21 :     if( getName()=="UPPER_WALLS") readInputLine( getShortcutLabel() + ": UPPER_WALLS_SCALAR ARG=" + allargs + " " + convertInputLineToString() );
+      74           2 :     else if( getName()=="LOWER_WALLS") readInputLine( getShortcutLabel() + ": LOWER_WALLS_SCALAR ARG=" + allargs + " " + convertInputLineToString() );
+      75           0 :     else plumed_merror( getName() + " is not valid");
+      76             :     return;
+      77             :   }
+      78             : 
+      79             :   // Note : the sizes of these vectors are checked automatically by parseVector
+      80           4 :   std::vector<std::string> kappa(args.size()); parseVector("KAPPA",kappa);
+      81           4 :   std::vector<std::string> offset(kappa.size()); parseVector("OFFSET",offset);
+      82           4 :   std::vector<std::string> eps(kappa.size()); parseVector("EPS",eps);
+      83           4 :   std::vector<std::string> exp(kappa.size()); parseVector("EXP",exp);
+      84           4 :   std::vector<std::string> at(kappa.size()); parseVector("AT",at);
+      85             : 
+      86             :   std::string biasinp, forceinp;
+      87           4 :   for(unsigned i=0; i<args.size(); ++i) {
+      88           2 :     std::string argn; std::size_t dot=args[i].find_first_of(".");
+      89           2 :     if(dot!=std::string::npos) argn = args[i].substr(0,dot) + "_" + args[i].substr(dot+1);
+      90             :     else argn = args[i];
+      91           4 :     readInputLine( getShortcutLabel() + "_cv_" + argn + ": COMBINE PERIODIC=NO ARG=" + args[i] + " PARAMETERS=" + at[i] );
+      92           2 :     if( getName()=="UPPER_WALLS" ) {
+      93           4 :       readInputLine( getShortcutLabel() + "_scale_" + argn + ": CUSTOM PERIODIC=NO FUNC=(x+" + offset[i] +")/" + eps[i] + " ARG=" + getShortcutLabel() + "_cv_" + argn );
+      94           4 :       readInputLine( getShortcutLabel() + "_pow_" + argn + ": CUSTOM PERIODIC=NO FUNC=step(x)*x^" + exp[i] + " ARG=" + getShortcutLabel() + "_scale_" + argn );
+      95           0 :     } else if( getName()=="LOWER_WALLS" ) {
+      96           0 :       readInputLine( getShortcutLabel() + "_scale_" + argn + ": CUSTOM PERIODIC=NO FUNC=(x-" + offset[i] +")/" + eps[i] + " ARG=" + getShortcutLabel() + "_cv_" + argn );
+      97           0 :       readInputLine( getShortcutLabel() + "_pow_" + argn + ": CUSTOM PERIODIC=NO FUNC=step(-x)*x^" + exp[i] + " ARG=" + getShortcutLabel() + "_scale_" + argn );
+      98             :     }
+      99           4 :     readInputLine( getShortcutLabel() + "_v_wall_" + argn + ": CUSTOM PERIODIC=NO FUNC=" + kappa[i] +"*x" + " ARG=" + getShortcutLabel() + "_pow_" + argn );
+     100           4 :     readInputLine( getShortcutLabel() + "_wall_" + argn + ": SUM ARG=" + getShortcutLabel() + "_v_wall_" + argn + " PERIODIC=NO");
+     101           6 :     readInputLine( getShortcutLabel() + "_force_" + argn + ": CUSTOM PERIODIC=NO FUNC=" + kappa[i] + "*" + exp[i] + "*x/(y*" + eps[i] + ") " +
+     102           6 :                    "ARG=" + getShortcutLabel() + "_pow_" + argn + "," + getShortcutLabel() + "_scale_" + argn );
+     103           4 :     readInputLine( getShortcutLabel() + "_v_force2_" + argn + ": CUSTOM PERIODIC=NO FUNC=x*x ARG=" + getShortcutLabel() + "_force_" + argn );
+     104           4 :     readInputLine( getShortcutLabel() + "_force2_" + argn + ": SUM ARG=" + getShortcutLabel() + "_v_force2_" + argn + " PERIODIC=NO");
+     105           2 :     if(i==0) {
+     106           4 :       biasinp = " ARG=" + getShortcutLabel() + "_wall_" + argn;
+     107           4 :       forceinp = " ARG=" + getShortcutLabel() + "_force2_" + argn;
+     108             :     } else {
+     109           0 :       biasinp += "," + getShortcutLabel() + "_wall_" + argn;
+     110           0 :       forceinp += "," + getShortcutLabel() + "_force2_" + argn;
+     111             :     }
+     112             :   }
+     113           4 :   readInputLine( getShortcutLabel() + "_bias: COMBINE PERIODIC=NO " + biasinp );
+     114           4 :   readInputLine( "BIASVALUE ARG=" + getShortcutLabel() + "_bias" );
+     115           4 :   readInputLine( getShortcutLabel() + "_force2: COMBINE PERIODIC=NO " + forceinp  );
+     116          15 : }
+     117             : 
+     118             : }
+     119             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/index-sort-f.html b/coverage/bias/index-sort-f.html new file mode 100644 index 000000000000..35c67f271d34 --- /dev/null +++ b/coverage/bias/index-sort-f.html @@ -0,0 +1,284 @@ + + + + + + + + LCOV - plumed test coverage - bias + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - biasHitTotalCoverage
Test:plumed test coverageLines:2443266991.5 %
Date:2024-04-19 12:12:35Functions:9712279.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
ReweightBase.h +
16.7%16.7%
+
16.7 %1 / 616.7 %1 / 6
Walls.cpp +
89.8%89.8%
+
89.8 %53 / 5966.7 %2 / 3
RestraintShortcut.cpp +
93.8%93.8%
+
93.8 %45 / 4866.7 %2 / 3
LWalls.cpp +
100.0%
+
100.0 %56 / 5675.0 %3 / 4
BiasValue.cpp +
100.0%
+
100.0 %20 / 2075.0 %3 / 4
Bias.cpp +
100.0%
+
100.0 %37 / 3775.0 %3 / 4
ABMD.cpp +
100.0%
+
100.0 %62 / 6275.0 %3 / 4
UWalls.cpp +
100.0%
+
100.0 %56 / 5675.0 %3 / 4
ReweightBias.cpp +
100.0%
+
100.0 %10 / 1075.0 %3 / 4
ReweightTemperaturePressure.cpp +
97.8%97.8%
+
97.8 %45 / 4675.0 %3 / 4
ReweightMetad.cpp +
100.0%
+
100.0 %10 / 1075.0 %3 / 4
External.cpp +
100.0%
+
100.0 %40 / 4075.0 %3 / 4
MovingRestraint.cpp +
100.0%
+
100.0 %109 / 10975.0 %3 / 4
ReweightBase.cpp +
100.0%
+
100.0 %18 / 1875.0 %3 / 4
Restraint.cpp +
100.0%
+
100.0 %41 / 4175.0 %3 / 4
ExtendedLagrangian.cpp +
98.9%98.9%
+
98.9 %90 / 9180.0 %4 / 5
PBMetaD.cpp +
88.3%88.3%
+
88.3 %566 / 64186.7 %13 / 15
MaxEnt.cpp +
96.6%96.6%
+
96.6 %225 / 23390.9 %10 / 11
MetaD.cpp +
88.2%88.2%
+
88.2 %950 / 107792.9 %26 / 28
Bias.h +
100.0%
+
100.0 %9 / 9100.0 %3 / 3
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/index-sort-l.html b/coverage/bias/index-sort-l.html new file mode 100644 index 000000000000..e47ac910f1e6 --- /dev/null +++ b/coverage/bias/index-sort-l.html @@ -0,0 +1,284 @@ + + + + + + + + LCOV - plumed test coverage - bias + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - biasHitTotalCoverage
Test:plumed test coverageLines:2443266991.5 %
Date:2024-04-19 12:12:35Functions:9712279.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
ReweightBase.h +
16.7%16.7%
+
16.7 %1 / 616.7 %1 / 6
PBMetaD.cpp +
88.3%88.3%
+
88.3 %566 / 64186.7 %13 / 15
MetaD.cpp +
88.2%88.2%
+
88.2 %950 / 107792.9 %26 / 28
Walls.cpp +
89.8%89.8%
+
89.8 %53 / 5966.7 %2 / 3
RestraintShortcut.cpp +
93.8%93.8%
+
93.8 %45 / 4866.7 %2 / 3
MaxEnt.cpp +
96.6%96.6%
+
96.6 %225 / 23390.9 %10 / 11
ReweightTemperaturePressure.cpp +
97.8%97.8%
+
97.8 %45 / 4675.0 %3 / 4
ExtendedLagrangian.cpp +
98.9%98.9%
+
98.9 %90 / 9180.0 %4 / 5
Bias.h +
100.0%
+
100.0 %9 / 9100.0 %3 / 3
ReweightBias.cpp +
100.0%
+
100.0 %10 / 1075.0 %3 / 4
ReweightMetad.cpp +
100.0%
+
100.0 %10 / 1075.0 %3 / 4
ReweightBase.cpp +
100.0%
+
100.0 %18 / 1875.0 %3 / 4
BiasValue.cpp +
100.0%
+
100.0 %20 / 2075.0 %3 / 4
Bias.cpp +
100.0%
+
100.0 %37 / 3775.0 %3 / 4
External.cpp +
100.0%
+
100.0 %40 / 4075.0 %3 / 4
Restraint.cpp +
100.0%
+
100.0 %41 / 4175.0 %3 / 4
LWalls.cpp +
100.0%
+
100.0 %56 / 5675.0 %3 / 4
UWalls.cpp +
100.0%
+
100.0 %56 / 5675.0 %3 / 4
ABMD.cpp +
100.0%
+
100.0 %62 / 6275.0 %3 / 4
MovingRestraint.cpp +
100.0%
+
100.0 %109 / 10975.0 %3 / 4
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/index.html b/coverage/bias/index.html new file mode 100644 index 000000000000..210aeeaa8415 --- /dev/null +++ b/coverage/bias/index.html @@ -0,0 +1,284 @@ + + + + + + + + LCOV - plumed test coverage - bias + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - biasHitTotalCoverage
Test:plumed test coverageLines:2443266991.5 %
Date:2024-04-19 12:12:35Functions:9712279.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
ABMD.cpp +
100.0%
+
100.0 %62 / 6275.0 %3 / 4
Bias.cpp +
100.0%
+
100.0 %37 / 3775.0 %3 / 4
Bias.h +
100.0%
+
100.0 %9 / 9100.0 %3 / 3
BiasValue.cpp +
100.0%
+
100.0 %20 / 2075.0 %3 / 4
ExtendedLagrangian.cpp +
98.9%98.9%
+
98.9 %90 / 9180.0 %4 / 5
External.cpp +
100.0%
+
100.0 %40 / 4075.0 %3 / 4
LWalls.cpp +
100.0%
+
100.0 %56 / 5675.0 %3 / 4
MaxEnt.cpp +
96.6%96.6%
+
96.6 %225 / 23390.9 %10 / 11
MetaD.cpp +
88.2%88.2%
+
88.2 %950 / 107792.9 %26 / 28
MovingRestraint.cpp +
100.0%
+
100.0 %109 / 10975.0 %3 / 4
PBMetaD.cpp +
88.3%88.3%
+
88.3 %566 / 64186.7 %13 / 15
Restraint.cpp +
100.0%
+
100.0 %41 / 4175.0 %3 / 4
RestraintShortcut.cpp +
93.8%93.8%
+
93.8 %45 / 4866.7 %2 / 3
ReweightBase.cpp +
100.0%
+
100.0 %18 / 1875.0 %3 / 4
ReweightBase.h +
16.7%16.7%
+
16.7 %1 / 616.7 %1 / 6
ReweightBias.cpp +
100.0%
+
100.0 %10 / 1075.0 %3 / 4
ReweightMetad.cpp +
100.0%
+
100.0 %10 / 1075.0 %3 / 4
ReweightTemperaturePressure.cpp +
97.8%97.8%
+
97.8 %45 / 4675.0 %3 / 4
UWalls.cpp +
100.0%
+
100.0 %56 / 5675.0 %3 / 4
Walls.cpp +
89.8%89.8%
+
89.8 %53 / 5966.7 %2 / 3
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/Benchmark.cpp.func-sort-c.html b/coverage/cltools/Benchmark.cpp.func-sort-c.html new file mode 100644 index 000000000000..21ef6df322c6 --- /dev/null +++ b/coverage/cltools/Benchmark.cpp.func-sort-c.html @@ -0,0 +1,181 @@ + + + + + + + + LCOV - plumed test coverage - cltools/Benchmark.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - Benchmark.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:193056.2 %
Date:2024-04-19 12:12:35Functions:62722.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools12_GLOBAL__N_110KernelBaseC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESA_PNS_3LogE0
_ZN4PLMD7cltools12_GLOBAL__N_112_GLOBAL__N_111uniformCube3boxERSt6vectorIdSaIdEEjjRNS_6RandomE0
_ZN4PLMD7cltools12_GLOBAL__N_112_GLOBAL__N_111uniformCube9positionsERSt6vectorINS_13VectorGenericILj3EEESaIS6_EEjRNS_6RandomE0
_ZN4PLMD7cltools12_GLOBAL__N_112_GLOBAL__N_113uniformSphere3boxERSt6vectorIdSaIdEEjjRNS_6RandomE0
_ZN4PLMD7cltools12_GLOBAL__N_112_GLOBAL__N_113uniformSphere9positionsERSt6vectorINS_13VectorGenericILj3EEESaIS6_EEjRNS_6RandomE0
_ZN4PLMD7cltools12_GLOBAL__N_112_GLOBAL__N_116AtomDistribution3boxERSt6vectorIdSaIdEEjjRNS_6RandomE0
_ZN4PLMD7cltools12_GLOBAL__N_112_GLOBAL__N_116tiledSimpleCubic3boxERSt6vectorIdSaIdEEjjRNS_6RandomE0
_ZN4PLMD7cltools12_GLOBAL__N_112_GLOBAL__N_116tiledSimpleCubic9positionsERSt6vectorINS_13VectorGenericILj3EEESaIS6_EEjRNS_6RandomE0
_ZN4PLMD7cltools12_GLOBAL__N_112_GLOBAL__N_119getAtomDistributionESt17basic_string_viewIcSt11char_traitsIcEE0
_ZN4PLMD7cltools12_GLOBAL__N_112_GLOBAL__N_122UniformSphericalVectorclERNS_6RandomE0
_ZN4PLMD7cltools12_GLOBAL__N_112_GLOBAL__N_17theLine9positionsERSt6vectorINS_13VectorGenericILj3EEESaIS6_EEjRNS_6RandomE0
_ZN4PLMD7cltools12_GLOBAL__N_112_GLOBAL__N_18twoGlobs3boxERSt6vectorIdSaIdEEjjRNS_6RandomE0
_ZN4PLMD7cltools12_GLOBAL__N_112_GLOBAL__N_18twoGlobs9positionsERSt6vectorINS_13VectorGenericILj3EEESaIS6_EEjRNS_6RandomE0
_ZN4PLMD7cltools12_GLOBAL__N_118SignalHandlerGuardC2EiPFviE0
_ZN4PLMD7cltools12_GLOBAL__N_16KernelD2Ev0
_ZN4PLMD7cltools12_GLOBAL__N_16KernelaSEOS2_0
_ZN4PLMD7cltools12_GLOBAL__N_19Benchmark4mainEP8_IO_FILES4_RNS_12CommunicatorE0
_ZZN4PLMD7cltools12_GLOBAL__N_110KernelBaseC4ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESA_PNS_3LogEENKUlvE_clEv0
_ZZN4PLMD7cltools12_GLOBAL__N_112_GLOBAL__N_18twoGlobs9positionsERSt6vectorINS_13VectorGenericILj3EEESaIS6_EEjRNS_6RandomEENKUlvE_clEv0
_ZZN4PLMD7cltools12_GLOBAL__N_19Benchmark4mainEP8_IO_FILES4_RNS_12CommunicatorEENKUlT_E_clIPSt6vectorINS1_6KernelESaISB_EEEEDaS7_0
signalHandler0
_ZN4PLMD7cltools12_GLOBAL__N_112_GLOBAL__N_119BenchmarkRegisterMe6createERKNS_13CLToolOptionsE4
_ZN4PLMD7cltools12_GLOBAL__N_19BenchmarkC2ERKNS_13CLToolOptionsE4
_ZNK4PLMD7cltools12_GLOBAL__N_19Benchmark11descriptionEv4
_ZN4PLMD7cltools12_GLOBAL__N_112_GLOBAL__N_119BenchmarkRegisterMeC2Ev5088
_ZN4PLMD7cltools12_GLOBAL__N_112_GLOBAL__N_119BenchmarkRegisterMeD2Ev5088
_ZN4PLMD7cltools12_GLOBAL__N_19Benchmark16registerKeywordsERNS_8KeywordsE5088
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/Benchmark.cpp.func.html b/coverage/cltools/Benchmark.cpp.func.html new file mode 100644 index 000000000000..bfe57244251c --- /dev/null +++ b/coverage/cltools/Benchmark.cpp.func.html @@ -0,0 +1,181 @@ + + + + + + + + LCOV - plumed test coverage - cltools/Benchmark.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - Benchmark.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:193056.2 %
Date:2024-04-19 12:12:35Functions:62722.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools12_GLOBAL__N_110KernelBaseC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESA_PNS_3LogE0
_ZN4PLMD7cltools12_GLOBAL__N_112_GLOBAL__N_111uniformCube3boxERSt6vectorIdSaIdEEjjRNS_6RandomE0
_ZN4PLMD7cltools12_GLOBAL__N_112_GLOBAL__N_111uniformCube9positionsERSt6vectorINS_13VectorGenericILj3EEESaIS6_EEjRNS_6RandomE0
_ZN4PLMD7cltools12_GLOBAL__N_112_GLOBAL__N_113uniformSphere3boxERSt6vectorIdSaIdEEjjRNS_6RandomE0
_ZN4PLMD7cltools12_GLOBAL__N_112_GLOBAL__N_113uniformSphere9positionsERSt6vectorINS_13VectorGenericILj3EEESaIS6_EEjRNS_6RandomE0
_ZN4PLMD7cltools12_GLOBAL__N_112_GLOBAL__N_116AtomDistribution3boxERSt6vectorIdSaIdEEjjRNS_6RandomE0
_ZN4PLMD7cltools12_GLOBAL__N_112_GLOBAL__N_116tiledSimpleCubic3boxERSt6vectorIdSaIdEEjjRNS_6RandomE0
_ZN4PLMD7cltools12_GLOBAL__N_112_GLOBAL__N_116tiledSimpleCubic9positionsERSt6vectorINS_13VectorGenericILj3EEESaIS6_EEjRNS_6RandomE0
_ZN4PLMD7cltools12_GLOBAL__N_112_GLOBAL__N_119BenchmarkRegisterMe6createERKNS_13CLToolOptionsE4
_ZN4PLMD7cltools12_GLOBAL__N_112_GLOBAL__N_119BenchmarkRegisterMeC2Ev5088
_ZN4PLMD7cltools12_GLOBAL__N_112_GLOBAL__N_119BenchmarkRegisterMeD2Ev5088
_ZN4PLMD7cltools12_GLOBAL__N_112_GLOBAL__N_119getAtomDistributionESt17basic_string_viewIcSt11char_traitsIcEE0
_ZN4PLMD7cltools12_GLOBAL__N_112_GLOBAL__N_122UniformSphericalVectorclERNS_6RandomE0
_ZN4PLMD7cltools12_GLOBAL__N_112_GLOBAL__N_17theLine9positionsERSt6vectorINS_13VectorGenericILj3EEESaIS6_EEjRNS_6RandomE0
_ZN4PLMD7cltools12_GLOBAL__N_112_GLOBAL__N_18twoGlobs3boxERSt6vectorIdSaIdEEjjRNS_6RandomE0
_ZN4PLMD7cltools12_GLOBAL__N_112_GLOBAL__N_18twoGlobs9positionsERSt6vectorINS_13VectorGenericILj3EEESaIS6_EEjRNS_6RandomE0
_ZN4PLMD7cltools12_GLOBAL__N_118SignalHandlerGuardC2EiPFviE0
_ZN4PLMD7cltools12_GLOBAL__N_16KernelD2Ev0
_ZN4PLMD7cltools12_GLOBAL__N_16KernelaSEOS2_0
_ZN4PLMD7cltools12_GLOBAL__N_19Benchmark16registerKeywordsERNS_8KeywordsE5088
_ZN4PLMD7cltools12_GLOBAL__N_19Benchmark4mainEP8_IO_FILES4_RNS_12CommunicatorE0
_ZN4PLMD7cltools12_GLOBAL__N_19BenchmarkC2ERKNS_13CLToolOptionsE4
_ZNK4PLMD7cltools12_GLOBAL__N_19Benchmark11descriptionEv4
_ZZN4PLMD7cltools12_GLOBAL__N_110KernelBaseC4ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESA_PNS_3LogEENKUlvE_clEv0
_ZZN4PLMD7cltools12_GLOBAL__N_112_GLOBAL__N_18twoGlobs9positionsERSt6vectorINS_13VectorGenericILj3EEESaIS6_EEjRNS_6RandomEENKUlvE_clEv0
_ZZN4PLMD7cltools12_GLOBAL__N_19Benchmark4mainEP8_IO_FILES4_RNS_12CommunicatorEENKUlT_E_clIPSt6vectorINS1_6KernelESaISB_EEEEDaS7_0
signalHandler0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/Benchmark.cpp.gcov.html b/coverage/cltools/Benchmark.cpp.gcov.html new file mode 100644 index 000000000000..cd309e8bc99e --- /dev/null +++ b/coverage/cltools/Benchmark.cpp.gcov.html @@ -0,0 +1,881 @@ + + + + + + + + LCOV - plumed test coverage - cltools/Benchmark.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - Benchmark.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:193056.2 %
Date:2024-04-19 12:12:35Functions:62722.2 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2019-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "CLTool.h"
+      23             : #include "core/CLToolRegister.h"
+      24             : #include "tools/Communicator.h"
+      25             : #include "tools/Tools.h"
+      26             : #include "config/Config.h"
+      27             : #include "tools/PlumedHandle.h"
+      28             : #include "tools/Stopwatch.h"
+      29             : #include "tools/Log.h"
+      30             : #include "tools/DLLoader.h"
+      31             : #include "tools/Random.h"
+      32             : 
+      33             : #include <cstdio>
+      34             : #include <string>
+      35             : #include <vector>
+      36             : #include <fstream>
+      37             : #include <atomic>
+      38             : #include <csignal>
+      39             : #include <cstdio>
+      40             : #include <random>
+      41             : #include <algorithm>
+      42             : #include <chrono>
+      43             : #include <string_view>
+      44             : 
+      45             : namespace PLMD {
+      46             : namespace cltools {
+      47             : 
+      48             : //+PLUMEDOC TOOLS benchmark
+      49             : /*
+      50             : benchmark is a lightweight reimplementation of driver focused on running benchmarks
+      51             : 
+      52             : The main difference wrt driver is that it generates a trajectory in memory rather than reading it
+      53             : from a file. This allows to better time the overhead of the plumed library, without including
+      54             : the time needed to read the trajectory.
+      55             : 
+      56             : It is also possible to load a separate version of the plumed kernel. This enables running
+      57             : benchmarks agaist previous plumed versions in a controlled setting, where systematic errors
+      58             : in the comparison are minimized.
+      59             : 
+      60             : \par Examples
+      61             : 
+      62             : First, you should create a sample `plumed.dat` file for testing. For instance:
+      63             : 
+      64             : \plumedfile
+      65             : WHOLEMOLECULES ENTITY0=1-10000
+      66             : p: POSITION ATOM=1
+      67             : RESTRAINT ARG=p.x KAPPA=1 AT=0
+      68             : \endplumedfile
+      69             : 
+      70             : Then you can test the performance of this input with the following command:
+      71             : \verbatim
+      72             : plumed benchmark
+      73             : \endverbatim
+      74             : 
+      75             : You can also test a different (older) version of PLUMED with the same input. To do so,
+      76             : you should run
+      77             : \verbatim
+      78             : plumed-runtime benchmark --kernel /path/to/lib/libplumedKernel.so
+      79             : \endverbatim
+      80             : 
+      81             : \warning It is necessary to use the `plumed-runtime` executable here to avoid conflicts between different
+      82             : plumed versions. You will find it in your path if you are using the non installed version of plumed,
+      83             : and in `$prefix/lib/plumed` if you installed plumed in $prefix,.
+      84             : 
+      85             : \par Comparing multiple versions
+      86             : 
+      87             : The best way to compare two versions of plumed on the same input is to pass multiple colon-separated kernels:
+      88             : 
+      89             : \verbatim
+      90             : plumed-runtime benchmark --kernel /path/to/lib/libplumedKernel.so:/path2/to/lib/libplumedKernel.so:this
+      91             : \endverbatim
+      92             : 
+      93             : Here `this` means the kernel of the version with which you are running the benchmark. This comparison runs the three
+      94             : instances simultaneously (alternating them) so that systematic differences in the load of your machine will affect them
+      95             : to the same extent.
+      96             : 
+      97             : In case the different versions require modified plumed.dat files, or if you simply want to compare
+      98             : two different plumed input files that compute the same thing, you can also use multiple plumed input files:
+      99             : 
+     100             : \verbatim
+     101             : plumed-runtime benchmark --kernel /path/to/lib/libplumedKernel.so:this --plumed plumed1.dat:plumed2.dat
+     102             : \endverbatim
+     103             : 
+     104             : Similarly, you might want to run two different inputs using the same kernel, which can be obtained with:
+     105             : 
+     106             : \verbatim
+     107             : plumed-runtime benchmark --plumed plumed1.dat:plumed2.dat
+     108             : \endverbatim
+     109             : 
+     110             : \par Profiling
+     111             : 
+     112             : If you want to attach a profiler on the fly to the process, you might find it convenient to use `--nsteps -1`.
+     113             : The simulation will run forever and can be interrupted with CTRL-C. When interrupted, the result of the timers
+     114             : should be displayed anyway.
+     115             : You can also run setting a maximum time with `--maxtime`.
+     116             : 
+     117             : If you run a profiler when testing multiple PLUMED versions you might be confused by which function is from
+     118             : each version. It is recommended to recompile separate instances with a separate C++ namespace (`-DPLMD=PLUMED_version_1`)
+     119             : so that you will be able to distinguish them. In addition, compiling with `CXXFLAGS="-g -O3"` will make the profiling
+     120             : report more complete, likely including code lines.
+     121             : 
+     122             : \par MPI runs
+     123             : 
+     124             : You can run emulating a domain decomposition. This is done automatically if plumed has been compiled with MPI
+     125             : and you run with `mpirun`
+     126             : 
+     127             : \verbatim
+     128             : mpirun -np 4 plumed-runtime benchmark
+     129             : \endverbatim
+     130             : 
+     131             : If you load separate PLUMED instances as discussed above, they should all be compiled against the same MPI version.
+     132             : Notice that when using MPI signals (CTRL-C) might not work.
+     133             : 
+     134             : Since some of the data transfer could happen asynchronously, you might want to use the `--sleep` option
+     135             : to simulate a lag between the `prepareCalc` and `performCalc` actions. This part of the calculation will not contribute
+     136             : to timer, but will obviously slow down your test.
+     137             : 
+     138             : \par Output
+     139             : 
+     140             : In the output you will see the usual reports about timing produced by the internal
+     141             : timers of the tested plumed instances.
+     142             : In addition, this tool will monitor the timing externally, with some slightly different criterion:
+     143             : - First, the initialization (construction of the input) will be shown with a separate timer,
+     144             :   as well as the timing for the first step.
+     145             : - Second, the timer corresponding to the calculation will be split in three parts, reporting
+     146             :   execution of the first 20% (warm-up) and the next two blocks of 40% each.
+     147             : - Finally, you might notice some discrepancy because some of the actions that are usually
+     148             :   not expensive are not included in the internal timers. The external timer will
+     149             :   thus provide a better estimate of the total elapsed time, including everything.
+     150             : 
+     151             : The internal timers are still useful to monitor what happens at the different stages
+     152             : and, with \ref DEBUG `DETAILED_TIMERS`, what happens in each action.
+     153             : 
+     154             : When you run multiple version, a comparative analisys of the time spent within PLUMED in the various
+     155             : instances will be done, showing the ratio between the total time and the time measured on the first
+     156             : instance, which will act as a reference. Errors will be estimated with bootstrapping. The warm-up phase will be discarded for
+     157             : this analysis.
+     158             : 
+     159             : */
+     160             : //+ENDPLUMEDOC
+     161             : 
+     162             : // We use an anonymous namespace here to avoid clashes with variables
+     163             : // declared in other parts of the code
+     164             : namespace {
+     165             : 
+     166             : //this is a sugar for changing idea faster about the rng
+     167             : using generator = std::mt19937;
+     168             : 
+     169             : std::atomic<bool> signalReceived(false);
+     170             : 
+     171             : class SignalHandlerGuard {
+     172             : public:
+     173           0 :   SignalHandlerGuard(int signal, void (*newHandler)(int)) : signal_(signal) {
+     174             :     // Store the current handler before setting the new one
+     175           0 :     prevHandler_ = std::signal(signal, newHandler);
+     176           0 :     if (prevHandler_ == SIG_ERR) {
+     177           0 :       throw std::runtime_error("Failed to set signal handler");
+     178             :     }
+     179           0 :   }
+     180             : 
+     181             :   ~SignalHandlerGuard() {
+     182             :     // Restore the previous handler upon destruction
+     183           0 :     std::signal(signal_, prevHandler_);
+     184           0 :   }
+     185             : 
+     186             :   // Delete copy constructor and assignment operator to prevent copying
+     187             :   SignalHandlerGuard(const SignalHandlerGuard&) = delete;
+     188             :   SignalHandlerGuard& operator=(const SignalHandlerGuard&) = delete;
+     189             : 
+     190             : private:
+     191             :   int signal_;
+     192             :   void (*prevHandler_)(int);
+     193             : };
+     194             : 
+     195           0 : extern "C" void signalHandler(int signal) {
+     196           0 :   if (signal == SIGINT) {
+     197             :     signalReceived.store(true);
+     198           0 :     fprintf(stderr, "Signal handler called\n");
+     199             :   }
+     200           0 : }
+     201             : 
+     202             : /// This base class contains members that are movable with default operations
+     203             : struct KernelBase {
+     204             :   std::string path;
+     205             :   std::string plumed_dat;
+     206             :   PlumedHandle handle;
+     207             :   Stopwatch stopwatch;
+     208             :   std::vector<long long int> timings;
+     209             :   double comparative_timing=-1.0;
+     210             :   double comparative_timing_error=-1.0;
+     211           0 :   KernelBase(const std::string & path_,const std::string & plumed_dat_, Log* log_):
+     212           0 :     path(path_),
+     213           0 :     plumed_dat(plumed_dat_),
+     214           0 :     handle([&]() {
+     215           0 :     if(path_=="this") return PlumedHandle();
+     216           0 :     else return PlumedHandle::dlopen(path.c_str());
+     217             :   }()),
+     218           0 :   stopwatch(*log_)
+     219             :   {
+     220           0 :   }
+     221             : };
+     222             : 
+     223             : /// Local structure handling a kernel and the related timers.
+     224             : /// This structure specifically contain the Log, which needs special treatment
+     225             : /// in move semantics
+     226             : struct Kernel :
+     227             :   public KernelBase {
+     228             :   Log* log=nullptr;
+     229           0 :   Kernel(const std::string & path_,const std::string & the_plumed_dat, Log* log_):
+     230             :     KernelBase(path_,the_plumed_dat,log_),
+     231           0 :     log(log_)
+     232             :   {
+     233             :   }
+     234             : 
+     235           0 :   ~Kernel() {
+     236           0 :     if(log) {
+     237           0 :       (*log)<<"\n";
+     238           0 :       (*log)        <<"Kernel:      "<<path<<"\n";
+     239           0 :       (*log)        <<"Input:       "<<plumed_dat<<"\n";
+     240           0 :       if(comparative_timing>0.0) {
+     241           0 :         (*log).printf("Comparative: %.3f +- %.3f\n",comparative_timing,comparative_timing_error);
+     242             :       }
+     243             :     }
+     244           0 :   }
+     245             : 
+     246           0 :   Kernel(Kernel && other) noexcept:
+     247             :     KernelBase(std::move(other)),
+     248           0 :     log(other.log)
+     249             :   {
+     250           0 :     other.log=nullptr; // ensure no log is done in the moved away object
+     251             :   }
+     252             : 
+     253           0 :   Kernel & operator=(Kernel && other) noexcept
+     254             :   {
+     255           0 :     if(this != &other) {
+     256           0 :       KernelBase::operator=(std::move(other));
+     257           0 :       log=other.log;
+     258           0 :       other.log=nullptr; // ensure no log is done in the moved away object
+     259             :     }
+     260           0 :     return *this;
+     261             :   }
+     262             : };
+     263             : 
+     264             : namespace  {
+     265             : 
+     266             : class UniformSphericalVector {
+     267             :   //double rminCub;
+     268             :   double rCub;
+     269             : 
+     270             : public:
+     271             :   //assuming rmin=0
+     272           0 :   UniformSphericalVector(const double rmax):
+     273           0 :     rCub (rmax*rmax*rmax/*-rminCub*/) {}
+     274           0 :   PLMD::Vector operator()(Random& rng) {
+     275           0 :     double rho = std::cbrt (/*rminCub + */rng.RandU01()*rCub);
+     276           0 :     double theta =std::acos (2.0*rng.RandU01() -1.0);
+     277           0 :     double phi = 2.0 * PLMD::pi * rng.RandU01();
+     278             :     return Vector (
+     279           0 :              rho * sin (theta) * cos (phi),
+     280           0 :              rho * sin (theta) * sin (phi),
+     281           0 :              rho * cos (theta));
+     282             :   }
+     283             : };
+     284             : 
+     285             : ///Acts as a template for any distribution
+     286             : struct AtomDistribution {
+     287             :   virtual void positions(std::vector<Vector>& posToUpdate, unsigned /*step*/, Random&)=0;
+     288           0 :   virtual void box(std::vector<double>& box, unsigned /*natoms*/, unsigned /*step*/, Random&) {
+     289             :     std::fill(box.begin(), box.end(),0);
+     290           0 :   };
+     291             : };
+     292             : 
+     293           0 : struct theLine:public AtomDistribution {
+     294           0 :   void positions(std::vector<Vector>& posToUpdate, unsigned step, Random&rng) override {
+     295             :     auto nat = posToUpdate.size();
+     296             :     UniformSphericalVector usv(0.5);
+     297             : 
+     298           0 :     for (unsigned i=0; i<nat; ++i) {
+     299           0 :       posToUpdate[i] = Vector(i, 0, 0) + usv(rng);
+     300             :     }
+     301           0 :   }
+     302             : };
+     303             : 
+     304           0 : struct uniformSphere:public AtomDistribution {
+     305           0 :   void positions(std::vector<Vector>& posToUpdate, unsigned /*step*/, Random& rng) override {
+     306             : 
+     307             :     //giving more or less a cubic udm of volume for each atom: V=nat
+     308           0 :     const double rmax= std::cbrt ((3.0/(4.0*PLMD::pi)) * posToUpdate.size());
+     309             : 
+     310             :     UniformSphericalVector usv(rmax);
+     311             :     auto s=posToUpdate.begin();
+     312             :     auto e=posToUpdate.end();
+     313             :     //I am using the iterators:this is slightly faster,
+     314             :     // enough to overcome the cost of the vtable that I added
+     315           0 :     for (unsigned i=0; s!=e; ++s,++i) {
+     316           0 :       *s = usv (rng);
+     317             :     }
+     318             : 
+     319           0 :   }
+     320           0 :   void box(std::vector<double>& box, unsigned natoms, unsigned /*step*/, Random&) override {
+     321           0 :     const double rmax= 2.0*std::cbrt((3.0/(4.0*PLMD::pi)) * natoms);
+     322           0 :     box[0]=rmax; box[1]=0.0;  box[2]=0.0;
+     323           0 :     box[3]=0.0;  box[4]=rmax; box[5]=0.0;
+     324           0 :     box[6]=0.0;  box[7]=0.0;  box[8]=rmax;
+     325             : 
+     326           0 :   }
+     327             : };
+     328             : 
+     329           0 : struct twoGlobs: public AtomDistribution {
+     330           0 :   virtual void positions(std::vector<Vector>& posToUpdate, unsigned /*step*/, Random&rng) {
+     331             :     //I am using two unigform spheres and 2V=n
+     332           0 :     const double rmax= std::cbrt ((3.0/(8.0*PLMD::pi)) * posToUpdate.size());
+     333             : 
+     334             :     UniformSphericalVector usv(rmax);
+     335             :     std::array<Vector,2> centers{
+     336             :       PLMD::Vector{0.0,0.0,0.0},
+     337             : //so they do not overlap
+     338             :       PLMD::Vector{2.0*rmax,2.0*rmax,2.0*rmax}
+     339           0 :     };
+     340           0 :     std::generate(posToUpdate.begin(),posToUpdate.end(),[&]() {
+     341             :       //RandInt is only declared
+     342             :       // return usv (rng) + centers[rng.RandInt(1)];
+     343           0 :       return usv (rng) + centers[rng.RandU01()>0.5];
+     344             :     });
+     345           0 :   }
+     346             : 
+     347           0 :   virtual void box(std::vector<double>& box, unsigned natoms, unsigned /*step*/, Random&) {
+     348             : 
+     349           0 :     const double rmax= 4.0 * std::cbrt ((3.0/(8.0*PLMD::pi)) * natoms);
+     350           0 :     box[0]=rmax; box[1]=0.0;  box[2]=0.0;
+     351           0 :     box[3]=0.0;  box[4]=rmax; box[5]=0.0;
+     352           0 :     box[6]=0.0;  box[7]=0.0;  box[8]=rmax;
+     353           0 :   };
+     354             : };
+     355             : 
+     356           0 : struct uniformCube:public AtomDistribution {
+     357           0 :   void positions(std::vector<Vector>& posToUpdate, unsigned /*step*/, Random& rng) override {
+     358             :     //giving more or less a cubic udm of volume for each atom: V = nat
+     359           0 :     const double rmax = std::cbrt(static_cast<double>(posToUpdate.size()));
+     360             : 
+     361             : 
+     362             : 
+     363             :     // std::generate(posToUpdate.begin(),posToUpdate.end(),[&]() {
+     364             :     //   return Vector (rndR(rng),rndR(rng),rndR(rng));
+     365             :     // });
+     366             :     auto s=posToUpdate.begin();
+     367             :     auto e=posToUpdate.end();
+     368             :     //I am using the iterators:this is slightly faster,
+     369             :     // enough to overcome the cost of the vtable that I added
+     370           0 :     for (unsigned i=0; s!=e; ++s,++i) {
+     371           0 :       *s = Vector (rng.RandU01()*rmax,rng.RandU01()*rmax,rng.RandU01()*rmax);
+     372             :     }
+     373           0 :   }
+     374           0 :   void box(std::vector<double>& box, unsigned natoms, unsigned /*step*/, Random&) override {
+     375             :     //+0.05 to avoid overlap
+     376           0 :     const double rmax= std::cbrt(natoms)+0.05;
+     377           0 :     box[0]=rmax; box[1]=0.0;  box[2]=0.0;
+     378           0 :     box[3]=0.0;  box[4]=rmax; box[5]=0.0;
+     379           0 :     box[6]=0.0;  box[7]=0.0;  box[8]=rmax;
+     380             : 
+     381           0 :   }
+     382             : };
+     383             : 
+     384           0 : struct tiledSimpleCubic:public AtomDistribution {
+     385           0 :   void positions(std::vector<Vector>& posToUpdate, unsigned /*step*/, Random& rng) override {
+     386             :     //Tiling the space in this way will not tests 100% the pbc, but
+     387             :     //I do not think that write a spacefilling curve, like Hilbert, Peano or Morton
+     388             :     //could be a good idea, in this case
+     389           0 :     const unsigned rmax = std::ceil(std::cbrt(static_cast<double>(posToUpdate.size())));
+     390             : 
+     391             :     auto s=posToUpdate.begin();
+     392             :     auto e=posToUpdate.end();
+     393             :     //I am using the iterators:this is slightly faster,
+     394             :     // enough to overcome the cost of the vtable that I added
+     395           0 :     for (unsigned k=0; k<rmax&&s!=e; ++k) {
+     396           0 :       for (unsigned j=0; j<rmax&&s!=e; ++j) {
+     397           0 :         for (unsigned i=0; i<rmax&&s!=e; ++i) {
+     398           0 :           *s = Vector (i,j,k);
+     399             :           ++s;
+     400             :         }
+     401             :       }
+     402             :     }
+     403           0 :   }
+     404           0 :   void box(std::vector<double>& box, unsigned natoms, unsigned /*step*/, Random&) override {
+     405           0 :     const double rmax= std::ceil(std::cbrt(static_cast<double>(natoms)));;
+     406           0 :     box[0]=rmax; box[1]=0.0;  box[2]=0.0;
+     407           0 :     box[3]=0.0;  box[4]=rmax; box[5]=0.0;
+     408           0 :     box[6]=0.0;  box[7]=0.0;  box[8]=rmax;
+     409             : 
+     410           0 :   }
+     411             : };
+     412           0 : std::unique_ptr<AtomDistribution> getAtomDistribution(std::string_view atomicDistr) {
+     413           0 :   std::unique_ptr<AtomDistribution> distribution;
+     414           0 :   if(atomicDistr == "line") {
+     415           0 :     distribution = std::make_unique<theLine>();
+     416           0 :   } else if (atomicDistr == "cube") {
+     417           0 :     distribution = std::make_unique<uniformCube>();
+     418           0 :   } else if (atomicDistr == "sphere") {
+     419           0 :     distribution = std::make_unique<uniformSphere>();
+     420           0 :   } else if (atomicDistr == "globs") {
+     421           0 :     distribution = std::make_unique<twoGlobs>();
+     422           0 :   } else if (atomicDistr == "sc") {
+     423           0 :     distribution = std::make_unique<tiledSimpleCubic>();
+     424             :   } else {
+     425           0 :     plumed_error() << R"(The atomic distribution can be only "line", "cube", "sphere", "globs" and "sc", the input was ")"
+     426           0 :                    << atomicDistr <<'"';
+     427             :   }
+     428           0 :   return distribution;
+     429           0 : }
+     430             : } //anonymus namespace for benchmark distributions
+     431             : class Benchmark:
+     432             :   public CLTool
+     433             : {
+     434             : public:
+     435             :   static void registerKeywords( Keywords& keys );
+     436             :   explicit Benchmark(const CLToolOptions& co );
+     437             :   int main(FILE* in, FILE*out,Communicator& pc) override;
+     438           4 :   std::string description()const override {
+     439           4 :     return "run a calculation with a fixed trajectory to find bottlenecks in PLUMED";
+     440             :   }
+     441             : };
+     442             : 
+     443       15268 : PLUMED_REGISTER_CLTOOL(Benchmark,"benchmark")
+     444             : 
+     445        5088 : void Benchmark::registerKeywords( Keywords& keys ) {
+     446        5088 :   CLTool::registerKeywords( keys );
+     447       10176 :   keys.add("compulsory","--plumed","plumed.dat","convert the input in this file to the html manual");
+     448       10176 :   keys.add("compulsory","--kernel","this","colon separated path(s) to kernel(s)");
+     449       10176 :   keys.add("compulsory","--natoms","100000","the number of atoms to use for the simulation");
+     450       10176 :   keys.add("compulsory","--nsteps","2000","number of steps of MD to perform (-1 means forever)");
+     451       10176 :   keys.add("compulsory","--maxtime","-1","maximum number of seconds (-1 means forever)");
+     452       10176 :   keys.add("compulsory","--sleep","0","number of seconds of sleep, mimicking MD calculation");
+     453       10176 :   keys.add("compulsory","--atom-distribution","line","the kind of possible atomic displacement at each step");
+     454       10176 :   keys.addFlag("--domain-decomposition",false,"simulate domain decomposition, implies --shuffle");
+     455       10176 :   keys.addFlag("--shuffled",false,"reshuffle atoms");
+     456        5088 : }
+     457             : 
+     458           4 : Benchmark::Benchmark(const CLToolOptions& co ):
+     459           4 :   CLTool(co)
+     460             : {
+     461           4 :   inputdata=commandline;
+     462           4 : }
+     463             : 
+     464             : 
+     465           0 : int Benchmark::main(FILE* in, FILE*out,Communicator& pc) {
+     466             :   // deterministic initializations to avoid issues with MPI
+     467             :   generator rng;
+     468           0 :   PLMD::Random atomicGenerator;
+     469           0 :   std::unique_ptr<AtomDistribution> distribution;
+     470             : 
+     471             :   struct FileDeleter {
+     472             :     void operator()(FILE*f) const noexcept {
+     473           0 :       if(f) std::fclose(f);
+     474           0 :     }
+     475             :   };
+     476             : 
+     477           0 :   std::unique_ptr<FILE,FileDeleter> log_dev_null{std::fopen("/dev/null","w")};
+     478             : 
+     479           0 :   Log log;
+     480           0 :   if(pc.Get_rank()==0) {
+     481           0 :     log.link(out);
+     482             :   } else {
+     483           0 :     log.link(log_dev_null.get());
+     484             :   }
+     485           0 :   log.setLinePrefix("BENCH:  ");
+     486             : 
+     487             :   std::vector<Kernel> kernels;
+     488             : 
+     489             :   // perform comparative analysis
+     490             :   // ensure that kernels vector is destroyed from last to first element upon exit
+     491           0 :   auto kernels_deleter=[&log](auto f) {
+     492           0 :     if(!f) {
+     493           0 :       return;
+     494             :     }
+     495           0 :     if(f->empty()) {
+     496             :       return;
+     497             :     }
+     498             :     generator bootstrapRng;
+     499             : 
+     500             :     const auto size=f->back().timings.size();
+     501             :     //B are the bootstrap iterations
+     502             :     constexpr int B=200;
+     503           0 :     const size_t numblocks=size;
+     504             :     // for some reasons, blocked bootstrap underestimates error
+     505             :     // For now I keep it off. If I remove it, the code below could be simplified
+     506             :     // if(numblocks>20) numblocks=20;
+     507           0 :     const auto blocksize=size/numblocks;
+     508             : 
+     509           0 :     if(f->size()<2) {
+     510           0 :       log<<"Single run, skipping comparative analysis\n";
+     511           0 :     } else if(size<10) {
+     512           0 :       log<<"Too small sample, skipping comparative analysis\n";
+     513             :     } else try {
+     514             : 
+     515           0 :         log<<"Running comparative analysis, "<<numblocks<<" blocks with size "<<blocksize<<"\n";
+     516             : 
+     517           0 :         std::vector<std::size_t> choice(size);
+     518           0 :         std::uniform_int_distribution<> distrib(0, numblocks-1);
+     519           0 :         std::vector<std::vector<long long int>> blocks(f->size());
+     520             : 
+     521             :         { int i=0;
+     522           0 :           for(auto it = f->rbegin(); it != f->rend(); ++it,++i) {
+     523             :             size_t l=0;
+     524           0 :             blocks[i].assign(numblocks,0);
+     525           0 :             for(auto j=0ULL; j<numblocks; j++) {
+     526           0 :               for(auto k=0ULL; k<blocksize; k++) {
+     527           0 :                 plumed_assert(l<it->timings.size());
+     528           0 :                 blocks[i][j]+=it->timings[l];
+     529           0 :                 l++;
+     530             :               }
+     531             :             }
+     532             :           }
+     533             :         }
+     534             : 
+     535           0 :         std::vector<std::vector<double>> ratios(f->size());
+     536           0 :         for(auto & r : ratios) {
+     537             :           //B are the bootstrap iterations
+     538           0 :           r.resize(B);
+     539             :         }
+     540             : 
+     541             :         //B are the bootstrap iterations
+     542           0 :         for(unsigned b=0; b<B; b++) {
+     543           0 :           for(auto & c : choice) c=distrib(bootstrapRng);
+     544             :           long long int reference=0;
+     545           0 :           for(auto & c : choice) {
+     546           0 :             reference+=blocks[0][c];
+     547             :           }
+     548           0 :           for(auto i=0ULL; i<blocks.size(); i++) {
+     549             :             long long int estimate=0;
+     550             :             // this would lead to separate bootstrap samples for each estimate:
+     551             :             // for(auto & c : choice){c=distrib(bootstrapRng);}
+     552           0 :             for(auto & c : choice) {
+     553           0 :               estimate+=blocks[i][c];
+     554             :             }
+     555           0 :             ratios[i][b]=double(estimate)/double(reference);
+     556             :           }
+     557             :         }
+     558             : 
+     559             :         {
+     560             :           int i=0;
+     561           0 :           for(auto it = f->rbegin(); it != f->rend(); ++it,++i) {
+     562             :             double sum=0.0;
+     563             :             double sum2=0.0;
+     564           0 :             for(auto r : ratios[i]) {
+     565           0 :               sum+=r;
+     566           0 :               sum2+=r*r;
+     567             :             }
+     568             :             //B are the bootstrap iterations
+     569           0 :             it->comparative_timing=sum/B;
+     570           0 :             it->comparative_timing_error=std::sqrt(sum2/B-sum*sum/(B*B));
+     571             :           }
+     572             :         }
+     573             : 
+     574           0 :       } catch(std::exception & e) {
+     575           0 :         log<<"Unexpected error during comparative analysis\n";
+     576           0 :         log<<e.what()<<"\n";
+     577             :       }
+     578           0 :     while(!f->empty()) f->pop_back();
+     579             : 
+     580             :   };
+     581             :   std::unique_ptr<decltype(kernels),decltype(kernels_deleter)> kernels_deleter_obj(&kernels,kernels_deleter);
+     582             : 
+     583             : 
+     584             :   // construct the kernels vector:
+     585             :   {
+     586             :     std::vector<std::string> allpaths;
+     587             : 
+     588             :     {
+     589             :       std::string paths;
+     590           0 :       parse("--kernel",paths);
+     591           0 :       allpaths=Tools::getWords(paths,":");
+     592             :     }
+     593             : 
+     594             :     std::vector<std::string> allplumed;
+     595             :     {
+     596             :       std::string paths;
+     597           0 :       parse("--plumed",paths);
+     598           0 :       allplumed=Tools::getWords(paths,":");
+     599             :     }
+     600             : 
+     601           0 :     plumed_assert(allplumed.size()>0 && allpaths.size()>0);
+     602             : 
+     603             :     // this check only works on MacOS
+     604             : #if defined(__APPLE__)
+     605             :     // if any of the paths if different from "this", we check if libplumed was loaded locally to avoid conflicts.
+     606             :     if(std::any_of(allpaths.begin(),allpaths.end(),[](auto value) {return value != "this";})) {
+     607             :       if(DLLoader::isPlumedGlobal()) {
+     608             :         plumed_error()<<"It looks like libplumed is loaded in the global namespace, you cannot load a different version of the kernel\n"
+     609             :                       <<"Please make sure you use the plumed-runtime executable and that the env var PLUMED_LOAD_NAMESPACE is not set to GLOBAL";
+     610             :       }
+     611             :     }
+     612             : #endif
+     613             : 
+     614           0 :     if(allplumed.size()>1 && allpaths.size()>1 && allplumed.size() != allpaths.size()) {
+     615           0 :       plumed_error() << "--kernel and --plumed should have either one element or the same number of elements";
+     616             :     }
+     617             : 
+     618           0 :     if(allplumed.size()>1 && allpaths.size()==1) for(unsigned i=1; i<allplumed.size(); i++) allpaths.push_back(allpaths[0]);
+     619           0 :     if(allplumed.size()==1 && allpaths.size()>1) for(unsigned i=1; i<allpaths.size(); i++) allplumed.push_back(allplumed[0]);
+     620             : 
+     621           0 :     for(unsigned i=0; i<allpaths.size(); i++) kernels.emplace_back(allpaths[i],allplumed[i],&log);
+     622           0 :   }
+     623             : 
+     624             :   // reverse order so that log happens in the forward order:
+     625           0 :   std::reverse(kernels.begin(),kernels.end());
+     626             : 
+     627             :   // read other flags:
+     628           0 :   bool shuffled=false;
+     629           0 :   parseFlag("--shuffled",shuffled);
+     630           0 :   int nf; parse("--nsteps",nf);
+     631           0 :   unsigned natoms; parse("--natoms",natoms);
+     632             : 
+     633           0 :   double maxtime; parse("--maxtime",maxtime);
+     634             : 
+     635           0 :   bool domain_decomposition=false;
+     636           0 :   parseFlag("--domain-decomposition",domain_decomposition);
+     637           0 :   if(pc.Get_size()>1) domain_decomposition=true;
+     638           0 :   if(domain_decomposition) shuffled=true;
+     639             : 
+     640             :   double timeToSleep;
+     641           0 :   parse("--sleep",timeToSleep);
+     642             : 
+     643             :   std::vector<int> shuffled_indexes;
+     644             : 
+     645             :   {
+     646             :     std::string atomicDistr;
+     647           0 :     parse("--atom-distribution",atomicDistr);
+     648           0 :     distribution = getAtomDistribution(atomicDistr);
+     649             :   }
+     650             : 
+     651           0 :   const auto initial_time=std::chrono::high_resolution_clock::now();
+     652             : 
+     653           0 :   for(auto & k : kernels) {
+     654             :     auto & p(k.handle);
+     655           0 :     auto sw=k.stopwatch.startStop("A Initialization");
+     656           0 :     if(Communicator::plumedHasMPI() && domain_decomposition) p.cmd("setMPIComm",&pc.Get_comm());
+     657           0 :     p.cmd("setRealPrecision",(int)sizeof(double));
+     658           0 :     p.cmd("setMDLengthUnits",1.0);
+     659           0 :     p.cmd("setMDChargeUnits",1.0);
+     660           0 :     p.cmd("setMDMassUnits",1.0);
+     661           0 :     p.cmd("setMDEngine","benchmarks");
+     662           0 :     p.cmd("setTimestep",1.0);
+     663           0 :     p.cmd("setPlumedDat",k.plumed_dat.c_str());
+     664           0 :     p.cmd("setLog",out);
+     665           0 :     p.cmd("setNatoms",natoms);
+     666           0 :     p.cmd("init");
+     667           0 :   }
+     668             : 
+     669           0 :   std::vector<double> cell( 9 ), virial( 9 );
+     670           0 :   std::vector<Vector> pos( natoms ), forces( natoms );
+     671           0 :   std::vector<double> masses( natoms, 1 ), charges( natoms, 0 );
+     672             : 
+     673           0 :   if(shuffled) {
+     674           0 :     shuffled_indexes.resize(natoms);
+     675           0 :     for(unsigned i=0; i<natoms; i++) shuffled_indexes[i]=i;
+     676           0 :     std::shuffle(shuffled_indexes.begin(),shuffled_indexes.end(),rng);
+     677             :   }
+     678             : 
+     679             :   // non owning pointers, used for shuffling the execution order
+     680             :   std::vector<Kernel*> kernels_ptr;
+     681           0 :   for(unsigned i=0; i<kernels.size(); i++) kernels_ptr.push_back(&kernels[i]);
+     682             : 
+     683           0 :   int plumedStopCondition=0;
+     684             :   bool fast_finish=false;
+     685             :   int part=0;
+     686             : 
+     687           0 :   log<<"Starting MD loop\n";
+     688           0 :   log<<"Use CTRL+C to stop at any time and collect timers (not working in MPI runs)\n";
+     689             :   // trap signals:
+     690           0 :   SignalHandlerGuard sigIntGuard(SIGINT, signalHandler);
+     691             : 
+     692             : 
+     693           0 :   for(int step=0; nf<0 || step<nf; ++step) {
+     694           0 :     std::shuffle(kernels_ptr.begin(),kernels_ptr.end(),rng);
+     695           0 :     distribution->positions(pos,step,atomicGenerator);
+     696           0 :     distribution->box(cell,natoms,step,atomicGenerator);
+     697             :     double* pos_ptr;
+     698             :     double* for_ptr;
+     699             :     double* charges_ptr;
+     700             :     double* masses_ptr;
+     701             :     int* indexes_ptr=nullptr;
+     702             :     int n_local_atoms;
+     703             : 
+     704           0 :     if(domain_decomposition) {
+     705           0 :       const auto nproc=pc.Get_size();
+     706           0 :       const auto nn=natoms/nproc;
+     707             :       //using int to remove warning, MPI don't work with unsigned
+     708           0 :       int excess=natoms%nproc;
+     709           0 :       const auto myrank=pc.Get_rank();
+     710             :       auto shift=0;
+     711           0 :       n_local_atoms=nn;
+     712           0 :       if(myrank<excess) n_local_atoms+=1;
+     713           0 :       for(int i=0; i<myrank; i++) {
+     714           0 :         shift+=nn;
+     715           0 :         if(i<excess) shift+=1;
+     716             :       }
+     717           0 :       pos_ptr=&pos[shift][0];
+     718           0 :       for_ptr=&forces[shift][0];
+     719             :       charges_ptr=&charges[shift];
+     720             :       masses_ptr=&masses[shift];
+     721           0 :       indexes_ptr=shuffled_indexes.data()+shift;
+     722             :     } else {
+     723           0 :       pos_ptr=&pos[0][0];
+     724           0 :       for_ptr=&forces[0][0];
+     725             :       charges_ptr=&charges[0];
+     726             :       masses_ptr=&masses[0];
+     727           0 :       n_local_atoms=natoms;
+     728             :       indexes_ptr=shuffled_indexes.data();
+     729             :     }
+     730             : 
+     731             :     const char* sw_name;
+     732           0 :     if(part==0)      sw_name="B0 First step";
+     733           0 :     else if(part==1) sw_name="B1 Warm-up";
+     734           0 :     else if(part==2) sw_name="B2 Calculation part 1";
+     735             :     else             sw_name="B3 Calculation part 2";
+     736             : 
+     737             : 
+     738           0 :     for(unsigned i=0; i<kernels_ptr.size(); i++) {
+     739           0 :       auto & p(kernels_ptr[i]->handle);
+     740             : 
+     741             :       {
+     742           0 :         auto sw=kernels_ptr[i]->stopwatch.startPause(sw_name);
+     743           0 :         p.cmd("setStep",step);
+     744           0 :         p.cmd("setStopFlag",&plumedStopCondition);
+     745           0 :         p.cmd("setForces",for_ptr,n_local_atoms*3);
+     746           0 :         p.cmd("setBox",&cell[0],9);
+     747           0 :         p.cmd("setVirial",&virial[0],9);
+     748           0 :         p.cmd("setPositions",pos_ptr,n_local_atoms*3);
+     749           0 :         p.cmd("setMasses",masses_ptr,n_local_atoms);
+     750           0 :         p.cmd("setCharges",charges_ptr,n_local_atoms);
+     751           0 :         if(shuffled) {
+     752           0 :           p.cmd("setAtomsNlocal",n_local_atoms);
+     753           0 :           p.cmd("setAtomsGatindex",indexes_ptr,n_local_atoms);
+     754             :         }
+     755           0 :         p.cmd("prepareCalc");
+     756           0 :       }
+     757             : 
+     758             :       // mimick MD calculation here
+     759             :       {
+     760             :         unsigned k=0;
+     761           0 :         auto start=std::chrono::high_resolution_clock::now();
+     762           0 :         while(std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::high_resolution_clock::now()-start).count()<(long long int)1e9*timeToSleep) k+=i*i;
+     763             :         std::fprintf(log_dev_null.get(),"%u",k);
+     764             :       }
+     765             : 
+     766             :       {
+     767           0 :         auto sw=kernels_ptr[i]->stopwatch.startStop(sw_name);
+     768           0 :         p.cmd("performCalc");
+     769           0 :       }
+     770             : 
+     771           0 :       if(kernels_ptr.size()>1 && part>1) kernels_ptr[i]->timings.push_back(kernels_ptr[i]->stopwatch.getLastCycle(sw_name));
+     772           0 :       if(plumedStopCondition || signalReceived.load()) fast_finish=true;
+     773             :     }
+     774           0 :     auto elapsed=std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::high_resolution_clock::now()-initial_time).count();
+     775           0 :     if(part==0) part=1;
+     776           0 :     if(part<2) {
+     777           0 :       if((maxtime>0 && elapsed>(long long int)(0.2*1e9*maxtime)) || (nf>0 && step+1>=nf/5) || (maxtime<0 && nf<0 && step+1>=100)) {
+     778             :         part=2;
+     779           0 :         log<<"Warm-up completed\n";
+     780             :       }
+     781             :     }
+     782           0 :     if(part<3) {
+     783           0 :       if((maxtime>0 && elapsed>(long long int)(0.6*1e9*maxtime)) || (nf>0 && step+1>=3*nf/5)) {
+     784             :         part=3;
+     785           0 :         log<<"60% completed\n";
+     786             :       }
+     787             :     }
+     788             : 
+     789           0 :     if(maxtime>0 && elapsed>(long long int)(1e9*maxtime)) fast_finish=true;
+     790             : 
+     791             :     {
+     792           0 :       unsigned tmp=fast_finish;
+     793           0 :       pc.Bcast(tmp,0);
+     794           0 :       fast_finish=tmp;
+     795             :     }
+     796           0 :     if(fast_finish) break;
+     797             :   }
+     798             : 
+     799           0 :   return 0;
+     800           0 : }
+     801             : 
+     802             : } // namespace unnamed
+     803             : } // namespace cltools
+     804             : } // namespace PLMD
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/Completion.cpp.func-sort-c.html b/coverage/cltools/Completion.cpp.func-sort-c.html new file mode 100644 index 000000000000..949bad6c0945 --- /dev/null +++ b/coverage/cltools/Completion.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - cltools/Completion.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - Completion.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:103627.8 %
Date:2024-04-19 12:12:35Functions: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_8KeywordsE5088
_ZN4PLMD7cltools12_GLOBAL__N_120CompletionRegisterMeC2Ev5088
_ZN4PLMD7cltools12_GLOBAL__N_120CompletionRegisterMeD2Ev5088
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/Completion.cpp.func.html b/coverage/cltools/Completion.cpp.func.html new file mode 100644 index 000000000000..8d36a4bc3472 --- /dev/null +++ b/coverage/cltools/Completion.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - cltools/Completion.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - Completion.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:103627.8 %
Date:2024-04-19 12:12:35Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools10Completion16registerKeywordsERNS_8KeywordsE5088
_ZN4PLMD7cltools10Completion4mainEP8_IO_FILES3_RNS_12CommunicatorE0
_ZN4PLMD7cltools10CompletionC2ERKNS_13CLToolOptionsE4
_ZN4PLMD7cltools12_GLOBAL__N_120CompletionRegisterMe6createERKNS_13CLToolOptionsE4
_ZN4PLMD7cltools12_GLOBAL__N_120CompletionRegisterMeC2Ev5088
_ZN4PLMD7cltools12_GLOBAL__N_120CompletionRegisterMeD2Ev5088
_ZNK4PLMD7cltools10Completion11descriptionB5cxx11Ev4
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/Completion.cpp.gcov.html b/coverage/cltools/Completion.cpp.gcov.html new file mode 100644 index 000000000000..7a1f5531fd16 --- /dev/null +++ b/coverage/cltools/Completion.cpp.gcov.html @@ -0,0 +1,212 @@ + + + + + + + + LCOV - plumed test coverage - cltools/Completion.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - Completion.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:103627.8 %
Date:2024-04-19 12:12:35Functions:6785.7 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools6DriverIdE16registerKeywordsERNS_8KeywordsE5088
_ZN4PLMD7cltools6DriverIdE28evaluateNumericalDerivativesERKxRNS_10PlumedMainERKSt6vectorIdSaIdEESB_SB_RS9_RKdSC_96
_ZN4PLMD7cltools6DriverIdE4mainEP8_IO_FILES4_RNS_12CommunicatorE919
_ZN4PLMD7cltools6DriverIdEC2ERKNS_13CLToolOptionsE923
_ZN4PLMD7cltools6DriverIfE16registerKeywordsERNS_8KeywordsE5088
_ZN4PLMD7cltools6DriverIfE28evaluateNumericalDerivativesERKxRNS_10PlumedMainERKSt6vectorIfSaIfEESB_SB_RS9_RKdSC_0
_ZN4PLMD7cltools6DriverIfE4mainEP8_IO_FILES4_RNS_12CommunicatorE0
_ZN4PLMD7cltools6DriverIfEC2ERKNS_13CLToolOptionsE4
_ZN4PLMD7cltoolsL11register_cbEPvPNS_7molfile11vmdplugin_tE91584
_ZNK4PLMD7cltools6DriverIdE11descriptionB5cxx11Ev4
_ZZN4PLMD7cltools6DriverIdE4mainEP8_IO_FILES4_RNS_12CommunicatorEENKUlPvE0_clES7_265
_ZZN4PLMD7cltools6DriverIfE4mainEP8_IO_FILES4_RNS_12CommunicatorEENKUlPvE0_clES7_0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/Driver.cpp.gcov.html b/coverage/cltools/Driver.cpp.gcov.html new file mode 100644 index 000000000000..137bbe0caa30 --- /dev/null +++ b/coverage/cltools/Driver.cpp.gcov.html @@ -0,0 +1,1258 @@ + + + + + + + + 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:55261789.5 %
Date:2024-04-19 12:12:35Functions:91275.0 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools12_GLOBAL__N_122DriverDoubleRegisterMe6createERKNS_13CLToolOptionsE923
_ZN4PLMD7cltools12_GLOBAL__N_122DriverDoubleRegisterMeC2Ev5088
_ZN4PLMD7cltools12_GLOBAL__N_122DriverDoubleRegisterMeD2Ev5088
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/DriverDouble.cpp.func.html b/coverage/cltools/DriverDouble.cpp.func.html new file mode 100644 index 000000000000..c2b979e59105 --- /dev/null +++ b/coverage/cltools/DriverDouble.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - cltools/DriverDouble.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - DriverDouble.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-04-19 12:12:35Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools12_GLOBAL__N_122DriverDoubleRegisterMe6createERKNS_13CLToolOptionsE923
_ZN4PLMD7cltools12_GLOBAL__N_122DriverDoubleRegisterMeC2Ev5088
_ZN4PLMD7cltools12_GLOBAL__N_122DriverDoubleRegisterMeD2Ev5088
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/DriverDouble.cpp.gcov.html b/coverage/cltools/DriverDouble.cpp.gcov.html new file mode 100644 index 000000000000..7faf2f909cd1 --- /dev/null +++ b/coverage/cltools/DriverDouble.cpp.gcov.html @@ -0,0 +1,114 @@ + + + + + + + + LCOV - plumed test coverage - cltools/DriverDouble.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - DriverDouble.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-04-19 12:12:35Functions: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       16187 : PLUMED_REGISTER_CLTOOL(DriverDouble,"driver")
+      34             : 
+      35             : }
+      36             : }
+      37             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/DriverFloat.cpp.func-sort-c.html b/coverage/cltools/DriverFloat.cpp.func-sort-c.html new file mode 100644 index 000000000000..e292a7fe30d0 --- /dev/null +++ b/coverage/cltools/DriverFloat.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - cltools/DriverFloat.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - DriverFloat.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22100.0 %
Date:2024-04-19 12:12:35Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools12_GLOBAL__N_121DriverFloatRegisterMe6createERKNS_13CLToolOptionsE4
_ZNK4PLMD7cltools6DriverIfE11descriptionB5cxx11Ev4
_ZN4PLMD7cltools12_GLOBAL__N_121DriverFloatRegisterMeC2Ev5088
_ZN4PLMD7cltools12_GLOBAL__N_121DriverFloatRegisterMeD2Ev5088
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/DriverFloat.cpp.func.html b/coverage/cltools/DriverFloat.cpp.func.html new file mode 100644 index 000000000000..376fab52ccf1 --- /dev/null +++ b/coverage/cltools/DriverFloat.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - cltools/DriverFloat.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - DriverFloat.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22100.0 %
Date:2024-04-19 12:12:35Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools12_GLOBAL__N_121DriverFloatRegisterMe6createERKNS_13CLToolOptionsE4
_ZN4PLMD7cltools12_GLOBAL__N_121DriverFloatRegisterMeC2Ev5088
_ZN4PLMD7cltools12_GLOBAL__N_121DriverFloatRegisterMeD2Ev5088
_ZNK4PLMD7cltools6DriverIfE11descriptionB5cxx11Ev4
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/DriverFloat.cpp.gcov.html b/coverage/cltools/DriverFloat.cpp.gcov.html new file mode 100644 index 000000000000..e533f0c74b33 --- /dev/null +++ b/coverage/cltools/DriverFloat.cpp.gcov.html @@ -0,0 +1,119 @@ + + + + + + + + LCOV - plumed test coverage - cltools/DriverFloat.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - DriverFloat.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22100.0 %
Date:2024-04-19 12:12:35Functions: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       15268 : PLUMED_REGISTER_CLTOOL(DriverFloat,"driver-float")
+      39             : 
+      40             : }
+      41             : }
+      42             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/GenExample.cpp.func-sort-c.html b/coverage/cltools/GenExample.cpp.func-sort-c.html new file mode 100644 index 000000000000..035797269628 --- /dev/null +++ b/coverage/cltools/GenExample.cpp.func-sort-c.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - cltools/GenExample.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - GenExample.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:172207.7 %
Date:2024-04-19 12:12:35Functions: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_8KeywordsE5088
_ZN4PLMD7cltools12_GLOBAL__N_120GenExampleRegisterMeC2Ev5088
_ZN4PLMD7cltools12_GLOBAL__N_120GenExampleRegisterMeD2Ev5088
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/GenExample.cpp.func.html b/coverage/cltools/GenExample.cpp.func.html new file mode 100644 index 000000000000..ee0cb93ea772 --- /dev/null +++ b/coverage/cltools/GenExample.cpp.func.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - cltools/GenExample.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - GenExample.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:172207.7 %
Date:2024-04-19 12:12:35Functions:6966.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools10GenExample15createLongInputERKSt6vectorIS2_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EESaISA_EE0
_ZN4PLMD7cltools10GenExample16registerKeywordsERNS_8KeywordsE5088
_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_120GenExampleRegisterMeC2Ev5088
_ZN4PLMD7cltools12_GLOBAL__N_120GenExampleRegisterMeD2Ev5088
_ZNK4PLMD7cltools10GenExample11descriptionB5cxx11Ev4
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/GenExample.cpp.gcov.html b/coverage/cltools/GenExample.cpp.gcov.html new file mode 100644 index 000000000000..f4e18af4d4af --- /dev/null +++ b/coverage/cltools/GenExample.cpp.gcov.html @@ -0,0 +1,428 @@ + + + + + + + + LCOV - plumed test coverage - cltools/GenExample.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - GenExample.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:172207.7 %
Date:2024-04-19 12:12:35Functions:6966.7 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools12_GLOBAL__N_117GenJsonRegisterMe6createERKNS_13CLToolOptionsE5
_ZN4PLMD7cltools12_GLOBAL__N_117GenJsonRegisterMeC2Ev5088
_ZN4PLMD7cltools12_GLOBAL__N_117GenJsonRegisterMeD2Ev5088
_ZN4PLMD7cltools7GenJson16registerKeywordsERNS_8KeywordsE5088
_ZN4PLMD7cltools7GenJson4mainEP8_IO_FILES3_RNS_12CommunicatorE1
_ZN4PLMD7cltools7GenJsonC2ERKNS_13CLToolOptionsE5
_ZNK4PLMD7cltools7GenJson11descriptionB5cxx11Ev4
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/GenJson.cpp.gcov.html b/coverage/cltools/GenJson.cpp.gcov.html new file mode 100644 index 000000000000..da3a4409a78b --- /dev/null +++ b/coverage/cltools/GenJson.cpp.gcov.html @@ -0,0 +1,267 @@ + + + + + + + + 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:101101100.0 %
Date:2024-04-19 12:12:35Functions:77100.0 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools11GenTemplate16registerKeywordsERNS_8KeywordsE5088
_ZN4PLMD7cltools11GenTemplate4mainEP8_IO_FILES3_RNS_12CommunicatorE0
_ZN4PLMD7cltools11GenTemplateC2ERKNS_13CLToolOptionsE4
_ZN4PLMD7cltools12_GLOBAL__N_121GenTemplateRegisterMe6createERKNS_13CLToolOptionsE4
_ZN4PLMD7cltools12_GLOBAL__N_121GenTemplateRegisterMeC2Ev5088
_ZN4PLMD7cltools12_GLOBAL__N_121GenTemplateRegisterMeD2Ev5088
_ZNK4PLMD7cltools11GenTemplate11descriptionB5cxx11Ev4
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/GenTemplate.cpp.gcov.html b/coverage/cltools/GenTemplate.cpp.gcov.html new file mode 100644 index 000000000000..cc501032debe --- /dev/null +++ b/coverage/cltools/GenTemplate.cpp.gcov.html @@ -0,0 +1,179 @@ + + + + + + + + LCOV - plumed test coverage - cltools/GenTemplate.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - GenTemplate.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:132356.5 %
Date:2024-04-19 12:12:35Functions:6785.7 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD7cltools4Info11descriptionB5cxx11Ev4
_ZN4PLMD7cltools4Info4mainEP8_IO_FILES3_RNS_12CommunicatorE2227
_ZN4PLMD7cltools12_GLOBAL__N_114InfoRegisterMe6createERKNS_13CLToolOptionsE2231
_ZN4PLMD7cltools4InfoC2ERKNS_13CLToolOptionsE2231
_ZN4PLMD7cltools12_GLOBAL__N_114InfoRegisterMeC2Ev5088
_ZN4PLMD7cltools12_GLOBAL__N_114InfoRegisterMeD2Ev5088
_ZN4PLMD7cltools4Info16registerKeywordsERNS_8KeywordsE5088
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/Info.cpp.func.html b/coverage/cltools/Info.cpp.func.html new file mode 100644 index 000000000000..b1efd37836dd --- /dev/null +++ b/coverage/cltools/Info.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - cltools/Info.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - Info.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:394783.0 %
Date:2024-04-19 12:12:35Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools12_GLOBAL__N_114InfoRegisterMe6createERKNS_13CLToolOptionsE2231
_ZN4PLMD7cltools12_GLOBAL__N_114InfoRegisterMeC2Ev5088
_ZN4PLMD7cltools12_GLOBAL__N_114InfoRegisterMeD2Ev5088
_ZN4PLMD7cltools4Info16registerKeywordsERNS_8KeywordsE5088
_ZN4PLMD7cltools4Info4mainEP8_IO_FILES3_RNS_12CommunicatorE2227
_ZN4PLMD7cltools4InfoC2ERKNS_13CLToolOptionsE2231
_ZNK4PLMD7cltools4Info11descriptionB5cxx11Ev4
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/Info.cpp.gcov.html b/coverage/cltools/Info.cpp.gcov.html new file mode 100644 index 000000000000..37a2762c9219 --- /dev/null +++ b/coverage/cltools/Info.cpp.gcov.html @@ -0,0 +1,200 @@ + + + + + + + + LCOV - plumed test coverage - cltools/Info.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - Info.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:394783.0 %
Date:2024-04-19 12:12:35Functions:77100.0 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD7cltools6Manual11descriptionB5cxx11Ev4
_ZN4PLMD7cltools6Manual4mainEP8_IO_FILES3_RNS_12CommunicatorE435
_ZN4PLMD7cltools12_GLOBAL__N_116ManualRegisterMe6createERKNS_13CLToolOptionsE439
_ZN4PLMD7cltools6ManualC2ERKNS_13CLToolOptionsE439
_ZN4PLMD7cltools12_GLOBAL__N_116ManualRegisterMeC2Ev5088
_ZN4PLMD7cltools12_GLOBAL__N_116ManualRegisterMeD2Ev5088
_ZN4PLMD7cltools6Manual16registerKeywordsERNS_8KeywordsE5088
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/Manual.cpp.func.html b/coverage/cltools/Manual.cpp.func.html new file mode 100644 index 000000000000..7008fede8d08 --- /dev/null +++ b/coverage/cltools/Manual.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - cltools/Manual.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - Manual.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2424100.0 %
Date:2024-04-19 12:12:35Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools12_GLOBAL__N_116ManualRegisterMe6createERKNS_13CLToolOptionsE439
_ZN4PLMD7cltools12_GLOBAL__N_116ManualRegisterMeC2Ev5088
_ZN4PLMD7cltools12_GLOBAL__N_116ManualRegisterMeD2Ev5088
_ZN4PLMD7cltools6Manual16registerKeywordsERNS_8KeywordsE5088
_ZN4PLMD7cltools6Manual4mainEP8_IO_FILES3_RNS_12CommunicatorE435
_ZN4PLMD7cltools6ManualC2ERKNS_13CLToolOptionsE439
_ZNK4PLMD7cltools6Manual11descriptionB5cxx11Ev4
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/Manual.cpp.gcov.html b/coverage/cltools/Manual.cpp.gcov.html new file mode 100644 index 000000000000..4fc676170afd --- /dev/null +++ b/coverage/cltools/Manual.cpp.gcov.html @@ -0,0 +1,178 @@ + + + + + + + + LCOV - plumed test coverage - cltools/Manual.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - Manual.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2424100.0 %
Date:2024-04-19 12:12:35Functions:77100.0 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools11PdbRenumber16registerKeywordsERNS_8KeywordsE5088
_ZN4PLMD7cltools11PdbRenumber4mainEP8_IO_FILES3_RNS_12CommunicatorE3
_ZN4PLMD7cltools11PdbRenumberC2ERKNS_13CLToolOptionsE7
_ZN4PLMD7cltools12_GLOBAL__N_121PdbRenumberRegisterMe6createERKNS_13CLToolOptionsE7
_ZN4PLMD7cltools12_GLOBAL__N_121PdbRenumberRegisterMeC2Ev5088
_ZN4PLMD7cltools12_GLOBAL__N_121PdbRenumberRegisterMeD2Ev5088
_ZNK4PLMD7cltools11PdbRenumber11descriptionB5cxx11Ev4
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/PdbRenumber.cpp.gcov.html b/coverage/cltools/PdbRenumber.cpp.gcov.html new file mode 100644 index 000000000000..91baad606566 --- /dev/null +++ b/coverage/cltools/PdbRenumber.cpp.gcov.html @@ -0,0 +1,275 @@ + + + + + + + + LCOV - plumed test coverage - cltools/PdbRenumber.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - PdbRenumber.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:515396.2 %
Date:2024-04-19 12:12:35Functions:77100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2018-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "CLTool.h"
+      23             : #include "core/CLToolRegister.h"
+      24             : #include "tools/Tools.h"
+      25             : #include "core/ActionRegister.h"
+      26             : #include "tools/IFile.h"
+      27             : #include "tools/OFile.h"
+      28             : #include "tools/h36.h"
+      29             : #include <cstdio>
+      30             : #include <string>
+      31             : #include <vector>
+      32             : #include <array>
+      33             : #include <limits>
+      34             : 
+      35             : namespace PLMD {
+      36             : namespace cltools {
+      37             : 
+      38             : //+PLUMEDOC TOOLS pdbrenumber
+      39             : /*
+      40             : Modify atom numbers in a PDB, possibly using hybrid-36 coding.
+      41             : 
+      42             : When reading a PDB files, PLUMED honors the serial number of each atom.
+      43             : This command can be used to process a PDB file changing the atom serial numbers.
+      44             : Notice that the resulting list might have gaps. It is however fundamental
+      45             : that atom numbers correspond to those used within the MD code.
+      46             : Importantly, if the serial number of an atom is greater than 99999, it is
+      47             : written in hybrid-36 notation (see \ref pdbreader).
+      48             : The main use of \ref pdbrenumber is thus that of producing files where atoms
+      49             : are numbered using hybrid-36 convention.
+      50             : 
+      51             : The output PDB file is identical to the input PDB file, except for the atom number
+      52             : field.
+      53             : The rest of the line is written unchanged
+      54             : to the output file, even if it is incorrectly formatted. Residue numbers are not touched,
+      55             : and atom numbers in the input file are ignored.
+      56             : 
+      57             : 
+      58             : \par Examples
+      59             : 
+      60             : By default, \ref pdbreader  just sets the numbers as progressive starting from 1.
+      61             : For instance the following command:
+      62             : \verbatim
+      63             : > plumed pdbrenumber --ipdb input.pdb --opdb output.pdb
+      64             : \endverbatim
+      65             : will copy file `input.pdb` to `output.pdb` replacing all the serial atoms with
+      66             : increasing numbers starting from one. Atoms that have an index that is greater than 99999 will be written
+      67             : in the output PDB file in hybrid-36 code.
+      68             : 
+      69             : It is possible to set a different serial number for the first atom, letting the
+      70             : following ones grow by one at each line. Here for instance the first atom
+      71             : will be assigned serial 1000, the second serial 1001, etc:
+      72             : \verbatim
+      73             : > plumed pdbrenumber --ipdb input.pdb --opdb output.pdb --firstatomnumber 1000
+      74             : \endverbatim
+      75             : If the first atom number is >99999, it should be given as a decimal number (not in hybrid-36 code).
+      76             : However, numbers >99999 in the output PDB file will be written in hybrid-36 code.
+      77             : 
+      78             : As an alternative, one can provide a list of atoms as one per line in an auxiliary file.
+      79             : \verbatim
+      80             : > plumed pdbrenumber --ipdb input.pdb --opdb output.pdb --atomnumbers list.txt
+      81             : \endverbatim
+      82             : The `list.txt` file might be something like this
+      83             : \verbatim
+      84             : 120000
+      85             : 120001
+      86             : 120002
+      87             : 1
+      88             : 2
+      89             : 3
+      90             : \endverbatim
+      91             : Numbers >99999 in the list should be provided as decimal numbers (not in hybrid-36 code).
+      92             : However, numbers >99999 in the output PDB file will be written in hybrid-36 code.
+      93             : Notice that there should be at least enough lines in `list.txt` as many atoms in the PDB file.
+      94             : Additional lines in `list.txt` will just be ignored.
+      95             : 
+      96             : 
+      97             : */
+      98             : //+ENDPLUMEDOC
+      99             : 
+     100             : class PdbRenumber:
+     101             :   public CLTool
+     102             : {
+     103             : public:
+     104             :   static void registerKeywords( Keywords& keys );
+     105             :   explicit PdbRenumber(const CLToolOptions& co );
+     106             :   int main(FILE* in, FILE*out,Communicator& pc) override;
+     107           4 :   std::string description()const override {
+     108           4 :     return "Modify atom numbers in a PDB, possibly using hybrid-36 coding";
+     109             :   }
+     110             : };
+     111             : 
+     112       15271 : PLUMED_REGISTER_CLTOOL(PdbRenumber,"pdbrenumber")
+     113             : 
+     114        5088 : void PdbRenumber::registerKeywords( Keywords& keys ) {
+     115        5088 :   CLTool::registerKeywords( keys );
+     116       10176 :   keys.add("compulsory","--ipdb","specify the name of the input PDB file");
+     117       10176 :   keys.add("compulsory","--opdb","specify the name of the output PDB file");
+     118       10176 :   keys.add("optional","--firstatomnumber","specify the desired serial number of the first atom of the output file");
+     119       10176 :   keys.add("optional","--atomnumbers","specify the desired serial numbers of the atoms of the output file using a separate list");
+     120        5088 : }
+     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/ShowGraph.cpp.func-sort-c.html b/coverage/cltools/ShowGraph.cpp.func-sort-c.html new file mode 100644 index 000000000000..acef970e2284 --- /dev/null +++ b/coverage/cltools/ShowGraph.cpp.func-sort-c.html @@ -0,0 +1,125 @@ + + + + + + + + LCOV - plumed test coverage - cltools/ShowGraph.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - ShowGraph.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:177177100.0 %
Date:2024-04-19 12:12:35Functions:1313100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD7cltools9ShowGraph11descriptionB5cxx11Ev4
_ZN4PLMD7cltools9ShowGraph4mainEP8_IO_FILES3_RNS_12CommunicatorE8
_ZN4PLMD7cltools12_GLOBAL__N_119ShowGraphRegisterMe6createERKNS_13CLToolOptionsE12
_ZN4PLMD7cltools9ShowGraphC2ERKNS_13CLToolOptionsE12
_ZN4PLMD7cltools9ShowGraph24drawActionWithVectorNodeERNS_5OFileERNS_10PlumedMainEPNS_6ActionERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISE_EERS8_IbSaIbEE30
_ZN4PLMD7cltools9ShowGraph20printAtomConnectionsEPKNS_15ActionAtomisticERjRKbRNS_5OFileE55
_ZN4PLMD7cltools9ShowGraph24printArgumentConnectionsEPKNS_19ActionWithArgumentsERjRKbRNS_5OFileE63
_ZN4PLMD7cltools9ShowGraph10printStyleERKjPKNS_5ValueERNS_5OFileE85
_ZN4PLMD7cltools9ShowGraph8getLabelB5cxx11EPKNS_6ActionERKb377
_ZN4PLMD7cltools9ShowGraph8getLabelERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKb453
_ZN4PLMD7cltools12_GLOBAL__N_119ShowGraphRegisterMeC2Ev5088
_ZN4PLMD7cltools12_GLOBAL__N_119ShowGraphRegisterMeD2Ev5088
_ZN4PLMD7cltools9ShowGraph16registerKeywordsERNS_8KeywordsE5088
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/ShowGraph.cpp.func.html b/coverage/cltools/ShowGraph.cpp.func.html new file mode 100644 index 000000000000..990fb72adb22 --- /dev/null +++ b/coverage/cltools/ShowGraph.cpp.func.html @@ -0,0 +1,125 @@ + + + + + + + + LCOV - plumed test coverage - cltools/ShowGraph.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - ShowGraph.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:177177100.0 %
Date:2024-04-19 12:12:35Functions:1313100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools12_GLOBAL__N_119ShowGraphRegisterMe6createERKNS_13CLToolOptionsE12
_ZN4PLMD7cltools12_GLOBAL__N_119ShowGraphRegisterMeC2Ev5088
_ZN4PLMD7cltools12_GLOBAL__N_119ShowGraphRegisterMeD2Ev5088
_ZN4PLMD7cltools9ShowGraph10printStyleERKjPKNS_5ValueERNS_5OFileE85
_ZN4PLMD7cltools9ShowGraph16registerKeywordsERNS_8KeywordsE5088
_ZN4PLMD7cltools9ShowGraph20printAtomConnectionsEPKNS_15ActionAtomisticERjRKbRNS_5OFileE55
_ZN4PLMD7cltools9ShowGraph24drawActionWithVectorNodeERNS_5OFileERNS_10PlumedMainEPNS_6ActionERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISE_EERS8_IbSaIbEE30
_ZN4PLMD7cltools9ShowGraph24printArgumentConnectionsEPKNS_19ActionWithArgumentsERjRKbRNS_5OFileE63
_ZN4PLMD7cltools9ShowGraph4mainEP8_IO_FILES3_RNS_12CommunicatorE8
_ZN4PLMD7cltools9ShowGraph8getLabelB5cxx11EPKNS_6ActionERKb377
_ZN4PLMD7cltools9ShowGraph8getLabelERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKb453
_ZN4PLMD7cltools9ShowGraphC2ERKNS_13CLToolOptionsE12
_ZNK4PLMD7cltools9ShowGraph11descriptionB5cxx11Ev4
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/ShowGraph.cpp.gcov.html b/coverage/cltools/ShowGraph.cpp.gcov.html new file mode 100644 index 000000000000..a900ba7b72fd --- /dev/null +++ b/coverage/cltools/ShowGraph.cpp.gcov.html @@ -0,0 +1,404 @@ + + + + + + + + LCOV - plumed test coverage - cltools/ShowGraph.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - ShowGraph.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:177177100.0 %
Date:2024-04-19 12:12:35Functions: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             : #include "CLTool.h"
+      23             : #include "core/CLToolRegister.h"
+      24             : #include "tools/Tools.h"
+      25             : #include "config/Config.h"
+      26             : #include "core/PlumedMain.h"
+      27             : #include "core/ActionSet.h"
+      28             : #include "core/ActionRegister.h"
+      29             : #include "core/ActionShortcut.h"
+      30             : #include "core/ActionToPutData.h"
+      31             : #include "core/ActionWithVirtualAtom.h"
+      32             : #include "core/ActionWithVector.h"
+      33             : #include <cstdio>
+      34             : #include <string>
+      35             : #include <iostream>
+      36             : 
+      37             : namespace PLMD {
+      38             : namespace cltools {
+      39             : 
+      40             : //+PLUMEDOC TOOLS show_graph
+      41             : /*
+      42             : show_graph is a tool that takes a plumed input and generates a graph showing how
+      43             : data flows through the action set involved.
+      44             : 
+      45             : If this tool is invoked without the --force keyword then the way data is passed through the code during the forward pass
+      46             : through the action is shown.
+      47             : 
+      48             : When the --force keyword is used then the way forces are passed from biases through actions is shown.
+      49             : 
+      50             : \par Examples
+      51             : 
+      52             : The following generates the mermaid file for the input in plumed.dat
+      53             : \verbatim
+      54             : plumed show_graph --plumed plumed.dat
+      55             : \endverbatim
+      56             : 
+      57             : */
+      58             : //+ENDPLUMEDOC
+      59             : 
+      60             : class ShowGraph :
+      61             :   public CLTool
+      62             : {
+      63             : public:
+      64             :   static void registerKeywords( Keywords& keys );
+      65             :   explicit ShowGraph(const CLToolOptions& co );
+      66             :   int main(FILE* in, FILE*out,Communicator& pc);
+      67           4 :   std::string description()const {
+      68           4 :     return "generate a graph showing how data flows through a PLUMED action set";
+      69             :   }
+      70             :   std::string getLabel(const Action* a, const bool& amp=false);
+      71             :   std::string getLabel(const std::string& s, const bool& amp=false );
+      72             :   void printStyle( const unsigned& linkcount, const Value* v, OFile& ofile );
+      73             :   void printArgumentConnections( const ActionWithArguments* a, unsigned& linkcount, const bool& force, OFile& ofile );
+      74             :   void printAtomConnections( const ActionAtomistic* a, unsigned& linkcount, const bool& force, OFile& ofile );
+      75             :   void drawActionWithVectorNode( OFile& ofile, PlumedMain& p, Action* ag, const std::vector<std::string>& mychain, std::vector<bool>& printed );
+      76             : };
+      77             : 
+      78       15276 : PLUMED_REGISTER_CLTOOL(ShowGraph,"show_graph")
+      79             : 
+      80        5088 : void ShowGraph::registerKeywords( Keywords& keys ) {
+      81        5088 :   CLTool::registerKeywords( keys );
+      82       10176 :   keys.add("compulsory","--plumed","plumed.dat","the plumed input that we are generating the graph for");
+      83       10176 :   keys.add("compulsory","--out","graph.md","the dot file containing the graph that has been generated");
+      84       10176 :   keys.addFlag("--force",false,"print a graph that shows how forces are passed through the actions");
+      85        5088 : }
+      86             : 
+      87          12 : ShowGraph::ShowGraph(const CLToolOptions& co ):
+      88          12 :   CLTool(co)
+      89             : {
+      90          12 :   inputdata=commandline;
+      91          12 : }
+      92             : 
+      93         377 : std::string ShowGraph::getLabel(const Action* a, const bool& amp) {
+      94         377 :   return getLabel( a->getLabel(), amp );
+      95             : }
+      96             : 
+      97         453 : std::string ShowGraph::getLabel( const std::string& s, const bool& amp ) {
+      98         453 :   if( s.find("@")==std::string::npos ) return s;
+      99          48 :   std::size_t p=s.find_first_of("@");
+     100          63 :   if( amp ) return "#64;" + s.substr(p+1);
+     101          33 :   return s.substr(p+1);
+     102             : }
+     103             : 
+     104          85 : void ShowGraph::printStyle( const unsigned& linkcount, const Value* v, OFile& ofile ) {
+     105          85 :   if( v->getRank()>0 && v->hasDerivatives() ) ofile.printf("linkStyle %d stroke:green,color:green;\n", linkcount);
+     106          85 :   else if( v->getRank()==1 ) ofile.printf("linkStyle %d stroke:blue,color:blue;\n", linkcount);
+     107          52 :   else if ( v->getRank()==2 ) ofile.printf("linkStyle %d stroke:red,color:red;\n", linkcount);
+     108          85 : }
+     109             : 
+     110          63 : void ShowGraph::printArgumentConnections( const ActionWithArguments* a, unsigned& linkcount, const bool& force, OFile& ofile ) {
+     111          63 :   if( !a ) return;
+     112         101 :   for(const auto & v : a->getArguments() ) {
+     113          55 :     if( force && v->forcesWereAdded() ) {
+     114          28 :       ofile.printf("%s -- %s --> %s\n", getLabel(a).c_str(), v->getName().c_str(), getLabel(v->getPntrToAction()).c_str() );
+     115          14 :       printStyle( linkcount, v, ofile ); linkcount++;
+     116          41 :     } else if( !force ) {
+     117          66 :       ofile.printf("%s -- %s --> %s\n", getLabel(v->getPntrToAction()).c_str(),v->getName().c_str(),getLabel(a).c_str() );
+     118          33 :       printStyle( linkcount, v, ofile ); linkcount++;
+     119             :     }
+     120             :   }
+     121             : }
+     122             : 
+     123          55 : void ShowGraph::printAtomConnections( const ActionAtomistic* a, unsigned& linkcount, const bool& force, OFile& ofile ) {
+     124          55 :   if( !a ) return;
+     125         179 :   for(const auto & d : a->getDependencies() ) {
+     126         138 :     ActionToPutData* dp=dynamic_cast<ActionToPutData*>(d);
+     127         138 :     if( dp && dp->getLabel()=="posx" ) {
+     128          18 :       if( force && (dp->copyOutput(0))->forcesWereAdded() ) {
+     129           8 :         ofile.printf("%s --> MD\n", getLabel(a).c_str() );
+     130           8 :         ofile.printf("linkStyle %d stroke:violet,color:violet;\n", linkcount); linkcount++;
+     131             :       } else {
+     132          10 :         ofile.printf("MD --> %s\n", getLabel(a).c_str() );
+     133          10 :         ofile.printf("linkStyle %d stroke:violet,color:violet;\n", linkcount); linkcount++;
+     134             :       }
+     135         120 :     } else if( dp && dp->getLabel()!="posy" && dp->getLabel()!="posz" && dp->getLabel()!="Masses" && dp->getLabel()!="Charges" ) {
+     136          21 :       if( force && (dp->copyOutput(0))->forcesWereAdded() ) {
+     137          18 :         ofile.printf("%s -- %s --> %s\n",getLabel(a).c_str(), getLabel(d).c_str(), getLabel(d).c_str() );
+     138           9 :         printStyle( linkcount, dp->copyOutput(0), ofile ); linkcount++;
+     139             :       } else {
+     140          24 :         ofile.printf("%s -- %s --> %s\n", getLabel(d).c_str(),getLabel(d).c_str(),getLabel(a).c_str() );
+     141          12 :         printStyle( linkcount, dp->copyOutput(0), ofile ); linkcount++;
+     142             :       }
+     143          21 :       continue;
+     144             :     }
+     145         117 :     ActionWithVirtualAtom* dv=dynamic_cast<ActionWithVirtualAtom*>(d);
+     146         117 :     if( dv ) {
+     147           4 :       if( force && (dv->copyOutput(0))->forcesWereAdded() ) {
+     148           2 :         ofile.printf("%s -- %s --> %s\n", getLabel(a).c_str(),getLabel(d).c_str(),getLabel(d).c_str() );
+     149           1 :         ofile.printf("linkStyle %d stroke:violet,color:violet;\n", linkcount); linkcount++;
+     150             :       } else {
+     151           6 :         ofile.printf("%s -- %s --> %s\n", getLabel(d).c_str(),getLabel(d).c_str(),getLabel(a).c_str() );
+     152           3 :         ofile.printf("linkStyle %d stroke:violet,color:violet;\n", linkcount); linkcount++;
+     153             :       }
+     154             :     }
+     155             :   }
+     156             : }
+     157             : 
+     158          30 : void ShowGraph::drawActionWithVectorNode( OFile& ofile, PlumedMain& p, Action* ag, const std::vector<std::string>& mychain, std::vector<bool>& printed ) {
+     159          30 :   ActionWithVector* agg=dynamic_cast<ActionWithVector*>(ag);
+     160          30 :   std::vector<std::string> matchain; agg->getAllActionLabelsInMatrixChain( matchain );
+     161          30 :   if( matchain.size()>0 ) {
+     162          16 :     ofile.printf("subgraph sub%s_mat [%s]\n",getLabel(agg).c_str(), getLabel(agg).c_str());
+     163          24 :     for(unsigned j=0; j<matchain.size(); ++j ) {
+     164          16 :       Action* agm=p.getActionSet().selectWithLabel<Action*>(matchain[j]);
+     165          60 :       for(unsigned k=0; k<mychain.size(); ++k ) {
+     166          76 :         if( mychain[k]==matchain[j] ) { printed[k]=true; break; }
+     167             :       }
+     168          32 :       ofile.printf("%s([\"label=%s \n %s \n\"])\n", getLabel(matchain[j]).c_str(), getLabel(matchain[j],true).c_str(), agm->writeInGraph().c_str() );
+     169             :     }
+     170           8 :     ofile.printf("end\n");
+     171          16 :     ofile.printf("style sub%s_mat fill:lightblue\n",getLabel(ag).c_str());
+     172          44 :   } else ofile.printf("%s([\"label=%s \n %s \n\"])\n", getLabel(ag->getLabel()).c_str(), getLabel(ag->getLabel(),true).c_str(), ag->writeInGraph().c_str() );
+     173          30 : }
+     174             : 
+     175           8 : int ShowGraph::main(FILE* in, FILE*out,Communicator& pc) {
+     176             : 
+     177          16 :   std::string inpt; parse("--plumed",inpt);
+     178           8 :   std::string outp; parse("--out",outp);
+     179           8 :   bool forces; parseFlag("--force",forces);
+     180             : 
+     181             :   // Create a plumed main object and initilize
+     182           8 :   PlumedMain p; int rr=sizeof(double);
+     183           8 :   p.cmd("setRealPrecision",&rr);
+     184           8 :   double lunit=1.0; p.cmd("setMDLengthUnits",&lunit);
+     185           8 :   double cunit=1.0; p.cmd("setMDChargeUnits",&cunit);
+     186           8 :   double munit=1.0; p.cmd("setMDMassUnits",&munit);
+     187           8 :   p.cmd("setPlumedDat",inpt.c_str());
+     188           8 :   p.cmd("setLog",out);
+     189           8 :   int natoms=1000000; p.cmd("setNatoms",&natoms);
+     190           8 :   p.cmd("init");
+     191             : 
+     192           8 :   unsigned linkcount=0; OFile ofile; ofile.open(outp);
+     193           8 :   if( forces ) {
+     194           4 :     unsigned step=1; p.cmd("setStep",step);
+     195           4 :     p.cmd("prepareCalc");
+     196           4 :     ofile.printf("flowchart BT \n"); std::vector<std::string> drawn_nodes; std::set<std::string> atom_force_set;
+     197         103 :     for(auto pp=p.getActionSet().rbegin(); pp!=p.getActionSet().rend(); ++pp) {
+     198             :       const auto & a(pp->get());
+     199         534 :       if( a->getName()=="DOMAIN_DECOMPOSITION" || a->getLabel()=="posx" || a->getLabel()=="posy" || a->getLabel()=="posz" || a->getLabel()=="Masses" || a->getLabel()=="Charges" ) continue;
+     200             : 
+     201          75 :       if(a->isActive()) {
+     202          44 :         ActionToPutData* ap=dynamic_cast<ActionToPutData*>(a);
+     203          44 :         if( ap ) {
+     204           8 :           ofile.printf("%s(\"label=%s \n %s \n\")\n", getLabel(a).c_str(), getLabel(a,true).c_str(), a->writeInGraph().c_str() );
+     205           4 :           continue;
+     206             :         }
+     207          40 :         ActionWithValue* av=dynamic_cast<ActionWithValue*>(a);
+     208          40 :         if( !av ) continue ;
+     209             :         // Now apply the force if there is one
+     210          35 :         a->apply();
+     211             :         bool hasforce=false;
+     212          67 :         for(int i=0; i<av->getNumberOfComponents(); ++i) {
+     213          42 :           if( (av->copyOutput(i))->forcesWereAdded() ) { hasforce=true; break; }
+     214             :         }
+     215             :         //Check if there are forces here
+     216          35 :         ActionWithArguments* aaa=dynamic_cast<ActionWithArguments*>(a);
+     217          35 :         if( aaa ) {
+     218          46 :           for(const auto & v : aaa->getArguments() ) {
+     219          30 :             if( v->forcesWereAdded() ) { hasforce=true; break; }
+     220             :           }
+     221             :         }
+     222          35 :         if( !hasforce ) continue;
+     223          21 :         ActionWithVector* avec=dynamic_cast<ActionWithVector*>(a);
+     224          21 :         if( avec ) {
+     225           8 :           ActionWithVector* head=avec->getFirstActionInChain();
+     226           8 :           std::vector<std::string> mychain; head->getAllActionLabelsInChain( mychain ); std::vector<bool> printed(mychain.size(),false);
+     227          16 :           ofile.printf("subgraph sub%s [%s]\n",getLabel(head).c_str(),getLabel(head).c_str());
+     228          70 :           for(unsigned i=0; i<mychain.size(); ++i) {
+     229             :             bool drawn=false;
+     230         314 :             for(unsigned j=0; j<drawn_nodes.size(); ++j ) {
+     231         294 :               if( drawn_nodes[j]==mychain[i] ) { drawn=true; break; }
+     232             :             }
+     233          62 :             if( drawn ) continue;
+     234          20 :             ActionWithVector* ag=p.getActionSet().selectWithLabel<ActionWithVector*>(mychain[i]); plumed_assert( ag ); drawn_nodes.push_back( mychain[i] );
+     235          20 :             if( !printed[i] ) { drawActionWithVectorNode( ofile, p, ag, mychain, printed ); printed[i]=true; }
+     236          41 :             for(const auto & v : ag->getArguments() ) {
+     237             :               bool chain_conn=false;
+     238         109 :               for(unsigned j=0; j<mychain.size(); ++j) {
+     239         105 :                 if( (v->getPntrToAction())->getLabel()==mychain[j] ) { chain_conn=true; break; }
+     240             :               }
+     241          21 :               if( !chain_conn ) continue;
+     242          34 :               ofile.printf("%s -. %s .-> %s\n", getLabel(v->getPntrToAction()).c_str(),v->getName().c_str(),getLabel(ag).c_str() );
+     243          17 :               printStyle( linkcount, v, ofile ); linkcount++;
+     244             :             }
+     245             :           }
+     246           8 :           ofile.printf("end\n");
+     247           8 :           if( avec!=head ) {
+     248          70 :             for(unsigned i=0; i<mychain.size(); ++i) {
+     249          62 :               ActionWithVector* c = p.getActionSet().selectWithLabel<ActionWithVector*>( mychain[i] ); plumed_assert(c);
+     250          62 :               if( c->getNumberOfAtoms()>0 || c->hasStoredArguments() ) {
+     251          60 :                 for(unsigned j=0; j<avec->getNumberOfComponents(); ++j ) {
+     252          30 :                   if( avec->copyOutput(j)->getRank()>0 ) continue;
+     253          20 :                   ofile.printf("%s == %s ==> %s\n", getLabel(avec).c_str(), avec->copyOutput(j)->getName().c_str(), getLabel(c).c_str() );
+     254          10 :                   linkcount++;
+     255             :                 }
+     256          30 :                 if( c->getNumberOfAtoms()>0 ) atom_force_set.insert( c->getLabel() );
+     257             :               }
+     258             :             }
+     259             :           }
+     260           8 :         } else {
+     261             :           // Print out the node if we have force on it
+     262          26 :           ofile.printf("%s([\"label=%s \n %s \n\"])\n", getLabel(a).c_str(), getLabel(a,true).c_str(), a->writeInGraph().c_str() );
+     263             :         }
+     264             :         // Check where this force is being added
+     265          21 :         printArgumentConnections( aaa, linkcount, true, ofile );
+     266             :       }
+     267             :     }
+     268             :     // Now draw connections from action atomistic to relevant actions
+     269           4 :     std::vector<ActionAtomistic*> all_atoms = p.getActionSet().select<ActionAtomistic*>();
+     270          33 :     for(const auto & at : all_atoms ) {
+     271          29 :       ActionWithValue* av=dynamic_cast<ActionWithValue*>(at); bool hasforce=false;
+     272          29 :       if( av ) {
+     273          44 :         for(unsigned i=0; i<av->getNumberOfComponents(); ++i ) {
+     274          26 :           if( av->copyOutput(i)->forcesWereAdded() ) {
+     275           8 :             printAtomConnections( at, linkcount, true, ofile );
+     276           8 :             atom_force_set.erase( av->getLabel() ); break;
+     277             :           }
+     278             :         }
+     279             :       }
+     280             :     }
+     281           9 :     for(const auto & l : atom_force_set ) {
+     282           5 :       ActionAtomistic* at = p.getActionSet().selectWithLabel<ActionAtomistic*>(l);
+     283           5 :       plumed_assert(at); printAtomConnections( at, linkcount, true, ofile );
+     284             :     }
+     285           4 :     ofile.printf("MD(positions from MD)\n");
+     286             :     return 0;
+     287           4 :   }
+     288             : 
+     289           4 :   ofile.printf("flowchart TB \n"); ofile.printf("MD(positions from MD)\n");
+     290          98 :   for(const auto & aa : p.getActionSet() ) {
+     291             :     Action* a(aa.get());
+     292         504 :     if( a->getName()=="DOMAIN_DECOMPOSITION" || a->getLabel()=="posx" || a->getLabel()=="posy" || a->getLabel()=="posz" || a->getLabel()=="Masses" || a->getLabel()=="Charges" ) continue;
+     293          70 :     ActionToPutData* ap=dynamic_cast<ActionToPutData*>(a);
+     294          70 :     if( ap ) {
+     295           8 :       ofile.printf("%s(\"label=%s \n %s \n\")\n", getLabel(a).c_str(), getLabel(a,true).c_str(), a->writeInGraph().c_str() );
+     296           4 :       continue;
+     297             :     }
+     298          66 :     ActionShortcut* as=dynamic_cast<ActionShortcut*>(a); if( as ) continue ;
+     299          42 :     ActionWithValue* av=dynamic_cast<ActionWithValue*>(a);
+     300          42 :     ActionWithArguments* aaa=dynamic_cast<ActionWithArguments*>(a);
+     301          42 :     ActionAtomistic* at=dynamic_cast<ActionAtomistic*>(a);
+     302          42 :     ActionWithVector* avec=dynamic_cast<ActionWithVector*>(a);
+     303             :     // Print out the connections between nodes
+     304          42 :     printAtomConnections( at, linkcount, false, ofile );
+     305          42 :     printArgumentConnections( aaa, linkcount, false, ofile );
+     306             :     // Print out the nodes
+     307          42 :     if( avec && !avec->actionInChain() ) {
+     308           6 :       ofile.printf("subgraph sub%s [%s]\n",getLabel(a).c_str(),getLabel(a).c_str());
+     309           3 :       std::vector<std::string> mychain; avec->getAllActionLabelsInChain( mychain ); std::vector<bool> printed(mychain.size(),false);
+     310          21 :       for(unsigned i=0; i<mychain.size(); ++i) {
+     311          18 :         Action* ag=p.getActionSet().selectWithLabel<Action*>(mychain[i]);
+     312          18 :         if( !printed[i] ) { drawActionWithVectorNode( ofile, p, ag, mychain, printed ); printed[i]=true; }
+     313             :       }
+     314           3 :       ofile.printf("end\n");
+     315          42 :     } else if( !av ) {
+     316          22 :       ofile.printf("%s(\"label=%s \n %s \n\")\n", getLabel(a).c_str(), getLabel(a,true).c_str(), a->writeInGraph().c_str() );
+     317          28 :     } else if( !avec ) {
+     318          26 :       ofile.printf("%s([\"label=%s \n %s \n\"])\n", getLabel(a).c_str(), getLabel(a,true).c_str(), a->writeInGraph().c_str() );
+     319             :     }
+     320             :   }
+     321           4 :   ofile.close();
+     322             : 
+     323             :   return 0;
+     324           8 : }
+     325             : 
+     326             : } // End of namespace
+     327             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/SimpleMD.cpp.func-sort-c.html b/coverage/cltools/SimpleMD.cpp.func-sort-c.html new file mode 100644 index 000000000000..83ecf1e5dcd5 --- /dev/null +++ b/coverage/cltools/SimpleMD.cpp.func-sort-c.html @@ -0,0 +1,153 @@ + + + + + + + + LCOV - plumed test coverage - cltools/SimpleMD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - SimpleMD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:231231100.0 %
Date:2024-04-19 12:12:35Functions: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_EEPKdb42
_ZN4PLMD7cltools8SimpleMD16write_statisticsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEidiiddd177
_ZN4PLMD7cltools8SimpleMD12compute_listEiRKSt6vectorINS_13VectorGenericILj3EEESaIS4_EEPKddRS2_IS2_IiSaIiEESaISC_EE437
_ZN4PLMD7cltools8SimpleMD10check_listEiRKSt6vectorINS_13VectorGenericILj3EEESaIS4_EES8_ddRb3750
_ZN4PLMD7cltools8SimpleMD14compute_engkinEiRKSt6vectorIdSaIdEERKS2_INS_13VectorGenericILj3EEESaIS8_EERd3750
_ZN4PLMD7cltools8SimpleMD14compute_forcesEiddRKSt6vectorINS_13VectorGenericILj3EEESaIS4_EEPKddRKS2_IS2_IiSaIiEESaISC_EERS6_Rd3759
_ZN4PLMD7cltools12_GLOBAL__N_118SimpleMDRegisterMeC2Ev5088
_ZN4PLMD7cltools12_GLOBAL__N_118SimpleMDRegisterMeD2Ev5088
_ZN4PLMD7cltools8SimpleMD16registerKeywordsERNS_8KeywordsE5088
_ZN4PLMD7cltools8SimpleMD10thermostatEiiRKSt6vectorIdSaIdEEdddRS2_INS_13VectorGenericILj3EEESaIS8_EERdRNS_6RandomE7500
_ZN4PLMD7cltools8SimpleMD3pbcEPKdRKNS_13VectorGenericILj3EEERS5_10165978
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/SimpleMD.cpp.func.html b/coverage/cltools/SimpleMD.cpp.func.html new file mode 100644 index 000000000000..b86fa9005de7 --- /dev/null +++ b/coverage/cltools/SimpleMD.cpp.func.html @@ -0,0 +1,153 @@ + + + + + + + + LCOV - plumed test coverage - cltools/SimpleMD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - SimpleMD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:231231100.0 %
Date:2024-04-19 12:12:35Functions:2020100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools12_GLOBAL__N_118SimpleMDRegisterMe6createERKNS_13CLToolOptionsE13
_ZN4PLMD7cltools12_GLOBAL__N_118SimpleMDRegisterMeC2Ev5088
_ZN4PLMD7cltools12_GLOBAL__N_118SimpleMDRegisterMeD2Ev5088
_ZN4PLMD7cltools8SimpleMD10check_listEiRKSt6vectorINS_13VectorGenericILj3EEESaIS4_EES8_ddRb3750
_ZN4PLMD7cltools8SimpleMD10read_inputERdS2_S2_S2_S2_RiS3_S3_RbRNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESB_SB_SB_S3_S3_S2_S2_9
_ZN4PLMD7cltools8SimpleMD10thermostatEiiRKSt6vectorIdSaIdEEdddRS2_INS_13VectorGenericILj3EEESaIS8_EERdRNS_6RandomE7500
_ZN4PLMD7cltools8SimpleMD11read_natomsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERi9
_ZN4PLMD7cltools8SimpleMD12compute_listEiRKSt6vectorINS_13VectorGenericILj3EEESaIS4_EEPKddRS2_IS2_IiSaIiEESaISC_EE437
_ZN4PLMD7cltools8SimpleMD14compute_engkinEiRKSt6vectorIdSaIdEERKS2_INS_13VectorGenericILj3EEESaIS8_EERd3750
_ZN4PLMD7cltools8SimpleMD14compute_forcesEiddRKSt6vectorINS_13VectorGenericILj3EEESaIS4_EEPKddRKS2_IS2_IiSaIiEESaISC_EERS6_Rd3759
_ZN4PLMD7cltools8SimpleMD14read_positionsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiRSt6vectorINS_13VectorGenericILj3EEESaISC_EEPd9
_ZN4PLMD7cltools8SimpleMD15write_positionsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiRKSt6vectorINS_13VectorGenericILj3EEESaISC_EEPKdb42
_ZN4PLMD7cltools8SimpleMD16registerKeywordsERNS_8KeywordsE5088
_ZN4PLMD7cltools8SimpleMD16write_statisticsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEidiiddd177
_ZN4PLMD7cltools8SimpleMD20randomize_velocitiesEiidRKSt6vectorIdSaIdEERS2_INS_13VectorGenericILj3EEESaIS8_EERNS_6RandomE9
_ZN4PLMD7cltools8SimpleMD21write_final_positionsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiRKSt6vectorINS_13VectorGenericILj3EEESaISC_EEPKdb9
_ZN4PLMD7cltools8SimpleMD3pbcEPKdRKNS_13VectorGenericILj3EEERS5_10165978
_ZN4PLMD7cltools8SimpleMD4mainEP8_IO_FILES3_RNS_12CommunicatorE9
_ZN4PLMD7cltools8SimpleMDC2ERKNS_13CLToolOptionsE13
_ZNK4PLMD7cltools8SimpleMD11descriptionB5cxx11Ev4
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/SimpleMD.cpp.gcov.html b/coverage/cltools/SimpleMD.cpp.gcov.html new file mode 100644 index 000000000000..327ae50f1e7d --- /dev/null +++ b/coverage/cltools/SimpleMD.cpp.gcov.html @@ -0,0 +1,685 @@ + + + + + + + + LCOV - plumed test coverage - cltools/SimpleMD.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - SimpleMD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:231231100.0 %
Date:2024-04-19 12:12:35Functions:2020100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "CLTool.h"
+      23             : #include "core/CLToolRegister.h"
+      24             : #include "core/PlumedMain.h"
+      25             : #include "tools/Vector.h"
+      26             : #include "tools/Random.h"
+      27             : #include "tools/OpenMP.h"
+      28             : #include <string>
+      29             : #include <cstdio>
+      30             : #include <cmath>
+      31             : #include <vector>
+      32             : #include <memory>
+      33             : 
+      34             : namespace PLMD {
+      35             : namespace cltools {
+      36             : 
+      37             : //+PLUMEDOC TOOLS simplemd
+      38             : /*
+      39             : simplemd allows one to do molecular dynamics on systems of Lennard-Jones atoms.
+      40             : 
+      41             : The input to simplemd is specified in an input file. Configurations are input and
+      42             : output in xyz format. The input file should contain one directive per line.
+      43             : The directives available are as follows:
+      44             : 
+      45             : \par Examples
+      46             : 
+      47             : You run an MD simulation using simplemd with the following command:
+      48             : \verbatim
+      49             : plumed simplemd < in
+      50             : \endverbatim
+      51             : 
+      52             : The following is an example of an input file for a simplemd calculation. This file
+      53             : instructs simplemd to do 50 steps of MD at a temperature of 0.722
+      54             : \verbatim
+      55             : inputfile input.xyz
+      56             : outputfile output.xyz
+      57             : temperature 0.722
+      58             : tstep 0.005
+      59             : friction 1
+      60             : forcecutoff 2.5
+      61             : listcutoff  3.0
+      62             : nstep 50
+      63             : nconfig 10 trajectory.xyz
+      64             : nstat   10 energies.dat
+      65             : \endverbatim
+      66             : 
+      67             : If you run the following a description of all the directives that can be used in the
+      68             : input file will be output.
+      69             : \verbatim
+      70             : plumed simplemd --help
+      71             : \endverbatim
+      72             : 
+      73             : */
+      74             : //+ENDPLUMEDOC
+      75             : 
+      76             : // simple static function to close a file
+      77             : // defined once here since it's used in many places in this file
+      78             : // in addition, this seems the only way to use it in the write_statistics_fp_deleter member
+      79             : static void (*deleter)(FILE* f) = [](auto f) { if(f) std::fclose(f); };
+      80             : 
+      81             : class SimpleMD:
+      82             :   public PLMD::CLTool
+      83             : {
+      84           4 :   std::string description()const override {
+      85           4 :     return "run lj code";
+      86             :   }
+      87             : 
+      88             :   bool write_positions_first;
+      89             :   bool write_statistics_first;
+      90             :   int write_statistics_last_time_reopened;
+      91             :   FILE* write_statistics_fp;
+      92             :   std::unique_ptr<FILE,decltype(deleter)> write_statistics_fp_deleter{nullptr,deleter};
+      93             : 
+      94             : 
+      95             : public:
+      96        5088 :   static void registerKeywords( Keywords& keys ) {
+      97       10176 :     keys.add("compulsory","nstep","The number of steps of dynamics you want to run");
+      98       10176 :     keys.add("compulsory","temperature","NVE","the temperature at which you wish to run the simulation in LJ units");
+      99       10176 :     keys.add("compulsory","friction","off","The friction (in LJ units) for the Langevin thermostat that is used to keep the temperature constant");
+     100       10176 :     keys.add("compulsory","tstep","0.005","the integration timestep in LJ units");
+     101       10176 :     keys.add("compulsory","epsilon","1.0","LJ parameter");
+     102       10176 :     keys.add("compulsory","sigma","1.0","LJ parameter");
+     103       10176 :     keys.add("compulsory","inputfile","An xyz file containing the initial configuration of the system");
+     104       10176 :     keys.add("compulsory","forcecutoff","2.5","");
+     105       10176 :     keys.add("compulsory","listcutoff","3.0","");
+     106       10176 :     keys.add("compulsory","outputfile","An output xyz file containing the final configuration of the system");
+     107       10176 :     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       10176 :     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       10176 :     keys.add("compulsory","idum","0","The random number seed");
+     110       10176 :     keys.add("compulsory","ndim","3","The dimensionality of the system (some interesting LJ clusters are two dimensional)");
+     111       10176 :     keys.add("compulsory","wrapatoms","false","If true, atomic coordinates are written wrapped in minimal cell");
+     112        5088 :   }
+     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         880 :     for(int i=0; i<natoms; i++) {
+     211         871 :       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         871 :       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        3486 :     for(int iatom=0; iatom<natoms; iatom++) for(int i=0; i<ndim; i++)
+     220        2606 :         velocities[iatom][i]=std::sqrt(temperature/masses[iatom])*random.Gaussian();
+     221           9 :   }
+     222             : 
+     223    10165978 :   void pbc(const double cell[3],const Vector & vin,Vector & vout) {
+     224             : // apply periodic boundary condition to a vector
+     225    40663912 :     for(int i=0; i<3; i++) {
+     226    30497934 :       vout[i]=vin[i]-std::floor(vin[i]/cell[i]+0.5)*cell[i];
+     227             :     }
+     228    10165978 :   }
+     229             : 
+     230        3750 :   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        3750 :     recompute=false;
+     235        3750 :     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      206750 :     for(int iatom=0; iatom<natoms; iatom++) {
+     238      203000 :       if(modulo2(positions[iatom]-positions0[iatom])>delta2) recompute=true;
+     239             :     }
+     240        3750 :   }
+     241             : 
+     242             : 
+     243         437 :   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         437 :     double listcutoff2=listcutoff*listcutoff; // squared list cutoff
+     246         437 :     list.assign(natoms,std::vector<int>());
+     247         437 :     #   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         437 :   }
+     259             : 
+     260        3759 :   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        3759 :     double forcecutoff2=forcecutoff*forcecutoff; // squared force cutoff
+     264        3759 :     engconf=0.0;
+     265             :     double engconf_tmp=0.0; // separate variable for reduction (gcc 4.8 does not make reductions on references)
+     266      819243 :     for(int i=0; i<natoms; i++)for(int k=0; k<3; k++) forces[i][k]=0.0;
+     267        3759 :     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        3759 :     #   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        3759 :     engconf=engconf_tmp;
+     297             : 
+     298        3759 :   }
+     299             : 
+     300        3750 :   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        3750 :     engkin=0.0;
+     304      206750 :     for(int iatom=0; iatom<natoms; iatom++) {
+     305      203000 :       engkin+=0.5*masses[iatom]*modulo2(velocities[iatom]);
+     306             :     }
+     307        3750 :   }
+     308             : 
+     309             : 
+     310        7500 :   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        7500 :     double c1=std::exp(-friction*dt);
+     316      413500 :     for(int iatom=0; iatom<natoms; iatom++) {
+     317      406000 :       double c2=std::sqrt((1.0-c1*c1)*temperature/masses[iatom]);
+     318     1596000 :       for(int i=0; i<ndim; i++) {
+     319     1190000 :         engint+=0.5*masses[iatom]*velocities[iatom][i]*velocities[iatom][i];
+     320     1190000 :         velocities[iatom][i]=c1*velocities[iatom][i]+c2*random.Gaussian();
+     321     1190000 :         engint-=0.5*masses[iatom]*velocities[iatom][i]*velocities[iatom][i];
+     322             :       }
+     323             :     }
+     324        7500 :   }
+     325             : 
+     326          42 :   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          42 :     Vector pos;
+     331             :     FILE*fp;
+     332          42 :     if(write_positions_first) {
+     333           9 :       fp=std::fopen(trajfile.c_str(),"w");
+     334           9 :       write_positions_first=false;
+     335             :     } else {
+     336          33 :       fp=std::fopen(trajfile.c_str(),"a");
+     337             :     }
+     338          42 :     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          42 :     std::fprintf(fp,"%f %f %f\n",cell[0],cell[1],cell[2]);
+     343        4376 :     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        4334 :       if(wrapatoms) pbc(cell,positions[iatom],pos);
+     347        3254 :       else pos=positions[iatom];
+     348        4334 :       std::fprintf(fp,"Ar %10.7f %10.7f %10.7f\n",pos[0],pos[1],pos[2]);
+     349             :     }
+     350          42 :   }
+     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         880 :     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         871 :       if(wrapatoms) pbc(cell,positions[iatom],pos);
+     367         655 :       else pos=positions[iatom];
+     368         871 :       std::fprintf(fp,"Ar %10.7f %10.7f %10.7f\n",pos[0],pos[1],pos[2]);
+     369             :     }
+     370           9 :   }
+     371             : 
+     372             : 
+     373         177 :   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         177 :     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         177 :     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          14 :       write_statistics_fp=std::fopen(statfile.c_str(),"a");
+     386             :       write_statistics_fp_deleter.reset(write_statistics_fp);
+     387          14 :       write_statistics_last_time_reopened=istep;
+     388             :     }
+     389         177 :     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         177 :   }
+     391             : 
+     392             : 
+     393             : 
+     394           9 :   int main(FILE* in,FILE*out,PLMD::Communicator& pc) override {
+     395             :     int            natoms;       // number of atoms
+     396             :     std::vector<Vector> positions;    // atomic positions
+     397             :     std::vector<Vector> velocities;   // velocities
+     398             :     std::vector<double> masses;       // masses
+     399             :     std::vector<Vector> forces;       // forces
+     400             :     double         cell[3];      // cell size
+     401             :     double         cell9[3][3];  // cell size
+     402             : 
+     403             : // neighbour list variables
+     404             : // see Allen and Tildesey book for details
+     405             :     std::vector< std::vector<int> >  list; // neighbour list
+     406             :     std::vector<Vector> positions0;   // reference atomic positions, i.e. positions when the neighbour list
+     407             : 
+     408             : // input parameters
+     409             : // all of them have a reasonable default value, set in read_input()
+     410             :     double      tstep;             // simulation timestep
+     411             :     double      temperature;       // temperature
+     412             :     double      friction;          // friction for Langevin dynamics (for NVE, use 0)
+     413             :     double      listcutoff;        // cutoff for neighbour list
+     414             :     double      forcecutoff;       // cutoff for forces
+     415             :     int         nstep;             // number of steps
+     416             :     int         nconfig;           // stride for output of configurations
+     417             :     int         nstat;             // stride for output of statistics
+     418             :     int         ndim;              // dimensionality of the system (1, 2, or 3)
+     419             :     int         idum;              // seed
+     420             :     int         plumedWantsToStop; // stop flag
+     421             :     bool        wrapatoms;         // if true, atomic coordinates are written wrapped in minimal cell
+     422             :     std::string inputfile;         // name of file with starting configuration (xyz)
+     423             :     std::string outputfile;        // name of file with final configuration (xyz)
+     424             :     std::string trajfile;          // name of the trajectory file (xyz)
+     425             :     std::string statfile;          // name of the file with statistics
+     426             : 
+     427             :     double      epsilon, sigma;    // LJ parameters
+     428             : 
+     429             :     double engkin;                 // kinetic energy
+     430             :     double engconf;                // configurational energy
+     431             :     double engint;                 // integral for conserved energy in Langevin dynamics
+     432             : 
+     433             :     bool recompute_list;           // control if the neighbour list have to be recomputed
+     434             : 
+     435           9 :     Random random;                 // random numbers stream
+     436             : 
+     437           9 :     std::unique_ptr<PlumedMain> plumed;
+     438             : 
+     439             : // Commenting the next line it is possible to switch-off plumed
+     440           9 :     plumed=Tools::make_unique<PLMD::PlumedMain>();
+     441             : 
+     442           9 :     if(plumed) plumed->cmd("setRealPrecision",int(sizeof(double)));
+     443             : 
+     444           9 :     read_input(temperature,tstep,friction,forcecutoff,
+     445             :                listcutoff,nstep,nconfig,nstat,
+     446             :                wrapatoms,inputfile,outputfile,trajfile,statfile,
+     447             :                ndim,idum,epsilon,sigma);
+     448             : 
+     449             : // number of atoms is read from file inputfile
+     450           9 :     read_natoms(inputfile,natoms);
+     451             : 
+     452             : // write the parameters in output so they can be checked
+     453             :     std::fprintf(out,"%s %s\n","Starting configuration           :",inputfile.c_str());
+     454             :     std::fprintf(out,"%s %s\n","Final configuration              :",outputfile.c_str());
+     455           9 :     std::fprintf(out,"%s %d\n","Number of atoms                  :",natoms);
+     456           9 :     std::fprintf(out,"%s %f\n","Temperature                      :",temperature);
+     457           9 :     std::fprintf(out,"%s %f\n","Time step                        :",tstep);
+     458           9 :     std::fprintf(out,"%s %f\n","Friction                         :",friction);
+     459           9 :     std::fprintf(out,"%s %f\n","Cutoff for forces                :",forcecutoff);
+     460           9 :     std::fprintf(out,"%s %f\n","Cutoff for neighbour list        :",listcutoff);
+     461           9 :     std::fprintf(out,"%s %d\n","Number of steps                  :",nstep);
+     462           9 :     std::fprintf(out,"%s %d\n","Stride for trajectory            :",nconfig);
+     463             :     std::fprintf(out,"%s %s\n","Trajectory file                  :",trajfile.c_str());
+     464           9 :     std::fprintf(out,"%s %d\n","Stride for statistics            :",nstat);
+     465             :     std::fprintf(out,"%s %s\n","Statistics file                  :",statfile.c_str());
+     466           9 :     std::fprintf(out,"%s %d\n","Dimensionality                   :",ndim);
+     467           9 :     std::fprintf(out,"%s %d\n","Seed                             :",idum);
+     468           9 :     std::fprintf(out,"%s %s\n","Are atoms wrapped on output?     :",(wrapatoms?"T":"F"));
+     469           9 :     std::fprintf(out,"%s %f\n","Epsilon                          :",epsilon);
+     470           9 :     std::fprintf(out,"%s %f\n","Sigma                            :",sigma);
+     471             : 
+     472             : // Setting the seed
+     473           9 :     random.setSeed(idum);
+     474             : 
+     475             : // allocation of dynamical arrays
+     476           9 :     positions.resize(natoms);
+     477           9 :     positions0.resize(natoms);
+     478           9 :     velocities.resize(natoms);
+     479           9 :     forces.resize(natoms);
+     480           9 :     masses.resize(natoms);
+     481           9 :     list.resize(natoms);
+     482             : 
+     483             : // masses are hard-coded to 1
+     484         880 :     for(int i=0; i<natoms; ++i) masses[i]=1.0;
+     485             : 
+     486             : // energy integral initialized to 0
+     487           9 :     engint=0.0;
+     488             : 
+     489             : // positions are read from file inputfile
+     490           9 :     read_positions(inputfile,natoms,positions,cell);
+     491             : 
+     492             : // velocities are randomized according to temperature
+     493           9 :     randomize_velocities(natoms,ndim,temperature,masses,velocities,random);
+     494             : 
+     495           9 :     if(plumed) {
+     496           9 :       plumed->cmd("setNatoms",natoms);
+     497           9 :       plumed->cmd("setNoVirial");
+     498           9 :       plumed->cmd("setMDEngine","simpleMD");
+     499           9 :       plumed->cmd("setTimestep",tstep);
+     500           9 :       plumed->cmd("setPlumedDat","plumed.dat");
+     501           9 :       int pversion=0;
+     502           9 :       plumed->cmd("getApiVersion",&pversion);
+     503             : // setting kbT is only implemented with api>1
+     504             : // even if not necessary in principle in SimpleMD (which is part of plumed)
+     505             : // we leave the check here as a reference
+     506           9 :       if(pversion>1) plumed->cmd("setKbT",temperature);
+     507           9 :       plumed->cmd("init");
+     508             :     }
+     509             : 
+     510             : // neighbour list are computed, and reference positions are saved
+     511           9 :     compute_list(natoms,positions,cell,listcutoff,list);
+     512             : 
+     513             :     int list_size=0;
+     514         880 :     for(int i=0; i<list.size(); i++) list_size+=list[i].size();
+     515             :     std::fprintf(out,"List size: %d\n",list_size);
+     516         880 :     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          15 :       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        3759 :     for(int istep=0; istep<nstep; istep++) {
+     537        3750 :       thermostat(natoms,ndim,masses,0.5*tstep,friction,temperature,velocities,engint,random);
+     538             : 
+     539      206750 :       for(int iatom=0; iatom<natoms; iatom++)
+     540      203000 :         velocities[iatom]+=forces[iatom]*0.5*tstep/masses[iatom];
+     541             : 
+     542      206750 :       for(int iatom=0; iatom<natoms; iatom++)
+     543      203000 :         positions[iatom]+=velocities[iatom]*tstep;
+     544             : 
+     545             : // a check is performed to decide whether to recalculate the neighbour list
+     546        3750 :       check_list(natoms,positions,positions0,listcutoff,forcecutoff,recompute_list);
+     547        3750 :       if(recompute_list) {
+     548         428 :         compute_list(natoms,positions,cell,listcutoff,list);
+     549       44329 :         for(int iatom=0; iatom<natoms; ++iatom) positions0[iatom]=positions[iatom];
+     550             :         int list_size=0;
+     551       44329 :         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        3750 :       compute_forces(natoms,epsilon,sigma,positions,cell,forcecutoff,list,forces,engconf);
+     556             : 
+     557        3750 :       if(plumed) {
+     558        3750 :         plumedWantsToStop=0;
+     559       48750 :         for(int i=0; i<3; i++)for(int k=0; k<3; k++) cell9[i][k]=0.0;
+     560       15000 :         for(int i=0; i<3; i++) cell9[i][i]=cell[i];
+     561        3750 :         plumed->cmd("setStep",istep+1);
+     562        3750 :         plumed->cmd("setMasses",&masses[0]);
+     563        3750 :         plumed->cmd("setForces",&forces[0][0]);
+     564        3750 :         plumed->cmd("setEnergy",engconf);
+     565        3750 :         plumed->cmd("setPositions",&positions[0][0]);
+     566        3750 :         plumed->cmd("setBox",&cell9[0][0]);
+     567        3750 :         plumed->cmd("setStopFlag",&plumedWantsToStop);
+     568        3750 :         plumed->cmd("calc");
+     569        3750 :         if(plumedWantsToStop) nstep=istep;
+     570             :       }
+     571             : // remove forces if ndim<3
+     572        3750 :       if(ndim<3)
+     573       30000 :         for(int iatom=0; iatom<natoms; ++iatom) for(int k=ndim; k<3; ++k) forces[iatom][k]=0.0;
+     574             : 
+     575      206750 :       for(int iatom=0; iatom<natoms; iatom++)
+     576      203000 :         velocities[iatom]+=forces[iatom]*0.5*tstep/masses[iatom];
+     577             : 
+     578        3750 :       thermostat(natoms,ndim,masses,0.5*tstep,friction,temperature,velocities,engint,random);
+     579             : 
+     580             : // kinetic energy is calculated
+     581        3750 :       compute_engkin(natoms,masses,velocities,engkin);
+     582             : 
+     583             : // eventually, write positions and statistics
+     584        3750 :       if((istep+1)%nconfig==0) write_positions(trajfile,natoms,positions,cell,wrapatoms);
+     585        3750 :       if((istep+1)%nstat==0)   write_statistics(statfile,istep+1,tstep,natoms,ndim,engkin,engconf,engint);
+     586             : 
+     587             :     }
+     588             : 
+     589             : // call final plumed jobs
+     590           9 :     plumed->cmd("runFinalJobs");
+     591             : 
+     592             : // write final positions
+     593           9 :     write_final_positions(outputfile,natoms,positions,cell,wrapatoms);
+     594             : 
+     595           9 :     return 0;
+     596          18 :   }
+     597             : 
+     598             : 
+     599             : };
+     600             : 
+     601       15277 : PLUMED_REGISTER_CLTOOL(SimpleMD,"simplemd")
+     602             : 
+     603             : }
+     604             : }
+     605             : 
+     606             : 
+     607             : 
+     608             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/SumHills.cpp.func-sort-c.html b/coverage/cltools/SumHills.cpp.func-sort-c.html new file mode 100644 index 000000000000..e7336871f934 --- /dev/null +++ b/coverage/cltools/SumHills.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - cltools/SumHills.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - SumHills.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:19621690.7 %
Date:2024-04-19 12:12:35Functions: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_124CLToolSumHillsRegisterMeC2Ev5088
_ZN4PLMD7cltools12_GLOBAL__N_124CLToolSumHillsRegisterMeD2Ev5088
_ZN4PLMD7cltools14CLToolSumHills16registerKeywordsERNS_8KeywordsE5088
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/SumHills.cpp.func.html b/coverage/cltools/SumHills.cpp.func.html new file mode 100644 index 000000000000..bef181f1042b --- /dev/null +++ b/coverage/cltools/SumHills.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - cltools/SumHills.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - SumHills.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:19621690.7 %
Date:2024-04-19 12:12:35Functions:88100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools12_GLOBAL__N_124CLToolSumHillsRegisterMe6createERKNS_13CLToolOptionsE13
_ZN4PLMD7cltools12_GLOBAL__N_124CLToolSumHillsRegisterMeC2Ev5088
_ZN4PLMD7cltools12_GLOBAL__N_124CLToolSumHillsRegisterMeD2Ev5088
_ZN4PLMD7cltools14CLToolSumHills16registerKeywordsERNS_8KeywordsE5088
_ZN4PLMD7cltools14CLToolSumHills18findCvsAndPeriodicERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorISA_IS7_SaIS7_EESaISC_EERSC_SG_RbRS7_SI_9
_ZN4PLMD7cltools14CLToolSumHills4mainEP8_IO_FILES3_RNS_12CommunicatorE9
_ZN4PLMD7cltools14CLToolSumHillsC2ERKNS_13CLToolOptionsE13
_ZNK4PLMD7cltools14CLToolSumHills11descriptionB5cxx11Ev4
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/SumHills.cpp.gcov.html b/coverage/cltools/SumHills.cpp.gcov.html new file mode 100644 index 000000000000..3bcd3b88d155 --- /dev/null +++ b/coverage/cltools/SumHills.cpp.gcov.html @@ -0,0 +1,702 @@ + + + + + + + + LCOV - plumed test coverage - cltools/SumHills.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - SumHills.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:19621690.7 %
Date:2024-04-19 12:12:35Functions:88100.0 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools16SwitchingPlotter4mainEP8_IO_FILES3_RNS_12CommunicatorE0
_ZZN4PLMD7cltools16SwitchingPlotter4mainEP8_IO_FILES3_RNS_12CommunicatorEENKUlvE_clEv0
_ZN4PLMD7cltools12_GLOBAL__N_126SwitchingPlotterRegisterMe6createERKNS_13CLToolOptionsE4
_ZN4PLMD7cltools16SwitchingPlotterC2ERKNS_13CLToolOptionsE4
_ZN4PLMD7cltools12_GLOBAL__N_126SwitchingPlotterRegisterMeC2Ev5088
_ZN4PLMD7cltools12_GLOBAL__N_126SwitchingPlotterRegisterMeD2Ev5088
_ZN4PLMD7cltools16SwitchingPlotter16registerKeywordsERNS_8KeywordsE5088
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/SwitchingPlotter.cpp.func.html b/coverage/cltools/SwitchingPlotter.cpp.func.html new file mode 100644 index 000000000000..d884fabb653f --- /dev/null +++ b/coverage/cltools/SwitchingPlotter.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - cltools/SwitchingPlotter.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - SwitchingPlotter.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:196827.9 %
Date:2024-04-19 12:12:35Functions:5771.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools12_GLOBAL__N_126SwitchingPlotterRegisterMe6createERKNS_13CLToolOptionsE4
_ZN4PLMD7cltools12_GLOBAL__N_126SwitchingPlotterRegisterMeC2Ev5088
_ZN4PLMD7cltools12_GLOBAL__N_126SwitchingPlotterRegisterMeD2Ev5088
_ZN4PLMD7cltools16SwitchingPlotter16registerKeywordsERNS_8KeywordsE5088
_ZN4PLMD7cltools16SwitchingPlotter4mainEP8_IO_FILES3_RNS_12CommunicatorE0
_ZN4PLMD7cltools16SwitchingPlotterC2ERKNS_13CLToolOptionsE4
_ZZN4PLMD7cltools16SwitchingPlotter4mainEP8_IO_FILES3_RNS_12CommunicatorEENKUlvE_clEv0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/SwitchingPlotter.cpp.gcov.html b/coverage/cltools/SwitchingPlotter.cpp.gcov.html new file mode 100644 index 000000000000..9bf6c3615940 --- /dev/null +++ b/coverage/cltools/SwitchingPlotter.cpp.gcov.html @@ -0,0 +1,269 @@ + + + + + + + + LCOV - plumed test coverage - cltools/SwitchingPlotter.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - SwitchingPlotter.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:196827.9 %
Date:2024-04-19 12:12:35Functions:5771.4 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 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             : 
+      23             : #include "CLTool.h"
+      24             : #include "core/CLToolRegister.h"
+      25             : #include "tools/Tools.h"
+      26             : #include "tools/SwitchingFunction.h"
+      27             : #include <string>
+      28             : #include <iostream>
+      29             : #include <iomanip>
+      30             : #include <limits>
+      31             : 
+      32             : //+PLUMEDOC TOOLS plotswitch
+      33             : /*
+      34             : plotswitch is a tool that takes a the input of a switching function and tabulates the output on the terminal
+      35             : 
+      36             : The tabulated data is compatible with gnuplot and numpy.loadtxt
+      37             : 
+      38             : Without options plotswitch will tabulate 50 points between 0 and R_0, and then continue in tabulating points with the same step until 2*R_0 or if D_MAX is set, D_MAX
+      39             : 
+      40             : Without options plotswitch will tabulate data calling calculateSqr, since should be the most used option within the various colvars
+      41             : 
+      42             : Note that if R_0 happen to be between "from" and "to" the number of steps may not be exacly the number requested in order to force r0 to be computed.
+      43             : 
+      44             : The various --rational** options use the special set option for the rational, like in COORDINATION.
+      45             : 
+      46             : \par Examples
+      47             : 
+      48             : Without option will plot the NN=6 MM=12 rational
+      49             : \verbatim
+      50             : plumed plotswitch > plot.dat
+      51             : \endverbatim
+      52             : 
+      53             : \verbatim
+      54             : plumed plotswitch --switch="RATIONAL NN=5 MM=9 R_0=1.3" --from=1.29999 --to=1.30001 --steps=100> plot.dat
+      55             : \endverbatim
+      56             : If you use this with a older plumed version you will see the discontinuity in dfunc around 1.3
+      57             : (i use gnuplot with "p 'plot.dat' u 1:3 w l t 'dfunc', 'plot.dat' u 1:2 w l axis x1y2 t 'res'")
+      58             : */
+      59             : //+ENDPLUMEDOC
+      60             : 
+      61             : namespace PLMD {
+      62             : namespace cltools {
+      63             : class SwitchingPlotter : public CLTool {
+      64             : public:
+      65             :   explicit SwitchingPlotter(const CLToolOptions&);
+      66             :   static void registerKeywords( Keywords&  );
+      67             : 
+      68             :   int main( FILE*, FILE*, Communicator& ) override;
+      69             : 
+      70             : };
+      71       15268 : PLUMED_REGISTER_CLTOOL(SwitchingPlotter,"plotswitch")
+      72             : 
+      73        5088 : void SwitchingPlotter::registerKeywords( Keywords& keys ) {
+      74        5088 :   CLTool::registerKeywords( keys );
+      75       10176 :   keys.add("compulsory","--switch",
+      76             :            "RATIONAL NN=6 R_0=1.0","the input to pass to the switching function,"
+      77             :            " please remeber the quotes");
+      78       10176 :   keys.add("compulsory","--steps","50",
+      79             :            "the number of steps between 0 and R_O, or in the specified interval");
+      80       10176 :   keys.add("compulsory","--from","-1",
+      81             :            "the start of the interval, if negative will be set to 0");
+      82       10176 :   keys.add("compulsory","--to","-1",
+      83             :            "the end of the interval, will be D_MAX or 2*R_0 if D_MAX is not set");
+      84       10176 :   keys.add("compulsory","--plotprecision","8",
+      85             :            "the precision to use for the tabulated results");
+      86       10176 :   keys.add("compulsory","--rationalR_0","-1",
+      87             :            "The r_0 parameter of the switching function, this will activate the "
+      88             :            "--rational options, note that this will ignore the --switch option silently");
+      89       10176 :   keys.add("compulsory","--rationalNN","6",
+      90             :            "The n parameter of the switching function");
+      91       10176 :   keys.add("compulsory","--rationalMM","0",
+      92             :            "The m parameter of the switching function; 0 implies 2*NN");
+      93       10176 :   keys.add("compulsory","--rationalD_0","0.0",
+      94             :            "The d_0 parameter of the switching function");
+      95       10176 :   keys.addFlag("--nosquare",false,"use calculate instead of calculateSqr");
+      96       10176 :   keys.add("compulsory","--centerrange","-1",
+      97             :            "centers the visualization in R_0 in a range given epsilons times r_0"
+      98             :            ", note that specifying this will overide all the other range options");
+      99        5088 : }
+     100             : 
+     101           4 : SwitchingPlotter::SwitchingPlotter(const CLToolOptions& co ):
+     102           4 :   CLTool(co) {
+     103           4 :   inputdata=commandline;
+     104           4 : }
+     105           0 : int SwitchingPlotter::main( FILE*, FILE*, Communicator& ) {
+     106             :   //collecting options:
+     107             :   std::string swInput;
+     108           0 :   parse("--switch",swInput);
+     109             :   bool dontOptimize;
+     110           0 :   parseFlag("--nosquare",dontOptimize);
+     111             :   int Nsteps;
+     112           0 :   parse("--steps",Nsteps);
+     113             :   double lowerLimit;
+     114           0 :   parse("--from",lowerLimit);
+     115             :   double upperLimit;
+     116           0 :   parse("--to",upperLimit);
+     117             :   unsigned plotPrecision;
+     118           0 :   parse("--plotprecision",plotPrecision);
+     119             :   int rationalNN;
+     120           0 :   parse("--rationalNN",rationalNN);
+     121             :   int rationalMM;
+     122           0 :   parse("--rationalMM",rationalMM);
+     123             :   double rationalD_0;
+     124           0 :   parse("--rationalD_0",rationalD_0);
+     125             :   double rationalR_0;
+     126           0 :   parse("--rationalR_0",rationalR_0);
+     127             :   //this works only because we use lepton to parse the numbers
+     128             :   double centerrange;
+     129           0 :   parse("--centerrange",centerrange);
+     130             :   //setting up the switching function
+     131           0 :   PLMD::SwitchingFunction switchingFunction;
+     132           0 :   if (rationalR_0>0) {
+     133           0 :     switchingFunction.set(rationalNN,rationalMM,rationalR_0,rationalD_0);
+     134             :   } else {
+     135             :     std::string errors;
+     136           0 :     switchingFunction.set(swInput,errors);
+     137           0 :     if( errors.length()!=0 ) {
+     138           0 :       error("problem reading SWITCH keyword : " + errors );
+     139             :     }
+     140             :   }
+     141             : 
+     142             :   //setting up the limits:
+     143           0 :   const double r0 = switchingFunction.get_r0();
+     144           0 :   const double dmax = switchingFunction.get_dmax();
+     145             : 
+     146           0 :   if (lowerLimit <0) {
+     147           0 :     lowerLimit=0.0;
+     148             :   }
+     149           0 :   if (upperLimit < 0) {
+     150           0 :     upperLimit = dmax;
+     151           0 :     if (! (upperLimit < std::numeric_limits<double>::max())) {
+     152           0 :       upperLimit = 2*r0;
+     153             :     }
+     154             :   }
+     155           0 :   if(centerrange>0) {
+     156           0 :     upperLimit=(1.0+centerrange*PLMD::epsilon)*r0;
+     157           0 :     lowerLimit=(1.0-centerrange*PLMD::epsilon)*r0;
+     158             :   }
+     159           0 :   const double step = [=]() {
+     160           0 :     if(r0 > lowerLimit && r0< upperLimit) {
+     161             :       //this will make the step pass trough r0
+     162           0 :       double interval = (r0-lowerLimit)/(upperLimit-lowerLimit);
+     163           0 :       return  (r0-lowerLimit)/(interval *Nsteps);
+     164             :     }
+     165           0 :     return (upperLimit-lowerLimit)/double(Nsteps);
+     166           0 :   }();
+     167           0 :   if (step <0.0) {
+     168           0 :     error("I calculated a negative step");
+     169             :   }
+     170             : 
+     171             :   //finally doing the job
+     172             :   //descriptions starts with the values of "r_0"
+     173           0 :   std::cout <<"#r val dfunc ( r_0="<<switchingFunction.description()<<")\n";
+     174           0 :   double x=lowerLimit;
+     175           0 :   while(x < upperLimit) {
+     176           0 :     double dfunc=0.0;
+     177             :     double res;
+     178           0 :     if(dontOptimize) {
+     179           0 :       res=switchingFunction.calculate(x,dfunc);
+     180             :     } else {
+     181           0 :       res=switchingFunction.calculateSqr(x*x,dfunc);
+     182             :     }
+     183           0 :     std::cout << std::setprecision(plotPrecision) << x << "\t"
+     184           0 :               << std::setprecision(plotPrecision) << res << "\t"
+     185           0 :               << std::setprecision(plotPrecision) << dfunc << '\n';
+     186           0 :     x+=step;
+     187             :   }
+     188           0 :   return 0;
+     189             : }
+     190             : 
+     191             : } //namespace cltools
+     192             : } // namespace PLMD
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/index-sort-f.html b/coverage/cltools/index-sort-f.html new file mode 100644 index 000000000000..921a88fa21b1 --- /dev/null +++ b/coverage/cltools/index-sort-f.html @@ -0,0 +1,254 @@ + + + + + + + + LCOV - plumed test coverage - cltools + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltoolsHitTotalCoverage
Test:plumed test coverageLines:1598226770.5 %
Date:2024-04-19 12:12:35Functions:12815980.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Benchmark.cpp +
6.2%6.2%
+
6.2 %19 / 30522.2 %6 / 27
GenExample.cpp +
7.7%7.7%
+
7.7 %17 / 22066.7 %6 / 9
SwitchingPlotter.cpp +
27.9%27.9%
+
27.9 %19 / 6871.4 %5 / 7
Driver.cpp +
89.5%89.5%
+
89.5 %552 / 61775.0 %9 / 12
GenTemplate.cpp +
56.5%56.5%
+
56.5 %13 / 2385.7 %6 / 7
Completion.cpp +
27.8%27.8%
+
27.8 %10 / 3685.7 %6 / 7
DriverDouble.cpp +
100.0%
+
100.0 %1 / 1100.0 %3 / 3
DriverFloat.cpp +
100.0%
+
100.0 %2 / 2100.0 %4 / 4
PdbRenumber.cpp +
96.2%96.2%
+
96.2 %51 / 53100.0 %7 / 7
kT.cpp +
100.0%
+
100.0 %19 / 19100.0 %7 / 7
Manual.cpp +
100.0%
+
100.0 %24 / 24100.0 %7 / 7
GenJson.cpp +
100.0%
+
100.0 %101 / 101100.0 %7 / 7
Info.cpp +
83.0%83.0%
+
83.0 %39 / 47100.0 %7 / 7
pesmd.cpp +
100.0%
+
100.0 %127 / 127100.0 %7 / 7
SumHills.cpp +
90.7%90.7%
+
90.7 %196 / 216100.0 %8 / 8
ShowGraph.cpp +
100.0%
+
100.0 %177 / 177100.0 %13 / 13
SimpleMD.cpp +
100.0%
+
100.0 %231 / 231100.0 %20 / 20
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/index-sort-l.html b/coverage/cltools/index-sort-l.html new file mode 100644 index 000000000000..dbc645c7be9d --- /dev/null +++ b/coverage/cltools/index-sort-l.html @@ -0,0 +1,254 @@ + + + + + + + + LCOV - plumed test coverage - cltools + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltoolsHitTotalCoverage
Test:plumed test coverageLines:1598226770.5 %
Date:2024-04-19 12:12:35Functions:12815980.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Benchmark.cpp +
6.2%6.2%
+
6.2 %19 / 30522.2 %6 / 27
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
SwitchingPlotter.cpp +
27.9%27.9%
+
27.9 %19 / 6871.4 %5 / 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
Driver.cpp +
89.5%89.5%
+
89.5 %552 / 61775.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
kT.cpp +
100.0%
+
100.0 %19 / 19100.0 %7 / 7
Manual.cpp +
100.0%
+
100.0 %24 / 24100.0 %7 / 7
GenJson.cpp +
100.0%
+
100.0 %101 / 101100.0 %7 / 7
pesmd.cpp +
100.0%
+
100.0 %127 / 127100.0 %7 / 7
ShowGraph.cpp +
100.0%
+
100.0 %177 / 177100.0 %13 / 13
SimpleMD.cpp +
100.0%
+
100.0 %231 / 231100.0 %20 / 20
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/index.html b/coverage/cltools/index.html new file mode 100644 index 000000000000..c7b464f11385 --- /dev/null +++ b/coverage/cltools/index.html @@ -0,0 +1,254 @@ + + + + + + + + LCOV - plumed test coverage - cltools + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltoolsHitTotalCoverage
Test:plumed test coverageLines:1598226770.5 %
Date:2024-04-19 12:12:35Functions:12815980.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Benchmark.cpp +
6.2%6.2%
+
6.2 %19 / 30522.2 %6 / 27
Completion.cpp +
27.8%27.8%
+
27.8 %10 / 3685.7 %6 / 7
Driver.cpp +
89.5%89.5%
+
89.5 %552 / 61775.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 %101 / 101100.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
ShowGraph.cpp +
100.0%
+
100.0 %177 / 177100.0 %13 / 13
SimpleMD.cpp +
100.0%
+
100.0 %231 / 231100.0 %20 / 20
SumHills.cpp +
90.7%90.7%
+
90.7 %196 / 216100.0 %8 / 8
SwitchingPlotter.cpp +
27.9%27.9%
+
27.9 %19 / 6871.4 %5 / 7
kT.cpp +
100.0%
+
100.0 %19 / 19100.0 %7 / 7
pesmd.cpp +
100.0%
+
100.0 %127 / 127100.0 %7 / 7
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/kT.cpp.func-sort-c.html b/coverage/cltools/kT.cpp.func-sort-c.html new file mode 100644 index 000000000000..a5ad084c4bac --- /dev/null +++ b/coverage/cltools/kT.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - cltools/kT.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - kT.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1919100.0 %
Date:2024-04-19 12:12:35Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD7cltools2kt11descriptionB5cxx11Ev4
_ZN4PLMD7cltools2kt4mainEP8_IO_FILES3_RNS_12CommunicatorE6
_ZN4PLMD7cltools12_GLOBAL__N_112ktRegisterMe6createERKNS_13CLToolOptionsE10
_ZN4PLMD7cltools2ktC2ERKNS_13CLToolOptionsE10
_ZN4PLMD7cltools12_GLOBAL__N_112ktRegisterMeC2Ev5088
_ZN4PLMD7cltools12_GLOBAL__N_112ktRegisterMeD2Ev5088
_ZN4PLMD7cltools2kt16registerKeywordsERNS_8KeywordsE5088
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/kT.cpp.func.html b/coverage/cltools/kT.cpp.func.html new file mode 100644 index 000000000000..f1b0dfe4f3bf --- /dev/null +++ b/coverage/cltools/kT.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - cltools/kT.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - kT.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1919100.0 %
Date:2024-04-19 12:12:35Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools12_GLOBAL__N_112ktRegisterMe6createERKNS_13CLToolOptionsE10
_ZN4PLMD7cltools12_GLOBAL__N_112ktRegisterMeC2Ev5088
_ZN4PLMD7cltools12_GLOBAL__N_112ktRegisterMeD2Ev5088
_ZN4PLMD7cltools2kt16registerKeywordsERNS_8KeywordsE5088
_ZN4PLMD7cltools2kt4mainEP8_IO_FILES3_RNS_12CommunicatorE6
_ZN4PLMD7cltools2ktC2ERKNS_13CLToolOptionsE10
_ZNK4PLMD7cltools2kt11descriptionB5cxx11Ev4
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/kT.cpp.gcov.html b/coverage/cltools/kT.cpp.gcov.html new file mode 100644 index 000000000000..b0057e3a6ec6 --- /dev/null +++ b/coverage/cltools/kT.cpp.gcov.html @@ -0,0 +1,164 @@ + + + + + + + + LCOV - plumed test coverage - cltools/kT.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - kT.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1919100.0 %
Date:2024-04-19 12:12:35Functions: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 "CLTool.h"
+      23             : #include "core/CLToolRegister.h"
+      24             : #include "tools/Tools.h"
+      25             : #include "config/Config.h"
+      26             : #include "tools/Units.h"
+      27             : #include "core/ActionRegister.h"
+      28             : #include <cstdio>
+      29             : #include <string>
+      30             : 
+      31             : namespace PLMD {
+      32             : namespace cltools {
+      33             : 
+      34             : //+PLUMEDOC TOOLS kt
+      35             : /*
+      36             : Print out the value of \f$k_BT\f$ at a particular temperature
+      37             : 
+      38             : \par Examples
+      39             : 
+      40             : The following command will tell you the value of \f$k_BT\f$ when T is equal
+      41             : to 300 K in eV
+      42             : 
+      43             : \verbatim
+      44             : plumed kt --temp 300 --units eV
+      45             : \endverbatim
+      46             : 
+      47             : */
+      48             : //+ENDPLUMEDOC
+      49             : 
+      50             : class kt:
+      51             :   public CLTool
+      52             : {
+      53             : public:
+      54             :   static void registerKeywords( Keywords& keys );
+      55             :   explicit kt(const CLToolOptions& co );
+      56             :   int main(FILE* in, FILE*out,Communicator& pc) override;
+      57           4 :   std::string description()const override {
+      58           4 :     return "print out the value of kT at a particular temperature";
+      59             :   }
+      60             : };
+      61             : 
+      62       15274 : PLUMED_REGISTER_CLTOOL(kt,"kt")
+      63             : 
+      64        5088 : void kt::registerKeywords( Keywords& keys ) {
+      65        5088 :   CLTool::registerKeywords( keys );
+      66       10176 :   keys.add("compulsory","--temp","print the manual for this particular action");
+      67       10176 :   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        5088 : }
+      69             : 
+      70          10 : kt::kt(const CLToolOptions& co ):
+      71          10 :   CLTool(co)
+      72             : {
+      73          10 :   inputdata=commandline;
+      74          10 : }
+      75             : 
+      76           6 : int kt::main(FILE* in, FILE*out,Communicator& pc) {
+      77             : 
+      78           6 :   std::string unitname; parse("--units",unitname);
+      79           6 :   Units units; units.setEnergy( unitname );
+      80           6 :   double temp; parse("--temp",temp);
+      81           6 :   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           6 :   return 0;
+      84           6 : }
+      85             : 
+      86             : } // End of namespace
+      87             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/pesmd.cpp.func-sort-c.html b/coverage/cltools/pesmd.cpp.func-sort-c.html new file mode 100644 index 000000000000..de6630e826f9 --- /dev/null +++ b/coverage/cltools/pesmd.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - cltools/pesmd.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - pesmd.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:127127100.0 %
Date:2024-04-19 12:12:35Functions: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_115PesMDRegisterMeC2Ev5088
_ZN4PLMD7cltools12_GLOBAL__N_115PesMDRegisterMeD2Ev5088
_ZN4PLMD7cltools5PesMD16registerKeywordsERNS_8KeywordsE5088
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/pesmd.cpp.func.html b/coverage/cltools/pesmd.cpp.func.html new file mode 100644 index 000000000000..856856275eb8 --- /dev/null +++ b/coverage/cltools/pesmd.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - cltools/pesmd.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - pesmd.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:127127100.0 %
Date:2024-04-19 12:12:35Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools12_GLOBAL__N_115PesMDRegisterMe6createERKNS_13CLToolOptionsE7
_ZN4PLMD7cltools12_GLOBAL__N_115PesMDRegisterMeC2Ev5088
_ZN4PLMD7cltools12_GLOBAL__N_115PesMDRegisterMeD2Ev5088
_ZN4PLMD7cltools5PesMD10read_inputERdS2_S2_RiRNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIdSaIdEES3_RbSE_S3_3
_ZN4PLMD7cltools5PesMD16registerKeywordsERNS_8KeywordsE5088
_ZN4PLMD7cltools5PesMD4mainEP8_IO_FILES3_RNS_12CommunicatorE3
_ZNK4PLMD7cltools5PesMD11descriptionB5cxx11Ev4
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/pesmd.cpp.gcov.html b/coverage/cltools/pesmd.cpp.gcov.html new file mode 100644 index 000000000000..5b37630d65f0 --- /dev/null +++ b/coverage/cltools/pesmd.cpp.gcov.html @@ -0,0 +1,389 @@ + + + + + + + + LCOV - plumed test coverage - cltools/pesmd.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - pesmd.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:127127100.0 %
Date:2024-04-19 12:12:35Functions:77100.0 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8clusters15ClusterDiameterC2ERKNS_13ActionOptionsE0
_ZN4PLMD8clusters15ClusterDiameterC1ERKNS_13ActionOptionsE2
_ZN4PLMD8clusters15ClusterDiameter16registerKeywordsERNS_8KeywordsE4
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/clusters/ClusterDiameter.cpp.func.html b/coverage/clusters/ClusterDiameter.cpp.func.html new file mode 100644 index 000000000000..40065d897386 --- /dev/null +++ b/coverage/clusters/ClusterDiameter.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - clusters/ClusterDiameter.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - clusters - ClusterDiameter.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1616100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8clusters15ClusterDiameter16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD8clusters15ClusterDiameterC1ERKNS_13ActionOptionsE2
_ZN4PLMD8clusters15ClusterDiameterC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/clusters/ClusterDiameter.cpp.gcov.html b/coverage/clusters/ClusterDiameter.cpp.gcov.html new file mode 100644 index 000000000000..d5c9c9b532f5 --- /dev/null +++ b/coverage/clusters/ClusterDiameter.cpp.gcov.html @@ -0,0 +1,175 @@ + + + + + + + + LCOV - plumed test coverage - clusters/ClusterDiameter.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - clusters - ClusterDiameter.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1616100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2020 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received 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             : //+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 clusters {
+      62             : 
+      63             : class ClusterDiameter : public ActionShortcut {
+      64             : public:
+      65             :   static void registerKeywords(Keywords& keys);
+      66             :   explicit ClusterDiameter(const ActionOptions&);
+      67             : };
+      68             : 
+      69             : PLUMED_REGISTER_ACTION(ClusterDiameter,"CLUSTER_DIAMETER")
+      70             : 
+      71           4 : void ClusterDiameter::registerKeywords( Keywords& keys ) {
+      72           4 :   ActionShortcut::registerKeywords( keys );
+      73           8 :   keys.add("optional","ARG","calculate ths radius of the cluster that are in this particular cluster");
+      74           8 :   keys.add("compulsory","ATOMS","the atoms that were used to calculate the matrix that was clustered");
+      75          12 :   keys.needsAction("DISTANCE_MATRIX"); keys.needsAction("OUTER_PRODUCT"); keys.needsAction("CUSTOM");
+      76           8 :   keys.needsAction("FLATTEN"); keys.needsAction("HIGHEST");
+      77           4 : }
+      78             : 
+      79           2 : ClusterDiameter::ClusterDiameter(const ActionOptions& ao):
+      80             :   Action(ao),
+      81           2 :   ActionShortcut(ao)
+      82             : {
+      83             :   // Read in the argument
+      84           4 :   std::string arg_str, atdata; parse("ARG",arg_str); parse("ATOMS",atdata);
+      85             :   // Distance matrix
+      86           4 :   readInputLine( getShortcutLabel() + "_dmat: DISTANCE_MATRIX GROUP=" + atdata );
+      87             :   // Matrix of bonds in cluster
+      88           4 :   readInputLine( getShortcutLabel() + "_bmat: OUTER_PRODUCT FUNC=x*y ARG=" + arg_str + "," + arg_str );
+      89             :   // Product of matrices
+      90           4 :   readInputLine( getShortcutLabel() + "_dcls: CUSTOM ARG=" + getShortcutLabel() + "_dmat," + getShortcutLabel() + "_bmat FUNC=x*y PERIODIC=NO");
+      91             :   // Convert matrix to a vector to get highest
+      92           4 :   readInputLine( getShortcutLabel() + "_vdcls: FLATTEN ARG=" + getShortcutLabel() + "_dcls" );
+      93             :   // And take the highest value
+      94           4 :   readInputLine( getShortcutLabel() + ": HIGHEST ARG=" + getShortcutLabel() + "_vdcls");
+      95           2 : }
+      96             : 
+      97             : }
+      98             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/clusters/ClusterDistribution.cpp.func-sort-c.html b/coverage/clusters/ClusterDistribution.cpp.func-sort-c.html new file mode 100644 index 000000000000..44ad56af6654 --- /dev/null +++ b/coverage/clusters/ClusterDistribution.cpp.func-sort-c.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - clusters/ClusterDistribution.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - clusters - ClusterDistribution.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:545794.7 %
Date:2024-04-19 12:12:35Functions:6966.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8clusters19ClusterDistribution22getNumberOfDerivativesEv0
_ZN4PLMD8clusters19ClusterDistributionC2ERKNS_13ActionOptionsE0
_ZN4PLMD8clusters27ClusterDistributionShortcutC2ERKNS_13ActionOptionsE0
_ZN4PLMD8clusters19ClusterDistribution5applyEv2
_ZN4PLMD8clusters19ClusterDistribution9calculateEv2
_ZN4PLMD8clusters19ClusterDistributionC1ERKNS_13ActionOptionsE2
_ZN4PLMD8clusters27ClusterDistributionShortcutC1ERKNS_13ActionOptionsE2
_ZN4PLMD8clusters19ClusterDistribution16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD8clusters27ClusterDistributionShortcut16registerKeywordsERNS_8KeywordsE6
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/clusters/ClusterDistribution.cpp.func.html b/coverage/clusters/ClusterDistribution.cpp.func.html new file mode 100644 index 000000000000..39e93e331f0f --- /dev/null +++ b/coverage/clusters/ClusterDistribution.cpp.func.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - clusters/ClusterDistribution.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - clusters - ClusterDistribution.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:545794.7 %
Date:2024-04-19 12:12:35Functions:6966.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8clusters19ClusterDistribution16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD8clusters19ClusterDistribution22getNumberOfDerivativesEv0
_ZN4PLMD8clusters19ClusterDistribution5applyEv2
_ZN4PLMD8clusters19ClusterDistribution9calculateEv2
_ZN4PLMD8clusters19ClusterDistributionC1ERKNS_13ActionOptionsE2
_ZN4PLMD8clusters19ClusterDistributionC2ERKNS_13ActionOptionsE0
_ZN4PLMD8clusters27ClusterDistributionShortcut16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD8clusters27ClusterDistributionShortcutC1ERKNS_13ActionOptionsE2
_ZN4PLMD8clusters27ClusterDistributionShortcutC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/clusters/ClusterDistribution.cpp.gcov.html b/coverage/clusters/ClusterDistribution.cpp.gcov.html new file mode 100644 index 000000000000..6630e784b1e6 --- /dev/null +++ b/coverage/clusters/ClusterDistribution.cpp.gcov.html @@ -0,0 +1,261 @@ + + + + + + + + LCOV - plumed test coverage - clusters/ClusterDistribution.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - clusters - ClusterDistribution.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:545794.7 %
Date:2024-04-19 12:12:35Functions:6966.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2020 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received 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/ActionWithArguments.h"
+      24             : #include "core/ActionRegister.h"
+      25             : #include "core/ActionShortcut.h"
+      26             : #include "core/PlumedMain.h"
+      27             : #include "multicolvar/MultiColvarShortcuts.h"
+      28             : #include "ClusteringBase.h"
+      29             : 
+      30             : //+PLUMEDOC CONCOMP CLUSTER_DISTRIBUTION
+      31             : /*
+      32             : Calculate functions of the distribution of properties in your connected components.
+      33             : 
+      34             : This collective variable was developed for looking at nucleation phenomena, where you are
+      35             : interested in using studying the behavior of atoms in small aggregates or nuclei.  In these sorts of
+      36             : problems you might be interested in the distribution of the sizes of the clusters in your system.
+      37             : A detailed description of this CV can be found in \cite tribello-clustering.
+      38             : 
+      39             : \par Examples
+      40             : 
+      41             : The input provided below calculates the local q6 Steinhardt parameter on each atom.  The coordination number
+      42             : that atoms with a high value for the local q6 Steinhardt parameter have with other atoms that have a high
+      43             : value for the local q6 Steinhardt parameter is then computed.  A contact matrix is then computed that measures
+      44             : whether atoms atoms \f$i\f$ and \f$j\f$ have a high value for this coordination number and if they are within
+      45             : 3.6 nm of each other.  The connected components of this matrix are then found using a depth first clustering
+      46             : algorithm on the corresponding graph. The number of components in this graph that contain more than 27 atoms is then computed.
+      47             : 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
+      48             : GeTe.
+      49             : 
+      50             : \plumedfile
+      51             : q6: Q6 SPECIES=1-300 SWITCH={GAUSSIAN D_0=5.29 R_0=0.01 D_MAX=5.3} LOWMEM
+      52             : lq6: LOCAL_Q6 SPECIES=q6 SWITCH={GAUSSIAN D_0=5.29 R_0=0.01 D_MAX=5.3} LOWMEM
+      53             : flq6: MFILTER_MORE DATA=lq6 SWITCH={GAUSSIAN D_0=0.19 R_0=0.01 D_MAX=0.2}
+      54             : cc: COORDINATIONNUMBER SPECIES=flq6 SWITCH={GAUSSIAN D_0=3.59 R_0=0.01 D_MAX=3.6}
+      55             : fcc: MFILTER_MORE DATA=cc SWITCH={GAUSSIAN D_0=5.99 R_0=0.01 D_MAX=6.0}
+      56             : mat: CONTACT_MATRIX ATOMS=fcc SWITCH={GAUSSIAN D_0=3.59 R_0=0.01 D_MAX=3.6}
+      57             : dfs: DFSCLUSTERING MATRIX=mat
+      58             : 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}
+      59             : PRINT ARG=nclust.* FILE=colvar
+      60             : \endplumedfile
+      61             : 
+      62             : */
+      63             : //+ENDPLUMEDOC
+      64             : 
+      65             : //+PLUMEDOC CONCOMP CLUSTER_DISTRIBUTION_CALC
+      66             : /*
+      67             : Calculate functions of the distribution of properties in your connected components.
+      68             : 
+      69             : See \ref CLUSTER_DISTRIBUTION
+      70             : 
+      71             : \par Examples
+      72             : 
+      73             : */
+      74             : //+ENDPLUMEDOC
+      75             : 
+      76             : 
+      77             : namespace PLMD {
+      78             : namespace clusters {
+      79             : 
+      80             : class ClusterDistribution :
+      81             :   public ActionWithArguments,
+      82             :   public ActionWithValue {
+      83             : public:
+      84             : /// Create manual
+      85             :   static void registerKeywords( Keywords& keys );
+      86             : /// Constructor
+      87             :   explicit ClusterDistribution(const ActionOptions&);
+      88             : /// The number of derivatives
+      89             :   unsigned getNumberOfDerivatives() override ;
+      90             : /// Do the calculation
+      91             :   void calculate() override;
+      92             : /// We can use ActionWithVessel to run all the calculation
+      93           2 :   void apply() override {}
+      94             : };
+      95             : 
+      96             : PLUMED_REGISTER_ACTION(ClusterDistribution,"CLUSTER_DISTRIBUTION_CALC")
+      97             : 
+      98           4 : void ClusterDistribution::registerKeywords( Keywords& keys ) {
+      99           4 :   Action::registerKeywords( keys );
+     100           4 :   ActionWithArguments::registerKeywords( keys );
+     101           4 :   ActionWithValue::registerKeywords( keys ); keys.remove("NUMERICAL_DERIVATIVES");
+     102           8 :   keys.add("compulsory","CLUSTERS","the label of the action that does the clustering");
+     103           8 :   keys.add("optional","WEIGHTS","use the vector of values calculated by this action as weights rather than giving each atom a unit weight");
+     104           4 : }
+     105             : 
+     106           2 : ClusterDistribution::ClusterDistribution(const ActionOptions&ao):
+     107             :   Action(ao),
+     108             :   ActionWithArguments(ao),
+     109           2 :   ActionWithValue(ao)
+     110             : {
+     111             :   // Read in the clustering object
+     112           4 :   std::vector<Value*> clusters; parseArgumentList("CLUSTERS",clusters);
+     113           2 :   if( clusters.size()!=1 ) error("should pass only one matrix to clustering base");
+     114           2 :   ClusteringBase* cc = dynamic_cast<ClusteringBase*>( clusters[0]->getPntrToAction() );
+     115           2 :   if( !cc ) error("input to CLUSTERS keyword should be a clustering action");
+     116           4 :   std::vector<Value*> weights; parseArgumentList("WEIGHTS",weights);
+     117           2 :   if( weights.size()==0 ) {
+     118           1 :     log.printf("  using unit weights in cluster distribution \n");
+     119           1 :   } else if( weights.size()==1 ) {
+     120           1 :     if( weights[0]->getRank()!=1 ) error("input weights has wrong shape");
+     121           1 :     if( weights[0]->getShape()[0]!=clusters[0]->getShape()[0] ) error("mismatch between number of weights and number of atoms");
+     122           1 :     log.printf("  using weights from action with label %s in cluster distribution \n", weights[0]->getName().c_str() );
+     123           1 :     clusters.push_back( weights[0] );
+     124             :   } else {
+     125           0 :     error("should have only one argument for weights \n");
+     126             :   }
+     127             :   // Request the arguments
+     128           2 :   requestArguments( clusters );
+     129           2 :   getPntrToArgument(0)->buildDataStore();
+     130           2 :   if( getNumberOfArguments()>1 ) getPntrToArgument(1)->buildDataStore();
+     131             :   // Now create the value
+     132           2 :   std::vector<unsigned> shape(1); shape[0]=clusters[0]->getShape()[0];
+     133           2 :   addValue( shape ); setNotPeriodic(); getPntrToValue()->buildDataStore();
+     134           2 : }
+     135             : 
+     136           0 : unsigned ClusterDistribution::getNumberOfDerivatives() {
+     137           0 :   return 0;
+     138             : }
+     139             : 
+     140           2 : void ClusterDistribution::calculate() {
+     141           2 :   plumed_assert( getPntrToArgument(0)->valueHasBeenSet() );
+     142           2 :   if( getNumberOfArguments()>1 ) plumed_assert( getPntrToArgument(1)->valueHasBeenSet() );
+     143           2 :   double csize = getPntrToArgument(0)->get(0);
+     144          12 :   for(unsigned i=1; i<getPntrToArgument(0)->getShape()[0]; ++i) {
+     145          10 :     if( getPntrToArgument(0)->get(i)>csize ) csize = getPntrToArgument(0)->get(i);
+     146             :   }
+     147           2 :   unsigned ntasks = static_cast<unsigned>( csize );
+     148           8 :   for(unsigned i=0; i<ntasks; ++i) {
+     149          42 :     for(unsigned j=0; j<getPntrToArgument(0)->getShape()[0]; ++j) {
+     150          36 :       if( fabs(getPntrToArgument(0)->get(j)-i)<epsilon ) {
+     151          10 :         if( getNumberOfArguments()==2 ) getPntrToValue()->add( i, getPntrToArgument(1)->get(j) );
+     152           5 :         else getPntrToValue()->add( i, 1.0 );
+     153             :       }
+     154             :     }
+     155             :   }
+     156           2 : }
+     157             : 
+     158             : class ClusterDistributionShortcut : public ActionShortcut {
+     159             : public:
+     160             :   static void registerKeywords( Keywords& keys );
+     161             :   ClusterDistributionShortcut(const ActionOptions&);
+     162             : };
+     163             : 
+     164             : PLUMED_REGISTER_ACTION(ClusterDistributionShortcut,"CLUSTER_DISTRIBUTION")
+     165             : 
+     166           6 : void ClusterDistributionShortcut::registerKeywords( Keywords& keys ) {
+     167           6 :   ActionShortcut::registerKeywords( keys );
+     168          12 :   keys.add("compulsory","CLUSTERS","the label of the action that does the clustering");
+     169          12 :   keys.add("optional","WEIGHTS","use the vector of values calculated by this action as weights rather than giving each atom a unit weight");
+     170           6 :   multicolvar::MultiColvarShortcuts::shortcutKeywords( keys );
+     171           6 :   keys.addActionNameSuffix("_CALC");
+     172           6 : }
+     173             : 
+     174           2 : ClusterDistributionShortcut::ClusterDistributionShortcut(const ActionOptions&ao):
+     175             :   Action(ao),
+     176           2 :   ActionShortcut(ao)
+     177             : {
+     178           2 :   std::map<std::string,std::string> keymap; multicolvar::MultiColvarShortcuts::readShortcutKeywords( keymap, this );
+     179           4 :   readInputLine( getShortcutLabel() + ": CLUSTER_DISTRIBUTION_CALC " + convertInputLineToString() );
+     180           4 :   multicolvar::MultiColvarShortcuts::expandFunctions( getShortcutLabel(),  getShortcutLabel(),  "", keymap, this );
+     181           2 : }
+     182             : 
+     183             : }
+     184             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/clusters/ClusterNatoms.cpp.func-sort-c.html b/coverage/clusters/ClusterNatoms.cpp.func-sort-c.html new file mode 100644 index 000000000000..0b86806369d7 --- /dev/null +++ b/coverage/clusters/ClusterNatoms.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - clusters/ClusterNatoms.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - clusters - ClusterNatoms.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1111100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8clusters13ClusterNatomsC2ERKNS_13ActionOptionsE0
_ZN4PLMD8clusters13ClusterNatomsC1ERKNS_13ActionOptionsE2
_ZN4PLMD8clusters13ClusterNatoms16registerKeywordsERNS_8KeywordsE4
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/clusters/ClusterNatoms.cpp.func.html b/coverage/clusters/ClusterNatoms.cpp.func.html new file mode 100644 index 000000000000..b286cca103c7 --- /dev/null +++ b/coverage/clusters/ClusterNatoms.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - clusters/ClusterNatoms.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - clusters - ClusterNatoms.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1111100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8clusters13ClusterNatoms16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD8clusters13ClusterNatomsC1ERKNS_13ActionOptionsE2
_ZN4PLMD8clusters13ClusterNatomsC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/clusters/ClusterNatoms.cpp.gcov.html b/coverage/clusters/ClusterNatoms.cpp.gcov.html new file mode 100644 index 000000000000..ad3d36ed3178 --- /dev/null +++ b/coverage/clusters/ClusterNatoms.cpp.gcov.html @@ -0,0 +1,140 @@ + + + + + + + + LCOV - plumed test coverage - clusters/ClusterNatoms.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - clusters - ClusterNatoms.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1111100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2020 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received 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             : //+PLUMEDOC CONCOMP CLUSTER_NATOMS
+      26             : /*
+      27             : Calculate the number of atoms in the cluster of interest
+      28             : 
+      29             : \par Examples
+      30             : 
+      31             : */
+      32             : //+ENDPLUMEDOC
+      33             : 
+      34             : namespace PLMD {
+      35             : namespace clusters {
+      36             : 
+      37             : class ClusterNatoms : public ActionShortcut {
+      38             : public:
+      39             :   static void registerKeywords(Keywords& keys);
+      40             :   explicit ClusterNatoms(const ActionOptions&);
+      41             : };
+      42             : 
+      43             : PLUMED_REGISTER_ACTION(ClusterNatoms,"CLUSTER_NATOMS")
+      44             : 
+      45           4 : void ClusterNatoms::registerKeywords(Keywords& keys) {
+      46           4 :   ActionShortcut::registerKeywords( keys );
+      47           8 :   keys.add("compulsory","CLUSTERS","the label of the action that does the clustering");
+      48           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.");
+      49           8 :   keys.needsAction("CLUSTER_WEIGHTS"); keys.needsAction("SUM");
+      50           4 : }
+      51             : 
+      52           2 : ClusterNatoms::ClusterNatoms(const ActionOptions& ao):
+      53             :   Action(ao),
+      54           2 :   ActionShortcut(ao)
+      55             : {
+      56             :   // Create a cluster weights object
+      57           4 :   readInputLine( getShortcutLabel() + "_weights: CLUSTER_WEIGHTS " + convertInputLineToString() );
+      58             :   // Add all the weights together (weights are 1 or 0)
+      59           4 :   readInputLine( getShortcutLabel() + ": SUM ARG=" + getShortcutLabel() + "_weights PERIODIC=NO");
+      60           2 : }
+      61             : 
+      62             : }
+      63             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/clusters/ClusterProperties.cpp.func-sort-c.html b/coverage/clusters/ClusterProperties.cpp.func-sort-c.html new file mode 100644 index 000000000000..0bb7c3535aa4 --- /dev/null +++ b/coverage/clusters/ClusterProperties.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - clusters/ClusterProperties.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - clusters - ClusterProperties.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1515100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8clusters17ClusterPropertiesC2ERKNS_13ActionOptionsE0
_ZN4PLMD8clusters17ClusterPropertiesC1ERKNS_13ActionOptionsE20
_ZN4PLMD8clusters17ClusterProperties16registerKeywordsERNS_8KeywordsE54
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/clusters/ClusterProperties.cpp.func.html b/coverage/clusters/ClusterProperties.cpp.func.html new file mode 100644 index 000000000000..786a99915bf3 --- /dev/null +++ b/coverage/clusters/ClusterProperties.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - clusters/ClusterProperties.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - clusters - ClusterProperties.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1515100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8clusters17ClusterProperties16registerKeywordsERNS_8KeywordsE54
_ZN4PLMD8clusters17ClusterPropertiesC1ERKNS_13ActionOptionsE20
_ZN4PLMD8clusters17ClusterPropertiesC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/clusters/ClusterProperties.cpp.gcov.html b/coverage/clusters/ClusterProperties.cpp.gcov.html new file mode 100644 index 000000000000..eaa1ab1bd933 --- /dev/null +++ b/coverage/clusters/ClusterProperties.cpp.gcov.html @@ -0,0 +1,168 @@ + + + + + + + + LCOV - plumed test coverage - clusters/ClusterProperties.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - clusters - ClusterProperties.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1515100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2014-2020 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionShortcut.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "multicolvar/MultiColvarShortcuts.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 clusters {
+      58             : 
+      59             : class ClusterProperties : public ActionShortcut {
+      60             : public:
+      61             :   static void registerKeywords(Keywords& keys);
+      62             :   explicit ClusterProperties(const ActionOptions&);
+      63             : };
+      64             : 
+      65             : PLUMED_REGISTER_ACTION(ClusterProperties,"CLUSTER_PROPERTIES")
+      66             : 
+      67          54 : void ClusterProperties::registerKeywords(Keywords& keys) {
+      68          54 :   ActionShortcut::registerKeywords( keys );
+      69         108 :   keys.add("compulsory","ARG","calculate the sum of the arguments calculated by this action for the cluster");
+      70         108 :   keys.add("compulsory","CLUSTERS","the label of the action that does the clustering");
+      71         108 :   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.");
+      72          54 :   multicolvar::MultiColvarShortcuts::shortcutKeywords( keys );
+      73          54 :   keys.needsAction("CLUSTER_WEIGHTS");
+      74          54 : }
+      75             : 
+      76          20 : ClusterProperties::ClusterProperties(const ActionOptions& ao):
+      77             :   Action(ao),
+      78          20 :   ActionShortcut(ao)
+      79             : {
+      80             :   // Read the property we are interested in
+      81          40 :   std::string argstr; parse("ARG",argstr);
+      82             :   // Read in the shortcut keywords
+      83          20 :   std::map<std::string,std::string> keymap; multicolvar::MultiColvarShortcuts::readShortcutKeywords( keymap, this );
+      84             :   // Create a cluster weights object
+      85          40 :   readInputLine( getShortcutLabel() + ": CLUSTER_WEIGHTS " + convertInputLineToString() );
+      86             :   // Now do the multicolvar bit
+      87          20 :   multicolvar::MultiColvarShortcuts::expandFunctions( getShortcutLabel(), argstr, getShortcutLabel(), keymap, this );
+      88          20 : }
+      89             : 
+      90             : }
+      91             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/clusters/ClusterWeights.cpp.func-sort-c.html b/coverage/clusters/ClusterWeights.cpp.func-sort-c.html new file mode 100644 index 000000000000..08c1fd839be2 --- /dev/null +++ b/coverage/clusters/ClusterWeights.cpp.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - clusters/ClusterWeights.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - clusters - ClusterWeights.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3232100.0 %
Date:2024-04-19 12:12:35Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8clusters14ClusterWeightsC2ERKNS_13ActionOptionsE0
_ZN4PLMD8clusters14ClusterWeights22getNumberOfDerivativesEv24
_ZN4PLMD8clusters14ClusterWeightsC1ERKNS_13ActionOptionsE29
_ZN4PLMD8clusters14ClusterWeights16registerKeywordsERNS_8KeywordsE31
_ZN4PLMD8clusters14ClusterWeights5applyEv51
_ZN4PLMD8clusters14ClusterWeights9calculateEv51
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/clusters/ClusterWeights.cpp.func.html b/coverage/clusters/ClusterWeights.cpp.func.html new file mode 100644 index 000000000000..e02fc50b708a --- /dev/null +++ b/coverage/clusters/ClusterWeights.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - clusters/ClusterWeights.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - clusters - ClusterWeights.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3232100.0 %
Date:2024-04-19 12:12:35Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8clusters14ClusterWeights16registerKeywordsERNS_8KeywordsE31
_ZN4PLMD8clusters14ClusterWeights22getNumberOfDerivativesEv24
_ZN4PLMD8clusters14ClusterWeights5applyEv51
_ZN4PLMD8clusters14ClusterWeights9calculateEv51
_ZN4PLMD8clusters14ClusterWeightsC1ERKNS_13ActionOptionsE29
_ZN4PLMD8clusters14ClusterWeightsC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/clusters/ClusterWeights.cpp.gcov.html b/coverage/clusters/ClusterWeights.cpp.gcov.html new file mode 100644 index 000000000000..229a664112fc --- /dev/null +++ b/coverage/clusters/ClusterWeights.cpp.gcov.html @@ -0,0 +1,188 @@ + + + + + + + + LCOV - plumed test coverage - clusters/ClusterWeights.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - clusters - ClusterWeights.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3232100.0 %
Date:2024-04-19 12:12:35Functions:5683.3 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2014-2017 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received 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/ActionWithArguments.h"
+      24             : #include "core/ActionRegister.h"
+      25             : #include "core/PlumedMain.h"
+      26             : #include "core/ActionSet.h"
+      27             : #include "ClusteringBase.h"
+      28             : 
+      29             : //+PLUMEDOC CONCOMP CLUSTER_WEIGHTS
+      30             : /*
+      31             : Setup a vector that has one for all the atoms that form part of the cluster of interest and that has zero for all other atoms.
+      32             : 
+      33             : \par Examples
+      34             : 
+      35             : 
+      36             : */
+      37             : //+ENDPLUMEDOC
+      38             : 
+      39             : namespace PLMD {
+      40             : namespace clusters {
+      41             : 
+      42             : class ClusterWeights :
+      43             :   public ActionWithArguments,
+      44             :   public ActionWithValue {
+      45             : private:
+      46             : /// The cluster we are looking for
+      47             :   unsigned clustr;
+      48             : /// The forces
+      49             :   std::vector<double> forcesToApply;
+      50             : public:
+      51             : /// Create manual
+      52             :   static void registerKeywords( Keywords& keys );
+      53             : /// Constructor
+      54             :   explicit ClusterWeights(const ActionOptions&);
+      55             : /// The number of derivatives
+      56             :   unsigned getNumberOfDerivatives() override ;
+      57             : /// Do the calculation
+      58             :   void calculate() override ;
+      59             : ///
+      60          51 :   void apply() override {}
+      61             : };
+      62             : 
+      63             : PLUMED_REGISTER_ACTION(ClusterWeights,"CLUSTER_WEIGHTS")
+      64             : 
+      65          31 : void ClusterWeights::registerKeywords( Keywords& keys ) {
+      66          31 :   Action::registerKeywords( keys );
+      67          31 :   ActionWithArguments::registerKeywords( keys ); keys.remove("ARG");
+      68          31 :   ActionWithValue::registerKeywords( keys ); keys.remove("NUMERICAL_DERIVATIVES");
+      69          62 :   keys.add("compulsory","CLUSTERS","the label of the action that does the clustering");
+      70          62 :   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.");
+      71          62 :   keys.addFlag("LOWMEM",false,"this flag does nothing and is present only to ensure back-compatibility");
+      72             :   // keys.add("hidden","FROM_PROPERTIES","indicates that this is created from CLUSTER_PROPERTIES shortcut");
+      73          31 : }
+      74             : 
+      75          29 : ClusterWeights::ClusterWeights(const ActionOptions&ao):
+      76             :   Action(ao),
+      77             :   ActionWithArguments(ao),
+      78          29 :   ActionWithValue(ao)
+      79             : {
+      80          29 :   bool lowmem; parseFlag("LOWMEM",lowmem);
+      81          29 :   if( lowmem ) warning("LOWMEM flag is deprecated and is no longer required for this action");
+      82             :   // Read in the clustering object
+      83          58 :   std::vector<Value*> clusters; parseArgumentList("CLUSTERS",clusters);
+      84          29 :   if( clusters.size()!=1 ) error("should pass only one matrix to clustering base");
+      85          29 :   ClusteringBase* cc = dynamic_cast<ClusteringBase*>( clusters[0]->getPntrToAction() );
+      86          29 :   if( !cc ) error("input to CLUSTERS keyword should be a clustering action");
+      87             :   // Request the arguments
+      88          29 :   requestArguments( clusters );
+      89             :   // Now create the value
+      90          29 :   std::vector<unsigned> shape(1); shape[0]=clusters[0]->getShape()[0];
+      91          29 :   addValue( shape ); setNotPeriodic(); getPntrToComponent(0)->buildDataStore();
+      92             :   // Find out which cluster we want
+      93          29 :   parse("CLUSTER",clustr);
+      94          29 :   if( clustr<1 ) error("cannot look for a cluster larger than the largest cluster");
+      95          29 :   if( clustr>clusters[0]->getShape()[0] ) error("cluster selected is invalid - too few atoms in system");
+      96          29 :   log.printf("  atoms in %dth largest cluster calculated by %s are equal to one \n",clustr, cc->getLabel().c_str() );
+      97          29 : }
+      98             : 
+      99          24 : unsigned ClusterWeights::getNumberOfDerivatives() {
+     100          24 :   return 0;
+     101             : }
+     102             : 
+     103          51 : void ClusterWeights::calculate() {
+     104          51 :   plumed_assert( getPntrToArgument(0)->valueHasBeenSet() );
+     105       36627 :   for(unsigned i=0; i<getPntrToArgument(0)->getShape()[0]; ++i) {
+     106       36576 :     if( fabs(getPntrToArgument(0)->get(i)-clustr)<epsilon ) getPntrToComponent(0)->set( i, 1.0 );
+     107             :   }
+     108          51 : }
+     109             : 
+     110             : }
+     111             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/clusters/ClusterWithSurface.cpp.func-sort-c.html b/coverage/clusters/ClusterWithSurface.cpp.func-sort-c.html new file mode 100644 index 000000000000..35bb9ab763e7 --- /dev/null +++ b/coverage/clusters/ClusterWithSurface.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - clusters/ClusterWithSurface.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - clusters - ClusterWithSurface.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2121100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8clusters18ClusterWithSurfaceC2ERKNS_13ActionOptionsE0
_ZN4PLMD8clusters18ClusterWithSurfaceC1ERKNS_13ActionOptionsE2
_ZN4PLMD8clusters18ClusterWithSurface16registerKeywordsERNS_8KeywordsE4
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/clusters/ClusterWithSurface.cpp.func.html b/coverage/clusters/ClusterWithSurface.cpp.func.html new file mode 100644 index 000000000000..a9255cc3d2e5 --- /dev/null +++ b/coverage/clusters/ClusterWithSurface.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - clusters/ClusterWithSurface.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - clusters - ClusterWithSurface.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2121100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8clusters18ClusterWithSurface16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD8clusters18ClusterWithSurfaceC1ERKNS_13ActionOptionsE2
_ZN4PLMD8clusters18ClusterWithSurfaceC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/clusters/ClusterWithSurface.cpp.gcov.html b/coverage/clusters/ClusterWithSurface.cpp.gcov.html new file mode 100644 index 000000000000..3cfd6fe7e0d7 --- /dev/null +++ b/coverage/clusters/ClusterWithSurface.cpp.gcov.html @@ -0,0 +1,157 @@ + + + + + + + + LCOV - plumed test coverage - clusters/ClusterWithSurface.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - clusters - ClusterWithSurface.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2121100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2020 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received 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             : //+PLUMEDOC CONCOMP CLUSTER_WITHSURFACE
+      26             : /*
+      27             : Determine the atoms that are within a certain cutoff of the atoms in a cluster
+      28             : 
+      29             : \par Examples
+      30             : 
+      31             : 
+      32             : */
+      33             : //+ENDPLUMEDOC
+      34             : 
+      35             : namespace PLMD {
+      36             : namespace clusters {
+      37             : 
+      38             : class ClusterWithSurface : public ActionShortcut {
+      39             : public:
+      40             :   static void registerKeywords(Keywords& keys);
+      41             :   explicit ClusterWithSurface(const ActionOptions&);
+      42             : };
+      43             : 
+      44             : PLUMED_REGISTER_ACTION(ClusterWithSurface,"CLUSTER_WITHSURFACE")
+      45             : 
+      46           4 : void ClusterWithSurface::registerKeywords(Keywords& keys) {
+      47           4 :   ActionShortcut::registerKeywords(keys);
+      48           8 :   keys.add("optional","RCUT_SURF","");
+      49           8 :   keys.add("compulsory","ATOMS","the atoms that were used to calculate the matrix that was clustered");
+      50           8 :   keys.add("compulsory","CLUSTERS","the label of the action that does the clustering");
+      51           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.");
+      52           8 :   keys.needsAction("CLUSTER_WEIGHTS"); keys.needsAction("CONTACT_MATRIX");
+      53           8 :   keys.needsAction("OUTER_PRODUCT"); keys.needsAction("CUSTOM");
+      54           4 :   keys.needsAction("DFSCLUSTERING");
+      55           4 : }
+      56             : 
+      57           2 : ClusterWithSurface::ClusterWithSurface(const ActionOptions& ao):
+      58             :   Action(ao),
+      59           2 :   ActionShortcut(ao)
+      60             : {
+      61             :   // Read atoms for contact matrix
+      62           4 :   std::string atdata; parse("ATOMS",atdata);
+      63             :   // Read rcut input
+      64           2 :   std::string rcut_surf_str; parse("RCUT_SURF",rcut_surf_str);
+      65             :   // Create a cluster weights object
+      66           4 :   readInputLine( getShortcutLabel() + "_wnosurf: CLUSTER_WEIGHTS " + convertInputLineToString() );
+      67             :   // Now create a contact matrix
+      68           4 :   readInputLine( getShortcutLabel() + "_cmat: CONTACT_MATRIX GROUP=" + atdata + " SWITCH={" + rcut_surf_str +"}" );
+      69             :   // Now create a custom matrix
+      70           4 :   readInputLine( getShortcutLabel() + "_cwmat: OUTER_PRODUCT ARG=" + getShortcutLabel() + "_wnosurf," + getShortcutLabel() + "_wnosurf FUNC=max");
+      71             :   // Product of matrices
+      72           4 :   readInputLine( getShortcutLabel() + "_pmat: CUSTOM ARG=" + getShortcutLabel() + "_cmat," + getShortcutLabel() + "_cwmat FUNC=x*y PERIODIC=NO");
+      73             :   // DFS clustering
+      74           4 :   readInputLine( getShortcutLabel() + "_clust: DFSCLUSTERING ARG=" + getShortcutLabel() + "_pmat");
+      75             :   // And final cluster weights
+      76           4 :   readInputLine( getShortcutLabel() + ": CLUSTER_WEIGHTS CLUSTERS=" + getShortcutLabel() + "_clust CLUSTER=1");
+      77           2 : }
+      78             : 
+      79             : }
+      80             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/clusters/ClusteringBase.cpp.func-sort-c.html b/coverage/clusters/ClusteringBase.cpp.func-sort-c.html new file mode 100644 index 000000000000..b3079e402cc6 --- /dev/null +++ b/coverage/clusters/ClusteringBase.cpp.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - clusters/ClusteringBase.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - clusters - ClusteringBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3333100.0 %
Date:2024-04-19 12:12:35Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8clusters14ClusteringBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD8clusters14ClusteringBaseC2ERKNS_13ActionOptionsE17
_ZN4PLMD8clusters14ClusteringBase16registerKeywordsERNS_8KeywordsE19
_ZN4PLMD8clusters14ClusteringBase22retrieveAdjacencyListsERSt6vectorIjSaIjEERNS_6MatrixIjEE38
_ZN4PLMD8clusters14ClusteringBase5applyEv38
_ZN4PLMD8clusters14ClusteringBase9calculateEv38
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/clusters/ClusteringBase.cpp.func.html b/coverage/clusters/ClusteringBase.cpp.func.html new file mode 100644 index 000000000000..f4bdb965cb03 --- /dev/null +++ b/coverage/clusters/ClusteringBase.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - clusters/ClusteringBase.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - clusters - ClusteringBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3333100.0 %
Date:2024-04-19 12:12:35Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8clusters14ClusteringBase16registerKeywordsERNS_8KeywordsE19
_ZN4PLMD8clusters14ClusteringBase22retrieveAdjacencyListsERSt6vectorIjSaIjEERNS_6MatrixIjEE38
_ZN4PLMD8clusters14ClusteringBase5applyEv38
_ZN4PLMD8clusters14ClusteringBase9calculateEv38
_ZN4PLMD8clusters14ClusteringBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD8clusters14ClusteringBaseC2ERKNS_13ActionOptionsE17
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/clusters/ClusteringBase.cpp.gcov.html b/coverage/clusters/ClusteringBase.cpp.gcov.html new file mode 100644 index 000000000000..d986f05ff6e6 --- /dev/null +++ b/coverage/clusters/ClusteringBase.cpp.gcov.html @@ -0,0 +1,168 @@ + + + + + + + + LCOV - plumed test coverage - clusters/ClusteringBase.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - clusters - ClusteringBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3333100.0 %
Date:2024-04-19 12:12:35Functions:5683.3 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2020 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received 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 "core/PlumedMain.h"
+      24             : 
+      25             : namespace PLMD {
+      26             : namespace clusters {
+      27             : 
+      28          19 : void ClusteringBase::registerKeywords( Keywords& keys ) {
+      29          19 :   adjmat::MatrixOperationBase::registerKeywords( keys ); keys.use("ARG");
+      30          19 : }
+      31             : 
+      32          17 : ClusteringBase::ClusteringBase(const ActionOptions&ao):
+      33             :   Action(ao),
+      34             :   adjmat::MatrixOperationBase(ao),
+      35          17 :   number_of_cluster(-1)
+      36             : {
+      37             :   // Do some checks on the input
+      38          17 :   if( getPntrToArgument(0)->getShape()[0]!=getPntrToArgument(0)->getShape()[1] ) error("input matrix should be square");
+      39             : 
+      40             :   // Now create a value - this holds the data on which cluster each guy is in
+      41          17 :   std::vector<unsigned> shape(1); shape[0]=getPntrToArgument(0)->getShape()[0];
+      42             :   // Build the store here to make sure that next action has all data
+      43          17 :   addValue( shape ); setNotPeriodic(); getPntrToValue()->buildDataStore();
+      44             :   // Resize local variables
+      45          17 :   which_cluster.resize( getPntrToArgument(0)->getShape()[0] ); cluster_sizes.resize( getPntrToArgument(0)->getShape()[0] );
+      46          17 : }
+      47             : 
+      48          38 : void ClusteringBase::retrieveAdjacencyLists( std::vector<unsigned>& nneigh, Matrix<unsigned>& adj_list ) {
+      49             :   // Make sure we have the edges stored
+      50             :   std::vector<std::pair<unsigned,unsigned> > pairs; std::vector<double> vals;
+      51          38 :   unsigned nedge; getPntrToArgument(0)->retrieveEdgeList( nedge, pairs, vals );
+      52             :   // Currently everything has zero neighbors
+      53       20912 :   for(unsigned i=0; i<nneigh.size(); ++i) nneigh[i]=0;
+      54             :   // Resize the adjacency list if it is needed
+      55          38 :   if( adj_list.ncols()!=getPntrToArgument(0)->getNumberOfColumns() ) {
+      56          21 :     unsigned nrows = getPntrToArgument(0)->getShape()[0];
+      57             :     adj_list.resize( nrows, getPntrToArgument(0)->getNumberOfColumns() );
+      58             :   }
+      59             : 
+      60             :   // And set up the adjacency list
+      61       66502 :   for(unsigned i=0; i<nedge; ++i) {
+      62             :     // Store if atoms are connected
+      63       66464 :     unsigned j=pairs[i].first, k=pairs[i].second;
+      64       66464 :     if( j==k ) continue;
+      65       66464 :     adj_list(j,nneigh[j])=k; nneigh[j]++;
+      66       66464 :     adj_list(k,nneigh[k])=j; nneigh[k]++;
+      67             :   }
+      68          38 : }
+      69             : 
+      70          38 : void ClusteringBase::calculate() {
+      71             :   // All the clusters have zero size initially
+      72       20912 :   for(unsigned i=0; i<cluster_sizes.size(); ++i) { cluster_sizes[i].first=0; cluster_sizes[i].second=i; }
+      73             :   // Do the clustering bit
+      74          38 :   performClustering();
+      75             :   // Order the clusters in the system by size (this returns ascending order )
+      76          38 :   std::sort( cluster_sizes.begin(), cluster_sizes.end() );
+      77             :   // Set the elements of the value to the cluster identies
+      78       20912 :   for(unsigned i=0; i<cluster_sizes.size(); ++i) {
+      79       20874 :     double this_size = static_cast<double>(cluster_sizes.size()-i);
+      80    21921410 :     for(unsigned j=0; j<cluster_sizes.size(); ++j) {
+      81    21900536 :       if( which_cluster[j]==cluster_sizes[i].second ) getPntrToValue()->set( j, this_size );
+      82             :     }
+      83             :   }
+      84          38 : }
+      85             : 
+      86          38 : void ClusteringBase::apply() {
+      87          38 :   if( getPntrToComponent(0)->forcesWereAdded() ) error("forces on clustering actions cannot work as clustering is not differentiable");
+      88          38 : }
+      89             : 
+      90             : }
+      91             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/clusters/ClusteringBase.h.func-sort-c.html b/coverage/clusters/ClusteringBase.h.func-sort-c.html new file mode 100644 index 000000000000..89fe8e77fb82 --- /dev/null +++ b/coverage/clusters/ClusteringBase.h.func-sort-c.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - clusters/ClusteringBase.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - clusters - ClusteringBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2366.7 %
Date:2024-04-19 12:12:35Functions:1250.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD8clusters14ClusteringBase23getForceOnMatrixElementERKjS3_0
_ZN4PLMD8clusters14ClusteringBase22getNumberOfDerivativesEv24
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/clusters/ClusteringBase.h.func.html b/coverage/clusters/ClusteringBase.h.func.html new file mode 100644 index 000000000000..d529ebe2156f --- /dev/null +++ b/coverage/clusters/ClusteringBase.h.func.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - clusters/ClusteringBase.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - clusters - ClusteringBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2366.7 %
Date:2024-04-19 12:12:35Functions:1250.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8clusters14ClusteringBase22getNumberOfDerivativesEv24
_ZNK4PLMD8clusters14ClusteringBase23getForceOnMatrixElementERKjS3_0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/clusters/ClusteringBase.h.gcov.html b/coverage/clusters/ClusteringBase.h.gcov.html new file mode 100644 index 000000000000..2c569c5248a0 --- /dev/null +++ b/coverage/clusters/ClusteringBase.h.gcov.html @@ -0,0 +1,143 @@ + + + + + + + + LCOV - plumed test coverage - clusters/ClusteringBase.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - clusters - ClusteringBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2366.7 %
Date:2024-04-19 12:12:35Functions:1250.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2020 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_clusters_ClusteringBase_h
+      23             : #define __PLUMED_clusters_ClusteringBase_h
+      24             : 
+      25             : #include "adjmat/MatrixOperationBase.h"
+      26             : #include "tools/Matrix.h"
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace clusters {
+      30             : 
+      31             : class ClusteringBase : public adjmat::MatrixOperationBase {
+      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             : /// Get the number of nodes
+      40             :   unsigned getNumberOfNodes() const ;
+      41             : /// Get the neighbour list based on the adjacency matrix
+      42             :   void retrieveAdjacencyLists( std::vector<unsigned>& nneigh, Matrix<unsigned>& adj_list );
+      43             : public:
+      44             : /// Create manual
+      45             :   static void registerKeywords( Keywords& keys );
+      46             : /// Constructor
+      47             :   explicit ClusteringBase(const ActionOptions&);
+      48             : ///
+      49          24 :   unsigned getNumberOfDerivatives() override { return 0; }
+      50             : ///
+      51             :   void calculate() override;
+      52             : ///
+      53             :   virtual void performClustering()=0;
+      54             : /// Cannot apply forces on a clustering object
+      55             :   void apply() override ;
+      56           0 :   double getForceOnMatrixElement( const unsigned& jrow, const unsigned& krow ) const override { plumed_error(); }
+      57             : };
+      58             : 
+      59             : inline
+      60             : unsigned ClusteringBase::getNumberOfNodes() const {
+      61       20929 :   return getPntrToArgument(0)->getShape()[0];
+      62             : }
+      63             : 
+      64             : }
+      65             : }
+      66             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/clusters/DFSClustering.cpp.func-sort-c.html b/coverage/clusters/DFSClustering.cpp.func-sort-c.html new file mode 100644 index 000000000000..61365fc8cb05 --- /dev/null +++ b/coverage/clusters/DFSClustering.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - clusters/DFSClustering.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - clusters - DFSClustering.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2424100.0 %
Date:2024-04-19 12:12:35Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8clusters13DFSClusteringC2ERKNS_13ActionOptionsE0
_ZN4PLMD8clusters13DFSClusteringC1ERKNS_13ActionOptionsE17
_ZN4PLMD8clusters13DFSClustering16registerKeywordsERNS_8KeywordsE19
_ZN4PLMD8clusters13DFSClustering17performClusteringEv38
_ZN4PLMD8clusters13DFSClustering7exploreERKj20874
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/clusters/DFSClustering.cpp.func.html b/coverage/clusters/DFSClustering.cpp.func.html new file mode 100644 index 000000000000..44fdb0a3e934 --- /dev/null +++ b/coverage/clusters/DFSClustering.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - clusters/DFSClustering.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - clusters - DFSClustering.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2424100.0 %
Date:2024-04-19 12:12:35Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8clusters13DFSClustering16registerKeywordsERNS_8KeywordsE19
_ZN4PLMD8clusters13DFSClustering17performClusteringEv38
_ZN4PLMD8clusters13DFSClustering7exploreERKj20874
_ZN4PLMD8clusters13DFSClusteringC1ERKNS_13ActionOptionsE17
_ZN4PLMD8clusters13DFSClusteringC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/clusters/DFSClustering.cpp.gcov.html b/coverage/clusters/DFSClustering.cpp.gcov.html new file mode 100644 index 000000000000..56ee7ae23809 --- /dev/null +++ b/coverage/clusters/DFSClustering.cpp.gcov.html @@ -0,0 +1,227 @@ + + + + + + + + LCOV - plumed test coverage - clusters/DFSClustering.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - clusters - DFSClustering.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2424100.0 %
Date:2024-04-19 12:12:35Functions:4580.0 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8clusters13OutputClusterC2ERKNS_13ActionOptionsE0
_ZN4PLMD8clusters13OutputClusterC1ERKNS_13ActionOptionsE2
_ZN4PLMD8clusters13OutputCluster16registerKeywordsERNS_8KeywordsE4
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/clusters/OutputCluster.cpp.func.html b/coverage/clusters/OutputCluster.cpp.func.html new file mode 100644 index 000000000000..b2b383eeaae1 --- /dev/null +++ b/coverage/clusters/OutputCluster.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - clusters/OutputCluster.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - clusters - OutputCluster.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1818100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8clusters13OutputCluster16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD8clusters13OutputClusterC1ERKNS_13ActionOptionsE2
_ZN4PLMD8clusters13OutputClusterC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/clusters/OutputCluster.cpp.gcov.html b/coverage/clusters/OutputCluster.cpp.gcov.html new file mode 100644 index 000000000000..c54335296609 --- /dev/null +++ b/coverage/clusters/OutputCluster.cpp.gcov.html @@ -0,0 +1,170 @@ + + + + + + + + LCOV - plumed test coverage - clusters/OutputCluster.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - clusters - OutputCluster.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1818100.0 %
Date:2024-04-19 12:12:35Functions:2366.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/ActionShortcut.h"
+      23             : #include "core/ActionRegister.h"
+      24             : 
+      25             : //+PLUMEDOC CONCOMP OUTPUT_CLUSTER
+      26             : /*
+      27             : Output the indices of the atoms in one of the clusters identified by a clustering object
+      28             : 
+      29             : This action provides one way of getting output from a \ref DFSCLUSTERING calculation.
+      30             : The output in question here is either
+      31             : 
+      32             : - a file that contains a list of the atom indices that form part of one of the clusters that was identified using \ref DFSCLUSTERING
+      33             : - an xyz file containing the positions of the atoms in one of the the clusters that was identified using \ref DFSCLUSTERING
+      34             : 
+      35             : Notice also that if you choose to output an xyz file you can ask PLUMED to try to reconstruct the cluster
+      36             : taking the periodic boundary conditions into account by using the MAKE_WHOLE flag.
+      37             : 
+      38             : \par Examples
+      39             : 
+      40             : The input shown below identifies those atoms with a coordination number less than 13
+      41             : and then constructs a contact matrix that describes the connectivity between the atoms
+      42             : that satisfy this criteria.  The DFS algorithm is then used to find the connected components
+      43             : in this matrix and the indices of the atoms in the largest connected component are then output
+      44             : to a file.
+      45             : 
+      46             : \plumedfile
+      47             : c1: COORDINATIONNUMBER SPECIES=1-1996 SWITCH={CUBIC D_0=0.34 D_MAX=0.38}
+      48             : cf: MFILTER_LESS DATA=c1 SWITCH={CUBIC D_0=13 D_MAX=13.5}
+      49             : mat: CONTACT_MATRIX ATOMS=cf SWITCH={CUBIC D_0=0.34 D_MAX=0.38}
+      50             : dfs: DFSCLUSTERING MATRIX=mat
+      51             : OUTPUT_CLUSTER CLUSTERS=dfs CLUSTER=1 FILE=dfs.dat
+      52             : \endplumedfile
+      53             : 
+      54             : */
+      55             : //+ENDPLUMEDOC
+      56             : 
+      57             : namespace PLMD {
+      58             : namespace clusters {
+      59             : 
+      60             : class OutputCluster : public ActionShortcut {
+      61             : public:
+      62             :   static void registerKeywords( Keywords& keys );
+      63             :   explicit OutputCluster(const ActionOptions&);
+      64             : };
+      65             : 
+      66             : PLUMED_REGISTER_ACTION(OutputCluster,"OUTPUT_CLUSTER")
+      67             : 
+      68           4 : void OutputCluster::registerKeywords( Keywords& keys ) {
+      69           4 :   ActionShortcut::registerKeywords( keys );
+      70           8 :   keys.add("compulsory","ATOMS","the atoms for which clustering were performed");
+      71           8 :   keys.add("compulsory","CLUSTERS","the action that performed the clustering");
+      72           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");
+      73           8 :   keys.add("compulsory","STRIDE","1","the frequency with which you would like to output the atoms in the cluster");
+      74           8 :   keys.add("compulsory","FILE","the name of the file on which to output the details of the cluster");
+      75           4 :   keys.needsAction("PRINT_NDX");
+      76           4 : }
+      77             : 
+      78           2 : OutputCluster::OutputCluster(const ActionOptions& ao):
+      79             :   Action(ao),
+      80           2 :   ActionShortcut(ao)
+      81             : {
+      82           4 :   std::string id; parse("CLUSTER",id);
+      83           4 :   std::string stride; parse("STRIDE",stride);
+      84           4 :   std::string clusters; parse("CLUSTERS",clusters);
+      85           4 :   std::string filename; parse("FILE",filename);
+      86           2 :   std::string atoms; parse("ATOMS",atoms);
+      87           4 :   readInputLine("PRINT_NDX ATOMS=" + atoms + " ARG=" + clusters + " FILE=" + filename + " STRIDE=" + stride + " LESS_THAN_OR_EQUAL=" + id + " GREATER_THAN_OR_EQUAL=" + id );
+      88           2 : }
+      89             : 
+      90             : }
+      91             : }
+      92             : 
+      93             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/clusters/index-sort-f.html b/coverage/clusters/index-sort-f.html new file mode 100644 index 000000000000..41f5c37a03ca --- /dev/null +++ b/coverage/clusters/index-sort-f.html @@ -0,0 +1,184 @@ + + + + + + + + LCOV - plumed test coverage - clusters + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - clustersHitTotalCoverage
Test:plumed test coverageLines:22623098.3 %
Date:2024-04-19 12:12:35Functions:314372.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
ClusteringBase.h +
66.7%66.7%
+
66.7 %2 / 350.0 %1 / 2
OutputCluster.cpp +
100.0%
+
100.0 %18 / 1866.7 %2 / 3
ClusterDiameter.cpp +
100.0%
+
100.0 %16 / 1666.7 %2 / 3
ClusterProperties.cpp +
100.0%
+
100.0 %15 / 1566.7 %2 / 3
ClusterNatoms.cpp +
100.0%
+
100.0 %11 / 1166.7 %2 / 3
ClusterWithSurface.cpp +
100.0%
+
100.0 %21 / 2166.7 %2 / 3
ClusterDistribution.cpp +
94.7%94.7%
+
94.7 %54 / 5766.7 %6 / 9
DFSClustering.cpp +
100.0%
+
100.0 %24 / 2480.0 %4 / 5
ClusteringBase.cpp +
100.0%
+
100.0 %33 / 3383.3 %5 / 6
ClusterWeights.cpp +
100.0%
+
100.0 %32 / 3283.3 %5 / 6
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/clusters/index-sort-l.html b/coverage/clusters/index-sort-l.html new file mode 100644 index 000000000000..66e6d61baa15 --- /dev/null +++ b/coverage/clusters/index-sort-l.html @@ -0,0 +1,184 @@ + + + + + + + + LCOV - plumed test coverage - clusters + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - clustersHitTotalCoverage
Test:plumed test coverageLines:22623098.3 %
Date:2024-04-19 12:12:35Functions:314372.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
ClusteringBase.h +
66.7%66.7%
+
66.7 %2 / 350.0 %1 / 2
ClusterDistribution.cpp +
94.7%94.7%
+
94.7 %54 / 5766.7 %6 / 9
ClusterNatoms.cpp +
100.0%
+
100.0 %11 / 1166.7 %2 / 3
ClusterProperties.cpp +
100.0%
+
100.0 %15 / 1566.7 %2 / 3
ClusterDiameter.cpp +
100.0%
+
100.0 %16 / 1666.7 %2 / 3
OutputCluster.cpp +
100.0%
+
100.0 %18 / 1866.7 %2 / 3
ClusterWithSurface.cpp +
100.0%
+
100.0 %21 / 2166.7 %2 / 3
DFSClustering.cpp +
100.0%
+
100.0 %24 / 2480.0 %4 / 5
ClusterWeights.cpp +
100.0%
+
100.0 %32 / 3283.3 %5 / 6
ClusteringBase.cpp +
100.0%
+
100.0 %33 / 3383.3 %5 / 6
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/clusters/index.html b/coverage/clusters/index.html new file mode 100644 index 000000000000..26236c145d22 --- /dev/null +++ b/coverage/clusters/index.html @@ -0,0 +1,184 @@ + + + + + + + + LCOV - plumed test coverage - clusters + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - clustersHitTotalCoverage
Test:plumed test coverageLines:22623098.3 %
Date:2024-04-19 12:12:35Functions:314372.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
ClusterDiameter.cpp +
100.0%
+
100.0 %16 / 1666.7 %2 / 3
ClusterDistribution.cpp +
94.7%94.7%
+
94.7 %54 / 5766.7 %6 / 9
ClusterNatoms.cpp +
100.0%
+
100.0 %11 / 1166.7 %2 / 3
ClusterProperties.cpp +
100.0%
+
100.0 %15 / 1566.7 %2 / 3
ClusterWeights.cpp +
100.0%
+
100.0 %32 / 3283.3 %5 / 6
ClusterWithSurface.cpp +
100.0%
+
100.0 %21 / 2166.7 %2 / 3
ClusteringBase.cpp +
100.0%
+
100.0 %33 / 3383.3 %5 / 6
ClusteringBase.h +
66.7%66.7%
+
66.7 %2 / 350.0 %1 / 2
DFSClustering.cpp +
100.0%
+
100.0 %24 / 2480.0 %4 / 5
OutputCluster.cpp +
100.0%
+
100.0 %18 / 1866.7 %2 / 3
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Angle.cpp.func-sort-c.html b/coverage/colvar/Angle.cpp.func-sort-c.html new file mode 100644 index 000000000000..06f2145c7700 --- /dev/null +++ b/coverage/colvar/Angle.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - colvar/Angle.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Angle.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:505198.0 %
Date:2024-04-19 12:12:35Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar5AngleC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar5Angle21getModeAndSetupValuesEPNS_15ActionWithValueE3
_ZN4PLMD6colvar5AngleC1ERKNS_13ActionOptionsE23
_ZN4PLMD6colvar5Angle16registerKeywordsERNS_8KeywordsE62
_ZN4PLMD6colvar5Angle13parseAtomListERKiRSt6vectorINS_10AtomNumberESaIS5_EEPNS_15ActionAtomisticE73
_ZN4PLMD6colvar5Angle9calculateEv319
_ZN4PLMD6colvar5Angle11calculateCVERKjRKSt6vectorIdSaIdEES8_RKS4_INS_13VectorGenericILj3EEESaISA_EERS6_RS4_ISC_SaISC_EERS4_INS_13TensorGenericILj3ELj3EEESaISK_EEPKNS_15ActionAtomisticE554
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Angle.cpp.func.html b/coverage/colvar/Angle.cpp.func.html new file mode 100644 index 000000000000..3b7020c7eb1a --- /dev/null +++ b/coverage/colvar/Angle.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - colvar/Angle.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Angle.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:505198.0 %
Date:2024-04-19 12:12:35Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar5Angle11calculateCVERKjRKSt6vectorIdSaIdEES8_RKS4_INS_13VectorGenericILj3EEESaISA_EERS6_RS4_ISC_SaISC_EERS4_INS_13TensorGenericILj3ELj3EEESaISK_EEPKNS_15ActionAtomisticE554
_ZN4PLMD6colvar5Angle13parseAtomListERKiRSt6vectorINS_10AtomNumberESaIS5_EEPNS_15ActionAtomisticE73
_ZN4PLMD6colvar5Angle16registerKeywordsERNS_8KeywordsE62
_ZN4PLMD6colvar5Angle21getModeAndSetupValuesEPNS_15ActionWithValueE3
_ZN4PLMD6colvar5Angle9calculateEv319
_ZN4PLMD6colvar5AngleC1ERKNS_13ActionOptionsE23
_ZN4PLMD6colvar5AngleC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Angle.cpp.gcov.html b/coverage/colvar/Angle.cpp.gcov.html new file mode 100644 index 000000000000..e38ee738deea --- /dev/null +++ b/coverage/colvar/Angle.cpp.gcov.html @@ -0,0 +1,271 @@ + + + + + + + + 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:505198.0 %
Date:2024-04-19 12:12:35Functions: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 "ColvarShortcut.h"
+      24             : #include "MultiColvarTemplate.h"
+      25             : #include "core/ActionRegister.h"
+      26             : #include "tools/Angle.h"
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace colvar {
+      30             : 
+      31             : //+PLUMEDOC COLVAR ANGLE
+      32             : /*
+      33             : Calculate an angle.
+      34             : 
+      35             : This command can be used to compute the angle between three atoms. Alternatively
+      36             : if four atoms appear in the atom
+      37             : specification it calculates the angle between
+      38             : two vectors identified by two pairs of atoms.
+      39             : 
+      40             : If _three_ atoms are given, the angle is defined as:
+      41             : \f[
+      42             : \theta=\arccos\left(\frac{ {\bf r}_{21}\cdot {\bf r}_{23}}{
+      43             : |{\bf r}_{21}| |{\bf r}_{23}|}\right)
+      44             : \f]
+      45             : Here \f$ {\bf r}_{ij}\f$ is the distance vector among the
+      46             : \f$i\f$th and the \f$j\f$th listed atom.
+      47             : 
+      48             : If _four_ atoms are given, the angle is defined as:
+      49             : \f[
+      50             : \theta=\arccos\left(\frac{ {\bf r}_{21}\cdot {\bf r}_{34}}{
+      51             : |{\bf r}_{21}| |{\bf r}_{34}|}\right)
+      52             : \f]
+      53             : 
+      54             : Notice that angles defined in this way are non-periodic variables and
+      55             : their value is limited by definition between 0 and \f$\pi\f$.
+      56             : 
+      57             : The vectors \f$ {\bf r}_{ij}\f$ are by default evaluated taking
+      58             : periodic boundary conditions into account.
+      59             : This behavior can be changed with the NOPBC flag.
+      60             : 
+      61             : \par Examples
+      62             : 
+      63             : This command tells plumed to calculate the angle between the vector connecting atom 1 to atom 2 and
+      64             : the vector connecting atom 2 to atom 3 and to print it on file COLVAR1. At the same time,
+      65             : the angle between vector connecting atom 1 to atom 2 and the vector connecting atom 3 to atom 4 is printed
+      66             : on file COLVAR2.
+      67             : \plumedfile
+      68             : 
+      69             : a: ANGLE ATOMS=1,2,3
+      70             : # equivalently one could state:
+      71             : # a: ANGLE ATOMS=1,2,2,3
+      72             : 
+      73             : b: ANGLE ATOMS=1,2,3,4
+      74             : 
+      75             : PRINT ARG=a FILE=COLVAR1
+      76             : PRINT ARG=b FILE=COLVAR2
+      77             : \endplumedfile
+      78             : 
+      79             : 
+      80             : */
+      81             : //+ENDPLUMEDOC
+      82             : 
+      83             : //+PLUMEDOC COLVAR ANGLE_SCALAR
+      84             : /*
+      85             : Calculate an angle.
+      86             : 
+      87             : \par Examples
+      88             : 
+      89             : */
+      90             : //+ENDPLUMEDOC
+      91             : 
+      92             : //+PLUMEDOC COLVAR ANGLE_VECTOR
+      93             : /*
+      94             : Calculate multiple angles.
+      95             : 
+      96             : \par Examples
+      97             : 
+      98             : */
+      99             : //+ENDPLUMEDOC
+     100             : 
+     101             : class Angle : public Colvar {
+     102             :   bool pbc;
+     103             :   std::vector<double> value, masses, charges;
+     104             :   std::vector<std::vector<Vector> > derivs;
+     105             :   std::vector<Tensor> virial;
+     106             : public:
+     107             :   explicit Angle(const ActionOptions&);
+     108             : // active methods:
+     109             :   void calculate() override;
+     110             :   static void registerKeywords( Keywords& keys );
+     111             :   static void parseAtomList( const int& num, std::vector<AtomNumber>& t, ActionAtomistic* aa );
+     112             :   static unsigned getModeAndSetupValues( ActionWithValue* av );
+     113             :   static void calculateCV( const unsigned& mode, const std::vector<double>& masses, const std::vector<double>& charges,
+     114             :                            const std::vector<Vector>& pos, std::vector<double>& vals, std::vector<std::vector<Vector> >& derivs,
+     115             :                            std::vector<Tensor>& virial, const ActionAtomistic* aa );
+     116             : };
+     117             : 
+     118             : typedef ColvarShortcut<Angle> AngleShortcut;
+     119             : PLUMED_REGISTER_ACTION(AngleShortcut,"ANGLE")
+     120             : PLUMED_REGISTER_ACTION(Angle,"ANGLE_SCALAR")
+     121             : typedef MultiColvarTemplate<Angle> AngleMulti;
+     122             : PLUMED_REGISTER_ACTION(AngleMulti,"ANGLE_VECTOR")
+     123             : 
+     124          62 : void Angle::registerKeywords( Keywords& keys ) {
+     125          62 :   Colvar::registerKeywords(keys);
+     126         124 :   keys.add("atoms","ATOMS","the list of atoms involved in this collective variable (either 3 or 4 atoms)");
+     127         124 :   keys.add("hidden","NO_ACTION_LOG","suppresses printing from action on the log");
+     128          62 : }
+     129             : 
+     130          73 : void Angle::parseAtomList( const int& num, std::vector<AtomNumber>& atoms, ActionAtomistic* aa ) {
+     131         146 :   aa->parseAtomList("ATOMS",num,atoms);
+     132          73 :   if(atoms.size()==3) {
+     133          62 :     aa->log.printf("  between atoms %d %d %d\n",atoms[0].serial(),atoms[1].serial(),atoms[2].serial());
+     134          62 :     atoms.resize(4);
+     135          62 :     atoms[3]=atoms[2];
+     136          62 :     atoms[2]=atoms[1];
+     137          11 :   } else if(atoms.size()==4) {
+     138           7 :     aa->log.printf("  between lines %d-%d and %d-%d\n",atoms[0].serial(),atoms[1].serial(),atoms[2].serial(),atoms[3].serial());
+     139           4 :   } else if( num<0 || atoms.size()>0 ) aa->error("Number of specified atoms should be either 3 or 4");
+     140          72 : }
+     141             : 
+     142           3 : unsigned Angle::getModeAndSetupValues( ActionWithValue* av ) {
+     143           6 :   av->addValueWithDerivatives(); av->setNotPeriodic(); return 0;
+     144             : }
+     145             : 
+     146          23 : Angle::Angle(const ActionOptions&ao):
+     147             :   PLUMED_COLVAR_INIT(ao),
+     148          23 :   pbc(true),
+     149          23 :   value(1),
+     150          24 :   derivs(1),
+     151          46 :   virial(1)
+     152             : {
+     153          23 :   derivs[0].resize(4);
+     154          23 :   std::vector<AtomNumber> atoms; parseAtomList( -1, atoms, this );
+     155          22 :   bool nopbc=!pbc;
+     156          22 :   parseFlag("NOPBC",nopbc);
+     157          22 :   pbc=!nopbc;
+     158             : 
+     159          22 :   if(pbc) log.printf("  using periodic boundary conditions\n");
+     160           0 :   else    log.printf("  without periodic boundary conditions\n");
+     161             : 
+     162          45 :   addValueWithDerivatives(); setNotPeriodic();
+     163          22 :   requestAtoms(atoms);
+     164          22 :   checkRead();
+     165          25 : }
+     166             : 
+     167             : // calculator
+     168         319 : void Angle::calculate() {
+     169             : 
+     170         319 :   if(pbc) makeWhole();
+     171         319 :   calculateCV( 0, masses, charges, getPositions(), value, derivs, virial, this );
+     172         319 :   setValue( value[0] );
+     173        1595 :   for(unsigned i=0; i<derivs[0].size(); ++i) setAtomsDerivatives( i, derivs[0][i] );
+     174         319 :   setBoxDerivatives( virial[0] );
+     175         319 : }
+     176             : 
+     177         554 : void Angle::calculateCV( const unsigned& mode, const std::vector<double>& masses, const std::vector<double>& charges,
+     178             :                          const std::vector<Vector>& pos, std::vector<double>& vals, std::vector<std::vector<Vector> >& derivs,
+     179             :                          std::vector<Tensor>& virial, const ActionAtomistic* aa ) {
+     180         554 :   Vector dij,dik;
+     181         554 :   dij=delta(pos[2],pos[3]);
+     182         554 :   dik=delta(pos[1],pos[0]);
+     183         554 :   Vector ddij,ddik; PLMD::Angle a;
+     184         554 :   vals[0]=a.compute(dij,dik,ddij,ddik);
+     185         554 :   derivs[0][0]=ddik; derivs[0][1]=-ddik;
+     186         554 :   derivs[0][2]=-ddij; derivs[0][3]=ddij;
+     187         554 :   setBoxDerivativesNoPbc( pos, derivs, virial );
+     188         554 : }
+     189             : 
+     190             : }
+     191             : }
+     192             : 
+     193             : 
+     194             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Cell.cpp.func-sort-c.html b/coverage/colvar/Cell.cpp.func-sort-c.html new file mode 100644 index 000000000000..1e961ec40a95 --- /dev/null +++ b/coverage/colvar/Cell.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - colvar/Cell.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Cell.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3535100.0 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

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

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

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar14ColvarShortcutINS0_19DihedralCorrelationEEC1ERKNS_13ActionOptionsE1
_ZN4PLMD6colvar14ColvarShortcutINS0_5PlaneEEC1ERKNS_13ActionOptionsE1
_ZN4PLMD6colvar14ColvarShortcutINS0_19DihedralCorrelationEE16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD6colvar14ColvarShortcutINS0_5PlaneEE16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD6colvar14ColvarShortcutINS_12crystdistrib10QuaternionEEC1ERKNS_13ActionOptionsE17
_ZN4PLMD6colvar14ColvarShortcutINS0_16SelectMassChargeEEC1ERKNS_13ActionOptionsE18
_ZN4PLMD6colvar14ColvarShortcutINS0_16SelectMassChargeEE16registerKeywordsERNS_8KeywordsE22
_ZN4PLMD6colvar14ColvarShortcutINS0_5AngleEEC1ERKNS_13ActionOptionsE26
_ZN4PLMD6colvar14ColvarShortcutINS0_5AngleEE16registerKeywordsERNS_8KeywordsE32
_ZN4PLMD6colvar14ColvarShortcutINS_12crystdistrib10QuaternionEE16registerKeywordsERNS_8KeywordsE48
_ZN4PLMD6colvar14ColvarShortcutINS0_6DipoleEEC1ERKNS_13ActionOptionsE61
_ZN4PLMD6colvar14ColvarShortcutINS0_6DipoleEE16registerKeywordsERNS_8KeywordsE66
_ZN4PLMD6colvar14ColvarShortcutINS0_8PositionEEC1ERKNS_13ActionOptionsE134
_ZN4PLMD6colvar14ColvarShortcutINS0_8PositionEE16registerKeywordsERNS_8KeywordsE152
_ZN4PLMD6colvar14ColvarShortcutINS0_7TorsionEEC1ERKNS_13ActionOptionsE679
_ZN4PLMD6colvar14ColvarShortcutINS0_7TorsionEE16registerKeywordsERNS_8KeywordsE681
_ZN4PLMD6colvar14ColvarShortcutINS0_8DistanceEEC1ERKNS_13ActionOptionsE699
_ZN4PLMD6colvar14ColvarShortcutINS0_8DistanceEE16registerKeywordsERNS_8KeywordsE720
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/ColvarShortcut.h.func.html b/coverage/colvar/ColvarShortcut.h.func.html new file mode 100644 index 000000000000..bffe08e42f0a --- /dev/null +++ b/coverage/colvar/ColvarShortcut.h.func.html @@ -0,0 +1,145 @@ + + + + + + + + LCOV - plumed test coverage - colvar/ColvarShortcut.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - ColvarShortcut.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2121100.0 %
Date:2024-04-19 12:12:35Functions:1818100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar14ColvarShortcutINS0_16SelectMassChargeEE16registerKeywordsERNS_8KeywordsE22
_ZN4PLMD6colvar14ColvarShortcutINS0_16SelectMassChargeEEC1ERKNS_13ActionOptionsE18
_ZN4PLMD6colvar14ColvarShortcutINS0_19DihedralCorrelationEE16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD6colvar14ColvarShortcutINS0_19DihedralCorrelationEEC1ERKNS_13ActionOptionsE1
_ZN4PLMD6colvar14ColvarShortcutINS0_5AngleEE16registerKeywordsERNS_8KeywordsE32
_ZN4PLMD6colvar14ColvarShortcutINS0_5AngleEEC1ERKNS_13ActionOptionsE26
_ZN4PLMD6colvar14ColvarShortcutINS0_5PlaneEE16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD6colvar14ColvarShortcutINS0_5PlaneEEC1ERKNS_13ActionOptionsE1
_ZN4PLMD6colvar14ColvarShortcutINS0_6DipoleEE16registerKeywordsERNS_8KeywordsE66
_ZN4PLMD6colvar14ColvarShortcutINS0_6DipoleEEC1ERKNS_13ActionOptionsE61
_ZN4PLMD6colvar14ColvarShortcutINS0_7TorsionEE16registerKeywordsERNS_8KeywordsE681
_ZN4PLMD6colvar14ColvarShortcutINS0_7TorsionEEC1ERKNS_13ActionOptionsE679
_ZN4PLMD6colvar14ColvarShortcutINS0_8DistanceEE16registerKeywordsERNS_8KeywordsE720
_ZN4PLMD6colvar14ColvarShortcutINS0_8DistanceEEC1ERKNS_13ActionOptionsE699
_ZN4PLMD6colvar14ColvarShortcutINS0_8PositionEE16registerKeywordsERNS_8KeywordsE152
_ZN4PLMD6colvar14ColvarShortcutINS0_8PositionEEC1ERKNS_13ActionOptionsE134
_ZN4PLMD6colvar14ColvarShortcutINS_12crystdistrib10QuaternionEE16registerKeywordsERNS_8KeywordsE48
_ZN4PLMD6colvar14ColvarShortcutINS_12crystdistrib10QuaternionEEC1ERKNS_13ActionOptionsE17
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/ColvarShortcut.h.gcov.html b/coverage/colvar/ColvarShortcut.h.gcov.html new file mode 100644 index 000000000000..2ba158fb5428 --- /dev/null +++ b/coverage/colvar/ColvarShortcut.h.gcov.html @@ -0,0 +1,151 @@ + + + + + + + + LCOV - plumed test coverage - colvar/ColvarShortcut.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - ColvarShortcut.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2121100.0 %
Date:2024-04-19 12:12:35Functions:1818100.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_colvar_ColvarShortcut_h
+      23             : #define __PLUMED_colvar_ColvarShortcut_h
+      24             : 
+      25             : #include "core/ActionShortcut.h"
+      26             : 
+      27             : namespace PLMD {
+      28             : namespace colvar {
+      29             : 
+      30             : template <class T>
+      31             : class ColvarShortcut : public ActionShortcut {
+      32             : public:
+      33             :   static void registerKeywords(Keywords&);
+      34             :   explicit ColvarShortcut(const ActionOptions&);
+      35             : };
+      36             : 
+      37             : template <class T>
+      38        1727 : void ColvarShortcut<T>::registerKeywords(Keywords& keys ) {
+      39        1727 :   T::registerKeywords( keys ); keys.remove("NO_ACTION_LOG");
+      40        1727 :   unsigned nkeys = keys.size();
+      41       16432 :   for(unsigned i=0; i<nkeys; ++i) {
+      42       34716 :     if( keys.style( keys.get(i), "atoms" ) ) keys.reset_style( keys.get(i), "numbered" );
+      43             :   }
+      44        3454 :   keys.addActionNameSuffix("_SCALAR"); keys.addActionNameSuffix("_VECTOR");
+      45        1727 : }
+      46             : 
+      47             : template <class T>
+      48        1636 : ColvarShortcut<T>::ColvarShortcut(const ActionOptions&ao):
+      49             :   Action(ao),
+      50        1636 :   ActionShortcut(ao)
+      51             : {
+      52        1636 :   bool scalar=true; unsigned nkeys = keywords.size();
+      53        4881 :   if( getName()=="MASS" || getName()=="CHARGE" || getName()=="POSITION" ) {
+      54         304 :     std::string inpt; parse("ATOMS",inpt);
+      55         152 :     if( inpt.length()>0 ) {
+      56         114 :       readInputLine( getShortcutLabel() + ": " + getName() + "_VECTOR ATOMS=" + inpt + " " + convertInputLineToString() );
+      57             :       scalar=false;
+      58             :     }
+      59             :   }
+      60       15331 :   for(unsigned i=0; i<nkeys; ++i) {
+      61       27670 :     if( keywords.style( keywords.get(i), "atoms" ) ) {
+      62       10228 :       std::string inpt; parseNumbered( keywords.get(i), 1, inpt );
+      63        5114 :       if( inpt.length()>0 ) {
+      64         280 :         readInputLine( getShortcutLabel() + ": " + getName() + "_VECTOR " + keywords.get(i) + "1=" + inpt + " " + convertInputLineToString() );
+      65             :         scalar=false; break;
+      66             :       }
+      67             :     }
+      68             :   }
+      69        2953 :   if( scalar ) readInputLine( getShortcutLabel() + ": " + getName() + "_SCALAR " + convertInputLineToString() );
+      70        1642 : }
+      71             : 
+      72             : }
+      73             : }
+      74             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/ContactMap.cpp.func-sort-c.html b/coverage/colvar/ContactMap.cpp.func-sort-c.html new file mode 100644 index 000000000000..805cb87eb690 --- /dev/null +++ b/coverage/colvar/ContactMap.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - colvar/ContactMap.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - ContactMap.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12013191.6 %
Date:2024-04-19 12:12:35Functions:3560.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

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

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

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar12CoordinationC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar12CoordinationC1ERKNS_13ActionOptionsE219
_ZN4PLMD6colvar12Coordination16registerKeywordsERNS_8KeywordsE221
_ZNK4PLMD6colvar12Coordination7pairingEdRdjj15264886
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Coordination.cpp.func.html b/coverage/colvar/Coordination.cpp.func.html new file mode 100644 index 000000000000..a3b170b81968 --- /dev/null +++ b/coverage/colvar/Coordination.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - colvar/Coordination.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Coordination.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2929100.0 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar12Coordination16registerKeywordsERNS_8KeywordsE221
_ZN4PLMD6colvar12CoordinationC1ERKNS_13ActionOptionsE219
_ZN4PLMD6colvar12CoordinationC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6colvar12Coordination7pairingEdRdjj15264886
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Coordination.cpp.gcov.html b/coverage/colvar/Coordination.cpp.gcov.html new file mode 100644 index 000000000000..c2ce08521528 --- /dev/null +++ b/coverage/colvar/Coordination.cpp.gcov.html @@ -0,0 +1,231 @@ + + + + + + + + LCOV - plumed test coverage - colvar/Coordination.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Coordination.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2929100.0 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar16CoordinationBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar16CoordinationBaseD0Ev0
_ZN4PLMD6colvar16CoordinationBaseD1Ev0
_ZN4PLMD6colvar16CoordinationBaseC2ERKNS_13ActionOptionsE228
_ZN4PLMD6colvar16CoordinationBaseD2Ev228
_ZN4PLMD6colvar16CoordinationBase16registerKeywordsERNS_8KeywordsE234
_ZN4PLMD6colvar16CoordinationBase9calculateEv3787
_ZN4PLMD6colvar16CoordinationBase7prepareEv4012
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/CoordinationBase.cpp.func.html b/coverage/colvar/CoordinationBase.cpp.func.html new file mode 100644 index 000000000000..dff9fca81529 --- /dev/null +++ b/coverage/colvar/CoordinationBase.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - colvar/CoordinationBase.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - CoordinationBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:899098.9 %
Date:2024-04-19 12:12:35Functions:5862.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar16CoordinationBase16registerKeywordsERNS_8KeywordsE234
_ZN4PLMD6colvar16CoordinationBase7prepareEv4012
_ZN4PLMD6colvar16CoordinationBase9calculateEv3787
_ZN4PLMD6colvar16CoordinationBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar16CoordinationBaseC2ERKNS_13ActionOptionsE228
_ZN4PLMD6colvar16CoordinationBaseD0Ev0
_ZN4PLMD6colvar16CoordinationBaseD1Ev0
_ZN4PLMD6colvar16CoordinationBaseD2Ev228
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/CoordinationBase.cpp.gcov.html b/coverage/colvar/CoordinationBase.cpp.gcov.html new file mode 100644 index 000000000000..f6cffedf88ba --- /dev/null +++ b/coverage/colvar/CoordinationBase.cpp.gcov.html @@ -0,0 +1,284 @@ + + + + + + + + LCOV - plumed test coverage - colvar/CoordinationBase.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - CoordinationBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:899098.9 %
Date:2024-04-19 12:12:35Functions: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         234 : void CoordinationBase::registerKeywords( Keywords& keys ) {
+      31         234 :   Colvar::registerKeywords(keys);
+      32         468 :   keys.addFlag("SERIAL",false,"Perform the calculation in serial - for debug purpose");
+      33         468 :   keys.addFlag("PAIR",false,"Pair only 1st element of the 1st group with 1st element in the second, etc");
+      34         468 :   keys.addFlag("NLIST",false,"Use a neighbor list to speed up the calculation");
+      35         468 :   keys.add("optional","NL_CUTOFF","The cutoff for the neighbor list");
+      36         468 :   keys.add("optional","NL_STRIDE","The frequency with which we are updating the atoms in the neighbor list");
+      37         468 :   keys.add("atoms","GROUPA","First list of atoms");
+      38         468 :   keys.add("atoms","GROUPB","Second list of atoms (if empty, N*(N-1)/2 pairs in GROUPA are counted)");
+      39         234 : }
+      40             : 
+      41         228 : CoordinationBase::CoordinationBase(const ActionOptions&ao):
+      42             :   PLUMED_COLVAR_INIT(ao),
+      43         228 :   pbc(true),
+      44         228 :   serial(false),
+      45         228 :   invalidateList(true),
+      46         228 :   firsttime(true)
+      47             : {
+      48             : 
+      49         456 :   parseFlag("SERIAL",serial);
+      50             : 
+      51             :   std::vector<AtomNumber> ga_lista,gb_lista;
+      52         228 :   parseAtomList("GROUPA",ga_lista);
+      53         228 :   parseAtomList("GROUPB",gb_lista);
+      54             : 
+      55         228 :   bool nopbc=!pbc;
+      56         228 :   parseFlag("NOPBC",nopbc);
+      57         228 :   pbc=!nopbc;
+      58             : 
+      59             : // pair stuff
+      60         228 :   bool dopair=false;
+      61         228 :   parseFlag("PAIR",dopair);
+      62             : 
+      63             : // neighbor list stuff
+      64         228 :   bool doneigh=false;
+      65         228 :   double nl_cut=0.0;
+      66         228 :   int nl_st=0;
+      67         228 :   parseFlag("NLIST",doneigh);
+      68         228 :   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         456 :   addValueWithDerivatives(); setNotPeriodic();
+      76         228 :   if(gb_lista.size()>0) {
+      77         241 :     if(doneigh)  nl=Tools::make_unique<NeighborList>(ga_lista,gb_lista,serial,dopair,pbc,getPbc(),comm,nl_cut,nl_st);
+      78         386 :     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         228 :   requestAtoms(nl->getFullAtomList());
+      85             : 
+      86         228 :   log.printf("  between two groups of %u and %u atoms\n",static_cast<unsigned>(ga_lista.size()),static_cast<unsigned>(gb_lista.size()));
+      87         228 :   log.printf("  first group:\n");
+      88        5535 :   for(unsigned int i=0; i<ga_lista.size(); ++i) {
+      89        5307 :     if ( (i+1) % 25 == 0 ) log.printf("  \n");
+      90        5307 :     log.printf("  %d", ga_lista[i].serial());
+      91             :   }
+      92         228 :   log.printf("  \n  second group:\n");
+      93       10971 :   for(unsigned int i=0; i<gb_lista.size(); ++i) {
+      94       10743 :     if ( (i+1) % 25 == 0 ) log.printf("  \n");
+      95       10743 :     log.printf("  %d", gb_lista[i].serial());
+      96             :   }
+      97         228 :   log.printf("  \n");
+      98         228 :   if(pbc) log.printf("  using periodic boundary conditions\n");
+      99           0 :   else    log.printf("  without periodic boundary conditions\n");
+     100         228 :   if(dopair) log.printf("  with PAIR option\n");
+     101         228 :   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         228 : }
+     106             : 
+     107         228 : CoordinationBase::~CoordinationBase() {
+     108             : // destructor required to delete forward declared class
+     109         228 : }
+     110             : 
+     111        4012 : void CoordinationBase::prepare() {
+     112        4012 :   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        4012 : }
+     125             : 
+     126             : // calculator
+     127        3787 : void CoordinationBase::calculate()
+     128             : {
+     129             : 
+     130        3787 :   double ncoord=0.;
+     131        3787 :   Tensor virial;
+     132        3787 :   std::vector<Vector> deriv(getNumberOfAtoms());
+     133             : 
+     134        3787 :   if(nl->getStride()>0 && invalidateList) {
+     135         143 :     nl->update(getPositions());
+     136             :   }
+     137             : 
+     138             :   unsigned stride;
+     139             :   unsigned rank;
+     140        3787 :   if(serial) {
+     141             :     stride=1;
+     142             :     rank=0;
+     143             :   } else {
+     144        3787 :     stride=comm.Get_size();
+     145        3787 :     rank=comm.Get_rank();
+     146             :   }
+     147             : 
+     148        3787 :   unsigned nt=OpenMP::getNumThreads();
+     149        3787 :   const unsigned nn=nl->size();
+     150        3787 :   if(nt*stride*10>nn) nt=1;
+     151             : 
+     152        3787 :   #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        3787 :   if(!serial) {
+     196        3787 :     comm.Sum(ncoord);
+     197        3787 :     if(!deriv.empty()) comm.Sum(&deriv[0][0],3*deriv.size());
+     198        3787 :     comm.Sum(virial);
+     199             :   }
+     200             : 
+     201      380565 :   for(unsigned i=0; i<deriv.size(); ++i) setAtomsDerivatives(i,deriv[i]);
+     202        3787 :   setValue           (ncoord);
+     203        3787 :   setBoxDerivatives  (virial);
+     204             : 
+     205        3787 : }
+     206             : }
+     207             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/DHEnergy.cpp.func-sort-c.html b/coverage/colvar/DHEnergy.cpp.func-sort-c.html new file mode 100644 index 000000000000..4a4b5e5d150c --- /dev/null +++ b/coverage/colvar/DHEnergy.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - colvar/DHEnergy.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - DHEnergy.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:313393.9 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

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

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

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar5DRMSDC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar5DRMSDC1ERKNS_13ActionOptionsE13
_ZN4PLMD6colvar5DRMSD16registerKeywordsERNS_8KeywordsE15
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/DRMSD.cpp.func.html b/coverage/colvar/DRMSD.cpp.func.html new file mode 100644 index 000000000000..dcbd1a5a41d3 --- /dev/null +++ b/coverage/colvar/DRMSD.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + 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:9710097.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar5DRMSD16registerKeywordsERNS_8KeywordsE15
_ZN4PLMD6colvar5DRMSDC1ERKNS_13ActionOptionsE13
_ZN4PLMD6colvar5DRMSDC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/DRMSD.cpp.gcov.html b/coverage/colvar/DRMSD.cpp.gcov.html new file mode 100644 index 000000000000..af7bd4802fc0 --- /dev/null +++ b/coverage/colvar/DRMSD.cpp.gcov.html @@ -0,0 +1,347 @@ + + + + + + + + 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:9710097.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-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 "core/ActionShortcut.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "core/PlumedMain.h"
+      25             : #include "core/ActionSet.h"
+      26             : #include "core/Group.h"
+      27             : #include "tools/PDB.h"
+      28             : 
+      29             : namespace PLMD {
+      30             : namespace colvar {
+      31             : 
+      32             : //+PLUMEDOC DCOLVAR DRMSD
+      33             : /*
+      34             : Calculate the distance RMSD with respect to a reference structure.
+      35             : 
+      36             : To calculate the root-mean-square deviation between the atoms in two configurations
+      37             : you must first superimpose the two structures in some ways.  Obviously, it is the internal vibrational
+      38             : motions of the structure - i.e. not the translations and rotations - that are interesting. However,
+      39             : aligning two structures by removing the translational and rotational motions is not easy.  Furthermore,
+      40             : in some cases there can be alignment issues caused by so-called frame-fitting problems. It is thus
+      41             : often cheaper and easier to calculate the distances between all the pairs of atoms.  The distance
+      42             : between the two structures, \f$\mathbf{X}^a\f$ and \f$\mathbf{X}^b\f$ can then be measured as:
+      43             : 
+      44             : \f[
+      45             : d(\mathbf{X}^A, \mathbf{X}^B) = \sqrt{\frac{1}{N(N-1)} \sum_{i \ne j} [ d(\mathbf{x}_i^a,\mathbf{x}_j^a) - d(\mathbf{x}_i^b,\mathbf{x}_j^b) ]^2}
+      46             : \f]
+      47             : 
+      48             : where \f$N\f$ is the number of atoms and \f$d(\mathbf{x}_i,\mathbf{x}_j)\f$ represents the distance between
+      49             : atoms \f$i\f$ and \f$j\f$.  Clearly, this representation of the configuration is invariant to translation and rotation.
+      50             : However, it can become expensive to calculate when the number of atoms is large.  This can be resolved
+      51             : within the DRMSD colvar by setting LOWER_CUTOFF and UPPER_CUTOFF.  These keywords ensure that only
+      52             : pairs of atoms that are within a certain range are incorporated into the above sum.
+      53             : 
+      54             : In PDB files the atomic coordinates and box lengths should be in Angstroms unless
+      55             : you are working with natural units.  If you are working with natural units then the coordinates
+      56             : should be in your natural length unit.  For more details on the PDB file format visit http://www.wwpdb.org/docs.html
+      57             : 
+      58             : \par Examples
+      59             : 
+      60             : The following tells plumed to calculate the distance RMSD between
+      61             : the positions of the atoms in the reference file and their instantaneous
+      62             : position. Only pairs of atoms whose distance in the reference structure is within
+      63             : 0.1 and 0.8 nm are considered.
+      64             : 
+      65             : \plumedfile
+      66             : DRMSD REFERENCE=file1.pdb LOWER_CUTOFF=0.1 UPPER_CUTOFF=0.8
+      67             : \endplumedfile
+      68             : 
+      69             : The reference file is a PDB file that looks like this
+      70             : 
+      71             : \auxfile{file1.pdb}
+      72             : ATOM      8  HT3 ALA     2      -1.480  -1.560   1.212  1.00  1.00      DIA  H
+      73             : ATOM      9  CAY ALA     2      -0.096   2.144  -0.669  1.00  1.00      DIA  C
+      74             : ATOM     10  HY1 ALA     2       0.871   2.385  -0.588  1.00  1.00      DIA  H
+      75             : ATOM     12  HY3 ALA     2      -0.520   2.679  -1.400  1.00  1.00      DIA  H
+      76             : ATOM     14  OY  ALA     2      -1.139   0.931  -0.973  1.00  1.00      DIA  O
+      77             : END
+      78             : \endauxfile
+      79             : 
+      80             : The following tells plumed to calculate a DRMSD value for a pair of molecules.
+      81             : 
+      82             : \plumedfile
+      83             : DRMSD REFERENCE=file2.pdb LOWER_CUTOFF=0.1 UPPER_CUTOFF=0.8 TYPE=INTER-DRMSD
+      84             : \endplumedfile
+      85             : 
+      86             : In the input reference file (file.pdb) the atoms in each of the two molecules are separated by a TER
+      87             : command as shown below.
+      88             : 
+      89             : \auxfile{file2.pdb}
+      90             : ATOM      8  HT3 ALA     2      -1.480  -1.560   1.212  1.00  1.00      DIA  H
+      91             : ATOM      9  CAY ALA     2      -0.096   2.144  -0.669  1.00  1.00      DIA  C
+      92             : ATOM     10  HY1 ALA     2       0.871   2.385  -0.588  1.00  1.00      DIA  H
+      93             : TER
+      94             : ATOM     12  HY3 ALA     2      -0.520   2.679  -1.400  1.00  1.00      DIA  H
+      95             : ATOM     14  OY  ALA     2      -1.139   0.931  -0.973  1.00  1.00      DIA  O
+      96             : END
+      97             : \endauxfile
+      98             : 
+      99             : In this example the INTER-DRMSD type ensures that the set of distances from which the final
+     100             : quantity is computed involve one atom from each of the two molecules.  If this is replaced
+     101             : by INTRA-DRMSD then only those distances involving pairs of atoms that are both in the same
+     102             : molecule are computed.
+     103             : 
+     104             : */
+     105             : //+ENDPLUMEDOC
+     106             : 
+     107             : class DRMSD : public ActionShortcut {
+     108             : public:
+     109             :   static void registerKeywords(Keywords& keys);
+     110             :   explicit DRMSD(const ActionOptions&);
+     111             : };
+     112             : 
+     113             : PLUMED_REGISTER_ACTION(DRMSD,"DRMSD")
+     114             : 
+     115          15 : void DRMSD::registerKeywords( Keywords& keys ) {
+     116          15 :   ActionShortcut::registerKeywords( keys );
+     117          30 :   keys.add("compulsory","REFERENCE","a file in pdb format containing the reference structure and the atoms involved in the CV.");
+     118          30 :   keys.add("optional","LOWER_CUTOFF","only pairs of atoms further than LOWER_CUTOFF are considered in the calculation.");
+     119          30 :   keys.add("optional","UPPER_CUTOFF","only pairs of atoms closer than UPPER_CUTOFF are considered in the calculation.");
+     120          30 :   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 "
+     121             :            "the atoms in your molecule.  Alternatively, if you have multiple molecules you can use the type INTER-DRMSD "
+     122             :            "to compute DRMSD values involving only those distances between the atoms at least two molecules or the type INTRA-DRMSD "
+     123             :            "to compute DRMSD values involving only those distances between atoms in the same molecule");
+     124          30 :   keys.addFlag("SQUARED",false,"This should be setted if you want MSD instead of RMSD ");
+     125          30 :   keys.addFlag("NOPBC",false,"ignore the periodic boundary conditions when calculating distances");
+     126             :   // This is just ignored in reality which is probably bad
+     127          30 :   keys.addFlag("NUMERICAL_DERIVATIVES",false,"calculate the derivatives for these quantities numerically");
+     128          75 :   keys.needsAction("SUM"); keys.needsAction("DISTANCE"); keys.needsAction("CONSTANT"); keys.needsAction("EUCLIDEAN_DISTANCE"); keys.needsAction("CUSTOM");
+     129          15 : }
+     130             : 
+     131          13 : DRMSD::DRMSD( const ActionOptions& ao ):
+     132             :   Action(ao),
+     133          13 :   ActionShortcut(ao)
+     134             : {
+     135             :   // Read in the reference configuration
+     136          13 :   std::string reference; parse("REFERENCE",reference);
+     137             :   // First bit of input for the instantaneous distances
+     138          26 :   bool numder; parseFlag("NUMERICAL_DERIVATIVES",numder); double fake_unit=0.1;
+     139          13 :   FILE* fp2=fopen(reference.c_str(),"r"); bool do_read=true; unsigned nframes=0;
+     140          65 :   while( do_read ) {
+     141          54 :     PDB mypdb; do_read=mypdb.readFromFilepointer(fp2,false,fake_unit);
+     142          54 :     if( !do_read && nframes>0 ) break ;
+     143          53 :     nframes++;
+     144          54 :   }
+     145          12 :   fclose(fp2);
+     146             : 
+     147             :   // Get cutoff information
+     148          25 :   double lcut=0; parse("LOWER_CUTOFF",lcut); std::string drmsd_type; parse("TYPE",drmsd_type);
+     149          12 :   double ucut=std::numeric_limits<double>::max(); parse("UPPER_CUTOFF",ucut);
+     150          24 :   bool nopbc; parseFlag("NOPBC",nopbc); std::string pbc_str; if(nopbc) pbc_str="NOPBC";
+     151             :   // Open the pdb file
+     152          12 :   FILE* fp=fopen(reference.c_str(),"r"); do_read=true;
+     153          12 :   if(!fp) error("could not open reference file " + reference ); unsigned n=0; std::string allpairs="";
+     154             :   std::vector<std::pair<unsigned,unsigned> > upairs; std::vector<std::string> refvals;
+     155          65 :   while ( do_read ) {
+     156          54 :     PDB mypdb; do_read=mypdb.readFromFilepointer(fp,false,fake_unit);
+     157          54 :     if( !do_read && n>0 ) break ;
+     158          53 :     std::vector<Vector> pos( mypdb.getPositions() ); unsigned nn=1;
+     159          53 :     if( pos.size()==0 ) error("read no atoms from file named " + reference );
+     160             :     // This is what we do for the first frame
+     161          53 :     if( n==0 ) {
+     162          12 :       std::vector<AtomNumber> atoms( mypdb.getAtomNumbers() );
+     163          12 :       if( drmsd_type=="DRMSD" ) {
+     164         102 :         for(unsigned i=0; i<atoms.size()-1; ++i) {
+     165          92 :           std::string istr; Tools::convert( atoms[i].serial(), istr );
+     166         671 :           for(unsigned j=i+1; j<atoms.size(); ++j) {
+     167         579 :             std::string jstr; Tools::convert( atoms[j].serial(), jstr );
+     168         579 :             double distance = delta( pos[i], pos[j] ).modulo();
+     169         579 :             if( distance < ucut && distance > lcut ) {
+     170         386 :               std::string num; Tools::convert( nn, num ); nn++;
+     171             :               // Add this pair to list of pairs
+     172         386 :               upairs.push_back( std::pair<unsigned,unsigned>(i,j) );
+     173             :               // Add this distance to list of reference values
+     174         386 :               std::string dstr; Tools::convert( distance, dstr ); refvals.push_back( dstr );
+     175             :               // Calculate this distance
+     176         694 :               if( nframes==1 ) allpairs += " ATOMS" + num + "=" + istr + "," + jstr;
+     177         156 :               else readInputLine( getShortcutLabel() + "_d" + num + ": DISTANCE ATOMS=" + istr + "," + jstr + " " + pbc_str );
+     178             :             }
+     179             :           }
+     180             :         }
+     181             :       } else {
+     182           2 :         unsigned nblocks = mypdb.getNumberOfAtomBlocks(); std::vector<unsigned> blocks( 1 + nblocks );
+     183           2 :         if( nblocks==1 ) { blocks[0]=0; blocks[1]=atoms.size(); }
+     184           6 :         else { blocks[0]=0; for(unsigned i=0; i<nblocks; ++i) blocks[i+1]=mypdb.getAtomBlockEnds()[i]; }
+     185           2 :         if( drmsd_type=="INTRA-DRMSD" ) {
+     186           3 :           for(unsigned i=0; i<nblocks; ++i) {
+     187           7 :             for(unsigned iatom=blocks[i]+1; iatom<blocks[i+1]; ++iatom) {
+     188           5 :               std::string istr; Tools::convert( atoms[iatom].serial(), istr );
+     189          14 :               for(unsigned jatom=blocks[i]; jatom<iatom; ++jatom) {
+     190           9 :                 std::string jstr; Tools::convert( atoms[jatom].serial(), jstr );
+     191           9 :                 double distance = delta( pos[iatom], pos[jatom] ).modulo();
+     192           9 :                 if(distance < ucut && distance > lcut ) {
+     193           9 :                   std::string num; Tools::convert( nn, num ); nn++;
+     194             :                   // Add this pair to list of pairs
+     195           9 :                   upairs.push_back( std::pair<unsigned,unsigned>(iatom,jatom) );
+     196             :                   // Add this distance to list of reference values
+     197           9 :                   std::string dstr; Tools::convert( distance, dstr ); refvals.push_back( dstr );
+     198             :                   // Calculate this distance
+     199          18 :                   if( nframes==1 ) allpairs += " ATOMS" + num + "=" + istr + "," + jstr;
+     200           0 :                   else readInputLine( getShortcutLabel() + "_d" + num + ": DISTANCE ATOMS=" + istr + "," + jstr + " " + pbc_str );
+     201             :                 }
+     202             :               }
+     203             :             }
+     204             :           }
+     205           1 :         } else if( drmsd_type=="INTER-DRMSD" ) {
+     206           2 :           for(unsigned i=1; i<nblocks; ++i) {
+     207           2 :             for(unsigned j=0; j<i; ++j) {
+     208           4 :               for(unsigned iatom=blocks[i]; iatom<blocks[i+1]; ++iatom) {
+     209           3 :                 std::string istr; Tools::convert( atoms[iatom].serial(), istr );
+     210          15 :                 for(unsigned jatom=blocks[j]; jatom<blocks[j+1]; ++jatom) {
+     211          12 :                   std::string jstr; Tools::convert( atoms[jatom].serial(), jstr );
+     212          12 :                   double distance = delta( pos[iatom], pos[jatom] ).modulo();
+     213          12 :                   if(distance < ucut && distance > lcut ) {
+     214          12 :                     std::string num; Tools::convert( nn, num ); nn++;
+     215             :                     // Add this pair to list of pairs
+     216          12 :                     upairs.push_back( std::pair<unsigned,unsigned>(iatom,jatom) );
+     217             :                     // Add this distance to list of reference values
+     218          12 :                     std::string dstr; Tools::convert( distance, dstr ); refvals.push_back( dstr );
+     219             :                     // Calculate this distance
+     220          24 :                     if( nframes==1 ) allpairs += " ATOMS" + num + "=" + istr + "," + jstr;
+     221           0 :                     else readInputLine( getShortcutLabel() + "_d" + num + ": DISTANCE ATOMS=" + istr + "," + jstr + " " + pbc_str );
+     222             :                   }
+     223             :                 }
+     224             :               }
+     225             :             }
+     226             :           }
+     227           0 :         } else plumed_merror( drmsd_type + " is not valid input to TYPE keyword");
+     228             :       }
+     229             :       // This is for every subsequent frame
+     230             :     } else {
+     231        3239 :       for(unsigned i=0; i<refvals.size(); ++i) {
+     232        3198 :         std::string dstr; Tools::convert( delta( pos[upairs[i].first], pos[upairs[i].second] ).modulo(), dstr );
+     233        6396 :         refvals[i] += "," + dstr;
+     234             :       }
+     235             :     }
+     236          53 :     n++;
+     237          54 :   }
+     238             :   // Now create values that hold all the reference distances
+     239          12 :   fclose(fp);
+     240             : 
+     241          12 :   if( nframes==1 ) {
+     242          22 :     readInputLine( getShortcutLabel() + "_d: DISTANCE" + allpairs + " " + pbc_str );
+     243         340 :     std::string refstr = refvals[0]; for(unsigned i=1; i<refvals.size(); ++i) refstr += "," + refvals[i];
+     244          22 :     readInputLine( getShortcutLabel() + "_ref: CONSTANT VALUES="  + refstr );
+     245          22 :     readInputLine( getShortcutLabel() + "_diffs: CUSTOM ARG=" + getShortcutLabel() + "_d," + getShortcutLabel() + "_ref FUNC=(x-y)*(x-y) PERIODIC=NO");
+     246          22 :     readInputLine( getShortcutLabel() + "_u: SUM ARG=" + getShortcutLabel() + "_diffs PERIODIC=NO");
+     247             :   } else {
+     248             :     std::string arg_str1, arg_str2;
+     249          79 :     for(unsigned i=0; i<refvals.size(); ++i ) {
+     250          78 :       std::string inum; Tools::convert( i+1, inum );
+     251         156 :       readInputLine( getShortcutLabel() + "_ref" + inum + ": CONSTANT VALUES=" + refvals[i] );
+     252          80 :       if( i==0 ) { arg_str1 = getShortcutLabel() + "_d" + inum; arg_str2 = getShortcutLabel() + "_ref" + inum; }
+     253         231 :       else { arg_str1 += "," + getShortcutLabel() + "_d" + inum; arg_str2 += "," + getShortcutLabel() + "_ref" + inum; }
+     254             :     }
+     255             :     // And calculate the euclidean distances between the true distances and the references
+     256           2 :     readInputLine( getShortcutLabel() + "_u: EUCLIDEAN_DISTANCE SQUARED ARG1=" + arg_str1 + " ARG2=" + arg_str2 );
+     257             :   }
+     258             :   // And final value
+     259          12 :   std::string nvals; Tools::convert( refvals.size(), nvals ); bool squared; parseFlag("SQUARED",squared);
+     260          15 :   if( squared ) readInputLine( getShortcutLabel() + ": CUSTOM ARG=" + getShortcutLabel() + "_u FUNC=x/" + nvals + " PERIODIC=NO");
+     261             :   else {
+     262          18 :     readInputLine( getShortcutLabel() + "_2: CUSTOM ARG=" + getShortcutLabel() + "_u FUNC=(x/" + nvals + ") PERIODIC=NO");
+     263          18 :     readInputLine( getShortcutLabel() + ": CUSTOM ARG=" + getShortcutLabel() + "_2 FUNC=sqrt(x) PERIODIC=NO");
+     264             :   }
+     265          26 : }
+     266             : 
+     267             : }
+     268             : }
+     269             : 
+     270             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/DihedralCorrelation.cpp.func-sort-c.html b/coverage/colvar/DihedralCorrelation.cpp.func-sort-c.html new file mode 100644 index 000000000000..6d6bcdf4f3b7 --- /dev/null +++ b/coverage/colvar/DihedralCorrelation.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - colvar/DihedralCorrelation.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - DihedralCorrelation.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:436467.2 %
Date:2024-04-19 12:12:35Functions:4757.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar19DihedralCorrelation9calculateEv0
_ZN4PLMD6colvar19DihedralCorrelationC1ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar19DihedralCorrelationC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar19DihedralCorrelation21getModeAndSetupValuesEPNS_15ActionWithValueE1
_ZN4PLMD6colvar19DihedralCorrelation13parseAtomListERKiRSt6vectorINS_10AtomNumberESaIS5_EEPNS_15ActionAtomisticE3
_ZN4PLMD6colvar19DihedralCorrelation16registerKeywordsERNS_8KeywordsE8
_ZN4PLMD6colvar19DihedralCorrelation11calculateCVERKjRKSt6vectorIdSaIdEES8_RKS4_INS_13VectorGenericILj3EEESaISA_EERS6_RS4_ISC_SaISC_EERS4_INS_13TensorGenericILj3ELj3EEESaISK_EEPKNS_15ActionAtomisticE10
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/DihedralCorrelation.cpp.func.html b/coverage/colvar/DihedralCorrelation.cpp.func.html new file mode 100644 index 000000000000..50ca9e02afa3 --- /dev/null +++ b/coverage/colvar/DihedralCorrelation.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - colvar/DihedralCorrelation.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - DihedralCorrelation.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:436467.2 %
Date:2024-04-19 12:12:35Functions:4757.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar19DihedralCorrelation11calculateCVERKjRKSt6vectorIdSaIdEES8_RKS4_INS_13VectorGenericILj3EEESaISA_EERS6_RS4_ISC_SaISC_EERS4_INS_13TensorGenericILj3ELj3EEESaISK_EEPKNS_15ActionAtomisticE10
_ZN4PLMD6colvar19DihedralCorrelation13parseAtomListERKiRSt6vectorINS_10AtomNumberESaIS5_EEPNS_15ActionAtomisticE3
_ZN4PLMD6colvar19DihedralCorrelation16registerKeywordsERNS_8KeywordsE8
_ZN4PLMD6colvar19DihedralCorrelation21getModeAndSetupValuesEPNS_15ActionWithValueE1
_ZN4PLMD6colvar19DihedralCorrelation9calculateEv0
_ZN4PLMD6colvar19DihedralCorrelationC1ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar19DihedralCorrelationC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/DihedralCorrelation.cpp.gcov.html b/coverage/colvar/DihedralCorrelation.cpp.gcov.html new file mode 100644 index 000000000000..19b22bef5036 --- /dev/null +++ b/coverage/colvar/DihedralCorrelation.cpp.gcov.html @@ -0,0 +1,256 @@ + + + + + + + + LCOV - plumed test coverage - colvar/DihedralCorrelation.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - DihedralCorrelation.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:436467.2 %
Date:2024-04-19 12:12:35Functions:4757.1 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2020 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received 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 "ColvarShortcut.h"
+      24             : #include "MultiColvarTemplate.h"
+      25             : #include "tools/Torsion.h"
+      26             : #include "core/ActionRegister.h"
+      27             : 
+      28             : #include <string>
+      29             : #include <cmath>
+      30             : 
+      31             : namespace PLMD {
+      32             : namespace colvar {
+      33             : 
+      34             : //+PLUMEDOC COLVAR DIHEDRAL_CORRELATION
+      35             : /*
+      36             : Measure the correlation between a pair of dihedral angles
+      37             : 
+      38             : 
+      39             : \par Examples
+      40             : 
+      41             : */
+      42             : //+ENDPLUMEDOC
+      43             : 
+      44             : //+PLUMEDOC COLVAR DIHEDRAL_CORRELATION_SCALAR
+      45             : /*
+      46             : Measure the correlation between a multiple pairs of dihedral angles
+      47             : 
+      48             : 
+      49             : \par Examples
+      50             : 
+      51             : */
+      52             : //+ENDPLUMEDOC
+      53             : 
+      54             : //+PLUMEDOC COLVAR DIHEDRAL_CORRELATION_VECTOR
+      55             : /*
+      56             : Measure the correlation between a multiple pairs of dihedral angles
+      57             : 
+      58             : 
+      59             : \par Examples
+      60             : 
+      61             : */
+      62             : //+ENDPLUMEDOC
+      63             : 
+      64             : class DihedralCorrelation : public Colvar {
+      65             : private:
+      66             :   bool pbc;
+      67             :   std::vector<double> value, masses, charges;
+      68             :   std::vector<std::vector<Vector> > derivs;
+      69             :   std::vector<Tensor> virial;
+      70             : public:
+      71             :   static void registerKeywords( Keywords& keys );
+      72             :   explicit DihedralCorrelation(const ActionOptions&);
+      73             :   static void parseAtomList( const int& num, std::vector<AtomNumber>& t, ActionAtomistic* aa );
+      74             :   static unsigned getModeAndSetupValues( ActionWithValue* av );
+      75             :   void calculate() override;
+      76             :   static void calculateCV( const unsigned& mode, const std::vector<double>& masses, const std::vector<double>& charges,
+      77             :                            const std::vector<Vector>& pos, std::vector<double>& vals, std::vector<std::vector<Vector> >& derivs,
+      78             :                            std::vector<Tensor>& virial, const ActionAtomistic* aa );
+      79             : };
+      80             : 
+      81             : typedef ColvarShortcut<DihedralCorrelation> DihedralCorrelationShortcut;
+      82             : PLUMED_REGISTER_ACTION(DihedralCorrelationShortcut,"DIHEDRAL_CORRELATION")
+      83             : PLUMED_REGISTER_ACTION(DihedralCorrelation,"DIHEDRAL_CORRELATION_SCALAR")
+      84             : typedef MultiColvarTemplate<DihedralCorrelation> DihedralCorrelationMulti;
+      85             : PLUMED_REGISTER_ACTION(DihedralCorrelationMulti,"DIHEDRAL_CORRELATION_VECTOR")
+      86             : 
+      87           8 : void DihedralCorrelation::registerKeywords( Keywords& keys ) {
+      88           8 :   Colvar::registerKeywords( keys );
+      89          16 :   keys.add("atoms","ATOMS","the set of 8 atoms that are being used to calculate this quantity");
+      90          16 :   keys.add("hidden","NO_ACTION_LOG","suppresses printing from action on the log");
+      91           8 : }
+      92             : 
+      93           0 : DihedralCorrelation::DihedralCorrelation(const ActionOptions&ao):
+      94             :   PLUMED_COLVAR_INIT(ao),
+      95           0 :   pbc(true),
+      96           0 :   value(1),
+      97           0 :   derivs(1),
+      98           0 :   virial(1)
+      99             : {
+     100           0 :   derivs[0].resize(8); std::vector<AtomNumber> atoms;
+     101           0 :   parseAtomList(-1,atoms,this);
+     102           0 :   if( atoms.size()!=8 ) error("Number of specified atoms should be 8");
+     103             : 
+     104           0 :   bool nopbc=!pbc;
+     105           0 :   parseFlag("NOPBC",nopbc);
+     106           0 :   pbc=!nopbc;
+     107             : 
+     108           0 :   if(pbc) log.printf("  using periodic boundary conditions\n");
+     109           0 :   else    log.printf("  without periodic boundary conditions\n");
+     110           0 : }
+     111             : 
+     112           3 : void DihedralCorrelation::parseAtomList( const int& num, std::vector<AtomNumber>& t, ActionAtomistic* aa ) {
+     113           3 :   aa->parseAtomList("ATOMS",num,t);
+     114           3 :   if( num<0 && t.size()!=8 ) aa->error("Number of specified atoms should be 8");
+     115           3 :   if( t.size()==8 ) {
+     116           2 :     aa->log.printf("  correlation between dihedral angle for atoms %d %d %d %d and atoms %d %d %d %d\n",
+     117             :                    t[0].serial(),t[1].serial(),t[2].serial(),t[3].serial(),t[4].serial(),t[5].serial(),t[6].serial(),t[7].serial());
+     118             :   }
+     119           3 : }
+     120             : 
+     121           1 : unsigned DihedralCorrelation::getModeAndSetupValues( ActionWithValue* av ) {
+     122           2 :   av->addValueWithDerivatives(); av->setNotPeriodic(); return 0;
+     123             : }
+     124             : 
+     125           0 : void DihedralCorrelation::calculate() {
+     126             : 
+     127           0 :   if(pbc) makeWhole();
+     128           0 :   calculateCV( 0, masses, charges, getPositions(), value, derivs, virial, this );
+     129           0 :   setValue( value[0] );
+     130           0 :   for(unsigned i=0; i<derivs[0].size(); ++i) setAtomsDerivatives( i, derivs[0][i] );
+     131           0 :   setBoxDerivatives( virial[0] );
+     132           0 : }
+     133             : 
+     134          10 : void DihedralCorrelation::calculateCV( const unsigned& mode, const std::vector<double>& masses, const std::vector<double>& charges,
+     135             :                                        const std::vector<Vector>& pos, std::vector<double>& vals, std::vector<std::vector<Vector> >& derivs,
+     136             :                                        std::vector<Tensor>& virial, const ActionAtomistic* aa ) {
+     137          10 :   const Vector d10=delta(pos[1],pos[0]);
+     138          10 :   const Vector d11=delta(pos[2],pos[1]);
+     139          10 :   const Vector d12=delta(pos[3],pos[2]);
+     140             : 
+     141          10 :   Vector dd10,dd11,dd12;
+     142             :   PLMD::Torsion t1;
+     143          10 :   const double phi1  = t1.compute(d10,d11,d12,dd10,dd11,dd12);
+     144             : 
+     145          10 :   const Vector d20=delta(pos[5],pos[4]);
+     146          10 :   const Vector d21=delta(pos[6],pos[5]);
+     147          10 :   const Vector d22=delta(pos[7],pos[6]);
+     148             : 
+     149          10 :   Vector dd20,dd21,dd22;
+     150             :   PLMD::Torsion t2;
+     151          10 :   const double phi2 = t2.compute( d20, d21, d22, dd20, dd21, dd22 );
+     152             : 
+     153             :   // Calculate value
+     154          10 :   const double diff = phi2 - phi1;
+     155          10 :   vals[0] = 0.5*(1.+std::cos(diff));
+     156             :   // Derivatives wrt phi1
+     157          10 :   const double dval = 0.5*std::sin(diff);
+     158          10 :   dd10 *= dval;
+     159          10 :   dd11 *= dval;
+     160          10 :   dd12 *= dval;
+     161             :   // And add
+     162          10 :   derivs[0][0]=dd10;
+     163          10 :   derivs[0][1]=dd11-dd10;
+     164          10 :   derivs[0][2]=dd12-dd11;
+     165          10 :   derivs[0][3]=-dd12;
+     166             :   // Derivative wrt phi2
+     167          10 :   dd20 *= -dval;
+     168          10 :   dd21 *= -dval;
+     169          10 :   dd22 *= -dval;
+     170             :   // And add
+     171          10 :   derivs[0][4]=dd20;
+     172          10 :   derivs[0][5]=dd21-dd20;
+     173          10 :   derivs[0][6]=dd22-dd21;
+     174          10 :   derivs[0][7]=-dd22;
+     175          10 :   virial[0] = -(extProduct(d10,dd10)+extProduct(d11,dd11)+extProduct(d12,dd12)) - (extProduct(d20,dd20)+extProduct(d21,dd21)+extProduct(d22,dd22));
+     176          10 : }
+     177             : 
+     178             : }
+     179             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Dimer.cpp.func-sort-c.html b/coverage/colvar/Dimer.cpp.func-sort-c.html new file mode 100644 index 000000000000..ad6a1005415d --- /dev/null +++ b/coverage/colvar/Dimer.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - colvar/Dimer.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Dimer.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:828992.1 %
Date:2024-04-19 12:12:35Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

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

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

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar6DipoleC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar6DipoleC1ERKNS_13ActionOptionsE58
_ZN4PLMD6colvar6Dipole21getModeAndSetupValuesEPNS_15ActionWithValueE61
_ZN4PLMD6colvar6Dipole16registerKeywordsERNS_8KeywordsE131
_ZN4PLMD6colvar6Dipole13parseAtomListERKiRSt6vectorINS_10AtomNumberESaIS5_EEPNS_15ActionAtomisticE576
_ZN4PLMD6colvar6Dipole9calculateEv943
_ZN4PLMD6colvar6Dipole11calculateCVERKjRKSt6vectorIdSaIdEERS6_RKS4_INS_13VectorGenericILj3EEESaISB_EES9_RS4_ISD_SaISD_EERS4_INS_13TensorGenericILj3ELj3EEESaISK_EEPKNS_15ActionAtomisticE4029
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Dipole.cpp.func.html b/coverage/colvar/Dipole.cpp.func.html new file mode 100644 index 000000000000..bf8d2196a335 --- /dev/null +++ b/coverage/colvar/Dipole.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - colvar/Dipole.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Dipole.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:838498.8 %
Date:2024-04-19 12:12:35Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar6Dipole11calculateCVERKjRKSt6vectorIdSaIdEERS6_RKS4_INS_13VectorGenericILj3EEESaISB_EES9_RS4_ISD_SaISD_EERS4_INS_13TensorGenericILj3ELj3EEESaISK_EEPKNS_15ActionAtomisticE4029
_ZN4PLMD6colvar6Dipole13parseAtomListERKiRSt6vectorINS_10AtomNumberESaIS5_EEPNS_15ActionAtomisticE576
_ZN4PLMD6colvar6Dipole16registerKeywordsERNS_8KeywordsE131
_ZN4PLMD6colvar6Dipole21getModeAndSetupValuesEPNS_15ActionWithValueE61
_ZN4PLMD6colvar6Dipole9calculateEv943
_ZN4PLMD6colvar6DipoleC1ERKNS_13ActionOptionsE58
_ZN4PLMD6colvar6DipoleC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Dipole.cpp.gcov.html b/coverage/colvar/Dipole.cpp.gcov.html new file mode 100644 index 000000000000..83c5b819db48 --- /dev/null +++ b/coverage/colvar/Dipole.cpp.gcov.html @@ -0,0 +1,301 @@ + + + + + + + + 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:838498.8 %
Date:2024-04-19 12:12:35Functions: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 "ColvarShortcut.h"
+      24             : #include "MultiColvarTemplate.h"
+      25             : #include "core/ActionRegister.h"
+      26             : 
+      27             : namespace PLMD {
+      28             : namespace colvar {
+      29             : 
+      30             : //+PLUMEDOC COLVAR DIPOLE
+      31             : /*
+      32             : Calculate the dipole moment for a group of atoms.
+      33             : 
+      34             : When running with periodic boundary conditions, the atoms should be
+      35             : in the proper periodic image. This is done automatically since PLUMED 2.5,
+      36             : by considering the ordered list of atoms and rebuilding the molecule with a procedure
+      37             : that is equivalent to that done in \ref WHOLEMOLECULES . Notice that
+      38             : rebuilding is local to this action. This is different from \ref WHOLEMOLECULES
+      39             : which actually modifies the coordinates stored in PLUMED.
+      40             : 
+      41             : In case you want to recover the old behavior you should use the NOPBC flag.
+      42             : In that case you need to take care that atoms are in the correct
+      43             : periodic image.
+      44             : 
+      45             : \par Examples
+      46             : 
+      47             : The following tells plumed to calculate the dipole of the group of atoms containing
+      48             : the atoms from 1-10 and print it every 5 steps
+      49             : \plumedfile
+      50             : d: DIPOLE GROUP=1-10
+      51             : PRINT FILE=output STRIDE=5 ARG=d
+      52             : \endplumedfile
+      53             : 
+      54             : \attention
+      55             : If the total charge Q of the group in non zero, then a charge Q/N will be subtracted to every atom,
+      56             : where N is the number of atoms. This implies that the dipole (which for a charged system depends
+      57             : on the position) is computed on the geometric center of the group.
+      58             : 
+      59             : 
+      60             : */
+      61             : //+ENDPLUMEDOC
+      62             : 
+      63             : //+PLUMEDOC COLVAR DIPOLE_SCALAR
+      64             : /*
+      65             : Calculate the dipole moment for a group of atoms.
+      66             : 
+      67             : \par Examples
+      68             : 
+      69             : */
+      70             : //+ENDPLUMEDOC
+      71             : 
+      72             : //+PLUMEDOC MCOLVAR DIPOLE_VECTOR
+      73             : /*
+      74             : Calculate a vector of dipole moments for a set of groups of atoms.
+      75             : 
+      76             : \par Examples
+      77             : 
+      78             : */
+      79             : //+ENDPLUMEDOC
+      80             : 
+      81             : class Dipole : public Colvar {
+      82             :   std::vector<AtomNumber> ga_lista;
+      83             :   bool components;
+      84             :   bool nopbc;
+      85             :   std::vector<double> value, masses, charges;
+      86             :   std::vector<std::vector<Vector> > derivs;
+      87             :   std::vector<Tensor> virial;
+      88             :   Value* valuex=nullptr;
+      89             :   Value* valuey=nullptr;
+      90             :   Value* valuez=nullptr;
+      91             : public:
+      92             :   explicit Dipole(const ActionOptions&);
+      93             :   static void parseAtomList( const int& num, std::vector<AtomNumber>& t, ActionAtomistic* aa );
+      94             :   static unsigned getModeAndSetupValues( ActionWithValue* av );
+      95             :   void calculate() override;
+      96             :   static void registerKeywords(Keywords& keys);
+      97             :   static void calculateCV( const unsigned& mode, const std::vector<double>& masses, std::vector<double>& charges,
+      98             :                            const std::vector<Vector>& pos, std::vector<double>& vals, std::vector<std::vector<Vector> >& derivs,
+      99             :                            std::vector<Tensor>& virial, const ActionAtomistic* aa );
+     100             : };
+     101             : 
+     102             : typedef ColvarShortcut<Dipole> DipoleShortcut;
+     103             : PLUMED_REGISTER_ACTION(DipoleShortcut,"DIPOLE")
+     104             : PLUMED_REGISTER_ACTION(Dipole,"DIPOLE_SCALAR")
+     105             : typedef MultiColvarTemplate<Dipole> DipoleMulti;
+     106             : PLUMED_REGISTER_ACTION(DipoleMulti,"DIPOLE_VECTOR")
+     107             : 
+     108         131 : void Dipole::registerKeywords(Keywords& keys) {
+     109         131 :   Colvar::registerKeywords(keys);
+     110         262 :   keys.add("atoms","GROUP","the group of atoms we are calculating the dipole moment for");
+     111         262 :   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");
+     112         262 :   keys.addOutputComponent("x","COMPONENTS","the x-component of the dipole");
+     113         262 :   keys.addOutputComponent("y","COMPONENTS","the y-component of the dipole");
+     114         262 :   keys.addOutputComponent("z","COMPONENTS","the z-component of the dipole");
+     115         262 :   keys.add("hidden","NO_ACTION_LOG","suppresses printing from action on the log");
+     116         131 : }
+     117             : 
+     118          58 : Dipole::Dipole(const ActionOptions&ao):
+     119             :   PLUMED_COLVAR_INIT(ao),
+     120          58 :   components(false),
+     121          58 :   value(1),
+     122           0 :   derivs(1),
+     123          58 :   virial(1)
+     124             : {
+     125          58 :   parseAtomList(-1,ga_lista,this); charges.resize(ga_lista.size());
+     126          58 :   components=(getModeAndSetupValues(this)==1);
+     127          58 :   if( components ) {
+     128           4 :     value.resize(3); derivs.resize(3); virial.resize(3);
+     129           4 :     valuex=getPntrToComponent("x");
+     130           4 :     valuey=getPntrToComponent("y");
+     131           4 :     valuez=getPntrToComponent("z");
+     132             :   }
+     133         124 :   for(unsigned i=0; i<derivs.size(); ++i) derivs[i].resize( ga_lista.size() );
+     134          58 :   parseFlag("NOPBC",nopbc);
+     135          58 :   checkRead();
+     136             : 
+     137          58 :   if(nopbc) log.printf("  without periodic boundary conditions\n");
+     138          20 :   else      log.printf("  using periodic boundary conditions\n");
+     139             : 
+     140          58 :   requestAtoms(ga_lista);
+     141          58 : }
+     142             : 
+     143         576 : void Dipole::parseAtomList( const int& num, std::vector<AtomNumber>& t, ActionAtomistic* aa ) {
+     144        1152 :   aa->parseAtomList("GROUP",num,t);
+     145         576 :   if( t.size()>0 ) {
+     146         573 :     aa->log.printf("  of %u atoms\n",static_cast<unsigned>(t.size()));
+     147        2479 :     for(unsigned int i=0; i<t.size(); ++i) {
+     148        1906 :       aa->log.printf("  %d", t[i].serial());
+     149             :     }
+     150         573 :     aa->log.printf("  \n");
+     151             :   }
+     152         576 : }
+     153             : 
+     154          61 : unsigned Dipole::getModeAndSetupValues( ActionWithValue* av ) {
+     155          61 :   bool c; av->parseFlag("COMPONENTS",c);
+     156          61 :   if( c ) {
+     157          12 :     av->addComponentWithDerivatives("x"); av->componentIsNotPeriodic("x");
+     158          12 :     av->addComponentWithDerivatives("y"); av->componentIsNotPeriodic("y");
+     159          12 :     av->addComponentWithDerivatives("z"); av->componentIsNotPeriodic("z");
+     160           6 :     return 1;
+     161             :   }
+     162         110 :   av->addValueWithDerivatives(); av->setNotPeriodic(); return 0;
+     163             : }
+     164             : 
+     165             : // calculator
+     166         943 : void Dipole::calculate()
+     167             : {
+     168         943 :   if(!nopbc) makeWhole();
+     169             :   unsigned N=getNumberOfAtoms();
+     170        7398 :   for(unsigned i=0; i<N; ++i) charges[i]=getCharge(i);
+     171             : 
+     172         943 :   if(!components) {
+     173         788 :     calculateCV( 0, masses, charges, getPositions(), value, derivs, virial, this );
+     174        6313 :     for(unsigned i=0; i<N; i++) setAtomsDerivatives(i,derivs[0][i]);
+     175         788 :     setBoxDerivatives(virial[0]);
+     176         788 :     setValue(value[0]);
+     177             :   } else {
+     178         155 :     calculateCV( 1, masses, charges, getPositions(), value, derivs, virial, this );
+     179        1085 :     for(unsigned i=0; i<N; i++) {
+     180         930 :       setAtomsDerivatives(valuex,i,derivs[0][i]);
+     181         930 :       setAtomsDerivatives(valuey,i,derivs[1][i]);
+     182         930 :       setAtomsDerivatives(valuez,i,derivs[2][i]);
+     183             :     }
+     184         155 :     setBoxDerivatives(valuex,virial[0]);
+     185         155 :     setBoxDerivatives(valuey,virial[1]);
+     186         155 :     setBoxDerivatives(valuez,virial[2]);
+     187         155 :     valuex->set(value[0]);
+     188         155 :     valuey->set(value[1]);
+     189         155 :     valuez->set(value[2]);
+     190             :   }
+     191         943 : }
+     192             : 
+     193        4029 : void Dipole::calculateCV( const unsigned& mode, const std::vector<double>& masses, std::vector<double>& charges,
+     194             :                           const std::vector<Vector>& pos, std::vector<double>& vals, std::vector<std::vector<Vector> >& derivs,
+     195             :                           std::vector<Tensor>& virial, const ActionAtomistic* aa ) {
+     196        4029 :   unsigned N=pos.size(); double ctot=0.;
+     197       19802 :   for(unsigned i=0; i<N; ++i) ctot += charges[i];
+     198        4029 :   ctot/=(double)N;
+     199             : 
+     200        4029 :   Vector dipje;
+     201       19802 :   for(unsigned i=0; i<N; ++i) {
+     202       15773 :     charges[i]-=ctot; dipje += charges[i]*pos[i];
+     203             :   }
+     204             : 
+     205        4029 :   if( mode==1 ) {
+     206       13419 :     for(unsigned i=0; i<N; i++) {
+     207       10188 :       derivs[0][i]=charges[i]*Vector(1.0,0.0,0.0);
+     208       10188 :       derivs[1][i]=charges[i]*Vector(0.0,1.0,0.0);
+     209       10188 :       derivs[2][i]=charges[i]*Vector(0.0,0.0,1.0);
+     210             :     }
+     211       12924 :     for(unsigned i=0; i<3; ++i ) vals[i] = dipje[i];
+     212             :   } else {
+     213         798 :     vals[0] = dipje.modulo();
+     214         798 :     double idip = 1./vals[0];
+     215        6383 :     for(unsigned i=0; i<N; i++) {
+     216        5585 :       double dfunc=charges[i]*idip;
+     217        5585 :       derivs[0][i] = dfunc*dipje;
+     218             :     }
+     219             :   }
+     220        4029 :   setBoxDerivativesNoPbc( pos, derivs, virial );
+     221        4029 : }
+     222             : 
+     223             : }
+     224             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Distance.cpp.func-sort-c.html b/coverage/colvar/Distance.cpp.func-sort-c.html new file mode 100644 index 000000000000..278473164bf6 --- /dev/null +++ b/coverage/colvar/Distance.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - colvar/Distance.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Distance.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:119119100.0 %
Date:2024-04-19 12:12:35Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar8DistanceC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar8DistanceC1ERKNS_13ActionOptionsE595
_ZN4PLMD6colvar8Distance21getModeAndSetupValuesEPNS_15ActionWithValueE698
_ZN4PLMD6colvar8Distance16registerKeywordsERNS_8KeywordsE1423
_ZN4PLMD6colvar8Distance13parseAtomListERKiRSt6vectorINS_10AtomNumberESaIS5_EEPNS_15ActionAtomisticE25716
_ZN4PLMD6colvar8Distance9calculateEv74389
_ZN4PLMD6colvar8Distance11calculateCVERKjRKSt6vectorIdSaIdEES8_RKS4_INS_13VectorGenericILj3EEESaISA_EERS6_RS4_ISC_SaISC_EERS4_INS_13TensorGenericILj3ELj3EEESaISK_EEPKNS_15ActionAtomisticE406082
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Distance.cpp.func.html b/coverage/colvar/Distance.cpp.func.html new file mode 100644 index 000000000000..fc5904c29689 --- /dev/null +++ b/coverage/colvar/Distance.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - colvar/Distance.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Distance.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:119119100.0 %
Date:2024-04-19 12:12:35Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar8Distance11calculateCVERKjRKSt6vectorIdSaIdEES8_RKS4_INS_13VectorGenericILj3EEESaISA_EERS6_RS4_ISC_SaISC_EERS4_INS_13TensorGenericILj3ELj3EEESaISK_EEPKNS_15ActionAtomisticE406082
_ZN4PLMD6colvar8Distance13parseAtomListERKiRSt6vectorINS_10AtomNumberESaIS5_EEPNS_15ActionAtomisticE25716
_ZN4PLMD6colvar8Distance16registerKeywordsERNS_8KeywordsE1423
_ZN4PLMD6colvar8Distance21getModeAndSetupValuesEPNS_15ActionWithValueE698
_ZN4PLMD6colvar8Distance9calculateEv74389
_ZN4PLMD6colvar8DistanceC1ERKNS_13ActionOptionsE595
_ZN4PLMD6colvar8DistanceC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Distance.cpp.gcov.html b/coverage/colvar/Distance.cpp.gcov.html new file mode 100644 index 000000000000..a9f79379aed7 --- /dev/null +++ b/coverage/colvar/Distance.cpp.gcov.html @@ -0,0 +1,385 @@ + + + + + + + + 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:119119100.0 %
Date:2024-04-19 12:12:35Functions: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 "ColvarShortcut.h"
+      24             : #include "MultiColvarTemplate.h"
+      25             : #include "core/ActionRegister.h"
+      26             : #include "tools/Pbc.h"
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace colvar {
+      30             : 
+      31             : //+PLUMEDOC COLVAR DISTANCE
+      32             : /*
+      33             : Calculate the distance between a pair of atoms.
+      34             : 
+      35             : By default the distance is computed taking into account periodic
+      36             : boundary conditions. This behavior can be changed with the NOPBC flag.
+      37             : Moreover, single components in Cartesian space (x,y, and z, with COMPONENTS)
+      38             : or single components projected to the three lattice vectors (a,b, and c, with SCALED_COMPONENTS)
+      39             : can be also computed.
+      40             : 
+      41             : Notice that Cartesian components will not have the proper periodicity!
+      42             : If you have to study e.g. the permeation of a molecule across a membrane,
+      43             : better to use SCALED_COMPONENTS.
+      44             : 
+      45             : \par Examples
+      46             : 
+      47             : The following input tells plumed to print the distance between atoms 3 and 5,
+      48             : the distance between atoms 2 and 4 and the x component of the distance between atoms 2 and 4.
+      49             : \plumedfile
+      50             : d1:  DISTANCE ATOMS=3,5
+      51             : d2:  DISTANCE ATOMS=2,4
+      52             : d2c: DISTANCE ATOMS=2,4 COMPONENTS
+      53             : PRINT ARG=d1,d2,d2c.x
+      54             : \endplumedfile
+      55             : 
+      56             : The following input computes the end-to-end distance for a polymer
+      57             : of 100 atoms and keeps it at a value around 5.
+      58             : \plumedfile
+      59             : WHOLEMOLECULES ENTITY0=1-100
+      60             : e2e: DISTANCE ATOMS=1,100 NOPBC
+      61             : RESTRAINT ARG=e2e KAPPA=1 AT=5
+      62             : \endplumedfile
+      63             : 
+      64             : Notice that NOPBC is used
+      65             : to be sure that if the end-to-end distance is larger than half the simulation
+      66             : box the distance is compute properly. Also notice that, since many MD
+      67             : codes break molecules across cell boundary, it might be necessary to
+      68             : use the \ref WHOLEMOLECULES keyword (also notice that it should be
+      69             : _before_ distance). The list of atoms provided to \ref WHOLEMOLECULES
+      70             : here contains all the atoms between 1 and 100. Strictly speaking, this
+      71             : is not necessary. If you know for sure that atoms with difference in
+      72             : the index say equal to 10 are _not_ going to be farther than half cell
+      73             : you can e.g. use
+      74             : \plumedfile
+      75             : WHOLEMOLECULES ENTITY0=1,10,20,30,40,50,60,70,80,90,100
+      76             : e2e: DISTANCE ATOMS=1,100 NOPBC
+      77             : RESTRAINT ARG=e2e KAPPA=1 AT=5
+      78             : \endplumedfile
+      79             : Just be sure that the ordered list provide to \ref WHOLEMOLECULES has the following
+      80             : properties:
+      81             : - Consecutive atoms should be closer than half-cell throughout the entire simulation.
+      82             : - Atoms required later for the distance (e.g. 1 and 100) should be included in the list
+      83             : 
+      84             : The following example shows how to take into account periodicity e.g.
+      85             : in z-component of a distance
+      86             : \plumedfile
+      87             : # this is a center of mass of a large group
+      88             : c: COM ATOMS=1-100
+      89             : # this is the distance between atom 101 and the group
+      90             : d: DISTANCE ATOMS=c,101 COMPONENTS
+      91             : # this makes a new variable, dd, equal to d and periodic, with domain -10,10
+      92             : # this is the right choise if e.g. the cell is orthorombic and its size in
+      93             : # z direction is 20.
+      94             : dz: COMBINE ARG=d.z PERIODIC=-10,10
+      95             : # metadynamics on dd
+      96             : METAD ARG=dz SIGMA=0.1 HEIGHT=0.1 PACE=200
+      97             : \endplumedfile
+      98             : 
+      99             : Using SCALED_COMPONENTS this problem should not arise because they are always periodic
+     100             : with domain (-0.5,+0.5).
+     101             : 
+     102             : 
+     103             : 
+     104             : 
+     105             : */
+     106             : //+ENDPLUMEDOC
+     107             : 
+     108             : //+PLUMEDOC MCOLVAR DISTANCE_SCALAR
+     109             : /*
+     110             : Calculate the distance between a pair of atoms
+     111             : 
+     112             : \par Examples
+     113             : 
+     114             : */
+     115             : //+ENDPLUMEDOC
+     116             : 
+     117             : //+PLUMEDOC MCOLVAR DISTANCE_VECTOR
+     118             : /*
+     119             : Calculate a vector containing the distances between various pairs of atoms
+     120             : 
+     121             : \par Examples
+     122             : 
+     123             : */
+     124             : //+ENDPLUMEDOC
+     125             : 
+     126             : class Distance : public Colvar {
+     127             :   bool components;
+     128             :   bool scaled_components;
+     129             :   bool pbc;
+     130             : 
+     131             :   std::vector<double> value, masses, charges;
+     132             :   std::vector<std::vector<Vector> > derivs;
+     133             :   std::vector<Tensor> virial;
+     134             : public:
+     135             :   static void registerKeywords( Keywords& keys );
+     136             :   explicit Distance(const ActionOptions&);
+     137             :   static void parseAtomList( const int& num, std::vector<AtomNumber>& t, ActionAtomistic* aa );
+     138             :   static unsigned getModeAndSetupValues( ActionWithValue* av );
+     139             : // active methods:
+     140             :   void calculate() override;
+     141             :   static void calculateCV( const unsigned& mode, const std::vector<double>& masses, const std::vector<double>& charges,
+     142             :                            const std::vector<Vector>& pos, std::vector<double>& vals, std::vector<std::vector<Vector> >& derivs,
+     143             :                            std::vector<Tensor>& virial, const ActionAtomistic* aa );
+     144             : };
+     145             : 
+     146             : typedef ColvarShortcut<Distance> DistanceShortcut;
+     147             : PLUMED_REGISTER_ACTION(DistanceShortcut,"DISTANCE")
+     148             : PLUMED_REGISTER_ACTION(Distance,"DISTANCE_SCALAR")
+     149             : typedef MultiColvarTemplate<Distance> DistanceMulti;
+     150             : PLUMED_REGISTER_ACTION(DistanceMulti,"DISTANCE_VECTOR")
+     151             : 
+     152        1423 : void Distance::registerKeywords( Keywords& keys ) {
+     153        1423 :   Colvar::registerKeywords( keys );
+     154        2846 :   keys.add("atoms","ATOMS","the pair of atom that we are calculating the distance between");
+     155        2846 :   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");
+     156        2846 :   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");
+     157        2846 :   keys.addOutputComponent("x","COMPONENTS","the x-component of the vector connecting the two atoms");
+     158        2846 :   keys.addOutputComponent("y","COMPONENTS","the y-component of the vector connecting the two atoms");
+     159        2846 :   keys.addOutputComponent("z","COMPONENTS","the z-component of the vector connecting the two atoms");
+     160        2846 :   keys.addOutputComponent("a","SCALED_COMPONENTS","the normalized projection on the first lattice vector of the vector connecting the two atoms");
+     161        2846 :   keys.addOutputComponent("b","SCALED_COMPONENTS","the normalized projection on the second lattice vector of the vector connecting the two atoms");
+     162        2846 :   keys.addOutputComponent("c","SCALED_COMPONENTS","the normalized projection on the third lattice vector of the vector connecting the two atoms");
+     163        2846 :   keys.add("hidden","NO_ACTION_LOG","suppresses printing from action on the log");
+     164        1423 : }
+     165             : 
+     166         595 : Distance::Distance(const ActionOptions&ao):
+     167             :   PLUMED_COLVAR_INIT(ao),
+     168         595 :   components(false),
+     169         595 :   scaled_components(false),
+     170         595 :   pbc(true),
+     171         595 :   value(1),
+     172         597 :   derivs(1),
+     173        1190 :   virial(1)
+     174             : {
+     175         595 :   derivs[0].resize(2);
+     176             :   std::vector<AtomNumber> atoms;
+     177         595 :   parseAtomList(-1,atoms,this);
+     178         595 :   if(atoms.size()!=2)
+     179           1 :     error("Number of specified atoms should be 2");
+     180             : 
+     181         594 :   bool nopbc=!pbc;
+     182         596 :   parseFlag("NOPBC",nopbc);
+     183         594 :   pbc=!nopbc;
+     184             : 
+     185         594 :   if(pbc) log.printf("  using periodic boundary conditions\n");
+     186           4 :   else    log.printf("  without periodic boundary conditions\n");
+     187             : 
+     188         594 :   unsigned mode = getModeAndSetupValues( this );
+     189         593 :   if(mode==1) components=true; else if(mode==2) scaled_components=true;
+     190         593 :   if( components || scaled_components ) {
+     191          40 :     value.resize(3); derivs.resize(3); virial.resize(3);
+     192         160 :     for(unsigned i=0; i<3; ++i) derivs[i].resize(2);
+     193             :   }
+     194         593 :   requestAtoms(atoms);
+     195         599 : }
+     196             : 
+     197       25716 : void Distance::parseAtomList( const int& num, std::vector<AtomNumber>& t, ActionAtomistic* aa ) {
+     198       51432 :   aa->parseAtomList("ATOMS",num,t);
+     199       25716 :   if( t.size()==2 ) aa->log.printf("  between atoms %d %d\n",t[0].serial(),t[1].serial());
+     200       25716 : }
+     201             : 
+     202         698 : unsigned Distance::getModeAndSetupValues( ActionWithValue* av ) {
+     203         698 :   bool c; av->parseFlag("COMPONENTS",c);
+     204         698 :   bool sc; av->parseFlag("SCALED_COMPONENTS",sc);
+     205         698 :   if( c && sc ) av->error("COMPONENTS and SCALED_COMPONENTS are not compatible");
+     206             : 
+     207         697 :   if(c) {
+     208         158 :     av->addComponentWithDerivatives("x"); av->componentIsNotPeriodic("x");
+     209         158 :     av->addComponentWithDerivatives("y"); av->componentIsNotPeriodic("y");
+     210         158 :     av->addComponentWithDerivatives("z"); av->componentIsNotPeriodic("z");
+     211          79 :     av->log<<"  WARNING: components will not have the proper periodicity - see manual\n";
+     212          79 :     return 1;
+     213         618 :   } else if(sc) {
+     214          18 :     av->addComponentWithDerivatives("a"); av->componentIsPeriodic("a","-0.5","+0.5");
+     215          18 :     av->addComponentWithDerivatives("b"); av->componentIsPeriodic("b","-0.5","+0.5");
+     216          18 :     av->addComponentWithDerivatives("c"); av->componentIsPeriodic("c","-0.5","+0.5");
+     217           6 :     return 2;
+     218             :   }
+     219        1224 :   av->addValueWithDerivatives(); av->setNotPeriodic();
+     220             :   return 0;
+     221             : }
+     222             : 
+     223             : // calculator
+     224       74389 : void Distance::calculate() {
+     225             : 
+     226       74389 :   if(pbc) makeWhole();
+     227             : 
+     228       74389 :   if( components ) {
+     229         409 :     calculateCV( 1, masses, charges, getPositions(), value, derivs, virial, this );
+     230         409 :     Value* valuex=getPntrToComponent("x");
+     231         409 :     Value* valuey=getPntrToComponent("y");
+     232         409 :     Value* valuez=getPntrToComponent("z");
+     233             : 
+     234        1227 :     for(unsigned i=0; i<2; ++i) setAtomsDerivatives(valuex,i,derivs[0][i] );
+     235         409 :     setBoxDerivatives(valuex,virial[0]);
+     236         409 :     valuex->set(value[0]);
+     237             : 
+     238        1227 :     for(unsigned i=0; i<2; ++i) setAtomsDerivatives(valuey,i,derivs[1][i] );
+     239         409 :     setBoxDerivatives(valuey,virial[1]);
+     240         409 :     valuey->set(value[1]);
+     241             : 
+     242        1227 :     for(unsigned i=0; i<2; ++i) setAtomsDerivatives(valuez,i,derivs[2][i] );
+     243         409 :     setBoxDerivatives(valuez,virial[2]);
+     244         409 :     valuez->set(value[2]);
+     245       73980 :   } else if( scaled_components ) {
+     246          26 :     calculateCV( 2, masses, charges, getPositions(), value, derivs, virial, this );
+     247             : 
+     248          26 :     Value* valuea=getPntrToComponent("a");
+     249          26 :     Value* valueb=getPntrToComponent("b");
+     250          26 :     Value* valuec=getPntrToComponent("c");
+     251          78 :     for(unsigned i=0; i<2; ++i) setAtomsDerivatives(valuea,i,derivs[0][i] );
+     252          26 :     valuea->set(value[0]);
+     253          78 :     for(unsigned i=0; i<2; ++i) setAtomsDerivatives(valueb,i,derivs[1][i] );
+     254          26 :     valueb->set(value[1]);
+     255          78 :     for(unsigned i=0; i<2; ++i) setAtomsDerivatives(valuec,i,derivs[2][i] );
+     256          26 :     valuec->set(value[2]);
+     257             :   } else  {
+     258       73954 :     calculateCV( 0, masses, charges, getPositions(), value, derivs, virial, this );
+     259      221862 :     for(unsigned i=0; i<2; ++i) setAtomsDerivatives(i,derivs[0][i] );
+     260       73954 :     setBoxDerivatives(virial[0]);
+     261       73954 :     setValue           (value[0]);
+     262             :   }
+     263       74389 : }
+     264             : 
+     265      406082 : void Distance::calculateCV( const unsigned& mode, const std::vector<double>& masses, const std::vector<double>& charges,
+     266             :                             const std::vector<Vector>& pos, std::vector<double>& vals, std::vector<std::vector<Vector> >& derivs,
+     267             :                             std::vector<Tensor>& virial, const ActionAtomistic* aa ) {
+     268      406082 :   Vector distance=delta(pos[0],pos[1]);
+     269      406082 :   const double value=distance.modulo();
+     270      406082 :   const double invvalue=1.0/value;
+     271             : 
+     272      406082 :   if(mode==1) {
+     273       94377 :     derivs[0][0] = Vector(-1,0,0);
+     274       94377 :     derivs[0][1] = Vector(+1,0,0);
+     275       94377 :     vals[0] = distance[0];
+     276             : 
+     277       94377 :     derivs[1][0] = Vector(0,-1,0);
+     278       94377 :     derivs[1][1] = Vector(0,+1,0);
+     279       94377 :     vals[1] = distance[1];
+     280             : 
+     281       94377 :     derivs[2][0] = Vector(0,0,-1);
+     282       94377 :     derivs[2][1] = Vector(0,0,+1);
+     283       94377 :     vals[2] = distance[2];
+     284       94377 :     setBoxDerivativesNoPbc( pos, derivs, virial );
+     285      311705 :   } else if(mode==2) {
+     286          41 :     Vector d=aa->getPbc().realToScaled(distance);
+     287          41 :     derivs[0][0] = matmul(aa->getPbc().getInvBox(),Vector(-1,0,0));
+     288          41 :     derivs[0][1] = matmul(aa->getPbc().getInvBox(),Vector(+1,0,0));
+     289          41 :     vals[0] = Tools::pbc(d[0]);
+     290          41 :     derivs[1][0] = matmul(aa->getPbc().getInvBox(),Vector(0,-1,0));
+     291          41 :     derivs[1][1] = matmul(aa->getPbc().getInvBox(),Vector(0,+1,0));
+     292          41 :     vals[1] = Tools::pbc(d[1]);
+     293          41 :     derivs[2][0] = matmul(aa->getPbc().getInvBox(),Vector(0,0,-1));
+     294          41 :     derivs[2][1] = matmul(aa->getPbc().getInvBox(),Vector(0,0,+1));
+     295          41 :     vals[2] = Tools::pbc(d[2]);
+     296             :   } else {
+     297      311664 :     derivs[0][0] = -invvalue*distance;
+     298      311664 :     derivs[0][1] = invvalue*distance;
+     299      311664 :     setBoxDerivativesNoPbc( pos, derivs, virial );
+     300      311664 :     vals[0] = value;
+     301             :   }
+     302      406082 : }
+     303             : 
+     304             : }
+     305             : }
+     306             : 
+     307             : 
+     308             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/EEFSolv.cpp.func-sort-c.html b/coverage/colvar/EEFSolv.cpp.func-sort-c.html new file mode 100644 index 000000000000..788664c36566 --- /dev/null +++ b/coverage/colvar/EEFSolv.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - colvar/EEFSolv.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - EEFSolv.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22924394.2 %
Date:2024-04-19 12:12:35Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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

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

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

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

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

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

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

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

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

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar7ExtraCV16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD6colvar7ExtraCVC1ERKNS_13ActionOptionsE3
_ZN4PLMD6colvar7ExtraCVC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/ExtraCV.cpp.gcov.html b/coverage/colvar/ExtraCV.cpp.gcov.html new file mode 100644 index 000000000000..34fdd1997e53 --- /dev/null +++ b/coverage/colvar/ExtraCV.cpp.gcov.html @@ -0,0 +1,156 @@ + + + + + + + + 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:1111100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ + + + + + + + +

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

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

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

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

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

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

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

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

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

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar16GyrationShortcutC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar16GyrationShortcutC1ERKNS_13ActionOptionsE37
_ZN4PLMD6colvar16GyrationShortcut16registerKeywordsERNS_8KeywordsE43
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/GyrationShortcut.cpp.func.html b/coverage/colvar/GyrationShortcut.cpp.func.html new file mode 100644 index 000000000000..08e800dcf9cd --- /dev/null +++ b/coverage/colvar/GyrationShortcut.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - colvar/GyrationShortcut.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - GyrationShortcut.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:509154.9 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar16GyrationShortcut16registerKeywordsERNS_8KeywordsE43
_ZN4PLMD6colvar16GyrationShortcutC1ERKNS_13ActionOptionsE37
_ZN4PLMD6colvar16GyrationShortcutC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/GyrationShortcut.cpp.gcov.html b/coverage/colvar/GyrationShortcut.cpp.gcov.html new file mode 100644 index 000000000000..4e6eb69fc267 --- /dev/null +++ b/coverage/colvar/GyrationShortcut.cpp.gcov.html @@ -0,0 +1,259 @@ + + + + + + + + LCOV - plumed test coverage - colvar/GyrationShortcut.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - GyrationShortcut.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:509154.9 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2020 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             :    See http://www.plumed.org for more information.
+       5             :    This file is part of plumed, version 2.
+       6             :    plumed 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             :    plumed 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             :    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 "core/ActionRegister.h"
+      18             : #include "core/PlumedMain.h"
+      19             : #include "core/ActionSet.h"
+      20             : #include "core/ActionWithValue.h"
+      21             : #include "core/ActionShortcut.h"
+      22             : 
+      23             : namespace PLMD {
+      24             : namespace colvar {
+      25             : 
+      26             : //+PLUMEDOC COLVAR GYRATION
+      27             : /*
+      28             : Calculate the radius of gyration, or other properties related to it.
+      29             : 
+      30             : With this version of the command you can use any property you so choose to define the weights that are used when computing the average.
+      31             : If you use the mass or if all the atoms are ascribed weights of one PLUMED defaults to \ref GYRATION_FAST
+      32             : 
+      33             : \par Examples
+      34             : 
+      35             : */
+      36             : //+ENDPLUMEDOC
+      37             : 
+      38             : //+PLUMEDOC MCOLVAR GYRATION_TENSOR
+      39             : /*
+      40             : Calculate the gyration tensor using a user specified vector of weights
+      41             : 
+      42             : \par Examples
+      43             : 
+      44             : */
+      45             : //+ENDPLUMEDOC
+      46             : 
+      47             : class GyrationShortcut : public ActionShortcut {
+      48             : public:
+      49             :   static void registerKeywords( Keywords& keys );
+      50             :   explicit GyrationShortcut(const ActionOptions&);
+      51             : };
+      52             : 
+      53             : PLUMED_REGISTER_ACTION(GyrationShortcut,"GYRATION")
+      54             : PLUMED_REGISTER_ACTION(GyrationShortcut,"GYRATION_TENSOR")
+      55             : 
+      56          43 : void GyrationShortcut::registerKeywords( Keywords& keys ) {
+      57          43 :   ActionShortcut::registerKeywords( keys );
+      58          86 :   keys.add("atoms","ATOMS","the group of atoms that you are calculating the Gyration Tensor for");
+      59          86 :   keys.add("compulsory","TYPE","RADIUS","The type of calculation relative to the Gyration Tensor you want to perform");
+      60          86 :   keys.addFlag("NOPBC",false,"ignore the periodic boundary conditions when calculating distances");
+      61          86 :   keys.add("optional","WEIGHTS","what weights should be used when calculating the center.  If this keyword is not present the geometric center is computed. "
+      62             :            "If WEIGHTS=@Masses is used the center of mass is computed.  If WEIGHTS=@charges the center of charge is computed.  If "
+      63             :            "the label of an action is provided PLUMED assumes that that action calculates a list of symmetry functions that can be used "
+      64             :            "as weights. Lastly, an explicit list of numbers to use as weights can be provided");
+      65          86 :   keys.addFlag("PHASES",false,"use trigonometric phases when computing position of center of mass");
+      66          86 :   keys.addFlag("MASS",false,"calculate the center of mass");
+      67          86 :   keys.addFlag("MASS_WEIGHTED",false,"set the masses of all the atoms equal to one");
+      68          86 :   keys.addFlag("UNORMALIZED",false,"do not divide by the sum of the weights");
+      69         129 :   keys.addActionNameSuffix("_FAST"); keys.needsAction("CENTER"); keys.needsAction("CONSTANT");
+      70         129 :   keys.needsAction("ONES"); keys.needsAction("MASS"); keys.needsAction("DISTANCE");
+      71          86 :   keys.needsAction("COVARIANCE_MATRIX"); keys.needsAction("SELECT_COMPONENTS");
+      72         129 :   keys.needsAction("SUM"); keys.needsAction("CUSTOM"); keys.needsAction("DIAGONALIZE");
+      73          43 : }
+      74             : 
+      75          37 : GyrationShortcut::GyrationShortcut(const ActionOptions& ao):
+      76             :   Action(ao),
+      77          37 :   ActionShortcut(ao)
+      78             : {
+      79         111 :   bool usemass, phases; parseFlag("MASS",usemass); parseFlag("PHASES",phases);
+      80          74 :   std::vector<std::string> str_weights; parseVector("WEIGHTS",str_weights); std::string wflab;
+      81          37 :   if( !phases ) {
+      82          36 :     if( usemass || str_weights.size()==0 || (str_weights.size()==1 && str_weights[0]=="@Masses") ) {
+      83             :       std::string wt_str;
+      84          33 :       if( str_weights.size()>0 ) {
+      85           0 :         wt_str="WEIGHTS=" + str_weights[0]; for(unsigned i=1; i<str_weights.size(); ++i) wt_str += "," + str_weights[i];
+      86             :       }
+      87          33 :       if( usemass || (str_weights.size()==1 && str_weights[0]=="@Masses") ) wt_str = "MASS";
+      88          74 :       readInputLine( getShortcutLabel() + ": GYRATION_FAST " + wt_str + " " + convertInputLineToString() );
+      89             :       return;
+      90             :     }
+      91             :   }
+      92           4 :   if( usemass ) { str_weights.resize(1); str_weights[0]="@Masses"; }
+      93          10 :   log<<"  Bibliography "<<plumed.cite("JiriÌ Vymetal and JiriÌ Vondrasek, J. Phys. Chem. A 115, 11455 (2011)")<<"\n";
+      94             :   // Read in the atoms involved
+      95           8 :   std::vector<std::string> atoms; parseVector("ATOMS",atoms); Tools::interpretRanges(atoms);
+      96          12 :   std::string gtype, atlist=atoms[0]; for(unsigned i=1; i<atoms.size(); ++i) atlist += "," + atoms[i];
+      97           8 :   bool nopbc; parseFlag("NOPBC",nopbc); std::string pbcstr; if(nopbc) pbcstr = " NOPBC";
+      98           4 :   std::string phasestr; if(phases) phasestr = " PHASES";
+      99             :   // Create the geometric center of the molecule
+     100           4 :   std::string weights_str=" WEIGHTS=" + str_weights[0];
+     101           8 :   for(unsigned i=1; i<str_weights.size(); ++i) weights_str += "," + str_weights[i];
+     102           8 :   readInputLine( getShortcutLabel() + "_cent: CENTER ATOMS=" + atlist + pbcstr + phasestr + weights_str );
+     103           4 :   if( str_weights.size()==0 ) {
+     104           0 :     wflab = getShortcutLabel() + "_w"; std::string str_natoms; Tools::convert( atoms.size(), str_natoms );
+     105           0 :     readInputLine( getShortcutLabel() + "_w: ONES SIZE=" + str_natoms );
+     106           6 :   } else if( str_weights.size()==1 && str_weights[0]=="@Masses" ) {
+     107           0 :     wflab = getShortcutLabel() + "_m";
+     108           0 :     readInputLine( getShortcutLabel() + "_m: MASS ATOMS=" + atlist );
+     109           4 :   } else if( str_weights.size()>1 ) {
+     110           6 :     std::string vals=str_weights[0]; for(unsigned i=1; i<str_weights.size(); ++i) vals += "," + str_weights[i];
+     111           6 :     readInputLine( getShortcutLabel() + "_w: CONSTANT VALUES=" + vals ); wflab=getShortcutLabel() + "_w";
+     112             :   } else {
+     113           2 :     plumed_assert( str_weights.size()==1 ); wflab = getShortcutLabel() + "_cent_w";
+     114           2 :     ActionWithValue* av=plumed.getActionSet().selectWithLabel<ActionWithValue*>( wflab );
+     115           2 :     if( !av ) { wflab = str_weights[0]; }
+     116             :   }
+     117             :   // Check for normalisation
+     118           8 :   bool unorm; parseFlag("UNORMALIZED",unorm);
+     119             :   // Find out the type
+     120           4 :   if( getName()!="GYRATION_TENSOR" ) {
+     121           0 :     parse("TYPE",gtype);
+     122           0 :     if( gtype!="RADIUS" && gtype!="TRACE" && gtype!="GTPC_1" && gtype!="GTPC_2" && gtype!="GTPC_3" && gtype!="ASPHERICITY" && gtype!="ACYLINDRICITY"
+     123           0 :         && gtype!= "KAPPA2" && gtype!="RGYR_1" && gtype!="RGYR_2" && gtype!="RGYR_3" ) error("type " + gtype + " is invalid");
+     124             :     // Check if we need to calculate the unormlised radius
+     125           0 :     if( gtype=="TRACE" || gtype=="KAPPA2" ) unorm=true;
+     126             :   }
+     127             :   // Compute all the vectors separating all the positions from the center
+     128           4 :   std::string distance_act = getShortcutLabel() + "_dists: DISTANCE COMPONENTS" + pbcstr;
+     129          28 :   for(unsigned i=0; i<atoms.size(); ++i) { std::string num; Tools::convert( i+1, num ); distance_act += " ATOMS" + num + "=" + getShortcutLabel() + "_cent," + atoms[i]; }
+     130           4 :   readInputLine( distance_act );
+     131             :   // And calculate the covariance
+     132           4 :   std::string norm_str; if( unorm ) norm_str = " UNORMALIZED";
+     133           4 :   if( getName()=="GYRATION_TENSOR" ) {
+     134           8 :     readInputLine( getShortcutLabel() + ": COVARIANCE_MATRIX ARG=" + getShortcutLabel() + "_dists.x," + getShortcutLabel() + "_dists.y," + getShortcutLabel() + "_dists.z WEIGHTS=" + wflab + norm_str );
+     135             :     return;
+     136             :   }
+     137           0 :   readInputLine( getShortcutLabel() + "_tensor: COVARIANCE_MATRIX ARG=" + getShortcutLabel() + "_dists.x," + getShortcutLabel() + "_dists.y," + getShortcutLabel() + "_dists.z WEIGHTS=" + wflab + norm_str );
+     138             :   // Pick out the diagonal elements
+     139           0 :   readInputLine( getShortcutLabel() + "_diag_elements: SELECT_COMPONENTS ARG=" + getShortcutLabel() + "_tensor COMPONENTS=1.1,2.2,3.3");
+     140           0 :   if( gtype=="RADIUS") {
+     141             :     // And now we need the average trace for the gyration radius
+     142           0 :     readInputLine( getShortcutLabel() + "_trace: SUM ARG=" + getShortcutLabel() + "_diag_elements PERIODIC=NO");
+     143             :     // Square root the radius
+     144           0 :     readInputLine( getShortcutLabel() + ": CUSTOM ARG=" + getShortcutLabel() + "_trace FUNC=sqrt(x) PERIODIC=NO");
+     145           0 :   } else if( gtype=="TRACE" ) {
+     146             :     // Compte the trace of the gyration tensor
+     147           0 :     readInputLine( getShortcutLabel() + "_trace: SUM ARG=" + getShortcutLabel() + "_diag_elements PERIODIC=NO");
+     148             :     // And double it
+     149           0 :     readInputLine( getShortcutLabel() + ": CUSTOM ARG=" + getShortcutLabel() + "_trace FUNC=2*x PERIODIC=NO");
+     150             :   } else {
+     151             :     // Diagonalize the gyration tensor
+     152           0 :     readInputLine( getShortcutLabel() + "_diag: DIAGONALIZE ARG=" + getShortcutLabel() + "_tensor VECTORS=all" );
+     153           0 :     if( gtype.find("GTPC")!=std::string::npos ) {
+     154           0 :       std::size_t und=gtype.find_first_of("_"); if( und==std::string::npos ) error( gtype + " is not a valid type for gyration radius");
+     155           0 :       std::string num = gtype.substr(und+1); if( num!="1" && num!="2" && num!="3" ) error( gtype + " is not a valid type for gyration radius");
+     156             :       // Now get the appropriate eigenvalue
+     157           0 :       readInputLine( getShortcutLabel() + ": CUSTOM ARG=" + getShortcutLabel() + "_diag.vals-" + num + " FUNC=sqrt(x) PERIODIC=NO");
+     158           0 :     } else if( gtype.find("RGYR")!=std::string::npos ) {
+     159           0 :       std::size_t und=gtype.find_first_of("_"); if( und==std::string::npos ) error( gtype + " is not a valid type for gyration radius");
+     160           0 :       unsigned ind; Tools::convert( gtype.substr(und+1), ind );
+     161             :       // Now get the appropriate quantity
+     162           0 :       if( ind==3 ) {
+     163           0 :         readInputLine( getShortcutLabel() + ": CUSTOM ARG=" + getShortcutLabel() + "_diag.vals-1," + getShortcutLabel() + "_diag.vals-2 FUNC=sqrt(x+y) PERIODIC=NO");
+     164           0 :       } else if( ind==2 ) {
+     165           0 :         readInputLine( getShortcutLabel() + ": CUSTOM ARG=" + getShortcutLabel() + "_diag.vals-1," + getShortcutLabel() + "_diag.vals-3 FUNC=sqrt(x+y) PERIODIC=NO");
+     166           0 :       } else if( ind==1 ) {
+     167           0 :         readInputLine( getShortcutLabel() + ": CUSTOM ARG=" + getShortcutLabel() + "_diag.vals-2," + getShortcutLabel() + "_diag.vals-3 FUNC=sqrt(x+y) PERIODIC=NO");
+     168           0 :       } else error( gtype + " is not a valid type for gyration radius");
+     169           0 :     } else if( gtype=="ASPHERICITY" ) {
+     170           0 :       readInputLine( getShortcutLabel() + ": CUSTOM ARG=" + getShortcutLabel() + "_diag.vals-1," + getShortcutLabel() + "_diag.vals-2," + getShortcutLabel() + "_diag.vals-3 FUNC=sqrt(x-0.5*(y+z)) PERIODIC=NO" );
+     171           0 :     } else if( gtype=="ACYLINDRICITY" ) {
+     172           0 :       readInputLine( getShortcutLabel() + ": CUSTOM ARG=" + getShortcutLabel() + "_diag.vals-2," + getShortcutLabel() + "_diag.vals-3 FUNC=sqrt(x-y) PERIODIC=NO" );
+     173           0 :     } else if( gtype=="KAPPA2" ) {
+     174           0 :       readInputLine( getShortcutLabel() + "_numer: CUSTOM ARG=" + getShortcutLabel() + "_diag.vals-1," + getShortcutLabel() + "_diag.vals-2," + getShortcutLabel() + "_diag.vals-3 FUNC=x*y+x*z+y*z PERIODIC=NO" );
+     175           0 :       readInputLine( getShortcutLabel() + "_denom: CUSTOM ARG=" + getShortcutLabel() + "_diag.vals-1," + getShortcutLabel() + "_diag.vals-2," + getShortcutLabel() + "_diag.vals-3 FUNC=x+y+z PERIODIC=NO" );
+     176           0 :       readInputLine( getShortcutLabel() + ": CUSTOM ARG=" + getShortcutLabel() + "_numer," + getShortcutLabel() + "_denom FUNC=1-3*(x/(y*y)) PERIODIC=NO");
+     177           0 :     } else error( gtype + " is not a valid type for gyration radius");
+     178             :   }
+     179          45 : }
+     180             : 
+     181             : }
+     182             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/MultiColvarTemplate.h.func-sort-c.html b/coverage/colvar/MultiColvarTemplate.h.func-sort-c.html new file mode 100644 index 000000000000..68e6074df252 --- /dev/null +++ b/coverage/colvar/MultiColvarTemplate.h.func-sort-c.html @@ -0,0 +1,361 @@ + + + + + + + + LCOV - plumed test coverage - colvar/MultiColvarTemplate.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - MultiColvarTemplate.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:919397.8 %
Date:2024-04-19 12:12:35Functions:657290.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar19MultiColvarTemplateINS0_16SelectMassChargeEE27addComponentWithDerivativesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIjSaIjEE0
_ZN4PLMD6colvar19MultiColvarTemplateINS0_19DihedralCorrelationEE27addComponentWithDerivativesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIjSaIjEE0
_ZN4PLMD6colvar19MultiColvarTemplateINS0_5AngleEE27addComponentWithDerivativesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIjSaIjEE0
_ZN4PLMD6colvar19MultiColvarTemplateINS0_5PlaneEE23addValueWithDerivativesERKSt6vectorIjSaIjEE0
_ZN4PLMD6colvar19MultiColvarTemplateINS0_7TorsionEE27addComponentWithDerivativesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIjSaIjEE0
_ZN4PLMD6colvar19MultiColvarTemplateINS0_8PositionEE23addValueWithDerivativesERKSt6vectorIjSaIjEE0
_ZN4PLMD6colvar19MultiColvarTemplateINS_12crystdistrib10QuaternionEE23addValueWithDerivativesERKSt6vectorIjSaIjEE0
_ZN4PLMD6colvar19MultiColvarTemplateINS0_19DihedralCorrelationEE23addValueWithDerivativesERKSt6vectorIjSaIjEE1
_ZN4PLMD6colvar19MultiColvarTemplateINS0_19DihedralCorrelationEEC1ERKNS_13ActionOptionsE1
_ZN4PLMD6colvar19MultiColvarTemplateINS0_5PlaneEEC1ERKNS_13ActionOptionsE1
_ZN4PLMD6colvar19MultiColvarTemplateINS0_6DipoleEE23addValueWithDerivativesERKSt6vectorIjSaIjEE1
_ZN4PLMD6colvar19MultiColvarTemplateINS0_5AngleEE22getNumberOfDerivativesEv2
_ZN4PLMD6colvar19MultiColvarTemplateINS0_19DihedralCorrelationEE16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD6colvar19MultiColvarTemplateINS0_19DihedralCorrelationEE22getNumberOfDerivativesEv3
_ZN4PLMD6colvar19MultiColvarTemplateINS0_5AngleEE23addValueWithDerivativesERKSt6vectorIjSaIjEE3
_ZN4PLMD6colvar19MultiColvarTemplateINS0_5AngleEEC1ERKNS_13ActionOptionsE3
_ZN4PLMD6colvar19MultiColvarTemplateINS0_5PlaneEE16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD6colvar19MultiColvarTemplateINS0_5PlaneEE27addComponentWithDerivativesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIjSaIjEE3
_ZN4PLMD6colvar19MultiColvarTemplateINS0_6DipoleEEC1ERKNS_13ActionOptionsE3
_ZN4PLMD6colvar19MultiColvarTemplateINS0_19DihedralCorrelationEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSC_SC_SC_5
_ZN4PLMD6colvar19MultiColvarTemplateINS0_19DihedralCorrelationEE9calculateEv5
_ZN4PLMD6colvar19MultiColvarTemplateINS0_5AngleEE16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD6colvar19MultiColvarTemplateINS0_6DipoleEE16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD6colvar19MultiColvarTemplateINS0_6DipoleEE22getNumberOfDerivativesEv6
_ZN4PLMD6colvar19MultiColvarTemplateINS0_6DipoleEE27addComponentWithDerivativesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIjSaIjEE6
_ZNK4PLMD6colvar19MultiColvarTemplateINS0_19DihedralCorrelationEE11performTaskERKjRNS_10MultiValueE10
_ZN4PLMD6colvar19MultiColvarTemplateINS0_5PlaneEE9calculateEv11
_ZN4PLMD6colvar19MultiColvarTemplateINS_12crystdistrib10QuaternionEEC1ERKNS_13ActionOptionsE12
_ZN4PLMD6colvar19MultiColvarTemplateINS0_7TorsionEE23addValueWithDerivativesERKSt6vectorIjSaIjEE14
_ZN4PLMD6colvar19MultiColvarTemplateINS0_7TorsionEEC1ERKNS_13ActionOptionsE14
_ZN4PLMD6colvar19MultiColvarTemplateINS_12crystdistrib10QuaternionEE16registerKeywordsERNS_8KeywordsE14
_ZN4PLMD6colvar19MultiColvarTemplateINS0_5AngleEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSC_SC_SC_15
_ZN4PLMD6colvar19MultiColvarTemplateINS0_5AngleEE9calculateEv15
_ZN4PLMD6colvar19MultiColvarTemplateINS0_6DipoleEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSC_SC_SC_16
_ZN4PLMD6colvar19MultiColvarTemplateINS0_6DipoleEE9calculateEv16
_ZN4PLMD6colvar19MultiColvarTemplateINS0_7TorsionEE16registerKeywordsERNS_8KeywordsE16
_ZN4PLMD6colvar19MultiColvarTemplateINS0_16SelectMassChargeEE23addValueWithDerivativesERKSt6vectorIjSaIjEE18
_ZN4PLMD6colvar19MultiColvarTemplateINS0_16SelectMassChargeEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSC_SC_SC_18
_ZN4PLMD6colvar19MultiColvarTemplateINS0_16SelectMassChargeEE9calculateEv18
_ZN4PLMD6colvar19MultiColvarTemplateINS0_16SelectMassChargeEEC1ERKNS_13ActionOptionsE18
_ZN4PLMD6colvar19MultiColvarTemplateINS0_16SelectMassChargeEE16registerKeywordsERNS_8KeywordsE22
_ZN4PLMD6colvar19MultiColvarTemplateINS0_5PlaneEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSC_SC_SC_22
_ZN4PLMD6colvar19MultiColvarTemplateINS0_16SelectMassChargeEE22getNumberOfDerivativesEv38
_ZN4PLMD6colvar19MultiColvarTemplateINS0_8PositionEEC1ERKNS_13ActionOptionsE41
_ZN4PLMD6colvar19MultiColvarTemplateINS0_8PositionEE16registerKeywordsERNS_8KeywordsE43
_ZN4PLMD6colvar19MultiColvarTemplateINS_12crystdistrib10QuaternionEE22getNumberOfDerivativesEv48
_ZN4PLMD6colvar19MultiColvarTemplateINS_12crystdistrib10QuaternionEE27addComponentWithDerivativesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIjSaIjEE48
_ZN4PLMD6colvar19MultiColvarTemplateINS_12crystdistrib10QuaternionEE9calculateEv54
_ZN4PLMD6colvar19MultiColvarTemplateINS0_8DistanceEE23addValueWithDerivativesERKSt6vectorIjSaIjEE59
_ZN4PLMD6colvar19MultiColvarTemplateINS0_7TorsionEE9calculateEv84
_ZN4PLMD6colvar19MultiColvarTemplateINS_12crystdistrib10QuaternionEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSD_SD_SD_84
_ZN4PLMD6colvar19MultiColvarTemplateINS0_8DistanceEEC1ERKNS_13ActionOptionsE104
_ZN4PLMD6colvar19MultiColvarTemplateINS0_5PlaneEE22getNumberOfDerivativesEv105
_ZN4PLMD6colvar19MultiColvarTemplateINS0_8DistanceEE16registerKeywordsERNS_8KeywordsE106
_ZN4PLMD6colvar19MultiColvarTemplateINS0_7TorsionEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSC_SC_SC_123
_ZN4PLMD6colvar19MultiColvarTemplateINS0_8PositionEE27addComponentWithDerivativesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIjSaIjEE123
_ZN4PLMD6colvar19MultiColvarTemplateINS0_7TorsionEE22getNumberOfDerivativesEv128
_ZN4PLMD6colvar19MultiColvarTemplateINS0_8DistanceEE27addComponentWithDerivativesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIjSaIjEE135
_ZNK4PLMD6colvar19MultiColvarTemplateINS0_5PlaneEE11performTaskERKjRNS_10MultiValueE176
_ZNK4PLMD6colvar19MultiColvarTemplateINS0_5AngleEE11performTaskERKjRNS_10MultiValueE235
_ZN4PLMD6colvar19MultiColvarTemplateINS0_8DistanceEE22getNumberOfDerivativesEv553
_ZN4PLMD6colvar19MultiColvarTemplateINS0_8PositionEE22getNumberOfDerivativesEv729
_ZNK4PLMD6colvar19MultiColvarTemplateINS0_7TorsionEE11performTaskERKjRNS_10MultiValueE779
_ZNK4PLMD6colvar19MultiColvarTemplateINS0_6DipoleEE11performTaskERKjRNS_10MultiValueE3086
_ZNK4PLMD6colvar19MultiColvarTemplateINS0_16SelectMassChargeEE11performTaskERKjRNS_10MultiValueE5144
_ZNK4PLMD6colvar19MultiColvarTemplateINS_12crystdistrib10QuaternionEE11performTaskERKjRNS_10MultiValueE5673
_ZN4PLMD6colvar19MultiColvarTemplateINS0_8PositionEE9calculateEv7229
_ZN4PLMD6colvar19MultiColvarTemplateINS0_8PositionEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSC_SC_SC_12212
_ZN4PLMD6colvar19MultiColvarTemplateINS0_8DistanceEE9calculateEv15253
_ZN4PLMD6colvar19MultiColvarTemplateINS0_8DistanceEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSC_SC_SC_15596
_ZNK4PLMD6colvar19MultiColvarTemplateINS0_8PositionEE11performTaskERKjRNS_10MultiValueE143344
_ZNK4PLMD6colvar19MultiColvarTemplateINS0_8DistanceEE11performTaskERKjRNS_10MultiValueE331693
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/MultiColvarTemplate.h.func.html b/coverage/colvar/MultiColvarTemplate.h.func.html new file mode 100644 index 000000000000..d72c38e23173 --- /dev/null +++ b/coverage/colvar/MultiColvarTemplate.h.func.html @@ -0,0 +1,361 @@ + + + + + + + + LCOV - plumed test coverage - colvar/MultiColvarTemplate.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - MultiColvarTemplate.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:919397.8 %
Date:2024-04-19 12:12:35Functions:657290.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar19MultiColvarTemplateINS0_16SelectMassChargeEE16registerKeywordsERNS_8KeywordsE22
_ZN4PLMD6colvar19MultiColvarTemplateINS0_16SelectMassChargeEE22getNumberOfDerivativesEv38
_ZN4PLMD6colvar19MultiColvarTemplateINS0_16SelectMassChargeEE23addValueWithDerivativesERKSt6vectorIjSaIjEE18
_ZN4PLMD6colvar19MultiColvarTemplateINS0_16SelectMassChargeEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSC_SC_SC_18
_ZN4PLMD6colvar19MultiColvarTemplateINS0_16SelectMassChargeEE27addComponentWithDerivativesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIjSaIjEE0
_ZN4PLMD6colvar19MultiColvarTemplateINS0_16SelectMassChargeEE9calculateEv18
_ZN4PLMD6colvar19MultiColvarTemplateINS0_16SelectMassChargeEEC1ERKNS_13ActionOptionsE18
_ZN4PLMD6colvar19MultiColvarTemplateINS0_19DihedralCorrelationEE16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD6colvar19MultiColvarTemplateINS0_19DihedralCorrelationEE22getNumberOfDerivativesEv3
_ZN4PLMD6colvar19MultiColvarTemplateINS0_19DihedralCorrelationEE23addValueWithDerivativesERKSt6vectorIjSaIjEE1
_ZN4PLMD6colvar19MultiColvarTemplateINS0_19DihedralCorrelationEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSC_SC_SC_5
_ZN4PLMD6colvar19MultiColvarTemplateINS0_19DihedralCorrelationEE27addComponentWithDerivativesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIjSaIjEE0
_ZN4PLMD6colvar19MultiColvarTemplateINS0_19DihedralCorrelationEE9calculateEv5
_ZN4PLMD6colvar19MultiColvarTemplateINS0_19DihedralCorrelationEEC1ERKNS_13ActionOptionsE1
_ZN4PLMD6colvar19MultiColvarTemplateINS0_5AngleEE16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD6colvar19MultiColvarTemplateINS0_5AngleEE22getNumberOfDerivativesEv2
_ZN4PLMD6colvar19MultiColvarTemplateINS0_5AngleEE23addValueWithDerivativesERKSt6vectorIjSaIjEE3
_ZN4PLMD6colvar19MultiColvarTemplateINS0_5AngleEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSC_SC_SC_15
_ZN4PLMD6colvar19MultiColvarTemplateINS0_5AngleEE27addComponentWithDerivativesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIjSaIjEE0
_ZN4PLMD6colvar19MultiColvarTemplateINS0_5AngleEE9calculateEv15
_ZN4PLMD6colvar19MultiColvarTemplateINS0_5AngleEEC1ERKNS_13ActionOptionsE3
_ZN4PLMD6colvar19MultiColvarTemplateINS0_5PlaneEE16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD6colvar19MultiColvarTemplateINS0_5PlaneEE22getNumberOfDerivativesEv105
_ZN4PLMD6colvar19MultiColvarTemplateINS0_5PlaneEE23addValueWithDerivativesERKSt6vectorIjSaIjEE0
_ZN4PLMD6colvar19MultiColvarTemplateINS0_5PlaneEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSC_SC_SC_22
_ZN4PLMD6colvar19MultiColvarTemplateINS0_5PlaneEE27addComponentWithDerivativesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIjSaIjEE3
_ZN4PLMD6colvar19MultiColvarTemplateINS0_5PlaneEE9calculateEv11
_ZN4PLMD6colvar19MultiColvarTemplateINS0_5PlaneEEC1ERKNS_13ActionOptionsE1
_ZN4PLMD6colvar19MultiColvarTemplateINS0_6DipoleEE16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD6colvar19MultiColvarTemplateINS0_6DipoleEE22getNumberOfDerivativesEv6
_ZN4PLMD6colvar19MultiColvarTemplateINS0_6DipoleEE23addValueWithDerivativesERKSt6vectorIjSaIjEE1
_ZN4PLMD6colvar19MultiColvarTemplateINS0_6DipoleEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSC_SC_SC_16
_ZN4PLMD6colvar19MultiColvarTemplateINS0_6DipoleEE27addComponentWithDerivativesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIjSaIjEE6
_ZN4PLMD6colvar19MultiColvarTemplateINS0_6DipoleEE9calculateEv16
_ZN4PLMD6colvar19MultiColvarTemplateINS0_6DipoleEEC1ERKNS_13ActionOptionsE3
_ZN4PLMD6colvar19MultiColvarTemplateINS0_7TorsionEE16registerKeywordsERNS_8KeywordsE16
_ZN4PLMD6colvar19MultiColvarTemplateINS0_7TorsionEE22getNumberOfDerivativesEv128
_ZN4PLMD6colvar19MultiColvarTemplateINS0_7TorsionEE23addValueWithDerivativesERKSt6vectorIjSaIjEE14
_ZN4PLMD6colvar19MultiColvarTemplateINS0_7TorsionEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSC_SC_SC_123
_ZN4PLMD6colvar19MultiColvarTemplateINS0_7TorsionEE27addComponentWithDerivativesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIjSaIjEE0
_ZN4PLMD6colvar19MultiColvarTemplateINS0_7TorsionEE9calculateEv84
_ZN4PLMD6colvar19MultiColvarTemplateINS0_7TorsionEEC1ERKNS_13ActionOptionsE14
_ZN4PLMD6colvar19MultiColvarTemplateINS0_8DistanceEE16registerKeywordsERNS_8KeywordsE106
_ZN4PLMD6colvar19MultiColvarTemplateINS0_8DistanceEE22getNumberOfDerivativesEv553
_ZN4PLMD6colvar19MultiColvarTemplateINS0_8DistanceEE23addValueWithDerivativesERKSt6vectorIjSaIjEE59
_ZN4PLMD6colvar19MultiColvarTemplateINS0_8DistanceEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSC_SC_SC_15596
_ZN4PLMD6colvar19MultiColvarTemplateINS0_8DistanceEE27addComponentWithDerivativesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIjSaIjEE135
_ZN4PLMD6colvar19MultiColvarTemplateINS0_8DistanceEE9calculateEv15253
_ZN4PLMD6colvar19MultiColvarTemplateINS0_8DistanceEEC1ERKNS_13ActionOptionsE104
_ZN4PLMD6colvar19MultiColvarTemplateINS0_8PositionEE16registerKeywordsERNS_8KeywordsE43
_ZN4PLMD6colvar19MultiColvarTemplateINS0_8PositionEE22getNumberOfDerivativesEv729
_ZN4PLMD6colvar19MultiColvarTemplateINS0_8PositionEE23addValueWithDerivativesERKSt6vectorIjSaIjEE0
_ZN4PLMD6colvar19MultiColvarTemplateINS0_8PositionEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSC_SC_SC_12212
_ZN4PLMD6colvar19MultiColvarTemplateINS0_8PositionEE27addComponentWithDerivativesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIjSaIjEE123
_ZN4PLMD6colvar19MultiColvarTemplateINS0_8PositionEE9calculateEv7229
_ZN4PLMD6colvar19MultiColvarTemplateINS0_8PositionEEC1ERKNS_13ActionOptionsE41
_ZN4PLMD6colvar19MultiColvarTemplateINS_12crystdistrib10QuaternionEE16registerKeywordsERNS_8KeywordsE14
_ZN4PLMD6colvar19MultiColvarTemplateINS_12crystdistrib10QuaternionEE22getNumberOfDerivativesEv48
_ZN4PLMD6colvar19MultiColvarTemplateINS_12crystdistrib10QuaternionEE23addValueWithDerivativesERKSt6vectorIjSaIjEE0
_ZN4PLMD6colvar19MultiColvarTemplateINS_12crystdistrib10QuaternionEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSD_SD_SD_84
_ZN4PLMD6colvar19MultiColvarTemplateINS_12crystdistrib10QuaternionEE27addComponentWithDerivativesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIjSaIjEE48
_ZN4PLMD6colvar19MultiColvarTemplateINS_12crystdistrib10QuaternionEE9calculateEv54
_ZN4PLMD6colvar19MultiColvarTemplateINS_12crystdistrib10QuaternionEEC1ERKNS_13ActionOptionsE12
_ZNK4PLMD6colvar19MultiColvarTemplateINS0_16SelectMassChargeEE11performTaskERKjRNS_10MultiValueE5144
_ZNK4PLMD6colvar19MultiColvarTemplateINS0_19DihedralCorrelationEE11performTaskERKjRNS_10MultiValueE10
_ZNK4PLMD6colvar19MultiColvarTemplateINS0_5AngleEE11performTaskERKjRNS_10MultiValueE235
_ZNK4PLMD6colvar19MultiColvarTemplateINS0_5PlaneEE11performTaskERKjRNS_10MultiValueE176
_ZNK4PLMD6colvar19MultiColvarTemplateINS0_6DipoleEE11performTaskERKjRNS_10MultiValueE3086
_ZNK4PLMD6colvar19MultiColvarTemplateINS0_7TorsionEE11performTaskERKjRNS_10MultiValueE779
_ZNK4PLMD6colvar19MultiColvarTemplateINS0_8DistanceEE11performTaskERKjRNS_10MultiValueE331693
_ZNK4PLMD6colvar19MultiColvarTemplateINS0_8PositionEE11performTaskERKjRNS_10MultiValueE143344
_ZNK4PLMD6colvar19MultiColvarTemplateINS_12crystdistrib10QuaternionEE11performTaskERKjRNS_10MultiValueE5673
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/MultiColvarTemplate.h.gcov.html b/coverage/colvar/MultiColvarTemplate.h.gcov.html new file mode 100644 index 000000000000..046526d03789 --- /dev/null +++ b/coverage/colvar/MultiColvarTemplate.h.gcov.html @@ -0,0 +1,284 @@ + + + + + + + + LCOV - plumed test coverage - colvar/MultiColvarTemplate.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - MultiColvarTemplate.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:919397.8 %
Date:2024-04-19 12:12:35Functions:657290.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             : #ifndef __PLUMED_colvar_MultiColvarTemplate_h
+      23             : #define __PLUMED_colvar_MultiColvarTemplate_h
+      24             : 
+      25             : #include "core/ActionWithVector.h"
+      26             : 
+      27             : namespace PLMD {
+      28             : namespace colvar {
+      29             : 
+      30             : template <class T>
+      31             : class MultiColvarTemplate : public ActionWithVector {
+      32             : private:
+      33             : /// An index that decides what we are calculating
+      34             :   unsigned mode;
+      35             : /// Are we using pbc to calculate the CVs
+      36             :   bool usepbc;
+      37             : /// Do we reassemble the molecule
+      38             :   bool wholemolecules;
+      39             : /// Blocks of atom numbers
+      40             :   std::vector< std::vector<unsigned> > ablocks;
+      41             : public:
+      42             :   static void registerKeywords(Keywords&);
+      43             :   explicit MultiColvarTemplate(const ActionOptions&);
+      44             :   unsigned getNumberOfDerivatives() override ;
+      45             :   void addValueWithDerivatives( const std::vector<unsigned>& shape=std::vector<unsigned>() ) override ;
+      46             :   void addComponentWithDerivatives( const std::string& name, const std::vector<unsigned>& shape=std::vector<unsigned>() ) override ;
+      47             :   void setupStreamedComponents( const std::string& headstr, unsigned& nquants, unsigned& nmat, unsigned& maxcol, unsigned& nbookeeping ) override ;
+      48             :   void performTask( const unsigned&, MultiValue& ) const override ;
+      49             :   void calculate() override;
+      50             : };
+      51             : 
+      52             : template <class T>
+      53         217 : void MultiColvarTemplate<T>::registerKeywords(Keywords& keys ) {
+      54         217 :   T::registerKeywords( keys );
+      55         217 :   unsigned nkeys = keys.size();
+      56        1983 :   for(unsigned i=0; i<nkeys; ++i) {
+      57        3894 :     if( keys.style( keys.get(i), "atoms" ) ) keys.reset_style( keys.get(i), "numbered" );
+      58             :   }
+      59         217 : }
+      60             : 
+      61             : template <class T>
+      62         197 : MultiColvarTemplate<T>::MultiColvarTemplate(const ActionOptions&ao):
+      63             :   Action(ao),
+      64             :   ActionWithVector(ao),
+      65         197 :   mode(0),
+      66         197 :   usepbc(true),
+      67         197 :   wholemolecules(false)
+      68             : {
+      69             :   std::vector<AtomNumber> all_atoms;
+      70         559 :   if( getName()=="POSITION_VECTOR" || getName()=="MASS_VECTOR" || getName()=="CHARGE_VECTOR" ) parseAtomList( "ATOMS", all_atoms );
+      71         197 :   if( all_atoms.size()>0 ) {
+      72          57 :     ablocks.resize(1); ablocks[0].resize( all_atoms.size() );
+      73        8109 :     for(unsigned i=0; i<all_atoms.size(); ++i) ablocks[0][i] = i;
+      74             :   } else {
+      75             :     std::vector<AtomNumber> t;
+      76       27127 :     for(int i=1;; ++i ) {
+      77       27127 :       T::parseAtomList( i, t, this );
+      78       27127 :       if( t.empty() ) break;
+      79             : 
+      80       26987 :       if( i==1 ) { ablocks.resize(t.size()); }
+      81       26987 :       if( t.size()!=ablocks.size() ) {
+      82           0 :         std::string ss; Tools::convert(i,ss);
+      83           0 :         error("ATOMS" + ss + " keyword has the wrong number of atoms");
+      84             :       }
+      85       83269 :       for(unsigned j=0; j<ablocks.size(); ++j) {
+      86       56282 :         ablocks[j].push_back( ablocks.size()*(i-1)+j ); all_atoms.push_back( t[j] );
+      87             :       }
+      88       26987 :       t.resize(0);
+      89             :     }
+      90             :   }
+      91         197 :   if( all_atoms.size()==0 ) error("No atoms have been specified");
+      92         197 :   requestAtoms(all_atoms);
+      93         394 :   if( keywords.exists("NOPBC") ) {
+      94         197 :     bool nopbc=!usepbc; parseFlag("NOPBC",nopbc);
+      95         197 :     usepbc=!nopbc;
+      96             :   }
+      97         394 :   if( keywords.exists("WHOLEMOLECULES") ) {
+      98          41 :     parseFlag("WHOLEMOLECULES",wholemolecules);
+      99          41 :     if( wholemolecules ) usepbc=false;
+     100             :   }
+     101         197 :   if( usepbc ) log.printf("  using periodic boundary conditions\n");
+     102          34 :   else    log.printf("  without periodic boundary conditions\n");
+     103             : 
+     104             :   // Setup the values
+     105         197 :   mode = T::getModeAndSetupValues( this );
+     106         197 : }
+     107             : 
+     108             : template <class T>
+     109        1612 : unsigned MultiColvarTemplate<T>::getNumberOfDerivatives() {
+     110        1612 :   return 3*getNumberOfAtoms()+9;
+     111             : }
+     112             : 
+     113             : template <class T>
+     114       22685 : void MultiColvarTemplate<T>::calculate() {
+     115       22685 :   runAllTasks();
+     116       22685 : }
+     117             : 
+     118             : template <class T>
+     119          96 : void MultiColvarTemplate<T>::addValueWithDerivatives( const std::vector<unsigned>& shape ) {
+     120          96 :   std::vector<unsigned> s(1); s[0]=ablocks[0].size(); addValue( s );
+     121          96 : }
+     122             : 
+     123             : template <class T>
+     124         315 : void MultiColvarTemplate<T>::addComponentWithDerivatives( const std::string& name, const std::vector<unsigned>& shape ) {
+     125         315 :   std::vector<unsigned> s(1); s[0]=ablocks[0].size(); addComponent( name, s );
+     126         315 : }
+     127             : 
+     128             : template <class T>
+     129       28091 : void MultiColvarTemplate<T>::setupStreamedComponents( const std::string& headstr, unsigned& nquants, unsigned& nmat, unsigned& maxcol, unsigned& nbookeeping ) {
+     130       28091 :   if( wholemolecules ) makeWhole();
+     131       28091 :   ActionWithVector::setupStreamedComponents( headstr, nquants, nmat, maxcol, nbookeeping );
+     132       28091 : }
+     133             : 
+     134             : template <class T>
+     135      490140 : void MultiColvarTemplate<T>::performTask( const unsigned& task_index, MultiValue& myvals ) const {
+     136             :   // Retrieve the positions
+     137             :   std::vector<Vector> & fpositions( myvals.getFirstAtomVector() );
+     138      490140 :   if( fpositions.size()!=ablocks.size() ) fpositions.resize( ablocks.size() );
+     139     1334749 :   for(unsigned i=0; i<ablocks.size(); ++i) fpositions[i] = getPosition( ablocks[i][task_index] );
+     140             :   // If we are using pbc make whole
+     141      490140 :   if( usepbc ) {
+     142      233347 :     if( fpositions.size()==1 ) {
+     143       57816 :       fpositions[0]=pbcDistance(Vector(0.0,0.0,0.0),getPosition( ablocks[0][task_index] ) );
+     144             :     } else {
+     145      418629 :       for(unsigned j=0; j<fpositions.size()-1; ++j) {
+     146      214190 :         const Vector & first (fpositions[j]); Vector & second (fpositions[j+1]);
+     147      214190 :         second=first+pbcDistance(first,second);
+     148             :       }
+     149             :     }
+     150      256793 :   } else if( fpositions.size()==1 ) fpositions[0]=delta(Vector(0.0,0.0,0.0),getPosition( ablocks[0][task_index] ) );
+     151             :   // Retrieve the masses and charges
+     152      490140 :   myvals.resizeTemporyVector(2);
+     153             :   std::vector<double> & mass( myvals.getTemporyVector(0) );
+     154             :   std::vector<double> & charge( myvals.getTemporyVector(1) );
+     155      490140 :   if( mass.size()!=ablocks.size() ) { mass.resize(ablocks.size()); charge.resize(ablocks.size()); }
+     156     1334749 :   for(unsigned i=0; i<ablocks.size(); ++i) { mass[i]=getMass( ablocks[i][task_index] ); charge[i]=getCharge( ablocks[i][task_index] ); }
+     157             :   // Make some space to store various things
+     158      490140 :   std::vector<double> values( getNumberOfComponents() );
+     159             :   std::vector<Tensor> & virial( myvals.getFirstAtomVirialVector() );
+     160             :   std::vector<std::vector<Vector> > & derivs( myvals.getFirstAtomDerivativeVector() );
+     161      490140 :   if( derivs.size()!=values.size() ) { derivs.resize( values.size() ); virial.resize( values.size() ); }
+     162     1478457 :   for(unsigned i=0; i<derivs.size(); ++i) {
+     163      988317 :     if( derivs[i].size()<ablocks.size() ) derivs[i].resize( ablocks.size() );
+     164             :   }
+     165             :   // Calculate the CVs using the method in the Colvar
+     166      490140 :   T::calculateCV( mode, mass, charge, fpositions, values, derivs, virial, this );
+     167     1478457 :   for(unsigned i=0; i<values.size(); ++i) myvals.setValue( getConstPntrToComponent(i)->getPositionInStream(), values[i] );
+     168             :   // Finish if there are no derivatives
+     169      490140 :   if( doNotCalculateDerivatives() ) return;
+     170             : 
+     171             :   // Now transfer the derivatives to the underlying MultiValue
+     172      868925 :   for(unsigned i=0; i<ablocks.size(); ++i) {
+     173      547918 :     unsigned base=3*ablocks[i][task_index];
+     174     1456521 :     for(int j=0; j<getNumberOfComponents(); ++j) {
+     175      908603 :       unsigned jval=getConstPntrToComponent(j)->getPositionInStream();
+     176      908603 :       myvals.addDerivative( jval, base + 0, derivs[j][i][0] );
+     177      908603 :       myvals.addDerivative( jval, base + 1, derivs[j][i][1] );
+     178      908603 :       myvals.addDerivative( jval, base + 2, derivs[j][i][2] );
+     179             :     }
+     180             :     // Check for duplicated indices during update to avoid double counting
+     181             :     bool newi=true;
+     182      787032 :     for(unsigned j=0; j<i; ++j) {
+     183      239114 :       if( ablocks[j][task_index]==ablocks[i][task_index] ) { newi=false; break; }
+     184             :     }
+     185      547918 :     if( !newi ) continue;
+     186     1456521 :     for(int j=0; j<getNumberOfComponents(); ++j) {
+     187      908603 :       unsigned jval=getConstPntrToComponent(j)->getPositionInStream();
+     188      908603 :       myvals.updateIndex( jval, base );
+     189      908603 :       myvals.updateIndex( jval, base + 1 );
+     190      908603 :       myvals.updateIndex( jval, base + 2 );
+     191             :     }
+     192             :   }
+     193      321007 :   unsigned nvir=3*getNumberOfAtoms();
+     194      913213 :   for(int j=0; j<getNumberOfComponents(); ++j) {
+     195      592206 :     unsigned jval=getConstPntrToComponent(j)->getPositionInStream();
+     196     2368824 :     for(unsigned i=0; i<3; ++i) {
+     197     7106472 :       for(unsigned k=0; k<3; ++k) {
+     198     5329854 :         myvals.addDerivative( jval, nvir + 3*i + k, virial[j][i][k] );
+     199     5329854 :         myvals.updateIndex( jval, nvir + 3*i + k );
+     200             :       }
+     201             :     }
+     202             :   }
+     203             : }
+     204             : 
+     205             : }
+     206             : }
+     207             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/MultiRMSD.cpp.func-sort-c.html b/coverage/colvar/MultiRMSD.cpp.func-sort-c.html new file mode 100644 index 000000000000..56d08e3ebd3b --- /dev/null +++ b/coverage/colvar/MultiRMSD.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + 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:505590.9 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar9MultiRMSDC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar9MultiRMSDC1ERKNS_13ActionOptionsE1
_ZN4PLMD6colvar9MultiRMSD16registerKeywordsERNS_8KeywordsE3
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/MultiRMSD.cpp.func.html b/coverage/colvar/MultiRMSD.cpp.func.html new file mode 100644 index 000000000000..5bc76ca23c97 --- /dev/null +++ b/coverage/colvar/MultiRMSD.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + 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:505590.9 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar9MultiRMSD16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD6colvar9MultiRMSDC1ERKNS_13ActionOptionsE1
_ZN4PLMD6colvar9MultiRMSDC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/MultiRMSD.cpp.gcov.html b/coverage/colvar/MultiRMSD.cpp.gcov.html new file mode 100644 index 000000000000..bab7e259e9e4 --- /dev/null +++ b/coverage/colvar/MultiRMSD.cpp.gcov.html @@ -0,0 +1,207 @@ + + + + + + + + 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:505590.9 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionShortcut.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "core/ActionWithArguments.h"
+      25             : #include "tools/PDB.h"
+      26             : #include "core/PlumedMain.h"
+      27             : 
+      28             : //+PLUMEDOC DCOLVAR MULTI_RMSD
+      29             : /*
+      30             : Calculate RMSD distances for different domains and combine them.
+      31             : 
+      32             : This action is largely depracated.  In previous versions of PLUMED a more complex version of this method was implemented.
+      33             : We felt, however, that the input syntax for the method was not very transparant.  We have thus provided this minimal action
+      34             : that creates the input for calculating the MultiDomain RMSD for simple cases.  This action is a shortcut.  If you look at the log you can see how we
+      35             : use the various actions that are in PLUMED to calculate the final quantity.  If you would like to implement some of the more
+      36             : complicated CVs things that this could do with MULTI_RMSD looking at how this shortcut works will help you start.
+      37             : 
+      38             : 
+      39             : \par Examples
+      40             : 
+      41             : */
+      42             : //+ENDPLUMEDOC
+      43             : 
+      44             : namespace PLMD {
+      45             : namespace colvar {
+      46             : 
+      47             : class MultiRMSD : public ActionShortcut {
+      48             : public:
+      49             :   static void registerKeywords(Keywords& keys);
+      50             :   explicit MultiRMSD(const ActionOptions&);
+      51             : };
+      52             : 
+      53             : PLUMED_REGISTER_ACTION(MultiRMSD,"MULTI_RMSD")
+      54             : 
+      55           3 : void MultiRMSD::registerKeywords(Keywords& keys) {
+      56           3 :   ActionShortcut::registerKeywords( keys );
+      57           6 :   keys.add("compulsory","REFERENCE","a file in pdb format containing the reference structure and the atoms involved in the CV.");
+      58           6 :   keys.add("compulsory","TYPE","SIMPLE","the manner in which RMSD alignment is performed.  Should be MULTI-OPTIMAL, MULTI-OPTIMAL-FAST,  MULTI-SIMPLE or MULTI-DRMSD.");
+      59           6 :   keys.addFlag("SQUARED",false," This should be set if you want the mean squared displacement instead of the root mean squared displacement");
+      60           6 :   keys.addFlag("NOPBC",false,"don't use periodic boundary conditions");
+      61           9 :   keys.needsAction("CONSTANT"); keys.needsAction("WHOLEMOLECULES"); keys.needsAction("POSITION");
+      62          12 :   keys.needsAction("CONCATENATE"); keys.needsAction("RMSD_VECTOR"); keys.needsAction("COMBINE"); keys.needsAction("CUSTOM");
+      63           3 : }
+      64             : 
+      65           1 : MultiRMSD::MultiRMSD(const ActionOptions& ao):
+      66             :   Action(ao),
+      67           1 :   ActionShortcut(ao)
+      68             : {
+      69           2 :   warning("this action is depracated.  look at the log to see how it is implemented using the new syntax");
+      70           2 :   std::string type; parse("TYPE",type); bool nopbc; parseFlag("NOPBC",nopbc);
+      71           1 :   std::size_t dash=type.find_first_of("-");
+      72           1 :   if( dash!=std::string::npos ) {
+      73           2 :     if( type.substr(0,dash)=="MULTI" ) warning("MULTI is deprecated.  You can just use OPTIMAL/SIMPLE");
+      74           0 :     else error("cannot understand type " + type );
+      75           2 :     type = type.substr(dash+1);
+      76             :   }
+      77           2 :   std::string reference; parse("REFERENCE",reference); PDB pdb;
+      78           1 :   if( !pdb.read(reference,usingNaturalUnits(),0.1/getUnits().getLength()) ) error("missing input file " + reference );
+      79             : 
+      80           1 :   unsigned nblocks =  pdb.getNumberOfAtomBlocks();
+      81           1 :   if( nblocks<2 ) error("multidomain RMSD only has one block of atoms");
+      82           1 :   std::string num; std::vector<unsigned> blocks( nblocks+1 ); blocks[0]=0;
+      83           3 :   for(unsigned i=0; i<nblocks; ++i) blocks[i+1]=pdb.getAtomBlockEnds()[i];
+      84             : 
+      85           3 :   for(unsigned i=1; i<=nblocks; ++i) {
+      86             :     // Setup a constant
+      87           2 :     double asum=0; std::string bnum; Tools::convert( i, bnum );
+      88          17 :     for(unsigned j=blocks[i-1]; j<blocks[i]; ++j) asum += pdb.getOccupancy()[j];
+      89           2 :     Vector center; center.zero();
+      90          17 :     for(unsigned j=blocks[i-1]; j<blocks[i]; ++j) center += ( pdb.getOccupancy()[j] / asum )*pdb.getPositions()[j];
+      91             :     std::vector<double> vals;
+      92           8 :     for(unsigned k=0; k<3; ++k) {
+      93          51 :       for(unsigned j=blocks[i-1]; j<blocks[i]; ++j) vals.push_back( pdb.getPositions()[j][k] - center[k] );
+      94             :     }
+      95           2 :     std::string valstr; Tools::convert( vals[0], valstr );
+      96          45 :     for(unsigned i=1; i<vals.size(); ++i) { std::string rnum; Tools::convert( vals[i], rnum ); valstr += "," + rnum; }
+      97             :     // Create the reference value
+      98           4 :     readInputLine( getShortcutLabel() + "_ref" + bnum + ": CONSTANT VALUES=" + valstr );
+      99             :     // Do whole molecules
+     100           2 :     if( !nopbc ) {
+     101           0 :       std::string num; Tools::convert( pdb.getAtomNumbers()[blocks[i-1]].serial(), num ); std::string wm_line = "WHOLEMOLECULES ENTITY0=" + num;
+     102           0 :       for(unsigned j=blocks[i-1]+1; j<blocks[i]; ++j) { Tools::convert( pdb.getAtomNumbers()[j].serial(), num ); wm_line += "," + num; }
+     103           0 :       readInputLine( wm_line );
+     104             :     }
+     105             :     // Get the positions of the atoms in this block
+     106           4 :     std::string num; Tools::convert( pdb.getAtomNumbers()[blocks[i-1]].serial(), num ); std::string pos_line = getShortcutLabel() + "_cpos" + bnum + ": POSITION NOPBC ATOMS=" + num;
+     107          15 :     for(unsigned j=blocks[i-1]+1; j<blocks[i]; ++j) { Tools::convert( pdb.getAtomNumbers()[j].serial(), num ); pos_line += "," + num; }
+     108           2 :     readInputLine( pos_line );
+     109             :     // Concatenate the positiosn together
+     110           4 :     readInputLine( getShortcutLabel() + "_pos" + bnum + ": CONCATENATE ARG=" + getShortcutLabel() + "_cpos" + bnum + ".x," + getShortcutLabel() + "_cpos" + bnum + ".y," + getShortcutLabel() + "_cpos" + bnum + ".z");
+     111             :     // Computer the RMSD for this block
+     112           4 :     std::string rmsd_line = getShortcutLabel() + "_rmsd" + bnum + ": RMSD_VECTOR SQUARED ARG=" + getShortcutLabel() + "_pos" + bnum + "," + getShortcutLabel() + "_ref" + bnum;
+     113             :     // Now align
+     114           4 :     Tools::convert( pdb.getOccupancy()[blocks[i-1]], num ); rmsd_line += " ALIGN=" + num;
+     115          15 :     for(unsigned j=blocks[i-1]+1; j<blocks[i]; ++j) { Tools::convert( pdb.getOccupancy()[j], num ); rmsd_line += "," + num; }
+     116             :     // And displace
+     117           4 :     Tools::convert( pdb.getBeta()[blocks[i-1]], num ); rmsd_line += " DISPLACE=" + num;
+     118          15 :     for(unsigned j=blocks[i-1]+1; j<blocks[i]; ++j) { Tools::convert( pdb.getBeta()[j], num ); rmsd_line += "," + num; }
+     119           4 :     readInputLine( rmsd_line + " TYPE=" + type );
+     120             :   }
+     121           3 :   std::string argstr = getShortcutLabel() + "_rmsd1"; for(unsigned i=1; i<nblocks; ++i) { std::string bnum; Tools::convert( i+1, bnum); argstr += "," + getShortcutLabel() + "_rmsd" + bnum; }
+     122           1 :   bool squared; parseFlag("SQUARED",squared);
+     123           1 :   if( !squared ) {
+     124           2 :     readInputLine( getShortcutLabel() + "_2: COMBINE ARG=" + argstr + " PERIODIC=NO");
+     125           2 :     readInputLine( getShortcutLabel() + ": CUSTOM ARG=" + getShortcutLabel() + "_2 FUNC=sqrt(x) PERIODIC=NO");
+     126           0 :   } else readInputLine( getShortcutLabel() + ": COMBINE ARG=" + argstr + " PERIODIC=NO");
+     127           2 : }
+     128             : 
+     129             : }
+     130             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/PCARMSD.cpp.func-sort-c.html b/coverage/colvar/PCARMSD.cpp.func-sort-c.html new file mode 100644 index 000000000000..1ee734d42f69 --- /dev/null +++ b/coverage/colvar/PCARMSD.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - colvar/PCARMSD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - PCARMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:939498.9 %
Date:2024-04-19 12:12:35Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

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

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

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

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

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

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

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

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

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

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

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

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar5Plane9calculateEv0
_ZN4PLMD6colvar5PlaneC1ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar5PlaneC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar5Plane21getModeAndSetupValuesEPNS_15ActionWithValueE1
_ZN4PLMD6colvar5Plane16registerKeywordsERNS_8KeywordsE8
_ZN4PLMD6colvar5Plane13parseAtomListERKiRSt6vectorINS_10AtomNumberESaIS5_EEPNS_15ActionAtomisticE9
_ZN4PLMD6colvar5Plane11calculateCVERKjRKSt6vectorIdSaIdEES8_RKS4_INS_13VectorGenericILj3EEESaISA_EERS6_RS4_ISC_SaISC_EERS4_INS_13TensorGenericILj3ELj3EEESaISK_EEPKNS_15ActionAtomisticE176
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Plane.cpp.func.html b/coverage/colvar/Plane.cpp.func.html new file mode 100644 index 000000000000..60edc9cb7e19 --- /dev/null +++ b/coverage/colvar/Plane.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - colvar/Plane.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Plane.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:467065.7 %
Date:2024-04-19 12:12:35Functions:4757.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar5Plane11calculateCVERKjRKSt6vectorIdSaIdEES8_RKS4_INS_13VectorGenericILj3EEESaISA_EERS6_RS4_ISC_SaISC_EERS4_INS_13TensorGenericILj3ELj3EEESaISK_EEPKNS_15ActionAtomisticE176
_ZN4PLMD6colvar5Plane13parseAtomListERKiRSt6vectorINS_10AtomNumberESaIS5_EEPNS_15ActionAtomisticE9
_ZN4PLMD6colvar5Plane16registerKeywordsERNS_8KeywordsE8
_ZN4PLMD6colvar5Plane21getModeAndSetupValuesEPNS_15ActionWithValueE1
_ZN4PLMD6colvar5Plane9calculateEv0
_ZN4PLMD6colvar5PlaneC1ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar5PlaneC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Plane.cpp.gcov.html b/coverage/colvar/Plane.cpp.gcov.html new file mode 100644 index 000000000000..1111d5d19cd9 --- /dev/null +++ b/coverage/colvar/Plane.cpp.gcov.html @@ -0,0 +1,254 @@ + + + + + + + + LCOV - plumed test coverage - colvar/Plane.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Plane.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:467065.7 %
Date:2024-04-19 12:12:35Functions:4757.1 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "Colvar.h"
+      23             : #include "ColvarShortcut.h"
+      24             : #include "core/ActionRegister.h"
+      25             : #include "MultiColvarTemplate.h"
+      26             : #include "tools/Pbc.h"
+      27             : 
+      28             : #include <string>
+      29             : #include <cmath>
+      30             : 
+      31             : //+PLUMEDOC COLVAR PLANE
+      32             : /*
+      33             : Calculate the plane perpendicular to two vectors in order to represent the orientation of a planar molecule.
+      34             : 
+      35             : \par Examples
+      36             : 
+      37             : 
+      38             : */
+      39             : //+ENDPLUMEDOC
+      40             : 
+      41             : //+PLUMEDOC COLVAR PLANE_SCALAR
+      42             : /*
+      43             : Calculate the plane perpendicular to two vectors in order to represent the orientation of a planar molecule.
+      44             : 
+      45             : \par Examples
+      46             : 
+      47             : */
+      48             : //+ENDPLUMEDOC
+      49             : 
+      50             : //+PLUMEDOC COLVAR PLANE_VECTOR
+      51             : /*
+      52             : Calculate the plane perpendicular to two vectors in order to represent the orientation of a planar molecule multiple times.
+      53             : 
+      54             : \par Examples
+      55             : 
+      56             : */
+      57             : //+ENDPLUMEDOC
+      58             : 
+      59             : namespace PLMD {
+      60             : namespace colvar {
+      61             : 
+      62             : class Plane : public Colvar {
+      63             : private:
+      64             :   bool pbc;
+      65             :   std::vector<double> value, masses, charges;
+      66             :   std::vector<std::vector<Vector> > derivs;
+      67             :   std::vector<Tensor> virial;
+      68             : public:
+      69             :   static void registerKeywords( Keywords& keys );
+      70             :   explicit Plane(const ActionOptions&);
+      71             :   static void parseAtomList( const int& num, std::vector<AtomNumber>& t, ActionAtomistic* aa );
+      72             :   static unsigned getModeAndSetupValues( ActionWithValue* av );
+      73             : // active methods:
+      74             :   void calculate() override;
+      75             :   static void calculateCV( const unsigned& mode, const std::vector<double>& masses, const std::vector<double>& charges,
+      76             :                            const std::vector<Vector>& pos, std::vector<double>& vals, std::vector<std::vector<Vector> >& derivs,
+      77             :                            std::vector<Tensor>& virial, const ActionAtomistic* aa );
+      78             : };
+      79             : 
+      80             : typedef ColvarShortcut<Plane> PlaneShortcut;
+      81             : PLUMED_REGISTER_ACTION(PlaneShortcut,"PLANE")
+      82             : PLUMED_REGISTER_ACTION(Plane,"PLANE_SCALAR")
+      83             : typedef MultiColvarTemplate<Plane> PlaneMulti;
+      84             : PLUMED_REGISTER_ACTION(PlaneMulti,"PLANE_VECTOR")
+      85             : 
+      86           8 : void Plane::registerKeywords( Keywords& keys ) {
+      87           8 :   Colvar::registerKeywords( keys );
+      88          16 :   keys.add("atoms","ATOMS","the three or four atoms whose plane we are computing");
+      89          16 :   keys.addOutputComponent("x","default","the x-component of the vector that is normal to the plane containing the atoms");
+      90          16 :   keys.addOutputComponent("y","default","the y-component of the vector that is normal to the plane containing the atoms");
+      91          16 :   keys.addOutputComponent("z","default","the z-component of the vector that is normal to the plane containing the atoms");
+      92          16 :   keys.add("hidden","NO_ACTION_LOG","suppresses printing from action on the log");
+      93           8 : }
+      94             : 
+      95           9 : void Plane::parseAtomList( const int& num, std::vector<AtomNumber>& atoms, ActionAtomistic* aa ) {
+      96          18 :   aa->parseAtomList("ATOMS",num,atoms);
+      97           9 :   if(atoms.size()==3) {
+      98           8 :     aa->log.printf("  containing atoms %d %d %d\n",atoms[0].serial(),atoms[1].serial(),atoms[2].serial());
+      99           8 :     atoms.resize(4);
+     100           8 :     atoms[3]=atoms[2];
+     101           8 :     atoms[2]=atoms[1];
+     102           1 :   } else if(atoms.size()==4) {
+     103           0 :     aa->log.printf("  containing lines %d-%d and %d-%d\n",atoms[0].serial(),atoms[1].serial(),atoms[2].serial(),atoms[3].serial());
+     104           1 :   } else if( num<0 || atoms.size()>0 ) aa->error("Number of specified atoms should be either 3 or 4");
+     105           9 : }
+     106             : 
+     107           1 : unsigned Plane::getModeAndSetupValues( ActionWithValue* av ) {
+     108           2 :   av->addComponentWithDerivatives("x"); av->componentIsNotPeriodic("x");
+     109           2 :   av->addComponentWithDerivatives("y"); av->componentIsNotPeriodic("y");
+     110           2 :   av->addComponentWithDerivatives("z"); av->componentIsNotPeriodic("z");
+     111           1 :   return 0;
+     112             : }
+     113             : 
+     114           0 : Plane::Plane(const ActionOptions&ao):
+     115             :   PLUMED_COLVAR_INIT(ao),
+     116           0 :   pbc(true),
+     117           0 :   value(3),
+     118           0 :   derivs(3),
+     119           0 :   virial(3)
+     120             : {
+     121           0 :   for(unsigned i=0; i<3; ++i) derivs[i].resize(4);
+     122           0 :   std::vector<AtomNumber> atoms; parseAtomList(-1,atoms,this);
+     123           0 :   bool nopbc=!pbc;
+     124           0 :   parseFlag("NOPBC",nopbc);
+     125           0 :   pbc=!nopbc;
+     126             : 
+     127           0 :   if(pbc) log.printf("  using periodic boundary conditions\n");
+     128           0 :   else    log.printf("  without periodic boundary conditions\n");
+     129             : 
+     130           0 :   unsigned mode = getModeAndSetupValues( this );
+     131           0 :   requestAtoms(atoms);
+     132           0 :   checkRead();
+     133           0 : }
+     134             : 
+     135           0 : void Plane::calculate() {
+     136             : 
+     137           0 :   if(pbc) makeWhole();
+     138           0 :   calculateCV( 0, masses, charges, getPositions(), value, derivs, virial, this );
+     139           0 :   setValue( value[0] );
+     140           0 :   for(unsigned i=0; i<derivs[0].size(); ++i) setAtomsDerivatives( i, derivs[0][i] );
+     141           0 :   setBoxDerivatives( virial[0] );
+     142           0 : }
+     143             : 
+     144         176 : void Plane::calculateCV( const unsigned& mode, const std::vector<double>& masses, const std::vector<double>& charges,
+     145             :                          const std::vector<Vector>& pos, std::vector<double>& vals, std::vector<std::vector<Vector> >& derivs,
+     146             :                          std::vector<Tensor>& virial, const ActionAtomistic* aa ) {
+     147         176 :   Vector d1=delta( pos[1], pos[0] );
+     148         176 :   Vector d2=delta( pos[2], pos[3] );
+     149         176 :   Vector cp = crossProduct( d1, d2 );
+     150             : 
+     151         176 :   derivs[0][0] = crossProduct( Vector(-1.0,0,0), d2 );
+     152         176 :   derivs[0][1] = crossProduct( Vector(+1.0,0,0), d2 );
+     153         176 :   derivs[0][2] = crossProduct( Vector(-1.0,0,0), d1 );
+     154         176 :   derivs[0][3] = crossProduct( Vector(+1.0,0,0), d1 );
+     155         176 :   virial[0] = Tensor(d1,crossProduct(Vector(+1.0,0,0), d2)) + Tensor( d2, crossProduct(Vector(-1.0,0,0), d1));
+     156         176 :   vals[0] = cp[0];
+     157             : 
+     158         176 :   derivs[1][0] = crossProduct( Vector(0,-1.0,0), d2 );
+     159         176 :   derivs[1][1] = crossProduct( Vector(0,+1.0,0), d2 );
+     160         176 :   derivs[1][2] = crossProduct( Vector(0,-1.0,0), d1 );
+     161         176 :   derivs[1][3] = crossProduct( Vector(0,+1.0,0), d1 );
+     162         176 :   virial[1] = Tensor(d1,crossProduct(Vector(0,+1.0,0), d2)) + Tensor( d2, crossProduct(Vector(0,-1.0,0), d1));
+     163         176 :   vals[1] = cp[1];
+     164             : 
+     165         176 :   derivs[2][0] = crossProduct( Vector(0,0,-1.0), d2 );
+     166         176 :   derivs[2][1] = crossProduct( Vector(0,0,+1.0), d2 );
+     167         176 :   derivs[2][2] = crossProduct( Vector(0,0,-1.0), d1 );
+     168         176 :   derivs[2][3] = crossProduct( Vector(0,0,+1.0), d1 );
+     169         176 :   virial[2] = Tensor(d1,crossProduct(Vector(0,0,+1.0), d2)) + Tensor( d2, crossProduct(Vector(0,0,-1.0), d1));
+     170         176 :   vals[2] = cp[2];
+     171         176 : }
+     172             : 
+     173             : }
+     174             : }
+     175             : 
+     176             : 
+     177             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Position.cpp.func-sort-c.html b/coverage/colvar/Position.cpp.func-sort-c.html new file mode 100644 index 000000000000..726e69349fc7 --- /dev/null +++ b/coverage/colvar/Position.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - colvar/Position.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Position.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:9090100.0 %
Date:2024-04-19 12:12:35Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar8PositionC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar8PositionC1ERKNS_13ActionOptionsE93
_ZN4PLMD6colvar8Position13parseAtomListERKiRSt6vectorINS_10AtomNumberESaIS5_EEPNS_15ActionAtomisticE101
_ZN4PLMD6colvar8Position21getModeAndSetupValuesEPNS_15ActionWithValueE133
_ZN4PLMD6colvar8Position16registerKeywordsERNS_8KeywordsE290
_ZN4PLMD6colvar8Position9calculateEv8067
_ZN4PLMD6colvar8Position11calculateCVERKjRKSt6vectorIdSaIdEES8_RKS4_INS_13VectorGenericILj3EEESaISA_EERS6_RS4_ISC_SaISC_EERS4_INS_13TensorGenericILj3ELj3EEESaISK_EEPKNS_15ActionAtomisticE151411
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Position.cpp.func.html b/coverage/colvar/Position.cpp.func.html new file mode 100644 index 000000000000..7c27509feaa5 --- /dev/null +++ b/coverage/colvar/Position.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - colvar/Position.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Position.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:9090100.0 %
Date:2024-04-19 12:12:35Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar8Position11calculateCVERKjRKSt6vectorIdSaIdEES8_RKS4_INS_13VectorGenericILj3EEESaISA_EERS6_RS4_ISC_SaISC_EERS4_INS_13TensorGenericILj3ELj3EEESaISK_EEPKNS_15ActionAtomisticE151411
_ZN4PLMD6colvar8Position13parseAtomListERKiRSt6vectorINS_10AtomNumberESaIS5_EEPNS_15ActionAtomisticE101
_ZN4PLMD6colvar8Position16registerKeywordsERNS_8KeywordsE290
_ZN4PLMD6colvar8Position21getModeAndSetupValuesEPNS_15ActionWithValueE133
_ZN4PLMD6colvar8Position9calculateEv8067
_ZN4PLMD6colvar8PositionC1ERKNS_13ActionOptionsE93
_ZN4PLMD6colvar8PositionC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Position.cpp.gcov.html b/coverage/colvar/Position.cpp.gcov.html new file mode 100644 index 000000000000..fc1b11660556 --- /dev/null +++ b/coverage/colvar/Position.cpp.gcov.html @@ -0,0 +1,316 @@ + + + + + + + + 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:9090100.0 %
Date:2024-04-19 12:12:35Functions: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 "ColvarShortcut.h"
+      24             : #include "MultiColvarTemplate.h"
+      25             : #include "core/ActionRegister.h"
+      26             : #include "tools/Pbc.h"
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace colvar {
+      30             : 
+      31             : //+PLUMEDOC COLVAR POSITION
+      32             : /*
+      33             : Calculate the components of the position of an atom.
+      34             : 
+      35             : Notice that single components will not have the proper periodicity!
+      36             : If you need the values to be consistent through PBC you should use SCALED_COMPONENTS,
+      37             : which defines values that by construction are in the -0.5,0.5 domain. This is
+      38             : similar to the equivalent flag for \ref DISTANCE.
+      39             : Also notice that by default the minimal image distance from the
+      40             : origin is considered (can be changed with NOPBC).
+      41             : 
+      42             : \attention
+      43             : This variable should be used with extreme care since it allows to easily go into troubles. See comments below.
+      44             : 
+      45             : This variable can be safely used only if
+      46             : Hamiltonian is not invariant for translation (i.e. there are other absolute positions which are biased, e.g. by position restraints)
+      47             : and cell size and shapes are fixed through the simulation.
+      48             : 
+      49             : 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.
+      50             : This can be done e.g. using \ref FIT_TO_TEMPLATE.
+      51             : 
+      52             : \par Examples
+      53             : 
+      54             : \plumedfile
+      55             : # align to a template
+      56             : FIT_TO_TEMPLATE REFERENCE=ref.pdb
+      57             : p: POSITION ATOM=3
+      58             : PRINT ARG=p.x,p.y,p.z
+      59             : \endplumedfile
+      60             : 
+      61             : The reference position is specified in a pdb file like the one shown below
+      62             : 
+      63             : \auxfile{ref.pdb}
+      64             : ATOM      3  HT3 ALA     2      -1.480  -1.560   1.212  1.00  1.00      DIA  H
+      65             : ATOM      9  CAY ALA     2      -0.096   2.144  -0.669  1.00  1.00      DIA  C
+      66             : ATOM     10  HY1 ALA     2       0.871   2.385  -0.588  1.00  1.00      DIA  H
+      67             : ATOM     12  HY3 ALA     2      -0.520   2.679  -1.400  1.00  1.00      DIA  H
+      68             : ATOM     14  OY  ALA     2      -1.139   0.931  -0.973  1.00  1.00      DIA  O
+      69             : END
+      70             : \endauxfile
+      71             : 
+      72             : */
+      73             : //+ENDPLUMEDOC
+      74             : 
+      75             : //+PLUMEDOC COLVAR POSITION_SCALAR
+      76             : /*
+      77             : Calculate the components of the position of an atom.
+      78             : 
+      79             : \par Examples
+      80             : 
+      81             : */
+      82             : //+ENDPLUMEDOC
+      83             : 
+      84             : //+PLUMEDOC COLVAR POSITION_VECTOR
+      85             : /*
+      86             : Create a vector that holds the components of the position of a set of atoms.
+      87             : 
+      88             : \par Examples
+      89             : 
+      90             : */
+      91             : //+ENDPLUMEDOC
+      92             : 
+      93             : class Position : public Colvar {
+      94             :   bool scaled_components;
+      95             :   bool pbc;
+      96             :   std::vector<double> value, masses, charges;
+      97             :   std::vector<std::vector<Vector> > derivs;
+      98             :   std::vector<Tensor> virial;
+      99             : public:
+     100             :   static void registerKeywords( Keywords& keys );
+     101             :   explicit Position(const ActionOptions&);
+     102             :   static void parseAtomList( const int& num, std::vector<AtomNumber>& t, ActionAtomistic* aa );
+     103             :   static unsigned getModeAndSetupValues( ActionWithValue* av );
+     104             : // active methods:
+     105             :   void calculate() override;
+     106             :   static void calculateCV( const unsigned& mode, const std::vector<double>& masses, const std::vector<double>& charges,
+     107             :                            const std::vector<Vector>& pos, std::vector<double>& vals, std::vector<std::vector<Vector> >& derivs,
+     108             :                            std::vector<Tensor>& virial, const ActionAtomistic* aa );
+     109             : };
+     110             : 
+     111             : typedef ColvarShortcut<Position> PositionShortcut;
+     112             : PLUMED_REGISTER_ACTION(PositionShortcut,"POSITION")
+     113             : PLUMED_REGISTER_ACTION(Position,"POSITION_SCALAR")
+     114             : typedef MultiColvarTemplate<Position> PositionMulti;
+     115             : PLUMED_REGISTER_ACTION(PositionMulti,"POSITION_VECTOR")
+     116             : 
+     117         290 : void Position::registerKeywords( Keywords& keys ) {
+     118         290 :   Colvar::registerKeywords( keys );
+     119         290 :   componentsAreNotOptional(keys);
+     120         580 :   keys.add("atoms","ATOM","the atom number");
+     121         580 :   keys.add("atoms","ATOMS","the atom numbers that you would like to use the positions of");
+     122         580 :   keys.addFlag("WHOLEMOLECULES",false,"if this is a vector of positions do you want to make the positions into a whole before");
+     123         580 :   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");
+     124         580 :   keys.addOutputComponent("x","default","the x-component of the atom position");
+     125         580 :   keys.addOutputComponent("y","default","the y-component of the atom position");
+     126         580 :   keys.addOutputComponent("z","default","the z-component of the atom position");
+     127         580 :   keys.addOutputComponent("a","SCALED_COMPONENTS","the normalized projection on the first lattice vector of the atom position");
+     128         580 :   keys.addOutputComponent("b","SCALED_COMPONENTS","the normalized projection on the second lattice vector of the atom position");
+     129         580 :   keys.addOutputComponent("c","SCALED_COMPONENTS","the normalized projection on the third lattice vector of the atom position");
+     130         580 :   keys.add("hidden","NO_ACTION_LOG","suppresses printing from action on the log");
+     131         290 : }
+     132             : 
+     133          93 : Position::Position(const ActionOptions&ao):
+     134             :   PLUMED_COLVAR_INIT(ao),
+     135          93 :   scaled_components(false),
+     136          93 :   pbc(true),
+     137          93 :   value(3),
+     138          94 :   derivs(3),
+     139         186 :   virial(3)
+     140             : {
+     141         372 :   for(unsigned i=0; i<3; ++i) derivs[i].resize(1);
+     142          93 :   std::vector<AtomNumber> atoms; parseAtomList(-1,atoms,this);
+     143          92 :   unsigned mode=getModeAndSetupValues(this);
+     144          92 :   if( mode==1 ) scaled_components=true;
+     145             : 
+     146          92 :   bool nopbc=!pbc;
+     147          93 :   parseFlag("NOPBC",nopbc);
+     148          92 :   pbc=!nopbc;
+     149          92 :   checkRead();
+     150             : 
+     151          92 :   if(pbc) log.printf("  using periodic boundary conditions\n");
+     152           4 :   else    log.printf("  without periodic boundary conditions\n");
+     153             : 
+     154          92 :   requestAtoms(atoms);
+     155          95 : }
+     156             : 
+     157         101 : void Position::parseAtomList( const int& num, std::vector<AtomNumber>& t, ActionAtomistic* aa ) {
+     158         202 :   aa->parseAtomList("ATOM",num,t);
+     159         101 :   if( t.size()==1 ) aa->log.printf("  for atom %d\n",t[0].serial());
+     160           3 :   else if( num<0 || t.size()!=0 ) aa->error("Number of specified atoms should be 1");
+     161         100 : }
+     162             : 
+     163         133 : unsigned Position::getModeAndSetupValues( ActionWithValue* av ) {
+     164         133 :   bool sc; av->parseFlag("SCALED_COMPONENTS",sc);
+     165         133 :   if(sc) {
+     166          45 :     av->addComponentWithDerivatives("a"); av->componentIsPeriodic("a","-0.5","+0.5");
+     167          45 :     av->addComponentWithDerivatives("b"); av->componentIsPeriodic("b","-0.5","+0.5");
+     168          45 :     av->addComponentWithDerivatives("c"); av->componentIsPeriodic("c","-0.5","+0.5");
+     169          15 :     return 1;
+     170             :   }
+     171         236 :   av->addComponentWithDerivatives("x"); av->componentIsNotPeriodic("x");
+     172         236 :   av->addComponentWithDerivatives("y"); av->componentIsNotPeriodic("y");
+     173         236 :   av->addComponentWithDerivatives("z"); av->componentIsNotPeriodic("z");
+     174         118 :   av->log<<"  WARNING: components will not have the proper periodicity - see manual\n";
+     175             :   return 0;
+     176             : }
+     177             : 
+     178             : // calculator
+     179        8067 : void Position::calculate() {
+     180             : 
+     181        8067 :   std::vector<Vector> distance(1);
+     182        8067 :   if(pbc) {
+     183       16044 :     distance[0]=pbcDistance(Vector(0.0,0.0,0.0),getPosition(0));
+     184             :   } else {
+     185          45 :     distance[0]=delta(Vector(0.0,0.0,0.0),getPosition(0));
+     186             :   }
+     187             : 
+     188        8067 :   if(scaled_components) {
+     189          56 :     calculateCV( 1, masses, charges, distance, value, derivs, virial, this );
+     190          56 :     Value* valuea=getPntrToComponent("a");
+     191          56 :     Value* valueb=getPntrToComponent("b");
+     192          56 :     Value* valuec=getPntrToComponent("c");
+     193          56 :     setAtomsDerivatives (valuea,0,derivs[0][0]);
+     194          56 :     valuea->set(value[0]);
+     195          56 :     setAtomsDerivatives (valueb,0,derivs[1][0]);
+     196          56 :     valueb->set(value[1]);
+     197          56 :     setAtomsDerivatives (valuec,0,derivs[2][0]);
+     198          56 :     valuec->set(value[2]);
+     199             :   } else {
+     200        8011 :     calculateCV( 0, masses, charges, distance, value, derivs, virial, this );
+     201        8011 :     Value* valuex=getPntrToComponent("x");
+     202        8011 :     Value* valuey=getPntrToComponent("y");
+     203        8011 :     Value* valuez=getPntrToComponent("z");
+     204             : 
+     205        8011 :     setAtomsDerivatives (valuex,0,derivs[0][0]);
+     206        8011 :     setBoxDerivatives   (valuex,virial[0]);
+     207        8011 :     valuex->set(value[0]);
+     208             : 
+     209        8011 :     setAtomsDerivatives (valuey,0,derivs[1][0]);
+     210        8011 :     setBoxDerivatives   (valuey,virial[1]);
+     211        8011 :     valuey->set(value[1]);
+     212             : 
+     213        8011 :     setAtomsDerivatives (valuez,0,derivs[2][0]);
+     214        8011 :     setBoxDerivatives   (valuez,virial[2]);
+     215        8011 :     valuez->set(value[2]);
+     216             :   }
+     217        8067 : }
+     218             : 
+     219      151411 : void Position::calculateCV( const unsigned& mode, const std::vector<double>& masses, const std::vector<double>& charges,
+     220             :                             const std::vector<Vector>& pos, std::vector<double>& vals, std::vector<std::vector<Vector> >& derivs,
+     221             :                             std::vector<Tensor>& virial, const ActionAtomistic* aa ) {
+     222      151411 :   if( mode==1 ) {
+     223       10841 :     Vector d=aa->getPbc().realToScaled(pos[0]);
+     224       10841 :     vals[0]=Tools::pbc(d[0]); vals[1]=Tools::pbc(d[1]); vals[2]=Tools::pbc(d[2]);
+     225       10841 :     derivs[0][0]=matmul(aa->getPbc().getInvBox(),Vector(+1,0,0));
+     226       10841 :     derivs[1][0]=matmul(aa->getPbc().getInvBox(),Vector(0,+1,0));
+     227       10841 :     derivs[2][0]=matmul(aa->getPbc().getInvBox(),Vector(0,0,+1));
+     228             :   } else {
+     229      562280 :     for(unsigned i=0; i<3; ++i) vals[i]=pos[0][i];
+     230      140570 :     derivs[0][0]=Vector(+1,0,0); derivs[1][0]=Vector(0,+1,0); derivs[2][0]=Vector(0,0,+1);
+     231      140570 :     virial[0]=Tensor(pos[0],Vector(-1,0,0)); virial[1]=Tensor(pos[0],Vector(0,-1,0)); virial[2]=Tensor(pos[0],Vector(0,0,-1));
+     232             :   }
+     233      151411 : }
+     234             : 
+     235             : }
+     236             : }
+     237             : 
+     238             : 
+     239             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/ProjectionOnAxis.cpp.func-sort-c.html b/coverage/colvar/ProjectionOnAxis.cpp.func-sort-c.html new file mode 100644 index 000000000000..83cbec5b3da0 --- /dev/null +++ b/coverage/colvar/ProjectionOnAxis.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - colvar/ProjectionOnAxis.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - ProjectionOnAxis.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:596295.2 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

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

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

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

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

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

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

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

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

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar4RMSDC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar4RMSDC1ERKNS_13ActionOptionsE81
_ZN4PLMD6colvar4RMSD16registerKeywordsERNS_8KeywordsE83
_ZN4PLMD6colvar4RMSD9calculateEv40516
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/RMSD.cpp.func.html b/coverage/colvar/RMSD.cpp.func.html new file mode 100644 index 000000000000..2524f8e3d6b0 --- /dev/null +++ b/coverage/colvar/RMSD.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - colvar/RMSD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - RMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:404197.6 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar4RMSD16registerKeywordsERNS_8KeywordsE83
_ZN4PLMD6colvar4RMSD9calculateEv40516
_ZN4PLMD6colvar4RMSDC1ERKNS_13ActionOptionsE81
_ZN4PLMD6colvar4RMSDC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/RMSD.cpp.gcov.html b/coverage/colvar/RMSD.cpp.gcov.html new file mode 100644 index 000000000000..4ac8cafa5fcc --- /dev/null +++ b/coverage/colvar/RMSD.cpp.gcov.html @@ -0,0 +1,307 @@ + + + + + + + + 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:404197.6 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar12RMSDShortcutC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar12RMSDShortcutC1ERKNS_13ActionOptionsE104
_ZN4PLMD6colvar12RMSDShortcut16registerKeywordsERNS_8KeywordsE106
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/RMSDShortcut.cpp.func.html b/coverage/colvar/RMSDShortcut.cpp.func.html new file mode 100644 index 000000000000..3c8e0b508675 --- /dev/null +++ b/coverage/colvar/RMSDShortcut.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - colvar/RMSDShortcut.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - RMSDShortcut.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:5252100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar12RMSDShortcut16registerKeywordsERNS_8KeywordsE106
_ZN4PLMD6colvar12RMSDShortcutC1ERKNS_13ActionOptionsE104
_ZN4PLMD6colvar12RMSDShortcutC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/RMSDShortcut.cpp.gcov.html b/coverage/colvar/RMSDShortcut.cpp.gcov.html new file mode 100644 index 000000000000..5891b241b0f6 --- /dev/null +++ b/coverage/colvar/RMSDShortcut.cpp.gcov.html @@ -0,0 +1,183 @@ + + + + + + + + LCOV - plumed test coverage - colvar/RMSDShortcut.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - RMSDShortcut.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:5252100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionShortcut.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "core/ActionWithArguments.h"
+      25             : #include "tools/PDB.h"
+      26             : #include "core/PlumedMain.h"
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace colvar {
+      30             : 
+      31             : class RMSDShortcut : public ActionShortcut {
+      32             : public:
+      33             :   static void registerKeywords(Keywords& keys);
+      34             :   explicit RMSDShortcut(const ActionOptions&);
+      35             : };
+      36             : 
+      37             : PLUMED_REGISTER_ACTION(RMSDShortcut,"RMSD")
+      38             : 
+      39         106 : void RMSDShortcut::registerKeywords(Keywords& keys) {
+      40         106 :   ActionShortcut::registerKeywords( keys );
+      41         212 :   keys.add("compulsory","REFERENCE","a file in pdb format containing the reference structure and the atoms involved in the CV");
+      42         212 :   keys.add("compulsory","TYPE","SIMPLE","the manner in which RMSD alignment is performed.  Should be OPTIMAL or SIMPLE.");
+      43         212 :   keys.addFlag("SQUARED",false," This should be setted if you want MSD instead of RMSD ");
+      44         212 :   keys.addFlag("NOPBC",false,"ignore the periodic boundary conditions when calculating distances");
+      45         212 :   keys.addFlag("NUMERICAL_DERIVATIVES", false, "calculate the derivatives for these quantities numerically");
+      46         212 :   keys.addFlag("DISPLACEMENT",false,"Calculate the vector of displacements instead of the length of this vector");
+      47         212 :   keys.add("compulsory","NUMBER","0","if there are multiple structures in the pdb file you can specify that you want the RMSD from a specific structure by specifying its place in the file here. If NUMBER=0 then the RMSD from all structures are computed");
+      48         212 :   keys.addActionNameSuffix("_SCALAR"); keys.addActionNameSuffix("_VECTOR");
+      49         212 :   keys.needsAction("PDB2CONSTANT"); keys.needsAction("WHOLEMOLECULES");
+      50         212 :   keys.needsAction("POSITION"); keys.needsAction("CONCATENATE");
+      51         106 : }
+      52             : 
+      53         104 : RMSDShortcut::RMSDShortcut(const ActionOptions& ao):
+      54             :   Action(ao),
+      55         104 :   ActionShortcut(ao)
+      56             : {
+      57         208 :   bool disp; parseFlag("DISPLACEMENT",disp);
+      58         106 :   std::string reference; parse("REFERENCE",reference);
+      59             :   // Read the reference pdb file
+      60         106 :   PDB pdb; if( !pdb.read(reference,plumed.usingNaturalUnits(),0.1/plumed.getUnits().getLength()) ) plumed_merror("missing file " + reference );
+      61         103 :   unsigned frame; parse("NUMBER",frame); unsigned nf=1;
+      62         103 :   if( frame==0 ) {
+      63          94 :     FILE* fp=std::fopen(reference.c_str(),"r"); bool do_read=true; nf=0;
+      64         561 :     while ( do_read ) {
+      65         495 :       PDB mypdb; do_read=mypdb.readFromFilepointer(fp,plumed.usingNaturalUnits(),0.1/plumed.getUnits().getLength());
+      66         495 :       if( !do_read && nf>0 ) break ;
+      67         467 :       nf++;
+      68         495 :     }
+      69             :   }
+      70         103 :   bool nopbc; parseFlag("NOPBC",nopbc);
+      71             :   // Now create the RMSD object
+      72         103 :   std::string rmsd_line = getShortcutLabel() + ": ";
+      73         103 :   if( nf==1 && !disp ) {
+      74         162 :     rmsd_line += "RMSD_SCALAR REFERENCE=" + reference; if(nopbc) rmsd_line += " NOPBC";
+      75             :   } else {
+      76          22 :     std::string ffnum; Tools::convert( frame, ffnum );
+      77          44 :     readInputLine( getShortcutLabel() + "_ref: PDB2CONSTANT REFERENCE=" + reference + " NUMBER=" + ffnum );
+      78          22 :     std::vector<AtomNumber> anum( pdb.getAtomNumbers() );
+      79          22 :     if( !nopbc ) {
+      80          20 :       std::string num; Tools::convert( anum[0].serial(), num ); std::string wm_line = "WHOLEMOLECULES ENTITY0=" + num;
+      81         196 :       for(unsigned i=1; i<anum.size(); ++i) { Tools::convert( anum[i].serial(), num ); wm_line += "," + num; }
+      82          20 :       readInputLine( wm_line );
+      83             :     }
+      84          22 :     std::string num; Tools::convert( anum[0].serial(), num ); std::string pos_line = getShortcutLabel() + "_cpos: POSITION NOPBC ATOMS=" + num;
+      85         398 :     for(unsigned i=1; i<anum.size(); ++i) { Tools::convert( anum[i].serial(), num ); pos_line += "," + num; }
+      86          22 :     readInputLine( pos_line );
+      87             :     // Concatenate the three positions together
+      88          44 :     readInputLine( getShortcutLabel() + "_pos: CONCATENATE ARG=" + getShortcutLabel() + "_cpos.x," + getShortcutLabel() + "_cpos.y," + getShortcutLabel() + "_cpos.z");
+      89          44 :     rmsd_line += "RMSD_VECTOR ARG=" + getShortcutLabel() + "_pos," + getShortcutLabel() + "_ref";
+      90          22 :     if( disp ) rmsd_line += " DISPLACEMENT";
+      91             :     // Now align
+      92          22 :     std::vector<double> align( pdb.getOccupancy() ); Tools::convert( align[0], num ); rmsd_line += " ALIGN=" + num;
+      93         210 :     for(unsigned i=1; i<align.size(); ++i) { Tools::convert( align[i], num ); rmsd_line += "," + num; }
+      94             :     // And displace
+      95          22 :     std::vector<double> displace( pdb.getBeta() ); Tools::convert( displace[0], num ); rmsd_line += " DISPLACE=" + num;
+      96         210 :     for(unsigned i=1; i<displace.size(); ++i) { Tools::convert( displace[i], num ); rmsd_line += "," + num; }
+      97             :   }
+      98             :   // And create the RMSD object
+      99         103 :   bool numder; parseFlag("NUMERICAL_DERIVATIVES",numder);
+     100         103 :   if(numder && nf==1 && !disp ) rmsd_line += " NUMERICAL_DERIVATIVES"; else if( numder ) error("can only use NUMERICAL_DERIVATIVES flag when RMSD is calculating a single scalar value");
+     101         207 :   bool squared; parseFlag("SQUARED",squared); if(squared) rmsd_line += " SQUARED";
+     102         310 :   std::string tt; parse("TYPE",tt); readInputLine( rmsd_line + " TYPE=" + tt );
+     103         210 : }
+     104             : 
+     105             : }
+     106             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/RMSDVector.cpp.func-sort-c.html b/coverage/colvar/RMSDVector.cpp.func-sort-c.html new file mode 100644 index 000000000000..7e77bb229d9a --- /dev/null +++ b/coverage/colvar/RMSDVector.cpp.func-sort-c.html @@ -0,0 +1,121 @@ + + + + + + + + LCOV - plumed test coverage - colvar/RMSDVector.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - RMSDVector.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:16116597.6 %
Date:2024-04-19 12:12:35Functions:111291.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar10RMSDVectorC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar10RMSDVectorC1ERKNS_13ActionOptionsE49
_ZN4PLMD6colvar10RMSDVector16registerKeywordsERNS_8KeywordsE51
_ZN4PLMD6colvar10RMSDVector22getNumberOfDerivativesEv804
_ZN4PLMD6colvar10RMSDVector26setReferenceConfigurationsEv10631
_ZN4PLMD6colvar10RMSDVector5applyEv17162
_ZN4PLMD6colvar10RMSDVector9calculateEv17182
_ZNK4PLMD6colvar10RMSDVector25gatherForcesOnStoredValueEPKNS_5ValueERKjRKNS_10MultiValueERSt6vectorIdSaIdEE20442
_ZNK4PLMD6colvar10RMSDVector17checkForTaskForceERKjPKNS_5ValueE160524
_ZNK4PLMD6colvar10RMSDVector11performTaskERKjRNS_10MultiValueE180588
_ZNK4PLMD6colvar10RMSDVector13calculateRMSDERKjRSt6vectorINS_13VectorGenericILj3EEESaIS6_EES9_S9_192996
_ZNK4PLMD6colvar10RMSDVector17gatherStoredValueERKjS3_RKNS_10MultiValueES3_RSt6vectorIdSaIdEE202902
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/RMSDVector.cpp.func.html b/coverage/colvar/RMSDVector.cpp.func.html new file mode 100644 index 000000000000..1f38a236325c --- /dev/null +++ b/coverage/colvar/RMSDVector.cpp.func.html @@ -0,0 +1,121 @@ + + + + + + + + LCOV - plumed test coverage - colvar/RMSDVector.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - RMSDVector.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:16116597.6 %
Date:2024-04-19 12:12:35Functions:111291.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar10RMSDVector16registerKeywordsERNS_8KeywordsE51
_ZN4PLMD6colvar10RMSDVector22getNumberOfDerivativesEv804
_ZN4PLMD6colvar10RMSDVector26setReferenceConfigurationsEv10631
_ZN4PLMD6colvar10RMSDVector5applyEv17162
_ZN4PLMD6colvar10RMSDVector9calculateEv17182
_ZN4PLMD6colvar10RMSDVectorC1ERKNS_13ActionOptionsE49
_ZN4PLMD6colvar10RMSDVectorC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6colvar10RMSDVector11performTaskERKjRNS_10MultiValueE180588
_ZNK4PLMD6colvar10RMSDVector13calculateRMSDERKjRSt6vectorINS_13VectorGenericILj3EEESaIS6_EES9_S9_192996
_ZNK4PLMD6colvar10RMSDVector17checkForTaskForceERKjPKNS_5ValueE160524
_ZNK4PLMD6colvar10RMSDVector17gatherStoredValueERKjS3_RKNS_10MultiValueES3_RSt6vectorIdSaIdEE202902
_ZNK4PLMD6colvar10RMSDVector25gatherForcesOnStoredValueEPKNS_5ValueERKjRKNS_10MultiValueERSt6vectorIdSaIdEE20442
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/RMSDVector.cpp.gcov.html b/coverage/colvar/RMSDVector.cpp.gcov.html new file mode 100644 index 000000000000..d9b39e44aec7 --- /dev/null +++ b/coverage/colvar/RMSDVector.cpp.gcov.html @@ -0,0 +1,367 @@ + + + + + + + + LCOV - plumed test coverage - colvar/RMSDVector.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - RMSDVector.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:16116597.6 %
Date:2024-04-19 12:12:35Functions: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 "RMSDVector.h"
+      23             : #include "core/PlumedMain.h"
+      24             : #include "core/ActionRegister.h"
+      25             : #include "tools/PDB.h"
+      26             : 
+      27             : //+PLUMEDOC DCOLVAR RMSD_VECTOR
+      28             : /*
+      29             : Calculate the RMSD distance between the instaneous configuration and multiple reference configurations
+      30             : 
+      31             : 
+      32             : \par Examples
+      33             : 
+      34             : */
+      35             : //+ENDPLUMEDOC
+      36             : 
+      37             : namespace PLMD {
+      38             : namespace colvar {
+      39             : 
+      40             : PLUMED_REGISTER_ACTION(RMSDVector,"RMSD_VECTOR")
+      41             : 
+      42          51 : void RMSDVector::registerKeywords(Keywords& keys) {
+      43          51 :   ActionWithVector::registerKeywords(keys); keys.use("ARG");
+      44         102 :   keys.add("compulsory","TYPE","SIMPLE","the manner in which RMSD alignment is performed.  Should be OPTIMAL or SIMPLE.");
+      45         102 :   keys.add("compulsory","ALIGN","1.0","the weights to use when aligning to the reference structure");
+      46         102 :   keys.add("compulsory","DISPLACE","1.0","the weights to use when calculating the displacement from the reference structure");
+      47         102 :   keys.addFlag("SQUARED",false," This should be set if you want mean squared displacement instead of RMSD ");
+      48         102 :   keys.addFlag("UNORMALIZED",false,"by default the mean sequare deviation or root mean square deviation is calculated.  If this option is given no averaging is done");
+      49         102 :   keys.addFlag("DISPLACEMENT",false,"Calculate the vector of displacements instead of the length of this vector");
+      50         102 :   keys.addOutputComponent("disp","DISPLACEMENT","the vector of displacements for the atoms");
+      51         102 :   keys.addOutputComponent("dist","DISPLACEMENT","the RMSD distance the atoms have moved");
+      52          51 : }
+      53             : 
+      54          49 : RMSDVector::RMSDVector(const ActionOptions&ao):
+      55             :   Action(ao),
+      56             :   ActionWithVector(ao),
+      57          49 :   firststep(true)
+      58             : {
+      59          49 :   if( getPntrToArgument(0)->getRank()!=1 ) error("first argument should be vector");
+      60          49 :   if( getPntrToArgument(1)->getRank()<1 ) error("second argument should be matrix or a vector");
+      61          49 :   if( getPntrToArgument(1)->getRank()==1 ) {
+      62           7 :     if( getPntrToArgument(0)->getNumberOfValues()!=getPntrToArgument(1)->getNumberOfValues() ) error("mismatch between sizes of input vectors");
+      63          42 :   } else if( getPntrToArgument(1)->getRank()==2 ) {
+      64          42 :     if( getPntrToArgument(0)->getNumberOfValues()!=getPntrToArgument(1)->getShape()[1] ) error("mismatch between sizes of input vectors");
+      65             :   }
+      66          49 :   if( getPntrToArgument(0)->getNumberOfValues()%3!=0 ) error("number of components in input arguments should be multiple of three");
+      67             : 
+      68          49 :   unsigned natoms = getPntrToArgument(0)->getNumberOfValues() / 3;
+      69          98 :   type.assign("SIMPLE"); parse("TYPE",type); parseFlag("SQUARED",squared);
+      70          49 :   align.resize( natoms ); parseVector("ALIGN",align);
+      71          49 :   displace.resize( natoms ); parseVector("DISPLACE",displace);
+      72          98 :   bool unorm=false; parseFlag("UNORMALIZED",unorm); norm_weights=!unorm;
+      73          49 :   double wa=0, wd=0; sqrtdisplace.resize( displace.size() );
+      74         630 :   for(unsigned i=0; i<align.size(); ++i) { wa+=align[i]; wd+=displace[i]; }
+      75             : 
+      76          49 :   if( wa>epsilon ) {
+      77          49 :     double iwa = 1. / wa;
+      78         630 :     for(unsigned i=0; i<align.size(); ++i) align[i] *= iwa;
+      79             :   } else {
+      80           0 :     double iwa = 1. / natoms;
+      81           0 :     for(unsigned i=0; i<align.size(); ++i) align[i] = iwa;
+      82             :   }
+      83          49 :   if( wd>epsilon ) {
+      84          49 :     if( !norm_weights ) { wd = 1; } double iwd = 1. / wd;
+      85         630 :     for(unsigned i=0; i<align.size(); ++i) displace[i] *= iwd;
+      86             :   } else {
+      87           0 :     double iwd = 1. / natoms;
+      88           0 :     for(unsigned i=0; i<align.size(); ++i) displace[i] = iwd;
+      89             :   }
+      90         630 :   for(unsigned i=0; i<align.size(); ++i) sqrtdisplace[i] = sqrt(displace[i]);
+      91             : 
+      92          49 :   parseFlag("DISPLACEMENT",displacement);
+      93          49 :   if( displacement && (getPntrToArgument(1)->getRank()==1 || getPntrToArgument(1)->getShape()[0]<=1) ) {
+      94          78 :     addComponentWithDerivatives("dist"); componentIsNotPeriodic("dist");
+      95          26 :     std::vector<unsigned> shape( 1, getPntrToArgument(0)->getNumberOfValues() );
+      96          78 :     addComponent( "disp", shape ); getPntrToComponent(1)->buildDataStore(); componentIsNotPeriodic("disp");
+      97          23 :   } else if( displacement ) {
+      98           2 :     std::vector<unsigned> shape( 1, getPntrToArgument(1)->getShape()[0] );
+      99           4 :     addComponent( "dist", shape ); getPntrToComponent(0)->buildDataStore();
+     100           2 :     componentIsNotPeriodic("dist");
+     101           2 :     shape.resize(2); shape[0] = getPntrToArgument(1)->getShape()[0]; shape[1] = getPntrToArgument(0)->getNumberOfValues();
+     102           4 :     addComponent( "disp", shape ); getPntrToComponent(1)->buildDataStore(); getPntrToComponent(1)->reshapeMatrixStore( shape[1] );
+     103           4 :     componentIsNotPeriodic("disp");
+     104          21 :   } else if( (getPntrToArgument(1)->getRank()==1 || getPntrToArgument(1)->getShape()[0]==1) ) {
+     105          26 :     addValue(); setNotPeriodic();
+     106             :   } else {
+     107           8 :     std::vector<unsigned> shape( 1, getPntrToArgument(1)->getShape()[0] );
+     108           8 :     addValue( shape ); setNotPeriodic();
+     109             :   }
+     110          49 :   if( getPntrToArgument(1)->getRank()==1 || getPntrToArgument(1)->getNumberOfValues()==0 ) myrmsd.resize(1);
+     111          42 :   else myrmsd.resize( getPntrToArgument(1)->getShape()[0] );
+     112             : 
+     113          49 :   if( getPntrToArgument(1)->getRank()==1 ) log.printf("  calculating RMSD distance between %d atoms. Distance between the avectors of atoms in %s and %s\n",
+     114             :         natoms, getPntrToArgument(0)->getName().c_str(), getPntrToArgument(1)->getName().c_str() );
+     115          42 :   else log.printf("  calculating RMSD distance between %d sets of %d atoms. Distance between vector %s of atoms and matrix of configurations in %s\n",
+     116             :                     getPntrToArgument(1)->getShape()[0], natoms, getPntrToArgument(0)->getName().c_str(), getPntrToArgument(1)->getName().c_str() );
+     117          49 :   log.printf("  method for alignment : %s \n",type.c_str() );
+     118          49 :   if(squared)log.printf("  chosen to use SQUARED option for MSD instead of RMSD\n");
+     119          21 :   else      log.printf("  using periodic boundary conditions\n");
+     120          49 : }
+     121             : 
+     122         804 : unsigned RMSDVector::getNumberOfDerivatives() {
+     123         804 :   return getPntrToArgument(0)->getNumberOfValues() + getPntrToArgument(1)->getNumberOfValues();
+     124             : }
+     125             : 
+     126       10631 : void RMSDVector::setReferenceConfigurations() {
+     127       10631 :   unsigned natoms = getPntrToArgument(0)->getShape()[0] / 3;
+     128       10631 :   Vector center; std::vector<Vector> pos( natoms );
+     129       22578 :   for(unsigned jconf=0; jconf<myrmsd.size(); ++jconf) {
+     130       11947 :     center.zero();
+     131      172431 :     for(unsigned i=0; i<pos.size(); ++i) {
+     132      641936 :       for(unsigned j=0; j<3; ++j) pos[i][j] = getPntrToArgument(1)->get( (3*jconf+j)*pos.size() + i );
+     133      160484 :       center+=pos[i]*align[i];
+     134             :     }
+     135      172431 :     for(unsigned i=0; i<pos.size(); ++i) pos[i] -= center;
+     136       11947 :     myrmsd[jconf].clear(); myrmsd[jconf].set(align,displace,pos,type,true,norm_weights);
+     137             :   }
+     138       10631 : }
+     139             : 
+     140      192996 : double RMSDVector::calculateRMSD( const unsigned& current, std::vector<Vector>& pos, std::vector<Vector>& der, std::vector<Vector>& direction ) const {
+     141      192996 :   unsigned natoms = pos.size();
+     142     2704147 :   for(unsigned i=0; i<natoms; ++i) {
+     143    10044604 :     for(unsigned j=0; j<3; ++j) pos[i][j] = getPntrToArgument(0)->get( j*natoms + i );
+     144             :   }
+     145             : 
+     146      192996 :   if( displacement && type=="SIMPLE" ) {
+     147         646 :     const Value* myval = getConstPntrToComponent(1);
+     148         646 :     double r = myrmsd[current].simpleAlignment( align, displace, pos, myrmsd[current].getReference(), der, direction, squared );
+     149         646 :     if( !doNotCalculateDerivatives() && myval->forcesWereAdded() ) {
+     150          33 :       Vector comforce; comforce.zero();
+     151         187 :       for(unsigned i=0; i<natoms; i++) {
+     152         616 :         for(unsigned k=0; k<3; ++k) comforce[k] += align[i]*myval->getForce( (3*current+k)*natoms + i);
+     153             :       }
+     154         187 :       for(unsigned i=0; i<natoms; i++) {
+     155         616 :         for(unsigned k=0; k<3; ++k) direction[i][k] = myval->getForce( (3*current+k)*natoms + i ) - comforce[k];
+     156             :       }
+     157             :     }
+     158         646 :     return r;
+     159      192350 :   } else if( displacement ) {
+     160       55589 :     const Value* myval = getConstPntrToComponent(1);
+     161      111178 :     Tensor rot; Matrix<std::vector<Vector> > DRotDPos(3,3); std::vector<Vector> centeredpos( natoms ), centeredreference( natoms );
+     162       55589 :     double r = myrmsd[current].calc_PCAelements( pos, der, rot, DRotDPos, direction, centeredpos, centeredreference, squared ); std::vector<Vector> ref( myrmsd[current].getReference() );
+     163       55589 :     if( !doNotCalculateDerivatives() && myval->forcesWereAdded() ) {
+     164        1671 :       Tensor trot=rot.transpose(); double prefactor = 1 / static_cast<double>( natoms ); Vector v1; v1.zero();
+     165       22573 :       for(unsigned n=0; n<natoms; n++) {
+     166       83608 :         Vector ff; for(unsigned k=0; k<3; ++k ) ff[k] = myval->getForce( (3*current+k)*natoms + n );
+     167       20902 :         v1+=prefactor*matmul(trot,ff);
+     168             :       }
+     169             :       // Notice that we use centreredreference here to accumulate the true forces
+     170       22573 :       for(unsigned n=0; n<natoms; n++) {
+     171       83608 :         Vector ff; for(unsigned k=0; k<3; ++k ) ff[k] = myval->getForce( (3*current+k)*natoms + n );
+     172       20902 :         centeredreference[n] = sqrtdisplace[n]*( matmul(trot,ff) - v1 );
+     173             :       }
+     174        6684 :       for(unsigned a=0; a<3; a++) {
+     175       20052 :         for(unsigned b=0; b<3; b++) {
+     176      203157 :           double tmp1=0.; for(unsigned m=0; m<natoms; m++) tmp1+=centeredpos[m][b]*myval->getForce( (3*current+a)*natoms + m );
+     177      203157 :           for(unsigned i=0; i<natoms; i++) centeredreference[i] += sqrtdisplace[i]*tmp1*DRotDPos[a][b][i];
+     178             :         }
+     179             :       }
+     180             :       // Now subtract the current force and add on the true force
+     181       22573 :       for(unsigned n=0; n<natoms; n++) {
+     182       83608 :         for(unsigned k=0; k<3; ++k) direction[n][k] = centeredreference[n][k];
+     183             :       }
+     184             :     } else {
+     185      759226 :       for(unsigned i=0; i<direction.size(); ++i) direction[i] = sqrtdisplace[i]*( direction[i] - ref[i] );
+     186             :     }
+     187             :     return r;
+     188             :   }
+     189      136761 :   return myrmsd[current].calculate( pos, der, squared );
+     190             : }
+     191             : 
+     192             : // calculator
+     193       17182 : void RMSDVector::calculate() {
+     194       17182 :   if( firststep || !getPntrToArgument(1)->isConstant() ) { setReferenceConfigurations(); firststep=false; }
+     195             : 
+     196       17182 :   if( getPntrToComponent(0)->getRank()==0 ) {
+     197       11796 :     unsigned natoms = getPntrToArgument(0)->getShape()[0] / 3;
+     198       11796 :     std::vector<Vector> pos( natoms ), der( natoms ), direction( natoms );
+     199       11796 :     double r = calculateRMSD( 0, pos, der, direction );
+     200             : 
+     201       11796 :     getPntrToComponent(0)->set( r );
+     202       11796 :     if( getNumberOfComponents()==2 ) {
+     203       11775 :       Value* mydisp = getPntrToComponent(1);
+     204      168204 :       for(unsigned i=0; i<natoms; i++) {
+     205      625716 :         for(unsigned j=0; j<3; ++j ) mydisp->set( j*natoms+i, direction[i][j] );
+     206             :       }
+     207             :     }
+     208       11796 :     if( doNotCalculateDerivatives() ) return;
+     209             : 
+     210         612 :     Value* myval = getPntrToComponent(0);
+     211        7472 :     for(unsigned i=0; i<natoms; i++) {
+     212       27440 :       for(unsigned j=0; j<3; ++j ) myval->setDerivative( j*natoms+i, der[i][j] );
+     213             :     }
+     214        5386 :   } else runAllTasks();
+     215             : }
+     216             : 
+     217      160524 : bool RMSDVector::checkForTaskForce( const unsigned& itask, const Value* myval ) const {
+     218      160524 :   if( myval->getRank()<2 ) return ActionWithVector::checkForTaskForce( itask, myval );
+     219       22932 :   unsigned nelements = myval->getShape()[1], startr = itask*nelements;
+     220      874692 :   for(unsigned j=0; j<nelements; ++j ) {
+     221      852852 :     if( fabs( myval->getForce( startr + j ) )>epsilon ) return true;
+     222             :   }
+     223             :   return false;
+     224             : }
+     225             : 
+     226       17162 : void RMSDVector::apply() {
+     227       17162 :   if( doNotCalculateDerivatives() ) return;
+     228             : 
+     229        4980 :   if( getPntrToComponent(0)->getRank()==0 ) {
+     230         612 :     std::vector<double> forces( getNumberOfDerivatives(), 0 );
+     231         612 :     bool wasforced = getPntrToComponent(0)->applyForce( forces );
+     232             : 
+     233         612 :     if( getNumberOfComponents()==2 && getPntrToComponent(1)->forcesWereAdded() ) {
+     234         612 :       unsigned natoms = getPntrToArgument(0)->getShape()[0] / 3;
+     235         612 :       std::vector<Vector> pos( natoms ), der( natoms ), direction( natoms );
+     236         612 :       double r = calculateRMSD( 0, pos, der, direction );
+     237        7472 :       for(unsigned i=0; i<natoms; ++i) {
+     238       27440 :         for(unsigned j=0; j<3; ++j ) forces[j*natoms+i] += direction[i][j];
+     239             :       }
+     240             :       wasforced=true;
+     241             :     }
+     242         612 :     if( wasforced ) { unsigned ss=0; addForcesOnArguments( 0, forces, ss, getLabel() ); }
+     243        4368 :   } else ActionWithVector::apply();
+     244             : }
+     245             : 
+     246      180588 : void RMSDVector::performTask( const unsigned& current, MultiValue& myvals ) const {
+     247      180588 :   unsigned natoms = getPntrToArgument(0)->getShape()[0] / 3;
+     248             :   std::vector<Vector>& pos( myvals.getFirstAtomVector() );
+     249             :   std::vector<std::vector<Vector> > & allder( myvals.getFirstAtomDerivativeVector() );
+     250      180588 :   if( allder.size()!=2 ) allder.resize(2);
+     251             :   std::vector<Vector>& der( allder[0] ); std::vector<Vector>& direction( allder[1] );
+     252      180588 :   if( pos.size()!=natoms ) { pos.resize( natoms ); der.resize( natoms ); direction.resize( natoms ); }
+     253     2528232 :   for(unsigned i=0; i<pos.size(); ++i) {
+     254     9390576 :     for(unsigned j=0; j<3; ++j) pos[i][j] = getPntrToArgument(0)->get( j*natoms + i );
+     255             :   }
+     256      180588 :   double r = calculateRMSD( current, pos, der, direction );
+     257      180588 :   unsigned ostrn = getConstPntrToComponent(0)->getPositionInStream();
+     258      180588 :   myvals.setValue( ostrn, r );
+     259             : 
+     260      180588 :   if( doNotCalculateDerivatives() ) return;
+     261             : 
+     262     1929648 :   for(unsigned i=0; i<natoms; i++) {
+     263     7167264 :     for(unsigned j=0; j<3; ++j ) { myvals.addDerivative( ostrn, j*natoms+i, der[i][j] ); myvals.updateIndex( ostrn, j*natoms+i ); }
+     264             :   }
+     265             : }
+     266             : 
+     267      202902 : void RMSDVector::gatherStoredValue( const unsigned& valindex, const unsigned& code, const MultiValue& myvals,
+     268             :                                     const unsigned& bufstart, std::vector<double>& buffer ) const {
+     269      202902 :   if( getConstPntrToComponent(valindex)->getRank()==1 ) { ActionWithVector::gatherStoredValue( valindex, code, myvals, bufstart, buffer ); return; }
+     270             :   const std::vector<Vector>& direction( myvals.getConstFirstAtomDerivativeVector()[1] );
+     271       42756 :   unsigned natoms = direction.size(); unsigned vindex = bufstart + 3*code*natoms;
+     272      598584 :   for(unsigned i=0; i<natoms; ++i) {
+     273     2223312 :     for(unsigned j=0; j<3; ++j ) buffer[vindex + j*natoms + i] += direction[i][j];
+     274             :   }
+     275             : }
+     276             : 
+     277       20442 : void RMSDVector::gatherForcesOnStoredValue( const Value* myval, const unsigned& itask, const MultiValue& myvals, std::vector<double>& forces ) const {
+     278       20442 :   if( myval->getRank()==1 ) { ActionWithVector::gatherForcesOnStoredValue( myval, itask, myvals, forces ); return; }
+     279        1092 :   const std::vector<Vector>& direction( myvals.getConstFirstAtomDerivativeVector()[1] ); unsigned natoms = direction.size();
+     280       15288 :   for(unsigned i=0; i<natoms; ++i) {
+     281       56784 :     for(unsigned j=0; j<3; ++j ) forces[j*natoms+i] += direction[i][j];
+     282             :   }
+     283             : }
+     284             : 
+     285             : 
+     286             : }
+     287             : }
+     288             : 
+     289             : 
+     290             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/SelectMassCharge.cpp.func-sort-c.html b/coverage/colvar/SelectMassCharge.cpp.func-sort-c.html new file mode 100644 index 000000000000..e281a503f5a2 --- /dev/null +++ b/coverage/colvar/SelectMassCharge.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - colvar/SelectMassCharge.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - SelectMassCharge.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:203557.1 %
Date:2024-04-19 12:12:35Functions:3742.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar16SelectMassCharge13parseAtomListERKiRSt6vectorINS_10AtomNumberESaIS5_EEPNS_15ActionAtomisticE0
_ZN4PLMD6colvar16SelectMassCharge9calculateEv0
_ZN4PLMD6colvar16SelectMassChargeC1ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar16SelectMassChargeC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar16SelectMassCharge21getModeAndSetupValuesEPNS_15ActionWithValueE18
_ZN4PLMD6colvar16SelectMassCharge16registerKeywordsERNS_8KeywordsE48
_ZN4PLMD6colvar16SelectMassCharge11calculateCVERKjRKSt6vectorIdSaIdEES8_RKS4_INS_13VectorGenericILj3EEESaISA_EERS6_RS4_ISC_SaISC_EERS4_INS_13TensorGenericILj3ELj3EEESaISK_EEPKNS_15ActionAtomisticE5144
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/SelectMassCharge.cpp.func.html b/coverage/colvar/SelectMassCharge.cpp.func.html new file mode 100644 index 000000000000..655d69abdaf6 --- /dev/null +++ b/coverage/colvar/SelectMassCharge.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - colvar/SelectMassCharge.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - SelectMassCharge.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:203557.1 %
Date:2024-04-19 12:12:35Functions:3742.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar16SelectMassCharge11calculateCVERKjRKSt6vectorIdSaIdEES8_RKS4_INS_13VectorGenericILj3EEESaISA_EERS6_RS4_ISC_SaISC_EERS4_INS_13TensorGenericILj3ELj3EEESaISK_EEPKNS_15ActionAtomisticE5144
_ZN4PLMD6colvar16SelectMassCharge13parseAtomListERKiRSt6vectorINS_10AtomNumberESaIS5_EEPNS_15ActionAtomisticE0
_ZN4PLMD6colvar16SelectMassCharge16registerKeywordsERNS_8KeywordsE48
_ZN4PLMD6colvar16SelectMassCharge21getModeAndSetupValuesEPNS_15ActionWithValueE18
_ZN4PLMD6colvar16SelectMassCharge9calculateEv0
_ZN4PLMD6colvar16SelectMassChargeC1ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar16SelectMassChargeC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/SelectMassCharge.cpp.gcov.html b/coverage/colvar/SelectMassCharge.cpp.gcov.html new file mode 100644 index 000000000000..3887b52f4d8a --- /dev/null +++ b/coverage/colvar/SelectMassCharge.cpp.gcov.html @@ -0,0 +1,236 @@ + + + + + + + + LCOV - plumed test coverage - colvar/SelectMassCharge.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - SelectMassCharge.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:203557.1 %
Date:2024-04-19 12:12:35Functions:3742.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 "Colvar.h"
+      23             : #include "ColvarShortcut.h"
+      24             : #include "core/ActionRegister.h"
+      25             : #include "MultiColvarTemplate.h"
+      26             : #include "tools/Pbc.h"
+      27             : 
+      28             : //+PLUMEDOC MCOLVAR CHARGE
+      29             : /*
+      30             : Get the charges of one or multiple atoms
+      31             : 
+      32             : \par Examples
+      33             : 
+      34             : */
+      35             : //+ENDPLUMEDOC
+      36             : 
+      37             : //+PLUMEDOC MCOLVAR CHARGE_SCALAR
+      38             : /*
+      39             : Get the charges of one or multiple atoms
+      40             : 
+      41             : \par Examples
+      42             : 
+      43             : */
+      44             : //+ENDPLUMEDOC
+      45             : 
+      46             : //+PLUMEDOC MCOLVAR CHARGE_VECTOR
+      47             : /*
+      48             : Get the charges of one or multiple atoms
+      49             : 
+      50             : \par Examples
+      51             : 
+      52             : */
+      53             : //+ENDPLUMEDOC
+      54             : 
+      55             : //+PLUMEDOC MCOLVAR MASS
+      56             : /*
+      57             : Get the mass of one or multiple atoms
+      58             : 
+      59             : \par Examples
+      60             : 
+      61             : */
+      62             : //+ENDPLUMEDOC
+      63             : 
+      64             : //+PLUMEDOC MCOLVAR MASS_SCALAR
+      65             : /*
+      66             : Get the mass of one or multiple atoms
+      67             : 
+      68             : \par Examples
+      69             : 
+      70             : */
+      71             : //+ENDPLUMEDOC
+      72             : 
+      73             : //+PLUMEDOC MCOLVAR MASS_VECTOR
+      74             : /*
+      75             : Get the mass of one or multiple atoms
+      76             : 
+      77             : \par Examples
+      78             : 
+      79             : */
+      80             : //+ENDPLUMEDOC
+      81             : 
+      82             : namespace PLMD {
+      83             : namespace colvar {
+      84             : 
+      85             : class SelectMassCharge : public Colvar {
+      86             : public:
+      87             :   static void registerKeywords( Keywords& keys );
+      88             :   explicit SelectMassCharge(const ActionOptions&);
+      89             :   static void parseAtomList( const int& num, std::vector<AtomNumber>& t, ActionAtomistic* aa );
+      90             :   static unsigned getModeAndSetupValues( ActionWithValue* av );
+      91             : // active methods:
+      92             :   void calculate() override;
+      93             :   static void calculateCV( const unsigned& mode, const std::vector<double>& masses, const std::vector<double>& charges,
+      94             :                            const std::vector<Vector>& pos, std::vector<double>& vals, std::vector<std::vector<Vector> >& derivs,
+      95             :                            std::vector<Tensor>& virial, const ActionAtomistic* aa );
+      96             : };
+      97             : 
+      98             : typedef ColvarShortcut<SelectMassCharge> MQShortcut;
+      99             : PLUMED_REGISTER_ACTION(MQShortcut,"MASS")
+     100             : PLUMED_REGISTER_ACTION(MQShortcut,"CHARGE")
+     101             : PLUMED_REGISTER_ACTION(SelectMassCharge,"MASS_SCALAR")
+     102             : PLUMED_REGISTER_ACTION(SelectMassCharge,"CHARGE_SCALAR")
+     103             : typedef MultiColvarTemplate<SelectMassCharge> MQMulti;
+     104             : PLUMED_REGISTER_ACTION(MQMulti,"MASS_VECTOR")
+     105             : PLUMED_REGISTER_ACTION(MQMulti,"CHARGE_VECTOR")
+     106             : 
+     107          48 : void SelectMassCharge::registerKeywords( Keywords& keys ) {
+     108          48 :   Colvar::registerKeywords( keys );
+     109          96 :   keys.add("atoms","ATOM","the atom number");
+     110          96 :   keys.add("atoms","ATOMS","the atom numbers that you would like to store the masses and charges of");
+     111          96 :   keys.add("hidden","NO_ACTION_LOG","suppresses printing from action on the log");
+     112          48 : }
+     113             : 
+     114           0 : SelectMassCharge::SelectMassCharge(const ActionOptions&ao):
+     115           0 :   PLUMED_COLVAR_INIT(ao)
+     116             : {
+     117           0 :   std::vector<AtomNumber> atoms; parseAtomList(-1,atoms,this);
+     118           0 :   unsigned mode=getModeAndSetupValues(this);
+     119           0 :   requestAtoms(atoms);
+     120           0 : }
+     121             : 
+     122           0 : void SelectMassCharge::parseAtomList( const int& num, std::vector<AtomNumber>& t, ActionAtomistic* aa ) {
+     123           0 :   aa->parseAtomList("ATOM",num,t);
+     124           0 :   if( t.size()==1 ) aa->log.printf("  for atom %d\n",t[0].serial());
+     125           0 :   else if( num<0 || t.size()!=0 ) aa->error("Number of specified atoms should be 1");
+     126           0 : }
+     127             : 
+     128          18 : unsigned SelectMassCharge::getModeAndSetupValues( ActionWithValue* av ) {
+     129          36 :   av->addValueWithDerivatives(); av->setNotPeriodic(); bool constant=true;
+     130          18 :   ActionAtomistic* aa=dynamic_cast<ActionAtomistic*>( av ); plumed_assert( aa );
+     131        5162 :   for(unsigned i=0; i<aa->getNumberOfAtoms(); ++i) {
+     132        5144 :     std::pair<std::size_t,std::size_t> p = aa->getValueIndices( aa->getAbsoluteIndex(i) );
+     133        5144 :     if( av->getName().find("MASS")!=std::string::npos && !aa->masv[p.first]->isConstant() ) constant=false;
+     134        5144 :     if( av->getName().find("CHARGE")!=std::string::npos && !aa->chargev[p.first]->isConstant() ) constant=false;
+     135             :   }
+     136          18 :   if( !constant ) av->error("cannot deal with non-constant " + av->getName() + " values");
+     137          18 :   (av->copyOutput(0))->setConstant();
+     138          18 :   return 0;
+     139             : }
+     140             : 
+     141             : // calculator
+     142           0 : void SelectMassCharge::calculate() {
+     143           0 :   std::vector<double> masses(1), charges(1), vals(1);
+     144             :   std::vector<Vector> pos; std::vector<std::vector<Vector> > derivs; std::vector<Tensor> virial;
+     145           0 :   calculateCV( 0, masses, charges, pos, vals, derivs, virial, this ); setValue( vals[0] );
+     146           0 : }
+     147             : 
+     148        5144 : void SelectMassCharge::calculateCV( const unsigned& mode, const std::vector<double>& masses, const std::vector<double>& charges,
+     149             :                                     const std::vector<Vector>& pos, std::vector<double>& vals, std::vector<std::vector<Vector> >& derivs,
+     150             :                                     std::vector<Tensor>& virial, const ActionAtomistic* aa ) {
+     151        5144 :   if( aa->getName().find("MASSES")!=std::string::npos ) vals[0]=masses[0];
+     152        5144 :   else if( aa->chargesWereSet ) vals[0]=charges[0];
+     153        5144 : }
+     154             : 
+     155             : }
+     156             : }
+     157             : 
+     158             : 
+     159             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Template.cpp.func-sort-c.html b/coverage/colvar/Template.cpp.func-sort-c.html new file mode 100644 index 000000000000..d6b2d21a20ce --- /dev/null +++ b/coverage/colvar/Template.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - colvar/Template.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Template.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:73420.6 %
Date:2024-04-19 12:12:35Functions:1425.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

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

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

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar7TorsionC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar7TorsionC1ERKNS_13ActionOptionsE665
_ZN4PLMD6colvar7Torsion21getModeAndSetupValuesEPNS_15ActionWithValueE678
_ZN4PLMD6colvar7Torsion13parseAtomListERKiRSt6vectorINS_10AtomNumberESaIS5_EEPNS_15ActionAtomisticE768
_ZN4PLMD6colvar7Torsion16registerKeywordsERNS_8KeywordsE1364
_ZN4PLMD6colvar7Torsion9calculateEv35675
_ZN4PLMD6colvar7Torsion11calculateCVERKjRKSt6vectorIdSaIdEES8_RKS4_INS_13VectorGenericILj3EEESaISA_EERS6_RS4_ISC_SaISC_EERS4_INS_13TensorGenericILj3ELj3EEESaISK_EEPKNS_15ActionAtomisticE36454
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Torsion.cpp.func.html b/coverage/colvar/Torsion.cpp.func.html new file mode 100644 index 000000000000..bcd865d545fb --- /dev/null +++ b/coverage/colvar/Torsion.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - colvar/Torsion.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Torsion.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:9910198.0 %
Date:2024-04-19 12:12:35Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar7Torsion11calculateCVERKjRKSt6vectorIdSaIdEES8_RKS4_INS_13VectorGenericILj3EEESaISA_EERS6_RS4_ISC_SaISC_EERS4_INS_13TensorGenericILj3ELj3EEESaISK_EEPKNS_15ActionAtomisticE36454
_ZN4PLMD6colvar7Torsion13parseAtomListERKiRSt6vectorINS_10AtomNumberESaIS5_EEPNS_15ActionAtomisticE768
_ZN4PLMD6colvar7Torsion16registerKeywordsERNS_8KeywordsE1364
_ZN4PLMD6colvar7Torsion21getModeAndSetupValuesEPNS_15ActionWithValueE678
_ZN4PLMD6colvar7Torsion9calculateEv35675
_ZN4PLMD6colvar7TorsionC1ERKNS_13ActionOptionsE665
_ZN4PLMD6colvar7TorsionC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Torsion.cpp.gcov.html b/coverage/colvar/Torsion.cpp.gcov.html new file mode 100644 index 000000000000..eb84d0aa3f4f --- /dev/null +++ b/coverage/colvar/Torsion.cpp.gcov.html @@ -0,0 +1,338 @@ + + + + + + + + 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:9910198.0 %
Date:2024-04-19 12:12:35Functions: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 "ColvarShortcut.h"
+      24             : #include "MultiColvarTemplate.h"
+      25             : #include "core/ActionRegister.h"
+      26             : #include "tools/Torsion.h"
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace colvar {
+      30             : 
+      31             : //+PLUMEDOC COLVAR TORSION
+      32             : /*
+      33             : Calculate a torsional angle.
+      34             : 
+      35             : This command can be used to compute the torsion between four atoms or alternatively
+      36             : to calculate the angle between two vectors projected on the plane
+      37             : orthogonal to an axis.
+      38             : 
+      39             : \par Examples
+      40             : 
+      41             : This input tells plumed to print the torsional angle between atoms 1, 2, 3 and 4
+      42             : on file COLVAR.
+      43             : \plumedfile
+      44             : t: TORSION ATOMS=1,2,3,4
+      45             : # this is an alternative, equivalent, definition:
+      46             : # t: TORSION VECTOR1=2,1 AXIS=2,3 VECTOR2=3,4
+      47             : PRINT ARG=t FILE=COLVAR
+      48             : \endplumedfile
+      49             : 
+      50             : 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$
+      51             : by using TORSION in combination with the \ref MOLINFO command.  This can be done by using the following
+      52             : syntax.
+      53             : 
+      54             : \plumedfile
+      55             : #SETTINGS MOLFILE=regtest/basic/rt32/helix.pdb
+      56             : MOLINFO MOLTYPE=protein STRUCTURE=myprotein.pdb
+      57             : t1: TORSION ATOMS=@phi-3
+      58             : t2: TORSION ATOMS=@psi-4
+      59             : PRINT ARG=t1,t2 FILE=colvar STRIDE=10
+      60             : \endplumedfile
+      61             : 
+      62             : Here, \@phi-3 tells plumed that you would like to calculate the \f$\phi\f$ angle in the third residue of the protein.
+      63             : Similarly \@psi-4 tells plumed that you want to calculate the \f$\psi\f$ angle of the fourth residue of the protein.
+      64             : 
+      65             : Both of the previous examples specify that the torsion angle should be calculated based on the position of four atoms.
+      66             : For the first example in particular the assumption when the torsion is specified in this way is that there are chemical
+      67             : bonds between atoms 1 and 2, atoms 2 and 3 and atoms 3 and 4. In general, however, a torsional angle measures the angle
+      68             : between two planes, which have at least one vector in common.  As shown below, there is thus an alternate, more general, way
+      69             : through which we can define a torsional angle:
+      70             : 
+      71             : \plumedfile
+      72             : t1: TORSION VECTOR1=1,2 AXIS=3,4 VECTOR2=5,6
+      73             : PRINT ARG=t1 FILE=colvar STRIDE=20
+      74             : \endplumedfile
+      75             : 
+      76             : This input instructs PLUMED to calculate the angle between the plane containing the vector connecting atoms 1 and 2 and the vector
+      77             : connecting atoms 3 and 4 and the plane containing this second vector and the vector connecting atoms 5 and 6.  We can even use
+      78             : PLUMED to calculate the torsional angle between two bond vectors around the z-axis as shown below:
+      79             : 
+      80             : \plumedfile
+      81             : a0: FIXEDATOM AT=0,0,0
+      82             : az: FIXEDATOM AT=0,0,1
+      83             : t1: TORSION VECTOR1=1,2 AXIS=a0,az VECTOR2=5,6
+      84             : PRINT ARG=t1 FILE=colvar STRIDE=20
+      85             : \endplumedfile
+      86             : 
+      87             : 
+      88             : */
+      89             : //+ENDPLUMEDOC
+      90             : 
+      91             : //+PLUMEDOC COLVAR TORSION_SCALAR
+      92             : /*
+      93             : Calculate a torsional angle.
+      94             : 
+      95             : \par Examples
+      96             : 
+      97             : */
+      98             : //+ENDPLUMEDOC
+      99             : 
+     100             : //+PLUMEDOC MCOLVAR TORSION_VECTOR
+     101             : /*
+     102             : Calculate multiple torsional angles.
+     103             : 
+     104             : \par Examples
+     105             : 
+     106             : */
+     107             : //+ENDPLUMEDOC
+     108             : 
+     109             : class Torsion : public Colvar {
+     110             :   bool pbc;
+     111             :   bool do_cosine;
+     112             : 
+     113             :   std::vector<double> value, masses, charges;
+     114             :   std::vector<std::vector<Vector> > derivs;
+     115             :   std::vector<Tensor> virial;
+     116             : public:
+     117             :   explicit Torsion(const ActionOptions&);
+     118             :   static void parseAtomList( const int& num, std::vector<AtomNumber>& t, ActionAtomistic* aa );
+     119             :   static unsigned getModeAndSetupValues( ActionWithValue* av );
+     120             : // active methods:
+     121             :   void calculate() override;
+     122             :   static void calculateCV( const unsigned& mode, const std::vector<double>& masses, const std::vector<double>& charges,
+     123             :                            const std::vector<Vector>& pos, std::vector<double>& vals, std::vector<std::vector<Vector> >& derivs,
+     124             :                            std::vector<Tensor>& virial, const ActionAtomistic* aa );
+     125             :   static void registerKeywords(Keywords& keys);
+     126             : };
+     127             : 
+     128             : typedef ColvarShortcut<Torsion> TorsionShortcut;
+     129             : PLUMED_REGISTER_ACTION(TorsionShortcut,"TORSION")
+     130             : PLUMED_REGISTER_ACTION(Torsion,"TORSION_SCALAR")
+     131             : typedef MultiColvarTemplate<Torsion> TorsionMulti;
+     132             : PLUMED_REGISTER_ACTION(TorsionMulti,"TORSION_VECTOR")
+     133             : 
+     134        1364 : void Torsion::registerKeywords(Keywords& keys) {
+     135        1364 :   Colvar::registerKeywords( keys );
+     136        2728 :   keys.add("atoms-1","ATOMS","the four atoms involved in the torsional angle");
+     137        2728 :   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 VECTORA and VECTORB keywords.");
+     138        2728 :   keys.add("atoms-2","VECTORA","two atoms that define a vector.  You can use this in combination with VECTOR2 and AXIS");
+     139        2728 :   keys.add("atoms-2","VECTORB","two atoms that define a vector.  You can use this in combination with VECTOR1 and AXIS");
+     140        2728 :   keys.add("atoms-3","VECTOR1","two atoms that define a vector.  You can use this in combination with VECTOR2 and AXIS");
+     141        2728 :   keys.add("atoms-3","VECTOR2","two atoms that define a vector.  You can use this in combination with VECTOR1 and AXIS");
+     142        2728 :   keys.addFlag("COSINE",false,"calculate cosine instead of dihedral");
+     143        2728 :   keys.add("hidden","NO_ACTION_LOG","suppresses printing from action on the log");
+     144        1364 : }
+     145             : 
+     146         665 : Torsion::Torsion(const ActionOptions&ao):
+     147             :   PLUMED_COLVAR_INIT(ao),
+     148         665 :   pbc(true),
+     149         665 :   do_cosine(false),
+     150         665 :   value(1),
+     151         667 :   derivs(1),
+     152        1330 :   virial(1)
+     153             : {
+     154         665 :   derivs[0].resize(6); std::vector<AtomNumber> atoms;
+     155        1330 :   std::vector<AtomNumber> v1; ActionAtomistic::parseAtomList("VECTOR1",v1);
+     156         665 :   if( v1.size()>0 ) {
+     157           4 :     std::vector<AtomNumber> v2; ActionAtomistic::parseAtomList("VECTOR2",v2);
+     158           4 :     std::vector<AtomNumber> axis; ActionAtomistic::parseAtomList("AXIS",axis);
+     159           2 :     if( !(v1.size()==2 && v2.size()==2 && axis.size()==2)) error("VECTOR1, VECTOR2 and AXIS should specify 2 atoms each");
+     160           2 :     atoms.resize(6);
+     161           2 :     atoms[0]=v1[1];
+     162           2 :     atoms[1]=v1[0];
+     163           2 :     atoms[2]=axis[0];
+     164           2 :     atoms[3]=axis[1];
+     165           2 :     atoms[4]=v2[0];
+     166           2 :     atoms[5]=v2[1];
+     167           2 :     log.printf("  between lines %d-%d and %d-%d, projected on the plane orthogonal to line %d-%d\n",
+     168             :                v1[0].serial(),v1[1].serial(),v2[0].serial(),v2[1].serial(),axis[0].serial(),axis[1].serial());
+     169         663 :   } else parseAtomList(-1,atoms,this);
+     170         664 :   unsigned mode=getModeAndSetupValues(this);
+     171         664 :   if( mode==1 ) do_cosine=true;
+     172             : 
+     173         664 :   bool nopbc=!pbc;
+     174         666 :   parseFlag("NOPBC",nopbc);
+     175         664 :   pbc=!nopbc;
+     176         664 :   checkRead();
+     177             : 
+     178         663 :   if(pbc) log.printf("  using periodic boundary conditions\n");
+     179         112 :   else    log.printf("  without periodic boundary conditions\n");
+     180         663 :   requestAtoms(atoms);
+     181         669 : }
+     182             : 
+     183         768 : void Torsion::parseAtomList( const int& num, std::vector<AtomNumber>& t, ActionAtomistic* aa ) {
+     184             :   std::vector<AtomNumber> v1,v2,axis;
+     185         768 :   aa->parseAtomList("ATOMS",num,t);
+     186         768 :   aa->parseAtomList("VECTORA",num,v1);
+     187         768 :   aa->parseAtomList("VECTORB",num,v2);
+     188        1536 :   aa->parseAtomList("AXIS",num,axis);
+     189             : 
+     190         768 :   if(t.size()==4) {
+     191         721 :     if(!(v1.empty() && v2.empty() && axis.empty()))
+     192           0 :       aa->error("ATOMS keyword is not compatible with VECTORA, VECTORB and AXIS keywords");
+     193         721 :     aa->log.printf("  between atoms %d %d %d %d\n",t[0].serial(),t[1].serial(),t[2].serial(),t[3].serial());
+     194         721 :     t.resize(6);
+     195         721 :     t[5]=t[3];
+     196         721 :     t[4]=t[2];
+     197         721 :     t[3]=t[2];
+     198         721 :     t[2]=t[1];
+     199          47 :   } else if(t.empty()) {
+     200          46 :     if( num>0 && v1.empty() && v2.empty() && axis.empty() ) return;
+     201          32 :     if(!(v1.size()==2 && v2.size()==2 && axis.size()==2))
+     202           0 :       aa->error("VECTORA, VECTORB and AXIS should specify 2 atoms each");
+     203          32 :     aa->log.printf("  between lines %d-%d and %d-%d, projected on the plane orthogonal to line %d-%d\n",
+     204             :                    v1[0].serial(),v1[1].serial(),v2[0].serial(),v2[1].serial(),axis[0].serial(),axis[1].serial());
+     205          32 :     t.resize(6);
+     206          32 :     t[0]=v1[1];
+     207          32 :     t[1]=v1[0];
+     208          32 :     t[2]=axis[0];
+     209          32 :     t[3]=axis[1];
+     210          32 :     t[4]=v2[0];
+     211          32 :     t[5]=v2[1];
+     212           2 :   } else if( t.size()!=4 ) aa->error("ATOMS should specify 4 atoms");
+     213             : }
+     214             : 
+     215         678 : unsigned Torsion::getModeAndSetupValues( ActionWithValue* av ) {
+     216         678 :   bool do_cos; av->parseFlag("COSINE",do_cos);
+     217         678 :   if(do_cos) av->log.printf("  calculating cosine instead of torsion\n");
+     218             : 
+     219         678 :   av->addValueWithDerivatives();
+     220        1352 :   if(!do_cos) { av->setPeriodic("-pi","pi"); return 0; }
+     221           4 :   av->setNotPeriodic(); return 1;
+     222             : }
+     223             : 
+     224             : // calculator
+     225       35675 : void Torsion::calculate() {
+     226       35675 :   if(pbc) makeWhole();
+     227       35675 :   if(do_cosine) calculateCV( 1, masses, charges, getPositions(), value, derivs, virial, this );
+     228       35660 :   else calculateCV( 0, masses, charges, getPositions(), value, derivs, virial, this );
+     229      249725 :   for(unsigned i=0; i<6; ++i) setAtomsDerivatives(i,derivs[0][i] );
+     230       35675 :   setValue(value[0]); setBoxDerivatives( virial[0] );
+     231       35675 : }
+     232             : 
+     233       36454 : void Torsion::calculateCV( const unsigned& mode, const std::vector<double>& masses, const std::vector<double>& charges,
+     234             :                            const std::vector<Vector>& pos, std::vector<double>& vals, std::vector<std::vector<Vector> >& derivs,
+     235             :                            std::vector<Tensor>& virial, const ActionAtomistic* aa ) {
+     236       36454 :   Vector d0=delta(pos[1],pos[0]);
+     237       36454 :   Vector d1=delta(pos[3],pos[2]);
+     238       36454 :   Vector d2=delta(pos[5],pos[4]);
+     239       36454 :   Vector dd0,dd1,dd2;
+     240             :   PLMD::Torsion t;
+     241       36454 :   vals[0] = t.compute(d0,d1,d2,dd0,dd1,dd2);
+     242       36454 :   if(mode==1) {
+     243          30 :     dd0 *= -std::sin(vals[0]);
+     244          30 :     dd1 *= -std::sin(vals[0]);
+     245          30 :     dd2 *= -std::sin(vals[0]);
+     246          30 :     vals[0] = std::cos(vals[0]);
+     247             :   }
+     248       36454 :   derivs[0][0] = dd0;
+     249       36454 :   derivs[0][1] = -dd0;
+     250       36454 :   derivs[0][2] = dd1;
+     251       36454 :   derivs[0][3] = -dd1;
+     252       36454 :   derivs[0][4] = dd2;
+     253       36454 :   derivs[0][5] = -dd2;
+     254       36454 :   setBoxDerivativesNoPbc( pos, derivs, virial );
+     255       36454 : }
+     256             : 
+     257             : }
+     258             : }
+     259             : 
+     260             : 
+     261             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Volume.cpp.func-sort-c.html b/coverage/colvar/Volume.cpp.func-sort-c.html new file mode 100644 index 000000000000..4ef88db58754 --- /dev/null +++ b/coverage/colvar/Volume.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - colvar/Volume.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Volume.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1616100.0 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar6VolumeC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar6VolumeC1ERKNS_13ActionOptionsE15
_ZN4PLMD6colvar6Volume16registerKeywordsERNS_8KeywordsE17
_ZN4PLMD6colvar6Volume9calculateEv163
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Volume.cpp.func.html b/coverage/colvar/Volume.cpp.func.html new file mode 100644 index 000000000000..3683ecace1cf --- /dev/null +++ b/coverage/colvar/Volume.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - colvar/Volume.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Volume.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1616100.0 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar6Volume16registerKeywordsERNS_8KeywordsE17
_ZN4PLMD6colvar6Volume9calculateEv163
_ZN4PLMD6colvar6VolumeC1ERKNS_13ActionOptionsE15
_ZN4PLMD6colvar6VolumeC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Volume.cpp.gcov.html b/coverage/colvar/Volume.cpp.gcov.html new file mode 100644 index 000000000000..86c2e2a3205c --- /dev/null +++ b/coverage/colvar/Volume.cpp.gcov.html @@ -0,0 +1,162 @@ + + + + + + + + LCOV - plumed test coverage - colvar/Volume.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Volume.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1616100.0 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ + + + + + + + +

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

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Template.cpp +
20.6%20.6%
+
20.6 %7 / 3425.0 %1 / 4
SelectMassCharge.cpp +
57.1%57.1%
+
57.1 %20 / 3542.9 %3 / 7
Fake.cpp +
81.1%81.1%
+
81.1 %30 / 3750.0 %2 / 4
Plane.cpp +
65.7%65.7%
+
65.7 %46 / 7057.1 %4 / 7
DihedralCorrelation.cpp +
67.2%67.2%
+
67.2 %43 / 6457.1 %4 / 7
ContactMap.cpp +
91.6%91.6%
+
91.6 %120 / 13160.0 %3 / 5
CoordinationBase.cpp +
98.9%98.9%
+
98.9 %89 / 9062.5 %5 / 8
PathMSDBase.cpp +
97.8%97.8%
+
97.8 %180 / 18462.5 %5 / 8
RMSDShortcut.cpp +
100.0%
+
100.0 %52 / 5266.7 %2 / 3
DRMSD.cpp +
97.0%97.0%
+
97.0 %97 / 10066.7 %2 / 3
PathMSD.cpp +
100.0%
+
100.0 %20 / 2066.7 %2 / 3
MultiRMSD.cpp +
90.9%90.9%
+
90.9 %50 / 5566.7 %2 / 3
ExtraCV.cpp +
100.0%
+
100.0 %11 / 1166.7 %2 / 3
PropertyMap.cpp +
92.6%92.6%
+
92.6 %25 / 2766.7 %2 / 3
GyrationShortcut.cpp +
54.9%54.9%
+
54.9 %50 / 9166.7 %2 / 3
Coordination.cpp +
100.0%
+
100.0 %29 / 2975.0 %3 / 4
GHBFIX.cpp +
100.0%
+
100.0 %76 / 7675.0 %3 / 4
Volume.cpp +
100.0%
+
100.0 %16 / 1675.0 %3 / 4
ProjectionOnAxis.cpp +
95.2%95.2%
+
95.2 %59 / 6275.0 %3 / 4
Gyration.cpp +
77.6%77.6%
+
77.6 %142 / 18375.0 %3 / 4
Cell.cpp +
100.0%
+
100.0 %35 / 3575.0 %3 / 4
DHEnergy.cpp +
93.9%93.9%
+
93.9 %31 / 3375.0 %3 / 4
ERMSD.cpp +
98.0%98.0%
+
98.0 %50 / 5175.0 %3 / 4
RMSD.cpp +
97.6%97.6%
+
97.6 %40 / 4175.0 %3 / 4
Energy.cpp +
100.0%
+
100.0 %31 / 3180.0 %4 / 5
Dimer.cpp +
92.1%92.1%
+
92.1 %82 / 8980.0 %4 / 5
PCARMSD.cpp +
98.9%98.9%
+
98.9 %93 / 9480.0 %4 / 5
Puckering.cpp +
99.6%99.6%
+
99.6 %228 / 22983.3 %5 / 6
Position.cpp +
100.0%
+
100.0 %90 / 9085.7 %6 / 7
Distance.cpp +
100.0%
+
100.0 %119 / 11985.7 %6 / 7
Dipole.cpp +
98.8%98.8%
+
98.8 %83 / 8485.7 %6 / 7
Angle.cpp +
98.0%98.0%
+
98.0 %50 / 5185.7 %6 / 7
Torsion.cpp +
98.0%98.0%
+
98.0 %99 / 10185.7 %6 / 7
EEFSolv.cpp +
94.2%94.2%
+
94.2 %229 / 24387.5 %7 / 8
MultiColvarTemplate.h +
97.8%97.8%
+
97.8 %91 / 9390.3 %65 / 72
RMSDVector.cpp +
97.6%97.6%
+
97.6 %161 / 16591.7 %11 / 12
PathMSDBase.h +
50.0%50.0%
+
50.0 %1 / 2-0 / 0
ColvarShortcut.h +
100.0%
+
100.0 %21 / 21100.0 %18 / 18
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/index-sort-l.html b/coverage/colvar/index-sort-l.html new file mode 100644 index 000000000000..5b3511d56d32 --- /dev/null +++ b/coverage/colvar/index-sort-l.html @@ -0,0 +1,464 @@ + + + + + + + + LCOV - plumed test coverage - colvar + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvarHitTotalCoverage
Test:plumed test coverageLines:2696293991.7 %
Date:2024-04-19 12:12:35Functions:21627379.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Template.cpp +
20.6%20.6%
+
20.6 %7 / 3425.0 %1 / 4
PathMSDBase.h +
50.0%50.0%
+
50.0 %1 / 2-0 / 0
GyrationShortcut.cpp +
54.9%54.9%
+
54.9 %50 / 9166.7 %2 / 3
SelectMassCharge.cpp +
57.1%57.1%
+
57.1 %20 / 3542.9 %3 / 7
Plane.cpp +
65.7%65.7%
+
65.7 %46 / 7057.1 %4 / 7
DihedralCorrelation.cpp +
67.2%67.2%
+
67.2 %43 / 6457.1 %4 / 7
Gyration.cpp +
77.6%77.6%
+
77.6 %142 / 18375.0 %3 / 4
Fake.cpp +
81.1%81.1%
+
81.1 %30 / 3750.0 %2 / 4
MultiRMSD.cpp +
90.9%90.9%
+
90.9 %50 / 5566.7 %2 / 3
ContactMap.cpp +
91.6%91.6%
+
91.6 %120 / 13160.0 %3 / 5
Dimer.cpp +
92.1%92.1%
+
92.1 %82 / 8980.0 %4 / 5
PropertyMap.cpp +
92.6%92.6%
+
92.6 %25 / 2766.7 %2 / 3
DHEnergy.cpp +
93.9%93.9%
+
93.9 %31 / 3375.0 %3 / 4
EEFSolv.cpp +
94.2%94.2%
+
94.2 %229 / 24387.5 %7 / 8
ProjectionOnAxis.cpp +
95.2%95.2%
+
95.2 %59 / 6275.0 %3 / 4
DRMSD.cpp +
97.0%97.0%
+
97.0 %97 / 10066.7 %2 / 3
RMSD.cpp +
97.6%97.6%
+
97.6 %40 / 4175.0 %3 / 4
RMSDVector.cpp +
97.6%97.6%
+
97.6 %161 / 16591.7 %11 / 12
MultiColvarTemplate.h +
97.8%97.8%
+
97.8 %91 / 9390.3 %65 / 72
PathMSDBase.cpp +
97.8%97.8%
+
97.8 %180 / 18462.5 %5 / 8
ERMSD.cpp +
98.0%98.0%
+
98.0 %50 / 5175.0 %3 / 4
Angle.cpp +
98.0%98.0%
+
98.0 %50 / 5185.7 %6 / 7
Torsion.cpp +
98.0%98.0%
+
98.0 %99 / 10185.7 %6 / 7
Dipole.cpp +
98.8%98.8%
+
98.8 %83 / 8485.7 %6 / 7
CoordinationBase.cpp +
98.9%98.9%
+
98.9 %89 / 9062.5 %5 / 8
PCARMSD.cpp +
98.9%98.9%
+
98.9 %93 / 9480.0 %4 / 5
Puckering.cpp +
99.6%99.6%
+
99.6 %228 / 22983.3 %5 / 6
ExtraCV.cpp +
100.0%
+
100.0 %11 / 1166.7 %2 / 3
Volume.cpp +
100.0%
+
100.0 %16 / 1675.0 %3 / 4
PathMSD.cpp +
100.0%
+
100.0 %20 / 2066.7 %2 / 3
ColvarShortcut.h +
100.0%
+
100.0 %21 / 21100.0 %18 / 18
Coordination.cpp +
100.0%
+
100.0 %29 / 2975.0 %3 / 4
Energy.cpp +
100.0%
+
100.0 %31 / 3180.0 %4 / 5
Cell.cpp +
100.0%
+
100.0 %35 / 3575.0 %3 / 4
RMSDShortcut.cpp +
100.0%
+
100.0 %52 / 5266.7 %2 / 3
GHBFIX.cpp +
100.0%
+
100.0 %76 / 7675.0 %3 / 4
Position.cpp +
100.0%
+
100.0 %90 / 9085.7 %6 / 7
Distance.cpp +
100.0%
+
100.0 %119 / 11985.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 000000000000..4dae97c07aac --- /dev/null +++ b/coverage/colvar/index.html @@ -0,0 +1,464 @@ + + + + + + + + LCOV - plumed test coverage - colvar + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvarHitTotalCoverage
Test:plumed test coverageLines:2696293991.7 %
Date:2024-04-19 12:12:35Functions:21627379.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Angle.cpp +
98.0%98.0%
+
98.0 %50 / 5185.7 %6 / 7
Cell.cpp +
100.0%
+
100.0 %35 / 3575.0 %3 / 4
ColvarShortcut.h +
100.0%
+
100.0 %21 / 21100.0 %18 / 18
ContactMap.cpp +
91.6%91.6%
+
91.6 %120 / 13160.0 %3 / 5
Coordination.cpp +
100.0%
+
100.0 %29 / 2975.0 %3 / 4
CoordinationBase.cpp +
98.9%98.9%
+
98.9 %89 / 9062.5 %5 / 8
DHEnergy.cpp +
93.9%93.9%
+
93.9 %31 / 3375.0 %3 / 4
DRMSD.cpp +
97.0%97.0%
+
97.0 %97 / 10066.7 %2 / 3
DihedralCorrelation.cpp +
67.2%67.2%
+
67.2 %43 / 6457.1 %4 / 7
Dimer.cpp +
92.1%92.1%
+
92.1 %82 / 8980.0 %4 / 5
Dipole.cpp +
98.8%98.8%
+
98.8 %83 / 8485.7 %6 / 7
Distance.cpp +
100.0%
+
100.0 %119 / 11985.7 %6 / 7
EEFSolv.cpp +
94.2%94.2%
+
94.2 %229 / 24387.5 %7 / 8
ERMSD.cpp +
98.0%98.0%
+
98.0 %50 / 5175.0 %3 / 4
Energy.cpp +
100.0%
+
100.0 %31 / 3180.0 %4 / 5
ExtraCV.cpp +
100.0%
+
100.0 %11 / 1166.7 %2 / 3
Fake.cpp +
81.1%81.1%
+
81.1 %30 / 3750.0 %2 / 4
GHBFIX.cpp +
100.0%
+
100.0 %76 / 7675.0 %3 / 4
Gyration.cpp +
77.6%77.6%
+
77.6 %142 / 18375.0 %3 / 4
GyrationShortcut.cpp +
54.9%54.9%
+
54.9 %50 / 9166.7 %2 / 3
MultiColvarTemplate.h +
97.8%97.8%
+
97.8 %91 / 9390.3 %65 / 72
MultiRMSD.cpp +
90.9%90.9%
+
90.9 %50 / 5566.7 %2 / 3
PCARMSD.cpp +
98.9%98.9%
+
98.9 %93 / 9480.0 %4 / 5
PathMSD.cpp +
100.0%
+
100.0 %20 / 2066.7 %2 / 3
PathMSDBase.cpp +
97.8%97.8%
+
97.8 %180 / 18462.5 %5 / 8
PathMSDBase.h +
50.0%50.0%
+
50.0 %1 / 2-0 / 0
Plane.cpp +
65.7%65.7%
+
65.7 %46 / 7057.1 %4 / 7
Position.cpp +
100.0%
+
100.0 %90 / 9085.7 %6 / 7
ProjectionOnAxis.cpp +
95.2%95.2%
+
95.2 %59 / 6275.0 %3 / 4
PropertyMap.cpp +
92.6%92.6%
+
92.6 %25 / 2766.7 %2 / 3
Puckering.cpp +
99.6%99.6%
+
99.6 %228 / 22983.3 %5 / 6
RMSD.cpp +
97.6%97.6%
+
97.6 %40 / 4175.0 %3 / 4
RMSDShortcut.cpp +
100.0%
+
100.0 %52 / 5266.7 %2 / 3
RMSDVector.cpp +
97.6%97.6%
+
97.6 %161 / 16591.7 %11 / 12
SelectMassCharge.cpp +
57.1%57.1%
+
57.1 %20 / 3542.9 %3 / 7
Template.cpp +
20.6%20.6%
+
20.6 %7 / 3425.0 %1 / 4
Torsion.cpp +
98.0%98.0%
+
98.0 %99 / 10185.7 %6 / 7
Volume.cpp +
100.0%
+
100.0 %16 / 1675.0 %3 / 4
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/config/Config.inc.func-sort-c.html b/coverage/config/Config.inc.func-sort-c.html new file mode 100644 index 000000000000..702368342b76 --- /dev/null +++ b/coverage/config/Config.inc.func-sort-c.html @@ -0,0 +1,173 @@ + + + + + + + + LCOV - plumed test coverage - config/Config.inc - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - config - Config.inc (source / functions)HitTotalCoverage
Test:plumed test coverageLines:86811.8 %
Date:2024-04-19 12:12:35Functions:32512.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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

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

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6config10getVersionB5cxx11Ev0
_ZN4PLMD6config10hasMolfileEv0
_ZN4PLMD6config11hasMathevalEv0
_ZN4PLMD6config18hasExternalMolfileEv0
_ZN4PLMD6config7hasZlibEv0
_ZN4PLMD6config9hasCregexEv0
_ZN4PLMD6config9hasDlopenEv0
_ZN4PLMD6config11getMakefileB5cxx11Ev35
_ZN4PLMD6config13getEnvCommandB5cxx11Ev834
_ZN4PLMD6config14plumed_htmldirEv834
_ZN4PLMD6config16getPlumedHtmldirB5cxx11Ev834
_ZN4PLMD6config17plumed_includedirEv834
_ZN4PLMD6config19getPlumedIncludedirB5cxx11Ev834
_ZN4PLMD6config19plumed_program_nameEv834
_ZN4PLMD6config20getPlumedProgramNameB5cxx11Ev834
_ZN4PLMD6config13getVersionGitB5cxx11Ev1186
_ZN4PLMD6config14getLibraryPathB5cxx11Ev1186
_ZN4PLMD6config18getCompilationDateB5cxx11Ev1186
_ZN4PLMD6config18getCompilationTimeB5cxx11Ev1186
_ZN4PLMD6config12plumed_soextEv1501
_ZN4PLMD6config8getSoExtB5cxx11Ev1501
_ZN4PLMD6config14getVersionLongB5cxx11Ev2024
_ZN4PLMD6config11isInstalledEv3267
_ZN4PLMD6config11plumed_rootEv8666
_ZN4PLMD6config13getPlumedRootB5cxx11Ev8666
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/config/ConfigInstall.inc.func.html b/coverage/config/ConfigInstall.inc.func.html new file mode 100644 index 000000000000..91cab364ab1d --- /dev/null +++ b/coverage/config/ConfigInstall.inc.func.html @@ -0,0 +1,173 @@ + + + + + + + + LCOV - plumed test coverage - config/ConfigInstall.inc - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - config - ConfigInstall.inc (source / functions)HitTotalCoverage
Test:plumed test coverageLines:496872.1 %
Date:2024-04-19 12:12:35Functions:182572.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6config10getVersionB5cxx11Ev0
_ZN4PLMD6config10hasMolfileEv0
_ZN4PLMD6config11getMakefileB5cxx11Ev35
_ZN4PLMD6config11hasMathevalEv0
_ZN4PLMD6config11isInstalledEv3267
_ZN4PLMD6config11plumed_rootEv8666
_ZN4PLMD6config12plumed_soextEv1501
_ZN4PLMD6config13getEnvCommandB5cxx11Ev834
_ZN4PLMD6config13getPlumedRootB5cxx11Ev8666
_ZN4PLMD6config13getVersionGitB5cxx11Ev1186
_ZN4PLMD6config14getLibraryPathB5cxx11Ev1186
_ZN4PLMD6config14getVersionLongB5cxx11Ev2024
_ZN4PLMD6config14plumed_htmldirEv834
_ZN4PLMD6config16getPlumedHtmldirB5cxx11Ev834
_ZN4PLMD6config17plumed_includedirEv834
_ZN4PLMD6config18getCompilationDateB5cxx11Ev1186
_ZN4PLMD6config18getCompilationTimeB5cxx11Ev1186
_ZN4PLMD6config18hasExternalMolfileEv0
_ZN4PLMD6config19getPlumedIncludedirB5cxx11Ev834
_ZN4PLMD6config19plumed_program_nameEv834
_ZN4PLMD6config20getPlumedProgramNameB5cxx11Ev834
_ZN4PLMD6config7hasZlibEv0
_ZN4PLMD6config8getSoExtB5cxx11Ev1501
_ZN4PLMD6config9hasCregexEv0
_ZN4PLMD6config9hasDlopenEv0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/config/ConfigInstall.inc.gcov.html b/coverage/config/ConfigInstall.inc.gcov.html new file mode 100644 index 000000000000..d05b4de0cc78 --- /dev/null +++ b/coverage/config/ConfigInstall.inc.gcov.html @@ -0,0 +1,273 @@ + + + + + + + + LCOV - plumed test coverage - config/ConfigInstall.inc + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - config - ConfigInstall.inc (source / functions)HitTotalCoverage
Test:plumed test coverageLines:496872.1 %
Date:2024-04-19 12:12:35Functions:182572.0 %
+
+ + + + + + + + +

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

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

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

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Config.inc +
11.8%11.8%
+
11.8 %8 / 6812.0 %3 / 25
ConfigInstall.inc +
72.1%72.1%
+
72.1 %49 / 6872.0 %18 / 25
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/contour/ContourFindingBase.cpp.func-sort-c.html b/coverage/contour/ContourFindingBase.cpp.func-sort-c.html new file mode 100644 index 000000000000..3b4c78bf037a --- /dev/null +++ b/coverage/contour/ContourFindingBase.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - contour/ContourFindingBase.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - contour - ContourFindingBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1313100.0 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7contour18ContourFindingBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD7contour18ContourFindingBase16setupOnFirstStepEb3
_ZN4PLMD7contour18ContourFindingBaseC2ERKNS_13ActionOptionsE3
_ZN4PLMD7contour18ContourFindingBase16registerKeywordsERNS_8KeywordsE9
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/contour/ContourFindingBase.cpp.func.html b/coverage/contour/ContourFindingBase.cpp.func.html new file mode 100644 index 000000000000..795ff64d59db --- /dev/null +++ b/coverage/contour/ContourFindingBase.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - contour/ContourFindingBase.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - contour - ContourFindingBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1313100.0 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7contour18ContourFindingBase16registerKeywordsERNS_8KeywordsE9
_ZN4PLMD7contour18ContourFindingBase16setupOnFirstStepEb3
_ZN4PLMD7contour18ContourFindingBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD7contour18ContourFindingBaseC2ERKNS_13ActionOptionsE3
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/contour/ContourFindingBase.cpp.gcov.html b/coverage/contour/ContourFindingBase.cpp.gcov.html new file mode 100644 index 000000000000..8849f3dcb7e6 --- /dev/null +++ b/coverage/contour/ContourFindingBase.cpp.gcov.html @@ -0,0 +1,124 @@ + + + + + + + + LCOV - plumed test coverage - contour/ContourFindingBase.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - contour - ContourFindingBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1313100.0 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2020 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received 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 contour {
+      26             : 
+      27           9 : void ContourFindingBase::registerKeywords( Keywords& keys ) {
+      28           9 :   gridtools::ActionWithGrid::registerKeywords( keys ); keys.use("ARG");
+      29          18 :   keys.add("compulsory","CONTOUR","the value we would like to draw the contour at in the space");
+      30           9 :   gridtools::EvaluateGridFunction gg; gg.registerKeywords(keys);
+      31           9 : }
+      32             : 
+      33           3 : ContourFindingBase::ContourFindingBase(const ActionOptions&ao):
+      34             :   Action(ao),
+      35             :   ActionWithGrid(ao),
+      36           3 :   mymin(this)
+      37             : {
+      38           6 :   parse("CONTOUR",contour); function.read( this );
+      39           3 :   log.printf("  calculating dividing surface along which function equals %f \n", contour);
+      40           3 : }
+      41             : 
+      42           3 : void ContourFindingBase::setupOnFirstStep( const bool incalc ) {
+      43           3 :   function.setup( this ); setupValuesOnFirstStep();
+      44           3 : }
+      45             : 
+      46             : }
+      47             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/contour/ContourFindingBase.h.func-sort-c.html b/coverage/contour/ContourFindingBase.h.func-sort-c.html new file mode 100644 index 000000000000..471eb531c854 --- /dev/null +++ b/coverage/contour/ContourFindingBase.h.func-sort-c.html @@ -0,0 +1,77 @@ + + + + + + + + LCOV - plumed test coverage - contour/ContourFindingBase.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - contour - ContourFindingBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:66100.0 %
Date:2024-04-19 12:12:35Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD7contour18ContourFindingBase24getDifferenceFromContourERKSt6vectorIdSaIdEERS4_13479
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/contour/ContourFindingBase.h.func.html b/coverage/contour/ContourFindingBase.h.func.html new file mode 100644 index 000000000000..5585b960355d --- /dev/null +++ b/coverage/contour/ContourFindingBase.h.func.html @@ -0,0 +1,77 @@ + + + + + + + + LCOV - plumed test coverage - contour/ContourFindingBase.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - contour - ContourFindingBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:66100.0 %
Date:2024-04-19 12:12:35Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD7contour18ContourFindingBase24getDifferenceFromContourERKSt6vectorIdSaIdEERS4_13479
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/contour/ContourFindingBase.h.gcov.html b/coverage/contour/ContourFindingBase.h.gcov.html new file mode 100644 index 000000000000..217c727152df --- /dev/null +++ b/coverage/contour/ContourFindingBase.h.gcov.html @@ -0,0 +1,150 @@ + + + + + + + + LCOV - plumed test coverage - contour/ContourFindingBase.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - contour - ContourFindingBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:66100.0 %
Date:2024-04-19 12:12:35Functions: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_contour_ContourFindingBase_h
+      23             : #define __PLUMED_contour_ContourFindingBase_h
+      24             : 
+      25             : #include "tools/RootFindingBase.h"
+      26             : #include "gridtools/ActionWithGrid.h"
+      27             : #include "gridtools/EvaluateGridFunction.h"
+      28             : 
+      29             : namespace PLMD {
+      30             : namespace contour {
+      31             : 
+      32             : class ContourFindingBase : public gridtools::ActionWithGrid {
+      33             : private:
+      34             : /// This is the object that does the root finding
+      35             :   RootFindingBase<ContourFindingBase> mymin;
+      36             : /// This holds the input grid
+      37             :   gridtools::EvaluateGridFunction function;
+      38             : protected:
+      39             : /// Where you would like to find the contour
+      40             :   double contour;
+      41             : /// Find a contour along line specified by direction
+      42             :   void findContour( const std::vector<double>& direction, std::vector<double>& point ) const ;
+      43             : /// Get the input grid object for the grid that we are finding the contour in
+      44             :   const gridtools::GridCoordinatesObject& getInputGridObject() const ;
+      45             : public:
+      46             :   static void registerKeywords( Keywords& keys );
+      47             :   explicit ContourFindingBase(const ActionOptions&ao);
+      48             :   void setupOnFirstStep( const bool incalc ) override;
+      49             :   virtual void setupValuesOnFirstStep() = 0;
+      50             : /// Get the contour value
+      51             :   double getDifferenceFromContour( const std::vector<double>& x, std::vector<double>& der ) const ;
+      52             : };
+      53             : 
+      54             : inline
+      55             : void ContourFindingBase::findContour( const std::vector<double>& direction, std::vector<double>& point ) const {
+      56        1896 :   mymin.linesearch( direction, point, &ContourFindingBase::getDifferenceFromContour );
+      57        1896 : }
+      58             : 
+      59             : inline
+      60       13479 : double ContourFindingBase::getDifferenceFromContour( const std::vector<double>& x, std::vector<double>& der ) const {
+      61       13479 :   std::vector<double> vals(1); Matrix<double> deriva( 1, x.size() ); function.calc( this, x, vals, deriva );
+      62       53916 :   for(unsigned i=0; i<der.size(); ++i) der[i] = deriva(0,i);
+      63       26958 :   return vals[0] - contour;
+      64             : }
+      65             : 
+      66             : inline
+      67             : const gridtools::GridCoordinatesObject& ContourFindingBase::getInputGridObject() const {
+      68             :   return function.getGridObject();
+      69             : }
+      70             : 
+      71             : }
+      72             : }
+      73             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/contour/DistanceFromContour.cpp.func-sort-c.html b/coverage/contour/DistanceFromContour.cpp.func-sort-c.html new file mode 100644 index 000000000000..21dc67cc7dbf --- /dev/null +++ b/coverage/contour/DistanceFromContour.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - contour/DistanceFromContour.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - contour - DistanceFromContour.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:819585.3 %
Date:2024-04-19 12:12:35Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7contour19DistanceFromContourC2ERKNS_13ActionOptionsE0
_ZN4PLMD7contour19DistanceFromContourC1ERKNS_13ActionOptionsE1
_ZN4PLMD7contour19DistanceFromContour16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD7contour19DistanceFromContour9calculateEv137
_ZN4PLMD7contour19DistanceFromContour19evaluateDerivativesERKNS_13VectorGenericILj3EEERKd274
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/contour/DistanceFromContour.cpp.func.html b/coverage/contour/DistanceFromContour.cpp.func.html new file mode 100644 index 000000000000..946a2484ce21 --- /dev/null +++ b/coverage/contour/DistanceFromContour.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - contour/DistanceFromContour.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - contour - DistanceFromContour.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:819585.3 %
Date:2024-04-19 12:12:35Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7contour19DistanceFromContour16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD7contour19DistanceFromContour19evaluateDerivativesERKNS_13VectorGenericILj3EEERKd274
_ZN4PLMD7contour19DistanceFromContour9calculateEv137
_ZN4PLMD7contour19DistanceFromContourC1ERKNS_13ActionOptionsE1
_ZN4PLMD7contour19DistanceFromContourC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/contour/DistanceFromContour.cpp.gcov.html b/coverage/contour/DistanceFromContour.cpp.gcov.html new file mode 100644 index 000000000000..8f7491dd03c0 --- /dev/null +++ b/coverage/contour/DistanceFromContour.cpp.gcov.html @@ -0,0 +1,323 @@ + + + + + + + + LCOV - plumed test coverage - contour/DistanceFromContour.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - contour - DistanceFromContour.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:819585.3 %
Date:2024-04-19 12:12:35Functions: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 "DistanceFromContourBase.h"
+      23             : #include "core/ActionRegister.h"
+      24             : 
+      25             : //+PLUMEDOC COLVAR DISTANCE_FROM_CONTOUR
+      26             : /*
+      27             : Calculate the perpendicular distance from a Willard-Chandler dividing surface.
+      28             : 
+      29             : Suppose that you have calculated a multicolvar.  By doing so you have calculated a
+      30             : set of colvars, \f$s_i\f$, and each of these colvars has a well defined position in
+      31             : space \f$(x_i,y_i,z_i)\f$.  You can use this information to calculate a phase-field
+      32             : model of the colvar density using:
+      33             : 
+      34             : \f[
+      35             : 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]
+      36             : \f]
+      37             : 
+      38             : In this expression \f$\sigma_x, \sigma_y\f$ and \f$\sigma_z\f$ are bandwidth parameters and
+      39             : \f$K\f$ is one of the \ref kernelfunctions.  This is what is done within \ref MULTICOLVARDENS
+      40             : 
+      41             : The Willard-Chandler surface is a surface of constant density in the above phase field \f$p(x,y,z)\f$.
+      42             : In other words, it is a set of points, \f$(x',y',z')\f$, in your box which have:
+      43             : 
+      44             : \f[
+      45             : p(x',y',z') = \rho
+      46             : \f]
+      47             : 
+      48             : where \f$\rho\f$ is some target density.  This action calculates the distance projected on the \f$x, y\f$ or
+      49             : \f$z\f$ axis between the position of some test particle and this surface of constant field density.
+      50             : 
+      51             : \par Examples
+      52             : 
+      53             : In this example atoms 2-100 are assumed to be concentrated along some part of the \f$z\f$ axis so that you
+      54             : an interface between a liquid/solid and the vapor.  The quantity dc measures the distance between the
+      55             : surface at which the density of 2-100 atoms is equal to 0.2 and the position of the test particle atom 1.
+      56             : 
+      57             : \plumedfile
+      58             : dens: DENSITY SPECIES=2-100
+      59             : dc: DISTANCE_FROM_CONTOUR DATA=dens ATOM=1 BANDWIDTH=0.5,0.5,0.5 DIR=z CONTOUR=0.2
+      60             : \endplumedfile
+      61             : 
+      62             : */
+      63             : //+ENDPLUMEDOC
+      64             : 
+      65             : namespace PLMD {
+      66             : namespace contour {
+      67             : 
+      68             : class DistanceFromContour : public DistanceFromContourBase {
+      69             : private:
+      70             :   unsigned dir;
+      71             :   double pbc_param;
+      72             :   std::vector<double> pos1, pos2, dirv, dirv2;
+      73             :   std::vector<unsigned> perp_dirs;
+      74             :   std::vector<Vector> atom_deriv;
+      75             : public:
+      76             :   static void registerKeywords( Keywords& keys );
+      77             :   explicit DistanceFromContour( const ActionOptions& );
+      78             :   void calculate() override;
+      79             :   void evaluateDerivatives( const Vector& root1, const double& root2 );
+      80             : };
+      81             : 
+      82             : PLUMED_REGISTER_ACTION(DistanceFromContour,"DISTANCE_FROM_CONTOUR")
+      83             : 
+      84           3 : void DistanceFromContour::registerKeywords( Keywords& keys ) {
+      85           3 :   DistanceFromContourBase::registerKeywords( keys );
+      86           6 :   keys.addOutputComponent("dist1","default","the distance between the reference atom and the nearest contour");
+      87           6 :   keys.addOutputComponent("dist2","default","the distance between the reference atom and the other contour");
+      88           6 :   keys.addOutputComponent("qdist","default","the differentiable (squared) distance between the two contours (see above)");
+      89           6 :   keys.addOutputComponent("thickness","default","the distance between the two contours on the line from the reference atom");
+      90           6 :   keys.add("compulsory","DIR","the direction perpendicular to the contour that you are looking for");
+      91           6 :   keys.add("compulsory","TOLERANCE","0.1","this parameter is used to manage periodic boundary conditions.  The problem "
+      92             :            "here is that we can be between contours even when we are not within the membrane "
+      93             :            "because of periodic boundary conditions.  When we are in the contour, however, we "
+      94             :            "should have it so that the sums of the absolute values of the distances to the two "
+      95             :            "contours is approximately the distance between the two contours.  There can be numerical errors in these calculations, however, so "
+      96             :            "we specify a small tolerance here");
+      97           3 : }
+      98             : 
+      99           1 : DistanceFromContour::DistanceFromContour( const ActionOptions& ao ):
+     100             :   Action(ao),
+     101             :   DistanceFromContourBase(ao),
+     102           2 :   pos1(3,0.0),
+     103           1 :   pos2(3,0.0),
+     104           1 :   dirv(3,0.0),
+     105           1 :   dirv2(3,0.0),
+     106           1 :   perp_dirs(2),
+     107           2 :   atom_deriv(active_list.size())
+     108             : {
+     109             :   // Get the direction
+     110           2 :   std::string ldir; parse("DIR",ldir );
+     111           1 :   if( ldir=="x" ) { dir=0; perp_dirs[0]=1; perp_dirs[1]=2; dirv[0]=1; dirv2[0]=-1; }
+     112           1 :   else if( ldir=="y" ) { dir=1; perp_dirs[0]=0; perp_dirs[1]=2; dirv[1]=1; dirv2[1]=-1; }
+     113           1 :   else if( ldir=="z" ) { dir=2; perp_dirs[0]=0; perp_dirs[1]=1; dirv[2]=1; dirv2[2]=-1; }
+     114           0 :   else error(ldir + " is not a valid direction use x, y or z");
+     115             : 
+     116             :   // Read in the tolerance for the pbc parameter
+     117           2 :   parse("TOLERANCE",pbc_param);
+     118             : 
+     119             :   std::vector<unsigned> shape;
+     120             :   // Create the values
+     121           2 :   addComponent("thickness", shape ); componentIsNotPeriodic("thickness");
+     122           2 :   addComponent("dist1", shape ); componentIsNotPeriodic("dist1");
+     123           2 :   addComponent("dist2", shape ); componentIsNotPeriodic("dist2");
+     124           3 :   addComponentWithDerivatives("qdist", shape ); componentIsNotPeriodic("qdist");
+     125           1 : }
+     126             : 
+     127         137 : void DistanceFromContour::calculate() {
+     128             :   // Check box is orthorhombic
+     129         137 :   if( !getPbc().isOrthorombic() ) error("cell box must be orthorhombic");
+     130             : 
+     131             :   // The nanoparticle is at the origin of our coordinate system
+     132         137 :   pos1[0]=pos1[1]=pos1[2]=0.0; pos2[0]=pos2[1]=pos2[2]=0.0;
+     133             : 
+     134             :   // Set bracket as center of mass of membrane in active region
+     135         137 :   Vector myvec = pbcDistance( getPosition(getNumberOfAtoms()-1), getPosition(0) ); pos2[dir]=myvec[dir];
+     136         137 :   nactive=1; active_list[0]=0; double d2, mindist = myvec.modulo2();
+     137         137 :   for(unsigned j=1; j<getNumberOfAtoms()-1; ++j) {
+     138           0 :     Vector distance=pbcDistance( getPosition(getNumberOfAtoms()-1), getPosition(j) );
+     139           0 :     if( (d2=distance[perp_dirs[0]]*distance[perp_dirs[0]])<rcut2 &&
+     140           0 :         (d2+=distance[perp_dirs[1]]*distance[perp_dirs[1]])<rcut2 ) {
+     141           0 :       d2+=distance[dir]*distance[dir];
+     142           0 :       if( d2<mindist && fabs(distance[dir])>epsilon ) { pos2[dir]=distance[dir]; mindist = d2; }
+     143           0 :       active_list[nactive]=j; nactive++;
+     144             :     }
+     145             :   }
+     146             :   // pos1 position of the nanoparticle, in the first time
+     147             :   // pos2 is the position of the closer atom in the membrane with respect the nanoparticle
+     148             :   // fa = distance between pos1 and the contour
+     149             :   // fb = distance between pos2 and the contour
+     150         137 :   std::vector<double> faked(3);
+     151         137 :   double fa = getDifferenceFromContour( pos1, faked );
+     152         137 :   double fb = getDifferenceFromContour( pos2, faked );
+     153         137 :   if( fa*fb>0 ) {
+     154           0 :     unsigned maxtries = std::floor( ( getBox()(dir,dir) ) / bw[dir] );
+     155           0 :     for(unsigned i=0; i<maxtries; ++i) {
+     156           0 :       double sign=(pos2[dir]>0)? -1 : +1; // If the nanoparticle is inside the membrane push it out
+     157           0 :       pos1[dir] += sign*bw[dir]; fa = getDifferenceFromContour( pos1, faked );
+     158           0 :       if( fa*fb<0 ) break;
+     159             :       // if fa*fb is less than zero the new pos 1 is outside the contour
+     160             :     }
+     161             :   }
+     162             :   // Set direction for contour search
+     163         137 :   dirv[dir] = pos2[dir] - pos1[dir];
+     164             :   // Bracket for second root starts in center of membrane
+     165         137 :   double fc = getDifferenceFromContour( pos2, faked );
+     166         137 :   if( fc*fb>0 ) {
+     167             :     // first time is true, because fc=fb
+     168             :     // push pos2 from its initial position inside the membrane towards the second contourn
+     169         137 :     unsigned maxtries = std::floor( ( getBox()(dir,dir) ) / bw[dir] );
+     170         230 :     for(unsigned i=0; i<maxtries; ++i) {
+     171         230 :       double sign=(dirv[dir]>0)? +1 : -1;
+     172         230 :       pos2[dir] += sign*bw[dir]; fc = getDifferenceFromContour( pos2, faked );
+     173         230 :       if( fc*fb<0 ) break;
+     174             :     }
+     175         137 :     dirv2[dir] = ( pos1[dir] + dirv[dir] ) - pos2[dir];
+     176             :   }
+     177             : 
+     178             :   // Now do a search for the two contours
+     179         137 :   findContour( dirv, pos1 );
+     180             :   // Save the first value
+     181         137 :   Vector root1; root1.zero(); root1[dir] = pval[dir];
+     182         137 :   findContour( dirv2, pos2 );
+     183             :   // Calculate the separation between the two roots using PBC
+     184         137 :   Vector root2; root2.zero(); root2[dir] = pval[dir];
+     185         137 :   Vector sep = pbcDistance( root1, root2 ); double spacing = fabs( sep[dir] ); plumed_assert( spacing>epsilon );
+     186         137 :   getPntrToComponent("thickness")->set( spacing );
+     187             : 
+     188             :   // Make sure the sign is right
+     189         137 :   double predir=(root1[dir]*root2[dir]<0)? -1 : 1;
+     190             :   // This deals with periodic boundary conditions - if we are inside the membrane the sum of the absolute
+     191             :   // distances from the contours should add up to the spacing.  When this is not the case we must be outside
+     192             :   // the contour
+     193             :   // if( predir==-1 && (fabs(root1[dir])+fabs(root2[dir]))>(spacing+pbc_param) ) predir=1;
+     194             :   // Set the final value to root that is closest to the "origin" = position of atom
+     195         137 :   if( fabs(root1[dir])<fabs(root2[dir]) ) {
+     196         137 :     getPntrToComponent("dist1")->set( predir*fabs(root1[dir]) );
+     197         274 :     getPntrToComponent("dist2")->set( fabs(root2[dir]) );
+     198             :   } else {
+     199           0 :     getPntrToComponent("dist1")->set( predir*fabs(root2[dir]) );
+     200           0 :     getPntrToComponent("dist2")->set( fabs(root1[dir]) );
+     201             :   }
+     202         137 :   getPntrToComponent("qdist")->set( root2[dir]*root1[dir] );
+     203             : 
+     204             :   // Now calculate the derivatives
+     205         137 :   if( !doNotCalculateDerivatives() ) {
+     206         137 :     evaluateDerivatives( root1, root2[dir] ); evaluateDerivatives( root2, root1[dir] );
+     207             :   }
+     208         137 : }
+     209             : 
+     210         274 : void DistanceFromContour::evaluateDerivatives( const Vector& root1, const double& root2 ) {
+     211         274 :   if( getNumberOfArguments()>0 ) plumed_merror("derivatives for phase field distance from contour have not been implemented yet");
+     212             : 
+     213         274 :   Vector origind; origind.zero(); Tensor vir; vir.zero();
+     214         274 :   double sumd = 0; std::vector<double> pp(3), ddd(3,0);
+     215         548 :   for(unsigned i=0; i<nactive; ++i) {
+     216         274 :     double newval = evaluateKernel( getPosition(active_list[i]), root1, ddd );
+     217         274 :     Vector distance = pbcDistance( getPosition(getNumberOfAtoms()-1), getPosition(active_list[i]) );
+     218             : 
+     219         274 :     if( getNumberOfArguments()==1 ) {
+     220             :     } else {
+     221         274 :       sumd += ddd[dir];
+     222        1096 :       for(unsigned j=0; j<3; ++j) atom_deriv[i][j] = -ddd[j];
+     223         274 :       origind += -atom_deriv[i]; vir -= Tensor(atom_deriv[i],distance);
+     224             :     }
+     225             :   }
+     226             : 
+     227             :   // Add derivatives to atoms involved
+     228         274 :   Value* val=getPntrToComponent("qdist"); double prefactor =  root2 / sumd;
+     229         548 :   for(unsigned i=0; i<nactive; ++i) {
+     230         274 :     val->addDerivative( 3*active_list[i] + 0, -prefactor*atom_deriv[i][0] );
+     231         274 :     val->addDerivative( 3*active_list[i] + 1, -prefactor*atom_deriv[i][1] );
+     232         274 :     val->addDerivative( 3*active_list[i] + 2, -prefactor*atom_deriv[i][2] );
+     233             :   }
+     234             : 
+     235             :   // Add derivatives to atoms at origin
+     236         274 :   unsigned nbase = 3*(getNumberOfAtoms()-1);
+     237         274 :   val->addDerivative( nbase, -prefactor*origind[0] ); nbase++;
+     238         274 :   val->addDerivative( nbase, -prefactor*origind[1] ); nbase++;
+     239         274 :   val->addDerivative( nbase, -prefactor*origind[2] ); nbase++;
+     240             : 
+     241             :   // Add derivatives to virial
+     242        3562 :   for(unsigned i=0; i<3; ++i) for(unsigned j=0; j<3; ++j) { val->addDerivative( nbase, -prefactor*vir(i,j) ); nbase++; }
+     243         274 : }
+     244             : 
+     245             : }
+     246             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/contour/DistanceFromContourBase.cpp.func-sort-c.html b/coverage/contour/DistanceFromContourBase.cpp.func-sort-c.html new file mode 100644 index 000000000000..45ead0b2fc81 --- /dev/null +++ b/coverage/contour/DistanceFromContourBase.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - contour/DistanceFromContourBase.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - contour - DistanceFromContourBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:7474100.0 %
Date:2024-04-19 12:12:35Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7contour23DistanceFromContourBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD7contour23DistanceFromContourBaseC2ERKNS_13ActionOptionsE2
_ZN4PLMD7contour23DistanceFromContourBase16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD7contour23DistanceFromContourBase12lockRequestsEv154
_ZN4PLMD7contour23DistanceFromContourBase14unlockRequestsEv154
_ZN4PLMD7contour23DistanceFromContourBase5applyEv154
_ZN4PLMD7contour23DistanceFromContourBase24getDifferenceFromContourERKSt6vectorIdSaIdEERS4_3283
_ZNK4PLMD7contour23DistanceFromContourBase14evaluateKernelERKNS_13VectorGenericILj3EEES5_RSt6vectorIdSaIdEE190081
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/contour/DistanceFromContourBase.cpp.func.html b/coverage/contour/DistanceFromContourBase.cpp.func.html new file mode 100644 index 000000000000..71c9e0e3331f --- /dev/null +++ b/coverage/contour/DistanceFromContourBase.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - contour/DistanceFromContourBase.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - contour - DistanceFromContourBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:7474100.0 %
Date:2024-04-19 12:12:35Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7contour23DistanceFromContourBase12lockRequestsEv154
_ZN4PLMD7contour23DistanceFromContourBase14unlockRequestsEv154
_ZN4PLMD7contour23DistanceFromContourBase16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD7contour23DistanceFromContourBase24getDifferenceFromContourERKSt6vectorIdSaIdEERS4_3283
_ZN4PLMD7contour23DistanceFromContourBase5applyEv154
_ZN4PLMD7contour23DistanceFromContourBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD7contour23DistanceFromContourBaseC2ERKNS_13ActionOptionsE2
_ZNK4PLMD7contour23DistanceFromContourBase14evaluateKernelERKNS_13VectorGenericILj3EEES5_RSt6vectorIdSaIdEE190081
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/contour/DistanceFromContourBase.cpp.gcov.html b/coverage/contour/DistanceFromContourBase.cpp.gcov.html new file mode 100644 index 000000000000..d6a67ed1d626 --- /dev/null +++ b/coverage/contour/DistanceFromContourBase.cpp.gcov.html @@ -0,0 +1,222 @@ + + + + + + + + LCOV - plumed test coverage - contour/DistanceFromContourBase.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - contour - DistanceFromContourBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:7474100.0 %
Date:2024-04-19 12:12:35Functions: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 "DistanceFromContourBase.h"
+      23             : 
+      24             : namespace PLMD {
+      25             : namespace contour {
+      26             : 
+      27           6 : void DistanceFromContourBase::registerKeywords( Keywords& keys ) {
+      28           6 :   Action::registerKeywords( keys ); ActionWithValue::registerKeywords( keys );
+      29           6 :   ActionAtomistic::registerKeywords( keys ); ActionWithArguments::registerKeywords( keys );
+      30          12 :   keys.remove("NUMERICAL_DERIVATIVES"); keys.use("ARG");
+      31          12 :   keys.add("atoms","POSITIONS","the positions of the atoms that we are calculating the contour from");
+      32          12 :   keys.add("atoms","ATOM","The atom whose perpendicular distance we are calculating from the contour");
+      33          12 :   keys.add("compulsory","BANDWIDTH","the bandwidths for kernel density esimtation");
+      34          12 :   keys.add("compulsory","KERNEL","GAUSSIAN","the kernel function you are using.  More details on  the kernels available "
+      35             :            "in plumed plumed can be found in \\ref kernelfunctions.");
+      36          12 :   keys.add("compulsory","CUTOFF","6.25","the cutoff at which to stop evaluating the kernel functions is set equal to sqrt(2*x)*bandwidth in each direction where x is this number");
+      37          12 :   keys.add("compulsory","CONTOUR","the value we would like for the contour");
+      38           6 : }
+      39             : 
+      40           2 : DistanceFromContourBase::DistanceFromContourBase( const ActionOptions& ao ):
+      41             :   Action(ao),
+      42             :   ActionWithValue(ao),
+      43             :   ActionAtomistic(ao),
+      44             :   ActionWithArguments(ao),
+      45             :   mymin(this),
+      46           2 :   nactive(0)
+      47             : {
+      48           2 :   if( getNumberOfArguments()>1 ) error("should only use one argument for this action");
+      49           2 :   if( getNumberOfArguments()==1 ) {
+      50           1 :     if( getPntrToArgument(0)->getRank()!=1 ) error("ARG for distance from contour should be rank one");
+      51           1 :     getPntrToArgument(0)->buildDataStore();
+      52             :   }
+      53             :   // Read in the multicolvar/atoms
+      54           4 :   std::vector<AtomNumber> atoms; parseAtomList("POSITIONS",atoms);
+      55           4 :   std::vector<AtomNumber> origin; parseAtomList("ATOM",origin);
+      56           2 :   if( origin.size()!=1 ) error("should only specify one atom for origin keyword");
+      57             :   std::vector<AtomNumber> center;
+      58           4 :   if( keywords.exists("ORIGIN") ) {
+      59           2 :     parseAtomList("ORIGIN",center);
+      60           1 :     if( center.size()!=1 ) error("should only specify one atom for center keyword");
+      61             :   }
+      62             : 
+      63           2 :   if( center.size()==1 ) log.printf("  calculating distance between atom %d and contour along vector connecting it to atom %d \n", origin[0].serial(),center[0].serial() );
+      64           1 :   else log.printf("  calculating distance between atom %d and contour \n", origin[0].serial() );
+      65             : 
+      66           2 :   log.printf("  contour is in field constructed from positions of atoms : ");
+      67         515 :   for(unsigned i=0; i<atoms.size(); ++i) log.printf("%d ",atoms[i].serial() );
+      68           2 :   if( getNumberOfArguments()==1 ) {
+      69           1 :     if( getPntrToArgument(0)->getShape()[0]!=atoms.size() ) error("mismatch between number of atoms and size of vector specified using ARG keyword");
+      70           1 :     log.printf("\n  and weights from %s \n", getPntrToArgument(0)->getName().c_str() );
+      71             :   } else {
+      72           1 :     log.printf("\n  all weights are set equal to one \n");
+      73             :   }
+      74             :   // Request everything we need
+      75           2 :   active_list.resize( atoms.size(), 0 );
+      76           2 :   std::vector<Value*> args( getArguments() ); atoms.push_back( origin[0] );
+      77           2 :   if( center.size()==1 ) atoms.push_back( center[0] );
+      78           2 :   requestArguments( args ); requestAtoms( atoms );
+      79             :   // Fix to request arguments
+      80           2 :   if( args.size()==1 ) addDependency( args[0]->getPntrToAction() );
+      81             : 
+      82             :   // Read in details of phase field construction
+      83           8 :   parseVector("BANDWIDTH",bw); parse("KERNEL",kerneltype); parse("CONTOUR",contour);
+      84           4 :   std::string errors; switchingFunction.set( kerneltype + " R_0=1.0 NOSTRETCH", errors );
+      85           2 :   if( errors.length()!=0 ) error("problem reading switching function description " + errors);
+      86           8 :   double det=1; for(unsigned i=0; i<bw.size(); ++i) det*=bw[i]*bw[i];
+      87           2 :   gvol=1.0; if( kerneltype=="GAUSSIAN" ) gvol=pow( 2*pi, 0.5*bw.size() ) * pow( det, 0.5 );
+      88           2 :   log.printf("  constructing phase field using %s kernels with bandwidth (%f, %f, %f) \n",kerneltype.c_str(), bw[0], bw[1], bw[2] );
+      89             : 
+      90             :   // And a cutoff
+      91           2 :   std::vector<double> pp( bw.size(),0 );
+      92           4 :   double dp2cutoff; parse("CUTOFF",dp2cutoff); double rcut =  sqrt(2*dp2cutoff)*bw[0];
+      93           6 :   for(unsigned j=1; j<bw.size(); ++j) {
+      94           4 :     if( sqrt(2*dp2cutoff)*bw[j]>rcut ) rcut=sqrt(2*dp2cutoff)*bw[j];
+      95             :   }
+      96           2 :   rcut2=rcut*rcut;
+      97             : 
+      98             :   // Create the vector of values that holds the position
+      99           2 :   forcesToApply.resize( 3*getNumberOfAtoms() + 9 );
+     100           2 : }
+     101             : 
+     102         154 : void DistanceFromContourBase::lockRequests() {
+     103             :   ActionWithArguments::lockRequests();
+     104             :   ActionAtomistic::lockRequests();
+     105         154 : }
+     106             : 
+     107         154 : void DistanceFromContourBase::unlockRequests() {
+     108             :   ActionWithArguments::unlockRequests();
+     109             :   ActionAtomistic::unlockRequests();
+     110         154 : }
+     111             : 
+     112      190081 : double DistanceFromContourBase::evaluateKernel( const Vector& cpos, const Vector& apos, std::vector<double>& der ) const {
+     113      190081 :   Vector distance = pbcDistance( getPosition(getNumberOfAtoms()-1), cpos );
+     114             :   Vector dist2 = pbcDistance( distance, apos );
+     115      760324 :   double dval=0; for(unsigned j=0; j<3; ++j) { der[j] = dist2[j]/bw[j]; dval += der[j]*der[j]; }
+     116      190081 :   double dfunc, newval = switchingFunction.calculateSqr( dval, dfunc ) / gvol;
+     117      760324 :   double tmp = dfunc / gvol; for(unsigned j=0; j<3; ++j) der[j] *= -tmp;
+     118      190081 :   return newval;
+     119             : }
+     120             : 
+     121        3283 : double DistanceFromContourBase::getDifferenceFromContour( const std::vector<double>& x, std::vector<double>& der ) {
+     122             :   // Transer the position to the local Vector
+     123       13132 :   for(unsigned j=0; j<3; ++j) pval[j] = x[j];
+     124             :   // Now find the contour
+     125        3283 :   double sumk = 0, sumd = 0; std::vector<double> pp(3), ddd(3,0);
+     126      193090 :   for(unsigned i=0; i<nactive; ++i) {
+     127      189807 :     double newval = evaluateKernel( getPosition(active_list[i]), pval, ddd );
+     128             : 
+     129      189807 :     if( getNumberOfArguments()==1 ) {
+     130      186966 :       sumk += getPntrToArgument(0)->get(active_list[i])*newval;
+     131      186966 :       sumd += newval;
+     132        2841 :     } else sumk += newval;
+     133             :   }
+     134        3283 :   if( getNumberOfArguments()==0 ) return sumk - contour;
+     135         442 :   if( fabs(sumk)<epsilon ) return -contour;
+     136         195 :   return (sumk/sumd) - contour;
+     137             : }
+     138             : 
+     139         154 : void DistanceFromContourBase::apply() {
+     140         154 :   if( !checkForForces() ) return ;
+     141         137 :   unsigned ind=0; setForcesOnAtoms( getForcesToApply(), ind );
+     142             : }
+     143             : 
+     144             : }
+     145             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/contour/DistanceFromContourBase.h.func-sort-c.html b/coverage/contour/DistanceFromContourBase.h.func-sort-c.html new file mode 100644 index 000000000000..1f42f1ea86ff --- /dev/null +++ b/coverage/contour/DistanceFromContourBase.h.func-sort-c.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - contour/DistanceFromContourBase.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - contour - DistanceFromContourBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:5683.3 %
Date:2024-04-19 12:12:35Functions:1250.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7contour23DistanceFromContourBase29calculateNumericalDerivativesEPNS_15ActionWithValueE0
_ZN4PLMD7contour23DistanceFromContourBase22getNumberOfDerivativesEv166
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/contour/DistanceFromContourBase.h.func.html b/coverage/contour/DistanceFromContourBase.h.func.html new file mode 100644 index 000000000000..b77c348f4211 --- /dev/null +++ b/coverage/contour/DistanceFromContourBase.h.func.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - contour/DistanceFromContourBase.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - contour - DistanceFromContourBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:5683.3 %
Date:2024-04-19 12:12:35Functions:1250.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7contour23DistanceFromContourBase22getNumberOfDerivativesEv166
_ZN4PLMD7contour23DistanceFromContourBase29calculateNumericalDerivativesEPNS_15ActionWithValueE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/contour/DistanceFromContourBase.h.gcov.html b/coverage/contour/DistanceFromContourBase.h.gcov.html new file mode 100644 index 000000000000..bbb640d43d32 --- /dev/null +++ b/coverage/contour/DistanceFromContourBase.h.gcov.html @@ -0,0 +1,156 @@ + + + + + + + + LCOV - plumed test coverage - contour/DistanceFromContourBase.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - contour - DistanceFromContourBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:5683.3 %
Date:2024-04-19 12:12:35Functions:1250.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_contour_DistanceFromContourBase_h
+      23             : #define __PLUMED_contour_DistanceFromContourBase_h
+      24             : 
+      25             : #include "core/ActionAtomistic.h"
+      26             : #include "core/ActionWithValue.h"
+      27             : #include "core/ActionWithArguments.h"
+      28             : #include "tools/SwitchingFunction.h"
+      29             : #include "tools/RootFindingBase.h"
+      30             : 
+      31             : namespace PLMD {
+      32             : namespace contour {
+      33             : 
+      34             : class DistanceFromContourBase :
+      35             :   public ActionWithValue,
+      36             :   public ActionAtomistic,
+      37             :   public ActionWithArguments
+      38             : {
+      39             : private:
+      40             :   double contour, gvol;
+      41             :   RootFindingBase<DistanceFromContourBase> mymin;
+      42             : protected:
+      43             :   std::string kerneltype;
+      44             :   std::vector<double> bw;
+      45             :   double rcut2;
+      46             :   unsigned nactive;
+      47             :   Vector pval;
+      48             :   std::vector<double> forcesToApply;
+      49             :   std::vector<unsigned> active_list;
+      50             :   SwitchingFunction switchingFunction;
+      51             : ///
+      52             :   double evaluateKernel( const Vector& cpos, const Vector& apos, std::vector<double>& der ) const ;
+      53             : /// Find a contour along line specified by direction
+      54             :   void findContour( const std::vector<double>& direction, std::vector<double>& point ) const ;
+      55             : public:
+      56             :   static void registerKeywords( Keywords& keys );
+      57             :   explicit DistanceFromContourBase( const ActionOptions& );
+      58             :   unsigned getNumberOfDerivatives() override ;
+      59             :   void lockRequests();
+      60             :   void unlockRequests();
+      61           0 :   void calculateNumericalDerivatives( ActionWithValue* a ) { plumed_merror("numerical derivatives are not implemented for this action"); }
+      62             :   double getDifferenceFromContour( const std::vector<double>& x, std::vector<double>& der );
+      63             :   void apply();
+      64             : };
+      65             : 
+      66             : inline
+      67         166 : unsigned DistanceFromContourBase::getNumberOfDerivatives() {
+      68         166 :   if( getNumberOfArguments()==1 ) return 4*getNumberOfAtoms() + 8;  // One derivative for each weight hence four times the number of atoms - 1
+      69         149 :   return 3*getNumberOfAtoms() + 9;
+      70             : }
+      71             : 
+      72             : inline
+      73             : void DistanceFromContourBase::findContour( const std::vector<double>& direction, std::vector<double>& point ) const {
+      74         291 :   mymin.lsearch( direction, point, &DistanceFromContourBase::getDifferenceFromContour );
+      75         291 : }
+      76             : 
+      77             : }
+      78             : }
+      79             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/contour/DistanceFromSphericalContour.cpp.func-sort-c.html b/coverage/contour/DistanceFromSphericalContour.cpp.func-sort-c.html new file mode 100644 index 000000000000..79b86b0b2b20 --- /dev/null +++ b/coverage/contour/DistanceFromSphericalContour.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - contour/DistanceFromSphericalContour.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - contour - DistanceFromSphericalContour.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:343694.4 %
Date:2024-04-19 12:12:35Functions:3560.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7contour28DistanceFromSphericalContour19evaluateDerivativesERKNS_13VectorGenericILj3EEERKd0
_ZN4PLMD7contour28DistanceFromSphericalContourC2ERKNS_13ActionOptionsE0
_ZN4PLMD7contour28DistanceFromSphericalContourC1ERKNS_13ActionOptionsE1
_ZN4PLMD7contour28DistanceFromSphericalContour16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD7contour28DistanceFromSphericalContour9calculateEv17
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/contour/DistanceFromSphericalContour.cpp.func.html b/coverage/contour/DistanceFromSphericalContour.cpp.func.html new file mode 100644 index 000000000000..db9d22c0491e --- /dev/null +++ b/coverage/contour/DistanceFromSphericalContour.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - contour/DistanceFromSphericalContour.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - contour - DistanceFromSphericalContour.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:343694.4 %
Date:2024-04-19 12:12:35Functions:3560.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7contour28DistanceFromSphericalContour16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD7contour28DistanceFromSphericalContour19evaluateDerivativesERKNS_13VectorGenericILj3EEERKd0
_ZN4PLMD7contour28DistanceFromSphericalContour9calculateEv17
_ZN4PLMD7contour28DistanceFromSphericalContourC1ERKNS_13ActionOptionsE1
_ZN4PLMD7contour28DistanceFromSphericalContourC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/contour/DistanceFromSphericalContour.cpp.gcov.html b/coverage/contour/DistanceFromSphericalContour.cpp.gcov.html new file mode 100644 index 000000000000..f816fb644b9f --- /dev/null +++ b/coverage/contour/DistanceFromSphericalContour.cpp.gcov.html @@ -0,0 +1,185 @@ + + + + + + + + LCOV - plumed test coverage - contour/DistanceFromSphericalContour.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - contour - DistanceFromSphericalContour.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:343694.4 %
Date:2024-04-19 12:12:35Functions:3560.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "DistanceFromContourBase.h"
+      23             : #include "core/ActionRegister.h"
+      24             : 
+      25             : //+PLUMEDOC COLVAR DISTANCE_FROM_SPHERICAL_CONTOUR
+      26             : /*
+      27             : Calculate the perpendicular distance from a Willard-Chandler dividing surface.
+      28             : 
+      29             : \par Examples
+      30             : 
+      31             : */
+      32             : //+ENDPLUMEDOC
+      33             : 
+      34             : namespace PLMD {
+      35             : namespace contour {
+      36             : 
+      37             : class DistanceFromSphericalContour : public DistanceFromContourBase {
+      38             : public:
+      39             :   static void registerKeywords( Keywords& keys );
+      40             :   explicit DistanceFromSphericalContour( const ActionOptions& );
+      41             :   void calculate();
+      42             :   void evaluateDerivatives( const Vector& root1, const double& root2 );
+      43             : };
+      44             : 
+      45             : PLUMED_REGISTER_ACTION(DistanceFromSphericalContour,"DISTANCE_FROM_SPHERICAL_CONTOUR")
+      46             : 
+      47           3 : void DistanceFromSphericalContour::registerKeywords( Keywords& keys ) {
+      48           3 :   DistanceFromContourBase::registerKeywords( keys );
+      49           6 :   keys.addOutputComponent("dist","default","the distance between the reference atom and the nearest contour");
+      50           6 :   keys.addOutputComponent("radius","default","the radial distance from the center of the contour to the edge");
+      51           6 :   keys.add("atoms","ORIGIN","The position of the center of the region that the contour encloses");
+      52           3 : }
+      53             : 
+      54           1 : DistanceFromSphericalContour::DistanceFromSphericalContour( const ActionOptions& ao ):
+      55             :   Action(ao),
+      56           1 :   DistanceFromContourBase(ao)
+      57             : {
+      58             :   // Create the values
+      59             :   std::vector<unsigned> shape;
+      60           2 :   addComponentWithDerivatives("dist", shape ); componentIsNotPeriodic("dist");
+      61           3 :   addComponent("radius", shape ); componentIsNotPeriodic("radius");
+      62           1 : }
+      63             : 
+      64          17 : void DistanceFromSphericalContour::calculate() {
+      65             :   // Check box is orthorhombic
+      66          17 :   if( !getPbc().isOrthorombic() ) error("cell box must be orthorhombic");
+      67             : 
+      68             :   // Calculate the director of the vector connecting the center of the sphere to the molecule of interest
+      69          17 :   Vector dirv = pbcDistance( getPosition(getNumberOfAtoms()-1), getPosition(getNumberOfAtoms()-2) );
+      70          17 :   double len=dirv.modulo(); dirv /= len;
+      71             :   // Now work out which atoms need to be considered explicitly
+      72          17 :   Vector myvec = pbcDistance( getPosition(getNumberOfAtoms()-1), getPosition(0) );
+      73          17 :   nactive=1; active_list[0]=0;
+      74        8704 :   for(unsigned j=1; j<getNumberOfAtoms()-2; ++j) {
+      75        8687 :     if( getNumberOfArguments()==1 ) {
+      76        8687 :       if( getPntrToArgument(0)->get(j)<epsilon ) continue;
+      77             :     }
+      78        6698 :     active_list[nactive]=j; nactive++;
+      79        6698 :     Vector distance=pbcDistance( getPosition(getNumberOfAtoms()-1), getPosition(j) );
+      80        6698 :     double dp = dotProduct( distance, dirv ); double cp = distance.modulo2() - dp*dp;
+      81        6698 :     if( cp<rcut2 ) { active_list[nactive]=j; nactive++; }
+      82             :   }
+      83             :   // Get maximum length to fit in box
+      84          17 :   double hbox = 0.5*getBox()(0,0);
+      85          17 :   if( 0.5*getBox()(1,1)<hbox ) hbox = 0.5*getBox()(1,1);
+      86          17 :   if( 0.5*getBox()(2,2)<hbox ) hbox = 0.5*getBox()(2,2);
+      87             :   // Set initial guess for position of contour to position of closest molecule in region
+      88          17 :   std::vector<double> pos1(3), dirv2(3);
+      89          68 :   for(unsigned k=0; k<3; ++k) { dirv2[k]=hbox*dirv[k]; pos1[k]=0; }
+      90             :   // Now do a search for the contours
+      91             :   findContour( dirv2, pos1 );
+      92             :   // Now find the distance between the center of the sphere and the contour
+      93          17 :   double rad = sqrt( pos1[0]*pos1[0] + pos1[1]*pos1[1] + pos1[2]*pos1[2] );
+      94             :   // Set the radius
+      95          17 :   getPntrToComponent("radius")->set( rad );
+      96             :   // Set the distance between the contour and the molecule
+      97          17 :   getPntrToComponent("dist")->set( len - rad );
+      98             : 
+      99             :   // Now calculate the derivatives
+     100          17 :   if( !doNotCalculateDerivatives() ) plumed_merror("derivatives not implemented");
+     101          17 : }
+     102             : 
+     103           0 : void DistanceFromSphericalContour::evaluateDerivatives( const Vector& root1, const double& root2 ) {
+     104           0 :   plumed_error();
+     105             : }
+     106             : 
+     107             : }
+     108             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/contour/DumpContour.cpp.func-sort-c.html b/coverage/contour/DumpContour.cpp.func-sort-c.html new file mode 100644 index 000000000000..1bda90a536e7 --- /dev/null +++ b/coverage/contour/DumpContour.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - contour/DumpContour.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - contour - DumpContour.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3535100.0 %
Date:2024-04-19 12:12:35Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7contour11DumpContourC2ERKNS_13ActionOptionsE0
_ZN4PLMD7contour11DumpContourC1ERKNS_13ActionOptionsE1
_ZN4PLMD7contour11DumpContourD0Ev1
_ZN4PLMD7contour11DumpContourD1Ev1
_ZN4PLMD7contour11DumpContour5applyEv2
_ZN4PLMD7contour11DumpContour6updateEv2
_ZN4PLMD7contour11DumpContour9calculateEv2
_ZN4PLMD7contour11DumpContour16registerKeywordsERNS_8KeywordsE3
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/contour/DumpContour.cpp.func.html b/coverage/contour/DumpContour.cpp.func.html new file mode 100644 index 000000000000..30c9d251178b --- /dev/null +++ b/coverage/contour/DumpContour.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - contour/DumpContour.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - contour - DumpContour.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3535100.0 %
Date:2024-04-19 12:12:35Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7contour11DumpContour16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD7contour11DumpContour5applyEv2
_ZN4PLMD7contour11DumpContour6updateEv2
_ZN4PLMD7contour11DumpContour9calculateEv2
_ZN4PLMD7contour11DumpContourC1ERKNS_13ActionOptionsE1
_ZN4PLMD7contour11DumpContourC2ERKNS_13ActionOptionsE0
_ZN4PLMD7contour11DumpContourD0Ev1
_ZN4PLMD7contour11DumpContourD1Ev1
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/contour/DumpContour.cpp.gcov.html b/coverage/contour/DumpContour.cpp.gcov.html new file mode 100644 index 000000000000..6ee3bbeaa2e0 --- /dev/null +++ b/coverage/contour/DumpContour.cpp.gcov.html @@ -0,0 +1,180 @@ + + + + + + + + LCOV - plumed test coverage - contour/DumpContour.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - contour - DumpContour.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3535100.0 %
Date:2024-04-19 12:12:35Functions: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/ActionWithArguments.h"
+      23             : #include "core/ActionPilot.h"
+      24             : #include "core/ActionRegister.h"
+      25             : #include "tools/OFile.h"
+      26             : #include "core/PlumedMain.h"
+      27             : #include "FindContour.h"
+      28             : 
+      29             : namespace PLMD {
+      30             : namespace contour {
+      31             : 
+      32             : //+PLUMEDOC GRIDANALYSIS DUMPCONTOUR
+      33             : /*
+      34             : Print the contour
+      35             : 
+      36             : \par Examples
+      37             : 
+      38             : */
+      39             : //+ENDPLUMEDOC
+      40             : 
+      41             : class DumpContour :
+      42             :   public ActionWithArguments,
+      43             :   public ActionPilot {
+      44             : private:
+      45             :   std::string fmt, filename;
+      46             : public:
+      47             :   static void registerKeywords( Keywords& keys );
+      48             :   explicit DumpContour(const ActionOptions&ao);
+      49           2 :   ~DumpContour() {}
+      50           2 :   void calculate() override {}
+      51           2 :   void apply() override {}
+      52             :   void update() override ;
+      53             : };
+      54             : 
+      55             : PLUMED_REGISTER_ACTION(DumpContour,"DUMPCONTOUR")
+      56             : 
+      57           3 : void DumpContour::registerKeywords( Keywords& keys ) {
+      58           3 :   Action::registerKeywords( keys );
+      59           3 :   ActionPilot::registerKeywords( keys );
+      60           3 :   ActionWithArguments::registerKeywords( keys ); keys.use("ARG");
+      61           6 :   keys.add("compulsory","STRIDE","1","the frequency with which the grid should be output to the file.");
+      62           6 :   keys.add("compulsory","FILE","density","the file on which to write the grid.");
+      63           6 :   keys.add("optional","FMT","the format that should be used to output real numbers");
+      64           3 : }
+      65             : 
+      66           1 : DumpContour::DumpContour(const ActionOptions&ao):
+      67             :   Action(ao),
+      68             :   ActionWithArguments(ao),
+      69             :   ActionPilot(ao),
+      70           1 :   fmt("%f")
+      71             : {
+      72           1 :   if( getNumberOfArguments()!=1 ) error("should only be one argument");
+      73           1 :   FindContour* fc=dynamic_cast<FindContour*>( getPntrToArgument(0)->getPntrToAction() );
+      74           1 :   if( !fc ) error("can only use this action to print data from FIND_CONTOUR actions");
+      75             : 
+      76           2 :   parse("FILE",filename);
+      77           1 :   if(filename.length()==0) error("name out output file was not specified");
+      78             : 
+      79           1 :   log.printf("  outputting contour with label %s to file named %s",getPntrToArgument(0)->getName().c_str(), filename.c_str() );
+      80           2 :   parse("FMT",fmt); log.printf(" with format %s \n", fmt.c_str() ); fmt = " " + fmt;
+      81           1 : }
+      82             : 
+      83           2 : void DumpContour::update() {
+      84           2 :   OFile ofile; ofile.link(*this);
+      85           2 :   ofile.setBackupString("analysis");
+      86           2 :   ofile.open( filename );
+      87             : 
+      88           2 :   FindContour* fc=dynamic_cast<FindContour*>( getPntrToArgument(0)->getPntrToAction() );
+      89           2 :   unsigned maxp = fc->active_cells.size(), ncomp = fc->getNumberOfComponents();
+      90       32930 :   unsigned ntasks = 0; for(unsigned i=0; i<maxp; ++i) ntasks += fc->active_cells[i];
+      91             : 
+      92           2 :   ofile.printf("%d\n", ntasks ); ofile.printf("Points found on isocontour\n");
+      93       32930 :   for(unsigned i=0; i<maxp; ++i) {
+      94       32928 :     if( fc->active_cells[i]==0 ) continue ;
+      95        1108 :     const char* defname="X"; const char* name=defname; ofile.printf("%s", name);
+      96        4432 :     for(unsigned j=0; j<ncomp; ++j ) ofile.printf((" " + fmt).c_str(), (fc->copyOutput(j))->get(i)  );
+      97        1108 :     ofile.printf("\n");
+      98             :   }
+      99           2 : }
+     100             : 
+     101             : 
+     102             : }
+     103             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/contour/FindContour.cpp.func-sort-c.html b/coverage/contour/FindContour.cpp.func-sort-c.html new file mode 100644 index 000000000000..1114abc755a4 --- /dev/null +++ b/coverage/contour/FindContour.cpp.func-sort-c.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - contour/FindContour.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - contour - FindContour.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:545696.4 %
Date:2024-04-19 12:12:35Functions:7977.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7contour11FindContour22getNumberOfDerivativesEv0
_ZN4PLMD7contour11FindContourC2ERKNS_13ActionOptionsE0
_ZN4PLMD7contour11FindContour19areAllTasksRequiredERSt6vectorIPNS_16ActionWithVectorESaIS4_EE1
_ZN4PLMD7contour11FindContour22setupValuesOnFirstStepEv1
_ZN4PLMD7contour11FindContourC1ERKNS_13ActionOptionsE1
_ZN4PLMD7contour11FindContour16getNumberOfTasksERj2
_ZN4PLMD7contour11FindContour16registerKeywordsERNS_8KeywordsE3
_ZNK4PLMD7contour11FindContour11performTaskERKjRNS_10MultiValueE1108
_ZNK4PLMD7contour11FindContour15checkTaskStatusERKjRi32928
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/contour/FindContour.cpp.func.html b/coverage/contour/FindContour.cpp.func.html new file mode 100644 index 000000000000..45fb036a1c2b --- /dev/null +++ b/coverage/contour/FindContour.cpp.func.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - contour/FindContour.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - contour - FindContour.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:545696.4 %
Date:2024-04-19 12:12:35Functions:7977.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7contour11FindContour16getNumberOfTasksERj2
_ZN4PLMD7contour11FindContour16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD7contour11FindContour19areAllTasksRequiredERSt6vectorIPNS_16ActionWithVectorESaIS4_EE1
_ZN4PLMD7contour11FindContour22getNumberOfDerivativesEv0
_ZN4PLMD7contour11FindContour22setupValuesOnFirstStepEv1
_ZN4PLMD7contour11FindContourC1ERKNS_13ActionOptionsE1
_ZN4PLMD7contour11FindContourC2ERKNS_13ActionOptionsE0
_ZNK4PLMD7contour11FindContour11performTaskERKjRNS_10MultiValueE1108
_ZNK4PLMD7contour11FindContour15checkTaskStatusERKjRi32928
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/contour/FindContour.cpp.gcov.html b/coverage/contour/FindContour.cpp.gcov.html new file mode 100644 index 000000000000..bdd844daf53d --- /dev/null +++ b/coverage/contour/FindContour.cpp.gcov.html @@ -0,0 +1,264 @@ + + + + + + + + LCOV - plumed test coverage - contour/FindContour.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - contour - FindContour.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:545696.4 %
Date:2024-04-19 12:12:35Functions:7977.8 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2020 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "FindContour.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "core/PlumedMain.h"
+      25             : 
+      26             : //+PLUMEDOC GRIDANALYSIS FIND_CONTOUR
+      27             : /*
+      28             : Find an isocontour in a smooth function.
+      29             : 
+      30             : As discussed in the part of the manual on \ref Analysis PLUMED contains a number of tools that allow you to calculate
+      31             : a function on a grid.  The function on this grid might be a \ref HISTOGRAM as a function of a few collective variables
+      32             : or it might be a phase field that has been calculated using \ref MULTICOLVARDENS.  If this function has one or two input
+      33             : arguments it is relatively straightforward to plot the function.  If by contrast the data has a three or more dimensions
+      34             : it can be difficult to visualize.
+      35             : 
+      36             : This action provides one tool for visualizing these functions.  It can be used to search for a set of points on a contour
+      37             : where the function takes a particular values.  In other words, for the function \f$f(x,y)\f$ this action would find a set
+      38             : of points \f$\{x_c,y_c\}\f$ that have:
+      39             : 
+      40             : \f[
+      41             : f(x_c,y_c) - c = 0
+      42             : \f]
+      43             : 
+      44             : where \f$c\f$ is some constant value that is specified by the user.  The points on this contour are detected using a variant
+      45             : on the marching squares or marching cubes algorithm, which you can find information on here:
+      46             : 
+      47             : https://en.wikipedia.org/wiki/Marching_squares
+      48             : https://en.wikipedia.org/wiki/Marching_cubes
+      49             : 
+      50             : As such, and unlike \ref FIND_CONTOUR_SURFACE or \ref FIND_SPHERICAL_CONTOUR, the function input to this action can have any dimension.
+      51             : Furthermore, the topology of the contour will be determined by the algorithm and does not need to be specified by the user.
+      52             : 
+      53             : \par Examples
+      54             : 
+      55             : The input below allows you to calculate something akin to a Willard-Chandler dividing surface \cite wcsurface.
+      56             : The simulation cell in this case contains a solid phase and a liquid phase.  The Willard-Chandler surface is the
+      57             : surface that separates the parts of the box containing the solid from the parts containing the liquid.  To compute the position
+      58             : of this surface  the \ref FCCUBIC symmetry function is calculated for each of the atoms in the system from on the geometry of the
+      59             : atoms in the first coordination sphere of each of the atoms.  These quantities are then transformed using a switching function.
+      60             : This procedure generates a single number for each atom in the system and this quantity has a value of one for atoms that are in
+      61             : parts of the box that resemble the solid structure and zero for atoms that are in parts of the box that resemble the liquid.
+      62             : The position of a virtual atom is then computed using \ref CENTER_OF_MULTICOLVAR and a phase field model is constructed using
+      63             : \ref MULTICOLVARDENS.  These procedure ensures that we have a continuous function that gives a measure of the average degree of
+      64             : solidness at each point in the simulation cell.  The Willard-Chandler dividing surface is calculated by finding a a set of points
+      65             : at which the value of this phase field is equal to 0.5.  This set of points is output to file called mycontour.dat.  A new contour
+      66             : is found on every single step for each frame that is read in.
+      67             : 
+      68             : \plumedfile
+      69             : UNITS NATURAL
+      70             : FCCUBIC ...
+      71             :   SPECIES=1-96000 SWITCH={CUBIC D_0=1.2 D_MAX=1.5}
+      72             :   ALPHA=27 PHI=0.0 THETA=-1.5708 PSI=-2.35619 LABEL=fcc
+      73             : ... FCCUBIC
+      74             : 
+      75             : tfcc: MTRANSFORM_MORE DATA=fcc LOWMEM SWITCH={SMAP R_0=0.5 A=8 B=8}
+      76             : center: CENTER_OF_MULTICOLVAR DATA=tfcc
+      77             : 
+      78             : dens: MULTICOLVARDENS ...
+      79             :   DATA=tfcc ORIGIN=center DIR=xyz
+      80             :   NBINS=80,80,80 BANDWIDTH=1.0,1.0,1.0 STRIDE=1 CLEAR=1
+      81             : ...
+      82             : 
+      83             : FIND_CONTOUR GRID=dens CONTOUR=0.5 FILE=mycontour.xyz
+      84             : \endplumedfile
+      85             : 
+      86             : */
+      87             : //+ENDPLUMEDOC
+      88             : 
+      89             : namespace PLMD {
+      90             : namespace contour {
+      91             : 
+      92             : PLUMED_REGISTER_ACTION(FindContour,"FIND_CONTOUR")
+      93             : 
+      94           3 : void FindContour::registerKeywords( Keywords& keys ) {
+      95           3 :   ContourFindingBase::registerKeywords( keys ); ActionWithValue::useCustomisableComponents(keys);
+      96             : // We want a better way of doing this bit
+      97           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");
+      98           3 : }
+      99             : 
+     100           1 : FindContour::FindContour(const ActionOptions&ao):
+     101             :   Action(ao),
+     102           1 :   ContourFindingBase(ao)
+     103             : {
+     104           1 :   parse("BUFFER",gbuffer);
+     105           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);
+     106           1 :   checkRead();
+     107             : 
+     108           1 :   gridtools::ActionWithGrid* ag=dynamic_cast<gridtools::ActionWithGrid*>( getPntrToArgument(0)->getPntrToAction() );
+     109           1 :   std::vector<std::string> argn( ag->getGridCoordinateNames() );
+     110             : 
+     111           1 :   std::vector<unsigned> shape(1); shape[0]=0;
+     112           4 :   for(unsigned i=0; i<argn.size(); ++i ) {
+     113           3 :     addComponent( argn[i], shape ); componentIsNotPeriodic( argn[i] ); getPntrToComponent(i)->buildDataStore();
+     114             :   }
+     115             :   // Check for task reduction
+     116           1 :   updateTaskListReductionStatus();
+     117           1 : }
+     118             : 
+     119           1 : void FindContour::setupValuesOnFirstStep() {
+     120           1 :   std::vector<unsigned> shape(1); shape[0] = getPntrToArgument(0)->getRank()*getPntrToArgument(0)->getNumberOfValues();
+     121           4 :   for(unsigned i=0; i<getNumberOfComponents(); ++i) getPntrToComponent(i)->setShape( shape );
+     122           1 :   active_cells.resize( shape[0] );
+     123           1 : }
+     124             : 
+     125           0 : unsigned FindContour::getNumberOfDerivatives() {
+     126           0 :   return 0;
+     127             : }
+     128             : 
+     129           1 : void FindContour::areAllTasksRequired( std::vector<ActionWithVector*>& task_reducing_actions ) {
+     130           1 :   task_reducing_actions.push_back(this);
+     131           1 : }
+     132             : 
+     133           2 : void FindContour::getNumberOfTasks( unsigned& ntasks ) {
+     134           2 :   ntasks = active_cells.size();
+     135             : 
+     136             :   Value* gval=getPntrToArgument(0);
+     137           2 :   unsigned npoints = gval->getNumberOfValues();
+     138           2 :   std::vector<unsigned> ind( gval->getRank() );
+     139           2 :   std::vector<unsigned> ones( gval->getRank(), 1 );
+     140           2 :   std::vector<unsigned> nbin( getInputGridObject().getNbin( false ) );
+     141             :   unsigned num_neighbours; std::vector<unsigned> neighbours;
+     142             : 
+     143             :   std::fill( active_cells.begin(), active_cells.end(), 0 );
+     144       10978 :   for(unsigned i=0; i<npoints; ++i) {
+     145             :     // Get the index of the current grid point
+     146       10976 :     getInputGridObject().getIndices( i, ind );
+     147       10976 :     getInputGridObject().getNeighbors( ind, ones, num_neighbours, neighbours );
+     148             :     // Get the value of a point on the grid
+     149       10976 :     double val1=gval->get( i ) - contour;
+     150             :     bool edge=false;
+     151       43904 :     for(unsigned j=0; j<gval->getRank(); ++j) {
+     152             :       // Make sure we don't search at the edge of the grid
+     153       32928 :       if( !getInputGridObject().isPeriodic(j) && (ind[j]+1)==nbin[j] ) continue;
+     154       32928 :       else if( (ind[j]+1)==nbin[j] ) { edge=true; ind[j]=0; }
+     155       30968 :       else ind[j]+=1;
+     156       32928 :       double val2=gval->get( getInputGridObject().getIndex(ind) ) - contour;
+     157       32928 :       if( val1*val2<0 ) active_cells[gval->getRank()*i + j] = 1;
+     158       32928 :       if( getInputGridObject().isPeriodic(j) && edge ) { edge=false; ind[j]=nbin[j]-1; }
+     159       30968 :       else ind[j]-=1;
+     160             :     }
+     161             :   }
+     162           2 : }
+     163             : 
+     164       32928 : int FindContour::checkTaskStatus( const unsigned& taskno, int& flag ) const {
+     165       32928 :   if( active_cells[taskno]>0 ) return 1;
+     166             :   return 0;
+     167             : }
+     168             : 
+     169        1108 : void FindContour::performTask( const unsigned& current, MultiValue& myvals ) const {
+     170             :   // Retrieve the initial grid point coordinates
+     171        1108 :   unsigned gpoint = std::floor( current / getPntrToArgument(0)->getRank() );
+     172        1108 :   std::vector<double> point( getPntrToArgument(0)->getRank() );
+     173        1108 :   getInputGridObject().getGridPointCoordinates( gpoint, point );
+     174             : 
+     175             :   // Retrieve the direction we are searching for the contour
+     176        1108 :   unsigned gdir = current%(getPntrToArgument(0)->getRank() );
+     177        1108 :   std::vector<double> direction( getPntrToArgument(0)->getRank(), 0 );
+     178        1108 :   direction[gdir] = 0.999999999*getInputGridObject().getGridSpacing()[gdir];
+     179             : 
+     180             :   // Now find the contour
+     181             :   findContour( direction, point );
+     182             :   // And transfer to the store data vessel
+     183        4432 :   for(unsigned i=0; i<getPntrToArgument(0)->getRank(); ++i) myvals.setValue( getConstPntrToComponent(i)->getPositionInStream(), point[i] );
+     184        1108 : }
+     185             : 
+     186             : }
+     187             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/contour/FindContour.h.func-sort-c.html b/coverage/contour/FindContour.h.func-sort-c.html new file mode 100644 index 000000000000..083a493e8211 --- /dev/null +++ b/coverage/contour/FindContour.h.func-sort-c.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - contour/FindContour.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - contour - FindContour.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:020.0 %
Date:2024-04-19 12:12:35Functions:020.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD7contour11FindContour22getGridCoordinateNamesB5cxx11Ev0
_ZNK4PLMD7contour11FindContour24getGridCoordinatesObjectEv0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/contour/FindContour.h.func.html b/coverage/contour/FindContour.h.func.html new file mode 100644 index 000000000000..4b6fc8686a65 --- /dev/null +++ b/coverage/contour/FindContour.h.func.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - contour/FindContour.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - contour - FindContour.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:020.0 %
Date:2024-04-19 12:12:35Functions:020.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD7contour11FindContour22getGridCoordinateNamesB5cxx11Ev0
_ZNK4PLMD7contour11FindContour24getGridCoordinatesObjectEv0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/contour/FindContour.h.gcov.html b/coverage/contour/FindContour.h.gcov.html new file mode 100644 index 000000000000..54d452672d0a --- /dev/null +++ b/coverage/contour/FindContour.h.gcov.html @@ -0,0 +1,127 @@ + + + + + + + + LCOV - plumed test coverage - contour/FindContour.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - contour - FindContour.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:020.0 %
Date:2024-04-19 12:12:35Functions:020.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2020 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_contour_FindContour_h
+      23             : #define __PLUMED_contour_FindContour_h
+      24             : 
+      25             : #include "ContourFindingBase.h"
+      26             : 
+      27             : namespace PLMD {
+      28             : namespace contour {
+      29             : 
+      30             : class FindContour : public ContourFindingBase {
+      31             :   friend class DumpContour;
+      32             : private:
+      33             :   unsigned gbuffer;
+      34             :   std::vector<unsigned> active_cells;
+      35             : public:
+      36             :   static void registerKeywords( Keywords& keys );
+      37             :   explicit FindContour(const ActionOptions&ao);
+      38             :   void setupValuesOnFirstStep() override;
+      39             :   unsigned getNumberOfDerivatives() override ;
+      40             :   void areAllTasksRequired( std::vector<ActionWithVector*>& task_reducing_actions ) override ;
+      41             :   void getNumberOfTasks( unsigned& ntasks ) override ;
+      42             :   int checkTaskStatus( const unsigned& taskno, int& flag ) const override ;
+      43           0 :   std::vector<std::string> getGridCoordinateNames() const override { plumed_error(); }
+      44           0 :   const gridtools::GridCoordinatesObject& getGridCoordinatesObject() const override { plumed_error(); }
+      45             :   void performTask( const unsigned& current, MultiValue& myvals ) const override;
+      46             : };
+      47             : 
+      48             : }
+      49             : }
+      50             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/contour/FindContourSurface.cpp.func-sort-c.html b/coverage/contour/FindContourSurface.cpp.func-sort-c.html new file mode 100644 index 000000000000..3efc7a9bcebc --- /dev/null +++ b/coverage/contour/FindContourSurface.cpp.func-sort-c.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - contour/FindContourSurface.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - contour - FindContourSurface.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:737696.1 %
Date:2024-04-19 12:12:35Functions:8988.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7contour18FindContourSurfaceC2ERKNS_13ActionOptionsE0
_ZN4PLMD7contour18FindContourSurface22setupValuesOnFirstStepEv1
_ZN4PLMD7contour18FindContourSurfaceC1ERKNS_13ActionOptionsE1
_ZN4PLMD7contour18FindContourSurface16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD7contour18FindContourSurface22getNumberOfDerivativesEv3
_ZNK4PLMD7contour18FindContourSurface22getGridCoordinateNamesB5cxx11Ev3
_ZNK4PLMD7contour18FindContourSurface24getGridCoordinatesObjectEv3
_ZNK4PLMD7contour18FindContourSurface11performTaskERKjRNS_10MultiValueE588
_ZNK4PLMD7contour18FindContourSurface17gatherStoredValueERKjS3_RKNS_10MultiValueES3_RSt6vectorIdSaIdEE588
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/contour/FindContourSurface.cpp.func.html b/coverage/contour/FindContourSurface.cpp.func.html new file mode 100644 index 000000000000..3dbaeb19524e --- /dev/null +++ b/coverage/contour/FindContourSurface.cpp.func.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - contour/FindContourSurface.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - contour - FindContourSurface.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:737696.1 %
Date:2024-04-19 12:12:35Functions:8988.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7contour18FindContourSurface16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD7contour18FindContourSurface22getNumberOfDerivativesEv3
_ZN4PLMD7contour18FindContourSurface22setupValuesOnFirstStepEv1
_ZN4PLMD7contour18FindContourSurfaceC1ERKNS_13ActionOptionsE1
_ZN4PLMD7contour18FindContourSurfaceC2ERKNS_13ActionOptionsE0
_ZNK4PLMD7contour18FindContourSurface11performTaskERKjRNS_10MultiValueE588
_ZNK4PLMD7contour18FindContourSurface17gatherStoredValueERKjS3_RKNS_10MultiValueES3_RSt6vectorIdSaIdEE588
_ZNK4PLMD7contour18FindContourSurface22getGridCoordinateNamesB5cxx11Ev3
_ZNK4PLMD7contour18FindContourSurface24getGridCoordinatesObjectEv3
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/contour/FindContourSurface.cpp.gcov.html b/coverage/contour/FindContourSurface.cpp.gcov.html new file mode 100644 index 000000000000..06e35abee74a --- /dev/null +++ b/coverage/contour/FindContourSurface.cpp.gcov.html @@ -0,0 +1,315 @@ + + + + + + + + LCOV - plumed test coverage - contour/FindContourSurface.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - contour - FindContourSurface.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:737696.1 %
Date:2024-04-19 12:12:35Functions: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/ActionRegister.h"
+      23             : #include "ContourFindingBase.h"
+      24             : #include "core/PlumedMain.h"
+      25             : 
+      26             : //+PLUMEDOC GRIDANALYSIS FIND_CONTOUR_SURFACE
+      27             : /*
+      28             : Find an isocontour by searching along either the x, y or z direction.
+      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 lines
+      45             : 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
+      46             : function evaluated on a grid that gives us the height of the interface as a function of two coordinates.
+      47             : 
+      48             : 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
+      49             : 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
+      50             : function have the appropriate topology you should use \ref FIND_CONTOUR in place of \ref FIND_CONTOUR_SURFACE.
+      51             : 
+      52             : 
+      53             : \par Examples
+      54             : 
+      55             : 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
+      56             : 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
+      57             : 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
+      58             : 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
+      59             : 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
+      60             : \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
+      61             : 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
+      62             : 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
+      63             : 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$
+      64             : position.  This grid is then output to a file called contour2.dat.
+      65             : 
+      66             : 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
+      67             : on every step.
+      68             : 
+      69             : \plumedfile
+      70             : UNITS NATURAL
+      71             : FCCUBIC ...
+      72             :   SPECIES=1-96000 SWITCH={CUBIC D_0=1.2 D_MAX=1.5}
+      73             :   ALPHA=27 PHI=0.0 THETA=-1.5708 PSI=-2.35619 LABEL=fcc
+      74             : ... FCCUBIC
+      75             : 
+      76             : 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
+      77             : 
+      78             : ss2: FIND_CONTOUR_SURFACE GRID=dens2 CONTOUR=0.42 SEARCHDIR=z STRIDE=1 CLEAR=1
+      79             : DUMPGRID GRID=ss2 FILE=contour2.dat FMT=%8.4f STRIDE=1
+      80             : \endplumedfile
+      81             : 
+      82             : */
+      83             : //+ENDPLUMEDOC
+      84             : 
+      85             : namespace PLMD {
+      86             : namespace contour {
+      87             : 
+      88             : class FindContourSurface : public ContourFindingBase {
+      89             : private:
+      90             :   unsigned dir_n;
+      91             :   std::vector<unsigned> ones;
+      92             :   std::vector<unsigned> gdirs;
+      93             :   std::vector<double> direction;
+      94             :   std::vector<std::string> gnames;
+      95             :   gridtools::GridCoordinatesObject gridcoords;
+      96             : public:
+      97             :   static void registerKeywords( Keywords& keys );
+      98             :   explicit FindContourSurface(const ActionOptions&ao);
+      99             :   void setupValuesOnFirstStep() override;
+     100             :   unsigned getNumberOfDerivatives() override ;
+     101             :   std::vector<std::string> getGridCoordinateNames() const override ;
+     102             :   const gridtools::GridCoordinatesObject& getGridCoordinatesObject() const override ;
+     103             :   void performTask( const unsigned& current, MultiValue& myvals ) const override;
+     104             :   void gatherStoredValue( const unsigned& valindex, const unsigned& code, const MultiValue& myvals,
+     105             :                           const unsigned& bufstart, std::vector<double>& buffer ) const override ;
+     106             : };
+     107             : 
+     108             : PLUMED_REGISTER_ACTION(FindContourSurface,"FIND_CONTOUR_SURFACE")
+     109             : 
+     110           3 : void FindContourSurface::registerKeywords( Keywords& keys ) {
+     111           3 :   ContourFindingBase::registerKeywords( keys );
+     112           6 :   keys.add("compulsory","SEARCHDIR","In which directions do you wish to search for the contour.");
+     113           3 : }
+     114             : 
+     115           1 : FindContourSurface::FindContourSurface(const ActionOptions&ao):
+     116             :   Action(ao),
+     117             :   ContourFindingBase(ao),
+     118           1 :   ones(getPntrToArgument(0)->getRank(),1)
+     119             : {
+     120           1 :   if( getPntrToArgument(0)->getRank()<2 ) error("cannot find dividing surface if input grid is one dimensional");
+     121             : 
+     122           1 :   std::string dir; parse("SEARCHDIR",dir);
+     123           1 :   log.printf("  calculating location of contour on %d dimensional grid \n", getPntrToArgument(0)->getRank()-1 );
+     124           1 :   checkRead();
+     125             : 
+     126             :   Value* gval=getPntrToArgument(0); unsigned n=0;
+     127           1 :   gdirs.resize( gval->getRank()-1 ); gnames.resize( getPntrToArgument(0)->getRank()-1 );
+     128             : 
+     129           1 :   gridtools::ActionWithGrid* ag=dynamic_cast<gridtools::ActionWithGrid*>( gval->getPntrToAction() );
+     130           1 :   if( !ag ) error("input argument must be a grid");
+     131           2 :   if( getInputGridObject().getGridType()=="fibonacci") error("cannot search for contours in fibonacci grids");
+     132           1 :   std::vector<std::string> argn( ag->getGridCoordinateNames() );
+     133             : 
+     134           4 :   for(unsigned i=0; i<gval->getRank(); ++i) {
+     135           3 :     if( argn[i]==dir ) {
+     136           1 :       dir_n=i;
+     137             :     } else {
+     138           2 :       if( n==gdirs.size() ) error("could not find " + dir + " direction in input grid");
+     139           4 :       gdirs[n]=i; gnames[n]=argn[i]; n++;
+     140             :     }
+     141             :   }
+     142           1 :   if( n!=(gval->getRank()-1) ) error("output of grid is not understood");
+     143             : 
+     144           1 :   std::vector<bool> ipbc( getInputGridObject().getDimension()-1 );
+     145           3 :   for(unsigned i=0; i<gdirs.size(); ++i) ipbc[i] = getInputGridObject().isPeriodic(gdirs[i]);
+     146           2 :   gridcoords.setup( "flat", ipbc, 0, 0.0 );
+     147             : 
+     148             :   // Now add a value
+     149           1 :   std::vector<unsigned> shape( getInputGridObject().getDimension()-1 );
+     150           1 :   addValueWithDerivatives( shape ); setNotPeriodic();
+     151           1 :   getPntrToComponent(0)->buildDataStore();
+     152           2 : }
+     153             : 
+     154           1 : void FindContourSurface::setupValuesOnFirstStep() {
+     155           1 :   std::vector<double> fspacing; std::vector<unsigned> snbins( gridcoords.getDimension() );
+     156           1 :   std::vector<std::string> smin( gridcoords.getDimension() ), smax( gridcoords.getDimension() );
+     157           3 :   for(unsigned i=0; i<gdirs.size(); ++i) {
+     158           6 :     smin[i]=getInputGridObject().getMin()[gdirs[i]]; smax[i]=getInputGridObject().getMax()[gdirs[i]];
+     159           2 :     snbins[i]=getInputGridObject().getNbin(false)[gdirs[i]];
+     160             :   }
+     161           1 :   gridcoords.setBounds( smin, smax, snbins, fspacing );
+     162           2 :   getPntrToComponent(0)->setShape( gridcoords.getNbin(true) );
+     163             : 
+     164           1 :   std::vector<unsigned> find( gridcoords.getDimension() );
+     165           1 :   std::vector<unsigned> ind( gridcoords.getDimension() );
+     166         197 :   for(unsigned i=0; i<gridcoords.getNumberOfPoints(); ++i) {
+     167         196 :     find.assign( find.size(), 0 ); gridcoords.getIndices( i, ind );
+     168         588 :     for(unsigned j=0; j<gdirs.size(); ++j) find[gdirs[j]]=ind[j];
+     169             :   }
+     170             : 
+     171             :   // Set the direction in which to look for the contour
+     172           1 :   direction.resize( getInputGridObject().getDimension(), 0 );
+     173           1 :   direction[dir_n] = 0.999999999*getInputGridObject().getGridSpacing()[dir_n];
+     174           2 : }
+     175             : 
+     176           3 : unsigned FindContourSurface::getNumberOfDerivatives() {
+     177           3 :   return gridcoords.getDimension();
+     178             : }
+     179             : 
+     180           3 : std::vector<std::string> FindContourSurface::getGridCoordinateNames() const {
+     181           3 :   return gnames;
+     182             : }
+     183             : 
+     184           3 : const gridtools::GridCoordinatesObject& FindContourSurface::getGridCoordinatesObject() const {
+     185           3 :   return gridcoords;
+     186             : }
+     187             : 
+     188         588 : void FindContourSurface::performTask( const unsigned& current, MultiValue& myvals ) const {
+     189             :   std::vector<unsigned> neighbours; unsigned num_neighbours; unsigned nfound=0; double minv=0, minp;
+     190         588 :   std::vector<unsigned> bins_n( getInputGridObject().getNbin(false) ); unsigned shiftn=current;
+     191         588 :   std::vector<unsigned> ind( getInputGridObject().getDimension() ); std::vector<double> point( getInputGridObject().getDimension() );
+     192             : #ifndef DNDEBUG
+     193         588 :   std::vector<unsigned> oind( gridcoords.getDimension() ); gridcoords.getIndices( current, oind );
+     194             : #endif
+     195       16842 :   for(unsigned i=0; i<bins_n[dir_n]; ++i) {
+     196             : #ifndef DNDEBUG
+     197       16842 :     std::vector<unsigned> base_ind( getInputGridObject().getDimension() ); getInputGridObject().getIndices( shiftn, base_ind );
+     198       50526 :     for(unsigned j=0; j<gdirs.size(); ++j) plumed_dbg_assert( base_ind[gdirs[j]]==oind[j] );
+     199             : #endif
+     200             :     // Get the index of the current grid point
+     201       16842 :     getInputGridObject().getIndices( shiftn, ind );
+     202             :     // Exit if we are at the edge of the grid
+     203       16842 :     if( !getInputGridObject().isPeriodic(dir_n) && (ind[dir_n]+1)==bins_n[dir_n] ) {
+     204           0 :       shiftn += getInputGridObject().getStride()[dir_n]; continue;
+     205             :     }
+     206             : 
+     207             :     // Ensure points with inactive neighbours are ignored
+     208       16842 :     getInputGridObject().getNeighbors( ind, ones, num_neighbours, neighbours );
+     209             : 
+     210             :     // Now get the function value at two points
+     211       16842 :     double val1=getPntrToArgument(0)->get( shiftn ) - contour; double val2;
+     212       16842 :     if( (ind[dir_n]+1)==bins_n[dir_n] ) val2 = getPntrToArgument(0)->get( current ) - contour;
+     213       16842 :     else val2=getPntrToArgument(0)->get( shiftn + getInputGridObject().getStride()[dir_n] ) - contour;
+     214             : 
+     215             :     // Check if the minimum is bracketed
+     216       16842 :     if( val1*val2<0 ) {
+     217         588 :       getInputGridObject().getGridPointCoordinates( shiftn, point ); findContour( direction, point );
+     218         588 :       minp=point[dir_n]; nfound++; break;
+     219             :     }
+     220             : 
+     221             :     // This moves us on to the next point
+     222       16254 :     shiftn += getInputGridObject().getStride()[dir_n];
+     223             :   }
+     224             :   if( nfound==0 ) {
+     225           0 :     std::string num; Tools::convert( getStep(), num );
+     226           0 :     error("On step " + num + " failed to find required grid point");
+     227             :   }
+     228         588 :   myvals.setValue( getConstPntrToComponent(0)->getPositionInStream(), minp );
+     229         588 : }
+     230             : 
+     231         588 : void FindContourSurface::gatherStoredValue( const unsigned& valindex, const unsigned& code, const MultiValue& myvals,
+     232             :     const unsigned& bufstart, std::vector<double>& buffer ) const {
+     233         588 :   plumed_dbg_assert( valindex==0 ); unsigned istart = bufstart + (1+gridcoords.getDimension())*code;
+     234         588 :   unsigned valout = getConstPntrToComponent(0)->getPositionInStream(); buffer[istart] += myvals.get( valout );
+     235         588 : }
+     236             : 
+     237             : }
+     238             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/contour/FindSphericalContour.cpp.func-sort-c.html b/coverage/contour/FindSphericalContour.cpp.func-sort-c.html new file mode 100644 index 000000000000..f74c1fe68af9 --- /dev/null +++ b/coverage/contour/FindSphericalContour.cpp.func-sort-c.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - contour/FindSphericalContour.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - contour - FindSphericalContour.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:424789.4 %
Date:2024-04-19 12:12:35Functions:7977.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7contour20FindSphericalContourC2ERKNS_13ActionOptionsE0
_ZNK4PLMD7contour20FindSphericalContour22getGridCoordinateNamesB5cxx11Ev0
_ZN4PLMD7contour20FindSphericalContour22setupValuesOnFirstStepEv1
_ZN4PLMD7contour20FindSphericalContourC1ERKNS_13ActionOptionsE1
_ZN4PLMD7contour20FindSphericalContour22getNumberOfDerivativesEv2
_ZN4PLMD7contour20FindSphericalContour16registerKeywordsERNS_8KeywordsE3
_ZNK4PLMD7contour20FindSphericalContour24getGridCoordinatesObjectEv3
_ZNK4PLMD7contour20FindSphericalContour11performTaskERKjRNS_10MultiValueE200
_ZNK4PLMD7contour20FindSphericalContour17gatherStoredValueERKjS3_RKNS_10MultiValueES3_RSt6vectorIdSaIdEE200
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/contour/FindSphericalContour.cpp.func.html b/coverage/contour/FindSphericalContour.cpp.func.html new file mode 100644 index 000000000000..b7e029a7534b --- /dev/null +++ b/coverage/contour/FindSphericalContour.cpp.func.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - contour/FindSphericalContour.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - contour - FindSphericalContour.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:424789.4 %
Date:2024-04-19 12:12:35Functions:7977.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7contour20FindSphericalContour16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD7contour20FindSphericalContour22getNumberOfDerivativesEv2
_ZN4PLMD7contour20FindSphericalContour22setupValuesOnFirstStepEv1
_ZN4PLMD7contour20FindSphericalContourC1ERKNS_13ActionOptionsE1
_ZN4PLMD7contour20FindSphericalContourC2ERKNS_13ActionOptionsE0
_ZNK4PLMD7contour20FindSphericalContour11performTaskERKjRNS_10MultiValueE200
_ZNK4PLMD7contour20FindSphericalContour17gatherStoredValueERKjS3_RKNS_10MultiValueES3_RSt6vectorIdSaIdEE200
_ZNK4PLMD7contour20FindSphericalContour22getGridCoordinateNamesB5cxx11Ev0
_ZNK4PLMD7contour20FindSphericalContour24getGridCoordinatesObjectEv3
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/contour/FindSphericalContour.cpp.gcov.html b/coverage/contour/FindSphericalContour.cpp.gcov.html new file mode 100644 index 000000000000..f2de5d9eeac6 --- /dev/null +++ b/coverage/contour/FindSphericalContour.cpp.gcov.html @@ -0,0 +1,279 @@ + + + + + + + + LCOV - plumed test coverage - contour/FindSphericalContour.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - contour - FindSphericalContour.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:424789.4 %
Date:2024-04-19 12:12:35Functions:7977.8 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2020 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received 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 contour {
+     110             : 
+     111             : class FindSphericalContour : public ContourFindingBase {
+     112             : private:
+     113             :   unsigned nbins, npoints;
+     114             :   double min, max;
+     115             :   gridtools::GridCoordinatesObject gridcoords;
+     116             : public:
+     117             :   static void registerKeywords( Keywords& keys );
+     118             :   explicit FindSphericalContour(const ActionOptions&ao);
+     119           1 :   void setupValuesOnFirstStep() override {}
+     120             :   unsigned getNumberOfDerivatives() override ;
+     121             :   std::vector<std::string> getGridCoordinateNames() const override ;
+     122             :   const gridtools::GridCoordinatesObject& getGridCoordinatesObject() const override ;
+     123             :   void performTask( const unsigned& current, MultiValue& myvals ) const override;
+     124             :   void gatherStoredValue( const unsigned& valindex, const unsigned& code, const MultiValue& myvals,
+     125             :                           const unsigned& bufstart, std::vector<double>& buffer ) const override ;
+     126             : };
+     127             : 
+     128             : PLUMED_REGISTER_ACTION(FindSphericalContour,"FIND_SPHERICAL_CONTOUR")
+     129             : 
+     130           3 : void FindSphericalContour::registerKeywords( Keywords& keys ) {
+     131           3 :   ContourFindingBase::registerKeywords( keys );
+     132           6 :   keys.add("compulsory","NPOINTS","the number of points for which we are looking for the contour");
+     133           6 :   keys.add("compulsory","INNER_RADIUS","the minimum radius on which to look for the contour");
+     134           6 :   keys.add("compulsory","OUTER_RADIUS","the outer radius on which to look for the contour");
+     135           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");
+     136           3 : }
+     137             : 
+     138           1 : FindSphericalContour::FindSphericalContour(const ActionOptions&ao):
+     139             :   Action(ao),
+     140           1 :   ContourFindingBase(ao)
+     141             : {
+     142           1 :   if( getPntrToArgument(0)->getRank()!=3 ) error("input grid must be three dimensional");
+     143             : 
+     144           2 :   parse("NPOINTS",npoints); log.printf("  searching for %u points on dividing surface \n",npoints);
+     145           3 :   parse("INNER_RADIUS",min); parse("OUTER_RADIUS",max); parse("NBINS",nbins);
+     146           1 :   log.printf("  expecting to find dividing surface at radii between %f and %f \n",min,max);
+     147           1 :   log.printf("  looking for contour in windows of length %f \n", (max-min)/nbins);
+     148             :   // Set this here so the same set of grid points are used on every turn
+     149           1 :   std::vector<bool> ipbc( 3, false ); gridcoords.setup( "fibonacci", ipbc, npoints, 0.0 );
+     150             :   // Now create a value
+     151           1 :   std::vector<unsigned> shape( 3 ); shape[0]=npoints; shape[1]=shape[2]=1;
+     152           1 :   addValueWithDerivatives( shape ); setNotPeriodic();
+     153           1 :   getPntrToComponent(0)->buildDataStore(); checkRead();
+     154           1 : }
+     155             : 
+     156           2 : unsigned FindSphericalContour::getNumberOfDerivatives() {
+     157           2 :   return gridcoords.getDimension();
+     158             : }
+     159             : 
+     160           0 : std::vector<std::string> FindSphericalContour::getGridCoordinateNames() const {
+     161           0 :   gridtools::ActionWithGrid* ag=dynamic_cast<gridtools::ActionWithGrid*>( getPntrToArgument(0)->getPntrToAction() );
+     162           0 :   plumed_assert( ag ); return ag->getGridCoordinateNames();
+     163             : }
+     164             : 
+     165           3 : const gridtools::GridCoordinatesObject& FindSphericalContour::getGridCoordinatesObject() const {
+     166           3 :   return gridcoords;
+     167             : }
+     168             : 
+     169         200 : void FindSphericalContour::performTask( const unsigned& current, MultiValue& myvals ) const {
+     170             :   // Generate contour point on inner sphere
+     171         200 :   std::vector<double> contour_point(3), direction(3), der(3), tmp(3);
+     172             :   // Retrieve this contour point from grid
+     173         200 :   gridcoords.getGridPointCoordinates( current, direction );
+     174             :   // Now setup contour point on inner sphere
+     175         800 :   for(unsigned j=0; j<3; ++j) {
+     176         600 :     contour_point[j] = min*direction[j];
+     177         600 :     direction[j] = (max-min)*direction[j] / static_cast<double>(nbins);
+     178             :   }
+     179             : 
+     180             :   bool found=false;
+     181         200 :   for(unsigned k=0; k<nbins; ++k) {
+     182         800 :     for(unsigned j=0; j<3; ++j) tmp[j] = contour_point[j] + direction[j];
+     183         200 :     double val1 = getDifferenceFromContour( contour_point, der );
+     184         200 :     double val2 = getDifferenceFromContour( tmp, der );
+     185         200 :     if( val1*val2<0 ) {
+     186             :       findContour( direction, contour_point );
+     187         800 :       double norm=0; for(unsigned j=0; j<3; ++j) norm += contour_point[j]*contour_point[j];
+     188         200 :       myvals.setValue( getConstPntrToComponent(0)->getPositionInStream(), sqrt(norm) ); found=true; break;
+     189             :     }
+     190           0 :     for(unsigned j=0; j<3; ++j) contour_point[j] = tmp[j];
+     191             :   }
+     192           0 :   if( !found ) error("range does not bracket the dividing surface");
+     193         200 : }
+     194             : 
+     195         200 : void FindSphericalContour::gatherStoredValue( const unsigned& valindex, const unsigned& code, const MultiValue& myvals,
+     196             :     const unsigned& bufstart, std::vector<double>& buffer ) const {
+     197         200 :   plumed_assert( valindex==0 ); unsigned istart = bufstart + (1+gridcoords.getDimension())*code;
+     198         200 :   unsigned valout = getConstPntrToComponent(0)->getPositionInStream(); buffer[istart] += myvals.get( valout );
+     199         200 : }
+     200             : 
+     201             : }
+     202             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/contour/index-sort-f.html b/coverage/contour/index-sort-f.html new file mode 100644 index 000000000000..8576df926b6b --- /dev/null +++ b/coverage/contour/index-sort-f.html @@ -0,0 +1,194 @@ + + + + + + + + LCOV - plumed test coverage - contour + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - contourHitTotalCoverage
Test:plumed test coverageLines:41744693.5 %
Date:2024-04-19 12:12:35Functions:486277.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
FindContour.h +
0.0%
+
0.0 %0 / 20.0 %0 / 2
DistanceFromContourBase.h +
83.3%83.3%
+
83.3 %5 / 650.0 %1 / 2
DistanceFromSphericalContour.cpp +
94.4%94.4%
+
94.4 %34 / 3660.0 %3 / 5
ContourFindingBase.cpp +
100.0%
+
100.0 %13 / 1375.0 %3 / 4
FindContour.cpp +
96.4%96.4%
+
96.4 %54 / 5677.8 %7 / 9
FindSphericalContour.cpp +
89.4%89.4%
+
89.4 %42 / 4777.8 %7 / 9
DistanceFromContour.cpp +
85.3%85.3%
+
85.3 %81 / 9580.0 %4 / 5
DumpContour.cpp +
100.0%
+
100.0 %35 / 3587.5 %7 / 8
DistanceFromContourBase.cpp +
100.0%
+
100.0 %74 / 7487.5 %7 / 8
FindContourSurface.cpp +
96.1%96.1%
+
96.1 %73 / 7688.9 %8 / 9
ContourFindingBase.h +
100.0%
+
100.0 %6 / 6100.0 %1 / 1
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/contour/index-sort-l.html b/coverage/contour/index-sort-l.html new file mode 100644 index 000000000000..121ef2ae0edb --- /dev/null +++ b/coverage/contour/index-sort-l.html @@ -0,0 +1,194 @@ + + + + + + + + LCOV - plumed test coverage - contour + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - contourHitTotalCoverage
Test:plumed test coverageLines:41744693.5 %
Date:2024-04-19 12:12:35Functions:486277.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
FindContour.h +
0.0%
+
0.0 %0 / 20.0 %0 / 2
DistanceFromContourBase.h +
83.3%83.3%
+
83.3 %5 / 650.0 %1 / 2
DistanceFromContour.cpp +
85.3%85.3%
+
85.3 %81 / 9580.0 %4 / 5
FindSphericalContour.cpp +
89.4%89.4%
+
89.4 %42 / 4777.8 %7 / 9
DistanceFromSphericalContour.cpp +
94.4%94.4%
+
94.4 %34 / 3660.0 %3 / 5
FindContourSurface.cpp +
96.1%96.1%
+
96.1 %73 / 7688.9 %8 / 9
FindContour.cpp +
96.4%96.4%
+
96.4 %54 / 5677.8 %7 / 9
ContourFindingBase.h +
100.0%
+
100.0 %6 / 6100.0 %1 / 1
ContourFindingBase.cpp +
100.0%
+
100.0 %13 / 1375.0 %3 / 4
DumpContour.cpp +
100.0%
+
100.0 %35 / 3587.5 %7 / 8
DistanceFromContourBase.cpp +
100.0%
+
100.0 %74 / 7487.5 %7 / 8
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/contour/index.html b/coverage/contour/index.html new file mode 100644 index 000000000000..804309bd99f7 --- /dev/null +++ b/coverage/contour/index.html @@ -0,0 +1,194 @@ + + + + + + + + LCOV - plumed test coverage - contour + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - contourHitTotalCoverage
Test:plumed test coverageLines:41744693.5 %
Date:2024-04-19 12:12:35Functions:486277.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
ContourFindingBase.cpp +
100.0%
+
100.0 %13 / 1375.0 %3 / 4
ContourFindingBase.h +
100.0%
+
100.0 %6 / 6100.0 %1 / 1
DistanceFromContour.cpp +
85.3%85.3%
+
85.3 %81 / 9580.0 %4 / 5
DistanceFromContourBase.cpp +
100.0%
+
100.0 %74 / 7487.5 %7 / 8
DistanceFromContourBase.h +
83.3%83.3%
+
83.3 %5 / 650.0 %1 / 2
DistanceFromSphericalContour.cpp +
94.4%94.4%
+
94.4 %34 / 3660.0 %3 / 5
DumpContour.cpp +
100.0%
+
100.0 %35 / 3587.5 %7 / 8
FindContour.cpp +
96.4%96.4%
+
96.4 %54 / 5677.8 %7 / 9
FindContour.h +
0.0%
+
0.0 %0 / 20.0 %0 / 2
FindContourSurface.cpp +
96.1%96.1%
+
96.1 %73 / 7688.9 %8 / 9
FindSphericalContour.cpp +
89.4%89.4%
+
89.4 %42 / 4777.8 %7 / 9
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/Action.cpp.func-sort-c.html b/coverage/core/Action.cpp.func-sort-c.html new file mode 100644 index 000000000000..532b711e2896 --- /dev/null +++ b/coverage/core/Action.cpp.func-sort-c.html @@ -0,0 +1,221 @@ + + + + + + + + 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:16920283.7 %
Date:2024-04-19 12:12:35Functions:313783.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6Action10getKeywordERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD6Action12clearOptionsEv0
_ZN4PLMD6Action16calculateFromPDBERKNS_3PDBE0
_ZN4PLMD6Action29calculateNumericalDerivativesEPNS_15ActionWithValueE0
_ZN4PLMD6Action4exitEi0
_ZN4PLMD6ActionD0Ev0
_ZN4PLMD6Action4citeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE24
_ZNK4PLMD6Action5errorERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE28
_ZNK4PLMD6Action12writeInGraphB5cxx11Ev44
_ZN4PLMD6Action5fopenEPKcS2_82
_ZN4PLMD6Action6fcloseEP8_IO_FILE99
_ZN4PLMD6Action6getkBTEv619
_ZNK4PLMD6Action13getKBoltzmannEv668
_ZNK4PLMD6Action6getCPTEv1095
_ZNK4PLMD6Action17usingNaturalUnitsEv2119
_ZN4PLMD6Action9setOptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2228
_ZN4PLMD6Action7warningERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE4167
_ZNK4PLMD6Action15getExchangeStepEv28109
_ZN4PLMD6ActionD2Ev49643
_ZN4PLMD13ActionOptionsC2ERKS0_RKNS_8KeywordsE49644
_ZN4PLMD6ActionC2ERKNS_13ActionOptionsE49644
_ZN4PLMD13ActionOptionsC2ERNS_10PlumedMainERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EE49646
_ZN4PLMD6Action16registerKeywordsERNS_8KeywordsE51019
_ZN4PLMD6Action6fflushEv60157
_ZN4PLMD6Action9checkReadEv65377
_ZN4PLMD6Action9parseFlagERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERb91701
_ZN4PLMD6Action19setupConstantValuesERKb92606
_ZN4PLMD6Action17clearDependenciesEv199191
_ZNK4PLMD6Action11getTimeStepEv217999
_ZN4PLMD6Action18checkForDependencyEPS0_571248
_ZN4PLMD6Action7prepareEv998496
_ZN4PLMD6Action13addDependencyEPS0_1261652
_ZNK4PLMD6Action11checkUpdateEv2518274
_ZNK4PLMD6Action7getTimeEv3620571
_ZN4PLMD6Action8activateEv5177861
_ZNK4PLMD6Action7getStepEv5349590
_ZNK4PLMD6Action8getUnitsEv14981252
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/Action.cpp.func.html b/coverage/core/Action.cpp.func.html new file mode 100644 index 000000000000..2ef1a09ae1e5 --- /dev/null +++ b/coverage/core/Action.cpp.func.html @@ -0,0 +1,221 @@ + + + + + + + + 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:16920283.7 %
Date:2024-04-19 12:12:35Functions:313783.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD13ActionOptionsC2ERKS0_RKNS_8KeywordsE49644
_ZN4PLMD13ActionOptionsC2ERNS_10PlumedMainERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EE49646
_ZN4PLMD6Action10getKeywordERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD6Action12clearOptionsEv0
_ZN4PLMD6Action13addDependencyEPS0_1261652
_ZN4PLMD6Action16calculateFromPDBERKNS_3PDBE0
_ZN4PLMD6Action16registerKeywordsERNS_8KeywordsE51019
_ZN4PLMD6Action17clearDependenciesEv199191
_ZN4PLMD6Action18checkForDependencyEPS0_571248
_ZN4PLMD6Action19setupConstantValuesERKb92606
_ZN4PLMD6Action29calculateNumericalDerivativesEPNS_15ActionWithValueE0
_ZN4PLMD6Action4citeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE24
_ZN4PLMD6Action4exitEi0
_ZN4PLMD6Action5fopenEPKcS2_82
_ZN4PLMD6Action6fcloseEP8_IO_FILE99
_ZN4PLMD6Action6fflushEv60157
_ZN4PLMD6Action6getkBTEv619
_ZN4PLMD6Action7prepareEv998496
_ZN4PLMD6Action7warningERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE4167
_ZN4PLMD6Action8activateEv5177861
_ZN4PLMD6Action9checkReadEv65377
_ZN4PLMD6Action9parseFlagERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERb91701
_ZN4PLMD6Action9setOptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2228
_ZN4PLMD6ActionC2ERKNS_13ActionOptionsE49644
_ZN4PLMD6ActionD0Ev0
_ZN4PLMD6ActionD2Ev49643
_ZNK4PLMD6Action11checkUpdateEv2518274
_ZNK4PLMD6Action11getTimeStepEv217999
_ZNK4PLMD6Action12writeInGraphB5cxx11Ev44
_ZNK4PLMD6Action13getKBoltzmannEv668
_ZNK4PLMD6Action15getExchangeStepEv28109
_ZNK4PLMD6Action17usingNaturalUnitsEv2119
_ZNK4PLMD6Action5errorERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE28
_ZNK4PLMD6Action6getCPTEv1095
_ZNK4PLMD6Action7getStepEv5349590
_ZNK4PLMD6Action7getTimeEv3620571
_ZNK4PLMD6Action8getUnitsEv14981252
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/Action.cpp.gcov.html b/coverage/core/Action.cpp.gcov.html new file mode 100644 index 000000000000..e6c6f41833c7 --- /dev/null +++ b/coverage/core/Action.cpp.gcov.html @@ -0,0 +1,441 @@ + + + + + + + + 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:16920283.7 %
Date:2024-04-19 12:12:35Functions:313783.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 "Action.h"
+      23             : #include "ActionAtomistic.h"
+      24             : #include "ActionWithValue.h"
+      25             : #include "ActionWithArguments.h"
+      26             : #include "ActionWithVirtualAtom.h"
+      27             : #include "ActionForInterface.h"
+      28             : #include "DomainDecomposition.h"
+      29             : #include "PbcAction.h"
+      30             : #include "ActionToPutData.h"
+      31             : #include "ActionToGetData.h"
+      32             : #include "PlumedMain.h"
+      33             : #include "tools/Log.h"
+      34             : #include "tools/Exception.h"
+      35             : #include "tools/Communicator.h"
+      36             : #include "ActionSet.h"
+      37             : #include <iostream>
+      38             : 
+      39             : namespace PLMD {
+      40             : 
+      41             : Keywords ActionOptions::emptyKeys;
+      42             : 
+      43       49646 : ActionOptions::ActionOptions(PlumedMain&p,const std::vector<std::string>&l):
+      44       49646 :   plumed(p),
+      45       49646 :   line(l),
+      46       49646 :   keys(emptyKeys)
+      47             : {
+      48       49646 : }
+      49             : 
+      50       49644 : ActionOptions::ActionOptions(const ActionOptions&ao,const Keywords&keys):
+      51       49644 :   plumed(ao.plumed),
+      52       49644 :   line(ao.line),
+      53       49644 :   keys(keys)
+      54             : {
+      55       49644 : }
+      56             : 
+      57       51019 : void Action::registerKeywords( Keywords& keys ) {
+      58       51019 :   plumed_assert( keys.size()==0 );
+      59      102038 :   keys.add( "hidden", "LABEL", "a label for the action so that its output can be referenced in the input to other actions.  Actions with scalar output are referenced using their label only.  Actions with vector output must have a separate label for every component.  Individual components are then referred to using label.component" );
+      60      102038 :   keys.reserve("optional","UPDATE_FROM","Only update this action from this time");
+      61      102038 :   keys.reserve("optional","UPDATE_UNTIL","Only update this action until this time");
+      62      102038 :   keys.reserve("optional","RESTART","allows per-action setting of restart (YES/NO/AUTO)");
+      63       51019 : }
+      64             : 
+      65       49644 : Action::Action(const ActionOptions&ao):
+      66       49644 :   name(ao.line[0]),
+      67       49644 :   line(ao.line),
+      68       49644 :   update_from(std::numeric_limits<double>::max()),
+      69       49644 :   update_until(std::numeric_limits<double>::max()),
+      70       49644 :   timestep(0),
+      71       49644 :   active(false),
+      72       49644 :   restart(ao.plumed.getRestart()),
+      73       49644 :   doCheckPoint(ao.plumed.getCPT()),
+      74       49644 :   never_activate(name=="CONSTANT"),
+      75       49644 :   plumed(ao.plumed),
+      76       49644 :   log(plumed.getLog()),
+      77       49644 :   comm(plumed.comm),
+      78       49644 :   multi_sim_comm(plumed.multi_sim_comm),
+      79       99288 :   keywords(ao.keys)
+      80             : {
+      81             :   // Retrieve the timestep and save it
+      82       49645 :   ActionWithValue* ts = plumed.getActionSet().selectWithLabel<ActionWithValue*>("timestep");
+      83       49644 :   if( ts ) timestep = (ts->copyOutput(0))->get();
+      84             : 
+      85             :   line.erase(line.begin());
+      86       99288 :   if( !keywords.exists("NO_ACTION_LOG") ) {
+      87       35098 :     log.printf("Action %s\n",name.c_str());
+      88       35098 :     if(ao.fullPath.length()>0) log<<"  from library: "<<ao.fullPath<<"\n";
+      89             :   }
+      90             : 
+      91       49644 :   if(comm.Get_rank()==0) {
+      92       35817 :     replica_index=multi_sim_comm.Get_rank();
+      93             :   }
+      94       49644 :   comm.Bcast(replica_index,0);
+      95             : 
+      96      148731 :   if ( keywords.exists("LABEL") ) { parse("LABEL",label); }
+      97       49644 :   if(label.length()==0) {
+      98        2898 :     std::string s; Tools::convert(plumed.getActionSet().size()-plumed.getActionSet().select<ActionForInterface*>().size(),s);
+      99        5796 :     label="@"+s;
+     100             :   }
+     101       49644 :   if( plumed.getActionSet().selectWithLabel<Action*>(label) ) error("label " + label + " has been already used");
+     102       99288 :   if( !keywords.exists("NO_ACTION_LOG") ) log.printf("  with label %s\n",label.c_str());
+     103      101390 :   if ( keywords.exists("UPDATE_FROM") ) parse("UPDATE_FROM",update_from);
+     104       99288 :   if( !keywords.exists("NO_ACTION_LOG") && update_from!=std::numeric_limits<double>::max()) log.printf("  only update from time %f\n",update_from);
+     105      101390 :   if ( keywords.exists("UPDATE_UNTIL") ) parse("UPDATE_UNTIL",update_until);
+     106       99288 :   if( !keywords.exists("NO_ACTION_LOG") && update_until!=std::numeric_limits<double>::max()) log.printf("  only update until time %f\n",update_until);
+     107       99288 :   if ( keywords.exists("RESTART") ) {
+     108        2020 :     std::string srestart="AUTO";
+     109        2019 :     parse("RESTART",srestart);
+     110        2019 :     if( plumed.parseOnlyMode() ) restart=false;
+     111        2019 :     else if(srestart=="YES") restart=true;
+     112        1937 :     else if(srestart=="NO")  restart=false;
+     113        1915 :     else if(srestart=="AUTO") {
+     114             :       // do nothing, this is the default
+     115           2 :     } else error("RESTART should be either YES, NO, or AUTO");
+     116             :   }
+     117       49644 : }
+     118             : 
+     119       99286 : Action::~Action() {
+     120       49643 :   if(files.size()!=0) {
+     121           0 :     std::cerr<<"WARNING: some files open in action "+getLabel()+" where not properly closed. This could lead to data loss!!\n";
+     122             :   }
+     123       99286 : }
+     124             : 
+     125          82 : FILE* Action::fopen(const char *path, const char *mode) {
+     126             :   bool write(false);
+     127         164 :   for(const char*p=mode; *p; p++) if(*p=='w' || *p=='a' || *p=='+') write=true;
+     128             :   FILE* fp;
+     129          82 :   if(write && comm.Get_rank()!=0) fp=plumed.fopen("/dev/null",mode);
+     130          82 :   else      fp=plumed.fopen(path,mode);
+     131          81 :   files.insert(fp);
+     132          81 :   return fp;
+     133             : }
+     134             : 
+     135          99 : int Action::fclose(FILE*fp) {
+     136             :   files.erase(fp);
+     137          99 :   return plumed.fclose(fp);
+     138             : }
+     139             : 
+     140       60157 : void Action::fflush() {
+     141       60157 :   for(const auto & p : files) {
+     142           0 :     std::fflush(p);
+     143             :   }
+     144       60157 : }
+     145             : 
+     146           0 : std::string Action::getKeyword(const std::string& key) {
+     147             :   // Check keyword has been registered
+     148           0 :   plumed_massert(keywords.exists(key), "keyword " + key + " has not been registered");
+     149             : 
+     150             :   std::string outkey;
+     151           0 :   if( Tools::getKey(line,key,outkey ) ) return key + outkey;
+     152             : 
+     153           0 :   if( keywords.style(key,"compulsory") ) {
+     154           0 :     if( keywords.getDefaultValue(key,outkey) ) {
+     155           0 :       if( outkey.length()==0 ) error("keyword " + key + " has weird default value");
+     156           0 :       return key + "=" +  outkey;
+     157             :     } else {
+     158           0 :       error("keyword " + key + " is compulsory for this action");
+     159             :     }
+     160             :   }
+     161           0 :   return "";
+     162             : }
+     163             : 
+     164       91701 : void Action::parseFlag(const std::string&key,bool & t) {
+     165             :   // Check keyword has been registered
+     166       91701 :   plumed_massert(keywords.exists(key), "keyword " + key + " has not been registered");
+     167             :   // Check keyword is a flag
+     168      183402 :   if(!keywords.style(key,"nohtml")) {
+     169      183402 :     plumed_massert( keywords.style(key,"vessel") || keywords.style(key,"flag") || keywords.style(key,"hidden"), "keyword " + key + " is not a flag");
+     170             :   }
+     171             : 
+     172             :   // Read in the flag otherwise get the default value from the keywords object
+     173       91701 :   if(!Tools::parseFlag(line,key,t)) {
+     174      161432 :     if( keywords.style(key,"nohtml") || keywords.style(key,"vessel") ) {
+     175           0 :       t=false;
+     176       80716 :     } else if ( !keywords.getLogicalDefault(key,t) ) {
+     177           0 :       log.printf("ERROR in action %s with label %s : flag %s has no default",name.c_str(),label.c_str(),key.c_str() );
+     178           0 :       plumed_error();
+     179             :     }
+     180             :   }
+     181       91701 : }
+     182             : 
+     183     1261652 : void Action::addDependency(Action*action) {
+     184             :   bool found=false;
+     185    40063890 :   for(const auto & d : after ) {
+     186    39064989 :     if( action==d ) { found=true; break; }
+     187             :   }
+     188     1261652 :   if( !found ) after.push_back(action);
+     189     1261652 : }
+     190             : 
+     191      571248 : bool Action::checkForDependency( Action* action ) {
+     192     1124556 :   for(const auto & d : after) {
+     193      563813 :     if( action==d ) { return true; }
+     194      557480 :     if( d->checkForDependency(action) ) { return true; }
+     195             :   }
+     196             :   return false;
+     197             : }
+     198             : 
+     199     5177861 : void Action::activate() {
+     200             : // This is set to true if actions are only need to be computed in setup (during checkRead)
+     201     5177861 :   if( never_activate ) return;
+     202             : // preparation step is called only the first time an Action is activated.
+     203             : // since it could change its dependences (e.g. in an ActionAtomistic which is
+     204             : // accessing to a virtual atom), this is done just before dependencies are
+     205             : // activated
+     206     5063503 :   if(!active) {
+     207     2617646 :     this->unlockRequests();
+     208     2617646 :     prepare();
+     209     2617646 :     this->lockRequests();
+     210             :   } else return;
+     211     6453273 :   for(const auto & p : after) p->activate();
+     212     2617646 :   active=true;
+     213             : }
+     214             : 
+     215        2228 : void Action::setOption(const std::string &s) {
+     216             : // This overloads the action and activate some options
+     217        2228 :   options.insert(s);
+     218        4370 :   for(const auto & p : after) p->setOption(s);
+     219        2228 : }
+     220             : 
+     221           0 : void Action::clearOptions() {
+     222             : // This overloads the action and activate some options
+     223             :   options.clear();
+     224           0 : }
+     225             : 
+     226             : 
+     227      199191 : void Action::clearDependencies() {
+     228             :   after.clear();
+     229      199191 : }
+     230             : 
+     231       65377 : void Action::checkRead() {
+     232       65377 :   if(!line.empty()) {
+     233           1 :     std::string msg="cannot understand the following words from the input line : ";
+     234           2 :     for(unsigned i=0; i<line.size(); i++) {
+     235           1 :       if(i>0) msg = msg + ", ";
+     236           2 :       msg = msg + line[i];
+     237             :     }
+     238           1 :     error(msg);
+     239             :   }
+     240       65376 :   setupConstantValues(false);
+     241       65376 : }
+     242             : 
+     243       92606 : void Action::setupConstantValues( const bool& have_atoms ) {
+     244       92606 :   if( have_atoms ) {
+     245             :     // This ensures that we switch off actions that only depend on constant when passed from the
+     246             :     // MD code on the first step
+     247       27230 :     ActionAtomistic* at = castToActionAtomistic();
+     248       27230 :     ActionWithValue* av = castToActionWithValue();
+     249       27230 :     if( at && av ) {
+     250       15817 :       never_activate=av->getNumberOfComponents()>0;
+     251       15864 :       for(unsigned i=0; i<av->getNumberOfComponents(); ++i) {
+     252       15817 :         if( !av->copyOutput(i)->isConstant() ) { never_activate=false; break; }
+     253             :       }
+     254             :     }
+     255             :   }
+     256       92606 :   ActionWithArguments* aa = castToActionWithArguments();
+     257      110968 :   if( aa && aa->getNumberOfArguments()>0 && getName()!="BIASVALUE" ) never_activate = aa->calculateConstantValues( have_atoms );
+     258       92606 : }
+     259             : 
+     260     5349590 : long long int Action::getStep()const {
+     261     5349590 :   return plumed.getStep();
+     262             : }
+     263             : 
+     264     3620571 : double Action::getTime()const {
+     265     3620571 :   return timestep*getStep();
+     266             : }
+     267             : 
+     268      217999 : double Action::getTimeStep()const {
+     269      217999 :   return timestep;
+     270             : }
+     271             : 
+     272         619 : double Action::getkBT() {
+     273         619 :   double temp=-1.0;
+     274        1843 :   if( keywords.exists("TEMP") ) parse("TEMP",temp);
+     275        1555 :   if(temp>=0.0 && keywords.style("TEMP","optional") ) return getKBoltzmann()*temp;
+     276         238 :   ActionForInterface* kb=plumed.getActionSet().selectWithLabel<ActionForInterface*>("kBT");
+     277         238 :   double kbt=0; if(kb) kbt=(kb->copyOutput(0))->get();
+     278         354 :   if( temp>=0 && keywords.style("TEMP","compulsory") ) {
+     279          58 :     double kB=getKBoltzmann();
+     280          58 :     if( kbt>0 && std::abs(kbt-kB*temp)>1e-4) {
+     281           0 :       std::string strt1, strt2; Tools::convert( temp, strt1 ); Tools::convert( kbt/kB, strt2 );
+     282           0 :       warning("using TEMP=" + strt1 + " while MD engine uses " + strt2 + "\n");
+     283             :     }
+     284          58 :     kbt = kB*temp;
+     285          58 :     plumed_massert(kbt>0,"your MD engine does not pass the temperature to plumed, you must specify it using TEMP");
+     286             :     return kbt;
+     287             :   }
+     288             :   return kbt;
+     289             : }
+     290             : 
+     291           0 : void Action::exit(int c) {
+     292           0 :   plumed.exit(c);
+     293           0 : }
+     294             : 
+     295           0 : void Action::calculateNumericalDerivatives( ActionWithValue* a ) {
+     296           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");
+     297             : }
+     298             : 
+     299      998496 : void Action::prepare() {
+     300      998496 :   return;
+     301             : }
+     302             : 
+     303          28 : [[noreturn]] void Action::error( const std::string & msg ) const {
+     304          56 :   if( !keywords.exists("NO_ACTION_LOG") ) log.printf("ERROR in input to action %s with label %s : %s \n \n", name.c_str(), label.c_str(), msg.c_str() );
+     305          84 :   plumed_merror("ERROR in input to action " + name + " with label " + label + " : " + msg );
+     306             : }
+     307             : 
+     308        4167 : void Action::warning( const std::string & msg ) {
+     309        4167 :   log.printf("WARNING for action %s with label %s : %s \n", name.c_str(), label.c_str(), msg.c_str() );
+     310        4167 : }
+     311             : 
+     312           0 : void Action::calculateFromPDB( const PDB& pdb ) {
+     313           0 :   activate();
+     314           0 :   for(const auto & p : after) {
+     315           0 :     ActionWithValue*av=castToActionWithValue();
+     316           0 :     if(av) { av->clearInputForces(); av->clearDerivatives(); }
+     317           0 :     p->readAtomsFromPDB( pdb );
+     318           0 :     p->calculate();
+     319             :   }
+     320           0 :   readAtomsFromPDB( pdb );
+     321           0 :   calculate();
+     322           0 : }
+     323             : 
+     324       28109 : bool Action::getExchangeStep()const {
+     325       28109 :   return plumed.getExchangeStep();
+     326             : }
+     327             : 
+     328          24 : std::string Action::cite(const std::string&s) {
+     329          24 :   return plumed.cite(s);
+     330             : }
+     331             : 
+     332             : /// Check if action should be updated.
+     333     2518274 : bool Action::checkUpdate()const {
+     334     2518274 :   double t=getTime();
+     335     2518274 :   if(t<update_until && (update_from==std::numeric_limits<double>::max() || t>=update_from)) return true;
+     336         510 :   else return false;
+     337             : }
+     338             : 
+     339        1095 : bool Action::getCPT() const {
+     340        1095 :   return plumed.getCPT();
+     341             : }
+     342             : 
+     343    14981252 : const Units& Action::getUnits() const {
+     344    14981252 :   return plumed.getUnits();
+     345             : }
+     346             : 
+     347        2119 : bool Action::usingNaturalUnits() const {
+     348        2119 :   return plumed.usingNaturalUnits();
+     349             : }
+     350             : 
+     351         668 : double Action::getKBoltzmann() const {
+     352         668 :   if( usingNaturalUnits() ) return 1.0;
+     353         668 :   else return kBoltzmann/getUnits().getEnergy();
+     354             : }
+     355             : 
+     356          44 : std::string Action::writeInGraph() const {
+     357             :   std::string nam=getName();
+     358          44 :   std::size_t u=nam.find_last_of("_"); std::string sub=nam.substr(u+1);
+     359         118 :   if( sub=="SCALAR" || sub=="VECTOR" || sub=="GRID" ) return nam.substr(0,u);
+     360             :   return nam;
+     361             : }
+     362             : 
+     363             : }
+     364             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/Action.h.func-sort-c.html b/coverage/core/Action.h.func-sort-c.html new file mode 100644 index 000000000000..ed796694442d --- /dev/null +++ b/coverage/core/Action.h.func-sort-c.html @@ -0,0 +1,225 @@ + + + + + + + + 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:778491.7 %
Date:2024-04-19 12:12:35Functions:333886.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6Action13parseNumberedIeEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiRT_0
_ZN4PLMD6Action15castToPbcActionEv0
_ZN4PLMD6Action16readAtomsFromPDBERKNS_3PDBE0
_ZN4PLMD6Action20castToActionShortcutEv0
_ZN4PLMD6Action21castToActionToGetDataEv0
_ZN4PLMD6Action5parseImEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_12
_ZN4PLMD6Action19parseNumberedVectorIxEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiRSt6vectorIT_SaISB_EE14
_ZN4PLMD6Action19parseNumberedVectorIeEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiRSt6vectorIT_SaISB_EE32
_ZN4PLMD6Action11parseVectorIiEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIT_SaISB_EE36
_ZN4PLMD6Action5parseIxEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_109
_ZN4PLMD6Action24castToActionForInterfaceEv620
_ZN4PLMD6Action13parseNumberedIdEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiRT_1374
_ZN4PLMD6Action19parseNumberedVectorIdEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiRSt6vectorIT_SaISB_EE1377
_ZN4PLMD6Action5parseIjEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_5796
_ZN4PLMD6Action5parseIiEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_7198
_ZN4PLMD6Action11parseVectorIjEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIT_SaISB_EE7257
_ZN4PLMD6Action25castToDomainDecompositionEv7700
_ZN4PLMD6Action11parseVectorIdEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIT_SaISB_EE15976
_ZN4PLMD6Action5parseIdEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_28469
_ZN4PLMD6Action19parseNumberedVectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEbRKS7_iRSt6vectorIT_SaISB_EE29063
_ZN4PLMD6Action13parseNumberedINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEbRKS7_iRT_37170
_ZN4PLMD6Action12runFinalJobsEv45829
_ZN4PLMD6Action11parseVectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKS7_RSt6vectorIT_SaISB_EE56968
_ZN4PLMD6Action25castToActionWithArgumentsEv72209
_ZN4PLMD6Action5parseINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKS7_RT_91704
_ZN4PLMD6Action19parseNumberedVectorIjEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiRSt6vectorIT_SaISB_EE99393
_ZNK4PLMD6Action25checkNumericalDerivativesEv276714
_ZN4PLMD6Action21castToActionWithValueEv282933
_ZN4PLMD6Action6updateEv1269474
_ZN4PLMD6Action12lockRequestsEv1464634
_ZN4PLMD6Action14unlockRequestsEv1464634
_ZNK4PLMD6Action10isOptionOnERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1850573
_ZN4PLMD6Action21castToActionAtomisticEv2152357
_ZNK4PLMD6Action19checkNeedsGradientsEv2607447
_ZN4PLMD6Action27castToActionWithVirtualAtomEv3383068
_ZN4PLMD6Action12beforeUpdateEv4099354
_ZN4PLMD6Action10deactivateEv4350797
_ZN4PLMD6Action21castToActionToPutDataEv7392929
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/Action.h.func.html b/coverage/core/Action.h.func.html new file mode 100644 index 000000000000..5850073977c3 --- /dev/null +++ b/coverage/core/Action.h.func.html @@ -0,0 +1,225 @@ + + + + + + + + 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:778491.7 %
Date:2024-04-19 12:12:35Functions:333886.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14ActionAnyorderC1ERKNS_13ActionOptionsE0
_ZN4PLMD14ActionAnyorder16registerKeywordsERNS_8KeywordsE44
_ZN4PLMD14ActionAnyorderC2ERKNS_13ActionOptionsE156
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionAnyorder.cpp.func.html b/coverage/core/ActionAnyorder.cpp.func.html new file mode 100644 index 000000000000..826e2c016397 --- /dev/null +++ b/coverage/core/ActionAnyorder.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionAnyorder.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionAnyorder.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:66100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14ActionAnyorder16registerKeywordsERNS_8KeywordsE44
_ZN4PLMD14ActionAnyorderC1ERKNS_13ActionOptionsE0
_ZN4PLMD14ActionAnyorderC2ERKNS_13ActionOptionsE156
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionAnyorder.cpp.gcov.html b/coverage/core/ActionAnyorder.cpp.gcov.html new file mode 100644 index 000000000000..69818574394f --- /dev/null +++ b/coverage/core/ActionAnyorder.cpp.gcov.html @@ -0,0 +1,115 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionAnyorder.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionAnyorder.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:66100.0 %
Date:2024-04-19 12:12:35Functions: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 "ActionAnyorder.h"
+      23             : #include "PlumedMain.h"
+      24             : #include "ActionSet.h"
+      25             : #include "tools/Exception.h"
+      26             : 
+      27             : namespace PLMD {
+      28             : 
+      29         156 : ActionAnyorder::ActionAnyorder(const ActionOptions&ao):
+      30         156 :   Action(ao)
+      31             : {
+      32         156 : }
+      33             : 
+      34          44 : void ActionAnyorder::registerKeywords( Keywords& keys ) {
+      35          44 :   Action::registerKeywords(keys);
+      36          44 : }
+      37             : 
+      38             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionAnyorder.h.func-sort-c.html b/coverage/core/ActionAnyorder.h.func-sort-c.html new file mode 100644 index 000000000000..bbfda67dab7c --- /dev/null +++ b/coverage/core/ActionAnyorder.h.func-sort-c.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionAnyorder.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionAnyorder.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1333.3 %
Date:2024-04-19 12:12:35Functions:020.0 %
+
+ +
+ + + + + + + + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14ActionAnyorder5applyEv0
_ZN4PLMD14ActionAnyorder9calculateEv0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionAnyorder.h.gcov.html b/coverage/core/ActionAnyorder.h.gcov.html new file mode 100644 index 000000000000..753eb0b203a9 --- /dev/null +++ b/coverage/core/ActionAnyorder.h.gcov.html @@ -0,0 +1,125 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionAnyorder.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionAnyorder.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1333.3 %
Date:2024-04-19 12:12:35Functions: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          92 : class ActionAnyorder :
+      34             :   public virtual Action {
+      35             : public:
+      36             : /// Constructor
+      37             :   explicit ActionAnyorder(const ActionOptions&ao);
+      38             : /// Creator of keywords
+      39             :   static void registerKeywords( Keywords& keys );
+      40             : /// Do nothing.
+      41           0 :   void calculate() override {}
+      42             : /// Do nothing.
+      43           0 :   void apply() override {}
+      44             : };
+      45             : 
+      46             : }
+      47             : 
+      48             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionAtomistic.cpp.func-sort-c.html b/coverage/core/ActionAtomistic.cpp.func-sort-c.html new file mode 100644 index 000000000000..1a132e6e4e88 --- /dev/null +++ b/coverage/core/ActionAtomistic.cpp.func-sort-c.html @@ -0,0 +1,177 @@ + + + + + + + + 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:26728394.3 %
Date:2024-04-19 12:12:35Functions:212680.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15ActionAtomistic16readAtomsFromPDBERKNS_3PDBE0
_ZN4PLMD15ActionAtomistic9changeBoxERKNS_13TensorGenericILj3ELj3EEE0
_ZN4PLMD15ActionAtomisticC1ERKNS_13ActionOptionsE0
_ZN4PLMD15ActionAtomisticD0Ev0
_ZN4PLMD15ActionAtomisticD1Ev0
_ZNK4PLMD15ActionAtomistic9getVirialEv6
_ZN4PLMD15ActionAtomistic29calculateNumericalDerivativesEPNS_15ActionWithValueE156
_ZN4PLMD15ActionAtomistic35calculateAtomicNumericalDerivativesEPNS_15ActionWithValueERKj240
_ZNK4PLMD15ActionAtomistic11getGradientERKjRNS_13VectorGenericILj3EEERSt3mapINS_10AtomNumberES4_St4lessIS7_ESaISt4pairIKS7_S4_EEE8208
_ZN4PLMD15ActionAtomistic13parseAtomListERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorINS_10AtomNumberESaISA_EE13738
_ZN4PLMD15ActionAtomistic12requestAtomsERKSt6vectorINS_10AtomNumberESaIS2_EEb13881
_ZNK4PLMD15ActionAtomistic11getTotAtomsEv14144
_ZN4PLMD15ActionAtomistic16registerKeywordsERNS_8KeywordsE17946
_ZN4PLMD15ActionAtomisticC2ERKNS_13ActionOptionsE18047
_ZN4PLMD15ActionAtomisticD2Ev18047
_ZN4PLMD15ActionAtomistic17interpretAtomListERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EERS1_INS_10AtomNumberESaISB_EE42549
_ZN4PLMD15ActionAtomistic13parseAtomListERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiRSt6vectorINS_10AtomNumberESaISA_EE46016
_ZN4PLMD15ActionAtomistic15actionHasForcesEv103912
_ZN4PLMD15ActionAtomistic15setForcesOnCellERKSt6vectorIdSaIdEERj142143
_ZN4PLMD15ActionAtomistic9makeWholeEv146906
_ZN4PLMD15ActionAtomistic15setForcesOnCellEPKdmRj165042
_ZN4PLMD15ActionAtomistic16setForcesOnAtomsERKSt6vectorIdSaIdEERj245883
_ZN4PLMD15ActionAtomistic17updateUniqueLocalERKbRKSt6vectorIiSaIiEE253722
_ZNK4PLMD15ActionAtomistic8pbcApplyERSt6vectorINS_13VectorGenericILj3EEESaIS3_EEj405876
_ZN4PLMD15ActionAtomistic13retrieveAtomsERKb540521
_ZNK4PLMD15ActionAtomistic15getValueIndicesERKNS_10AtomNumberE1691776
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionAtomistic.cpp.func.html b/coverage/core/ActionAtomistic.cpp.func.html new file mode 100644 index 000000000000..a2f00db9795a --- /dev/null +++ b/coverage/core/ActionAtomistic.cpp.func.html @@ -0,0 +1,177 @@ + + + + + + + + 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:26728394.3 %
Date:2024-04-19 12:12:35Functions:212680.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15ActionAtomistic12requestAtomsERKSt6vectorINS_10AtomNumberESaIS2_EEb13881
_ZN4PLMD15ActionAtomistic13parseAtomListERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorINS_10AtomNumberESaISA_EE13738
_ZN4PLMD15ActionAtomistic13parseAtomListERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiRSt6vectorINS_10AtomNumberESaISA_EE46016
_ZN4PLMD15ActionAtomistic13retrieveAtomsERKb540521
_ZN4PLMD15ActionAtomistic15actionHasForcesEv103912
_ZN4PLMD15ActionAtomistic15setForcesOnCellEPKdmRj165042
_ZN4PLMD15ActionAtomistic15setForcesOnCellERKSt6vectorIdSaIdEERj142143
_ZN4PLMD15ActionAtomistic16readAtomsFromPDBERKNS_3PDBE0
_ZN4PLMD15ActionAtomistic16registerKeywordsERNS_8KeywordsE17946
_ZN4PLMD15ActionAtomistic16setForcesOnAtomsERKSt6vectorIdSaIdEERj245883
_ZN4PLMD15ActionAtomistic17interpretAtomListERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EERS1_INS_10AtomNumberESaISB_EE42549
_ZN4PLMD15ActionAtomistic17updateUniqueLocalERKbRKSt6vectorIiSaIiEE253722
_ZN4PLMD15ActionAtomistic29calculateNumericalDerivativesEPNS_15ActionWithValueE156
_ZN4PLMD15ActionAtomistic35calculateAtomicNumericalDerivativesEPNS_15ActionWithValueERKj240
_ZN4PLMD15ActionAtomistic9changeBoxERKNS_13TensorGenericILj3ELj3EEE0
_ZN4PLMD15ActionAtomistic9makeWholeEv146906
_ZN4PLMD15ActionAtomisticC1ERKNS_13ActionOptionsE0
_ZN4PLMD15ActionAtomisticC2ERKNS_13ActionOptionsE18047
_ZN4PLMD15ActionAtomisticD0Ev0
_ZN4PLMD15ActionAtomisticD1Ev0
_ZN4PLMD15ActionAtomisticD2Ev18047
_ZNK4PLMD15ActionAtomistic11getGradientERKjRNS_13VectorGenericILj3EEERSt3mapINS_10AtomNumberES4_St4lessIS7_ESaISt4pairIKS7_S4_EEE8208
_ZNK4PLMD15ActionAtomistic11getTotAtomsEv14144
_ZNK4PLMD15ActionAtomistic15getValueIndicesERKNS_10AtomNumberE1691776
_ZNK4PLMD15ActionAtomistic8pbcApplyERSt6vectorINS_13VectorGenericILj3EEESaIS3_EEj405876
_ZNK4PLMD15ActionAtomistic9getVirialEv6
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionAtomistic.cpp.gcov.html b/coverage/core/ActionAtomistic.cpp.gcov.html new file mode 100644 index 000000000000..0cbc8d706bdf --- /dev/null +++ b/coverage/core/ActionAtomistic.cpp.gcov.html @@ -0,0 +1,536 @@ + + + + + + + + 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:26728394.3 %
Date:2024-04-19 12:12:35Functions:212680.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 "ActionAtomistic.h"
+      23             : #include "PlumedMain.h"
+      24             : #include "ActionSet.h"
+      25             : #include "GenericMolInfo.h"
+      26             : #include "PbcAction.h"
+      27             : #include <vector>
+      28             : #include <string>
+      29             : #include "ActionWithValue.h"
+      30             : #include "Group.h"
+      31             : #include "ActionWithVirtualAtom.h"
+      32             : #include "tools/Exception.h"
+      33             : #include "tools/Pbc.h"
+      34             : #include "tools/PDB.h"
+      35             : 
+      36             : namespace PLMD {
+      37             : 
+      38       18047 : ActionAtomistic::~ActionAtomistic() {
+      39             : // empty destructor to delete unique_ptr
+      40       18047 : }
+      41             : 
+      42       18047 : ActionAtomistic::ActionAtomistic(const ActionOptions&ao):
+      43             :   Action(ao),
+      44       18047 :   unique_local_needs_update(true),
+      45       18047 :   boxValue(NULL),
+      46       18047 :   lockRequestAtoms(false),
+      47       18047 :   donotretrieve(false),
+      48       18047 :   donotforce(false),
+      49       18047 :   chargesWereSet(false)
+      50             : {
+      51       18047 :   ActionWithValue* bv = plumed.getActionSet().selectWithLabel<ActionWithValue*>("Box");
+      52       18047 :   if( bv ) boxValue=bv->copyOutput(0);
+      53             :   // We now get all the information about atoms that are lying about
+      54       18047 :   std::vector<ActionWithValue*> vatoms = plumed.getActionSet().select<ActionWithValue*>();
+      55     7536043 :   for(const auto & vv : vatoms ) {
+      56     7517996 :     plumed_assert(vv); // needed for following calls, see #1046
+      57     7517996 :     ActionToPutData* ap = vv->castToActionToPutData();
+      58     7517996 :     if( ap ) {
+      59      250132 :       if( ap->getRole()=="x" ) xpos.push_back( ap->copyOutput(0) );
+      60      250132 :       if( ap->getRole()=="y" ) ypos.push_back( ap->copyOutput(0) );
+      61      250132 :       if( ap->getRole()=="z" ) zpos.push_back( ap->copyOutput(0) );
+      62      250132 :       if( ap->getRole()=="m" ) masv.push_back( ap->copyOutput(0) );
+      63      250132 :       if( ap->getRole()=="q" ) chargev.push_back( ap->copyOutput(0) );
+      64             :     }
+      65     7517996 :     ActionWithVirtualAtom* av = vv->castToActionWithVirtualAtom();
+      66     7517996 :     if( av || vv->getName()=="ARGS2VATOM" ) {
+      67     6711774 :       xpos.push_back( vv->copyOutput( vv->getLabel() + ".x") );
+      68     6711774 :       ypos.push_back( vv->copyOutput( vv->getLabel() + ".y") );
+      69     6711774 :       zpos.push_back( vv->copyOutput( vv->getLabel() + ".z") );
+      70     6711774 :       masv.push_back( vv->copyOutput( vv->getLabel() + ".mass") );
+      71     6711774 :       chargev.push_back( vv->copyOutput( vv->getLabel() + ".charge") );
+      72             :     }
+      73             :   }
+      74       18047 :   if( xpos.size()!=ypos.size() || xpos.size()!=zpos.size() || xpos.size()!=masv.size() || xpos.size()!=chargev.size() )
+      75           0 :     error("mismatch between value arrays");
+      76       18047 : }
+      77             : 
+      78       17946 : void ActionAtomistic::registerKeywords( Keywords& keys ) {
+      79             :   (void) keys; // avoid warning
+      80       17946 : }
+      81             : 
+      82             : 
+      83       13881 : void ActionAtomistic::requestAtoms(const std::vector<AtomNumber> & a, const bool clearDep) {
+      84       13881 :   plumed_massert(!lockRequestAtoms,"requested atom list can only be changed in the prepare() method");
+      85       13881 :   int nat=a.size();
+      86       13881 :   indexes=a;
+      87       13881 :   positions.resize(nat);
+      88       13881 :   forces.resize(nat);
+      89       13881 :   masses.resize(nat);
+      90       13881 :   charges.resize(nat);
+      91       13881 :   atom_value_ind.resize( a.size() );
+      92       13881 :   int n=getTotAtoms();
+      93       13881 :   if(clearDep) clearDependencies();
+      94       14408 :   unique.clear(); std::vector<bool> requirements( xpos.size(), false );
+      95       13881 :   if( boxValue ) addDependency( boxValue->getPntrToAction() );
+      96     1273094 :   for(unsigned i=0; i<indexes.size(); i++) {
+      97     1259216 :     if(indexes[i].index()>=n) { std::string num; Tools::convert( indexes[i].serial(),num ); error("atom " + num + " out of range"); }
+      98     1259213 :     atom_value_ind[i] = getValueIndices( indexes[i] ); requirements[atom_value_ind[i].first] = true;
+      99     1259213 :     if( atom_value_ind[i].first==0 ) unique.push_back(indexes[i]);
+     100       18016 :     else if( atom_value_ind[i].second>0 ) error("action atomistic is not set up to deal with multiple vectors in position input");
+     101             :   }
+     102             : 
+     103       13880 :   atom_value_ind_grouped.clear();
+     104             : 
+     105       13880 :   if(atom_value_ind.size()>0) {
+     106       13842 :     auto nn = atom_value_ind[0].first;
+     107       13842 :     auto kk = atom_value_ind[0].second;
+     108       13842 :     atom_value_ind_grouped.push_back(std::pair<std::size_t,std::vector<std::size_t>>(nn, {}));
+     109       13842 :     atom_value_ind_grouped.back().second.push_back(kk);
+     110             :     auto prev_nn=nn;
+     111     1259206 :     for(unsigned i=1; i<atom_value_ind.size(); i++) {
+     112     1245364 :       auto nn = atom_value_ind[i].first;
+     113     1245364 :       auto kk = atom_value_ind[i].second;
+     114     1265040 :       if(nn!=prev_nn) atom_value_ind_grouped.push_back(std::pair<std::size_t,std::vector<std::size_t>>(nn, {}));
+     115     1245364 :       atom_value_ind_grouped.back().second.push_back(kk);
+     116             :       prev_nn=nn;
+     117             :     }
+     118             :   }
+     119             : 
+     120             :   // Add the dependencies to the actions that we require
+     121       13880 :   Tools::removeDuplicates(unique); value_depends.resize(0);
+     122     6660940 :   for(unsigned i=0; i<requirements.size(); ++i ) {
+     123     6647060 :     if( !requirements[i] ) continue;
+     124       30583 :     value_depends.push_back( i );
+     125       30582 :     addDependency( xpos[i]->getPntrToAction() );
+     126       30582 :     addDependency( ypos[i]->getPntrToAction() );
+     127       30582 :     addDependency( zpos[i]->getPntrToAction() );
+     128       30582 :     addDependency( masv[i]->getPntrToAction() );
+     129       30582 :     addDependency( chargev[i]->getPntrToAction() );
+     130             :   }
+     131       13880 :   unique_local_needs_update=true;
+     132       13880 : }
+     133             : 
+     134      405876 : void ActionAtomistic::pbcApply(std::vector<Vector>& dlist, unsigned max_index)const {
+     135      405876 :   pbc.apply(dlist, max_index);
+     136      405876 : }
+     137             : 
+     138         156 : void ActionAtomistic::calculateNumericalDerivatives( ActionWithValue* a ) {
+     139         156 :   calculateAtomicNumericalDerivatives( a, 0 );
+     140         156 : }
+     141             : 
+     142           0 : void ActionAtomistic::changeBox( const Tensor& newbox ) {
+     143           0 :   pbc.setBox( newbox );
+     144           0 : }
+     145             : 
+     146         240 : void ActionAtomistic::calculateAtomicNumericalDerivatives( ActionWithValue* a, const unsigned& startnum ) {
+     147         240 :   if(!a) {
+     148         240 :     a=castToActionWithValue();
+     149         240 :     plumed_massert(a,"only Actions with a value can be differentiated");
+     150             :   }
+     151             : 
+     152         240 :   const size_t nval=a->getNumberOfComponents();
+     153         240 :   const size_t natoms=getNumberOfAtoms();
+     154         240 :   std::vector<Vector> value(nval*natoms);
+     155         240 :   std::vector<Tensor> valuebox(nval);
+     156         240 :   std::vector<Vector> savedPositions(natoms);
+     157             :   const double delta=std::sqrt(epsilon);
+     158             : 
+     159       82068 :   for(int i=0; i<natoms; i++) for(int k=0; k<3; k++) {
+     160       61371 :       savedPositions[i][k]=positions[i][k];
+     161       61371 :       positions[i][k]=positions[i][k]+delta;
+     162       61371 :       a->calculate();
+     163       61371 :       positions[i][k]=savedPositions[i][k];
+     164      188208 :       for(int j=0; j<nval; j++) {
+     165      126837 :         value[j*natoms+i][k]=a->getOutputQuantity(j);
+     166             :       }
+     167             :     }
+     168         240 :   Tensor box(pbc.getBox());
+     169        3120 :   for(int i=0; i<3; i++) for(int k=0; k<3; k++) {
+     170        2160 :       double arg0=box(i,k);
+     171      186273 :       for(int j=0; j<natoms; j++) positions[j]=pbc.realToScaled(positions[j]);
+     172        2160 :       box(i,k)=box(i,k)+delta;
+     173        2160 :       pbc.setBox(box);
+     174      186273 :       for(int j=0; j<natoms; j++) positions[j]=pbc.scaledToReal(positions[j]);
+     175        2160 :       a->calculate();
+     176        2160 :       box(i,k)=arg0;
+     177        2160 :       pbc.setBox(box);
+     178      186273 :       for(int j=0; j<natoms; j++) positions[j]=savedPositions[j];
+     179       14886 :       for(int j=0; j<nval; j++) valuebox[j](i,k)=a->getOutputQuantity(j);
+     180             :     }
+     181             : 
+     182         240 :   a->calculate();
+     183         240 :   a->clearDerivatives();
+     184        1654 :   for(int j=0; j<nval; j++) {
+     185        1414 :     Value* v=a->copyOutput(j);
+     186        1414 :     double ref=v->get();
+     187        1414 :     if(v->hasDerivatives()) {
+     188       89779 :       for(int i=0; i<natoms; i++) for(int k=0; k<3; k++) {
+     189       66975 :           double d=(value[j*natoms+i][k]-ref)/delta;
+     190       66975 :           v->addDerivative(startnum+3*i+k,d);
+     191             :         }
+     192         479 :       Tensor virial;
+     193        6227 :       for(int i=0; i<3; i++) for(int k=0; k<3; k++)virial(i,k)= (valuebox[j](i,k)-ref)/delta;
+     194             : // BE CAREFUL WITH NON ORTHOROMBIC CELL
+     195         479 :       virial=-matmul(box.transpose(),virial);
+     196        6227 :       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));
+     197             :     }
+     198             :   }
+     199         240 : }
+     200             : 
+     201      103912 : bool ActionAtomistic::actionHasForces() {
+     202      103912 :   ActionWithValue* av = castToActionWithValue();
+     203      103912 :   if( av ) return !av->doNotCalculateDerivatives();
+     204           0 :   if( indexes.size()>0 ) plumed_merror("you have to overwrite the function actionHasForce to tell plumed if you method applies forces");
+     205             :   return true;
+     206             : }
+     207             : 
+     208       13738 : void ActionAtomistic::parseAtomList(const std::string&key, std::vector<AtomNumber> &t) {
+     209       13738 :   parseAtomList(key,-1,t);
+     210       13737 : }
+     211             : 
+     212       46016 : void ActionAtomistic::parseAtomList(const std::string&key,const int num, std::vector<AtomNumber> &t) {
+     213       46016 :   plumed_massert( keywords.style(key,"atoms") || keywords.style(key,"hidden"), "keyword " + key + " should be registered as atoms");
+     214             :   std::vector<std::string> strings;
+     215       46016 :   if( num<0 ) {
+     216       17164 :     parseVector(key,strings);
+     217       17163 :     if(strings.empty()) return;
+     218             :   } else {
+     219       28852 :     if ( !parseNumberedVector(key,num,strings) ) return;
+     220             :   }
+     221       41973 :   t.resize(0); interpretAtomList( strings, t );
+     222       46016 : }
+     223             : 
+     224       42549 : void ActionAtomistic::interpretAtomList(std::vector<std::string>& strings, std::vector<AtomNumber> &t) {
+     225       42549 :   Tools::interpretRanges(strings);
+     226     1085751 :   for(unsigned i=0; i<strings.size(); ++i) {
+     227             :     AtomNumber atom;
+     228     1043202 :     bool ok=Tools::convertNoexcept(strings[i],atom); // this is converting strings to AtomNumbers
+     229     1043202 :     if(ok) t.push_back(atom);
+     230             : // here we check if this is a special symbol for MOLINFO
+     231     1043202 :     if( !ok && strings[i].compare(0,1,"@")==0 ) {
+     232         677 :       std::string symbol=strings[i].substr(1);
+     233         677 :       if(symbol=="allatoms") {
+     234          24 :         auto n=0; for(unsigned i=0; i<xpos.size(); ++i) n += xpos[i]->getNumberOfValues();
+     235         365 :         t.reserve(n); for(unsigned i=0; i<n; i++) t.push_back(AtomNumber::index(i));
+     236             :         ok=true;
+     237         667 :       } else if(symbol=="mdatoms") {
+     238          12 :         const auto n=xpos[0]->getNumberOfValues();
+     239          12 :         t.reserve(t.size()+n);
+     240         948 :         for(unsigned i=0; i<n; i++) t.push_back(AtomNumber::index(i));
+     241             :         ok=true;
+     242        1310 :       } else if(Tools::startWith(symbol,"ndx:")) {
+     243          40 :         auto words=Tools::getWords(symbol.substr(4));
+     244             :         std::string ndxfile,ndxgroup;
+     245          20 :         if(words.size()==1) {
+     246             :           ndxfile=words[0];
+     247          18 :         } else if(words.size()==2) {
+     248             :           ndxfile=words[0];
+     249             :           ndxgroup=words[1];
+     250           0 :         } else plumed_error()<<"Cannot intepret selection "<<symbol;
+     251             : 
+     252          38 :         if(ndxgroup.size()>0) log<<"  importing group '"+ndxgroup+"'";
+     253           2 :         else                  log<<"  importing first group";
+     254          20 :         log<<" from index file "<<ndxfile<<"\n";
+     255             : 
+     256          20 :         IFile ifile;
+     257          20 :         ifile.open(ndxfile);
+     258             :         std::string line;
+     259             :         std::string groupname;
+     260             :         bool firstgroup=true;
+     261             :         bool groupfound=false;
+     262        3849 :         while(ifile.getline(line)) {
+     263        3829 :           std::vector<std::string> words=Tools::getWords(line);
+     264        7765 :           if(words.size()>=3 && words[0]=="[" && words[2]=="]") {
+     265         168 :             if(groupname.length()>0) firstgroup=false;
+     266             :             groupname=words[1];
+     267         168 :             if(groupname==ndxgroup || ndxgroup.length()==0) groupfound=true;
+     268        3661 :           } else if(groupname==ndxgroup || (firstgroup && ndxgroup.length()==0)) {
+     269        6186 :             for(unsigned i=0; i<words.size(); i++) {
+     270        5782 :               AtomNumber at; Tools::convert(words[i],at);
+     271        5782 :               t.push_back(at);
+     272             :             }
+     273             :           }
+     274        3829 :         }
+     275          20 :         if(!groupfound) plumed_error()<<"group has not been found in index file";
+     276             :         ok=true;
+     277          40 :       } else {
+     278         635 :         auto* moldat=plumed.getActionSet().selectLatest<GenericMolInfo*>(this);
+     279         635 :         if( moldat ) {
+     280         635 :           std::vector<AtomNumber> atom_list; moldat->interpretSymbol( symbol, atom_list );
+     281         635 :           if( atom_list.size()>0 ) { ok=true; t.insert(t.end(),atom_list.begin(),atom_list.end()); }
+     282           0 :           else { error(strings[i] + " is not a label plumed knows"); }
+     283             :         } else {
+     284           0 :           error("atoms specified using @ symbol but no MOLINFO was available");
+     285             :         }
+     286             :       }
+     287             :     }
+     288             : // here we check if the atom name is the name of a group
+     289     1042525 :     if(!ok) {
+     290       24209 :       Group* mygrp=plumed.getActionSet().selectWithLabel<Group*>(strings[i]);
+     291       24209 :       if(mygrp) {
+     292         439 :         std::vector<std::string> grp_str( mygrp->getGroupAtoms() );
+     293         439 :         interpretAtomList( grp_str, t ); ok=true;
+     294         439 :       } else {
+     295       23770 :         Group* mygrp2=plumed.getActionSet().selectWithLabel<Group*>(strings[i]+"_grp");
+     296       23770 :         if(mygrp2) {
+     297         111 :           std::vector<std::string> grp_str( mygrp2->getGroupAtoms() );
+     298         111 :           interpretAtomList( grp_str, t ); ok=true;
+     299         111 :         }
+     300             :       }
+     301             :     }
+     302             : // here we check if the atom name is the name of an added virtual atom
+     303     1042652 :     if(!ok) {
+     304             :       unsigned ind = 0;
+     305    13269117 :       for(unsigned j=0; j<xpos.size(); ++j) {
+     306    13269117 :         if( xpos[j]->getPntrToAction()->getLabel()==strings[i] ) {
+     307       23659 :           t.push_back( AtomNumber::index(ind) ); ok=true; break;
+     308             :         }
+     309    13245458 :         ind = ind + xpos[j]->getNumberOfValues();
+     310             :       }
+     311             :     }
+     312     1019543 :     if(!ok) error("it was not possible to interpret atom name " + strings[i]);
+     313             :     // plumed_massert(ok,"it was not possible to interpret atom name " + strings[i]);
+     314             :   }
+     315       42549 : }
+     316             : 
+     317     1691776 : std::pair<std::size_t, std::size_t> ActionAtomistic::getValueIndices( const AtomNumber& i ) const {
+     318     1691776 :   std::size_t valno=0, k = i.index();
+     319    15416966 :   for(unsigned j=0; j<xpos.size(); ++j) {
+     320    15416966 :     if( k<xpos[j]->getNumberOfValues() ) { valno=j; break; }
+     321    13725190 :     k = k - xpos[j]->getNumberOfValues();
+     322             :   }
+     323     1691776 :   return std::pair<std::size_t, std::size_t>( valno, k );
+     324             : }
+     325             : 
+     326      540521 : void ActionAtomistic::retrieveAtoms( const bool& force ) {
+     327      540521 :   if( boxValue ) {
+     328      524006 :     auto* ptr=boxValue->getPntrToAction();
+     329      524006 :     plumed_assert(ptr); // needed for following calls, see #1046
+     330      524006 :     PbcAction* pbca = ptr->castToPbcAction();
+     331      524006 :     plumed_assert( pbca ); pbc=pbca->pbc;
+     332             :   }
+     333      540521 :   if( donotretrieve || indexes.size()==0 ) return;
+     334      223238 :   auto * ptr=chargev[0]->getPntrToAction();
+     335      223238 :   plumed_assert(ptr); // needed for following calls, see #1046
+     336      223238 :   ActionToPutData* cv = ptr->castToActionToPutData();
+     337      223238 :   if(cv) chargesWereSet=cv->hasBeenSet();
+     338             :   unsigned j = 0;
+     339             : 
+     340             : // for(const auto & a : atom_value_ind) {
+     341             : //   std::size_t nn = a.first, kk = a.second;
+     342             : //   positions[j][0] = xpos[nn]->data[kk];
+     343             : //   positions[j][1] = ypos[nn]->data[kk];
+     344             : //   positions[j][2] = zpos[nn]->data[kk];
+     345             : //   charges[j] = chargev[nn]->data[kk];
+     346             : //   masses[j] = masv[nn]->data[kk];
+     347             : //   j++;
+     348             : // }
+     349             : 
+     350      837110 :   for(const auto & a : atom_value_ind_grouped) {
+     351      613872 :     const auto nn=a.first;
+     352      613872 :     auto & xp=xpos[nn]->data;
+     353      613872 :     auto & yp=ypos[nn]->data;
+     354      613872 :     auto & zp=zpos[nn]->data;
+     355      613872 :     auto & ch=chargev[nn]->data;
+     356      613872 :     auto & ma=masv[nn]->data;
+     357     6519614 :     for(const auto & kk : a.second) {
+     358     5905742 :       positions[j][0] = xp[kk];
+     359     5905742 :       positions[j][1] = yp[kk];
+     360     5905742 :       positions[j][2] = zp[kk];
+     361     5905742 :       charges[j] = ch[kk];
+     362     5905742 :       masses[j] = ma[kk];
+     363     5905742 :       j++;
+     364             :     }
+     365             :   }
+     366             : 
+     367             : }
+     368             : 
+     369      245883 : void ActionAtomistic::setForcesOnAtoms(const std::vector<double>& forcesToApply, unsigned& ind) {
+     370      245883 :   if( donotforce || (indexes.size()==0 && getName()!="FIXEDATOM") ) return;
+     371      483654 :   for(unsigned i=0; i<value_depends.size(); ++i) {
+     372      341599 :     xpos[value_depends[i]]->hasForce = true;
+     373      341599 :     ypos[value_depends[i]]->hasForce = true;
+     374      341599 :     zpos[value_depends[i]]->hasForce = true;
+     375             :   }
+     376             : 
+     377             : // for(const auto & a : atom_value_ind) {
+     378             : //   plumed_dbg_massert( ind<forcesToApply.size(), "problem setting forces in " + getLabel() );
+     379             : //   std::size_t nn = a.first, kk = a.second;
+     380             : //   xpos[nn]->inputForce[kk] += forcesToApply[ind]; ind++;
+     381             : //   ypos[nn]->inputForce[kk] += forcesToApply[ind]; ind++;
+     382             : //   zpos[nn]->inputForce[kk] += forcesToApply[ind]; ind++;
+     383             : // }
+     384             : 
+     385      794042 :   for(const auto & a : atom_value_ind_grouped) {
+     386      651987 :     const auto nn=a.first;
+     387             :     plumed_dbg_assert(ind<forcesToApply.size()) << "problem setting forces in " << getLabel();
+     388      651987 :     auto & xp=xpos[nn]->inputForce;
+     389      651987 :     auto & yp=ypos[nn]->inputForce;
+     390      651987 :     auto & zp=zpos[nn]->inputForce;
+     391     3944237 :     for(const auto & kk : a.second) {
+     392     3292250 :       xp[kk] += forcesToApply[ind]; ind++;
+     393     3292250 :       yp[kk] += forcesToApply[ind]; ind++;
+     394     3292250 :       zp[kk] += forcesToApply[ind]; ind++;
+     395             :     }
+     396             :   }
+     397             : 
+     398      142055 :   setForcesOnCell( forcesToApply, ind );
+     399             : }
+     400             : 
+     401      142143 : void ActionAtomistic::setForcesOnCell(const std::vector<double>& forcesToApply, unsigned& ind) {
+     402      142143 :   setForcesOnCell(forcesToApply.data(),forcesToApply.size(),ind);
+     403      142143 : }
+     404             : 
+     405      165042 : void ActionAtomistic::setForcesOnCell(const double* forcesToApply, std::size_t size, unsigned& ind) {
+     406     1650420 :   for(unsigned i=0; i<9; ++i) {
+     407             :     plumed_dbg_massert( ind<size, "problem setting forces in " + getLabel() );
+     408     1485378 :     boxValue->addForce( i, forcesToApply[ind] ); ind++;
+     409             :   }
+     410      165042 : }
+     411             : 
+     412           6 : Tensor ActionAtomistic::getVirial() const {
+     413          78 :   Tensor vir; for(unsigned i=0; i<3; ++i) for(unsigned j=0; j<3; ++j) vir[i][j] = boxValue->getForce(3*i+j);
+     414           6 :   return vir;
+     415             : }
+     416             : 
+     417           0 : void ActionAtomistic::readAtomsFromPDB(const PDB& pdb) {
+     418             : 
+     419           0 :   for(unsigned j=0; j<indexes.size(); j++) {
+     420           0 :     if( indexes[j].index()>pdb.size() ) error("there are not enough atoms in the input pdb file");
+     421           0 :     if( pdb.getAtomNumbers()[j].index()!=indexes[j].index() ) error("there are atoms missing in the pdb file");
+     422           0 :     positions[j]=pdb.getPositions()[indexes[j].index()];
+     423             :   }
+     424           0 :   for(unsigned j=0; j<indexes.size(); j++) charges[j]=pdb.getBeta()[indexes[j].index()];
+     425           0 :   for(unsigned j=0; j<indexes.size(); j++) masses[j]=pdb.getOccupancy()[indexes[j].index()];
+     426           0 : }
+     427             : 
+     428       14144 : unsigned ActionAtomistic::getTotAtoms()const {
+     429             :   unsigned natoms = 0;
+     430     6661540 :   for(unsigned i=0; i<xpos.size(); ++i ) natoms += xpos[i]->getNumberOfValues();
+     431       14144 :   return natoms;
+     432             : }
+     433             : 
+     434      146906 : void ActionAtomistic::makeWhole() {
+     435     1361420 :   for(unsigned j=0; j<positions.size()-1; ++j) {
+     436             :     const Vector & first (positions[j]);
+     437     1214514 :     Vector & second (positions[j+1]);
+     438     1214514 :     second=first+pbcDistance(first,second);
+     439             :   }
+     440      146906 : }
+     441             : 
+     442        8208 : void ActionAtomistic::getGradient( const unsigned& ind, Vector& deriv, std::map<AtomNumber,Vector>& gradients ) const {
+     443        8208 :   std::size_t nn = atom_value_ind[ind].first;
+     444        8208 :   if( nn==0 ) { gradients[indexes[ind]] += deriv; return; }
+     445          39 :   xpos[nn]->passGradients( deriv[0], gradients );
+     446          39 :   ypos[nn]->passGradients( deriv[1], gradients );
+     447          39 :   zpos[nn]->passGradients( deriv[2], gradients );
+     448             : }
+     449             : 
+     450      253722 : void ActionAtomistic::updateUniqueLocal( const bool& useunique, const std::vector<int>& g2l ) {
+     451      253722 :   if( useunique ) { unique_local=unique; return; }
+     452             :   // Update unique local if it needs an update
+     453        9064 :   unique_local_needs_update=false; unique_local.clear();
+     454       71922 :   for(auto pp=unique.begin(); pp!=unique.end(); ++pp) {
+     455       62858 :     if(g2l[pp->index()]>=0) unique_local.push_back(*pp); // already sorted
+     456             :   }
+     457             : }
+     458             : 
+     459             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionAtomistic.h.func-sort-c.html b/coverage/core/ActionAtomistic.h.func-sort-c.html new file mode 100644 index 000000000000..351db308f397 --- /dev/null +++ b/coverage/core/ActionAtomistic.h.func-sort-c.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionAtomistic.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionAtomistic.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4646100.0 %
Date:2024-04-19 12:12:35Functions:99100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD15ActionAtomistic18getAbsoluteIndexesEv216
_ZN4PLMD15ActionAtomistic8addForceERKSt4pairImmERKNS_13VectorGenericILj3EEE9946
_ZNK4PLMD15ActionAtomistic8getForceERKSt4pairImmE15886
_ZN4PLMD15ActionAtomistic12lockRequestsEv193978
_ZN4PLMD15ActionAtomistic14unlockRequestsEv193978
_ZN4PLMD15ActionAtomistic17setGlobalPositionERKSt4pairImmERKNS_13VectorGenericILj3EEE412912
_ZNK4PLMD15ActionAtomistic17getGlobalPositionERKSt4pairImmE424571
_ZN4PLMD15ActionAtomistic21castToActionAtomisticEv502748
_ZNK4PLMD15ActionAtomistic9getChargeEi1037148
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionAtomistic.h.func.html b/coverage/core/ActionAtomistic.h.func.html new file mode 100644 index 000000000000..05a9c22a1745 --- /dev/null +++ b/coverage/core/ActionAtomistic.h.func.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionAtomistic.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionAtomistic.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4646100.0 %
Date:2024-04-19 12:12:35Functions:99100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15ActionAtomistic12lockRequestsEv193978
_ZN4PLMD15ActionAtomistic14unlockRequestsEv193978
_ZN4PLMD15ActionAtomistic17setGlobalPositionERKSt4pairImmERKNS_13VectorGenericILj3EEE412912
_ZN4PLMD15ActionAtomistic21castToActionAtomisticEv502748
_ZN4PLMD15ActionAtomistic8addForceERKSt4pairImmERKNS_13VectorGenericILj3EEE9946
_ZNK4PLMD15ActionAtomistic17getGlobalPositionERKSt4pairImmE424571
_ZNK4PLMD15ActionAtomistic18getAbsoluteIndexesEv216
_ZNK4PLMD15ActionAtomistic8getForceERKSt4pairImmE15886
_ZNK4PLMD15ActionAtomistic9getChargeEi1037148
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionAtomistic.h.gcov.html b/coverage/core/ActionAtomistic.h.gcov.html new file mode 100644 index 000000000000..1cdb22b0395a --- /dev/null +++ b/coverage/core/ActionAtomistic.h.gcov.html @@ -0,0 +1,380 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionAtomistic.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionAtomistic.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4646100.0 %
Date:2024-04-19 12:12:35Functions:99100.0 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18ActionForInterfaceC1ERKNS_13ActionOptionsE0
_ZN4PLMD18ActionForInterface16registerKeywordsERNS_8KeywordsE7635
_ZN4PLMD18ActionForInterfaceC2ERKNS_13ActionOptionsE8762
_ZNK4PLMD18ActionForInterface7getRoleB5cxx11Ev625523
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionForInterface.cpp.func.html b/coverage/core/ActionForInterface.cpp.func.html new file mode 100644 index 000000000000..61fa74d0dd2a --- /dev/null +++ b/coverage/core/ActionForInterface.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionForInterface.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionForInterface.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1313100.0 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18ActionForInterface16registerKeywordsERNS_8KeywordsE7635
_ZN4PLMD18ActionForInterfaceC1ERKNS_13ActionOptionsE0
_ZN4PLMD18ActionForInterfaceC2ERKNS_13ActionOptionsE8762
_ZNK4PLMD18ActionForInterface7getRoleB5cxx11Ev625523
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionForInterface.cpp.gcov.html b/coverage/core/ActionForInterface.cpp.gcov.html new file mode 100644 index 000000000000..ceec84678ab8 --- /dev/null +++ b/coverage/core/ActionForInterface.cpp.gcov.html @@ -0,0 +1,126 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionForInterface.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionForInterface.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1313100.0 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD18ActionForInterface26getNumberOfForcesToRescaleEv0
_ZN4PLMD18ActionForInterface24castToActionForInterfaceEv835
_ZN4PLMD18ActionForInterface5resetEv93523
_ZN4PLMD18ActionForInterface16clearDerivativesERKb518217
_ZN4PLMD18ActionForInterface20setGradientsIfNeededEv518217
_ZN4PLMD18ActionForInterface9calculateEv518217
_ZN4PLMD18ActionForInterface22getNumberOfDerivativesEv807277
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionForInterface.h.func.html b/coverage/core/ActionForInterface.h.func.html new file mode 100644 index 000000000000..64e55a728148 --- /dev/null +++ b/coverage/core/ActionForInterface.h.func.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionForInterface.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionForInterface.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:7887.5 %
Date:2024-04-19 12:12:35Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18ActionForInterface16clearDerivativesERKb518217
_ZN4PLMD18ActionForInterface20setGradientsIfNeededEv518217
_ZN4PLMD18ActionForInterface22getNumberOfDerivativesEv807277
_ZN4PLMD18ActionForInterface24castToActionForInterfaceEv835
_ZN4PLMD18ActionForInterface5resetEv93523
_ZN4PLMD18ActionForInterface9calculateEv518217
_ZNK4PLMD18ActionForInterface26getNumberOfForcesToRescaleEv0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionForInterface.h.gcov.html b/coverage/core/ActionForInterface.h.gcov.html new file mode 100644 index 000000000000..13317000d18e --- /dev/null +++ b/coverage/core/ActionForInterface.h.gcov.html @@ -0,0 +1,167 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionForInterface.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionForInterface.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:7887.5 %
Date:2024-04-19 12:12:35Functions:6785.7 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11ActionPilotC1ERKNS_13ActionOptionsE0
_ZN4PLMD11ActionPilot9setStrideERKi8
_ZN4PLMD11ActionPilotC2ERKNS_13ActionOptionsE3170
_ZN4PLMD11ActionPilot16registerKeywordsERNS_8KeywordsE3179
_ZNK4PLMD11ActionPilot9getStrideEv120437
_ZNK4PLMD11ActionPilot6onStepEv1573702
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionPilot.cpp.func.html b/coverage/core/ActionPilot.cpp.func.html new file mode 100644 index 000000000000..93d1b29b25c1 --- /dev/null +++ b/coverage/core/ActionPilot.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionPilot.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionPilot.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:141593.3 %
Date:2024-04-19 12:12:35Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11ActionPilot16registerKeywordsERNS_8KeywordsE3179
_ZN4PLMD11ActionPilot9setStrideERKi8
_ZN4PLMD11ActionPilotC1ERKNS_13ActionOptionsE0
_ZN4PLMD11ActionPilotC2ERKNS_13ActionOptionsE3170
_ZNK4PLMD11ActionPilot6onStepEv1573702
_ZNK4PLMD11ActionPilot9getStrideEv120437
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionPilot.cpp.gcov.html b/coverage/core/ActionPilot.cpp.gcov.html new file mode 100644 index 000000000000..6b6c170141b5 --- /dev/null +++ b/coverage/core/ActionPilot.cpp.gcov.html @@ -0,0 +1,132 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionPilot.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionPilot.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:141593.3 %
Date:2024-04-19 12:12:35Functions: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        3179 : void ActionPilot::registerKeywords(Keywords& keys) {}
+      27             : 
+      28        3170 : ActionPilot::ActionPilot(const ActionOptions&ao):
+      29             :   Action(ao),
+      30        3170 :   stride(1)
+      31             : {
+      32        6340 :   if( keywords.exists("STRIDE") ) {
+      33        3170 :     parse("STRIDE",stride);
+      34        6340 :     if( !keywords.style("STRIDE","hidden") ) log.printf("  with stride %d\n",stride);
+      35             :   } else {
+      36           0 :     stride=0;
+      37             :   }
+      38        3170 : }
+      39             : 
+      40     1573702 : bool ActionPilot::onStep()const {
+      41     1573702 :   if( stride>0 ) return getStep()%stride==0;
+      42             :   return false;
+      43             : }
+      44             : 
+      45      120437 : int ActionPilot::getStride()const {
+      46      120437 :   return stride;
+      47             : }
+      48             : 
+      49           8 : void ActionPilot::setStride(const int& n) {
+      50           8 :   stride=n;
+      51           8 : }
+      52             : 
+      53             : }
+      54             : 
+      55             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionPilot.h.func-sort-c.html b/coverage/core/ActionPilot.h.func-sort-c.html new file mode 100644 index 000000000000..666da7178f85 --- /dev/null +++ b/coverage/core/ActionPilot.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionPilot.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionPilot.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-04-19 12:12:35Functions:00-
+
+ +
+ + + + + + +

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

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14ActionRegister13printTemplateERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEb0
_ZN4PLMD14ActionRegister6createERKNS_13ActionOptionsE0
_ZNK4PLMD14ActionRegister14getActionNamesB5cxx11Ev1
_ZN4PLMD14ActionRegister11printManualERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKbSA_435
_ZN4PLMD14ActionRegister11getKeywordsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERNS_8KeywordsE1467
_ZN4PLMD14ActionRegister6createERKSt6vectorIPvSaIS2_EERKNS_13ActionOptionsE49646
_ZN4PLMD14ActionRegister3addENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPFSt10unique_ptrINS_6ActionESt14default_deleteIS8_EERKNS_13ActionOptionsEEPFvRNS_8KeywordsEE2208205
_ZN4PLMD14actionRegisterEv4472585
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionRegister.cpp.func.html b/coverage/core/ActionRegister.cpp.func.html new file mode 100644 index 000000000000..1021cba48f1c --- /dev/null +++ b/coverage/core/ActionRegister.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + 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:273871.1 %
Date:2024-04-19 12:12:35Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14ActionRegister11getKeywordsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERNS_8KeywordsE1467
_ZN4PLMD14ActionRegister11printManualERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKbSA_435
_ZN4PLMD14ActionRegister13printTemplateERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEb0
_ZN4PLMD14ActionRegister3addENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPFSt10unique_ptrINS_6ActionESt14default_deleteIS8_EERKNS_13ActionOptionsEEPFvRNS_8KeywordsEE2208205
_ZN4PLMD14ActionRegister6createERKNS_13ActionOptionsE0
_ZN4PLMD14ActionRegister6createERKSt6vectorIPvSaIS2_EERKNS_13ActionOptionsE49646
_ZN4PLMD14actionRegisterEv4472585
_ZNK4PLMD14ActionRegister14getActionNamesB5cxx11Ev1
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionRegister.cpp.gcov.html b/coverage/core/ActionRegister.cpp.gcov.html new file mode 100644 index 000000000000..6b6f8ec14f40 --- /dev/null +++ b/coverage/core/ActionRegister.cpp.gcov.html @@ -0,0 +1,172 @@ + + + + + + + + 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:273871.1 %
Date:2024-04-19 12:12:35Functions:6875.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 "Action.h"
+      24             : #include <algorithm>
+      25             : 
+      26             : namespace PLMD {
+      27             : 
+      28     4472585 : ActionRegister& actionRegister() {
+      29     4477673 :   static ActionRegister ans;
+      30     4472585 :   return ans;
+      31             : }
+      32             : 
+      33           0 : std::unique_ptr<Action> ActionRegister::create(const ActionOptions&ao) {
+      34             :   std::vector<void*> images; // empty vector
+      35           0 :   return create(images,ao);
+      36             : }
+      37             : 
+      38       49646 : std::unique_ptr<Action> ActionRegister::create(const std::vector<void*> & images,const ActionOptions&ao) {
+      39       49646 :   if(ao.line.size()<1)return nullptr;
+      40             : 
+      41       49646 :   auto content=get(images,ao.line[0]);
+      42       49644 :   Keywords keys;
+      43       49644 :   content.keys(keys);
+      44       49644 :   ActionOptions nao( ao,keys );
+      45       49644 :   auto fullPath=getFullPath(images,ao.line[0]);
+      46             :   nao.setFullPath(fullPath);
+      47       49644 :   return content.create(nao);
+      48       49644 : }
+      49             : 
+      50         435 : bool ActionRegister::printManual(const std::string& action, const bool& vimout, const bool& spellout) {
+      51         435 :   if ( check(action) ) {
+      52         434 :     Keywords keys; getKeywords( action, keys );
+      53         434 :     if( vimout ) {
+      54         434 :       printf("%s",action.c_str()); keys.print_vim(); printf("\n");
+      55           0 :     } else if( spellout ) {
+      56           0 :       keys.print_spelling();
+      57             :     } else {
+      58           0 :       keys.print_html();
+      59             :     }
+      60             :     return true;
+      61         434 :   } else {
+      62             :     return false;
+      63             :   }
+      64             : }
+      65             : 
+      66           0 : bool ActionRegister::printTemplate(const std::string& action, bool include_optional) {
+      67           0 :   if( check(action) ) {
+      68           0 :     Keywords keys;
+      69           0 :     get(action).keys(keys);
+      70           0 :     keys.print_template(action, include_optional);
+      71             :     return true;
+      72           0 :   } else {
+      73             :     return false;
+      74             :   }
+      75             : }
+      76             : 
+      77           1 : std::vector<std::string> ActionRegister::getActionNames() const {
+      78           1 :   return getKeys();
+      79             : }
+      80             : 
+      81     2208205 : ActionRegister::ID ActionRegister::add(std::string key,creator_pointer cp,keywords_pointer kp) {
+      82             :   // this force each action to be registered as an uppercase string
+      83    11478575 :   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";
+      84     4416410 :   return RegisterBase::add(key,Pointers{cp,kp});
+      85             : }
+      86             : 
+      87        1467 : bool ActionRegister::getKeywords(const std::string& action, Keywords& keys) {
+      88        1467 :   if(check(action)) {
+      89        1467 :     get(action).keys(keys);
+      90        1467 :     return true;
+      91             :   }
+      92             :   return false;
+      93             : }
+      94             : 
+      95             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionRegister.h.func-sort-c.html b/coverage/core/ActionRegister.h.func-sort-c.html new file mode 100644 index 000000000000..2228823ee839 --- /dev/null +++ b/coverage/core/ActionRegister.h.func-sort-c.html @@ -0,0 +1,4681 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionRegister.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionRegister.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:77100.0 %
Date:2024-04-19 12:12:35Functions:1133115298.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18ActionRegistrationINS_11multicolvar11MFilterLessEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_11multicolvar11MFilterMoreEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_11multicolvar15DumpMultiColvarEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_11multicolvar6UWallsEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_4isdb6ShadowEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_4isdb7EMMIVOXEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_4isdb7RescaleEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_6adjmat11DeterminantEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_6colvar16SelectMassChargeEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_6colvar19DihedralCorrelationEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_6colvar5PlaneEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_6colvar8TemplateEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_7generic15RandomExchangesEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_7generic4TimeEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_7volumes14VolumeShortcutIXadL_ZNS1_14glob_tetraporeEEEEEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_7volumes15VolumeTetraporeEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_7volumes7DensityEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_3SumEEEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_6BesselEEEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_11multicolvar10XYTorsionsEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_11multicolvar13PlaneShortcutEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_11multicolvar16InPlaneDistancesEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_11multicolvar6AnglesEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_11multicolvar6DihcorEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_11multicolvar6XAngleEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_12crystdistrib12BopsShortcutEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_12crystdistrib12RopsShortcutEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_14membranefusion10memFusionPEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_14membranefusion20fusionPoreExpansionPEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_14membranefusion21fusionPoreNucleationPEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_3ves19Opt_RobbinsMonroSGDEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_3ves9Opt_DummyEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_4bias13ReweightMetadEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_4bias4ABMDEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_4bias6LWallsEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_4maze10Steered_MDEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_4maze13OptimizerBiasEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_4maze19Simulated_AnnealingEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_4maze22Random_Acceleration_MDEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_6adjmat16FunctionOfMatrixINS_8function7BetweenEEEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_6adjmat16FunctionOfMatrixINS_8function8LessThanEEEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_6adjmat6SprintEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_19DihedralCorrelationEEEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_5PlaneEEEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_6colvar16ProjectionOnAxisEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_19DihedralCorrelationEEEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_5PlaneEEEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_6colvar6GHBFIXEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_6colvar9MultiRMSDEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_6dimred19SketchMapProjectionEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_7contour11DumpContourEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_7contour11FindContourEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_7contour18FindContourSurfaceEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_7contour19DistanceFromContourEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_7contour20FindSphericalContourEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_7contour28DistanceFromSphericalContourEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_7fourier16FourierTransformEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_7generic15DumpProjectionsEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_7symfunc10AtomicSMACEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_7symfunc11RadialTetraEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_7symfunc12AngularTetraEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_7symfunc17HexacticParameterEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_7symfunc18LocalCrystallinityEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_7volumes12VolumeCavityEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_7volumes14VolumeShortcutIXadL_ZNS1_11glob_cavityEEEEEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_7volumes14VolumeShortcutIXadL_ZNS1_13glob_contoursEEEEEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_7volumes14VolumeShortcutIXadL_ZNS1_13glob_cylinderEEEEEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_7volumes16VolumeInCylinderEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_7volumes16VolumeInEnvelopeEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_8analysis21FarthestPointSamplingEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_8function15FuncPathGeneralEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_7MomentsEEEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS_9gridtools20EvaluateGridFunctionEEEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS_9gridtools20EvaluateGridFunctionEEEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS_7symfunc19CylindricalHarmonicEEEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_9gridtools13PairEntropiesEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_11multicolvar11CoordAnglesEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_11multicolvar9AlphaBetaEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_12crystdistrib12DopsShortcutEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_3ves11BF_CombinedEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_3ves17TD_MulticanonicalEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_3ves25TD_MultithermalMultibaricEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_3ves8Opt_AdamEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_4bias18ExtendedLagrangianEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_4bias8ExternalEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_4isdb6SelectEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_4isdb8SelectorEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_4maze11Random_WalkEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_4maze7MemeticEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_4opes9ECVcustomEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_4pamm4PAMMEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_4sasa10SASA_HASELEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_4sasa9SASA_LCPOEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_5fisst5FISSTEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_6adjmat11HbondMatrixEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_6adjmat16FunctionOfMatrixINS_7symfunc19CylindricalHarmonicEEEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_6colvar5DimerEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_6colvar7PCARMSDEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_6dimred13ProjectPointsEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_6dimred3PCAEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_7generic9ResetCellEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_7mapping12AdaptivePathEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_7mapping17PathDisplacementsEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_7mapping21GeometricPathShortcutEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_8clusters13ClusterNatomsEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_8clusters13OutputClusterEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_8clusters15ClusterDiameterEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_8clusters18ClusterWithSurfaceEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_8clusters19ClusterDistributionEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_8clusters27ClusterDistributionShortcutEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_8function11FuncPathMSDEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_8function13LocalEnsembleEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_7HighestEEEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_4SortEEEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_9gridtools15FindGridOptimumEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_9gridtools22EvaluateFunctionOnGridEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_18secondarystructure9AlphaRMSDEE6createERKNS_13ActionOptionsE3
_ZN4PLMD18ActionRegistrationINS_3ves12BF_GaussiansEE6createERKNS_13ActionOptionsE3
_ZN4PLMD18ActionRegistrationINS_3ves13OutputFesBiasEE6createERKNS_13ActionOptionsE3
_ZN4PLMD18ActionRegistrationINS_3ves16BF_CubicBsplinesEE6createERKNS_13ActionOptionsE3
_ZN4PLMD18ActionRegistrationINS_4bias12ReweightBiasEE6createERKNS_13ActionOptionsE3
_ZN4PLMD18ActionRegistrationINS_4opes16ECVumbrellasFileEE6createERKNS_13ActionOptionsE3
_ZN4PLMD18ActionRegistrationINS_6adjmat9NeighborsEE6createERKNS_13ActionOptionsE3
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_5AngleEEEE6createERKNS_13ActionOptionsE3
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_6DipoleEEEE6createERKNS_13ActionOptionsE3
_ZN4PLMD18ActionRegistrationINS_6colvar7ExtraCVEE6createERKNS_13ActionOptionsE3
_ZN4PLMD18ActionRegistrationINS_6logmfd6LogMFDEE6createERKNS_13ActionOptionsE3
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_9PiecewiseEEEE6createERKNS_13ActionOptionsE3
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_9PiecewiseEEEE6createERKNS_13ActionOptionsE3
_ZN4PLMD18ActionRegistrationINS_12crystdistrib27QuaternionBondProductMatrixEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_3ves12BF_ChebyshevEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_3ves21TD_ProductCombinationEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_3ves7BF_SineEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_3ves9BF_CosineEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_3ves9VesDeltaFEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_4bias15MovingRestraintEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_4bias27ReweightTemperaturePressureEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_4isdb3PREEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_4isdb7CaliberEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_4opes9ECVlinearEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_6adjmat16CovarianceMatrixEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_6colvar5ERMSDEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_6dimred9SketchMapEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_6funnel6FunnelEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_7generic8PrintNDXEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_7mapping13GeometricPathEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_7mapping22PathReparameterizationEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_8analysis7AverageEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_7MomentsEEEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_8function7pytorch12PytorchModelEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_12crystdistrib10QuaternionEE6createERKNS_13ActionOptionsE5
_ZN4PLMD18ActionRegistrationINS_3ves26TD_GeneralizedExtremeValueEE6createERKNS_13ActionOptionsE5
_ZN4PLMD18ActionRegistrationINS_6adjmat16FunctionOfMatrixINS_7symfunc7FccubicEEEE6createERKNS_13ActionOptionsE5
_ZN4PLMD18ActionRegistrationINS_6colvar7EEFSolvEE6createERKNS_13ActionOptionsE5
_ZN4PLMD18ActionRegistrationINS_6dimred13ArrangePointsEE6createERKNS_13ActionOptionsE5
_ZN4PLMD18ActionRegistrationINS_6funnel9FUNNEL_PSEE6createERKNS_13ActionOptionsE5
_ZN4PLMD18ActionRegistrationINS_7mapping7PCAVarsEE6createERKNS_13ActionOptionsE5
_ZN4PLMD18ActionRegistrationINS_7symfunc19ThreeBodyGFunctionsEE6createERKNS_13ActionOptionsE5
_ZN4PLMD18ActionRegistrationINS_7symfunc4SMACEE6createERKNS_13ActionOptionsE5
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_7MomentsEEEE6createERKNS_13ActionOptionsE5
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS_7symfunc7FccubicEEEE6createERKNS_13ActionOptionsE5
_ZN4PLMD18ActionRegistrationINS_8function7annfunc3ANNEE6createERKNS_13ActionOptionsE5
_ZN4PLMD18ActionRegistrationINS_9gridtools9KLEntropyEE6createERKNS_13ActionOptionsE5
_ZN4PLMD18ActionRegistrationINS_11multicolvar8TorsionsEE6createERKNS_13ActionOptionsE6
_ZN4PLMD18ActionRegistrationINS_12crystdistrib23QuaternionProductMatrixEE6createERKNS_13ActionOptionsE6
_ZN4PLMD18ActionRegistrationINS_3ves32TD_ExponentiallyModifiedGaussianEE6createERKNS_13ActionOptionsE6
_ZN4PLMD18ActionRegistrationINS_4isdb9JCouplingEE6createERKNS_13ActionOptionsE6
_ZN4PLMD18ActionRegistrationINS_4pamm12HBPammMatrixEE6createERKNS_13ActionOptionsE6
_ZN4PLMD18ActionRegistrationINS_4pamm14HBPammShortcutEE6createERKNS_13ActionOptionsE6
_ZN4PLMD18ActionRegistrationINS_6adjmat16FunctionOfMatrixINS_8function8MoreThanEEEE6createERKNS_13ActionOptionsE6
_ZN4PLMD18ActionRegistrationINS_6adjmat7VoronoiEE6createERKNS_13ActionOptionsE6
_ZN4PLMD18ActionRegistrationINS_7generic10WrapAroundEE6createERKNS_13ActionOptionsE6
_ZN4PLMD18ActionRegistrationINS_7generic5DebugEE6createERKNS_13ActionOptionsE6
_ZN4PLMD18ActionRegistrationINS_8analysis11WhamWeightsEE6createERKNS_13ActionOptionsE6
_ZN4PLMD18ActionRegistrationINS_8analysis13WhamHistogramEE6createERKNS_13ActionOptionsE6
_ZN4PLMD18ActionRegistrationINS_4opes9OPESmetadINS1_11explorationEEEE6createERKNS_13ActionOptionsE7
_ZN4PLMD18ActionRegistrationINS_6adjmat14TorsionsMatrixEE6createERKNS_13ActionOptionsE7
_ZN4PLMD18ActionRegistrationINS_6dimred32ClassicalMultiDimensionalScalingEE6createERKNS_13ActionOptionsE7
_ZN4PLMD18ActionRegistrationINS_7generic8UpdateIfEE6createERKNS_13ActionOptionsE7
_ZN4PLMD18ActionRegistrationINS_7symfunc15LocalSteinhardtEE6createERKNS_13ActionOptionsE7
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_6BesselEEEE6createERKNS_13ActionOptionsE7
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_6BesselEEEE6createERKNS_13ActionOptionsE7
_ZN4PLMD18ActionRegistrationINS_9gridtools8GradientEE6createERKNS_13ActionOptionsE7
_ZN4PLMD18ActionRegistrationINS_3eds3EDSEE6createERKNS_13ActionOptionsE8
_ZN4PLMD18ActionRegistrationINS_3ves14TD_ExponentialEE6createERKNS_13ActionOptionsE8
_ZN4PLMD18ActionRegistrationINS_3ves20TD_GeneralizedNormalEE6createERKNS_13ActionOptionsE8
_ZN4PLMD18ActionRegistrationINS_4maze4LossEE6createERKNS_13ActionOptionsE8
_ZN4PLMD18ActionRegistrationINS_4opes16ECVumbrellasLineEE6createERKNS_13ActionOptionsE8
_ZN4PLMD18ActionRegistrationINS_6adjmat12BridgeMatrixEE6createERKNS_13ActionOptionsE8
_ZN4PLMD18ActionRegistrationINS_6adjmat14TopologyMatrixEE6createERKNS_13ActionOptionsE8
_ZN4PLMD18ActionRegistrationINS_6adjmat6BridgeEE6createERKNS_13ActionOptionsE8
_ZN4PLMD18ActionRegistrationINS_6colvar10ContactMapEE6createERKNS_13ActionOptionsE8
_ZN4PLMD18ActionRegistrationINS_6colvar8DHEnergyEE6createERKNS_13ActionOptionsE8
_ZN4PLMD18ActionRegistrationINS_7refdist27NormalizedEuclideanDistanceEE6createERKNS_13ActionOptionsE8
_ZN4PLMD18ActionRegistrationINS_7symfunc24CoordShellVectorFunctionEE6createERKNS_13ActionOptionsE8
_ZN4PLMD18ActionRegistrationINS_8analysis17LandmarkSelectionEE6createERKNS_13ActionOptionsE8
_ZN4PLMD18ActionRegistrationINS_9gridtools18MultiColvarDensityEE6createERKNS_13ActionOptionsE8
_ZN4PLMD18ActionRegistrationINS_3ves11TD_VonMisesEE6createERKNS_13ActionOptionsE9
_ZN4PLMD18ActionRegistrationINS_3ves13TD_ChiSquaredEE6createERKNS_13ActionOptionsE9
_ZN4PLMD18ActionRegistrationINS_3ves6TD_ChiEE6createERKNS_13ActionOptionsE9
_ZN4PLMD18ActionRegistrationINS_3ves7TD_GridEE6createERKNS_13ActionOptionsE9
_ZN4PLMD18ActionRegistrationINS_4opes20ECVmultiThermalBaricEE6createERKNS_13ActionOptionsE9
_ZN4PLMD18ActionRegistrationINS_5vatom11ArgsToVatomEE6createERKNS_13ActionOptionsE9
_ZN4PLMD18ActionRegistrationINS_6adjmat12InvertMatrixEE6createERKNS_13ActionOptionsE9
_ZN4PLMD18ActionRegistrationINS_6colvar4CellEE6createERKNS_13ActionOptionsE9
_ZN4PLMD18ActionRegistrationINS_7generic13FitToTemplateEE6createERKNS_13ActionOptionsE9
_ZN4PLMD18ActionRegistrationINS_7generic20EffectiveEnergyDriftEE6createERKNS_13ActionOptionsE9
_ZN4PLMD18ActionRegistrationINS_7refdist6KernelEE6createERKNS_13ActionOptionsE9
_ZN4PLMD18ActionRegistrationINS_8analysis9CommittorEE6createERKNS_13ActionOptionsE9
_ZN4PLMD18ActionRegistrationINS_8analysis9LogSumExpEE6createERKNS_13ActionOptionsE9
_ZN4PLMD18ActionRegistrationINS_8function12FuncSumHillsEE6createERKNS_13ActionOptionsE9
_ZN4PLMD18ActionRegistrationINS_8valtools7FlattenEE6createERKNS_13ActionOptionsE9
_ZN4PLMD18ActionRegistrationINS_3ves9BF_CustomEE6createERKNS_13ActionOptionsE10
_ZN4PLMD18ActionRegistrationINS_4bias6UWallsEE6createERKNS_13ActionOptionsE10
_ZN4PLMD18ActionRegistrationINS_6envsim21EnvironmentSimilarityEE6createERKNS_13ActionOptionsE10
_ZN4PLMD18ActionRegistrationINS_7mapping4PathEE6createERKNS_13ActionOptionsE10
_ZN4PLMD18ActionRegistrationINS_7symfunc12LocalAverageEE6createERKNS_13ActionOptionsE10
_ZN4PLMD18ActionRegistrationINS_7volumes14VolumeInSphereEE6createERKNS_13ActionOptionsE10
_ZN4PLMD18ActionRegistrationINS_7volumes14VolumeShortcutIXadL_ZNS1_11glob_sphereEEEEEE6createERKNS_13ActionOptionsE10
_ZN4PLMD18ActionRegistrationINS_18secondarystructure12AntibetaRMSDEE6createERKNS_13ActionOptionsE11
_ZN4PLMD18ActionRegistrationINS_4isdb3NOEEE6createERKNS_13ActionOptionsE11
_ZN4PLMD18ActionRegistrationINS_4opes15ECVmultiThermalEE6createERKNS_13ActionOptionsE11
_ZN4PLMD18ActionRegistrationINS_6colvar11PropertyMapEE6createERKNS_13ActionOptionsE11
_ZN4PLMD18ActionRegistrationINS_9gridtools15ReadGridInSetupEE6createERKNS_13ActionOptionsE11
_ZN4PLMD18ActionRegistrationINS_18secondarystructure12ParabetaRMSDEE6createERKNS_13ActionOptionsE12
_ZN4PLMD18ActionRegistrationINS_3drr27DynamicReferenceRestrainingEE6createERKNS_13ActionOptionsE12
_ZN4PLMD18ActionRegistrationINS_3piv3PIVEE6createERKNS_13ActionOptionsE12
_ZN4PLMD18ActionRegistrationINS_3ves20TD_LinearCombinationEE6createERKNS_13ActionOptionsE12
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS_12crystdistrib10QuaternionEEEE6createERKNS_13ActionOptionsE12
_ZN4PLMD18ActionRegistrationINS_7generic14DumpMassChargeEE6createERKNS_13ActionOptionsE12
_ZN4PLMD18ActionRegistrationINS_7generic6PlumedEE6createERKNS_13ActionOptionsE12
_ZN4PLMD18ActionRegistrationINS_7refdist19MahalanobisDistanceEE6createERKNS_13ActionOptionsE12
_ZN4PLMD18ActionRegistrationINS_8analysis14GatherReplicasEE6createERKNS_13ActionOptionsE12
_ZN4PLMD18ActionRegistrationINS_8analysis4WhamEE6createERKNS_13ActionOptionsE12
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_4SortEEEE6createERKNS_13ActionOptionsE12
_ZN4PLMD18ActionRegistrationINS_4bias5WallsEE6createERKNS_13ActionOptionsE13
_ZN4PLMD18ActionRegistrationINS_6colvar5DRMSDEE6createERKNS_13ActionOptionsE13
_ZN4PLMD18ActionRegistrationINS_4isdb14FretEfficiencyEE6createERKNS_13ActionOptionsE14
_ZN4PLMD18ActionRegistrationINS_4opes9OPESmetadINS1_11convergenceEEEE6createERKNS_13ActionOptionsE14
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_7TorsionEEEE6createERKNS_13ActionOptionsE14
_ZN4PLMD18ActionRegistrationINS_6colvar7PathMSDEE6createERKNS_13ActionOptionsE14
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_4SortEEEE6createERKNS_13ActionOptionsE14
_ZN4PLMD18ActionRegistrationINS_3ves22TD_ProductDistributionEE6createERKNS_13ActionOptionsE15
_ZN4PLMD18ActionRegistrationINS_6colvar6VolumeEE6createERKNS_13ActionOptionsE15
_ZN4PLMD18ActionRegistrationINS_7generic7DumpPDBEE6createERKNS_13ActionOptionsE15
_ZN4PLMD18ActionRegistrationINS_8analysis10CreateMaskEE6createERKNS_13ActionOptionsE15
_ZN4PLMD18ActionRegistrationINS_9gridtools12ConvertToFESEE6createERKNS_13ActionOptionsE15
_ZN4PLMD18ActionRegistrationINS_3ves9BF_PowersEE6createERKNS_13ActionOptionsE16
_ZN4PLMD18ActionRegistrationINS_3ves9TD_CustomEE6createERKNS_13ActionOptionsE16
_ZN4PLMD18ActionRegistrationINS_6colvar10ColvarFakeEE6createERKNS_13ActionOptionsE17
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS_12crystdistrib10QuaternionEEEE6createERKNS_13ActionOptionsE17
_ZN4PLMD18ActionRegistrationINS_7generic5FlushEE6createERKNS_13ActionOptionsE17
_ZN4PLMD18ActionRegistrationINS_8clusters13DFSClusteringEE6createERKNS_13ActionOptionsE17
_ZN4PLMD18ActionRegistrationINS_4isdb11CS2BackboneEE6createERKNS_13ActionOptionsE18
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_16SelectMassChargeEEEE6createERKNS_13ActionOptionsE18
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_16SelectMassChargeEEEE6createERKNS_13ActionOptionsE18
_ZN4PLMD18ActionRegistrationINS_4isdb13MetainferenceEE6createERKNS_13ActionOptionsE19
_ZN4PLMD18ActionRegistrationINS_8analysis13CollectFramesEE6createERKNS_13ActionOptionsE19
_ZN4PLMD18ActionRegistrationINS_4isdb4EMMIEE6createERKNS_13ActionOptionsE20
_ZN4PLMD18ActionRegistrationINS_8clusters17ClusterPropertiesEE6createERKNS_13ActionOptionsE20
_ZN4PLMD18ActionRegistrationINS_6adjmat17DiagonalizeMatrixEE6createERKNS_13ActionOptionsE22
_ZN4PLMD18ActionRegistrationINS_8analysis9HistogramEE6createERKNS_13ActionOptionsE22
_ZN4PLMD18ActionRegistrationINS_6colvar5AngleEE6createERKNS_13ActionOptionsE23
_ZN4PLMD18ActionRegistrationINS_7generic7IncludeEE6createERKNS_13ActionOptionsE23
_ZN4PLMD18ActionRegistrationINS_4s2cm14S2ContactModelEE6createERKNS_13ActionOptionsE24
_ZN4PLMD18ActionRegistrationINS_18secondarystructure22SecondaryStructureRMSDEE6createERKNS_13ActionOptionsE26
_ZN4PLMD18ActionRegistrationINS_6adjmat16FunctionOfMatrixINS_8function7CombineEEEE6createERKNS_13ActionOptionsE26
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_5AngleEEEE6createERKNS_13ActionOptionsE26
_ZN4PLMD18ActionRegistrationINS_8function8EnsembleEE6createERKNS_13ActionOptionsE27
_ZN4PLMD18ActionRegistrationINS_5setup5UnitsEE6createERKNS_13ActionOptionsE28
_ZN4PLMD18ActionRegistrationINS_7generic10DumpForcesEE6createERKNS_13ActionOptionsE28
_ZN4PLMD18ActionRegistrationINS_7refdist17EuclideanDistanceEE6createERKNS_13ActionOptionsE28
_ZN4PLMD18ActionRegistrationINS_3ves15TD_WellTemperedEE6createERKNS_13ActionOptionsE29
_ZN4PLMD18ActionRegistrationINS_4isdb3RDCEE6createERKNS_13ActionOptionsE29
_ZN4PLMD18ActionRegistrationINS_8clusters14ClusterWeightsEE6createERKNS_13ActionOptionsE29
_ZN4PLMD18ActionRegistrationINS_4opes12OPESexpandedEE6createERKNS_13ActionOptionsE30
_ZN4PLMD18ActionRegistrationINS_8function5StatsEE6createERKNS_13ActionOptionsE31
_ZN4PLMD18ActionRegistrationINS_4isdb4SAXSEE6createERKNS_13ActionOptionsE32
_ZN4PLMD18ActionRegistrationINS_6colvar8GyrationEE6createERKNS_13ActionOptionsE33
_ZN4PLMD18ActionRegistrationINS_5vatom9FixedAtomEE6createERKNS_13ActionOptionsE35
_ZN4PLMD18ActionRegistrationINS_7generic10DumpVectorEE6createERKNS_13ActionOptionsE36
_ZN4PLMD18ActionRegistrationINS_6colvar16GyrationShortcutEE6createERKNS_13ActionOptionsE37
_ZN4PLMD18ActionRegistrationINS_6colvar6EnergyEE6createERKNS_13ActionOptionsE40
_ZN4PLMD18ActionRegistrationINS_4bias7PBMetaDEE6createERKNS_13ActionOptionsE41
_ZN4PLMD18ActionRegistrationINS_6adjmat16FunctionOfMatrixINS_7symfunc17SphericalHarmonicEEEE6createERKNS_13ActionOptionsE41
_ZN4PLMD18ActionRegistrationINS_6adjmat16FunctionOfMatrixINS_8function3SumEEEE6createERKNS_13ActionOptionsE41
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_8PositionEEEE6createERKNS_13ActionOptionsE41
_ZN4PLMD18ActionRegistrationINS_7symfunc10SteinhardtEE6createERKNS_13ActionOptionsE41
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS_7refdist10DifferenceEEEE6createERKNS_13ActionOptionsE41
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS_7symfunc17SphericalHarmonicEEEE6createERKNS_13ActionOptionsE41
_ZN4PLMD18ActionRegistrationINS_5setup4LoadEE6createERKNS_13ActionOptionsE42
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_7HighestEEEE6createERKNS_13ActionOptionsE44
_ZN4PLMD18ActionRegistrationINS_7symfunc19CoordinationNumbersEE6createERKNS_13ActionOptionsE45
_ZN4PLMD18ActionRegistrationINS_7volumes12VolumeAroundEE6createERKNS_13ActionOptionsE46
_ZN4PLMD18ActionRegistrationINS_7volumes14VolumeShortcutIXadL_ZNS1_11glob_aroundEEEEEE6createERKNS_13ActionOptionsE46
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_7HighestEEEE6createERKNS_13ActionOptionsE46
_ZN4PLMD18ActionRegistrationINS_3ves11BF_WaveletsEE6createERKNS_13ActionOptionsE47
_ZN4PLMD18ActionRegistrationINS_6colvar10RMSDVectorEE6createERKNS_13ActionOptionsE49
_ZN4PLMD18ActionRegistrationINS_4bias6MaxEntEE6createERKNS_13ActionOptionsE50
_ZN4PLMD18ActionRegistrationINS_7refdist12DisplacementEE6createERKNS_13ActionOptionsE52
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_7BetweenEEEE6createERKNS_13ActionOptionsE52
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_7BetweenEEEE6createERKNS_13ActionOptionsE53
_ZN4PLMD18ActionRegistrationINS_6colvar9PuckeringEE6createERKNS_13ActionOptionsE54
_ZN4PLMD18ActionRegistrationINS_7refdist21MatrixProductDiagonalEE6createERKNS_13ActionOptionsE55
_ZN4PLMD18ActionRegistrationINS_11multicolvar9DistancesEE6createERKNS_13ActionOptionsE56
_ZN4PLMD18ActionRegistrationINS_5setup7RestartEE6createERKNS_13ActionOptionsE56
_ZN4PLMD18ActionRegistrationINS_6adjmat17MatrixTimesMatrixEE6createERKNS_13ActionOptionsE57
_ZN4PLMD18ActionRegistrationINS_7generic14WholeMoleculesEE6createERKNS_13ActionOptionsE57
_ZN4PLMD18ActionRegistrationINS_8valtools16SelectComponentsEE6createERKNS_13ActionOptionsE57
_ZN4PLMD18ActionRegistrationINS_6colvar6DipoleEE6createERKNS_13ActionOptionsE58
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_8LessThanEEEE6createERKNS_13ActionOptionsE58
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_8LessThanEEEE6createERKNS_13ActionOptionsE59
_ZN4PLMD18ActionRegistrationINS_3ves11BF_LegendreEE6createERKNS_13ActionOptionsE61
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_6DipoleEEEE6createERKNS_13ActionOptionsE61
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_8MoreThanEEEE6createERKNS_13ActionOptionsE62
_ZN4PLMD18ActionRegistrationINS_8analysis10AccumulateEE6createERKNS_13ActionOptionsE63
_ZN4PLMD18ActionRegistrationINS_9gridtools11PairEntropyEE6createERKNS_13ActionOptionsE65
_ZN4PLMD18ActionRegistrationINS_9gridtools3RDFEE6createERKNS_13ActionOptionsE66
_ZN4PLMD18ActionRegistrationINS_9gridtools8DumpGridEE6createERKNS_13ActionOptionsE66
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_8MoreThanEEEE6createERKNS_13ActionOptionsE68
_ZN4PLMD18ActionRegistrationINS_3ves20OutputBasisFunctionsEE6createERKNS_13ActionOptionsE71
_ZN4PLMD18ActionRegistrationINS_3ves10TD_UniformEE6createERKNS_13ActionOptionsE73
_ZN4PLMD18ActionRegistrationINS_3ves19Opt_BachAveragedSGDEE6createERKNS_13ActionOptionsE75
_ZN4PLMD18ActionRegistrationINS_6adjmat12OuterProductEE6createERKNS_13ActionOptionsE77
_ZN4PLMD18ActionRegistrationINS_6colvar4RMSDEE6createERKNS_13ActionOptionsE81
_ZN4PLMD18ActionRegistrationINS_9gridtools15InterpolateGridEE6createERKNS_13ActionOptionsE82
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_7CombineEEEE6createERKNS_13ActionOptionsE83
_ZN4PLMD18ActionRegistrationINS_7generic4ReadEE6createERKNS_13ActionOptionsE89
_ZN4PLMD18ActionRegistrationINS_3ves18VesLinearExpansionEE6createERKNS_13ActionOptionsE90
_ZN4PLMD18ActionRegistrationINS_9gridtools14FunctionOfGridINS_8function3SumEEEE6createERKNS_13ActionOptionsE90
_ZN4PLMD18ActionRegistrationINS_14GenericMolInfoEE6createERKNS_13ActionOptionsE91
_ZN4PLMD18ActionRegistrationINS_6adjmat14DistanceMatrixEE6createERKNS_13ActionOptionsE92
_ZN4PLMD18ActionRegistrationINS_8analysis7CollectEE6createERKNS_13ActionOptionsE92
_ZN4PLMD18ActionRegistrationINS_6colvar8PositionEE6createERKNS_13ActionOptionsE93
_ZN4PLMD18ActionRegistrationINS_8valtools14SelectWithMaskEE6createERKNS_13ActionOptionsE93
_ZN4PLMD18ActionRegistrationINS_3ves10BF_FourierEE6createERKNS_13ActionOptionsE95
_ZN4PLMD18ActionRegistrationINS_6colvar12RMSDShortcutEE6createERKNS_13ActionOptionsE104
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_8DistanceEEEE6createERKNS_13ActionOptionsE104
_ZN4PLMD18ActionRegistrationINS_8function7ProductEE6createERKNS_13ActionOptionsE114
_ZN4PLMD18ActionRegistrationINS_15ActionToGetDataEE6createERKNS_13ActionOptionsE115
_ZN4PLMD18ActionRegistrationINS_7generic12PDB2ConstantEE6createERKNS_13ActionOptionsE115
_ZN4PLMD18ActionRegistrationINS_3ves24OutputTargetDistributionEE6createERKNS_13ActionOptionsE120
_ZN4PLMD18ActionRegistrationINS_6adjmat6VStackEE6createERKNS_13ActionOptionsE134
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_8PositionEEEE6createERKNS_13ActionOptionsE134
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS_7refdist10DifferenceEEEE6createERKNS_13ActionOptionsE143
_ZN4PLMD18ActionRegistrationINS_9gridtools3KDEEE6createERKNS_13ActionOptionsE146
_ZN4PLMD18ActionRegistrationINS_4bias5MetaDEE6createERKNS_13ActionOptionsE157
_ZN4PLMD18ActionRegistrationINS_6adjmat15TransposeMatrixEE6createERKNS_13ActionOptionsE162
_ZN4PLMD18ActionRegistrationINS_8valtools11ConcatenateEE6createERKNS_13ActionOptionsE175
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS_7refdist10DifferenceEEEE6createERKNS_13ActionOptionsE184
_ZN4PLMD18ActionRegistrationINS_3ves11TD_GaussianEE6createERKNS_13ActionOptionsE191
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_7CombineEEEE6createERKNS_13ActionOptionsE194
_ZN4PLMD18ActionRegistrationINS_4bias9RestraintEE6createERKNS_13ActionOptionsE203
_ZN4PLMD18ActionRegistrationINS_4bias9BiasValueEE6createERKNS_13ActionOptionsE204
_ZN4PLMD18ActionRegistrationINS_7generic9DumpAtomsEE6createERKNS_13ActionOptionsE205
_ZN4PLMD18ActionRegistrationINS_6adjmat21ContactMatrixShortcutEE6createERKNS_13ActionOptionsE206
_ZN4PLMD18ActionRegistrationINS_4bias17RestraintShortcutEE6createERKNS_13ActionOptionsE207
_ZN4PLMD18ActionRegistrationINS_6adjmat13ContactMatrixEE6createERKNS_13ActionOptionsE208
_ZN4PLMD18ActionRegistrationINS_6colvar12CoordinationEE6createERKNS_13ActionOptionsE219
_ZN4PLMD18ActionRegistrationINS_7generic15DumpDerivativesEE6createERKNS_13ActionOptionsE242
_ZN4PLMD18ActionRegistrationINS_7generic4OnesEE6createERKNS_13ActionOptionsE252
_ZN4PLMD18ActionRegistrationINS_7generic9EndPlumedEE6createERKNS_13ActionOptionsE281
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_7CombineEEEE6createERKNS_13ActionOptionsE303
_ZN4PLMD18ActionRegistrationINS_5GroupEE6createERKNS_13ActionOptionsE321
_ZN4PLMD18ActionRegistrationINS_6adjmat17MatrixTimesVectorEE6createERKNS_13ActionOptionsE348
_ZN4PLMD18ActionRegistrationINS_6adjmat16FunctionOfMatrixINS_8function6CustomEEEE6createERKNS_13ActionOptionsE369
_ZN4PLMD18ActionRegistrationINS_9gridtools14FunctionOfGridINS_8function6CustomEEEE6createERKNS_13ActionOptionsE432
_ZN4PLMD18ActionRegistrationINS_6colvar8DistanceEE6createERKNS_13ActionOptionsE595
_ZN4PLMD18ActionRegistrationINS_6colvar7TorsionEE6createERKNS_13ActionOptionsE665
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_7TorsionEEEE6createERKNS_13ActionOptionsE679
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_8DistanceEEEE6createERKNS_13ActionOptionsE699
_ZN4PLMD18ActionRegistrationINS_5vatom5GhostEE6createERKNS_13ActionOptionsE703
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_3SumEEEE6createERKNS_13ActionOptionsE768
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_3SumEEEE6createERKNS_13ActionOptionsE809
_ZN4PLMD18ActionRegistrationINS_7generic8ConstantEE6createERKNS_13ActionOptionsE842
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_6CustomEEEE6createERKNS_13ActionOptionsE1009
_ZN4PLMD18ActionRegistrationINS_7generic5PrintEE6createERKNS_13ActionOptionsE1019
_ZN4PLMD18ActionRegistrationINS_19DomainDecompositionEE6createERKNS_13ActionOptionsE1091
_ZN4PLMD18ActionRegistrationINS_9PbcActionEE6createERKNS_13ActionOptionsE1091
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_6CustomEEEE6createERKNS_13ActionOptionsE1172
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_6CustomEEEE6createERKNS_13ActionOptionsE2982
_ZN4PLMD18ActionRegistrationINS_11multicolvar11CoordAnglesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_11multicolvar11CoordAnglesEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_11multicolvar11MFilterLessEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_11multicolvar11MFilterLessEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_11multicolvar11MFilterMoreEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_11multicolvar11MFilterMoreEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_11multicolvar13PlaneShortcutEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_11multicolvar13PlaneShortcutEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_11multicolvar15DumpMultiColvarEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_11multicolvar15DumpMultiColvarEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_11multicolvar16InPlaneDistancesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_11multicolvar16InPlaneDistancesEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_11multicolvar6AnglesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_11multicolvar6AnglesEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_11multicolvar6DihcorEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_11multicolvar6DihcorEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_11multicolvar6UWallsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_11multicolvar6UWallsEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_11multicolvar8TorsionsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_11multicolvar8TorsionsEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_11multicolvar9AlphaBetaEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_11multicolvar9AlphaBetaEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_12crystdistrib10QuaternionEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_12crystdistrib10QuaternionEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_12crystdistrib12BopsShortcutEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_12crystdistrib12BopsShortcutEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_12crystdistrib12DopsShortcutEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_12crystdistrib12DopsShortcutEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_12crystdistrib12RopsShortcutEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_12crystdistrib12RopsShortcutEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_12crystdistrib23QuaternionProductMatrixEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_12crystdistrib23QuaternionProductMatrixEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_12crystdistrib27QuaternionBondProductMatrixEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_12crystdistrib27QuaternionBondProductMatrixEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_14GenericMolInfoEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_14GenericMolInfoEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_14membranefusion10memFusionPEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_14membranefusion10memFusionPEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_14membranefusion20fusionPoreExpansionPEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_14membranefusion20fusionPoreExpansionPEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_14membranefusion21fusionPoreNucleationPEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_14membranefusion21fusionPoreNucleationPEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_15ActionToGetDataEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_15ActionToGetDataEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_15ActionToPutDataEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_15ActionToPutDataEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_18secondarystructure12AntibetaRMSDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_18secondarystructure12AntibetaRMSDEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_18secondarystructure12ParabetaRMSDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_18secondarystructure12ParabetaRMSDEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_18secondarystructure22SecondaryStructureRMSDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_18secondarystructure22SecondaryStructureRMSDEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_18secondarystructure9AlphaRMSDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_18secondarystructure9AlphaRMSDEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_19DomainDecompositionEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_19DomainDecompositionEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_3drr27DynamicReferenceRestrainingEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_3drr27DynamicReferenceRestrainingEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_3eds3EDSEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_3eds3EDSEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_3piv3PIVEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_3piv3PIVEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_3ves10BF_FourierEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_3ves10BF_FourierEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_3ves10TD_UniformEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_3ves10TD_UniformEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_3ves11BF_CombinedEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_3ves11BF_CombinedEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_3ves11BF_LegendreEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_3ves11BF_LegendreEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_3ves11BF_WaveletsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_3ves11BF_WaveletsEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_3ves11TD_GaussianEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_3ves11TD_GaussianEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_3ves11TD_VonMisesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_3ves11TD_VonMisesEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_3ves12BF_ChebyshevEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_3ves12BF_ChebyshevEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_3ves12BF_GaussiansEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_3ves12BF_GaussiansEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_3ves13OutputFesBiasEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_3ves13OutputFesBiasEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_3ves13TD_ChiSquaredEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_3ves13TD_ChiSquaredEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_3ves14TD_ExponentialEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_3ves14TD_ExponentialEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_3ves15TD_WellTemperedEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_3ves15TD_WellTemperedEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_3ves16BF_CubicBsplinesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_3ves16BF_CubicBsplinesEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_3ves17TD_MulticanonicalEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_3ves17TD_MulticanonicalEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_3ves18VesLinearExpansionEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_3ves18VesLinearExpansionEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_3ves19Opt_BachAveragedSGDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_3ves19Opt_BachAveragedSGDEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_3ves19Opt_RobbinsMonroSGDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_3ves19Opt_RobbinsMonroSGDEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_3ves20OutputBasisFunctionsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_3ves20OutputBasisFunctionsEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_3ves20TD_GeneralizedNormalEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_3ves20TD_GeneralizedNormalEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_3ves20TD_LinearCombinationEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_3ves20TD_LinearCombinationEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_3ves21TD_ProductCombinationEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_3ves21TD_ProductCombinationEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_3ves22TD_ProductDistributionEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_3ves22TD_ProductDistributionEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_3ves24OutputTargetDistributionEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_3ves24OutputTargetDistributionEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_3ves25TD_MultithermalMultibaricEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_3ves25TD_MultithermalMultibaricEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_3ves26TD_GeneralizedExtremeValueEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_3ves26TD_GeneralizedExtremeValueEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_3ves32TD_ExponentiallyModifiedGaussianEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_3ves32TD_ExponentiallyModifiedGaussianEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_3ves6TD_ChiEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_3ves6TD_ChiEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_3ves7BF_SineEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_3ves7BF_SineEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_3ves7TD_GridEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_3ves7TD_GridEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_3ves8Opt_AdamEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_3ves8Opt_AdamEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_3ves9BF_CosineEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_3ves9BF_CosineEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_3ves9BF_CustomEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_3ves9BF_CustomEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_3ves9BF_PowersEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_3ves9BF_PowersEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_3ves9Opt_DummyEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_3ves9Opt_DummyEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_3ves9TD_CustomEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_3ves9TD_CustomEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_3ves9VesDeltaFEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_3ves9VesDeltaFEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4bias12ReweightBiasEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4bias12ReweightBiasEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4bias13ReweightMetadEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4bias13ReweightMetadEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4bias15MovingRestraintEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4bias15MovingRestraintEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4bias17RestraintShortcutEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4bias17RestraintShortcutEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4bias18ExtendedLagrangianEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4bias18ExtendedLagrangianEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4bias27ReweightTemperaturePressureEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4bias27ReweightTemperaturePressureEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4bias4ABMDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4bias4ABMDEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4bias5MetaDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4bias5MetaDEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4bias6LWallsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4bias6LWallsEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4bias6MaxEntEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4bias6MaxEntEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4bias6UWallsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4bias6UWallsEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4bias7PBMetaDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4bias7PBMetaDEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4bias8ExternalEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4bias8ExternalEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4bias9BiasValueEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4bias9BiasValueEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4bias9RestraintEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4bias9RestraintEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4isdb11CS2BackboneEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4isdb11CS2BackboneEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4isdb13MetainferenceEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4isdb13MetainferenceEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4isdb14FretEfficiencyEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4isdb14FretEfficiencyEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4isdb3NOEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4isdb3NOEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4isdb3PREEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4isdb3PREEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4isdb4EMMIEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4isdb4EMMIEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4isdb6SelectEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4isdb6SelectEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4isdb6ShadowEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4isdb6ShadowEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4isdb7CaliberEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4isdb7CaliberEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4isdb7EMMIVOXEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4isdb7EMMIVOXEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4isdb7RescaleEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4isdb7RescaleEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4isdb8SelectorEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4isdb8SelectorEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4isdb9JCouplingEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4isdb9JCouplingEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4maze10Steered_MDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4maze10Steered_MDEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4maze11Random_WalkEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4maze11Random_WalkEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4maze13OptimizerBiasEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4maze13OptimizerBiasEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4maze19Simulated_AnnealingEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4maze19Simulated_AnnealingEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4maze22Random_Acceleration_MDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4maze22Random_Acceleration_MDEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4maze4LossEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4maze4LossEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4maze7MemeticEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4maze7MemeticEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4opes12OPESexpandedEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4opes12OPESexpandedEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4opes15ECVmultiThermalEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4opes15ECVmultiThermalEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4opes16ECVumbrellasFileEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4opes16ECVumbrellasFileEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4opes16ECVumbrellasLineEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4opes16ECVumbrellasLineEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4opes20ECVmultiThermalBaricEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4opes20ECVmultiThermalBaricEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4opes9ECVcustomEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4opes9ECVcustomEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4opes9ECVlinearEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4opes9ECVlinearEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4opes9OPESmetadINS1_11convergenceEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4opes9OPESmetadINS1_11convergenceEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4opes9OPESmetadINS1_11explorationEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4opes9OPESmetadINS1_11explorationEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4pamm12HBPammMatrixEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4pamm12HBPammMatrixEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4pamm4PAMMEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4pamm4PAMMEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4s2cm14S2ContactModelEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4s2cm14S2ContactModelEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4sasa10SASA_HASELEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4sasa10SASA_HASELEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4sasa9SASA_LCPOEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4sasa9SASA_LCPOEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_5GroupEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_5GroupEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_5fisst5FISSTEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_5fisst5FISSTEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_5setup4LoadEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_5setup4LoadEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_5setup5UnitsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_5setup5UnitsEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_5setup7RestartEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_5setup7RestartEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_5vatom11ArgsToVatomEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_5vatom11ArgsToVatomEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_5vatom14CenterShortcutEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_5vatom14CenterShortcutEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_5vatom5GhostEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_5vatom5GhostEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_5vatom9FixedAtomEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_5vatom9FixedAtomEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6adjmat11DeterminantEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6adjmat11DeterminantEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6adjmat11HbondMatrixEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6adjmat11HbondMatrixEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6adjmat12BridgeMatrixEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6adjmat12BridgeMatrixEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6adjmat12InvertMatrixEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6adjmat12InvertMatrixEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6adjmat12OuterProductEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6adjmat12OuterProductEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6adjmat13ContactMatrixEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6adjmat13ContactMatrixEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6adjmat14DistanceMatrixEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6adjmat14DistanceMatrixEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6adjmat14TopologyMatrixEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6adjmat14TopologyMatrixEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6adjmat14TorsionsMatrixEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6adjmat14TorsionsMatrixEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6adjmat15TransposeMatrixEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6adjmat15TransposeMatrixEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6adjmat16CovarianceMatrixEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6adjmat16CovarianceMatrixEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6adjmat16FunctionOfMatrixINS_7symfunc17SphericalHarmonicEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6adjmat16FunctionOfMatrixINS_7symfunc17SphericalHarmonicEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6adjmat16FunctionOfMatrixINS_7symfunc19CylindricalHarmonicEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6adjmat16FunctionOfMatrixINS_7symfunc19CylindricalHarmonicEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6adjmat16FunctionOfMatrixINS_7symfunc7FccubicEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6adjmat16FunctionOfMatrixINS_7symfunc7FccubicEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6adjmat16FunctionOfMatrixINS_8function3SumEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6adjmat16FunctionOfMatrixINS_8function3SumEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6adjmat16FunctionOfMatrixINS_8function7BetweenEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6adjmat16FunctionOfMatrixINS_8function7BetweenEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6adjmat16FunctionOfMatrixINS_8function7CombineEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6adjmat16FunctionOfMatrixINS_8function7CombineEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6adjmat16FunctionOfMatrixINS_8function8LessThanEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6adjmat16FunctionOfMatrixINS_8function8LessThanEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6adjmat16FunctionOfMatrixINS_8function8MoreThanEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6adjmat16FunctionOfMatrixINS_8function8MoreThanEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6adjmat17DiagonalizeMatrixEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6adjmat17DiagonalizeMatrixEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6adjmat17MatrixTimesVectorEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6adjmat17MatrixTimesVectorEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6adjmat21ContactMatrixShortcutEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6adjmat21ContactMatrixShortcutEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6adjmat6BridgeEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6adjmat6BridgeEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6adjmat6SprintEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6adjmat6SprintEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6adjmat6VStackEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6adjmat6VStackEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6adjmat7VoronoiEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6adjmat7VoronoiEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6adjmat9NeighborsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6adjmat9NeighborsEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar10ColvarFakeEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar10ColvarFakeEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar10ContactMapEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar10ContactMapEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar10RMSDVectorEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar10RMSDVectorEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar11PropertyMapEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar11PropertyMapEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar12CoordinationEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar12CoordinationEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar12RMSDShortcutEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar12RMSDShortcutEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_19DihedralCorrelationEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_19DihedralCorrelationEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_5AngleEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_5AngleEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_5PlaneEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_5PlaneEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_6DipoleEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_6DipoleEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_7TorsionEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_7TorsionEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_8DistanceEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_8DistanceEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_8PositionEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_8PositionEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS_12crystdistrib10QuaternionEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS_12crystdistrib10QuaternionEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar16ProjectionOnAxisEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar16ProjectionOnAxisEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar19DihedralCorrelationEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar19DihedralCorrelationEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_19DihedralCorrelationEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_19DihedralCorrelationEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_5AngleEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_5AngleEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_5PlaneEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_5PlaneEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_6DipoleEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_6DipoleEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_7TorsionEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_7TorsionEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_8DistanceEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_8DistanceEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_8PositionEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_8PositionEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS_12crystdistrib10QuaternionEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS_12crystdistrib10QuaternionEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar4CellEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar4CellEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar4RMSDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar4RMSDEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar5AngleEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar5AngleEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar5DRMSDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar5DRMSDEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar5DimerEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar5DimerEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar5ERMSDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar5ERMSDEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar5PlaneEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar5PlaneEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar6DipoleEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar6DipoleEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar6EnergyEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar6EnergyEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar6GHBFIXEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar6GHBFIXEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar6VolumeEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar6VolumeEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar7EEFSolvEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar7EEFSolvEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar7ExtraCVEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar7ExtraCVEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar7PCARMSDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar7PCARMSDEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar7PathMSDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar7PathMSDEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar7TorsionEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar7TorsionEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar8DHEnergyEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar8DHEnergyEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar8DistanceEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar8DistanceEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar8GyrationEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar8GyrationEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar8PositionEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar8PositionEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar8TemplateEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar8TemplateEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar9MultiRMSDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar9MultiRMSDEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar9PuckeringEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar9PuckeringEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6dimred13ArrangePointsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6dimred13ArrangePointsEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6dimred13ProjectPointsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6dimred13ProjectPointsEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6dimred19SketchMapProjectionEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6dimred19SketchMapProjectionEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6dimred32ClassicalMultiDimensionalScalingEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6dimred32ClassicalMultiDimensionalScalingEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6dimred3PCAEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6dimred3PCAEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6dimred9SketchMapEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6dimred9SketchMapEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6envsim21EnvironmentSimilarityEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6envsim21EnvironmentSimilarityEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6funnel6FunnelEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6funnel6FunnelEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6funnel9FUNNEL_PSEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6funnel9FUNNEL_PSEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6logmfd6LogMFDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6logmfd6LogMFDEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7contour11DumpContourEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7contour11DumpContourEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7contour11FindContourEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7contour11FindContourEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7contour18FindContourSurfaceEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7contour18FindContourSurfaceEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7contour19DistanceFromContourEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7contour19DistanceFromContourEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7contour20FindSphericalContourEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7contour20FindSphericalContourEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7contour28DistanceFromSphericalContourEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7contour28DistanceFromSphericalContourEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7fourier16FourierTransformEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7fourier16FourierTransformEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7generic10DumpForcesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7generic10DumpForcesEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7generic10DumpVectorEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7generic10DumpVectorEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7generic10WrapAroundEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7generic10WrapAroundEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7generic12PDB2ConstantEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7generic12PDB2ConstantEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7generic13FitToTemplateEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7generic13FitToTemplateEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7generic14DumpMassChargeEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7generic14DumpMassChargeEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7generic14WholeMoleculesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7generic14WholeMoleculesEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7generic15DumpDerivativesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7generic15DumpDerivativesEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7generic15DumpProjectionsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7generic15DumpProjectionsEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7generic15RandomExchangesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7generic15RandomExchangesEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7generic20EffectiveEnergyDriftEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7generic20EffectiveEnergyDriftEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7generic4OnesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7generic4OnesEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7generic4ReadEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7generic4ReadEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7generic4TimeEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7generic4TimeEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7generic5DebugEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7generic5DebugEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7generic5FlushEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7generic5FlushEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7generic5PrintEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7generic5PrintEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7generic6PlumedEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7generic6PlumedEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7generic7DumpPDBEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7generic7DumpPDBEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7generic7IncludeEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7generic7IncludeEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7generic8ConstantEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7generic8ConstantEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7generic8PrintNDXEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7generic8PrintNDXEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7generic8UpdateIfEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7generic8UpdateIfEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7generic9DumpAtomsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7generic9DumpAtomsEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7generic9EndPlumedEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7generic9EndPlumedEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7generic9ResetCellEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7generic9ResetCellEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7mapping12AdaptivePathEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7mapping12AdaptivePathEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7mapping13GeometricPathEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7mapping13GeometricPathEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7mapping17PathDisplacementsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7mapping17PathDisplacementsEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7mapping21GeometricPathShortcutEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7mapping21GeometricPathShortcutEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7mapping22PathReparameterizationEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7mapping22PathReparameterizationEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7mapping7PCAVarsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7mapping7PCAVarsEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7refdist12DisplacementEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7refdist12DisplacementEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7refdist17EuclideanDistanceEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7refdist17EuclideanDistanceEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7refdist19MahalanobisDistanceEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7refdist19MahalanobisDistanceEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7refdist21MatrixProductDiagonalEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7refdist21MatrixProductDiagonalEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7refdist27NormalizedEuclideanDistanceEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7refdist27NormalizedEuclideanDistanceEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7refdist6KernelEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7refdist6KernelEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7symfunc10AtomicSMACEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7symfunc10AtomicSMACEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7symfunc11RadialTetraEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7symfunc11RadialTetraEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7symfunc12AngularTetraEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7symfunc12AngularTetraEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7symfunc12LocalAverageEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7symfunc12LocalAverageEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7symfunc17HexacticParameterEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7symfunc17HexacticParameterEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7symfunc18LocalCrystallinityEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7symfunc18LocalCrystallinityEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7symfunc19ThreeBodyGFunctionsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7symfunc19ThreeBodyGFunctionsEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7symfunc4SMACEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7symfunc4SMACEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7volumes12VolumeAroundEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7volumes12VolumeAroundEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7volumes12VolumeCavityEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7volumes12VolumeCavityEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7volumes14VolumeInSphereEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7volumes14VolumeInSphereEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7volumes14VolumeShortcutIXadL_ZNS1_11glob_aroundEEEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7volumes14VolumeShortcutIXadL_ZNS1_11glob_aroundEEEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7volumes14VolumeShortcutIXadL_ZNS1_11glob_cavityEEEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7volumes14VolumeShortcutIXadL_ZNS1_11glob_cavityEEEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7volumes14VolumeShortcutIXadL_ZNS1_11glob_sphereEEEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7volumes14VolumeShortcutIXadL_ZNS1_11glob_sphereEEEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7volumes14VolumeShortcutIXadL_ZNS1_13glob_contoursEEEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7volumes14VolumeShortcutIXadL_ZNS1_13glob_contoursEEEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7volumes14VolumeShortcutIXadL_ZNS1_13glob_cylinderEEEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7volumes14VolumeShortcutIXadL_ZNS1_13glob_cylinderEEEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7volumes14VolumeShortcutIXadL_ZNS1_14glob_tetraporeEEEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7volumes14VolumeShortcutIXadL_ZNS1_14glob_tetraporeEEEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7volumes15VolumeTetraporeEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7volumes15VolumeTetraporeEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7volumes16VolumeInCylinderEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7volumes16VolumeInCylinderEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7volumes16VolumeInEnvelopeEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7volumes16VolumeInEnvelopeEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7volumes7DensityEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7volumes7DensityEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8analysis10AccumulateEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8analysis10AccumulateEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8analysis10CreateMaskEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8analysis10CreateMaskEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8analysis11WhamWeightsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8analysis11WhamWeightsEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8analysis13CollectFramesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8analysis13CollectFramesEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8analysis13WhamHistogramEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8analysis13WhamHistogramEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8analysis14GatherReplicasEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8analysis14GatherReplicasEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8analysis21FarthestPointSamplingEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8analysis21FarthestPointSamplingEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8analysis4WhamEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8analysis4WhamEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8analysis7AverageEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8analysis7AverageEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8analysis7CollectEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8analysis7CollectEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8analysis9CommittorEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8analysis9CommittorEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8analysis9HistogramEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8analysis9HistogramEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8analysis9LogSumExpEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8analysis9LogSumExpEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8clusters13ClusterNatomsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8clusters13ClusterNatomsEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8clusters13DFSClusteringEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8clusters13DFSClusteringEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8clusters13OutputClusterEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8clusters13OutputClusterEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8clusters14ClusterWeightsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8clusters14ClusterWeightsEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8clusters15ClusterDiameterEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8clusters15ClusterDiameterEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8clusters17ClusterPropertiesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8clusters17ClusterPropertiesEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8clusters18ClusterWithSurfaceEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8clusters18ClusterWithSurfaceEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8clusters19ClusterDistributionEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8clusters19ClusterDistributionEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8clusters27ClusterDistributionShortcutEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8clusters27ClusterDistributionShortcutEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8function11FuncPathMSDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8function11FuncPathMSDEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8function12FuncSumHillsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8function12FuncSumHillsEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8function13LocalEnsembleEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8function13LocalEnsembleEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8function15FuncPathGeneralEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8function15FuncPathGeneralEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_4SortEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_4SortEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_6BesselEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_6BesselEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_7CombineEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_7CombineEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_7MomentsEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_7MomentsEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_9PiecewiseEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_9PiecewiseEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS_7refdist10DifferenceEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS_7refdist10DifferenceEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS_9gridtools20EvaluateGridFunctionEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS_9gridtools20EvaluateGridFunctionEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_4SortEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_4SortEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_6BesselEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_6BesselEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_7BetweenEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_7BetweenEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_7CombineEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_7CombineEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_7MomentsEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_7MomentsEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_8LessThanEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_8LessThanEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_8MoreThanEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_8MoreThanEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS_7refdist10DifferenceEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS_7refdist10DifferenceEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS_9gridtools20EvaluateGridFunctionEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS_9gridtools20EvaluateGridFunctionEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_4SortEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_4SortEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_6BesselEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_6BesselEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_7BetweenEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_7BetweenEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_7CombineEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_7CombineEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_7MomentsEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_7MomentsEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_8LessThanEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_8LessThanEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_8MoreThanEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_8MoreThanEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_9PiecewiseEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_9PiecewiseEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS_7refdist10DifferenceEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS_7refdist10DifferenceEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS_7symfunc17SphericalHarmonicEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS_7symfunc17SphericalHarmonicEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS_7symfunc19CylindricalHarmonicEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS_7symfunc19CylindricalHarmonicEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS_7symfunc7FccubicEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS_7symfunc7FccubicEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8function5StatsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8function5StatsEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8function7ProductEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8function7ProductEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8function7annfunc3ANNEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8function7annfunc3ANNEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8function7pytorch12PytorchModelEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8function7pytorch12PytorchModelEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8function8EnsembleEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8function8EnsembleEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8valtools11ConcatenateEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8valtools11ConcatenateEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8valtools14SelectWithMaskEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8valtools14SelectWithMaskEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8valtools16SelectComponentsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8valtools16SelectComponentsEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8valtools7FlattenEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8valtools7FlattenEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_9PbcActionEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_9PbcActionEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_9gridtools11PairEntropyEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_9gridtools11PairEntropyEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_9gridtools12ConvertToFESEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_9gridtools12ConvertToFESEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_9gridtools13PairEntropiesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_9gridtools13PairEntropiesEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_9gridtools15InterpolateGridEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_9gridtools15InterpolateGridEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_9gridtools15ReadGridInSetupEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_9gridtools15ReadGridInSetupEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_9gridtools18MultiColvarDensityEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_9gridtools18MultiColvarDensityEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_9gridtools22EvaluateFunctionOnGridEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_9gridtools22EvaluateFunctionOnGridEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_9gridtools3RDFEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_9gridtools3RDFEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_9gridtools8GradientEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_9gridtools8GradientEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_9gridtools9KLEntropyEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_9gridtools9KLEntropyEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_15ActionToPutDataEE6createERKNS_13ActionOptionsE6540
_ZN4PLMD18ActionRegistrationINS_5vatom14CenterShortcutEE6createERKNS_13ActionOptionsE7745
_ZN4PLMD18ActionRegistrationINS_5vatom6CenterEE6createERKNS_13ActionOptionsE9573
_ZN4PLMD18ActionRegistrationINS_4bias5WallsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10176
_ZN4PLMD18ActionRegistrationINS_4bias5WallsEED2Ev10176
_ZN4PLMD18ActionRegistrationINS_4isdb3RDCEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10176
_ZN4PLMD18ActionRegistrationINS_4isdb3RDCEED2Ev10176
_ZN4PLMD18ActionRegistrationINS_4isdb4SAXSEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10176
_ZN4PLMD18ActionRegistrationINS_4isdb4SAXSEED2Ev10176
_ZN4PLMD18ActionRegistrationINS_5vatom6CenterEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10176
_ZN4PLMD18ActionRegistrationINS_5vatom6CenterEED2Ev10176
_ZN4PLMD18ActionRegistrationINS_6adjmat16FunctionOfMatrixINS_8function6CustomEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10176
_ZN4PLMD18ActionRegistrationINS_6adjmat16FunctionOfMatrixINS_8function6CustomEEEED2Ev10176
_ZN4PLMD18ActionRegistrationINS_6adjmat17MatrixTimesMatrixEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10176
_ZN4PLMD18ActionRegistrationINS_6adjmat17MatrixTimesMatrixEED2Ev10176
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_16SelectMassChargeEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10176
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_16SelectMassChargeEEEED2Ev10176
_ZN4PLMD18ActionRegistrationINS_6colvar16GyrationShortcutEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10176
_ZN4PLMD18ActionRegistrationINS_6colvar16GyrationShortcutEED2Ev10176
_ZN4PLMD18ActionRegistrationINS_6colvar16SelectMassChargeEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10176
_ZN4PLMD18ActionRegistrationINS_6colvar16SelectMassChargeEED2Ev10176
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_16SelectMassChargeEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10176
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_16SelectMassChargeEEEED2Ev10176
_ZN4PLMD18ActionRegistrationINS_7mapping4PathEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10176
_ZN4PLMD18ActionRegistrationINS_7mapping4PathEED2Ev10176
_ZN4PLMD18ActionRegistrationINS_7symfunc19CoordinationNumbersEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10176
_ZN4PLMD18ActionRegistrationINS_7symfunc19CoordinationNumbersEED2Ev10176
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_3SumEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10176
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_3SumEEEED2Ev10176
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_6CustomEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10176
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_6CustomEEEED2Ev10176
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_7HighestEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10176
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_7HighestEEEED2Ev10176
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_3SumEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10176
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_3SumEEEED2Ev10176
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_6CustomEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10176
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_6CustomEEEED2Ev10176
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_7HighestEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10176
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_7HighestEEEED2Ev10176
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_3SumEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10176
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_3SumEEEED2Ev10176
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_6CustomEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10176
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_6CustomEEEED2Ev10176
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_7HighestEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10176
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_7HighestEEEED2Ev10176
_ZN4PLMD18ActionRegistrationINS_9gridtools14FunctionOfGridINS_8function3SumEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10176
_ZN4PLMD18ActionRegistrationINS_9gridtools14FunctionOfGridINS_8function3SumEEEED2Ev10176
_ZN4PLMD18ActionRegistrationINS_9gridtools14FunctionOfGridINS_8function6CustomEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10176
_ZN4PLMD18ActionRegistrationINS_9gridtools14FunctionOfGridINS_8function6CustomEEEED2Ev10176
_ZN4PLMD18ActionRegistrationINS_9gridtools15FindGridOptimumEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10176
_ZN4PLMD18ActionRegistrationINS_9gridtools15FindGridOptimumEED2Ev10176
_ZN4PLMD18ActionRegistrationINS_9gridtools3KDEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10176
_ZN4PLMD18ActionRegistrationINS_9gridtools3KDEEED2Ev10176
_ZN4PLMD18ActionRegistrationINS_9gridtools8DumpGridEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10176
_ZN4PLMD18ActionRegistrationINS_9gridtools8DumpGridEED2Ev10176
_ZN4PLMD18ActionRegistrationINS_11multicolvar6XAngleEEC2ESt17basic_string_viewIcSt11char_traitsIcEE15264
_ZN4PLMD18ActionRegistrationINS_11multicolvar6XAngleEED2Ev15264
_ZN4PLMD18ActionRegistrationINS_4pamm14HBPammShortcutEEC2ESt17basic_string_viewIcSt11char_traitsIcEE15264
_ZN4PLMD18ActionRegistrationINS_4pamm14HBPammShortcutEED2Ev15264
_ZN4PLMD18ActionRegistrationINS_8analysis17LandmarkSelectionEEC2ESt17basic_string_viewIcSt11char_traitsIcEE15264
_ZN4PLMD18ActionRegistrationINS_8analysis17LandmarkSelectionEED2Ev15264
_ZN4PLMD18ActionRegistrationINS_11multicolvar9DistancesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE20352
_ZN4PLMD18ActionRegistrationINS_11multicolvar9DistancesEED2Ev20352
_ZN4PLMD18ActionRegistrationINS_7symfunc10SteinhardtEEC2ESt17basic_string_viewIcSt11char_traitsIcEE20352
_ZN4PLMD18ActionRegistrationINS_7symfunc10SteinhardtEED2Ev20352
_ZN4PLMD18ActionRegistrationINS_7symfunc15LocalSteinhardtEEC2ESt17basic_string_viewIcSt11char_traitsIcEE20352
_ZN4PLMD18ActionRegistrationINS_7symfunc15LocalSteinhardtEED2Ev20352
_ZN4PLMD18ActionRegistrationINS_7symfunc24CoordShellVectorFunctionEEC2ESt17basic_string_viewIcSt11char_traitsIcEE25440
_ZN4PLMD18ActionRegistrationINS_7symfunc24CoordShellVectorFunctionEED2Ev25440
_ZN4PLMD18ActionRegistrationINS_11multicolvar10XYTorsionsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE30528
_ZN4PLMD18ActionRegistrationINS_11multicolvar10XYTorsionsEED2Ev30528
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionRegister.h.func.html b/coverage/core/ActionRegister.h.func.html new file mode 100644 index 000000000000..66e71956b018 --- /dev/null +++ b/coverage/core/ActionRegister.h.func.html @@ -0,0 +1,4681 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionRegister.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionRegister.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:77100.0 %
Date:2024-04-19 12:12:35Functions:1133115298.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18ActionRegistrationINS_11multicolvar10XYTorsionsEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_11multicolvar10XYTorsionsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE30528
_ZN4PLMD18ActionRegistrationINS_11multicolvar10XYTorsionsEED2Ev30528
_ZN4PLMD18ActionRegistrationINS_11multicolvar11CoordAnglesEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_11multicolvar11CoordAnglesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_11multicolvar11CoordAnglesEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_11multicolvar11MFilterLessEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_11multicolvar11MFilterLessEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_11multicolvar11MFilterLessEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_11multicolvar11MFilterMoreEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_11multicolvar11MFilterMoreEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_11multicolvar11MFilterMoreEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_11multicolvar13PlaneShortcutEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_11multicolvar13PlaneShortcutEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_11multicolvar13PlaneShortcutEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_11multicolvar15DumpMultiColvarEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_11multicolvar15DumpMultiColvarEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_11multicolvar15DumpMultiColvarEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_11multicolvar16InPlaneDistancesEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_11multicolvar16InPlaneDistancesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_11multicolvar16InPlaneDistancesEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_11multicolvar6AnglesEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_11multicolvar6AnglesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_11multicolvar6AnglesEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_11multicolvar6DihcorEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_11multicolvar6DihcorEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_11multicolvar6DihcorEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_11multicolvar6UWallsEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_11multicolvar6UWallsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_11multicolvar6UWallsEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_11multicolvar6XAngleEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_11multicolvar6XAngleEEC2ESt17basic_string_viewIcSt11char_traitsIcEE15264
_ZN4PLMD18ActionRegistrationINS_11multicolvar6XAngleEED2Ev15264
_ZN4PLMD18ActionRegistrationINS_11multicolvar8TorsionsEE6createERKNS_13ActionOptionsE6
_ZN4PLMD18ActionRegistrationINS_11multicolvar8TorsionsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_11multicolvar8TorsionsEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_11multicolvar9AlphaBetaEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_11multicolvar9AlphaBetaEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_11multicolvar9AlphaBetaEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_11multicolvar9DistancesEE6createERKNS_13ActionOptionsE56
_ZN4PLMD18ActionRegistrationINS_11multicolvar9DistancesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE20352
_ZN4PLMD18ActionRegistrationINS_11multicolvar9DistancesEED2Ev20352
_ZN4PLMD18ActionRegistrationINS_12crystdistrib10QuaternionEE6createERKNS_13ActionOptionsE5
_ZN4PLMD18ActionRegistrationINS_12crystdistrib10QuaternionEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_12crystdistrib10QuaternionEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_12crystdistrib12BopsShortcutEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_12crystdistrib12BopsShortcutEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_12crystdistrib12BopsShortcutEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_12crystdistrib12DopsShortcutEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_12crystdistrib12DopsShortcutEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_12crystdistrib12DopsShortcutEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_12crystdistrib12RopsShortcutEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_12crystdistrib12RopsShortcutEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_12crystdistrib12RopsShortcutEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_12crystdistrib23QuaternionProductMatrixEE6createERKNS_13ActionOptionsE6
_ZN4PLMD18ActionRegistrationINS_12crystdistrib23QuaternionProductMatrixEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_12crystdistrib23QuaternionProductMatrixEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_12crystdistrib27QuaternionBondProductMatrixEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_12crystdistrib27QuaternionBondProductMatrixEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_12crystdistrib27QuaternionBondProductMatrixEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_14GenericMolInfoEE6createERKNS_13ActionOptionsE91
_ZN4PLMD18ActionRegistrationINS_14GenericMolInfoEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_14GenericMolInfoEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_14membranefusion10memFusionPEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_14membranefusion10memFusionPEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_14membranefusion10memFusionPEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_14membranefusion20fusionPoreExpansionPEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_14membranefusion20fusionPoreExpansionPEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_14membranefusion20fusionPoreExpansionPEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_14membranefusion21fusionPoreNucleationPEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_14membranefusion21fusionPoreNucleationPEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_14membranefusion21fusionPoreNucleationPEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_15ActionToGetDataEE6createERKNS_13ActionOptionsE115
_ZN4PLMD18ActionRegistrationINS_15ActionToGetDataEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_15ActionToGetDataEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_15ActionToPutDataEE6createERKNS_13ActionOptionsE6540
_ZN4PLMD18ActionRegistrationINS_15ActionToPutDataEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_15ActionToPutDataEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_18secondarystructure12AntibetaRMSDEE6createERKNS_13ActionOptionsE11
_ZN4PLMD18ActionRegistrationINS_18secondarystructure12AntibetaRMSDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_18secondarystructure12AntibetaRMSDEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_18secondarystructure12ParabetaRMSDEE6createERKNS_13ActionOptionsE12
_ZN4PLMD18ActionRegistrationINS_18secondarystructure12ParabetaRMSDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_18secondarystructure12ParabetaRMSDEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_18secondarystructure22SecondaryStructureRMSDEE6createERKNS_13ActionOptionsE26
_ZN4PLMD18ActionRegistrationINS_18secondarystructure22SecondaryStructureRMSDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_18secondarystructure22SecondaryStructureRMSDEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_18secondarystructure9AlphaRMSDEE6createERKNS_13ActionOptionsE3
_ZN4PLMD18ActionRegistrationINS_18secondarystructure9AlphaRMSDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_18secondarystructure9AlphaRMSDEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_19DomainDecompositionEE6createERKNS_13ActionOptionsE1091
_ZN4PLMD18ActionRegistrationINS_19DomainDecompositionEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_19DomainDecompositionEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_3drr27DynamicReferenceRestrainingEE6createERKNS_13ActionOptionsE12
_ZN4PLMD18ActionRegistrationINS_3drr27DynamicReferenceRestrainingEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_3drr27DynamicReferenceRestrainingEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_3eds3EDSEE6createERKNS_13ActionOptionsE8
_ZN4PLMD18ActionRegistrationINS_3eds3EDSEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_3eds3EDSEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_3piv3PIVEE6createERKNS_13ActionOptionsE12
_ZN4PLMD18ActionRegistrationINS_3piv3PIVEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_3piv3PIVEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_3ves10BF_FourierEE6createERKNS_13ActionOptionsE95
_ZN4PLMD18ActionRegistrationINS_3ves10BF_FourierEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_3ves10BF_FourierEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_3ves10TD_UniformEE6createERKNS_13ActionOptionsE73
_ZN4PLMD18ActionRegistrationINS_3ves10TD_UniformEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_3ves10TD_UniformEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_3ves11BF_CombinedEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_3ves11BF_CombinedEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_3ves11BF_CombinedEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_3ves11BF_LegendreEE6createERKNS_13ActionOptionsE61
_ZN4PLMD18ActionRegistrationINS_3ves11BF_LegendreEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_3ves11BF_LegendreEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_3ves11BF_WaveletsEE6createERKNS_13ActionOptionsE47
_ZN4PLMD18ActionRegistrationINS_3ves11BF_WaveletsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_3ves11BF_WaveletsEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_3ves11TD_GaussianEE6createERKNS_13ActionOptionsE191
_ZN4PLMD18ActionRegistrationINS_3ves11TD_GaussianEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_3ves11TD_GaussianEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_3ves11TD_VonMisesEE6createERKNS_13ActionOptionsE9
_ZN4PLMD18ActionRegistrationINS_3ves11TD_VonMisesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_3ves11TD_VonMisesEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_3ves12BF_ChebyshevEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_3ves12BF_ChebyshevEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_3ves12BF_ChebyshevEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_3ves12BF_GaussiansEE6createERKNS_13ActionOptionsE3
_ZN4PLMD18ActionRegistrationINS_3ves12BF_GaussiansEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_3ves12BF_GaussiansEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_3ves13OutputFesBiasEE6createERKNS_13ActionOptionsE3
_ZN4PLMD18ActionRegistrationINS_3ves13OutputFesBiasEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_3ves13OutputFesBiasEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_3ves13TD_ChiSquaredEE6createERKNS_13ActionOptionsE9
_ZN4PLMD18ActionRegistrationINS_3ves13TD_ChiSquaredEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_3ves13TD_ChiSquaredEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_3ves14TD_ExponentialEE6createERKNS_13ActionOptionsE8
_ZN4PLMD18ActionRegistrationINS_3ves14TD_ExponentialEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_3ves14TD_ExponentialEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_3ves15TD_WellTemperedEE6createERKNS_13ActionOptionsE29
_ZN4PLMD18ActionRegistrationINS_3ves15TD_WellTemperedEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_3ves15TD_WellTemperedEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_3ves16BF_CubicBsplinesEE6createERKNS_13ActionOptionsE3
_ZN4PLMD18ActionRegistrationINS_3ves16BF_CubicBsplinesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_3ves16BF_CubicBsplinesEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_3ves17TD_MulticanonicalEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_3ves17TD_MulticanonicalEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_3ves17TD_MulticanonicalEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_3ves18VesLinearExpansionEE6createERKNS_13ActionOptionsE90
_ZN4PLMD18ActionRegistrationINS_3ves18VesLinearExpansionEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_3ves18VesLinearExpansionEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_3ves19Opt_BachAveragedSGDEE6createERKNS_13ActionOptionsE75
_ZN4PLMD18ActionRegistrationINS_3ves19Opt_BachAveragedSGDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_3ves19Opt_BachAveragedSGDEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_3ves19Opt_RobbinsMonroSGDEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_3ves19Opt_RobbinsMonroSGDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_3ves19Opt_RobbinsMonroSGDEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_3ves20OutputBasisFunctionsEE6createERKNS_13ActionOptionsE71
_ZN4PLMD18ActionRegistrationINS_3ves20OutputBasisFunctionsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_3ves20OutputBasisFunctionsEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_3ves20TD_GeneralizedNormalEE6createERKNS_13ActionOptionsE8
_ZN4PLMD18ActionRegistrationINS_3ves20TD_GeneralizedNormalEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_3ves20TD_GeneralizedNormalEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_3ves20TD_LinearCombinationEE6createERKNS_13ActionOptionsE12
_ZN4PLMD18ActionRegistrationINS_3ves20TD_LinearCombinationEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_3ves20TD_LinearCombinationEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_3ves21TD_ProductCombinationEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_3ves21TD_ProductCombinationEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_3ves21TD_ProductCombinationEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_3ves22TD_ProductDistributionEE6createERKNS_13ActionOptionsE15
_ZN4PLMD18ActionRegistrationINS_3ves22TD_ProductDistributionEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_3ves22TD_ProductDistributionEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_3ves24OutputTargetDistributionEE6createERKNS_13ActionOptionsE120
_ZN4PLMD18ActionRegistrationINS_3ves24OutputTargetDistributionEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_3ves24OutputTargetDistributionEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_3ves25TD_MultithermalMultibaricEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_3ves25TD_MultithermalMultibaricEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_3ves25TD_MultithermalMultibaricEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_3ves26TD_GeneralizedExtremeValueEE6createERKNS_13ActionOptionsE5
_ZN4PLMD18ActionRegistrationINS_3ves26TD_GeneralizedExtremeValueEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_3ves26TD_GeneralizedExtremeValueEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_3ves32TD_ExponentiallyModifiedGaussianEE6createERKNS_13ActionOptionsE6
_ZN4PLMD18ActionRegistrationINS_3ves32TD_ExponentiallyModifiedGaussianEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_3ves32TD_ExponentiallyModifiedGaussianEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_3ves6TD_ChiEE6createERKNS_13ActionOptionsE9
_ZN4PLMD18ActionRegistrationINS_3ves6TD_ChiEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_3ves6TD_ChiEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_3ves7BF_SineEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_3ves7BF_SineEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_3ves7BF_SineEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_3ves7TD_GridEE6createERKNS_13ActionOptionsE9
_ZN4PLMD18ActionRegistrationINS_3ves7TD_GridEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_3ves7TD_GridEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_3ves8Opt_AdamEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_3ves8Opt_AdamEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_3ves8Opt_AdamEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_3ves9BF_CosineEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_3ves9BF_CosineEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_3ves9BF_CosineEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_3ves9BF_CustomEE6createERKNS_13ActionOptionsE10
_ZN4PLMD18ActionRegistrationINS_3ves9BF_CustomEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_3ves9BF_CustomEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_3ves9BF_PowersEE6createERKNS_13ActionOptionsE16
_ZN4PLMD18ActionRegistrationINS_3ves9BF_PowersEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_3ves9BF_PowersEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_3ves9Opt_DummyEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_3ves9Opt_DummyEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_3ves9Opt_DummyEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_3ves9TD_CustomEE6createERKNS_13ActionOptionsE16
_ZN4PLMD18ActionRegistrationINS_3ves9TD_CustomEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_3ves9TD_CustomEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_3ves9VesDeltaFEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_3ves9VesDeltaFEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_3ves9VesDeltaFEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4bias12ReweightBiasEE6createERKNS_13ActionOptionsE3
_ZN4PLMD18ActionRegistrationINS_4bias12ReweightBiasEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4bias12ReweightBiasEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4bias13ReweightMetadEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_4bias13ReweightMetadEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4bias13ReweightMetadEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4bias15MovingRestraintEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_4bias15MovingRestraintEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4bias15MovingRestraintEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4bias17RestraintShortcutEE6createERKNS_13ActionOptionsE207
_ZN4PLMD18ActionRegistrationINS_4bias17RestraintShortcutEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4bias17RestraintShortcutEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4bias18ExtendedLagrangianEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_4bias18ExtendedLagrangianEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4bias18ExtendedLagrangianEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4bias27ReweightTemperaturePressureEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_4bias27ReweightTemperaturePressureEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4bias27ReweightTemperaturePressureEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4bias4ABMDEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_4bias4ABMDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4bias4ABMDEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4bias5MetaDEE6createERKNS_13ActionOptionsE157
_ZN4PLMD18ActionRegistrationINS_4bias5MetaDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4bias5MetaDEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4bias5WallsEE6createERKNS_13ActionOptionsE13
_ZN4PLMD18ActionRegistrationINS_4bias5WallsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10176
_ZN4PLMD18ActionRegistrationINS_4bias5WallsEED2Ev10176
_ZN4PLMD18ActionRegistrationINS_4bias6LWallsEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_4bias6LWallsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4bias6LWallsEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4bias6MaxEntEE6createERKNS_13ActionOptionsE50
_ZN4PLMD18ActionRegistrationINS_4bias6MaxEntEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4bias6MaxEntEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4bias6UWallsEE6createERKNS_13ActionOptionsE10
_ZN4PLMD18ActionRegistrationINS_4bias6UWallsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4bias6UWallsEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4bias7PBMetaDEE6createERKNS_13ActionOptionsE41
_ZN4PLMD18ActionRegistrationINS_4bias7PBMetaDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4bias7PBMetaDEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4bias8ExternalEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_4bias8ExternalEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4bias8ExternalEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4bias9BiasValueEE6createERKNS_13ActionOptionsE204
_ZN4PLMD18ActionRegistrationINS_4bias9BiasValueEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4bias9BiasValueEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4bias9RestraintEE6createERKNS_13ActionOptionsE203
_ZN4PLMD18ActionRegistrationINS_4bias9RestraintEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4bias9RestraintEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4isdb11CS2BackboneEE6createERKNS_13ActionOptionsE18
_ZN4PLMD18ActionRegistrationINS_4isdb11CS2BackboneEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4isdb11CS2BackboneEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4isdb13MetainferenceEE6createERKNS_13ActionOptionsE19
_ZN4PLMD18ActionRegistrationINS_4isdb13MetainferenceEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4isdb13MetainferenceEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4isdb14FretEfficiencyEE6createERKNS_13ActionOptionsE14
_ZN4PLMD18ActionRegistrationINS_4isdb14FretEfficiencyEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4isdb14FretEfficiencyEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4isdb3NOEEE6createERKNS_13ActionOptionsE11
_ZN4PLMD18ActionRegistrationINS_4isdb3NOEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4isdb3NOEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4isdb3PREEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_4isdb3PREEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4isdb3PREEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4isdb3RDCEE6createERKNS_13ActionOptionsE29
_ZN4PLMD18ActionRegistrationINS_4isdb3RDCEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10176
_ZN4PLMD18ActionRegistrationINS_4isdb3RDCEED2Ev10176
_ZN4PLMD18ActionRegistrationINS_4isdb4EMMIEE6createERKNS_13ActionOptionsE20
_ZN4PLMD18ActionRegistrationINS_4isdb4EMMIEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4isdb4EMMIEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4isdb4SAXSEE6createERKNS_13ActionOptionsE32
_ZN4PLMD18ActionRegistrationINS_4isdb4SAXSEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10176
_ZN4PLMD18ActionRegistrationINS_4isdb4SAXSEED2Ev10176
_ZN4PLMD18ActionRegistrationINS_4isdb6SelectEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_4isdb6SelectEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4isdb6SelectEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4isdb6ShadowEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_4isdb6ShadowEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4isdb6ShadowEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4isdb7CaliberEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_4isdb7CaliberEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4isdb7CaliberEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4isdb7EMMIVOXEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_4isdb7EMMIVOXEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4isdb7EMMIVOXEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4isdb7RescaleEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_4isdb7RescaleEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4isdb7RescaleEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4isdb8SelectorEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_4isdb8SelectorEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4isdb8SelectorEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4isdb9JCouplingEE6createERKNS_13ActionOptionsE6
_ZN4PLMD18ActionRegistrationINS_4isdb9JCouplingEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4isdb9JCouplingEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4maze10Steered_MDEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_4maze10Steered_MDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4maze10Steered_MDEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4maze11Random_WalkEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_4maze11Random_WalkEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4maze11Random_WalkEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4maze13OptimizerBiasEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_4maze13OptimizerBiasEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4maze13OptimizerBiasEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4maze19Simulated_AnnealingEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_4maze19Simulated_AnnealingEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4maze19Simulated_AnnealingEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4maze22Random_Acceleration_MDEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_4maze22Random_Acceleration_MDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4maze22Random_Acceleration_MDEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4maze4LossEE6createERKNS_13ActionOptionsE8
_ZN4PLMD18ActionRegistrationINS_4maze4LossEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4maze4LossEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4maze7MemeticEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_4maze7MemeticEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4maze7MemeticEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4opes12OPESexpandedEE6createERKNS_13ActionOptionsE30
_ZN4PLMD18ActionRegistrationINS_4opes12OPESexpandedEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4opes12OPESexpandedEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4opes15ECVmultiThermalEE6createERKNS_13ActionOptionsE11
_ZN4PLMD18ActionRegistrationINS_4opes15ECVmultiThermalEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4opes15ECVmultiThermalEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4opes16ECVumbrellasFileEE6createERKNS_13ActionOptionsE3
_ZN4PLMD18ActionRegistrationINS_4opes16ECVumbrellasFileEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4opes16ECVumbrellasFileEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4opes16ECVumbrellasLineEE6createERKNS_13ActionOptionsE8
_ZN4PLMD18ActionRegistrationINS_4opes16ECVumbrellasLineEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4opes16ECVumbrellasLineEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4opes20ECVmultiThermalBaricEE6createERKNS_13ActionOptionsE9
_ZN4PLMD18ActionRegistrationINS_4opes20ECVmultiThermalBaricEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4opes20ECVmultiThermalBaricEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4opes9ECVcustomEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_4opes9ECVcustomEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4opes9ECVcustomEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4opes9ECVlinearEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_4opes9ECVlinearEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4opes9ECVlinearEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4opes9OPESmetadINS1_11convergenceEEEE6createERKNS_13ActionOptionsE14
_ZN4PLMD18ActionRegistrationINS_4opes9OPESmetadINS1_11convergenceEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4opes9OPESmetadINS1_11convergenceEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4opes9OPESmetadINS1_11explorationEEEE6createERKNS_13ActionOptionsE7
_ZN4PLMD18ActionRegistrationINS_4opes9OPESmetadINS1_11explorationEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4opes9OPESmetadINS1_11explorationEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4pamm12HBPammMatrixEE6createERKNS_13ActionOptionsE6
_ZN4PLMD18ActionRegistrationINS_4pamm12HBPammMatrixEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4pamm12HBPammMatrixEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4pamm14HBPammShortcutEE6createERKNS_13ActionOptionsE6
_ZN4PLMD18ActionRegistrationINS_4pamm14HBPammShortcutEEC2ESt17basic_string_viewIcSt11char_traitsIcEE15264
_ZN4PLMD18ActionRegistrationINS_4pamm14HBPammShortcutEED2Ev15264
_ZN4PLMD18ActionRegistrationINS_4pamm4PAMMEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_4pamm4PAMMEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4pamm4PAMMEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4s2cm14S2ContactModelEE6createERKNS_13ActionOptionsE24
_ZN4PLMD18ActionRegistrationINS_4s2cm14S2ContactModelEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4s2cm14S2ContactModelEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4sasa10SASA_HASELEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_4sasa10SASA_HASELEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4sasa10SASA_HASELEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_4sasa9SASA_LCPOEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_4sasa9SASA_LCPOEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_4sasa9SASA_LCPOEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_5GroupEE6createERKNS_13ActionOptionsE321
_ZN4PLMD18ActionRegistrationINS_5GroupEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_5GroupEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_5fisst5FISSTEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_5fisst5FISSTEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_5fisst5FISSTEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_5setup4LoadEE6createERKNS_13ActionOptionsE42
_ZN4PLMD18ActionRegistrationINS_5setup4LoadEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_5setup4LoadEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_5setup5UnitsEE6createERKNS_13ActionOptionsE28
_ZN4PLMD18ActionRegistrationINS_5setup5UnitsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_5setup5UnitsEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_5setup7RestartEE6createERKNS_13ActionOptionsE56
_ZN4PLMD18ActionRegistrationINS_5setup7RestartEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_5setup7RestartEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_5vatom11ArgsToVatomEE6createERKNS_13ActionOptionsE9
_ZN4PLMD18ActionRegistrationINS_5vatom11ArgsToVatomEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_5vatom11ArgsToVatomEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_5vatom14CenterShortcutEE6createERKNS_13ActionOptionsE7745
_ZN4PLMD18ActionRegistrationINS_5vatom14CenterShortcutEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_5vatom14CenterShortcutEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_5vatom5GhostEE6createERKNS_13ActionOptionsE703
_ZN4PLMD18ActionRegistrationINS_5vatom5GhostEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_5vatom5GhostEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_5vatom6CenterEE6createERKNS_13ActionOptionsE9573
_ZN4PLMD18ActionRegistrationINS_5vatom6CenterEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10176
_ZN4PLMD18ActionRegistrationINS_5vatom6CenterEED2Ev10176
_ZN4PLMD18ActionRegistrationINS_5vatom9FixedAtomEE6createERKNS_13ActionOptionsE35
_ZN4PLMD18ActionRegistrationINS_5vatom9FixedAtomEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_5vatom9FixedAtomEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6adjmat11DeterminantEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_6adjmat11DeterminantEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6adjmat11DeterminantEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6adjmat11HbondMatrixEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_6adjmat11HbondMatrixEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6adjmat11HbondMatrixEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6adjmat12BridgeMatrixEE6createERKNS_13ActionOptionsE8
_ZN4PLMD18ActionRegistrationINS_6adjmat12BridgeMatrixEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6adjmat12BridgeMatrixEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6adjmat12InvertMatrixEE6createERKNS_13ActionOptionsE9
_ZN4PLMD18ActionRegistrationINS_6adjmat12InvertMatrixEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6adjmat12InvertMatrixEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6adjmat12OuterProductEE6createERKNS_13ActionOptionsE77
_ZN4PLMD18ActionRegistrationINS_6adjmat12OuterProductEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6adjmat12OuterProductEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6adjmat13ContactMatrixEE6createERKNS_13ActionOptionsE208
_ZN4PLMD18ActionRegistrationINS_6adjmat13ContactMatrixEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6adjmat13ContactMatrixEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6adjmat14DistanceMatrixEE6createERKNS_13ActionOptionsE92
_ZN4PLMD18ActionRegistrationINS_6adjmat14DistanceMatrixEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6adjmat14DistanceMatrixEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6adjmat14TopologyMatrixEE6createERKNS_13ActionOptionsE8
_ZN4PLMD18ActionRegistrationINS_6adjmat14TopologyMatrixEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6adjmat14TopologyMatrixEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6adjmat14TorsionsMatrixEE6createERKNS_13ActionOptionsE7
_ZN4PLMD18ActionRegistrationINS_6adjmat14TorsionsMatrixEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6adjmat14TorsionsMatrixEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6adjmat15TransposeMatrixEE6createERKNS_13ActionOptionsE162
_ZN4PLMD18ActionRegistrationINS_6adjmat15TransposeMatrixEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6adjmat15TransposeMatrixEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6adjmat16CovarianceMatrixEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_6adjmat16CovarianceMatrixEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6adjmat16CovarianceMatrixEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6adjmat16FunctionOfMatrixINS_7symfunc17SphericalHarmonicEEEE6createERKNS_13ActionOptionsE41
_ZN4PLMD18ActionRegistrationINS_6adjmat16FunctionOfMatrixINS_7symfunc17SphericalHarmonicEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6adjmat16FunctionOfMatrixINS_7symfunc17SphericalHarmonicEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6adjmat16FunctionOfMatrixINS_7symfunc19CylindricalHarmonicEEEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_6adjmat16FunctionOfMatrixINS_7symfunc19CylindricalHarmonicEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6adjmat16FunctionOfMatrixINS_7symfunc19CylindricalHarmonicEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6adjmat16FunctionOfMatrixINS_7symfunc7FccubicEEEE6createERKNS_13ActionOptionsE5
_ZN4PLMD18ActionRegistrationINS_6adjmat16FunctionOfMatrixINS_7symfunc7FccubicEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6adjmat16FunctionOfMatrixINS_7symfunc7FccubicEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6adjmat16FunctionOfMatrixINS_8function3SumEEEE6createERKNS_13ActionOptionsE41
_ZN4PLMD18ActionRegistrationINS_6adjmat16FunctionOfMatrixINS_8function3SumEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6adjmat16FunctionOfMatrixINS_8function3SumEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6adjmat16FunctionOfMatrixINS_8function6CustomEEEE6createERKNS_13ActionOptionsE369
_ZN4PLMD18ActionRegistrationINS_6adjmat16FunctionOfMatrixINS_8function6CustomEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10176
_ZN4PLMD18ActionRegistrationINS_6adjmat16FunctionOfMatrixINS_8function6CustomEEEED2Ev10176
_ZN4PLMD18ActionRegistrationINS_6adjmat16FunctionOfMatrixINS_8function7BetweenEEEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_6adjmat16FunctionOfMatrixINS_8function7BetweenEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6adjmat16FunctionOfMatrixINS_8function7BetweenEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6adjmat16FunctionOfMatrixINS_8function7CombineEEEE6createERKNS_13ActionOptionsE26
_ZN4PLMD18ActionRegistrationINS_6adjmat16FunctionOfMatrixINS_8function7CombineEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6adjmat16FunctionOfMatrixINS_8function7CombineEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6adjmat16FunctionOfMatrixINS_8function8LessThanEEEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_6adjmat16FunctionOfMatrixINS_8function8LessThanEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6adjmat16FunctionOfMatrixINS_8function8LessThanEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6adjmat16FunctionOfMatrixINS_8function8MoreThanEEEE6createERKNS_13ActionOptionsE6
_ZN4PLMD18ActionRegistrationINS_6adjmat16FunctionOfMatrixINS_8function8MoreThanEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6adjmat16FunctionOfMatrixINS_8function8MoreThanEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6adjmat17DiagonalizeMatrixEE6createERKNS_13ActionOptionsE22
_ZN4PLMD18ActionRegistrationINS_6adjmat17DiagonalizeMatrixEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6adjmat17DiagonalizeMatrixEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6adjmat17MatrixTimesMatrixEE6createERKNS_13ActionOptionsE57
_ZN4PLMD18ActionRegistrationINS_6adjmat17MatrixTimesMatrixEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10176
_ZN4PLMD18ActionRegistrationINS_6adjmat17MatrixTimesMatrixEED2Ev10176
_ZN4PLMD18ActionRegistrationINS_6adjmat17MatrixTimesVectorEE6createERKNS_13ActionOptionsE348
_ZN4PLMD18ActionRegistrationINS_6adjmat17MatrixTimesVectorEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6adjmat17MatrixTimesVectorEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6adjmat21ContactMatrixShortcutEE6createERKNS_13ActionOptionsE206
_ZN4PLMD18ActionRegistrationINS_6adjmat21ContactMatrixShortcutEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6adjmat21ContactMatrixShortcutEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6adjmat6BridgeEE6createERKNS_13ActionOptionsE8
_ZN4PLMD18ActionRegistrationINS_6adjmat6BridgeEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6adjmat6BridgeEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6adjmat6SprintEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_6adjmat6SprintEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6adjmat6SprintEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6adjmat6VStackEE6createERKNS_13ActionOptionsE134
_ZN4PLMD18ActionRegistrationINS_6adjmat6VStackEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6adjmat6VStackEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6adjmat7VoronoiEE6createERKNS_13ActionOptionsE6
_ZN4PLMD18ActionRegistrationINS_6adjmat7VoronoiEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6adjmat7VoronoiEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6adjmat9NeighborsEE6createERKNS_13ActionOptionsE3
_ZN4PLMD18ActionRegistrationINS_6adjmat9NeighborsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6adjmat9NeighborsEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar10ColvarFakeEE6createERKNS_13ActionOptionsE17
_ZN4PLMD18ActionRegistrationINS_6colvar10ColvarFakeEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar10ColvarFakeEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar10ContactMapEE6createERKNS_13ActionOptionsE8
_ZN4PLMD18ActionRegistrationINS_6colvar10ContactMapEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar10ContactMapEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar10RMSDVectorEE6createERKNS_13ActionOptionsE49
_ZN4PLMD18ActionRegistrationINS_6colvar10RMSDVectorEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar10RMSDVectorEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar11PropertyMapEE6createERKNS_13ActionOptionsE11
_ZN4PLMD18ActionRegistrationINS_6colvar11PropertyMapEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar11PropertyMapEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar12CoordinationEE6createERKNS_13ActionOptionsE219
_ZN4PLMD18ActionRegistrationINS_6colvar12CoordinationEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar12CoordinationEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar12RMSDShortcutEE6createERKNS_13ActionOptionsE104
_ZN4PLMD18ActionRegistrationINS_6colvar12RMSDShortcutEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar12RMSDShortcutEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_16SelectMassChargeEEEE6createERKNS_13ActionOptionsE18
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_16SelectMassChargeEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10176
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_16SelectMassChargeEEEED2Ev10176
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_19DihedralCorrelationEEEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_19DihedralCorrelationEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_19DihedralCorrelationEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_5AngleEEEE6createERKNS_13ActionOptionsE26
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_5AngleEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_5AngleEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_5PlaneEEEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_5PlaneEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_5PlaneEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_6DipoleEEEE6createERKNS_13ActionOptionsE61
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_6DipoleEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_6DipoleEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_7TorsionEEEE6createERKNS_13ActionOptionsE679
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_7TorsionEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_7TorsionEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_8DistanceEEEE6createERKNS_13ActionOptionsE699
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_8DistanceEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_8DistanceEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_8PositionEEEE6createERKNS_13ActionOptionsE134
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_8PositionEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS1_8PositionEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS_12crystdistrib10QuaternionEEEE6createERKNS_13ActionOptionsE17
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS_12crystdistrib10QuaternionEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar14ColvarShortcutINS_12crystdistrib10QuaternionEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar16GyrationShortcutEE6createERKNS_13ActionOptionsE37
_ZN4PLMD18ActionRegistrationINS_6colvar16GyrationShortcutEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10176
_ZN4PLMD18ActionRegistrationINS_6colvar16GyrationShortcutEED2Ev10176
_ZN4PLMD18ActionRegistrationINS_6colvar16ProjectionOnAxisEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_6colvar16ProjectionOnAxisEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar16ProjectionOnAxisEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar16SelectMassChargeEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_6colvar16SelectMassChargeEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10176
_ZN4PLMD18ActionRegistrationINS_6colvar16SelectMassChargeEED2Ev10176
_ZN4PLMD18ActionRegistrationINS_6colvar19DihedralCorrelationEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_6colvar19DihedralCorrelationEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar19DihedralCorrelationEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_16SelectMassChargeEEEE6createERKNS_13ActionOptionsE18
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_16SelectMassChargeEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10176
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_16SelectMassChargeEEEED2Ev10176
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_19DihedralCorrelationEEEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_19DihedralCorrelationEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_19DihedralCorrelationEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_5AngleEEEE6createERKNS_13ActionOptionsE3
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_5AngleEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_5AngleEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_5PlaneEEEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_5PlaneEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_5PlaneEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_6DipoleEEEE6createERKNS_13ActionOptionsE3
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_6DipoleEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_6DipoleEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_7TorsionEEEE6createERKNS_13ActionOptionsE14
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_7TorsionEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_7TorsionEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_8DistanceEEEE6createERKNS_13ActionOptionsE104
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_8DistanceEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_8DistanceEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_8PositionEEEE6createERKNS_13ActionOptionsE41
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_8PositionEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS1_8PositionEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS_12crystdistrib10QuaternionEEEE6createERKNS_13ActionOptionsE12
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS_12crystdistrib10QuaternionEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar19MultiColvarTemplateINS_12crystdistrib10QuaternionEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar4CellEE6createERKNS_13ActionOptionsE9
_ZN4PLMD18ActionRegistrationINS_6colvar4CellEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar4CellEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar4RMSDEE6createERKNS_13ActionOptionsE81
_ZN4PLMD18ActionRegistrationINS_6colvar4RMSDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar4RMSDEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar5AngleEE6createERKNS_13ActionOptionsE23
_ZN4PLMD18ActionRegistrationINS_6colvar5AngleEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar5AngleEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar5DRMSDEE6createERKNS_13ActionOptionsE13
_ZN4PLMD18ActionRegistrationINS_6colvar5DRMSDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar5DRMSDEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar5DimerEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_6colvar5DimerEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar5DimerEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar5ERMSDEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_6colvar5ERMSDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar5ERMSDEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar5PlaneEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_6colvar5PlaneEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar5PlaneEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar6DipoleEE6createERKNS_13ActionOptionsE58
_ZN4PLMD18ActionRegistrationINS_6colvar6DipoleEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar6DipoleEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar6EnergyEE6createERKNS_13ActionOptionsE40
_ZN4PLMD18ActionRegistrationINS_6colvar6EnergyEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar6EnergyEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar6GHBFIXEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_6colvar6GHBFIXEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar6GHBFIXEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar6VolumeEE6createERKNS_13ActionOptionsE15
_ZN4PLMD18ActionRegistrationINS_6colvar6VolumeEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar6VolumeEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar7EEFSolvEE6createERKNS_13ActionOptionsE5
_ZN4PLMD18ActionRegistrationINS_6colvar7EEFSolvEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar7EEFSolvEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar7ExtraCVEE6createERKNS_13ActionOptionsE3
_ZN4PLMD18ActionRegistrationINS_6colvar7ExtraCVEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar7ExtraCVEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar7PCARMSDEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_6colvar7PCARMSDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar7PCARMSDEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar7PathMSDEE6createERKNS_13ActionOptionsE14
_ZN4PLMD18ActionRegistrationINS_6colvar7PathMSDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar7PathMSDEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar7TorsionEE6createERKNS_13ActionOptionsE665
_ZN4PLMD18ActionRegistrationINS_6colvar7TorsionEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar7TorsionEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar8DHEnergyEE6createERKNS_13ActionOptionsE8
_ZN4PLMD18ActionRegistrationINS_6colvar8DHEnergyEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar8DHEnergyEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar8DistanceEE6createERKNS_13ActionOptionsE595
_ZN4PLMD18ActionRegistrationINS_6colvar8DistanceEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar8DistanceEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar8GyrationEE6createERKNS_13ActionOptionsE33
_ZN4PLMD18ActionRegistrationINS_6colvar8GyrationEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar8GyrationEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar8PositionEE6createERKNS_13ActionOptionsE93
_ZN4PLMD18ActionRegistrationINS_6colvar8PositionEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar8PositionEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar8TemplateEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_6colvar8TemplateEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar8TemplateEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar9MultiRMSDEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_6colvar9MultiRMSDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar9MultiRMSDEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6colvar9PuckeringEE6createERKNS_13ActionOptionsE54
_ZN4PLMD18ActionRegistrationINS_6colvar9PuckeringEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6colvar9PuckeringEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6dimred13ArrangePointsEE6createERKNS_13ActionOptionsE5
_ZN4PLMD18ActionRegistrationINS_6dimred13ArrangePointsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6dimred13ArrangePointsEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6dimred13ProjectPointsEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_6dimred13ProjectPointsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6dimred13ProjectPointsEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6dimred19SketchMapProjectionEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_6dimred19SketchMapProjectionEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6dimred19SketchMapProjectionEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6dimred32ClassicalMultiDimensionalScalingEE6createERKNS_13ActionOptionsE7
_ZN4PLMD18ActionRegistrationINS_6dimred32ClassicalMultiDimensionalScalingEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6dimred32ClassicalMultiDimensionalScalingEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6dimred3PCAEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_6dimred3PCAEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6dimred3PCAEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6dimred9SketchMapEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_6dimred9SketchMapEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6dimred9SketchMapEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6envsim21EnvironmentSimilarityEE6createERKNS_13ActionOptionsE10
_ZN4PLMD18ActionRegistrationINS_6envsim21EnvironmentSimilarityEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6envsim21EnvironmentSimilarityEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6funnel6FunnelEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_6funnel6FunnelEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6funnel6FunnelEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6funnel9FUNNEL_PSEE6createERKNS_13ActionOptionsE5
_ZN4PLMD18ActionRegistrationINS_6funnel9FUNNEL_PSEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6funnel9FUNNEL_PSEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_6logmfd6LogMFDEE6createERKNS_13ActionOptionsE3
_ZN4PLMD18ActionRegistrationINS_6logmfd6LogMFDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_6logmfd6LogMFDEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7contour11DumpContourEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_7contour11DumpContourEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7contour11DumpContourEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7contour11FindContourEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_7contour11FindContourEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7contour11FindContourEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7contour18FindContourSurfaceEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_7contour18FindContourSurfaceEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7contour18FindContourSurfaceEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7contour19DistanceFromContourEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_7contour19DistanceFromContourEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7contour19DistanceFromContourEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7contour20FindSphericalContourEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_7contour20FindSphericalContourEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7contour20FindSphericalContourEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7contour28DistanceFromSphericalContourEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_7contour28DistanceFromSphericalContourEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7contour28DistanceFromSphericalContourEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7fourier16FourierTransformEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_7fourier16FourierTransformEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7fourier16FourierTransformEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7generic10DumpForcesEE6createERKNS_13ActionOptionsE28
_ZN4PLMD18ActionRegistrationINS_7generic10DumpForcesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7generic10DumpForcesEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7generic10DumpVectorEE6createERKNS_13ActionOptionsE36
_ZN4PLMD18ActionRegistrationINS_7generic10DumpVectorEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7generic10DumpVectorEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7generic10WrapAroundEE6createERKNS_13ActionOptionsE6
_ZN4PLMD18ActionRegistrationINS_7generic10WrapAroundEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7generic10WrapAroundEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7generic12PDB2ConstantEE6createERKNS_13ActionOptionsE115
_ZN4PLMD18ActionRegistrationINS_7generic12PDB2ConstantEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7generic12PDB2ConstantEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7generic13FitToTemplateEE6createERKNS_13ActionOptionsE9
_ZN4PLMD18ActionRegistrationINS_7generic13FitToTemplateEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7generic13FitToTemplateEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7generic14DumpMassChargeEE6createERKNS_13ActionOptionsE12
_ZN4PLMD18ActionRegistrationINS_7generic14DumpMassChargeEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7generic14DumpMassChargeEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7generic14WholeMoleculesEE6createERKNS_13ActionOptionsE57
_ZN4PLMD18ActionRegistrationINS_7generic14WholeMoleculesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7generic14WholeMoleculesEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7generic15DumpDerivativesEE6createERKNS_13ActionOptionsE242
_ZN4PLMD18ActionRegistrationINS_7generic15DumpDerivativesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7generic15DumpDerivativesEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7generic15DumpProjectionsEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_7generic15DumpProjectionsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7generic15DumpProjectionsEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7generic15RandomExchangesEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_7generic15RandomExchangesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7generic15RandomExchangesEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7generic20EffectiveEnergyDriftEE6createERKNS_13ActionOptionsE9
_ZN4PLMD18ActionRegistrationINS_7generic20EffectiveEnergyDriftEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7generic20EffectiveEnergyDriftEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7generic4OnesEE6createERKNS_13ActionOptionsE252
_ZN4PLMD18ActionRegistrationINS_7generic4OnesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7generic4OnesEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7generic4ReadEE6createERKNS_13ActionOptionsE89
_ZN4PLMD18ActionRegistrationINS_7generic4ReadEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7generic4ReadEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7generic4TimeEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_7generic4TimeEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7generic4TimeEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7generic5DebugEE6createERKNS_13ActionOptionsE6
_ZN4PLMD18ActionRegistrationINS_7generic5DebugEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7generic5DebugEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7generic5FlushEE6createERKNS_13ActionOptionsE17
_ZN4PLMD18ActionRegistrationINS_7generic5FlushEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7generic5FlushEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7generic5PrintEE6createERKNS_13ActionOptionsE1019
_ZN4PLMD18ActionRegistrationINS_7generic5PrintEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7generic5PrintEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7generic6PlumedEE6createERKNS_13ActionOptionsE12
_ZN4PLMD18ActionRegistrationINS_7generic6PlumedEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7generic6PlumedEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7generic7DumpPDBEE6createERKNS_13ActionOptionsE15
_ZN4PLMD18ActionRegistrationINS_7generic7DumpPDBEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7generic7DumpPDBEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7generic7IncludeEE6createERKNS_13ActionOptionsE23
_ZN4PLMD18ActionRegistrationINS_7generic7IncludeEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7generic7IncludeEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7generic8ConstantEE6createERKNS_13ActionOptionsE842
_ZN4PLMD18ActionRegistrationINS_7generic8ConstantEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7generic8ConstantEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7generic8PrintNDXEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_7generic8PrintNDXEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7generic8PrintNDXEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7generic8UpdateIfEE6createERKNS_13ActionOptionsE7
_ZN4PLMD18ActionRegistrationINS_7generic8UpdateIfEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7generic8UpdateIfEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7generic9DumpAtomsEE6createERKNS_13ActionOptionsE205
_ZN4PLMD18ActionRegistrationINS_7generic9DumpAtomsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7generic9DumpAtomsEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7generic9EndPlumedEE6createERKNS_13ActionOptionsE281
_ZN4PLMD18ActionRegistrationINS_7generic9EndPlumedEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7generic9EndPlumedEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7generic9ResetCellEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_7generic9ResetCellEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7generic9ResetCellEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7mapping12AdaptivePathEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_7mapping12AdaptivePathEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7mapping12AdaptivePathEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7mapping13GeometricPathEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_7mapping13GeometricPathEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7mapping13GeometricPathEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7mapping17PathDisplacementsEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_7mapping17PathDisplacementsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7mapping17PathDisplacementsEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7mapping21GeometricPathShortcutEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_7mapping21GeometricPathShortcutEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7mapping21GeometricPathShortcutEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7mapping22PathReparameterizationEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_7mapping22PathReparameterizationEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7mapping22PathReparameterizationEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7mapping4PathEE6createERKNS_13ActionOptionsE10
_ZN4PLMD18ActionRegistrationINS_7mapping4PathEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10176
_ZN4PLMD18ActionRegistrationINS_7mapping4PathEED2Ev10176
_ZN4PLMD18ActionRegistrationINS_7mapping7PCAVarsEE6createERKNS_13ActionOptionsE5
_ZN4PLMD18ActionRegistrationINS_7mapping7PCAVarsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7mapping7PCAVarsEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7refdist12DisplacementEE6createERKNS_13ActionOptionsE52
_ZN4PLMD18ActionRegistrationINS_7refdist12DisplacementEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7refdist12DisplacementEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7refdist17EuclideanDistanceEE6createERKNS_13ActionOptionsE28
_ZN4PLMD18ActionRegistrationINS_7refdist17EuclideanDistanceEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7refdist17EuclideanDistanceEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7refdist19MahalanobisDistanceEE6createERKNS_13ActionOptionsE12
_ZN4PLMD18ActionRegistrationINS_7refdist19MahalanobisDistanceEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7refdist19MahalanobisDistanceEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7refdist21MatrixProductDiagonalEE6createERKNS_13ActionOptionsE55
_ZN4PLMD18ActionRegistrationINS_7refdist21MatrixProductDiagonalEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7refdist21MatrixProductDiagonalEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7refdist27NormalizedEuclideanDistanceEE6createERKNS_13ActionOptionsE8
_ZN4PLMD18ActionRegistrationINS_7refdist27NormalizedEuclideanDistanceEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7refdist27NormalizedEuclideanDistanceEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7refdist6KernelEE6createERKNS_13ActionOptionsE9
_ZN4PLMD18ActionRegistrationINS_7refdist6KernelEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7refdist6KernelEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7symfunc10AtomicSMACEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_7symfunc10AtomicSMACEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7symfunc10AtomicSMACEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7symfunc10SteinhardtEE6createERKNS_13ActionOptionsE41
_ZN4PLMD18ActionRegistrationINS_7symfunc10SteinhardtEEC2ESt17basic_string_viewIcSt11char_traitsIcEE20352
_ZN4PLMD18ActionRegistrationINS_7symfunc10SteinhardtEED2Ev20352
_ZN4PLMD18ActionRegistrationINS_7symfunc11RadialTetraEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_7symfunc11RadialTetraEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7symfunc11RadialTetraEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7symfunc12AngularTetraEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_7symfunc12AngularTetraEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7symfunc12AngularTetraEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7symfunc12LocalAverageEE6createERKNS_13ActionOptionsE10
_ZN4PLMD18ActionRegistrationINS_7symfunc12LocalAverageEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7symfunc12LocalAverageEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7symfunc15LocalSteinhardtEE6createERKNS_13ActionOptionsE7
_ZN4PLMD18ActionRegistrationINS_7symfunc15LocalSteinhardtEEC2ESt17basic_string_viewIcSt11char_traitsIcEE20352
_ZN4PLMD18ActionRegistrationINS_7symfunc15LocalSteinhardtEED2Ev20352
_ZN4PLMD18ActionRegistrationINS_7symfunc17HexacticParameterEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_7symfunc17HexacticParameterEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7symfunc17HexacticParameterEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7symfunc18LocalCrystallinityEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_7symfunc18LocalCrystallinityEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7symfunc18LocalCrystallinityEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7symfunc19CoordinationNumbersEE6createERKNS_13ActionOptionsE45
_ZN4PLMD18ActionRegistrationINS_7symfunc19CoordinationNumbersEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10176
_ZN4PLMD18ActionRegistrationINS_7symfunc19CoordinationNumbersEED2Ev10176
_ZN4PLMD18ActionRegistrationINS_7symfunc19ThreeBodyGFunctionsEE6createERKNS_13ActionOptionsE5
_ZN4PLMD18ActionRegistrationINS_7symfunc19ThreeBodyGFunctionsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7symfunc19ThreeBodyGFunctionsEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7symfunc24CoordShellVectorFunctionEE6createERKNS_13ActionOptionsE8
_ZN4PLMD18ActionRegistrationINS_7symfunc24CoordShellVectorFunctionEEC2ESt17basic_string_viewIcSt11char_traitsIcEE25440
_ZN4PLMD18ActionRegistrationINS_7symfunc24CoordShellVectorFunctionEED2Ev25440
_ZN4PLMD18ActionRegistrationINS_7symfunc4SMACEE6createERKNS_13ActionOptionsE5
_ZN4PLMD18ActionRegistrationINS_7symfunc4SMACEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7symfunc4SMACEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7volumes12VolumeAroundEE6createERKNS_13ActionOptionsE46
_ZN4PLMD18ActionRegistrationINS_7volumes12VolumeAroundEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7volumes12VolumeAroundEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7volumes12VolumeCavityEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_7volumes12VolumeCavityEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7volumes12VolumeCavityEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7volumes14VolumeInSphereEE6createERKNS_13ActionOptionsE10
_ZN4PLMD18ActionRegistrationINS_7volumes14VolumeInSphereEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7volumes14VolumeInSphereEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7volumes14VolumeShortcutIXadL_ZNS1_11glob_aroundEEEEEE6createERKNS_13ActionOptionsE46
_ZN4PLMD18ActionRegistrationINS_7volumes14VolumeShortcutIXadL_ZNS1_11glob_aroundEEEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7volumes14VolumeShortcutIXadL_ZNS1_11glob_aroundEEEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7volumes14VolumeShortcutIXadL_ZNS1_11glob_cavityEEEEEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_7volumes14VolumeShortcutIXadL_ZNS1_11glob_cavityEEEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7volumes14VolumeShortcutIXadL_ZNS1_11glob_cavityEEEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7volumes14VolumeShortcutIXadL_ZNS1_11glob_sphereEEEEEE6createERKNS_13ActionOptionsE10
_ZN4PLMD18ActionRegistrationINS_7volumes14VolumeShortcutIXadL_ZNS1_11glob_sphereEEEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7volumes14VolumeShortcutIXadL_ZNS1_11glob_sphereEEEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7volumes14VolumeShortcutIXadL_ZNS1_13glob_contoursEEEEEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_7volumes14VolumeShortcutIXadL_ZNS1_13glob_contoursEEEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7volumes14VolumeShortcutIXadL_ZNS1_13glob_contoursEEEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7volumes14VolumeShortcutIXadL_ZNS1_13glob_cylinderEEEEEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_7volumes14VolumeShortcutIXadL_ZNS1_13glob_cylinderEEEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7volumes14VolumeShortcutIXadL_ZNS1_13glob_cylinderEEEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7volumes14VolumeShortcutIXadL_ZNS1_14glob_tetraporeEEEEEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_7volumes14VolumeShortcutIXadL_ZNS1_14glob_tetraporeEEEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7volumes14VolumeShortcutIXadL_ZNS1_14glob_tetraporeEEEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7volumes15VolumeTetraporeEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_7volumes15VolumeTetraporeEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7volumes15VolumeTetraporeEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7volumes16VolumeInCylinderEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_7volumes16VolumeInCylinderEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7volumes16VolumeInCylinderEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7volumes16VolumeInEnvelopeEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_7volumes16VolumeInEnvelopeEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7volumes16VolumeInEnvelopeEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_7volumes7DensityEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_7volumes7DensityEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_7volumes7DensityEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8analysis10AccumulateEE6createERKNS_13ActionOptionsE63
_ZN4PLMD18ActionRegistrationINS_8analysis10AccumulateEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8analysis10AccumulateEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8analysis10CreateMaskEE6createERKNS_13ActionOptionsE15
_ZN4PLMD18ActionRegistrationINS_8analysis10CreateMaskEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8analysis10CreateMaskEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8analysis11WhamWeightsEE6createERKNS_13ActionOptionsE6
_ZN4PLMD18ActionRegistrationINS_8analysis11WhamWeightsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8analysis11WhamWeightsEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8analysis13CollectFramesEE6createERKNS_13ActionOptionsE19
_ZN4PLMD18ActionRegistrationINS_8analysis13CollectFramesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8analysis13CollectFramesEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8analysis13WhamHistogramEE6createERKNS_13ActionOptionsE6
_ZN4PLMD18ActionRegistrationINS_8analysis13WhamHistogramEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8analysis13WhamHistogramEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8analysis14GatherReplicasEE6createERKNS_13ActionOptionsE12
_ZN4PLMD18ActionRegistrationINS_8analysis14GatherReplicasEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8analysis14GatherReplicasEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8analysis17LandmarkSelectionEE6createERKNS_13ActionOptionsE8
_ZN4PLMD18ActionRegistrationINS_8analysis17LandmarkSelectionEEC2ESt17basic_string_viewIcSt11char_traitsIcEE15264
_ZN4PLMD18ActionRegistrationINS_8analysis17LandmarkSelectionEED2Ev15264
_ZN4PLMD18ActionRegistrationINS_8analysis21FarthestPointSamplingEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_8analysis21FarthestPointSamplingEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8analysis21FarthestPointSamplingEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8analysis4WhamEE6createERKNS_13ActionOptionsE12
_ZN4PLMD18ActionRegistrationINS_8analysis4WhamEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8analysis4WhamEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8analysis7AverageEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_8analysis7AverageEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8analysis7AverageEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8analysis7CollectEE6createERKNS_13ActionOptionsE92
_ZN4PLMD18ActionRegistrationINS_8analysis7CollectEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8analysis7CollectEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8analysis9CommittorEE6createERKNS_13ActionOptionsE9
_ZN4PLMD18ActionRegistrationINS_8analysis9CommittorEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8analysis9CommittorEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8analysis9HistogramEE6createERKNS_13ActionOptionsE22
_ZN4PLMD18ActionRegistrationINS_8analysis9HistogramEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8analysis9HistogramEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8analysis9LogSumExpEE6createERKNS_13ActionOptionsE9
_ZN4PLMD18ActionRegistrationINS_8analysis9LogSumExpEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8analysis9LogSumExpEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8clusters13ClusterNatomsEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_8clusters13ClusterNatomsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8clusters13ClusterNatomsEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8clusters13DFSClusteringEE6createERKNS_13ActionOptionsE17
_ZN4PLMD18ActionRegistrationINS_8clusters13DFSClusteringEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8clusters13DFSClusteringEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8clusters13OutputClusterEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_8clusters13OutputClusterEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8clusters13OutputClusterEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8clusters14ClusterWeightsEE6createERKNS_13ActionOptionsE29
_ZN4PLMD18ActionRegistrationINS_8clusters14ClusterWeightsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8clusters14ClusterWeightsEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8clusters15ClusterDiameterEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_8clusters15ClusterDiameterEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8clusters15ClusterDiameterEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8clusters17ClusterPropertiesEE6createERKNS_13ActionOptionsE20
_ZN4PLMD18ActionRegistrationINS_8clusters17ClusterPropertiesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8clusters17ClusterPropertiesEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8clusters18ClusterWithSurfaceEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_8clusters18ClusterWithSurfaceEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8clusters18ClusterWithSurfaceEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8clusters19ClusterDistributionEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_8clusters19ClusterDistributionEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8clusters19ClusterDistributionEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8clusters27ClusterDistributionShortcutEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_8clusters27ClusterDistributionShortcutEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8clusters27ClusterDistributionShortcutEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8function11FuncPathMSDEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_8function11FuncPathMSDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8function11FuncPathMSDEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8function12FuncSumHillsEE6createERKNS_13ActionOptionsE9
_ZN4PLMD18ActionRegistrationINS_8function12FuncSumHillsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8function12FuncSumHillsEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8function13LocalEnsembleEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_8function13LocalEnsembleEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8function13LocalEnsembleEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8function15FuncPathGeneralEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_8function15FuncPathGeneralEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8function15FuncPathGeneralEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_3SumEEEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_3SumEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10176
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_3SumEEEED2Ev10176
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_4SortEEEE6createERKNS_13ActionOptionsE12
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_4SortEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_4SortEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_6BesselEEEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_6BesselEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_6BesselEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_6CustomEEEE6createERKNS_13ActionOptionsE1172
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_6CustomEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10176
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_6CustomEEEED2Ev10176
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_7CombineEEEE6createERKNS_13ActionOptionsE194
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_7CombineEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_7CombineEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_7HighestEEEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_7HighestEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10176
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_7HighestEEEED2Ev10176
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_7MomentsEEEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_7MomentsEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_7MomentsEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_9PiecewiseEEEE6createERKNS_13ActionOptionsE3
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_9PiecewiseEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS1_9PiecewiseEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS_7refdist10DifferenceEEEE6createERKNS_13ActionOptionsE41
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS_7refdist10DifferenceEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS_7refdist10DifferenceEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS_9gridtools20EvaluateGridFunctionEEEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS_9gridtools20EvaluateGridFunctionEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfScalarINS_9gridtools20EvaluateGridFunctionEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_3SumEEEE6createERKNS_13ActionOptionsE768
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_3SumEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10176
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_3SumEEEED2Ev10176
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_4SortEEEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_4SortEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_4SortEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_6BesselEEEE6createERKNS_13ActionOptionsE7
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_6BesselEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_6BesselEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_6CustomEEEE6createERKNS_13ActionOptionsE1009
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_6CustomEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10176
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_6CustomEEEED2Ev10176
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_7BetweenEEEE6createERKNS_13ActionOptionsE52
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_7BetweenEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_7BetweenEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_7CombineEEEE6createERKNS_13ActionOptionsE83
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_7CombineEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_7CombineEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_7HighestEEEE6createERKNS_13ActionOptionsE44
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_7HighestEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10176
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_7HighestEEEED2Ev10176
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_7MomentsEEEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_7MomentsEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_7MomentsEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_8LessThanEEEE6createERKNS_13ActionOptionsE58
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_8LessThanEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_8LessThanEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_8MoreThanEEEE6createERKNS_13ActionOptionsE62
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_8MoreThanEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS1_8MoreThanEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS_7refdist10DifferenceEEEE6createERKNS_13ActionOptionsE143
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS_7refdist10DifferenceEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS_7refdist10DifferenceEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS_9gridtools20EvaluateGridFunctionEEEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS_9gridtools20EvaluateGridFunctionEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionOfVectorINS_9gridtools20EvaluateGridFunctionEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_3SumEEEE6createERKNS_13ActionOptionsE809
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_3SumEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10176
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_3SumEEEED2Ev10176
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_4SortEEEE6createERKNS_13ActionOptionsE14
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_4SortEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_4SortEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_6BesselEEEE6createERKNS_13ActionOptionsE7
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_6BesselEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_6BesselEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_6CustomEEEE6createERKNS_13ActionOptionsE2982
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_6CustomEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10176
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_6CustomEEEED2Ev10176
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_7BetweenEEEE6createERKNS_13ActionOptionsE53
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_7BetweenEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_7BetweenEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_7CombineEEEE6createERKNS_13ActionOptionsE303
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_7CombineEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_7CombineEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_7HighestEEEE6createERKNS_13ActionOptionsE46
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_7HighestEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10176
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_7HighestEEEED2Ev10176
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_7MomentsEEEE6createERKNS_13ActionOptionsE5
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_7MomentsEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_7MomentsEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_8LessThanEEEE6createERKNS_13ActionOptionsE59
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_8LessThanEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_8LessThanEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_8MoreThanEEEE6createERKNS_13ActionOptionsE68
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_8MoreThanEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_8MoreThanEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_9PiecewiseEEEE6createERKNS_13ActionOptionsE3
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_9PiecewiseEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS1_9PiecewiseEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS_7refdist10DifferenceEEEE6createERKNS_13ActionOptionsE184
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS_7refdist10DifferenceEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS_7refdist10DifferenceEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS_7symfunc17SphericalHarmonicEEEE6createERKNS_13ActionOptionsE41
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS_7symfunc17SphericalHarmonicEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS_7symfunc17SphericalHarmonicEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS_7symfunc19CylindricalHarmonicEEEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS_7symfunc19CylindricalHarmonicEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS_7symfunc19CylindricalHarmonicEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS_7symfunc7FccubicEEEE6createERKNS_13ActionOptionsE5
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS_7symfunc7FccubicEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8function16FunctionShortcutINS_7symfunc7FccubicEEEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8function5StatsEE6createERKNS_13ActionOptionsE31
_ZN4PLMD18ActionRegistrationINS_8function5StatsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8function5StatsEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8function7ProductEE6createERKNS_13ActionOptionsE114
_ZN4PLMD18ActionRegistrationINS_8function7ProductEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8function7ProductEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8function7annfunc3ANNEE6createERKNS_13ActionOptionsE5
_ZN4PLMD18ActionRegistrationINS_8function7annfunc3ANNEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8function7annfunc3ANNEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8function7pytorch12PytorchModelEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_8function7pytorch12PytorchModelEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8function7pytorch12PytorchModelEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8function8EnsembleEE6createERKNS_13ActionOptionsE27
_ZN4PLMD18ActionRegistrationINS_8function8EnsembleEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8function8EnsembleEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8valtools11ConcatenateEE6createERKNS_13ActionOptionsE175
_ZN4PLMD18ActionRegistrationINS_8valtools11ConcatenateEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8valtools11ConcatenateEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8valtools14SelectWithMaskEE6createERKNS_13ActionOptionsE93
_ZN4PLMD18ActionRegistrationINS_8valtools14SelectWithMaskEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8valtools14SelectWithMaskEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8valtools16SelectComponentsEE6createERKNS_13ActionOptionsE57
_ZN4PLMD18ActionRegistrationINS_8valtools16SelectComponentsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8valtools16SelectComponentsEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_8valtools7FlattenEE6createERKNS_13ActionOptionsE9
_ZN4PLMD18ActionRegistrationINS_8valtools7FlattenEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_8valtools7FlattenEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_9PbcActionEE6createERKNS_13ActionOptionsE1091
_ZN4PLMD18ActionRegistrationINS_9PbcActionEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_9PbcActionEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_9gridtools11PairEntropyEE6createERKNS_13ActionOptionsE65
_ZN4PLMD18ActionRegistrationINS_9gridtools11PairEntropyEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_9gridtools11PairEntropyEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_9gridtools12ConvertToFESEE6createERKNS_13ActionOptionsE15
_ZN4PLMD18ActionRegistrationINS_9gridtools12ConvertToFESEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_9gridtools12ConvertToFESEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_9gridtools13PairEntropiesEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_9gridtools13PairEntropiesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_9gridtools13PairEntropiesEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_9gridtools14FunctionOfGridINS_8function3SumEEEE6createERKNS_13ActionOptionsE90
_ZN4PLMD18ActionRegistrationINS_9gridtools14FunctionOfGridINS_8function3SumEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10176
_ZN4PLMD18ActionRegistrationINS_9gridtools14FunctionOfGridINS_8function3SumEEEED2Ev10176
_ZN4PLMD18ActionRegistrationINS_9gridtools14FunctionOfGridINS_8function6CustomEEEE6createERKNS_13ActionOptionsE432
_ZN4PLMD18ActionRegistrationINS_9gridtools14FunctionOfGridINS_8function6CustomEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10176
_ZN4PLMD18ActionRegistrationINS_9gridtools14FunctionOfGridINS_8function6CustomEEEED2Ev10176
_ZN4PLMD18ActionRegistrationINS_9gridtools15FindGridOptimumEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_9gridtools15FindGridOptimumEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10176
_ZN4PLMD18ActionRegistrationINS_9gridtools15FindGridOptimumEED2Ev10176
_ZN4PLMD18ActionRegistrationINS_9gridtools15InterpolateGridEE6createERKNS_13ActionOptionsE82
_ZN4PLMD18ActionRegistrationINS_9gridtools15InterpolateGridEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_9gridtools15InterpolateGridEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_9gridtools15ReadGridInSetupEE6createERKNS_13ActionOptionsE11
_ZN4PLMD18ActionRegistrationINS_9gridtools15ReadGridInSetupEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_9gridtools15ReadGridInSetupEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_9gridtools18MultiColvarDensityEE6createERKNS_13ActionOptionsE8
_ZN4PLMD18ActionRegistrationINS_9gridtools18MultiColvarDensityEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_9gridtools18MultiColvarDensityEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_9gridtools22EvaluateFunctionOnGridEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_9gridtools22EvaluateFunctionOnGridEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_9gridtools22EvaluateFunctionOnGridEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_9gridtools3KDEEE6createERKNS_13ActionOptionsE146
_ZN4PLMD18ActionRegistrationINS_9gridtools3KDEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10176
_ZN4PLMD18ActionRegistrationINS_9gridtools3KDEEED2Ev10176
_ZN4PLMD18ActionRegistrationINS_9gridtools3RDFEE6createERKNS_13ActionOptionsE66
_ZN4PLMD18ActionRegistrationINS_9gridtools3RDFEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_9gridtools3RDFEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_9gridtools8DumpGridEE6createERKNS_13ActionOptionsE66
_ZN4PLMD18ActionRegistrationINS_9gridtools8DumpGridEEC2ESt17basic_string_viewIcSt11char_traitsIcEE10176
_ZN4PLMD18ActionRegistrationINS_9gridtools8DumpGridEED2Ev10176
_ZN4PLMD18ActionRegistrationINS_9gridtools8GradientEE6createERKNS_13ActionOptionsE7
_ZN4PLMD18ActionRegistrationINS_9gridtools8GradientEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_9gridtools8GradientEED2Ev5088
_ZN4PLMD18ActionRegistrationINS_9gridtools9KLEntropyEE6createERKNS_13ActionOptionsE5
_ZN4PLMD18ActionRegistrationINS_9gridtools9KLEntropyEEC2ESt17basic_string_viewIcSt11char_traitsIcEE5088
_ZN4PLMD18ActionRegistrationINS_9gridtools9KLEntropyEED2Ev5088
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionRegister.h.gcov.html b/coverage/core/ActionRegister.h.gcov.html new file mode 100644 index 000000000000..28c80c2fd466 --- /dev/null +++ b/coverage/core/ActionRegister.h.gcov.html @@ -0,0 +1,199 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionRegister.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionRegister.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:77100.0 %
Date:2024-04-19 12:12:35Functions:1133115298.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_core_ActionRegister_h
+      23             : #define __PLUMED_core_ActionRegister_h
+      24             : 
+      25             : #include "RegisterBase.h"
+      26             : 
+      27             : #include "tools/Keywords.h"
+      28             : 
+      29             : namespace PLMD {
+      30             : 
+      31             : class Action;
+      32             : class ActionOptions;
+      33             : 
+      34             : struct ActionRegisterPointers {
+      35             : /// Pointer to a function which, given the options, create an Action
+      36             :   typedef std::unique_ptr<Action>(*creator_pointer)(const ActionOptions&);
+      37             : /// Pointer to a function which, returns the keywords allowed
+      38             :   typedef void(*keywords_pointer)(Keywords&);
+      39             :   creator_pointer create;
+      40             :   keywords_pointer keys;
+      41             : };
+      42             : 
+      43             : /// Register holding all the allowed keywords.
+      44             : /// This is a register which holds a map between strings (directives) and function pointers.
+      45             : /// The function pointers are pointing to functions which create an object of
+      46             : /// the corresponding class given the corresponding options (ActionOptions).
+      47             : /// There should be only one of there objects allocated.
+      48             : /// Actions should be registered here at the beginning of execution
+      49             : ///
+      50        5088 : class ActionRegister:
+      51             :   public RegisterBase<ActionRegisterPointers> {
+      52             : 
+      53             :   typedef ActionRegisterPointers::creator_pointer creator_pointer;
+      54             :   typedef ActionRegisterPointers::keywords_pointer keywords_pointer;
+      55             :   typedef ActionRegisterPointers Pointers;
+      56             : 
+      57             : public:
+      58             :   ID add(std::string key,creator_pointer cp,keywords_pointer kp);
+      59             : /// Create an Action of the type indicated in the options
+      60             : /// \param ao object containing information for initialization, such as the full input line, a pointer to PlumedMain, etc
+      61             :   std::unique_ptr<Action> create(const ActionOptions&ao);
+      62             :   std::unique_ptr<Action> create(const std::vector<void*> & images,const ActionOptions&ao);
+      63             : /// Print out the keywords for an action in html/vim ready for input into the manual
+      64             :   bool printManual(const std::string& action, const bool& vimout, const bool& spellout);
+      65             : /// Retrieve a keywords object for a particular action
+      66             :   bool getKeywords( const std::string& action, Keywords& keys );
+      67             : /// Print out a template command for an action
+      68             :   bool printTemplate(const std::string& action, bool include_optional);
+      69             :   std::vector<std::string> getActionNames() const;
+      70             : };
+      71             : 
+      72             : /// Function returning a reference to the ActionRegister.
+      73             : /// \relates ActionRegister
+      74             : /// To avoid problems with order of initialization, this function contains
+      75             : /// a static ActionRegister which is built the first time the function is called.
+      76             : /// In this manner, it is always initialized before it's used
+      77             : ActionRegister& actionRegister();
+      78             : 
+      79             : template<typename T>
+      80             : inline constexpr bool isActionType = std::is_base_of<Action, T>::value;
+      81             : //in C++20 you we'll make this a concept
+      82             : //template<typename T>
+      83             : //concept ActionType = std::is_base_of<::PLMD::Action, T>::value;
+      84             : //so the template will be template<ActionType ActionType>class ActionRegistration{...}
+      85             : //without the explicit need of the static assert
+      86             : 
+      87             : ///Each instance of this specialized class represents an action that can be called
+      88             : ///with  the specified directive.
+      89             : ///As soon it goes out of scope it will deregister the directive from the singleton ActionRegister
+      90             : template<typename ActionClass>
+      91             : class ActionRegistration {
+      92             :   ActionRegister::ID id;
+      93       49603 :   static std::unique_ptr<Action> create(const ActionOptions&ao) {
+      94       98020 :     return std::make_unique<ActionClass>(ao);
+      95             :   }
+      96             : public:
+      97             :   ///On construction register the ActionClass with the wanted directive
+      98     2208192 :   ActionRegistration(std::string_view directive):
+      99     2208192 :     id(actionRegister().add(directive.data(),create,ActionClass::registerKeywords))
+     100             :   {
+     101             :     static_assert(isActionType<ActionClass>,
+     102             :                   "ActionRegistration accepts only class that inherit from Action");
+     103     2208192 :   }
+     104             :   ///On destruction deregister the ActionClass (useful when you unload a shared object)
+     105     2208192 :   ~ActionRegistration() {actionRegister().remove(id);}
+     106             : };
+     107             : } //PLMD
+     108             : 
+     109             : #define PLUMED_CONCATENATE_DIRECT(s1, s2) s1##s2
+     110             : #define PLUMED_CONCATENATE(s1, s2) PLUMED_CONCATENATE_DIRECT(s1, s2)
+     111             : 
+     112             : /// Shortcut for Action registration
+     113             : /// \relates PLMD::ActionRegister
+     114             : /// For easier registration, this file also provides a macro PLUMED_REGISTER_ACTION.
+     115             : /// \param classname the name of the class to be registered
+     116             : /// \param directive a string containing the corresponding directive
+     117             : /// This macro should be used in the .cpp file of the corresponding class
+     118             : #define PLUMED_REGISTER_ACTION(classname,directive) \
+     119             :   namespace {::PLMD::ActionRegistration<classname> \
+     120             :              PLUMED_CONCATENATE(classname##Registerer,__LINE__)(directive);}
+     121             : #endif
+     122             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionSet.cpp.func-sort-c.html b/coverage/core/ActionSet.cpp.func-sort-c.html new file mode 100644 index 000000000000..afe3a579e1f1 --- /dev/null +++ b/coverage/core/ActionSet.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + 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:1515100.0 %
Date:2024-04-19 12:12:35Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9ActionSet11clearDeleteEv3
_ZNK4PLMD9ActionSet26getShortcutActionWithLabelERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE6252
_ZN4PLMD9ActionSetC2ERNS_10PlumedMainE806370
_ZN4PLMD9ActionSetD2Ev806370
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionSet.cpp.func.html b/coverage/core/ActionSet.cpp.func.html new file mode 100644 index 000000000000..0f10c6eee68f --- /dev/null +++ b/coverage/core/ActionSet.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + 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:1515100.0 %
Date:2024-04-19 12:12:35Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9ActionSet11clearDeleteEv3
_ZN4PLMD9ActionSetC2ERNS_10PlumedMainE806370
_ZN4PLMD9ActionSetD2Ev806370
_ZNK4PLMD9ActionSet26getShortcutActionWithLabelERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE6252
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionSet.cpp.gcov.html b/coverage/core/ActionSet.cpp.gcov.html new file mode 100644 index 000000000000..3e3320f1aa5e --- /dev/null +++ b/coverage/core/ActionSet.cpp.gcov.html @@ -0,0 +1,129 @@ + + + + + + + + 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:1515100.0 %
Date:2024-04-19 12:12:35Functions: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             : #include "ActionSet.h"
+      23             : 
+      24             : namespace PLMD {
+      25             : 
+      26      806370 : ActionSet::ActionSet(PlumedMain&p):
+      27      806370 :   plumed(p) {
+      28             :   (void) plumed; // to suppress warning about "unused plumed"
+      29      806370 : }
+      30             : 
+      31      806370 : ActionSet::~ActionSet()
+      32             : {
+      33             : // required in order to deallocate in reverse order:
+      34      855916 :   for(int i=size()-1; i>=0; i--) (*this)[i].reset();
+      35      806370 : }
+      36             : 
+      37           3 : void ActionSet::clearDelete() {
+      38          48 :   for(int i=size()-1; i>=0; i--) (*this)[i].reset();
+      39           3 :   clear();
+      40           3 : }
+      41             : 
+      42        6252 : ActionShortcut* ActionSet::getShortcutActionWithLabel( const std::string& s ) const {
+      43             :   ActionShortcut* scf = NULL;
+      44      269704 :   for(const auto & p : (*this)) {
+      45      263452 :     ActionShortcut* sc=dynamic_cast<ActionShortcut*>(p.get());
+      46      263452 :     if( sc && sc->shortcutlabel==s ) scf = sc;
+      47             :   }
+      48        6252 :   if( scf ) return scf;
+      49             :   return NULL;
+      50             : }
+      51             : 
+      52             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionSet.h.func-sort-c.html b/coverage/core/ActionSet.h.func-sort-c.html new file mode 100644 index 000000000000..d0a55c73fb73 --- /dev/null +++ b/coverage/core/ActionSet.h.func-sort-c.html @@ -0,0 +1,197 @@ + + + + + + + + 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-04-19 12:12:35Functions:273187.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_21ActionWithVirtualAtomEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZNK4PLMD9ActionSet6selectIPNS_3ves14BasisFunctionsEEESt6vectorIT_SaIS6_EEv0
_ZNK4PLMD9ActionSet6selectIPNS_3ves18TargetDistributionEEESt6vectorIT_SaIS6_EEv0
_ZNK4PLMD9ActionSet6selectIPNS_3ves7VesBiasEEESt6vectorIT_SaIS6_EEv0
_ZNK4PLMD9ActionSet12getLabelListIPNS_15ActionWithValueEEENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEv1
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_4maze9OptimizerEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_15ActionAtomisticEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE6
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_4maze4LossEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE7
_ZNK4PLMD9ActionSet6selectIPNS_6colvar10RMSDVectorEEESt6vectorIT_SaIS6_EEv10
_ZNK4PLMD9ActionSet12selectLatestIPNS_3piv3PIVEEET_PKNS_6ActionE12
_ZNK4PLMD9ActionSet6selectIPNS_14ActionShortcutEEESt6vectorIT_SaIS5_EEv18
_ZNK4PLMD9ActionSet6selectIPNS_4opes12ExpansionCVsEEESt6vectorIT_SaIS6_EEv30
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_9PbcActionEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE75
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_3ves7VesBiasEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE88
_ZNK4PLMD9ActionSet6selectIPNS_7generic4ReadEEESt6vectorIT_SaIS6_EEv89
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_3ves14BasisFunctionsEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE241
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_15ActionToGetDataEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE281
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_3ves18TargetDistributionEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE407
_ZNK4PLMD9ActionSet6selectIPNS_19DomainDecompositionEEESt6vectorIT_SaIS5_EEv979
_ZNK4PLMD9ActionSet12selectLatestIPNS_14GenericMolInfoEEET_PKNS_6ActionE1028
_ZNK4PLMD9ActionSet6selectIPNS_15ActionAtomisticEEESt6vectorIT_SaIS5_EEv1033
_ZNK4PLMD9ActionSet6selectIPNS_15ActionToPutDataEEESt6vectorIT_SaIS5_EEv1227
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_18ActionForInterfaceEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1406
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_15ActionToPutDataEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE10249
_ZNK4PLMD9ActionSet6selectIPNS_15ActionWithValueEEESt6vectorIT_SaIS5_EEv18385
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_6ActionEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE49678
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_5GroupEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE50474
_ZNK4PLMD9ActionSet6selectIPNS_11ActionPilotEEESt6vectorIT_SaIS5_EEv50606
_ZNK4PLMD9ActionSet6selectIPNS_18ActionForInterfaceEEESt6vectorIT_SaIS5_EEv53504
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_16ActionWithVectorEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE176560
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_15ActionWithValueEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1189141
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionSet.h.func.html b/coverage/core/ActionSet.h.func.html new file mode 100644 index 000000000000..21858ca7371a --- /dev/null +++ b/coverage/core/ActionSet.h.func.html @@ -0,0 +1,197 @@ + + + + + + + + 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-04-19 12:12:35Functions:273187.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD9ActionSet12getLabelListIPNS_15ActionWithValueEEENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEv1
_ZNK4PLMD9ActionSet12selectLatestIPNS_14GenericMolInfoEEET_PKNS_6ActionE1028
_ZNK4PLMD9ActionSet12selectLatestIPNS_3piv3PIVEEET_PKNS_6ActionE12
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_15ActionAtomisticEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE6
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_15ActionToGetDataEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE281
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_15ActionToPutDataEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE10249
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_15ActionWithValueEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1189141
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_16ActionWithVectorEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE176560
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_18ActionForInterfaceEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1406
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_21ActionWithVirtualAtomEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_3ves14BasisFunctionsEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE241
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_3ves18TargetDistributionEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE407
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_3ves7VesBiasEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE88
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_4maze4LossEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE7
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_4maze9OptimizerEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_5GroupEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE50474
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_6ActionEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE49678
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_9PbcActionEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE75
_ZNK4PLMD9ActionSet6selectIPNS_11ActionPilotEEESt6vectorIT_SaIS5_EEv50606
_ZNK4PLMD9ActionSet6selectIPNS_14ActionShortcutEEESt6vectorIT_SaIS5_EEv18
_ZNK4PLMD9ActionSet6selectIPNS_15ActionAtomisticEEESt6vectorIT_SaIS5_EEv1033
_ZNK4PLMD9ActionSet6selectIPNS_15ActionToPutDataEEESt6vectorIT_SaIS5_EEv1227
_ZNK4PLMD9ActionSet6selectIPNS_15ActionWithValueEEESt6vectorIT_SaIS5_EEv18385
_ZNK4PLMD9ActionSet6selectIPNS_18ActionForInterfaceEEESt6vectorIT_SaIS5_EEv53504
_ZNK4PLMD9ActionSet6selectIPNS_19DomainDecompositionEEESt6vectorIT_SaIS5_EEv979
_ZNK4PLMD9ActionSet6selectIPNS_3ves14BasisFunctionsEEESt6vectorIT_SaIS6_EEv0
_ZNK4PLMD9ActionSet6selectIPNS_3ves18TargetDistributionEEESt6vectorIT_SaIS6_EEv0
_ZNK4PLMD9ActionSet6selectIPNS_3ves7VesBiasEEESt6vectorIT_SaIS6_EEv0
_ZNK4PLMD9ActionSet6selectIPNS_4opes12ExpansionCVsEEESt6vectorIT_SaIS6_EEv30
_ZNK4PLMD9ActionSet6selectIPNS_6colvar10RMSDVectorEEESt6vectorIT_SaIS6_EEv10
_ZNK4PLMD9ActionSet6selectIPNS_7generic4ReadEEESt6vectorIT_SaIS6_EEv89
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionSet.h.gcov.html b/coverage/core/ActionSet.h.gcov.html new file mode 100644 index 000000000000..ff4cfa3694ba --- /dev/null +++ b/coverage/core/ActionSet.h.gcov.html @@ -0,0 +1,227 @@ + + + + + + + + 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-04-19 12:12:35Functions:273187.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_core_ActionSet_h
+      23             : #define __PLUMED_core_ActionSet_h
+      24             : 
+      25             : #include "Action.h"
+      26             : #include "ActionShortcut.h"
+      27             : #include <memory>
+      28             : 
+      29             : namespace PLMD {
+      30             : 
+      31             : class PlumedMain;
+      32             : 
+      33             : /// std::vector containing the sequence of Action to be done.
+      34             : /// It is a vector of Action*, and as such it has the entire
+      35             : /// std::vector interface. Moreover, it implements methods to extract
+      36             : /// Acion* of a given type (select<T>()), NOT of a given type (selectNot<T>())
+      37             : /// or to find an Action with a given label (selectWithLabel())
+      38             : /// Finally, since it holds pointers, there is a clearDelete() function
+      39             : /// which deletes the pointers before deleting the vector
+      40             : class ActionSet:
+      41             :   public std::vector<std::unique_ptr<Action>>
+      42             : {
+      43             :   PlumedMain& plumed;
+      44             : public:
+      45             :   explicit ActionSet(PlumedMain&p);
+      46             :   ~ActionSet();
+      47             : /// Clear and deletes all the included pointers.
+      48             :   void clearDelete();
+      49             : 
+      50             : /// Extract pointers to all Action's of type T
+      51             : /// To extract all Colvar , use select<Colvar*>();
+      52             :   template <class T>
+      53             :   std::vector<T> select()const;
+      54             : /// Extract pointers to all Action's which are not of type T
+      55             : /// E.g., to extract all noncolvars, use
+      56             : ///    selectNot<Colvar*>();
+      57             :   template <class T>
+      58             :   std::vector<Action*> selectNot()const;
+      59             : /// Extract pointer to an action labeled s, only if it is of
+      60             : /// type T. E.g., to extract an action labeled "pippo", use selectWithLabel<Action*>("pippo")
+      61             : /// If you want it to be a Colvar, use selectWithLabel<Colvar*>(pippo). If it is
+      62             : /// not found, it returns NULL
+      63             :   template <class T>
+      64             :   T selectWithLabel(const std::string&s)const;
+      65             : /// get the labels in the list of actions in form of a string (useful to debug)
+      66             : /// Only classes that can be dynamic casted to T are reported
+      67             :   template <class T>
+      68             :   std::string getLabelList() const;
+      69             : /// get the labels in the form of a vector of strings
+      70             : /// Only classes that can be dynamic casted to T are reported
+      71             :   template <class T>
+      72             :   std::vector<std::string> getLabelVector() const;
+      73             : /// Extract pointer to last action of type T located before
+      74             : /// action. If action is not in ActionSet or if there is no action of type T
+      75             : /// returns NULL.
+      76             : /// Typically to be used as selectLatest<Type>(this);
+      77             :   template <class T>
+      78             :   T selectLatest(const Action*action)const;
+      79             : /// Get any shortcuts with this shortcut label
+      80             :   ActionShortcut* getShortcutActionWithLabel( const std::string& s ) const ;
+      81             : };
+      82             : 
+      83             : /////
+      84             : // INLINE IMPLEMENTATIONS:
+      85             : 
+      86             : template <class T>
+      87      125881 : std::vector<T> ActionSet::select()const {
+      88             :   std::vector<T> ret;
+      89    73427176 :   for(const auto & p : (*this)) {
+      90    73301295 :     T t=dynamic_cast<T>(p.get());
+      91    73301295 :     if(t) ret.push_back(t);
+      92             :   };
+      93      125881 :   return ret;
+      94             : }
+      95             : 
+      96             : template <class T>
+      97     1478614 : T ActionSet::selectWithLabel(const std::string&s)const {
+      98   162625116 :   for(const auto & p : (*this)) {
+      99   133318468 :     T t=dynamic_cast<T>(p.get());
+     100   162512200 :     if(t && t->getLabel()==s) return t;
+     101             :   };
+     102             :   return NULL;
+     103             : }
+     104             : 
+     105             : template <class T>
+     106             : std::vector<Action*> ActionSet::selectNot()const {
+     107             :   std::vector<Action*> ret;
+     108             :   for(const auto & p : (*this)) {
+     109             :     T t=dynamic_cast<T>(p);
+     110             :     if(!t) ret.push_back(p.get());
+     111             :   };
+     112             :   return ret;
+     113             : }
+     114             : 
+     115             : template <class T>
+     116           1 : std::string ActionSet::getLabelList() const {
+     117             :   std::string outlist;
+     118          16 :   for(const auto & p : (*this)) {
+     119          26 :     if(dynamic_cast<T>(p.get())) outlist+=p->getLabel()+" ";
+     120             :   };
+     121           1 :   return  outlist;
+     122             : }
+     123             : 
+     124             : 
+     125             : template <class T>
+     126             : std::vector<std::string> ActionSet::getLabelVector() const {
+     127             :   std::vector<std::string> outlist;
+     128             :   for(const auto & p : (*this)) {
+     129             :     if(dynamic_cast<T>(p.get())) outlist.push_back(p->getLabel());
+     130             :   };
+     131             :   return  outlist;
+     132             : }
+     133             : 
+     134             : template <class T>
+     135        1040 : T ActionSet::selectLatest(const Action*action) const {
+     136             :   T t=nullptr;
+     137       36805 :   for(const auto & p : (*this)) {
+     138       35793 :     if(p.get()==action) return t;
+     139       35765 :     T r=dynamic_cast<T>(p.get());
+     140       35765 :     if(r) t=r;
+     141             :   }
+     142             :   return t;
+     143             : }
+     144             : 
+     145             : 
+     146             : 
+     147             : }
+     148             : 
+     149             : #endif
+     150             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionSetup.cpp.func-sort-c.html b/coverage/core/ActionSetup.cpp.func-sort-c.html new file mode 100644 index 000000000000..77c5929f412b --- /dev/null +++ b/coverage/core/ActionSetup.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionSetup.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionSetup.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:101190.9 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11ActionSetup16registerKeywordsERNS_8KeywordsE181
_ZN4PLMD11ActionSetupC1ERKNS_13ActionOptionsE0
_ZN4PLMD11ActionSetupC2ERKNS_13ActionOptionsE84
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionSetup.cpp.gcov.html b/coverage/core/ActionSetup.cpp.gcov.html new file mode 100644 index 000000000000..8ca93090c9c5 --- /dev/null +++ b/coverage/core/ActionSetup.cpp.gcov.html @@ -0,0 +1,125 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionSetup.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionSetup.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:101190.9 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ + + + + + + + +

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

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11ActionSetup5applyEv0
_ZN4PLMD11ActionSetup9calculateEv0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionSetup.h.gcov.html b/coverage/core/ActionSetup.h.gcov.html new file mode 100644 index 000000000000..a8dc6d62c5a4 --- /dev/null +++ b/coverage/core/ActionSetup.h.gcov.html @@ -0,0 +1,125 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionSetup.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionSetup.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:030.0 %
Date:2024-04-19 12:12:35Functions: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           0 : class ActionSetup :
+      34             :   public virtual Action {
+      35             : public:
+      36             : /// Constructor
+      37             :   explicit ActionSetup(const ActionOptions&ao);
+      38             : /// Creator of keywords
+      39             :   static void registerKeywords( Keywords& keys );
+      40             : /// Do nothing.
+      41           0 :   void calculate() override {}
+      42             : /// Do nothing.
+      43           0 :   void apply() override {}
+      44             : };
+      45             : 
+      46             : }
+      47             : 
+      48             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionShortcut.cpp.func-sort-c.html b/coverage/core/ActionShortcut.cpp.func-sort-c.html new file mode 100644 index 000000000000..7d78731b933e --- /dev/null +++ b/coverage/core/ActionShortcut.cpp.func-sort-c.html @@ -0,0 +1,113 @@ + + + + + + + + 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:799186.8 %
Date:2024-04-19 12:12:35Functions:81080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14ActionShortcutC1ERKNS_13ActionOptionsE0
_ZNK4PLMD14ActionShortcut18getSavedInputLinesB5cxx11Ev0
_ZNK4PLMD14ActionShortcut15getUpdateLimitsB5cxx11Ev37
_ZN4PLMD14ActionShortcut20readShortcutKeywordsERKNS_8KeywordsERSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESA_St4lessISA_ESaISt4pairIKSA_SA_EEE229
_ZNK4PLMD14ActionShortcut18interpretDataLabelERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPNS_6ActionERSt6vectorIPNS_5ValueESaISD_EE512
_ZN4PLMD14ActionShortcut24convertInputLineToStringB5cxx11Ev14547
_ZN4PLMD14ActionShortcut16registerKeywordsERNS_8KeywordsE14658
_ZN4PLMD14ActionShortcutC2ERKNS_13ActionOptionsE15811
_ZN4PLMD14ActionShortcut13readInputLineERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE21350
_ZNK4PLMD14ActionShortcut16getShortcutLabelB5cxx11Ev27230
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionShortcut.cpp.func.html b/coverage/core/ActionShortcut.cpp.func.html new file mode 100644 index 000000000000..deb5e1ea11ce --- /dev/null +++ b/coverage/core/ActionShortcut.cpp.func.html @@ -0,0 +1,113 @@ + + + + + + + + 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:799186.8 %
Date:2024-04-19 12:12:35Functions:81080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14ActionShortcut13readInputLineERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE21350
_ZN4PLMD14ActionShortcut16registerKeywordsERNS_8KeywordsE14658
_ZN4PLMD14ActionShortcut20readShortcutKeywordsERKNS_8KeywordsERSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESA_St4lessISA_ESaISt4pairIKSA_SA_EEE229
_ZN4PLMD14ActionShortcut24convertInputLineToStringB5cxx11Ev14547
_ZN4PLMD14ActionShortcutC1ERKNS_13ActionOptionsE0
_ZN4PLMD14ActionShortcutC2ERKNS_13ActionOptionsE15811
_ZNK4PLMD14ActionShortcut15getUpdateLimitsB5cxx11Ev37
_ZNK4PLMD14ActionShortcut16getShortcutLabelB5cxx11Ev27230
_ZNK4PLMD14ActionShortcut18getSavedInputLinesB5cxx11Ev0
_ZNK4PLMD14ActionShortcut18interpretDataLabelERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPNS_6ActionERSt6vectorIPNS_5ValueESaISD_EE512
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionShortcut.cpp.gcov.html b/coverage/core/ActionShortcut.cpp.gcov.html new file mode 100644 index 000000000000..e71323e1b32a --- /dev/null +++ b/coverage/core/ActionShortcut.cpp.gcov.html @@ -0,0 +1,239 @@ + + + + + + + + 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:799186.8 %
Date:2024-04-19 12:12:35Functions:81080.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 "ActionShortcut.h"
+      23             : #include "PlumedMain.h"
+      24             : #include "ActionWithValue.h"
+      25             : #include "ActionRegister.h"
+      26             : #include "ActionSet.h"
+      27             : 
+      28             : namespace PLMD {
+      29             : 
+      30       14658 : void ActionShortcut::registerKeywords( Keywords& keys ) {
+      31       14658 :   Action::registerKeywords( keys );
+      32       29316 :   keys.add("hidden","IS_SHORTCUT","hidden keyword to tell if actions are shortcuts so that example generator can provide expansions of shortcuts");
+      33       14658 : }
+      34             : 
+      35         229 : void ActionShortcut::readShortcutKeywords( const Keywords& keys, std::map<std::string,std::string>& keymap ) {
+      36        2738 :   for(unsigned i=0; i<keys.size(); ++i) {
+      37        2509 :     std::string t, keyname = keys.get(i);
+      38        3421 :     if( keys.style( keyname, "optional") || keys.style( keyname, "compulsory") ) {
+      39        1597 :       parse(keyname,t);
+      40        1597 :       if( t.length()>0 ) {
+      41         102 :         keymap.insert(std::pair<std::string,std::string>(keyname,t));
+      42        1546 :       } else if( keys.numbered( keyname ) ) {
+      43         647 :         for(unsigned i=1;; ++i) {
+      44         660 :           std::string istr; Tools::convert( i, istr );
+      45         660 :           if( !parseNumbered(keyname,i,t) ) break ;
+      46          26 :           keymap.insert(std::pair<std::string,std::string>(keyname + istr,t));
+      47          13 :         }
+      48             :       }
+      49        1824 :     } else if( keys.style( keyname, "flag") ) {
+      50         912 :       bool found=false; parseFlag(keyname,found);
+      51        1014 :       if( found ) keymap.insert(std::pair<std::string,std::string>(keyname,""));
+      52           0 :     } else plumed_merror("shortcut keywords should be optional, compulsory or flags");
+      53             :   }
+      54         229 : }
+      55             : 
+      56       15811 : ActionShortcut::ActionShortcut(const ActionOptions&ao):
+      57             :   Action(ao),
+      58       15811 :   shortcutlabel(label)
+      59             : {
+      60       15811 :   std::string s; Tools::convert(plumed.getActionSet().size(),s);
+      61       15811 :   if( shortcutlabel==("@" + s) ) {
+      62           0 :     std::string t; Tools::convert(plumed.getActionSet().size(),t);
+      63           0 :     shortcutlabel="@" + t;
+      64       31622 :   } else label = ("@s" + s);
+      65       15811 : }
+      66             : 
+      67       21350 : void ActionShortcut::readInputLine( const std::string& input ) {
+      68       21350 :   std::vector<std::string> words=Tools::getWords(input); Tools::interpretLabel(words);
+      69             :   // Check if this action name has been registered
+      70       21350 :   bool found = std::find(keywords.neededActions.begin(), keywords.neededActions.end(), words[0] )!=keywords.neededActions.end();
+      71             :   // Check if we are just calling something like SUM_VECTOR using just SUM.
+      72       35922 :   if( !found && words[0].find(getName())!=std::string::npos ) {
+      73       19302 :     for(unsigned j=0 ; j<keywords.actionNameSuffixes.size(); ++j) {
+      74       19302 :       if( (getName() + keywords.actionNameSuffixes[j])==words[0] ) { found=true; break; }
+      75             :     }
+      76             :   }
+      77       21350 :   if( found ) {
+      78       21350 :     std::string f_input = input; savedInputLines.push_back( input );
+      79       42700 :     if( keywords.exists("RESTART") ) {
+      80           0 :       if( restart ) f_input += " RESTART=YES";
+      81           0 :       if( !restart ) f_input += " RESTART=NO";
+      82             :     }
+      83       21350 :     plumed.readInputLine( f_input );
+      84           0 :   } else error("requirement for action " + words[0] + " should be registered in registerKeywords function for shortcut action using keys.useAction");
+      85       21350 : }
+      86             : 
+      87          37 : std::string ActionShortcut::getUpdateLimits() const {
+      88          37 :   std::string f_input="";
+      89          37 :   if( update_from!=std::numeric_limits<double>::max() ) {
+      90           4 :     std::string ufrom; Tools::convert( update_from, ufrom ); f_input += " UPDATE_FROM=" + ufrom;
+      91             :   }
+      92          37 :   if( update_until!=std::numeric_limits<double>::max() ) {
+      93           4 :     std::string util; Tools::convert( update_until, util ); f_input += " UPDATE_UNTIL=" + util;
+      94             :   }
+      95          37 :   return f_input;
+      96             : }
+      97             : 
+      98       27230 : const std::string & ActionShortcut::getShortcutLabel() const {
+      99       27230 :   return shortcutlabel;
+     100             : }
+     101             : 
+     102           0 : std::vector<std::string> ActionShortcut::getSavedInputLines() const {
+     103           0 :   return savedInputLines;
+     104             : }
+     105             : 
+     106       14547 : std::string ActionShortcut::convertInputLineToString() {
+     107             :   std::string output;
+     108       60371 :   for(auto p=line.begin(); p!=line.end(); ++p) {
+     109       45824 :     if( (*p).find(" " )!=std::string::npos ) {
+     110         395 :       std::size_t eq = (*p).find_first_of("=");
+     111         790 :       output += " " + (*p).substr(0,eq) + "={" + (*p).substr(eq+1) + "}";
+     112       90858 :     } else output += " " + (*p);
+     113             :   }
+     114       14547 :   line.resize(0); return output;
+     115             : }
+     116             : 
+     117         512 : void ActionShortcut::interpretDataLabel( const std::string& mystr, Action* myuser, std::vector<Value*>& arg ) const {
+     118         512 :   std::size_t dot=mystr.find_first_of('.'); std::string a=mystr.substr(0,dot); std::string name=mystr.substr(dot+1);
+     119             :   // Retrieve the keywords for the shortcut
+     120         512 :   Keywords skeys; actionRegister().getKeywords( getName(), skeys );
+     121         512 :   std::vector<std::string> out_comps( skeys.getOutputComponents() );
+     122             :   // Now get the output components
+     123         512 :   if( name=="*" ) {
+     124        2555 :     for(unsigned k=0; k<out_comps.size(); ++k) {
+     125        2188 :       if( out_comps[k]=="" ) {
+     126           0 :         ActionWithValue* action=plumed.getActionSet().selectWithLabel<ActionWithValue*>( a );
+     127           0 :         if( action ) {
+     128           0 :           if( action->getNumberOfComponents()!=1 ) myuser->error("action named " + a + " has more than one component");
+     129           0 :           arg.push_back(action->copyOutput(0));
+     130             :         }
+     131             :       } else {
+     132        4376 :         ActionWithValue* action=plumed.getActionSet().selectWithLabel<ActionWithValue*>( a + "_" + out_comps[k] );
+     133        2188 :         if( action ) {
+     134         216 :           if( action->getNumberOfComponents()!=1 ) myuser->error("action named " + a + "_" + out_comps[k] + " has more than one component");
+     135         216 :           arg.push_back(action->copyOutput(0));
+     136             :         } else {
+     137        1972 :           for(unsigned j=1;; ++j) {
+     138        3987 :             std::string numstr; Tools::convert( j, numstr );
+     139        7974 :             ActionWithValue* act=plumed.getActionSet().selectWithLabel<ActionWithValue*>( a + "_" + out_comps[k] + "-" + numstr );
+     140        3987 :             if( act ) {
+     141         140 :               for(unsigned n=0; n<act->getNumberOfComponents(); ++n ) arg.push_back(act->copyOutput(n));
+     142        3917 :             } else if( j>1 ) break;    // This ensures that * syntax works with moments, which normally start from 2
+     143        2015 :           }
+     144             :         }
+     145             :       }
+     146             :     }
+     147             :   } else {
+     148             :     // Check for an action that has action.component
+     149         145 :     ActionWithValue* act=plumed.getActionSet().selectWithLabel<ActionWithValue*>( a );
+     150         145 :     if( act && act->exists(mystr) ) return;
+     151             :     // Get components that are actually actions
+     152         163 :     for(unsigned k=0; k<out_comps.size(); ++k) {
+     153         106 :       if(name.find_first_of(out_comps[k])!=std::string::npos ) {
+     154         164 :         ActionWithValue* action=plumed.getActionSet().selectWithLabel<ActionWithValue*>( a + "_" + name );
+     155          82 :         if( action ) arg.push_back(action->copyOutput(a+"_"+name));
+     156             :         break;
+     157             :       }
+     158             :     }
+     159             :   }
+     160         512 : }
+     161             : 
+     162             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionShortcut.h.func-sort-c.html b/coverage/core/ActionShortcut.h.func-sort-c.html new file mode 100644 index 000000000000..2304757af599 --- /dev/null +++ b/coverage/core/ActionShortcut.h.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionShortcut.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionShortcut.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:030.0 %
Date:2024-04-19 12:12:35Functions:030.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

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

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

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15ActionToGetDataC2ERKNS_13ActionOptionsE0
_ZN4PLMD15ActionToGetData9get_shapeERKNS_11TypesafePtrE51
_ZN4PLMD15ActionToGetData10set_memoryERKNS_11TypesafePtrE115
_ZN4PLMD15ActionToGetData8get_rankERKNS_11TypesafePtrE115
_ZN4PLMD15ActionToGetDataC1ERKNS_13ActionOptionsE115
_ZN4PLMD15ActionToGetData16registerKeywordsERNS_8KeywordsE117
_ZN4PLMD15ActionToGetData9calculateEv12447
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionToGetData.cpp.func.html b/coverage/core/ActionToGetData.cpp.func.html new file mode 100644 index 000000000000..4d1b8dfdfae7 --- /dev/null +++ b/coverage/core/ActionToGetData.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionToGetData.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionToGetData.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:283190.3 %
Date:2024-04-19 12:12:35Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15ActionToGetData10set_memoryERKNS_11TypesafePtrE115
_ZN4PLMD15ActionToGetData16registerKeywordsERNS_8KeywordsE117
_ZN4PLMD15ActionToGetData8get_rankERKNS_11TypesafePtrE115
_ZN4PLMD15ActionToGetData9calculateEv12447
_ZN4PLMD15ActionToGetData9get_shapeERKNS_11TypesafePtrE51
_ZN4PLMD15ActionToGetDataC1ERKNS_13ActionOptionsE115
_ZN4PLMD15ActionToGetDataC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionToGetData.cpp.gcov.html b/coverage/core/ActionToGetData.cpp.gcov.html new file mode 100644 index 000000000000..e6deb42c177f --- /dev/null +++ b/coverage/core/ActionToGetData.cpp.gcov.html @@ -0,0 +1,161 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionToGetData.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionToGetData.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:283190.3 %
Date:2024-04-19 12:12:35Functions:6785.7 %
+
+ + + + + + + + +

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

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

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

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

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD15ActionToPutData26getNumberOfForcesToRescaleEv150
_ZN4PLMD15ActionToPutData13rescaleForcesERKd200
_ZN4PLMD15ActionToPutData10readBinaryERSi798
_ZN4PLMD15ActionToPutData11writeBinaryERSo798
_ZN4PLMD15ActionToPutDataC2ERKNS_13ActionOptionsE1131
_ZNK4PLMD15ActionToPutData14getLocalValuesERSt6vectorIdSaIdEE1350
_ZN4PLMD15ActionToPutDataC1ERKNS_13ActionOptionsE6540
_ZN4PLMD15ActionToPutData16registerKeywordsERNS_8KeywordsE6542
_ZN4PLMD15ActionToPutData7setUnitERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_7671
_ZNK4PLMD15ActionToPutData11getUnitNameB5cxx11Ev7844
_ZN4PLMD15ActionToPutData11updateUnitsEPNS_16DataPassingToolsE7864
_ZN4PLMD15ActionToPutData4waitEv93671
_ZN4PLMD15ActionToPutData5applyEv443376
_ZN4PLMD15ActionToPutData8setStartERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKj448823
_ZN4PLMD15ActionToPutData9setStrideERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKj448823
_ZN4PLMD15ActionToPutData15setForcePointerERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_11TypesafePtrE972084
_ZN4PLMD15ActionToPutData15setValuePointerERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_11TypesafePtrE1923333
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionToPutData.cpp.func.html b/coverage/core/ActionToPutData.cpp.func.html new file mode 100644 index 000000000000..43cddaf174c2 --- /dev/null +++ b/coverage/core/ActionToPutData.cpp.func.html @@ -0,0 +1,141 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionToPutData.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionToPutData.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:9610492.3 %
Date:2024-04-19 12:12:35Functions:1717100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15ActionToPutData10readBinaryERSi798
_ZN4PLMD15ActionToPutData11updateUnitsEPNS_16DataPassingToolsE7864
_ZN4PLMD15ActionToPutData11writeBinaryERSo798
_ZN4PLMD15ActionToPutData13rescaleForcesERKd200
_ZN4PLMD15ActionToPutData15setForcePointerERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_11TypesafePtrE972084
_ZN4PLMD15ActionToPutData15setValuePointerERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_11TypesafePtrE1923333
_ZN4PLMD15ActionToPutData16registerKeywordsERNS_8KeywordsE6542
_ZN4PLMD15ActionToPutData4waitEv93671
_ZN4PLMD15ActionToPutData5applyEv443376
_ZN4PLMD15ActionToPutData7setUnitERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_7671
_ZN4PLMD15ActionToPutData8setStartERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKj448823
_ZN4PLMD15ActionToPutData9setStrideERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKj448823
_ZN4PLMD15ActionToPutDataC1ERKNS_13ActionOptionsE6540
_ZN4PLMD15ActionToPutDataC2ERKNS_13ActionOptionsE1131
_ZNK4PLMD15ActionToPutData11getUnitNameB5cxx11Ev7844
_ZNK4PLMD15ActionToPutData14getLocalValuesERSt6vectorIdSaIdEE1350
_ZNK4PLMD15ActionToPutData26getNumberOfForcesToRescaleEv150
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionToPutData.cpp.gcov.html b/coverage/core/ActionToPutData.cpp.gcov.html new file mode 100644 index 000000000000..472a4692d3a2 --- /dev/null +++ b/coverage/core/ActionToPutData.cpp.gcov.html @@ -0,0 +1,260 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionToPutData.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionToPutData.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:9610492.3 %
Date:2024-04-19 12:12:35Functions:1717100.0 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15ActionToPutData8Set_commERNS_12CommunicatorE1
_ZN4PLMD15ActionToPutData8shareAllEv228
_ZNK4PLMD15ActionToPutData6onStepEv3415
_ZN4PLMD15ActionToPutData21castToActionToPutDataEv348304
_ZN4PLMD15ActionToPutData5shareEv742165
_ZN4PLMD15ActionToPutData17resetForStepStartEv753340
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionToPutData.h.func.html b/coverage/core/ActionToPutData.h.func.html new file mode 100644 index 000000000000..35b969f7d8f5 --- /dev/null +++ b/coverage/core/ActionToPutData.h.func.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionToPutData.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionToPutData.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:66100.0 %
Date:2024-04-19 12:12:35Functions:66100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15ActionToPutData17resetForStepStartEv753340
_ZN4PLMD15ActionToPutData21castToActionToPutDataEv348304
_ZN4PLMD15ActionToPutData5shareEv742165
_ZN4PLMD15ActionToPutData8Set_commERNS_12CommunicatorE1
_ZN4PLMD15ActionToPutData8shareAllEv228
_ZNK4PLMD15ActionToPutData6onStepEv3415
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionToPutData.h.gcov.html b/coverage/core/ActionToPutData.h.gcov.html new file mode 100644 index 000000000000..5f2cb9647cd9 --- /dev/null +++ b/coverage/core/ActionToPutData.h.gcov.html @@ -0,0 +1,173 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionToPutData.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionToPutData.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:66100.0 %
Date:2024-04-19 12:12:35Functions:66100.0 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD19ActionWithArguments21expandArgKeywordInPDBERKNS_3PDBE0
_ZN4PLMD19ActionWithArgumentsC1ERKNS_13ActionOptionsE0
_ZN4PLMD19ActionWithArguments24requestExtraDependenciesERKSt6vectorIPNS_5ValueESaIS3_EE4
_ZN4PLMD19ActionWithArguments29calculateNumericalDerivativesEPNS_15ActionWithValueE58
_ZNK4PLMD19ActionWithArguments12setGradientsEPNS_5ValueERj83
_ZN4PLMD19ActionWithArguments17parseArgumentListERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiRSt6vectorIPNS_5ValueESaISB_EE101
_ZNK4PLMD19ActionWithArguments13getProjectionEjj261
_ZN4PLMD19ActionWithArguments17parseArgumentListERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIPNS_5ValueESaISB_EE9560
_ZN4PLMD19ActionWithArgumentsC2ERKNS_13ActionOptionsE9880
_ZN4PLMD19ActionWithArguments16registerKeywordsERNS_8KeywordsE10250
_ZN4PLMD19ActionWithArguments21interpretArgumentListERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EERKNS_9ActionSetEPNS_6ActionERS1_IPNS_5ValueESaISI_EE14757
_ZN4PLMD19ActionWithArguments23calculateConstantValuesERKb17451
_ZN4PLMD19ActionWithArguments16requestArgumentsERKSt6vectorIPNS_5ValueESaIS3_EE185626
_ZN4PLMD19ActionWithArguments20addForcesOnArgumentsERKjRKSt6vectorIdSaIdEERjRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE200163
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionWithArguments.cpp.func.html b/coverage/core/ActionWithArguments.cpp.func.html new file mode 100644 index 000000000000..512151459eaf --- /dev/null +++ b/coverage/core/ActionWithArguments.cpp.func.html @@ -0,0 +1,129 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionWithArguments.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionWithArguments.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:18220588.8 %
Date:2024-04-19 12:12:35Functions:121485.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD19ActionWithArguments16registerKeywordsERNS_8KeywordsE10250
_ZN4PLMD19ActionWithArguments16requestArgumentsERKSt6vectorIPNS_5ValueESaIS3_EE185626
_ZN4PLMD19ActionWithArguments17parseArgumentListERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIPNS_5ValueESaISB_EE9560
_ZN4PLMD19ActionWithArguments17parseArgumentListERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiRSt6vectorIPNS_5ValueESaISB_EE101
_ZN4PLMD19ActionWithArguments20addForcesOnArgumentsERKjRKSt6vectorIdSaIdEERjRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE200163
_ZN4PLMD19ActionWithArguments21expandArgKeywordInPDBERKNS_3PDBE0
_ZN4PLMD19ActionWithArguments21interpretArgumentListERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EERKNS_9ActionSetEPNS_6ActionERS1_IPNS_5ValueESaISI_EE14757
_ZN4PLMD19ActionWithArguments23calculateConstantValuesERKb17451
_ZN4PLMD19ActionWithArguments24requestExtraDependenciesERKSt6vectorIPNS_5ValueESaIS3_EE4
_ZN4PLMD19ActionWithArguments29calculateNumericalDerivativesEPNS_15ActionWithValueE58
_ZN4PLMD19ActionWithArgumentsC1ERKNS_13ActionOptionsE0
_ZN4PLMD19ActionWithArgumentsC2ERKNS_13ActionOptionsE9880
_ZNK4PLMD19ActionWithArguments12setGradientsEPNS_5ValueERj83
_ZNK4PLMD19ActionWithArguments13getProjectionEjj261
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionWithArguments.cpp.gcov.html b/coverage/core/ActionWithArguments.cpp.gcov.html new file mode 100644 index 000000000000..4446385b8874 --- /dev/null +++ b/coverage/core/ActionWithArguments.cpp.gcov.html @@ -0,0 +1,437 @@ + + + + + + + + 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:18220588.8 %
Date:2024-04-19 12:12:35Functions:121485.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 "ActionAtomistic.h"
+      25             : #include "ActionForInterface.h"
+      26             : #include "ActionWithVector.h"
+      27             : #include "ActionWithVirtualAtom.h"
+      28             : #include "ActionShortcut.h"
+      29             : #include "tools/PDB.h"
+      30             : #include "PlumedMain.h"
+      31             : #include "ActionSet.h"
+      32             : #include <iostream>
+      33             : #include <regex>
+      34             : 
+      35             : namespace PLMD {
+      36             : 
+      37       10250 : void ActionWithArguments::registerKeywords(Keywords& keys) {
+      38       20500 :   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 "
+      39             :                "are referenced using the label of the action. If the label appears on its own then it is assumed that the Action calculates "
+      40             :                "a single scalar value.  The value of this scalar is thus used as the input to this new action.  If * or *.* appears the "
+      41             :                "scalars calculated by all the proceeding actions in the input file are taken.  Some actions have multi-component outputs and "
+      42             :                "each component of the output has a specific label.  For example a \\ref DISTANCE action labelled dist may have three components "
+      43             :                "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.*."
+      44             :                "More information on the referencing of Actions can be found in the section of the manual on the PLUMED \\ref Syntax.  "
+      45             :                "Scalar values can also be "
+      46             :                "referenced using POSIX regular expressions as detailed in the section on \\ref Regex. To use this feature you you must compile "
+      47             :                "PLUMED with the appropriate flag.");
+      48       10250 : }
+      49             : 
+      50        9560 : void ActionWithArguments::parseArgumentList(const std::string&key,std::vector<Value*>&arg) {
+      51        9560 :   std::string def; std::vector<std::string> c; arg.clear(); parseVector(key,c);
+      52       10357 :   if( c.size()==0 && (keywords.style(key,"compulsory") || keywords.style(key,"hidden")) ) {
+      53           7 :     if( keywords.getDefaultValue(key,def) ) c.push_back( def );
+      54             :     else return;
+      55             :   }
+      56        9553 :   interpretArgumentList(c,plumed.getActionSet(),this,arg);
+      57        9560 : }
+      58             : 
+      59         101 : bool ActionWithArguments::parseArgumentList(const std::string&key,int i,std::vector<Value*>&arg) {
+      60             :   std::vector<std::string> c;
+      61             :   arg.clear();
+      62         101 :   if(parseNumberedVector(key,i,c)) {
+      63          42 :     interpretArgumentList(c,plumed.getActionSet(),this,arg);
+      64             :     return true;
+      65             :   } else return false;
+      66         101 : }
+      67             : 
+      68       14757 : void ActionWithArguments::interpretArgumentList(const std::vector<std::string>& c, const ActionSet& as, Action* readact, std::vector<Value*>&arg) {
+      69       39874 :   for(unsigned i=0; i<c.size(); i++) {
+      70             :     // is a regex? then just interpret it. The signal is ()
+      71       25120 :     if(!c[i].compare(0,1,"(")) {
+      72         215 :       unsigned l=c[i].length();
+      73         215 :       if(!c[i].compare(l-1,1,")")) {
+      74             :         // start regex parsing
+      75             :         bool found_something=false;
+      76             :         // take the string enclosed in quotes and put in round brackets
+      77         214 :         std::string myregex=c[i];
+      78         214 :         std::vector<ActionWithValue*> all=as.select<ActionWithValue*>();
+      79         215 :         if( all.empty() ) readact->error("your input file is not telling plumed to calculate anything");
+      80             : 
+      81             :         try {
+      82         214 :           std::regex txt_regex(myregex,std::regex::extended);
+      83         213 :           plumed_massert(txt_regex.mark_count()==1,"I can parse with only one subexpression");
+      84       24189 :           for(unsigned j=0; j<all.size(); j++) {
+      85       23976 :             std::vector<std::string> ss=all[j]->getComponentsVector();
+      86      349507 :             for(unsigned  k=0; k<ss.size(); ++k) {
+      87      325531 :               if(std::regex_match(ss[k],txt_regex)) {
+      88       21565 :                 arg.push_back(all[j]->copyOutput(ss[k]));
+      89             :                 found_something=true;
+      90             :               }
+      91             :             }
+      92       23976 :           }
+      93         214 :         } catch(std::regex_error & e) {
+      94           3 :           plumed_error()<<"Error parsing regular expression: "<<e.what();
+      95           1 :         }
+      96         213 :         if(!found_something) plumed_error()<<"There isn't any action matching your regex " << myregex;
+      97             :       } else {
+      98           2 :         plumed_merror("did you want to use regexp to input arguments? enclose it between two round braces (...) with no spaces!");
+      99             :       }
+     100             :     } else {
+     101             :       std::size_t dot=c[i].find_first_of('.');
+     102       24905 :       std::string a=c[i].substr(0,dot);
+     103       24905 :       std::string name=c[i].substr(dot+1);
+     104       24905 :       if(c[i].find(".")!=std::string::npos) {   // if it contains a dot:
+     105        6250 :         if(a=="*" && name=="*") {
+     106             :           // Take all values from all actions
+     107           1 :           std::vector<ActionWithValue*> all=as.select<ActionWithValue*>();
+     108           1 :           if( all.empty() ) readact->error("your input file is not telling plumed to calculate anything");
+     109          17 :           for(unsigned j=0; j<all.size(); j++) {
+     110          16 :             plumed_assert(all[j]); // needed for following calls, see #1046
+     111          16 :             ActionForInterface* ap=all[j]->castToActionForInterface(); if( ap ) continue;
+     112          18 :             for(int k=0; k<all[j]->getNumberOfComponents(); ++k) arg.push_back(all[j]->copyOutput(k));
+     113             :           }
+     114        6240 :         } else if ( name=="*") {
+     115             :           unsigned carg=arg.size();
+     116             :           // Take all the values from an action with a specific name
+     117         574 :           ActionShortcut* shortcut=as.getShortcutActionWithLabel(a);
+     118         941 :           if( shortcut ) shortcut->interpretDataLabel( a + "." + name, readact, arg );
+     119         574 :           if( arg.size()==carg ) {
+     120             :             // Take all the values from an action with a specific name
+     121         361 :             ActionWithValue* action=as.selectWithLabel<ActionWithValue*>(a);
+     122         361 :             if(!action) {
+     123           0 :               std::string str=" (hint! the actions with value in this ActionSet are: ";
+     124           0 :               str+=as.getLabelList<ActionWithValue*>()+")";
+     125           0 :               readact->error("cannot find action named " + a + str);
+     126             :             }
+     127         361 :             if( action->getNumberOfComponents()==0 ) readact->error("found " + a +".* indicating use all components calculated by action with label " + a + " but this action has no components");
+     128        6038 :             for(int k=0; k<action->getNumberOfComponents(); ++k) arg.push_back(action->copyOutput(k));
+     129             :           }
+     130        5666 :         } else if ( a=="*" ) {
+     131           8 :           std::vector<ActionShortcut*> shortcuts=as.select<ActionShortcut*>();
+     132             :           // Take components from all actions with a specific name
+     133           8 :           std::vector<ActionWithValue*> all=as.select<ActionWithValue*>();
+     134           8 :           if( all.empty() ) readact->error("your input file is not telling plumed to calculate anything");
+     135             :           unsigned carg=arg.size();
+     136          79 :           for(unsigned j=0; j<shortcuts.size(); ++j) {
+     137         142 :             shortcuts[j]->interpretDataLabel( shortcuts[j]->getShortcutLabel() + "." + name, readact, arg );
+     138             :           }
+     139             :           unsigned nval=0;
+     140         158 :           for(unsigned j=0; j<all.size(); j++) {
+     141         300 :             std::string flab; flab=all[j]->getLabel() + "." + name;
+     142         150 :             if( all[j]->exists(flab) ) { arg.push_back(all[j]->copyOutput(flab)); nval++; }
+     143             :           }
+     144           8 :           if(nval==0 && arg.size()==carg) readact->error("found no actions with a component called " + name );
+     145             :         } else {
+     146             :           // Take values with a specific name
+     147        5658 :           ActionWithValue* action=as.selectWithLabel<ActionWithValue*>(a);
+     148        5658 :           ActionShortcut* shortcut=as.getShortcutActionWithLabel(a);
+     149        5658 :           if( !shortcut && !action ) {
+     150           0 :             std::string str=" (hint! the actions with value in this ActionSet are: ";
+     151           0 :             str+=as.getLabelList<ActionWithValue*>()+")";
+     152           0 :             readact->error("cannot find action named " + a +str);
+     153        5658 :           } else if( action && action->exists(c[i]) ) {
+     154        5584 :             arg.push_back(action->copyOutput(c[i]));
+     155          74 :           } else if( shortcut ) {
+     156         148 :             unsigned narg=arg.size(); shortcut->interpretDataLabel( a + "." + name, readact, arg );
+     157          74 :             if( arg.size()==narg ) readact->error("found no element in " + a + " with label " + name );
+     158             :           } else {
+     159           0 :             std::string str=" (hint! the components in this actions are: ";
+     160           0 :             str+=action->getComponentsList()+")";
+     161           0 :             readact->error("action " + a + " has no component named " + name + str);
+     162             :           }
+     163             :         }
+     164             :       } else {    // if it doesn't contain a dot
+     165       18664 :         if(c[i]=="*") {
+     166             :           // Take all values from all actions
+     167         106 :           std::vector<ActionWithValue*> all=as.select<ActionWithValue*>();
+     168         106 :           if( all.empty() ) readact->error("your input file is not telling plumed to calculate anything");
+     169        1602 :           for(unsigned j=0; j<all.size(); j++) {
+     170        1496 :             plumed_assert(all[j]); // needed for following calls, see #1046
+     171        1496 :             ActionWithVirtualAtom* av=all[j]->castToActionWithVirtualAtom(); if( av ) continue;
+     172        1439 :             ActionForInterface* ap=all[j]->castToActionForInterface(); if( ap && all[j]->getName()!="ENERGY" ) continue;
+     173        1312 :             for(int k=0; k<all[j]->getNumberOfComponents(); ++k) arg.push_back(all[j]->copyOutput(k));
+     174             :           }
+     175             :         } else {
+     176       18558 :           ActionWithValue* action=as.selectWithLabel<ActionWithValue*>(c[i]);
+     177       18558 :           if(!action) {
+     178           1 :             std::string str=" (hint! the actions with value in this ActionSet are: ";
+     179           2 :             str+=as.getLabelList<ActionWithValue*>()+")";
+     180           3 :             readact->error("cannot find action named " + c[i] + str );
+     181             :           }
+     182       18557 :           if( !(action->exists(c[i])) ) {
+     183           0 :             std::string str=" (hint! the components in this actions are: ";
+     184           0 :             str+=action->getComponentsList()+")";
+     185           0 :             readact->error("action " + c[i] + " has no component named " + c[i] +str);
+     186             :           };
+     187       18558 :           arg.push_back(action->copyOutput(c[i]));
+     188             :         }
+     189             :       }
+     190             :     }
+     191             :   }
+     192       14754 : }
+     193             : 
+     194           0 : void ActionWithArguments::expandArgKeywordInPDB( const PDB& pdb ) {
+     195           0 :   std::vector<std::string> arg_names = pdb.getArgumentNames();
+     196           0 :   if( arg_names.size()>0 ) {
+     197             :     std::vector<Value*> arg_vals;
+     198           0 :     interpretArgumentList( arg_names, plumed.getActionSet(), this, arg_vals );
+     199             :   }
+     200           0 : }
+     201             : 
+     202      185626 : void ActionWithArguments::requestArguments(const std::vector<Value*> &arg) {
+     203      185626 :   plumed_massert(!lockRequestArguments,"requested argument list can only be changed in the prepare() method");
+     204      185626 :   arguments=arg;
+     205      185626 :   clearDependencies();
+     206             :   std::string fullname;
+     207             :   std::string name;
+     208     1274865 :   for(unsigned i=0; i<arguments.size(); i++) {
+     209     1089239 :     fullname=arguments[i]->getName();
+     210     1089239 :     if(fullname.find(".")!=std::string::npos) {
+     211             :       std::size_t dot=fullname.find_first_of('.');
+     212      745278 :       name=fullname.substr(0,dot);
+     213             :     } else {
+     214             :       name=fullname;
+     215             :     }
+     216     1089239 :     ActionWithValue* action=plumed.getActionSet().selectWithLabel<ActionWithValue*>(name);
+     217     1089239 :     plumed_massert(action,"cannot find action named (in requestArguments - this is weird)" + name);
+     218     1089239 :     addDependency(action);
+     219             :   }
+     220      185626 :   ActionWithValue* av=dynamic_cast<ActionWithValue*>(this);
+     221      185626 :   if(av) av->firststep=true;
+     222      185626 : }
+     223             : 
+     224           4 : void ActionWithArguments::requestExtraDependencies(const std::vector<Value*> &extra) {
+     225           4 :   plumed_massert(!lockRequestArguments,"requested argument list can only be changed in the prepare() method");
+     226             :   std::string fullname;
+     227             :   std::string name;
+     228           9 :   for(unsigned i=0; i<extra.size(); i++) {
+     229           5 :     fullname=extra[i]->getName();
+     230           5 :     if(fullname.find(".")!=std::string::npos) {
+     231             :       std::size_t dot=fullname.find_first_of('.');
+     232           0 :       name=fullname.substr(0,dot);
+     233             :     } else {
+     234             :       name=fullname;
+     235             :     }
+     236           5 :     ActionWithValue* action=plumed.getActionSet().selectWithLabel<ActionWithValue*>(name);
+     237           5 :     plumed_massert(action,"cannot find action named (in requestArguments - this is weird)" + name);
+     238           5 :     addDependency(action);
+     239             :   }
+     240           4 : }
+     241             : 
+     242        9880 : ActionWithArguments::ActionWithArguments(const ActionOptions&ao):
+     243             :   Action(ao),
+     244        9880 :   lockRequestArguments(false)
+     245             : {
+     246       19760 :   if( keywords.exists("ARG") ) {
+     247             :     std::vector<Value*> arg;
+     248       18438 :     parseArgumentList("ARG",arg);
+     249             : 
+     250        9219 :     if(!arg.empty()) {
+     251        8944 :       log.printf("  with arguments : \n");
+     252       44475 :       for(unsigned i=0; i<arg.size(); i++) {
+     253       35531 :         if( arg[i]->hasDerivatives() && arg[i]->getRank()>0 ) log.printf(" function on grid with label %s \n",arg[i]->getName().c_str());
+     254       34525 :         else if( arg[i]->getRank()==2 ) log.printf("   matrix with label %s \n",arg[i]->getName().c_str());
+     255       31945 :         else if( arg[i]->getRank()==1 ) log.printf("   vector with label %s \n",arg[i]->getName().c_str());
+     256       25887 :         else if( arg[i]->getRank()==0 ) log.printf("   scalar with label %s \n",arg[i]->getName().c_str());
+     257           0 :         else error("type of argument does not make sense");
+     258             :       }
+     259             :     }
+     260        9219 :     requestArguments(arg);
+     261             :   }
+     262        9880 : }
+     263             : 
+     264          58 : void ActionWithArguments::calculateNumericalDerivatives( ActionWithValue* a ) {
+     265          58 :   if(!a) {
+     266          58 :     a=castToActionWithValue();
+     267          58 :     plumed_massert(a,"cannot compute numerical derivatives for an action without values");
+     268             :   }
+     269             : 
+     270          58 :   const size_t nval=a->getNumberOfComponents();
+     271             :   const size_t npar=arguments.size();
+     272          58 :   std::vector<double> value (nval*npar);
+     273         161 :   for(int i=0; i<npar; i++) {
+     274         103 :     double arg0=arguments[i]->get();
+     275         103 :     arguments[i]->set(arg0+std::sqrt(epsilon));
+     276         103 :     a->calculate();
+     277         103 :     arguments[i]->set(arg0);
+     278        1367 :     for(int j=0; j<nval; j++) {
+     279        1264 :       value[i*nval+j]=a->getOutputQuantity(j);
+     280             :     }
+     281             :   }
+     282          58 :   a->calculate();
+     283          58 :   a->clearDerivatives();
+     284        1192 :   for(int j=0; j<nval; j++) {
+     285        1134 :     Value* v=a->copyOutput(j);
+     286        1804 :     if( v->hasDerivatives() ) for(int i=0; i<npar; i++) v->addDerivative(i,(value[i*nval+j]-a->getOutputQuantity(j))/std::sqrt(epsilon));
+     287             :   }
+     288          58 : }
+     289             : 
+     290         261 : double ActionWithArguments::getProjection(unsigned i,unsigned j)const {
+     291         261 :   plumed_massert(i<arguments.size()," making projections with an index which  is too large");
+     292         261 :   plumed_massert(j<arguments.size()," making projections with an index which  is too large");
+     293         261 :   const Value* v1=arguments[i];
+     294         261 :   const Value* v2=arguments[j];
+     295         261 :   return Value::projection(*v1,*v2);
+     296             : }
+     297             : 
+     298      200163 : void ActionWithArguments::addForcesOnArguments( const unsigned& argstart, const std::vector<double>& forces, unsigned& ind, const std::string& c  ) {
+     299      526491 :   for(unsigned i=0; i<arguments.size(); ++i) {
+     300      326328 :     if( i==0 && getName().find("EVALUATE_FUNCTION_FROM_GRID")!=std::string::npos ) continue ;
+     301      322978 :     if( !arguments[i]->ignoreStoredValue(c) || arguments[i]->getRank()==0 || (arguments[i]->getRank()>0 && arguments[i]->hasDerivatives()) ) {
+     302      300623 :       unsigned nvals = arguments[i]->getNumberOfValues();
+     303    34171375 :       for(unsigned j=0; j<nvals; ++j) { arguments[i]->addForce( j, forces[ind] ); ind++; }
+     304             :     }
+     305             :   }
+     306      200163 : }
+     307             : 
+     308          83 : void ActionWithArguments::setGradients( Value* myval, unsigned& start ) const {
+     309          83 :   if( !myval->hasDeriv ) return; plumed_assert( myval->getRank()==0 );
+     310             : 
+     311             :   bool scalar=true;
+     312         249 :   for(unsigned i=0; i<arguments.size(); ++i ) {
+     313         166 :     if( arguments[i]->getRank()!=0 ) { scalar=false; break; }
+     314             :   }
+     315          83 :   if( !scalar ) {
+     316             :     bool constant=true;
+     317           0 :     for(unsigned i=0; i<arguments.size(); ++i ) {
+     318           0 :       if( !arguments[i]->isConstant() ) { constant=false; break; }
+     319           0 :       else start += arguments[i]->getNumberOfValues();
+     320             :     }
+     321           0 :     if( !constant ) error("cannot set gradient as unable to handle non-constant actions that take vectors/matrices/grids in input");
+     322             :   }
+     323             :   // Now pass the gradients
+     324         249 :   for(unsigned i=0; i<arguments.size(); ++i ) arguments[i]->passGradients( myval->getDerivative(i), myval->gradients );
+     325             : }
+     326             : 
+     327       17451 : bool ActionWithArguments::calculateConstantValues( const bool& haveatoms ) {
+     328       17451 :   ActionWithValue* av = castToActionWithValue();
+     329       17451 :   if( !av || arguments.size()==0 ) return false;
+     330             :   bool constant = true, atoms=false;
+     331       14437 :   for(unsigned i=0; i<arguments.size(); ++i) {
+     332       13329 :     auto * ptr=arguments[i]->getPntrToAction();
+     333       13329 :     plumed_assert(ptr); // needed for following calls, see #1046
+     334       13329 :     ActionAtomistic* aa=ptr->castToActionAtomistic();
+     335       13329 :     if( aa ) {
+     336       10441 :       ActionWithVector* av=dynamic_cast<ActionWithVector*>( arguments[i]->getPntrToAction() );
+     337       10441 :       if( !av || aa->getNumberOfAtoms()>0 ) atoms=true;
+     338             :     }
+     339       13329 :     if( !arguments[i]->isConstant() ) { constant=false; break; }
+     340             :   }
+     341       13081 :   if( constant ) {
+     342             :     // Set everything constant first as we need to set the shape
+     343        2240 :     for(unsigned i=0; i<av->getNumberOfComponents(); ++i) (av->copyOutput(i))->setConstant();
+     344        1108 :     if( !haveatoms ) log.printf("  values stored by this action are computed during startup and stay fixed during the simulation\n");
+     345        1108 :     if( atoms ) return haveatoms;
+     346             :   }
+     347             :   // Now do the calculation and store the values if we don't need anything from the atoms
+     348       13045 :   if( constant && !haveatoms ) {
+     349        1072 :     plumed_assert( !atoms ); activate(); calculate(); deactivate();
+     350        2168 :     for(unsigned i=0; i<av->getNumberOfComponents(); ++i) {
+     351        1096 :       unsigned nv = av->copyOutput(i)->getNumberOfValues();
+     352        1096 :       log.printf("  %d values stored in component labelled %s are : ", nv, (av->copyOutput(i))->getName().c_str() );
+     353        3923 :       for(unsigned j=0; j<nv; ++j) log.printf(" %f", (av->copyOutput(i))->get(j) );
+     354        1096 :       log.printf("\n");
+     355             :     }
+     356             :   }
+     357             :   return constant;
+     358             : }
+     359             : 
+     360             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionWithArguments.h.func-sort-c.html b/coverage/core/ActionWithArguments.h.func-sort-c.html new file mode 100644 index 000000000000..cf17ec72e8aa --- /dev/null +++ b/coverage/core/ActionWithArguments.h.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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:1717100.0 %
Date:2024-04-19 12:12:35Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD19ActionWithArgumentsD2Ev9880
_ZN4PLMD19ActionWithArguments25castToActionWithArgumentsEv20359
_ZNK4PLMD19ActionWithArguments12getArgumentsEv186244
_ZNK4PLMD19ActionWithArguments11getArgumentEj205207
_ZN4PLMD19ActionWithArguments12lockRequestsEv675763
_ZN4PLMD19ActionWithArguments14unlockRequestsEv675763
_ZNK4PLMD19ActionWithArguments20getNumberOfArgumentsEv596683180
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionWithArguments.h.func.html b/coverage/core/ActionWithArguments.h.func.html new file mode 100644 index 000000000000..45e02a8a2002 --- /dev/null +++ b/coverage/core/ActionWithArguments.h.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:1717100.0 %
Date:2024-04-19 12:12:35Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD19ActionWithArguments12lockRequestsEv675763
_ZN4PLMD19ActionWithArguments14unlockRequestsEv675763
_ZN4PLMD19ActionWithArguments25castToActionWithArgumentsEv20359
_ZN4PLMD19ActionWithArgumentsD2Ev9880
_ZNK4PLMD19ActionWithArguments11getArgumentEj205207
_ZNK4PLMD19ActionWithArguments12getArgumentsEv186244
_ZNK4PLMD19ActionWithArguments20getNumberOfArgumentsEv596683180
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionWithArguments.h.gcov.html b/coverage/core/ActionWithArguments.h.gcov.html new file mode 100644 index 000000000000..9f52f259b2c5 --- /dev/null +++ b/coverage/core/ActionWithArguments.h.gcov.html @@ -0,0 +1,216 @@ + + + + + + + + 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:1717100.0 %
Date:2024-04-19 12:12:35Functions: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_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 ActionSet;
+      43             : 
+      44             : class ActionWithArguments:
+      45             :   public virtual Action
+      46             : {
+      47             :   std::vector<Value*> arguments;
+      48             :   bool lockRequestArguments;
+      49             : protected:
+      50             : /// This changes the arg keyword in the pdb file
+      51             :   void expandArgKeywordInPDB( const PDB& pdb );
+      52             : public:
+      53             : /// Get the scalar product between the gradients of two variables
+      54             :   double getProjection(unsigned i,unsigned j)const;
+      55             : /// Registers the list of keywords
+      56             :   static void registerKeywords( Keywords& keys );
+      57             : /// Returns the value of an argument
+      58             :   double getArgument( const unsigned n ) const;
+      59             : /// Return a pointer to specific argument
+      60             :   Value* getPntrToArgument( const unsigned n ) const;
+      61             : /// Returns the number of arguments
+      62             :   virtual unsigned getNumberOfArguments() const ;
+      63             : /// Takes the difference taking into account pbc for arg i
+      64             :   double difference(int, double, double) const;
+      65             : /// Takes one value and brings it back into the pbc of argument i
+      66             :   double bringBackInPbc(int i,double d1)const;
+      67             : /// Parse a list of arguments
+      68             :   void parseArgumentList(const std::string&key,std::vector<Value*>&args);
+      69             : /// Parse a numbered list of arguments
+      70             :   bool parseArgumentList(const std::string&key,int i,std::vector<Value*>&args);
+      71             : /// Setup the dependencies
+      72             :   void requestArguments(const std::vector<Value*> &arg);
+      73             :   void requestExtraDependencies(const std::vector<Value*> &extra);
+      74             : /// Add forces to arguments (used in apply)
+      75             :   void addForcesOnArguments( const unsigned& argstart, const std::vector<double>& forces, unsigned& ind, const std::string& c );
+      76             : public:
+      77             :   explicit ActionWithArguments(const ActionOptions&);
+      78        9880 :   virtual ~ActionWithArguments() {}
+      79             : /// Calculate the numerical derivatives
+      80             : /// N.B. only pass an ActionWithValue to this routine if you know exactly what you
+      81             : /// are doing.  The default will be correct for the vast majority of cases
+      82             :   void calculateNumericalDerivatives( ActionWithValue* a=NULL ) override;
+      83             :   void lockRequests() override;
+      84             :   void unlockRequests() override;
+      85             : /// Returns an array of pointers to the arguments
+      86             :   virtual const std::vector<Value*>    & getArguments() const ;
+      87             : /// Convert a list of argument names into a list of pointers to the values
+      88             :   static void interpretArgumentList(const std::vector<std::string>& c, const ActionSet& as, Action* action, std::vector<Value*>&arg);
+      89             : /// Used to calculate constant values in startup
+      90             :   virtual bool calculateConstantValues( const bool& have_atoms );
+      91             : /// Get the gradient for this action
+      92             :   void setGradients( Value* myval, unsigned& start ) const ;
+      93       20359 :   ActionWithArguments* castToActionWithArguments() noexcept final { return this; }
+      94             : };
+      95             : 
+      96             : 
+      97             : inline
+      98             : Value* ActionWithArguments::getPntrToArgument( const unsigned n ) const {
+      99  1049652352 :   return arguments[n];
+     100             : }
+     101             : 
+     102             : inline
+     103      205207 : double ActionWithArguments::getArgument(const unsigned n) const {
+     104      205207 :   return arguments[n]->get();
+     105             : }
+     106             : 
+     107             : inline
+     108   596683180 : unsigned ActionWithArguments::getNumberOfArguments()const {
+     109   596718475 :   return arguments.size();
+     110             : }
+     111             : 
+     112             : inline
+     113             : double ActionWithArguments::difference(int i,double d1,double d2)const {
+     114    11458801 :   return arguments[i]->difference(d1,d2);
+     115             : }
+     116             : 
+     117             : inline
+     118             : double ActionWithArguments::bringBackInPbc(int i,double d1)const {
+     119        1427 :   return arguments[i]->bringBackInPbc(d1);
+     120             : }
+     121             : 
+     122             : inline
+     123      675763 : void ActionWithArguments::lockRequests() {
+     124      958990 :   lockRequestArguments=true;
+     125      675763 : }
+     126             : 
+     127             : inline
+     128      675763 : void ActionWithArguments::unlockRequests() {
+     129      958990 :   lockRequestArguments=false;
+     130      675763 : }
+     131             : 
+     132             : inline
+     133      186244 : const std::vector<Value*> & ActionWithArguments::getArguments() const {
+     134      186671 :   return arguments;
+     135             : }
+     136             : 
+     137             : }
+     138             : 
+     139             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionWithValue.cpp.func-sort-c.html b/coverage/core/ActionWithValue.cpp.func-sort-c.html new file mode 100644 index 000000000000..ae07f6501411 --- /dev/null +++ b/coverage/core/ActionWithValue.cpp.func-sort-c.html @@ -0,0 +1,205 @@ + + + + + + + + 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:15116492.1 %
Date:2024-04-19 12:12:35Functions:283384.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15ActionWithValue23noAnalyticalDerivativesERNS_8KeywordsE0
_ZN4PLMD15ActionWithValueC1ERKNS_13ActionOptionsE0
_ZN4PLMD15ActionWithValueD0Ev0
_ZN4PLMD15ActionWithValueD1Ev0
_ZNK4PLMD15ActionWithValue17getComponentsListB5cxx11Ev0
_ZNK4PLMD15ActionWithValue21getMatrixColumnTitlesERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EE19
_ZN4PLMD15ActionWithValue19componentIsPeriodicERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_S8_137
_ZN4PLMD15ActionWithValue25useCustomisableComponentsERNS_8KeywordsE565
_ZN4PLMD15ActionWithValue11setPeriodicERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_798
_ZN4PLMD15ActionWithValue24componentsAreNotOptionalERNS_8KeywordsE1644
_ZN4PLMD15ActionWithValue23addValueWithDerivativesERKSt6vectorIjSaIjEE4974
_ZN4PLMD15ActionWithValue8addValueERKSt6vectorIjSaIjEE12019
_ZN4PLMD15ActionWithValue14setNotPeriodicEv16194
_ZN4PLMD15ActionWithValue16registerKeywordsERNS_8KeywordsE21207
_ZNK4PLMD15ActionWithValue19getComponentsVectorB5cxx11Ev24029
_ZN4PLMD15ActionWithValueC2ERKNS_13ActionOptionsE30276
_ZN4PLMD15ActionWithValueD2Ev30276
_ZN4PLMD15ActionWithValue27addComponentWithDerivativesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIjSaIjEE41911
_ZN4PLMD15ActionWithValue12addComponentERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIjSaIjEE45867
_ZN4PLMD15ActionWithValue22componentIsNotPeriodicERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE84560
_ZN4PLMD15ActionWithValue14checkForForcesEv497871
_ZNK4PLMD15ActionWithValue10copyOutputERKj1085271
_ZN4PLMD15ActionWithValue17turnOnDerivativesEv1636576
_ZN4PLMD15ActionWithValue20setGradientsIfNeededEv1850573
_ZN4PLMD15ActionWithValue16clearDerivativesERKb1885239
_ZN4PLMD15ActionWithValue16clearInputForcesERKb2403731
_ZN4PLMD15ActionWithValue17calculateOnUpdateEv4604793
_ZN4PLMD15ActionWithValue18getPntrToComponentERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE10602425
_ZNK4PLMD15ActionWithValue12getComponentERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE10687122
_ZNK4PLMD15ActionWithValue6existsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE10711705
_ZNK4PLMD15ActionWithValue10copyOutputERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE33604668
_ZN4PLMD15ActionWithValue18getPntrToComponentEi87155539
_ZNK4PLMD15ActionWithValue23getConstPntrToComponentEi1450184588
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionWithValue.cpp.func.html b/coverage/core/ActionWithValue.cpp.func.html new file mode 100644 index 000000000000..4cc5f8caafd5 --- /dev/null +++ b/coverage/core/ActionWithValue.cpp.func.html @@ -0,0 +1,205 @@ + + + + + + + + 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:15116492.1 %
Date:2024-04-19 12:12:35Functions:283384.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15ActionWithValue11setPeriodicERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_798
_ZN4PLMD15ActionWithValue12addComponentERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIjSaIjEE45867
_ZN4PLMD15ActionWithValue14checkForForcesEv497871
_ZN4PLMD15ActionWithValue14setNotPeriodicEv16194
_ZN4PLMD15ActionWithValue16clearDerivativesERKb1885239
_ZN4PLMD15ActionWithValue16clearInputForcesERKb2403731
_ZN4PLMD15ActionWithValue16registerKeywordsERNS_8KeywordsE21207
_ZN4PLMD15ActionWithValue17calculateOnUpdateEv4604793
_ZN4PLMD15ActionWithValue17turnOnDerivativesEv1636576
_ZN4PLMD15ActionWithValue18getPntrToComponentERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE10602425
_ZN4PLMD15ActionWithValue18getPntrToComponentEi87155539
_ZN4PLMD15ActionWithValue19componentIsPeriodicERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_S8_137
_ZN4PLMD15ActionWithValue20setGradientsIfNeededEv1850573
_ZN4PLMD15ActionWithValue22componentIsNotPeriodicERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE84560
_ZN4PLMD15ActionWithValue23addValueWithDerivativesERKSt6vectorIjSaIjEE4974
_ZN4PLMD15ActionWithValue23noAnalyticalDerivativesERNS_8KeywordsE0
_ZN4PLMD15ActionWithValue24componentsAreNotOptionalERNS_8KeywordsE1644
_ZN4PLMD15ActionWithValue25useCustomisableComponentsERNS_8KeywordsE565
_ZN4PLMD15ActionWithValue27addComponentWithDerivativesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIjSaIjEE41911
_ZN4PLMD15ActionWithValue8addValueERKSt6vectorIjSaIjEE12019
_ZN4PLMD15ActionWithValueC1ERKNS_13ActionOptionsE0
_ZN4PLMD15ActionWithValueC2ERKNS_13ActionOptionsE30276
_ZN4PLMD15ActionWithValueD0Ev0
_ZN4PLMD15ActionWithValueD1Ev0
_ZN4PLMD15ActionWithValueD2Ev30276
_ZNK4PLMD15ActionWithValue10copyOutputERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE33604668
_ZNK4PLMD15ActionWithValue10copyOutputERKj1085271
_ZNK4PLMD15ActionWithValue12getComponentERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE10687122
_ZNK4PLMD15ActionWithValue17getComponentsListB5cxx11Ev0
_ZNK4PLMD15ActionWithValue19getComponentsVectorB5cxx11Ev24029
_ZNK4PLMD15ActionWithValue21getMatrixColumnTitlesERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EE19
_ZNK4PLMD15ActionWithValue23getConstPntrToComponentEi1450184588
_ZNK4PLMD15ActionWithValue6existsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE10711705
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionWithValue.cpp.gcov.html b/coverage/core/ActionWithValue.cpp.gcov.html new file mode 100644 index 000000000000..b7558709c46d --- /dev/null +++ b/coverage/core/ActionWithValue.cpp.gcov.html @@ -0,0 +1,410 @@ + + + + + + + + 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:15116492.1 %
Date:2024-04-19 12:12:35Functions:283384.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 "ActionWithValue.h"
+      23             : #include "ActionWithArguments.h"
+      24             : #include "ActionAtomistic.h"
+      25             : #include "tools/Exception.h"
+      26             : #include "tools/OpenMP.h"
+      27             : #include "tools/Communicator.h"
+      28             : #include "blas/blas.h"
+      29             : 
+      30             : namespace PLMD {
+      31             : 
+      32       21207 : void ActionWithValue::registerKeywords(Keywords& keys) {
+      33       21207 :   keys.setComponentsIntroduction("By default the value of the calculated quantity can be referenced elsewhere in the "
+      34             :                                  "input file by using the label of the action.  Alternatively this Action can be used "
+      35             :                                  "to calculate the following quantities by employing the keywords listed "
+      36             :                                  "below.  These quantities can be referenced elsewhere in the input by using this Action's "
+      37             :                                  "label followed by a dot and the name of the quantity required from the list below.");
+      38       42414 :   keys.addFlag("NUMERICAL_DERIVATIVES", false, "calculate the derivatives for these quantities numerically");
+      39       42414 :   keys.add("hidden","HAS_VALUES","this is used in json output to determine those actions that have values");
+      40       21207 : }
+      41             : 
+      42           0 : void ActionWithValue::noAnalyticalDerivatives(Keywords& keys) {
+      43           0 :   keys.remove("NUMERICAL_DERIVATIVES");
+      44           0 :   keys.addFlag("NUMERICAL_DERIVATIVES",false,"analytical derivatives are not implemented for this keyword so numerical derivatives are always used");
+      45           0 : }
+      46             : 
+      47        1644 : void ActionWithValue::componentsAreNotOptional(Keywords& keys) {
+      48        1644 :   keys.setComponentsIntroduction("By default this Action calculates the following quantities. These quantities can "
+      49             :                                  "be referenced elsewhere in the input by using this Action's label followed by a "
+      50             :                                  "dot and the name of the quantity required from the list below.");
+      51        1644 : }
+      52             : 
+      53         565 : void ActionWithValue::useCustomisableComponents(Keywords& keys) {
+      54         565 :   keys.setComponentsIntroduction("The names of the components in this action can be customized by the user in the "
+      55             :                                  "actions input file.  However, in addition to the components that can be customized the "
+      56             :                                  "following quantities will always be output");
+      57         565 : }
+      58             : 
+      59       30276 : ActionWithValue::ActionWithValue(const ActionOptions&ao):
+      60             :   Action(ao),
+      61       30276 :   firststep(true),
+      62       30276 :   noderiv(true),
+      63       30276 :   numericalDerivatives(false)
+      64             : {
+      65       75666 :   if( keywords.exists("NUMERICAL_DERIVATIVES") ) parseFlag("NUMERICAL_DERIVATIVES",numericalDerivatives);
+      66       60552 :   if(!keywords.exists("NO_ACTION_LOG") && numericalDerivatives) log.printf("  using numerical derivatives\n");
+      67       30276 : }
+      68             : 
+      69       30276 : ActionWithValue::~ActionWithValue() {
+      70             : // empty destructor to delete unique_ptr
+      71       30276 : }
+      72             : 
+      73     2403731 : void ActionWithValue::clearInputForces( const bool& force ) {
+      74     5649411 :   for(unsigned i=0; i<values.size(); i++) values[i]->clearInputForce();
+      75     2403731 : }
+      76             : 
+      77     1885239 : void ActionWithValue::clearDerivatives( const bool& force ) {
+      78     1885239 :   unsigned nt = OpenMP::getNumThreads();
+      79     1885239 :   #pragma omp parallel num_threads(nt)
+      80             :   {
+      81             :     #pragma omp for
+      82             :     for(unsigned i=0; i<values.size(); i++) values[i]->clearDerivatives();
+      83             :   }
+      84     1885239 : }
+      85             : 
+      86             : // -- These are the routine for copying the value pointers to other classes -- //
+      87             : 
+      88    10711705 : bool ActionWithValue::exists( const std::string& name ) const {
+      89   101765698 :   for(unsigned i=0; i<values.size(); ++i) {
+      90    91078161 :     if (values[i]->name==name) return true;
+      91             :   }
+      92             :   return false;
+      93             : }
+      94             : 
+      95          19 : void ActionWithValue::getMatrixColumnTitles( std::vector<std::string>& argnames ) const {
+      96          19 :   plumed_assert( getNumberOfComponents()==1 && getConstPntrToComponent(0)->getRank()==2 );
+      97          19 :   unsigned nargs = getConstPntrToComponent(0)->getShape()[1]; std::string aname = getConstPntrToComponent(0)->getName();
+      98         393 :   for(unsigned j=0; j<nargs; ++j) { std::string nn; Tools::convert( j+1, nn ); argnames.push_back( aname + "." + nn ); }
+      99          19 : }
+     100             : 
+     101    33604668 : Value* ActionWithValue::copyOutput( const std::string& name ) const {
+     102   112034814 :   for(unsigned i=0; i<values.size(); ++i) {
+     103   112034814 :     if (values[i]->name==name) return values[i].get();
+     104             :   }
+     105           0 :   plumed_merror("there is no pointer with name " + name);
+     106             : }
+     107             : 
+     108     1085271 : Value* ActionWithValue::copyOutput( const unsigned& n ) const {
+     109     1085271 :   plumed_massert(n<values.size(),"you have requested a pointer that is out of bounds");
+     110     1085271 :   return values[n].get();
+     111             : }
+     112             : 
+     113             : // -- HERE WE HAVE THE STUFF FOR THE DEFAULT VALUE -- //
+     114             : 
+     115       12019 : void ActionWithValue::addValue( const std::vector<unsigned>& shape ) {
+     116       12019 :   plumed_massert(values.empty(),"You have already added the default value for this action");
+     117       12019 :   values.emplace_back(Tools::make_unique<Value>(this,getLabel(), false, shape ) );
+     118       12019 : }
+     119             : 
+     120        4974 : void ActionWithValue::addValueWithDerivatives( const std::vector<unsigned>& shape ) {
+     121        4974 :   plumed_massert(values.empty(),"You have already added the default value for this action");
+     122        4974 :   values.emplace_back(Tools::make_unique<Value>(this,getLabel(), true, shape ) );
+     123        4974 : }
+     124             : 
+     125       16194 : void ActionWithValue::setNotPeriodic() {
+     126       16194 :   plumed_massert(values.size()==1,"The number of components is not equal to one");
+     127       16194 :   plumed_massert(values[0]->name==getLabel(), "The value you are trying to set is not the default");
+     128       16194 :   values[0]->min=0; values[0]->max=0;
+     129       16194 :   values[0]->setupPeriodicity();
+     130       16194 : }
+     131             : 
+     132         798 : void ActionWithValue::setPeriodic( const std::string& min, const std::string& max ) {
+     133         798 :   plumed_massert(values.size()==1,"The number of components is not equal to one");
+     134         798 :   plumed_massert(values[0]->name==getLabel(), "The value you are trying to set is not the default");
+     135         798 :   values[0]->setDomain( min, max );
+     136         798 : }
+     137             : 
+     138             : // -- HERE WE HAVE THE STUFF FOR NAMED VALUES / COMPONENTS -- //
+     139             : 
+     140       45867 : void ActionWithValue::addComponent( const std::string& name, const std::vector<unsigned>& shape ) {
+     141       45867 :   if( !keywords.outputComponentExists(name,true) ) {
+     142           0 :     plumed_merror("a description of component " + name + " has not been added to the manual. Components should be registered like keywords in "
+     143             :                   "registerKeywords as described in the developer docs.");
+     144             :   }
+     145       91734 :   std::string thename; thename=getLabel() + "." + name;
+     146    18798039 :   for(unsigned i=0; i<values.size(); ++i) {
+     147    18752172 :     plumed_massert(values[i]->name!=getLabel(),"Cannot mix single values with components");
+     148    18752172 :     plumed_massert(values[i]->name!=thename,"there is already a value with this name: "+thename);
+     149    18752172 :     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"
+     150             :                    "Remove the line addComponent(\"bias\") from your bias.");
+     151             :   }
+     152       45867 :   values.emplace_back(Tools::make_unique<Value>(this,thename, false, shape ) );
+     153       45867 :   std::string msg="  added component to this action:  "+thename+" \n";
+     154       45867 :   log.printf(msg.c_str());
+     155       45867 : }
+     156             : 
+     157       41911 : void ActionWithValue::addComponentWithDerivatives( const std::string& name, const std::vector<unsigned>& shape ) {
+     158       41911 :   if( !keywords.outputComponentExists(name,true) ) {
+     159           0 :     plumed_merror("a description of component " + name + " has not been added to the manual. Components should be registered like keywords in "
+     160             :                   "registerKeywords as described in the developer doc.");
+     161             :   }
+     162       83822 :   std::string thename; thename=getLabel() + "." + name;
+     163     2504539 :   for(unsigned i=0; i<values.size(); ++i) {
+     164     2462628 :     plumed_massert(values[i]->name!=getLabel(),"Cannot mix single values with components");
+     165     2462628 :     plumed_massert(values[i]->name!=thename,"there is already a value with this name: "+thename);
+     166     2462628 :     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"
+     167             :                    "Remove the line addComponentWithDerivatives(\"bias\") from your bias.");
+     168             :   }
+     169       41911 :   values.emplace_back(Tools::make_unique<Value>(this,thename, true, shape ) );
+     170       41911 :   std::string msg="  added component to this action:  "+thename+" \n";
+     171       41911 :   log.printf(msg.c_str());
+     172       41911 : }
+     173             : 
+     174    10687122 : int ActionWithValue::getComponent( const std::string& name ) const {
+     175    10687122 :   plumed_massert( !exists( getLabel() ), "You should not be calling this routine if you are using a value");
+     176    21374244 :   std::string thename; thename=getLabel() + "." + name;
+     177    64345802 :   for(unsigned i=0; i<values.size(); ++i) {
+     178    64345802 :     if (values[i]->name==thename) return i;
+     179             :   }
+     180           0 :   plumed_merror("there is no component with name " + name);
+     181             : }
+     182             : 
+     183           0 : std::string ActionWithValue::getComponentsList( ) const {
+     184             :   std::string complist;
+     185           0 :   for(unsigned i=0; i<values.size(); ++i) {
+     186           0 :     complist+=values[i]->name+" ";
+     187             :   }
+     188           0 :   return complist;
+     189             : }
+     190             : 
+     191       24029 : std::vector<std::string> ActionWithValue::getComponentsVector( ) const {
+     192             :   std::vector<std::string> complist;
+     193      349645 :   for(unsigned i=0; i<values.size(); ++i) {
+     194      325616 :     complist.push_back(values[i]->name);
+     195             :   }
+     196       24029 :   return complist;
+     197           0 : }
+     198             : 
+     199       84560 : void ActionWithValue::componentIsNotPeriodic( const std::string& name ) {
+     200       84560 :   int kk=getComponent(name);
+     201       84560 :   values[kk]->min=0; values[kk]->max=0;
+     202       84560 :   values[kk]->setupPeriodicity();
+     203       84560 : }
+     204             : 
+     205         137 : void ActionWithValue::componentIsPeriodic( const std::string& name, const std::string& min, const std::string& max ) {
+     206         137 :   int kk=getComponent(name);
+     207         137 :   values[kk]->setDomain(min,max);
+     208         137 : }
+     209             : 
+     210     1850573 : void ActionWithValue::setGradientsIfNeeded() {
+     211     3701146 :   if(isOptionOn("GRADIENTS")) {
+     212         201 :     ActionAtomistic* aa=castToActionAtomistic();
+     213         201 :     if(aa) {
+     214         308 :       for(unsigned i=0; i<values.size(); i++) { unsigned start=0; values[i]->gradients.clear(); values[i]->setGradients( aa, start ); }
+     215             :     } else {
+     216          83 :       ActionWithArguments* aarg = castToActionWithArguments();
+     217          83 :       if( !aarg ) plumed_merror( "failing in " + getLabel() );
+     218         166 :       for(unsigned i=0; i<values.size(); i++) { unsigned start=0; values[i]->gradients.clear(); aarg->setGradients( values[i].get(), start ); }
+     219             :     }
+     220             :   }
+     221     1850573 : }
+     222             : 
+     223     1636576 : void ActionWithValue::turnOnDerivatives() {
+     224             :   // Turn on the derivatives
+     225     1636576 :   noderiv=false;
+     226             :   // Resize the derivatives
+     227     5987667 :   for(unsigned i=0; i<values.size(); ++i) values[i]->resizeDerivatives( getNumberOfDerivatives() );
+     228             :   // And turn on the derivatives in all actions on which we are dependent
+     229     3267457 :   for(unsigned i=0; i<getDependencies().size(); ++i) {
+     230     1630881 :     ActionWithValue* vv=getDependencies()[i]->castToActionWithValue();
+     231     1630881 :     if(vv) vv->turnOnDerivatives();
+     232             :   }
+     233     1636576 : }
+     234             : 
+     235    10602425 : Value* ActionWithValue::getPntrToComponent( const std::string& name ) {
+     236    10602425 :   int kk=getComponent(name);
+     237    10602425 :   return values[kk].get();
+     238             : }
+     239             : 
+     240  1450184588 : const Value* ActionWithValue::getConstPntrToComponent(int n) const {
+     241             :   plumed_dbg_massert(n<values.size(),"you have requested a pointer that is out of bounds");
+     242  1450184588 :   return values[n].get();
+     243             : }
+     244             : 
+     245    87155539 : Value* ActionWithValue::getPntrToComponent( int n ) {
+     246             :   plumed_dbg_massert(n<values.size(),"you have requested a pointer that is out of bounds");
+     247    87155539 :   return values[n].get();
+     248             : }
+     249             : 
+     250     4604793 : bool ActionWithValue::calculateOnUpdate() {
+     251     4604793 :   if( firststep ) {
+     252      205299 :     ActionWithArguments* aa=dynamic_cast<ActionWithArguments*>(this);
+     253      205299 :     if(aa) {
+     254      183849 :       const std::vector<Value*> & args(aa->getArguments());
+     255     1261336 :       for(const auto & p : args ) {
+     256     1077896 :         if( p->calculateOnUpdate() ) {
+     257         859 :           for(unsigned i=0; i<values.size(); ++i) values[i]->setValType("calcFromAverage");
+     258             :           break;
+     259             :         }
+     260             :       }
+     261             :     }
+     262      205299 :     firststep=false;
+     263             :   }
+     264    11022510 :   for(unsigned i=0; i<values.size(); ++i) {
+     265     6426561 :     if( values[i]->calculateOnUpdate() ) return true;
+     266             :   }
+     267             :   return false;
+     268             : }
+     269             : 
+     270      497871 : bool ActionWithValue::checkForForces() {
+     271      497871 :   const unsigned    ncp=getNumberOfComponents();
+     272      497871 :   unsigned    nder=getNumberOfDerivatives();
+     273      497871 :   if( ncp==0 || nder==0 ) return false;
+     274             : 
+     275             :   unsigned nvalsWithForce=0;
+     276      496725 :   valsToForce.resize(ncp);
+     277     1392328 :   for(unsigned i=0; i<ncp; ++i) {
+     278      895603 :     if( values[i]->hasForce && !values[i]->isConstant() ) {
+     279      287740 :       valsToForce[nvalsWithForce]=i; nvalsWithForce++;
+     280             :     }
+     281             :   }
+     282      496725 :   if( nvalsWithForce==0 ) return false;
+     283             : 
+     284             :   // Make sure forces to apply is empty of forces
+     285      237005 :   if( forcesForApply.size()!=nder ) forcesForApply.resize( nder );
+     286             :   std::fill(forcesForApply.begin(),forcesForApply.end(),0);
+     287             : 
+     288             :   unsigned stride=1;
+     289             :   unsigned rank=0;
+     290      237005 :   if(ncp>4*comm.Get_size()) {
+     291       22968 :     stride=comm.Get_size();
+     292       22968 :     rank=comm.Get_rank();
+     293             :   }
+     294             : 
+     295      237005 :   unsigned nt=OpenMP::getNumThreads();
+     296      237005 :   if(nt>ncp/(4*stride)) nt=1;
+     297             : 
+     298      237005 :   #pragma omp parallel num_threads(nt)
+     299             :   {
+     300             :     std::vector<double> omp_f;
+     301             :     if( nt>1 ) omp_f.resize(nder,0);
+     302             :     #pragma omp for
+     303             :     for(unsigned i=rank; i<nvalsWithForce; i+=stride) {
+     304             :       double ff=values[valsToForce[i]]->inputForce[0];
+     305             :       std::vector<double> & thisderiv( values[valsToForce[i]]->data );
+     306             :       int nn=nder;
+     307             :       int one1=1;
+     308             :       int one2=1;
+     309             :       if( nt>1 ) plumed_blas_daxpy(&nn,&ff,thisderiv.data()+1,&one1,omp_f.data(),&one2);
+     310             :       else       plumed_blas_daxpy(&nn,&ff,thisderiv.data()+1,&one1,forcesForApply.data(),&one2);
+     311             :       // if( nt>1 ) for(unsigned j=0; j<nder; ++j) omp_f[j] += ff*thisderiv[1+j];
+     312             :       //else for(unsigned j=0; j<nder; ++j) forcesForApply[j] += ff*thisderiv[1+j];
+     313             :     }
+     314             :     #pragma omp critical
+     315             :     {
+     316             :       if( nt>1 ) {
+     317             :         int nn=forcesForApply.size();
+     318             :         double one0=1.0;
+     319             :         int one1=1;
+     320             :         int one2=1;
+     321             :         plumed_blas_daxpy(&nn,&one0,omp_f.data(),&one1,forcesForApply.data(),&one2);
+     322             :       }
+     323             :       // for(unsigned j=0; j<forcesForApply.size(); ++j) {
+     324             :       // forcesForApply[j]+=omp_f[j];
+     325             :       // }
+     326             :     }
+     327             :   }
+     328             : 
+     329      237005 :   if(ncp>4*comm.Get_size()) comm.Sum(&forcesForApply[0],nder);
+     330             :   return true;
+     331             : }
+     332             : 
+     333             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionWithValue.h.func-sort-c.html b/coverage/core/ActionWithValue.h.func-sort-c.html new file mode 100644 index 000000000000..3826efd1ee73 --- /dev/null +++ b/coverage/core/ActionWithValue.h.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionWithValue.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionWithValue.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:202195.2 %
Date:2024-04-19 12:12:35Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15ActionWithValue18checkFieldsAllowedEv0
_ZNK4PLMD15ActionWithValue17getOutputQuantityEj142134
_ZN4PLMD15ActionWithValue8setValueERKd167368
_ZNK4PLMD15ActionWithValue25checkNumericalDerivativesEv2333658
_ZN4PLMD15ActionWithValue21castToActionWithValueEv4111180
_ZNK4PLMD15ActionWithValue17getOutputQuantityERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE4667854
_ZNK4PLMD15ActionWithValue25doNotCalculateDerivativesEv225557078
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionWithValue.h.func.html b/coverage/core/ActionWithValue.h.func.html new file mode 100644 index 000000000000..f9b6d133f712 --- /dev/null +++ b/coverage/core/ActionWithValue.h.func.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionWithValue.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionWithValue.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:202195.2 %
Date:2024-04-19 12:12:35Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15ActionWithValue18checkFieldsAllowedEv0
_ZN4PLMD15ActionWithValue21castToActionWithValueEv4111180
_ZN4PLMD15ActionWithValue8setValueERKd167368
_ZNK4PLMD15ActionWithValue17getOutputQuantityERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE4667854
_ZNK4PLMD15ActionWithValue17getOutputQuantityEj142134
_ZNK4PLMD15ActionWithValue25checkNumericalDerivativesEv2333658
_ZNK4PLMD15ActionWithValue25doNotCalculateDerivativesEv225557078
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionWithValue.h.gcov.html b/coverage/core/ActionWithValue.h.gcov.html new file mode 100644 index 000000000000..478c6f36946e --- /dev/null +++ b/coverage/core/ActionWithValue.h.gcov.html @@ -0,0 +1,330 @@ + + + + + + + + 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:202195.2 %
Date:2024-04-19 12:12:35Functions: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             : #include <cstring>
+      31             : 
+      32             : namespace PLMD {
+      33             : 
+      34             : /**
+      35             : \ingroup MULTIINHERIT
+      36             : Used to create a PLMD::Action that has some scalar or vectorial output that may or may not have some derivatives.
+      37             : This is used for PLMD::Bias, PLMD::Colvar and PLMD::Function
+      38             : 
+      39             : The vast majority of the PLMD::Action objects that are implemented in
+      40             : plumed calculate some quantity or a set of quantities.  This could be
+      41             : the value of a CV, the value of a function or the potential due to a bias.
+      42             : PLMD::ActionWithValue provides the functionality for storing these quantities
+      43             : and (in tandem with PLMD::ActionWithArguments) the functionality for passing
+      44             : quantities between PLMD::Actions.  When you are deciding what quantities
+      45             : your new PLMD::Action will need to store using PLMD::ActionWithValue you must
+      46             : ask yourself the following two questions:
+      47             : 
+      48             : - Do I need to differentiate my output quantities
+      49             : - Is my PLMD::Action calculating a single thing or does the output have multiple components
+      50             : 
+      51             : If the answer to the first of these questions is yes then you must setup your values
+      52             : you using either PLMD::ActionWithValue::addValueWithDerivatives() or
+      53             : PLMD::ActionWithValue::addComponentWithDerivatives.  If the answer is no you
+      54             : can set up values using PLMD::ActionWithValue::addValue() or PLMD::ActionWithValue::addComponent().
+      55             : The precise routine you use to setup your values will depend on your answer to the
+      56             : second question.  As you are probably aware if the output of your PLMD::Action is a
+      57             : single quantity you can reference that quantity in the input file using the label of the
+      58             : PLMD::Action it was calculated in.  If your action <b> outputs only one quantity </b>
+      59             : we call that quantity the <b> value </b> of the Action.  To set the <b> value </b> and get pointers to it
+      60             : you should <b> use the set of routines that have the word value in the name </b>.  If, by contrast,
+      61             : your PLMD::Action calculates multiple quantities then these quantities are referenced in input using the
+      62             : label.component syntax.  We refer to these <b> multiple quantities </b> the <b> components </b>
+      63             : of the PLMD::Action.  Perhaps unsurprisingly, when you manipulate the <b> components </b> of an
+      64             : PLMD::Action you should use <b> the routines with the word component in the name. </b>
+      65             : */
+      66             : 
+      67             : class ActionWithValue :
+      68             :   public virtual Action
+      69             : {
+      70             :   friend class ActionWithVector;
+      71             :   friend class ActionWithArguments;
+      72             : private:
+      73             : /// This finishes setup on first step to check if actions are calculated during update
+      74             :   bool firststep;
+      75             : /// An array containing the values for this action
+      76             :   std::vector<std::unique_ptr<Value>> values;
+      77             : /// A vector that is used to hold the forces that we will apply on the input quantities
+      78             :   std::vector<double> forcesForApply;
+      79             :   std::vector<unsigned> valsToForce;
+      80             : /// Are we skipping the calculation of the derivatives
+      81             :   bool noderiv;
+      82             : /// Are we using numerical derivatives to differentiate
+      83             :   bool numericalDerivatives;
+      84             : /// Return the index for the component named name
+      85             :   int getComponent( const std::string& name ) const;
+      86             : public:
+      87             : 
+      88             : // -------- The action has one value only  ---------------- //
+      89             : 
+      90             : /// Add a value with the name label
+      91             :   void addValue( const std::vector<unsigned>& shape=std::vector<unsigned>() );
+      92             : /// Add a value with the name label that has derivatives
+      93             :   virtual void addValueWithDerivatives( const std::vector<unsigned>& shape=std::vector<unsigned>() );
+      94             : /// Set your default value to have no periodicity
+      95             :   void setNotPeriodic();
+      96             : /// Set the value to be periodic with a particular domain
+      97             :   void setPeriodic( const std::string& min, const std::string& max );
+      98             : protected:
+      99             : /// Get a pointer to the default value
+     100             :   Value* getPntrToValue();
+     101             : /// Set the default value (the one without name)
+     102             :   void setValue(const double& d);
+     103             : 
+     104             : // -------- The action has multiple components ---------- //
+     105             : 
+     106             : public:
+     107             : /// Add a value with a name like label.name
+     108             :   void addComponent( const std::string& name, const std::vector<unsigned>& shape=std::vector<unsigned>() );
+     109             : /// Add a value with a name like label.name that has derivatives
+     110             :   virtual void addComponentWithDerivatives( const std::string& name, const std::vector<unsigned>& shape=std::vector<unsigned>() );
+     111             : /// Set your value component to have no periodicity
+     112             :   void componentIsNotPeriodic( const std::string& name );
+     113             : /// Set the value to be periodic with a particular domain
+     114             :   void componentIsPeriodic( const std::string& name, const std::string& min, const std::string& max );
+     115             : protected:
+     116             : /// Return a pointer to the component by index
+     117             :   Value* getPntrToComponent(int i);
+     118             : /// Get a const pointer to the ith component
+     119             :   const Value* getConstPntrToComponent(int i) const;
+     120             : /// Return a pointer to the value by name
+     121             :   Value* getPntrToComponent(const std::string& name);
+     122             : /// Accumulate the forces from the Values
+     123             :   bool checkForForces();
+     124             : /// Get the forces to apply
+     125             :   const std::vector<double>& getForcesToApply() const;
+     126             : public:
+     127             :   explicit ActionWithValue(const ActionOptions&ao);
+     128             :   ~ActionWithValue();
+     129             : 
+     130             : /// Register all the relevant keywords for the action
+     131             :   static void registerKeywords( Keywords& keys );
+     132             : /// Insist that numerical derivatives should always be used for an action and make this fact appear in the manual
+     133             :   static void noAnalyticalDerivatives(Keywords& keys);
+     134             : /// Puts a message into the manual that the components always output
+     135             :   static void componentsAreNotOptional(Keywords& keys);
+     136             : /// The components in the action will depend on the user
+     137             :   static void useCustomisableComponents(Keywords& keys);
+     138             : /// Are we not calculating derivatives
+     139             :   virtual bool doNotCalculateDerivatives() const ;
+     140             : /// Get the value of one of the components of the PLMD::Action
+     141             :   double getOutputQuantity( const unsigned j ) const ;
+     142             : /// Get the value with a specific name (N.B. if there is no such value this returns zero)
+     143             :   double getOutputQuantity( const std::string& name ) const ;
+     144             : 
+     145             : //  --- Routines for passing stuff to ActionWithArguments -- //
+     146             : 
+     147             : /// Check if a value with a particular name is present.  This is only used in PLMD::ActionWithArguments.
+     148             : /// You should not use it when manipulating components.
+     149             :   bool exists( const std::string& name ) const;
+     150             : /// Return a pointer to the value with name (this is used to retrieve values in other PLMD::Actions)
+     151             : /// You should NEVER use this routine to refer to the components of your PLMD::Action.  Use
+     152             : /// getPntrToComponent instead.
+     153             :   Value* copyOutput( const std::string&name ) const;
+     154             : /// Return a pointer to the value with this number (this is used to retrieve values in other PLMD::Actions)
+     155             : /// You should NEVER use this routine to refer to the components of your PLMD::Action.  Use
+     156             : /// getPntrToComponent instead.
+     157             :   Value* copyOutput( const unsigned& n ) const;
+     158             : /// get a string that contains all the available components
+     159             :   std::string getComponentsList( ) const ;
+     160             : /// get a vector that contains the label for all the components
+     161             :   std::vector<std::string> getComponentsVector( ) const ;
+     162             : 
+     163             : 
+     164             : // -- Routines for everything else -- //
+     165             : 
+     166             : /// Returns the number of values defined
+     167             :   int getNumberOfComponents() const ;
+     168             : /// Clear the forces on the values
+     169             :   virtual void clearInputForces( const bool& force=false );
+     170             : /// Clear the derivatives of values wrt parameters
+     171             :   virtual void clearDerivatives( const bool& force=false );
+     172             : /// Calculate the gradients and store them for all the values (need for projections)
+     173             :   virtual void setGradientsIfNeeded();
+     174             : /// Set the value
+     175             :   void setValue(Value*,double);
+     176             : /// Check if numerical derivatives should be used
+     177             :   bool checkNumericalDerivatives() const override;
+     178             : /// This forces the class to use numerical derivatives
+     179             :   void useNumericalDerivatives();
+     180             : // These are things for using vectors of values as fields
+     181           0 :   virtual void checkFieldsAllowed() { error("cannot use this action as a field"); }
+     182             :   virtual unsigned getNumberOfDerivatives()=0;
+     183             : /// Activate the calculation of derivatives
+     184             :   virtual void turnOnDerivatives();
+     185             : /// Get the titles to use for the columns of the matrix
+     186             :   virtual void getMatrixColumnTitles( std::vector<std::string>& argnames ) const ;
+     187             : /// This is used to check if we run calculate during the update step
+     188             :   virtual bool calculateOnUpdate();
+     189     4111180 :   ActionWithValue* castToActionWithValue() noexcept final { return this; }
+     190             : };
+     191             : 
+     192             : inline
+     193      142134 : double ActionWithValue::getOutputQuantity(const unsigned j) const {
+     194      142134 :   plumed_massert(j<values.size(),"index requested is out of bounds");
+     195      142134 :   return values[j]->get();
+     196             : }
+     197             : 
+     198             : inline
+     199     4667854 : double ActionWithValue::getOutputQuantity( const std::string& name ) const {
+     200     4667854 :   auto offset=getLabel().size();
+     201    10494969 :   for(unsigned i=0; i<values.size(); ++i) {
+     202             :     const std::string & valname=values[i]->name;
+     203     5935013 :     if(valname.size()>offset+1 && valname[offset]=='.' ) {
+     204             :       plumed_dbg_assert(Tools::startWith(valname,getLabel()));
+     205     2560821 :       if(!std::strcmp(valname.c_str()+offset+1,name.c_str())) return values[i]->get();
+     206             :     }
+     207             :   }
+     208             :   return 0.0;
+     209             : }
+     210             : 
+     211             : inline
+     212      167368 : void ActionWithValue::setValue(const double& d) {
+     213      167368 :   plumed_massert(values.size()==1, "cannot use setValue in multi-component actions");
+     214      167368 :   plumed_massert(values[0]->name==getLabel(), "The value you are trying to set is not the default");
+     215      167368 :   values[0]->set(d);
+     216      167368 : }
+     217             : 
+     218             : inline
+     219             : int ActionWithValue::getNumberOfComponents() const {
+     220  1470862641 :   return values.size();
+     221             : }
+     222             : 
+     223             : inline
+     224             : void ActionWithValue::useNumericalDerivatives() {
+     225             :   plumed_massert( keywords.exists("NUMERICAL_DERIVATIVES"), "numerical derivatives are not permitted for this action" );
+     226             :   numericalDerivatives=true;
+     227             : }
+     228             : 
+     229             : inline
+     230     2333658 : bool ActionWithValue::checkNumericalDerivatives() const {
+     231     2333658 :   return numericalDerivatives;
+     232             : }
+     233             : 
+     234             : inline
+     235   225557078 : bool ActionWithValue::doNotCalculateDerivatives() const {
+     236   225557078 :   return noderiv;
+     237             : }
+     238             : 
+     239             : inline
+     240             : const std::vector<double>& ActionWithValue::getForcesToApply() const {
+     241      288943 :   return forcesForApply;
+     242             : }
+     243             : 
+     244             : inline
+     245             : Value* ActionWithValue::getPntrToValue() {
+     246             :   plumed_dbg_massert(values.size()==1,"The number of components is not equal to one");
+     247             :   plumed_dbg_massert(values[0]->name==getLabel(), "The value you are trying to retrieve is not the default");
+     248             :   return values[0].get();
+     249             : }
+     250             : 
+     251             : }
+     252             : 
+     253             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionWithVector.cpp.func-sort-c.html b/coverage/core/ActionWithVector.cpp.func-sort-c.html new file mode 100644 index 000000000000..624563419c37 --- /dev/null +++ b/coverage/core/ActionWithVector.cpp.func-sort-c.html @@ -0,0 +1,289 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionWithVector.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionWithVector.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:42042698.6 %
Date:2024-04-19 12:12:35Functions:505492.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD16ActionWithVector29calculateNumericalDerivativesEPNS_15ActionWithValueE0
_ZN4PLMD16ActionWithVectorC1ERKNS_13ActionOptionsE0
_ZN4PLMD16ActionWithVectorD0Ev0
_ZN4PLMD16ActionWithVectorD1Ev0
_ZNK4PLMD16ActionWithVector18hasStoredArgumentsEv46
_ZNK4PLMD16ActionWithVector21getFirstActionInChainEv46
_ZN4PLMD16ActionWithVector23getNumberOfStoredValuesEPNS_5ValueERjRKjRKSt6vectorIS2_SaIS2_EE136
_ZN4PLMD16ActionWithVector17argumentDependsOnERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS0_PNS_5ValueE344
_ZN4PLMD16ActionWithVector24reallyBuildArgumentStoreERKj979
_ZN4PLMD16ActionWithVector26getAdditionalTasksRequiredEPS0_RSt6vectorIjSaIjEE1273
_ZN4PLMD16ActionWithVector29updateTaskListReductionStatusEv2637
_ZN4PLMD16ActionWithVector16registerKeywordsERNS_8KeywordsE2763
_ZN4PLMD16ActionWithVector18buildArgumentStoreERKj3358
_ZN4PLMD16ActionWithVector16finishChainBuildEPS0_3479
_ZN4PLMD16ActionWithVectorC2ERKNS_13ActionOptionsE4855
_ZN4PLMD16ActionWithVectorD2Ev4855
_ZN4PLMD16ActionWithVector16addActionToChainERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EEPS0_11716
_ZN4PLMD16ActionWithVector24getActionWithDerivativesEPS0_17589
_ZN4PLMD16ActionWithVector14canReduceTasksERSt6vectorIPS0_SaIS2_EE20799
_ZNK4PLMD16ActionWithVector25getAllActionLabelsInChainERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EE36744
_ZNK4PLMD16ActionWithVector25updateForceTasksFromValueEPKNS_5ValueERSt6vectorIjSaIjEE90719
_ZNK4PLMD16ActionWithVector13getForceTasksERSt6vectorIjSaIjEE103595
_ZN4PLMD16ActionWithVector15gatherProcessesERSt6vectorIdSaIdEE132916
_ZN4PLMD16ActionWithVector11runAllTasksEv132958
_ZN4PLMD16ActionWithVector20getListOfActiveTasksEPS0_144803
_ZN4PLMD16ActionWithVector16addForcesToInputERKSt6vectorIdSaIdEERj186295
_ZN4PLMD16ActionWithVector13gatherThreadsERKjS2_RKSt6vectorIdSaIdEERS5_RNS_10MultiValueE209851
_ZN4PLMD16ActionWithVector23updateTaskReductionFlagERb229460
_ZN4PLMD16ActionWithVector14checkForForcesEv254294
_ZN4PLMD16ActionWithVector5applyEv254294
_ZN4PLMD16ActionWithVector12lockRequestsEv273388
_ZN4PLMD16ActionWithVector14unlockRequestsEv273388
_ZN4PLMD16ActionWithVector7prepareEv274392
_ZNK4PLMD16ActionWithVector28checkChainForNonScalarForcesEv292756
_ZN4PLMD16ActionWithVector16getNumberOfTasksERj314828
_ZN4PLMD16ActionWithVector15getSizeOfBufferERKjRj317546
_ZN4PLMD16ActionWithVector18finishComputationsERKSt6vectorIdSaIdEE317546
_ZNK4PLMD16ActionWithVector13checkForGridsERj317546
_ZN4PLMD16ActionWithVector23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjS9_S9_S9_421141
_ZN4PLMD16ActionWithVector29getNumberOfStreamedQuantitiesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjS9_S9_S9_421141
_ZN4PLMD16ActionWithVector30getNumberOfStreamedDerivativesERjPNS_5ValueE424060
_ZN4PLMD16ActionWithVector13retrieveAtomsERKb456179
_ZN4PLMD16ActionWithVector16clearDerivativesERKb457414
_ZN4PLMD16ActionWithVector16clearInputForcesERKb457414
_ZNK4PLMD16ActionWithVector25gatherForcesOnStoredValueEPKNS_5ValueERKjRKNS_10MultiValueERSt6vectorIdSaIdEE1565796
_ZNK4PLMD16ActionWithVector23checkComponentsForForceEv2039456
_ZNK4PLMD16ActionWithVector12gatherForcesERKjRKNS_10MultiValueERSt6vectorIdSaIdEE2101182
_ZNK4PLMD16ActionWithVector17gatherStoredValueERKjS2_RKNS_10MultiValueES2_RSt6vectorIdSaIdEE3572803
_ZN4PLMD16ActionWithVector28broadcastThatTasksAreReducedEPS0_3843401
_ZNK4PLMD16ActionWithVector17checkForTaskForceERKjPKNS_5ValueE5561312
_ZNK4PLMD16ActionWithVector12taskIsActiveERKjRi6143576
_ZNK4PLMD16ActionWithVector18gatherAccumulatorsERKjRKNS_10MultiValueERSt6vectorIdSaIdEE9174066
_ZNK4PLMD16ActionWithVector7runTaskERKjRNS_10MultiValueE11275248
_ZN4PLMD16ActionWithVector21getFirstActionInChainEv209533153
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionWithVector.cpp.func.html b/coverage/core/ActionWithVector.cpp.func.html new file mode 100644 index 000000000000..6a65cbd28cdd --- /dev/null +++ b/coverage/core/ActionWithVector.cpp.func.html @@ -0,0 +1,289 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionWithVector.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionWithVector.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:42042698.6 %
Date:2024-04-19 12:12:35Functions:505492.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD16ActionWithVector11runAllTasksEv132958
_ZN4PLMD16ActionWithVector12lockRequestsEv273388
_ZN4PLMD16ActionWithVector13gatherThreadsERKjS2_RKSt6vectorIdSaIdEERS5_RNS_10MultiValueE209851
_ZN4PLMD16ActionWithVector13retrieveAtomsERKb456179
_ZN4PLMD16ActionWithVector14canReduceTasksERSt6vectorIPS0_SaIS2_EE20799
_ZN4PLMD16ActionWithVector14checkForForcesEv254294
_ZN4PLMD16ActionWithVector14unlockRequestsEv273388
_ZN4PLMD16ActionWithVector15gatherProcessesERSt6vectorIdSaIdEE132916
_ZN4PLMD16ActionWithVector15getSizeOfBufferERKjRj317546
_ZN4PLMD16ActionWithVector16addActionToChainERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EEPS0_11716
_ZN4PLMD16ActionWithVector16addForcesToInputERKSt6vectorIdSaIdEERj186295
_ZN4PLMD16ActionWithVector16clearDerivativesERKb457414
_ZN4PLMD16ActionWithVector16clearInputForcesERKb457414
_ZN4PLMD16ActionWithVector16finishChainBuildEPS0_3479
_ZN4PLMD16ActionWithVector16getNumberOfTasksERj314828
_ZN4PLMD16ActionWithVector16registerKeywordsERNS_8KeywordsE2763
_ZN4PLMD16ActionWithVector17argumentDependsOnERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS0_PNS_5ValueE344
_ZN4PLMD16ActionWithVector18buildArgumentStoreERKj3358
_ZN4PLMD16ActionWithVector18finishComputationsERKSt6vectorIdSaIdEE317546
_ZN4PLMD16ActionWithVector20getListOfActiveTasksEPS0_144803
_ZN4PLMD16ActionWithVector21getFirstActionInChainEv209533153
_ZN4PLMD16ActionWithVector23getNumberOfStoredValuesEPNS_5ValueERjRKjRKSt6vectorIS2_SaIS2_EE136
_ZN4PLMD16ActionWithVector23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjS9_S9_S9_421141
_ZN4PLMD16ActionWithVector23updateTaskReductionFlagERb229460
_ZN4PLMD16ActionWithVector24getActionWithDerivativesEPS0_17589
_ZN4PLMD16ActionWithVector24reallyBuildArgumentStoreERKj979
_ZN4PLMD16ActionWithVector26getAdditionalTasksRequiredEPS0_RSt6vectorIjSaIjEE1273
_ZN4PLMD16ActionWithVector28broadcastThatTasksAreReducedEPS0_3843401
_ZN4PLMD16ActionWithVector29calculateNumericalDerivativesEPNS_15ActionWithValueE0
_ZN4PLMD16ActionWithVector29getNumberOfStreamedQuantitiesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjS9_S9_S9_421141
_ZN4PLMD16ActionWithVector29updateTaskListReductionStatusEv2637
_ZN4PLMD16ActionWithVector30getNumberOfStreamedDerivativesERjPNS_5ValueE424060
_ZN4PLMD16ActionWithVector5applyEv254294
_ZN4PLMD16ActionWithVector7prepareEv274392
_ZN4PLMD16ActionWithVectorC1ERKNS_13ActionOptionsE0
_ZN4PLMD16ActionWithVectorC2ERKNS_13ActionOptionsE4855
_ZN4PLMD16ActionWithVectorD0Ev0
_ZN4PLMD16ActionWithVectorD1Ev0
_ZN4PLMD16ActionWithVectorD2Ev4855
_ZNK4PLMD16ActionWithVector12gatherForcesERKjRKNS_10MultiValueERSt6vectorIdSaIdEE2101182
_ZNK4PLMD16ActionWithVector12taskIsActiveERKjRi6143576
_ZNK4PLMD16ActionWithVector13checkForGridsERj317546
_ZNK4PLMD16ActionWithVector13getForceTasksERSt6vectorIjSaIjEE103595
_ZNK4PLMD16ActionWithVector17checkForTaskForceERKjPKNS_5ValueE5561312
_ZNK4PLMD16ActionWithVector17gatherStoredValueERKjS2_RKNS_10MultiValueES2_RSt6vectorIdSaIdEE3572803
_ZNK4PLMD16ActionWithVector18gatherAccumulatorsERKjRKNS_10MultiValueERSt6vectorIdSaIdEE9174066
_ZNK4PLMD16ActionWithVector18hasStoredArgumentsEv46
_ZNK4PLMD16ActionWithVector21getFirstActionInChainEv46
_ZNK4PLMD16ActionWithVector23checkComponentsForForceEv2039456
_ZNK4PLMD16ActionWithVector25gatherForcesOnStoredValueEPKNS_5ValueERKjRKNS_10MultiValueERSt6vectorIdSaIdEE1565796
_ZNK4PLMD16ActionWithVector25getAllActionLabelsInChainERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EE36744
_ZNK4PLMD16ActionWithVector25updateForceTasksFromValueEPKNS_5ValueERSt6vectorIjSaIjEE90719
_ZNK4PLMD16ActionWithVector28checkChainForNonScalarForcesEv292756
_ZNK4PLMD16ActionWithVector7runTaskERKjRNS_10MultiValueE11275248
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionWithVector.cpp.gcov.html b/coverage/core/ActionWithVector.cpp.gcov.html new file mode 100644 index 000000000000..e11cd85ed8d6 --- /dev/null +++ b/coverage/core/ActionWithVector.cpp.gcov.html @@ -0,0 +1,848 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionWithVector.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionWithVector.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:42042698.6 %
Date:2024-04-19 12:12:35Functions:505492.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 "ActionWithVector.h"
+      23             : #include "PlumedMain.h"
+      24             : #include "ActionSet.h"
+      25             : #include "tools/OpenMP.h"
+      26             : #include "tools/Communicator.h"
+      27             : 
+      28             : namespace PLMD {
+      29             : 
+      30        2763 : void ActionWithVector::registerKeywords( Keywords& keys ) {
+      31        2763 :   Action::registerKeywords( keys );
+      32        2763 :   ActionAtomistic::registerKeywords( keys );
+      33        2763 :   ActionWithValue::registerKeywords( keys ); keys.remove("NUMERICAL_DERIVATIVES");
+      34        2763 :   ActionWithArguments::registerKeywords( keys );
+      35        5526 :   keys.addFlag("SERIAL",false,"do the calculation in serial.  Do not parallelize");
+      36        2763 : }
+      37             : 
+      38        4855 : ActionWithVector::ActionWithVector(const ActionOptions&ao):
+      39             :   Action(ao),
+      40             :   ActionAtomistic(ao),
+      41             :   ActionWithValue(ao),
+      42             :   ActionWithArguments(ao),
+      43        4855 :   serial(false),
+      44        4855 :   action_to_do_before(NULL),
+      45        4855 :   action_to_do_after(NULL),
+      46        4855 :   never_reduce_tasks(false),
+      47        4855 :   reduce_tasks(false),
+      48        4855 :   atomsWereRetrieved(false),
+      49        4855 :   done_in_chain(false)
+      50             : {
+      51       12124 :   if( keywords.exists("SERIAL") ) parseFlag("SERIAL",serial);
+      52        4855 : }
+      53             : 
+      54        4855 : ActionWithVector::~ActionWithVector() {
+      55        4855 :   if( action_to_do_before ) action_to_do_before->action_to_do_after=NULL;
+      56        4855 : }
+      57             : 
+      58      273388 : void ActionWithVector::lockRequests() {
+      59             :   ActionAtomistic::lockRequests();
+      60             :   ActionWithArguments::lockRequests();
+      61      273388 : }
+      62             : 
+      63      273388 : void ActionWithVector::unlockRequests() {
+      64             :   ActionAtomistic::unlockRequests();
+      65             :   ActionWithArguments::unlockRequests();
+      66      273388 : }
+      67             : 
+      68           0 : void ActionWithVector::calculateNumericalDerivatives(ActionWithValue* av) {
+      69           0 :   plumed_merror("cannot calculate numerical derivative for action " + getName() + " with label " + getLabel() );
+      70             : }
+      71             : 
+      72      457414 : void ActionWithVector::clearDerivatives( const bool& force ) {
+      73      457414 :   if( !force && actionInChain() ) return;
+      74      338825 :   ActionWithValue::clearDerivatives();
+      75      338825 :   if( action_to_do_after ) action_to_do_after->clearDerivatives( true );
+      76             : }
+      77             : 
+      78      457414 : void ActionWithVector::clearInputForces( const bool& force ) {
+      79      457414 :   if( !force && actionInChain() ) return;
+      80      338825 :   ActionWithValue::clearInputForces();
+      81      338825 :   if( action_to_do_after ) action_to_do_after->clearInputForces( true );
+      82             : }
+      83             : 
+      84          46 : const ActionWithVector* ActionWithVector::getFirstActionInChain() const {
+      85          46 :   if( !actionInChain() ) return this;
+      86          46 :   return action_to_do_before->getFirstActionInChain();
+      87             : }
+      88             : 
+      89   209533153 : ActionWithVector* ActionWithVector::getFirstActionInChain() {
+      90   209533153 :   if( !actionInChain() ) return this;
+      91   198645812 :   return action_to_do_before->getFirstActionInChain();
+      92             : }
+      93             : 
+      94      456179 : void ActionWithVector::retrieveAtoms( const bool& force ) {
+      95      456179 :   if( !force && actionInChain() || atomsWereRetrieved ) return;
+      96      337251 :   ActionAtomistic::retrieveAtoms(); atomsWereRetrieved = !actionInChain();
+      97      337251 :   if( action_to_do_after ) action_to_do_after->retrieveAtoms( true );
+      98             : }
+      99             : 
+     100          46 : bool ActionWithVector::hasStoredArguments() const {
+     101          46 :   std::string headstr=getFirstActionInChain()->getLabel();
+     102         100 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     103          68 :     if( !getPntrToArgument(i)->ignoreStoredValue(headstr) ) return true;
+     104             :   }
+     105             :   return false;
+     106             : }
+     107             : 
+     108         344 : bool ActionWithVector::argumentDependsOn( const std::string& headstr, ActionWithVector* faction, Value* thearg ) {
+     109         826 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     110         488 :     if( this!=faction && thearg==getPntrToArgument(i) ) return true;
+     111         485 :     ActionWithVector* av = dynamic_cast<ActionWithVector*>( getPntrToArgument(i)->getPntrToAction() );
+     112         485 :     if( av && (av->getFirstActionInChain())->getLabel()==headstr ) {
+     113         180 :       if( av->argumentDependsOn( headstr, faction, thearg ) ) return true;;
+     114             :     }
+     115             :   }
+     116             :   return false;
+     117             : }
+     118             : 
+     119        3358 : unsigned ActionWithVector::buildArgumentStore( const unsigned& argstart ) {
+     120             :   // Don't use chains for grids
+     121       10518 :   for(unsigned i=argstart; i<getNumberOfArguments(); ++i) {
+     122        7538 :     if( getPntrToArgument(i)->isConstant() ) continue;
+     123        6645 :     ActionWithVector* av=dynamic_cast<ActionWithVector*>(getPntrToArgument(i)->getPntrToAction());
+     124        6645 :     if( !av || getPntrToArgument(i)->getRank()>0 && getPntrToArgument(i)->hasDerivatives() ) { done_in_chain=false; break; }
+     125             :   }
+     126        3358 :   if( done_in_chain ) {
+     127             :     std::vector<std::string> alabels; std::vector<ActionWithVector*> f_actions;
+     128        8530 :     for(unsigned i=argstart; i<getNumberOfArguments(); ++i) {
+     129        6140 :       bool found=false; std::string mylab = (getPntrToArgument(i)->getPntrToAction())->getLabel();
+     130       12735 :       for(unsigned j=0; j<alabels.size(); ++j) {
+     131        8722 :         if( alabels[j]==mylab ) { found=true; break; }
+     132             :       }
+     133        6140 :       if( !found ) alabels.push_back( mylab );
+     134             : 
+     135             :       // If this is calculated in setup we never need to add to chain
+     136        6140 :       if( getPntrToArgument(i)->isConstant() ) continue;
+     137             :       // Find the chain we need to add this to from the arguments
+     138        5727 :       ActionWithVector* av=dynamic_cast<ActionWithVector*>(getPntrToArgument(i)->getPntrToAction()); plumed_assert( av );
+     139        5727 :       found=false; ActionWithVector* myact = av->getFirstActionInChain();
+     140        5727 :       if( getPntrToArgument(i)->getRank()==1 && getPntrToArgument(i)->storedata ) {
+     141        5535 :         for(unsigned j=argstart; j<getNumberOfArguments(); ++j) {
+     142        5249 :           ActionWithArguments* aarg=dynamic_cast<ActionWithArguments*>( getPntrToArgument(j)->getPntrToAction() );
+     143        5249 :           if( !aarg || i==j ) continue;
+     144       14181 :           for(unsigned k=0; k<aarg->getNumberOfArguments(); ++k) {
+     145        9263 :             if( aarg->getPntrToArgument(k)==getPntrToArgument(i) ) { done_in_chain=false; return reallyBuildArgumentStore( argstart ); }
+     146             :           }
+     147             :         }
+     148             :       }
+     149        6073 :       for(unsigned j=0; j<f_actions.size(); ++j) {
+     150        3298 :         if( f_actions[j]==myact ) { found=true; break; }
+     151             :       }
+     152        5707 :       if( !found ) {
+     153        2775 :         if( f_actions.size()>0 ) {
+     154         336 :           if( f_actions[0]->checkForDependency(myact) ) getPntrToArgument(i)->buildDataStore();
+     155         336 :           if( myact->checkForDependency(f_actions[0]) ) error("cannot deal with arguments in this order. Try swapping argument order");
+     156             :         }
+     157        2775 :         if( !getPntrToArgument(i)->storedata && getPntrToArgument(i)->getRank()>0 ) f_actions.push_back( myact );
+     158             :       }
+     159             :     }
+     160             :     // Now make sure that everything we need is in the chain
+     161        2390 :     if( f_actions.size()>0 ) {
+     162             :       // Check everything for later f_actions is done before f_actions[0]
+     163        2416 :       for(unsigned i=1; i<f_actions.size(); ++i) {
+     164         122 :         ActionWithArguments* aarg = dynamic_cast<ActionWithArguments*>( f_actions[i] );
+     165         122 :         if( !aarg || aarg->getNumberOfArguments()==0 ) continue;
+     166         179 :         for(unsigned j=0; j<aarg->getNumberOfArguments(); ++j) {
+     167         134 :           if( (aarg->getPntrToArgument(j))->isConstant() ) continue ;
+     168         123 :           bool found=false; std::string dep_argname = (aarg->getPntrToArgument(j))->getPntrToAction()->getLabel();
+     169       17501 :           for(const auto & pp : plumed.getActionSet()) {
+     170             :             Action* p(pp.get());
+     171             :             // Check if this is the dependency
+     172       17501 :             if( p->getLabel()==dep_argname ) { found=true; break; }
+     173             :             // Check if this is the first of the arguments that will appear in this chain
+     174       17389 :             else if( p->getLabel()==f_actions[0]->getLabel() ) break;
+     175             :           }
+     176         123 :           if( !found ) { done_in_chain=false; break; }
+     177             :         }
+     178             :         // Stop trying to add things in the chain if we cannot
+     179          56 :         if( !done_in_chain ) return reallyBuildArgumentStore( argstart );
+     180             :       }
+     181        2294 :       std::vector<std::string> empty(1); empty[0] = f_actions[0]->getLabel();
+     182        2405 :       for(unsigned i=1; i<f_actions.size(); ++i) f_actions[0]->addActionToChain( empty, f_actions[i] );
+     183        2294 :     }
+     184             :     // Now add this argument to the chain
+     185             :     bool added=false;
+     186        2427 :     for(unsigned i=argstart; i<getNumberOfArguments(); ++i) {
+     187             :       // Add this function to jobs to do in recursive loop in previous action
+     188        2427 :       if( getPntrToArgument(i)->getRank()>0 && !getPntrToArgument(i)->isConstant() ) {
+     189        2427 :         ActionWithVector* av=dynamic_cast<ActionWithVector*>( getPntrToArgument(i)->getPntrToAction() );
+     190        2427 :         if( av && av->addActionToChain( alabels, this ) ) { added=true; break; }
+     191             :       }
+     192             :     }
+     193        2379 :     plumed_massert(added, "could not add action " + getLabel() + " to chain of any of its arguments");
+     194             :     // And get the number of derivatives
+     195        2379 :     ActionWithVector* head=getFirstActionInChain();
+     196        2379 :     unsigned nder=0; arg_deriv_starts.resize( getNumberOfArguments() );
+     197        8472 :     for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     198             :       // Ensures that we ignore the grid (first argument) if we are evaluating a function on a grid
+     199        6093 :       if( i==0 && getName().find("EVALUATE_FUNCTION_FROM_GRID")!=std::string::npos ) continue ;
+     200        6092 :       ActionWithVector* iaction=dynamic_cast<ActionWithVector*>(getPntrToArgument(i)->getPntrToAction());
+     201        6092 :       if( actionInChain() && !getPntrToArgument(i)->ignoreStoredValue(head->getLabel()) ) {
+     202         670 :         arg_deriv_starts[i] = 0; head->getNumberOfStreamedDerivatives( arg_deriv_starts[i], getPntrToArgument(i) );
+     203        5422 :       } else if( iaction && iaction->isInSubChain(nder) ) {
+     204        2246 :         arg_deriv_starts[i] = nder;
+     205             :         // Add the total number of derivatives that we have by this point in the chain to nder
+     206        2246 :         if( iaction ) { nder=0; head->getNumberOfStreamedDerivatives( nder, getPntrToArgument(i) ); }
+     207             :       } else {
+     208             :         // Check if we have already found this action
+     209             :         int k=-1;
+     210        3176 :         if( iaction ) {
+     211        3176 :           ActionWithVector* ider_action=iaction->getActionWithDerivatives( iaction );
+     212        3396 :           for(unsigned j=0; j<i; ++j) {
+     213        1612 :             if( j==0 && getName().find("EVALUATE_FUNCTION_FROM_GRID")!=std::string::npos ) continue ;
+     214        1611 :             ActionWithVector* jaction=dynamic_cast<ActionWithVector*>(getPntrToArgument(j)->getPntrToAction());
+     215        1611 :             if( jaction->getActionWithDerivatives(jaction)==ider_action || jaction->checkForDependency(ider_action) ) { k=j; break; }
+     216             :           }
+     217        3176 :           if( k>=0 ) { arg_deriv_starts[i] = arg_deriv_starts[k]; continue; }
+     218             :         }
+     219             : 
+     220        1784 :         if( i>0 ) {
+     221             :           // This is a fudge so that inputs like this work:
+     222             :           // c: CONTACT_MATRIX ATOMS=1-100
+     223             :           // d: MATRIX_PRODUCT ARG=mat1,mat2
+     224             :           // e: CUSTOM ARG=c,d
+     225             :           // f: MATRIX_PRODUCT ARG=mat3,mat4
+     226             :           // g: CUSTOM ARG=c,f
+     227             :           // See symfunc rt-nbonds-q6 for an example
+     228             :           // In this example when we set arg_deriv_starts[1] for f in g nder=number of derivatives of c
+     229             :           // mder is equal to the number of derivatives by the time you get to f minus the number of derivatives for c
+     230         135 :           unsigned mder=0;
+     231         135 :           ActionWithVector* jaction=dynamic_cast<ActionWithVector*>(getPntrToArgument(i-1)->getPntrToAction());
+     232         135 :           if( jaction->action_to_do_after && !(jaction->action_to_do_after)->getNumberOfStoredValues( getPntrToArgument(i-1), mder, i, getArguments() ) ) mder=0;
+     233         135 :           if( mder>0 ) nder = nder + mder;
+     234             :         }
+     235             : 
+     236        1784 :         arg_deriv_starts[i] = nder;
+     237             :         // Add the total number of derivatives that we have by this point in the chain to nder
+     238        1784 :         if( iaction ) {
+     239        1784 :           nder=0;
+     240        1784 :           if( (getPntrToArgument(i)->getPntrToAction())->getName().find("DIFFERENCE")!=std::string::npos ) {
+     241           0 :             ActionWithArguments* aarg=dynamic_cast<ActionWithArguments*>( getPntrToArgument(i)->getPntrToAction() );
+     242           0 :             plumed_assert( aarg && aarg->getNumberOfArguments()==2 );
+     243           0 :             head->getNumberOfStreamedDerivatives( nder, aarg->getPntrToArgument(0) );
+     244           0 :             nder += (aarg->getPntrToArgument(1))->getNumberOfValues();
+     245        1784 :           } else head->getNumberOfStreamedDerivatives( nder, getPntrToArgument(i) );
+     246             :         }
+     247             :       }
+     248             :     }
+     249        2379 :     nder=0; head->getNumberOfStreamedDerivatives( nder, NULL );
+     250        2379 :     return nder;
+     251        2410 :   }
+     252         948 :   return reallyBuildArgumentStore( argstart );
+     253             : }
+     254             : 
+     255         979 : unsigned ActionWithVector::reallyBuildArgumentStore( const unsigned& argstart ) {
+     256        2679 :   for(unsigned i=argstart; i<getNumberOfArguments(); ++i) { if( getPntrToArgument(i)->getRank()>0 ) getPntrToArgument(i)->buildDataStore(); }
+     257         979 :   unsigned nder=0; arg_deriv_starts.resize( getNumberOfArguments() );
+     258        2679 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) { arg_deriv_starts[i] = nder; nder += getPntrToArgument(i)->getNumberOfValues(); }
+     259         979 :   return nder;
+     260             : }
+     261             : 
+     262       17589 : ActionWithVector* ActionWithVector::getActionWithDerivatives( ActionWithVector* depaction ) {
+     263       17589 :   if( depaction==this || depaction->checkForDependency(this) ) {
+     264       11534 :     if( getNumberOfAtoms()>0 ) return this;
+     265        6747 :     std::string c=getFirstActionInChain()->getLabel();
+     266       42499 :     for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     267       36209 :       if( !getPntrToArgument(i)->ignoreStoredValue(c) && !getPntrToArgument(i)->isConstant() ) return this;
+     268             :     }
+     269             :   }
+     270       12802 :   plumed_assert( action_to_do_before );
+     271       12802 :   return action_to_do_before->getActionWithDerivatives(depaction);
+     272             : }
+     273             : 
+     274       11716 : bool ActionWithVector::addActionToChain( const std::vector<std::string>& alabels, ActionWithVector* act ) {
+     275       11716 :   if( action_to_do_after ) { bool state=action_to_do_after->addActionToChain( alabels, act ); return state; }
+     276             :   // Check action is not already in chain
+     277        2538 :   std::vector<std::string> mylabels; getFirstActionInChain()->getAllActionLabelsInChain( mylabels );
+     278       21096 :   for(unsigned i=0; i<mylabels.size(); ++i) {
+     279       18558 :     if( act->getLabel()==mylabels[i] ) return true;
+     280             :   }
+     281             : 
+     282             :   // Check that everything that is required has been calculated
+     283        6680 :   for(unsigned i=0; i<alabels.size(); ++i) {
+     284             :     bool found=false;
+     285       20669 :     for(unsigned j=0; j<mylabels.size(); ++j) {
+     286       19945 :       if( alabels[i]==mylabels[j] ) { found=true; break; }
+     287             :     }
+     288        4190 :     if( !found ) {
+     289         724 :       ActionWithValue* av=plumed.getActionSet().selectWithLabel<ActionWithValue*>( alabels[i] );
+     290         724 :       plumed_massert( av, "could not cast " + alabels[i] ); bool storingall=true;
+     291        1510 :       for(int j=0; j<av->getNumberOfComponents(); ++j) {
+     292         786 :         if( !(av->getPntrToComponent(j))->storedata ) storingall=false;
+     293             :       }
+     294         724 :       if( !storingall ) return false;
+     295             :     }
+     296             :   }
+     297             :   // This checks that there is nothing that will cause problems in the chain
+     298        2490 :   mylabels.resize(0); getFirstActionInChain()->getAllActionLabelsInChain( mylabels );
+     299       20596 :   for(unsigned i=0; i<mylabels.size(); ++i) {
+     300       18106 :     ActionWithVector* av1=plumed.getActionSet().selectWithLabel<ActionWithVector*>( mylabels[i] );
+     301      176478 :     for(unsigned j=0; j<i; ++j) {
+     302      158372 :       ActionWithVector* av2=plumed.getActionSet().selectWithLabel<ActionWithVector*>( mylabels[j] );
+     303      158372 :       if( !av1->canBeAfterInChain( av2 ) ) error("must calculate " + mylabels[j] + " before " + mylabels[i] );
+     304             :     }
+     305             :   }
+     306        2490 :   action_to_do_after=act; act->action_to_do_before=this; updateTaskListReductionStatus();
+     307        2490 :   ActionWithVector* head = getFirstActionInChain();
+     308        2490 :   head->broadcastThatTasksAreReduced( head ); head->finishChainBuild( act );
+     309             :   return true;
+     310        2538 : }
+     311             : 
+     312        2637 : void ActionWithVector::updateTaskListReductionStatus() {
+     313        2637 :   ActionWithVector* head = getFirstActionInChain();
+     314        2637 :   std::vector<ActionWithVector*> task_reducing_actions; head->canReduceTasks( task_reducing_actions );
+     315        2637 :   if( task_reducing_actions.size()>0 ) head->reduce_tasks=true;
+     316        2637 : }
+     317             : 
+     318     3843401 : void ActionWithVector::broadcastThatTasksAreReduced( ActionWithVector* aselect ) {
+     319     3843401 :   std::string c=getFirstActionInChain()->getLabel();
+     320    18085092 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     321    14241691 :     if( !getPntrToArgument(i)->ignoreStoredValue(c) ) {
+     322       71187 :       ActionWithVector* av = dynamic_cast<ActionWithVector*>( getPntrToArgument(i)->getPntrToAction() );
+     323       71187 :       if( av ) {
+     324             :         bool found=false;
+     325       12107 :         ActionWithVector* av_head = av->getFirstActionInChain();
+     326       17727 :         for(unsigned i=0; i<av_head->task_control_list.size(); ++i) {
+     327       17268 :           if( aselect==av_head->task_control_list[i] ) { found=true; break; }
+     328             :         }
+     329       12107 :         if( !found ) av_head->task_control_list.insert( av_head->task_control_list.begin(), aselect );
+     330             : 
+     331       12107 :         av_head->reduce_tasks=true; av_head->updateTaskReductionFlag( av_head->reduce_tasks );
+     332             :       }
+     333             :     }
+     334             :   }
+     335     3843401 :   if( action_to_do_after ) action_to_do_after->broadcastThatTasksAreReduced( aselect );
+     336     3843401 : }
+     337             : 
+     338      229460 : void ActionWithVector::updateTaskReductionFlag( bool& head_reduce_tasks ) {
+     339      229460 :   if( actionInChain() ) {
+     340      217353 :     plumed_assert( task_control_list.size()==0 );
+     341             :   } else {
+     342       30759 :     for(unsigned i=0; i<task_control_list.size(); ++i) {
+     343       18652 :       if( !(task_control_list[i]->getFirstActionInChain())->reduce_tasks ) head_reduce_tasks=false;
+     344             :     }
+     345             :   }
+     346      229460 :   broadcastThatTasksAreReduced( getFirstActionInChain() );
+     347      229460 :   if( action_to_do_after ) action_to_do_after->updateTaskReductionFlag( head_reduce_tasks );
+     348      229460 : }
+     349             : 
+     350       20799 : void ActionWithVector::canReduceTasks( std::vector<ActionWithVector*>& task_reducing_actions ) {
+     351       20799 :   areAllTasksRequired( task_reducing_actions );
+     352       20799 :   if( action_to_do_after ) action_to_do_after->canReduceTasks( task_reducing_actions );
+     353       20799 : }
+     354             : 
+     355        3479 : void ActionWithVector::finishChainBuild( ActionWithVector* act ) {
+     356        3479 :   if( action_to_do_after ) action_to_do_after->finishChainBuild( act );
+     357        3479 : }
+     358             : 
+     359       36744 : void ActionWithVector::getAllActionLabelsInChain( std::vector<std::string>& mylabels ) const {
+     360             :   bool found = false ;
+     361      358974 :   for(unsigned i=0; i<mylabels.size(); ++i) {
+     362      322230 :     if( getLabel()==mylabels[i] ) { found=true; }
+     363             :   }
+     364       36744 :   if( !found ) mylabels.push_back( getLabel() );
+     365       36744 :   if( action_to_do_after ) action_to_do_after->getAllActionLabelsInChain( mylabels );
+     366       36744 : }
+     367             : 
+     368     6143576 : void ActionWithVector::taskIsActive( const unsigned& current, int& flag ) const {
+     369     6143576 :   if( isActive() ) flag = checkTaskStatus( current, flag );
+     370     6143576 :   if( flag<=0 && action_to_do_after ) action_to_do_after->taskIsActive( current, flag );
+     371     6143576 : }
+     372             : 
+     373        1273 : void ActionWithVector::getAdditionalTasksRequired( ActionWithVector* action, std::vector<unsigned>& atasks ) {
+     374        1305 :   for(unsigned i=0; i<task_control_list.size(); ++i ) task_control_list[i]->getAdditionalTasksRequired( action, atasks );
+     375        1273 : }
+     376             : 
+     377      274392 : void ActionWithVector::prepare() {
+     378      274392 :   active_tasks.resize(0); atomsWereRetrieved=false;
+     379      274392 : }
+     380             : 
+     381      144803 : std::vector<unsigned>& ActionWithVector::getListOfActiveTasks( ActionWithVector* action ) {
+     382      144803 :   if( active_tasks.size()>0 ) return active_tasks;
+     383      132814 :   unsigned ntasks=0; getNumberOfTasks( ntasks );
+     384             : 
+     385      132814 :   unsigned stride=comm.Get_size();
+     386      132814 :   unsigned rank=comm.Get_rank();
+     387      132814 :   if(serial) { stride=1; rank=0; }
+     388             : 
+     389             :   // Get number of threads for OpenMP
+     390      132814 :   unsigned nt=OpenMP::getNumThreads();
+     391      132814 :   if( nt*stride*10>ntasks ) nt=ntasks/stride/10;
+     392             :   if( nt==0 ) nt=1;
+     393             : 
+     394      132814 :   if( !never_reduce_tasks && reduce_tasks ) {
+     395        1457 :     if( task_control_list.size()>0 ) {
+     396             :       // Get the list of tasks that are active in the action that uses the output of this action
+     397         238 :       for(unsigned i=0; i<task_control_list.size(); ++i) {
+     398         130 :         task_control_list[i]->retrieveAtoms();
+     399         130 :         active_tasks = task_control_list[i]->getListOfActiveTasks( action );
+     400             :       }
+     401             :       // Now work out else we need from here to calculate the later action
+     402         108 :       getAdditionalTasksRequired( action, active_tasks );
+     403             :     } else {
+     404        1349 :       std::vector<int> taskFlags( ntasks, -1 );
+     405             : 
+     406        1349 :       #pragma omp parallel num_threads(nt)
+     407             :       {
+     408             :         #pragma omp for nowait
+     409             :         for(unsigned i=rank; i<ntasks; i+=stride ) {
+     410             :           taskIsActive( i, taskFlags[i] );
+     411             :         }
+     412             :       }
+     413     2293809 :       for(unsigned i=0; i<ntasks; ++i) taskFlags[i] = std::abs( taskFlags[i] );
+     414        1349 :       if( !serial ) comm.Sum( taskFlags );
+     415             : 
+     416             :       unsigned nt=0;
+     417     2293809 :       for(unsigned i=0; i<ntasks; ++i) {
+     418     2292460 :         if( taskFlags[i]>=stride ) nt++;
+     419             :       }
+     420        1349 :       active_tasks.resize(nt); nt=0;
+     421     2293809 :       for(unsigned i=0; i<ntasks; ++i) {
+     422     2292460 :         if( taskFlags[i]>=stride ) { active_tasks[nt]=i; nt++; }
+     423             :       }
+     424        1349 :       getAdditionalTasksRequired( this, active_tasks );
+     425             :     }
+     426             :   } else {
+     427      131357 :     active_tasks.resize( ntasks );
+     428     5115712 :     for(unsigned i=0; i<ntasks; ++i) active_tasks[i]=i;
+     429             :   }
+     430      132814 :   return active_tasks;
+     431             : }
+     432             : 
+     433      132958 : void ActionWithVector::runAllTasks() {
+     434             : // Skip this if this is done elsewhere
+     435      132958 :   if( action_to_do_before ) return;
+     436             : 
+     437      132923 :   unsigned stride=comm.Get_size();
+     438      132923 :   unsigned rank=comm.Get_rank();
+     439      132923 :   if(serial) { stride=1; rank=0; }
+     440             : 
+     441             :   // Get the list of active tasks
+     442      132923 :   std::vector<unsigned> & partialTaskList( getListOfActiveTasks( this ) );
+     443      132923 :   unsigned nactive_tasks=partialTaskList.size();
+     444             : 
+     445             :   // Get number of threads for OpenMP
+     446      132923 :   unsigned nt=OpenMP::getNumThreads();
+     447      132923 :   if( nt*stride*10>nactive_tasks ) nt=nactive_tasks/stride/10;
+     448      132923 :   if( nt==0 ) nt=1;
+     449             : 
+     450             :   // Now do all preparations required to run all the tasks
+     451             :   // prepareForTaskLoop();
+     452             : 
+     453             :   // Get the total number of streamed quantities that we need
+     454      132923 :   unsigned nquants=0, nmatrices=0, maxcol=0, nbooks=0;
+     455      132923 :   getNumberOfStreamedQuantities( getLabel(), nquants, nmatrices, maxcol, nbooks );
+     456             :   // Get size for buffer
+     457      132923 :   unsigned bufsize=0; getSizeOfBuffer( nactive_tasks, bufsize );
+     458      132923 :   if( buffer.size()!=bufsize ) buffer.resize( bufsize );
+     459             :   // Clear buffer
+     460      132923 :   buffer.assign( buffer.size(), 0.0 );
+     461             : 
+     462             :   // Recover the number of derivatives we require
+     463      132923 :   unsigned nderivatives = 0; bool gridsInStream=checkForGrids(nderivatives);
+     464      132923 :   if( !doNotCalculateDerivatives() && !gridsInStream ) getNumberOfStreamedDerivatives( nderivatives, NULL );
+     465             : 
+     466      132923 :   #pragma omp parallel num_threads(nt)
+     467             :   {
+     468             :     std::vector<double> omp_buffer;
+     469             :     if( nt>1 ) omp_buffer.resize( bufsize, 0.0 );
+     470             :     MultiValue myvals( nquants, nderivatives, nmatrices, maxcol, nbooks );
+     471             :     myvals.clearAll(true);
+     472             : 
+     473             :     #pragma omp for nowait
+     474             :     for(unsigned i=rank; i<nactive_tasks; i+=stride) {
+     475             :       // Calculate the stuff in the loop for this action
+     476             :       runTask( partialTaskList[i], myvals );
+     477             : 
+     478             :       // Now transfer the data to the actions that accumulate values from the calculated quantities
+     479             :       if( nt>1 ) gatherAccumulators( partialTaskList[i], myvals, omp_buffer );
+     480             :       else gatherAccumulators( partialTaskList[i], myvals, buffer );
+     481             : 
+     482             :       // Clear the value
+     483             :       myvals.clearAll(true);
+     484             :     }
+     485             :     #pragma omp critical
+     486             :     gatherThreads( nt, bufsize, omp_buffer, buffer, myvals );
+     487             :   }
+     488             : 
+     489             :   // MPI Gather everything
+     490      132923 :   if( !serial && buffer.size()>0 ) gatherProcesses( buffer );
+     491      132923 :   finishComputations( buffer );
+     492             : }
+     493             : 
+     494      209851 : void ActionWithVector::gatherThreads( const unsigned& nt, const unsigned& bufsize, const std::vector<double>& omp_buffer, std::vector<double>& buffer, MultiValue& myvals ) {
+     495   100156601 :   if( nt>1 ) for(unsigned i=0; i<bufsize; ++i) buffer[i]+=omp_buffer[i];
+     496      209851 : }
+     497             : 
+     498      132916 : void ActionWithVector::gatherProcesses( std::vector<double>& buffer ) {
+     499      132916 :   comm.Sum( buffer );
+     500      132916 : }
+     501             : 
+     502      317546 : bool ActionWithVector::checkForGrids( unsigned& nder ) const {
+     503      650289 :   for(int i=0; i<getNumberOfComponents(); ++i) {
+     504      341476 :     if( getConstPntrToComponent(i)->getRank()>0 && getConstPntrToComponent(i)->hasDerivatives() ) {
+     505        8733 :       nder=getConstPntrToComponent(i)->getNumberOfGridDerivatives(); return true;
+     506             :     }
+     507             :   }
+     508      308813 :   if( action_to_do_after ) return action_to_do_after->checkForGrids(nder);
+     509             :   return false;
+     510             : }
+     511             : 
+     512      314828 : void ActionWithVector::getNumberOfTasks( unsigned& ntasks ) {
+     513      314828 :   if( ntasks==0 ) {
+     514      130161 :     if( getNumberOfArguments()==1 && getNumberOfComponents()==1 && getPntrToComponent(0)->getRank()==0 ) {
+     515        2285 :       if( !getPntrToArgument(0)->hasDerivatives() && getPntrToArgument(0)->getRank()==2 ) ntasks = getPntrToArgument(0)->getShape()[0];
+     516        2268 :       else ntasks = getPntrToArgument(0)->getNumberOfValues();
+     517             :     } else {
+     518      127876 :       plumed_assert( getNumberOfComponents()>0 && getPntrToComponent(0)->getRank()>0 );
+     519      127876 :       if( getPntrToComponent(0)->hasDerivatives() ) ntasks = getPntrToComponent(0)->getNumberOfValues();
+     520      121815 :       else ntasks = getPntrToComponent(0)->getShape()[0];
+     521             :     }
+     522             :   }
+     523      653582 :   for(int i=0; i<getNumberOfComponents(); ++i) {
+     524      338754 :     if( getPntrToComponent(i)->getRank()==0 ) {
+     525       65901 :       if( getNumberOfArguments()!=1 ) error("mismatched numbers of tasks in streamed quantities");
+     526       65901 :       if( getPntrToArgument(0)->hasDerivatives() && ntasks!=getPntrToArgument(0)->getNumberOfValues() ) error("mismatched numbers of tasks in streamed quantities");
+     527       65901 :       else if ( !getPntrToArgument(0)->hasDerivatives() && ntasks!=getPntrToArgument(0)->getShape()[0] ) error("mismatched numbers of tasks in streamed quantities");
+     528      272853 :     } else if( getPntrToComponent(i)->hasDerivatives() && ntasks!=getPntrToComponent(i)->getNumberOfValues() ) error("mismatched numbers of tasks in streamed quantities");
+     529      272853 :     else if( !getPntrToComponent(i)->hasDerivatives() && ntasks!=getPntrToComponent(i)->getShape()[0] ) error("mismatched numbers of tasks in streamed quantities");
+     530             :   }
+     531      314828 :   if( action_to_do_after ) action_to_do_after->getNumberOfTasks( ntasks );
+     532      314828 : }
+     533             : 
+     534      421141 : void ActionWithVector::setupStreamedComponents( const std::string& headstr, unsigned& nquants, unsigned& nmat, unsigned& maxcol, unsigned& nbookeeping ) {
+     535     1074956 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     536      653815 :     if( !getPntrToArgument(i)->ignoreStoredValue(headstr) ) { getPntrToArgument(i)->streampos=nquants; nquants++; }
+     537             :   }
+     538      881303 :   for(int i=0; i<getNumberOfComponents(); ++i) { getPntrToComponent(i)->streampos=nquants; nquants++; }
+     539      421141 : }
+     540             : 
+     541      421141 : void ActionWithVector::getNumberOfStreamedQuantities( const std::string& headstr, unsigned& nquants, unsigned& nmat, unsigned& maxcol, unsigned& nbookeeping ) {
+     542      421141 :   setupStreamedComponents( headstr, nquants, nmat, maxcol, nbookeeping );
+     543      421141 :   if( action_to_do_after ) action_to_do_after->getNumberOfStreamedQuantities( headstr, nquants, nmat, maxcol, nbookeeping );
+     544      421141 : }
+     545             : 
+     546      317546 : void ActionWithVector::getSizeOfBuffer( const unsigned& nactive_tasks, unsigned& bufsize ) {
+     547      659022 :   for(int i=0; i<getNumberOfComponents(); ++i) { getPntrToComponent(i)->bufstart=bufsize; bufsize += getPntrToComponent(i)->data.size(); }
+     548      317546 :   if( action_to_do_after ) action_to_do_after->getSizeOfBuffer( nactive_tasks, bufsize );
+     549      317546 : }
+     550             : 
+     551      424060 : void ActionWithVector::getNumberOfStreamedDerivatives( unsigned& nderivatives, Value* stopat ) {
+     552      424060 :   std::string c=getFirstActionInChain()->getLabel();
+     553     1144070 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     554      720680 :     if( !getPntrToArgument(i)->ignoreStoredValue(c) ) {
+     555      385817 :       if( getPntrToArgument(i)==stopat ) return;
+     556      385147 :       nderivatives += getPntrToArgument(i)->getNumberOfValues();
+     557             :     }
+     558             :   }
+     559      423390 :   if( getNumberOfAtoms()>0 ) nderivatives += 3*getNumberOfAtoms() + 9;
+     560             :   // Don't do the whole chain if we have been told to stop early
+     561      423390 :   if( stopat && stopat->getPntrToAction()==this ) return;
+     562             : 
+     563      419256 :   if( action_to_do_after ) action_to_do_after->getNumberOfStreamedDerivatives( nderivatives, stopat );
+     564             : }
+     565             : 
+     566         136 : bool ActionWithVector::getNumberOfStoredValues( Value* startat, unsigned& nvals, const unsigned& astart, const std::vector<Value*>& stopat ) {
+     567         181 :   for(unsigned j=astart; j<stopat.size(); ++j) {
+     568         151 :     if( stopat[j] && (stopat[j]->getPntrToAction()==this || (stopat[j]->getPntrToAction())->checkForDependency(this)) ) return true;
+     569             :   }
+     570             : 
+     571          30 :   std::string c=getFirstActionInChain()->getLabel();
+     572          77 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     573          47 :     if( !getPntrToArgument(i)->ignoreStoredValue(c) ) {
+     574           4 :       for(unsigned j=astart; j<stopat.size(); ++j) {
+     575           2 :         if( getPntrToArgument(i)==stopat[j] ) return true;
+     576             :       }
+     577           2 :       nvals += getPntrToArgument(i)->getNumberOfValues();
+     578             :     }
+     579             :   }
+     580          30 :   if( startat->getPntrToAction()!=this && getNumberOfAtoms()>0 ) return false;
+     581             : 
+     582          30 :   if( action_to_do_after ) return action_to_do_after->getNumberOfStoredValues( startat, nvals, astart, stopat );
+     583             :   return false;
+     584             : }
+     585             : 
+     586    11275248 : void ActionWithVector::runTask( const unsigned& current, MultiValue& myvals ) const {
+     587    11275248 :   if( isActive() ) {
+     588    10159199 :     myvals.setTaskIndex(current); myvals.vector_call=true; performTask( current, myvals );
+     589             :   }
+     590    11275248 :   if( action_to_do_after ) action_to_do_after->runTask( current, myvals );
+     591    11275248 : }
+     592             : 
+     593     9174066 : void ActionWithVector::gatherAccumulators( const unsigned& taskCode, const MultiValue& myvals, std::vector<double>& buffer ) const {
+     594     9174066 :   if( isActive() ) {
+     595    18422785 :     for(int i=0; i<getNumberOfComponents(); ++i) {
+     596    10209765 :       unsigned bufstart = getConstPntrToComponent(i)->bufstart;
+     597             :       // This looks after storing of scalars that are summed from vectors/matrices
+     598    10209765 :       if( getConstPntrToComponent(i)->getRank()==0 ) {
+     599             :         plumed_dbg_massert( bufstart<buffer.size(), "problem in " + getLabel() );
+     600     1127850 :         unsigned sind = getConstPntrToComponent(i)->streampos; buffer[bufstart] += myvals.get(sind);
+     601     1127850 :         if( getConstPntrToComponent(i)->hasDerivatives() ) {
+     602    33654637 :           for(unsigned k=0; k<myvals.getNumberActive(sind); ++k) {
+     603    32526787 :             unsigned kindex = myvals.getActiveIndex(sind,k);
+     604             :             plumed_dbg_massert( bufstart+1+kindex<buffer.size(), "problem in " + getLabel()  );
+     605    32526787 :             buffer[bufstart + 1 + kindex] += myvals.getDerivative(sind,kindex);
+     606             :           }
+     607             :         }
+     608             :         // This looks after storing of vectors
+     609     9081915 :       } else if( getConstPntrToComponent(i)->storedata ) gatherStoredValue( i, taskCode, myvals, bufstart, buffer );
+     610             :     }
+     611             :   }
+     612     9174066 :   if( action_to_do_after ) action_to_do_after->gatherAccumulators( taskCode, myvals, buffer );
+     613     9174066 : }
+     614             : 
+     615     3572803 : void ActionWithVector::gatherStoredValue( const unsigned& valindex, const unsigned& taskCode, const MultiValue& myvals,
+     616             :     const unsigned& bufstart, std::vector<double>& buffer ) const {
+     617             :   plumed_dbg_assert( getConstPntrToComponent(valindex)->getRank()==1 && !getConstPntrToComponent(valindex)->hasDeriv );
+     618     3572803 :   unsigned vindex = getConstPntrToComponent(valindex)->bufstart + taskCode; plumed_dbg_massert( vindex<buffer.size(), "failing in " + getLabel() );
+     619     3572803 :   buffer[vindex] += myvals.get(getConstPntrToComponent(valindex)->streampos);
+     620     3572803 : }
+     621             : 
+     622      317546 : void ActionWithVector::finishComputations( const std::vector<double>& buf ) {
+     623      317546 :   if( isActive() ) {
+     624      526990 :     for(int i=0; i<getNumberOfComponents(); ++i) {
+     625             :       // This gathers vectors and grids at the end of the calculation
+     626      275460 :       unsigned bufstart = getPntrToComponent(i)->bufstart;
+     627      275460 :       getPntrToComponent(i)->data.assign( getPntrToComponent(i)->data.size(), 0 );
+     628      275460 :       if( (getPntrToComponent(i)->getRank()>0 && getPntrToComponent(i)->hasDerivatives()) || getPntrToComponent(i)->storedata ) {
+     629      130909 :         unsigned sz_v = getPntrToComponent(i)->data.size();
+     630    46581530 :         for(unsigned j=0; j<sz_v; ++j) {
+     631             :           plumed_dbg_assert( bufstart+j<buf.size() );
+     632    46450621 :           getPntrToComponent(i)->add( j, buf[bufstart+j] );
+     633             :         }
+     634             :         // Make sure single values are set
+     635      144551 :       } else if( getPntrToComponent(i)->getRank()==0 ) getPntrToComponent(i)->set( buf[bufstart] );
+     636             :       // This gathers derivatives of scalars
+     637      275460 :       if( !doNotCalculateDerivatives() && getPntrToComponent(i)->hasDeriv && getPntrToComponent(i)->getRank()==0 ) {
+     638    16151047 :         for(unsigned j=0; j<getPntrToComponent(i)->getNumberOfDerivatives(); ++j) getPntrToComponent(i)->setDerivative( j, buf[bufstart+1+j] );
+     639             :       }
+     640             :     }
+     641             :   }
+     642      317546 :   if( action_to_do_after ) action_to_do_after->finishComputations( buf );
+     643      317546 : }
+     644             : 
+     645      292756 : bool ActionWithVector::checkChainForNonScalarForces() const {
+     646      522906 :   for(unsigned i=0; i<getNumberOfComponents(); ++i) {
+     647      304987 :     if( getConstPntrToComponent(i)->getRank()>0 && getConstPntrToComponent(i)->forcesWereAdded() ) return true;
+     648             :   }
+     649      217919 :   if( action_to_do_after ) return action_to_do_after->checkChainForNonScalarForces();
+     650             :   return false;
+     651             : }
+     652             : 
+     653      254294 : bool ActionWithVector::checkForForces() {
+     654      254294 :   if( getPntrToComponent(0)->getRank()==0 ) return ActionWithValue::checkForForces();
+     655      202558 :   else if( actionInChain() ) return false;
+     656             : 
+     657             :   // Check if there are any forces
+     658      125226 :   if( !checkChainForNonScalarForces() ) return false;
+     659             : 
+     660             :   // Setup MPI parallel loop
+     661       74837 :   unsigned stride=comm.Get_size();
+     662       74837 :   unsigned rank=comm.Get_rank();
+     663       74837 :   if(serial) { stride=1; rank=0; }
+     664             : 
+     665             :   // Get the number of tasks
+     666       74837 :   std::vector<unsigned> force_tasks; getForceTasks( force_tasks );
+     667       74837 :   Tools::removeDuplicates(force_tasks); unsigned nf_tasks=force_tasks.size();
+     668             : 
+     669             :   // Get number of threads for OpenMP
+     670       74837 :   unsigned nt=OpenMP::getNumThreads();
+     671       74837 :   if( nt*stride*10>nf_tasks ) nt=nf_tasks/stride/10;
+     672             :   if( nt==0 ) nt=1;
+     673             : 
+     674             :   // Now determine how big the multivalue needs to be
+     675       74837 :   unsigned nquants=0, nmatrices=0, maxcol=0, nbooks=0;
+     676       74837 :   getNumberOfStreamedQuantities( getLabel(), nquants, nmatrices, maxcol, nbooks );
+     677             :   // Recover the number of derivatives we require (this should be equal to the number of forces)
+     678       74837 :   unsigned nderiv=0; getNumberOfStreamedDerivatives( nderiv, NULL );
+     679       74837 :   if( forcesForApply.size()!=nderiv ) forcesForApply.resize( nderiv );
+     680             :   // Clear force buffer
+     681       74837 :   forcesForApply.assign( forcesForApply.size(), 0.0 );
+     682             : 
+     683       74837 :   #pragma omp parallel num_threads(nt)
+     684             :   {
+     685             :     std::vector<double> omp_forces;
+     686             :     if( nt>1 ) omp_forces.resize( forcesForApply.size(), 0.0 );
+     687             :     MultiValue myvals( nquants, nderiv, nmatrices, maxcol, nbooks );
+     688             :     myvals.clearAll(true);
+     689             : 
+     690             :     #pragma omp for nowait
+     691             :     for(unsigned i=rank; i<nf_tasks; i+=stride) {
+     692             :       runTask( force_tasks[i], myvals );
+     693             : 
+     694             :       // Now get the forces
+     695             :       if( nt>1 ) gatherForces( force_tasks[i], myvals, omp_forces );
+     696             :       else gatherForces( force_tasks[i], myvals, forcesForApply );
+     697             : 
+     698             :       myvals.clearAll(true);
+     699             :     }
+     700             :     #pragma omp critical
+     701             :     if(nt>1) for(unsigned i=0; i<forcesForApply.size(); ++i) forcesForApply[i]+=omp_forces[i];
+     702             :   }
+     703             :   // MPI Gather on forces
+     704       74837 :   if( !serial ) comm.Sum( forcesForApply );
+     705             :   return true;
+     706             : }
+     707             : 
+     708     2039456 : bool ActionWithVector::checkComponentsForForce() const {
+     709     2777915 :   for(unsigned i=0; i<values.size(); ++i) {
+     710     2546733 :     if( getConstPntrToComponent(i)->forcesWereAdded() ) return true;
+     711             :   }
+     712             :   return false;
+     713             : }
+     714             : 
+     715     5561312 : bool ActionWithVector::checkForTaskForce( const unsigned& itask, const Value* myval ) const {
+     716             :   plumed_dbg_assert( !(myval->getRank()==2 && !myval->hasDerivatives()) );
+     717     5561312 :   return fabs(myval->getForce(itask))>epsilon;
+     718             : }
+     719             : 
+     720       90719 : void ActionWithVector::updateForceTasksFromValue( const Value* myval, std::vector<unsigned>& force_tasks ) const {
+     721       90719 :   if( myval->getRank()>0 && myval->forcesWereAdded() ) {
+     722       85478 :     unsigned nt = myval->getNumberOfValues();
+     723       85478 :     if( !myval->hasDerivatives() ) nt = myval->getShape()[0];
+     724     6149611 :     for(unsigned i=0; i<nt; ++i) {
+     725     6064133 :       if( checkForTaskForce(i, myval) ) force_tasks.push_back( i );
+     726             :     }
+     727             :   }
+     728       90719 : }
+     729             : 
+     730      103595 : void ActionWithVector::getForceTasks( std::vector<unsigned>& force_tasks ) const {
+     731      103595 :   if( isActive() && checkComponentsForForce() ) {
+     732      171577 :     for(unsigned k=0; k<values.size(); ++k) {
+     733       91329 :       updateForceTasksFromValue( getConstPntrToComponent(k), force_tasks );
+     734             :     }
+     735             :   }
+     736      103595 :   if( action_to_do_after ) action_to_do_after->getForceTasks( force_tasks );
+     737      103595 : }
+     738             : 
+     739     1565796 : void ActionWithVector::gatherForcesOnStoredValue( const Value* myval, const unsigned& itask, const MultiValue& myvals, std::vector<double>& forces ) const {
+     740             :   plumed_dbg_assert( myval->storedata && !(myval->getRank()==2 && !myval->hasDerivatives()) );
+     741     1565796 :   double fforce = myval->getForce(itask);
+     742             :   unsigned sspos = myval->getPositionInStream();
+     743    36850733 :   for(unsigned j=0; j<myvals.getNumberActive(sspos); ++j) {
+     744    35284937 :     unsigned jder=myvals.getActiveIndex(sspos, j); plumed_dbg_assert( jder<forces.size() );
+     745    35284937 :     forces[jder] += fforce*myvals.getDerivative( sspos, jder );
+     746             :   }
+     747     1565796 : }
+     748             : 
+     749     2101182 : void ActionWithVector::gatherForces( const unsigned& itask, const MultiValue& myvals, std::vector<double>& forces ) const {
+     750     2101182 :   if( isActive() && checkComponentsForForce() ) {
+     751     3587802 :     for(unsigned k=0; k<getNumberOfComponents(); ++k) {
+     752     1859776 :       const Value* myval=getConstPntrToComponent(k);
+     753     1859776 :       if( myval->getRank()>0 && myval->forcesWereAdded() ) gatherForcesOnStoredValue( myval, itask, myvals, forces );
+     754             :     }
+     755             :   }
+     756     2101182 :   if( action_to_do_after ) action_to_do_after->gatherForces( itask, myvals, forces );
+     757     2101182 : }
+     758             : 
+     759      254294 : void ActionWithVector::apply() {
+     760      254294 :   if( !checkForForces() ) return;
+     761             :   // Find the top of the chain and add forces
+     762      117795 :   unsigned ind=0; getFirstActionInChain()->addForcesToInput( getForcesToApply(), ind );
+     763             : }
+     764             : 
+     765      186295 : void ActionWithVector::addForcesToInput( const std::vector<double>& forcesToApply, unsigned& ind ) {
+     766      186295 :   if( ind>=forcesToApply.size() ) return;
+     767      136785 :   addForcesOnArguments( 0, forcesToApply, ind, getFirstActionInChain()->getLabel() ); setForcesOnAtoms( forcesToApply, ind );
+     768      136785 :   if( action_to_do_after ) action_to_do_after->addForcesToInput( forcesToApply, ind );
+     769             : }
+     770             : 
+     771             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionWithVector.h.func-sort-c.html b/coverage/core/ActionWithVector.h.func-sort-c.html new file mode 100644 index 000000000000..fd2744f2519d --- /dev/null +++ b/coverage/core/ActionWithVector.h.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionWithVector.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionWithVector.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:8988.9 %
Date:2024-04-19 12:12:35Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD16ActionWithVector19switchTaskReductionERKbPS0_0
_ZNK4PLMD16ActionWithVector31getAllActionLabelsInMatrixChainERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EE22
_ZN4PLMD16ActionWithVector12isInSubChainERj3176
_ZN4PLMD16ActionWithVector19areAllTasksRequiredERSt6vectorIPS0_SaIS2_EE7651
_ZNK4PLMD16ActionWithVector23updateAdditionalIndicesERKjRNS_10MultiValueE13807
_ZN4PLMD16ActionWithVector17canBeAfterInChainEPS0_158372
_ZNK4PLMD16ActionWithVector15checkTaskStatusERKjRi3769981
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionWithVector.h.func.html b/coverage/core/ActionWithVector.h.func.html new file mode 100644 index 000000000000..367d5f003248 --- /dev/null +++ b/coverage/core/ActionWithVector.h.func.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionWithVector.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionWithVector.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:8988.9 %
Date:2024-04-19 12:12:35Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD16ActionWithVector12isInSubChainERj3176
_ZN4PLMD16ActionWithVector17canBeAfterInChainEPS0_158372
_ZN4PLMD16ActionWithVector19areAllTasksRequiredERSt6vectorIPS0_SaIS2_EE7651
_ZN4PLMD16ActionWithVector19switchTaskReductionERKbPS0_0
_ZNK4PLMD16ActionWithVector15checkTaskStatusERKjRi3769981
_ZNK4PLMD16ActionWithVector23updateAdditionalIndicesERKjRNS_10MultiValueE13807
_ZNK4PLMD16ActionWithVector31getAllActionLabelsInMatrixChainERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EE22
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionWithVector.h.gcov.html b/coverage/core/ActionWithVector.h.gcov.html new file mode 100644 index 000000000000..a0ed55d4598e --- /dev/null +++ b/coverage/core/ActionWithVector.h.gcov.html @@ -0,0 +1,268 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionWithVector.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionWithVector.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:8988.9 %
Date:2024-04-19 12:12:35Functions: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_ActionWithVector_h
+      23             : #define __PLUMED_core_ActionWithVector_h
+      24             : 
+      25             : #include "ActionWithValue.h"
+      26             : #include "ActionAtomistic.h"
+      27             : #include "ActionWithArguments.h"
+      28             : #include "tools/MultiValue.h"
+      29             : #include <vector>
+      30             : 
+      31             : namespace PLMD {
+      32             : 
+      33             : class ActionWithVector:
+      34             :   public ActionAtomistic,
+      35             :   public ActionWithValue,
+      36             :   public ActionWithArguments
+      37             : {
+      38             :   friend class Value;
+      39             : private:
+      40             : /// Is the calculation to be done in serial
+      41             :   bool serial;
+      42             : /// The buffer that we use (we keep a copy here to avoid resizing)
+      43             :   std::vector<double> buffer;
+      44             : /// The list of active tasks
+      45             :   std::vector<unsigned> active_tasks;
+      46             :   /// Action that must be done before this one
+      47             :   ActionWithVector* action_to_do_before;
+      48             : /// Actions that must be done after this one
+      49             :   ActionWithVector* action_to_do_after;
+      50             : /// This is the list of actions that control the tasks that we do here
+      51             :   std::vector<ActionWithVector*> task_control_list;
+      52             : /// Work backwards through the chain to find an action that has either stored arguments or derivatives
+      53             :   ActionWithVector* getActionWithDerivatives( ActionWithVector* depaction );
+      54             : /// Check if there are any grids in the stream
+      55             :   bool checkForGrids(unsigned& nder) const ;
+      56             : ///  Run the task
+      57             :   void runTask( const unsigned& taskno, MultiValue& myvals ) const ;
+      58             : /// Gather the values that we intend to store in the buffer
+      59             :   void gatherAccumulators( const unsigned& taskCode, const MultiValue& myvals, std::vector<double>& buffer ) const ;
+      60             : /// Gather the forces on non-scalar quantities
+      61             :   void gatherForces( const unsigned& i, const MultiValue& myvals, std::vector<double>& forces ) const ;
+      62             : /// Get the size of the buffer array that holds the data we are gathering over the MPI loop
+      63             :   void getSizeOfBuffer( const unsigned& nactive_tasks, unsigned& bufsize );
+      64             : /// Get the number of quantities in the stream
+      65             :   void getNumberOfStreamedQuantities( const std::string& headstr, unsigned& nquants, unsigned& nmat, unsigned& maxcol, unsigned& nbookeeping );
+      66             : /// Get the number of stored values in the stream
+      67             :   bool getNumberOfStoredValues( Value* startat, unsigned& nvals, const unsigned& astart, const std::vector<Value*>& stopat );
+      68             : /// Add this action to the recursive chain
+      69             :   bool addActionToChain( const std::vector<std::string>& alabels, ActionWithVector* act );
+      70             : /// Check the chain for non scalar forces
+      71             :   bool checkChainForNonScalarForces() const ;
+      72             : /// Check if a force has been added on one of the components of this action
+      73             :   bool checkComponentsForForce() const ;
+      74             : /// Get the tasks that we need for forces
+      75             :   void getForceTasks( std::vector<unsigned>& force_tasks ) const ;
+      76             : /// Add the gathered forces to the inputs across the whole chain
+      77             :   void addForcesToInput( const std::vector<double>& forcesToApply, unsigned& ind );
+      78             : /// Check if this ation can reduce the number of tasks we perform
+      79             :   void canReduceTasks( std::vector<ActionWithVector*>& task_reducing_actions );
+      80             : /// Send information to arguments that tasks are reduced in depedent actions
+      81             :   void broadcastThatTasksAreReduced( ActionWithVector* aselect );
+      82             : /// Turn on task reduction flag in dependent actions
+      83             :   void updateTaskReductionFlag( bool& head_reduce_tasks );
+      84             : /// Check if a particular task is active at this time
+      85             :   void taskIsActive( const unsigned& current, int& flag ) const ;
+      86             : /// This is turned on if there is some action that needs all the tasks
+      87             :   bool never_reduce_tasks;
+      88             : /// Are we allowed to reduce the number of tasks being performed
+      89             :   bool reduce_tasks;
+      90             : /// Were the atoms retrieved in some earlier action
+      91             :   bool atomsWereRetrieved;
+      92             : /// This is used to build the argument store when we cannot use the chain
+      93             :   unsigned reallyBuildArgumentStore( const unsigned& argstart );
+      94             : protected:
+      95             : /// A vector that contains the start point for the argument derivatives
+      96             :   std::vector<unsigned> arg_deriv_starts;
+      97             : /// Assert if this action is part of a chain
+      98             :   bool done_in_chain;
+      99             : /// This updates whether or not we are using all the task reduction stuff
+     100             :   void updateTaskListReductionStatus();
+     101             : /// Run all calculations in serial
+     102             :   bool runInSerial() const ;
+     103             : /// Get the list of tasks that are active
+     104             :   std::vector<unsigned>& getListOfActiveTasks( ActionWithVector* action );
+     105             : /// Check if the arguments of this action depend on thearg
+     106             :   bool argumentDependsOn( const std::string& headstr, ActionWithVector* faction, Value* thearg );
+     107             : /// This sets up the arguments at the start of the calculation
+     108             :   unsigned buildArgumentStore( const unsigned& argstart );
+     109             : /// Run all the tasks in the list
+     110             :   void runAllTasks();
+     111             : /// Accumulate the forces from the Values
+     112             :   bool checkForForces();
+     113             : public:
+     114             :   static void registerKeywords( Keywords& keys );
+     115             :   explicit ActionWithVector(const ActionOptions&);
+     116             :   virtual ~ActionWithVector();
+     117             :   void lockRequests() override;
+     118             :   void unlockRequests() override;
+     119             :   virtual void prepare() override;
+     120             :   void retrieveAtoms( const bool& force=false ) override;
+     121             :   void calculateNumericalDerivatives(ActionWithValue* av) override;
+     122             : /// Are we running this command in a chain
+     123             :   bool actionInChain() const ;
+     124             : /// This is overwritten within ActionWithMatrix and is used to build the chain of just matrix actions
+     125             :   virtual void finishChainBuild( ActionWithVector* act );
+     126             : /// Check if there are any stored values in arguments
+     127             :   bool hasStoredArguments() const ;
+     128             : /// Return a pointer to the first action in the chain
+     129             :   const ActionWithVector* getFirstActionInChain() const ;
+     130             :   ActionWithVector* getFirstActionInChain();
+     131             : /// This is overridden in ActionWithMatrix
+     132          22 :   virtual void getAllActionLabelsInMatrixChain( std::vector<std::string>& matchain ) const {}
+     133             : /// Get the number of derivatives in the stream
+     134             :   void getNumberOfStreamedDerivatives( unsigned& nderivatives, Value* stopat );
+     135             : /// Get every the label of every value that is calculated in this chain
+     136             :   void getAllActionLabelsInChain( std::vector<std::string>& mylabels ) const ;
+     137             : /// We override clearInputForces here to ensure that forces are deleted from all values
+     138             :   void clearInputForces( const bool& force=false ) override;
+     139             : /// We override clearDerivatives here to prevent data in streams from being deleted
+     140             :   void clearDerivatives( const bool& force=false ) override;
+     141             : /// Check if we can be after another ActionWithVector
+     142      158372 :   virtual bool canBeAfterInChain( ActionWithVector* av ) { return true; }
+     143             : /// Do we always need to do all the tasks for this action
+     144        7651 :   virtual void areAllTasksRequired( std::vector<ActionWithVector*>& task_reducing_actions ) {}
+     145             : /// Find out how many tasks we need to perform in this loop
+     146             :   virtual void getNumberOfTasks( unsigned& ntasks );
+     147             : /// Check the status of the ith task
+     148     3769981 :   virtual int checkTaskStatus( const unsigned& taskno, int& flag ) const { return flag; }
+     149             : /// Check if we are in a subchain
+     150        3176 :   virtual bool isInSubChain( unsigned& nder ) { return false; }
+     151             : /// Get the additional tasks that are required here
+     152             :   virtual void getAdditionalTasksRequired( ActionWithVector* action, std::vector<unsigned>& atasks );
+     153             : /// setup the streamed quantities
+     154             :   virtual void setupStreamedComponents( const std::string& headstr, unsigned& nquants, unsigned& nmat, unsigned& maxcol, unsigned& nbookeeping );
+     155             : /// This we override to perform each individual task
+     156             :   virtual void performTask( const unsigned& current, MultiValue& myvals ) const = 0;
+     157             : /// This is used to ensure that all indices are updated when you do local average
+     158       13807 :   virtual void updateAdditionalIndices( const unsigned& ostrn, MultiValue& myvals ) const {}
+     159             : /// Gather the data from all the OpenMP threads
+     160             :   virtual void gatherThreads( const unsigned& nt, const unsigned& bufsize, const std::vector<double>& omp_buffer, std::vector<double>& buffer, MultiValue& myvals );
+     161             : /// Can be used to reduce the number of tasks that are performed when you use an ation from elsewhere
+     162           0 :   virtual void switchTaskReduction( const bool& task_reduction, ActionWithVector* aselect ) {}
+     163             : /// Gather all the data from the MPI processes
+     164             :   virtual void gatherProcesses( std::vector<double>& buffer );
+     165             : /// Gather the values that we intend to store in the buffer
+     166             :   virtual void gatherStoredValue( const unsigned& valindex, const unsigned& code, const MultiValue& myvals, const unsigned& bufstart, std::vector<double>& buffer ) const ;
+     167             : /// Get the force tasks that are active for this action
+     168             :   virtual void updateForceTasksFromValue( const Value* myval, std::vector<unsigned>& force_tasks ) const ;
+     169             : /// Check if there is a force that needs to be accumulated on the ith task
+     170             :   virtual bool checkForTaskForce( const unsigned& itask, const Value* myval ) const ;
+     171             : /// Gather the forces on a particular value
+     172             :   virtual void gatherForcesOnStoredValue( const Value* myval, const unsigned& itask, const MultiValue& myvals, std::vector<double>& forces ) const ;
+     173             : /// This is to transfer data from the buffer to the final value
+     174             :   void finishComputations( const std::vector<double>& buf );
+     175             : /// Apply the forces on this data
+     176             :   virtual void apply();
+     177             : };
+     178             : 
+     179             : inline
+     180             : bool ActionWithVector::actionInChain() const {
+     181   257385710 :   return (action_to_do_before!=NULL);
+     182             : }
+     183             : 
+     184             : inline
+     185             : bool ActionWithVector::runInSerial() const {
+     186       27741 :   return serial;
+     187             : }
+     188             : 
+     189             : }
+     190             : 
+     191             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionWithVirtualAtom.cpp.func-sort-c.html b/coverage/core/ActionWithVirtualAtom.cpp.func-sort-c.html new file mode 100644 index 000000000000..58b8309b8e83 --- /dev/null +++ b/coverage/core/ActionWithVirtualAtom.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionWithVirtualAtom.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionWithVirtualAtom.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:6363100.0 %
Date:2024-04-19 12:12:35Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD21ActionWithVirtualAtomC1ERKNS_13ActionOptionsE0
_ZN4PLMD21ActionWithVirtualAtom17setBoxDerivativesERKSt6vectorINS_13TensorGenericILj3ELj3EEESaIS3_EE2137
_ZN4PLMD21ActionWithVirtualAtom22setBoxDerivativesNoPbcEv2137
_ZN4PLMD21ActionWithVirtualAtom12requestAtomsERKSt6vectorINS_10AtomNumberESaIS2_EE10275
_ZN4PLMD21ActionWithVirtualAtomC2ERKNS_13ActionOptionsE10311
_ZN4PLMD21ActionWithVirtualAtom16registerKeywordsERNS_8KeywordsE10319
_ZN4PLMD21ActionWithVirtualAtom5applyEv35005
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionWithVirtualAtom.cpp.func.html b/coverage/core/ActionWithVirtualAtom.cpp.func.html new file mode 100644 index 000000000000..77afcc98e3c5 --- /dev/null +++ b/coverage/core/ActionWithVirtualAtom.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionWithVirtualAtom.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionWithVirtualAtom.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:6363100.0 %
Date:2024-04-19 12:12:35Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD21ActionWithVirtualAtom12requestAtomsERKSt6vectorINS_10AtomNumberESaIS2_EE10275
_ZN4PLMD21ActionWithVirtualAtom16registerKeywordsERNS_8KeywordsE10319
_ZN4PLMD21ActionWithVirtualAtom17setBoxDerivativesERKSt6vectorINS_13TensorGenericILj3ELj3EEESaIS3_EE2137
_ZN4PLMD21ActionWithVirtualAtom22setBoxDerivativesNoPbcEv2137
_ZN4PLMD21ActionWithVirtualAtom5applyEv35005
_ZN4PLMD21ActionWithVirtualAtomC1ERKNS_13ActionOptionsE0
_ZN4PLMD21ActionWithVirtualAtomC2ERKNS_13ActionOptionsE10311
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionWithVirtualAtom.cpp.gcov.html b/coverage/core/ActionWithVirtualAtom.cpp.gcov.html new file mode 100644 index 000000000000..6803b05eeee4 --- /dev/null +++ b/coverage/core/ActionWithVirtualAtom.cpp.gcov.html @@ -0,0 +1,208 @@ + + + + + + + + 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:6363100.0 %
Date:2024-04-19 12:12:35Functions:6785.7 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD21ActionWithVirtualAtom7setMassEd27089
_ZN4PLMD21ActionWithVirtualAtom9setChargeEd27089
_ZN4PLMD21ActionWithVirtualAtom11setPositionERKNS_13VectorGenericILj3EEE35088
_ZN4PLMD21ActionWithVirtualAtom19setAtomsDerivativesERKSt6vectorINS_13TensorGenericILj3ELj3EEESaIS3_EE35088
_ZN4PLMD21ActionWithVirtualAtom22getNumberOfDerivativesEv645585
_ZN4PLMD21ActionWithVirtualAtom27castToActionWithVirtualAtomEv6746795
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionWithVirtualAtom.h.func.html b/coverage/core/ActionWithVirtualAtom.h.func.html new file mode 100644 index 000000000000..c98b45445aa7 --- /dev/null +++ b/coverage/core/ActionWithVirtualAtom.h.func.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionWithVirtualAtom.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionWithVirtualAtom.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2222100.0 %
Date:2024-04-19 12:12:35Functions:66100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD21ActionWithVirtualAtom11setPositionERKNS_13VectorGenericILj3EEE35088
_ZN4PLMD21ActionWithVirtualAtom19setAtomsDerivativesERKSt6vectorINS_13TensorGenericILj3ELj3EEESaIS3_EE35088
_ZN4PLMD21ActionWithVirtualAtom22getNumberOfDerivativesEv645585
_ZN4PLMD21ActionWithVirtualAtom27castToActionWithVirtualAtomEv6746795
_ZN4PLMD21ActionWithVirtualAtom7setMassEd27089
_ZN4PLMD21ActionWithVirtualAtom9setChargeEd27089
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionWithVirtualAtom.h.gcov.html b/coverage/core/ActionWithVirtualAtom.h.gcov.html new file mode 100644 index 000000000000..aacf7dfbf6d0 --- /dev/null +++ b/coverage/core/ActionWithVirtualAtom.h.gcov.html @@ -0,0 +1,197 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionWithVirtualAtom.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionWithVirtualAtom.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2222100.0 %
Date:2024-04-19 12:12:35Functions:66100.0 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6CLTool5errorERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD6CLTool13readInputFileEiPPcP8_IO_FILES4_52
_ZN4PLMD6CLTool19readCommandLineArgsEiPPcP8_IO_FILE3627
_ZN4PLMD6CLTool21setRemainingToDefaultEP8_IO_FILE3679
_ZN4PLMD6CLTool9readInputEiPPcP8_IO_FILES4_3679
_ZN4PLMD13CLToolOptionsC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3755
_ZN4PLMD13CLToolOptionsC2ERKS0_RKNS_8KeywordsE3755
_ZN4PLMD6CLToolC2ERKNS_13CLToolOptionsE3755
_ZN4PLMD6CLTool9parseFlagERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERb25170
_ZN4PLMD6CLTool16registerKeywordsERNS_8KeywordsE86505
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/CLTool.cpp.func.html b/coverage/core/CLTool.cpp.func.html new file mode 100644 index 000000000000..d4dfb75601e2 --- /dev/null +++ b/coverage/core/CLTool.cpp.func.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - core/CLTool.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - CLTool.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:859985.9 %
Date:2024-04-19 12:12:35Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD13CLToolOptionsC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3755
_ZN4PLMD13CLToolOptionsC2ERKS0_RKNS_8KeywordsE3755
_ZN4PLMD6CLTool13readInputFileEiPPcP8_IO_FILES4_52
_ZN4PLMD6CLTool16registerKeywordsERNS_8KeywordsE86505
_ZN4PLMD6CLTool19readCommandLineArgsEiPPcP8_IO_FILE3627
_ZN4PLMD6CLTool21setRemainingToDefaultEP8_IO_FILE3679
_ZN4PLMD6CLTool5errorERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD6CLTool9parseFlagERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERb25170
_ZN4PLMD6CLTool9readInputEiPPcP8_IO_FILES4_3679
_ZN4PLMD6CLToolC2ERKNS_13CLToolOptionsE3755
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/CLTool.cpp.gcov.html b/coverage/core/CLTool.cpp.gcov.html new file mode 100644 index 000000000000..e52bb21f3a30 --- /dev/null +++ b/coverage/core/CLTool.cpp.gcov.html @@ -0,0 +1,293 @@ + + + + + + + + LCOV - plumed test coverage - core/CLTool.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - CLTool.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:859985.9 %
Date:2024-04-19 12:12:35Functions: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        3755 : CLToolOptions::CLToolOptions(const std::string &name):
+      29        3755 :   line(1,name),
+      30        3755 :   keys(emptyKeys)
+      31             : {
+      32        3755 : }
+      33             : 
+      34        3755 : CLToolOptions::CLToolOptions(const CLToolOptions& co, const Keywords& k):
+      35        3755 :   line(co.line),
+      36        3755 :   keys(k)
+      37             : {
+      38        3755 : }
+      39             : 
+      40       86505 : void CLTool::registerKeywords( Keywords& keys ) {
+      41      173010 :   keys.addFlag("--help/-h",false,"print this help");
+      42       86505 : }
+      43             : 
+      44        3755 : CLTool::CLTool(const CLToolOptions& co ):
+      45        3755 :   name(co.line[0]),
+      46        3755 :   keywords(co.keys),
+      47        3755 :   inputdata(unset)
+      48             : {
+      49        3755 : }
+      50             : 
+      51       25170 : void CLTool::parseFlag( const std::string&key, bool&t ) {
+      52       25170 :   plumed_massert(keywords.exists(key),"keyword " + key + " has not been registered");
+      53       50340 :   plumed_massert(keywords.style(key,"flag"),"keyword " + key + " has not been registered as a flag");
+      54           0 :   plumed_assert(inputData.count(key)>0);
+      55       50340 :   if( inputData[key]=="true") t=true;
+      56       44852 :   else if( inputData[key]=="false") t=false;
+      57           0 :   else plumed_error();
+      58       25170 : }
+      59             : 
+      60        3679 : bool CLTool::readInput( int argc, char**argv, FILE* in, FILE*out ) {
+      61        3679 :   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        3679 :   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        3627 : bool CLTool::readCommandLineArgs( int argc, char**argv, FILE*out ) {
+      71        3627 :   plumed_assert(inputdata==commandline);
+      72        3627 :   std::string prefix(""), a(""), thiskey;
+      73             : 
+      74             :   // Set all flags to default false
+      75       66586 :   for(unsigned k=0; k<keywords.size(); ++k) {
+      76       62959 :     thiskey=keywords.get(k);
+      77      155102 :     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       14813 :   for(int i=1; i<argc; i++) {
+      83       22372 :     a=prefix+argv[i];
+      84       11186 :     if(a.length()==0) continue;
+      85       22372 :     if(a=="-h" || a=="--help") {
+      86             :       printhelp=true;
+      87             :     } else {
+      88             :       bool found=false;
+      89      353260 :       for(unsigned k=0; k<keywords.size(); ++k) {
+      90      342074 :         thiskey=keywords.get(k);
+      91      684148 :         if( keywords.style(thiskey,"flag") ) {
+      92       71370 :           if( a==thiskey ) { found=true; inputData[thiskey]="true"; }
+      93             :         } else {
+      94      270704 :           if( a==thiskey ) {
+      95        3904 :             prefix=thiskey+"="; found=true;
+      96        7808 :             inputData.insert(std::pair<std::string,std::string>(thiskey,""));
+      97      533600 :           } else if(Tools::startWith(a,thiskey+"=")) {
+      98        4540 :             a.erase(0,a.find("=")+1); prefix=""; found=true;
+      99             :             if(inputData.count(thiskey)==0) {
+     100        1274 :               inputData.insert(std::pair<std::string,std::string>(thiskey,a));
+     101             :             } else {
+     102        3903 :               inputData[thiskey]=a;
+     103             :             }
+     104             :           }
+     105             :         }
+     106             :       }
+     107       11186 :       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       11186 :     if(printhelp) break;
+     116             :   }
+     117             : 
+     118        3627 :   if(!printhelp) setRemainingToDefault(out);
+     119             : 
+     120        3627 :   if(printhelp) {
+     121             :     std::fprintf(out,"Usage: %s [options] \n\n", name.c_str() );
+     122           0 :     keywords.print( out );
+     123             :   }
+     124             : 
+     125        3627 :   return !printhelp;
+     126             : }
+     127             : 
+     128        3679 : void CLTool::setRemainingToDefault(FILE* out) {
+     129             :   std::string def, thiskey;
+     130       67646 :   for(unsigned k=0; k<keywords.size(); ++k) {
+     131       63967 :     thiskey=keywords.get(k);
+     132      127934 :     if( keywords.style(thiskey,"compulsory") ) {
+     133             :       if( inputData.count(thiskey)==0 ) {
+     134        1929 :         if( keywords.getDefaultValue(thiskey,def) ) {
+     135        1929 :           plumed_assert( def.length()>0 );
+     136        3858 :           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        3679 : }
+     145             : 
+     146          52 : bool CLTool::readInputFile( int argc, char**argv, FILE* in, FILE*out ) {
+     147          52 :   plumed_assert(inputdata==ifile);
+     148             : 
+     149             :   // Check if use is just asking for help
+     150             :   std::string a;
+     151          95 :   for(int i=1; i<argc; i++) {
+     152          43 :     a=argv[i];
+     153          43 :     if(a.length()==0) continue;
+     154          86 :     if(a=="-h" || a=="--help") {
+     155             :       std::fprintf(out,"Usage: %s < inputFile \n", name.c_str() );
+     156             :       std::fprintf(out,"inputFile should contain one directive per line.  The directives should come from amongst the following\n\n");
+     157           0 :       keywords.print( out );
+     158             :       return false;
+     159             :     }
+     160             :   }
+     161             : 
+     162             :   FILE* mystdin=in;
+     163             : // call fclose when fp_deleter goes out of scope
+     164          43 :   auto deleter=[](auto f) { std::fclose(f); };
+     165             :   std::unique_ptr<FILE,decltype(deleter)> fp_deleter(nullptr,deleter);
+     166             : 
+     167          52 :   if(argc==2) {
+     168          43 :     mystdin=std::fopen(argv[1],"r");
+     169          43 :     if(!mystdin) {
+     170           0 :       std::fprintf(stderr,"ERROR: cannot open file %s\n\n",argv[1]);
+     171             :       std::fprintf(out,"Usage: %s < inputFile \n", name.c_str() );
+     172             :       std::fprintf(out,"inputFile should contain one directive per line.  The directives should come from amongst the following\n\n");
+     173           0 :       keywords.print( out );
+     174             :       return false;
+     175             :     }
+     176             :     fp_deleter.reset(mystdin);
+     177             :   }
+     178             : 
+     179          52 :   plumed_assert(mystdin);
+     180             : 
+     181             :   char buffer[256]; std::string line; line.resize(256);
+     182         863 :   while(fgets(buffer,256,mystdin)) {
+     183             :     line=buffer;
+     184       24504 :     for(unsigned i=0; i<line.length(); ++i) if(line[i]=='#' || line[i]=='\n') line.erase(i);
+     185         811 :     Tools::stripLeadingAndTrailingBlanks( line );
+     186         811 :     if(line.length()==0) continue;
+     187         774 :     std::sscanf(line.c_str(),"%255s",buffer);
+     188         774 :     std::string keyword=buffer; bool found=false;
+     189       16220 :     for(unsigned i=0; i<keywords.size(); ++i) {
+     190       15446 :       std::string thiskey=keywords.get(i);
+     191       15446 :       if(thiskey==keyword) {
+     192             :         found=true;
+     193         774 :         std::size_t keypos=line.find_first_of(keyword)+keyword.length();
+     194        1548 :         inputData.insert(std::pair<std::string,std::string>(thiskey,line.substr(keypos)));
+     195         774 :         Tools::stripLeadingAndTrailingBlanks( inputData[thiskey] );
+     196             :       }
+     197             :     }
+     198         774 :     if(!found) {
+     199           0 :       std::fprintf(stderr,"ERROR in input for command line tool %s : unknown keyword %s found in input file\n\n",name.c_str(),keyword.c_str());
+     200             :       std::fprintf(out,"Usage: %s < inputFile \n", name.c_str() );
+     201             :       std::fprintf(out,"inputFile should contain one directive per line.  The directives should come from amongst the following\n\n");
+     202           0 :       keywords.print( out );
+     203             :       return false;
+     204             :     }
+     205             :   }
+     206             : 
+     207          52 :   setRemainingToDefault(out);
+     208             :   return true;
+     209             : }
+     210             : 
+     211           0 : [[noreturn]] void CLTool::error( const std::string& msg ) {
+     212           0 :   std::fprintf(stderr,"ERROR : in input for command line tool %s : %s\n",name.c_str(),msg.c_str());
+     213           0 :   plumed_error();
+     214             : }
+     215             : 
+     216             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/CLTool.h.func-sort-c.html b/coverage/core/CLTool.h.func-sort-c.html new file mode 100644 index 000000000000..4f58bd1de8b6 --- /dev/null +++ b/coverage/core/CLTool.h.func-sort-c.html @@ -0,0 +1,133 @@ + + + + + + + + LCOV - plumed test coverage - core/CLTool.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - CLTool.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:253473.5 %
Date:2024-04-19 12:12:35Functions:131586.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6CLTool5parseIfEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_0
_ZN4PLMD6CLToolD0Ev0
_ZN4PLMD6CLTool11parseVectorIjEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIT_SaISB_EE2
_ZNK4PLMD6CLTool11descriptionB5cxx11Ev4
_ZN4PLMD6CLTool11parseVectorIiEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIT_SaISB_EE40
_ZN4PLMD6CLTool5parseIyEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_40
_ZN4PLMD6CLTool5parseImEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_80
_ZN4PLMD6CLTool11parseVectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEbRKS7_RSt6vectorIT_SaISB_EE162
_ZN4PLMD6CLTool11parseVectorIdEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIT_SaISB_EE166
_ZN4PLMD6CLTool5parseIxEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_919
_ZN4PLMD6CLTool5parseIjEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_967
_ZN4PLMD6CLTool5parseIiEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_1818
_ZN4PLMD6CLTool5parseIdEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_1932
_ZN4PLMD6CLToolD2Ev3745
_ZN4PLMD6CLTool5parseINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEbRKS7_RT_25942
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/CLTool.h.func.html b/coverage/core/CLTool.h.func.html new file mode 100644 index 000000000000..41bcce21dc15 --- /dev/null +++ b/coverage/core/CLTool.h.func.html @@ -0,0 +1,133 @@ + + + + + + + + LCOV - plumed test coverage - core/CLTool.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - CLTool.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:253473.5 %
Date:2024-04-19 12:12:35Functions:131586.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6CLTool11parseVectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEbRKS7_RSt6vectorIT_SaISB_EE162
_ZN4PLMD6CLTool11parseVectorIdEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIT_SaISB_EE166
_ZN4PLMD6CLTool11parseVectorIiEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIT_SaISB_EE40
_ZN4PLMD6CLTool11parseVectorIjEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIT_SaISB_EE2
_ZN4PLMD6CLTool5parseINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEbRKS7_RT_25942
_ZN4PLMD6CLTool5parseIdEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_1932
_ZN4PLMD6CLTool5parseIfEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_0
_ZN4PLMD6CLTool5parseIiEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_1818
_ZN4PLMD6CLTool5parseIjEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_967
_ZN4PLMD6CLTool5parseImEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_80
_ZN4PLMD6CLTool5parseIxEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_919
_ZN4PLMD6CLTool5parseIyEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_40
_ZN4PLMD6CLToolD0Ev0
_ZN4PLMD6CLToolD2Ev3745
_ZNK4PLMD6CLTool11descriptionB5cxx11Ev4
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/CLTool.h.gcov.html b/coverage/core/CLTool.h.gcov.html new file mode 100644 index 000000000000..1d905b54ab0d --- /dev/null +++ b/coverage/core/CLTool.h.gcov.html @@ -0,0 +1,242 @@ + + + + + + + + LCOV - plumed test coverage - core/CLTool.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - CLTool.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:253473.5 %
Date:2024-04-19 12:12:35Functions: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             : #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        7510 : 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           4 :   virtual std::string description()const {return "(no description available)";}
+      98             : /// virtual destructor to allow inheritance
+      99        3745 :   virtual ~CLTool() {}
+     100             : };
+     101             : 
+     102             : template<class T>
+     103       31698 : bool CLTool::parse(const std::string&key,T&t) {
+     104       31698 :   plumed_massert(keywords.exists(key),"keyword " + key + " has not been registered");
+     105       63396 :   if(keywords.style(key,"compulsory") ) {
+     106           0 :     if(inputData.count(key)==0) error("missing data for keyword " + key);
+     107        4722 :     bool check=Tools::convertNoexcept(inputData[key],t);
+     108        4722 :     if(!check) error("data input for keyword " + key + " has wrong type");
+     109             :     return true;
+     110             :   }
+     111       24781 :   if( inputData.count(key)==0 ) return false;
+     112        2195 :   Tools::convert(inputData[key],t);
+     113        2195 :   return true;
+     114             : }
+     115             : // very limited support and check: take more from core/Action.h parseVector
+     116             : template<class T>
+     117         370 : bool CLTool::parseVector(const std::string&key,std::vector<T>&t) {
+     118             : 
+     119             :   // Check keyword has been registered
+     120         370 :   plumed_massert(keywords.exists(key), "keyword " + key + " has not been registered");
+     121             :   // initial size
+     122         370 :   unsigned size=t.size();
+     123             :   bool skipcheck=false;
+     124         370 :   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         740 :   plumed_massert(inputData[key]!="false","compulsory keyword "+std::string(key)+"has no data");
+     129         370 :   std::vector<std::string> words=Tools::getWords(inputData[key],"\t\n ,");
+     130         370 :   t.resize(0);
+     131         370 :   if(words.size()==0)return false;
+     132             : 
+     133         779 :   for(unsigned i=0; i<words.size(); ++i) {
+     134             :     T v;
+     135         491 :     Tools::convert(words[i],v);
+     136         491 :     t.push_back(v);
+     137             :   }
+     138             :   // check the size
+     139         288 :   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         576 :   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         370 : }
+     160             : 
+     161             : 
+     162             : 
+     163             : }
+     164             : 
+     165             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/CLToolMain.cpp.func-sort-c.html b/coverage/core/CLToolMain.cpp.func-sort-c.html new file mode 100644 index 000000000000..94566bd74f09 --- /dev/null +++ b/coverage/core/CLToolMain.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - core/CLToolMain.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - CLToolMain.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11213384.2 %
Date:2024-04-19 12:12:35Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10CLToolMain3runEiPPcP8_IO_FILES4_RNS_12CommunicatorE5140
_ZN4PLMD10CLToolMainC2Ev5140
_ZN4PLMD10CLToolMainD0Ev5140
_ZN4PLMD10CLToolMainD2Ev5140
_ZN4PLMD10CLToolMain3cmdESt17basic_string_viewIcSt11char_traitsIcEERKNS_11TypesafePtrE15697
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/CLToolMain.cpp.func.html b/coverage/core/CLToolMain.cpp.func.html new file mode 100644 index 000000000000..bcb28d9e24c1 --- /dev/null +++ b/coverage/core/CLToolMain.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - core/CLToolMain.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - CLToolMain.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11213384.2 %
Date:2024-04-19 12:12:35Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10CLToolMain3cmdESt17basic_string_viewIcSt11char_traitsIcEERKNS_11TypesafePtrE15697
_ZN4PLMD10CLToolMain3runEiPPcP8_IO_FILES4_RNS_12CommunicatorE5140
_ZN4PLMD10CLToolMainC2Ev5140
_ZN4PLMD10CLToolMainD0Ev5140
_ZN4PLMD10CLToolMainD2Ev5140
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/CLToolMain.cpp.gcov.html b/coverage/core/CLToolMain.cpp.gcov.html new file mode 100644 index 000000000000..edd0f7057c2c --- /dev/null +++ b/coverage/core/CLToolMain.cpp.gcov.html @@ -0,0 +1,364 @@ + + + + + + + + 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:11213384.2 %
Date:2024-04-19 12:12:35Functions: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 "tools/Subprocess.h"
+      31             : #include <string>
+      32             : #include <cstdlib>
+      33             : #include <cstdio>
+      34             : #include <iostream>
+      35             : #include <algorithm>
+      36             : #include <memory>
+      37             : 
+      38             : namespace PLMD {
+      39             : 
+      40        5140 : CLToolMain::CLToolMain():
+      41        5140 :   argc(0),
+      42        5140 :   in(stdin),
+      43        5140 :   out(stdout)
+      44             : {
+      45        5140 : }
+      46             : 
+      47       10280 : CLToolMain::~CLToolMain() {
+      48             : // empty destructor to delete unique_ptr
+      49       10280 : }
+      50             : 
+      51             : #define CHECK_NULL(val,word) plumed_assert(val) << "NULL pointer received in cmd(\"CLTool " << word <<  "\"";
+      52             : 
+      53       15697 : void CLToolMain::cmd(std::string_view 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 Tools::FastStringUnorderedMap<int> word_map = {
+      62             : #include "CLToolMainMap.inc"
+      63       15697 :   };
+      64             : 
+      65             :   gch::small_vector<std::string_view> words;
+      66       15697 :   Tools::getWordsSimple(words,word);
+      67       15697 :   unsigned nw=words.size();
+      68       15697 :   if(nw==0) {
+      69             :     // do nothing
+      70             :   } else {
+      71             :     int iword=-1;
+      72             :     const char*const*v;
+      73             :     const char*vv;
+      74             :     const auto it=word_map.find(words[0]);
+      75       15697 :     if(it!=word_map.end()) iword=it->second;
+      76       15697 :     switch(iword) {
+      77             :     case cmd_setArgc:
+      78        5056 :       CHECK_NULL(val,word);
+      79        5056 :       argc=val.get<int>();
+      80        5056 :       break;
+      81             :     case cmd_setArgv:
+      82        5056 :       CHECK_NULL(val,word);
+      83        5056 :       v=val.get<const char*const*>(argc);
+      84       32742 :       for(int i=0; i<argc; ++i) argv.push_back(std::string(v[i]));
+      85             :       break;
+      86             :     case cmd_setArgvLine:
+      87          84 :       CHECK_NULL(val,word);
+      88             :       vv=val.get<const char*>();
+      89          84 :       argv=Tools::getWords(vv);
+      90          84 :       break;
+      91             :     case cmd_setIn:
+      92           0 :       CHECK_NULL(val,word);
+      93           0 :       in=val.get<FILE*>();
+      94           0 :       break;
+      95             :     case cmd_setOut:
+      96          17 :       CHECK_NULL(val,word);
+      97          17 :       out=val.get<FILE*>();
+      98          17 :       break;
+      99         344 :     case cmd_setMPIComm:
+     100         344 :       comm.Set_comm(val);
+     101             :       break;
+     102           0 :     case cmd_setMPIFComm:
+     103           0 :       comm.Set_fcomm(val);
+     104             :       break;
+     105             :     case cmd_run:
+     106        5140 :       CHECK_NULL(val,word);
+     107        5140 :       argc=argv.size();
+     108             :       {
+     109       33314 :         int n=0; for(int i=0; i<argc; ++i) n+=argv[i].length()+1;
+     110        5140 :         std::vector<char> args(n);
+     111        5140 :         std::vector<char*> vvv(argc);
+     112             :         char* ptr=&args[0];
+     113       33314 :         for(int i=0; i<argc; ++i) {
+     114       28174 :           vvv[i]=ptr;
+     115      244237 :           for(unsigned c=0; c<argv[i].length(); ++c) {
+     116      216063 :             *ptr=argv[i][c]; ptr++;
+     117             :           }
+     118       28174 :           *ptr=0; ptr++;
+     119             :         }
+     120        5140 :         val.set(int(run(argc,&vvv[0],in,out,comm)));
+     121             :       }
+     122        5140 :       break;
+     123           0 :     default:
+     124           0 :       plumed_error() << "cannot interpret cmd(\"CLTool " << word << "\"). check plumed developers manual to see the available commands.";
+     125             :       break;
+     126             :     }
+     127             :   }
+     128       15697 : }
+     129             : 
+     130             : /**
+     131             : This is the entry point to the command line tools
+     132             : included in the plumed library.
+     133             : */
+     134             : 
+     135        5140 : int CLToolMain::run(int argc, char **argv,FILE*in,FILE*out,Communicator& pc) {
+     136             :   int i;
+     137             :   bool printhelp=false;
+     138             : 
+     139        5140 :   DLLoader dlloader;
+     140             : 
+     141        5140 :   std::string root=config::getPlumedRoot();
+     142             : 
+     143             :   bool standalone_executable=false;
+     144             : 
+     145             : // Start parsing options
+     146        5140 :   std::string prefix("");
+     147        5140 :   std::string a("");
+     148        9856 :   for(i=1; i<argc; i++) {
+     149       19712 :     a=prefix+argv[i];
+     150        9856 :     if(a.length()==0) continue;
+     151       29568 :     if(a=="help" || a=="-h" || a=="--help") {
+     152             :       printhelp=true;
+     153             :       break;
+     154        9852 :     } else if(a=="--has-mpi") {
+     155           0 :       if(Communicator::initialized()) return 0;
+     156           0 :       else return 1;
+     157        9852 :     } else if(a=="--has-cregex") {
+     158           0 :       return (config::hasCregex()?0:1);
+     159        9852 :     } else if(a=="--has-dlopen") {
+     160           0 :       return (config::hasDlopen()?0:1);
+     161        9852 :     } else if(a=="--has-molfile") {
+     162           0 :       return (config::hasMolfile()?0:1);
+     163        9852 :     } else if(a=="--has-external-molfile") {
+     164           0 :       return (config::hasExternalMolfile()?0:1);
+     165        9852 :     } else if(a=="--has-zlib") {
+     166           0 :       return (config::hasZlib()?0:1);
+     167        9852 :     } else if(a=="--has-xdrfile") {
+     168             :       return 0; // always ok
+     169        9852 :     } else if(a=="--is-installed") {
+     170         765 :       return (config::isInstalled()?0:1);
+     171        9087 :     } else if(a=="--no-mpi") {
+     172             : // this is ignored, as it is parsed in main
+     173        4696 :       continue;
+     174        4391 :     } else if(a=="--mpi") {
+     175             : // this is ignored, as it is parsed in main
+     176           0 :       continue;
+     177        4391 :     } else if(a=="--standalone-executable") {
+     178             :       standalone_executable=true;
+     179        8782 :     } else if(Tools::startWith(a,"--load=")) {
+     180          10 :       a.erase(0,a.find("=")+1);
+     181             :       prefix="";
+     182          10 :       dlloader.load(a);
+     183        4381 :     } else if(a=="--load") {
+     184             :       prefix="--load=";
+     185        4371 :     } else if(a[0]=='-') {
+     186           0 :       std::string msg="ERROR: Unknown option " +a;
+     187           0 :       std::fprintf(stderr,"%s\n",msg.c_str());
+     188             :       return 1;
+     189             :     } else break;
+     190             :   }
+     191             : 
+     192             : // Check if plumedRoot/patches/ directory exists (as a further check)
+     193        4375 :   if(!standalone_executable) {
+     194        4375 :     std::vector<std::string> files=Tools::ls(root);
+     195        4375 :     if(find(files.begin(),files.end(),"patches")==files.end()) {
+     196             :       std::string msg=
+     197           0 :         "WARNING: I cannot find "+root+"/patches/ directory. Set PLUMED_ROOT or reinstall PLUMED\n\n";
+     198           0 :       std::fprintf(stderr,"%s",msg.c_str());
+     199             :     }
+     200        4375 :   }
+     201             : 
+     202             : // Build list of available C++ tools:
+     203        4375 :   std::vector<std::string> availableCxx=cltoolRegister().list();
+     204             : // Build list of available shell tools:
+     205             :   std::vector<std::string> availableShell;
+     206        4375 :   if(!standalone_executable) {
+     207             :     std::vector<std::string> tmp;
+     208        8750 :     tmp=Tools::ls(std::string(root+"/scripts"));
+     209       35000 :     for(unsigned j=0; j<tmp.size(); ++j) {
+     210       30625 :       size_t ff=tmp[j].find(".sh");
+     211       30625 :       if(ff==std::string::npos) tmp[j].erase();
+     212       30625 :       else                 tmp[j].erase(ff);
+     213             :     }
+     214       35000 :     for(unsigned j=0; j<tmp.size(); ++j) if(tmp[j].length()>0) availableShell.push_back(tmp[j]);
+     215        4375 :   }
+     216             : 
+     217        4375 :   if(printhelp) {
+     218             :     std::string msg=
+     219             :       "Usage: plumed [options] [command] [command options]\n"
+     220             :       "  plumed [command] -h|--help: to print help for a specific command\n"
+     221             :       "Options:\n"
+     222             :       "  [help|-h|--help]          : to print this help\n"
+     223             :       "  [--is-installed]          : fails if plumed is not installed\n"
+     224             :       "  [--has-mpi]               : fails if plumed is running without MPI\n"
+     225             :       "  [--has-dlopen]            : fails if plumed is compiled without dlopen\n"
+     226             :       "  [--load LIB]              : loads a shared object (typically a plugin library)\n"
+     227             :       "  [--standalone-executable] : tells plumed not to look for commands implemented as scripts\n"
+     228           4 :       "Commands:\n";
+     229             :     std::fprintf(out,"%s",msg.c_str());
+     230          80 :     for(unsigned j=0; j<availableCxx.size(); ++j) {
+     231         152 :       auto cl=cltoolRegister().create(dlloader.getHandles(),CLToolOptions(availableCxx[j]));
+     232          76 :       plumed_assert(cl);
+     233         152 :       std::string manual=availableCxx[j]+" : "+cl->description();
+     234             :       std::fprintf(out,"  plumed %s\n", manual.c_str());
+     235          76 :     }
+     236          32 :     for(unsigned j=0; j<availableShell.size(); ++j) {
+     237             :       std::string manual;
+     238          28 :       if(Subprocess::available()) {
+     239          56 :         auto cmd=config::getEnvCommand()+" \""+root+"/scripts/"+availableShell[j]+".sh\" --description";
+     240          28 :         auto proc=Subprocess(cmd);
+     241             :         // we only need the first line, so this is fine:
+     242          28 :         proc.getline(manual);
+     243             :         // process will be killed immediately after
+     244          28 :       } else {
+     245             :         manual="(doc not avail)";
+     246             :       }
+     247          56 :       manual= availableShell[j]+" : "+manual;
+     248             :       std::fprintf(out,"  plumed %s\n", manual.c_str());
+     249             :     }
+     250             :     return 0;
+     251             :   }
+     252        4371 :   if(i==argc) {
+     253             :     std::fprintf(out,"%s","Nothing to do. Use 'plumed help' for help\n");
+     254             :     return 0;
+     255             :   }
+     256             : 
+     257             : // this is the command to be executed:
+     258        4371 :   std::string command(argv[i]);
+     259             : 
+     260        4371 :   if(find(availableCxx.begin(),availableCxx.end(),command)!=availableCxx.end()) {
+     261        7358 :     auto cl=cltoolRegister().create(dlloader.getHandles(),CLToolOptions(command));
+     262        3679 :     plumed_assert(cl);
+     263             :     // Read the command line options (returns false if we are just printing help)
+     264        3679 :     if( !cl->readInput( argc-i,&argv[i],in,out ) ) { return 0; }
+     265        3679 :     int ret=cl->main(in,out,pc);
+     266             :     return ret;
+     267        3679 :   }
+     268             : 
+     269         692 :   if(find(availableShell.begin(),availableShell.end(),command)!=availableShell.end()) {
+     270         692 :     plumed_massert(in==stdin,"shell tools can only work on stdin");
+     271         692 :     plumed_massert(out==stdout,"shell tools can only work on stdin");
+     272        1384 :     std::string cmd=config::getEnvCommand()+" \""+root+"/scripts/"+command+".sh\"";
+     273        2641 :     for(int j=i+1; j<argc; j++) cmd+=std::string(" ")+argv[j];
+     274         692 :     int r=std::system(cmd.c_str());
+     275             : // this is necessary since system seems to return numbers which are multiple
+     276             : // of 256. this would make the interpretation by the shell wrong
+     277             : // I just return 1 in case of failure and 0 in case of success
+     278         692 :     if(r!=0) return 1;
+     279         579 :     else return 0;
+     280             :   }
+     281             : 
+     282           0 :   std::string msg="ERROR: unknown command " + command + ". Use 'plumed help' for help";
+     283           0 :   std::fprintf(stderr,"%s\n",msg.c_str());
+     284             :   return 1;
+     285             : 
+     286        9515 : }
+     287             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/CLToolRegister.cpp.func-sort-c.html b/coverage/core/CLToolRegister.cpp.func-sort-c.html new file mode 100644 index 000000000000..0da648478b72 --- /dev/null +++ b/coverage/core/CLToolRegister.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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:183158.1 %
Date:2024-04-19 12:12:35Functions:5771.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14CLToolRegister6createERKNS_13CLToolOptionsE0
_ZNK4PLMD14CLToolRegister7getKeysERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD14CLToolRegister11printManualERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKb1
_ZN4PLMD14CLToolRegister6createERKSt6vectorIPvSaIS2_EERKNS_13CLToolOptionsE3755
_ZNK4PLMD14CLToolRegister4listB5cxx11Ev4375
_ZN4PLMD14CLToolRegister3addENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPFSt10unique_ptrINS_6CLToolESt14default_deleteIS8_EERKNS_13CLToolOptionsEEPFvRNS_8KeywordsEE96681
_ZN4PLMD14cltoolRegisterEv201928
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/CLToolRegister.cpp.func.html b/coverage/core/CLToolRegister.cpp.func.html new file mode 100644 index 000000000000..d58f13aa0ab4 --- /dev/null +++ b/coverage/core/CLToolRegister.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:183158.1 %
Date:2024-04-19 12:12:35Functions:5771.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14CLToolRegister11printManualERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKb1
_ZN4PLMD14CLToolRegister3addENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPFSt10unique_ptrINS_6CLToolESt14default_deleteIS8_EERKNS_13CLToolOptionsEEPFvRNS_8KeywordsEE96681
_ZN4PLMD14CLToolRegister6createERKNS_13CLToolOptionsE0
_ZN4PLMD14CLToolRegister6createERKSt6vectorIPvSaIS2_EERKNS_13CLToolOptionsE3755
_ZN4PLMD14cltoolRegisterEv201928
_ZNK4PLMD14CLToolRegister4listB5cxx11Ev4375
_ZNK4PLMD14CLToolRegister7getKeysERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/CLToolRegister.cpp.gcov.html b/coverage/core/CLToolRegister.cpp.gcov.html new file mode 100644 index 000000000000..7c4cb4bbe1a6 --- /dev/null +++ b/coverage/core/CLToolRegister.cpp.gcov.html @@ -0,0 +1,165 @@ + + + + + + + + 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:183158.1 %
Date:2024-04-19 12:12:35Functions: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 "CLToolRegister.h"
+      23             : #include "tools/Tools.h"
+      24             : #include "CLTool.h"
+      25             : #include <algorithm>
+      26             : #include <iostream>
+      27             : 
+      28             : 
+      29             : namespace PLMD {
+      30             : 
+      31      201928 : CLToolRegister& cltoolRegister() {
+      32      207016 :   static CLToolRegister ans;
+      33      201928 :   return ans;
+      34             : }
+      35             : 
+      36           0 : std::unique_ptr<CLTool> CLToolRegister::create(const CLToolOptions&ao) {
+      37             :   std::vector<void*> images; // empty vector
+      38           0 :   return create(images,ao);
+      39             : }
+      40             : 
+      41        3755 : std::unique_ptr<CLTool> CLToolRegister::create(const std::vector<void*> & images,const CLToolOptions&ao) {
+      42        3755 :   if(ao.line.size()<1)return nullptr;
+      43        3755 :   auto & content=get(images,ao.line[0]);
+      44        3755 :   CLToolOptions nao( ao,content.keys );
+      45        3755 :   return content.create(nao);
+      46             : }
+      47             : 
+      48       96681 : CLToolRegister::ID CLToolRegister::add(std::string key,creator_pointer cp,keywords_pointer kp) {
+      49             :   // this force each action to be registered as an uppercase string
+      50      417243 :   if ( std::any_of( std::begin( key ), std::end( key ), []( char c ) { return ( std::isupper( c ) ); } ) ) plumed_error() << "CLTool: " + key + " cannot be registered, use only LOWERCASE characters";
+      51             : 
+      52       96681 :   Keywords keys; kp(keys);
+      53      290043 :   return RegisterBase::add(key,Pointers{cp,keys});
+      54       96681 : }
+      55             : 
+      56           1 : bool CLToolRegister::printManual( const std::string& cltool, const bool& spelling ) {
+      57           1 :   if( spelling && check(cltool) ) {
+      58           0 :     auto cl=get(cltool);
+      59           0 :     cl.keys.print_spelling();
+      60             :     return true;
+      61           1 :   } else if ( check(cltool) ) {
+      62           0 :     auto cl=get(cltool);
+      63           0 :     cl.keys.print_html();
+      64             :     return true;
+      65             :   } else {
+      66             :     return false;
+      67             :   }
+      68             : }
+      69             : 
+      70           0 : std::vector<std::string> CLToolRegister::getKeys(const std::string& cltool)const {
+      71           0 :   if ( check(cltool) ) {
+      72           0 :     auto cl=get(cltool);
+      73             :     auto k=cl.keys.getKeys();
+      74           0 :     std::cerr<<k.size()<<"\n";
+      75           0 :     for(unsigned i=0; i<k.size(); i++) std::cerr<<k[i]<<"\n";
+      76             :     return k;
+      77           0 :   } else {
+      78             :     std::vector<std::string> empty;
+      79             :     return empty;
+      80           0 :   }
+      81             : }
+      82             : 
+      83             : 
+      84        4375 : std::vector<std::string> CLToolRegister::list()const {
+      85        4375 :   return RegisterBase::getKeys();
+      86             : }
+      87             : 
+      88             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/CLToolRegister.h.func-sort-c.html b/coverage/core/CLToolRegister.h.func-sort-c.html new file mode 100644 index 000000000000..7a7f6eaeee07 --- /dev/null +++ b/coverage/core/CLToolRegister.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage - core/CLToolRegister.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - CLToolRegister.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22100.0 %
Date:2024-04-19 12:12:35Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/CLToolRegister.h.func.html b/coverage/core/CLToolRegister.h.func.html new file mode 100644 index 000000000000..822252d8ac2e --- /dev/null +++ b/coverage/core/CLToolRegister.h.func.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage - core/CLToolRegister.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - CLToolRegister.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22100.0 %
Date:2024-04-19 12:12:35Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/CLToolRegister.h.gcov.html b/coverage/core/CLToolRegister.h.gcov.html new file mode 100644 index 000000000000..218efb01ab4c --- /dev/null +++ b/coverage/core/CLToolRegister.h.gcov.html @@ -0,0 +1,185 @@ + + + + + + + + LCOV - plumed test coverage - core/CLToolRegister.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - CLToolRegister.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22100.0 %
Date:2024-04-19 12:12:35Functions: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_core_CLToolRegister_h
+      23             : #define __PLUMED_core_CLToolRegister_h
+      24             : 
+      25             : #include "RegisterBase.h"
+      26             : #include "tools/Keywords.h"
+      27             : 
+      28             : namespace PLMD {
+      29             : 
+      30             : class CLTool;
+      31             : class CLToolOptions;
+      32             : 
+      33      386715 : struct CLToolRegisterPointers {
+      34             : /// Pointer to a function which, given the options, create an CLTool
+      35             :   typedef std::unique_ptr<CLTool>(*creator_pointer)(const CLToolOptions&);
+      36             : /// Pointer to a function which, returns the keywords allowed
+      37             :   typedef void(*keywords_pointer)(Keywords&);
+      38             :   creator_pointer create;
+      39             :   Keywords keys;
+      40             : };
+      41             : 
+      42             : 
+      43             : /// Same as ActionRegister, but for CLTools
+      44        5088 : class CLToolRegister :
+      45             :   public RegisterBase<CLToolRegisterPointers> {
+      46             :   typedef CLToolRegisterPointers::creator_pointer creator_pointer;
+      47             :   typedef CLToolRegisterPointers::keywords_pointer keywords_pointer;
+      48             :   typedef CLToolRegisterPointers Pointers;
+      49             : 
+      50             :   // this is necessary to avoid warnings on getKeys overload.
+      51             :   // notice that RegisterBase<CLToolRegisterPointers>::getKeys returns
+      52             :   // the list of keys (here: CLTools). conversely
+      53             :   // CLToolRegister::getKeys(std::string name) returns the options
+      54             :   // associated to CLTool name.
+      55             :   // We hide the former here, which is actually implemented by list()
+      56             :   // not to break existing code.
+      57             :   using RegisterBase<CLToolRegisterPointers>::getKeys;
+      58             : 
+      59             : public:
+      60             : /// Register a new class.
+      61             : /// \param key The name of the directive to be used in the input file
+      62             : /// \param cp  A pointer to a function which creates an object of that class
+      63             : /// \param kp  A pointer to a function which returns the allowed keywords
+      64             :   ID add(std::string key,creator_pointer cp,keywords_pointer kp);
+      65             : /// Create an CLTool of the type indicated in the options
+      66             : /// \param ao object containing information for initialization, such as the full input line, a pointer to PlumedMain, etc
+      67             :   std::unique_ptr<CLTool> create(const CLToolOptions&ao);
+      68             :   std::unique_ptr<CLTool> create(const std::vector<void*> & images,const CLToolOptions&ao);
+      69             : /// Returns a list of the allowed CLTools
+      70             :   std::vector<std::string> list()const;
+      71             : /// Print out the instructions for using the tool in html ready for input into the manual
+      72             :   bool printManual(const std::string& cltool,const bool& spelling);
+      73             : /// Return all the keys of this cltool
+      74             :   std::vector<std::string> getKeys(const std::string& cltool)const;
+      75             : };
+      76             : 
+      77             : /// Function returning a reference to the CLToolRegister.
+      78             : /// \relates CLToolRegister
+      79             : /// To avoid problems with order of initialization, this function contains
+      80             : /// a static CLToolRegister which is built the first time the function is called.
+      81             : /// In this manner, it is always initialized before it's used
+      82             : CLToolRegister& cltoolRegister();
+      83             : 
+      84             : }
+      85             : 
+      86             : 
+      87             : /// Shortcut for CLTool registration
+      88             : /// \relates PLMD::CLToolRegister
+      89             : /// For easier registration, this file also provides a macro PLUMED_REGISTER_CLTOOL.
+      90             : /// \param classname the name of the class to be registered
+      91             : /// \param directive a string containing the corresponding directive
+      92             : /// This macro should be used in the .cpp file of the corresponding class
+      93             : #define PLUMED_REGISTER_CLTOOL(classname,directive) \
+      94             :   namespace { class classname##RegisterMe{ \
+      95             :     CLToolRegister::ID id; \
+      96             :     static std::unique_ptr<CLTool> create(const CLToolOptions&ao) { \
+      97             :       return std::make_unique<classname>(ao); \
+      98             :     } \
+      99             :   public: \
+     100             :     classname##RegisterMe() : \
+     101             :       id(PLMD::cltoolRegister().add(directive,create,classname::registerKeywords)) \
+     102             :     {} \
+     103             :     ~classname##RegisterMe(){PLMD::cltoolRegister().remove(id);} \
+     104             :   } classname##RegisterMeObject; }
+     105             : 
+     106             : 
+     107             : #endif
+     108             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/Colvar.cpp.func-sort-c.html b/coverage/core/Colvar.cpp.func-sort-c.html new file mode 100644 index 000000000000..8daf15d2bae9 --- /dev/null +++ b/coverage/core/Colvar.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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:3030100.0 %
Date:2024-04-19 12:12:35Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6ColvarC1ERKNS_13ActionOptionsE0
_ZN4PLMD6ColvarC2ERKNS_13ActionOptionsE2040
_ZN4PLMD6Colvar12requestAtomsERKSt6vectorINS_10AtomNumberESaIS2_EE2473
_ZN4PLMD6Colvar16registerKeywordsERNS_8KeywordsE4046
_ZN4PLMD6Colvar22setBoxDerivativesNoPbcEPNS_5ValueE111941
_ZN4PLMD6Colvar5applyEv142059
_ZN4PLMD6Colvar22setBoxDerivativesNoPbcERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERS1_IS5_SaIS5_EERS1_INS_13TensorGenericILj3ELj3EEESaISC_EE452796
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/Colvar.cpp.func.html b/coverage/core/Colvar.cpp.func.html new file mode 100644 index 000000000000..043ed2ef0c12 --- /dev/null +++ b/coverage/core/Colvar.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:3030100.0 %
Date:2024-04-19 12:12:35Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6Colvar12requestAtomsERKSt6vectorINS_10AtomNumberESaIS2_EE2473
_ZN4PLMD6Colvar16registerKeywordsERNS_8KeywordsE4046
_ZN4PLMD6Colvar22setBoxDerivativesNoPbcEPNS_5ValueE111941
_ZN4PLMD6Colvar22setBoxDerivativesNoPbcERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERS1_IS5_SaIS5_EERS1_INS_13TensorGenericILj3ELj3EEESaISC_EE452796
_ZN4PLMD6Colvar5applyEv142059
_ZN4PLMD6ColvarC1ERKNS_13ActionOptionsE0
_ZN4PLMD6ColvarC2ERKNS_13ActionOptionsE2040
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/Colvar.cpp.gcov.html b/coverage/core/Colvar.cpp.gcov.html new file mode 100644 index 000000000000..afe82e71e5cb --- /dev/null +++ b/coverage/core/Colvar.cpp.gcov.html @@ -0,0 +1,150 @@ + + + + + + + + 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:3030100.0 %
Date:2024-04-19 12:12:35Functions: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 "tools/OpenMP.h"
+      24             : #include <vector>
+      25             : #include <string>
+      26             : 
+      27             : namespace PLMD {
+      28             : 
+      29        2040 : Colvar::Colvar(const ActionOptions&ao):
+      30             :   Action(ao),
+      31             :   ActionAtomistic(ao),
+      32        2040 :   ActionWithValue(ao)
+      33             : {
+      34        2040 : }
+      35             : 
+      36        4046 : void Colvar::registerKeywords( Keywords& keys ) {
+      37        4046 :   Action::registerKeywords( keys );
+      38        4046 :   ActionWithValue::registerKeywords( keys );
+      39        4046 :   ActionAtomistic::registerKeywords( keys );
+      40        8092 :   keys.addFlag("NOPBC",false,"ignore the periodic boundary conditions when calculating distances");
+      41        4046 : }
+      42             : 
+      43        2473 : void Colvar::requestAtoms(const std::vector<AtomNumber> & a) {
+      44             : // Tell actionAtomistic what atoms we are getting
+      45        2473 :   ActionAtomistic::requestAtoms(a);
+      46             : // Resize the derivatives of all atoms
+      47        6431 :   for(int i=0; i<getNumberOfComponents(); ++i) getPntrToComponent(i)->resizeDerivatives(3*a.size()+9);
+      48        2472 : }
+      49             : 
+      50      142059 : void Colvar::apply() {
+      51      142059 :   if( !checkForForces() ) return ;
+      52      108595 :   unsigned ind=0;
+      53      108595 :   if( getNumberOfAtoms()>0 ) setForcesOnAtoms( getForcesToApply(), ind );
+      54          88 :   else setForcesOnCell( getForcesToApply(), ind );
+      55             : }
+      56             : 
+      57      452796 : void Colvar::setBoxDerivativesNoPbc( const std::vector<Vector>& pos, std::vector<std::vector<Vector> >& derivs, std::vector<Tensor>& virial ) {
+      58      452796 :   unsigned nat=pos.size();
+      59     1117962 :   for(unsigned i=0; i<virial.size(); ++i) {
+      60     2180461 :     virial[i].zero(); for(unsigned j=0; j<nat; j++) virial[i]-=Tensor(pos[j],derivs[i][j]);
+      61             :   }
+      62      452796 : }
+      63             : 
+      64      111941 : void Colvar::setBoxDerivativesNoPbc(Value* v) {
+      65      111941 :   Tensor virial;
+      66             :   unsigned nat=getNumberOfAtoms();
+      67    32945271 :   for(unsigned i=0; i<nat; i++) virial-=Tensor(getPosition(i),
+      68    16416665 :                                           Vector(v->getDerivative(3*i+0),
+      69             :                                               v->getDerivative(3*i+1),
+      70    32833330 :                                               v->getDerivative(3*i+2)));
+      71      111941 :   setBoxDerivatives(v,virial);
+      72      111941 : }
+      73             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/Colvar.h.func-sort-c.html b/coverage/core/Colvar.h.func-sort-c.html new file mode 100644 index 000000000000..94fba3117968 --- /dev/null +++ b/coverage/core/Colvar.h.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - core/Colvar.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - Colvar.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2424100.0 %
Date:2024-04-19 12:12:35Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6ColvarD2Ev2000
_ZN4PLMD6Colvar22getNumberOfDerivativesEv148778
_ZN4PLMD6Colvar17setBoxDerivativesEPNS_5ValueERKNS_13TensorGenericILj3ELj3EEE262339
_ZN4PLMD6Colvar19setAtomsDerivativesEPNS_5ValueEiRKNS_13VectorGenericILj3EEE18275017
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/Colvar.h.func.html b/coverage/core/Colvar.h.func.html new file mode 100644 index 000000000000..cd507fcbba63 --- /dev/null +++ b/coverage/core/Colvar.h.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - core/Colvar.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - Colvar.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2424100.0 %
Date:2024-04-19 12:12:35Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6Colvar17setBoxDerivativesEPNS_5ValueERKNS_13TensorGenericILj3ELj3EEE262339
_ZN4PLMD6Colvar19setAtomsDerivativesEPNS_5ValueEiRKNS_13VectorGenericILj3EEE18275017
_ZN4PLMD6Colvar22getNumberOfDerivativesEv148778
_ZN4PLMD6ColvarD2Ev2000
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/Colvar.h.gcov.html b/coverage/core/Colvar.h.gcov.html new file mode 100644 index 000000000000..f0f5e547e7c0 --- /dev/null +++ b/coverage/core/Colvar.h.gcov.html @@ -0,0 +1,194 @@ + + + + + + + + LCOV - plumed test coverage - core/Colvar.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - Colvar.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2424100.0 %
Date:2024-04-19 12:12:35Functions:44100.0 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD22DataPassingObjectTypedIfE10share_dataERKSt6vectorINS_10AtomNumberESaIS3_EERKS2_IjSaIjEEPNS_5ValueE0
_ZN4PLMD22DataPassingObjectTypedIfE10share_dataERKjS3_PNS_5ValueE0
_ZN4PLMD22DataPassingObjectTypedIfE13rescale_forceERKjRKdPNS_5ValueE0
_ZN4PLMD22DataPassingObjectTypedIfE15setForcePointerERKNS_11TypesafePtrERKSt6vectorIjSaIjEE0
_ZN4PLMD22DataPassingObjectTypedIfE15setValuePointerERKNS_11TypesafePtrERKSt6vectorIjSaIjEERKb0
_ZN4PLMD22DataPassingObjectTypedIfE17saveValueAsDoubleERKNS_11TypesafePtrE0
_ZN4PLMD22DataPassingObjectTypedIfE7setDataEPNS_5ValueE0
_ZN4PLMD22DataPassingObjectTypedIfE9add_forceEPNS_5ValueE0
_ZN4PLMD22DataPassingObjectTypedIfE9add_forceERKSt6vectorINS_10AtomNumberESaIS3_EERKS2_IjSaIjEEPNS_5ValueE0
_ZN4PLMD22DataPassingObjectTypedIfE9add_forceERKSt6vectorIiSaIiEEPNS_5ValueE0
_ZN4PLMDL10getPointerIKfEEvRKNS_11TypesafePtrERKSt6vectorIjSaIjEERKjSB_RPT_0
_ZN4PLMDL10getPointerIfEEvRKNS_11TypesafePtrERKSt6vectorIjSaIjEERKjSA_RPT_0
_ZNK4PLMD22DataPassingObjectTypedIdE9MD2doubleERKNS_11TypesafePtrE0
_ZNK4PLMD22DataPassingObjectTypedIfE10share_dataERSt6vectorIdSaIdEE0
_ZNK4PLMD22DataPassingObjectTypedIfE9MD2doubleERKNS_11TypesafePtrE0
_ZN4PLMD22DataPassingObjectTypedIdE13rescale_forceERKjRKdPNS_5ValueE150
_ZNK4PLMD22DataPassingObjectTypedIdE10share_dataERSt6vectorIdSaIdEE1350
_ZN4PLMD22DataPassingObjectTypedIdE17saveValueAsDoubleERKNS_11TypesafePtrE5053
_ZN4PLMD17DataPassingObject6createEj7786
_ZN4PLMD22DataPassingObjectTypedIdE7setDataEPNS_5ValueE12447
_ZN4PLMD22DataPassingObjectTypedIdE9add_forceEPNS_5ValueE39638
_ZN4PLMD22DataPassingObjectTypedIdE9add_forceERKSt6vectorINS_10AtomNumberESaIS3_EERKS2_IjSaIjEEPNS_5ValueE61881
_ZN4PLMD22DataPassingObjectTypedIdE10share_dataERKSt6vectorINS_10AtomNumberESaIS3_EERKS2_IjSaIjEEPNS_5ValueE69782
_ZN4PLMD22DataPassingObjectTypedIdE9add_forceERKSt6vectorIiSaIiEEPNS_5ValueE79413
_ZN4PLMDL10getPointerIdEEvRKNS_11TypesafePtrERKSt6vectorIjSaIjEERKjSA_RPT_192786
_ZN4PLMD22DataPassingObjectTypedIdE10share_dataERKjS3_PNS_5ValueE238205
_ZN4PLMD22DataPassingObjectTypedIdE15setForcePointerERKNS_11TypesafePtrERKSt6vectorIjSaIjEE281168
_ZN4PLMDL10getPointerIKdEEvRKNS_11TypesafePtrERKSt6vectorIjSaIjEERKjSB_RPT_303122
_ZN4PLMD22DataPassingObjectTypedIdE15setValuePointerERKNS_11TypesafePtrERKSt6vectorIjSaIjEERKb444949
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/DataPassingObject.cpp.func.html b/coverage/core/DataPassingObject.cpp.func.html new file mode 100644 index 000000000000..27a6348fe7cf --- /dev/null +++ b/coverage/core/DataPassingObject.cpp.func.html @@ -0,0 +1,189 @@ + + + + + + + + LCOV - plumed test coverage - core/DataPassingObject.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - DataPassingObject.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:687689.5 %
Date:2024-04-19 12:12:35Functions:142948.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD17DataPassingObject6createEj7786
_ZN4PLMD22DataPassingObjectTypedIdE10share_dataERKSt6vectorINS_10AtomNumberESaIS3_EERKS2_IjSaIjEEPNS_5ValueE69782
_ZN4PLMD22DataPassingObjectTypedIdE10share_dataERKjS3_PNS_5ValueE238205
_ZN4PLMD22DataPassingObjectTypedIdE13rescale_forceERKjRKdPNS_5ValueE150
_ZN4PLMD22DataPassingObjectTypedIdE15setForcePointerERKNS_11TypesafePtrERKSt6vectorIjSaIjEE281168
_ZN4PLMD22DataPassingObjectTypedIdE15setValuePointerERKNS_11TypesafePtrERKSt6vectorIjSaIjEERKb444949
_ZN4PLMD22DataPassingObjectTypedIdE17saveValueAsDoubleERKNS_11TypesafePtrE5053
_ZN4PLMD22DataPassingObjectTypedIdE7setDataEPNS_5ValueE12447
_ZN4PLMD22DataPassingObjectTypedIdE9add_forceEPNS_5ValueE39638
_ZN4PLMD22DataPassingObjectTypedIdE9add_forceERKSt6vectorINS_10AtomNumberESaIS3_EERKS2_IjSaIjEEPNS_5ValueE61881
_ZN4PLMD22DataPassingObjectTypedIdE9add_forceERKSt6vectorIiSaIiEEPNS_5ValueE79413
_ZN4PLMD22DataPassingObjectTypedIfE10share_dataERKSt6vectorINS_10AtomNumberESaIS3_EERKS2_IjSaIjEEPNS_5ValueE0
_ZN4PLMD22DataPassingObjectTypedIfE10share_dataERKjS3_PNS_5ValueE0
_ZN4PLMD22DataPassingObjectTypedIfE13rescale_forceERKjRKdPNS_5ValueE0
_ZN4PLMD22DataPassingObjectTypedIfE15setForcePointerERKNS_11TypesafePtrERKSt6vectorIjSaIjEE0
_ZN4PLMD22DataPassingObjectTypedIfE15setValuePointerERKNS_11TypesafePtrERKSt6vectorIjSaIjEERKb0
_ZN4PLMD22DataPassingObjectTypedIfE17saveValueAsDoubleERKNS_11TypesafePtrE0
_ZN4PLMD22DataPassingObjectTypedIfE7setDataEPNS_5ValueE0
_ZN4PLMD22DataPassingObjectTypedIfE9add_forceEPNS_5ValueE0
_ZN4PLMD22DataPassingObjectTypedIfE9add_forceERKSt6vectorINS_10AtomNumberESaIS3_EERKS2_IjSaIjEEPNS_5ValueE0
_ZN4PLMD22DataPassingObjectTypedIfE9add_forceERKSt6vectorIiSaIiEEPNS_5ValueE0
_ZN4PLMDL10getPointerIKdEEvRKNS_11TypesafePtrERKSt6vectorIjSaIjEERKjSB_RPT_303122
_ZN4PLMDL10getPointerIKfEEvRKNS_11TypesafePtrERKSt6vectorIjSaIjEERKjSB_RPT_0
_ZN4PLMDL10getPointerIdEEvRKNS_11TypesafePtrERKSt6vectorIjSaIjEERKjSA_RPT_192786
_ZN4PLMDL10getPointerIfEEvRKNS_11TypesafePtrERKSt6vectorIjSaIjEERKjSA_RPT_0
_ZNK4PLMD22DataPassingObjectTypedIdE10share_dataERSt6vectorIdSaIdEE1350
_ZNK4PLMD22DataPassingObjectTypedIdE9MD2doubleERKNS_11TypesafePtrE0
_ZNK4PLMD22DataPassingObjectTypedIfE10share_dataERSt6vectorIdSaIdEE0
_ZNK4PLMD22DataPassingObjectTypedIfE9MD2doubleERKNS_11TypesafePtrE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/DataPassingObject.cpp.gcov.html b/coverage/core/DataPassingObject.cpp.gcov.html new file mode 100644 index 000000000000..2462aa8e0397 --- /dev/null +++ b/coverage/core/DataPassingObject.cpp.gcov.html @@ -0,0 +1,271 @@ + + + + + + + + LCOV - plumed test coverage - core/DataPassingObject.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - DataPassingObject.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:687689.5 %
Date:2024-04-19 12:12:35Functions:142948.3 %
+
+ + + + + + + + +

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

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

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

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

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD21DataPassingToolsTypedIfE16getRealPrecisionEv0
_ZNK4PLMD21DataPassingToolsTypedIfE9MD2doubleERKNS_11TypesafePtrE0
_ZNK4PLMD21DataPassingToolsTypedIfE9double2MDERKdRKNS_11TypesafePtrE1
_ZNK4PLMD21DataPassingToolsTypedIdE9MD2doubleERKNS_11TypesafePtrE2850
_ZNK4PLMD21DataPassingToolsTypedIdE9double2MDERKdRKNS_11TypesafePtrE7267
_ZNK4PLMD21DataPassingToolsTypedIdE16getRealPrecisionEv8972
_ZNK4PLMD16DataPassingTools17getUnitConversionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE22909
_ZN4PLMD16DataPassingTools6createEj807390
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/DataPassingTools.cpp.func.html b/coverage/core/DataPassingTools.cpp.func.html new file mode 100644 index 000000000000..51f05ed66d43 --- /dev/null +++ b/coverage/core/DataPassingTools.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - core/DataPassingTools.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - DataPassingTools.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:192382.6 %
Date:2024-04-19 12:12:35Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD16DataPassingTools6createEj807390
_ZNK4PLMD16DataPassingTools17getUnitConversionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE22909
_ZNK4PLMD21DataPassingToolsTypedIdE16getRealPrecisionEv8972
_ZNK4PLMD21DataPassingToolsTypedIdE9MD2doubleERKNS_11TypesafePtrE2850
_ZNK4PLMD21DataPassingToolsTypedIdE9double2MDERKdRKNS_11TypesafePtrE7267
_ZNK4PLMD21DataPassingToolsTypedIfE16getRealPrecisionEv0
_ZNK4PLMD21DataPassingToolsTypedIfE9MD2doubleERKNS_11TypesafePtrE0
_ZNK4PLMD21DataPassingToolsTypedIfE9double2MDERKdRKNS_11TypesafePtrE1
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/DataPassingTools.cpp.gcov.html b/coverage/core/DataPassingTools.cpp.gcov.html new file mode 100644 index 000000000000..849360458764 --- /dev/null +++ b/coverage/core/DataPassingTools.cpp.gcov.html @@ -0,0 +1,149 @@ + + + + + + + + LCOV - plumed test coverage - core/DataPassingTools.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - DataPassingTools.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:192382.6 %
Date:2024-04-19 12:12:35Functions:6875.0 %
+
+ + + + + + + + +

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

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

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

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD19DomainDecompositionC2ERKNS_13ActionOptionsE0
_ZNK4PLMD19DomainDecomposition26getNumberOfForcesToRescaleEv0
_ZN4PLMD19DomainDecomposition10readBinaryERSi114
_ZN4PLMD19DomainDecomposition11writeBinaryERSo114
_ZN4PLMD19DomainDecomposition11getFullListERKNS_11TypesafePtrE116
_ZN4PLMD19DomainDecomposition13clearFullListEv116
_ZN4PLMD19DomainDecomposition14createFullListERKNS_11TypesafePtrE116
_ZN4PLMD19DomainDecomposition11DomainComms6enableERNS_12CommunicatorE385
_ZN4PLMD19DomainDecomposition8Set_commERNS_12CommunicatorE385
_ZNK4PLMD19DomainDecomposition11getGatindexEv459
_ZN4PLMD19DomainDecomposition18setAtomsContiguousEi537
_ZN4PLMD12_GLOBAL__N_118interpretEnvStringEPKcS2_719
_ZNK4PLMD19DomainDecomposition9getDdStepEv900
_ZN4PLMD19DomainDecomposition16setAtomsGatindexERKNS_11TypesafePtrEb978
_ZN4PLMD19DomainDecompositionC1ERKNS_13ActionOptionsE1091
_ZN4PLMD19DomainDecomposition16registerKeywordsERNS_8KeywordsE1093
_ZN4PLMD19DomainDecomposition8shareAllEv1143
_ZN4PLMD19DomainDecomposition14setAtomsNlocalEi1515
_ZN4PLMD19DomainDecomposition17getAllActiveAtomsERSt6vectorINS_10AtomNumberESaIS2_EE2159
_ZN4PLMD19DomainDecomposition14sumOverDomainsEPNS_5ValueE3989
_ZN4PLMD19DomainDecomposition18broadcastToDomainsEPNS_5ValueE66268
_ZN4PLMD12_GLOBAL__N_117getenvForceUniqueEv69646
_ZN4PLMD19DomainDecomposition5applyEv69960
_ZN4PLMD19DomainDecomposition5resetEv69960
_ZN4PLMD19DomainDecomposition4waitEv70084
_ZN4PLMD19DomainDecomposition5shareERKSt6vectorINS_10AtomNumberESaIS2_EE70092
_ZN4PLMD19DomainDecomposition5shareEv70675
_ZN4PLMD19DomainDecomposition17resetForStepStartEv72266
_ZN4PLMD19DomainDecomposition15setForcePointerERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_11TypesafePtrE216771
_ZN4PLMD19DomainDecomposition8setStartERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKj353243
_ZN4PLMD19DomainDecomposition9setStrideERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKj353243
_ZN4PLMD19DomainDecomposition15setValuePointerERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_11TypesafePtrE357265
_ZNK4PLMD19DomainDecomposition16getNumberOfAtomsEv535094
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/DomainDecomposition.cpp.func.html b/coverage/core/DomainDecomposition.cpp.func.html new file mode 100644 index 000000000000..9e231cd8c466 --- /dev/null +++ b/coverage/core/DomainDecomposition.cpp.func.html @@ -0,0 +1,205 @@ + + + + + + + + LCOV - plumed test coverage - core/DomainDecomposition.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - DomainDecomposition.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:26127794.2 %
Date:2024-04-19 12:12:35Functions:313393.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12_GLOBAL__N_117getenvForceUniqueEv69646
_ZN4PLMD12_GLOBAL__N_118interpretEnvStringEPKcS2_719
_ZN4PLMD19DomainDecomposition10readBinaryERSi114
_ZN4PLMD19DomainDecomposition11DomainComms6enableERNS_12CommunicatorE385
_ZN4PLMD19DomainDecomposition11getFullListERKNS_11TypesafePtrE116
_ZN4PLMD19DomainDecomposition11writeBinaryERSo114
_ZN4PLMD19DomainDecomposition13clearFullListEv116
_ZN4PLMD19DomainDecomposition14createFullListERKNS_11TypesafePtrE116
_ZN4PLMD19DomainDecomposition14setAtomsNlocalEi1515
_ZN4PLMD19DomainDecomposition14sumOverDomainsEPNS_5ValueE3989
_ZN4PLMD19DomainDecomposition15setForcePointerERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_11TypesafePtrE216771
_ZN4PLMD19DomainDecomposition15setValuePointerERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_11TypesafePtrE357265
_ZN4PLMD19DomainDecomposition16registerKeywordsERNS_8KeywordsE1093
_ZN4PLMD19DomainDecomposition16setAtomsGatindexERKNS_11TypesafePtrEb978
_ZN4PLMD19DomainDecomposition17getAllActiveAtomsERSt6vectorINS_10AtomNumberESaIS2_EE2159
_ZN4PLMD19DomainDecomposition17resetForStepStartEv72266
_ZN4PLMD19DomainDecomposition18broadcastToDomainsEPNS_5ValueE66268
_ZN4PLMD19DomainDecomposition18setAtomsContiguousEi537
_ZN4PLMD19DomainDecomposition4waitEv70084
_ZN4PLMD19DomainDecomposition5applyEv69960
_ZN4PLMD19DomainDecomposition5resetEv69960
_ZN4PLMD19DomainDecomposition5shareERKSt6vectorINS_10AtomNumberESaIS2_EE70092
_ZN4PLMD19DomainDecomposition5shareEv70675
_ZN4PLMD19DomainDecomposition8Set_commERNS_12CommunicatorE385
_ZN4PLMD19DomainDecomposition8setStartERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKj353243
_ZN4PLMD19DomainDecomposition8shareAllEv1143
_ZN4PLMD19DomainDecomposition9setStrideERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKj353243
_ZN4PLMD19DomainDecompositionC1ERKNS_13ActionOptionsE1091
_ZN4PLMD19DomainDecompositionC2ERKNS_13ActionOptionsE0
_ZNK4PLMD19DomainDecomposition11getGatindexEv459
_ZNK4PLMD19DomainDecomposition16getNumberOfAtomsEv535094
_ZNK4PLMD19DomainDecomposition26getNumberOfForcesToRescaleEv0
_ZNK4PLMD19DomainDecomposition9getDdStepEv900
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/DomainDecomposition.cpp.gcov.html b/coverage/core/DomainDecomposition.cpp.gcov.html new file mode 100644 index 000000000000..853604281feb --- /dev/null +++ b/coverage/core/DomainDecomposition.cpp.gcov.html @@ -0,0 +1,577 @@ + + + + + + + + LCOV - plumed test coverage - core/DomainDecomposition.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - DomainDecomposition.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:26127794.2 %
Date:2024-04-19 12:12:35Functions:313393.9 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD19DomainDecomposition11DomainCommsC2Ev1091
_ZNK4PLMD19DomainDecomposition6onStepEv1707
_ZN4PLMD19DomainDecomposition25castToDomainDecompositionEv3699
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/DomainDecomposition.h.func.html b/coverage/core/DomainDecomposition.h.func.html new file mode 100644 index 000000000000..122603fedb44 --- /dev/null +++ b/coverage/core/DomainDecomposition.h.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - core/DomainDecomposition.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - DomainDecomposition.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:44100.0 %
Date:2024-04-19 12:12:35Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD19DomainDecomposition11DomainCommsC2Ev1091
_ZN4PLMD19DomainDecomposition25castToDomainDecompositionEv3699
_ZNK4PLMD19DomainDecomposition6onStepEv1707
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/DomainDecomposition.h.gcov.html b/coverage/core/DomainDecomposition.h.gcov.html new file mode 100644 index 000000000000..fd126ac15957 --- /dev/null +++ b/coverage/core/DomainDecomposition.h.gcov.html @@ -0,0 +1,191 @@ + + + + + + + + LCOV - plumed test coverage - core/DomainDecomposition.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - DomainDecomposition.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:44100.0 %
Date:2024-04-19 12:12:35Functions:33100.0 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD16ExchangePatterns7getFlagERi0
_ZN4PLMD16ExchangePatterns7getListERKNS_11TypesafePtrE0
_ZN4PLMD16ExchangePatterns7setFlagEi0
_ZN4PLMD16ExchangePatterns7setNofREi0
_ZN4PLMD16ExchangePatterns7setSeedEi0
_ZN4PLMD16ExchangePatternsC2Ev806370
_ZN4PLMD16ExchangePatternsD2Ev806370
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ExchangePatterns.cpp.func.html b/coverage/core/ExchangePatterns.cpp.func.html new file mode 100644 index 000000000000..6757895a803e --- /dev/null +++ b/coverage/core/ExchangePatterns.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - core/ExchangePatterns.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ExchangePatterns.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:52619.2 %
Date:2024-04-19 12:12:35Functions:2728.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD16ExchangePatterns7getFlagERi0
_ZN4PLMD16ExchangePatterns7getListERKNS_11TypesafePtrE0
_ZN4PLMD16ExchangePatterns7setFlagEi0
_ZN4PLMD16ExchangePatterns7setNofREi0
_ZN4PLMD16ExchangePatterns7setSeedEi0
_ZN4PLMD16ExchangePatternsC2Ev806370
_ZN4PLMD16ExchangePatternsD2Ev806370
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ExchangePatterns.cpp.gcov.html b/coverage/core/ExchangePatterns.cpp.gcov.html new file mode 100644 index 000000000000..e9b575d1d715 --- /dev/null +++ b/coverage/core/ExchangePatterns.cpp.gcov.html @@ -0,0 +1,149 @@ + + + + + + + + LCOV - plumed test coverage - core/ExchangePatterns.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ExchangePatterns.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:52619.2 %
Date:2024-04-19 12:12:35Functions: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      806370 : ExchangePatterns::ExchangePatterns():
+      28      806370 :   PatternFlag(NONE),
+      29      806370 :   NumberOfReplicas(1)
+      30      806370 : {}
+      31             : 
+      32      806370 : ExchangePatterns::~ExchangePatterns() {}
+      33             : 
+      34           0 : void ExchangePatterns::setNofR(const int nrepl) {
+      35           0 :   NumberOfReplicas=nrepl;
+      36           0 : }
+      37             : 
+      38           0 : void ExchangePatterns::setFlag(const int flag) {
+      39           0 :   PatternFlag=flag;
+      40           0 : }
+      41             : 
+      42           0 : void ExchangePatterns::getFlag(int &flag) {
+      43           0 :   flag=PatternFlag;
+      44           0 : }
+      45             : 
+      46           0 : void ExchangePatterns::setSeed(const int seed)
+      47             : {
+      48           0 :   random.setSeed(seed);
+      49           0 : }
+      50             : 
+      51           0 : void ExchangePatterns::getList(const TypesafePtr & ind)
+      52             : {
+      53           0 :   auto iind=ind.get<int*>(NumberOfReplicas);
+      54           0 :   switch(PatternFlag)
+      55             :   {
+      56             :   case RANDOM:
+      57           0 :     for(int i=0; i<NumberOfReplicas; i++) {
+      58             :       int stat=1;
+      59           0 :       while(stat) {
+      60             :         stat=0;
+      61           0 :         iind[i] = (int) (random.U01()*NumberOfReplicas);
+      62           0 :         for(int j=0; j<i; j++) if(iind[i]==iind[j]) stat=1;
+      63             :       }
+      64             :     }
+      65             :     break;
+      66             :   case NEIGHBOR:
+      67           0 :     for(int i=0; i<NumberOfReplicas; i++) iind[i]=i;
+      68             :     break;
+      69             :   }
+      70           0 : }
+      71             : 
+      72             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/FlexibleBin.cpp.func-sort-c.html b/coverage/core/FlexibleBin.cpp.func-sort-c.html new file mode 100644 index 000000000000..2025c22d3d3f --- /dev/null +++ b/coverage/core/FlexibleBin.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - core/FlexibleBin.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - FlexibleBin.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11514678.8 %
Date:2024-04-19 12:12:35Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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

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

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

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

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

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14GenericMolInfo11getBackboneERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EERKS7_RS1_IS1_INS_10AtomNumberESaISD_EESaISF_EE26
_ZN4PLMD14GenericMolInfo15interpretSymbolERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorINS_10AtomNumberESaISA_EE635
_ZN4PLMD14GenericMolInfo16registerKeywordsERNS_8KeywordsE93
_ZN4PLMD14GenericMolInfo18getSpecialKeywordsB5cxx11Ev1
_ZN4PLMD14GenericMolInfo7prepareEv5123
_ZN4PLMD14GenericMolInfoC1ERKNS_13ActionOptionsE91
_ZN4PLMD14GenericMolInfoC2ERKNS_13ActionOptionsE0
_ZN4PLMD14GenericMolInfoD0Ev91
_ZN4PLMD14GenericMolInfoD1Ev91
_ZN4PLMD14GenericMolInfoD2Ev0
_ZNK4PLMD14GenericMolInfo10getChainIDB5cxx11ENS_10AtomNumberE0
_ZNK4PLMD14GenericMolInfo10getPDBsizeEv15189
_ZNK4PLMD14GenericMolInfo11getAtomNameB5cxx11ENS_10AtomNumberE46261
_ZNK4PLMD14GenericMolInfo11getPositionENS_10AtomNumberE186
_ZNK4PLMD14GenericMolInfo12checkForAtomENS_10AtomNumberE249
_ZNK4PLMD14GenericMolInfo14getResidueNameB5cxx11ENS_10AtomNumberE14233
_ZNK4PLMD14GenericMolInfo16getResidueNumberENS_10AtomNumberE60285
_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 000000000000..0f91fd462e62 --- /dev/null +++ b/coverage/core/GenericMolInfo.cpp.gcov.html @@ -0,0 +1,445 @@ + + + + + + + + LCOV - plumed test coverage - core/GenericMolInfo.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - GenericMolInfo.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:18121982.6 %
Date:2024-04-19 12:12:35Functions:151883.3 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "GenericMolInfo.h"
+      23             : #include "ActionRegister.h"
+      24             : #include "ActionSet.h"
+      25             : #include "PlumedMain.h"
+      26             : #include "tools/MolDataClass.h"
+      27             : #include "tools/PDB.h"
+      28             : #include "tools/Communicator.h"
+      29             : #include "config/Config.h"
+      30             : 
+      31             : namespace PLMD {
+      32             : 
+      33             : 
+      34             : /*
+      35             : This action is defined in core/ as it is used by other actions.
+      36             : Anyway, it is registered in setup/, so that excluding that module from
+      37             : compilation will exclude it from plumed.
+      38             : */
+      39             : 
+      40             : 
+      41          93 : void GenericMolInfo::registerKeywords( Keywords& keys ) {
+      42          93 :   ActionSetup::registerKeywords(keys);
+      43         186 :   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         186 :   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         186 :   keys.add("compulsory","PYTHON_BIN","default","python interpreter");
+      48         186 :   keys.add("atoms","CHAIN","(for masochists ( mostly Davide Branduardi ) ) The atoms involved in each of the chains of interest in the structure.");
+      49         186 :   keys.add("hidden","STRIDE","frequency for resetting the python interpreter. Should be 1.");
+      50         186 :   keys.addFlag("WHOLE", false, "The reference structure is whole, i.e. not broken by PBC");
+      51          93 : }
+      52             : 
+      53         182 : GenericMolInfo::~GenericMolInfo() {
+      54             : // empty destructor to delete unique_ptr
+      55         273 : }
+      56             : 
+      57          91 : GenericMolInfo::GenericMolInfo( const ActionOptions&ao ):
+      58             :   Action(ao),
+      59             :   ActionAnyorder(ao),
+      60             :   ActionPilot(ao),
+      61             :   ActionAtomistic(ao),
+      62          91 :   iswhole_(false)
+      63             : {
+      64          91 :   plumed_assert(getStride()==1);
+      65             :   // Read what is contained in the pdb file
+      66          91 :   parse("MOLTYPE",mytype);
+      67             : 
+      68             :   // check if whole
+      69          91 :   parseFlag("WHOLE", iswhole_);
+      70             : 
+      71          91 :   auto* moldat=plumed.getActionSet().selectLatest<GenericMolInfo*>(this);
+      72          91 :   if( moldat ) log<<"  overriding last MOLINFO with label " << moldat->getLabel()<<"\n";
+      73             : 
+      74             :   std::vector<AtomNumber> backbone;
+      75         182 :   parseAtomList("CHAIN",backbone);
+      76          91 :   if( read_backbone.size()==0 ) {
+      77           0 :     for(unsigned i=1;; ++i) {
+      78         182 :       parseAtomList("CHAIN",i,backbone);
+      79          91 :       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          91 :   if( read_backbone.size()==0 ) {
+      87          91 :     parse("STRUCTURE",reference);
+      88             : 
+      89          91 :     if( ! pdb.read(reference,usingNaturalUnits(),0.1/getUnits().getLength()))plumed_merror("missing input file " + reference );
+      90             : 
+      91          91 :     std::vector<std::string> chains; pdb.getChainNames( chains );
+      92          91 :     log.printf("  pdb file named %s contains %u chains \n",reference.c_str(), static_cast<unsigned>(chains.size()));
+      93         256 :     for(unsigned i=0; i<chains.size(); ++i) {
+      94             :       unsigned start,end; std::string errmsg;
+      95         165 :       pdb.getResidueRange( chains[i], start, end, errmsg );
+      96         165 :       if( errmsg.length()!=0 ) error( errmsg );
+      97             :       AtomNumber astart,aend;
+      98         165 :       pdb.getAtomRange( chains[i], astart, aend, errmsg );
+      99         165 :       if( errmsg.length()!=0 ) error( errmsg );
+     100         165 :       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         182 :     parse("PYTHON_BIN",python_bin);
+     105          91 :     if(python_bin=="no") {
+     106           0 :       log<<"  python interpreter disabled\n";
+     107             :     } else {
+     108         182 :       pythonCmd=config::getEnvCommand();
+     109          91 :       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          91 :       const auto & at=pdb.getAtomNumbers();
+     115       92189 :       for(unsigned i=0; i<at.size(); i++) {
+     116       92098 :         if(at[i].index()!=i) sorted=false;
+     117             :       }
+     118          91 :       if(!sorted) {
+     119           2 :         log<<"  PDB is not sorted, python interpreter will be disabled\n";
+     120          89 :       } else if(!Subprocess::available()) {
+     121           0 :         log<<"  subprocess is not available, python interpreter will be disabled\n";
+     122             :       } else {
+     123          89 :         enablePythonInterpreter=true;
+     124             :       }
+     125             :     }
+     126          91 :   }
+     127          91 : }
+     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          26 : void GenericMolInfo::getBackbone( std::vector<std::string>& restrings, const std::string& fortype, std::vector< std::vector<AtomNumber> >& backbone ) {
+     170          26 :   if( fortype!=mytype ) error("cannot calculate a variable designed for " + fortype + " molecules for molecule type " + mytype );
+     171          26 :   if( MolDataClass::numberOfAtomsPerResidueInBackbone( mytype )==0 ) error("backbone is not defined for molecule type " + mytype );
+     172             : 
+     173          26 :   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          26 :     if( restrings.size()==1 ) {
+     184          25 :       useter=( restrings[0].find("ter")!=std::string::npos );
+     185          25 :       if( restrings[0].find("all")!=std::string::npos ) {
+     186          24 :         std::vector<std::string> chains; pdb.getChainNames( chains );
+     187         354 :         for(unsigned i=0; i<chains.size(); ++i) {
+     188             :           unsigned r_start, r_end; std::string errmsg, mm, nn;
+     189         330 :           pdb.getResidueRange( chains[i], r_start, r_end, errmsg );
+     190         330 :           if( !useter ) {
+     191         330 :             std::string resname = pdb.getResidueName( r_start );
+     192         330 :             if( MolDataClass::isTerminalGroup( mytype, resname ) ) r_start++;
+     193         330 :             resname = pdb.getResidueName( r_end );
+     194         330 :             if( MolDataClass::isTerminalGroup( mytype, resname ) ) r_end--;
+     195             :           }
+     196         330 :           Tools::convert(r_start,mm); Tools::convert(r_end,nn);
+     197         354 :           if(i==0) restrings[0] = mm + "-" + nn;
+     198         612 :           else restrings.push_back(  mm + "-" + nn );
+     199             :         }
+     200          24 :       }
+     201             :     }
+     202          26 :     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          26 :     Tools::convert(restrings[0],nk); thissegment.push_back(nk);
+     208        2676 :     for(unsigned i=1; i<restrings.size(); ++i) {
+     209        2650 :       Tools::convert(restrings[i-1],nk);
+     210        2650 :       Tools::convert(restrings[i],nj);
+     211        7336 :       if( (nk+1)!=nj || pdb.getChainID(nk)!=pdb.getChainID(nj) ) {
+     212         307 :         segments.push_back(thissegment);
+     213         307 :         thissegment.resize(0);
+     214             :       }
+     215        2650 :       thissegment.push_back(nj);
+     216             :     }
+     217          26 :     segments.push_back( thissegment );
+     218             : 
+     219             :     // And now get the backbone atoms from each segment
+     220          26 :     backbone.resize( segments.size() );
+     221             :     std::vector<AtomNumber> atomnumbers;
+     222         359 :     for(unsigned i=0; i<segments.size(); ++i) {
+     223        3009 :       for(unsigned j=0; j<segments[i].size(); ++j) {
+     224        2676 :         std::string resname=pdb.getResidueName( segments[i][j] );
+     225        2676 :         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        2676 :         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        2676 :         if( resname=="GLY" ) warning("GLY residues are achiral - assuming HA1 atom is in CB position");
+     234        2676 :         MolDataClass::getBackboneForResidue( mytype, segments[i][j], pdb, atomnumbers );
+     235        2676 :         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       16056 :           for(unsigned k=0; k<atomnumbers.size(); ++k) backbone[i].push_back( atomnumbers[k] );
+     240             :         }
+     241        2676 :         atomnumbers.resize(0);
+     242             :       }
+     243             :     }
+     244          26 :   }
+     245          26 : }
+     246             : 
+     247         635 : void GenericMolInfo::interpretSymbol( const std::string& symbol, std::vector<AtomNumber>& atoms ) {
+     248        2522 :   if(Tools::startWith(symbol,"mdt:") || Tools::startWith(symbol,"mda:") || Tools::startWith(symbol,"vmd:") || Tools::startWith(symbol,"vmdexec:")) {
+     249             : 
+     250           8 :     plumed_assert(enablePythonInterpreter);
+     251             : 
+     252          16 :     log<<"  symbol " + symbol + " will be sent to python interpreter\n";
+     253           8 :     if(!selector) {
+     254           1 :       log<<"  MOLINFO "<<getLabel()<<": starting python interpreter\n";
+     255           1 :       if(comm.Get_rank()==0) {
+     256           2 :         selector=Tools::make_unique<Subprocess>(pythonCmd+" \""+config::getPlumedRoot()+"\"/scripts/selector.sh --pdb " + reference);
+     257           1 :         selector->stop();
+     258             :       }
+     259             :     }
+     260             : 
+     261           8 :     if(comm.Get_rank()==0) {
+     262           8 :       int ok=0;
+     263             :       std::string error_msg;
+     264             :       // this is a complicated way to have the exception propagated with MPI.
+     265             :       // It is necessary since only one process calls the selector.
+     266             :       // Probably I should recycle the exception propagation at library boundaries
+     267             :       // to allow transferring the exception to other processes.
+     268             :       try {
+     269           8 :         plumed_assert(selector) << "Python interpreter is disabled, selection " + symbol + " cannot be interpreted";
+     270             :         auto h=selector->contStop(); // stops again when it goes out of scope
+     271           8 :         (*selector) << symbol << "\n";
+     272           8 :         selector->flush();
+     273             :         std::string res;
+     274             :         std::vector<std::string> words;
+     275             :         while(true) {
+     276           8 :           selector->getline(res);
+     277          16 :           words=Tools::getWords(res);
+     278          16 :           if(!words.empty() && words[0]=="Error") plumed_error()<<res;
+     279          16 :           if(!words.empty() && words[0]=="Selection:") break;
+     280             :         }
+     281             :         words.erase(words.begin());
+     282           8 :         atoms.resize(0);
+     283         356 :         for(const auto & w : words) {
+     284             :           int n;
+     285         348 :           if(w.empty()) continue;
+     286         348 :           Tools::convert(w,n);
+     287         696 :           atoms.push_back(AtomNumber::serial(n));
+     288             :         }
+     289           8 :         ok=1;
+     290          16 :       } catch (const Exception & e) {
+     291           0 :         error_msg=e.what();
+     292           0 :       }
+     293           8 :       comm.Bcast(ok,0);
+     294           8 :       if(!ok) {
+     295           0 :         size_t s=error_msg.length();
+     296           0 :         comm.Bcast(s,0);
+     297           0 :         comm.Bcast(error_msg,0);
+     298           0 :         throw Exception()<<error_msg;
+     299             :       }
+     300           8 :       size_t nat=atoms.size();
+     301           8 :       comm.Bcast(nat,0);
+     302           8 :       comm.Bcast(atoms,0);
+     303             :     } else {
+     304           0 :       int ok=0;
+     305             :       std::string error_msg;
+     306           0 :       comm.Bcast(ok,0);
+     307           0 :       if(!ok) {
+     308             :         size_t s;
+     309           0 :         comm.Bcast(s,0);
+     310           0 :         error_msg.resize(s);
+     311           0 :         comm.Bcast(error_msg,0);
+     312           0 :         throw Exception()<<error_msg;
+     313             :       }
+     314           0 :       size_t nat=0;
+     315           0 :       comm.Bcast(nat,0);
+     316           0 :       comm.Bcast(atoms,0);
+     317             :     }
+     318           8 :     log<<"  selection interpreted using ";
+     319          18 :     if(Tools::startWith(symbol,"mdt:")) log<<"mdtraj "<<cite("McGibbon et al, Biophys. J., 109, 1528 (2015)")<<"\n";
+     320          22 :     if(Tools::startWith(symbol,"mda:")) log<<"MDAnalysis "<<cite("Gowers et al, Proceedings of the 15th Python in Science Conference, doi:10.25080/majora-629e541a-00e (2016)")<<"\n";
+     321          16 :     if(Tools::startWith(symbol,"vmdexec:")) log<<"VMD "<<cite("Humphrey, Dalke, and Schulten, K., J. Molec. Graphics, 14, 33 (1996)")<<"\n";
+     322          16 :     if(Tools::startWith(symbol,"vmd:")) log<<"VMD (github.com/Eigenstate/vmd-python) "<<cite("Humphrey, Dalke, and Schulten, K., J. Molec. Graphics, 14, 33 (1996)")<<"\n";
+     323           8 :     return;
+     324             :   }
+     325         627 :   MolDataClass::specialSymbol( mytype, symbol, pdb, atoms );
+     326         627 :   if(atoms.empty()) error(symbol + " not found in your MOLINFO structure");
+     327             : }
+     328             : 
+     329       46261 : std::string GenericMolInfo::getAtomName(AtomNumber a)const {
+     330       46261 :   return pdb.getAtomName(a);
+     331             : }
+     332             : 
+     333         249 : bool GenericMolInfo::checkForAtom(AtomNumber a)const {
+     334         249 :   return pdb.checkForAtom(a);
+     335             : }
+     336             : 
+     337       60285 : unsigned GenericMolInfo::getResidueNumber(AtomNumber a)const {
+     338       60285 :   return pdb.getResidueNumber(a);
+     339             : }
+     340             : 
+     341       15189 : unsigned GenericMolInfo::getPDBsize()const {
+     342       15189 :   return pdb.size();
+     343             : }
+     344             : 
+     345       14233 : std::string GenericMolInfo::getResidueName(AtomNumber a)const {
+     346       14233 :   return pdb.getResidueName(a);
+     347             : }
+     348             : 
+     349           0 : std::string GenericMolInfo::getChainID(AtomNumber a)const {
+     350           0 :   return pdb.getChainID(a);
+     351             : }
+     352             : 
+     353         186 : Vector GenericMolInfo::getPosition(AtomNumber a)const {
+     354         186 :   return pdb.getPosition(a);
+     355             : }
+     356             : 
+     357           2 : bool GenericMolInfo::isWhole() const {
+     358           2 :   return iswhole_;
+     359             : }
+     360             : 
+     361        5123 : void GenericMolInfo::prepare() {
+     362        5123 :   if(selector) {
+     363           1 :     log<<"  MOLINFO "<<getLabel()<<": killing python interpreter\n";
+     364             :     selector.reset();
+     365             :   }
+     366        5123 : }
+     367             : 
+     368             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/GenericMolInfo.h.func-sort-c.html b/coverage/core/GenericMolInfo.h.func-sort-c.html new file mode 100644 index 000000000000..cb8fb9656908 --- /dev/null +++ b/coverage/core/GenericMolInfo.h.func-sort-c.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - core/GenericMolInfo.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - GenericMolInfo.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22100.0 %
Date:2024-04-19 12:12:35Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14GenericMolInfo5applyEv5123
_ZN4PLMD14GenericMolInfo9calculateEv5123
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/GenericMolInfo.h.func.html b/coverage/core/GenericMolInfo.h.func.html new file mode 100644 index 000000000000..66d14a0ddddb --- /dev/null +++ b/coverage/core/GenericMolInfo.h.func.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - core/GenericMolInfo.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - GenericMolInfo.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22100.0 %
Date:2024-04-19 12:12:35Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14GenericMolInfo5applyEv5123
_ZN4PLMD14GenericMolInfo9calculateEv5123
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/GenericMolInfo.h.gcov.html b/coverage/core/GenericMolInfo.h.gcov.html new file mode 100644 index 000000000000..790b7193d665 --- /dev/null +++ b/coverage/core/GenericMolInfo.h.gcov.html @@ -0,0 +1,163 @@ + + + + + + + + LCOV - plumed test coverage - core/GenericMolInfo.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - GenericMolInfo.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22100.0 %
Date:2024-04-19 12:12:35Functions:22100.0 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5GroupC2ERKNS_13ActionOptionsE0
_ZN4PLMD5GroupC1ERKNS_13ActionOptionsE321
_ZN4PLMD5Group16registerKeywordsERNS_8KeywordsE323
_ZNK4PLMD5Group13getGroupAtomsB5cxx11Ev560
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/Group.cpp.func.html b/coverage/core/Group.cpp.func.html new file mode 100644 index 000000000000..17413cf63e23 --- /dev/null +++ b/coverage/core/Group.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - core/Group.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - Group.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:606198.4 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5Group16registerKeywordsERNS_8KeywordsE323
_ZN4PLMD5GroupC1ERKNS_13ActionOptionsE321
_ZN4PLMD5GroupC2ERKNS_13ActionOptionsE0
_ZNK4PLMD5Group13getGroupAtomsB5cxx11Ev560
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/Group.cpp.gcov.html b/coverage/core/Group.cpp.gcov.html new file mode 100644 index 000000000000..ddad7a5ef4ce --- /dev/null +++ b/coverage/core/Group.cpp.gcov.html @@ -0,0 +1,306 @@ + + + + + + + + LCOV - plumed test coverage - core/Group.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - Group.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:606198.4 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ + + + + + + + +

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

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

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

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9PbcActionC2ERKNS_13ActionOptionsE0
_ZN4PLMD9PbcAction10readBinaryERSi114
_ZN4PLMD9PbcActionC1ERKNS_13ActionOptionsE1091
_ZN4PLMD9PbcAction16registerKeywordsERNS_8KeywordsE1093
_ZN4PLMD9PbcAction4waitEv66154
_ZN4PLMD9PbcAction6setPbcEv66268
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/PbcAction.cpp.func.html b/coverage/core/PbcAction.cpp.func.html new file mode 100644 index 000000000000..7421d335a19e --- /dev/null +++ b/coverage/core/PbcAction.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - core/PbcAction.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - PbcAction.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2525100.0 %
Date:2024-04-19 12:12:35Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9PbcAction10readBinaryERSi114
_ZN4PLMD9PbcAction16registerKeywordsERNS_8KeywordsE1093
_ZN4PLMD9PbcAction4waitEv66154
_ZN4PLMD9PbcAction6setPbcEv66268
_ZN4PLMD9PbcActionC1ERKNS_13ActionOptionsE1091
_ZN4PLMD9PbcActionC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/PbcAction.cpp.gcov.html b/coverage/core/PbcAction.cpp.gcov.html new file mode 100644 index 000000000000..0496e9a5bad6 --- /dev/null +++ b/coverage/core/PbcAction.cpp.gcov.html @@ -0,0 +1,157 @@ + + + + + + + + LCOV - plumed test coverage - core/PbcAction.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - PbcAction.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2525100.0 %
Date:2024-04-19 12:12:35Functions:5683.3 %
+
+ + + + + + + + +

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

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

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

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10PlumedMain21activateParseOnlyModeEv0
_ZN4PLMD10PlumedMain4exitEi0
_ZN4PLMD10PlumedMain9justApplyEv0
_ZNK4PLMD10PlumedMain15DeprecatedAtoms16setCollectEnergyEb0
_ZNK4PLMD10PlumedMain15DeprecatedAtoms9getEnergyEv0
_ZNK4PLMD10PlumedMain18MDQuantityToPLUMEDERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_11TypesafePtrE0
_ZN4PLMD10PlumedMain14readInputLinesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1
_ZNK4PLMD10PlumedMain15DeprecatedAtoms13getKBoltzmannEv1
_ZNK4PLMD10PlumedMain15DeprecatedAtoms17usingNaturalUnitsEv1
_ZNK4PLMD10PlumedMain15DeprecatedAtoms6getKbTEv1
_ZNK4PLMD10PlumedMain15DeprecatedAtoms9getNatomsEv1
_ZN4PLMD10PlumedMain8getAtomsEv4
_ZN4PLMD10PlumedMain19performCalcNoForcesEv10
_ZN4PLMD10PlumedMain14setEnergyValueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE40
_ZN4PLMD10PlumedMain4loadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE42
_ZNK4PLMD10PlumedMain24useCountReferenceCounterEv42
_ZNK4PLMD10PlumedMain11valueExistsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE60
_ZN4PLMDL9testThrowEPKc61
_ZN4PLMD10PlumedMain4stopEv65
_ZN4PLMD10PlumedMain5fopenEPKcS2_82
_ZN4PLMD10PlumedMain6fcloseEP8_IO_FILE99
_ZN4PLMD10PlumedMain10readBinaryERSi114
_ZN4PLMD10PlumedMain8shareAllEv114
_ZNK4PLMD10PlumedMain11writeBinaryERSo114
_ZNK4PLMD10PlumedMain7getWorkEv450
_ZN4PLMD10PlumedMain25runJobsAtEndOfCalculationEv928
_ZN4PLMD10PlumedMain13readInputFileERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1011
_ZN4PLMD10PlumedMain13readInputFileERNS_5IFileE1012
_ZN4PLMD10PlumedMain4initEv1186
_ZN4PLMD10PlumedMain8setUnitsERKbRKNS_5UnitsE1217
_ZN4PLMD10PlumedMain6fflushEv1705
_ZNK4PLMD10PlumedMain15inputsAreActiveEv1763
_ZNK4PLMD10PlumedMain13parseOnlyModeEv2019
_ZN4PLMD10PlumedMain4citeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE4420
_ZN4PLMD10PlumedMain10insertFileERNS_8FileBaseE4929
_ZNK4PLMD10PlumedMain17usingNaturalUnitsEv4997
_ZN4PLMD12_GLOBAL__N_114CountInstancesD2Ev5088
_ZN4PLMD10PlumedMain9eraseFileERNS_8FileBaseE5190
_ZN4PLMD10PlumedMain19performCalcNoUpdateEv7011
_ZNK4PLMD10PlumedMain18plumedQuantityToMDERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKdRKNS_11TypesafePtrE7221
_ZNK4PLMD10PlumedMain7getBiasEv7683
_ZNK4PLMD10PlumedMain16getRealPrecisionEv7786
_ZN4PLMD10PlumedMain13readInputLineERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKb31494
_ZN4PLMD10PlumedMain6getLogEv49644
_ZN4PLMD10PlumedMain14readInputWordsERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EERKb49821
_ZN4PLMD10PlumedMain21setupInterfaceActionsEv50606
_ZN4PLMD10PlumedMain4calcEv277657
_ZN4PLMD10PlumedMain11performCalcEv277667
_ZN4PLMD10PlumedMain6updateEv277746
_ZN4PLMD10PlumedMain13setInputForceERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_11TypesafePtrE281168
_ZN4PLMD10PlumedMain9startStepEv284584
_ZN4PLMD10PlumedMain11prepareCalcEv284608
_ZN4PLMD10PlumedMain11resetInputsEv284678
_ZN4PLMD10PlumedMain17backwardPropagateEv284678
_ZN4PLMD10PlumedMain9shareDataEv284692
_ZN4PLMD10PlumedMain13justCalculateEv284802
_ZN4PLMD10PlumedMain8waitDataEv284802
_ZN4PLMD10PlumedMain19prepareDependenciesEv284935
_ZN4PLMD10PlumedMain13setInputValueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjSA_RKNS_11TypesafePtrE448826
_ZN4PLMD10PlumedMainD0Ev805416
_ZN4PLMD10PlumedMainC2Ev806370
_ZN4PLMD10PlumedMainD2Ev806370
_ZN4PLMD10PlumedMain3cmdESt17basic_string_viewIcSt11char_traitsIcEERKNS_11TypesafePtrE1326408
_ZN4PLMD10PlumedMain24decreaseReferenceCounterEv8805437
_ZN4PLMD10PlumedMain24increaseReferenceCounterEv8806493
_ZN4PLMD10PlumedMain8getUnitsEv14986245
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/PlumedMain.cpp.func.html b/coverage/core/PlumedMain.cpp.func.html new file mode 100644 index 000000000000..f4ec2d0b4c77 --- /dev/null +++ b/coverage/core/PlumedMain.cpp.func.html @@ -0,0 +1,337 @@ + + + + + + + + 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:84093689.7 %
Date:2024-04-19 12:12:35Functions:606690.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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

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

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/PlumedMain.h.gcov.html b/coverage/core/PlumedMain.h.gcov.html new file mode 100644 index 000000000000..b89c0902ff00 --- /dev/null +++ b/coverage/core/PlumedMain.h.gcov.html @@ -0,0 +1,690 @@ + + + + + + + + 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-04-19 12:12:35Functions:00-
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZL13typesafeDebugPKc16plumed_safeptr_x0
plumed_plumedmain_cmd_nothrow0
plumed_plumedmain_use_count42
_ZL16translate_nested24plumed_nothrow_handler_x68
plumed_plumedmain_cmd_safe95
_ZL17translate_current24plumed_nothrow_handler_xPPvPKc134
plumed_plumedmain_cmd357
_ZN4PLMD12_GLOBAL__N_121PlumedMainInitializerC2Ev5088
_ZN4PLMD12_GLOBAL__N_121PlumedMainInitializerD2Ev5088
plumed_plumedmain_cmd_safe_nothrow18233
_ZL19getenvTypesafeDebugv18328
plumed_plumedmain_create805314
plumed_plumedmain_finalize805314
plumed_symbol_table_init810371
plumed_plumedmain_create_reference8000123
plumed_plumedmain_delete_reference8805437
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/PlumedMainInitializer.cpp.func.html b/coverage/core/PlumedMainInitializer.cpp.func.html new file mode 100644 index 000000000000..10c3d8a84ee8 --- /dev/null +++ b/coverage/core/PlumedMainInitializer.cpp.func.html @@ -0,0 +1,137 @@ + + + + + + + + LCOV - plumed test coverage - core/PlumedMainInitializer.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - PlumedMainInitializer.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22326982.9 %
Date:2024-04-19 12:12:35Functions:141687.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZL13typesafeDebugPKc16plumed_safeptr_x0
_ZL16translate_nested24plumed_nothrow_handler_x68
_ZL17translate_current24plumed_nothrow_handler_xPPvPKc134
_ZL19getenvTypesafeDebugv18328
_ZN4PLMD12_GLOBAL__N_121PlumedMainInitializerC2Ev5088
_ZN4PLMD12_GLOBAL__N_121PlumedMainInitializerD2Ev5088
plumed_plumedmain_cmd357
plumed_plumedmain_cmd_nothrow0
plumed_plumedmain_cmd_safe95
plumed_plumedmain_cmd_safe_nothrow18233
plumed_plumedmain_create805314
plumed_plumedmain_create_reference8000123
plumed_plumedmain_delete_reference8805437
plumed_plumedmain_finalize805314
plumed_plumedmain_use_count42
plumed_symbol_table_init810371
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/PlumedMainInitializer.cpp.gcov.html b/coverage/core/PlumedMainInitializer.cpp.gcov.html new file mode 100644 index 000000000000..50d0170b87dc --- /dev/null +++ b/coverage/core/PlumedMainInitializer.cpp.gcov.html @@ -0,0 +1,567 @@ + + + + + + + + LCOV - plumed test coverage - core/PlumedMainInitializer.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - PlumedMainInitializer.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22326982.9 %
Date:2024-04-19 12:12:35Functions:141687.5 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8Register16RegistrationLockC2EOS1_0
_ZN4PLMD8RegisterD0Ev0
_ZNK4PLMD8Register19getKeysWithDLHandleB5cxx11EPv41
_ZN4PLMD8Register16RegistrationLockC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE51
_ZN4PLMD8Register16RegistrationLockD2Ev51
_ZN4PLMD8Register16registrationLockERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE51
_ZN4PLMD8Register17popDLRegistrationEv51
_ZN4PLMD8Register18pushDLRegistrationERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE51
_ZN4PLMD8Register24completeAllRegistrationsEPv51
_ZN4PLMD8Register13imageToStringB5cxx11EPv245
_ZN4PLMDlsERSoRKNS_8RegisterE870
_ZN4PLMD8RegisterC2Ev10176
_ZN4PLMD8RegisterD2Ev10176
_ZN4PLMD8Register15isDLRegisteringEv2304886
_ZN4PLMD8Register22getRegisteringFullPathB5cxx11Ev2304886
_ZN4PLMD12_GLOBAL__N_112getSingletonEv4630277
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/RegisterBase.cpp.func.html b/coverage/core/RegisterBase.cpp.func.html new file mode 100644 index 000000000000..479e0931eafa --- /dev/null +++ b/coverage/core/RegisterBase.cpp.func.html @@ -0,0 +1,137 @@ + + + + + + + + LCOV - plumed test coverage - core/RegisterBase.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - RegisterBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:636991.3 %
Date:2024-04-19 12:12:35Functions:141687.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12_GLOBAL__N_112getSingletonEv4630277
_ZN4PLMD8Register13imageToStringB5cxx11EPv245
_ZN4PLMD8Register15isDLRegisteringEv2304886
_ZN4PLMD8Register16RegistrationLockC2EOS1_0
_ZN4PLMD8Register16RegistrationLockC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE51
_ZN4PLMD8Register16RegistrationLockD2Ev51
_ZN4PLMD8Register16registrationLockERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE51
_ZN4PLMD8Register17popDLRegistrationEv51
_ZN4PLMD8Register18pushDLRegistrationERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE51
_ZN4PLMD8Register22getRegisteringFullPathB5cxx11Ev2304886
_ZN4PLMD8Register24completeAllRegistrationsEPv51
_ZN4PLMD8RegisterC2Ev10176
_ZN4PLMD8RegisterD0Ev0
_ZN4PLMD8RegisterD2Ev10176
_ZN4PLMDlsERSoRKNS_8RegisterE870
_ZNK4PLMD8Register19getKeysWithDLHandleB5cxx11EPv41
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/RegisterBase.cpp.gcov.html b/coverage/core/RegisterBase.cpp.gcov.html new file mode 100644 index 000000000000..f9c992adcad1 --- /dev/null +++ b/coverage/core/RegisterBase.cpp.gcov.html @@ -0,0 +1,223 @@ + + + + + + + + LCOV - plumed test coverage - core/RegisterBase.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - RegisterBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:636991.3 %
Date:2024-04-19 12:12:35Functions: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 "RegisterBase.h"
+      23             : 
+      24             : #include <mutex>
+      25             : #include "tools/Tools.h"
+      26             : 
+      27             : namespace PLMD {
+      28             : 
+      29             : namespace {
+      30        5088 : class Singleton {
+      31             : public:
+      32             :   /// Mutex to avoid simultaneous registrations from multiple threads
+      33             :   std::mutex registeringMutex;
+      34             : 
+      35             :   /// Count simultaneous registrations
+      36             :   /// This is here if in the future we want to expand to recursive registrations
+      37             :   unsigned registeringCounter=0;
+      38             : 
+      39             :   /// Take care of all exisiting registers
+      40             :   std::vector<Register*> registers;
+      41             : 
+      42             :   /// Full path of the registering library
+      43             :   std::string fullPath;
+      44             : };
+      45             : 
+      46     4630277 : Singleton & getSingleton() {
+      47     4630277 :   static Singleton singleton;
+      48     4630277 :   return singleton;
+      49             : }
+      50             : 
+      51             : }
+      52             : 
+      53          51 : Register::RegistrationLock::RegistrationLock(const std::string & fullPath):
+      54          51 :   active(true)
+      55             : {
+      56          51 :   pushDLRegistration(fullPath);
+      57          51 : }
+      58             : 
+      59          51 : Register::RegistrationLock::~RegistrationLock() noexcept {
+      60          51 :   if(active) popDLRegistration();
+      61          51 : }
+      62             : 
+      63           0 : Register::RegistrationLock::RegistrationLock(RegistrationLock&& other) noexcept:
+      64           0 :   active(other.active)
+      65             : {
+      66           0 :   other.active=false;
+      67           0 : }
+      68             : 
+      69          51 : Register::RegistrationLock Register::registrationLock(const std::string & fullPath) {
+      70          51 :   return RegistrationLock(fullPath);
+      71             : }
+      72             : 
+      73          51 : void Register::pushDLRegistration(const std::string & fullPath) {
+      74          51 :   auto & singleton=getSingleton();
+      75          51 :   singleton.registeringMutex.lock();
+      76          51 :   singleton.fullPath=fullPath;
+      77          51 :   if(singleton.registeringCounter>0) {
+      78             :     singleton.registeringMutex.unlock();
+      79           0 :     plumed_error()<<"recursive registrations are technically possible but disabled at this stage "<<singleton.registeringCounter;
+      80             :   }
+      81          51 :   singleton.registeringCounter++;
+      82          51 : }
+      83             : 
+      84          51 : void Register::popDLRegistration() noexcept {
+      85          51 :   auto & singleton=getSingleton();
+      86         153 :   for(auto & reg : singleton.registers) reg->clearStaged();
+      87          51 :   singleton.registeringCounter--;
+      88             :   singleton.registeringMutex.unlock();
+      89          51 : }
+      90             : 
+      91          51 : void Register::completeAllRegistrations(void* image) {
+      92          51 :   auto & singleton=getSingleton();
+      93         153 :   for(auto & reg : singleton.registers) reg->completeRegistration(image);
+      94          51 : }
+      95             : 
+      96         245 : std::string Register::imageToString(void* image) {
+      97         245 :   std::stringstream ss;
+      98             :   ss << image;
+      99         245 :   return ss.str();
+     100         245 : }
+     101             : 
+     102     2304886 : bool Register::isDLRegistering() noexcept {
+     103     2304886 :   auto & singleton=getSingleton();
+     104     2304886 :   return singleton.registeringCounter>0;
+     105             : }
+     106             : 
+     107     2304886 : const std::string Register::getRegisteringFullPath() noexcept {
+     108     2304886 :   auto & singleton=getSingleton();
+     109     2304886 :   return singleton.fullPath;
+     110             : }
+     111             : 
+     112       10176 : Register::Register() {
+     113       10176 :   auto & singleton=getSingleton();
+     114             :   // this is to protect insertion
+     115       10176 :   std::unique_lock lock(singleton.registeringMutex);
+     116       10176 :   singleton.registers.push_back(this);
+     117       10176 : }
+     118             : 
+     119       10176 : Register::~Register() noexcept {
+     120       10176 :   auto & singleton=getSingleton();
+     121             :   // this is to protect removal
+     122       10176 :   std::unique_lock lock(singleton.registeringMutex);
+     123       10176 :   auto it=std::find(singleton.registers.begin(),singleton.registers.end(),this);
+     124       10176 :   if(it!=singleton.registers.end()) singleton.registers.erase(it);
+     125       10176 : }
+     126             : 
+     127          41 : std::vector<std::string> Register::getKeysWithDLHandle(void* image) const {
+     128             :   std::vector<std::string> res;
+     129          41 :   const auto prefix=imageToString(image)+":";
+     130       17906 :   for(auto & k : getKeys()) {
+     131       17865 :     if(Tools::startWith(k,prefix)) {
+     132          82 :       if(!std::getenv("PLUMED_LOAD_ACTION_DEBUG")) k=k.substr(prefix.length());
+     133          41 :       res.push_back(k);
+     134             :     }
+     135          41 :   }
+     136          41 :   return res;
+     137           0 : }
+     138             : 
+     139         870 : std::ostream & operator<<(std::ostream &log,const Register &reg) {
+     140         870 :   std::vector<std::string> s(reg.getKeys());
+     141      197925 :   for(unsigned i=0; i<s.size(); i++) log<<"  "<<s[i]<<"\n";
+     142         870 :   return log;
+     143         870 : }
+     144             : 
+     145             : 
+     146             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/RegisterBase.h.func-sort-c.html b/coverage/core/RegisterBase.h.func-sort-c.html new file mode 100644 index 000000000000..1d30d15317e8 --- /dev/null +++ b/coverage/core/RegisterBase.h.func-sort-c.html @@ -0,0 +1,161 @@ + + + + + + + + LCOV - plumed test coverage - core/RegisterBase.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - RegisterBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:586885.3 %
Date:2024-04-19 12:12:35Functions:192286.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12RegisterBaseINS_22ActionRegisterPointersEED0Ev0
_ZN4PLMD12RegisterBaseINS_22CLToolRegisterPointersEED0Ev0
_ZNK4PLMD12RegisterBaseINS_22CLToolRegisterPointersEE3getERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZNK4PLMD12RegisterBaseINS_22CLToolRegisterPointersEE5checkERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1
_ZNK4PLMD12RegisterBaseINS_22ActionRegisterPointersEE5checkERKSt6vectorIPvSaIS4_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZN4PLMD12RegisterBaseINS_22ActionRegisterPointersEE11clearStagedEv51
_ZN4PLMD12RegisterBaseINS_22ActionRegisterPointersEE20completeRegistrationEPv51
_ZN4PLMD12RegisterBaseINS_22CLToolRegisterPointersEE11clearStagedEv51
_ZN4PLMD12RegisterBaseINS_22CLToolRegisterPointersEE20completeRegistrationEPv51
_ZNK4PLMD12RegisterBaseINS_22ActionRegisterPointersEE7getKeysB5cxx11Ev477
_ZNK4PLMD12RegisterBaseINS_22ActionRegisterPointersEE3getERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1467
_ZNK4PLMD12RegisterBaseINS_22CLToolRegisterPointersEE3getERKSt6vectorIPvSaIS4_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3755
_ZNK4PLMD12RegisterBaseINS_22CLToolRegisterPointersEE7getKeysB5cxx11Ev4810
_ZN4PLMD12RegisterBaseINS_22ActionRegisterPointersEED2Ev5088
_ZN4PLMD12RegisterBaseINS_22CLToolRegisterPointersEED2Ev5088
_ZNK4PLMD12RegisterBaseINS_22ActionRegisterPointersEE5checkERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE6484
_ZNK4PLMD12RegisterBaseINS_22ActionRegisterPointersEE11getFullPathERKSt6vectorIPvSaIS4_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE49644
_ZNK4PLMD12RegisterBaseINS_22ActionRegisterPointersEE3getERKSt6vectorIPvSaIS4_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE49646
_ZN4PLMD12RegisterBaseINS_22CLToolRegisterPointersEE6removeENS2_2IDE96672
_ZN4PLMD12RegisterBaseINS_22CLToolRegisterPointersEE3addENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKS1_96681
_ZN4PLMD12RegisterBaseINS_22ActionRegisterPointersEE6removeENS2_2IDE2208192
_ZN4PLMD12RegisterBaseINS_22ActionRegisterPointersEE3addENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKS1_2208205
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/RegisterBase.h.func.html b/coverage/core/RegisterBase.h.func.html new file mode 100644 index 000000000000..fcd7b5987cc5 --- /dev/null +++ b/coverage/core/RegisterBase.h.func.html @@ -0,0 +1,161 @@ + + + + + + + + LCOV - plumed test coverage - core/RegisterBase.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - RegisterBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:586885.3 %
Date:2024-04-19 12:12:35Functions:192286.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12RegisterBaseINS_22ActionRegisterPointersEE11clearStagedEv51
_ZN4PLMD12RegisterBaseINS_22ActionRegisterPointersEE20completeRegistrationEPv51
_ZN4PLMD12RegisterBaseINS_22ActionRegisterPointersEE3addENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKS1_2208205
_ZN4PLMD12RegisterBaseINS_22ActionRegisterPointersEE6removeENS2_2IDE2208192
_ZN4PLMD12RegisterBaseINS_22ActionRegisterPointersEED0Ev0
_ZN4PLMD12RegisterBaseINS_22ActionRegisterPointersEED2Ev5088
_ZN4PLMD12RegisterBaseINS_22CLToolRegisterPointersEE11clearStagedEv51
_ZN4PLMD12RegisterBaseINS_22CLToolRegisterPointersEE20completeRegistrationEPv51
_ZN4PLMD12RegisterBaseINS_22CLToolRegisterPointersEE3addENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKS1_96681
_ZN4PLMD12RegisterBaseINS_22CLToolRegisterPointersEE6removeENS2_2IDE96672
_ZN4PLMD12RegisterBaseINS_22CLToolRegisterPointersEED0Ev0
_ZN4PLMD12RegisterBaseINS_22CLToolRegisterPointersEED2Ev5088
_ZNK4PLMD12RegisterBaseINS_22ActionRegisterPointersEE11getFullPathERKSt6vectorIPvSaIS4_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE49644
_ZNK4PLMD12RegisterBaseINS_22ActionRegisterPointersEE3getERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1467
_ZNK4PLMD12RegisterBaseINS_22ActionRegisterPointersEE3getERKSt6vectorIPvSaIS4_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE49646
_ZNK4PLMD12RegisterBaseINS_22ActionRegisterPointersEE5checkERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE6484
_ZNK4PLMD12RegisterBaseINS_22ActionRegisterPointersEE5checkERKSt6vectorIPvSaIS4_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZNK4PLMD12RegisterBaseINS_22ActionRegisterPointersEE7getKeysB5cxx11Ev477
_ZNK4PLMD12RegisterBaseINS_22CLToolRegisterPointersEE3getERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZNK4PLMD12RegisterBaseINS_22CLToolRegisterPointersEE3getERKSt6vectorIPvSaIS4_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3755
_ZNK4PLMD12RegisterBaseINS_22CLToolRegisterPointersEE5checkERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1
_ZNK4PLMD12RegisterBaseINS_22CLToolRegisterPointersEE7getKeysB5cxx11Ev4810
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/RegisterBase.h.gcov.html b/coverage/core/RegisterBase.h.gcov.html new file mode 100644 index 000000000000..3f955846c2d7 --- /dev/null +++ b/coverage/core/RegisterBase.h.gcov.html @@ -0,0 +1,369 @@ + + + + + + + + LCOV - plumed test coverage - core/RegisterBase.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - RegisterBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:586885.3 %
Date:2024-04-19 12:12:35Functions:192286.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_core_RegisterBase_h
+      23             : #define __PLUMED_core_RegisterBase_h
+      24             : 
+      25             : #include "tools/Exception.h"
+      26             : #include <string>
+      27             : #include <map>
+      28             : #include <memory>
+      29             : #include <iostream>
+      30             : #include <vector>
+      31             : #include <algorithm>
+      32             : #include <mutex>
+      33             : #include <shared_mutex>
+      34             : 
+      35             : namespace PLMD {
+      36             : 
+      37             : /// Base class, with type independent information.
+      38             : /// Actual registers should inherit through the RegisterBase class below
+      39             : class Register {
+      40             :   /// Initialize registration - only used by registrationLock()
+      41             :   static void pushDLRegistration(const std::string & fullpath);
+      42             :   /// Finalize registration - only used by registrationLock()
+      43             :   static void popDLRegistration() noexcept;
+      44             : 
+      45             : protected:
+      46             :   /// Mutex protecting access to map
+      47             :   mutable std::shared_mutex mutex;
+      48             :   /// Internal tool to format image addresses
+      49             :   static std::string imageToString(void* image);
+      50             :   /// Check if we are in a dlopen section
+      51             :   static bool isDLRegistering() noexcept;
+      52             :   /// Return the path of the currently-loading library
+      53             :   static const std::string getRegisteringFullPath() noexcept;
+      54             :   /// Save all staged objects from a register
+      55             :   virtual void completeRegistration(void* image)=0;
+      56             :   /// Clear staged objects.
+      57             :   /// Should be used when leaving the dlopen section to remove
+      58             :   /// any dangling object.
+      59             :   virtual void clearStaged() noexcept =0;
+      60             :   /// Get all registered keys.
+      61             :   /// These are the keys in the map, not the plumed keywords!
+      62             :   virtual std::vector<std::string> getKeys() const =0;
+      63             : 
+      64             : public:
+      65             :   /// Constructor.
+      66             :   /// This keeps track of all created instances.
+      67             :   Register();
+      68             :   /// Destructor.
+      69             :   virtual ~Register() noexcept;
+      70             :   /// Disable move
+      71             :   Register(Register &&) = delete;
+      72             :   /// Disable copy
+      73             :   Register(const Register &) = delete;
+      74             : 
+      75             :   /// Small class to manage registration lock
+      76             :   /// This is used during dlopen, to avoid data races in registrations
+      77             :   class RegistrationLock {
+      78             :     bool active;
+      79             :   public:
+      80             :     RegistrationLock(const std::string & fullpath);
+      81             :     RegistrationLock(const RegistrationLock&) = delete;
+      82             :     RegistrationLock(RegistrationLock&& other) noexcept;
+      83             :     ~RegistrationLock() noexcept;
+      84             :   };
+      85             : 
+      86             :   /// return a registration lock
+      87             :   static RegistrationLock registrationLock(const std::string & fullpath);
+      88             : 
+      89             :   /// Save all staged objects in all registers
+      90             :   static void completeAllRegistrations(void* image);
+      91             : 
+      92             :   /// Get only keys registered specifically by a given image
+      93             :   std::vector<std::string> getKeysWithDLHandle(void* handle) const;
+      94             : 
+      95             :   friend std::ostream & operator<<(std::ostream &log,const Register &reg);
+      96             : };
+      97             : 
+      98             : /// General register.
+      99             : /// This class provide a generic implementation based on the content of the Register
+     100             : template<class Content>
+     101             : class RegisterBase :
+     102             :   public Register {
+     103             : 
+     104             : public:
+     105             : /// auxiliary class
+     106     4609741 :   struct ContentAndFullPath {
+     107             :     Content content;
+     108             :     std::string fullPath;
+     109             :   };
+     110             : 
+     111             : private:
+     112             : /// Main register map
+     113             :   std::map<std::string,std::unique_ptr<ContentAndFullPath>> m;
+     114             : /// Map of staged keys
+     115             :   std::map<std::string,std::unique_ptr<ContentAndFullPath>> staged_m;
+     116             : 
+     117             : public:
+     118             : 
+     119             :   struct ID {
+     120             :     ContentAndFullPath* ptr{nullptr};
+     121             :   };
+     122             : /// Register a new class.
+     123             : /// \param key The name of the directive to be used in the input file
+     124             : /// \param content The registered content
+     125             : /// \param ID A returned ID that can be used to remove the directive later
+     126             :   ID add(std::string key,const Content & content);
+     127             : 
+     128             : /// Verify if a key is present in the register, accessing to registered images
+     129             :   bool check(const std::vector<void*> & images,const std::string & key) const;
+     130             : 
+     131             : /// Verify if a key is present in the register, only considering the default image
+     132             :   bool check(const std::string & key) const;
+     133             : 
+     134             : /// Return the content associated to a key in the register, accessing to registerd images
+     135             :   const Content & get(const std::vector<void*> & images,const std::string & key) const;
+     136             : 
+     137             : /// Return the full path associated to a key in the register, accessing to registerd images
+     138             :   const std::string & getFullPath(const std::vector<void*> & images,const std::string & key) const;
+     139             : 
+     140             : /// Return the content associated to a key in the register, only considering the default image
+     141             :   const Content & get(const std::string & key) const;
+     142             : 
+     143             : /// Remove a registered keyword.
+     144             : /// Use the ID returned by add().
+     145             :   void remove(ID id);
+     146             : 
+     147             : /// Get a list of keys
+     148             : /// Notice that these are the keys in the map, not the plumed keywords!
+     149             : /// Also notice that this list includes keys from all images, including the
+     150             : /// textual version of the image void*
+     151             :   std::vector<std::string> getKeys() const override;
+     152             : 
+     153             :   ~RegisterBase() noexcept override;
+     154             : 
+     155             :   /// complete registration
+     156             :   /// all staged keys will be enabled
+     157             :   /// Should be called after dlopen has been completed correctly.
+     158             :   void completeRegistration(void*handle) override;
+     159             : 
+     160             :   void clearStaged() noexcept override;
+     161             : 
+     162             : };
+     163             : 
+     164             : template<class Content>
+     165     2304886 : typename RegisterBase<Content>::ID RegisterBase<Content>::add(std::string key,const Content & content) {
+     166             : 
+     167     4609772 :   auto ptr=std::make_unique<ContentAndFullPath>(ContentAndFullPath{content,getRegisteringFullPath()});
+     168             :   ID id{ptr.get()};
+     169             : 
+     170             :   // lock map for writing
+     171     2304886 :   std::unique_lock<std::shared_mutex> lock(mutex);
+     172             : 
+     173     2304886 :   if(isDLRegistering()) {
+     174           0 :     plumed_assert(!staged_m.count(key)) << "cannot stage key twice with the same name "<< key<<"\n";
+     175          22 :     staged_m.insert({key, std::move(ptr)});
+     176             :   } else {
+     177           0 :     plumed_assert(!m.count(key)) << "cannot register key twice with the same name "<< key<<"\n";
+     178     2304864 :     m.insert({key, std::move(ptr)});
+     179             :   }
+     180     4609772 :   return id;
+     181     2304886 : }
+     182             : std::ostream & operator<<(std::ostream &log,const Register &reg);
+     183             : 
+     184             : template<class Content>
+     185           2 : bool RegisterBase<Content>::check(const std::vector<void*> & images,const std::string & key) const {
+     186             :   // lock map for reading
+     187           2 :   std::shared_lock<std::shared_mutex> lock(mutex);
+     188           1 :   if(m.count(key)>0) return true;
+     189           1 :   for(auto image : images) {
+     190           0 :     std::string k=imageToString(image)+":"+key;
+     191             :     if(m.count(k)>0) return true;
+     192             :   }
+     193             :   return false;
+     194             : }
+     195             : 
+     196             : template<class Content>
+     197        6485 : bool RegisterBase<Content>::check(const std::string & key) const {
+     198             :   // lock map for reading
+     199        6485 :   std::shared_lock<std::shared_mutex> lock(mutex);
+     200        6485 :   return m.count(key)>0;
+     201             : }
+     202             : 
+     203             : template<class Content>
+     204       53401 : const Content & RegisterBase<Content>::get(const std::vector<void*> & images,const std::string & key) const {
+     205             :   // lock map for reading
+     206       53401 :   std::shared_lock<std::shared_mutex> lock(mutex);
+     207       53446 :   for(auto image = images.rbegin(); image != images.rend(); ++image) {
+     208         194 :     auto qualified_key=imageToString(*image) + ":" + key;
+     209          51 :     if(m.count(qualified_key)>0) return m.find(qualified_key)->second->content;
+     210             :   }
+     211           4 :   plumed_assert(m.count(key)>0);
+     212       53348 :   return m.find(key)->second->content;
+     213             : }
+     214             : 
+     215             : template<class Content>
+     216       49644 : const std::string & RegisterBase<Content>::getFullPath(const std::vector<void*> & images,const std::string & key) const {
+     217             :   // lock map for reading
+     218       49644 :   std::shared_lock<std::shared_mutex> lock(mutex);
+     219       49689 :   for(auto image = images.rbegin(); image != images.rend(); ++image) {
+     220         172 :     auto qualified_key=imageToString(*image) + ":" + key;
+     221          41 :     if(m.count(qualified_key)>0) return m.find(qualified_key)->second->fullPath;
+     222             :   }
+     223           0 :   plumed_assert(m.count(key)>0);
+     224       49603 :   return m.find(key)->second->fullPath;
+     225             : }
+     226             : 
+     227             : template<class Content>
+     228        1467 : const Content & RegisterBase<Content>::get(const std::string & key) const {
+     229             :   // lock map for reading
+     230        1467 :   std::shared_lock<std::shared_mutex> lock(mutex);
+     231           0 :   plumed_assert(m.count(key)>0);
+     232        1467 :   return m.find(key)->second->content;
+     233             : }
+     234             : 
+     235             : template<class Content>
+     236     2304864 : void RegisterBase<Content>::remove(ID id) {
+     237             :   // lock map for writing
+     238     2304864 :   std::unique_lock<std::shared_mutex> lock(mutex);
+     239     2304864 :   if(id.ptr) {
+     240   273103488 :     for(auto p=m.begin(); p!=m.end(); ++p) {
+     241   273103488 :       if(p->second.get()==id.ptr) {
+     242     2304864 :         m.erase(p); break;
+     243             :       }
+     244             :     }
+     245             :   }
+     246     2304864 : }
+     247             : 
+     248             : template<class Content>
+     249        5287 : std::vector<std::string> RegisterBase<Content>::getKeys() const {
+     250             :   // lock map for reading
+     251        5287 :   std::shared_lock<std::shared_mutex> lock(mutex);
+     252             :   std::vector<std::string> s;
+     253      303779 :   for(const auto & it : m) s.push_back(it.first);
+     254        5287 :   std::sort(s.begin(),s.end());
+     255        5287 :   return s;
+     256           0 : }
+     257             : 
+     258             : template<class Content>
+     259       10176 : RegisterBase<Content>::~RegisterBase() noexcept {
+     260       10176 :   if(m.size()>0) {
+     261           0 :     std::string names="";
+     262           0 :     for(const auto & p : m) names+=p.first+" ";
+     263           0 :     std::cerr<<"WARNING: Directive "+ names +" has not been properly unregistered. This might lead to memory leak!!\n";
+     264             :   }
+     265       20352 : }
+     266             : 
+     267             : template<class Content>
+     268         102 : void RegisterBase<Content>::completeRegistration(void*handle) {
+     269             :   // lock map for writing
+     270         102 :   std::unique_lock<std::shared_mutex> lock(mutex);
+     271         124 :   for (auto iter = staged_m.begin(); iter != staged_m.end(); ) {
+     272          44 :     auto key = imageToString(handle) + ":" + iter->first;
+     273           0 :     plumed_assert(!m.count(key)) << "cannot register key twice with the same name "<< key<<"\n";
+     274          22 :     m[key] = std::move(iter->second);
+     275             :     // Since we've moved out the value, we can safely erase the element from the original map
+     276             :     // This also avoids invalidating our iterator since erase returns the next iterator
+     277          22 :     iter = staged_m.erase(iter);
+     278             :   }
+     279         102 :   plumed_assert(staged_m.empty());
+     280         102 : }
+     281             : 
+     282             : template<class Content>
+     283         102 : void RegisterBase<Content>::clearStaged() noexcept {
+     284             :   // lock map for writing
+     285         102 :   std::unique_lock<std::shared_mutex> lock(mutex);
+     286             :   staged_m.clear();
+     287         102 : }
+     288             : }
+     289             : 
+     290             : #endif
+     291             : 
+     292             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/TargetDist.cpp.func-sort-c.html b/coverage/core/TargetDist.cpp.func-sort-c.html new file mode 100644 index 000000000000..b24dfb028f98 --- /dev/null +++ b/coverage/core/TargetDist.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - core/TargetDist.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - TargetDist.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:0270.0 %
Date:2024-04-19 12:12:35Functions:030.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

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

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

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

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
_ZN4PLMD5ValueC2Ev164
_ZN4PLMD5Value12setGradientsEPNS_15ActionAtomisticERj190
_ZN4PLMD5Value10projectionERKS0_S2_261
_ZNK4PLMD5Value13passGradientsERKdRSt3mapINS_10AtomNumberENS_13VectorGenericILj3EEESt4lessIS4_ESaISt4pairIKS4_S6_EEE283
_ZN4PLMD5Value10setValTypeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE450
_ZN4PLMD5Value10readBinaryERSi456
_ZNK4PLMD5Value11writeBinaryERSo456
_ZN4PLMD5Value12setSymmetricERKb1264
_ZN4PLMD5Value16retrieveEdgeListERjRSt6vectorISt4pairIjjESaIS4_EERS2_IdSaIdEE2220
_ZN4PLMD5Value11setConstantEv5266
_ZN4PLMD5Value18reshapeMatrixStoreERKj6963
_ZN4PLMD5Value9setDomainERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_7738
_ZN4PLMD5Value14buildDataStoreEb11669
_ZNK4PLMD5Value9getDomainERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES7_16758
_ZN4PLMD5Value24setPositionInMatrixStashERKj35382
_ZN4PLMD5Value9push_backERKd74915
_ZN4PLMD5Value16setupPeriodicityEv108492
_ZN4PLMD5ValueC2EPNS_15ActionWithValueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbRKSt6vectorIjSaIjEE117404
_ZN4PLMD5Value8setShapeERKSt6vectorIjSaIjEE129330
_ZNK4PLMD5Value17getGoodNumThreadsERKjS2_231990
_ZNK4PLMD5Value10applyForceERSt6vectorIdSaIdEE404010
_ZNK4PLMD5Value5printERNS_5OFileE547576
_ZNK4PLMD5Value21convertIndexToindicesERKmRSt6vectorIjSaIjEE775666
_ZN4PLMD5Value14setNotPeriodicEv1103780
_ZNK4PLMD5Value10isPeriodicEv1687317
_ZN4PLMD5Value3setERKmRKd4928104
_ZNK4PLMD5Value17calculateOnUpdateEv7504457
_ZNK4PLMD5Value17ignoreStoredValueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE15989629
_ZN4PLMD5Value15getPntrToActionEv18422721
_ZN4PLMD5Value8addForceERKmdb39869045
_ZNK4PLMD5Value3getERKmb622535126
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/Value.cpp.func.html b/coverage/core/Value.cpp.func.html new file mode 100644 index 000000000000..64a4e66d13e2 --- /dev/null +++ b/coverage/core/Value.cpp.func.html @@ -0,0 +1,217 @@ + + + + + + + + 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:24727091.5 %
Date:2024-04-19 12:12:35Functions:333691.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3addERKNS_5ValueEPS0_0
_ZN4PLMD4copyERKNS_5ValueEPS0_0
_ZN4PLMD4copyERKNS_5ValueERS0_0
_ZN4PLMD5Value10projectionERKS0_S2_261
_ZN4PLMD5Value10readBinaryERSi456
_ZN4PLMD5Value10setValTypeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE450
_ZN4PLMD5Value11setConstantEv5266
_ZN4PLMD5Value12setGradientsEPNS_15ActionAtomisticERj190
_ZN4PLMD5Value12setSymmetricERKb1264
_ZN4PLMD5Value14buildDataStoreEb11669
_ZN4PLMD5Value14setNotPeriodicEv1103780
_ZN4PLMD5Value15getPntrToActionEv18422721
_ZN4PLMD5Value16retrieveEdgeListERjRSt6vectorISt4pairIjjESaIS4_EERS2_IdSaIdEE2220
_ZN4PLMD5Value16setupPeriodicityEv108492
_ZN4PLMD5Value18reshapeMatrixStoreERKj6963
_ZN4PLMD5Value24setPositionInMatrixStashERKj35382
_ZN4PLMD5Value3setERKmRKd4928104
_ZN4PLMD5Value8addForceERKmdb39869045
_ZN4PLMD5Value8setShapeERKSt6vectorIjSaIjEE129330
_ZN4PLMD5Value9push_backERKd74915
_ZN4PLMD5Value9setDomainERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_7738
_ZN4PLMD5ValueC2EPNS_15ActionWithValueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbRKSt6vectorIjSaIjEE117404
_ZN4PLMD5ValueC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE18
_ZN4PLMD5ValueC2Ev164
_ZNK4PLMD5Value10applyForceERSt6vectorIdSaIdEE404010
_ZNK4PLMD5Value10isPeriodicEv1687317
_ZNK4PLMD5Value11writeBinaryERSo456
_ZNK4PLMD5Value13passGradientsERKdRSt3mapINS_10AtomNumberENS_13VectorGenericILj3EEESt4lessIS4_ESaISt4pairIKS4_S6_EEE283
_ZNK4PLMD5Value17calculateOnUpdateEv7504457
_ZNK4PLMD5Value17getGoodNumThreadsERKjS2_231990
_ZNK4PLMD5Value17ignoreStoredValueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE15989629
_ZNK4PLMD5Value21convertIndexToindicesERKmRSt6vectorIjSaIjEE775666
_ZNK4PLMD5Value3getERKmb622535126
_ZNK4PLMD5Value5printERNS_5OFileE547576
_ZNK4PLMD5Value9getDomainERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES7_16758
_ZNK4PLMD5Value9getDomainERdS1_34
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/Value.cpp.gcov.html b/coverage/core/Value.cpp.gcov.html new file mode 100644 index 000000000000..02e64c8bcf76 --- /dev/null +++ b/coverage/core/Value.cpp.gcov.html @@ -0,0 +1,483 @@ + + + + + + + + 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:24727091.5 %
Date:2024-04-19 12:12:35Functions:333691.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 "Value.h"
+      23             : #include "ActionWithValue.h"
+      24             : #include "ActionAtomistic.h"
+      25             : #include "ActionWithArguments.h"
+      26             : #include "ActionWithVector.h"
+      27             : #include "ActionWithVirtualAtom.h"
+      28             : #include "tools/Exception.h"
+      29             : #include "tools/OpenMP.h"
+      30             : #include "tools/OFile.h"
+      31             : #include "PlumedMain.h"
+      32             : 
+      33             : namespace PLMD {
+      34             : 
+      35         164 : Value::Value():
+      36         164 :   action(NULL),
+      37         164 :   value_set(false),
+      38         164 :   hasForce(false),
+      39         164 :   storedata(false),
+      40             :   shape(std::vector<unsigned>()),
+      41         164 :   hasDeriv(true),
+      42         164 :   bufstart(0),
+      43         164 :   streampos(0),
+      44         164 :   matpos(0),
+      45         164 :   ngrid_der(0),
+      46         164 :   ncols(0),
+      47         164 :   book_start(0),
+      48         164 :   symmetric(false),
+      49         164 :   periodicity(unset),
+      50         164 :   min(0.0),
+      51         164 :   max(0.0),
+      52         164 :   max_minus_min(0.0),
+      53         164 :   inv_max_minus_min(0.0),
+      54         164 :   derivativeIsZeroWhenValueIsZero(false)
+      55             : {
+      56         164 :   data.resize(1); inputForce.resize(1);
+      57         164 : }
+      58             : 
+      59          18 : Value::Value(const std::string& name):
+      60          18 :   action(NULL),
+      61          18 :   value_set(false),
+      62          18 :   hasForce(false),
+      63          18 :   name(name),
+      64          18 :   storedata(false),
+      65             :   shape(std::vector<unsigned>()),
+      66          18 :   hasDeriv(true),
+      67          18 :   bufstart(0),
+      68          18 :   streampos(0),
+      69          18 :   ngrid_der(0),
+      70          18 :   matpos(0),
+      71          18 :   ncols(0),
+      72          18 :   book_start(0),
+      73          18 :   symmetric(false),
+      74          18 :   periodicity(unset),
+      75          18 :   min(0.0),
+      76          18 :   max(0.0),
+      77          18 :   max_minus_min(0.0),
+      78          18 :   inv_max_minus_min(0.0),
+      79          18 :   derivativeIsZeroWhenValueIsZero(false)
+      80             : {
+      81          18 :   data.resize(1); inputForce.resize(1);
+      82          18 :   data[0]=inputForce[0]=0;
+      83          18 : }
+      84             : 
+      85      117404 : Value::Value(ActionWithValue* av, const std::string& name, const bool withderiv, const std::vector<unsigned>&ss):
+      86      117404 :   action(av),
+      87      117404 :   value_set(false),
+      88      117404 :   hasForce(false),
+      89      117404 :   name(name),
+      90      117404 :   storedata(false),
+      91      117404 :   hasDeriv(withderiv),
+      92      117404 :   bufstart(0),
+      93      117404 :   streampos(0),
+      94      117404 :   ngrid_der(0),
+      95      117404 :   matpos(0),
+      96      117404 :   ncols(0),
+      97      117404 :   book_start(0),
+      98      117404 :   symmetric(false),
+      99      117404 :   periodicity(unset),
+     100      117404 :   min(0.0),
+     101      117404 :   max(0.0),
+     102      117404 :   max_minus_min(0.0),
+     103      117404 :   inv_max_minus_min(0.0),
+     104      117404 :   derivativeIsZeroWhenValueIsZero(false)
+     105             : {
+     106      117404 :   if( action ) {
+     107      116948 :     if( action->getName()=="ACCUMULATE" || action->getName()=="COLLECT" ) valtype=average;
+     108             :   }
+     109      227657 :   if( action ) storedata=action->getName()=="PUT" || valtype==average;
+     110      117404 :   if( ss.size() && withderiv ) storedata=true;
+     111      117404 :   setShape( ss );
+     112      117404 : }
+     113             : 
+     114         450 : void Value::setValType( const std::string& vtype ) {
+     115         450 :   if( vtype=="normal" ) valtype=normal;
+     116         450 :   else if( vtype=="constant" ) valtype=constant;
+     117         450 :   else if( vtype=="average" ) valtype=average;
+     118         450 :   else if( vtype=="calcFromAverage" ) valtype=calcFromAverage;
+     119           0 :   else plumed_merror("invalid valtype " + vtype );
+     120         450 : }
+     121             : 
+     122      129330 : void Value::setShape( const std::vector<unsigned>&ss ) {
+     123      129330 :   std::size_t tot=1; shape.resize( ss.size() );
+     124      158793 :   for(unsigned i=0; i<shape.size(); ++i) { tot = tot*ss[i]; shape[i]=ss[i]; }
+     125             : 
+     126      129330 :   if( shape.size()>0 && hasDeriv ) {
+     127             :     // This is for grids
+     128        1997 :     ngrid_der = shape.size();
+     129        1997 :     if( action ) ngrid_der = action->getNumberOfDerivatives();
+     130        1997 :     std::size_t ndata = tot*(1+ngrid_der);
+     131        1997 :     data.resize( ndata ); inputForce.resize( tot );
+     132      127333 :   } else if( shape.size()==0 ) {
+     133             :     // This is for scalars
+     134      105887 :     data.resize(1); inputForce.resize(1);
+     135       21446 :   } else if( storedata && shape.size()<2 ) {
+     136             :     // This is for vectors (matrices have special version because we have sparse storage)
+     137       11651 :     data.resize( tot ); inputForce.resize( tot );
+     138             :   }
+     139      129330 : }
+     140             : 
+     141      108492 : void Value::setupPeriodicity() {
+     142      108492 :   if( min==0 && max==0 ) {
+     143      100754 :     periodicity=notperiodic;
+     144             :   } else {
+     145        7738 :     periodicity=periodic;
+     146        7738 :     max_minus_min=max-min;
+     147        7738 :     plumed_massert(max_minus_min>0, "your function has a very strange domain?");
+     148        7738 :     inv_max_minus_min=1.0/max_minus_min;
+     149             :   }
+     150      108492 : }
+     151             : 
+     152     1687317 : bool Value::isPeriodic()const {
+     153     1687317 :   plumed_massert(periodicity!=unset,"periodicity should be set");
+     154     1687317 :   return periodicity==periodic;
+     155             : }
+     156             : 
+     157      404010 : bool Value::applyForce(std::vector<double>& forces ) const {
+     158      404010 :   if( !hasForce || valtype!=normal ) return false;
+     159             :   plumed_dbg_massert( data.size()-1==forces.size()," forces array has wrong size" );
+     160        9165 :   const unsigned N=data.size()-1;
+     161    41672481 :   for(unsigned i=0; i<N; ++i) forces[i]=inputForce[0]*data[1+i];
+     162             :   return true;
+     163             : }
+     164             : 
+     165     1103780 : void Value::setNotPeriodic() {
+     166     1103780 :   min=0; max=0; periodicity=notperiodic;
+     167     1103780 : }
+     168             : 
+     169        7738 : void Value::setDomain(const std::string& pmin,const std::string& pmax) {
+     170        7738 :   str_min=pmin;
+     171        7738 :   if( !Tools::convertNoexcept(str_min,min) ) action->error("could not convert period string " + str_min + " to real");
+     172        7738 :   str_max=pmax;
+     173        7738 :   if( !Tools::convertNoexcept(str_max,max) ) action->error("could not convert period string " + str_max + " to read");
+     174        7738 :   setupPeriodicity();
+     175        7738 : }
+     176             : 
+     177       16758 : void Value::getDomain(std::string&minout,std::string&maxout) const {
+     178       16758 :   plumed_massert(periodicity==periodic,"function should be periodic");
+     179       16758 :   minout=str_min;
+     180       16758 :   maxout=str_max;
+     181       16758 : }
+     182             : 
+     183          34 : void Value::getDomain(double&minout,double&maxout) const {
+     184          34 :   plumed_massert(periodicity==periodic,"function should be periodic");
+     185          34 :   minout=min;
+     186          34 :   maxout=max;
+     187          34 : }
+     188             : 
+     189         190 : void Value::setGradients( ActionAtomistic* aa, unsigned& start ) {
+     190             :   // Can't do gradients if we don't have derivatives
+     191         190 :   if( !hasDeriv ) return;
+     192         154 :   plumed_assert( shape.size()==0 );
+     193        8362 :   for(unsigned j=0; j<aa->getNumberOfAtoms(); ++j) {
+     194        8208 :     Vector der(data[1+start+3*j],data[1+start+3*j+1],data[1+start+3*j+2]);
+     195        8208 :     aa->getGradient( j, der, gradients );
+     196             :   }
+     197         154 :   start += aa->getNumberOfAtoms();
+     198             : }
+     199             : 
+     200         283 : void Value::passGradients( const double& der, std::map<AtomNumber,Vector>& g ) const {
+     201        8921 :   for(const auto & p : gradients) { AtomNumber iatom=p.first; g[iatom] += p.second*der; }
+     202         283 : }
+     203             : 
+     204         261 : double Value::projection(const Value& v1,const Value&v2) {
+     205             :   double proj=0.0;
+     206             :   const std::map<AtomNumber,Vector> & grad1(v1.gradients);
+     207             :   const std::map<AtomNumber,Vector> & grad2(v2.gradients);
+     208       16167 :   for(const auto & p1 : grad1) {
+     209       15906 :     AtomNumber a=p1.first;
+     210             :     const auto p2=grad2.find(a);
+     211       15906 :     if(p2!=grad2.end()) {
+     212        8224 :       proj+=dotProduct(p1.second,(*p2).second);
+     213             :     }
+     214             :   }
+     215         261 :   return proj;
+     216             : }
+     217             : 
+     218    18422721 : ActionWithValue* Value::getPntrToAction() {
+     219    18422721 :   plumed_assert( action!=NULL );
+     220    18422721 :   return action;
+     221             : }
+     222             : 
+     223     4928104 : void Value::set(const std::size_t& n, const double& v ) {
+     224     4928104 :   value_set=true;
+     225     4928104 :   if( getRank()==0 ) { plumed_assert( n==0 ); data[n]=v; applyPeriodicity(n); }
+     226     4902429 :   else if( !hasDeriv ) { plumed_dbg_massert( n<data.size(), "failing in " + getName() ); data[n]=v; applyPeriodicity(n); }
+     227      317316 :   else { data[n*(1+ngrid_der)] = v; }
+     228     4928104 : }
+     229             : 
+     230       74915 : void Value::push_back( const double& v ) {
+     231       74915 :   value_set=true;
+     232       74915 :   if( shape.size()==1 ) {
+     233       36356 :     data.push_back(v); shape[0]++;
+     234       38559 :   } else if( shape.size()==2 ) {
+     235       38559 :     data.push_back(v);
+     236       38559 :     shape[0] = std::ceil( data.size() / shape[1] );
+     237             :   }
+     238       74915 : }
+     239             : 
+     240   622535126 : double Value::get(const std::size_t& ival, const bool trueind) const {
+     241   622535126 :   if( hasDeriv ) return data[ival*(1+ngrid_der)];
+     242             : #ifdef DNDEBUG
+     243             :   if( action ) plumed_dbg_massert( ival<getNumberOfValues(), "could not get value from " + name );
+     244             : #endif
+     245   607626418 :   if( shape.size()==2 && ncols<shape[1] && trueind ) {
+     246     2000962 :     unsigned irow = std::floor( ival / shape[1] ), jcol = ival%shape[1];
+     247             :     // This is a special treatment for the lower triangular matrices that are used when
+     248             :     // we do ITRE with COLLECT_FRAMES
+     249     2000962 :     if( ncols==0 ) {
+     250           0 :       if( jcol<=irow ) return data[0.5*irow*(irow+1) + jcol];
+     251             :       return 0;
+     252             :     }
+     253    20654648 :     for(unsigned i=0; i<getRowLength(irow); ++i) {
+     254    19056534 :       if( getRowIndex(irow,i)==jcol ) return data[irow*ncols+i];
+     255             :     }
+     256             :     return 0.0;
+     257             :   }
+     258   605625456 :   plumed_massert( ival<data.size(), "cannot get value from " + name );
+     259   605625456 :   return data[ival];
+     260             : }
+     261             : 
+     262    39869045 : void Value::addForce(const std::size_t& iforce, double f, const bool trueind) {
+     263    39869045 :   hasForce=true;
+     264    39869045 :   if( shape.size()==2 && !hasDeriv && ncols<shape[1] && trueind ) {
+     265      808020 :     unsigned irow = std::floor( iforce / shape[0] ), jcol = iforce%shape[0];
+     266     6142736 :     for(unsigned i=0; i<getRowLength(irow); ++i) {
+     267     5361844 :       if( getRowIndex(irow,i)==jcol ) { inputForce[irow*ncols+i]+=f; return; }
+     268             :     }
+     269      780892 :     plumed_assert( fabs(f)<epsilon ); return;
+     270             :   }
+     271    39061025 :   plumed_massert( iforce<inputForce.size(), "can't add force to " + name );
+     272    39061025 :   inputForce[iforce]+=f;
+     273             : }
+     274             : 
+     275             : 
+     276       11669 : void Value::buildDataStore( const bool forprint ) {
+     277       11669 :   if( getRank()==0 ) return;
+     278        5144 :   storedata=true; setShape( shape );
+     279        5144 :   if( !forprint ) return ;
+     280         192 :   ActionWithVector* av=dynamic_cast<ActionWithVector*>( action );
+     281         192 :   if( av ) (av->getFirstActionInChain())->never_reduce_tasks=true;
+     282             : }
+     283             : 
+     284        6963 : void Value::reshapeMatrixStore( const unsigned& n ) {
+     285             :   plumed_dbg_assert( shape.size()==2 && !hasDeriv );
+     286        6963 :   if( !storedata ) return ;
+     287        6963 :   ncols=n; if( ncols>shape[1] ) ncols=shape[1];
+     288        6963 :   unsigned size=shape[0]*ncols;
+     289        6963 :   if( matrix_bookeeping.size()!=(size+shape[0]) ) {
+     290        2453 :     data.resize( size ); inputForce.resize( size );
+     291        2453 :     matrix_bookeeping.resize( size + shape[0], 0 );
+     292        2453 :     if( ncols>=shape[1] ) {
+     293      246727 :       for(unsigned i=0; i<shape[0]; ++i) {
+     294      244337 :         matrix_bookeeping[(1+ncols)*i] = shape[1];
+     295    23647679 :         for(unsigned j=0; j<shape[1]; ++j) matrix_bookeeping[(1+ncols)*i+1+j]=j;
+     296             :       }
+     297             :     }
+     298             :   }
+     299        6963 :   if( ncols<shape[1] ) std::fill(matrix_bookeeping.begin(), matrix_bookeeping.end(), 0);
+     300             : }
+     301             : 
+     302       35382 : void Value::setPositionInMatrixStash( const unsigned& p ) {
+     303             :   plumed_dbg_assert( shape.size()==2 && !hasDeriv );
+     304       35382 :   matpos=p;
+     305       35382 : }
+     306             : 
+     307    15989629 : bool Value::ignoreStoredValue(const std::string& c) const {
+     308    15989629 :   if( !storedata && shape.size()>0 ) return true;
+     309     6830976 :   ActionWithVector* av=dynamic_cast<ActionWithVector*>(action);
+     310     6830976 :   if( av ) return (av->getFirstActionInChain())->getLabel()==c;
+     311             :   return false;
+     312             : }
+     313             : 
+     314        5266 : void Value::setConstant() {
+     315        5266 :   valtype=constant; storedata=true; setShape( shape );
+     316        5266 :   if( getRank()==2 && !hasDeriv ) reshapeMatrixStore( shape[1] );
+     317        5266 : }
+     318             : 
+     319         456 : void Value::writeBinary(std::ostream&o) const {
+     320         456 :   o.write(reinterpret_cast<const char*>(&data[0]),data.size()*sizeof(double));
+     321         456 : }
+     322             : 
+     323        1264 : void Value::setSymmetric( const bool& sym ) {
+     324        1264 :   plumed_assert( shape.size()==2 && !hasDeriv );
+     325        1264 :   if( sym && shape[0]!=shape[1] ) plumed_merror("non-square matrix cannot be symmetric");
+     326        1264 :   symmetric=sym;
+     327        1264 : }
+     328             : 
+     329        2220 : void Value::retrieveEdgeList( unsigned& nedge, std::vector<std::pair<unsigned,unsigned> >& active, std::vector<double>& elems ) {
+     330        2220 :   nedge=0; plumed_dbg_assert( shape.size()==2 && !hasDeriv );
+     331             :   // Check we have enough space to store the edge list
+     332        2220 :   if( elems.size()<shape[0]*ncols ) { elems.resize( shape[0]*ncols ); active.resize( shape[0]*ncols ); }
+     333             : 
+     334      269579 :   for(unsigned i=0; i<shape[0]; ++i) {
+     335             :     unsigned ncol = getRowLength(i);
+     336    15002116 :     for(unsigned j=0; j<ncol; ++j) {
+     337    14734757 :       if( fabs(get(i*ncols+j,false))<epsilon ) continue;
+     338     3265037 :       if( symmetric && getRowIndex(i,j)>i ) continue;
+     339     3213497 :       active[nedge].first = i; active[nedge].second = getRowIndex(i,j);
+     340     3213497 :       elems[nedge] = get(i*ncols+j,false); nedge++;
+     341             :     }
+     342             :   }
+     343        2220 : }
+     344             : 
+     345         456 : void Value::readBinary(std::istream&i) {
+     346         456 :   i.read(reinterpret_cast<char*>(&data[0]),data.size()*sizeof(double));
+     347         456 : }
+     348             : 
+     349      775666 : void Value::convertIndexToindices(const std::size_t& index, std::vector<unsigned>& indices ) const {
+     350      775666 :   if( hasDeriv || getRank()==1 ) {
+     351       12302 :     std::size_t kk=index; indices[0]=index%shape[0];
+     352       12302 :     for(unsigned i=1; i<shape.size()-1; ++i) {
+     353           0 :       kk=(kk-indices[i-1])/shape[i-1];
+     354           0 :       indices[i]=kk%shape[i];
+     355             :     }
+     356       12302 :     if(shape.size()>=2) indices[shape.size()-1]=(kk-indices[shape.size()-2])/shape[shape.size()-2];
+     357      763364 :   } else if( getRank()==2 ) {
+     358      763364 :     indices[0]=std::floor( index/shape[1] ); indices[1] = index%shape[1];
+     359             :   }
+     360      775666 : }
+     361             : 
+     362      547576 : void Value::print( OFile& ofile ) const {
+     363      570554 :   if( isPeriodic() ) { ofile.printField( "min_" + name, str_min ); ofile.printField("max_" + name, str_max ); }
+     364      547576 :   if( shape.size()==0 || getNumberOfValues()==1 ) {
+     365      546257 :     ofile.printField( name, get(0) );
+     366             :   } else {
+     367        1319 :     std::vector<unsigned> indices( shape.size() );
+     368      776985 :     for(unsigned i=0; i<getNumberOfValues(); ++i) {
+     369      775666 :       convertIndexToindices( i, indices ); std::string num, fname = name;
+     370     2314696 :       for(unsigned i=0; i<shape.size(); ++i) { Tools::convert( indices[i]+1, num ); fname += "." + num; }
+     371      775666 :       ofile.printField( fname, get(i) );
+     372             :     }
+     373             :   }
+     374      547576 : }
+     375             : 
+     376      231990 : unsigned Value::getGoodNumThreads( const unsigned& j, const unsigned& k ) const {
+     377      231990 :   return OpenMP::getGoodNumThreads( &data[j], (k-j) );
+     378             : }
+     379             : 
+     380           0 : void copy( const Value& val1, Value& val2 ) {
+     381           0 :   unsigned nder=val1.getNumberOfDerivatives();
+     382           0 :   if( nder!=val2.getNumberOfDerivatives() ) { val2.resizeDerivatives( nder ); }
+     383           0 :   val2.clearDerivatives();
+     384           0 :   for(unsigned i=0; i<val1.getNumberOfDerivatives(); ++i) val2.addDerivative( i, val1.getDerivative(i) );
+     385           0 :   val2.set( val1.get() );
+     386           0 : }
+     387             : 
+     388           0 : void copy( const Value& val1, Value* val2 ) {
+     389           0 :   unsigned nder=val1.getNumberOfDerivatives();
+     390           0 :   if( nder!=val2->getNumberOfDerivatives() ) { val2->resizeDerivatives( nder ); }
+     391           0 :   val2->clearDerivatives();
+     392           0 :   for(unsigned i=0; i<val1.getNumberOfDerivatives(); ++i) val2->addDerivative( i, val1.getDerivative(i) );
+     393           0 :   val2->set( val1.get() );
+     394           0 : }
+     395             : 
+     396           0 : void add( const Value& val1, Value* val2 ) {
+     397           0 :   plumed_assert( val1.getNumberOfDerivatives()==val2->getNumberOfDerivatives() );
+     398           0 :   for(unsigned i=0; i<val1.getNumberOfDerivatives(); ++i) val2->addDerivative( i, val1.getDerivative(i) );
+     399           0 :   val2->set( val1.get() + val2->get() );
+     400           0 : }
+     401             : 
+     402     7504457 : bool Value::calculateOnUpdate() const {
+     403     7504457 :   return (valtype==average || valtype==calcFromAverage);
+     404             : }
+     405             : 
+     406             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/Value.h.func-sort-c.html b/coverage/core/Value.h.func-sort-c.html new file mode 100644 index 000000000000..806c4f083a77 --- /dev/null +++ b/coverage/core/Value.h.func-sort-c.html @@ -0,0 +1,121 @@ + + + + + + + + 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:818397.6 %
Date:2024-04-19 12:12:35Functions:1212100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5Value3addEd2144
_ZNK4PLMD5Value14bringBackInPbcEd3173
_ZN4PLMD5Value15clearInputForceERKSt6vectorINS_10AtomNumberESaIS2_EE115450
_ZN4PLMD5Value18addGridDerivativesERKjS2_RKd1089247
_ZN4PLMD5Value16clearDerivativesEb2801776
_ZNK4PLMD5Value10differenceEd3989526
_ZN4PLMD5Value17resizeDerivativesEi4445221
_ZNK4PLMD5Value22getNumberOfDerivativesEv16215891
_ZNK4PLMD5Value17getNumberOfValuesEv45433116
_ZN4PLMD5Value3addERKmRKd46450631
_ZN4PLMD5Value16applyPeriodicityERKj56790951
_ZNK4PLMD5Value10differenceEdd135676778
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/Value.h.func.html b/coverage/core/Value.h.func.html new file mode 100644 index 000000000000..b3f085193d09 --- /dev/null +++ b/coverage/core/Value.h.func.html @@ -0,0 +1,121 @@ + + + + + + + + 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:818397.6 %
Date:2024-04-19 12:12:35Functions:1212100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5Value15clearInputForceERKSt6vectorINS_10AtomNumberESaIS2_EE115450
_ZN4PLMD5Value16applyPeriodicityERKj56790951
_ZN4PLMD5Value16clearDerivativesEb2801776
_ZN4PLMD5Value17resizeDerivativesEi4445221
_ZN4PLMD5Value18addGridDerivativesERKjS2_RKd1089247
_ZN4PLMD5Value3addERKmRKd46450631
_ZN4PLMD5Value3addEd2144
_ZNK4PLMD5Value10differenceEd3989526
_ZNK4PLMD5Value10differenceEdd135676778
_ZNK4PLMD5Value14bringBackInPbcEd3173
_ZNK4PLMD5Value17getNumberOfValuesEv45433116
_ZNK4PLMD5Value22getNumberOfDerivativesEv16215891
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/Value.h.gcov.html b/coverage/core/Value.h.gcov.html new file mode 100644 index 000000000000..6f1ad757ec63 --- /dev/null +++ b/coverage/core/Value.h.gcov.html @@ -0,0 +1,621 @@ + + + + + + + + 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:818397.6 %
Date:2024-04-19 12:12:35Functions:1212100.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 OFile;
+      36             : class ActionWithValue;
+      37             : class ActionAtomistic;
+      38             : 
+      39             : /// \ingroup TOOLBOX
+      40             : /// A class for holding the value of a function together with its derivatives.
+      41             : /// Typically, an  object of type PLMD::ActionWithValue will contain one
+      42             : /// object of type PLUMD::Value that will be named after the label.  If the
+      43             : /// PLMD::ActionWithValue is part of a class that calculates multiple components
+      44             : /// then the class will contain multiple that will be called label.component-name
+      45             : /// This class is used to pass information between different PLMD::Action
+      46             : /// objects.  However, if you find a use for a tempory PLMD::Value in some method
+      47             : /// you are implementing please feel free to use it.
+      48             : class Value {
+      49             :   friend class ActionWithValue;
+      50             :   friend class ActionWithVector;
+      51             :   friend class ActionAtomistic;
+      52             :   friend class ActionWithArguments;
+      53             :   friend class ActionWithVirtualAtom;
+      54             :   friend class DomainDecomposition;
+      55             :   template<typename T>
+      56             :   friend class DataPassingObjectTyped;
+      57             : /// This copies the contents of a value into a second value (just the derivatives and value)
+      58             :   friend void copy( const Value& val1, Value& val2 );
+      59             : /// This copies the contents of a value into a second value (but second value is a pointer)
+      60             :   friend void copy( const Value& val, Value* val2 );
+      61             : /// This adds some derivatives onto the value
+      62             :   friend void add( const Value& val1, Value* valout );
+      63             : /// This calculates val1*val2 and sorts out the derivatives
+      64             :   friend void product( const Value& val1, const Value& val2, Value& valout );
+      65             : /// This calculates va1/val2 and sorts out the derivatives
+      66             :   friend void quotient( const Value& val1, const Value& val2, Value* valout );
+      67             : private:
+      68             : /// The action in which this quantity is calculated
+      69             :   ActionWithValue* action;
+      70             : /// Had the value been set
+      71             :   bool value_set;
+      72             : /// The value of the quantity
+      73             :   std::vector<double> data;
+      74             : /// The force acting on this quantity
+      75             :   std::vector<double> inputForce;
+      76             : /// A flag telling us we have a force acting on this quantity
+      77             :   bool hasForce;
+      78             : /// The way this value is used in the code
+      79             : /// normal = regular value that is determined during calculate
+      80             : /// constant = constnt value that is determined during startup and that doesn't change during simulation
+      81             : /// average = value that is averaged/collected over multiple steps of trajectory
+      82             : /// calcFromAverage = value that is calculated from an average value
+      83             :   enum {normal,constant,average,calcFromAverage} valtype=normal;
+      84             : /// This is used by ActionWithValue to set the valtype
+      85             :   void setValType( const std::string& vtype );
+      86             : /// This is used by ActionWithValue to determine if we need to calculate on update
+      87             :   bool calculateOnUpdate() const ;
+      88             : /// The derivatives of the quantity stored in value
+      89             :   std::map<AtomNumber,Vector> gradients;
+      90             : /// The name of this quantiy
+      91             :   std::string name;
+      92             : /// Are we storing the data for this value if it is vector or matrix
+      93             :   bool storedata;
+      94             : /// What is the shape of the value (0 dimensional=scalar, n dimensional with derivatives=grid, 1 dimensional no derivatives=vector, 2 dimensional no derivatives=matrix)
+      95             :   std::vector<unsigned> shape;
+      96             : /// Does this quanity have derivatives
+      97             :   bool hasDeriv;
+      98             : /// Variables for storing data
+      99             :   unsigned bufstart, streampos, matpos, ngrid_der, ncols, book_start;
+     100             : /// If we are storing a matrix is it symmetric?
+     101             :   bool symmetric;
+     102             : /// This is a bookeeping array that holds the non-zero elements of the "sparse" matrix
+     103             :   std::vector<unsigned> matrix_bookeeping;
+     104             : /// Is this quantity periodic
+     105             :   enum {unset,periodic,notperiodic} periodicity;
+     106             : /// Various quantities that describe the domain of this value
+     107             :   std::string str_min, str_max;
+     108             :   double min,max;
+     109             :   double max_minus_min;
+     110             :   double inv_max_minus_min;
+     111             : /// Is the derivative of this quantity zero when the value is zero
+     112             :   bool derivativeIsZeroWhenValueIsZero;
+     113             : /// Complete the setup of the periodicity
+     114             :   void setupPeriodicity();
+     115             : // bring value within PBCs
+     116             :   void applyPeriodicity( const unsigned& ival );
+     117             : public:
+     118             : /// A constructor that can be used to make Vectors of values
+     119             :   Value();
+     120             : /// A constructor that can be used to make Vectors of named values
+     121             :   explicit Value(const std::string& name);
+     122             : /// A constructor that is used throughout the code to setup the value poiters
+     123             :   Value(ActionWithValue* av, const std::string& name, const bool withderiv,const std::vector<unsigned>&ss=std::vector<unsigned>());
+     124             : /// Set the shape of the Value
+     125             :   void setShape( const std::vector<unsigned>&ss );
+     126             : /// Set the value of the function
+     127             :   void set(double);
+     128             : /// Set the value of the stored data
+     129             :   void set(const std::size_t& n, const double& v );
+     130             : /// Add something to the value of the function
+     131             :   void add(double);
+     132             : /// Add something to the ith element of the data array
+     133             :   void add(const std::size_t& n, const double& v );
+     134             : /// Get the value of the function
+     135     6788394 :   double get( const std::size_t& ival=0, const bool trueind=true ) const;
+     136             : /// Find out if the value has been set
+     137             :   bool valueHasBeenSet() const;
+     138             : /// Check if the value is periodic
+     139             :   bool isPeriodic() const;
+     140             : /// Set the function not periodic
+     141             :   void setNotPeriodic();
+     142             : /// Set the domain of the function
+     143             :   void setDomain(const std::string&, const std::string&);
+     144             : /// Get the domain of the quantity
+     145             :   void getDomain(std::string&,std::string&) const;
+     146             : /// Get the domain of the quantity
+     147             :   void getDomain(double&,double&) const;
+     148             : /// Get the name of the quantity
+     149             :   const std::string& getName() const;
+     150             : /// Check whether or not this particular quantity has derivatives
+     151             :   bool hasDerivatives()const;
+     152             : /// Get the number of derivatives that this particular value has
+     153             :   unsigned getNumberOfDerivatives() const;
+     154             : /// Set the number of derivatives
+     155             :   void resizeDerivatives(int n);
+     156             : /// Set all the derivatives to zero
+     157             :   void clearDerivatives( const bool force=false );
+     158             : /// Add some derivative to the ith component of the derivatives array
+     159             :   void addDerivative(unsigned i,double d);
+     160             : /// Set the value of the ith component of the derivatives array
+     161             :   void setDerivative(unsigned i, double d);
+     162             : /// Apply the chain rule to the derivatives
+     163             :   void chainRule(double df);
+     164             : /// Get the derivative with respect to component n
+     165             :   double getDerivative(const unsigned n) const;
+     166             : /// Clear the input force on the variable
+     167             :   void clearInputForce();
+     168             : /// Special method for clearing forces on variables used by DataPassingObject
+     169             :   void clearInputForce( const std::vector<AtomNumber>& index );
+     170             : /// Add some force on this value
+     171             :   void addForce(double f);
+     172             : /// Add some force on the ival th component of this value
+     173             :   void addForce( const std::size_t& ival, double f, const bool trueind=true );
+     174             : /// Get the value of the force on this colvar
+     175             :   double getForce( const std::size_t& ival=0 ) const ;
+     176             : /// Apply the forces to the derivatives using the chain rule (if there are no forces this routine returns false)
+     177             :   bool applyForce( std::vector<double>& forces ) const ;
+     178             : /// Calculate the difference between the instantaneous value of the function and some other point: other_point-inst_val
+     179             :   double difference(double)const;
+     180             : /// Calculate the difference between two values of this function: d2 -d1
+     181             :   double difference(double d1,double d2)const;
+     182             : /// This returns the pointer to the action where this value is calculated
+     183             :   ActionWithValue* getPntrToAction();
+     184             : /// Bring back one value into the correct pbc if needed, else give back the value
+     185             :   double bringBackInPbc(double d1)const;
+     186             : /// Get the difference between max and minimum of domain
+     187             :   double getMaxMinusMin()const;
+     188             : /// This sets up the gradients
+     189             :   void setGradients( ActionAtomistic* aa, unsigned& start );
+     190             : /// This passes gradients from one action to another
+     191             :   void passGradients( const double& der, std::map<AtomNumber,Vector>& g ) const ;
+     192             :   static double projection(const Value&,const Value&);
+     193             : /// Get the rank of the object that is contained in this value
+     194             :   unsigned getRank() const ;
+     195             : /// Get the shape of the object that is contained in this value
+     196             :   const std::vector<unsigned>& getShape() const ;
+     197             : /// This turns on storing of vectors/matrices
+     198             :   void buildDataStore( const bool forprint=false );
+     199             : /// Reshape the storage for sparse matrices
+     200             :   void reshapeMatrixStore( const unsigned& n );
+     201             : /// Set the symmetric flag equal true for this matrix
+     202             :   void setSymmetric( const bool& sym );
+     203             : /// Get the total number of scalars that are stored here
+     204             :   unsigned getNumberOfValues() const ;
+     205             : /// Get the number of threads to use when assigning this value
+     206             :   unsigned getGoodNumThreads( const unsigned& j, const unsigned& k ) const ;
+     207             : /// These are used for passing around the data in this value when we are doing replica exchange
+     208             :   void writeBinary(std::ostream&o) const ;
+     209             :   void readBinary(std::istream&i);
+     210             : /// These are used for making constant values
+     211             :   bool isConstant() const ;
+     212             :   void setConstant();
+     213             : /// Check if forces have been added on this value
+     214             :   bool forcesWereAdded() const ;
+     215             : /// Set a bool that tells us if the derivative is zero when the value is zero true
+     216             :   void setDerivativeIsZeroWhenValueIsZero();
+     217             : /// Return a bool that tells us if the derivative is zero when the value is zero
+     218             :   bool isDerivativeZeroWhenValueIsZero() const ;
+     219             : ///
+     220             :   unsigned getPositionInStream() const ;
+     221             : /// This stuff handles where to look for the start of the row that contains the row of the matrix
+     222             :   void setPositionInMatrixStash( const unsigned& p );
+     223             :   unsigned getPositionInMatrixStash() const ;
+     224             : /// This stuff handles where to keep the bookeeping stuff for storing the sparse matrix
+     225             :   void setMatrixBookeepingStart( const unsigned& b );
+     226             :   unsigned getMatrixBookeepingStart() const ;
+     227             : /// Convert the input index to its corresponding indices
+     228             :   void convertIndexToindices(const std::size_t& index, std::vector<unsigned>& indices ) const ;
+     229             : /// Print out all the values in this Value
+     230             :   void print( OFile& ofile ) const ;
+     231             : /// Are we to ignore the stored value
+     232             :   bool ignoreStoredValue(const std::string& n) const ;
+     233             : /// Set a matrix element to be non zero
+     234             :   void setMatrixBookeepingElement( const unsigned& i, const unsigned& n );
+     235             : ///
+     236             :   unsigned getRowLength( const unsigned& irow ) const ;
+     237             : ///
+     238             :   unsigned getRowIndex( const unsigned& irow, const unsigned& jind ) const ;
+     239             : /// Are we storing this value
+     240             :   bool valueIsStored() const ;
+     241             : ///
+     242             :   unsigned getNumberOfColumns() const ;
+     243             : ///
+     244             :   bool isSymmetric() const ;
+     245             : /// Retrieve the non-zero edges in a matrix
+     246             :   void retrieveEdgeList( unsigned& nedge, std::vector<std::pair<unsigned,unsigned> >& active, std::vector<double>& elems );
+     247             : /// Get the number of derivatives that the grid has
+     248             :   unsigned getNumberOfGridDerivatives() const ;
+     249             : /// get the derivative of a grid at a point n with resepct to argument j
+     250             :   double getGridDerivative(const unsigned& n, const unsigned& j ) const ;
+     251             : /// Add the derivatives of the grid to the corner
+     252             :   void addGridDerivatives( const unsigned& n, const unsigned& j, const double& val );
+     253             : ///
+     254             :   void setGridDerivatives( const unsigned& n, const unsigned& j, const double& val );
+     255             : /// Add another value to the end of the data vector held by this value.  This is used in COLLECT
+     256             :   void push_back( const double& val );
+     257             : };
+     258             : 
+     259             : void copy( const Value& val1, Value& val2 );
+     260             : void copy( const Value& val1, Value* val2 );
+     261             : void add( const Value& val1, Value* valout );
+     262             : 
+     263             : inline
+     264    56790951 : void Value::applyPeriodicity(const unsigned& ival) {
+     265    56790951 :   if(periodicity==periodic) {
+     266     2384751 :     data[ival]=min+difference(min,data[ival]);
+     267     2384751 :     if(data[ival]<min)data[ival]+=max_minus_min;
+     268             :   }
+     269    56790951 : }
+     270             : 
+     271             : inline
+     272             : void product( const Value& val1, const Value& val2, Value& valout ) {
+     273             :   plumed_assert( val1.getNumberOfDerivatives()==val2.getNumberOfDerivatives() );
+     274             :   if( valout.getNumberOfDerivatives()!=val1.getNumberOfDerivatives() ) valout.resizeDerivatives( val1.getNumberOfDerivatives() );
+     275             :   valout.value_set=false;
+     276             :   valout.clearDerivatives();
+     277             :   double u=val1.get();
+     278             :   double v=val2.get();
+     279             :   for(unsigned i=0; i<val1.getNumberOfDerivatives(); ++i) {
+     280             :     valout.addDerivative(i, u*val2.getDerivative(i) + v*val1.getDerivative(i) );
+     281             :   }
+     282             :   valout.set( u*v );
+     283             : }
+     284             : 
+     285             : inline
+     286             : void quotient( const Value& val1, const Value& val2, Value* valout ) {
+     287             :   plumed_assert( val1.getNumberOfDerivatives()==val2.getNumberOfDerivatives());
+     288             :   if( valout->getNumberOfDerivatives()!=val1.getNumberOfDerivatives() ) valout->resizeDerivatives( val1.getNumberOfDerivatives() );
+     289             :   valout->value_set=false;
+     290             :   valout->clearDerivatives();
+     291             :   double u=val1.get();
+     292             :   double v=val2.get();
+     293             :   for(unsigned i=0; i<val1.getNumberOfDerivatives(); ++i) {
+     294             :     valout->addDerivative(i, v*val1.getDerivative(i) - u*val2.getDerivative(i) );
+     295             :   }
+     296             :   valout->chainRule( 1/(v*v) ); valout->set( u / v );
+     297             : }
+     298             : 
+     299             : inline
+     300             : void Value::set(double v) {
+     301     5307374 :   value_set=true;
+     302     5526072 :   data[0]=v;
+     303     5483324 :   applyPeriodicity(0);
+     304       62958 : }
+     305             : 
+     306             : inline
+     307        2144 : void Value::add(double v) {
+     308        2144 :   value_set=true;
+     309        2144 :   data[0]+=v;
+     310        2144 :   applyPeriodicity(0);
+     311        2144 : }
+     312             : 
+     313             : inline
+     314    46450631 : void Value::add(const std::size_t& n, const double& v ) {
+     315    46450631 :   value_set=true; data[n]+=v; applyPeriodicity(n);
+     316    46450631 : }
+     317             : 
+     318             : inline
+     319             : bool Value::valueHasBeenSet() const {
+     320   312152540 :   return value_set;
+     321             : }
+     322             : 
+     323             : inline
+     324             : const std::string& Value::getName()const {
+     325     4992890 :   return name;
+     326             : }
+     327             : 
+     328             : inline
+     329    16215891 : unsigned Value::getNumberOfDerivatives() const {
+     330    16215891 :   plumed_massert(hasDeriv,"the derivatives array for this value has zero size");
+     331    16215891 :   if( shape.size()>0 ) return shape.size();
+     332    16215891 :   return data.size() - 1;
+     333             : }
+     334             : 
+     335             : inline
+     336             : double Value::getDerivative(const unsigned n) const {
+     337             :   plumed_dbg_massert(n<getNumberOfDerivatives(),"you are asking for a derivative that is out of bounds");
+     338    18937536 :   return data[1+n];
+     339             : }
+     340             : 
+     341             : inline
+     342             : bool Value::hasDerivatives() const {
+     343   240123206 :   return hasDeriv;
+     344             : }
+     345             : 
+     346             : inline
+     347     4445221 : void Value::resizeDerivatives(int n) {
+     348     4445221 :   if( shape.size()>0 ) return;
+     349     3550720 :   if(hasDeriv) data.resize(1+n);
+     350             : }
+     351             : 
+     352             : inline
+     353             : void Value::addDerivative(unsigned i,double d) {
+     354             :   plumed_dbg_massert(i<getNumberOfDerivatives(),"derivative is out of bounds");
+     355    20049513 :   data[1+i]+=d;
+     356             : }
+     357             : 
+     358             : inline
+     359             : void Value::setDerivative(unsigned i, double d) {
+     360             :   plumed_dbg_massert(i<getNumberOfDerivatives(),"derivative is out of bounds");
+     361    17571418 :   data[1+i]=d;
+     362             : }
+     363             : 
+     364             : inline
+     365             : void Value::chainRule(double df) {
+     366             :   for(unsigned i=0; i<getNumberOfDerivatives(); ++i) data[1+i]*=df;
+     367             : }
+     368             : 
+     369             : inline
+     370             : void Value::clearInputForce() {
+     371     3245757 :   if( !hasForce ) return;
+     372      545881 :   hasForce=false; std::fill(inputForce.begin(),inputForce.end(),0);
+     373             : }
+     374             : 
+     375             : inline
+     376      115450 : void Value::clearInputForce( const std::vector<AtomNumber>& index ) {
+     377      115450 :   if( !hasForce ) return;
+     378     1982754 :   hasForce=false; for(const auto & p : index) inputForce[p.index()]=0;
+     379             : }
+     380             : 
+     381             : inline
+     382     2801776 : void Value::clearDerivatives( const bool force ) {
+     383     2801776 :   if( !force && (valtype==constant || valtype==average) ) return;
+     384             : 
+     385     2781673 :   value_set=false;
+     386     2781673 :   if( data.size()>1 ) std::fill(data.begin()+1, data.end(), 0);
+     387             : }
+     388             : 
+     389             : inline
+     390             : void Value::addForce(double f) {
+     391      177397 :   hasForce=true;
+     392      177397 :   inputForce[0]+=f;
+     393        2623 : }
+     394             : 
+     395             : inline
+     396             : bool Value::forcesWereAdded() const {
+     397    19662922 :   return hasForce;
+     398             : }
+     399             : 
+     400             : inline
+     401             : double Value::getForce( const std::size_t& ival ) const {
+     402             :   plumed_dbg_assert( ival<inputForce.size() );
+     403    24534365 :   return inputForce[ival];
+     404             : }
+     405             : 
+     406             : /// d2-d1
+     407             : inline
+     408   135676778 : double Value::difference(double d1,double d2)const {
+     409   135676778 :   if(periodicity==notperiodic) {
+     410    33850549 :     return d2-d1;
+     411   101826229 :   } else if(periodicity==periodic) {
+     412   101826229 :     double s=(d2-d1)*inv_max_minus_min;
+     413             :     // remember: pbc brings the difference in a range of -0.5:0.5
+     414   101826229 :     s=Tools::pbc(s);
+     415   101826229 :     return s*max_minus_min;
+     416           0 :   } else plumed_merror("periodicity should be set to compute differences");
+     417             : }
+     418             : 
+     419             : inline
+     420        3173 : double Value::bringBackInPbc(double d1)const {
+     421        3173 :   return min+max_minus_min/2.+difference(min+max_minus_min/2., d1);
+     422             : }
+     423             : 
+     424             : inline
+     425     3989526 : double Value::difference(double d)const {
+     426     3989526 :   return difference(get(),d);
+     427             : }
+     428             : 
+     429             : inline
+     430             : double Value::getMaxMinusMin()const {
+     431             :   plumed_dbg_assert( periodicity==periodic );
+     432           0 :   return max_minus_min;
+     433             : }
+     434             : 
+     435             : inline
+     436             : unsigned Value::getRank() const {
+     437   827543198 :   return shape.size();
+     438             : }
+     439             : 
+     440             : inline
+     441             : const std::vector<unsigned>& Value::getShape() const {
+     442      469568 :   return shape;
+     443             : }
+     444             : 
+     445             : inline
+     446    45433116 : unsigned Value::getNumberOfValues() const {
+     447    55209134 :   unsigned size=1; for(unsigned i=0; i<shape.size(); ++i) size *= shape[i];
+     448    45433116 :   return size;
+     449             : }
+     450             : 
+     451             : inline
+     452             : bool Value::isConstant() const {
+     453      393802 :   return valtype==constant;
+     454             : }
+     455             : 
+     456             : inline
+     457             : void Value::setDerivativeIsZeroWhenValueIsZero() {
+     458        1184 :   derivativeIsZeroWhenValueIsZero=true;
+     459          15 : }
+     460             : 
+     461             : inline
+     462             : bool Value::isDerivativeZeroWhenValueIsZero() const {
+     463        1791 :   return derivativeIsZeroWhenValueIsZero;
+     464             : }
+     465             : 
+     466             : inline
+     467             : unsigned Value::getPositionInStream() const {
+     468  1279183384 :   return streampos;
+     469             : }
+     470             : 
+     471             : inline
+     472             : unsigned Value::getPositionInMatrixStash() const {
+     473    28644839 :   return matpos;
+     474             : }
+     475             : 
+     476             : inline
+     477             : void Value::setMatrixBookeepingStart( const unsigned& b ) {
+     478        7787 :   book_start = b;
+     479             : }
+     480             : 
+     481             : inline
+     482             : unsigned Value::getMatrixBookeepingStart() const {
+     483    14157640 :   return book_start;
+     484             : }
+     485             : 
+     486             : inline
+     487             : void Value::setMatrixBookeepingElement( const unsigned& i, const unsigned& n ) {
+     488             :   plumed_dbg_assert( i<matrix_bookeeping.size() );
+     489     5060232 :   matrix_bookeeping[i]=n;
+     490             : }
+     491             : 
+     492             : inline
+     493             : bool Value::valueIsStored() const {
+     494   108799882 :   return storedata;
+     495             : }
+     496             : 
+     497             : inline
+     498             : unsigned Value::getRowLength( const unsigned& irow ) const {
+     499             :   plumed_dbg_assert( (1+ncols)*irow<matrix_bookeeping.size() );
+     500    28741293 :   return matrix_bookeeping[(1+ncols)*irow];
+     501             : }
+     502             : 
+     503             : inline
+     504             : unsigned Value::getRowIndex( const unsigned& irow, const unsigned& jind ) const {
+     505             :   plumed_dbg_assert( (1+ncols)*irow+1+jind<matrix_bookeeping.size() && jind<matrix_bookeeping[(1+ncols)*irow] );
+     506    46965680 :   return matrix_bookeeping[(1+ncols)*irow+1+jind];
+     507             : }
+     508             : 
+     509             : inline
+     510             : unsigned Value::getNumberOfColumns() const {
+     511    14400017 :   return ncols;
+     512             : }
+     513             : 
+     514             : inline
+     515             : bool Value::isSymmetric() const {
+     516        1447 :   return symmetric;
+     517             : }
+     518             : 
+     519             : inline
+     520             : unsigned Value::getNumberOfGridDerivatives() const {
+     521     1911185 :   return ngrid_der;
+     522             : }
+     523             : 
+     524             : inline
+     525             : double Value::getGridDerivative(const unsigned& n, const unsigned& j ) const {
+     526             :   plumed_dbg_assert( hasDeriv && n*(1+ngrid_der) + 1 + j < data.size() );
+     527     8329578 :   return data[n*(1+ngrid_der) + 1 + j];
+     528             : }
+     529             : 
+     530             : inline
+     531     1089247 : void Value::addGridDerivatives( const unsigned& n, const unsigned& j, const double& val ) {
+     532             :   plumed_dbg_assert( hasDeriv && n*(1+ngrid_der) + 1 + j < data.size() );
+     533     1089247 :   data[n*(1+ngrid_der) + 1 + j] += val;
+     534     1089247 : }
+     535             : 
+     536             : inline
+     537             : void Value::setGridDerivatives( const unsigned& n, const unsigned& j, const double& val ) {
+     538             :   plumed_dbg_assert( hasDeriv && n*(1+ngrid_der) + 1 + j < data.size() );
+     539       48400 :   data[n*(1+ngrid_der) + 1 + j] = val;
+     540             : }
+     541             : 
+     542             : }
+     543             : #endif
+     544             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/WithCmd.h.func-sort-c.html b/coverage/core/WithCmd.h.func-sort-c.html new file mode 100644 index 000000000000..dfea34ecc7d2 --- /dev/null +++ b/coverage/core/WithCmd.h.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - core/WithCmd.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - WithCmd.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:91464.3 %
Date:2024-04-19 12:12:35Functions:3650.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7WithCmd3cmdESt17basic_string_viewIcSt11char_traitsIcEERKNS_11TypesafePtrE0
_ZN4PLMD7WithCmdD0Ev0
_ZN4PLMD7WithCmdD2Ev0
_ZN4PLMD7WithCmd3cmdERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_11TypesafePtrE315
_ZN4PLMD7WithCmd3cmdESt17basic_string_viewIcSt11char_traitsIcEERKNS_11TypesafePtrEmPKm386246
_ZN4PLMD7WithCmd3cmdEPKcRKNS_11TypesafePtrE956843
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/WithCmd.h.func.html b/coverage/core/WithCmd.h.func.html new file mode 100644 index 000000000000..97687693911e --- /dev/null +++ b/coverage/core/WithCmd.h.func.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - core/WithCmd.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - WithCmd.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:91464.3 %
Date:2024-04-19 12:12:35Functions:3650.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7WithCmd3cmdEPKcRKNS_11TypesafePtrE956843
_ZN4PLMD7WithCmd3cmdERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_11TypesafePtrE315
_ZN4PLMD7WithCmd3cmdESt17basic_string_viewIcSt11char_traitsIcEERKNS_11TypesafePtrE0
_ZN4PLMD7WithCmd3cmdESt17basic_string_viewIcSt11char_traitsIcEERKNS_11TypesafePtrEmPKm386246
_ZN4PLMD7WithCmdD0Ev0
_ZN4PLMD7WithCmdD2Ev0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/WithCmd.h.gcov.html b/coverage/core/WithCmd.h.gcov.html new file mode 100644 index 000000000000..93b432c98a9b --- /dev/null +++ b/coverage/core/WithCmd.h.gcov.html @@ -0,0 +1,144 @@ + + + + + + + + LCOV - plumed test coverage - core/WithCmd.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - WithCmd.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:91464.3 %
Date:2024-04-19 12:12:35Functions:3650.0 %
+
+ + + + + + + + +

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

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Group.h +
0.0%
+
0.0 %0 / 20.0 %0 / 2
ActionAnyorder.h +
33.3%33.3%
+
33.3 %1 / 30.0 %0 / 2
ActionSetup.h +
0.0%
+
0.0 %0 / 30.0 %0 / 2
ActionShortcut.h +
0.0%
+
0.0 %0 / 30.0 %0 / 3
TargetDist.cpp +
0.0%
+
0.0 %0 / 270.0 %0 / 3
ExchangePatterns.cpp +
19.2%19.2%
+
19.2 %5 / 2628.6 %2 / 7
DataPassingObject.cpp +
89.5%89.5%
+
89.5 %68 / 7648.3 %14 / 29
DataPassingTools.h +
100.0%
+
100.0 %1 / 150.0 %1 / 2
ActionToGetData.h +
50.0%50.0%
+
50.0 %1 / 250.0 %1 / 2
WithCmd.h +
64.3%64.3%
+
64.3 %9 / 1450.0 %3 / 6
ActionAnyorder.cpp +
100.0%
+
100.0 %6 / 666.7 %2 / 3
ActionSetup.cpp +
90.9%90.9%
+
90.9 %10 / 1166.7 %2 / 3
CLToolRegister.cpp +
58.1%58.1%
+
58.1 %18 / 3171.4 %5 / 7
ActionForInterface.cpp +
100.0%
+
100.0 %13 / 1375.0 %3 / 4
Group.cpp +
98.4%98.4%
+
98.4 %60 / 6175.0 %3 / 4
DataPassingTools.cpp +
82.6%82.6%
+
82.6 %19 / 2375.0 %6 / 8
ActionRegister.cpp +
71.1%71.1%
+
71.1 %27 / 3875.0 %6 / 8
ActionShortcut.cpp +
86.8%86.8%
+
86.8 %79 / 9180.0 %8 / 10
ActionAtomistic.cpp +
94.3%94.3%
+
94.3 %267 / 28380.8 %21 / 26
ActionPilot.cpp +
93.3%93.3%
+
93.3 %14 / 1583.3 %5 / 6
PbcAction.cpp +
100.0%
+
100.0 %25 / 2583.3 %5 / 6
GenericMolInfo.cpp +
82.6%82.6%
+
82.6 %181 / 21983.3 %15 / 18
Action.cpp +
83.7%83.7%
+
83.7 %169 / 20283.8 %31 / 37
ActionWithValue.cpp +
92.1%92.1%
+
92.1 %151 / 16484.8 %28 / 33
ActionWithValue.h +
95.2%95.2%
+
95.2 %20 / 2185.7 %6 / 7
ActionForInterface.h +
87.5%87.5%
+
87.5 %7 / 885.7 %6 / 7
ActionWithVirtualAtom.cpp +
100.0%
+
100.0 %63 / 6385.7 %6 / 7
ActionToGetData.cpp +
90.3%90.3%
+
90.3 %28 / 3185.7 %6 / 7
ActionWithVector.h +
88.9%88.9%
+
88.9 %8 / 985.7 %6 / 7
Colvar.cpp +
100.0%
+
100.0 %30 / 3085.7 %6 / 7
FlexibleBin.cpp +
78.8%78.8%
+
78.8 %115 / 14685.7 %6 / 7
ActionWithArguments.cpp +
88.8%88.8%
+
88.8 %182 / 20585.7 %12 / 14
RegisterBase.h +
85.3%85.3%
+
85.3 %58 / 6886.4 %19 / 22
CLTool.h +
73.5%73.5%
+
73.5 %25 / 3486.7 %13 / 15
Action.h +
91.7%91.7%
+
91.7 %77 / 8486.8 %33 / 38
ActionSet.h +
100.0%
+
100.0 %18 / 1887.1 %27 / 31
PlumedMainInitializer.cpp +
82.9%82.9%
+
82.9 %223 / 26987.5 %14 / 16
RegisterBase.cpp +
91.3%91.3%
+
91.3 %63 / 6987.5 %14 / 16
CLTool.cpp +
85.9%85.9%
+
85.9 %85 / 9990.0 %9 / 10
PlumedMain.cpp +
89.7%89.7%
+
89.7 %840 / 93690.9 %60 / 66
Value.cpp +
91.5%91.5%
+
91.5 %247 / 27091.7 %33 / 36
ActionWithVector.cpp +
98.6%98.6%
+
98.6 %420 / 42692.6 %50 / 54
DomainDecomposition.cpp +
94.2%94.2%
+
94.2 %261 / 27793.9 %31 / 33
ActionRegister.h +
100.0%
+
100.0 %7 / 798.4 %1133 / 1152
DataPassingObject.h +
100.0%
+
100.0 %4 / 4-0 / 0
ActionPilot.h +
100.0%
+
100.0 %1 / 1-0 / 0
CLToolRegister.h +
100.0%
+
100.0 %2 / 2-0 / 0
PlumedMain.h +
88.9%88.9%
+
88.9 %16 / 18-0 / 0
PbcAction.h +
100.0%
+
100.0 %2 / 2100.0 %1 / 1
GenericMolInfo.h +
100.0%
+
100.0 %2 / 2100.0 %2 / 2
DomainDecomposition.h +
100.0%
+
100.0 %4 / 4100.0 %3 / 3
Colvar.h +
100.0%
+
100.0 %24 / 24100.0 %4 / 4
ActionSet.cpp +
100.0%
+
100.0 %15 / 15100.0 %4 / 4
CLToolMain.cpp +
84.2%84.2%
+
84.2 %112 / 133100.0 %5 / 5
ActionToPutData.h +
100.0%
+
100.0 %6 / 6100.0 %6 / 6
GREX.cpp +
75.2%75.2%
+
75.2 %100 / 133100.0 %6 / 6
ActionWithVirtualAtom.h +
100.0%
+
100.0 %22 / 22100.0 %6 / 6
ActionWithArguments.h +
100.0%
+
100.0 %17 / 17100.0 %7 / 7
ActionAtomistic.h +
100.0%
+
100.0 %46 / 46100.0 %9 / 9
Value.h +
97.6%97.6%
+
97.6 %81 / 83100.0 %12 / 12
ActionToPutData.cpp +
92.3%92.3%
+
92.3 %96 / 104100.0 %17 / 17
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/index-sort-l.html b/coverage/core/index-sort-l.html new file mode 100644 index 000000000000..0e7190e89428 --- /dev/null +++ b/coverage/core/index-sort-l.html @@ -0,0 +1,694 @@ + + + + + + + + LCOV - plumed test coverage - core + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - coreHitTotalCoverage
Test:plumed test coverageLines:4451502588.6 %
Date:2024-04-19 12:12:35Functions:1733186592.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Group.h +
0.0%
+
0.0 %0 / 20.0 %0 / 2
ActionShortcut.h +
0.0%
+
0.0 %0 / 30.0 %0 / 3
ActionSetup.h +
0.0%
+
0.0 %0 / 30.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
ActionToGetData.h +
50.0%50.0%
+
50.0 %1 / 250.0 %1 / 2
CLToolRegister.cpp +
58.1%58.1%
+
58.1 %18 / 3171.4 %5 / 7
WithCmd.h +
64.3%64.3%
+
64.3 %9 / 1450.0 %3 / 6
ActionRegister.cpp +
71.1%71.1%
+
71.1 %27 / 3875.0 %6 / 8
CLTool.h +
73.5%73.5%
+
73.5 %25 / 3486.7 %13 / 15
GREX.cpp +
75.2%75.2%
+
75.2 %100 / 133100.0 %6 / 6
FlexibleBin.cpp +
78.8%78.8%
+
78.8 %115 / 14685.7 %6 / 7
DataPassingTools.cpp +
82.6%82.6%
+
82.6 %19 / 2375.0 %6 / 8
GenericMolInfo.cpp +
82.6%82.6%
+
82.6 %181 / 21983.3 %15 / 18
PlumedMainInitializer.cpp +
82.9%82.9%
+
82.9 %223 / 26987.5 %14 / 16
Action.cpp +
83.7%83.7%
+
83.7 %169 / 20283.8 %31 / 37
CLToolMain.cpp +
84.2%84.2%
+
84.2 %112 / 133100.0 %5 / 5
RegisterBase.h +
85.3%85.3%
+
85.3 %58 / 6886.4 %19 / 22
CLTool.cpp +
85.9%85.9%
+
85.9 %85 / 9990.0 %9 / 10
ActionShortcut.cpp +
86.8%86.8%
+
86.8 %79 / 9180.0 %8 / 10
ActionForInterface.h +
87.5%87.5%
+
87.5 %7 / 885.7 %6 / 7
ActionWithArguments.cpp +
88.8%88.8%
+
88.8 %182 / 20585.7 %12 / 14
ActionWithVector.h +
88.9%88.9%
+
88.9 %8 / 985.7 %6 / 7
PlumedMain.h +
88.9%88.9%
+
88.9 %16 / 18-0 / 0
DataPassingObject.cpp +
89.5%89.5%
+
89.5 %68 / 7648.3 %14 / 29
PlumedMain.cpp +
89.7%89.7%
+
89.7 %840 / 93690.9 %60 / 66
ActionToGetData.cpp +
90.3%90.3%
+
90.3 %28 / 3185.7 %6 / 7
ActionSetup.cpp +
90.9%90.9%
+
90.9 %10 / 1166.7 %2 / 3
RegisterBase.cpp +
91.3%91.3%
+
91.3 %63 / 6987.5 %14 / 16
Value.cpp +
91.5%91.5%
+
91.5 %247 / 27091.7 %33 / 36
Action.h +
91.7%91.7%
+
91.7 %77 / 8486.8 %33 / 38
ActionWithValue.cpp +
92.1%92.1%
+
92.1 %151 / 16484.8 %28 / 33
ActionToPutData.cpp +
92.3%92.3%
+
92.3 %96 / 104100.0 %17 / 17
ActionPilot.cpp +
93.3%93.3%
+
93.3 %14 / 1583.3 %5 / 6
DomainDecomposition.cpp +
94.2%94.2%
+
94.2 %261 / 27793.9 %31 / 33
ActionAtomistic.cpp +
94.3%94.3%
+
94.3 %267 / 28380.8 %21 / 26
ActionWithValue.h +
95.2%95.2%
+
95.2 %20 / 2185.7 %6 / 7
Value.h +
97.6%97.6%
+
97.6 %81 / 83100.0 %12 / 12
Group.cpp +
98.4%98.4%
+
98.4 %60 / 6175.0 %3 / 4
ActionWithVector.cpp +
98.6%98.6%
+
98.6 %420 / 42692.6 %50 / 54
DataPassingTools.h +
100.0%
+
100.0 %1 / 150.0 %1 / 2
ActionPilot.h +
100.0%
+
100.0 %1 / 1-0 / 0
PbcAction.h +
100.0%
+
100.0 %2 / 2100.0 %1 / 1
CLToolRegister.h +
100.0%
+
100.0 %2 / 2-0 / 0
GenericMolInfo.h +
100.0%
+
100.0 %2 / 2100.0 %2 / 2
DomainDecomposition.h +
100.0%
+
100.0 %4 / 4100.0 %3 / 3
DataPassingObject.h +
100.0%
+
100.0 %4 / 4-0 / 0
ActionToPutData.h +
100.0%
+
100.0 %6 / 6100.0 %6 / 6
ActionAnyorder.cpp +
100.0%
+
100.0 %6 / 666.7 %2 / 3
ActionRegister.h +
100.0%
+
100.0 %7 / 798.4 %1133 / 1152
ActionForInterface.cpp +
100.0%
+
100.0 %13 / 1375.0 %3 / 4
ActionSet.cpp +
100.0%
+
100.0 %15 / 15100.0 %4 / 4
ActionWithArguments.h +
100.0%
+
100.0 %17 / 17100.0 %7 / 7
ActionSet.h +
100.0%
+
100.0 %18 / 1887.1 %27 / 31
ActionWithVirtualAtom.h +
100.0%
+
100.0 %22 / 22100.0 %6 / 6
Colvar.h +
100.0%
+
100.0 %24 / 24100.0 %4 / 4
PbcAction.cpp +
100.0%
+
100.0 %25 / 2583.3 %5 / 6
Colvar.cpp +
100.0%
+
100.0 %30 / 3085.7 %6 / 7
ActionAtomistic.h +
100.0%
+
100.0 %46 / 46100.0 %9 / 9
ActionWithVirtualAtom.cpp +
100.0%
+
100.0 %63 / 6385.7 %6 / 7
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/index.html b/coverage/core/index.html new file mode 100644 index 000000000000..55a25b017778 --- /dev/null +++ b/coverage/core/index.html @@ -0,0 +1,694 @@ + + + + + + + + LCOV - plumed test coverage - core + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - coreHitTotalCoverage
Test:plumed test coverageLines:4451502588.6 %
Date:2024-04-19 12:12:35Functions:1733186592.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Action.cpp +
83.7%83.7%
+
83.7 %169 / 20283.8 %31 / 37
Action.h +
91.7%91.7%
+
91.7 %77 / 8486.8 %33 / 38
ActionAnyorder.cpp +
100.0%
+
100.0 %6 / 666.7 %2 / 3
ActionAnyorder.h +
33.3%33.3%
+
33.3 %1 / 30.0 %0 / 2
ActionAtomistic.cpp +
94.3%94.3%
+
94.3 %267 / 28380.8 %21 / 26
ActionAtomistic.h +
100.0%
+
100.0 %46 / 46100.0 %9 / 9
ActionForInterface.cpp +
100.0%
+
100.0 %13 / 1375.0 %3 / 4
ActionForInterface.h +
87.5%87.5%
+
87.5 %7 / 885.7 %6 / 7
ActionPilot.cpp +
93.3%93.3%
+
93.3 %14 / 1583.3 %5 / 6
ActionPilot.h +
100.0%
+
100.0 %1 / 1-0 / 0
ActionRegister.cpp +
71.1%71.1%
+
71.1 %27 / 3875.0 %6 / 8
ActionRegister.h +
100.0%
+
100.0 %7 / 798.4 %1133 / 1152
ActionSet.cpp +
100.0%
+
100.0 %15 / 15100.0 %4 / 4
ActionSet.h +
100.0%
+
100.0 %18 / 1887.1 %27 / 31
ActionSetup.cpp +
90.9%90.9%
+
90.9 %10 / 1166.7 %2 / 3
ActionSetup.h +
0.0%
+
0.0 %0 / 30.0 %0 / 2
ActionShortcut.cpp +
86.8%86.8%
+
86.8 %79 / 9180.0 %8 / 10
ActionShortcut.h +
0.0%
+
0.0 %0 / 30.0 %0 / 3
ActionToGetData.cpp +
90.3%90.3%
+
90.3 %28 / 3185.7 %6 / 7
ActionToGetData.h +
50.0%50.0%
+
50.0 %1 / 250.0 %1 / 2
ActionToPutData.cpp +
92.3%92.3%
+
92.3 %96 / 104100.0 %17 / 17
ActionToPutData.h +
100.0%
+
100.0 %6 / 6100.0 %6 / 6
ActionWithArguments.cpp +
88.8%88.8%
+
88.8 %182 / 20585.7 %12 / 14
ActionWithArguments.h +
100.0%
+
100.0 %17 / 17100.0 %7 / 7
ActionWithValue.cpp +
92.1%92.1%
+
92.1 %151 / 16484.8 %28 / 33
ActionWithValue.h +
95.2%95.2%
+
95.2 %20 / 2185.7 %6 / 7
ActionWithVector.cpp +
98.6%98.6%
+
98.6 %420 / 42692.6 %50 / 54
ActionWithVector.h +
88.9%88.9%
+
88.9 %8 / 985.7 %6 / 7
ActionWithVirtualAtom.cpp +
100.0%
+
100.0 %63 / 6385.7 %6 / 7
ActionWithVirtualAtom.h +
100.0%
+
100.0 %22 / 22100.0 %6 / 6
CLTool.cpp +
85.9%85.9%
+
85.9 %85 / 9990.0 %9 / 10
CLTool.h +
73.5%73.5%
+
73.5 %25 / 3486.7 %13 / 15
CLToolMain.cpp +
84.2%84.2%
+
84.2 %112 / 133100.0 %5 / 5
CLToolRegister.cpp +
58.1%58.1%
+
58.1 %18 / 3171.4 %5 / 7
CLToolRegister.h +
100.0%
+
100.0 %2 / 2-0 / 0
Colvar.cpp +
100.0%
+
100.0 %30 / 3085.7 %6 / 7
Colvar.h +
100.0%
+
100.0 %24 / 24100.0 %4 / 4
DataPassingObject.cpp +
89.5%89.5%
+
89.5 %68 / 7648.3 %14 / 29
DataPassingObject.h +
100.0%
+
100.0 %4 / 4-0 / 0
DataPassingTools.cpp +
82.6%82.6%
+
82.6 %19 / 2375.0 %6 / 8
DataPassingTools.h +
100.0%
+
100.0 %1 / 150.0 %1 / 2
DomainDecomposition.cpp +
94.2%94.2%
+
94.2 %261 / 27793.9 %31 / 33
DomainDecomposition.h +
100.0%
+
100.0 %4 / 4100.0 %3 / 3
ExchangePatterns.cpp +
19.2%19.2%
+
19.2 %5 / 2628.6 %2 / 7
FlexibleBin.cpp +
78.8%78.8%
+
78.8 %115 / 14685.7 %6 / 7
GREX.cpp +
75.2%75.2%
+
75.2 %100 / 133100.0 %6 / 6
GenericMolInfo.cpp +
82.6%82.6%
+
82.6 %181 / 21983.3 %15 / 18
GenericMolInfo.h +
100.0%
+
100.0 %2 / 2100.0 %2 / 2
Group.cpp +
98.4%98.4%
+
98.4 %60 / 6175.0 %3 / 4
Group.h +
0.0%
+
0.0 %0 / 20.0 %0 / 2
PbcAction.cpp +
100.0%
+
100.0 %25 / 2583.3 %5 / 6
PbcAction.h +
100.0%
+
100.0 %2 / 2100.0 %1 / 1
PlumedMain.cpp +
89.7%89.7%
+
89.7 %840 / 93690.9 %60 / 66
PlumedMain.h +
88.9%88.9%
+
88.9 %16 / 18-0 / 0
PlumedMainInitializer.cpp +
82.9%82.9%
+
82.9 %223 / 26987.5 %14 / 16
RegisterBase.cpp +
91.3%91.3%
+
91.3 %63 / 6987.5 %14 / 16
RegisterBase.h +
85.3%85.3%
+
85.3 %58 / 6886.4 %19 / 22
TargetDist.cpp +
0.0%
+
0.0 %0 / 270.0 %0 / 3
Value.cpp +
91.5%91.5%
+
91.5 %247 / 27091.7 %33 / 36
Value.h +
97.6%97.6%
+
97.6 %81 / 83100.0 %12 / 12
WithCmd.h +
64.3%64.3%
+
64.3 %9 / 1450.0 %3 / 6
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystdistrib/BopsShortcut.cpp.func-sort-c.html b/coverage/crystdistrib/BopsShortcut.cpp.func-sort-c.html new file mode 100644 index 000000000000..47d1ce3eaf93 --- /dev/null +++ b/coverage/crystdistrib/BopsShortcut.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - crystdistrib/BopsShortcut.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystdistrib - BopsShortcut.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:505394.3 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12crystdistrib12BopsShortcutC2ERKNS_13ActionOptionsE0
_ZN4PLMD12crystdistrib12BopsShortcutC1ERKNS_13ActionOptionsE1
_ZN4PLMD12crystdistrib12BopsShortcut16registerKeywordsERNS_8KeywordsE3
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystdistrib/BopsShortcut.cpp.func.html b/coverage/crystdistrib/BopsShortcut.cpp.func.html new file mode 100644 index 000000000000..ae1b442e6b77 --- /dev/null +++ b/coverage/crystdistrib/BopsShortcut.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - crystdistrib/BopsShortcut.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystdistrib - BopsShortcut.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:505394.3 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12crystdistrib12BopsShortcut16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD12crystdistrib12BopsShortcutC1ERKNS_13ActionOptionsE1
_ZN4PLMD12crystdistrib12BopsShortcutC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystdistrib/BopsShortcut.cpp.gcov.html b/coverage/crystdistrib/BopsShortcut.cpp.gcov.html new file mode 100644 index 000000000000..3b287111e2eb --- /dev/null +++ b/coverage/crystdistrib/BopsShortcut.cpp.gcov.html @@ -0,0 +1,233 @@ + + + + + + + + LCOV - plumed test coverage - crystdistrib/BopsShortcut.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystdistrib - BopsShortcut.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:505394.3 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) crystdistrib 2023-2023 The code team
+       3             :    (see the PEOPLE-crystdistrib file at the root of this folder for a list of names)
+       4             : 
+       5             :    This file is part of crystdistrib code module.
+       6             : 
+       7             :    The crystdistrib code module is free software: you can redistribute it and/or modify
+       8             :    it under the terms of the GNU Lesser General Public License as published by
+       9             :    the Free Software Foundation, either version 3 of the License, or
+      10             :    (at your option) any later version.
+      11             : 
+      12             :    The crystdistrib code module is distributed in the hope that it will be useful,
+      13             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      14             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      15             :    GNU Lesser General Public License for more details.
+      16             : 
+      17             :    You should have received a copy of the GNU Lesser General Public License
+      18             :    along with the crystdistrib code module.  If not, see <http://www.gnu.org/licenses/>.
+      19             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      20             : #include "core/ActionShortcut.h"
+      21             : #include "core/ActionRegister.h"
+      22             : #include "core/PlumedMain.h"
+      23             : #include "core/ActionSet.h"
+      24             : #include "core/ActionWithValue.h"
+      25             : #include "tools/IFile.h"
+      26             : 
+      27             : namespace PLMD {
+      28             : namespace crystdistrib {
+      29             : 
+      30             : //+PLUMEDOC COLVAR BOPS
+      31             : /*
+      32             : Calculate the BOPS order parameter
+      33             : 
+      34             : \par Examples
+      35             : 
+      36             : */
+      37             : //+ENDPLUMEDOC
+      38             : 
+      39             : class BopsShortcut : public ActionShortcut {
+      40             : public:
+      41             :   static void registerKeywords( Keywords& keys );
+      42             :   explicit BopsShortcut(const ActionOptions&);
+      43             : };
+      44             : 
+      45             : PLUMED_REGISTER_ACTION(BopsShortcut,"BOPS")
+      46             : 
+      47           3 : void BopsShortcut::registerKeywords( Keywords& keys ) {
+      48           3 :   ActionShortcut::registerKeywords( keys );
+      49           6 :   keys.add("atoms","SPECIES","this keyword is used for colvars such as coordination number. In that context it specifies that plumed should calculate "
+      50             :            "one coordination number for each of the atoms specified.  Each of these coordination numbers specifies how many of the "
+      51             :            "other specified atoms are within a certain cutoff of the central atom.  You can specify the atoms here as another multicolvar "
+      52             :            "action or using a MultiColvarFilter or ActionVolume action.  When you do so the quantity is calculated for those atoms specified "
+      53             :            "in the previous multicolvar.  This is useful if you would like to calculate the Steinhardt parameter for those atoms that have a "
+      54             :            "coordination number more than four for example");
+      55           6 :   keys.add("atoms-2","SPECIESA","this keyword is used for colvars such as the coordination number.  In that context it species that plumed should calculate "
+      56             :            "one coordination number for each of the atoms specified in SPECIESA.  Each of these cooordination numbers specifies how many "
+      57             :            "of the atoms specifies using SPECIESB is within the specified cutoff.  As with the species keyword the input can also be specified "
+      58             :            "using the label of another multicolvar");
+      59           6 :   keys.add("atoms-2","SPECIESB","this keyword is used for colvars such as the coordination number.  It must appear with SPECIESA.  For a full explanation see "
+      60             :            "the documentation for that keyword");
+      61           6 :   keys.add("compulsory","QUATERNIONS","the label of the action that computes the quaternions that should be used");
+      62           6 :   keys.add("compulsory","KERNELFILE_DOPS","the file containing the list of kernel parameters.  We expect h, mu and sigma parameters for a 1D Gaussian kernel of the form h*exp(-(x-mu)^2/2sigma^2)");
+      63           6 :   keys.add("compulsory","KERNELFILE_BOPS","the second file containing the list of kernel parameters. Expecting a normalization factor (height), concentration parameter (kappa), and 3 norm vector pieces of the mean (mu_i, mu_j, mu_k )for a fisher distribution. of the form h*exp(kappa*dot(r_mean,r)), where dot is a standard dot product.");
+      64           6 :   keys.add("compulsory", "CUTOFF", "cutoff for the distance matrix");
+      65             : //  keys.add("compulsory","SWITCH","the switching function that acts on the distances between points)");
+      66           9 :   keys.needsAction("DISTANCE_MATRIX"); keys.needsAction("QUATERNION_BOND_PRODUCT_MATRIX"); keys.needsAction("CUSTOM");
+      67           6 :   keys.needsAction("ONES"); keys.needsAction("MATRIX_VECTOR_PRODUCT");
+      68           3 : }
+      69             : 
+      70           1 : BopsShortcut::BopsShortcut(const ActionOptions&ao):
+      71             :   Action(ao),
+      72           1 :   ActionShortcut(ao)
+      73             : {
+      74             :   // Open a file and read in the kernels
+      75             :   double h_dops,h_bops; std::string kfunc, kfunc_dops,kfunc_bops,fname_dops,fname_bops;
+      76           3 :   parse("KERNELFILE_DOPS",fname_dops); parse("KERNELFILE_BOPS",fname_bops); IFile ifile_dops, ifile_bops; ifile_dops.open(fname_dops); ifile_bops.open(fname_bops);
+      77          10 :   for(unsigned k=0;; ++k) {
+      78          21 :     if( !ifile_dops.scanField("height",h_dops) || !ifile_bops.scanField("height",h_bops) ) break;//checks eof
+      79          30 :     std::string ktype_dops, ktype_bops;  ifile_dops.scanField("kerneltype",ktype_dops); ifile_bops.scanField("kerneltype",ktype_bops);
+      80          10 :     if( ktype_dops!="gaussian" ) error("cannot process kernels of type " + ktype_dops );//straightup error
+      81          10 :     if( ktype_bops!="gaussian" ) error("cannot process kernels of type " + ktype_bops );
+      82             : 
+      83             :     double mu_dops, mu_i, mu_j, mu_k; std::string hstr_dops, hstr_bops, smu_dops,smu_i, smu_j, smu_k, sigmastr,kappastr;
+      84             : 
+      85             : 
+      86          10 :     Tools::convert( h_dops, hstr_dops );
+      87          10 :     Tools::convert( h_bops, hstr_bops );
+      88             : 
+      89          20 :     ifile_dops.scanField("mu",mu_dops); Tools::convert( mu_dops, smu_dops );
+      90             :     //ifile_bops.scanField("mu_w",mu_w); Tools::convert( mu_w, smu_w );
+      91          20 :     ifile_bops.scanField("mu_i",mu_i); Tools::convert( mu_i, smu_i );
+      92          20 :     ifile_bops.scanField("mu_j",mu_j); Tools::convert( mu_j, smu_j );
+      93          20 :     ifile_bops.scanField("mu_k",mu_k); Tools::convert( mu_k, smu_k );
+      94             : 
+      95             : 
+      96             :     double sigma,kappa;
+      97          20 :     ifile_dops.scanField("sigma",sigma); Tools::convert( sigma, sigmastr );
+      98          20 :     ifile_bops.scanField("kappa",kappa); Tools::convert( kappa, kappastr );
+      99             : 
+     100             : 
+     101             : 
+     102          10 :     ifile_dops.scanField(); /*if( k==0 )*/ kfunc_dops =  hstr_dops; //else kfunc_dops += "+" + hstr;
+     103          10 :     ifile_bops.scanField(); /*if( k==0 )*/ kfunc_bops =  hstr_bops; //else kfunc_bops += "+" + hstr;
+     104             : 
+     105          20 :     kfunc_bops += "*exp(" + kappastr + "*(i*" + smu_i + "+j*" + smu_j + "+k*" + smu_k + "))";
+     106          20 :     kfunc_dops += "*exp(-(x-" + smu_dops +")^2/" + "(2*" + sigmastr +"*" +sigmastr + "))";
+     107          20 :     if (k==0) kfunc = kfunc_dops + "*" + kfunc_bops; else kfunc+= "+" + kfunc_dops + "*" + kfunc_bops;
+     108          10 :   }
+     109             :   std::string sp_str, specA, specB, grpinfo;
+     110             :   double cutoff;
+     111           5 :   parse("SPECIES",sp_str); parse("SPECIESA",specA); parse("SPECIESB",specB); parse("CUTOFF",cutoff);
+     112           1 :   if( sp_str.length()>0 ) {
+     113           2 :     grpinfo="GROUP=" + sp_str;
+     114             :   } else {//not sure how to use this
+     115           0 :     if( specA.length()==0 || specB.length()==0 ) error("no atoms were specified in input use either SPECIES or SPECIESA + SPECIESB");
+     116           0 :     grpinfo="GROUPA=" + specA + " GROUPB=" + specB;
+     117             :   }
+     118           1 :   std::string cutstr; Tools::convert( cutoff, cutstr );
+     119             :   // Setup the contact matrix
+     120             : //  std::string switchstr; parse("SWITCH",switchstr);
+     121           2 :   readInputLine( getShortcutLabel() + "_cmat: DISTANCE_MATRIX  " + grpinfo + " CUTOFF=" + cutstr + " COMPONENTS");
+     122             : 
+     123           1 :   if( specA.length()==0 ) {
+     124           1 :     std::string quatstr; parse("QUATERNIONS",quatstr);
+     125           2 :     readInputLine( getShortcutLabel() + "_quatprod: QUATERNION_BOND_PRODUCT_MATRIX ARG=" + quatstr + ".*," + getShortcutLabel() + "_cmat.*" );
+     126             :   }  else {
+     127           0 :     plumed_error();
+     128             :   }
+     129             :   //
+     130             : 
+     131             :   ///////////////////
+     132             :   ///replace/////
+     133           2 :   readInputLine( getShortcutLabel() + "_dist: CUSTOM ARG=" + getShortcutLabel() + "_cmat.x," + getShortcutLabel() + "_cmat.y," + getShortcutLabel() + "_cmat.z " +
+     134             :                  "FUNC=sqrt((x^2)+(y^2)+(z^2)) PERIODIC=NO");
+     135           2 :   readInputLine( getShortcutLabel() + "_kfunc: CUSTOM ARG=" + getShortcutLabel() + "_quatprod.i," + getShortcutLabel() + "_quatprod.j," + getShortcutLabel() + "_quatprod.k,"+ getShortcutLabel() + "_dist " + "VAR=i,j,k,x FUNC=" + kfunc + " PERIODIC=NO");
+     136             : 
+     137             : //replace ^^^ to remove distance hack
+     138             : //readInputLine( getShortcutLabel() + "_kfunc: CUSTOM ARG=" + getShortcutLabel() + "_quatprod.i," + getShortcutLabel() + "_quatprod.j," + getShortcutLabel() + "_quatprod.k,"+ getShortcutLabel() + "_cmat.w " + "VAR=i,j,k,x FUNC=" + kfunc + " PERIODIC=NO");
+     139             : ///end replace////
+     140             : 
+     141             :   // Element wise product of cmat and kfunc
+     142             : //  readInputLine( getShortcutLabel() + "_kdmat: CUSTOM ARG=" + getShortcutLabel() + "_cmat.w," + getShortcutLabel() + "_kfunc FUNC=x*y PERIODIC=NO");
+     143             :   // Find the number of ones we need to multiply by
+     144           1 :   ActionWithValue* av = plumed.getActionSet().selectWithLabel<ActionWithValue*>( getShortcutLabel() + "_cmat");
+     145           1 :   plumed_assert( av && av->getNumberOfComponents()>0 && (av->copyOutput(0))->getRank()==2 );
+     146           1 :   std::string size; Tools::convert( (av->copyOutput(0))->getShape()[1], size );
+     147           2 :   readInputLine( getShortcutLabel() + "_ones: ONES SIZE=" + size );
+     148             :   //
+     149           2 :   readInputLine( getShortcutLabel() + ": MATRIX_VECTOR_PRODUCT ARG=" + getShortcutLabel() + "_kfunc," + getShortcutLabel() + "_ones");
+     150           2 : }
+     151             : 
+     152             : }
+     153             : }
+     154             : 
+     155             : 
+     156             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystdistrib/DopsShortcut.cpp.func-sort-c.html b/coverage/crystdistrib/DopsShortcut.cpp.func-sort-c.html new file mode 100644 index 000000000000..76429563120e --- /dev/null +++ b/coverage/crystdistrib/DopsShortcut.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - crystdistrib/DopsShortcut.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystdistrib - DopsShortcut.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:363894.7 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12crystdistrib12DopsShortcutC2ERKNS_13ActionOptionsE0
_ZN4PLMD12crystdistrib12DopsShortcutC1ERKNS_13ActionOptionsE2
_ZN4PLMD12crystdistrib12DopsShortcut16registerKeywordsERNS_8KeywordsE4
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystdistrib/DopsShortcut.cpp.func.html b/coverage/crystdistrib/DopsShortcut.cpp.func.html new file mode 100644 index 000000000000..fcaf5f5641e7 --- /dev/null +++ b/coverage/crystdistrib/DopsShortcut.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - crystdistrib/DopsShortcut.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystdistrib - DopsShortcut.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:363894.7 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12crystdistrib12DopsShortcut16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD12crystdistrib12DopsShortcutC1ERKNS_13ActionOptionsE2
_ZN4PLMD12crystdistrib12DopsShortcutC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystdistrib/DopsShortcut.cpp.gcov.html b/coverage/crystdistrib/DopsShortcut.cpp.gcov.html new file mode 100644 index 000000000000..9fc57f2b3be0 --- /dev/null +++ b/coverage/crystdistrib/DopsShortcut.cpp.gcov.html @@ -0,0 +1,189 @@ + + + + + + + + LCOV - plumed test coverage - crystdistrib/DopsShortcut.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystdistrib - DopsShortcut.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:363894.7 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) crystdistrib 2023-2023 The code team
+       3             :    (see the PEOPLE-crystdistrib file at the root of this folder for a list of names)
+       4             : 
+       5             :    This file is part of crystdistrib code module.
+       6             : 
+       7             :    The crystdistrib code module is free software: you can redistribute it and/or modify
+       8             :    it under the terms of the GNU Lesser General Public License as published by
+       9             :    the Free Software Foundation, either version 3 of the License, or
+      10             :    (at your option) any later version.
+      11             : 
+      12             :    The crystdistrib code module is distributed in the hope that it will be useful,
+      13             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      14             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      15             :    GNU Lesser General Public License for more details.
+      16             : 
+      17             :    You should have received a copy of the GNU Lesser General Public License
+      18             :    along with the crystdistrib code module.  If not, see <http://www.gnu.org/licenses/>.
+      19             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      20             : #include "core/ActionShortcut.h"
+      21             : #include "core/ActionRegister.h"
+      22             : #include "core/PlumedMain.h"
+      23             : #include "core/ActionSet.h"
+      24             : #include "core/ActionWithValue.h"
+      25             : #include "tools/IFile.h"
+      26             : 
+      27             : namespace PLMD {
+      28             : namespace crystdistrib {
+      29             : 
+      30             : //+PLUMEDOC COLVAR DOPS
+      31             : /*
+      32             : Calculate the DOPS order parameter
+      33             : 
+      34             : \par Examples
+      35             : 
+      36             : */
+      37             : //+ENDPLUMEDOC
+      38             : 
+      39             : class DopsShortcut : public ActionShortcut {
+      40             : public:
+      41             :   static void registerKeywords( Keywords& keys );
+      42             :   explicit DopsShortcut(const ActionOptions&);
+      43             : };
+      44             : 
+      45             : PLUMED_REGISTER_ACTION(DopsShortcut,"DOPS")
+      46             : 
+      47           4 : void DopsShortcut::registerKeywords( Keywords& keys ) {
+      48           4 :   ActionShortcut::registerKeywords( keys );
+      49           8 :   keys.add("atoms","SPECIES","this keyword is used for colvars such as coordination number. In that context it specifies that plumed should calculate "
+      50             :            "one coordination number for each of the atoms specified.  Each of these coordination numbers specifies how many of the "
+      51             :            "other specified atoms are within a certain cutoff of the central atom.  You can specify the atoms here as another multicolvar "
+      52             :            "action or using a MultiColvarFilter or ActionVolume action.  When you do so the quantity is calculated for those atoms specified "
+      53             :            "in the previous multicolvar.  This is useful if you would like to calculate the Steinhardt parameter for those atoms that have a "
+      54             :            "coordination number more than four for example");
+      55           8 :   keys.add("atoms-2","SPECIESA","this keyword is used for colvars such as the coordination number.  In that context it species that plumed should calculate "
+      56             :            "one coordination number for each of the atoms specified in SPECIESA.  Each of these cooordination numbers specifies how many "
+      57             :            "of the atoms specifies using SPECIESB is within the specified cutoff.  As with the species keyword the input can also be specified "
+      58             :            "using the label of another multicolvar");
+      59           8 :   keys.add("atoms-2","SPECIESB","this keyword is used for colvars such as the coordination number.  It must appear with SPECIESA.  For a full explanation see "
+      60             :            "the documentation for that keyword");
+      61           8 :   keys.add("compulsory","KERNELFILE","the file containing the list of kernel parameters.  We expect h, mu and sigma parameters for a 1D Gaussian kernel of the form h*exp(-(x-mu)^2/2sigma^2)");
+      62           8 :   keys.add("compulsory","CUTOFF","6.25","to make the calculation faster we calculate a cutoff value on the distances.  The input to this keyword determines x in this expreession max(mu + sqrt(2*x)/sigma)");
+      63          16 :   keys.needsAction("DISTANCE_MATRIX"); keys.needsAction("CUSTOM"); keys.needsAction("ONES"); keys.needsAction("MATRIX_VECTOR_PRODUCT");
+      64           4 : }
+      65             : 
+      66           2 : DopsShortcut::DopsShortcut(const ActionOptions&ao):
+      67             :   Action(ao),
+      68           2 :   ActionShortcut(ao)
+      69             : {
+      70             :   // Open a file and read in the kernels
+      71           2 :   double cutoff=0, h; std::string kfunc,fname; double dp2cutoff; parse("CUTOFF",dp2cutoff);
+      72           4 :   parse("KERNELFILE",fname); IFile ifile; ifile.open(fname);
+      73          20 :   for(unsigned k=0;; ++k) {
+      74          44 :     if( !ifile.scanField("height",h) ) break;
+      75          40 :     std::string ktype; ifile.scanField("kerneltype",ktype); if( ktype!="gaussian" ) error("cannot process kernels of type " + ktype );
+      76          60 :     double mu, sigma; ifile.scanField("mu",mu); ifile.scanField("sigma",sigma); ifile.scanField();
+      77          20 :     std::string hstr, mustr, sigmastr; Tools::convert( h, hstr );
+      78          20 :     Tools::convert( 2*sigma*sigma, sigmastr ); Tools::convert( mu, mustr );
+      79             :     // Get a sensible value for the cutoff
+      80          20 :     double support = sqrt(2.0*dp2cutoff)*(1.0/sigma);
+      81          20 :     if( mu+support>cutoff ) cutoff= mu + support;
+      82             :     // And make the kernel
+      83          38 :     if( k==0 ) kfunc = hstr; else kfunc += "+" + hstr;
+      84          40 :     kfunc += "*exp(-(x-" + mustr +")^2/" + sigmastr + ")";
+      85          20 :   }
+      86             :   std::string sp_str, specA, specB, grpinfo;
+      87           8 :   parse("SPECIES",sp_str); parse("SPECIESA",specA); parse("SPECIESB",specB);
+      88           2 :   if( sp_str.length()>0 ) {
+      89           4 :     grpinfo="GROUP=" + sp_str;
+      90             :   } else {
+      91           0 :     if( specA.length()==0 || specB.length()==0 ) error("no atoms were specified in input use either SPECIES or SPECIESA + SPECIESB");
+      92           0 :     grpinfo="GROUPA=" + specA + " GROUPB=" + specB;
+      93             :   }
+      94           2 :   std::string cutstr; Tools::convert( cutoff, cutstr );
+      95             :   // Setup the contact matrix
+      96           4 :   readInputLine( getShortcutLabel() + "_cmat: DISTANCE_MATRIX  " + grpinfo + " CUTOFF=" + cutstr);
+      97             :   // And the kernels
+      98           4 :   readInputLine( getShortcutLabel() + "_kval: CUSTOM ARG=" + getShortcutLabel() + "_cmat PERIODIC=NO FUNC=" + kfunc );
+      99             :   // Find the number of ones we need to multiply by
+     100           2 :   ActionWithValue* av = plumed.getActionSet().selectWithLabel<ActionWithValue*>( getShortcutLabel() + "_cmat");
+     101           2 :   plumed_assert( av && av->getNumberOfComponents()>0 && (av->copyOutput(0))->getRank()==2 );
+     102           2 :   std::string size; Tools::convert( (av->copyOutput(0))->getShape()[1], size );
+     103           4 :   readInputLine( getShortcutLabel() + "_ones: ONES SIZE=" + size );
+     104             :   // And the final order parameters
+     105           4 :   readInputLine( getShortcutLabel() + ": MATRIX_VECTOR_PRODUCT ARG=" + getShortcutLabel() + "_kval," + getShortcutLabel() + "_ones");
+     106           4 : }
+     107             : 
+     108             : }
+     109             : }
+     110             : 
+     111             : 
+     112             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystdistrib/Quaternion.cpp.func-sort-c.html b/coverage/crystdistrib/Quaternion.cpp.func-sort-c.html new file mode 100644 index 000000000000..f7b9b640fffc --- /dev/null +++ b/coverage/crystdistrib/Quaternion.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - crystdistrib/Quaternion.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystdistrib - Quaternion.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:14617882.0 %
Date:2024-04-19 12:12:35Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12crystdistrib10QuaternionC2ERKNS_13ActionOptionsE0
_ZN4PLMD12crystdistrib10QuaternionC1ERKNS_13ActionOptionsE5
_ZN4PLMD12crystdistrib10Quaternion21getModeAndSetupValuesEPNS_15ActionWithValueE17
_ZN4PLMD12crystdistrib10Quaternion9calculateEv45
_ZN4PLMD12crystdistrib10Quaternion16registerKeywordsERNS_8KeywordsE69
_ZN4PLMD12crystdistrib10Quaternion13parseAtomListERKiRSt6vectorINS_10AtomNumberESaIS5_EEPNS_15ActionAtomisticE1318
_ZN4PLMD12crystdistrib10Quaternion11calculateCVERKjRKSt6vectorIdSaIdEES8_RKS4_INS_13VectorGenericILj3EEESaISA_EERS6_RS4_ISC_SaISC_EERS4_INS_13TensorGenericILj3ELj3EEESaISK_EEPKNS_15ActionAtomisticE5718
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystdistrib/Quaternion.cpp.func.html b/coverage/crystdistrib/Quaternion.cpp.func.html new file mode 100644 index 000000000000..ec8093f57608 --- /dev/null +++ b/coverage/crystdistrib/Quaternion.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - crystdistrib/Quaternion.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystdistrib - Quaternion.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:14617882.0 %
Date:2024-04-19 12:12:35Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12crystdistrib10Quaternion11calculateCVERKjRKSt6vectorIdSaIdEES8_RKS4_INS_13VectorGenericILj3EEESaISA_EERS6_RS4_ISC_SaISC_EERS4_INS_13TensorGenericILj3ELj3EEESaISK_EEPKNS_15ActionAtomisticE5718
_ZN4PLMD12crystdistrib10Quaternion13parseAtomListERKiRSt6vectorINS_10AtomNumberESaIS5_EEPNS_15ActionAtomisticE1318
_ZN4PLMD12crystdistrib10Quaternion16registerKeywordsERNS_8KeywordsE69
_ZN4PLMD12crystdistrib10Quaternion21getModeAndSetupValuesEPNS_15ActionWithValueE17
_ZN4PLMD12crystdistrib10Quaternion9calculateEv45
_ZN4PLMD12crystdistrib10QuaternionC1ERKNS_13ActionOptionsE5
_ZN4PLMD12crystdistrib10QuaternionC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystdistrib/Quaternion.cpp.gcov.html b/coverage/crystdistrib/Quaternion.cpp.gcov.html new file mode 100644 index 000000000000..0d01d0684339 --- /dev/null +++ b/coverage/crystdistrib/Quaternion.cpp.gcov.html @@ -0,0 +1,471 @@ + + + + + + + + LCOV - plumed test coverage - crystdistrib/Quaternion.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystdistrib - Quaternion.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:14617882.0 %
Date:2024-04-19 12:12:35Functions:6785.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) crystdistrib 2023-2023 The code team
+       3             :    (see the PEOPLE-crystdistrib file at the root of this folder for a list of names)
+       4             : 
+       5             :    This file is part of crystdistrib code module.
+       6             : 
+       7             :    The crystdistrib code module is free software: you can redistribute it and/or modify
+       8             :    it under the terms of the GNU Lesser General Public License as published by
+       9             :    the Free Software Foundation, either version 3 of the License, or
+      10             :    (at your option) any later version.
+      11             : 
+      12             :    The crystdistrib code module is distributed in the hope that it will be useful,
+      13             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      14             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      15             :    GNU Lesser General Public License for more details.
+      16             : 
+      17             :    You should have received a copy of the GNU Lesser General Public License
+      18             :    along with the crystdistrib code module.  If not, see <http://www.gnu.org/licenses/>.
+      19             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      20             : #include "core/Colvar.h"
+      21             : #include "colvar/ColvarShortcut.h"
+      22             : #include "colvar/MultiColvarTemplate.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "tools/Pbc.h"
+      25             : 
+      26             : namespace PLMD {
+      27             : namespace crystdistrib {
+      28             : 
+      29             : //+PLUMEDOC COLVAR QUATERNION
+      30             : /*
+      31             : Calculate quaternions for molecules.
+      32             : 
+      33             : The reference frame for the molecule is defined using the positions of three user selected atoms.  From the positions of these atoms,
+      34             : \f$\mathbf{x}_1\f$, \f$\mathbf{x}_2\f$ and \f$\mathbf{x}_3\f$, we define the vectors of the reference frame as:
+      35             : 
+      36             : \f[
+      37             : \begin{aligned}
+      38             : \mathbf{x} & = \mathbf{x}_2 - \mathbf{x}_1 \\
+      39             : \mathbf{y} & = (\mathbf{x}_2 - \mathbf{x}_1) \times (\mathbf{x}_3 - \mathbf{x}_1) \\
+      40             : \mathbf{z} & \mathbf{x} \times \mathbf{y}
+      41             : \f]
+      42             : 
+      43             : \par Examples
+      44             : 
+      45             : This calculates the quaternions for a molecule with 10 atoms
+      46             : 
+      47             : \plumedfile
+      48             : q1: QUATERNION ATOMS1=1,2,3
+      49             : PRINT ARG=q1.w,q1.i,q1.j,q1.k FILE=colvar
+      50             : \endplumedfile
+      51             : 
+      52             : This calculate the quaternions for two molecules with 10 atoms
+      53             : 
+      54             : \plumedfile
+      55             : q1: QUATERNION ATOMS1=1,2,3 ATOMS=4,5,6
+      56             : PRINT ARG=q1.w,q1.i,q1.j,q1.k FILE=colvar
+      57             : \endplumedfile
+      58             : 
+      59             : */
+      60             : //+ENDPLUMEDOC
+      61             : 
+      62             : //+PLUMEDOC COLVAR QUATERNION_SCALAR
+      63             : /*
+      64             : Calculate a single quaternion
+      65             : 
+      66             : See \ref QUATERNION for more details
+      67             : 
+      68             : \par Examples
+      69             : 
+      70             : */
+      71             : //+ENDPLUMEDOC
+      72             : 
+      73             : //+PLUMEDOC COLVAR QUATERNION_VECTOR
+      74             : /*
+      75             : Calculate multiple quaternions
+      76             : 
+      77             : See \ref QUATERNION for more details
+      78             : 
+      79             : \par Examples
+      80             : 
+      81             : */
+      82             : //+ENDPLUMEDOC
+      83             : 
+      84             : //simple hamilton/quaternion product, which is just expanding the two quats as expected, then applying the rules for i j k
+      85             : //passing 12 references might be a bit silly
+      86             : //void QuatProduct(double &a1, double &b1, double &c1, double &d1, double &a2, double &b2, double &c2, double &d2, double &w, double &i, double &j, double &k) {
+      87             : //
+      88             : //  w = a1*a2 - b1*b2 - c1*c2 - d1*d2;
+      89             : //  i = a1*b2 + b1*a2 + c1*d2 - d1*c2;
+      90             : //  j = a1*c2 - b1*d2 + c1*a2 + d1*b2;
+      91             : //  k = a1*d2 + b1*c2 - c1*b2 + d1*a2;
+      92             : //}
+      93             : //
+      94             : //
+      95             : //
+      96             : 
+      97             : class Quaternion : public Colvar {
+      98             : private:
+      99             :   bool pbc;
+     100             :   std::vector<double> value, masses, charges;
+     101             :   std::vector<std::vector<Vector> > derivs;
+     102             :   std::vector<Tensor> virial;
+     103             : public:
+     104             :   static void registerKeywords( Keywords& keys );
+     105             :   explicit Quaternion(const ActionOptions&);
+     106             :   static void parseAtomList( const int& num, std::vector<AtomNumber>& t, ActionAtomistic* aa );
+     107             :   static unsigned getModeAndSetupValues( ActionWithValue* av );
+     108             : // active methods:
+     109             :   void calculate() override;
+     110             :   static void calculateCV( const unsigned& mode, const std::vector<double>& masses, const std::vector<double>& charges,
+     111             :                            const std::vector<Vector>& pos, std::vector<double>& vals, std::vector<std::vector<Vector> >& derivs,
+     112             :                            std::vector<Tensor>& virial, const ActionAtomistic* aa );
+     113             : };
+     114             : 
+     115             : typedef colvar::ColvarShortcut<Quaternion> QuaternionShortcut;
+     116             : PLUMED_REGISTER_ACTION(QuaternionShortcut,"QUATERNION")
+     117             : PLUMED_REGISTER_ACTION(Quaternion,"QUATERNION_SCALAR")
+     118             : typedef colvar::MultiColvarTemplate<Quaternion> QuaternionMulti;
+     119             : PLUMED_REGISTER_ACTION(QuaternionMulti,"QUATERNION_VECTOR")
+     120             : 
+     121          69 : void Quaternion::registerKeywords( Keywords& keys ) {
+     122          69 :   Colvar::registerKeywords( keys );
+     123         138 :   keys.add("atoms","ATOMS","the three atom that we are using to calculate the quaternion");
+     124         138 :   keys.addOutputComponent("w","default","the real component of quaternion");
+     125         138 :   keys.addOutputComponent("i","default","the i component of the quaternion");
+     126         138 :   keys.addOutputComponent("j","default","the j component of the quaternion");
+     127         138 :   keys.addOutputComponent("k","default","the k component of the quaternion");
+     128         138 :   keys.add("hidden","NO_ACTION_LOG","suppresses printing from action on the log");
+     129          69 : }
+     130             : 
+     131           5 : Quaternion::Quaternion(const ActionOptions&ao):
+     132             :   PLUMED_COLVAR_INIT(ao),
+     133           5 :   pbc(true),
+     134           5 :   value(4),
+     135           5 :   derivs(4),
+     136          10 :   virial(4)
+     137             : {
+     138          25 :   for(unsigned i=0; i<4; ++i) derivs[i].resize(3);
+     139             :   std::vector<AtomNumber> atoms;
+     140           5 :   parseAtomList(-1,atoms,this);
+     141           5 :   if(atoms.size()!=3) error("Number of specified atoms should be 3");
+     142             :   // please note, I do NO checking if these atoms are in the same molecule at all, so be careful in your input
+     143             : 
+     144           5 :   bool nopbc=!pbc;
+     145           5 :   parseFlag("NOPBC",nopbc);
+     146           5 :   pbc=!nopbc;
+     147             : 
+     148           5 :   unsigned mode = getModeAndSetupValues( this );
+     149           5 :   requestAtoms(atoms);
+     150           5 : }
+     151             : 
+     152        1318 : void Quaternion::parseAtomList( const int& num, std::vector<AtomNumber>& t, ActionAtomistic* aa ) {
+     153        2636 :   aa->parseAtomList("ATOMS",num,t);
+     154        1318 :   if( t.size()==3 ) aa->log.printf("  involving atoms %d %d %d\n",t[0].serial(),t[1].serial(),t[0].serial());
+     155        1318 : }
+     156             : 
+     157          17 : unsigned Quaternion::getModeAndSetupValues( ActionWithValue* av ) {
+     158             :   // This sets up values that we can pass around in PLUMED
+     159          34 :   av->addComponentWithDerivatives("w"); av->componentIsNotPeriodic("w");
+     160          34 :   av->addComponentWithDerivatives("i"); av->componentIsNotPeriodic("i");
+     161          34 :   av->addComponentWithDerivatives("j"); av->componentIsNotPeriodic("j");
+     162          34 :   av->addComponentWithDerivatives("k"); av->componentIsNotPeriodic("k");
+     163          17 :   return 0;
+     164             : }
+     165             : 
+     166          45 : void Quaternion::calculate() {
+     167          45 :   if(pbc) makeWhole();
+     168             : 
+     169          45 :   calculateCV( 0, masses, charges, getPositions(), value, derivs, virial, this );
+     170         225 :   for(unsigned j=0; j<4; ++j) {
+     171         180 :     Value* valuej=getPntrToComponent(j);
+     172         720 :     for(unsigned i=0; i<3; ++i) setAtomsDerivatives(valuej,i,derivs[j][i] );
+     173         180 :     setBoxDerivatives(valuej,virial[j]);
+     174         180 :     valuej->set(value[j]);
+     175             :   }
+     176          45 : }
+     177             : 
+     178             : // calculator
+     179        5718 : void Quaternion::calculateCV( const unsigned& mode, const std::vector<double>& masses, const std::vector<double>& charges,
+     180             :                               const std::vector<Vector>& pos, std::vector<double>& vals, std::vector<std::vector<Vector> >& derivs,
+     181             :                               std::vector<Tensor>& virial, const ActionAtomistic* aa ) {
+     182             :   //declarations
+     183        5718 :   Vector vec1_comp = delta( pos[0], pos[1] ); //components between atom 1 and 2
+     184        5718 :   Vector vec2_comp = delta( pos[0], pos[2] ); //components between atom 1 and 3
+     185             : 
+     186             : ////////x-vector calculations///////
+     187        5718 :   double magx = vec1_comp.modulo(); Vector xt = vec1_comp / magx;
+     188        5718 :   std::vector<Tensor> dx(3); double magx3= magx*magx*magx;
+     189             : //dx[i] - derivatives of atom i's coordinates
+     190        5718 :   dx[0](0,0) = ( -(vec1_comp[1]*vec1_comp[1]+vec1_comp[2]*vec1_comp[2])/magx3 ); //dx[0]/dx0
+     191        5718 :   dx[0](0,1) = (  vec1_comp[0]*vec1_comp[1]/magx3 );                 // dx[0]/dy0
+     192        5718 :   dx[0](0,2) = (  vec1_comp[0]*vec1_comp[2]/magx3 );                 // dx[0]/dz0
+     193        5718 :   dx[0](1,0) = (  vec1_comp[1]*vec1_comp[0]/magx3 );                 // dx[1]/dx0
+     194        5718 :   dx[0](1,1) = ( -(vec1_comp[0]*vec1_comp[0]+vec1_comp[2]*vec1_comp[2])/magx3 );   // dx[1]/dy0
+     195        5718 :   dx[0](1,2) = (  vec1_comp[1]*vec1_comp[2]/magx3 ); //dx[1]/dz0
+     196        5718 :   dx[0](2,0) = (  vec1_comp[2]*vec1_comp[0]/magx3 );//etc
+     197        5718 :   dx[0](2,1) = (  vec1_comp[2]*vec1_comp[1]/magx3 );
+     198        5718 :   dx[0](2,2) = ( -(vec1_comp[1]*vec1_comp[1]+vec1_comp[0]*vec1_comp[0])/magx3 );
+     199             : 
+     200        5718 :   dx[1](0,0) = ( (vec1_comp[1]*vec1_comp[1]+vec1_comp[2]*vec1_comp[2])/magx3 );//dx[0]/dx1
+     201        5718 :   dx[1](0,1) = ( -vec1_comp[0]*vec1_comp[1]/magx3 );//dx[0]/dy1
+     202        5718 :   dx[1](0,2) = ( -vec1_comp[0]*vec1_comp[2]/magx3 );
+     203        5718 :   dx[1](1,0) = ( -vec1_comp[1]*vec1_comp[0]/magx3 );
+     204        5718 :   dx[1](1,1) = ( (vec1_comp[0]*vec1_comp[0]+vec1_comp[2]*vec1_comp[2])/magx3 );
+     205        5718 :   dx[1](1,2) = ( -vec1_comp[1]*vec1_comp[2]/magx3 );
+     206        5718 :   dx[1](2,0) = ( -vec1_comp[2]*vec1_comp[0]/magx3 );
+     207        5718 :   dx[1](2,1) = ( -vec1_comp[2]*vec1_comp[1]/magx3 );
+     208        5718 :   dx[1](2,2) = ( (vec1_comp[1]*vec1_comp[1]+vec1_comp[0]*vec1_comp[0])/magx3 );
+     209        5718 :   dx[2].zero();//not atom[2] terms present
+     210             : 
+     211             : ////////y-vector calculations////////
+     212             :   //project vec2_comp on to vec1_comp
+     213             :   //first do dot product of unormalized x and unormed y, divided by magnitude of x^2
+     214        5718 :   double dp = dotProduct( vec1_comp, vec2_comp ); double magx2=magx*magx;
+     215        5718 :   std::vector<Vector> fac_derivs(3); double magx4=magx2*magx2, fac = dp/magx2; //fac meaning factor on front
+     216        5718 :   fac_derivs[0] = (-vec2_comp - vec1_comp)/magx2 + 2*dp*vec1_comp / magx4;
+     217        5718 :   fac_derivs[1] = (vec2_comp)/(magx2) - 2*dp*vec1_comp / magx4;
+     218        5718 :   fac_derivs[2] = (vec1_comp)/(magx2);   //atom 1, components x2,y2,z2
+     219             :   //now multiply fac by unormed x, and subtract it from unormed y, then normalize
+     220        5718 :   Vector yt = vec2_comp - fac*vec1_comp; std::vector<Tensor> dy(3);
+     221        5718 :   dy[0](0,0) = -1 - fac_derivs[0][0]*vec1_comp[0] + fac;   // dy[0]/dx0
+     222        5718 :   dy[0](0,1) = -fac_derivs[0][1]*vec1_comp[0];             // dy[0]/dy0
+     223        5718 :   dy[0](0,2) = -fac_derivs[0][2]*vec1_comp[0];
+     224        5718 :   dy[0](1,0) = -fac_derivs[0][0]*vec1_comp[1];
+     225        5718 :   dy[0](1,1) = -1 - fac_derivs[0][1]*vec1_comp[1] + fac;
+     226        5718 :   dy[0](1,2) = -fac_derivs[0][2]*vec1_comp[1];
+     227        5718 :   dy[0](2,0) = -fac_derivs[0][0]*vec1_comp[2];
+     228        5718 :   dy[0](2,1) = -fac_derivs[0][1]*vec1_comp[2];
+     229        5718 :   dy[0](2,2) = -1 - fac_derivs[0][2]*vec1_comp[2] + fac;
+     230             : 
+     231        5718 :   dy[1](0,0) = -fac_derivs[1][0]*vec1_comp[0] - fac; //dy[0]/dx0
+     232        5718 :   dy[1](0,1) = -fac_derivs[1][1]*vec1_comp[0];
+     233        5718 :   dy[1](0,2) = -fac_derivs[1][2]*vec1_comp[0];
+     234        5718 :   dy[1](1,0) = -fac_derivs[1][0]*vec1_comp[1];
+     235        5718 :   dy[1](1,1) = -fac_derivs[1][1]*vec1_comp[1] - fac;
+     236        5718 :   dy[1](1,2) = -fac_derivs[1][2]*vec1_comp[1];
+     237        5718 :   dy[1](2,0) = -fac_derivs[1][0]*vec1_comp[2];
+     238        5718 :   dy[1](2,1) = -fac_derivs[1][1]*vec1_comp[2];
+     239        5718 :   dy[1](2,2) = -fac_derivs[1][2]*vec1_comp[2] - fac;
+     240             : 
+     241        5718 :   dy[2](0,0) = 1 - fac_derivs[2][0]*vec1_comp[0];//dy[0]/dx2
+     242        5718 :   dy[2](0,1) = -fac_derivs[2][1]*vec1_comp[0];
+     243        5718 :   dy[2](0,2) = -fac_derivs[2][2]*vec1_comp[0];
+     244        5718 :   dy[2](1,0) = -fac_derivs[2][0]*vec1_comp[1];
+     245        5718 :   dy[2](1,1) = 1 - fac_derivs[2][1]*vec1_comp[1];
+     246        5718 :   dy[2](1,2) = -fac_derivs[2][2]*vec1_comp[1];
+     247        5718 :   dy[2](2,0) = -fac_derivs[2][0]*vec1_comp[2];
+     248        5718 :   dy[2](2,1) = -fac_derivs[2][1]*vec1_comp[2];
+     249        5718 :   dy[2](2,2) = 1 - fac_derivs[2][2]*vec1_comp[2];
+     250             :   //now normalize, and we have our y vector
+     251        5718 :   double magy = yt.modulo(); double imagy = 1/magy, magy3 = magy*magy*magy;
+     252       22872 :   Tensor abc; for(unsigned i=0; i<3; ++i) abc.setRow(i, yt);
+     253        5718 :   Tensor abc_diag; abc_diag.setRow(0, Vector(yt[0], 0, 0)); abc_diag.setRow(1, Vector(0, yt[1], 0)); abc_diag.setRow(2, Vector(0, 0, yt[2]));
+     254        5718 :   Tensor abc_prod = matmul(abc_diag, abc);
+     255       22872 :   for(unsigned i=0; i<3; ++i) dy[i] = dy[i]/magy - matmul(abc_prod, dy[i])/magy3;
+     256             :   //normalize now, derivatives are with respect to un-normalized y vector
+     257        5718 :   yt = yt / magy;
+     258             : 
+     259             : ///////z-vector calculations/////////
+     260             : //comparatively simple
+     261        5718 :   Vector zt = crossProduct(xt,yt); std::vector<Tensor> dz(3);
+     262        5718 :   dz[0].setCol( 0, crossProduct( dx[0].getCol(0), yt ) + crossProduct( xt, dy[0].getCol(0) ) );
+     263        5718 :   dz[0].setCol( 1, crossProduct( dx[0].getCol(1), yt ) + crossProduct( xt, dy[0].getCol(1) ) );
+     264        5718 :   dz[0].setCol( 2, crossProduct( dx[0].getCol(2), yt ) + crossProduct( xt, dy[0].getCol(2) ) );
+     265             : 
+     266        5718 :   dz[1].setCol( 0, crossProduct( dx[1].getCol(0), yt ) + crossProduct( xt, dy[1].getCol(0) ) );
+     267        5718 :   dz[1].setCol( 1, crossProduct( dx[1].getCol(1), yt ) + crossProduct( xt, dy[1].getCol(1) ) );
+     268        5718 :   dz[1].setCol( 2, crossProduct( dx[1].getCol(2), yt ) + crossProduct( xt, dy[1].getCol(2) ) );
+     269             : 
+     270        5718 :   dz[2].setCol( 0, crossProduct( xt, dy[2].getCol(0) ) );
+     271        5718 :   dz[2].setCol( 1, crossProduct( xt, dy[2].getCol(1) ) );
+     272        5718 :   dz[2].setCol( 2, crossProduct( xt, dy[2].getCol(2) ) );
+     273             : 
+     274             : //for debugging frame values
+     275             : //aa->log.printf("%8.6f %8.6f %8.6f\n%8.6f %8.6f %8.6f\n%8.6f %8.6f %8.6f\n",xt[0],xt[1],xt[2],yt[0],yt[1],yt[2],zt[0],zt[1],zt[2]);
+     276             : 
+     277             : //for bebuffing derivatives
+     278             : //aa->log.printf("x1 x2 x3 y1 y2 y3 z1 z2 z3\n");
+     279             : //for (int i=0; i<3; i++){
+     280             : //for (int j=0;j<3;j++){
+     281             : //aa->log.printf("%8.4f %8.4f %8.4f\n%8.4f %8.4f %8.4f\n%8.4f %8.4f %8.4f\n",dx[i](0,j), dx[i](1,j), dx[i](2,j), dy[i](0,j), dy[i](1,j), dy[i](2,j), dz[i](0,j), dz[i](1,j), dz[i](2,j));
+     282             : //}
+     283             : //}
+     284             : //
+     285             : 
+     286             : //the above 9 components form an orthonormal basis, centered on the molecule in question
+     287             : //the rotation matrix is generally the inverse of this matrix, and in this case since it is 1) orthogonal and 2) its determinant is 1
+     288             : //the inverse is simply the transpose
+     289             : 
+     290             : 
+     291             : //[x[0] x[1] x[2]]
+     292             : //[y[0] y[1] y[2]]
+     293             : //[z[0] z[1] z[2]]
+     294             : //QUICKFIX to transpose basis
+     295        5718 :   Vector x(xt[0],yt[0],zt[0]);
+     296        5718 :   Vector y(xt[1],yt[1],zt[1]);
+     297        5718 :   Vector z(xt[2],yt[2],zt[2]);
+     298             : 
+     299             : //likewise transposing the tensors into proper form
+     300        5718 :   std::vector<Tensor> tdx(3);
+     301        5718 :   std::vector<Tensor> tdy(3);
+     302        5718 :   std::vector<Tensor> tdz(3);
+     303       22872 :   for (int i=0; i<3; ++i) {
+     304       17154 :     tdx[i].setRow(0, dx[i].getRow(0));
+     305       17154 :     tdx[i].setRow(1, dy[i].getRow(0));
+     306       17154 :     tdx[i].setRow(2, dz[i].getRow(0));
+     307             : 
+     308       17154 :     tdy[i].setRow(0, dx[i].getRow(1));
+     309       17154 :     tdy[i].setRow(1, dy[i].getRow(1));
+     310       17154 :     tdy[i].setRow(2, dz[i].getRow(1));
+     311             : 
+     312       17154 :     tdz[i].setRow(0, dx[i].getRow(2));
+     313       17154 :     tdz[i].setRow(1, dy[i].getRow(2));
+     314       17154 :     tdz[i].setRow(2, dz[i].getRow(2));
+     315             :   }
+     316             : 
+     317             : //convert to quaternion
+     318        5718 :   double tr = x[0] + y[1] + z[2] + 1; //trace of the rotation matrix + 1
+     319        5718 :   std::vector<Vector> dS(3);
+     320        5718 :   if (tr > 1.0E-8) { //to avoid numerical instability
+     321        5718 :     double S = 1/(sqrt(tr) * 2); // S=4*qw
+     322       22872 :     for(unsigned i=0; i<3; ++i) dS[i] = (-2*S*S*S)*(tdx[i].getRow(0) + tdy[i].getRow(1) + tdz[i].getRow(2));
+     323             : 
+     324        5718 :     vals[0] = 0.25 / S;
+     325       22872 :     for(unsigned i=0; i<3; ++i) derivs[0][i] =-0.25*dS[i]/(S*S);
+     326             : 
+     327        5718 :     vals[1] = (z[1] - y[2]) * S;
+     328       22872 :     for(unsigned i=0; i<3; ++i) derivs[1][i] = (S)*(tdz[i].getRow(1) - tdy[i].getRow(2)) + (z[1]-y[2])*dS[i];
+     329             : 
+     330        5718 :     vals[2] = (x[2] - z[0]) * S;
+     331       22872 :     for(unsigned i=0; i<3; ++i) derivs[2][i] = (S)*(tdx[i].getRow(2) - tdz[i].getRow(0)) + (x[2]-z[0])*dS[i];
+     332             : 
+     333        5718 :     vals[3] = (y[0] - x[1]) * S;
+     334       22872 :     for(unsigned i=0; i<3; ++i) derivs[3][i] = (S)*(tdy[i].getRow(0) - tdx[i].getRow(1)) + (y[0]-x[1])*dS[i];
+     335             :   }
+     336           0 :   else if ((x[0] > y[1])&(x[0] > z[2])) {
+     337           0 :     float S = sqrt(1.0 + x[0] - y[1] - z[2]) * 2; // S=4*qx
+     338           0 :     for(unsigned i=0; i<3; ++i) dS[i] = (2/S)*(tdx[i].getRow(0) - tdy[i].getRow(1) - tdz[i].getRow(2));
+     339             : 
+     340           0 :     vals[0] = (z[1] - y[2]) / S;
+     341           0 :     for(unsigned i=0; i<3; ++i) derivs[0][i] = (1/S)*(tdz[i].getRow(1) - tdy[i].getRow(2)) - (vals[0]/S)*dS[i];
+     342             : 
+     343           0 :     vals[1] = 0.25 * S;
+     344           0 :     for(unsigned i=0; i<3; ++i) derivs[1][i] =0.25*dS[i];
+     345             : 
+     346           0 :     vals[2] = (x[1] + y[0]) / S;
+     347           0 :     for(unsigned i=0; i<3; ++i) derivs[2][i] = (1/S)*(tdx[i].getRow(1) + tdy[i].getRow(0)) - (vals[2]/S)*dS[i];
+     348             : 
+     349           0 :     vals[3] = (x[2] + z[0]) / S;
+     350           0 :     for(unsigned i=0; i<3; ++i) derivs[3][i] = (1/S)*(tdx[i].getRow(2) + tdz[i].getRow(0)) - (vals[3]/S)*dS[i];
+     351             :   }
+     352           0 :   else if (y[1] > z[2]) {
+     353           0 :     float S = sqrt(1.0 + y[1] - x[0] - z[2]) * 2; // S=4*qy
+     354           0 :     for(unsigned i=0; i<3; ++i) dS[i] = (2/S)*( -tdx[i].getRow(0) + tdy[i].getRow(1) - tdz[i].getRow(2));
+     355             : 
+     356             : 
+     357           0 :     vals[0] = (x[2] - z[0]) / S;
+     358           0 :     for(unsigned i=0; i<3; ++i) derivs[0][i] = (1/S)*(tdx[i].getRow(2) - tdz[i].getRow(0)) - (vals[0]/S)*dS[i];
+     359             : 
+     360           0 :     vals[1] = (x[1] + y[0]) / S;
+     361           0 :     for(unsigned i=0; i<3; ++i) derivs[1][i] = (1/S)*(tdx[i].getRow(1) + tdy[i].getRow(0)) - (vals[1]/S)*dS[i];
+     362             : 
+     363           0 :     vals[2] = 0.25 * S;
+     364           0 :     for(unsigned i=0; i<3; ++i) derivs[2][i] =0.25*dS[i];
+     365             : 
+     366           0 :     vals[3] = (y[2] + z[1]) / S;
+     367           0 :     for(unsigned i=0; i<3; ++i) derivs[3][i] = (1/S)*(tdy[i].getRow(2) + tdz[i].getRow(1)) - (vals[3]/S)*dS[i];
+     368             :   }
+     369             :   else {
+     370           0 :     float S = sqrt(1.0 + z[2] - x[0] - y[1]) * 2; // S=4*qz
+     371           0 :     for(unsigned i=0; i<3; ++i) dS[i] = (2/S)*(-tdx[i].getRow(0) - tdy[i].getRow(1) + tdz[i].getRow(2));
+     372             : 
+     373             : 
+     374           0 :     vals[0] = (y[0] - x[1]) / S;
+     375           0 :     for(unsigned i=0; i<3; ++i) derivs[0][i] = (1/S)*(tdy[i].getRow(0) - tdx[i].getRow(1)) - (vals[0]/S)*dS[i];
+     376             : 
+     377           0 :     vals[1] = (x[2] + z[0]) / S;
+     378           0 :     for(unsigned i=0; i<3; ++i) derivs[1][i] = (1/S)*(tdx[i].getRow(2) + tdz[i].getRow(0)) - (vals[1]/S)*dS[i];
+     379             : 
+     380           0 :     vals[2] = (y[2] + z[1]) / S;
+     381           0 :     for(unsigned i=0; i<3; ++i) derivs[2][i] = (1/S)*(tdy[i].getRow(2) + tdz[i].getRow(1)) - (vals[2]/S)*dS[i];
+     382             : 
+     383           0 :     vals[3] = 0.25 * S;
+     384           0 :     for(unsigned i=0; i<3; ++i) derivs[3][i] =0.25*dS[i];
+     385             :   }
+     386        5718 :   setBoxDerivativesNoPbc( pos, derivs, virial );
+     387             : 
+     388        5718 : }
+     389             : 
+     390             : }
+     391             : }
+     392             : 
+     393             : 
+     394             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystdistrib/QuaternionBondProductMatrix.cpp.func-sort-c.html b/coverage/crystdistrib/QuaternionBondProductMatrix.cpp.func-sort-c.html new file mode 100644 index 000000000000..db20c77616d6 --- /dev/null +++ b/coverage/crystdistrib/QuaternionBondProductMatrix.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - crystdistrib/QuaternionBondProductMatrix.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystdistrib - QuaternionBondProductMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:14815396.7 %
Date:2024-04-19 12:12:35Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12crystdistrib27QuaternionBondProductMatrixC2ERKNS_13ActionOptionsE0
_ZNK4PLMD12crystdistrib27QuaternionBondProductMatrix12setupForTaskERKjRSt6vectorIjSaIjEERNS_10MultiValueE0
_ZN4PLMD12crystdistrib27QuaternionBondProductMatrixC1ERKNS_13ActionOptionsE4
_ZN4PLMD12crystdistrib27QuaternionBondProductMatrix16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD12crystdistrib27QuaternionBondProductMatrix22getNumberOfDerivativesEv32
_ZNK4PLMD12crystdistrib27QuaternionBondProductMatrix18getNumberOfColumnsEv96
_ZNK4PLMD12crystdistrib27QuaternionBondProductMatrix15runEndOfRowJobsERKjRKSt6vectorIjSaIjEERNS_10MultiValueE1614
_ZNK4PLMD12crystdistrib27QuaternionBondProductMatrix11performTaskERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjSB_RNS_10MultiValueE381366
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystdistrib/QuaternionBondProductMatrix.cpp.func.html b/coverage/crystdistrib/QuaternionBondProductMatrix.cpp.func.html new file mode 100644 index 000000000000..e2827628ed66 --- /dev/null +++ b/coverage/crystdistrib/QuaternionBondProductMatrix.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - crystdistrib/QuaternionBondProductMatrix.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystdistrib - QuaternionBondProductMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:14815396.7 %
Date:2024-04-19 12:12:35Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12crystdistrib27QuaternionBondProductMatrix16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD12crystdistrib27QuaternionBondProductMatrix22getNumberOfDerivativesEv32
_ZN4PLMD12crystdistrib27QuaternionBondProductMatrixC1ERKNS_13ActionOptionsE4
_ZN4PLMD12crystdistrib27QuaternionBondProductMatrixC2ERKNS_13ActionOptionsE0
_ZNK4PLMD12crystdistrib27QuaternionBondProductMatrix11performTaskERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjSB_RNS_10MultiValueE381366
_ZNK4PLMD12crystdistrib27QuaternionBondProductMatrix12setupForTaskERKjRSt6vectorIjSaIjEERNS_10MultiValueE0
_ZNK4PLMD12crystdistrib27QuaternionBondProductMatrix15runEndOfRowJobsERKjRKSt6vectorIjSaIjEERNS_10MultiValueE1614
_ZNK4PLMD12crystdistrib27QuaternionBondProductMatrix18getNumberOfColumnsEv96
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystdistrib/QuaternionBondProductMatrix.cpp.gcov.html b/coverage/crystdistrib/QuaternionBondProductMatrix.cpp.gcov.html new file mode 100644 index 000000000000..b4977bdd4f91 --- /dev/null +++ b/coverage/crystdistrib/QuaternionBondProductMatrix.cpp.gcov.html @@ -0,0 +1,461 @@ + + + + + + + + LCOV - plumed test coverage - crystdistrib/QuaternionBondProductMatrix.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystdistrib - QuaternionBondProductMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:14815396.7 %
Date:2024-04-19 12:12:35Functions:6875.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 "adjmat/ActionWithMatrix.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "tools/Torsion.h"
+      25             : 
+      26             : 
+      27             : #include <iostream>
+      28             : 
+      29             : namespace PLMD {
+      30             : namespace crystdistrib {
+      31             : 
+      32             : //+PLUMEDOC MCOLVAR QUATERNION_BOND_PRODUCT_MATRIX
+      33             : /*
+      34             : Calculate the product between a matrix of quaternions and the bonds
+      35             : 
+      36             : \par Examples
+      37             : 
+      38             : */
+      39             : //+ENDPLUMEDOC
+      40             : 
+      41             : class QuaternionBondProductMatrix : public adjmat::ActionWithMatrix {
+      42             : private:
+      43             :   unsigned nderivatives;
+      44             :   std::vector<bool> stored;
+      45             : //  const Vector4d& rightMultiply(Tensor4d&, Vector4d&);
+      46             : public:
+      47             :   static void registerKeywords( Keywords& keys );
+      48             :   explicit QuaternionBondProductMatrix(const ActionOptions&);
+      49             :   unsigned getNumberOfDerivatives();
+      50             :   unsigned getNumberOfColumns() const override ;
+      51             :   void setupForTask( const unsigned& task_index, std::vector<unsigned>& indices, MultiValue& myvals ) const ;
+      52             :   void performTask( const std::string& controller, const unsigned& index1, const unsigned& index2, MultiValue& myvals ) const override;
+      53             :   void runEndOfRowJobs( const unsigned& ival, const std::vector<unsigned> & indices, MultiValue& myvals ) const override ;
+      54             : };
+      55             : 
+      56             : PLUMED_REGISTER_ACTION(QuaternionBondProductMatrix,"QUATERNION_BOND_PRODUCT_MATRIX")
+      57             : 
+      58             : 
+      59             : //const Vector4d& QuaternionBondMatrix::rightMultiply(Tensor4d& pref, Vector4d& quat) {
+      60             : //  Vector4d temp;
+      61             : //  int sumTemp;
+      62             : //  for (int i=0; i<4; i++){ //rows
+      63             : //    sumTemp=0;
+      64             : //    for (int j=0; j<4; j++){ //cols
+      65             : //      sumTemp+=pref(i,j)*quat[j];
+      66             : //    }
+      67             : //    temp[i]=sumTemp;
+      68             : //  }
+      69             : //  return temp;
+      70             : //}
+      71             : 
+      72             : 
+      73             : 
+      74             : 
+      75           6 : void QuaternionBondProductMatrix::registerKeywords( Keywords& keys ) {
+      76           6 :   adjmat::ActionWithMatrix::registerKeywords(keys); keys.use("ARG");
+      77          12 :   keys.addOutputComponent("w","default","the real component of quaternion");
+      78          12 :   keys.addOutputComponent("i","default","the i component of the quaternion");
+      79          12 :   keys.addOutputComponent("j","default","the j component of the quaternion");
+      80          12 :   keys.addOutputComponent("k","default","the k component of the quaternion");
+      81           6 : }
+      82             : 
+      83           4 : QuaternionBondProductMatrix::QuaternionBondProductMatrix(const ActionOptions&ao):
+      84             :   Action(ao),
+      85           4 :   ActionWithMatrix(ao)
+      86             : {
+      87           4 :   if( getNumberOfArguments()!=8 ) error("should be eight arguments to this action, 4 quaternion components and 4 matrices");
+      88           4 :   unsigned nquat = getPntrToArgument(0)->getNumberOfValues();
+      89          20 :   for(unsigned i=0; i<4; ++i) {
+      90          16 :     Value* myarg=getPntrToArgument(i); myarg->buildDataStore();
+      91          16 :     if( myarg->getRank()!=1 ) error("first four arguments to this action should be vectors");
+      92          16 :     if( (myarg->getPntrToAction())->getName()!="QUATERNION_VECTOR" ) error("first four arguments to this action should be quaternions");
+      93          16 :     std::string mylab=getPntrToArgument(i)->getName(); std::size_t dot=mylab.find_first_of(".");
+      94          24 :     if( i==0 && mylab.substr(dot+1)!="w" ) error("quaternion arguments are in wrong order");
+      95          24 :     if( i==1 && mylab.substr(dot+1)!="i" ) error("quaternion arguments are in wrong order");
+      96          24 :     if( i==2 && mylab.substr(dot+1)!="j" ) error("quaternion arguments are in wrong order");
+      97          24 :     if( i==3 && mylab.substr(dot+1)!="k" ) error("quaternion arguments are in wrong order");
+      98             :   }
+      99           4 :   std::vector<unsigned> shape( getPntrToArgument(4)->getShape() );
+     100          20 :   for(unsigned i=4; i<8; ++i) {
+     101             :     Value* myarg=getPntrToArgument(i);
+     102          16 :     if( myarg->getRank()!=2 ) error("second four arguments to this action should be matrices");
+     103          16 :     if( myarg->getShape()[0]!=shape[0] || myarg->getShape()[1]!=shape[1] ) error("matrices should all have the same shape");
+     104          16 :     if( myarg->getShape()[0]!=nquat ) error("number of rows in matrix should equal number of input quaternions");
+     105          16 :     std::string mylab=getPntrToArgument(i)->getName(); std::size_t dot=mylab.find_first_of(".");
+     106          24 :     if( i==5 && mylab.substr(dot+1)!="x" ) error("quaternion arguments are in wrong order");
+     107          24 :     if( i==6 && mylab.substr(dot+1)!="y" ) error("quaternion arguments are in wrong order");
+     108          24 :     if( i==7 && mylab.substr(dot+1)!="z" ) error("quaternion arguments are in wrong order");
+     109             :   }
+     110           8 :   addComponent( "w", shape ); componentIsNotPeriodic("w");
+     111           8 :   addComponent( "i", shape ); componentIsNotPeriodic("i");
+     112           8 :   addComponent( "j", shape ); componentIsNotPeriodic("j");
+     113           8 :   addComponent( "k", shape ); componentIsNotPeriodic("k");
+     114           4 :   done_in_chain=true; nderivatives = buildArgumentStore(0);
+     115             : 
+     116           4 :   std::string headstr=getFirstActionInChain()->getLabel(); stored.resize( getNumberOfArguments() );
+     117          36 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) stored[i] = getPntrToArgument(i)->ignoreStoredValue( headstr );
+     118           4 : }
+     119             : 
+     120          32 : unsigned QuaternionBondProductMatrix::getNumberOfDerivatives() {
+     121          32 :   return nderivatives;
+     122             : }
+     123             : 
+     124          96 : unsigned QuaternionBondProductMatrix::getNumberOfColumns() const {
+     125          96 :   const ActionWithMatrix* am=dynamic_cast<const ActionWithMatrix*>( getPntrToArgument(4)->getPntrToAction() );
+     126          96 :   plumed_assert( am ); return am->getNumberOfColumns();
+     127             : }
+     128             : 
+     129           0 : void QuaternionBondProductMatrix::setupForTask( const unsigned& task_index, std::vector<unsigned>& indices, MultiValue& myvals ) const {
+     130           0 :   unsigned start_n = getPntrToArgument(4)->getShape()[0], size_v = getPntrToArgument(4)->getShape()[1];
+     131           0 :   if( indices.size()!=size_v+1 ) indices.resize( size_v+1 );
+     132           0 :   for(unsigned i=0; i<size_v; ++i) indices[i+1] = start_n + i;
+     133             :   myvals.setSplitIndex( size_v + 1 );
+     134           0 : }
+     135             : 
+     136      381366 : void QuaternionBondProductMatrix::performTask( const std::string& controller, const unsigned& index1, const unsigned& index2, MultiValue& myvals ) const {
+     137      381366 :   unsigned ind2=index2;
+     138      381366 :   if( index2>=getPntrToArgument(0)->getShape()[0] ) ind2 = index2 - getPntrToArgument(0)->getShape()[0];
+     139             : 
+     140      381366 :   std::vector<double> quat(4), bond(4), quatTemp(4);
+     141      381366 :   std::vector<Tensor4d> dqt(2); //dqt[0] -> derivs w.r.t quat [dwt/dw1 dwt/di1 dwt/dj1 dwt/dk1]
+     142             :   //[dit/dw1 dit/di1 dit/dj1 dit/dk1] etc, and dqt[1] is w.r.t the vector-turned-quaternion called bond
+     143             : 
+     144             :   // Retrieve the quaternion
+     145     1906830 :   for(unsigned i=0; i<4; ++i) quat[i] = getArgumentElement( i, index1, myvals );
+     146             : 
+     147             :   // Retrieve the components of the matrix
+     148      381366 :   double weight = getElementOfMatrixArgument( 4, index1, ind2, myvals );
+     149     1525464 :   for(unsigned i=1; i<4; ++i) bond[i] = getElementOfMatrixArgument( 4+i, index1, ind2, myvals );
+     150             : 
+     151             :   // calculate normalization factor
+     152      381366 :   bond[0]=0.0;
+     153      381366 :   double normFac = 1/sqrt(bond[1]*bond[1] + bond[2]*bond[2] + bond[3]*bond[3]);
+     154      381366 :   if (bond[1] == 0.0 && bond[2]==0.0 && bond[3]==0) normFac=1; //just for the case where im comparing a quat to itself, itll be 0 at the end anyway
+     155             :   double normFac3 = normFac*normFac*normFac;
+     156             :   //I hold off on normalizing because this can be done at the very end, and it makes the derivatives with respect to 'bond' more simple
+     157             : 
+     158             : 
+     159             : 
+     160      381366 :   std::vector<double> quat_conj(4);
+     161      381366 :   quat_conj[0] = quat[0]; quat_conj[1] = -1*quat[1]; quat_conj[2] = -1*quat[2]; quat_conj[3] = -1*quat[3];
+     162             :   //make a conjugate of q1 my own sanity
+     163             : 
+     164             : 
+     165             : 
+     166             : 
+     167             : //q1_conj * r first, while keep track of derivs
+     168             :   double pref=1;
+     169             :   double conj=1;
+     170             :   double pref2=1;
+     171             :   //real part of q1*q2
+     172             : 
+     173     1906830 :   for(unsigned i=0; i<4; ++i) {
+     174     1525464 :     if( i>0 ) {pref=-1; conj=-1; pref2=-1;}
+     175     1525464 :     quatTemp[0]+=pref*quat_conj[i]*bond[i];
+     176     1525464 :     dqt[0](0,i) = conj*pref*bond[i];
+     177     1525464 :     dqt[1](0,i) = pref2*quat_conj[i];
+     178             :     //addDerivativeOnVectorArgument( false, 0, i, index1, conj*pref*bond[i], myvals );
+     179             :     //addDerivativeOnVectorArgument( false, 0, 4+i, ind2, conj*pref*quat[i], myvals );
+     180             :   }
+     181             :   //i component
+     182             :   pref=1;
+     183             :   conj=1;
+     184             :   pref2=1;
+     185             : 
+     186     1906830 :   for (unsigned i=0; i<4; i++) {
+     187     1525464 :     if(i==3) pref=-1;
+     188             :     else pref=1;
+     189     1525464 :     if(i==2) pref2=-1;
+     190             :     else pref2=1;
+     191     1525464 :     if (i>0) conj=-1;
+     192             : 
+     193     1525464 :     quatTemp[1]+=pref*quat_conj[i]*bond[(5-i)%4];
+     194     1525464 :     dqt[0](1,i) =conj*pref*bond[(5-i)%4];
+     195     1525464 :     dqt[1](1,i) = pref2*quat_conj[(5-i)%4];
+     196             :     //addDerivativeOnVectorArgument( false, 1, i, index1, conj*pref*bond[(5-i)%4], myvals );
+     197             :     //addDerivativeOnVectorArgument( false, 1, 4+i, ind2, conj*pref*quat[i], myvals );
+     198             :   }
+     199             : 
+     200             :   //j component
+     201             :   pref=1;
+     202             :   pref2=1;
+     203             :   conj=1;
+     204             : 
+     205     1906830 :   for (unsigned i=0; i<4; i++) {
+     206     1525464 :     if(i==1) pref=-1;
+     207             :     else pref=1;
+     208     1525464 :     if (i==3) pref2=-1;
+     209             :     else pref2=1;
+     210     1525464 :     if (i>0) conj=-1;
+     211             : 
+     212     1525464 :     quatTemp[2]+=pref*quat_conj[i]*bond[(i+2)%4];
+     213     1525464 :     dqt[0](2,i)=conj*pref*bond[(i+2)%4];
+     214     1525464 :     dqt[1](2,i)=pref2*quat_conj[(i+2)%4];
+     215             :     //addDerivativeOnVectorArgument( false, 2, i, index1, conj*pref*bond[(i+2)%4], myvals );
+     216             :     //addDerivativeOnVectorArgument( false, 2, 4+i, ind2, conj*pref*quat[i], myvals );
+     217             :   }
+     218             : 
+     219             :   //k component
+     220             :   pref=1;
+     221             :   pref2=1;
+     222             :   conj=1;
+     223             : 
+     224     1906830 :   for (unsigned i=0; i<4; i++) {
+     225     1525464 :     if(i==2) pref=-1;
+     226             :     else pref=1;
+     227     1525464 :     if(i==1) pref2=-1;
+     228             :     else pref2=1;
+     229     1525464 :     if(i>0) conj=-1;
+     230     1525464 :     quatTemp[3]+=pref*quat_conj[i]*bond[(3-i)];
+     231     1525464 :     dqt[0](3,i)=conj*pref*bond[3-i];
+     232     1525464 :     dqt[1](3,i)= pref2*quat_conj[3-i];
+     233             :     //addDerivativeOnVectorArgument( false, 3, i, index1, conj*pref*bond[3-i], myvals );
+     234             :     //addDerivativeOnVectorArgument( false, 3, 4+i, ind2, conj*pref*quat[i], myvals );
+     235             : 
+     236             :   }
+     237             : 
+     238             : 
+     239             : //now previous ^ product times quat again, not conjugated
+     240             :   //real part of q1*q2
+     241      381366 :   double tempDot=0,wf=0,xf=0,yf=0,zf=0;
+     242             :   pref=1;
+     243             :   pref2=1;
+     244     1906830 :   for(unsigned i=0; i<4; ++i) {
+     245     1525464 :     if( i>0 ) {pref=-1; pref2=-1;}
+     246     1525464 :     myvals.addValue( getConstPntrToComponent(0)->getPositionInStream(), normFac*pref*quatTemp[i]*quat[i] );
+     247             :     wf+=normFac*pref*quatTemp[i]*quat[i];
+     248     1525464 :     if( doNotCalculateDerivatives() ) continue ;
+     249     1525464 :     tempDot=(dotProduct(Vector4d(quat[0],-quat[1],-quat[2],-quat[3]), dqt[0].getCol(i)) + pref2*quatTemp[i])*normFac;
+     250     1525464 :     addDerivativeOnVectorArgument( stored[i], 0, i,   index1, tempDot, myvals);
+     251             :   }
+     252             :   //had to split because bond's derivatives depend on the value of the overall quaternion component
+     253             :   //addDerivativeOnMatrixArgument( false, 0, 4, index1, ind2, 0.0, myvals );
+     254     1906830 :   for(unsigned i=0; i<4; ++i) {
+     255     1525464 :     tempDot=dotProduct(Vector4d(quat[0],-quat[1],-quat[2],-quat[3]), dqt[1].getCol(i))*normFac;
+     256     1525464 :     if (i!=0 )addDerivativeOnMatrixArgument( stored[4+i], 0, 4+i, index1, ind2, tempDot, myvals );
+     257      381366 :     else addDerivativeOnMatrixArgument( stored[4+i], 0, 4+i, index1, ind2, 0.0, myvals );
+     258             :   }
+     259             : // for (unsigned i=0; i<4; ++i) {
+     260             : //myvals.addValue( getConstPntrToComponent(0)->getPositionInStream(), 0.0 );
+     261             : //if( doNotCalculateDerivatives() ) continue ;
+     262             : //addDerivativeOnVectorArgument( false, 0, i,   index1, 0.0, myvals);
+     263             : //addDerivativeOnVectorArgument( false, 0, 4+i, ind2, 0.0 ,  myvals);
+     264             : //  }
+     265             : //the w component should always be zero, barring some catastrophe, but we calculate it out anyway
+     266             : 
+     267             :   //i component
+     268             :   pref=1;
+     269             :   pref2=1;
+     270     1906830 :   for (unsigned i=0; i<4; i++) {
+     271     1525464 :     if(i==3) pref=-1;
+     272             :     else pref=1;
+     273     1525464 :     myvals.addValue( getConstPntrToComponent(1)->getPositionInStream(), normFac*pref*quatTemp[i]*quat[(5-i)%4]);
+     274     1525464 :     xf+=normFac*pref*quatTemp[i]*quat[(5-i)%4];
+     275     1525464 :     if(i==2) pref2=-1;
+     276             :     else pref2=1;
+     277     1525464 :     if( doNotCalculateDerivatives() ) continue ;
+     278     1525464 :     tempDot=(dotProduct(Vector4d(quat[1],quat[0],quat[3],-quat[2]), dqt[0].getCol(i)) + pref2*quatTemp[(5-i)%4])*normFac;
+     279     1525464 :     addDerivativeOnVectorArgument( stored[i], 1, i,   index1, tempDot, myvals);
+     280             :   }
+     281             :   //addDerivativeOnMatrixArgument( false, 1, 4, index1, ind2, 0.0, myvals );
+     282             : 
+     283     1906830 :   for(unsigned i=0; i<4; ++i) {
+     284     1525464 :     tempDot=dotProduct(Vector4d(quat[1],quat[0],quat[3],-quat[2]), dqt[1].getCol(i))*normFac;
+     285     1525464 :     if (i!=0) addDerivativeOnMatrixArgument( stored[4+i], 1, 4+i, index1, ind2, tempDot+(-bond[i]*normFac*normFac*xf), myvals );
+     286      381366 :     else  addDerivativeOnMatrixArgument( stored[4+i], 1, 4+i, index1, ind2, 0.0, myvals );
+     287             : 
+     288             :   }
+     289             : 
+     290             : 
+     291             :   //j component
+     292             :   pref=1;
+     293             :   pref2=1;
+     294     1906830 :   for (unsigned i=0; i<4; i++) {
+     295     1525464 :     if(i==1) pref=-1;
+     296             :     else pref=1;
+     297     1525464 :     if (i==3) pref2=-1;
+     298             :     else pref2=1;
+     299             : 
+     300     1525464 :     myvals.addValue( getConstPntrToComponent(2)->getPositionInStream(), normFac*pref*quatTemp[i]*quat[(i+2)%4]);
+     301     1525464 :     yf+=normFac*pref*quatTemp[i]*quat[(i+2)%4];
+     302     1525464 :     if( doNotCalculateDerivatives() ) continue ;
+     303     1525464 :     tempDot=(dotProduct(Vector4d(quat[2],-quat[3],quat[0],quat[1]), dqt[0].getCol(i)) + pref2*quatTemp[(i+2)%4])*normFac;
+     304     1525464 :     addDerivativeOnVectorArgument( stored[i], 2, i,   index1, tempDot, myvals);
+     305             :   }
+     306             :   //    addDerivativeOnMatrixArgument( false, 2, 4, index1, ind2,0.0   , myvals );
+     307             : 
+     308     1906830 :   for(unsigned i=0; i<4; ++i) {
+     309     1525464 :     tempDot=dotProduct(Vector4d(quat[2],-quat[3],quat[0],quat[1]), dqt[1].getCol(i))*normFac;
+     310     1525464 :     if (i!=0) addDerivativeOnMatrixArgument( stored[4+i], 2, 4+i, index1, ind2, tempDot+(-bond[i]*normFac*normFac*yf), myvals );
+     311      381366 :     else  addDerivativeOnMatrixArgument( stored[4+i], 2, 4+i, index1, ind2, 0.0, myvals );
+     312             : 
+     313             : 
+     314             :   }
+     315             : 
+     316             :   //k component
+     317             :   pref=1;
+     318             :   pref2=1;
+     319     1906830 :   for (unsigned i=0; i<4; i++) {
+     320     1525464 :     if(i==2) pref=-1;
+     321             :     else pref=1;
+     322     1525464 :     if(i==1) pref2=-1;
+     323             :     else pref2=1;
+     324             : 
+     325     1525464 :     myvals.addValue( getConstPntrToComponent(3)->getPositionInStream(), normFac*pref*quatTemp[i]*quat[(3-i)]);
+     326     1525464 :     zf+=normFac*pref*quatTemp[i]*quat[(3-i)];
+     327     1525464 :     if( doNotCalculateDerivatives() ) continue ;
+     328     1525464 :     tempDot=(dotProduct(Vector4d(quat[3],quat[2],-quat[1],quat[0]), dqt[0].getCol(i)) + pref2*quatTemp[(3-i)])*normFac;
+     329     1525464 :     addDerivativeOnVectorArgument( stored[i], 3, i,   index1, tempDot, myvals);
+     330             :   }
+     331             :   //addDerivativeOnMatrixArgument( false, 3, 4, index1, ind2,  0.0 , myvals );
+     332             : 
+     333     1906830 :   for(unsigned i=0; i<4; ++i) {
+     334     1525464 :     tempDot=dotProduct(Vector4d(quat[3],quat[2],-quat[1],quat[0]), dqt[1].getCol(i))*normFac;
+     335     1525464 :     if (i!=0) addDerivativeOnMatrixArgument( stored[4+i], 3, 4+i, index1, ind2, tempDot+(-bond[i]*normFac*normFac*zf), myvals );
+     336      381366 :     else addDerivativeOnMatrixArgument( stored[4+i], 3, 4+i, index1, ind2, 0.0, myvals );
+     337             : 
+     338             : 
+     339             :   }
+     340      381366 :   if( doNotCalculateDerivatives() ) return ;
+     341             : 
+     342     1906830 :   for(unsigned outcomp=0; outcomp<4; ++outcomp) {
+     343     1525464 :     unsigned ostrn = getConstPntrToComponent(outcomp)->getPositionInStream();
+     344     7627320 :     for(unsigned i=4; i<8; ++i) {
+     345             :       bool found=false;
+     346     6101856 :       for(unsigned j=4; j<i; ++j) {
+     347     4576392 :         if( arg_deriv_starts[i]==arg_deriv_starts[j] ) { found=true; break; }
+     348             :       }
+     349     6101856 :       if( found || !stored[i] ) continue;
+     350             : 
+     351             :       unsigned istrn = getPntrToArgument(i)->getPositionInStream();
+     352    24407424 :       for(unsigned k=0; k<myvals.getNumberActive(istrn); ++k) {
+     353    22881960 :         unsigned kind=myvals.getActiveIndex(istrn,k); myvals.updateIndex( ostrn, kind );
+     354             :       }
+     355             :     }
+     356             :   }
+     357             : }
+     358             : 
+     359        1614 : void QuaternionBondProductMatrix::runEndOfRowJobs( const unsigned& ival, const std::vector<unsigned> & indices, MultiValue& myvals ) const {
+     360        1614 :   if( doNotCalculateDerivatives() || !matrixChainContinues() ) return ;
+     361             : 
+     362        8070 :   for(unsigned j=0; j<getNumberOfComponents(); ++j) {
+     363        6456 :     unsigned nmat = getConstPntrToComponent(j)->getPositionInMatrixStash(), nmat_ind = myvals.getNumberOfMatrixRowDerivatives( nmat );
+     364             :     std::vector<unsigned>& matrix_indices( myvals.getMatrixRowDerivativeIndices( nmat ) ); unsigned ntwo_atoms = myvals.getSplitIndex();
+     365             :     // Quaternion
+     366       32280 :     for(unsigned k=0; k<4; ++k) { matrix_indices[nmat_ind] = arg_deriv_starts[k] + ival; nmat_ind++; }
+     367             :     // Loop over row of matrix
+     368       32280 :     for(unsigned n=4; n<8; ++n) {
+     369             :       bool found=false;
+     370       25824 :       for(unsigned k=4; k<n; ++k) {
+     371       19368 :         if( arg_deriv_starts[k]==arg_deriv_starts[n] ) { found=true; break; }
+     372             :       }
+     373       25824 :       if( found ) continue;
+     374             :       unsigned istrn = getPntrToArgument(n)->getPositionInMatrixStash();
+     375             :       std::vector<unsigned>& imat_indices( myvals.getMatrixRowDerivativeIndices( istrn ) );
+     376     4660320 :       for(unsigned k=0; k<myvals.getNumberOfMatrixRowDerivatives( istrn ); ++k) matrix_indices[nmat_ind + k] = arg_deriv_starts[n] + imat_indices[k];
+     377        6456 :       nmat_ind += myvals.getNumberOfMatrixRowDerivatives( getPntrToArgument(4)->getPositionInMatrixStash() );
+     378             :     }
+     379             :     myvals.setNumberOfMatrixRowDerivatives( nmat, nmat_ind );
+     380             :   }
+     381             : }
+     382             : 
+     383             : }
+     384             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystdistrib/QuaternionProductMatrix.cpp.func-sort-c.html b/coverage/crystdistrib/QuaternionProductMatrix.cpp.func-sort-c.html new file mode 100644 index 000000000000..31f27717eee7 --- /dev/null +++ b/coverage/crystdistrib/QuaternionProductMatrix.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - crystdistrib/QuaternionProductMatrix.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystdistrib - QuaternionProductMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:8585100.0 %
Date:2024-04-19 12:12:35Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12crystdistrib23QuaternionProductMatrixC2ERKNS_13ActionOptionsE0
_ZN4PLMD12crystdistrib23QuaternionProductMatrixC1ERKNS_13ActionOptionsE6
_ZN4PLMD12crystdistrib23QuaternionProductMatrix16registerKeywordsERNS_8KeywordsE8
_ZN4PLMD12crystdistrib23QuaternionProductMatrix22getNumberOfDerivativesEv16
_ZNK4PLMD12crystdistrib23QuaternionProductMatrix12setupForTaskERKjRSt6vectorIjSaIjEERNS_10MultiValueE18
_ZNK4PLMD12crystdistrib23QuaternionProductMatrix18getNumberOfColumnsEv48
_ZNK4PLMD12crystdistrib23QuaternionProductMatrix15runEndOfRowJobsERKjRKSt6vectorIjSaIjEERNS_10MultiValueE2028
_ZNK4PLMD12crystdistrib23QuaternionProductMatrix11performTaskERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjSB_RNS_10MultiValueE399598
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystdistrib/QuaternionProductMatrix.cpp.func.html b/coverage/crystdistrib/QuaternionProductMatrix.cpp.func.html new file mode 100644 index 000000000000..70bbc98c3893 --- /dev/null +++ b/coverage/crystdistrib/QuaternionProductMatrix.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - crystdistrib/QuaternionProductMatrix.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystdistrib - QuaternionProductMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:8585100.0 %
Date:2024-04-19 12:12:35Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12crystdistrib23QuaternionProductMatrix16registerKeywordsERNS_8KeywordsE8
_ZN4PLMD12crystdistrib23QuaternionProductMatrix22getNumberOfDerivativesEv16
_ZN4PLMD12crystdistrib23QuaternionProductMatrixC1ERKNS_13ActionOptionsE6
_ZN4PLMD12crystdistrib23QuaternionProductMatrixC2ERKNS_13ActionOptionsE0
_ZNK4PLMD12crystdistrib23QuaternionProductMatrix11performTaskERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjSB_RNS_10MultiValueE399598
_ZNK4PLMD12crystdistrib23QuaternionProductMatrix12setupForTaskERKjRSt6vectorIjSaIjEERNS_10MultiValueE18
_ZNK4PLMD12crystdistrib23QuaternionProductMatrix15runEndOfRowJobsERKjRKSt6vectorIjSaIjEERNS_10MultiValueE2028
_ZNK4PLMD12crystdistrib23QuaternionProductMatrix18getNumberOfColumnsEv48
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystdistrib/QuaternionProductMatrix.cpp.gcov.html b/coverage/crystdistrib/QuaternionProductMatrix.cpp.gcov.html new file mode 100644 index 000000000000..b54e327b4026 --- /dev/null +++ b/coverage/crystdistrib/QuaternionProductMatrix.cpp.gcov.html @@ -0,0 +1,274 @@ + + + + + + + + LCOV - plumed test coverage - crystdistrib/QuaternionProductMatrix.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystdistrib - QuaternionProductMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:8585100.0 %
Date:2024-04-19 12:12:35Functions: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 "adjmat/ActionWithMatrix.h"
+      23             : #include "core/ActionRegister.h"
+      24             : 
+      25             : //+PLUMEDOC MCOLVAR QUATERNION_PRODUCT_MATRIX
+      26             : /*
+      27             : Calculate the outer product matrix from two vectors of quaternions
+      28             : 
+      29             : \par Examples
+      30             : 
+      31             : */
+      32             : //+ENDPLUMEDOC
+      33             : 
+      34             : namespace PLMD {
+      35             : namespace crystdistrib {
+      36             : 
+      37             : class QuaternionProductMatrix : public adjmat::ActionWithMatrix {
+      38             : private:
+      39             :   unsigned nderivatives;
+      40             : public:
+      41             :   static void registerKeywords( Keywords& keys );
+      42             :   explicit QuaternionProductMatrix(const ActionOptions&);
+      43             :   unsigned getNumberOfDerivatives();
+      44          48 :   unsigned getNumberOfColumns() const override { return getConstPntrToComponent(0)->getShape()[1]; }
+      45             :   void setupForTask( const unsigned& task_index, std::vector<unsigned>& indices, MultiValue& myvals ) const ;
+      46             :   void performTask( const std::string& controller, const unsigned& index1, const unsigned& index2, MultiValue& myvals ) const override;
+      47             :   void runEndOfRowJobs( const unsigned& ival, const std::vector<unsigned> & indices, MultiValue& myvals ) const override ;
+      48             : };
+      49             : 
+      50             : PLUMED_REGISTER_ACTION(QuaternionProductMatrix,"QUATERNION_PRODUCT_MATRIX")
+      51             : 
+      52           8 : void QuaternionProductMatrix::registerKeywords( Keywords& keys ) {
+      53           8 :   adjmat::ActionWithMatrix::registerKeywords(keys); keys.use("ARG");
+      54          16 :   keys.addOutputComponent("w","default","the real component of quaternion");
+      55          16 :   keys.addOutputComponent("i","default","the i component of the quaternion");
+      56          16 :   keys.addOutputComponent("j","default","the j component of the quaternion");
+      57          16 :   keys.addOutputComponent("k","default","the k component of the quaternion");
+      58           8 : }
+      59             : 
+      60           6 : QuaternionProductMatrix::QuaternionProductMatrix(const ActionOptions&ao):
+      61             :   Action(ao),
+      62           6 :   ActionWithMatrix(ao)
+      63             : {
+      64           6 :   if( getNumberOfArguments()!=8 ) error("should be eight arguments to this action.  Four quaternions for each set of atoms.  You can repeat actions");
+      65           6 :   unsigned nquat = getPntrToArgument(0)->getNumberOfValues();
+      66          54 :   for(unsigned i=0; i<8; ++i) {
+      67          48 :     Value* myarg=getPntrToArgument(i); if( i==4 ) nquat = getPntrToArgument(i)->getNumberOfValues();
+      68          48 :     if( myarg->getRank()!=1 ) error("all arguments to this action should be vectors");
+      69          48 :     if( (myarg->getPntrToAction())->getName()!="QUATERNION_VECTOR" ) error("all arguments to this action should be quaternions");
+      70          48 :     std::string mylab=getPntrToArgument(i)->getName(); std::size_t dot=mylab.find_first_of(".");
+      71          72 :     if( (i==0 || i==4) && mylab.substr(dot+1)!="w" ) error("quaternion arguments are in wrong order");
+      72          72 :     if( (i==1 || i==5) && mylab.substr(dot+1)!="i" ) error("quaternion arguments are in wrong order");
+      73          72 :     if( (i==2 || i==6) && mylab.substr(dot+1)!="j" ) error("quaternion arguments are in wrong order");
+      74          72 :     if( (i==3 || i==7) && mylab.substr(dot+1)!="k" ) error("quaternion arguments are in wrong order");
+      75             :   }
+      76           6 :   std::vector<unsigned> shape(2); shape[0]=getPntrToArgument(0)->getShape()[0]; shape[1]=getPntrToArgument(4)->getShape()[0];
+      77          12 :   addComponent( "w", shape ); componentIsNotPeriodic("w");
+      78          12 :   addComponent( "i", shape ); componentIsNotPeriodic("i");
+      79          12 :   addComponent( "j", shape ); componentIsNotPeriodic("j");
+      80          12 :   addComponent( "k", shape ); componentIsNotPeriodic("k");
+      81           6 :   nderivatives = buildArgumentStore(0);
+      82           6 : }
+      83             : 
+      84          16 : unsigned QuaternionProductMatrix::getNumberOfDerivatives() {
+      85          16 :   return nderivatives;
+      86             : }
+      87             : 
+      88          18 : void QuaternionProductMatrix::setupForTask( const unsigned& task_index, std::vector<unsigned>& indices, MultiValue& myvals ) const {
+      89          18 :   unsigned start_n = getPntrToArgument(0)->getShape()[0], size_v = getPntrToArgument(4)->getShape()[0];
+      90          18 :   if( indices.size()!=size_v+1 ) indices.resize( size_v+1 );
+      91          63 :   for(unsigned i=0; i<size_v; ++i) indices[i+1] = start_n + i;
+      92             :   myvals.setSplitIndex( size_v + 1 );
+      93          18 : }
+      94             : 
+      95      399598 : void QuaternionProductMatrix::performTask( const std::string& controller, const unsigned& index1, const unsigned& index2, MultiValue& myvals ) const {
+      96      399598 :   unsigned ostrn, ind2=index2;
+      97      399598 :   if( index2>=getPntrToArgument(0)->getShape()[0] ) ind2 = index2 - getPntrToArgument(0)->getShape()[0];
+      98             : 
+      99      399598 :   std::vector<double> quat1(4), quat2(4);
+     100             : 
+     101             :   // Retrieve the first quaternion
+     102     1997990 :   for(unsigned i=0; i<4; ++i) quat1[i] = getArgumentElement( i, index1, myvals );
+     103             :   // Retrieve the second quaternion
+     104     1997990 :   for(unsigned i=0; i<4; ++i) quat2[i] = getArgumentElement( 4+i, ind2, myvals );
+     105             : 
+     106             :   //make q1 the conjugate
+     107      399598 :   quat1[1] *= -1;
+     108      399598 :   quat1[2] *= -1;
+     109      399598 :   quat1[3] *= -1;
+     110             : 
+     111             : 
+     112             :   double pref=1;
+     113             :   double pref2=1;
+     114             :   double conj=1;
+     115             : //real part of q1*q2
+     116     1997990 :   for(unsigned i=0; i<4; ++i) {
+     117     1598392 :     if( i>0 ) {pref=-1; pref2=-1;}
+     118     1598392 :     myvals.addValue( getConstPntrToComponent(0)->getPositionInStream(), pref*quat1[i]*quat2[i] );
+     119     1598392 :     if( doNotCalculateDerivatives() ) continue ;
+     120      759240 :     if (i>0) conj=-1;
+     121      759240 :     addDerivativeOnVectorArgument( false, 0, i, index1, conj*pref*quat2[i], myvals );
+     122      759240 :     addDerivativeOnVectorArgument( false, 0, 4+i, ind2, pref2*quat1[i], myvals );
+     123             :   }
+     124             :   //i component
+     125             :   pref=1;
+     126             :   conj=1;
+     127             :   pref2=1;
+     128     1997990 :   for (unsigned i=0; i<4; i++) {
+     129     1598392 :     if(i==3) pref=-1;
+     130             :     else pref=1;
+     131     1598392 :     if(i==2) pref2=-1;
+     132             :     else pref2=1;
+     133     1598392 :     myvals.addValue( getConstPntrToComponent(1)->getPositionInStream(), pref*quat1[i]*quat2[(5-i)%4]);
+     134     1598392 :     if( doNotCalculateDerivatives() ) continue ;
+     135      759240 :     if (i>0) conj=-1;
+     136      759240 :     addDerivativeOnVectorArgument( false, 1, i, index1, conj*pref*quat2[(5-i)%4], myvals );
+     137      759240 :     addDerivativeOnVectorArgument( false, 1, 4+i, ind2, pref2*quat1[(5-i)%4], myvals );
+     138             :   }
+     139             : 
+     140             :   //j component
+     141             :   pref=1;
+     142             :   conj=1;
+     143             :   pref2=1;
+     144     1997990 :   for (unsigned i=0; i<4; i++) {
+     145     1598392 :     if(i==1) pref=-1;
+     146             :     else pref=1;
+     147     1598392 :     if (i==3) pref2=-1;
+     148             :     else pref2=1;
+     149     1598392 :     myvals.addValue( getConstPntrToComponent(2)->getPositionInStream(), pref*quat1[i]*quat2[(i+2)%4]);
+     150     1598392 :     if( doNotCalculateDerivatives() ) continue ;
+     151      759240 :     if (i>0) conj=-1;
+     152      759240 :     addDerivativeOnVectorArgument( false, 2, i, index1, conj*pref*quat2[(i+2)%4], myvals );
+     153      759240 :     addDerivativeOnVectorArgument( false, 2, 4+i, ind2, pref2*quat1[(i+2)%4], myvals );
+     154             :   }
+     155             : 
+     156             :   //k component
+     157             :   pref=1;
+     158             :   conj=1;
+     159             :   pref2=1;
+     160     1997990 :   for (unsigned i=0; i<4; i++) {
+     161     1598392 :     if(i==2) pref=-1;
+     162             :     else pref=1;
+     163     1598392 :     if(i==1) pref2=-1;
+     164             :     else pref2=1;
+     165     1598392 :     myvals.addValue( getConstPntrToComponent(3)->getPositionInStream(), pref*quat1[i]*quat2[(3-i)]);
+     166     1598392 :     if( doNotCalculateDerivatives() ) continue ;
+     167      759240 :     if (i>0) conj=-1;
+     168      759240 :     addDerivativeOnVectorArgument( false, 3, i, index1, conj*pref*quat2[3-i], myvals );
+     169      759240 :     addDerivativeOnVectorArgument( false, 3, 4+i, ind2, pref2*quat1[3-i], myvals );
+     170             : 
+     171             :   }
+     172             : 
+     173             : 
+     174      399598 : }
+     175             : 
+     176        2028 : void QuaternionProductMatrix::runEndOfRowJobs( const unsigned& ival, const std::vector<unsigned> & indices, MultiValue& myvals ) const {
+     177        2028 :   if( doNotCalculateDerivatives() || !matrixChainContinues() ) return ;
+     178             : 
+     179        3915 :   for(unsigned j=0; j<getNumberOfComponents(); ++j) {
+     180        3132 :     unsigned nmat = getConstPntrToComponent(j)->getPositionInMatrixStash(), nmat_ind = myvals.getNumberOfMatrixRowDerivatives( nmat );
+     181             :     std::vector<unsigned>& matrix_indices( myvals.getMatrixRowDerivativeIndices( nmat ) ); unsigned ntwo_atoms = myvals.getSplitIndex();
+     182             :     // Quaternion for first molecule
+     183       15660 :     unsigned base = 0; for(unsigned k=0; k<4; ++k) { matrix_indices[nmat_ind] = base + ival; base += getPntrToArgument(k)->getShape()[0]; nmat_ind++; }
+     184             :     // Loop over row of matrix
+     185      762372 :     for(unsigned i=1; i<ntwo_atoms; ++i) {
+     186      759240 :       unsigned ind2 = indices[i]; if( ind2>=getPntrToArgument(0)->getShape()[0] ) ind2 = indices[i] - getPntrToArgument(0)->getShape()[0];
+     187      759240 :       base = 4*getPntrToArgument(0)->getShape()[0];
+     188             :       // Quaternion of second molecule
+     189     3796200 :       for(unsigned k=0; k<4; ++k) { matrix_indices[nmat_ind] = base + ind2; base += getPntrToArgument(4+k)->getShape()[0]; nmat_ind++; }
+     190             :     }
+     191             :     myvals.setNumberOfMatrixRowDerivatives( nmat, nmat_ind );
+     192             :   }
+     193             : 
+     194             : }
+     195             : 
+     196             : }
+     197             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystdistrib/RopsShortcut.cpp.func-sort-c.html b/coverage/crystdistrib/RopsShortcut.cpp.func-sort-c.html new file mode 100644 index 000000000000..9b91cd570a96 --- /dev/null +++ b/coverage/crystdistrib/RopsShortcut.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - crystdistrib/RopsShortcut.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystdistrib - RopsShortcut.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:505394.3 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12crystdistrib12RopsShortcutC2ERKNS_13ActionOptionsE0
_ZN4PLMD12crystdistrib12RopsShortcutC1ERKNS_13ActionOptionsE1
_ZN4PLMD12crystdistrib12RopsShortcut16registerKeywordsERNS_8KeywordsE3
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystdistrib/RopsShortcut.cpp.func.html b/coverage/crystdistrib/RopsShortcut.cpp.func.html new file mode 100644 index 000000000000..e7a86b89f224 --- /dev/null +++ b/coverage/crystdistrib/RopsShortcut.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - crystdistrib/RopsShortcut.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystdistrib - RopsShortcut.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:505394.3 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12crystdistrib12RopsShortcut16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD12crystdistrib12RopsShortcutC1ERKNS_13ActionOptionsE1
_ZN4PLMD12crystdistrib12RopsShortcutC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystdistrib/RopsShortcut.cpp.gcov.html b/coverage/crystdistrib/RopsShortcut.cpp.gcov.html new file mode 100644 index 000000000000..2934ca631378 --- /dev/null +++ b/coverage/crystdistrib/RopsShortcut.cpp.gcov.html @@ -0,0 +1,223 @@ + + + + + + + + LCOV - plumed test coverage - crystdistrib/RopsShortcut.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystdistrib - RopsShortcut.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:505394.3 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) crystdistrib 2023-2023 The code team
+       3             :    (see the PEOPLE-crystdistrib file at the root of this folder for a list of names)
+       4             : 
+       5             :    This file is part of crystdistrib code module.
+       6             : 
+       7             :    The crystdistrib code module is free software: you can redistribute it and/or modify
+       8             :    it under the terms of the GNU Lesser General Public License as published by
+       9             :    the Free Software Foundation, either version 3 of the License, or
+      10             :    (at your option) any later version.
+      11             : 
+      12             :    The crystdistrib code module is distributed in the hope that it will be useful,
+      13             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      14             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      15             :    GNU Lesser General Public License for more details.
+      16             : 
+      17             :    You should have received a copy of the GNU Lesser General Public License
+      18             :    along with the crystdistrib code module.  If not, see <http://www.gnu.org/licenses/>.
+      19             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      20             : #include "core/ActionShortcut.h"
+      21             : #include "core/ActionRegister.h"
+      22             : #include "core/PlumedMain.h"
+      23             : #include "core/ActionSet.h"
+      24             : #include "core/ActionWithValue.h"
+      25             : #include "tools/IFile.h"
+      26             : 
+      27             : namespace PLMD {
+      28             : namespace crystdistrib {
+      29             : 
+      30             : //+PLUMEDOC COLVAR ROPS
+      31             : /*
+      32             : Calculate the ROPS order parameter
+      33             : 
+      34             : \par Examples
+      35             : 
+      36             : */
+      37             : //+ENDPLUMEDOC
+      38             : 
+      39             : class RopsShortcut : public ActionShortcut {
+      40             : public:
+      41             :   static void registerKeywords( Keywords& keys );
+      42             :   explicit RopsShortcut(const ActionOptions&);
+      43             : };
+      44             : 
+      45             : PLUMED_REGISTER_ACTION(RopsShortcut,"ROPS")
+      46             : 
+      47           3 : void RopsShortcut::registerKeywords( Keywords& keys ) {
+      48           3 :   ActionShortcut::registerKeywords( keys );
+      49           6 :   keys.add("atoms","SPECIES","this keyword is used for colvars such as coordination number. In that context it specifies that plumed should calculate "
+      50             :            "one coordination number for each of the atoms specified.  Each of these coordination numbers specifies how many of the "
+      51             :            "other specified atoms are within a certain cutoff of the central atom.  You can specify the atoms here as another multicolvar "
+      52             :            "action or using a MultiColvarFilter or ActionVolume action.  When you do so the quantity is calculated for those atoms specified "
+      53             :            "in the previous multicolvar.  This is useful if you would like to calculate the Steinhardt parameter for those atoms that have a "
+      54             :            "coordination number more than four for example");
+      55           6 :   keys.add("atoms-2","SPECIESA","this keyword is used for colvars such as the coordination number.  In that context it species that plumed should calculate "
+      56             :            "one coordination number for each of the atoms specified in SPECIESA.  Each of these cooordination numbers specifies how many "
+      57             :            "of the atoms specifies using SPECIESB is within the specified cutoff.  As with the species keyword the input can also be specified "
+      58             :            "using the label of another multicolvar");
+      59           6 :   keys.add("atoms-2","SPECIESB","this keyword is used for colvars such as the coordination number.  It must appear with SPECIESA.  For a full explanation see "
+      60             :            "the documentation for that keyword");
+      61           6 :   keys.add("compulsory","QUATERNIONS","the label of the action that computes the quaternions that should be used");
+      62           6 :   keys.add("compulsory","KERNELFILE_DOPS","the file containing the list of kernel parameters.  We expect h, mu and sigma parameters for a 1D Gaussian kernel of the form h*exp(-(x-mu)^2/2sigma^2)");
+      63           6 :   keys.add("compulsory","KERNELFILE_ROPS","the file containing the list of kernel parameters.  We expect the normalization factor (height), concentration parameter (kappa), and 4 quaternion pieces of the mean for a bipolar watson distribution (mu_w,mu_i,mu_j,mu_k)): (h*exp(kappa*dot(q_mean,q))), where dot is the dot product ");
+      64           6 :   keys.add("compulsory", "CUTOFF", "cutoff for the distance matrix");
+      65             : //  keys.add("compulsory","SWITCH","the switching function that acts on the distances between points)");
+      66           6 :   keys.needsAction("DISTANCE_MATRIX"); keys.needsAction("QUATERNION_PRODUCT_MATRIX");
+      67           9 :   keys.needsAction("ONES"); keys.needsAction("CUSTOM"); keys.needsAction("MATRIX_VECTOR_PRODUCT");
+      68           3 : }
+      69             : 
+      70           1 : RopsShortcut::RopsShortcut(const ActionOptions&ao):
+      71             :   Action(ao),
+      72           1 :   ActionShortcut(ao)
+      73             : {
+      74             :   // Open a file and read in the kernels
+      75             :   double h_dops,h_rops; std::string kfunc, kfunc_dops,kfunc_rops,fname_dops,fname_rops;
+      76           3 :   parse("KERNELFILE_DOPS",fname_dops); parse("KERNELFILE_ROPS",fname_rops); IFile ifile_dops, ifile_rops; ifile_dops.open(fname_dops); ifile_rops.open(fname_rops);
+      77          10 :   for(unsigned k=0;; ++k) {
+      78          21 :     if( !ifile_dops.scanField("height",h_dops) || !ifile_rops.scanField("height",h_rops) ) break;//checks eof
+      79          30 :     std::string ktype_dops, ktype_rops;  ifile_dops.scanField("kerneltype",ktype_dops); ifile_rops.scanField("kerneltype",ktype_rops);
+      80          10 :     if( ktype_dops!="gaussian" ) error("cannot process kernels of type " + ktype_dops );//straightup error
+      81          10 :     if( ktype_rops!="gaussian" ) error("cannot process kernels of type " + ktype_rops );
+      82             : 
+      83             :     double mu_dops,mu_w, mu_i, mu_j, mu_k; std::string hstr_dops, hstr_rops, smu_dops,smu_w, smu_i, smu_j, smu_k, sigmastr,kappastr;
+      84             : 
+      85             : 
+      86          10 :     Tools::convert( h_dops, hstr_dops );
+      87          10 :     Tools::convert( h_rops, hstr_rops );
+      88             : 
+      89          20 :     ifile_dops.scanField("mu",mu_dops); Tools::convert( mu_dops, smu_dops );
+      90          20 :     ifile_rops.scanField("mu_w",mu_w); Tools::convert( mu_w, smu_w );
+      91          20 :     ifile_rops.scanField("mu_i",mu_i); Tools::convert( mu_i, smu_i );
+      92          20 :     ifile_rops.scanField("mu_j",mu_j); Tools::convert( mu_j, smu_j );
+      93          20 :     ifile_rops.scanField("mu_k",mu_k); Tools::convert( mu_k, smu_k );
+      94             : 
+      95             : 
+      96             :     double sigma,kappa;
+      97          20 :     ifile_dops.scanField("sigma",sigma); Tools::convert( sigma, sigmastr );
+      98          20 :     ifile_rops.scanField("kappa",kappa); Tools::convert( kappa, kappastr );
+      99             : 
+     100             : 
+     101             : 
+     102          10 :     ifile_dops.scanField(); /*if( k==0 )*/ kfunc_dops =  hstr_dops; //else kfunc_dops += "+" + hstr;
+     103          10 :     ifile_rops.scanField(); /*if( k==0 )*/ kfunc_rops =  hstr_rops; //else kfunc_rops += "+" + hstr;
+     104             : 
+     105          20 :     kfunc_rops += "*exp(" + kappastr + "*(w*" + smu_w + "+i*" + smu_i + "+j*" + smu_j + "+k*" + smu_k + ")^2)";
+     106          20 :     kfunc_dops += "*exp(-(x-" + smu_dops +")^2/" + "(2*" + sigmastr +"*" +sigmastr + "))";
+     107          20 :     if (k==0) kfunc = kfunc_dops + "*" + kfunc_rops; else kfunc+= "+" + kfunc_dops + "*" + kfunc_rops;
+     108          10 :   }
+     109             :   std::string sp_str, specA, specB, grpinfo;
+     110             :   double cutoff;
+     111           5 :   parse("SPECIES",sp_str); parse("SPECIESA",specA); parse("SPECIESB",specB); parse("CUTOFF",cutoff);
+     112           1 :   if( sp_str.length()>0 ) {
+     113           2 :     grpinfo="GROUP=" + sp_str;
+     114             :   } else {//not sure how to use this
+     115           0 :     if( specA.length()==0 || specB.length()==0 ) error("no atoms were specified in input use either SPECIES or SPECIESA + SPECIESB");
+     116           0 :     grpinfo="GROUPA=" + specA + " GROUPB=" + specB;
+     117             :   }
+     118           1 :   std::string cutstr; Tools::convert( cutoff, cutstr );
+     119             :   // Setup the contact matrix
+     120             : //  std::string switchstr; parse("SWITCH",switchstr);
+     121           2 :   readInputLine( getShortcutLabel() + "_cmat: DISTANCE_MATRIX  " + grpinfo + " CUTOFF=" + cutstr);
+     122             : 
+     123           1 :   if( specA.length()==0 ) {
+     124           1 :     std::string quatstr; parse("QUATERNIONS",quatstr);
+     125           2 :     readInputLine( getShortcutLabel() + "_quatprod: QUATERNION_PRODUCT_MATRIX ARG=" + quatstr + ".*," + quatstr + ".*" );
+     126             :   }  else {
+     127           0 :     plumed_error();
+     128             :   }
+     129             :   //
+     130           2 :   readInputLine( getShortcutLabel() + "_kfunc: CUSTOM ARG=" + getShortcutLabel() + "_cmat,"+ getShortcutLabel() + "_quatprod.* " + "VAR=x,w,i,j,k PERIODIC=NO FUNC=" + kfunc );
+     131             :   // Element wise product of cmat and kfunc
+     132             : //  readInputLine( getShortcutLabel() + "_kdmat: CUSTOM ARG=" + getShortcutLabel() + "_cmat.w," + getShortcutLabel() + "_kfunc FUNC=x*y PERIODIC=NO");
+     133             :   // Find the number of ones we need to multiply by
+     134           1 :   ActionWithValue* av = plumed.getActionSet().selectWithLabel<ActionWithValue*>( getShortcutLabel() + "_cmat");
+     135           1 :   plumed_assert( av && av->getNumberOfComponents()>0 && (av->copyOutput(0))->getRank()==2 );
+     136           1 :   std::string size; Tools::convert( (av->copyOutput(0))->getShape()[1], size );
+     137           2 :   readInputLine( getShortcutLabel() + "_ones: ONES SIZE=" + size );
+     138             :   //
+     139           2 :   readInputLine( getShortcutLabel() + ": MATRIX_VECTOR_PRODUCT ARG=" + getShortcutLabel() + "_kfunc," + getShortcutLabel() + "_ones");
+     140           2 : }
+     141             : 
+     142             : }
+     143             : }
+     144             : 
+     145             : 
+     146             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystdistrib/index-sort-f.html b/coverage/crystdistrib/index-sort-f.html new file mode 100644 index 000000000000..7f426d4065f6 --- /dev/null +++ b/coverage/crystdistrib/index-sort-f.html @@ -0,0 +1,144 @@ + + + + + + + + LCOV - plumed test coverage - crystdistrib + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystdistribHitTotalCoverage
Test:plumed test coverageLines:51556092.0 %
Date:2024-04-19 12:12:35Functions:253278.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
RopsShortcut.cpp +
94.3%94.3%
+
94.3 %50 / 5366.7 %2 / 3
BopsShortcut.cpp +
94.3%94.3%
+
94.3 %50 / 5366.7 %2 / 3
DopsShortcut.cpp +
94.7%94.7%
+
94.7 %36 / 3866.7 %2 / 3
QuaternionBondProductMatrix.cpp +
96.7%96.7%
+
96.7 %148 / 15375.0 %6 / 8
Quaternion.cpp +
82.0%82.0%
+
82.0 %146 / 17885.7 %6 / 7
QuaternionProductMatrix.cpp +
100.0%
+
100.0 %85 / 8587.5 %7 / 8
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystdistrib/index-sort-l.html b/coverage/crystdistrib/index-sort-l.html new file mode 100644 index 000000000000..9da0d760a2c8 --- /dev/null +++ b/coverage/crystdistrib/index-sort-l.html @@ -0,0 +1,144 @@ + + + + + + + + LCOV - plumed test coverage - crystdistrib + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystdistribHitTotalCoverage
Test:plumed test coverageLines:51556092.0 %
Date:2024-04-19 12:12:35Functions:253278.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Quaternion.cpp +
82.0%82.0%
+
82.0 %146 / 17885.7 %6 / 7
RopsShortcut.cpp +
94.3%94.3%
+
94.3 %50 / 5366.7 %2 / 3
BopsShortcut.cpp +
94.3%94.3%
+
94.3 %50 / 5366.7 %2 / 3
DopsShortcut.cpp +
94.7%94.7%
+
94.7 %36 / 3866.7 %2 / 3
QuaternionBondProductMatrix.cpp +
96.7%96.7%
+
96.7 %148 / 15375.0 %6 / 8
QuaternionProductMatrix.cpp +
100.0%
+
100.0 %85 / 8587.5 %7 / 8
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystdistrib/index.html b/coverage/crystdistrib/index.html new file mode 100644 index 000000000000..7bfdb96345f2 --- /dev/null +++ b/coverage/crystdistrib/index.html @@ -0,0 +1,144 @@ + + + + + + + + LCOV - plumed test coverage - crystdistrib + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystdistribHitTotalCoverage
Test:plumed test coverageLines:51556092.0 %
Date:2024-04-19 12:12:35Functions:253278.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
BopsShortcut.cpp +
94.3%94.3%
+
94.3 %50 / 5366.7 %2 / 3
DopsShortcut.cpp +
94.7%94.7%
+
94.7 %36 / 3866.7 %2 / 3
Quaternion.cpp +
82.0%82.0%
+
82.0 %146 / 17885.7 %6 / 7
QuaternionBondProductMatrix.cpp +
96.7%96.7%
+
96.7 %148 / 15375.0 %6 / 8
QuaternionProductMatrix.cpp +
100.0%
+
100.0 %85 / 8587.5 %7 / 8
RopsShortcut.cpp +
94.3%94.3%
+
94.3 %50 / 5366.7 %2 / 3
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/ArrangePoints.cpp.func-sort-c.html b/coverage/dimred/ArrangePoints.cpp.func-sort-c.html new file mode 100644 index 000000000000..a6af7f6f7b38 --- /dev/null +++ b/coverage/dimred/ArrangePoints.cpp.func-sort-c.html @@ -0,0 +1,117 @@ + + + + + + + + LCOV - plumed test coverage - dimred/ArrangePoints.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - dimred - ArrangePoints.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:17117398.8 %
Date:2024-04-19 12:12:35Functions:91181.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred13ArrangePoints22getNumberOfDerivativesEv0
_ZN4PLMD6dimred13ArrangePointsC2ERKNS_13ActionOptionsE0
_ZN4PLMD6dimred13ArrangePoints5applyEv2
_ZNK4PLMD6dimred13ArrangePoints24recalculateSmacofWeightsERKSt6vectorIdSaIdEERNS0_6SMACOFE2
_ZN4PLMD6dimred13ArrangePointsC1ERKNS_13ActionOptionsE5
_ZN4PLMD6dimred13ArrangePoints16registerKeywordsERNS_8KeywordsE7
_ZN4PLMD6dimred13ArrangePoints8optimizeERSt6vectorIdSaIdEE7
_ZN4PLMD6dimred13ArrangePoints9calculateEv7
_ZNK4PLMD6dimred13ArrangePoints16checkInputMatrixERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjRKSt6vectorIPNS_5ValueESaISE_EE12
_ZN4PLMD6dimred13ArrangePoints19calculateFullStressERKSt6vectorIdSaIdEERS4_1932
_ZN4PLMD6dimred13ArrangePoints15calculateStressERKSt6vectorIdSaIdEERS4_24600
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/ArrangePoints.cpp.func.html b/coverage/dimred/ArrangePoints.cpp.func.html new file mode 100644 index 000000000000..3bf26805fc67 --- /dev/null +++ b/coverage/dimred/ArrangePoints.cpp.func.html @@ -0,0 +1,117 @@ + + + + + + + + LCOV - plumed test coverage - dimred/ArrangePoints.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - dimred - ArrangePoints.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:17117398.8 %
Date:2024-04-19 12:12:35Functions:91181.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred13ArrangePoints15calculateStressERKSt6vectorIdSaIdEERS4_24600
_ZN4PLMD6dimred13ArrangePoints16registerKeywordsERNS_8KeywordsE7
_ZN4PLMD6dimred13ArrangePoints19calculateFullStressERKSt6vectorIdSaIdEERS4_1932
_ZN4PLMD6dimred13ArrangePoints22getNumberOfDerivativesEv0
_ZN4PLMD6dimred13ArrangePoints5applyEv2
_ZN4PLMD6dimred13ArrangePoints8optimizeERSt6vectorIdSaIdEE7
_ZN4PLMD6dimred13ArrangePoints9calculateEv7
_ZN4PLMD6dimred13ArrangePointsC1ERKNS_13ActionOptionsE5
_ZN4PLMD6dimred13ArrangePointsC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6dimred13ArrangePoints16checkInputMatrixERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjRKSt6vectorIPNS_5ValueESaISE_EE12
_ZNK4PLMD6dimred13ArrangePoints24recalculateSmacofWeightsERKSt6vectorIdSaIdEERNS0_6SMACOFE2
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/ArrangePoints.cpp.gcov.html b/coverage/dimred/ArrangePoints.cpp.gcov.html new file mode 100644 index 000000000000..21410ea68028 --- /dev/null +++ b/coverage/dimred/ArrangePoints.cpp.gcov.html @@ -0,0 +1,407 @@ + + + + + + + + LCOV - plumed test coverage - dimred/ArrangePoints.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - dimred - ArrangePoints.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:17117398.8 %
Date:2024-04-19 12:12:35Functions:91181.8 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2020 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received 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/ActionWithArguments.h"
+      24             : #include "core/ActionRegister.h"
+      25             : #include "tools/ConjugateGradient.h"
+      26             : #include "tools/SwitchingFunction.h"
+      27             : #include "gridtools/GridSearch.h"
+      28             : #include "SMACOF.h"
+      29             : 
+      30             : namespace PLMD {
+      31             : namespace dimred {
+      32             : 
+      33             : //+PLUMEDOC DIMRED ARRANGE_POINTS
+      34             : /*
+      35             : Arrange points in a low dimensional space so that the (transformed) distances between points in the low dimensional space match the dissimilarities provided in an input matrix.
+      36             : 
+      37             : \par Examples
+      38             : 
+      39             : */
+      40             : //+ENDPLUMEDOC
+      41             : 
+      42             : class ArrangePoints :
+      43             :   public ActionWithValue,
+      44             :   public ActionWithArguments {
+      45             : private:
+      46             :   unsigned dimout, maxiter, ncycles, current_index;
+      47             :   double cgtol, gbuf;
+      48             :   std::vector<unsigned> npoints, nfgrid;
+      49             :   std::vector<double> mypos;
+      50             :   double smacof_tol, smacof_reg;
+      51             :   int dist_target;
+      52             :   enum {conjgrad,pointwise,smacof} mintype;
+      53             :   std::vector<SwitchingFunction> switchingFunction;
+      54             :   void checkInputMatrix( const std::string& key, const unsigned& nvals, const std::vector<Value*>& mat ) const ;
+      55             :   double recalculateSmacofWeights( const std::vector<double>& p, SMACOF& mysmacof ) const ;
+      56             : protected:
+      57             :   double calculateStress( const std::vector<double>& p, std::vector<double>& d );
+      58             :   double calculateFullStress( const std::vector<double>& p, std::vector<double>& d );
+      59             : public:
+      60             :   static void registerKeywords( Keywords& keys );
+      61             :   ArrangePoints( const ActionOptions& );
+      62           0 :   unsigned getNumberOfDerivatives() override { return 0; }
+      63             :   void calculate() override ;
+      64             :   virtual void optimize( std::vector<double>& pos );
+      65           2 :   void apply() override {}
+      66             : };
+      67             : 
+      68             : PLUMED_REGISTER_ACTION(ArrangePoints,"ARRANGE_POINTS")
+      69             : 
+      70           7 : void ArrangePoints::registerKeywords( Keywords& keys ) {
+      71           7 :   Action::registerKeywords( keys ); ActionWithValue::registerKeywords( keys );
+      72           7 :   ActionWithArguments::registerKeywords( keys ); keys.use("ARG");
+      73          14 :   keys.add("numbered","TARGET","the matrix of target quantities that you would like to match");
+      74          14 :   keys.add("numbered","FUNC","a function that is applied on the distances between the points in the low dimensional space");
+      75          14 :   keys.add("numbered","WEIGHTS","the matrix with the weights of the target quantities");
+      76          14 :   keys.add("compulsory","MINTYPE","conjgrad","the method to use for the minimisation");
+      77          14 :   keys.add("compulsory","MAXITER","1000","maximum number of optimization cycles for optimisation algorithms");
+      78          14 :   keys.add("compulsory","CGTOL","1E-6","the tolerance for the conjugate gradient minimization");
+      79          14 :   keys.add("compulsory","NCYCLES","5","the number of cycles of global optimization to attempt");
+      80          14 :   keys.add("compulsory","BUFFER","1.1","grid extent for search is (max projection - minimum projection) multiplied by this value");
+      81          14 :   keys.add("compulsory","CGRID_SIZE","10","number of points to use in each grid direction");
+      82          14 :   keys.add("compulsory","FGRID_SIZE","0","interpolate the grid onto this number of points -- only works in 2D");
+      83          14 :   keys.add("compulsory","SMACTOL","1E-4","the tolerance for the smacof algorithm");
+      84          14 :   keys.add("compulsory","SMACREG","0.001","this is used to ensure that we don't divide by zero when updating weights for SMACOF algorithm");
+      85          14 :   keys.addOutputComponent("coord","default","the coordinates of the points in the low dimensional space");
+      86           7 : }
+      87             : 
+      88             : 
+      89           5 : ArrangePoints::ArrangePoints( const ActionOptions& ao ) :
+      90             :   Action(ao),
+      91             :   ActionWithValue(ao),
+      92             :   ActionWithArguments(ao),
+      93           5 :   current_index(0),
+      94           5 :   dist_target(-1)
+      95             : {
+      96           5 :   dimout = getNumberOfArguments();
+      97           5 :   std::vector<unsigned> shape(1); shape[0]=getPntrToArgument(0)->getNumberOfValues();
+      98          15 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+      99          20 :     if( shape[0]!=getPntrToArgument(i)->getNumberOfValues() ) error("mismatch between sizes of input coordinates");
+     100          10 :     std::string num; Tools::convert( i+1, num ); addComponent( "coord-" + num, shape );
+     101          20 :     componentIsNotPeriodic( "coord-" + num ); getPntrToArgument(i)->buildDataStore();
+     102             :   }
+     103           5 :   std::vector<Value*> args( getArguments() ), target, weights; std::string sfd, errors;
+     104             :   // Read in target "distances" and target weights
+     105           5 :   for(unsigned i=1;; ++i) {
+     106          22 :     target.resize(0); if( !parseArgumentList("TARGET",i,target) ) break;
+     107           6 :     std::string inum; Tools::convert( i, inum ); checkInputMatrix( "TARGET" + inum, shape[0], target );
+     108          12 :     if( !parseArgumentList("WEIGHTS",i,weights) ) error("missing WEIGHTS" + inum + " keyword in input");
+     109          12 :     checkInputMatrix( "WEIGHTS" + inum, shape[0], weights );
+     110           6 :     args.push_back( target[0] ); args.push_back( weights[0] );
+     111          12 :     bool has_sf = parseNumbered("FUNC",i,sfd); switchingFunction.push_back( SwitchingFunction() );
+     112           6 :     if( !has_sf ) {
+     113           2 :       switchingFunction[i-1].set( "CUSTOM FUNC=1-sqrt(x2) R_0=1.0", errors ); dist_target=i-1;
+     114             :     } else {
+     115           5 :       switchingFunction[i-1].set( sfd, errors );
+     116           5 :       if( errors.length()!=0 ) error("problem reading switching function description " + errors);
+     117             :     }
+     118           6 :     log.printf("  %sth term seeks to match tranformed distances with those in matrix %s \n", inum.c_str(), target[0]->getName().c_str() );
+     119           6 :     log.printf("  in %sth term distances are transformed by 1-switching function with r_0=%s \n", inum.c_str(), switchingFunction[i-1].description().c_str() );
+     120           6 :     log.printf("  in %sth term weights of matrix elements in stress function are given by %s \n", inum.c_str(), weights[0]->getName().c_str() );
+     121           6 :   }
+     122          10 :   std::string mtype; parse("MINTYPE",mtype);
+     123           5 :   if( mtype=="conjgrad" ) {
+     124           3 :     mintype=conjgrad;
+     125           3 :     log.printf("  minimimising stress function using conjugate gradients\n");
+     126           2 :   } else if( mtype=="pointwise") {
+     127           1 :     mintype=pointwise;
+     128           1 :     log.printf("  minimimising stress function using pointwise global optimisation\n");
+     129           1 :     npoints.resize(dimout); nfgrid.resize(dimout);
+     130           3 :     parseVector("CGRID_SIZE",npoints); parse("BUFFER",gbuf); parse("NCYCLES",ncycles);
+     131           2 :     parseVector("FGRID_SIZE",nfgrid); if( nfgrid[0]!=0 && dimout!=2 ) error("interpolation only works in two dimensions");
+     132           1 :     log.printf("  doing %u cycles of global optimization sweeps\n",ncycles);
+     133           1 :     log.printf("  using coarse grid of points that is %u",npoints[0]);
+     134           2 :     for(unsigned j=1; j<npoints.size(); ++j) log.printf(" by %u",npoints[j]);
+     135           1 :     log.printf("\n  grid is %f times larger than the difference between the position of the minimum and maximum projection \n",gbuf);
+     136           1 :     if( nfgrid[0]>0 ) {
+     137           1 :       log.printf("  interpolating stress onto grid of points that is %u",nfgrid[0]);
+     138           2 :       for(unsigned j=1; j<nfgrid.size(); ++j) log.printf(" by %u",nfgrid[j]);
+     139           1 :       log.printf("\n");
+     140             :     }
+     141           1 :   } else if( mtype=="smacof" ) {
+     142           1 :     mintype=smacof; if( dist_target<0 ) error("one of targets must be distances in order to use smacof");
+     143           1 :     log.printf("  minimising stress fucntion using smacof\n");
+     144           2 :     parse("SMACTOL",smacof_tol); parse("SMACREG",smacof_reg);
+     145           1 :     log.printf("  tolerance for smacof algorithms equals %f \n", smacof_tol);
+     146           1 :     log.printf("  using %f as regularisation parameter for weights in smacof algorithm\n", smacof_reg);
+     147           0 :   } else error("invalid MINTYPE");
+     148           5 :   if( mintype!=smacof) {
+     149           8 :     parse("CGTOL",cgtol); log.printf("  tolerance for conjugate gradient algorithm equals %f \n",cgtol);
+     150             :   }
+     151          10 :   parse("MAXITER",maxiter); log.printf("  maximum number of iterations for minimimization algorithms equals %d \n", maxiter );
+     152           5 :   requestArguments( args ); checkRead();
+     153           5 : }
+     154             : 
+     155          12 : void ArrangePoints::checkInputMatrix( const std::string& key, const unsigned& nvals, const std::vector<Value*>& mat ) const {
+     156          12 :   mat[0]->buildDataStore();
+     157          12 :   if( mat.size()!=1 ) error("should only be one value in input to " + key );
+     158          12 :   if( mat[0]->getRank()!=2 || mat[0]->hasDerivatives() ) error("input to " + key + " keyword should be a matrix");
+     159          12 :   if( mat[0]->getShape()[0]!=nvals || mat[0]->getShape()[1]!=nvals ) error("input to " + key + " keyword has the wrong size");
+     160          12 : }
+     161             : 
+     162       24600 : double ArrangePoints::calculateStress( const std::vector<double>& p, std::vector<double>& d ) {
+     163       73800 :   double stress=0; for(unsigned i=0; i<p.size(); ++i) d[i]=0.0;
+     164       24600 :   std::vector<double> dtmp(dimout);
+     165       24600 :   std::vector<unsigned> shape( getPntrToArgument( dimout )->getShape() );
+     166       24600 :   unsigned targi=shape[0]*current_index;
+     167       24600 :   unsigned nmatrices = ( getNumberOfArguments() - dimout ) / 2;
+     168     2484600 :   for(unsigned i=0; i<shape[0]; ++i) {
+     169     2460000 :     if( i==current_index ) continue ;
+     170             :     // Calculate distance in low dimensional space
+     171     7306200 :     double dd2=0; for(unsigned k=0; k<dimout; ++k) { dtmp[k]=p[k] - mypos[dimout*i+k]; dd2+=dtmp[k]*dtmp[k]; }
+     172             : 
+     173     4870800 :     for(unsigned k=0; k<nmatrices; ++k ) {
+     174             :       // Now do transformations and calculate differences
+     175     2435400 :       double df, fd = 1. - switchingFunction[k].calculateSqr( dd2, df );
+     176             :       // Get the weight for this connection
+     177             :       double weight = 0;
+     178   245975400 :       for(unsigned j=0; j<shape[0]; ++j) weight += getPntrToArgument( dimout + 2*k + 1 )->get( shape[0]*i+j );
+     179             :       // Get the difference for the connection
+     180     2435400 :       double fdiff = fd - getPntrToArgument( dimout + 2*k )->get( targi+i );
+     181             :       // Calculate derivatives
+     182     2435400 :       double pref = -2.*weight*fdiff*df;
+     183     7306200 :       for(unsigned n=0; n<dimout; ++n) d[n] += pref*dtmp[n];
+     184             :       // Accumulate the total stress
+     185     2435400 :       stress += weight*fdiff*fdiff;
+     186             :     }
+     187             :   }
+     188       24600 :   return stress;
+     189             : }
+     190             : 
+     191        1932 : double ArrangePoints::calculateFullStress( const std::vector<double>& p, std::vector<double>& d ) {
+     192             :   // Zero derivative and stress accumulators
+     193      387932 :   for(unsigned i=0; i<p.size(); ++i) d[i]=0.0;
+     194        1932 :   double stress=0; std::vector<double> dtmp( dimout );
+     195             : 
+     196        1932 :   unsigned nmatrices = ( getNumberOfArguments() - dimout ) / 2;
+     197        1932 :   std::vector<unsigned> shape( getPntrToArgument( dimout )->getShape() );
+     198      193000 :   for(unsigned i=1; i<shape[0]; ++i) {
+     199    14134568 :     for(unsigned j=0; j<i; ++j) {
+     200             :       // Calculate distance in low dimensional space
+     201    41830500 :       double dd2=0; for(unsigned k=0; k<dimout; ++k) { dtmp[k]=p[dimout*i+k] - p[dimout*j+k]; dd2+=dtmp[k]*dtmp[k]; }
+     202             : 
+     203    27887000 :       for(unsigned k=0; k<nmatrices; ++k ) {
+     204             :         // Now do transformations and calculate differences
+     205    13943500 :         double df, fd = 1. - switchingFunction[k].calculateSqr( dd2, df );
+     206             :         // Get the weight for this connection
+     207    13943500 :         double weight = getPntrToArgument( dimout + 2*k + 1 )->get( shape[0]*i+j );
+     208             :         // Get the difference for the connection
+     209    13943500 :         double fdiff = fd - getPntrToArgument( dimout + 2*k )->get( shape[0]*i+j );
+     210             :         // Calculate derivatives
+     211    13943500 :         double pref = -2.*weight*fdiff*df;
+     212    41830500 :         for(unsigned n=0; n<dimout; ++n) { double dterm=pref*dtmp[n]; d[dimout*i+n]+=dterm; d[dimout*j+n]-=dterm; }
+     213             :         // Accumulate the total stress
+     214    13943500 :         stress += weight*fdiff*fdiff;
+     215             :       }
+     216             :     }
+     217             :   }
+     218        1932 :   return stress;
+     219             : }
+     220             : 
+     221           2 : double ArrangePoints::recalculateSmacofWeights( const std::vector<double>& p, SMACOF& mysmacof ) const {
+     222             :   double stress=0, totalWeight=0;
+     223           2 :   unsigned nmatrices = ( getNumberOfArguments() - dimout ) / 2;
+     224           2 :   std::vector<unsigned> shape( getPntrToArgument( dimout )->getShape() );
+     225        1000 :   for(unsigned i=1; i<shape[0]; ++i) {
+     226      250498 :     for(unsigned j=0; j<i; ++j) {
+     227             :       // Calculate distance in low dimensional space
+     228      748500 :       double dd2=0; for(unsigned k=0; k<dimout; ++k) { double dtmp=p[dimout*i+k] - p[dimout*j+k]; dd2+=dtmp*dtmp; }
+     229             :       // Calculate difference between target difference and true difference
+     230      249500 :       double wval=0, dd1 = sqrt(dd2); double diff = mysmacof.getDistance(i,j) - dd1;
+     231             : 
+     232      748500 :       for(unsigned k=0; k<nmatrices; ++k ) {
+     233             :         // Don't need to do anything for distances we are matching
+     234      499000 :         if( k==dist_target ) continue;
+     235             :         // Now do transformations and calculate differences
+     236      249500 :         double df, fd = 1. - switchingFunction[k].calculateSqr( dd2, df );
+     237             :         // Get the weight for this connection
+     238      249500 :         double weight = getPntrToArgument( dimout + 2*k + 1 )->get( shape[0]*i+j );
+     239             :         // Get the difference for the connection
+     240      249500 :         double fdiff = getPntrToArgument( dimout + 2*k )->get( shape[0]*i+j ) - fd;
+     241             :         // Now set the weight if difference in distance is larger than regularisation parameter
+     242      249500 :         if( fabs(diff)>smacof_reg  ) wval -= weight*fdiff*df*dd1 / diff;
+     243             :         // And the total stress and weights
+     244      249500 :         stress += weight*fdiff*fdiff; totalWeight += weight;
+     245             :       }
+     246      249500 :       mysmacof.setWeight( j, i, wval ); mysmacof.setWeight( i, j, wval );
+     247             :     }
+     248             :   }
+     249           2 :   return stress / totalWeight;
+     250             : }
+     251             : 
+     252           7 : void ArrangePoints::optimize( std::vector<double>& pos ) {
+     253             :   ConjugateGradient<ArrangePoints> mycgminimise( this );
+     254           7 :   if( mintype==conjgrad ) {
+     255           5 :     mycgminimise.minimise( cgtol, pos, &ArrangePoints::calculateFullStress );
+     256           2 :   } else if( mintype==pointwise ) {
+     257           1 :     unsigned nvals=getPntrToArgument( dimout )->getShape()[0];
+     258           1 :     std::vector<double> gmin( dimout ), gmax( dimout ), mypoint( dimout );
+     259             :     // Find the extent of the grid
+     260           3 :     for(unsigned j=0; j<dimout; ++j) gmin[j]=gmax[j]=pos[j];
+     261         100 :     for(unsigned i=1; i<nvals; ++i) {
+     262         297 :       for(unsigned j=0; j<dimout; ++j) {
+     263         198 :         if( pos[dimout*i+j] < gmin[j] ) gmin[j] = pos[dimout*i+j];
+     264         198 :         if( pos[dimout*i+j] > gmax[j] ) gmax[j] = pos[dimout*i+j];
+     265             :       }
+     266             :     }
+     267           3 :     for(unsigned j=0; j<dimout; ++j) {
+     268           2 :       double gbuffer = 0.5*gbuf*( gmax[j]-gmin[j] ) - 0.5*( gmax[j]- gmin[j] );
+     269           2 :       gmin[j]-=gbuffer; gmax[j]+=gbuffer;
+     270             :     }
+     271         202 :     mypos.resize( pos.size() ); for(unsigned i=0; i<mypos.size(); ++i) mypos[i] = pos[i];
+     272           1 :     gridtools::GridSearch<ArrangePoints> mygridsearch( gmin, gmax, npoints, nfgrid, this );
+     273             :     // Run multiple loops over all projections
+     274           3 :     for(unsigned i=0; i<ncycles; ++i) {
+     275         202 :       for(unsigned j=0; j<nvals; ++j) {
+     276             :         // Setup target distances and target functions for calculate stress
+     277         200 :         current_index=j;
+     278             : 
+     279             :         // Find current projection of jth point
+     280         600 :         for(unsigned k=0; k<dimout; ++k) mypoint[k]=mypos[j*dimout+k];
+     281             :         // Minimise using grid search
+     282         200 :         bool moved=mygridsearch.minimise( mypoint, &ArrangePoints::calculateStress );
+     283         200 :         if( moved ) {
+     284             :           // Reassign the new projection
+     285          66 :           for(unsigned k=0; k<dimout; ++k) mypos[dimout*j+k]=mypoint[k];
+     286             :           // Minimise output using conjugate gradient
+     287          22 :           mycgminimise.minimise( cgtol, mypos, &ArrangePoints::calculateFullStress );
+     288             :         }
+     289             :       }
+     290         402 :       for(unsigned i=0; i<mypos.size(); ++i) pos[i] = mypos[i];
+     291             :     }
+     292           2 :   } else if( mintype==smacof ) {
+     293           1 :     SMACOF mysmacof( getPntrToArgument( dimout + 2*dist_target) ); double stress = recalculateSmacofWeights( pos, mysmacof );
+     294             : 
+     295           1 :     for(unsigned i=0; i<maxiter; ++i) {
+     296             :       // Optimise using smacof and current weights
+     297           1 :       mysmacof.optimize( smacof_tol, maxiter, pos );
+     298             :       // Recalculate weights matrix and sigma
+     299           1 :       double newsig = recalculateSmacofWeights( pos, mysmacof );
+     300             :       // Test whether or not the algorithm has converged
+     301           1 :       if( fabs( newsig - stress )<smacof_tol ) break;
+     302             :       // Make initial sigma into new sigma so that the value of new sigma is used every time so that the error can be reduced
+     303             :       stress=newsig;
+     304             :     }
+     305             :   }
+     306           7 : }
+     307             : 
+     308           7 : void ArrangePoints::calculate() {
+     309             :   // Retrive the initial value
+     310           7 :   unsigned nvals = getPntrToArgument( dimout )->getShape()[0];
+     311           7 :   std::vector<double> pos( dimout*nvals );
+     312        1107 :   for(unsigned i=0; i<nvals; ++i) {
+     313        3300 :     for(unsigned j=0; j<dimout; ++j) pos[ dimout*i + j ] = getPntrToArgument(j)->get(i);
+     314             :   }
+     315             :   // Do the optimization
+     316           7 :   optimize( pos );
+     317             :   // Make sure all the components are the right size
+     318          21 :   for(unsigned j=0; j<dimout; ++j) {
+     319          14 :     if( getPntrToComponent(j)->getShape()[0]!=nvals ) {
+     320           8 :       std::vector<unsigned> shape(1,nvals); getPntrToComponent(j)->setShape( shape );
+     321             :     }
+     322             :   }
+     323             :   // And set the final values
+     324        1107 :   for(unsigned i=0; i<nvals; ++i) {
+     325        3300 :     for(unsigned j=0; j<dimout; ++j) getPntrToComponent(j)->set( i, pos[dimout*i+j] );
+     326             :   }
+     327           7 : }
+     328             : 
+     329             : }
+     330             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/ClassicalMultiDimensionalScaling.cpp.func-sort-c.html b/coverage/dimred/ClassicalMultiDimensionalScaling.cpp.func-sort-c.html new file mode 100644 index 000000000000..c19e80f5d5ee --- /dev/null +++ b/coverage/dimred/ClassicalMultiDimensionalScaling.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + 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:404197.6 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred32ClassicalMultiDimensionalScalingC2ERKNS_13ActionOptionsE0
_ZN4PLMD6dimred32ClassicalMultiDimensionalScalingC1ERKNS_13ActionOptionsE7
_ZN4PLMD6dimred32ClassicalMultiDimensionalScaling16registerKeywordsERNS_8KeywordsE9
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/ClassicalMultiDimensionalScaling.cpp.func.html b/coverage/dimred/ClassicalMultiDimensionalScaling.cpp.func.html new file mode 100644 index 000000000000..25c04c88f17c --- /dev/null +++ b/coverage/dimred/ClassicalMultiDimensionalScaling.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + 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:404197.6 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred32ClassicalMultiDimensionalScaling16registerKeywordsERNS_8KeywordsE9
_ZN4PLMD6dimred32ClassicalMultiDimensionalScalingC1ERKNS_13ActionOptionsE7
_ZN4PLMD6dimred32ClassicalMultiDimensionalScalingC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/ClassicalMultiDimensionalScaling.cpp.gcov.html b/coverage/dimred/ClassicalMultiDimensionalScaling.cpp.gcov.html new file mode 100644 index 000000000000..09b8385e39c6 --- /dev/null +++ b/coverage/dimred/ClassicalMultiDimensionalScaling.cpp.gcov.html @@ -0,0 +1,312 @@ + + + + + + + + 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:404197.6 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2020 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received 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/ActionPilot.h"
+      24             : #include "core/ActionWithValue.h"
+      25             : #include "core/ActionRegister.h"
+      26             : #include "core/PlumedMain.h"
+      27             : #include "core/ActionSet.h"
+      28             : 
+      29             : //+PLUMEDOC DIMRED CLASSICAL_MDS
+      30             : /*
+      31             : Create a low-dimensional projection of a trajectory using the classical multidimensional
+      32             :  scaling algorithm.
+      33             : 
+      34             : Multidimensional scaling (MDS) is similar to what is done when you make a map. You start with distances
+      35             : between London, Belfast, Paris and Dublin and then you try to arrange points on a piece of paper so that the (suitably scaled)
+      36             : distances between the points in your map representing each of those cities are related to the true distances between the cities.
+      37             : Stating this more mathematically MDS endeavors to find an <a href="http://en.wikipedia.org/wiki/Isometry">isometry</a>
+      38             : between points distributed in a high-dimensional space and a set of points distributed in a low-dimensional plane.
+      39             : In other words, if we have \f$M\f$ \f$D\f$-dimensional points, \f$\mathbf{X}\f$,
+      40             : 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,
+      41             : \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
+      42             : Euclidean distances between pairs of them, \f$d_{ij}\f$, resemble the dissimilarities between the high dimensional points.  In short we minimize:
+      43             : 
+      44             : \f[
+      45             : \chi^2 = \sum_{i \ne j} \left( D_{ij} - d_{ij} \right)^2
+      46             : \f]
+      47             : 
+      48             : 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
+      49             : 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
+      50             : 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>
+      51             : 
+      52             : \par Examples
+      53             : 
+      54             : The following command instructs plumed to construct a classical multidimensional scaling projection of a trajectory.
+      55             : The RMSD distance between atoms 1-256 have moved is used to measure the distances in the high-dimensional space.
+      56             : 
+      57             : \plumedfile
+      58             : data: COLLECT_FRAMES ATOMS=1-256
+      59             : mat: EUCLIDEAN_DISSIMILARITIES USE_OUTPUT_DATA_FROM=data
+      60             : mds: CLASSICAL_MDS USE_OUTPUT_DATA_FROM=mat NLOW_DIM=2
+      61             : OUTPUT_ANALYSIS_DATA_TO_COLVAR USE_OUTPUT_DATA_FROM=mds FILE=rmsd-embed
+      62             : \endplumedfile
+      63             : 
+      64             : The following section is for people who are interested in how this method works in detail. A solid understanding of this material is
+      65             : not necessary to use MDS.
+      66             : 
+      67             : \section dim-sec Method of optimization
+      68             : 
+      69             : The stress function can be minimized using a standard optimization algorithm such as conjugate gradients or steepest descent.
+      70             : However, it is more common to do this minimization using a technique known as classical scaling.  Classical scaling works by
+      71             : recognizing that each of the distances $D_{ij}$ in the above sum can be written as:
+      72             : 
+      73             : \f[
+      74             : 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
+      75             : \f]
+      76             : 
+      77             : We can use this expression and matrix algebra to calculate multiple distances at once.  For instance if we have three points,
+      78             : \f$\mathbf{X}\f$, we can write distances between them as:
+      79             : 
+      80             : \f{eqnarray*}{
+      81             : D^2(\mathbf{X}) &=& \left[ \begin{array}{ccc}
+      82             : 0 & d_{12}^2 & d_{13}^2 \\
+      83             : d_{12}^2 & 0 & d_{23}^2 \\
+      84             : d_{13}^2 & d_{23}^2 & 0
+      85             : \end{array}\right] \\
+      86             : &=&
+      87             : \sum_\alpha \left[ \begin{array}{ccc}
+      88             : (X^1_\alpha)^2 & (X^1_\alpha)^2 & (X^1_\alpha)^2 \\
+      89             : (X^2_\alpha)^2 & (X^2_\alpha)^2 & (X^2_\alpha)^2 \\
+      90             : (X^3_\alpha)^2 & (X^3_\alpha)^2 & (X^3_\alpha)^2 \\
+      91             : \end{array}\right]
+      92             :  + \sum_\alpha \left[ \begin{array}{ccc}
+      93             : (X^1_\alpha)^2 & (X^2_\alpha)^2 & (X^3_\alpha)^2 \\
+      94             : (X^1_\alpha)^2 & (X^2_\alpha)^2 & (X^3_\alpha)^2 \\
+      95             : (X^1_\alpha)^2 & (X^2_\alpha)^2 & (X^3_\alpha)^2 \\
+      96             : \end{array}\right]
+      97             : - 2 \sum_\alpha \left[ \begin{array}{ccc}
+      98             : X^1_\alpha X^1_\alpha & X^1_\alpha X^2_\alpha & X^1_\alpha X^3_\alpha \\
+      99             : X^2_\alpha X^1_\alpha & X^2_\alpha X^2_\alpha & X^2_\alpha X^3_\alpha \\
+     100             : X^1_\alpha X^3_\alpha & X^3_\alpha X^2_\alpha & X^3_\alpha X^3_\alpha
+     101             : \end{array}\right] \nonumber \\
+     102             : &=& \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}
+     103             : \f}
+     104             : 
+     105             : 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
+     106             : 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
+     107             : of ones and \f$\mathbf{c}\f$ is a vector with components given by:
+     108             : 
+     109             : \f[
+     110             : c_i = \sum_\alpha (x_\alpha^i)^2
+     111             : \f]
+     112             : 
+     113             : These quantities are the diagonal elements of \f$\mathbf{X X^T}\f$, which is a dot product or Gram Matrix that contains the
+     114             : dot product of the vector \f$X_i\f$ with the vector \f$X_j\f$ in element \f$i,j\f$.
+     115             : 
+     116             : In classical scaling we introduce a centering matrix \f$\mathbf{J}\f$ that is given by:
+     117             : 
+     118             : \f[
+     119             : \mathbf{J} = \mathbf{I} - \frac{1}{M} \mathbf{11^T}
+     120             : \f]
+     121             : 
+     122             : 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:
+     123             : 
+     124             : \f{eqnarray*}{
+     125             :  -\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} \\
+     126             :  &=& -\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} \\
+     127             :  &=& \mathbf{ J X X^T J } = \mathbf{X X^T } \label{eqn:scaling}
+     128             : \f}
+     129             : 
+     130             : 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$
+     131             : is a matrix containing all zeros.  In the final step meanwhile we use the fact that the matrix of squared distances will not
+     132             : 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$:
+     133             : \f[
+     134             : \mu_\alpha = \frac{1}{M} \sum_{i=1}^N \mathbf{X}^i_\alpha
+     135             : \f]
+     136             : 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
+     137             : \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$.
+     138             : 
+     139             : The matrix of squared distances is symmetric and positive-definite we can thus use the spectral decomposition to decompose it as:
+     140             : 
+     141             : \f[
+     142             : \Phi= \mathbf{V} \Lambda \mathbf{V}^T
+     143             : \f]
+     144             : 
+     145             : Furthermore, because the matrix we are diagonalizing, \f$\mathbf{X X^T}\f$, is the product of a matrix and its transpose
+     146             : we can use this decomposition to write:
+     147             : 
+     148             : \f[
+     149             : \mathbf{X} =\mathbf{V} \Lambda^\frac{1}{2}
+     150             : \f]
+     151             : 
+     152             : Much as in PCA there are generally a small number of large eigenvalues in \f$\Lambda\f$ and many small eigenvalues.
+     153             : We can safely use only the large eigenvalues and their corresponding eigenvectors to express the relationship between
+     154             : the coordinates \f$\mathbf{X}\f$.  This gives us our set of low-dimensional projections.
+     155             : 
+     156             : This derivation makes a number of assumptions about the how the low dimensional points should best be arranged to minimize
+     157             : the stress. If you use an interactive optimization algorithm such as SMACOF you may thus be able to find a better
+     158             : (lower-stress) projection of the points.  For more details on the assumptions made
+     159             : see <a href="http://quest4rigor.com/tag/multidimensional-scaling/"> this website.</a>
+     160             : */
+     161             : //+ENDPLUMEDOC
+     162             : 
+     163             : namespace PLMD {
+     164             : namespace dimred {
+     165             : 
+     166             : class ClassicalMultiDimensionalScaling : public ActionShortcut {
+     167             : public:
+     168             :   static void registerKeywords( Keywords& keys );
+     169             :   explicit ClassicalMultiDimensionalScaling( const ActionOptions& ao );
+     170             : };
+     171             : 
+     172             : PLUMED_REGISTER_ACTION(ClassicalMultiDimensionalScaling,"CLASSICAL_MDS")
+     173             : 
+     174           9 : void ClassicalMultiDimensionalScaling::registerKeywords( Keywords& keys ) {
+     175           9 :   ActionShortcut::registerKeywords( keys );
+     176          18 :   keys.add("compulsory","ARG","the arguments that you would like to make the histogram for");
+     177          18 :   keys.add("compulsory","NLOW_DIM","number of low-dimensional coordinates required");
+     178          36 :   keys.needsAction("TRANSPOSE"); keys.needsAction("DISSIMILARITIES"); keys.needsAction("MATRIX_VECTOR_PRODUCT"); keys.needsAction("VSTACK");
+     179          36 :   keys.needsAction("SUM"); keys.needsAction("CUSTOM"); keys.needsAction("OUTER_PRODUCT"); keys.needsAction("DIAGONALIZE");
+     180           9 : }
+     181             : 
+     182           7 : ClassicalMultiDimensionalScaling::ClassicalMultiDimensionalScaling( const ActionOptions& ao):
+     183             :   Action(ao),
+     184           7 :   ActionShortcut(ao)
+     185             : {
+     186             :   // Find the argument name
+     187          14 :   std::string argn; parse("ARG",argn); std::string dissimilarities="";
+     188           7 :   ActionShortcut* as = plumed.getActionSet().getShortcutActionWithLabel( argn );
+     189           7 :   if( !as ) error("found no action with name " + argn );
+     190           7 :   if( as->getName()!="COLLECT_FRAMES" ) {
+     191           1 :     if( as->getName().find("LANDMARK_SELECT")==std::string::npos ) {
+     192           0 :       error("found no COLLECT_FRAMES or LANDMARK_SELECT action with label " + argn );
+     193             :     } else {
+     194           1 :       ActionWithValue* dissims = plumed.getActionSet().selectWithLabel<ActionWithValue*>( argn + "_sqrdissims");
+     195           2 :       if( dissims ) dissimilarities = argn + "_sqrdissims";
+     196             :     }
+     197             :   }
+     198           7 :   if( dissimilarities.length()==0 ) {
+     199           6 :     dissimilarities = getShortcutLabel() + "_mat";
+     200             :     // Transpose matrix of stored data values
+     201          12 :     readInputLine( argn + "_dataT: TRANSPOSE ARG=" + argn + "_data");
+     202             :     // Calculate the dissimilarity matrix
+     203          12 :     readInputLine( getShortcutLabel() + "_mat: DISSIMILARITIES SQUARED ARG=" + argn + "_data," + argn + "_dataT");
+     204             :   }
+     205             :   // Center the matrix
+     206             :   // Step 1: calculate the sum of the rows and duplicate them into a matrix
+     207          14 :   readInputLine( getShortcutLabel() + "_rsums: MATRIX_VECTOR_PRODUCT ARG=" + dissimilarities + "," + argn + "_ones" );
+     208          14 :   readInputLine( getShortcutLabel() + "_nones: SUM ARG=" + argn + "_ones PERIODIC=NO");
+     209          14 :   readInputLine( getShortcutLabel() + "_rsumsn: CUSTOM ARG=" + getShortcutLabel() + "_rsums," + getShortcutLabel() + "_nones FUNC=x/y PERIODIC=NO");
+     210          14 :   readInputLine( getShortcutLabel() + "_rsummat: OUTER_PRODUCT ARG=" + getShortcutLabel() + "_rsumsn," + argn + "_ones");
+     211             :   // Step 2: Multiply matrix by -0.5 and subtract row sums
+     212          14 :   readInputLine( getShortcutLabel() + "_int: CUSTOM ARG=" + getShortcutLabel() + "_rsummat," + dissimilarities + " FUNC=-0.5*y+0.5*x PERIODIC=NO");
+     213             :   // Step 3: Calculate column sums for new matrix and duplicate them into a matrix
+     214          14 :   readInputLine( getShortcutLabel() + "_intT: TRANSPOSE ARG=" + getShortcutLabel() + "_int");
+     215          14 :   readInputLine( getShortcutLabel() + "_csums: MATRIX_VECTOR_PRODUCT ARG=" + getShortcutLabel() + "_intT," + argn + "_ones" );
+     216          14 :   readInputLine( getShortcutLabel() + "_csumsn: CUSTOM ARG=" + getShortcutLabel() + "_csums," + getShortcutLabel() + "_nones FUNC=x/y PERIODIC=NO");
+     217          14 :   readInputLine( getShortcutLabel() + "_csummat: OUTER_PRODUCT ARG=" + getShortcutLabel() + "_csumsn," + argn + "_ones");
+     218             :   // Step 4: subtract the column sums
+     219          14 :   readInputLine( getShortcutLabel() + "_cmat: CUSTOM ARG=" + getShortcutLabel() + "_csummat," + getShortcutLabel() + "_intT FUNC=y-x PERIODIC=NO");
+     220             :   // And generate the multidimensional scaling projection
+     221           7 :   unsigned ndim; parse("NLOW_DIM",ndim);
+     222          19 :   std::string vecstr="1"; for(unsigned i=1; i<ndim; ++i) { std::string num; Tools::convert( i+1, num ); vecstr += "," + num; }
+     223          14 :   readInputLine( getShortcutLabel() + "_eig: DIAGONALIZE ARG=" + getShortcutLabel() + "_cmat VECTORS=" + vecstr );
+     224          20 :   for(unsigned i=0; i<ndim; ++i) {
+     225          13 :     std::string num; Tools::convert( i+1, num );
+     226          26 :     readInputLine( getShortcutLabel() + "-" +  num + ": CUSTOM ARG=" + getShortcutLabel() + "_eig.vals-" + num + "," + getShortcutLabel() + "_eig.vecs-" + num + " FUNC=sqrt(x)*y PERIODIC=NO");
+     227             :   }
+     228           7 :   std::string eigvec_args = " ARG=" + getShortcutLabel() + "-1";
+     229             :   // The final output is a stack of all the low dimensional coordinates
+     230          19 :   for(unsigned i=1; i<ndim; ++i) { std::string num; Tools::convert( i+1, num ); eigvec_args += "," + getShortcutLabel() + "-" + num; }
+     231          14 :   readInputLine( getShortcutLabel() + ": VSTACK" + eigvec_args );
+     232           7 : }
+     233             : 
+     234             : }
+     235             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/PCA.cpp.func-sort-c.html b/coverage/dimred/PCA.cpp.func-sort-c.html new file mode 100644 index 000000000000..a99be8f0ce6f --- /dev/null +++ b/coverage/dimred/PCA.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + 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:5656100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred3PCAC2ERKNS_13ActionOptionsE0
_ZN4PLMD6dimred3PCAC1ERKNS_13ActionOptionsE2
_ZN4PLMD6dimred3PCA16registerKeywordsERNS_8KeywordsE4
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/PCA.cpp.func.html b/coverage/dimred/PCA.cpp.func.html new file mode 100644 index 000000000000..f2c702fab4bc --- /dev/null +++ b/coverage/dimred/PCA.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + 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:5656100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred3PCA16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD6dimred3PCAC1ERKNS_13ActionOptionsE2
_ZN4PLMD6dimred3PCAC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/PCA.cpp.gcov.html b/coverage/dimred/PCA.cpp.gcov.html new file mode 100644 index 000000000000..259d50c41ecf --- /dev/null +++ b/coverage/dimred/PCA.cpp.gcov.html @@ -0,0 +1,260 @@ + + + + + + + + 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:5656100.0 %
Date:2024-04-19 12:12:35Functions: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 "core/ActionShortcut.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "core/ActionWithValue.h"
+      25             : #include "core/ActionPilot.h"
+      26             : #include "core/ActionAtomistic.h"
+      27             : #include "core/PlumedMain.h"
+      28             : #include "core/ActionSet.h"
+      29             : 
+      30             : //+PLUMEDOC DIMRED PCA
+      31             : /*
+      32             : Perform principal component analysis (PCA) using either the positions of the atoms a large number of collective variables as input.
+      33             : 
+      34             : Principal component analysis is a statistical technique that uses an orthogonal transformation to convert a set of observations of
+      35             : poorly correlated variables into a set of linearly uncorrelated variables.  You can read more about the specifics of this technique
+      36             : here: https://en.wikipedia.org/wiki/Principal_component_analysis
+      37             : 
+      38             : When used with molecular dynamics simulations a set of frames taken from the trajectory, \f$\{X_i\}\f$, or the values of
+      39             : a number of collective variables which are calculated from the trajectory frames are used as input.  In this second instance your
+      40             : input to the PCA analysis algorithm is thus a set of high-dimensional vectors of collective variables.  However, if
+      41             : collective variables are calculated from the positions of the atoms or if the positions are used directly the assumption is that
+      42             : this input trajectory is a set of poorly correlated (high-dimensional) vectors.  After principal component analysis has been
+      43             : performed the output is a set of orthogonal vectors that describe the directions in which the largest motions have been seen.
+      44             : In other words, principal component analysis provides a method for lowering the dimensionality of the data contained in a trajectory.
+      45             : 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
+      46             : or some linear combination of the input collective variables if a high-dimensional vector of collective variables was used as input.
+      47             : 
+      48             : As explained on the Wikipedia page you must calculate the average and covariance for each of the input coordinates.  In other words, you must
+      49             : calculate the average structure and the amount the system fluctuates around this average structure.  The problem in doing so when the
+      50             : \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
+      51             : atoms comes from the translational and rotational degrees of freedom of the molecule.  The first six principal components will thus, most likely,
+      52             : be uninteresting.  Consequently, to remedy this problem PLUMED provides the functionality to perform an RMSD alignment of the all the structures
+      53             : to be analyzed to the first frame in the trajectory.  This can be used to effectively remove translational and/or rotational motions from
+      54             : consideration.  The resulting principal components thus describe vibrational motions of the molecule.
+      55             : 
+      56             : 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
+      57             : used as input for the \ref PCAVARS action.
+      58             : 
+      59             : \par Examples
+      60             : 
+      61             : The following input instructs PLUMED to perform a principal component analysis in which the covariance matrix is calculated from changes in the positions
+      62             : of the first 22 atoms.  The TYPE=OPTIMAL instruction ensures that translational and rotational degrees of freedom are removed from consideration.
+      63             : 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
+      64             : will be performed at the end of the simulation.
+      65             : 
+      66             : \plumedfile
+      67             : ff: COLLECT_FRAMES ATOMS=1-22 STRIDE=1
+      68             : pca: PCA USE_OUTPUT_DATA_FROM=ff METRIC=OPTIMAL NLOW_DIM=2
+      69             : OUTPUT_PCA_PROJECTION USE_OUTPUT_DATA_FROM=pca FILE=PCA-comp.pdb
+      70             : \endplumedfile
+      71             : 
+      72             : The following input instructs PLUMED to perform a principal component analysis in which the covariance matrix is calculated from changes in the six distances
+      73             : 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
+      74             : 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.
+      75             : 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
+      76             : 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
+      77             : when calculating averages and covariance matrices a reweighting should be performed based and each frames' weight in these calculations should be determined based on
+      78             : the current value of the instantaneous bias (see \ref REWEIGHT_BIAS).
+      79             : 
+      80             : \plumedfile
+      81             : d1: DISTANCE ATOMS=1,2
+      82             : d2: DISTANCE ATOMS=1,3
+      83             : d3: DISTANCE ATOMS=1,4
+      84             : d4: DISTANCE ATOMS=2,3
+      85             : d5: DISTANCE ATOMS=2,4
+      86             : d6: DISTANCE ATOMS=3,4
+      87             : rr: RESTRAINT ARG=d1 AT=0.1 KAPPA=10
+      88             : rbias: REWEIGHT_BIAS TEMP=300
+      89             : 
+      90             : ff: COLLECT_FRAMES ARG=d1,d2,d3,d4,d5,d6 LOGWEIGHTS=rbias STRIDE=5
+      91             : pca: PCA USE_OUTPUT_DATA_FROM=ff METRIC=EUCLIDEAN NLOW_DIM=2
+      92             : OUTPUT_PCA_PROJECTION USE_OUTPUT_DATA_FROM=pca STRIDE=100 FILE=PCA-comp.pdb
+      93             : \endplumedfile
+      94             : 
+      95             : */
+      96             : //+ENDPLUMEDOC
+      97             : 
+      98             : namespace PLMD {
+      99             : namespace dimred {
+     100             : 
+     101             : class PCA : public ActionShortcut {
+     102             : public:
+     103             :   static void registerKeywords( Keywords& keys );
+     104             :   PCA( const ActionOptions& );
+     105             : };
+     106             : 
+     107             : PLUMED_REGISTER_ACTION(PCA,"PCA")
+     108             : 
+     109           4 : void PCA::registerKeywords( Keywords& keys ) {
+     110           4 :   ActionShortcut::registerKeywords( keys );
+     111           8 :   keys.add("compulsory","ARG","the arguments that you would like to make the histogram for");
+     112           8 :   keys.add("compulsory","NLOW_DIM","number of low-dimensional coordinates required");
+     113           8 :   keys.add("compulsory","STRIDE","0","the frequency with which to perform this analysis");
+     114           8 :   keys.add("optional","FILE","the file on which to output the low dimensional coordinates");
+     115           8 :   keys.add("optional","FMT","the format to use when outputting the low dimensional coordinates");
+     116          12 :   keys.needsAction("LOGSUMEXP"); keys.needsAction("TRANSPOSE"); keys.needsAction("MATRIX_VECTOR_PRODUCT");
+     117          16 :   keys.needsAction("CONSTANT"); keys.needsAction("COLLECT"); keys.needsAction("OUTER_PRODUCT"); keys.needsAction("CUSTOM");
+     118          16 :   keys.needsAction("MATRIX_PRODUCT"); keys.needsAction("DIAGONALIZE"); keys.needsAction("VSTACK"); keys.needsAction("DUMPPDB");
+     119           4 : }
+     120             : 
+     121             : 
+     122           2 : PCA::PCA(const ActionOptions&ao):
+     123             :   Action(ao),
+     124           2 :   ActionShortcut(ao)
+     125             : {
+     126             :   // Find the argument name
+     127           2 :   std::string argn; parse("ARG",argn);
+     128           2 :   ActionShortcut* as = plumed.getActionSet().getShortcutActionWithLabel( argn );
+     129           2 :   if( !as || as->getName()!="COLLECT_FRAMES" ) error("found no COLLECT_FRAMES action with label " + argn );
+     130             :   // Get the final weights using the logsumexp trick
+     131           4 :   readInputLine( getShortcutLabel() + "_weights: LOGSUMEXP ARG=" + argn + "_logweights");
+     132             :   // Now transpose the collected frames
+     133           4 :   readInputLine( getShortcutLabel() + "_dataT: TRANSPOSE ARG=" + argn + "_data");
+     134             :   // And multiply the transpose by the weights to get the averages
+     135           4 :   readInputLine( getShortcutLabel() + "_mean: MATRIX_VECTOR_PRODUCT ARG=" + getShortcutLabel() + "_dataT," + getShortcutLabel() + "_weights");
+     136             :   // Make a matrix of averages
+     137           4 :   readInputLine( getShortcutLabel() + "_averages: OUTER_PRODUCT ARG=" + argn + "_ones," + getShortcutLabel() + "_mean");
+     138             :   // Make a matrix of weights
+     139           2 :   ActionWithValue* av2 = plumed.getActionSet().selectWithLabel<ActionWithValue*>( argn + "_data" );
+     140           2 :   if( !av2 ) error("count not find data");
+     141           2 :   unsigned nones = (av2->copyOutput(0))->getShape()[1];
+     142          68 :   std::string ones="1"; for(unsigned i=1; i<nones; ++i) ones += ",1";
+     143           4 :   readInputLine( getShortcutLabel() + "_wones: CONSTANT VALUES=" + ones );
+     144           4 :   readInputLine( getShortcutLabel() + "_wmat: OUTER_PRODUCT ARG=" + getShortcutLabel() + "_weights," + getShortcutLabel() + "_wones");
+     145             :   // And compute the data substract the mean
+     146           4 :   readInputLine( getShortcutLabel() + "_diff: CUSTOM ARG=" + argn + "_data," + getShortcutLabel() + "_averages FUNC=(x-y) PERIODIC=NO");
+     147           4 :   readInputLine( getShortcutLabel() + "_wdiff: CUSTOM ARG=" + getShortcutLabel() + "_wmat," + getShortcutLabel() + "_diff FUNC=sqrt(x)*y PERIODIC=NO");
+     148             :   // And the covariance
+     149           4 :   readInputLine( getShortcutLabel() + "_wdiffT: TRANSPOSE ARG=" + getShortcutLabel() + "_wdiff");
+     150           4 :   readInputLine( getShortcutLabel() + "_covar: MATRIX_PRODUCT ARG=" + getShortcutLabel() + "_wdiffT," + getShortcutLabel() + "_wdiff");
+     151             :   // Read the dimensionality of the low dimensional space
+     152           4 :   unsigned ndim; parse("NLOW_DIM",ndim); std::string vecstr="1";
+     153           2 :   if( ndim<=0 || ndim>nones ) error("cannot generate projection in space of dimension higher than input coordinates");
+     154           6 :   for(unsigned i=1; i<ndim; ++i) { std::string num; Tools::convert( i+1, num ); vecstr += "," + num; }
+     155           4 :   readInputLine( getShortcutLabel() + "_eig: DIAGONALIZE ARG=" + getShortcutLabel() + "_covar VECTORS=" + vecstr );
+     156             :   // Now create a matrix to hold the output data
+     157           2 :   std::string outd = "ARG=" + getShortcutLabel() + "_mean";
+     158          10 :   for(unsigned i=0; i<ndim; ++i) { std::string num; Tools::convert( i+1, num ); outd += "," + getShortcutLabel() + "_eig.vecs-" + num; }
+     159           4 :   readInputLine( getShortcutLabel() + "_pcaT: VSTACK " + outd );
+     160           4 :   readInputLine( getShortcutLabel() + "_pca: TRANSPOSE ARG=" + getShortcutLabel() + "_pcaT");
+     161             :   // And output it all
+     162           6 :   std::string filename, pstride; parse("STRIDE",pstride); parse("FILE",filename);
+     163           2 :   if( filename.length()>0 && av2->getName()=="VSTACK" ) {
+     164           1 :     std::vector<std::string> argnames; av2->getMatrixColumnTitles( argnames );
+     165           2 :     std::string argname_str=argnames[0]; for(unsigned i=1; i<argnames.size(); ++i) argname_str += "," + argnames[i];
+     166           3 :     std::string fmt; parse("FMT",fmt); if( fmt.length()>0 ) fmt=" FMT=" + fmt;
+     167           2 :     readInputLine("DUMPPDB DESCRIPTION=PCA ARG_NAMES=" + argname_str + " ARG=" + getShortcutLabel() + "_pca FILE=" + filename + " STRIDE=" + pstride + fmt );
+     168           1 :   } else {
+     169           1 :     if( av2->getName()!="COLLECT" ) error("input data should be VSTACK if list of arguments of COLLECT if atom positions");
+     170           1 :     ActionAtomistic* rmsdact = plumed.getActionSet().selectWithLabel<ActionAtomistic*>( argn + "_getposx" );
+     171           1 :     if( !rmsdact ) error("could not find action that gets positions from trajectory for RMSD");
+     172           1 :     std::vector<AtomNumber> atoms( rmsdact->getAbsoluteIndexes() ); std::string indices; Tools::convert( atoms[0].serial(), indices );
+     173          22 :     for(unsigned i=1; i<atoms.size(); ++i) { std::string jnum; Tools::convert( atoms[i].serial(), jnum ); indices += "," + jnum; }
+     174           2 :     readInputLine("DUMPPDB DESCRIPTION=PCA ATOM_INDICES=" + indices + " ATOMS=" + getShortcutLabel() + "_pca FILE=" + filename + " STRIDE=" + pstride );
+     175             :   }
+     176           4 :   outd = "ARG=" + getShortcutLabel() + "_eig.vecs-1";
+     177           6 :   for(unsigned i=1; i<ndim; ++i) { std::string num; Tools::convert( i+1, num ); outd += "," + getShortcutLabel() + "_eig.vecs-" + num; }
+     178           4 :   readInputLine( getShortcutLabel() + "_eigv: VSTACK " + outd );
+     179           4 :   readInputLine( getShortcutLabel() + ": MATRIX_PRODUCT ARG=" + getShortcutLabel() + "_diff," + getShortcutLabel() + "_eigv");
+     180           2 : }
+     181             : 
+     182             : }
+     183             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/ProjectPoints.cpp.func-sort-c.html b/coverage/dimred/ProjectPoints.cpp.func-sort-c.html new file mode 100644 index 000000000000..6546fef7743b --- /dev/null +++ b/coverage/dimred/ProjectPoints.cpp.func-sort-c.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - dimred/ProjectPoints.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - dimred - ProjectPoints.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:858896.6 %
Date:2024-04-19 12:12:35Functions:81080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred13ProjectPoints22getNumberOfDerivativesEv0
_ZN4PLMD6dimred13ProjectPointsC2ERKNS_13ActionOptionsE0
_ZN4PLMD6dimred13ProjectPointsC1ERKNS_13ActionOptionsE2
_ZN4PLMD6dimred13ProjectPoints16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD6dimred13ProjectPoints5applyEv168
_ZN4PLMD6dimred13ProjectPoints7prepareEv169
_ZN4PLMD6dimred13ProjectPoints9calculateEv169
_ZNK4PLMD6dimred13ProjectPoints11performTaskERKjRNS_10MultiValueE500
_ZNK4PLMD6dimred13ProjectPoints13getProjectionERKjRSt6vectorIdSaIdEE668
_ZN4PLMD6dimred13ProjectPoints15calculateStressERKSt6vectorIdSaIdEERS4_24180
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/ProjectPoints.cpp.func.html b/coverage/dimred/ProjectPoints.cpp.func.html new file mode 100644 index 000000000000..d418da29a090 --- /dev/null +++ b/coverage/dimred/ProjectPoints.cpp.func.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - dimred/ProjectPoints.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - dimred - ProjectPoints.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:858896.6 %
Date:2024-04-19 12:12:35Functions:81080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred13ProjectPoints15calculateStressERKSt6vectorIdSaIdEERS4_24180
_ZN4PLMD6dimred13ProjectPoints16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD6dimred13ProjectPoints22getNumberOfDerivativesEv0
_ZN4PLMD6dimred13ProjectPoints5applyEv168
_ZN4PLMD6dimred13ProjectPoints7prepareEv169
_ZN4PLMD6dimred13ProjectPoints9calculateEv169
_ZN4PLMD6dimred13ProjectPointsC1ERKNS_13ActionOptionsE2
_ZN4PLMD6dimred13ProjectPointsC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6dimred13ProjectPoints11performTaskERKjRNS_10MultiValueE500
_ZNK4PLMD6dimred13ProjectPoints13getProjectionERKjRSt6vectorIdSaIdEE668
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/ProjectPoints.cpp.gcov.html b/coverage/dimred/ProjectPoints.cpp.gcov.html new file mode 100644 index 000000000000..0c6ca79a44ae --- /dev/null +++ b/coverage/dimred/ProjectPoints.cpp.gcov.html @@ -0,0 +1,260 @@ + + + + + + + + LCOV - plumed test coverage - dimred/ProjectPoints.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - dimred - ProjectPoints.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:858896.6 %
Date:2024-04-19 12:12:35Functions:81080.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2020 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received 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/ActionWithVector.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "tools/ConjugateGradient.h"
+      25             : #include "tools/SwitchingFunction.h"
+      26             : #include "tools/OpenMP.h"
+      27             : #include "tools/Random.h"
+      28             : 
+      29             : namespace PLMD {
+      30             : namespace dimred {
+      31             : 
+      32             : //+PLUMEDOC DIMRED PROJECT_POINTS
+      33             : /*
+      34             : Find the projection of a point in a low dimensional space by matching the (transformed) distance between it and a series of reference configurations that were input
+      35             : 
+      36             : \par Examples
+      37             : 
+      38             : */
+      39             : //+ENDPLUMEDOC
+      40             : 
+      41             : class ProjectPoints : public ActionWithVector {
+      42             : private:
+      43             :   double cgtol;
+      44             :   unsigned dimout;
+      45             :   mutable std::vector<unsigned> rowstart;
+      46             :   std::vector<SwitchingFunction> switchingFunction;
+      47             :   ConjugateGradient<ProjectPoints> myminimiser;
+      48             :   void getProjection( const unsigned& current, std::vector<double>& point ) const ;
+      49             : public:
+      50             :   static void registerKeywords( Keywords& keys );
+      51             :   ProjectPoints( const ActionOptions& );
+      52           0 :   unsigned getNumberOfDerivatives() { return 0; }
+      53             :   void prepare() override ;
+      54             :   void performTask( const unsigned& current, MultiValue& myvals ) const override ;
+      55             :   double calculateStress( const std::vector<double>& pp, std::vector<double>& der );
+      56             :   void calculate() override ;
+      57         168 :   void apply() override {}
+      58             : };
+      59             : 
+      60             : PLUMED_REGISTER_ACTION(ProjectPoints,"PROJECT_POINTS")
+      61             : 
+      62           4 : void ProjectPoints::registerKeywords( Keywords& keys ) {
+      63           4 :   ActionWithVector::registerKeywords( keys ); keys.use("ARG");
+      64           8 :   keys.add("numbered","TARGET","the matrix of target quantities that you would like to match");
+      65           8 :   keys.add("numbered","FUNC","a function that is applied on the distances between the points in the low dimensional space");
+      66           8 :   keys.add("numbered","WEIGHTS","the matrix with the weights of the target quantities");
+      67           8 :   keys.add("compulsory","CGTOL","1E-6","the tolerance for the conjugate gradient minimization");
+      68           8 :   keys.addOutputComponent("coord","default","the coordinates of the points in the low dimensional space");
+      69           4 : }
+      70             : 
+      71             : 
+      72           2 : ProjectPoints::ProjectPoints( const ActionOptions& ao ) :
+      73             :   Action(ao),
+      74             :   ActionWithVector(ao),
+      75           2 :   rowstart(OpenMP::getNumThreads()),
+      76           4 :   myminimiser( this )
+      77             : {
+      78           2 :   dimout = getNumberOfArguments(); unsigned nvals=getPntrToArgument(0)->getNumberOfValues();
+      79           6 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+      80           4 :     if( nvals!=getPntrToArgument(i)->getNumberOfValues() ) error("mismatch between numbers of projections");
+      81             :   }
+      82           2 :   std::vector<Value*> args( getArguments() ), target, weights; std::string sfd, errors; unsigned ntoproj=0;
+      83             :   // Read in target "distances" and target weights
+      84           2 :   for(unsigned i=1;; ++i) {
+      85           8 :     target.resize(0); if( !parseArgumentList("TARGET",i,target) ) break;
+      86           2 :     std::string inum; Tools::convert( i, inum );
+      87           2 :     if( target.size()!=1 ) error("should only be one value in input to TARGET" + inum );
+      88           2 :     if( (target[0]->getRank()!=1 && target[0]->getRank()!=2) || target[0]->hasDerivatives() ) error("input to TARGET" + inum + " keyword should be a vector/matrix");
+      89           2 :     if( target[0]->getShape()[0]!=nvals ) error("number of rows in target matrix should match number of input coordinates");
+      90           2 :     if( i==1 && target[0]->getRank()==1 ) { ntoproj = 1; }
+      91           1 :     else if( ntoproj==1 && target[0]->getRank()!=1 ) error("mismatch between numbers of target distances");
+      92           1 :     else if( i==1 ) ntoproj = target[0]->getShape()[1];
+      93           0 :     else if( ntoproj!=target[0]->getShape()[1] ) error("mismatch between numbers of target distances");
+      94           4 :     if( !parseArgumentList("WEIGHTS",i,weights) ) error("missing WEIGHTS" + inum + " keyword in input");
+      95           2 :     if( weights.size()!=1 ) error("should only be one value in input to WEIGHTS" + inum );
+      96           2 :     if( weights[0]->getRank()!=1 || weights[0]->hasDerivatives() ) error("input to WEIGHTS" + inum + " keyword should be a vector");
+      97           2 :     if( weights[0]->getShape()[0]!=nvals ) error("number of weights should match number of input coordinates");
+      98           2 :     target[0]->buildDataStore(); weights[0]->buildDataStore(); args.push_back( target[0] ); args.push_back( weights[0] );
+      99           4 :     bool has_sf = parseNumbered("FUNC",i,sfd); switchingFunction.push_back( SwitchingFunction() );
+     100           2 :     if( !has_sf ) {
+     101           0 :       switchingFunction[i-1].set( "CUSTOM FUNC=1-sqrt(x2) R_0=1.0", errors );
+     102             :     } else {
+     103           2 :       switchingFunction[i-1].set( sfd, errors );
+     104           2 :       if( errors.length()!=0 ) error("problem reading switching function description " + errors);
+     105             :     }
+     106           2 :     log.printf("  %sth term seeks to match tranformed distances with those in matrix %s \n", inum.c_str(), target[0]->getName().c_str() );
+     107           2 :     log.printf("  in %sth term distances are transformed by 1-switching function with r_0=%s \n", inum.c_str(), switchingFunction[i-1].description().c_str() );
+     108           2 :     log.printf("  in %sth term weights of matrix elements in stress function are given by %s \n", inum.c_str(), weights[0]->getName().c_str() );
+     109           2 :   }
+     110           2 :   std::vector<unsigned> shape(1); shape[0]=ntoproj; if( ntoproj==1 ) shape.resize(0);
+     111           6 :   for(unsigned i=0; i<dimout; ++i) {
+     112           4 :     std::string num; Tools::convert( i+1, num ); addComponent( "coord-" + num, shape );
+     113           8 :     componentIsNotPeriodic( "coord-" + num );
+     114             :   }
+     115             :   // Create a list of tasks to perform
+     116           4 :   parse("CGTOL",cgtol); log.printf("  tolerance for conjugate gradient algorithm equals %f \n",cgtol);
+     117           2 :   requestArguments( args ); checkRead();
+     118           2 : }
+     119             : 
+     120         169 : void ProjectPoints::prepare() {
+     121         169 :   if( getPntrToComponent(0)->getRank()==0 ) return;
+     122             : 
+     123           1 :   std::vector<unsigned> shape(1); shape[0] = getPntrToArgument(dimout)->getShape()[0];
+     124           3 :   for(unsigned i=0; i<dimout; ++i) {
+     125           2 :     if( getPntrToComponent(i)->getShape()[0]!=shape[0] ) getPntrToComponent(i)->setShape(shape);
+     126             :   }
+     127             : }
+     128             : 
+     129       24180 : double ProjectPoints::calculateStress( const std::vector<double>& pp, std::vector<double>& der ) {
+     130       24180 :   unsigned nmatrices = ( getNumberOfArguments() - dimout ) / 2; double stress=0;
+     131             : 
+     132       24180 :   unsigned t=OpenMP::getThreadNum();
+     133       24180 :   std::vector<double> dtmp( pp.size() ); unsigned nland = getPntrToArgument(0)->getShape()[0];
+     134     4889418 :   for(unsigned i=0; i<nland; ++i) {
+     135             :     // Calculate distance in low dimensional space
+     136    14595714 :     double dd2 = 0; for(unsigned k=0; k<pp.size(); ++k) { dtmp[k] = pp[k] - getPntrToArgument(k)->get(i); dd2 += dtmp[k]*dtmp[k]; }
+     137             : 
+     138     9730476 :     for(unsigned k=0; k<nmatrices; ++k ) {
+     139             :       // Now do transformations and calculate differences
+     140     4865238 :       double df, fd = 1. - switchingFunction[k].calculateSqr( dd2, df );
+     141             :       // Get the weight for this connection
+     142     4865238 :       double weight = getPntrToArgument( dimout + 2*k + 1 )->get( i );
+     143             :       // Get the difference for the connection
+     144     4865238 :       double fdiff = fd - getPntrToArgument( dimout + 2*k )->get( rowstart[t]+i );
+     145             :       // Calculate derivatives
+     146    14595714 :       double pref = -2.*weight*fdiff*df; for(unsigned n=0; n<pp.size(); ++n) der[n]+=pref*dtmp[n];
+     147             :       // Accumulate the total stress
+     148     4865238 :       stress += weight*fdiff*fdiff;
+     149             :     }
+     150             :   }
+     151       24180 :   return stress;
+     152             : }
+     153             : 
+     154         668 : void ProjectPoints::getProjection( const unsigned& current, std::vector<double>& point ) const {
+     155         668 :   Value* targ = getPntrToArgument( dimout ); unsigned nland = getPntrToArgument(0)->getShape()[0];
+     156         668 :   unsigned base = current; if( targ->getRank()==2 ) base = current*targ->getShape()[1];
+     157         668 :   unsigned closest=0; double mindist = targ->get( base );
+     158      139112 :   for(unsigned i=1; i<nland; ++i) {
+     159      138444 :     double dist = targ->get( base + i );
+     160      138444 :     if( dist<mindist ) { mindist=dist; closest=i; }
+     161             :   }
+     162             :   // Put the initial guess near to the closest landmark  -- may wish to use grid here again Sandip??
+     163         668 :   Random random; random.setSeed(-1234);
+     164        2004 :   for(unsigned j=0; j<dimout; ++j) point[j] = getPntrToArgument(j)->get(closest) + (random.RandU01() - 0.5)*0.01;
+     165             :   // And do the optimisation
+     166         668 :   rowstart[OpenMP::getThreadNum()]=current; if( targ->getRank()==2 ) rowstart[OpenMP::getThreadNum()] = current*targ->getShape()[1];
+     167         668 :   myminimiser.minimise( cgtol, point, &ProjectPoints::calculateStress );
+     168         668 : }
+     169             : 
+     170         500 : void ProjectPoints::performTask( const unsigned& current, MultiValue& myvals ) const {
+     171         500 :   std::vector<double> point( dimout ); getProjection( current, point );
+     172        1500 :   for(unsigned j=0; j<dimout; ++j) myvals.setValue( getConstPntrToComponent(j)->getPositionInStream(), point[j] );
+     173         500 : }
+     174             : 
+     175         169 : void ProjectPoints::calculate() {
+     176         169 :   if( getPntrToComponent(0)->getRank()==0 ) {
+     177         168 :     std::vector<double> point( dimout ); getProjection( 0, point );
+     178         504 :     for(unsigned i=0; i<dimout; ++i) getPntrToComponent(i)->set(point[i]);
+     179           1 :   } else runAllTasks();
+     180         169 : }
+     181             : 
+     182             : }
+     183             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/SMACOF.cpp.func-sort-c.html b/coverage/dimred/SMACOF.cpp.func-sort-c.html new file mode 100644 index 000000000000..d18fa9db476a --- /dev/null +++ b/coverage/dimred/SMACOF.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + 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:424397.7 %
Date:2024-04-19 12:12:35Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred6SMACOF8optimizeERKdRKjRSt6vectorIdSaIdEE1
_ZN4PLMD6dimred6SMACOFC2EPKNS_5ValueE1
_ZN4PLMD6dimred6SMACOF14calculateSigmaERKNS_6MatrixIdEERS3_15
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/SMACOF.cpp.func.html b/coverage/dimred/SMACOF.cpp.func.html new file mode 100644 index 000000000000..d7e4823d30e5 --- /dev/null +++ b/coverage/dimred/SMACOF.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + 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:424397.7 %
Date:2024-04-19 12:12:35Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred6SMACOF14calculateSigmaERKNS_6MatrixIdEERS3_15
_ZN4PLMD6dimred6SMACOF8optimizeERKdRKjRSt6vectorIdSaIdEE1
_ZN4PLMD6dimred6SMACOFC2EPKNS_5ValueE1
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/SMACOF.cpp.gcov.html b/coverage/dimred/SMACOF.cpp.gcov.html new file mode 100644 index 000000000000..11c05feeb7fa --- /dev/null +++ b/coverage/dimred/SMACOF.cpp.gcov.html @@ -0,0 +1,187 @@ + + + + + + + + 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:424397.7 %
Date:2024-04-19 12:12:35Functions:33100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2020 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received 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 : SMACOF::SMACOF( const Value* target)
+      28             : {
+      29           1 :   std::vector<unsigned> shape( target->getShape() );
+      30           1 :   Distances.resize( shape[0], shape[1] ); Weights.resize( shape[0], shape[1] );
+      31         501 :   for(unsigned i=0; i<shape[0]; ++i) {
+      32      250500 :     for(unsigned j=0; j<shape[1]; ++j) Distances(i,j) = sqrt( target->get(shape[0]*i+j) );
+      33             :   }
+      34           1 : }
+      35             : 
+      36           1 : void SMACOF::optimize( const double& tol, const unsigned& maxloops, std::vector<double>& proj ) {
+      37           1 :   unsigned M = Distances.nrows(); unsigned nlow=proj.size() / M; Matrix<double> Z( M, nlow );
+      38             :   // Transfer initial projection to matrix
+      39             :   unsigned k = 0;
+      40         501 :   for(unsigned i=0; i<M; ++i) {
+      41        1500 :     for(unsigned j=0; j<nlow; ++j) { Z(i,j)=proj[k]; k++; }
+      42             :   }
+      43             : 
+      44             :   // Calculate V
+      45             :   Matrix<double> V(M,M);
+      46         501 :   for(unsigned i=0; i<M; ++i) {
+      47      250500 :     for(unsigned j=0; j<M; ++j) {
+      48      250000 :       if(i==j) continue;
+      49      249500 :       V(i,j)=-Weights(i,j);
+      50             :     }
+      51      250500 :     for(unsigned j=0; j<M; ++j) {
+      52      250000 :       if(i==j)continue;
+      53      249500 :       V(i,i)-=V(i,j);
+      54             :     }
+      55             :   }
+      56             :   // And pseudo invert V
+      57           1 :   Matrix<double> mypseudo(M, M); pseudoInvert(V, mypseudo);
+      58           1 :   Matrix<double> dists( M, M ); double myfirstsig = calculateSigma( Z, dists );
+      59             : 
+      60             :   // initial sigma is made up of the original distances minus the distances between the projections all squared.
+      61             :   Matrix<double> temp( M, M ), BZ( M, M ), newZ( M, nlow );
+      62          14 :   for(unsigned n=0; n<maxloops; ++n) {
+      63          14 :     if(n==maxloops-1) plumed_merror("ran out of steps in SMACOF algorithm");
+      64             : 
+      65             :     // Recompute BZ matrix
+      66        7014 :     for(unsigned i=0; i<M; ++i) {
+      67     3507000 :       for(unsigned j=0; j<M; ++j) {
+      68     3500000 :         if(i==j) continue;  //skips over the diagonal elements
+      69             : 
+      70     3493000 :         if( dists(i,j)>0 ) BZ(i,j) = -Weights(i,j)*Distances(i,j) / dists(i,j);
+      71           0 :         else BZ(i,j)=0.;
+      72             :       }
+      73             :       //the diagonal elements are -off diagonal elements BZ(i,i)-=BZ(i,j)   (Equation 8.25)
+      74        7000 :       BZ(i,i)=0; //create the space memory for the diagonal elements which are scalars
+      75     3507000 :       for(unsigned j=0; j<M; ++j) {
+      76     3500000 :         if(i==j) continue;
+      77     3493000 :         BZ(i,i)-=BZ(i,j);
+      78             :       }
+      79             :     }
+      80             : 
+      81          14 :     mult( mypseudo, BZ, temp); mult(temp, Z, newZ);
+      82             :     //Compute new sigma
+      83          14 :     double newsig = calculateSigma( newZ, dists );
+      84             :     //Computing whether the algorithm has converged (has the mass of the potato changed
+      85             :     //when we put it back in the oven!)
+      86          14 :     if( fabs( newsig - myfirstsig )<tol ) break;
+      87             :     myfirstsig=newsig; Z = newZ;
+      88             :   }
+      89             : 
+      90             :   // Transfer final projection matrix to output proj
+      91             :   k = 0;
+      92         501 :   for(unsigned i=0; i<M; ++i) {
+      93        1500 :     for(unsigned j=0; j<nlow; ++j) { proj[k]=Z(i,j); k++; }
+      94             :   }
+      95           1 : }
+      96             : 
+      97          15 : double SMACOF::calculateSigma( const Matrix<double>& Z, Matrix<double>& dists ) {
+      98             :   unsigned M = Distances.nrows(); double sigma=0; double totalWeight=0;
+      99        7500 :   for(unsigned i=1; i<M; ++i) {
+     100     1878735 :     for(unsigned j=0; j<i; ++j) {
+     101     5613750 :       double dlow=0; for(unsigned k=0; k<Z.ncols(); ++k) { double tmp=Z(i,k) - Z(j,k); dlow+=tmp*tmp; }
+     102     1871250 :       dists(i,j)=dists(j,i)=sqrt(dlow); double tmp3 = Distances(i,j) - dists(i,j);
+     103     1871250 :       sigma += Weights(i,j)*tmp3*tmp3; totalWeight+=Weights(i,j);
+     104             :     }
+     105             :   }
+     106          15 :   return sigma / totalWeight;
+     107             : }
+     108             : 
+     109             : }
+     110             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/SMACOF.h.func-sort-c.html b/coverage/dimred/SMACOF.h.func-sort-c.html new file mode 100644 index 000000000000..0cc5ec5299a7 --- /dev/null +++ b/coverage/dimred/SMACOF.h.func-sort-c.html @@ -0,0 +1,77 @@ + + + + + + + + LCOV - plumed test coverage - dimred/SMACOF.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - dimred - SMACOF.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:55100.0 %
Date:2024-04-19 12:12:35Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred6SMACOF9setWeightERKjS3_RKd499000
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/SMACOF.h.func.html b/coverage/dimred/SMACOF.h.func.html new file mode 100644 index 000000000000..61477244b040 --- /dev/null +++ b/coverage/dimred/SMACOF.h.func.html @@ -0,0 +1,77 @@ + + + + + + + + LCOV - plumed test coverage - dimred/SMACOF.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - dimred - SMACOF.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:55100.0 %
Date:2024-04-19 12:12:35Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred6SMACOF9setWeightERKjS3_RKd499000
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/SMACOF.h.gcov.html b/coverage/dimred/SMACOF.h.gcov.html new file mode 100644 index 000000000000..b9bf1ec55c50 --- /dev/null +++ b/coverage/dimred/SMACOF.h.gcov.html @@ -0,0 +1,132 @@ + + + + + + + + LCOV - plumed test coverage - dimred/SMACOF.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - dimred - SMACOF.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:55100.0 %
Date:2024-04-19 12:12:35Functions:11100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2020 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a 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_SMACOF_h
+      23             : #define __PLUMED_dimred_SMACOF_h
+      24             : 
+      25             : #include <vector>
+      26             : #include "core/Value.h"
+      27             : #include "tools/Matrix.h"
+      28             : 
+      29             : namespace PLMD {
+      30             : namespace dimred {
+      31             : 
+      32           1 : class SMACOF {
+      33             : private:
+      34             :   Matrix<double> Distances, Weights;
+      35             :   double calculateSigma( const Matrix<double>& InitialZ, Matrix<double>& dists );
+      36             : public:
+      37             :   explicit SMACOF( const Value* mysquaredists );
+      38             :   void optimize( const double& tol, const unsigned& maxloops, std::vector<double>& proj);
+      39             :   double getDistance( const unsigned& i, const unsigned& j ) const ;
+      40             :   void setWeight( const unsigned& i, const unsigned& j, const double& ww );
+      41             : };
+      42             : 
+      43             : inline
+      44             : double SMACOF::getDistance( const unsigned& i, const unsigned& j ) const {
+      45      249500 :   return Distances( i, j );
+      46             : }
+      47             : 
+      48             : inline
+      49      499000 : void SMACOF::setWeight( const unsigned& i, const unsigned& j, const double& ww ) {
+      50      499000 :   Weights(i,j) = Weights(j,i ) = ww;
+      51      499000 : }
+      52             : 
+      53             : }
+      54             : }
+      55             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/SketchMap.cpp.func-sort-c.html b/coverage/dimred/SketchMap.cpp.func-sort-c.html new file mode 100644 index 000000000000..b6d6f34e523a --- /dev/null +++ b/coverage/dimred/SketchMap.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - dimred/SketchMap.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - dimred - SketchMap.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:677095.7 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred9SketchMapC2ERKNS_13ActionOptionsE0
_ZN4PLMD6dimred9SketchMapC1ERKNS_13ActionOptionsE4
_ZN4PLMD6dimred9SketchMap16registerKeywordsERNS_8KeywordsE10
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/SketchMap.cpp.func.html b/coverage/dimred/SketchMap.cpp.func.html new file mode 100644 index 000000000000..671b6c7ddcbf --- /dev/null +++ b/coverage/dimred/SketchMap.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - dimred/SketchMap.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - dimred - SketchMap.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:677095.7 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred9SketchMap16registerKeywordsERNS_8KeywordsE10
_ZN4PLMD6dimred9SketchMapC1ERKNS_13ActionOptionsE4
_ZN4PLMD6dimred9SketchMapC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/SketchMap.cpp.gcov.html b/coverage/dimred/SketchMap.cpp.gcov.html new file mode 100644 index 000000000000..2ea9a7e06e88 --- /dev/null +++ b/coverage/dimred/SketchMap.cpp.gcov.html @@ -0,0 +1,216 @@ + + + + + + + + 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:677095.7 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2020 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received 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/PlumedMain.h"
+      24             : #include "core/ActionSet.h"
+      25             : #include "core/ActionRegister.h"
+      26             : #include "core/ActionWithValue.h"
+      27             : 
+      28             : //+PLUMEDOC DIMRED SKETCHMAP
+      29             : /*
+      30             : Construct a sketch map projection of the input data
+      31             : 
+      32             : \par Examples
+      33             : 
+      34             : */
+      35             : //+ENDPLUMEDOC
+      36             : 
+      37             : namespace PLMD {
+      38             : namespace dimred {
+      39             : 
+      40             : class SketchMap : public ActionShortcut {
+      41             : public:
+      42             :   static void registerKeywords( Keywords& keys );
+      43             :   explicit SketchMap( const ActionOptions& ao );
+      44             : };
+      45             : 
+      46             : PLUMED_REGISTER_ACTION(SketchMap,"SKETCHMAP")
+      47             : 
+      48          10 : void SketchMap::registerKeywords( Keywords& keys ) {
+      49          10 :   ActionShortcut::registerKeywords( keys );
+      50          20 :   keys.add("compulsory","NLOW_DIM","number of low-dimensional coordinates required");
+      51          20 :   keys.add("optional","WEIGHTS","a vector containing the weights of the points");
+      52          20 :   keys.add("compulsory","ARG","the matrix of high dimensional coordinates that you want to project in the low dimensional space");
+      53          20 :   keys.add("compulsory","HIGH_DIM_FUNCTION","the parameters of the switching function in the high dimensional space");
+      54          20 :   keys.add("compulsory","LOW_DIM_FUNCTION","the parameters of the switching function in the low dimensional space");
+      55          20 :   keys.add("compulsory","CGTOL","1E-6","The tolerance for the conjugate gradient minimization that finds the projection of the landmarks");
+      56          20 :   keys.add("compulsory","MAXITER","1000","maximum number of optimization cycles for optimisation algorithms");
+      57          20 :   keys.add("compulsory","NCYCLES","0","The number of cycles of pointwise global optimisation that are required");
+      58          20 :   keys.add("compulsory","BUFFER","1.1","grid extent for search is (max projection - minimum projection) multiplied by this value");
+      59          20 :   keys.add("compulsory","CGRID_SIZE","10","number of points to use in each grid direction");
+      60          20 :   keys.add("compulsory","FGRID_SIZE","0","interpolate the grid onto this number of points -- only works in 2D");
+      61          20 :   keys.addFlag("PROJECT_ALL",false,"if the input are landmark coordinates then project the out of sample configurations");
+      62          20 :   keys.add("compulsory","OS_CGTOL","1E-6","The tolerance for the conjugate gradient minimization that finds the out of sample projections");
+      63          20 :   keys.addFlag("USE_SMACOF",false,"find the projection in the low dimensional space using the SMACOF algorithm");
+      64          20 :   keys.add("compulsory","SMACTOL","1E-4","the tolerance for the smacof algorithm");
+      65          20 :   keys.add("compulsory","SMACREG","0.001","this is used to ensure that we don't divide by zero when updating weights for SMACOF algorithm");
+      66          40 :   keys.needsAction("CLASSICAL_MDS"); keys.needsAction("MORE_THAN"); keys.needsAction("SUM"); keys.needsAction("CUSTOM");
+      67          30 :   keys.needsAction("OUTER_PRODUCT"); keys.needsAction("ARRANGE_POINTS"); keys.needsAction("PROJECT_POINTS");
+      68          10 : }
+      69             : 
+      70           4 : SketchMap::SketchMap( const ActionOptions& ao):
+      71             :   Action(ao),
+      72           4 :   ActionShortcut(ao)
+      73             : {
+      74             :   // Get the high dimensioal data
+      75           8 :   std::string argn; parse("ARG",argn); std::string dissimilarities = getShortcutLabel() + "_mds_mat";
+      76           4 :   ActionShortcut* as = plumed.getActionSet().getShortcutActionWithLabel( argn );
+      77           4 :   if( !as ) error("found no action with name " + argn );
+      78           4 :   if( as->getName()!="COLLECT_FRAMES" ) {
+      79           1 :     if( as->getName().find("LANDMARK_SELECT")==std::string::npos ) {
+      80           0 :       error("found no COLLECT_FRAMES or LANDMARK_SELECT action with label " + argn );
+      81             :     } else {
+      82           1 :       ActionWithValue* dissims = plumed.getActionSet().selectWithLabel<ActionWithValue*>( argn + "_sqrdissims");
+      83           2 :       if( dissims ) dissimilarities = argn + "_sqrdissims";
+      84             :     }
+      85             :   }
+      86           8 :   unsigned ndim; parse("NLOW_DIM",ndim);
+      87           4 :   std::string str_ndim; Tools::convert( ndim, str_ndim );
+      88             :   // Construct a projection using classical MDS
+      89           8 :   readInputLine( getShortcutLabel() + "_mds: CLASSICAL_MDS ARG=" + argn + " NLOW_DIM=" + str_ndim );
+      90             :   // Transform the dissimilarities using the switching function
+      91           4 :   std::string hdfunc; parse("HIGH_DIM_FUNCTION",hdfunc);
+      92           8 :   readInputLine( getShortcutLabel() + "_hdmat: MORE_THAN ARG=" + dissimilarities + " SQUARED SWITCH={" + hdfunc + "}");
+      93             :   // Now for the weights - read the vector of weights first
+      94           9 :   std::string wvec; parse("WEIGHTS",wvec); if( wvec.length()==0 ) wvec = argn + "_weights";
+      95             :   // Now calculate the sum of thse weights
+      96           8 :   readInputLine( wvec + "_sum: SUM ARG=" + wvec + " PERIODIC=NO");
+      97             :   // And normalise the vector of weights using this sum
+      98           8 :   readInputLine( wvec + "_normed: CUSTOM ARG=" + wvec + "_sum," + wvec + " FUNC=y/x PERIODIC=NO");
+      99             :   // And now create the matrix of weights
+     100           8 :   readInputLine( wvec + "_mat: OUTER_PRODUCT ARG=" + wvec + "_normed," + wvec + "_normed");
+     101             :   // Run the arrange points object
+     102          20 :   std::string ldfunc, cgtol, maxiter; parse("LOW_DIM_FUNCTION",ldfunc); parse("CGTOL",cgtol); parse("MAXITER",maxiter); unsigned ncycles; parse("NCYCLES",ncycles);
+     103           5 :   std::string num, argstr, lname=getShortcutLabel(); if( ncycles>0 ) lname = getShortcutLabel() + "_cg";
+     104          12 :   argstr = "ARG=" + getShortcutLabel() + "_mds-1"; for(unsigned i=1; i<ndim; ++i) { Tools::convert( i+1, num ); argstr += "," + getShortcutLabel() + "_mds-" + num; }
+     105           4 :   bool usesmacof; parseFlag("USE_SMACOF",usesmacof);
+     106           4 :   if( usesmacof ) {
+     107           2 :     std::string smactol, smacreg; parse("SMACTOL",smactol); parse("SMACREG",smacreg);
+     108           3 :     readInputLine( lname + ": ARRANGE_POINTS " + argstr  + " MINTYPE=smacof TARGET1=" + getShortcutLabel() + "_hdmat FUNC1={" + ldfunc + "} WEIGHTS1=" + wvec + "_mat" +
+     109           3 :                    " MAXITER=" + maxiter + " SMACTOL=" + smactol + " SMACREG=" + smacreg + " TARGET2=" + getShortcutLabel() + "_mds_mat WEIGHTS2=" + wvec + "_mat");
+     110             :   } else {
+     111           6 :     readInputLine( lname + ": ARRANGE_POINTS " + argstr  + " MINTYPE=conjgrad TARGET1=" + getShortcutLabel() + "_hdmat FUNC1={" + ldfunc + "} WEIGHTS1=" + wvec + "_mat CGTOL=" + cgtol);
+     112           3 :     if( ncycles>0 ) {
+     113           2 :       std::string buf; parse("BUFFER",buf);
+     114           2 :       std::vector<std::string> fgrid; parseVector("FGRID_SIZE",fgrid);
+     115           2 :       std::string ncyc; Tools::convert(ncycles,ncyc); std::string pwise_args=" NCYCLES=" + ncyc + " BUFFER=" + buf;
+     116           1 :       if( fgrid.size()>0 ) {
+     117           1 :         if( fgrid.size()!=ndim ) error("number of elements of fgrid is not correct");
+     118           3 :         pwise_args += " FGRID_SIZE=" + fgrid[0];  for(unsigned i=1; i<fgrid.size(); ++i) pwise_args += "," + fgrid[i];
+     119             :       }
+     120           2 :       std::vector<std::string> cgrid(ndim); parseVector("CGRID_SIZE",cgrid);
+     121           3 :       pwise_args += " CGRID_SIZE=" + cgrid[0]; for(unsigned i=1; i<cgrid.size(); ++i) pwise_args += "," + cgrid[i];
+     122           3 :       argstr="ARG=" + getShortcutLabel() + "_cg.coord-1"; for(unsigned i=1; i<ndim; ++i) { Tools::convert( i+1, num ); argstr += "," + getShortcutLabel() + "_cg.coord-" + num; }
+     123           2 :       readInputLine( getShortcutLabel() + ": ARRANGE_POINTS " + argstr  + pwise_args + " MINTYPE=pointwise TARGET1=" + getShortcutLabel() + "_hdmat FUNC1={" + ldfunc + "} WEIGHTS1=" + wvec + "_mat CGTOL=" + cgtol);
+     124           2 :     }
+     125             :   }
+     126           8 :   bool projall; parseFlag("PROJECT_ALL",projall); if( !projall ) return ;
+     127           4 :   parse("OS_CGTOL",cgtol); argstr = getShortcutLabel() + ".coord-1"; for(unsigned i=1; i<ndim; ++i) { Tools::convert( i+1, num ); argstr += "," + getShortcutLabel() + ".coord-" + num; }
+     128           1 :   if( as->getName().find("LANDMARK_SELECT")==std::string::npos ) {
+     129           0 :     readInputLine( getShortcutLabel() + "_osample: PROJECT_POINTS " + argstr + " TARGET1=" + getShortcutLabel() + "_hdmat FUNC1={" + ldfunc + "} WEIGHTS1=" + wvec + "_normed CGTOL=" + cgtol );
+     130             :   } else {
+     131           1 :     ActionWithValue* dissims = plumed.getActionSet().selectWithLabel<ActionWithValue*>( argn + "_rectdissims");
+     132           1 :     if( !dissims ) error("cannot PROJECT_ALL as " + as->getName() + " with label " + argn + " was involved without the DISSIMILARITIES keyword");
+     133           2 :     readInputLine( getShortcutLabel() + "_lhdmat: MORE_THAN ARG=" + argn + "_rectdissims SQUARED SWITCH={" + hdfunc + "}");
+     134           2 :     readInputLine( getShortcutLabel() + "_osample: PROJECT_POINTS ARG=" + argstr + " TARGET1=" + getShortcutLabel() + "_lhdmat FUNC1={" + ldfunc + "} WEIGHTS1=" + wvec + "_normed CGTOL=" + cgtol );
+     135             :   }
+     136           0 : }
+     137             : 
+     138             : }
+     139             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/SketchMapProjection.cpp.func-sort-c.html b/coverage/dimred/SketchMapProjection.cpp.func-sort-c.html new file mode 100644 index 000000000000..01a9feff602e --- /dev/null +++ b/coverage/dimred/SketchMapProjection.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - dimred/SketchMapProjection.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - dimred - SketchMapProjection.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2828100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred19SketchMapProjectionC2ERKNS_13ActionOptionsE0
_ZN4PLMD6dimred19SketchMapProjectionC1ERKNS_13ActionOptionsE1
_ZN4PLMD6dimred19SketchMapProjection16registerKeywordsERNS_8KeywordsE4
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/SketchMapProjection.cpp.func.html b/coverage/dimred/SketchMapProjection.cpp.func.html new file mode 100644 index 000000000000..7ca5a119997c --- /dev/null +++ b/coverage/dimred/SketchMapProjection.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - dimred/SketchMapProjection.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - dimred - SketchMapProjection.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2828100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred19SketchMapProjection16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD6dimred19SketchMapProjectionC1ERKNS_13ActionOptionsE1
_ZN4PLMD6dimred19SketchMapProjectionC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/SketchMapProjection.cpp.gcov.html b/coverage/dimred/SketchMapProjection.cpp.gcov.html new file mode 100644 index 000000000000..b37820d9a452 --- /dev/null +++ b/coverage/dimred/SketchMapProjection.cpp.gcov.html @@ -0,0 +1,163 @@ + + + + + + + + LCOV - plumed test coverage - dimred/SketchMapProjection.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - dimred - SketchMapProjection.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2828100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2020 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionShortcut.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "mapping/Path.h"
+      25             : 
+      26             : //+PLUMEDOC DIMRED SKETCHMAP_PROJECTION
+      27             : /*
+      28             : Read in a sketch-map projection
+      29             : 
+      30             : \par Examples
+      31             : 
+      32             : */
+      33             : //+ENDPLUMEDOC
+      34             : 
+      35             : namespace PLMD {
+      36             : namespace dimred {
+      37             : 
+      38             : class SketchMapProjection : public ActionShortcut {
+      39             : public:
+      40             :   static void registerKeywords( Keywords& keys );
+      41             :   explicit SketchMapProjection( const ActionOptions& ao );
+      42             : };
+      43             : 
+      44             : PLUMED_REGISTER_ACTION(SketchMapProjection,"SKETCHMAP_PROJECTION")
+      45             : 
+      46           4 : void SketchMapProjection::registerKeywords( Keywords& keys ) {
+      47           4 :   ActionShortcut::registerKeywords( keys ); mapping::Path::registerInputFileKeywords( keys );
+      48           8 :   keys.add("compulsory","PROPERTY","the property to be used in the index. This should be in the REMARK of the reference");
+      49           8 :   keys.add("compulsory","WEIGHT","the weight of each individual landmark in the stress fucntion that is to be optimised");
+      50           8 :   keys.add("compulsory","HIGH_DIM_FUNCTION","the parameters of the switching function in the high dimensional space");
+      51           8 :   keys.add("compulsory","LOW_DIM_FUNCTION","the parameters of the switching function in the low dimensional space");
+      52           8 :   keys.add("compulsory","CGTOL","1E-6","The tolerance for the conjugate gradient minimization that finds the out of sample projections");
+      53          16 :   keys.needsAction("RMSD"); keys.needsAction("PDB2CONSTANT"); keys.needsAction("CONSTANT"); keys.needsAction("CUSTOM");
+      54           8 :   keys.needsAction("EUCLIDEAN_DISTANCE"); keys.needsAction("NORMALIZED_EUCLIDEAN_DISTANCE");
+      55          12 :   keys.needsAction("SUM"); keys.needsAction("MORE_THAN"); keys.needsAction("PROJECT_POINTS");
+      56           4 : }
+      57             : 
+      58           1 : SketchMapProjection::SketchMapProjection( const ActionOptions& ao):
+      59             :   Action(ao),
+      60           1 :   ActionShortcut(ao)
+      61             : {
+      62             :   // Use path to read in the projections
+      63             :   std::string refname, refactions, metric;
+      64           2 :   std::vector<std::string> argnames; parseVector("ARG",argnames);
+      65           2 :   std::string type, reference_data, reference; parse("REFERENCE",reference); parse("TYPE",type);
+      66           1 :   mapping::Path::readInputFrames( reference, type, argnames, false, this, reference_data );
+      67             :   // And read in the data that we want on the projections
+      68           2 :   std::vector<std::string> pnames; parseVector("PROPERTY",pnames);
+      69           2 :   std::string weights; parse("WEIGHT",weights); pnames.push_back( weights );
+      70             :   // Now create fixed vectors using some sort of reference action
+      71           1 :   mapping::Path::readPropertyInformation( pnames, getShortcutLabel(), reference, this );
+      72             :   // Normalise the vector of weights
+      73           2 :   readInputLine( getShortcutLabel() + "_wsum: SUM PERIODIC=NO ARG=" + weights + "_ref");
+      74           2 :   readInputLine( getShortcutLabel() + "_weights: CUSTOM ARG=" + getShortcutLabel() + "_wsum," +  weights + "_ref FUNC=y/x PERIODIC=NO");
+      75             :   // Transform the high dimensional distances
+      76           1 :   std::string hdfunc; parse("HIGH_DIM_FUNCTION",hdfunc);
+      77           2 :   readInputLine( getShortcutLabel() + "_targ: MORE_THAN ARG=" + getShortcutLabel() + "_data SQUARED SWITCH={" + hdfunc + "}");
+      78             :   // Create the projection object
+      79           3 :   std::string ldfunc, cgtol; parse("LOW_DIM_FUNCTION",ldfunc); parse("CGTOL",cgtol);
+      80           3 :   std::string argstr="ARG=" + pnames[0] + "_ref"; for(unsigned i=1; i<pnames.size()-1; ++i) argstr += "," + pnames[i] + "_ref";
+      81           3 :   readInputLine( getShortcutLabel() + ": PROJECT_POINTS " + argstr + " TARGET1=" + getShortcutLabel() + "_targ " +
+      82           3 :                  "FUNC1={" + ldfunc + "} WEIGHTS1=" + getShortcutLabel() + "_weights CGTOL=" + cgtol );
+      83           3 : }
+      84             : 
+      85             : }
+      86             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/index-sort-f.html b/coverage/dimred/index-sort-f.html new file mode 100644 index 000000000000..77da29644859 --- /dev/null +++ b/coverage/dimred/index-sort-f.html @@ -0,0 +1,164 @@ + + + + + + + + LCOV - plumed test coverage - dimred + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - dimredHitTotalCoverage
Test:plumed test coverageLines:49450498.0 %
Date:2024-04-19 12:12:35Functions:293778.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
SketchMapProjection.cpp +
100.0%
+
100.0 %28 / 2866.7 %2 / 3
SketchMap.cpp +
95.7%95.7%
+
95.7 %67 / 7066.7 %2 / 3
PCA.cpp +
100.0%
+
100.0 %56 / 5666.7 %2 / 3
ClassicalMultiDimensionalScaling.cpp +
97.6%97.6%
+
97.6 %40 / 4166.7 %2 / 3
ProjectPoints.cpp +
96.6%96.6%
+
96.6 %85 / 8880.0 %8 / 10
ArrangePoints.cpp +
98.8%98.8%
+
98.8 %171 / 17381.8 %9 / 11
SMACOF.h +
100.0%
+
100.0 %5 / 5100.0 %1 / 1
SMACOF.cpp +
97.7%97.7%
+
97.7 %42 / 43100.0 %3 / 3
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/index-sort-l.html b/coverage/dimred/index-sort-l.html new file mode 100644 index 000000000000..6fc013754033 --- /dev/null +++ b/coverage/dimred/index-sort-l.html @@ -0,0 +1,164 @@ + + + + + + + + LCOV - plumed test coverage - dimred + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - dimredHitTotalCoverage
Test:plumed test coverageLines:49450498.0 %
Date:2024-04-19 12:12:35Functions:293778.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
SketchMap.cpp +
95.7%95.7%
+
95.7 %67 / 7066.7 %2 / 3
ProjectPoints.cpp +
96.6%96.6%
+
96.6 %85 / 8880.0 %8 / 10
ClassicalMultiDimensionalScaling.cpp +
97.6%97.6%
+
97.6 %40 / 4166.7 %2 / 3
SMACOF.cpp +
97.7%97.7%
+
97.7 %42 / 43100.0 %3 / 3
ArrangePoints.cpp +
98.8%98.8%
+
98.8 %171 / 17381.8 %9 / 11
SMACOF.h +
100.0%
+
100.0 %5 / 5100.0 %1 / 1
SketchMapProjection.cpp +
100.0%
+
100.0 %28 / 2866.7 %2 / 3
PCA.cpp +
100.0%
+
100.0 %56 / 5666.7 %2 / 3
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/index.html b/coverage/dimred/index.html new file mode 100644 index 000000000000..770da18b1991 --- /dev/null +++ b/coverage/dimred/index.html @@ -0,0 +1,164 @@ + + + + + + + + LCOV - plumed test coverage - dimred + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - dimredHitTotalCoverage
Test:plumed test coverageLines:49450498.0 %
Date:2024-04-19 12:12:35Functions:293778.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
ArrangePoints.cpp +
98.8%98.8%
+
98.8 %171 / 17381.8 %9 / 11
ClassicalMultiDimensionalScaling.cpp +
97.6%97.6%
+
97.6 %40 / 4166.7 %2 / 3
PCA.cpp +
100.0%
+
100.0 %56 / 5666.7 %2 / 3
ProjectPoints.cpp +
96.6%96.6%
+
96.6 %85 / 8880.0 %8 / 10
SMACOF.cpp +
97.7%97.7%
+
97.7 %42 / 43100.0 %3 / 3
SMACOF.h +
100.0%
+
100.0 %5 / 5100.0 %1 / 1
SketchMap.cpp +
95.7%95.7%
+
95.7 %67 / 7066.7 %2 / 3
SketchMapProjection.cpp +
100.0%
+
100.0 %28 / 2866.7 %2 / 3
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/drr/DRR.cpp.func-sort-c.html b/coverage/drr/DRR.cpp.func-sort-c.html new file mode 100644 index 000000000000..5ffb5b9d716d --- /dev/null +++ b/coverage/drr/DRR.cpp.func-sort-c.html @@ -0,0 +1,173 @@ + + + + + + + + LCOV - plumed test coverage - drr/DRR.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - drr - DRR.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:33135593.2 %
Date:2024-04-19 12:12:35Functions:242596.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD3drr7DRRAxis12isInBoundaryEd0
_ZN4PLMD3drr3ABF11mergewindowERKS1_S3_2
_ZN4PLMD3drr4CZAR11mergewindowERKS1_S3_2
_ZNK4PLMD3drr12DRRForceGrid15writeDivergenceERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_2
_ZN4PLMD3drr12DRRForceGrid5mergeERKSt6vectorINS0_7DRRAxisESaIS3_EES7_4
_ZN4PLMD3drr7DRRAxis5mergeERKS1_S3_4
_ZNK4PLMD3drr4CZAR16writeZCountZGradERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEb18
_ZN4PLMD3drr12DRRForceGridC2ERKSt6vectorINS0_7DRRAxisESaIS3_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEb26
_ZNK4PLMD3drr12DRRForceGrid10write1DPMFENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKS7_26
_ZN4PLMD3drr12DRRForceGrid9fillTableERKSt6vectorIS2_IdSaIdEESaIS4_EE34
_ZNK4PLMD3drr12DRRForceGrid8writeAllERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_b36
_ZN4PLMD3drr12DRRForceGridC2Ev38
_ZN4PLMD3drr7DRRAxis15getMiddlePointsEv60
_ZN4PLMD3drr3ABF13store_getbiasERKSt6vectorIdSaIdEES6_RS4_123
_ZNK4PLMD3drr12DRRForceGrid20getAccumulatedForcesERKSt6vectorIdSaIdEE1600
_ZN4PLMD3drr12DRRForceGrid5storeERKSt6vectorIdSaIdEES6_m1723
_ZNK4PLMD3drr7DRRAxis14isRealPeriodicEv5860
_ZNK4PLMD3drr12DRRForceGrid13getDivergenceERKSt6vectorIdSaIdEE64800
_ZNK4PLMD3drr12DRRForceGrid8getCountERKSt6vectorIdSaIdEEb67612
_ZNK4PLMD3drr12DRRForceGrid11getGradientERKSt6vectorIdSaIdEEb195576
_ZNK4PLMD3drr12DRRForceGrid22getCountsLogDerivativeERKSt6vectorIdSaIdEE195576
_ZNK4PLMD3drr4CZAR11getGradientERKSt6vectorIdSaIdEEb195576
_ZNK4PLMD3drr12DRRForceGrid12isInBoundaryERKSt6vectorIdSaIdEE393846
_ZNK4PLMD3drr12DRRForceGrid13sampleAddressERKSt6vectorIdSaIdEE1012383
_ZN4PLMD3drr12DRRForceGrid7index1DERKNS0_7DRRAxisEd2407170
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/drr/DRR.cpp.func.html b/coverage/drr/DRR.cpp.func.html new file mode 100644 index 000000000000..a2b1f46b4c6e --- /dev/null +++ b/coverage/drr/DRR.cpp.func.html @@ -0,0 +1,173 @@ + + + + + + + + LCOV - plumed test coverage - drr/DRR.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - drr - DRR.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:33135593.2 %
Date:2024-04-19 12:12:35Functions:242596.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3drr12DRRForceGrid5mergeERKSt6vectorINS0_7DRRAxisESaIS3_EES7_4
_ZN4PLMD3drr12DRRForceGrid5storeERKSt6vectorIdSaIdEES6_m1723
_ZN4PLMD3drr12DRRForceGrid7index1DERKNS0_7DRRAxisEd2407170
_ZN4PLMD3drr12DRRForceGrid9fillTableERKSt6vectorIS2_IdSaIdEESaIS4_EE34
_ZN4PLMD3drr12DRRForceGridC2ERKSt6vectorINS0_7DRRAxisESaIS3_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEb26
_ZN4PLMD3drr12DRRForceGridC2Ev38
_ZN4PLMD3drr3ABF11mergewindowERKS1_S3_2
_ZN4PLMD3drr3ABF13store_getbiasERKSt6vectorIdSaIdEES6_RS4_123
_ZN4PLMD3drr4CZAR11mergewindowERKS1_S3_2
_ZN4PLMD3drr7DRRAxis15getMiddlePointsEv60
_ZN4PLMD3drr7DRRAxis5mergeERKS1_S3_4
_ZNK4PLMD3drr12DRRForceGrid10write1DPMFENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKS7_26
_ZNK4PLMD3drr12DRRForceGrid11getGradientERKSt6vectorIdSaIdEEb195576
_ZNK4PLMD3drr12DRRForceGrid12isInBoundaryERKSt6vectorIdSaIdEE393846
_ZNK4PLMD3drr12DRRForceGrid13getDivergenceERKSt6vectorIdSaIdEE64800
_ZNK4PLMD3drr12DRRForceGrid13sampleAddressERKSt6vectorIdSaIdEE1012383
_ZNK4PLMD3drr12DRRForceGrid15writeDivergenceERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_2
_ZNK4PLMD3drr12DRRForceGrid20getAccumulatedForcesERKSt6vectorIdSaIdEE1600
_ZNK4PLMD3drr12DRRForceGrid22getCountsLogDerivativeERKSt6vectorIdSaIdEE195576
_ZNK4PLMD3drr12DRRForceGrid8getCountERKSt6vectorIdSaIdEEb67612
_ZNK4PLMD3drr12DRRForceGrid8writeAllERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_b36
_ZNK4PLMD3drr4CZAR11getGradientERKSt6vectorIdSaIdEEb195576
_ZNK4PLMD3drr4CZAR16writeZCountZGradERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEb18
_ZNK4PLMD3drr7DRRAxis12isInBoundaryEd0
_ZNK4PLMD3drr7DRRAxis14isRealPeriodicEv5860
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/drr/DRR.cpp.gcov.html b/coverage/drr/DRR.cpp.gcov.html new file mode 100644 index 000000000000..3b050387282b --- /dev/null +++ b/coverage/drr/DRR.cpp.gcov.html @@ -0,0 +1,635 @@ + + + + + + + + LCOV - plumed test coverage - drr/DRR.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - drr - DRR.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:33135593.2 %
Date:2024-04-19 12:12:35Functions:242596.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :     Copyright (c) 2017 of Haochuan Chen (excluding colvar_UIestimator.h)
+       3             :     Copyright (c) 2017 of Haohao Fu (colvar_UIestimator.h)
+       4             : 
+       5             :     This program is free software: you can redistribute it and/or modify
+       6             :     it under the terms of the GNU Lesser General Public License as published
+       7             :     by the Free Software Foundation, either version 3 of the License, or
+       8             :     (at your option) any later version.
+       9             : 
+      10             :     This program is distributed in the hope that it will be useful,
+      11             :     but WITHOUT ANY WARRANTY; without even the implied warranty of
+      12             :     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      13             :     GNU Lesser General Public License for more details.
+      14             : 
+      15             :     You should have received a copy of the GNU Lesser General Public License
+      16             :     along with this program.  If not, see <http://www.gnu.org/licenses/>.
+      17             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      18             : #ifdef __PLUMED_HAS_BOOST_SERIALIZATION
+      19             : #include "DRR.h"
+      20             : 
+      21             : namespace PLMD {
+      22             : namespace drr {
+      23             : 
+      24             : using std::vector;
+      25             : using std::string;
+      26             : using std::begin;
+      27             : using std::end;
+      28             : 
+      29           0 : bool DRRAxis::isInBoundary(double x) const {
+      30           0 :   if (x < min || x > max)
+      31             :     return false;
+      32             :   else
+      33           0 :     return true;
+      34             : }
+      35             : 
+      36        5860 : bool DRRAxis::isRealPeriodic() const {
+      37        5860 :   if (periodic == true) {
+      38        5808 :     if (std::abs(domainMax - max) < binWidth &&
+      39        5796 :         std::abs(domainMin - min) < binWidth) {
+      40             :       return true;
+      41             :     } else {
+      42          12 :       return false;
+      43             :     }
+      44             :   } else {
+      45             :     return false;
+      46             :   }
+      47             : }
+      48             : 
+      49           4 : DRRAxis DRRAxis::merge(const DRRAxis &d1, const DRRAxis &d2) {
+      50           4 :   const double newmin = std::min(d1.min, d2.min);
+      51           4 :   const double newmax = std::max(d1.max, d2.max);
+      52           4 :   const double newWidth = d1.binWidth;
+      53           4 :   const size_t newbins = size_t(std::nearbyint((newmax - newmin) / newWidth));
+      54           4 :   const bool newpbc = d1.periodic;
+      55           4 :   const double newdmin = std::min(d1.domainMin, d2.domainMin);
+      56           4 :   const double newdmax = std::max(d1.domainMax, d2.domainMax);
+      57             :   DRRAxis result(newmin, newmax, newbins, newpbc, newdmin, newdmax);
+      58           4 :   return result;
+      59             : }
+      60             : 
+      61          60 : vector<double> DRRAxis::getMiddlePoints() {
+      62          60 :   vector<double> result(nbins, 0);
+      63          60 :   const double width = binWidth;
+      64          60 :   double temp = min - width / 2;
+      65          60 :   std::generate(begin(result), end(result), [&temp, &width]() {
+      66        3382 :     temp += width;
+      67             :     return temp;
+      68             :   });
+      69          60 :   return result;
+      70             : }
+      71             : 
+      72     2407170 : size_t DRRForceGrid::index1D(const DRRAxis &c, double x) {
+      73     2407170 :   size_t idx = size_t(std::floor((x - c.min) / c.binWidth));
+      74     2407170 :   idx = (idx == c.nbins) ? (c.nbins - 1) : idx;
+      75     2407170 :   return idx;
+      76             : }
+      77             : 
+      78          34 : void DRRForceGrid::fillTable(const vector<vector<double>> &in) {
+      79          34 :   table.resize(ndims, vector<double>(sampleSize, 0));
+      80          82 :   for (size_t i = 0; i < ndims; ++i) {
+      81             :     size_t repeatAll = 1, repeatOne = 1;
+      82          62 :     for (size_t j = i + 1; j < ndims; ++j)
+      83          14 :       repeatOne *= in[j].size();
+      84          62 :     for (size_t j = 0; j < i; ++j)
+      85          14 :       repeatAll *= in[j].size();
+      86             :     size_t in_i_sz = in[i].size();
+      87        3390 :     for (size_t l = 0; l < in_i_sz; ++l)
+      88        3342 :       std::fill_n(begin(table[i]) + l * repeatOne, repeatOne, in[i][l]);
+      89         784 :     for (size_t k = 0; k < repeatAll - 1; ++k)
+      90         736 :       std::copy_n(begin(table[i]), repeatOne * in_i_sz,
+      91         736 :                   begin(table[i]) + repeatOne * in_i_sz * (k + 1));
+      92             :   }
+      93          34 : }
+      94             : 
+      95          38 : DRRForceGrid::DRRForceGrid()
+      96          38 :   : suffix(""), ndims(0), dimensions(0), sampleSize(0),
+      97          38 :     headers(""), table(0), forces(0), samples(0), endpoints(0), shifts(0),
+      98          76 :     outputunit(1.0) {}
+      99             : 
+     100          26 : DRRForceGrid::DRRForceGrid(const vector<DRRAxis> &p_dimensions,
+     101          26 :                            const string &p_suffix, bool initializeTable)
+     102          26 :   : suffix(p_suffix), ndims(p_dimensions.size()), dimensions(p_dimensions) {
+     103          26 :   sampleSize = 1;
+     104          26 :   vector<vector<double>> mp(ndims);
+     105          26 :   std::stringstream ss;
+     106          26 :   ss << "# " << ndims << '\n';
+     107          26 :   shifts.resize(ndims, 0);
+     108          26 :   shifts[0] = 1;
+     109          64 :   for (size_t i = 0; i < ndims; ++i) {
+     110          38 :     sampleSize = dimensions[i].nbins * sampleSize;
+     111          38 :     mp[i] = dimensions[i].getMiddlePoints();
+     112          38 :     if (i > 0) {
+     113          12 :       shifts[i] = shifts[i - 1] * dimensions[i - 1].nbins;
+     114             :     }
+     115             :     ss.precision(std::numeric_limits<double>::max_digits10);
+     116          76 :     ss << std::fixed << "# " << dimensions[i].min << ' '
+     117          76 :        << dimensions[i].binWidth << ' ' << dimensions[i].nbins;
+     118          38 :     if (dimensions[i].isPeriodic())
+     119          56 :       ss << " 1" << '\n';
+     120             :     else
+     121          20 :       ss << " 0" << '\n';
+     122             :   }
+     123          26 :   headers = ss.str();
+     124          26 :   if (initializeTable)
+     125          18 :     fillTable(mp);
+     126          26 :   forces.resize(sampleSize * ndims, 0.0);
+     127          26 :   samples.resize(sampleSize, 0);
+     128          26 :   outputunit = 1.0;
+     129             :   // For 1D pmf
+     130          26 :   if (ndims == 1) {
+     131          14 :     endpoints.resize(dimensions[0].nbins + 1, 0);
+     132          14 :     double ep = dimensions[0].min;
+     133          14 :     double stride = dimensions[0].binWidth;
+     134         882 :     for (auto &i : endpoints) {
+     135         868 :       i = ep;
+     136         868 :       ep += stride;
+     137             :     }
+     138             :   }
+     139          26 : }
+     140             : 
+     141      393846 : bool DRRForceGrid::isInBoundary(const vector<double> &pos) const {
+     142             :   bool result = true;
+     143     1175042 :   for (size_t i = 0; i < ndims; ++i) {
+     144      782805 :     if (pos[i] < dimensions[i].min || pos[i] > dimensions[i].max)
+     145             :       return false;
+     146             :   }
+     147             :   return result;
+     148             : }
+     149             : 
+     150     1012383 : size_t DRRForceGrid::sampleAddress(const vector<double> &pos) const {
+     151             :   size_t saddr = 0;
+     152     3029541 :   for (size_t i = 0; i < ndims; ++i) {
+     153     2017158 :     saddr += shifts[i] * index1D(dimensions[i], pos[i]);
+     154             :   }
+     155     1012383 :   return saddr;
+     156             : }
+     157             : 
+     158        1723 : bool DRRForceGrid::store(const vector<double> &pos, const vector<double> &f,
+     159             :                          unsigned long int nsamples) {
+     160        1723 :   if (isInBoundary(pos)) {
+     161        1714 :     if (nsamples == 0)
+     162             :       return true;
+     163         914 :     const size_t baseaddr = sampleAddress(pos);
+     164         914 :     samples[baseaddr] += nsamples;
+     165         914 :     auto it_fa = begin(forces) + baseaddr * ndims;
+     166         914 :     std::transform(begin(f), end(f), it_fa, it_fa, std::plus<double>());
+     167         914 :     return true;
+     168             :   } else {
+     169             :     return false;
+     170             :   }
+     171             : }
+     172             : 
+     173           4 : vector<DRRAxis> DRRForceGrid::merge(const vector<DRRAxis> &dA,
+     174             :                                     const vector<DRRAxis> &dB) {
+     175           4 :   vector<DRRAxis> dR(dA.size());
+     176           4 :   std::transform(begin(dA), end(dA), begin(dB), begin(dR), DRRAxis::merge);
+     177           4 :   return dR;
+     178             : }
+     179             : 
+     180             : vector<double>
+     181        1600 : DRRForceGrid::getAccumulatedForces(const vector<double> &pos) const {
+     182        1600 :   vector<double> result(ndims, 0);
+     183        1600 :   if (!isInBoundary(pos))
+     184             :     return result;
+     185         800 :   const size_t force_addr = sampleAddress(pos) * ndims;
+     186         800 :   std::copy(begin(forces) + force_addr, begin(forces) + force_addr + ndims,
+     187             :             begin(result));
+     188         800 :   return result;
+     189             : }
+     190             : 
+     191       67612 : unsigned long int DRRForceGrid::getCount(const vector<double> &pos,
+     192             :     bool SkipCheck) const {
+     193       67612 :   if (!SkipCheck) {
+     194        1600 :     if (!isInBoundary(pos)) {
+     195             :       return 0;
+     196             :     }
+     197             :   }
+     198       66812 :   return samples[sampleAddress(pos)];
+     199             : }
+     200             : 
+     201      195576 : vector<double> DRRForceGrid::getGradient(const vector<double> &pos,
+     202             :     bool SkipCheck) const {
+     203      195576 :   vector<double> result(ndims, 0);
+     204      195576 :   if (!SkipCheck) {
+     205      162000 :     if (!isInBoundary(pos)) {
+     206             :       return result;
+     207             :     }
+     208             :   }
+     209      195576 :   const size_t baseaddr = sampleAddress(pos);
+     210             :   const unsigned long int &count = samples[baseaddr];
+     211      195576 :   if (count == 0)
+     212             :     return result;
+     213      195411 :   auto it_fa = begin(forces) + baseaddr * ndims;
+     214      195411 :   std::transform(it_fa, it_fa + ndims, begin(result),
+     215      389802 :   [&count](double fa) { return (-1.0) * fa / count; });
+     216      195411 :   return result;
+     217             : }
+     218             : 
+     219       64800 : double DRRForceGrid::getDivergence(const vector<double> &pos) const {
+     220             :   double div = 0.0;
+     221       64800 :   vector<double> grad_deriv(ndims, 0.0);
+     222       64800 :   if (!isInBoundary(pos)) {
+     223             :     return div;
+     224             :   }
+     225       64800 :   const size_t force_addr = sampleAddress(pos) * ndims;
+     226       64800 :   vector<double> grad = getGradient(pos);
+     227      194400 :   for (size_t i = 0; i < ndims; ++i) {
+     228      129600 :     const double binWidth = dimensions[i].binWidth;
+     229      129600 :     vector<double> first = pos;
+     230      129600 :     first[i] = dimensions[i].min + binWidth * 0.5;
+     231      129600 :     vector<double> last = pos;
+     232      129600 :     last[i] = dimensions[i].max - binWidth * 0.5;
+     233      129600 :     const size_t force_addr_first = sampleAddress(first) * ndims;
+     234      129600 :     const size_t force_addr_last = sampleAddress(last) * ndims;
+     235      129600 :     if (force_addr == force_addr_first) {
+     236         720 :       if (dimensions[i].isRealPeriodic() == true) {
+     237         720 :         vector<double> next = pos;
+     238         720 :         next[i] += binWidth;
+     239         720 :         const vector<double> grad_next = getGradient(next);
+     240         720 :         const vector<double> grad_prev = getGradient(last);
+     241         720 :         grad_deriv[i] = (grad_next[i] - grad_prev[i]) / (2.0 * binWidth);
+     242             :       } else {
+     243           0 :         vector<double> next = pos;
+     244           0 :         next[i] += binWidth;
+     245           0 :         vector<double> next_2 = next;
+     246           0 :         next_2[i] += binWidth;
+     247           0 :         const vector<double> grad_next = getGradient(next);
+     248           0 :         const vector<double> grad_next_2 = getGradient(next_2);
+     249           0 :         grad_deriv[i] =
+     250           0 :           (grad_next_2[i] * -1.0 + grad_next[i] * 4.0 - grad[i] * 3.0) /
+     251           0 :           (2.0 * binWidth);
+     252             :       }
+     253      128880 :     } else if (force_addr == force_addr_last) {
+     254         720 :       if (dimensions[i].isRealPeriodic() == true) {
+     255         720 :         vector<double> prev = pos;
+     256         720 :         prev[i] -= binWidth;
+     257         720 :         const vector<double> grad_next = getGradient(first);
+     258         720 :         const vector<double> grad_prev = getGradient(prev);
+     259         720 :         grad_deriv[i] = (grad_next[i] - grad_prev[i]) / (2.0 * binWidth);
+     260             :       } else {
+     261           0 :         vector<double> prev = pos;
+     262           0 :         prev[i] -= binWidth;
+     263           0 :         vector<double> prev_2 = prev;
+     264           0 :         prev_2[i] -= binWidth;
+     265           0 :         const vector<double> grad_prev = getGradient(prev);
+     266           0 :         const vector<double> grad_prev_2 = getGradient(prev_2);
+     267           0 :         grad_deriv[i] =
+     268           0 :           (grad[i] * 3.0 - grad_prev[i] * 4.0 + grad_prev_2[i] * 1.0) /
+     269           0 :           (2.0 * binWidth);
+     270             :       }
+     271             :     } else {
+     272      128160 :       vector<double> prev = pos;
+     273      128160 :       prev[i] -= binWidth;
+     274      128160 :       vector<double> next = pos;
+     275      128160 :       next[i] += binWidth;
+     276      128160 :       const vector<double> grad_next = getGradient(next);
+     277      128160 :       const vector<double> grad_prev = getGradient(prev);
+     278      128160 :       grad_deriv[i] = (grad_next[i] - grad_prev[i]) / (2.0 * binWidth);
+     279             :     }
+     280             :   }
+     281             :   div = std::accumulate(begin(grad_deriv), end(grad_deriv), 0.0);
+     282             :   return div;
+     283             : }
+     284             : 
+     285             : vector<double>
+     286      195576 : DRRForceGrid::getCountsLogDerivative(const vector<double> &pos) const {
+     287      195576 :   const size_t addr = sampleAddress(pos);
+     288      195576 :   const unsigned long int count_this = samples[addr];
+     289      195576 :   vector<double> result(ndims, 0);
+     290      585588 :   for (size_t i = 0; i < ndims; ++i) {
+     291      390012 :     const double binWidth = dimensions[i].binWidth;
+     292             :     const size_t addr_first =
+     293      390012 :       addr - shifts[i] * index1D(dimensions[i], pos[i]) + 0;
+     294      390012 :     const size_t addr_last = addr_first + shifts[i] * (dimensions[i].nbins - 1);
+     295      390012 :     if (addr == addr_first) {
+     296        2210 :       if (dimensions[i].isRealPeriodic() == true) {
+     297        2178 :         const unsigned long int &count_next = samples[addr + shifts[i]];
+     298             :         const unsigned long int &count_prev = samples[addr_last];
+     299        2178 :         if (count_next != 0 && count_prev != 0)
+     300        2160 :           result[i] =
+     301        2160 :             (std::log(count_next) - std::log(count_prev)) / (2 * binWidth);
+     302             :       } else {
+     303          32 :         const unsigned long int &count_next = samples[addr + shifts[i]];
+     304          32 :         const unsigned long int &count_next2 = samples[addr + shifts[i] * 2];
+     305          32 :         if (count_next != 0 && count_this != 0 && count_next2 != 0)
+     306           6 :           result[i] =
+     307           6 :             (std::log(count_next2) * (-1.0) + std::log(count_next) * 4.0 -
+     308           6 :              std::log(count_this) * 3.0) /
+     309           6 :             (2.0 * binWidth);
+     310             :       }
+     311      387802 :     } else if (addr == addr_last) {
+     312        2210 :       if (dimensions[i].isRealPeriodic() == true) {
+     313        2178 :         const unsigned long int &count_prev = samples[addr - shifts[i]];
+     314             :         const unsigned long int &count_next = samples[addr_first];
+     315        2178 :         if (count_next != 0 && count_prev != 0)
+     316        2160 :           result[i] =
+     317        2160 :             (std::log(count_next) - std::log(count_prev)) / (2 * binWidth);
+     318             :       } else {
+     319          32 :         const unsigned long int &count_prev = samples[addr - shifts[i]];
+     320          32 :         const unsigned long int &count_prev2 = samples[addr - shifts[i] * 2];
+     321          32 :         if (count_prev != 0 && count_this != 0 && count_prev2 != 0)
+     322           6 :           result[i] = (std::log(count_this) * 3.0 - std::log(count_prev) * 4.0 +
+     323           6 :                        std::log(count_prev2)) /
+     324           6 :                       (2.0 * binWidth);
+     325             :       }
+     326             :     } else {
+     327      385592 :       const unsigned long int &count_prev = samples[addr - shifts[i]];
+     328      385592 :       const unsigned long int &count_next = samples[addr + shifts[i]];
+     329      385592 :       if (count_next != 0 && count_prev != 0)
+     330      385432 :         result[i] =
+     331      385432 :           (std::log(count_next) - std::log(count_prev)) / (2 * binWidth);
+     332             :     }
+     333             :   }
+     334      195576 :   return result;
+     335             : }
+     336             : 
+     337          26 : void DRRForceGrid::write1DPMF(string filename, const string &fmt) const {
+     338          26 :   filename += suffix + ".pmf";
+     339          52 :   std::string fmtv=fmt+" "+fmt+"\n";
+     340             :   FILE *ppmf;
+     341          26 :   ppmf = fopen(filename.c_str(), "w");
+     342          26 :   const double w = dimensions[0].binWidth;
+     343             :   double pmf = 0;
+     344          26 :   fprintf(ppmf, fmtv.c_str(), endpoints[0], pmf);
+     345        1166 :   for (size_t i = 0; i < dimensions[0].nbins; ++i) {
+     346        1140 :     vector<double> pos(1, 0);
+     347        1140 :     pos[0] = table[0][i];
+     348        1140 :     const vector<double> f = getGradient(pos, true);
+     349        1140 :     pmf += f[0] * w / outputunit;
+     350        1140 :     fprintf(ppmf, fmtv.c_str(), endpoints[i + 1], pmf);
+     351             :   }
+     352          26 :   fclose(ppmf);
+     353          26 : }
+     354             : 
+     355          36 : void DRRForceGrid::writeAll(const string &filename, const string &fmt, bool addition) const {
+     356          36 :   const std::string countname = filename + suffix + ".count";
+     357          36 :   const std::string gradname = filename + suffix + ".grad";
+     358          36 :   std::string fmtv=" "+fmt;
+     359          36 :   vector<double> pos(ndims, 0);
+     360             :   FILE *pGrad, *pCount;
+     361          36 :   if (addition) {
+     362           8 :     pGrad = fopen(gradname.c_str(), "a");
+     363           8 :     pCount = fopen(countname.c_str(), "a");
+     364             :   } else {
+     365          28 :     pGrad = fopen(gradname.c_str(), "w");
+     366          28 :     pCount = fopen(countname.c_str(), "w");
+     367             :   }
+     368             : 
+     369             :   char *buffer1, *buffer2;
+     370          36 :   buffer1 = (char *)malloc((sizeof(double)) * sampleSize * ndims);
+     371          36 :   buffer2 = (char *)malloc((sizeof(double)) * sampleSize * ndims);
+     372          36 :   setvbuf(pGrad, buffer1, _IOFBF, (sizeof(double)) * sampleSize * ndims);
+     373          36 :   setvbuf(pCount, buffer2, _IOFBF, (sizeof(double)) * sampleSize * ndims);
+     374          36 :   fwrite(headers.c_str(), sizeof(char), strlen(headers.c_str()), pGrad);
+     375          36 :   fwrite(headers.c_str(), sizeof(char), strlen(headers.c_str()), pCount);
+     376       66048 :   for (size_t i = 0; i < sampleSize; ++i) {
+     377      196896 :     for (size_t j = 0; j < ndims; ++j) {
+     378      130884 :       pos[j] = table[j][i];
+     379      130884 :       fprintf(pGrad, fmtv.c_str(), table[j][i]);
+     380      130884 :       fprintf(pCount, fmtv.c_str(), table[j][i]);
+     381             :     }
+     382       66012 :     fprintf(pCount, " %lu\n", getCount(pos, true));
+     383       66012 :     vector<double> f = getGradient(pos, true);
+     384      196896 :     for (size_t j = 0; j < ndims; ++j) {
+     385      130884 :       fprintf(pGrad, fmtv.c_str(), (f[j] / outputunit));
+     386             :     }
+     387             :     fprintf(pGrad, "\n");
+     388             :   }
+     389          36 :   fclose(pGrad);
+     390          36 :   fclose(pCount);
+     391          36 :   free(buffer1);
+     392          36 :   free(buffer2);
+     393          36 :   if (ndims == 1) {
+     394          52 :     write1DPMF(filename, fmt);
+     395             :   }
+     396          36 : }
+     397             : 
+     398           2 : void DRRForceGrid::writeDivergence(const string &filename, const string &fmt) const {
+     399           2 :   const string divname = filename + suffix + ".div";
+     400           2 :   std::string fmtv=" "+fmt;
+     401           2 :   vector<double> pos(ndims, 0);
+     402             :   FILE *pDiv;
+     403           2 :   pDiv = fopen(divname.c_str(), "w");
+     404           2 :   fwrite(headers.c_str(), sizeof(char), strlen(headers.c_str()), pDiv);
+     405       64802 :   for (size_t i = 0; i < sampleSize; ++i) {
+     406      194400 :     for (size_t j = 0; j < ndims; ++j) {
+     407      129600 :       pos[j] = table[j][i];
+     408      129600 :       fprintf(pDiv, fmtv.c_str(), table[j][i]);
+     409             :     }
+     410       64800 :     const double divergence = getDivergence(pos);
+     411       64800 :     fprintf(pDiv, fmtv.c_str(), (divergence / outputunit));
+     412             :     fprintf(pDiv, "\n");
+     413             :   }
+     414           2 :   fclose(pDiv);
+     415           2 : }
+     416             : 
+     417         123 : bool ABF::store_getbias(const vector<double> &pos, const vector<double> &f,
+     418             :                         vector<double> &fbias) {
+     419         123 :   if (!isInBoundary(pos)) {
+     420             :     std::fill(begin(fbias), end(fbias), 0.0);
+     421             :     return false;
+     422             :   }
+     423         123 :   const size_t baseaddr = sampleAddress(pos);
+     424             :   unsigned long int &count = samples[baseaddr];
+     425         123 :   ++count;
+     426         123 :   double factor = 2 * (static_cast<double>(count)) / mFullSamples - 1;
+     427         123 :   auto it_fa = begin(forces) + baseaddr * ndims;
+     428             :   auto it_fb = begin(fbias);
+     429             :   auto it_f = begin(f);
+     430             :   auto it_maxFactor = begin(mMaxFactors);
+     431             :   do {
+     432             :     // Clamp to [0,maxFactors]
+     433         207 :     factor = factor < 0 ? 0 : factor > (*it_maxFactor) ? (*it_maxFactor) : factor;
+     434         207 :     (*it_fa) += (*it_f); // Accumulate instantaneous force
+     435         207 :     (*it_fb) = factor * (*it_fa) * (-1.0) /
+     436         207 :                static_cast<double>(count); // Calculate bias force
+     437             :     ++it_fa;
+     438             :     ++it_fb;
+     439             :     ++it_f;
+     440             :     ++it_maxFactor;
+     441         207 :   } while (it_f != end(f));
+     442             : 
+     443             :   return true;
+     444             : }
+     445             : 
+     446           2 : ABF ABF::mergewindow(const ABF &aWA, const ABF &aWB) {
+     447           2 :   const vector<DRRAxis> dR = merge(aWA.dimensions, aWB.dimensions);
+     448           2 :   const string suffix = ".abf";
+     449           2 :   ABF result(dR, suffix);
+     450           2 :   const size_t nrows = result.sampleSize;
+     451           2 :   const size_t ncols = result.ndims;
+     452           2 :   vector<double> pos(ncols, 0);
+     453         402 :   for (size_t i = 0; i < nrows; ++i) {
+     454         800 :     for (size_t j = 0; j < ncols; ++j) {
+     455         400 :       pos[j] = result.table[j][i];
+     456             :     }
+     457         400 :     const unsigned long int countA = aWA.getCount(pos);
+     458         400 :     const unsigned long int countB = aWB.getCount(pos);
+     459         400 :     const vector<double> aForceA = aWA.getAccumulatedForces(pos);
+     460         400 :     const vector<double> aForceB = aWB.getAccumulatedForces(pos);
+     461         400 :     result.store(pos, aForceA, countA);
+     462         400 :     result.store(pos, aForceB, countB);
+     463             :   }
+     464           2 :   return result;
+     465           0 : }
+     466             : 
+     467      195576 : vector<double> CZAR::getGradient(const vector<double> &pos,
+     468             :                                  bool SkipCheck) const {
+     469      195576 :   vector<double> result(ndims, 0);
+     470      195576 :   if (!SkipCheck) {
+     471      162000 :     if (!isInBoundary(pos)) {
+     472             :       return result;
+     473             :     }
+     474             :   }
+     475      195576 :   if (kbt <= std::numeric_limits<double>::epsilon()) {
+     476             :     std::cerr << "ERROR! The kbt shouldn't be zero when use CZAR estimator. "
+     477           0 :               << '\n';
+     478           0 :     std::abort();
+     479             :   }
+     480      195576 :   const size_t baseaddr = sampleAddress(pos);
+     481      195576 :   const vector<double> log_deriv(getCountsLogDerivative(pos));
+     482             :   const unsigned long int &count = samples[baseaddr];
+     483      195576 :   if (count == 0)
+     484             :     return result;
+     485      195421 :   auto it_fa = begin(forces) + baseaddr * ndims;
+     486      195421 :   std::transform(it_fa, it_fa + ndims, begin(log_deriv), begin(result),
+     487      389822 :   [&count, this](double fa, double ld) {
+     488      389822 :     return fa * (-1.0) / count - kbt * ld;
+     489             :   });
+     490      195421 :   return result;
+     491             : }
+     492             : 
+     493           2 : CZAR CZAR::mergewindow(const CZAR &cWA, const CZAR &cWB) {
+     494           2 :   const vector<DRRAxis> dR = merge(cWA.dimensions, cWB.dimensions);
+     495           2 :   const double newkbt = cWA.kbt;
+     496           2 :   const string suffix = ".czar";
+     497             :   CZAR result(dR, suffix, newkbt);
+     498           2 :   const size_t nrows = result.sampleSize;
+     499           2 :   const size_t ncols = result.ndims;
+     500           2 :   vector<double> pos(ncols, 0);
+     501         402 :   for (size_t i = 0; i < nrows; ++i) {
+     502         800 :     for (size_t j = 0; j < ncols; ++j) {
+     503         400 :       pos[j] = result.table[j][i];
+     504             :     }
+     505         400 :     const unsigned long int countA = cWA.getCount(pos);
+     506         400 :     const unsigned long int countB = cWB.getCount(pos);
+     507         400 :     const vector<double> aForceA = cWA.getAccumulatedForces(pos);
+     508         400 :     const vector<double> aForceB = cWB.getAccumulatedForces(pos);
+     509         400 :     result.store(pos, aForceA, countA);
+     510         400 :     result.store(pos, aForceB, countB);
+     511             :   }
+     512           2 :   return result;
+     513             : }
+     514             : 
+     515          18 : void CZAR:: writeZCountZGrad(const string &filename, bool addition) const {
+     516          18 :   const string countname = filename + ".zcount";
+     517          18 :   const string gradname = filename + ".zgrad";
+     518          18 :   vector<double> pos(ndims, 0);
+     519             :   FILE *pCount;
+     520             :   FILE *pGrad;
+     521          18 :   if (addition) {
+     522           4 :     pCount = fopen(countname.c_str(), "a");
+     523           4 :     pGrad = fopen(gradname.c_str(), "a");
+     524             :   } else {
+     525          14 :     pCount = fopen(countname.c_str(), "w");
+     526          14 :     pGrad = fopen(gradname.c_str(), "w");
+     527             :   }
+     528          18 :   fwrite(headers.c_str(), sizeof(char), strlen(headers.c_str()), pCount);
+     529          18 :   fwrite(headers.c_str(), sizeof(char), strlen(headers.c_str()), pGrad);
+     530       33024 :   for (size_t i = 0; i < sampleSize; ++i) {
+     531       98448 :     for (size_t j = 0; j < ndims; ++j) {
+     532       65442 :       pos[j] = table[j][i];
+     533       65442 :       fprintf(pCount, " %.9f", table[j][i]);
+     534       65442 :       fprintf(pGrad, " %.9f", table[j][i]);
+     535             :     }
+     536       33006 :     const size_t baseaddr = sampleAddress(pos);
+     537             :     const auto& current_sample = samples[baseaddr];
+     538       33006 :     fprintf(pCount, " %lu\n", current_sample);
+     539       33006 :     if (current_sample == 0) {
+     540         195 :       for (size_t j = 0; j < ndims; ++j) {
+     541             :         fprintf(pGrad, " %.9f", 0.0);
+     542             :       }
+     543             :     } else {
+     544       98253 :       for (size_t j = 0; j < ndims; ++j) {
+     545       65332 :         const double grad = -1.0 * forces[baseaddr * ndims + j] / current_sample;
+     546       65332 :         fprintf(pGrad, " %.9f", grad / outputunit);
+     547             :       }
+     548             :     }
+     549             :     fprintf(pGrad, "\n");
+     550             :   }
+     551          18 :   fclose(pCount);
+     552          18 :   fclose(pGrad);
+     553          18 : }
+     554             : 
+     555             : }
+     556             : }
+     557             : 
+     558             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/drr/DRR.h.func-sort-c.html b/coverage/drr/DRR.h.func-sort-c.html new file mode 100644 index 000000000000..04d1873c32b9 --- /dev/null +++ b/coverage/drr/DRR.h.func-sort-c.html @@ -0,0 +1,129 @@ + + + + + + + + LCOV - plumed test coverage - drr/DRR.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - drr - DRR.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:9999100.0 %
Date:2024-04-19 12:12:35Functions:111478.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3drr12DRRForceGridD0Ev0
_ZN4PLMD3drr3ABFD0Ev0
_ZN4PLMD3drr4CZARD0Ev0
_ZN4PLMD3drr3ABFC2ERKSt6vectorINS0_7DRRAxisESaIS3_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEddb2
_ZN4PLMD3drr4CZARD2Ev6
_ZN4PLMD3drr4CZAR9serializeIN5boost7archive15binary_iarchiveEEEvRT_j8
_ZN4PLMD3drr3ABFC2ERKSt6vectorINS0_7DRRAxisESaIS3_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdRKS2_IdSaIdEEb11
_ZN4PLMD3drr12DRRForceGrid4loadIN5boost7archive15binary_iarchiveEEEvRT_j16
_ZN4PLMD3drr4CZAR9serializeIN5boost7archive15binary_oarchiveEEEvRT_j19
_ZN4PLMD3drr7DRRAxis4loadIN5boost7archive15binary_iarchiveEEEvRT_j22
_ZN4PLMD3drr3ABFD2Ev38
_ZNK4PLMD3drr12DRRForceGrid4saveIN5boost7archive15binary_oarchiveEEEvRT_j38
_ZNK4PLMD3drr7DRRAxis4saveIN5boost7archive15binary_oarchiveEEEvRT_j52
_ZN4PLMD3drr12DRRForceGridD2Ev76
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/drr/DRR.h.func.html b/coverage/drr/DRR.h.func.html new file mode 100644 index 000000000000..095cc206694a --- /dev/null +++ b/coverage/drr/DRR.h.func.html @@ -0,0 +1,129 @@ + + + + + + + + LCOV - plumed test coverage - drr/DRR.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - drr - DRR.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:9999100.0 %
Date:2024-04-19 12:12:35Functions:111478.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3drr12DRRForceGrid4loadIN5boost7archive15binary_iarchiveEEEvRT_j16
_ZN4PLMD3drr12DRRForceGridD0Ev0
_ZN4PLMD3drr12DRRForceGridD2Ev76
_ZN4PLMD3drr3ABFC2ERKSt6vectorINS0_7DRRAxisESaIS3_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdRKS2_IdSaIdEEb11
_ZN4PLMD3drr3ABFC2ERKSt6vectorINS0_7DRRAxisESaIS3_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEddb2
_ZN4PLMD3drr3ABFD0Ev0
_ZN4PLMD3drr3ABFD2Ev38
_ZN4PLMD3drr4CZAR9serializeIN5boost7archive15binary_iarchiveEEEvRT_j8
_ZN4PLMD3drr4CZAR9serializeIN5boost7archive15binary_oarchiveEEEvRT_j19
_ZN4PLMD3drr4CZARD0Ev0
_ZN4PLMD3drr4CZARD2Ev6
_ZN4PLMD3drr7DRRAxis4loadIN5boost7archive15binary_iarchiveEEEvRT_j22
_ZNK4PLMD3drr12DRRForceGrid4saveIN5boost7archive15binary_oarchiveEEEvRT_j38
_ZNK4PLMD3drr7DRRAxis4saveIN5boost7archive15binary_oarchiveEEEvRT_j52
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/drr/DRR.h.gcov.html b/coverage/drr/DRR.h.gcov.html new file mode 100644 index 000000000000..b9000249a51e --- /dev/null +++ b/coverage/drr/DRR.h.gcov.html @@ -0,0 +1,435 @@ + + + + + + + + LCOV - plumed test coverage - drr/DRR.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - drr - DRR.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:9999100.0 %
Date:2024-04-19 12:12:35Functions:111478.6 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :     Copyright (c) 2017 of Haochuan Chen (excluding colvar_UIestimator.h)
+       3             :     Copyright (c) 2017 of Haohao Fu (colvar_UIestimator.h)
+       4             : 
+       5             :     This program is free software: you can redistribute it and/or modify
+       6             :     it under the terms of the GNU Lesser General Public License as published
+       7             :     by the Free Software Foundation, either version 3 of the License, or
+       8             :     (at your option) any later version.
+       9             : 
+      10             :     This program is distributed in the hope that it will be useful,
+      11             :     but WITHOUT ANY WARRANTY; without even the implied warranty of
+      12             :     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      13             :     GNU Lesser General Public License for more details.
+      14             : 
+      15             :     You should have received a copy of the GNU Lesser General Public License
+      16             :     along with this program.  If not, see <http://www.gnu.org/licenses/>.
+      17             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      18             : #ifndef __PLUMED_drr_DRR_h
+      19             : #define __PLUMED_drr_DRR_h
+      20             : // Build requirement: boost, c++11 compatible compiler.
+      21             : #ifdef __PLUMED_HAS_BOOST_SERIALIZATION
+      22             : 
+      23             : #include <algorithm>
+      24             : #include <cmath>
+      25             : #include <cstddef>
+      26             : #include <cstdlib>
+      27             : #include <fstream>
+      28             : #include <iomanip>
+      29             : #include <iostream>
+      30             : #include <iterator>
+      31             : #include <limits>
+      32             : #include <numeric>
+      33             : #include <sstream>
+      34             : 
+      35             : // boost headers for serialization
+      36             : #include <boost/archive/binary_iarchive.hpp>
+      37             : #include <boost/archive/binary_oarchive.hpp>
+      38             : #include <boost/serialization/string.hpp>
+      39             : #include <boost/serialization/vector.hpp>
+      40             : 
+      41             : namespace PLMD {
+      42             : namespace drr {
+      43             : 
+      44             : using std::vector;
+      45             : using std::string;
+      46             : using std::begin;
+      47             : using std::end;
+      48             : 
+      49             : /// This class can store the minimum, maximum and bins of a dimension(axis).
+      50             : class DRRAxis {
+      51             : public:
+      52             :   /// Default empty constructor
+      53          64 :   DRRAxis() {
+      54          64 :     min = max = 0.0;
+      55          64 :     nbins = 0;
+      56          64 :     periodic = false;
+      57          64 :     domainMax = domainMin = 0.0;
+      58          64 :     binWidth = 0.0;
+      59             :   }
+      60             :   /// Constructor using maximum value, minimum value and the number of bins(No
+      61             :   /// pbc)
+      62             :   DRRAxis(double l, double h, size_t n)
+      63             :     : min(l), max(h), nbins(n), periodic(false), domainMax(0), domainMin(0),
+      64             :       binWidth((max - min) / double(nbins)) {}
+      65             :   /// PBC-aware constructor
+      66             :   DRRAxis(double l, double h, size_t n, bool pbc, double dMax, double dMin)
+      67           4 :     : min(l), max(h), nbins(n), periodic(pbc), domainMax(dMax),
+      68           4 :       domainMin(dMin), binWidth((max - min) / double(nbins)) {}
+      69             :   /// Set values
+      70             :   void set(double l, double h, size_t n, bool pbc = false, double dmin = 0,
+      71             :            double dmax = 0) {
+      72          38 :     min = l;
+      73          38 :     max = h;
+      74          38 :     nbins = n;
+      75          38 :     periodic = pbc;
+      76          38 :     domainMax = dmax;
+      77          38 :     domainMin = dmin;
+      78          38 :     binWidth = (max - min) / nbins;
+      79             :   }
+      80             :   /// Set PBC data
+      81             :   void setPeriodicity(double dmin, double dmax) {
+      82          16 :     domainMax = dmax;
+      83          16 :     domainMin = dmin;
+      84          16 :     periodic = true;
+      85             :   }
+      86             :   /// Getters
+      87          41 :   double getMin() const { return this->min; }
+      88          40 :   double getMax() const { return this->max; }
+      89          31 :   double getWidth() const { return binWidth; }
+      90             :   double getDomainMax() const { return this->domainMax; }
+      91             :   double getDomainMin() const { return this->domainMin; }
+      92             :   size_t getBins() const { return this->nbins; }
+      93             : 
+      94             :   /// Check periodicity
+      95          60 :   bool isPeriodic() const { return this->periodic; }
+      96             :   /// Check real periodicity, i.e. the maximum == the domain maximum
+      97             :   bool isRealPeriodic() const;
+      98             : 
+      99             :   /// Check whether x is in this axis
+     100             :   bool isInBoundary(double x) const;
+     101             :   /// Get an array of middle points of each bins
+     102             :   vector<double> getMiddlePoints();
+     103             : 
+     104             :   /// Combine two axes if they share the same bin width.
+     105             :   static DRRAxis merge(const DRRAxis &d1, const DRRAxis &d2);
+     106             : 
+     107             :   friend class DRRForceGrid;
+     108             : 
+     109             : protected:
+     110             :   double min;       // Minimum value of the axis
+     111             :   double max;       // Maximum value of the axis
+     112             :   size_t nbins;     // Number of bins
+     113             :   bool periodic;    // Periodicity
+     114             :   double domainMax; // Maximum value of the CV domain
+     115             :   double domainMin; // Minimum value of the CV domain
+     116             :   friend class boost::serialization::access;
+     117             :   /// Use boost serialization
+     118             :   template <typename Archive>
+     119          52 :   void save(Archive &ar, const unsigned int version) const {
+     120          52 :     ar &min;
+     121          52 :     ar &max;
+     122          52 :     ar &nbins;
+     123          52 :     ar &periodic;
+     124          52 :     ar &domainMax;
+     125          52 :     ar &domainMin;
+     126          52 :   }
+     127             :   /// Split save and load. The bin width is calculated after initialization.
+     128             :   template <typename Archive>
+     129          22 :   void load(Archive &ar, const unsigned int version) {
+     130          22 :     ar &min;
+     131          22 :     ar &max;
+     132          22 :     ar &nbins;
+     133          22 :     ar &periodic;
+     134          22 :     ar &domainMax;
+     135          22 :     ar &domainMin;
+     136          22 :     binWidth = (max - min) / double(nbins);
+     137          22 :   }
+     138             :   template <typename Archive>
+     139             :   void serialize(Archive &ar, const unsigned int version) {
+     140             :     boost::serialization::split_member(ar, *this, version);
+     141             :   }
+     142             : 
+     143             : private:
+     144             :   double binWidth; // bin width
+     145             : };
+     146             : 
+     147             : /// A class for collecting instantaneous forces, calculating average forces and
+     148             : /// build CV histogram.
+     149             : class DRRForceGrid {
+     150             : public:
+     151             :   /// Empty constructor
+     152             :   DRRForceGrid();
+     153             :   /// "Real" constructor
+     154             :   /// The 2D table vector is mainly used for print grid points in grad and count
+     155             :   /// file.
+     156             :   /// So when use binary output we can set initializeTable to false to save
+     157             :   /// memory.
+     158             :   explicit DRRForceGrid(const vector<DRRAxis> &p_dimensions,
+     159             :                         const string &p_suffix,
+     160             :                         bool initializeTable = true);
+     161             :   /// Check whether a point is in this grid
+     162             :   bool isInBoundary(const vector<double> &pos) const;
+     163             :   //  /// Get internal indices of a point
+     164             :   //  vector<size_t> index(const vector<double> &pos) const;
+     165             :   /// Get internal counts address of a point
+     166             :   size_t sampleAddress(const vector<double> &pos) const;
+     167             :   /// Store instantaneous forces of a point
+     168             :   /// nsamples > 1 is useful for merging windows
+     169             :   bool store(const vector<double> &pos, const vector<double> &f,
+     170             :              unsigned long int nsamples = 1);
+     171             :   /// Get accumulated forces of a point
+     172             :   vector<double>
+     173             :   getAccumulatedForces(const vector<double> &pos) const;
+     174             :   /// Get counts of a point
+     175             :   unsigned long int getCount(const vector<double> &pos,
+     176             :                              bool SkipCheck = false) const;
+     177             :   /// Virtual function! get gradients of a point
+     178             :   /// CZAR and naive(ABF) have different gradient formulae
+     179             :   virtual vector<double> getGradient(const vector<double> &pos,
+     180             :                                      bool SkipCheck = false) const;
+     181             :   /// Calculate divergence of the mean force field (experimental)
+     182             :   double getDivergence(const vector<double> &pos) const;
+     183             :   /// Calculate dln(Ï)/dz, useful for CZAR
+     184             :   /// This function may be moved to CZAR class in the future
+     185             :   vector<double>
+     186             :   getCountsLogDerivative(const vector<double> &pos) const;
+     187             :   /// Write grad file
+     188             : //   void writeGrad(string filename) const;
+     189             :   /// Write 1D pmf file on one dimensional occasion
+     190             :   void write1DPMF(string filename, const string &fmt="%.9f") const;
+     191             :   /// Write count file
+     192             : //   void writeCount(string filename) const;
+     193             :   /// Write necessary output file in one function (.grad and .count)
+     194             :   void writeAll(const string &filename, const string &fmt="%.9f", bool addition = false) const;
+     195             :   /// Output divergence (.div) (experimental)
+     196             :   void writeDivergence(const string &filename, const string &fmt="%.9f") const;
+     197             :   /// merge windows
+     198             :   static vector<DRRAxis> merge(const vector<DRRAxis> &dA,
+     199             :                                const vector<DRRAxis> &dB);
+     200             :   /// Get suffix
+     201             :   string getSuffix() const { return suffix; }
+     202             :   /// Set unit for .grad output
+     203           4 :   void setOutputUnit(double unit) { outputunit = unit; }
+     204             :   /// Destructor
+     205         228 :   virtual ~DRRForceGrid() {}
+     206             : 
+     207             : protected:
+     208             :   /// The output suffix appended before .grad(.czar.grad) and
+     209             :   /// .count(.czar.count)
+     210             :   string suffix;
+     211             :   /// Number of dimensions
+     212             :   size_t ndims;
+     213             :   /// Store each axes
+     214             :   vector<DRRAxis> dimensions;
+     215             :   /// Size of samples
+     216             :   size_t sampleSize;
+     217             :   /// The header lines of .grad and .count files
+     218             :   string headers;
+     219             :   /// A table stores the middle points of all dimensions.
+     220             :   /// For output in .grad and .count files
+     221             :   vector<vector<double>> table;
+     222             :   /// Store the average force of each bins
+     223             :   vector<double> forces;
+     224             :   /// Store counts of each bins
+     225             :   vector<unsigned long int> samples;
+     226             :   /// Only for 1D pmf output
+     227             :   vector<double> endpoints;
+     228             :   /// For faster indexing
+     229             :   /// shifts[0] = 1, shifts[n+1] = shifts[n] * dimensions[n].nbins
+     230             :   vector<size_t> shifts;
+     231             :   /// For set different output units
+     232             :   double outputunit;
+     233             : 
+     234             :   /// Miscellaneous helper functions
+     235             :   static size_t index1D(const DRRAxis &c, double x);
+     236             :   void fillTable(const vector<vector<double>> &in);
+     237             : 
+     238             :   /// Boost serialization functions
+     239             :   friend class boost::serialization::access;
+     240             :   template <class Archive>
+     241          38 :   void save(Archive &ar, const unsigned int version) const {
+     242             :     // Don't save all members.
+     243          38 :     ar << suffix;
+     244          38 :     ar << dimensions;
+     245          38 :     ar << forces;
+     246          38 :     ar << samples;
+     247          38 :   }
+     248          16 :   template <class Archive> void load(Archive &ar, const unsigned int version) {
+     249          16 :     ar >> suffix;
+     250          16 :     ar >> dimensions;
+     251          16 :     ar >> forces;
+     252          16 :     ar >> samples;
+     253             :     // Restore other members.
+     254          16 :     ndims = dimensions.size();
+     255          16 :     sampleSize = samples.size();
+     256          16 :     std::stringstream ss;
+     257          16 :     ss << "# " << ndims << '\n';
+     258          16 :     vector<vector<double>> mp(ndims);
+     259          16 :     shifts.resize(ndims, 0);
+     260          16 :     shifts[0] = 1;
+     261          38 :     for (size_t i = 0; i < ndims; ++i) {
+     262          22 :       mp[i] = dimensions[i].getMiddlePoints();
+     263          22 :       if (i > 0) {
+     264           6 :         shifts[i] = shifts[i - 1] * dimensions[i - 1].nbins;
+     265             :       }
+     266             :       ss.precision(std::numeric_limits<double>::max_digits10);
+     267          44 :       ss << std::fixed << "# " << dimensions[i].min << ' '
+     268          44 :          << dimensions[i].binWidth << ' ' << dimensions[i].nbins;
+     269          22 :       if (dimensions[i].isPeriodic())
+     270          24 :         ss << " 1" << '\n';
+     271             :       else
+     272          20 :         ss << " 0" << '\n';
+     273             :     }
+     274          16 :     fillTable(mp);
+     275          16 :     headers = ss.str();
+     276          16 :     outputunit = 1.0;
+     277             :     // For 1D pmf
+     278          16 :     if (ndims == 1) {
+     279          10 :       endpoints.resize(dimensions[0].nbins + 1, 0);
+     280          10 :       double ep = dimensions[0].min;
+     281          10 :       double stride = dimensions[0].binWidth;
+     282        1020 :       for (auto it = begin(endpoints); it != end(endpoints); ++it) {
+     283        1010 :         (*it) = ep;
+     284        1010 :         ep += stride;
+     285             :       }
+     286             :     }
+     287          16 :   }
+     288             :   template <typename Archive>
+     289             :   void serialize(Archive &ar, const unsigned int version) {
+     290             :     boost::serialization::split_member(ar, *this, version);
+     291             :   }
+     292             : };
+     293             : 
+     294             : class ABF : public DRRForceGrid {
+     295             : public:
+     296          16 :   ABF() {}
+     297           2 :   ABF(const vector<DRRAxis> &p_dimensions, const string &p_suffix,
+     298             :       double fullSamples = 500.0, double maxFactor = 1.0,
+     299             :       bool initializeTable = true)
+     300           2 :     : DRRForceGrid(p_dimensions, p_suffix, initializeTable),
+     301           2 :       mFullSamples(fullSamples), mMaxFactors(p_dimensions.size(), maxFactor) {}
+     302          11 :   ABF(const vector<DRRAxis> &p_dimensions, const string &p_suffix,
+     303             :       double fullSamples, const vector<double>& maxFactors,
+     304             :       bool initializeTable = true)
+     305          11 :     : DRRForceGrid(p_dimensions, p_suffix, initializeTable),
+     306          11 :       mFullSamples(fullSamples), mMaxFactors(maxFactors) {}
+     307             :   // Provide a setter for ABF parametres (fullsamples, maxfactor)
+     308             :   void setParameters(double fullSamples, const vector<double>& maxFactors) {
+     309           1 :     mFullSamples = fullSamples;
+     310           1 :     mMaxFactors = maxFactors;
+     311           1 :   }
+     312             :   // Store the "instantaneous" spring force of a point and get ABF bias forces.
+     313             :   bool store_getbias(const vector<double> &pos,
+     314             :                      const vector<double> &f,
+     315             :                      vector<double> &fbias);
+     316             :   static ABF mergewindow(const ABF &aWA, const ABF &aWB);
+     317          38 :   ~ABF() {}
+     318             : 
+     319             : private:
+     320             :   // Parametres for calculate bias force
+     321             :   double mFullSamples;
+     322             :   vector<double> mMaxFactors;
+     323             :   // Boost serialization
+     324             :   friend class boost::serialization::access;
+     325             :   template <typename Archive>
+     326             :   void serialize(Archive &ar, const unsigned int version) {
+     327          27 :     ar &boost::serialization::base_object<DRRForceGrid>(*this);
+     328             :   }
+     329             : };
+     330             : 
+     331          28 : class CZAR : public DRRForceGrid {
+     332             : public:
+     333          16 :   CZAR() : kbt(0) {}
+     334             :   CZAR(const vector<DRRAxis> &p_dimensions, const string &p_suffix,
+     335             :        double p_kbt, bool initializeTable = true)
+     336          13 :     : DRRForceGrid(p_dimensions, p_suffix, initializeTable), kbt(p_kbt) {}
+     337             :   vector<double> getGradient(const vector<double> &pos,
+     338             :                              bool SkipCheck = false) const;
+     339             :   double getkbt() const { return kbt; }
+     340             :   void setkbt(double p_kbt) { kbt = p_kbt; }
+     341             :   static CZAR mergewindow(const CZAR &cWA, const CZAR &cWB);
+     342             :   void writeZCountZGrad(const string &filename, bool addition = false) const;
+     343          23 :   ~CZAR() {}
+     344             : 
+     345             : private:
+     346             :   double kbt;
+     347             :   friend class boost::serialization::access;
+     348             :   template <typename Archive>
+     349          27 :   void serialize(Archive &ar, const unsigned int version) {
+     350          27 :     ar &boost::serialization::base_object<DRRForceGrid>(*this);
+     351          27 :     ar &kbt;
+     352          27 :   }
+     353             : };
+     354             : }
+     355             : }
+     356             : 
+     357             : #endif
+     358             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/drr/DynamicReferenceRestraining.cpp.func-sort-c.html b/coverage/drr/DynamicReferenceRestraining.cpp.func-sort-c.html new file mode 100644 index 000000000000..fb4bdc1b7abe --- /dev/null +++ b/coverage/drr/DynamicReferenceRestraining.cpp.func-sort-c.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - drr/DynamicReferenceRestraining.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - drr - DynamicReferenceRestraining.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:40444391.2 %
Date:2024-04-19 12:12:35Functions:8988.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3drr27DynamicReferenceRestrainingC2ERKNS_13ActionOptionsE0
_ZN4PLMD3drr27DynamicReferenceRestraining10backupFileERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1
_ZN4PLMD3drr27DynamicReferenceRestraining13is_file_existEPKc1
_ZN4PLMD3drr27DynamicReferenceRestraining4loadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1
_ZN4PLMD3drr27DynamicReferenceRestrainingC1ERKNS_13ActionOptionsE12
_ZN4PLMD3drr27DynamicReferenceRestraining16registerKeywordsERNS_8KeywordsE14
_ZN4PLMD3drr27DynamicReferenceRestraining4saveERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEx19
_ZN4PLMD3drr27DynamicReferenceRestraining6updateEv123
_ZN4PLMD3drr27DynamicReferenceRestraining9calculateEv123
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/drr/DynamicReferenceRestraining.cpp.func.html b/coverage/drr/DynamicReferenceRestraining.cpp.func.html new file mode 100644 index 000000000000..a2a1a0a3e5fb --- /dev/null +++ b/coverage/drr/DynamicReferenceRestraining.cpp.func.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - drr/DynamicReferenceRestraining.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - drr - DynamicReferenceRestraining.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:40444391.2 %
Date:2024-04-19 12:12:35Functions:8988.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3drr27DynamicReferenceRestraining10backupFileERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1
_ZN4PLMD3drr27DynamicReferenceRestraining13is_file_existEPKc1
_ZN4PLMD3drr27DynamicReferenceRestraining16registerKeywordsERNS_8KeywordsE14
_ZN4PLMD3drr27DynamicReferenceRestraining4loadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1
_ZN4PLMD3drr27DynamicReferenceRestraining4saveERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEx19
_ZN4PLMD3drr27DynamicReferenceRestraining6updateEv123
_ZN4PLMD3drr27DynamicReferenceRestraining9calculateEv123
_ZN4PLMD3drr27DynamicReferenceRestrainingC1ERKNS_13ActionOptionsE12
_ZN4PLMD3drr27DynamicReferenceRestrainingC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/drr/DynamicReferenceRestraining.cpp.gcov.html b/coverage/drr/DynamicReferenceRestraining.cpp.gcov.html new file mode 100644 index 000000000000..b1048c006104 --- /dev/null +++ b/coverage/drr/DynamicReferenceRestraining.cpp.gcov.html @@ -0,0 +1,969 @@ + + + + + + + + LCOV - plumed test coverage - drr/DynamicReferenceRestraining.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - drr - DynamicReferenceRestraining.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:40444391.2 %
Date:2024-04-19 12:12:35Functions:8988.9 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3drr11UIestimator11UIestimator15read_inputfilesERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EE1
_ZN4PLMD3drr11UIestimator11UIestimator11calc_1D_pmfEv9
_ZN4PLMD3drr11UIestimator11UIestimator12write_1D_pmfEv9
_ZN4PLMD3drr11UIestimator11UIestimatorC2ERKSt6vectorIdSaIdEES7_S7_S7_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEibRKS3_ISD_SaISD_EEd9
_ZN4PLMD3drr11UIestimator8n_matrixC2ERKSt6vectorIdSaIdEES7_S7_i9
_ZN4PLMD3drr11UIestimator8n_vectorISt6vectorIdSaIdEEEC2ERKS5_S8_S8_iS8_10
_ZN4PLMD3drr11UIestimator11UIestimatorC2Ev12
_ZN4PLMD3drr11UIestimator8n_vectorIiEC2ERKSt6vectorIdSaIdEES8_S8_iRKi19
_ZN4PLMD3drr11UIestimator11UIestimator11write_filesEv21
_ZN4PLMD3drr11UIestimator11UIestimator8calc_pmfEv21
_ZN4PLMD3drr11UIestimator11UIestimatorD2Ev21
_ZN4PLMD3drr11UIestimator8n_matrixC2Ev21
_ZN4PLMD3drr11UIestimator8n_vectorIdEC2Ev21
_ZN4PLMD3drr11UIestimator8n_vectorISt6vectorIdSaIdEEEC2Ev42
_ZN4PLMD3drr11UIestimator8n_vectorIdEC2ERKSt6vectorIdSaIdEES8_S8_iRKd63
_ZN4PLMD3drr11UIestimator8n_vectorIiEC2Ev63
_ZNK4PLMD3drr11UIestimator11UIestimator9writeheadERSt14basic_ofstreamIcSt11char_traitsIcEE63
_ZN4PLMD3drr11UIestimator11UIestimator6updateEiRKSt6vectorIdSaIdEES5_87
_ZN4PLMD3drr11UIestimator8n_matrix14increase_valueERKSt6vectorIdSaIdEES7_i87
_ZN4PLMD3drr11UIestimator8n_vectorIiE14increase_valueERKSt6vectorIdSaIdEERKi91
_ZN4PLMD3drr11UIestimator8n_vectorIiE9set_valueERKSt6vectorIdSaIdEERKi212
_ZN4PLMD3drr11UIestimator8n_vectorISt6vectorIdSaIdEEE9set_valueERKS5_S8_225
_ZN4PLMD3drr11UIestimator8n_vectorIdE14increase_valueERKSt6vectorIdSaIdEERKd318
_ZN4PLMD3drr11UIestimator8n_vectorISt6vectorIdSaIdEEE9get_valueERKS5_737
_ZN4PLMD3drr11UIestimator8n_vectorISt6vectorIdSaIdEEE9convert_xERKS5_962
_ZN4PLMD3drr11UIestimator8n_vectorIiE9get_valueERKSt6vectorIdSaIdEE7196
_ZN4PLMD3drr11UIestimator8n_vectorIiE9convert_xERKSt6vectorIdSaIdEE7499
_ZN4PLMD3drr11UIestimator8n_vectorIdE9set_valueERKSt6vectorIdSaIdEERKd26790
_ZN4PLMD3drr11UIestimator8n_matrix9get_valueERKSt6vectorIdSaIdEES7_171000
_ZN4PLMD3drr11UIestimator8n_matrix9convert_xERKSt6vectorIdSaIdEE171087
_ZN4PLMD3drr11UIestimator8n_matrix9convert_yERKSt6vectorIdSaIdEES7_171087
_ZN4PLMD3drr11UIestimator8n_vectorIdE9get_valueERKSt6vectorIdSaIdEE280499
_ZN4PLMD3drr11UIestimator8n_vectorIdE9convert_xERKSt6vectorIdSaIdEE307607
_ZN4PLMD3drr11UIestimator8n_matrix5roundEd1018791
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/drr/colvar_UIestimator.h.func.html b/coverage/drr/colvar_UIestimator.h.func.html new file mode 100644 index 000000000000..312633ded71c --- /dev/null +++ b/coverage/drr/colvar_UIestimator.h.func.html @@ -0,0 +1,209 @@ + + + + + + + + LCOV - plumed test coverage - drr/colvar_UIestimator.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - drr - colvar_UIestimator.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:29930299.0 %
Date:2024-04-19 12:12:35Functions:3434100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3drr11UIestimator11UIestimator11calc_1D_pmfEv9
_ZN4PLMD3drr11UIestimator11UIestimator11write_filesEv21
_ZN4PLMD3drr11UIestimator11UIestimator12write_1D_pmfEv9
_ZN4PLMD3drr11UIestimator11UIestimator15read_inputfilesERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EE1
_ZN4PLMD3drr11UIestimator11UIestimator6updateEiRKSt6vectorIdSaIdEES5_87
_ZN4PLMD3drr11UIestimator11UIestimator8calc_pmfEv21
_ZN4PLMD3drr11UIestimator11UIestimatorC2ERKSt6vectorIdSaIdEES7_S7_S7_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEibRKS3_ISD_SaISD_EEd9
_ZN4PLMD3drr11UIestimator11UIestimatorC2Ev12
_ZN4PLMD3drr11UIestimator11UIestimatorD2Ev21
_ZN4PLMD3drr11UIestimator8n_matrix14increase_valueERKSt6vectorIdSaIdEES7_i87
_ZN4PLMD3drr11UIestimator8n_matrix5roundEd1018791
_ZN4PLMD3drr11UIestimator8n_matrix9convert_xERKSt6vectorIdSaIdEE171087
_ZN4PLMD3drr11UIestimator8n_matrix9convert_yERKSt6vectorIdSaIdEES7_171087
_ZN4PLMD3drr11UIestimator8n_matrix9get_valueERKSt6vectorIdSaIdEES7_171000
_ZN4PLMD3drr11UIestimator8n_matrixC2ERKSt6vectorIdSaIdEES7_S7_i9
_ZN4PLMD3drr11UIestimator8n_matrixC2Ev21
_ZN4PLMD3drr11UIestimator8n_vectorISt6vectorIdSaIdEEE9convert_xERKS5_962
_ZN4PLMD3drr11UIestimator8n_vectorISt6vectorIdSaIdEEE9get_valueERKS5_737
_ZN4PLMD3drr11UIestimator8n_vectorISt6vectorIdSaIdEEE9set_valueERKS5_S8_225
_ZN4PLMD3drr11UIestimator8n_vectorISt6vectorIdSaIdEEEC2ERKS5_S8_S8_iS8_10
_ZN4PLMD3drr11UIestimator8n_vectorISt6vectorIdSaIdEEEC2Ev42
_ZN4PLMD3drr11UIestimator8n_vectorIdE14increase_valueERKSt6vectorIdSaIdEERKd318
_ZN4PLMD3drr11UIestimator8n_vectorIdE9convert_xERKSt6vectorIdSaIdEE307607
_ZN4PLMD3drr11UIestimator8n_vectorIdE9get_valueERKSt6vectorIdSaIdEE280499
_ZN4PLMD3drr11UIestimator8n_vectorIdE9set_valueERKSt6vectorIdSaIdEERKd26790
_ZN4PLMD3drr11UIestimator8n_vectorIdEC2ERKSt6vectorIdSaIdEES8_S8_iRKd63
_ZN4PLMD3drr11UIestimator8n_vectorIdEC2Ev21
_ZN4PLMD3drr11UIestimator8n_vectorIiE14increase_valueERKSt6vectorIdSaIdEERKi91
_ZN4PLMD3drr11UIestimator8n_vectorIiE9convert_xERKSt6vectorIdSaIdEE7499
_ZN4PLMD3drr11UIestimator8n_vectorIiE9get_valueERKSt6vectorIdSaIdEE7196
_ZN4PLMD3drr11UIestimator8n_vectorIiE9set_valueERKSt6vectorIdSaIdEERKi212
_ZN4PLMD3drr11UIestimator8n_vectorIiEC2ERKSt6vectorIdSaIdEES8_S8_iRKi19
_ZN4PLMD3drr11UIestimator8n_vectorIiEC2Ev63
_ZNK4PLMD3drr11UIestimator11UIestimator9writeheadERSt14basic_ofstreamIcSt11char_traitsIcEE63
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/drr/colvar_UIestimator.h.gcov.html b/coverage/drr/colvar_UIestimator.h.gcov.html new file mode 100644 index 000000000000..7d0efabfe7eb --- /dev/null +++ b/coverage/drr/colvar_UIestimator.h.gcov.html @@ -0,0 +1,932 @@ + + + + + + + + LCOV - plumed test coverage - drr/colvar_UIestimator.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - drr - colvar_UIestimator.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:29930299.0 %
Date:2024-04-19 12:12:35Functions:3434100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :     Copyright (c) 2017 of Haochuan Chen (excluding colvar_UIestimator.h)
+       3             :     Copyright (c) 2017 of Haohao Fu (colvar_UIestimator.h)
+       4             : 
+       5             :     This program is free software: you can redistribute it and/or modify
+       6             :     it under the terms of the GNU Lesser General Public License as published
+       7             :     by the Free Software Foundation, either version 3 of the License, or
+       8             :     (at your option) any later version.
+       9             : 
+      10             :     This program is distributed in the hope that it will be useful,
+      11             :     but WITHOUT ANY WARRANTY; without even the implied warranty of
+      12             :     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      13             :     GNU Lesser General Public License for more details.
+      14             : 
+      15             :     You should have received a copy of the GNU Lesser General Public License
+      16             :     along with this program.  If not, see <http://www.gnu.org/licenses/>.
+      17             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      18             : #ifndef __PLUMED_drr_colvar_UIestimator_h
+      19             : #define __PLUMED_drr_colvar_UIestimator_h
+      20             : // The original code(https://github.com/fhh2626/colvars/blob/master/src/colvar_UIestimator.h) has been modified by Haochuan Chen.
+      21             : // Modifications:
+      22             : // 1. Disable colvars related code.
+      23             : // 2. Change boltzmann constant.
+      24             : // 3. Change output precision.
+      25             : // I(Haochuan Chen) don't know how to maintain this code and how it runs. If you are interested in it, please contact Haohao Fu.
+      26             : 
+      27             : #include <cmath>
+      28             : #include <vector>
+      29             : #include <fstream>
+      30             : #include <string>
+      31             : #include <iomanip>
+      32             : #include <limits>
+      33             : 
+      34             : #include <typeinfo>
+      35             : 
+      36             : // only for colvar module!
+      37             : // when integrated into other code, just remove this line and "...cvm::backup_file(...)"
+      38             : // #include "colvarmodule.h"
+      39             : 
+      40             : namespace PLMD {
+      41             : namespace drr {
+      42             : 
+      43             : namespace UIestimator
+      44             : {
+      45             : const int Y_SIZE = 21;
+      46             : const int HALF_Y_SIZE = 10;
+      47             : const double BOLTZMANN = 0.0083144621;
+      48             : const int EXTENDED_X_SIZE = HALF_Y_SIZE;
+      49             : 
+      50             : class n_matrix    // spare matrix, stores the distribution matrix of n(x,y)
+      51             : {
+      52             : public:
+      53          21 :   n_matrix() {}
+      54           9 :   n_matrix(const std::vector<double> & lowerboundary_p,   // lowerboundary of x
+      55             :            const std::vector<double> & upperboundary_p,   // upperboundary of
+      56             :            const std::vector<double> & width_p,           // width of x
+      57             :            const int y_size)           // size of y, for example, ysize=7, then when x=1, the distribution of y in [-2,4] is considered
+      58           9 :     : lowerboundary(lowerboundary_p), upperboundary(upperboundary_p), width(width_p)
+      59             :   {
+      60           9 :     this->dimension = lowerboundary.size();
+      61           9 :     this->y_size = y_size;     // keep in mind the internal (spare) matrix is stored in diagonal form
+      62           9 :     this->y_total_size = int(pow(y_size, dimension) + 0.000001);
+      63             : 
+      64             :     // the range of the matrix is [lowerboundary, upperboundary]
+      65           9 :     x_total_size = 1;
+      66          24 :     for (int i = 0; i < dimension; i++)
+      67             :     {
+      68          15 :       x_size.push_back(int((upperboundary[i] - lowerboundary[i]) / width[i] + 0.000001));
+      69          15 :       x_total_size *= x_size[i];
+      70             :     }
+      71             : 
+      72             :     // initialize the internal matrix
+      73           9 :     matrix.reserve(x_total_size);
+      74         100 :     for (int i = 0; i < x_total_size; i++)
+      75             :     {
+      76         182 :       matrix.push_back(std::vector<int>(y_total_size, 0));
+      77             :     }
+      78             : 
+      79           9 :     temp.resize(dimension);
+      80           9 :   }
+      81             : 
+      82      171000 :   int inline get_value(const std::vector<double> & x, const std::vector<double> & y)
+      83             :   {
+      84             :     //if (matrix[convert_x(x)][convert_y(x, y)]!=0)
+      85             :     //{
+      86             :     //std::cout<<convert_x(x)<<" "<<convert_y(x, y)<<" "<<x[0]<<" "<<x[1]<<" "<<y[0]<<" "<<y[1]<<" ";
+      87             :     //std::cout<<matrix[convert_x(x)][convert_y(x, y)]<<"sadasfdasaaaaaaaa"<<std::endl;
+      88             :     //}
+      89      171000 :     return matrix[convert_x(x)][convert_y(x, y)];
+      90             :   }
+      91             : 
+      92             :   void inline set_value(const std::vector<double> & x, const std::vector<double> & y, const int value)
+      93             :   {
+      94             :     matrix[convert_x(x)][convert_y(x,y)] = value;
+      95             :   }
+      96             : 
+      97          87 :   void inline increase_value(const std::vector<double> & x, const std::vector<double> & y, const int value)
+      98             :   {
+      99          87 :     matrix[convert_x(x)][convert_y(x,y)] += value;
+     100          87 :   }
+     101             : 
+     102             : private:
+     103             :   std::vector<double> lowerboundary;
+     104             :   std::vector<double> upperboundary;
+     105             :   std::vector<double> width;
+     106             :   int dimension;
+     107             :   std::vector<int> x_size;       // the size of x in each dimension
+     108             :   int x_total_size;              // the size of x of the internal matrix
+     109             :   int y_size;                    // the size of y in each dimension
+     110             :   int y_total_size;              // the size of y of the internal matrix
+     111             : 
+     112             :   std::vector<std::vector<int> > matrix;  // the internal matrix
+     113             : 
+     114             :   std::vector<int> temp;         // this vector is used in convert_x and convert_y to save computational resource
+     115             : 
+     116      171087 :   int convert_x(const std::vector<double> & x)        // convert real x value to its interal index
+     117             :   {
+     118      510684 :     for (int i = 0; i < dimension; i++)
+     119             :     {
+     120      339597 :       temp[i] = int((x[i] - lowerboundary[i]) / width[i] + 0.000001);
+     121             :     }
+     122             : 
+     123             :     int index = 0;
+     124      510684 :     for (int i = 0; i < dimension; i++)
+     125             :     {
+     126      339597 :       if (i + 1 < dimension)
+     127             :       {
+     128             :         int x_temp = 1;
+     129      337020 :         for (int j = i + 1; j < dimension; j++)
+     130      168510 :           x_temp *= x_size[j];
+     131      168510 :         index += temp[i] * x_temp;
+     132             :       }
+     133             :       else
+     134      171087 :         index += temp[i];
+     135             :     }
+     136      171087 :     return index;
+     137             :   }
+     138             : 
+     139      171087 :   int convert_y(const std::vector<double> & x, const std::vector<double> & y)        // convert real y value to its interal index
+     140             :   {
+     141      510684 :     for (int i = 0; i < dimension; i++)
+     142             :     {
+     143      339597 :       temp[i] = round((round(y[i] / width[i] + 0.000001) - round(x[i] / width[i] + 0.000001)) + (y_size - 1) / 2 + 0.000001);
+     144             :     }
+     145             : 
+     146             :     int index = 0;
+     147      510684 :     for (int i = 0; i < dimension; i++)
+     148             :     {
+     149      339597 :       if (i + 1 < dimension)
+     150      168510 :         index += temp[i] * int(pow(y_size, dimension - i - 1) + 0.000001);
+     151             :       else
+     152      171087 :         index += temp[i];
+     153             :     }
+     154      171087 :     return index;
+     155             :   }
+     156             : 
+     157     1018791 :   double round(double r)
+     158             :   {
+     159     1018791 :     return (r > 0.0) ? floor(r + 0.5) : ceil(r - 0.5);
+     160             :   }
+     161             : };
+     162             : 
+     163             : // vector, store the sum_x, sum_x_square, count_y
+     164             : template <typename T>
+     165             : class n_vector
+     166             : {
+     167             : public:
+     168         126 :   n_vector() {}
+     169          92 :   n_vector(const std::vector<double> & lowerboundary,   // lowerboundary of x
+     170             :            const std::vector<double> & upperboundary,   // upperboundary of
+     171             :            const std::vector<double> & width_p,                // width of x
+     172             :            const int y_size,           // size of y, for example, ysize=7, then when x=1, the distribution of y in [-2,4] is considered
+     173             :            const T & default_value)          //   the default value of T
+     174          92 :     :width(width_p)
+     175             :   {
+     176          92 :     this->dimension = lowerboundary.size();
+     177             : 
+     178          92 :     x_total_size = 1;
+     179         252 :     for (int i = 0; i < dimension; i++)
+     180             :     {
+     181         160 :       this->lowerboundary.push_back(lowerboundary[i] - (y_size - 1) / 2 * width[i] - 0.000001);
+     182         160 :       this->upperboundary.push_back(upperboundary[i] + (y_size - 1) / 2 * width[i] + 0.000001);
+     183             : 
+     184         160 :       x_size.push_back(int((this->upperboundary[i] - this->lowerboundary[i]) / this->width[i] + 0.000001));
+     185         160 :       x_total_size *= x_size[i];
+     186             :     }
+     187             : 
+     188             :     // initialize the internal vector
+     189          92 :     vector.resize(x_total_size, default_value);
+     190             : 
+     191          92 :     temp.resize(dimension);
+     192          92 :   }
+     193             : 
+     194      288432 :   T inline get_value(const std::vector<double> & x)
+     195             :   {
+     196      288432 :     return vector[convert_x(x)];
+     197             :   }
+     198             : 
+     199       27227 :   void inline set_value(const std::vector<double> & x, const T & value)
+     200             :   {
+     201       27227 :     vector[convert_x(x)] = value;
+     202       27227 :   }
+     203             : 
+     204         409 :   void inline increase_value(const std::vector<double> & x, const T & value)
+     205             :   {
+     206         409 :     vector[convert_x(x)] += value;
+     207         409 :   }
+     208             : private:
+     209             :   std::vector<double> lowerboundary;
+     210             :   std::vector<double> upperboundary;
+     211             :   std::vector<double> width;
+     212             :   int dimension;
+     213             :   std::vector<int> x_size;       // the size of x in each dimension
+     214             :   int x_total_size;              // the size of x of the internal matrix
+     215             : 
+     216             :   std::vector<T> vector;  // the internal vector
+     217             : 
+     218             :   std::vector<int> temp;         // this vector is used in convert_x and convert_y to save computational resource
+     219             : 
+     220      316068 :   int convert_x(const std::vector<double> & x)        // convert real x value to its interal index
+     221             :   {
+     222      943161 :     for (int i = 0; i < dimension; i++)
+     223             :     {
+     224      627093 :       temp[i] = int((x[i] - lowerboundary[i]) / width[i] + 0.000001);
+     225             :     }
+     226             : 
+     227             :     int index = 0;
+     228      943161 :     for (int i = 0; i < dimension; i++)
+     229             :     {
+     230      627093 :       if (i + 1 < dimension)
+     231             :       {
+     232             :         int x_temp = 1;
+     233      622050 :         for (int j = i + 1; j < dimension; j++)
+     234      311025 :           x_temp *= x_size[j];
+     235      311025 :         index += temp[i] * x_temp;
+     236             :       }
+     237             :       else
+     238      316068 :         index += temp[i];
+     239             :     }
+     240      316068 :     return index;
+     241             :   }
+     242             : };
+     243             : 
+     244             : class UIestimator      // the implemension of UI estimator
+     245             : {
+     246             : public:
+     247          12 :   UIestimator() {}
+     248             : 
+     249             :   //called when (re)start an eabf simulation
+     250           9 :   UIestimator(const std::vector<double>& lowerboundary_p,
+     251             :               const std::vector<double>& upperboundary_p,
+     252             :               const std::vector<double>& width_p,
+     253             :               const std::vector<double>& krestr_p,                // force constant in eABF
+     254             :               const std::string& output_filename_p,              // the prefix of output files
+     255             :               const int output_freq_p,
+     256             :               const bool restart_p,                              // whether restart from a .count and a .grad file
+     257             :               const std::vector<std::string>& input_filename_p,   // the prefixes of input files
+     258             :               const double temperature_p)
+     259           9 :     : lowerboundary(lowerboundary_p), upperboundary(upperboundary_p),
+     260           9 :       width(width_p), krestr(krestr_p),
+     261           9 :       output_filename(output_filename_p), output_freq(output_freq_p),
+     262           9 :       restart(restart_p), input_filename(input_filename_p),
+     263          18 :       temperature(temperature_p)
+     264             :   {
+     265             : 
+     266           9 :     dimension = lowerboundary.size();
+     267             : 
+     268          24 :     for (int i = 0; i < dimension; i++)
+     269             :     {
+     270          30 :       sum_x.push_back(n_vector<double>(lowerboundary, upperboundary, width, Y_SIZE, 0.0));
+     271          30 :       sum_x_square.push_back(n_vector<double>(lowerboundary, upperboundary, width, Y_SIZE, 0.0));
+     272             : 
+     273          30 :       x_av.push_back(n_vector<double>(lowerboundary, upperboundary, width, Y_SIZE, 0.0));
+     274          30 :       sigma_square.push_back(n_vector<double>(lowerboundary, upperboundary, width, Y_SIZE, 0.0));
+     275             :     }
+     276             : 
+     277           9 :     count_y = n_vector<int>(lowerboundary, upperboundary, width, Y_SIZE, 0);
+     278           9 :     distribution_x_y = n_matrix(lowerboundary, upperboundary, width, Y_SIZE);
+     279             : 
+     280           9 :     grad = n_vector<std::vector<double> >(lowerboundary, upperboundary, width, 1, std::vector<double>(dimension, 0.0));
+     281           9 :     count = n_vector<int>(lowerboundary, upperboundary, width, 1, 0);
+     282             : 
+     283           9 :     written = false;
+     284           9 :     written_1D = false;
+     285             : 
+     286           9 :     if (dimension == 1)
+     287             :     {
+     288           3 :       std::vector<double> upperboundary_temp = upperboundary;
+     289           3 :       upperboundary_temp[0] = upperboundary[0] + width[0];
+     290           3 :       oneD_pmf = n_vector<double>(lowerboundary, upperboundary_temp, width, 1, 0.0);
+     291             :     }
+     292             : 
+     293           9 :     if (restart == true)
+     294             :     {
+     295           1 :       input_grad = n_vector<std::vector<double> >(lowerboundary, upperboundary, width, 1, std::vector<double>(dimension, 0.0));
+     296           1 :       input_count = n_vector<int>(lowerboundary, upperboundary, width, 1, 0);
+     297             : 
+     298             :       // initialize input_Grad and input_count
+     299           1 :       std::vector<double> loop_flag(dimension, 0);
+     300           3 :       for (int i = 0; i < dimension; i++)
+     301             :       {
+     302           2 :         loop_flag[i] = lowerboundary[i];
+     303             :       }
+     304             :       while (true)
+     305             :       {
+     306          27 :         for (int i = 0; i < dimension; i++)
+     307             :         {
+     308          36 :           input_grad.set_value(loop_flag, std::vector<double>(dimension,0));
+     309             :         }
+     310           9 :         input_count.set_value(loop_flag, 0);
+     311             : 
+     312             :         // iterate over any dimensions
+     313           9 :         int i = dimension - 1;
+     314             :         while (true)
+     315             :         {
+     316          12 :           loop_flag[i] += width[i];
+     317          12 :           if (loop_flag[i] > upperboundary[i] - width[i] + 0.00001)
+     318             :           {
+     319           4 :             loop_flag[i] = lowerboundary[i];
+     320           4 :             i--;
+     321           4 :             if (i < 0)
+     322           1 :               goto INITIAL_LOOPEND;
+     323             :           }
+     324             :           else
+     325             :             break;
+     326             :         }
+     327             :       }
+     328             : INITIAL_LOOPEND:
+     329           1 :       read_inputfiles(input_filename);
+     330             :     }
+     331           9 :   }
+     332             : 
+     333          42 :   ~UIestimator() {}
+     334             : 
+     335             :   // called from MD engine every step
+     336          87 :   bool update(const int step, const std::vector<double> & x, std::vector<double> y)
+     337             :   {
+     338             : 
+     339             :     //std::cout<<"weeeee: :"<<std::endl;
+     340             :     //for (int i = 0; i < dimension; i++)
+     341             :     //{
+     342             :     //  std::cout<<x[i]<<" "<<y[i]<<" ";
+     343             :     //}
+     344             :     //std::cout<<std::endl;
+     345             : 
+     346          87 :     if (step % output_freq == 0)
+     347             :     {
+     348          21 :       calc_pmf();
+     349          21 :       write_files();
+     350             :       //write_interal_data();
+     351             :     }
+     352             : 
+     353         246 :     for (int i = 0; i < dimension; i++)
+     354             :     {
+     355             :       // for dihedral RC, it is possible that x = 179 and y = -179, should correct it
+     356             :       // may have problem, need to fix
+     357         159 :       if (x[i] > 150 && y[i] < -150)
+     358             :       {
+     359             :         //std::vector<double> x_temp(x);
+     360             :         //x_temp[i] -= 360;
+     361             :         //update(7, x_temp, y);
+     362           0 :         y[i] += 360;
+     363             :       }
+     364         159 :       if (x[i] < -150 && y[i] > 150)
+     365             :       {
+     366             :         //std::vector<double> x_temp(x);
+     367             :         //x_temp[i] += 360;
+     368             :         //update(7, x_temp, y);
+     369           0 :         y[i] -= 360;
+     370             :       }
+     371             : 
+     372         159 :       if (x[i] < lowerboundary[i] - EXTENDED_X_SIZE * width[i] + 0.00001 || x[i] > upperboundary[i] + EXTENDED_X_SIZE * width[i] - 0.00001 \
+     373         159 :           || y[i] - x[i] < -HALF_Y_SIZE * width[i] + 0.00001 || y[i] - x[i] > HALF_Y_SIZE * width[i] - 0.00001 \
+     374         318 :           || y[i] - lowerboundary[i] < -HALF_Y_SIZE * width[i] + 0.00001 || y[i] - upperboundary[i] > HALF_Y_SIZE * width[i] - 0.00001)
+     375             :         return false;
+     376             :     }
+     377             : 
+     378             :     //for (int i = 0; i < dimension; i++)
+     379             :     //{
+     380             :     //  std::cout<<x[i]<<" "<<y[i]<<" ";
+     381             :     //}
+     382             :     //std::cout<<std::endl;
+     383             : 
+     384         246 :     for (int i = 0; i < dimension; i++)
+     385             :     {
+     386         159 :       sum_x[i].increase_value(y, x[i]);
+     387         159 :       sum_x_square[i].increase_value(y, x[i] * x[i]);
+     388             :     }
+     389          87 :     count_y.increase_value(y, 1);
+     390             : 
+     391         246 :     for (int i = 0; i < dimension; i++)
+     392             :     {
+     393             :       //if (x[i] < lowerboundary[i] + 0.000001 || x[i] > upperboundary[i] - 0.000001)
+     394             :       // adapt colvars precision
+     395         159 :       if (x[i] < lowerboundary[i] + 0.00001 || x[i] > upperboundary[i] - 0.00001)
+     396             :         return false;
+     397             :     }
+     398          87 :     distribution_x_y.increase_value(x, y, 1);
+     399             : 
+     400          87 :     return true;
+     401             :   }
+     402             : 
+     403             :   // update the output_filename
+     404             :   void update_output_filename(const std::string& filename)
+     405             :   {
+     406          87 :     output_filename = filename;
+     407             :   }
+     408             : 
+     409             : private:
+     410             :   std::vector<n_vector<double> > sum_x;                        // the sum of x in each y bin
+     411             :   std::vector<n_vector<double> > sum_x_square;                 // the sum of x in each y bin
+     412             :   n_vector<int> count_y;                              // the distribution of y
+     413             :   n_matrix distribution_x_y;   // the distribution of <x, y> pair
+     414             : 
+     415             :   int dimension;
+     416             : 
+     417             :   std::vector<double> lowerboundary;
+     418             :   std::vector<double> upperboundary;
+     419             :   std::vector<double> width;
+     420             :   std::vector<double> krestr;
+     421             :   std::string output_filename;
+     422             :   int output_freq;
+     423             :   bool restart;
+     424             :   std::vector<std::string> input_filename;
+     425             :   double temperature;
+     426             : 
+     427             :   n_vector<std::vector<double> > grad;
+     428             :   n_vector<int> count;
+     429             : 
+     430             :   n_vector<double> oneD_pmf;
+     431             : 
+     432             :   n_vector<std::vector<double> > input_grad;
+     433             :   n_vector<int> input_count;
+     434             : 
+     435             :   // used in double integration
+     436             :   std::vector<n_vector<double> > x_av;
+     437             :   std::vector<n_vector<double> > sigma_square;
+     438             : 
+     439             :   bool written;
+     440             :   bool written_1D;
+     441             : 
+     442             :   // calculate gradients from the internal variables
+     443          21 :   void calc_pmf()
+     444             :   {
+     445             :     int norm;
+     446             : 
+     447          21 :     std::vector<double> loop_flag(dimension, 0);
+     448          54 :     for (int i = 0; i < dimension; i++)
+     449             :     {
+     450          33 :       loop_flag[i] = lowerboundary[i] - HALF_Y_SIZE * width[i];
+     451             :     }
+     452             : 
+     453             :     while (true)
+     454             :     {
+     455        6783 :       norm = count_y.get_value(loop_flag) > 0 ? count_y.get_value(loop_flag) : 1;
+     456       20106 :       for (int i = 0; i < dimension; i++)
+     457             :       {
+     458       13323 :         x_av[i].set_value(loop_flag, sum_x[i].get_value(loop_flag) / norm);
+     459       13323 :         sigma_square[i].set_value(loop_flag, sum_x_square[i].get_value(loop_flag) / norm - x_av[i].get_value(loop_flag) * x_av[i].get_value(loop_flag));
+     460             :       }
+     461             : 
+     462             :       // iterate over any dimensions
+     463        6783 :       int i = dimension - 1;
+     464             :       while (true)
+     465             :       {
+     466        7063 :         loop_flag[i] += width[i];
+     467        7063 :         if (loop_flag[i] > upperboundary[i] + HALF_Y_SIZE * width[i] - width[i] + 0.00001)
+     468             :         {
+     469         301 :           loop_flag[i] = lowerboundary[i] - HALF_Y_SIZE * width[i];
+     470         301 :           i--;
+     471         301 :           if (i < 0)
+     472          21 :             goto LOOPEND;
+     473             :         }
+     474             :         else
+     475             :           break;
+     476             :       }
+     477             :     }
+     478             : LOOPEND:
+     479             : 
+     480             :     // double integration
+     481          21 :     std::vector<double> av(dimension, 0);
+     482          21 :     std::vector<double> diff_av(dimension, 0);
+     483             : 
+     484          21 :     std::vector<double> loop_flag_x(dimension, 0);
+     485          21 :     std::vector<double> loop_flag_y(dimension, 0);
+     486          54 :     for (int i = 0; i < dimension; i++)
+     487             :     {
+     488          33 :       loop_flag_x[i] = lowerboundary[i];
+     489          33 :       loop_flag_y[i] = loop_flag_x[i] - HALF_Y_SIZE * width[i];
+     490             :     }
+     491             : 
+     492             :     while (true)
+     493             :     {
+     494         203 :       norm = 0;
+     495         546 :       for (int i = 0; i < dimension; i++)
+     496             :       {
+     497         343 :         av[i] = 0;
+     498         343 :         diff_av[i] = 0;
+     499         343 :         loop_flag_y[i] = loop_flag_x[i] - HALF_Y_SIZE * width[i];
+     500             :       }
+     501             : 
+     502             :       while (true)
+     503             :       {
+     504             :         //std::cout<<"pppppppppppppppppppppp "<<loop_flag_x[0]<<" "<<loop_flag_x[1]<<" "<<loop_flag_y[0]<<" "<<loop_flag_y[1]<<std::endl;
+     505       57260 :         norm += distribution_x_y.get_value(loop_flag_x, loop_flag_y);
+     506      170520 :         for (int i = 0; i < dimension; i++)
+     507             :         {
+     508      113260 :           if (sigma_square[i].get_value(loop_flag_y) > 0.00001 || sigma_square[i].get_value(loop_flag_y) < -0.00001)
+     509         480 :             av[i] += distribution_x_y.get_value(loop_flag_x, loop_flag_y) * ( (loop_flag_x[i] + 0.5 * width[i]) - x_av[i].get_value(loop_flag_y)) / sigma_square[i].get_value(loop_flag_y);
+     510             : 
+     511      113260 :           diff_av[i] += distribution_x_y.get_value(loop_flag_x, loop_flag_y) * (loop_flag_x[i] - loop_flag_y[i]);
+     512             :         }
+     513             : 
+     514             :         // iterate over any dimensions
+     515       57260 :         int i = dimension - 1;
+     516             :         while (true)
+     517             :         {
+     518       60060 :           loop_flag_y[i] += width[i];
+     519       60060 :           if (loop_flag_y[i] > loop_flag_x[i] + HALF_Y_SIZE * width[i] - width[i] + 0.00001)
+     520             :           {
+     521        3003 :             loop_flag_y[i] = loop_flag_x[i] - HALF_Y_SIZE * width[i];
+     522        3003 :             i--;
+     523        3003 :             if (i < 0)
+     524         203 :               goto LOOPEND2;
+     525             :           }
+     526             :           else
+     527             :             break;
+     528             :         }
+     529             :       }
+     530             : LOOPEND2:
+     531             : 
+     532         203 :       std::vector<double> grad_temp(dimension, 0);
+     533         546 :       for (int i = 0; i < dimension; i++)
+     534             :       {
+     535         343 :         diff_av[i] /= (norm > 0 ? norm : 1);
+     536         343 :         av[i] = BOLTZMANN * temperature * av[i] / (norm > 0 ? norm : 1);
+     537         343 :         grad_temp[i] = av[i] - krestr[i] * diff_av[i];
+     538             :       }
+     539         203 :       grad.set_value(loop_flag_x, grad_temp);
+     540         203 :       count.set_value(loop_flag_x, norm);
+     541             : 
+     542             :       // iterate over any dimensions
+     543         203 :       int i = dimension - 1;
+     544             :       while (true)
+     545             :       {
+     546         243 :         loop_flag_x[i] += width[i];
+     547         243 :         if (loop_flag_x[i] > upperboundary[i] - width[i] + 0.00001)
+     548             :         {
+     549          61 :           loop_flag_x[i] = lowerboundary[i];
+     550          61 :           i--;
+     551          61 :           if (i < 0)
+     552          21 :             goto LOOPEND3;
+     553             :         }
+     554             :         else
+     555             :           break;
+     556             :       }
+     557             :     }
+     558             : LOOPEND3:;
+     559          21 :   }
+     560             : 
+     561             : 
+     562             :   // calculate 1D pmf
+     563           9 :   void calc_1D_pmf()
+     564             :   {
+     565           9 :     std::vector<double> last_position(1, 0);
+     566           9 :     std::vector<double> position(1, 0);
+     567             : 
+     568             :     double min = 0;
+     569           9 :     double dG = 0;
+     570             : 
+     571           9 :     oneD_pmf.set_value(lowerboundary, 0);
+     572           9 :     last_position = lowerboundary;
+     573          72 :     for (double i = lowerboundary[0] + width[0]; i < upperboundary[0] + 0.000001; i += width[0])
+     574             :     {
+     575          63 :       position[0] = i + 0.000001;
+     576          63 :       if (restart == false || input_count.get_value(last_position) == 0)
+     577             :       {
+     578          63 :         dG = oneD_pmf.get_value(last_position) + grad.get_value(last_position)[0] * width[0];
+     579             :       }
+     580             :       else
+     581             :       {
+     582           0 :         dG = oneD_pmf.get_value(last_position) + ((grad.get_value(last_position)[0] * count.get_value(last_position) + input_grad.get_value(last_position)[0] * input_count.get_value(last_position)) / (count.get_value(last_position) + input_count.get_value(last_position))) * width[0];
+     583             :       }
+     584          63 :       if (dG < min)
+     585             :         min = dG;
+     586          63 :       oneD_pmf.set_value(position, dG);
+     587          63 :       last_position[0] = i + 0.000001;
+     588             :     }
+     589             : 
+     590          81 :     for (double i = lowerboundary[0]; i < upperboundary[0] + 0.000001; i += width[0])
+     591             :     {
+     592          72 :       position[0] = i + 0.000001;
+     593          72 :       oneD_pmf.set_value(position, oneD_pmf.get_value(position) - min);
+     594             :     }
+     595           9 :   }
+     596             : 
+     597             :   // write 1D pmf
+     598           9 :   void write_1D_pmf()
+     599             :   {
+     600           9 :     std::string pmf_filename = output_filename + ".UI.pmf";
+     601             : 
+     602             :     // only for colvars module!
+     603             : //                      if (written_1D) cvm::backup_file(pmf_filename.c_str());
+     604             : 
+     605           9 :     std::ofstream ofile_pmf(pmf_filename.c_str());
+     606             : 
+     607           9 :     std::vector<double> position(1, 0);
+     608          81 :     for (double i = lowerboundary[0]; i < upperboundary[0] + 0.000001; i += width[0])
+     609             :     {
+     610          72 :       ofile_pmf << i << " ";
+     611          72 :       position[0] = i + 0.000001;
+     612          72 :       ofile_pmf << oneD_pmf.get_value(position) << std::endl;
+     613             :     }
+     614           9 :     ofile_pmf.close();
+     615             : 
+     616           9 :     written_1D = true;
+     617          18 :   }
+     618             : 
+     619             :   // write heads of the output files
+     620          63 :   void writehead(std::ofstream& os) const
+     621             :   {
+     622          63 :     os << "# " << dimension << std::endl;
+     623         162 :     for (int i = 0; i < dimension; i++)
+     624             :     {
+     625          99 :       os.precision(std::numeric_limits<double>::max_digits10);
+     626         198 :       os << "# " << std::fixed << lowerboundary[i] << " " << width[i] << " " << int((upperboundary[i] - lowerboundary[i]) / width[i] + 0.000001) << " " << 0 << std::endl;
+     627             :     }
+     628             :     os << std::endl;
+     629          63 :   }
+     630             : 
+     631             :   // write interal data, used for testing
+     632             : //   void write_interal_data()
+     633             : //   {
+     634             : //     std::string internal_filaname = output_filename + ".UI.internal";
+     635             : //
+     636             : //     std::ofstream ofile_internal(internal_filaname.c_str());
+     637             : //
+     638             : //     std::vector<double> loop_flag(dimension, 0);
+     639             : //     for (int i = 0; i < dimension; i++)
+     640             : //     {
+     641             : //       loop_flag[i] = lowerboundary[i];
+     642             : //     }
+     643             : //     while (true)
+     644             : //     {
+     645             : //       for (int i = 0; i < dimension; i++)
+     646             : //       {
+     647             : //         ofile_internal << loop_flag[i] + 0.5 * width[i] << " ";
+     648             : //       }
+     649             : //
+     650             : //       for (int i = 0; i < dimension; i++)
+     651             : //       {
+     652             : //         ofile_internal << grad.get_value(loop_flag)[i] << " ";
+     653             : //       }
+     654             : //
+     655             : //       std::vector<double> ii(dimension,0);
+     656             : //       for (double i = loop_flag[0] - 10; i < loop_flag[0] + 10 + 0.00001; i+= width[0])
+     657             : //       {
+     658             : //         for (double j = loop_flag[1] - 10; j< loop_flag[1] + 10 +0.00001; j+=width[1])
+     659             : //         {
+     660             : //           ii[0] = i;
+     661             : //           ii[1] = j;
+     662             : //           ofile_internal << i <<" "<<j<<" "<< distribution_x_y.get_value(loop_flag,ii)<< " ";
+     663             : //         }
+     664             : //       }
+     665             : //       ofile_internal << std::endl;
+     666             : //
+     667             : //       // iterate over any dimensions
+     668             : //       int i = dimension - 1;
+     669             : //       while (true)
+     670             : //       {
+     671             : //         loop_flag[i] += width[i];
+     672             : //         if (loop_flag[i] > upperboundary[i] - width[i] + 0.00001)
+     673             : //         {
+     674             : //           loop_flag[i] = lowerboundary[i];
+     675             : //           i--;
+     676             : //           if (i < 0)
+     677             : //             goto LOOPEND5;
+     678             : //         }
+     679             : //         else
+     680             : //           break;
+     681             : //       }
+     682             : //     }
+     683             : // LOOPEND5:
+     684             : //     ofile_internal.close();
+     685             : //   }
+     686             : 
+     687             :   // write output files
+     688          21 :   void write_files()
+     689             :   {
+     690          21 :     std::string grad_filename = output_filename + ".UI.grad";
+     691          21 :     std::string hist_filename = output_filename + ".UI.hist.grad";
+     692          21 :     std::string count_filename = output_filename + ".UI.count";
+     693             : 
+     694             :     // only for colvars module!
+     695             : //                      if (written) cvm::backup_file(grad_filename.c_str());
+     696             :     //if (written) cvm::backup_file(hist_filename.c_str());
+     697             : //                      if (written) cvm::backup_file(count_filename.c_str());
+     698             : 
+     699          21 :     std::ofstream ofile(grad_filename.c_str());
+     700          21 :     std::ofstream ofile_hist(hist_filename.c_str(), std::ios::app);
+     701          21 :     std::ofstream ofile_count(count_filename.c_str());
+     702             : 
+     703          21 :     writehead(ofile);
+     704          21 :     writehead(ofile_hist);
+     705          21 :     writehead(ofile_count);
+     706             : 
+     707          21 :     if (dimension == 1)
+     708             :     {
+     709           9 :       calc_1D_pmf();
+     710           9 :       write_1D_pmf();
+     711             :     }
+     712             : 
+     713          21 :     std::vector<double> loop_flag(dimension, 0);
+     714          54 :     for (int i = 0; i < dimension; i++)
+     715             :     {
+     716          33 :       loop_flag[i] = lowerboundary[i];
+     717             :     }
+     718             :     while (true)
+     719             :     {
+     720         546 :       for (int i = 0; i < dimension; i++)
+     721             :       {
+     722         343 :         ofile << std::fixed << std::setprecision(6) << loop_flag[i] + 0.5 * width[i] << " ";
+     723         343 :         ofile_hist << std::fixed << std::setprecision(6) << loop_flag[i] + 0.5 * width[i] << " ";
+     724         343 :         ofile_count << std::fixed << std::setprecision(6) << loop_flag[i] + 0.5 * width[i] << " ";
+     725             :       }
+     726             : 
+     727         203 :       if (restart == false)
+     728             :       {
+     729         492 :         for (int i = 0; i < dimension; i++)
+     730             :         {
+     731         614 :           ofile << std::fixed << std::setprecision(6) << grad.get_value(loop_flag)[i] << " ";
+     732         614 :           ofile_hist << std::fixed << std::setprecision(6) << grad.get_value(loop_flag)[i] << " ";
+     733             :         }
+     734             :         ofile << std::endl;
+     735             :         ofile_hist << std::endl;
+     736         185 :         ofile_count << count.get_value(loop_flag) << " " <<std::endl;
+     737             :       }
+     738             :       else
+     739             :       {
+     740             :         double final_grad = 0;
+     741          54 :         for (int i = 0; i < dimension; i++)
+     742             :         {
+     743          36 :           int total_count_temp = (count.get_value(loop_flag) + input_count.get_value(loop_flag));
+     744          36 :           if (input_count.get_value(loop_flag) == 0)
+     745          20 :             final_grad = grad.get_value(loop_flag)[i];
+     746             :           else
+     747          16 :             final_grad = ((grad.get_value(loop_flag)[i] * count.get_value(loop_flag) + input_grad.get_value(loop_flag)[i] * input_count.get_value(loop_flag)) / total_count_temp);
+     748          36 :           ofile << std::fixed << std::setprecision(6) << final_grad << " ";
+     749          36 :           ofile_hist << std::fixed << std::setprecision(6) << final_grad << " ";
+     750             :         }
+     751             :         ofile << std::endl;
+     752             :         ofile_hist << std::endl;
+     753          18 :         ofile_count << (count.get_value(loop_flag) + input_count.get_value(loop_flag)) << " " <<std::endl;
+     754             :       }
+     755             : 
+     756             :       // iterate over any dimensions
+     757         203 :       int i = dimension - 1;
+     758             :       while (true)
+     759             :       {
+     760         243 :         loop_flag[i] += width[i];
+     761         243 :         if (loop_flag[i] > upperboundary[i] - width[i] + 0.00001)
+     762             :         {
+     763          61 :           loop_flag[i] = lowerboundary[i];
+     764          61 :           i--;
+     765             :           ofile << std::endl;
+     766             :           ofile_hist << std::endl;
+     767             :           ofile_count << std::endl;
+     768          61 :           if (i < 0)
+     769          21 :             goto LOOPEND4;
+     770             :         }
+     771             :         else
+     772             :           break;
+     773             :       }
+     774             :     }
+     775             : LOOPEND4:
+     776          21 :     ofile.close();
+     777          21 :     ofile_count.close();
+     778          21 :     ofile_hist.close();
+     779             : 
+     780          21 :     written = true;
+     781          42 :   }
+     782             : 
+     783             :   // read input files
+     784           1 :   void read_inputfiles(const std::vector<std::string>& input_filename)
+     785             :   {
+     786             :     char sharp;
+     787             :     double nothing;
+     788             :     int dimension_temp;
+     789             : 
+     790           1 :     std::vector<double> loop_bin_size(dimension, 0);
+     791           1 :     std::vector<double> position_temp(dimension, 0);
+     792           1 :     std::vector<double> grad_temp(dimension, 0);
+     793           1 :     int count_temp = 0;
+     794           2 :     for (unsigned int i = 0; i < input_filename.size(); i++)
+     795             :     {
+     796           1 :       int size = 1, size_temp = 0;
+     797             : 
+     798           1 :       std::string count_filename = input_filename[i] + ".UI.count";
+     799           1 :       std::string grad_filename = input_filename[i] + ".UI.grad";
+     800             : 
+     801           1 :       std::ifstream count_file(count_filename.c_str(), std::ios::in);
+     802           1 :       std::ifstream grad_file(grad_filename.c_str(), std::ios::in);
+     803             : 
+     804           1 :       count_file >> sharp >> dimension_temp;
+     805           1 :       grad_file >> sharp >> dimension_temp;
+     806             : 
+     807           3 :       for (int j = 0; j < dimension; j++)
+     808             :       {
+     809           4 :         count_file >> sharp >> nothing >> nothing >> size_temp >> nothing;
+     810           2 :         grad_file >> sharp >> nothing >> nothing >> nothing >> nothing;
+     811           2 :         size *= size_temp;
+     812             :       }
+     813             : 
+     814          10 :       for (int j = 0; j < size; j++)
+     815             :       {
+     816             :         do
+     817             :         {
+     818          27 :           for (int k = 0; k < dimension; k++)
+     819             :           {
+     820          18 :             count_file >> position_temp[k];
+     821             :             grad_file >> nothing;
+     822             :           }
+     823             : 
+     824          27 :           for (int l = 0; l < dimension; l++)
+     825             :           {
+     826          18 :             grad_file >> grad_temp[l];
+     827             :           }
+     828           9 :           count_file >> count_temp;
+     829             :         }
+     830           9 :         while (position_temp[i] < lowerboundary[i] - 0.000001 || position_temp[i] > upperboundary[i] + 0.000001);
+     831             : 
+     832           9 :         if (count_temp == 0)
+     833             :         {
+     834           5 :           continue;
+     835             :         }
+     836             : 
+     837          12 :         for (int m = 0; m < dimension; m++)
+     838             :         {
+     839           8 :           grad_temp[m] = (grad_temp[m] * count_temp + input_grad.get_value(position_temp)[m] * input_count.get_value(position_temp)) / (count_temp + input_count.get_value(position_temp));
+     840             :         }
+     841           4 :         input_grad.set_value(position_temp, grad_temp);
+     842           4 :         input_count.increase_value(position_temp, count_temp);
+     843             :       }
+     844             : 
+     845           1 :       count_file.close();
+     846           1 :       grad_file.close();
+     847           1 :     }
+     848           1 :   }
+     849             : };
+     850             : }
+     851             : 
+     852             : }
+     853             : }
+     854             : 
+     855             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/drr/drrtool.cpp.func-sort-c.html b/coverage/drr/drrtool.cpp.func-sort-c.html new file mode 100644 index 000000000000..49a5001fdcb0 --- /dev/null +++ b/coverage/drr/drrtool.cpp.func-sort-c.html @@ -0,0 +1,121 @@ + + + + + + + + LCOV - plumed test coverage - drr/drrtool.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - drr - drrtool.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:687294.4 %
Date:2024-04-19 12:12:35Functions:1212100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3drr7drrtool14calcDivergenceERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_1
_ZN4PLMD3drr7drrtool10extractdrrERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EE2
_ZN4PLMD3drr7drrtool12mergewindowsERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EES8_2
_ZZN4PLMD3drr7drrtool12mergewindowsERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EES8_ENKUlRKS8_E_clESE_2
_ZZN4PLMD3drr7drrtool12mergewindowsERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EES8_ENKUlRKS8_SE_E0_clESE_SE_2
_ZNK4PLMD3drr7drrtool11descriptionB5cxx11Ev4
_ZN4PLMD3drr7drrtool4mainEP8_IO_FILES3_RNS_12CommunicatorE5
_ZN4PLMD3drr12_GLOBAL__N_117drrtoolRegisterMe6createERKNS_13CLToolOptionsE9
_ZN4PLMD3drr7drrtoolC2ERKNS_13CLToolOptionsE9
_ZN4PLMD3drr12_GLOBAL__N_117drrtoolRegisterMeC2Ev5088
_ZN4PLMD3drr12_GLOBAL__N_117drrtoolRegisterMeD2Ev5088
_ZN4PLMD3drr7drrtool16registerKeywordsERNS_8KeywordsE5088
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/drr/drrtool.cpp.func.html b/coverage/drr/drrtool.cpp.func.html new file mode 100644 index 000000000000..1527fadc0369 --- /dev/null +++ b/coverage/drr/drrtool.cpp.func.html @@ -0,0 +1,121 @@ + + + + + + + + LCOV - plumed test coverage - drr/drrtool.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - drr - drrtool.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:687294.4 %
Date:2024-04-19 12:12:35Functions:1212100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3drr12_GLOBAL__N_117drrtoolRegisterMe6createERKNS_13CLToolOptionsE9
_ZN4PLMD3drr12_GLOBAL__N_117drrtoolRegisterMeC2Ev5088
_ZN4PLMD3drr12_GLOBAL__N_117drrtoolRegisterMeD2Ev5088
_ZN4PLMD3drr7drrtool10extractdrrERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EE2
_ZN4PLMD3drr7drrtool12mergewindowsERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EES8_2
_ZN4PLMD3drr7drrtool14calcDivergenceERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_1
_ZN4PLMD3drr7drrtool16registerKeywordsERNS_8KeywordsE5088
_ZN4PLMD3drr7drrtool4mainEP8_IO_FILES3_RNS_12CommunicatorE5
_ZN4PLMD3drr7drrtoolC2ERKNS_13CLToolOptionsE9
_ZNK4PLMD3drr7drrtool11descriptionB5cxx11Ev4
_ZZN4PLMD3drr7drrtool12mergewindowsERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EES8_ENKUlRKS8_E_clESE_2
_ZZN4PLMD3drr7drrtool12mergewindowsERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EES8_ENKUlRKS8_SE_E0_clESE_SE_2
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/drr/drrtool.cpp.gcov.html b/coverage/drr/drrtool.cpp.gcov.html new file mode 100644 index 000000000000..da47bfa17c32 --- /dev/null +++ b/coverage/drr/drrtool.cpp.gcov.html @@ -0,0 +1,345 @@ + + + + + + + + LCOV - plumed test coverage - drr/drrtool.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - drr - drrtool.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:687294.4 %
Date:2024-04-19 12:12:35Functions:1212100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :     Copyright (c) 2017 of Haochuan Chen (excluding colvar_UIestimator.h)
+       3             :     Copyright (c) 2017 of Haohao Fu (colvar_UIestimator.h)
+       4             : 
+       5             :     This program is free software: you can redistribute it and/or modify
+       6             :     it under the terms of the GNU Lesser General Public License as published
+       7             :     by the Free Software Foundation, either version 3 of the License, or
+       8             :     (at your option) any later version.
+       9             : 
+      10             :     This program is distributed in the hope that it will be useful,
+      11             :     but WITHOUT ANY WARRANTY; without even the implied warranty of
+      12             :     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      13             :     GNU Lesser General Public License for more details.
+      14             : 
+      15             :     You should have received a copy of the GNU Lesser General Public License
+      16             :     along with this program.  If not, see <http://www.gnu.org/licenses/>.
+      17             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      18             : #ifdef __PLUMED_HAS_BOOST_SERIALIZATION
+      19             : #include "cltools/CLTool.h"
+      20             : #include "core/CLToolRegister.h"
+      21             : #include "config/Config.h"
+      22             : #include "core/ActionRegister.h"
+      23             : #include "DRR.h"
+      24             : #include "tools/Tools.h"
+      25             : #include "tools/Units.h"
+      26             : #include <boost/archive/binary_iarchive.hpp>
+      27             : #include <boost/archive/binary_oarchive.hpp>
+      28             : #include <boost/serialization/vector.hpp>
+      29             : #include <cstdlib>
+      30             : #include <fstream>
+      31             : #include <iostream>
+      32             : #include <string>
+      33             : 
+      34             : using namespace PLMD;
+      35             : using namespace cltools;
+      36             : 
+      37             : namespace PLMD {
+      38             : namespace drr {
+      39             : 
+      40             : //+PLUMEDOC EABFMOD_TOOLS drr_tool
+      41             : /*
+      42             :  - Extract .grad and .count files from the binary output .drrstate
+      43             :  - Merge windows
+      44             : 
+      45             : \par Examples
+      46             : 
+      47             : The following command will extract .grad and .count files.
+      48             : \verbatim
+      49             : plumed drr_tool --extract eabf.drrstate
+      50             : \endverbatim
+      51             : 
+      52             : The following command will merge windows of two .drrstate file, and output the
+      53             : .grad and .count files.
+      54             : \verbatim
+      55             : plumed drr_tool --merge win1.drrstate,win2.drrstate
+      56             : \endverbatim
+      57             : 
+      58             : After getting the .grad and .count file, you can do numerical integration by
+      59             : using abf_integrate tool from
+      60             : https://github.com/Colvars/colvars/tree/master/colvartools
+      61             : \verbatim
+      62             : abf_integrate eabf.czar.grad
+      63             : \endverbatim
+      64             : \note
+      65             : The abf_integrate in colvartools is in kcal/mol, so it may be better to use --units kcal/mol when running drr_tool
+      66             : 
+      67             : */
+      68             : //+ENDPLUMEDOC
+      69             : 
+      70             : using std::vector;
+      71             : using std::string;
+      72             : 
+      73             : class drrtool : public CLTool {
+      74             : public:
+      75             :   static void registerKeywords(Keywords &keys);
+      76             :   explicit drrtool(const CLToolOptions &co);
+      77             :   int main(FILE *in, FILE *out, Communicator &pc);
+      78             :   void extractdrr(const vector<string> &filename);
+      79             :   void mergewindows(const vector<string> &filename, string outputname);
+      80             :   void calcDivergence(const vector<string> &filename, const string &fmt);
+      81           4 :   string description() const { return "Extract or merge the drrstate files."; }
+      82             : 
+      83             : private:
+      84             :   bool verbosity;
+      85             :   Units units;
+      86             :   const string suffix{".drrstate"};
+      87             : };
+      88             : 
+      89       15273 : PLUMED_REGISTER_CLTOOL(drrtool, "drr_tool")
+      90             : 
+      91        5088 : void drrtool::registerKeywords(Keywords &keys) {
+      92        5088 :   CLTool::registerKeywords(keys);
+      93       10176 :   keys.add("optional", "--extract", "Extract drrstate file(s)");
+      94       10176 :   keys.add("optional", "--merge", "Merge eABF windows");
+      95       10176 :   keys.add("optional", "--merge_output", "The output filename of the merged result");
+      96       10176 :   keys.add("optional", "--divergence", "Calculate divergence of gradient field (experimental)");
+      97       10176 :   keys.add("optional","--dump-fmt","( default=%%f ) the format to use to dump the output");
+      98       10176 :   keys.add("compulsory","--units","kj/mol","the units of energy can be kj/mol, kcal/mol, j/mol, eV or the conversion factor from kj/mol");
+      99       10176 :   keys.addFlag("-v", false, "Verbose output");
+     100        5088 : }
+     101             : 
+     102           9 : drrtool::drrtool(const CLToolOptions &co) : CLTool(co) {
+     103           9 :   inputdata = commandline;
+     104           9 :   verbosity = false;
+     105           9 : }
+     106             : 
+     107           5 : int drrtool::main(FILE *in, FILE *out, Communicator &pc) {
+     108          10 :   parseFlag("-v", verbosity);
+     109             :   vector<string> stateFilesToExtract;
+     110             :   string unitname;
+     111           5 :   parse("--units",unitname);
+     112           5 :   units.setEnergy( unitname );
+     113           5 :   std::string dumpFmt("%.9f");;
+     114           5 :   parse("--dump-fmt", dumpFmt);
+     115           5 :   bool doextract = parseVector("--extract", stateFilesToExtract);
+     116           5 :   if (doextract) {
+     117           2 :     extractdrr(stateFilesToExtract);
+     118             :   }
+     119             :   vector<string> stateFilesToMerge;
+     120           5 :   bool domerge = parseVector("--merge", stateFilesToMerge);
+     121           5 :   if (domerge) {
+     122             :     string merge_outputname;
+     123           2 :     parse("--merge_output", merge_outputname);
+     124           4 :     mergewindows(stateFilesToMerge, merge_outputname);
+     125             :   }
+     126             :   vector<string> stateFilesToDivergence;
+     127           5 :   bool dodivergence = parseVector("--divergence", stateFilesToDivergence);
+     128           5 :   if (dodivergence) {
+     129           1 :     calcDivergence(stateFilesToDivergence, dumpFmt);
+     130             :   }
+     131           5 :   return 0;
+     132          10 : }
+     133             : 
+     134           2 : void drrtool::extractdrr(const vector<string> &filename) {
+     135           2 :   #pragma omp parallel for
+     136             :   for (size_t j = 0; j < filename.size(); ++j) {
+     137             :     std::ifstream in;
+     138             :     in.open(filename[j]);
+     139             :     boost::archive::binary_iarchive ia(in);
+     140             :     long long int step;
+     141             :     vector<double> fict;
+     142             :     vector<double> vfict;
+     143             :     vector<double> vfict_laststep;
+     144             :     vector<double> ffict;
+     145             :     ABF abfgrid;
+     146             :     CZAR czarestimator;
+     147             :     ia >> step >> fict >> vfict >> vfict_laststep >> ffict >> abfgrid >>
+     148             :        czarestimator;
+     149             :     in.close();
+     150             :     abfgrid.setOutputUnit(units.getEnergy());
+     151             :     czarestimator.setOutputUnit(units.getEnergy());
+     152             :     if (verbosity) {
+     153             :       std::cout << "Output units factor: " << units.getEnergy() << '\n';
+     154             :       std::cout << "Dumping information of extended variables..." << '\n';
+     155             :       std::cout << "Step: " << step << '\n';
+     156             :       for (size_t i = 0; i < fict.size(); ++i) {
+     157             :         std::cout << "Dimension[" << i + 1 << "]:\n"
+     158             :                   << "  Coordinate: " << fict[i] << '\n'
+     159             :                   << "  Velocity: " << vfict[i] << '\n'
+     160             :                   << "  Velocity(laststep): " << vfict_laststep[i] << '\n'
+     161             :                   << "  Force: " << ffict[i] << '\n';
+     162             :       }
+     163             :       std::cout << "Dumping counts and gradients from grids..." << '\n';
+     164             :     }
+     165             :     string outputname(filename[j]);
+     166             :     outputname.resize(outputname.length() - suffix.length());
+     167             :     if (verbosity)
+     168             :       std::cout << "Writing ABF(naive) estimator files..." << '\n';
+     169             :     abfgrid.writeAll(outputname);
+     170             :     if (verbosity)
+     171             :       std::cout << "Writing CZAR estimator files..." << '\n';
+     172             :     czarestimator.writeAll(outputname);
+     173             :     czarestimator.writeZCountZGrad(outputname);
+     174             :   }
+     175           2 : }
+     176             : 
+     177           2 : void drrtool::mergewindows(const vector<string> &filename, string outputname) {
+     178           2 :   if (filename.size() < 2) {
+     179           0 :     std::cerr << "ERROR! You need at least two .drrstate file to merge windows!" << std::endl;
+     180           0 :     std::abort();
+     181             :   }
+     182             :   // Read grid into abfs and czars;
+     183             :   vector<ABF> abfs;
+     184             :   vector<CZAR> czars;
+     185           6 :   for (auto it_fn = filename.begin(); it_fn != filename.end(); ++it_fn) {
+     186           4 :     std::ifstream in;
+     187           4 :     in.open((*it_fn));
+     188           4 :     boost::archive::binary_iarchive ia(in);
+     189             :     long long int step;
+     190             :     vector<double> fict;
+     191             :     vector<double> vfict;
+     192             :     vector<double> vfict_laststep;
+     193             :     vector<double> ffict;
+     194             :     ABF abfgrid;
+     195             :     CZAR czarestimator;
+     196             :     ia >> step >> fict >> vfict >> vfict_laststep >> ffict >> abfgrid >>
+     197             :        czarestimator;
+     198           4 :     abfgrid.setOutputUnit(units.getEnergy());
+     199             :     czarestimator.setOutputUnit(units.getEnergy());
+     200           4 :     abfs.push_back(abfgrid);
+     201           4 :     czars.push_back(czarestimator);
+     202           4 :     in.close();
+     203           8 :   }
+     204           2 :   CZAR cmerged = CZAR::mergewindow(czars[0], czars[1]);
+     205           2 :   ABF amerged = ABF::mergewindow(abfs[0], abfs[1]);
+     206           2 :   for (size_t i = 2; i < czars.size(); ++i) {
+     207           0 :     cmerged = CZAR::mergewindow(cmerged, czars[i]);
+     208           0 :     amerged = ABF::mergewindow(amerged, abfs[i]);
+     209             :   }
+     210           2 :   if (outputname.empty()) {
+     211             :     // Generate new file name for merged grad and count
+     212           1 :     vector<string> tmp_name = filename;
+     213           1 :     std::transform(std::begin(tmp_name), std::end(tmp_name), std::begin(tmp_name),
+     214           2 :     [&](const string & s) {return s.substr(0, s.find(suffix));});
+     215           2 :     outputname = std::accumulate(std::begin(tmp_name), std::end(tmp_name), string(""),
+     216           5 :     [](const string & a, const string & b) {return a + b + "+";});
+     217           1 :     outputname.resize(outputname.size() - 1);
+     218             :     std::cerr << "You have not specified an output filename for the merged"
+     219           1 :               << " result, so the default name \"" + outputname
+     220           2 :               << "\" is used here, which may yield unexpected behavior.\n";
+     221           1 :   }
+     222           2 :   cmerged.writeAll(outputname);
+     223           2 :   cmerged.writeZCountZGrad(outputname);
+     224           2 :   amerged.writeAll(outputname);
+     225           4 : }
+     226             : 
+     227           1 : void drrtool::calcDivergence(const vector<string> &filename, const string &dumpFmt) {
+     228           1 :   #pragma omp parallel for
+     229             :   for (size_t j = 0; j < filename.size(); ++j) {
+     230             :     std::ifstream in;
+     231             :     in.open(filename[j]);
+     232             :     boost::archive::binary_iarchive ia(in);
+     233             :     long long int step;
+     234             :     vector<double> fict;
+     235             :     vector<double> vfict;
+     236             :     vector<double> vfict_laststep;
+     237             :     vector<double> ffict;
+     238             :     ABF abfgrid;
+     239             :     CZAR czarestimator;
+     240             :     ia >> step >> fict >> vfict >> vfict_laststep >> ffict >> abfgrid >>
+     241             :        czarestimator;
+     242             :     in.close();
+     243             :     abfgrid.setOutputUnit(units.getEnergy());
+     244             :     czarestimator.setOutputUnit(units.getEnergy());
+     245             :     if (verbosity) {
+     246             :       std::cout << "Output units factor: " << units.getEnergy() << '\n';
+     247             :       std::cout << "Dumping information of extended variables..." << '\n';
+     248             :       std::cout << "Step: " << step << '\n';
+     249             :       for (size_t i = 0; i < fict.size(); ++i) {
+     250             :         std::cout << "Dimension[" << i + 1 << "]:\n"
+     251             :                   << "  Coordinate: " << fict[i] << '\n'
+     252             :                   << "  Velocity: " << vfict[i] << '\n'
+     253             :                   << "  Velocity(laststep): " << vfict_laststep[i] << '\n'
+     254             :                   << "  Force: " << ffict[i] << '\n';
+     255             :       }
+     256             :       std::cout << "Dumping counts and gradients from grids..." << '\n';
+     257             :     }
+     258             :     string outputname(filename[j]);
+     259             :     outputname.resize(outputname.length() - suffix.length());
+     260             :     abfgrid.writeDivergence(outputname, dumpFmt);
+     261             :     czarestimator.writeDivergence(outputname, dumpFmt);
+     262             :   }
+     263           1 : }
+     264             : 
+     265             : } // End of namespace
+     266             : }
+     267             : 
+     268             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/drr/index-sort-f.html b/coverage/drr/index-sort-f.html new file mode 100644 index 000000000000..af01e01d8951 --- /dev/null +++ b/coverage/drr/index-sort-f.html @@ -0,0 +1,134 @@ + + + + + + + + LCOV - plumed test coverage - drr + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - drrHitTotalCoverage
Test:plumed test coverageLines:1201127194.5 %
Date:2024-04-19 12:12:35Functions:899494.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
DRR.h +
100.0%
+
100.0 %99 / 9978.6 %11 / 14
DynamicReferenceRestraining.cpp +
91.2%91.2%
+
91.2 %404 / 44388.9 %8 / 9
DRR.cpp +
93.2%93.2%
+
93.2 %331 / 35596.0 %24 / 25
drrtool.cpp +
94.4%94.4%
+
94.4 %68 / 72100.0 %12 / 12
colvar_UIestimator.h +
99.0%99.0%
+
99.0 %299 / 302100.0 %34 / 34
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/drr/index-sort-l.html b/coverage/drr/index-sort-l.html new file mode 100644 index 000000000000..a82328ddd5b6 --- /dev/null +++ b/coverage/drr/index-sort-l.html @@ -0,0 +1,134 @@ + + + + + + + + LCOV - plumed test coverage - drr + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - drrHitTotalCoverage
Test:plumed test coverageLines:1201127194.5 %
Date:2024-04-19 12:12:35Functions:899494.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
DynamicReferenceRestraining.cpp +
91.2%91.2%
+
91.2 %404 / 44388.9 %8 / 9
DRR.cpp +
93.2%93.2%
+
93.2 %331 / 35596.0 %24 / 25
drrtool.cpp +
94.4%94.4%
+
94.4 %68 / 72100.0 %12 / 12
colvar_UIestimator.h +
99.0%99.0%
+
99.0 %299 / 302100.0 %34 / 34
DRR.h +
100.0%
+
100.0 %99 / 9978.6 %11 / 14
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/drr/index.html b/coverage/drr/index.html new file mode 100644 index 000000000000..d551483b57ec --- /dev/null +++ b/coverage/drr/index.html @@ -0,0 +1,134 @@ + + + + + + + + LCOV - plumed test coverage - drr + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - drrHitTotalCoverage
Test:plumed test coverageLines:1201127194.5 %
Date:2024-04-19 12:12:35Functions:899494.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
DRR.cpp +
93.2%93.2%
+
93.2 %331 / 35596.0 %24 / 25
DRR.h +
100.0%
+
100.0 %99 / 9978.6 %11 / 14
DynamicReferenceRestraining.cpp +
91.2%91.2%
+
91.2 %404 / 44388.9 %8 / 9
colvar_UIestimator.h +
99.0%99.0%
+
99.0 %299 / 302100.0 %34 / 34
drrtool.cpp +
94.4%94.4%
+
94.4 %68 / 72100.0 %12 / 12
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/eds/EDS.cpp.func-sort-c.html b/coverage/eds/EDS.cpp.func-sort-c.html new file mode 100644 index 000000000000..b0809459b1de --- /dev/null +++ b/coverage/eds/EDS.cpp.func-sort-c.html @@ -0,0 +1,153 @@ + + + + + + + + LCOV - plumed test coverage - eds/EDS.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - eds - EDS.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:45148692.8 %
Date:2024-04-19 12:12:35Functions:172085.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3eds3EDS17turnOnDerivativesEv0
_ZN4PLMD3eds3EDSC2ERKNS_13ActionOptionsE0
_ZN4PLMD3eds3EDSD2Ev0
_ZN4PLMD3eds3EDS17calc_lm_step_sizeEv1
_ZN4PLMD3eds3EDS20calc_covar_step_sizeEv1
_ZN4PLMD3eds3EDS13readInRestartEb2
_ZN4PLMD3eds3EDS20update_pseudo_virialEv2
_ZN4PLMD3eds3EDS18calc_ssd_step_sizeEv6
_ZN4PLMD3eds3EDS11update_biasEv8
_ZN4PLMD3eds3EDS15setupOutRestartEv8
_ZN4PLMD3eds3EDS16reset_statisticsEv8
_ZN4PLMD3eds3EDSC1ERKNS_13ActionOptionsE8
_ZN4PLMD3eds3EDSD0Ev8
_ZN4PLMD3eds3EDSD1Ev8
_ZN4PLMD3eds3EDS16registerKeywordsERNS_8KeywordsE10
_ZN4PLMD3eds3EDS17update_statisticsEv12
_ZN4PLMD3eds3EDS15writeOutRestartEv27
_ZN4PLMD3eds3EDS10apply_biasEv40
_ZN4PLMD3eds3EDS6updateEv40
_ZN4PLMD3eds3EDS9calculateEv40
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/eds/EDS.cpp.func.html b/coverage/eds/EDS.cpp.func.html new file mode 100644 index 000000000000..2db572ee5e81 --- /dev/null +++ b/coverage/eds/EDS.cpp.func.html @@ -0,0 +1,153 @@ + + + + + + + + LCOV - plumed test coverage - eds/EDS.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - eds - EDS.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:45148692.8 %
Date:2024-04-19 12:12:35Functions:172085.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3eds3EDS10apply_biasEv40
_ZN4PLMD3eds3EDS11update_biasEv8
_ZN4PLMD3eds3EDS13readInRestartEb2
_ZN4PLMD3eds3EDS15setupOutRestartEv8
_ZN4PLMD3eds3EDS15writeOutRestartEv27
_ZN4PLMD3eds3EDS16registerKeywordsERNS_8KeywordsE10
_ZN4PLMD3eds3EDS16reset_statisticsEv8
_ZN4PLMD3eds3EDS17calc_lm_step_sizeEv1
_ZN4PLMD3eds3EDS17turnOnDerivativesEv0
_ZN4PLMD3eds3EDS17update_statisticsEv12
_ZN4PLMD3eds3EDS18calc_ssd_step_sizeEv6
_ZN4PLMD3eds3EDS20calc_covar_step_sizeEv1
_ZN4PLMD3eds3EDS20update_pseudo_virialEv2
_ZN4PLMD3eds3EDS6updateEv40
_ZN4PLMD3eds3EDS9calculateEv40
_ZN4PLMD3eds3EDSC1ERKNS_13ActionOptionsE8
_ZN4PLMD3eds3EDSC2ERKNS_13ActionOptionsE0
_ZN4PLMD3eds3EDSD0Ev8
_ZN4PLMD3eds3EDSD1Ev8
_ZN4PLMD3eds3EDSD2Ev0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/eds/EDS.cpp.gcov.html b/coverage/eds/EDS.cpp.gcov.html new file mode 100644 index 000000000000..83f211cd2017 --- /dev/null +++ b/coverage/eds/EDS.cpp.gcov.html @@ -0,0 +1,1251 @@ + + + + + + + + LCOV - plumed test coverage - eds/EDS.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - eds - EDS.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:45148692.8 %
Date:2024-04-19 12:12:35Functions:172085.0 %
+
+ + + + + + + + +

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

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
EDS.cpp +
92.8%92.8%
+
92.8 %451 / 48685.0 %17 / 20
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/eds/index-sort-l.html b/coverage/eds/index-sort-l.html new file mode 100644 index 000000000000..2edda57cf4f4 --- /dev/null +++ b/coverage/eds/index-sort-l.html @@ -0,0 +1,94 @@ + + + + + + + + LCOV - plumed test coverage - eds + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - edsHitTotalCoverage
Test:plumed test coverageLines:45148692.8 %
Date:2024-04-19 12:12:35Functions:172085.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
EDS.cpp +
92.8%92.8%
+
92.8 %451 / 48685.0 %17 / 20
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/eds/index.html b/coverage/eds/index.html new file mode 100644 index 000000000000..616f8daaa1a5 --- /dev/null +++ b/coverage/eds/index.html @@ -0,0 +1,94 @@ + + + + + + + + LCOV - plumed test coverage - eds + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - edsHitTotalCoverage
Test:plumed test coverageLines:45148692.8 %
Date:2024-04-19 12:12:35Functions:172085.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
EDS.cpp +
92.8%92.8%
+
92.8 %451 / 48685.0 %17 / 20
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/emerald.png b/coverage/emerald.png new file mode 100644 index 0000000000000000000000000000000000000000..38ad4f4068b935643d2486f323005fb294a9bd7e GIT binary patch literal 141 zcmeAS@N?(olHy`uVBq!ia0vp^j3CU&3?x-=hn)ga>?NMQuI!iC1^Jb!lvI6;R0X`wF(yt=9xVZRt1vCRixIA4P dLn>}1Cji+@42)0J?}79&c)I$ztaD0e0sy@GAL0N2 literal 0 HcmV?d00001 diff --git a/coverage/envsim/EnvironmentSimilarity.cpp.func-sort-c.html b/coverage/envsim/EnvironmentSimilarity.cpp.func-sort-c.html new file mode 100644 index 000000000000..d1179dc19e82 --- /dev/null +++ b/coverage/envsim/EnvironmentSimilarity.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - envsim/EnvironmentSimilarity.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - envsim - EnvironmentSimilarity.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:18419494.8 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6envsim21EnvironmentSimilarityC2ERKNS_13ActionOptionsE0
_ZN4PLMD6envsim21EnvironmentSimilarityC1ERKNS_13ActionOptionsE10
_ZN4PLMD6envsim21EnvironmentSimilarity23getReferenceEnvironmentERKNS_3PDBERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISB_EERd14
_ZN4PLMD6envsim21EnvironmentSimilarity16registerKeywordsERNS_8KeywordsE28
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/envsim/EnvironmentSimilarity.cpp.func.html b/coverage/envsim/EnvironmentSimilarity.cpp.func.html new file mode 100644 index 000000000000..4ff91df8ccdb --- /dev/null +++ b/coverage/envsim/EnvironmentSimilarity.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - envsim/EnvironmentSimilarity.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - envsim - EnvironmentSimilarity.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:18419494.8 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6envsim21EnvironmentSimilarity16registerKeywordsERNS_8KeywordsE28
_ZN4PLMD6envsim21EnvironmentSimilarity23getReferenceEnvironmentERKNS_3PDBERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISB_EERd14
_ZN4PLMD6envsim21EnvironmentSimilarityC1ERKNS_13ActionOptionsE10
_ZN4PLMD6envsim21EnvironmentSimilarityC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/envsim/EnvironmentSimilarity.cpp.gcov.html b/coverage/envsim/EnvironmentSimilarity.cpp.gcov.html new file mode 100644 index 000000000000..f2ea24fbe66b --- /dev/null +++ b/coverage/envsim/EnvironmentSimilarity.cpp.gcov.html @@ -0,0 +1,524 @@ + + + + + + + + LCOV - plumed test coverage - envsim/EnvironmentSimilarity.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - envsim - EnvironmentSimilarity.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:18419494.8 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) envsim 2023-2024 The code team
+       3             :    (see the PEOPLE-envsim file at the root of the distribution for a list of names)
+       4             : 
+       5             :    This file is part of envsim code module.
+       6             : 
+       7             :    The envsim code module is free software: you can redistribute it and/or modify
+       8             :    it under the terms of the GNU Lesser General Public License as published by
+       9             :    the Free Software Foundation, either version 3 of the License, or
+      10             :    (at your option) any later version.
+      11             : 
+      12             :    The envsim code module is distributed in the hope that it will be useful,
+      13             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      14             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      15             :    GNU Lesser General Public License for more details.
+      16             : 
+      17             :    You should have received a copy of the GNU Lesser General Public License
+      18             :    along with the envsim code module.  If not, see <http://www.gnu.org/licenses/>.
+      19             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      20             : #include "core/ActionShortcut.h"
+      21             : #include "core/ActionRegister.h"
+      22             : #include "core/ActionWithValue.h"
+      23             : #include "core/PlumedMain.h"
+      24             : #include "core/ActionSet.h"
+      25             : #include "tools/PDB.h"
+      26             : #include "multicolvar/MultiColvarShortcuts.h"
+      27             : #include <string>
+      28             : #include <cmath>
+      29             : 
+      30             : using namespace std;
+      31             : 
+      32             : namespace PLMD {
+      33             : namespace envsim {
+      34             : 
+      35             : //+PLUMEDOC MCOLVAR ENVIRONMENTSIMILARITY
+      36             : /*
+      37             : Measure how similar the environment around atoms is to that found in some reference crystal structure.
+      38             : 
+      39             : This CV was introduced in this article \cite Piaggi-JCP-2019.
+      40             : The starting point for the definition of the CV is the local atomic density around an atom.
+      41             : We consider an environment \f$\chi\f$ around this atom and we define the density by
+      42             : \f[
+      43             :  \rho_{\chi}(\mathbf{r})=\sum\limits_{i\in\chi} \exp\left(- \frac{|\mathbf{r}_i-\mathbf{r}|^2} {2\sigma^2} \right),
+      44             : \f]
+      45             : 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
+      46             : coordinates of the neighbors relative to the central atom.
+      47             : 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$
+      48             : that describe, for instance, the nearest neighbors in a given lattice.
+      49             : \f$\sigma\f$ is set using the SIGMA keyword and \f$\chi_0\f$ is chosen with the CRYSTAL_STRUCTURE keyword.
+      50             : If only the SPECIES keyword is given then the atoms defined there will be the central and neighboring atoms.
+      51             : If instead the SPECIESA and SPECIESB keywords are given then SPECIESA determines the central atoms and SPECIESB the neighbors.
+      52             : 
+      53             : The environments \f$\chi\f$ and \f$\chi_0\f$ are compared using the kernel,
+      54             : \f[
+      55             :  k_{\chi_0}(\chi)= \int d\mathbf{r} \rho_{\chi}(\mathbf{r}) \rho_{\chi_0}(\mathbf{r}) .
+      56             : \f]
+      57             : Combining the two equations above and performing the integration analytically we obtain,
+      58             : \f[
+      59             :  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).
+      60             : \f]
+      61             : The kernel is finally normalized,
+      62             : \f[
+      63             :  \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),
+      64             : \f]
+      65             : such that \f$\tilde{k}_{\chi_0}(\chi_0) = 1\f$.
+      66             : The above kernel is computed for each atom in the SPECIES or SPECIESA keywords.
+      67             : This quantity is a multicolvar so you can compute it for multiple atoms using a single PLUMED action and then compute
+      68             : 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
+      69             : so on.
+      70             : 
+      71             : The kernel can be generalized to crystal structures described as a lattice with a basis of more than one atom.
+      72             : In this case there is more than one type of environment.
+      73             : 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:
+      74             : \f[
+      75             :  \tilde{k}_X(\chi)= \frac{1}{\lambda} \log \left ( \sum\limits_{l=1}^{M}\exp \left (\lambda \: \tilde{k}_{\chi_l}(\chi) \right ) \right ).
+      76             : \f]
+      77             : 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$.
+      78             : This approach can be used, for instance, to target the hexagonal closed packed (HCP keyword) or the diamond structure (DIAMOND keyword).
+      79             : 
+      80             : The CRYSTAL_STRUCTURE keyword can take the values SC (simple cubic), BCC (body centered cubic), FCC (face centered cubic),
+      81             : HCP (hexagonal closed pack), DIAMOND (cubic diamond), and CUSTOM (user defined).
+      82             : All options follow the same conventions as in the [lattice command](https://lammps.sandia.gov/doc/lattice.html) of [LAMMPS](https://lammps.sandia.gov/).
+      83             : If a CRYSTAL_STRUCTURE other than CUSTOM is used, then the lattice constants have to be specified using the keyword LATTICE_CONSTANTS.
+      84             : 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).
+      85             : 
+      86             : If the CUSTOM option is used then the reference environments have to be specified by the user.
+      87             : The reference environments are specified in pdb files containing the distance vectors from the central atom to the neighbors.
+      88             : Make sure your PDB file is correctly formatted as explained \ref pdbreader "in this page"
+      89             : If only one reference environment is specified then the filename should be given as argument of the keyword REFERENCE.
+      90             : If instead several reference environments are given, then they have to be provided in separate pdb files and given as arguments of the
+      91             : keywords REFERENCE_1, REFERENCE_2, etc.
+      92             : 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.
+      93             : 
+      94             : 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.
+      95             : This information is provided in pdb files using the atom name field.
+      96             : The comparison between environments is performed taking into account whether the atom names match.
+      97             : 
+      98             : \par Examples
+      99             : 
+     100             : The following input calculates the ENVIRONMENTSIMILARITY kernel for 250 atoms in the system
+     101             : using the BCC atomic environment as target, and then calculates and prints the average value
+     102             :  for this quantity.
+     103             : 
+     104             : \plumedfile
+     105             : ENVIRONMENTSIMILARITY SPECIES=1-250 SIGMA=0.05 LATTICE_CONSTANTS=0.423 CRYSTAL_STRUCTURE=BCC MEAN LABEL=es
+     106             : 
+     107             : PRINT ARG=es.mean FILE=COLVAR
+     108             : \endplumedfile
+     109             : 
+     110             : The next example compares the environments of the 96 selected atoms with a user specified reference
+     111             : environment. The reference environment is contained in the env1.pdb file. Once the kernel is computed
+     112             :  the average and the number of atoms with a kernel larger than 0.5 are computed.
+     113             : 
+     114             : \plumedfile
+     115             : ENVIRONMENTSIMILARITY ...
+     116             :  SPECIES=1-288:3
+     117             :  SIGMA=0.05
+     118             :  CRYSTAL_STRUCTURE=CUSTOM
+     119             :  REFERENCE=env1.pdb
+     120             :  LABEL=es
+     121             :  MEAN
+     122             :  MORE_THAN={RATIONAL R_0=0.5 NN=12 MM=24}
+     123             : ... ENVIRONMENTSIMILARITY
+     124             : 
+     125             : PRINT ARG=es.mean,es.morethan FILE=COLVAR
+     126             : \endplumedfile
+     127             : 
+     128             : The next example is similar to the one above but in this case 4 reference environments are specified.
+     129             :  Each reference environment is given in a separate pdb file.
+     130             : 
+     131             : \plumedfile
+     132             : ENVIRONMENTSIMILARITY ...
+     133             :  SPECIES=1-288:3
+     134             :  SIGMA=0.05
+     135             :  CRYSTAL_STRUCTURE=CUSTOM
+     136             :  REFERENCE_1=env1.pdb
+     137             :  REFERENCE_2=env2.pdb
+     138             :  REFERENCE_3=env3.pdb
+     139             :  REFERENCE_4=env4.pdb
+     140             :  LABEL=es
+     141             :  MEAN
+     142             :  MORE_THAN={RATIONAL R_0=0.5 NN=12 MM=24}
+     143             : ... ENVIRONMENTSIMILARITY
+     144             : 
+     145             : PRINT ARG=es.mean,es.morethan FILE=COLVAR
+     146             : \endplumedfile
+     147             : 
+     148             : The following examples illustrates the use of pdb files to provide information about different chemical species:
+     149             : \plumedfile
+     150             : ENVIRONMENTSIMILARITY ...
+     151             :  SPECIES=1-6
+     152             :  SIGMA=0.05
+     153             :  CRYSTAL_STRUCTURE=CUSTOM
+     154             :  REFERENCE=env.pdb
+     155             :  LABEL=es
+     156             :  MEAN
+     157             :  MORE_THAN={RATIONAL R_0=0.5 NN=12 MM=24}
+     158             :  ATOM_NAMES_FILE=atom-names.pdb
+     159             : ... ENVIRONMENTSIMILARITY
+     160             : \endplumedfile
+     161             : Here the file env.pdb is:
+     162             : \verbatim
+     163             : ATOM      1    O MOL     1      -2.239  -1.296  -0.917  1.00  0.00           O
+     164             : ATOM      2    O MOL     1       0.000   0.000   2.751  1.00  0.00           O
+     165             : \endverbatim
+     166             : where atoms are of type O, and the atom-names.pdb file is:
+     167             : \verbatim
+     168             : ATOM      1  O       X   1       0.000   2.593   4.126  0.00  0.00           O
+     169             : ATOM      2  H       X   1       0.000   3.509   3.847  0.00  0.00           H
+     170             : ATOM      3  H       X   1       0.000   2.635   5.083  0.00  0.00           H
+     171             : ATOM      4  O       X   1       0.000   2.593  11.462  0.00  0.00           O
+     172             : ATOM      5  H       X   1       0.000   3.509  11.183  0.00  0.00           H
+     173             : ATOM      6  H       X   1       0.000   2.635  12.419  0.00  0.00           H
+     174             : \endverbatim
+     175             : where atoms are of type O and H.
+     176             : In this case, all atoms are used as centers, but only neighbors of type O are taken into account.
+     177             : 
+     178             : */
+     179             : //+ENDPLUMEDOC
+     180             : 
+     181             : class EnvironmentSimilarity : public ActionShortcut {
+     182             : private:
+     183             :   std::vector<std::pair<unsigned,Vector> > getReferenceEnvironment( const PDB& pdb, const std::vector<std::string>& anames, double& maxdist );
+     184             : public:
+     185             :   static void registerKeywords( Keywords& keys );
+     186             :   explicit EnvironmentSimilarity(const ActionOptions&);
+     187             : };
+     188             : 
+     189             : PLUMED_REGISTER_ACTION(EnvironmentSimilarity,"ENVIRONMENTSIMILARITY")
+     190             : 
+     191          28 : void EnvironmentSimilarity::registerKeywords( Keywords& keys ) {
+     192          28 :   ActionShortcut::registerKeywords( keys );
+     193          56 :   keys.add("atoms-3","SPECIES","this keyword is used for colvars such as coordination number. In that context it specifies that plumed should calculate "
+     194             :            "one coordination number for each of the atoms specified.  Each of these coordination numbers specifies how many of the "
+     195             :            "other specified atoms are within a certain cutoff of the central atom.  You can specify the atoms here as another multicolvar "
+     196             :            "action or using a MultiColvarFilter or ActionVolume action.  When you do so the quantity is calculated for those atoms specified "
+     197             :            "in the previous multicolvar.  This is useful if you would like to calculate the Steinhardt parameter for those atoms that have a "
+     198             :            "coordination number more than four for example");
+     199          56 :   keys.add("atoms-4","SPECIESA","this keyword is used for colvars such as the coordination number.  In that context it species that plumed should calculate "
+     200             :            "one coordination number for each of the atoms specified in SPECIESA.  Each of these cooordination numbers specifies how many "
+     201             :            "of the atoms specifies using SPECIESB is within the specified cutoff.  As with the species keyword the input can also be specified "
+     202             :            "using the label of another multicolvar");
+     203          56 :   keys.add("atoms-4","SPECIESB","this keyword is used for colvars such as the coordination number.  It must appear with SPECIESA.  For a full explanation see "
+     204             :            "the documentation for that keyword");
+     205          56 :   keys.add("compulsory","CRYSTAL_STRUCTURE","FCC","Targeted crystal structure. Options are: "
+     206             :            "SC: simple cubic, "
+     207             :            "BCC: body center cubic, "
+     208             :            "FCC: face centered cubic, "
+     209             :            "HCP: hexagonal closed pack, "
+     210             :            "DIAMOND: cubic diamond, "
+     211             :            "CUSTOM: user defined "
+     212             :            " ");
+     213          56 :   keys.add("compulsory","LATTICE_CONSTANTS","Lattice constants. Two comma separated values for HCP, "
+     214             :            "one value for all other CRYSTAL_STRUCTURES.");
+     215          56 :   keys.add("compulsory","SIGMA","0.1","the width to use for the gaussian kernels");
+     216          56 :   keys.add("compulsory","LCUTOFF","0.0001","any atoms separated by less than this tolerance should be ignored");
+     217          56 :   keys.add("optional","REFERENCE","PDB files with relative distances from central atom.  Use this keyword if you are targeting a single reference environment.");
+     218          56 :   keys.add("numbered","REFERENCE_","PDB files with relative distances from central atom. Each file corresponds to one template. Use these keywords if you are targeting more than one reference environment.");
+     219          56 :   keys.add("compulsory","LAMBDA","100","Lambda parameter.  This is only used if you have more than one reference environment");
+     220          56 :   keys.add("compulsory","CUTOFF","3","how many multiples of sigma would you like to consider beyond the maximum distance in the environment");
+     221          56 :   keys.add("optional","ATOM_NAMES_FILE","PDB file with atom names for all atoms in SPECIES. Atoms in reference environments will be compared only if atom names match.");
+     222          28 :   multicolvar::MultiColvarShortcuts::shortcutKeywords( keys ); keys.needsAction("GROUP");
+     223          84 :   keys.needsAction("DISTANCE_MATRIX"); keys.needsAction("ONES"); keys.needsAction("CONSTANT");
+     224          84 :   keys.needsAction("CUSTOM"); keys.needsAction("MATRIX_VECTOR_PRODUCT"); keys.needsAction("COMBINE");
+     225          28 : }
+     226             : 
+     227          10 : EnvironmentSimilarity::EnvironmentSimilarity(const ActionOptions&ao):
+     228             :   Action(ao),
+     229          10 :   ActionShortcut(ao)
+     230             : {
+     231          20 :   std::string atomNamesFile; parse("ATOM_NAMES_FILE",atomNamesFile); PDB atomnamepdb;
+     232          10 :   if( !atomNamesFile.empty() && !atomnamepdb.read(atomNamesFile,usingNaturalUnits(),0.1/getUnits().getLength()) ) error("missing input file " + atomNamesFile);
+     233             : 
+     234          10 :   double maxdist=0; std::vector<std::string> allspec(1);
+     235          20 :   std::string crystal_structure; parse("CRYSTAL_STRUCTURE", crystal_structure);
+     236             :   std::vector<std::vector<std::pair<unsigned,Vector> > > environments;
+     237          10 :   if( crystal_structure=="CUSTOM" ) {
+     238           5 :     if( !atomNamesFile.empty()  ) {
+     239           2 :       allspec[0]=atomnamepdb.getAtomName(atomnamepdb.getAtomNumbers()[0]); unsigned natoms=atomnamepdb.getPositions().size();
+     240         385 :       for(unsigned i=0; i<natoms; ++i) {
+     241             :         bool found=false;
+     242         576 :         for(unsigned j=0; j<allspec.size(); ++j) {
+     243         575 :           if( allspec[j]==atomnamepdb.getAtomName(atomnamepdb.getAtomNumbers()[i] ) ) { found=true; break; }
+     244             :         }
+     245         385 :         if( !found ) allspec.push_back( atomnamepdb.getAtomName(atomnamepdb.getAtomNumbers()[i]) );
+     246             :       }
+     247             :     }
+     248          10 :     std::string reffile; parse("REFERENCE",reffile);
+     249           5 :     if( reffile.length()>0 ) {
+     250           2 :       PDB pdb; pdb.read(reffile,plumed.usingNaturalUnits(),0.1/plumed.getUnits().getLength());
+     251           2 :       environments.push_back( getReferenceEnvironment( pdb, allspec, maxdist ) );
+     252           2 :       log.printf("  reading %d reference vectors from %s \n", environments[0].size(), reffile.c_str() );
+     253           2 :     } else {
+     254          12 :       for(unsigned int i=1;; i++) {
+     255          30 :         PDB pdb; if( !parseNumbered("REFERENCE_",i,reffile) ) break;
+     256          12 :         if( !pdb.read(reffile,usingNaturalUnits(),0.1/getUnits().getLength()) ) error("missing input file " + reffile );
+     257          12 :         environments.push_back( getReferenceEnvironment( pdb, allspec, maxdist ) );
+     258          12 :         log.printf("  Reference environment %d : reading %d reference vectors from %s \n", i, environments[i-1].size(), reffile.c_str() );
+     259          15 :       }
+     260             :     }
+     261             :   } else {
+     262          10 :     std::vector<double> lattice_constants; parseVector("LATTICE_CONSTANTS", lattice_constants);
+     263           5 :     if (crystal_structure == "FCC") {
+     264           1 :       if (lattice_constants.size() != 1) error("Number of LATTICE_CONSTANTS arguments must be one for FCC");
+     265           1 :       environments.resize(1); environments[0].resize(12);
+     266           1 :       environments[0][0]  = std::pair<unsigned,Vector>( 0, Vector(+0.5,+0.5,+0.0)*lattice_constants[0] );
+     267           1 :       environments[0][1]  = std::pair<unsigned,Vector>( 0, Vector(-0.5,-0.5,+0.0)*lattice_constants[0] );
+     268           1 :       environments[0][2]  = std::pair<unsigned,Vector>( 0, Vector(+0.5,-0.5,+0.0)*lattice_constants[0] );
+     269           1 :       environments[0][3]  = std::pair<unsigned,Vector>( 0, Vector(-0.5,+0.5,+0.0)*lattice_constants[0] );
+     270           1 :       environments[0][4]  = std::pair<unsigned,Vector>( 0, Vector(+0.5,+0.0,+0.5)*lattice_constants[0] );
+     271           1 :       environments[0][5]  = std::pair<unsigned,Vector>( 0, Vector(-0.5,+0.0,-0.5)*lattice_constants[0] );
+     272           1 :       environments[0][6]  = std::pair<unsigned,Vector>( 0, Vector(-0.5,+0.0,+0.5)*lattice_constants[0] );
+     273           1 :       environments[0][7]  = std::pair<unsigned,Vector>( 0, Vector(+0.5,+0.0,-0.5)*lattice_constants[0] );
+     274           1 :       environments[0][8]  = std::pair<unsigned,Vector>( 0, Vector(+0.0,+0.5,+0.5)*lattice_constants[0] );
+     275           1 :       environments[0][9]  = std::pair<unsigned,Vector>( 0, Vector(+0.0,-0.5,-0.5)*lattice_constants[0] );
+     276           1 :       environments[0][10] = std::pair<unsigned,Vector>( 0, Vector(+0.0,-0.5,+0.5)*lattice_constants[0] );
+     277           1 :       environments[0][11] = std::pair<unsigned,Vector>( 0, Vector(+0.0,+0.5,-0.5)*lattice_constants[0] );
+     278           1 :       maxdist = std::sqrt(2)*lattice_constants[0]/2.;
+     279           4 :     } else if (crystal_structure == "SC") {
+     280           0 :       if (lattice_constants.size() != 1) error("Number of LATTICE_CONSTANTS arguments must be one for SC");
+     281           0 :       environments.resize(1); environments[0].resize(6);
+     282           0 :       environments[0][0]  = std::pair<unsigned,Vector>( 0, Vector(+1.0,+0.0,+0.0)*lattice_constants[0] );
+     283           0 :       environments[0][1]  = std::pair<unsigned,Vector>( 0, Vector(-1.0,+0.0,+0.0)*lattice_constants[0] );
+     284           0 :       environments[0][2]  = std::pair<unsigned,Vector>( 0, Vector(+0.0,+1.0,+0.0)*lattice_constants[0] );
+     285           0 :       environments[0][3]  = std::pair<unsigned,Vector>( 0, Vector(+0.0,-1.0,+0.0)*lattice_constants[0] );
+     286           0 :       environments[0][4]  = std::pair<unsigned,Vector>( 0, Vector(+0.0,+0.0,+1.0)*lattice_constants[0] );
+     287           0 :       environments[0][5]  = std::pair<unsigned,Vector>( 0, Vector(+0.0,+0.0,-1.0)*lattice_constants[0] );
+     288           0 :       maxdist = lattice_constants[0];
+     289           4 :     } else if( crystal_structure == "BCC") {
+     290           2 :       if (lattice_constants.size() != 1) error("Number of LATTICE_CONSTANTS arguments must be one for BCC");
+     291           2 :       environments.resize(1); environments[0].resize(14);
+     292           2 :       environments[0][0]  = std::pair<unsigned,Vector>( 0, Vector(+0.5,+0.5,+0.5)*lattice_constants[0] );
+     293           2 :       environments[0][1]  = std::pair<unsigned,Vector>( 0, Vector(-0.5,-0.5,-0.5)*lattice_constants[0] );
+     294           2 :       environments[0][2]  = std::pair<unsigned,Vector>( 0, Vector(-0.5,+0.5,+0.5)*lattice_constants[0] );
+     295           2 :       environments[0][3]  = std::pair<unsigned,Vector>( 0, Vector(+0.5,-0.5,+0.5)*lattice_constants[0] );
+     296           2 :       environments[0][4]  = std::pair<unsigned,Vector>( 0, Vector(+0.5,+0.5,-0.5)*lattice_constants[0] );
+     297           2 :       environments[0][5]  = std::pair<unsigned,Vector>( 0, Vector(-0.5,-0.5,+0.5)*lattice_constants[0] );
+     298           2 :       environments[0][6]  = std::pair<unsigned,Vector>( 0, Vector(+0.5,-0.5,-0.5)*lattice_constants[0] );
+     299           2 :       environments[0][7]  = std::pair<unsigned,Vector>( 0, Vector(-0.5,+0.5,-0.5)*lattice_constants[0] );
+     300           2 :       environments[0][8]  = std::pair<unsigned,Vector>( 0, Vector(+1.0,+0.0,+0.0)*lattice_constants[0] );
+     301           2 :       environments[0][9]  = std::pair<unsigned,Vector>( 0, Vector(+0.0,+1.0,+0.0)*lattice_constants[0] );
+     302           2 :       environments[0][10] = std::pair<unsigned,Vector>( 0, Vector(+0.0,+0.0,+1.0)*lattice_constants[0] );
+     303           2 :       environments[0][11] = std::pair<unsigned,Vector>( 0, Vector(-1.0,+0.0,+0.0)*lattice_constants[0] );
+     304           2 :       environments[0][12] = std::pair<unsigned,Vector>( 0, Vector(+0.0,-1.0,+0.0)*lattice_constants[0] );
+     305           2 :       environments[0][13] = std::pair<unsigned,Vector>( 0, Vector(+0.0,+0.0,-1.0)*lattice_constants[0] );
+     306           2 :       maxdist = lattice_constants[0];
+     307           2 :     } else if (crystal_structure == "HCP") {
+     308           1 :       if (lattice_constants.size() != 2) error("Number of LATTICE_CONSTANTS arguments must be two for HCP");
+     309           1 :       environments.resize(2); environments[0].resize(12); environments[1].resize(12); double sqrt3=std::sqrt(3);
+     310           1 :       environments[0][0]  = std::pair<unsigned,Vector>( 0, Vector(+0.5,+sqrt3/2.0,+0.0)*lattice_constants[0] );
+     311           1 :       environments[0][1]  = std::pair<unsigned,Vector>( 0, Vector(-0.5,+sqrt3/2.0,+0.0)*lattice_constants[0] );
+     312           1 :       environments[0][2]  = std::pair<unsigned,Vector>( 0, Vector(+0.5,-sqrt3/2.0,+0.0)*lattice_constants[0] );
+     313           1 :       environments[0][3]  = std::pair<unsigned,Vector>( 0, Vector(-0.5,-sqrt3/2.0,+0.0)*lattice_constants[0] );
+     314           1 :       environments[0][4]  = std::pair<unsigned,Vector>( 0, Vector(+1.0,+0.0,+0.0)      *lattice_constants[0] );
+     315           1 :       environments[0][5]  = std::pair<unsigned,Vector>( 0, Vector(-1.0,+0.0,+0.0)      *lattice_constants[0] );
+     316           1 :       environments[0][6]  = std::pair<unsigned,Vector>( 0, Vector(+0.5,+sqrt3/6.0,+0.0)*lattice_constants[0] + Vector(+0.0,+0.0,+0.5)*lattice_constants[1] );
+     317           1 :       environments[0][7]  = std::pair<unsigned,Vector>( 0, Vector(-0.5,+sqrt3/6.0,+0.0)*lattice_constants[0] + Vector(+0.0,+0.0,+0.5)*lattice_constants[1] );
+     318           1 :       environments[0][8]  = std::pair<unsigned,Vector>( 0, Vector(+0.0,-sqrt3/3.0,+0.0)*lattice_constants[0] + Vector(+0.0,+0.0,+0.5)*lattice_constants[1] );
+     319           1 :       environments[0][9]  = std::pair<unsigned,Vector>( 0, Vector(+0.5,+sqrt3/6.0,+0.0)*lattice_constants[0] + Vector(+0.0,+0.0,-0.5)*lattice_constants[1] );
+     320           1 :       environments[0][10] = std::pair<unsigned,Vector>( 0, Vector(-0.5,+sqrt3/6.0,+0.0)*lattice_constants[0] + Vector(+0.0,+0.0,-0.5)*lattice_constants[1] );
+     321           1 :       environments[0][11] = std::pair<unsigned,Vector>( 0, Vector(+0.0,-sqrt3/3.0,+0.0)*lattice_constants[0] + Vector(+0.0,+0.0,-0.5)*lattice_constants[1] );
+     322           1 :       environments[1][0]  = std::pair<unsigned,Vector>( 0, Vector(+0.5,+sqrt3/2.0,+0.0)*lattice_constants[0] );
+     323           1 :       environments[1][1]  = std::pair<unsigned,Vector>( 0, Vector(-0.5,+sqrt3/2.0,+0.0)*lattice_constants[0] );
+     324           1 :       environments[1][2]  = std::pair<unsigned,Vector>( 0, Vector(+0.5,-sqrt3/2.0,+0.0)*lattice_constants[0] );
+     325           1 :       environments[1][3]  = std::pair<unsigned,Vector>( 0, Vector(-0.5,-sqrt3/2.0,+0.0)*lattice_constants[0] );
+     326           1 :       environments[1][4]  = std::pair<unsigned,Vector>( 0, Vector(+1.0,+0.0,+0.0)      *lattice_constants[0] );
+     327           1 :       environments[1][5]  = std::pair<unsigned,Vector>( 0, Vector(-1.0,+0.0,+0.0)      *lattice_constants[0] );
+     328           1 :       environments[1][6]  = std::pair<unsigned,Vector>( 0, Vector(+0.5,-sqrt3/6.0,+0.0)*lattice_constants[0] + Vector(+0.0,+0.0,+0.5)*lattice_constants[1] );
+     329           1 :       environments[1][7]  = std::pair<unsigned,Vector>( 0, Vector(-0.5,-sqrt3/6.0,+0.0)*lattice_constants[0] + Vector(+0.0,+0.0,+0.5)*lattice_constants[1] );
+     330           1 :       environments[1][8]  = std::pair<unsigned,Vector>( 0, Vector(+0.0,+sqrt3/3.0,+0.0)*lattice_constants[0] + Vector(+0.0,+0.0,+0.5)*lattice_constants[1] );
+     331           1 :       environments[1][9]  = std::pair<unsigned,Vector>( 0, Vector(+0.5,-sqrt3/6.0,+0.0)*lattice_constants[0] + Vector(+0.0,+0.0,-0.5)*lattice_constants[1] );
+     332           1 :       environments[1][10] = std::pair<unsigned,Vector>( 0, Vector(-0.5,-sqrt3/6.0,+0.0)*lattice_constants[0] + Vector(+0.0,+0.0,-0.5)*lattice_constants[1] );
+     333           1 :       environments[1][11] = std::pair<unsigned,Vector>( 0, Vector(+0.0,+sqrt3/3.0,+0.0)*lattice_constants[0] + Vector(+0.0,+0.0,-0.5)*lattice_constants[1] );
+     334           1 :       maxdist = lattice_constants[0];
+     335           1 :     } else if (crystal_structure == "DIAMOND") {
+     336           1 :       if (lattice_constants.size() != 1) error("Number of LATTICE_CONSTANTS arguments must be one for DIAMOND");
+     337           1 :       environments.resize(2); environments[0].resize(4); environments[1].resize(4);
+     338           1 :       environments[0][0]  = std::pair<unsigned,Vector>( 0, Vector(+1.0,+1.0,+1.0)*lattice_constants[0]/4.0 );
+     339           1 :       environments[0][1]  = std::pair<unsigned,Vector>( 0, Vector(-1.0,-1.0,+1.0)*lattice_constants[0]/4.0 );
+     340           1 :       environments[0][2]  = std::pair<unsigned,Vector>( 0, Vector(+1.0,-1.0,-1.0)*lattice_constants[0]/4.0 );
+     341           1 :       environments[0][3]  = std::pair<unsigned,Vector>( 0, Vector(-1.0,+1.0,-1.0)*lattice_constants[0]/4.0 );
+     342           1 :       environments[1][0]  = std::pair<unsigned,Vector>( 0, Vector(+1.0,-1.0,+1.0)*lattice_constants[0]/4.0 );
+     343           1 :       environments[1][1]  = std::pair<unsigned,Vector>( 0, Vector(-1.0,+1.0,+1.0)*lattice_constants[0]/4.0 );
+     344           1 :       environments[1][2]  = std::pair<unsigned,Vector>( 0, Vector(+1.0,+1.0,-1.0)*lattice_constants[0]/4.0 );
+     345           1 :       environments[1][3]  = std::pair<unsigned,Vector>( 0, Vector(-1.0,-1.0,-1.0)*lattice_constants[0]/4.0 );
+     346           1 :       maxdist = std::sqrt(3)*lattice_constants[0]/4.0;
+     347           0 :     } else error( crystal_structure + " is not a valid input for keyword CRYSTAL_STRUCTURE");
+     348             :   }
+     349          10 :   std::string matlab = getShortcutLabel() + "_cmat";
+     350          40 :   double cutoff, sig; parse("SIGMA",sig); parse("CUTOFF",cutoff); std::string lcutoff; parse("LCUTOFF",lcutoff);
+     351          10 :   std::string sig2; Tools::convert( sig*sig, sig2 ); std::vector<std::vector<std::string> > funcstr(environments.size());
+     352          10 :   std::string str_cutoff; Tools::convert( maxdist + cutoff*sig, str_cutoff );
+     353          10 :   std::string str_natoms, xpos, ypos, zpos; Tools::convert( environments[0].size(), str_natoms );
+     354          31 :   for(unsigned j=0; j<environments.size(); ++j) {
+     355          21 :     funcstr[j].resize( allspec.size() );
+     356          46 :     for(unsigned k=0; k<allspec.size(); ++k) {
+     357         177 :       for(unsigned i=0; i<environments[j].size(); ++i) {
+     358         152 :         if( environments[j][i].first!=k ) continue ;
+     359         136 :         Tools::convert( environments[j][i].second[0], xpos ); Tools::convert( environments[j][i].second[1], ypos ); Tools::convert( environments[j][i].second[2], zpos );
+     360         157 :         if( i==0 ) funcstr[j][k] = "FUNC=(step(w-" + lcutoff + ")*step(" + str_cutoff + "-w)/" + str_natoms + ")*(exp(-((x-" + xpos + ")^2+(y-" + ypos + ")^2+(z-" + zpos + ")^2)/(4*" + sig2 + "))";
+     361         230 :         else funcstr[j][k] += "+exp(-((x-" + xpos + ")^2+(y-" + ypos + ")^2+(z-" + zpos + ")^2)/(4*" + sig2 + "))";
+     362             :       }
+     363          25 :       if( funcstr[j][k].length()>0 ) funcstr[j][k] += ")"; else funcstr[j][k] ="FUNC=0";
+     364             :     }
+     365             :   }
+     366             : 
+     367             :   // Create the constact matrix
+     368          40 :   std::string sp_str, specA, specB; parse("SPECIES",sp_str); parse("SPECIESA",specA); parse("SPECIESB",specB);
+     369          10 :   if( sp_str.length()>0 ) {
+     370          18 :     readInputLine( matlab + ": DISTANCE_MATRIX COMPONENTS GROUP=" + sp_str + " CUTOFF=" + str_cutoff );
+     371          18 :     readInputLine( getShortcutLabel() + "_grp: GROUP ATOMS=" + sp_str );
+     372             :   } else {
+     373           1 :     if( specA.length()==0 ) error("no atoms were specified use SPECIES or SPECIESA+SPECIESB");
+     374           1 :     if( specB.length()==0 ) error("no atoms were specified for SPECIESB");
+     375           2 :     readInputLine( matlab + ": DISTANCE_MATRIX COMPONENTS GROUPA=" + specA + " GROUPB=" + specB + " CUTOFF=" + str_cutoff );
+     376           2 :     readInputLine( getShortcutLabel() + "_grp: GROUP ATOMS=" + specA );
+     377             :   }
+     378             : 
+     379             :   // Make a vector containing all ones
+     380          10 :   ActionWithValue* av = plumed.getActionSet().selectWithLabel<ActionWithValue*>( matlab );
+     381          10 :   plumed_assert( av && av->getNumberOfComponents()>0 && (av->copyOutput(0))->getRank()==2 );
+     382          10 :   std::string size; Tools::convert( (av->copyOutput(0))->getShape()[1], size );
+     383          10 :   if( allspec.size()==1 ) {
+     384          18 :     readInputLine( getShortcutLabel() + "_ones: ONES SIZE=" + size );
+     385             :   } else {
+     386           1 :     unsigned natoms=atomnamepdb.getPositions().size();
+     387           1 :     unsigned firstneigh=0; if( sp_str.length()==0 ) firstneigh = (av->copyOutput(0))->getShape()[0];
+     388           3 :     for(unsigned i=0; i<allspec.size(); ++i) {
+     389           2 :       std::string onesstr="0"; if( atomnamepdb.getAtomName(atomnamepdb.getAtomNumbers()[firstneigh])==allspec[i] ) onesstr = "1";
+     390         576 :       for(unsigned j=firstneigh+1; j<natoms; ++j) {
+     391         574 :         if( atomnamepdb.getAtomName(atomnamepdb.getAtomNumbers()[j])==allspec[i] ) onesstr += ",1";
+     392             :         else onesstr += ",0";
+     393             :       }
+     394           4 :       readInputLine( getShortcutLabel() + "_ones_" + allspec[i] + ": CONSTANT VALUES=" + onesstr );
+     395             :     }
+     396             :   }
+     397             : 
+     398          15 :   std::string envargstr,varstr, maxfuncstr, lambda; if( funcstr.size()>1 ) parse("LAMBDA",lambda);
+     399             :   // And now do the funcstr bit
+     400          31 :   for(unsigned j=0; j<funcstr.size(); ++j) {
+     401          21 :     std::string jnum; Tools::convert( j+1, jnum );
+     402          21 :     if(j==0) {
+     403          30 :       varstr = "v" + jnum; maxfuncstr = "(1/" + lambda + ")*log(exp(" + lambda + "*v1)";
+     404          20 :       envargstr = getShortcutLabel() + "_env" + jnum;
+     405             :     } else {
+     406          33 :       varstr += ",v" + jnum; maxfuncstr += "+exp(" + lambda + "*v" + jnum + ")";
+     407          22 :       envargstr += "," + getShortcutLabel() + "_env" + jnum;
+     408             :     }
+     409             :     // And coordination numbers
+     410          21 :     if( allspec.size()>1 ) {
+     411             :       std::string argnames;
+     412          12 :       for(unsigned i=0; i<allspec.size(); ++i) {
+     413          16 :         readInputLine( getShortcutLabel() + "_" + allspec[i] + "_matenv" + jnum + ": CUSTOM ARG=" + matlab + ".x," + matlab + ".y," + matlab + ".z," + matlab + ".w VAR=x,y,z,w PERIODIC=NO " + funcstr[j][i] );
+     414          16 :         readInputLine( getShortcutLabel() + "_" + allspec[i] + "_env" + jnum + ": MATRIX_VECTOR_PRODUCT ARG=" + getShortcutLabel() + "_" + allspec[i] + "_matenv" + jnum + "," + getShortcutLabel() + "_ones_" + allspec[i] );
+     415          16 :         if( i==0 ) argnames = getShortcutLabel() + "_" + allspec[i] + "_env" + jnum; else argnames += "," + getShortcutLabel() + "_" + allspec[i] + "_env" + jnum;
+     416             :       }
+     417           4 :       if( funcstr.size()==1) readInputLine( getShortcutLabel() + ": COMBINE PERIODIC=NO ARG=" + argnames );
+     418           8 :       else readInputLine( getShortcutLabel() + "_env" + jnum + ": COMBINE PERIODIC=NO ARG=" + argnames );
+     419             :     } else {
+     420          34 :       readInputLine( getShortcutLabel() + "_matenv" + jnum + ": CUSTOM ARG=" + matlab + ".x," + matlab + ".y," + matlab + ".z," + matlab + ".w VAR=x,y,z,w PERIODIC=NO " + funcstr[j][0] );
+     421          22 :       if( funcstr.size()==1) readInputLine( getShortcutLabel() + ": MATRIX_VECTOR_PRODUCT ARG=" + getShortcutLabel() + "_matenv" + jnum + "," + getShortcutLabel() + "_ones");
+     422          24 :       else readInputLine( getShortcutLabel() + "_env" + jnum + ": MATRIX_VECTOR_PRODUCT ARG=" + getShortcutLabel() + "_matenv" + jnum + "," + getShortcutLabel() + "_ones");
+     423             :     }
+     424             :   }
+     425             :   // And get the maximum
+     426          15 :   if( funcstr.size()>1 ) readInputLine( getShortcutLabel() + ": CUSTOM ARG=" + envargstr + " PERIODIC=NO VAR=" + varstr + " FUNC=" + maxfuncstr + ")" );
+     427             :   // Read in all the shortcut stuff
+     428          10 :   std::map<std::string,std::string> keymap; multicolvar::MultiColvarShortcuts::readShortcutKeywords( keymap, this );
+     429          20 :   multicolvar::MultiColvarShortcuts::expandFunctions( getShortcutLabel(), getShortcutLabel(), "", keymap, this );
+     430          40 : }
+     431             : 
+     432          14 : std::vector<std::pair<unsigned,Vector> > EnvironmentSimilarity::getReferenceEnvironment( const PDB& pdb, const std::vector<std::string>& anames,  double& maxdist ) {
+     433          14 :   unsigned natoms = pdb.getPositions().size(); std::vector<std::pair<unsigned,Vector> > env( natoms );
+     434          78 :   for(unsigned i=0; i<natoms; ++i) {
+     435             :     unsigned identity=0;
+     436          80 :     for(unsigned j=1; j<anames.size(); ++j) {
+     437          16 :       if( pdb.getAtomName(pdb.getAtomNumbers()[i])==anames[j] ) { identity=j; break; }
+     438             :     }
+     439          64 :     env[i] = std::pair<unsigned,Vector>( identity, pdb.getPositions()[i] );
+     440          64 :     double dist = env[i].second.modulo();
+     441          64 :     if( dist>maxdist ) maxdist = dist;
+     442             :   }
+     443          14 :   return env;
+     444             : }
+     445             : 
+     446             : }
+     447             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/envsim/index-sort-f.html b/coverage/envsim/index-sort-f.html new file mode 100644 index 000000000000..3a78d18c8b87 --- /dev/null +++ b/coverage/envsim/index-sort-f.html @@ -0,0 +1,94 @@ + + + + + + + + LCOV - plumed test coverage - envsim + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - envsimHitTotalCoverage
Test:plumed test coverageLines:18419494.8 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
EnvironmentSimilarity.cpp +
94.8%94.8%
+
94.8 %184 / 19475.0 %3 / 4
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/envsim/index-sort-l.html b/coverage/envsim/index-sort-l.html new file mode 100644 index 000000000000..d7a2950749bf --- /dev/null +++ b/coverage/envsim/index-sort-l.html @@ -0,0 +1,94 @@ + + + + + + + + LCOV - plumed test coverage - envsim + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - envsimHitTotalCoverage
Test:plumed test coverageLines:18419494.8 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
EnvironmentSimilarity.cpp +
94.8%94.8%
+
94.8 %184 / 19475.0 %3 / 4
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/envsim/index.html b/coverage/envsim/index.html new file mode 100644 index 000000000000..2b8f8600d1b4 --- /dev/null +++ b/coverage/envsim/index.html @@ -0,0 +1,94 @@ + + + + + + + + LCOV - plumed test coverage - envsim + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - envsimHitTotalCoverage
Test:plumed test coverageLines:18419494.8 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
EnvironmentSimilarity.cpp +
94.8%94.8%
+
94.8 %184 / 19475.0 %3 / 4
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/fisst/FISST.cpp.func-sort-c.html b/coverage/fisst/FISST.cpp.func-sort-c.html new file mode 100644 index 000000000000..afbd6b1ea8a2 --- /dev/null +++ b/coverage/fisst/FISST.cpp.func-sort-c.html @@ -0,0 +1,149 @@ + + + + + + + + LCOV - plumed test coverage - fisst/FISST.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - fisst - FISST.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:24730880.2 %
Date:2024-04-19 12:12:35Functions:151978.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5fisst5FISST13readInRestartEv0
_ZN4PLMD5fisst5FISST17turnOnDerivativesEv0
_ZN4PLMD5fisst5FISSTC2ERKNS_13ActionOptionsE0
_ZN4PLMD5fisst5FISSTD2Ev0
_ZN4PLMD5fisst5FISST15setupOutRestartEv2
_ZN4PLMD5fisst5FISST18setupOutObservableEv2
_ZN4PLMD5fisst5FISSTC1ERKNS_13ActionOptionsE2
_ZN4PLMD5fisst5FISSTD0Ev2
_ZN4PLMD5fisst5FISSTD1Ev2
_ZN4PLMD5fisst5FISST16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD5fisst5FISST25compute_observable_weightEv8
_ZN4PLMD5fisst5FISST10apply_biasEv10
_ZN4PLMD5fisst5FISST11update_biasEv10
_ZN4PLMD5fisst5FISST15writeOutRestartEv10
_ZN4PLMD5fisst5FISST17update_statisticsEv10
_ZN4PLMD5fisst5FISST18writeOutObservableEv10
_ZN4PLMD5fisst5FISST6updateEv10
_ZN4PLMD5fisst5FISST9calculateEv10
_ZN4PLMD5fisst5FISST21NormalizeForceWeightsEv12
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/fisst/FISST.cpp.func.html b/coverage/fisst/FISST.cpp.func.html new file mode 100644 index 000000000000..18c2b4289163 --- /dev/null +++ b/coverage/fisst/FISST.cpp.func.html @@ -0,0 +1,149 @@ + + + + + + + + LCOV - plumed test coverage - fisst/FISST.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - fisst - FISST.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:24730880.2 %
Date:2024-04-19 12:12:35Functions:151978.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5fisst5FISST10apply_biasEv10
_ZN4PLMD5fisst5FISST11update_biasEv10
_ZN4PLMD5fisst5FISST13readInRestartEv0
_ZN4PLMD5fisst5FISST15setupOutRestartEv2
_ZN4PLMD5fisst5FISST15writeOutRestartEv10
_ZN4PLMD5fisst5FISST16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD5fisst5FISST17turnOnDerivativesEv0
_ZN4PLMD5fisst5FISST17update_statisticsEv10
_ZN4PLMD5fisst5FISST18setupOutObservableEv2
_ZN4PLMD5fisst5FISST18writeOutObservableEv10
_ZN4PLMD5fisst5FISST21NormalizeForceWeightsEv12
_ZN4PLMD5fisst5FISST25compute_observable_weightEv8
_ZN4PLMD5fisst5FISST6updateEv10
_ZN4PLMD5fisst5FISST9calculateEv10
_ZN4PLMD5fisst5FISSTC1ERKNS_13ActionOptionsE2
_ZN4PLMD5fisst5FISSTC2ERKNS_13ActionOptionsE0
_ZN4PLMD5fisst5FISSTD0Ev2
_ZN4PLMD5fisst5FISSTD1Ev2
_ZN4PLMD5fisst5FISSTD2Ev0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/fisst/FISST.cpp.gcov.html b/coverage/fisst/FISST.cpp.gcov.html new file mode 100644 index 000000000000..0467a0487b68 --- /dev/null +++ b/coverage/fisst/FISST.cpp.gcov.html @@ -0,0 +1,736 @@ + + + + + + + + LCOV - plumed test coverage - fisst/FISST.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - fisst - FISST.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:24730880.2 %
Date:2024-04-19 12:12:35Functions:151978.9 %
+
+ + + + + + + + +

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

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
FISST.cpp +
80.2%80.2%
+
80.2 %247 / 30878.9 %15 / 19
legendre_rule_fast.cpp +
77.4%77.4%
+
77.4 %72 / 9385.7 %6 / 7
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/fisst/index-sort-l.html b/coverage/fisst/index-sort-l.html new file mode 100644 index 000000000000..75829a84a818 --- /dev/null +++ b/coverage/fisst/index-sort-l.html @@ -0,0 +1,104 @@ + + + + + + + + LCOV - plumed test coverage - fisst + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - fisstHitTotalCoverage
Test:plumed test coverageLines:31940179.6 %
Date:2024-04-19 12:12:35Functions:212680.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
legendre_rule_fast.cpp +
77.4%77.4%
+
77.4 %72 / 9385.7 %6 / 7
FISST.cpp +
80.2%80.2%
+
80.2 %247 / 30878.9 %15 / 19
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/fisst/index.html b/coverage/fisst/index.html new file mode 100644 index 000000000000..f0c714e0956f --- /dev/null +++ b/coverage/fisst/index.html @@ -0,0 +1,104 @@ + + + + + + + + LCOV - plumed test coverage - fisst + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - fisstHitTotalCoverage
Test:plumed test coverageLines:31940179.6 %
Date:2024-04-19 12:12:35Functions:212680.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
FISST.cpp +
80.2%80.2%
+
80.2 %247 / 30878.9 %15 / 19
legendre_rule_fast.cpp +
77.4%77.4%
+
77.4 %72 / 9385.7 %6 / 7
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/fisst/legendre_rule_fast.cpp.func-sort-c.html b/coverage/fisst/legendre_rule_fast.cpp.func-sort-c.html new file mode 100644 index 000000000000..3561df16d266 --- /dev/null +++ b/coverage/fisst/legendre_rule_fast.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - fisst/legendre_rule_fast.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - fisst - legendre_rule_fast.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:729377.4 %
Date:2024-04-19 12:12:35Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5fisst21legendre_compute_glr2EdiPdS1_0
_ZN4PLMD5fisst20legendre_compute_glrEiPdS1_2
_ZN4PLMD5fisst21legendre_compute_glr0EiPdS1_2
_ZN4PLMD5fisst21legendre_compute_glr1EiPdS1_2
_ZN4PLMD5fisst7rescaleEddiPdS1_2
_ZN4PLMD5fisst7rk2_legEdddi30
_ZN4PLMD5fisst7ts_multEPddi330
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/fisst/legendre_rule_fast.cpp.func.html b/coverage/fisst/legendre_rule_fast.cpp.func.html new file mode 100644 index 000000000000..306ef3ea808f --- /dev/null +++ b/coverage/fisst/legendre_rule_fast.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - fisst/legendre_rule_fast.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - fisst - legendre_rule_fast.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:729377.4 %
Date:2024-04-19 12:12:35Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5fisst20legendre_compute_glrEiPdS1_2
_ZN4PLMD5fisst21legendre_compute_glr0EiPdS1_2
_ZN4PLMD5fisst21legendre_compute_glr1EiPdS1_2
_ZN4PLMD5fisst21legendre_compute_glr2EdiPdS1_0
_ZN4PLMD5fisst7rescaleEddiPdS1_2
_ZN4PLMD5fisst7rk2_legEdddi30
_ZN4PLMD5fisst7ts_multEPddi330
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/fisst/legendre_rule_fast.cpp.gcov.html b/coverage/fisst/legendre_rule_fast.cpp.gcov.html new file mode 100644 index 000000000000..56552edad40f --- /dev/null +++ b/coverage/fisst/legendre_rule_fast.cpp.gcov.html @@ -0,0 +1,642 @@ + + + + + + + + LCOV - plumed test coverage - fisst/legendre_rule_fast.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - fisst - legendre_rule_fast.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:729377.4 %
Date:2024-04-19 12:12:35Functions: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/fourier/FourierTransform.cpp.func-sort-c.html b/coverage/fourier/FourierTransform.cpp.func-sort-c.html new file mode 100644 index 000000000000..124205dba49e --- /dev/null +++ b/coverage/fourier/FourierTransform.cpp.func-sort-c.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - fourier/FourierTransform.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - fourier - FourierTransform.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:869986.9 %
Date:2024-04-19 12:12:35Functions:6966.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7fourier16FourierTransform16setupOnFirstStepEb0
_ZN4PLMD7fourier16FourierTransformC2ERKNS_13ActionOptionsE0
_ZNK4PLMD7fourier16FourierTransform11performTaskERKjRNS_10MultiValueE0
_ZN4PLMD7fourier16FourierTransform9calculateEv1
_ZN4PLMD7fourier16FourierTransformC1ERKNS_13ActionOptionsE1
_ZNK4PLMD7fourier16FourierTransform22getGridCoordinateNamesB5cxx11Ev2
_ZN4PLMD7fourier16FourierTransform16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD7fourier16FourierTransform22getNumberOfDerivativesEv4
_ZNK4PLMD7fourier16FourierTransform24getGridCoordinatesObjectEv7
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/fourier/FourierTransform.cpp.func.html b/coverage/fourier/FourierTransform.cpp.func.html new file mode 100644 index 000000000000..f95cb48380a2 --- /dev/null +++ b/coverage/fourier/FourierTransform.cpp.func.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - fourier/FourierTransform.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - fourier - FourierTransform.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:869986.9 %
Date:2024-04-19 12:12:35Functions:6966.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7fourier16FourierTransform16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD7fourier16FourierTransform16setupOnFirstStepEb0
_ZN4PLMD7fourier16FourierTransform22getNumberOfDerivativesEv4
_ZN4PLMD7fourier16FourierTransform9calculateEv1
_ZN4PLMD7fourier16FourierTransformC1ERKNS_13ActionOptionsE1
_ZN4PLMD7fourier16FourierTransformC2ERKNS_13ActionOptionsE0
_ZNK4PLMD7fourier16FourierTransform11performTaskERKjRNS_10MultiValueE0
_ZNK4PLMD7fourier16FourierTransform22getGridCoordinateNamesB5cxx11Ev2
_ZNK4PLMD7fourier16FourierTransform24getGridCoordinatesObjectEv7
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/fourier/FourierTransform.cpp.gcov.html b/coverage/fourier/FourierTransform.cpp.gcov.html new file mode 100644 index 000000000000..d322cbc51a94 --- /dev/null +++ b/coverage/fourier/FourierTransform.cpp.gcov.html @@ -0,0 +1,333 @@ + + + + + + + + LCOV - plumed test coverage - fourier/FourierTransform.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - fourier - FourierTransform.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:869986.9 %
Date:2024-04-19 12:12:35Functions: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             : #include <iostream>
+      23             : #include <complex>
+      24             : #include "gridtools/ActionWithGrid.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 fourier {
+      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 gridtools::ActionWithGrid {
+      70             : private:
+      71             :   bool firsttime;
+      72             :   std::string output_type;
+      73             :   bool real_output, store_norm;
+      74             :   std::vector<int> fourier_params;
+      75             :   gridtools::GridCoordinatesObject gridcoords;
+      76             : public:
+      77             :   static void registerKeywords( Keywords& keys );
+      78             :   explicit FourierTransform(const ActionOptions&ao);
+      79           0 :   void setupOnFirstStep( const bool incalc ) override { plumed_error(); }
+      80             :   unsigned getNumberOfDerivatives() override ;
+      81             :   const gridtools::GridCoordinatesObject& getGridCoordinatesObject() const override ;
+      82             :   std::vector<std::string> getGridCoordinateNames() const override ;
+      83           0 :   void performTask( const unsigned& current, MultiValue& myvals ) const override { plumed_error(); }
+      84             :   void calculate() override ;
+      85             : };
+      86             : 
+      87             : PLUMED_REGISTER_ACTION(FourierTransform,"FOURIER_TRANSFORM")
+      88             : 
+      89           3 : void FourierTransform::registerKeywords( Keywords& keys ) {
+      90           3 :   ActionWithGrid::registerKeywords( keys ); keys.use("ARG");
+      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           6 :   keys.addOutputComponent("real","FT_TYPE","the real part of the function");
+      96           6 :   keys.addOutputComponent("imag","FT_TYPE","the imaginary part of the function");
+      97           3 : }
+      98             : 
+      99           1 : FourierTransform::FourierTransform(const ActionOptions&ao):
+     100             :   Action(ao),
+     101             :   ActionWithGrid(ao),
+     102           1 :   firsttime(true),
+     103           1 :   real_output(true),
+     104           1 :   store_norm(false),
+     105           1 :   fourier_params(2)
+     106             : {
+     107           1 :   if( getPntrToArgument(0)->getRank()!=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           1 :   std::vector<unsigned> shape( getPntrToArgument(0)->getRank() );
+     139           1 :   if (real_output) {
+     140           0 :     addValueWithDerivatives( shape );
+     141             :   } else {
+     142           1 :     addComponentWithDerivatives( "real", shape );
+     143           2 :     addComponentWithDerivatives( "imag", shape );
+     144             :   }
+     145             : 
+     146             :   unsigned dimension = getPntrToArgument(0)->getRank();
+     147           1 :   gridtools::ActionWithGrid* ag=dynamic_cast<gridtools::ActionWithGrid*>( getPntrToArgument(0)->getPntrToAction() );
+     148           1 :   if( !ag ) error("input action should be a grid");
+     149           1 :   const gridtools::GridCoordinatesObject & gcoords( ag->getGridCoordinatesObject() );
+     150           2 :   if( gcoords.getGridType()=="fibonacci" ) error("cannot fourier transform fibonacci grids");
+     151           3 :   std::vector<bool> ipbc( dimension ); for(unsigned i=0; i<dimension; ++i) ipbc[i] = gcoords.isPeriodic(i);
+     152           2 :   gridcoords.setup( "flat", ipbc, 0, 0.0 ); checkRead();
+     153             : #ifndef __PLUMED_HAS_FFTW
+     154             :   error("this feature is only available if you compile PLUMED with FFTW");
+     155             : #endif
+     156           1 : }
+     157             : 
+     158           4 : unsigned FourierTransform::getNumberOfDerivatives() {
+     159           4 :   return 2;
+     160             : }
+     161             : 
+     162           7 : const gridtools::GridCoordinatesObject& FourierTransform::getGridCoordinatesObject() const {
+     163           7 :   return gridcoords;
+     164             : }
+     165             : 
+     166           2 : std::vector<std::string> FourierTransform::getGridCoordinateNames() const {
+     167           2 :   gridtools::ActionWithGrid* ag=dynamic_cast<gridtools::ActionWithGrid*>( getPntrToArgument(0)->getPntrToAction() );
+     168           2 :   return ag->getGridCoordinateNames();
+     169             : }
+     170             : 
+     171           1 : void FourierTransform::calculate() {
+     172           1 :   if( firsttime ) {
+     173           1 :     gridtools::ActionWithGrid* ag=dynamic_cast<gridtools::ActionWithGrid*>( getPntrToArgument(0)->getPntrToAction() );
+     174           1 :     const gridtools::GridCoordinatesObject & gcoords( ag->getGridCoordinatesObject() );
+     175           1 :     std::vector<double> fspacing; std::vector<unsigned> snbins( getGridCoordinatesObject().getDimension() );
+     176           1 :     std::vector<std::string> smin( gcoords.getDimension() ), smax( gcoords.getDimension() );
+     177           3 :     for(unsigned i=0; i<getGridCoordinatesObject().getDimension(); ++i) {
+     178           6 :       smin[i]=gcoords.getMin()[i]; smax[i]=gcoords.getMax()[i];
+     179             :       // Compute k-grid extents
+     180           2 :       double dmin, dmax; snbins[i]=gcoords.getNbin(false)[i];
+     181           2 :       Tools::convert(smin[i],dmin); Tools::convert(smax[i],dmax);
+     182           2 :       dmax=2.0*pi*snbins[i]/( dmax - dmin ); dmin=0.0;
+     183           2 :       Tools::convert(dmin,smin[i]); Tools::convert(dmax,smax[i]);
+     184             :     }
+     185           1 :     gridcoords.setBounds( smin, smax, snbins, fspacing ); firsttime=false;
+     186           3 :     for(unsigned i=0; i<getNumberOfComponents(); ++i) getPntrToComponent(i)->setShape( gcoords.getNbin(true) );
+     187           1 :   }
+     188             : 
+     189             : #ifdef __PLUMED_HAS_FFTW
+     190             :   // *** CHECK CORRECT k-GRID BOUNDARIES ***
+     191             :   //log<<"Real grid boundaries: \n"
+     192             :   //    <<"  min_x: "<<mygrid->getMin()[0]<<"  min_y: "<<mygrid->getMin()[1]<<"\n"
+     193             :   //    <<"  max_x: "<<mygrid->getMax()[0]<<"  max_y: "<<mygrid->getMax()[1]<<"\n"
+     194             :   //    <<"K-grid boundaries:"<<"\n"
+     195             :   //    <<"  min_x: "<<ft_min[0]<<"  min_y: "<<ft_min[1]<<"\n"
+     196             :   //    <<"  max_x: "<<ft_max[0]<<"  max_y: "<<ft_max[1]<<"\n";
+     197             : 
+     198             :   // Get the size of the input data arrays (to allocate FFT data)
+     199           1 :   std::vector<unsigned> N_input_data( gridcoords.getNbin(true) );
+     200           3 :   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] );
+     201             :   // FFT arrays
+     202           1 :   std::vector<std::complex<double> > input_data(fft_dimension), fft_data(fft_dimension);
+     203             : 
+     204             :   // Fill real input with the data on the grid
+     205             :   Value* arg=getPntrToArgument(0);
+     206           1 :   unsigned nargs=arg->getNumberOfValues();
+     207           1 :   std::vector<unsigned> ind( arg->getRank() );
+     208       10202 :   for (unsigned i=0; i<arg->getNumberOfValues(); ++i) {
+     209             :     // Get point indices
+     210       10201 :     gridcoords.getIndices(i, ind);
+     211             :     // Fill input data in row-major order
+     212       10201 :     input_data[ind[0]*N_input_data[0]+ind[1]].real( arg->get( i ) );
+     213       10201 :     input_data[ind[0]*N_input_data[0]+ind[1]].imag( 0.0 );
+     214             :   }
+     215             : 
+     216             :   // *** 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 ...
+     217           1 :   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);
+     218             : 
+     219             :   // Compute FT
+     220           1 :   fftw_execute( plan_complex );
+     221             : 
+     222             :   // Compute the normalization constant
+     223             :   double norm=1.0;
+     224           3 :   for (unsigned i=0; i<N_input_data.size(); ++i) {
+     225           2 :     norm *= pow( N_input_data[i], (1-fourier_params[0])/2 );
+     226             :   }
+     227             : 
+     228             :   // Save FT data to output grid
+     229           1 :   std::vector<unsigned> N_out_data ( getGridCoordinatesObject().getNbin(true) );
+     230           1 :   std::vector<unsigned> out_ind ( getPntrToArgument(0)->getRank() );
+     231       10202 :   for(unsigned i=0; i<getPntrToArgument(0)->getNumberOfValues(); ++i) {
+     232       10201 :     gridcoords.getIndices( i, out_ind );
+     233       10201 :     if (real_output) {
+     234             :       double ft_value;
+     235             :       // Compute abs/norm and fix normalization
+     236           0 :       if (!store_norm) ft_value=std::abs( fft_data[out_ind[0]*N_out_data[0]+out_ind[1]] / norm );
+     237           0 :       else ft_value=std::norm( fft_data[out_ind[0]*N_out_data[0]+out_ind[1]] / norm );
+     238             :       // Set the value
+     239           0 :       getPntrToComponent(0)->set( i, ft_value);
+     240             :     } else {
+     241             :       double ft_value_real, ft_value_imag;
+     242       10201 :       ft_value_real=fft_data[out_ind[0]*N_out_data[0]+out_ind[1]].real() / norm;
+     243       10201 :       ft_value_imag=fft_data[out_ind[0]*N_out_data[0]+out_ind[1]].imag() / norm;
+     244             :       // Set values
+     245       10201 :       getPntrToComponent(0)->set( i, ft_value_real );
+     246       10201 :       getPntrToComponent(1)->set( i, ft_value_imag );
+     247             :     }
+     248             :   }
+     249             : 
+     250             :   // Free FFTW stuff
+     251           1 :   fftw_destroy_plan(plan_complex);
+     252             : #endif
+     253           1 : }
+     254             : 
+     255             : } // end namespace 'gridtools'
+     256             : } // end namespace 'PLMD'
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/fourier/index-sort-f.html b/coverage/fourier/index-sort-f.html new file mode 100644 index 000000000000..5a4533c62cda --- /dev/null +++ b/coverage/fourier/index-sort-f.html @@ -0,0 +1,94 @@ + + + + + + + + LCOV - plumed test coverage - fourier + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - fourierHitTotalCoverage
Test:plumed test coverageLines:869986.9 %
Date:2024-04-19 12:12:35Functions:6966.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
FourierTransform.cpp +
86.9%86.9%
+
86.9 %86 / 9966.7 %6 / 9
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/fourier/index-sort-l.html b/coverage/fourier/index-sort-l.html new file mode 100644 index 000000000000..cd50c6202d09 --- /dev/null +++ b/coverage/fourier/index-sort-l.html @@ -0,0 +1,94 @@ + + + + + + + + LCOV - plumed test coverage - fourier + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - fourierHitTotalCoverage
Test:plumed test coverageLines:869986.9 %
Date:2024-04-19 12:12:35Functions:6966.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
FourierTransform.cpp +
86.9%86.9%
+
86.9 %86 / 9966.7 %6 / 9
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/fourier/index.html b/coverage/fourier/index.html new file mode 100644 index 000000000000..07bbae3f042e --- /dev/null +++ b/coverage/fourier/index.html @@ -0,0 +1,94 @@ + + + + + + + + LCOV - plumed test coverage - fourier + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - fourierHitTotalCoverage
Test:plumed test coverageLines:869986.9 %
Date:2024-04-19 12:12:35Functions:6966.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
FourierTransform.cpp +
86.9%86.9%
+
86.9 %86 / 9966.7 %6 / 9
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Bessel.cpp.func-sort-c.html b/coverage/function/Bessel.cpp.func-sort-c.html new file mode 100644 index 000000000000..2eb58d2101b0 --- /dev/null +++ b/coverage/function/Bessel.cpp.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - function/Bessel.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - Bessel.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:333594.3 %
Date:2024-04-19 12:12:35Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function6Bessel22derivativesImplementedEv0
_ZN4PLMD8function6Bessel17fill_coefficientsEv7
_ZN4PLMD8function6Bessel4readEPNS_19ActionWithArgumentsE7
_ZNK4PLMD8function6Bessel4calcEPKNS_19ActionWithArgumentsERKSt6vectorIdSaIdEERS7_RNS_6MatrixIdEE14
_ZNK4PLMD8function6Bessel6chbevlEdRSt6vectorIdSaIdEE14
_ZN4PLMD8function6Bessel16registerKeywordsERNS_8KeywordsE20
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Bessel.cpp.func.html b/coverage/function/Bessel.cpp.func.html new file mode 100644 index 000000000000..47be1d78a5ed --- /dev/null +++ b/coverage/function/Bessel.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - function/Bessel.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - Bessel.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:333594.3 %
Date:2024-04-19 12:12:35Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function6Bessel16registerKeywordsERNS_8KeywordsE20
_ZN4PLMD8function6Bessel17fill_coefficientsEv7
_ZN4PLMD8function6Bessel22derivativesImplementedEv0
_ZN4PLMD8function6Bessel4readEPNS_19ActionWithArgumentsE7
_ZNK4PLMD8function6Bessel4calcEPKNS_19ActionWithArgumentsERKSt6vectorIdSaIdEERS7_RNS_6MatrixIdEE14
_ZNK4PLMD8function6Bessel6chbevlEdRSt6vectorIdSaIdEE14
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Bessel.cpp.gcov.html b/coverage/function/Bessel.cpp.gcov.html new file mode 100644 index 000000000000..428f334d23b9 --- /dev/null +++ b/coverage/function/Bessel.cpp.gcov.html @@ -0,0 +1,272 @@ + + + + + + + + LCOV - plumed test coverage - function/Bessel.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - Bessel.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:333594.3 %
Date:2024-04-19 12:12:35Functions:5683.3 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2017 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "FunctionTemplateBase.h"
+      23             : #include "FunctionShortcut.h"
+      24             : #include "FunctionOfScalar.h"
+      25             : #include "FunctionOfVector.h"
+      26             : #include "core/ActionRegister.h"
+      27             : #include "tools/SwitchingFunction.h"
+      28             : #include <array>
+      29             : #include <cmath>
+      30             : 
+      31             : namespace PLMD {
+      32             : namespace function {
+      33             : 
+      34             : //+PLUMEDOC FUNCTION BESSEL
+      35             : /*
+      36             : Calculate the value of a Bessel function.
+      37             : 
+      38             : \par Examples
+      39             : 
+      40             : */
+      41             : //+ENDPLUMEDOC
+      42             : 
+      43             : //+PLUMEDOC FUNCTION BESSEL_SCALAR
+      44             : /*
+      45             : Calculate the value of a Bessel function.
+      46             : 
+      47             : \par Examples
+      48             : 
+      49             : */
+      50             : //+ENDPLUMEDOC
+      51             : 
+      52             : //+PLUMEDOC FUNCTION BESSEL_VECTOR
+      53             : /*
+      54             : Calculate the bessel function for all the elements in a vector
+      55             : 
+      56             : \par Examples
+      57             : 
+      58             : */
+      59             : //+ENDPLUMEDOC
+      60             : 
+      61             : 
+      62          34 : class Bessel : public FunctionTemplateBase {
+      63             : private:
+      64             :   unsigned order;
+      65             :   // Cheb coefficient for range [0,8]
+      66             :   static std::vector<double> A;
+      67             :   // Cheb coefficient for range (8,inf)
+      68             :   static std::vector<double> B;
+      69             :   double chbevl(double x,std::vector<double>& array) const; // sub copied from scipy in C
+      70             :   void fill_coefficients();
+      71             : public:
+      72           0 :   bool derivativesImplemented() override { return false; }
+      73             :   void registerKeywords( Keywords& keys ) override;
+      74             :   void read( ActionWithArguments* action ) override;
+      75             :   void calc( const ActionWithArguments* action, const std::vector<double>& args, std::vector<double>& vals, Matrix<double>& derivatives ) const override;
+      76             : };
+      77             : 
+      78             : typedef FunctionShortcut<Bessel> BesselShortcut;
+      79             : PLUMED_REGISTER_ACTION(BesselShortcut,"BESSEL")
+      80             : typedef FunctionOfScalar<Bessel> ScalarBessel;
+      81             : PLUMED_REGISTER_ACTION(ScalarBessel,"BESSEL_SCALAR")
+      82             : typedef FunctionOfVector<Bessel> VectorBessel;
+      83             : PLUMED_REGISTER_ACTION(VectorBessel,"BESSEL_VECTOR")
+      84             : 
+      85          20 : void Bessel::registerKeywords(Keywords& keys) {
+      86          40 :   keys.add("compulsory","ORDER","0","the order of Bessel function to use.  Can only be zero at the moment.");
+      87          20 : }
+      88             : 
+      89           7 : void Bessel::read( ActionWithArguments* action ) {
+      90           7 :   if( action->getNumberOfArguments()!=1 ) action->error("should only be one argument to bessel actions");
+      91           7 :   if( action->getPntrToArgument(0)->isPeriodic() ) action->error("cannot use this function on periodic functions");
+      92          14 :   action->parse("ORDER",order); action->log.printf("  computing %dth order bessel function \n", order );
+      93           7 :   if( order!=0 ) action->error("only zero order bessel function is implemented");
+      94           7 :   fill_coefficients();
+      95           7 : }
+      96             : 
+      97          14 : double Bessel::chbevl(double x,std::vector<double>& array) const {
+      98             :   double b0, b1, b2;
+      99          14 :   int n = array.size();
+     100             : 
+     101          14 :   b0 = array[0];
+     102             :   b1 = 0.0;
+     103             :   b2 = b1 ;
+     104             : 
+     105         375 :   for(int index = 1 ; index < n ; index++) {
+     106             :     b2 = b1;
+     107             :     b1 = b0;
+     108         361 :     b0 = x * b1 - b2 + array[index];
+     109             :   }
+     110          14 :   return (0.5 * (b0 - b2));
+     111             : }
+     112             : 
+     113             : 
+     114          14 : void Bessel::calc( const ActionWithArguments* action, const std::vector<double>& args, std::vector<double>& vals, Matrix<double>& derivatives ) const {
+     115             :   plumed_dbg_assert( args.size()==1 );
+     116          14 :   if( order==0 ) {
+     117          14 :     double x = fabs(args[0]);
+     118          14 :     if (x <= 8.0) {
+     119           5 :       double y = (x / 2.0) - 2.0;
+     120           5 :       vals[0] =  chbevl(y, A) ;
+     121           5 :       return;
+     122             :     }
+     123           9 :     vals[0] = chbevl(32.0 / x - 2.0, B) / sqrt(x) ;
+     124           0 :   } else plumed_error();
+     125             : }
+     126             : 
+     127             : std::vector<double> Bessel::A;
+     128             : std::vector<double> Bessel::B;
+     129             : 
+     130           7 : void Bessel::fill_coefficients() {
+     131           7 :   A.resize(30);
+     132          14 :   A = {-4.41534164647933937950E-18,
+     133             :        3.33079451882223809783E-17,
+     134             :        -2.43127984654795469359E-16,
+     135             :        1.71539128555513303061E-15,
+     136             :        -1.16853328779934516808E-14,
+     137             :        7.67618549860493561688E-14,
+     138             :        -4.85644678311192946090E-13,
+     139             :        2.95505266312963983461E-12,
+     140             :        -1.72682629144155570723E-11,
+     141             :        9.67580903537323691224E-11,
+     142             :        -5.18979560163526290666E-10,
+     143             :        2.65982372468238665035E-9,
+     144             :        -1.30002500998624804212E-8,
+     145             :        6.04699502254191894932E-8,
+     146             :        -2.67079385394061173391E-7,
+     147             :        1.11738753912010371815E-6,
+     148             :        -4.41673835845875056359E-6,
+     149             :        1.64484480707288970893E-5,
+     150             :        -5.75419501008210370398E-5,
+     151             :        1.88502885095841655729E-4,
+     152             :        -5.76375574538582365885E-4,
+     153             :        1.63947561694133579842E-3,
+     154             :        -4.32430999505057594430E-3,
+     155             :        1.05464603945949983183E-2,
+     156             :        -2.37374148058994688156E-2,
+     157             :        4.93052842396707084878E-2,
+     158             :        -9.49010970480476444210E-2,
+     159             :        1.71620901522208775349E-1,
+     160             :        -3.04682672343198398683E-1,
+     161             :        6.76795274409476084995E-1
+     162           7 :       };
+     163           7 :   B.resize(25);
+     164          14 :   B = {-7.23318048787475395456E-18,
+     165             :        -4.83050448594418207126E-18,
+     166             :        4.46562142029675999901E-17,
+     167             :        3.46122286769746109310E-17,
+     168             :        -2.82762398051658348494E-16,
+     169             :        -3.42548561967721913462E-16,
+     170             :        1.77256013305652638360E-15,
+     171             :        3.81168066935262242075E-15,
+     172             :        -9.55484669882830764870E-15,
+     173             :        -4.15056934728722208663E-14,
+     174             :        1.54008621752140982691E-14,
+     175             :        3.85277838274214270114E-13,
+     176             :        7.18012445138366623367E-13,
+     177             :        -1.79417853150680611778E-12,
+     178             :        -1.32158118404477131188E-11,
+     179             :        -3.14991652796324136454E-11,
+     180             :        1.18891471078464383424E-11,
+     181             :        4.94060238822496958910E-10,
+     182             :        3.39623202570838634515E-9,
+     183             :        2.26666899049817806459E-8,
+     184             :        2.04891858946906374183E-7,
+     185             :        2.89137052083475648297E-6,
+     186             :        6.88975834691682398426E-5,
+     187             :        3.36911647825569408990E-3,
+     188             :        8.04490411014108831608E-1
+     189           7 :       };
+     190           7 : }
+     191             : 
+     192             : }
+     193             : }
+     194             : 
+     195             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Between.cpp.func-sort-c.html b/coverage/function/Between.cpp.func-sort-c.html new file mode 100644 index 000000000000..8e5d10a53b4f --- /dev/null +++ b/coverage/function/Between.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - function/Between.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - Between.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2525100.0 %
Date:2024-04-19 12:12:35Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function7Between4readEPNS_19ActionWithArgumentsE53
_ZN4PLMD8function7Between16registerKeywordsERNS_8KeywordsE112
_ZNK4PLMD8function7Between4calcEPKNS_19ActionWithArgumentsERKSt6vectorIdSaIdEERS7_RNS_6MatrixIdEE49226
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Between.cpp.func.html b/coverage/function/Between.cpp.func.html new file mode 100644 index 000000000000..473d89023ff8 --- /dev/null +++ b/coverage/function/Between.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - function/Between.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - Between.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2525100.0 %
Date:2024-04-19 12:12:35Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function7Between16registerKeywordsERNS_8KeywordsE112
_ZN4PLMD8function7Between4readEPNS_19ActionWithArgumentsE53
_ZNK4PLMD8function7Between4calcEPKNS_19ActionWithArgumentsERKSt6vectorIdSaIdEERS7_RNS_6MatrixIdEE49226
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Between.cpp.gcov.html b/coverage/function/Between.cpp.gcov.html new file mode 100644 index 000000000000..1edd56851856 --- /dev/null +++ b/coverage/function/Between.cpp.gcov.html @@ -0,0 +1,173 @@ + + + + + + + + LCOV - plumed test coverage - function/Between.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - Between.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2525100.0 %
Date:2024-04-19 12:12:35Functions:33100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2017 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "Between.h"
+      23             : #include "FunctionShortcut.h"
+      24             : #include "FunctionOfVector.h"
+      25             : #include "core/ActionRegister.h"
+      26             : 
+      27             : #include <cmath>
+      28             : 
+      29             : namespace PLMD {
+      30             : namespace function {
+      31             : 
+      32             : //+PLUMEDOC FUNCTION BETWEEN
+      33             : /*
+      34             : Use a switching function to determine how many of the input variables are within a certain range.
+      35             : 
+      36             : \par Examples
+      37             : 
+      38             : */
+      39             : //+ENDPLUMEDOC
+      40             : 
+      41             : //+PLUMEDOC FUNCTION BETWEEN_VECTOR
+      42             : /*
+      43             : Use a switching function to determine how many of the input components are within a certain range
+      44             : 
+      45             : \par Examples
+      46             : 
+      47             : */
+      48             : //+ENDPLUMEDOC
+      49             : 
+      50             : typedef FunctionShortcut<Between> BetweenShortcut;
+      51             : PLUMED_REGISTER_ACTION(BetweenShortcut,"BETWEEN")
+      52             : typedef FunctionOfVector<Between> VectorBetween;
+      53             : PLUMED_REGISTER_ACTION(VectorBetween,"BETWEEN_VECTOR")
+      54             : 
+      55         112 : void Between::registerKeywords(Keywords& keys) {
+      56         224 :   keys.add("compulsory","LOWER","the lower boundary for this particular bin");
+      57         224 :   keys.add("compulsory","UPPER","the upper boundary for this particular bin");
+      58         224 :   keys.add("compulsory","SMEAR","0.5","the ammount to smear the Gaussian for each value in the distribution");
+      59         224 :   keys.add("optional","SWITCH","This keyword is used if you want to employ an alternative to the continuous function defined above. "
+      60             :            "The following provides information on the \\ref histogrambead that are available. "
+      61             :            "When this keyword is present you no longer need the LOWER, UPPER, SMEAR and KERNEL keywords.");
+      62         112 : }
+      63             : 
+      64          53 : void Between::read( ActionWithArguments* action ) {
+      65          53 :   if( action->getNumberOfArguments()!=1 ) action->error("should only be one argument to between actions");
+      66             : 
+      67             :   std::string str_min, str_max, tstr_min, tstr_max;
+      68          53 :   bool isPeriodic = action->getPntrToArgument(0)->isPeriodic();
+      69          53 :   if( isPeriodic ) action->getPntrToArgument(0)->getDomain( str_min, str_max );
+      70             : 
+      71         106 :   std::string hinput; action->parse("SWITCH",hinput);
+      72          53 :   if(hinput.length()==0) {
+      73             :     std::string low, up, sme;
+      74          15 :     action->parse("LOWER",low); action->parse("UPPER",up); action->parse("SMEAR",sme);
+      75          10 :     hinput = "GAUSSIAN LOWER=" + low + " UPPER=" + up + " SMEAR=" + sme;
+      76             :   }
+      77          53 :   std::string errors; hist.set( hinput, errors );
+      78          53 :   if( errors.size()!=0 ) action->error( errors );
+      79          53 :   action->log.printf("  %s \n", hist.description().c_str() );
+      80             : 
+      81          53 :   if( !isPeriodic ) hist.isNotPeriodic();
+      82             :   else {
+      83           1 :     double min; Tools::convert( str_min, min );
+      84           1 :     double max; Tools::convert( str_max, max );
+      85           1 :     hist.isPeriodic( min, max );
+      86             :   }
+      87          53 : }
+      88             : 
+      89       49226 : void Between::calc( const ActionWithArguments* action, const std::vector<double>& args, std::vector<double>& vals, Matrix<double>& derivatives ) const {
+      90       49226 :   plumed_dbg_assert( args.size()==1 ); vals[0] = hist.calculate( args[0], derivatives(0,0) );
+      91       49226 : }
+      92             : 
+      93             : }
+      94             : }
+      95             : 
+      96             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Between.h.func-sort-c.html b/coverage/function/Between.h.func-sort-c.html new file mode 100644 index 000000000000..a9c038e4bca2 --- /dev/null +++ b/coverage/function/Between.h.func-sort-c.html @@ -0,0 +1,77 @@ + + + + + + + + LCOV - plumed test coverage - function/Between.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - Between.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1250.0 %
Date:2024-04-19 12:12:35Functions:010.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD8function7Between30getDerivativeZeroIfValueIsZeroEv0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Between.h.func.html b/coverage/function/Between.h.func.html new file mode 100644 index 000000000000..30e0741d3e53 --- /dev/null +++ b/coverage/function/Between.h.func.html @@ -0,0 +1,77 @@ + + + + + + + + LCOV - plumed test coverage - function/Between.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - Between.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1250.0 %
Date:2024-04-19 12:12:35Functions:010.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD8function7Between30getDerivativeZeroIfValueIsZeroEv0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Between.h.gcov.html b/coverage/function/Between.h.gcov.html new file mode 100644 index 000000000000..18810f1c64e4 --- /dev/null +++ b/coverage/function/Between.h.gcov.html @@ -0,0 +1,119 @@ + + + + + + + + LCOV - plumed test coverage - function/Between.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - Between.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1250.0 %
Date:2024-04-19 12:12:35Functions:010.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2020 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a 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_Between_h
+      23             : #define __PLUMED_function_Between_h
+      24             : 
+      25             : #include "FunctionTemplateBase.h"
+      26             : #include "tools/HistogramBead.h"
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace function {
+      30             : 
+      31         218 : class Between : public FunctionTemplateBase {
+      32             :   HistogramBead hist;
+      33             : public:
+      34             :   void registerKeywords( Keywords& keys ) override;
+      35             :   void read( ActionWithArguments* action ) override;
+      36           0 :   bool getDerivativeZeroIfValueIsZero() const override { return true; }
+      37             :   void calc( const ActionWithArguments* action, const std::vector<double>& args, std::vector<double>& vals, Matrix<double>& derivatives ) const override;
+      38             : };
+      39             : 
+      40             : }
+      41             : }
+      42             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Combine.cpp.func-sort-c.html b/coverage/function/Combine.cpp.func-sort-c.html new file mode 100644 index 000000000000..40a003c1b660 --- /dev/null +++ b/coverage/function/Combine.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + 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:3333100.0 %
Date:2024-04-19 12:12:35Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function7Combine4readEPNS_19ActionWithArgumentsE303
_ZN4PLMD8function7Combine16registerKeywordsERNS_8KeywordsE616
_ZNK4PLMD8function7Combine4calcEPKNS_19ActionWithArgumentsERKSt6vectorIdSaIdEERS7_RNS_6MatrixIdEE4369188
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Combine.cpp.func.html b/coverage/function/Combine.cpp.func.html new file mode 100644 index 000000000000..78f070d1009c --- /dev/null +++ b/coverage/function/Combine.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + 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:3333100.0 %
Date:2024-04-19 12:12:35Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function7Combine16registerKeywordsERNS_8KeywordsE616
_ZN4PLMD8function7Combine4readEPNS_19ActionWithArgumentsE303
_ZNK4PLMD8function7Combine4calcEPKNS_19ActionWithArgumentsERKSt6vectorIdSaIdEERS7_RNS_6MatrixIdEE4369188
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Combine.cpp.gcov.html b/coverage/function/Combine.cpp.gcov.html new file mode 100644 index 000000000000..9aff6a2d930b --- /dev/null +++ b/coverage/function/Combine.cpp.gcov.html @@ -0,0 +1,225 @@ + + + + + + + + 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:3333100.0 %
Date:2024-04-19 12:12:35Functions: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 "Combine.h"
+      23             : #include "FunctionTemplateBase.h"
+      24             : #include "FunctionShortcut.h"
+      25             : #include "FunctionOfScalar.h"
+      26             : #include "FunctionOfVector.h"
+      27             : #include "core/ActionRegister.h"
+      28             : 
+      29             : namespace PLMD {
+      30             : namespace function {
+      31             : 
+      32             : //+PLUMEDOC FUNCTION COMBINE
+      33             : /*
+      34             : Calculate a polynomial combination of a set of other variables.
+      35             : 
+      36             : The functional form of this function is
+      37             : \f[
+      38             : C=\sum_{i=1}^{N_{arg}} c_i (x_i-a_i)^{p_i}
+      39             : \f]
+      40             : 
+      41             : The coefficients c, the parameters a and the powers p are provided as vectors.
+      42             : 
+      43             : Notice that COMBINE is not able to predict which will be periodic domain
+      44             : of the computed value automatically. The user is thus forced to specify it
+      45             : explicitly. Use PERIODIC=NO if the resulting variable is not periodic,
+      46             : and PERIODIC=A,B where A and B are the two boundaries if the resulting variable
+      47             : is periodic.
+      48             : 
+      49             : 
+      50             : 
+      51             : \par Examples
+      52             : 
+      53             : The following input tells plumed to print the distance between atoms 3 and 5
+      54             : its square (as computed from the x,y,z components) and the distance
+      55             : again as computed from the square root of the square.
+      56             : \plumedfile
+      57             : DISTANCE LABEL=dist      ATOMS=3,5 COMPONENTS
+      58             : COMBINE  LABEL=distance2 ARG=dist.x,dist.y,dist.z POWERS=2,2,2 PERIODIC=NO
+      59             : COMBINE  LABEL=distance  ARG=distance2 POWERS=0.5 PERIODIC=NO
+      60             : PRINT ARG=distance,distance2
+      61             : \endplumedfile
+      62             : (See also \ref PRINT and \ref DISTANCE).
+      63             : 
+      64             : The following input tells plumed to add a restraint on the
+      65             : cube of a dihedral angle. Notice that since the angle has a
+      66             : periodic domain
+      67             : -pi,pi its cube has a domain -pi**3,pi**3.
+      68             : \plumedfile
+      69             : t: TORSION ATOMS=1,3,5,7
+      70             : c: COMBINE ARG=t POWERS=3 PERIODIC=-31.0062766802998,31.0062766802998
+      71             : RESTRAINT ARG=c KAPPA=10 AT=0
+      72             : \endplumedfile
+      73             : 
+      74             : 
+      75             : 
+      76             : */
+      77             : //+ENDPLUMEDOC
+      78             : 
+      79             : //+PLUMEDOC FUNCTION COMBINE_SCALAR
+      80             : /*
+      81             : Calculate a polynomial combination of a set of other variables.
+      82             : 
+      83             : \par Examples
+      84             : 
+      85             : */
+      86             : //+ENDPLUMEDOC
+      87             : 
+      88             : //+PLUMEDOC FUNCTION COMBINE_VECTOR
+      89             : /*
+      90             : Add together the elements of a set of vectors elementwise
+      91             : 
+      92             : \par Examples
+      93             : 
+      94             : */
+      95             : //+ENDPLUMEDOC
+      96             : 
+      97             : typedef FunctionShortcut<Combine> CombineShortcut;
+      98             : PLUMED_REGISTER_ACTION(CombineShortcut,"COMBINE")
+      99             : typedef FunctionOfScalar<Combine> ScalarCombine;
+     100             : PLUMED_REGISTER_ACTION(ScalarCombine,"COMBINE_SCALAR")
+     101             : typedef FunctionOfVector<Combine> VectorCombine;
+     102             : PLUMED_REGISTER_ACTION(VectorCombine,"COMBINE_VECTOR")
+     103             : 
+     104         616 : void Combine::registerKeywords(Keywords& keys) {
+     105         616 :   keys.use("PERIODIC");
+     106        1232 :   keys.add("compulsory","COEFFICIENTS","1.0","the coefficients of the arguments in your function");
+     107        1232 :   keys.add("compulsory","PARAMETERS","0.0","the parameters of the arguments in your function");
+     108        1232 :   keys.add("compulsory","POWERS","1.0","the powers to which you are raising each of the arguments in your function");
+     109        1232 :   keys.addFlag("NORMALIZE",false,"normalize all the coefficients so that in total they are equal to one");
+     110         616 : }
+     111             : 
+     112         303 : void Combine::read( ActionWithArguments* action ) {
+     113         303 :   coefficients.resize( action->getNumberOfArguments() ); parameters.resize( action->getNumberOfArguments() ); powers.resize( action->getNumberOfArguments() );
+     114         605 :   parseVector(action,"COEFFICIENTS",coefficients);
+     115         302 :   if(coefficients.size()!=static_cast<unsigned>(action->getNumberOfArguments())) action->error("Size of COEFFICIENTS array should be the same as number for arguments");
+     116         603 :   parseVector(action,"PARAMETERS",parameters);
+     117         301 :   if(parameters.size()!=static_cast<unsigned>(action->getNumberOfArguments())) action->error("Size of PARAMETERS array should be the same as number for arguments");
+     118         601 :   parseVector(action,"POWERS",powers); if(powers.size()!=static_cast<unsigned>(action->getNumberOfArguments())) action->error("Size of POWERS array should be the same as number for arguments");
+     119             : 
+     120         300 :   parseFlag(action,"NORMALIZE",normalize);
+     121         300 :   if(normalize) {
+     122             :     double n=0.0;
+     123          43 :     for(unsigned i=0; i<coefficients.size(); i++) n+=coefficients[i];
+     124          43 :     for(unsigned i=0; i<coefficients.size(); i++) coefficients[i]*=(1.0/n);
+     125             :   }
+     126             : 
+     127         300 :   action->log.printf("  with coefficients:");
+     128        1493 :   for(unsigned i=0; i<coefficients.size(); i++) action->log.printf(" %f",coefficients[i]);
+     129         300 :   action->log.printf("\n  with parameters:");
+     130        1493 :   for(unsigned i=0; i<parameters.size(); i++) action->log.printf(" %f",parameters[i]);
+     131         300 :   action->log.printf("\n  and powers:");
+     132        1493 :   for(unsigned i=0; i<powers.size(); i++) action->log.printf(" %f",powers[i]);
+     133         300 :   action->log.printf("\n");
+     134         300 : }
+     135             : 
+     136     4369188 : void Combine::calc( const ActionWithArguments* action, const std::vector<double>& args, std::vector<double>& vals, Matrix<double>& derivatives ) const {
+     137     4369188 :   vals[0]=0.0;
+     138    10983355 :   for(unsigned i=0; i<coefficients.size(); ++i) {
+     139     6614167 :     double cv = action->difference( i, parameters[i], args[i] );
+     140     6614167 :     vals[0] += coefficients[i]*pow( cv, powers[i] );
+     141     6614167 :     derivatives(0,i) = coefficients[i]*powers[i]*pow(cv,powers[i]-1.0);
+     142             :   }
+     143     4369188 : }
+     144             : 
+     145             : }
+     146             : }
+     147             : 
+     148             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Combine.h.func-sort-c.html b/coverage/function/Combine.h.func-sort-c.html new file mode 100644 index 000000000000..0c396c218da9 --- /dev/null +++ b/coverage/function/Combine.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage - function/Combine.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - Combine.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-04-19 12:12:35Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Combine.h.func.html b/coverage/function/Combine.h.func.html new file mode 100644 index 000000000000..102ce129c011 --- /dev/null +++ b/coverage/function/Combine.h.func.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage - function/Combine.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - Combine.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-04-19 12:12:35Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Combine.h.gcov.html b/coverage/function/Combine.h.gcov.html new file mode 100644 index 000000000000..0775add05d99 --- /dev/null +++ b/coverage/function/Combine.h.gcov.html @@ -0,0 +1,121 @@ + + + + + + + + LCOV - plumed test coverage - function/Combine.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - Combine.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-04-19 12:12:35Functions: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_function_Combine_h
+      23             : #define __PLUMED_function_Combine_h
+      24             : 
+      25             : #include "FunctionTemplateBase.h"
+      26             : 
+      27             : namespace PLMD {
+      28             : namespace function {
+      29             : 
+      30        1222 : class Combine : public FunctionTemplateBase
+      31             : {
+      32             :   bool normalize;
+      33             :   std::vector<double> coefficients;
+      34             :   std::vector<double> parameters;
+      35             :   std::vector<double> powers;
+      36             : public:
+      37             :   void registerKeywords(Keywords& keys) override;
+      38             :   void read( ActionWithArguments* action ) override;
+      39             :   void calc( const ActionWithArguments* action, const std::vector<double>& args, std::vector<double>& vals, Matrix<double>& derivatives ) const override;
+      40             : };
+      41             : 
+      42             : }
+      43             : }
+      44             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Custom.cpp.func-sort-c.html b/coverage/function/Custom.cpp.func-sort-c.html new file mode 100644 index 000000000000..4543c8f3bd8d --- /dev/null +++ b/coverage/function/Custom.cpp.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + 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:6464100.0 %
Date:2024-04-19 12:12:35Functions:66100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD8function6Custom12getGraphInfoERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE5
_ZN4PLMD8function6Custom19getArgumentsToCheckERKSt6vectorIPNS_5ValueESaIS4_EE966
_ZNK4PLMD8function6Custom30getDerivativeZeroIfValueIsZeroEv1810
_ZN4PLMD8function6Custom4readEPNS_19ActionWithArgumentsE2982
_ZN4PLMD8function6Custom16registerKeywordsERNS_8KeywordsE6019
_ZNK4PLMD8function6Custom4calcEPKNS_19ActionWithArgumentsERKSt6vectorIdSaIdEERS7_RNS_6MatrixIdEE20476587
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Custom.cpp.func.html b/coverage/function/Custom.cpp.func.html new file mode 100644 index 000000000000..58258e26e1d7 --- /dev/null +++ b/coverage/function/Custom.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + 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:6464100.0 %
Date:2024-04-19 12:12:35Functions:66100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function6Custom16registerKeywordsERNS_8KeywordsE6019
_ZN4PLMD8function6Custom19getArgumentsToCheckERKSt6vectorIPNS_5ValueESaIS4_EE966
_ZN4PLMD8function6Custom4readEPNS_19ActionWithArgumentsE2982
_ZNK4PLMD8function6Custom12getGraphInfoERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE5
_ZNK4PLMD8function6Custom30getDerivativeZeroIfValueIsZeroEv1810
_ZNK4PLMD8function6Custom4calcEPKNS_19ActionWithArgumentsERKSt6vectorIdSaIdEERS7_RNS_6MatrixIdEE20476587
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Custom.cpp.gcov.html b/coverage/function/Custom.cpp.gcov.html new file mode 100644 index 000000000000..78444fbb8cb2 --- /dev/null +++ b/coverage/function/Custom.cpp.gcov.html @@ -0,0 +1,421 @@ + + + + + + + + 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:6464100.0 %
Date:2024-04-19 12:12:35Functions: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 "Custom.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "FunctionShortcut.h"
+      25             : #include "FunctionOfScalar.h"
+      26             : #include "FunctionOfVector.h"
+      27             : #include "tools/OpenMP.h"
+      28             : #include "tools/LeptonCall.h"
+      29             : 
+      30             : namespace PLMD {
+      31             : namespace function {
+      32             : 
+      33             : //+PLUMEDOC FUNCTION CUSTOM
+      34             : /*
+      35             : Calculate a combination of variables using a custom expression.
+      36             : 
+      37             : This action computes an  arbitrary function of one or more
+      38             : collective variables. Arguments are chosen with the ARG keyword,
+      39             : and the function is provided with the FUNC string. Notice that this
+      40             : string should contain no space. Within FUNC, one can refer to the
+      41             : arguments as x,y,z, and t (up to four variables provided as ARG).
+      42             : This names can be customized using the VAR keyword (see examples below).
+      43             : 
+      44             : This function is implemented using the Lepton library, that allows to evaluate
+      45             : algebraic expressions and to automatically differentiate them.
+      46             : 
+      47             : If you want a function that depends not only on collective variables
+      48             : but also on time you can use the \subpage TIME action.
+      49             : 
+      50             : \par Examples
+      51             : 
+      52             : The following input tells plumed to perform a metadynamics
+      53             : using as a CV the difference between two distances.
+      54             : \plumedfile
+      55             : dAB: DISTANCE ATOMS=10,12
+      56             : dAC: DISTANCE ATOMS=10,15
+      57             : diff: CUSTOM ARG=dAB,dAC FUNC=y-x PERIODIC=NO
+      58             : # notice: the previous line could be replaced with the following
+      59             : # diff: COMBINE ARG=dAB,dAC COEFFICIENTS=-1,1
+      60             : METAD ARG=diff SIGMA=0.1 HEIGHT=0.5 BIASFACTOR=10 PACE=100
+      61             : \endplumedfile
+      62             : (see also \ref DISTANCE, \ref COMBINE, and \ref METAD).
+      63             : Notice that forces applied to diff will be correctly propagated
+      64             : to atoms 10, 12, and 15.
+      65             : Also notice that since CUSTOM is used without the VAR option
+      66             : the two arguments should be referred to as x and y in the expression FUNC.
+      67             : For simple functions
+      68             : such as this one it is possible to use \ref COMBINE.
+      69             : 
+      70             : The following input tells plumed to print the angle between vectors
+      71             : identified by atoms 1,2 and atoms 2,3
+      72             : its square (as computed from the x,y,z components) and the distance
+      73             : again as computed from the square root of the square.
+      74             : \plumedfile
+      75             : DISTANCE LABEL=d1 ATOMS=1,2 COMPONENTS
+      76             : DISTANCE LABEL=d2 ATOMS=2,3 COMPONENTS
+      77             : CUSTOM ...
+      78             :   LABEL=theta
+      79             :   ARG=d1.x,d1.y,d1.z,d2.x,d2.y,d2.z
+      80             :   VAR=ax,ay,az,bx,by,bz
+      81             :   FUNC=acos((ax*bx+ay*by+az*bz)/sqrt((ax*ax+ay*ay+az*az)*(bx*bx+by*by+bz*bz)))
+      82             :   PERIODIC=NO
+      83             : ... CUSTOM
+      84             : PRINT ARG=theta
+      85             : \endplumedfile
+      86             : (See also \ref PRINT and \ref DISTANCE).
+      87             : 
+      88             : Notice that this action implements a large number of functions (trigonometric, exp, log, etc).
+      89             : Among the useful functions, have a look at the step function (that is the Heaviside function).
+      90             : `step(x)` is defined as 1 when `x` is positive and `0` when x is negative. This allows for
+      91             : a straightforward implementation of if clauses.
+      92             : 
+      93             : For example, imagine that you want to implement a restraint that only acts when a
+      94             : distance is larger than 0.5. You can do it with
+      95             : \plumedfile
+      96             : d: DISTANCE ATOMS=10,15
+      97             : m: CUSTOM ARG=d FUNC=0.5*step(0.5-x)+x*step(x-0.5) PERIODIC=NO
+      98             : # check the function you are applying:
+      99             : PRINT ARG=d,m FILE=checkme
+     100             : RESTRAINT ARG=d AT=0.5 KAPPA=10.0
+     101             : \endplumedfile
+     102             : (see also \ref DISTANCE, \ref PRINT, and \ref RESTRAINT)
+     103             : 
+     104             : The meaning of the function `0.5*step(0.5-x)+x*step(x-0.5)` is:
+     105             : - If x<0.5 (step(0.5-x)!=0) use 0.5
+     106             : - If x>0.5 (step(x-0.5)!=0) use x
+     107             : Notice that the same could have been obtained using an \ref UPPER_WALLS
+     108             : However, with CUSTOM you can create way more complex definitions.
+     109             : 
+     110             : \warning If you apply forces on the variable (as in the previous example) you should
+     111             : make sure that the variable is continuous!
+     112             : Conversely, if you are just analyzing a trajectory you can safely use
+     113             : discontinuous variables.
+     114             : 
+     115             : A possible continuity check with gnuplot is
+     116             : \verbatim
+     117             : # this allow to step function to be used in gnuplot:
+     118             : gnuplot> step(x)=0.5*(erf(x*10000000)+1)
+     119             : # here you can test your function
+     120             : gnuplot> p 0.5*step(0.5-x)+x*step(x-0.5)
+     121             : \endverbatim
+     122             : 
+     123             : Also notice that you can easily make logical operations on the conditions that you
+     124             : create. The equivalent of the AND operator is the product: `step(1.0-x)*step(x-0.5)` is
+     125             : 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,
+     126             : `1-step(1.0-x)*step(x-0.5)` is only equal to 1 when x is outside the 0.5-1.0 interval.
+     127             : 
+     128             : CUSTOM can be used in combination with \ref DISTANCE to implement variants of the
+     129             : DISTANCE keyword that were present in PLUMED 1.3 and that allowed to compute
+     130             : the distance of a point from a line defined by two other points, or the progression
+     131             : along that line.
+     132             : \plumedfile
+     133             : # take center of atoms 1 to 10 as reference point 1
+     134             : p1: CENTER ATOMS=1-10
+     135             : # take center of atoms 11 to 20 as reference point 2
+     136             : p2: CENTER ATOMS=11-20
+     137             : # take center of atoms 21 to 30 as reference point 3
+     138             : p3: CENTER ATOMS=21-30
+     139             : 
+     140             : # compute distances
+     141             : d12: DISTANCE ATOMS=p1,p2
+     142             : d13: DISTANCE ATOMS=p1,p3
+     143             : d23: DISTANCE ATOMS=p2,p3
+     144             : 
+     145             : # compute progress variable of the projection of point p3
+     146             : # along the vector joining p1 and p2
+     147             : # notice that progress is measured from the middle point
+     148             : onaxis: CUSTOM ARG=d13,d23,d12 FUNC=(0.5*(y^2-x^2)/z) PERIODIC=NO
+     149             : 
+     150             : # compute between point p3 and the vector joining p1 and p2
+     151             : 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
+     152             : 
+     153             : PRINT ARG=onaxis,fromaxis
+     154             : 
+     155             : \endplumedfile
+     156             : 
+     157             : Notice that these equations have been used to combine \ref RMSD
+     158             : from different snapshots of a protein so as to define
+     159             : progression (S) and distance (Z) variables \cite perez2015atp.
+     160             : 
+     161             : 
+     162             : */
+     163             : //+ENDPLUMEDOC
+     164             : 
+     165             : //+PLUMEDOC FUNCTION MATHEVAL_SCALAR
+     166             : /*
+     167             : Calculate a function of a set of input scalars
+     168             : 
+     169             : See \ref MATHEVAL
+     170             : 
+     171             : \par Examples
+     172             : 
+     173             : */
+     174             : //+ENDPLUMEDOC
+     175             : 
+     176             : //+PLUMEDOC FUNCTION CUSTOM_SCALAR
+     177             : /*
+     178             : Calculate a function of a set of input scalars
+     179             : 
+     180             : See \ref CUSTOM
+     181             : 
+     182             : \par Examples
+     183             : 
+     184             : */
+     185             : //+ENDPLUMEDOC
+     186             : 
+     187             : //+PLUMEDOC FUNCTION MATHEVAL_VECTOR
+     188             : /*
+     189             : Calculate a function of a set of input vectors elementwise
+     190             : 
+     191             : See \ref MATHEVAL
+     192             : 
+     193             : \par Examples
+     194             : 
+     195             : */
+     196             : //+ENDPLUMEDOC
+     197             : 
+     198             : //+PLUMEDOC FUNCTION CUSTOM_VECTOR
+     199             : /*
+     200             : Calculate a function of a set of input vectors elementwise
+     201             : 
+     202             : See \ref CUSTOM
+     203             : 
+     204             : \par Examples
+     205             : 
+     206             : */
+     207             : //+ENDPLUMEDOC
+     208             : 
+     209             : typedef FunctionShortcut<Custom> CustomShortcut;
+     210             : PLUMED_REGISTER_ACTION(CustomShortcut,"CUSTOM")
+     211             : PLUMED_REGISTER_ACTION(CustomShortcut,"MATHEVAL")
+     212             : typedef FunctionOfScalar<Custom> ScalarCustom;
+     213             : PLUMED_REGISTER_ACTION(ScalarCustom,"CUSTOM_SCALAR")
+     214             : PLUMED_REGISTER_ACTION(ScalarCustom,"MATHEVAL_SCALAR")
+     215             : typedef FunctionOfVector<Custom> VectorCustom;
+     216             : PLUMED_REGISTER_ACTION(VectorCustom,"CUSTOM_VECTOR")
+     217             : PLUMED_REGISTER_ACTION(VectorCustom,"MATHEVAL_VECTOR")
+     218             : 
+     219             : //+PLUMEDOC FUNCTION MATHEVAL
+     220             : /*
+     221             : An alias to the \ref CUSTOM function.
+     222             : 
+     223             : This alias is kept in order to maintain compatibility with previous PLUMED versions.
+     224             : However, notice that as of PLUMED 2.5 the libmatheval library is not linked anymore,
+     225             : and the \ref MATHEVAL function is implemented using the Lepton library.
+     226             : 
+     227             : \par Examples
+     228             : 
+     229             : Just replace \ref CUSTOM with \ref MATHEVAL.
+     230             : 
+     231             : \plumedfile
+     232             : d: DISTANCE ATOMS=10,15
+     233             : m: MATHEVAL ARG=d FUNC=0.5*step(0.5-x)+x*step(x-0.5) PERIODIC=NO
+     234             : # check the function you are applying:
+     235             : PRINT ARG=d,m FILE=checkme
+     236             : RESTRAINT ARG=d AT=0.5 KAPPA=10.0
+     237             : \endplumedfile
+     238             : (see also \ref DISTANCE, \ref PRINT, and \ref RESTRAINT)
+     239             : 
+     240             : */
+     241             : //+ENDPLUMEDOC
+     242             : 
+     243        6019 : void Custom::registerKeywords(Keywords& keys) {
+     244        6019 :   keys.use("PERIODIC");
+     245       12038 :   keys.add("compulsory","FUNC","the function you wish to evaluate");
+     246       12038 :   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.");
+     247        6019 : }
+     248             : 
+     249        2982 : void Custom::read( ActionWithArguments* action ) {
+     250             :   // Read in the variables
+     251        8946 :   std::vector<std::string> var; parseVector(action,"VAR",var); parse(action,"FUNC",func);
+     252        2982 :   if(var.size()==0) {
+     253        2923 :     var.resize(action->getNumberOfArguments());
+     254        2923 :     if(var.size()>3) action->error("Using more than 3 arguments you should explicitly write their names with VAR");
+     255        2923 :     if(var.size()>0) var[0]="x";
+     256        2923 :     if(var.size()>1) var[1]="y";
+     257        2923 :     if(var.size()>2) var[2]="z";
+     258             :   }
+     259        2982 :   if(var.size()!=action->getNumberOfArguments()) action->error("Size of VAR array should be the same as number of arguments");
+     260             :   // Check for operations that are not multiplication (this can probably be done much more cleverly)
+     261        2982 :   bool onlymultiplication = func.find("*")!=std::string::npos;
+     262             :   // Find first bracket in expression
+     263        2982 :   if( func.find("(")!=std::string::npos ) {
+     264        1590 :     std::size_t br = func.find_first_of("("); std::string subexpr=func.substr(0,br); onlymultiplication = func.find("*")!=std::string::npos;
+     265        1590 :     if( subexpr.find("/")!=std::string::npos ) { std::size_t sl = func.find_first_of("/"); std::string aa = subexpr.substr(0,sl); subexpr=aa; }
+     266        1590 :     if( subexpr.find("+")!=std::string::npos || subexpr.find("-")!=std::string::npos ) onlymultiplication=false;
+     267             :     // Now work out which vars are in multiplication
+     268        1483 :     if( onlymultiplication ) {
+     269        2293 :       for(unsigned i=0; i<var.size(); ++i) {
+     270        1451 :         if( subexpr.find(var[i])!=std::string::npos &&
+     271         316 :             action->getPntrToArgument(i)->isDerivativeZeroWhenValueIsZero() ) check_multiplication_vars.push_back(i);
+     272             :       }
+     273             :     }
+     274        1392 :   } else if( func.find("/")!=std::string::npos ) {
+     275         816 :     onlymultiplication=true; if( func.find("+")!=std::string::npos || func.find("-")!=std::string::npos ) onlymultiplication=false;
+     276             :     if( onlymultiplication ) {
+     277         815 :       std::size_t br = func.find_first_of("/"); std::string subexpr=func.substr(0,br);
+     278        2267 :       for(unsigned i=0; i<var.size(); ++i) {
+     279        1452 :         if( subexpr.find(var[i])!=std::string::npos &&
+     280          30 :             action->getPntrToArgument(i)->isDerivativeZeroWhenValueIsZero() ) check_multiplication_vars.push_back(i);
+     281             :       }
+     282             :     }
+     283         576 :   } else if( func.find("+")!=std::string::npos || func.find("-")!=std::string::npos ) {
+     284             :     onlymultiplication=false;
+     285             :   } else {
+     286        1021 :     for(unsigned i=0; i<var.size(); ++i) {
+     287         620 :       if( action->getPntrToArgument(i)->isDerivativeZeroWhenValueIsZero() ) check_multiplication_vars.push_back(i);
+     288             :     }
+     289             :   }
+     290        2982 :   if( check_multiplication_vars.size()>0 ) {
+     291         449 :     action->log.printf("  optimizing implementation as function only involves multiplication \n");
+     292             :   }
+     293             : 
+     294        2982 :   action->log.printf("  with function : %s\n",func.c_str());
+     295        2982 :   action->log.printf("  with variables :");
+     296        7777 :   for(unsigned i=0; i<var.size(); i++) action->log.printf(" %s",var[i].c_str());
+     297        2982 :   action->log.printf("\n"); function.set( func, var, action );
+     298        2982 :   std::vector<double> zeros( action->getNumberOfArguments(), 0 ); double fval = abs(function.evaluate(zeros));
+     299        2982 :   zerowhenallzero=(fval<epsilon );
+     300        2982 :   if( zerowhenallzero ) action->log.printf("  not calculating when all arguments are zero \n");
+     301        2982 : }
+     302             : 
+     303           5 : std::string Custom::getGraphInfo( const std::string& name ) const {
+     304          10 :   return FunctionTemplateBase::getGraphInfo( name ) + + "\n" + "FUNC=" + func;
+     305             : }
+     306             : 
+     307        1810 : bool Custom::getDerivativeZeroIfValueIsZero() const {
+     308        1810 :   return check_multiplication_vars.size()>0;
+     309             : }
+     310             : 
+     311         966 : std::vector<Value*> Custom::getArgumentsToCheck( const std::vector<Value*>& args ) {
+     312         966 :   std::vector<Value*> fargs( check_multiplication_vars.size() );
+     313        2093 :   for(unsigned i=0; i<check_multiplication_vars.size(); ++i) fargs[i] = args[check_multiplication_vars[i]];
+     314         966 :   return fargs;
+     315             : }
+     316             : 
+     317    20476587 : void Custom::calc( const ActionWithArguments* action, const std::vector<double>& args, std::vector<double>& vals, Matrix<double>& derivatives ) const {
+     318    20476587 :   if( args.size()>1 ) {
+     319             :     bool allzero=false;
+     320    15780962 :     if( check_multiplication_vars.size()>0 ) {
+     321    17313345 :       for(unsigned i=0; i<check_multiplication_vars.size(); ++i) {
+     322    10885579 :         if( fabs(args[check_multiplication_vars[i]])<epsilon ) { allzero=true; break; }
+     323             :       }
+     324     5142171 :     } else if( zerowhenallzero ) {
+     325     2860794 :       allzero=(fabs(args[0])<epsilon);
+     326     3302058 :       for(unsigned i=1; i<args.size(); ++i) {
+     327     3154874 :         if( fabs(args[i])>epsilon ) { allzero=false; break; }
+     328             :       }
+     329             :     }
+     330    13499585 :     if( allzero ) {
+     331    13364017 :       vals[0]=0; for(unsigned i=0; i<args.size(); i++) derivatives(0,i) = 0.0;
+     332             :       return;
+     333             :     }
+     334             :   }
+     335    16122318 :   vals[0] = function.evaluate( args );
+     336    16122318 :   if( !noderiv ) {
+     337    47264329 :     for(unsigned i=0; i<args.size(); i++) derivatives(0,i) = function.evaluateDeriv( i, args );
+     338             :   }
+     339             : }
+     340             : 
+     341             : }
+     342             : }
+     343             : 
+     344             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Ensemble.cpp.func-sort-c.html b/coverage/function/Ensemble.cpp.func-sort-c.html new file mode 100644 index 000000000000..a17eebdd59f4 --- /dev/null +++ b/coverage/function/Ensemble.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - function/Ensemble.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - Ensemble.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:8012763.0 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function8EnsembleC2ERKNS_13ActionOptionsE0
_ZN4PLMD8function8EnsembleC1ERKNS_13ActionOptionsE27
_ZN4PLMD8function8Ensemble16registerKeywordsERNS_8KeywordsE29
_ZN4PLMD8function8Ensemble9calculateEv125
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Ensemble.cpp.func.html b/coverage/function/Ensemble.cpp.func.html new file mode 100644 index 000000000000..3d48eabb1a52 --- /dev/null +++ b/coverage/function/Ensemble.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - function/Ensemble.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - Ensemble.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:8012763.0 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function8Ensemble16registerKeywordsERNS_8KeywordsE29
_ZN4PLMD8function8Ensemble9calculateEv125
_ZN4PLMD8function8EnsembleC1ERKNS_13ActionOptionsE27
_ZN4PLMD8function8EnsembleC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Ensemble.cpp.gcov.html b/coverage/function/Ensemble.cpp.gcov.html new file mode 100644 index 000000000000..3a476c8da676 --- /dev/null +++ b/coverage/function/Ensemble.cpp.gcov.html @@ -0,0 +1,340 @@ + + + + + + + + LCOV - plumed test coverage - function/Ensemble.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - Ensemble.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:8012763.0 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2014-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "Function.h"
+      23             : #include "tools/Communicator.h"
+      24             : #include "core/ActionRegister.h"
+      25             : #include "core/PlumedMain.h"
+      26             : 
+      27             : namespace PLMD {
+      28             : namespace function {
+      29             : 
+      30             : //+PLUMEDOC FUNCTION ENSEMBLE
+      31             : /*
+      32             : Calculates the replica averaging of a collective variable over multiple replicas.
+      33             : 
+      34             : Each collective variable is averaged separately and stored in a component labelled <em>label</em>.cvlabel.
+      35             : 
+      36             : \par Examples
+      37             : 
+      38             : The following input tells plumed to calculate the distance between atoms 3 and 5
+      39             : and the average it over the available replicas.
+      40             : \plumedfile
+      41             : dist: DISTANCE ATOMS=3,5
+      42             : ens: ENSEMBLE ARG=dist
+      43             : PRINT ARG=dist,ens.dist
+      44             : \endplumedfile
+      45             : 
+      46             : */
+      47             : //+ENDPLUMEDOC
+      48             : 
+      49             : 
+      50             : class Ensemble :
+      51             :   public Function
+      52             : {
+      53             :   unsigned ens_dim;
+      54             :   unsigned my_repl;
+      55             :   unsigned narg;
+      56             :   bool     master;
+      57             :   bool     do_reweight;
+      58             :   bool     do_moments;
+      59             :   bool     do_central;
+      60             :   bool     do_powers;
+      61             :   double   kbt;
+      62             :   double   moment;
+      63             :   double   power;
+      64             : public:
+      65             :   explicit Ensemble(const ActionOptions&);
+      66             :   void     calculate() override;
+      67             :   static void registerKeywords(Keywords& keys);
+      68             : };
+      69             : 
+      70             : 
+      71             : PLUMED_REGISTER_ACTION(Ensemble,"ENSEMBLE")
+      72             : 
+      73          29 : void Ensemble::registerKeywords(Keywords& keys) {
+      74          29 :   Function::registerKeywords(keys);
+      75          29 :   keys.use("ARG");
+      76          58 :   keys.addFlag("REWEIGHT",false,"simple REWEIGHT using the latest ARG as energy");
+      77          58 :   keys.addFlag("CENTRAL",false,"calculate a central moment instead of a standard moment");
+      78          58 :   keys.add("optional","TEMP","the system temperature - this is only needed if you are reweighting");
+      79          58 :   keys.add("optional","MOMENT","the moment you want to calculate in alternative to the mean or the variance");
+      80          58 :   keys.add("optional","POWER","the power of the mean (and moment)");
+      81          29 :   ActionWithValue::useCustomisableComponents(keys);
+      82          29 : }
+      83             : 
+      84          27 : Ensemble::Ensemble(const ActionOptions&ao):
+      85             :   Action(ao),
+      86             :   Function(ao),
+      87          27 :   do_reweight(false),
+      88          27 :   do_moments(false),
+      89          27 :   do_central(false),
+      90          27 :   do_powers(false),
+      91          27 :   kbt(-1.0),
+      92          27 :   moment(0),
+      93          27 :   power(0)
+      94             : {
+      95          27 :   parseFlag("REWEIGHT", do_reweight);
+      96          27 :   if(do_reweight) {
+      97          12 :     kbt=getkBT();
+      98          12 :     if(kbt==0.0) error("Unless the MD engine passes the temperature to plumed, with REWEIGHT you must specify TEMP");
+      99          30 :   } else { double temp=0.0; parse("TEMP",temp); }
+     100             : 
+     101          27 :   parse("MOMENT",moment);
+     102          27 :   if(moment==1) error("MOMENT can be any number but for 0 and 1");
+     103          27 :   if(moment!=0) do_moments=true;
+     104          27 :   parseFlag("CENTRAL", do_central);
+     105          27 :   if(!do_moments&&do_central) error("To calculate a CENTRAL moment you need to define for which MOMENT");
+     106             : 
+     107          27 :   parse("POWER",power);
+     108          27 :   if(power==1) error("POWER can be any number but for 0 and 1");
+     109          27 :   if(power!=0) do_powers=true;
+     110             : 
+     111          27 :   checkRead();
+     112             : 
+     113          27 :   master = (comm.Get_rank()==0);
+     114          27 :   ens_dim=0;
+     115          27 :   my_repl=0;
+     116          27 :   if(master) {
+     117          17 :     ens_dim=multi_sim_comm.Get_size();
+     118          17 :     my_repl=multi_sim_comm.Get_rank();
+     119             :   }
+     120          27 :   comm.Bcast(ens_dim,0);
+     121          27 :   comm.Bcast(my_repl,0);
+     122          27 :   if(ens_dim<2) log.printf("WARNING: ENSEMBLE with one replica is not doing any averaging!\n");
+     123             : 
+     124             :   // prepare output components, the number depending on reweighing or not
+     125          27 :   narg = getNumberOfArguments();
+     126          27 :   if(do_reweight) narg--;
+     127             : 
+     128             :   // these are the averages
+     129        3044 :   for(unsigned i=0; i<narg; i++) {
+     130        3017 :     std::string s=getPntrToArgument(i)->getName();
+     131        3017 :     addComponentWithDerivatives(s);
+     132        3017 :     getPntrToComponent(i)->setNotPeriodic();
+     133             :   }
+     134             :   // these are the moments
+     135          27 :   if(do_moments) {
+     136           0 :     for(unsigned i=0; i<narg; i++) {
+     137           0 :       std::string s=getPntrToArgument(i)->getName()+"_m";
+     138           0 :       addComponentWithDerivatives(s);
+     139           0 :       getPntrToComponent(i+narg)->setNotPeriodic();
+     140             :     }
+     141             :   }
+     142             : 
+     143          27 :   log.printf("  averaging over %u replicas.\n", ens_dim);
+     144          27 :   if(do_reweight) log.printf("  doing simple REWEIGHT using the latest ARGUMENT as energy.\n");
+     145          27 :   if(do_moments&&!do_central)  log.printf("  calculating also the %lf standard moment\n", moment);
+     146          27 :   if(do_moments&&do_central)   log.printf("  calculating also the %lf central moment\n", moment);
+     147          27 :   if(do_powers)                log.printf("  calculating the %lf power of the mean (and moment)\n", power);
+     148          27 : }
+     149             : 
+     150         125 : void Ensemble::calculate() {
+     151             :   double norm = 0.0;
+     152         125 :   double fact = 0.0;
+     153             : 
+     154             :   // calculate the weights either from BIAS
+     155         125 :   if(do_reweight) {
+     156             :     std::vector<double> bias;
+     157           0 :     bias.resize(ens_dim);
+     158           0 :     if(master) {
+     159           0 :       bias[my_repl] = getArgument(narg);
+     160           0 :       if(ens_dim>1) multi_sim_comm.Sum(&bias[0], ens_dim);
+     161             :     }
+     162           0 :     comm.Sum(&bias[0], ens_dim);
+     163           0 :     const double maxbias = *(std::max_element(bias.begin(), bias.end()));
+     164           0 :     for(unsigned i=0; i<ens_dim; ++i) {
+     165           0 :       bias[i] = exp((bias[i]-maxbias)/kbt);
+     166           0 :       norm += bias[i];
+     167             :     }
+     168           0 :     fact = bias[my_repl]/norm;
+     169             :     // or arithmetic ones
+     170             :   } else {
+     171         125 :     norm = static_cast<double>(ens_dim);
+     172         125 :     fact = 1.0/norm;
+     173             :   }
+     174             : 
+     175         125 :   const double fact_kbt = fact/kbt;
+     176             : 
+     177         125 :   std::vector<double> mean(narg);
+     178         125 :   std::vector<double> dmean(narg,fact);
+     179             :   // calculate the mean
+     180         125 :   if(master) {
+     181        2106 :     for(unsigned i=0; i<narg; ++i) mean[i] = fact*getArgument(i);
+     182          99 :     if(ens_dim>1) multi_sim_comm.Sum(&mean[0], narg);
+     183             :   }
+     184         125 :   comm.Sum(&mean[0], narg);
+     185             : 
+     186             :   std::vector<double> v_moment, dv_moment;
+     187             :   // calculate other moments
+     188         125 :   if(do_moments) {
+     189           0 :     v_moment.resize(narg);
+     190           0 :     dv_moment.resize(narg);
+     191             :     // standard moment
+     192           0 :     if(!do_central) {
+     193           0 :       if(master) {
+     194           0 :         for(unsigned i=0; i<narg; ++i) {
+     195           0 :           const double tmp = fact*std::pow(getArgument(i),moment-1);
+     196           0 :           v_moment[i]      = tmp*getArgument(i);
+     197           0 :           dv_moment[i]     = moment*tmp;
+     198             :         }
+     199           0 :         if(ens_dim>1) multi_sim_comm.Sum(&v_moment[0], narg);
+     200             :       } else {
+     201           0 :         for(unsigned i=0; i<narg; ++i) {
+     202           0 :           const double tmp = fact*std::pow(getArgument(i),moment-1);
+     203           0 :           dv_moment[i]     = moment*tmp;
+     204             :         }
+     205             :       }
+     206             :       // central moment
+     207             :     } else {
+     208           0 :       if(master) {
+     209           0 :         for(unsigned i=0; i<narg; ++i) {
+     210           0 :           const double tmp = std::pow(getArgument(i)-mean[i],moment-1);
+     211           0 :           v_moment[i]      = fact*tmp*(getArgument(i)-mean[i]);
+     212           0 :           dv_moment[i]     = moment*tmp*(fact-fact/norm);
+     213             :         }
+     214           0 :         if(ens_dim>1) multi_sim_comm.Sum(&v_moment[0], narg);
+     215             :       } else {
+     216           0 :         for(unsigned i=0; i<narg; ++i) {
+     217           0 :           const double tmp = std::pow(getArgument(i)-mean[i],moment-1);
+     218           0 :           dv_moment[i]     = moment*tmp*(fact-fact/norm);
+     219             :         }
+     220             :       }
+     221             :     }
+     222           0 :     comm.Sum(&v_moment[0], narg);
+     223             :   }
+     224             : 
+     225             :   // calculate powers of moments
+     226         125 :   if(do_powers) {
+     227          72 :     for(unsigned i=0; i<narg; ++i) {
+     228          48 :       const double tmp1 = std::pow(mean[i],power-1);
+     229          48 :       mean[i]          *= tmp1;
+     230          48 :       dmean[i]         *= power*tmp1;
+     231          48 :       if(do_moments) {
+     232           0 :         const double tmp2 = std::pow(v_moment[i],power-1);
+     233           0 :         v_moment[i]      *= tmp2;
+     234           0 :         dv_moment[i]     *= power*tmp2;
+     235             :       }
+     236             :     }
+     237             :   }
+     238             : 
+     239             :   // set components
+     240        3358 :   for(unsigned i=0; i<narg; ++i) {
+     241             :     // set mean
+     242        3233 :     Value* v=getPntrToComponent(i);
+     243        3233 :     v->set(mean[i]);
+     244        3233 :     setDerivative(v, i, dmean[i]);
+     245        3233 :     if(do_reweight) {
+     246           0 :       const double w_tmp = fact_kbt*(getArgument(i) - mean[i]);
+     247           0 :       setDerivative(v, narg, w_tmp);
+     248             :     }
+     249        3233 :     if(do_moments) {
+     250             :       // set moments
+     251           0 :       Value* u=getPntrToComponent(i+narg);
+     252           0 :       u->set(v_moment[i]);
+     253           0 :       setDerivative(u, i, dv_moment[i]);
+     254           0 :       if(do_reweight) {
+     255           0 :         const double w_tmp = fact_kbt*(pow(getArgument(i),moment) - v_moment[i]);
+     256           0 :         setDerivative(u, narg, w_tmp);
+     257             :       }
+     258             :     }
+     259             :   }
+     260         125 : }
+     261             : 
+     262             : }
+     263             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/FuncPathGeneral.cpp.func-sort-c.html b/coverage/function/FuncPathGeneral.cpp.func-sort-c.html new file mode 100644 index 000000000000..e1a8b2385ca2 --- /dev/null +++ b/coverage/function/FuncPathGeneral.cpp.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - function/FuncPathGeneral.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - FuncPathGeneral.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10012977.5 %
Date:2024-04-19 12:12:35Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function15FuncPathGeneralC2ERKNS_13ActionOptionsE0
_ZN4PLMD8function15FuncPathGeneral13loadReferenceEv1
_ZN4PLMD8function15FuncPathGeneralC1ERKNS_13ActionOptionsE1
_ZN4PLMD8function15FuncPathGeneral16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD8function15FuncPathGeneral7prepareEv175001
_ZN4PLMD8function15FuncPathGeneral9calculateEv175001
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/FuncPathGeneral.cpp.func.html b/coverage/function/FuncPathGeneral.cpp.func.html new file mode 100644 index 000000000000..5461e8532c15 --- /dev/null +++ b/coverage/function/FuncPathGeneral.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - function/FuncPathGeneral.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - FuncPathGeneral.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10012977.5 %
Date:2024-04-19 12:12:35Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function15FuncPathGeneral13loadReferenceEv1
_ZN4PLMD8function15FuncPathGeneral16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD8function15FuncPathGeneral7prepareEv175001
_ZN4PLMD8function15FuncPathGeneral9calculateEv175001
_ZN4PLMD8function15FuncPathGeneralC1ERKNS_13ActionOptionsE1
_ZN4PLMD8function15FuncPathGeneralC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/FuncPathGeneral.cpp.gcov.html b/coverage/function/FuncPathGeneral.cpp.gcov.html new file mode 100644 index 000000000000..d9573217369a --- /dev/null +++ b/coverage/function/FuncPathGeneral.cpp.gcov.html @@ -0,0 +1,418 @@ + + + + + + + + LCOV - plumed test coverage - function/FuncPathGeneral.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - FuncPathGeneral.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10012977.5 %
Date:2024-04-19 12:12:35Functions:5683.3 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function11FuncPathMSDC2ERKNS_13ActionOptionsE0
_ZN4PLMD8function11FuncPathMSDC1ERKNS_13ActionOptionsE2
_ZN4PLMD8function11FuncPathMSD16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD8function11FuncPathMSD7prepareEv1092
_ZN4PLMD8function11FuncPathMSD9calculateEv1092
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/FuncPathMSD.cpp.func.html b/coverage/function/FuncPathMSD.cpp.func.html new file mode 100644 index 000000000000..a4e9da8b7c0e --- /dev/null +++ b/coverage/function/FuncPathMSD.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - function/FuncPathMSD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - FuncPathMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:748092.5 %
Date:2024-04-19 12:12:35Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function11FuncPathMSD16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD8function11FuncPathMSD7prepareEv1092
_ZN4PLMD8function11FuncPathMSD9calculateEv1092
_ZN4PLMD8function11FuncPathMSDC1ERKNS_13ActionOptionsE2
_ZN4PLMD8function11FuncPathMSDC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/FuncPathMSD.cpp.gcov.html b/coverage/function/FuncPathMSD.cpp.gcov.html new file mode 100644 index 000000000000..d696a4d8ee48 --- /dev/null +++ b/coverage/function/FuncPathMSD.cpp.gcov.html @@ -0,0 +1,445 @@ + + + + + + + + LCOV - plumed test coverage - function/FuncPathMSD.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - FuncPathMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:748092.5 %
Date:2024-04-19 12:12:35Functions:4580.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "Function.h"
+      24             : #include "core/ActionRegister.h"
+      25             : 
+      26             : namespace PLMD {
+      27             : namespace function {
+      28             : 
+      29             : //+PLUMEDOC FUNCTION FUNCPATHMSD
+      30             : /*
+      31             : This function calculates path collective variables.
+      32             : 
+      33             : This is the Path Collective Variables implementation
+      34             : ( see \cite brand07 ).
+      35             : This variable computes the progress along a given set of frames that is provided
+      36             : in input ("s" component) and the distance from them ("z" component).
+      37             : It is a function of mean squared displacement that are obtained by the joint use of mean squared displacement variables with the SQUARED flag
+      38             : (see below).
+      39             : 
+      40             : \par Examples
+      41             : 
+      42             : Here below is a case where you have defined three frames and you want to
+      43             : calculate the progress along the path and the distance from it in p1
+      44             : 
+      45             : \plumedfile
+      46             : t1: RMSD REFERENCE=frame_1.pdb TYPE=OPTIMAL SQUARED
+      47             : t2: RMSD REFERENCE=frame_21.pdb TYPE=OPTIMAL SQUARED
+      48             : t3: RMSD REFERENCE=frame_42.pdb TYPE=OPTIMAL SQUARED
+      49             : p1: FUNCPATHMSD ARG=t1,t2,t3 LAMBDA=500.0
+      50             : PRINT ARG=t1,t2,t3,p1.s,p1.z STRIDE=1 FILE=colvar FMT=%8.4f
+      51             : \endplumedfile
+      52             : 
+      53             : For this input you would then define the position of the reference coordinates in three separate pdb files.  The contents of the
+      54             : file frame_1.pdb are shown below:
+      55             : 
+      56             : \auxfile{frame_1.pdb}
+      57             : ATOM      1  CL  ALA     1      -3.171   0.295   2.045  1.00  1.00
+      58             : ATOM      5  CLP ALA     1      -1.819  -0.143   1.679  1.00  1.00
+      59             : ATOM      6  OL  ALA     1      -1.177  -0.889   2.401  1.00  1.00
+      60             : ATOM      7  NL  ALA     1      -1.313   0.341   0.529  1.00  1.00
+      61             : ATOM      8  HL  ALA     1      -1.845   0.961  -0.011  1.00  1.00
+      62             : END
+      63             : \endauxfile
+      64             : 
+      65             : This is then frame.21.pdb:
+      66             : 
+      67             : \auxfile{frame_21.pdb}
+      68             : ATOM      1  CL  ALA     1      -3.089   1.850   1.546  1.00  1.00
+      69             : ATOM      5  CLP ALA     1      -1.667   1.457   1.629  1.00  1.00
+      70             : ATOM      6  OL  ALA     1      -0.974   1.868   2.533  1.00  1.00
+      71             : ATOM      7  NL  ALA     1      -1.204   0.683   0.642  1.00  1.00
+      72             : ATOM      8  HL  ALA     1      -1.844   0.360  -0.021  1.00  1.00
+      73             : END
+      74             : \endauxfile
+      75             : 
+      76             : and finally this is frame_42.pdb:
+      77             : 
+      78             : \auxfile{frame_42.pdb}
+      79             : ATOM      1  CL  ALA     1      -3.257   1.605   1.105  1.00  1.00
+      80             : ATOM      5  CLP ALA     1      -1.941   1.459   0.447  1.00  1.00
+      81             : ATOM      6  OL  ALA     1      -1.481   2.369  -0.223  1.00  1.00
+      82             : ATOM      7  NL  ALA     1      -1.303   0.291   0.647  1.00  1.00
+      83             : ATOM      8  HL  ALA     1      -1.743  -0.379   1.229  1.00  1.00
+      84             : END
+      85             : \endauxfile
+      86             : 
+      87             : This second example shows how to define a PATH in \ref CONTACTMAP space:
+      88             : 
+      89             : \plumedfile
+      90             : CONTACTMAP ...
+      91             : ATOMS1=1,2 REFERENCE1=0.1
+      92             : ATOMS2=3,4 REFERENCE2=0.5
+      93             : ATOMS3=4,5 REFERENCE3=0.25
+      94             : ATOMS4=5,6 REFERENCE4=0.0
+      95             : SWITCH={RATIONAL R_0=1.5}
+      96             : LABEL=c1
+      97             : CMDIST
+      98             : ... CONTACTMAP
+      99             : 
+     100             : CONTACTMAP ...
+     101             : ATOMS1=1,2 REFERENCE1=0.3
+     102             : ATOMS2=3,4 REFERENCE2=0.9
+     103             : ATOMS3=4,5 REFERENCE3=0.45
+     104             : ATOMS4=5,6 REFERENCE4=0.1
+     105             : SWITCH={RATIONAL R_0=1.5}
+     106             : LABEL=c2
+     107             : CMDIST
+     108             : ... CONTACTMAP
+     109             : 
+     110             : CONTACTMAP ...
+     111             : ATOMS1=1,2 REFERENCE1=1.0
+     112             : ATOMS2=3,4 REFERENCE2=1.0
+     113             : ATOMS3=4,5 REFERENCE3=1.0
+     114             : ATOMS4=5,6 REFERENCE4=1.0
+     115             : SWITCH={RATIONAL R_0=1.5}
+     116             : LABEL=c3
+     117             : CMDIST
+     118             : ... CONTACTMAP
+     119             : 
+     120             : p1: FUNCPATHMSD ARG=c1,c2,c3 LAMBDA=500.0
+     121             : PRINT ARG=c1,c2,c3,p1.s,p1.z STRIDE=1 FILE=colvar FMT=%8.4f
+     122             : \endplumedfile
+     123             : 
+     124             : This third example shows how to define a PATH in \ref PIV space:
+     125             : 
+     126             : \plumedfile
+     127             : PIV ...
+     128             : LABEL=c1
+     129             : PRECISION=1000
+     130             : NLIST
+     131             : REF_FILE=Ref1.pdb
+     132             : PIVATOMS=2
+     133             : ATOMTYPES=A,B
+     134             : ONLYDIRECT
+     135             : SFACTOR=1.0,0.2
+     136             : SORT=1,1
+     137             : SWITCH1={RATIONAL R_0=0.6 MM=12 NN=4}
+     138             : SWITCH2={RATIONAL R_0=0.5 MM=10 NN=5}
+     139             : NL_CUTOFF=1.2,1.2
+     140             : NL_STRIDE=10,10
+     141             : NL_SKIN=0.1,0.1
+     142             : ... PIV
+     143             : PIV ...
+     144             : LABEL=c2
+     145             : PRECISION=1000
+     146             : NLIST
+     147             : REF_FILE=Ref2.pdb
+     148             : PIVATOMS=2
+     149             : ATOMTYPES=A,B
+     150             : ONLYDIRECT
+     151             : SFACTOR=1.0,0.2
+     152             : SORT=1,1
+     153             : SWITCH1={RATIONAL R_0=0.6 MM=12 NN=4}
+     154             : SWITCH2={RATIONAL R_0=0.4 MM=10 NN=5}
+     155             : NL_CUTOFF=1.2,1.2
+     156             : NL_STRIDE=10,10
+     157             : NL_SKIN=0.1,0.1
+     158             : ... PIV
+     159             : 
+     160             : p1: FUNCPATHMSD ARG=c1,c2 LAMBDA=0.180338
+     161             : METAD ARG=p1.s,p1.z SIGMA=0.01,0.2 HEIGHT=0.8 PACE=500   LABEL=res
+     162             : PRINT ARG=c1,c2,p1.s,p1.z,res.bias STRIDE=500  FILE=colvar FMT=%15.6f
+     163             : \endplumedfile
+     164             : 
+     165             : */
+     166             : //+ENDPLUMEDOC
+     167             : 
+     168             : class FuncPathMSD : public Function {
+     169             :   double lambda;
+     170             :   int neigh_size;
+     171             :   double neigh_stride;
+     172             :   std::vector< std::pair<Value *,double> > neighpair;
+     173             :   std::map<Value *,double > indexmap; // use double to allow isomaps
+     174             :   std::vector <Value*> allArguments;
+     175             : // XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+     176             : // this below is useful when one wants to sort a vector of double and have back the order
+     177             : // XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+     178             : // create a custom sorter
+     179             :   typedef std::vector<double>::const_iterator myiter;
+     180             :   struct ordering {
+     181             :     bool operator ()(std::pair<unsigned, myiter> const& a, std::pair<unsigned, myiter> const& b) {
+     182             :       return *(a.second) < *(b.second);
+     183             :     }
+     184             :   };
+     185             : // sorting utility
+     186             :   std::vector<int> increasingOrder( std::vector<double> &v) {
+     187             :     // make a pair
+     188             :     std::vector< std::pair<unsigned, myiter> > order(v.size());
+     189             :     unsigned n = 0;
+     190             :     for (myiter it = v.begin(); it != v.end(); ++it, ++n) {
+     191             :       order[n] = make_pair(n, it); // note: heere i do not put the values but the addresses that point to the value
+     192             :     }
+     193             :     // now sort according the second value
+     194             :     std::sort(order.begin(), order.end(), ordering());
+     195             :     std::vector<int> vv(v.size()); n=0;
+     196             :     for (const auto & it : order) {
+     197             :       vv[n]=it.first; n++;
+     198             :     }
+     199             :     return vv;
+     200             :   }
+     201             : // XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+     202             : // XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+     203             : 
+     204             :   struct pairordering {
+     205             :     bool operator ()(std::pair<Value *, double> const& a, std::pair<Value*, double> const& b) {
+     206         437 :       return (a).second > (b).second;
+     207             :     }
+     208             :   };
+     209             : 
+     210             : public:
+     211             :   explicit FuncPathMSD(const ActionOptions&);
+     212             : // active methods:
+     213             :   void calculate() override;
+     214             :   void prepare() override;
+     215             :   static void registerKeywords(Keywords& keys);
+     216             : };
+     217             : 
+     218             : PLUMED_REGISTER_ACTION(FuncPathMSD,"FUNCPATHMSD")
+     219             : 
+     220           4 : void FuncPathMSD::registerKeywords(Keywords& keys) {
+     221           4 :   Function::registerKeywords(keys);
+     222           4 :   keys.use("ARG");
+     223           8 :   keys.add("compulsory","LAMBDA","the lambda parameter is needed for smoothing, is in the units of plumed");
+     224           8 :   keys.add("optional","NEIGH_SIZE","size of the neighbor list");
+     225           8 :   keys.add("optional","NEIGH_STRIDE","how often the neighbor list needs to be calculated in time units");
+     226           4 :   componentsAreNotOptional(keys);
+     227           8 :   keys.addOutputComponent("s","default","the position on the path");
+     228           8 :   keys.addOutputComponent("z","default","the distance from the path");
+     229           4 : }
+     230           2 : FuncPathMSD::FuncPathMSD(const ActionOptions&ao):
+     231             :   Action(ao),
+     232             :   Function(ao),
+     233           2 :   neigh_size(-1),
+     234           2 :   neigh_stride(-1.)
+     235             : {
+     236             : 
+     237           2 :   parse("LAMBDA",lambda);
+     238           2 :   parse("NEIGH_SIZE",neigh_size);
+     239           2 :   parse("NEIGH_STRIDE",neigh_stride);
+     240           2 :   checkRead();
+     241           2 :   log.printf("  lambda is %f\n",lambda);
+     242             :   // list the action involved and check the type
+     243           2 :   std::string myname=getPntrToArgument(0)->getPntrToAction()->getName();
+     244           2 :   if(myname!="RMSD_SCALAR"&&myname!="CONTACTMAP"&&myname!="DISTANCE"&&myname!="PIV") error("One or more of your arguments is not of RMSD/CONTACTMAP/DISTANCE/PIV type!!!");
+     245           6 :   for(unsigned i=1; i<getNumberOfArguments(); i++) {
+     246             :     // for each value get the name and the label of the corresponding action
+     247           4 :     if( getPntrToArgument(i)->getPntrToAction()->getName()!=myname ) error("mismatch between the types of arguments");
+     248             :   }
+     249           2 :   log.printf("  Consistency check completed! Your path cvs look good!\n");
+     250             :   // do some neighbor printout
+     251           2 :   if(neigh_stride>0. || neigh_size>0) {
+     252           1 :     if(neigh_size>static_cast<int>(getNumberOfArguments())) {
+     253           0 :       log.printf(" List size required ( %d ) is too large: resizing to the maximum number of arg required: %d  \n",neigh_size,getNumberOfArguments());
+     254           0 :       neigh_size=getNumberOfArguments();
+     255             :     }
+     256           1 :     log.printf("  Neighbor list enabled: \n");
+     257           1 :     log.printf("                size   :  %d elements\n",neigh_size);
+     258           1 :     log.printf("                stride :  %f time \n",neigh_stride);
+     259             :   } else {
+     260           1 :     log.printf("  Neighbor list NOT enabled \n");
+     261             :   }
+     262             : 
+     263           4 :   addComponentWithDerivatives("s"); componentIsNotPeriodic("s");
+     264           4 :   addComponentWithDerivatives("z"); componentIsNotPeriodic("z");
+     265             : 
+     266             :   // now backup the arguments
+     267           8 :   for(unsigned i=0; i<getNumberOfArguments(); i++)allArguments.push_back(getPntrToArgument(i));
+     268             :   double i=1.;
+     269           8 :   for(const auto & it : allArguments) {
+     270           6 :     indexmap[it]=i; i+=1.;
+     271             :   }
+     272             : 
+     273           2 : }
+     274             : // calculator
+     275        1092 : void FuncPathMSD::calculate() {
+     276             : // log.printf("NOW CALCULATE! \n");
+     277             :   double s_path=0.;
+     278             :   double partition=0.;
+     279        1092 :   if(neighpair.empty()) { // at first step, resize it
+     280           0 :     neighpair.resize(allArguments.size());
+     281           0 :     for(unsigned i=0; i<allArguments.size(); i++)neighpair[i].first=allArguments[i];
+     282             :   }
+     283             : 
+     284        1092 :   Value* val_s_path=getPntrToComponent("s");
+     285        2184 :   Value* val_z_path=getPntrToComponent("z");
+     286             : 
+     287        3959 :   for(auto & it : neighpair) {
+     288        2867 :     it.second=std::exp(-lambda*(it.first->get()));
+     289        2867 :     s_path+=(indexmap[it.first])*it.second;
+     290        2867 :     partition+=it.second;
+     291             :   }
+     292        1092 :   s_path/=partition;
+     293             :   val_s_path->set(s_path);
+     294        1092 :   val_z_path->set(-(1./lambda)*std::log(partition));
+     295             :   int n=0;
+     296        3959 :   for(const auto & it : neighpair) {
+     297        2867 :     double expval=it.second;
+     298        2867 :     double tmp=lambda*expval*(s_path-(indexmap[it.first]))/partition;
+     299             :     setDerivative(val_s_path,n,tmp);
+     300        2867 :     setDerivative(val_z_path,n,expval/partition);
+     301        2867 :     n++;
+     302             :   }
+     303             : 
+     304             : //  log.printf("CALCULATION DONE! \n");
+     305        1092 : }
+     306             : ///
+     307             : /// this function updates the needed argument list
+     308             : ///
+     309        1092 : void FuncPathMSD::prepare() {
+     310             : 
+     311             :   // neighbor list: rank and activate the chain for the next step
+     312             : 
+     313             :   // neighbor list: if neigh_size<0 never sort and keep the full vector
+     314             :   // neighbor list: if neigh_size>0
+     315             :   //                if the size is full -> sort the vector and decide the dependencies for next step
+     316             :   //                if the size is not full -> check if next step will need the full dependency otherwise keep this dependencies
+     317             : 
+     318             :   // here just resize the neighpair. The real resizing of reinit will be done by the prepare stage that will modify the  list of arguments
+     319        1092 :   if (neigh_size>0) {
+     320         546 :     if(neighpair.size()==allArguments.size()) { // I just did the complete round: need to sort, shorten and give it a go
+     321             :       // sort the values
+     322         137 :       std::sort(neighpair.begin(),neighpair.end(),pairordering());
+     323             :       // resize the effective list
+     324         137 :       neighpair.resize(neigh_size);
+     325         137 :       log.printf("  NEIGH LIST NOW INCLUDE INDEXES: ");
+     326         411 :       for(int i=0; i<neigh_size; ++i) {log.printf(" %f ",indexmap[neighpair[i].first]);} log.printf(" \n");
+     327             :     } else {
+     328         409 :       if( int(getStep())%int(neigh_stride/getTimeStep())==0 ) {
+     329         137 :         log.printf(" Time %f : recalculating full neighlist \n",getStep()*getTimeStep());
+     330         137 :         neighpair.resize(allArguments.size());
+     331         548 :         for(unsigned i=0; i<allArguments.size(); i++)neighpair[i].first=allArguments[i];
+     332             :       }
+     333             :     }
+     334             :   } else {
+     335         546 :     if( int(getStep())==0) {
+     336           1 :       neighpair.resize(allArguments.size());
+     337           4 :       for(unsigned i=0; i<allArguments.size(); i++)neighpair[i].first=allArguments[i];
+     338             :     }
+     339             :   }
+     340             :   std::vector<Value*> argstocall;
+     341             : //log.printf("PREPARING \n");
+     342             :   argstocall.clear();
+     343        1092 :   if(!neighpair.empty()) {
+     344        3959 :     for(const auto & it : neighpair) {
+     345        2867 :       argstocall.push_back( it.first );
+     346             :       //     log.printf("CALLING %p %f ",(*it).first ,indexmap[(*it).first] );
+     347             :     }
+     348             :   } else {
+     349           0 :     for(unsigned i=0; i<allArguments.size(); i++) {
+     350           0 :       argstocall.push_back(allArguments[i]);
+     351             :     }
+     352             :   }
+     353             : // now the list of argument changes
+     354        1092 :   requestArguments(argstocall);
+     355             : //now resize the derivatives as well
+     356             : //for each value in this action
+     357        3276 :   for(int i=0; i< getNumberOfComponents(); i++) {
+     358             :     //resize the derivative to the number   the
+     359        2184 :     getPntrToComponent(i)->clearDerivatives();
+     360        2184 :     getPntrToComponent(i)->resizeDerivatives(getNumberOfArguments());
+     361             :   }
+     362             : //log.printf("PREPARING DONE! \n");
+     363        1092 : }
+     364             : 
+     365             : }
+     366             : }
+     367             : 
+     368             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/FuncSumHills.cpp.func-sort-c.html b/coverage/function/FuncSumHills.cpp.func-sort-c.html new file mode 100644 index 000000000000..89ce7808e3bc --- /dev/null +++ b/coverage/function/FuncSumHills.cpp.func-sort-c.html @@ -0,0 +1,121 @@ + + + + + + + + LCOV - plumed test coverage - function/FuncSumHills.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - FuncSumHills.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:29232589.8 %
Date:2024-04-19 12:12:35Functions:101283.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function12FuncSumHills9calculateEv0
_ZN4PLMD8function12FuncSumHillsC2ERKNS_13ActionOptionsE0
_ZN4PLMD8function12FilesHandler12getMinMaxBinERKSt6vectorIPNS_5ValueESaIS4_EERNS_12CommunicatorERS2_IdSaIdEESD_RS2_IjSaIjEERKSC_1
_ZN4PLMD8function12FilesHandler12getMinMaxBinERKSt6vectorIPNS_5ValueESaIS4_EERNS_12CommunicatorERS2_IdSaIdEESD_RS2_IjSaIjEE4
_ZN4PLMD8function12FuncSumHills21checkFilesAreExistingERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EE9
_ZN4PLMD8function12FuncSumHillsC1ERKNS_13ActionOptionsE9
_ZN4PLMD8function12FuncSumHills16registerKeywordsERNS_8KeywordsE11
_ZN4PLMD8function12FilesHandlerC2ERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKbRNS_6ActionERNS_3LogE14
_ZN4PLMD8function12FilesHandler9readBunchEPNS_18BiasRepresentationEi15
_ZN4PLMD8function5mylogEd900
_ZN4PLMD8function8mylogderEd1800
_ZN4PLMD8function12FilesHandler11scanOneHillEPNS_18BiasRepresentationEPNS_5IFileE5578
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/FuncSumHills.cpp.func.html b/coverage/function/FuncSumHills.cpp.func.html new file mode 100644 index 000000000000..1222f73be917 --- /dev/null +++ b/coverage/function/FuncSumHills.cpp.func.html @@ -0,0 +1,121 @@ + + + + + + + + LCOV - plumed test coverage - function/FuncSumHills.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - FuncSumHills.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:29232589.8 %
Date:2024-04-19 12:12:35Functions:101283.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function12FilesHandler11scanOneHillEPNS_18BiasRepresentationEPNS_5IFileE5578
_ZN4PLMD8function12FilesHandler12getMinMaxBinERKSt6vectorIPNS_5ValueESaIS4_EERNS_12CommunicatorERS2_IdSaIdEESD_RS2_IjSaIjEE4
_ZN4PLMD8function12FilesHandler12getMinMaxBinERKSt6vectorIPNS_5ValueESaIS4_EERNS_12CommunicatorERS2_IdSaIdEESD_RS2_IjSaIjEERKSC_1
_ZN4PLMD8function12FilesHandler9readBunchEPNS_18BiasRepresentationEi15
_ZN4PLMD8function12FilesHandlerC2ERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKbRNS_6ActionERNS_3LogE14
_ZN4PLMD8function12FuncSumHills16registerKeywordsERNS_8KeywordsE11
_ZN4PLMD8function12FuncSumHills21checkFilesAreExistingERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EE9
_ZN4PLMD8function12FuncSumHills9calculateEv0
_ZN4PLMD8function12FuncSumHillsC1ERKNS_13ActionOptionsE9
_ZN4PLMD8function12FuncSumHillsC2ERKNS_13ActionOptionsE0
_ZN4PLMD8function5mylogEd900
_ZN4PLMD8function8mylogderEd1800
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/FuncSumHills.cpp.gcov.html b/coverage/function/FuncSumHills.cpp.gcov.html new file mode 100644 index 000000000000..c92de7bb3f7b --- /dev/null +++ b/coverage/function/FuncSumHills.cpp.gcov.html @@ -0,0 +1,715 @@ + + + + + + + + LCOV - plumed test coverage - function/FuncSumHills.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - FuncSumHills.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:29232589.8 %
Date:2024-04-19 12:12:35Functions:101283.3 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionRegister.h"
+      23             : #include "Function.h"
+      24             : #include "tools/Exception.h"
+      25             : #include "tools/Communicator.h"
+      26             : #include "tools/BiasRepresentation.h"
+      27             : #include "tools/KernelFunctions.h"
+      28             : #include "tools/File.h"
+      29             : #include "tools/Tools.h"
+      30             : #include "tools/Stopwatch.h"
+      31             : #include "tools/Grid.h"
+      32             : 
+      33             : namespace PLMD {
+      34             : namespace function {
+      35             : 
+      36             : 
+      37             : //+PLUMEDOC FUNCTION FUNCSUMHILLS
+      38             : /*
+      39             : This function is intended to be called by the command line tool sum_hills.  It is meant to integrate a HILLS file or an HILLS file interpreted as a histogram in a variety of ways. It is, therefore, not expected that you use this during your dynamics (it will crash!)
+      40             : 
+      41             : In the future one could implement periodic integration during the metadynamics
+      42             : or straightforward MD as a tool to check convergence
+      43             : 
+      44             : \par Examples
+      45             : 
+      46             : There are currently no examples for this keyword.
+      47             : 
+      48             : */
+      49             : //+ENDPLUMEDOC
+      50             : 
+      51          14 : class FilesHandler {
+      52             :   std::vector <std::string> filenames;
+      53             :   std::vector <std::unique_ptr<IFile>>  ifiles;
+      54             :   Action *action;
+      55             :   Log *log;
+      56             :   bool parallelread;
+      57             :   unsigned beingread;
+      58             :   bool isopen;
+      59             : public:
+      60             :   FilesHandler(const std::vector<std::string> &filenames, const bool &parallelread,  Action &myaction, Log &mylog);
+      61             :   bool readBunch(BiasRepresentation *br, int stride);
+      62             :   bool scanOneHill(BiasRepresentation *br, IFile *ifile );
+      63             :   void getMinMaxBin(const std::vector<Value*> & vals, Communicator &cc, std::vector<double> &vmin, std::vector<double> &vmax, std::vector<unsigned> &vbin);
+      64             :   void getMinMaxBin(const std::vector<Value*> & vals, Communicator &cc, std::vector<double> &vmin, std::vector<double> &vmax, std::vector<unsigned> &vbin, const std::vector<double> &histosigma);
+      65             : };
+      66          14 : FilesHandler::FilesHandler(const std::vector<std::string> &filenames, const bool &parallelread, Action &action, Log &mylog ):filenames(filenames),log(&mylog),parallelread(parallelread),beingread(0),isopen(false) {
+      67          14 :   this->action=&action;
+      68          29 :   for(unsigned i=0; i<filenames.size(); i++) {
+      69             :     auto ifile=Tools::make_unique<IFile>();
+      70          15 :     ifile->link(action);
+      71          15 :     plumed_massert((ifile->FileExist(filenames[i])), "the file "+filenames[i]+" does not exist " );
+      72          15 :     ifiles.emplace_back(std::move(ifile));
+      73          15 :   }
+      74             : 
+      75          14 : }
+      76             : 
+      77             : // note that the FileHandler is completely transparent respect to the biasrepresentation
+      78             : // no check are made at this level
+      79          15 : bool FilesHandler::readBunch(BiasRepresentation *br, int stride = -1) {
+      80             :   bool morefiles; morefiles=true;
+      81          15 :   if(parallelread) {
+      82           0 :     (*log)<<"  doing parallelread \n";
+      83           0 :     plumed_merror("parallelread is not yet implemented !!!");
+      84             :   } else {
+      85          15 :     (*log)<<"  doing serialread \n";
+      86             :     // read one by one hills
+      87             :     // is the type defined? if not, assume it is a gaussian
+      88             :     IFile *ff;
+      89          15 :     ff=ifiles[beingread].get();
+      90          15 :     if(!isopen) {
+      91          14 :       (*log)<<"  opening file "<<filenames[beingread]<<"\n";
+      92          14 :       ff->open(filenames[beingread]); isopen=true;
+      93             :     }
+      94          15 :     int n=0;
+      95             :     while(true) {
+      96             :       bool fileisover=true;
+      97        5578 :       while(scanOneHill(br,ff)) {
+      98             :         // here do the dump if needed
+      99        5563 :         n=br->getNumberOfKernels();
+     100        5563 :         if(stride>0 && n%stride==0 && n!=0  ) {
+     101           1 :           (*log)<<"  done with this chunk: now with "<<n<<" kernels  \n";
+     102             :           fileisover=false;
+     103             :           break;
+     104             :         }
+     105             :       }
+     106             :       if(fileisover) {
+     107          15 :         (*log)<<"  closing file "<<filenames[beingread]<<"\n";
+     108          15 :         ff->close();
+     109          15 :         isopen=false;
+     110          15 :         (*log)<<"  now total "<<br->getNumberOfKernels()<<" kernels \n";
+     111          15 :         beingread++;
+     112          15 :         if(beingread<ifiles.size()) {
+     113           1 :           ff=ifiles[beingread].get(); ff->open(filenames[beingread]);
+     114           1 :           (*log)<<"  opening file "<<filenames[beingread]<<"\n";
+     115           1 :           isopen=true;
+     116             :         } else {
+     117             :           morefiles=false;
+     118          14 :           (*log)<<"  final chunk: now with "<<n<<" kernels  \n";
+     119             :           break;
+     120             :         }
+     121             :       }
+     122             :       // if there are no more files to read and this file is over then quit
+     123             :       if(fileisover && !morefiles) {break;}
+     124             :       // if you are in the middle of a file and you are here
+     125             :       // then means that you read what you need to read
+     126           2 :       if(!fileisover ) {break;}
+     127             :     }
+     128             :   }
+     129          15 :   return morefiles;
+     130             : }
+     131           4 : void FilesHandler::getMinMaxBin(const std::vector<Value*> & vals, Communicator &cc, std::vector<double> &vmin, std::vector<double> &vmax, std::vector<unsigned> &vbin) {
+     132             :   // create the representation (no grid)
+     133           4 :   BiasRepresentation br(vals,cc);
+     134             :   // read all the kernels
+     135           4 :   readBunch(&br);
+     136             :   // loop over the kernels and get the support
+     137           4 :   br.getMinMaxBin(vmin,vmax,vbin);
+     138           4 : }
+     139           1 : void FilesHandler::getMinMaxBin(const std::vector<Value*> & vals, Communicator &cc, std::vector<double> &vmin, std::vector<double> &vmax, std::vector<unsigned> &vbin, const std::vector<double> &histosigma) {
+     140           1 :   BiasRepresentation br(vals,cc,histosigma);
+     141             :   // read all the kernels
+     142           1 :   readBunch(&br);
+     143             :   // loop over the kernels and get the support
+     144           1 :   br.getMinMaxBin(vmin,vmax,vbin);
+     145             :   //for(unsigned i=0;i<vals.size();i++){cerr<<"XXX "<<vmin[i]<<" "<<vmax[i]<<" "<<vbin[i]<<"\n";}
+     146           1 : }
+     147        5578 : bool FilesHandler::scanOneHill(BiasRepresentation *br, IFile *ifile ) {
+     148             :   double dummy;
+     149       11156 :   if(ifile->scanField("time",dummy)) {
+     150             :     //(*log)<<"   scanning one hill: "<<dummy<<" \n";
+     151       16689 :     if(ifile->FieldExist("biasf")) ifile->scanField("biasf",dummy);
+     152       11126 :     if(ifile->FieldExist("clock")) ifile->scanField("clock",dummy);
+     153             :     // keep this intermediate function in case you need to parse more data in the future
+     154        5563 :     br->pushKernel(ifile);
+     155             :     //(*log)<<"  read hill\n";
+     156        5563 :     if(br->hasSigmaInInput())ifile->allowIgnoredFields();
+     157        5563 :     ifile->scanField();
+     158        5563 :     return true;
+     159             :   } else {
+     160             :     return false;
+     161             :   }
+     162             : }
+     163             : 
+     164             : 
+     165         900 : double  mylog( double v1 ) {
+     166         900 :   return std::log(v1);
+     167             : }
+     168             : 
+     169        1800 : double  mylogder( double v1 ) {
+     170        1800 :   return 1./v1;
+     171             : }
+     172             : 
+     173             : 
+     174             : 
+     175             : class FuncSumHills :
+     176             :   public Function
+     177             : {
+     178             :   std::vector<std::string> hillsFiles,histoFiles;
+     179             :   std::vector<std::string> proj;
+     180             :   int initstride;
+     181             :   bool iscltool,integratehills,integratehisto,parallelread;
+     182             :   bool negativebias;
+     183             :   bool nohistory;
+     184             :   bool minTOzero;
+     185             :   bool doInt;
+     186             :   double lowI_;
+     187             :   double uppI_;
+     188             :   double beta;
+     189             :   std::string outhills,outhisto,fmt;
+     190             :   std::unique_ptr<BiasRepresentation> biasrep;
+     191             :   std::unique_ptr<BiasRepresentation> historep;
+     192             : public:
+     193             :   explicit FuncSumHills(const ActionOptions&);
+     194             :   void calculate() override; // this probably is not needed
+     195             :   bool checkFilesAreExisting(const std::vector<std::string> & hills );
+     196             :   static void registerKeywords(Keywords& keys);
+     197             : };
+     198             : 
+     199             : PLUMED_REGISTER_ACTION(FuncSumHills,"FUNCSUMHILLS")
+     200             : 
+     201          11 : void FuncSumHills::registerKeywords(Keywords& keys) {
+     202          11 :   Function::registerKeywords(keys);
+     203          11 :   keys.use("ARG");
+     204          22 :   keys.add("optional","HILLSFILES"," source file for hills creation(may be the same as HILLS)"); // this can be a vector!
+     205          22 :   keys.add("optional","HISTOFILES"," source file for histogram creation(may be the same as HILLS)"); // also this can be a vector!
+     206          22 :   keys.add("optional","HISTOSIGMA"," sigmas for binning when the histogram correction is needed    ");
+     207          22 :   keys.add("optional","PROJ"," only with sumhills: the projection on the CVs");
+     208          22 :   keys.add("optional","KT"," only with sumhills: the kt factor when projection on CVs");
+     209          22 :   keys.add("optional","GRID_MIN","the lower bounds for the grid");
+     210          22 :   keys.add("optional","GRID_MAX","the upper bounds for the grid");
+     211          22 :   keys.add("optional","GRID_BIN","the number of bins for the grid");
+     212          22 :   keys.add("optional","GRID_SPACING","the approximate grid spacing (to be used as an alternative or together with GRID_BIN)");
+     213          22 :   keys.add("optional","INTERVAL","set one dimensional INTERVAL");
+     214          22 :   keys.add("optional","OUTHILLS"," output file for hills ");
+     215          22 :   keys.add("optional","OUTHISTO"," output file for histogram ");
+     216          22 :   keys.add("optional","INITSTRIDE"," stride if you want an initial dump ");
+     217          22 :   keys.add("optional","STRIDE"," stride when you do it on the fly ");
+     218          22 :   keys.addFlag("ISCLTOOL",false,"use via plumed command line: calculate at read phase and then go");
+     219          22 :   keys.addFlag("PARALLELREAD",false,"read parallel HILLS file");
+     220          22 :   keys.addFlag("NEGBIAS",false,"dump  negative bias ( -bias )   instead of the free energy: needed in well tempered with flexible hills ");
+     221          22 :   keys.addFlag("NOHISTORY",false,"to be used with INITSTRIDE:  it splits the bias/histogram in pieces without previous history  ");
+     222          22 :   keys.addFlag("MINTOZERO",false,"translate the resulting bias/histogram to have the minimum to zero  ");
+     223          22 :   keys.add("optional","FMT","the format that should be used to output real numbers");
+     224          11 : }
+     225             : 
+     226           9 : FuncSumHills::FuncSumHills(const ActionOptions&ao):
+     227             :   Action(ao),
+     228             :   Function(ao),
+     229           9 :   initstride(-1),
+     230           9 :   iscltool(false),
+     231           9 :   integratehills(false),
+     232           9 :   integratehisto(false),
+     233           9 :   parallelread(false),
+     234           9 :   negativebias(false),
+     235           9 :   nohistory(false),
+     236           9 :   minTOzero(false),
+     237           9 :   doInt(false),
+     238           9 :   lowI_(-1.),
+     239           9 :   uppI_(-1.),
+     240           9 :   beta(-1.),
+     241           9 :   fmt("%14.9f")
+     242             : {
+     243             : 
+     244             :   // format
+     245           9 :   parse("FMT",fmt);
+     246           9 :   log<<"  Output format is "<<fmt<<"\n";
+     247             :   // here read
+     248             :   // Grid Stuff
+     249             :   std::vector<std::string> gmin;
+     250          18 :   parseVector("GRID_MIN",gmin);
+     251           9 :   if(gmin.size()!=getNumberOfArguments() && gmin.size()!=0) error("not enough values for GRID_MIN");
+     252           9 :   plumed_massert(gmin.size()==getNumberOfArguments() || gmin.size()==0,"need GRID_MIN argument for this") ;
+     253             :   std::vector<std::string> gmax;
+     254          18 :   parseVector("GRID_MAX",gmax);
+     255           9 :   if(gmax.size()!=getNumberOfArguments() && gmax.size()!=0) error("not enough values for GRID_MAX");
+     256           9 :   plumed_massert(gmax.size()==getNumberOfArguments() || gmax.size()==0,"need GRID_MAX argument for this") ;
+     257             :   std::vector<unsigned> gbin;
+     258             :   std::vector<double>   gspacing;
+     259          18 :   parseVector("GRID_BIN",gbin);
+     260           9 :   plumed_massert(gbin.size()==getNumberOfArguments() || gbin.size()==0,"need GRID_BIN argument for this") ;
+     261           9 :   if(gbin.size()!=getNumberOfArguments() && gbin.size()!=0) error("not enough values for GRID_BIN");
+     262          18 :   parseVector("GRID_SPACING",gspacing);
+     263           9 :   plumed_massert(gspacing.size()==getNumberOfArguments() || gspacing.size()==0,"need GRID_SPACING argument for this") ;
+     264           9 :   if(gspacing.size()!=getNumberOfArguments() && gspacing.size()!=0) error("not enough values for GRID_SPACING");
+     265           9 :   if(gspacing.size()!=0 && gbin.size()==0) {
+     266           1 :     log<<"  The number of bins will be estimated from GRID_SPACING\n";
+     267           8 :   } else if(gspacing.size()!=0 && gbin.size()!=0) {
+     268           0 :     log<<"  You specified both GRID_BIN and GRID_SPACING\n";
+     269           0 :     log<<"  The more conservative (highest) number of bins will be used for each variable\n";
+     270             :   }
+     271          10 :   if(gspacing.size()!=0) for(unsigned i=0; i<getNumberOfArguments(); i++) {
+     272           1 :       if(gbin.size()==0) gbin.assign(getNumberOfArguments(),1);
+     273             :       double a,b;
+     274           1 :       Tools::convert(gmin[i],a);
+     275           1 :       Tools::convert(gmax[i],b);
+     276           1 :       unsigned n=std::ceil((b-a)/gspacing[i]);
+     277           1 :       if(gbin[i]<n) gbin[i]=n;
+     278             :     }
+     279             : 
+     280             :   // Inteval keyword
+     281           9 :   std::vector<double> tmpI(2);
+     282          18 :   parseVector("INTERVAL",tmpI);
+     283           9 :   if(tmpI.size()!=2&&tmpI.size()!=0) error("both a lower and an upper limits must be provided with INTERVAL");
+     284           9 :   else if(tmpI.size()==2) {
+     285           0 :     lowI_=tmpI.at(0);
+     286           0 :     uppI_=tmpI.at(1);
+     287           0 :     if(getNumberOfArguments()!=1) error("INTERVAL limits correction works only for monodimensional metadynamics!");
+     288           0 :     if(uppI_<lowI_) error("The Upper limit must be greater than the Lower limit!");
+     289           0 :     doInt=true;
+     290             :   }
+     291           9 :   if(doInt) {
+     292           0 :     log << "  Upper and Lower limits boundaries for the bias are activated at " << lowI_ << " - " << uppI_<<"\n";
+     293           0 :     log << "  Using the same values as boundaries for the grid if not other value was defined (default: 200 bins)\n";
+     294           0 :     std::ostringstream strsmin, strsmax;
+     295           0 :     strsmin << lowI_;
+     296           0 :     strsmax << uppI_;
+     297           0 :     if(gmin.size()==0) gmin.push_back(strsmin.str());
+     298           0 :     if(gmax.size()==0) gmax.push_back(strsmax.str());
+     299           0 :     if(gbin.size()==0) gbin.push_back(200);
+     300           0 :   }
+     301             : 
+     302             : 
+     303             :   // hills file:
+     304          18 :   parseVector("HILLSFILES",hillsFiles);
+     305           9 :   if(hillsFiles.size()==0) {
+     306           1 :     integratehills=false; // default behaviour
+     307             :   } else {
+     308           8 :     integratehills=true;
+     309          17 :     for(unsigned i=0; i<hillsFiles.size(); i++) log<<"  hillsfile  : "<<hillsFiles[i]<<"\n";
+     310             :   }
+     311             :   // histo file:
+     312          18 :   parseVector("HISTOFILES",histoFiles);
+     313           9 :   if(histoFiles.size()==0) {
+     314           8 :     integratehisto=false;
+     315             :   } else {
+     316           1 :     integratehisto=true;
+     317           2 :     for(unsigned i=0; i<histoFiles.size(); i++) log<<"  histofile  : "<<histoFiles[i]<<"\n";
+     318             :   }
+     319             :   std::vector<double> histoSigma;
+     320           9 :   if(integratehisto) {
+     321           1 :     parseVector("HISTOSIGMA",histoSigma);
+     322           3 :     for(unsigned i=0; i<histoSigma.size(); i++) log<<"  histosigma  : "<<histoSigma[i]<<"\n";
+     323             :   }
+     324             : 
+     325             :   // needs a projection?
+     326             :   proj.clear();
+     327           9 :   parseVector("PROJ",proj);
+     328           9 :   if(integratehills) {
+     329           8 :     plumed_massert(proj.size()<getNumberOfArguments()," The number of projection must be less than the full list of arguments ");
+     330             :   }
+     331           9 :   if(integratehisto) {
+     332           1 :     plumed_massert(proj.size()<=getNumberOfArguments()," The number of projection must be less or equal to the full list of arguments ");
+     333             :   }
+     334           9 :   if(integratehisto&&proj.size()==0) {
+     335           3 :     for(unsigned i=0; i<getNumberOfArguments(); i++) proj.push_back(getPntrToArgument(i)->getName());
+     336             :   }
+     337             : 
+     338             :   // add some automatic hills width: not in case stride is defined
+     339             :   // since when you start from zero the automatic size will be zero!
+     340           9 :   if(gmin.size()==0 || gmax.size()==0) {
+     341           5 :     log<<"   \n";
+     342           5 :     log<<"  No boundaries defined: need to do a prescreening of hills \n";
+     343             :     std::vector<Value*> tmphillsvalues, tmphistovalues;
+     344           5 :     if(integratehills) {
+     345          12 :       for(unsigned i=0; i<getNumberOfArguments(); i++)tmphillsvalues.push_back( getPntrToArgument(i) );
+     346             :     }
+     347           5 :     if(integratehisto) {
+     348           3 :       for(unsigned i=0; i<getNumberOfArguments(); i++) {
+     349           2 :         std::string ss = getPntrToArgument(i)->getName();
+     350           6 :         for(unsigned j=0; j<proj.size(); j++) {
+     351           4 :           if(proj[j]==ss) tmphistovalues.push_back( getPntrToArgument(i) );
+     352             :         }
+     353             :       }
+     354             :     }
+     355             : 
+     356           5 :     if(integratehills) {
+     357           4 :       FilesHandler hillsHandler(hillsFiles,parallelread,*this, log);
+     358             :       std::vector<double> vmin,vmax;
+     359             :       std::vector<unsigned> vbin;
+     360           4 :       hillsHandler.getMinMaxBin(tmphillsvalues,comm,vmin,vmax,vbin);
+     361           4 :       log<<"  found boundaries from hillsfile: \n";
+     362           4 :       gmin.resize(vmin.size());
+     363           4 :       gmax.resize(vmax.size());
+     364           4 :       if(gbin.size()==0) {
+     365           3 :         gbin=vbin;
+     366             :       } else {
+     367           1 :         log<<"  found nbins in input, this overrides the automatic choice \n";
+     368             :       }
+     369          12 :       for(unsigned i=0; i<getNumberOfArguments(); i++) {
+     370           8 :         Tools::convert(vmin[i],gmin[i]);
+     371           8 :         Tools::convert(vmax[i],gmax[i]);
+     372           8 :         log<<"  variable "<< getPntrToArgument(i)->getName()<<" min: "<<gmin[i]<<" max: "<<gmax[i]<<" nbin: "<<gbin[i]<<"\n";
+     373             :       }
+     374             :     }
+     375             :     // if at this stage bins are not there then do it with histo
+     376           5 :     if(gmin.size()==0) {
+     377           1 :       FilesHandler histoHandler(histoFiles,parallelread,*this, log);
+     378             :       std::vector<double> vmin,vmax;
+     379             :       std::vector<unsigned> vbin;
+     380           1 :       histoHandler.getMinMaxBin(tmphistovalues,comm,vmin,vmax,vbin,histoSigma);
+     381           1 :       log<<"  found boundaries from histofile: \n";
+     382           1 :       gmin.resize(vmin.size());
+     383           1 :       gmax.resize(vmax.size());
+     384           1 :       if(gbin.size()==0) {
+     385           0 :         gbin=vbin;
+     386             :       } else {
+     387           1 :         log<<"  found nbins in input, this overrides the automatic choice \n";
+     388             :       }
+     389           3 :       for(unsigned i=0; i<proj.size(); i++) {
+     390           2 :         Tools::convert(vmin[i],gmin[i]);
+     391           2 :         Tools::convert(vmax[i],gmax[i]);
+     392           2 :         log<<"  variable "<< proj[i] <<" min: "<<gmin[i]<<" max: "<<gmax[i]<<" nbin: "<<gbin[i]<<"\n";
+     393             :       }
+     394             :     }
+     395           5 :     log<<"  done!\n";
+     396           5 :     log<<"   \n";
+     397             :   }
+     398             : 
+     399             : 
+     400           9 :   if( proj.size() != 0 || integratehisto==true  ) {
+     401           3 :     parse("KT",beta);
+     402           7 :     for(unsigned i=0; i<proj.size(); i++) log<<"  projection "<<i<<" : "<<proj[i]<<"\n";
+     403             :     // this should be only for projection or free energy from histograms
+     404           3 :     plumed_massert(beta>0.,"if you make a projection or a histogram correction then you need KT flag!");
+     405           3 :     beta=1./beta;
+     406           3 :     log<<"  beta is "<<beta<<"\n";
+     407             :   }
+     408             :   // is a cltool: then you start and then die
+     409           9 :   parseFlag("ISCLTOOL",iscltool);
+     410             :   //
+     411           9 :   parseFlag("NEGBIAS",negativebias);
+     412             :   //
+     413           9 :   parseFlag("PARALLELREAD",parallelread);
+     414             :   // stride
+     415           9 :   parse("INITSTRIDE",initstride);
+     416             :   // output suffix or names
+     417           9 :   if(initstride<0) {
+     418           8 :     log<<"  Doing only one integration: no stride \n";
+     419             :     outhills="fes.dat"; outhisto="histo.dat";
+     420             :   }
+     421             :   else {
+     422             :     outhills="fes_"; outhisto="histo_";
+     423           1 :     log<<"  Doing integration slices every "<<initstride<<" kernels\n";
+     424           1 :     parseFlag("NOHISTORY",nohistory);
+     425           1 :     if(nohistory)log<<"  nohistory: each stride block has no memory of the previous block\n";
+     426             :   }
+     427           9 :   parseFlag("MINTOZERO",minTOzero);
+     428           9 :   if(minTOzero)log<<"  mintozero: bias/histogram will be translated to have the minimum value equal to zero\n";
+     429             :   //what might it be this?
+     430             :   // here start
+     431             :   // want something right now?? do it and return
+     432             :   // your argument is a set of cvs
+     433             :   // then you need: a hills / a colvar-like file (to do a histogram)
+     434             :   // create a bias representation for this
+     435           9 :   if(iscltool) {
+     436             : 
+     437             :     std::vector<Value*> tmphillsvalues, tmphistovalues;
+     438           9 :     if(integratehills) {
+     439          23 :       for(unsigned i=0; i<getNumberOfArguments(); i++) {
+     440             :         // allocate a new value from the old one: no deriv here
+     441             :         // if we are summing hills then all the arguments are needed
+     442          15 :         tmphillsvalues.push_back( getPntrToArgument(i) );
+     443             :       }
+     444             :     }
+     445           9 :     if(integratehisto) {
+     446           3 :       for(unsigned i=0; i<getNumberOfArguments(); i++) {
+     447           2 :         std::string ss = getPntrToArgument(i)->getName();
+     448           6 :         for(unsigned j=0; j<proj.size(); j++) {
+     449           4 :           if(proj[j]==ss) tmphistovalues.push_back( getPntrToArgument(i) );
+     450             :         }
+     451             :       }
+     452             :     }
+     453             : 
+     454             :     // check if the files exists
+     455           9 :     if(integratehills) {
+     456           8 :       checkFilesAreExisting(hillsFiles);
+     457          16 :       biasrep=Tools::make_unique<BiasRepresentation>(tmphillsvalues,comm, gmin, gmax, gbin, doInt, lowI_, uppI_);
+     458           8 :       if(negativebias) {
+     459           1 :         biasrep->setRescaledToBias(true);
+     460           1 :         log<<"  required the -bias instead of the free energy \n";
+     461           1 :         if(initstride<0) {outhills="negativebias.dat";}
+     462             :         else {outhills="negativebias_";}
+     463             :       }
+     464             :     }
+     465             : 
+     466           9 :     parse("OUTHILLS",outhills);
+     467           9 :     parse("OUTHISTO",outhisto);
+     468           9 :     if(integratehills)log<<"  output file for fes/bias  is :  "<<outhills<<"\n";
+     469           9 :     if(integratehisto)log<<"  output file for histogram is :  "<<outhisto<<"\n";
+     470           9 :     checkRead();
+     471             : 
+     472           9 :     log<<"\n";
+     473           9 :     log<<"  Now calculating...\n";
+     474           9 :     log<<"\n";
+     475             : 
+     476             :     // here it defines the column to be histogrammed, tmpvalues should be only
+     477             :     // the list of the collective variable one want to consider
+     478           9 :     if(integratehisto) {
+     479           1 :       checkFilesAreExisting(histoFiles);
+     480           2 :       historep=Tools::make_unique<BiasRepresentation>(tmphistovalues,comm,gmin,gmax,gbin,histoSigma);
+     481             :     }
+     482             : 
+     483             :     // decide how to source hills ( serial/parallel )
+     484             :     // here below the input control
+     485             :     // say how many hills and it will read them from the
+     486             :     // bunch of files provided, will update the representation
+     487             :     // of hills (i.e. a list of hills and the associated grid)
+     488             : 
+     489             :     // decide how to source colvars ( serial parallel )
+     490           9 :     std::unique_ptr<FilesHandler> hillsHandler;
+     491           9 :     std::unique_ptr<FilesHandler> histoHandler;
+     492             : 
+     493          17 :     if(integratehills)  hillsHandler=Tools::make_unique<FilesHandler>(hillsFiles,parallelread,*this, log);
+     494          10 :     if(integratehisto)  histoHandler=Tools::make_unique<FilesHandler>(histoFiles,parallelread,*this, log);
+     495             : 
+     496             : // Stopwatch is logged when it goes out of scope
+     497           9 :     Stopwatch sw(log);
+     498             : 
+     499             : // Stopwatch is stopped when swh goes out of scope
+     500           9 :     auto swh=sw.startStop("0 Summing hills");
+     501             : 
+     502             :     // read a number of hills and put in the bias representation
+     503             :     int nfiles=0;
+     504           9 :     bool ibias=integratehills; bool ihisto=integratehisto;
+     505             :     while(true) {
+     506          10 :       if(  integratehills  && ibias  ) {
+     507           9 :         if(nohistory) {biasrep->clear(); log<<"  clearing history before reading a new block\n";};
+     508           9 :         log<<"  reading hills: \n";
+     509           9 :         ibias=hillsHandler->readBunch(biasrep.get(),initstride) ; log<<"\n";
+     510             :       }
+     511             : 
+     512          10 :       if(  integratehisto  && ihisto ) {
+     513           1 :         if(nohistory) {historep->clear(); log<<"  clearing history before reading a new block\n";};
+     514           1 :         log<<"  reading histogram: \n";
+     515           1 :         ihisto=histoHandler->readBunch(historep.get(),initstride) ;  log<<"\n";
+     516             :       }
+     517             : 
+     518             :       // dump: need to project?
+     519          10 :       if(proj.size()!=0) {
+     520             : 
+     521           4 :         if(integratehills) {
+     522             : 
+     523           3 :           log<<"  Bias: Projecting on subgrid... \n";
+     524           3 :           BiasWeight Bw(beta);
+     525           3 :           Grid biasGrid=*(biasrep->getGridPtr());
+     526           3 :           Grid smallGrid=biasGrid.project(proj,&Bw);
+     527           3 :           OFile gridfile; gridfile.link(*this);
+     528           3 :           std::ostringstream ostr; ostr<<nfiles;
+     529             :           std::string myout;
+     530           7 :           if(initstride>0) { myout=outhills+ostr.str()+".dat" ;} else {myout=outhills;}
+     531           3 :           log<<"  Bias: Writing subgrid on file "<<myout<<" \n";
+     532           3 :           gridfile.open(myout);
+     533           3 :           if(minTOzero) smallGrid.setMinToZero();
+     534             :           smallGrid.setOutputFmt(fmt);
+     535           3 :           smallGrid.writeToFile(gridfile);
+     536           3 :           gridfile.close();
+     537           3 :           if(!ibias)integratehills=false;// once you get to the final bunch just give up
+     538           3 :         }
+     539             :         // this should be removed
+     540           4 :         if(integratehisto) {
+     541             : 
+     542           1 :           log<<"  Histo: Projecting on subgrid... \n";
+     543           1 :           Grid histoGrid=*(historep->getGridPtr());
+     544             : 
+     545           1 :           OFile gridfile; gridfile.link(*this);
+     546           1 :           std::ostringstream ostr; ostr<<nfiles;
+     547             :           std::string myout;
+     548           1 :           if(initstride>0) { myout=outhisto+ostr.str()+".dat" ;} else {myout=outhisto;}
+     549           1 :           log<<"  Histo: Writing subgrid on file "<<myout<<" \n";
+     550           1 :           gridfile.open(myout);
+     551             : 
+     552           1 :           histoGrid.applyFunctionAllValuesAndDerivatives(&mylog,&mylogder);
+     553           1 :           histoGrid.scaleAllValuesAndDerivatives(-1./beta);
+     554           1 :           if(minTOzero) histoGrid.setMinToZero();
+     555             :           histoGrid.setOutputFmt(fmt);
+     556           1 :           histoGrid.writeToFile(gridfile);
+     557             : 
+     558           1 :           if(!ihisto)integratehisto=false;// once you get to the final bunch just give up
+     559           1 :         }
+     560             : 
+     561             :       } else {
+     562             : 
+     563           6 :         if(integratehills) {
+     564             : 
+     565           6 :           Grid biasGrid=*(biasrep->getGridPtr());
+     566           6 :           biasGrid.scaleAllValuesAndDerivatives(-1.);
+     567             : 
+     568           6 :           OFile gridfile; gridfile.link(*this);
+     569           6 :           std::ostringstream ostr; ostr<<nfiles;
+     570             :           std::string myout;
+     571           6 :           if(initstride>0) { myout=outhills+ostr.str()+".dat" ;} else {myout=outhills;}
+     572           6 :           log<<"  Writing full grid on file "<<myout<<" \n";
+     573           6 :           gridfile.open(myout);
+     574             : 
+     575           6 :           if(minTOzero) biasGrid.setMinToZero();
+     576             :           biasGrid.setOutputFmt(fmt);
+     577           6 :           biasGrid.writeToFile(gridfile);
+     578             :           // rescale back prior to accumulate
+     579           6 :           if(!ibias)integratehills=false;// once you get to the final bunch just give up
+     580           6 :         }
+     581           6 :         if(integratehisto) {
+     582             : 
+     583           0 :           Grid histoGrid=*(historep->getGridPtr());
+     584             :           // do this if you want a free energy from a grid, otherwise do not
+     585           0 :           histoGrid.applyFunctionAllValuesAndDerivatives(&mylog,&mylogder);
+     586           0 :           histoGrid.scaleAllValuesAndDerivatives(-1./beta);
+     587             : 
+     588           0 :           OFile gridfile; gridfile.link(*this);
+     589           0 :           std::ostringstream ostr; ostr<<nfiles;
+     590             :           std::string myout;
+     591           0 :           if(initstride>0) { myout=outhisto+ostr.str()+".dat" ;} else {myout=outhisto;}
+     592           0 :           log<<"  Writing full grid on file "<<myout<<" \n";
+     593           0 :           gridfile.open(myout);
+     594             : 
+     595             :           // also this is useful only for free energy
+     596           0 :           if(minTOzero) histoGrid.setMinToZero();
+     597             :           histoGrid.setOutputFmt(fmt);
+     598           0 :           histoGrid.writeToFile(gridfile);
+     599             : 
+     600           0 :           if(!ihisto)integratehisto=false; // once you get to the final bunch just give up
+     601           0 :         }
+     602             :       }
+     603          10 :       if ( !ibias && !ihisto) break; //when both are over then just quit
+     604             : 
+     605           1 :       nfiles++;
+     606           1 :     }
+     607             : 
+     608             :     return;
+     609           9 :   }
+     610             :   // just an initialization but you need to do something on the fly?: need to connect with a metad run and its grid representation
+     611             :   // your argument is a metad run
+     612             :   // if the grid does not exist crash and say that you need some data
+     613             :   // otherwise just link with it
+     614             : 
+     615           9 : }
+     616             : 
+     617           0 : void FuncSumHills::calculate() {
+     618             :   // this should be connected only with a grid representation to metadynamics
+     619             :   // at regular time just dump it
+     620           0 :   plumed_merror("You should have never got here: this stuff is not yet implemented!");
+     621             : }
+     622             : 
+     623           9 : bool FuncSumHills::checkFilesAreExisting(const std::vector<std::string> & hills ) {
+     624           9 :   plumed_massert(hills.size()!=0,"the number of  files provided should be at least one" );
+     625             :   auto ifile=Tools::make_unique<IFile>();
+     626           9 :   ifile->link(*this);
+     627          19 :   for(unsigned i=0; i< hills.size(); i++) {
+     628          10 :     plumed_massert(ifile->FileExist(hills[i]),"missing file "+hills[i]);
+     629             :   }
+     630           9 :   return true;
+     631             : 
+     632           9 : }
+     633             : 
+     634             : }
+     635             : 
+     636             : }
+     637             : 
+     638             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Function.cpp.func-sort-c.html b/coverage/function/Function.cpp.func-sort-c.html new file mode 100644 index 000000000000..5b602dc1d4f0 --- /dev/null +++ b/coverage/function/Function.cpp.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - function/Function.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - Function.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2222100.0 %
Date:2024-04-19 12:12:35Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function8FunctionC1ERKNS_13ActionOptionsE0
_ZN4PLMD8function8Function23addValueWithDerivativesEv1410
_ZN4PLMD8function8FunctionC2ERKNS_13ActionOptionsE1509
_ZN4PLMD8function8Function16registerKeywordsERNS_8KeywordsE1553
_ZN4PLMD8function8Function27addComponentWithDerivativesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3174
_ZN4PLMD8function8Function5applyEv268891
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Function.cpp.func.html b/coverage/function/Function.cpp.func.html new file mode 100644 index 000000000000..b2124a392e56 --- /dev/null +++ b/coverage/function/Function.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - function/Function.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - Function.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2222100.0 %
Date:2024-04-19 12:12:35Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function8Function16registerKeywordsERNS_8KeywordsE1553
_ZN4PLMD8function8Function23addValueWithDerivativesEv1410
_ZN4PLMD8function8Function27addComponentWithDerivativesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3174
_ZN4PLMD8function8Function5applyEv268891
_ZN4PLMD8function8FunctionC1ERKNS_13ActionOptionsE0
_ZN4PLMD8function8FunctionC2ERKNS_13ActionOptionsE1509
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Function.cpp.gcov.html b/coverage/function/Function.cpp.gcov.html new file mode 100644 index 000000000000..7eb700f49526 --- /dev/null +++ b/coverage/function/Function.cpp.gcov.html @@ -0,0 +1,139 @@ + + + + + + + + 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:2222100.0 %
Date:2024-04-19 12:12:35Functions: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        1553 : void Function::registerKeywords(Keywords& keys) {
+      30        1553 :   Action::registerKeywords(keys);
+      31        1553 :   ActionWithValue::registerKeywords(keys);
+      32        1553 :   ActionWithArguments::registerKeywords(keys);
+      33        3106 :   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        1553 : }
+      35             : 
+      36        1509 : Function::Function(const ActionOptions&ao):
+      37             :   Action(ao),
+      38             :   ActionWithValue(ao),
+      39        1509 :   ActionWithArguments(ao)
+      40             : {
+      41        1509 : }
+      42             : 
+      43        1410 : void Function::addValueWithDerivatives() {
+      44        1410 :   plumed_massert( getNumberOfArguments()!=0, "for functions you must requestArguments before adding values");
+      45        2820 :   ActionWithValue::addValueWithDerivatives();
+      46        1410 :   getPntrToValue()->resizeDerivatives(getNumberOfArguments());
+      47        1410 : }
+      48             : 
+      49        3174 : void Function::addComponentWithDerivatives( const std::string& name ) {
+      50        3174 :   plumed_massert( getNumberOfArguments()!=0, "for functions you must requestArguments before adding values");
+      51        3174 :   ActionWithValue::addComponentWithDerivatives(name);
+      52        3174 :   getPntrToComponent(name)->resizeDerivatives(getNumberOfArguments());
+      53        3174 : }
+      54             : 
+      55      268891 : void Function::apply()
+      56             : {
+      57      268891 :   if( !checkForForces() ) return;
+      58       62409 :   unsigned ind=0; addForcesOnArguments( 0, getForcesToApply(), ind, getLabel() );
+      59             : }
+      60             : 
+      61             : }
+      62             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Function.h.func-sort-c.html b/coverage/function/Function.h.func-sort-c.html new file mode 100644 index 000000000000..eeca2b33458f --- /dev/null +++ b/coverage/function/Function.h.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - function/Function.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - Function.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:8988.9 %
Date:2024-04-19 12:12:35Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function8FunctionD2Ev1509
_ZN4PLMD8function8Function11getArgumentERKj24190
_ZN4PLMD8function8Function22getNumberOfDerivativesEv277155
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Function.h.func.html b/coverage/function/Function.h.func.html new file mode 100644 index 000000000000..abc3ffb04921 --- /dev/null +++ b/coverage/function/Function.h.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - function/Function.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - Function.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:8988.9 %
Date:2024-04-19 12:12:35Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function8Function11getArgumentERKj24190
_ZN4PLMD8function8Function22getNumberOfDerivativesEv277155
_ZN4PLMD8function8FunctionD2Ev1509
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Function.h.gcov.html b/coverage/function/Function.h.gcov.html new file mode 100644 index 000000000000..7616fc926b92 --- /dev/null +++ b/coverage/function/Function.h.gcov.html @@ -0,0 +1,160 @@ + + + + + + + + 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:8988.9 %
Date:2024-04-19 12:12:35Functions: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        1509 :   virtual ~Function() {}
+      49             :   double getArgument( const unsigned& iarg );
+      50             :   void apply() override;
+      51             :   static void registerKeywords(Keywords&);
+      52             :   unsigned getNumberOfDerivatives() override;
+      53             : };
+      54             : 
+      55             : inline
+      56             : void Function::setDerivative(Value*v,int i,double d) {
+      57        2867 :   v->addDerivative(i,d);
+      58           0 : }
+      59             : 
+      60             : inline
+      61             : void Function::setDerivative(int i,double d) {
+      62             :   setDerivative(getPntrToValue(),i,d);
+      63             : }
+      64             : 
+      65             : inline
+      66      277155 : unsigned Function::getNumberOfDerivatives() {
+      67             :   unsigned narg=0;
+      68     4979595 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+      69     4702440 :     if( getPntrToArgument(i)->getRank()==0 ) narg++;
+      70             :   }
+      71      277155 :   return narg;
+      72             : }
+      73             : 
+      74             : inline
+      75       24190 : double Function::getArgument( const unsigned& iarg ) {
+      76       24190 :   return getPntrToArgument(iarg)->get();
+      77             : }
+      78             : 
+      79             : }
+      80             : }
+      81             : 
+      82             : #endif
+      83             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/FunctionOfScalar.h.func-sort-c.html b/coverage/function/FunctionOfScalar.h.func-sort-c.html new file mode 100644 index 000000000000..bc9920dbabcc --- /dev/null +++ b/coverage/function/FunctionOfScalar.h.func-sort-c.html @@ -0,0 +1,353 @@ + + + + + + + + LCOV - plumed test coverage - function/FunctionOfScalar.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - FunctionOfScalar.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:384095.0 %
Date:2024-04-19 12:12:35Functions:517072.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function16FunctionOfScalarINS0_3SumEE17turnOnDerivativesEv0
_ZN4PLMD8function16FunctionOfScalarINS0_3SumEE9calculateEv0
_ZN4PLMD8function16FunctionOfScalarINS0_3SumEEC1ERKNS_13ActionOptionsE0
_ZN4PLMD8function16FunctionOfScalarINS0_3SumEED0Ev0
_ZN4PLMD8function16FunctionOfScalarINS0_3SumEED1Ev0
_ZN4PLMD8function16FunctionOfScalarINS0_6BesselEE17turnOnDerivativesEv0
_ZN4PLMD8function16FunctionOfScalarINS0_6BesselEE9calculateEv0
_ZN4PLMD8function16FunctionOfScalarINS0_6BesselEEC1ERKNS_13ActionOptionsE0
_ZN4PLMD8function16FunctionOfScalarINS0_6BesselEED0Ev0
_ZN4PLMD8function16FunctionOfScalarINS0_6BesselEED1Ev0
_ZNK4PLMD8function16FunctionOfScalarINS0_3SumEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD8function16FunctionOfScalarINS0_4SortEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD8function16FunctionOfScalarINS0_6BesselEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD8function16FunctionOfScalarINS0_7CombineEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD8function16FunctionOfScalarINS0_7HighestEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD8function16FunctionOfScalarINS0_7MomentsEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD8function16FunctionOfScalarINS0_9PiecewiseEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD8function16FunctionOfScalarINS_7refdist10DifferenceEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD8function16FunctionOfScalarINS_9gridtools20EvaluateGridFunctionEE12writeInGraphB5cxx11Ev0
_ZN4PLMD8function16FunctionOfScalarINS0_7MomentsEEC1ERKNS_13ActionOptionsE1
_ZN4PLMD8function16FunctionOfScalarINS0_7MomentsEED0Ev1
_ZN4PLMD8function16FunctionOfScalarINS0_7MomentsEED1Ev1
_ZN4PLMD8function16FunctionOfScalarINS_9gridtools20EvaluateGridFunctionEEC1ERKNS_13ActionOptionsE1
_ZN4PLMD8function16FunctionOfScalarINS_9gridtools20EvaluateGridFunctionEED0Ev1
_ZN4PLMD8function16FunctionOfScalarINS_9gridtools20EvaluateGridFunctionEED1Ev1
_ZN4PLMD8function16FunctionOfScalarINS0_6BesselEE16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD8function16FunctionOfScalarINS0_7HighestEE17turnOnDerivativesEv2
_ZN4PLMD8function16FunctionOfScalarINS0_7HighestEEC1ERKNS_13ActionOptionsE2
_ZN4PLMD8function16FunctionOfScalarINS0_7HighestEED0Ev2
_ZN4PLMD8function16FunctionOfScalarINS0_7HighestEED1Ev2
_ZN4PLMD8function16FunctionOfScalarINS0_7MomentsEE17turnOnDerivativesEv2
_ZN4PLMD8function16FunctionOfScalarINS0_9PiecewiseEED0Ev2
_ZN4PLMD8function16FunctionOfScalarINS0_9PiecewiseEED1Ev2
_ZN4PLMD8function16FunctionOfScalarINS_9gridtools20EvaluateGridFunctionEE17turnOnDerivativesEv2
_ZN4PLMD8function16FunctionOfScalarINS0_7MomentsEE16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD8function16FunctionOfScalarINS0_9PiecewiseEEC1ERKNS_13ActionOptionsE3
_ZN4PLMD8function16FunctionOfScalarINS_9gridtools20EvaluateGridFunctionEE16registerKeywordsERNS_8KeywordsE3
_ZNK4PLMD8function16FunctionOfScalarINS0_6CustomEE12writeInGraphB5cxx11Ev3
_ZN4PLMD8function16FunctionOfScalarINS0_3SumEE16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD8function16FunctionOfScalarINS0_4SortEE17turnOnDerivativesEv4
_ZN4PLMD8function16FunctionOfScalarINS0_9PiecewiseEE17turnOnDerivativesEv4
_ZN4PLMD8function16FunctionOfScalarINS0_7MomentsEE9calculateEv5
_ZN4PLMD8function16FunctionOfScalarINS0_9PiecewiseEE16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD8function16FunctionOfScalarINS0_7HighestEE16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD8function16FunctionOfScalarINS_7refdist10DifferenceEE17turnOnDerivativesEv6
_ZN4PLMD8function16FunctionOfScalarINS0_7HighestEE9calculateEv10
_ZN4PLMD8function16FunctionOfScalarINS0_9PiecewiseEE9calculateEv10
_ZN4PLMD8function16FunctionOfScalarINS0_4SortEE9calculateEv11
_ZN4PLMD8function16FunctionOfScalarINS0_4SortEED0Ev11
_ZN4PLMD8function16FunctionOfScalarINS0_4SortEED1Ev11
_ZN4PLMD8function16FunctionOfScalarINS0_4SortEEC1ERKNS_13ActionOptionsE12
_ZN4PLMD8function16FunctionOfScalarINS0_4SortEE16registerKeywordsERNS_8KeywordsE14
_ZN4PLMD8function16FunctionOfScalarINS_7refdist10DifferenceEEC1ERKNS_13ActionOptionsE41
_ZN4PLMD8function16FunctionOfScalarINS_7refdist10DifferenceEED0Ev41
_ZN4PLMD8function16FunctionOfScalarINS_7refdist10DifferenceEED1Ev41
_ZN4PLMD8function16FunctionOfScalarINS_7refdist10DifferenceEE16registerKeywordsERNS_8KeywordsE43
_ZN4PLMD8function16FunctionOfScalarINS0_7CombineEED0Ev191
_ZN4PLMD8function16FunctionOfScalarINS0_7CombineEED1Ev191
_ZN4PLMD8function16FunctionOfScalarINS0_7CombineEEC1ERKNS_13ActionOptionsE194
_ZN4PLMD8function16FunctionOfScalarINS0_7CombineEE16registerKeywordsERNS_8KeywordsE196
_ZN4PLMD8function16FunctionOfScalarINS0_7CombineEE17turnOnDerivativesEv611
_ZN4PLMD8function16FunctionOfScalarINS0_6CustomEEC1ERKNS_13ActionOptionsE1172
_ZN4PLMD8function16FunctionOfScalarINS0_6CustomEED0Ev1172
_ZN4PLMD8function16FunctionOfScalarINS0_6CustomEED1Ev1172
_ZN4PLMD8function16FunctionOfScalarINS0_6CustomEE16registerKeywordsERNS_8KeywordsE1176
_ZN4PLMD8function16FunctionOfScalarINS0_6CustomEE17turnOnDerivativesEv1527
_ZN4PLMD8function16FunctionOfScalarINS_9gridtools20EvaluateGridFunctionEE9calculateEv1675
_ZN4PLMD8function16FunctionOfScalarINS_7refdist10DifferenceEE9calculateEv1676
_ZN4PLMD8function16FunctionOfScalarINS0_7CombineEE9calculateEv31267
_ZN4PLMD8function16FunctionOfScalarINS0_6CustomEE9calculateEv56792
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/FunctionOfScalar.h.func.html b/coverage/function/FunctionOfScalar.h.func.html new file mode 100644 index 000000000000..fab11cd5b63c --- /dev/null +++ b/coverage/function/FunctionOfScalar.h.func.html @@ -0,0 +1,353 @@ + + + + + + + + LCOV - plumed test coverage - function/FunctionOfScalar.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - FunctionOfScalar.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:384095.0 %
Date:2024-04-19 12:12:35Functions:517072.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function16FunctionOfScalarINS0_3SumEE16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD8function16FunctionOfScalarINS0_3SumEE17turnOnDerivativesEv0
_ZN4PLMD8function16FunctionOfScalarINS0_3SumEE9calculateEv0
_ZN4PLMD8function16FunctionOfScalarINS0_3SumEEC1ERKNS_13ActionOptionsE0
_ZN4PLMD8function16FunctionOfScalarINS0_3SumEED0Ev0
_ZN4PLMD8function16FunctionOfScalarINS0_3SumEED1Ev0
_ZN4PLMD8function16FunctionOfScalarINS0_4SortEE16registerKeywordsERNS_8KeywordsE14
_ZN4PLMD8function16FunctionOfScalarINS0_4SortEE17turnOnDerivativesEv4
_ZN4PLMD8function16FunctionOfScalarINS0_4SortEE9calculateEv11
_ZN4PLMD8function16FunctionOfScalarINS0_4SortEEC1ERKNS_13ActionOptionsE12
_ZN4PLMD8function16FunctionOfScalarINS0_4SortEED0Ev11
_ZN4PLMD8function16FunctionOfScalarINS0_4SortEED1Ev11
_ZN4PLMD8function16FunctionOfScalarINS0_6BesselEE16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD8function16FunctionOfScalarINS0_6BesselEE17turnOnDerivativesEv0
_ZN4PLMD8function16FunctionOfScalarINS0_6BesselEE9calculateEv0
_ZN4PLMD8function16FunctionOfScalarINS0_6BesselEEC1ERKNS_13ActionOptionsE0
_ZN4PLMD8function16FunctionOfScalarINS0_6BesselEED0Ev0
_ZN4PLMD8function16FunctionOfScalarINS0_6BesselEED1Ev0
_ZN4PLMD8function16FunctionOfScalarINS0_6CustomEE16registerKeywordsERNS_8KeywordsE1176
_ZN4PLMD8function16FunctionOfScalarINS0_6CustomEE17turnOnDerivativesEv1527
_ZN4PLMD8function16FunctionOfScalarINS0_6CustomEE9calculateEv56792
_ZN4PLMD8function16FunctionOfScalarINS0_6CustomEEC1ERKNS_13ActionOptionsE1172
_ZN4PLMD8function16FunctionOfScalarINS0_6CustomEED0Ev1172
_ZN4PLMD8function16FunctionOfScalarINS0_6CustomEED1Ev1172
_ZN4PLMD8function16FunctionOfScalarINS0_7CombineEE16registerKeywordsERNS_8KeywordsE196
_ZN4PLMD8function16FunctionOfScalarINS0_7CombineEE17turnOnDerivativesEv611
_ZN4PLMD8function16FunctionOfScalarINS0_7CombineEE9calculateEv31267
_ZN4PLMD8function16FunctionOfScalarINS0_7CombineEEC1ERKNS_13ActionOptionsE194
_ZN4PLMD8function16FunctionOfScalarINS0_7CombineEED0Ev191
_ZN4PLMD8function16FunctionOfScalarINS0_7CombineEED1Ev191
_ZN4PLMD8function16FunctionOfScalarINS0_7HighestEE16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD8function16FunctionOfScalarINS0_7HighestEE17turnOnDerivativesEv2
_ZN4PLMD8function16FunctionOfScalarINS0_7HighestEE9calculateEv10
_ZN4PLMD8function16FunctionOfScalarINS0_7HighestEEC1ERKNS_13ActionOptionsE2
_ZN4PLMD8function16FunctionOfScalarINS0_7HighestEED0Ev2
_ZN4PLMD8function16FunctionOfScalarINS0_7HighestEED1Ev2
_ZN4PLMD8function16FunctionOfScalarINS0_7MomentsEE16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD8function16FunctionOfScalarINS0_7MomentsEE17turnOnDerivativesEv2
_ZN4PLMD8function16FunctionOfScalarINS0_7MomentsEE9calculateEv5
_ZN4PLMD8function16FunctionOfScalarINS0_7MomentsEEC1ERKNS_13ActionOptionsE1
_ZN4PLMD8function16FunctionOfScalarINS0_7MomentsEED0Ev1
_ZN4PLMD8function16FunctionOfScalarINS0_7MomentsEED1Ev1
_ZN4PLMD8function16FunctionOfScalarINS0_9PiecewiseEE16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD8function16FunctionOfScalarINS0_9PiecewiseEE17turnOnDerivativesEv4
_ZN4PLMD8function16FunctionOfScalarINS0_9PiecewiseEE9calculateEv10
_ZN4PLMD8function16FunctionOfScalarINS0_9PiecewiseEEC1ERKNS_13ActionOptionsE3
_ZN4PLMD8function16FunctionOfScalarINS0_9PiecewiseEED0Ev2
_ZN4PLMD8function16FunctionOfScalarINS0_9PiecewiseEED1Ev2
_ZN4PLMD8function16FunctionOfScalarINS_7refdist10DifferenceEE16registerKeywordsERNS_8KeywordsE43
_ZN4PLMD8function16FunctionOfScalarINS_7refdist10DifferenceEE17turnOnDerivativesEv6
_ZN4PLMD8function16FunctionOfScalarINS_7refdist10DifferenceEE9calculateEv1676
_ZN4PLMD8function16FunctionOfScalarINS_7refdist10DifferenceEEC1ERKNS_13ActionOptionsE41
_ZN4PLMD8function16FunctionOfScalarINS_7refdist10DifferenceEED0Ev41
_ZN4PLMD8function16FunctionOfScalarINS_7refdist10DifferenceEED1Ev41
_ZN4PLMD8function16FunctionOfScalarINS_9gridtools20EvaluateGridFunctionEE16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD8function16FunctionOfScalarINS_9gridtools20EvaluateGridFunctionEE17turnOnDerivativesEv2
_ZN4PLMD8function16FunctionOfScalarINS_9gridtools20EvaluateGridFunctionEE9calculateEv1675
_ZN4PLMD8function16FunctionOfScalarINS_9gridtools20EvaluateGridFunctionEEC1ERKNS_13ActionOptionsE1
_ZN4PLMD8function16FunctionOfScalarINS_9gridtools20EvaluateGridFunctionEED0Ev1
_ZN4PLMD8function16FunctionOfScalarINS_9gridtools20EvaluateGridFunctionEED1Ev1
_ZNK4PLMD8function16FunctionOfScalarINS0_3SumEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD8function16FunctionOfScalarINS0_4SortEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD8function16FunctionOfScalarINS0_6BesselEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD8function16FunctionOfScalarINS0_6CustomEE12writeInGraphB5cxx11Ev3
_ZNK4PLMD8function16FunctionOfScalarINS0_7CombineEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD8function16FunctionOfScalarINS0_7HighestEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD8function16FunctionOfScalarINS0_7MomentsEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD8function16FunctionOfScalarINS0_9PiecewiseEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD8function16FunctionOfScalarINS_7refdist10DifferenceEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD8function16FunctionOfScalarINS_9gridtools20EvaluateGridFunctionEE12writeInGraphB5cxx11Ev0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/FunctionOfScalar.h.gcov.html b/coverage/function/FunctionOfScalar.h.gcov.html new file mode 100644 index 000000000000..0320261b1753 --- /dev/null +++ b/coverage/function/FunctionOfScalar.h.gcov.html @@ -0,0 +1,190 @@ + + + + + + + + LCOV - plumed test coverage - function/FunctionOfScalar.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - FunctionOfScalar.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:384095.0 %
Date:2024-04-19 12:12:35Functions:517072.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_function_FunctionOfScalar_h
+      23             : #define __PLUMED_function_FunctionOfScalar_h
+      24             : 
+      25             : #include "Function.h"
+      26             : #include "tools/Matrix.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             : template <class T>
+      38             : class FunctionOfScalar : public Function {
+      39             : private:
+      40             : /// The function that is being computed
+      41             :   T myfunc;
+      42             : /// Are we on the first step
+      43             :   bool firststep;
+      44             : public:
+      45             :   explicit FunctionOfScalar(const ActionOptions&);
+      46        2842 :   virtual ~FunctionOfScalar() {}
+      47             : /// Get the label to write in the graph
+      48           3 :   std::string writeInGraph() const override { return myfunc.getGraphInfo( getName() ); }
+      49             :   void calculate() override;
+      50             :   static void registerKeywords(Keywords&);
+      51             :   void turnOnDerivatives() override;
+      52             : };
+      53             : 
+      54             : template <class T>
+      55        1452 : void FunctionOfScalar<T>::registerKeywords(Keywords& keys) {
+      56        1452 :   Function::registerKeywords(keys); keys.use("ARG");
+      57        2904 :   keys.add("hidden","NO_ACTION_LOG","suppresses printing from action on the log");
+      58        1403 :   T tfunc; tfunc.registerKeywords( keys );
+      59        1452 : }
+      60             : 
+      61             : template <class T>
+      62        1426 : FunctionOfScalar<T>::FunctionOfScalar(const ActionOptions&ao):
+      63             :   Action(ao),
+      64             :   Function(ao),
+      65        1426 :   firststep(true)
+      66             : {
+      67        1426 :   myfunc.read( this );
+      68             :   // Get the names of the components
+      69        1421 :   std::vector<std::string> components( keywords.getOutputComponents() );
+      70             :   // Create the values to hold the output
+      71        1378 :   std::vector<std::string> str_ind( myfunc.getComponentsPerLabel() );
+      72        1421 :   if( components.size()==0 && str_ind.size()==0 ) addValueWithDerivatives();
+      73          14 :   else if ( components.size()==0 ) {
+      74          34 :     for(unsigned j=0; j<str_ind.size(); ++j) addComponentWithDerivatives( str_ind[j] );
+      75             :   } else {
+      76           1 :     std::vector<std::string> str_ind( myfunc.getComponentsPerLabel() );
+      77           6 :     for(unsigned i=0; i<components.size(); ++i) {
+      78           1 :       if( str_ind.size()>0 ) {
+      79           2 :         for(unsigned j=0; j<str_ind.size(); ++j) addComponentWithDerivatives( components[i] + str_ind[j] );
+      80           2 :       } else if( components[i].find_first_of("_")!=std::string::npos ) {
+      81           2 :         if( getNumberOfArguments()==1 ) addValueWithDerivatives();
+      82           3 :         else { for(unsigned j=0; j<getNumberOfArguments(); ++j) addComponentWithDerivatives( getPntrToArgument(j)->getName() + components[i] ); }
+      83           0 :       } else addComponentWithDerivatives( components[i] );
+      84             :     }
+      85           3 :   }
+      86             :   // Set the periodicities of the output components
+      87        1421 :   myfunc.setPeriodicityForOutputs( this ); myfunc.setPrefactor( this, 1.0 );
+      88        1434 : }
+      89             : 
+      90             : template <class T>
+      91        2158 : void FunctionOfScalar<T>::turnOnDerivatives() {
+      92           0 :   if( !myfunc.derivativesImplemented() ) error("derivatives have not been implemended for " + getName() );
+      93        2158 :   ActionWithValue::turnOnDerivatives();
+      94        2158 : }
+      95             : 
+      96             : template <class T>
+      97       91446 : void FunctionOfScalar<T>::calculate() {
+      98       91446 :   if( firststep ) { myfunc.setup( this ); firststep=false; } unsigned argstart = myfunc.getArgStart();
+      99      207635 :   std::vector<double> args( getNumberOfArguments() - argstart ); for(unsigned i=argstart; i<getNumberOfArguments(); ++i) args[i-argstart]=getPntrToArgument(i)->get();
+     100       91446 :   std::vector<double> vals( getNumberOfComponents() ); Matrix<double> derivatives( getNumberOfComponents(), args.size() );
+     101       91446 :   myfunc.calc( this, args, vals, derivatives );
+     102      182929 :   for(unsigned i=0; i<vals.size(); ++i) copyOutput(i)->set(vals[i]);
+     103       91446 :   if( doNotCalculateDerivatives() ) return;
+     104             : 
+     105      157760 :   for(unsigned i=0; i<vals.size(); ++i) {
+     106       78895 :     Value* val = getPntrToComponent(i);
+     107      174138 :     for(unsigned j=0; j<args.size(); ++j) setDerivative( val, j, derivatives(i,j) );
+     108             :   }
+     109             : }
+     110             : 
+     111             : }
+     112             : }
+     113             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/FunctionOfVector.h.func-sort-c.html b/coverage/function/FunctionOfVector.h.func-sort-c.html new file mode 100644 index 000000000000..56db49173e74 --- /dev/null +++ b/coverage/function/FunctionOfVector.h.func-sort-c.html @@ -0,0 +1,709 @@ + + + + + + + + LCOV - plumed test coverage - function/FunctionOfVector.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - FunctionOfVector.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:14415493.5 %
Date:2024-04-19 12:12:35Functions:14515991.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function16FunctionOfVectorINS0_4SortEE19areAllTasksRequiredERSt6vectorIPNS_16ActionWithVectorESaIS6_EE0
_ZN4PLMD8function16FunctionOfVectorINS0_4SortEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSC_SC_SC_0
_ZN4PLMD8function16FunctionOfVectorINS0_6BesselEE19areAllTasksRequiredERSt6vectorIPNS_16ActionWithVectorESaIS6_EE0
_ZN4PLMD8function16FunctionOfVectorINS0_7MomentsEE19areAllTasksRequiredERSt6vectorIPNS_16ActionWithVectorESaIS6_EE0
_ZN4PLMD8function16FunctionOfVectorINS0_7MomentsEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSC_SC_SC_0
_ZNK4PLMD8function16FunctionOfVectorINS0_4SortEE11performTaskERKjRNS_10MultiValueE0
_ZNK4PLMD8function16FunctionOfVectorINS0_4SortEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD8function16FunctionOfVectorINS0_6BesselEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD8function16FunctionOfVectorINS0_7CombineEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD8function16FunctionOfVectorINS0_7HighestEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD8function16FunctionOfVectorINS0_7MomentsEE11performTaskERKjRNS_10MultiValueE0
_ZNK4PLMD8function16FunctionOfVectorINS0_7MomentsEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD8function16FunctionOfVectorINS_7refdist10DifferenceEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD8function16FunctionOfVectorINS_9gridtools20EvaluateGridFunctionEE12writeInGraphB5cxx11Ev0
_ZN4PLMD8function16FunctionOfVectorINS_9gridtools20EvaluateGridFunctionEE21getNumberOfFinalTasksEv1
_ZN4PLMD8function16FunctionOfVectorINS_9gridtools20EvaluateGridFunctionEEC1ERKNS_13ActionOptionsE1
_ZN4PLMD8function16FunctionOfVectorINS_9gridtools20EvaluateGridFunctionEED0Ev1
_ZN4PLMD8function16FunctionOfVectorINS_9gridtools20EvaluateGridFunctionEED1Ev1
_ZNK4PLMD8function16FunctionOfVectorINS0_7BetweenEE12writeInGraphB5cxx11Ev1
_ZN4PLMD8function16FunctionOfVectorINS0_4SortEE21getNumberOfFinalTasksEv2
_ZN4PLMD8function16FunctionOfVectorINS0_4SortEEC1ERKNS_13ActionOptionsE2
_ZN4PLMD8function16FunctionOfVectorINS0_4SortEED0Ev2
_ZN4PLMD8function16FunctionOfVectorINS0_4SortEED1Ev2
_ZN4PLMD8function16FunctionOfVectorINS0_7MomentsEE17turnOnDerivativesEv2
_ZN4PLMD8function16FunctionOfVectorINS_9gridtools20EvaluateGridFunctionEE17turnOnDerivativesEv2
_ZN4PLMD8function16FunctionOfVectorINS_9gridtools20EvaluateGridFunctionEE19areAllTasksRequiredERSt6vectorIPNS_16ActionWithVectorESaIS7_EE2
_ZN4PLMD8function16FunctionOfVectorINS_9gridtools20EvaluateGridFunctionEE22getNumberOfDerivativesEv2
_ZNK4PLMD8function16FunctionOfVectorINS0_6CustomEE12writeInGraphB5cxx11Ev2
_ZNK4PLMD8function16FunctionOfVectorINS0_8LessThanEE12writeInGraphB5cxx11Ev2
_ZN4PLMD8function16FunctionOfVectorINS_9gridtools20EvaluateGridFunctionEE16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD8function16FunctionOfVectorINS0_4SortEE16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD8function16FunctionOfVectorINS0_7MomentsEE21getNumberOfFinalTasksEv4
_ZN4PLMD8function16FunctionOfVectorINS0_7MomentsEEC1ERKNS_13ActionOptionsE4
_ZN4PLMD8function16FunctionOfVectorINS0_7MomentsEED0Ev4
_ZN4PLMD8function16FunctionOfVectorINS0_7MomentsEED1Ev4
_ZN4PLMD8function16FunctionOfVectorINS0_7MomentsEE16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD8function16FunctionOfVectorINS0_6BesselEE21getNumberOfFinalTasksEv7
_ZN4PLMD8function16FunctionOfVectorINS0_6BesselEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSC_SC_SC_7
_ZN4PLMD8function16FunctionOfVectorINS0_6BesselEE7prepareEv7
_ZN4PLMD8function16FunctionOfVectorINS0_6BesselEE9calculateEv7
_ZN4PLMD8function16FunctionOfVectorINS0_6BesselEEC1ERKNS_13ActionOptionsE7
_ZN4PLMD8function16FunctionOfVectorINS0_6BesselEED0Ev7
_ZN4PLMD8function16FunctionOfVectorINS0_6BesselEED1Ev7
_ZNK4PLMD8function16FunctionOfVectorINS0_3SumEE12writeInGraphB5cxx11Ev7
_ZNK4PLMD8function16FunctionOfVectorINS0_8MoreThanEE12writeInGraphB5cxx11Ev8
_ZN4PLMD8function16FunctionOfVectorINS0_6BesselEE16registerKeywordsERNS_8KeywordsE9
_ZNK4PLMD8function16FunctionOfVectorINS0_6BesselEE11performTaskERKjRNS_10MultiValueE14
_ZN4PLMD8function16FunctionOfVectorINS0_6BesselEE17turnOnDerivativesEv16
_ZN4PLMD8function16FunctionOfVectorINS0_6BesselEE22getNumberOfDerivativesEv16
_ZN4PLMD8function16FunctionOfVectorINS0_4SortEE17turnOnDerivativesEv28
_ZN4PLMD8function16FunctionOfVectorINS0_4SortEE24runSingleTaskCalculationEPKNS_5ValueEPNS_15ActionWithValueERS2_34
_ZN4PLMD8function16FunctionOfVectorINS0_4SortEE7prepareEv34
_ZN4PLMD8function16FunctionOfVectorINS0_4SortEE9calculateEv34
_ZN4PLMD8function16FunctionOfVectorINS0_7HighestEE19areAllTasksRequiredERSt6vectorIPNS_16ActionWithVectorESaIS6_EE36
_ZN4PLMD8function16FunctionOfVectorINS0_7HighestEE21getNumberOfFinalTasksEv44
_ZN4PLMD8function16FunctionOfVectorINS0_7HighestEEC1ERKNS_13ActionOptionsE44
_ZN4PLMD8function16FunctionOfVectorINS0_7HighestEED0Ev44
_ZN4PLMD8function16FunctionOfVectorINS0_7HighestEED1Ev44
_ZN4PLMD8function16FunctionOfVectorINS0_7HighestEE16registerKeywordsERNS_8KeywordsE48
_ZN4PLMD8function16FunctionOfVectorINS0_7BetweenEE21getNumberOfFinalTasksEv52
_ZN4PLMD8function16FunctionOfVectorINS0_7BetweenEEC1ERKNS_13ActionOptionsE52
_ZN4PLMD8function16FunctionOfVectorINS0_7BetweenEED0Ev52
_ZN4PLMD8function16FunctionOfVectorINS0_7BetweenEED1Ev52
_ZN4PLMD8function16FunctionOfVectorINS0_7BetweenEE16registerKeywordsERNS_8KeywordsE54
_ZN4PLMD8function16FunctionOfVectorINS0_8LessThanEE21getNumberOfFinalTasksEv58
_ZN4PLMD8function16FunctionOfVectorINS0_8LessThanEEC1ERKNS_13ActionOptionsE58
_ZN4PLMD8function16FunctionOfVectorINS0_8LessThanEED0Ev58
_ZN4PLMD8function16FunctionOfVectorINS0_8LessThanEED1Ev58
_ZN4PLMD8function16FunctionOfVectorINS0_8LessThanEE16registerKeywordsERNS_8KeywordsE60
_ZN4PLMD8function16FunctionOfVectorINS0_8MoreThanEE21getNumberOfFinalTasksEv62
_ZN4PLMD8function16FunctionOfVectorINS0_8MoreThanEEC1ERKNS_13ActionOptionsE62
_ZN4PLMD8function16FunctionOfVectorINS0_8MoreThanEED0Ev62
_ZN4PLMD8function16FunctionOfVectorINS0_8MoreThanEED1Ev62
_ZN4PLMD8function16FunctionOfVectorINS0_8MoreThanEE16registerKeywordsERNS_8KeywordsE64
_ZN4PLMD8function16FunctionOfVectorINS_7refdist10DifferenceEE19areAllTasksRequiredERSt6vectorIPNS_16ActionWithVectorESaIS7_EE71
_ZN4PLMD8function16FunctionOfVectorINS0_7BetweenEE17turnOnDerivativesEv74
_ZN4PLMD8function16FunctionOfVectorINS0_7BetweenEE22getNumberOfDerivativesEv74
_ZN4PLMD8function16FunctionOfVectorINS0_7CombineEE21getNumberOfFinalTasksEv83
_ZN4PLMD8function16FunctionOfVectorINS0_7CombineEEC1ERKNS_13ActionOptionsE83
_ZN4PLMD8function16FunctionOfVectorINS0_7CombineEED0Ev83
_ZN4PLMD8function16FunctionOfVectorINS0_7CombineEED1Ev83
_ZN4PLMD8function16FunctionOfVectorINS0_7CombineEE16registerKeywordsERNS_8KeywordsE85
_ZN4PLMD8function16FunctionOfVectorINS0_7HighestEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSC_SC_SC_90
_ZN4PLMD8function16FunctionOfVectorINS0_8LessThanEE17turnOnDerivativesEv97
_ZN4PLMD8function16FunctionOfVectorINS0_8LessThanEE22getNumberOfDerivativesEv97
_ZN4PLMD8function16FunctionOfVectorINS0_7HighestEE17turnOnDerivativesEv106
_ZN4PLMD8function16FunctionOfVectorINS_7refdist10DifferenceEE21getNumberOfFinalTasksEv143
_ZN4PLMD8function16FunctionOfVectorINS_7refdist10DifferenceEEC1ERKNS_13ActionOptionsE143
_ZN4PLMD8function16FunctionOfVectorINS_7refdist10DifferenceEED0Ev143
_ZN4PLMD8function16FunctionOfVectorINS_7refdist10DifferenceEED1Ev143
_ZN4PLMD8function16FunctionOfVectorINS_7refdist10DifferenceEE16registerKeywordsERNS_8KeywordsE145
_ZN4PLMD8function16FunctionOfVectorINS0_8MoreThanEE17turnOnDerivativesEv175
_ZN4PLMD8function16FunctionOfVectorINS0_8MoreThanEE22getNumberOfDerivativesEv175
_ZN4PLMD8function16FunctionOfVectorINS0_7BetweenEE9calculateEv192
_ZN4PLMD8function16FunctionOfVectorINS0_7BetweenEE19areAllTasksRequiredERSt6vectorIPNS_16ActionWithVectorESaIS6_EE193
_ZN4PLMD8function16FunctionOfVectorINS0_7BetweenEE7prepareEv193
_ZN4PLMD8function16FunctionOfVectorINS0_7MomentsEE24runSingleTaskCalculationEPKNS_5ValueEPNS_15ActionWithValueERS2_217
_ZN4PLMD8function16FunctionOfVectorINS0_7MomentsEE7prepareEv217
_ZN4PLMD8function16FunctionOfVectorINS0_7MomentsEE9calculateEv217
_ZN4PLMD8function16FunctionOfVectorINS0_7MomentsEE22getNumberOfDerivativesEv219
_ZN4PLMD8function16FunctionOfVectorINS0_4SortEE22getNumberOfDerivativesEv230
_ZN4PLMD8function16FunctionOfVectorINS0_7BetweenEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSC_SC_SC_233
_ZN4PLMD8function16FunctionOfVectorINS0_8MoreThanEE19areAllTasksRequiredERSt6vectorIPNS_16ActionWithVectorESaIS6_EE245
_ZN4PLMD8function16FunctionOfVectorINS0_7CombineEE17turnOnDerivativesEv313
_ZN4PLMD8function16FunctionOfVectorINS0_7CombineEE22getNumberOfDerivativesEv313
_ZN4PLMD8function16FunctionOfVectorINS0_8LessThanEE19areAllTasksRequiredERSt6vectorIPNS_16ActionWithVectorESaIS6_EE324
_ZN4PLMD8function16FunctionOfVectorINS0_8LessThanEE9calculateEv446
_ZN4PLMD8function16FunctionOfVectorINS0_8LessThanEE7prepareEv447
_ZN4PLMD8function16FunctionOfVectorINS0_8LessThanEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSC_SC_SC_476
_ZN4PLMD8function16FunctionOfVectorINS0_8MoreThanEE9calculateEv517
_ZN4PLMD8function16FunctionOfVectorINS0_8MoreThanEE7prepareEv521
_ZN4PLMD8function16FunctionOfVectorINS0_7CombineEE19areAllTasksRequiredERSt6vectorIPNS_16ActionWithVectorESaIS6_EE623
_ZN4PLMD8function16FunctionOfVectorINS0_8MoreThanEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSC_SC_SC_650
_ZNK4PLMD8function16FunctionOfVectorINS0_7BetweenEE11performTaskERKjRNS_10MultiValueE716
_ZN4PLMD8function16FunctionOfVectorINS0_3SumEE21getNumberOfFinalTasksEv768
_ZN4PLMD8function16FunctionOfVectorINS0_3SumEEC1ERKNS_13ActionOptionsE768
_ZN4PLMD8function16FunctionOfVectorINS0_3SumEED0Ev768
_ZN4PLMD8function16FunctionOfVectorINS0_3SumEED1Ev768
_ZN4PLMD8function16FunctionOfVectorINS0_3SumEE16registerKeywordsERNS_8KeywordsE772
_ZN4PLMD8function16FunctionOfVectorINS0_3SumEE17turnOnDerivativesEv797
_ZN4PLMD8function16FunctionOfVectorINS0_6CustomEE21getNumberOfFinalTasksEv1009
_ZN4PLMD8function16FunctionOfVectorINS0_6CustomEEC1ERKNS_13ActionOptionsE1009
_ZN4PLMD8function16FunctionOfVectorINS0_6CustomEED0Ev1009
_ZN4PLMD8function16FunctionOfVectorINS0_6CustomEED1Ev1009
_ZN4PLMD8function16FunctionOfVectorINS0_6CustomEE16registerKeywordsERNS_8KeywordsE1013
_ZN4PLMD8function16FunctionOfVectorINS_9gridtools20EvaluateGridFunctionEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSD_SD_SD_1675
_ZN4PLMD8function16FunctionOfVectorINS_9gridtools20EvaluateGridFunctionEE7prepareEv1675
_ZN4PLMD8function16FunctionOfVectorINS_9gridtools20EvaluateGridFunctionEE9calculateEv1675
_ZN4PLMD8function16FunctionOfVectorINS0_6CustomEE17turnOnDerivativesEv2100
_ZN4PLMD8function16FunctionOfVectorINS0_6CustomEE22getNumberOfDerivativesEv2100
_ZN4PLMD8function16FunctionOfVectorINS_7refdist10DifferenceEE17turnOnDerivativesEv2390
_ZN4PLMD8function16FunctionOfVectorINS_7refdist10DifferenceEE22getNumberOfDerivativesEv2390
_ZN4PLMD8function16FunctionOfVectorINS0_3SumEE19areAllTasksRequiredERSt6vectorIPNS_16ActionWithVectorESaIS6_EE2710
_ZN4PLMD8function16FunctionOfVectorINS0_7HighestEE24runSingleTaskCalculationEPKNS_5ValueEPNS_15ActionWithValueERS2_5290
_ZN4PLMD8function16FunctionOfVectorINS0_7HighestEE9calculateEv5380
_ZN4PLMD8function16FunctionOfVectorINS0_7HighestEE7prepareEv5384
_ZN4PLMD8function16FunctionOfVectorINS0_7HighestEE22getNumberOfDerivativesEv5387
_ZN4PLMD8function16FunctionOfVectorINS0_6CustomEE19areAllTasksRequiredERSt6vectorIPNS_16ActionWithVectorESaIS6_EE7870
_ZNK4PLMD8function16FunctionOfVectorINS_9gridtools20EvaluateGridFunctionEE11performTaskERKjRNS_10MultiValueE8375
_ZNK4PLMD8function16FunctionOfVectorINS0_7HighestEE11performTaskERKjRNS_10MultiValueE18499
_ZN4PLMD8function16FunctionOfVectorINS0_7CombineEE9calculateEv22536
_ZN4PLMD8function16FunctionOfVectorINS0_7CombineEE7prepareEv23125
_ZN4PLMD8function16FunctionOfVectorINS0_7CombineEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSC_SC_SC_32776
_ZN4PLMD8function16FunctionOfVectorINS0_3SumEE9calculateEv41271
_ZN4PLMD8function16FunctionOfVectorINS0_3SumEE7prepareEv41282
_ZN4PLMD8function16FunctionOfVectorINS0_3SumEE22getNumberOfDerivativesEv41932
_ZN4PLMD8function16FunctionOfVectorINS_7refdist10DifferenceEE7prepareEv49487
_ZN4PLMD8function16FunctionOfVectorINS_7refdist10DifferenceEE9calculateEv49487
_ZNK4PLMD8function16FunctionOfVectorINS0_8MoreThanEE11performTaskERKjRNS_10MultiValueE53152
_ZN4PLMD8function16FunctionOfVectorINS0_6CustomEE9calculateEv63042
_ZN4PLMD8function16FunctionOfVectorINS0_6CustomEE7prepareEv63061
_ZN4PLMD8function16FunctionOfVectorINS0_3SumEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSC_SC_SC_78899
_ZN4PLMD8function16FunctionOfVectorINS_7refdist10DifferenceEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSD_SD_SD_94404
_ZN4PLMD8function16FunctionOfVectorINS0_6CustomEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSC_SC_SC_103234
_ZNK4PLMD8function16FunctionOfVectorINS0_8LessThanEE11performTaskERKjRNS_10MultiValueE121283
_ZNK4PLMD8function16FunctionOfVectorINS0_7CombineEE11performTaskERKjRNS_10MultiValueE357792
_ZNK4PLMD8function16FunctionOfVectorINS0_3SumEE11performTaskERKjRNS_10MultiValueE1252574
_ZNK4PLMD8function16FunctionOfVectorINS0_6CustomEE11performTaskERKjRNS_10MultiValueE1900084
_ZNK4PLMD8function16FunctionOfVectorINS_7refdist10DifferenceEE11performTaskERKjRNS_10MultiValueE2876173
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/FunctionOfVector.h.func.html b/coverage/function/FunctionOfVector.h.func.html new file mode 100644 index 000000000000..92432185e7df --- /dev/null +++ b/coverage/function/FunctionOfVector.h.func.html @@ -0,0 +1,709 @@ + + + + + + + + LCOV - plumed test coverage - function/FunctionOfVector.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - FunctionOfVector.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:14415493.5 %
Date:2024-04-19 12:12:35Functions:14515991.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function16FunctionOfVectorINS0_3SumEE16registerKeywordsERNS_8KeywordsE772
_ZN4PLMD8function16FunctionOfVectorINS0_3SumEE17turnOnDerivativesEv797
_ZN4PLMD8function16FunctionOfVectorINS0_3SumEE19areAllTasksRequiredERSt6vectorIPNS_16ActionWithVectorESaIS6_EE2710
_ZN4PLMD8function16FunctionOfVectorINS0_3SumEE21getNumberOfFinalTasksEv768
_ZN4PLMD8function16FunctionOfVectorINS0_3SumEE22getNumberOfDerivativesEv41932
_ZN4PLMD8function16FunctionOfVectorINS0_3SumEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSC_SC_SC_78899
_ZN4PLMD8function16FunctionOfVectorINS0_3SumEE7prepareEv41282
_ZN4PLMD8function16FunctionOfVectorINS0_3SumEE9calculateEv41271
_ZN4PLMD8function16FunctionOfVectorINS0_3SumEEC1ERKNS_13ActionOptionsE768
_ZN4PLMD8function16FunctionOfVectorINS0_3SumEED0Ev768
_ZN4PLMD8function16FunctionOfVectorINS0_3SumEED1Ev768
_ZN4PLMD8function16FunctionOfVectorINS0_4SortEE16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD8function16FunctionOfVectorINS0_4SortEE17turnOnDerivativesEv28
_ZN4PLMD8function16FunctionOfVectorINS0_4SortEE19areAllTasksRequiredERSt6vectorIPNS_16ActionWithVectorESaIS6_EE0
_ZN4PLMD8function16FunctionOfVectorINS0_4SortEE21getNumberOfFinalTasksEv2
_ZN4PLMD8function16FunctionOfVectorINS0_4SortEE22getNumberOfDerivativesEv230
_ZN4PLMD8function16FunctionOfVectorINS0_4SortEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSC_SC_SC_0
_ZN4PLMD8function16FunctionOfVectorINS0_4SortEE24runSingleTaskCalculationEPKNS_5ValueEPNS_15ActionWithValueERS2_34
_ZN4PLMD8function16FunctionOfVectorINS0_4SortEE7prepareEv34
_ZN4PLMD8function16FunctionOfVectorINS0_4SortEE9calculateEv34
_ZN4PLMD8function16FunctionOfVectorINS0_4SortEEC1ERKNS_13ActionOptionsE2
_ZN4PLMD8function16FunctionOfVectorINS0_4SortEED0Ev2
_ZN4PLMD8function16FunctionOfVectorINS0_4SortEED1Ev2
_ZN4PLMD8function16FunctionOfVectorINS0_6BesselEE16registerKeywordsERNS_8KeywordsE9
_ZN4PLMD8function16FunctionOfVectorINS0_6BesselEE17turnOnDerivativesEv16
_ZN4PLMD8function16FunctionOfVectorINS0_6BesselEE19areAllTasksRequiredERSt6vectorIPNS_16ActionWithVectorESaIS6_EE0
_ZN4PLMD8function16FunctionOfVectorINS0_6BesselEE21getNumberOfFinalTasksEv7
_ZN4PLMD8function16FunctionOfVectorINS0_6BesselEE22getNumberOfDerivativesEv16
_ZN4PLMD8function16FunctionOfVectorINS0_6BesselEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSC_SC_SC_7
_ZN4PLMD8function16FunctionOfVectorINS0_6BesselEE7prepareEv7
_ZN4PLMD8function16FunctionOfVectorINS0_6BesselEE9calculateEv7
_ZN4PLMD8function16FunctionOfVectorINS0_6BesselEEC1ERKNS_13ActionOptionsE7
_ZN4PLMD8function16FunctionOfVectorINS0_6BesselEED0Ev7
_ZN4PLMD8function16FunctionOfVectorINS0_6BesselEED1Ev7
_ZN4PLMD8function16FunctionOfVectorINS0_6CustomEE16registerKeywordsERNS_8KeywordsE1013
_ZN4PLMD8function16FunctionOfVectorINS0_6CustomEE17turnOnDerivativesEv2100
_ZN4PLMD8function16FunctionOfVectorINS0_6CustomEE19areAllTasksRequiredERSt6vectorIPNS_16ActionWithVectorESaIS6_EE7870
_ZN4PLMD8function16FunctionOfVectorINS0_6CustomEE21getNumberOfFinalTasksEv1009
_ZN4PLMD8function16FunctionOfVectorINS0_6CustomEE22getNumberOfDerivativesEv2100
_ZN4PLMD8function16FunctionOfVectorINS0_6CustomEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSC_SC_SC_103234
_ZN4PLMD8function16FunctionOfVectorINS0_6CustomEE7prepareEv63061
_ZN4PLMD8function16FunctionOfVectorINS0_6CustomEE9calculateEv63042
_ZN4PLMD8function16FunctionOfVectorINS0_6CustomEEC1ERKNS_13ActionOptionsE1009
_ZN4PLMD8function16FunctionOfVectorINS0_6CustomEED0Ev1009
_ZN4PLMD8function16FunctionOfVectorINS0_6CustomEED1Ev1009
_ZN4PLMD8function16FunctionOfVectorINS0_7BetweenEE16registerKeywordsERNS_8KeywordsE54
_ZN4PLMD8function16FunctionOfVectorINS0_7BetweenEE17turnOnDerivativesEv74
_ZN4PLMD8function16FunctionOfVectorINS0_7BetweenEE19areAllTasksRequiredERSt6vectorIPNS_16ActionWithVectorESaIS6_EE193
_ZN4PLMD8function16FunctionOfVectorINS0_7BetweenEE21getNumberOfFinalTasksEv52
_ZN4PLMD8function16FunctionOfVectorINS0_7BetweenEE22getNumberOfDerivativesEv74
_ZN4PLMD8function16FunctionOfVectorINS0_7BetweenEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSC_SC_SC_233
_ZN4PLMD8function16FunctionOfVectorINS0_7BetweenEE7prepareEv193
_ZN4PLMD8function16FunctionOfVectorINS0_7BetweenEE9calculateEv192
_ZN4PLMD8function16FunctionOfVectorINS0_7BetweenEEC1ERKNS_13ActionOptionsE52
_ZN4PLMD8function16FunctionOfVectorINS0_7BetweenEED0Ev52
_ZN4PLMD8function16FunctionOfVectorINS0_7BetweenEED1Ev52
_ZN4PLMD8function16FunctionOfVectorINS0_7CombineEE16registerKeywordsERNS_8KeywordsE85
_ZN4PLMD8function16FunctionOfVectorINS0_7CombineEE17turnOnDerivativesEv313
_ZN4PLMD8function16FunctionOfVectorINS0_7CombineEE19areAllTasksRequiredERSt6vectorIPNS_16ActionWithVectorESaIS6_EE623
_ZN4PLMD8function16FunctionOfVectorINS0_7CombineEE21getNumberOfFinalTasksEv83
_ZN4PLMD8function16FunctionOfVectorINS0_7CombineEE22getNumberOfDerivativesEv313
_ZN4PLMD8function16FunctionOfVectorINS0_7CombineEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSC_SC_SC_32776
_ZN4PLMD8function16FunctionOfVectorINS0_7CombineEE7prepareEv23125
_ZN4PLMD8function16FunctionOfVectorINS0_7CombineEE9calculateEv22536
_ZN4PLMD8function16FunctionOfVectorINS0_7CombineEEC1ERKNS_13ActionOptionsE83
_ZN4PLMD8function16FunctionOfVectorINS0_7CombineEED0Ev83
_ZN4PLMD8function16FunctionOfVectorINS0_7CombineEED1Ev83
_ZN4PLMD8function16FunctionOfVectorINS0_7HighestEE16registerKeywordsERNS_8KeywordsE48
_ZN4PLMD8function16FunctionOfVectorINS0_7HighestEE17turnOnDerivativesEv106
_ZN4PLMD8function16FunctionOfVectorINS0_7HighestEE19areAllTasksRequiredERSt6vectorIPNS_16ActionWithVectorESaIS6_EE36
_ZN4PLMD8function16FunctionOfVectorINS0_7HighestEE21getNumberOfFinalTasksEv44
_ZN4PLMD8function16FunctionOfVectorINS0_7HighestEE22getNumberOfDerivativesEv5387
_ZN4PLMD8function16FunctionOfVectorINS0_7HighestEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSC_SC_SC_90
_ZN4PLMD8function16FunctionOfVectorINS0_7HighestEE24runSingleTaskCalculationEPKNS_5ValueEPNS_15ActionWithValueERS2_5290
_ZN4PLMD8function16FunctionOfVectorINS0_7HighestEE7prepareEv5384
_ZN4PLMD8function16FunctionOfVectorINS0_7HighestEE9calculateEv5380
_ZN4PLMD8function16FunctionOfVectorINS0_7HighestEEC1ERKNS_13ActionOptionsE44
_ZN4PLMD8function16FunctionOfVectorINS0_7HighestEED0Ev44
_ZN4PLMD8function16FunctionOfVectorINS0_7HighestEED1Ev44
_ZN4PLMD8function16FunctionOfVectorINS0_7MomentsEE16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD8function16FunctionOfVectorINS0_7MomentsEE17turnOnDerivativesEv2
_ZN4PLMD8function16FunctionOfVectorINS0_7MomentsEE19areAllTasksRequiredERSt6vectorIPNS_16ActionWithVectorESaIS6_EE0
_ZN4PLMD8function16FunctionOfVectorINS0_7MomentsEE21getNumberOfFinalTasksEv4
_ZN4PLMD8function16FunctionOfVectorINS0_7MomentsEE22getNumberOfDerivativesEv219
_ZN4PLMD8function16FunctionOfVectorINS0_7MomentsEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSC_SC_SC_0
_ZN4PLMD8function16FunctionOfVectorINS0_7MomentsEE24runSingleTaskCalculationEPKNS_5ValueEPNS_15ActionWithValueERS2_217
_ZN4PLMD8function16FunctionOfVectorINS0_7MomentsEE7prepareEv217
_ZN4PLMD8function16FunctionOfVectorINS0_7MomentsEE9calculateEv217
_ZN4PLMD8function16FunctionOfVectorINS0_7MomentsEEC1ERKNS_13ActionOptionsE4
_ZN4PLMD8function16FunctionOfVectorINS0_7MomentsEED0Ev4
_ZN4PLMD8function16FunctionOfVectorINS0_7MomentsEED1Ev4
_ZN4PLMD8function16FunctionOfVectorINS0_8LessThanEE16registerKeywordsERNS_8KeywordsE60
_ZN4PLMD8function16FunctionOfVectorINS0_8LessThanEE17turnOnDerivativesEv97
_ZN4PLMD8function16FunctionOfVectorINS0_8LessThanEE19areAllTasksRequiredERSt6vectorIPNS_16ActionWithVectorESaIS6_EE324
_ZN4PLMD8function16FunctionOfVectorINS0_8LessThanEE21getNumberOfFinalTasksEv58
_ZN4PLMD8function16FunctionOfVectorINS0_8LessThanEE22getNumberOfDerivativesEv97
_ZN4PLMD8function16FunctionOfVectorINS0_8LessThanEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSC_SC_SC_476
_ZN4PLMD8function16FunctionOfVectorINS0_8LessThanEE7prepareEv447
_ZN4PLMD8function16FunctionOfVectorINS0_8LessThanEE9calculateEv446
_ZN4PLMD8function16FunctionOfVectorINS0_8LessThanEEC1ERKNS_13ActionOptionsE58
_ZN4PLMD8function16FunctionOfVectorINS0_8LessThanEED0Ev58
_ZN4PLMD8function16FunctionOfVectorINS0_8LessThanEED1Ev58
_ZN4PLMD8function16FunctionOfVectorINS0_8MoreThanEE16registerKeywordsERNS_8KeywordsE64
_ZN4PLMD8function16FunctionOfVectorINS0_8MoreThanEE17turnOnDerivativesEv175
_ZN4PLMD8function16FunctionOfVectorINS0_8MoreThanEE19areAllTasksRequiredERSt6vectorIPNS_16ActionWithVectorESaIS6_EE245
_ZN4PLMD8function16FunctionOfVectorINS0_8MoreThanEE21getNumberOfFinalTasksEv62
_ZN4PLMD8function16FunctionOfVectorINS0_8MoreThanEE22getNumberOfDerivativesEv175
_ZN4PLMD8function16FunctionOfVectorINS0_8MoreThanEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSC_SC_SC_650
_ZN4PLMD8function16FunctionOfVectorINS0_8MoreThanEE7prepareEv521
_ZN4PLMD8function16FunctionOfVectorINS0_8MoreThanEE9calculateEv517
_ZN4PLMD8function16FunctionOfVectorINS0_8MoreThanEEC1ERKNS_13ActionOptionsE62
_ZN4PLMD8function16FunctionOfVectorINS0_8MoreThanEED0Ev62
_ZN4PLMD8function16FunctionOfVectorINS0_8MoreThanEED1Ev62
_ZN4PLMD8function16FunctionOfVectorINS_7refdist10DifferenceEE16registerKeywordsERNS_8KeywordsE145
_ZN4PLMD8function16FunctionOfVectorINS_7refdist10DifferenceEE17turnOnDerivativesEv2390
_ZN4PLMD8function16FunctionOfVectorINS_7refdist10DifferenceEE19areAllTasksRequiredERSt6vectorIPNS_16ActionWithVectorESaIS7_EE71
_ZN4PLMD8function16FunctionOfVectorINS_7refdist10DifferenceEE21getNumberOfFinalTasksEv143
_ZN4PLMD8function16FunctionOfVectorINS_7refdist10DifferenceEE22getNumberOfDerivativesEv2390
_ZN4PLMD8function16FunctionOfVectorINS_7refdist10DifferenceEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSD_SD_SD_94404
_ZN4PLMD8function16FunctionOfVectorINS_7refdist10DifferenceEE7prepareEv49487
_ZN4PLMD8function16FunctionOfVectorINS_7refdist10DifferenceEE9calculateEv49487
_ZN4PLMD8function16FunctionOfVectorINS_7refdist10DifferenceEEC1ERKNS_13ActionOptionsE143
_ZN4PLMD8function16FunctionOfVectorINS_7refdist10DifferenceEED0Ev143
_ZN4PLMD8function16FunctionOfVectorINS_7refdist10DifferenceEED1Ev143
_ZN4PLMD8function16FunctionOfVectorINS_9gridtools20EvaluateGridFunctionEE16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD8function16FunctionOfVectorINS_9gridtools20EvaluateGridFunctionEE17turnOnDerivativesEv2
_ZN4PLMD8function16FunctionOfVectorINS_9gridtools20EvaluateGridFunctionEE19areAllTasksRequiredERSt6vectorIPNS_16ActionWithVectorESaIS7_EE2
_ZN4PLMD8function16FunctionOfVectorINS_9gridtools20EvaluateGridFunctionEE21getNumberOfFinalTasksEv1
_ZN4PLMD8function16FunctionOfVectorINS_9gridtools20EvaluateGridFunctionEE22getNumberOfDerivativesEv2
_ZN4PLMD8function16FunctionOfVectorINS_9gridtools20EvaluateGridFunctionEE23setupStreamedComponentsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjSD_SD_SD_1675
_ZN4PLMD8function16FunctionOfVectorINS_9gridtools20EvaluateGridFunctionEE7prepareEv1675
_ZN4PLMD8function16FunctionOfVectorINS_9gridtools20EvaluateGridFunctionEE9calculateEv1675
_ZN4PLMD8function16FunctionOfVectorINS_9gridtools20EvaluateGridFunctionEEC1ERKNS_13ActionOptionsE1
_ZN4PLMD8function16FunctionOfVectorINS_9gridtools20EvaluateGridFunctionEED0Ev1
_ZN4PLMD8function16FunctionOfVectorINS_9gridtools20EvaluateGridFunctionEED1Ev1
_ZNK4PLMD8function16FunctionOfVectorINS0_3SumEE11performTaskERKjRNS_10MultiValueE1252574
_ZNK4PLMD8function16FunctionOfVectorINS0_3SumEE12writeInGraphB5cxx11Ev7
_ZNK4PLMD8function16FunctionOfVectorINS0_4SortEE11performTaskERKjRNS_10MultiValueE0
_ZNK4PLMD8function16FunctionOfVectorINS0_4SortEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD8function16FunctionOfVectorINS0_6BesselEE11performTaskERKjRNS_10MultiValueE14
_ZNK4PLMD8function16FunctionOfVectorINS0_6BesselEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD8function16FunctionOfVectorINS0_6CustomEE11performTaskERKjRNS_10MultiValueE1900084
_ZNK4PLMD8function16FunctionOfVectorINS0_6CustomEE12writeInGraphB5cxx11Ev2
_ZNK4PLMD8function16FunctionOfVectorINS0_7BetweenEE11performTaskERKjRNS_10MultiValueE716
_ZNK4PLMD8function16FunctionOfVectorINS0_7BetweenEE12writeInGraphB5cxx11Ev1
_ZNK4PLMD8function16FunctionOfVectorINS0_7CombineEE11performTaskERKjRNS_10MultiValueE357792
_ZNK4PLMD8function16FunctionOfVectorINS0_7CombineEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD8function16FunctionOfVectorINS0_7HighestEE11performTaskERKjRNS_10MultiValueE18499
_ZNK4PLMD8function16FunctionOfVectorINS0_7HighestEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD8function16FunctionOfVectorINS0_7MomentsEE11performTaskERKjRNS_10MultiValueE0
_ZNK4PLMD8function16FunctionOfVectorINS0_7MomentsEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD8function16FunctionOfVectorINS0_8LessThanEE11performTaskERKjRNS_10MultiValueE121283
_ZNK4PLMD8function16FunctionOfVectorINS0_8LessThanEE12writeInGraphB5cxx11Ev2
_ZNK4PLMD8function16FunctionOfVectorINS0_8MoreThanEE11performTaskERKjRNS_10MultiValueE53152
_ZNK4PLMD8function16FunctionOfVectorINS0_8MoreThanEE12writeInGraphB5cxx11Ev8
_ZNK4PLMD8function16FunctionOfVectorINS_7refdist10DifferenceEE11performTaskERKjRNS_10MultiValueE2876173
_ZNK4PLMD8function16FunctionOfVectorINS_7refdist10DifferenceEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD8function16FunctionOfVectorINS_9gridtools20EvaluateGridFunctionEE11performTaskERKjRNS_10MultiValueE8375
_ZNK4PLMD8function16FunctionOfVectorINS_9gridtools20EvaluateGridFunctionEE12writeInGraphB5cxx11Ev0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/FunctionOfVector.h.gcov.html b/coverage/function/FunctionOfVector.h.gcov.html new file mode 100644 index 000000000000..d0a50f7cea59 --- /dev/null +++ b/coverage/function/FunctionOfVector.h.gcov.html @@ -0,0 +1,420 @@ + + + + + + + + LCOV - plumed test coverage - function/FunctionOfVector.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - FunctionOfVector.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:14415493.5 %
Date:2024-04-19 12:12:35Functions:14515991.2 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2020 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a 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_FunctionOfVector_h
+      23             : #define __PLUMED_function_FunctionOfVector_h
+      24             : 
+      25             : #include "core/ActionWithVector.h"
+      26             : //#include "core/CollectFrames.h"
+      27             : #include "core/ActionSetup.h"
+      28             : #include "tools/Matrix.h"
+      29             : #include "Sum.h"
+      30             : 
+      31             : namespace PLMD {
+      32             : namespace function {
+      33             : 
+      34             : template <class T>
+      35             : class FunctionOfVector : public ActionWithVector {
+      36             : private:
+      37             : /// Do the calculation at the end of the run
+      38             :   bool doAtEnd;
+      39             : /// Is this the first time we are doing the calc
+      40             :   bool firststep;
+      41             : /// The function that is being computed
+      42             :   T myfunc;
+      43             : /// The number of derivatives for this action
+      44             :   unsigned nderivatives;
+      45             : /// A vector that tells us if we have stored the input value
+      46             :   std::vector<bool> stored_arguments;
+      47             : public:
+      48             :   static void registerKeywords(Keywords&);
+      49             : /// This method is used to run the calculation with functions such as highest/lowest and sort.
+      50             : /// It is static so we can reuse the functionality in FunctionOfMatrix
+      51             :   static void runSingleTaskCalculation( const Value* arg, ActionWithValue* action, T& f );
+      52             :   explicit FunctionOfVector(const ActionOptions&);
+      53        4590 :   ~FunctionOfVector() {}
+      54             : /// Get the size of the task list at the end of the run
+      55             :   unsigned getNumberOfFinalTasks();
+      56             : /// Check if derivatives are available
+      57             :   void turnOnDerivatives() override;
+      58             : /// Get the number of derivatives for this action
+      59             :   unsigned getNumberOfDerivatives() override ;
+      60             : /// Resize vectors that are the wrong size
+      61             :   void prepare() override ;
+      62             : /// Check if all he actions are required
+      63             :   void areAllTasksRequired( std::vector<ActionWithVector*>& task_reducing_actions );
+      64             : /// Get the label to write in the graph
+      65          20 :   std::string writeInGraph() const override { return myfunc.getGraphInfo( getName() ); }
+      66             : /// This builds the task list for the action
+      67             :   void calculate() override;
+      68             : /// This ensures that we create some bookeeping stuff during the first step
+      69             :   void setupStreamedComponents( const std::string& headstr, unsigned& nquants, unsigned& nmat, unsigned& maxcol, unsigned& nbookeeping ) override ;
+      70             : /// Calculate the function
+      71             :   void performTask( const unsigned& current, MultiValue& myvals ) const override ;
+      72             : };
+      73             : 
+      74             : template <class T>
+      75        2263 : void FunctionOfVector<T>::registerKeywords(Keywords& keys ) {
+      76        2263 :   Action::registerKeywords(keys); ActionWithValue::registerKeywords(keys); ActionWithArguments::registerKeywords(keys); keys.use("ARG");
+      77        4526 :   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");
+      78        4526 :   keys.add("hidden","NO_ACTION_LOG","suppresses printing from action on the log");
+      79        2070 :   T tfunc; tfunc.registerKeywords( keys );
+      80        2263 : }
+      81             : 
+      82             : template <class T>
+      83        2233 : FunctionOfVector<T>::FunctionOfVector(const ActionOptions&ao):
+      84             :   Action(ao),
+      85             :   ActionWithVector(ao),
+      86        2233 :   doAtEnd(true),
+      87        2233 :   firststep(true),
+      88        2233 :   nderivatives(0)
+      89             : {
+      90             :   // Get the shape of the output
+      91        2233 :   std::vector<unsigned> shape(1); shape[0]=getNumberOfFinalTasks();
+      92             :   // Read the input and do some checks
+      93        2233 :   myfunc.read( this );
+      94             :   // Create the task list
+      95        2090 :   if( myfunc.doWithTasks() ) {
+      96        2195 :     doAtEnd=false; if( shape[0]>0 ) done_in_chain=true;
+      97          38 :   } else { plumed_assert( getNumberOfArguments()==1 ); done_in_chain=false; getPntrToArgument(0)->buildDataStore(); }
+      98             :   // Get the names of the components
+      99        2233 :   std::vector<std::string> components( keywords.getOutputComponents() );
+     100             :   // Create the values to hold the output
+     101          50 :   std::vector<std::string> str_ind( myfunc.getComponentsPerLabel() );
+     102        1618 :   if( components.size()==0 && myfunc.zeroRank() && str_ind.size()==0 ) addValueWithDerivatives();
+     103          18 :   else if( components.size()==0 && myfunc.zeroRank() ) {
+     104          16 :     for(unsigned j=0; j<str_ind.size(); ++j) addComponentWithDerivatives( str_ind[j] );
+     105        1431 :   } else if( components.size()==0 && str_ind.size()==0 ) addValue( shape );
+     106           4 :   else if( components.size()==0 ) {
+     107           0 :     for(unsigned j=0; j<str_ind.size(); ++j) addComponent( str_ind[j], shape );
+     108             :   } else {
+     109           8 :     for(unsigned i=0; i<components.size(); ++i) {
+     110           4 :       if( str_ind.size()>0 ) {
+     111          11 :         for(unsigned j=0; j<str_ind.size(); ++j) {
+     112          14 :           if( myfunc.zeroRank() ) addComponentWithDerivatives( components[i] + str_ind[j] );
+     113           0 :           else addComponent( components[i] + str_ind[j], shape );
+     114             :         }
+     115           0 :       } else if( components[i].find_first_of("_")!=std::string::npos ) {
+     116           0 :         if( getNumberOfArguments()==1 && myfunc.zeroRank() ) addValueWithDerivatives();
+     117           0 :         else if( getNumberOfArguments()==1 ) addValue( shape );
+     118             :         else {
+     119             :           unsigned argstart=myfunc.getArgStart();
+     120           0 :           for(unsigned i=argstart; i<getNumberOfArguments(); ++i) {
+     121           0 :             if( myfunc.zeroRank() ) addComponentWithDerivatives( getPntrToArgument(i)->getName() + components[i] );
+     122           0 :             else addComponent( getPntrToArgument(i)->getName() + components[i], shape );
+     123             :           }
+     124             :         }
+     125           0 :       } else if( myfunc.zeroRank() ) addComponentWithDerivatives( components[i] );
+     126           0 :       else addComponent( components[i], shape );
+     127             :     }
+     128             :   }
+     129             :   // Check if we can turn off the derivatives when they are zero
+     130        1009 :   if( myfunc.getDerivativeZeroIfValueIsZero() )  {
+     131         596 :     for(int i=0; i<getNumberOfComponents(); ++i) getPntrToComponent(i)->setDerivativeIsZeroWhenValueIsZero();
+     132             :   }
+     133             :   // Check if this is a timeseries
+     134             :   unsigned argstart=myfunc.getArgStart();
+     135             :   // for(unsigned i=argstart; i<getNumberOfArguments();++i) {
+     136             :   //   if( getPntrToArgument(i)->isTimeSeries() ) {
+     137             :   //       for(unsigned i=0; i<getNumberOfComponents(); ++i) getPntrToOutput(i)->makeHistoryDependent();
+     138             :   //       break;
+     139             :   //   }
+     140             :   // }
+     141             :   // Set the periodicities of the output components
+     142        2233 :   myfunc.setPeriodicityForOutputs( this );
+     143             :   // Check if we can put the function in a chain
+     144        6070 :   for(unsigned i=argstart; i<getNumberOfArguments(); ++i) {
+     145             :     // CollectFrames* ab=dynamic_cast<CollectFrames*>( getPntrToArgument(i)->getPntrToAction() );
+     146             :     // if( ab && ab->hasClear() ) { doNotChain=true; getPntrToArgument(i)->buildDataStore( getLabel() ); }
+     147             :     // No chains if we are using a sum or a mean
+     148        3837 :     if( getPntrToArgument(i)->getRank()==0 ) {
+     149         246 :       FunctionOfVector<Sum>* as = dynamic_cast<FunctionOfVector<Sum>*>( getPntrToArgument(i)->getPntrToAction() );
+     150         246 :       if(as) done_in_chain=false;
+     151             :     } else {
+     152        3591 :       ActionWithVector* av=dynamic_cast<ActionWithVector*>( getPntrToArgument(i)->getPntrToAction() );
+     153        3591 :       if( !av ) done_in_chain=false;
+     154             :     }
+     155             :   }
+     156             :   // Don't need to do the calculation in a chain if the input is constant
+     157             :   bool allconstant=true;
+     158        2560 :   for(unsigned i=argstart; i<getNumberOfArguments(); ++i) {
+     159        2244 :     if( !getPntrToArgument(i)->isConstant() ) { allconstant=false; break; }
+     160             :   }
+     161        2233 :   if( allconstant ) done_in_chain=false;
+     162        2233 :   nderivatives = buildArgumentStore(myfunc.getArgStart());
+     163        4466 : }
+     164             : 
+     165             : template <class T>
+     166        6100 : void FunctionOfVector<T>::turnOnDerivatives() {
+     167        6100 :   if( !getPntrToComponent(0)->isConstant() && !myfunc.derivativesImplemented() ) error("derivatives have not been implemended for " + getName() );
+     168        6100 :   ActionWithValue::turnOnDerivatives(); myfunc.setup(this );
+     169        6100 : }
+     170             : 
+     171             : template <class T>
+     172       52935 : unsigned FunctionOfVector<T>::getNumberOfDerivatives() {
+     173       52935 :   return nderivatives;
+     174             : }
+     175             : 
+     176             : template <class T>
+     177      185433 : void FunctionOfVector<T>::prepare() {
+     178      185433 :   unsigned argstart = myfunc.getArgStart(); std::vector<unsigned> shape(1);
+     179      232411 :   for(unsigned i=argstart; i<getNumberOfArguments(); ++i) {
+     180      232411 :     if( getPntrToArgument(i)->getRank()==1 ) {
+     181      185433 :       shape[0] = getPntrToArgument(i)->getShape()[0]; break;
+     182             :     }
+     183             :   }
+     184      371282 :   for(unsigned i=0; i<getNumberOfComponents(); ++i) {
+     185      185849 :     Value* myval = getPntrToComponent(i);
+     186      185849 :     if( myval->getRank()==1 && myval->getShape()[0]!=shape[0] ) { myval->setShape(shape); }
+     187             :   }
+     188      185433 :   ActionWithVector::prepare();
+     189      185433 : }
+     190             : 
+     191             : template <class T>
+     192      312444 : void FunctionOfVector<T>::setupStreamedComponents( const std::string& headstr, unsigned& nquants, unsigned& nmat, unsigned& maxcol, unsigned& nbookeeping ) {
+     193      312444 :   if( firststep ) {
+     194        2149 :     stored_arguments.resize( getNumberOfArguments() );
+     195        2149 :     std::string control = getFirstActionInChain()->getLabel();
+     196        5895 :     for(unsigned i=0; i<stored_arguments.size(); ++i) {
+     197        3746 :       if( getPntrToArgument(i)->isConstant() ) stored_arguments[i]=false;
+     198        3231 :       else stored_arguments[i] = !getPntrToArgument(i)->ignoreStoredValue( control );
+     199             :     }
+     200        2149 :     firststep=false;
+     201             :   }
+     202      312444 :   ActionWithVector::setupStreamedComponents( headstr, nquants, nmat, maxcol, nbookeeping );
+     203      312444 : }
+     204             : 
+     205             : template <class T>
+     206     6588662 : void FunctionOfVector<T>::performTask( const unsigned& current, MultiValue& myvals ) const {
+     207     6588662 :   unsigned argstart=myfunc.getArgStart(); std::vector<double> args( getNumberOfArguments()-argstart);
+     208     6588662 :   if( actionInChain() ) {
+     209     6732111 :     for(unsigned i=argstart; i<getNumberOfArguments(); ++i) {
+     210     3869154 :       if(  getPntrToArgument(i)->getRank()==0 ) args[i-argstart] = getPntrToArgument(i)->get();
+     211     3851366 :       else if( !getPntrToArgument(i)->valueHasBeenSet() ) args[i-argstart] = myvals.get( getPntrToArgument(i)->getPositionInStream() );
+     212      154930 :       else args[i-argstart] = getPntrToArgument(i)->get( myvals.getTaskIndex() );
+     213             :     }
+     214             :   } else {
+     215    11032784 :     for(unsigned i=argstart; i<getNumberOfArguments(); ++i) {
+     216     7307079 :       if( getPntrToArgument(i)->getRank()==1 ) args[i-argstart]=getPntrToArgument(i)->get(current);
+     217     3242545 :       else args[i-argstart] = getPntrToArgument(i)->get();
+     218             :     }
+     219             :   }
+     220             :   // Calculate the function and its derivatives
+     221     6588662 :   std::vector<double> vals( getNumberOfComponents() ); Matrix<double> derivatives( getNumberOfComponents(), args.size() );
+     222     6588662 :   myfunc.calc( this, args, vals, derivatives );
+     223             :   // And set the values
+     224    13177324 :   for(unsigned i=0; i<vals.size(); ++i) myvals.addValue( getConstPntrToComponent(i)->getPositionInStream(), vals[i] );
+     225             :   // Return if we are not computing derivatives
+     226     6588662 :   if( doNotCalculateDerivatives() ) return;
+     227             :   // And now compute the derivatives
+     228             :   // Second condition here is only not true if actionInChain()==True if
+     229             :   // input arguments the only non-constant objects in input are scalars.
+     230             :   // In that case we can use the non chain version to calculate the derivatives
+     231             :   // with respect to the scalar.
+     232     5676052 :   if( actionInChain() ) {
+     233     5083370 :     for(unsigned j=0; j<args.size(); ++j) {
+     234        8375 :       unsigned istrn = getPntrToArgument(argstart+j)->getPositionInStream();
+     235     2831929 :       if( stored_arguments[argstart+j] ) {
+     236          70 :         unsigned task_index = myvals.getTaskIndex(); if( getPntrToArgument(argstart+j)->getRank()==0 ) task_index=0;
+     237          70 :         myvals.addDerivative( istrn, task_index, 1.0 ); myvals.updateIndex( istrn, task_index );
+     238             :       }
+     239     2831929 :       unsigned arg_deriv_s = arg_deriv_starts[argstart+j];
+     240   173560439 :       for(unsigned k=0; k<myvals.getNumberActive(istrn); ++k) {
+     241   170728510 :         unsigned kind=myvals.getActiveIndex(istrn,k);
+     242   341457020 :         for(int i=0; i<getNumberOfComponents(); ++i) {
+     243   170728510 :           unsigned ostrn=getConstPntrToComponent(i)->getPositionInStream();
+     244   170728510 :           myvals.addDerivative( ostrn, arg_deriv_s + kind, derivatives(i,j)*myvals.getDerivative( istrn, kind ) );
+     245             :         }
+     246             :       }
+     247             :       // Ensure we only store one lot of derivative indices
+     248     2831929 :       bool found=false; ActionWithValue* aav=getPntrToArgument(argstart+j)->getPntrToAction();
+     249     2865851 :       for(unsigned k=0; k<j; ++k) {
+     250      580552 :         if( arg_deriv_starts[argstart+k]==arg_deriv_s ) {
+     251      546630 :           if( getPntrToArgument(argstart+k)->getPntrToAction()!=aav ) {
+     252      386484 :             ActionWithVector* av = dynamic_cast<ActionWithVector*>( getPntrToArgument(argstart+j)->getPntrToAction() );
+     253      386484 :             if( av ) {
+     254      772968 :               for(int i=0; i<getNumberOfComponents(); ++i) av->updateAdditionalIndices( getConstPntrToComponent(i)->getPositionInStream(), myvals );
+     255             :             }
+     256             :           }
+     257             :           found=true; break;
+     258             :         }
+     259             :       }
+     260      546630 :       if( found ) continue;
+     261   118643126 :       for(unsigned k=0; k<myvals.getNumberActive(istrn); ++k) {
+     262   116357827 :         unsigned kind=myvals.getActiveIndex(istrn,k);
+     263   232715654 :         for(int i=0; i<getNumberOfComponents(); ++i) {
+     264   116357827 :           unsigned ostrn=getConstPntrToComponent(i)->getPositionInStream();
+     265   116357827 :           myvals.updateIndex( ostrn, arg_deriv_s + kind );
+     266             :         }
+     267             :       }
+     268             :     }
+     269             :   } else {
+     270             :     unsigned base=0;
+     271    10141540 :     for(unsigned j=0; j<args.size(); ++j) {
+     272     6716929 :       if( getPntrToArgument(argstart+j)->getRank()==1 ) {
+     273     7241248 :         for(int i=0; i<getNumberOfComponents(); ++i) {
+     274     3620624 :           unsigned ostrn=getConstPntrToComponent(i)->getPositionInStream();
+     275     3620624 :           myvals.addDerivative( ostrn, base+current, derivatives(i,j) );
+     276     3620624 :           myvals.updateIndex( ostrn, base+current );
+     277             :         }
+     278             :       } else {
+     279     6192610 :         for(int i=0; i<getNumberOfComponents(); ++i) {
+     280     3096305 :           unsigned ostrn=getConstPntrToComponent(i)->getPositionInStream();
+     281     3096305 :           myvals.addDerivative( ostrn, base, derivatives(i,j) );
+     282     3096305 :           myvals.updateIndex( ostrn, base );
+     283             :         }
+     284             :       }
+     285     6716929 :       base += getPntrToArgument(argstart+j)->getNumberOfValues();
+     286             :     }
+     287             :   }
+     288             : }
+     289             : 
+     290             : template <class T>
+     291        2233 : unsigned FunctionOfVector<T>::getNumberOfFinalTasks() {
+     292             :   unsigned nelements=0, argstart=myfunc.getArgStart();
+     293        6070 :   for(unsigned i=argstart; i<getNumberOfArguments(); ++i) {
+     294        3837 :     plumed_assert( getPntrToArgument(i)->getRank()<2 );
+     295        3837 :     if( getPntrToArgument(i)->getRank()==1 ) {
+     296        3591 :       if( nelements>0 ) {
+     297             :         // if( getPntrToArgument(i)->isTimeSeries() && getPntrToArgument(i)->getShape()[0]<nelements ) nelements=getPntrToArgument(i)->isTimeSeries();
+     298             :         // else
+     299        1358 :         if(getPntrToArgument(i)->getShape()[0]!=nelements ) error("all vectors input should have the same length");
+     300        2233 :       } else if( nelements==0 ) nelements=getPntrToArgument(i)->getShape()[0];
+     301        3591 :       plumed_assert( !getPntrToArgument(i)->hasDerivatives() );
+     302             :     }
+     303             :   }
+     304             :   // The prefactor for average and sum is set here so the number of input scalars is guaranteed to be correct
+     305         768 :   myfunc.setPrefactor( this, 1.0 );
+     306        2233 :   return nelements;
+     307             : }
+     308             : 
+     309             : template <class T>
+     310       12074 : void FunctionOfVector<T>::areAllTasksRequired( std::vector<ActionWithVector*>& task_reducing_actions ) {
+     311       12074 :   if( task_reducing_actions.size()==0 ) return;
+     312        2194 :   if( !myfunc.allComponentsRequired( getArguments(), task_reducing_actions ) ) task_reducing_actions.push_back(this);
+     313             : }
+     314             : 
+     315             : template <class T>
+     316        5541 : void FunctionOfVector<T>::runSingleTaskCalculation( const Value* arg, ActionWithValue* action, T& f ) {
+     317             :   // This is used if we are doing sorting actions on a single vector
+     318        5541 :   unsigned nv = arg->getNumberOfValues(); std::vector<double> args( nv );
+     319     8198467 :   for(unsigned i=0; i<nv; ++i) args[i] = arg->get(i);
+     320        5541 :   std::vector<double> vals( action->getNumberOfComponents() ); Matrix<double> derivatives( action->getNumberOfComponents(), nv );
+     321        5541 :   ActionWithArguments* aa=dynamic_cast<ActionWithArguments*>(action); plumed_assert( aa ); f.calc( aa, args, vals, derivatives );
+     322       11498 :   for(unsigned i=0; i<vals.size(); ++i) action->copyOutput(i)->set( vals[i] );
+     323             :   // Return if we are not computing derivatives
+     324        5541 :   if( action->doNotCalculateDerivatives() ) return;
+     325             :   // Now set the derivatives
+     326      198059 :   for(unsigned j=0; j<nv; ++j) {
+     327      388720 :     for(unsigned i=0; i<vals.size(); ++i) action->copyOutput(i)->setDerivative( j, derivatives(i,j) );
+     328             :   }
+     329             : }
+     330             : 
+     331             : template <class T>
+     332      184804 : void FunctionOfVector<T>::calculate() {
+     333             :   // Everything is done elsewhere
+     334      184804 :   if( actionInChain() ) return;
+     335             :   // This is done if we are calculating a function of multiple cvs
+     336       80091 :   if( !doAtEnd ) runAllTasks();
+     337             :   // This is used if we are doing sorting actions on a single vector
+     338        5541 :   else if( !myfunc.doWithTasks() ) runSingleTaskCalculation( getPntrToArgument(0), this, myfunc );
+     339             : }
+     340             : 
+     341             : }
+     342             : }
+     343             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/FunctionShortcut.h.func-sort-c.html b/coverage/function/FunctionShortcut.h.func-sort-c.html new file mode 100644 index 000000000000..f54aa0a74edf --- /dev/null +++ b/coverage/function/FunctionShortcut.h.func-sort-c.html @@ -0,0 +1,257 @@ + + + + + + + + LCOV - plumed test coverage - function/FunctionShortcut.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - FunctionShortcut.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:283384.8 %
Date:2024-04-19 12:12:35Functions:4646100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function16FunctionShortcutINS_7symfunc19CylindricalHarmonicEE12createActionEPNS_14ActionShortcutERKSt6vectorIPNS_5ValueESaIS9_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1
_ZN4PLMD8function16FunctionShortcutINS_7symfunc19CylindricalHarmonicEEC1ERKNS_13ActionOptionsE1
_ZN4PLMD8function16FunctionShortcutIiE12createActionEPNS_14ActionShortcutERKSt6vectorIPNS_5ValueESaIS7_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZN4PLMD8function16FunctionShortcutINS0_9PiecewiseEE12createActionEPNS_14ActionShortcutERKSt6vectorIPNS_5ValueESaIS8_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3
_ZN4PLMD8function16FunctionShortcutINS0_9PiecewiseEEC1ERKNS_13ActionOptionsE3
_ZN4PLMD8function16FunctionShortcutINS_7symfunc19CylindricalHarmonicEE16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD8function16FunctionShortcutINS0_7MomentsEE12createActionEPNS_14ActionShortcutERKSt6vectorIPNS_5ValueESaIS8_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE5
_ZN4PLMD8function16FunctionShortcutINS0_7MomentsEEC1ERKNS_13ActionOptionsE5
_ZN4PLMD8function16FunctionShortcutINS0_9PiecewiseEE16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD8function16FunctionShortcutINS_7symfunc7FccubicEE12createActionEPNS_14ActionShortcutERKSt6vectorIPNS_5ValueESaIS9_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE5
_ZN4PLMD8function16FunctionShortcutINS_7symfunc7FccubicEEC1ERKNS_13ActionOptionsE5
_ZN4PLMD8function16FunctionShortcutINS0_6BesselEE12createActionEPNS_14ActionShortcutERKSt6vectorIPNS_5ValueESaIS8_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE7
_ZN4PLMD8function16FunctionShortcutINS0_6BesselEEC1ERKNS_13ActionOptionsE7
_ZN4PLMD8function16FunctionShortcutINS_7symfunc7FccubicEE16registerKeywordsERNS_8KeywordsE7
_ZN4PLMD8function16FunctionShortcutINS0_6BesselEE16registerKeywordsERNS_8KeywordsE9
_ZN4PLMD8function16FunctionShortcutINS0_7MomentsEE16registerKeywordsERNS_8KeywordsE13
_ZN4PLMD8function16FunctionShortcutINS0_4SortEE12createActionEPNS_14ActionShortcutERKSt6vectorIPNS_5ValueESaIS8_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE14
_ZN4PLMD8function16FunctionShortcutINS0_4SortEEC1ERKNS_13ActionOptionsE14
_ZN4PLMD8function16FunctionShortcutINS0_4SortEE16registerKeywordsERNS_8KeywordsE20
_ZN4PLMD8function16FunctionShortcutINS_7symfunc17SphericalHarmonicEE12createActionEPNS_14ActionShortcutERKSt6vectorIPNS_5ValueESaIS9_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE41
_ZN4PLMD8function16FunctionShortcutINS_7symfunc17SphericalHarmonicEEC1ERKNS_13ActionOptionsE41
_ZN4PLMD8function16FunctionShortcutINS0_7HighestEE12createActionEPNS_14ActionShortcutERKSt6vectorIPNS_5ValueESaIS8_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE46
_ZN4PLMD8function16FunctionShortcutINS0_7HighestEEC1ERKNS_13ActionOptionsE46
_ZN4PLMD8function16FunctionShortcutINS0_7HighestEE16registerKeywordsERNS_8KeywordsE50
_ZN4PLMD8function16FunctionShortcutINS0_7BetweenEE12createActionEPNS_14ActionShortcutERKSt6vectorIPNS_5ValueESaIS8_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE53
_ZN4PLMD8function16FunctionShortcutINS0_7BetweenEEC1ERKNS_13ActionOptionsE53
_ZN4PLMD8function16FunctionShortcutINS0_7BetweenEE16registerKeywordsERNS_8KeywordsE55
_ZN4PLMD8function16FunctionShortcutINS0_8LessThanEE12createActionEPNS_14ActionShortcutERKSt6vectorIPNS_5ValueESaIS8_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE59
_ZN4PLMD8function16FunctionShortcutINS0_8LessThanEEC1ERKNS_13ActionOptionsE59
_ZN4PLMD8function16FunctionShortcutINS0_8LessThanEE16registerKeywordsERNS_8KeywordsE61
_ZN4PLMD8function16FunctionShortcutINS0_8MoreThanEE12createActionEPNS_14ActionShortcutERKSt6vectorIPNS_5ValueESaIS8_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE68
_ZN4PLMD8function16FunctionShortcutINS0_8MoreThanEEC1ERKNS_13ActionOptionsE68
_ZN4PLMD8function16FunctionShortcutINS0_8MoreThanEE16registerKeywordsERNS_8KeywordsE70
_ZN4PLMD8function16FunctionShortcutINS_7symfunc17SphericalHarmonicEE16registerKeywordsERNS_8KeywordsE84
_ZN4PLMD8function16FunctionShortcutINS_7refdist10DifferenceEE12createActionEPNS_14ActionShortcutERKSt6vectorIPNS_5ValueESaIS9_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE184
_ZN4PLMD8function16FunctionShortcutINS_7refdist10DifferenceEEC1ERKNS_13ActionOptionsE184
_ZN4PLMD8function16FunctionShortcutINS_7refdist10DifferenceEE16registerKeywordsERNS_8KeywordsE186
_ZN4PLMD8function16FunctionShortcutINS0_7CombineEE12createActionEPNS_14ActionShortcutERKSt6vectorIPNS_5ValueESaIS8_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE303
_ZN4PLMD8function16FunctionShortcutINS0_7CombineEEC1ERKNS_13ActionOptionsE303
_ZN4PLMD8function16FunctionShortcutINS0_7CombineEE16registerKeywordsERNS_8KeywordsE307
_ZN4PLMD8function16FunctionShortcutINS0_3SumEE12createActionEPNS_14ActionShortcutERKSt6vectorIPNS_5ValueESaIS8_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE809
_ZN4PLMD8function16FunctionShortcutINS0_3SumEEC1ERKNS_13ActionOptionsE809
_ZN4PLMD8function16FunctionShortcutINS0_3SumEE16registerKeywordsERNS_8KeywordsE818
_ZN4PLMD8function16FunctionShortcutINS0_6CustomEE12createActionEPNS_14ActionShortcutERKSt6vectorIPNS_5ValueESaIS8_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2982
_ZN4PLMD8function16FunctionShortcutINS0_6CustomEEC1ERKNS_13ActionOptionsE2982
_ZN4PLMD8function16FunctionShortcutINS0_6CustomEE16registerKeywordsERNS_8KeywordsE3021
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/FunctionShortcut.h.func.html b/coverage/function/FunctionShortcut.h.func.html new file mode 100644 index 000000000000..d3c1bd5690da --- /dev/null +++ b/coverage/function/FunctionShortcut.h.func.html @@ -0,0 +1,257 @@ + + + + + + + + LCOV - plumed test coverage - function/FunctionShortcut.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - FunctionShortcut.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:283384.8 %
Date:2024-04-19 12:12:35Functions:4646100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function16FunctionShortcutINS0_3SumEE12createActionEPNS_14ActionShortcutERKSt6vectorIPNS_5ValueESaIS8_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE809
_ZN4PLMD8function16FunctionShortcutINS0_3SumEE16registerKeywordsERNS_8KeywordsE818
_ZN4PLMD8function16FunctionShortcutINS0_3SumEEC1ERKNS_13ActionOptionsE809
_ZN4PLMD8function16FunctionShortcutINS0_4SortEE12createActionEPNS_14ActionShortcutERKSt6vectorIPNS_5ValueESaIS8_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE14
_ZN4PLMD8function16FunctionShortcutINS0_4SortEE16registerKeywordsERNS_8KeywordsE20
_ZN4PLMD8function16FunctionShortcutINS0_4SortEEC1ERKNS_13ActionOptionsE14
_ZN4PLMD8function16FunctionShortcutINS0_6BesselEE12createActionEPNS_14ActionShortcutERKSt6vectorIPNS_5ValueESaIS8_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE7
_ZN4PLMD8function16FunctionShortcutINS0_6BesselEE16registerKeywordsERNS_8KeywordsE9
_ZN4PLMD8function16FunctionShortcutINS0_6BesselEEC1ERKNS_13ActionOptionsE7
_ZN4PLMD8function16FunctionShortcutINS0_6CustomEE12createActionEPNS_14ActionShortcutERKSt6vectorIPNS_5ValueESaIS8_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2982
_ZN4PLMD8function16FunctionShortcutINS0_6CustomEE16registerKeywordsERNS_8KeywordsE3021
_ZN4PLMD8function16FunctionShortcutINS0_6CustomEEC1ERKNS_13ActionOptionsE2982
_ZN4PLMD8function16FunctionShortcutINS0_7BetweenEE12createActionEPNS_14ActionShortcutERKSt6vectorIPNS_5ValueESaIS8_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE53
_ZN4PLMD8function16FunctionShortcutINS0_7BetweenEE16registerKeywordsERNS_8KeywordsE55
_ZN4PLMD8function16FunctionShortcutINS0_7BetweenEEC1ERKNS_13ActionOptionsE53
_ZN4PLMD8function16FunctionShortcutINS0_7CombineEE12createActionEPNS_14ActionShortcutERKSt6vectorIPNS_5ValueESaIS8_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE303
_ZN4PLMD8function16FunctionShortcutINS0_7CombineEE16registerKeywordsERNS_8KeywordsE307
_ZN4PLMD8function16FunctionShortcutINS0_7CombineEEC1ERKNS_13ActionOptionsE303
_ZN4PLMD8function16FunctionShortcutINS0_7HighestEE12createActionEPNS_14ActionShortcutERKSt6vectorIPNS_5ValueESaIS8_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE46
_ZN4PLMD8function16FunctionShortcutINS0_7HighestEE16registerKeywordsERNS_8KeywordsE50
_ZN4PLMD8function16FunctionShortcutINS0_7HighestEEC1ERKNS_13ActionOptionsE46
_ZN4PLMD8function16FunctionShortcutINS0_7MomentsEE12createActionEPNS_14ActionShortcutERKSt6vectorIPNS_5ValueESaIS8_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE5
_ZN4PLMD8function16FunctionShortcutINS0_7MomentsEE16registerKeywordsERNS_8KeywordsE13
_ZN4PLMD8function16FunctionShortcutINS0_7MomentsEEC1ERKNS_13ActionOptionsE5
_ZN4PLMD8function16FunctionShortcutINS0_8LessThanEE12createActionEPNS_14ActionShortcutERKSt6vectorIPNS_5ValueESaIS8_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE59
_ZN4PLMD8function16FunctionShortcutINS0_8LessThanEE16registerKeywordsERNS_8KeywordsE61
_ZN4PLMD8function16FunctionShortcutINS0_8LessThanEEC1ERKNS_13ActionOptionsE59
_ZN4PLMD8function16FunctionShortcutINS0_8MoreThanEE12createActionEPNS_14ActionShortcutERKSt6vectorIPNS_5ValueESaIS8_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE68
_ZN4PLMD8function16FunctionShortcutINS0_8MoreThanEE16registerKeywordsERNS_8KeywordsE70
_ZN4PLMD8function16FunctionShortcutINS0_8MoreThanEEC1ERKNS_13ActionOptionsE68
_ZN4PLMD8function16FunctionShortcutINS0_9PiecewiseEE12createActionEPNS_14ActionShortcutERKSt6vectorIPNS_5ValueESaIS8_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3
_ZN4PLMD8function16FunctionShortcutINS0_9PiecewiseEE16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD8function16FunctionShortcutINS0_9PiecewiseEEC1ERKNS_13ActionOptionsE3
_ZN4PLMD8function16FunctionShortcutINS_7refdist10DifferenceEE12createActionEPNS_14ActionShortcutERKSt6vectorIPNS_5ValueESaIS9_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE184
_ZN4PLMD8function16FunctionShortcutINS_7refdist10DifferenceEE16registerKeywordsERNS_8KeywordsE186
_ZN4PLMD8function16FunctionShortcutINS_7refdist10DifferenceEEC1ERKNS_13ActionOptionsE184
_ZN4PLMD8function16FunctionShortcutINS_7symfunc17SphericalHarmonicEE12createActionEPNS_14ActionShortcutERKSt6vectorIPNS_5ValueESaIS9_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE41
_ZN4PLMD8function16FunctionShortcutINS_7symfunc17SphericalHarmonicEE16registerKeywordsERNS_8KeywordsE84
_ZN4PLMD8function16FunctionShortcutINS_7symfunc17SphericalHarmonicEEC1ERKNS_13ActionOptionsE41
_ZN4PLMD8function16FunctionShortcutINS_7symfunc19CylindricalHarmonicEE12createActionEPNS_14ActionShortcutERKSt6vectorIPNS_5ValueESaIS9_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1
_ZN4PLMD8function16FunctionShortcutINS_7symfunc19CylindricalHarmonicEE16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD8function16FunctionShortcutINS_7symfunc19CylindricalHarmonicEEC1ERKNS_13ActionOptionsE1
_ZN4PLMD8function16FunctionShortcutINS_7symfunc7FccubicEE12createActionEPNS_14ActionShortcutERKSt6vectorIPNS_5ValueESaIS9_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE5
_ZN4PLMD8function16FunctionShortcutINS_7symfunc7FccubicEE16registerKeywordsERNS_8KeywordsE7
_ZN4PLMD8function16FunctionShortcutINS_7symfunc7FccubicEEC1ERKNS_13ActionOptionsE5
_ZN4PLMD8function16FunctionShortcutIiE12createActionEPNS_14ActionShortcutERKSt6vectorIPNS_5ValueESaIS7_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/FunctionShortcut.h.gcov.html b/coverage/function/FunctionShortcut.h.gcov.html new file mode 100644 index 000000000000..46ad3b6c8a32 --- /dev/null +++ b/coverage/function/FunctionShortcut.h.gcov.html @@ -0,0 +1,168 @@ + + + + + + + + LCOV - plumed test coverage - function/FunctionShortcut.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - FunctionShortcut.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:283384.8 %
Date:2024-04-19 12:12:35Functions:4646100.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_FunctionShortcut_h
+      23             : #define __PLUMED_function_FunctionShortcut_h
+      24             : 
+      25             : #include "core/ActionShortcut.h"
+      26             : #include "core/PlumedMain.h"
+      27             : #include "core/ActionSet.h"
+      28             : #include "core/ActionRegister.h"
+      29             : #include "core/ActionWithArguments.h"
+      30             : #include "core/Value.h"
+      31             : 
+      32             : namespace PLMD {
+      33             : namespace function {
+      34             : 
+      35             : template <class T>
+      36             : class FunctionShortcut : public ActionShortcut {
+      37             : private:
+      38             : /// The function that is being computed
+      39             :   T myfunc;
+      40             : public:
+      41             :   static void registerKeywords(Keywords&);
+      42             :   explicit FunctionShortcut(const ActionOptions&);
+      43             :   static void createAction( ActionShortcut* action, const std::vector<Value*>& vals, const std::string& allargs );
+      44             : };
+      45             : 
+      46             : template <class T>
+      47        4709 : void FunctionShortcut<T>::registerKeywords(Keywords& keys ) {
+      48        4709 :   ActionShortcut::registerKeywords( keys );
+      49        9418 :   keys.add("numbered","ARG","the input to this function");
+      50        9418 :   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");
+      51       20474 :   keys.addActionNameSuffix("_SCALAR"); keys.addActionNameSuffix("_VECTOR"); keys.addActionNameSuffix("_MATRIX"); keys.addActionNameSuffix("_GRID");
+      52        4473 :   T tfunc; tfunc.registerKeywords( keys );
+      53        4709 : }
+      54             : 
+      55             : template <class T>
+      56        4580 : FunctionShortcut<T>::FunctionShortcut(const ActionOptions&ao):
+      57             :   Action(ao),
+      58        4580 :   ActionShortcut(ao)
+      59             : {
+      60        9160 :   std::vector<std::string> args; parseVector("ARG",args);
+      61       12163 :   std::string allargs=args[0]; for(unsigned i=1; i<args.size(); ++i) allargs += "," + args[i];
+      62        4580 :   std::vector<Value*> vals; ActionWithArguments::interpretArgumentList( args, plumed.getActionSet(), this, vals );
+      63        4585 :   if( vals.size()==0 ) error("found no input arguments to function");
+      64        4580 :   createAction( this, vals, allargs );
+      65        4593 : }
+      66             : 
+      67             : template <class T>
+      68        4582 : void FunctionShortcut<T>::createAction( ActionShortcut* action, const std::vector<Value*>& vals, const std::string& allargs ) {
+      69        4582 :   unsigned maxrank=vals[0]->getRank(); bool isgrid=false;
+      70       12232 :   for(unsigned i=0; i<vals.size(); ++i) {
+      71        7650 :     if( vals[i]->getRank()>0 && vals[i]->hasDerivatives() ) isgrid=true;
+      72             :     if( vals[i]->getRank()>maxrank ) maxrank=vals[i]->getRank();
+      73             :   }
+      74        4582 :   if( isgrid ) {
+      75        1296 :     if( actionRegister().check( action->getName() + "_GRID") ) action->readInputLine( action->getShortcutLabel() + ": " + action->getName() + "_GRID ARG=" + allargs + " " + action->convertInputLineToString() );
+      76           0 :     else plumed_merror("there is no action registered that allows you to do " + action->getName() + " with functions on a grid");
+      77        4150 :   } else if( maxrank==0 ) {
+      78        4303 :     if( actionRegister().check( action->getName() + "_SCALAR") ) action->readInputLine( action->getShortcutLabel() + ": " + action->getName() + "_SCALAR ARG=" + allargs + " " + action->convertInputLineToString() );
+      79           0 :     else plumed_merror("there is no action registered that allows you to do " + action->getName() + " with scalars");
+      80        2724 :   } else if( maxrank==1 ) {
+      81        6699 :     if( actionRegister().check( action->getName() + "_VECTOR") ) action->readInputLine( action->getShortcutLabel() + ": " + action->getName() + "_VECTOR ARG=" + allargs + " " + action->convertInputLineToString() );
+      82           0 :     else plumed_merror("there is no action registered that allows you to do " + action->getName() + " with vectors");
+      83         491 :   } else if( maxrank==2  ) {
+      84        1473 :     if( actionRegister().check( action->getName() + "_MATRIX") ) action->readInputLine( action->getShortcutLabel() + ": " + action->getName() + "_MATRIX ARG=" + allargs + " " + action->convertInputLineToString() );
+      85           0 :     else plumed_merror("there is no action registered that allows you to do " + action->getName() + " with matrices");
+      86           0 :   } else plumed_error();
+      87        4577 : }
+      88             : 
+      89             : }
+      90             : }
+      91             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/FunctionTemplateBase.h.func-sort-c.html b/coverage/function/FunctionTemplateBase.h.func-sort-c.html new file mode 100644 index 000000000000..bd914d0488b1 --- /dev/null +++ b/coverage/function/FunctionTemplateBase.h.func-sort-c.html @@ -0,0 +1,145 @@ + + + + + + + + LCOV - plumed test coverage - function/FunctionTemplateBase.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - FunctionTemplateBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:374582.2 %
Date:2024-04-19 12:12:35Functions:111861.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function20FunctionTemplateBase12setPrefactorEPNS_19ActionWithArgumentsEd0
_ZN4PLMD8function20FunctionTemplateBase22derivativesImplementedEv0
_ZNK4PLMD8function20FunctionTemplateBase11doWithTasksEv0
_ZNK4PLMD8function20FunctionTemplateBase11getArgStartEv0
_ZNK4PLMD8function20FunctionTemplateBase21getComponentsPerLabelB5cxx11Ev0
_ZNK4PLMD8function20FunctionTemplateBase30getDerivativeZeroIfValueIsZeroEv0
_ZNK4PLMD8function20FunctionTemplateBase8zeroRankEv0
_ZN4PLMD8function20FunctionTemplateBase11parseVectorIiEEvPNS_6ActionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIT_SaISE_EE5
_ZN4PLMD8function20FunctionTemplateBase5parseIdEEvPNS_6ActionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_5
_ZNK4PLMD8function20FunctionTemplateBase12getGraphInfoERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE23
_ZN4PLMD8function20FunctionTemplateBase5parseIiEEvPNS_6ActionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_43
_ZN4PLMD8function20FunctionTemplateBase11parseVectorIdEEvPNS_6ActionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIT_SaISE_EE906
_ZN4PLMD8function20FunctionTemplateBase19getArgumentsToCheckERKSt6vectorIPNS_5ValueESaIS4_EE1228
_ZN4PLMD8function20FunctionTemplateBase21allComponentsRequiredERKSt6vectorIPNS_5ValueESaIS4_EERKS2_IPNS_16ActionWithVectorESaISA_EE2194
_ZN4PLMD8function20FunctionTemplateBase5parseINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvPNS_6ActionERKS8_RT_3069
_ZN4PLMD8function20FunctionTemplateBase24setPeriodicityForOutputsEPNS_15ActionWithValueE4421
_ZN4PLMD8function20FunctionTemplateBase11parseVectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvPNS_6ActionERKS8_RSt6vectorIT_SaISE_EE7163
_ZN4PLMD8function20FunctionTemplateBase5setupEPNS_15ActionWithValueE10605
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/FunctionTemplateBase.h.func.html b/coverage/function/FunctionTemplateBase.h.func.html new file mode 100644 index 000000000000..46e4c73300a2 --- /dev/null +++ b/coverage/function/FunctionTemplateBase.h.func.html @@ -0,0 +1,145 @@ + + + + + + + + LCOV - plumed test coverage - function/FunctionTemplateBase.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - FunctionTemplateBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:374582.2 %
Date:2024-04-19 12:12:35Functions:111861.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function20FunctionTemplateBase11parseVectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvPNS_6ActionERKS8_RSt6vectorIT_SaISE_EE7163
_ZN4PLMD8function20FunctionTemplateBase11parseVectorIdEEvPNS_6ActionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIT_SaISE_EE906
_ZN4PLMD8function20FunctionTemplateBase11parseVectorIiEEvPNS_6ActionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIT_SaISE_EE5
_ZN4PLMD8function20FunctionTemplateBase12setPrefactorEPNS_19ActionWithArgumentsEd0
_ZN4PLMD8function20FunctionTemplateBase19getArgumentsToCheckERKSt6vectorIPNS_5ValueESaIS4_EE1228
_ZN4PLMD8function20FunctionTemplateBase21allComponentsRequiredERKSt6vectorIPNS_5ValueESaIS4_EERKS2_IPNS_16ActionWithVectorESaISA_EE2194
_ZN4PLMD8function20FunctionTemplateBase22derivativesImplementedEv0
_ZN4PLMD8function20FunctionTemplateBase24setPeriodicityForOutputsEPNS_15ActionWithValueE4421
_ZN4PLMD8function20FunctionTemplateBase5parseINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvPNS_6ActionERKS8_RT_3069
_ZN4PLMD8function20FunctionTemplateBase5parseIdEEvPNS_6ActionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_5
_ZN4PLMD8function20FunctionTemplateBase5parseIiEEvPNS_6ActionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_43
_ZN4PLMD8function20FunctionTemplateBase5setupEPNS_15ActionWithValueE10605
_ZNK4PLMD8function20FunctionTemplateBase11doWithTasksEv0
_ZNK4PLMD8function20FunctionTemplateBase11getArgStartEv0
_ZNK4PLMD8function20FunctionTemplateBase12getGraphInfoERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE23
_ZNK4PLMD8function20FunctionTemplateBase21getComponentsPerLabelB5cxx11Ev0
_ZNK4PLMD8function20FunctionTemplateBase30getDerivativeZeroIfValueIsZeroEv0
_ZNK4PLMD8function20FunctionTemplateBase8zeroRankEv0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/FunctionTemplateBase.h.gcov.html b/coverage/function/FunctionTemplateBase.h.gcov.html new file mode 100644 index 000000000000..a5a4d0df5e33 --- /dev/null +++ b/coverage/function/FunctionTemplateBase.h.gcov.html @@ -0,0 +1,212 @@ + + + + + + + + LCOV - plumed test coverage - function/FunctionTemplateBase.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - FunctionTemplateBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:374582.2 %
Date:2024-04-19 12:12:35Functions:111861.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_function_FunctionTemplateBase_h
+      23             : #define __PLUMED_function_FunctionTemplateBase_h
+      24             : 
+      25             : #include "core/ActionWithValue.h"
+      26             : #include "core/ActionWithArguments.h"
+      27             : #include "core/ActionWithVector.h"
+      28             : #include "tools/Matrix.h"
+      29             : 
+      30             : namespace PLMD {
+      31             : namespace function {
+      32             : 
+      33        6814 : class FunctionTemplateBase {
+      34             : protected:
+      35             : /// Are we using derivatives
+      36             :   bool noderiv = false;
+      37             : /// Parse a keyword from the input as a value
+      38             :   template<class T>
+      39             :   void parse( Action* action, const std::string&key, T&t );
+      40             : /// Parse a keyword from the input as a vector
+      41             :   template<class T>
+      42             :   void parseVector( Action* action, const std::string&key,std::vector<T>&t);
+      43             : /// Parse a keyword from the input as a flag
+      44             :   void parseFlag( Action* action, const std::string&key, bool&t );
+      45             : public:
+      46             : /// Override this function if you have not implemented the derivatives
+      47           0 :   virtual bool derivativesImplemented() { return true; }
+      48             : ////
+      49             :   virtual std::vector<std::string> getComponentsPerLabel() const ;
+      50           0 :   virtual bool getDerivativeZeroIfValueIsZero() const { return false; }
+      51             :   virtual std::string getGraphInfo( const std::string& lab ) const ;
+      52             :   virtual void registerKeywords( Keywords& keys ) = 0;
+      53             :   virtual void read( ActionWithArguments* action ) = 0;
+      54           0 :   virtual bool doWithTasks() const { return true; }
+      55             :   virtual std::vector<Value*> getArgumentsToCheck( const std::vector<Value*>& args );
+      56             :   bool allComponentsRequired( const std::vector<Value*>& args, const std::vector<ActionWithVector*>& actions );
+      57           0 :   virtual bool zeroRank() const { return false; }
+      58             :   virtual void setPeriodicityForOutputs( ActionWithValue* action );
+      59           0 :   virtual void setPrefactor( ActionWithArguments* action, const double pref ) {}
+      60           0 :   virtual unsigned getArgStart() const { return 0; }
+      61             :   virtual void setup( ActionWithValue* action );
+      62             :   virtual void calc( const ActionWithArguments* action, const std::vector<double>& args, std::vector<double>& vals, Matrix<double>& derivatives ) const = 0;
+      63             : };
+      64             : 
+      65             : template<class T>
+      66        3117 : void FunctionTemplateBase::parse( Action* action, const std::string&key, T&t ) {
+      67        3117 :   action->parse(key,t);
+      68        3117 : }
+      69             : 
+      70             : template<class T>
+      71        8074 : void FunctionTemplateBase::parseVector( Action* action, const std::string&key,std::vector<T>&t) {
+      72        8074 :   action->parseVector(key,t);
+      73        8071 : }
+      74             : 
+      75             : inline
+      76             : void FunctionTemplateBase::parseFlag( Action* action, const std::string&key, bool&t ) {
+      77         387 :   action->parseFlag(key,t);
+      78         387 : }
+      79             : 
+      80             : inline
+      81           0 : std::vector<std::string> FunctionTemplateBase::getComponentsPerLabel() const {
+      82           0 :   std::vector<std::string> comps; return comps;
+      83             : }
+      84             : 
+      85             : inline
+      86       10605 : void FunctionTemplateBase::setup( ActionWithValue* action ) {
+      87       10605 :   noderiv=action->doNotCalculateDerivatives();
+      88             :   // Check for grids in input
+      89       10605 :   ActionWithArguments* aarg=dynamic_cast<ActionWithArguments*>( action ); plumed_assert( aarg );
+      90       32879 :   for(unsigned i=0; i<aarg->getNumberOfArguments(); ++i) {
+      91       23488 :     if( aarg->getPntrToArgument(i)->getRank()>0 && aarg->getPntrToArgument(i)->hasDerivatives() ) { noderiv=false; break; }
+      92             :   }
+      93       10605 : }
+      94             : 
+      95             : inline
+      96        4421 : void FunctionTemplateBase::setPeriodicityForOutputs( ActionWithValue* action ) {
+      97        4421 :   plumed_massert( action->getNumberOfComponents()==1,"you must defined a setPeriodicityForOutputs function in your function class");
+      98        8842 :   if( action->keywords.exists("PERIODIC") ) {
+      99        8362 :     std::vector<std::string> period; parseVector(action,"PERIODIC",period);
+     100        4181 :     if( period.size()==1 ) {
+     101        4177 :       if( period[0]!="NO") action->error("input to PERIODIC keyword does not make sense");
+     102        4177 :       action->setNotPeriodic(); return;
+     103           4 :     } else if( period.size()!=2 ) action->error("input to PERIODIC keyword does not make sense");
+     104           4 :     action->setPeriodic( period[0], period[1] );
+     105        4421 :   } else action->setNotPeriodic();
+     106             : }
+     107             : 
+     108             : inline
+     109        1228 : std::vector<Value*> FunctionTemplateBase::getArgumentsToCheck( const std::vector<Value*>& args ) {
+     110        1228 :   return args;
+     111             : }
+     112             : 
+     113             : inline
+     114        2194 : bool FunctionTemplateBase::allComponentsRequired( const std::vector<Value*>& args, const std::vector<ActionWithVector*>& actions ) {
+     115        2194 :   std::vector<Value*> checkArgs = getArgumentsToCheck( args );
+     116        3935 :   for(unsigned i=0; i<checkArgs.size(); ++i ) {
+     117        2224 :     ActionWithVector* av = dynamic_cast<ActionWithVector*>( checkArgs[i]->getPntrToAction() );
+     118        2224 :     if( !av ) return false;
+     119             :     bool found=false;
+     120       18070 :     for(unsigned j=0; j<actions.size(); ++j) {
+     121       17587 :       if( actions[j]==av ) { found=true; break; }
+     122             :     }
+     123        2224 :     if( !found ) return true;
+     124             :   }
+     125             :   return false;
+     126             : }
+     127             : 
+     128             : inline
+     129          23 : std::string FunctionTemplateBase::getGraphInfo( const std::string& name ) const {
+     130          23 :   std::size_t und = name.find_last_of("_"); return name.substr(0,und);
+     131             : }
+     132             : 
+     133             : }
+     134             : }
+     135             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Highest.cpp.func-sort-c.html b/coverage/function/Highest.cpp.func-sort-c.html new file mode 100644 index 000000000000..f90ed1e7fdf2 --- /dev/null +++ b/coverage/function/Highest.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - function/Highest.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - Highest.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:171894.4 %
Date:2024-04-19 12:12:35Functions:2540.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function7Highest16registerKeywordsERNS_8KeywordsE0
_ZNK4PLMD8function7Highest11doWithTasksEv0
_ZNK4PLMD8function7Highest8zeroRankEv0
_ZN4PLMD8function7Highest4readEPNS_19ActionWithArgumentsE46
_ZNK4PLMD8function7Highest4calcEPKNS_19ActionWithArgumentsERKSt6vectorIdSaIdEERS7_RNS_6MatrixIdEE23799
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Highest.cpp.func.html b/coverage/function/Highest.cpp.func.html new file mode 100644 index 000000000000..75502ec71cd7 --- /dev/null +++ b/coverage/function/Highest.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - function/Highest.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - Highest.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:171894.4 %
Date:2024-04-19 12:12:35Functions:2540.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function7Highest16registerKeywordsERNS_8KeywordsE0
_ZN4PLMD8function7Highest4readEPNS_19ActionWithArgumentsE46
_ZNK4PLMD8function7Highest11doWithTasksEv0
_ZNK4PLMD8function7Highest4calcEPKNS_19ActionWithArgumentsERKSt6vectorIdSaIdEERS7_RNS_6MatrixIdEE23799
_ZNK4PLMD8function7Highest8zeroRankEv0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Highest.cpp.gcov.html b/coverage/function/Highest.cpp.gcov.html new file mode 100644 index 000000000000..61df596088c2 --- /dev/null +++ b/coverage/function/Highest.cpp.gcov.html @@ -0,0 +1,205 @@ + + + + + + + + LCOV - plumed test coverage - function/Highest.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - Highest.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:171894.4 %
Date:2024-04-19 12:12:35Functions:2540.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionRegister.h"
+      23             : #include "FunctionShortcut.h"
+      24             : #include "FunctionOfScalar.h"
+      25             : #include "FunctionOfVector.h"
+      26             : #include "FunctionTemplateBase.h"
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace function {
+      30             : 
+      31             : //+PLUMEDOC FUNCTION HIGHEST
+      32             : /*
+      33             : This function can be used to find the highest colvar by magnitude in a set.
+      34             : 
+      35             : \par Examples
+      36             : 
+      37             : */
+      38             : //+ENDPLUMEDOC
+      39             : 
+      40             : //+PLUMEDOC COLVAR HIGHEST_SCALAR
+      41             : /*
+      42             : Calculate the highest of a set of sclalar arguments
+      43             : 
+      44             : \par Examples
+      45             : 
+      46             : */
+      47             : //+ENDPLUMEDOC
+      48             : 
+      49             : //+PLUMEDOC COLVAR HIGHEST_VECTOR
+      50             : /*
+      51             : Calculate the largest element in a vector of inputs
+      52             : 
+      53             : \par Examples
+      54             : 
+      55             : */
+      56             : //+ENDPLUMEDOC
+      57             : 
+      58             : //+PLUMEDOC FUNCTION LOWEST
+      59             : /*
+      60             : This function can be used to find the lowest colvar by magnitude in a set.
+      61             : 
+      62             : \par Examples
+      63             : 
+      64             : */
+      65             : //+ENDPLUMEDOC
+      66             : 
+      67             : //+PLUMEDOC COLVAR LOWEST_SCALAR
+      68             : /*
+      69             : Calculate the lowest of a set of sclalar arguments
+      70             : 
+      71             : \par Examples
+      72             : 
+      73             : */
+      74             : //+ENDPLUMEDOC
+      75             : 
+      76             : //+PLUMEDOC COLVAR LOWEST_VECTOR
+      77             : /*
+      78             : Calculate the lowest element in a vector of inputs
+      79             : 
+      80             : \par Examples
+      81             : 
+      82             : */
+      83             : //+ENDPLUMEDOC
+      84             : 
+      85          92 : class Highest : public FunctionTemplateBase {
+      86             : private:
+      87             :   bool min, scalar_out;
+      88             : public:
+      89           0 :   void registerKeywords( Keywords& keys ) override {}
+      90             :   void read( ActionWithArguments* action ) override;
+      91          56 :   bool zeroRank() const override { return scalar_out; }
+      92        5334 :   bool doWithTasks() const override { return !scalar_out; }
+      93             :   void calc( const ActionWithArguments* action, const std::vector<double>& args, std::vector<double>& vals, Matrix<double>& derivatives ) const override;
+      94             : };
+      95             : 
+      96             : typedef FunctionShortcut<Highest> HighestShortcut;
+      97             : PLUMED_REGISTER_ACTION(HighestShortcut,"HIGHEST")
+      98             : PLUMED_REGISTER_ACTION(HighestShortcut,"LOWEST")
+      99             : typedef FunctionOfScalar<Highest> ScalarHighest;
+     100             : PLUMED_REGISTER_ACTION(ScalarHighest,"HIGHEST_SCALAR")
+     101             : PLUMED_REGISTER_ACTION(ScalarHighest,"LOWEST_SCALAR")
+     102             : typedef FunctionOfVector<Highest> VectorHighest;
+     103             : PLUMED_REGISTER_ACTION(VectorHighest,"HIGHEST_VECTOR")
+     104             : PLUMED_REGISTER_ACTION(VectorHighest,"LOWEST_VECTOR")
+     105             : 
+     106          46 : void Highest::read( ActionWithArguments* action ) {
+     107          46 :   min=action->getName().find("LOWEST")!=std::string::npos; if( !min ) plumed_assert( action->getName().find("HIGHEST")!=std::string::npos );
+     108         110 :   for(unsigned i=0; i<action->getNumberOfArguments(); ++i) {
+     109          64 :     if( action->getPntrToArgument(i)->isPeriodic() ) action->error("Cannot sort periodic values (check argument "+ action->getPntrToArgument(i)->getName() +")");
+     110             :   }
+     111          46 :   scalar_out = action->getNumberOfArguments()==1;
+     112          46 :   if( scalar_out && action->getPntrToArgument(0)->getRank()==0 ) action->error("sorting a single scalar is trivial");
+     113          46 : }
+     114             : 
+     115       23799 : void Highest::calc( const ActionWithArguments* action, const std::vector<double>& args, std::vector<double>& vals, Matrix<double>& derivatives ) const {
+     116       23799 :   if( min ) {
+     117       23665 :     vals[0] = *std::min_element(args.begin(), args.end());
+     118       23665 :     derivatives(0,std::min_element(args.begin(), args.end()) - args.begin()) = 1;
+     119             :   } else {
+     120         134 :     vals[0] = *std::max_element(args.begin(), args.end());
+     121         134 :     derivatives(0,std::max_element(args.begin(), args.end()) - args.begin()) = 1;
+     122             :   }
+     123       23799 : }
+     124             : 
+     125             : }
+     126             : }
+     127             : 
+     128             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/LessThan.cpp.func-sort-c.html b/coverage/function/LessThan.cpp.func-sort-c.html new file mode 100644 index 000000000000..f83d2f65f8ff --- /dev/null +++ b/coverage/function/LessThan.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - function/LessThan.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - LessThan.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:242885.7 %
Date:2024-04-19 12:12:35Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function8LessThan4readEPNS_19ActionWithArgumentsE59
_ZN4PLMD8function8LessThan16registerKeywordsERNS_8KeywordsE124
_ZNK4PLMD8function8LessThan4calcEPKNS_19ActionWithArgumentsERKSt6vectorIdSaIdEERS7_RNS_6MatrixIdEE169793
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/LessThan.cpp.func.html b/coverage/function/LessThan.cpp.func.html new file mode 100644 index 000000000000..e9c431c2aba2 --- /dev/null +++ b/coverage/function/LessThan.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - function/LessThan.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - LessThan.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:242885.7 %
Date:2024-04-19 12:12:35Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function8LessThan16registerKeywordsERNS_8KeywordsE124
_ZN4PLMD8function8LessThan4readEPNS_19ActionWithArgumentsE59
_ZNK4PLMD8function8LessThan4calcEPKNS_19ActionWithArgumentsERKSt6vectorIdSaIdEERS7_RNS_6MatrixIdEE169793
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/LessThan.cpp.gcov.html b/coverage/function/LessThan.cpp.gcov.html new file mode 100644 index 000000000000..9106095c118f --- /dev/null +++ b/coverage/function/LessThan.cpp.gcov.html @@ -0,0 +1,174 @@ + + + + + + + + LCOV - plumed test coverage - function/LessThan.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - LessThan.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:242885.7 %
Date:2024-04-19 12:12:35Functions:33100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2017 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received 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 "FunctionShortcut.h"
+      24             : #include "FunctionOfVector.h"
+      25             : #include "core/ActionRegister.h"
+      26             : 
+      27             : #include <cmath>
+      28             : 
+      29             : namespace PLMD {
+      30             : namespace function {
+      31             : 
+      32             : //+PLUMEDOC FUNCTION LESS_THAN
+      33             : /*
+      34             : Use a switching function to determine how many of the input variables are less than a certain cutoff.
+      35             : 
+      36             : \par Examples
+      37             : 
+      38             : */
+      39             : //+ENDPLUMEDOC
+      40             : 
+      41             : //+PLUMEDOC FUNCTION LESS_THAN_VECTOR
+      42             : /*
+      43             : Use a switching function to determine how many components of the vector are less than a certain cutoff.
+      44             : 
+      45             : \par Examples
+      46             : 
+      47             : */
+      48             : //+ENDPLUMEDOC
+      49             : 
+      50             : typedef FunctionShortcut<LessThan> LessThanShortcut;
+      51             : PLUMED_REGISTER_ACTION(LessThanShortcut,"LESS_THAN")
+      52             : typedef FunctionOfVector<LessThan> VectorLessThan;
+      53             : PLUMED_REGISTER_ACTION(VectorLessThan,"LESS_THAN_VECTOR")
+      54             : 
+      55         124 : void LessThan::registerKeywords(Keywords& keys) {
+      56         248 :   keys.add("compulsory","NN","6","The n parameter of the switching function ");
+      57         248 :   keys.add("compulsory","MM","0","The m parameter of the switching function; 0 implies 2*NN");
+      58         248 :   keys.add("compulsory","D_0","0.0","The d_0 parameter of the switching function");
+      59         248 :   keys.add("compulsory","R_0","The r_0 parameter of the switching function");
+      60         248 :   keys.add("optional","SWITCH","This keyword is used if you want to employ an alternative to the continuous swiching function defined above. "
+      61             :            "The following provides information on the \\ref switchingfunction that are available. "
+      62             :            "When this keyword is present you no longer need the NN, MM, D_0 and R_0 keywords.");
+      63         248 :   keys.addFlag("SQUARED",false,"is the input quantity the square of the value that you would like to apply the switching function to");
+      64         124 : }
+      65             : 
+      66          59 : void LessThan::read( ActionWithArguments* action ) {
+      67          59 :   if( action->getNumberOfArguments()!=1 ) action->error("should only be one argument to less_than actions");
+      68          59 :   if( action->getPntrToArgument(0)->isPeriodic() ) action->error("cannot use this function on periodic functions");
+      69             : 
+      70             : 
+      71             :   std::string sw,errors;
+      72         118 :   action->parse("SWITCH",sw);
+      73          59 :   if(sw.length()>0) {
+      74          59 :     switchingFunction.set(sw,errors);
+      75          59 :     if( errors.length()!=0 ) action->error("problem reading SWITCH keyword : " + errors );
+      76             :   } else {
+      77           0 :     int nn=6; int mm=0; double d0=0.0; double r0=0.0; action->parse("R_0",r0);
+      78           0 :     if(r0<=0.0) action->error("R_0 should be explicitly specified and positive");
+      79           0 :     action->parse("D_0",d0); action->parse("NN",nn); action->parse("MM",mm);
+      80           0 :     switchingFunction.set(nn,mm,r0,d0);
+      81             :   }
+      82          59 :   action->log<<"  using switching function with cutoff "<<switchingFunction.description()<<"\n";
+      83          59 :   action->parseFlag("SQUARED",squared);
+      84          59 :   if( squared ) action->log<<"  input quantity is square of quantity that switching function acts upon\n";
+      85          59 : }
+      86             : 
+      87      169793 : void LessThan::calc( const ActionWithArguments* action, const std::vector<double>& args, std::vector<double>& vals, Matrix<double>& derivatives ) const {
+      88             :   plumed_dbg_assert( args.size()==1 );
+      89      169793 :   if( squared ) vals[0] = switchingFunction.calculateSqr( args[0], derivatives(0,0) );
+      90      169793 :   else vals[0] = switchingFunction.calculate( args[0], derivatives(0,0) );
+      91      169793 :   derivatives(0,0) = args[0]*derivatives(0,0);
+      92      169793 : }
+      93             : 
+      94             : }
+      95             : }
+      96             : 
+      97             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/LessThan.h.func-sort-c.html b/coverage/function/LessThan.h.func-sort-c.html new file mode 100644 index 000000000000..ee3def165ab4 --- /dev/null +++ b/coverage/function/LessThan.h.func-sort-c.html @@ -0,0 +1,77 @@ + + + + + + + + LCOV - plumed test coverage - function/LessThan.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - LessThan.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1250.0 %
Date:2024-04-19 12:12:35Functions:010.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD8function8LessThan30getDerivativeZeroIfValueIsZeroEv0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/LessThan.h.func.html b/coverage/function/LessThan.h.func.html new file mode 100644 index 000000000000..53fc84a833a0 --- /dev/null +++ b/coverage/function/LessThan.h.func.html @@ -0,0 +1,77 @@ + + + + + + + + LCOV - plumed test coverage - function/LessThan.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - LessThan.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1250.0 %
Date:2024-04-19 12:12:35Functions:010.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD8function8LessThan30getDerivativeZeroIfValueIsZeroEv0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/LessThan.h.gcov.html b/coverage/function/LessThan.h.gcov.html new file mode 100644 index 000000000000..3b95af2848ff --- /dev/null +++ b/coverage/function/LessThan.h.gcov.html @@ -0,0 +1,120 @@ + + + + + + + + LCOV - plumed test coverage - function/LessThan.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - LessThan.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1250.0 %
Date:2024-04-19 12:12:35Functions:010.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2020 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a 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_LessThan_h
+      23             : #define __PLUMED_function_LessThan_h
+      24             : 
+      25             : #include "FunctionTemplateBase.h"
+      26             : #include "tools/SwitchingFunction.h"
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace function {
+      30             : 
+      31         300 : class LessThan : public FunctionTemplateBase {
+      32             :   bool squared;
+      33             :   SwitchingFunction switchingFunction;
+      34             : public:
+      35             :   void registerKeywords( Keywords& keys ) override;
+      36             :   void read( ActionWithArguments* action ) override;
+      37           0 :   bool getDerivativeZeroIfValueIsZero() const override { return true; }
+      38             :   void calc( const ActionWithArguments* action, const std::vector<double>& args, std::vector<double>& vals, Matrix<double>& derivatives ) const override;
+      39             : };
+      40             : 
+      41             : }
+      42             : }
+      43             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/LocalEnsemble.cpp.func-sort-c.html b/coverage/function/LocalEnsemble.cpp.func-sort-c.html new file mode 100644 index 000000000000..5511085238c6 --- /dev/null +++ b/coverage/function/LocalEnsemble.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - function/LocalEnsemble.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - LocalEnsemble.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3131100.0 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function13LocalEnsembleC2ERKNS_13ActionOptionsE0
_ZN4PLMD8function13LocalEnsembleC1ERKNS_13ActionOptionsE2
_ZN4PLMD8function13LocalEnsemble16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD8function13LocalEnsemble9calculateEv40
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/LocalEnsemble.cpp.func.html b/coverage/function/LocalEnsemble.cpp.func.html new file mode 100644 index 000000000000..9a83baf0382e --- /dev/null +++ b/coverage/function/LocalEnsemble.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - function/LocalEnsemble.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - LocalEnsemble.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3131100.0 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function13LocalEnsemble16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD8function13LocalEnsemble9calculateEv40
_ZN4PLMD8function13LocalEnsembleC1ERKNS_13ActionOptionsE2
_ZN4PLMD8function13LocalEnsembleC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/LocalEnsemble.cpp.gcov.html b/coverage/function/LocalEnsemble.cpp.gcov.html new file mode 100644 index 000000000000..8ffc05222e85 --- /dev/null +++ b/coverage/function/LocalEnsemble.cpp.gcov.html @@ -0,0 +1,228 @@ + + + + + + + + LCOV - plumed test coverage - function/LocalEnsemble.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - LocalEnsemble.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3131100.0 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "Function.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "tools/OpenMP.h"
+      25             : 
+      26             : namespace PLMD {
+      27             : namespace function {
+      28             : 
+      29             : //+PLUMEDOC FUNCTION LOCALENSEMBLE
+      30             : /*
+      31             : Calculates the average over multiple arguments.
+      32             : 
+      33             : If more than one collective variable is given for each argument then they
+      34             : are averaged separately. The average is stored in a component labelled <em>label</em>.cvlabel.
+      35             : 
+      36             : \par Examples
+      37             : 
+      38             : The following input tells plumed to calculate the chemical shifts for four
+      39             : different proteins in the same simulation box then average them, calculated
+      40             : the sum of the squared deviation with respect to the experimental values and
+      41             : applies a linear restraint.
+      42             : \plumedfile
+      43             : MOLINFO STRUCTURE=data/template.pdb
+      44             : 
+      45             : chaina: GROUP ATOMS=1-1640
+      46             : chainb: GROUP ATOMS=1641-3280
+      47             : chainc: GROUP ATOMS=3281-4920
+      48             : chaind: GROUP ATOMS=4921-6560
+      49             : 
+      50             : WHOLEMOLECULES ENTITY0=chaina ENTITY1=chainb ENTITY2=chainc ENTITY3=chaind
+      51             : 
+      52             : csa: CS2BACKBONE ATOMS=chaina NRES=100 DATA=data/ TEMPLATE=chaina.pdb NOPBC
+      53             : csb: CS2BACKBONE ATOMS=chainb NRES=100 DATA=data/ TEMPLATE=chainb.pdb NOPBC
+      54             : csc: CS2BACKBONE ATOMS=chainc NRES=100 DATA=data/ TEMPLATE=chainc.pdb NOPBC
+      55             : csd: CS2BACKBONE ATOMS=chaind NRES=100 DATA=data/ TEMPLATE=chaind.pdb NOPBC
+      56             : 
+      57             : ensca: LOCALENSEMBLE NUM=4 ARG1=(csa\.ca_.*) ARG2=(csb\.ca_.*) ARG3=(csc\.ca_.*) ARG4=(csd\.ca_.*)
+      58             : enscb: LOCALENSEMBLE NUM=4 ARG1=(csa\.cb_.*) ARG2=(csb\.cb_.*) ARG3=(csc\.cb_.*) ARG4=(csd\.cb_.*)
+      59             : ensco: LOCALENSEMBLE NUM=4 ARG1=(csa\.co_.*) ARG2=(csb\.co_.*) ARG3=(csc\.co_.*) ARG4=(csd\.co_.*)
+      60             : enshn: LOCALENSEMBLE NUM=4 ARG1=(csa\.hn_.*) ARG2=(csb\.hn_.*) ARG3=(csc\.hn_.*) ARG4=(csd\.hn_.*)
+      61             : ensnh: LOCALENSEMBLE NUM=4 ARG1=(csa\.nh_.*) ARG2=(csb\.nh_.*) ARG3=(csc\.nh_.*) ARG4=(csd\.nh_.*)
+      62             : 
+      63             : stca: STATS ARG=(ensca\.csa\.ca_.*) PARARG=(csa\.expca_.*) SQDEVSUM
+      64             : stcb: STATS ARG=(enscb\.csa\.cb_.*) PARARG=(csa\.expcb_.*) SQDEVSUM
+      65             : stco: STATS ARG=(ensco\.csa\.co_.*) PARARG=(csa\.expco_.*) SQDEVSUM
+      66             : sthn: STATS ARG=(enshn\.csa\.hn_.*) PARARG=(csa\.exphn_.*) SQDEVSUM
+      67             : stnh: STATS ARG=(ensnh\.csa\.nh_.*) PARARG=(csa\.expnh_.*) SQDEVSUM
+      68             : 
+      69             : res: RESTRAINT ARG=stca.*,stcb.*,stco.*,sthn.*,stnh.* AT=0.,0.,0.,0.,0. KAPPA=0.,0.,0.,0.,0 SLOPE=16.,16.,12.,24.,0.5
+      70             : \endplumedfile
+      71             : 
+      72             : */
+      73             : //+ENDPLUMEDOC
+      74             : 
+      75             : 
+      76             : class LocalEnsemble :
+      77             :   public Function
+      78             : {
+      79             :   unsigned ens_dim;
+      80             :   unsigned narg;
+      81             : public:
+      82             :   explicit LocalEnsemble(const ActionOptions&);
+      83             :   void     calculate() override;
+      84             :   static void registerKeywords(Keywords& keys);
+      85             : };
+      86             : 
+      87             : 
+      88             : PLUMED_REGISTER_ACTION(LocalEnsemble,"LOCALENSEMBLE")
+      89             : 
+      90           4 : void LocalEnsemble::registerKeywords(Keywords& keys) {
+      91           4 :   Function::registerKeywords(keys);
+      92           4 :   keys.use("ARG");
+      93           8 :   keys.add("compulsory","NUM","the number of local replicas");
+      94           4 :   useCustomisableComponents(keys);
+      95           4 : }
+      96             : 
+      97           2 : LocalEnsemble::LocalEnsemble(const ActionOptions&ao):
+      98             :   Action(ao),
+      99             :   Function(ao),
+     100           2 :   ens_dim(0)
+     101             : {
+     102           2 :   parse("NUM",ens_dim);
+     103           2 :   if(ens_dim==0) error("NUM should be greater or equal to 1");
+     104             : 
+     105             :   std::vector<Value*> arg;
+     106             :   int oldsize=-1;
+     107           8 :   for(unsigned i=1; i<=ens_dim; ++i ) {
+     108             :     std::vector<Value*> larg;
+     109          12 :     if(!parseArgumentList("ARG",i,larg)) break;
+     110          18 :     for(unsigned j=0; j<larg.size(); j++) arg.push_back(larg[j]);
+     111           6 :     if(oldsize!=-1&&oldsize!=static_cast<int>(larg.size())) error("In LOCALENSEMBLE you should have the same number of arguments for each ARG keyword");
+     112           6 :     oldsize = larg.size();
+     113           6 :     if(!larg.empty()) {
+     114           6 :       log.printf("  with arguments %u: ", i);
+     115          18 :       for(unsigned j=0; j<larg.size(); j++) log.printf(" %s",larg[j]->getName().c_str());
+     116           6 :       log.printf("\n");
+     117             :     }
+     118             :   }
+     119           2 :   requestArguments(arg);
+     120           2 :   narg = arg.size()/ens_dim;
+     121             : 
+     122             :   // these are the averages
+     123           6 :   for(unsigned i=0; i<narg; i++) {
+     124           4 :     std::string s=getPntrToArgument(i)->getName();
+     125           4 :     addComponentWithDerivatives(s);
+     126           4 :     getPntrToComponent(i)->setNotPeriodic();
+     127             :   }
+     128             : 
+     129           2 :   log.printf("  averaging over %u replicas.\n", ens_dim);
+     130           2 : }
+     131             : 
+     132          40 : void LocalEnsemble::calculate()
+     133             : {
+     134          40 :   const double fact = 1.0/static_cast<double>(ens_dim);
+     135          40 :   #pragma omp parallel for num_threads(OpenMP::getNumThreads())
+     136             :   for(unsigned i=0; i<narg; ++i) {
+     137             :     double mean = 0.;
+     138             :     Value* v=getPntrToComponent(i);
+     139             :     for(unsigned j=0; j<ens_dim; ++j) {
+     140             :       const unsigned index = j*narg+i;
+     141             :       setDerivative(v, index, fact);
+     142             :       mean += fact*getArgument(index);
+     143             :     }
+     144             :     v->set(mean);
+     145             :   }
+     146          40 : }
+     147             : 
+     148             : }
+     149             : }
+     150             : 
+     151             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Moments.cpp.func-sort-c.html b/coverage/function/Moments.cpp.func-sort-c.html new file mode 100644 index 000000000000..0e77ed986d5f --- /dev/null +++ b/coverage/function/Moments.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - function/Moments.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - Moments.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:384879.2 %
Date:2024-04-19 12:12:35Functions:5771.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD8function7Moments11doWithTasksEv0
_ZNK4PLMD8function7Moments8zeroRankEv0
_ZN4PLMD8function7Moments24setPeriodicityForOutputsEPNS_15ActionWithValueE5
_ZN4PLMD8function7Moments4readEPNS_19ActionWithArgumentsE5
_ZNK4PLMD8function7Moments21getComponentsPerLabelB5cxx11Ev6
_ZN4PLMD8function7Moments16registerKeywordsERNS_8KeywordsE22
_ZNK4PLMD8function7Moments4calcEPKNS_19ActionWithArgumentsERKSt6vectorIdSaIdEERS7_RNS_6MatrixIdEE222
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Moments.cpp.func.html b/coverage/function/Moments.cpp.func.html new file mode 100644 index 000000000000..904cbed5df8f --- /dev/null +++ b/coverage/function/Moments.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - function/Moments.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - Moments.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:384879.2 %
Date:2024-04-19 12:12:35Functions:5771.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function7Moments16registerKeywordsERNS_8KeywordsE22
_ZN4PLMD8function7Moments24setPeriodicityForOutputsEPNS_15ActionWithValueE5
_ZN4PLMD8function7Moments4readEPNS_19ActionWithArgumentsE5
_ZNK4PLMD8function7Moments11doWithTasksEv0
_ZNK4PLMD8function7Moments21getComponentsPerLabelB5cxx11Ev6
_ZNK4PLMD8function7Moments4calcEPKNS_19ActionWithArgumentsERKSt6vectorIdSaIdEERS7_RNS_6MatrixIdEE222
_ZNK4PLMD8function7Moments8zeroRankEv0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Moments.cpp.gcov.html b/coverage/function/Moments.cpp.gcov.html new file mode 100644 index 000000000000..380e84e7393c --- /dev/null +++ b/coverage/function/Moments.cpp.gcov.html @@ -0,0 +1,233 @@ + + + + + + + + LCOV - plumed test coverage - function/Moments.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - Moments.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:384879.2 %
Date:2024-04-19 12:12:35Functions:5771.4 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2017 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "FunctionShortcut.h"
+      23             : #include "FunctionOfScalar.h"
+      24             : #include "FunctionOfVector.h"
+      25             : #include "core/ActionRegister.h"
+      26             : #include "FunctionTemplateBase.h"
+      27             : 
+      28             : #include <cmath>
+      29             : 
+      30             : namespace PLMD {
+      31             : namespace function {
+      32             : 
+      33             : //+PLUMEDOC FUNCTION MOMENTS
+      34             : /*
+      35             : Calculate the moments of the distribution of input quantities
+      36             : 
+      37             : \par Examples
+      38             : 
+      39             : */
+      40             : //+ENDPLUMEDOC
+      41             : 
+      42             : //+PLUMEDOC FUNCTION MOMENTS_SCALAR
+      43             : /*
+      44             : Calculate the moments of the distribution of input quantities
+      45             : 
+      46             : \par Examples
+      47             : 
+      48             : */
+      49             : //+ENDPLUMEDOC
+      50             : 
+      51             : //+PLUMEDOC FUNCTION MOMENTS_VECTOR
+      52             : /*
+      53             : Calculate the moments of the distribution of input vectors
+      54             : 
+      55             : \par Examples
+      56             : 
+      57             : */
+      58             : //+ENDPLUMEDOC
+      59             : 
+      60          37 : class Moments : public FunctionTemplateBase {
+      61             :   bool isperiodic, scalar_out;
+      62             :   double min, max, pfactor;
+      63             :   std::vector<int> powers;
+      64             : public:
+      65             :   void registerKeywords(Keywords& keys) override;
+      66             :   void read( ActionWithArguments* action ) override;
+      67           7 :   bool zeroRank() const override { return scalar_out; }
+      68         221 :   bool doWithTasks() const override { return !scalar_out; }
+      69             :   std::vector<std::string> getComponentsPerLabel() const override ;
+      70             :   void setPeriodicityForOutputs( ActionWithValue* action ) override;
+      71             :   void calc( const ActionWithArguments* action, const std::vector<double>& args, std::vector<double>& vals, Matrix<double>& derivatives ) const override;
+      72             : };
+      73             : 
+      74             : typedef FunctionShortcut<Moments> MomentsShortcut;
+      75             : PLUMED_REGISTER_ACTION(MomentsShortcut,"MOMENTS")
+      76             : typedef FunctionOfScalar<Moments> ScalarMoments;
+      77             : PLUMED_REGISTER_ACTION(ScalarMoments,"MOMENTS_SCALAR")
+      78             : typedef FunctionOfVector<Moments> VectorMoments;
+      79             : PLUMED_REGISTER_ACTION(VectorMoments,"MOMENTS_VECTOR")
+      80             : 
+      81          22 : void Moments::registerKeywords(Keywords& keys) {
+      82          44 :   keys.add("compulsory","POWERS","calculate the central moments of the distribution of collective variables. "
+      83             :            "The \\f$m\\f$th central 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 "
+      84             :            "the average for the distribution. The POWERS keyword takes a lists of integers as input or a range. Each integer is a value of \\f$m\\f$. The final "
+      85             :            "calculated values can be referenced using moment-\\f$m\\f$.");
+      86          44 :   keys.addOutputComponent("moment","default","the central moments of the distribution of values. The second central moment "
+      87             :                           "would be referenced elsewhere in the input file using "
+      88             :                           "<em>label</em>.moment-2, the third as <em>label</em>.moment-3, etc.");
+      89          22 : }
+      90             : 
+      91           5 : void Moments::read( ActionWithArguments* action ) {
+      92           5 :   scalar_out = action->getNumberOfArguments()==1;
+      93           5 :   if( scalar_out && action->getPntrToArgument(0)->getRank()==0 ) action->error("cannot calculate moments if only given one variable");
+      94             : 
+      95           5 :   isperiodic = (action->getPntrToArgument(0))->isPeriodic();
+      96           5 :   if( isperiodic ) {
+      97           0 :     std::string str_min, str_max; (action->getPntrToArgument(0))->getDomain( str_min, str_max );
+      98           0 :     for(unsigned i=1; i<action->getNumberOfArguments(); ++i) {
+      99           0 :       if( !(action->getPntrToArgument(i))->isPeriodic() ) action->error("cannot mix periodic and non periodic variables when calculating moments");
+     100           0 :       std::string str_min2, str_max2; (action->getPntrToArgument(i))->getDomain( str_min2, str_max2);
+     101           0 :       if( str_min!=str_min2 || str_max!=str_max2 ) action->error("all input arguments should have same domain when calculating moments");
+     102             :     }
+     103           0 :     Tools::convert(str_min,min); Tools::convert(str_max,max); pfactor = 2*pi / ( max-min );
+     104             :   } else {
+     105          14 :     for(unsigned i=1; i<action->getNumberOfArguments(); ++i) {
+     106           9 :       if( (action->getPntrToArgument(i))->isPeriodic() ) action->error("cannot mix periodic and non periodic variables when calculating moments");
+     107             :     }
+     108             :   }
+     109             : 
+     110           5 :   parseVector(action,"POWERS",powers);
+     111          13 :   for(unsigned i=0; i<powers.size(); ++i) {
+     112           8 :     if( powers[i]<2 ) action->error("first central moment is zero do you really need to calculate that");
+     113           8 :     action->log.printf("  computing %dth central moment of distribution of input cvs \n", powers[i]);
+     114             :   }
+     115           5 : }
+     116             : 
+     117           6 : std::vector<std::string> Moments::getComponentsPerLabel() const {
+     118             :   std::vector<std::string> comp; std::string num;
+     119          15 :   for(unsigned i=0; i<powers.size(); ++i) {
+     120          18 :     Tools::convert(powers[i],num); comp.push_back( "-" + num );
+     121             :   }
+     122           6 :   return comp;
+     123           0 : }
+     124             : 
+     125           5 : void Moments::setPeriodicityForOutputs( ActionWithValue* action ) {
+     126          13 :   for(unsigned i=0; i<powers.size(); ++i) { std::string num; Tools::convert(powers[i],num); action->componentIsNotPeriodic("moment-" + num); }
+     127           5 : }
+     128             : 
+     129         222 : void Moments::calc( const ActionWithArguments* action, const std::vector<double>& args, std::vector<double>& vals, Matrix<double>& derivatives ) const {
+     130         222 :   double mean=0; double inorm = 1.0 / static_cast<double>( args.size() );
+     131         222 :   if( isperiodic ) {
+     132             :     double sinsum=0, cossum=0, val;
+     133           0 :     for(unsigned i=0; i<args.size(); ++i) { val=pfactor*( args[i] - min ); sinsum+=sin(val); cossum+=cos(val); }
+     134           0 :     mean = 0.5 + atan2( inorm*sinsum, inorm*cossum ) / (2*pi);
+     135           0 :     mean = min + (max-min)*mean;
+     136             :   } else {
+     137        1758 :     for(unsigned i=0; i<args.size(); ++i) mean+=args[i];
+     138         222 :     mean *= inorm;
+     139             :   }
+     140             : 
+     141             :   Value* arg0 = action->getPntrToArgument(0);
+     142         656 :   for(unsigned npow=0; npow<powers.size(); ++npow) {
+     143             :     double dev1=0;
+     144        3406 :     for(unsigned i=0; i<args.size(); ++i) dev1+=pow( arg0->difference( mean, args[i] ), powers[npow] - 1 );
+     145         434 :     dev1*=inorm; vals[npow] = 0; double prefactor = powers[npow]*inorm;
+     146        3406 :     for(unsigned i=0; i<args.size(); ++i) {
+     147        2972 :       double tmp=arg0->difference( mean, args[i] ); vals[npow] += inorm*pow( tmp, powers[npow] );
+     148        2972 :       derivatives(npow,i) = prefactor*(pow( tmp, powers[npow] - 1 ) - dev1);
+     149             :     }
+     150             :   }
+     151         222 : }
+     152             : 
+     153             : }
+     154             : }
+     155             : 
+     156             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/MoreThan.cpp.func-sort-c.html b/coverage/function/MoreThan.cpp.func-sort-c.html new file mode 100644 index 000000000000..51d412940e3d --- /dev/null +++ b/coverage/function/MoreThan.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - function/MoreThan.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - MoreThan.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:242885.7 %
Date:2024-04-19 12:12:35Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function8MoreThan4readEPNS_19ActionWithArgumentsE68
_ZN4PLMD8function8MoreThan16registerKeywordsERNS_8KeywordsE142
_ZNK4PLMD8function8MoreThan4calcEPKNS_19ActionWithArgumentsERKSt6vectorIdSaIdEERS7_RNS_6MatrixIdEE556662
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/MoreThan.cpp.func.html b/coverage/function/MoreThan.cpp.func.html new file mode 100644 index 000000000000..aee329dd8e51 --- /dev/null +++ b/coverage/function/MoreThan.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - function/MoreThan.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - MoreThan.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:242885.7 %
Date:2024-04-19 12:12:35Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function8MoreThan16registerKeywordsERNS_8KeywordsE142
_ZN4PLMD8function8MoreThan4readEPNS_19ActionWithArgumentsE68
_ZNK4PLMD8function8MoreThan4calcEPKNS_19ActionWithArgumentsERKSt6vectorIdSaIdEERS7_RNS_6MatrixIdEE556662
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/MoreThan.cpp.gcov.html b/coverage/function/MoreThan.cpp.gcov.html new file mode 100644 index 000000000000..7ef59caf647a --- /dev/null +++ b/coverage/function/MoreThan.cpp.gcov.html @@ -0,0 +1,174 @@ + + + + + + + + LCOV - plumed test coverage - function/MoreThan.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - MoreThan.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:242885.7 %
Date:2024-04-19 12:12:35Functions:33100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2017 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "MoreThan.h"
+      23             : #include "FunctionShortcut.h"
+      24             : #include "FunctionOfVector.h"
+      25             : #include "core/ActionRegister.h"
+      26             : 
+      27             : #include <cmath>
+      28             : 
+      29             : namespace PLMD {
+      30             : namespace function {
+      31             : 
+      32             : //+PLUMEDOC FUNCTION MORE_THAN
+      33             : /*
+      34             : Use a switching function to determine how many of the input variables are more than a certain cutoff.
+      35             : 
+      36             : \par Examples
+      37             : 
+      38             : */
+      39             : //+ENDPLUMEDOC
+      40             : 
+      41             : //+PLUMEDOC FUNCTION MORE_THAN_VECTOR
+      42             : /*
+      43             : Use a switching function to determine how many of elements in the input vector are more than a certain cutoff.
+      44             : 
+      45             : \par Examples
+      46             : 
+      47             : */
+      48             : //+ENDPLUMEDOC
+      49             : 
+      50             : typedef FunctionShortcut<MoreThan> MoreThanShortcut;
+      51             : PLUMED_REGISTER_ACTION(MoreThanShortcut,"MORE_THAN")
+      52             : typedef FunctionOfVector<MoreThan> VectorMoreThan;
+      53             : PLUMED_REGISTER_ACTION(VectorMoreThan,"MORE_THAN_VECTOR")
+      54             : 
+      55         142 : void MoreThan::registerKeywords(Keywords& keys) {
+      56         284 :   keys.add("compulsory","NN","6","The n parameter of the switching function ");
+      57         284 :   keys.add("compulsory","MM","0","The m parameter of the switching function; 0 implies 2*NN");
+      58         284 :   keys.add("compulsory","D_0","0.0","The d_0 parameter of the switching function");
+      59         284 :   keys.add("compulsory","R_0","The r_0 parameter of the switching function");
+      60         284 :   keys.add("optional","SWITCH","This keyword is used if you want to employ an alternative to the continuous swiching function defined above. "
+      61             :            "The following provides information on the \\ref switchingfunction that are available. "
+      62             :            "When this keyword is present you no longer need the NN, MM, D_0 and R_0 keywords.");
+      63         284 :   keys.addFlag("SQUARED",false,"is the input quantity the square of the value that you would like to apply the switching function to");
+      64         142 : }
+      65             : 
+      66          68 : void MoreThan::read( ActionWithArguments* action ) {
+      67          68 :   if( action->getNumberOfArguments()!=1 ) action->error("should only be one argument to more_than actions");
+      68          68 :   if( action->getPntrToArgument(0)->isPeriodic() ) action->error("cannot use this function on periodic functions");
+      69             : 
+      70             : 
+      71             :   std::string sw,errors;
+      72         136 :   action->parse("SWITCH",sw);
+      73          68 :   if(sw.length()>0) {
+      74          68 :     switchingFunction.set(sw,errors);
+      75          68 :     if( errors.length()!=0 ) action->error("problem reading SWITCH keyword : " + errors );
+      76             :   } else {
+      77           0 :     int nn=6; int mm=0; double d0=0.0; double r0=0.0; action->parse("R_0",r0);
+      78           0 :     if(r0<=0.0) action->error("R_0 should be explicitly specified and positive");
+      79           0 :     action->parse("D_0",d0); action->parse("NN",nn); action->parse("MM",mm);
+      80           0 :     switchingFunction.set(nn,mm,r0,d0);
+      81             :   }
+      82          68 :   action->log<<"  using switching function with cutoff "<<switchingFunction.description()<<"\n";
+      83          68 :   action->parseFlag("SQUARED",squared);
+      84          68 :   if( squared ) action->log<<"  input quantity is square of quantity that switching function acts upon\n";
+      85          68 : }
+      86             : 
+      87      556662 : void MoreThan::calc( const ActionWithArguments* action, const std::vector<double>& args, std::vector<double>& vals, Matrix<double>& derivatives ) const {
+      88             :   plumed_dbg_assert( args.size()==1 );
+      89      556662 :   if( squared ) vals[0] = 1.0 - switchingFunction.calculateSqr( args[0], derivatives(0,0) );
+      90       87550 :   else vals[0] = 1.0 - switchingFunction.calculate( args[0], derivatives(0,0) );
+      91      556662 :   derivatives(0,0) = -args[0]*derivatives(0,0);
+      92      556662 : }
+      93             : 
+      94             : }
+      95             : }
+      96             : 
+      97             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/MoreThan.h.func-sort-c.html b/coverage/function/MoreThan.h.func-sort-c.html new file mode 100644 index 000000000000..0996e8e102b7 --- /dev/null +++ b/coverage/function/MoreThan.h.func-sort-c.html @@ -0,0 +1,77 @@ + + + + + + + + LCOV - plumed test coverage - function/MoreThan.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - MoreThan.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1250.0 %
Date:2024-04-19 12:12:35Functions:010.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD8function8MoreThan30getDerivativeZeroIfValueIsZeroEv0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/MoreThan.h.func.html b/coverage/function/MoreThan.h.func.html new file mode 100644 index 000000000000..41c73389fda8 --- /dev/null +++ b/coverage/function/MoreThan.h.func.html @@ -0,0 +1,77 @@ + + + + + + + + LCOV - plumed test coverage - function/MoreThan.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - MoreThan.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1250.0 %
Date:2024-04-19 12:12:35Functions:010.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD8function8MoreThan30getDerivativeZeroIfValueIsZeroEv0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/MoreThan.h.gcov.html b/coverage/function/MoreThan.h.gcov.html new file mode 100644 index 000000000000..53405d140d7d --- /dev/null +++ b/coverage/function/MoreThan.h.gcov.html @@ -0,0 +1,120 @@ + + + + + + + + LCOV - plumed test coverage - function/MoreThan.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - MoreThan.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1250.0 %
Date:2024-04-19 12:12:35Functions:010.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2020 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a 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_MoreThan_h
+      23             : #define __PLUMED_function_MoreThan_h
+      24             : 
+      25             : #include "FunctionTemplateBase.h"
+      26             : #include "tools/SwitchingFunction.h"
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace function {
+      30             : 
+      31         340 : class MoreThan : public FunctionTemplateBase {
+      32             :   bool squared;
+      33             :   SwitchingFunction switchingFunction;
+      34             : public:
+      35             :   void registerKeywords( Keywords& keys ) override;
+      36             :   void read( ActionWithArguments* action ) override;
+      37           0 :   bool getDerivativeZeroIfValueIsZero() const override { return true; }
+      38             :   void calc( const ActionWithArguments* action, const std::vector<double>& args, std::vector<double>& vals, Matrix<double>& derivatives ) const override;
+      39             : };
+      40             : 
+      41             : }
+      42             : }
+      43             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Piecewise.cpp.func-sort-c.html b/coverage/function/Piecewise.cpp.func-sort-c.html new file mode 100644 index 000000000000..8efa138f0fa6 --- /dev/null +++ b/coverage/function/Piecewise.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - function/Piecewise.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - Piecewise.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3636100.0 %
Date:2024-04-19 12:12:35Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function9Piecewise24setPeriodicityForOutputsEPNS_15ActionWithValueE2
_ZN4PLMD8function9Piecewise4readEPNS_19ActionWithArgumentsE3
_ZN4PLMD8function9Piecewise16registerKeywordsERNS_8KeywordsE10
_ZNK4PLMD8function9Piecewise4calcEPKNS_19ActionWithArgumentsERKSt6vectorIdSaIdEERS7_RNS_6MatrixIdEE10
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Piecewise.cpp.func.html b/coverage/function/Piecewise.cpp.func.html new file mode 100644 index 000000000000..96711903b7db --- /dev/null +++ b/coverage/function/Piecewise.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - function/Piecewise.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - Piecewise.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3636100.0 %
Date:2024-04-19 12:12:35Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function9Piecewise16registerKeywordsERNS_8KeywordsE10
_ZN4PLMD8function9Piecewise24setPeriodicityForOutputsEPNS_15ActionWithValueE2
_ZN4PLMD8function9Piecewise4readEPNS_19ActionWithArgumentsE3
_ZNK4PLMD8function9Piecewise4calcEPKNS_19ActionWithArgumentsERKSt6vectorIdSaIdEERS7_RNS_6MatrixIdEE10
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Piecewise.cpp.gcov.html b/coverage/function/Piecewise.cpp.gcov.html new file mode 100644 index 000000000000..7d68a4a84056 --- /dev/null +++ b/coverage/function/Piecewise.cpp.gcov.html @@ -0,0 +1,223 @@ + + + + + + + + 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:3636100.0 %
Date:2024-04-19 12:12:35Functions: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 "core/ActionRegister.h"
+      23             : #include "FunctionTemplateBase.h"
+      24             : #include "FunctionShortcut.h"
+      25             : #include "FunctionOfScalar.h"
+      26             : 
+      27             : namespace PLMD {
+      28             : namespace function {
+      29             : 
+      30             : //+PLUMEDOC FUNCTION PIECEWISE
+      31             : /*
+      32             : Compute a piece wise straight line through its arguments that passes through a set of ordered control points.
+      33             : 
+      34             : For variables less than the first
+      35             : (greater than the last) point, the value of the first (last) point is used.
+      36             : 
+      37             : \f[
+      38             : \frac{y_{i+1}-y_i}{x_{i+1}-x_i}(s-x_i)+y_i ;  if x_i<s<x_{i+1}
+      39             : \f]
+      40             : \f[
+      41             : y_N ; if x>x_{N-1}
+      42             : \f]
+      43             : \f[
+      44             : y_1 ; if x<x_0
+      45             : \f]
+      46             : 
+      47             : Control points are passed using the POINT0=... POINT1=... syntax as in the example below
+      48             : 
+      49             : If one argument is supplied, it results in a scalar quantity.
+      50             : If multiple arguments are supplied, it results
+      51             : in a vector of values. Each value will be named as the name of the original
+      52             : argument with suffix _pfunc.
+      53             : 
+      54             : \par Examples
+      55             : 
+      56             : \plumedfile
+      57             : dist1: DISTANCE ATOMS=1,10
+      58             : dist2: DISTANCE ATOMS=2,11
+      59             : 
+      60             : pw: PIECEWISE POINT0=1,10 POINT1=2,PI POINT2=3,10 ARG=dist1
+      61             : ppww: PIECEWISE POINT0=1,10 POINT1=2,PI POINT2=3,10 ARG=dist1,dist2
+      62             : PRINT ARG=pw,ppww.dist1_pfunc,ppww.dist2_pfunc
+      63             : \endplumedfile
+      64             : 
+      65             : 
+      66             : */
+      67             : //+ENDPLUMEDOC
+      68             : 
+      69             : //+PLUMEDOC FUNCTION PIECEWISE_SCALAR
+      70             : /*
+      71             : Compute a piece wise straight line through its arguments that passes through a set of ordered control points.
+      72             : 
+      73             : \par Examples
+      74             : 
+      75             : */
+      76             : //+ENDPLUMEDOC
+      77             : 
+      78          19 : class Piecewise : public FunctionTemplateBase {
+      79             :   std::vector<std::pair<double,double> > points;
+      80             : public:
+      81             :   void registerKeywords(Keywords& keys) override;
+      82             :   void read( ActionWithArguments* action ) override;
+      83             :   void setPeriodicityForOutputs( ActionWithValue* action ) override;
+      84             :   void calc( const ActionWithArguments* action, const std::vector<double>& args, std::vector<double>& vals, Matrix<double>& derivatives ) const override;
+      85             : };
+      86             : 
+      87             : 
+      88             : typedef FunctionShortcut<Piecewise> PiecewiseShortcut;
+      89             : PLUMED_REGISTER_ACTION(PiecewiseShortcut,"PIECEWISE")
+      90             : typedef FunctionOfScalar<Piecewise> ScalarPiecewise;
+      91             : PLUMED_REGISTER_ACTION(ScalarPiecewise,"PIECEWISE_SCALAR")
+      92             : 
+      93          10 : void Piecewise::registerKeywords(Keywords& keys) {
+      94          20 :   keys.add("numbered","POINT","This keyword is used to specify the various points in the function above.");
+      95          20 :   keys.reset_style("POINT","compulsory");
+      96          20 :   keys.addOutputComponent("_pfunc","default","one or multiple instances of this quantity can be referenced elsewhere "
+      97             :                           "in the input file.  These quantities will be named with the arguments of the "
+      98             :                           "function followed by the character string _pfunc.  These quantities tell the "
+      99             :                           "user the values of the piece wise functions of each of the arguments.");
+     100          10 : }
+     101             : 
+     102           3 : void Piecewise::read( ActionWithArguments* action ) {
+     103           9 :   for(int i=0;; i++) {
+     104             :     std::vector<double> pp;
+     105          24 :     if(!action->parseNumberedVector("POINT",i,pp) ) break;
+     106           9 :     if(pp.size()!=2) action->error("points should be in x,y format");
+     107           9 :     points.push_back(std::pair<double,double>(pp[0],pp[1]));
+     108           9 :     if(i>0 && points[i].first<=points[i-1].first) action->error("points abscissas should be monotonously increasing");
+     109           9 :   }
+     110             : 
+     111           6 :   for(unsigned i=0; i<action->getNumberOfArguments(); i++) {
+     112           4 :     if(action->getPntrToArgument(i)->isPeriodic()) action->error("Cannot use PIECEWISE on periodic arguments");
+     113             :   }
+     114           2 :   action->log.printf("  on points:");
+     115           8 :   for(unsigned i=0; i<points.size(); i++) action->log.printf("   (%f,%f)",points[i].first,points[i].second);
+     116           2 :   action->log.printf("\n");
+     117           2 : }
+     118             : 
+     119           2 : void Piecewise::setPeriodicityForOutputs( ActionWithValue* action ) {
+     120           5 :   for(unsigned i=0; i<action->getNumberOfComponents(); ++i) action->copyOutput(i)->setNotPeriodic();
+     121           2 : }
+     122             : 
+     123          10 : void Piecewise::calc( const ActionWithArguments* action, const std::vector<double>& args, std::vector<double>& vals, Matrix<double>& derivatives ) const {
+     124          25 :   for(unsigned i=0; i<args.size(); i++) {
+     125             :     unsigned p=0;
+     126          37 :     for(; p<points.size(); p++) {
+     127          33 :       if(args[i]<points[p].first) break;
+     128             :     }
+     129          15 :     if(p==0) {
+     130           5 :       vals[i]=points[0].second;
+     131           5 :       derivatives(i,i)=0.0;
+     132          10 :     } else if(p==points.size()) {
+     133           4 :       vals[i]=points[points.size()-1].second;
+     134           4 :       derivatives(i,i)=0.0;
+     135             :     } else {
+     136           6 :       double m=(points[p].second-points[p-1].second) / (points[p].first-points[p-1].first);
+     137           6 :       vals[i]=m*(args[i]-points[p-1].first)+points[p-1].second;
+     138           6 :       derivatives(i,i)=m;
+     139             :     }
+     140             :   }
+     141          10 : }
+     142             : 
+     143             : }
+     144             : }
+     145             : 
+     146             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Product.cpp.func-sort-c.html b/coverage/function/Product.cpp.func-sort-c.html new file mode 100644 index 000000000000..db1792b0534d --- /dev/null +++ b/coverage/function/Product.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - function/Product.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - Product.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1313100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function7ProductC2ERKNS_13ActionOptionsE0
_ZN4PLMD8function7ProductC1ERKNS_13ActionOptionsE114
_ZN4PLMD8function7Product16registerKeywordsERNS_8KeywordsE120
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Product.cpp.func.html b/coverage/function/Product.cpp.func.html new file mode 100644 index 000000000000..e8e9b0103ef3 --- /dev/null +++ b/coverage/function/Product.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - function/Product.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - Product.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1313100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function7Product16registerKeywordsERNS_8KeywordsE120
_ZN4PLMD8function7ProductC1ERKNS_13ActionOptionsE114
_ZN4PLMD8function7ProductC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Product.cpp.gcov.html b/coverage/function/Product.cpp.gcov.html new file mode 100644 index 000000000000..5463150c2068 --- /dev/null +++ b/coverage/function/Product.cpp.gcov.html @@ -0,0 +1,140 @@ + + + + + + + + LCOV - plumed test coverage - function/Product.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - Product.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1313100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2014-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionRegister.h"
+      23             : #include "core/ActionShortcut.h"
+      24             : 
+      25             : //+PLUMEDOC FUNCTION PRODUCT
+      26             : /*
+      27             : Calculate the product of the input quantities
+      28             : 
+      29             : \par Examples
+      30             : 
+      31             : */
+      32             : //+ENDPLUMEDOC
+      33             : 
+      34             : namespace PLMD {
+      35             : namespace function {
+      36             : 
+      37             : class Product : public ActionShortcut {
+      38             : public:
+      39             :   static void registerKeywords( Keywords& keys );
+      40             :   explicit Product(const ActionOptions&ao);
+      41             : };
+      42             : 
+      43             : PLUMED_REGISTER_ACTION(Product,"PRODUCT")
+      44             : 
+      45         120 : void Product::registerKeywords( Keywords& keys ) {
+      46         120 :   ActionShortcut::registerKeywords(keys);
+      47         240 :   keys.add("compulsory","ARG","The point that we are calculating the distance from");
+      48         360 :   keys.needsAction("CONCATENATE"); keys.needsAction("CUSTOM"); keys.needsAction("SUM");
+      49         120 : }
+      50             : 
+      51         114 : Product::Product( const ActionOptions& ao):
+      52             :   Action(ao),
+      53         114 :   ActionShortcut(ao)
+      54             : {
+      55         114 :   std::string arg; parse("ARG",arg);
+      56         228 :   readInputLine( getShortcutLabel() + "_vec: CONCATENATE ARG=" + arg );
+      57         228 :   readInputLine( getShortcutLabel() + "_logs: CUSTOM ARG=" + getShortcutLabel() + "_vec FUNC=log(x) PERIODIC=NO");
+      58         228 :   readInputLine( getShortcutLabel() + "_logsum: SUM ARG=" + getShortcutLabel() + "_logs PERIODIC=NO");
+      59         228 :   readInputLine( getShortcutLabel() + ": CUSTOM ARG=" + getShortcutLabel() + "_logsum FUNC=exp(x) PERIODIC=NO");
+      60         114 : }
+      61             : 
+      62             : }
+      63             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Sort.cpp.func-sort-c.html b/coverage/function/Sort.cpp.func-sort-c.html new file mode 100644 index 000000000000..4b331bb1440b --- /dev/null +++ b/coverage/function/Sort.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - function/Sort.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - Sort.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:252792.6 %
Date:2024-04-19 12:12:35Functions:5771.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD8function4Sort11doWithTasksEv0
_ZNK4PLMD8function4Sort8zeroRankEv0
_ZN4PLMD8function4Sort24setPeriodicityForOutputsEPNS_15ActionWithValueE13
_ZNK4PLMD8function4Sort21getComponentsPerLabelB5cxx11Ev13
_ZN4PLMD8function4Sort4readEPNS_19ActionWithArgumentsE14
_ZN4PLMD8function4Sort16registerKeywordsERNS_8KeywordsE38
_ZNK4PLMD8function4Sort4calcEPKNS_19ActionWithArgumentsERKSt6vectorIdSaIdEERS7_RNS_6MatrixIdEE45
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Sort.cpp.func.html b/coverage/function/Sort.cpp.func.html new file mode 100644 index 000000000000..1a5ec2c5257c --- /dev/null +++ b/coverage/function/Sort.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - function/Sort.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - Sort.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:252792.6 %
Date:2024-04-19 12:12:35Functions:5771.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function4Sort16registerKeywordsERNS_8KeywordsE38
_ZN4PLMD8function4Sort24setPeriodicityForOutputsEPNS_15ActionWithValueE13
_ZN4PLMD8function4Sort4readEPNS_19ActionWithArgumentsE14
_ZNK4PLMD8function4Sort11doWithTasksEv0
_ZNK4PLMD8function4Sort21getComponentsPerLabelB5cxx11Ev13
_ZNK4PLMD8function4Sort4calcEPKNS_19ActionWithArgumentsERKSt6vectorIdSaIdEERS7_RNS_6MatrixIdEE45
_ZNK4PLMD8function4Sort8zeroRankEv0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Sort.cpp.gcov.html b/coverage/function/Sort.cpp.gcov.html new file mode 100644 index 000000000000..c0ce86dd97bc --- /dev/null +++ b/coverage/function/Sort.cpp.gcov.html @@ -0,0 +1,213 @@ + + + + + + + + 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:252792.6 %
Date:2024-04-19 12:12:35Functions: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 "FunctionShortcut.h"
+      23             : #include "FunctionOfScalar.h"
+      24             : #include "FunctionOfVector.h"
+      25             : #include "core/ActionRegister.h"
+      26             : #include "FunctionTemplateBase.h"
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace function {
+      30             : 
+      31             : //+PLUMEDOC FUNCTION SORT
+      32             : /*
+      33             : This function can be used to sort colvars according to their magnitudes.
+      34             : 
+      35             : \par Description of components
+      36             : 
+      37             : This function sorts its arguments according to their magnitudes. The lowest argument will be
+      38             : labelled <em>label</em>.1, the second lowest will be labelled <em>label</em>.2 and so on.
+      39             : 
+      40             : \par Examples
+      41             : 
+      42             : The following input tells plumed to print the distance of the closest and of
+      43             : the farthest atoms to atom 1, chosen among atoms from 2 to 5
+      44             : \plumedfile
+      45             : d12:  DISTANCE ATOMS=1,2
+      46             : d13:  DISTANCE ATOMS=1,3
+      47             : d14:  DISTANCE ATOMS=1,4
+      48             : d15:  DISTANCE ATOMS=1,5
+      49             : sort: SORT ARG=d12,d13,d14,d15
+      50             : PRINT ARG=sort.1,sort.4
+      51             : \endplumedfile
+      52             : 
+      53             : */
+      54             : //+ENDPLUMEDOC
+      55             : 
+      56             : //+PLUMEDOC FUNCTION SORT_SCALAR
+      57             : /*
+      58             : Sort the input scalars in a vector according to their magnitudes
+      59             : 
+      60             : \par Examples
+      61             : 
+      62             : */
+      63             : //+ENDPLUMEDOC
+      64             : 
+      65             : //+PLUMEDOC FUNCTION SORT_VECTOR
+      66             : /*
+      67             : Sort the elements in a vector according to their magnitudes
+      68             : 
+      69             : \par Examples
+      70             : 
+      71             : */
+      72             : //+ENDPLUMEDOC
+      73             : 
+      74          66 : class Sort : public FunctionTemplateBase {
+      75             : private:
+      76             :   bool scalar_out;
+      77             :   unsigned nargs;
+      78             : public:
+      79             :   void registerKeywords(Keywords& keys) override ;
+      80             :   void read( ActionWithArguments* action ) override;
+      81           0 :   bool zeroRank() const override { return true; }
+      82          36 :   bool doWithTasks() const override { return !scalar_out; }
+      83             :   std::vector<std::string> getComponentsPerLabel() const override ;
+      84             :   void setPeriodicityForOutputs( ActionWithValue* action ) override;
+      85             :   void calc( const ActionWithArguments* action, const std::vector<double>& args, std::vector<double>& vals, Matrix<double>& derivatives ) const override;
+      86             : };
+      87             : 
+      88             : typedef FunctionShortcut<Sort> SortShortcut;
+      89             : PLUMED_REGISTER_ACTION(SortShortcut,"SORT")
+      90             : typedef FunctionOfScalar<Sort> ScalarSort;
+      91             : PLUMED_REGISTER_ACTION(ScalarSort,"SORT_SCALAR")
+      92             : typedef FunctionOfVector<Sort> VectorSort;
+      93             : PLUMED_REGISTER_ACTION(VectorSort,"SORT_VECTOR")
+      94             : 
+      95          38 : void Sort::registerKeywords(Keywords& keys) {
+      96          38 :   keys.setComponentsIntroduction("The names of the components in this action will be customized in accordance with the contents of the input file. "
+      97             :                                  "The largest value is called label.1th, the second largest label.2th, the third label.3th and so on");
+      98          38 : }
+      99             : 
+     100             : 
+     101          14 : void Sort::read( ActionWithArguments* action ) {
+     102          14 :   scalar_out = action->getNumberOfArguments()==1; nargs = action->getNumberOfArguments(); if( scalar_out ) nargs = action->getPntrToArgument(0)->getNumberOfValues();
+     103             : 
+     104          39 :   for(unsigned i=0; i<action->getNumberOfArguments(); ++i) {
+     105          27 :     if((action->getPntrToArgument(i))->isPeriodic()) action->error("Cannot sort periodic values (check argument "+ (action->getPntrToArgument(i))->getName() +")");
+     106             :   }
+     107          13 : }
+     108             : 
+     109          13 : std::vector<std::string> Sort::getComponentsPerLabel() const {
+     110             :   std::vector<std::string> comp; std::string num;
+     111          50 :   for(unsigned i=0; i<nargs; ++i) {
+     112          37 :     Tools::convert(i+1,num); comp.push_back( num );
+     113             :   }
+     114          13 :   return comp;
+     115           0 : }
+     116             : 
+     117          13 : void Sort::setPeriodicityForOutputs( ActionWithValue* action ) {
+     118          50 :   for(unsigned i=0; i<nargs; ++i) { std::string num; Tools::convert(i+1,num); action->componentIsNotPeriodic( num ); }
+     119          13 : }
+     120             : 
+     121          45 : void Sort::calc( const ActionWithArguments* action, const std::vector<double>& args, std::vector<double>& vals, Matrix<double>& derivatives ) const {
+     122          45 :   std::vector<std::pair<double,int> > data(args.size());
+     123         326 :   for(unsigned i=0; i<args.size(); ++i) {
+     124         281 :     data[i].first=args[i];
+     125             : // In this manner I remember from which argument the component depends:
+     126         281 :     data[i].second=i;
+     127             :   }
+     128             : // STL sort sorts based on first element (value) then second (index)
+     129          45 :   std::sort(data.begin(),data.end()); derivatives = 0;
+     130         326 :   for(int i=0; i<vals.size(); ++i) { vals[i] = data[i].first; derivatives(i, data[i].second ) = 1; }
+     131          45 : }
+     132             : 
+     133             : }
+     134             : }
+     135             : 
+     136             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Stats.cpp.func-sort-c.html b/coverage/function/Stats.cpp.func-sort-c.html new file mode 100644 index 000000000000..f2e36fb75966 --- /dev/null +++ b/coverage/function/Stats.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - function/Stats.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - Stats.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:9910396.1 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function5StatsC2ERKNS_13ActionOptionsE0
_ZN4PLMD8function5StatsC1ERKNS_13ActionOptionsE31
_ZN4PLMD8function5Stats16registerKeywordsERNS_8KeywordsE33
_ZN4PLMD8function5Stats9calculateEv122
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Stats.cpp.func.html b/coverage/function/Stats.cpp.func.html new file mode 100644 index 000000000000..6faa0c4251f4 --- /dev/null +++ b/coverage/function/Stats.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - function/Stats.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - Stats.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:9910396.1 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function5Stats16registerKeywordsERNS_8KeywordsE33
_ZN4PLMD8function5Stats9calculateEv122
_ZN4PLMD8function5StatsC1ERKNS_13ActionOptionsE31
_ZN4PLMD8function5StatsC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Stats.cpp.gcov.html b/coverage/function/Stats.cpp.gcov.html new file mode 100644 index 000000000000..ead40ca63fc3 --- /dev/null +++ b/coverage/function/Stats.cpp.gcov.html @@ -0,0 +1,316 @@ + + + + + + + + LCOV - plumed test coverage - function/Stats.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - Stats.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:9910396.1 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "Function.h"
+      23             : #include "core/ActionRegister.h"
+      24             : 
+      25             : namespace PLMD {
+      26             : namespace function {
+      27             : 
+      28             : //+PLUMEDOC FUNCTION STATS
+      29             : /*
+      30             : Calculates statistical properties of a set of collective variables with respect to a set of reference values.
+      31             : 
+      32             : In particular it calculates and stores as components the sum of the squared deviations, the correlation, the
+      33             : slope and the intercept of a linear fit.
+      34             : 
+      35             : The reference values can be either provided as values using PARAMETERS or using value without derivatives
+      36             : from other actions using PARARG (for example using experimental values from collective variables such as
+      37             : \ref CS2BACKBONE, \ref RDC, \ref NOE, \ref PRE).
+      38             : 
+      39             : \par Examples
+      40             : 
+      41             : The following input tells plumed to print the distance between three couple of atoms
+      42             : and compare them with three reference distances.
+      43             : 
+      44             : \plumedfile
+      45             : d1: DISTANCE ATOMS=10,50
+      46             : d2: DISTANCE ATOMS=1,100
+      47             : d3: DISTANCE ATOMS=45,75
+      48             : st: STATS ARG=d1,d2,d3 PARAMETERS=1.5,4.0,2.0
+      49             : PRINT ARG=d1,d2,d3,st.*
+      50             : \endplumedfile
+      51             : 
+      52             : */
+      53             : //+ENDPLUMEDOC
+      54             : 
+      55             : 
+      56             : class Stats :
+      57             :   public Function
+      58             : {
+      59             :   std::vector<double> parameters;
+      60             :   bool sqdonly;
+      61             :   bool components;
+      62             :   bool upperd;
+      63             : public:
+      64             :   explicit Stats(const ActionOptions&);
+      65             :   void calculate() override;
+      66             :   static void registerKeywords(Keywords& keys);
+      67             : };
+      68             : 
+      69             : 
+      70             : PLUMED_REGISTER_ACTION(Stats,"STATS")
+      71             : 
+      72          33 : void Stats::registerKeywords(Keywords& keys) {
+      73          33 :   Function::registerKeywords(keys);
+      74          33 :   keys.use("ARG");
+      75          66 :   keys.add("optional","PARARG","the input for this action is the scalar output from one or more other actions without derivatives.");
+      76          66 :   keys.add("optional","PARAMETERS","the parameters of the arguments in your function");
+      77          66 :   keys.addFlag("SQDEVSUM",false,"calculates only SQDEVSUM");
+      78          66 :   keys.addFlag("SQDEV",false,"calculates and store the SQDEV as components");
+      79          66 :   keys.addFlag("UPPERDISTS",false,"calculates and store the SQDEV as components");
+      80          66 :   keys.addOutputComponent("sqdevsum","default","the sum of the squared deviations between arguments and parameters");
+      81          66 :   keys.addOutputComponent("corr","default","the correlation between arguments and parameters");
+      82          66 :   keys.addOutputComponent("slope","default","the slope of a linear fit between arguments and parameters");
+      83          66 :   keys.addOutputComponent("intercept","default","the intercept of a linear fit between arguments and parameters");
+      84          66 :   keys.addOutputComponent("sqd","SQDEV","the squared deviations between arguments and parameters");
+      85          33 : }
+      86             : 
+      87          31 : Stats::Stats(const ActionOptions&ao):
+      88             :   Action(ao),
+      89             :   Function(ao),
+      90          31 :   sqdonly(false),
+      91          31 :   components(false),
+      92          31 :   upperd(false)
+      93             : {
+      94          62 :   parseVector("PARAMETERS",parameters);
+      95          31 :   if(parameters.size()!=static_cast<unsigned>(getNumberOfArguments())&&!parameters.empty())
+      96           0 :     error("Size of PARAMETERS array should be either 0 or the same as of the number of arguments in ARG1");
+      97             : 
+      98             :   std::vector<Value*> arg2;
+      99          62 :   parseArgumentList("PARARG",arg2);
+     100             : 
+     101          31 :   if(!arg2.empty()) {
+     102          14 :     if(parameters.size()>0) error("It is not possible to use PARARG and PARAMETERS together");
+     103          14 :     if(arg2.size()!=getNumberOfArguments()) error("Size of PARARG array should be the same as number for arguments in ARG");
+     104        5912 :     for(unsigned i=0; i<arg2.size(); i++) {
+     105        5898 :       parameters.push_back(arg2[i]->get());
+     106        5898 :       if(arg2[i]->hasDerivatives()==true) error("PARARG can only accept arguments without derivatives");
+     107             :     }
+     108             :   }
+     109             : 
+     110          31 :   if(parameters.size()!=getNumberOfArguments())
+     111           0 :     error("PARARG or PARAMETERS arrays should include the same number of elements as the arguments in ARG");
+     112             : 
+     113          31 :   if(getNumberOfArguments()<2) error("STATS need at least two arguments to be used");
+     114             : 
+     115          31 :   parseFlag("SQDEVSUM",sqdonly);
+     116          31 :   parseFlag("SQDEV",components);
+     117          31 :   parseFlag("UPPERDISTS",upperd);
+     118             : 
+     119          31 :   if(sqdonly&&components) error("You cannot used SQDEVSUM and SQDEV at the sametime");
+     120             : 
+     121          31 :   if(components) sqdonly = true;
+     122             : 
+     123          31 :   if(!arg2.empty()) log.printf("  using %zu parameters from inactive actions:", arg2.size());
+     124          17 :   else              log.printf("  using %zu parameters:", arg2.size());
+     125        6000 :   for(unsigned i=0; i<parameters.size(); i++) log.printf(" %f",parameters[i]);
+     126          31 :   log.printf("\n");
+     127             : 
+     128          31 :   if(sqdonly) {
+     129          17 :     if(components) {
+     130          60 :       for(unsigned i=0; i<parameters.size(); i++) {
+     131          48 :         std::string num; Tools::convert(i,num);
+     132          48 :         addComponentWithDerivatives("sqd-"+num);
+     133          96 :         componentIsNotPeriodic("sqd-"+num);
+     134             :       }
+     135             :     } else {
+     136           5 :       addComponentWithDerivatives("sqdevsum");
+     137          10 :       componentIsNotPeriodic("sqdevsum");
+     138             :     }
+     139             :   } else {
+     140          14 :     addComponentWithDerivatives("sqdevsum");
+     141          14 :     componentIsNotPeriodic("sqdevsum");
+     142          14 :     addComponentWithDerivatives("corr");
+     143          14 :     componentIsNotPeriodic("corr");
+     144          14 :     addComponentWithDerivatives("slope");
+     145          14 :     componentIsNotPeriodic("slope");
+     146          14 :     addComponentWithDerivatives("intercept");
+     147          28 :     componentIsNotPeriodic("intercept");
+     148             :   }
+     149             : 
+     150          31 :   checkRead();
+     151          31 : }
+     152             : 
+     153         122 : void Stats::calculate()
+     154             : {
+     155         122 :   if(sqdonly) {
+     156             : 
+     157             :     double nsqd = 0.;
+     158             :     Value* val;
+     159         106 :     if(!components) val=getPntrToComponent("sqdevsum");
+     160         174 :     for(unsigned i=0; i<parameters.size(); ++i) {
+     161         121 :       double dev = getArgument(i)-parameters[i];
+     162         121 :       if(upperd&&dev<0) dev=0.;
+     163         121 :       if(components) {
+     164           0 :         val=getPntrToComponent(i);
+     165           0 :         val->set(dev*dev);
+     166             :       } else {
+     167         121 :         nsqd += dev*dev;
+     168             :       }
+     169         121 :       setDerivative(val,i,2.*dev);
+     170             :     }
+     171          53 :     if(!components) val->set(nsqd);
+     172             : 
+     173             :   } else {
+     174             : 
+     175             :     double scx=0., scx2=0., scy=0., scy2=0., scxy=0.;
+     176             : 
+     177        6230 :     for(unsigned i=0; i<parameters.size(); ++i) {
+     178        6161 :       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        6161 :       setDerivative(valueb,i,co_der);
+     229        6161 :       setDerivative(valuec,i,sl_der);
+     230        6161 :       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/Sum.cpp.func-sort-c.html b/coverage/function/Sum.cpp.func-sort-c.html new file mode 100644 index 000000000000..ddbeffbfd5c8 --- /dev/null +++ b/coverage/function/Sum.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - function/Sum.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - Sum.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1515100.0 %
Date:2024-04-19 12:12:35Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function3Sum4readEPNS_19ActionWithArgumentsE899
_ZN4PLMD8function3Sum12setPrefactorEPNS_19ActionWithArgumentsEd989
_ZN4PLMD8function3Sum16registerKeywordsERNS_8KeywordsE1731
_ZNK4PLMD8function3Sum8zeroRankEv25703
_ZNK4PLMD8function3Sum4calcEPKNS_19ActionWithArgumentsERKSt6vectorIdSaIdEERS7_RNS_6MatrixIdEE1882990
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Sum.cpp.func.html b/coverage/function/Sum.cpp.func.html new file mode 100644 index 000000000000..baf3e45d1127 --- /dev/null +++ b/coverage/function/Sum.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - function/Sum.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - Sum.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1515100.0 %
Date:2024-04-19 12:12:35Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function3Sum12setPrefactorEPNS_19ActionWithArgumentsEd989
_ZN4PLMD8function3Sum16registerKeywordsERNS_8KeywordsE1731
_ZN4PLMD8function3Sum4readEPNS_19ActionWithArgumentsE899
_ZNK4PLMD8function3Sum4calcEPKNS_19ActionWithArgumentsERKSt6vectorIdSaIdEERS7_RNS_6MatrixIdEE1882990
_ZNK4PLMD8function3Sum8zeroRankEv25703
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Sum.cpp.gcov.html b/coverage/function/Sum.cpp.gcov.html new file mode 100644 index 000000000000..6c55af119d66 --- /dev/null +++ b/coverage/function/Sum.cpp.gcov.html @@ -0,0 +1,195 @@ + + + + + + + + LCOV - plumed test coverage - function/Sum.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - Sum.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1515100.0 %
Date:2024-04-19 12:12:35Functions:55100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "Sum.h"
+      23             : #include "FunctionShortcut.h"
+      24             : #include "FunctionOfScalar.h"
+      25             : #include "FunctionOfVector.h"
+      26             : #include "core/ActionRegister.h"
+      27             : 
+      28             : //+PLUMEDOC COLVAR SUM
+      29             : /*
+      30             : Calculate the sum of the arguments
+      31             : 
+      32             : \par Examples
+      33             : 
+      34             : */
+      35             : //+ENDPLUMEDOC
+      36             : 
+      37             : //+PLUMEDOC COLVAR SUM_VECTOR
+      38             : /*
+      39             : Calculate the sum of the elements in a vector
+      40             : 
+      41             : \par Examples
+      42             : 
+      43             : */
+      44             : //+ENDPLUMEDOC
+      45             : 
+      46             : //+PLUMEDOC COLVAR SUM_SCALAR
+      47             : /*
+      48             : Calculate the SUM of the set of input scalars
+      49             : 
+      50             : \par Examples
+      51             : 
+      52             : */
+      53             : //+ENDPLUMEDOC
+      54             : 
+      55             : //+PLUMEDOC COLVAR MEAN
+      56             : /*
+      57             : Calculate the arithmetic mean of the elements in a vector
+      58             : 
+      59             : \par Examples
+      60             : 
+      61             : */
+      62             : //+ENDPLUMEDOC
+      63             : 
+      64             : //+PLUMEDOC COLVAR MEAN_SCALAR
+      65             : /*
+      66             : Calculate the arithmetic mean of the set of input scalars
+      67             : 
+      68             : \par Examples
+      69             : 
+      70             : */
+      71             : //+ENDPLUMEDOC
+      72             : 
+      73             : //+PLUMEDOC COLVAR MEAN_VECTOR
+      74             : /*
+      75             : Calculate the arithmetic mean of the elements in a vector
+      76             : 
+      77             : \par Examples
+      78             : 
+      79             : */
+      80             : //+ENDPLUMEDOC
+      81             : 
+      82             : 
+      83             : namespace PLMD {
+      84             : namespace function {
+      85             : 
+      86             : typedef FunctionShortcut<Sum> SumShortcut;
+      87             : PLUMED_REGISTER_ACTION(SumShortcut,"SUM")
+      88             : PLUMED_REGISTER_ACTION(SumShortcut,"MEAN")
+      89             : typedef FunctionOfScalar<Sum> ScalarSum;
+      90             : PLUMED_REGISTER_ACTION(ScalarSum,"SUM_SCALAR")
+      91             : PLUMED_REGISTER_ACTION(ScalarSum,"MEAN_SCALAR")
+      92             : typedef FunctionOfVector<Sum> VectorSum;
+      93             : PLUMED_REGISTER_ACTION(VectorSum,"SUM_VECTOR")
+      94             : PLUMED_REGISTER_ACTION(VectorSum,"MEAN_VECTOR")
+      95             : 
+      96        1731 : void Sum::registerKeywords( Keywords& keys ) {
+      97        1731 :   keys.use("PERIODIC");
+      98        1731 : }
+      99             : 
+     100         899 : void Sum::read( ActionWithArguments* action ) {
+     101         899 :   if( action->getNumberOfArguments()!=1 ) action->error("should only be one argument to sum actions");
+     102         899 : }
+     103             : 
+     104         989 : void Sum::setPrefactor( ActionWithArguments* action, const double pref ) {
+     105         989 :   if(action->getName().find("MEAN")!=std::string::npos) prefactor = pref / (action->getPntrToArgument(0))->getNumberOfValues();
+     106         813 :   else prefactor = pref;
+     107         989 : }
+     108             : 
+     109       25703 : bool Sum::zeroRank() const {
+     110       25703 :   return true;
+     111             : }
+     112             : 
+     113     1882990 : void Sum::calc( const ActionWithArguments* action, const std::vector<double>& args, std::vector<double>& vals, Matrix<double>& derivatives ) const {
+     114     1882990 :   vals[0]=prefactor*args[0]; derivatives(0,0)=prefactor;
+     115     1882990 : }
+     116             : 
+     117             : }
+     118             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Sum.h.func-sort-c.html b/coverage/function/Sum.h.func-sort-c.html new file mode 100644 index 000000000000..b1758cc62d4a --- /dev/null +++ b/coverage/function/Sum.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage - function/Sum.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - Sum.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-04-19 12:12:35Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Sum.h.func.html b/coverage/function/Sum.h.func.html new file mode 100644 index 000000000000..e17b0d74a10c --- /dev/null +++ b/coverage/function/Sum.h.func.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage - function/Sum.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - Sum.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-04-19 12:12:35Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Sum.h.gcov.html b/coverage/function/Sum.h.gcov.html new file mode 100644 index 000000000000..dccbcc34d2e0 --- /dev/null +++ b/coverage/function/Sum.h.gcov.html @@ -0,0 +1,120 @@ + + + + + + + + LCOV - plumed test coverage - function/Sum.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - Sum.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-04-19 12:12:35Functions: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_function_Sum_h
+      23             : #define __PLUMED_function_Sum_h
+      24             : 
+      25             : #include "FunctionTemplateBase.h"
+      26             : 
+      27             : namespace PLMD {
+      28             : namespace function {
+      29             : 
+      30        3439 : class Sum : public FunctionTemplateBase {
+      31             : private:
+      32             :   double prefactor;
+      33             : public:
+      34             :   void registerKeywords( Keywords& keys ) override;
+      35             :   void read( ActionWithArguments* action ) override;
+      36             :   bool zeroRank() const override;
+      37             :   void setPrefactor( ActionWithArguments* action, const double pref ) override;
+      38             :   void calc( const ActionWithArguments* action, const std::vector<double>& args, std::vector<double>& vals, Matrix<double>& derivatives ) const override;
+      39             : };
+      40             : 
+      41             : }
+      42             : }
+      43             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/index-sort-f.html b/coverage/function/index-sort-f.html new file mode 100644 index 000000000000..98123238d5e7 --- /dev/null +++ b/coverage/function/index-sort-f.html @@ -0,0 +1,374 @@ + + + + + + + + LCOV - plumed test coverage - function + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - functionHitTotalCoverage
Test:plumed test coverageLines:1305147688.4 %
Date:2024-04-19 12:12:35Functions:33539584.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
MoreThan.h +
50.0%50.0%
+
50.0 %1 / 20.0 %0 / 1
LessThan.h +
50.0%50.0%
+
50.0 %1 / 20.0 %0 / 1
Between.h +
50.0%50.0%
+
50.0 %1 / 20.0 %0 / 1
Highest.cpp +
94.4%94.4%
+
94.4 %17 / 1840.0 %2 / 5
FunctionTemplateBase.h +
82.2%82.2%
+
82.2 %37 / 4561.1 %11 / 18
Product.cpp +
100.0%
+
100.0 %13 / 1366.7 %2 / 3
Moments.cpp +
79.2%79.2%
+
79.2 %38 / 4871.4 %5 / 7
Sort.cpp +
92.6%92.6%
+
92.6 %25 / 2771.4 %5 / 7
FunctionOfScalar.h +
95.0%95.0%
+
95.0 %38 / 4072.9 %51 / 70
LocalEnsemble.cpp +
100.0%
+
100.0 %31 / 3175.0 %3 / 4
Stats.cpp +
96.1%96.1%
+
96.1 %99 / 10375.0 %3 / 4
Ensemble.cpp +
63.0%63.0%
+
63.0 %80 / 12775.0 %3 / 4
FuncPathMSD.cpp +
92.5%92.5%
+
92.5 %74 / 8080.0 %4 / 5
FuncPathGeneral.cpp +
77.5%77.5%
+
77.5 %100 / 12983.3 %5 / 6
Function.cpp +
100.0%
+
100.0 %22 / 2283.3 %5 / 6
Bessel.cpp +
94.3%94.3%
+
94.3 %33 / 3583.3 %5 / 6
FuncSumHills.cpp +
89.8%89.8%
+
89.8 %292 / 32583.3 %10 / 12
FunctionOfVector.h +
93.5%93.5%
+
93.5 %144 / 15491.2 %145 / 159
Combine.h +
100.0%
+
100.0 %1 / 1-0 / 0
Sum.h +
100.0%
+
100.0 %1 / 1-0 / 0
Between.cpp +
100.0%
+
100.0 %25 / 25100.0 %3 / 3
MoreThan.cpp +
85.7%85.7%
+
85.7 %24 / 28100.0 %3 / 3
LessThan.cpp +
85.7%85.7%
+
85.7 %24 / 28100.0 %3 / 3
Combine.cpp +
100.0%
+
100.0 %33 / 33100.0 %3 / 3
Function.h +
88.9%88.9%
+
88.9 %8 / 9100.0 %3 / 3
Piecewise.cpp +
100.0%
+
100.0 %36 / 36100.0 %4 / 4
Sum.cpp +
100.0%
+
100.0 %15 / 15100.0 %5 / 5
Custom.cpp +
100.0%
+
100.0 %64 / 64100.0 %6 / 6
FunctionShortcut.h +
84.8%84.8%
+
84.8 %28 / 33100.0 %46 / 46
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/index-sort-l.html b/coverage/function/index-sort-l.html new file mode 100644 index 000000000000..2fef48257ba0 --- /dev/null +++ b/coverage/function/index-sort-l.html @@ -0,0 +1,374 @@ + + + + + + + + LCOV - plumed test coverage - function + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - functionHitTotalCoverage
Test:plumed test coverageLines:1305147688.4 %
Date:2024-04-19 12:12:35Functions:33539584.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
MoreThan.h +
50.0%50.0%
+
50.0 %1 / 20.0 %0 / 1
LessThan.h +
50.0%50.0%
+
50.0 %1 / 20.0 %0 / 1
Between.h +
50.0%50.0%
+
50.0 %1 / 20.0 %0 / 1
Ensemble.cpp +
63.0%63.0%
+
63.0 %80 / 12775.0 %3 / 4
FuncPathGeneral.cpp +
77.5%77.5%
+
77.5 %100 / 12983.3 %5 / 6
Moments.cpp +
79.2%79.2%
+
79.2 %38 / 4871.4 %5 / 7
FunctionTemplateBase.h +
82.2%82.2%
+
82.2 %37 / 4561.1 %11 / 18
FunctionShortcut.h +
84.8%84.8%
+
84.8 %28 / 33100.0 %46 / 46
MoreThan.cpp +
85.7%85.7%
+
85.7 %24 / 28100.0 %3 / 3
LessThan.cpp +
85.7%85.7%
+
85.7 %24 / 28100.0 %3 / 3
Function.h +
88.9%88.9%
+
88.9 %8 / 9100.0 %3 / 3
FuncSumHills.cpp +
89.8%89.8%
+
89.8 %292 / 32583.3 %10 / 12
Sort.cpp +
92.6%92.6%
+
92.6 %25 / 2771.4 %5 / 7
FuncPathMSD.cpp +
92.5%92.5%
+
92.5 %74 / 8080.0 %4 / 5
FunctionOfVector.h +
93.5%93.5%
+
93.5 %144 / 15491.2 %145 / 159
Bessel.cpp +
94.3%94.3%
+
94.3 %33 / 3583.3 %5 / 6
Highest.cpp +
94.4%94.4%
+
94.4 %17 / 1840.0 %2 / 5
FunctionOfScalar.h +
95.0%95.0%
+
95.0 %38 / 4072.9 %51 / 70
Stats.cpp +
96.1%96.1%
+
96.1 %99 / 10375.0 %3 / 4
Combine.h +
100.0%
+
100.0 %1 / 1-0 / 0
Sum.h +
100.0%
+
100.0 %1 / 1-0 / 0
Product.cpp +
100.0%
+
100.0 %13 / 1366.7 %2 / 3
Sum.cpp +
100.0%
+
100.0 %15 / 15100.0 %5 / 5
Function.cpp +
100.0%
+
100.0 %22 / 2283.3 %5 / 6
Between.cpp +
100.0%
+
100.0 %25 / 25100.0 %3 / 3
LocalEnsemble.cpp +
100.0%
+
100.0 %31 / 3175.0 %3 / 4
Combine.cpp +
100.0%
+
100.0 %33 / 33100.0 %3 / 3
Piecewise.cpp +
100.0%
+
100.0 %36 / 36100.0 %4 / 4
Custom.cpp +
100.0%
+
100.0 %64 / 64100.0 %6 / 6
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/index.html b/coverage/function/index.html new file mode 100644 index 000000000000..70502304011e --- /dev/null +++ b/coverage/function/index.html @@ -0,0 +1,374 @@ + + + + + + + + LCOV - plumed test coverage - function + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - functionHitTotalCoverage
Test:plumed test coverageLines:1305147688.4 %
Date:2024-04-19 12:12:35Functions:33539584.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Bessel.cpp +
94.3%94.3%
+
94.3 %33 / 3583.3 %5 / 6
Between.cpp +
100.0%
+
100.0 %25 / 25100.0 %3 / 3
Between.h +
50.0%50.0%
+
50.0 %1 / 20.0 %0 / 1
Combine.cpp +
100.0%
+
100.0 %33 / 33100.0 %3 / 3
Combine.h +
100.0%
+
100.0 %1 / 1-0 / 0
Custom.cpp +
100.0%
+
100.0 %64 / 64100.0 %6 / 6
Ensemble.cpp +
63.0%63.0%
+
63.0 %80 / 12775.0 %3 / 4
FuncPathGeneral.cpp +
77.5%77.5%
+
77.5 %100 / 12983.3 %5 / 6
FuncPathMSD.cpp +
92.5%92.5%
+
92.5 %74 / 8080.0 %4 / 5
FuncSumHills.cpp +
89.8%89.8%
+
89.8 %292 / 32583.3 %10 / 12
Function.cpp +
100.0%
+
100.0 %22 / 2283.3 %5 / 6
Function.h +
88.9%88.9%
+
88.9 %8 / 9100.0 %3 / 3
FunctionOfScalar.h +
95.0%95.0%
+
95.0 %38 / 4072.9 %51 / 70
FunctionOfVector.h +
93.5%93.5%
+
93.5 %144 / 15491.2 %145 / 159
FunctionShortcut.h +
84.8%84.8%
+
84.8 %28 / 33100.0 %46 / 46
FunctionTemplateBase.h +
82.2%82.2%
+
82.2 %37 / 4561.1 %11 / 18
Highest.cpp +
94.4%94.4%
+
94.4 %17 / 1840.0 %2 / 5
LessThan.cpp +
85.7%85.7%
+
85.7 %24 / 28100.0 %3 / 3
LessThan.h +
50.0%50.0%
+
50.0 %1 / 20.0 %0 / 1
LocalEnsemble.cpp +
100.0%
+
100.0 %31 / 3175.0 %3 / 4
Moments.cpp +
79.2%79.2%
+
79.2 %38 / 4871.4 %5 / 7
MoreThan.cpp +
85.7%85.7%
+
85.7 %24 / 28100.0 %3 / 3
MoreThan.h +
50.0%50.0%
+
50.0 %1 / 20.0 %0 / 1
Piecewise.cpp +
100.0%
+
100.0 %36 / 36100.0 %4 / 4
Product.cpp +
100.0%
+
100.0 %13 / 1366.7 %2 / 3
Sort.cpp +
92.6%92.6%
+
92.6 %25 / 2771.4 %5 / 7
Stats.cpp +
96.1%96.1%
+
96.1 %99 / 10375.0 %3 / 4
Sum.cpp +
100.0%
+
100.0 %15 / 15100.0 %5 / 5
Sum.h +
100.0%
+
100.0 %1 / 1-0 / 0
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/funnel/FPS.cpp.func-sort-c.html b/coverage/funnel/FPS.cpp.func-sort-c.html new file mode 100644 index 000000000000..2610bb8aa260 --- /dev/null +++ b/coverage/funnel/FPS.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - funnel/FPS.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - funnel - FPS.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:959996.0 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6funnel9FUNNEL_PSC2ERKNS_13ActionOptionsE0
_ZN4PLMD6funnel9FUNNEL_PSC1ERKNS_13ActionOptionsE5
_ZN4PLMD6funnel9FUNNEL_PS16registerKeywordsERNS_8KeywordsE7
_ZN4PLMD6funnel9FUNNEL_PS9calculateEv150
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/funnel/FPS.cpp.func.html b/coverage/funnel/FPS.cpp.func.html new file mode 100644 index 000000000000..2a3dc3894b58 --- /dev/null +++ b/coverage/funnel/FPS.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - funnel/FPS.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - funnel - FPS.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:959996.0 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6funnel9FUNNEL_PS16registerKeywordsERNS_8KeywordsE7
_ZN4PLMD6funnel9FUNNEL_PS9calculateEv150
_ZN4PLMD6funnel9FUNNEL_PSC1ERKNS_13ActionOptionsE5
_ZN4PLMD6funnel9FUNNEL_PSC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/funnel/FPS.cpp.gcov.html b/coverage/funnel/FPS.cpp.gcov.html new file mode 100644 index 000000000000..e950cad98320 --- /dev/null +++ b/coverage/funnel/FPS.cpp.gcov.html @@ -0,0 +1,396 @@ + + + + + + + + LCOV - plumed test coverage - funnel/FPS.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - funnel - FPS.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:959996.0 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6funnel6FunnelC2ERKNS_13ActionOptionsE0
_ZN4PLMD6funnel6Funnel10createBIASERKdS3_S3_S3_S3_S3_S3_S3_S3_RKbS3_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESD_3
_ZN4PLMD6funnel6FunnelC1ERKNS_13ActionOptionsE4
_ZN4PLMD6funnel6Funnel16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD6funnel6Funnel9calculateEv120
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/funnel/Funnel.cpp.func.html b/coverage/funnel/Funnel.cpp.func.html new file mode 100644 index 000000000000..7b8e2d3e13a8 --- /dev/null +++ b/coverage/funnel/Funnel.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - funnel/Funnel.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - funnel - Funnel.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:15215399.3 %
Date:2024-04-19 12:12:35Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6funnel6Funnel10createBIASERKdS3_S3_S3_S3_S3_S3_S3_S3_RKbS3_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESD_3
_ZN4PLMD6funnel6Funnel16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD6funnel6Funnel9calculateEv120
_ZN4PLMD6funnel6FunnelC1ERKNS_13ActionOptionsE4
_ZN4PLMD6funnel6FunnelC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/funnel/Funnel.cpp.gcov.html b/coverage/funnel/Funnel.cpp.gcov.html new file mode 100644 index 000000000000..68edce593988 --- /dev/null +++ b/coverage/funnel/Funnel.cpp.gcov.html @@ -0,0 +1,529 @@ + + + + + + + + LCOV - plumed test coverage - funnel/Funnel.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - funnel - Funnel.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:15215399.3 %
Date:2024-04-19 12:12:35Functions:4580.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2019-2020
+       3             : 
+       4             :    This file is part of funnel code module.
+       5             : 
+       6             :    The FM code respects the CC BY-NC license.
+       7             :    Users are free to download, adapt and use the code as long as it is not for commercial purposes.
+       8             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+       9             : #include "bias/Bias.h"
+      10             : #include "core/ActionRegister.h"
+      11             : #include "tools/Grid.h"
+      12             : #include "tools/Exception.h"
+      13             : #include "tools/File.h"
+      14             : #include <cstring>
+      15             : #include "tools/Communicator.h"
+      16             : #include "core/ActionSet.h"
+      17             : #include "tools/FileBase.h"
+      18             : #include <memory>
+      19             : #include "core/PlumedMain.h"
+      20             : 
+      21             : using namespace std;
+      22             : using namespace PLMD::bias;
+      23             : 
+      24             : 
+      25             : namespace PLMD {
+      26             : namespace funnel {
+      27             : 
+      28             : //+PLUMEDOC FUNNELMOD_BIAS FUNNEL
+      29             : /*
+      30             : Calculate a funnel-shape restraint potential that is defined on a grid that is read during the setup.
+      31             : 
+      32             : If the input file is not already present, it will create one with the name specified in the FILE flag.
+      33             : The potential has a two-dimensional resolution since it has been devised to be used with the two
+      34             : components of \ref FUNNEL_PS (i.e., fps.lp and fps.ld) and it is divided in two sections, a cone shape
+      35             : attached to a cylindrical one. The user can customize the shape of both the sections by modifying a
+      36             : number of flags. In particular the cone section of the funnel is calculated with the following formula:
+      37             : 
+      38             : \f[
+      39             : MAX_Z=R_{cyl} + tg_{alpha} * (z_{cc} - MIN_S)
+      40             : \f]
+      41             : 
+      42             : where  \f$ MAX_Z \f$ is the radius of the cone base,  \f$ R_{cyl} \f$ is the radius of the cylinder part,
+      43             : \f$ tg_{alpha} \f$ is the angle regulating how steep the cone is, \f$ z_{cc} \f$ is the switching point
+      44             : between cone and cylinder, and \f$ MIN_S \f$ is the lowest possible value assumed by fps.lp of \ref FUNNEL_PS.
+      45             : As for the cylinder, it starts from the value of \f$ z_{cc} \f$ and stops at the value of \f$ MAX_S \f$
+      46             : with a section of \f$ pi*r_{cyl}^2 \f$.
+      47             : 
+      48             : There is the option of transforming the cone region into a sphere with the use of the SPHERE flag. In this
+      49             : case, the new shape will have a radius of \f$ z_{cc} \f$. It might be necessary tuning the SAFETY option
+      50             : to select how much the potential extends from the sphere.
+      51             : 
+      52             : \par Examples
+      53             : 
+      54             : The following is an input for a calculation with a funnel potential that is defined in the file BIAS
+      55             : and that acts on the collective variables defined by FUNNEL_PS.
+      56             : \plumedfile
+      57             : lig: COM ATOMS=3221,3224,3225,3228,3229,3231,3233,3235,3237
+      58             : fps: FUNNEL_PS LIGAND=lig REFERENCE=start.pdb ANCHOR=2472 POINTS=4.724,5.369,4.069,4.597,5.721,4.343
+      59             : 
+      60             : FUNNEL ARG=fps.lp,fps.ld ZCC=1.8 ALPHA=0.55 RCYL=0.1 MINS=-0.5 MAXS=3.7 KAPPA=35100 NBINS=500 NBINZ=500 FILE=BIAS LABEL=funnel
+      61             : \endplumedfile
+      62             : 
+      63             : The BIAS will then look something like this:
+      64             : \auxfile{BIAS}
+      65             : #! FIELDS fps.lp fps.ld funnel.bias der_fps.lp der_fps.ld
+      66             : #! SET min_fps.lp -0.500000
+      67             : #! SET max_fps.lp 3.700000
+      68             : #! SET nbins_fps.lp 500.000000
+      69             : #! SET periodic_fps.lp false
+      70             : #! SET min_fps.ld 0.000000
+      71             : #! SET max_fps.ld 1.510142
+      72             : #! SET nbins_fps.ld 500.000000
+      73             : #! SET periodic_fps.ld false
+      74             :     -0.500000      0.000000      0.000000      0.000000      0.000000
+      75             :     -0.500000      0.003020      0.000000      0.000000      0.000000
+      76             :     -0.500000      0.006041      0.000000      0.000000      0.000000
+      77             :     -0.500000      0.009061      0.000000      0.000000      0.000000
+      78             :     -0.500000      0.012081      0.000000      0.000000      0.000000
+      79             :     -0.500000      0.015101      0.000000      0.000000      0.000000
+      80             : \endauxfile
+      81             : 
+      82             : The Funnel potential should always be used in combination with the collective variable  \ref FUNNEL_PS, since it
+      83             : is constructed to take as inputs fps.lp and fps.ld (the former linepos and linedist of Funnel-Metadynamics
+      84             : \cite FM).  In the first block of data the value of fps.lp (the value in the first column) is kept fixed
+      85             : and the value of the function is given at 500 equally spaced values for fps.ld between 0 and 1.51. In
+      86             : the second block of data fps.lp is fixed at \f$-0.5 + \frac{4.2}{500}\f$ and the value of the function
+      87             : is given at 500 equally spaced values for fps.ld between 0 and 1.51. In the third block of data the same
+      88             : is done but fps.lp is fixed at \f$-0.5 + \frac{8.4}{100}\f$ and so on until you get to the five hundredth
+      89             : block of data where fps.lp is fixed at \f$3.7\f$.
+      90             : 
+      91             : It is possible to switch the shape of the cone region, transforming it in a sphere, with the flag SPHERE.
+      92             : \plumedfile
+      93             : lig: COM ATOMS=545,546,547,548,549,550,551,552,553
+      94             : fps: FUNNEL_PS LIGAND=lig REFERENCE=ref.pdb ANCHOR=52 POINTS=2.793,3.696,3.942,3.607,4.298,3.452
+      95             : 
+      96             : FUNNEL ARG=fps.lp,fps.ld ZCC=4.0 RCYL=0.1 MINS=0.2 MAXS=4.9 KAPPA=100000 NBINS=500 NBINZ=500 SPHERE SAFETY=1.0 FILE=BIAS LABEL=funnel
+      97             : \endplumedfile
+      98             : 
+      99             : */
+     100             : //+ENDPLUMEDOC
+     101             : class Funnel : public Bias {
+     102             : 
+     103             : private:
+     104             :   std::unique_ptr<GridBase> BiasGrid_;
+     105             : 
+     106             :   /////////////////////
+     107             :   // old 2.3
+     108             :   //Grid* BiasGrid_;
+     109             :   /////////////////////
+     110             :   //Optional parameters
+     111             :   double NBINS;
+     112             :   double NBINZ;
+     113             :   double MINS;
+     114             :   double KAPPA;
+     115             :   double RCYL;
+     116             :   double safety;
+     117             :   double slope;
+     118             :   double ALPHA;
+     119             :   //Compulsory parameters
+     120             :   double MAXS;
+     121             :   double ZCC;
+     122             :   double scale_;
+     123             : 
+     124             : 
+     125             : public:
+     126             :   explicit Funnel(const ActionOptions&);
+     127             : 
+     128             :   // old Funnel-2.3
+     129             :   // ~Funnel();
+     130             : 
+     131             :   void calculate();
+     132             :   static void registerKeywords(Keywords& keys);
+     133             :   void createBIAS(const double& R_cyl, const double& z_cc, const double& alpha, const double& KAPPA,
+     134             :                   const double& MIN_S, const double& MAX_S, const double& NBIN_S, const double& NBIN_Z,
+     135             :                   const double& safety, const bool& sphere, const double& slope, const string& funcl,
+     136             :                   const string& file);
+     137             : //  void createBIAS3D(const double& R_cyl, const double& z_cc, const double& alpha,
+     138             : //                      const double& KAPPA, const double& MIN_S, const double& MAX_S, const double& NBIN_S,
+     139             : //                      const double& NBIN_Z, const double& safety, const bool& sphere, const double& slope,
+     140             : //                      const string& funcl);
+     141             : };
+     142             : 
+     143             : PLUMED_REGISTER_ACTION(Funnel,"FUNNEL")
+     144             : 
+     145           6 : void Funnel::registerKeywords(Keywords& keys) {
+     146           6 :   Bias::registerKeywords(keys);
+     147           6 :   keys.use("ARG");
+     148          12 :   keys.addFlag("NOSPLINE",false,"specifies that no spline interpolation is to be used when calculating the energy and forces due to the external potential");
+     149          12 :   keys.addFlag("SPARSE",false,"specifies that the external potential uses a sparse grid");
+     150          12 :   keys.addFlag("SPHERE",false, "The Funnel potential including the binding site can be spherical instead of a cone");
+     151          12 :   keys.add("compulsory","SCALE","1.0","a factor that multiplies the external potential, useful to invert free energies");
+     152             : // old stuff?
+     153             :   //  componentsAreNotOptional(keys);
+     154             :   //  keys.addOutputComponent("bias","default","the instantaneous value of the bias potential");
+     155             : 
+     156             :   //Defining optional arguments
+     157          12 :   keys.add("optional","NBINS","number of bins along fps.lp");
+     158          12 :   keys.add("optional","NBINZ","number of bins along fps.ld");
+     159          12 :   keys.add("optional","MINS","minimum value assumed by fps.lp, if the ligand is able to go beyond this value the simulation will crash");
+     160          12 :   keys.add("optional","KAPPA","constant to be used for the funnel-shape restraint potential");
+     161          12 :   keys.add("optional","RCYL","radius of the cylindrical section");
+     162          12 :   keys.add("optional","SAFETY","To be used in case the SPHERE flag is chosen, it regulates how much the potential extends (in nm)");
+     163          12 :   keys.add("optional","SLOPE","Adjust the behavior of the potential outside the funnel, greater values than 1.0 will tend to push the ligand more towards the cylinder and vice versa");
+     164          12 :   keys.add("optional","ALPHA","angle to change the width of the cone section");
+     165             :   //Defining compulsory arguments
+     166          12 :   keys.add("compulsory","MAXS","MAXS","maximum value assumed by fps.lp");
+     167          12 :   keys.add("compulsory","ZCC","ZCC","switching point between cylinder and cone");
+     168          12 :   keys.add("compulsory","FILE","name of the Funnel potential file");
+     169          12 :   keys.addFlag("WALKERS_MPI",false,"To be used when gromacs + multiple walkers are used");
+     170           6 : }
+     171             : 
+     172             : // Old version 2.3
+     173             : //Funnel::~Funnel(){
+     174             : //  delete BiasGrid_;
+     175             : //}
+     176             : 
+     177           4 : Funnel::Funnel(const ActionOptions& ao):
+     178             :   PLUMED_BIAS_INIT(ao),
+     179             : // Old version 2.3
+     180             : // BiasGrid_(NULL),
+     181           4 :   NBINS(500.0),
+     182           4 :   NBINZ(500.0),
+     183           4 :   MINS(0.0),
+     184           4 :   KAPPA(84.0),
+     185           4 :   RCYL(0.1),
+     186           4 :   safety(1.0),
+     187           4 :   slope(1.0),
+     188           4 :   ALPHA(1.413)
+     189             : 
+     190             : {
+     191           4 :   bool sparsegrid=false;
+     192           4 :   parseFlag("SPARSE",sparsegrid);
+     193           4 :   bool nospline=false;
+     194           4 :   parseFlag("NOSPLINE",nospline);
+     195           4 :   bool spline=!nospline;
+     196           4 :   bool walkers_mpi=false;
+     197           4 :   parseFlag("WALKERS_MPI",walkers_mpi);
+     198             : //  bool components=false;
+     199             : //  parseFlag("POINTS",components);
+     200           4 :   bool sphere=false;
+     201           4 :   parseFlag("SPHERE",sphere);
+     202           8 :   parse("SAFETY",safety);
+     203             :   string file;
+     204           8 :   parse("FILE",file);
+     205           4 :   if( file.length()==0 ) error("No funnel file name was specified");
+     206           4 :   parse("SCALE",scale_);
+     207             : 
+     208             :   //Reading optional arguments
+     209           4 :   parse("KAPPA",KAPPA);
+     210           4 :   parse("NBINS",NBINS);
+     211           4 :   parse("NBINZ",NBINZ);
+     212           4 :   parse("MINS",MINS);
+     213           4 :   parse("RCYL",RCYL);
+     214           4 :   parse("SLOPE",slope);
+     215           4 :   parse("ALPHA",ALPHA);
+     216             :   //Reading compulsory arguments
+     217           4 :   parse("MAXS",MAXS);
+     218           4 :   parse("ZCC",ZCC);
+     219             : 
+     220             : 
+     221           4 :   checkRead();
+     222             : 
+     223           4 :   log.printf("  External potential from file %s\n",file.c_str());
+     224           4 :   log.printf("  Multiplied by %lf\n",scale_);
+     225           4 :   if(spline) {
+     226           4 :     log.printf("  External potential uses spline interpolation\n");
+     227             :   }
+     228           4 :   if(sparsegrid) {
+     229           0 :     log.printf("  External potential uses sparse grid\n");
+     230             :   }
+     231             : 
+     232             :   // Non più necessario dalla 2.3
+     233             : //  addComponent("bias"); componentIsNotPeriodic("bias");
+     234             : 
+     235           4 :   std::string funcl=getLabel() + ".bias";
+     236             : 
+     237             : //  int size = plumed.comm.Get_size();
+     238             : //  int rank = plumed.comm.Get_rank();
+     239           4 :   IFile I_hate_this;
+     240           4 :   bool do_exist=I_hate_this.FileExist(file);
+     241             : 
+     242           4 :   if(walkers_mpi) {
+     243           2 :     if(comm.Get_rank()==0 && multi_sim_comm.Get_rank()==0) {
+     244           1 :       if(!do_exist) {
+     245           1 :         createBIAS(RCYL, ZCC, ALPHA, KAPPA, MINS, MAXS, NBINS, NBINZ, safety, sphere, slope, funcl, file);
+     246             :       }
+     247             :     }
+     248           2 :     multi_sim_comm.Barrier();
+     249             :   } else {
+     250           2 :     if(comm.Get_rank()==0) {
+     251           2 :       if(!do_exist) {
+     252           2 :         createBIAS(RCYL, ZCC, ALPHA, KAPPA, MINS, MAXS, NBINS, NBINZ, safety, sphere, slope, funcl, file);
+     253             :       }
+     254             :     }
+     255             :   }
+     256             : 
+     257             :   /*
+     258             :   if(comm.Get_rank()==0){
+     259             :     if(multi_sim_comm.Get_rank()==0 && walkers_mpi){
+     260             :           if(!do_exist){
+     261             :                   createBIAS(RCYL, ZCC, ALPHA, KAPPA, MINS, MAXS, NBINS, NBINZ, safety, sphere, slope, funcl, file);
+     262             :           }
+     263             :     } else {
+     264             :           if(!do_exist){
+     265             :                   createBIAS(RCYL, ZCC, ALPHA, KAPPA, MINS, MAXS, NBINS, NBINZ, safety, sphere, slope, funcl, file);
+     266             :           }
+     267             :     }
+     268             :     if(walkers_mpi) multi_sim_comm.Barrier();
+     269             :   }
+     270             :   */
+     271           4 :   comm.Barrier();
+     272             : 
+     273             : // read grid
+     274           4 :   IFile gridfile;
+     275           4 :   gridfile.open(file);
+     276           8 :   BiasGrid_=Grid::create(funcl,getArguments(),gridfile,sparsegrid,spline,true);
+     277             : //not necessary anymore?  gridfile.close();
+     278           4 :   if(BiasGrid_->getDimension()!=getNumberOfArguments()) error("mismatch between dimensionality of input grid and number of arguments");
+     279          12 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     280          16 :     if( getPntrToArgument(i)->isPeriodic()!=BiasGrid_->getIsPeriodic()[i] ) error("periodicity mismatch between arguments and input bias");
+     281             :   }
+     282           4 :   comm.Barrier();
+     283           4 :   if(comm.Get_rank()==0 && walkers_mpi) multi_sim_comm.Barrier();
+     284           8 :   log<<"  Bibliography "<<plumed.cite("Limongelli, Bonomi, and Parrinello, PNAS 110, 6358 (2013)")<<"\n";
+     285           8 : }
+     286             : 
+     287             : 
+     288           3 : void Funnel::createBIAS(const double& R_cyl, const double& z_cc, const double& alpha,
+     289             :                         const double& KAPPA, const double& MIN_S, const double& MAX_S, const double& NBIN_S,
+     290             :                         const double& NBIN_Z, const double& safety, const bool& sphere, const double& slope,
+     291             :                         const string& funcl, const string& file) {
+     292             :   //R_cyl and z_cc forms the parameters of the cylinder.
+     293             :   //alpha defines the angle in degrees.
+     294             : 
+     295             :   //PARAMETERS OF THE CONE
+     296           3 :   double tg_alpha= tan(alpha);
+     297             : 
+     298             :   //parameters for PROGRESSION
+     299             :   //parameters for DISTANCE
+     300             :   double MIN_Z=0;
+     301             :   double MAX_Z;
+     302           3 :   if (sphere==false) {
+     303           2 :     MAX_Z=R_cyl + tg_alpha * (z_cc - MIN_S);
+     304             :   }
+     305             :   else {
+     306           1 :     MAX_Z=z_cc+safety;
+     307             :   }
+     308             : 
+     309             :   //bin size
+     310           3 :   double DX_Z = (MAX_Z - MIN_Z) / NBIN_Z;
+     311             :   double DX_S;
+     312           3 :   if (sphere==false) {
+     313           2 :     DX_S=(MAX_S - MIN_S) / NBIN_S;
+     314             :   }
+     315             :   else {
+     316           1 :     DX_S=(MAX_S + z_cc + safety)/NBIN_S;
+     317             :   }
+     318             : 
+     319             :   double SS, Zmax, ZZ, D, d;
+     320             :   double POT, FZ, FS;
+     321             : 
+     322           3 :   PLMD::OFile pof;
+     323           3 :   pof.open(file);
+     324             : 
+     325             :   //Write the header
+     326           3 :   pof.printf("#! FIELDS %s %s %s der_%s der_%s \n", getPntrToArgument(0)->getName().c_str(), getPntrToArgument(1)->getName().c_str(), funcl.c_str(), getPntrToArgument(0)->getName().c_str(), getPntrToArgument(1)->getName().c_str());
+     327           3 :   if (sphere==false) pof.printf("#! SET min_%s %f\n", getPntrToArgument(0)->getName().c_str(), MIN_S);
+     328           1 :   else pof.printf("#! SET min_%s %f\n", getPntrToArgument(0)->getName().c_str(), -z_cc-safety);
+     329           3 :   pof.printf("#! SET max_%s %f\n", getPntrToArgument(0)->getName().c_str(), MAX_S);
+     330           3 :   pof.printf("#! SET nbins_%s %f\n", getPntrToArgument(0)->getName().c_str(), NBIN_S);
+     331           3 :   pof.printf("#! SET periodic_%s false\n", getPntrToArgument(0)->getName().c_str());
+     332           3 :   pof.printf("#! SET min_%s %f\n", getPntrToArgument(1)->getName().c_str(), MIN_Z);
+     333           3 :   pof.printf("#! SET max_%s %f\n", getPntrToArgument(1)->getName().c_str(), MAX_Z);
+     334           3 :   pof.printf("#! SET nbins_%s %f\n", getPntrToArgument(1)->getName().c_str(), NBIN_Z);
+     335           3 :   pof.printf("#! SET periodic_%s false\n", getPntrToArgument(1)->getName().c_str());
+     336             : 
+     337             :   //Calculate and write the GRID
+     338             :   //Cone or cylinder?
+     339             : 
+     340        1506 :   for(int is=0; is <= NBIN_S; is++) {
+     341        1503 :     if (sphere==false) {
+     342        1002 :       SS = MIN_S + is * DX_S;
+     343             :     }
+     344             :     else {
+     345         501 :       SS = - z_cc - safety + is * DX_S;
+     346             :     }
+     347             :     bool cone = false;
+     348        1503 :     if (sphere==false) {
+     349        1002 :       if(SS <= z_cc) cone = true;
+     350             :     }
+     351             :     else {
+     352         501 :       if (SS <= sqrt(pow(z_cc,2)-pow(R_cyl,2))) cone = true;
+     353             :     }
+     354             :     //Set wall boundaries properly
+     355             :     if(cone == true) {
+     356         902 :       if(sphere==false) {
+     357         548 :         Zmax = R_cyl + (z_cc - SS) * tg_alpha;
+     358             :       }
+     359             :       else {
+     360         354 :         if (SS > -z_cc) {
+     361         277 :           Zmax = sqrt(pow(z_cc,2) - pow(SS,2));
+     362             :         }
+     363             :         else {
+     364             :           Zmax = 0;
+     365             :         }
+     366             :       }
+     367             :     }
+     368         601 :     else Zmax = R_cyl;
+     369             : 
+     370      754506 :     for(int iz=0; iz <= NBIN_Z; iz++) {
+     371      753003 :       ZZ = MIN_Z + iz * DX_Z;
+     372             : 
+     373             :       //Inside or outside?
+     374             :       bool inside;
+     375      753003 :       if(ZZ < Zmax) inside = true;
+     376             :       else inside = false;
+     377             : 
+     378             :       if(inside == true) {
+     379             :         POT = 0;
+     380             :         FS = 0;
+     381             :         FZ = 0;
+     382             :       }
+     383             :       else {
+     384      518149 :         if(cone == true) {
+     385      235130 :           if(sphere==false) {
+     386      127824 :             POT = 0.5 * KAPPA * (ZZ - Zmax) * (ZZ - Zmax);
+     387      127824 :             FZ = - KAPPA * (ZZ - Zmax);
+     388      127824 :             FS = - KAPPA * (ZZ - Zmax) * tg_alpha;
+     389             :           }
+     390             :           else {
+     391      107306 :             D = sqrt(pow(ZZ,2)+pow(SS,2));
+     392      107306 :             d = D - z_cc;
+     393      107306 :             POT = 0.5 * KAPPA * pow(d,2);
+     394      107306 :             FZ = - KAPPA * d * ZZ / D;
+     395      107306 :             FS = - KAPPA * d * SS / D;
+     396             :           }
+     397             :         }
+     398             :         else {
+     399      283019 :           if(sphere==false) {
+     400      212018 :             POT = 0.5 * KAPPA * (ZZ - Zmax) * (ZZ - Zmax);
+     401      212018 :             FZ = - KAPPA * (ZZ - Zmax);
+     402             :             FS = 0;
+     403             :           }
+     404             :           else {
+     405       71001 :             D = sqrt(pow(ZZ,2)+pow(SS,2));
+     406       71001 :             d = D - z_cc;
+     407       71001 :             if(ZZ>=R_cyl+slope*(SS-z_cc)) {
+     408       45984 :               POT = 0.5 * KAPPA * pow(d,2);
+     409       45984 :               FZ = - KAPPA * d * ZZ / D;
+     410       45984 :               FS = - KAPPA * d * SS / D;
+     411             :             }
+     412             :             else {
+     413       25017 :               POT = 0.5 * KAPPA * pow(sqrt(pow((ZZ+slope*z_cc-R_cyl)/slope,2)+pow(ZZ,2))-
+     414             :                                       z_cc,2);
+     415       25017 :               FZ = - KAPPA*(sqrt(pow((ZZ+slope*z_cc-R_cyl)/slope,2)+pow(ZZ,2))-z_cc)*
+     416       25017 :                    ZZ/sqrt(pow((ZZ+slope*z_cc-R_cyl)/slope,2)+pow(ZZ,2));
+     417             :               FS = 0;
+     418             :             }
+     419             :           }
+     420             :         }
+     421             :       }
+     422      753003 :       pof.printf("%13.6lf %13.6lf %13.6lf %13.6lf %13.6lf\n", SS, ZZ, POT, FS, FZ);
+     423             :     }
+     424        1503 :     pof.printf("\n");
+     425             :   }
+     426           3 :   pof.close();
+     427           3 : }
+     428             : 
+     429         120 : void Funnel::calculate()
+     430             : {
+     431         120 :   unsigned ncv=getNumberOfArguments();
+     432         120 :   vector<double> cv(ncv), der(ncv);
+     433             : 
+     434         360 :   for(unsigned i=0; i<ncv; ++i) {
+     435         240 :     cv[i]=getArgument(i);
+     436             :   }
+     437             : 
+     438             : //  log.printf("  In Funnel: %13.6lf  %13.6lf\n", cv[0], cv[1]);
+     439             : 
+     440         120 :   double ene=scale_*BiasGrid_->getValueAndDerivatives(cv,der);
+     441             : 
+     442         120 :   setBias(ene);
+     443             : 
+     444             : // set Forces
+     445         360 :   for(unsigned i=0; i<ncv; ++i) {
+     446         240 :     const double f=-scale_*der[i];
+     447         240 :     setOutputForce(i,f);
+     448             :   }
+     449         120 : }
+     450             : 
+     451             : }
+     452             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/funnel/index-sort-f.html b/coverage/funnel/index-sort-f.html new file mode 100644 index 000000000000..c9c0e8776146 --- /dev/null +++ b/coverage/funnel/index-sort-f.html @@ -0,0 +1,104 @@ + + + + + + + + LCOV - plumed test coverage - funnel + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - funnelHitTotalCoverage
Test:plumed test coverageLines:24725298.0 %
Date:2024-04-19 12:12:35Functions:7977.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
FPS.cpp +
96.0%96.0%
+
96.0 %95 / 9975.0 %3 / 4
Funnel.cpp +
99.3%99.3%
+
99.3 %152 / 15380.0 %4 / 5
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/funnel/index-sort-l.html b/coverage/funnel/index-sort-l.html new file mode 100644 index 000000000000..aadf97be35af --- /dev/null +++ b/coverage/funnel/index-sort-l.html @@ -0,0 +1,104 @@ + + + + + + + + LCOV - plumed test coverage - funnel + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - funnelHitTotalCoverage
Test:plumed test coverageLines:24725298.0 %
Date:2024-04-19 12:12:35Functions:7977.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
FPS.cpp +
96.0%96.0%
+
96.0 %95 / 9975.0 %3 / 4
Funnel.cpp +
99.3%99.3%
+
99.3 %152 / 15380.0 %4 / 5
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/funnel/index.html b/coverage/funnel/index.html new file mode 100644 index 000000000000..3f96ab5c749f --- /dev/null +++ b/coverage/funnel/index.html @@ -0,0 +1,104 @@ + + + + + + + + LCOV - plumed test coverage - funnel + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - funnelHitTotalCoverage
Test:plumed test coverageLines:24725298.0 %
Date:2024-04-19 12:12:35Functions:7977.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic8Constant16clearDerivativesERKb0
_ZN4PLMD7generic8Constant5applyEv0
_ZN4PLMD7generic8Constant9calculateEv0
_ZN4PLMD7generic8ConstantC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic8ConstantC1ERKNS_13ActionOptionsE842
_ZN4PLMD7generic8Constant16registerKeywordsERNS_8KeywordsE844
_ZN4PLMD7generic8Constant22getNumberOfDerivativesEv6041
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/Constant.cpp.func.html b/coverage/generic/Constant.cpp.func.html new file mode 100644 index 000000000000..9297d6c0032e --- /dev/null +++ b/coverage/generic/Constant.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - generic/Constant.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - Constant.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:586392.1 %
Date:2024-04-19 12:12:35Functions:3742.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic8Constant16clearDerivativesERKb0
_ZN4PLMD7generic8Constant16registerKeywordsERNS_8KeywordsE844
_ZN4PLMD7generic8Constant22getNumberOfDerivativesEv6041
_ZN4PLMD7generic8Constant5applyEv0
_ZN4PLMD7generic8Constant9calculateEv0
_ZN4PLMD7generic8ConstantC1ERKNS_13ActionOptionsE842
_ZN4PLMD7generic8ConstantC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/Constant.cpp.gcov.html b/coverage/generic/Constant.cpp.gcov.html new file mode 100644 index 000000000000..7912f23df42f --- /dev/null +++ b/coverage/generic/Constant.cpp.gcov.html @@ -0,0 +1,229 @@ + + + + + + + + LCOV - plumed test coverage - generic/Constant.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - Constant.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:586392.1 %
Date:2024-04-19 12:12:35Functions:3742.9 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2018 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received 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 "tools/IFile.h"
+      25             : 
+      26             : //+PLUMEDOC COLVAR CONSTANT
+      27             : /*
+      28             : Create a constant value that can be passed to actions
+      29             : 
+      30             : Useful in combination with functions that
+      31             : takes in input constants or parameters.
+      32             : 
+      33             : \par Examples
+      34             : 
+      35             : The following input instructs plumed to compute the distance
+      36             : between atoms 1 and 2. If this distance is between 1.0 and 2.0, it is
+      37             : printed. If it is lower than 1.0 (larger than 2.0), 1.0 (2.0) is printed
+      38             : 
+      39             : \plumedfile
+      40             : cn: CONSTANT VALUES=1.0,2.0
+      41             : dis: DISTANCE ATOMS=1,2
+      42             : sss: SORT ARG=cn.v-0,dis,cn.v-1
+      43             : PRINT ARG=sss.2
+      44             : \endplumedfile
+      45             : 
+      46             : In case you want to pass a single value you can use VALUE:
+      47             : \plumedfile
+      48             : cn: CONSTANT VALUE=1.0
+      49             : dis: DISTANCE ATOMS=1,2
+      50             : sss: SORT ARG=cn,dis
+      51             : PRINT ARG=sss.1
+      52             : \endplumedfile
+      53             : 
+      54             : */
+      55             : //+ENDPLUMEDOC
+      56             : 
+      57             : namespace PLMD {
+      58             : namespace generic {
+      59             : 
+      60             : class Constant : public ActionWithValue {
+      61             : public:
+      62             :   static void registerKeywords( Keywords& keys );
+      63             :   explicit Constant(const ActionOptions&ao);
+      64           0 :   void clearDerivatives( const bool& force=false ) {}
+      65        6041 :   unsigned getNumberOfDerivatives() override { return 0; }
+      66           0 :   void calculate() override {}
+      67           0 :   void apply() override {}
+      68             : };
+      69             : 
+      70             : PLUMED_REGISTER_ACTION(Constant,"CONSTANT")
+      71             : 
+      72         844 : void Constant::registerKeywords( Keywords& keys ) {
+      73         844 :   Action::registerKeywords(keys); ActionWithValue::registerKeywords(keys); keys.remove("NUMERICAL_DERIVATIVES");
+      74        1688 :   keys.add("optional","FILE","an input file containing the matrix");
+      75        1688 :   keys.add("compulsory","NROWS","0","the number of rows in your input matrix");
+      76        1688 :   keys.add("compulsory","NCOLS","0","the number of columns in your matrix");
+      77        1688 :   keys.add("optional","VALUE","the single number that you would like to store");
+      78        1688 :   keys.add("optional","VALUES","the numbers that are in your constant value");
+      79        1688 :   keys.addFlag("SCALARS",false,"treat the input list of numbers as a set of scalars");
+      80        1688 :   keys.addFlag("NOLOG",false,"do not report all the read in scalars in the log");
+      81        1688 :   keys.addOutputComponent("v","SCALARS","the # value");
+      82         844 : }
+      83             : 
+      84         842 : Constant::Constant(const ActionOptions&ao):
+      85             :   Action(ao),
+      86         842 :   ActionWithValue(ao)
+      87             : {
+      88         842 :   bool nolog=false; parseFlag("NOLOG",nolog);
+      89        1684 :   bool scalars=false; std::string fname, vname; parse("FILE",fname);
+      90             :   std::vector<unsigned> shape; std::vector<double> vals;
+      91         842 :   if( fname.length()>0 ) {
+      92           3 :     IFile mfile; mfile.open(fname);
+      93             :     // Read in first line
+      94             :     std::vector<std::string> words; unsigned nline=0;
+      95           6 :     while( nline==0 ) {
+      96           3 :       Tools::getParsedLine( mfile, words );
+      97           3 :       nline=words.size();
+      98             :     }
+      99             :     std::vector<std::vector<double> > dissimilarities;
+     100           3 :     if( nline==1 ) {
+     101           0 :       shape.resize(1);
+     102           0 :       error("invalid matrix in input file");
+     103             :     }
+     104           3 :     shape.resize(2); shape[1]=nline;
+     105           3 :     std::vector<double> tmpdis( shape[1] );
+     106          34 :     for(unsigned j=0; j<shape[1]; ++j) Tools::convert( words[j], tmpdis[j] );
+     107           3 :     dissimilarities.push_back( tmpdis );
+     108             : 
+     109          31 :     while( Tools::getParsedLine( mfile, words ) ) {
+     110          28 :       if( words.size()!=nline ) error("bad formatting in matrix file");
+     111         360 :       for(unsigned j=0; j<nline; ++j) Tools::convert( words[j], tmpdis[j] );
+     112          28 :       dissimilarities.push_back( tmpdis );
+     113             :     }
+     114           3 :     mfile.close(); shape[0] = dissimilarities.size(); vals.resize(shape[0]);
+     115           3 :     if( shape.size()==2 ) vals.resize( shape[0]*shape[1] );
+     116          34 :     for(unsigned i=0; i<shape[0]; ++i) {
+     117         394 :       for(unsigned j=0; j<nline; ++j) vals[i*nline+j] = dissimilarities[i][j];
+     118             :     }
+     119           3 :   } else {
+     120        1678 :     unsigned nr, nc; parse("NROWS",nr); parse("NCOLS",nc);
+     121         839 :     if( nr>0 && nc>0 ) {
+     122          73 :       shape.resize(2); shape[0]=nr; shape[1]=nc; vals.resize( nr*nc );
+     123          73 :       log.printf("  reading in %d by %d matrix \n", nr, nc );
+     124         766 :     } else if( nr>0 || nc>0 ) error("makes no sense to set only one of NROWS and NCOLS to a non-zero value");
+     125        2517 :     parseVector("VALUES",vals); parseFlag("SCALARS",scalars);
+     126         839 :     if( vals.size()==0 ) {
+     127         132 :       parseVector("VALUE",vals);
+     128          66 :       if( vals.size()!=1 ) error("VALUE keyword should take a single scalar");
+     129         773 :     } else if( vals.size()==1 ) scalars=false;
+     130             : 
+     131         839 :     log.printf("  read in %d values :", vals.size() );
+     132       26100 :     if( !nolog ) { for(unsigned i=0; i<vals.size(); ++i) log.printf(" %f", vals[i] ); }
+     133         839 :     log.printf("\n");
+     134         839 :     if( !scalars && shape.size()==0 && vals.size()>1 ) { shape.resize(1); shape[0] = vals.size(); }
+     135             :   }
+     136         842 :   if( !scalars ) {
+     137             :     // Now set the value
+     138         841 :     addValue( shape ); setNotPeriodic(); getPntrToComponent(0)->setConstant();
+     139      136417 :     for(unsigned i=0; i<vals.size(); ++i) getPntrToComponent(0)->set( i, vals[i] );
+     140             :   } else {
+     141           3 :     for(unsigned i=0; i<vals.size(); i++) {
+     142           2 :       std::string num; Tools::convert(i,num);
+     143           4 :       addComponent("v-"+num); componentIsNotPeriodic("v-"+num);
+     144           2 :       Value* comp=getPntrToComponent("v-"+num);
+     145           2 :       comp->setConstant(); comp->set(vals[i]);
+     146             :     }
+     147             :   }
+     148         842 : }
+     149             : 
+     150             : }
+     151             : }
+     152             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/Debug.cpp.func-sort-c.html b/coverage/generic/Debug.cpp.func-sort-c.html new file mode 100644 index 000000000000..5ff6c24f39b2 --- /dev/null +++ b/coverage/generic/Debug.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - generic/Debug.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - Debug.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:5656100.0 %
Date:2024-04-19 12:12:35Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic5DebugC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic5DebugC1ERKNS_13ActionOptionsE6
_ZN4PLMD7generic5Debug16registerKeywordsERNS_8KeywordsE8
_ZN4PLMD7generic5Debug5applyEv140
_ZN4PLMD7generic5Debug9calculateEv140
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/Debug.cpp.func.html b/coverage/generic/Debug.cpp.func.html new file mode 100644 index 000000000000..c329e4987f77 --- /dev/null +++ b/coverage/generic/Debug.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - generic/Debug.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - Debug.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:5656100.0 %
Date:2024-04-19 12:12:35Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic5Debug16registerKeywordsERNS_8KeywordsE8
_ZN4PLMD7generic5Debug5applyEv140
_ZN4PLMD7generic5Debug9calculateEv140
_ZN4PLMD7generic5DebugC1ERKNS_13ActionOptionsE6
_ZN4PLMD7generic5DebugC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/Debug.cpp.gcov.html b/coverage/generic/Debug.cpp.gcov.html new file mode 100644 index 000000000000..03798c4dcdc8 --- /dev/null +++ b/coverage/generic/Debug.cpp.gcov.html @@ -0,0 +1,217 @@ + + + + + + + + LCOV - plumed test coverage - generic/Debug.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - Debug.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:5656100.0 %
Date:2024-04-19 12:12:35Functions:4580.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionRegister.h"
+      23             : #include "core/ActionPilot.h"
+      24             : #include "core/ActionSet.h"
+      25             : #include "core/PlumedMain.h"
+      26             : 
+      27             : namespace PLMD {
+      28             : namespace generic {
+      29             : 
+      30             : //+PLUMEDOC GENERIC DEBUG
+      31             : /*
+      32             : Set some debug options.
+      33             : 
+      34             : Can be used while debugging or optimizing plumed.
+      35             : 
+      36             : \par Examples
+      37             : 
+      38             : \plumedfile
+      39             : # print detailed (action-by-action) timers at the end of simulation
+      40             : DEBUG DETAILED_TIMERS
+      41             : # dump every two steps which are the atoms required from the MD code
+      42             : DEBUG logRequestedAtoms STRIDE=2
+      43             : \endplumedfile
+      44             : 
+      45             : */
+      46             : //+ENDPLUMEDOC
+      47             : class Debug:
+      48             :   public ActionPilot
+      49             : {
+      50             :   OFile ofile;
+      51             :   bool logActivity;
+      52             :   bool logRequestedAtoms;
+      53             :   bool novirial;
+      54             :   bool detailedTimers;
+      55             : public:
+      56             :   explicit Debug(const ActionOptions&ao);
+      57             : /// Register all the relevant keywords for the action
+      58             :   static void registerKeywords( Keywords& keys );
+      59         140 :   void calculate() override {}
+      60             :   void apply() override;
+      61             : };
+      62             : 
+      63             : PLUMED_REGISTER_ACTION(Debug,"DEBUG")
+      64             : 
+      65           8 : void Debug::registerKeywords( Keywords& keys ) {
+      66           8 :   Action::registerKeywords( keys );
+      67           8 :   ActionPilot::registerKeywords(keys);
+      68          16 :   keys.add("compulsory","STRIDE","1","the frequency with which this action is to be performed");
+      69          16 :   keys.addFlag("logActivity",false,"write in the log which actions are inactive and which are inactive");
+      70          16 :   keys.addFlag("logRequestedAtoms",false,"write in the log which atoms have been requested at a given time");
+      71          16 :   keys.addFlag("NOVIRIAL",false,"switch off the virial contribution for the entirety of the simulation");
+      72          16 :   keys.addFlag("DETAILED_TIMERS",false,"switch on detailed timers");
+      73          16 :   keys.add("optional","FILE","the name of the file on which to output these quantities");
+      74           8 : }
+      75             : 
+      76           6 : Debug::Debug(const ActionOptions&ao):
+      77             :   Action(ao),
+      78             :   ActionPilot(ao),
+      79           6 :   logActivity(false),
+      80           6 :   logRequestedAtoms(false),
+      81           6 :   novirial(false) {
+      82           6 :   parseFlag("logActivity",logActivity);
+      83           6 :   if(logActivity) log.printf("  logging activity\n");
+      84           6 :   parseFlag("logRequestedAtoms",logRequestedAtoms);
+      85           6 :   if(logRequestedAtoms) log.printf("  logging requested atoms\n");
+      86           6 :   parseFlag("NOVIRIAL",novirial);
+      87           6 :   if(novirial) log.printf("  Switching off virial contribution\n");
+      88           6 :   if(novirial) plumed.novirial=true;
+      89           6 :   parseFlag("DETAILED_TIMERS",detailedTimers);
+      90           6 :   if(detailedTimers) {
+      91           2 :     log.printf("  Detailed timing on\n");
+      92           2 :     plumed.detailedTimers=true;
+      93             :   }
+      94           6 :   ofile.link(*this);
+      95             :   std::string file;
+      96          12 :   parse("FILE",file);
+      97           6 :   if(file.length()>0) {
+      98           2 :     ofile.open(file);
+      99           2 :     log.printf("  on file %s\n",file.c_str());
+     100             :   } else {
+     101           4 :     log.printf("  on plumed log file\n");
+     102           4 :     ofile.link(log);
+     103             :   }
+     104           6 :   checkRead();
+     105           6 : }
+     106             : 
+     107         140 : void Debug::apply() {
+     108         140 :   if(logActivity) {
+     109          10 :     const ActionSet&actionSet(plumed.getActionSet());
+     110             :     int a=0;
+     111         225 :     for(const auto & p : actionSet) {
+     112         215 :       if(dynamic_cast<Debug*>(p.get()))continue;
+     113         200 :       if(p->isActive()) a++;
+     114             :     };
+     115          10 :     if(a>0) {
+     116           9 :       ofile<<"activity at step "<<getStep()<<": ";
+     117         207 :       for(const auto & p : actionSet) {
+     118         198 :         if(dynamic_cast<Debug*>(p.get()))continue;
+     119         185 :         if(p->isActive()) ofile.printf("+");
+     120          64 :         else                 ofile.printf("-");
+     121             :       };
+     122           9 :       ofile.printf("\n");
+     123             :     };
+     124             :   };
+     125         140 :   if(logRequestedAtoms) {
+     126          17 :     ofile<<"requested atoms at step "<<getStep()<<": ";
+     127             :     const int* l;
+     128             :     int n;
+     129          17 :     plumed.cmd("createFullList",&n);
+     130          17 :     plumed.cmd("getFullList",&l);
+     131         213 :     for(int i=0; i<n; i++) ofile.printf(" %d",l[i]);
+     132          17 :     ofile.printf("\n");
+     133          17 :     plumed.cmd("clearFullList");
+     134             :   }
+     135             : 
+     136         140 : }
+     137             : 
+     138             : }
+     139             : }
+     140             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/DumpAtoms.cpp.func-sort-c.html b/coverage/generic/DumpAtoms.cpp.func-sort-c.html new file mode 100644 index 000000000000..c11d256524c5 --- /dev/null +++ b/coverage/generic/DumpAtoms.cpp.func-sort-c.html @@ -0,0 +1,125 @@ + + + + + + + + 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:14214697.3 %
Date:2024-04-19 12:12:35Functions:101376.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic9DumpAtoms29calculateNumericalDerivativesEPNS_15ActionWithValueE0
_ZN4PLMD7generic9DumpAtomsC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic9DumpAtomsD2Ev0
_ZN4PLMD7generic9DumpAtoms15actionHasForcesEv62
_ZN4PLMD7generic9DumpAtomsC1ERKNS_13ActionOptionsE205
_ZN4PLMD7generic9DumpAtomsD0Ev205
_ZN4PLMD7generic9DumpAtomsD1Ev205
_ZN4PLMD7generic9DumpAtoms16registerKeywordsERNS_8KeywordsE207
_ZN4PLMD7generic9DumpAtoms6updateEv8851
_ZN4PLMD7generic9DumpAtoms12lockRequestsEv8946
_ZN4PLMD7generic9DumpAtoms14unlockRequestsEv8946
_ZN4PLMD7generic9DumpAtoms5applyEv8946
_ZN4PLMD7generic9DumpAtoms9calculateEv8946
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/DumpAtoms.cpp.func.html b/coverage/generic/DumpAtoms.cpp.func.html new file mode 100644 index 000000000000..0562432e8aa9 --- /dev/null +++ b/coverage/generic/DumpAtoms.cpp.func.html @@ -0,0 +1,125 @@ + + + + + + + + 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:14214697.3 %
Date:2024-04-19 12:12:35Functions:101376.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic9DumpAtoms12lockRequestsEv8946
_ZN4PLMD7generic9DumpAtoms14unlockRequestsEv8946
_ZN4PLMD7generic9DumpAtoms15actionHasForcesEv62
_ZN4PLMD7generic9DumpAtoms16registerKeywordsERNS_8KeywordsE207
_ZN4PLMD7generic9DumpAtoms29calculateNumericalDerivativesEPNS_15ActionWithValueE0
_ZN4PLMD7generic9DumpAtoms5applyEv8946
_ZN4PLMD7generic9DumpAtoms6updateEv8851
_ZN4PLMD7generic9DumpAtoms9calculateEv8946
_ZN4PLMD7generic9DumpAtomsC1ERKNS_13ActionOptionsE205
_ZN4PLMD7generic9DumpAtomsC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic9DumpAtomsD0Ev205
_ZN4PLMD7generic9DumpAtomsD1Ev205
_ZN4PLMD7generic9DumpAtomsD2Ev0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/DumpAtoms.cpp.gcov.html b/coverage/generic/DumpAtoms.cpp.gcov.html new file mode 100644 index 000000000000..27f99d5a1f56 --- /dev/null +++ b/coverage/generic/DumpAtoms.cpp.gcov.html @@ -0,0 +1,439 @@ + + + + + + + + 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:14214697.3 %
Date:2024-04-19 12:12:35Functions:101376.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 "core/ActionAtomistic.h"
+      23             : #include "core/ActionWithArguments.h"
+      24             : #include "core/ActionPilot.h"
+      25             : #include "core/ActionRegister.h"
+      26             : #include "tools/Pbc.h"
+      27             : #include "tools/File.h"
+      28             : #include "core/PlumedMain.h"
+      29             : #include "tools/Units.h"
+      30             : #include "tools/CheckInRange.h"
+      31             : #include <cstdio>
+      32             : #include <memory>
+      33             : #include "core/GenericMolInfo.h"
+      34             : #include "core/ActionSet.h"
+      35             : #include "xdrfile/xdrfile_xtc.h"
+      36             : #include "xdrfile/xdrfile_trr.h"
+      37             : 
+      38             : 
+      39             : namespace PLMD {
+      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 ActionWithArguments,
+     122             :   public ActionPilot
+     123             : {
+     124             :   OFile of;
+     125             :   double lenunit;
+     126             :   int iprecision;
+     127             :   CheckInRange bounds;
+     128             :   std::vector<std::string> names;
+     129             :   std::vector<unsigned>    residueNumbers;
+     130             :   std::vector<std::string> residueNames;
+     131             :   std::string type;
+     132             :   std::string fmt_gro_pos;
+     133             :   std::string fmt_gro_box;
+     134             :   std::string fmt_xyz;
+     135             :   xdrfile::XDRFILE* xd;
+     136             : public:
+     137             :   explicit DumpAtoms(const ActionOptions&);
+     138             :   ~DumpAtoms();
+     139             :   static void registerKeywords( Keywords& keys );
+     140             :   void calculateNumericalDerivatives( ActionWithValue* a=NULL ) override;
+     141          62 :   bool actionHasForces() override { return false; }
+     142             :   void lockRequests() override;
+     143             :   void unlockRequests() override;
+     144        8946 :   void calculate() override {}
+     145        8946 :   void apply() override {}
+     146             :   void update() override ;
+     147             : };
+     148             : 
+     149             : PLUMED_REGISTER_ACTION(DumpAtoms,"DUMPATOMS")
+     150             : 
+     151         207 : void DumpAtoms::registerKeywords( Keywords& keys ) {
+     152         207 :   Action::registerKeywords( keys );
+     153         207 :   ActionPilot::registerKeywords( keys );
+     154         207 :   ActionAtomistic::registerKeywords( keys );
+     155         207 :   ActionWithArguments::registerKeywords( keys ); keys.use("ARG");
+     156         414 :   keys.add("compulsory","STRIDE","1","the frequency with which the atoms should be output");
+     157         414 :   keys.add("atoms", "ATOMS", "the atom indices whose positions you would like to print out");
+     158         414 :   keys.add("compulsory", "FILE", "file on which to output coordinates; extension is automatically detected");
+     159         414 :   keys.add("compulsory", "UNITS","PLUMED","the units in which to print out the coordinates. PLUMED means internal PLUMED units");
+     160         414 :   keys.add("optional", "PRECISION","The number of digits in trajectory file");
+     161         414 :   keys.add("optional", "TYPE","file type, either xyz, gro, xtc, or trr, can override an automatically detected file extension");
+     162         414 :   keys.add("optional","LESS_THAN_OR_EQUAL","when printing with arguments that are vectors only print components of vectors have a value less than or equal to this value");
+     163         414 :   keys.add("optional","GREATER_THAN_OR_EQUAL","when printing with arguments that are vectors only print components of vectors have a value greater than or equal to this value");
+     164         207 :   keys.use("RESTART");
+     165         207 :   keys.use("UPDATE_FROM");
+     166         207 :   keys.use("UPDATE_UNTIL");
+     167         207 : }
+     168             : 
+     169         205 : DumpAtoms::DumpAtoms(const ActionOptions&ao):
+     170             :   Action(ao),
+     171             :   ActionAtomistic(ao),
+     172             :   ActionWithArguments(ao),
+     173             :   ActionPilot(ao),
+     174         205 :   iprecision(3)
+     175             : {
+     176             :   std::vector<AtomNumber> atoms;
+     177             :   std::string file;
+     178         410 :   parse("FILE",file);
+     179         205 :   if(file.length()==0) error("name out output file was not specified");
+     180         205 :   type=Tools::extension(file);
+     181         205 :   log<<"  file name "<<file<<"\n";
+     182         429 :   if(type=="gro" || type=="xyz" || type=="xtc" || type=="trr") {
+     183         185 :     log<<"  file extension indicates a "<<type<<" file\n";
+     184             :   } else {
+     185          20 :     log<<"  file extension not detected, assuming xyz\n";
+     186             :     type="xyz";
+     187             :   }
+     188             :   std::string ntype;
+     189         410 :   parse("TYPE",ntype);
+     190         205 :   if(ntype.length()>0) {
+     191           5 :     if(ntype!="xyz" && ntype!="gro" && ntype!="xtc" && ntype!="trr"
+     192           0 :       ) error("TYPE cannot be understood");
+     193           2 :     log<<"  file type enforced to be "<<ntype<<"\n";
+     194             :     type=ntype;
+     195             :   }
+     196             : 
+     197             :   fmt_gro_pos="%8.3f";
+     198             :   fmt_gro_box="%12.7f";
+     199             :   fmt_xyz="%f";
+     200             : 
+     201             :   std::string precision;
+     202         410 :   parse("PRECISION",precision);
+     203         205 :   if(precision.length()>0) {
+     204         136 :     Tools::convert(precision,iprecision);
+     205         136 :     log<<"  with precision "<<iprecision<<"\n";
+     206             :     std::string a,b;
+     207         136 :     Tools::convert(iprecision+5,a);
+     208         136 :     Tools::convert(iprecision,b);
+     209         272 :     fmt_gro_pos="%"+a+"."+b+"f";
+     210             :     fmt_gro_box=fmt_gro_pos;
+     211             :     fmt_xyz=fmt_gro_box;
+     212             :   }
+     213             : 
+     214         410 :   parseAtomList("ATOMS",atoms);
+     215             : 
+     216         410 :   std::string unitname; parse("UNITS",unitname);
+     217         205 :   if(unitname!="PLUMED") {
+     218          17 :     Units myunit; myunit.setLength(unitname);
+     219          32 :     if(myunit.getLength()!=1.0 && type=="gro") error("gro files should be in nm");
+     220          32 :     if(myunit.getLength()!=1.0 && type=="xtc") error("xtc files should be in nm");
+     221          32 :     if(myunit.getLength()!=1.0 && type=="trr") error("trr files should be in nm");
+     222          17 :     lenunit=getUnits().getLength()/myunit.getLength();
+     223         507 :   } else if(type=="gro" || type=="xtc" || type=="trr") lenunit=getUnits().getLength();
+     224         144 :   else lenunit=1.0;
+     225             : 
+     226         205 :   of.link(*this);
+     227         205 :   of.open(file);
+     228             :   std::string path=of.getPath();
+     229         205 :   log<<"  Writing on file "<<path<<"\n";
+     230             :   std::string mode=of.getMode();
+     231         205 :   if(type=="xtc") {
+     232           6 :     of.close();
+     233           6 :     xd=xdrfile::xdrfile_open(path.c_str(),mode.c_str());
+     234         199 :   } else if(type=="trr") {
+     235           4 :     of.close();
+     236           4 :     xd=xdrfile::xdrfile_open(path.c_str(),mode.c_str());
+     237             :   }
+     238         205 :   log.printf("  printing the following atoms in %s :", unitname.c_str() );
+     239       30097 :   for(unsigned i=0; i<atoms.size(); ++i) log.printf(" %d",atoms[i].serial() );
+     240         205 :   log.printf("\n");
+     241             : 
+     242         205 :   if( getNumberOfArguments()>0 ) {
+     243          39 :     if( type!="xyz" ) error("can only print atomic properties when outputting xyz files");
+     244             : 
+     245             :     std::vector<std::string> argnames;
+     246         119 :     for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     247          80 :       if( getPntrToArgument(i)->getRank()!=1 || getPntrToArgument(i)->hasDerivatives() ) error("arguments for xyz output should be vectors");
+     248          80 :       if( getPntrToArgument(i)->getNumberOfValues()!=atoms.size() ) error("number of elements in vector " + getPntrToArgument(i)->getName() + " is not equal to number of atoms output");
+     249          80 :       getPntrToArgument(i)->buildDataStore(true); argnames.push_back( getPntrToArgument(i)->getName() );
+     250             :     }
+     251             :     std::vector<std::string> str_upper, str_lower; std::string errors;
+     252         117 :     parseVector("LESS_THAN_OR_EQUAL",str_upper); parseVector("GREATER_THAN_OR_EQUAL",str_lower);
+     253          39 :     if( !bounds.setBounds( getNumberOfArguments(), str_lower, str_upper, errors ) ) error( errors );
+     254          52 :     if( bounds.wereSet() ) log.printf("  %s \n", bounds.report( argnames ).c_str() );
+     255          39 :   }
+     256             : 
+     257         205 :   requestAtoms(atoms, false);
+     258         205 :   auto* moldat=plumed.getActionSet().selectLatest<GenericMolInfo*>(this);
+     259         205 :   if( moldat ) {
+     260          44 :     log<<"  MOLINFO DATA found with label " <<moldat->getLabel()<<", using proper atom names\n";
+     261          44 :     names.resize(atoms.size());
+     262        5107 :     for(unsigned i=0; i<atoms.size(); i++) if(atoms[i].index()<moldat->getPDBsize()) names[i]=moldat->getAtomName(atoms[i]);
+     263          44 :     residueNumbers.resize(atoms.size());
+     264        5107 :     for(unsigned i=0; i<residueNumbers.size(); ++i) if(atoms[i].index()<moldat->getPDBsize()) residueNumbers[i]=moldat->getResidueNumber(atoms[i]);
+     265          44 :     residueNames.resize(atoms.size());
+     266        5107 :     for(unsigned i=0; i<residueNames.size(); ++i) if(atoms[i].index()<moldat->getPDBsize()) residueNames[i]=moldat->getResidueName(atoms[i]);
+     267             :   }
+     268         205 : }
+     269             : 
+     270           0 : void DumpAtoms::calculateNumericalDerivatives( ActionWithValue* a ) {
+     271           0 :   plumed_merror("this should never be called");
+     272             : }
+     273             : 
+     274        8946 : void DumpAtoms::lockRequests() {
+     275             :   ActionWithArguments::lockRequests();
+     276             :   ActionAtomistic::lockRequests();
+     277        8946 : }
+     278             : 
+     279        8946 : void DumpAtoms::unlockRequests() {
+     280             :   ActionWithArguments::unlockRequests();
+     281             :   ActionAtomistic::unlockRequests();
+     282        8946 : }
+     283             : 
+     284        8851 : void DumpAtoms::update() {
+     285        8851 :   if(type=="xyz") {
+     286        8409 :     unsigned nat=0; std::vector<double> args( getNumberOfArguments() );
+     287       73958 :     for(unsigned i=0; i<getNumberOfAtoms(); ++i)  {
+     288       95451 :       for(unsigned j=0; j<getNumberOfArguments(); ++j) args[j] = getPntrToArgument(j)->get(i);
+     289       65549 :       if( bounds.check( args ) ) nat++;
+     290             :     }
+     291        8409 :     of.printf("%d\n",nat);
+     292        8409 :     const Tensor & t(getPbc().getBox());
+     293        8409 :     if(getPbc().isOrthorombic()) {
+     294         606 :       of.printf((" "+fmt_xyz+" "+fmt_xyz+" "+fmt_xyz+"\n").c_str(),lenunit*t(0,0),lenunit*t(1,1),lenunit*t(2,2));
+     295             :     } else {
+     296       16212 :       of.printf((" "+fmt_xyz+" "+fmt_xyz+" "+fmt_xyz+" "+fmt_xyz+" "+fmt_xyz+" "+fmt_xyz+" "+fmt_xyz+" "+fmt_xyz+" "+fmt_xyz+"\n").c_str(),
+     297        8106 :                 lenunit*t(0,0),lenunit*t(0,1),lenunit*t(0,2),
+     298        8106 :                 lenunit*t(1,0),lenunit*t(1,1),lenunit*t(1,2),
+     299        8106 :                 lenunit*t(2,0),lenunit*t(2,1),lenunit*t(2,2)
+     300             :                );
+     301             :     }
+     302       73958 :     for(unsigned i=0; i<getNumberOfAtoms(); ++i) {
+     303       95451 :       for(unsigned j=0; j<getNumberOfArguments(); ++j) args[j] = getPntrToArgument(j)->get(i);
+     304       65549 :       if( !bounds.check(args) ) continue;
+     305             :       const char* defname="X";
+     306             :       const char* name=defname;
+     307       61743 :       if(names.size()>0) if(names[i].length()>0) name=names[i].c_str();
+     308      123486 :       of.printf(("%s "+fmt_xyz+" "+fmt_xyz+" "+fmt_xyz).c_str(),name,lenunit*getPosition(i)(0),lenunit*getPosition(i)(1),lenunit*getPosition(i)(2));
+     309       87839 :       for(unsigned j=0; j<getNumberOfArguments(); ++j) of.printf((" "+fmt_xyz).c_str(), getPntrToArgument(j)->get(i) );
+     310       61743 :       of.printf("\n");
+     311             :     }
+     312         442 :   } else if(type=="gro") {
+     313         322 :     const Tensor & t(getPbc().getBox());
+     314         322 :     of.printf("Made with PLUMED t=%f\n",getTime()/getUnits().getTime());
+     315         322 :     of.printf("%d\n",getNumberOfAtoms());
+     316       29668 :     for(unsigned i=0; i<getNumberOfAtoms(); ++i) {
+     317             :       const char* defname="X";
+     318             :       const char* name=defname;
+     319             :       unsigned residueNumber=0;
+     320       29346 :       if(names.size()>0) if(names[i].length()>0) name=names[i].c_str();
+     321       29346 :       if(residueNumbers.size()>0) residueNumber=residueNumbers[i];
+     322       29346 :       std::string resname="";
+     323       29346 :       if(residueNames.size()>0) resname=residueNames[i];
+     324       58692 :       of.printf(("%5u%-5s%5s%5d"+fmt_gro_pos+fmt_gro_pos+fmt_gro_pos+"\n").c_str(),
+     325             :                 residueNumber%100000,resname.c_str(),name,getAbsoluteIndex(i).serial()%100000,
+     326       29346 :                 lenunit*getPosition(i)(0),lenunit*getPosition(i)(1),lenunit*getPosition(i)(2));
+     327             :     }
+     328         644 :     of.printf((fmt_gro_box+" "+fmt_gro_box+" "+fmt_gro_box+" "+fmt_gro_box+" "+fmt_gro_box+" "+fmt_gro_box+" "+fmt_gro_box+" "+fmt_gro_box+" "+fmt_gro_box+"\n").c_str(),
+     329         322 :               lenunit*t(0,0),lenunit*t(1,1),lenunit*t(2,2),
+     330         322 :               lenunit*t(0,1),lenunit*t(0,2),lenunit*t(1,0),
+     331         322 :               lenunit*t(1,2),lenunit*t(2,0),lenunit*t(2,1));
+     332         168 :   } else if(type=="xtc" || type=="trr") {
+     333             :     xdrfile::matrix box;
+     334         120 :     const Tensor & t(getPbc().getBox());
+     335         120 :     int natoms=getNumberOfAtoms();
+     336         120 :     int step=getStep();
+     337         120 :     float time=getTime()/getUnits().getTime();
+     338         120 :     float precision=Tools::fastpow(10.0,iprecision);
+     339        1560 :     for(int i=0; i<3; i++) for(int j=0; j<3; j++) box[i][j]=lenunit*t(i,j);
+     340             : // here we cannot use a std::vector<rvec> since it does not compile.
+     341             : // we thus use a std::unique_ptr<rvec[]>
+     342             :     auto pos = Tools::make_unique<xdrfile::rvec[]>(natoms);
+     343       25464 :     for(int i=0; i<natoms; i++) for(int j=0; j<3; j++) pos[i][j]=lenunit*getPosition(i)(j);
+     344         120 :     if(type=="xtc") {
+     345          72 :       write_xtc(xd,natoms,step,time,box,&pos[0],precision);
+     346          48 :     } else if(type=="trr") {
+     347          48 :       write_trr(xd,natoms,step,time,0.0,box,&pos[0],NULL,NULL);
+     348             :     }
+     349           0 :   } else plumed_merror("unknown file type "+type);
+     350        8851 : }
+     351             : 
+     352         410 : DumpAtoms::~DumpAtoms() {
+     353         205 :   if(type=="xtc") {
+     354           6 :     xdrfile_close(xd);
+     355         199 :   } else if(type=="trr") {
+     356           4 :     xdrfile_close(xd);
+     357             :   }
+     358        1025 : }
+     359             : 
+     360             : 
+     361             : }
+     362             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/DumpDerivatives.cpp.func-sort-c.html b/coverage/generic/DumpDerivatives.cpp.func-sort-c.html new file mode 100644 index 000000000000..6a8a90e7c941 --- /dev/null +++ b/coverage/generic/DumpDerivatives.cpp.func-sort-c.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - generic/DumpDerivatives.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - DumpDerivatives.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4848100.0 %
Date:2024-04-19 12:12:35Functions:7977.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic15DumpDerivativesC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic15DumpDerivativesD2Ev0
_ZN4PLMD7generic15DumpDerivativesC1ERKNS_13ActionOptionsE242
_ZN4PLMD7generic15DumpDerivativesD0Ev242
_ZN4PLMD7generic15DumpDerivativesD1Ev242
_ZN4PLMD7generic15DumpDerivatives16registerKeywordsERNS_8KeywordsE244
_ZN4PLMD7generic15DumpDerivatives6updateEv9067
_ZN4PLMD7generic15DumpDerivatives5applyEv12252
_ZN4PLMD7generic15DumpDerivatives9calculateEv12294
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/DumpDerivatives.cpp.func.html b/coverage/generic/DumpDerivatives.cpp.func.html new file mode 100644 index 000000000000..4d34074f624f --- /dev/null +++ b/coverage/generic/DumpDerivatives.cpp.func.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - generic/DumpDerivatives.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - DumpDerivatives.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4848100.0 %
Date:2024-04-19 12:12:35Functions:7977.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic15DumpDerivatives16registerKeywordsERNS_8KeywordsE244
_ZN4PLMD7generic15DumpDerivatives5applyEv12252
_ZN4PLMD7generic15DumpDerivatives6updateEv9067
_ZN4PLMD7generic15DumpDerivatives9calculateEv12294
_ZN4PLMD7generic15DumpDerivativesC1ERKNS_13ActionOptionsE242
_ZN4PLMD7generic15DumpDerivativesC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic15DumpDerivativesD0Ev242
_ZN4PLMD7generic15DumpDerivativesD1Ev242
_ZN4PLMD7generic15DumpDerivativesD2Ev0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/DumpDerivatives.cpp.gcov.html b/coverage/generic/DumpDerivatives.cpp.gcov.html new file mode 100644 index 000000000000..bd57e7ffd3f7 --- /dev/null +++ b/coverage/generic/DumpDerivatives.cpp.gcov.html @@ -0,0 +1,212 @@ + + + + + + + + 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:4848100.0 %
Date:2024-04-19 12:12:35Functions:7977.8 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionPilot.h"
+      23             : #include "core/ActionWithValue.h"
+      24             : #include "core/ActionWithArguments.h"
+      25             : #include "core/ActionRegister.h"
+      26             : #include "tools/File.h"
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace generic {
+      30             : 
+      31             : //+PLUMEDOC PRINTANALYSIS DUMPDERIVATIVES
+      32             : /*
+      33             : Dump the derivatives with respect to the input parameters for one or more objects (generally CVs, functions or biases).
+      34             : 
+      35             : For a CV this line in input instructs plumed to print the derivative of the CV with respect to the atom positions
+      36             : and the cell vectors (virial-like form).  In contrast, for a function or bias the derivative with respect to the input "CVs"
+      37             : will be output.  This command is most often used to test whether or not analytic derivatives have been implemented correctly.  This
+      38             : can be done by outputting the derivatives calculated analytically and numerically.  You can control the buffering of output using the \ref FLUSH keyword.
+      39             : 
+      40             : \par Examples
+      41             : 
+      42             : The following input instructs plumed to write a file called deriv that contains both the
+      43             : analytical and numerical derivatives of the distance between atoms 1 and 2.
+      44             : \plumedfile
+      45             : DISTANCE ATOMS=1,2 LABEL=distance
+      46             : DISTANCE ATOMS=1,2 LABEL=distanceN NUMERICAL_DERIVATIVES
+      47             : DUMPDERIVATIVES ARG=distance,distanceN STRIDE=1 FILE=deriv
+      48             : \endplumedfile
+      49             : 
+      50             : (See also \ref DISTANCE)
+      51             : 
+      52             : */
+      53             : //+ENDPLUMEDOC
+      54             : 
+      55             : class DumpDerivatives :
+      56             :   public ActionPilot,
+      57             :   public ActionWithArguments
+      58             : {
+      59             :   std::string file;
+      60             :   std::string fmt;
+      61             :   OFile of;
+      62             : public:
+      63       12294 :   void calculate() override {}
+      64             :   explicit DumpDerivatives(const ActionOptions&);
+      65             :   static void registerKeywords(Keywords& keys);
+      66       12252 :   void apply() override {}
+      67             :   void update() override;
+      68             :   ~DumpDerivatives();
+      69             : };
+      70             : 
+      71             : PLUMED_REGISTER_ACTION(DumpDerivatives,"DUMPDERIVATIVES")
+      72             : 
+      73         244 : void DumpDerivatives::registerKeywords(Keywords& keys) {
+      74         244 :   Action::registerKeywords(keys);
+      75         244 :   ActionPilot::registerKeywords(keys);
+      76         244 :   ActionWithArguments::registerKeywords(keys);
+      77         244 :   keys.use("ARG");
+      78         488 :   keys.add("compulsory","STRIDE","1","the frequency with which the derivatives should be output");
+      79         488 :   keys.add("compulsory","FILE","the name of the file on which to output the derivatives");
+      80         488 :   keys.add("compulsory","FMT","%15.10f","the format with which the derivatives should be output");
+      81         244 :   keys.use("RESTART");
+      82         244 :   keys.use("UPDATE_FROM");
+      83         244 :   keys.use("UPDATE_UNTIL");
+      84         244 : }
+      85             : 
+      86         242 : DumpDerivatives::DumpDerivatives(const ActionOptions&ao):
+      87             :   Action(ao),
+      88             :   ActionPilot(ao),
+      89             :   ActionWithArguments(ao),
+      90         242 :   fmt("%15.10f")
+      91             : {
+      92         484 :   parse("FILE",file);
+      93         242 :   if( file.length()==0 ) error("name of output file was not specified");
+      94         242 :   parse("FMT",fmt);
+      95         242 :   fmt=" "+fmt;
+      96         242 :   of.link(*this);
+      97         242 :   of.open(file);
+      98         242 :   log.printf("  on file %s\n",file.c_str());
+      99         242 :   log.printf("  with format %s\n",fmt.c_str());
+     100             :   unsigned nargs=getNumberOfArguments();
+     101         242 :   if( nargs==0 ) error("no arguments specified");
+     102         242 :   (getPntrToArgument(0)->getPntrToAction())->turnOnDerivatives();
+     103         242 :   if( getPntrToArgument(0)->getRank()>0 ) error("cannot dump derivatives of non-scalar objects");
+     104         242 :   unsigned npar=getPntrToArgument(0)->getNumberOfDerivatives();
+     105         242 :   if( npar==0 ) error("one or more arguments has no derivatives");
+     106         793 :   for(unsigned i=1; i<nargs; i++) {
+     107         551 :     (getPntrToArgument(i)->getPntrToAction())->turnOnDerivatives();
+     108         551 :     if( getPntrToArgument(i)->getRank()>0 ) error("cannot dump derivatives of non-scalar objects");
+     109         551 :     if( npar!=getPntrToArgument(i)->getNumberOfDerivatives() ) error("the number of derivatives must be the same in all values being dumped");
+     110             :   }
+     111         242 :   checkRead();
+     112         242 : }
+     113             : 
+     114             : 
+     115        9067 : void DumpDerivatives::update() {
+     116        9067 :   unsigned npar=getPntrToArgument(0)->getNumberOfDerivatives();
+     117      653950 :   for(unsigned ipar=0; ipar<npar; ipar++) {
+     118      644883 :     of.fmtField(" %f");
+     119      644883 :     of.printField("time",getTime());
+     120      644883 :     of.printField("parameter",(int)ipar);
+     121     3024771 :     for(unsigned i=0; i<getNumberOfArguments(); i++) {
+     122     2379888 :       of.fmtField(fmt);
+     123     2379888 :       of.printField(getPntrToArgument(i)->getName(),getPntrToArgument(i)->getDerivative(ipar) );
+     124             :     }
+     125      644883 :     of.printField();
+     126             :   }
+     127        9067 : }
+     128             : 
+     129         484 : DumpDerivatives::~DumpDerivatives() {
+     130         484 : }
+     131             : 
+     132             : }
+     133             : 
+     134             : 
+     135             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/DumpForces.cpp.func-sort-c.html b/coverage/generic/DumpForces.cpp.func-sort-c.html new file mode 100644 index 000000000000..a962e09c8f7f --- /dev/null +++ b/coverage/generic/DumpForces.cpp.func-sort-c.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - generic/DumpForces.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - DumpForces.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3737100.0 %
Date:2024-04-19 12:12:35Functions:7977.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic10DumpForcesC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic10DumpForcesD2Ev0
_ZN4PLMD7generic10DumpForcesC1ERKNS_13ActionOptionsE28
_ZN4PLMD7generic10DumpForcesD0Ev28
_ZN4PLMD7generic10DumpForcesD1Ev28
_ZN4PLMD7generic10DumpForces16registerKeywordsERNS_8KeywordsE30
_ZN4PLMD7generic10DumpForces5applyEv400
_ZN4PLMD7generic10DumpForces6updateEv400
_ZN4PLMD7generic10DumpForces9calculateEv400
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/DumpForces.cpp.func.html b/coverage/generic/DumpForces.cpp.func.html new file mode 100644 index 000000000000..73332aad2375 --- /dev/null +++ b/coverage/generic/DumpForces.cpp.func.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - generic/DumpForces.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - DumpForces.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3737100.0 %
Date:2024-04-19 12:12:35Functions:7977.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic10DumpForces16registerKeywordsERNS_8KeywordsE30
_ZN4PLMD7generic10DumpForces5applyEv400
_ZN4PLMD7generic10DumpForces6updateEv400
_ZN4PLMD7generic10DumpForces9calculateEv400
_ZN4PLMD7generic10DumpForcesC1ERKNS_13ActionOptionsE28
_ZN4PLMD7generic10DumpForcesC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic10DumpForcesD0Ev28
_ZN4PLMD7generic10DumpForcesD1Ev28
_ZN4PLMD7generic10DumpForcesD2Ev0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/DumpForces.cpp.gcov.html b/coverage/generic/DumpForces.cpp.gcov.html new file mode 100644 index 000000000000..ac67bc590c50 --- /dev/null +++ b/coverage/generic/DumpForces.cpp.gcov.html @@ -0,0 +1,196 @@ + + + + + + + + LCOV - plumed test coverage - generic/DumpForces.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - DumpForces.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3737100.0 %
Date:2024-04-19 12:12:35Functions:7977.8 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionPilot.h"
+      23             : #include "core/ActionWithArguments.h"
+      24             : #include "core/ActionRegister.h"
+      25             : #include "tools/File.h"
+      26             : 
+      27             : namespace PLMD {
+      28             : namespace generic {
+      29             : 
+      30             : //+PLUMEDOC PRINTANALYSIS DUMPFORCES
+      31             : /*
+      32             : Dump the force acting on one of a values in a file.
+      33             : 
+      34             : For a CV this command will dump
+      35             : the force on the CV itself. Be aware that in order to have the forces on the atoms
+      36             : you should multiply the output from this argument by the output from DUMPDERIVATIVES.
+      37             : Furthermore, also note that you can output the forces on multiple quantities simultaneously
+      38             : by specifying more than one argument. You can control the buffering of output using the \ref FLUSH keyword.
+      39             : 
+      40             : 
+      41             : \par Examples
+      42             : 
+      43             : The following input instructs plumed to write a file called forces that contains
+      44             : the force acting on the distance between atoms 1 and 2.
+      45             : \plumedfile
+      46             : DISTANCE ATOMS=1,2 LABEL=distance
+      47             : DUMPFORCES ARG=distance STRIDE=1 FILE=forces
+      48             : \endplumedfile
+      49             : 
+      50             : */
+      51             : //+ENDPLUMEDOC
+      52             : 
+      53             : class DumpForces :
+      54             :   public ActionPilot,
+      55             :   public ActionWithArguments
+      56             : {
+      57             :   std::string file;
+      58             :   std::string fmt;
+      59             :   OFile of;
+      60             : public:
+      61         400 :   void calculate() override {}
+      62             :   explicit DumpForces(const ActionOptions&);
+      63             :   static void registerKeywords(Keywords& keys);
+      64         400 :   void apply() override {}
+      65             :   void update() override;
+      66             :   ~DumpForces();
+      67             : };
+      68             : 
+      69             : PLUMED_REGISTER_ACTION(DumpForces,"DUMPFORCES")
+      70             : 
+      71          30 : void DumpForces::registerKeywords(Keywords& keys) {
+      72          30 :   Action::registerKeywords(keys);
+      73          30 :   ActionPilot::registerKeywords(keys);
+      74          30 :   ActionWithArguments::registerKeywords(keys);
+      75          30 :   keys.use("ARG");
+      76          60 :   keys.add("compulsory","STRIDE","1","the frequency with which the forces should be output");
+      77          60 :   keys.add("compulsory","FILE","the name of the file on which to output the forces");
+      78          60 :   keys.add("compulsory","FMT","%15.10f","the format with which the derivatives should be output");
+      79          30 :   keys.use("RESTART");
+      80          30 :   keys.use("UPDATE_FROM");
+      81          30 :   keys.use("UPDATE_UNTIL");
+      82          30 : }
+      83             : 
+      84          28 : DumpForces::DumpForces(const ActionOptions&ao):
+      85             :   Action(ao),
+      86             :   ActionPilot(ao),
+      87             :   ActionWithArguments(ao),
+      88          28 :   fmt("%15.10f")
+      89             : {
+      90          56 :   parse("FILE",file);
+      91          28 :   if( file.length()==0 ) error("name of file was not specified");
+      92          28 :   parse("FMT",fmt);
+      93          28 :   fmt=" "+fmt;
+      94          28 :   of.link(*this);
+      95          28 :   of.open(file);
+      96          28 :   log.printf("  on file %s\n",file.c_str());
+      97          28 :   log.printf("  with format %s\n",fmt.c_str());
+      98          28 :   if( getNumberOfArguments()==0 ) error("no arguments have been specified");
+      99          28 :   checkRead();
+     100          28 : }
+     101             : 
+     102             : 
+     103         400 : void DumpForces::update() {
+     104         400 :   of.fmtField(" %f");
+     105         400 :   of.printField("time",getTime());
+     106        4992 :   for(unsigned i=0; i<getNumberOfArguments(); i++) {
+     107        4592 :     of.fmtField(fmt);
+     108        4592 :     of.printField(getPntrToArgument(i)->getName(),getPntrToArgument(i)->getForce());
+     109             :   }
+     110         400 :   of.printField();
+     111         400 : }
+     112             : 
+     113          56 : DumpForces::~DumpForces() {
+     114          56 : }
+     115             : 
+     116             : }
+     117             : 
+     118             : 
+     119             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/DumpMassCharge.cpp.func-sort-c.html b/coverage/generic/DumpMassCharge.cpp.func-sort-c.html new file mode 100644 index 000000000000..08fc59346c23 --- /dev/null +++ b/coverage/generic/DumpMassCharge.cpp.func-sort-c.html @@ -0,0 +1,117 @@ + + + + + + + + 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:626496.9 %
Date:2024-04-19 12:12:35Functions:81172.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic14DumpMassCharge15actionHasForcesEv0
_ZN4PLMD7generic14DumpMassChargeC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic14DumpMassChargeD2Ev0
_ZN4PLMD7generic14DumpMassChargeC1ERKNS_13ActionOptionsE12
_ZN4PLMD7generic14DumpMassChargeD0Ev12
_ZN4PLMD7generic14DumpMassChargeD1Ev12
_ZN4PLMD7generic14DumpMassCharge16registerKeywordsERNS_8KeywordsE14
_ZN4PLMD7generic14DumpMassCharge5applyEv84
_ZN4PLMD7generic14DumpMassCharge6updateEv84
_ZN4PLMD7generic14DumpMassCharge7prepareEv84
_ZN4PLMD7generic14DumpMassCharge9calculateEv84
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/DumpMassCharge.cpp.func.html b/coverage/generic/DumpMassCharge.cpp.func.html new file mode 100644 index 000000000000..36c6f1391127 --- /dev/null +++ b/coverage/generic/DumpMassCharge.cpp.func.html @@ -0,0 +1,117 @@ + + + + + + + + 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:626496.9 %
Date:2024-04-19 12:12:35Functions:81172.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic14DumpMassCharge15actionHasForcesEv0
_ZN4PLMD7generic14DumpMassCharge16registerKeywordsERNS_8KeywordsE14
_ZN4PLMD7generic14DumpMassCharge5applyEv84
_ZN4PLMD7generic14DumpMassCharge6updateEv84
_ZN4PLMD7generic14DumpMassCharge7prepareEv84
_ZN4PLMD7generic14DumpMassCharge9calculateEv84
_ZN4PLMD7generic14DumpMassChargeC1ERKNS_13ActionOptionsE12
_ZN4PLMD7generic14DumpMassChargeC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic14DumpMassChargeD0Ev12
_ZN4PLMD7generic14DumpMassChargeD1Ev12
_ZN4PLMD7generic14DumpMassChargeD2Ev0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/DumpMassCharge.cpp.gcov.html b/coverage/generic/DumpMassCharge.cpp.gcov.html new file mode 100644 index 000000000000..dc1e95d18532 --- /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:626496.9 %
Date:2024-04-19 12:12:35Functions: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/ActionAtomistic.h"
+      23             : #include "core/ActionPilot.h"
+      24             : #include "core/ActionRegister.h"
+      25             : #include "tools/File.h"
+      26             : #include "core/PlumedMain.h"
+      27             : 
+      28             : namespace PLMD
+      29             : {
+      30             : namespace generic {
+      31             : 
+      32             : //+PLUMEDOC PRINTANALYSIS DUMPMASSCHARGE
+      33             : /*
+      34             : Dump masses and charges on a selected file.
+      35             : 
+      36             : This command dumps a file containing charges and masses.
+      37             : It does so only once in the simulation (at first step).
+      38             : File can be recycled in the \ref driver tool.
+      39             : 
+      40             : Notice that masses and charges are only written once at the beginning
+      41             : of the simulation. In case no atom list is provided, charges and
+      42             : masses for all atoms are written.
+      43             : 
+      44             : \par Examples
+      45             : 
+      46             : You can add the DUMPMASSCHARGE action at the end of the plumed.dat
+      47             : file that you use during an MD simulations:
+      48             : 
+      49             : \plumedfile
+      50             : c1: COM ATOMS=1-10
+      51             : c2: COM ATOMS=11-20
+      52             : DUMPATOMS ATOMS=c1,c2 FILE=coms.xyz STRIDE=100
+      53             : 
+      54             : DUMPMASSCHARGE FILE=mcfile
+      55             : \endplumedfile
+      56             : 
+      57             : In this way, you will be able to use the same masses while processing
+      58             : a trajectory from the \ref driver . To do so, you need to
+      59             : add the --mc flag on the driver command line, e.g.
+      60             : \verbatim
+      61             : plumed driver --mc mcfile --plumed plumed.dat --ixyz traj.xyz
+      62             : \endverbatim
+      63             : 
+      64             : With the following input you can dump only the charges for a specific
+      65             : group:
+      66             : 
+      67             : \plumedfile
+      68             : solute_ions: GROUP ATOMS=1-121,200-2012
+      69             : DUMPATOMS FILE=traj.gro ATOMS=solute_ions STRIDE=100
+      70             : DUMPMASSCHARGE FILE=mcfile ATOMS=solute_ions
+      71             : \endplumedfile
+      72             : 
+      73             : */
+      74             : //+ENDPLUMEDOC
+      75             : 
+      76             : class DumpMassCharge:
+      77             :   public ActionAtomistic,
+      78             :   public ActionPilot
+      79             : {
+      80             :   std::string file;
+      81             :   bool first;
+      82             :   bool second;
+      83             :   bool print_masses;
+      84             :   bool print_charges;
+      85             : public:
+      86             :   explicit DumpMassCharge(const ActionOptions&);
+      87             :   ~DumpMassCharge();
+      88             :   static void registerKeywords( Keywords& keys );
+      89           0 :   bool actionHasForces() override { return false; }
+      90             :   void prepare() override;
+      91          84 :   void calculate() override {}
+      92          84 :   void apply() override {}
+      93             :   void update() override;
+      94             : };
+      95             : 
+      96             : 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           8 :     std::vector<std::string> strvec(1);
+     127           8 :     strvec[0]="@mdatoms"; interpretAtomList( strvec, atoms );
+     128           8 :   }
+     129             : 
+     130          12 :   bool only_masses = false;
+     131          12 :   parseFlag("ONLY_MASSES",only_masses);
+     132          12 :   if(only_masses) {
+     133           1 :     print_charges = false;
+     134           1 :     log.printf("  only masses will be written to file\n");
+     135             :   }
+     136             : 
+     137          12 :   bool only_charges = false;
+     138          12 :   parseFlag("ONLY_CHARGES",only_charges);
+     139          12 :   if(only_charges) {
+     140           1 :     print_masses = false;
+     141           1 :     log.printf("  only charges will be written to file\n");
+     142             :   }
+     143             : 
+     144             : 
+     145          12 :   checkRead();
+     146             : 
+     147          12 :   log.printf("  printing the following atoms:" );
+     148        1006 :   for(unsigned i=0; i<atoms.size(); ++i) log.printf(" %d",atoms[i].serial() );
+     149          12 :   log.printf("\n");
+     150          12 :   requestAtoms(atoms);
+     151             : 
+     152          12 :   if(only_masses && only_charges) {
+     153           0 :     plumed_merror("using both ONLY_MASSES and ONLY_CHARGES doesn't make sense");
+     154             :   }
+     155             : 
+     156          12 : }
+     157             : 
+     158          84 : void DumpMassCharge::prepare() {
+     159          84 :   if(!first && second) {
+     160          12 :     requestAtoms(std::vector<AtomNumber>());
+     161          12 :     second=false;
+     162             :   }
+     163          84 : }
+     164             : 
+     165          84 : void DumpMassCharge::update() {
+     166          84 :   if(!first) return;
+     167          12 :   first=false;
+     168             : 
+     169          12 :   OFile of;
+     170          12 :   of.link(*this);
+     171          12 :   of.open(file);
+     172             : 
+     173        1006 :   for(unsigned i=0; i<getNumberOfAtoms(); i++) {
+     174         994 :     int ii=getAbsoluteIndex(i).index();
+     175         994 :     of.printField("index",ii);
+     176        1880 :     if(print_masses) {of.printField("mass",getMass(i));}
+     177        1880 :     if(print_charges) {of.printField("charge",getCharge(i));}
+     178         994 :     of.printField();
+     179             :   }
+     180          12 : }
+     181             : 
+     182          24 : DumpMassCharge::~DumpMassCharge() {
+     183          24 : }
+     184             : 
+     185             : 
+     186             : }
+     187             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/DumpPDB.cpp.func-sort-c.html b/coverage/generic/DumpPDB.cpp.func-sort-c.html new file mode 100644 index 000000000000..c521fb8e8221 --- /dev/null +++ b/coverage/generic/DumpPDB.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - generic/DumpPDB.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - DumpPDB.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:9494100.0 %
Date:2024-04-19 12:12:35Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic7DumpPDBC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic7DumpPDB5applyEv7
_ZN4PLMD7generic7DumpPDB9calculateEv7
_ZN4PLMD7generic7DumpPDBC1ERKNS_13ActionOptionsE15
_ZN4PLMD7generic7DumpPDB16registerKeywordsERNS_8KeywordsE17
_ZN4PLMD7generic7DumpPDB6updateEv19
_ZN4PLMD7generic7DumpPDB13buildArgnamesEv23
_ZNK4PLMD7generic7DumpPDB9printAtomERNS_5OFileERKjRKNS_13VectorGenericILj3EEERKdSB_2143
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/DumpPDB.cpp.func.html b/coverage/generic/DumpPDB.cpp.func.html new file mode 100644 index 000000000000..a9e94f1412db --- /dev/null +++ b/coverage/generic/DumpPDB.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - generic/DumpPDB.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - DumpPDB.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:9494100.0 %
Date:2024-04-19 12:12:35Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic7DumpPDB13buildArgnamesEv23
_ZN4PLMD7generic7DumpPDB16registerKeywordsERNS_8KeywordsE17
_ZN4PLMD7generic7DumpPDB5applyEv7
_ZN4PLMD7generic7DumpPDB6updateEv19
_ZN4PLMD7generic7DumpPDB9calculateEv7
_ZN4PLMD7generic7DumpPDBC1ERKNS_13ActionOptionsE15
_ZN4PLMD7generic7DumpPDBC2ERKNS_13ActionOptionsE0
_ZNK4PLMD7generic7DumpPDB9printAtomERNS_5OFileERKjRKNS_13VectorGenericILj3EEERKdSB_2143
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/DumpPDB.cpp.gcov.html b/coverage/generic/DumpPDB.cpp.gcov.html new file mode 100644 index 000000000000..7e943af36eac --- /dev/null +++ b/coverage/generic/DumpPDB.cpp.gcov.html @@ -0,0 +1,262 @@ + + + + + + + + LCOV - plumed test coverage - generic/DumpPDB.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - DumpPDB.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:9494100.0 %
Date:2024-04-19 12:12:35Functions: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/ActionWithArguments.h"
+      23             : #include "core/ActionWithValue.h"
+      24             : #include "core/ActionPilot.h"
+      25             : #include "core/ActionRegister.h"
+      26             : #include "core/PlumedMain.h"
+      27             : #include "tools/OFile.h"
+      28             : #include "tools/h36.h"
+      29             : 
+      30             : namespace PLMD {
+      31             : namespace generic {
+      32             : 
+      33             : //+PLUMEDOC PRINTANALYSIS DUMPPDB
+      34             : /*
+      35             : Output PDB file.
+      36             : 
+      37             : 
+      38             : \par Examples
+      39             : 
+      40             : */
+      41             : //+ENDPLUMEDOC
+      42             : 
+      43             : class DumpPDB :
+      44             :   public ActionWithArguments,
+      45             :   public ActionPilot
+      46             : {
+      47             :   std::string fmt;
+      48             :   std::string file;
+      49             :   std::string description;
+      50             :   std::vector<std::string> argnames;
+      51             :   std::vector<unsigned> pdb_atom_indices;
+      52             :   void buildArgnames();
+      53             :   void printAtom( OFile& opdbf, const unsigned& anum, const Vector& pos, const double& m, const double& q ) const ;
+      54             : public:
+      55             :   static void registerKeywords( Keywords& keys );
+      56             :   explicit DumpPDB(const ActionOptions&);
+      57           7 :   void calculate() override {}
+      58           7 :   void apply() override {}
+      59             :   void update() override ;
+      60             : };
+      61             : 
+      62             : PLUMED_REGISTER_ACTION(DumpPDB,"DUMPPDB")
+      63             : 
+      64          17 : void DumpPDB::registerKeywords( Keywords& keys ) {
+      65          17 :   Action::registerKeywords( keys );
+      66          17 :   ActionPilot::registerKeywords( keys );
+      67          17 :   ActionWithArguments::registerKeywords( keys ); keys.use("ARG");
+      68          34 :   keys.add("optional","ATOMS","value containing positions of atoms that should be output");
+      69          34 :   keys.add("compulsory","STRIDE","0","the frequency with which the atoms should be output");
+      70          34 :   keys.add("compulsory","FILE","the name of the file on which to output these quantities");
+      71          34 :   keys.add("compulsory","FMT","%f","the format that should be used to output real numbers");
+      72          34 :   keys.add("optional","DESCRIPTION","the title to use for your PDB output");
+      73          34 :   keys.add("optional","ATOM_INDICES","the indices of the atoms in your PDB output");
+      74          34 :   keys.add("optional","ARG_NAMES","the names of the arguments that are being output");
+      75          17 : }
+      76             : 
+      77          15 : DumpPDB::DumpPDB(const ActionOptions&ao):
+      78             :   Action(ao),
+      79             :   ActionWithArguments(ao),
+      80          15 :   ActionPilot(ao)
+      81             : {
+      82          30 :   parse("FILE",file);
+      83          15 :   if(file.length()==0) error("name out output file was not specified");
+      84          30 :   std::vector<std::string> atoms; parseVector("ATOMS",atoms);
+      85          15 :   if( atoms.size()>0 ) {
+      86           8 :     std::vector<Value*> atom_args; interpretArgumentList( atoms, plumed.getActionSet(), this, atom_args );
+      87           8 :     if( atom_args.size()!=1 ) error("only one action should appear in input to atom args");
+      88           8 :     std::vector<Value*> args( getArguments() ); args.push_back( atom_args[0] ); requestArguments( args );
+      89          16 :     std::vector<std::string> indices; parseVector("ATOM_INDICES",indices); Tools::interpretRanges(indices);
+      90           8 :     log.printf("  printing atoms : ");
+      91         153 :     for(unsigned i=0; i<indices.size(); ++i) {
+      92         145 :       AtomNumber atom; bool ok=Tools::convertNoexcept(indices[i],atom);
+      93         145 :       if( !ok ) error("count not interpret atom " + indices[i] );
+      94         145 :       pdb_atom_indices.push_back(atom.serial()); log.printf("%d ", pdb_atom_indices[i] );
+      95             :     }
+      96           8 :     log.printf("\n");
+      97           8 :     if( pdb_atom_indices.size()!=atom_args[0]->getShape()[1]/3 ) error("mismatch between size of matrix containing positions and vector of atom indices");
+      98           8 :   }
+      99          15 :   log.printf("  printing configurations to PDB file to file named %s \n", file.c_str() );
+     100          30 :   parseVector("ARG_NAMES",argnames); if( argnames.size()==0 ) buildArgnames();
+     101          30 :   parse("FMT",fmt); fmt=" "+fmt;
+     102          15 :   if( getStride()==0 ) { setStride(0); log.printf("  printing pdb at end of calculation \n"); }
+     103             : 
+     104          30 :   parse("DESCRIPTION",description);
+     105          15 :   if( getPntrToArgument(0)->getRank()==0 || getPntrToArgument(0)->hasDerivatives() ) error("argument for printing of PDB should be vector or matrix");
+     106          15 :   unsigned nv=getPntrToArgument(0)->getShape()[0];
+     107          44 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     108          29 :     if( getPntrToArgument(i)->getRank()==0 || getPntrToArgument(i)->hasDerivatives() ) error("argument for printing of PDB should be vector or matrix");
+     109          29 :     if( getPntrToArgument(i)->getShape()[0]!=nv ) error("for printing to pdb files all arguments must have same number of values");
+     110             :   }
+     111          15 : }
+     112             : 
+     113        2143 : void DumpPDB::printAtom( OFile& opdbf, const unsigned& anum, const Vector& pos, const double& m, const double& q ) const {
+     114        2143 :   std::array<char,6> at; const char* msg = h36::hy36encode(5,anum,&at[0]);
+     115        2143 :   plumed_assert(msg==nullptr) << msg; at[5]=0; double lunits = plumed.getUnits().getLength()/0.1;
+     116        2143 :   opdbf.printf("ATOM  %s  X   RES  %4u    %8.3f%8.3f%8.3f%6.2f%6.2f\n",
+     117        2143 :                &at[0], anum, lunits*pos[0], lunits*pos[1], lunits*pos[2], m, q );
+     118        2143 : }
+     119             : 
+     120          23 : void DumpPDB::buildArgnames() {
+     121          23 :   unsigned nargs = getNumberOfArguments(); if( pdb_atom_indices.size()>0 ) nargs = nargs - 1;
+     122             :   if( nargs<0 ) return;
+     123             : 
+     124          23 :   argnames.resize(0); unsigned nvals = getPntrToArgument(0)->getShape()[0];
+     125             :   if( getPntrToArgument(0)->getRank()==2 ) nvals = getPntrToArgument(0)->getShape()[0];
+     126          48 :   for(unsigned i=0; i<nargs; ++i) {
+     127          25 :     if( getPntrToArgument(i)->getShape()[0]!=nvals ) error("all arguments should have same number of values");
+     128          25 :     if( getPntrToArgument(i)->getRank()==1 ) {
+     129          17 :       argnames.push_back( getPntrToArgument(i)->getName() );
+     130           8 :     } else if( getPntrToArgument(i)->getRank()==2 ) {
+     131           8 :       (getPntrToArgument(i)->getPntrToAction())->getMatrixColumnTitles( argnames );
+     132             :     }
+     133          25 :     getPntrToArgument(i)->buildDataStore();
+     134             :   }
+     135             : }
+     136             : 
+     137          19 : void DumpPDB::update() {
+     138          19 :   OFile opdbf; opdbf.link(*this);
+     139          19 :   opdbf.setBackupString("analysis");
+     140          19 :   opdbf.open( file );
+     141          19 :   std::size_t psign=fmt.find("%"); plumed_assert( psign!=std::string::npos );
+     142          38 :   std::string descr2="%s=%-" + fmt.substr(psign+1) + " ";
+     143             : 
+     144          19 :   unsigned totargs = 0; unsigned nvals = getPntrToArgument(0)->getShape()[0];
+     145          56 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     146          37 :     if( getPntrToArgument(i)->getShape()[0]!=nvals ) error("all arguments should have same number of values");
+     147          37 :     if( getPntrToArgument(i)->getRank()==1 ) totargs += 1;
+     148          18 :     else if( getPntrToArgument(i)->getRank()==2 ) totargs += getPntrToArgument(i)->getShape()[1];
+     149             :   }
+     150          19 :   if( totargs!=argnames.size() ) buildArgnames();
+     151             : 
+     152          19 :   if( description.length()>0 ) opdbf.printf("# %s AT STEP %lld TIME %f \n", description.c_str(), getStep(), getTime() );
+     153          19 :   unsigned nargs = getNumberOfArguments(), atomarg=0;
+     154          19 :   if( pdb_atom_indices.size()>0 ) {
+     155           9 :     if( nargs>1 ) { atomarg = nargs - 1; nargs = nargs-1; }
+     156             :     else nargs = 0;
+     157             :   }
+     158         448 :   for(unsigned i=0; i<nvals; ++i) {
+     159             :     unsigned n=0;
+     160        1269 :     for(unsigned j=0; j<nargs; j++) {
+     161         840 :       Value* thisarg=getPntrToArgument(j); opdbf.printf("REMARK ");
+     162         840 :       if( thisarg->getRank()==1 ) {
+     163         405 :         opdbf.printf( descr2.c_str(), argnames[n].c_str(), thisarg->get(i) ); n++;
+     164         435 :       } else if( thisarg->getRank()==2 ) {
+     165         435 :         unsigned ncols = thisarg->getShape()[1];
+     166        1297 :         for(unsigned k=0; k<ncols; ++k) { opdbf.printf( descr2.c_str(), argnames[n].c_str(), thisarg->get(i*ncols+k) ); n++; }
+     167             :       }
+     168         840 :       opdbf.printf("\n");
+     169             :     }
+     170         429 :     if( pdb_atom_indices.size()>0 ) {
+     171         138 :       unsigned npos = pdb_atom_indices.size(); Vector pos;
+     172        2281 :       for(unsigned k=0; k<npos; ++k) {
+     173        2143 :         pos[0]=getPntrToArgument(atomarg)->get(npos*(3*i+0) + k);
+     174        2143 :         pos[1]=getPntrToArgument(atomarg)->get(npos*(3*i+1) + k);
+     175        2143 :         pos[2]=getPntrToArgument(atomarg)->get(npos*(3*i+2) + k);
+     176        2143 :         printAtom( opdbf, pdb_atom_indices[k], pos, 1.0, 1.0 );
+     177             :       }
+     178             :     }
+     179         429 :     opdbf.printf("END\n");
+     180             :   }
+     181          19 :   opdbf.close();
+     182          19 : }
+     183             : 
+     184             : }
+     185             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/DumpProjections.cpp.func-sort-c.html b/coverage/generic/DumpProjections.cpp.func-sort-c.html new file mode 100644 index 000000000000..7725b175b1bb --- /dev/null +++ b/coverage/generic/DumpProjections.cpp.func-sort-c.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - generic/DumpProjections.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - DumpProjections.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3838100.0 %
Date:2024-04-19 12:12:35Functions:81080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic15DumpProjectionsC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic15DumpProjectionsD2Ev0
_ZN4PLMD7generic15DumpProjectionsC1ERKNS_13ActionOptionsE1
_ZN4PLMD7generic15DumpProjectionsD0Ev1
_ZN4PLMD7generic15DumpProjectionsD1Ev1
_ZN4PLMD7generic15DumpProjections16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD7generic15DumpProjections5applyEv3
_ZN4PLMD7generic15DumpProjections6updateEv3
_ZN4PLMD7generic15DumpProjections9calculateEv3
_ZNK4PLMD7generic15DumpProjections19checkNeedsGradientsEv3
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/DumpProjections.cpp.func.html b/coverage/generic/DumpProjections.cpp.func.html new file mode 100644 index 000000000000..0b5696bf421f --- /dev/null +++ b/coverage/generic/DumpProjections.cpp.func.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - generic/DumpProjections.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - DumpProjections.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3838100.0 %
Date:2024-04-19 12:12:35Functions:81080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic15DumpProjections16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD7generic15DumpProjections5applyEv3
_ZN4PLMD7generic15DumpProjections6updateEv3
_ZN4PLMD7generic15DumpProjections9calculateEv3
_ZN4PLMD7generic15DumpProjectionsC1ERKNS_13ActionOptionsE1
_ZN4PLMD7generic15DumpProjectionsC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic15DumpProjectionsD0Ev1
_ZN4PLMD7generic15DumpProjectionsD1Ev1
_ZN4PLMD7generic15DumpProjectionsD2Ev0
_ZNK4PLMD7generic15DumpProjections19checkNeedsGradientsEv3
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/DumpProjections.cpp.gcov.html b/coverage/generic/DumpProjections.cpp.gcov.html new file mode 100644 index 000000000000..3057a608e514 --- /dev/null +++ b/coverage/generic/DumpProjections.cpp.gcov.html @@ -0,0 +1,197 @@ + + + + + + + + LCOV - plumed test coverage - generic/DumpProjections.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - DumpProjections.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3838100.0 %
Date:2024-04-19 12:12:35Functions:81080.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionPilot.h"
+      23             : #include "core/ActionWithValue.h"
+      24             : #include "core/ActionWithArguments.h"
+      25             : #include "core/ActionRegister.h"
+      26             : #include "tools/File.h"
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace generic {
+      30             : 
+      31             : //+PLUMEDOC PRINTANALYSIS DUMPPROJECTIONS
+      32             : /*
+      33             : Dump the derivatives with respect to the input parameters for one or more objects (generally CVs, functions or biases).
+      34             : 
+      35             : \par Examples
+      36             : 
+      37             : Compute the distance between two groups and write on a file the
+      38             : derivatives of this distance with respect to all the atoms of the two groups
+      39             : 
+      40             : \plumedfile
+      41             : x1: CENTER ATOMS=1-10
+      42             : x2: CENTER ATOMS=11-20
+      43             : d: DISTANCE ATOMS=x1,x2
+      44             : DUMPPROJECTIONS ARG=d FILE=proj STRIDE=20
+      45             : \endplumedfile
+      46             : 
+      47             : */
+      48             : //+ENDPLUMEDOC
+      49             : 
+      50             : class DumpProjections :
+      51             :   public ActionPilot,
+      52             :   public ActionWithArguments
+      53             : {
+      54             :   std::string file;
+      55             :   std::string fmt;
+      56             :   OFile of;
+      57             : public:
+      58           3 :   void calculate() override {}
+      59             :   explicit DumpProjections(const ActionOptions&);
+      60             :   static void registerKeywords(Keywords& keys);
+      61           3 :   void apply() override {}
+      62             :   void update() override;
+      63           3 :   bool checkNeedsGradients()const override {return true;}
+      64             :   ~DumpProjections();
+      65             : };
+      66             : 
+      67             : PLUMED_REGISTER_ACTION(DumpProjections,"DUMPPROJECTIONS")
+      68             : 
+      69           3 : void DumpProjections::registerKeywords(Keywords& keys) {
+      70           3 :   Action::registerKeywords(keys);
+      71           3 :   ActionPilot::registerKeywords(keys);
+      72           3 :   ActionWithArguments::registerKeywords(keys);
+      73           3 :   keys.use("ARG");
+      74           6 :   keys.add("compulsory","STRIDE","1","the frequency with which the derivatives should be output");
+      75           6 :   keys.add("compulsory","FILE","the name of the file on which to output the derivatives");
+      76           6 :   keys.add("compulsory","FMT","%15.10f","the format with which the derivatives should be output");
+      77           3 :   keys.use("RESTART");
+      78           3 :   keys.use("UPDATE_FROM");
+      79           3 :   keys.use("UPDATE_UNTIL");
+      80           3 : }
+      81             : 
+      82           1 : DumpProjections::DumpProjections(const ActionOptions&ao):
+      83             :   Action(ao),
+      84             :   ActionPilot(ao),
+      85             :   ActionWithArguments(ao),
+      86           1 :   fmt("%15.10f")
+      87             : {
+      88           2 :   parse("FILE",file);
+      89           1 :   if( file.length()==0 ) error("filename not specified");
+      90           1 :   parse("FMT",fmt);
+      91           1 :   fmt=" "+fmt;
+      92           1 :   of.open(file);
+      93           1 :   log.printf("  on file %s\n",file.c_str());
+      94           1 :   log.printf("  with format %s\n",fmt.c_str());
+      95           1 :   checkRead();
+      96             : 
+      97           3 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+      98           2 :     (getPntrToArgument(i)->getPntrToAction())->turnOnDerivatives();
+      99             :   }
+     100           1 : }
+     101             : 
+     102             : 
+     103           3 : void DumpProjections::update() {
+     104           6 :   of.fmtField(" %f").printField("time",getTime());
+     105           9 :   for(unsigned i=0; i<getNumberOfArguments(); i++) {
+     106          18 :     for(unsigned j=0; j<getNumberOfArguments(); j++) {
+     107          12 :       of.fmtField(fmt);
+     108          24 :       of.printField(getPntrToArgument(i)->getName()+"-"+getPntrToArgument(j)->getName(),getProjection(i,j));
+     109             :     }
+     110             :   }
+     111           3 :   of.printField();
+     112           3 : }
+     113             : 
+     114           2 : DumpProjections::~DumpProjections() {
+     115           2 : }
+     116             : 
+     117             : }
+     118             : 
+     119             : 
+     120             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/DumpVector.cpp.func-sort-c.html b/coverage/generic/DumpVector.cpp.func-sort-c.html new file mode 100644 index 000000000000..83d405fafd70 --- /dev/null +++ b/coverage/generic/DumpVector.cpp.func-sort-c.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - generic/DumpVector.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - DumpVector.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:5454100.0 %
Date:2024-04-19 12:12:35Functions:8988.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic10DumpVectorC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic10DumpVector5applyEv16
_ZN4PLMD7generic10DumpVector9calculateEv16
_ZN4PLMD7generic10DumpVectorC1ERKNS_13ActionOptionsE36
_ZN4PLMD7generic10DumpVectorD0Ev36
_ZN4PLMD7generic10DumpVectorD1Ev36
_ZN4PLMD7generic10DumpVector16registerKeywordsERNS_8KeywordsE38
_ZN4PLMD7generic10DumpVector13buildArgnamesEv40
_ZN4PLMD7generic10DumpVector6updateEv46
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/DumpVector.cpp.func.html b/coverage/generic/DumpVector.cpp.func.html new file mode 100644 index 000000000000..737f6d5e55f5 --- /dev/null +++ b/coverage/generic/DumpVector.cpp.func.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - generic/DumpVector.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - DumpVector.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:5454100.0 %
Date:2024-04-19 12:12:35Functions:8988.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic10DumpVector13buildArgnamesEv40
_ZN4PLMD7generic10DumpVector16registerKeywordsERNS_8KeywordsE38
_ZN4PLMD7generic10DumpVector5applyEv16
_ZN4PLMD7generic10DumpVector6updateEv46
_ZN4PLMD7generic10DumpVector9calculateEv16
_ZN4PLMD7generic10DumpVectorC1ERKNS_13ActionOptionsE36
_ZN4PLMD7generic10DumpVectorC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic10DumpVectorD0Ev36
_ZN4PLMD7generic10DumpVectorD1Ev36
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/DumpVector.cpp.gcov.html b/coverage/generic/DumpVector.cpp.gcov.html new file mode 100644 index 000000000000..694eda6af685 --- /dev/null +++ b/coverage/generic/DumpVector.cpp.gcov.html @@ -0,0 +1,210 @@ + + + + + + + + LCOV - plumed test coverage - generic/DumpVector.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - DumpVector.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:5454100.0 %
Date:2024-04-19 12:12:35Functions: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/ActionWithArguments.h"
+      23             : #include "core/ActionWithValue.h"
+      24             : #include "core/ActionPilot.h"
+      25             : #include "core/ActionRegister.h"
+      26             : #include "core/PlumedMain.h"
+      27             : #include "tools/Communicator.h"
+      28             : #include "tools/OFile.h"
+      29             : 
+      30             : namespace PLMD {
+      31             : namespace generic {
+      32             : 
+      33             : //+PLUMEDOC PRINTANALYSIS DUMPVECTOR
+      34             : /*
+      35             : Print a vector to a file
+      36             : 
+      37             : \par Examples
+      38             : 
+      39             : */
+      40             : //+ENDPLUMEDOC
+      41             : 
+      42             : class DumpVector :
+      43             :   public ActionWithArguments,
+      44             :   public ActionPilot {
+      45             : private:
+      46             :   bool onefile;
+      47             :   std::vector<std::string> argnames;
+      48             :   std::string fmt, filename;
+      49             :   void buildArgnames();
+      50             : public:
+      51             :   static void registerKeywords( Keywords& keys );
+      52             :   explicit DumpVector(const ActionOptions&ao);
+      53          72 :   ~DumpVector() {}
+      54          16 :   void calculate() override {}
+      55          16 :   void apply() override {}
+      56             :   void update() override ;
+      57             : };
+      58             : 
+      59             : PLUMED_REGISTER_ACTION(DumpVector,"DUMPVECTOR")
+      60             : 
+      61          38 : void DumpVector::registerKeywords( Keywords& keys ) {
+      62          38 :   Action::registerKeywords( keys );
+      63          38 :   ActionPilot::registerKeywords( keys );
+      64          38 :   ActionWithArguments::registerKeywords( keys ); keys.use("ARG");
+      65          76 :   keys.add("compulsory","STRIDE","0","the frequency with which the grid should be output to the file.");
+      66          76 :   keys.add("compulsory","FILE","density","the file on which to write the vetors");
+      67          76 :   keys.add("optional","FMT","the format that should be used to output real numbers");
+      68          76 :   keys.addFlag("PRINT_ONE_FILE",false,"output vectors one after the other in a single file");
+      69          38 : }
+      70             : 
+      71          36 : DumpVector::DumpVector(const ActionOptions&ao):
+      72             :   Action(ao),
+      73             :   ActionWithArguments(ao),
+      74             :   ActionPilot(ao),
+      75          36 :   fmt("%f")
+      76             : {
+      77          36 :   if( getNumberOfArguments()==0 ) error("found no arguments");
+      78         108 :   buildArgnames(); parse("FILE",filename); parseFlag("PRINT_ONE_FILE", onefile);
+      79          36 :   if(filename.length()==0) error("name out output file was not specified");
+      80             : 
+      81          36 :   log.printf("  outputting data with label %s to file named %s",getPntrToArgument(0)->getName().c_str(), filename.c_str() );
+      82          72 :   parse("FMT",fmt); log.printf(" with format %s \n", fmt.c_str() ); fmt = " " + fmt;
+      83          36 :   if( onefile ) log.printf("  printing all grids on a single file \n");
+      84          36 :   else log.printf("  printing all grids on separate files \n");
+      85          36 : }
+      86             : 
+      87          40 : void DumpVector::buildArgnames() {
+      88          40 :   argnames.resize(0); unsigned nvals = getPntrToArgument(0)->getShape()[0];
+      89             :   if( getPntrToArgument(0)->getRank()==2 ) nvals = getPntrToArgument(0)->getShape()[0];
+      90         102 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+      91          62 :     if( getPntrToArgument(i)->getShape()[0]!=nvals ) error("all arguments should have same number of values");
+      92          62 :     if( getPntrToArgument(i)->getRank()==1 ) {
+      93          34 :       argnames.push_back( getPntrToArgument(i)->getName() );
+      94          28 :     } else if( getPntrToArgument(i)->getRank()==2 ) {
+      95          28 :       (getPntrToArgument(i)->getPntrToAction())->getMatrixColumnTitles( argnames );
+      96             :     }
+      97          62 :     getPntrToArgument(i)->buildDataStore();
+      98             :   }
+      99          40 : }
+     100             : 
+     101          46 : void DumpVector::update() {
+     102          46 :   OFile ofile; ofile.link(*this);
+     103          46 :   if( onefile ) ofile.enforceRestart();
+     104          92 :   else ofile.setBackupString("analysis");
+     105          46 :   ofile.open( filename );
+     106             : 
+     107             :   unsigned totargs = 0;
+     108         122 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     109          76 :     if( getPntrToArgument(i)->getRank()==1 ) totargs += 1;
+     110          33 :     else if( getPntrToArgument(i)->getRank()==2 ) totargs += getPntrToArgument(i)->getShape()[1];
+     111             :   }
+     112          46 :   if( totargs!=argnames.size() ) buildArgnames();
+     113             : 
+     114          46 :   unsigned nvals = getPntrToArgument(0)->getShape()[0];
+     115        5228 :   for(unsigned i=0; i<nvals; ++i) {
+     116             :     unsigned n=0;
+     117        5182 :     ofile.fmtField(" %f");
+     118        5182 :     ofile.printField("time",getTime());
+     119        5182 :     ofile.printField("parameter",int(i));
+     120       14613 :     for(unsigned j=0; j<getNumberOfArguments(); j++) {
+     121        9431 :       if( getPntrToArgument(j)->getRank()==1 ) {
+     122        7889 :         ofile.fmtField(fmt); ofile.printField(argnames[n],getPntrToArgument(j)->get(i) ); n++;
+     123        1542 :       } else if( getPntrToArgument(j)->getRank()==2 ) {
+     124        1542 :         unsigned ncols = getPntrToArgument(j)->getShape()[1];
+     125        9375 :         for(unsigned k=0; k<ncols; ++k) { ofile.fmtField(fmt); ofile.printField(argnames[n],getPntrToArgument(j)->get(i*ncols+k)); n++; }
+     126             :       }
+     127             :     }
+     128        5182 :     ofile.printField();
+     129             :   }
+     130          46 : }
+     131             : 
+     132             : }
+     133             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/EffectiveEnergyDrift.cpp.func-sort-c.html b/coverage/generic/EffectiveEnergyDrift.cpp.func-sort-c.html new file mode 100644 index 000000000000..f54f689d3d86 --- /dev/null +++ b/coverage/generic/EffectiveEnergyDrift.cpp.func-sort-c.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - generic/EffectiveEnergyDrift.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - EffectiveEnergyDrift.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:14715197.4 %
Date:2024-04-19 12:12:35Functions:7977.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic20EffectiveEnergyDriftC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic20EffectiveEnergyDriftD2Ev0
_ZN4PLMD7generic20EffectiveEnergyDriftC1ERKNS_13ActionOptionsE9
_ZN4PLMD7generic20EffectiveEnergyDriftD0Ev9
_ZN4PLMD7generic20EffectiveEnergyDriftD1Ev9
_ZN4PLMD7generic20EffectiveEnergyDrift16registerKeywordsERNS_8KeywordsE11
_ZN4PLMD7generic20EffectiveEnergyDrift5applyEv450
_ZN4PLMD7generic20EffectiveEnergyDrift6updateEv450
_ZN4PLMD7generic20EffectiveEnergyDrift9calculateEv450
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/EffectiveEnergyDrift.cpp.func.html b/coverage/generic/EffectiveEnergyDrift.cpp.func.html new file mode 100644 index 000000000000..362e7faac36b --- /dev/null +++ b/coverage/generic/EffectiveEnergyDrift.cpp.func.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - generic/EffectiveEnergyDrift.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - EffectiveEnergyDrift.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:14715197.4 %
Date:2024-04-19 12:12:35Functions:7977.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic20EffectiveEnergyDrift16registerKeywordsERNS_8KeywordsE11
_ZN4PLMD7generic20EffectiveEnergyDrift5applyEv450
_ZN4PLMD7generic20EffectiveEnergyDrift6updateEv450
_ZN4PLMD7generic20EffectiveEnergyDrift9calculateEv450
_ZN4PLMD7generic20EffectiveEnergyDriftC1ERKNS_13ActionOptionsE9
_ZN4PLMD7generic20EffectiveEnergyDriftC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic20EffectiveEnergyDriftD0Ev9
_ZN4PLMD7generic20EffectiveEnergyDriftD1Ev9
_ZN4PLMD7generic20EffectiveEnergyDriftD2Ev0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/EffectiveEnergyDrift.cpp.gcov.html b/coverage/generic/EffectiveEnergyDrift.cpp.gcov.html new file mode 100644 index 000000000000..f33e483e35e6 --- /dev/null +++ b/coverage/generic/EffectiveEnergyDrift.cpp.gcov.html @@ -0,0 +1,448 @@ + + + + + + + + LCOV - plumed test coverage - generic/EffectiveEnergyDrift.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - EffectiveEnergyDrift.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:14715197.4 %
Date:2024-04-19 12:12:35Functions:7977.8 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : /*
+      24             :  This class was originally written by Marco Jacopo Ferrarotti
+      25             :  (marco.ferrarotti@gmail.com) and Giovanni Bussi
+      26             : */
+      27             : 
+      28             : #include "core/Action.h"
+      29             : #include "core/ActionPilot.h"
+      30             : #include "core/ActionWithValue.h"
+      31             : #include "core/ActionSet.h"
+      32             : #include "core/ActionRegister.h"
+      33             : #include "core/DomainDecomposition.h"
+      34             : #include "core/ActionToPutData.h"
+      35             : #include "core/PbcAction.h"
+      36             : #include "core/PlumedMain.h"
+      37             : 
+      38             : #include "tools/File.h"
+      39             : #include "tools/Pbc.h"
+      40             : 
+      41             : #include <algorithm>
+      42             : 
+      43             : namespace PLMD {
+      44             : namespace generic {
+      45             : 
+      46             : //+PLUMEDOC GENERIC EFFECTIVE_ENERGY_DRIFT
+      47             : /*
+      48             : Print the effective energy drift
+      49             : 
+      50             : The method used to calculate the effective energy drift is described in Ref \cite Ferrarotti2015
+      51             : 
+      52             : 
+      53             : \par Examples
+      54             : 
+      55             : 
+      56             : This is to monitor the effective energy drift for a metadynamics
+      57             : simulation on the Debye-Huckel energy. Since this variable is very expensive,
+      58             : it could be conveniently computed every second step.
+      59             : \plumedfile
+      60             : dh: DHENERGY GROUPA=1-10 GROUPB=11-20 EPSILON=80.0 I=0.1 TEMP=300.0
+      61             : METAD ARG=dh HEIGHT=0.5 SIGMA=0.1 PACE=500 STRIDE=2
+      62             : EFFECTIVE_ENERGY_DRIFT PRINT_STRIDE=100 FILE=eff
+      63             : \endplumedfile
+      64             : 
+      65             : This is to monitor if a restraint is too stiff
+      66             : \plumedfile
+      67             : d: DISTANCE ATOMS=10,20
+      68             : RESTRAINT ARG=d KAPPA=100000 AT=0.6
+      69             : EFFECTIVE_ENERGY_DRIFT PRINT_STRIDE=100 FILE=eff
+      70             : \endplumedfile
+      71             : 
+      72             : */
+      73             : //+ENDPLUMEDOC
+      74             : 
+      75             : 
+      76             : class EffectiveEnergyDrift:
+      77             :   public ActionPilot {
+      78             :   OFile output;
+      79             :   long long int printStride;
+      80             :   std::string fmt;
+      81             : 
+      82             :   double eed;
+      83             : 
+      84             :   std::vector<ActionWithValue*> biases;
+      85             : 
+      86             :   long long int pDdStep;
+      87             :   int nLocalAtoms;
+      88             :   int pNLocalAtoms;
+      89             :   std::vector<int> pGatindex;
+      90             :   std::vector<double> xpositions;
+      91             :   std::vector<double> ypositions;
+      92             :   std::vector<double> zpositions;
+      93             :   std::vector<Vector> positions;
+      94             :   std::vector<Vector> pPositions;
+      95             :   std::vector<Vector> forces;
+      96             :   std::vector<Vector> pForces;
+      97             :   Tensor box,pbox;
+      98             :   Tensor fbox,pfbox;
+      99             : 
+     100             :   const int nProc;
+     101             :   std::vector<int> indexCnt;
+     102             :   std::vector<int> indexDsp;
+     103             :   std::vector<int> dataCnt;
+     104             :   std::vector<int> dataDsp;
+     105             :   std::vector<int> indexS;
+     106             :   std::vector<int> indexR;
+     107             :   std::vector<double> dataS;
+     108             :   std::vector<double> dataR;
+     109             :   std::vector<int> backmap;
+     110             : 
+     111             :   double initialBias;
+     112             :   bool isFirstStep;
+     113             : 
+     114             :   bool ensemble;
+     115             :   PbcAction* pbc_action;
+     116             :   DomainDecomposition* domains;
+     117             :   ActionToPutData* posx;
+     118             :   ActionToPutData* posy;
+     119             :   ActionToPutData* posz;
+     120             : public:
+     121             :   explicit EffectiveEnergyDrift(const ActionOptions&);
+     122             :   ~EffectiveEnergyDrift();
+     123             : 
+     124             :   static void registerKeywords( Keywords& keys );
+     125             : 
+     126         450 :   void calculate() override {};
+     127         450 :   void apply() override {};
+     128             :   void update() override;
+     129             : };
+     130             : 
+     131             : PLUMED_REGISTER_ACTION(EffectiveEnergyDrift,"EFFECTIVE_ENERGY_DRIFT")
+     132             : 
+     133          11 : void EffectiveEnergyDrift::registerKeywords( Keywords& keys ) {
+     134          11 :   Action::registerKeywords( keys );
+     135          11 :   ActionPilot::registerKeywords( keys );
+     136             : 
+     137          22 :   keys.add("compulsory","STRIDE","1","should be set to 1. Effective energy drift computation has to be active at each step.");
+     138          22 :   keys.add("compulsory", "FILE", "file on which to output the effective energy drift.");
+     139          22 :   keys.add("compulsory", "PRINT_STRIDE", "frequency to which output the effective energy drift on FILE");
+     140          22 :   keys.addFlag("ENSEMBLE",false,"Set to TRUE if you want to average over multiple replicas.");
+     141          22 :   keys.add("optional","FMT","the format that should be used to output real numbers");
+     142          11 :   keys.use("RESTART");
+     143          11 :   keys.use("UPDATE_FROM");
+     144          11 :   keys.use("UPDATE_UNTIL");
+     145          11 : }
+     146             : 
+     147           9 : EffectiveEnergyDrift::EffectiveEnergyDrift(const ActionOptions&ao):
+     148             :   Action(ao),
+     149             :   ActionPilot(ao),
+     150           9 :   fmt("%f"),
+     151           9 :   eed(0.0),
+     152           9 :   nProc(plumed.comm.Get_size()),
+     153           9 :   initialBias(0.0),
+     154           9 :   isFirstStep(true),
+     155           9 :   ensemble(false),
+     156           9 :   pbc_action(NULL),
+     157           9 :   domains(NULL),
+     158           9 :   posx(NULL),
+     159           9 :   posy(NULL),
+     160          27 :   posz(NULL)
+     161             : {
+     162             :   //stride must be == 1
+     163           9 :   if(getStride()!=1) error("EFFECTIVE_ENERGY_DRIFT must have STRIDE=1 to work properly");
+     164             : 
+     165             :   //parse and open FILE
+     166             :   std::string fileName;
+     167          18 :   parse("FILE",fileName);
+     168           9 :   if(fileName.length()==0) error("name out output file was not specified\n");
+     169           9 :   output.link(*this);
+     170           9 :   output.open(fileName);
+     171             : 
+     172             :   //parse PRINT_STRIDE
+     173           9 :   parse("PRINT_STRIDE",printStride);
+     174             : 
+     175             : 
+     176             :   //parse FMT
+     177           9 :   parse("FMT",fmt);
+     178           9 :   fmt=" "+fmt;
+     179           9 :   log.printf("  with format %s\n",fmt.c_str());
+     180             : 
+     181             :   //parse ENSEMBLE
+     182           9 :   ensemble=false;
+     183           9 :   parseFlag("ENSEMBLE",ensemble);
+     184           9 :   if(ensemble&&comm.Get_rank()==0) {
+     185           0 :     if(multi_sim_comm.Get_size()<2) error("You CANNOT run Replica-Averaged simulations without running multiple replicas!\n");
+     186             :   }
+     187             : 
+     188          18 :   log<<"Bibliography "<<cite("Ferrarotti, Bottaro, Perez-Villa, and Bussi, J. Chem. Theory Comput. 11, 139 (2015)")<<"\n";
+     189             : 
+     190             :   //construct biases from ActionWithValue with a component named bias
+     191           9 :   std::vector<ActionWithValue*> tmpActions=plumed.getActionSet().select<ActionWithValue*>();
+     192         100 :   for(unsigned i=0; i<tmpActions.size(); i++) if(tmpActions[i]->exists(tmpActions[i]->getLabel()+".bias")) biases.push_back(tmpActions[i]);
+     193             : 
+     194             :   //resize counters and displacements useful to communicate with MPI_Allgatherv
+     195           9 :   indexCnt.resize(nProc);
+     196           9 :   indexDsp.resize(nProc);
+     197           9 :   dataCnt.resize(nProc);
+     198           9 :   dataDsp.resize(nProc);
+     199             :   // Retrieve the box
+     200           9 :   pbc_action=plumed.getActionSet().selectWithLabel<PbcAction*>("Box");
+     201             :   // Get the domain decomposition object
+     202           9 :   std::vector<DomainDecomposition*> ddact=plumed.getActionSet().select<DomainDecomposition*>();
+     203           9 :   if( ddact.size()>1 ) warning("found more than one interface so don't know get gatindex");
+     204           9 :   domains = ddact[0];
+     205           9 :   std::vector<ActionToPutData*> inputs=plumed.getActionSet().select<ActionToPutData*>();
+     206          73 :   for(const auto & pp : inputs ) {
+     207         128 :     if( pp->getRole()=="x" ) posx = pp;
+     208         128 :     if( pp->getRole()=="y" ) posy = pp;
+     209         128 :     if( pp->getRole()=="z" ) posz = pp;
+     210             :   }
+     211           9 :   plumed_assert( posx && posy && posz );
+     212             :   //resize the received buffers
+     213           9 :   indexR.resize((posx->copyOutput(0))->getShape()[0]);
+     214           9 :   dataR.resize((posx->copyOutput(0))->getShape()[0]*6);
+     215           9 :   backmap.resize((posx->copyOutput(0))->getShape()[0]);
+     216           9 : }
+     217             : 
+     218          18 : EffectiveEnergyDrift::~EffectiveEnergyDrift() {
+     219             : 
+     220          18 : }
+     221             : 
+     222         450 : void EffectiveEnergyDrift::update() {
+     223         450 :   Pbc & tpbc(pbc_action->getPbc()); bool pbc=tpbc.isSet();
+     224             : 
+     225             :   //retrieve data of local atoms
+     226         450 :   const std::vector<int>& gatindex = domains->getGatindex();
+     227         450 :   nLocalAtoms = gatindex.size();
+     228         450 :   xpositions.resize( gatindex.size() ); posx->getLocalValues( xpositions );
+     229         450 :   ypositions.resize( gatindex.size() ); posy->getLocalValues( ypositions );
+     230         450 :   zpositions.resize( gatindex.size() ); posz->getLocalValues( zpositions );
+     231         450 :   positions.resize( gatindex.size() ); forces.resize( gatindex.size() );
+     232       16650 :   for(unsigned i=0; i<gatindex.size(); ++i ) {
+     233       16200 :     positions[i][0] = xpositions[i];
+     234       16200 :     positions[i][1] = ypositions[i];
+     235       16200 :     positions[i][2] = zpositions[i];
+     236       16200 :     forces[i][0] = (posx->copyOutput(0))->getForce( gatindex[i] );
+     237       16200 :     forces[i][1] = (posy->copyOutput(0))->getForce( gatindex[i] );
+     238       16200 :     forces[i][2] = (posz->copyOutput(0))->getForce( gatindex[i] );
+     239             :   }
+     240         450 :   if(pbc) {
+     241         450 :     Tensor B=tpbc.getBox();
+     242         450 :     Tensor IB=tpbc.getInvBox();
+     243         450 :     #pragma omp parallel for
+     244             :     for(unsigned i=0; i<positions.size(); ++i) {
+     245             :       positions[i]=matmul(positions[i],IB);
+     246             :       forces[i]=matmul(B,forces[i]);
+     247             :     }
+     248         450 :     box=B; Tensor virial; Value* boxValue = pbc_action->copyOutput(0);
+     249        5850 :     for(unsigned i=0; i<3; ++i) for(unsigned j=0; j<3; ++j) virial[i][j]=boxValue->getForce(3*i+j);
+     250         450 :     fbox=matmul(transpose(inverse(box)),virial);
+     251             :   }
+     252             : 
+     253             :   //init stored data at the first step
+     254         450 :   if(isFirstStep) {
+     255           9 :     pDdStep=0;
+     256           9 :     pGatindex = domains->getGatindex();
+     257           9 :     pNLocalAtoms = pGatindex.size();
+     258           9 :     pPositions=positions;
+     259           9 :     pForces=forces;
+     260           9 :     pbox=box;
+     261           9 :     pfbox=fbox;
+     262           9 :     initialBias=plumed.getBias();
+     263             : 
+     264           9 :     isFirstStep=false;
+     265             :   }
+     266             : 
+     267             :   //if the dd has changed we have to reshare the stored data
+     268         450 :   if(pDdStep<domains->getDdStep() && nLocalAtoms<(posx->copyOutput(0))->getShape()[0]) {
+     269             :     //prepare the data to be sent
+     270         204 :     indexS.resize(pNLocalAtoms);
+     271         204 :     dataS.resize(pNLocalAtoms*6);
+     272             : 
+     273        5712 :     for(int i=0; i<pNLocalAtoms; i++) {
+     274        5508 :       indexS[i] = pGatindex[i];
+     275        5508 :       dataS[i*6] = pPositions[i][0];
+     276        5508 :       dataS[i*6+1] = pPositions[i][1];
+     277        5508 :       dataS[i*6+2] = pPositions[i][2];
+     278        5508 :       dataS[i*6+3] = pForces[i][0];
+     279        5508 :       dataS[i*6+4] = pForces[i][1];
+     280        5508 :       dataS[i*6+5] = pForces[i][2];
+     281             :     }
+     282             : 
+     283             :     //setup the counters and displacements for the communication
+     284         204 :     plumed.comm.Allgather(&pNLocalAtoms,1,&indexCnt[0],1);
+     285         204 :     indexDsp[0] = 0;
+     286        1020 :     for(int i=0; i<nProc; i++) {
+     287         816 :       dataCnt[i] = indexCnt[i]*6;
+     288             : 
+     289         816 :       if(i+1<nProc) indexDsp[i+1] = indexDsp[i]+indexCnt[i];
+     290         816 :       dataDsp[i] = indexDsp[i]*6;
+     291             :     }
+     292             : 
+     293             :     //share stored data
+     294         402 :     plumed.comm.Allgatherv((!indexS.empty()?&indexS[0]:NULL), pNLocalAtoms, &indexR[0], &indexCnt[0], &indexDsp[0]);
+     295         402 :     plumed.comm.Allgatherv((!dataS.empty()?&dataS[0]:NULL), pNLocalAtoms*6, &dataR[0], &dataCnt[0], &dataDsp[0]);
+     296             : 
+     297             :     //resize vectors to store the proper amount of data
+     298         204 :     pGatindex.resize(nLocalAtoms);
+     299         204 :     pPositions.resize(nLocalAtoms);
+     300         204 :     pForces.resize(nLocalAtoms);
+     301             : 
+     302             :     //compute backmap
+     303       22236 :     for(unsigned j=0; j<indexR.size(); j++) backmap[indexR[j]]=j;
+     304             : 
+     305             :     //fill the vectors pGatindex, pPositions and pForces
+     306        5712 :     for(int i=0; i<nLocalAtoms; i++) {
+     307        5508 :       int glb=backmap[gatindex[i]];
+     308        5508 :       pGatindex[i] = indexR[glb];
+     309        5508 :       pPositions[i][0] = dataR[glb*6];
+     310        5508 :       pPositions[i][1] = dataR[glb*6+1];
+     311        5508 :       pPositions[i][2] = dataR[glb*6+2];
+     312        5508 :       pForces[i][0] = dataR[glb*6+3];
+     313        5508 :       pForces[i][1] = dataR[glb*6+4];
+     314        5508 :       pForces[i][2] = dataR[glb*6+5];
+     315             :     }
+     316             :   }
+     317             : 
+     318             :   //compute the effective energy drift on local atoms
+     319             : 
+     320         450 :   double eed_tmp=eed;
+     321         450 :   #pragma omp parallel for reduction(+:eed_tmp)
+     322             :   for(int i=0; i<nLocalAtoms; i++) {
+     323             :     Vector dst=delta(pPositions[i],positions[i]);
+     324             :     if(pbc) for(unsigned k=0; k<3; k++) dst[k]=Tools::pbc(dst[k]);
+     325             :     eed_tmp += dotProduct(dst, forces[i]+pForces[i])*0.5;
+     326             :   }
+     327             : 
+     328         450 :   eed=eed_tmp;
+     329             : 
+     330         450 :   if(plumed.comm.Get_rank()==0) {
+     331        1950 :     for(unsigned i=0; i<3; i++) for(unsigned j=0; j<3; j++)
+     332        1350 :         eed-=0.5*(pfbox(i,j)+fbox(i,j))*(box(i,j)-pbox(i,j));
+     333             :   }
+     334             : 
+     335             : 
+     336             :   //print the effective energy drift on FILE with frequency PRINT_STRIDE
+     337         450 :   if(plumed.getStep()%printStride==0) {
+     338         450 :     double eedSum = eed;
+     339             :     double bias = 0.0;
+     340             : 
+     341             :     //we cannot just use plumed.getBias() because it will be ==0.0 if PRINT_STRIDE
+     342             :     //is not a multiple of the bias actions stride
+     343         900 :     for(unsigned i=0; i<biases.size(); i++) bias+=biases[i]->getOutputQuantity("bias");
+     344             : 
+     345         450 :     plumed.comm.Sum(&eedSum,1);
+     346             : 
+     347         450 :     double effective = eedSum+bias-initialBias-plumed.getWork();
+     348             :     // this is to take into account ensemble averaging
+     349         450 :     if(ensemble) {
+     350           0 :       if(plumed.comm.Get_rank()==0) plumed.multi_sim_comm.Sum(&effective,1);
+     351           0 :       else effective=0.;
+     352           0 :       plumed.comm.Sum(&effective,1);
+     353             :     }
+     354         450 :     output.fmtField(" %f");
+     355         450 :     output.printField("time",getTime());
+     356         450 :     output.fmtField(fmt);
+     357         450 :     output.printField("effective-energy",effective);
+     358         450 :     output.printField();
+     359             :   }
+     360             : 
+     361             :   //store the data of the current step
+     362         450 :   pDdStep = domains->getDdStep();
+     363         450 :   pNLocalAtoms = nLocalAtoms;
+     364             :   pPositions.swap(positions);
+     365             :   pForces.swap(forces);
+     366         450 :   pbox=box;
+     367         450 :   pfbox=fbox;
+     368         450 : }
+     369             : 
+     370             : }
+     371             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/EndPlumed.cpp.func-sort-c.html b/coverage/generic/EndPlumed.cpp.func-sort-c.html new file mode 100644 index 000000000000..c397e196edad --- /dev/null +++ b/coverage/generic/EndPlumed.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - generic/EndPlumed.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - EndPlumed.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:81080.0 %
Date:2024-04-19 12:12:35Functions:2450.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic9EndPlumed5applyEv0
_ZN4PLMD7generic9EndPlumed9calculateEv0
_ZN4PLMD7generic9EndPlumedC2ERKNS_13ActionOptionsE281
_ZN4PLMD7generic9EndPlumed16registerKeywordsERNS_8KeywordsE283
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/EndPlumed.cpp.func.html b/coverage/generic/EndPlumed.cpp.func.html new file mode 100644 index 000000000000..4f716a4051b9 --- /dev/null +++ b/coverage/generic/EndPlumed.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - generic/EndPlumed.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - EndPlumed.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:81080.0 %
Date:2024-04-19 12:12:35Functions:2450.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic9EndPlumed16registerKeywordsERNS_8KeywordsE283
_ZN4PLMD7generic9EndPlumed5applyEv0
_ZN4PLMD7generic9EndPlumed9calculateEv0
_ZN4PLMD7generic9EndPlumedC2ERKNS_13ActionOptionsE281
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/EndPlumed.cpp.gcov.html b/coverage/generic/EndPlumed.cpp.gcov.html new file mode 100644 index 000000000000..fa05fc9857ef --- /dev/null +++ b/coverage/generic/EndPlumed.cpp.gcov.html @@ -0,0 +1,157 @@ + + + + + + + + LCOV - plumed test coverage - generic/EndPlumed.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - EndPlumed.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:81080.0 %
Date:2024-04-19 12:12:35Functions:2450.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2017-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionRegister.h"
+      23             : #include "core/ActionSet.h"
+      24             : #include "core/PlumedMain.h"
+      25             : 
+      26             : namespace PLMD {
+      27             : namespace generic {
+      28             : 
+      29             : //+PLUMEDOC GENERIC ENDPLUMED
+      30             : /*
+      31             : Terminate plumed input.
+      32             : 
+      33             : Can be used to effectively comment out the rest of the input file.
+      34             : It can be useful to quickly ignore part of a long input file. However,
+      35             : one should keep in mind that when opening the file it might be difficult to
+      36             : find where the commented out part begins. Regular comments (with `#`) are
+      37             : usually easier to read. Notice that \ref VimSyntax "VIM syntax" should be able
+      38             : to detect this command and properly mark the rest of the file as a comment,
+      39             : although since vim doesn't parse the whole file it might fail in doing so for long
+      40             : input files.
+      41             : 
+      42             : \par Examples
+      43             : 
+      44             : \plumedfile
+      45             : d: DISTANCE ATOMS=1,10
+      46             : PRINT ARG=d FILE=COLVAR STRIDE=10
+      47             : ENDPLUMED
+      48             : commands here are ignored
+      49             : PRINT ARG=d FILE=COLVAR STRIDE=1
+      50             : \endplumedfile
+      51             : 
+      52             : */
+      53             : //+ENDPLUMEDOC
+      54             : class EndPlumed:
+      55             :   public Action
+      56             : {
+      57             : public:
+      58             :   explicit EndPlumed(const ActionOptions&ao);
+      59             : /// Register all the relevant keywords for the action
+      60             :   static void registerKeywords( Keywords& keys );
+      61           0 :   void calculate() override {}
+      62           0 :   void apply() override {}
+      63             : };
+      64             : 
+      65             : PLUMED_REGISTER_ACTION(EndPlumed,"ENDPLUMED")
+      66             : 
+      67         283 : void EndPlumed::registerKeywords( Keywords& keys ) {
+      68         283 :   Action::registerKeywords( keys );
+      69         283 : }
+      70             : 
+      71         281 : EndPlumed::EndPlumed(const ActionOptions&ao):
+      72         281 :   Action(ao)
+      73             : {
+      74         281 :   checkRead();
+      75         281 :   plumed.setEndPlumed();
+      76         281 : }
+      77             : 
+      78             : }
+      79             : }
+      80             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/FitToTemplate.cpp.func-sort-c.html b/coverage/generic/FitToTemplate.cpp.func-sort-c.html new file mode 100644 index 000000000000..fe54edfa806d --- /dev/null +++ b/coverage/generic/FitToTemplate.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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:10410797.2 %
Date:2024-04-19 12:12:35Functions:5771.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic13FitToTemplate22getNumberOfDerivativesEv0
_ZN4PLMD7generic13FitToTemplateC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic13FitToTemplateC1ERKNS_13ActionOptionsE9
_ZN4PLMD7generic13FitToTemplate16registerKeywordsERNS_8KeywordsE11
_ZN4PLMD7generic13FitToTemplate15actionHasForcesEv55
_ZN4PLMD7generic13FitToTemplate5applyEv108
_ZN4PLMD7generic13FitToTemplate9calculateEv108
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/FitToTemplate.cpp.func.html b/coverage/generic/FitToTemplate.cpp.func.html new file mode 100644 index 000000000000..46bd3951a2d8 --- /dev/null +++ b/coverage/generic/FitToTemplate.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:10410797.2 %
Date:2024-04-19 12:12:35Functions:5771.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic13FitToTemplate15actionHasForcesEv55
_ZN4PLMD7generic13FitToTemplate16registerKeywordsERNS_8KeywordsE11
_ZN4PLMD7generic13FitToTemplate22getNumberOfDerivativesEv0
_ZN4PLMD7generic13FitToTemplate5applyEv108
_ZN4PLMD7generic13FitToTemplate9calculateEv108
_ZN4PLMD7generic13FitToTemplateC1ERKNS_13ActionOptionsE9
_ZN4PLMD7generic13FitToTemplateC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/FitToTemplate.cpp.gcov.html b/coverage/generic/FitToTemplate.cpp.gcov.html new file mode 100644 index 000000000000..05c7b21508a1 --- /dev/null +++ b/coverage/generic/FitToTemplate.cpp.gcov.html @@ -0,0 +1,461 @@ + + + + + + + + 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:10410797.2 %
Date:2024-04-19 12:12:35Functions:5771.4 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2014-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionAtomistic.h"
+      23             : #include "core/ActionPilot.h"
+      24             : #include "core/ActionRegister.h"
+      25             : #include "core/ActionWithValue.h"
+      26             : #include "tools/Vector.h"
+      27             : #include "tools/Matrix.h"
+      28             : #include "tools/AtomNumber.h"
+      29             : #include "tools/Tools.h"
+      30             : #include "tools/RMSD.h"
+      31             : #include "core/PlumedMain.h"
+      32             : #include "core/ActionSet.h"
+      33             : #include "core/GenericMolInfo.h"
+      34             : #include "core/PbcAction.h"
+      35             : #include "tools/PDB.h"
+      36             : #include "tools/Pbc.h"
+      37             : 
+      38             : #include <vector>
+      39             : #include <string>
+      40             : #include <memory>
+      41             : 
+      42             : namespace PLMD {
+      43             : namespace generic {
+      44             : 
+      45             : //+PLUMEDOC GENERIC FIT_TO_TEMPLATE
+      46             : /*
+      47             : This action is used to align a molecule to a template.
+      48             : 
+      49             : This can be used to move the coordinates stored in plumed
+      50             : so as to be aligned with a provided template in PDB format. Pdb should contain
+      51             : also weights for alignment (see the format of PDB files used e.g. for \ref RMSD).
+      52             : Make sure your PDB file is correctly formatted as explained \ref pdbreader "in this page".
+      53             : Weights for displacement are ignored, since no displacement is computed here.
+      54             : Notice that all atoms (not only those in the template) are aligned.
+      55             : To see what effect try
+      56             : the \ref DUMPATOMS directive to output the atomic positions.
+      57             : 
+      58             : Also notice that PLUMED propagate forces correctly so that you can add a bias on a CV computed
+      59             : after alignment. For many CVs this has no effect, but in some case the alignment can
+      60             : change the result. Examples are:
+      61             : - \ref POSITION CV since it is affected by a rigid shift of the system.
+      62             : - \ref DISTANCE CV with COMPONENTS. Since the alignment could involve a rotation (with TYPE=OPTIMAL) the actual components could be different
+      63             :   from the original ones.
+      64             : - \ref CELL components for a similar reason.
+      65             : - \ref DISTANCE from a \ref FIXEDATOM, provided the fixed atom is introduced _after_ the \ref FIT_TO_TEMPLATE action.
+      66             : 
+      67             : \attention
+      68             : The implementation of TYPE=OPTIMAL is available but should be considered in testing phase. Please report any
+      69             : strange behavior.
+      70             : 
+      71             : \attention
+      72             : This directive modifies the stored position at the precise moment
+      73             : it is executed. This means that only collective variables
+      74             : which are below it in the input script will see the corrected positions.
+      75             : As a general rule, put it at the top of the input file. Also, unless you
+      76             : know exactly what you are doing, leave the default stride (1), so that
+      77             : this action is performed at every MD step.
+      78             : 
+      79             : When running with periodic boundary conditions, the atoms should be
+      80             : in the proper periodic image. This is done automatically since PLUMED 2.5,
+      81             : by considering the ordered list of atoms and rebuilding the molecules using a procedure
+      82             : that is equivalent to that done in \ref WHOLEMOLECULES . Notice that
+      83             : rebuilding is local to this action. This is different from \ref WHOLEMOLECULES
+      84             : which actually modifies the coordinates stored in PLUMED.
+      85             : 
+      86             : In case you want to recover the old behavior you should use the NOPBC flag.
+      87             : In that case you need to take care that atoms are in the correct
+      88             : periodic image.
+      89             : 
+      90             : \par Examples
+      91             : 
+      92             : Align the atomic position to a template then print them.
+      93             : The following example is only translating the system so as
+      94             : to align the center of mass of a molecule to the one in the reference
+      95             : structure `ref.pdb`:
+      96             : \plumedfile
+      97             : # dump coordinates before fitting, to see the difference:
+      98             : DUMPATOMS FILE=dump-before.xyz ATOMS=1-20
+      99             : 
+     100             : # fit coordinates to ref.pdb template
+     101             : # this is a "TYPE=SIMPLE" fit, so that only translations are used.
+     102             : FIT_TO_TEMPLATE STRIDE=1 REFERENCE=ref.pdb TYPE=SIMPLE
+     103             : 
+     104             : # dump coordinates after fitting, to see the difference:
+     105             : DUMPATOMS FILE=dump-after.xyz ATOMS=1-20
+     106             : \endplumedfile
+     107             : 
+     108             : The following example instead performs a rototranslational fit.
+     109             : \plumedfile
+     110             : # dump coordinates before fitting, to see the difference:
+     111             : DUMPATOMS FILE=dump-before.xyz ATOMS=1-20
+     112             : 
+     113             : # fit coordinates to ref.pdb template
+     114             : # this is a "TYPE=OPTIMAL" fit, so that rototranslations are used.
+     115             : FIT_TO_TEMPLATE STRIDE=1 REFERENCE=ref.pdb TYPE=OPTIMAL
+     116             : 
+     117             : # dump coordinates after fitting, to see the difference:
+     118             : DUMPATOMS FILE=dump-after.xyz ATOMS=1-20
+     119             : \endplumedfile
+     120             : 
+     121             : In both these cases the reference structure should be provided in a reference pdb file such as the one below:
+     122             : 
+     123             : \auxfile{ref.pdb}
+     124             : ATOM      8  HT3 ALA     2      -1.480  -1.560   1.212  1.00  1.00      DIA  H
+     125             : ATOM      9  CAY ALA     2      -0.096   2.144  -0.669  1.00  1.00      DIA  C
+     126             : ATOM     10  HY1 ALA     2       0.871   2.385  -0.588  1.00  1.00      DIA  H
+     127             : ATOM     12  HY3 ALA     2      -0.520   2.679  -1.400  1.00  1.00      DIA  H
+     128             : ATOM     14  OY  ALA     2      -1.139   0.931  -0.973  1.00  1.00      DIA  O
+     129             : END
+     130             : \endauxfile
+     131             : 
+     132             : In the following example you see two completely equivalent way
+     133             : to restrain an atom close to a position that is defined in the reference
+     134             : frame of an aligned molecule. You could for instance use this command to calculate the
+     135             : position of the center of mass of a ligand after having aligned the atoms to the reference
+     136             : frame of the protein that is determined by aligning the atoms in the protein to the coordinates
+     137             : provided in the file ref.pdb
+     138             : \plumedfile
+     139             : # center of the ligand:
+     140             : center: CENTER ATOMS=100-110
+     141             : 
+     142             : FIT_TO_TEMPLATE REFERENCE=ref.pdb TYPE=OPTIMAL
+     143             : 
+     144             : # place a fixed atom in the protein reference coordinates:
+     145             : fix: FIXEDATOM AT=1.0,1.1,1.0
+     146             : 
+     147             : # take the distance between the fixed atom and the center of the ligand
+     148             : d: DISTANCE ATOMS=center,fix
+     149             : 
+     150             : # apply a restraint
+     151             : RESTRAINT ARG=d AT=0.0 KAPPA=100.0
+     152             : \endplumedfile
+     153             : 
+     154             : Notice that you could have obtained an (almost) identical result by adding a fictitious
+     155             : atom to `ref.pdb` with the serial number corresponding to the atom labelled `center` (there is no automatic way
+     156             : to get it, but in this example it should be the number of atoms of the system plus one),
+     157             : and properly setting the weights for alignment and displacement in \ref RMSD.
+     158             : There are two differences to be expected:
+     159             : (ab) \ref FIT_TO_TEMPLATE might be slower since it has to rototranslate all the available atoms and
+     160             : (b) variables employing periodic boundary conditions (such as \ref DISTANCE without `NOPBC`, as in the example above)
+     161             :   are allowed after \ref FIT_TO_TEMPLATE, whereas \ref RMSD expects the issues related to the periodic boundary conditions to be already solved.
+     162             : The latter means that before the \ref RMSD statement one should use \ref WRAPAROUND or \ref WHOLEMOLECULES to properly place
+     163             : the ligand.
+     164             : 
+     165             : 
+     166             : */
+     167             : //+ENDPLUMEDOC
+     168             : 
+     169             : 
+     170             : class FitToTemplate:
+     171             :   public ActionPilot,
+     172             :   public ActionAtomistic,
+     173             :   public ActionWithValue
+     174             : {
+     175             :   std::string type;
+     176             :   bool nopbc;
+     177             :   std::vector<double> weights;
+     178             :   std::vector<std::pair<std::size_t,std::size_t> > p_aligned;
+     179             :   Vector center;
+     180             :   Vector shift;
+     181             :   // optimal alignment related stuff
+     182             :   std::unique_ptr<PLMD::RMSD> rmsd;
+     183             :   Tensor rotation;
+     184             :   Matrix< std::vector<Vector> > drotdpos;
+     185             :   // not used anymore (see notes below at doNotRetrieve())
+     186             :   // std::vector<Vector> positions;
+     187             :   std::vector<Vector> DDistDRef;
+     188             :   std::vector<Vector> ddistdpos;
+     189             :   std::vector<Vector> centeredpositions;
+     190             :   Vector center_positions;
+     191             :   // Copy of the box value
+     192             :   Value* boxValue;
+     193             :   PbcAction* pbc_action;
+     194             : public:
+     195             :   explicit FitToTemplate(const ActionOptions&ao);
+     196             :   static void registerKeywords( Keywords& keys );
+     197          55 :   bool actionHasForces() override { return true; }
+     198             :   void calculate() override;
+     199             :   void apply() override;
+     200           0 :   unsigned getNumberOfDerivatives() override {plumed_merror("You should not call this function");};
+     201             : };
+     202             : 
+     203             : PLUMED_REGISTER_ACTION(FitToTemplate,"FIT_TO_TEMPLATE")
+     204             : 
+     205          11 : void FitToTemplate::registerKeywords( Keywords& keys ) {
+     206          11 :   Action::registerKeywords( keys );
+     207          11 :   ActionAtomistic::registerKeywords( keys );
+     208          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!");
+     209          22 :   keys.add("compulsory","REFERENCE","a file in pdb format containing the reference structure and the atoms involved in the CV.");
+     210          22 :   keys.add("compulsory","TYPE","SIMPLE","the manner in which RMSD alignment is performed.  Should be OPTIMAL or SIMPLE.");
+     211          22 :   keys.addFlag("NOPBC",false,"ignore the periodic boundary conditions when calculating distances");
+     212          11 : }
+     213             : 
+     214           9 : FitToTemplate::FitToTemplate(const ActionOptions&ao):
+     215             :   Action(ao),
+     216             :   ActionPilot(ao),
+     217             :   ActionAtomistic(ao),
+     218             :   ActionWithValue(ao),
+     219          18 :   nopbc(false)
+     220             : {
+     221             :   std::string reference;
+     222           9 :   parse("REFERENCE",reference);
+     223           9 :   type.assign("SIMPLE");
+     224           9 :   parse("TYPE",type);
+     225             : 
+     226           9 :   parseFlag("NOPBC",nopbc);
+     227             : // if(type!="SIMPLE") error("Only TYPE=SIMPLE is implemented in FIT_TO_TEMPLATE");
+     228             : 
+     229           9 :   checkRead();
+     230             : 
+     231           9 :   PDB pdb;
+     232             : 
+     233             :   // read everything in ang and transform to nm if we are not in natural units
+     234           9 :   if( !pdb.read(reference,usingNaturalUnits(),0.1/getUnits().getLength()) )
+     235           0 :     error("missing input file " + reference );
+     236             : 
+     237           9 :   requestAtoms(pdb.getAtomNumbers());
+     238           9 :   log.printf("  found %zu atoms in input \n",pdb.getAtomNumbers().size());
+     239           9 :   log.printf("  with indices : ");
+     240          42 :   for(unsigned i=0; i<pdb.getAtomNumbers().size(); ++i) {
+     241          33 :     if(i%25==0) log<<"\n";
+     242          33 :     log.printf("%d ",pdb.getAtomNumbers()[i].serial());
+     243             :   }
+     244           9 :   log.printf("\n");
+     245             : 
+     246           9 :   std::vector<Vector> positions=pdb.getPositions();
+     247           9 :   weights=pdb.getOccupancy();
+     248           9 :   std::vector<AtomNumber> aligned=pdb.getAtomNumbers(); p_aligned.resize( aligned.size() );
+     249          42 :   for(unsigned i=0; i<aligned.size(); ++i) p_aligned[i] = getValueIndices( aligned[i] );
+     250             : 
+     251             : 
+     252             :   // normalize weights
+     253          42 :   double n=0.0; for(unsigned i=0; i<weights.size(); ++i) n+=weights[i];
+     254           9 :   if(n==0.0) {
+     255           0 :     error("PDB file " + reference + " has zero weights. Please check the occupancy column.");
+     256             :   }
+     257           9 :   n=1.0/n;
+     258          42 :   for(unsigned i=0; i<weights.size(); ++i) weights[i]*=n;
+     259             : 
+     260             :   // normalize weights for rmsd calculation
+     261           9 :   std::vector<double> weights_measure=pdb.getBeta();
+     262          42 :   n=0.0; for(unsigned i=0; i<weights_measure.size(); ++i) n+=weights_measure[i]; n=1.0/n;
+     263          42 :   for(unsigned i=0; i<weights_measure.size(); ++i) weights_measure[i]*=n;
+     264             : 
+     265             :   // subtract the center
+     266          42 :   for(unsigned i=0; i<weights.size(); ++i) center+=positions[i]*weights[i];
+     267          42 :   for(unsigned i=0; i<weights.size(); ++i) positions[i]-=center;
+     268             : 
+     269          13 :   if(type=="OPTIMAL" or type=="OPTIMAL-FAST" ) {
+     270           5 :     rmsd=Tools::make_unique<RMSD>();
+     271           5 :     rmsd->set(weights,weights_measure,positions,type,false,false);// note: the reference is shifted now with center in the origin
+     272          10 :     log<<"  Method chosen for fitting: "<<rmsd->getMethod()<<" \n";
+     273             :   }
+     274           9 :   if(nopbc) {
+     275           1 :     log<<"  Ignoring PBCs when doing alignment, make sure your molecule is whole!<n";
+     276             :   }
+     277             :   // register the value of rmsd (might be useful sometimes)
+     278          18 :   addValue(); setNotPeriodic();
+     279             : 
+     280             :   // I remove this optimization now in order to use makeWhole()
+     281             :   // Notice that for FIT_TO_TEMPLATE TYPE=OPTIMAL a copy was made anyway
+     282             :   // (due to the need to store position to propagate forces on rotational matrix later)
+     283             :   // For FIT_TO_TEMPLATE TYPE=SIMPLE in principle we could use it and write an ad hoc
+     284             :   // version of makeWhole that only computes the center. Too lazy to do it now.
+     285             :   // In case we do it later, remember that uncommenting this line means that
+     286             :   // getPositions will not work anymore! GB
+     287             :   // doNotRetrieve();
+     288             : 
+     289             :   // this is required so as to allow modifyGlobalForce() to return correct
+     290             :   // also for forces that are not owned (and thus not zeored) by all processors.
+     291           9 :   pbc_action=plumed.getActionSet().selectWithLabel<PbcAction*>("Box");
+     292           9 :   if( !pbc_action ) error("cannot align box has not been set");
+     293           9 :   boxValue=pbc_action->copyOutput(0);
+     294          18 : }
+     295             : 
+     296             : 
+     297         108 : void FitToTemplate::calculate() {
+     298             : 
+     299         108 :   if(!nopbc) makeWhole();
+     300             : 
+     301         108 :   if (type=="SIMPLE") {
+     302          48 :     Vector cc;
+     303             : 
+     304         144 :     for(unsigned i=0; i<p_aligned.size(); ++i) {
+     305          96 :       cc+=weights[i]*getPosition(i);
+     306             :     }
+     307             : 
+     308          48 :     shift=center-cc;
+     309          48 :     setValue(shift.modulo());
+     310          48 :     unsigned nat = getTotAtoms();
+     311        6384 :     for(unsigned i=0; i<nat; i++) {
+     312        6336 :       std::pair<std::size_t,std::size_t> a = getValueIndices( AtomNumber::index(i));
+     313        6336 :       Vector ato=getGlobalPosition(a);
+     314        6336 :       setGlobalPosition(a,ato+shift);
+     315             :     }
+     316             :   }
+     317          60 :   else if( type=="OPTIMAL" or type=="OPTIMAL-FAST") {
+     318             :     // specific stuff that provides all that is needed
+     319          60 :     double r=rmsd->calc_FitElements( getPositions(), rotation,  drotdpos, centeredpositions, center_positions);
+     320          60 :     setValue(r); unsigned nat = getTotAtoms();
+     321        8004 :     for(unsigned i=0; i<nat; i++) {
+     322        7944 :       std::pair<std::size_t,std::size_t> a = getValueIndices( AtomNumber::index(i));
+     323        7944 :       Vector ato=getGlobalPosition(a);
+     324        7944 :       setGlobalPosition(a,matmul(rotation,ato-center_positions)+center);
+     325             :     }
+     326             : // rotate box
+     327          60 :     Pbc& pbc(pbc_action->getPbc());
+     328          60 :     pbc.setBox(matmul(pbc_action->getPbc().getBox(),transpose(rotation)));
+     329             :   }
+     330         108 : }
+     331             : 
+     332         108 : void FitToTemplate::apply() {
+     333         108 :   auto nat=getTotAtoms();
+     334         108 :   if (type=="SIMPLE") {
+     335          48 :     Vector totForce;
+     336        6384 :     for(unsigned i=0; i<nat; i++) {
+     337        6336 :       std::pair<std::size_t,std::size_t> a = getValueIndices( AtomNumber::index(i));
+     338        6336 :       totForce+=getForce(a);
+     339             :     }
+     340          48 :     Tensor vv=Tensor(center,totForce);
+     341         624 :     for(unsigned i=0; i<3; ++i) for(unsigned j=0; j<3; ++j) boxValue->addForce( 3*i+j, vv(i,j) );
+     342         144 :     for(unsigned i=0; i<p_aligned.size(); ++i) { addForce( p_aligned[i], -totForce*weights[i]); }
+     343          60 :   } else if ( type=="OPTIMAL" or type=="OPTIMAL-FAST") {
+     344          60 :     Vector totForce;
+     345        8004 :     for(unsigned i=0; i<nat; i++) {
+     346        7944 :       std::pair<std::size_t,std::size_t> a = getValueIndices( AtomNumber::index(i));
+     347        7944 :       Vector f=getForce(a);
+     348             : // rotate back forces
+     349        7944 :       Vector nf=matmul(transpose(rotation),f);
+     350        7944 :       addForce(a, nf-f);
+     351             : // accumulate rotated c.o.m. forces - this is already in the non rotated reference frame
+     352        7944 :       totForce+=nf;
+     353             :     }
+     354          60 :     Tensor virial;
+     355         780 :     for(unsigned i=0; i<3; ++i) for(unsigned j=0; j<3; ++j) virial[i][j] = boxValue->getForce( 3*i+j );
+     356             : // notice that an extra Tensor(center,matmul(rotation,totForce)) is required to
+     357             : // compute the derivatives of the rotation with respect to center
+     358          60 :     Tensor ww=matmul(transpose(rotation),virial+Tensor(center,matmul(rotation,totForce)));
+     359             : // rotate back virial
+     360          60 :     virial=matmul(transpose(rotation),matmul(virial,rotation));
+     361             : 
+     362             : // now we compute the force due to alignment
+     363         360 :     for(unsigned i=0; i<p_aligned.size(); i++) {
+     364         300 :       Vector g;
+     365        1200 :       for(unsigned k=0; k<3; k++) {
+     366             : // this could be made faster computing only the diagonal of d
+     367         900 :         Tensor d=matmul(ww,RMSD::getMatrixFromDRot(drotdpos,i,k));
+     368         900 :         g[k]=(d(0,0)+d(1,1)+d(2,2));
+     369             :       }
+     370             : // here is the extra contribution
+     371         300 :       addForce( p_aligned[i], -g-weights[i]*totForce );
+     372             : // here it the contribution to the virial
+     373             : // notice that here we can use absolute positions since, for the alignment to be defined,
+     374             : // positions should be in one well defined periodic image
+     375         300 :       virial+=extProduct(getPosition(i),g);
+     376             :     }
+     377             : // finally, correction to the virial
+     378         120 :     boxValue->clearInputForce(); virial+=extProduct(matmul(transpose(rotation),center),totForce);
+     379         780 :     for(unsigned i=0; i<3; ++i) for(unsigned j=0; j<3; ++j) boxValue->addForce( 3*i+j, virial(i,j) );
+     380             :   }
+     381         108 : }
+     382             : 
+     383             : }
+     384             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/Flush.cpp.func-sort-c.html b/coverage/generic/Flush.cpp.func-sort-c.html new file mode 100644 index 000000000000..b77d976b056a --- /dev/null +++ b/coverage/generic/Flush.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - generic/Flush.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - Flush.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1919100.0 %
Date:2024-04-19 12:12:35Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic5FlushC1ERKNS_13ActionOptionsE17
_ZN4PLMD7generic5Flush16registerKeywordsERNS_8KeywordsE19
_ZN4PLMD7generic5Flush5applyEv561
_ZN4PLMD7generic5Flush6updateEv561
_ZN4PLMD7generic5Flush9calculateEv561
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/Flush.cpp.func.html b/coverage/generic/Flush.cpp.func.html new file mode 100644 index 000000000000..caf31821c8fa --- /dev/null +++ b/coverage/generic/Flush.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - generic/Flush.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - Flush.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1919100.0 %
Date:2024-04-19 12:12:35Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic5Flush16registerKeywordsERNS_8KeywordsE19
_ZN4PLMD7generic5Flush5applyEv561
_ZN4PLMD7generic5Flush6updateEv561
_ZN4PLMD7generic5Flush9calculateEv561
_ZN4PLMD7generic5FlushC1ERKNS_13ActionOptionsE17
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/Flush.cpp.gcov.html b/coverage/generic/Flush.cpp.gcov.html new file mode 100644 index 000000000000..e664f30a6518 --- /dev/null +++ b/coverage/generic/Flush.cpp.gcov.html @@ -0,0 +1,168 @@ + + + + + + + + LCOV - plumed test coverage - generic/Flush.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - Flush.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1919100.0 %
Date:2024-04-19 12:12:35Functions:55100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionRegister.h"
+      23             : #include "core/ActionPilot.h"
+      24             : #include "core/PlumedMain.h"
+      25             : #include "core/ActionSet.h"
+      26             : 
+      27             : namespace PLMD {
+      28             : namespace generic {
+      29             : 
+      30             : //+PLUMEDOC GENERIC FLUSH
+      31             : /*
+      32             : This command instructs plumed to flush all the open files with a user specified frequency.
+      33             : Notice that all files are flushed anyway every 10000 steps.
+      34             : 
+      35             : This
+      36             : is useful for preventing data loss that would otherwise arise as a consequence of the code
+      37             : storing data for printing in the buffers. Notice that wherever it is written in the
+      38             : plumed input file, it will flush all the open files.
+      39             : 
+      40             : \par Examples
+      41             : 
+      42             : A command like this in the input will instruct plumed to flush all the output files every 100 steps
+      43             : \plumedfile
+      44             : d1: DISTANCE ATOMS=1,10
+      45             : PRINT ARG=d1 STRIDE=5 FILE=colvar1
+      46             : 
+      47             : FLUSH STRIDE=100
+      48             : 
+      49             : d2: DISTANCE ATOMS=2,11
+      50             : # also this print is flushed every 100 steps:
+      51             : PRINT ARG=d2 STRIDE=10 FILE=colvar2
+      52             : \endplumedfile
+      53             : (see also \ref DISTANCE and \ref PRINT).
+      54             : */
+      55             : //+ENDPLUMEDOC
+      56             : 
+      57             : class Flush:
+      58             :   public ActionPilot
+      59             : {
+      60             : public:
+      61          17 :   explicit Flush(const ActionOptions&ao):
+      62             :     Action(ao),
+      63          17 :     ActionPilot(ao)
+      64             :   {
+      65          17 :     checkRead();
+      66          17 :   }
+      67             :   static void registerKeywords( Keywords& keys );
+      68         561 :   void calculate() override {}
+      69         561 :   void apply() override {}
+      70         561 :   void update() override {
+      71         561 :     plumed.fflush();
+      72         561 :     log.flush();
+      73         561 :     const ActionSet & actionSet(plumed.getActionSet());
+      74        9527 :     for(const auto & p : actionSet)
+      75        8966 :       p->fflush();
+      76         561 :   }
+      77             : };
+      78             : 
+      79             : PLUMED_REGISTER_ACTION(Flush,"FLUSH")
+      80             : 
+      81          19 : void Flush::registerKeywords( Keywords& keys ) {
+      82          19 :   Action::registerKeywords( keys );
+      83          19 :   ActionPilot::registerKeywords( keys );
+      84          38 :   keys.add("compulsory","STRIDE","the frequency with which all the open files should be flushed");
+      85          19 :   keys.remove("LABEL");
+      86          19 : }
+      87             : 
+      88             : }
+      89             : }
+      90             : 
+      91             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/Include.cpp.func-sort-c.html b/coverage/generic/Include.cpp.func-sort-c.html new file mode 100644 index 000000000000..ad5e7daa30e4 --- /dev/null +++ b/coverage/generic/Include.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - generic/Include.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - Include.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:101283.3 %
Date:2024-04-19 12:12:35Functions:2540.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic7Include5applyEv0
_ZN4PLMD7generic7Include9calculateEv0
_ZN4PLMD7generic7IncludeC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic7IncludeC1ERKNS_13ActionOptionsE23
_ZN4PLMD7generic7Include16registerKeywordsERNS_8KeywordsE25
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/Include.cpp.func.html b/coverage/generic/Include.cpp.func.html new file mode 100644 index 000000000000..e219eb065d44 --- /dev/null +++ b/coverage/generic/Include.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - generic/Include.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - Include.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:101283.3 %
Date:2024-04-19 12:12:35Functions:2540.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic7Include16registerKeywordsERNS_8KeywordsE25
_ZN4PLMD7generic7Include5applyEv0
_ZN4PLMD7generic7Include9calculateEv0
_ZN4PLMD7generic7IncludeC1ERKNS_13ActionOptionsE23
_ZN4PLMD7generic7IncludeC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/Include.cpp.gcov.html b/coverage/generic/Include.cpp.gcov.html new file mode 100644 index 000000000000..42cb0a47e462 --- /dev/null +++ b/coverage/generic/Include.cpp.gcov.html @@ -0,0 +1,256 @@ + + + + + + + + LCOV - plumed test coverage - generic/Include.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - Include.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:101283.3 %
Date:2024-04-19 12:12:35Functions:2540.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/Action.h"
+      23             : #include "core/ActionAnyorder.h"
+      24             : #include "core/ActionRegister.h"
+      25             : #include "core/PlumedMain.h"
+      26             : #include "tools/Exception.h"
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace generic {
+      30             : 
+      31             : //+PLUMEDOC GENERIC INCLUDE
+      32             : /*
+      33             : Includes an external input file, similar to #include in C preprocessor.
+      34             : 
+      35             : Useful to split very large plumed.dat files. Notice that in PLUMED 2.4 this action
+      36             : cannot be used before the initial setup part of the file (e.g. in the part with \ref UNITS, \ref MOLINFO, etc).
+      37             : As of PLUMED 2.5, \ref INCLUDE can be used in any position of the file.
+      38             : 
+      39             : \par Examples
+      40             : 
+      41             : This input:
+      42             : \plumedfile
+      43             : c1: COM ATOMS=1-100
+      44             : c2: COM ATOMS=101-202
+      45             : d: DISTANCE ATOMS=c1,c2
+      46             : PRINT ARG=d
+      47             : \endplumedfile
+      48             : can be replaced with this input:
+      49             : \plumedfile
+      50             : INCLUDE FILE=pippo.dat
+      51             : d: DISTANCE ATOMS=c1,c2
+      52             : PRINT ARG=d
+      53             : \endplumedfile
+      54             : where the content of file pippo.dat is
+      55             : \plumedfile
+      56             : #SETTINGS FILENAME=pippo.dat
+      57             : # this is pippo.dat
+      58             : c1: COM ATOMS=1-100
+      59             : c2: COM ATOMS=101-202
+      60             : \endplumedfile
+      61             : 
+      62             : The files in this example are rather short, but imagine a case like this one:
+      63             : \plumedfile
+      64             : INCLUDE FILE=groups.dat
+      65             : c: COORDINATION GROUPA=groupa GROUPB=groupb R_0=0.5
+      66             : METAD ARG=c HEIGHT=0.2 PACE=100 SIGMA=0.2 BIASFACTOR=5
+      67             : \endplumedfile
+      68             : Here `groups.dat` could be a huge file containing group definitions.  This groups.dat file might look something
+      69             : like the following example but with more atom indices in the groups.
+      70             : \plumedfile
+      71             : #SETTINGS FILENAME=groups.dat
+      72             : # this is groups.dat
+      73             : groupa: GROUP ...
+      74             :   ATOMS={
+      75             :     10
+      76             :     50
+      77             :     60
+      78             :     70
+      79             :     80
+      80             :     120
+      81             :   }
+      82             : ...
+      83             : groupb: GROUP ...
+      84             :   ATOMS={
+      85             :     11
+      86             :     51
+      87             :     61
+      88             :     71
+      89             :     81
+      90             :     121
+      91             :   }
+      92             : ...
+      93             : \endplumedfile
+      94             : So, included files are the best place where one can store long definitions.
+      95             : 
+      96             : Another case where INCLUDE is very useful is when running multi-replica simulations.
+      97             : Here different replicas might have different input files, but perhaps a large part of the
+      98             : input is shared. This part can be put in a common included file. For instance you could have
+      99             : `common.dat`:
+     100             : \plumedfile
+     101             : #SETTINGS FILENAME=common.dat
+     102             : # this is common.dat
+     103             : t: TORSION ATOMS=1,2,3,4
+     104             : \endplumedfile
+     105             : Then `plumed.0.dat`:
+     106             : \plumedfile
+     107             : # this is plumed.0.dat
+     108             : INCLUDE FILE=common.dat
+     109             : RESTRAINT ARG=t AT=1.0 KAPPA=10
+     110             : \endplumedfile
+     111             : And `plumed.1.dat`:
+     112             : \plumedfile
+     113             : # this is plumed.1.dat
+     114             : INCLUDE FILE=common.dat
+     115             : RESTRAINT ARG=t AT=1.2 KAPPA=10
+     116             : \endplumedfile
+     117             : 
+     118             : \warning
+     119             : Remember that when using multi replica simulations whenever plumed tried to open
+     120             : a file for reading it looks for a file with the replica suffix first.
+     121             : This is true also for files opened by INCLUDE!
+     122             : 
+     123             : As an example, the same result of the inputs above could have been obtained using
+     124             : the following `plumed.dat` file:
+     125             : \plumedfile
+     126             : #SETTINGS NREPLICAS=2
+     127             : t: TORSION ATOMS=1,2,3,4
+     128             : INCLUDE FILE=other.inc
+     129             : \endplumedfile
+     130             : Then `other.0.inc`:
+     131             : \plumedfile
+     132             : #SETTINGS FILENAME=other.0.inc
+     133             : # this is other.0.inc
+     134             : RESTRAINT ARG=t AT=1.0 KAPPA=10
+     135             : \endplumedfile
+     136             : And `other.1.inc`:
+     137             : \plumedfile
+     138             : #SETTINGS FILENAME=other.1.inc
+     139             : # this is other.1.inc
+     140             : RESTRAINT ARG=t AT=1.2 KAPPA=10
+     141             : \endplumedfile
+     142             : 
+     143             : 
+     144             : 
+     145             : 
+     146             : 
+     147             : */
+     148             : //+ENDPLUMEDOC
+     149             : 
+     150             : class Include :
+     151             :   public ActionAnyorder
+     152             : {
+     153             : public:
+     154             :   static void registerKeywords( Keywords& keys );
+     155             :   explicit Include(const ActionOptions&ao);
+     156           0 :   void calculate() override {}
+     157           0 :   void apply() override {}
+     158             : };
+     159             : 
+     160             : PLUMED_REGISTER_ACTION(Include,"INCLUDE")
+     161             : 
+     162          25 : void Include::registerKeywords( Keywords& keys ) {
+     163          25 :   Action::registerKeywords(keys);
+     164          50 :   keys.add("compulsory","FILE","file to be included");
+     165          25 : }
+     166             : 
+     167          23 : Include::Include(const ActionOptions&ao):
+     168             :   Action(ao),
+     169          23 :   ActionAnyorder(ao)
+     170             : {
+     171             :   std::string f;
+     172          23 :   parse("FILE",f);
+     173          23 :   checkRead();
+     174          23 :   plumed.readInputFile(f);
+     175          23 : }
+     176             : 
+     177             : }
+     178             : }
+     179             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/Ones.cpp.func-sort-c.html b/coverage/generic/Ones.cpp.func-sort-c.html new file mode 100644 index 000000000000..784b9ee7b783 --- /dev/null +++ b/coverage/generic/Ones.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - generic/Ones.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - Ones.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1111100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic4OnesC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic4OnesC1ERKNS_13ActionOptionsE252
_ZN4PLMD7generic4Ones16registerKeywordsERNS_8KeywordsE257
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/Ones.cpp.func.html b/coverage/generic/Ones.cpp.func.html new file mode 100644 index 000000000000..e6b3127cc8de --- /dev/null +++ b/coverage/generic/Ones.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - generic/Ones.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - Ones.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1111100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic4Ones16registerKeywordsERNS_8KeywordsE257
_ZN4PLMD7generic4OnesC1ERKNS_13ActionOptionsE252
_ZN4PLMD7generic4OnesC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/Ones.cpp.gcov.html b/coverage/generic/Ones.cpp.gcov.html new file mode 100644 index 000000000000..9c47dfe24d55 --- /dev/null +++ b/coverage/generic/Ones.cpp.gcov.html @@ -0,0 +1,138 @@ + + + + + + + + LCOV - plumed test coverage - generic/Ones.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - Ones.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1111100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionShortcut.h"
+      23             : #include "core/ActionRegister.h"
+      24             : 
+      25             : namespace PLMD {
+      26             : namespace generic {
+      27             : 
+      28             : //+PLUMEDOC COLVAR ONES
+      29             : /*
+      30             : Create a constant vector with all elements equal to one
+      31             : 
+      32             : \par Examples
+      33             : 
+      34             : */
+      35             : //+ENDPLUMEDOC
+      36             : 
+      37             : class Ones : public ActionShortcut {
+      38             : public:
+      39             :   static void registerKeywords(Keywords& keys);
+      40             :   explicit Ones(const ActionOptions&);
+      41             : };
+      42             : 
+      43             : PLUMED_REGISTER_ACTION(Ones,"ONES")
+      44             : 
+      45         257 : void Ones::registerKeywords(Keywords& keys) {
+      46         257 :   ActionShortcut::registerKeywords( keys );
+      47         514 :   keys.add("compulsory","SIZE","the number of ones that you would like to create");
+      48         257 :   keys.needsAction("CONSTANT");
+      49         257 : }
+      50             : 
+      51         252 : Ones::Ones(const ActionOptions& ao):
+      52             :   Action(ao),
+      53         252 :   ActionShortcut(ao)
+      54             : {
+      55         504 :   unsigned size; parse("SIZE",size); if( size<1 ) error("size should be greater than 0");
+      56      110541 :   std::string ones="1"; for(unsigned i=1; i<size; ++i) ones +=",1";
+      57         504 :   readInputLine( getShortcutLabel() + ": CONSTANT NOLOG VALUES=" + ones );
+      58         252 : }
+      59             : 
+      60             : }
+      61             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/PDB2Constant.cpp.func-sort-c.html b/coverage/generic/PDB2Constant.cpp.func-sort-c.html new file mode 100644 index 000000000000..9bf4808e9e3d --- /dev/null +++ b/coverage/generic/PDB2Constant.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - generic/PDB2Constant.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - PDB2Constant.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:545598.2 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic12PDB2ConstantC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic12PDB2ConstantC1ERKNS_13ActionOptionsE115
_ZN4PLMD7generic12PDB2Constant16registerKeywordsERNS_8KeywordsE117
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/PDB2Constant.cpp.func.html b/coverage/generic/PDB2Constant.cpp.func.html new file mode 100644 index 000000000000..7268602056c9 --- /dev/null +++ b/coverage/generic/PDB2Constant.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - generic/PDB2Constant.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - PDB2Constant.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:545598.2 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic12PDB2Constant16registerKeywordsERNS_8KeywordsE117
_ZN4PLMD7generic12PDB2ConstantC1ERKNS_13ActionOptionsE115
_ZN4PLMD7generic12PDB2ConstantC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/PDB2Constant.cpp.gcov.html b/coverage/generic/PDB2Constant.cpp.gcov.html new file mode 100644 index 000000000000..c0f3b0eba989 --- /dev/null +++ b/coverage/generic/PDB2Constant.cpp.gcov.html @@ -0,0 +1,196 @@ + + + + + + + + LCOV - plumed test coverage - generic/PDB2Constant.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - PDB2Constant.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:545598.2 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionShortcut.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "core/ActionWithArguments.h"
+      25             : #include "core/PlumedMain.h"
+      26             : #include "tools/PDB.h"
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace generic {
+      30             : 
+      31             : //+PLUMEDOC COLVAR PDB2CONSTANT
+      32             : /*
+      33             : Create a constant value from a PDB input file
+      34             : 
+      35             : \par Examples
+      36             : 
+      37             : */
+      38             : //+ENDPLUMEDOC
+      39             : 
+      40             : class PDB2Constant : public ActionShortcut {
+      41             : public:
+      42             :   static void registerKeywords(Keywords& keys);
+      43             :   explicit PDB2Constant(const ActionOptions&);
+      44             : };
+      45             : 
+      46             : PLUMED_REGISTER_ACTION(PDB2Constant,"PDB2CONSTANT")
+      47             : 
+      48         117 : void PDB2Constant::registerKeywords(Keywords& keys) {
+      49         117 :   ActionShortcut::registerKeywords( keys );
+      50         234 :   keys.add("compulsory","REFERENCE","a file in pdb format containing the reference structure");
+      51         234 :   keys.add("compulsory","NUMBER","0","if there are multiple structures in the pdb file you can specify that you want the RMSD from a specific structure by specifying its place in the file here. If NUMBER=0 then the RMSD from all structures are computed");
+      52         234 :   keys.addFlag("NOARGS",false,"the arguments that are being read from the PDB file are not in the plumed input");
+      53         234 :   keys.add("optional","ARG","read this single argument from the input rather than the atomic structure");
+      54         117 :   keys.needsAction("CONSTANT");
+      55         117 : }
+      56             : 
+      57         115 : PDB2Constant::PDB2Constant(const ActionOptions& ao):
+      58             :   Action(ao),
+      59         115 :   ActionShortcut(ao)
+      60             : {
+      61         115 :   std::string input; parse("REFERENCE",input);
+      62         230 :   unsigned frame; parse("NUMBER",frame); bool noargs=false;
+      63         230 :   std::vector<std::string> argn; parseVector("ARG",argn); std::vector<Value*> theargs;
+      64         115 :   if( argn.size()>0 ) {
+      65          75 :     parseFlag("NOARGS",noargs);
+      66          75 :     if( !noargs ) ActionWithArguments::interpretArgumentList( argn, plumed.getActionSet(), this, theargs );
+      67           2 :     else if( argn.size()>1 ) error("can only read one argument at a time from input pdb file");
+      68           2 :     else log.printf("  reading argument %s from file \n", argn[0].c_str() );
+      69             :   }
+      70         115 :   if( theargs.size()>1 ) error("can only read one argument at a time from input pdb file");
+      71             : 
+      72         115 :   FILE* fp=std::fopen(input.c_str(),"r"); bool do_read=true; std::vector<double> vals;
+      73         115 :   if(!fp) plumed_merror("could not open reference file " + input); unsigned natoms=0, nframes=0;
+      74             : 
+      75        2235 :   while ( do_read ) {
+      76        2235 :     PDB mypdb; do_read=mypdb.readFromFilepointer(fp,plumed.usingNaturalUnits(),0.1/plumed.getUnits().getLength());
+      77        2235 :     if( !do_read && nframes>0 ) break ;
+      78             : 
+      79        2120 :     if( natoms==0 ) natoms = mypdb.getPositions().size();
+      80         742 :     else if( mypdb.getPositions().size()!=natoms ) plumed_merror("mismatch between sizes of reference configurations");
+      81             : 
+      82        2120 :     if( nframes+1==frame || frame==0 ) {
+      83        1642 :       std::vector<double> align( mypdb.getOccupancy() );
+      84       10326 :       double asum=0; for(unsigned i=0; i<align.size(); ++i) asum += align[i];
+      85        1642 :       if( asum>epsilon ) {
+      86        9358 :         double iasum = 1 / asum; for(unsigned i=0; i<align.size(); ++i) align[i] *= iasum;
+      87         968 :       } else if( mypdb.size()>0 ) {
+      88           0 :         double iasum = 1 / mypdb.size(); for(unsigned i=0; i<align.size(); ++i) align[i] = iasum;
+      89             :       }
+      90       10326 :       Vector center; center.zero(); for(unsigned i=0; i<mypdb.getPositions().size(); ++i) center += align[i]*mypdb.getPositions()[i];
+      91             : 
+      92        1642 :       if( theargs.size()==0 && argn.size()==0 ) {
+      93        1688 :         for(unsigned j=0; j<3; ++j) {
+      94       17490 :           for(unsigned i=0; i<mypdb.getPositions().size(); ++i) vals.push_back( mypdb.getPositions()[i][j] - center[j] );
+      95             :         }
+      96        1220 :       } else if( noargs ) {
+      97          20 :         std::vector<double> argvals( 1 );
+      98          20 :         if( !mypdb.getArgumentValue(argn[0], argvals ) ) error("argument " + argn[0] + " was not set in pdb input");
+      99          20 :         vals.push_back( argvals[0] );
+     100             :       } else {
+     101        1200 :         std::vector<double> argvals( theargs[0]->getNumberOfValues() );
+     102        1200 :         if( !mypdb.getArgumentValue(theargs[0]->getName(), argvals ) ) error("argument " + theargs[0]->getName() + " was not set in pdb input");
+     103        2402 :         for(unsigned i=0; i<argvals.size(); ++i) vals.push_back( argvals[i] );
+     104             :       }
+     105             :     }
+     106        2120 :     nframes++;
+     107        2235 :   }
+     108         115 :   if( frame>0 ) nframes=1;
+     109         115 :   std::fclose(fp); std::string rnum; plumed_assert( vals.size()>0 );
+     110         115 :   Tools::convert( vals[0], rnum ); std::string valstr = " VALUES=" + rnum;
+     111       17446 :   for(unsigned i=1; i<vals.size(); ++i) { Tools::convert( vals[i], rnum ); valstr += "," + rnum; }
+     112         115 :   if( vals.size()>nframes ) {
+     113          41 :     std::string nc, nr; Tools::convert( nframes, nr ); Tools::convert( vals.size()/nframes, nc );
+     114          82 :     readInputLine( getShortcutLabel() + ": CONSTANT NROWS=" + nr + " NCOLS=" + nc + valstr );
+     115         148 :   } else readInputLine( getShortcutLabel() + ": CONSTANT" + valstr );
+     116         230 : }
+     117             : 
+     118             : }
+     119             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/Plumed.cpp.func-sort-c.html b/coverage/generic/Plumed.cpp.func-sort-c.html new file mode 100644 index 000000000000..68ee4fe0f137 --- /dev/null +++ b/coverage/generic/Plumed.cpp.func-sort-c.html @@ -0,0 +1,121 @@ + + + + + + + + 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:16617893.3 %
Date:2024-04-19 12:12:35Functions:101283.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic6Plumed22getNumberOfDerivativesEv0
_ZN4PLMD7generic6PlumedC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic6PlumedC1ERKNS_13ActionOptionsE12
_ZZN4PLMD7generic6PlumedC4ERKNS_13ActionOptionsEENKUlvE0_clEv12
_ZZN4PLMD7generic6PlumedC4ERKNS_13ActionOptionsEENKUlvE1_clEv12
_ZZN4PLMD7generic6PlumedC4ERKNS_13ActionOptionsEENKUlvE_clEv12
_ZN4PLMD7generic6Plumed16registerKeywordsERNS_8KeywordsE14
_ZN4PLMD7generic6Plumed15actionHasForcesEv92
_ZN4PLMD7generic6Plumed5applyEv104
_ZN4PLMD7generic6Plumed6updateEv104
_ZN4PLMD7generic6Plumed9calculateEv134
_ZN4PLMD7generic6Plumed7prepareEv164
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/Plumed.cpp.func.html b/coverage/generic/Plumed.cpp.func.html new file mode 100644 index 000000000000..7fba9c341d88 --- /dev/null +++ b/coverage/generic/Plumed.cpp.func.html @@ -0,0 +1,121 @@ + + + + + + + + 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:16617893.3 %
Date:2024-04-19 12:12:35Functions:101283.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic5PrintC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic5PrintD2Ev0
_ZNK4PLMD7generic5Print12writeInGraphB5cxx11Ev8
_ZN4PLMD7generic5PrintC1ERKNS_13ActionOptionsE1019
_ZN4PLMD7generic5PrintD0Ev1019
_ZN4PLMD7generic5PrintD1Ev1019
_ZN4PLMD7generic5Print16registerKeywordsERNS_8KeywordsE1021
_ZN4PLMD7generic5Print6updateEv218261
_ZN4PLMD7generic5Print5applyEv225431
_ZN4PLMD7generic5Print9calculateEv225553
_ZN4PLMD7generic5Print7prepareEv225681
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/Print.cpp.func.html b/coverage/generic/Print.cpp.func.html new file mode 100644 index 000000000000..9689a54d950a --- /dev/null +++ b/coverage/generic/Print.cpp.func.html @@ -0,0 +1,117 @@ + + + + + + + + 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:586096.7 %
Date:2024-04-19 12:12:35Functions:91181.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic5Print16registerKeywordsERNS_8KeywordsE1021
_ZN4PLMD7generic5Print5applyEv225431
_ZN4PLMD7generic5Print6updateEv218261
_ZN4PLMD7generic5Print7prepareEv225681
_ZN4PLMD7generic5Print9calculateEv225553
_ZN4PLMD7generic5PrintC1ERKNS_13ActionOptionsE1019
_ZN4PLMD7generic5PrintC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic5PrintD0Ev1019
_ZN4PLMD7generic5PrintD1Ev1019
_ZN4PLMD7generic5PrintD2Ev0
_ZNK4PLMD7generic5Print12writeInGraphB5cxx11Ev8
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/Print.cpp.gcov.html b/coverage/generic/Print.cpp.gcov.html new file mode 100644 index 000000000000..932c0b5dd17e --- /dev/null +++ b/coverage/generic/Print.cpp.gcov.html @@ -0,0 +1,264 @@ + + + + + + + + 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:586096.7 %
Date:2024-04-19 12:12:35Functions:91181.8 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "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      225553 :   void calculate() override {}
+      87             :   void prepare() override;
+      88             :   std::string writeInGraph() const override;
+      89             :   explicit Print(const ActionOptions&);
+      90             :   static void registerKeywords(Keywords& keys);
+      91      225431 :   void apply() override {}
+      92             :   void update() override;
+      93             :   ~Print();
+      94             : };
+      95             : 
+      96             : PLUMED_REGISTER_ACTION(Print,"PRINT")
+      97             : 
+      98        1021 : void Print::registerKeywords(Keywords& keys) {
+      99        1021 :   Action::registerKeywords(keys);
+     100        1021 :   ActionPilot::registerKeywords(keys);
+     101        1021 :   ActionWithArguments::registerKeywords(keys);
+     102        1021 :   keys.use("ARG");
+     103        2042 :   keys.add("compulsory","STRIDE","1","the frequency with which the quantities of interest should be output");
+     104        2042 :   keys.add("optional","FILE","the name of the file on which to output these quantities");
+     105        2042 :   keys.add("optional","FMT","the format that should be used to output real numbers");
+     106        2042 :   keys.add("hidden","_ROTATE","some funky thing implemented by GBussi");
+     107        1021 :   keys.use("RESTART");
+     108        1021 :   keys.use("UPDATE_FROM");
+     109        1021 :   keys.use("UPDATE_UNTIL");
+     110        1021 : }
+     111             : 
+     112        1019 : Print::Print(const ActionOptions&ao):
+     113             :   Action(ao),
+     114             :   ActionPilot(ao),
+     115             :   ActionWithArguments(ao),
+     116        1019 :   fmt("%f"),
+     117        2038 :   rotate(0)
+     118             : {
+     119        1019 :   ofile.link(*this);
+     120        2038 :   parse("FILE",file);
+     121        1019 :   if(file.length()>0) {
+     122        1019 :     ofile.open(file);
+     123        1019 :     log.printf("  on file %s\n",file.c_str());
+     124             :   } else {
+     125           0 :     log.printf("  on plumed log file\n");
+     126           0 :     ofile.link(log);
+     127             :   }
+     128        1019 :   parse("FMT",fmt);
+     129        1019 :   fmt=" "+fmt;
+     130        1019 :   log.printf("  with format %s\n",fmt.c_str());
+     131        7061 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     132        6042 :     ofile.setupPrintValue( getPntrToArgument(i) );
+     133        6042 :     getPntrToArgument(i)->buildDataStore(true);
+     134             :   }
+     135             : /////////////////////////////////////////
+     136             : // these are crazy things just for debug:
+     137             : // they allow to change regularly the
+     138             : // printed argument
+     139        1019 :   parse("_ROTATE",rotate);
+     140        1019 :   if(rotate>0) {
+     141           1 :     rotateCountdown=rotate;
+     142           4 :     for(unsigned i=0; i<getNumberOfArguments(); ++i) rotateArguments.push_back( getPntrToArgument(i) );
+     143           1 :     std::vector<Value*> a(1,rotateArguments[0]);
+     144           1 :     requestArguments(std::vector<Value*>(1,rotateArguments[0]));
+     145           1 :     rotateLast=0;
+     146             :   }
+     147             : /////////////////////////////////////////
+     148        1019 :   checkRead();
+     149        1019 : }
+     150             : 
+     151           8 : std::string Print::writeInGraph() const {
+     152          16 :   return getName() + "\n" + "FILE=" + file;
+     153             : }
+     154             : 
+     155      225681 : void Print::prepare() {
+     156             : /////////////////////////////////////////
+     157             : // these are crazy things just for debug:
+     158             : // they allow to change regularly the
+     159             : // printed argument
+     160      225681 :   if(rotate>0) {
+     161           5 :     rotateCountdown--;
+     162           5 :     if(rotateCountdown==0) {
+     163           2 :       rotateCountdown=rotate;
+     164           2 :       rotateLast++;
+     165           2 :       rotateLast%=rotateArguments.size();
+     166           4 :       requestArguments(std::vector<Value*>(1,rotateArguments[rotateLast]));
+     167             :     }
+     168             :   }
+     169             : /////////////////////////////////////////
+     170      225681 : }
+     171             : 
+     172      218261 : void Print::update() {
+     173      218261 :   ofile.fmtField(" %f");
+     174      218261 :   ofile.printField("time",getTime());
+     175      765837 :   for(unsigned i=0; i<getNumberOfArguments(); i++) {
+     176      547576 :     ofile.fmtField(fmt); getPntrToArgument(i)->print( ofile );
+     177             :   }
+     178      218261 :   ofile.printField();
+     179      218261 : }
+     180             : 
+     181        2038 : Print::~Print() {
+     182        2038 : }
+     183             : 
+     184             : }
+     185             : 
+     186             : 
+     187             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/PrintNDX.cpp.func-sort-c.html b/coverage/generic/PrintNDX.cpp.func-sort-c.html new file mode 100644 index 000000000000..dd97e8b73244 --- /dev/null +++ b/coverage/generic/PrintNDX.cpp.func-sort-c.html @@ -0,0 +1,125 @@ + + + + + + + + LCOV - plumed test coverage - generic/PrintNDX.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - PrintNDX.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:566290.3 %
Date:2024-04-19 12:12:35Functions:91369.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic8PrintNDX15actionHasForcesEv0
_ZN4PLMD7generic8PrintNDX29calculateNumericalDerivativesEPNS_15ActionWithValueE0
_ZN4PLMD7generic8PrintNDXC2ERKNS_13ActionOptionsE0
_ZNK4PLMD7generic8PrintNDX12writeInGraphB5cxx11Ev0
_ZN4PLMD7generic8PrintNDX12lockRequestsEv4
_ZN4PLMD7generic8PrintNDX14unlockRequestsEv4
_ZN4PLMD7generic8PrintNDX5applyEv4
_ZN4PLMD7generic8PrintNDX6updateEv4
_ZN4PLMD7generic8PrintNDX9calculateEv4
_ZN4PLMD7generic8PrintNDXC1ERKNS_13ActionOptionsE4
_ZN4PLMD7generic8PrintNDXD0Ev4
_ZN4PLMD7generic8PrintNDXD1Ev4
_ZN4PLMD7generic8PrintNDX16registerKeywordsERNS_8KeywordsE6
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/PrintNDX.cpp.func.html b/coverage/generic/PrintNDX.cpp.func.html new file mode 100644 index 000000000000..aa1b2be20fc4 --- /dev/null +++ b/coverage/generic/PrintNDX.cpp.func.html @@ -0,0 +1,125 @@ + + + + + + + + LCOV - plumed test coverage - generic/PrintNDX.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - PrintNDX.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:566290.3 %
Date:2024-04-19 12:12:35Functions:91369.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic8PrintNDX12lockRequestsEv4
_ZN4PLMD7generic8PrintNDX14unlockRequestsEv4
_ZN4PLMD7generic8PrintNDX15actionHasForcesEv0
_ZN4PLMD7generic8PrintNDX16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD7generic8PrintNDX29calculateNumericalDerivativesEPNS_15ActionWithValueE0
_ZN4PLMD7generic8PrintNDX5applyEv4
_ZN4PLMD7generic8PrintNDX6updateEv4
_ZN4PLMD7generic8PrintNDX9calculateEv4
_ZN4PLMD7generic8PrintNDXC1ERKNS_13ActionOptionsE4
_ZN4PLMD7generic8PrintNDXC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic8PrintNDXD0Ev4
_ZN4PLMD7generic8PrintNDXD1Ev4
_ZNK4PLMD7generic8PrintNDX12writeInGraphB5cxx11Ev0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/PrintNDX.cpp.gcov.html b/coverage/generic/PrintNDX.cpp.gcov.html new file mode 100644 index 000000000000..36d4ae91baf7 --- /dev/null +++ b/coverage/generic/PrintNDX.cpp.gcov.html @@ -0,0 +1,222 @@ + + + + + + + + LCOV - plumed test coverage - generic/PrintNDX.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - PrintNDX.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:566290.3 %
Date:2024-04-19 12:12:35Functions:91369.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 "core/ActionPilot.h"
+      23             : #include "core/ActionWithArguments.h"
+      24             : #include "core/ActionAtomistic.h"
+      25             : #include "core/ActionRegister.h"
+      26             : #include "tools/CheckInRange.h"
+      27             : 
+      28             : //+PLUMEDOC PRINTANALYSIS PRINT_NDX
+      29             : /*
+      30             : Print an ndx file
+      31             : 
+      32             : \par Examples
+      33             : 
+      34             : */
+      35             : //+ENDPLUMEDOC
+      36             : 
+      37             : namespace PLMD {
+      38             : namespace generic {
+      39             : 
+      40             : class PrintNDX :
+      41             :   public ActionPilot,
+      42             :   public ActionAtomistic,
+      43             :   public ActionWithArguments
+      44             : {
+      45             :   std::string file;
+      46             :   OFile ofile;
+      47             :   CheckInRange bounds;
+      48             : public:
+      49           4 :   void calculate() override {}
+      50             :   std::string writeInGraph() const override;
+      51             :   explicit PrintNDX(const ActionOptions&);
+      52             :   static void registerKeywords(Keywords& keys);
+      53           0 :   bool actionHasForces() override { return false; }
+      54           0 :   void calculateNumericalDerivatives( ActionWithValue* a=NULL ) override { plumed_error(); }
+      55             :   void lockRequests() override;
+      56             :   void unlockRequests() override;
+      57           4 :   void apply() override {}
+      58             :   void update() override;
+      59          12 :   ~PrintNDX() {}
+      60             : };
+      61             : 
+      62             : PLUMED_REGISTER_ACTION(PrintNDX,"PRINT_NDX")
+      63             : 
+      64           6 : void PrintNDX::registerKeywords(Keywords& keys) {
+      65           6 :   Action::registerKeywords(keys);
+      66           6 :   ActionPilot::registerKeywords(keys);
+      67           6 :   ActionAtomistic::registerKeywords( keys );
+      68           6 :   ActionWithArguments::registerKeywords(keys);
+      69           6 :   keys.use("ARG");
+      70          12 :   keys.add("atoms","ATOMS","the list of atoms that have the corresponding arguments");
+      71          12 :   keys.add("compulsory","STRIDE","1","the frequency with which the quantities of interest should be output");
+      72          12 :   keys.add("optional","FILE","the name of the file on which to output these quantities");
+      73          12 :   keys.add("optional","LESS_THAN_OR_EQUAL","when printing with arguments that are vectors only print components of vectors have a value less than or equal to this value");
+      74          12 :   keys.add("optional","GREATER_THAN_OR_EQUAL","when printing with arguments that are vectors only print components of vectors have a value greater than or equal to this value");
+      75           6 :   keys.use("RESTART");
+      76           6 :   keys.use("UPDATE_FROM");
+      77           6 :   keys.use("UPDATE_UNTIL");
+      78           6 : }
+      79             : 
+      80           4 : PrintNDX::PrintNDX(const ActionOptions&ao):
+      81             :   Action(ao),
+      82             :   ActionPilot(ao),
+      83             :   ActionAtomistic(ao),
+      84           4 :   ActionWithArguments(ao)
+      85             : {
+      86           4 :   ofile.link(*this);
+      87           8 :   parse("FILE",file);
+      88           4 :   if(file.length()>0) {
+      89           4 :     ofile.open(file);
+      90           4 :     log.printf("  on file %s\n",file.c_str());
+      91             :   } else {
+      92           0 :     log.printf("  on plumed log file\n");
+      93           0 :     ofile.link(log);
+      94             :   }
+      95           8 :   std::vector<AtomNumber> all_atoms; parseAtomList("ATOMS",all_atoms); std::vector<std::string> argnames( getNumberOfArguments() );
+      96           4 :   requestAtoms( all_atoms, false );
+      97           8 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+      98           4 :     if( getPntrToArgument(i)->getRank()!=1 || getPntrToArgument(i)->hasDerivatives() ) error("arguments for print ndx should be vector");
+      99           4 :     if( getPntrToArgument(i)->getShape()[0]!=all_atoms.size() ) error("mismatch between number of arguments and number of input atoms");
+     100           4 :     getPntrToArgument(i)->buildDataStore(true); argnames[i] = getPntrToArgument(i)->getName();
+     101             :   }
+     102           4 :   log.printf("  printing ndx file containing indices of atoms that have arguments in ranges prescribed below \n");
+     103           4 :   log.printf("  full set of atom indices investigated are : ");
+     104        7988 :   for(unsigned int i=0; i<all_atoms.size(); ++i) {
+     105        7984 :     if ( (i+1) % 25 == 0 ) log.printf("  \n");
+     106        7984 :     log.printf("  %d", all_atoms[i].serial());
+     107             :   }
+     108           4 :   log.printf("\n"); std::vector<std::string> str_upper, str_lower; std::string errors;
+     109          12 :   parseVector("LESS_THAN_OR_EQUAL",str_upper); parseVector("GREATER_THAN_OR_EQUAL",str_lower);
+     110           4 :   if( !bounds.setBounds( getNumberOfArguments(), str_lower, str_upper, errors ) ) error( errors );
+     111           8 :   if( bounds.wereSet() ) log.printf("  %s \n", bounds.report( argnames ).c_str() );
+     112           4 :   checkRead();
+     113           8 : }
+     114             : 
+     115           0 : std::string PrintNDX::writeInGraph() const {
+     116           0 :   return getName() + "\n" + "FILE=" + file;
+     117             : }
+     118             : 
+     119           4 : void PrintNDX::lockRequests() {
+     120             :   ActionWithArguments::lockRequests();
+     121             :   ActionAtomistic::lockRequests();
+     122           4 : }
+     123             : 
+     124           4 : void PrintNDX::unlockRequests() {
+     125             :   ActionWithArguments::unlockRequests();
+     126             :   ActionAtomistic::unlockRequests();
+     127           4 : }
+     128             : 
+     129           4 : void PrintNDX::update() {
+     130           4 :   unsigned n=0; std::vector<double> argvals( getNumberOfArguments() );
+     131           4 :   ofile.printf("[ %s step %d ] \n", getLabel().c_str(), getStep() );
+     132        7988 :   for(unsigned i=0; i<getNumberOfAtoms(); ++i) {
+     133       15968 :     for(unsigned j=0; j<getNumberOfArguments(); ++j) argvals[j] = getPntrToArgument(j)->get(i);
+     134        7984 :     if( bounds.check( argvals ) ) {
+     135         156 :       ofile.printf("%6d", getAbsoluteIndexes()[i].serial() ); n++;
+     136         156 :       if( n%15==0 ) ofile.printf("\n");
+     137             :     }
+     138             :   }
+     139           4 :   ofile.printf("\n");
+     140           4 : }
+     141             : 
+     142             : }
+     143             : 
+     144             : 
+     145             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/RandomExchanges.cpp.func-sort-c.html b/coverage/generic/RandomExchanges.cpp.func-sort-c.html new file mode 100644 index 000000000000..a8c2ffbfdbe7 --- /dev/null +++ b/coverage/generic/RandomExchanges.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - generic/RandomExchanges.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - RandomExchanges.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:41330.8 %
Date:2024-04-19 12:12:35Functions:1425.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic15RandomExchanges5applyEv0
_ZN4PLMD7generic15RandomExchanges9calculateEv0
_ZN4PLMD7generic15RandomExchangesC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic15RandomExchanges16registerKeywordsERNS_8KeywordsE2
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/RandomExchanges.cpp.func.html b/coverage/generic/RandomExchanges.cpp.func.html new file mode 100644 index 000000000000..46f738618055 --- /dev/null +++ b/coverage/generic/RandomExchanges.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - generic/RandomExchanges.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - RandomExchanges.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:41330.8 %
Date:2024-04-19 12:12:35Functions:1425.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic15RandomExchanges16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD7generic15RandomExchanges5applyEv0
_ZN4PLMD7generic15RandomExchanges9calculateEv0
_ZN4PLMD7generic15RandomExchangesC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/RandomExchanges.cpp.gcov.html b/coverage/generic/RandomExchanges.cpp.gcov.html new file mode 100644 index 000000000000..e2856e253db4 --- /dev/null +++ b/coverage/generic/RandomExchanges.cpp.gcov.html @@ -0,0 +1,179 @@ + + + + + + + + LCOV - plumed test coverage - generic/RandomExchanges.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - RandomExchanges.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:41330.8 %
Date:2024-04-19 12:12:35Functions:1425.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/Action.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "core/PlumedMain.h"
+      25             : #include "tools/Exception.h"
+      26             : #include "core/ExchangePatterns.h"
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace generic {
+      30             : 
+      31             : //+PLUMEDOC GENERIC RANDOM_EXCHANGES
+      32             : /*
+      33             : Set random pattern for exchanges.
+      34             : 
+      35             : In this way, exchanges will not be done between replicas with consecutive index, but
+      36             : will be done using a random pattern.  Typically used in bias exchange \cite piana.
+      37             : 
+      38             : \par Examples
+      39             : 
+      40             : Using the following three input files one can run a bias exchange
+      41             : metadynamics simulation using a different angle in each replica.
+      42             : Exchanges will be randomly tried between replicas 0-1, 0-2 and 1-2
+      43             : 
+      44             : Here is plumed.0.dat
+      45             : \plumedfile
+      46             : RANDOM_EXCHANGES
+      47             : t: TORSION ATOMS=1,2,3,4
+      48             : METAD ARG=t HEIGHT=0.1 PACE=100 SIGMA=0.3
+      49             : \endplumedfile
+      50             : 
+      51             : Here is plumed.1.dat
+      52             : \plumedfile
+      53             : RANDOM_EXCHANGES
+      54             : t: TORSION ATOMS=2,3,4,5
+      55             : METAD ARG=t HEIGHT=0.1 PACE=100 SIGMA=0.3
+      56             : \endplumedfile
+      57             : 
+      58             : Here is plumed.2.dat
+      59             : \plumedfile
+      60             : RANDOM_EXCHANGES
+      61             : t: TORSION ATOMS=3,4,5,6
+      62             : METAD ARG=t HEIGHT=0.1 PACE=100 SIGMA=0.3
+      63             : \endplumedfile
+      64             : 
+      65             : \warning Multi replica simulations are presently only working with gromacs.
+      66             : 
+      67             : \warning The directive should appear in input files for every replicas. In case SEED is specified, it
+      68             : should be the same in all input files.
+      69             : 
+      70             : */
+      71             : //+ENDPLUMEDOC
+      72             : 
+      73             : class RandomExchanges:
+      74             :   public Action
+      75             : {
+      76             : public:
+      77             :   static void registerKeywords( Keywords& keys );
+      78             :   explicit RandomExchanges(const ActionOptions&ao);
+      79           0 :   void calculate() override {}
+      80           0 :   void apply() override {}
+      81             : };
+      82             : 
+      83             : PLUMED_REGISTER_ACTION(RandomExchanges,"RANDOM_EXCHANGES")
+      84             : 
+      85           2 : void RandomExchanges::registerKeywords( Keywords& keys ) {
+      86           2 :   Action::registerKeywords(keys);
+      87           4 :   keys.add("optional","SEED","seed for random exchanges");
+      88           2 : }
+      89             : 
+      90           0 : RandomExchanges::RandomExchanges(const ActionOptions&ao):
+      91           0 :   Action(ao)
+      92             : {
+      93           0 :   plumed.getExchangePatterns().setFlag(ExchangePatterns::RANDOM);
+      94             : // I convert the seed to -seed because I think it is more general to use a positive seed in input
+      95           0 :   int seed=-1;
+      96           0 :   parse("SEED",seed);
+      97           0 :   if(seed>=0) plumed.getExchangePatterns().setSeed(-seed);
+      98           0 : }
+      99             : 
+     100             : }
+     101             : }
+     102             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/Read.cpp.func-sort-c.html b/coverage/generic/Read.cpp.func-sort-c.html new file mode 100644 index 000000000000..b0e156f68124 --- /dev/null +++ b/coverage/generic/Read.cpp.func-sort-c.html @@ -0,0 +1,117 @@ + + + + + + + + LCOV - plumed test coverage - generic/Read.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - Read.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:949994.9 %
Date:2024-04-19 12:12:35Functions:91181.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic4Read22getNumberOfDerivativesEv0
_ZN4PLMD7generic4ReadC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic4Read17turnOnDerivativesEv26
_ZN4PLMD7generic4Read7getFileEv46
_ZNK4PLMD7generic4Read11getFilenameB5cxx11Ev49
_ZN4PLMD7generic4ReadC1ERKNS_13ActionOptionsE89
_ZN4PLMD7generic4Read16registerKeywordsERNS_8KeywordsE91
_ZN4PLMD7generic4Read5applyEv921429
_ZN4PLMD7generic4Read6updateEv921429
_ZN4PLMD7generic4Read7prepareEv921429
_ZN4PLMD7generic4Read9calculateEv921429
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/Read.cpp.func.html b/coverage/generic/Read.cpp.func.html new file mode 100644 index 000000000000..9dec7408c862 --- /dev/null +++ b/coverage/generic/Read.cpp.func.html @@ -0,0 +1,117 @@ + + + + + + + + LCOV - plumed test coverage - generic/Read.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - Read.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:949994.9 %
Date:2024-04-19 12:12:35Functions:91181.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic4Read16registerKeywordsERNS_8KeywordsE91
_ZN4PLMD7generic4Read17turnOnDerivativesEv26
_ZN4PLMD7generic4Read22getNumberOfDerivativesEv0
_ZN4PLMD7generic4Read5applyEv921429
_ZN4PLMD7generic4Read6updateEv921429
_ZN4PLMD7generic4Read7getFileEv46
_ZN4PLMD7generic4Read7prepareEv921429
_ZN4PLMD7generic4Read9calculateEv921429
_ZN4PLMD7generic4ReadC1ERKNS_13ActionOptionsE89
_ZN4PLMD7generic4ReadC2ERKNS_13ActionOptionsE0
_ZNK4PLMD7generic4Read11getFilenameB5cxx11Ev49
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/Read.cpp.gcov.html b/coverage/generic/Read.cpp.gcov.html new file mode 100644 index 000000000000..b439820ee80d --- /dev/null +++ b/coverage/generic/Read.cpp.gcov.html @@ -0,0 +1,332 @@ + + + + + + + + LCOV - plumed test coverage - generic/Read.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - Read.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:949994.9 %
Date:2024-04-19 12:12:35Functions:91181.8 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionPilot.h"
+      23             : #include "core/ActionWithValue.h"
+      24             : #include "core/ActionRegister.h"
+      25             : #include "core/PlumedMain.h"
+      26             : #include "core/ActionSet.h"
+      27             : #include "tools/IFile.h"
+      28             : #include <memory>
+      29             : 
+      30             : namespace PLMD {
+      31             : namespace generic {
+      32             : 
+      33             : //+PLUMEDOC GENERIC READ
+      34             : /*
+      35             : Read quantities from a colvar file.
+      36             : 
+      37             : This Action can be used with driver to read in a colvar file that was generated during
+      38             : an MD simulation
+      39             : 
+      40             : \par Description of components
+      41             : 
+      42             : The READ command will read those fields that are labelled with the text string given to the
+      43             : VALUE keyword.  It will also read in any fields that are labeled with the text string
+      44             : given to the VALUE keyword followed by a dot and a further string. If a single Value is read in
+      45             : this value can be referenced using the label of the Action.  Alternatively, if multiple quantities
+      46             : are read in, they can be referenced elsewhere in the input by using the label for the Action
+      47             : followed by a dot and the character string that appeared after the dot in the title of the field.
+      48             : 
+      49             : \par Examples
+      50             : 
+      51             : This input reads in data from a file called input_colvar.data that was generated
+      52             : in a calculation that involved PLUMED.  The first command reads in the data from the
+      53             : column headed phi1 while the second reads in the data from the column headed phi2.
+      54             : 
+      55             : \plumedfile
+      56             : rphi1:       READ FILE=input_colvar.data  VALUES=phi1
+      57             : rphi2:       READ FILE=input_colvar.data  VALUES=phi2
+      58             : PRINT ARG=rphi1,rphi2 STRIDE=500  FILE=output_colvar.data
+      59             : \endplumedfile
+      60             : 
+      61             : The file input_colvar.data is just a normal colvar file as shown below
+      62             : 
+      63             : \auxfile{input_colvar.data}
+      64             : #! FIELDS time phi psi metad.bias metad.rbias metad.rct
+      65             : #! SET min_phi -pi
+      66             : #! SET max_phi pi
+      67             : #! SET min_psi -pi
+      68             : #! SET max_psi pi
+      69             :  0.000000  -1.2379   0.8942   0.0000   0.0000   0.0000
+      70             :  1.000000  -1.4839   1.0482   0.0000   0.0000   0.0089
+      71             :  2.000000  -1.3243   0.6055   0.0753   0.0664   0.0184
+      72             : \endauxfile
+      73             : 
+      74             : */
+      75             : //+ENDPLUMEDOC
+      76             : 
+      77             : class Read :
+      78             :   public ActionPilot,
+      79             :   public ActionWithValue
+      80             : {
+      81             : private:
+      82             :   bool ignore_time;
+      83             :   bool ignore_forces;
+      84             :   bool cloned_file;
+      85             :   unsigned nlinesPerStep;
+      86             :   std::string filename;
+      87             : /// Unique pointer with the same scope as ifile.
+      88             :   std::unique_ptr<IFile> ifile_ptr;
+      89             : /// Pointer to input file.
+      90             : /// It is either pointing to the content of ifile_ptr
+      91             : /// or to the file it is cloned from.
+      92             :   IFile* ifile;
+      93             :   std::vector<std::unique_ptr<Value>> readvals;
+      94             : public:
+      95             :   static void registerKeywords( Keywords& keys );
+      96             :   explicit Read(const ActionOptions&);
+      97             :   void prepare() override;
+      98      921429 :   void apply() override {}
+      99             :   void calculate() override;
+     100             :   void update() override;
+     101             :   std::string getFilename() const;
+     102             :   IFile* getFile();
+     103             :   unsigned getNumberOfDerivatives() override;
+     104             :   void turnOnDerivatives() override;
+     105             : };
+     106             : 
+     107             : PLUMED_REGISTER_ACTION(Read,"READ")
+     108             : 
+     109          91 : void Read::registerKeywords(Keywords& keys) {
+     110          91 :   Action::registerKeywords(keys);
+     111          91 :   ActionPilot::registerKeywords(keys);
+     112          91 :   ActionWithValue::registerKeywords(keys);
+     113         182 :   keys.add("compulsory","STRIDE","1","the frequency with which the file should be read.");
+     114         182 :   keys.add("compulsory","EVERY","1","only read every \\f$n\\f$th line of the colvar file. This should be used if the colvar was written more frequently than the trajectory.");
+     115         182 :   keys.add("compulsory","VALUES","the values to read from the file");
+     116         182 :   keys.add("compulsory","FILE","the name of the file from which to read these quantities");
+     117         182 :   keys.addFlag("IGNORE_TIME",false,"ignore the time in the colvar file. When this flag is not present read will be quite strict "
+     118             :                "about the start time of the simulation and the stride between frames");
+     119         182 :   keys.addFlag("IGNORE_FORCES",false,"use this flag if the forces added by any bias can be safely ignored.  As an example forces can be "
+     120             :                "safely ignored if you are doing post processing that does not involve outputting forces");
+     121          91 :   keys.remove("NUMERICAL_DERIVATIVES");
+     122          91 :   keys.use("UPDATE_FROM");
+     123          91 :   keys.use("UPDATE_UNTIL");
+     124          91 :   ActionWithValue::useCustomisableComponents(keys);
+     125          91 : }
+     126             : 
+     127          89 : Read::Read(const ActionOptions&ao):
+     128             :   Action(ao),
+     129             :   ActionPilot(ao),
+     130             :   ActionWithValue(ao),
+     131          89 :   ignore_time(false),
+     132          89 :   ignore_forces(false),
+     133          89 :   nlinesPerStep(1)
+     134             : {
+     135             :   // Read the file name from the input line
+     136          89 :   parse("FILE",filename);
+     137             :   // Check if time is to be ignored
+     138          89 :   parseFlag("IGNORE_TIME",ignore_time);
+     139             :   // Check if forces are to be ignored
+     140          89 :   parseFlag("IGNORE_FORCES",ignore_forces);
+     141             :   // Open the file if it is not already opened
+     142          89 :   cloned_file=false;
+     143          89 :   std::vector<Read*> other_reads=plumed.getActionSet().select<Read*>();
+     144         138 :   for(unsigned i=0; i<other_reads.size(); ++i) {
+     145          49 :     if( other_reads[i]->getFilename()==filename ) {
+     146          46 :       ifile=other_reads[i]->getFile();
+     147          46 :       cloned_file=true;
+     148             :     }
+     149             :   }
+     150          89 :   if( !cloned_file ) {
+     151          62 :     ifile_ptr=Tools::make_unique<IFile>();
+     152          62 :     ifile=ifile_ptr.get();
+     153          62 :     if( !ifile->FileExist(filename) ) error("could not find file named " + filename);
+     154          62 :     ifile->link(*this);
+     155          62 :     ifile->open(filename);
+     156          62 :     ifile->allowIgnoredFields();
+     157             :   }
+     158          89 :   parse("EVERY",nlinesPerStep);
+     159          89 :   if(nlinesPerStep>1) log.printf("  only reading every %uth line of file %s\n",nlinesPerStep,filename.c_str() );
+     160          87 :   else log.printf("  reading data from file %s\n",filename.c_str() );
+     161             :   // Find out what we are reading
+     162          89 :   std::vector<std::string> valread; parseVector("VALUES",valread);
+     163             : 
+     164          89 :   if(nlinesPerStep>1 && cloned_file) error("Opening a file multiple times and using EVERY is not allowed");
+     165             : 
+     166             :   std::size_t dot=valread[0].find_first_of('.');
+     167          89 :   if( valread[0].find(".")!=std::string::npos ) {
+     168           9 :     std::string label=valread[0].substr(0,dot);
+     169           9 :     std::string name=valread[0].substr(dot+1);
+     170           9 :     if( name=="*" ) {
+     171           1 :       if( valread.size()>1 ) error("all values must be from the same Action when using READ");
+     172             :       std::vector<std::string> fieldnames;
+     173           1 :       ifile->scanFieldList( fieldnames );
+     174           8 :       for(unsigned i=0; i<fieldnames.size(); ++i) {
+     175           7 :         if( fieldnames[i].substr(0,dot)==label ) {
+     176           6 :           readvals.emplace_back(Tools::make_unique<Value>(this, fieldnames[i], false) ); addComponentWithDerivatives( fieldnames[i].substr(dot+1) );
+     177           6 :           if( ifile->FieldExist("min_" + fieldnames[i]) ) componentIsPeriodic( fieldnames[i].substr(dot+1), "-pi","pi" );
+     178           6 :           else componentIsNotPeriodic( fieldnames[i].substr(dot+1) );
+     179             :         }
+     180             :       }
+     181           1 :     } else {
+     182           8 :       readvals.emplace_back(Tools::make_unique<Value>(this, valread[0], false) ); addComponentWithDerivatives( name );
+     183          16 :       if( ifile->FieldExist("min_" + valread[0]) ) componentIsPeriodic( valread[0].substr(dot+1), "-pi", "pi" );
+     184          16 :       else componentIsNotPeriodic( valread[0].substr(dot+1) );
+     185          11 :       for(unsigned i=1; i<valread.size(); ++i) {
+     186           6 :         if( valread[i].substr(0,dot)!=label ) error("all values must be from the same Action when using READ");;
+     187           6 :         readvals.emplace_back(Tools::make_unique<Value>(this, valread[i], false) ); addComponentWithDerivatives( valread[i].substr(dot+1) );
+     188           6 :         if( ifile->FieldExist("min_" + valread[i]) ) componentIsPeriodic( valread[i].substr(dot+1), "-pi", "pi" );
+     189           6 :         else componentIsNotPeriodic( valread[i].substr(dot+1) );
+     190             :       }
+     191             :     }
+     192             :   } else {
+     193          80 :     if( valread.size()!=1 ) error("all values must be from the same Action when using READ");
+     194          80 :     readvals.emplace_back(Tools::make_unique<Value>(this, valread[0], false) ); addValueWithDerivatives();
+     195         169 :     if( ifile->FieldExist("min_" + valread[0]) ) setPeriodic( "-pi", "pi" );
+     196          71 :     else setNotPeriodic();
+     197          80 :     log.printf("  reading value %s and storing as %s\n",valread[0].c_str(),getLabel().c_str() );
+     198             :   }
+     199          89 :   checkRead();
+     200         178 : }
+     201             : 
+     202          49 : std::string Read::getFilename() const {
+     203          49 :   return filename;
+     204             : }
+     205             : 
+     206          46 : IFile* Read::getFile() {
+     207          46 :   return ifile;
+     208             : }
+     209             : 
+     210           0 : unsigned Read::getNumberOfDerivatives() {
+     211           0 :   return 0;
+     212             : }
+     213             : 
+     214          26 : void Read::turnOnDerivatives() {
+     215          26 :   if( !ignore_forces ) error("cannot calculate derivatives for colvars that are read in from a file.  If you are postprocessing and "
+     216             :                                "these forces do not matter add the flag IGNORE_FORCES to all READ actions");
+     217          26 : }
+     218             : 
+     219      921429 : void Read::prepare() {
+     220      921429 :   if( !cloned_file ) {
+     221             :     double du_time;
+     222      403414 :     if( !ifile->scanField("time",du_time) ) {
+     223           0 :       error("Reached end of file " + filename + " before end of trajectory");
+     224      201707 :     } else if( std::abs( du_time-getTime() )>getTimeStep() && !ignore_time ) {
+     225           0 :       std::string str_dutime,str_ptime; Tools::convert(du_time,str_dutime); Tools::convert(getTime(),str_ptime);
+     226           0 :       error("mismatched times in colvar files : colvar time=" + str_dutime + " plumed time=" + str_ptime + ". Add IGNORE_TIME to ignore error.");
+     227             :     }
+     228             :   }
+     229      921429 : }
+     230             : 
+     231      921429 : void Read::calculate() {
+     232             :   std::string smin, smax;
+     233     2019293 :   for(unsigned i=0; i<readvals.size(); ++i) {
+     234             : // .get  returns the raw pointer
+     235             : // ->get calls the Value::get() method
+     236     1097864 :     ifile->scanField( readvals[i].get() );
+     237     1097864 :     getPntrToComponent(i)->set( readvals[i]->get() );
+     238     1097864 :     if( readvals[i]->isPeriodic() ) {
+     239        3309 :       readvals[i]->getDomain( smin, smax );
+     240        3309 :       getPntrToComponent(i)->setDomain( smin, smax );
+     241             :     }
+     242             :   }
+     243      921429 : }
+     244             : 
+     245      921429 : void Read::update() {
+     246      921429 :   if( !cloned_file ) {
+     247      403965 :     for(unsigned i=0; i<nlinesPerStep; ++i) {
+     248      202258 :       ifile->scanField(); double du_time;
+     249      404516 :       if( !ifile->scanField("time",du_time) && !plumed.inputsAreActive() ) plumed.stop();
+     250             :     }
+     251             :   }
+     252      921429 : }
+     253             : 
+     254             : }
+     255             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/ResetCell.cpp.func-sort-c.html b/coverage/generic/ResetCell.cpp.func-sort-c.html new file mode 100644 index 000000000000..108dab409a68 --- /dev/null +++ b/coverage/generic/ResetCell.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - generic/ResetCell.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - ResetCell.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:5555100.0 %
Date:2024-04-19 12:12:35Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic9ResetCellC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic9ResetCellC1ERKNS_13ActionOptionsE2
_ZN4PLMD7generic9ResetCell16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD7generic9ResetCell5applyEv17
_ZN4PLMD7generic9ResetCell9calculateEv17
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/ResetCell.cpp.func.html b/coverage/generic/ResetCell.cpp.func.html new file mode 100644 index 000000000000..8f2d487b81f6 --- /dev/null +++ b/coverage/generic/ResetCell.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - generic/ResetCell.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - ResetCell.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:5555100.0 %
Date:2024-04-19 12:12:35Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic9ResetCell16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD7generic9ResetCell5applyEv17
_ZN4PLMD7generic9ResetCell9calculateEv17
_ZN4PLMD7generic9ResetCellC1ERKNS_13ActionOptionsE2
_ZN4PLMD7generic9ResetCellC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/ResetCell.cpp.gcov.html b/coverage/generic/ResetCell.cpp.gcov.html new file mode 100644 index 000000000000..ae26a8c61f5b --- /dev/null +++ b/coverage/generic/ResetCell.cpp.gcov.html @@ -0,0 +1,284 @@ + + + + + + + + LCOV - plumed test coverage - generic/ResetCell.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - ResetCell.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:5555100.0 %
Date:2024-04-19 12:12:35Functions:4580.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionAtomistic.h"
+      23             : #include "core/ActionPilot.h"
+      24             : #include "core/ActionRegister.h"
+      25             : #include "core/PlumedMain.h"
+      26             : #include "core/ActionSet.h"
+      27             : #include "tools/Vector.h"
+      28             : #include "tools/Matrix.h"
+      29             : #include "tools/AtomNumber.h"
+      30             : #include "tools/Tools.h"
+      31             : #include "core/PbcAction.h"
+      32             : #include "tools/Pbc.h"
+      33             : 
+      34             : namespace PLMD {
+      35             : namespace generic {
+      36             : 
+      37             : //+PLUMEDOC GENERIC RESET_CELL
+      38             : /*
+      39             : This action is used to rotate the full cell
+      40             : 
+      41             : This can be used to modify the periodic box. Notice that
+      42             : this is done at fixed scaled coordinates,
+      43             : so that also atomic coordinates for the entire system are affected.
+      44             : To see what effect try
+      45             : the \ref DUMPATOMS directive to output the atomic positions.
+      46             : 
+      47             : Also notice that PLUMED propagate forces correctly so that you can add a bias on a CV computed
+      48             : after rotation. See also \ref FIT_TO_TEMPLATE
+      49             : 
+      50             : Currently, only TYPE=TRIANGULAR is implemented, which allows one to reset
+      51             : the cell to a lower triangular one. Namely, a proper rotation is found that allows
+      52             : rotating the box so that the first lattice vector is in the form (ax,0,0),
+      53             : the second lattice vector is in the form (bx,by,0), and the third lattice vector is
+      54             : arbitrary.
+      55             : 
+      56             : \attention
+      57             : The implementation of this action is available but should be considered in testing phase. Please report any
+      58             : strange behavior.
+      59             : 
+      60             : \attention
+      61             : This directive modifies the stored position at the precise moment
+      62             : it is executed. This means that only collective variables
+      63             : which are below it in the input script will see the corrected positions.
+      64             : Unless you
+      65             : know exactly what you are doing, leave the default stride (1), so that
+      66             : this action is performed at every MD step.
+      67             : 
+      68             : \par Examples
+      69             : 
+      70             : Reset cell to be triangular after a rototranslational fit
+      71             : \plumedfile
+      72             : DUMPATOMS FILE=dump-original.xyz ATOMS=1-20
+      73             : FIT_TO_TEMPLATE STRIDE=1 REFERENCE=ref.pdb TYPE=OPTIMAL
+      74             : DUMPATOMS FILE=dump-fit.xyz ATOMS=1-20
+      75             : RESET_CELL TYPE=TRIANGULAR
+      76             : DUMPATOMS FILE=dump-reset.xyz ATOMS=1-20
+      77             : \endplumedfile
+      78             : 
+      79             : The reference file for the FIT_TO_TEMPLATE is just a normal pdb file with the format shown below:
+      80             : 
+      81             : \auxfile{ref.pdb}
+      82             : ATOM      8  HT3 ALA     2      -1.480  -1.560   1.212  1.00  1.00      DIA  H
+      83             : ATOM      9  CAY ALA     2      -0.096   2.144  -0.669  1.00  1.00      DIA  C
+      84             : ATOM     10  HY1 ALA     2       0.871   2.385  -0.588  1.00  1.00      DIA  H
+      85             : ATOM     12  HY3 ALA     2      -0.520   2.679  -1.400  1.00  1.00      DIA  H
+      86             : ATOM     14  OY  ALA     2      -1.139   0.931  -0.973  1.00  1.00      DIA  O
+      87             : END
+      88             : \endauxfile
+      89             : 
+      90             : */
+      91             : //+ENDPLUMEDOC
+      92             : 
+      93             : 
+      94             : class ResetCell:
+      95             :   public ActionPilot,
+      96             :   public ActionAtomistic
+      97             : {
+      98             :   std::string type;
+      99             :   Tensor rotation,newbox;
+     100             :   Value* boxValue;
+     101             :   PbcAction* pbc_action;
+     102             : public:
+     103             :   explicit ResetCell(const ActionOptions&ao);
+     104             :   static void registerKeywords( Keywords& keys );
+     105             :   void calculate() override;
+     106             :   void apply() override;
+     107             : };
+     108             : 
+     109             : PLUMED_REGISTER_ACTION(ResetCell,"RESET_CELL")
+     110             : 
+     111           4 : void ResetCell::registerKeywords( Keywords& keys ) {
+     112           4 :   Action::registerKeywords( keys );
+     113           4 :   ActionAtomistic::registerKeywords( keys );
+     114           8 :   keys.add("compulsory","STRIDE","1","the frequency with which molecules are reassembled.  Unless you are completely certain about what you are doing leave this set equal to 1!");
+     115           8 :   keys.add("compulsory","TYPE","TRIANGULAR","the manner in which the cell is reset");
+     116           4 : }
+     117             : 
+     118           2 : ResetCell::ResetCell(const ActionOptions&ao):
+     119             :   Action(ao),
+     120             :   ActionPilot(ao),
+     121           2 :   ActionAtomistic(ao)
+     122             : {
+     123           2 :   type.assign("TRIANGULAR");
+     124           2 :   parse("TYPE",type);
+     125             : 
+     126           2 :   log<<"  type: "<<type<<"\n";
+     127           2 :   if(type!="TRIANGULAR") error("undefined type "+type);
+     128             : 
+     129           2 :   pbc_action=plumed.getActionSet().selectWithLabel<PbcAction*>("Box");
+     130           2 :   if( !pbc_action ) error("cannot reset cell if box has not been set");
+     131           2 :   boxValue=pbc_action->copyOutput(0);
+     132           2 : }
+     133             : 
+     134             : 
+     135          17 : void ResetCell::calculate() {
+     136          17 :   Pbc & pbc(pbc_action->getPbc());
+     137          17 :   Tensor box=pbc.getBox();
+     138             : 
+     139             : // moduli of lattice vectors
+     140          17 :   double a=modulo(box.getRow(0));
+     141          17 :   double b=modulo(box.getRow(1));
+     142          17 :   double c=modulo(box.getRow(2));
+     143             : // cos-angle between lattice vectors
+     144          17 :   double ab=dotProduct(box.getRow(0),box.getRow(1))/(a*b);
+     145          17 :   double ac=dotProduct(box.getRow(0),box.getRow(2))/(a*c);
+     146          17 :   double bc=dotProduct(box.getRow(1),box.getRow(2))/(b*c);
+     147             : 
+     148             : // generate a new set of lattice vectors as a lower triangular matrix
+     149          17 :   newbox[0][0]=a;
+     150          17 :   newbox[1][0]=b*ab;
+     151          17 :   newbox[1][1]=std::sqrt(b*b-newbox[1][0]*newbox[1][0]);
+     152          17 :   newbox[2][0]=c*ac;
+     153          17 :   newbox[2][1]=c*(bc-ac*ab)/std::sqrt(1-ab*ab);
+     154          17 :   newbox[2][2]=std::sqrt(c*c-newbox[2][0]*newbox[2][0]-newbox[2][1]*newbox[2][1]);
+     155             : 
+     156          17 :   if(determinant(newbox)*determinant(box)<0) newbox[2][2]=-newbox[2][2];
+     157             : 
+     158             : // rotation matrix from old to new coordinates
+     159          17 :   rotation=transpose(matmul(inverse(box),newbox));
+     160             : 
+     161             : // rotate all coordinates
+     162          17 :   unsigned nat = getTotAtoms();
+     163        1623 :   for(unsigned i=0; i<nat; i++) {
+     164        1606 :     std::pair<std::size_t,std::size_t> a = getValueIndices( AtomNumber::index(i));
+     165        1606 :     Vector ato=matmul(rotation,getGlobalPosition(a));
+     166        1606 :     setGlobalPosition(a,ato);
+     167             :   }
+     168             : // rotate box
+     169          17 :   pbc.setBox(newbox);
+     170          17 : }
+     171             : 
+     172          17 : void ResetCell::apply() {
+     173             : // rotate back forces
+     174          17 :   unsigned nat = getTotAtoms();
+     175        1623 :   for(unsigned i=0; i<nat; i++) {
+     176        1606 :     std::pair<std::size_t,std::size_t> a = getValueIndices( AtomNumber::index(i));
+     177        1606 :     Vector f=getForce(a);
+     178        1606 :     Vector nf=matmul(transpose(rotation),f);
+     179        1606 :     addForce(a, nf-f );
+     180             :   }
+     181             : 
+     182             : // I have no mathematical derivation for this.
+     183             : // The reasoning is the following.
+     184             : // virial= h^T * dU/dh, where h is the box matrix and dU/dh its derivatives.
+     185             : // The final virial should be rotationally invariant, that is symmetric.
+     186             : // in the rotated frame, dU/dh elements [0][1], [0][2], and [1][2] should
+     187             : // be changed so as to enforce rotational invariance. Thus we here have to
+     188             : // make the virial matrix symmetric.
+     189             : // Since h^T is upper triangular, it can be shown that any change in these elements
+     190             : // will only affect the corresponding elements of the virial matrix.
+     191             : // Thus, the only possibility is to set the corresponding elements
+     192             : // of the virial matrix equal to their symmetric ones.
+     193             : // GB
+     194          17 :   Tensor virial;
+     195         221 :   for(unsigned i=0; i<3; ++i) for(unsigned j=0; j<3; ++j) virial[i][j]=boxValue->getForce( 3*i+j );
+     196          17 :   virial[0][1]=virial[1][0];
+     197          17 :   virial[0][2]=virial[2][0];
+     198          17 :   virial[1][2]=virial[2][1];
+     199             : // rotate back virial
+     200          17 :   virial=matmul(transpose(rotation),matmul(virial,rotation)); boxValue->clearInputForce();
+     201         221 :   for(unsigned i=0; i<3; ++i) for(unsigned j=0; j<3; ++j) boxValue->addForce( 3*i+j, virial(i,j) );
+     202             : 
+     203             : 
+     204          17 : }
+     205             : 
+     206             : }
+     207             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/Time.cpp.func-sort-c.html b/coverage/generic/Time.cpp.func-sort-c.html new file mode 100644 index 000000000000..1eb898cecf6e --- /dev/null +++ b/coverage/generic/Time.cpp.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - generic/Time.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - Time.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:41428.6 %
Date:2024-04-19 12:12:35Functions:1616.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic4Time22getNumberOfDerivativesEv0
_ZN4PLMD7generic4Time5applyEv0
_ZN4PLMD7generic4Time9calculateEv0
_ZN4PLMD7generic4TimeC1ERKNS_13ActionOptionsE0
_ZN4PLMD7generic4TimeC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic4Time16registerKeywordsERNS_8KeywordsE2
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/Time.cpp.func.html b/coverage/generic/Time.cpp.func.html new file mode 100644 index 000000000000..e75f5de40f41 --- /dev/null +++ b/coverage/generic/Time.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - generic/Time.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - Time.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:41428.6 %
Date:2024-04-19 12:12:35Functions:1616.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic4Time16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD7generic4Time22getNumberOfDerivativesEv0
_ZN4PLMD7generic4Time5applyEv0
_ZN4PLMD7generic4Time9calculateEv0
_ZN4PLMD7generic4TimeC1ERKNS_13ActionOptionsE0
_ZN4PLMD7generic4TimeC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/Time.cpp.gcov.html b/coverage/generic/Time.cpp.gcov.html new file mode 100644 index 000000000000..bb4c6a8758d3 --- /dev/null +++ b/coverage/generic/Time.cpp.gcov.html @@ -0,0 +1,156 @@ + + + + + + + + LCOV - plumed test coverage - generic/Time.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - Time.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:41428.6 %
Date:2024-04-19 12:12:35Functions:1616.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionWithValue.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include <string>
+      25             : #include <cmath>
+      26             : 
+      27             : namespace PLMD {
+      28             : namespace generic {
+      29             : 
+      30             : //+PLUMEDOC GENERIC TIME
+      31             : /*
+      32             : retrieve the time of the simulation to be used elsewhere
+      33             : 
+      34             : \par Examples
+      35             : 
+      36             : \plumedfile
+      37             : TIME            LABEL=t1
+      38             : PRINT ARG=t1
+      39             : \endplumedfile
+      40             : 
+      41             : */
+      42             : //+ENDPLUMEDOC
+      43             : 
+      44             : class Time : public ActionWithValue {
+      45             : public:
+      46             :   static void registerKeywords( Keywords& keys );
+      47             :   explicit Time(const ActionOptions&);
+      48             : // active methods:
+      49             :   void calculate() override;
+      50           0 :   void apply() override {}
+      51           0 :   unsigned getNumberOfDerivatives() override { return 0; }
+      52             : };
+      53             : 
+      54             : PLUMED_REGISTER_ACTION(Time,"TIME")
+      55             : 
+      56           2 : void Time::registerKeywords( Keywords& keys ) {
+      57           2 :   Action::registerKeywords( keys );
+      58           2 :   ActionWithValue::registerKeywords( keys );
+      59           2 : }
+      60             : 
+      61           0 : Time::Time(const ActionOptions&ao):
+      62           0 :   Action(ao),ActionWithValue(ao)
+      63             : {
+      64           0 :   addValueWithDerivatives(); setNotPeriodic();
+      65             :   // resize derivative by hand to a nonzero value
+      66           0 :   getPntrToValue()->resizeDerivatives(1);
+      67           0 : }
+      68             : 
+      69           0 : void Time::calculate() {
+      70           0 :   setValue           (getTime());
+      71           0 : }
+      72             : 
+      73             : }
+      74             : 
+      75             : 
+      76             : 
+      77             : 
+      78             : 
+      79             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/UpdateIf.cpp.func-sort-c.html b/coverage/generic/UpdateIf.cpp.func-sort-c.html new file mode 100644 index 000000000000..711cdf870599 --- /dev/null +++ b/coverage/generic/UpdateIf.cpp.func-sort-c.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - generic/UpdateIf.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - UpdateIf.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4242100.0 %
Date:2024-04-19 12:12:35Functions:81080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic8UpdateIfC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic8UpdateIfD2Ev0
_ZN4PLMD7generic8UpdateIfC1ERKNS_13ActionOptionsE7
_ZN4PLMD7generic8UpdateIfD0Ev7
_ZN4PLMD7generic8UpdateIfD1Ev7
_ZN4PLMD7generic8UpdateIf16registerKeywordsERNS_8KeywordsE9
_ZN4PLMD7generic8UpdateIf12beforeUpdateEv28
_ZN4PLMD7generic8UpdateIf5applyEv28
_ZN4PLMD7generic8UpdateIf7prepareEv28
_ZN4PLMD7generic8UpdateIf9calculateEv28
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/UpdateIf.cpp.func.html b/coverage/generic/UpdateIf.cpp.func.html new file mode 100644 index 000000000000..68a894448ffe --- /dev/null +++ b/coverage/generic/UpdateIf.cpp.func.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - generic/UpdateIf.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - UpdateIf.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4242100.0 %
Date:2024-04-19 12:12:35Functions:81080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic8UpdateIf12beforeUpdateEv28
_ZN4PLMD7generic8UpdateIf16registerKeywordsERNS_8KeywordsE9
_ZN4PLMD7generic8UpdateIf5applyEv28
_ZN4PLMD7generic8UpdateIf7prepareEv28
_ZN4PLMD7generic8UpdateIf9calculateEv28
_ZN4PLMD7generic8UpdateIfC1ERKNS_13ActionOptionsE7
_ZN4PLMD7generic8UpdateIfC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic8UpdateIfD0Ev7
_ZN4PLMD7generic8UpdateIfD1Ev7
_ZN4PLMD7generic8UpdateIfD2Ev0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/UpdateIf.cpp.gcov.html b/coverage/generic/UpdateIf.cpp.gcov.html new file mode 100644 index 000000000000..b776c91e7a2b --- /dev/null +++ b/coverage/generic/UpdateIf.cpp.gcov.html @@ -0,0 +1,235 @@ + + + + + + + + LCOV - plumed test coverage - generic/UpdateIf.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - UpdateIf.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4242100.0 %
Date:2024-04-19 12:12:35Functions:81080.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionPilot.h"
+      23             : #include "core/ActionWithArguments.h"
+      24             : #include "core/ActionRegister.h"
+      25             : #include "core/PlumedMain.h"
+      26             : 
+      27             : namespace PLMD {
+      28             : namespace generic {
+      29             : 
+      30             : //+PLUMEDOC PRINTANALYSIS UPDATE_IF
+      31             : /*
+      32             : Conditional update of other actions.
+      33             : 
+      34             : 
+      35             : This action can be used to enable and disable the update step for the following actions
+      36             : depending on the value of its arguments. This allows for example to extract snapshots
+      37             : with value of some CVs in a given range.
+      38             : 
+      39             : When called with MORE_THAN and/or LESS_THAN keywords, this action starts an if block.
+      40             : The block is executed if all the arguments are less than all the respective values
+      41             : in the LESS_THAN keyword (if present) and all the arguments are more than all the
+      42             : respective values
+      43             : in the MORE_THAN keyword (if present).
+      44             : 
+      45             : When called with the END flag, this action ends the corresponding IF block.
+      46             : Notice that in this case one should also provide the ARG keyword. It is recommended to
+      47             : use the same ARG keyword that was used to begin the block, so as to make the input more readable.
+      48             : 
+      49             : Of course, blocks can be nested at will.
+      50             : 
+      51             : There are many potential usages for this keyword. One might e.g. decide to analyze some variable
+      52             : only when another variable is within a given range.
+      53             : 
+      54             : \warning
+      55             : Notice that not all the possible usage make
+      56             : particular sense. For example, conditionally updating a \ref METAD keyword
+      57             : (that is: adding hills only if a variable is within a given range)
+      58             : can lead to unexpected results.
+      59             : 
+      60             : \par Examples
+      61             : 
+      62             : The following input instructs plumed dump all the snapshots where an atom is in touch with
+      63             : the solute.
+      64             : \plumedfile
+      65             : solute: GROUP ATOMS=1-124
+      66             : coord: COORDINATION GROUPA=solute GROUPB=500 R_0=0.5
+      67             : 
+      68             : # A coordination number higher than 0.5 indicate that there is at least one
+      69             : # atom of group `solute` at less than 5 A from atom number 500
+      70             : 
+      71             : UPDATE_IF ARG=coord MORE_THAN=0.5
+      72             : DUMPATOMS ATOMS=solute,500 FILE=output.xyz
+      73             : UPDATE_IF ARG=coord END
+      74             : \endplumedfile
+      75             : 
+      76             : */
+      77             : //+ENDPLUMEDOC
+      78             : 
+      79             : class UpdateIf:
+      80             :   public ActionPilot,
+      81             :   public ActionWithArguments
+      82             : {
+      83             :   std::vector<double> lower;
+      84             :   std::vector<double> upper;
+      85             :   bool on;
+      86             :   bool end;
+      87             : public:
+      88             :   void prepare() override;
+      89             :   void calculate() override;
+      90             :   void beforeUpdate() override;
+      91             :   explicit UpdateIf(const ActionOptions&);
+      92             :   static void registerKeywords(Keywords& keys);
+      93          28 :   void apply() override {}
+      94             :   ~UpdateIf();
+      95             : };
+      96             : 
+      97             : PLUMED_REGISTER_ACTION(UpdateIf,"UPDATE_IF")
+      98             : 
+      99           9 : void UpdateIf::registerKeywords(Keywords& keys) {
+     100           9 :   Action::registerKeywords(keys);
+     101           9 :   ActionPilot::registerKeywords(keys);
+     102           9 :   ActionWithArguments::registerKeywords(keys);
+     103           9 :   keys.use("ARG");
+     104          18 :   keys.add("compulsory","STRIDE","1","the frequency with which the quantities of interest should be output");
+     105          18 :   keys.addFlag("END",false,"end");
+     106          18 :   keys.add("optional","LESS_THAN","upper bound");
+     107          18 :   keys.add("optional","MORE_THAN","lower bound");
+     108           9 : }
+     109             : 
+     110           7 : UpdateIf::UpdateIf(const ActionOptions&ao):
+     111             :   Action(ao),
+     112             :   ActionPilot(ao),
+     113             :   ActionWithArguments(ao),
+     114           7 :   on(false),
+     115           7 :   end(false)
+     116             : {
+     117           7 :   parseFlag("END",end);
+     118           7 :   parseVector("LESS_THAN",upper);
+     119           7 :   parseVector("MORE_THAN",lower);
+     120           7 :   if(end && upper.size()!=0) error("END and LESS_THAN are not compatible");
+     121           7 :   if(end && lower.size()!=0) error("END and MORE_THAN are not compatible");
+     122           7 :   if(upper.size()==0) upper.assign(getNumberOfArguments(),+std::numeric_limits<double>::max());
+     123           7 :   if(lower.size()==0) lower.assign(getNumberOfArguments(),-std::numeric_limits<double>::max());
+     124           7 :   if(upper.size()!=getNumberOfArguments()) error("LESS_THAN should have the same size as ARG");
+     125           7 :   if(lower.size()!=getNumberOfArguments()) error("MORE_THAN should have the same size as ARG");
+     126          15 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     127           8 :     log<<"  boundaries for argument "<<i<<"    "<<lower[i]<<" "<<upper[i]<<"\n";
+     128             :   }
+     129           7 :   checkRead();
+     130           7 : }
+     131             : 
+     132          28 : void UpdateIf::prepare() {
+     133          28 :   on=false;
+     134          28 : }
+     135             : 
+     136          28 : void UpdateIf::calculate() {
+     137          28 :   on=true;
+     138          60 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     139          32 :     if(getArgument(i)>=upper[i] || getArgument(i)<=lower[i]) on=false;
+     140             :   }
+     141          28 : }
+     142             : 
+     143          28 : void UpdateIf::beforeUpdate() {
+     144          28 :   if(end) plumed.updateFlagsPop();
+     145             :   else {
+     146          23 :     if(on) plumed.updateFlagsPush(plumed.updateFlagsTop());
+     147           9 :     else   plumed.updateFlagsPush(false);
+     148             :   }
+     149          28 : }
+     150             : 
+     151             : 
+     152          14 : UpdateIf::~UpdateIf() {
+     153          14 : }
+     154             : 
+     155             : }
+     156             : 
+     157             : 
+     158             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/WholeMolecules.cpp.func-sort-c.html b/coverage/generic/WholeMolecules.cpp.func-sort-c.html new file mode 100644 index 000000000000..1b97ff453334 --- /dev/null +++ b/coverage/generic/WholeMolecules.cpp.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + 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:778788.5 %
Date:2024-04-19 12:12:35Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic14WholeMoleculesC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic14WholeMoleculesC1ERKNS_13ActionOptionsE57
_ZN4PLMD7generic14WholeMolecules16registerKeywordsERNS_8KeywordsE59
_ZN4PLMD7generic14WholeMolecules15actionHasForcesEv841
_ZN4PLMD7generic14WholeMolecules5applyEv9887
_ZN4PLMD7generic14WholeMolecules9calculateEv9887
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/WholeMolecules.cpp.func.html b/coverage/generic/WholeMolecules.cpp.func.html new file mode 100644 index 000000000000..12eca825dee9 --- /dev/null +++ b/coverage/generic/WholeMolecules.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + 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:778788.5 %
Date:2024-04-19 12:12:35Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic10WrapAround15actionHasForcesEv0
_ZN4PLMD7generic10WrapAroundC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic10WrapAroundC1ERKNS_13ActionOptionsE6
_ZN4PLMD7generic10WrapAround16registerKeywordsERNS_8KeywordsE8
_ZN4PLMD7generic10WrapAround5applyEv590
_ZN4PLMD7generic10WrapAround9calculateEv590
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/WrapAround.cpp.func.html b/coverage/generic/WrapAround.cpp.func.html new file mode 100644 index 000000000000..9e1d03e64658 --- /dev/null +++ b/coverage/generic/WrapAround.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + 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:575996.6 %
Date:2024-04-19 12:12:35Functions:4666.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic10WrapAround15actionHasForcesEv0
_ZN4PLMD7generic10WrapAround16registerKeywordsERNS_8KeywordsE8
_ZN4PLMD7generic10WrapAround5applyEv590
_ZN4PLMD7generic10WrapAround9calculateEv590
_ZN4PLMD7generic10WrapAroundC1ERKNS_13ActionOptionsE6
_ZN4PLMD7generic10WrapAroundC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/WrapAround.cpp.gcov.html b/coverage/generic/WrapAround.cpp.gcov.html new file mode 100644 index 000000000000..318b52c76310 --- /dev/null +++ b/coverage/generic/WrapAround.cpp.gcov.html @@ -0,0 +1,334 @@ + + + + + + + + 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:575996.6 %
Date:2024-04-19 12:12:35Functions:4666.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2014-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionAtomistic.h"
+      23             : #include "core/ActionPilot.h"
+      24             : #include "core/ActionRegister.h"
+      25             : #include "tools/Vector.h"
+      26             : #include "tools/AtomNumber.h"
+      27             : #include "tools/Tools.h"
+      28             : #include "core/PlumedMain.h"
+      29             : #include "core/ActionSet.h"
+      30             : #include "core/GenericMolInfo.h"
+      31             : 
+      32             : #include <vector>
+      33             : 
+      34             : namespace PLMD {
+      35             : namespace generic {
+      36             : 
+      37             : //+PLUMEDOC GENERIC WRAPAROUND
+      38             : /*
+      39             : Rebuild periodic boundary conditions around chosen atoms.
+      40             : 
+      41             : 
+      42             : Modify position of atoms indicated by ATOMS by shifting them by lattice vectors so that they are
+      43             : as close as possible to the atoms indicated by AROUND. More precisely, for every atom i
+      44             : in the ATOMS list the following procedure is performed:
+      45             : - The atom j among those in the AROUND list is searched that is closest to atom i.
+      46             : - The atom i is replaced with its periodic image that is closest to atom j.
+      47             : 
+      48             : This action works similarly to \ref WHOLEMOLECULES in that it replaces atoms coordinate. Notice that only
+      49             : atoms specified with ATOMS are replaced, and that, at variance with \ref WHOLEMOLECULES,
+      50             : the order in which atoms are specified is irrelevant.
+      51             : 
+      52             : This is often convenient at a post processing stage (using the \ref driver), but sometime
+      53             : it is required during the simulation if collective variables need atoms to be in a specific periodic image.
+      54             : 
+      55             : \attention This directive modifies the stored position at the precise moment it is executed. This means that only collective variables which are below it in the input script will see the corrected positions. As a general rule, put it at the top of the input file. Also, unless you know exactly what you are doing, leave the default stride (1), so that this action is performed at every MD step.
+      56             : 
+      57             : Consider that the computational cost grows with the product
+      58             : of the size of the two lists (ATOMS and AROUND), so that this action can become very expensive.
+      59             : If you are using it to analyze a trajectory this is usually not a big problem. If you use it to
+      60             : analyze a simulation on the fly, e.g. with \ref DUMPATOMS to store a properly wrapped trajectory,
+      61             : consider the possibility of using the STRIDE keyword here (with great care).
+      62             : \par Examples
+      63             : 
+      64             : This command instructs plumed to move all the ions to their periodic image that is as close as possible to
+      65             : the rna group.
+      66             : 
+      67             : \plumedfile
+      68             : rna: GROUP ATOMS=1-100
+      69             : ions: GROUP ATOMS=101-110
+      70             : # first make the rna molecule whole
+      71             : WHOLEMOLECULES ENTITY0=rna
+      72             : WRAPAROUND ATOMS=ions AROUND=rna
+      73             : DUMPATOMS FILE=dump.xyz ATOMS=rna,ions
+      74             : \endplumedfile
+      75             : 
+      76             : In case you want to do it during a simulation and you only care about wrapping the ions in
+      77             : the `dump.xyz` file, you can use the following:
+      78             : 
+      79             : \plumedfile
+      80             : # add some restraint that do not require molecules to be whole:
+      81             : a: TORSION ATOMS=1,2,10,11
+      82             : RESTRAINT ARG=a AT=0.0 KAPPA=5
+      83             : 
+      84             : 
+      85             : # then do the things that are required for dumping the trajectory
+      86             : # notice that they are all done every 100 steps, so as not to
+      87             : # unnecessarily overload the calculation
+      88             : 
+      89             : rna: GROUP ATOMS=1-100
+      90             : ions: GROUP ATOMS=101-110
+      91             : # first make the rna molecule whole
+      92             : WHOLEMOLECULES ENTITY0=rna STRIDE=100
+      93             : WRAPAROUND ATOMS=ions AROUND=rna STRIDE=100
+      94             : DUMPATOMS FILE=dump.xyz ATOMS=rna,ions STRIDE=100
+      95             : \endplumedfile
+      96             : 
+      97             : Notice that if the biased variable requires a molecule to be whole, you might have to put
+      98             : just the \ref WHOLEMOLECULES command before computing that variable and leave the default STRIDE=1.
+      99             : 
+     100             : This command instructs plumed to center all atoms around the center of mass of a solute molecule.
+     101             : 
+     102             : \plumedfile
+     103             : solute: GROUP ATOMS=1-100
+     104             : all: GROUP ATOMS=1-1000
+     105             : # center of the solute:
+     106             : # notice that since plumed 2.2 this also works if the
+     107             : # solute molecule is broken
+     108             : com: COM ATOMS=solute
+     109             : # notice that we wrap around a single atom. this should be fast
+     110             : WRAPAROUND ATOMS=all AROUND=com
+     111             : DUMPATOMS FILE=dump.xyz ATOMS=all
+     112             : \endplumedfile
+     113             : 
+     114             : Notice that whereas \ref WHOLEMOLECULES is designed to make molecules whole,
+     115             : \ref WRAPAROUND can easily break molecules. In the last example,
+     116             : if solvent (atoms 101-1000) is made e.g. of water, then water
+     117             : molecules could be broken by \ref WRAPAROUND (hydrogen could end up
+     118             : in an image and oxygen in another one).
+     119             : One solution is to use \ref WHOLEMOLECULES on _all_ the water molecules
+     120             : after \ref WRAPAROUND. This is tedious. A better solution is to use the
+     121             : GROUPBY option which is going
+     122             : to consider the atoms listed in ATOMS as a list of groups
+     123             : each of size GROUPBY. The first atom of the group will be brought
+     124             : close to the AROUND atoms. The following atoms of the group
+     125             : will be just brought close to the first atom of the group.
+     126             : Assuming that oxygen is the first atom of each water molecules,
+     127             : in the following examples all the water oxygen atoms will be brought
+     128             : close to the solute, and all the hydrogen atoms will be kept close
+     129             : to their related oxygen.
+     130             : 
+     131             : \plumedfile
+     132             : solute: GROUP ATOMS=1-100
+     133             : water: GROUP ATOMS=101-1000
+     134             : com: COM ATOMS=solute
+     135             : # notice that we wrap around a single atom. this should be fast
+     136             : WRAPAROUND ATOMS=solute AROUND=com
+     137             : # notice that we wrap around a single atom. this should be fast
+     138             : WRAPAROUND ATOMS=water AROUND=com GROUPBY=3
+     139             : DUMPATOMS FILE=dump.xyz ATOMS=solute,water
+     140             : \endplumedfile
+     141             : 
+     142             : */
+     143             : //+ENDPLUMEDOC
+     144             : 
+     145             : 
+     146             : class WrapAround:
+     147             :   public ActionPilot,
+     148             :   public ActionAtomistic
+     149             : {
+     150             :   // cppcheck-suppress duplInheritedMember
+     151             :   std::vector<Vector> refatoms;
+     152             :   std::vector<std::pair<std::size_t,std::size_t> > p_atoms;
+     153             :   std::vector<std::pair<std::size_t,std::size_t> > p_reference;
+     154             :   unsigned groupby;
+     155             :   bool pair_;
+     156             : public:
+     157             :   explicit WrapAround(const ActionOptions&ao);
+     158             :   static void registerKeywords( Keywords& keys );
+     159           0 :   bool actionHasForces() override { return false; }
+     160             :   void calculate() override;
+     161         590 :   void apply() override {}
+     162             : };
+     163             : 
+     164             : PLUMED_REGISTER_ACTION(WrapAround,"WRAPAROUND")
+     165             : 
+     166           8 : void WrapAround::registerKeywords( Keywords& keys ) {
+     167           8 :   Action::registerKeywords( keys );
+     168           8 :   ActionAtomistic::registerKeywords( keys );
+     169           8 :   ActionPilot::registerKeywords( keys );
+     170          16 :   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!");
+     171          16 :   keys.add("atoms","AROUND","reference atoms");
+     172          16 :   keys.add("atoms","ATOMS","wrapped atoms");
+     173          16 :   keys.add("compulsory","GROUPBY","1","group atoms so as not to break molecules");
+     174          16 :   keys.addFlag("PAIR", false, "Pair atoms in AROUND and ATOMS groups");
+     175           8 : }
+     176             : 
+     177           6 : WrapAround::WrapAround(const ActionOptions&ao):
+     178             :   Action(ao),
+     179             :   ActionPilot(ao),
+     180             :   ActionAtomistic(ao),
+     181           6 :   groupby(1),
+     182           6 :   pair_(false)
+     183             : {
+     184          12 :   std::vector<AtomNumber> atoms; parseAtomList("ATOMS",atoms);
+     185           6 :   std::vector<AtomNumber> reference; parseAtomList("AROUND",reference);
+     186           6 :   parse("GROUPBY",groupby);
+     187           6 :   parseFlag("PAIR", pair_);
+     188             : 
+     189           6 :   log.printf("  atoms in reference :");
+     190          13 :   for(unsigned j=0; j<reference.size(); ++j) log.printf(" %d",reference[j].serial() );
+     191           6 :   log.printf("\n");
+     192           6 :   log.printf("  atoms to be wrapped :");
+     193         422 :   for(unsigned j=0; j<atoms.size(); ++j) log.printf(" %d",atoms[j].serial() );
+     194           6 :   log.printf("\n");
+     195           6 :   if(groupby>1) log<<"  atoms will be grouped by "<<groupby<<"\n";
+     196           6 :   if(pair_) log.printf("  pairing atoms and references\n");
+     197             : 
+     198           6 :   if(atoms.size()%groupby!=0) error("number of atoms should be a multiple of groupby option");
+     199             :   // additional checks with PAIR
+     200           6 :   if(pair_ && atoms.size()!=reference.size()*groupby) error("with PAIR you must have: #ATOMS = #AROUND * #GROUPBY");
+     201             : 
+     202           6 :   checkRead();
+     203             : 
+     204             :   // do not remove duplicates with pair
+     205           6 :   if(!pair_) {
+     206           6 :     if(groupby<=1) Tools::removeDuplicates(atoms);
+     207           6 :     Tools::removeDuplicates(reference);
+     208             :   }
+     209             : 
+     210           6 :   std::vector<AtomNumber> merged(atoms.size()+reference.size());
+     211           6 :   merge(atoms.begin(),atoms.end(),reference.begin(),reference.end(),merged.begin());
+     212         428 :   p_atoms.resize( atoms.size() ); for(unsigned i=0; i<atoms.size(); ++i) p_atoms[i] = getValueIndices( atoms[i] );
+     213           6 :   refatoms.resize( reference.size() ); p_reference.resize( reference.size() );
+     214          13 :   for(unsigned i=0; i<reference.size(); ++i) p_reference[i] = getValueIndices( reference[i] );
+     215           6 :   Tools::removeDuplicates(merged);
+     216           6 :   requestAtoms(merged);
+     217             :   doNotRetrieve();
+     218             :   doNotForce();
+     219           6 : }
+     220             : 
+     221         590 : void WrapAround::calculate() {
+     222        1185 :   for(unsigned j=0; j<p_reference.size(); ++j) refatoms[j] = getGlobalPosition(p_reference[j]);
+     223             : 
+     224       15265 :   for(unsigned i=0; i<p_atoms.size(); i+=groupby) {
+     225       14675 :     Vector second, first=getGlobalPosition(p_atoms[i]);
+     226             :     double mindist2=std::numeric_limits<double>::max();
+     227             :     int closest=-1;
+     228       14675 :     if(pair_) {
+     229           0 :       closest = i/groupby;
+     230             :     } else {
+     231       29900 :       for(unsigned j=0; j<p_reference.size(); ++j) {
+     232       15225 :         second=refatoms[j];
+     233             :         const Vector distance=pbcDistance(first,second);
+     234       15225 :         const double distance2=modulo2(distance);
+     235       15225 :         if(distance2<mindist2) {
+     236             :           mindist2=distance2;
+     237       14955 :           closest=j;
+     238             :         }
+     239             :       }
+     240       14675 :       plumed_massert(closest>=0,"closest not found");
+     241             :     }
+     242       14675 :     second=refatoms[closest];
+     243             : // place first atom of the group
+     244       14675 :     first=second+pbcDistance(second,first); setGlobalPosition(p_atoms[i],first);
+     245             : // then place other atoms close to the first of the group
+     246       15170 :     for(unsigned j=1; j<groupby; j++) {
+     247         495 :       second=getGlobalPosition(p_atoms[i+j]);
+     248         495 :       setGlobalPosition( p_atoms[i+j], first+pbcDistance(first,second) );
+     249             :     }
+     250             :   }
+     251         590 : }
+     252             : 
+     253             : 
+     254             : 
+     255             : }
+     256             : 
+     257             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/index-sort-f.html b/coverage/generic/index-sort-f.html new file mode 100644 index 000000000000..f2a8b7661fd8 --- /dev/null +++ b/coverage/generic/index-sort-f.html @@ -0,0 +1,344 @@ + + + + + + + + LCOV - plumed test coverage - generic + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - genericHitTotalCoverage
Test:plumed test coverageLines:1555163495.2 %
Date:2024-04-19 12:12:35Functions:14720173.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Time.cpp +
28.6%28.6%
+
28.6 %4 / 1416.7 %1 / 6
RandomExchanges.cpp +
30.8%30.8%
+
30.8 %4 / 1325.0 %1 / 4
Include.cpp +
83.3%83.3%
+
83.3 %10 / 1240.0 %2 / 5
Constant.cpp +
92.1%92.1%
+
92.1 %58 / 6342.9 %3 / 7
EndPlumed.cpp +
80.0%80.0%
+
80.0 %8 / 1050.0 %2 / 4
Ones.cpp +
100.0%
+
100.0 %11 / 1166.7 %2 / 3
PDB2Constant.cpp +
98.2%98.2%
+
98.2 %54 / 5566.7 %2 / 3
WrapAround.cpp +
96.6%96.6%
+
96.6 %57 / 5966.7 %4 / 6
PrintNDX.cpp +
90.3%90.3%
+
90.3 %56 / 6269.2 %9 / 13
FitToTemplate.cpp +
97.2%97.2%
+
97.2 %104 / 10771.4 %5 / 7
DumpMassCharge.cpp +
96.9%96.9%
+
96.9 %62 / 6472.7 %8 / 11
DumpAtoms.cpp +
97.3%97.3%
+
97.3 %142 / 14676.9 %10 / 13
DumpForces.cpp +
100.0%
+
100.0 %37 / 3777.8 %7 / 9
DumpDerivatives.cpp +
100.0%
+
100.0 %48 / 4877.8 %7 / 9
EffectiveEnergyDrift.cpp +
97.4%97.4%
+
97.4 %147 / 15177.8 %7 / 9
ResetCell.cpp +
100.0%
+
100.0 %55 / 5580.0 %4 / 5
Debug.cpp +
100.0%
+
100.0 %56 / 5680.0 %4 / 5
UpdateIf.cpp +
100.0%
+
100.0 %42 / 4280.0 %8 / 10
DumpProjections.cpp +
100.0%
+
100.0 %38 / 3880.0 %8 / 10
Print.cpp +
96.7%96.7%
+
96.7 %58 / 6081.8 %9 / 11
Read.cpp +
94.9%94.9%
+
94.9 %94 / 9981.8 %9 / 11
WholeMolecules.cpp +
88.5%88.5%
+
88.5 %77 / 8783.3 %5 / 6
Plumed.cpp +
93.3%93.3%
+
93.3 %166 / 17883.3 %10 / 12
DumpPDB.cpp +
100.0%
+
100.0 %94 / 9487.5 %7 / 8
DumpVector.cpp +
100.0%
+
100.0 %54 / 5488.9 %8 / 9
Flush.cpp +
100.0%
+
100.0 %19 / 19100.0 %5 / 5
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/index-sort-l.html b/coverage/generic/index-sort-l.html new file mode 100644 index 000000000000..22236a2d339f --- /dev/null +++ b/coverage/generic/index-sort-l.html @@ -0,0 +1,344 @@ + + + + + + + + LCOV - plumed test coverage - generic + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - genericHitTotalCoverage
Test:plumed test coverageLines:1555163495.2 %
Date:2024-04-19 12:12:35Functions:14720173.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Time.cpp +
28.6%28.6%
+
28.6 %4 / 1416.7 %1 / 6
RandomExchanges.cpp +
30.8%30.8%
+
30.8 %4 / 1325.0 %1 / 4
EndPlumed.cpp +
80.0%80.0%
+
80.0 %8 / 1050.0 %2 / 4
Include.cpp +
83.3%83.3%
+
83.3 %10 / 1240.0 %2 / 5
WholeMolecules.cpp +
88.5%88.5%
+
88.5 %77 / 8783.3 %5 / 6
PrintNDX.cpp +
90.3%90.3%
+
90.3 %56 / 6269.2 %9 / 13
Constant.cpp +
92.1%92.1%
+
92.1 %58 / 6342.9 %3 / 7
Plumed.cpp +
93.3%93.3%
+
93.3 %166 / 17883.3 %10 / 12
Read.cpp +
94.9%94.9%
+
94.9 %94 / 9981.8 %9 / 11
WrapAround.cpp +
96.6%96.6%
+
96.6 %57 / 5966.7 %4 / 6
Print.cpp +
96.7%96.7%
+
96.7 %58 / 6081.8 %9 / 11
DumpMassCharge.cpp +
96.9%96.9%
+
96.9 %62 / 6472.7 %8 / 11
FitToTemplate.cpp +
97.2%97.2%
+
97.2 %104 / 10771.4 %5 / 7
DumpAtoms.cpp +
97.3%97.3%
+
97.3 %142 / 14676.9 %10 / 13
EffectiveEnergyDrift.cpp +
97.4%97.4%
+
97.4 %147 / 15177.8 %7 / 9
PDB2Constant.cpp +
98.2%98.2%
+
98.2 %54 / 5566.7 %2 / 3
Ones.cpp +
100.0%
+
100.0 %11 / 1166.7 %2 / 3
Flush.cpp +
100.0%
+
100.0 %19 / 19100.0 %5 / 5
DumpForces.cpp +
100.0%
+
100.0 %37 / 3777.8 %7 / 9
DumpProjections.cpp +
100.0%
+
100.0 %38 / 3880.0 %8 / 10
UpdateIf.cpp +
100.0%
+
100.0 %42 / 4280.0 %8 / 10
DumpDerivatives.cpp +
100.0%
+
100.0 %48 / 4877.8 %7 / 9
DumpVector.cpp +
100.0%
+
100.0 %54 / 5488.9 %8 / 9
ResetCell.cpp +
100.0%
+
100.0 %55 / 5580.0 %4 / 5
Debug.cpp +
100.0%
+
100.0 %56 / 5680.0 %4 / 5
DumpPDB.cpp +
100.0%
+
100.0 %94 / 9487.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 000000000000..0c8c0370ef26 --- /dev/null +++ b/coverage/generic/index.html @@ -0,0 +1,344 @@ + + + + + + + + LCOV - plumed test coverage - generic + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - genericHitTotalCoverage
Test:plumed test coverageLines:1555163495.2 %
Date:2024-04-19 12:12:35Functions:14720173.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Constant.cpp +
92.1%92.1%
+
92.1 %58 / 6342.9 %3 / 7
Debug.cpp +
100.0%
+
100.0 %56 / 5680.0 %4 / 5
DumpAtoms.cpp +
97.3%97.3%
+
97.3 %142 / 14676.9 %10 / 13
DumpDerivatives.cpp +
100.0%
+
100.0 %48 / 4877.8 %7 / 9
DumpForces.cpp +
100.0%
+
100.0 %37 / 3777.8 %7 / 9
DumpMassCharge.cpp +
96.9%96.9%
+
96.9 %62 / 6472.7 %8 / 11
DumpPDB.cpp +
100.0%
+
100.0 %94 / 9487.5 %7 / 8
DumpProjections.cpp +
100.0%
+
100.0 %38 / 3880.0 %8 / 10
DumpVector.cpp +
100.0%
+
100.0 %54 / 5488.9 %8 / 9
EffectiveEnergyDrift.cpp +
97.4%97.4%
+
97.4 %147 / 15177.8 %7 / 9
EndPlumed.cpp +
80.0%80.0%
+
80.0 %8 / 1050.0 %2 / 4
FitToTemplate.cpp +
97.2%97.2%
+
97.2 %104 / 10771.4 %5 / 7
Flush.cpp +
100.0%
+
100.0 %19 / 19100.0 %5 / 5
Include.cpp +
83.3%83.3%
+
83.3 %10 / 1240.0 %2 / 5
Ones.cpp +
100.0%
+
100.0 %11 / 1166.7 %2 / 3
PDB2Constant.cpp +
98.2%98.2%
+
98.2 %54 / 5566.7 %2 / 3
Plumed.cpp +
93.3%93.3%
+
93.3 %166 / 17883.3 %10 / 12
Print.cpp +
96.7%96.7%
+
96.7 %58 / 6081.8 %9 / 11
PrintNDX.cpp +
90.3%90.3%
+
90.3 %56 / 6269.2 %9 / 13
RandomExchanges.cpp +
30.8%30.8%
+
30.8 %4 / 1325.0 %1 / 4
Read.cpp +
94.9%94.9%
+
94.9 %94 / 9981.8 %9 / 11
ResetCell.cpp +
100.0%
+
100.0 %55 / 5580.0 %4 / 5
Time.cpp +
28.6%28.6%
+
28.6 %4 / 1416.7 %1 / 6
UpdateIf.cpp +
100.0%
+
100.0 %42 / 4280.0 %8 / 10
WholeMolecules.cpp +
88.5%88.5%
+
88.5 %77 / 8783.3 %5 / 6
WrapAround.cpp +
96.6%96.6%
+
96.6 %57 / 5966.7 %4 / 6
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/glass.png b/coverage/glass.png new file mode 100644 index 0000000000000000000000000000000000000000..e1abc00680a3093c49fdb775ae6bdb6764c95af2 GIT binary patch literal 167 zcmeAS@N?(olHy`uVBq!ia0vp^j3CU&3?x-=hn)gaEa{HEjtmSN`?>!lvI6;R0X`wF z|Ns97GD8ntt^-nxB|(0{3=Yq3q=7g|-tI089jvk*Kn`btM`SSr1Gf+eGhVt|_XjA* zUgGKN%6^Gmn4d%Ph(nkFP>9RZ#WAE}PI3Z}&BVayv3^M*kj3EX>gTe~DWM4f=_Dpv literal 0 HcmV?d00001 diff --git a/coverage/gridtools/ActionWithGrid.cpp.func-sort-c.html b/coverage/gridtools/ActionWithGrid.cpp.func-sort-c.html new file mode 100644 index 000000000000..908c065908d2 --- /dev/null +++ b/coverage/gridtools/ActionWithGrid.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + 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:1717100.0 %
Date:2024-04-19 12:12:35Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools14ActionWithGridC1ERKNS_13ActionOptionsE0
_ZN4PLMD9gridtools14ActionWithGridC2ERKNS_13ActionOptionsE767
_ZN4PLMD9gridtools14ActionWithGrid16registerKeywordsERNS_8KeywordsE795
_ZN4PLMD9gridtools14ActionWithGrid9calculateEv10835
_ZN4PLMD9gridtools14ActionWithGrid22getInputActionWithGridEPNS_6ActionE16513
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/ActionWithGrid.cpp.func.html b/coverage/gridtools/ActionWithGrid.cpp.func.html new file mode 100644 index 000000000000..413615ee78e8 --- /dev/null +++ b/coverage/gridtools/ActionWithGrid.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + 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:1717100.0 %
Date:2024-04-19 12:12:35Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools14ActionWithGrid16registerKeywordsERNS_8KeywordsE795
_ZN4PLMD9gridtools14ActionWithGrid22getInputActionWithGridEPNS_6ActionE16513
_ZN4PLMD9gridtools14ActionWithGrid9calculateEv10835
_ZN4PLMD9gridtools14ActionWithGridC1ERKNS_13ActionOptionsE0
_ZN4PLMD9gridtools14ActionWithGridC2ERKNS_13ActionOptionsE767
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/ActionWithGrid.cpp.gcov.html b/coverage/gridtools/ActionWithGrid.cpp.gcov.html new file mode 100644 index 000000000000..dc19eece0ae0 --- /dev/null +++ b/coverage/gridtools/ActionWithGrid.cpp.gcov.html @@ -0,0 +1,132 @@ + + + + + + + + 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:1717100.0 %
Date:2024-04-19 12:12:35Functions:4580.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2017 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received 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             : 
+      24             : namespace PLMD {
+      25             : namespace gridtools {
+      26             : 
+      27       16513 : ActionWithGrid* ActionWithGrid::getInputActionWithGrid( Action* action ) {
+      28       16513 :   ActionWithGrid* ag = dynamic_cast<ActionWithGrid*>( action );
+      29       17371 :   if( !ag && action->getName()=="ACCUMULATE" ) {
+      30         858 :     ActionWithArguments* aa=dynamic_cast<ActionWithArguments*>( action );
+      31         858 :     plumed_assert( aa ); ag = dynamic_cast<ActionWithGrid*>( (aa->getPntrToArgument(0))->getPntrToAction() );
+      32             :   }
+      33       16513 :   plumed_assert( ag ); return ag;
+      34             : }
+      35             : 
+      36         795 : void ActionWithGrid::registerKeywords( Keywords& keys ) {
+      37         795 :   ActionWithVector::registerKeywords( keys );
+      38         795 : }
+      39             : 
+      40         767 : ActionWithGrid::ActionWithGrid(const ActionOptions&ao):
+      41             :   Action(ao),
+      42             :   ActionWithVector(ao),
+      43         767 :   firststep(true)
+      44             : {
+      45         767 : }
+      46             : 
+      47       10835 : void ActionWithGrid::calculate() {
+      48       10835 :   plumed_assert( !actionInChain() );
+      49       10835 :   if( firststep ) { setupOnFirstStep( true ); firststep=false; }
+      50             : 
+      51       10835 :   runAllTasks();
+      52       10835 : }
+      53             : 
+      54             : }
+      55             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/ConvertToFES.cpp.func-sort-c.html b/coverage/gridtools/ConvertToFES.cpp.func-sort-c.html new file mode 100644 index 000000000000..e8297a9c1ca8 --- /dev/null +++ b/coverage/gridtools/ConvertToFES.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + 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:2121100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools12ConvertToFESC2ERKNS_13ActionOptionsE0
_ZN4PLMD9gridtools12ConvertToFESC1ERKNS_13ActionOptionsE15
_ZN4PLMD9gridtools12ConvertToFES16registerKeywordsERNS_8KeywordsE17
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/ConvertToFES.cpp.func.html b/coverage/gridtools/ConvertToFES.cpp.func.html new file mode 100644 index 000000000000..832de390d058 --- /dev/null +++ b/coverage/gridtools/ConvertToFES.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + 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:2121100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools12ConvertToFES16registerKeywordsERNS_8KeywordsE17
_ZN4PLMD9gridtools12ConvertToFESC1ERKNS_13ActionOptionsE15
_ZN4PLMD9gridtools12ConvertToFESC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/ConvertToFES.cpp.gcov.html b/coverage/gridtools/ConvertToFES.cpp.gcov.html new file mode 100644 index 000000000000..33c6579f6f62 --- /dev/null +++ b/coverage/gridtools/ConvertToFES.cpp.gcov.html @@ -0,0 +1,175 @@ + + + + + + + + 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:2121100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2020 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received 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/ActionShortcut.h"
+      24             : #include "core/PlumedMain.h"
+      25             : 
+      26             : //+PLUMEDOC GRIDANALYSIS CONVERT_TO_FES
+      27             : /*
+      28             : Convert a histogram to a free energy surface.
+      29             : 
+      30             : This action allows you to take a free energy surface that was calculated using the \ref HISTOGRAM
+      31             : action and to convert it to a free energy surface.  This transformation performed by doing:
+      32             : 
+      33             : \f[
+      34             : F(x) = -k_B T \ln H(x)
+      35             : \f]
+      36             : 
+      37             : The free energy calculated on a grid is output by this action and can be printed using \ref DUMPGRID
+      38             : 
+      39             : \par Examples
+      40             : 
+      41             : This is a typical example showing how CONVERT_TO_FES might be used when post processing a trajectory.
+      42             : The input below calculates the free energy as a function of the distance between atom 1 and atom 2.
+      43             : This is done by accumulating a histogram as a function of this distance using kernel density estimation
+      44             : and the HISTOGRAM action.  All the data within this trajectory is used in the construction of this
+      45             : HISTOGRAM.  Finally, once all the data has been read in, the histogram is converted to a free energy
+      46             : using the formula above and the free energy is output to a file called fes.dat
+      47             : 
+      48             : \plumedfile
+      49             : x: DISTANCE ATOMS=1,2
+      50             : hA1: HISTOGRAM ARG=x GRID_MIN=0.0 GRID_MAX=3.0 GRID_BIN=100 BANDWIDTH=0.1
+      51             : ff: CONVERT_TO_FES GRID=hA1 TEMP=300
+      52             : DUMPGRID GRID=ff FILE=fes.dat
+      53             : \endplumedfile
+      54             : 
+      55             : */
+      56             : //+ENDPLUMEDOC
+      57             : 
+      58             : namespace PLMD {
+      59             : namespace gridtools {
+      60             : 
+      61             : class ConvertToFES : public ActionShortcut {
+      62             : public:
+      63             :   static void registerKeywords( Keywords& keys );
+      64             :   explicit ConvertToFES(const ActionOptions&ao);
+      65             : };
+      66             : 
+      67             : PLUMED_REGISTER_ACTION(ConvertToFES,"CONVERT_TO_FES")
+      68             : 
+      69          17 : void ConvertToFES::registerKeywords( Keywords& keys ) {
+      70          17 :   ActionShortcut::registerKeywords( keys );
+      71          34 :   keys.add("optional","GRID","the histogram that you would like to convert into a free energy surface (old syntax)");
+      72          34 :   keys.add("compulsory","ARG","the histogram that you would like to convert into a free energy surface");
+      73          34 :   keys.add("optional","TEMP","the temperature at which you are operating");
+      74          34 :   keys.addFlag("MINTOZERO",false,"set the minimum in the free energy to be equal to zero");
+      75          34 :   keys.needsAction("FIND_GRID_MINIMUM"); keys.needsAction("CUSTOM");
+      76          17 : }
+      77             : 
+      78          15 : ConvertToFES::ConvertToFES(const ActionOptions&ao):
+      79             :   Action(ao),
+      80          15 :   ActionShortcut(ao)
+      81             : {
+      82          15 :   bool minzero=false; parseFlag("MINTOZERO",minzero);
+      83          15 :   double simtemp=getkBT(); if( simtemp==0 ) error("TEMP not set - use keyword TEMP");
+      84             : 
+      85          30 :   std::vector<std::string> argv; parseVector("GRID",argv);
+      86          30 :   if( argv.size()==0 ) parseVector("ARG",argv);
+      87          15 :   if( argv.size()!=1 ) error("should only have one argument");
+      88             : 
+      89          15 :   std::string str_temp; Tools::convert( simtemp, str_temp ); std::string flab=""; if( minzero ) flab="_unz";
+      90          30 :   readInputLine( getShortcutLabel() + flab + ": CUSTOM ARG=" + argv[0] + " FUNC=-" + str_temp + "*log(x) PERIODIC=NO");
+      91          15 :   if( minzero ) {
+      92           4 :     readInputLine( getShortcutLabel() + "_min: FIND_GRID_MINIMUM ARG=" + getShortcutLabel() + "_unz" );
+      93           4 :     readInputLine( getShortcutLabel() + ": CUSTOM ARG=" + getShortcutLabel() + "_unz," + getShortcutLabel() + "_min.optval FUNC=x-y PERIODIC=NO");
+      94             :   }
+      95          15 : }
+      96             : 
+      97             : }
+      98             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/DumpGrid.cpp.func-sort-c.html b/coverage/gridtools/DumpGrid.cpp.func-sort-c.html new file mode 100644 index 000000000000..853883bc6ba4 --- /dev/null +++ b/coverage/gridtools/DumpGrid.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + 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:11111398.2 %
Date:2024-04-19 12:12:35Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools8DumpGridC2ERKNS_13ActionOptionsE0
_ZN4PLMD9gridtools8DumpGridC1ERKNS_13ActionOptionsE66
_ZN4PLMD9gridtools8DumpGridD0Ev66
_ZN4PLMD9gridtools8DumpGridD1Ev66
_ZN4PLMD9gridtools8DumpGrid16registerKeywordsERNS_8KeywordsE70
_ZN4PLMD9gridtools8DumpGrid5applyEv105
_ZN4PLMD9gridtools8DumpGrid9calculateEv105
_ZN4PLMD9gridtools8DumpGrid6updateEv137
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/DumpGrid.cpp.func.html b/coverage/gridtools/DumpGrid.cpp.func.html new file mode 100644 index 000000000000..ff04f21a0dea --- /dev/null +++ b/coverage/gridtools/DumpGrid.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + 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:11111398.2 %
Date:2024-04-19 12:12:35Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools8DumpGrid16registerKeywordsERNS_8KeywordsE70
_ZN4PLMD9gridtools8DumpGrid5applyEv105
_ZN4PLMD9gridtools8DumpGrid6updateEv137
_ZN4PLMD9gridtools8DumpGrid9calculateEv105
_ZN4PLMD9gridtools8DumpGridC1ERKNS_13ActionOptionsE66
_ZN4PLMD9gridtools8DumpGridC2ERKNS_13ActionOptionsE0
_ZN4PLMD9gridtools8DumpGridD0Ev66
_ZN4PLMD9gridtools8DumpGridD1Ev66
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/DumpGrid.cpp.gcov.html b/coverage/gridtools/DumpGrid.cpp.gcov.html new file mode 100644 index 000000000000..93edc8a26d2f --- /dev/null +++ b/coverage/gridtools/DumpGrid.cpp.gcov.html @@ -0,0 +1,426 @@ + + + + + + + + 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:11111398.2 %
Date:2024-04-19 12:12:35Functions: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/ActionWithArguments.h"
+      23             : #include "core/ActionPilot.h"
+      24             : #include "core/ActionRegister.h"
+      25             : #include "core/PlumedMain.h"
+      26             : #include "ActionWithGrid.h"
+      27             : #include "tools/OFile.h"
+      28             : 
+      29             : namespace PLMD {
+      30             : namespace gridtools {
+      31             : 
+      32             : //+PLUMEDOC GRIDANALYSIS DUMPCUBE
+      33             : /*
+      34             : Output a three dimensional grid using the Gaussian cube file format.
+      35             : 
+      36             : Suppose you have calculated the value of a function on a three dimensional grid.
+      37             : This function might be a \ref HISTOGRAM or it might be a free energy energy surface
+      38             : that was calculated from this histogram by using \ref CONVERT_TO_FES.  Alternatively,
+      39             : your function might be a phase-field that was calculated using \ref MULTICOLVARDENS.
+      40             : Whatever the function is, however, you obviously cannot show it using a typical contour
+      41             : plotting program such as gnuplot as you have three input variables.
+      42             : 
+      43             : Tools like VMD have nice features for plotting these types of three dimensional functions
+      44             : but typically you are required to use a Gaussian cube file format to input the data.  This
+      45             : action thus allows you to output a function evaluated on a grid to a Gaussian cube file format.
+      46             : 
+      47             : \par Examples
+      48             : 
+      49             : The input below can be used to post process a trajectory.  A histogram as a function of the distance
+      50             : between atoms 1 and 2, the distance between atom 1 and 3 and the angle between the vector connecting atoms 1 and
+      51             : 2 and 1 and 3 is computed using kernel density estimation.  Once all the data contained in the trajectory has been read in and
+      52             : all the kernels have been added the resulting histogram is output to a file called histoA1.cube.  This file has the
+      53             : Gaussian cube file format.  The histogram can thus be visualized using tools such as VMD.
+      54             : 
+      55             : \plumedfile
+      56             : x1: DISTANCE ATOMS=1,2
+      57             : x2: DISTANCE ATOMS=1,3
+      58             : x3: ANGLE ATOMS=1,2,3
+      59             : 
+      60             : 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
+      61             : DUMPCUBE GRID=hA1 FILE=histoA1.cube
+      62             : \endplumedfile
+      63             : 
+      64             : */
+      65             : //+ENDPLUMEDOC
+      66             : 
+      67             : //+PLUMEDOC GRIDANALYSIS DUMPGRID
+      68             : /*
+      69             : Output the function on the grid to a file with the PLUMED grid format.
+      70             : 
+      71             : PLUMED provides a number of actions that calculate the values of functions on grids.
+      72             : For instance, whenever you calculate a free energy as a function of a collective variable using
+      73             : \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
+      74             : discrete grid that covers the CV space uniformly.  Alternatively you may want to calculate
+      75             : what value some symmetry function takes at different points inside your simulation cell using \ref MULTICOLVARDENS.
+      76             : 
+      77             : This action allows you to output these functions calculated on a grid using a format that can be read in using gnuplot
+      78             : and other such plotting programs.  The file output using this action will have a header that contains some essential
+      79             : information about the function plotted and that looks something like this:
+      80             : 
+      81             : \verbatim
+      82             : #! FIELDS x y hA1 dhA1_x dhA1_x
+      83             : #! SET normalisation    2.0000
+      84             : #! SET min_x 0.0
+      85             : #! SET max_x 3.0
+      86             : #! SET nbins_x  100
+      87             : #! SET periodic_x false
+      88             : #! SET min_y 0.0
+      89             : #! SET max_y 3.0
+      90             : #! SET nbins_y  100
+      91             : #! SET periodic_y false
+      92             : \endverbatim
+      93             : 
+      94             : The header shown here tells us that we have grid showing the values that a function with two arguments x and y
+      95             : takes at various points in our cell.  The lines beneath the first line then tell us a little bit about these two
+      96             : input arguments.
+      97             : 
+      98             : The remaining lines of the file give us information on the positions of our grid points and the value the function and
+      99             : its partial derivatives with respect to x and y.  If the header is as above a list of values of the function that have
+     100             : 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.
+     101             : There will then be a second block of values which will all have been evaluated the same value of x and all possible values
+     102             : 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.
+     103             : 
+     104             : \par Examples
+     105             : 
+     106             : The following input monitors two torsional angles during a simulation
+     107             : and outputs a continuous histogram as a function of them at the end of the simulation.
+     108             : \plumedfile
+     109             : TORSION ATOMS=1,2,3,4 LABEL=r1
+     110             : TORSION ATOMS=2,3,4,5 LABEL=r2
+     111             : HISTOGRAM ...
+     112             :   ARG=r1,r2
+     113             :   GRID_MIN=-3.14,-3.14
+     114             :   GRID_MAX=3.14,3.14
+     115             :   GRID_BIN=200,200
+     116             :   BANDWIDTH=0.05,0.05
+     117             :   LABEL=hh
+     118             : ... HISTOGRAM
+     119             : 
+     120             : DUMPGRID GRID=hh FILE=histo
+     121             : \endplumedfile
+     122             : 
+     123             : The following input monitors two torsional angles during a simulation
+     124             : and outputs a discrete histogram as a function of them at the end of the simulation.
+     125             : \plumedfile
+     126             : TORSION ATOMS=1,2,3,4 LABEL=r1
+     127             : TORSION ATOMS=2,3,4,5 LABEL=r2
+     128             : HISTOGRAM ...
+     129             :   ARG=r1,r2
+     130             :   KERNEL=DISCRETE
+     131             :   GRID_MIN=-3.14,-3.14
+     132             :   GRID_MAX=3.14,3.14
+     133             :   GRID_BIN=200,200
+     134             :   LABEL=hh
+     135             : ... HISTOGRAM
+     136             : 
+     137             : DUMPGRID GRID=hh FILE=histo
+     138             : \endplumedfile
+     139             : 
+     140             : The following input monitors two torsional angles during a simulation
+     141             : and outputs the histogram accumulated thus far every 100000 steps.
+     142             : \plumedfile
+     143             : TORSION ATOMS=1,2,3,4 LABEL=r1
+     144             : TORSION ATOMS=2,3,4,5 LABEL=r2
+     145             : HISTOGRAM ...
+     146             :   ARG=r1,r2
+     147             :   GRID_MIN=-3.14,-3.14
+     148             :   GRID_MAX=3.14,3.14
+     149             :   GRID_BIN=200,200
+     150             :   BANDWIDTH=0.05,0.05
+     151             :   LABEL=hh
+     152             : ... HISTOGRAM
+     153             : 
+     154             : DUMPGRID GRID=hh FILE=histo STRIDE=100000
+     155             : \endplumedfile
+     156             : 
+     157             : The following input monitors two torsional angles during a simulation
+     158             : and outputs a separate histogram for each 100000 steps worth of trajectory.
+     159             : Notice how the CLEAR keyword is used here and how it is not used in the
+     160             : previous example.
+     161             : 
+     162             : \plumedfile
+     163             : TORSION ATOMS=1,2,3,4 LABEL=r1
+     164             : TORSION ATOMS=2,3,4,5 LABEL=r2
+     165             : HISTOGRAM ...
+     166             :   ARG=r1,r2 CLEAR=100000
+     167             :   GRID_MIN=-3.14,-3.14
+     168             :   GRID_MAX=3.14,3.14
+     169             :   GRID_BIN=200,200
+     170             :   BANDWIDTH=0.05,0.05
+     171             :   LABEL=hh
+     172             : ... HISTOGRAM
+     173             : 
+     174             : DUMPGRID GRID=hh FILE=histo STRIDE=100000
+     175             : \endplumedfile
+     176             : 
+     177             : */
+     178             : //+ENDPLUMEDOC
+     179             : 
+     180             : class DumpGrid :
+     181             :   public ActionWithArguments,
+     182             :   public ActionPilot {
+     183             : private:
+     184             :   std::string fmt, filename;
+     185             :   bool onefile, xyzfile;
+     186             : public:
+     187             :   static void registerKeywords( Keywords& keys );
+     188             :   explicit DumpGrid(const ActionOptions&ao);
+     189         132 :   ~DumpGrid() {}
+     190         105 :   void calculate() override {}
+     191         105 :   void apply() override {}
+     192             :   void update() override ;
+     193             : };
+     194             : 
+     195             : PLUMED_REGISTER_ACTION(DumpGrid,"DUMPCUBE")
+     196             : PLUMED_REGISTER_ACTION(DumpGrid,"DUMPGRID")
+     197             : 
+     198          70 : void DumpGrid::registerKeywords( Keywords& keys ) {
+     199          70 :   Action::registerKeywords( keys );
+     200          70 :   ActionPilot::registerKeywords( keys );
+     201          70 :   ActionWithArguments::registerKeywords( keys ); keys.use("ARG");
+     202         140 :   keys.add("optional","GRID","the grid you would like to print (can also use ARG for specifying what is being printed)");
+     203         140 :   keys.add("compulsory","STRIDE","0","the frequency with which the grid should be output to the file.  Default of zero means dump at end of calculation");
+     204         140 :   keys.add("compulsory","FILE","density","the file on which to write the grid.");
+     205         140 :   keys.add("optional","FMT","the format that should be used to output real numbers");
+     206         140 :   keys.addFlag("PRINT_XYZ",false,"output coordinates on fibonacci grid to xyz file");
+     207         140 :   keys.addFlag("PRINT_ONE_FILE",false,"output grids one after the other in a single file");
+     208          70 : }
+     209             : 
+     210          66 : DumpGrid::DumpGrid(const ActionOptions&ao):
+     211             :   Action(ao),
+     212             :   ActionWithArguments(ao),
+     213             :   ActionPilot(ao),
+     214          66 :   fmt("%f")
+     215             : {
+     216          66 :   if( getNumberOfArguments()==0 ) {
+     217           0 :     std::vector<Value*> grids; parseArgumentList("GRID",grids); requestArguments(grids);
+     218             :   }
+     219          66 :   if( getNumberOfArguments()!=1 ) error("should only be one argument");
+     220          66 :   if( getPntrToArgument(0)->getRank()==0 || !getPntrToArgument(0)->hasDerivatives() ) error("input should be a grid");
+     221          66 :   if( getName()=="DUMPCUBE" && getPntrToArgument(0)->getRank()!=3 ) error("input should be a three dimensional grid");
+     222         132 :   parse("FILE",filename);
+     223          66 :   if(filename.length()==0) error("name out output file was not specified");
+     224          66 :   ActionWithGrid* ag = ActionWithGrid::getInputActionWithGrid( getPntrToArgument(0)->getPntrToAction() );
+     225          66 :   if( !ag ) error( getPntrToArgument(0)->getName() + " is not grid");
+     226             : 
+     227          66 :   log.printf("  outputting grid with label %s to file named %s",getPntrToArgument(0)->getName().c_str(), filename.c_str() );
+     228         132 :   parse("FMT",fmt); log.printf(" with format %s \n", fmt.c_str() );
+     229         137 :   if( getName()=="DUMPGRID" ) fmt = " " + fmt; else if( getName()=="DUMPCUBE" ) fmt = fmt + " ";
+     230         132 :   parseFlag("PRINT_ONE_FILE", onefile); parseFlag("PRINT_XYZ",xyzfile);
+     231          66 :   if( xyzfile ) {
+     232           4 :     if( getName()=="DUMPCUBE" ) error("PRINT_XYZ flag not compatible with DUMPCUBE");
+     233           8 :     if( ag->getGridCoordinatesObject().getGridType()=="flat" ) error("can only use PRINT_XYZ option for fibonacci grids");
+     234           4 :     log.printf("  outputting grid to xyzfile\n");
+     235             :   }
+     236          66 :   if( onefile ) log.printf("  printing all grids on a single file \n");
+     237          64 :   else log.printf("  printing all grids on separate files \n");
+     238          66 : }
+     239             : 
+     240         137 : void DumpGrid::update() {
+     241         137 :   OFile ofile; ofile.link(*this);
+     242         137 :   if( onefile ) {
+     243          10 :     ofile.enforceRestart();
+     244          10 :     ofile.open( filename );
+     245             :   } else {
+     246         127 :     ofile.setBackupString("analysis");
+     247         127 :     ofile.open( filename );
+     248             :   }
+     249             : 
+     250         137 :   ActionWithGrid* ag = ActionWithGrid::getInputActionWithGrid( getPntrToArgument(0)->getPntrToAction() );
+     251         137 :   plumed_assert( ag ); const GridCoordinatesObject & mygrid = ag->getGridCoordinatesObject();
+     252             : 
+     253         137 :   if( getName()=="DUMPCUBE" ) {
+     254          11 :     double lunit=1.0; std::vector<std::string> argnames( ag->getGridCoordinateNames() );
+     255             : 
+     256          11 :     ofile.printf("PLUMED CUBE FILE\n");
+     257          11 :     ofile.printf("OUTER LOOP: X, MIDDLE LOOP: Y, INNER LOOP: Z\n");
+     258             :     // Number of atoms followed by position of origin (origin set so that center of grid is in center of cell)
+     259          11 :     bool isdists=true; std::vector<double> extent(3); std::vector<std::string> min( mygrid.getMin() ), max( mygrid.getMax() );
+     260          44 :     for(unsigned j=0; j<3; ++j) {
+     261          33 :       if( argnames[j].find(".")!=std::string::npos ) {
+     262           3 :         std::size_t dot = argnames[j].find(".");
+     263           3 :         std::string name = argnames[j].substr(dot+1);
+     264           6 :         if( name!="x" && name!="y" && name!="z" ) isdists=false;
+     265             :       } else isdists=false;
+     266             : 
+     267          33 :       double mind, maxd; Tools::convert( min[j], mind ); Tools::convert( max[j], maxd );
+     268          33 :       if( mygrid.isPeriodic(j) ) extent[j]=maxd-mind;
+     269          30 :       else { extent[j]=maxd-mind+mygrid.getGridSpacing()[j]; }
+     270             :     }
+     271          11 :     if( isdists ) {
+     272           1 :       if( plumed.usingNaturalUnits() ) lunit = 1.0/0.5292;
+     273           0 :       else lunit = plumed.getUnits().getLength()/.05929;
+     274             :     }
+     275          22 :     std::string ostr = "%d " + fmt + fmt + fmt + "\n"; Value* gval=getPntrToArgument(0);
+     276          11 :     ofile.printf(ostr.c_str(),1,-0.5*lunit*extent[0],-0.5*lunit*extent[1],-0.5*lunit*extent[2]);
+     277          11 :     ofile.printf(ostr.c_str(),mygrid.getNbin(true)[0],lunit*mygrid.getGridSpacing()[0],0.0,0.0);  // Number of bins in each direction followed by
+     278          11 :     ofile.printf(ostr.c_str(),mygrid.getNbin(true)[1],0.0,lunit*mygrid.getGridSpacing()[1],0.0);  // shape of voxel
+     279          22 :     ofile.printf(ostr.c_str(),mygrid.getNbin(true)[2],0.0,0.0,lunit*mygrid.getGridSpacing()[2]);
+     280          11 :     ofile.printf(ostr.c_str(),1,0.0,0.0,0.0); // Fake atom otherwise VMD doesn't work
+     281          11 :     std::vector<unsigned> pp(3); std::vector<unsigned> nbin( mygrid.getNbin(true) );
+     282         135 :     for(pp[0]=0; pp[0]<nbin[0]; ++pp[0]) {
+     283        1530 :       for(pp[1]=0; pp[1]<nbin[1]; ++pp[1]) {
+     284       20204 :         for(pp[2]=0; pp[2]<nbin[2]; ++pp[2]) {
+     285       18798 :           unsigned ival=pp[pp.size()-1];
+     286       56394 :           for(unsigned i=pp.size()-1; i>0; --i) ival=ival*nbin[i-1]+pp[i-1];
+     287       18798 :           ofile.printf(fmt.c_str(), gval->get(ival) );
+     288       18798 :           if(pp[2]%6==5) ofile.printf("\n");
+     289             :         }
+     290        1406 :         ofile.printf("\n");
+     291             :       }
+     292             :     }
+     293         148 :   } else if( xyzfile ) {
+     294          13 :     std::vector<double> coords(3);
+     295             :     Value* myarg = getPntrToArgument(0);
+     296          13 :     unsigned nvals = myarg->getNumberOfValues(); ofile.printf("%d\n\n", nvals);
+     297        1797 :     for(unsigned i=0; i<nvals; ++i) {
+     298        1784 :       double val = myarg->get(i); mygrid.getGridPointCoordinates( i, coords );
+     299        1784 :       ofile.printf("X");
+     300        7136 :       for(unsigned j=0; j<3; ++j) ofile.printf((" " + fmt).c_str(), val*coords[j] );
+     301        1784 :       ofile.printf("\n");
+     302             :     }
+     303             :   } else {
+     304             :     Value* gval=getPntrToArgument(0);
+     305         113 :     std::vector<double> xx( gval->getRank() );
+     306         113 :     std::vector<unsigned> ind( gval->getRank() );
+     307         113 :     std::vector<std::string> argn( ag->getGridCoordinateNames() );
+     308         226 :     if( mygrid.getGridType()=="fibonacci" ) {
+     309          12 :       ofile.addConstantField("nbins");
+     310             :     } else {
+     311         214 :       plumed_assert( mygrid.getGridType()=="flat" );
+     312         229 :       for(unsigned i=0; i<gval->getRank(); ++i) {
+     313         244 :         ofile.addConstantField("min_" + argn[i] );
+     314         244 :         ofile.addConstantField("max_" + argn[i] );
+     315         244 :         ofile.addConstantField("nbins_" + argn[i] );
+     316         244 :         ofile.addConstantField("periodic_" + argn[i] );
+     317             :       }
+     318             :     }
+     319             : 
+     320      213260 :     for(unsigned i=0; i<gval->getNumberOfValues(); ++i) {
+     321             :       // Retrieve and print the grid coordinates
+     322      213147 :       mygrid.getGridPointCoordinates( i, ind, xx );
+     323      213147 :       if(i>0 && gval->getRank()==2 && ind[gval->getRank()-2]==0) ofile.printf("\n");
+     324      213147 :       ofile.fmtField(fmt);
+     325      426294 :       if( mygrid.getGridType()=="fibonacci" ) {
+     326        1200 :         ofile.printField("nbins", static_cast<int>(gval->getNumberOfValues()) );
+     327             :       } else {
+     328      682787 :         for(unsigned j=0; j<gval->getRank(); ++j) {
+     329      940480 :           ofile.printField("min_" + argn[j], mygrid.getMin()[j] );
+     330      940480 :           ofile.printField("max_" + argn[j], mygrid.getMax()[j] );
+     331      940480 :           ofile.printField("nbins_" + argn[j], static_cast<int>(mygrid.getNbin(false)[j]) );
+     332      650466 :           if( mygrid.isPeriodic(j) ) ofile.printField("periodic_" + argn[j], "true" );
+     333      580028 :           else         ofile.printField("periodic_" + argn[j], "false" );
+     334             :         }
+     335             :       }
+     336             :       // Print the grid coordinates
+     337      685187 :       for(unsigned j=0; j<gval->getRank(); ++j) { ofile.fmtField(fmt); ofile.printField(argn[j],xx[j]); }
+     338             :       // Print value
+     339      213147 :       ofile.fmtField(fmt); ofile.printField( gval->getName(), gval->get(i) );
+     340             :       // Print the derivatives
+     341      685187 :       for(unsigned j=0; j<gval->getRank(); ++j) { ofile.fmtField(fmt); ofile.printField( "d" + gval->getName() + "_" + argn[j], gval->getGridDerivative(i,j) ); }
+     342      213147 :       ofile.printField();
+     343             :     }
+     344         113 :   }
+     345         137 : }
+     346             : 
+     347             : 
+     348             : }
+     349             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/EvaluateFunctionOnGrid.cpp.func-sort-c.html b/coverage/gridtools/EvaluateFunctionOnGrid.cpp.func-sort-c.html new file mode 100644 index 000000000000..7d7e435f8492 --- /dev/null +++ b/coverage/gridtools/EvaluateFunctionOnGrid.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/EvaluateFunctionOnGrid.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - EvaluateFunctionOnGrid.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2626100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools22EvaluateFunctionOnGridC2ERKNS_13ActionOptionsE0
_ZN4PLMD9gridtools22EvaluateFunctionOnGridC1ERKNS_13ActionOptionsE2
_ZN4PLMD9gridtools22EvaluateFunctionOnGrid16registerKeywordsERNS_8KeywordsE4
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/EvaluateFunctionOnGrid.cpp.func.html b/coverage/gridtools/EvaluateFunctionOnGrid.cpp.func.html new file mode 100644 index 000000000000..bed4d43acd20 --- /dev/null +++ b/coverage/gridtools/EvaluateFunctionOnGrid.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/EvaluateFunctionOnGrid.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - EvaluateFunctionOnGrid.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2626100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools22EvaluateFunctionOnGrid16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD9gridtools22EvaluateFunctionOnGridC1ERKNS_13ActionOptionsE2
_ZN4PLMD9gridtools22EvaluateFunctionOnGridC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/EvaluateFunctionOnGrid.cpp.gcov.html b/coverage/gridtools/EvaluateFunctionOnGrid.cpp.gcov.html new file mode 100644 index 000000000000..3271ebffbb23 --- /dev/null +++ b/coverage/gridtools/EvaluateFunctionOnGrid.cpp.gcov.html @@ -0,0 +1,186 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/EvaluateFunctionOnGrid.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - EvaluateFunctionOnGrid.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2626100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2018 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received 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/FunctionShortcut.h"
+      24             : #include "function/FunctionOfScalar.h"
+      25             : #include "function/FunctionOfVector.h"
+      26             : #include "EvaluateGridFunction.h"
+      27             : #include "ActionWithGrid.h"
+      28             : 
+      29             : //+PLUMEDOC GRIDCALC EVALUATE_FUNCTION_FROM_GRID
+      30             : /*
+      31             : Calculate the function stored on the input grid at an arbitrary point
+      32             : 
+      33             : \par Examples
+      34             : 
+      35             : */
+      36             : //+ENDPLUMEDOC
+      37             : 
+      38             : //+PLUMEDOC GRIDCALC EVALUATE_FUNCTION_FROM_GRID_SCALAR
+      39             : /*
+      40             : Calculate the function stored on the input grid at an arbitrary point
+      41             : 
+      42             : \par Examples
+      43             : 
+      44             : */
+      45             : //+ENDPLUMEDOC
+      46             : 
+      47             : //+PLUMEDOC GRIDCALC EVALUATE_FUNCTION_FROM_GRID_VECTOR
+      48             : /*
+      49             : Calculate the function stored on the input grid for each of the points in the input vector/s
+      50             : 
+      51             : \par Examples
+      52             : 
+      53             : */
+      54             : //+ENDPLUMEDOC
+      55             : 
+      56             : 
+      57             : namespace PLMD {
+      58             : namespace gridtools {
+      59             : 
+      60             : class EvaluateFunctionOnGrid : public ActionShortcut {
+      61             : public:
+      62             :   static void registerKeywords(Keywords&);
+      63             :   explicit EvaluateFunctionOnGrid(const ActionOptions&);
+      64             : };
+      65             : 
+      66             : PLUMED_REGISTER_ACTION(EvaluateFunctionOnGrid,"EVALUATE_FUNCTION_FROM_GRID")
+      67             : typedef function::FunctionOfScalar<EvaluateGridFunction> ScalarEvalGrid;
+      68             : PLUMED_REGISTER_ACTION(ScalarEvalGrid,"EVALUATE_FUNCTION_FROM_GRID_SCALAR")
+      69             : typedef function::FunctionOfVector<EvaluateGridFunction> VectorEvalGrid;
+      70             : PLUMED_REGISTER_ACTION(VectorEvalGrid,"EVALUATE_FUNCTION_FROM_GRID_VECTOR")
+      71             : 
+      72           4 : void EvaluateFunctionOnGrid::registerKeywords(Keywords& keys ) {
+      73           4 :   ActionShortcut::registerKeywords( keys );
+      74           8 :   keys.add("compulsory","GRID","the name of the grid that we are using to evaluate the function");
+      75           8 :   keys.add("optional","ARG","the arguments that you would like to use when evaluating the function.  If not specified these are determined from the names of the grid dimensions");
+      76           8 :   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");
+      77           4 :   EvaluateGridFunction ii; ii.registerKeywords( keys );
+      78           8 :   keys.addActionNameSuffix("_SCALAR"); keys.addActionNameSuffix("_VECTOR");
+      79           4 : }
+      80             : 
+      81           2 : EvaluateFunctionOnGrid::EvaluateFunctionOnGrid(const ActionOptions&ao):
+      82             :   Action(ao),
+      83           2 :   ActionShortcut(ao)
+      84             : {
+      85             :   // Get the grid that we are evaluating here
+      86           4 :   std::vector<std::string> gridn(1); parse("GRID",gridn[0]);
+      87           2 :   std::vector<Value*> gridv; ActionWithArguments::interpretArgumentList( gridn, plumed.getActionSet(), this, gridv );
+      88             :   // Read the input arguments from the input file
+      89           4 :   std::vector<std::string> argn; parseVector("ARG",argn);
+      90             :   // Now get the arguments
+      91           2 :   ActionWithGrid* ag = dynamic_cast<ActionWithGrid*>( gridv[0]->getPntrToAction() );
+      92           2 :   if( !ag ) error("argument to GRID argument is not a grid");
+      93           2 :   if( argn.size()==0 ) {
+      94           2 :     std::vector<std::string> argn2( ag->getGridCoordinateNames() );
+      95           4 :     argn.resize( argn2.size() ); for(unsigned i=0; i<argn2.size(); ++i) argn[i]=argn2[i];
+      96           2 :   }
+      97           2 :   if( argn.size()!=gridv[0]->getRank() ) error("found wrong number of arguments in Evaluate function on grid");
+      98             :   // Now use this information to create a gridobject
+      99           4 :   if( ag->getGridCoordinatesObject().getGridType()=="fibonacci" ) error("cannot interpolate on fibonacci sphere");
+     100             :   // Now get the actual values we are using
+     101           2 :   std::vector<Value*> vals; ActionWithArguments::interpretArgumentList( argn, plumed.getActionSet(), this, vals );
+     102           2 :   if( vals.size()==0 ) error("found no input arguments to function");
+     103           4 :   std::string allargs = gridn[0]; for(unsigned i=0; i<argn.size(); ++i) allargs += "," + argn[i];
+     104           2 :   function::FunctionShortcut<int>::createAction( this, vals, allargs );
+     105           4 : }
+     106             : 
+     107             : 
+     108             : }
+     109             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/EvaluateGridFunction.cpp.func-sort-c.html b/coverage/gridtools/EvaluateGridFunction.cpp.func-sort-c.html new file mode 100644 index 000000000000..d3b41a6d039a --- /dev/null +++ b/coverage/gridtools/EvaluateGridFunction.cpp.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/EvaluateGridFunction.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - EvaluateGridFunction.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:8910188.1 %
Date:2024-04-19 12:12:35Functions:66100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools20EvaluateGridFunction4readEPNS_19ActionWithArgumentsE87
_ZN4PLMD9gridtools20EvaluateGridFunction16registerKeywordsERNS_8KeywordsE103
_ZN4PLMD9gridtools20EvaluateGridFunction5setupEPNS_15ActionWithValueE170
_ZNK4PLMD9gridtools20EvaluateGridFunction6getPbcEv242
_ZNK4PLMD9gridtools20EvaluateGridFunction10applyForceEPKNS_19ActionWithArgumentsERKSt6vectorIdSaIdEERKdRS7_1956
_ZNK4PLMD9gridtools20EvaluateGridFunction4calcEPKNS_19ActionWithArgumentsERKSt6vectorIdSaIdEERS7_RNS_6MatrixIdEE39145
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/EvaluateGridFunction.cpp.func.html b/coverage/gridtools/EvaluateGridFunction.cpp.func.html new file mode 100644 index 000000000000..5ef10dec8647 --- /dev/null +++ b/coverage/gridtools/EvaluateGridFunction.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/EvaluateGridFunction.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - EvaluateGridFunction.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:8910188.1 %
Date:2024-04-19 12:12:35Functions:66100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools20EvaluateGridFunction16registerKeywordsERNS_8KeywordsE103
_ZN4PLMD9gridtools20EvaluateGridFunction4readEPNS_19ActionWithArgumentsE87
_ZN4PLMD9gridtools20EvaluateGridFunction5setupEPNS_15ActionWithValueE170
_ZNK4PLMD9gridtools20EvaluateGridFunction10applyForceEPKNS_19ActionWithArgumentsERKSt6vectorIdSaIdEERKdRS7_1956
_ZNK4PLMD9gridtools20EvaluateGridFunction4calcEPKNS_19ActionWithArgumentsERKSt6vectorIdSaIdEERS7_RNS_6MatrixIdEE39145
_ZNK4PLMD9gridtools20EvaluateGridFunction6getPbcEv242
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/EvaluateGridFunction.cpp.gcov.html b/coverage/gridtools/EvaluateGridFunction.cpp.gcov.html new file mode 100644 index 000000000000..7175eb62781c --- /dev/null +++ b/coverage/gridtools/EvaluateGridFunction.cpp.gcov.html @@ -0,0 +1,228 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/EvaluateGridFunction.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - EvaluateGridFunction.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:8910188.1 %
Date:2024-04-19 12:12:35Functions:66100.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 "EvaluateGridFunction.h"
+      23             : #include "ActionWithGrid.h"
+      24             : #include "core/PlumedMain.h"
+      25             : #include "core/ActionSet.h"
+      26             : 
+      27             : namespace PLMD {
+      28             : namespace gridtools {
+      29             : 
+      30         103 : void EvaluateGridFunction::registerKeywords( Keywords& keys ) {
+      31         206 :   keys.add("compulsory","INTERPOLATION_TYPE","spline","the method to use for interpolation.  Can be spline, linear, ceiling or floor.");
+      32         206 :   keys.addFlag("ZERO_OUTSIDE_GRID_RANGE",false,"if we are asked to evaluate the function for a number that is outside the range of the grid set it to zero");
+      33         103 : }
+      34             : 
+      35         242 : std::vector<bool> EvaluateGridFunction::getPbc() const {
+      36         242 :   std::vector<bool> ipbc( gridobject.getDimension() );
+      37         484 :   for(unsigned i=0; i<ipbc.size(); ++i) ipbc[i] = gridobject.isPeriodic(i);
+      38         242 :   return ipbc;
+      39             : }
+      40             : 
+      41          87 : void EvaluateGridFunction::read( ActionWithArguments* action ) {
+      42          87 :   if( action->getPntrToArgument(0)->getRank()==0 || !action->getPntrToArgument(0)->hasDerivatives() ) action->error("should have one grid as input to this action");
+      43             :   // Get the input grid
+      44          87 :   ActionWithGrid* ag = ActionWithGrid::getInputActionWithGrid( (action->getPntrToArgument(0))->getPntrToAction() );
+      45         174 :   if( ag->getGridCoordinatesObject().getGridType()!="flat" ) action->error("cannot interpolate on fibonacci sphere");
+      46          87 :   std::vector<bool> ipbc( ag->getGridCoordinatesObject().getDimension() );
+      47         180 :   for(unsigned i=0; i<ipbc.size(); ++i) ipbc[i] = ag->getGridCoordinatesObject().isPeriodic(i);
+      48         174 :   gridobject.setup( "flat", ipbc, 0, 0.0 );
+      49             :   // Now use this information to create a gridobject
+      50             :   std::vector<std::string> argn;
+      51          87 :   parseFlag(action,"ZERO_OUTSIDE_GRID_RANGE",set_zero_outside_range);
+      52          87 :   if( set_zero_outside_range ) action->log.printf("  function is zero outside grid range \n");
+      53             :   // Get the type of interpolation that we are doing
+      54         174 :   std::string itype; parse(action,"INTERPOLATION_TYPE",itype);
+      55          87 :   if( itype=="spline" ) {
+      56           7 :     interpolation_type=spline;
+      57           7 :     spline_interpolator=Tools::make_unique<Interpolator>( action->getPntrToArgument(0), gridobject );
+      58          80 :   } else if( itype=="linear" ) {
+      59          65 :     interpolation_type=linear;
+      60          15 :   } else if( itype=="floor" ) {
+      61           0 :     interpolation_type=floor;
+      62          15 :   } else if( itype=="ceiling" ) {
+      63          15 :     interpolation_type=ceiling;
+      64           0 :   } else action->error("type " + itype + " of interpolation is not defined");
+      65          87 :   action->log.printf("  generating off grid points using %s interpolation \n", itype.c_str() );
+      66         174 : }
+      67             : 
+      68         170 : void EvaluateGridFunction::setup( ActionWithValue* action ) {
+      69         170 :   FunctionTemplateBase::setup( action );
+      70         170 :   ActionWithArguments* aarg = dynamic_cast<ActionWithArguments*>( action );
+      71         170 :   ActionWithGrid* ag = ActionWithGrid::getInputActionWithGrid( (aarg->getPntrToArgument(0))->getPntrToAction() );
+      72         170 :   const GridCoordinatesObject & ingrid = ag->getGridCoordinatesObject(); std::vector<double> sp( ingrid.getGridSpacing() );
+      73         170 :   gridobject.setBounds( ingrid.getMin(), ingrid.getMax(), ingrid.getNbin(false), sp );
+      74         170 : }
+      75             : 
+      76       39145 : void EvaluateGridFunction::calc( const ActionWithArguments* action, const std::vector<double>& args, std::vector<double>& vals, Matrix<double>& derivatives ) const {
+      77       39145 :   if( set_zero_outside_range && !gridobject.inbounds( args ) ) { vals[0]=0.0; return; }
+      78             :   unsigned dimension = gridobject.getDimension(); plumed_dbg_assert( args.size()==dimension && vals.size()==1 );
+      79       39145 :   if( interpolation_type==spline ) {
+      80       23729 :     std::vector<double> der( dimension );
+      81       23729 :     vals[0] =  spline_interpolator->splineInterpolation( args, der );
+      82       74416 :     for(unsigned j=0; j<dimension; ++j) derivatives(0,j) = der[j];
+      83       15416 :   } else if( interpolation_type==linear ) {
+      84        6600 :     Value* values=action->getPntrToArgument(0); std::vector<double> xfloor(dimension);
+      85        6600 :     std::vector<unsigned> indices(dimension), nindices(dimension), ind(dimension);
+      86        6600 :     gridobject.getIndices( args, indices ); unsigned nn=gridobject.getIndex(args);
+      87        6600 :     gridobject.getGridPointCoordinates( nn, nindices, xfloor );
+      88        6600 :     double y1 = values->get(nn); vals[0] = y1;
+      89       13200 :     for(unsigned i=0; i<args.size(); ++i) {
+      90        6600 :       int x0=1; if(nindices[i]==indices[i]) x0=0;
+      91        6600 :       double ddx=gridobject.getGridSpacing()[i];
+      92        6600 :       double X = fabs((args[i]-xfloor[i])/ddx-(double)x0);
+      93       13200 :       for(unsigned j=0; j<args.size(); ++j) ind[j] = indices[j];
+      94        6600 :       if( gridobject.isPeriodic(i) && (ind[i]+1)==gridobject.getNbin(false)[i] ) ind[i]=0;
+      95        6600 :       else ind[i] = ind[i] + 1;
+      96        6600 :       vals[0] += ( values->get( gridobject.getIndex(ind) ) - y1 )*X;
+      97        6600 :       derivatives(0,i) = ( values->get( gridobject.getIndex(ind) ) - y1 ) / ddx;
+      98             :     }
+      99        8816 :   } else if( interpolation_type==floor ) {
+     100           0 :     Value* values=action->getPntrToArgument(0); std::vector<unsigned> indices(dimension);
+     101           0 :     gridobject.getIndices( args, indices ); unsigned nn = gridobject.getIndex(indices);
+     102             :     plumed_dbg_assert( nn<values->getNumberOfValues() );
+     103           0 :     vals[0] = values->get( nn );
+     104           0 :     for(unsigned j=0; j<dimension; ++j) derivatives(0,j) = values->getGridDerivative( nn, j );
+     105        8816 :   } else if( interpolation_type==ceiling ) {
+     106        8816 :     Value* values=action->getPntrToArgument(0); std::vector<unsigned> indices(dimension);
+     107        8816 :     gridobject.getIndices( args, indices );
+     108       17632 :     for(unsigned i=0; i<indices.size(); ++i) {
+     109       17632 :       if( gridobject.isPeriodic(i) && (indices[i]+1)==gridobject.getNbin(false)[i] ) indices[i]=0;
+     110        6612 :       else indices[i] = indices[i] + 1;
+     111             :     }
+     112        8816 :     unsigned nn = gridobject.getIndex(indices); vals[0] = values->get( nn );
+     113       17632 :     for(unsigned j=0; j<dimension; ++j) derivatives(0,j) = values->getGridDerivative( nn, j );
+     114           0 :   } else plumed_error();
+     115             : }
+     116             : 
+     117        1956 : void EvaluateGridFunction::applyForce( const ActionWithArguments* action, const std::vector<double>& args, const double& force, std::vector<double>& forcesToApply ) const {
+     118             :   unsigned dimension = gridobject.getDimension();
+     119        1956 :   if( interpolation_type==spline ) {
+     120           0 :     action->error("can't apply forces on values interpolated using splines");
+     121        1956 :   } else if( interpolation_type==linear ) {
+     122         100 :     Value* values=action->getPntrToArgument(0); std::vector<double> xfloor(dimension);
+     123         100 :     std::vector<unsigned> indices(dimension), nindices(dimension), ind(dimension);
+     124         100 :     gridobject.getIndices( args, indices ); unsigned nn=gridobject.getIndex(args);
+     125         100 :     gridobject.getGridPointCoordinates( nn, nindices, xfloor );
+     126         200 :     for(unsigned i=0; i<args.size(); ++i) {
+     127         100 :       int x0=1; if(nindices[i]==indices[i]) x0=0;
+     128         100 :       double ddx=gridobject.getGridSpacing()[i];
+     129         100 :       double X = fabs((args[i]-xfloor[i])/ddx-(double)x0);
+     130         200 :       for(unsigned j=0; j<args.size(); ++j) ind[j] = indices[j];
+     131         100 :       if( gridobject.isPeriodic(i) && (ind[i]+1)==gridobject.getNbin(false)[i] ) ind[i]=0;
+     132         100 :       else ind[i] = ind[i] + 1;
+     133         100 :       forcesToApply[nn] += force*(1-X); forcesToApply[gridobject.getIndex(ind)] += X*force;
+     134             :     }
+     135        1856 :   } else if( interpolation_type==floor ) {
+     136           0 :     Value* values=action->getPntrToArgument(0); std::vector<unsigned> indices(dimension);
+     137           0 :     gridobject.getIndices( args, indices ); unsigned nn = gridobject.getIndex(indices);
+     138           0 :     forcesToApply[nn] += force;
+     139        1856 :   } else if( interpolation_type==ceiling ) {
+     140        1856 :     Value* values=action->getPntrToArgument(0); std::vector<unsigned> indices(dimension);
+     141        1856 :     gridobject.getIndices( args, indices );
+     142        3712 :     for(unsigned i=0; i<indices.size(); ++i) {
+     143        3712 :       if( gridobject.isPeriodic(i) && (indices[i]+1)==gridobject.getNbin(false)[i] ) indices[i]=0;
+     144        1392 :       else indices[i] = indices[i] + 1;
+     145             :     }
+     146        1856 :     unsigned nn = gridobject.getIndex(indices); forcesToApply[nn] += force;
+     147           0 :   } else plumed_error();
+     148        1956 : }
+     149             : 
+     150             : }
+     151             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/EvaluateGridFunction.h.func-sort-c.html b/coverage/gridtools/EvaluateGridFunction.h.func-sort-c.html new file mode 100644 index 000000000000..14c9a07c4c91 --- /dev/null +++ b/coverage/gridtools/EvaluateGridFunction.h.func-sort-c.html @@ -0,0 +1,77 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/EvaluateGridFunction.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - EvaluateGridFunction.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:6785.7 %
Date:2024-04-19 12:12:35Functions:010.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD9gridtools20EvaluateGridFunction11getArgStartEv0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/EvaluateGridFunction.h.func.html b/coverage/gridtools/EvaluateGridFunction.h.func.html new file mode 100644 index 000000000000..c82d615c8142 --- /dev/null +++ b/coverage/gridtools/EvaluateGridFunction.h.func.html @@ -0,0 +1,77 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/EvaluateGridFunction.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - EvaluateGridFunction.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:6785.7 %
Date:2024-04-19 12:12:35Functions:010.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD9gridtools20EvaluateGridFunction11getArgStartEv0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/EvaluateGridFunction.h.gcov.html b/coverage/gridtools/EvaluateGridFunction.h.gcov.html new file mode 100644 index 000000000000..7fa49cbe71b1 --- /dev/null +++ b/coverage/gridtools/EvaluateGridFunction.h.gcov.html @@ -0,0 +1,168 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/EvaluateGridFunction.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - EvaluateGridFunction.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:6785.7 %
Date:2024-04-19 12:12:35Functions: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_gridtools_EvaluateGridFunction_h
+      23             : #define __PLUMED_gridtools_EvaluateGridFunction_h
+      24             : 
+      25             : #include "function/FunctionTemplateBase.h"
+      26             : #include "Interpolator.h"
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace gridtools {
+      30             : 
+      31         190 : class EvaluateGridFunction : public function::FunctionTemplateBase {
+      32             : private:
+      33             : /// Holds the information on the grid
+      34             :   GridCoordinatesObject gridobject;
+      35             : /// How should we set the value of this function outside the range
+      36             :   bool set_zero_outside_range;
+      37             : /// How are we doing interpolation
+      38             :   enum {spline,linear,floor,ceiling} interpolation_type;
+      39             : /// This does the interpolating
+      40             :   std::unique_ptr<Interpolator> spline_interpolator;
+      41             : public:
+      42             : /// This is used to setup the input gridobject's bounds with the grid data from values
+      43             :   void registerKeywords( Keywords& keys ) override ;
+      44             :   void read( ActionWithArguments* action ) override ;
+      45           0 :   unsigned getArgStart() const override { return 1; }
+      46             :   void setup( ActionWithValue* action ) override;
+      47             :   void calc( const ActionWithArguments* action, const std::vector<double>& args, std::vector<double>& vals, Matrix<double>& derivatives ) const override ;
+      48             : /// Get the vector containing the minimum value of the grid in each dimension
+      49             :   std::vector<std::string> getMin() const ;
+      50             : /// Get the vector containing the maximum value of the grid in each dimension
+      51             :   std::vector<std::string> getMax() const ;
+      52             : /// Get the periodicity of the grid
+      53             :   std::vector<bool> getPbc() const ;
+      54             : /// Get the number of grid points in each direction
+      55             :   std::vector<unsigned> getNbin() const ;
+      56             : /// Get the grid spacing
+      57             :   const std::vector<double>& getGridSpacing() const ;
+      58             : /// This is used to apply forces in interpolate
+      59             :   void applyForce( const ActionWithArguments* action, const std::vector<double>& args, const double& force, std::vector<double>& forcesToApply ) const ;
+      60             : /// This gets the grid object
+      61             :   const GridCoordinatesObject & getGridObject() const ;
+      62             : };
+      63             : 
+      64             : inline
+      65             : std::vector<std::string> EvaluateGridFunction::getMin() const {
+      66         160 :   return gridobject.getMin();
+      67             : }
+      68             : 
+      69             : inline
+      70             : std::vector<std::string> EvaluateGridFunction::getMax() const {
+      71         160 :   return gridobject.getMax();
+      72             : }
+      73             : 
+      74             : inline
+      75             : std::vector<unsigned> EvaluateGridFunction::getNbin() const {
+      76         160 :   return gridobject.getNbin(false);
+      77             : }
+      78             : 
+      79             : inline
+      80             : const std::vector<double>& EvaluateGridFunction::getGridSpacing() const {
+      81         160 :   return gridobject.getGridSpacing();
+      82             : }
+      83             : 
+      84             : inline
+      85             : const GridCoordinatesObject & EvaluateGridFunction::getGridObject() const {
+      86        1702 :   return gridobject;
+      87             : }
+      88             : 
+      89             : }
+      90             : }
+      91             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/FindGridOptimum.cpp.func-sort-c.html b/coverage/gridtools/FindGridOptimum.cpp.func-sort-c.html new file mode 100644 index 000000000000..67534103afb5 --- /dev/null +++ b/coverage/gridtools/FindGridOptimum.cpp.func-sort-c.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/FindGridOptimum.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - FindGridOptimum.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:465583.6 %
Date:2024-04-19 12:12:35Functions:61060.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools15FindGridOptimum16setupOnFirstStepEb0
_ZN4PLMD9gridtools15FindGridOptimum22getNumberOfDerivativesEv0
_ZN4PLMD9gridtools15FindGridOptimumC2ERKNS_13ActionOptionsE0
_ZNK4PLMD9gridtools15FindGridOptimum11performTaskERKjRNS_10MultiValueE0
_ZN4PLMD9gridtools15FindGridOptimum9calculateEv2
_ZN4PLMD9gridtools15FindGridOptimumC1ERKNS_13ActionOptionsE2
_ZNK4PLMD9gridtools15FindGridOptimum22getGridCoordinateNamesB5cxx11Ev2
_ZN4PLMD9gridtools15FindGridOptimum16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD9gridtools15FindGridOptimum28calculateValueAndDerivativesERKSt6vectorIdSaIdEERS4_236
_ZNK4PLMD9gridtools15FindGridOptimum24getGridCoordinatesObjectEv240
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/FindGridOptimum.cpp.func.html b/coverage/gridtools/FindGridOptimum.cpp.func.html new file mode 100644 index 000000000000..982b363fbfc0 --- /dev/null +++ b/coverage/gridtools/FindGridOptimum.cpp.func.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/FindGridOptimum.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - FindGridOptimum.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:465583.6 %
Date:2024-04-19 12:12:35Functions:61060.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools15FindGridOptimum16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD9gridtools15FindGridOptimum16setupOnFirstStepEb0
_ZN4PLMD9gridtools15FindGridOptimum22getNumberOfDerivativesEv0
_ZN4PLMD9gridtools15FindGridOptimum28calculateValueAndDerivativesERKSt6vectorIdSaIdEERS4_236
_ZN4PLMD9gridtools15FindGridOptimum9calculateEv2
_ZN4PLMD9gridtools15FindGridOptimumC1ERKNS_13ActionOptionsE2
_ZN4PLMD9gridtools15FindGridOptimumC2ERKNS_13ActionOptionsE0
_ZNK4PLMD9gridtools15FindGridOptimum11performTaskERKjRNS_10MultiValueE0
_ZNK4PLMD9gridtools15FindGridOptimum22getGridCoordinateNamesB5cxx11Ev2
_ZNK4PLMD9gridtools15FindGridOptimum24getGridCoordinatesObjectEv240
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/FindGridOptimum.cpp.gcov.html b/coverage/gridtools/FindGridOptimum.cpp.gcov.html new file mode 100644 index 000000000000..cccd71a2c836 --- /dev/null +++ b/coverage/gridtools/FindGridOptimum.cpp.gcov.html @@ -0,0 +1,228 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/FindGridOptimum.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - FindGridOptimum.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:465583.6 %
Date:2024-04-19 12:12:35Functions:61060.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2018 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received 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/ConjugateGradient.h"
+      24             : #include "ActionWithGrid.h"
+      25             : #include "EvaluateGridFunction.h"
+      26             : #include "Interpolator.h"
+      27             : 
+      28             : //+PLUMEDOC GRIDCALC FIND_GRID_MINIMUM
+      29             : /*
+      30             : Find the point with the lowest value of the function on the grid
+      31             : 
+      32             : \par Examples
+      33             : 
+      34             : */
+      35             : //+ENDPLUMEDOC
+      36             : 
+      37             : //+PLUMEDOC GRIDCALC FIND_GRID_MAXIMUM
+      38             : /*
+      39             : Find the point with the highest value of the function on the grid
+      40             : 
+      41             : \par Examples
+      42             : 
+      43             : */
+      44             : //+ENDPLUMEDOC
+      45             : 
+      46             : namespace PLMD {
+      47             : namespace gridtools {
+      48             : 
+      49             : class FindGridOptimum : public ActionWithGrid {
+      50             : private:
+      51             :   bool domin;
+      52             :   double cgtol;
+      53             :   std::unique_ptr<Interpolator> function;
+      54             : public:
+      55             :   static void registerKeywords( Keywords& keys );
+      56             :   explicit FindGridOptimum(const ActionOptions&ao);
+      57           0 :   void setupOnFirstStep( const bool incalc ) override { plumed_error(); }
+      58             :   unsigned getNumberOfDerivatives() override ;
+      59             :   void calculate() override ;
+      60             :   std::vector<std::string> getGridCoordinateNames() const override ;
+      61             :   const GridCoordinatesObject& getGridCoordinatesObject() const override ;
+      62             :   double calculateValueAndDerivatives( const std::vector<double>& pp, std::vector<double>& der );
+      63           0 :   void performTask( const unsigned& current, MultiValue& myvals ) const override { plumed_error(); }
+      64             : };
+      65             : 
+      66             : PLUMED_REGISTER_ACTION(FindGridOptimum,"FIND_GRID_MAXIMUM")
+      67             : PLUMED_REGISTER_ACTION(FindGridOptimum,"FIND_GRID_MINIMUM")
+      68             : 
+      69           6 : void FindGridOptimum::registerKeywords( Keywords& keys ) {
+      70           6 :   ActionWithGrid::registerKeywords( keys ); keys.use("ARG");
+      71          12 :   keys.addFlag("NOINTERPOL",false,"do not interpolate the function when finding the optimum");
+      72          12 :   keys.add("compulsory","CGTOL","1E-4","the tolerance for the conjugate gradient optimization");
+      73          12 :   keys.addOutputComponent("optval","default","the value of the function at the optimum");
+      74          12 :   keys.addOutputComponent("_opt","default","the values of the arguments of the function at the optimum can be referenced elsewhere in the input file "
+      75             :                           "by using the names of the arguments followed by the string _opt");
+      76           6 : }
+      77             : 
+      78           2 : FindGridOptimum::FindGridOptimum(const ActionOptions&ao):
+      79             :   Action(ao),
+      80             :   ActionWithGrid(ao),
+      81           2 :   cgtol(0)
+      82             : {
+      83           2 :   if( getName()=="FIND_GRID_MAXIMUM" ) domin=false;
+      84           2 :   else if( getName()=="FIND_GRID_MINIMUM" ) domin=true;
+      85           0 :   else plumed_error();
+      86             :   // Create value for this function
+      87           2 :   std::vector<std::string> argn( getGridCoordinateNames() );
+      88           5 :   std::vector<unsigned> shape(0); for(unsigned i=0; i<argn.size(); ++i) addComponent( argn[i] + "_opt", shape );
+      89           4 :   addComponent( "optval", shape ); componentIsNotPeriodic( "optval" );
+      90           2 :   bool nointerpol=false; parseFlag("NOINTERPOL",nointerpol);
+      91           6 :   if( !nointerpol ) { parse("CGTOL",cgtol); function=Tools::make_unique<Interpolator>( getPntrToArgument(0), getGridCoordinatesObject() ); }
+      92           2 : }
+      93             : 
+      94           0 : unsigned FindGridOptimum::getNumberOfDerivatives() {
+      95           0 :   return 0;
+      96             : }
+      97             : 
+      98         240 : const GridCoordinatesObject& FindGridOptimum::getGridCoordinatesObject() const {
+      99         240 :   ActionWithGrid* ag=ActionWithGrid::getInputActionWithGrid( getPntrToArgument(0)->getPntrToAction() );
+     100         240 :   plumed_assert( ag ); return ag->getGridCoordinatesObject();
+     101             : }
+     102             : 
+     103           2 : std::vector<std::string> FindGridOptimum::getGridCoordinateNames() const {
+     104           2 :   ActionWithGrid* ag=ActionWithGrid::getInputActionWithGrid( getPntrToArgument(0)->getPntrToAction() );
+     105           2 :   plumed_assert( ag ); return ag->getGridCoordinateNames();
+     106             : }
+     107             : 
+     108         236 : double FindGridOptimum::calculateValueAndDerivatives( const std::vector<double>& pp, std::vector<double>& der ) {
+     109         236 :   double val = function->splineInterpolation( pp, der );
+     110             :   // We normalise the derivatives here and set them so that the linesearch is done over the cell that we know
+     111             :   // in the grid that we know the minimum is inside
+     112         236 :   std::vector<double> spacing( getGridCoordinatesObject().getGridSpacing() );
+     113         623 :   double norm = 0; for(unsigned i=0; i<der.size(); ++i) norm += der[i]*der[i];
+     114         623 :   norm = sqrt(norm); for(unsigned i=0; i<der.size(); ++i) der[i] = spacing[i]*der[i] / norm;
+     115         236 :   if( domin ) return val;
+     116             :   // If we are looking for a maximum
+     117           0 :   for(unsigned i=0; i<der.size(); ++i) der[i] = -der[i];
+     118           0 :   return -val;
+     119             : }
+     120             : 
+     121           2 : void FindGridOptimum::calculate() {
+     122           2 :   const GridCoordinatesObject& ingrid = getGridCoordinatesObject(); Value* gval = getPntrToArgument(0);
+     123           2 :   std::vector<double> optargs( gval->getRank() ); std::vector<unsigned> gridind( gval->getRank() );
+     124           2 :   double optval=gval->get( 0 ); ingrid.getGridPointCoordinates( 0, gridind, optargs );
+     125           2 :   unsigned nval = gval->getNumberOfValues(); bool constant=true;
+     126        2602 :   for(unsigned i=0; i<nval; ++i) {
+     127        2600 :     double tval = gval->get( i );
+     128        2600 :     if( domin && (tval<optval || std::isnan(optval)) ) { constant=false; optval=tval; ingrid.getGridPointCoordinates( i, gridind, optargs ); }
+     129        2600 :     if( !domin && (tval>optval || std::isnan(optval)) ) { constant=false; optval=tval; ingrid.getGridPointCoordinates( i, gridind, optargs ); }
+     130             :   }
+     131             :   // This basically ensures we deal with cases where all points on the grid are infinity as isinf doesn't work on intel compiler
+     132           2 :   if( constant ) {
+     133           0 :     if( domin && gval->get(0)>=gval->get(1) ) return;
+     134           0 :     else if( gval->get(0)<=gval->get(1) ) return;
+     135             :   }
+     136           2 :   if( std::isinf(optval) ) { return; }
+     137             : 
+     138           2 :   if( std::isnan(optval) ) error("all values on grid are nans");
+     139             :   // And do conjugate gradient optimisation (because we can!!)
+     140           2 :   if( cgtol>0 ) {
+     141             :     ConjugateGradient<FindGridOptimum> myminimiser( this );
+     142           2 :     myminimiser.minimise( cgtol, optargs, &FindGridOptimum::calculateValueAndDerivatives );
+     143             :   }
+     144             :   // And set the final value
+     145           5 :   for(unsigned j=0; j<optargs.size(); ++j) getPntrToComponent(j)->set( optargs[j] );
+     146           2 :   std::vector<double> optder( gval->getRank() );
+     147           2 :   getPntrToComponent(optargs.size())->set( function->splineInterpolation( optargs, optder ) );
+     148             : }
+     149             : 
+     150             : }
+     151             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/FunctionOfGrid.h.func-sort-c.html b/coverage/gridtools/FunctionOfGrid.h.func-sort-c.html new file mode 100644 index 000000000000..e37d01260e8c --- /dev/null +++ b/coverage/gridtools/FunctionOfGrid.h.func-sort-c.html @@ -0,0 +1,153 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/FunctionOfGrid.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - FunctionOfGrid.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:969997.0 %
Date:2024-04-19 12:12:35Functions:162080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD9gridtools14FunctionOfGridINS_8function3SumEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD9gridtools14FunctionOfGridINS_8function3SumEE17gatherStoredValueERKjS6_RKNS_10MultiValueES6_RSt6vectorIdSaIdEE0
_ZNK4PLMD9gridtools14FunctionOfGridINS_8function3SumEE22getGridCoordinateNamesB5cxx11Ev0
_ZNK4PLMD9gridtools14FunctionOfGridINS_8function6CustomEE12writeInGraphB5cxx11Ev0
_ZN4PLMD9gridtools14FunctionOfGridINS_8function3SumEEC1ERKNS_13ActionOptionsE90
_ZN4PLMD9gridtools14FunctionOfGridINS_8function3SumEE16registerKeywordsERNS_8KeywordsE94
_ZN4PLMD9gridtools14FunctionOfGridINS_8function3SumEE16setupOnFirstStepEb180
_ZNK4PLMD9gridtools14FunctionOfGridINS_8function6CustomEE22getGridCoordinateNamesB5cxx11Ev197
_ZN4PLMD9gridtools14FunctionOfGridINS_8function6CustomEEC1ERKNS_13ActionOptionsE432
_ZN4PLMD9gridtools14FunctionOfGridINS_8function6CustomEE16registerKeywordsERNS_8KeywordsE436
_ZNK4PLMD9gridtools14FunctionOfGridINS_8function3SumEE24getGridCoordinatesObjectEv512
_ZN4PLMD9gridtools14FunctionOfGridINS_8function3SumEE22getNumberOfDerivativesEv514
_ZN4PLMD9gridtools14FunctionOfGridINS_8function6CustomEE16setupOnFirstStepEb864
_ZN4PLMD9gridtools14FunctionOfGridINS_8function6CustomEE22getNumberOfDerivativesEv1298
_ZN4PLMD9gridtools14FunctionOfGridINS_8function3SumEE5applyEv2100
_ZN4PLMD9gridtools14FunctionOfGridINS_8function6CustomEE5applyEv3967
_ZNK4PLMD9gridtools14FunctionOfGridINS_8function6CustomEE24getGridCoordinatesObjectEv14936
_ZNK4PLMD9gridtools14FunctionOfGridINS_8function3SumEE11performTaskERKjRNS_10MultiValueE23665
_ZNK4PLMD9gridtools14FunctionOfGridINS_8function6CustomEE11performTaskERKjRNS_10MultiValueE951149
_ZNK4PLMD9gridtools14FunctionOfGridINS_8function6CustomEE17gatherStoredValueERKjS6_RKNS_10MultiValueES6_RSt6vectorIdSaIdEE951149
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/FunctionOfGrid.h.func.html b/coverage/gridtools/FunctionOfGrid.h.func.html new file mode 100644 index 000000000000..d926f1136b77 --- /dev/null +++ b/coverage/gridtools/FunctionOfGrid.h.func.html @@ -0,0 +1,153 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/FunctionOfGrid.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - FunctionOfGrid.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:969997.0 %
Date:2024-04-19 12:12:35Functions:162080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools14FunctionOfGridINS_8function3SumEE16registerKeywordsERNS_8KeywordsE94
_ZN4PLMD9gridtools14FunctionOfGridINS_8function3SumEE16setupOnFirstStepEb180
_ZN4PLMD9gridtools14FunctionOfGridINS_8function3SumEE22getNumberOfDerivativesEv514
_ZN4PLMD9gridtools14FunctionOfGridINS_8function3SumEE5applyEv2100
_ZN4PLMD9gridtools14FunctionOfGridINS_8function3SumEEC1ERKNS_13ActionOptionsE90
_ZN4PLMD9gridtools14FunctionOfGridINS_8function6CustomEE16registerKeywordsERNS_8KeywordsE436
_ZN4PLMD9gridtools14FunctionOfGridINS_8function6CustomEE16setupOnFirstStepEb864
_ZN4PLMD9gridtools14FunctionOfGridINS_8function6CustomEE22getNumberOfDerivativesEv1298
_ZN4PLMD9gridtools14FunctionOfGridINS_8function6CustomEE5applyEv3967
_ZN4PLMD9gridtools14FunctionOfGridINS_8function6CustomEEC1ERKNS_13ActionOptionsE432
_ZNK4PLMD9gridtools14FunctionOfGridINS_8function3SumEE11performTaskERKjRNS_10MultiValueE23665
_ZNK4PLMD9gridtools14FunctionOfGridINS_8function3SumEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD9gridtools14FunctionOfGridINS_8function3SumEE17gatherStoredValueERKjS6_RKNS_10MultiValueES6_RSt6vectorIdSaIdEE0
_ZNK4PLMD9gridtools14FunctionOfGridINS_8function3SumEE22getGridCoordinateNamesB5cxx11Ev0
_ZNK4PLMD9gridtools14FunctionOfGridINS_8function3SumEE24getGridCoordinatesObjectEv512
_ZNK4PLMD9gridtools14FunctionOfGridINS_8function6CustomEE11performTaskERKjRNS_10MultiValueE951149
_ZNK4PLMD9gridtools14FunctionOfGridINS_8function6CustomEE12writeInGraphB5cxx11Ev0
_ZNK4PLMD9gridtools14FunctionOfGridINS_8function6CustomEE17gatherStoredValueERKjS6_RKNS_10MultiValueES6_RSt6vectorIdSaIdEE951149
_ZNK4PLMD9gridtools14FunctionOfGridINS_8function6CustomEE22getGridCoordinateNamesB5cxx11Ev197
_ZNK4PLMD9gridtools14FunctionOfGridINS_8function6CustomEE24getGridCoordinatesObjectEv14936
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/FunctionOfGrid.h.gcov.html b/coverage/gridtools/FunctionOfGrid.h.gcov.html new file mode 100644 index 000000000000..56c342f7ec2d --- /dev/null +++ b/coverage/gridtools/FunctionOfGrid.h.gcov.html @@ -0,0 +1,305 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/FunctionOfGrid.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - FunctionOfGrid.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:969997.0 %
Date:2024-04-19 12:12:35Functions:162080.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2020 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a 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_FunctionOfGrid_h
+      23             : #define __PLUMED_gridtools_FunctionOfGrid_h
+      24             : 
+      25             : #include "ActionWithGrid.h"
+      26             : #include "function/Custom.h"
+      27             : #include "tools/Matrix.h"
+      28             : 
+      29             : namespace PLMD {
+      30             : namespace gridtools {
+      31             : 
+      32             : template <class T>
+      33             : class FunctionOfGrid : public ActionWithGrid {
+      34             : private:
+      35             : /// The function that is being computed
+      36             :   T myfunc;
+      37             : public:
+      38             :   static void registerKeywords(Keywords&);
+      39             :   explicit FunctionOfGrid(const ActionOptions&);
+      40             : /// This does setup required on first step
+      41             :   void setupOnFirstStep( const bool incalc ) override ;
+      42             : /// Get the number of derivatives for this action
+      43             :   unsigned getNumberOfDerivatives() override ;
+      44             : /// Get the label to write in the graph
+      45           0 :   std::string writeInGraph() const override { return myfunc.getGraphInfo( getName() ); }
+      46             : /// Get the underlying names
+      47             :   std::vector<std::string> getGridCoordinateNames() const override ;
+      48             : /// Get the underlying grid coordinates object
+      49             :   const GridCoordinatesObject& getGridCoordinatesObject() const override ;
+      50             : /// Calculate the function
+      51             :   void performTask( const unsigned& current, MultiValue& myvals ) const override ;
+      52             : ///
+      53             :   void gatherStoredValue( const unsigned& valindex, const unsigned& code, const MultiValue& myvals,
+      54             :                           const unsigned& bufstart, std::vector<double>& buffer ) const override ;
+      55             : /// Add the forces
+      56             :   void apply() override;
+      57             : };
+      58             : 
+      59             : template <class T>
+      60         530 : void FunctionOfGrid<T>::registerKeywords(Keywords& keys ) {
+      61         530 :   ActionWithGrid::registerKeywords(keys); keys.use("ARG");
+      62        1060 :   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");
+      63         530 :   T tfunc; tfunc.registerKeywords( keys ); if( typeid(tfunc)==typeid(function::Custom()) ) keys.add("hidden","NO_ACTION_LOG","suppresses printing from action on the log");
+      64         530 : }
+      65             : 
+      66             : template <class T>
+      67         522 : FunctionOfGrid<T>::FunctionOfGrid(const ActionOptions&ao):
+      68             :   Action(ao),
+      69         522 :   ActionWithGrid(ao)
+      70             : {
+      71         522 :   if( getNumberOfArguments()==0 ) error("found no arguments");
+      72             :   // This will require a fix
+      73         522 :   if( getPntrToArgument(0)->getRank()==0 || !getPntrToArgument(0)->hasDerivatives() ) error("first input to this action must be a grid");
+      74             :   // Get the shape of the input grid
+      75         522 :   std::vector<unsigned> shape( getPntrToArgument(0)->getShape() );
+      76         935 :   for(unsigned i=1; i<getNumberOfArguments(); ++i ) {
+      77         413 :     if( getPntrToArgument(i)->getRank()==0 ) continue;
+      78         291 :     std::vector<unsigned> s( getPntrToArgument(i)->getShape() );
+      79         291 :     if( s.size()!=shape.size() ) error("mismatch between dimensionalities of input grids");
+      80             :   }
+      81             :   // Read the input and do some checks
+      82         522 :   myfunc.read( this );
+      83             :   // Check we are not calculating an integral
+      84         522 :   if( myfunc.zeroRank() ) { shape.resize(0); }
+      85             :   // Check that derivatives are available
+      86          90 :   if( !myfunc.derivativesImplemented() ) error("derivatives have not been implemended for " + getName() );
+      87             :   // Get the names of the components
+      88         522 :   std::vector<std::string> components( keywords.getOutputComponents() );
+      89             :   // Create the values to hold the output
+      90         180 :   if( components.size()==0 && myfunc.zeroRank() ) addValueWithDerivatives();
+      91         432 :   else if( components.size()==0 ) addValueWithDerivatives( shape );
+      92           0 :   else error("functions of grid should only output one grid");
+      93             :   // Set the periodicities of the output components
+      94         522 :   myfunc.setPeriodicityForOutputs( this );
+      95             :   // Check if we can turn off the derivatives when they are zero
+      96         432 :   if( myfunc.getDerivativeZeroIfValueIsZero() )  {
+      97         490 :     for(int i=0; i<getNumberOfComponents(); ++i) getPntrToComponent(i)->setDerivativeIsZeroWhenValueIsZero();
+      98             :   }
+      99         522 :   setupOnFirstStep( false );
+     100        1044 : }
+     101             : 
+     102             : template <class T>
+     103        1044 : void FunctionOfGrid<T>::setupOnFirstStep( const bool incalc ) {
+     104             :   double volume = 1.0;
+     105        1044 :   const GridCoordinatesObject& mygrid = getGridCoordinatesObject();
+     106        1044 :   unsigned npoints = getPntrToArgument(0)->getNumberOfValues();
+     107        2088 :   if( mygrid.getGridType()=="flat" ) {
+     108         998 :     std::vector<unsigned> shape( getGridCoordinatesObject().getNbin(true) );
+     109        1792 :     for(unsigned i=1; i<getNumberOfArguments(); ++i ) {
+     110         794 :       if( getPntrToArgument(i)->getRank()==0 ) continue;
+     111         572 :       std::vector<unsigned> s( getPntrToArgument(i)->getShape() );
+     112        1156 :       for(unsigned j=0; j<shape.size(); ++j) {
+     113         584 :         if( shape[j]!=s[j] ) error("mismatch between sizes of input grids");
+     114             :       }
+     115             :     }
+     116        1996 :     for(int i=0; i<getNumberOfComponents(); ++i) {
+     117         998 :       if( getPntrToComponent(i)->getRank()>0 ) getPntrToComponent(i)->setShape(shape);
+     118             :     }
+     119         998 :     std::vector<double> vv( getGridCoordinatesObject().getGridSpacing() );
+     120        1078 :     volume=vv[0]; for(unsigned i=1; i<vv.size(); ++i) volume *=vv[i];
+     121          14 :   } else volume=4*pi / static_cast<double>( npoints );
+     122             :   // This resizes the scalars
+     123        2088 :   for(int i=0; i<getNumberOfComponents(); ++i) {
+     124        1044 :     if( getPntrToComponent(i)->getRank()==0 ) getPntrToComponent(i)->resizeDerivatives( npoints );
+     125             :   }
+     126        1044 :   if( getName()=="SUM_GRID" ) volume = 1.0;
+     127             :   // This sets the prefactor to the volume which converts integrals to sums
+     128        1044 :   myfunc.setup( this ); myfunc.setPrefactor( this, volume );
+     129        1044 : }
+     130             : 
+     131             : template <class T>
+     132       15448 : const GridCoordinatesObject& FunctionOfGrid<T>::getGridCoordinatesObject() const {
+     133       15448 :   ActionWithGrid* ag=ActionWithGrid::getInputActionWithGrid( getPntrToArgument(0)->getPntrToAction() );
+     134       15448 :   plumed_assert( ag ); return ag->getGridCoordinatesObject();
+     135             : }
+     136             : 
+     137             : template <class T>
+     138         197 : std::vector<std::string> FunctionOfGrid<T>::getGridCoordinateNames() const {
+     139         197 :   ActionWithGrid* ag=ActionWithGrid::getInputActionWithGrid( getPntrToArgument(0)->getPntrToAction() );
+     140         197 :   plumed_assert( ag ); return ag->getGridCoordinateNames();
+     141             : }
+     142             : 
+     143             : template <class T>
+     144        1812 : unsigned FunctionOfGrid<T>::getNumberOfDerivatives() {
+     145         514 :   if( myfunc.zeroRank() ) return getPntrToArgument(0)->getNumberOfValues();
+     146        1298 :   unsigned nder = getGridCoordinatesObject().getDimension();
+     147        1298 :   return getGridCoordinatesObject().getDimension() + getNumberOfArguments() - myfunc.getArgStart();
+     148             : }
+     149             : 
+     150             : template <class T>
+     151      974814 : void FunctionOfGrid<T>::performTask( const unsigned& current, MultiValue& myvals ) const {
+     152      974814 :   unsigned argstart=myfunc.getArgStart(); std::vector<double> args( getNumberOfArguments() - argstart );
+     153     2629182 :   for(unsigned i=argstart; i<getNumberOfArguments(); ++i) {
+     154     1654368 :     if( getPntrToArgument(i)->getRank()==0 ) args[i-argstart]=getPntrToArgument(i)->get();
+     155     1110136 :     else args[i-argstart] = getPntrToArgument(i)->get(current);
+     156             :   }
+     157             :   // Calculate the function and its derivatives
+     158      974814 :   std::vector<double> vals(1); Matrix<double> derivatives( 1, getNumberOfArguments()-argstart );
+     159      974814 :   myfunc.calc( this, args, vals, derivatives ); unsigned np = myvals.getTaskIndex();
+     160             :   // And set the values and derivatives
+     161      974814 :   unsigned ostrn = getConstPntrToComponent(0)->getPositionInStream();
+     162      974814 :   myvals.addValue( ostrn, vals[0] );
+     163       23665 :   if( !myfunc.zeroRank() ) {
+     164             :     // Add the derivatives for a grid
+     165     2581852 :     for(unsigned j=argstart; j<getNumberOfArguments(); ++j) {
+     166             :       // We store all the derivatives of all the input values - i.e. the grid points these are used in apply
+     167     1630703 :       myvals.addDerivative( ostrn, getConstPntrToComponent(0)->getRank()+j-argstart, derivatives(0,j-argstart) );
+     168             :       // And now we calculate the derivatives of the value that is stored on the grid correctly so that we can interpolate functions
+     169     1630703 :       if( getPntrToArgument(j)->getRank()!=0 ) {
+     170     3413677 :         for(unsigned k=0; k<getPntrToArgument(j)->getRank(); ++k) myvals.addDerivative( ostrn, k, derivatives(0,j-argstart)*getPntrToArgument(j)->getGridDerivative( np, k ) );
+     171             :       }
+     172             :     }
+     173      951149 :     unsigned nderivatives = getConstPntrToComponent(0)->getNumberOfGridDerivatives();
+     174     4575808 :     for(unsigned j=0; j<nderivatives; ++j) myvals.updateIndex( ostrn, j );
+     175       23665 :   } else if( !doNotCalculateDerivatives() ) {
+     176             :     // These are the derivatives of the integral
+     177        8161 :     myvals.addDerivative( ostrn, current, derivatives(0,0) ); myvals.updateIndex( ostrn, current );
+     178             :   }
+     179      974814 : }
+     180             : 
+     181             : template <class T>
+     182      951149 : void FunctionOfGrid<T>::gatherStoredValue( const unsigned& valindex, const unsigned& code, const MultiValue& myvals,
+     183             :     const unsigned& bufstart, std::vector<double>& buffer ) const {
+     184      951149 :   if( getConstPntrToComponent(0)->getRank()>0 && getConstPntrToComponent(0)->hasDerivatives() ) {
+     185             :     plumed_dbg_assert( getNumberOfComponents()==1 && valindex==0 );
+     186      951149 :     unsigned nder = getConstPntrToComponent(0)->getNumberOfGridDerivatives();
+     187      951149 :     unsigned ostr = getConstPntrToComponent(0)->getPositionInStream();
+     188      951149 :     unsigned kp = bufstart + code*(1+nder); buffer[kp] += myvals.get( ostr );
+     189     4575808 :     for(unsigned i=0; i<nder; ++i) buffer[kp + 1 + i] += myvals.getDerivative( ostr, i );
+     190           0 :   } else ActionWithVector::gatherStoredValue( valindex, code, myvals, bufstart, buffer );
+     191      951149 : }
+     192             : 
+     193             : template <class T>
+     194        6067 : void FunctionOfGrid<T>::apply() {
+     195        6561 :   if( doNotCalculateDerivatives() || !getPntrToComponent(0)->forcesWereAdded() ) return;
+     196             : 
+     197             :   // This applies forces for the integral
+     198         494 :   if( myfunc.zeroRank() ) { ActionWithVector::apply(); return; }
+     199             : 
+     200             :   // Work out how to deal with arguments
+     201             :   unsigned nscalars=0, argstart=myfunc.getArgStart();
+     202        1870 :   for(unsigned i=argstart; i<getNumberOfArguments(); ++i) {
+     203        1245 :     if( getPntrToArgument(i)->getRank()==0 ) { nscalars++; }
+     204             :   }
+     205             : 
+     206         625 :   std::vector<double> totv(nscalars,0); Value* outval=getPntrToComponent(0);
+     207        7575 :   for(unsigned i=0; i<outval->getNumberOfValues(); ++i) {
+     208             :     nscalars=0;
+     209       19845 :     for(unsigned j=argstart; j<getNumberOfArguments(); ++j) {
+     210       12895 :       double fforce = outval->getForce(i);
+     211       12895 :       if( getPntrToArgument(j)->getRank()==0 ) {
+     212        3205 :         totv[nscalars] += fforce*outval->getGridDerivative( i, outval->getRank()+j ); nscalars++;
+     213             :       } else {
+     214        9690 :         double vval = outval->getGridDerivative( i, outval->getRank()+j  );
+     215        9690 :         getPntrToArgument(j)->addForce( i, fforce*vval );
+     216             :       }
+     217             :     }
+     218             :   }
+     219             :   nscalars=0;
+     220        1870 :   for(unsigned i=argstart; i<getNumberOfArguments(); ++i) {
+     221        1245 :     if( getPntrToArgument(i)->getRank()==0 ) { getPntrToArgument(i)->addForce( 0, totv[nscalars] ); nscalars++; }
+     222             :   }
+     223             : 
+     224             : }
+     225             : 
+     226             : }
+     227             : }
+     228             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/Gradient.cpp.func-sort-c.html b/coverage/gridtools/Gradient.cpp.func-sort-c.html new file mode 100644 index 000000000000..76c83504eebc --- /dev/null +++ b/coverage/gridtools/Gradient.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/Gradient.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - Gradient.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4747100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools8GradientC2ERKNS_13ActionOptionsE0
_ZN4PLMD9gridtools8GradientC1ERKNS_13ActionOptionsE7
_ZN4PLMD9gridtools8Gradient16registerKeywordsERNS_8KeywordsE9
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/Gradient.cpp.func.html b/coverage/gridtools/Gradient.cpp.func.html new file mode 100644 index 000000000000..0a0baee45207 --- /dev/null +++ b/coverage/gridtools/Gradient.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/Gradient.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - Gradient.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4747100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools8Gradient16registerKeywordsERNS_8KeywordsE9
_ZN4PLMD9gridtools8GradientC1ERKNS_13ActionOptionsE7
_ZN4PLMD9gridtools8GradientC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/Gradient.cpp.gcov.html b/coverage/gridtools/Gradient.cpp.gcov.html new file mode 100644 index 000000000000..39f73f294760 --- /dev/null +++ b/coverage/gridtools/Gradient.cpp.gcov.html @@ -0,0 +1,182 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/Gradient.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - Gradient.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4747100.0 %
Date:2024-04-19 12:12:35Functions: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 "core/ActionShortcut.h"
+      23             : #include "core/ActionRegister.h"
+      24             : 
+      25             : //+PLUMEDOC MCOLVAR GRADIENT
+      26             : /*
+      27             : Calculate the gradient of an input grid
+      28             : 
+      29             : \par Examples
+      30             : 
+      31             : */
+      32             : //+ENDPLUMEDOC
+      33             : 
+      34             : namespace PLMD {
+      35             : namespace gridtools {
+      36             : 
+      37             : class Gradient : public ActionShortcut {
+      38             : public:
+      39             :   static void registerKeywords(Keywords& keys);
+      40             :   explicit Gradient(const ActionOptions&);
+      41             : };
+      42             : 
+      43             : PLUMED_REGISTER_ACTION(Gradient,"GRADIENT")
+      44             : 
+      45           9 : void Gradient::registerKeywords( Keywords& keys ) {
+      46           9 :   ActionShortcut::registerKeywords( keys );
+      47          18 :   keys.add("compulsory","ORIGIN","we will use the position of this atom as the origin in our calculation");
+      48          18 :   keys.add("compulsory","NBINS","number of bins to use in each direction for the calculation of the gradient");
+      49          18 :   keys.add("compulsory","DIR","xyz","the directions in which we are calculating the graident.  Should be x, y, z, xy, xz, yz or xyz");
+      50          18 :   keys.add("compulsory","SIGMA","the width of the function to be used for kernel density estimation");
+      51          18 :   keys.add("compulsory","KERNEL","gaussian-bin","the type of kernel function to be used in the grids");
+      52          18 :   keys.add("compulsory","ATOMS","calculate the gradient of these atoms");
+      53          27 :   keys.needsAction("DISTANCES"); keys.needsAction("KDE"); keys.needsAction("INTERPOLATE_GRID");
+      54          27 :   keys.needsAction("CUSTOM"); keys.needsAction("SUM_GRID"); keys.needsAction("COMBINE");
+      55           9 : }
+      56             : 
+      57           7 : Gradient::Gradient(const ActionOptions&ao):
+      58             :   Action(ao),
+      59           7 :   ActionShortcut(ao)
+      60             : {
+      61          14 :   std::string atom_str; parse("ATOMS",atom_str);
+      62          14 :   std::string dir; parse("DIR",dir);
+      63          14 :   std::string origin_str; parse("ORIGIN",origin_str);
+      64          14 :   std::string nbin_str; parse("NBINS",nbin_str);
+      65          14 :   std::string band_str; parse("SIGMA",band_str);
+      66           7 :   std::string kernel_str; parse("KERNEL",kernel_str);
+      67             :   // First get positions of all atoms relative to origin
+      68          14 :   readInputLine( getShortcutLabel() + "_dist: DISTANCES ORIGIN=" + origin_str + " ATOMS=" + atom_str + " COMPONENTS");
+      69             :   // Now constrcut the histograms
+      70          22 :   if( dir=="x" || dir=="xy" || dir=="xz" || dir=="xyz" ) {
+      71           8 :     readInputLine( getShortcutLabel() + "_xhisto: KDE ARG=" + getShortcutLabel() + "_dist.x GRID_BIN=" + nbin_str + " KERNEL=" + kernel_str + " BANDWIDTH=" + band_str );
+      72           8 :     std::string thislab = getShortcutLabel() + "_xgrad"; if( dir=="x" ) thislab = getShortcutLabel();
+      73           8 :     readInputLine( thislab + "_shift: INTERPOLATE_GRID ARG=" + getShortcutLabel() + "_xhisto INTERPOLATION_TYPE=ceiling MIDPOINTS");
+      74           8 :     readInputLine( thislab + "_x2: CUSTOM ARG=" + getShortcutLabel() + "_xhisto," + thislab + "_shift FUNC=(x-y)*(x-y) PERIODIC=NO");
+      75           8 :     readInputLine( thislab + ": SUM_GRID ARG=" + thislab + "_x2 PERIODIC=NO");
+      76             :   }
+      77          22 :   if( dir=="y" || dir=="xy" || dir=="yz" || dir=="xyz" ) {
+      78           8 :     readInputLine( getShortcutLabel() + "_yhisto: KDE ARG=" + getShortcutLabel() + "_dist.y GRID_BIN=" + nbin_str + " KERNEL=" + kernel_str + " BANDWIDTH=" + band_str );
+      79           8 :     std::string thislab = getShortcutLabel() + "_ygrad"; if( dir=="y" ) thislab = getShortcutLabel();
+      80           8 :     readInputLine( thislab + "_shift: INTERPOLATE_GRID ARG=" + getShortcutLabel() + "_yhisto INTERPOLATION_TYPE=ceiling MIDPOINTS");
+      81           8 :     readInputLine( thislab + "_x2: CUSTOM ARG=" + getShortcutLabel() + "_yhisto," + thislab + "_shift FUNC=(x-y)*(x-y) PERIODIC=NO");
+      82           8 :     readInputLine( thislab + ": SUM_GRID ARG=" + thislab + "_x2 PERIODIC=NO");
+      83             :   }
+      84          22 :   if( dir=="z" || dir=="yz" || dir=="xz" || dir=="xyz" ) {
+      85           8 :     readInputLine( getShortcutLabel() + "_zhisto: KDE ARG=" + getShortcutLabel() + "_dist.z GRID_BIN=" + nbin_str + " KERNEL=" + kernel_str + " BANDWIDTH=" + band_str );
+      86           8 :     std::string thislab = getShortcutLabel() + "_zgrad"; if( dir=="z" ) thislab = getShortcutLabel();
+      87           8 :     readInputLine( thislab + "_shift: INTERPOLATE_GRID ARG=" + getShortcutLabel() + "_zhisto INTERPOLATION_TYPE=ceiling MIDPOINTS");
+      88           8 :     readInputLine( thislab + "_x2: CUSTOM ARG=" + getShortcutLabel() + "_zhisto," + thislab + "_shift FUNC=(x-y)*(x-y) PERIODIC=NO");
+      89           8 :     readInputLine( thislab + ": SUM_GRID ARG=" + thislab + "_x2 PERIODIC=NO");
+      90             :   }
+      91           7 :   if( dir=="xy" ) {
+      92           2 :     readInputLine( getShortcutLabel() + ": COMBINE ARG=" + getShortcutLabel() + "_xgrad," + getShortcutLabel() + "_ygrad PERIODIC=NO");
+      93           6 :   } else if( dir=="xz" ) {
+      94           2 :     readInputLine( getShortcutLabel() + ": COMBINE ARG=" + getShortcutLabel() + "_xgrad," + getShortcutLabel() + "_zgrad PERIODIC=NO");
+      95           5 :   } else if( dir=="yz" ) {
+      96           2 :     readInputLine( getShortcutLabel() + ": COMBINE ARG=" + getShortcutLabel() + "_ygrad," + getShortcutLabel() + "_zgrad PERIODIC=NO");
+      97           4 :   } else if( dir=="xyz" ) {
+      98           2 :     readInputLine( getShortcutLabel() + ": COMBINE ARG=" + getShortcutLabel() + "_xgrad," + getShortcutLabel() + "_ygrad," + getShortcutLabel() + "_zgrad PERIODIC=NO");
+      99             :   }
+     100           7 : }
+     101             : 
+     102             : 
+     103             : 
+     104             : }
+     105             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/GridCoordinatesObject.cpp.func-sort-c.html b/coverage/gridtools/GridCoordinatesObject.cpp.func-sort-c.html new file mode 100644 index 000000000000..613ebf242fa6 --- /dev/null +++ b/coverage/gridtools/GridCoordinatesObject.cpp.func-sort-c.html @@ -0,0 +1,153 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/GridCoordinatesObject.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - GridCoordinatesObject.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:18820691.3 %
Date:2024-04-19 12:12:35Functions:192095.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD9gridtools21GridCoordinatesObject20putCoordinateAtValueERKjRKdRSt6vectorIdSaIdEE0
_ZN4PLMD9gridtools21GridCoordinatesObject5setupERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIbSaIbEERKjRKd331
_ZN4PLMD9gridtools21GridCoordinatesObject9setBoundsERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EESC_RKS2_IjSaIjEERS2_IdSaIdEE615
_ZNK4PLMD9gridtools21GridCoordinatesObject17getFibonacciIndexERKSt6vectorIdSaIdEE16510
_ZNK4PLMD9gridtools21GridCoordinatesObject8inboundsERKSt6vectorIdSaIdEE197426
_ZNK4PLMD9gridtools21GridCoordinatesObject12getNeighborsERKSt6vectorIdSaIdEERKS2_IjSaIjEERjRS8_231602
_ZNK4PLMD9gridtools21GridCoordinatesObject12getNeighborsERKSt6vectorIjSaIjEES6_RjRS4_245010
_ZNK4PLMD9gridtools21GridCoordinatesObject6getMaxB5cxx11Ev470843
_ZNK4PLMD9gridtools21GridCoordinatesObject6getMinB5cxx11Ev470843
_ZNK4PLMD9gridtools21GridCoordinatesObject7getNbinERKb483325
_ZNK4PLMD9gridtools21GridCoordinatesObject18getSplineNeighborsERKjRjRSt6vectorIjSaIjEE544167
_ZNK4PLMD9gridtools21GridCoordinatesObject8getIndexERKSt6vectorIdSaIdEE615967
_ZNK4PLMD9gridtools21GridCoordinatesObject10getIndicesERKSt6vectorIdSaIdEERS2_IjSaIjEE1175406
_ZNK4PLMD9gridtools21GridCoordinatesObject23getFibonacciCoordinatesERKjRSt6vectorIdSaIdEE4974037
_ZNK4PLMD9gridtools21GridCoordinatesObject22getFlatGridCoordinatesERKjRSt6vectorIjSaIjEERS4_IdSaIdEE39980732
_ZNK4PLMD9gridtools21GridCoordinatesObject23getGridPointCoordinatesERKjRSt6vectorIdSaIdEE40720264
_ZNK4PLMD9gridtools21GridCoordinatesObject23getGridPointCoordinatesERKjRSt6vectorIjSaIjEERS4_IdSaIdEE41484313
_ZNK4PLMD9gridtools21GridCoordinatesObject10getIndicesERKjRSt6vectorIjSaIjEE42760057
_ZNK4PLMD9gridtools21GridCoordinatesObject8getIndexERKSt6vectorIjSaIjEE42783311
_ZNK4PLMD9gridtools21GridCoordinatesObject21convertIndexToIndicesERKjRKSt6vectorIjSaIjEERS6_94917677
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/GridCoordinatesObject.cpp.func.html b/coverage/gridtools/GridCoordinatesObject.cpp.func.html new file mode 100644 index 000000000000..cdf1f4d4f493 --- /dev/null +++ b/coverage/gridtools/GridCoordinatesObject.cpp.func.html @@ -0,0 +1,153 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/GridCoordinatesObject.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - GridCoordinatesObject.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:18820691.3 %
Date:2024-04-19 12:12:35Functions:192095.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools21GridCoordinatesObject5setupERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIbSaIbEERKjRKd331
_ZN4PLMD9gridtools21GridCoordinatesObject9setBoundsERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EESC_RKS2_IjSaIjEERS2_IdSaIdEE615
_ZNK4PLMD9gridtools21GridCoordinatesObject10getIndicesERKSt6vectorIdSaIdEERS2_IjSaIjEE1175406
_ZNK4PLMD9gridtools21GridCoordinatesObject10getIndicesERKjRSt6vectorIjSaIjEE42760057
_ZNK4PLMD9gridtools21GridCoordinatesObject12getNeighborsERKSt6vectorIdSaIdEERKS2_IjSaIjEERjRS8_231602
_ZNK4PLMD9gridtools21GridCoordinatesObject12getNeighborsERKSt6vectorIjSaIjEES6_RjRS4_245010
_ZNK4PLMD9gridtools21GridCoordinatesObject17getFibonacciIndexERKSt6vectorIdSaIdEE16510
_ZNK4PLMD9gridtools21GridCoordinatesObject18getSplineNeighborsERKjRjRSt6vectorIjSaIjEE544167
_ZNK4PLMD9gridtools21GridCoordinatesObject20putCoordinateAtValueERKjRKdRSt6vectorIdSaIdEE0
_ZNK4PLMD9gridtools21GridCoordinatesObject21convertIndexToIndicesERKjRKSt6vectorIjSaIjEERS6_94917677
_ZNK4PLMD9gridtools21GridCoordinatesObject22getFlatGridCoordinatesERKjRSt6vectorIjSaIjEERS4_IdSaIdEE39980732
_ZNK4PLMD9gridtools21GridCoordinatesObject23getFibonacciCoordinatesERKjRSt6vectorIdSaIdEE4974037
_ZNK4PLMD9gridtools21GridCoordinatesObject23getGridPointCoordinatesERKjRSt6vectorIdSaIdEE40720264
_ZNK4PLMD9gridtools21GridCoordinatesObject23getGridPointCoordinatesERKjRSt6vectorIjSaIjEERS4_IdSaIdEE41484313
_ZNK4PLMD9gridtools21GridCoordinatesObject6getMaxB5cxx11Ev470843
_ZNK4PLMD9gridtools21GridCoordinatesObject6getMinB5cxx11Ev470843
_ZNK4PLMD9gridtools21GridCoordinatesObject7getNbinERKb483325
_ZNK4PLMD9gridtools21GridCoordinatesObject8getIndexERKSt6vectorIdSaIdEE615967
_ZNK4PLMD9gridtools21GridCoordinatesObject8getIndexERKSt6vectorIjSaIjEE42783311
_ZNK4PLMD9gridtools21GridCoordinatesObject8inboundsERKSt6vectorIdSaIdEE197426
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/GridCoordinatesObject.cpp.gcov.html b/coverage/gridtools/GridCoordinatesObject.cpp.gcov.html new file mode 100644 index 000000000000..924f49ce2d6c --- /dev/null +++ b/coverage/gridtools/GridCoordinatesObject.cpp.gcov.html @@ -0,0 +1,414 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/GridCoordinatesObject.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - GridCoordinatesObject.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:18820691.3 %
Date:2024-04-19 12:12:35Functions:192095.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 "GridCoordinatesObject.h"
+      23             : #include "tools/Random.h"
+      24             : #include "tools/Matrix.h"
+      25             : 
+      26             : namespace PLMD {
+      27             : namespace gridtools {
+      28             : 
+      29         331 : void GridCoordinatesObject::setup( const std::string& geom, const std::vector<bool>& ipbc,
+      30             :                                    const unsigned& np, const double& fib_cutoff ) {
+      31         331 :   if( geom=="flat" ) { gtype=flat; dimension = ipbc.size(); }
+      32          17 :   else if( geom=="fibonacci" ) { gtype=fibonacci; dimension = 3; }
+      33           0 :   else plumed_merror( geom + " is invalid geometry type");
+      34             : 
+      35         331 :   if( gtype==flat ) {
+      36         664 :     bounds_set=false; npoints=0; pbc.resize( ipbc.size() ); for(unsigned i=0; i<ipbc.size(); ++i) pbc[i]=ipbc[i];
+      37          17 :   } else if( gtype==fibonacci ) {
+      38          17 :     bounds_set=true; root5 = sqrt(5);
+      39          17 :     npoints = np; golden = ( 1 + sqrt(5) ) / 2.0; igolden = golden - 1;
+      40          17 :     fib_increment = 2*pi*igolden; log_golden2 = std::log( golden*golden );
+      41          17 :     fib_offset = 2 / static_cast<double>( npoints );
+      42          17 :     fib_shift = fib_offset/2 - 1;
+      43             : 
+      44          17 :     std::vector<double> icoord( dimension ), jcoord( dimension );
+      45             :     // Find minimum distance between each pair of points
+      46          17 :     std::vector<unsigned> tindices( dimension ); std::vector<double> mindists( npoints );
+      47        4849 :     for(unsigned i=0; i<npoints; ++i) {
+      48        4832 :       getFibonacciCoordinates( i, icoord ); mindists[i] = 0;
+      49     1707040 :       for(unsigned j=0; j<npoints; ++j) {
+      50     1702208 :         if( i==j ) continue ; // Points are not neighbors to themselves
+      51     1697376 :         getFibonacciCoordinates( j, jcoord );
+      52             :         // Calculate the dot product
+      53     6789504 :         double dot=0; for(unsigned k=0; k<dimension; ++k) dot += icoord[k]*jcoord[k];
+      54     1697376 :         if( dot>mindists[i] ) mindists[i]=dot;
+      55             :       }
+      56             :     }
+      57             :     // And now take minimum of dot products
+      58          17 :     double min=mindists[0];
+      59        4832 :     for(unsigned i=1; i<npoints; ++i) {
+      60        4815 :       if( mindists[i]<min ) min=mindists[i];
+      61             :     }
+      62             :     double final_cutoff;
+      63          17 :     if( fib_cutoff<-1 ) final_cutoff=-1;
+      64          15 :     else final_cutoff = cos( acos( fib_cutoff ) + acos( min ) );
+      65             : 
+      66             :     // And now construct the neighbor list
+      67          17 :     fib_nlist.resize( npoints );
+      68        4849 :     for(unsigned i=0; i<npoints; ++i) {
+      69        4832 :       getFibonacciCoordinates( i, icoord );
+      70     1707040 :       for(unsigned j=0; j<npoints; ++j) {
+      71     1702208 :         if( i==j ) continue ; // Points are not neighbors to themselves
+      72     1697376 :         getFibonacciCoordinates( j, jcoord );
+      73             :         // Calculate the dot product
+      74     6789504 :         double dot=0; for(unsigned k=0; k<dimension; ++k) dot += icoord[k]*jcoord[k];
+      75     1697376 :         if( dot>final_cutoff ) { fib_nlist[i].push_back(j); }
+      76             :       }
+      77             :     }
+      78           0 :   } else plumed_error();
+      79         331 : }
+      80             : 
+      81         615 : void GridCoordinatesObject::setBounds( const std::vector<std::string>& smin, const std::vector<std::string>& smax,
+      82             :                                        const std::vector<unsigned>& binsin, std::vector<double>& spacing ) {
+      83             :   plumed_dbg_assert( smin.size()==dimension && smax.size()==dimension );
+      84         615 :   plumed_assert( gtype==flat && (spacing.size()==dimension || binsin.size()==dimension) );
+      85         615 :   str_min.resize( dimension ); str_max.resize( dimension ); nbin.resize( dimension );
+      86         615 :   min.resize( dimension ); max.resize( dimension ); dx.resize( dimension ); stride.resize( dimension );
+      87             : 
+      88        1160 :   npoints=1; bounds_set=(smin[0]!="auto" && smax[0]!="auto");
+      89         615 :   if( bounds_set ) {
+      90         595 :     for(unsigned i=1; i<dimension; ++i) {
+      91         100 :       if( smin[i]=="auto" || smax[i]=="auto" ) { bounds_set=false; break; }
+      92             :     }
+      93             :   }
+      94        1292 :   for(unsigned i=0; i<dimension; ++i) {
+      95         677 :     str_min[i]=smin[i]; str_max[i]=smax[i];
+      96         677 :     if( bounds_set ) {
+      97         595 :       Tools::convert( str_min[i], min[i] );
+      98         595 :       Tools::convert( str_max[i], max[i] );
+      99             :     }
+     100         677 :     if( spacing.size()==dimension && binsin.size()==dimension ) {
+     101         290 :       if( spacing[i]==0 ) nbin[i] = binsin[i];
+     102         273 :       else if( bounds_set ) {
+     103         273 :         double range = max[i] - min[i]; nbin[i] = std::round( range / spacing[i]); dx[i]=spacing[i];
+     104             :         // This check ensures that nbins is set correctly if spacing is set the same as the number of bins
+     105         273 :         if( nbin[i]!=binsin[i] ) plumed_merror("mismatch between input spacing and input number of bins");
+     106             :       }
+     107         387 :     } else if( binsin.size()==dimension ) {
+     108         387 :       nbin[i]=binsin[i]; dx[i] = ( max[i] - min[i] ) / static_cast<double>( nbin[i] );
+     109           0 :     } else if( spacing.size()==dimension && bounds_set ) {
+     110           0 :       nbin[i] = std::floor(( max[i] - min[i] ) / spacing[i]) + 1; dx[i]=spacing[i];
+     111           0 :     } else if( bounds_set ) plumed_error();
+     112         677 :     if( !pbc[i] ) { max[i] +=dx[i]; nbin[i]+=1; }
+     113         677 :     stride[i]=npoints;
+     114         677 :     npoints*=nbin[i];
+     115             :   }
+     116         615 :   if( spacing.size()!=dimension && bounds_set ) {
+     117         614 :     spacing.resize(dimension); for(unsigned i=0; i<dimension; ++i) spacing[i]=dx[i];
+     118             :   }
+     119         615 : }
+     120             : 
+     121    42783311 : unsigned GridCoordinatesObject::getIndex( const std::vector<unsigned>& indices ) const {
+     122             :   plumed_dbg_assert( gtype==flat && indices.size()==dimension );
+     123             :   // indices are flattended using a column-major order
+     124    42783311 :   unsigned index=indices[dimension-1];
+     125   122880687 :   for(unsigned i=dimension-1; i>0; --i) {
+     126    80097376 :     index=index*nbin[i-1]+indices[i-1];
+     127             :   }
+     128    42783311 :   return index;
+     129             : }
+     130             : 
+     131      197426 : bool GridCoordinatesObject::inbounds( const std::vector<double>& point ) const {
+     132      197426 :   if( gtype==fibonacci ) return true;
+     133             :   plumed_dbg_assert( bounds_set && point.size()==dimension );
+     134      461467 :   for(unsigned i=0; i<dimension; ++i) {
+     135      296963 :     if( pbc[i] ) continue;
+     136       60839 :     if( point[i]<min[i] || point[i]>(max[i]-dx[i]) ) return false;
+     137             :   }
+     138             :   return true;
+     139             : }
+     140             : 
+     141     1175406 : void GridCoordinatesObject::getIndices( const std::vector<double>& point, std::vector<unsigned>& indices ) const {
+     142             :   plumed_dbg_assert( gtype==flat && bounds_set && point.size()==dimension && indices.size()==dimension );
+     143     3445432 :   for(unsigned i=0; i<dimension; ++i) {
+     144     2270026 :     indices[i]=std::floor( (point[i] - min[i])/dx[i] );
+     145     2270026 :     if( pbc[i] ) indices[i]=indices[i]%nbin[i];
+     146     2179718 :     else if( indices[i]>nbin[i] ) plumed_merror("point is outside grid range");
+     147             :   }
+     148     1175406 : }
+     149             : 
+     150      615967 : unsigned GridCoordinatesObject::getIndex( const std::vector<double>& point ) const {
+     151             :   plumed_dbg_assert( bounds_set && point.size()==dimension );
+     152      615967 :   if( gtype==flat ) {
+     153      613867 :     std::vector<unsigned> indices(dimension); getIndices( point, indices );
+     154      613867 :     return getIndex( indices );
+     155        2100 :   } else if( gtype==fibonacci ) {
+     156        2100 :     return getFibonacciIndex( point );
+     157             :   } else {
+     158           0 :     plumed_error();
+     159             :   }
+     160             : }
+     161             : 
+     162       16510 : unsigned GridCoordinatesObject::getFibonacciIndex( const std::vector<double>& p ) const {
+     163             :   plumed_dbg_assert( gtype==fibonacci );
+     164             :   // Convert input point to coordinates on cylinder
+     165       16510 :   int k=2; double phi = atan2( p[2], p[0] ), sinthet2 = 1 - p[1]*p[1];
+     166             :   // Calculate power to raise golden ratio
+     167       16510 :   if( sinthet2<epsilon ) { k = 2; }
+     168             :   else {
+     169       16510 :     k = std::floor( std::log( npoints*pi*root5*sinthet2 ) / log_golden2 );
+     170             :     if( k<2 ) k = 2;
+     171             :   }
+     172       16510 :   double Fk = pow( golden, k ) / root5, F0 = std::round(Fk), F1 = std::round(Fk*golden);
+     173       16510 :   Matrix<double> B(2,2), invB(2,2); std::vector<double> thisp(3);
+     174       16510 :   B(0,0) = 2*pi*((F0+1)*igolden - std::floor((F0+1)*igolden)) - fib_increment;
+     175       16510 :   B(0,1) = 2*pi*((F1+1)*igolden - std::floor((F1+1)*igolden)) - fib_increment;
+     176       16510 :   B(1,0) = -2*F0/npoints; B(1,1) = -2*F1/npoints; Invert( B, invB );
+     177       16510 :   std::vector<double> vv(2), rc(2); vv[0]=-phi; vv[1] = p[1] - fib_shift;
+     178       16510 :   mult( invB, vv, rc ); std::vector<int> c(2); c[0]=std::floor(rc[0]); c[1]=std::floor(rc[1]);
+     179             :   unsigned outind=0; double mindist = 10000000.;
+     180       82550 :   for(int s=0; s<4; ++s) {
+     181       66040 :     double ttt, costheta = B(1,0)*( c[0] + s%2 ) + B(1,1)*( c[1] + s/2 ) + fib_shift;
+     182       66040 :     if( costheta>1 ) ttt=1; else if( costheta<-1 ) ttt=-1; else ttt=costheta;
+     183       66040 :     costheta = 2*ttt - costheta;
+     184       66040 :     unsigned i = std::floor( 0.5*npoints*(1+costheta) ); getFibonacciCoordinates( i, thisp );
+     185      264160 :     double dist=0; for(unsigned j=0; j<3; ++j) { double tmp=thisp[j]-p[j]; dist += tmp*tmp; }
+     186       66040 :     if( dist<mindist ) { outind = i; mindist = dist; }
+     187             :   }
+     188       16510 :   return outind;
+     189             : }
+     190             : 
+     191    94917677 : void GridCoordinatesObject::convertIndexToIndices( const unsigned& index, const std::vector<unsigned>& nnbin, std::vector<unsigned>& indices ) const {
+     192    94917677 :   plumed_dbg_assert( gtype==flat ); unsigned kk=index; indices[0]=index%nnbin[0];
+     193   183492225 :   for(unsigned i=1; i<dimension-1; ++i) {
+     194    88574548 :     kk=(kk-indices[i-1])/nnbin[i-1];
+     195    88574548 :     indices[i]=kk%nnbin[i];
+     196             :   }
+     197    94917677 :   if(dimension>=2) { // I think this is wrong
+     198    92728227 :     indices[dimension-1]=(kk-indices[dimension-2])/nnbin[dimension-2];
+     199             :   }
+     200    94917677 : }
+     201             : 
+     202    42760057 : void GridCoordinatesObject::getIndices( const unsigned& index, std::vector<unsigned>& indices ) const {
+     203    42760057 :   plumed_dbg_assert( gtype==flat ); convertIndexToIndices( index, nbin, indices );
+     204    42760057 : }
+     205             : 
+     206    40720264 : void GridCoordinatesObject::getGridPointCoordinates( const unsigned& ipoint, std::vector<double>& x ) const {
+     207    40720264 :   std::vector<unsigned> tindices( dimension ); getGridPointCoordinates( ipoint, tindices, x );
+     208    40720264 : }
+     209             : 
+     210    41484313 : void GridCoordinatesObject::getGridPointCoordinates( const unsigned& ipoint, std::vector<unsigned>& tindices, std::vector<double>& x ) const {
+     211             :   plumed_dbg_assert( bounds_set && x.size()==dimension && tindices.size()==dimension && ipoint<npoints );
+     212    41484313 :   if( gtype==flat ) {
+     213    39980732 :     getFlatGridCoordinates( ipoint, tindices, x );
+     214     1503581 :   } else if( gtype==fibonacci ) {
+     215     1503581 :     getFibonacciCoordinates( ipoint, x );
+     216             :   } else {
+     217           0 :     plumed_error();
+     218             :   }
+     219    41484313 : }
+     220             : 
+     221           0 : void GridCoordinatesObject::putCoordinateAtValue( const unsigned& ind, const double& val, std::vector<double>& coords ) const {
+     222           0 :   std::vector<double> point( dimension ); getGridPointCoordinates( ind, point );
+     223           0 :   if( gtype==flat ) {
+     224           0 :     if( coords.size()!=(dimension+1) ) coords.resize( (dimension+1) );
+     225           0 :     for(unsigned i=0; i<dimension; ++i) coords[i]=point[i]; coords[point.size()]=val;
+     226           0 :   } else if( gtype==fibonacci ) {
+     227           0 :     if( coords.size()!=3 ) coords.resize(3);
+     228           0 :     for(unsigned i=0; i<3; ++i) coords[i] = val*point[i];
+     229             :   } else {
+     230           0 :     plumed_error();
+     231             :   }
+     232           0 : }
+     233             : 
+     234    39980732 : void GridCoordinatesObject::getFlatGridCoordinates( const unsigned& ipoint, std::vector<unsigned>& tindices, std::vector<double>& x ) const {
+     235    39980732 :   plumed_dbg_assert( gtype==flat ); getIndices( ipoint, tindices );
+     236   156503342 :   for(unsigned i=0; i<dimension; ++i) x[i] = min[i] + dx[i]*tindices[i];
+     237    39980732 : }
+     238             : 
+     239     4974037 : void GridCoordinatesObject::getFibonacciCoordinates( const unsigned& ipoint, std::vector<double>& x ) const {
+     240             :   plumed_dbg_assert( gtype==fibonacci );
+     241     4974037 :   x[1] = (ipoint*fib_offset) + fib_shift; double r = sqrt( 1 - x[1]*x[1] );
+     242     4974037 :   double phi = ipoint*fib_increment; x[0] = r*cos(phi); x[2] = r*sin(phi);
+     243    19896148 :   double norm=0; for(unsigned j=0; j<3; ++j) norm+=x[j]*x[j];
+     244    19896148 :   norm = sqrt(norm); for(unsigned j=0; j<3; ++j) x[j] = x[j] / norm;
+     245     4974037 : }
+     246             : 
+     247      544167 : void GridCoordinatesObject::getSplineNeighbors( const unsigned& mybox, unsigned& nneighbors, std::vector<unsigned>& mysneigh ) const {
+     248      544167 :   plumed_dbg_assert( gtype==flat ); mysneigh.resize( static_cast<unsigned>(pow(2.,dimension)) );
+     249             : 
+     250      544167 :   unsigned inind; nneighbors = 0;
+     251      544167 :   std::vector<unsigned> tmp_indices( dimension );
+     252      544167 :   std::vector<unsigned> my_indices( dimension );
+     253      544167 :   getIndices( mybox, my_indices );
+     254     2754079 :   for(unsigned i=0; i<mysneigh.size(); ++i) {
+     255             :     unsigned tmp=i; inind=0;
+     256     6716896 :     for(unsigned j=0; j<dimension; ++j) {
+     257     4506984 :       unsigned i0=tmp%2+my_indices[j]; tmp/=2;
+     258     4506984 :       if(!pbc[j] && i0==nbin[j]) continue;
+     259     4466184 :       if( pbc[j] && i0==nbin[j]) i0=0;
+     260     4466184 :       tmp_indices[inind++]=i0;
+     261             :     }
+     262     2209912 :     if( inind==dimension ) mysneigh[nneighbors++]=getIndex( tmp_indices );
+     263             :   }
+     264      544167 : }
+     265             : 
+     266      470843 : std::vector<std::string> GridCoordinatesObject::getMin() const {
+     267      470843 :   plumed_dbg_assert( gtype==flat ); return str_min;
+     268             : }
+     269             : 
+     270      470843 : std::vector<std::string> GridCoordinatesObject::getMax() const {
+     271      470843 :   plumed_dbg_assert( gtype==flat ); return str_max;
+     272             : }
+     273             : 
+     274      483325 : std::vector<unsigned> GridCoordinatesObject::getNbin( const bool& shape ) const {
+     275             :   plumed_dbg_assert( gtype==flat && nbin.size()==dimension );
+     276      483325 :   std::vector<unsigned> ngrid( dimension );
+     277     1591454 :   for(unsigned i=0; i<dimension; ++i) {
+     278     1108129 :     if( !pbc[i] && !shape ) ngrid[i]=nbin[i] - 1;
+     279      534047 :     else ngrid[i]=nbin[i];
+     280             :   }
+     281      483325 :   return ngrid;
+     282             : }
+     283             : 
+     284      231602 : void GridCoordinatesObject::getNeighbors( const std::vector<double>& pp, const std::vector<unsigned>& nneigh,
+     285             :     unsigned& num_neighbors, std::vector<unsigned>& neighbors ) const {
+     286             :   plumed_dbg_assert( bounds_set );
+     287             : 
+     288      231602 :   if( gtype == flat ) {
+     289             :     plumed_dbg_assert( nneigh.size()==dimension );
+     290      217192 :     std::vector<unsigned> indices( dimension );
+     291      490941 :     for(unsigned i=0; i<dimension; ++i) indices[i] = std::floor( (pp[i]-min[i])/dx[i] );
+     292      217192 :     getNeighbors( indices, nneigh, num_neighbors, neighbors );
+     293       14410 :   } else if( gtype == fibonacci ) {
+     294       14410 :     unsigned find = getFibonacciIndex( pp );
+     295       14410 :     num_neighbors = 1 + fib_nlist[find].size();
+     296       14410 :     if( neighbors.size()<num_neighbors ) neighbors.resize( num_neighbors );
+     297     1500997 :     neighbors[0]=find; for(unsigned i=0; i<fib_nlist[find].size(); ++i) neighbors[1+i] = fib_nlist[find][i];
+     298             :   } else {
+     299           0 :     plumed_error();
+     300             :   }
+     301      231602 : }
+     302             : 
+     303      245010 : void GridCoordinatesObject::getNeighbors( const std::vector<unsigned>& indices, const std::vector<unsigned>& nneigh,
+     304             :     unsigned& num_neighbors, std::vector<unsigned>& neighbors ) const {
+     305             :   plumed_dbg_assert( gtype==flat && bounds_set && nneigh.size()==dimension );
+     306             : 
+     307      245010 :   unsigned num_neigh=1; std::vector<unsigned> small_bin( dimension );
+     308      602213 :   for(unsigned i=0; i<dimension; ++i) {
+     309      357203 :     small_bin[i]=(2*nneigh[i]+1);
+     310      357203 :     if( pbc[i] && small_bin[i]>nbin[i] ) small_bin[i]=nbin[i];
+     311      357203 :     num_neigh *=small_bin[i];
+     312             :   }
+     313      245010 :   if( neighbors.size()!=num_neigh ) neighbors.resize( num_neigh );
+     314             : 
+     315      245010 :   num_neighbors=0;
+     316      245010 :   std::vector<unsigned> s_indices(dimension), t_indices(dimension);
+     317    52402630 :   for(unsigned index=0; index<num_neigh; ++index) {
+     318             :     bool found=true;
+     319    52157620 :     convertIndexToIndices( index, small_bin, s_indices );
+     320   206161849 :     for(unsigned i=0; i<dimension; ++i) {
+     321   154004229 :       int i0=s_indices[i]-nneigh[i]+indices[i];
+     322   154004229 :       if(!pbc[i] && i0<0)        found=false;
+     323   154004229 :       if(!pbc[i] && i0>=nbin[i]) found=false;
+     324   154004229 :       if( pbc[i] && i0<0)        i0=nbin[i]-(-i0)%nbin[i];
+     325   154004229 :       if( pbc[i] && i0>=nbin[i]) i0%=nbin[i];
+     326   154004229 :       t_indices[i]=static_cast<unsigned>(i0);
+     327             :     }
+     328    52157620 :     if( found ) {
+     329    39399065 :       neighbors[num_neighbors]=getIndex( t_indices );
+     330    39399065 :       num_neighbors++;
+     331             :     }
+     332             :   }
+     333      245010 : }
+     334             : 
+     335             : }
+     336             : }
+     337             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/GridCoordinatesObject.h.func-sort-c.html b/coverage/gridtools/GridCoordinatesObject.h.func-sort-c.html new file mode 100644 index 000000000000..d7a0e868740b --- /dev/null +++ b/coverage/gridtools/GridCoordinatesObject.h.func-sort-c.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/GridCoordinatesObject.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - GridCoordinatesObject.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:81080.0 %
Date:2024-04-19 12:12:35Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD9gridtools21GridCoordinatesObject11getGridTypeB5cxx11Ev214506
_ZNK4PLMD9gridtools21GridCoordinatesObject14getGridSpacingEv5000598
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/GridCoordinatesObject.h.func.html b/coverage/gridtools/GridCoordinatesObject.h.func.html new file mode 100644 index 000000000000..35b9bd71c287 --- /dev/null +++ b/coverage/gridtools/GridCoordinatesObject.h.func.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/GridCoordinatesObject.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - GridCoordinatesObject.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:81080.0 %
Date:2024-04-19 12:12:35Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD9gridtools21GridCoordinatesObject11getGridTypeB5cxx11Ev214506
_ZNK4PLMD9gridtools21GridCoordinatesObject14getGridSpacingEv5000598
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/GridCoordinatesObject.h.gcov.html b/coverage/gridtools/GridCoordinatesObject.h.gcov.html new file mode 100644 index 000000000000..20b9eb902394 --- /dev/null +++ b/coverage/gridtools/GridCoordinatesObject.h.gcov.html @@ -0,0 +1,244 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/GridCoordinatesObject.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - GridCoordinatesObject.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:81080.0 %
Date:2024-04-19 12:12:35Functions: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_gridtools_GridCoordinatesObject_h
+      23             : #define __PLUMED_gridtools_GridCoordinatesObject_h
+      24             : 
+      25             : #include <string>
+      26             : #include <cstring>
+      27             : #include <vector>
+      28             : #include "tools/Exception.h"
+      29             : #include "tools/Tools.h"
+      30             : 
+      31             : namespace PLMD {
+      32             : namespace gridtools {
+      33             : 
+      34             : class GridCoordinatesObject {
+      35             : private:
+      36             : /// Have the bounds been setup on the grid
+      37             :   bool bounds_set;
+      38             : /// The way that grid points are constructed
+      39             :   enum {flat,fibonacci} gtype;
+      40             : /// The number of points in the grid
+      41             :   unsigned npoints;
+      42             : /// Stuff for fibonacci grids
+      43             :   double root5, golden, igolden, log_golden2;
+      44             : /// Fib increment here is equal to 2*pi*(INVERSE GOLDEN RATIO)
+      45             :   double fib_offset, fib_increment, fib_shift;
+      46             :   std::vector<std::vector<unsigned> > fib_nlist;
+      47             : /// The minimum and maximum of the grid stored as doubles
+      48             :   std::vector<double> min, max;
+      49             : /// The numerical distance between adjacent grid points
+      50             :   std::vector<unsigned> stride;
+      51             : /// The number of bins in each grid direction
+      52             :   std::vector<unsigned> nbin;
+      53             : /// Is this direction periodic
+      54             :   std::vector<bool> pbc;
+      55             : /// The minimum and maximum in the grid stored as strings
+      56             :   std::vector<std::string> str_min, str_max;
+      57             : /// The spacing between grid points
+      58             :   std::vector<double> dx;
+      59             : /// The dimensionality of the grid
+      60             :   unsigned dimension;
+      61             : /// Get the index of the closest point on the fibonacci sphere
+      62             :   unsigned getFibonacciIndex( const std::vector<double>& p ) const ;
+      63             : /// Get the flat grid coordinates
+      64             :   void getFlatGridCoordinates( const unsigned& ipoint, std::vector<unsigned>& tindices, std::vector<double>& x ) const ;
+      65             : /// Get the coordinates on the Fibonacci grid
+      66             :   void getFibonacciCoordinates( const unsigned& ipoint, std::vector<double>& x ) const ;
+      67             : public:
+      68             : /// Setup the grid
+      69             :   void setup( const std::string& geom, const std::vector<bool>& ipbc, const unsigned& np, const double& fib_cutoff );
+      70             : /// Set the minimum and maximum of the grid
+      71             :   void setBounds( const std::vector<std::string>& smin, const std::vector<std::string>& smax, const std::vector<unsigned>& nbins, std::vector<double>& spacing );
+      72             : /// Convert an index into indices
+      73             :   void convertIndexToIndices( const unsigned& index, const std::vector<unsigned>& nnbin, std::vector<unsigned>& indices ) const ;
+      74             : /// Check if a point is within the grid boundaries
+      75             :   bool inbounds( const std::vector<double>& point ) const ;
+      76             : /// Convert a point in space the the correspoinding grid point
+      77             :   unsigned getIndex( const std::vector<double>& p ) const ;
+      78             : ///  Flatten the grid and get the grid index for a point
+      79             :   unsigned getIndex( const std::vector<unsigned>& indices ) const ;
+      80             : /// Get the indices fof a point
+      81             :   void getIndices( const unsigned& index, std::vector<unsigned>& indices ) const ;
+      82             : /// Get the indices of a particular point
+      83             :   void getIndices( const std::vector<double>& point, std::vector<unsigned>& indices ) const ;
+      84             : /// Get the number of points in the grid
+      85             :   unsigned getNumberOfPoints() const;
+      86             : /// Get the coordinates for a point in the grid
+      87             :   void getGridPointCoordinates( const unsigned&, std::vector<double>& ) const ;
+      88             :   void getGridPointCoordinates( const unsigned&, std::vector<unsigned>&, std::vector<double>& ) const ;
+      89             : /// Create a coordinate that has this value of the grid
+      90             :   void putCoordinateAtValue( const unsigned&, const double&, std::vector<double>& ) const ;
+      91             : /// Get the dimensionality of the function
+      92             :   unsigned getDimension() const ;
+      93             : /// Is the grid periodic in the ith direction
+      94             :   bool isPeriodic( const unsigned& i ) const ;
+      95             : /// Get the number of grid points for each dimension
+      96             :   std::vector<unsigned> getNbin( const bool& shape ) const ;
+      97             : /// Get the vector containing the minimum value of the grid in each dimension
+      98             :   std::vector<std::string> getMin() const ;
+      99             : /// Get the vector containing the maximum value of the grid in each dimension
+     100             :   std::vector<std::string> getMax() const ;
+     101             : /// Return the volume of one of the grid cells
+     102             :   double getCellVolume() const ;
+     103             : /// Get the set of points neighouring a particular location in space
+     104             :   void getNeighbors( const std::vector<double>& pp, const std::vector<unsigned>& nneigh,
+     105             :                      unsigned& num_neighbours, std::vector<unsigned>& neighbors ) const ;
+     106             : /// Get the neighbors for a set of indices of a point
+     107             :   void getNeighbors( const std::vector<unsigned>& indices, const std::vector<unsigned>& nneigh,
+     108             :                      unsigned& num_neighbors, std::vector<unsigned>& neighbors ) const ;
+     109             : /// Get the points neighboring a particular spline point
+     110             :   void getSplineNeighbors( const unsigned& mybox, unsigned& nneighbors, std::vector<unsigned>& mysneigh ) const ;
+     111             : /// Get the spacing between grid points
+     112             :   const std::vector<double>& getGridSpacing() const ;
+     113             : /// Get the stride (the distance between the grid points of an index)
+     114             :   const std::vector<unsigned>& getStride() const ;
+     115             : /// Get the type of the grid
+     116             :   std::string getGridType() const ;
+     117             : };
+     118             : 
+     119             : inline
+     120             : unsigned GridCoordinatesObject::getNumberOfPoints() const {
+     121      544597 :   return npoints;
+     122             : }
+     123             : 
+     124             : inline
+     125     5000598 : const std::vector<double>& GridCoordinatesObject::getGridSpacing() const {
+     126     5000598 :   if( gtype==flat ) return dx;
+     127           0 :   plumed_merror("dont understand what spacing means for spherical grids");
+     128             :   return dx;
+     129             : }
+     130             : 
+     131             : inline
+     132             : double GridCoordinatesObject::getCellVolume() const {
+     133             :   if( gtype==flat ) {
+     134             :     double myvol=1.0; for(unsigned i=0; i<dimension; ++i) myvol *= dx[i];
+     135             :     return myvol;
+     136             :   } else {
+     137             :     return 4*pi / static_cast<double>( getNumberOfPoints() );
+     138             :   }
+     139             : }
+     140             : 
+     141             : inline
+     142             : unsigned GridCoordinatesObject::getDimension() const {
+     143     2506939 :   return dimension;
+     144             : }
+     145             : 
+     146             : inline
+     147             : bool GridCoordinatesObject::isPeriodic( const unsigned& i ) const {
+     148             :   plumed_dbg_assert( gtype==flat );
+     149       16844 :   return pbc[i];
+     150             : }
+     151             : 
+     152             : inline
+     153             : const std::vector<unsigned>& GridCoordinatesObject::getStride() const {
+     154             :   plumed_dbg_assert( gtype==flat );
+     155             :   return stride;
+     156             : }
+     157             : 
+     158             : inline
+     159      214506 : std::string GridCoordinatesObject::getGridType() const {
+     160      214506 :   if( gtype==flat ) return "flat";
+     161         656 :   else if( gtype==fibonacci ) return "fibonacci";
+     162           0 :   return "";
+     163             : }
+     164             : 
+     165             : }
+     166             : }
+     167             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/GridSearch.h.func-sort-c.html b/coverage/gridtools/GridSearch.h.func-sort-c.html new file mode 100644 index 000000000000..6e802c4de675 --- /dev/null +++ b/coverage/gridtools/GridSearch.h.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + 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-04-19 12:12:35Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools10GridSearchINS_6dimred13ArrangePointsEEC2ERKSt6vectorIdSaIdEES9_RKS5_IjSaIjEESD_PS3_1
_ZN4PLMD9gridtools10GridSearchINS_6dimred13ArrangePointsEE8minimiseERSt6vectorIdSaIdEEMS3_FdRKS7_S8_E200
_ZN4PLMD9gridtools10GridSearchINS_6dimred13ArrangePointsEE14setGridElementERKjRKdRKSt6vectorIdSaIdEE24200
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/GridSearch.h.func.html b/coverage/gridtools/GridSearch.h.func.html new file mode 100644 index 000000000000..ba3a22d288de --- /dev/null +++ b/coverage/gridtools/GridSearch.h.func.html @@ -0,0 +1,85 @@ + + + + + + + + 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-04-19 12:12:35Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools10GridSearchINS_6dimred13ArrangePointsEE14setGridElementERKjRKdRKSt6vectorIdSaIdEE24200
_ZN4PLMD9gridtools10GridSearchINS_6dimred13ArrangePointsEE8minimiseERSt6vectorIdSaIdEEMS3_FdRKS7_S8_E200
_ZN4PLMD9gridtools10GridSearchINS_6dimred13ArrangePointsEEC2ERKSt6vectorIdSaIdEES9_RKS5_IjSaIjEESD_PS3_1
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/GridSearch.h.gcov.html b/coverage/gridtools/GridSearch.h.gcov.html new file mode 100644 index 000000000000..6ec92ef93c6b --- /dev/null +++ b/coverage/gridtools/GridSearch.h.gcov.html @@ -0,0 +1,194 @@ + + + + + + + + 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-04-19 12:12:35Functions:33100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-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             : #ifndef __PLUMED_gridtools_GridSearch_h
+      23             : #define __PLUMED_gridtools_GridSearch_h
+      24             : 
+      25             : #include "core/Value.h"
+      26             : #include "tools/MinimiseBase.h"
+      27             : #include "GridCoordinatesObject.h"
+      28             : #include "Interpolator.h"
+      29             : #include <iostream>
+      30             : #include <memory>
+      31             : 
+      32             : namespace PLMD {
+      33             : namespace gridtools {
+      34             : 
+      35             : template <class FCLASS>
+      36             : class GridSearch {
+      37             : private:
+      38             : /// This is the pointer to the member function in the energy
+      39             : /// calculating class that calculates the energy
+      40             :   typedef double(FCLASS::*engf_pointer)( const std::vector<double>& p, std::vector<double>& der );
+      41             :   FCLASS* myclass_func;
+      42             :   bool using_fgrid;
+      43             :   std::unique_ptr<Value> value;
+      44             :   std::unique_ptr<Interpolator> myinterp;
+      45             :   GridCoordinatesObject mygrid;
+      46             :   GridCoordinatesObject myfgrid;
+      47             : public:
+      48           1 :   GridSearch( const std::vector<double>& mmin, const std::vector<double>& mmax, const std::vector<unsigned>& ng, const std::vector<unsigned>& nfg, FCLASS* funcc ) :
+      49           1 :     myclass_func( funcc ),
+      50           1 :     using_fgrid(false)
+      51             :   {
+      52             :     // Setup the min and max values for the grid
+      53           1 :     std::vector<std::string> gmin( nfg.size() ), gmax( nfg.size() );
+      54           1 :     std::vector<bool> pbc( nfg.size(), false ); std::vector<double> dummy_spacing;
+      55           3 :     for(unsigned i=0; i<nfg.size(); ++i) { Tools::convert(mmin[i],gmin[i]); Tools::convert(mmax[i],gmax[i]); }
+      56             :     // Create the coarse grid grid objects
+      57           1 :     mygrid.setup( "flat", pbc, 0, 0.0 );
+      58           1 :     mygrid.setBounds( gmin, gmax, ng, dummy_spacing );
+      59             :     // Setup the fine grid object
+      60           1 :     if( nfg[0]>0 ) {
+      61           2 :       using_fgrid=true; myfgrid.setup("flat", pbc, 0, 0.0 ); dummy_spacing.resize(0);
+      62           1 :       myfgrid.setBounds( gmin, gmax, nfg, dummy_spacing );
+      63             :     }
+      64           2 :     value.reset( new Value( NULL, "gval", true, mygrid.getNbin(true)) );
+      65           1 :     myinterp.reset( new Interpolator( value.get(), mygrid ) );
+      66           1 :   }
+      67             :   void setGridElement( const unsigned& ind, const double& emin, const std::vector<double>& der );
+      68             :   bool minimise( std::vector<double>& p, engf_pointer myfunc );
+      69             : };
+      70             : 
+      71             : template <class FCLASS>
+      72       24200 : void GridSearch<FCLASS>::setGridElement( const unsigned& ind, const double& emin, const std::vector<double>& der ) {
+      73       72600 :   value->set( ind, emin ); for(unsigned j=0; j<der.size(); ++j) value->setGridDerivatives( ind, j, der[j] );
+      74       24200 : }
+      75             : 
+      76             : template <class FCLASS>
+      77         200 : bool GridSearch<FCLASS>::minimise( std::vector<double>& p, engf_pointer myfunc ) {
+      78         200 :   std::vector<double> der( p.size() ); std::vector<double> coords( p.size() );
+      79         200 :   double initial_eng = (myclass_func->*myfunc)( p, der );
+      80         200 :   mygrid.getGridPointCoordinates( 0, coords ); unsigned pmin=0;
+      81         200 :   double emin=(myclass_func->*myfunc)( coords, der ); setGridElement( 0, emin, der );
+      82       24200 :   for(unsigned i=1; i<mygrid.getNumberOfPoints(); ++i) {
+      83       24000 :     mygrid.getGridPointCoordinates( i, coords );
+      84       24000 :     double eng = (myclass_func->*myfunc)( coords, der );
+      85       24000 :     setGridElement( i, eng, der );
+      86       24000 :     if( eng<emin ) { emin=eng; pmin=i; }
+      87             :   }
+      88             : 
+      89         200 :   if( using_fgrid ) {
+      90         200 :     myfgrid.getGridPointCoordinates( 0, coords ); pmin=0;
+      91         200 :     double emin = myinterp->splineInterpolation( coords, der );
+      92      520200 :     for(unsigned i=1; i<myfgrid.getNumberOfPoints(); ++i) {
+      93      520000 :       myfgrid.getGridPointCoordinates( i, coords );
+      94      520000 :       double eng = myinterp->splineInterpolation( coords, der );
+      95      520000 :       if( eng<emin ) { emin=eng; pmin=i; }
+      96             :     }
+      97         200 :     myfgrid.getGridPointCoordinates( pmin, coords );
+      98         200 :     double checkEng = (myclass_func->*myfunc)( coords, der );
+      99         200 :     if( checkEng<initial_eng ) {
+     100          22 :       myfgrid.getGridPointCoordinates( pmin, p );
+     101             :       return true;
+     102             :     } else {
+     103             :       return false;
+     104             :     }
+     105             :   }
+     106             : 
+     107           0 :   if( emin<initial_eng ) {
+     108           0 :     mygrid.getGridPointCoordinates( pmin, p );
+     109             :     return true;
+     110             :   }
+     111             :   return false;
+     112             : }
+     113             : 
+     114             : }
+     115             : }
+     116             : #endif
+     117             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/InterpolateGrid.cpp.func-sort-c.html b/coverage/gridtools/InterpolateGrid.cpp.func-sort-c.html new file mode 100644 index 000000000000..d9dd4b2b4b4a --- /dev/null +++ b/coverage/gridtools/InterpolateGrid.cpp.func-sort-c.html @@ -0,0 +1,113 @@ + + + + + + + + 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:717693.4 %
Date:2024-04-19 12:12:35Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools15InterpolateGridC2ERKNS_13ActionOptionsE0
_ZNK4PLMD9gridtools15InterpolateGrid22getGridCoordinateNamesB5cxx11Ev2
_ZN4PLMD9gridtools15InterpolateGridC1ERKNS_13ActionOptionsE82
_ZN4PLMD9gridtools15InterpolateGrid16registerKeywordsERNS_8KeywordsE84
_ZN4PLMD9gridtools15InterpolateGrid16setupOnFirstStepEb164
_ZN4PLMD9gridtools15InterpolateGrid22getNumberOfDerivativesEv256
_ZNK4PLMD9gridtools15InterpolateGrid24getGridCoordinatesObjectEv392
_ZNK4PLMD9gridtools15InterpolateGrid25gatherForcesOnStoredValueEPKNS_5ValueERKjRKNS_10MultiValueERSt6vectorIdSaIdEE1956
_ZNK4PLMD9gridtools15InterpolateGrid17gatherStoredValueERKjS3_RKNS_10MultiValueES3_RSt6vectorIdSaIdEE13660
_ZNK4PLMD9gridtools15InterpolateGrid11performTaskERKjRNS_10MultiValueE15616
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/InterpolateGrid.cpp.func.html b/coverage/gridtools/InterpolateGrid.cpp.func.html new file mode 100644 index 000000000000..22dca9864517 --- /dev/null +++ b/coverage/gridtools/InterpolateGrid.cpp.func.html @@ -0,0 +1,113 @@ + + + + + + + + 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:717693.4 %
Date:2024-04-19 12:12:35Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools15InterpolateGrid16registerKeywordsERNS_8KeywordsE84
_ZN4PLMD9gridtools15InterpolateGrid16setupOnFirstStepEb164
_ZN4PLMD9gridtools15InterpolateGrid22getNumberOfDerivativesEv256
_ZN4PLMD9gridtools15InterpolateGridC1ERKNS_13ActionOptionsE82
_ZN4PLMD9gridtools15InterpolateGridC2ERKNS_13ActionOptionsE0
_ZNK4PLMD9gridtools15InterpolateGrid11performTaskERKjRNS_10MultiValueE15616
_ZNK4PLMD9gridtools15InterpolateGrid17gatherStoredValueERKjS3_RKNS_10MultiValueES3_RSt6vectorIdSaIdEE13660
_ZNK4PLMD9gridtools15InterpolateGrid22getGridCoordinateNamesB5cxx11Ev2
_ZNK4PLMD9gridtools15InterpolateGrid24getGridCoordinatesObjectEv392
_ZNK4PLMD9gridtools15InterpolateGrid25gatherForcesOnStoredValueEPKNS_5ValueERKjRKNS_10MultiValueERSt6vectorIdSaIdEE1956
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/InterpolateGrid.cpp.gcov.html b/coverage/gridtools/InterpolateGrid.cpp.gcov.html new file mode 100644 index 000000000000..e1559041aac3 --- /dev/null +++ b/coverage/gridtools/InterpolateGrid.cpp.gcov.html @@ -0,0 +1,259 @@ + + + + + + + + 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:717693.4 %
Date:2024-04-19 12:12:35Functions:91090.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionRegister.h"
+      23             : #include "core/PlumedMain.h"
+      24             : #include "EvaluateGridFunction.h"
+      25             : #include "ActionWithGrid.h"
+      26             : 
+      27             : //+PLUMEDOC GRIDANALYSIS INTERPOLATE_GRID
+      28             : /*
+      29             : Interpolate a smooth function stored on a grid onto a grid with a smaller grid spacing.
+      30             : 
+      31             : This action takes a function evaluated on a grid as input and can be used to interpolate the values of that
+      32             : function on to a finer grained grid.  The interpolation within this algorithm is done using splines.
+      33             : 
+      34             : \par Examples
+      35             : 
+      36             : The input below can be used to post process a trajectory.  It calculates a \ref HISTOGRAM as a function the
+      37             : distance between atoms 1 and 2 using kernel density estimation.  During the calculation the values of the kernels
+      38             : 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
+      39             : simulation this function is interpolated onto a finer grid of 200 points between 0.0 and 3.0.
+      40             : 
+      41             : \plumedfile
+      42             : x: DISTANCE ATOMS=1,2
+      43             : hA1: HISTOGRAM ARG=x GRID_MIN=0.0 GRID_MAX=3.0 GRID_BIN=100 BANDWIDTH=0.1
+      44             : ii: INTERPOLATE_GRID GRID=hA1 GRID_BIN=200
+      45             : DUMPGRID GRID=ii FILE=histo.dat
+      46             : \endplumedfile
+      47             : 
+      48             : */
+      49             : //+ENDPLUMEDOC
+      50             : 
+      51             : namespace PLMD {
+      52             : namespace gridtools {
+      53             : 
+      54             : class InterpolateGrid : public ActionWithGrid {
+      55             : private:
+      56             :   bool midpoints;
+      57             :   std::vector<unsigned> nbin;
+      58             :   std::vector<double> gspacing;
+      59             :   EvaluateGridFunction input_grid;
+      60             :   GridCoordinatesObject output_grid;
+      61             : public:
+      62             :   static void registerKeywords( Keywords& keys );
+      63             :   explicit InterpolateGrid(const ActionOptions&ao);
+      64             :   void setupOnFirstStep( const bool incalc ) override ;
+      65             :   unsigned getNumberOfDerivatives() override ;
+      66             :   const GridCoordinatesObject& getGridCoordinatesObject() const override ;
+      67             :   std::vector<std::string> getGridCoordinateNames() const override ;
+      68             :   void performTask( const unsigned& current, MultiValue& myvals ) const override ;
+      69             :   void gatherStoredValue( const unsigned& valindex, const unsigned& code, const MultiValue& myvals,
+      70             :                           const unsigned& bufstart, std::vector<double>& buffer ) const ;
+      71             :   void gatherForcesOnStoredValue( const Value* myval, const unsigned& itask, const MultiValue& myvals, std::vector<double>& forces ) const override ;
+      72             : };
+      73             : 
+      74             : PLUMED_REGISTER_ACTION(InterpolateGrid,"INTERPOLATE_GRID")
+      75             : 
+      76          84 : void InterpolateGrid::registerKeywords( Keywords& keys ) {
+      77          84 :   ActionWithGrid::registerKeywords( keys );
+      78         168 :   keys.add("optional","GRID_BIN","the number of bins for the grid"); keys.use("ARG");
+      79         168 :   keys.add("optional","GRID_SPACING","the approximate grid spacing (to be used as an alternative or together with GRID_BIN)");
+      80         168 :   keys.addFlag("MIDPOINTS",false,"interpolate the values of the function at the midpoints of the grid coordinates of the input grid");
+      81          84 :   EvaluateGridFunction ii; ii.registerKeywords( keys );
+      82          84 : }
+      83             : 
+      84          82 : InterpolateGrid::InterpolateGrid(const ActionOptions&ao):
+      85             :   Action(ao),
+      86          82 :   ActionWithGrid(ao)
+      87             : {
+      88          82 :   if( getNumberOfArguments()!=1 ) error("should only be one argument to this action");
+      89          82 :   if( getPntrToArgument(0)->getRank()==0 || !getPntrToArgument(0)->hasDerivatives() ) error("input to this action should be a grid");
+      90             : 
+      91         328 :   parseFlag("MIDPOINTS",midpoints); parseVector("GRID_BIN",nbin); parseVector("GRID_SPACING",gspacing); unsigned dimension = getPntrToArgument(0)->getRank();
+      92          82 :   if( !midpoints && nbin.size()!=dimension && gspacing.size()!=dimension ) error("MIDPOINTS, GRID_BIN or GRID_SPACING must be set");
+      93          82 :   if( midpoints ) {
+      94          80 :     log.printf("  evaluating function at midpoints of cells in input grid\n");
+      95           2 :   } else if( nbin.size()==dimension ) {
+      96           2 :     log.printf("  number of bins in grid %d", nbin[0]);
+      97           2 :     for(unsigned i=1; i<nbin.size(); ++i) log.printf(", %d", nbin[i]);
+      98           2 :     log.printf("\n");
+      99           0 :   } else if( gspacing.size()==dimension ) {
+     100           0 :     log.printf("  spacing for bins in grid %f", gspacing[0]);
+     101           0 :     for(unsigned i=1; i<gspacing.size(); ++i) log.printf(", %d", gspacing[i]);
+     102           0 :     log.printf("\n");
+     103             :   }
+     104             :   // Create the input grid
+     105          82 :   input_grid.read( this );
+     106             :   // Need this for creation of tasks
+     107         164 :   output_grid.setup( "flat", input_grid.getPbc(), 0, 0.0 );
+     108             : 
+     109             :   // Now add a value
+     110          82 :   std::vector<unsigned> shape( dimension, 0 );
+     111          82 :   addValueWithDerivatives( shape );
+     112             : 
+     113          82 :   if( getPntrToArgument(0)->isPeriodic() ) {
+     114           0 :     std::string min, max; getPntrToArgument(0)->getDomain( min, max ); setPeriodic( min, max );
+     115          82 :   } else setNotPeriodic();
+     116          82 :   setupOnFirstStep( false );
+     117          82 : }
+     118             : 
+     119         164 : void InterpolateGrid::setupOnFirstStep( const bool incalc ) {
+     120         164 :   input_grid.setup( this );
+     121         164 :   ActionWithGrid* ag=ActionWithGrid::getInputActionWithGrid( getPntrToArgument(0)->getPntrToAction() );
+     122         164 :   plumed_assert( ag ); const GridCoordinatesObject& mygrid = ag->getGridCoordinatesObject();
+     123         164 :   if( midpoints ) {
+     124         160 :     double min, max; nbin.resize( getPntrToComponent(0)->getRank() );
+     125             :     std::vector<std::string> str_min( input_grid.getMin() ), str_max(input_grid.getMax() );
+     126         320 :     for(unsigned i=0; i<nbin.size(); ++i) {
+     127         160 :       if( incalc ) {
+     128          80 :         Tools::convert( str_min[i], min ); Tools::convert( str_max[i], max );
+     129          80 :         min += 0.5*input_grid.getGridSpacing()[i];
+     130             :       }
+     131         320 :       if( input_grid.getPbc()[i] ) {
+     132          30 :         nbin[i] = input_grid.getNbin()[i];
+     133          45 :         if( incalc ) max += 0.5*input_grid.getGridSpacing()[i];
+     134             :       } else {
+     135         130 :         nbin[i] = input_grid.getNbin()[i] - 1;
+     136         195 :         if( incalc ) max -= 0.5*input_grid.getGridSpacing()[i];
+     137             :       }
+     138         160 :       if( incalc ) {
+     139          80 :         Tools::convert( min, str_min[i] ); Tools::convert( max, str_max[i] );
+     140             :       }
+     141             :     }
+     142         160 :     output_grid.setBounds( str_min, str_max, nbin,  gspacing );
+     143         164 :   } else output_grid.setBounds( mygrid.getMin(), mygrid.getMax(), nbin, gspacing );
+     144         164 :   getPntrToComponent(0)->setShape( output_grid.getNbin(true) );
+     145         164 :   if( !incalc ) gspacing.resize(0);
+     146         164 : }
+     147             : 
+     148         256 : unsigned InterpolateGrid::getNumberOfDerivatives() {
+     149         256 :   return getPntrToArgument(0)->getRank();
+     150             : }
+     151             : 
+     152         392 : const GridCoordinatesObject& InterpolateGrid::getGridCoordinatesObject() const {
+     153         392 :   return output_grid;
+     154             : }
+     155             : 
+     156           2 : std::vector<std::string> InterpolateGrid::getGridCoordinateNames() const {
+     157           2 :   ActionWithGrid* ag = ActionWithGrid::getInputActionWithGrid( getPntrToArgument(0)->getPntrToAction() );
+     158           2 :   plumed_assert( ag ); return ag->getGridCoordinateNames();
+     159             : }
+     160             : 
+     161       15616 : void InterpolateGrid::performTask( const unsigned& current, MultiValue& myvals ) const {
+     162       15616 :   std::vector<double> pos( output_grid.getDimension() ); output_grid.getGridPointCoordinates( current, pos );
+     163       15616 :   std::vector<double> val(1); Matrix<double> der( 1, output_grid.getDimension() ); input_grid.calc( this, pos, val, der );
+     164       15616 :   unsigned ostrn = getConstPntrToComponent(0)->getPositionInStream(); myvals.setValue( ostrn, val[0] );
+     165       31232 :   for(unsigned i=0; i<output_grid.getDimension(); ++i) { myvals.addDerivative( ostrn, i, der(0,i) ); myvals.updateIndex( ostrn, i ); }
+     166       15616 : }
+     167             : 
+     168       13660 : void InterpolateGrid::gatherStoredValue( const unsigned& valindex, const unsigned& code, const MultiValue& myvals,
+     169             :     const unsigned& bufstart, std::vector<double>& buffer ) const {
+     170       13660 :   plumed_dbg_assert( valindex==0 ); unsigned ostrn = getConstPntrToComponent(0)->getPositionInStream();
+     171       13660 :   unsigned istart = bufstart + (1+output_grid.getDimension())*code; buffer[istart] += myvals.get( ostrn );
+     172       27320 :   for(unsigned i=0; i<output_grid.getDimension(); ++i) buffer[istart+1+i] += myvals.getDerivative( ostrn, i );
+     173       13660 : }
+     174             : 
+     175        1956 : void InterpolateGrid::gatherForcesOnStoredValue( const Value* myval, const unsigned& itask, const MultiValue& myvals, std::vector<double>& forces ) const {
+     176        1956 :   std::vector<double> pos(output_grid.getDimension()); double ff = myval->getForce(itask);
+     177        1956 :   output_grid.getGridPointCoordinates( itask, pos ); input_grid.applyForce( this, pos, ff, forces );
+     178        1956 : }
+     179             : 
+     180             : 
+     181             : }
+     182             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/Interpolator.cpp.func-sort-c.html b/coverage/gridtools/Interpolator.cpp.func-sort-c.html new file mode 100644 index 000000000000..10a6eee1b680 --- /dev/null +++ b/coverage/gridtools/Interpolator.cpp.func-sort-c.html @@ -0,0 +1,77 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/Interpolator.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - Interpolator.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3333100.0 %
Date:2024-04-19 12:12:35Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD9gridtools12Interpolator19splineInterpolationERKSt6vectorIdSaIdEERS4_544167
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/Interpolator.cpp.func.html b/coverage/gridtools/Interpolator.cpp.func.html new file mode 100644 index 000000000000..cd8efcfdb113 --- /dev/null +++ b/coverage/gridtools/Interpolator.cpp.func.html @@ -0,0 +1,77 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/Interpolator.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - Interpolator.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3333100.0 %
Date:2024-04-19 12:12:35Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD9gridtools12Interpolator19splineInterpolationERKSt6vectorIdSaIdEERS4_544167
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/Interpolator.cpp.gcov.html b/coverage/gridtools/Interpolator.cpp.gcov.html new file mode 100644 index 000000000000..569e37c9a092 --- /dev/null +++ b/coverage/gridtools/Interpolator.cpp.gcov.html @@ -0,0 +1,152 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/Interpolator.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - Interpolator.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3333100.0 %
Date:2024-04-19 12:12:35Functions: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             : #include "Interpolator.h"
+      23             : 
+      24             : namespace PLMD {
+      25             : namespace gridtools {
+      26             : 
+      27      544167 : double Interpolator::splineInterpolation( const std::vector<double>& x, std::vector<double>& der ) const {
+      28      544167 :   plumed_dbg_assert( gridobject.getGridType()=="flat" ); unsigned dimension = gridobject.getDimension();
+      29             : 
+      30      544167 :   double X,X2,X3,value=0; der.assign(der.size(),0.0);
+      31      544167 :   std::vector<double> fd(dimension);
+      32      544167 :   std::vector<double> C(dimension);
+      33      544167 :   std::vector<double> D(dimension);
+      34      544167 :   std::vector<double> dder(dimension);
+      35             : 
+      36      544167 :   std::vector<unsigned> nindices(dimension);
+      37      544167 :   std::vector<unsigned> indices(dimension); gridobject.getIndices( x, indices );
+      38      544167 :   std::vector<double> xfloor(dimension); gridobject.getGridPointCoordinates( gridobject.getIndex(x), nindices, xfloor );
+      39             : 
+      40             :   // loop over neighbors
+      41             :   std::vector<unsigned> neigh; unsigned n_neigh;
+      42      544167 :   gridobject.getSplineNeighbors( gridobject.getIndex(indices), n_neigh, neigh );
+      43     2713479 :   for(unsigned int ipoint=0; ipoint<n_neigh; ++ipoint) {
+      44     2169312 :     double grid=values->get( neigh[ipoint] );
+      45     6595096 :     for(unsigned j=0; j<dimension; ++j) dder[j] = values->getGridDerivative( neigh[ipoint], j );
+      46             : 
+      47     2169312 :     gridobject.getIndices( neigh[ipoint], nindices );
+      48             :     double ff=1.0;
+      49     6595096 :     for(unsigned j=0; j<dimension; ++j) {
+      50             :       int x0=1;
+      51     4425784 :       if(nindices[j]==indices[j]) x0=0;
+      52     4425784 :       double ddx=gridobject.getGridSpacing()[j];
+      53     4425784 :       X=fabs((x[j]-xfloor[j])/ddx-(double)x0);
+      54     4425784 :       X2=X*X;
+      55     4425784 :       X3=X2*X;
+      56             :       double yy;
+      57     4425784 :       if(fabs(grid)<0.0000001) yy=0.0;
+      58     4398326 :       else yy=-dder[j]/grid;
+      59     6658876 :       C[j]=(1.0-3.0*X2+2.0*X3) - (x0?-1.0:1.0)*yy*(X-2.0*X2+X3)*ddx;
+      60     4425784 :       D[j]=( -6.0*X +6.0*X2) - (x0?-1.0:1.0)*yy*(1.0-4.0*X +3.0*X2)*ddx;
+      61     4425784 :       D[j]*=(x0?-1.0:1.0)/ddx;
+      62     4425784 :       ff*=C[j];
+      63             :     }
+      64     6595096 :     for(unsigned j=0; j<dimension; ++j) {
+      65     4425784 :       fd[j]=D[j];
+      66    13580176 :       for(unsigned i=0; i<dimension; ++i) if(i!=j) fd[j]*=C[i];
+      67             :     }
+      68     2169312 :     value+=grid*ff;
+      69     6595096 :     for(unsigned j=0; j<dimension; ++j) der[j]+=grid*fd[j];
+      70             :   }
+      71      544167 :   return value;
+      72             : }
+      73             : 
+      74             : }
+      75             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/Interpolator.h.func-sort-c.html b/coverage/gridtools/Interpolator.h.func-sort-c.html new file mode 100644 index 000000000000..c40df8689a01 --- /dev/null +++ b/coverage/gridtools/Interpolator.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/Interpolator.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - Interpolator.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-04-19 12:12:35Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/Interpolator.h.func.html b/coverage/gridtools/Interpolator.h.func.html new file mode 100644 index 000000000000..82a0b4bf03b9 --- /dev/null +++ b/coverage/gridtools/Interpolator.h.func.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/Interpolator.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - Interpolator.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-04-19 12:12:35Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/Interpolator.h.gcov.html b/coverage/gridtools/Interpolator.h.gcov.html new file mode 100644 index 000000000000..83d279845576 --- /dev/null +++ b/coverage/gridtools/Interpolator.h.gcov.html @@ -0,0 +1,121 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/Interpolator.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - Interpolator.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-04-19 12:12:35Functions: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_gridtools_Interpolator_h
+      23             : #define __PLUMED_gridtools_Interpolator_h
+      24             : 
+      25             : #include "core/Value.h"
+      26             : #include "GridCoordinatesObject.h"
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace gridtools {
+      30             : 
+      31             : class Interpolator {
+      32             : private:
+      33             :   Value* values;
+      34             :   const GridCoordinatesObject& gridobject;
+      35             : 
+      36             : public:
+      37          10 :   Interpolator( Value* myval, const GridCoordinatesObject& mygrid ) : values(myval), gridobject(mygrid) {}
+      38             :   /// Interpolate the function using splines
+      39             :   double splineInterpolation( const std::vector<double>& x, std::vector<double>& der ) const ;
+      40             : };
+      41             : 
+      42             : }
+      43             : }
+      44             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/KDE.cpp.func-sort-c.html b/coverage/gridtools/KDE.cpp.func-sort-c.html new file mode 100644 index 000000000000..d4904cf271df --- /dev/null +++ b/coverage/gridtools/KDE.cpp.func-sort-c.html @@ -0,0 +1,149 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/KDE.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - KDE.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:29233886.4 %
Date:2024-04-19 12:12:35Functions:181994.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools3KDEC2ERKNS_13ActionOptionsE0
_ZNK4PLMD9gridtools3KDE22getGridCoordinateNamesB5cxx11Ev124
_ZN4PLMD9gridtools3KDE19areAllTasksRequiredERSt6vectorIPNS_16ActionWithVectorESaIS4_EE146
_ZN4PLMD9gridtools3KDEC1ERKNS_13ActionOptionsE146
_ZN4PLMD9gridtools3KDE16registerKeywordsERNS_8KeywordsE150
_ZN4PLMD9gridtools3KDE20setupNeighborsVectorEv237
_ZN4PLMD9gridtools3KDE16setupOnFirstStepEb292
_ZNK4PLMD9gridtools3KDE25updateForceTasksFromValueEPKNS_5ValueERSt6vectorIjSaIjEE610
_ZN4PLMD9gridtools3KDE22getNumberOfDerivativesEv1049
_ZN4PLMD9gridtools3KDE16getNumberOfTasksERj2651
_ZNK4PLMD9gridtools3KDE24getGridCoordinatesObjectEv6210
_ZNK4PLMD9gridtools3KDE25gatherForcesOnStoredValueEPKNS_5ValueERKjRKNS_10MultiValueERSt6vectorIdSaIdEE58028
_ZNK4PLMD9gridtools3KDE19setupHistogramBeadsERSt6vectorINS_13HistogramBeadESaIS3_EE133400
_ZNK4PLMD9gridtools3KDE17gatherStoredValueERKjS3_RKNS_10MultiValueES3_RSt6vectorIdSaIdEE251539
_ZNK4PLMD9gridtools3KDE26retrieveArgumentsAndHeightERKNS_10MultiValueERSt6vectorIdSaIdEERd288290
_ZNK4PLMD9gridtools3KDE11performTaskERKjRNS_10MultiValueE309567
_ZNK4PLMD9gridtools3KDE17evaluateBeadValueERSt6vectorINS_13HistogramBeadESaIS3_EERKS2_IdSaIdEESA_RKdRS8_533600
_ZNK4PLMD9gridtools3KDE15checkTaskStatusERKjRi1500435
_ZNK4PLMD9gridtools3KDE14evaluateKernelERKSt6vectorIdSaIdEES6_RKdRS4_38119671
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/KDE.cpp.func.html b/coverage/gridtools/KDE.cpp.func.html new file mode 100644 index 000000000000..f03f64c37021 --- /dev/null +++ b/coverage/gridtools/KDE.cpp.func.html @@ -0,0 +1,149 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/KDE.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - KDE.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:29233886.4 %
Date:2024-04-19 12:12:35Functions:181994.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools3KDE16getNumberOfTasksERj2651
_ZN4PLMD9gridtools3KDE16registerKeywordsERNS_8KeywordsE150
_ZN4PLMD9gridtools3KDE16setupOnFirstStepEb292
_ZN4PLMD9gridtools3KDE19areAllTasksRequiredERSt6vectorIPNS_16ActionWithVectorESaIS4_EE146
_ZN4PLMD9gridtools3KDE20setupNeighborsVectorEv237
_ZN4PLMD9gridtools3KDE22getNumberOfDerivativesEv1049
_ZN4PLMD9gridtools3KDEC1ERKNS_13ActionOptionsE146
_ZN4PLMD9gridtools3KDEC2ERKNS_13ActionOptionsE0
_ZNK4PLMD9gridtools3KDE11performTaskERKjRNS_10MultiValueE309567
_ZNK4PLMD9gridtools3KDE14evaluateKernelERKSt6vectorIdSaIdEES6_RKdRS4_38119671
_ZNK4PLMD9gridtools3KDE15checkTaskStatusERKjRi1500435
_ZNK4PLMD9gridtools3KDE17evaluateBeadValueERSt6vectorINS_13HistogramBeadESaIS3_EERKS2_IdSaIdEESA_RKdRS8_533600
_ZNK4PLMD9gridtools3KDE17gatherStoredValueERKjS3_RKNS_10MultiValueES3_RSt6vectorIdSaIdEE251539
_ZNK4PLMD9gridtools3KDE19setupHistogramBeadsERSt6vectorINS_13HistogramBeadESaIS3_EE133400
_ZNK4PLMD9gridtools3KDE22getGridCoordinateNamesB5cxx11Ev124
_ZNK4PLMD9gridtools3KDE24getGridCoordinatesObjectEv6210
_ZNK4PLMD9gridtools3KDE25gatherForcesOnStoredValueEPKNS_5ValueERKjRKNS_10MultiValueERSt6vectorIdSaIdEE58028
_ZNK4PLMD9gridtools3KDE25updateForceTasksFromValueEPKNS_5ValueERSt6vectorIjSaIjEE610
_ZNK4PLMD9gridtools3KDE26retrieveArgumentsAndHeightERKNS_10MultiValueERSt6vectorIdSaIdEERd288290
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/KDE.cpp.gcov.html b/coverage/gridtools/KDE.cpp.gcov.html new file mode 100644 index 000000000000..4f9f19483a7a --- /dev/null +++ b/coverage/gridtools/KDE.cpp.gcov.html @@ -0,0 +1,652 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/KDE.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - KDE.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:29233886.4 %
Date:2024-04-19 12:12:35Functions:181994.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2017 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received 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             : #include "core/ActionRegister.h"
+      26             : #include "core/PbcAction.h"
+      27             : #include "tools/HistogramBead.h"
+      28             : #include "tools/SwitchingFunction.h"
+      29             : 
+      30             : //+PLUMEDOC ANALYSIS KDE
+      31             : /*
+      32             : Create a histogram from the input scalar/vector/matrix using KDE
+      33             : 
+      34             : \par Examples
+      35             : 
+      36             : 
+      37             : */
+      38             : //+ENDPLUMEDOC
+      39             : 
+      40             : //+PLUMEDOC ANALYSIS SPHERICAL_KDE
+      41             : /*
+      42             : Create a histogram from the input scalar/vector/matrix using SPHERICAL_KDE
+      43             : 
+      44             : \par Examples
+      45             : 
+      46             : 
+      47             : */
+      48             : //+ENDPLUMEDOC
+      49             : 
+      50             : namespace PLMD {
+      51             : namespace gridtools {
+      52             : 
+      53             : class KDE : public ActionWithGrid {
+      54             : private:
+      55             :   double hh;
+      56             :   bool hasheight;
+      57             :   bool ignore_out_of_bounds, fixed_width;
+      58             :   double dp2cutoff;
+      59             :   std::string kerneltype;
+      60             :   GridCoordinatesObject gridobject;
+      61             :   std::vector<std::string> gmin, gmax;
+      62             :   std::vector<double> center;
+      63             :   std::vector<double> gspacing;
+      64             :   unsigned num_neigh, bwargno;
+      65             :   std::vector<Value> grid_diff_value;
+      66             :   std::vector<unsigned> nbin, nneigh, neighbors;
+      67             :   unsigned numberOfKernels, nbins;
+      68             :   SwitchingFunction switchingFunction;
+      69             :   double von_misses_concentration, von_misses_norm;
+      70             :   void setupNeighborsVector();
+      71             :   void retrieveArgumentsAndHeight( const MultiValue& myvals, std::vector<double>& args, double& height ) const ;
+      72             :   double evaluateKernel( const std::vector<double>& gpoint, const std::vector<double>& args, const double& height, std::vector<double>& der ) const ;
+      73             :   void setupHistogramBeads( std::vector<HistogramBead>& bead ) const ;
+      74             :   double evaluateBeadValue( std::vector<HistogramBead>& bead, const std::vector<double>& gpoint, const std::vector<double>& args, const double& height, std::vector<double>& der ) const ;
+      75             : public:
+      76             :   static void registerKeywords( Keywords& keys );
+      77             :   explicit KDE(const ActionOptions&ao);
+      78             :   std::vector<std::string> getGridCoordinateNames() const override ;
+      79             :   const GridCoordinatesObject& getGridCoordinatesObject() const override ;
+      80             :   unsigned getNumberOfDerivatives() override;
+      81             :   void setupOnFirstStep( const bool incalc ) override ;
+      82             :   void getNumberOfTasks( unsigned& ntasks ) override ;
+      83             :   void areAllTasksRequired( std::vector<ActionWithVector*>& task_reducing_actions ) override ;
+      84             :   int checkTaskStatus( const unsigned& taskno, int& flag ) const override ;
+      85             :   void performTask( const unsigned& current, MultiValue& myvals ) const override ;
+      86             :   void gatherStoredValue( const unsigned& valindex, const unsigned& code, const MultiValue& myvals,
+      87             :                           const unsigned& bufstart, std::vector<double>& buffer ) const override ;
+      88             :   void updateForceTasksFromValue( const Value* myval, std::vector<unsigned>& force_tasks ) const override ;
+      89             :   void gatherForcesOnStoredValue( const Value* myval, const unsigned& itask, const MultiValue& myvals, std::vector<double>& forces ) const override ;
+      90             : };
+      91             : 
+      92             : PLUMED_REGISTER_ACTION(KDE,"KDE")
+      93             : PLUMED_REGISTER_ACTION(KDE,"SPHERICAL_KDE")
+      94             : 
+      95         150 : void KDE::registerKeywords( Keywords& keys ) {
+      96         150 :   ActionWithGrid::registerKeywords( keys ); keys.use("ARG");
+      97         300 :   keys.add("optional","HEIGHTS","this keyword takes the label of an action that calculates a vector of values.  The elements of this vector "
+      98             :            "are used as weights for the Gaussians.");
+      99         300 :   keys.add("optional","VOLUMES","this keyword take the label of an action that calculates a vector of values.  The elements of this vector "
+     100             :            "divided by the volume of the Gaussian are used as weights for the Gaussians");
+     101             :   // Keywords for KDE
+     102         300 :   keys.add("compulsory","GRID_MIN","auto","the lower bounds for the grid");
+     103         300 :   keys.add("compulsory","GRID_MAX","auto","the upper bounds for the grid");
+     104         300 :   keys.add("optional","BANDWIDTH","the bandwidths for kernel density esimtation");
+     105         300 :   keys.add("compulsory","METRIC","the inverse covariance to use for the kernels that are added to the grid");
+     106         300 :   keys.add("compulsory","CUTOFF","6.25","the cutoff at which to stop evaluating the kernel functions is set equal to sqrt(2*x)*bandwidth in each direction where x is this number");
+     107         300 :   keys.add("compulsory","KERNEL","GAUSSIAN","the kernel function you are using.  More details on  the kernels available "
+     108             :            "in plumed plumed can be found in \\ref kernelfunctions.");
+     109         300 :   keys.add("optional","GRID_BIN","the number of bins for the grid");
+     110         300 :   keys.addFlag("IGNORE_IF_OUT_OF_RANGE",false,"if a kernel is outside of the range of the grid it is safe to ignore");
+     111         300 :   keys.add("optional","GRID_SPACING","the approximate grid spacing (to be used as an alternative or together with GRID_BIN)");
+     112             :   // Keywords for spherical KDE
+     113         300 :   keys.add("compulsory","CONCENTRATION","the concentration parameter for Von Mises-Fisher distributions (only required for SPHERICAL_KDE)");
+     114         150 : }
+     115             : 
+     116         146 : KDE::KDE(const ActionOptions&ao):
+     117             :   Action(ao),
+     118             :   ActionWithGrid(ao),
+     119         146 :   hasheight(false),
+     120         146 :   fixed_width(false)
+     121             : {
+     122         146 :   std::vector<unsigned> shape( getNumberOfArguments() ); center.resize( getNumberOfArguments() );
+     123         146 :   numberOfKernels=getPntrToArgument(0)->getNumberOfValues();
+     124         192 :   for(unsigned i=1; i<shape.size(); ++i) {
+     125          46 :     if( numberOfKernels!=getPntrToArgument(i)->getNumberOfValues() ) error("mismatch between numbers of values in input arguments");
+     126             :   }
+     127             : 
+     128         292 :   bool weights_are_volumes=true; std::vector<std::string> weight_str; parseVector("VOLUMES",weight_str);
+     129         146 :   if( weight_str.size()==0 ) {
+     130         140 :     parseVector("HEIGHTS",weight_str);
+     131          70 :     if( weight_str.size()>0 ) weights_are_volumes=false;
+     132             :   }
+     133         146 :   hasheight=(weight_str.size()==1);
+     134         146 :   if( weight_str.size()>1 ) error("only one scalar/vector/matrix should be input to HEIGHTS");
+     135             : 
+     136         146 :   if( getName()=="KDE" ) {
+     137         272 :     parse("KERNEL",kerneltype);
+     138         136 :     if( kerneltype!="DISCRETE" ) {
+     139         250 :       std::string bandwidth; std::vector<std::string> bwidths; parseVector("BANDWIDTH",bwidths);
+     140         125 :       if( bwidths.size()>0 ) {
+     141         125 :         std::string band="VALUES=" + bwidths[0];
+     142         276 :         for(unsigned i=0; i<bwidths.size(); ++i) {
+     143         177 :           if( i>0 ) band += "," + bwidths[i];
+     144             :         }
+     145         250 :         plumed.readInputLine( getLabel() + "_sigma: CONSTANT " + band );
+     146         250 :         plumed.readInputLine( getLabel() + "_cov: CUSTOM ARG=" + getLabel() + "_sigma FUNC=x*x PERIODIC=NO" );
+     147         250 :         plumed.readInputLine( getLabel() + "_icov: CUSTOM ARG=" + getLabel() + "_cov FUNC=1/x PERIODIC=NO" );
+     148         250 :         bandwidth = getLabel() + "_icov";
+     149             : 
+     150         250 :         if( (kerneltype=="gaussian" || kerneltype=="GAUSSIAN") && weights_are_volumes ) {
+     151         105 :           std::string pstr; Tools::convert( sqrt(pow(2*pi,bwidths.size())), pstr );
+     152         210 :           plumed.readInputLine( getLabel() + "_bwprod: PRODUCT ARG=" + getLabel() + "_cov");
+     153         210 :           plumed.readInputLine( getLabel() + "_vol: CUSTOM ARG=" + getLabel() + "_bwprod FUNC=(sqrt(x)*" + pstr + ") PERIODIC=NO");
+     154         181 :           if( hasheight ) plumed.readInputLine( getLabel() + "_height: CUSTOM ARG=" + weight_str[0] + "," + getLabel() + "_vol FUNC=x/y PERIODIC=NO");
+     155          58 :           else plumed.readInputLine( getLabel() + "_height: CUSTOM ARG=" + getLabel() + "_vol FUNC=1/x PERIODIC=NO");
+     156         210 :           hasheight=true; weight_str.resize(1); weight_str[0] = getLabel() + "_height";
+     157             :         }
+     158           0 :       } else parse("METRIC",bandwidth);
+     159         125 :       weight_str.push_back( bandwidth );
+     160         125 :     }
+     161             :   }
+     162         146 :   if( weight_str.size()>0 ) {
+     163         142 :     std::vector<Value*> weight_args; ActionWithArguments::interpretArgumentList( weight_str, plumed.getActionSet(), this, weight_args );
+     164         142 :     std::vector<Value*> args( getArguments() ); args.push_back( weight_args[0] );
+     165         142 :     if( hasheight && weight_args[0]->getNumberOfValues()>1 && numberOfKernels!=weight_args[0]->getNumberOfValues() ) error("mismatch between numbers of values in input arguments and HEIGHTS");
+     166             : 
+     167         142 :     if( weight_str.size()==2 ) {
+     168         110 :       log.printf("  quantities used for weights are : %s \n", weight_str[0].c_str() );
+     169         110 :       args.push_back( weight_args[1] );
+     170         110 :       if( weight_args[1]->getRank()==1 && weight_args[1]->getNumberOfValues()!=shape.size() ) error("size of bandwidth vector is incorrect");
+     171         110 :       if( weight_args[1]->getRank()>2 ) error("bandwidths cannot have rank greater than 2");
+     172         110 :       bwargno=args.size()-1; log.printf("  bandwidths are taken from : %s \n", weight_str[1].c_str() );
+     173          32 :     } else if( !hasheight ) {
+     174          15 :       if( weight_args[0]->getRank()==1 && weight_args[0]->getNumberOfValues()!=shape.size() ) error("size of bandwidth vector is incorrect");
+     175          15 :       if( weight_args[0]->getRank()>2 ) error("bandwidths cannot have rank greater than 2");
+     176          15 :       bwargno=args.size()-1; log.printf("  bandwidths are taken from : %s \n", weight_str[0].c_str() );
+     177          17 :     } else if ( weight_str.size()==1 ) {
+     178          17 :       log.printf("  quantities used for weights are : %s \n", weight_str[0].c_str() );
+     179           0 :     } else error("only one scalar/vector/matrix should be input to HEIGHTS");
+     180         142 :     requestArguments( args );
+     181             :   }
+     182             : 
+     183         146 :   if( getName()=="KDE" ) {
+     184         136 :     bool hasauto=false; gmin.resize( shape.size() ); gmax.resize( shape.size() );
+     185         272 :     parseVector("GRID_MIN",gmin); parseVector("GRID_MAX",gmax);
+     186         298 :     for(unsigned i=0; i<gmin.size(); ++i) {
+     187         162 :       if( gmin[i]=="auto" ) {
+     188          46 :         log.printf("  for %dth coordinate min and max are set from cell directions \n", (i+1) );
+     189             :         hasauto=true;  // We need to do a preparation step to set the grid from the box size
+     190          46 :         if( gmax[i]!="auto" ) error("if gmin is set from box vectors gmax must also be set in the same way");
+     191          46 :         if( getPntrToArgument(i)->isPeriodic() ) {
+     192           0 :           if( gmin[i]=="auto" ) getPntrToArgument(i)->getDomain( gmin[i], gmax[i] );
+     193             :           else {
+     194           0 :             std::string str_min, str_max; getPntrToArgument(i)->getDomain( str_min, str_max );
+     195           0 :             if( str_min!=gmin[i] || str_max!=gmax[i] ) error("all periodic arguments should have the same domain");
+     196             :           }
+     197          46 :         } else if( getPntrToArgument(i)->getName().find(".")!=std::string::npos ) {
+     198          46 :           std::size_t dot = getPntrToArgument(i)->getName().find_first_of(".");
+     199          46 :           std::string name = getPntrToArgument(i)->getName().substr(dot+1);
+     200          78 :           if( name!="x" && name!="y" && name!="z" ) {
+     201           0 :             error("cannot set GRID_MIN and GRID_MAX automatically if input argument is not component of distance");
+     202             :           }
+     203             :         } else {
+     204           0 :           error("cannot set GRID_MIN and GRID_MAX automatically if input argument is not component of distance");
+     205             :         }
+     206             :       } else {
+     207         116 :         log.printf("  for %dth coordinate min is set to %s and max is set to %s \n", (i+1), gmin[i].c_str(), gmax[i].c_str() );
+     208             :       }
+     209             :     }
+     210         136 :     if( hasauto && gmin.size()>3 ) error("can only set GRID_MIN and GRID_MAX automatically if components of distance are used in input");
+     211             : 
+     212         408 :     parseVector("GRID_BIN",nbin); parseVector("GRID_SPACING",gspacing); parse("CUTOFF",dp2cutoff);
+     213         254 :     if( kerneltype.find("bin")==std::string::npos && kerneltype!="DISCRETE" ) {
+     214         214 :       std::string errors; switchingFunction.set( kerneltype + " R_0=1.0 NOSTRETCH", errors );
+     215         107 :       if( errors.length()!=0 ) error("problem reading switching function description " + errors);
+     216             :     }
+     217             : 
+     218         136 :     if( nbin.size()!=shape.size() && gspacing.size()!=shape.size() ) error("GRID_BIN or GRID_SPACING must be set");
+     219             :     // Create a value
+     220         136 :     std::vector<bool> ipbc( shape.size() );
+     221         298 :     for(unsigned i=0; i<shape.size(); ++i) {
+     222         311 :       if( getPntrToArgument( i )->isPeriodic() || gmin[i]=="auto" ) ipbc[i]=true;
+     223             :       else ipbc[i]=false;
+     224             :     }
+     225         272 :     gridobject.setup( "flat", ipbc, 0, 0.0 );
+     226             :   } else {
+     227          10 :     if( shape.size()!=3 ) error("should have three coordinates in input to this action");
+     228             : 
+     229          20 :     parse("GRID_BIN",nbins); log.printf("  setting number of bins to %d \n", nbins );
+     230          10 :     parse("CONCENTRATION",von_misses_concentration); fixed_width=true;
+     231          10 :     von_misses_norm = von_misses_concentration / ( 4*pi*sinh( von_misses_concentration ) );
+     232          10 :     log.printf("  setting concentration parameter to %f \n", von_misses_concentration );
+     233             : 
+     234             :     // Create a value
+     235          10 :     std::vector<bool> ipbc( shape.size(), false );
+     236          10 :     double fib_cutoff = std::log( epsilon / von_misses_norm ) / von_misses_concentration;
+     237          20 :     gridobject.setup( "fibonacci", ipbc, nbins, fib_cutoff ); checkRead();
+     238             : 
+     239             :     // Setup the grid
+     240          10 :     shape[0]=nbins; shape[1]=shape[2]=1;
+     241             :   }
+     242         146 :   parseFlag("IGNORE_IF_OUT_OF_RANGE",ignore_out_of_bounds);
+     243         146 :   if( ignore_out_of_bounds ) log.printf("  ignoring kernels that are outside of grid \n");
+     244         146 :   addValueWithDerivatives( shape ); setNotPeriodic();
+     245         146 :   getPntrToComponent(0)->setDerivativeIsZeroWhenValueIsZero();
+     246             :   // Make sure we store all the arguments
+     247         590 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) getPntrToArgument(i)->buildDataStore();
+     248             :   // Check for task reduction
+     249         146 :   updateTaskListReductionStatus(); setupOnFirstStep( false );
+     250         292 : }
+     251             : 
+     252         292 : void KDE::setupOnFirstStep( const bool incalc ) {
+     253         292 :   if( getName()=="SPHERICAL_KDE" ) return ;
+     254             : 
+     255         596 :   for(unsigned i=0; i<getNumberOfDerivatives(); ++i) {
+     256         324 :     if( gmin[i]=="auto" && incalc ) {
+     257             :       double lcoord, ucoord;
+     258          92 :       PbcAction* bv = plumed.getActionSet().selectWithLabel<PbcAction*>("Box"); Tensor box( bv->getPbc().getBox() );
+     259          46 :       std::size_t dot = getPntrToArgument(i)->getName().find_first_of(".");
+     260          46 :       std::string name = getPntrToArgument(i)->getName().substr(dot+1);
+     261          46 :       if( name=="x" ) { lcoord=-0.5*box(0,0); ucoord=0.5*box(0,0); }
+     262          22 :       else if( name=="y" ) { lcoord=-0.5*box(1,1); ucoord=0.5*box(1,1); }
+     263          10 :       else if( name=="z" ) { lcoord=-0.5*box(2,2); ucoord=0.5*box(2,2); }
+     264           0 :       else plumed_error();
+     265             :       // And convert to strings for bin and bmax
+     266          46 :       Tools::convert( lcoord, gmin[i] ); Tools::convert( ucoord, gmax[i] );
+     267             :     }
+     268         324 :     if( incalc ) {
+     269         324 :       grid_diff_value.push_back( Value() );
+     270         162 :       if( gridobject.isPeriodic(i) ) grid_diff_value[i].setDomain( gmin[i], gmax[i] );
+     271         103 :       else grid_diff_value[i].setNotPeriodic();
+     272             :     }
+     273             :   }
+     274             :   // And setup the grid object
+     275         272 :   gridobject.setBounds( gmin, gmax, nbin, gspacing );
+     276         272 :   std::vector<unsigned> shape( gridobject.getNbin(true) );
+     277         272 :   getPntrToComponent(0)->setShape( shape );
+     278         860 :   bool hasauto=false; for(unsigned i=0; i<gmin.size(); ++i) { if(gmin[i]=="auto" || gmax[i]=="auto" ) { hasauto=true; break; } }
+     279             :   // And setup the neighbors
+     280         272 :   if( !hasauto && kerneltype!="DISCRETE" && getPntrToArgument(bwargno)->isConstant() ) {
+     281         214 :     fixed_width=true; setupNeighborsVector();
+     282             :   }
+     283             : }
+     284             : 
+     285         237 : void KDE::setupNeighborsVector() {
+     286         237 :   if( kerneltype!="DISCRETE" ) {
+     287         214 :     std::vector<double> support(gmin.size(),0); nneigh.resize( gmin.size() );
+     288         214 :     if( kerneltype.find("bin")!=std::string::npos ) {
+     289          18 :       std::size_t dd = kerneltype.find("-bin");
+     290          18 :       HistogramBead bead; bead.setKernelType( kerneltype.substr(0,dd) );
+     291          18 :       Value* bw_arg=getPntrToArgument(bwargno);
+     292          18 :       if( bw_arg->getRank()<2 ) {
+     293          36 :         for(unsigned i=0; i<support.size(); ++i) {
+     294          18 :           bead.set( 0, gridobject.getGridSpacing()[i], 1./sqrt(bw_arg->get(i)) );
+     295          18 :           support[i] = bead.getCutoff(); nneigh[i] = static_cast<unsigned>( ceil( support[i]/gridobject.getGridSpacing()[i] ));
+     296             :         }
+     297           0 :       } else plumed_error();
+     298             :     } else {
+     299         196 :       Value* bw_arg=getPntrToArgument(bwargno);
+     300         196 :       if( bw_arg->getRank()<2 ) {
+     301         432 :         for(unsigned i=0; i<support.size(); ++i) {
+     302         236 :           support[i] = sqrt(2.0*dp2cutoff)*(1.0/sqrt(bw_arg->get(i)));
+     303         236 :           nneigh[i] = static_cast<unsigned>( ceil( support[i] / gridobject.getGridSpacing()[i] ) );
+     304             :         }
+     305           0 :       } else if( bw_arg->getRank()==2 ) {
+     306           0 :         Matrix<double> metric(support.size(),support.size()); unsigned k=0;
+     307           0 :         for(unsigned i=0; i<support.size(); ++i) {
+     308           0 :           for(unsigned j=0; j<support.size(); ++j) { metric(i,j)=bw_arg->get(k); k++; }
+     309             :         }
+     310           0 :         Matrix<double> myautovec(support.size(),support.size()); std::vector<double> myautoval(support.size());
+     311           0 :         diagMat(metric,myautoval,myautovec); double maxautoval=1/myautoval[0]; unsigned ind_maxautoval=0;
+     312           0 :         for(unsigned i=1; i<support.size(); i++) {
+     313           0 :           double neweig=1/myautoval[i]; if(neweig>maxautoval) { maxautoval=neweig; ind_maxautoval=i; }
+     314             :         }
+     315           0 :         for(unsigned i=0; i<support.size(); i++) {
+     316           0 :           support[i] = sqrt(2.0*dp2cutoff)*fabs(sqrt(maxautoval)*myautovec(i,ind_maxautoval));
+     317           0 :           nneigh[i] = static_cast<unsigned>( ceil( support[i] / gridobject.getGridSpacing()[i] ) );
+     318             :         }
+     319           0 :       } else plumed_error();
+     320             :     }
+     321         468 :     for(unsigned i=0; i<gridobject.getDimension(); ++i) {
+     322         254 :       double fmax, fmin; Tools::convert( gridobject.getMin()[i], fmin ); Tools::convert( gridobject.getMax()[i], fmax );
+     323         254 :       if( gridobject.isPeriodic(i) && 2*support[i]>(fmax-fmin) ) error("bandwidth is too large for periodic grid");
+     324             :     }
+     325             :   }
+     326         237 : }
+     327             : 
+     328        1049 : unsigned KDE::getNumberOfDerivatives() {
+     329        1049 :   return gridobject.getDimension();
+     330             : }
+     331             : 
+     332         124 : std::vector<std::string> KDE::getGridCoordinateNames() const {
+     333         124 :   std::vector<std::string> names( gridobject.getDimension() );
+     334         297 :   for(unsigned i=0; i<names.size(); ++i) names[i] = getPntrToArgument(i)->getName();
+     335         124 :   return names;
+     336           0 : }
+     337             : 
+     338        6210 : const GridCoordinatesObject& KDE::getGridCoordinatesObject() const {
+     339        6210 :   return gridobject;
+     340             : }
+     341             : 
+     342         146 : void KDE::areAllTasksRequired( std::vector<ActionWithVector*>& task_reducing_actions ) {
+     343         146 :   if( numberOfKernels==1 || (hasheight && getPntrToArgument(gridobject.getDimension())->getRank()>0) ) task_reducing_actions.push_back(this);
+     344         146 : }
+     345             : 
+     346        2651 : void KDE::getNumberOfTasks( unsigned& ntasks ) {
+     347        2651 :   if( !fixed_width ) setupNeighborsVector();
+     348        2651 :   ntasks = numberOfKernels = getPntrToArgument(0)->getNumberOfValues();
+     349        2651 :   if( numberOfKernels>1 ) return;
+     350             : 
+     351         132 :   hh = 1.0; if( hasheight ) hh = getPntrToArgument(gridobject.getDimension())->get();
+     352         309 :   for(unsigned i=0; i<center.size(); ++i) center[i]=getPntrToArgument(i)->get();
+     353         132 :   if( !ignore_out_of_bounds && !gridobject.inbounds( center ) ) {
+     354             :     //if( fabs(height)>epsilon ) warning("bounds are possibly set too small as hills with substantial heights are being ignored");
+     355             :     return;
+     356             :   }
+     357         132 :   if( kerneltype=="DISCRETE" ) {
+     358          12 :     num_neigh=1; neighbors.resize(1);
+     359          24 :     for(unsigned i=0; i<center.size(); ++i) center[i] += 0.5*gridobject.getGridSpacing()[i];
+     360          12 :     neighbors[0]=gridobject.getIndex( center );
+     361         120 :   } else gridobject.getNeighbors( center, nneigh, num_neigh, neighbors );
+     362         132 :   ntasks = getPntrToComponent(0)->getNumberOfValues();
+     363         132 :   return;
+     364             : }
+     365             : 
+     366     1500435 : int KDE::checkTaskStatus( const unsigned& taskno, int& flag ) const {
+     367     1500435 :   if( numberOfKernels>1 ) {
+     368     1400374 :     if( hasheight && getPntrToArgument(gridobject.getDimension())->getRank()>0
+     369     2823898 :         && fabs(getPntrToArgument(gridobject.getDimension())->get(taskno))<epsilon ) return 0;
+     370      185408 :     return 1;
+     371             :   }
+     372    19394629 :   for(unsigned i=0; i<num_neigh; ++i) {
+     373    19339045 :     if( taskno==neighbors[i] ) return 1;
+     374             :   }
+     375             :   return 0;
+     376             : }
+     377             : 
+     378      309567 : void KDE::performTask( const unsigned& current, MultiValue& myvals ) const {
+     379      309567 :   if( numberOfKernels==1 ) {
+     380       21277 :     double newval; std::vector<double> args( gridobject.getDimension() ), der( gridobject.getDimension() );
+     381       21277 :     unsigned valout = getConstPntrToComponent(0)->getPositionInStream();
+     382       21277 :     gridobject.getGridPointCoordinates( current, args );
+     383       21277 :     if( getName()=="KDE" ) {
+     384       21277 :       if( kerneltype=="DISCRETE" ) {
+     385             :         newval = 1.0;
+     386       21265 :       } else if( kerneltype.find("bin")!=std::string::npos ) {
+     387           0 :         double val=hh; std::size_t dd = kerneltype.find("-bin");
+     388           0 :         HistogramBead bead; bead.setKernelType( kerneltype.substr(0,dd) ); Value* bw_arg=getPntrToArgument(bwargno);
+     389           0 :         for(unsigned j=0; j<args.size(); ++j) {
+     390           0 :           if( gridobject.isPeriodic(j) ) {
+     391           0 :             double lcoord,  ucoord; Tools::convert( gmin[j], lcoord );
+     392           0 :             Tools::convert( gmax[j], ucoord ); bead.isPeriodic( lcoord, ucoord );
+     393             :           } else bead.isNotPeriodic();
+     394           0 :           if( bw_arg->getRank()<2 ) bead.set( args[j], args[j]+gridobject.getGridSpacing()[j], 1/sqrt(bw_arg->get(j)) );
+     395           0 :           else if( bw_arg->getRank()==2 ) plumed_error();
+     396           0 :           double contr = bead.calculateWithCutoff( args[j], der[j] );
+     397           0 :           val = val*contr; der[j] = der[j] / contr;
+     398             :         }
+     399           0 :         for(unsigned j=0; j<args.size(); ++j) der[j] *= val; newval=val;
+     400             :       } else {
+     401       21265 :         newval = evaluateKernel( args, center, hh, der );
+     402             :       }
+     403             :     } else {
+     404           0 :       double dot=0; for(unsigned i=0; i<der.size(); ++i) { dot += args[i]*center[i]; }
+     405           0 :       newval = hh*von_misses_norm*exp( von_misses_concentration*dot );
+     406           0 :       for(unsigned i=0; i<der.size(); ++i) der[i] = von_misses_concentration*newval*args[i];
+     407             :     }
+     408       21277 :     myvals.setValue( valout, newval );
+     409       78047 :     for(unsigned i=0; i<der.size(); ++i) { myvals.addDerivative( valout, i, der[i] ); myvals.updateIndex( valout, i ); }
+     410             :   }
+     411      309567 : }
+     412             : 
+     413      288290 : void KDE::retrieveArgumentsAndHeight( const MultiValue& myvals, std::vector<double>& args, double& height ) const {
+     414      712540 :   height=1.0; for(unsigned i=0; i<args.size(); ++i) args[i]=getPntrToArgument(i)->get( myvals.getTaskIndex() );
+     415      288290 :   if( hasheight && getPntrToArgument(args.size())->getRank()==0 ) height = getPntrToArgument( args.size() )->get();
+     416      272358 :   else if( hasheight ) height = getPntrToArgument( args.size() )->get( myvals.getTaskIndex() );
+     417      288290 : }
+     418             : 
+     419    38119671 : double KDE::evaluateKernel( const std::vector<double>& gpoint, const std::vector<double>& args, const double& height, std::vector<double>& der ) const {
+     420    38119671 :   double r2=0, hval = height; Value* bw_arg=getPntrToArgument(bwargno);
+     421    38119671 :   if( bw_arg->getRank()<2 ) {
+     422   151428182 :     for(unsigned j=0; j<der.size(); ++j) {
+     423   113308511 :       double tmp = -grid_diff_value[j].difference( gpoint[j], args[j] );
+     424   113308511 :       der[j] = tmp*bw_arg->get(j); r2 += tmp*der[j];
+     425             :     }
+     426           0 :   } else if( bw_arg->getRank()==2 ) {
+     427           0 :     for(unsigned j=0; j<der.size(); ++j) {
+     428           0 :       der[j]=0; double dp_j, dp_k; dp_j = -grid_diff_value[j].difference( gpoint[j], args[j] );
+     429           0 :       for(unsigned k=0; k<der.size(); ++k ) {
+     430           0 :         if(j==k) dp_k = dp_j;
+     431           0 :         else dp_k = -grid_diff_value[k].difference( gpoint[k], args[k] );
+     432           0 :         der[j] += bw_arg->get(j*der.size()+k)*dp_k; r2 += dp_j*dp_k*bw_arg->get(j*der.size()+k);
+     433             :       }
+     434             :     }
+     435           0 :   } else plumed_error();
+     436    38119671 :   double dval, val=hval*switchingFunction.calculateSqr( r2, dval );
+     437   151428182 :   dval *= hval; for(unsigned j=0; j<der.size(); ++j) der[j] *= dval;
+     438    38119671 :   return val;
+     439             : }
+     440             : 
+     441      133400 : void KDE::setupHistogramBeads( std::vector<HistogramBead>& bead ) const {
+     442      133400 :   std::size_t dd = kerneltype.find("-bin");
+     443      133400 :   std::string ktype=kerneltype.substr(0,dd);
+     444      266800 :   for(unsigned j=0; j<bead.size(); ++j) {
+     445      133400 :     bead[j].setKernelType( ktype );
+     446      133400 :     if( gridobject.isPeriodic(j) ) {
+     447      133400 :       double lcoord,  ucoord; Tools::convert( gmin[j], lcoord );
+     448      133400 :       Tools::convert( gmax[j], ucoord ); bead[j].isPeriodic( lcoord, ucoord );
+     449             :     } else bead[j].isNotPeriodic();
+     450             :   }
+     451      133400 : }
+     452             : 
+     453      533600 : double KDE::evaluateBeadValue( std::vector<HistogramBead>& bead, const std::vector<double>& gpoint, const std::vector<double>& args,
+     454             :                                const double& height, std::vector<double>& der ) const {
+     455      533600 :   double val=height; std::vector<double> contr( args.size() ); Value* bw_arg=getPntrToArgument(bwargno);
+     456      533600 :   if( bw_arg->getRank()<2 ) {
+     457     1067200 :     for(unsigned j=0; j<args.size(); ++j) {
+     458      533600 :       bead[j].set( gpoint[j], gpoint[j]+gridobject.getGridSpacing()[j], 1/sqrt(bw_arg->get(j)) );
+     459      533600 :       contr[j] = bead[j].calculateWithCutoff( args[j], der[j] );
+     460      533600 :       val = val*contr[j];
+     461             :     }
+     462           0 :   } else plumed_error();
+     463     1067200 :   for(unsigned j=0; j<args.size(); ++j) {
+     464      533600 :     if( fabs(contr[j])>epsilon ) der[j] *= val / contr[j];
+     465             :   }
+     466      533600 :   return val;
+     467             : }
+     468             : 
+     469      251539 : void KDE::gatherStoredValue( const unsigned& valindex, const unsigned& code, const MultiValue& myvals,
+     470             :                              const unsigned& bufstart, std::vector<double>& buffer ) const {
+     471             :   plumed_dbg_assert( valindex==0 );
+     472      251539 :   if( numberOfKernels==1 ) {
+     473       21277 :     unsigned istart = bufstart + (1+gridobject.getDimension())*code;
+     474       21277 :     unsigned valout = getConstPntrToComponent(0)->getPositionInStream(); buffer[istart] += myvals.get( valout );
+     475       78047 :     for(unsigned i=0; i<gridobject.getDimension(); ++i) buffer[istart+1+i] += myvals.getDerivative( valout, i );
+     476       46591 :     return;
+     477             :   }
+     478      230262 :   std::vector<double> args( gridobject.getDimension() ); double height; retrieveArgumentsAndHeight( myvals, args, height );
+     479      230262 :   if( !ignore_out_of_bounds && !gridobject.inbounds( args ) ) {
+     480             :     // if( fabs(height)>epsilon ) warning("bounds are possibly set too small as hills with substantial heights are being ignored");
+     481             :     return ;
+     482             :   }
+     483             :   // Add the kernel to the grid
+     484             :   unsigned num_neigh; std::vector<unsigned> neighbors;
+     485      204948 :   if( kerneltype!="DISCRETE" ) gridobject.getNeighbors( args, nneigh, num_neigh, neighbors );
+     486      204948 :   std::vector<double> der( args.size() ), gpoint( args.size() );
+     487      204948 :   if( fabs(height)>epsilon ) {
+     488      204948 :     if( getName()=="KDE" ) {
+     489      197340 :       if( kerneltype=="DISCRETE" ) {
+     490       31494 :         std::vector<double> newargs( args.size() );
+     491       62988 :         for(unsigned i=0; i<args.size(); ++i) newargs[i] = args[i] + 0.5*gridobject.getGridSpacing()[i];
+     492       31494 :         plumed_assert( bufstart + gridobject.getIndex( newargs )*(1+args.size())<buffer.size() );
+     493       31494 :         buffer[ bufstart + gridobject.getIndex( newargs )*(1+args.size()) ] += height;
+     494      165846 :       } else if( kerneltype.find("bin")!=std::string::npos ) {
+     495      104400 :         std::vector<HistogramBead> bead( args.size() ); setupHistogramBeads( bead );
+     496      522000 :         for(unsigned i=0; i<num_neigh; ++i) {
+     497      417600 :           gridobject.getGridPointCoordinates( neighbors[i], gpoint );
+     498      417600 :           double val = evaluateBeadValue( bead, gpoint, args, height, der );
+     499      417600 :           buffer[ bufstart + neighbors[i]*(1+der.size()) ] += val;
+     500      835200 :           for(unsigned j=0; j<der.size(); ++j) buffer[ bufstart + neighbors[i]*(1+der.size()) + 1 + j ] += val*der[j];
+     501             :         }
+     502             :       } else {
+     503    37979124 :         for(unsigned i=0; i<num_neigh; ++i) {
+     504    37917678 :           gridobject.getGridPointCoordinates( neighbors[i], gpoint );
+     505    37917678 :           buffer[ bufstart + neighbors[i]*(1+der.size()) ] += evaluateKernel( gpoint, args, height, der );
+     506   150985777 :           for(unsigned j=0; j<der.size(); ++j) buffer[ bufstart + neighbors[i]*(1+der.size()) + 1 + j ] += der[j];
+     507             :         }
+     508             :       }
+     509             :     } else {
+     510      828405 :       for(unsigned i=0; i<num_neigh; ++i) {
+     511      820797 :         gridobject.getGridPointCoordinates( neighbors[i], gpoint );
+     512     3283188 :         double dot=0; for(unsigned j=0; j<gpoint.size(); ++j) dot += args[j]*gpoint[j];
+     513      820797 :         double newval = height*von_misses_norm*exp( von_misses_concentration*dot );
+     514      820797 :         buffer[ bufstart + neighbors[i]*(1+gpoint.size()) ] += newval;
+     515     3283188 :         for(unsigned j=0; j<gpoint.size(); ++j) buffer[ bufstart + neighbors[i]*(1+gpoint.size()) + 1 + j ] += von_misses_concentration*newval*gpoint[j];
+     516             :       }
+     517             :     }
+     518             :   }
+     519             : }
+     520             : 
+     521         610 : void KDE::updateForceTasksFromValue( const Value* myval, std::vector<unsigned>& force_tasks ) const {
+     522         610 :   if( !myval->forcesWereAdded() ) return ;
+     523         610 :   if( numberOfKernels==1 ) plumed_error();
+     524             : 
+     525         610 :   int flag=1;
+     526      290135 :   for(unsigned i=0; i<numberOfKernels; ++i) {
+     527      289525 :     if( checkTaskStatus( i, flag ) ) force_tasks.push_back(i);
+     528             :   }
+     529             : }
+     530             : 
+     531       58028 : void KDE::gatherForcesOnStoredValue( const Value* myval, const unsigned& itask, const MultiValue& myvals, std::vector<double>& forces ) const {
+     532       58028 :   if( numberOfKernels==1 ) {
+     533           0 :     plumed_error();
+     534             :     return;
+     535             :   }
+     536       58028 :   double height; std::vector<double> args( gridobject.getDimension() );
+     537       58028 :   retrieveArgumentsAndHeight( myvals, args, height );
+     538             :   unsigned num_neigh; std::vector<unsigned> neighbors;
+     539       58028 :   gridobject.getNeighbors( args, nneigh, num_neigh, neighbors );
+     540       58028 :   std::vector<double> der( args.size() ), gpoint( args.size() );
+     541       58028 :   if( fabs(height)>epsilon ) {
+     542       58028 :     if( getName()=="KDE" ) {
+     543       51226 :       if( kerneltype.find("bin")!=std::string::npos ) {
+     544       29000 :         std::vector<HistogramBead> bead( args.size() ); setupHistogramBeads( bead );
+     545      145000 :         for(unsigned i=0; i<num_neigh; ++i) {
+     546      116000 :           gridobject.getGridPointCoordinates( neighbors[i], gpoint );
+     547      116000 :           double val = evaluateBeadValue( bead, gpoint, args, height, der ); double fforce = getConstPntrToComponent(0)->getForce( neighbors[i] );
+     548      116000 :           if( hasheight && getPntrToArgument(args.size())->getRank()==0 ) forces[ args.size()*numberOfKernels ] += val*fforce / height;
+     549      116000 :           else if( hasheight ) forces[ args.size()*numberOfKernels + itask ] += val*fforce / height;
+     550      232000 :           unsigned n=itask; for(unsigned j=0; j<der.size(); ++j) { forces[n] += der[j]*fforce; n += numberOfKernels; }
+     551             :         }
+     552             :       } else {
+     553      202954 :         for(unsigned i=0; i<num_neigh; ++i) {
+     554      180728 :           gridobject.getGridPointCoordinates( neighbors[i], gpoint );
+     555      180728 :           double val = evaluateKernel( gpoint, args, height, der ), fforce = getConstPntrToComponent(0)->getForce( neighbors[i] );
+     556      180728 :           if( hasheight && getPntrToArgument(args.size())->getRank()==0 ) forces[ args.size()*numberOfKernels ] += val*fforce / height;
+     557      179910 :           else if( hasheight ) forces[ args.size()*numberOfKernels + itask ] += val*fforce / height;
+     558      364382 :           unsigned n=itask; for(unsigned j=0; j<der.size(); ++j) { forces[n] += -der[j]*fforce; n += numberOfKernels; }
+     559             :         }
+     560             :       }
+     561             :     } else {
+     562      687002 :       for(unsigned i=0; i<num_neigh; ++i) {
+     563      680200 :         gridobject.getGridPointCoordinates( neighbors[i], gpoint );
+     564     2720800 :         double dot=0; for(unsigned j=0; j<gpoint.size(); ++j) dot += args[j]*gpoint[j];
+     565      680200 :         double fforce = myval->getForce( neighbors[i] ); double newval = height*von_misses_norm*exp( von_misses_concentration*dot );
+     566      680200 :         if( hasheight && getPntrToArgument(args.size())->getRank()==0 ) forces[ args.size()*numberOfKernels ] += newval*fforce / height;
+     567      680200 :         else if( hasheight ) forces[ args.size()*numberOfKernels + itask ] += newval*fforce / height;
+     568     2720800 :         unsigned n=itask; for(unsigned j=0; j<gpoint.size(); ++j) { forces[n] += von_misses_concentration*newval*gpoint[j]*fforce; n += numberOfKernels; }
+     569             :       }
+     570             :     }
+     571             :   }
+     572             : }
+     573             : 
+     574             : }
+     575             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/KLEntropy.cpp.func-sort-c.html b/coverage/gridtools/KLEntropy.cpp.func-sort-c.html new file mode 100644 index 000000000000..954bb5e64542 --- /dev/null +++ b/coverage/gridtools/KLEntropy.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/KLEntropy.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - KLEntropy.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1515100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools9KLEntropyC2ERKNS_13ActionOptionsE0
_ZN4PLMD9gridtools9KLEntropyC1ERKNS_13ActionOptionsE5
_ZN4PLMD9gridtools9KLEntropy16registerKeywordsERNS_8KeywordsE7
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/KLEntropy.cpp.func.html b/coverage/gridtools/KLEntropy.cpp.func.html new file mode 100644 index 000000000000..1e25aa18a1b2 --- /dev/null +++ b/coverage/gridtools/KLEntropy.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/KLEntropy.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - KLEntropy.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1515100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools9KLEntropy16registerKeywordsERNS_8KeywordsE7
_ZN4PLMD9gridtools9KLEntropyC1ERKNS_13ActionOptionsE5
_ZN4PLMD9gridtools9KLEntropyC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/KLEntropy.cpp.gcov.html b/coverage/gridtools/KLEntropy.cpp.gcov.html new file mode 100644 index 000000000000..a115f8005bd2 --- /dev/null +++ b/coverage/gridtools/KLEntropy.cpp.gcov.html @@ -0,0 +1,146 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/KLEntropy.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - KLEntropy.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1515100.0 %
Date:2024-04-19 12:12:35Functions: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 "core/ActionRegister.h"
+      23             : #include "core/ActionShortcut.h"
+      24             : 
+      25             : //+PLUMEDOC ANALYSIS KL_ENTROPY
+      26             : /*
+      27             : Calculate the KL entropy of a distribution
+      28             : 
+      29             : \par Examples
+      30             : 
+      31             : 
+      32             : */
+      33             : //+ENDPLUMEDOC
+      34             : 
+      35             : namespace PLMD {
+      36             : namespace gridtools {
+      37             : 
+      38             : class KLEntropy : public ActionShortcut {
+      39             : public:
+      40             :   static void registerKeywords( Keywords& keys );
+      41             :   explicit KLEntropy(const ActionOptions&ao);
+      42             : };
+      43             : 
+      44             : PLUMED_REGISTER_ACTION(KLEntropy,"KL_ENTROPY")
+      45             : 
+      46           7 : void KLEntropy::registerKeywords( Keywords& keys ) {
+      47           7 :   ActionShortcut::registerKeywords(keys);
+      48          14 :   keys.add("compulsory","ARG","the grid that you wish to use in the KL entropy calculation");
+      49          14 :   keys.add("compulsory","REFERENCE","a file containing the reference density in grid format");
+      50          14 :   keys.add("compulsory","VALUE","the name of the value that should be read from the grid");
+      51          21 :   keys.needsAction("REFERENCE_GRID"); keys.needsAction("CUSTOM"); keys.needsAction("INTEGRATE_GRID");
+      52           7 : }
+      53             : 
+      54           5 : KLEntropy::KLEntropy( const ActionOptions& ao):
+      55             :   Action(ao),
+      56           5 :   ActionShortcut(ao)
+      57             : {
+      58             :   // Reference grid object
+      59          15 :   std::string ref_str, val_str, input_g; parse("VALUE",val_str); parse("REFERENCE",ref_str); parse("ARG",input_g);
+      60          10 :   readInputLine( getShortcutLabel() + "_ref: REFERENCE_GRID VALUE=" + val_str + " FILE=" + ref_str );
+      61             :   // Compute KL divergence
+      62           5 :   if( input_g=="") plumed_merror("could not find ARG keyword in input to KL_ENTROPY");
+      63          10 :   readInputLine( getShortcutLabel()  + "_kl: CUSTOM ARG=" + input_g + "," + getShortcutLabel() + "_ref FUNC=y*log(y/(0.5*(x+y))) PERIODIC=NO");
+      64             :   // Compute integral
+      65          10 :   readInputLine( getShortcutLabel() + ": INTEGRATE_GRID ARG=" + getShortcutLabel() + "_kl PERIODIC=NO");
+      66           5 : }
+      67             : 
+      68             : }
+      69             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/MultiColvarDensity.cpp.func-sort-c.html b/coverage/gridtools/MultiColvarDensity.cpp.func-sort-c.html new file mode 100644 index 000000000000..9d23c752c429 --- /dev/null +++ b/coverage/gridtools/MultiColvarDensity.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/MultiColvarDensity.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - MultiColvarDensity.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:435184.3 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools18MultiColvarDensityC2ERKNS_13ActionOptionsE0
_ZN4PLMD9gridtools18MultiColvarDensityC1ERKNS_13ActionOptionsE8
_ZN4PLMD9gridtools18MultiColvarDensity16registerKeywordsERNS_8KeywordsE10
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/MultiColvarDensity.cpp.func.html b/coverage/gridtools/MultiColvarDensity.cpp.func.html new file mode 100644 index 000000000000..1d3687241dc1 --- /dev/null +++ b/coverage/gridtools/MultiColvarDensity.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/MultiColvarDensity.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - MultiColvarDensity.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:435184.3 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools18MultiColvarDensity16registerKeywordsERNS_8KeywordsE10
_ZN4PLMD9gridtools18MultiColvarDensityC1ERKNS_13ActionOptionsE8
_ZN4PLMD9gridtools18MultiColvarDensityC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/MultiColvarDensity.cpp.gcov.html b/coverage/gridtools/MultiColvarDensity.cpp.gcov.html new file mode 100644 index 000000000000..25c308528d3c --- /dev/null +++ b/coverage/gridtools/MultiColvarDensity.cpp.gcov.html @@ -0,0 +1,234 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/MultiColvarDensity.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - MultiColvarDensity.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:435184.3 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionRegister.h"
+      23             : #include "core/ActionShortcut.h"
+      24             : 
+      25             : namespace PLMD {
+      26             : namespace gridtools {
+      27             : 
+      28             : //+PLUMEDOC GRIDCALC MULTICOLVARDENS
+      29             : /*
+      30             : Evaluate the average value of a multicolvar on a grid.
+      31             : 
+      32             : This keyword allows one to construct a phase field representation for a symmetry function from
+      33             : an atomistic description.  If each atom has an associated order parameter, \f$\phi_i\f$ then a
+      34             : smooth phase field function \f$\phi(r)\f$ can be computed using:
+      35             : 
+      36             : \f[
+      37             : \phi(\mathbf{r}) = \frac{\sum_i K(\mathbf{r}-\mathbf{r}_i) \phi_i }{ \sum_i K(\mathbf{r} - \mathbf{r}_i )}
+      38             : \f]
+      39             : 
+      40             : where \f$\mathbf{r}_i\f$ is the position of atom \f$i\f$, the sums run over all the atoms input
+      41             : and \f$K(\mathbf{r} - \mathbf{r}_i)\f$ is one of the \ref kernelfunctions implemented in plumed.
+      42             : This action calculates the above function on a grid, which can then be used in the input to further
+      43             : actions.
+      44             : 
+      45             : \par Examples
+      46             : 
+      47             : The following example shows perhaps the simplest way in which this action can be used.  The following
+      48             : input computes the density of atoms at each point on the grid and outputs this quantity to a file.  In
+      49             : other words this input instructs plumed to calculate \f$\rho(\mathbf{r}) = \sum_i K(\mathbf{r} - \mathbf{r}_i )\f$
+      50             : 
+      51             : \plumedfile
+      52             : dens: DENSITY SPECIES=1-100
+      53             : grid: MULTICOLVARDENS DATA=dens ORIGIN=1 DIR=xyz NBINS=100,100,100 BANDWIDTH=0.05,0.05,0.05 STRIDE=1
+      54             : DUMPGRID GRID=grid STRIDE=500 FILE=density
+      55             : \endplumedfile
+      56             : 
+      57             : In the above example density is added to the grid on every step.  The PRINT_GRID instruction thus tells PLUMED to
+      58             : output the average density at each point on the grid every 500 steps of simulation.  Notice that the that grid output
+      59             : on step 1000 is an average over all 1000 frames of the trajectory.  If you would like to analyze these two blocks
+      60             : of data separately you must use the CLEAR flag.
+      61             : 
+      62             : This second example computes an order parameter (in this case \ref FCCUBIC) and constructs a phase field model
+      63             : for this order parameter using the equation above.
+      64             : 
+      65             : \plumedfile
+      66             : fcc: FCCUBIC SPECIES=1-5184 SWITCH={CUBIC D_0=1.2 D_MAX=1.5} ALPHA=27
+      67             : dens: MULTICOLVARDENS DATA=fcc ORIGIN=1 DIR=xyz NBINS=14,14,28 BANDWIDTH=1.0,1.0,1.0 STRIDE=1 CLEAR=1
+      68             : DUMPCUBE GRID=dens STRIDE=1 FILE=dens.cube
+      69             : \endplumedfile
+      70             : 
+      71             : In this example the phase field model is computed and output to a file on every step of the simulation.  Furthermore,
+      72             : because the CLEAR=1 keyword is set on the MULTICOLVARDENS line each Gaussian cube file output is a phase field
+      73             : model for a particular trajectory frame. The average value accumulated thus far is cleared at the start of every single
+      74             : timestep and there is no averaging over trajectory frames in this case.
+      75             : 
+      76             : */
+      77             : //+ENDPLUMEDOC
+      78             : 
+      79             : class MultiColvarDensity : public ActionShortcut {
+      80             : public:
+      81             :   explicit MultiColvarDensity(const ActionOptions&);
+      82             :   static void registerKeywords( Keywords& keys );
+      83             : };
+      84             : 
+      85             : PLUMED_REGISTER_ACTION(MultiColvarDensity,"MULTICOLVARDENS")
+      86             : 
+      87          10 : void MultiColvarDensity::registerKeywords( Keywords& keys ) {
+      88          10 :   ActionShortcut::registerKeywords( keys );
+      89          20 :   keys.add("compulsory","STRIDE","1","the frequency with which to accumulate the densities");
+      90          20 :   keys.add("compulsory","CLEAR","0","the frequency with which to clear the density");
+      91          20 :   keys.add("compulsory","ORIGIN","we will use the position of this atom as the origin");
+      92          20 :   keys.add("compulsory","DIR","the direction in which to calculate the density profile");
+      93          20 :   keys.add("optional","BANDWIDTH","the bandwidths for kernel density esimtation");
+      94          20 :   keys.add("compulsory","KERNEL","GAUSSIAN","the kernel function you are using.  More details on  the kernels available "
+      95             :            "in plumed plumed can be found in \\ref kernelfunctions.");
+      96          20 :   keys.add("optional","NBINS","the number of bins to use in each direction (alternative to GRID_NBIN)");
+      97          20 :   keys.add("optional","DATA","the multicolvar which you would like to calculate the density profile for");
+      98          20 :   keys.add("optional","ATOMS","if you are calculating a atomic density you use this keyword to specify the atoms that are involved");
+      99          20 :   keys.addFlag("UNORMALIZED",false,"do not divide by the density");
+     100          20 :   keys.add("optional","NORMALIZATION","set true/false to determine how to the data is normalised");
+     101          30 :   keys.needsAction("DISTANCES"); keys.needsAction("KDE"); keys.needsAction("ACCUMULATE");
+     102          30 :   keys.needsAction("CUSTOM"); keys.needsAction("ONES"); keys.needsAction("CUSTOM");
+     103          10 : }
+     104             : 
+     105           8 : MultiColvarDensity::MultiColvarDensity(const ActionOptions&ao):
+     106             :   Action(ao),
+     107           8 :   ActionShortcut(ao)
+     108             : {
+     109             :   // Read in the position of the origin
+     110          16 :   std::string origin_str; parse("ORIGIN",origin_str);
+     111             :   // Read in the quantity we are calculating the density for
+     112          24 :   std::string atoms_str, data_str; parse("ATOMS",atoms_str); parse("DATA",data_str);
+     113           8 :   if( atoms_str.length()==0 && data_str.length()==0 ) error("quantity to calculate the density for was not specified used DATA/ATOMS");
+     114             :   // Get the information on the direction for the density
+     115          24 :   std::string dir, direction_string; parse("DIR",dir); std::string nbins=""; parse("NBINS",nbins); if(nbins.length()>0) nbins=" GRID_BIN=" + nbins;
+     116          16 :   if( dir=="x" ) direction_string = "ARG=" + getShortcutLabel() + "_dist.x " + nbins;
+     117           0 :   else if( dir=="y" ) direction_string = "ARG=" + getShortcutLabel() + "_dist.y " + nbins;
+     118           0 :   else if( dir=="z" ) direction_string = "ARG=" + getShortcutLabel() + "_dist.z " + nbins;
+     119           0 :   else if( dir=="xy" ) direction_string = "ARG=" + getShortcutLabel() + "_dist.x," + getShortcutLabel() + "_dist.y " + nbins;
+     120           0 :   else if( dir=="xz" ) direction_string = "ARG=" + getShortcutLabel() + "_dist.x," + getShortcutLabel() + "_dist.z " + nbins;
+     121           0 :   else if( dir=="yz" ) direction_string = "ARG=" + getShortcutLabel() + "_dist.y," + getShortcutLabel() + "_dist.z " + nbins;
+     122           0 :   else if( dir=="xyz" ) direction_string = "ARG=" + getShortcutLabel() + "_dist.x," + getShortcutLabel() + "_dist.y," + getShortcutLabel() + "_dist.z " + nbins;
+     123           0 :   else error( dir + " is invalid dir specification use x/y/z/xy/xz/yz/xyz");
+     124             : 
+     125             :   // Parse the keymap for this averaging stuff
+     126          24 :   std::string stride, clear; parse("STRIDE",stride); parse("CLEAR",clear); bool unorm; parseFlag("UNORMALIZED",unorm);
+     127          14 :   if( !unorm ) { std::string normstr; parse("NORMALIZATION",normstr); if( normstr=="false" ) unorm=true; }
+     128             :   // Create distance action
+     129          16 :   bool hasheights; std::string dist_words = getShortcutLabel() + "_dist: DISTANCES COMPONENTS ORIGIN=" + origin_str;
+     130          11 :   if( atoms_str.length()>0 ) { hasheights=false; dist_words += " ATOMS=" + atoms_str; }
+     131          10 :   else { hasheights=true; dist_words += " ATOMS=" + data_str; }
+     132             :   // plumed_massert( keys.count("ORIGIN"), "you must specify the position of the origin" );
+     133           8 :   readInputLine( dist_words );
+     134             : 
+     135           8 :   std::string inputLine = convertInputLineToString();
+     136             :   // Make the kde object for the numerator if needed
+     137           8 :   if( hasheights ) {
+     138          10 :     readInputLine( getShortcutLabel() + "_inumer: KDE VOLUMES=" + data_str + " " + direction_string + " " + inputLine );
+     139           7 :     if( unorm ) { readInputLine( getShortcutLabel() + ": ACCUMULATE ARG=" + getShortcutLabel() + "_inumer STRIDE=" + stride + " CLEAR=" + clear ); return; }
+     140           6 :     else readInputLine( getShortcutLabel() + "_numer: ACCUMULATE ARG=" + getShortcutLabel() + "_inumer STRIDE=" + stride + " CLEAR=" + clear );
+     141             :   }
+     142             :   // Make the kde object
+     143          12 :   readInputLine( getShortcutLabel() + "_kde: KDE " + inputLine  + " " + direction_string );
+     144             :   // Make the division object if it is required
+     145           6 :   if( hasheights && !unorm ) {
+     146           6 :     readInputLine( getShortcutLabel() + "_denom: ACCUMULATE ARG=" + getShortcutLabel() + "_kde STRIDE=" + stride + " CLEAR=" + clear );
+     147           6 :     readInputLine( getShortcutLabel() + ": CUSTOM ARG=" + getShortcutLabel() + "_numer," + getShortcutLabel() + "_denom FUNC=x/y PERIODIC=NO");
+     148           3 :   } else if( !hasheights ) {
+     149           3 :     readInputLine( getShortcutLabel() + "_weight: ONES SIZE=1" );
+     150           6 :     readInputLine( getShortcutLabel() + "_numer: ACCUMULATE ARG=" + getShortcutLabel() + "_kde STRIDE=" + stride + " CLEAR=" + clear );
+     151           6 :     readInputLine( getShortcutLabel() + "_denom: ACCUMULATE ARG=" + getShortcutLabel() + "_weight STRIDE=" + stride + " CLEAR=" + clear );
+     152           6 :     readInputLine( getShortcutLabel() + ": CUSTOM ARG=" + getShortcutLabel() + "_numer," + getShortcutLabel() + "_denom FUNC=x/y PERIODIC=NO");
+     153             :   }
+     154           0 : }
+     155             : 
+     156             : }
+     157             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/PairEntropies.cpp.func-sort-c.html b/coverage/gridtools/PairEntropies.cpp.func-sort-c.html new file mode 100644 index 000000000000..9ae10dc88e09 --- /dev/null +++ b/coverage/gridtools/PairEntropies.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/PairEntropies.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - PairEntropies.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2525100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools13PairEntropiesC2ERKNS_13ActionOptionsE0
_ZN4PLMD9gridtools13PairEntropiesC1ERKNS_13ActionOptionsE1
_ZN4PLMD9gridtools13PairEntropies16registerKeywordsERNS_8KeywordsE3
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/PairEntropies.cpp.func.html b/coverage/gridtools/PairEntropies.cpp.func.html new file mode 100644 index 000000000000..b3b276812baa --- /dev/null +++ b/coverage/gridtools/PairEntropies.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/PairEntropies.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - PairEntropies.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2525100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools13PairEntropies16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD9gridtools13PairEntropiesC1ERKNS_13ActionOptionsE1
_ZN4PLMD9gridtools13PairEntropiesC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/PairEntropies.cpp.gcov.html b/coverage/gridtools/PairEntropies.cpp.gcov.html new file mode 100644 index 000000000000..3b8f4a46b951 --- /dev/null +++ b/coverage/gridtools/PairEntropies.cpp.gcov.html @@ -0,0 +1,160 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/PairEntropies.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - PairEntropies.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2525100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2017 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "RDF.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "core/ActionShortcut.h"
+      25             : 
+      26             : //+PLUMEDOC MCOLVAR PAIRENTROPIES
+      27             : /*
+      28             : Calculate the KL entropy from the RDF around each of the atoms
+      29             : 
+      30             : \par Examples
+      31             : 
+      32             : */
+      33             : //+ENDPLUMEDOC
+      34             : 
+      35             : namespace PLMD {
+      36             : namespace gridtools {
+      37             : 
+      38             : class PairEntropies : public ActionShortcut {
+      39             : public:
+      40             :   static void registerKeywords( Keywords& keys );
+      41             :   explicit PairEntropies(const ActionOptions&ao);
+      42             : };
+      43             : 
+      44             : PLUMED_REGISTER_ACTION(PairEntropies,"PAIRENTROPIES")
+      45             : 
+      46           3 : void PairEntropies::registerKeywords( Keywords& keys ) {
+      47           9 :   RDF::registerKeywords( keys ); keys.remove("GROUP"); keys.remove("GROUPA"); keys.remove("GROUPB");
+      48           6 :   keys.add("atoms","ATOMS","the atoms that you would like to compute the entropies for");
+      49           6 :   keys.needsAction("PAIRENTROPY"); keys.needsAction("INTERPOLATE_GRID");
+      50           6 :   keys.needsAction("INTEGRATE_GRID"); keys.needsAction("CUSTOM");
+      51           3 :   keys.needsAction("CONCATENATE");
+      52           3 : }
+      53             : 
+      54           1 : PairEntropies::PairEntropies(const ActionOptions&ao):
+      55             :   Action(ao),
+      56           1 :   ActionShortcut(ao)
+      57             : {
+      58             :   // Read in the atoms involved
+      59           2 :   std::string atoms_str; parse("ATOMS",atoms_str);
+      60             :   // Create the x2 value
+      61           3 :   std::string maxr, nbins, dens; parse("MAXR",maxr); parse("GRID_BIN",nbins); parse("DENSITY",dens);
+      62           2 :   std::string grid_setup = "GRID_MIN=0 GRID_MAX=" + maxr + " GRID_BIN=" + nbins;
+      63           1 :   RDF::createX2ReferenceObject( getShortcutLabel(), grid_setup, dens.length()==0, this );
+      64             :   // Create the number of input atoms
+      65           2 :   std::string pair_str = "GRID_BIN=" + nbins + " MAXR=" + maxr + " " + convertInputLineToString();
+      66           1 :   std::vector<std::string> awords=Tools::getWords(atoms_str,"\t\n ,"); Tools::interpretRanges( awords );
+      67             :   // Now create all the pairentropy objects
+      68          65 :   for(unsigned i=0; i<awords.size(); ++i) {
+      69          64 :     std::string ilab, jlab, atoms_str2; Tools::convert( awords[i], ilab );
+      70        4160 :     for(unsigned j=0; j<awords.size(); ++j) {
+      71        4096 :       if( awords[i]==awords[j] ) continue; Tools::convert( awords[j], jlab );
+      72        8000 :       if( atoms_str2.length()==0 ) atoms_str2 = jlab; else atoms_str2 += "," + jlab;
+      73             :     }
+      74         128 :     readInputLine( getShortcutLabel() + ilab + ": PAIRENTROPY GROUPA=" + ilab + " GROUPB=" + atoms_str2 + " " + pair_str + " REFERENCE=" + getShortcutLabel() );
+      75             :   }
+      76             :   // And compose a vector containing the values of all the pair entropies
+      77           1 :   std::string num, argstr = "ARG=" + getShortcutLabel() + "1";
+      78          64 :   for(unsigned i=1; i<awords.size(); ++i) { Tools::convert( i+1, num ); argstr += "," + getShortcutLabel() + num; }
+      79           2 :   readInputLine( getShortcutLabel() + ": CONCATENATE " + argstr );
+      80           2 : }
+      81             : 
+      82             : }
+      83             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/PairEntropy.cpp.func-sort-c.html b/coverage/gridtools/PairEntropy.cpp.func-sort-c.html new file mode 100644 index 000000000000..35226a41f950 --- /dev/null +++ b/coverage/gridtools/PairEntropy.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/PairEntropy.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - PairEntropy.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3131100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools11PairEntropyC2ERKNS_13ActionOptionsE0
_ZN4PLMD9gridtools11PairEntropyC1ERKNS_13ActionOptionsE65
_ZN4PLMD9gridtools11PairEntropy16registerKeywordsERNS_8KeywordsE67
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/PairEntropy.cpp.func.html b/coverage/gridtools/PairEntropy.cpp.func.html new file mode 100644 index 000000000000..86a58000f554 --- /dev/null +++ b/coverage/gridtools/PairEntropy.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/PairEntropy.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - PairEntropy.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3131100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools11PairEntropy16registerKeywordsERNS_8KeywordsE67
_ZN4PLMD9gridtools11PairEntropyC1ERKNS_13ActionOptionsE65
_ZN4PLMD9gridtools11PairEntropyC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/PairEntropy.cpp.gcov.html b/coverage/gridtools/PairEntropy.cpp.gcov.html new file mode 100644 index 000000000000..4936032781bc --- /dev/null +++ b/coverage/gridtools/PairEntropy.cpp.gcov.html @@ -0,0 +1,166 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/PairEntropy.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - PairEntropy.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3131100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2017 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "RDF.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "core/ActionShortcut.h"
+      25             : 
+      26             : //+PLUMEDOC MCOLVAR PAIRENTROPY
+      27             : /*
+      28             : Calculate the KL Entropy from the radial distribution function
+      29             : 
+      30             : \par Examples
+      31             : 
+      32             : */
+      33             : //+ENDPLUMEDOC
+      34             : 
+      35             : namespace PLMD {
+      36             : namespace gridtools {
+      37             : 
+      38             : class PairEntropy : public ActionShortcut {
+      39             : public:
+      40             :   static void registerKeywords( Keywords& keys );
+      41             :   explicit PairEntropy(const ActionOptions&ao);
+      42             : };
+      43             : 
+      44             : PLUMED_REGISTER_ACTION(PairEntropy,"PAIRENTROPY")
+      45             : 
+      46          67 : void PairEntropy::registerKeywords( Keywords& keys ) {
+      47          67 :   RDF::registerKeywords( keys ); keys.needsAction("RDF");
+      48         134 :   keys.needsAction("INTERPOLATE_GRID"); keys.needsAction("INTEGRATE_GRID");
+      49          67 : }
+      50             : 
+      51          65 : PairEntropy::PairEntropy(const ActionOptions&ao):
+      52             :   Action(ao),
+      53          65 :   ActionShortcut(ao)
+      54             : {
+      55         130 :   std::string ref_str, ref_name; parse("REFERENCE",ref_name);
+      56         130 :   if( ref_name.length()>0 ) ref_str = "REFERENCE=" + ref_name; else ref_name = getShortcutLabel() + "_rdf";
+      57             :   // Read in the atoms and get the number of atoms that we are using
+      58         130 :   std::string atom_str, group_str, natoms; parse("GROUP",group_str);
+      59          65 :   if( group_str.length()>0 ) {
+      60           1 :     atom_str="GROUP=" + group_str;
+      61           1 :     std::vector<std::string> awords=Tools::getWords(group_str,"\t\n ,");
+      62           1 :     Tools::interpretRanges( awords ); Tools::convert( awords.size(), natoms );
+      63           1 :   } else {
+      64             :     std::string groupa_str, groupb_str;
+      65         128 :     parse("GROUPA",groupa_str); parse("GROUPB",groupb_str);
+      66         128 :     atom_str="GROUPA=" + groupa_str + " GROUPB=" + groupb_str;
+      67          64 :     std::vector<std::string> awords=Tools::getWords(groupb_str,"\t\n ,");
+      68          64 :     Tools::interpretRanges( awords ); Tools::convert( awords.size()+1, natoms );
+      69          64 :   }
+      70             :   // Read in all other keywords and create the RDF object
+      71         390 :   std::string maxr, nbins, dens, bw, cutoff; parse("MAXR",maxr); parse("GRID_BIN",nbins); parse("DENSITY",dens); parse("BANDWIDTH",bw); parse("CUTOFF",cutoff);
+      72          65 :   std::string dens_str; if( dens.length()>0 ) dens_str = " DENSITY=" + dens;
+      73         130 :   readInputLine( getShortcutLabel() + "_rdf: RDF " + atom_str + " CUTOFF=" + cutoff + " GRID_BIN=" + nbins + " MAXR=" + maxr + dens_str + " BANDWIDTH=" + bw + " " + ref_str);
+      74             :   // And compute the two functions we are integrating (we use two matheval objects here and sum them in order to avoid nans from taking logarithms of zero)
+      75         130 :   readInputLine( getShortcutLabel() + "_conv_t1: CUSTOM ARG=" + getShortcutLabel() + "_rdf," + ref_name + "_x2 FUNC=x*y*log(x) PERIODIC=NO");
+      76         130 :   readInputLine( getShortcutLabel() + "_conv_t2: CUSTOM ARG=" + getShortcutLabel() + "_rdf," + ref_name + "_x2 FUNC=(1-x)*y PERIODIC=NO");
+      77         130 :   readInputLine( getShortcutLabel() + "_conv: CUSTOM ARG=" + getShortcutLabel() + "_conv_t1," + getShortcutLabel() + "_conv_t2 FUNC=x+y PERIODIC=NO");
+      78             :   // Now integrate using trapezium rule
+      79         130 :   readInputLine( getShortcutLabel() + "_midp: INTERPOLATE_GRID ARG=" + getShortcutLabel() + "_conv INTERPOLATION_TYPE=linear MIDPOINTS"); // First interpolate onto midpoints
+      80         130 :   readInputLine( getShortcutLabel() + "_int: INTEGRATE_GRID ARG=" + getShortcutLabel() + "_midp PERIODIC=NO"); // And then integrate
+      81             :   // And multiply by final normalizing constant
+      82             :   std::string norm_str;
+      83          65 :   if( dens.length()>0 ) norm_str = " FUNC=-2*pi*x*" + dens;
+      84         130 :   else norm_str = "," + ref_name + "_vol FUNC=-(2*pi*x/y)*" + natoms;
+      85         130 :   readInputLine( getShortcutLabel() + ": CUSTOM PERIODIC=NO ARG=" + getShortcutLabel() + "_int" + norm_str );
+      86          65 : }
+      87             : 
+      88             : }
+      89             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/RDF.cpp.func-sort-c.html b/coverage/gridtools/RDF.cpp.func-sort-c.html new file mode 100644 index 000000000000..0344868620b9 --- /dev/null +++ b/coverage/gridtools/RDF.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/RDF.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - RDF.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:636596.9 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools3RDFC2ERKNS_13ActionOptionsE0
_ZN4PLMD9gridtools3RDF23createX2ReferenceObjectERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_RKbPNS_14ActionShortcutE3
_ZN4PLMD9gridtools3RDFC1ERKNS_13ActionOptionsE66
_ZN4PLMD9gridtools3RDF16registerKeywordsERNS_8KeywordsE138
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/RDF.cpp.func.html b/coverage/gridtools/RDF.cpp.func.html new file mode 100644 index 000000000000..a21346dea76b --- /dev/null +++ b/coverage/gridtools/RDF.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/RDF.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - RDF.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:636596.9 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools3RDF16registerKeywordsERNS_8KeywordsE138
_ZN4PLMD9gridtools3RDF23createX2ReferenceObjectERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_RKbPNS_14ActionShortcutE3
_ZN4PLMD9gridtools3RDFC1ERKNS_13ActionOptionsE66
_ZN4PLMD9gridtools3RDFC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/RDF.cpp.gcov.html b/coverage/gridtools/RDF.cpp.gcov.html new file mode 100644 index 000000000000..38e5ab453b6c --- /dev/null +++ b/coverage/gridtools/RDF.cpp.gcov.html @@ -0,0 +1,208 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/RDF.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - RDF.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:636596.9 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2017 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "RDF.h"
+      23             : #include "core/ActionRegister.h"
+      24             : 
+      25             : //+PLUMEDOC ANALYSIS RDF
+      26             : /*
+      27             : Calculate the radial distribution function
+      28             : 
+      29             : \par Examples
+      30             : 
+      31             : */
+      32             : //+ENDPLUMEDOC
+      33             : 
+      34             : namespace PLMD {
+      35             : namespace gridtools {
+      36             : 
+      37             : PLUMED_REGISTER_ACTION(RDF,"RDF")
+      38             : 
+      39           3 : void RDF::createX2ReferenceObject( const std::string& lab, const std::string& grid_setup, const bool& calc_dens, ActionShortcut* action ) {
+      40             :   // Create grid with normalizing function
+      41           6 :   action->readInputLine( lab  + "_x2: REFERENCE_GRID PERIODIC=NO FUNC=x*x " + grid_setup );
+      42             :   // Compute density if required
+      43           6 :   if( calc_dens ) action->readInputLine( lab + "_vol: VOLUME" );
+      44           3 : }
+      45             : 
+      46         138 : void RDF::registerKeywords( Keywords& keys ) {
+      47         138 :   ActionShortcut::registerKeywords( keys );
+      48         276 :   keys.add("atoms","GROUP","");
+      49         276 :   keys.add("atoms-2","GROUPA","");
+      50         276 :   keys.add("atoms-2","GROUPB","");
+      51         276 :   keys.add("compulsory","GRID_BIN","the number of bins to use when computing the RDF");
+      52         276 :   keys.add("compulsory","KERNEL","GAUSSIAN","the type of kernel to use for computing the histograms for the RDF");
+      53         276 :   keys.add("compulsory","CUTOFF","6.25","the cutoff at which to stop evaluating the kernel functions is set equal to sqrt(2*x)*bandwidth in each direction where x is this number");
+      54         276 :   keys.add("compulsory","MAXR","the maximum distance to use for the rdf");
+      55         276 :   keys.add("compulsory","BANDWIDTH","the bandwidths for kernel density esimtation");
+      56         276 :   keys.add("compulsory","CLEAR","1","the frequency with which to clear the estimate of the rdf.  Set equal to 0 if you want to compute an rdf over the whole trajectory");
+      57         276 :   keys.add("compulsory","STRIDE","1","the frequency with which to compute the rdf and accumulate averages");
+      58         276 :   keys.add("optional","DENSITY","the reference density to use when normalizing the RDF");
+      59         276 :   keys.add("hidden","REFERENCE","this is the label of the reference objects");
+      60         414 :   keys.needsAction("REFERENCE_GRID"); keys.needsAction("VOLUME"); keys.needsAction("DISTANCE_MATRIX");
+      61         414 :   keys.needsAction("CUSTOM"); keys.needsAction("KDE"); keys.needsAction("ACCUMULATE");
+      62         138 :   keys.needsAction("CONSTANT");
+      63         138 : }
+      64             : 
+      65          66 : RDF::RDF(const ActionOptions&ao):
+      66             :   Action(ao),
+      67          66 :   ActionShortcut(ao)
+      68             : {
+      69             :   // Read in grid extent and number of bins
+      70         198 :   std::string maxr, nbins, dens; parse("MAXR",maxr); parse("GRID_BIN",nbins); parse("DENSITY",dens);
+      71         132 :   std::string grid_setup = "GRID_MIN=0 GRID_MAX=" + maxr + " GRID_BIN=" + nbins;
+      72             :   // Create grid with normalizing function on it
+      73         132 :   std::string refstr; parse("REFERENCE",refstr);
+      74          66 :   if( refstr.length()==0 ) {
+      75           2 :     createX2ReferenceObject( getShortcutLabel(), grid_setup, dens.length()==0, this ); refstr = getShortcutLabel();
+      76             :   }
+      77             :   // Read input to histogram
+      78         132 :   std::string cutoff, kernel, bandwidth, kernel_data; parse("KERNEL",kernel);
+      79          66 :   if( kernel=="DISCRETE" ) {
+      80             :     cutoff = maxr; kernel_data="KERNEL=DISCRETE";
+      81           2 :     warning("rdf is normalised by dividing by the surface area at the grid value and not by the volume of the bin as it should be with discrete kernels");
+      82             :   } else {
+      83         260 :     parse("BANDWIDTH",bandwidth); double rcut; parse("CUTOFF",rcut); kernel_data="KERNEL=" + kernel + " IGNORE_IF_OUT_OF_RANGE BANDWIDTH=" + bandwidth;
+      84          65 :     double bw; Tools::convert( bandwidth, bw ); double fcut; Tools::convert( maxr, fcut ); Tools::convert( fcut + sqrt(2.0*rcut)*bw, cutoff );
+      85             :   }
+      86             : 
+      87             :   // Create contact matrix
+      88         132 :   std::string natoms, str_norm_atoms, atom_str, group_str, groupa_str, groupb_str; parse("GROUP",group_str);
+      89          66 :   if( group_str.length()>0 ) {
+      90           4 :     atom_str="GROUP=" + group_str; std::vector<std::string> awords=Tools::getWords(group_str,"\t\n ,");
+      91           2 :     Tools::interpretRanges( awords ); Tools::convert( awords.size(), natoms ); str_norm_atoms = natoms;
+      92           2 :   } else {
+      93         128 :     parse("GROUPA",groupa_str); parse("GROUPB",groupb_str);
+      94          64 :     std::vector<std::string> awords=Tools::getWords(groupb_str,"\t\n ,");
+      95          64 :     Tools::interpretRanges( awords ); Tools::convert( awords.size(), natoms );
+      96         128 :     atom_str="GROUPA=" + groupa_str + " GROUPB=" + groupb_str;
+      97          64 :     std::vector<std::string> bwords=Tools::getWords(groupa_str,"\t\n ,"); Tools::interpretRanges( bwords );
+      98          64 :     Tools::convert( bwords.size()+1, str_norm_atoms );
+      99          64 :   }
+     100             :   // Retrieve the number of atoms
+     101         132 :   readInputLine( getShortcutLabel() + "_mat: DISTANCE_MATRIX CUTOFF=" + cutoff + " " + atom_str);
+     102             : 
+     103             :   // Calculate weights of distances
+     104         132 :   readInputLine( getShortcutLabel() + "_wmat: CUSTOM ARG=" + getShortcutLabel() + "_mat FUNC=step(" + cutoff + "-x) PERIODIC=NO");
+     105             :   // Now create a histogram from the contact matrix
+     106         132 :   unsigned clear, stride; parse("CLEAR",clear); parse("STRIDE",stride);
+     107          66 :   if( clear==1 ) {
+     108         130 :     readInputLine( getShortcutLabel() + "_kde: KDE ARG=" + getShortcutLabel() + "_mat VOLUMES=" + getShortcutLabel() + "_wmat " + grid_setup + " " + kernel_data);
+     109             :   } else {
+     110           1 :     std::string stridestr, clearstr; Tools::convert( stride, stridestr ); Tools::convert( clear, clearstr );
+     111           2 :     readInputLine( getShortcutLabel() + "_okde: KDE ARG=" + getShortcutLabel() + "_mat HEIGHTS=" + getShortcutLabel() + "_wmat " + grid_setup + " " + kernel_data);
+     112           2 :     readInputLine( getShortcutLabel() + "_kde: ACCUMULATE ARG=" + getShortcutLabel() + "_okde STRIDE=" + stridestr + " CLEAR=" + clearstr );
+     113           1 :     readInputLine( getShortcutLabel() + "_one: CONSTANT VALUE=1");
+     114           2 :     readInputLine( getShortcutLabel() + "_norm: ACCUMULATE ARG=" + getShortcutLabel() + "_one STRIDE=" + stridestr + " CLEAR=" + clearstr );
+     115             :   }
+     116             :   // Transform the histogram by normalizing factor for rdf
+     117         132 :   readInputLine( getShortcutLabel() + "_vrdf: CUSTOM ARG=" + getShortcutLabel() + "_kde," + refstr + "_x2 FUNC=x/(4*pi*y) PERIODIC=NO");
+     118             :   // And normalize by density and number of atoms (separated from above to avoid nans)
+     119         132 :   std::string func_str = "PERIODIC=NO ARG=" + getShortcutLabel() + "_vrdf";
+     120          66 :   if( dens.length()>0 ) {
+     121           0 :     if( clear==1 ) func_str += " FUNC=x/(" + dens + "*" + str_norm_atoms + ")";
+     122           0 :     else func_str += "," + getShortcutLabel() + "_norm FUNC=x/(y*" + dens + "*" + str_norm_atoms + ")";
+     123             :   } else {
+     124         131 :     if( clear==1 ) func_str += "," + refstr + "_vol FUNC=x*y/(" + natoms + "*" + str_norm_atoms + ")";
+     125           2 :     else func_str += "," + refstr + "_vol," + getShortcutLabel() + "_norm FUNC=x*y/(z*" + natoms + "*" + str_norm_atoms + ")";
+     126             :   }
+     127         132 :   readInputLine( getShortcutLabel() + ": CUSTOM " + func_str);
+     128          66 : }
+     129             : 
+     130             : }
+     131             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/ReadGridInSetup.cpp.func-sort-c.html b/coverage/gridtools/ReadGridInSetup.cpp.func-sort-c.html new file mode 100644 index 000000000000..3adaffa74637 --- /dev/null +++ b/coverage/gridtools/ReadGridInSetup.cpp.func-sort-c.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/ReadGridInSetup.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - ReadGridInSetup.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12114881.8 %
Date:2024-04-19 12:12:35Functions:6966.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools15ReadGridInSetup16setupOnFirstStepEb0
_ZN4PLMD9gridtools15ReadGridInSetupC2ERKNS_13ActionOptionsE0
_ZNK4PLMD9gridtools15ReadGridInSetup11performTaskERKjRNS_10MultiValueE0
_ZNK4PLMD9gridtools15ReadGridInSetup22getGridCoordinateNamesB5cxx11Ev3
_ZN4PLMD9gridtools15ReadGridInSetup18createGridAndValueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIbSaIbEERKjRKSA_IS7_SaIS7_EESK_RKSA_IjSaIjEE11
_ZN4PLMD9gridtools15ReadGridInSetupC1ERKNS_13ActionOptionsE11
_ZNK4PLMD9gridtools15ReadGridInSetup24getGridCoordinatesObjectEv12
_ZN4PLMD9gridtools15ReadGridInSetup16registerKeywordsERNS_8KeywordsE13
_ZN4PLMD9gridtools15ReadGridInSetup22getNumberOfDerivativesEv34
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/ReadGridInSetup.cpp.func.html b/coverage/gridtools/ReadGridInSetup.cpp.func.html new file mode 100644 index 000000000000..79a0378f1e3b --- /dev/null +++ b/coverage/gridtools/ReadGridInSetup.cpp.func.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/ReadGridInSetup.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - ReadGridInSetup.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12114881.8 %
Date:2024-04-19 12:12:35Functions:6966.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools15ReadGridInSetup16registerKeywordsERNS_8KeywordsE13
_ZN4PLMD9gridtools15ReadGridInSetup16setupOnFirstStepEb0
_ZN4PLMD9gridtools15ReadGridInSetup18createGridAndValueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIbSaIbEERKjRKSA_IS7_SaIS7_EESK_RKSA_IjSaIjEE11
_ZN4PLMD9gridtools15ReadGridInSetup22getNumberOfDerivativesEv34
_ZN4PLMD9gridtools15ReadGridInSetupC1ERKNS_13ActionOptionsE11
_ZN4PLMD9gridtools15ReadGridInSetupC2ERKNS_13ActionOptionsE0
_ZNK4PLMD9gridtools15ReadGridInSetup11performTaskERKjRNS_10MultiValueE0
_ZNK4PLMD9gridtools15ReadGridInSetup22getGridCoordinateNamesB5cxx11Ev3
_ZNK4PLMD9gridtools15ReadGridInSetup24getGridCoordinatesObjectEv12
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/ReadGridInSetup.cpp.gcov.html b/coverage/gridtools/ReadGridInSetup.cpp.gcov.html new file mode 100644 index 000000000000..b8b95e7d8543 --- /dev/null +++ b/coverage/gridtools/ReadGridInSetup.cpp.gcov.html @@ -0,0 +1,360 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/ReadGridInSetup.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - ReadGridInSetup.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12114881.8 %
Date:2024-04-19 12:12:35Functions:6966.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2018 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received 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/ActionRegister.h"
+      24             : #include "lepton/Lepton.h"
+      25             : #include "tools/IFile.h"
+      26             : 
+      27             : //+PLUMEDOC GRIDCALC REFERENCE_GRID
+      28             : /*
+      29             : Setup a constant grid by either reading values from a file or definining a function in input
+      30             : 
+      31             : \par Examples
+      32             : 
+      33             : */
+      34             : //+ENDPLUMEDOC
+      35             : 
+      36             : namespace PLMD {
+      37             : namespace gridtools {
+      38             : 
+      39             : static std::map<std::string, double> leptonConstants= {
+      40             :   {"e", std::exp(1.0)},
+      41             :   {"log2e", 1.0/std::log(2.0)},
+      42             :   {"log10e", 1.0/std::log(10.0)},
+      43             :   {"ln2", std::log(2.0)},
+      44             :   {"ln10", std::log(10.0)},
+      45             :   {"pi", pi},
+      46             :   {"pi_2", pi*0.5},
+      47             :   {"pi_4", pi*0.25},
+      48             : //  {"1_pi", 1.0/pi},
+      49             : //  {"2_pi", 2.0/pi},
+      50             : //  {"2_sqrtpi", 2.0/std::sqrt(pi)},
+      51             :   {"sqrt2", std::sqrt(2.0)},
+      52             :   {"sqrt1_2", std::sqrt(0.5)}
+      53             : };
+      54             : 
+      55             : class ReadGridInSetup : public ActionWithGrid {
+      56             : private:
+      57             :   GridCoordinatesObject gridobject;
+      58             :   std::vector<std::string> dernames;
+      59             :   void createGridAndValue( const std::string& gtype, const std::vector<bool>& ipbc, const unsigned& nfermi,
+      60             :                            const std::vector<std::string>& gmin, const std::vector<std::string>& gmax,
+      61             :                            const std::vector<unsigned>& gbin );
+      62             : public:
+      63             :   static void registerKeywords( Keywords& keys );
+      64             :   explicit ReadGridInSetup(const ActionOptions&ao);
+      65             :   unsigned getNumberOfDerivatives() override ;
+      66           0 :   void setupOnFirstStep( const bool incalc ) override { plumed_merror("should not be in ReadGridInSetup setupOnFirstStep" ); }
+      67           0 :   void performTask( const unsigned& current, MultiValue& myvals ) const override { plumed_merror("should not be in readGridInSetup performTask"); }
+      68             :   std::vector<std::string> getGridCoordinateNames() const override ;
+      69             :   const GridCoordinatesObject& getGridCoordinatesObject() const override ;
+      70             : };
+      71             : 
+      72             : PLUMED_REGISTER_ACTION(ReadGridInSetup,"REFERENCE_GRID")
+      73             : 
+      74          13 : void ReadGridInSetup::registerKeywords( Keywords& keys ) {
+      75          13 :   ActionWithGrid::registerKeywords(keys); keys.remove("SERIAL");
+      76          26 :   keys.add("optional","FUNC","the function to compute on the grid");
+      77          26 :   keys.add("compulsory","GRID_MIN","auto","the lower bounds for the grid");
+      78          26 :   keys.add("compulsory","GRID_MAX","auto","the upper bounds for the grid");
+      79          26 :   keys.add("compulsory","PERIODIC","are the grid directions periodic");
+      80          26 :   keys.add("optional","GRID_BIN","the number of bins for the grid");
+      81          26 :   keys.add("optional","GRID_SPACING","the approximate grid spacing (to be used as an alternative or together with GRID_BIN)");
+      82          26 :   keys.add("optional","VAR","the names to give each of the grid directions in the function.  If you have up to three grid coordinates 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.");
+      83          26 :   keys.add("compulsory","FILE","the name of the file that contains the reference data");
+      84          26 :   keys.add("compulsory","VALUE","the name of the value that should be read from the grid");
+      85          13 : }
+      86             : 
+      87          11 : ReadGridInSetup::ReadGridInSetup(const ActionOptions&ao):
+      88             :   Action(ao),
+      89          11 :   ActionWithGrid(ao)
+      90             : {
+      91          22 :   std::string func; parse("FUNC",func);
+      92          11 :   if( func.length()>0 ) {
+      93             :     // Read in stuff for grid
+      94          10 :     std::vector<std::string> gmin; parseVector("GRID_MIN",gmin);
+      95          10 :     std::vector<std::string> gmax(gmin.size()); parseVector("GRID_MAX",gmax);
+      96          10 :     std::vector<unsigned> gbin(gmin.size()); parseVector("GRID_BIN",gbin);
+      97          10 :     std::vector<std::string> pbc(gmin.size()); parseVector("PERIODIC",pbc);
+      98           5 :     std::vector<bool> ipbc( pbc.size() );
+      99          10 :     for(unsigned i=0; i<ipbc.size(); ++i) {
+     100           5 :       if( pbc[i]=="YES" ) ipbc[i]=true;
+     101           5 :       else if( pbc[i]=="NO" ) ipbc[i]=false;
+     102           0 :       else error( pbc[i] + " is not a valid instruction to the PERIODIC keyword");
+     103             :     }
+     104             : 
+     105             :     // Read in the variables
+     106          10 :     parseVector("VAR",dernames);
+     107           5 :     if(dernames.size()==0) {
+     108           3 :       dernames.resize(gmin.size());
+     109           3 :       if(gmin.size()>3)
+     110           0 :         error("Using more than 3 arguments you should explicitly write their names with VAR");
+     111           3 :       if(dernames.size()>0) dernames[0]="x";
+     112           3 :       if(dernames.size()>1) dernames[1]="y";
+     113           3 :       if(dernames.size()>2) dernames[2]="z";
+     114             :     }
+     115           5 :     if(dernames.size()!=gmin.size()) error("Size of VAR array should be the same as number of grid dimensions");
+     116             : 
+     117             :     // Create the grid and the value of the grid
+     118           5 :     createGridAndValue( "flat", ipbc, 0, gmin, gmax, gbin );
+     119             : 
+     120             :     // Read in stuff for function
+     121           5 :     log.printf("  evaluating function : %s\n",func.c_str());
+     122           5 :     log.printf("  with variables :");
+     123          10 :     for(unsigned i=0; i<dernames.size(); i++) log.printf(" %s",dernames[i].c_str());
+     124           5 :     log.printf("\n");
+     125           5 :     log.printf("  on %d", gbin[0]);
+     126           5 :     for(unsigned i=1; i<gbin.size(); ++i) log.printf(" by %d \n", gbin[i]);
+     127           5 :     log.printf(" grid of points between (%s", gmin[0].c_str() );
+     128           5 :     for(unsigned i=1; i<gmin.size(); ++i) log.printf(", %s", gmin[i].c_str() );
+     129           5 :     log.printf(") and (%s", gmax[0].c_str() );
+     130           5 :     for(unsigned i=1; i<gmax.size(); ++i) log.printf(", %s", gmax[i].c_str() );
+     131           5 :     log.printf(")\n");
+     132             : 
+     133           5 :     lepton::ParsedExpression pe=lepton::Parser::parse(func).optimize(leptonConstants);
+     134           5 :     log<<"  function as parsed by lepton: "<<pe<<"\n";
+     135           5 :     lepton::CompiledExpression expression=pe.createCompiledExpression();
+     136          10 :     for(auto &p: expression.getVariables()) {
+     137           5 :       if(std::find(dernames.begin(),dernames.end(),p)==dernames.end()) {
+     138           0 :         error("variable " + p + " is not defined");
+     139             :       }
+     140             :     }
+     141           5 :     log<<"  derivatives as computed by lepton:\n";
+     142           5 :     std::vector<lepton::CompiledExpression> expression_deriv( dernames.size() );
+     143          10 :     for(unsigned i=0; i<dernames.size(); i++) {
+     144          10 :       lepton::ParsedExpression pe=lepton::Parser::parse(func).differentiate(dernames[i]).optimize(leptonConstants);
+     145           5 :       log<<"    "<<pe<<"\n";
+     146           5 :       expression_deriv[i]=pe.createCompiledExpression();
+     147             :     }
+     148             :     // And finally calculate all the grid points
+     149           5 :     std::vector<double> dder( dernames.size() ), xx( dernames.size() ); Value* valout=getPntrToComponent(0);
+     150         115 :     for(unsigned index=0; index<valout->getNumberOfValues(); ++index) {
+     151         110 :       gridobject.getGridPointCoordinates( index, xx );
+     152         220 :       for(unsigned j=0; j<xx.size(); ++j) {
+     153             :         try {
+     154         110 :           expression.getVariableReference(dernames[j])=xx[j];
+     155           0 :         } catch(PLMD::lepton::Exception& exc) {
+     156             : // this is necessary since in some cases lepton things a variable is not present even though it is present
+     157             : // e.g. func=0*x
+     158           0 :         }
+     159             :       }
+     160         110 :       valout->set( index, expression.evaluate() );
+     161         220 :       for(unsigned k=0; k<xx.size(); ++k) {
+     162         220 :         for(unsigned j=0; j<xx.size(); ++j) {
+     163             :           try {
+     164         110 :             expression_deriv[k].getVariableReference(dernames[j])=xx[j];
+     165           0 :           } catch(PLMD::lepton::Exception& exc) {
+     166             : // this is necessary since in some cases lepton things a variable is not present even though it is present
+     167             : // e.g. func=0*x
+     168           0 :           }
+     169             :         }
+     170         110 :         valout->addGridDerivatives( index, k, expression_deriv[k].evaluate() );
+     171             :       }
+     172             :     }
+     173          15 :   } else {
+     174          12 :     std::string valuestr; parse("VALUE",valuestr);
+     175          12 :     std::string tstyle, filen; parse("FILE",filen);
+     176           6 :     if( filen.length()>0 ) {
+     177           6 :       std::size_t dot=filen.find_first_of(".");
+     178          12 :       if( dot!=std::string::npos ) tstyle=filen.substr(dot+1);
+     179           6 :       if( tstyle!="grid" ) error("can only read in grids using read value in setup");
+     180           6 :       log.printf("  reading function %s on grid from file %s \n", valuestr.c_str(), filen.c_str() );
+     181             :     }
+     182           6 :     IFile ifile; ifile.open(filen);
+     183           6 :     if( !ifile.FieldExist( valuestr ) ) error("could not find grid value in input file");
+     184           6 :     std::vector<std::string> fieldnames; ifile.scanFieldList( fieldnames );
+     185             : 
+     186             :     // Retrieve the names of the variables the grid is computed over
+     187             :     bool flatgrid=false;
+     188          54 :     for(unsigned i=0; i<fieldnames.size(); ++i) {
+     189          48 :       if( fieldnames[i].find("min_")!=std::string::npos ) flatgrid=true;
+     190          96 :       std::size_t dot = fieldnames[i].find_first_of("d" + valuestr + "_" );
+     191         114 :       if( fieldnames[i].find("d" + valuestr + "_")!=std::string::npos ) dernames.push_back( fieldnames[i].substr(dot+2+valuestr.length()) );
+     192             :     }
+     193           6 :     if( flatgrid && dernames.size()==0 ) error("could not find any derivatives for value " + valuestr + " in input file.  Header should contain at least columns with a name starting d" + valuestr + "_");
+     194             :     // Now get all the header data for the grid
+     195           6 :     std::vector<std::string> gmin( dernames.size() ), gmax( dernames.size() ); std::string pstring;
+     196           6 :     int gbin1; std::vector<unsigned> gbin( dernames.size() ); std::vector<bool> ipbc( dernames.size() );
+     197           6 :     if( !flatgrid ) {
+     198          12 :       ifile.scanField( "nbins", gbin1); gbin[0]=gbin1;
+     199          12 :       createGridAndValue( "fibonacci", ipbc, gbin[0], gmin, gmax, gbin );
+     200             :     } else {
+     201           0 :       for(unsigned i=0; i<dernames.size(); ++i) {
+     202           0 :         ifile.scanField( "min_" + dernames[i], gmin[i]);
+     203           0 :         ifile.scanField( "max_" + dernames[i], gmax[i]);
+     204           0 :         ifile.scanField( "periodic_" + dernames[i], pstring );
+     205           0 :         ifile.scanField( "nbins_" + dernames[i], gbin1); gbin[i]=gbin1;
+     206           0 :         if( pstring=="true" ) {
+     207           0 :           log.printf("   for periodic coordinate %s minimum is %s maximum is %s and number of bins is %d \n",dernames[i].c_str(),gmin[i].c_str(),gmax[i].c_str(),gbin[i]);
+     208             :           ipbc[i]=true;
+     209           0 :         } else if( pstring=="false" ) {
+     210           0 :           log.printf("   for coordinate %s minimum is %s maximum is %s and number of bins is %d \n",dernames[i].c_str(),gmin[i].c_str(),gmax[i].c_str(),gbin[i]);
+     211             :           ipbc[i]=false;
+     212           0 :         } else error("do not understand periodidicy of " + dernames[i] );
+     213             : 
+     214           0 :         bool hasder=ifile.FieldExist( "d" + valuestr + "_" + dernames[i] );
+     215           0 :         if( !hasder ) plumed_merror("missing derivatives from grid file");
+     216             :       }
+     217           0 :       createGridAndValue( "flat", ipbc, 0, gmin, gmax, gbin );
+     218             :     }
+     219             :     // And finally read all the grid points
+     220           6 :     Value* valout=getPntrToComponent(0);
+     221           6 :     std::vector<double> dder( dernames.size() ), xx( dernames.size() );
+     222        2106 :     for(unsigned i=0; i<valout->getNumberOfValues(); ++i) {
+     223        2100 :       double x, val; ifile.scanField( valuestr, val );
+     224        8400 :       for(unsigned j=0; j<dernames.size(); ++j) {
+     225        6300 :         ifile.scanField(dernames[j],x);
+     226        6300 :         if( !flatgrid ) {
+     227       12600 :           ifile.scanField("nbins", gbin1);
+     228             :         } else {
+     229           0 :           xx[j]=x+gridobject.getGridSpacing()[j]/2.0;
+     230           0 :           ifile.scanField( "min_" + dernames[j], gmin[j]);
+     231           0 :           ifile.scanField( "max_" + dernames[j], gmax[j]);
+     232           0 :           ifile.scanField( "nbins_" + dernames[j], gbin1);
+     233           0 :           ifile.scanField( "periodic_" + dernames[j], pstring );
+     234             :         }
+     235             :       }
+     236        8400 :       for(unsigned j=0; j<dernames.size(); ++j) ifile.scanField( "d" + valuestr + "_" + dernames[j], dder[j] );
+     237             : 
+     238        2100 :       unsigned index=gridobject.getIndex(xx); if( !flatgrid ) index=i;
+     239        2100 :       valout->set( index, val );
+     240        8400 :       for(unsigned j=0; j<dernames.size(); ++j) valout->addGridDerivatives( index, j, dder[j] );
+     241        2100 :       ifile.scanField();
+     242             :     }
+     243           6 :     ifile.close();
+     244           6 :   }
+     245          11 : }
+     246             : 
+     247          11 : void ReadGridInSetup::createGridAndValue( const std::string& gtype, const std::vector<bool>& ipbc, const unsigned& nfermi,
+     248             :     const std::vector<std::string>& gmin, const std::vector<std::string>& gmax,
+     249             :     const std::vector<unsigned>& gbin ) {
+     250          11 :   gridobject.setup( gtype, ipbc, nfermi, 0.0 ); std::vector<double> gspacing;
+     251          11 :   if( gtype=="flat" ) {
+     252           5 :     gridobject.setBounds( gmin, gmax, gbin, gspacing );
+     253             :     // Now create the value
+     254           5 :     std::vector<unsigned> shape( gridobject.getNbin(true) );
+     255           5 :     ActionWithValue::addValueWithDerivatives( shape ); setNotPeriodic();
+     256             :   } else {
+     257           6 :     std::vector<unsigned> shape( 3 ); shape[0]=gbin[0]; shape[1]=shape[2]=1;
+     258           6 :     ActionWithValue::addValueWithDerivatives( shape ); setNotPeriodic();
+     259             :   }
+     260          22 :   for(unsigned i=0; i<getNumberOfComponents(); ++i) {
+     261          11 :     getPntrToComponent(i)->setConstant();
+     262          11 :     getPntrToComponent(i)->setDerivativeIsZeroWhenValueIsZero();
+     263             :   }
+     264             :   // This ensures we set the flag to never active the action.  We can say we have atoms here as we don't need them
+     265             :   // to calculate the CV
+     266          11 :   setupConstantValues( true );
+     267          11 : }
+     268             : 
+     269          34 : unsigned ReadGridInSetup::getNumberOfDerivatives() {
+     270          34 :   return dernames.size();
+     271             : }
+     272             : 
+     273           3 : std::vector<std::string> ReadGridInSetup::getGridCoordinateNames() const {
+     274           3 :   return dernames;
+     275             : }
+     276             : 
+     277          12 : const GridCoordinatesObject& ReadGridInSetup::getGridCoordinatesObject() const {
+     278          12 :   return gridobject;
+     279             : }
+     280             : 
+     281             : }
+     282             : }
+     283             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/index-sort-f.html b/coverage/gridtools/index-sort-f.html new file mode 100644 index 000000000000..651f42bf02bf --- /dev/null +++ b/coverage/gridtools/index-sort-f.html @@ -0,0 +1,304 @@ + + + + + + + + LCOV - plumed test coverage - gridtools + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtoolsHitTotalCoverage
Test:plumed test coverageLines:1388152591.0 %
Date:2024-04-19 12:12:35Functions:11413982.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
EvaluateGridFunction.h +
85.7%85.7%
+
85.7 %6 / 70.0 %0 / 1
FindGridOptimum.cpp +
83.6%83.6%
+
83.6 %46 / 5560.0 %6 / 10
Gradient.cpp +
100.0%
+
100.0 %47 / 4766.7 %2 / 3
EvaluateFunctionOnGrid.cpp +
100.0%
+
100.0 %26 / 2666.7 %2 / 3
ConvertToFES.cpp +
100.0%
+
100.0 %21 / 2166.7 %2 / 3
PairEntropies.cpp +
100.0%
+
100.0 %25 / 2566.7 %2 / 3
PairEntropy.cpp +
100.0%
+
100.0 %31 / 3166.7 %2 / 3
MultiColvarDensity.cpp +
84.3%84.3%
+
84.3 %43 / 5166.7 %2 / 3
KLEntropy.cpp +
100.0%
+
100.0 %15 / 1566.7 %2 / 3
ReadGridInSetup.cpp +
81.8%81.8%
+
81.8 %121 / 14866.7 %6 / 9
RDF.cpp +
96.9%96.9%
+
96.9 %63 / 6575.0 %3 / 4
ActionWithGrid.cpp +
100.0%
+
100.0 %17 / 1780.0 %4 / 5
FunctionOfGrid.h +
97.0%97.0%
+
97.0 %96 / 9980.0 %16 / 20
DumpGrid.cpp +
98.2%98.2%
+
98.2 %111 / 11387.5 %7 / 8
InterpolateGrid.cpp +
93.4%93.4%
+
93.4 %71 / 7690.0 %9 / 10
KDE.cpp +
86.4%86.4%
+
86.4 %292 / 33894.7 %18 / 19
GridCoordinatesObject.cpp +
91.3%91.3%
+
91.3 %188 / 20695.0 %19 / 20
Interpolator.h +
100.0%
+
100.0 %1 / 1-0 / 0
Interpolator.cpp +
100.0%
+
100.0 %33 / 33100.0 %1 / 1
GridCoordinatesObject.h +
80.0%80.0%
+
80.0 %8 / 10100.0 %2 / 2
GridSearch.h +
95.0%95.0%
+
95.0 %38 / 40100.0 %3 / 3
EvaluateGridFunction.cpp +
88.1%88.1%
+
88.1 %89 / 101100.0 %6 / 6
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/index-sort-l.html b/coverage/gridtools/index-sort-l.html new file mode 100644 index 000000000000..7d20f681fd85 --- /dev/null +++ b/coverage/gridtools/index-sort-l.html @@ -0,0 +1,304 @@ + + + + + + + + LCOV - plumed test coverage - gridtools + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtoolsHitTotalCoverage
Test:plumed test coverageLines:1388152591.0 %
Date:2024-04-19 12:12:35Functions:11413982.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
GridCoordinatesObject.h +
80.0%80.0%
+
80.0 %8 / 10100.0 %2 / 2
ReadGridInSetup.cpp +
81.8%81.8%
+
81.8 %121 / 14866.7 %6 / 9
FindGridOptimum.cpp +
83.6%83.6%
+
83.6 %46 / 5560.0 %6 / 10
MultiColvarDensity.cpp +
84.3%84.3%
+
84.3 %43 / 5166.7 %2 / 3
EvaluateGridFunction.h +
85.7%85.7%
+
85.7 %6 / 70.0 %0 / 1
KDE.cpp +
86.4%86.4%
+
86.4 %292 / 33894.7 %18 / 19
EvaluateGridFunction.cpp +
88.1%88.1%
+
88.1 %89 / 101100.0 %6 / 6
GridCoordinatesObject.cpp +
91.3%91.3%
+
91.3 %188 / 20695.0 %19 / 20
InterpolateGrid.cpp +
93.4%93.4%
+
93.4 %71 / 7690.0 %9 / 10
GridSearch.h +
95.0%95.0%
+
95.0 %38 / 40100.0 %3 / 3
RDF.cpp +
96.9%96.9%
+
96.9 %63 / 6575.0 %3 / 4
FunctionOfGrid.h +
97.0%97.0%
+
97.0 %96 / 9980.0 %16 / 20
DumpGrid.cpp +
98.2%98.2%
+
98.2 %111 / 11387.5 %7 / 8
Interpolator.h +
100.0%
+
100.0 %1 / 1-0 / 0
KLEntropy.cpp +
100.0%
+
100.0 %15 / 1566.7 %2 / 3
ActionWithGrid.cpp +
100.0%
+
100.0 %17 / 1780.0 %4 / 5
ConvertToFES.cpp +
100.0%
+
100.0 %21 / 2166.7 %2 / 3
PairEntropies.cpp +
100.0%
+
100.0 %25 / 2566.7 %2 / 3
EvaluateFunctionOnGrid.cpp +
100.0%
+
100.0 %26 / 2666.7 %2 / 3
PairEntropy.cpp +
100.0%
+
100.0 %31 / 3166.7 %2 / 3
Interpolator.cpp +
100.0%
+
100.0 %33 / 33100.0 %1 / 1
Gradient.cpp +
100.0%
+
100.0 %47 / 4766.7 %2 / 3
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/index.html b/coverage/gridtools/index.html new file mode 100644 index 000000000000..5b23bf5eb0ed --- /dev/null +++ b/coverage/gridtools/index.html @@ -0,0 +1,304 @@ + + + + + + + + LCOV - plumed test coverage - gridtools + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtoolsHitTotalCoverage
Test:plumed test coverageLines:1388152591.0 %
Date:2024-04-19 12:12:35Functions:11413982.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
ActionWithGrid.cpp +
100.0%
+
100.0 %17 / 1780.0 %4 / 5
ConvertToFES.cpp +
100.0%
+
100.0 %21 / 2166.7 %2 / 3
DumpGrid.cpp +
98.2%98.2%
+
98.2 %111 / 11387.5 %7 / 8
EvaluateFunctionOnGrid.cpp +
100.0%
+
100.0 %26 / 2666.7 %2 / 3
EvaluateGridFunction.cpp +
88.1%88.1%
+
88.1 %89 / 101100.0 %6 / 6
EvaluateGridFunction.h +
85.7%85.7%
+
85.7 %6 / 70.0 %0 / 1
FindGridOptimum.cpp +
83.6%83.6%
+
83.6 %46 / 5560.0 %6 / 10
FunctionOfGrid.h +
97.0%97.0%
+
97.0 %96 / 9980.0 %16 / 20
Gradient.cpp +
100.0%
+
100.0 %47 / 4766.7 %2 / 3
GridCoordinatesObject.cpp +
91.3%91.3%
+
91.3 %188 / 20695.0 %19 / 20
GridCoordinatesObject.h +
80.0%80.0%
+
80.0 %8 / 10100.0 %2 / 2
GridSearch.h +
95.0%95.0%
+
95.0 %38 / 40100.0 %3 / 3
InterpolateGrid.cpp +
93.4%93.4%
+
93.4 %71 / 7690.0 %9 / 10
Interpolator.cpp +
100.0%
+
100.0 %33 / 33100.0 %1 / 1
Interpolator.h +
100.0%
+
100.0 %1 / 1-0 / 0
KDE.cpp +
86.4%86.4%
+
86.4 %292 / 33894.7 %18 / 19
KLEntropy.cpp +
100.0%
+
100.0 %15 / 1566.7 %2 / 3
MultiColvarDensity.cpp +
84.3%84.3%
+
84.3 %43 / 5166.7 %2 / 3
PairEntropies.cpp +
100.0%
+
100.0 %25 / 2566.7 %2 / 3
PairEntropy.cpp +
100.0%
+
100.0 %31 / 3166.7 %2 / 3
RDF.cpp +
96.9%96.9%
+
96.9 %63 / 6575.0 %3 / 4
ReadGridInSetup.cpp +
81.8%81.8%
+
81.8 %121 / 14866.7 %6 / 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 000000000000..06a5a181a09c --- /dev/null +++ b/coverage/index-sort-f.html @@ -0,0 +1,534 @@ + + + + + + + + LCOV - plumed test coverage + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top levelHitTotalCoverage
Test:plumed test coverageLines:520136151584.6 %
Date:2024-04-19 12:12:35Functions:5757729578.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Directory Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
config +
41.9%41.9%
+
41.9 %57 / 13642.0 %21 / 50
wrapper +
50.0%50.0%
+
50.0 %250 / 50056.7 %144 / 254
piv +
71.8%71.8%
+
71.8 %427 / 59560.0 %3 / 5
multicolvar +
85.3%85.3%
+
85.3 %504 / 59163.3 %31 / 49
ves +
82.0%82.0%
+
82.0 %5891 / 718065.6 %444 / 677
fourier +
86.9%86.9%
+
86.9 %86 / 9966.7 %6 / 9
setup +
97.6%97.6%
+
97.6 %82 / 8466.7 %6 / 9
isdb +
76.9%76.9%
+
76.9 %8783 / 1142869.4 %163 / 235
analysis +
96.6%96.6%
+
96.6 %597 / 61869.4 %50 / 72
pamm +
92.3%92.3%
+
92.3 %144 / 15670.0 %7 / 10
clusters +
98.3%98.3%
+
98.3 %226 / 23072.1 %31 / 43
small_vector +
86.7%86.7%
+
86.7 %91 / 10572.1 %31 / 43
volumes +
62.8%62.8%
+
62.8 %478 / 76172.3 %47 / 65
tools +
79.9%79.9%
+
79.9 %5702 / 713872.4 %1137 / 1571
generic +
95.2%95.2%
+
95.2 %1555 / 163473.1 %147 / 201
envsim +
94.8%94.8%
+
94.8 %184 / 19475.0 %3 / 4
s2cm +
91.5%91.5%
+
91.5 %151 / 16575.0 %6 / 8
membranefusion +
88.1%88.1%
+
88.1 %453 / 51475.0 %9 / 12
refdist +
91.0%91.0%
+
91.0 %305 / 33575.0 %21 / 28
vatom +
94.7%94.7%
+
94.7 %358 / 37876.2 %16 / 21
contour +
93.5%93.5%
+
93.5 %417 / 44677.4 %48 / 62
funnel +
98.0%98.0%
+
98.0 %247 / 25277.8 %7 / 9
crystdistrib +
92.0%92.0%
+
92.0 %515 / 56078.1 %25 / 32
dimred +
98.0%98.0%
+
98.0 %494 / 50478.4 %29 / 37
colvar +
91.7%91.7%
+
91.7 %2696 / 293979.1 %216 / 273
adjmat +
95.4%95.4%
+
95.4 %1582 / 165979.3 %226 / 285
bias +
91.5%91.5%
+
91.5 %2443 / 266979.5 %97 / 122
pytorch +
89.9%89.9%
+
89.9 %62 / 6980.0 %4 / 5
secondarystructure +
96.9%96.9%
+
96.9 %468 / 48380.0 %16 / 20
maze +
85.2%85.2%
+
85.2 %654 / 76880.2 %65 / 81
cltools +
70.5%70.5%
+
70.5 %1598 / 226780.5 %128 / 159
symfunc +
91.2%91.2%
+
91.2 %781 / 85680.6 %50 / 62
sasa +
82.0%82.0%
+
82.0 %996 / 121580.8 %21 / 26
fisst +
79.6%79.6%
+
79.6 %319 / 40180.8 %21 / 26
gridtools +
91.0%91.0%
+
91.0 %1388 / 152582.0 %114 / 139
annfunc +
97.1%97.1%
+
97.1 %133 / 13783.3 %5 / 6
valtools +
93.1%93.1%
+
93.1 %230 / 24783.3 %20 / 24
mapping +
96.6%96.6%
+
96.6 %777 / 80483.9 %47 / 56
function +
88.4%88.4%
+
88.4 %1305 / 147684.8 %335 / 395
eds +
92.8%92.8%
+
92.8 %451 / 48685.0 %17 / 20
logmfd +
87.9%87.9%
+
87.9 %326 / 37192.3 %12 / 13
opes +
96.1%96.1%
+
96.1 %2143 / 222992.3 %108 / 117
core +
88.6%88.6%
+
88.6 %4451 / 502592.9 %1733 / 1865
drr +
94.5%94.5%
+
94.5 %1201 / 127194.7 %89 / 94
main +
80.0%80.0%
+
80.0 %12 / 15100.0 %1 / 1
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/index-sort-l.html b/coverage/index-sort-l.html new file mode 100644 index 000000000000..7f647bbc1dc7 --- /dev/null +++ b/coverage/index-sort-l.html @@ -0,0 +1,534 @@ + + + + + + + + LCOV - plumed test coverage + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top levelHitTotalCoverage
Test:plumed test coverageLines:520136151584.6 %
Date:2024-04-19 12:12:35Functions:5757729578.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Directory Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
config +
41.9%41.9%
+
41.9 %57 / 13642.0 %21 / 50
wrapper +
50.0%50.0%
+
50.0 %250 / 50056.7 %144 / 254
volumes +
62.8%62.8%
+
62.8 %478 / 76172.3 %47 / 65
cltools +
70.5%70.5%
+
70.5 %1598 / 226780.5 %128 / 159
piv +
71.8%71.8%
+
71.8 %427 / 59560.0 %3 / 5
isdb +
76.9%76.9%
+
76.9 %8783 / 1142869.4 %163 / 235
fisst +
79.6%79.6%
+
79.6 %319 / 40180.8 %21 / 26
tools +
79.9%79.9%
+
79.9 %5702 / 713872.4 %1137 / 1571
main +
80.0%80.0%
+
80.0 %12 / 15100.0 %1 / 1
sasa +
82.0%82.0%
+
82.0 %996 / 121580.8 %21 / 26
ves +
82.0%82.0%
+
82.0 %5891 / 718065.6 %444 / 677
maze +
85.2%85.2%
+
85.2 %654 / 76880.2 %65 / 81
multicolvar +
85.3%85.3%
+
85.3 %504 / 59163.3 %31 / 49
small_vector +
86.7%86.7%
+
86.7 %91 / 10572.1 %31 / 43
fourier +
86.9%86.9%
+
86.9 %86 / 9966.7 %6 / 9
logmfd +
87.9%87.9%
+
87.9 %326 / 37192.3 %12 / 13
membranefusion +
88.1%88.1%
+
88.1 %453 / 51475.0 %9 / 12
function +
88.4%88.4%
+
88.4 %1305 / 147684.8 %335 / 395
core +
88.6%88.6%
+
88.6 %4451 / 502592.9 %1733 / 1865
pytorch +
89.9%89.9%
+
89.9 %62 / 6980.0 %4 / 5
refdist +
91.0%91.0%
+
91.0 %305 / 33575.0 %21 / 28
gridtools +
91.0%91.0%
+
91.0 %1388 / 152582.0 %114 / 139
symfunc +
91.2%91.2%
+
91.2 %781 / 85680.6 %50 / 62
s2cm +
91.5%91.5%
+
91.5 %151 / 16575.0 %6 / 8
bias +
91.5%91.5%
+
91.5 %2443 / 266979.5 %97 / 122
colvar +
91.7%91.7%
+
91.7 %2696 / 293979.1 %216 / 273
crystdistrib +
92.0%92.0%
+
92.0 %515 / 56078.1 %25 / 32
pamm +
92.3%92.3%
+
92.3 %144 / 15670.0 %7 / 10
eds +
92.8%92.8%
+
92.8 %451 / 48685.0 %17 / 20
valtools +
93.1%93.1%
+
93.1 %230 / 24783.3 %20 / 24
contour +
93.5%93.5%
+
93.5 %417 / 44677.4 %48 / 62
drr +
94.5%94.5%
+
94.5 %1201 / 127194.7 %89 / 94
vatom +
94.7%94.7%
+
94.7 %358 / 37876.2 %16 / 21
envsim +
94.8%94.8%
+
94.8 %184 / 19475.0 %3 / 4
generic +
95.2%95.2%
+
95.2 %1555 / 163473.1 %147 / 201
adjmat +
95.4%95.4%
+
95.4 %1582 / 165979.3 %226 / 285
opes +
96.1%96.1%
+
96.1 %2143 / 222992.3 %108 / 117
analysis +
96.6%96.6%
+
96.6 %597 / 61869.4 %50 / 72
mapping +
96.6%96.6%
+
96.6 %777 / 80483.9 %47 / 56
secondarystructure +
96.9%96.9%
+
96.9 %468 / 48380.0 %16 / 20
annfunc +
97.1%97.1%
+
97.1 %133 / 13783.3 %5 / 6
setup +
97.6%97.6%
+
97.6 %82 / 8466.7 %6 / 9
funnel +
98.0%98.0%
+
98.0 %247 / 25277.8 %7 / 9
dimred +
98.0%98.0%
+
98.0 %494 / 50478.4 %29 / 37
clusters +
98.3%98.3%
+
98.3 %226 / 23072.1 %31 / 43
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/index.html b/coverage/index.html new file mode 100644 index 000000000000..e861116abfd6 --- /dev/null +++ b/coverage/index.html @@ -0,0 +1,534 @@ + + + + + + + + LCOV - plumed test coverage + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top levelHitTotalCoverage
Test:plumed test coverageLines:520136151584.6 %
Date:2024-04-19 12:12:35Functions:5757729578.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Directory Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
adjmat +
95.4%95.4%
+
95.4 %1582 / 165979.3 %226 / 285
analysis +
96.6%96.6%
+
96.6 %597 / 61869.4 %50 / 72
annfunc +
97.1%97.1%
+
97.1 %133 / 13783.3 %5 / 6
bias +
91.5%91.5%
+
91.5 %2443 / 266979.5 %97 / 122
cltools +
70.5%70.5%
+
70.5 %1598 / 226780.5 %128 / 159
clusters +
98.3%98.3%
+
98.3 %226 / 23072.1 %31 / 43
colvar +
91.7%91.7%
+
91.7 %2696 / 293979.1 %216 / 273
config +
41.9%41.9%
+
41.9 %57 / 13642.0 %21 / 50
contour +
93.5%93.5%
+
93.5 %417 / 44677.4 %48 / 62
core +
88.6%88.6%
+
88.6 %4451 / 502592.9 %1733 / 1865
crystdistrib +
92.0%92.0%
+
92.0 %515 / 56078.1 %25 / 32
dimred +
98.0%98.0%
+
98.0 %494 / 50478.4 %29 / 37
drr +
94.5%94.5%
+
94.5 %1201 / 127194.7 %89 / 94
eds +
92.8%92.8%
+
92.8 %451 / 48685.0 %17 / 20
envsim +
94.8%94.8%
+
94.8 %184 / 19475.0 %3 / 4
fisst +
79.6%79.6%
+
79.6 %319 / 40180.8 %21 / 26
fourier +
86.9%86.9%
+
86.9 %86 / 9966.7 %6 / 9
function +
88.4%88.4%
+
88.4 %1305 / 147684.8 %335 / 395
funnel +
98.0%98.0%
+
98.0 %247 / 25277.8 %7 / 9
generic +
95.2%95.2%
+
95.2 %1555 / 163473.1 %147 / 201
gridtools +
91.0%91.0%
+
91.0 %1388 / 152582.0 %114 / 139
isdb +
76.9%76.9%
+
76.9 %8783 / 1142869.4 %163 / 235
logmfd +
87.9%87.9%
+
87.9 %326 / 37192.3 %12 / 13
main +
80.0%80.0%
+
80.0 %12 / 15100.0 %1 / 1
mapping +
96.6%96.6%
+
96.6 %777 / 80483.9 %47 / 56
maze +
85.2%85.2%
+
85.2 %654 / 76880.2 %65 / 81
membranefusion +
88.1%88.1%
+
88.1 %453 / 51475.0 %9 / 12
multicolvar +
85.3%85.3%
+
85.3 %504 / 59163.3 %31 / 49
opes +
96.1%96.1%
+
96.1 %2143 / 222992.3 %108 / 117
pamm +
92.3%92.3%
+
92.3 %144 / 15670.0 %7 / 10
piv +
71.8%71.8%
+
71.8 %427 / 59560.0 %3 / 5
pytorch +
89.9%89.9%
+
89.9 %62 / 6980.0 %4 / 5
refdist +
91.0%91.0%
+
91.0 %305 / 33575.0 %21 / 28
s2cm +
91.5%91.5%
+
91.5 %151 / 16575.0 %6 / 8
sasa +
82.0%82.0%
+
82.0 %996 / 121580.8 %21 / 26
secondarystructure +
96.9%96.9%
+
96.9 %468 / 48380.0 %16 / 20
setup +
97.6%97.6%
+
97.6 %82 / 8466.7 %6 / 9
small_vector +
86.7%86.7%
+
86.7 %91 / 10572.1 %31 / 43
symfunc +
91.2%91.2%
+
91.2 %781 / 85680.6 %50 / 62
tools +
79.9%79.9%
+
79.9 %5702 / 713872.4 %1137 / 1571
valtools +
93.1%93.1%
+
93.1 %230 / 24783.3 %20 / 24
vatom +
94.7%94.7%
+
94.7 %358 / 37876.2 %16 / 21
ves +
82.0%82.0%
+
82.0 %5891 / 718065.6 %444 / 677
volumes +
62.8%62.8%
+
62.8 %478 / 76172.3 %47 / 65
wrapper +
50.0%50.0%
+
50.0 %250 / 50056.7 %144 / 254
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/CS2Backbone.cpp.func-sort-c.html b/coverage/isdb/CS2Backbone.cpp.func-sort-c.html new file mode 100644 index 000000000000..56af37bc99dc --- /dev/null +++ b/coverage/isdb/CS2Backbone.cpp.func-sort-c.html @@ -0,0 +1,165 @@ + + + + + + + + LCOV - plumed test coverage - isdb/CS2Backbone.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - CS2Backbone.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:91696794.7 %
Date:2024-04-19 12:12:35Functions:222395.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb11CS2BackboneC2ERKNS_13ActionOptionsE0
_ZN4PLMD4isdb11CS2Backbone10init_ringsERKNS_3PDBE18
_ZN4PLMD4isdb11CS2Backbone10init_typesERKNS_3PDBE18
_ZN4PLMD4isdb11CS2Backbone13update_neighbEv18
_ZN4PLMD4isdb11CS2Backbone23compute_ring_parametersEv18
_ZN4PLMD4isdb11CS2Backbone6updateEv18
_ZN4PLMD4isdb11CS2Backbone9calculateEv18
_ZN4PLMD4isdb11CS2BackboneC1ERKNS_13ActionOptionsE18
_ZN4PLMD4isdb13CS2BackboneDB5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEd18
_ZN4PLMD4isdb11CS2Backbone16registerKeywordsERNS_8KeywordsE20
_ZN4PLMD4isdb11CS2Backbone7init_csERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_RKNS_3PDBE108
_ZN4PLMD4isdb11CS2Backbone8RingInfoC2Ev360
_ZN4PLMD4isdb13CS2BackboneDB6assignEPdRKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EEd10368
_ZN4PLMD4isdb11CS2Backbone13ChemicalShiftC2Ev10602
_ZN4PLMD4isdb11CS2Backbone16side_chain_atomsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE10602
_ZN4PLMD4isdb13CS2BackboneDB4kindERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE10926
_ZN4PLMD4isdb13CS2BackboneDB9atom_kindERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE10926
_ZN4PLMD4isdb13CS2BackboneDB5splitERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEc20430
_ZN4PLMD4isdb13CS2BackboneDB5splitERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEcRSt6vectorIS7_SaIS7_EE20430
_ZN4PLMD4isdb11CS2Backbone9frag2enumERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE31806
_ZN4PLMD4isdb11CS2Backbone5isSP2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_47016
_ZN4PLMD4isdb11CS2Backbone10is_chi1_cxERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_145728
_ZN4PLMD4isdb11CS2Backbone14xdist_name_mapERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3599784
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/CS2Backbone.cpp.func.html b/coverage/isdb/CS2Backbone.cpp.func.html new file mode 100644 index 000000000000..ab2ca1ec0e05 --- /dev/null +++ b/coverage/isdb/CS2Backbone.cpp.func.html @@ -0,0 +1,165 @@ + + + + + + + + LCOV - plumed test coverage - isdb/CS2Backbone.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - CS2Backbone.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:91696794.7 %
Date:2024-04-19 12:12:35Functions:222395.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb11CS2Backbone10init_ringsERKNS_3PDBE18
_ZN4PLMD4isdb11CS2Backbone10init_typesERKNS_3PDBE18
_ZN4PLMD4isdb11CS2Backbone10is_chi1_cxERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_145728
_ZN4PLMD4isdb11CS2Backbone13ChemicalShiftC2Ev10602
_ZN4PLMD4isdb11CS2Backbone13update_neighbEv18
_ZN4PLMD4isdb11CS2Backbone14xdist_name_mapERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3599784
_ZN4PLMD4isdb11CS2Backbone16registerKeywordsERNS_8KeywordsE20
_ZN4PLMD4isdb11CS2Backbone16side_chain_atomsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE10602
_ZN4PLMD4isdb11CS2Backbone23compute_ring_parametersEv18
_ZN4PLMD4isdb11CS2Backbone5isSP2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_47016
_ZN4PLMD4isdb11CS2Backbone6updateEv18
_ZN4PLMD4isdb11CS2Backbone7init_csERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_RKNS_3PDBE108
_ZN4PLMD4isdb11CS2Backbone8RingInfoC2Ev360
_ZN4PLMD4isdb11CS2Backbone9calculateEv18
_ZN4PLMD4isdb11CS2Backbone9frag2enumERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE31806
_ZN4PLMD4isdb11CS2BackboneC1ERKNS_13ActionOptionsE18
_ZN4PLMD4isdb11CS2BackboneC2ERKNS_13ActionOptionsE0
_ZN4PLMD4isdb13CS2BackboneDB4kindERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE10926
_ZN4PLMD4isdb13CS2BackboneDB5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEd18
_ZN4PLMD4isdb13CS2BackboneDB5splitERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEc20430
_ZN4PLMD4isdb13CS2BackboneDB5splitERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEcRSt6vectorIS7_SaIS7_EE20430
_ZN4PLMD4isdb13CS2BackboneDB6assignEPdRKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EEd10368
_ZN4PLMD4isdb13CS2BackboneDB9atom_kindERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE10926
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/CS2Backbone.cpp.gcov.html b/coverage/isdb/CS2Backbone.cpp.gcov.html new file mode 100644 index 000000000000..296e655a1e21 --- /dev/null +++ b/coverage/isdb/CS2Backbone.cpp.gcov.html @@ -0,0 +1,1921 @@ + + + + + + + + LCOV - plumed test coverage - isdb/CS2Backbone.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - CS2Backbone.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:91696794.7 %
Date:2024-04-19 12:12:35Functions:222395.7 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb7Caliber14get_sigma_meanEdRKSt6vectorIdSaIdEE0
_ZN4PLMD4isdb7Caliber18do_regression_zeroERKSt6vectorIdSaIdEE0
_ZN4PLMD4isdb7CaliberC2ERKNS_13ActionOptionsE0
_ZN4PLMD4isdb7CaliberC1ERKNS_13ActionOptionsE4
_ZN4PLMD4isdb7Caliber16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD4isdb7Caliber17replica_averagingEdRSt6vectorIdSaIdEE2004
_ZN4PLMD4isdb7Caliber9calculateEv2004
_ZN4PLMD4isdb7Caliber9getSplineEj2004
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/Caliber.cpp.func.html b/coverage/isdb/Caliber.cpp.func.html new file mode 100644 index 000000000000..3155ab5ce95f --- /dev/null +++ b/coverage/isdb/Caliber.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - isdb/Caliber.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - Caliber.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11614778.9 %
Date:2024-04-19 12:12:35Functions:5862.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb7Caliber14get_sigma_meanEdRKSt6vectorIdSaIdEE0
_ZN4PLMD4isdb7Caliber16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD4isdb7Caliber17replica_averagingEdRSt6vectorIdSaIdEE2004
_ZN4PLMD4isdb7Caliber18do_regression_zeroERKSt6vectorIdSaIdEE0
_ZN4PLMD4isdb7Caliber9calculateEv2004
_ZN4PLMD4isdb7Caliber9getSplineEj2004
_ZN4PLMD4isdb7CaliberC1ERKNS_13ActionOptionsE4
_ZN4PLMD4isdb7CaliberC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/Caliber.cpp.gcov.html b/coverage/isdb/Caliber.cpp.gcov.html new file mode 100644 index 000000000000..0bc0861c6b97 --- /dev/null +++ b/coverage/isdb/Caliber.cpp.gcov.html @@ -0,0 +1,424 @@ + + + + + + + + LCOV - plumed test coverage - isdb/Caliber.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - Caliber.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11614778.9 %
Date:2024-04-19 12:12:35Functions:5862.5 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2018-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "bias/Bias.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "core/PlumedMain.h"
+      25             : #include "tools/Communicator.h"
+      26             : #include <fstream>
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace isdb {
+      30             : 
+      31             : //+PLUMEDOC ISDB_BIAS CALIBER
+      32             : /*
+      33             : Add a time-dependent, harmonic restraint on one or more variables.
+      34             : 
+      35             : This allows implementing a maximum caliber restraint on one or more experimental time series by replica-averaged restrained simulations.
+      36             : See \cite Capelli:2018jt .
+      37             : 
+      38             : The time resolved experiments are read from a text file and intermediate values are obtained by splines.
+      39             : 
+      40             : \par Examples
+      41             : 
+      42             : In the following example a restraint is applied on the time evolution of a saxs spectrum
+      43             : 
+      44             : \plumedfile
+      45             : MOLINFO STRUCTURE=first.pdb
+      46             : 
+      47             : # Define saxs variable
+      48             : SAXS ...
+      49             : LABEL=saxs
+      50             : ATOMISTIC
+      51             : ATOMS=1-436
+      52             : QVALUE1=0.02 # Q-value at which calculate the scattering
+      53             : QVALUE2=0.0808
+      54             : QVALUE3=0.1264
+      55             : QVALUE4=0.1568
+      56             : QVALUE5=0.172
+      57             : QVALUE6=0.1872
+      58             : QVALUE7=0.2176
+      59             : QVALUE8=0.2328
+      60             : QVALUE9=0.248
+      61             : QVALUE10=0.2632
+      62             : QVALUE11=0.2936
+      63             : QVALUE12=0.3088
+      64             : QVALUE13=0.324
+      65             : QVALUE14=0.3544
+      66             : QVALUE15=0.4
+      67             : ... SAXS
+      68             : 
+      69             : 
+      70             : #define the caliber restraint
+      71             : CALIBER ...
+      72             :   ARG=(saxs\.q_.*)
+      73             :   FILE=expsaxs.dat
+      74             :   KAPPA=10
+      75             :   LABEL=cal0
+      76             :   STRIDE=10
+      77             :   REGRES_ZERO=200
+      78             :   AVERAGING=200
+      79             : ... CALIBER
+      80             : \endplumedfile
+      81             : 
+      82             : In particular the file expsaxs.dat contains the time traces for the 15 intensities at the selected scattering lengths, organized as time, q_1, etc.
+      83             : The strength of the bias is automatically evaluated from the standard error of the mean over AVERAGING steps and multiplied by KAPPA. This is useful when working with multiple experimental data
+      84             : Because \ref SAXS is usually defined in a manner that is irrespective of a scaling factor the scaling is evaluated from a linear fit every REGRES_ZERO step. Alternatively it can be given as a fixed constant as SCALE.
+      85             : The bias is here applied every tenth step.
+      86             : 
+      87             : */
+      88             : //+ENDPLUMEDOC
+      89             : 
+      90             : 
+      91             : class Caliber : public bias::Bias {
+      92             : public:
+      93             :   explicit Caliber(const ActionOptions&);
+      94             :   void calculate();
+      95             :   static void registerKeywords( Keywords& keys );
+      96             : private:
+      97             :   std::vector<double> time;
+      98             :   std::vector< std::vector<double> > var;
+      99             :   std::vector< std::vector<double> > dvar;
+     100             :   double   mult;
+     101             :   double   scale_;
+     102             :   bool     master;
+     103             :   unsigned replica_;
+     104             :   unsigned nrep_;
+     105             :   // scale and offset regression
+     106             :   bool doregres_zero_;
+     107             :   int  nregres_zero_;
+     108             :   // force constant
+     109             :   unsigned optsigmamean_stride_;
+     110             :   std::vector<double> sigma_mean2_;
+     111             :   std::vector< std::vector<double> > sigma_mean2_last_;
+     112             :   std::vector<Value*> x0comp;
+     113             :   std::vector<Value*> kcomp;
+     114             :   std::vector<Value*> mcomp;
+     115             :   Value* valueScale;
+     116             : 
+     117             :   void get_sigma_mean(const double fact, const std::vector<double> &mean);
+     118             :   void replica_averaging(const double fact, std::vector<double> &mean);
+     119             :   double getSpline(const unsigned iarg);
+     120             :   void do_regression_zero(const std::vector<double> &mean);
+     121             : };
+     122             : 
+     123             : PLUMED_REGISTER_ACTION(Caliber,"CALIBER")
+     124             : 
+     125           6 : void Caliber::registerKeywords( Keywords& keys ) {
+     126           6 :   Bias::registerKeywords(keys);
+     127           6 :   keys.use("ARG");
+     128          12 :   keys.addFlag("NOENSEMBLE",false,"don't perform any replica-averaging");
+     129          12 :   keys.add("compulsory","FILE","the name of the file containing the time-resolved values");
+     130          12 :   keys.add("compulsory","KAPPA","a force constant, this can be use to scale a constant estimated on-the-fly using AVERAGING");
+     131          12 :   keys.add("optional","AVERAGING", "Stride for calculation of the optimum kappa, if 0 only KAPPA is used.");
+     132          12 :   keys.add("compulsory","TSCALE","1.0","Apply a time scaling on the experimental time scale");
+     133          12 :   keys.add("compulsory","SCALE","1.0","Apply a constant scaling on the data provided as arguments");
+     134          12 :   keys.add("optional","REGRES_ZERO","stride for regression with zero offset");
+     135          12 :   keys.addOutputComponent("x0","default","the instantaneous value of the center of the potential");
+     136          12 :   keys.addOutputComponent("mean","default","the current average value of the calculated observable");
+     137          12 :   keys.addOutputComponent("kappa","default","the current force constant");
+     138          12 :   keys.addOutputComponent("scale","REGRES_ZERO","the current scaling constant");
+     139           6 : }
+     140             : 
+     141           4 : Caliber::Caliber(const ActionOptions&ao):
+     142             :   PLUMED_BIAS_INIT(ao),
+     143           4 :   mult(0),
+     144           4 :   scale_(1),
+     145           4 :   doregres_zero_(false),
+     146           4 :   nregres_zero_(0),
+     147           4 :   optsigmamean_stride_(0)
+     148             : {
+     149           8 :   parse("KAPPA",mult);
+     150             :   std::string filename;
+     151           8 :   parse("FILE",filename);
+     152           4 :   if( filename.length()==0 ) error("No external variable file was specified");
+     153           4 :   unsigned averaging=0;
+     154           4 :   parse("AVERAGING", averaging);
+     155           4 :   if(averaging>0) optsigmamean_stride_ = averaging;
+     156           4 :   double tscale=1.0;
+     157           4 :   parse("TSCALE", tscale);
+     158           4 :   if(tscale<=0.) error("The time scale factor must be greater than 0.");
+     159           4 :   parse("SCALE", scale_);
+     160           4 :   if(scale_==0.) error("The time scale factor cannot be 0.");
+     161             :   // regression with zero intercept
+     162           4 :   parse("REGRES_ZERO", nregres_zero_);
+     163           4 :   if(nregres_zero_>0) {
+     164             :     // set flag
+     165           0 :     doregres_zero_=true;
+     166           0 :     log.printf("  doing regression with zero intercept with stride: %d\n", nregres_zero_);
+     167             :   }
+     168             : 
+     169             : 
+     170           4 :   bool noensemble = false;
+     171           4 :   parseFlag("NOENSEMBLE", noensemble);
+     172             : 
+     173           4 :   checkRead();
+     174             : 
+     175             :   // set up replica stuff
+     176           4 :   master = (comm.Get_rank()==0);
+     177           4 :   if(master) {
+     178           4 :     nrep_    = multi_sim_comm.Get_size();
+     179           4 :     replica_ = multi_sim_comm.Get_rank();
+     180           4 :     if(noensemble) nrep_ = 1;
+     181             :   } else {
+     182           0 :     nrep_    = 0;
+     183           0 :     replica_ = 0;
+     184             :   }
+     185           4 :   comm.Sum(&nrep_,1);
+     186           4 :   comm.Sum(&replica_,1);
+     187             : 
+     188             :   const unsigned narg = getNumberOfArguments();
+     189           4 :   sigma_mean2_.resize(narg,1);
+     190           4 :   sigma_mean2_last_.resize(narg);
+     191           8 :   for(unsigned j=0; j<narg; j++) sigma_mean2_last_[j].push_back(0.000001);
+     192             : 
+     193           4 :   log.printf("  Time resolved data from file %s\n",filename.c_str());
+     194           4 :   std::ifstream varfile(filename.c_str());
+     195           4 :   if(varfile.fail()) error("Cannot open "+filename);
+     196           4 :   var.resize(narg);
+     197           4 :   dvar.resize(narg);
+     198        2012 :   while (!varfile.eof()) {
+     199             :     double tempT, tempVar;
+     200             :     varfile >> tempT;
+     201        2008 :     time.push_back(tempT/tscale);
+     202        4016 :     for(unsigned i=0; i<narg; i++) {
+     203             :       varfile >> tempVar;
+     204        2008 :       var[i].push_back(tempVar);
+     205             :     }
+     206             :   }
+     207           4 :   varfile.close();
+     208             : 
+     209           4 :   const double deltat = time[1] - time[0];
+     210           8 :   for(unsigned i=0; i<narg; i++) {
+     211        2012 :     for(unsigned j=0; j<var[i].size(); j++) {
+     212        2008 :       if(j==0) dvar[i].push_back((var[i][j+1] - var[i][j])/(deltat));
+     213        2004 :       else if(j==var[i].size()-1) dvar[i].push_back((var[i][j] - var[i][j-1])/(deltat));
+     214        2000 :       else dvar[i].push_back((var[i][j+1] - var[i][j-1])/(2.*deltat));
+     215             :     }
+     216             :   }
+     217             : 
+     218           8 :   for(unsigned i=0; i<narg; i++) {
+     219           4 :     std::string num; Tools::convert(i,num);
+     220          12 :     addComponent("x0-"+num); componentIsNotPeriodic("x0-"+num); x0comp.push_back(getPntrToComponent("x0-"+num));
+     221          12 :     addComponent("kappa-"+num); componentIsNotPeriodic("kappa-"+num); kcomp.push_back(getPntrToComponent("kappa-"+num));
+     222          12 :     addComponent("mean-"+num); componentIsNotPeriodic("mean-"+num); mcomp.push_back(getPntrToComponent("mean-"+num));
+     223             :   }
+     224             : 
+     225           4 :   if(doregres_zero_) {
+     226           0 :     addComponent("scale");
+     227           0 :     componentIsNotPeriodic("scale");
+     228           0 :     valueScale=getPntrToComponent("scale");
+     229             :   }
+     230             : 
+     231           8 :   log<<"  Bibliography "<<plumed.cite("Capelli, Tiana, Camilloni, J Chem Phys, 148, 184114");
+     232           8 : }
+     233             : 
+     234           0 : void Caliber::get_sigma_mean(const double fact, const std::vector<double> &mean)
+     235             : {
+     236           0 :   const unsigned narg = getNumberOfArguments();
+     237           0 :   const double dnrep = static_cast<double>(nrep_);
+     238             : 
+     239           0 :   if(sigma_mean2_last_[0].size()==optsigmamean_stride_) for(unsigned i=0; i<narg; ++i) sigma_mean2_last_[i].erase(sigma_mean2_last_[i].begin());
+     240           0 :   std::vector<double> sigma_mean2_now(narg,0);
+     241           0 :   if(master) {
+     242           0 :     for(unsigned i=0; i<narg; ++i) {
+     243           0 :       double tmp = getArgument(i)-mean[i];
+     244           0 :       sigma_mean2_now[i] = fact*tmp*tmp;
+     245             :     }
+     246           0 :     if(nrep_>1) multi_sim_comm.Sum(&sigma_mean2_now[0], narg);
+     247             :   }
+     248           0 :   comm.Sum(&sigma_mean2_now[0], narg);
+     249             : 
+     250           0 :   for(unsigned i=0; i<narg; ++i) {
+     251           0 :     sigma_mean2_last_[i].push_back(sigma_mean2_now[i]/dnrep);
+     252           0 :     sigma_mean2_[i] = *max_element(sigma_mean2_last_[i].begin(), sigma_mean2_last_[i].end());
+     253             :   }
+     254           0 : }
+     255             : 
+     256        2004 : void Caliber::replica_averaging(const double fact, std::vector<double> &mean)
+     257             : {
+     258        2004 :   const unsigned narg = getNumberOfArguments();
+     259        2004 :   if(master) {
+     260        4008 :     for(unsigned i=0; i<narg; ++i) mean[i] = fact*getArgument(i);
+     261        2004 :     if(nrep_>1) multi_sim_comm.Sum(&mean[0], narg);
+     262             :   }
+     263        2004 :   comm.Sum(&mean[0], narg);
+     264        2004 : }
+     265             : 
+     266        2004 : double Caliber::getSpline(const unsigned iarg)
+     267             : {
+     268        2004 :   const double deltat = time[1] - time[0];
+     269        2004 :   const int tindex = static_cast<int>(getTime()/deltat);
+     270             : 
+     271             :   unsigned start, end;
+     272        2004 :   start=tindex;
+     273        2004 :   if(tindex+1<var[iarg].size()) end=tindex+2;
+     274           0 :   else end=var[iarg].size();
+     275             : 
+     276             :   double value=0;
+     277        6012 :   for(unsigned ipoint=start; ipoint<end; ++ipoint) {
+     278        4008 :     double grid=var[iarg][ipoint];
+     279        4008 :     double dder=dvar[iarg][ipoint];
+     280             :     double yy=0.;
+     281        4008 :     if(std::abs(grid)>0.0000001) yy=-dder/grid;
+     282             : 
+     283             :     int x0=1;
+     284        4008 :     if(ipoint==tindex) x0=0;
+     285             : 
+     286        4008 :     double X=std::abs((getTime()-time[tindex])/deltat-(double)x0);
+     287        4008 :     double X2=X*X;
+     288        4008 :     double X3=X2*X;
+     289        4008 :     double C=(1.0-3.0*X2+2.0*X3) - (x0?-1.0:1.0)*yy*(X-2.0*X2+X3)*deltat;
+     290             : 
+     291        4008 :     value+=grid*C;
+     292             :   }
+     293        2004 :   return value;
+     294             : }
+     295             : 
+     296           0 : void Caliber::do_regression_zero(const std::vector<double> &mean)
+     297             : {
+     298             : // parameters[i] = scale_ * mean[i]: find scale_ with linear regression
+     299             :   double num = 0.0;
+     300             :   double den = 0.0;
+     301           0 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     302           0 :     num += mean[i] * getSpline(i);
+     303           0 :     den += mean[i] * mean[i];
+     304             :   }
+     305           0 :   if(den>0) {
+     306           0 :     scale_ = num / den;
+     307             :   } else {
+     308           0 :     scale_ = 1.0;
+     309             :   }
+     310           0 : }
+     311             : 
+     312        2004 : void Caliber::calculate()
+     313             : {
+     314        2004 :   const unsigned narg = getNumberOfArguments();
+     315        2004 :   const double dnrep = static_cast<double>(nrep_);
+     316        2004 :   const double fact = 1.0/dnrep;
+     317             : 
+     318        2004 :   std::vector<double> mean(narg,0);
+     319        2004 :   std::vector<double> dmean_x(narg,fact);
+     320        2004 :   replica_averaging(fact, mean);
+     321        2004 :   if(optsigmamean_stride_>0) get_sigma_mean(fact, mean);
+     322             : 
+     323             :   // in case of regression with zero intercept, calculate scale
+     324        2004 :   if(doregres_zero_ && getStep()%nregres_zero_==0) do_regression_zero(mean);
+     325             : 
+     326             :   double ene=0;
+     327        4008 :   for(unsigned i=0; i<narg; ++i) {
+     328        2004 :     const double x0 = getSpline(i);
+     329        2004 :     const double kappa = mult*dnrep/sigma_mean2_[i];
+     330        2004 :     const double cv=difference(i,x0,scale_*mean[i]);
+     331        2004 :     const double f=-kappa*cv*dmean_x[i]/scale_;
+     332        2004 :     setOutputForce(i,f);
+     333        2004 :     ene+=0.5*kappa*cv*cv;
+     334        2004 :     x0comp[i]->set(x0);
+     335        2004 :     kcomp[i]->set(kappa);
+     336        2004 :     mcomp[i]->set(mean[i]);
+     337             :   }
+     338             : 
+     339        2004 :   if(doregres_zero_) valueScale->set(scale_);
+     340             : 
+     341        2004 :   setBias(ene);
+     342        2004 : }
+     343             : 
+     344             : }
+     345             : }
+     346             : 
+     347             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/EMMI.cpp.func-sort-c.html b/coverage/isdb/EMMI.cpp.func-sort-c.html new file mode 100644 index 000000000000..e045511b3863 --- /dev/null +++ b/coverage/isdb/EMMI.cpp.func-sort-c.html @@ -0,0 +1,229 @@ + + + + + + + + LCOV - plumed test coverage - isdb/EMMI.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - EMMI.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:58977975.6 %
Date:2024-04-19 12:12:35Functions:293974.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb4EMMI11read_statusEv0
_ZN4PLMD4isdb4EMMI11scaleEnergyEd0
_ZN4PLMD4isdb4EMMI12doMonteCarloEv0
_ZN4PLMD4isdb4EMMI12doRegressionEv0
_ZN4PLMD4isdb4EMMI13get_annealingEx0
_ZN4PLMD4isdb4EMMI15read_exp_errorsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD4isdb4EMMI17read_exp_overlapsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD4isdb4EMMI19write_model_overlapEx0
_ZN4PLMD4isdb4EMMI8doAcceptEddd0
_ZN4PLMD4isdb4EMMIC2ERKNS_13ActionOptionsE0
_ZN4PLMD4isdb4EMMI29calculateNumericalDerivativesEPNS_15ActionWithValueE9
_ZN4PLMD4isdb4EMMI14setDerivativesEv20
_ZN4PLMD4isdb4EMMI17turnOnDerivativesEv20
_ZN4PLMD4isdb4EMMI22calculate_useful_stuffEd20
_ZN4PLMD4isdb4EMMI9get_GMM_dERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE20
_ZN4PLMD4isdb4EMMI9get_GMM_mERSt6vectorINS_10AtomNumberESaIS3_EE20
_ZN4PLMD4isdb4EMMIC1ERKNS_13ActionOptionsE20
_ZN4PLMD4isdb4EMMI16registerKeywordsERNS_8KeywordsE22
_ZN4PLMD4isdb4EMMI12lockRequestsEv30
_ZN4PLMD4isdb4EMMI14unlockRequestsEv30
_ZN4PLMD4isdb4EMMI5applyEv30
_ZN4PLMD4isdb4EMMI7prepareEv30
_ZN4PLMD4isdb4EMMI10get_medianERSt6vectorIdSaIdEE40
_ZN4PLMD4isdb4EMMI22getNumberOfDerivativesEv72
_ZN4PLMD4isdb4EMMI11check_GMM_dERKNS_13VectorGenericILj6EEEd1962
_ZN4PLMD4isdb4EMMI16get_self_overlapEj1962
_ZN4PLMD4isdb4EMMI18calculate_MarginalEv5451
_ZN4PLMD4isdb4EMMI18calculate_OutliersEv5451
_ZN4PLMD4isdb4EMMI15calculate_GaussEv5463
_ZN4PLMD4isdb4EMMI12print_statusEx10904
_ZN4PLMD4isdb4EMMI20update_neighbor_listEv16355
_ZN4PLMD4isdb4EMMI11get_weightsERdS2_S2_16365
_ZN4PLMD4isdb4EMMI17calculate_overlapEv16365
_ZN4PLMD4isdb4EMMI17setBoxDerivativesEPNS_5ValueERKNS_13TensorGenericILj3ELj3EEE16365
_ZN4PLMD4isdb4EMMI9calculateEv16365
_ZN4PLMD4isdb4EMMI21get_prefactor_inverseERKNS_13VectorGenericILj6EEES5_ddRS3_S6_1621458
_ZN4PLMD4isdb4EMMI11get_overlapERKNS_13VectorGenericILj3EEES5_dRKNS2_ILj6EEERS3_3732816
_ZN4PLMD4isdb4EMMI19setAtomsDerivativesEPNS_5ValueEjRKNS_13VectorGenericILj3EEE9844626
_ZN4PLMD4isdb4EMMI15get_exp_overlapERKNS_13VectorGenericILj3EEES5_RKNS2_ILj6EEE59085036
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/EMMI.cpp.func.html b/coverage/isdb/EMMI.cpp.func.html new file mode 100644 index 000000000000..0f443671129f --- /dev/null +++ b/coverage/isdb/EMMI.cpp.func.html @@ -0,0 +1,229 @@ + + + + + + + + LCOV - plumed test coverage - isdb/EMMI.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - EMMI.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:58977975.6 %
Date:2024-04-19 12:12:35Functions:293974.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb4EMMI10get_medianERSt6vectorIdSaIdEE40
_ZN4PLMD4isdb4EMMI11check_GMM_dERKNS_13VectorGenericILj6EEEd1962
_ZN4PLMD4isdb4EMMI11get_overlapERKNS_13VectorGenericILj3EEES5_dRKNS2_ILj6EEERS3_3732816
_ZN4PLMD4isdb4EMMI11get_weightsERdS2_S2_16365
_ZN4PLMD4isdb4EMMI11read_statusEv0
_ZN4PLMD4isdb4EMMI11scaleEnergyEd0
_ZN4PLMD4isdb4EMMI12doMonteCarloEv0
_ZN4PLMD4isdb4EMMI12doRegressionEv0
_ZN4PLMD4isdb4EMMI12lockRequestsEv30
_ZN4PLMD4isdb4EMMI12print_statusEx10904
_ZN4PLMD4isdb4EMMI13get_annealingEx0
_ZN4PLMD4isdb4EMMI14setDerivativesEv20
_ZN4PLMD4isdb4EMMI14unlockRequestsEv30
_ZN4PLMD4isdb4EMMI15calculate_GaussEv5463
_ZN4PLMD4isdb4EMMI15get_exp_overlapERKNS_13VectorGenericILj3EEES5_RKNS2_ILj6EEE59085036
_ZN4PLMD4isdb4EMMI15read_exp_errorsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD4isdb4EMMI16get_self_overlapEj1962
_ZN4PLMD4isdb4EMMI16registerKeywordsERNS_8KeywordsE22
_ZN4PLMD4isdb4EMMI17calculate_overlapEv16365
_ZN4PLMD4isdb4EMMI17read_exp_overlapsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD4isdb4EMMI17setBoxDerivativesEPNS_5ValueERKNS_13TensorGenericILj3ELj3EEE16365
_ZN4PLMD4isdb4EMMI17turnOnDerivativesEv20
_ZN4PLMD4isdb4EMMI18calculate_MarginalEv5451
_ZN4PLMD4isdb4EMMI18calculate_OutliersEv5451
_ZN4PLMD4isdb4EMMI19setAtomsDerivativesEPNS_5ValueEjRKNS_13VectorGenericILj3EEE9844626
_ZN4PLMD4isdb4EMMI19write_model_overlapEx0
_ZN4PLMD4isdb4EMMI20update_neighbor_listEv16355
_ZN4PLMD4isdb4EMMI21get_prefactor_inverseERKNS_13VectorGenericILj6EEES5_ddRS3_S6_1621458
_ZN4PLMD4isdb4EMMI22calculate_useful_stuffEd20
_ZN4PLMD4isdb4EMMI22getNumberOfDerivativesEv72
_ZN4PLMD4isdb4EMMI29calculateNumericalDerivativesEPNS_15ActionWithValueE9
_ZN4PLMD4isdb4EMMI5applyEv30
_ZN4PLMD4isdb4EMMI7prepareEv30
_ZN4PLMD4isdb4EMMI8doAcceptEddd0
_ZN4PLMD4isdb4EMMI9calculateEv16365
_ZN4PLMD4isdb4EMMI9get_GMM_dERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE20
_ZN4PLMD4isdb4EMMI9get_GMM_mERSt6vectorINS_10AtomNumberESaIS3_EE20
_ZN4PLMD4isdb4EMMIC1ERKNS_13ActionOptionsE20
_ZN4PLMD4isdb4EMMIC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/EMMI.cpp.gcov.html b/coverage/isdb/EMMI.cpp.gcov.html new file mode 100644 index 000000000000..d1d231f7242b --- /dev/null +++ b/coverage/isdb/EMMI.cpp.gcov.html @@ -0,0 +1,1824 @@ + + + + + + + + LCOV - plumed test coverage - isdb/EMMI.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - EMMI.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:58977975.6 %
Date:2024-04-19 12:12:35Functions:293974.4 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb7EMMIVOX10get_medianESt6vectorIdSaIdEE0
_ZN4PLMD4isdb7EMMIVOX10update_gpuEv0
_ZN4PLMD4isdb7EMMIVOX11get_overlapERKNS_13VectorGenericILj3EEES5_RKNS2_ILj5EEES8_d0
_ZN4PLMD4isdb7EMMIVOX11prepare_gpuEv0
_ZN4PLMD4isdb7EMMIVOX11read_statusEv0
_ZN4PLMD4isdb7EMMIVOX12get_exp_dataERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD4isdb7EMMIVOX12print_statusEl0
_ZN4PLMD4isdb7EMMIVOX14calculate_corrEv0
_ZN4PLMD4isdb7EMMIVOX14calculate_fmodEv0
_ZN4PLMD4isdb7EMMIVOX15calculate_scoreEv0
_ZN4PLMD4isdb7EMMIVOX15get_Model_paramERSt6vectorINS_10AtomNumberESaIS3_EE0
_ZN4PLMD4isdb7EMMIVOX17doMonteCarloBfactEv0
_ZN4PLMD4isdb7EMMIVOX18do_neighbor_sphereEv0
_ZN4PLMD4isdb7EMMIVOX18get_close_residuesEv0
_ZN4PLMD4isdb7EMMIVOX18initialize_BfactorEd0
_ZN4PLMD4isdb7EMMIVOX18push_auxiliary_gpuEv0
_ZN4PLMD4isdb7EMMIVOX19write_model_densityEl0
_ZN4PLMD4isdb7EMMIVOX20update_neighbor_listEv0
_ZN4PLMD4isdb7EMMIVOX21get_auxiliary_vectorsEv0
_ZN4PLMD4isdb7EMMIVOX22update_neighbor_sphereEv0
_ZN4PLMD4isdb7EMMIVOX7prepareEv0
_ZN4PLMD4isdb7EMMIVOX8doAcceptEddd0
_ZN4PLMD4isdb7EMMIVOX9calculateEv0
_ZN4PLMD4isdb7EMMIVOXC1ERKNS_13ActionOptionsE0
_ZN4PLMD4isdb7EMMIVOXC2ERKNS_13ActionOptionsE0
_ZN4PLMD4isdb7EMMIVOX16registerKeywordsERNS_8KeywordsE2
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/EMMIVox.cpp.func.html b/coverage/isdb/EMMIVox.cpp.func.html new file mode 100644 index 000000000000..44bc3619a843 --- /dev/null +++ b/coverage/isdb/EMMIVox.cpp.func.html @@ -0,0 +1,177 @@ + + + + + + + + LCOV - plumed test coverage - isdb/EMMIVox.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - EMMIVox.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:366485.6 %
Date:2024-04-19 12:12:35Functions:1263.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb7EMMIVOX10get_medianESt6vectorIdSaIdEE0
_ZN4PLMD4isdb7EMMIVOX10update_gpuEv0
_ZN4PLMD4isdb7EMMIVOX11get_overlapERKNS_13VectorGenericILj3EEES5_RKNS2_ILj5EEES8_d0
_ZN4PLMD4isdb7EMMIVOX11prepare_gpuEv0
_ZN4PLMD4isdb7EMMIVOX11read_statusEv0
_ZN4PLMD4isdb7EMMIVOX12get_exp_dataERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD4isdb7EMMIVOX12print_statusEl0
_ZN4PLMD4isdb7EMMIVOX14calculate_corrEv0
_ZN4PLMD4isdb7EMMIVOX14calculate_fmodEv0
_ZN4PLMD4isdb7EMMIVOX15calculate_scoreEv0
_ZN4PLMD4isdb7EMMIVOX15get_Model_paramERSt6vectorINS_10AtomNumberESaIS3_EE0
_ZN4PLMD4isdb7EMMIVOX16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD4isdb7EMMIVOX17doMonteCarloBfactEv0
_ZN4PLMD4isdb7EMMIVOX18do_neighbor_sphereEv0
_ZN4PLMD4isdb7EMMIVOX18get_close_residuesEv0
_ZN4PLMD4isdb7EMMIVOX18initialize_BfactorEd0
_ZN4PLMD4isdb7EMMIVOX18push_auxiliary_gpuEv0
_ZN4PLMD4isdb7EMMIVOX19write_model_densityEl0
_ZN4PLMD4isdb7EMMIVOX20update_neighbor_listEv0
_ZN4PLMD4isdb7EMMIVOX21get_auxiliary_vectorsEv0
_ZN4PLMD4isdb7EMMIVOX22update_neighbor_sphereEv0
_ZN4PLMD4isdb7EMMIVOX7prepareEv0
_ZN4PLMD4isdb7EMMIVOX8doAcceptEddd0
_ZN4PLMD4isdb7EMMIVOX9calculateEv0
_ZN4PLMD4isdb7EMMIVOXC1ERKNS_13ActionOptionsE0
_ZN4PLMD4isdb7EMMIVOXC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/EMMIVox.cpp.gcov.html b/coverage/isdb/EMMIVox.cpp.gcov.html new file mode 100644 index 000000000000..c4ff8eb548c0 --- /dev/null +++ b/coverage/isdb/EMMIVox.cpp.gcov.html @@ -0,0 +1,1655 @@ + + + + + + + + LCOV - plumed test coverage - isdb/EMMIVox.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - EMMIVox.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:366485.6 %
Date:2024-04-19 12:12:35Functions:1263.8 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #ifdef __PLUMED_HAS_LIBTORCH
+      24             : #include "colvar/Colvar.h"
+      25             : #include "core/ActionRegister.h"
+      26             : #include "core/PlumedMain.h"
+      27             : #include "tools/Communicator.h"
+      28             : #include "tools/Matrix.h"
+      29             : #include "core/GenericMolInfo.h"
+      30             : #include "core/ActionSet.h"
+      31             : #include "tools/File.h"
+      32             : #include "tools/OpenMP.h"
+      33             : #include <string>
+      34             : #include <cmath>
+      35             : #include <map>
+      36             : #include <numeric>
+      37             : #include <ctime>
+      38             : #include "tools/Random.h"
+      39             : 
+      40             : #include <torch/torch.h>
+      41             : #include <torch/script.h>
+      42             : 
+      43             : #ifndef M_PI
+      44             : #define M_PI           3.14159265358979323846
+      45             : #endif
+      46             : 
+      47             : namespace PLMD {
+      48             : namespace isdb {
+      49             : 
+      50             : //+PLUMEDOC ISDB_COLVAR EMMIVOX
+      51             : /*
+      52             : Bayesian single-structure and ensemble refinement with cryo-EM maps.
+      53             : 
+      54             : This action implements the Bayesian approach for single-structure and ensemble refinement from cryo-EM maps introduced <a href="https://www.biorxiv.org/content/10.1101/2023.10.18.562710v1">here</a>.
+      55             : EMMIVox does not require fitting the cryo-EM map with a Gaussian Mixture Model, as done in \ref EMMI, but uses directly the voxels in the deposited map.
+      56             : 
+      57             : When run in single-replica mode, this action allows atomistic, flexible refinement (and B-factors inference) of an individual structure into a density map.
+      58             : A coarse-grained forward model can also be used in combination with the MARTINI force field.
+      59             : Combined with a multi-replica framework (such as the -multi option in GROMACS), the user can model an ensemble of structures using
+      60             : the Metainference approach \cite Bonomi:2016ip . The approach can be used to model continous dynamics of flexible regions as well as semi-ordered waters, lipids, and ions.
+      61             : 
+      62             : \warning
+      63             :     To use EMMIVOX, PLUMED must be linked against the LibTorch library as described \ref ISDB "here"
+      64             : 
+      65             : \par Examples
+      66             : 
+      67             : Complete tutorials for single-structure and ensemble refinement can be found <a href="https://github.com/COSBlab/EMMIVox">here</a>.
+      68             : 
+      69             : */
+      70             : //+ENDPLUMEDOC
+      71             : 
+      72             : class EMMIVOX : public Colvar {
+      73             : 
+      74             : private:
+      75             : 
+      76             : // temperature in kbt
+      77             :   double kbt_;
+      78             : // model - atom types
+      79             :   std::vector<unsigned> Model_type_;
+      80             : // model - list of atom sigmas - one per atom type
+      81             :   std::vector<Vector5d> Model_s_;
+      82             : // model - list of atom weights - one per atom type
+      83             :   std::vector<Vector5d> Model_w_;
+      84             : // model - map between residue/chain IDs and list of atoms
+      85             :   std::map< std::pair<unsigned,std::string>, std::vector<unsigned> > Model_resmap_;
+      86             : // model - list of residue/chain IDs per atom
+      87             :   std::vector< std::pair<unsigned,std::string> > Model_res_;
+      88             : // model - list of neighboring voxels per atom
+      89             :   std::vector< std::vector<unsigned> > Model_nb_;
+      90             : // model - map between residue/chain ID and bfactor
+      91             :   std::map< std::pair<unsigned, std::string>, double> Model_b_;
+      92             : // model - global list of residue/chain IDs
+      93             :   std::vector< std::pair<unsigned,std::string> > Model_rlist_;
+      94             : // model density
+      95             :   std::vector<double> ovmd_;
+      96             : 
+      97             : // data map - voxel position
+      98             :   std::vector<Vector> Map_m_;
+      99             : // data map - density
+     100             :   std::vector<double> ovdd_;
+     101             : // data map - error
+     102             :   std::vector<double> exp_err_;
+     103             : 
+     104             : // derivatives
+     105             :   std::vector<Vector> ovmd_der_;
+     106             :   std::vector<Vector> atom_der_;
+     107             :   std::vector<double> score_der_;
+     108             : // constants
+     109             :   double inv_sqrt2_, sqrt2_pi_, inv_pi2_;
+     110             :   std::vector<Vector5d> pref_;
+     111             :   std::vector<Vector5d> invs2_;
+     112             :   std::vector<Vector5d> cfact_;
+     113             :   std::vector<double> cut_;
+     114             : // metainference
+     115             :   unsigned nrep_;
+     116             :   unsigned replica_;
+     117             :   std::vector<double> ismin_;
+     118             : // neighbor list
+     119             :   double nl_dist_cutoff_;
+     120             :   double nl_gauss_cutoff_;
+     121             :   unsigned nl_stride_;
+     122             :   bool first_time_;
+     123             :   std::vector< std::pair<unsigned,unsigned> > nl_;
+     124             :   std::vector< std::pair<unsigned,unsigned> > ns_;
+     125             :   std::vector<Vector> refpos_;
+     126             : // averaging
+     127             :   bool no_aver_;
+     128             : // correlation;
+     129             :   bool do_corr_;
+     130             : // Monte Carlo stuff
+     131             :   Random   random_;
+     132             :   // Scale and Offset
+     133             :   double scale_;
+     134             :   double offset_;
+     135             : // Bfact Monte Carlo
+     136             :   double   dbfact_;
+     137             :   double   bfactmin_;
+     138             :   double   bfactmax_;
+     139             :   double   bfactsig_;
+     140             :   bool     bfactnoc_;
+     141             :   bool     bfactread_;
+     142             :   int      MCBstride_;
+     143             :   double   MCBaccept_;
+     144             :   double   MCBtrials_;
+     145             : // residue neighbor list
+     146             :   std::vector< std::vector<unsigned> > nl_res_;
+     147             :   bool bfactemin_;
+     148             : // Martini scattering factors
+     149             :   bool martini_;
+     150             :   // status stuff
+     151             :   unsigned int statusstride_;
+     152             :   std::string       statusfilename_;
+     153             :   OFile        statusfile_;
+     154             :   bool         first_status_;
+     155             :   // total energy and virial
+     156             :   double ene_;
+     157             :   Tensor virial_;
+     158             :   double eps_;
+     159             :   // model density file
+     160             :   unsigned int mapstride_;
+     161             :   std::string       mapfilename_;
+     162             :   // Libtorch stuff
+     163             :   bool gpu_;
+     164             :   torch::Tensor ovmd_gpu_;
+     165             :   torch::Tensor ovmd_der_gpu_;
+     166             :   torch::Tensor ismin_gpu_;
+     167             :   torch::Tensor ovdd_gpu_;
+     168             :   torch::Tensor Map_m_gpu_;
+     169             :   torch::Tensor pref_gpu_;
+     170             :   torch::Tensor invs2_gpu_;
+     171             :   torch::Tensor nl_id_gpu_;
+     172             :   torch::Tensor nl_im_gpu_;
+     173             :   torch::Tensor pref_nl_gpu_;
+     174             :   torch::Tensor invs2_nl_gpu_;
+     175             :   torch::Tensor Map_m_nl_gpu_;
+     176             :   torch::DeviceType device_t_;
+     177             : //
+     178             : // write file with model density
+     179             :   void write_model_density(long int step);
+     180             : // get median of vector
+     181             :   double get_median(std::vector<double> v);
+     182             : // read and write status
+     183             :   void read_status();
+     184             :   void print_status(long int step);
+     185             : // accept or reject
+     186             :   bool doAccept(double oldE, double newE, double kbt);
+     187             : // vector of close residues
+     188             :   void get_close_residues();
+     189             : // do MonteCarlo for Bfactor
+     190             :   void doMonteCarloBfact();
+     191             : // calculate model parameters
+     192             :   std::vector<double> get_Model_param(std::vector<AtomNumber> &atoms);
+     193             : // read data file
+     194             :   void get_exp_data(const std::string &datafile);
+     195             : // auxiliary methods
+     196             :   void prepare_gpu();
+     197             :   void initialize_Bfactor(double reso);
+     198             :   void get_auxiliary_vectors();
+     199             :   void push_auxiliary_gpu();
+     200             : // calculate overlap between two Gaussians
+     201             :   double get_overlap(const Vector &d_m, const Vector &m_m,
+     202             :                      const Vector5d &cfact, const Vector5d &m_s, double bfact);
+     203             : // update the neighbor list
+     204             :   void update_neighbor_list();
+     205             : // update data on device
+     206             :   void update_gpu();
+     207             : // update the neighbor sphere
+     208             :   void update_neighbor_sphere();
+     209             :   bool do_neighbor_sphere();
+     210             : // calculate forward model and score on device
+     211             :   void calculate_fmod();
+     212             :   void calculate_score();
+     213             : // calculate correlation
+     214             :   void calculate_corr();
+     215             : 
+     216             : public:
+     217             :   static void registerKeywords( Keywords& keys );
+     218             :   explicit EMMIVOX(const ActionOptions&);
+     219             : // active methods:
+     220             :   void prepare() override;
+     221             :   void calculate() override;
+     222             : };
+     223             : 
+     224             : PLUMED_REGISTER_ACTION(EMMIVOX,"EMMIVOX")
+     225             : 
+     226           2 : void EMMIVOX::registerKeywords( Keywords& keys ) {
+     227           2 :   Colvar::registerKeywords( keys );
+     228           4 :   keys.add("atoms","ATOMS","atoms used in the calculation of the density map, typically all heavy atoms");
+     229           4 :   keys.add("compulsory","DATA_FILE","file with cryo-EM map");
+     230           4 :   keys.add("compulsory","RESOLUTION", "cryo-EM map resolution");
+     231           4 :   keys.add("compulsory","NORM_DENSITY","integral of experimental density");
+     232           4 :   keys.add("compulsory","WRITE_STRIDE","stride for writing status file");
+     233           4 :   keys.add("optional","NL_DIST_CUTOFF","neighbor list distance cutoff");
+     234           4 :   keys.add("optional","NL_GAUSS_CUTOFF","neighbor list Gaussian sigma cutoff");
+     235           4 :   keys.add("optional","NL_STRIDE","neighbor list update frequency");
+     236           4 :   keys.add("optional","SIGMA_MIN","minimum density error");
+     237           4 :   keys.add("optional","DBFACT","Bfactor MC step");
+     238           4 :   keys.add("optional","BFACT_MAX","Bfactor maximum value");
+     239           4 :   keys.add("optional","MCBFACT_STRIDE", "Bfactor MC stride");
+     240           4 :   keys.add("optional","BFACT_SIGMA","Bfactor sigma prior");
+     241           4 :   keys.add("optional","STATUS_FILE","write a file with all the data useful for restart");
+     242           4 :   keys.add("optional","SCALE","scale factor");
+     243           4 :   keys.add("optional","OFFSET","offset");
+     244           4 :   keys.add("optional","TEMP","temperature");
+     245           4 :   keys.add("optional","WRITE_MAP","file with model density");
+     246           4 :   keys.add("optional","WRITE_MAP_STRIDE","stride for writing model density to file");
+     247           4 :   keys.addFlag("NO_AVER",false,"no ensemble averaging in multi-replica mode");
+     248           4 :   keys.addFlag("CORRELATION",false,"calculate correlation coefficient");
+     249           4 :   keys.addFlag("GPU",false,"calculate EMMIVOX on GPU with Libtorch");
+     250           4 :   keys.addFlag("BFACT_NOCHAIN",false,"Do not use chain ID for Bfactor MC");
+     251           4 :   keys.addFlag("BFACT_READ",false,"Read Bfactor on RESTART (automatic with DBFACT>0)");
+     252           4 :   keys.addFlag("BFACT_MINIMIZE",false,"Accept only moves that decrease energy");
+     253           4 :   keys.addFlag("MARTINI",false,"Use Martini scattering factors");
+     254           2 :   componentsAreNotOptional(keys);
+     255           4 :   keys.addOutputComponent("scoreb","default","Bayesian score");
+     256           4 :   keys.addOutputComponent("scale", "default","scale factor");
+     257           4 :   keys.addOutputComponent("offset","default","offset");
+     258           4 :   keys.addOutputComponent("accB",  "default", "Bfactor MC acceptance");
+     259           4 :   keys.addOutputComponent("kbt",   "default", "temperature in energy unit");
+     260           4 :   keys.addOutputComponent("corr",  "CORRELATION", "correlation coefficient");
+     261           2 : }
+     262             : 
+     263           0 : EMMIVOX::EMMIVOX(const ActionOptions&ao):
+     264             :   PLUMED_COLVAR_INIT(ao),
+     265           0 :   nl_dist_cutoff_(1.0), nl_gauss_cutoff_(3.0), nl_stride_(50),
+     266           0 :   first_time_(true), no_aver_(false), do_corr_(false),
+     267           0 :   scale_(1.), offset_(0.),
+     268           0 :   dbfact_(0.0), bfactmin_(0.05), bfactmax_(5.0),
+     269           0 :   bfactsig_(0.1), bfactnoc_(false), bfactread_(false),
+     270           0 :   MCBstride_(1), MCBaccept_(0.), MCBtrials_(0.), bfactemin_(false),
+     271           0 :   martini_(false), statusstride_(0), first_status_(true),
+     272           0 :   eps_(0.0001), mapstride_(0), gpu_(false)
+     273             : {
+     274             :   // set constants
+     275           0 :   inv_sqrt2_ = 1.0/sqrt(2.0);
+     276           0 :   sqrt2_pi_  = sqrt(2.0 / M_PI);
+     277           0 :   inv_pi2_   = 0.5 / M_PI / M_PI;
+     278             : 
+     279             :   // list of atoms
+     280             :   std::vector<AtomNumber> atoms;
+     281           0 :   parseAtomList("ATOMS", atoms);
+     282             : 
+     283             :   // file with experimental cryo-EM map
+     284             :   std::string datafile;
+     285           0 :   parse("DATA_FILE", datafile);
+     286             : 
+     287             :   // neighbor list cutoffs
+     288           0 :   parse("NL_DIST_CUTOFF",nl_dist_cutoff_);
+     289           0 :   parse("NL_GAUSS_CUTOFF",nl_gauss_cutoff_);
+     290             :   // checks
+     291           0 :   if(nl_dist_cutoff_<=0. && nl_gauss_cutoff_<=0.) error("You must specify either NL_DIST_CUTOFF or NL_GAUSS_CUTOFF or both");
+     292           0 :   if(nl_gauss_cutoff_<=0.) nl_gauss_cutoff_ = 1.0e+10;
+     293           0 :   if(nl_dist_cutoff_<=0.) nl_dist_cutoff_ = 1.0e+10;
+     294             :   // neighbor list update stride
+     295           0 :   parse("NL_STRIDE",nl_stride_);
+     296           0 :   if(nl_stride_<=0) error("NL_STRIDE must be explicitly specified and positive");
+     297             : 
+     298             :   // minimum value for error
+     299           0 :   double sigma_min = 0.2;
+     300           0 :   parse("SIGMA_MIN", sigma_min);
+     301           0 :   if(sigma_min<0.) error("SIGMA_MIN must be greater or equal to zero");
+     302             : 
+     303             :   // status file parameters
+     304           0 :   parse("WRITE_STRIDE", statusstride_);
+     305           0 :   if(statusstride_<=0) error("you must specify a positive WRITE_STRIDE");
+     306           0 :   parse("STATUS_FILE",  statusfilename_);
+     307           0 :   if(statusfilename_=="") statusfilename_ = "EMMIStatus"+getLabel();
+     308             : 
+     309             :   // integral of the experimetal density
+     310             :   double norm_d;
+     311           0 :   parse("NORM_DENSITY", norm_d);
+     312             : 
+     313             :   // temperature
+     314           0 :   kbt_ = getkBT();
+     315             : 
+     316             :   // scale and offset
+     317           0 :   parse("SCALE", scale_);
+     318           0 :   parse("OFFSET",offset_);
+     319             : 
+     320             :   // B-factors MC
+     321           0 :   parse("DBFACT",dbfact_);
+     322             :   // read Bfactors
+     323           0 :   parseFlag("BFACT_READ",bfactread_);
+     324             :   // do not use chains
+     325           0 :   parseFlag("BFACT_NOCHAIN",bfactnoc_);
+     326             :   // other parameters
+     327           0 :   if(dbfact_>0.) {
+     328           0 :     parse("MCBFACT_STRIDE",MCBstride_);
+     329           0 :     parse("BFACT_MAX",bfactmax_);
+     330           0 :     parse("BFACT_SIGMA",bfactsig_);
+     331           0 :     parseFlag("BFACT_MINIMIZE",bfactemin_);
+     332             :     // checks
+     333           0 :     if(MCBstride_<=0) error("you must specify a positive MCBFACT_STRIDE");
+     334           0 :     if(bfactmax_<=bfactmin_) error("you must specify a positive BFACT_MAX");
+     335           0 :     if(MCBstride_%nl_stride_!=0) error("MCBFACT_STRIDE must be multiple of NL_STRIDE");
+     336           0 :     if(bfactsig_<=0.) error("you must specify a positive BFACT_SIGMA");
+     337             :   }
+     338             : 
+     339             :   // read map resolution
+     340             :   double reso;
+     341           0 :   parse("RESOLUTION", reso);
+     342           0 :   if(reso<=0.) error("RESOLUTION must be strictly positive");
+     343             : 
+     344             :   // averaging or not
+     345           0 :   parseFlag("NO_AVER",no_aver_);
+     346             : 
+     347             :   // calculate correlation coefficient
+     348           0 :   parseFlag("CORRELATION",do_corr_);
+     349             : 
+     350             :   // write density file
+     351           0 :   parse("WRITE_MAP_STRIDE", mapstride_);
+     352           0 :   parse("WRITE_MAP", mapfilename_);
+     353           0 :   if(mapstride_>0 && mapfilename_=="") error("With WRITE_MAP_STRIDE you must specify WRITE_MAP");
+     354             : 
+     355             :   // use GPU?
+     356           0 :   parseFlag("GPU",gpu_);
+     357             :   // set device
+     358           0 :   if (gpu_ && torch::cuda::is_available()) {
+     359           0 :     device_t_ = torch::kCUDA;
+     360             :   } else {
+     361           0 :     device_t_ = torch::kCPU;
+     362           0 :     gpu_ = false;
+     363             :   }
+     364             : 
+     365             : // Martini model
+     366           0 :   parseFlag("MARTINI",martini_);
+     367             : 
+     368             :   // check read
+     369           0 :   checkRead();
+     370             : 
+     371             :   // set parallel stuff
+     372           0 :   unsigned mpisize=comm.Get_size();
+     373           0 :   if(mpisize>1) error("EMMIVOX supports only OpenMP parallelization");
+     374             : 
+     375             :   // get number of replicas
+     376           0 :   if(no_aver_) {
+     377           0 :     nrep_ = 1;
+     378             :   } else {
+     379           0 :     nrep_ = multi_sim_comm.Get_size();
+     380             :   }
+     381           0 :   replica_ = multi_sim_comm.Get_rank();
+     382             : 
+     383           0 :   if(nrep_>1 && dbfact_>0) error("Bfactor sampling not supported with ensemble averaging");
+     384             : 
+     385           0 :   log.printf("  number of atoms involved : %u\n", atoms.size());
+     386           0 :   log.printf("  experimental density map : %s\n", datafile.c_str());
+     387           0 :   if(no_aver_) log.printf("  without ensemble averaging\n");
+     388           0 :   if(gpu_) {log.printf("  running on GPU \n");}
+     389           0 :   else {log.printf("  running on CPU \n");}
+     390           0 :   if(nl_dist_cutoff_ <1.0e+10) log.printf("  neighbor list distance cutoff : %lf\n", nl_dist_cutoff_);
+     391           0 :   if(nl_gauss_cutoff_<1.0e+10) log.printf("  neighbor list Gaussian sigma cutoff : %lf\n", nl_gauss_cutoff_);
+     392           0 :   log.printf("  neighbor list update stride : %u\n",  nl_stride_);
+     393           0 :   log.printf("  minimum density error : %f\n", sigma_min);
+     394           0 :   log.printf("  scale factor : %lf\n", scale_);
+     395           0 :   log.printf("  offset : %lf\n", offset_);
+     396           0 :   log.printf("  reading/writing to status file : %s\n", statusfilename_.c_str());
+     397           0 :   log.printf("  with stride : %u\n", statusstride_);
+     398           0 :   if(dbfact_>0) {
+     399           0 :     log.printf("  maximum Bfactor MC move : %f\n", dbfact_);
+     400           0 :     log.printf("  stride MC move : %u\n", MCBstride_);
+     401           0 :     log.printf("  using prior with sigma : %f\n", bfactsig_);
+     402             :   }
+     403           0 :   if(bfactread_) log.printf("  reading Bfactors from file : %s\n", statusfilename_.c_str());
+     404           0 :   log.printf("  temperature of the system in energy unit : %f\n", kbt_);
+     405           0 :   if(nrep_>1) {
+     406           0 :     log.printf("  number of replicas for averaging: %u\n", nrep_);
+     407           0 :     log.printf("  replica ID : %u\n", replica_);
+     408             :   }
+     409           0 :   if(mapstride_>0) {
+     410           0 :     log.printf("  writing model density to file : %s\n", mapfilename_.c_str());
+     411           0 :     log.printf("  with stride : %u\n", mapstride_);
+     412             :   }
+     413           0 :   if(martini_) log.printf("  using Martini scattering factors\n");
+     414             : 
+     415             :   // calculate model constant parameters
+     416           0 :   std::vector<double> Model_w = get_Model_param(atoms);
+     417             : 
+     418             :   // read experimental map and errors
+     419           0 :   get_exp_data(datafile);
+     420           0 :   log.printf("  number of voxels : %u\n", static_cast<unsigned>(ovdd_.size()));
+     421             : 
+     422             :   // normalize atom weight map
+     423             :   double norm_m = accumulate(Model_w.begin(),  Model_w.end(),  0.0);
+     424             :   // renormalization and constant factor on atom types
+     425           0 :   for(unsigned i=0; i<Model_w_.size(); ++i) {
+     426           0 :     Vector5d cf;
+     427           0 :     for(unsigned j=0; j<5; ++j) {
+     428           0 :       Model_w_[i][j] *= norm_d / norm_m;
+     429           0 :       cf[j] = Model_w_[i][j]/pow( 2.0*pi, 1.5 );
+     430             :     }
+     431           0 :     cfact_.push_back(cf);
+     432             :   }
+     433             : 
+     434             :   // median density
+     435           0 :   double ovdd_m = get_median(ovdd_);
+     436             :   // median experimental error
+     437           0 :   double err_m  = get_median(exp_err_);
+     438             :   // minimum error
+     439           0 :   double minerr = sigma_min*ovdd_m;
+     440             :   // print out statistics
+     441           0 :   log.printf("     median density : %lf\n", ovdd_m);
+     442           0 :   log.printf("     minimum error  : %lf\n", minerr);
+     443           0 :   log.printf("     median error   : %lf\n", err_m);
+     444             :   // populate ismin: cycle on all voxels
+     445           0 :   for(unsigned id=0; id<ovdd_.size(); ++id) {
+     446             :     // define smin
+     447           0 :     double smin = std::max(minerr, exp_err_[id]);
+     448             :     // and to ismin_
+     449           0 :     ismin_.push_back(1.0/smin);
+     450             :   }
+     451             : 
+     452             :   // prepare gpu stuff: map centers, data, and error
+     453           0 :   prepare_gpu();
+     454             : 
+     455             :   // initialize Bfactors
+     456           0 :   initialize_Bfactor(reso);
+     457             : 
+     458             :   // read status file if restarting
+     459           0 :   if(getRestart() || bfactread_) read_status();
+     460             : 
+     461             :   // prepare auxiliary vectors
+     462           0 :   get_auxiliary_vectors();
+     463             : 
+     464             :   // prepare other vectors: data and derivatives
+     465           0 :   ovmd_.resize(ovdd_.size());
+     466           0 :   atom_der_.resize(Model_type_.size());
+     467           0 :   score_der_.resize(ovdd_.size());
+     468             : 
+     469             :   // add components
+     470           0 :   addComponentWithDerivatives("scoreb"); componentIsNotPeriodic("scoreb");
+     471           0 :   addComponent("scale");                 componentIsNotPeriodic("scale");
+     472           0 :   addComponent("offset");                componentIsNotPeriodic("offset");
+     473           0 :   addComponent("kbt");                   componentIsNotPeriodic("kbt");
+     474           0 :   if(dbfact_>0)   {addComponent("accB"); componentIsNotPeriodic("accB");}
+     475           0 :   if(do_corr_)    {addComponent("corr"); componentIsNotPeriodic("corr");}
+     476             : 
+     477             :   // initialize random seed
+     478           0 :   unsigned iseed = time(NULL)+replica_;
+     479           0 :   random_.setSeed(-iseed);
+     480             : 
+     481             :   // request atoms
+     482           0 :   requestAtoms(atoms);
+     483             : 
+     484             :   // print bibliography
+     485           0 :   log<<"  Bibliography "<<plumed.cite("Bonomi, Camilloni, Bioinformatics, 33, 3999 (2017)");
+     486           0 :   log<<plumed.cite("Hoff, Thomasen, Lindorff-Larsen, Bonomi, bioRxiv (2023) doi: 10.1101/2023.10.18.562710");
+     487           0 :   if(!no_aver_ && nrep_>1)log<<plumed.cite("Bonomi, Camilloni, Cavalli, Vendruscolo, Sci. Adv. 2, e150117 (2016)");
+     488           0 :   log<<"\n";
+     489           0 : }
+     490             : 
+     491           0 : void EMMIVOX::prepare_gpu()
+     492             : {
+     493             :   // number of data points
+     494           0 :   int nd = ovdd_.size();
+     495             :   // 1) put ismin_ on device_t_
+     496           0 :   ismin_gpu_ = torch::from_blob(ismin_.data(), {nd}, torch::kFloat64).to(torch::kFloat32).to(device_t_);
+     497             :   // 2) put ovdd_ on device_t_
+     498           0 :   ovdd_gpu_  = torch::from_blob(ovdd_.data(),  {nd}, torch::kFloat64).to(torch::kFloat32).to(device_t_);
+     499             :   // 3) put Map_m_ on device_t_
+     500           0 :   std::vector<double> Map_m_gpu(3*nd);
+     501           0 :   #pragma omp parallel for num_threads(OpenMP::getNumThreads())
+     502             :   for(int i=0; i<nd; ++i) {
+     503             :     Map_m_gpu[i]      = Map_m_[i][0];
+     504             :     Map_m_gpu[i+nd]   = Map_m_[i][1];
+     505             :     Map_m_gpu[i+2*nd] = Map_m_[i][2];
+     506             :   }
+     507             :   // libtorch tensor
+     508           0 :   Map_m_gpu_ = torch::from_blob(Map_m_gpu.data(), {3,nd}, torch::kFloat64).clone().to(torch::kFloat32).to(device_t_);
+     509           0 : }
+     510             : 
+     511           0 : void EMMIVOX::write_model_density(long int step)
+     512             : {
+     513           0 :   OFile ovfile;
+     514           0 :   ovfile.link(*this);
+     515           0 :   std::string num; Tools::convert(step,num);
+     516           0 :   std::string name = mapfilename_+"-"+num;
+     517           0 :   ovfile.open(name);
+     518             :   ovfile.setHeavyFlush();
+     519           0 :   ovfile.fmtField("%10.7e ");
+     520             : // write density
+     521           0 :   for(unsigned i=0; i<ovmd_.size(); ++i) {
+     522           0 :     ovfile.printField("Model", ovmd_[i]);
+     523           0 :     ovfile.printField("ModelScaled", scale_ * ovmd_[i] + offset_);
+     524           0 :     ovfile.printField("Data", ovdd_[i]);
+     525           0 :     ovfile.printField();
+     526             :   }
+     527           0 :   ovfile.close();
+     528           0 : }
+     529             : 
+     530           0 : double EMMIVOX::get_median(std::vector<double> v)
+     531             : {
+     532             : // dimension of vector
+     533           0 :   unsigned size = v.size();
+     534             : // in case of only one entry
+     535           0 :   if (size==1) {
+     536           0 :     return v[0];
+     537             :   } else {
+     538             :     // reorder vector
+     539           0 :     sort(v.begin(), v.end());
+     540             :     // odd or even?
+     541           0 :     if (size%2==0) {
+     542           0 :       return (v[size/2-1]+v[size/2])/2.0;
+     543             :     } else {
+     544           0 :       return v[size/2];
+     545             :     }
+     546             :   }
+     547             : }
+     548             : 
+     549           0 : void EMMIVOX::read_status()
+     550             : {
+     551             :   double MDtime;
+     552             : // open file
+     553           0 :   IFile *ifile = new IFile();
+     554           0 :   ifile->link(*this);
+     555           0 :   if(ifile->FileExist(statusfilename_)) {
+     556           0 :     ifile->open(statusfilename_);
+     557           0 :     while(ifile->scanField("MD_time", MDtime)) {
+     558             :       // read scale and offset
+     559           0 :       ifile->scanField("scale", scale_);
+     560           0 :       ifile->scanField("offset", offset_);
+     561             :       // read bfactors if doing fitting of reading it at restart
+     562           0 :       if(dbfact_>0 || bfactread_) {
+     563             :         // cycle on residues
+     564           0 :         for(unsigned ir=0; ir<Model_rlist_.size(); ++ir) {
+     565             :           // key: pair of residue/chain IDs
+     566             :           std::pair<unsigned,std::string> key = Model_rlist_[ir];
+     567             :           // convert ires to std::string
+     568           0 :           std::string num; Tools::convert(key.first,num);
+     569             :           // read entry
+     570           0 :           std::string ch = key.second;
+     571           0 :           if(ch==" ") ch="";
+     572           0 :           ifile->scanField("bf-"+num+":"+ch, Model_b_[key]);
+     573             :         }
+     574             :       }
+     575             :       // new line
+     576           0 :       ifile->scanField();
+     577             :     }
+     578           0 :     ifile->close();
+     579             :   } else {
+     580           0 :     error("Cannot find status file "+statusfilename_+"\n");
+     581             :   }
+     582           0 :   delete ifile;
+     583           0 : }
+     584             : 
+     585           0 : void EMMIVOX::print_status(long int step)
+     586             : {
+     587             : // if first time open the file
+     588           0 :   if(first_status_) {
+     589           0 :     first_status_ = false;
+     590           0 :     statusfile_.link(*this);
+     591           0 :     statusfile_.open(statusfilename_);
+     592             :     statusfile_.setHeavyFlush();
+     593           0 :     statusfile_.fmtField("%10.7e ");
+     594             :   }
+     595             : // write fields
+     596           0 :   double MDtime = static_cast<double>(step)*getTimeStep();
+     597           0 :   statusfile_.printField("MD_time", MDtime);
+     598             :   // write scale and offset
+     599           0 :   statusfile_.printField("scale", scale_);
+     600           0 :   statusfile_.printField("offset", offset_);
+     601             :   // write bfactors only if doing fitting or reading bfactors
+     602           0 :   if(dbfact_>0 || bfactread_) {
+     603             :     // cycle on residues
+     604           0 :     for(unsigned ir=0; ir<Model_rlist_.size(); ++ir) {
+     605             :       // key: pair of residue/chain IDs
+     606             :       std::pair<unsigned,std::string> key = Model_rlist_[ir];
+     607             :       // bfactor from map
+     608           0 :       double bf = Model_b_[key];
+     609             :       // convert ires to std::string
+     610           0 :       std::string num; Tools::convert(key.first,num);
+     611             :       // print entry
+     612           0 :       statusfile_.printField("bf-"+num+":"+key.second, bf);
+     613             :     }
+     614             :   }
+     615           0 :   statusfile_.printField();
+     616           0 : }
+     617             : 
+     618           0 : bool EMMIVOX::doAccept(double oldE, double newE, double kbt)
+     619             : {
+     620             :   bool accept = false;
+     621             :   // calculate delta energy
+     622           0 :   double delta = ( newE - oldE ) / kbt;
+     623             :   // if delta is negative always accept move
+     624           0 :   if( delta < 0.0 ) {
+     625             :     accept = true;
+     626             :   } else {
+     627             :     // otherwise extract random number
+     628           0 :     double s = random_.RandU01();
+     629           0 :     if( s < exp(-delta) ) { accept = true; }
+     630             :   }
+     631           0 :   return accept;
+     632             : }
+     633             : 
+     634           0 : std::vector<double> EMMIVOX::get_Model_param(std::vector<AtomNumber> &atoms)
+     635             : {
+     636             :   // check if MOLINFO line is present
+     637           0 :   auto* moldat=plumed.getActionSet().selectLatest<GenericMolInfo*>(this);
+     638           0 :   if(!moldat) error("MOLINFO DATA not found\n");
+     639           0 :   log<<"  MOLINFO DATA found with label " <<moldat->getLabel()<<", using proper atom names\n";
+     640             : 
+     641             :   // list of weights - one per atom
+     642             :   std::vector<double> Model_w;
+     643             :   // 5-Gaussians parameters
+     644             :   // map of atom types to A and B coefficients of scattering factor
+     645             :   // f(s) = A * exp(-B*s**2)
+     646             :   // B is in Angstrom squared
+     647             :   // Elastic atomic scattering factors of electrons for neutral atoms
+     648             :   // and s up to 6.0 A^-1: as implemented in PLUMED
+     649             :   // map between an atom type and an index
+     650             :   std::map<std::string, unsigned> type_map;
+     651             :   // atomistic types
+     652           0 :   type_map["C"]=0;  type_map["O"]=1;  type_map["N"]=2;
+     653           0 :   type_map["S"]=3;  type_map["P"]=4;  type_map["F"]=5;
+     654           0 :   type_map["NA"]=6; type_map["MG"]=7; type_map["CL"]=8;
+     655           0 :   type_map["CA"]=9; type_map["K"]=10; type_map["ZN"]=11;
+     656             :   // Martini types
+     657           0 :   type_map["ALA_BB"]=12;    type_map["ALA_SC1"]=13;   type_map["CYS_BB"]=14;
+     658           0 :   type_map["CYS_SC1"]=15;   type_map["ASP_BB"]=16;    type_map["ASP_SC1"]=17;
+     659           0 :   type_map["GLU_BB"]=18;    type_map["GLU_SC1"]=19;   type_map["PHE_BB"]=20;
+     660           0 :   type_map["PHE_SC1"]=21;   type_map["PHE_SC2"]=22;   type_map["PHE_SC3"]=23;
+     661           0 :   type_map["GLY_BB"]=24;    type_map["HIS_BB"]=25;    type_map["HIS_SC1"]=26;
+     662           0 :   type_map["HIS_SC2"]=27;   type_map["HIS_SC3"]=28;   type_map["ILE_BB"]=29;
+     663           0 :   type_map["ILE_SC1"]=30;   type_map["LYS_BB"]=31;    type_map["LYS_SC1"]=32;
+     664           0 :   type_map["LYS_SC2"]=33;   type_map["LEU_BB"]=34;    type_map["LEU_SC1"]=35;
+     665           0 :   type_map["MET_BB"]=36;    type_map["MET_SC1"]=37;   type_map["ASN_BB"]=38;
+     666           0 :   type_map["ASN_SC1"]=39;   type_map["PRO_BB"]=40;    type_map["PRO_SC1"]=41;
+     667           0 :   type_map["GLN_BB"]=42;    type_map["GLN_SC1"]=43;   type_map["ARG_BB"]=44;
+     668           0 :   type_map["ARG_SC1"]=45;   type_map["ARG_SC2"]=46;   type_map["SER_BB"]=47;
+     669           0 :   type_map["SER_SC1"]=48;   type_map["THR_BB"]=49;    type_map["THR_SC1"]=50;
+     670           0 :   type_map["VAL_BB"]=51;    type_map["VAL_SC1"]=52;   type_map["TRP_BB"]=53;
+     671           0 :   type_map["TRP_SC1"]=54;   type_map["TRP_SC2"]=55;   type_map["TRP_SC3"]=56;
+     672           0 :   type_map["TRP_SC4"]=57;   type_map["TRP_SC5"]=58;   type_map["TYR_BB"]=59;
+     673           0 :   type_map["TYR_SC1"]=60;   type_map["TYR_SC2"]=61;   type_map["TYR_SC3"]=62;
+     674           0 :   type_map["TYR_SC4"]=63;
+     675             :   // fill in sigma vector for atoms
+     676           0 :   Model_s_.push_back(0.01*Vector5d(0.114,1.0825,5.4281,17.8811,51.1341));   // C
+     677           0 :   Model_s_.push_back(0.01*Vector5d(0.0652,0.6184,2.9449,9.6298,28.2194));   // O
+     678           0 :   Model_s_.push_back(0.01*Vector5d(0.0541,0.5165,2.8207,10.6297,34.3764));  // N
+     679           0 :   Model_s_.push_back(0.01*Vector5d(0.0838,0.7788,4.3462,15.5846,44.63655)); // S
+     680           0 :   Model_s_.push_back(0.01*Vector5d(0.0977,0.9084,4.9654,18.5471,54.3648));  // P
+     681           0 :   Model_s_.push_back(0.01*Vector5d(0.0613,0.5753,2.6858,8.8214,25.6668));   // F
+     682           0 :   Model_s_.push_back(0.01*Vector5d(0.1684,1.7150,8.8386,50.8265,147.2073)); // NA
+     683           0 :   Model_s_.push_back(0.01*Vector5d(0.1356,1.3579,6.9255,32.3165,92.1138));  // MG
+     684           0 :   Model_s_.push_back(0.01*Vector5d(0.0694,0.6443,3.5351,12.5058,35.8633));  // CL
+     685           0 :   Model_s_.push_back(0.01*Vector5d(0.1742,1.8329,8.8407,47.4583,134.9613)); // CA
+     686           0 :   Model_s_.push_back(0.01*Vector5d(0.1660,1.6906,8.7447,46.7825,165.6923)); // K
+     687           0 :   Model_s_.push_back(0.01*Vector5d(0.0876,0.8650,3.8612,18.8726,64.7016));  // ZN
+     688             :   // fill in sigma vector for Martini beads
+     689           0 :   Model_s_.push_back(0.01*Vector5d(22.000000,22.000000,22.000000,22.000000,22.000000)); // ALA_BB
+     690           0 :   Model_s_.push_back(0.01*Vector5d(0.500000,0.500000,0.500000,0.500000,0.500000)); // ALA_SC1
+     691           0 :   Model_s_.push_back(0.01*Vector5d(23.000000,23.000000,23.000000,23.000000,23.000000)); // CYS_BB
+     692           0 :   Model_s_.push_back(0.01*Vector5d(8.500000,8.500000,8.500000,8.500000,8.500000)); // CYS_SC1
+     693           0 :   Model_s_.push_back(0.01*Vector5d(23.000000,23.000000,23.000000,23.000000,23.000000)); // ASP_BB
+     694           0 :   Model_s_.push_back(0.01*Vector5d(17.000000,17.000000,17.000000,17.000000,17.000000)); // ASP_SC1
+     695           0 :   Model_s_.push_back(0.01*Vector5d(22.000000,22.000000,22.000000,22.000000,22.000000)); // GLU_BB
+     696           0 :   Model_s_.push_back(0.01*Vector5d(24.000000,24.000000,24.000000,24.000000,24.000000)); // GLU_SC1
+     697           0 :   Model_s_.push_back(0.01*Vector5d(23.000000,23.000000,23.000000,23.000000,23.000000)); // PHE_BB
+     698           0 :   Model_s_.push_back(0.01*Vector5d(17.500000,17.500000,17.500000,17.500000,17.500000)); // PHE_SC1
+     699           0 :   Model_s_.push_back(0.01*Vector5d(11.000000,11.000000,11.000000,11.000000,11.000000)); // PHE_SC2
+     700           0 :   Model_s_.push_back(0.01*Vector5d(11.000000,11.000000,11.000000,11.000000,11.000000)); // PHE_SC3
+     701           0 :   Model_s_.push_back(0.01*Vector5d(23.000000,23.000000,23.000000,23.000000,23.000000)); // GLY_BB
+     702           0 :   Model_s_.push_back(0.01*Vector5d(23.000000,23.000000,23.000000,23.000000,23.000000)); // HIS_BB
+     703           0 :   Model_s_.push_back(0.01*Vector5d(11.500000,11.500000,11.500000,11.500000,11.500000)); // HIS_SC1
+     704           0 :   Model_s_.push_back(0.01*Vector5d(9.000000,9.000000,9.000000,9.000000,9.000000)); // HIS_SC2
+     705           0 :   Model_s_.push_back(0.01*Vector5d(8.500000,8.500000,8.500000,8.500000,8.500000)); // HIS_SC3
+     706           0 :   Model_s_.push_back(0.01*Vector5d(23.000000,23.000000,23.000000,23.000000,23.000000)); // ILE_BB
+     707           0 :   Model_s_.push_back(0.01*Vector5d(25.500000,25.500000,25.500000,25.500000,25.500000)); // ILE_SC1
+     708           0 :   Model_s_.push_back(0.01*Vector5d(22.000000,22.000000,22.000000,22.000000,22.000000)); // LYS_BB
+     709           0 :   Model_s_.push_back(0.01*Vector5d(18.000000,18.000000,18.000000,18.000000,18.000000)); // LYS_SC1
+     710           0 :   Model_s_.push_back(0.01*Vector5d(11.000000,11.000000,11.000000,11.000000,11.000000)); // LYS_SC2
+     711           0 :   Model_s_.push_back(0.01*Vector5d(22.000000,22.000000,22.000000,22.000000,22.000000)); // LEU_BB
+     712           0 :   Model_s_.push_back(0.01*Vector5d(21.500000,21.500000,21.500000,21.500000,21.500000)); // LEU_SC1
+     713           0 :   Model_s_.push_back(0.01*Vector5d(22.000000,22.000000,22.000000,22.000000,22.000000)); // MET_BB
+     714           0 :   Model_s_.push_back(0.01*Vector5d(22.500000,22.500000,22.500000,22.500000,22.500000)); // MET_SC1
+     715           0 :   Model_s_.push_back(0.01*Vector5d(22.000000,22.000000,22.000000,22.000000,22.000000)); // ASN_BB
+     716           0 :   Model_s_.push_back(0.01*Vector5d(18.500000,18.500000,18.500000,18.500000,18.500000)); // ASN_SC1
+     717           0 :   Model_s_.push_back(0.01*Vector5d(23.500000,23.500000,23.500000,23.500000,23.500000)); // PRO_BB
+     718           0 :   Model_s_.push_back(0.01*Vector5d(17.500000,17.500000,17.500000,17.500000,17.500000)); // PRO_SC1
+     719           0 :   Model_s_.push_back(0.01*Vector5d(22.000000,22.000000,22.000000,22.000000,22.000000)); // GLN_BB
+     720           0 :   Model_s_.push_back(0.01*Vector5d(24.500000,24.500000,24.500000,24.500000,24.500000)); // GLN_SC1
+     721           0 :   Model_s_.push_back(0.01*Vector5d(23.000000,23.000000,23.000000,23.000000,23.000000)); // ARG_BB
+     722           0 :   Model_s_.push_back(0.01*Vector5d(18.000000,18.000000,18.000000,18.000000,18.000000)); // ARG_SC1
+     723           0 :   Model_s_.push_back(0.01*Vector5d(18.000000,18.000000,18.000000,18.000000,18.000000)); // ARG_SC2
+     724           0 :   Model_s_.push_back(0.01*Vector5d(23.000000,23.000000,23.000000,23.000000,23.000000)); // SER_BB
+     725           0 :   Model_s_.push_back(0.01*Vector5d(9.000000,9.000000,9.000000,9.000000,9.000000)); // SER_SC1
+     726           0 :   Model_s_.push_back(0.01*Vector5d(23.000000,23.000000,23.000000,23.000000,23.000000)); // THR_BB
+     727           0 :   Model_s_.push_back(0.01*Vector5d(17.000000,17.000000,17.000000,17.000000,17.000000)); // THR_SC1
+     728           0 :   Model_s_.push_back(0.01*Vector5d(23.000000,23.000000,23.000000,23.000000,23.000000)); // VAL_BB
+     729           0 :   Model_s_.push_back(0.01*Vector5d(18.000000,18.000000,18.000000,18.000000,18.000000)); // VAL_SC1
+     730           0 :   Model_s_.push_back(0.01*Vector5d(23.000000,23.000000,23.000000,23.000000,23.000000)); // TRP_BB
+     731           0 :   Model_s_.push_back(0.01*Vector5d(11.500000,11.500000,11.500000,11.500000,11.500000)); // TRP_SC1
+     732           0 :   Model_s_.push_back(0.01*Vector5d(9.000000,9.000000,9.000000,9.000000,9.000000)); // TRP_SC2
+     733           0 :   Model_s_.push_back(0.01*Vector5d(11.000000,11.000000,11.000000,11.000000,11.000000)); // TRP_SC3
+     734           0 :   Model_s_.push_back(0.01*Vector5d(11.000000,11.000000,11.000000,11.000000,11.000000)); // TRP_SC4
+     735           0 :   Model_s_.push_back(0.01*Vector5d(9.500000,9.500000,9.500000,9.500000,9.500000)); // TRP_SC5
+     736           0 :   Model_s_.push_back(0.01*Vector5d(23.000000,23.000000,23.000000,23.000000,23.000000)); // TYR_BB
+     737           0 :   Model_s_.push_back(0.01*Vector5d(12.000000,12.000000,12.000000,12.000000,12.000000)); // TYR_SC1
+     738           0 :   Model_s_.push_back(0.01*Vector5d(11.000000,11.000000,11.000000,11.000000,11.000000)); // TYR_SC2
+     739           0 :   Model_s_.push_back(0.01*Vector5d(11.000000,11.000000,11.000000,11.000000,11.000000)); // TYR_SC3
+     740           0 :   Model_s_.push_back(0.01*Vector5d(8.500000,8.500000,8.500000,8.500000,8.500000)); // TYR_SC4
+     741             :   // fill in weight vector for atoms
+     742           0 :   Model_w_.push_back(Vector5d(0.0489,0.2091,0.7537,1.1420,0.3555)); // C
+     743           0 :   Model_w_.push_back(Vector5d(0.0365,0.1729,0.5805,0.8814,0.3121)); // O
+     744           0 :   Model_w_.push_back(Vector5d(0.0267,0.1328,0.5301,1.1020,0.4215)); // N
+     745           0 :   Model_w_.push_back(Vector5d(0.0915,0.4312,1.0847,2.4671,1.0852)); // S
+     746           0 :   Model_w_.push_back(Vector5d(0.1005,0.4615,1.0663,2.5854,1.2725)); // P
+     747           0 :   Model_w_.push_back(Vector5d(0.0382,0.1822,0.5972,0.7707,0.2130)); // F
+     748           0 :   Model_w_.push_back(Vector5d(0.1260,0.6442,0.8893,1.8197,1.2988)); // NA
+     749           0 :   Model_w_.push_back(Vector5d(0.1130,0.5575,0.9046,2.1580,1.4735)); // MG
+     750           0 :   Model_w_.push_back(Vector5d(0.0799,0.3891,1.0037,2.3332,1.0507)); // CL
+     751           0 :   Model_w_.push_back(Vector5d(0.2355,0.9916,2.3959,3.7252,2.5647)); // CA
+     752           0 :   Model_w_.push_back(Vector5d(0.2149,0.8703,2.4999,2.3591,3.0318)); // K
+     753           0 :   Model_w_.push_back(Vector5d(0.1780,0.8096,1.6744,1.9499,1.4495)); // ZN
+     754             :   // fill in weight vector for Martini beads
+     755           0 :   Model_w_.push_back(Vector5d(1.800000,1.800000,1.800000,1.800000,1.800000)); // ALA_BB
+     756           0 :   Model_w_.push_back(Vector5d(0.100000,0.100000,0.100000,0.100000,0.100000)); // ALA_SC1
+     757           0 :   Model_w_.push_back(Vector5d(1.900000,1.900000,1.900000,1.900000,1.900000)); // CYS_BB
+     758           0 :   Model_w_.push_back(Vector5d(1.100000,1.100000,1.100000,1.100000,1.100000)); // CYS_SC1
+     759           0 :   Model_w_.push_back(Vector5d(1.900000,1.900000,1.900000,1.900000,1.900000)); // ASP_BB
+     760           0 :   Model_w_.push_back(Vector5d(1.700000,1.700000,1.700000,1.700000,1.700000)); // ASP_SC1
+     761           0 :   Model_w_.push_back(Vector5d(1.800000,1.800000,1.800000,1.800000,1.800000)); // GLU_BB
+     762           0 :   Model_w_.push_back(Vector5d(2.300000,2.300000,2.300000,2.300000,2.300000)); // GLU_SC1
+     763           0 :   Model_w_.push_back(Vector5d(1.900000,1.900000,1.900000,1.900000,1.900000)); // PHE_BB
+     764           0 :   Model_w_.push_back(Vector5d(1.400000,1.400000,1.400000,1.400000,1.400000)); // PHE_SC1
+     765           0 :   Model_w_.push_back(Vector5d(0.900000,0.900000,0.900000,0.900000,0.900000)); // PHE_SC2
+     766           0 :   Model_w_.push_back(Vector5d(0.900000,0.900000,0.900000,0.900000,0.900000)); // PHE_SC3
+     767           0 :   Model_w_.push_back(Vector5d(1.900000,1.900000,1.900000,1.900000,1.900000)); // GLY_BB
+     768           0 :   Model_w_.push_back(Vector5d(1.900000,1.900000,1.900000,1.900000,1.900000)); // HIS_BB
+     769           0 :   Model_w_.push_back(Vector5d(0.900000,0.900000,0.900000,0.900000,0.900000)); // HIS_SC1
+     770           0 :   Model_w_.push_back(Vector5d(0.800000,0.800000,0.800000,0.800000,0.800000)); // HIS_SC2
+     771           0 :   Model_w_.push_back(Vector5d(0.800000,0.800000,0.800000,0.800000,0.800000)); // HIS_SC3
+     772           0 :   Model_w_.push_back(Vector5d(1.900000,1.900000,1.900000,1.900000,1.900000)); // ILE_BB
+     773           0 :   Model_w_.push_back(Vector5d(2.000000,2.000000,2.000000,2.000000,2.000000)); // ILE_SC1
+     774           0 :   Model_w_.push_back(Vector5d(1.800000,1.800000,1.800000,1.800000,1.800000)); // LYS_BB
+     775           0 :   Model_w_.push_back(Vector5d(1.400000,1.400000,1.400000,1.400000,1.400000)); // LYS_SC1
+     776           0 :   Model_w_.push_back(Vector5d(0.900000,0.900000,0.900000,0.900000,0.900000)); // LYS_SC2
+     777           0 :   Model_w_.push_back(Vector5d(1.800000,1.800000,1.800000,1.800000,1.800000)); // LEU_BB
+     778           0 :   Model_w_.push_back(Vector5d(1.900000,1.900000,1.900000,1.900000,1.900000)); // LEU_SC1
+     779           0 :   Model_w_.push_back(Vector5d(1.800000,1.800000,1.800000,1.800000,1.800000)); // MET_BB
+     780           0 :   Model_w_.push_back(Vector5d(2.300000,2.300000,2.300000,2.300000,2.300000)); // MET_SC1
+     781           0 :   Model_w_.push_back(Vector5d(1.800000,1.800000,1.800000,1.800000,1.800000)); // ASN_BB
+     782           0 :   Model_w_.push_back(Vector5d(1.800000,1.800000,1.800000,1.800000,1.800000)); // ASN_SC1
+     783           0 :   Model_w_.push_back(Vector5d(1.900000,1.900000,1.900000,1.900000,1.900000)); // PRO_BB
+     784           0 :   Model_w_.push_back(Vector5d(1.400000,1.400000,1.400000,1.400000,1.400000)); // PRO_SC1
+     785           0 :   Model_w_.push_back(Vector5d(1.800000,1.800000,1.800000,1.800000,1.800000)); // GLN_BB
+     786           0 :   Model_w_.push_back(Vector5d(2.300000,2.300000,2.300000,2.300000,2.300000)); // GLN_SC1
+     787           0 :   Model_w_.push_back(Vector5d(1.900000,1.900000,1.900000,1.900000,1.900000)); // ARG_BB
+     788           0 :   Model_w_.push_back(Vector5d(1.400000,1.400000,1.400000,1.400000,1.400000)); // ARG_SC1
+     789           0 :   Model_w_.push_back(Vector5d(1.800000,1.800000,1.800000,1.800000,1.800000)); // ARG_SC2
+     790           0 :   Model_w_.push_back(Vector5d(1.900000,1.900000,1.900000,1.900000,1.900000)); // SER_BB
+     791           0 :   Model_w_.push_back(Vector5d(0.800000,0.800000,0.800000,0.800000,0.800000)); // SER_SC1
+     792           0 :   Model_w_.push_back(Vector5d(1.900000,1.900000,1.900000,1.900000,1.900000)); // THR_BB
+     793           0 :   Model_w_.push_back(Vector5d(1.400000,1.400000,1.400000,1.400000,1.400000)); // THR_SC1
+     794           0 :   Model_w_.push_back(Vector5d(1.900000,1.900000,1.900000,1.900000,1.900000)); // VAL_BB
+     795           0 :   Model_w_.push_back(Vector5d(1.400000,1.400000,1.400000,1.400000,1.400000)); // VAL_SC1
+     796           0 :   Model_w_.push_back(Vector5d(1.900000,1.900000,1.900000,1.900000,1.900000)); // TRP_BB
+     797           0 :   Model_w_.push_back(Vector5d(0.900000,0.900000,0.900000,0.900000,0.900000)); // TRP_SC1
+     798           0 :   Model_w_.push_back(Vector5d(0.800000,0.800000,0.800000,0.800000,0.800000)); // TRP_SC2
+     799           0 :   Model_w_.push_back(Vector5d(0.900000,0.900000,0.900000,0.900000,0.900000)); // TRP_SC3
+     800           0 :   Model_w_.push_back(Vector5d(0.900000,0.900000,0.900000,0.900000,0.900000)); // TRP_SC4
+     801           0 :   Model_w_.push_back(Vector5d(0.800000,0.800000,0.800000,0.800000,0.800000)); // TRP_SC5
+     802           0 :   Model_w_.push_back(Vector5d(1.900000,1.900000,1.900000,1.900000,1.900000)); // TYR_BB
+     803           0 :   Model_w_.push_back(Vector5d(0.900000,0.900000,0.900000,0.900000,0.900000)); // TYR_SC1
+     804           0 :   Model_w_.push_back(Vector5d(0.900000,0.900000,0.900000,0.900000,0.900000)); // TYR_SC2
+     805           0 :   Model_w_.push_back(Vector5d(0.900000,0.900000,0.900000,0.900000,0.900000)); // TYR_SC3
+     806           0 :   Model_w_.push_back(Vector5d(0.800000,0.800000,0.800000,0.800000,0.800000)); // TYR_SC4
+     807             :   // cycle on atoms
+     808           0 :   for(unsigned i=0; i<atoms.size(); ++i) {
+     809             :     // get atom name
+     810           0 :     std::string name = moldat->getAtomName(atoms[i]);
+     811             :     // get residue name
+     812           0 :     std::string resname = moldat->getResidueName(atoms[i]);
+     813             :     // type of atoms/bead
+     814             :     std::string type_s;
+     815             :     // Martini model
+     816           0 :     if(martini_) {
+     817           0 :       type_s = resname+"_"+name;
+     818             :       // Atomistic model
+     819             :     } else {
+     820             :       char type;
+     821             :       // get atom type
+     822           0 :       char first = name.at(0);
+     823             :       // GOLDEN RULE: type is first letter, if not a number
+     824           0 :       if (!isdigit(first)) {
+     825             :         type = first;
+     826             :         // otherwise is the second
+     827             :       } else {
+     828           0 :         type = name.at(1);
+     829             :       }
+     830             :       // convert to std::string
+     831           0 :       type_s = std::string(1,type);
+     832             :       // special cases
+     833           0 :       if(name=="SOD" || name=="NA" || name =="Na") type_s = "NA";
+     834           0 :       if(name=="MG"  || name=="Mg")                type_s = "MG";
+     835           0 :       if(name=="CLA" || name=="CL" || name =="Cl") type_s = "CL";
+     836           0 :       if((resname=="CAL" || resname=="CA") && (name=="CAL" || name=="CA" || name =="C0")) type_s = "CA";
+     837           0 :       if(name=="POT" || name=="K")                 type_s = "K";
+     838           0 :       if(name=="ZN"  || name=="Zn")                type_s = "ZN";
+     839             :     }
+     840             :     // check if key in map
+     841           0 :     if(type_map.find(type_s) != type_map.end()) {
+     842             :       // save atom type
+     843           0 :       Model_type_.push_back(type_map[type_s]);
+     844             :       // this will be normalized in the final density
+     845           0 :       Vector5d w = Model_w_[type_map[type_s]];
+     846           0 :       Model_w.push_back(w[0]+w[1]+w[2]+w[3]+w[4]);
+     847             :       // get residue id
+     848           0 :       unsigned ires = moldat->getResidueNumber(atoms[i]);
+     849             :       // and chain
+     850           0 :       std::string c ("*");
+     851           0 :       if(!bfactnoc_) c = moldat->getChainID(atoms[i]);
+     852             :       // define pair residue/chain IDs
+     853             :       std::pair<unsigned,std::string> key = std::make_pair(ires,c);
+     854             :       // add to map between residue/chain and list of atoms
+     855           0 :       Model_resmap_[key].push_back(i);
+     856             :       // and global list of residue/chain per atom
+     857           0 :       Model_res_.push_back(key);
+     858             :       // initialize Bfactor map
+     859           0 :       Model_b_[key] = 0.0;
+     860             :     } else {
+     861           0 :       error("Wrong atom type "+type_s+" from atom name "+name+"\n");
+     862             :     }
+     863             :   }
+     864             :   // create ordered vector of residue-chain IDs
+     865           0 :   for(unsigned i=0; i<Model_res_.size(); ++i) {
+     866             :     std::pair<unsigned,std::string> key = Model_res_[i];
+     867             :     // search in Model_rlist_
+     868           0 :     if(find(Model_rlist_.begin(), Model_rlist_.end(), key) == Model_rlist_.end())
+     869           0 :       Model_rlist_.push_back(key);
+     870             :   }
+     871             :   // return weights
+     872           0 :   return Model_w;
+     873             : }
+     874             : 
+     875             : // read experimental data file in PLUMED format:
+     876           0 : void EMMIVOX::get_exp_data(const std::string &datafile)
+     877             : {
+     878           0 :   Vector pos;
+     879             :   double dens, err;
+     880             :   int idcomp;
+     881             : 
+     882             : // open file
+     883           0 :   IFile *ifile = new IFile();
+     884           0 :   if(ifile->FileExist(datafile)) {
+     885           0 :     ifile->open(datafile);
+     886           0 :     while(ifile->scanField("Id",idcomp)) {
+     887           0 :       ifile->scanField("Pos_0",pos[0]);
+     888           0 :       ifile->scanField("Pos_1",pos[1]);
+     889           0 :       ifile->scanField("Pos_2",pos[2]);
+     890           0 :       ifile->scanField("Density",dens);
+     891           0 :       ifile->scanField("Error",err);
+     892             :       // voxel center
+     893           0 :       Map_m_.push_back(pos);
+     894             :       // experimental density
+     895           0 :       ovdd_.push_back(dens);
+     896             :       // error
+     897           0 :       exp_err_.push_back(err);
+     898             :       // new line
+     899           0 :       ifile->scanField();
+     900             :     }
+     901           0 :     ifile->close();
+     902             :   } else {
+     903           0 :     error("Cannot find DATA_FILE "+datafile+"\n");
+     904             :   }
+     905           0 :   delete ifile;
+     906           0 : }
+     907             : 
+     908           0 : void EMMIVOX::initialize_Bfactor(double reso)
+     909             : {
+     910           0 :   double bfactini = 0.0;
+     911             :   // if doing Bfactor Monte Carlo
+     912           0 :   if(dbfact_>0) {
+     913             :     // initialize B factor based on empirical relation between resolution and average bfactor
+     914             :     // calculated on ~8000 cryo-EM data with resolution < 5 Ang
+     915             :     // Bfact = A*reso**2+B; with A=6.95408 B=-2.45697/100.0 nm^2
+     916           0 :     bfactini = 6.95408*reso*reso - 0.01*2.45697;
+     917             :     // check for min and max
+     918           0 :     bfactini = std::min(bfactmax_, std::max(bfactmin_, bfactini));
+     919             :   }
+     920             :   // set initial Bfactor
+     921           0 :   for(std::map< std::pair<unsigned,std::string>, double>::iterator it=Model_b_.begin(); it!=Model_b_.end(); ++it) {
+     922           0 :     it->second = bfactini;
+     923             :   }
+     924           0 :   log.printf("  experimental map resolution : %3.2f\n", reso);
+     925             :   // if doing Bfactor Monte Carlo
+     926           0 :   if(dbfact_>0) {
+     927           0 :     log.printf("  minimum Bfactor value : %3.2f\n", bfactmin_);
+     928           0 :     log.printf("  maximum Bfactor value : %3.2f\n", bfactmax_);
+     929           0 :     log.printf("  initial Bfactor value : %3.2f\n", bfactini);
+     930             :   }
+     931           0 : }
+     932             : 
+     933             : // prepare auxiliary vectors
+     934           0 : void EMMIVOX::get_auxiliary_vectors()
+     935             : {
+     936             : // number of atoms
+     937           0 :   unsigned natoms = Model_res_.size();
+     938             : // clear lists
+     939           0 :   pref_.clear(); invs2_.clear(); cut_.clear();
+     940             : // resize
+     941           0 :   pref_.resize(natoms); invs2_.resize(natoms); cut_.resize(natoms);
+     942             : // cycle on all atoms
+     943           0 :   #pragma omp parallel for num_threads(OpenMP::getNumThreads())
+     944             :   for(unsigned im=0; im<natoms; ++im) {
+     945             :     // get atom type
+     946             :     unsigned atype = Model_type_[im];
+     947             :     // get residue/chain IDs
+     948             :     std::pair<unsigned,std::string> key = Model_res_[im];
+     949             :     // get bfactor
+     950             :     double bfact = Model_b_[key];
+     951             :     // sigma for 5 gaussians
+     952             :     Vector5d m_s = Model_s_[atype];
+     953             :     // calculate constant quantities
+     954             :     Vector5d pref, invs2;
+     955             :     // calculate cutoff
+     956             :     double n = 0.0;
+     957             :     double d = 0.0;
+     958             :     for(unsigned j=0; j<5; ++j) {
+     959             :       // total value of b
+     960             :       double m_b = m_s[j] + bfact/4.0;
+     961             :       // calculate invs2
+     962             :       invs2[j] = 1.0/(inv_pi2_*m_b);
+     963             :       // prefactor
+     964             :       pref[j]  = cfact_[atype][j] * pow(invs2[j],1.5);
+     965             :       // cutoff
+     966             :       n += pref[j] / invs2[j];
+     967             :       d += pref[j];
+     968             :     }
+     969             :     // put into global lists
+     970             :     pref_[im]  = pref;
+     971             :     invs2_[im] = invs2;
+     972             :     cut_[im] = std::min(nl_dist_cutoff_, sqrt(n/d)*nl_gauss_cutoff_);
+     973             :   }
+     974             :   // push to GPU
+     975           0 :   push_auxiliary_gpu();
+     976           0 : }
+     977             : 
+     978           0 : void EMMIVOX::push_auxiliary_gpu()
+     979             : {
+     980             :   // 1) create vector of pref_ and invs2_
+     981           0 :   int natoms = Model_type_.size();
+     982           0 :   std::vector<double> pref(5*natoms), invs2(5*natoms);
+     983           0 :   #pragma omp parallel for num_threads(OpenMP::getNumThreads())
+     984             :   for(int i=0; i<natoms; ++i) {
+     985             :     for(int j=0; j<5; ++j) {
+     986             :       pref[i+j*natoms]  = pref_[i][j];
+     987             :       invs2[i+j*natoms] = invs2_[i][j];
+     988             :     }
+     989             :   }
+     990             :   // 2) initialize gpu tensors
+     991           0 :   pref_gpu_  = torch::from_blob(pref.data(),  {5,natoms}, torch::kFloat64).clone().to(torch::kFloat32).to(device_t_);
+     992           0 :   invs2_gpu_ = torch::from_blob(invs2.data(), {5,natoms}, torch::kFloat64).clone().to(torch::kFloat32).to(device_t_);
+     993           0 : }
+     994             : 
+     995           0 : void EMMIVOX::get_close_residues()
+     996             : {
+     997             :   // clear neighbor list
+     998           0 :   nl_res_.clear(); nl_res_.resize(Model_rlist_.size());
+     999             : 
+    1000             :   // loop in parallel
+    1001           0 :   #pragma omp parallel num_threads(OpenMP::getNumThreads())
+    1002             :   {
+    1003             :     // private variable
+    1004             :     std::vector< std::vector<unsigned> > nl_res_l(Model_rlist_.size());
+    1005             :     // cycle on residues/chains #1
+    1006             :     #pragma omp for
+    1007             :     for(unsigned i=0; i<Model_rlist_.size()-1; ++i) {
+    1008             : 
+    1009             :       // key1: pair of residue/chain IDs
+    1010             :       std::pair<unsigned,std::string> key1 = Model_rlist_[i];
+    1011             : 
+    1012             :       // cycle over residues/chains #2
+    1013             :       for(unsigned j=i+1; j<Model_rlist_.size(); ++j) {
+    1014             : 
+    1015             :         // key2: pair of residue/chain IDs
+    1016             :         std::pair<unsigned,std::string> key2 = Model_rlist_[j];
+    1017             : 
+    1018             :         // set flag neighbor
+    1019             :         bool neigh = false;
+    1020             : 
+    1021             :         // cycle over all the atoms belonging to key1
+    1022             :         for(unsigned im1=0; im1<Model_resmap_[key1].size(); ++im1) {
+    1023             :           // get atom position #1
+    1024             :           Vector pos1 = getPosition(Model_resmap_[key1][im1]);
+    1025             :           // cycle over all the atoms belonging to key2
+    1026             :           for(unsigned im2=0; im2<Model_resmap_[key2].size(); ++im2) {
+    1027             :             // get atom position #2
+    1028             :             Vector pos2 = getPosition(Model_resmap_[key2][im2]);
+    1029             :             // if closer than 0.5 nm, then residues key1 and key2 are neighbors
+    1030             :             if(delta(pos1,pos2).modulo()<0.5) {
+    1031             :               // set neighbors
+    1032             :               neigh = true;
+    1033             :               // and exit
+    1034             :               break;
+    1035             :             }
+    1036             :           }
+    1037             :           // check if neighbor already found
+    1038             :           if(neigh) break;
+    1039             :         }
+    1040             : 
+    1041             :         // if neighbors, add to local list
+    1042             :         if(neigh) {
+    1043             :           nl_res_l[i].push_back(j);
+    1044             :           nl_res_l[j].push_back(i);
+    1045             :         }
+    1046             :       }
+    1047             :     }
+    1048             :     // add to global list
+    1049             :     #pragma omp critical
+    1050             :     {
+    1051             :       for(unsigned i=0; i<nl_res_.size(); ++i)
+    1052             :         nl_res_[i].insert(nl_res_[i].end(), nl_res_l[i].begin(), nl_res_l[i].end());
+    1053             :     }
+    1054             :   }
+    1055           0 : }
+    1056             : 
+    1057           0 : void EMMIVOX::doMonteCarloBfact()
+    1058             : {
+    1059             : // update residue neighbor list
+    1060           0 :   get_close_residues();
+    1061             : 
+    1062             : // cycle over residues/chains
+    1063           0 :   for(unsigned ir=0; ir<Model_rlist_.size(); ++ir) {
+    1064             : 
+    1065             :     // key: pair of residue/chain IDs
+    1066             :     std::pair<unsigned,std::string> key = Model_rlist_[ir];
+    1067             :     // old bfactor
+    1068           0 :     double bfactold = Model_b_[key];
+    1069             : 
+    1070             :     // propose move in bfactor
+    1071           0 :     double bfactnew = bfactold + dbfact_ * ( 2.0 * random_.RandU01() - 1.0 );
+    1072             :     // check boundaries
+    1073           0 :     if(bfactnew > bfactmax_) {bfactnew = 2.0*bfactmax_ - bfactnew;}
+    1074           0 :     if(bfactnew < bfactmin_) {bfactnew = 2.0*bfactmin_ - bfactnew;}
+    1075             : 
+    1076             :     // useful quantities
+    1077             :     std::map<unsigned, double> deltaov;
+    1078             : 
+    1079           0 :     #pragma omp parallel num_threads(OpenMP::getNumThreads())
+    1080             :     {
+    1081             :       // private variables
+    1082             :       std::map<unsigned, double> deltaov_l;
+    1083             :       #pragma omp for
+    1084             :       // cycle over all the atoms belonging to key (residue/chain)
+    1085             :       for(unsigned ia=0; ia<Model_resmap_[key].size(); ++ia) {
+    1086             : 
+    1087             :         // get atom id
+    1088             :         unsigned im = Model_resmap_[key][ia];
+    1089             :         // get atom type
+    1090             :         unsigned atype = Model_type_[im];
+    1091             :         // sigma for 5 Gaussians
+    1092             :         Vector5d m_s = Model_s_[atype];
+    1093             :         // prefactors
+    1094             :         Vector5d cfact = cfact_[atype];
+    1095             :         // and position
+    1096             :         Vector pos = getPosition(im);
+    1097             : 
+    1098             :         // cycle on all the neighboring voxels affected by a change in Bfactor
+    1099             :         for(unsigned i=0; i<Model_nb_[im].size(); ++i) {
+    1100             :           // voxel id
+    1101             :           unsigned id = Model_nb_[im][i];
+    1102             :           // get contribution to density in id before change
+    1103             :           double dold = get_overlap(Map_m_[id], pos, cfact, m_s, bfactold);
+    1104             :           // get contribution after change
+    1105             :           double dnew = get_overlap(Map_m_[id], pos, cfact, m_s, bfactnew);
+    1106             :           // update delta density
+    1107             :           deltaov_l[id] += dnew-dold;
+    1108             :         }
+    1109             :       }
+    1110             :       // add to global list
+    1111             :       #pragma omp critical
+    1112             :       {
+    1113             :         for(std::map<unsigned,double>::iterator itov=deltaov_l.begin(); itov!=deltaov_l.end(); ++itov)
+    1114             :           deltaov[itov->first] += itov->second;
+    1115             :       }
+    1116             :     }
+    1117             : 
+    1118             :     // now calculate new and old score
+    1119             :     double old_ene = 0.0;
+    1120             :     double new_ene = 0.0;
+    1121             : 
+    1122             :     // cycle on all affected voxels
+    1123           0 :     for(std::map<unsigned,double>::iterator itov=deltaov.begin(); itov!=deltaov.end(); ++itov) {
+    1124             :       // id of the component
+    1125           0 :       unsigned id = itov->first;
+    1126             :       // new value
+    1127           0 :       double ovmdnew = ovmd_[id]+itov->second;
+    1128             :       // deviations
+    1129           0 :       double devold = scale_ * ovmd_[id] + offset_ - ovdd_[id];
+    1130           0 :       double devnew = scale_ * ovmdnew   + offset_ - ovdd_[id];
+    1131             :       // inverse of sigma_min
+    1132           0 :       double ismin = ismin_[id];
+    1133             :       // scores
+    1134           0 :       if(devold==0.0) {
+    1135           0 :         old_ene += -kbt_ * std::log( 0.5 * sqrt2_pi_ * ismin );
+    1136             :       } else {
+    1137           0 :         old_ene += -kbt_ * std::log( 0.5 / devold * erf ( devold * inv_sqrt2_ * ismin ));
+    1138             :       }
+    1139           0 :       if(devnew==0.0) {
+    1140           0 :         new_ene += -kbt_ * std::log( 0.5 * sqrt2_pi_ * ismin );
+    1141             :       } else {
+    1142           0 :         new_ene += -kbt_ * std::log( 0.5 / devnew * erf ( devnew * inv_sqrt2_ * ismin ));
+    1143             :       }
+    1144             :     }
+    1145             : 
+    1146             :     // list of neighboring residues
+    1147           0 :     std::vector<unsigned> close = nl_res_[ir];
+    1148             :     // add restraint to keep Bfactors of close residues close
+    1149           0 :     for(unsigned i=0; i<close.size(); ++i) {
+    1150             :       // residue/chain IDs of neighbor
+    1151           0 :       std::pair<unsigned,std::string> keyn = Model_rlist_[close[i]];
+    1152             :       // deviations
+    1153           0 :       double devold = bfactold - Model_b_[keyn];
+    1154           0 :       double devnew = bfactnew - Model_b_[keyn];
+    1155             :       // inverse of sigma_min
+    1156           0 :       double ismin = 1.0 / bfactsig_;
+    1157             :       // scores
+    1158           0 :       if(devold==0.0) {
+    1159           0 :         old_ene += -kbt_ * std::log( 0.5 * sqrt2_pi_ * ismin );
+    1160             :       } else {
+    1161           0 :         old_ene += -kbt_ * std::log( 0.5 / devold * erf ( devold * inv_sqrt2_ * ismin ));
+    1162             :       }
+    1163           0 :       if(devnew==0.0) {
+    1164           0 :         new_ene += -kbt_ * std::log( 0.5 * sqrt2_pi_ * ismin );
+    1165             :       } else {
+    1166           0 :         new_ene += -kbt_ * std::log( 0.5 / devnew * erf ( devnew * inv_sqrt2_ * ismin ));
+    1167             :       }
+    1168             :     }
+    1169             : 
+    1170             :     // increment number of trials
+    1171           0 :     MCBtrials_ += 1.0;
+    1172             : 
+    1173             :     // accept or reject
+    1174             :     bool accept = false;
+    1175           0 :     if(bfactemin_) {
+    1176           0 :       if(new_ene < old_ene) accept = true;
+    1177             :     } else {
+    1178           0 :       accept = doAccept(old_ene, new_ene, kbt_);
+    1179             :     }
+    1180             : 
+    1181             :     // in case of acceptance
+    1182           0 :     if(accept) {
+    1183             :       // update acceptance rate
+    1184           0 :       MCBaccept_ += 1.0;
+    1185             :       // update bfactor
+    1186           0 :       Model_b_[key] = bfactnew;
+    1187             :       // change all the ovmd_ affected
+    1188           0 :       for(std::map<unsigned,double>::iterator itov=deltaov.begin(); itov!=deltaov.end(); ++itov)
+    1189           0 :         ovmd_[itov->first] += itov->second;
+    1190             :     }
+    1191             : 
+    1192             :   } // end cycle on bfactors
+    1193             : 
+    1194             : // update auxiliary lists (to update pref_gpu_, invs2_gpu_, and cut_ on CPU/GPU)
+    1195           0 :   get_auxiliary_vectors();
+    1196             : // update neighbor list (new cut_ + update pref_nl_gpu_ and invs2_nl_gpu_ on GPU)
+    1197           0 :   update_neighbor_list();
+    1198             : // recalculate fmod (to update derivatives)
+    1199           0 :   calculate_fmod();
+    1200           0 : }
+    1201             : 
+    1202             : // get overlap
+    1203           0 : double EMMIVOX::get_overlap(const Vector &d_m, const Vector &m_m,
+    1204             :                             const Vector5d &cfact, const Vector5d &m_s, double bfact)
+    1205             : {
+    1206             :   // calculate vector difference
+    1207           0 :   Vector md = delta(m_m, d_m);
+    1208             :   // norm squared
+    1209           0 :   double md2 = md[0]*md[0]+md[1]*md[1]+md[2]*md[2];
+    1210             :   // cycle on 5 Gaussians
+    1211             :   double ov_tot = 0.0;
+    1212           0 :   for(unsigned j=0; j<5; ++j) {
+    1213             :     // total value of b
+    1214           0 :     double m_b = m_s[j]+bfact/4.0;
+    1215             :     // calculate invs2
+    1216           0 :     double invs2 = 1.0/(inv_pi2_*m_b);
+    1217             :     // final calculation
+    1218           0 :     ov_tot += cfact[j] * pow(invs2, 1.5) * std::exp(-0.5 * md2 * invs2);
+    1219             :   }
+    1220           0 :   return ov_tot;
+    1221             : }
+    1222             : 
+    1223           0 : void EMMIVOX::update_neighbor_sphere()
+    1224             : {
+    1225             :   // number of atoms
+    1226           0 :   unsigned natoms = Model_type_.size();
+    1227             :   // clear neighbor sphere
+    1228             :   ns_.clear();
+    1229             :   // store reference positions
+    1230           0 :   refpos_ = getPositions();
+    1231             : 
+    1232             :   // cycle on voxels - in parallel
+    1233           0 :   #pragma omp parallel num_threads(OpenMP::getNumThreads())
+    1234             :   {
+    1235             :     // private variables
+    1236             :     std::vector< std::pair<unsigned,unsigned> > ns_l;
+    1237             :     #pragma omp for
+    1238             :     for(unsigned id=0; id<ovdd_.size(); ++id) {
+    1239             :       // grid point
+    1240             :       Vector d_m = Map_m_[id];
+    1241             :       // cycle on atoms
+    1242             :       for(unsigned im=0; im<natoms; ++im) {
+    1243             :         // calculate distance
+    1244             :         double dist = delta(getPosition(im), d_m).modulo();
+    1245             :         // add to local list
+    1246             :         if(dist<=2.0*cut_[im]) ns_l.push_back(std::make_pair(id,im));
+    1247             :       }
+    1248             :     }
+    1249             :     // add to global list
+    1250             :     #pragma omp critical
+    1251             :     ns_.insert(ns_.end(), ns_l.begin(), ns_l.end());
+    1252             :   }
+    1253           0 : }
+    1254             : 
+    1255           0 : bool EMMIVOX::do_neighbor_sphere()
+    1256             : {
+    1257           0 :   std::vector<double> dist(getPositions().size());
+    1258             :   bool update = false;
+    1259             : 
+    1260             : // calculate displacement
+    1261           0 :   #pragma omp parallel for num_threads(OpenMP::getNumThreads())
+    1262             :   for(unsigned im=0; im<dist.size(); ++im) {
+    1263             :     dist[im] = delta(getPosition(im),refpos_[im]).modulo()/cut_[im];
+    1264             :   }
+    1265             : 
+    1266             : // check if update or not
+    1267           0 :   double maxdist = *max_element(dist.begin(), dist.end());
+    1268           0 :   if(maxdist>=1.0) update=true;
+    1269             : 
+    1270             : // return if update or not
+    1271           0 :   return update;
+    1272             : }
+    1273             : 
+    1274           0 : void EMMIVOX::update_neighbor_list()
+    1275             : {
+    1276             :   // number of atoms
+    1277           0 :   unsigned natoms = Model_type_.size();
+    1278             :   // clear neighbor list
+    1279             :   nl_.clear();
+    1280             : 
+    1281             :   // cycle on neighbour sphere - in parallel
+    1282           0 :   #pragma omp parallel num_threads(OpenMP::getNumThreads())
+    1283             :   {
+    1284             :     // private variables
+    1285             :     std::vector< std::pair<unsigned,unsigned> > nl_l;
+    1286             :     #pragma omp for
+    1287             :     for(unsigned long long i=0; i<ns_.size(); ++i) {
+    1288             :       // calculate distance
+    1289             :       double dist = delta(Map_m_[ns_[i].first], getPosition(ns_[i].second)).modulo();
+    1290             :       // add to local neighbour list
+    1291             :       if(dist<=cut_[ns_[i].second]) nl_l.push_back(ns_[i]);
+    1292             :     }
+    1293             :     // add to global list
+    1294             :     #pragma omp critical
+    1295             :     nl_.insert(nl_.end(), nl_l.begin(), nl_l.end());
+    1296             :   }
+    1297             : 
+    1298             :   // new dimension of neighbor list
+    1299             :   unsigned long long nl_size = nl_.size();
+    1300             :   // now resize derivatives
+    1301           0 :   ovmd_der_.resize(nl_size);
+    1302             : 
+    1303             :   // in case of B-factors sampling - at the right step
+    1304           0 :   if(dbfact_>0 && getStep()%MCBstride_==0) {
+    1305             :     // clear vectors
+    1306           0 :     Model_nb_.clear(); Model_nb_.resize(natoms);
+    1307             :     // cycle over the neighbor list to creat a list of voxels per atom
+    1308           0 :     #pragma omp parallel num_threads(OpenMP::getNumThreads())
+    1309             :     {
+    1310             :       // private variables
+    1311             :       std::vector< std::vector<unsigned> > Model_nb_l(natoms);
+    1312             :       #pragma omp for
+    1313             :       for(unsigned long long i=0; i<nl_size; ++i) {
+    1314             :         Model_nb_l[nl_[i].second].push_back(nl_[i].first);
+    1315             :       }
+    1316             :       // add to global list
+    1317             :       #pragma omp critical
+    1318             :       {
+    1319             :         for(unsigned i=0; i<natoms; ++i)
+    1320             :           Model_nb_[i].insert(Model_nb_[i].end(), Model_nb_l[i].begin(), Model_nb_l[i].end());
+    1321             :       }
+    1322             :     }
+    1323             :   }
+    1324             : 
+    1325             :   // transfer data to gpu
+    1326           0 :   update_gpu();
+    1327           0 : }
+    1328             : 
+    1329           0 : void EMMIVOX::update_gpu()
+    1330             : {
+    1331             :   // dimension of neighbor list
+    1332             :   long long nl_size = nl_.size();
+    1333             :   // create useful vectors
+    1334           0 :   std::vector<int> nl_id(nl_size), nl_im(nl_size);
+    1335           0 :   #pragma omp parallel for num_threads(OpenMP::getNumThreads())
+    1336             :   for(unsigned long long i=0; i<nl_size; ++i) {
+    1337             :     nl_id[i] = static_cast<int>(nl_[i].first);
+    1338             :     nl_im[i] = static_cast<int>(nl_[i].second);
+    1339             :   }
+    1340             :   // create tensors on device
+    1341           0 :   nl_id_gpu_ = torch::from_blob(nl_id.data(), {nl_size}, torch::kInt32).clone().to(device_t_);
+    1342           0 :   nl_im_gpu_ = torch::from_blob(nl_im.data(), {nl_size}, torch::kInt32).clone().to(device_t_);
+    1343             :   // now we need to create pref_nl_gpu_ [5,nl_size]
+    1344           0 :   pref_nl_gpu_  = torch::index_select(pref_gpu_,1,nl_im_gpu_);
+    1345             :   // and invs2_nl_gpu_ [5,nl_size]
+    1346           0 :   invs2_nl_gpu_ = torch::index_select(invs2_gpu_,1,nl_im_gpu_);
+    1347             :   // and Map_m_nl_gpu_ [3,nl_size]
+    1348           0 :   Map_m_nl_gpu_ = torch::index_select(Map_m_gpu_,1,nl_id_gpu_);
+    1349           0 : }
+    1350             : 
+    1351           0 : void EMMIVOX::prepare()
+    1352             : {
+    1353           0 :   if(getExchangeStep()) first_time_=true;
+    1354           0 : }
+    1355             : 
+    1356             : // calculate forward model on gpu
+    1357           0 : void EMMIVOX::calculate_fmod()
+    1358             : {
+    1359             :   // number of atoms
+    1360           0 :   int natoms = Model_type_.size();
+    1361             :   // number of data points
+    1362           0 :   int nd = ovdd_.size();
+    1363             : 
+    1364             :   // fill positions in in parallel
+    1365           0 :   std::vector<double> posg(3*natoms);
+    1366           0 :   #pragma omp parallel for num_threads(OpenMP::getNumThreads())
+    1367             :   for (int i=0; i<natoms; ++i) {
+    1368             :     // fill vectors
+    1369             :     posg[i]          = getPosition(i)[0];
+    1370             :     posg[i+natoms]   = getPosition(i)[1];
+    1371             :     posg[i+2*natoms] = getPosition(i)[2];
+    1372             :   }
+    1373             :   // transfer positions to pos_gpu [3,natoms]
+    1374           0 :   torch::Tensor pos_gpu = torch::from_blob(posg.data(), {3,natoms}, torch::kFloat64).to(torch::kFloat32).to(device_t_);
+    1375             :   // create pos_nl_gpu_ [3,nl_size]
+    1376           0 :   torch::Tensor pos_nl_gpu = torch::index_select(pos_gpu,1,nl_im_gpu_);
+    1377             :   // calculate vector difference [3,nl_size]
+    1378           0 :   torch::Tensor md = Map_m_nl_gpu_ - pos_nl_gpu;
+    1379             :   // calculate norm squared by column [1,nl_size]
+    1380           0 :   torch::Tensor md2 = torch::sum(md*md,0);
+    1381             :   // calculate density [5,nl_size]
+    1382           0 :   torch::Tensor ov = pref_nl_gpu_ * torch::exp(-0.5 * md2 * invs2_nl_gpu_);
+    1383             :   // and derivatives [5,nl_size]
+    1384           0 :   ovmd_der_gpu_ = invs2_nl_gpu_ * ov;
+    1385             :   // sum density over 5 columns [1,nl_size]
+    1386           0 :   ov = torch::sum(ov,0);
+    1387             :   // sum contributions from the same atom
+    1388           0 :   auto options = torch::TensorOptions().device(device_t_).dtype(torch::kFloat32);
+    1389           0 :   ovmd_gpu_ = torch::zeros({nd}, options);
+    1390           0 :   ovmd_gpu_.index_add_(0, nl_id_gpu_, ov);
+    1391             :   // sum derivatives over 5 rows [1,nl_size] and multiply by md [3,nl_size]
+    1392           0 :   ovmd_der_gpu_ = md * torch::sum(ovmd_der_gpu_,0);
+    1393             : 
+    1394             :   // in case of metainference: average them across replicas
+    1395           0 :   if(!no_aver_ && nrep_>1) {
+    1396             :     // communicate ovmd_gpu_ to CPU [1, nd]
+    1397           0 :     torch::Tensor ovmd_cpu = ovmd_gpu_.detach().to(torch::kCPU).to(torch::kFloat64);
+    1398             :     // and put them in ovmd_
+    1399           0 :     ovmd_ = std::vector<double>(ovmd_cpu.data_ptr<double>(), ovmd_cpu.data_ptr<double>() + ovmd_cpu.numel());
+    1400             :     // sum across replicas
+    1401           0 :     multi_sim_comm.Sum(&ovmd_[0], nd);
+    1402             :     // and divide by number of replicas
+    1403           0 :     double escale = 1.0 / static_cast<double>(nrep_);
+    1404           0 :     for(int i=0; i<nd; ++i) ovmd_[i] *= escale;
+    1405             :     // put back on device
+    1406           0 :     ovmd_gpu_ = torch::from_blob(ovmd_.data(), {nd}, torch::kFloat64).to(torch::kFloat32).to(device_t_);
+    1407             :   }
+    1408             : 
+    1409             :   // communicate back model density
+    1410             :   // this is needed only in certain situations
+    1411           0 :   long int step = getStep();
+    1412             :   bool do_comm = false;
+    1413           0 :   if(mapstride_>0 && step%mapstride_==0) do_comm = true;
+    1414           0 :   if(dbfact_>0    && step%MCBstride_==0) do_comm = true;
+    1415           0 :   if(do_corr_) do_comm = true;
+    1416             :   // in case of metainference: already communicated
+    1417           0 :   if(!no_aver_ && nrep_>1) do_comm = false;
+    1418           0 :   if(do_comm) {
+    1419             :     // communicate ovmd_gpu_ to CPU [1, nd]
+    1420           0 :     torch::Tensor ovmd_cpu = ovmd_gpu_.detach().to(torch::kCPU).to(torch::kFloat64);
+    1421             :     // and put them in ovmd_
+    1422           0 :     ovmd_ = std::vector<double>(ovmd_cpu.data_ptr<double>(), ovmd_cpu.data_ptr<double>() + ovmd_cpu.numel());
+    1423             :   }
+    1424           0 : }
+    1425             : 
+    1426             : // calculate score
+    1427           0 : void EMMIVOX::calculate_score()
+    1428             : {
+    1429             :   // number of atoms
+    1430           0 :   int natoms = Model_type_.size();
+    1431             : 
+    1432             :   // calculate deviation model/data [1, nd]
+    1433           0 :   torch::Tensor dev = scale_ * ovmd_gpu_ + offset_ - ovdd_gpu_;
+    1434             :   // error function [1, nd]
+    1435           0 :   torch::Tensor errf = torch::erf( dev * inv_sqrt2_ * ismin_gpu_ );
+    1436             :   // take care of dev = zero
+    1437           0 :   torch::Tensor zeros_d = torch::ne(dev, 0.0);
+    1438             :   // redefine dev
+    1439           0 :   dev = dev * zeros_d + eps_ * torch::logical_not(zeros_d);
+    1440             :   // take care of errf = zero
+    1441           0 :   torch::Tensor zeros_e = torch::ne(errf, 0.0);
+    1442             :   // redefine errf
+    1443           0 :   errf = errf * zeros_e + eps_ * torch::logical_not(zeros_e);
+    1444             :   // logical AND: both dev and errf different from zero
+    1445             :   torch::Tensor zeros = torch::logical_and(zeros_d, zeros_e);
+    1446             :   // energy - with limit dev going to zero
+    1447           0 :   torch::Tensor ene = 0.5 * ( errf / dev * zeros + torch::logical_not(zeros) * sqrt2_pi_ *  ismin_gpu_);
+    1448             :   // logarithm and sum
+    1449           0 :   ene = -kbt_ * torch::sum(torch::log(ene));
+    1450             :   // and derivatives [1, nd]
+    1451           0 :   torch::Tensor d_der = -kbt_ * zeros * ( sqrt2_pi_ * torch::exp( -0.5 * dev * dev * ismin_gpu_ * ismin_gpu_ ) * ismin_gpu_ / errf - 1.0 / dev );
+    1452             :   // tensor for derivatives wrt atoms [1, nl_size]
+    1453           0 :   torch::Tensor der_gpu = torch::index_select(d_der,0,nl_id_gpu_);
+    1454             :   // multiply by ovmd_der_gpu_ and scale [3, nl_size]
+    1455           0 :   der_gpu = ovmd_der_gpu_ * scale_ * der_gpu;
+    1456             :   // sum contributions for each atom
+    1457           0 :   auto options = torch::TensorOptions().device(device_t_).dtype(torch::kFloat32);
+    1458           0 :   torch::Tensor atoms_der_gpu = torch::zeros({3,natoms}, options);
+    1459           0 :   atoms_der_gpu.index_add_(1, nl_im_gpu_, der_gpu);
+    1460             : 
+    1461             :   // FINAL STUFF
+    1462             :   //
+    1463             :   // 1) communicate total energy to CPU
+    1464           0 :   torch::Tensor ene_cpu = ene.detach().to(torch::kCPU).to(torch::kFloat64);
+    1465           0 :   ene_ = *ene_cpu.data_ptr<double>();
+    1466             :   // with marginal, simply multiply by number of replicas!
+    1467           0 :   if(!no_aver_ && nrep_>1) ene_ *= static_cast<double>(nrep_);
+    1468             :   //
+    1469             :   // 2) communicate derivatives to CPU
+    1470           0 :   torch::Tensor atom_der_cpu = atoms_der_gpu.detach().to(torch::kCPU).to(torch::kFloat64);
+    1471             :   // convert to std::vector<double>
+    1472           0 :   std::vector<double> atom_der = std::vector<double>(atom_der_cpu.data_ptr<double>(), atom_der_cpu.data_ptr<double>() + atom_der_cpu.numel());
+    1473             :   // and put in atom_der_
+    1474           0 :   #pragma omp parallel for num_threads(OpenMP::getNumThreads())
+    1475             :   for(int i=0; i<natoms; ++i) {
+    1476             :     atom_der_[i] = Vector(atom_der[i],atom_der[i+natoms],atom_der[i+2*natoms]);
+    1477             :   }
+    1478             :   //
+    1479             :   // 3) calculate virial on CPU
+    1480           0 :   Tensor virial;
+    1481             :   // declare omp reduction for Tensors
+    1482             :   #pragma omp declare reduction( sumTensor : Tensor : omp_out += omp_in )
+    1483             : 
+    1484           0 :   #pragma omp parallel for num_threads(OpenMP::getNumThreads()) reduction (sumTensor : virial)
+    1485             :   for(int i=0; i<natoms; ++i) {
+    1486             :     virial += Tensor(getPosition(i), -atom_der_[i]);
+    1487             :   }
+    1488             :   // store virial
+    1489           0 :   virial_ = virial;
+    1490           0 : }
+    1491             : 
+    1492           0 : void EMMIVOX::calculate()
+    1493             : {
+    1494             :   // get time step
+    1495           0 :   long int step = getStep();
+    1496             : 
+    1497             :   // set temperature value
+    1498           0 :   getPntrToComponent("kbt")->set(kbt_);
+    1499             : 
+    1500             :   // neighbor list update
+    1501           0 :   if(first_time_ || getExchangeStep() || step%nl_stride_==0) {
+    1502             :     // check if time to update neighbor sphere
+    1503             :     bool update = false;
+    1504           0 :     if(first_time_ || getExchangeStep()) update = true;
+    1505           0 :     else update = do_neighbor_sphere();
+    1506             :     // update neighbor sphere
+    1507           0 :     if(update) update_neighbor_sphere();
+    1508             :     // update neighbor list
+    1509           0 :     update_neighbor_list();
+    1510             :     // set flag
+    1511           0 :     first_time_=false;
+    1512             :   }
+    1513             : 
+    1514             :   // calculate forward model
+    1515           0 :   calculate_fmod();
+    1516             : 
+    1517             :   // Monte Carlo on bfactors
+    1518           0 :   if(dbfact_>0) {
+    1519             :     double acc = 0.0;
+    1520             :     // do Monte Carlo
+    1521           0 :     if(step%MCBstride_==0 && !getExchangeStep() && step>0) doMonteCarloBfact();
+    1522             :     // calculate acceptance ratio
+    1523           0 :     if(MCBtrials_>0) acc = MCBaccept_ / MCBtrials_;
+    1524             :     // set value
+    1525           0 :     getPntrToComponent("accB")->set(acc);
+    1526             :   }
+    1527             : 
+    1528             :   // calculate score
+    1529           0 :   calculate_score();
+    1530             : 
+    1531             :   // set score, virial, and derivatives
+    1532           0 :   Value* score = getPntrToComponent("scoreb");
+    1533           0 :   score->set(ene_);
+    1534           0 :   setBoxDerivatives(score, virial_);
+    1535           0 :   #pragma omp parallel for
+    1536             :   for(unsigned i=0; i<atom_der_.size(); ++i) setAtomsDerivatives(score, i, atom_der_[i]);
+    1537             :   // set scale and offset value
+    1538           0 :   getPntrToComponent("scale")->set(scale_);
+    1539           0 :   getPntrToComponent("offset")->set(offset_);
+    1540             :   // calculate correlation coefficient
+    1541           0 :   if(do_corr_) calculate_corr();
+    1542             :   // PRINT other quantities to files
+    1543             :   // - status file
+    1544           0 :   if(step%statusstride_==0) print_status(step);
+    1545             :   // - density file
+    1546           0 :   if(mapstride_>0 && step%mapstride_==0) write_model_density(step);
+    1547           0 : }
+    1548             : 
+    1549           0 : void EMMIVOX::calculate_corr()
+    1550             : {
+    1551             : // number of data points
+    1552           0 :   double nd = static_cast<double>(ovdd_.size());
+    1553             : // average ovmd_ and ovdd_
+    1554           0 :   double ave_md = std::accumulate(ovmd_.begin(), ovmd_.end(), 0.) / nd;
+    1555           0 :   double ave_dd = std::accumulate(ovdd_.begin(), ovdd_.end(), 0.) / nd;
+    1556             : // calculate correlation
+    1557             :   double num = 0.;
+    1558             :   double den1 = 0.;
+    1559             :   double den2 = 0.;
+    1560           0 :   #pragma omp parallel for num_threads(OpenMP::getNumThreads()) reduction( + : num, den1, den2)
+    1561             :   for(unsigned i=0; i<ovdd_.size(); ++i) {
+    1562             :     double md = ovmd_[i]-ave_md;
+    1563             :     double dd = ovdd_[i]-ave_dd;
+    1564             :     num  += md*dd;
+    1565             :     den1 += md*md;
+    1566             :     den2 += dd*dd;
+    1567             :   }
+    1568             : // correlation coefficient
+    1569           0 :   double cc = num / sqrt(den1*den2);
+    1570             : // set plumed
+    1571           0 :   getPntrToComponent("corr")->set(cc);
+    1572           0 : }
+    1573             : 
+    1574             : 
+    1575             : }
+    1576             : }
+    1577             : 
+    1578             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/FretEfficiency.cpp.func-sort-c.html b/coverage/isdb/FretEfficiency.cpp.func-sort-c.html new file mode 100644 index 000000000000..0f0cdc465c2b --- /dev/null +++ b/coverage/isdb/FretEfficiency.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - isdb/FretEfficiency.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - FretEfficiency.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:343694.4 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb14FretEfficiencyC2ERKNS_13ActionOptionsE0
_ZN4PLMD4isdb14FretEfficiencyC1ERKNS_13ActionOptionsE14
_ZN4PLMD4isdb14FretEfficiency16registerKeywordsERNS_8KeywordsE16
_ZN4PLMD4isdb14FretEfficiency9calculateEv238
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/FretEfficiency.cpp.func.html b/coverage/isdb/FretEfficiency.cpp.func.html new file mode 100644 index 000000000000..bc8bb2af0829 --- /dev/null +++ b/coverage/isdb/FretEfficiency.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - isdb/FretEfficiency.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - FretEfficiency.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:343694.4 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb14FretEfficiency16registerKeywordsERNS_8KeywordsE16
_ZN4PLMD4isdb14FretEfficiency9calculateEv238
_ZN4PLMD4isdb14FretEfficiencyC1ERKNS_13ActionOptionsE14
_ZN4PLMD4isdb14FretEfficiencyC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/FretEfficiency.cpp.gcov.html b/coverage/isdb/FretEfficiency.cpp.gcov.html new file mode 100644 index 000000000000..e2127c0dfbd1 --- /dev/null +++ b/coverage/isdb/FretEfficiency.cpp.gcov.html @@ -0,0 +1,232 @@ + + + + + + + + LCOV - plumed test coverage - isdb/FretEfficiency.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - FretEfficiency.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:343694.4 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "colvar/Colvar.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "core/PlumedMain.h"
+      25             : #include "tools/Pbc.h"
+      26             : 
+      27             : #include <string>
+      28             : #include <cmath>
+      29             : 
+      30             : namespace PLMD {
+      31             : namespace isdb {
+      32             : 
+      33             : //+PLUMEDOC ISDB_COLVAR FRET
+      34             : /*
+      35             : Calculates the FRET efficiency between a pair of atoms.
+      36             : The efficiency is calculated using the Forster relation:
+      37             : 
+      38             : \f[
+      39             : E=\frac{1}{1+(R/R_0)^6}
+      40             : \f]
+      41             : 
+      42             : where \f$R\f$ is the distance and \f$R_0\f$ is the Forster radius.
+      43             : 
+      44             : By default the distance is computed taking into account periodic
+      45             : boundary conditions. This behavior can be changed with the NOPBC flag.
+      46             : 
+      47             : 
+      48             : \par Examples
+      49             : 
+      50             : The following input tells plumed to print the FRET efficiencies
+      51             : calculated as a function of the distance between atoms 3 and 5 and
+      52             : the distance between atoms 2 and 4.
+      53             : \plumedfile
+      54             : fe1:  FRET ATOMS=3,5 R0=5.5
+      55             : fe2:  FRET ATOMS=2,4 R0=5.5
+      56             : PRINT ARG=fe1,fe2
+      57             : \endplumedfile
+      58             : 
+      59             : The following input computes the FRET efficiency calculated on the
+      60             : terminal atoms of a polymer
+      61             : of 100 atoms and keeps it at a value around 0.5.
+      62             : \plumedfile
+      63             : WHOLEMOLECULES ENTITY0=1-100
+      64             : fe: FRET ATOMS=1,100 R0=5.5 NOPBC
+      65             : RESTRAINT ARG=fe KAPPA=100 AT=0.5
+      66             : \endplumedfile
+      67             : 
+      68             : Notice that NOPBC is used
+      69             : to be sure that if the distance is larger than half the simulation
+      70             : box the distance is compute properly. Also notice that, since many MD
+      71             : codes break molecules across cell boundary, it might be necessary to
+      72             : use the \ref WHOLEMOLECULES keyword (also notice that it should be
+      73             : _before_ FRET).
+      74             : Just be sure that the ordered list provide to WHOLEMOLECULES has the following
+      75             : properties:
+      76             : - Consecutive atoms should be closer than half-cell throughout the entire simulation.
+      77             : - Atoms required later for the distance (e.g. 1 and 100) should be included in the list
+      78             : 
+      79             : */
+      80             : //+ENDPLUMEDOC
+      81             : 
+      82             : class FretEfficiency : public Colvar {
+      83             :   bool pbc;
+      84             :   double R0_;
+      85             : 
+      86             : public:
+      87             :   static void registerKeywords( Keywords& keys );
+      88             :   explicit FretEfficiency(const ActionOptions&);
+      89             : // active methods:
+      90             :   void calculate() override;
+      91             : };
+      92             : 
+      93             : PLUMED_REGISTER_ACTION(FretEfficiency,"FRET")
+      94             : 
+      95          16 : void FretEfficiency::registerKeywords( Keywords& keys ) {
+      96          16 :   Colvar::registerKeywords( keys );
+      97          32 :   keys.add("atoms","ATOMS","the pair of atom that we are calculating the distance between");
+      98          32 :   keys.add("compulsory","R0","The value of the Forster radius.");
+      99          16 : }
+     100             : 
+     101          14 : FretEfficiency::FretEfficiency(const ActionOptions&ao):
+     102             :   PLUMED_COLVAR_INIT(ao),
+     103          14 :   pbc(true)
+     104             : {
+     105             :   std::vector<AtomNumber> atoms;
+     106          28 :   parseAtomList("ATOMS",atoms);
+     107          14 :   if(atoms.size()!=2)
+     108           0 :     error("Number of specified atoms should be 2");
+     109          14 :   parse("R0",R0_);
+     110          14 :   bool nopbc=!pbc;
+     111          14 :   parseFlag("NOPBC",nopbc);
+     112          14 :   pbc=!nopbc;
+     113          14 :   checkRead();
+     114             : 
+     115          14 :   log.printf("  between atoms %d %d\n",atoms[0].serial(),atoms[1].serial());
+     116          14 :   log.printf("  with Forster radius set to %lf\n",R0_);
+     117             : 
+     118          14 :   if(pbc) log.printf("  using periodic boundary conditions\n");
+     119           0 :   else    log.printf("  without periodic boundary conditions\n");
+     120             : 
+     121          28 :   log << " Bibliography" << plumed.cite("Bonomi, Camilloni, Bioinformatics, 33, 3999 (2017)") << "\n";
+     122             : 
+     123          14 :   addValueWithDerivatives();
+     124          14 :   setNotPeriodic();
+     125             : 
+     126          14 :   requestAtoms(atoms);
+     127          14 : }
+     128             : 
+     129             : 
+     130             : // calculator
+     131         238 : void FretEfficiency::calculate() {
+     132             : 
+     133         238 :   if(pbc) makeWhole();
+     134             : 
+     135         238 :   Vector distance=delta(getPosition(0),getPosition(1));
+     136         238 :   const double dist_mod=distance.modulo();
+     137         238 :   const double inv_dist_mod=1.0/dist_mod;
+     138             : 
+     139         238 :   const double ratiosix=std::pow(dist_mod/R0_,6);
+     140         238 :   const double fret_eff = 1.0/(1.0+ratiosix);
+     141             : 
+     142         238 :   const double der = -6.0*fret_eff*fret_eff*ratiosix*inv_dist_mod;
+     143             : 
+     144         238 :   setAtomsDerivatives(0,-inv_dist_mod*der*distance);
+     145         476 :   setAtomsDerivatives(1, inv_dist_mod*der*distance);
+     146             :   setBoxDerivativesNoPbc();
+     147         238 :   setValue(fret_eff);
+     148             : 
+     149         238 : }
+     150             : 
+     151             : }
+     152             : }
+     153             : 
+     154             : 
+     155             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/Jcoupling.cpp.func-sort-c.html b/coverage/isdb/Jcoupling.cpp.func-sort-c.html new file mode 100644 index 000000000000..cce7dfc687f3 --- /dev/null +++ b/coverage/isdb/Jcoupling.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - isdb/Jcoupling.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - Jcoupling.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:16017293.0 %
Date:2024-04-19 12:12:35Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb9JCouplingC2ERKNS_13ActionOptionsE0
_ZN4PLMD4isdb9JCouplingC1ERKNS_13ActionOptionsE6
_ZN4PLMD4isdb9JCoupling16registerKeywordsERNS_8KeywordsE8
_ZN4PLMD4isdb9JCoupling6updateEv16
_ZN4PLMD4isdb9JCoupling9calculateEv16
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/Jcoupling.cpp.func.html b/coverage/isdb/Jcoupling.cpp.func.html new file mode 100644 index 000000000000..b24f11238432 --- /dev/null +++ b/coverage/isdb/Jcoupling.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - isdb/Jcoupling.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - Jcoupling.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:16017293.0 %
Date:2024-04-19 12:12:35Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb9JCoupling16registerKeywordsERNS_8KeywordsE8
_ZN4PLMD4isdb9JCoupling6updateEv16
_ZN4PLMD4isdb9JCoupling9calculateEv16
_ZN4PLMD4isdb9JCouplingC1ERKNS_13ActionOptionsE6
_ZN4PLMD4isdb9JCouplingC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/Jcoupling.cpp.gcov.html b/coverage/isdb/Jcoupling.cpp.gcov.html new file mode 100644 index 000000000000..c18fc79c77d2 --- /dev/null +++ b/coverage/isdb/Jcoupling.cpp.gcov.html @@ -0,0 +1,471 @@ + + + + + + + + LCOV - plumed test coverage - isdb/Jcoupling.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - Jcoupling.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:16017293.0 %
Date:2024-04-19 12:12:35Functions:4580.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "MetainferenceBase.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "tools/Pbc.h"
+      25             : #include "tools/Torsion.h"
+      26             : 
+      27             : namespace PLMD {
+      28             : namespace isdb {
+      29             : 
+      30             : //+PLUMEDOC ISDB_COLVAR JCOUPLING
+      31             : /*
+      32             : Calculates \f$^3J\f$ coupling constants for a dihedral angle.
+      33             : 
+      34             : The J-coupling between two atoms is given by the Karplus relation:
+      35             : 
+      36             : \f[
+      37             : ^3J(\theta)=A\cos^2(\theta+\Delta\theta)+B\cos(\theta+\Delta\theta)+C
+      38             : \f]
+      39             : 
+      40             : where \f$A\f$, \f$B\f$ and \f$C\f$ are the Karplus parameters and \f$\Delta\theta\f$ is an additional constant
+      41             : added on to the dihedral angle \f$\theta\f$. The Karplus parameters are determined empirically and are dependent
+      42             : on the type of J-coupling.
+      43             : 
+      44             : This collective variable computes the J-couplings for a set of atoms defining a dihedral angle. You can specify
+      45             : the atoms involved using the \ref MOLINFO notation. You can also specify the experimental couplings using the
+      46             :  COUPLING keywords. These will be included in the output. You must choose the type of
+      47             : coupling using the type keyword, you can also supply custom Karplus parameters using TYPE=CUSTOM and the A, B, C
+      48             : and SHIFT keywords. You will need to make sure you are using the correct dihedral angle:
+      49             : 
+      50             : - Ha-N: \f$\psi\f$
+      51             : - Ha-HN: \f$\phi\f$
+      52             : - N-C\f$\gamma\f$: \f$\chi_1\f$
+      53             : - CO-C\f$\gamma\f$: \f$\chi_1\f$
+      54             : 
+      55             : J-couplings can be used to calculate a Metainference score using the internal keyword DOSCORE and all the options
+      56             : of \ref METAINFERENCE .
+      57             : 
+      58             : \par Examples
+      59             : 
+      60             : In the following example we calculate the Ha-N J-coupling from a set of atoms involved in
+      61             : dihedral \f$\psi\f$ angles in the peptide backbone. We also add the experimental data points and compute
+      62             : the correlation and other measures and finally print the results.
+      63             : 
+      64             : \plumedfile
+      65             : #SETTINGS MOLFILE=regtest/basic/rt32/helix.pdb
+      66             : MOLINFO MOLTYPE=protein STRUCTURE=peptide.pdb
+      67             : WHOLEMOLECULES ENTITY0=1-111
+      68             : 
+      69             : JCOUPLING ...
+      70             :     TYPE=HAN
+      71             :     ATOMS1=@psi-2 COUPLING1=-0.49
+      72             :     ATOMS2=@psi-4 COUPLING2=-0.54
+      73             :     ATOMS3=@psi-5 COUPLING3=-0.53
+      74             :     ATOMS4=@psi-7 COUPLING4=-0.39
+      75             :     ATOMS5=@psi-8 COUPLING5=-0.39
+      76             :     LABEL=jhan
+      77             : ... JCOUPLING
+      78             : 
+      79             : jhanst: STATS ARG=(jhan\.j-.*) PARARG=(jhan\.exp-.*)
+      80             : 
+      81             : PRINT ARG=jhanst.*,jhan.* FILE=COLVAR STRIDE=100
+      82             : \endplumedfile
+      83             : 
+      84             : */
+      85             : //+ENDPLUMEDOC
+      86             : 
+      87             : class JCoupling :
+      88             :   public MetainferenceBase
+      89             : {
+      90             : private:
+      91             :   bool pbc;
+      92             :   enum { HAN, HAHN, CCG, NCG, CUSTOM };
+      93             :   unsigned ncoupl_;
+      94             :   double ka_;
+      95             :   double kb_;
+      96             :   double kc_;
+      97             :   double kshift_;
+      98             : 
+      99             : public:
+     100             :   static void registerKeywords(Keywords& keys);
+     101             :   explicit JCoupling(const ActionOptions&);
+     102             :   void calculate() override;
+     103             :   void update() override;
+     104             : };
+     105             : 
+     106             : PLUMED_REGISTER_ACTION(JCoupling, "JCOUPLING")
+     107             : 
+     108           8 : void JCoupling::registerKeywords(Keywords& keys) {
+     109           8 :   componentsAreNotOptional(keys);
+     110           8 :   MetainferenceBase::registerKeywords(keys);
+     111          16 :   keys.addFlag("NOPBC",false,"ignore the periodic boundary conditions when calculating distances");
+     112          16 :   keys.add("numbered", "ATOMS", "the 4 atoms involved in each of the bonds for which you wish to calculate the J-coupling. "
+     113             :            "Keywords like ATOMS1, ATOMS2, ATOMS3,... should be listed and one J-coupling will be "
+     114             :            "calculated for each ATOMS keyword you specify.");
+     115          16 :   keys.reset_style("ATOMS", "atoms");
+     116          16 :   keys.add("compulsory", "TYPE", "Type of J-coupling to compute (HAN,HAHN,CCG,NCG,CUSTOM)");
+     117          16 :   keys.add("optional", "A", "Karplus parameter A");
+     118          16 :   keys.add("optional", "B", "Karplus parameter B");
+     119          16 :   keys.add("optional", "C", "Karplus parameter C");
+     120          16 :   keys.add("optional", "SHIFT", "Angle shift in radians");
+     121          16 :   keys.add("numbered", "COUPLING", "Add an experimental value for each coupling");
+     122          16 :   keys.addOutputComponent("j", "default", "the calculated J-coupling");
+     123          16 :   keys.addOutputComponent("exp", "COUPLING", "the experimental J-coupling");
+     124           8 : }
+     125             : 
+     126           6 : JCoupling::JCoupling(const ActionOptions&ao):
+     127             :   PLUMED_METAINF_INIT(ao),
+     128           6 :   pbc(true)
+     129             : {
+     130           6 :   bool nopbc = !pbc;
+     131           6 :   parseFlag("NOPBC", nopbc);
+     132           6 :   pbc =! nopbc;
+     133             : 
+     134             :   // Read in the atoms
+     135             :   std::vector<AtomNumber> t, atoms;
+     136           6 :   for (int i = 1; ; ++i) {
+     137          68 :     parseAtomList("ATOMS", i, t );
+     138          34 :     if (t.empty()) {
+     139             :       break;
+     140             :     }
+     141             : 
+     142          28 :     if (t.size() != 4) {
+     143             :       std::string ss;
+     144           0 :       Tools::convert(i, ss);
+     145           0 :       error("ATOMS" + ss + " keyword has the wrong number of atoms");
+     146             :     }
+     147             : 
+     148             :     // This makes the distance calculation easier later on (see Torsion implementation)
+     149          28 :     atoms.push_back(t[0]);
+     150          28 :     atoms.push_back(t[1]);
+     151          28 :     atoms.push_back(t[1]);
+     152          28 :     atoms.push_back(t[2]);
+     153          28 :     atoms.push_back(t[2]);
+     154          28 :     atoms.push_back(t[3]);
+     155          28 :     t.resize(0);
+     156          28 :   }
+     157             : 
+     158             :   // We now have 6 atoms per datapoint
+     159           6 :   ncoupl_ = atoms.size()/6;
+     160             : 
+     161             :   // Parse J-Coupling type, this will determine the Karplus parameters
+     162             :   unsigned jtype_ = CUSTOM;
+     163             :   std::string string_type;
+     164          12 :   parse("TYPE", string_type);
+     165           6 :   if(string_type == "HAN") {
+     166             :     jtype_ = HAN;
+     167           5 :   } else if(string_type == "HAHN") {
+     168             :     jtype_ = HAHN;
+     169           2 :   } else if(string_type == "CCG") {
+     170             :     jtype_ = CCG;
+     171           1 :   } else if(string_type == "NCG") {
+     172             :     jtype_ = NCG;
+     173           0 :   } else if(string_type == "CUSTOM") {
+     174             :     jtype_ = CUSTOM;
+     175             :   } else {
+     176           0 :     error("Unknown J-coupling type!");
+     177             :   }
+     178             : 
+     179             :   // Optionally add an experimental value (like with RDCs)
+     180             :   std::vector<double> coupl;
+     181           6 :   coupl.resize( ncoupl_ );
+     182             :   unsigned ntarget=0;
+     183          13 :   for(unsigned i=0; i<ncoupl_; ++i) {
+     184          24 :     if( !parseNumbered( "COUPLING", i+1, coupl[i] ) ) break;
+     185           7 :     ntarget++;
+     186             :   }
+     187             :   bool addcoupling=false;
+     188           6 :   if(ntarget!=ncoupl_ && ntarget!=0) error("found wrong number of COUPLING values");
+     189           6 :   if(ntarget==ncoupl_) addcoupling=true;
+     190           6 :   if(getDoScore()&&!addcoupling) error("with DOSCORE you need to set the COUPLING values");
+     191             : 
+     192             :   // For custom types we allow use of custom Karplus parameters
+     193           6 :   if (jtype_ == CUSTOM) {
+     194           0 :     parse("A", ka_);
+     195           0 :     parse("B", kb_);
+     196           0 :     parse("C", kc_);
+     197           0 :     parse("SHIFT", kshift_);
+     198             :   }
+     199             : 
+     200           6 :   log << "  Bibliography ";
+     201          12 :   log<<plumed.cite("Bonomi, Camilloni, Bioinformatics, 33, 3999 (2017)");
+     202             : 
+     203             :   // Set Karplus parameters
+     204           6 :   switch (jtype_) {
+     205           1 :   case HAN:
+     206           1 :     ka_ = -0.88;
+     207           1 :     kb_ = -0.61;
+     208           1 :     kc_ = -0.27;
+     209           1 :     kshift_ = pi / 3.0;
+     210           2 :     log << plumed.cite("Wang A C, Bax A, J. Am. Chem. Soc. 117, 1810 (1995)");
+     211           1 :     log<<"\n";
+     212           1 :     log.printf("  J-coupling type is HAN, with A: %f, B: %f, C: %f, angle shift: %f\n", ka_, kb_, kc_, kshift_);
+     213             :     break;
+     214           3 :   case HAHN:
+     215           3 :     ka_ = 7.09;
+     216           3 :     kb_ = -1.42;
+     217           3 :     kc_ = 1.55;
+     218           3 :     kshift_ = -pi / 3.0;
+     219           6 :     log << plumed.cite("Hu J-S, Bax A, J. Am. Chem. Soc. 119, 6360 (1997)");
+     220           3 :     log<<"\n";
+     221           3 :     log.printf("  J-coupling type is HAHN, with A: %f, B: %f, C: %f, angle shift: %f\n", ka_, kb_, kc_, kshift_);
+     222             :     break;
+     223           1 :   case CCG:
+     224           1 :     ka_ = 2.31;
+     225           1 :     kb_ = -0.87;
+     226           1 :     kc_ = 0.55;
+     227           1 :     kshift_ = (2.0 * pi) / 3.0;
+     228           2 :     log << plumed.cite("Perez C, Löhr F, Rüterjans H, Schmidt J, J. Am. Chem. Soc. 123, 7081 (2001)");
+     229           1 :     log<<"\n";
+     230           1 :     log.printf("  J-coupling type is CCG, with A: %f, B: %f, C: %f, angle shift: %f\n", ka_, kb_, kc_, kshift_);
+     231             :     break;
+     232           1 :   case NCG:
+     233           1 :     ka_ = 1.29;
+     234           1 :     kb_ = -0.49;
+     235           1 :     kc_ = 0.37;
+     236           1 :     kshift_ = 0.0;
+     237           2 :     log << plumed.cite("Perez C, Löhr F, Rüterjans H, Schmidt J, J. Am. Chem. Soc. 123, 7081 (2001)");
+     238           1 :     log<<"\n";
+     239           1 :     log.printf("  J-coupling type is NCG, with A: %f, B: %f, C: %f, angle shift: %f\n", ka_, kb_, kc_, kshift_);
+     240             :     break;
+     241           0 :   case CUSTOM:
+     242           0 :     log<<"\n";
+     243           0 :     log.printf("  J-coupling type is custom, with A: %f, B: %f, C: %f, angle shift: %f\n", ka_, kb_, kc_, kshift_);
+     244             :     break;
+     245             :   }
+     246             : 
+     247          34 :   for (unsigned i = 0; i < ncoupl_; ++i) {
+     248          28 :     log.printf("  The %uth J-Coupling is calculated from atoms : %d %d %d %d.",
+     249          28 :                i+1, atoms[6*i].serial(), atoms[6*i+1].serial(), atoms[6*i+3].serial(), atoms[6*i+5].serial());
+     250          28 :     if (addcoupling) {
+     251           7 :       log.printf(" Experimental J-Coupling is %f.", coupl[i]);
+     252             :     }
+     253          28 :     log.printf("\n");
+     254             :   }
+     255             : 
+     256           6 :   if (pbc) {
+     257           0 :     log.printf("  using periodic boundary conditions\n");
+     258             :   } else {
+     259           6 :     log.printf("  without periodic boundary conditions\n");
+     260             :   }
+     261             : 
+     262           6 :   if(!getDoScore()) {
+     263          26 :     for (unsigned i = 0; i < ncoupl_; i++) {
+     264          21 :       std::string num; Tools::convert(i, num);
+     265          42 :       addComponentWithDerivatives("j-" + num);
+     266          42 :       componentIsNotPeriodic("j-" + num);
+     267             :     }
+     268             :   } else {
+     269           8 :     for (unsigned i = 0; i < ncoupl_; i++) {
+     270           7 :       std::string num; Tools::convert(i, num);
+     271          14 :       addComponent("j-" + num);
+     272          14 :       componentIsNotPeriodic("j-" + num);
+     273             :     }
+     274             :   }
+     275             : 
+     276           6 :   if (addcoupling||getDoScore()) {
+     277           8 :     for (unsigned i = 0; i < ncoupl_; i++) {
+     278           7 :       std::string num; Tools::convert(i, num);
+     279          14 :       addComponent("exp-" + num);
+     280           7 :       componentIsNotPeriodic("exp-" + num);
+     281           7 :       Value* comp = getPntrToComponent("exp-" + num);
+     282           7 :       comp->set(coupl[i]);
+     283             :     }
+     284             :   }
+     285             : 
+     286           6 :   requestAtoms(atoms, false);
+     287           6 :   if(getDoScore()) {
+     288           1 :     setParameters(coupl);
+     289           1 :     Initialise(ncoupl_);
+     290             :   }
+     291           6 :   setDerivatives();
+     292           6 :   checkRead();
+     293           6 : }
+     294             : 
+     295          16 : void JCoupling::calculate()
+     296             : {
+     297          16 :   if (pbc) makeWhole();
+     298          16 :   std::vector<Vector> deriv(ncoupl_*6);
+     299          16 :   std::vector<double> j(ncoupl_,0.);
+     300             : 
+     301          16 :   #pragma omp parallel num_threads(OpenMP::getNumThreads())
+     302             :   {
+     303             :     #pragma omp for
+     304             :     // Loop through atoms, with steps of 6 atoms (one iteration per datapoint)
+     305             :     for (unsigned r=0; r<ncoupl_; r++) {
+     306             :       // Index is the datapoint index
+     307             :       unsigned a0 = 6*r;
+     308             : 
+     309             :       // 6 atoms -> 3 vectors
+     310             :       Vector d0 = delta(getPosition(a0+1), getPosition(a0));
+     311             :       Vector d1 = delta(getPosition(a0+3), getPosition(a0+2));
+     312             :       Vector d2 = delta(getPosition(a0+5), getPosition(a0+4));
+     313             : 
+     314             :       // Calculate dihedral with 3 vectors, get the derivatives
+     315             :       Vector dd0, dd1, dd2;
+     316             :       PLMD::Torsion t;
+     317             :       double torsion = t.compute(d0, d1, d2, dd0, dd1, dd2);
+     318             : 
+     319             :       // Calculate the Karplus relation and its derivative
+     320             :       double theta = torsion + kshift_;
+     321             :       double cos_theta = std::cos(theta);
+     322             :       double sin_theta = std::sin(theta);
+     323             :       j[r] = ka_*cos_theta*cos_theta + kb_*cos_theta + kc_;
+     324             :       double derj = -2.*ka_*sin_theta*cos_theta - kb_*sin_theta;
+     325             : 
+     326             :       dd0 *= derj;
+     327             :       dd1 *= derj;
+     328             :       dd2 *= derj;
+     329             : 
+     330             :       if(getDoScore()) setCalcData(r, j[r]);
+     331             :       deriv[a0] =  dd0;
+     332             :       deriv[a0+1] = -dd0;
+     333             :       deriv[a0+2] =  dd1;
+     334             :       deriv[a0+3] = -dd1;
+     335             :       deriv[a0+4] =  dd2;
+     336             :       deriv[a0+5] = -dd2;
+     337             :     }
+     338             :   }
+     339             : 
+     340          16 :   if(getDoScore()) {
+     341             :     /* Metainference */
+     342           6 :     double score = getScore();
+     343           6 :     setScore(score);
+     344             : 
+     345             :     /* calculate final derivatives */
+     346           6 :     Tensor virial;
+     347           6 :     Value* val=getPntrToComponent("score");
+     348          48 :     for (unsigned r=0; r<ncoupl_; r++) {
+     349          42 :       const unsigned a0 = 6*r;
+     350          42 :       setAtomsDerivatives(val, a0, deriv[a0]*getMetaDer(r));
+     351          42 :       setAtomsDerivatives(val, a0+1, deriv[a0+1]*getMetaDer(r));
+     352          42 :       setAtomsDerivatives(val, a0+2, deriv[a0+2]*getMetaDer(r));
+     353          42 :       setAtomsDerivatives(val, a0+3, deriv[a0+3]*getMetaDer(r));
+     354          42 :       setAtomsDerivatives(val, a0+4, deriv[a0+4]*getMetaDer(r));
+     355          42 :       setAtomsDerivatives(val, a0+5, deriv[a0+5]*getMetaDer(r));
+     356          42 :       virial-=Tensor(getPosition(a0), deriv[a0]*getMetaDer(r));
+     357          42 :       virial-=Tensor(getPosition(a0+1), deriv[a0+1]*getMetaDer(r));
+     358          42 :       virial-=Tensor(getPosition(a0+2), deriv[a0+2]*getMetaDer(r));
+     359          42 :       virial-=Tensor(getPosition(a0+3), deriv[a0+3]*getMetaDer(r));
+     360          42 :       virial-=Tensor(getPosition(a0+4), deriv[a0+4]*getMetaDer(r));
+     361          42 :       virial-=Tensor(getPosition(a0+5), deriv[a0+5]*getMetaDer(r));
+     362             :     }
+     363           6 :     setBoxDerivatives(val, virial);
+     364             :   } else {
+     365          66 :     for (unsigned r=0; r<ncoupl_; r++) {
+     366          56 :       const unsigned a0 = 6*r;
+     367          56 :       std::string num; Tools::convert(r,num);
+     368          56 :       Value* val=getPntrToComponent("j-"+num);
+     369          56 :       val->set(j[r]);
+     370          56 :       setAtomsDerivatives(val, a0, deriv[a0]);
+     371          56 :       setAtomsDerivatives(val, a0+1, deriv[a0+1]);
+     372          56 :       setAtomsDerivatives(val, a0+2, deriv[a0+2]);
+     373          56 :       setAtomsDerivatives(val, a0+3, deriv[a0+3]);
+     374          56 :       setAtomsDerivatives(val, a0+4, deriv[a0+4]);
+     375          56 :       setAtomsDerivatives(val, a0+5, deriv[a0+5]);
+     376          56 :       Tensor virial;
+     377          56 :       virial-=Tensor(getPosition(a0), deriv[a0]);
+     378          56 :       virial-=Tensor(getPosition(a0+1), deriv[a0+1]);
+     379          56 :       virial-=Tensor(getPosition(a0+2), deriv[a0+2]);
+     380          56 :       virial-=Tensor(getPosition(a0+3), deriv[a0+3]);
+     381          56 :       virial-=Tensor(getPosition(a0+4), deriv[a0+4]);
+     382          56 :       virial-=Tensor(getPosition(a0+5), deriv[a0+5]);
+     383          56 :       setBoxDerivatives(val, virial);
+     384             :     }
+     385             :   }
+     386          16 : }
+     387             : 
+     388          16 : void JCoupling::update() {
+     389             :   // write status file
+     390          16 :   if(getWstride()>0&& (getStep()%getWstride()==0 || getCPT()) ) writeStatus();
+     391          16 : }
+     392             : 
+     393             : }
+     394             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/Metainference.cpp.func-sort-c.html b/coverage/isdb/Metainference.cpp.func-sort-c.html new file mode 100644 index 000000000000..a998ff7bb00d --- /dev/null +++ b/coverage/isdb/Metainference.cpp.func-sort-c.html @@ -0,0 +1,181 @@ + + + + + + + + LCOV - plumed test coverage - isdb/Metainference.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - Metainference.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:73987784.3 %
Date:2024-04-19 12:12:35Functions:242788.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb13Metainference18do_regression_zeroERKSt6vectorIdSaIdEE0
_ZN4PLMD4isdb13MetainferenceC2ERKNS_13ActionOptionsE0
_ZN4PLMD4isdb13MetainferenceD2Ev0
_ZN4PLMD4isdb13Metainference16getEnergyForceGJERKSt6vectorIdSaIdEES6_S6_12
_ZN4PLMD4isdb13Metainference19getEnergyForceMIGENERKSt6vectorIdSaIdEES6_S6_12
_ZN4PLMD4isdb13Metainference9moveTildeERKSt6vectorIdSaIdEERd12
_ZN4PLMD4isdb13Metainference11writeStatusEv19
_ZN4PLMD4isdb13MetainferenceC1ERKNS_13ActionOptionsE19
_ZN4PLMD4isdb13MetainferenceD0Ev19
_ZN4PLMD4isdb13MetainferenceD1Ev19
_ZN4PLMD4isdb13Metainference16registerKeywordsERNS_8KeywordsE21
_ZN4PLMD4isdb13Metainference11getEnergyGJERKSt6vectorIdSaIdEES6_dd36
_ZN4PLMD4isdb13Metainference14getEnergyMIGENERKSt6vectorIdSaIdEES6_S6_dd48
_ZN4PLMD4isdb13Metainference17getEnergyForceSPEERKSt6vectorIdSaIdEES6_S6_48
_ZN4PLMD4isdb13Metainference17getEnergyForceGJEERKSt6vectorIdSaIdEES6_S6_52
_ZN4PLMD4isdb13Metainference16getEnergyForceSPERKSt6vectorIdSaIdEES6_S6_54
_ZN4PLMD4isdb13Metainference12getEnergySPEERKSt6vectorIdSaIdEES6_dd144
_ZN4PLMD4isdb13Metainference12getEnergyGJEERKSt6vectorIdSaIdEES6_dd152
_ZN4PLMD4isdb13Metainference11getEnergySPERKSt6vectorIdSaIdEES6_dd156
_ZN4PLMD4isdb13Metainference15moveScaleOffsetERKSt6vectorIdSaIdEERd168
_ZN4PLMD4isdb13Metainference10moveSigmasERKSt6vectorIdSaIdEERdjRKS2_IjSaIjEERb178
_ZN4PLMD4isdb13Metainference11get_weightsEjRdS2_S2_178
_ZN4PLMD4isdb13Metainference12doMonteCarloERKSt6vectorIdSaIdEE178
_ZN4PLMD4isdb13Metainference14get_sigma_meanEjdddRKSt6vectorIdSaIdEE178
_ZN4PLMD4isdb13Metainference17replica_averagingEddRSt6vectorIdSaIdEES5_178
_ZN4PLMD4isdb13Metainference6updateEv178
_ZN4PLMD4isdb13Metainference9calculateEv178
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/Metainference.cpp.func.html b/coverage/isdb/Metainference.cpp.func.html new file mode 100644 index 000000000000..e2cd9cdcdbdb --- /dev/null +++ b/coverage/isdb/Metainference.cpp.func.html @@ -0,0 +1,181 @@ + + + + + + + + LCOV - plumed test coverage - isdb/Metainference.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - Metainference.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:73987784.3 %
Date:2024-04-19 12:12:35Functions:242788.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb13Metainference10moveSigmasERKSt6vectorIdSaIdEERdjRKS2_IjSaIjEERb178
_ZN4PLMD4isdb13Metainference11getEnergyGJERKSt6vectorIdSaIdEES6_dd36
_ZN4PLMD4isdb13Metainference11getEnergySPERKSt6vectorIdSaIdEES6_dd156
_ZN4PLMD4isdb13Metainference11get_weightsEjRdS2_S2_178
_ZN4PLMD4isdb13Metainference11writeStatusEv19
_ZN4PLMD4isdb13Metainference12doMonteCarloERKSt6vectorIdSaIdEE178
_ZN4PLMD4isdb13Metainference12getEnergyGJEERKSt6vectorIdSaIdEES6_dd152
_ZN4PLMD4isdb13Metainference12getEnergySPEERKSt6vectorIdSaIdEES6_dd144
_ZN4PLMD4isdb13Metainference14getEnergyMIGENERKSt6vectorIdSaIdEES6_S6_dd48
_ZN4PLMD4isdb13Metainference14get_sigma_meanEjdddRKSt6vectorIdSaIdEE178
_ZN4PLMD4isdb13Metainference15moveScaleOffsetERKSt6vectorIdSaIdEERd168
_ZN4PLMD4isdb13Metainference16getEnergyForceGJERKSt6vectorIdSaIdEES6_S6_12
_ZN4PLMD4isdb13Metainference16getEnergyForceSPERKSt6vectorIdSaIdEES6_S6_54
_ZN4PLMD4isdb13Metainference16registerKeywordsERNS_8KeywordsE21
_ZN4PLMD4isdb13Metainference17getEnergyForceGJEERKSt6vectorIdSaIdEES6_S6_52
_ZN4PLMD4isdb13Metainference17getEnergyForceSPEERKSt6vectorIdSaIdEES6_S6_48
_ZN4PLMD4isdb13Metainference17replica_averagingEddRSt6vectorIdSaIdEES5_178
_ZN4PLMD4isdb13Metainference18do_regression_zeroERKSt6vectorIdSaIdEE0
_ZN4PLMD4isdb13Metainference19getEnergyForceMIGENERKSt6vectorIdSaIdEES6_S6_12
_ZN4PLMD4isdb13Metainference6updateEv178
_ZN4PLMD4isdb13Metainference9calculateEv178
_ZN4PLMD4isdb13Metainference9moveTildeERKSt6vectorIdSaIdEERd12
_ZN4PLMD4isdb13MetainferenceC1ERKNS_13ActionOptionsE19
_ZN4PLMD4isdb13MetainferenceC2ERKNS_13ActionOptionsE0
_ZN4PLMD4isdb13MetainferenceD0Ev19
_ZN4PLMD4isdb13MetainferenceD1Ev19
_ZN4PLMD4isdb13MetainferenceD2Ev0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/Metainference.cpp.gcov.html b/coverage/isdb/Metainference.cpp.gcov.html new file mode 100644 index 000000000000..c8e70b0f219a --- /dev/null +++ b/coverage/isdb/Metainference.cpp.gcov.html @@ -0,0 +1,1879 @@ + + + + + + + + LCOV - plumed test coverage - isdb/Metainference.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - Metainference.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:73987784.3 %
Date:2024-04-19 12:12:35Functions:242788.9 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "bias/Bias.h"
+      24             : #include "core/ActionRegister.h"
+      25             : #include "core/PlumedMain.h"
+      26             : #include "core/Value.h"
+      27             : #include "tools/File.h"
+      28             : #include "tools/OpenMP.h"
+      29             : #include "tools/Random.h"
+      30             : #include "tools/Communicator.h"
+      31             : #include <chrono>
+      32             : #include <numeric>
+      33             : 
+      34             : #ifndef M_PI
+      35             : #define M_PI           3.14159265358979323846
+      36             : #endif
+      37             : 
+      38             : namespace PLMD {
+      39             : namespace isdb {
+      40             : 
+      41             : //+PLUMEDOC ISDB_BIAS METAINFERENCE
+      42             : /*
+      43             : Calculates the Metainference energy for a set of experimental data.
+      44             : 
+      45             : Metainference \cite Bonomi:2016ip is a Bayesian framework
+      46             : to model heterogeneous systems by integrating prior information with noisy, ensemble-averaged data.
+      47             : Metainference models a system and quantifies the level of noise in the data by considering a set of replicas of the system.
+      48             : 
+      49             : Calculated experimental data are given in input as ARG while reference experimental values
+      50             : can be given either from fixed components of other actions using PARARG or as numbers using
+      51             : PARAMETERS. The default behavior is that of averaging the data over the available replicas,
+      52             : if this is not wanted the keyword NOENSEMBLE prevent this averaging.
+      53             : 
+      54             : Metadynamics Metainference \cite Bonomi:2016ge or more in general biased Metainference requires the knowledge of
+      55             : biasing potential in order to calculate the weighted average. In this case the value of the bias
+      56             : can be provided as the last argument in ARG and adding the keyword REWEIGHT. To avoid the noise
+      57             : resulting from the instantaneous value of the bias the weight of each replica can be averaged
+      58             : over a give time using the keyword AVERAGING.
+      59             : 
+      60             : The data can be averaged by using multiple replicas and weighted for a bias if present.
+      61             : The functional form of Metainference can be chosen among four variants selected
+      62             : with NOISE=GAUSS,MGAUSS,OUTLIERS,MOUTLIERS,GENERIC which correspond to modelling the noise for
+      63             : the arguments as a single gaussian common to all the data points, a gaussian per data
+      64             : point, a single long-tailed gaussian common to all the data points, a log-tailed
+      65             :  gaussian per data point or using two distinct noises as for the most general formulation of Metainference.
+      66             : In this latter case the noise of the replica-averaging is gaussian (one per data point) and the noise for
+      67             : the comparison with the experimental data can chosen using the keyword LIKELIHOOD
+      68             : between gaussian or log-normal (one per data point), furthermore the evolution of the estimated average
+      69             : over an infinite number of replicas is driven by DFTILDE.
+      70             : 
+      71             : As for Metainference theory there are two sigma values: SIGMA_MEAN0 represent the
+      72             : error of calculating an average quantity using a finite set of replica and should
+      73             : be set as small as possible following the guidelines for replica-averaged simulations
+      74             : in the framework of the Maximum Entropy Principle. Alternatively, this can be obtained
+      75             : automatically using the internal sigma mean optimization as introduced in \cite Lohr:2017gc
+      76             : (OPTSIGMAMEAN=SEM), in this second case sigma_mean is estimated from the maximum standard error
+      77             : of the mean either over the simulation or over a defined time using the keyword AVERAGING.
+      78             : SIGMA_BIAS is an uncertainty parameter, sampled by a MC algorithm in the bounded interval
+      79             : defined by SIGMA_MIN and SIGMA_MAX. The initial value is set at SIGMA0. The MC move is a
+      80             : random displacement of maximum value equal to DSIGMA. If the number of data point is
+      81             : too large and the acceptance rate drops it is possible to make the MC move over mutually
+      82             : exclusive, random subset of size MC_CHUNKSIZE and run more than one move setting MC_STEPS
+      83             : in such a way that MC_CHUNKSIZE*MC_STEPS will cover all the data points.
+      84             : 
+      85             : Calculated and experimental data can be compared modulo a scaling factor and/or an offset
+      86             : using SCALEDATA and/or ADDOFFSET, the sampling is obtained by a MC algorithm either using
+      87             : a flat or a gaussian prior setting it with SCALE_PRIOR or OFFSET_PRIOR.
+      88             : 
+      89             : \par Examples
+      90             : 
+      91             : In the following example we calculate a set of \ref RDC, take the replica-average of
+      92             : them and comparing them with a set of experimental values. RDCs are compared with
+      93             : the experimental data but for a multiplication factor SCALE that is also sampled by
+      94             : MC on-the-fly
+      95             : 
+      96             : \plumedfile
+      97             : RDC ...
+      98             : LABEL=rdc
+      99             : SCALE=0.0001
+     100             : GYROM=-72.5388
+     101             : ATOMS1=22,23
+     102             : ATOMS2=25,27
+     103             : ATOMS3=29,31
+     104             : ATOMS4=33,34
+     105             : ... RDC
+     106             : 
+     107             : METAINFERENCE ...
+     108             : ARG=rdc.*
+     109             : NOISETYPE=MGAUSS
+     110             : PARAMETERS=1.9190,2.9190,3.9190,4.9190
+     111             : SCALEDATA SCALE0=1 SCALE_MIN=0.1 SCALE_MAX=3 DSCALE=0.01
+     112             : SIGMA0=0.01 SIGMA_MIN=0.00001 SIGMA_MAX=3 DSIGMA=0.01
+     113             : SIGMA_MEAN0=0.001
+     114             : LABEL=spe
+     115             : ... METAINFERENCE
+     116             : 
+     117             : PRINT ARG=spe.bias FILE=BIAS STRIDE=1
+     118             : \endplumedfile
+     119             : 
+     120             : in the following example instead of using one uncertainty parameter per data point we use
+     121             : a single uncertainty value in a long-tailed gaussian to take into account for outliers, furthermore
+     122             : the data are weighted for the bias applied to other variables of the system.
+     123             : 
+     124             : \plumedfile
+     125             : RDC ...
+     126             : LABEL=rdc
+     127             : SCALE=0.0001
+     128             : GYROM=-72.5388
+     129             : ATOMS1=22,23
+     130             : ATOMS2=25,27
+     131             : ATOMS3=29,31
+     132             : ATOMS4=33,34
+     133             : ... RDC
+     134             : 
+     135             : cv1: TORSION ATOMS=1,2,3,4
+     136             : cv2: TORSION ATOMS=2,3,4,5
+     137             : mm: METAD ARG=cv1,cv2 HEIGHT=0.5 SIGMA=0.3,0.3 PACE=200 BIASFACTOR=8 WALKERS_MPI
+     138             : 
+     139             : METAINFERENCE ...
+     140             : #SETTINGS NREPLICAS=2
+     141             : ARG=rdc.*,mm.bias
+     142             : REWEIGHT
+     143             : NOISETYPE=OUTLIERS
+     144             : PARAMETERS=1.9190,2.9190,3.9190,4.9190
+     145             : SCALEDATA SCALE0=1 SCALE_MIN=0.1 SCALE_MAX=3 DSCALE=0.01
+     146             : SIGMA0=0.01 SIGMA_MIN=0.00001 SIGMA_MAX=3 DSIGMA=0.01
+     147             : SIGMA_MEAN0=0.001
+     148             : LABEL=spe
+     149             : ... METAINFERENCE
+     150             : \endplumedfile
+     151             : 
+     152             : (See also \ref RDC, \ref PBMETAD).
+     153             : 
+     154             : */
+     155             : //+ENDPLUMEDOC
+     156             : 
+     157             : class Metainference : public bias::Bias
+     158             : {
+     159             :   // experimental values
+     160             :   std::vector<double> parameters;
+     161             :   // noise type
+     162             :   unsigned noise_type_;
+     163             :   enum { GAUSS, MGAUSS, OUTLIERS, MOUTLIERS, GENERIC };
+     164             :   unsigned gen_likelihood_;
+     165             :   enum { LIKE_GAUSS, LIKE_LOGN };
+     166             :   // scale is data scaling factor
+     167             :   // noise type
+     168             :   unsigned scale_prior_;
+     169             :   enum { SC_GAUSS, SC_FLAT };
+     170             :   bool   doscale_;
+     171             :   double scale_;
+     172             :   double scale_mu_;
+     173             :   double scale_min_;
+     174             :   double scale_max_;
+     175             :   double Dscale_;
+     176             :   // scale is data scaling factor
+     177             :   // noise type
+     178             :   unsigned offset_prior_;
+     179             :   bool   dooffset_;
+     180             :   double offset_;
+     181             :   double offset_mu_;
+     182             :   double offset_min_;
+     183             :   double offset_max_;
+     184             :   double Doffset_;
+     185             :   // scale and offset regression
+     186             :   bool doregres_zero_;
+     187             :   int  nregres_zero_;
+     188             :   // sigma is data uncertainty
+     189             :   std::vector<double> sigma_;
+     190             :   std::vector<double> sigma_min_;
+     191             :   std::vector<double> sigma_max_;
+     192             :   std::vector<double> Dsigma_;
+     193             :   // sigma_mean is uncertainty in the mean estimate
+     194             :   std::vector<double> sigma_mean2_;
+     195             :   // this is the estimator of the mean value per replica for generic metainference
+     196             :   std::vector<double> ftilde_;
+     197             :   double Dftilde_;
+     198             : 
+     199             :   // temperature in kbt
+     200             :   double   kbt_;
+     201             : 
+     202             :   // Monte Carlo stuff
+     203             :   std::vector<Random> random;
+     204             :   unsigned MCsteps_;
+     205             :   long long unsigned MCaccept_;
+     206             :   long long unsigned MCacceptScale_;
+     207             :   long long unsigned MCacceptFT_;
+     208             :   long long unsigned MCtrial_;
+     209             :   unsigned MCchunksize_;
+     210             : 
+     211             :   // output
+     212             :   Value*   valueScale;
+     213             :   Value*   valueOffset;
+     214             :   Value*   valueAccept;
+     215             :   Value*   valueAcceptScale;
+     216             :   Value*   valueAcceptFT;
+     217             :   std::vector<Value*> valueSigma;
+     218             :   std::vector<Value*> valueSigmaMean;
+     219             :   std::vector<Value*> valueFtilde;
+     220             : 
+     221             :   // restart
+     222             :   unsigned write_stride_;
+     223             :   OFile    sfile_;
+     224             : 
+     225             :   // others
+     226             :   bool         firstTime;
+     227             :   std::vector<bool> firstTimeW;
+     228             :   bool     master;
+     229             :   bool     do_reweight_;
+     230             :   unsigned do_optsigmamean_;
+     231             :   unsigned nrep_;
+     232             :   unsigned replica_;
+     233             :   unsigned narg;
+     234             : 
+     235             :   // selector
+     236             :   std::string selector_;
+     237             : 
+     238             :   // optimize sigma mean
+     239             :   std::vector< std::vector < std::vector <double> > > sigma_mean2_last_;
+     240             :   unsigned optsigmamean_stride_;
+     241             :   // optimize sigma max
+     242             :   unsigned N_optimized_step_;
+     243             :   unsigned optimized_step_;
+     244             :   bool sigmamax_opt_done_;
+     245             :   std::vector<double> sigma_max_est_;
+     246             : 
+     247             :   // average weights
+     248             :   unsigned                   average_weights_stride_;
+     249             :   std::vector< std::vector <double> >  average_weights_;
+     250             : 
+     251             :   double getEnergyMIGEN(const std::vector<double> &mean, const std::vector<double> &ftilde, const std::vector<double> &sigma,
+     252             :                         const double scale, const double offset);
+     253             :   double getEnergySP(const std::vector<double> &mean, const std::vector<double> &sigma,
+     254             :                      const double scale, const double offset);
+     255             :   double getEnergySPE(const std::vector<double> &mean, const std::vector<double> &sigma,
+     256             :                       const double scale, const double offset);
+     257             :   double getEnergyGJ(const std::vector<double> &mean, const std::vector<double> &sigma,
+     258             :                      const double scale, const double offset);
+     259             :   double getEnergyGJE(const std::vector<double> &mean, const std::vector<double> &sigma,
+     260             :                       const double scale, const double offset);
+     261             :   void moveTilde(const std::vector<double> &mean_, double &old_energy);
+     262             :   void moveScaleOffset(const std::vector<double> &mean_, double &old_energy);
+     263             :   void moveSigmas(const std::vector<double> &mean_, double &old_energy, const unsigned i, const std::vector<unsigned> &indices, bool &breaknow);
+     264             :   double doMonteCarlo(const std::vector<double> &mean);
+     265             :   void getEnergyForceMIGEN(const std::vector<double> &mean, const std::vector<double> &dmean_x, const std::vector<double> &dmean_b);
+     266             :   void getEnergyForceSP(const std::vector<double> &mean, const std::vector<double> &dmean_x, const std::vector<double> &dmean_b);
+     267             :   void getEnergyForceSPE(const std::vector<double> &mean, const std::vector<double> &dmean_x, const std::vector<double> &dmean_b);
+     268             :   void getEnergyForceGJ(const std::vector<double> &mean, const std::vector<double> &dmean_x, const std::vector<double> &dmean_b);
+     269             :   void getEnergyForceGJE(const std::vector<double> &mean, const std::vector<double> &dmean_x, const std::vector<double> &dmean_b);
+     270             :   void get_weights(const unsigned iselect, double &weight, double &norm, double &neff);
+     271             :   void replica_averaging(const double weight, const double norm, std::vector<double> &mean, std::vector<double> &dmean_b);
+     272             :   void get_sigma_mean(const unsigned iselect, const double weight, const double norm, const double neff, const std::vector<double> &mean);
+     273             :   void writeStatus();
+     274             :   void do_regression_zero(const std::vector<double> &mean);
+     275             : 
+     276             : public:
+     277             :   explicit Metainference(const ActionOptions&);
+     278             :   ~Metainference();
+     279             :   void calculate() override;
+     280             :   void update() override;
+     281             :   static void registerKeywords(Keywords& keys);
+     282             : };
+     283             : 
+     284             : 
+     285             : PLUMED_REGISTER_ACTION(Metainference,"METAINFERENCE")
+     286             : 
+     287          21 : void Metainference::registerKeywords(Keywords& keys) {
+     288          21 :   Bias::registerKeywords(keys);
+     289          21 :   keys.use("ARG");
+     290          42 :   keys.add("optional","PARARG","reference values for the experimental data, these can be provided as arguments without derivatives");
+     291          42 :   keys.add("optional","PARAMETERS","reference values for the experimental data");
+     292          42 :   keys.addFlag("NOENSEMBLE",false,"don't perform any replica-averaging");
+     293          42 :   keys.addFlag("REWEIGHT",false,"simple REWEIGHT using the latest ARG as energy");
+     294          42 :   keys.add("optional","AVERAGING", "Stride for calculation of averaged weights and sigma_mean");
+     295          42 :   keys.add("compulsory","NOISETYPE","MGAUSS","functional form of the noise (GAUSS,MGAUSS,OUTLIERS,MOUTLIERS,GENERIC)");
+     296          42 :   keys.add("compulsory","LIKELIHOOD","GAUSS","the likelihood for the GENERIC metainference model, GAUSS or LOGN");
+     297          42 :   keys.add("compulsory","DFTILDE","0.1","fraction of sigma_mean used to evolve ftilde");
+     298          42 :   keys.addFlag("SCALEDATA",false,"Set to TRUE if you want to sample a scaling factor common to all values and replicas");
+     299          42 :   keys.add("compulsory","SCALE0","1.0","initial value of the scaling factor");
+     300          42 :   keys.add("compulsory","SCALE_PRIOR","FLAT","either FLAT or GAUSSIAN");
+     301          42 :   keys.add("optional","SCALE_MIN","minimum value of the scaling factor");
+     302          42 :   keys.add("optional","SCALE_MAX","maximum value of the scaling factor");
+     303          42 :   keys.add("optional","DSCALE","maximum MC move of the scaling factor");
+     304          42 :   keys.addFlag("ADDOFFSET",false,"Set to TRUE if you want to sample an offset common to all values and replicas");
+     305          42 :   keys.add("compulsory","OFFSET0","0.0","initial value of the offset");
+     306          42 :   keys.add("compulsory","OFFSET_PRIOR","FLAT","either FLAT or GAUSSIAN");
+     307          42 :   keys.add("optional","OFFSET_MIN","minimum value of the offset");
+     308          42 :   keys.add("optional","OFFSET_MAX","maximum value of the offset");
+     309          42 :   keys.add("optional","DOFFSET","maximum MC move of the offset");
+     310          42 :   keys.add("optional","REGRES_ZERO","stride for regression with zero offset");
+     311          42 :   keys.add("compulsory","SIGMA0","1.0","initial value of the uncertainty parameter");
+     312          42 :   keys.add("compulsory","SIGMA_MIN","0.0","minimum value of the uncertainty parameter");
+     313          42 :   keys.add("compulsory","SIGMA_MAX","10.","maximum value of the uncertainty parameter");
+     314          42 :   keys.add("optional","DSIGMA","maximum MC move of the uncertainty parameter");
+     315          42 :   keys.add("compulsory","OPTSIGMAMEAN","NONE","Set to NONE/SEM to manually set sigma mean, or to estimate it on the fly");
+     316          42 :   keys.add("optional","SIGMA_MEAN0","starting value for the uncertainty in the mean estimate");
+     317          42 :   keys.add("optional","SIGMA_MAX_STEPS", "Number of steps used to optimise SIGMA_MAX, before that the SIGMA_MAX value is used");
+     318          42 :   keys.add("optional","TEMP","the system temperature - this is only needed if code doesn't pass the temperature to plumed");
+     319          42 :   keys.add("optional","MC_STEPS","number of MC steps");
+     320          42 :   keys.add("optional","MC_CHUNKSIZE","MC chunksize");
+     321          42 :   keys.add("optional","STATUS_FILE","write a file with all the data useful for restart/continuation of Metainference");
+     322          42 :   keys.add("compulsory","WRITE_STRIDE","10000","write the status to a file every N steps, this can be used for restart/continuation");
+     323          42 :   keys.add("optional","SELECTOR","name of selector");
+     324          42 :   keys.add("optional","NSELECT","range of values for selector [0, N-1]");
+     325          21 :   keys.use("RESTART");
+     326          42 :   keys.addOutputComponent("sigma",        "default",      "uncertainty parameter");
+     327          42 :   keys.addOutputComponent("sigmaMean",    "default",      "uncertainty in the mean estimate");
+     328          42 :   keys.addOutputComponent("neff",         "default",      "effective number of replicas");
+     329          42 :   keys.addOutputComponent("acceptSigma",  "default",      "MC acceptance for sigma values");
+     330          42 :   keys.addOutputComponent("acceptScale",  "SCALEDATA",    "MC acceptance for scale value");
+     331          42 :   keys.addOutputComponent("acceptFT",     "GENERIC",      "MC acceptance for general metainference f tilde value");
+     332          42 :   keys.addOutputComponent("weight",       "REWEIGHT",     "weights of the weighted average");
+     333          42 :   keys.addOutputComponent("biasDer",      "REWEIGHT",     "derivatives with respect to the bias");
+     334          42 :   keys.addOutputComponent("scale",        "SCALEDATA",    "scale parameter");
+     335          42 :   keys.addOutputComponent("offset",       "ADDOFFSET",    "offset parameter");
+     336          42 :   keys.addOutputComponent("ftilde",       "GENERIC",      "ensemble average estimator");
+     337          21 : }
+     338             : 
+     339          19 : Metainference::Metainference(const ActionOptions&ao):
+     340             :   PLUMED_BIAS_INIT(ao),
+     341          19 :   doscale_(false),
+     342          19 :   scale_(1.),
+     343          19 :   scale_mu_(0),
+     344          19 :   scale_min_(1),
+     345          19 :   scale_max_(-1),
+     346          19 :   Dscale_(-1),
+     347          19 :   dooffset_(false),
+     348          19 :   offset_(0.),
+     349          19 :   offset_mu_(0),
+     350          19 :   offset_min_(1),
+     351          19 :   offset_max_(-1),
+     352          19 :   Doffset_(-1),
+     353          19 :   doregres_zero_(false),
+     354          19 :   nregres_zero_(0),
+     355          19 :   Dftilde_(0.1),
+     356          19 :   random(3),
+     357          19 :   MCsteps_(1),
+     358          19 :   MCaccept_(0),
+     359          19 :   MCacceptScale_(0),
+     360          19 :   MCacceptFT_(0),
+     361          19 :   MCtrial_(0),
+     362          19 :   MCchunksize_(0),
+     363          19 :   write_stride_(0),
+     364          19 :   firstTime(true),
+     365          19 :   do_reweight_(false),
+     366          19 :   do_optsigmamean_(0),
+     367          19 :   optsigmamean_stride_(0),
+     368          19 :   N_optimized_step_(0),
+     369          19 :   optimized_step_(0),
+     370          19 :   sigmamax_opt_done_(false),
+     371          19 :   average_weights_stride_(1)
+     372             : {
+     373          19 :   bool noensemble = false;
+     374          19 :   parseFlag("NOENSEMBLE", noensemble);
+     375             : 
+     376             :   // set up replica stuff
+     377          19 :   master = (comm.Get_rank()==0);
+     378          19 :   if(master) {
+     379          11 :     nrep_    = multi_sim_comm.Get_size();
+     380          11 :     replica_ = multi_sim_comm.Get_rank();
+     381          11 :     if(noensemble) nrep_ = 1;
+     382             :   } else {
+     383           8 :     nrep_    = 0;
+     384           8 :     replica_ = 0;
+     385             :   }
+     386          19 :   comm.Sum(&nrep_,1);
+     387          19 :   comm.Sum(&replica_,1);
+     388             : 
+     389          19 :   unsigned nsel = 1;
+     390          19 :   parse("SELECTOR", selector_);
+     391          38 :   parse("NSELECT", nsel);
+     392             :   // do checks
+     393          19 :   if(selector_.length()>0 && nsel<=1) error("With SELECTOR active, NSELECT must be greater than 1");
+     394          19 :   if(selector_.length()==0 && nsel>1) error("With NSELECT greater than 1, you must specify SELECTOR");
+     395             : 
+     396             :   // initialise firstTimeW
+     397          19 :   firstTimeW.resize(nsel, true);
+     398             : 
+     399             :   // reweight implies a different number of arguments (the latest one must always be the bias)
+     400          19 :   parseFlag("REWEIGHT", do_reweight_);
+     401          19 :   if(do_reweight_&&nrep_<2) error("REWEIGHT can only be used in parallel with 2 or more replicas");
+     402          34 :   if(!getRestart()) average_weights_.resize(nsel, std::vector<double> (nrep_, 1./static_cast<double>(nrep_)));
+     403           8 :   else average_weights_.resize(nsel, std::vector<double> (nrep_, 0.));
+     404          19 :   narg = getNumberOfArguments();
+     405          19 :   if(do_reweight_) narg--;
+     406             : 
+     407          19 :   unsigned averaging=0;
+     408          19 :   parse("AVERAGING", averaging);
+     409          19 :   if(averaging>0) {
+     410           0 :     average_weights_stride_ = averaging;
+     411           0 :     optsigmamean_stride_    = averaging;
+     412             :   }
+     413             : 
+     414          38 :   parseVector("PARAMETERS",parameters);
+     415          19 :   if(parameters.size()!=static_cast<unsigned>(narg)&&!parameters.empty())
+     416           0 :     error("Size of PARAMETERS array should be either 0 or the same as of the number of arguments in ARG1");
+     417             : 
+     418             :   std::vector<Value*> arg2;
+     419          38 :   parseArgumentList("PARARG",arg2);
+     420          19 :   if(!arg2.empty()) {
+     421           4 :     if(parameters.size()>0) error("It is not possible to use PARARG and PARAMETERS together");
+     422           4 :     if(arg2.size()!=narg) error("Size of PARARG array should be the same as number for arguments in ARG");
+     423        2360 :     for(unsigned i=0; i<arg2.size(); i++) {
+     424        2356 :       parameters.push_back(arg2[i]->get());
+     425        2356 :       if(arg2[i]->hasDerivatives()==true) error("PARARG can only accept arguments without derivatives");
+     426             :     }
+     427             :   }
+     428             : 
+     429          19 :   if(parameters.size()!=narg)
+     430           0 :     error("PARARG or PARAMETERS arrays should include the same number of elements as the arguments in ARG");
+     431             : 
+     432             :   std::string stringa_noise;
+     433          38 :   parse("NOISETYPE",stringa_noise);
+     434          19 :   if(stringa_noise=="GAUSS")           noise_type_ = GAUSS;
+     435          18 :   else if(stringa_noise=="MGAUSS")     noise_type_ = MGAUSS;
+     436          10 :   else if(stringa_noise=="OUTLIERS")   noise_type_ = OUTLIERS;
+     437           5 :   else if(stringa_noise=="MOUTLIERS")  noise_type_ = MOUTLIERS;
+     438           1 :   else if(stringa_noise=="GENERIC")    noise_type_ = GENERIC;
+     439           0 :   else error("Unknown noise type!");
+     440             : 
+     441          19 :   if(noise_type_== GENERIC) {
+     442             :     std::string stringa_like;
+     443           2 :     parse("LIKELIHOOD",stringa_like);
+     444           1 :     if(stringa_like=="GAUSS") gen_likelihood_ = LIKE_GAUSS;
+     445           0 :     else if(stringa_like=="LOGN") gen_likelihood_ = LIKE_LOGN;
+     446           0 :     else error("Unknown likelihood type!");
+     447             : 
+     448           2 :     parse("DFTILDE",Dftilde_);
+     449             :   }
+     450             : 
+     451          38 :   parse("WRITE_STRIDE",write_stride_);
+     452             :   std::string status_file_name_;
+     453          38 :   parse("STATUS_FILE",status_file_name_);
+     454          38 :   if(status_file_name_=="") status_file_name_ = "MISTATUS"+getLabel();
+     455           0 :   else                      status_file_name_ = status_file_name_+getLabel();
+     456             : 
+     457             :   std::string stringa_optsigma;
+     458          38 :   parse("OPTSIGMAMEAN", stringa_optsigma);
+     459          19 :   if(stringa_optsigma=="NONE")      do_optsigmamean_=0;
+     460           0 :   else if(stringa_optsigma=="SEM")  do_optsigmamean_=1;
+     461           0 :   else if(stringa_optsigma=="SEM_MAX")  do_optsigmamean_=2;
+     462             : 
+     463          19 :   unsigned aver_max_steps=0;
+     464          19 :   parse("SIGMA_MAX_STEPS", aver_max_steps);
+     465          19 :   if(aver_max_steps==0&&do_optsigmamean_==2) aver_max_steps=averaging*2000;
+     466          19 :   if(aver_max_steps>0&&do_optsigmamean_<2) error("SIGMA_MAX_STEPS can only be used together with OPTSIGMAMEAN=SEM_MAX");
+     467          19 :   if(aver_max_steps>0&&do_optsigmamean_==2) N_optimized_step_=aver_max_steps;
+     468          19 :   if(aver_max_steps>0&&aver_max_steps<averaging) error("SIGMA_MAX_STEPS must be greater than AVERAGING");
+     469             : 
+     470             :   // resize std::vector for sigma_mean history
+     471          19 :   sigma_mean2_last_.resize(nsel);
+     472          38 :   for(unsigned i=0; i<nsel; i++) sigma_mean2_last_[i].resize(narg);
+     473             : 
+     474             :   std::vector<double> read_sigma_mean_;
+     475          19 :   parseVector("SIGMA_MEAN0",read_sigma_mean_);
+     476          19 :   if(do_optsigmamean_==0 && read_sigma_mean_.size()==0 && !getRestart())
+     477           0 :     error("If you don't use OPTSIGMAMEAN and you are not RESTARTING then you MUST SET SIGMA_MEAN0");
+     478             : 
+     479          19 :   if(noise_type_==MGAUSS||noise_type_==MOUTLIERS||noise_type_==GENERIC) {
+     480          13 :     if(read_sigma_mean_.size()==narg) {
+     481           0 :       sigma_mean2_.resize(narg);
+     482           0 :       for(unsigned i=0; i<narg; i++) sigma_mean2_[i]=read_sigma_mean_[i]*read_sigma_mean_[i];
+     483          13 :     } else if(read_sigma_mean_.size()==1) {
+     484          13 :       sigma_mean2_.resize(narg,read_sigma_mean_[0]*read_sigma_mean_[0]);
+     485           0 :     } else if(read_sigma_mean_.size()==0) {
+     486           0 :       sigma_mean2_.resize(narg,0.000001);
+     487             :     } else {
+     488           0 :       error("SIGMA_MEAN0 can accept either one single value or as many values as the arguments (with NOISETYPE=MGAUSS|MOUTLIERS)");
+     489             :     }
+     490             :     // set the initial value for the history
+     491        2416 :     for(unsigned i=0; i<nsel; i++) for(unsigned j=0; j<narg; j++) sigma_mean2_last_[i][j].push_back(sigma_mean2_[j]);
+     492             :   } else {
+     493           6 :     if(read_sigma_mean_.size()==1) {
+     494           6 :       sigma_mean2_.resize(1, read_sigma_mean_[0]*read_sigma_mean_[0]);
+     495           0 :     } else if(read_sigma_mean_.size()==0) {
+     496           0 :       sigma_mean2_.resize(1, 0.000001);
+     497             :     } else {
+     498           0 :       error("If you want to use more than one SIGMA_MEAN0 you should use NOISETYPE=MGAUSS|MOUTLIERS");
+     499             :     }
+     500             :     // set the initial value for the history
+     501          37 :     for(unsigned i=0; i<nsel; i++) for(unsigned j=0; j<narg; j++) sigma_mean2_last_[i][j].push_back(sigma_mean2_[0]);
+     502             :   }
+     503             : 
+     504          19 :   parseFlag("SCALEDATA", doscale_);
+     505          19 :   if(doscale_) {
+     506             :     std::string stringa_noise;
+     507          24 :     parse("SCALE_PRIOR",stringa_noise);
+     508          12 :     if(stringa_noise=="GAUSSIAN")  scale_prior_ = SC_GAUSS;
+     509          12 :     else if(stringa_noise=="FLAT") scale_prior_ = SC_FLAT;
+     510           0 :     else error("Unknown SCALE_PRIOR type!");
+     511          12 :     parse("SCALE0",scale_);
+     512          12 :     parse("DSCALE",Dscale_);
+     513          12 :     if(Dscale_<0.) error("DSCALE must be set when using SCALEDATA");
+     514          12 :     if(scale_prior_==SC_GAUSS) {
+     515           0 :       scale_mu_=scale_;
+     516             :     } else {
+     517          12 :       parse("SCALE_MIN",scale_min_);
+     518          12 :       parse("SCALE_MAX",scale_max_);
+     519          12 :       if(scale_max_<scale_min_) error("SCALE_MAX and SCALE_MIN must be set when using SCALE_PRIOR=FLAT");
+     520             :     }
+     521             :   }
+     522             : 
+     523          19 :   parseFlag("ADDOFFSET", dooffset_);
+     524          19 :   if(dooffset_) {
+     525             :     std::string stringa_noise;
+     526           4 :     parse("OFFSET_PRIOR",stringa_noise);
+     527           2 :     if(stringa_noise=="GAUSSIAN")  offset_prior_ = SC_GAUSS;
+     528           2 :     else if(stringa_noise=="FLAT") offset_prior_ = SC_FLAT;
+     529           0 :     else error("Unknown OFFSET_PRIOR type!");
+     530           2 :     parse("OFFSET0",offset_);
+     531           2 :     parse("DOFFSET",Doffset_);
+     532           2 :     if(offset_prior_==SC_GAUSS) {
+     533           0 :       offset_mu_=offset_;
+     534           0 :       if(Doffset_<0.) error("DOFFSET must be set when using OFFSET_PRIOR=GAUSS");
+     535             :     } else {
+     536           2 :       parse("OFFSET_MIN",offset_min_);
+     537           2 :       parse("OFFSET_MAX",offset_max_);
+     538           2 :       if(Doffset_<0) Doffset_ = 0.05*(offset_max_ - offset_min_);
+     539           2 :       if(offset_max_<offset_min_) error("OFFSET_MAX and OFFSET_MIN must be set when using OFFSET_PRIOR=FLAT");
+     540             :     }
+     541             :   }
+     542             : 
+     543             :   // regression with zero intercept
+     544          19 :   parse("REGRES_ZERO", nregres_zero_);
+     545          19 :   if(nregres_zero_>0) {
+     546             :     // set flag
+     547           0 :     doregres_zero_=true;
+     548             :     // check if already sampling scale and offset
+     549           0 :     if(doscale_)  error("REGRES_ZERO and SCALEDATA are mutually exclusive");
+     550           0 :     if(dooffset_) error("REGRES_ZERO and ADDOFFSET are mutually exclusive");
+     551             :   }
+     552             : 
+     553             :   std::vector<double> readsigma;
+     554          19 :   parseVector("SIGMA0",readsigma);
+     555          19 :   if((noise_type_!=MGAUSS&&noise_type_!=MOUTLIERS&&noise_type_!=GENERIC)&&readsigma.size()>1)
+     556           0 :     error("If you want to use more than one SIGMA you should use NOISETYPE=MGAUSS|MOUTLIERS|GENERIC");
+     557          19 :   if(noise_type_==MGAUSS||noise_type_==MOUTLIERS||noise_type_==GENERIC) {
+     558          13 :     sigma_.resize(readsigma.size());
+     559          13 :     sigma_=readsigma;
+     560           6 :   } else sigma_.resize(1, readsigma[0]);
+     561             : 
+     562             :   std::vector<double> readsigma_min;
+     563          19 :   parseVector("SIGMA_MIN",readsigma_min);
+     564          19 :   if((noise_type_!=MGAUSS&&noise_type_!=MOUTLIERS&&noise_type_!=GENERIC)&&readsigma_min.size()>1)
+     565           0 :     error("If you want to use more than one SIGMA you should use NOISETYPE=MGAUSS|MOUTLIERS|GENERIC");
+     566          19 :   if(noise_type_==MGAUSS||noise_type_==MOUTLIERS||noise_type_==GENERIC) {
+     567          13 :     sigma_min_.resize(readsigma_min.size());
+     568          13 :     sigma_min_=readsigma_min;
+     569           6 :   } else sigma_min_.resize(1, readsigma_min[0]);
+     570             : 
+     571             :   std::vector<double> readsigma_max;
+     572          19 :   parseVector("SIGMA_MAX",readsigma_max);
+     573          19 :   if((noise_type_!=MGAUSS&&noise_type_!=MOUTLIERS&&noise_type_!=GENERIC)&&readsigma_max.size()>1)
+     574           0 :     error("If you want to use more than one SIGMA you should use NOISETYPE=MGAUSS|MOUTLIERS|GENERIC");
+     575          19 :   if(noise_type_==MGAUSS||noise_type_==MOUTLIERS||noise_type_==GENERIC) {
+     576          13 :     sigma_max_.resize(readsigma_max.size());
+     577          13 :     sigma_max_=readsigma_max;
+     578           6 :   } else sigma_max_.resize(1, readsigma_max[0]);
+     579             : 
+     580          19 :   if(sigma_max_.size()!=sigma_min_.size()) error("The number of values for SIGMA_MIN and SIGMA_MAX must be the same");
+     581             : 
+     582             :   std::vector<double> read_dsigma;
+     583          19 :   parseVector("DSIGMA",read_dsigma);
+     584          19 :   if((noise_type_!=MGAUSS&&noise_type_!=MOUTLIERS&&noise_type_!=GENERIC)&&readsigma_max.size()>1)
+     585           0 :     error("If you want to use more than one SIGMA you should use NOISETYPE=MGAUSS|MOUTLIERS|GENERIC");
+     586          19 :   if(read_dsigma.size()>0) {
+     587          19 :     Dsigma_.resize(read_dsigma.size());
+     588          19 :     Dsigma_=read_dsigma;
+     589             :   } else {
+     590           0 :     Dsigma_.resize(sigma_max_.size(), -1.);
+     591             :     /* in this case Dsigma is initialised after reading the restart file if present */
+     592             :   }
+     593             : 
+     594             :   // monte carlo stuff
+     595          19 :   parse("MC_STEPS",MCsteps_);
+     596          19 :   parse("MC_CHUNKSIZE", MCchunksize_);
+     597             :   // get temperature
+     598          19 :   kbt_ = getkBT();
+     599          19 :   if(kbt_==0.0) error("Unless the MD engine passes the temperature to plumed, you must specify it using TEMP");
+     600             : 
+     601          19 :   checkRead();
+     602             : 
+     603             :   // set sigma_bias
+     604          19 :   if(noise_type_==MGAUSS||noise_type_==MOUTLIERS||noise_type_==GENERIC) {
+     605          13 :     if(sigma_.size()==1) {
+     606          13 :       double tmp = sigma_[0];
+     607          13 :       sigma_.resize(narg, tmp);
+     608           0 :     } else if(sigma_.size()>1&&sigma_.size()!=narg) {
+     609           0 :       error("SIGMA0 can accept either one single value or as many values as the number of arguments (with NOISETYPE=MGAUSS|MOUTLIERS|GENERIC)");
+     610             :     }
+     611          13 :     if(sigma_min_.size()==1) {
+     612          13 :       double tmp = sigma_min_[0];
+     613          13 :       sigma_min_.resize(narg, tmp);
+     614           0 :     } else if(sigma_min_.size()>1&&sigma_min_.size()!=narg) {
+     615           0 :       error("SIGMA_MIN can accept either one single value or as many values as the number of arguments (with NOISETYPE=MGAUSS|MOUTLIERS|GENERIC)");
+     616             :     }
+     617          13 :     if(sigma_max_.size()==1) {
+     618          13 :       double tmp = sigma_max_[0];
+     619          13 :       sigma_max_.resize(narg, tmp);
+     620           0 :     } else if(sigma_max_.size()>1&&sigma_max_.size()!=narg) {
+     621           0 :       error("SIGMA_MAX can accept either one single value or as many values as the number of arguments (with NOISETYPE=MGAUSS|MOUTLIERS|GENERIC)");
+     622             :     }
+     623          13 :     if(Dsigma_.size()==1) {
+     624          13 :       double tmp = Dsigma_[0];
+     625          13 :       Dsigma_.resize(narg, tmp);
+     626           0 :     } else if(Dsigma_.size()>1&&Dsigma_.size()!=narg) {
+     627           0 :       error("DSIGMA can accept either one single value or as many values as the number of arguments (with NOISETYPE=MGAUSS|MOUTLIERS|GENERIC)");
+     628             :     }
+     629             :   }
+     630             : 
+     631          19 :   sigma_max_est_.resize(sigma_max_.size(), 0.);
+     632             : 
+     633          19 :   IFile restart_sfile;
+     634          19 :   restart_sfile.link(*this);
+     635          19 :   if(getRestart()&&restart_sfile.FileExist(status_file_name_)) {
+     636           4 :     firstTime = false;
+     637           8 :     for(unsigned i=0; i<nsel; i++) firstTimeW[i] = false;
+     638           4 :     restart_sfile.open(status_file_name_);
+     639           4 :     log.printf("  Restarting from %s\n", status_file_name_.c_str());
+     640             :     double dummy;
+     641           8 :     if(restart_sfile.scanField("time",dummy)) {
+     642             :       // check for syncronisation
+     643           4 :       std::vector<double> dummy_time(nrep_,0);
+     644           4 :       if(master&&nrep_>1) {
+     645           2 :         dummy_time[replica_] = dummy;
+     646           2 :         multi_sim_comm.Sum(dummy_time);
+     647             :       }
+     648           4 :       comm.Sum(dummy_time);
+     649           8 :       for(unsigned i=1; i<nrep_; i++) {
+     650           4 :         std::string msg = "METAINFERENCE restart files " + status_file_name_ + "  are not in sync";
+     651           4 :         if(dummy_time[i]!=dummy_time[0]) plumed_merror(msg);
+     652             :       }
+     653             :       // nsel
+     654           8 :       for(unsigned i=0; i<sigma_mean2_last_.size(); i++) {
+     655             :         std::string msg_i;
+     656           4 :         Tools::convert(i,msg_i);
+     657             :         // narg
+     658           4 :         if(noise_type_==MGAUSS||noise_type_==MOUTLIERS||noise_type_==GENERIC) {
+     659          20 :           for(unsigned j=0; j<narg; ++j) {
+     660             :             std::string msg_j;
+     661          16 :             Tools::convert(j,msg_j);
+     662          16 :             std::string msg = msg_i+"_"+msg_j;
+     663             :             double read_sm;
+     664          16 :             restart_sfile.scanField("sigmaMean_"+msg,read_sm);
+     665          16 :             sigma_mean2_last_[i][j][0] = read_sm*read_sm;
+     666             :           }
+     667             :         }
+     668           4 :         if(noise_type_==GAUSS||noise_type_==OUTLIERS) {
+     669             :           double read_sm;
+     670             :           std::string msg_j;
+     671           0 :           Tools::convert(0,msg_j);
+     672           0 :           std::string msg = msg_i+"_"+msg_j;
+     673           0 :           restart_sfile.scanField("sigmaMean_"+msg,read_sm);
+     674           0 :           for(unsigned j=0; j<narg; j++) sigma_mean2_last_[i][j][0] = read_sm*read_sm;
+     675             :         }
+     676             :       }
+     677             : 
+     678          20 :       for(unsigned i=0; i<sigma_.size(); ++i) {
+     679             :         std::string msg;
+     680          16 :         Tools::convert(i,msg);
+     681          32 :         restart_sfile.scanField("sigma_"+msg,sigma_[i]);
+     682             :       }
+     683          20 :       for(unsigned i=0; i<sigma_max_.size(); ++i) {
+     684             :         std::string msg;
+     685          16 :         Tools::convert(i,msg);
+     686          16 :         restart_sfile.scanField("sigma_max_"+msg,sigma_max_[i]);
+     687          16 :         sigmamax_opt_done_=true;
+     688             :       }
+     689           4 :       if(noise_type_==GENERIC) {
+     690           0 :         for(unsigned i=0; i<ftilde_.size(); ++i) {
+     691             :           std::string msg;
+     692           0 :           Tools::convert(i,msg);
+     693           0 :           restart_sfile.scanField("ftilde_"+msg,ftilde_[i]);
+     694             :         }
+     695             :       }
+     696           4 :       restart_sfile.scanField("scale0_",scale_);
+     697           4 :       restart_sfile.scanField("offset0_",offset_);
+     698             : 
+     699           8 :       for(unsigned i=0; i<nsel; i++) {
+     700             :         std::string msg;
+     701           4 :         Tools::convert(i,msg);
+     702             :         double tmp_w;
+     703           4 :         restart_sfile.scanField("weight_"+msg,tmp_w);
+     704           4 :         if(master) {
+     705           2 :           average_weights_[i][replica_] = tmp_w;
+     706           2 :           if(nrep_>1) multi_sim_comm.Sum(&average_weights_[i][0], nrep_);
+     707             :         }
+     708           4 :         comm.Sum(&average_weights_[i][0], nrep_);
+     709             :       }
+     710             : 
+     711             :     }
+     712           4 :     restart_sfile.scanField();
+     713           4 :     restart_sfile.close();
+     714             :   }
+     715             : 
+     716             :   /* If DSIGMA is not yet initialised do it now */
+     717        2415 :   for(unsigned i=0; i<sigma_max_.size(); i++) if(Dsigma_[i]==-1) Dsigma_[i] = 0.05*(sigma_max_[i] - sigma_min_[i]);
+     718             : 
+     719          19 :   switch(noise_type_) {
+     720           1 :   case GENERIC:
+     721           1 :     log.printf("  with general metainference ");
+     722           1 :     if(gen_likelihood_==LIKE_GAUSS) log.printf(" and a gaussian likelihood\n");
+     723           0 :     else if(gen_likelihood_==LIKE_LOGN) log.printf(" and a log-normal likelihood\n");
+     724           1 :     log.printf("  ensemble average parameter sampled with a step %lf of sigma_mean\n", Dftilde_);
+     725             :     break;
+     726           1 :   case GAUSS:
+     727           1 :     log.printf("  with gaussian noise and a single noise parameter for all the data\n");
+     728             :     break;
+     729           8 :   case MGAUSS:
+     730           8 :     log.printf("  with gaussian noise and a noise parameter for each data point\n");
+     731             :     break;
+     732           5 :   case OUTLIERS:
+     733           5 :     log.printf("  with long tailed gaussian noise and a single noise parameter for all the data\n");
+     734             :     break;
+     735           4 :   case MOUTLIERS:
+     736           4 :     log.printf("  with long tailed gaussian noise and a noise parameter for each data point\n");
+     737             :     break;
+     738             :   }
+     739             : 
+     740          19 :   if(doscale_) {
+     741             :     // check that the scale value is the same for all replicas
+     742          12 :     std::vector<double> dummy_scale(nrep_,0);
+     743          12 :     if(master&&nrep_>1) {
+     744           6 :       dummy_scale[replica_] = scale_;
+     745           6 :       multi_sim_comm.Sum(dummy_scale);
+     746             :     }
+     747          12 :     comm.Sum(dummy_scale);
+     748          24 :     for(unsigned i=1; i<nrep_; i++) {
+     749          12 :       std::string msg = "The SCALE value must be the same for all replicas: check your input or restart file";
+     750          12 :       if(dummy_scale[i]!=dummy_scale[0]) plumed_merror(msg);
+     751             :     }
+     752          12 :     log.printf("  sampling a common scaling factor with:\n");
+     753          12 :     log.printf("    initial scale parameter %f\n",scale_);
+     754          12 :     if(scale_prior_==SC_GAUSS) {
+     755           0 :       log.printf("    gaussian prior with mean %f and width %f\n",scale_mu_,Dscale_);
+     756             :     }
+     757          12 :     if(scale_prior_==SC_FLAT) {
+     758          12 :       log.printf("    flat prior between %f - %f\n",scale_min_,scale_max_);
+     759          12 :       log.printf("    maximum MC move of scale parameter %f\n",Dscale_);
+     760             :     }
+     761             :   }
+     762             : 
+     763          19 :   if(dooffset_) {
+     764             :     // check that the offset value is the same for all replicas
+     765           2 :     std::vector<double> dummy_offset(nrep_,0);
+     766           2 :     if(master&&nrep_>1) {
+     767           0 :       dummy_offset[replica_] = offset_;
+     768           0 :       multi_sim_comm.Sum(dummy_offset);
+     769             :     }
+     770           2 :     comm.Sum(dummy_offset);
+     771           2 :     for(unsigned i=1; i<nrep_; i++) {
+     772           0 :       std::string msg = "The OFFSET value must be the same for all replicas: check your input or restart file";
+     773           0 :       if(dummy_offset[i]!=dummy_offset[0]) plumed_merror(msg);
+     774             :     }
+     775           2 :     log.printf("  sampling a common offset with:\n");
+     776           2 :     log.printf("    initial offset parameter %f\n",offset_);
+     777           2 :     if(offset_prior_==SC_GAUSS) {
+     778           0 :       log.printf("    gaussian prior with mean %f and width %f\n",offset_mu_,Doffset_);
+     779             :     }
+     780           2 :     if(offset_prior_==SC_FLAT) {
+     781           2 :       log.printf("    flat prior between %f - %f\n",offset_min_,offset_max_);
+     782           2 :       log.printf("    maximum MC move of offset parameter %f\n",Doffset_);
+     783             :     }
+     784             :   }
+     785             : 
+     786          19 :   if(doregres_zero_)
+     787           0 :     log.printf("  doing regression with zero intercept with stride: %d\n", nregres_zero_);
+     788             : 
+     789          19 :   log.printf("  number of experimental data points %u\n",narg);
+     790          19 :   log.printf("  number of replicas %u\n",nrep_);
+     791          19 :   log.printf("  initial data uncertainties");
+     792        2415 :   for(unsigned i=0; i<sigma_.size(); ++i) log.printf(" %f", sigma_[i]);
+     793          19 :   log.printf("\n");
+     794          19 :   log.printf("  minimum data uncertainties");
+     795        2415 :   for(unsigned i=0; i<sigma_.size(); ++i) log.printf(" %f",sigma_min_[i]);
+     796          19 :   log.printf("\n");
+     797          19 :   log.printf("  maximum data uncertainties");
+     798        2415 :   for(unsigned i=0; i<sigma_.size(); ++i) log.printf(" %f",sigma_max_[i]);
+     799          19 :   log.printf("\n");
+     800          19 :   log.printf("  maximum MC move of data uncertainties");
+     801        2415 :   for(unsigned i=0; i<sigma_.size(); ++i) log.printf(" %f",Dsigma_[i]);
+     802          19 :   log.printf("\n");
+     803          19 :   log.printf("  temperature of the system %f\n",kbt_);
+     804          19 :   log.printf("  MC steps %u\n",MCsteps_);
+     805          19 :   log.printf("  initial standard errors of the mean");
+     806        2415 :   for(unsigned i=0; i<sigma_mean2_.size(); ++i) log.printf(" %f", std::sqrt(sigma_mean2_[i]));
+     807          19 :   log.printf("\n");
+     808             : 
+     809          19 :   if(do_reweight_) {
+     810          32 :     addComponent("biasDer");
+     811          32 :     componentIsNotPeriodic("biasDer");
+     812          32 :     addComponent("weight");
+     813          32 :     componentIsNotPeriodic("weight");
+     814             :   }
+     815             : 
+     816          38 :   addComponent("neff");
+     817          19 :   componentIsNotPeriodic("neff");
+     818             : 
+     819          19 :   if(doscale_ || doregres_zero_) {
+     820          24 :     addComponent("scale");
+     821          12 :     componentIsNotPeriodic("scale");
+     822          12 :     valueScale=getPntrToComponent("scale");
+     823             :   }
+     824             : 
+     825          19 :   if(dooffset_) {
+     826           4 :     addComponent("offset");
+     827           2 :     componentIsNotPeriodic("offset");
+     828           2 :     valueOffset=getPntrToComponent("offset");
+     829             :   }
+     830             : 
+     831          19 :   if(dooffset_||doscale_) {
+     832          28 :     addComponent("acceptScale");
+     833          14 :     componentIsNotPeriodic("acceptScale");
+     834          14 :     valueAcceptScale=getPntrToComponent("acceptScale");
+     835             :   }
+     836             : 
+     837          19 :   if(noise_type_==GENERIC) {
+     838           2 :     addComponent("acceptFT");
+     839           1 :     componentIsNotPeriodic("acceptFT");
+     840           1 :     valueAcceptFT=getPntrToComponent("acceptFT");
+     841             :   }
+     842             : 
+     843          38 :   addComponent("acceptSigma");
+     844          19 :   componentIsNotPeriodic("acceptSigma");
+     845          19 :   valueAccept=getPntrToComponent("acceptSigma");
+     846             : 
+     847          19 :   if(noise_type_==MGAUSS||noise_type_==MOUTLIERS||noise_type_==GENERIC) {
+     848        2403 :     for(unsigned i=0; i<sigma_mean2_.size(); ++i) {
+     849        2390 :       std::string num; Tools::convert(i,num);
+     850        4780 :       addComponent("sigmaMean-"+num); componentIsNotPeriodic("sigmaMean-"+num);
+     851        2390 :       valueSigmaMean.push_back(getPntrToComponent("sigmaMean-"+num));
+     852        4780 :       getPntrToComponent("sigmaMean-"+num)->set(std::sqrt(sigma_mean2_[i]));
+     853        4780 :       addComponent("sigma-"+num); componentIsNotPeriodic("sigma-"+num);
+     854        2390 :       valueSigma.push_back(getPntrToComponent("sigma-"+num));
+     855        2390 :       getPntrToComponent("sigma-"+num)->set(sigma_[i]);
+     856        2390 :       if(noise_type_==GENERIC) {
+     857           4 :         addComponent("ftilde-"+num); componentIsNotPeriodic("ftilde-"+num);
+     858           2 :         valueFtilde.push_back(getPntrToComponent("ftilde-"+num));
+     859             :       }
+     860             :     }
+     861          13 :   } else {
+     862          12 :     addComponent("sigmaMean"); componentIsNotPeriodic("sigmaMean");
+     863           6 :     valueSigmaMean.push_back(getPntrToComponent("sigmaMean"));
+     864          12 :     getPntrToComponent("sigmaMean")->set(std::sqrt(sigma_mean2_[0]));
+     865          12 :     addComponent("sigma"); componentIsNotPeriodic("sigma");
+     866           6 :     valueSigma.push_back(getPntrToComponent("sigma"));
+     867          12 :     getPntrToComponent("sigma")->set(sigma_[0]);
+     868             :   }
+     869             : 
+     870             :   // initialize random seed
+     871             :   unsigned iseed;
+     872          19 :   if(master) {
+     873          11 :     auto ts = std::chrono::time_point_cast<std::chrono::nanoseconds>(std::chrono::steady_clock::now()).time_since_epoch().count();
+     874          11 :     iseed = static_cast<unsigned>(ts)+replica_;
+     875             :   } else {
+     876           8 :     iseed = 0;
+     877             :   }
+     878          19 :   comm.Sum(&iseed, 1);
+     879             :   // this is used for ftilde and sigma both the move and the acceptance
+     880             :   // this is different for each replica
+     881          19 :   random[0].setSeed(-iseed);
+     882          19 :   if(doscale_||dooffset_) {
+     883             :     // in this case we want the same seed everywhere
+     884          14 :     auto ts = std::chrono::time_point_cast<std::chrono::nanoseconds>(std::chrono::steady_clock::now()).time_since_epoch().count();
+     885          14 :     iseed = static_cast<unsigned>(ts);
+     886          14 :     if(master&&nrep_>1) multi_sim_comm.Bcast(iseed,0);
+     887          14 :     comm.Bcast(iseed,0);
+     888             :     // this is used for scale and offset sampling and acceptance
+     889          14 :     random[1].setSeed(-iseed);
+     890             :   }
+     891             :   // this is used for random chunk of sigmas, and it is different for each replica
+     892          19 :   if(master) {
+     893          11 :     auto ts = std::chrono::time_point_cast<std::chrono::nanoseconds>(std::chrono::steady_clock::now()).time_since_epoch().count();
+     894          11 :     iseed = static_cast<unsigned>(ts)+replica_;
+     895             :   } else {
+     896           8 :     iseed = 0;
+     897             :   }
+     898          19 :   comm.Sum(&iseed, 1);
+     899          19 :   random[2].setSeed(-iseed);
+     900             : 
+     901             :   // outfile stuff
+     902          19 :   if(write_stride_>0) {
+     903          19 :     sfile_.link(*this);
+     904          19 :     sfile_.open(status_file_name_);
+     905             :   }
+     906             : 
+     907          38 :   log<<"  Bibliography "<<plumed.cite("Bonomi, Camilloni, Cavalli, Vendruscolo, Sci. Adv. 2, e150117 (2016)");
+     908          35 :   if(do_reweight_) log<<plumed.cite("Bonomi, Camilloni, Vendruscolo, Sci. Rep. 6, 31232 (2016)");
+     909          19 :   if(do_optsigmamean_>0) log<<plumed.cite("Loehr, Jussupow, Camilloni, J. Chem. Phys. 146, 165102 (2017)");
+     910          38 :   log<<plumed.cite("Bonomi, Camilloni, Bioinformatics, 33, 3999 (2017)");
+     911          19 :   log<<"\n";
+     912          38 : }
+     913             : 
+     914          38 : Metainference::~Metainference()
+     915             : {
+     916          19 :   if(sfile_.isOpen()) sfile_.close();
+     917         114 : }
+     918             : 
+     919         156 : double Metainference::getEnergySP(const std::vector<double> &mean, const std::vector<double> &sigma,
+     920             :                                   const double scale, const double offset)
+     921             : {
+     922         156 :   const double scale2 = scale*scale;
+     923         156 :   const double sm2    = sigma_mean2_[0];
+     924         156 :   const double ss2    = sigma[0]*sigma[0] + scale2*sm2;
+     925         156 :   const double sss    = sigma[0]*sigma[0] + sm2;
+     926             : 
+     927             :   double ene = 0.0;
+     928         156 :   #pragma omp parallel num_threads(OpenMP::getNumThreads()) shared(ene)
+     929             :   {
+     930             :     #pragma omp for reduction( + : ene)
+     931             :     for(unsigned i=0; i<narg; ++i) {
+     932             :       const double dev = scale*mean[i]-parameters[i]+offset;
+     933             :       const double a2 = 0.5*dev*dev + ss2;
+     934             :       if(sm2 > 0.0) {
+     935             :         ene += std::log(2.0*a2/(1.0-std::exp(-a2/sm2)));
+     936             :       }
+     937             :       else {
+     938             :         ene += std::log(2.0*a2);
+     939             :       }
+     940             :     }
+     941             :   }
+     942             :   // add one single Jeffrey's prior and one normalisation per data point
+     943         156 :   ene += 0.5*std::log(sss) + static_cast<double>(narg)*0.5*std::log(0.5*M_PI*M_PI/ss2);
+     944         156 :   if(doscale_ || doregres_zero_) ene += 0.5*std::log(sss);
+     945         156 :   if(dooffset_) ene += 0.5*std::log(sss);
+     946         156 :   return kbt_ * ene;
+     947             : }
+     948             : 
+     949         144 : double Metainference::getEnergySPE(const std::vector<double> &mean, const std::vector<double> &sigma,
+     950             :                                    const double scale, const double offset)
+     951             : {
+     952         144 :   const double scale2 = scale*scale;
+     953             :   double ene = 0.0;
+     954         144 :   #pragma omp parallel num_threads(OpenMP::getNumThreads()) shared(ene)
+     955             :   {
+     956             :     #pragma omp for reduction( + : ene)
+     957             :     for(unsigned i=0; i<narg; ++i) {
+     958             :       const double sm2 = sigma_mean2_[i];
+     959             :       const double ss2 = sigma[i]*sigma[i] + scale2*sm2;
+     960             :       const double sss = sigma[i]*sigma[i] + sm2;
+     961             :       const double dev = scale*mean[i]-parameters[i]+offset;
+     962             :       const double a2  = 0.5*dev*dev + ss2;
+     963             :       if(sm2 > 0.0) {
+     964             :         ene += 0.5*std::log(sss) + 0.5*std::log(0.5*M_PI*M_PI/ss2) + std::log(2.0*a2/(1.0-std::exp(-a2/sm2)));
+     965             :       }
+     966             :       else {
+     967             :         ene += 0.5*std::log(sss) + 0.5*std::log(0.5*M_PI*M_PI/ss2) + std::log(2.0*a2);
+     968             :       }
+     969             :       if(doscale_ || doregres_zero_)  ene += 0.5*std::log(sss);
+     970             :       if(dooffset_) ene += 0.5*std::log(sss);
+     971             :     }
+     972             :   }
+     973         144 :   return kbt_ * ene;
+     974             : }
+     975             : 
+     976          48 : double Metainference::getEnergyMIGEN(const std::vector<double> &mean, const std::vector<double> &ftilde, const std::vector<double> &sigma,
+     977             :                                      const double scale, const double offset)
+     978             : {
+     979             :   double ene = 0.0;
+     980          48 :   #pragma omp parallel num_threads(OpenMP::getNumThreads()) shared(ene)
+     981             :   {
+     982             :     #pragma omp for reduction( + : ene)
+     983             :     for(unsigned i=0; i<narg; ++i) {
+     984             :       const double inv_sb2  = 1./(sigma[i]*sigma[i]);
+     985             :       const double inv_sm2  = 1./sigma_mean2_[i];
+     986             :       double devb = 0;
+     987             :       if(gen_likelihood_==LIKE_GAUSS)     devb = scale*ftilde[i]-parameters[i]+offset;
+     988             :       else if(gen_likelihood_==LIKE_LOGN) devb = std::log(scale*ftilde[i]/parameters[i]);
+     989             :       double devm = mean[i] - ftilde[i];
+     990             :       // deviation + normalisation + jeffrey
+     991             :       double normb = 0.;
+     992             :       if(gen_likelihood_==LIKE_GAUSS)     normb = -0.5*std::log(0.5/M_PI*inv_sb2);
+     993             :       else if(gen_likelihood_==LIKE_LOGN) normb = -0.5*std::log(0.5/M_PI*inv_sb2/(parameters[i]*parameters[i]));
+     994             :       const double normm         = -0.5*std::log(0.5/M_PI*inv_sm2);
+     995             :       const double jeffreys      = -0.5*std::log(2.*inv_sb2);
+     996             :       ene += 0.5*devb*devb*inv_sb2 + 0.5*devm*devm*inv_sm2 + normb + normm + jeffreys;
+     997             :       if(doscale_ || doregres_zero_)  ene += jeffreys;
+     998             :       if(dooffset_) ene += jeffreys;
+     999             :     }
+    1000             :   }
+    1001          48 :   return kbt_ * ene;
+    1002             : }
+    1003             : 
+    1004          36 : double Metainference::getEnergyGJ(const std::vector<double> &mean, const std::vector<double> &sigma,
+    1005             :                                   const double scale, const double offset)
+    1006             : {
+    1007          36 :   const double scale2  = scale*scale;
+    1008          36 :   const double inv_s2  = 1./(sigma[0]*sigma[0] + scale2*sigma_mean2_[0]);
+    1009          36 :   const double inv_sss = 1./(sigma[0]*sigma[0] + sigma_mean2_[0]);
+    1010             : 
+    1011             :   double ene = 0.0;
+    1012          36 :   #pragma omp parallel num_threads(OpenMP::getNumThreads()) shared(ene)
+    1013             :   {
+    1014             :     #pragma omp for reduction( + : ene)
+    1015             :     for(unsigned i=0; i<narg; ++i) {
+    1016             :       double dev = scale*mean[i]-parameters[i]+offset;
+    1017             :       ene += 0.5*dev*dev*inv_s2;
+    1018             :     }
+    1019             :   }
+    1020          36 :   const double normalisation = -0.5*std::log(0.5/M_PI*inv_s2);
+    1021          36 :   const double jeffreys = -0.5*std::log(2.*inv_sss);
+    1022             :   // add Jeffrey's prior in case one sigma for all data points + one normalisation per datapoint
+    1023          36 :   ene += jeffreys + static_cast<double>(narg)*normalisation;
+    1024          36 :   if(doscale_ || doregres_zero_)  ene += jeffreys;
+    1025          36 :   if(dooffset_) ene += jeffreys;
+    1026             : 
+    1027          36 :   return kbt_ * ene;
+    1028             : }
+    1029             : 
+    1030         152 : double Metainference::getEnergyGJE(const std::vector<double> &mean, const std::vector<double> &sigma,
+    1031             :                                    const double scale, const double offset)
+    1032             : {
+    1033         152 :   const double scale2 = scale*scale;
+    1034             : 
+    1035             :   double ene = 0.0;
+    1036         152 :   #pragma omp parallel num_threads(OpenMP::getNumThreads()) shared(ene)
+    1037             :   {
+    1038             :     #pragma omp for reduction( + : ene)
+    1039             :     for(unsigned i=0; i<narg; ++i) {
+    1040             :       const double inv_s2  = 1./(sigma[i]*sigma[i] + scale2*sigma_mean2_[i]);
+    1041             :       const double inv_sss = 1./(sigma[i]*sigma[i] + sigma_mean2_[i]);
+    1042             :       double dev = scale*mean[i]-parameters[i]+offset;
+    1043             :       // deviation + normalisation + jeffrey
+    1044             :       const double normalisation = -0.5*std::log(0.5/M_PI*inv_s2);
+    1045             :       const double jeffreys      = -0.5*std::log(2.*inv_sss);
+    1046             :       ene += 0.5*dev*dev*inv_s2 + normalisation + jeffreys;
+    1047             :       if(doscale_ || doregres_zero_)  ene += jeffreys;
+    1048             :       if(dooffset_) ene += jeffreys;
+    1049             :     }
+    1050             :   }
+    1051         152 :   return kbt_ * ene;
+    1052             : }
+    1053             : 
+    1054          12 : void Metainference::moveTilde(const std::vector<double> &mean_, double &old_energy)
+    1055             : {
+    1056          12 :   std::vector<double> new_ftilde(sigma_.size());
+    1057          12 :   new_ftilde = ftilde_;
+    1058             : 
+    1059             :   // change all tildes
+    1060          36 :   for(unsigned j=0; j<sigma_.size(); j++) {
+    1061          24 :     const double r3 = random[0].Gaussian();
+    1062          24 :     const double ds3 = Dftilde_*std::sqrt(sigma_mean2_[j])*r3;
+    1063          24 :     new_ftilde[j] = ftilde_[j] + ds3;
+    1064             :   }
+    1065             :   // calculate new energy
+    1066          12 :   double new_energy = getEnergyMIGEN(mean_,new_ftilde,sigma_,scale_,offset_);
+    1067             : 
+    1068             :   // accept or reject
+    1069          12 :   const double delta = ( new_energy - old_energy ) / kbt_;
+    1070             :   // if delta is negative always accept move
+    1071          12 :   if( delta <= 0.0 ) {
+    1072          12 :     old_energy = new_energy;
+    1073          12 :     ftilde_ = new_ftilde;
+    1074          12 :     MCacceptFT_++;
+    1075             :     // otherwise extract random number
+    1076             :   } else {
+    1077           0 :     const double s = random[0].RandU01();
+    1078           0 :     if( s < std::exp(-delta) ) {
+    1079           0 :       old_energy = new_energy;
+    1080           0 :       ftilde_ = new_ftilde;
+    1081           0 :       MCacceptFT_++;
+    1082             :     }
+    1083             :   }
+    1084          12 : }
+    1085             : 
+    1086         168 : void Metainference::moveScaleOffset(const std::vector<double> &mean_, double &old_energy)
+    1087             : {
+    1088         168 :   double new_scale = scale_;
+    1089             : 
+    1090         168 :   if(doscale_) {
+    1091         144 :     if(scale_prior_==SC_FLAT) {
+    1092         144 :       const double r1 = random[1].Gaussian();
+    1093         144 :       const double ds1 = Dscale_*r1;
+    1094         144 :       new_scale += ds1;
+    1095             :       // check boundaries
+    1096         144 :       if(new_scale > scale_max_) {new_scale = 2.0 * scale_max_ - new_scale;}
+    1097         144 :       if(new_scale < scale_min_) {new_scale = 2.0 * scale_min_ - new_scale;}
+    1098             :     } else {
+    1099           0 :       const double r1 = random[1].Gaussian();
+    1100           0 :       const double ds1 = 0.5*(scale_mu_-new_scale)+Dscale_*std::exp(1)/M_PI*r1;
+    1101           0 :       new_scale += ds1;
+    1102             :     }
+    1103             :   }
+    1104             : 
+    1105         168 :   double new_offset = offset_;
+    1106             : 
+    1107         168 :   if(dooffset_) {
+    1108          24 :     if(offset_prior_==SC_FLAT) {
+    1109          24 :       const double r1 = random[1].Gaussian();
+    1110          24 :       const double ds1 = Doffset_*r1;
+    1111          24 :       new_offset += ds1;
+    1112             :       // check boundaries
+    1113          24 :       if(new_offset > offset_max_) {new_offset = 2.0 * offset_max_ - new_offset;}
+    1114          24 :       if(new_offset < offset_min_) {new_offset = 2.0 * offset_min_ - new_offset;}
+    1115             :     } else {
+    1116           0 :       const double r1 = random[1].Gaussian();
+    1117           0 :       const double ds1 = 0.5*(offset_mu_-new_offset)+Doffset_*std::exp(1)/M_PI*r1;
+    1118           0 :       new_offset += ds1;
+    1119             :     }
+    1120             :   }
+    1121             : 
+    1122             :   // calculate new energy
+    1123             :   double new_energy = 0.;
+    1124             : 
+    1125         168 :   switch(noise_type_) {
+    1126          12 :   case GAUSS:
+    1127          12 :     new_energy = getEnergyGJ(mean_,sigma_,new_scale,new_offset);
+    1128             :     break;
+    1129          48 :   case MGAUSS:
+    1130          48 :     new_energy = getEnergyGJE(mean_,sigma_,new_scale,new_offset);
+    1131             :     break;
+    1132          48 :   case OUTLIERS:
+    1133          48 :     new_energy = getEnergySP(mean_,sigma_,new_scale,new_offset);
+    1134             :     break;
+    1135          48 :   case MOUTLIERS:
+    1136          48 :     new_energy = getEnergySPE(mean_,sigma_,new_scale,new_offset);
+    1137             :     break;
+    1138          12 :   case GENERIC:
+    1139          12 :     new_energy = getEnergyMIGEN(mean_,ftilde_,sigma_,new_scale,new_offset);
+    1140             :     break;
+    1141             :   }
+    1142             : 
+    1143             :   // for the scale/offset we need to consider the total energy
+    1144         168 :   std::vector<double> totenergies(2);
+    1145         168 :   if(master) {
+    1146          96 :     totenergies[0] = old_energy;
+    1147          96 :     totenergies[1] = new_energy;
+    1148          96 :     if(nrep_>1) multi_sim_comm.Sum(totenergies);
+    1149             :   } else {
+    1150          72 :     totenergies[0] = 0;
+    1151          72 :     totenergies[1] = 0;
+    1152             :   }
+    1153         168 :   comm.Sum(totenergies);
+    1154             : 
+    1155             :   // accept or reject
+    1156         168 :   const double delta = ( totenergies[1] - totenergies[0] ) / kbt_;
+    1157             :   // if delta is negative always accept move
+    1158         168 :   if( delta <= 0.0 ) {
+    1159         168 :     old_energy = new_energy;
+    1160         168 :     scale_ = new_scale;
+    1161         168 :     offset_ = new_offset;
+    1162         168 :     MCacceptScale_++;
+    1163             :     // otherwise extract random number
+    1164             :   } else {
+    1165           0 :     double s = random[1].RandU01();
+    1166           0 :     if( s < std::exp(-delta) ) {
+    1167           0 :       old_energy = new_energy;
+    1168           0 :       scale_ = new_scale;
+    1169           0 :       offset_ = new_offset;
+    1170           0 :       MCacceptScale_++;
+    1171             :     }
+    1172             :   }
+    1173         168 : }
+    1174             : 
+    1175         178 : void Metainference::moveSigmas(const std::vector<double> &mean_, double &old_energy, const unsigned i, const std::vector<unsigned> &indices, bool &breaknow)
+    1176             : {
+    1177         178 :   std::vector<double> new_sigma(sigma_.size());
+    1178         178 :   new_sigma = sigma_;
+    1179             : 
+    1180             :   // change MCchunksize_ sigmas
+    1181         178 :   if (MCchunksize_ > 0) {
+    1182           0 :     if ((MCchunksize_ * i) >= sigma_.size()) {
+    1183             :       // This means we are not moving any sigma, so we should break immediately
+    1184           0 :       breaknow = true;
+    1185             :     }
+    1186             : 
+    1187             :     // change random sigmas
+    1188           0 :     for(unsigned j=0; j<MCchunksize_; j++) {
+    1189           0 :       const unsigned shuffle_index = j + MCchunksize_ * i;
+    1190           0 :       if (shuffle_index >= sigma_.size()) {
+    1191             :         // Going any further will segfault but we should still evaluate the sigmas we changed
+    1192             :         break;
+    1193             :       }
+    1194           0 :       const unsigned index = indices[shuffle_index];
+    1195           0 :       const double r2 = random[0].Gaussian();
+    1196           0 :       const double ds2 = Dsigma_[index]*r2;
+    1197           0 :       new_sigma[index] = sigma_[index] + ds2;
+    1198             :       // check boundaries
+    1199           0 :       if(new_sigma[index] > sigma_max_[index]) {new_sigma[index] = 2.0 * sigma_max_[index] - new_sigma[index];}
+    1200           0 :       if(new_sigma[index] < sigma_min_[index]) {new_sigma[index] = 2.0 * sigma_min_[index] - new_sigma[index];}
+    1201             :     }
+    1202             :   } else {
+    1203             :     // change all sigmas
+    1204        3008 :     for(unsigned j=0; j<sigma_.size(); j++) {
+    1205        2830 :       const double r2 = random[0].Gaussian();
+    1206        2830 :       const double ds2 = Dsigma_[j]*r2;
+    1207        2830 :       new_sigma[j] = sigma_[j] + ds2;
+    1208             :       // check boundaries
+    1209        2830 :       if(new_sigma[j] > sigma_max_[j]) {new_sigma[j] = 2.0 * sigma_max_[j] - new_sigma[j];}
+    1210        2830 :       if(new_sigma[j] < sigma_min_[j]) {new_sigma[j] = 2.0 * sigma_min_[j] - new_sigma[j];}
+    1211             :     }
+    1212             :   }
+    1213             : 
+    1214         178 :   if (breaknow) {
+    1215             :     // We didnt move any sigmas, so no sense in evaluating anything
+    1216             :     return;
+    1217             :   }
+    1218             : 
+    1219             :   // calculate new energy
+    1220             :   double new_energy = 0.;
+    1221         178 :   switch(noise_type_) {
+    1222          12 :   case GAUSS:
+    1223          12 :     new_energy = getEnergyGJ(mean_,new_sigma,scale_,offset_);
+    1224             :     break;
+    1225          52 :   case MGAUSS:
+    1226          52 :     new_energy = getEnergyGJE(mean_,new_sigma,scale_,offset_);
+    1227             :     break;
+    1228          54 :   case OUTLIERS:
+    1229          54 :     new_energy = getEnergySP(mean_,new_sigma,scale_,offset_);
+    1230             :     break;
+    1231          48 :   case MOUTLIERS:
+    1232          48 :     new_energy = getEnergySPE(mean_,new_sigma,scale_,offset_);
+    1233             :     break;
+    1234          12 :   case GENERIC:
+    1235          12 :     new_energy = getEnergyMIGEN(mean_,ftilde_,new_sigma,scale_,offset_);
+    1236             :     break;
+    1237             :   }
+    1238             : 
+    1239             :   // accept or reject
+    1240         178 :   const double delta = ( new_energy - old_energy ) / kbt_;
+    1241             :   // if delta is negative always accept move
+    1242         178 :   if( delta <= 0.0 ) {
+    1243         178 :     old_energy = new_energy;
+    1244         178 :     sigma_ = new_sigma;
+    1245         178 :     MCaccept_++;
+    1246             :     // otherwise extract random number
+    1247             :   } else {
+    1248           0 :     const double s = random[0].RandU01();
+    1249           0 :     if( s < std::exp(-delta) ) {
+    1250           0 :       old_energy = new_energy;
+    1251           0 :       sigma_ = new_sigma;
+    1252           0 :       MCaccept_++;
+    1253             :     }
+    1254             :   }
+    1255             : }
+    1256             : 
+    1257         178 : double Metainference::doMonteCarlo(const std::vector<double> &mean_)
+    1258             : {
+    1259             :   // calculate old energy with the updated coordinates
+    1260         178 :   double old_energy=0.;
+    1261             : 
+    1262         178 :   switch(noise_type_) {
+    1263          12 :   case GAUSS:
+    1264          12 :     old_energy = getEnergyGJ(mean_,sigma_,scale_,offset_);
+    1265          12 :     break;
+    1266          52 :   case MGAUSS:
+    1267          52 :     old_energy = getEnergyGJE(mean_,sigma_,scale_,offset_);
+    1268          52 :     break;
+    1269          54 :   case OUTLIERS:
+    1270          54 :     old_energy = getEnergySP(mean_,sigma_,scale_,offset_);
+    1271          54 :     break;
+    1272          48 :   case MOUTLIERS:
+    1273          48 :     old_energy = getEnergySPE(mean_,sigma_,scale_,offset_);
+    1274          48 :     break;
+    1275          12 :   case GENERIC:
+    1276          12 :     old_energy = getEnergyMIGEN(mean_,ftilde_,sigma_,scale_,offset_);
+    1277          12 :     break;
+    1278             :   }
+    1279             : 
+    1280             :   // do not run MC if this is a replica-exchange trial
+    1281         178 :   if(!getExchangeStep()) {
+    1282             : 
+    1283             :     // Create std::vector of random sigma indices
+    1284             :     std::vector<unsigned> indices;
+    1285         178 :     if (MCchunksize_ > 0) {
+    1286           0 :       for (unsigned j=0; j<sigma_.size(); j++) {
+    1287           0 :         indices.push_back(j);
+    1288             :       }
+    1289           0 :       random[2].Shuffle(indices);
+    1290             :     }
+    1291         178 :     bool breaknow = false;
+    1292             : 
+    1293             :     // cycle on MC steps
+    1294         356 :     for(unsigned i=0; i<MCsteps_; ++i) {
+    1295         178 :       MCtrial_++;
+    1296             :       // propose move for ftilde
+    1297         178 :       if(noise_type_==GENERIC) moveTilde(mean_, old_energy);
+    1298             :       // propose move for scale and/or offset
+    1299         178 :       if(doscale_||dooffset_) moveScaleOffset(mean_, old_energy);
+    1300             :       // propose move for sigma
+    1301         178 :       moveSigmas(mean_, old_energy, i, indices, breaknow);
+    1302             :       // exit from the loop if this is the case
+    1303         178 :       if(breaknow) break;
+    1304             :     }
+    1305             : 
+    1306             :     /* save the result of the sampling */
+    1307             :     /* ftilde */
+    1308         178 :     if(noise_type_==GENERIC) {
+    1309          12 :       double accept = static_cast<double>(MCacceptFT_) / static_cast<double>(MCtrial_);
+    1310          12 :       valueAcceptFT->set(accept);
+    1311          36 :       for(unsigned i=0; i<sigma_.size(); i++) valueFtilde[i]->set(ftilde_[i]);
+    1312             :     }
+    1313             :     /* scale and offset */
+    1314         178 :     if(doscale_ || doregres_zero_) valueScale->set(scale_);
+    1315         178 :     if(dooffset_) valueOffset->set(offset_);
+    1316         178 :     if(doscale_||dooffset_) {
+    1317         168 :       double accept = static_cast<double>(MCacceptScale_) / static_cast<double>(MCtrial_);
+    1318         168 :       valueAcceptScale->set(accept);
+    1319             :     }
+    1320             :     /* sigmas */
+    1321        3008 :     for(unsigned i=0; i<sigma_.size(); i++) valueSigma[i]->set(sigma_[i]);
+    1322         178 :     double accept = static_cast<double>(MCaccept_) / static_cast<double>(MCtrial_);
+    1323         178 :     valueAccept->set(accept);
+    1324             :   }
+    1325             : 
+    1326             :   // here we sum the score over the replicas to get the full metainference score that we save as a bias
+    1327         178 :   if(master) {
+    1328         104 :     if(nrep_>1) multi_sim_comm.Sum(old_energy);
+    1329             :   } else {
+    1330          74 :     old_energy=0;
+    1331             :   }
+    1332         178 :   comm.Sum(old_energy);
+    1333             : 
+    1334             :   // this is the energy with current coordinates and parameters
+    1335         178 :   return old_energy;
+    1336             : }
+    1337             : 
+    1338             : /*
+    1339             :    In the following energy-force functions we don't add the normalisation and the jeffreys priors
+    1340             :    because they are not needed for the forces, the correct MetaInference energy is the one calculated
+    1341             :    in the Monte-Carlo
+    1342             : */
+    1343             : 
+    1344          54 : void Metainference::getEnergyForceSP(const std::vector<double> &mean, const std::vector<double> &dmean_x,
+    1345             :                                      const std::vector<double> &dmean_b)
+    1346             : {
+    1347          54 :   const double scale2 = scale_*scale_;
+    1348          54 :   const double sm2    = sigma_mean2_[0];
+    1349          54 :   const double ss2    = sigma_[0]*sigma_[0] + scale2*sm2;
+    1350          54 :   std::vector<double> f(narg,0);
+    1351             : 
+    1352          54 :   if(master) {
+    1353          30 :     #pragma omp parallel num_threads(OpenMP::getNumThreads())
+    1354             :     {
+    1355             :       #pragma omp for
+    1356             :       for(unsigned i=0; i<narg; ++i) {
+    1357             :         const double dev = scale_*mean[i]-parameters[i]+offset_;
+    1358             :         const double a2 = 0.5*dev*dev + ss2;
+    1359             :         if(sm2 > 0.0) {
+    1360             :           const double t = std::exp(-a2/sm2);
+    1361             :           const double dt = 1./t;
+    1362             :           const double dit = 1./(1.-dt);
+    1363             :           f[i] = -scale_*dev*(dit/sm2 + 1./a2);
+    1364             :         }
+    1365             :         else {
+    1366             :           f[i] = -scale_*dev*(1./a2);
+    1367             :         }
+    1368             :       }
+    1369             :     }
+    1370             :     // collect contribution to forces and energy from other replicas
+    1371          30 :     if(nrep_>1) multi_sim_comm.Sum(&f[0],narg);
+    1372             :   }
+    1373             :   // intra-replica summation
+    1374          54 :   comm.Sum(&f[0],narg);
+    1375             : 
+    1376             :   double w_tmp = 0.;
+    1377         288 :   for(unsigned i=0; i<narg; ++i) {
+    1378         234 :     setOutputForce(i, kbt_*f[i]*dmean_x[i]);
+    1379         234 :     w_tmp += kbt_*f[i]*dmean_b[i];
+    1380             :   }
+    1381             : 
+    1382          54 :   if(do_reweight_) {
+    1383          48 :     setOutputForce(narg, w_tmp);
+    1384          96 :     getPntrToComponent("biasDer")->set(-w_tmp);
+    1385             :   }
+    1386          54 : }
+    1387             : 
+    1388          48 : void Metainference::getEnergyForceSPE(const std::vector<double> &mean, const std::vector<double> &dmean_x,
+    1389             :                                       const std::vector<double> &dmean_b)
+    1390             : {
+    1391          48 :   const double scale2 = scale_*scale_;
+    1392          48 :   std::vector<double> f(narg,0);
+    1393             : 
+    1394          48 :   if(master) {
+    1395          24 :     #pragma omp parallel num_threads(OpenMP::getNumThreads())
+    1396             :     {
+    1397             :       #pragma omp for
+    1398             :       for(unsigned i=0; i<narg; ++i) {
+    1399             :         const double sm2 = sigma_mean2_[i];
+    1400             :         const double ss2 = sigma_[i]*sigma_[i] + scale2*sm2;
+    1401             :         const double dev = scale_*mean[i]-parameters[i]+offset_;
+    1402             :         const double a2  = 0.5*dev*dev + ss2;
+    1403             :         if(sm2 > 0.0) {
+    1404             :           const double t   = std::exp(-a2/sm2);
+    1405             :           const double dt  = 1./t;
+    1406             :           const double dit = 1./(1.-dt);
+    1407             :           f[i] = -scale_*dev*(dit/sm2 + 1./a2);
+    1408             :         }
+    1409             :         else {
+    1410             :           f[i] = -scale_*dev*(1./a2);
+    1411             :         }
+    1412             :       }
+    1413             :     }
+    1414             :     // collect contribution to forces and energy from other replicas
+    1415          24 :     if(nrep_>1) multi_sim_comm.Sum(&f[0],narg);
+    1416             :   }
+    1417          48 :   comm.Sum(&f[0],narg);
+    1418             : 
+    1419             :   double w_tmp = 0.;
+    1420         240 :   for(unsigned i=0; i<narg; ++i) {
+    1421         192 :     setOutputForce(i, kbt_ * dmean_x[i] * f[i]);
+    1422         192 :     w_tmp += kbt_ * dmean_b[i] *f[i];
+    1423             :   }
+    1424             : 
+    1425          48 :   if(do_reweight_) {
+    1426          48 :     setOutputForce(narg, w_tmp);
+    1427          96 :     getPntrToComponent("biasDer")->set(-w_tmp);
+    1428             :   }
+    1429          48 : }
+    1430             : 
+    1431          12 : void Metainference::getEnergyForceGJ(const std::vector<double> &mean, const std::vector<double> &dmean_x,
+    1432             :                                      const std::vector<double> &dmean_b)
+    1433             : {
+    1434          12 :   const double scale2 = scale_*scale_;
+    1435          12 :   double inv_s2=0.;
+    1436             : 
+    1437          12 :   if(master) {
+    1438          12 :     inv_s2 = 1./(sigma_[0]*sigma_[0] + scale2*sigma_mean2_[0]);
+    1439          12 :     if(nrep_>1) multi_sim_comm.Sum(inv_s2);
+    1440             :   }
+    1441          12 :   comm.Sum(inv_s2);
+    1442             : 
+    1443             :   double w_tmp = 0.;
+    1444          12 :   #pragma omp parallel num_threads(OpenMP::getNumThreads()) shared(w_tmp)
+    1445             :   {
+    1446             :     #pragma omp for reduction( + : w_tmp)
+    1447             :     for(unsigned i=0; i<narg; ++i) {
+    1448             :       const double dev = scale_*mean[i]-parameters[i]+offset_;
+    1449             :       const double mult = dev*scale_*inv_s2;
+    1450             :       setOutputForce(i, -kbt_*dmean_x[i]*mult);
+    1451             :       w_tmp += kbt_*dmean_b[i]*mult;
+    1452             :     }
+    1453             :   }
+    1454             : 
+    1455          12 :   if(do_reweight_) {
+    1456           0 :     setOutputForce(narg, -w_tmp);
+    1457           0 :     getPntrToComponent("biasDer")->set(w_tmp);
+    1458             :   }
+    1459          12 : }
+    1460             : 
+    1461          52 : void Metainference::getEnergyForceGJE(const std::vector<double> &mean, const std::vector<double> &dmean_x,
+    1462             :                                       const std::vector<double> &dmean_b)
+    1463             : {
+    1464          52 :   const double scale2 = scale_*scale_;
+    1465          52 :   std::vector<double> inv_s2(sigma_.size(),0.);
+    1466             : 
+    1467          52 :   if(master) {
+    1468        1300 :     for(unsigned i=0; i<sigma_.size(); ++i) inv_s2[i] = 1./(sigma_[i]*sigma_[i] + scale2*sigma_mean2_[i]);
+    1469          26 :     if(nrep_>1) multi_sim_comm.Sum(&inv_s2[0],sigma_.size());
+    1470             :   }
+    1471          52 :   comm.Sum(&inv_s2[0],sigma_.size());
+    1472             : 
+    1473             :   double w_tmp = 0.;
+    1474          52 :   #pragma omp parallel num_threads(OpenMP::getNumThreads()) shared(w_tmp)
+    1475             :   {
+    1476             :     #pragma omp for reduction( + : w_tmp)
+    1477             :     for(unsigned i=0; i<narg; ++i) {
+    1478             :       const double dev  = scale_*mean[i]-parameters[i]+offset_;
+    1479             :       const double mult = dev*scale_*inv_s2[i];
+    1480             :       setOutputForce(i, -kbt_*dmean_x[i]*mult);
+    1481             :       w_tmp += kbt_*dmean_b[i]*mult;
+    1482             :     }
+    1483             :   }
+    1484             : 
+    1485          52 :   if(do_reweight_) {
+    1486          52 :     setOutputForce(narg, -w_tmp);
+    1487         104 :     getPntrToComponent("biasDer")->set(w_tmp);
+    1488             :   }
+    1489          52 : }
+    1490             : 
+    1491          12 : void Metainference::getEnergyForceMIGEN(const std::vector<double> &mean, const std::vector<double> &dmean_x, const std::vector<double> &dmean_b)
+    1492             : {
+    1493          12 :   std::vector<double> inv_s2(sigma_.size(),0.);
+    1494          12 :   std::vector<double> dev(sigma_.size(),0.);
+    1495          12 :   std::vector<double> dev2(sigma_.size(),0.);
+    1496             : 
+    1497          36 :   for(unsigned i=0; i<sigma_.size(); ++i) {
+    1498          24 :     inv_s2[i]   = 1./sigma_mean2_[i];
+    1499          24 :     if(master) {
+    1500          24 :       dev[i]  = (mean[i]-ftilde_[i]);
+    1501          24 :       dev2[i] = dev[i]*dev[i];
+    1502             :     }
+    1503             :   }
+    1504          12 :   if(master&&nrep_>1) {
+    1505           0 :     multi_sim_comm.Sum(&dev[0],dev.size());
+    1506           0 :     multi_sim_comm.Sum(&dev2[0],dev2.size());
+    1507             :   }
+    1508          12 :   comm.Sum(&dev[0],dev.size());
+    1509          12 :   comm.Sum(&dev2[0],dev2.size());
+    1510             : 
+    1511             :   double dene_b = 0.;
+    1512          12 :   #pragma omp parallel num_threads(OpenMP::getNumThreads()) shared(dene_b)
+    1513             :   {
+    1514             :     #pragma omp for reduction( + : dene_b)
+    1515             :     for(unsigned i=0; i<narg; ++i) {
+    1516             :       const double dene_x  = kbt_*inv_s2[i]*dmean_x[i]*dev[i];
+    1517             :       dene_b += kbt_*inv_s2[i]*dmean_b[i]*dev[i];
+    1518             :       setOutputForce(i, -dene_x);
+    1519             :     }
+    1520             :   }
+    1521             : 
+    1522          12 :   if(do_reweight_) {
+    1523           0 :     setOutputForce(narg, -dene_b);
+    1524           0 :     getPntrToComponent("biasDer")->set(dene_b);
+    1525             :   }
+    1526          12 : }
+    1527             : 
+    1528         178 : void Metainference::get_weights(const unsigned iselect, double &weight, double &norm, double &neff)
+    1529             : {
+    1530         178 :   const double dnrep = static_cast<double>(nrep_);
+    1531             :   // calculate the weights either from BIAS
+    1532         178 :   if(do_reweight_) {
+    1533         148 :     std::vector<double> bias(nrep_,0);
+    1534         148 :     if(master) {
+    1535          74 :       bias[replica_] = getArgument(narg);
+    1536          74 :       if(nrep_>1) multi_sim_comm.Sum(&bias[0], nrep_);
+    1537             :     }
+    1538         148 :     comm.Sum(&bias[0], nrep_);
+    1539             : 
+    1540             :     // accumulate weights
+    1541         148 :     const double decay = 1./static_cast<double> (average_weights_stride_);
+    1542         148 :     if(!firstTimeW[iselect]) {
+    1543         408 :       for(unsigned i=0; i<nrep_; ++i) {
+    1544         272 :         const double delta=bias[i]-average_weights_[iselect][i];
+    1545         272 :         average_weights_[iselect][i]+=decay*delta;
+    1546             :       }
+    1547             :     } else {
+    1548             :       firstTimeW[iselect] = false;
+    1549          36 :       for(unsigned i=0; i<nrep_; ++i) average_weights_[iselect][i] = bias[i];
+    1550             :     }
+    1551             : 
+    1552             :     // set average back into bias and set norm to one
+    1553         148 :     const double maxbias = *(std::max_element(average_weights_[iselect].begin(), average_weights_[iselect].end()));
+    1554         444 :     for(unsigned i=0; i<nrep_; ++i) bias[i] = std::exp((average_weights_[iselect][i]-maxbias)/kbt_);
+    1555             :     // set local weight, norm and weight variance
+    1556         148 :     weight = bias[replica_];
+    1557             :     double w2=0.;
+    1558         444 :     for(unsigned i=0; i<nrep_; ++i) {
+    1559         296 :       w2 += bias[i]*bias[i];
+    1560         296 :       norm += bias[i];
+    1561             :     }
+    1562         148 :     neff = norm*norm/w2;
+    1563         296 :     getPntrToComponent("weight")->set(weight/norm);
+    1564             :   } else {
+    1565             :     // or arithmetic ones
+    1566          30 :     neff = dnrep;
+    1567          30 :     weight = 1.0;
+    1568          30 :     norm = dnrep;
+    1569             :   }
+    1570         178 :   getPntrToComponent("neff")->set(neff);
+    1571         178 : }
+    1572             : 
+    1573         178 : void Metainference::get_sigma_mean(const unsigned iselect, const double weight, const double norm, const double neff, const std::vector<double> &mean)
+    1574             : {
+    1575         178 :   const double dnrep    = static_cast<double>(nrep_);
+    1576         178 :   std::vector<double> sigma_mean2_tmp(sigma_mean2_.size(), 0.);
+    1577             : 
+    1578         178 :   if(do_optsigmamean_>0) {
+    1579             :     // remove first entry of the history std::vector
+    1580           0 :     if(sigma_mean2_last_[iselect][0].size()==optsigmamean_stride_&&optsigmamean_stride_>0)
+    1581           0 :       for(unsigned i=0; i<narg; ++i) sigma_mean2_last_[iselect][i].erase(sigma_mean2_last_[iselect][i].begin());
+    1582             :     /* this is the current estimate of sigma mean for each argument
+    1583             :        there is one of this per argument in any case  because it is
+    1584             :        the maximum among these to be used in case of GAUSS/OUTLIER */
+    1585           0 :     std::vector<double> sigma_mean2_now(narg,0);
+    1586           0 :     if(master) {
+    1587           0 :       for(unsigned i=0; i<narg; ++i) sigma_mean2_now[i] = weight*(getArgument(i)-mean[i])*(getArgument(i)-mean[i]);
+    1588           0 :       if(nrep_>1) multi_sim_comm.Sum(&sigma_mean2_now[0], narg);
+    1589             :     }
+    1590           0 :     comm.Sum(&sigma_mean2_now[0], narg);
+    1591           0 :     for(unsigned i=0; i<narg; ++i) sigma_mean2_now[i] *= 1.0/(neff-1.)/norm;
+    1592             : 
+    1593             :     // add sigma_mean2 to history
+    1594           0 :     if(optsigmamean_stride_>0) {
+    1595           0 :       for(unsigned i=0; i<narg; ++i) sigma_mean2_last_[iselect][i].push_back(sigma_mean2_now[i]);
+    1596             :     } else {
+    1597           0 :       for(unsigned i=0; i<narg; ++i) if(sigma_mean2_now[i] > sigma_mean2_last_[iselect][i][0]) sigma_mean2_last_[iselect][i][0] = sigma_mean2_now[i];
+    1598             :     }
+    1599             : 
+    1600           0 :     if(noise_type_==MGAUSS||noise_type_==MOUTLIERS||noise_type_==GENERIC) {
+    1601           0 :       for(unsigned i=0; i<narg; ++i) {
+    1602             :         /* set to the maximum in history std::vector */
+    1603           0 :         sigma_mean2_tmp[i] = *max_element(sigma_mean2_last_[iselect][i].begin(), sigma_mean2_last_[iselect][i].end());
+    1604             :         /* the standard error of the mean */
+    1605           0 :         valueSigmaMean[i]->set(std::sqrt(sigma_mean2_tmp[i]));
+    1606           0 :         if(noise_type_==GENERIC) {
+    1607           0 :           sigma_min_[i] = std::sqrt(sigma_mean2_tmp[i]);
+    1608           0 :           if(sigma_[i] < sigma_min_[i]) sigma_[i] = sigma_min_[i];
+    1609             :         }
+    1610             :       }
+    1611           0 :     } else if(noise_type_==GAUSS||noise_type_==OUTLIERS) {
+    1612             :       // find maximum for each data point
+    1613             :       std::vector <double> max_values;
+    1614           0 :       for(unsigned i=0; i<narg; ++i) max_values.push_back(*max_element(sigma_mean2_last_[iselect][i].begin(), sigma_mean2_last_[iselect][i].end()));
+    1615             :       // find maximum across data points
+    1616           0 :       const double max_now = *max_element(max_values.begin(), max_values.end());
+    1617             :       // set new value
+    1618           0 :       sigma_mean2_tmp[0] = max_now;
+    1619           0 :       valueSigmaMean[0]->set(std::sqrt(sigma_mean2_tmp[0]));
+    1620             :     }
+    1621             :     // endif sigma mean optimization
+    1622             :     // start sigma max optimization
+    1623           0 :     if(do_optsigmamean_>1&&!sigmamax_opt_done_) {
+    1624           0 :       for(unsigned i=0; i<sigma_max_.size(); i++) {
+    1625           0 :         if(sigma_max_est_[i]<sigma_mean2_tmp[i]&&optimized_step_>optsigmamean_stride_) sigma_max_est_[i]=sigma_mean2_tmp[i];
+    1626             :         // ready to set once and for all the value of sigma_max
+    1627           0 :         if(optimized_step_==N_optimized_step_) {
+    1628           0 :           sigmamax_opt_done_=true;
+    1629           0 :           for(unsigned i=0; i<sigma_max_.size(); i++) {
+    1630           0 :             sigma_max_[i]=std::sqrt(sigma_max_est_[i]*dnrep);
+    1631           0 :             Dsigma_[i] = 0.05*(sigma_max_[i] - sigma_min_[i]);
+    1632           0 :             if(sigma_[i]>sigma_max_[i]) sigma_[i]=sigma_max_[i];
+    1633             :           }
+    1634             :         }
+    1635             :       }
+    1636           0 :       optimized_step_++;
+    1637             :     }
+    1638             :     // end sigma max optimization
+    1639             :   } else {
+    1640         178 :     if(noise_type_==MGAUSS||noise_type_==MOUTLIERS||noise_type_==GENERIC) {
+    1641        2876 :       for(unsigned i=0; i<narg; ++i) {
+    1642        2764 :         sigma_mean2_tmp[i] = sigma_mean2_last_[iselect][i][0];
+    1643        2764 :         valueSigmaMean[i]->set(std::sqrt(sigma_mean2_tmp[i]));
+    1644             :       }
+    1645          66 :     } else if(noise_type_==GAUSS||noise_type_==OUTLIERS) {
+    1646          66 :       sigma_mean2_tmp[0] = sigma_mean2_last_[iselect][0][0];
+    1647          66 :       valueSigmaMean[0]->set(std::sqrt(sigma_mean2_tmp[0]));
+    1648             :     }
+    1649             :   }
+    1650             : 
+    1651         178 :   sigma_mean2_ = sigma_mean2_tmp;
+    1652         178 : }
+    1653             : 
+    1654         178 : void Metainference::replica_averaging(const double weight, const double norm, std::vector<double> &mean, std::vector<double> &dmean_b)
+    1655             : {
+    1656         178 :   if(master) {
+    1657        1660 :     for(unsigned i=0; i<narg; ++i) mean[i] = weight/norm*getArgument(i);
+    1658         104 :     if(nrep_>1) multi_sim_comm.Sum(&mean[0], narg);
+    1659             :   }
+    1660         178 :   comm.Sum(&mean[0], narg);
+    1661             :   // set the derivative of the mean with respect to the bias
+    1662        3200 :   for(unsigned i=0; i<narg; ++i) dmean_b[i] = weight/norm/kbt_*(getArgument(i)-mean[i])/static_cast<double>(average_weights_stride_);
+    1663             : 
+    1664             :   // this is only for generic metainference
+    1665         178 :   if(firstTime) {ftilde_ = mean; firstTime = false;}
+    1666         178 : }
+    1667             : 
+    1668           0 : void Metainference::do_regression_zero(const std::vector<double> &mean)
+    1669             : {
+    1670             : // parameters[i] = scale_ * mean[i]: find scale_ with linear regression
+    1671             :   double num = 0.0;
+    1672             :   double den = 0.0;
+    1673           0 :   for(unsigned i=0; i<parameters.size(); ++i) {
+    1674           0 :     num += mean[i] * parameters[i];
+    1675           0 :     den += mean[i] * mean[i];
+    1676             :   }
+    1677           0 :   if(den>0) {
+    1678           0 :     scale_ = num / den;
+    1679             :   } else {
+    1680           0 :     scale_ = 1.0;
+    1681             :   }
+    1682           0 : }
+    1683             : 
+    1684         178 : void Metainference::calculate()
+    1685             : {
+    1686             :   // get step
+    1687         178 :   const long long int step = getStep();
+    1688             : 
+    1689             :   unsigned iselect = 0;
+    1690             :   // set the value of selector for  REM-like stuff
+    1691         178 :   if(selector_.length()>0) iselect = static_cast<unsigned>(plumed.passMap[selector_]);
+    1692             : 
+    1693             :   /* 1) collect weights */
+    1694         178 :   double weight = 0.;
+    1695         178 :   double neff = 0.;
+    1696         178 :   double norm = 0.;
+    1697         178 :   get_weights(iselect, weight, norm, neff);
+    1698             : 
+    1699             :   /* 2) calculate average */
+    1700         178 :   std::vector<double> mean(narg,0);
+    1701             :   // this is the derivative of the mean with respect to the argument
+    1702         178 :   std::vector<double> dmean_x(narg,weight/norm);
+    1703             :   // this is the derivative of the mean with respect to the bias
+    1704         178 :   std::vector<double> dmean_b(narg,0);
+    1705             :   // calculate it
+    1706         178 :   replica_averaging(weight, norm, mean, dmean_b);
+    1707             : 
+    1708             :   /* 3) calculates parameters */
+    1709         178 :   get_sigma_mean(iselect, weight, norm, neff, mean);
+    1710             : 
+    1711             :   // in case of regression with zero intercept, calculate scale
+    1712         178 :   if(doregres_zero_ && step%nregres_zero_==0) do_regression_zero(mean);
+    1713             : 
+    1714             :   /* 4) run monte carlo */
+    1715         178 :   double ene = doMonteCarlo(mean);
+    1716             : 
+    1717             :   // calculate bias and forces
+    1718         178 :   switch(noise_type_) {
+    1719          12 :   case GAUSS:
+    1720          12 :     getEnergyForceGJ(mean, dmean_x, dmean_b);
+    1721             :     break;
+    1722          52 :   case MGAUSS:
+    1723          52 :     getEnergyForceGJE(mean, dmean_x, dmean_b);
+    1724             :     break;
+    1725          54 :   case OUTLIERS:
+    1726          54 :     getEnergyForceSP(mean, dmean_x, dmean_b);
+    1727             :     break;
+    1728          48 :   case MOUTLIERS:
+    1729          48 :     getEnergyForceSPE(mean, dmean_x, dmean_b);
+    1730             :     break;
+    1731          12 :   case GENERIC:
+    1732          12 :     getEnergyForceMIGEN(mean, dmean_x, dmean_b);
+    1733             :     break;
+    1734             :   }
+    1735             : 
+    1736         178 :   setBias(ene);
+    1737         178 : }
+    1738             : 
+    1739          19 : void Metainference::writeStatus()
+    1740             : {
+    1741          19 :   sfile_.rewind();
+    1742          19 :   sfile_.printField("time",getTimeStep()*getStep());
+    1743             :   //nsel
+    1744          38 :   for(unsigned i=0; i<sigma_mean2_last_.size(); i++) {
+    1745             :     std::string msg_i,msg_j;
+    1746          19 :     Tools::convert(i,msg_i);
+    1747             :     std::vector <double> max_values;
+    1748             :     //narg
+    1749        2434 :     for(unsigned j=0; j<narg; ++j) {
+    1750        2415 :       Tools::convert(j,msg_j);
+    1751        2415 :       std::string msg = msg_i+"_"+msg_j;
+    1752        2415 :       if(noise_type_==MGAUSS||noise_type_==MOUTLIERS||noise_type_==GENERIC) {
+    1753        7170 :         sfile_.printField("sigmaMean_"+msg,std::sqrt(*max_element(sigma_mean2_last_[i][j].begin(), sigma_mean2_last_[i][j].end())));
+    1754             :       } else {
+    1755             :         // find maximum for each data point
+    1756          50 :         max_values.push_back(*max_element(sigma_mean2_last_[i][j].begin(), sigma_mean2_last_[i][j].end()));
+    1757             :       }
+    1758             :     }
+    1759          19 :     if(noise_type_==GAUSS||noise_type_==OUTLIERS) {
+    1760             :       // find maximum across data points
+    1761           6 :       const double max_now = std::sqrt(*max_element(max_values.begin(), max_values.end()));
+    1762           6 :       Tools::convert(0,msg_j);
+    1763           6 :       std::string msg = msg_i+"_"+msg_j;
+    1764          12 :       sfile_.printField("sigmaMean_"+msg, max_now);
+    1765             :     }
+    1766             :   }
+    1767        2415 :   for(unsigned i=0; i<sigma_.size(); ++i) {
+    1768             :     std::string msg;
+    1769        2396 :     Tools::convert(i,msg);
+    1770        4792 :     sfile_.printField("sigma_"+msg,sigma_[i]);
+    1771             :   }
+    1772        2415 :   for(unsigned i=0; i<sigma_max_.size(); ++i) {
+    1773             :     std::string msg;
+    1774        2396 :     Tools::convert(i,msg);
+    1775        4792 :     sfile_.printField("sigma_max_"+msg,sigma_max_[i]);
+    1776             :   }
+    1777          19 :   if(noise_type_==GENERIC) {
+    1778           3 :     for(unsigned i=0; i<ftilde_.size(); ++i) {
+    1779             :       std::string msg;
+    1780           2 :       Tools::convert(i,msg);
+    1781           4 :       sfile_.printField("ftilde_"+msg,ftilde_[i]);
+    1782             :     }
+    1783             :   }
+    1784          19 :   sfile_.printField("scale0_",scale_);
+    1785          19 :   sfile_.printField("offset0_",offset_);
+    1786          38 :   for(unsigned i=0; i<average_weights_.size(); i++) {
+    1787             :     std::string msg_i;
+    1788          19 :     Tools::convert(i,msg_i);
+    1789          38 :     sfile_.printField("weight_"+msg_i,average_weights_[i][replica_]);
+    1790             :   }
+    1791          19 :   sfile_.printField();
+    1792          19 :   sfile_.flush();
+    1793          19 : }
+    1794             : 
+    1795         178 : void Metainference::update() {
+    1796             :   // write status file
+    1797         178 :   if(write_stride_>0&& (getStep()%write_stride_==0 || getCPT()) ) writeStatus();
+    1798         178 : }
+    1799             : 
+    1800             : }
+    1801             : }
+    1802             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/MetainferenceBase.cpp.func-sort-c.html b/coverage/isdb/MetainferenceBase.cpp.func-sort-c.html new file mode 100644 index 000000000000..5316285c17fc --- /dev/null +++ b/coverage/isdb/MetainferenceBase.cpp.func-sort-c.html @@ -0,0 +1,185 @@ + + + + + + + + LCOV - plumed test coverage - isdb/MetainferenceBase.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - MetainferenceBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:75488585.2 %
Date:2024-04-19 12:12:35Functions:232882.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb17MetainferenceBase18do_regression_zeroERKSt6vectorIdSaIdEE0
_ZN4PLMD4isdb17MetainferenceBase8SelectorEv0
_ZN4PLMD4isdb17MetainferenceBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD4isdb17MetainferenceBaseD0Ev0
_ZN4PLMD4isdb17MetainferenceBaseD1Ev0
_ZN4PLMD4isdb17MetainferenceBase16getEnergyForceSPERKSt6vectorIdSaIdEES6_S6_6
_ZN4PLMD4isdb17MetainferenceBase11getEnergySPERKSt6vectorIdSaIdEES6_dd12
_ZN4PLMD4isdb17MetainferenceBase19getEnergyForceMIGENERKSt6vectorIdSaIdEES6_S6_12
_ZN4PLMD4isdb17MetainferenceBase9moveTildeERKSt6vectorIdSaIdEERd12
_ZN4PLMD4isdb17MetainferenceBase10InitialiseEj31
_ZN4PLMD4isdb17MetainferenceBase14getEnergyMIGENERKSt6vectorIdSaIdEES6_S6_dd48
_ZN4PLMD4isdb17MetainferenceBase11writeStatusEv100
_ZN4PLMD4isdb17MetainferenceBaseC2ERKNS_13ActionOptionsE100
_ZN4PLMD4isdb17MetainferenceBaseD2Ev100
_ZN4PLMD4isdb17MetainferenceBase16registerKeywordsERNS_8KeywordsE116
_ZN4PLMD4isdb17MetainferenceBase17getEnergyForceGJEERKSt6vectorIdSaIdEES6_S6_160
_ZN4PLMD4isdb17MetainferenceBase16getEnergyForceGJERKSt6vectorIdSaIdEES6_S6_271
_ZN4PLMD4isdb17MetainferenceBase12getEnergyGJEERKSt6vectorIdSaIdEES6_dd368
_ZN4PLMD4isdb17MetainferenceBase11getEnergyGJERKSt6vectorIdSaIdEES6_dd554
_ZN4PLMD4isdb17MetainferenceBase17getEnergyForceSPEERKSt6vectorIdSaIdEES6_S6_1776
_ZN4PLMD4isdb17MetainferenceBase15moveScaleOffsetERKSt6vectorIdSaIdEERd1848
_ZN4PLMD4isdb17MetainferenceBase10moveSigmasERKSt6vectorIdSaIdEERdjRKS2_IjSaIjEERb2225
_ZN4PLMD4isdb17MetainferenceBase11get_weightsERdS2_S2_2225
_ZN4PLMD4isdb17MetainferenceBase12doMonteCarloERKSt6vectorIdSaIdEE2225
_ZN4PLMD4isdb17MetainferenceBase14get_sigma_meanEdddRKSt6vectorIdSaIdEE2225
_ZN4PLMD4isdb17MetainferenceBase17replica_averagingEddRSt6vectorIdSaIdEES5_2225
_ZN4PLMD4isdb17MetainferenceBase8getScoreEv2225
_ZN4PLMD4isdb17MetainferenceBase12getEnergySPEERKSt6vectorIdSaIdEES6_dd5328
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/MetainferenceBase.cpp.func.html b/coverage/isdb/MetainferenceBase.cpp.func.html new file mode 100644 index 000000000000..536a0c777f11 --- /dev/null +++ b/coverage/isdb/MetainferenceBase.cpp.func.html @@ -0,0 +1,185 @@ + + + + + + + + LCOV - plumed test coverage - isdb/MetainferenceBase.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - MetainferenceBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:75488585.2 %
Date:2024-04-19 12:12:35Functions:232882.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb17MetainferenceBase10InitialiseEj31
_ZN4PLMD4isdb17MetainferenceBase10moveSigmasERKSt6vectorIdSaIdEERdjRKS2_IjSaIjEERb2225
_ZN4PLMD4isdb17MetainferenceBase11getEnergyGJERKSt6vectorIdSaIdEES6_dd554
_ZN4PLMD4isdb17MetainferenceBase11getEnergySPERKSt6vectorIdSaIdEES6_dd12
_ZN4PLMD4isdb17MetainferenceBase11get_weightsERdS2_S2_2225
_ZN4PLMD4isdb17MetainferenceBase11writeStatusEv100
_ZN4PLMD4isdb17MetainferenceBase12doMonteCarloERKSt6vectorIdSaIdEE2225
_ZN4PLMD4isdb17MetainferenceBase12getEnergyGJEERKSt6vectorIdSaIdEES6_dd368
_ZN4PLMD4isdb17MetainferenceBase12getEnergySPEERKSt6vectorIdSaIdEES6_dd5328
_ZN4PLMD4isdb17MetainferenceBase14getEnergyMIGENERKSt6vectorIdSaIdEES6_S6_dd48
_ZN4PLMD4isdb17MetainferenceBase14get_sigma_meanEdddRKSt6vectorIdSaIdEE2225
_ZN4PLMD4isdb17MetainferenceBase15moveScaleOffsetERKSt6vectorIdSaIdEERd1848
_ZN4PLMD4isdb17MetainferenceBase16getEnergyForceGJERKSt6vectorIdSaIdEES6_S6_271
_ZN4PLMD4isdb17MetainferenceBase16getEnergyForceSPERKSt6vectorIdSaIdEES6_S6_6
_ZN4PLMD4isdb17MetainferenceBase16registerKeywordsERNS_8KeywordsE116
_ZN4PLMD4isdb17MetainferenceBase17getEnergyForceGJEERKSt6vectorIdSaIdEES6_S6_160
_ZN4PLMD4isdb17MetainferenceBase17getEnergyForceSPEERKSt6vectorIdSaIdEES6_S6_1776
_ZN4PLMD4isdb17MetainferenceBase17replica_averagingEddRSt6vectorIdSaIdEES5_2225
_ZN4PLMD4isdb17MetainferenceBase18do_regression_zeroERKSt6vectorIdSaIdEE0
_ZN4PLMD4isdb17MetainferenceBase19getEnergyForceMIGENERKSt6vectorIdSaIdEES6_S6_12
_ZN4PLMD4isdb17MetainferenceBase8SelectorEv0
_ZN4PLMD4isdb17MetainferenceBase8getScoreEv2225
_ZN4PLMD4isdb17MetainferenceBase9moveTildeERKSt6vectorIdSaIdEERd12
_ZN4PLMD4isdb17MetainferenceBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD4isdb17MetainferenceBaseC2ERKNS_13ActionOptionsE100
_ZN4PLMD4isdb17MetainferenceBaseD0Ev0
_ZN4PLMD4isdb17MetainferenceBaseD1Ev0
_ZN4PLMD4isdb17MetainferenceBaseD2Ev100
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/MetainferenceBase.cpp.gcov.html b/coverage/isdb/MetainferenceBase.cpp.gcov.html new file mode 100644 index 000000000000..a7fb3e4c3ff2 --- /dev/null +++ b/coverage/isdb/MetainferenceBase.cpp.gcov.html @@ -0,0 +1,1637 @@ + + + + + + + + LCOV - plumed test coverage - isdb/MetainferenceBase.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - MetainferenceBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:75488585.2 %
Date:2024-04-19 12:12:35Functions:232882.1 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb17MetainferenceBase13setParametersERKSt6vectorIdSaIdEE27
_ZN4PLMD4isdb17MetainferenceBase29calculateNumericalDerivativesEPNS_15ActionWithValueE75
_ZN4PLMD4isdb17MetainferenceBase14setDerivativesEv100
_ZN4PLMD4isdb17MetainferenceBase12lockRequestsEv705
_ZN4PLMD4isdb17MetainferenceBase14unlockRequestsEv705
_ZN4PLMD4isdb17MetainferenceBase5applyEv705
_ZN4PLMD4isdb17MetainferenceBase8setScoreEd2225
_ZN4PLMD4isdb17MetainferenceBase17turnOnDerivativesEv2711
_ZN4PLMD4isdb17MetainferenceBase17setBoxDerivativesEPNS_5ValueERKNS_13TensorGenericILj3ELj3EEE11908
_ZN4PLMD4isdb17MetainferenceBase19setAtomsDerivativesEPNS_5ValueEjRKNS_13VectorGenericILj3EEE2391632
_ZN4PLMD4isdb17MetainferenceBase22getNumberOfDerivativesEv2827966
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/MetainferenceBase.h.func.html b/coverage/isdb/MetainferenceBase.h.func.html new file mode 100644 index 000000000000..2e3639d22741 --- /dev/null +++ b/coverage/isdb/MetainferenceBase.h.func.html @@ -0,0 +1,117 @@ + + + + + + + + LCOV - plumed test coverage - isdb/MetainferenceBase.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - MetainferenceBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:717397.3 %
Date:2024-04-19 12:12:35Functions:1111100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb17MetainferenceBase12lockRequestsEv705
_ZN4PLMD4isdb17MetainferenceBase13setParametersERKSt6vectorIdSaIdEE27
_ZN4PLMD4isdb17MetainferenceBase14setDerivativesEv100
_ZN4PLMD4isdb17MetainferenceBase14unlockRequestsEv705
_ZN4PLMD4isdb17MetainferenceBase17setBoxDerivativesEPNS_5ValueERKNS_13TensorGenericILj3ELj3EEE11908
_ZN4PLMD4isdb17MetainferenceBase17turnOnDerivativesEv2711
_ZN4PLMD4isdb17MetainferenceBase19setAtomsDerivativesEPNS_5ValueEjRKNS_13VectorGenericILj3EEE2391632
_ZN4PLMD4isdb17MetainferenceBase22getNumberOfDerivativesEv2827966
_ZN4PLMD4isdb17MetainferenceBase29calculateNumericalDerivativesEPNS_15ActionWithValueE75
_ZN4PLMD4isdb17MetainferenceBase5applyEv705
_ZN4PLMD4isdb17MetainferenceBase8setScoreEd2225
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/MetainferenceBase.h.gcov.html b/coverage/isdb/MetainferenceBase.h.gcov.html new file mode 100644 index 000000000000..94b4b42437b6 --- /dev/null +++ b/coverage/isdb/MetainferenceBase.h.gcov.html @@ -0,0 +1,463 @@ + + + + + + + + LCOV - plumed test coverage - isdb/MetainferenceBase.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - MetainferenceBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:717397.3 %
Date:2024-04-19 12:12:35Functions:1111100.0 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb3NOEC2ERKNS_13ActionOptionsE0
_ZN4PLMD4isdb3NOEC1ERKNS_13ActionOptionsE11
_ZN4PLMD4isdb3NOE16registerKeywordsERNS_8KeywordsE13
_ZN4PLMD4isdb3NOE6updateEv132
_ZN4PLMD4isdb3NOE9calculateEv456
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/NOE.cpp.func.html b/coverage/isdb/NOE.cpp.func.html new file mode 100644 index 000000000000..8d7608e88dc3 --- /dev/null +++ b/coverage/isdb/NOE.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - isdb/NOE.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - NOE.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10210498.1 %
Date:2024-04-19 12:12:35Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb3NOE16registerKeywordsERNS_8KeywordsE13
_ZN4PLMD4isdb3NOE6updateEv132
_ZN4PLMD4isdb3NOE9calculateEv456
_ZN4PLMD4isdb3NOEC1ERKNS_13ActionOptionsE11
_ZN4PLMD4isdb3NOEC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/NOE.cpp.gcov.html b/coverage/isdb/NOE.cpp.gcov.html new file mode 100644 index 000000000000..e5f7243087ac --- /dev/null +++ b/coverage/isdb/NOE.cpp.gcov.html @@ -0,0 +1,351 @@ + + + + + + + + LCOV - plumed test coverage - isdb/NOE.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - NOE.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10210498.1 %
Date:2024-04-19 12:12:35Functions:4580.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2014-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "MetainferenceBase.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "tools/NeighborList.h"
+      25             : #include "tools/Pbc.h"
+      26             : #include <memory>
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace isdb {
+      30             : 
+      31             : //+PLUMEDOC ISDB_COLVAR NOE
+      32             : /*
+      33             : Calculates NOE intensities as sums of 1/r^6, also averaging over multiple equivalent atoms
+      34             :  or ambiguous NOE.
+      35             : 
+      36             : Each NOE is defined by two groups containing the same number of atoms, distances are
+      37             : calculated in pairs, transformed in 1/r^6, summed and saved as components.
+      38             : 
+      39             : \f[
+      40             : NOE() = (\frac{1}{N_{eq}}\sum_j^{N_{eq}} (\frac{1}{r_j^6}))
+      41             : \f]
+      42             : 
+      43             : NOE can be used to calculate a Metainference score over one or more replicas using the intrinsic implementation
+      44             : of \ref METAINFERENCE that is activated by DOSCORE.
+      45             : 
+      46             : \par Examples
+      47             : In the following examples three noes are defined, the first is calculated based on the distances
+      48             : of atom 1-2 and 3-2; the second is defined by the distance 5-7 and the third by the distances
+      49             : 4-15,4-16,8-15,8-16. \ref METAINFERENCE is activated using DOSCORE.
+      50             : 
+      51             : \plumedfile
+      52             : NOE ...
+      53             : GROUPA1=1,3 GROUPB1=2,2 NOEDIST1=0.6
+      54             : GROUPA2=5 GROUPB2=7 NOEDIST2=0.6
+      55             : GROUPA3=4,4,8,8 GROUPB3=15,16,15,16 NOEDIST3=0.6
+      56             : DOSCORE
+      57             : SIGMA_MEAN0=1
+      58             : LABEL=noes
+      59             : ... NOE
+      60             : 
+      61             : PRINT ARG=noes.* FILE=colvar
+      62             : \endplumedfile
+      63             : 
+      64             : */
+      65             : //+ENDPLUMEDOC
+      66             : 
+      67             : class NOE :
+      68             :   public MetainferenceBase
+      69             : {
+      70             : private:
+      71             :   bool             pbc;
+      72             :   std::vector<unsigned> nga;
+      73             :   std::unique_ptr<NeighborList> nl;
+      74             :   unsigned         tot_size;
+      75             : public:
+      76             :   static void registerKeywords( Keywords& keys );
+      77             :   explicit NOE(const ActionOptions&);
+      78             :   void calculate() override;
+      79             :   void update() override;
+      80             : };
+      81             : 
+      82             : PLUMED_REGISTER_ACTION(NOE,"NOE")
+      83             : 
+      84          13 : void NOE::registerKeywords( Keywords& keys ) {
+      85          13 :   componentsAreNotOptional(keys);
+      86          13 :   MetainferenceBase::registerKeywords(keys);
+      87          26 :   keys.addFlag("NOPBC",false,"ignore the periodic boundary conditions when calculating distances");
+      88          26 :   keys.add("numbered","GROUPA","the atoms involved in each of the contacts you wish to calculate. "
+      89             :            "Keywords like GROUPA1, GROUPA2, GROUPA3,... should be listed and one contact will be "
+      90             :            "calculated for each ATOM keyword you specify.");
+      91          26 :   keys.add("numbered","GROUPB","the atoms involved in each of the contacts you wish to calculate. "
+      92             :            "Keywords like GROUPB1, GROUPB2, GROUPB3,... should be listed and one contact will be "
+      93             :            "calculated for each ATOM keyword you specify.");
+      94          26 :   keys.reset_style("GROUPA","atoms");
+      95          26 :   keys.reset_style("GROUPB","atoms");
+      96          26 :   keys.add("numbered","NOEDIST","Add an experimental value for each NOE.");
+      97          26 :   keys.addOutputComponent("noe","default","the # NOE");
+      98          26 :   keys.addOutputComponent("exp","NOEDIST","the # NOE experimental distance");
+      99          13 : }
+     100             : 
+     101          11 : NOE::NOE(const ActionOptions&ao):
+     102             :   PLUMED_METAINF_INIT(ao),
+     103          11 :   pbc(true)
+     104             : {
+     105          11 :   bool nopbc=!pbc;
+     106          11 :   parseFlag("NOPBC",nopbc);
+     107          11 :   pbc=!nopbc;
+     108             : 
+     109             :   // Read in the atoms
+     110             :   std::vector<AtomNumber> t, ga_lista, gb_lista;
+     111          22 :   for(int i=1;; ++i ) {
+     112          66 :     parseAtomList("GROUPA", i, t );
+     113          33 :     if( t.empty() ) break;
+     114          55 :     for(unsigned j=0; j<t.size(); j++) ga_lista.push_back(t[j]);
+     115          22 :     nga.push_back(t.size());
+     116          22 :     t.resize(0);
+     117          22 :   }
+     118             :   std::vector<unsigned> ngb;
+     119          22 :   for(int i=1;; ++i ) {
+     120          66 :     parseAtomList("GROUPB", i, t );
+     121          33 :     if( t.empty() ) break;
+     122          55 :     for(unsigned j=0; j<t.size(); j++) gb_lista.push_back(t[j]);
+     123          22 :     ngb.push_back(t.size());
+     124          22 :     if(ngb[i-1]!=nga[i-1]) error("The same number of atoms is expected for the same GROUPA-GROUPB couple");
+     125          22 :     t.resize(0);
+     126          22 :   }
+     127          11 :   if(nga.size()!=ngb.size()) error("There should be the same number of GROUPA and GROUPB keywords");
+     128             :   // Create neighbour lists
+     129          22 :   nl=Tools::make_unique<NeighborList>(ga_lista,gb_lista,false,true,pbc,getPbc(),comm);
+     130             : 
+     131             :   // Optionally add an experimental value (like with RDCs)
+     132             :   std::vector<double> noedist;
+     133          11 :   noedist.resize( nga.size() );
+     134             :   unsigned ntarget=0;
+     135          29 :   for(unsigned i=0; i<nga.size(); ++i) {
+     136          40 :     if( !parseNumbered( "NOEDIST", i+1, noedist[i] ) ) break;
+     137          18 :     ntarget++;
+     138             :   }
+     139             :   bool addexp=false;
+     140          11 :   if(ntarget!=nga.size() && ntarget!=0) error("found wrong number of NOEDIST values");
+     141          11 :   if(ntarget==nga.size()) addexp=true;
+     142          11 :   if(getDoScore()&&!addexp) error("with DOSCORE you need to set the NOEDIST values");
+     143             : 
+     144             :   // Output details of all contacts
+     145             :   unsigned index=0;
+     146          33 :   for(unsigned i=0; i<nga.size(); ++i) {
+     147          22 :     log.printf("  The %uth NOE is calculated using %u equivalent couples of atoms\n", i, nga[i]);
+     148          55 :     for(unsigned j=0; j<nga[i]; j++) {
+     149          33 :       log.printf("    couple %u is %d %d.\n", j, ga_lista[index].serial(), gb_lista[index].serial() );
+     150          33 :       index++;
+     151             :     }
+     152             :   }
+     153          11 :   tot_size = index;
+     154             : 
+     155          11 :   if(pbc)      log.printf("  using periodic boundary conditions\n");
+     156           0 :   else         log.printf("  without periodic boundary conditions\n");
+     157             : 
+     158          22 :   log << " Bibliography" << plumed.cite("Bonomi, Camilloni, Bioinformatics, 33, 3999 (2017)") << "\n";
+     159             : 
+     160          11 :   if(!getDoScore()) {
+     161          21 :     for(unsigned i=0; i<nga.size(); i++) {
+     162          14 :       std::string num; Tools::convert(i,num);
+     163          28 :       addComponentWithDerivatives("noe-"+num);
+     164          28 :       componentIsNotPeriodic("noe-"+num);
+     165             :     }
+     166           7 :     if(addexp) {
+     167          15 :       for(unsigned i=0; i<nga.size(); i++) {
+     168          10 :         std::string num; Tools::convert(i,num);
+     169          20 :         addComponent("exp-"+num);
+     170          10 :         componentIsNotPeriodic("exp-"+num);
+     171          10 :         Value* comp=getPntrToComponent("exp-"+num);
+     172          10 :         comp->set(noedist[i]);
+     173             :       }
+     174             :     }
+     175             :   } else {
+     176          12 :     for(unsigned i=0; i<nga.size(); i++) {
+     177           8 :       std::string num; Tools::convert(i,num);
+     178          16 :       addComponent("noe-"+num);
+     179          16 :       componentIsNotPeriodic("noe-"+num);
+     180             :     }
+     181          12 :     for(unsigned i=0; i<nga.size(); i++) {
+     182           8 :       std::string num; Tools::convert(i,num);
+     183          16 :       addComponent("exp-"+num);
+     184           8 :       componentIsNotPeriodic("exp-"+num);
+     185           8 :       Value* comp=getPntrToComponent("exp-"+num);
+     186           8 :       comp->set(noedist[i]);
+     187             :     }
+     188             :   }
+     189             : 
+     190          11 :   requestAtoms(nl->getFullAtomList(), false);
+     191          11 :   if(getDoScore()) {
+     192           4 :     setParameters(noedist);
+     193           4 :     Initialise(nga.size());
+     194             :   }
+     195          11 :   setDerivatives();
+     196          11 :   checkRead();
+     197          11 : }
+     198             : 
+     199         456 : void NOE::calculate()
+     200             : {
+     201         456 :   const unsigned ngasz=nga.size();
+     202         456 :   std::vector<Vector> deriv(tot_size, Vector{0,0,0});
+     203             : 
+     204         456 :   #pragma omp parallel for num_threads(OpenMP::getNumThreads())
+     205             :   for(unsigned i=0; i<ngasz; i++) {
+     206             :     Tensor dervir;
+     207             :     double noe=0;
+     208             :     unsigned index=0;
+     209             :     for(unsigned k=0; k<i; k++) index+=nga[k];
+     210             :     std::string num; Tools::convert(i,num);
+     211             :     Value* val=getPntrToComponent("noe-"+num);
+     212             :     // cycle over equivalent atoms
+     213             :     for(unsigned j=0; j<nga[i]; j++) {
+     214             :       const unsigned i0=nl->getClosePair(index+j).first;
+     215             :       const unsigned i1=nl->getClosePair(index+j).second;
+     216             : 
+     217             :       Vector distance;
+     218             :       if(pbc) distance=pbcDistance(getPosition(i0),getPosition(i1));
+     219             :       else    distance=delta(getPosition(i0),getPosition(i1));
+     220             : 
+     221             :       const double ir2=1./distance.modulo2();
+     222             :       const double ir6=ir2*ir2*ir2;
+     223             :       const double ir8=6*ir6*ir2;
+     224             : 
+     225             :       noe += ir6;
+     226             :       deriv[index+j] = ir8*distance;
+     227             :       if(!getDoScore()) {
+     228             :         dervir += Tensor(distance, deriv[index+j]);
+     229             :         setAtomsDerivatives(val, i0,  deriv[index+j]);
+     230             :         setAtomsDerivatives(val, i1, -deriv[index+j]);
+     231             :       }
+     232             :     }
+     233             :     val->set(noe);
+     234             :     if(!getDoScore()) {
+     235             :       setBoxDerivatives(val, dervir);
+     236             :     } else setCalcData(i, noe);
+     237             :   }
+     238             : 
+     239         456 :   if(getDoScore()) {
+     240             :     /* Metainference */
+     241          48 :     Tensor dervir;
+     242          48 :     double score = getScore();
+     243          48 :     setScore(score);
+     244             : 
+     245             :     /* calculate final derivatives */
+     246          48 :     Value* val=getPntrToComponent("score");
+     247         144 :     for(unsigned i=0; i<ngasz; i++) {
+     248             :       unsigned index=0;
+     249         144 :       for(unsigned k=0; k<i; k++) index+=nga[k];
+     250             :       // cycle over equivalent atoms
+     251         240 :       for(unsigned j=0; j<nga[i]; j++) {
+     252         144 :         const unsigned i0=nl->getClosePair(index+j).first;
+     253         144 :         const unsigned i1=nl->getClosePair(index+j).second;
+     254             : 
+     255         144 :         Vector distance;
+     256         144 :         if(pbc) distance=pbcDistance(getPosition(i0),getPosition(i1));
+     257           0 :         else    distance=delta(getPosition(i0),getPosition(i1));
+     258             : 
+     259         144 :         dervir += Tensor(distance,deriv[index+j]*getMetaDer(i));
+     260         144 :         setAtomsDerivatives(val, i0,  deriv[index+j]*getMetaDer(i));
+     261         144 :         setAtomsDerivatives(val, i1, -deriv[index+j]*getMetaDer(i));
+     262             :       }
+     263             :     }
+     264          48 :     setBoxDerivatives(val, dervir);
+     265             :   }
+     266         456 : }
+     267             : 
+     268         132 : void NOE::update() {
+     269             :   // write status file
+     270         132 :   if(getWstride()>0&& (getStep()%getWstride()==0 || getCPT()) ) writeStatus();
+     271         132 : }
+     272             : 
+     273             : }
+     274             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/PRE.cpp.func-sort-c.html b/coverage/isdb/PRE.cpp.func-sort-c.html new file mode 100644 index 000000000000..0116c316ae7d --- /dev/null +++ b/coverage/isdb/PRE.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - isdb/PRE.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - PRE.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11912992.2 %
Date:2024-04-19 12:12:35Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb3PREC2ERKNS_13ActionOptionsE0
_ZN4PLMD4isdb3PREC1ERKNS_13ActionOptionsE4
_ZN4PLMD4isdb3PRE16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD4isdb3PRE6updateEv20
_ZN4PLMD4isdb3PRE9calculateEv350
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/PRE.cpp.func.html b/coverage/isdb/PRE.cpp.func.html new file mode 100644 index 000000000000..fd45fbb6bfa6 --- /dev/null +++ b/coverage/isdb/PRE.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - isdb/PRE.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - PRE.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11912992.2 %
Date:2024-04-19 12:12:35Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb3PRE16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD4isdb3PRE6updateEv20
_ZN4PLMD4isdb3PRE9calculateEv350
_ZN4PLMD4isdb3PREC1ERKNS_13ActionOptionsE4
_ZN4PLMD4isdb3PREC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/PRE.cpp.gcov.html b/coverage/isdb/PRE.cpp.gcov.html new file mode 100644 index 000000000000..969be4cd526e --- /dev/null +++ b/coverage/isdb/PRE.cpp.gcov.html @@ -0,0 +1,417 @@ + + + + + + + + LCOV - plumed test coverage - isdb/PRE.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - PRE.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11912992.2 %
Date:2024-04-19 12:12:35Functions:4580.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "MetainferenceBase.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "tools/NeighborList.h"
+      25             : #include "tools/Pbc.h"
+      26             : #include <memory>
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace isdb {
+      30             : 
+      31             : //+PLUMEDOC ISDB_COLVAR PRE
+      32             : /*
+      33             : Calculates the Paramagnetic Resonance Enhancement intensity ratio between a spin label atom and a list of atoms .
+      34             : 
+      35             : The reference atom for the spin label is added with SPINLABEL, the affected atom(s)
+      36             : are give as numbered GROUPA1, GROUPA2, ...
+      37             : The additional parameters needed for the calculation are given as INEPT, the inept
+      38             : time, TAUC the correlation time, OMEGA, the Larmor frequency and RTWO for the relaxation
+      39             : time.
+      40             : 
+      41             : \ref METAINFERENCE can be activated using DOSCORE and the other relevant keywords.
+      42             : 
+      43             : \par Examples
+      44             : 
+      45             : In the following example five PRE intensities are calculated using the distance between the
+      46             : oxygen of the spin label and the backbone hydrogen atoms. Omega is the NMR frequency, RTWO the
+      47             : R2 for the hydrogen atoms, INEPT of 8 ms for the experiment and a TAUC of 1.21 ns
+      48             : 
+      49             : \plumedfile
+      50             : PRE ...
+      51             : LABEL=HN_pre
+      52             : INEPT=8
+      53             : TAUC=1.21
+      54             : OMEGA=900
+      55             : SPINLABEL=1818
+      56             : GROUPA1=86  RTWO1=0.0120272827
+      57             : GROUPA2=177 RTWO2=0.0263953158
+      58             : GROUPA3=285 RTWO3=0.0058899829
+      59             : GROUPA4=335 RTWO4=0.0102072646
+      60             : GROUPA5=451 RTWO5=0.0086341843
+      61             : ... PRE
+      62             : 
+      63             : PRINT ARG=HN_pre.* FILE=PRE.dat STRIDE=1
+      64             : 
+      65             : \endplumedfile
+      66             : 
+      67             : */
+      68             : //+ENDPLUMEDOC
+      69             : 
+      70             : class PRE :
+      71             :   public MetainferenceBase
+      72             : {
+      73             : private:
+      74             :   bool             pbc;
+      75             :   bool             doratio;
+      76             :   double           constant;
+      77             :   double           inept;
+      78             :   std::vector<double>   rtwo;
+      79             :   std::vector<unsigned> nga;
+      80             :   std::unique_ptr<NeighborList> nl;
+      81             :   unsigned         tot_size;
+      82             : public:
+      83             :   static void registerKeywords( Keywords& keys );
+      84             :   explicit PRE(const ActionOptions&);
+      85             :   void calculate() override;
+      86             :   void update() override;
+      87             : };
+      88             : 
+      89             : PLUMED_REGISTER_ACTION(PRE,"PRE")
+      90             : 
+      91           6 : void PRE::registerKeywords( Keywords& keys ) {
+      92           6 :   componentsAreNotOptional(keys);
+      93           6 :   MetainferenceBase::registerKeywords(keys);
+      94          12 :   keys.addFlag("NOPBC",false,"ignore the periodic boundary conditions when calculating distances");
+      95          12 :   keys.addFlag("NORATIO",false,"Set to TRUE if you want to compute PRE without Intensity Ratio");
+      96          12 :   keys.add("compulsory","INEPT","is the INEPT time (in ms).");
+      97          12 :   keys.add("compulsory","TAUC","is the correlation time (in ns) for this electron-nuclear interaction.");
+      98          12 :   keys.add("compulsory","OMEGA","is the Larmor frequency of the nuclear spin (in MHz).");
+      99          12 :   keys.add("atoms","SPINLABEL","The atom to be used as the paramagnetic center.");
+     100          12 :   keys.add("numbered","GROUPA","the atoms involved in each of the contacts you wish to calculate. "
+     101             :            "Keywords like GROUPA1, GROUPA2, GROUPA3,... should be listed and one contact will be "
+     102             :            "calculated for each ATOM keyword you specify.");
+     103          12 :   keys.reset_style("GROUPA","atoms");
+     104          12 :   keys.add("numbered","RTWO","The relaxation of the atom/atoms in the corresponding GROUPA of atoms. "
+     105             :            "Keywords like RTWO1, RTWO2, RTWO3,... should be listed.");
+     106          12 :   keys.add("numbered","PREINT","Add an experimental value for each PRE.");
+     107          12 :   keys.addOutputComponent("pre","default","the # PRE");
+     108          12 :   keys.addOutputComponent("exp","PREINT","the # PRE experimental intensity");
+     109           6 : }
+     110             : 
+     111           4 : PRE::PRE(const ActionOptions&ao):
+     112             :   PLUMED_METAINF_INIT(ao),
+     113           4 :   pbc(true),
+     114           4 :   doratio(true)
+     115             : {
+     116           4 :   bool nopbc=!pbc;
+     117           4 :   parseFlag("NOPBC",nopbc);
+     118           4 :   pbc=!nopbc;
+     119             : 
+     120           4 :   bool noratio=!doratio;
+     121           4 :   parseFlag("NORATIO",noratio);
+     122           4 :   doratio=!noratio;
+     123             : 
+     124             :   std::vector<AtomNumber> atom;
+     125           8 :   parseAtomList("SPINLABEL",atom);
+     126           4 :   if(atom.size()!=1) error("Number of specified atom should be 1");
+     127             : 
+     128             :   // Read in the atoms
+     129             :   std::vector<AtomNumber> t, ga_lista, gb_lista;
+     130          12 :   for(int i=1;; ++i ) {
+     131          32 :     parseAtomList("GROUPA", i, t );
+     132          16 :     if( t.empty() ) break;
+     133          28 :     for(unsigned j=0; j<t.size(); j++) {ga_lista.push_back(t[j]); gb_lista.push_back(atom[0]);}
+     134          12 :     nga.push_back(t.size());
+     135          12 :     t.resize(0);
+     136          12 :   }
+     137             : 
+     138             :   // Read in reference values
+     139           4 :   rtwo.resize( nga.size() );
+     140           4 :   if(doratio) {
+     141             :     unsigned ntarget=0;
+     142           4 :     for(unsigned i=0; i<nga.size(); ++i) {
+     143           8 :       if( !parseNumbered( "RTWO", i+1, rtwo[i] ) ) break;
+     144           0 :       ntarget++;
+     145             :     }
+     146           4 :     if( ntarget==0 ) {
+     147           4 :       parse("RTWO",rtwo[0]);
+     148          12 :       for(unsigned i=1; i<nga.size(); ++i) rtwo[i]=rtwo[0];
+     149           0 :     } else if( ntarget!=nga.size() ) error("found wrong number of RTWO values");
+     150             :   }
+     151             : 
+     152           4 :   double tauc=0.;
+     153           4 :   parse("TAUC",tauc);
+     154           4 :   if(tauc==0.) error("TAUC must be set");
+     155             : 
+     156           4 :   double omega=0.;
+     157           4 :   parse("OMEGA",omega);
+     158           4 :   if(omega==0.) error("OMEGA must be set");
+     159             : 
+     160           4 :   inept=0.;
+     161           4 :   if(doratio) {
+     162           4 :     parse("INEPT",inept);
+     163           4 :     if(inept==0.) error("INEPT must be set");
+     164           4 :     inept *= 0.001; // ms2s
+     165             :   }
+     166             : 
+     167             :   const double ns2s   = 0.000000001;
+     168             :   const double MHz2Hz = 1000000.;
+     169             :   const double Kappa  = 12300000000.00; // this is 1/15*S*(S+1)*gamma^2*g^2*beta^2
+     170             :   // where gamma is the nuclear gyromagnetic ratio,
+     171             :   // g is the electronic g factor, and beta is the Bohr magneton
+     172             :   // in nm^6/s^2
+     173           4 :   constant = (4.*tauc*ns2s+(3.*tauc*ns2s)/(1+omega*omega*MHz2Hz*MHz2Hz*tauc*tauc*ns2s*ns2s))*Kappa;
+     174             : 
+     175             :   // Optionally add an experimental value (like with RDCs)
+     176             :   std::vector<double> exppre;
+     177           4 :   exppre.resize( nga.size() );
+     178             :   unsigned ntarget=0;
+     179          10 :   for(unsigned i=0; i<nga.size(); ++i) {
+     180          16 :     if( !parseNumbered( "PREINT", i+1, exppre[i] ) ) break;
+     181           6 :     ntarget++;
+     182             :   }
+     183             :   bool addexp=false;
+     184           4 :   if(ntarget!=nga.size() && ntarget!=0) error("found wrong number of PREINT values");
+     185           4 :   if(ntarget==nga.size()) addexp=true;
+     186           4 :   if(getDoScore()&&!addexp) error("with DOSCORE you need to set the PREINT values");
+     187             : 
+     188             :   // Create neighbour lists
+     189           8 :   nl=Tools::make_unique<NeighborList>(gb_lista,ga_lista,false,true,pbc,getPbc(),comm);
+     190             : 
+     191             :   // Output details of all contacts
+     192             :   unsigned index=0;
+     193          16 :   for(unsigned i=0; i<nga.size(); ++i) {
+     194          12 :     log.printf("  The %uth PRE is calculated using %u equivalent atoms:\n", i, nga[i]);
+     195          12 :     log.printf("    %d", ga_lista[index].serial());
+     196          12 :     index++;
+     197          16 :     for(unsigned j=1; j<nga[i]; j++) {
+     198           4 :       log.printf(" %d", ga_lista[index].serial());
+     199           4 :       index++;
+     200             :     }
+     201          12 :     log.printf("\n");
+     202             :   }
+     203           4 :   tot_size = index;
+     204             : 
+     205           4 :   if(pbc)      log.printf("  using periodic boundary conditions\n");
+     206           0 :   else         log.printf("  without periodic boundary conditions\n");
+     207             : 
+     208           8 :   log << " Bibliography" << plumed.cite("Bonomi, Camilloni, Bioinformatics, 33, 3999 (2017)") << "\n";
+     209             : 
+     210           4 :   if(!getDoScore()) {
+     211           8 :     for(unsigned i=0; i<nga.size(); i++) {
+     212           6 :       std::string num; Tools::convert(i,num);
+     213          12 :       addComponentWithDerivatives("pre-"+num);
+     214          12 :       componentIsNotPeriodic("pre-"+num);
+     215             :     }
+     216           2 :     if(addexp) {
+     217           0 :       for(unsigned i=0; i<nga.size(); i++) {
+     218           0 :         std::string num; Tools::convert(i,num);
+     219           0 :         addComponent("exp-"+num);
+     220           0 :         componentIsNotPeriodic("exp-"+num);
+     221           0 :         Value* comp=getPntrToComponent("exp-"+num);
+     222           0 :         comp->set(exppre[i]);
+     223             :       }
+     224             :     }
+     225             :   } else {
+     226           8 :     for(unsigned i=0; i<nga.size(); i++) {
+     227           6 :       std::string num; Tools::convert(i,num);
+     228          12 :       addComponent("pre-"+num);
+     229          12 :       componentIsNotPeriodic("pre-"+num);
+     230             :     }
+     231           8 :     for(unsigned i=0; i<nga.size(); i++) {
+     232           6 :       std::string num; Tools::convert(i,num);
+     233          12 :       addComponent("exp-"+num);
+     234           6 :       componentIsNotPeriodic("exp-"+num);
+     235           6 :       Value* comp=getPntrToComponent("exp-"+num);
+     236           6 :       comp->set(exppre[i]);
+     237             :     }
+     238             :   }
+     239             : 
+     240           4 :   requestAtoms(nl->getFullAtomList(), false);
+     241           4 :   if(getDoScore()) {
+     242           2 :     setParameters(exppre);
+     243           2 :     Initialise(nga.size());
+     244             :   }
+     245           4 :   setDerivatives();
+     246           4 :   checkRead();
+     247           4 : }
+     248             : 
+     249         350 : void PRE::calculate()
+     250             : {
+     251         350 :   std::vector<Vector> deriv(tot_size, Vector{0,0,0});
+     252         350 :   std::vector<double> fact(nga.size(), 0.);
+     253             : 
+     254             :   // cycle over the number of PRE
+     255         350 :   #pragma omp parallel for num_threads(OpenMP::getNumThreads())
+     256             :   for(unsigned i=0; i<nga.size(); i++) {
+     257             :     Tensor dervir;
+     258             :     double pre=0;
+     259             :     unsigned index=0;
+     260             :     for(unsigned k=0; k<i; k++) index+=nga[k];
+     261             :     const double c_aver=constant/static_cast<double>(nga[i]);
+     262             :     std::string num; Tools::convert(i,num);
+     263             :     Value* val=getPntrToComponent("pre-"+num);
+     264             :     // cycle over equivalent atoms
+     265             :     for(unsigned j=0; j<nga[i]; j++) {
+     266             :       // the first atom is always the same (the paramagnetic group)
+     267             :       const unsigned i0=nl->getClosePair(index+j).first;
+     268             :       const unsigned i1=nl->getClosePair(index+j).second;
+     269             : 
+     270             :       Vector distance;
+     271             :       if(pbc) distance=pbcDistance(getPosition(i0),getPosition(i1));
+     272             :       else    distance=delta(getPosition(i0),getPosition(i1));
+     273             : 
+     274             :       const double r2=distance.modulo2();
+     275             :       const double r6=r2*r2*r2;
+     276             :       const double r8=r6*r2;
+     277             :       const double tmpir6=c_aver/r6;
+     278             :       const double tmpir8=-6.*c_aver/r8;
+     279             : 
+     280             :       pre += tmpir6;
+     281             :       deriv[index+j] = -tmpir8*distance;
+     282             :       if(!getDoScore()) dervir   +=  Tensor(distance,deriv[index+j]);
+     283             :     }
+     284             :     double tmpratio;
+     285             :     if(!doratio) {
+     286             :       tmpratio = pre ; //prova a caso per vedere se lui da problemi
+     287             :       fact[i] = 1.; //prova a caso per vedere se lui da problemi
+     288             :     } else {
+     289             :       tmpratio = rtwo[i]*std::exp(-pre*inept) / (rtwo[i]+pre);
+     290             :       fact[i] = -tmpratio*(inept+1./(rtwo[i]+pre));
+     291             :     }
+     292             :     const double ratio = tmpratio;
+     293             :     val->set(ratio) ;
+     294             :     if(!getDoScore()) {
+     295             :       setBoxDerivatives(val, fact[i]*dervir);
+     296             :       for(unsigned j=0; j<nga[i]; j++) {
+     297             :         const unsigned i0=nl->getClosePair(index+j).first;
+     298             :         const unsigned i1=nl->getClosePair(index+j).second;
+     299             :         setAtomsDerivatives(val, i0,  fact[i]*deriv[index+j]);
+     300             :         setAtomsDerivatives(val, i1, -fact[i]*deriv[index+j]);
+     301             :       }
+     302             :     } else setCalcData(i, ratio);
+     303             :   }
+     304             : 
+     305         350 :   if(getDoScore()) {
+     306             :     /* Metainference */
+     307         175 :     Tensor dervir;
+     308         175 :     double score = getScore();
+     309         175 :     setScore(score);
+     310             : 
+     311             :     /* calculate final derivatives */
+     312         175 :     Value* val=getPntrToComponent("score");
+     313         700 :     for(unsigned i=0; i<nga.size(); i++) {
+     314             :       unsigned index=0;
+     315        1050 :       for(unsigned k=0; k<i; k++) index+=nga[k];
+     316             :       // cycle over equivalent atoms
+     317        1225 :       for(unsigned j=0; j<nga[i]; j++) {
+     318         700 :         const unsigned i0=nl->getClosePair(index+j).first;
+     319         700 :         const unsigned i1=nl->getClosePair(index+j).second;
+     320             : 
+     321         700 :         Vector distance;
+     322         700 :         if(pbc) distance=pbcDistance(getPosition(i0),getPosition(i1));
+     323           0 :         else    distance=delta(getPosition(i0),getPosition(i1));
+     324             : 
+     325         700 :         dervir += Tensor(distance,fact[i]*deriv[index+j]*getMetaDer(i));
+     326         700 :         setAtomsDerivatives(val, i0,  fact[i]*deriv[index+j]*getMetaDer(i));
+     327         700 :         setAtomsDerivatives(val, i1, -fact[i]*deriv[index+j]*getMetaDer(i));
+     328             :       }
+     329             :     }
+     330         175 :     setBoxDerivatives(val, dervir);
+     331             :   }
+     332         350 : }
+     333             : 
+     334          20 : void PRE::update() {
+     335             :   // write status file
+     336          20 :   if(getWstride()>0&& (getStep()%getWstride()==0 || getCPT()) ) writeStatus();
+     337          20 : }
+     338             : 
+     339             : }
+     340             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/RDC.cpp.func-sort-c.html b/coverage/isdb/RDC.cpp.func-sort-c.html new file mode 100644 index 000000000000..d557ab918901 --- /dev/null +++ b/coverage/isdb/RDC.cpp.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - isdb/RDC.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - RDC.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:17018193.9 %
Date:2024-04-19 12:12:35Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb3RDCC2ERKNS_13ActionOptionsE0
_ZN4PLMD4isdb3RDC6do_svdEv5
_ZN4PLMD4isdb3RDCC1ERKNS_13ActionOptionsE29
_ZN4PLMD4isdb3RDC16registerKeywordsERNS_8KeywordsE33
_ZN4PLMD4isdb3RDC6updateEv327
_ZN4PLMD4isdb3RDC9calculateEv2172
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/RDC.cpp.func.html b/coverage/isdb/RDC.cpp.func.html new file mode 100644 index 000000000000..fab9004767bb --- /dev/null +++ b/coverage/isdb/RDC.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - isdb/RDC.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - RDC.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:17018193.9 %
Date:2024-04-19 12:12:35Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb3RDC16registerKeywordsERNS_8KeywordsE33
_ZN4PLMD4isdb3RDC6do_svdEv5
_ZN4PLMD4isdb3RDC6updateEv327
_ZN4PLMD4isdb3RDC9calculateEv2172
_ZN4PLMD4isdb3RDCC1ERKNS_13ActionOptionsE29
_ZN4PLMD4isdb3RDCC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/RDC.cpp.gcov.html b/coverage/isdb/RDC.cpp.gcov.html new file mode 100644 index 000000000000..4a204c240ffd --- /dev/null +++ b/coverage/isdb/RDC.cpp.gcov.html @@ -0,0 +1,598 @@ + + + + + + + + LCOV - plumed test coverage - isdb/RDC.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - RDC.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:17018193.9 %
Date:2024-04-19 12:12:35Functions:5683.3 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2014-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "MetainferenceBase.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "tools/Pbc.h"
+      25             : 
+      26             : #ifdef __PLUMED_HAS_GSL
+      27             : #include <gsl/gsl_vector.h>
+      28             : #include <gsl/gsl_matrix.h>
+      29             : #include <gsl/gsl_linalg.h>
+      30             : #include <gsl/gsl_blas.h>
+      31             : #endif
+      32             : 
+      33             : namespace PLMD {
+      34             : namespace isdb {
+      35             : 
+      36             : //+PLUMEDOC ISDB_COLVAR RDC
+      37             : /*
+      38             : Calculates the (Residual) Dipolar Coupling between two atoms.
+      39             : 
+      40             : The Dipolar Coupling between two nuclei depends on the \f$\theta\f$ angle between
+      41             : the inter-nuclear vector and the external magnetic field.
+      42             : 
+      43             : \f[
+      44             : D=D_{max}0.5(3\cos^2(\theta)-1)
+      45             : \f]
+      46             : 
+      47             : where
+      48             : 
+      49             : \f[
+      50             : D_{max}=-\mu_0\gamma_1\gamma_2h/(8\pi^3r^3)
+      51             : \f]
+      52             : 
+      53             : that is the maximal value of the dipolar coupling for the two nuclear spins with gyromagnetic ratio \f$\gamma\f$.
+      54             : \f$\mu\f$ is the magnetic constant and h is the Planck constant.
+      55             : 
+      56             : Common Gyromagnetic Ratios (C.G.S)
+      57             : - H(1) 26.7513
+      58             : - C(13) 6.7261
+      59             : - N(15) -2.7116
+      60             : and their products (this is what is given in input using the keyword GYROM)
+      61             : - N-H -72.5388
+      62             : - C-H 179.9319
+      63             : - C-N -18.2385
+      64             : - C-C 45.2404
+      65             : 
+      66             : In isotropic media DCs average to zero because of the rotational
+      67             : averaging, but when the rotational symmetry is broken, either through the introduction of an alignment medium or for molecules
+      68             : with highly anisotropic paramagnetic susceptibility, then the average of the DCs is not zero and it is possible to measure a Residual Dipolar Coupling (RDCs).
+      69             : 
+      70             : This collective variable calculates the Dipolar Coupling for a set of couple of atoms using
+      71             : the above definition.
+      72             : 
+      73             : In a standard MD simulation the average over time of the DC should then be zero. If one wants to model the meaning of a set of measured RDCs it is possible to try to solve the following problem: "what is the distribution of structures and orientations that reproduce the measured RDCs".
+      74             : 
+      75             : This collective variable can then be use to break the rotational symmetry of a simulation by imposing that the average of the DCs over the conformational ensemble must be equal to the measured RDCs \cite Camilloni:2015ka . Since measured RDCs are also a function of the fraction of aligned molecules in the sample it is better to compare them modulo a constant or looking at the correlation.
+      76             : 
+      77             : Alternatively if the molecule is rigid it is possible to use the experimental data to calculate the alignment tensor and the use that to back calculate the RDCs, this is what is usually call the Single Value Decomposition approach. In this case the code rely on the
+      78             : a set of function from the GNU Scientific Library (GSL). (With SVD forces are not currently implemented).
+      79             : 
+      80             : Replica-Averaged simulations can be performed using RDCs, \ref ENSEMBLE, \ref STATS and \ref RESTRAINT .
+      81             : \ref METAINFERENCE can be activated using DOSCORE and the other relevant keywords.
+      82             : 
+      83             : Additional material and examples can be also found in the tutorial \ref isdb-1
+      84             : 
+      85             : \par Examples
+      86             : In the following example five N-H RDCs are defined and averaged over multiple replicas,
+      87             : their correlation is then calculated with respect to a set of experimental data and restrained.
+      88             : In addition, and only for analysis purposes, the same RDCs each single conformation are calculated
+      89             : using a Single Value Decomposition algorithm, then averaged and again compared with the experimental data.
+      90             : 
+      91             : \plumedfile
+      92             : #SETTINGS NREPLICAS=2
+      93             : RDC ...
+      94             : GYROM=-72.5388
+      95             : SCALE=0.001
+      96             : ATOMS1=20,21
+      97             : ATOMS2=37,38
+      98             : ATOMS3=56,57
+      99             : ATOMS4=76,77
+     100             : ATOMS5=92,93
+     101             : LABEL=nh
+     102             : ... RDC
+     103             : 
+     104             : erdc: ENSEMBLE ARG=nh.*
+     105             : 
+     106             : st: STATS ARG=erdc.* PARAMETERS=8.17,-8.271,-10.489,-9.871,-9.152
+     107             : 
+     108             : rdce: RESTRAINT ARG=st.corr KAPPA=0. SLOPE=-25000.0 AT=1.
+     109             : 
+     110             : RDC ...
+     111             : GYROM=-72.5388
+     112             : SVD
+     113             : ATOMS1=20,21 COUPLING1=8.17
+     114             : ATOMS2=37,38 COUPLING2=-8.271
+     115             : ATOMS3=56,57 COUPLING3=-10.489
+     116             : ATOMS4=76,77 COUPLING4=-9.871
+     117             : ATOMS5=92,93 COUPLING5=-9.152
+     118             : LABEL=svd
+     119             : ... RDC
+     120             : 
+     121             : esvd: ENSEMBLE ARG=(svd\.rdc-.*)
+     122             : 
+     123             : st_svd: STATS ARG=esvd.* PARAMETERS=8.17,-8.271,-10.489,-9.871,-9.152
+     124             : 
+     125             : PRINT ARG=st.corr,st_svd.corr,rdce.bias FILE=colvar
+     126             : \endplumedfile
+     127             : 
+     128             : */
+     129             : //+ENDPLUMEDOC
+     130             : 
+     131             : //+PLUMEDOC ISDB_COLVAR PCS
+     132             : /*
+     133             : Calculates the Pseudo-contact shift of a nucleus determined by the presence of a metal ion susceptible to anisotropic magnetization.
+     134             : 
+     135             : The PCS of an atomic nucleus depends on the \f$\theta\f$ angle between the vector from the spin-label to the nucleus
+     136             :  and the external magnetic field and the module of the vector itself \cite Camilloni:2015jf . While in principle the averaging
+     137             : resulting from the tumbling should remove the pseudo-contact shift, in presence of the NMR magnetic field the magnetically anisotropic molecule bound to system will break the rotational symmetry does resulting in measurable values for the PCS and RDC.
+     138             : 
+     139             : PCS values can also be calculated using a Single Value Decomposition approach, in this case the code rely on the
+     140             : a set of function from the GNU Scientific Library (GSL). (With SVD forces are not currently implemented).
+     141             : 
+     142             : Replica-Averaged simulations can be performed using PCS values, \ref ENSEMBLE, \ref STATS and \ref RESTRAINT .
+     143             : Metainference simulations can be performed with this CV and \ref METAINFERENCE .
+     144             : 
+     145             : \par Examples
+     146             : 
+     147             : In the following example five PCS values are defined and their correlation with
+     148             : respect to a set of experimental data is calculated and restrained. In addition,
+     149             : and only for analysis purposes, the same PCS values are calculated using a Single Value
+     150             : Decomposition algorithm.
+     151             : 
+     152             : \plumedfile
+     153             : PCS ...
+     154             : ATOMS1=20,21
+     155             : ATOMS2=20,38
+     156             : ATOMS3=20,57
+     157             : ATOMS4=20,77
+     158             : ATOMS5=20,93
+     159             : LABEL=nh
+     160             : ... PCS
+     161             : 
+     162             : enh: ENSEMBLE ARG=nh.*
+     163             : 
+     164             : st: STATS ARG=enh.* PARAMETERS=8.17,-8.271,-10.489,-9.871,-9.152
+     165             : 
+     166             : pcse: RESTRAINT ARG=st.corr KAPPA=0. SLOPE=-25000.0 AT=1.
+     167             : 
+     168             : PRINT ARG=st.corr,pcse.bias FILE=colvar
+     169             : \endplumedfile
+     170             : 
+     171             : */
+     172             : //+ENDPLUMEDOC
+     173             : 
+     174             : class RDC :
+     175             :   public MetainferenceBase
+     176             : {
+     177             : private:
+     178             :   double         Const;
+     179             :   double         mu_s;
+     180             :   double         scale;
+     181             :   std::vector<double> coupl;
+     182             :   bool           svd;
+     183             :   bool           pbc;
+     184             : 
+     185             : #ifdef __PLUMED_HAS_GSL
+     186             : /// Auxiliary class to delete a gsl_vector.
+     187             : /// If used somewhere else we can move it.
+     188             :   struct gsl_vector_deleter {
+     189             :     void operator()(gsl_vector* p) {
+     190          25 :       gsl_vector_free(p);
+     191          25 :     }
+     192             :   };
+     193             : 
+     194             : /// unique_ptr to a gsl_vector.
+     195             : /// Gets deleted when going out of scope.
+     196             :   typedef std::unique_ptr<gsl_vector,gsl_vector_deleter> gsl_vector_unique_ptr;
+     197             : 
+     198             : /// Auxiliary class to delete a gsl_matrix.
+     199             : /// If used somewhere else we can move it.
+     200             :   struct gsl_matrix_deleter {
+     201             :     void operator()(gsl_matrix* p) {
+     202          15 :       gsl_matrix_free(p);
+     203          15 :     }
+     204             :   };
+     205             : 
+     206             : /// unique_ptr to a gsl_matrix.
+     207             : /// Gets deleted when going out of scope.
+     208             :   typedef std::unique_ptr<gsl_matrix,gsl_matrix_deleter> gsl_matrix_unique_ptr;
+     209             : #endif
+     210             : 
+     211             : 
+     212             :   void do_svd();
+     213             : public:
+     214             :   explicit RDC(const ActionOptions&);
+     215             :   static void registerKeywords( Keywords& keys );
+     216             :   void calculate() override;
+     217             :   void update() override;
+     218             : };
+     219             : 
+     220             : PLUMED_REGISTER_ACTION(RDC,"RDC")
+     221             : PLUMED_REGISTER_ACTION(RDC,"PCS")
+     222             : 
+     223          33 : void RDC::registerKeywords( Keywords& keys ) {
+     224          33 :   componentsAreNotOptional(keys);
+     225          33 :   MetainferenceBase::registerKeywords(keys);
+     226          66 :   keys.addFlag("NOPBC",false,"ignore the periodic boundary conditions when calculating distances");
+     227          66 :   keys.add("numbered","ATOMS","the couple of atoms involved in each of the bonds for which you wish to calculate the RDC. "
+     228             :            "Keywords like ATOMS1, ATOMS2, ATOMS3,... should be listed and one dipolar coupling will be "
+     229             :            "calculated for each ATOMS keyword you specify.");
+     230          66 :   keys.reset_style("ATOMS","atoms");
+     231          66 :   keys.add("compulsory","GYROM","1.","Add the product of the gyromagnetic constants for the bond. ");
+     232          66 :   keys.add("compulsory","SCALE","1.","Add the scaling factor to take into account concentration and other effects. ");
+     233          66 :   keys.addFlag("SVD",false,"Set to TRUE if you want to back calculate using Single Value Decomposition (need GSL at compilation time).");
+     234          66 :   keys.add("numbered","COUPLING","Add an experimental value for each coupling (needed by SVD and useful for \\ref STATS).");
+     235          66 :   keys.addOutputComponent("rdc","default","the calculated # RDC");
+     236          66 :   keys.addOutputComponent("exp","SVD/COUPLING","the experimental # RDC");
+     237          66 :   keys.addOutputComponent("Sxx","SVD","Tensor component");
+     238          66 :   keys.addOutputComponent("Syy","SVD","Tensor component");
+     239          66 :   keys.addOutputComponent("Szz","SVD","Tensor component");
+     240          66 :   keys.addOutputComponent("Sxy","SVD","Tensor component");
+     241          66 :   keys.addOutputComponent("Sxz","SVD","Tensor component");
+     242          66 :   keys.addOutputComponent("Syz","SVD","Tensor component");
+     243          33 : }
+     244             : 
+     245          29 : RDC::RDC(const ActionOptions&ao):
+     246             :   PLUMED_METAINF_INIT(ao),
+     247          29 :   Const(1.),
+     248          29 :   mu_s(1.),
+     249          29 :   scale(1.),
+     250          29 :   pbc(true)
+     251             : {
+     252          29 :   bool nopbc=!pbc;
+     253          29 :   parseFlag("NOPBC",nopbc);
+     254          29 :   pbc=!nopbc;
+     255             : 
+     256             :   const double RDCConst = 0.3356806;
+     257             :   const double PCSConst = 1.0;
+     258             : 
+     259          29 :   if( getName().find("RDC")!=std::string::npos) { Const *= RDCConst; }
+     260           0 :   else if( getName().find("PCS")!=std::string::npos) { Const *= PCSConst; }
+     261             : 
+     262             :   // Read in the atoms
+     263             :   std::vector<AtomNumber> t, atoms;
+     264          29 :   for(int i=1;; ++i ) {
+     265         292 :     parseAtomList("ATOMS", i, t );
+     266         146 :     if( t.empty() ) break;
+     267         117 :     if( t.size()!=2 ) {
+     268           0 :       std::string ss; Tools::convert(i,ss);
+     269           0 :       error("ATOMS" + ss + " keyword has the wrong number of atoms");
+     270             :     }
+     271         117 :     atoms.push_back(t[0]);
+     272         117 :     atoms.push_back(t[1]);
+     273         117 :     t.resize(0);
+     274         117 :   }
+     275             : 
+     276          29 :   const unsigned ndata = atoms.size()/2;
+     277             : 
+     278             :   // Read in GYROMAGNETIC constants
+     279          29 :   parse("GYROM", mu_s);
+     280          29 :   if(mu_s==0.) error("GYROM cannot be 0");
+     281             : 
+     282             :   // Read in SCALING factors
+     283          29 :   parse("SCALE", scale);
+     284          29 :   if(scale==0.) error("SCALE cannot be 0");
+     285             : 
+     286          29 :   svd=false;
+     287          29 :   parseFlag("SVD",svd);
+     288             : #ifndef __PLUMED_HAS_GSL
+     289             :   if(svd) error("You CANNOT use SVD without GSL. Recompile PLUMED with GSL!\n");
+     290             : #endif
+     291          29 :   if(svd&&getDoScore()) error("It is not possible to use SVD and METAINFERENCE together");
+     292             : 
+     293             :   // Optionally add an experimental value
+     294          29 :   coupl.resize( ndata );
+     295             :   unsigned ntarget=0;
+     296          82 :   for(unsigned i=0; i<ndata; ++i) {
+     297         138 :     if( !parseNumbered( "COUPLING", i+1, coupl[i] ) ) break;
+     298          53 :     ntarget++;
+     299             :   }
+     300             :   bool addexp=false;
+     301          29 :   if(ntarget!=ndata && ntarget!=0) error("found wrong number of COUPLING values");
+     302          29 :   if(ntarget==ndata) addexp=true;
+     303          29 :   if(getDoScore()&&!addexp) error("with DOSCORE you need to set the COUPLING values");
+     304          29 :   if(svd&&!addexp) error("with SVD you need to set the COUPLING values");
+     305             : 
+     306             : 
+     307             :   // Output details of all contacts
+     308          29 :   log.printf("  Gyromagnetic moment is %f. Scaling factor is %f.",mu_s,scale);
+     309         146 :   for(unsigned i=0; i<ndata; ++i) {
+     310         117 :     log.printf("  The %uth Bond Dipolar Coupling is calculated from atoms : %d %d.", i+1, atoms[2*i].serial(), atoms[2*i+1].serial());
+     311         117 :     if(addexp) log.printf(" Experimental coupling is %f.", coupl[i]);
+     312         117 :     log.printf("\n");
+     313             :   }
+     314             : 
+     315          29 :   log<<"  Bibliography "
+     316          58 :      <<plumed.cite("Camilloni C, Vendruscolo M, J. Phys. Chem. B 119, 653 (2015)")
+     317          87 :      <<plumed.cite("Camilloni C, Vendruscolo M, Biochemistry 54, 7470 (2015)");
+     318          58 :   log<< plumed.cite("Bonomi, Camilloni, Bioinformatics, 33, 3999 (2017)") << "\n";
+     319             : 
+     320             : 
+     321          29 :   if(!getDoScore()&&!svd) {
+     322          80 :     for(unsigned i=0; i<ndata; i++) {
+     323          64 :       std::string num; Tools::convert(i,num);
+     324         128 :       addComponentWithDerivatives("rdc-"+num);
+     325         128 :       componentIsNotPeriodic("rdc-"+num);
+     326             :     }
+     327          16 :     if(addexp) {
+     328           0 :       for(unsigned i=0; i<ndata; i++) {
+     329           0 :         std::string num; Tools::convert(i,num);
+     330           0 :         addComponent("exp-"+num);
+     331           0 :         componentIsNotPeriodic("exp-"+num);
+     332           0 :         Value* comp=getPntrToComponent("exp-"+num);
+     333           0 :         comp->set(coupl[i]);
+     334             :       }
+     335             :     }
+     336             :   } else {
+     337          66 :     for(unsigned i=0; i<ndata; i++) {
+     338          53 :       std::string num; Tools::convert(i,num);
+     339         106 :       addComponentWithDerivatives("rdc-"+num);
+     340         106 :       componentIsNotPeriodic("rdc-"+num);
+     341             :     }
+     342          66 :     for(unsigned i=0; i<ndata; i++) {
+     343          53 :       std::string num; Tools::convert(i,num);
+     344         106 :       addComponent("exp-"+num);
+     345          53 :       componentIsNotPeriodic("exp-"+num);
+     346          53 :       Value* comp=getPntrToComponent("exp-"+num);
+     347          53 :       comp->set(coupl[i]);
+     348             :     }
+     349             :   }
+     350             : 
+     351          29 :   if(svd) {
+     352           3 :     addComponent("Sxx"); componentIsNotPeriodic("Sxx");
+     353           3 :     addComponent("Syy"); componentIsNotPeriodic("Syy");
+     354           3 :     addComponent("Szz"); componentIsNotPeriodic("Szz");
+     355           3 :     addComponent("Sxy"); componentIsNotPeriodic("Sxy");
+     356           3 :     addComponent("Sxz"); componentIsNotPeriodic("Sxz");
+     357           3 :     addComponent("Syz"); componentIsNotPeriodic("Syz");
+     358             :   }
+     359             : 
+     360          29 :   requestAtoms(atoms, false);
+     361          29 :   if(getDoScore()) {
+     362          12 :     setParameters(coupl);
+     363          12 :     Initialise(coupl.size());
+     364             :   }
+     365          29 :   setDerivatives();
+     366          29 :   checkRead();
+     367          29 : }
+     368             : 
+     369           5 : void RDC::do_svd()
+     370             : {
+     371             : #ifdef __PLUMED_HAS_GSL
+     372           5 :   gsl_vector_unique_ptr rdc_vec(gsl_vector_alloc(coupl.size())),
+     373           5 :                         S(gsl_vector_alloc(5)),
+     374           5 :                         Stmp(gsl_vector_alloc(5)),
+     375           5 :                         work(gsl_vector_alloc(5)),
+     376           5 :                         bc(gsl_vector_alloc(coupl.size()));
+     377             : 
+     378           5 :   gsl_matrix_unique_ptr coef_mat(gsl_matrix_alloc(coupl.size(),5)),
+     379           5 :                         A(gsl_matrix_alloc(coupl.size(),5)),
+     380           5 :                         V(gsl_matrix_alloc(5,5));
+     381             : 
+     382           5 :   gsl_matrix_set_zero(coef_mat.get());
+     383           5 :   gsl_vector_set_zero(bc.get());
+     384             : 
+     385             :   unsigned index=0;
+     386           5 :   std::vector<double> dmax(coupl.size());
+     387          30 :   for(unsigned r=0; r<getNumberOfAtoms(); r+=2) {
+     388          25 :     Vector  distance;
+     389          25 :     if(pbc) distance = pbcDistance(getPosition(r),getPosition(r+1));
+     390           0 :     else    distance = delta(getPosition(r),getPosition(r+1));
+     391          25 :     double d    = distance.modulo();
+     392          25 :     double d2   = d*d;
+     393          25 :     double d3   = d2*d;
+     394          25 :     double id3  = 1./d3;
+     395          25 :     double max  = -Const*mu_s*scale;
+     396          25 :     dmax[index] = id3*max;
+     397          25 :     double mu_x = distance[0]/d;
+     398          25 :     double mu_y = distance[1]/d;
+     399          25 :     double mu_z = distance[2]/d;
+     400          25 :     gsl_vector_set(rdc_vec.get(),index,coupl[index]/dmax[index]);
+     401          25 :     gsl_matrix_set(coef_mat.get(),index,0,gsl_matrix_get(coef_mat.get(),index,0)+(mu_x*mu_x-mu_z*mu_z));
+     402          25 :     gsl_matrix_set(coef_mat.get(),index,1,gsl_matrix_get(coef_mat.get(),index,1)+(mu_y*mu_y-mu_z*mu_z));
+     403          25 :     gsl_matrix_set(coef_mat.get(),index,2,gsl_matrix_get(coef_mat.get(),index,2)+(2.0*mu_x*mu_y));
+     404          25 :     gsl_matrix_set(coef_mat.get(),index,3,gsl_matrix_get(coef_mat.get(),index,3)+(2.0*mu_x*mu_z));
+     405          25 :     gsl_matrix_set(coef_mat.get(),index,4,gsl_matrix_get(coef_mat.get(),index,4)+(2.0*mu_y*mu_z));
+     406          25 :     index++;
+     407             :   }
+     408           5 :   gsl_matrix_memcpy(A.get(),coef_mat.get());
+     409           5 :   gsl_linalg_SV_decomp(A.get(), V.get(), Stmp.get(), work.get());
+     410           5 :   gsl_linalg_SV_solve(A.get(), V.get(), Stmp.get(), rdc_vec.get(), S.get());
+     411             :   /* tensor */
+     412             :   Value* tensor;
+     413           5 :   tensor=getPntrToComponent("Sxx");
+     414           5 :   double Sxx = gsl_vector_get(S.get(),0);
+     415             :   tensor->set(Sxx);
+     416           5 :   tensor=getPntrToComponent("Syy");
+     417           5 :   double Syy = gsl_vector_get(S.get(),1);
+     418             :   tensor->set(Syy);
+     419           5 :   tensor=getPntrToComponent("Szz");
+     420           5 :   double Szz = -Sxx-Syy;
+     421             :   tensor->set(Szz);
+     422           5 :   tensor=getPntrToComponent("Sxy");
+     423           5 :   double Sxy = gsl_vector_get(S.get(),2);
+     424             :   tensor->set(Sxy);
+     425           5 :   tensor=getPntrToComponent("Sxz");
+     426           5 :   double Sxz = gsl_vector_get(S.get(),3);
+     427             :   tensor->set(Sxz);
+     428           5 :   tensor=getPntrToComponent("Syz");
+     429           5 :   double Syz = gsl_vector_get(S.get(),4);
+     430             :   tensor->set(Syz);
+     431             : 
+     432           5 :   gsl_blas_dgemv(CblasNoTrans, 1.0, coef_mat.get(), S.get(), 0., bc.get());
+     433          30 :   for(index=0; index<coupl.size(); index++) {
+     434          25 :     double rdc = gsl_vector_get(bc.get(),index)*dmax[index];
+     435          25 :     Value* val=getPntrToComponent(index);
+     436             :     val->set(rdc);
+     437             :   }
+     438             : #endif
+     439           5 : }
+     440             : 
+     441        2172 : void RDC::calculate()
+     442             : {
+     443        2172 :   if(svd) {
+     444           5 :     do_svd();
+     445           5 :     return;
+     446             :   }
+     447             : 
+     448        2167 :   const double max  = -Const*scale*mu_s;
+     449             :   const unsigned N=getNumberOfAtoms();
+     450        2167 :   std::vector<Vector> dRDC(N/2, Vector{0.,0.,0.});
+     451             : 
+     452             :   /* RDC Calculations and forces */
+     453        2167 :   #pragma omp parallel num_threads(OpenMP::getNumThreads())
+     454             :   {
+     455             :     #pragma omp for
+     456             :     for(unsigned r=0; r<N; r+=2)
+     457             :     {
+     458             :       const unsigned index=r/2;
+     459             :       Vector  distance;
+     460             :       if(pbc) distance   = pbcDistance(getPosition(r),getPosition(r+1));
+     461             :       else    distance   = delta(getPosition(r),getPosition(r+1));
+     462             :       const double d2    = distance.modulo2();
+     463             :       const double ind   = 1./std::sqrt(d2);
+     464             :       const double ind2  = 1./d2;
+     465             :       const double ind3  = ind2*ind;
+     466             :       const double x2    = distance[0]*distance[0]*ind2;
+     467             :       const double y2    = distance[1]*distance[1]*ind2;
+     468             :       const double z2    = distance[2]*distance[2]*ind2;
+     469             :       const double dmax  = ind3*max;
+     470             :       const double ddmax = dmax*ind2;
+     471             : 
+     472             :       const double rdc   = 0.5*dmax*(3.*z2-1.);
+     473             :       const double prod_xy = (x2+y2-4.*z2);
+     474             :       const double prod_z =  (3.*x2 + 3.*y2 - 2.*z2);
+     475             : 
+     476             :       dRDC[index] = -1.5*ddmax*distance;
+     477             :       dRDC[index][0] *= prod_xy;
+     478             :       dRDC[index][1] *= prod_xy;
+     479             :       dRDC[index][2] *= prod_z;
+     480             : 
+     481             :       std::string num; Tools::convert(index,num);
+     482             :       Value* val=getPntrToComponent("rdc-"+num);
+     483             :       val->set(rdc);
+     484             :       if(!getDoScore()) {
+     485             :         setBoxDerivatives(val, Tensor(distance,dRDC[index]));
+     486             :         setAtomsDerivatives(val, r,  dRDC[index]);
+     487             :         setAtomsDerivatives(val, r+1, -dRDC[index]);
+     488             :       } else setCalcData(index, rdc);
+     489             :     }
+     490             :   }
+     491             : 
+     492        2167 :   if(getDoScore()) {
+     493             :     /* Metainference */
+     494        1824 :     Tensor dervir;
+     495        1824 :     double score = getScore();
+     496        1824 :     setScore(score);
+     497             : 
+     498             :     /* calculate final derivatives */
+     499        1824 :     Value* val=getPntrToComponent("score");
+     500        9120 :     for(unsigned r=0; r<N; r+=2)
+     501             :     {
+     502        7296 :       const unsigned index=r/2;
+     503        7296 :       Vector  distance;
+     504        7296 :       if(pbc) distance   = pbcDistance(getPosition(r),getPosition(r+1));
+     505           0 :       else    distance   = delta(getPosition(r),getPosition(r+1));
+     506        7296 :       const Vector der = dRDC[index]*getMetaDer(index);
+     507        7296 :       dervir += Tensor(distance, der);
+     508        7296 :       setAtomsDerivatives(val, r,  der);
+     509        7296 :       setAtomsDerivatives(val, r+1, -der);
+     510             :     }
+     511        1824 :     setBoxDerivatives(val, dervir);
+     512             :   }
+     513             : }
+     514             : 
+     515         327 : void RDC::update() {
+     516             :   // write status file
+     517         327 :   if(getWstride()>0&& (getStep()%getWstride()==0 || getCPT()) ) writeStatus();
+     518         327 : }
+     519             : 
+     520             : }
+     521             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/Rescale.cpp.func-sort-c.html b/coverage/isdb/Rescale.cpp.func-sort-c.html new file mode 100644 index 000000000000..d07499077dd1 --- /dev/null +++ b/coverage/isdb/Rescale.cpp.func-sort-c.html @@ -0,0 +1,121 @@ + + + + + + + + LCOV - plumed test coverage - isdb/Rescale.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - Rescale.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2118611.3 %
Date:2024-04-19 12:12:35Functions:1128.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb7Rescale10print_biasEx0
_ZN4PLMD4isdb7Rescale11proposeMoveEjjj0
_ZN4PLMD4isdb7Rescale12doMonteCarloEjdRKSt6vectorIdSaIdEES6_0
_ZN4PLMD4isdb7Rescale8doAcceptEdd0
_ZN4PLMD4isdb7Rescale9calculateEv0
_ZN4PLMD4isdb7Rescale9read_biasEv0
_ZN4PLMD4isdb7RescaleC1ERKNS_13ActionOptionsE0
_ZN4PLMD4isdb7RescaleC2ERKNS_13ActionOptionsE0
_ZN4PLMD4isdb7RescaleD0Ev0
_ZN4PLMD4isdb7RescaleD1Ev0
_ZN4PLMD4isdb7RescaleD2Ev0
_ZN4PLMD4isdb7Rescale16registerKeywordsERNS_8KeywordsE2
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/Rescale.cpp.func.html b/coverage/isdb/Rescale.cpp.func.html new file mode 100644 index 000000000000..fc9850ea193c --- /dev/null +++ b/coverage/isdb/Rescale.cpp.func.html @@ -0,0 +1,121 @@ + + + + + + + + LCOV - plumed test coverage - isdb/Rescale.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - Rescale.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2118611.3 %
Date:2024-04-19 12:12:35Functions:1128.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb7Rescale10print_biasEx0
_ZN4PLMD4isdb7Rescale11proposeMoveEjjj0
_ZN4PLMD4isdb7Rescale12doMonteCarloEjdRKSt6vectorIdSaIdEES6_0
_ZN4PLMD4isdb7Rescale16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD4isdb7Rescale8doAcceptEdd0
_ZN4PLMD4isdb7Rescale9calculateEv0
_ZN4PLMD4isdb7Rescale9read_biasEv0
_ZN4PLMD4isdb7RescaleC1ERKNS_13ActionOptionsE0
_ZN4PLMD4isdb7RescaleC2ERKNS_13ActionOptionsE0
_ZN4PLMD4isdb7RescaleD0Ev0
_ZN4PLMD4isdb7RescaleD1Ev0
_ZN4PLMD4isdb7RescaleD2Ev0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/Rescale.cpp.gcov.html b/coverage/isdb/Rescale.cpp.gcov.html new file mode 100644 index 000000000000..e8a52ae4a094 --- /dev/null +++ b/coverage/isdb/Rescale.cpp.gcov.html @@ -0,0 +1,590 @@ + + + + + + + + LCOV - plumed test coverage - isdb/Rescale.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - Rescale.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2118611.3 %
Date:2024-04-19 12:12:35Functions:1128.3 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2017-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : /*
+      23             : 
+      24             : */
+      25             : #include "bias/Bias.h"
+      26             : #include "core/ActionRegister.h"
+      27             : #include "core/PlumedMain.h"
+      28             : #include "core/Value.h"
+      29             : #include "tools/File.h"
+      30             : #include "tools/Random.h"
+      31             : #include "tools/Communicator.h"
+      32             : #include <ctime>
+      33             : 
+      34             : namespace PLMD {
+      35             : namespace isdb {
+      36             : 
+      37             : //+PLUMEDOC ISDB_BIAS RESCALE
+      38             : /*
+      39             : Scales the value of an another action, being a Collective Variable or a Bias.
+      40             : 
+      41             : The rescaling factor is determined by a parameter defined on a logarithmic grid of dimension NBIN in the range
+      42             : from 1 to MAX_RESCALE. The current value of the rescaling parameter is stored and shared across
+      43             : other actions using a \ref SELECTOR. A Monte Carlo procedure is used to update the value
+      44             : of the rescaling factor every MC_STRIDE steps of molecular dynamics. Well-tempered metadynamics, defined by the
+      45             : parameters W0 and BIASFACTOR, is used to enhance the sampling in the space of the rescaling factor.
+      46             : The well-tempered metadynamics bias potential is written to the file BFILE every BSTRIDE steps and read
+      47             : when restarting the simulation using the directive \ref RESTART.
+      48             : 
+      49             : \note
+      50             : Additional arguments not to be scaled, one for each bin in the rescaling parameter ladder, can be
+      51             : provided at the end of the ARG list. The number of such arguments is specified by the option NOT_RESCALED.
+      52             : These arguments will be not be scaled, but they will be
+      53             : considered as bias potentials and used in the computation of the Metropolis
+      54             : acceptance probability when proposing a move in the rescaling parameter. See example below.
+      55             : 
+      56             : \note
+      57             : If PLUMED is running in a multiple-replica framework (for example using the -multi option in GROMACS),
+      58             : the arguments will be summed across replicas, unless the NOT_SHARED option is used. Also, the value of the
+      59             : \ref SELECTOR will be shared and thus will be the same in all replicas.
+      60             : 
+      61             : \par Examples
+      62             : 
+      63             : In this example we use \ref RESCALE to implement a simulated-tempering like approach.
+      64             : The total potential energy of the system is scaled by a parameter defined on a logarithmic grid
+      65             : of 5 bins in the range from 1 to 1.5.
+      66             : A well-tempered metadynamics bias potential is used to ensure diffusion in the space of the rescaling
+      67             : parameter.
+      68             : 
+      69             : \plumedfile
+      70             : ene: ENERGY
+      71             : 
+      72             : SELECTOR NAME=GAMMA VALUE=0
+      73             : 
+      74             : RESCALE ...
+      75             : LABEL=res ARG=ene TEMP=300
+      76             : SELECTOR=GAMMA MAX_RESCALE=1.5 NBIN=5
+      77             : W0=1000 BIASFACTOR=100.0 BSTRIDE=2000 BFILE=bias.dat
+      78             : ...
+      79             : 
+      80             : PRINT FILE=COLVAR ARG=* STRIDE=100
+      81             : \endplumedfile
+      82             : 
+      83             : In this second example, we add to the simulated-tempering approach introduced above
+      84             : one Parallel Bias metadynamics simulation (see \ref PBMETAD) for each value of the rescaling parameter.
+      85             : At each moment of the simulation, only one of the \ref PBMETAD
+      86             : actions is activated, based on the current value of the associated \ref SELECTOR.
+      87             : The \ref PBMETAD bias potentials are not scaled, but just used in the calculation of
+      88             : the Metropolis acceptance probability when proposing a move in the rescaling parameter.
+      89             : 
+      90             : \plumedfile
+      91             : ene: ENERGY
+      92             : d: DISTANCE ATOMS=1,2
+      93             : 
+      94             : SELECTOR NAME=GAMMA VALUE=0
+      95             : 
+      96             : pbmetad0: PBMETAD ARG=d SELECTOR=GAMMA SELECTOR_ID=0 SIGMA=0.1 PACE=500 HEIGHT=1 BIASFACTOR=8 FILE=HILLS.0
+      97             : pbmetad1: PBMETAD ARG=d SELECTOR=GAMMA SELECTOR_ID=1 SIGMA=0.1 PACE=500 HEIGHT=1 BIASFACTOR=8 FILE=HILLS.1
+      98             : pbmetad2: PBMETAD ARG=d SELECTOR=GAMMA SELECTOR_ID=2 SIGMA=0.1 PACE=500 HEIGHT=1 BIASFACTOR=8 FILE=HILLS.2
+      99             : pbmetad3: PBMETAD ARG=d SELECTOR=GAMMA SELECTOR_ID=3 SIGMA=0.1 PACE=500 HEIGHT=1 BIASFACTOR=8 FILE=HILLS.3
+     100             : pbmetad4: PBMETAD ARG=d SELECTOR=GAMMA SELECTOR_ID=4 SIGMA=0.1 PACE=500 HEIGHT=1 BIASFACTOR=8 FILE=HILLS.4
+     101             : 
+     102             : RESCALE ...
+     103             : LABEL=res TEMP=300
+     104             : ARG=ene,pbmetad0.bias,pbmetad1.bias,pbmetad2.bias,pbmetad3.bias,pbmetad4.bias
+     105             : SELECTOR=GAMMA MAX_RESCALE=1.5 NOT_RESCALED=5 NBIN=5
+     106             : W0=1000 BIASFACTOR=100.0 BSTRIDE=2000 BFILE=bias.dat
+     107             : ...
+     108             : 
+     109             : PRINT FILE=COLVAR ARG=* STRIDE=100
+     110             : \endplumedfile
+     111             : 
+     112             : 
+     113             : 
+     114             : */
+     115             : //+ENDPLUMEDOC
+     116             : 
+     117             : class Rescale : public bias::Bias
+     118             : {
+     119             :   // gamma parameter
+     120             :   std::vector<double> gamma_;
+     121             :   double         w0_;
+     122             :   double         biasf_;
+     123             :   std::vector<double> bias_;
+     124             :   std::vector<double> expo_;
+     125             :   std::vector<unsigned> shared_;
+     126             :   unsigned nores_;
+     127             :   // bias
+     128             :   unsigned int   Biasstride_;
+     129             :   unsigned int   Biaspace_;
+     130             :   std::string         Biasfilename_;
+     131             :   bool           first_bias_;
+     132             :   OFile          Biasfile_;
+     133             :   // temperature in kbt
+     134             :   double kbt_;
+     135             :   // Monte Carlo stuff
+     136             :   unsigned MCsteps_;
+     137             :   unsigned MCstride_;
+     138             :   long long int MCfirst_;
+     139             :   long long unsigned MCaccgamma_;
+     140             :   // replica stuff
+     141             :   unsigned nrep_;
+     142             :   unsigned replica_;
+     143             :   // selector
+     144             :   std::string selector_;
+     145             : 
+     146             :   // Monte Carlo
+     147             :   void doMonteCarlo(unsigned igamma, double oldE, const std::vector<double> & args, const std::vector<double> & bargs);
+     148             :   unsigned proposeMove(unsigned x, unsigned xmin, unsigned xmax);
+     149             :   bool doAccept(double oldE, double newE);
+     150             :   // read and print bias
+     151             :   void read_bias();
+     152             :   void print_bias(long long int step);
+     153             : 
+     154             : public:
+     155             :   explicit Rescale(const ActionOptions&);
+     156             :   ~Rescale();
+     157             :   void calculate();
+     158             :   static void registerKeywords(Keywords& keys);
+     159             : };
+     160             : 
+     161             : 
+     162             : PLUMED_REGISTER_ACTION(Rescale,"RESCALE")
+     163             : 
+     164           2 : void Rescale::registerKeywords(Keywords& keys) {
+     165           2 :   Bias::registerKeywords(keys);
+     166           2 :   keys.use("ARG");
+     167           4 :   keys.add("compulsory","TEMP","temperature");
+     168           4 :   keys.add("compulsory","SELECTOR", "name of the SELECTOR used for rescaling");
+     169           4 :   keys.add("compulsory","MAX_RESCALE","maximum values for rescaling");
+     170           4 :   keys.add("compulsory","NBIN","number of bins for gamma grid");
+     171           4 :   keys.add("compulsory","W0", "initial bias height");
+     172           4 :   keys.add("compulsory","BIASFACTOR", "bias factor");
+     173           4 :   keys.add("compulsory","BSTRIDE", "stride for writing bias");
+     174           4 :   keys.add("compulsory","BFILE", "file name for bias");
+     175           4 :   keys.add("optional","NOT_SHARED",   "list of arguments (from 1 to N) not summed across replicas");
+     176           4 :   keys.add("optional","NOT_RESCALED", "these last N arguments will not be scaled");
+     177           4 :   keys.add("optional","MC_STEPS","number of MC steps");
+     178           4 :   keys.add("optional","MC_STRIDE","MC stride");
+     179           4 :   keys.add("optional","PACE", "Pace for adding bias, in MC stride unit");
+     180           2 :   componentsAreNotOptional(keys);
+     181           4 :   keys.addOutputComponent("igamma",  "default","gamma parameter");
+     182           4 :   keys.addOutputComponent("accgamma","default","MC acceptance for gamma");
+     183           4 :   keys.addOutputComponent("wtbias",  "default","well-tempered bias");
+     184           2 : }
+     185             : 
+     186           0 : Rescale::Rescale(const ActionOptions&ao):
+     187             :   PLUMED_BIAS_INIT(ao),
+     188           0 :   nores_(0), Biaspace_(1), first_bias_(true),
+     189           0 :   MCsteps_(1), MCstride_(1), MCfirst_(-1), MCaccgamma_(0)
+     190             : {
+     191             :   // set up replica stuff
+     192           0 :   if(comm.Get_rank()==0) {
+     193           0 :     nrep_    = multi_sim_comm.Get_size();
+     194           0 :     replica_ = multi_sim_comm.Get_rank();
+     195             :   } else {
+     196           0 :     nrep_    = 0;
+     197           0 :     replica_ = 0;
+     198             :   }
+     199           0 :   comm.Sum(&nrep_,1);
+     200           0 :   comm.Sum(&replica_,1);
+     201             : 
+     202             :   // wt-parameters
+     203           0 :   parse("W0", w0_);
+     204           0 :   parse("BIASFACTOR", biasf_);
+     205             : 
+     206             :   // selector name
+     207           0 :   parse("SELECTOR", selector_);
+     208             : 
+     209             :   // number of bins for gamma ladder
+     210             :   unsigned nbin;
+     211           0 :   parse("NBIN", nbin);
+     212             : 
+     213             :   // number of bias
+     214           0 :   parse("NOT_RESCALED", nores_);
+     215           0 :   if(nores_>0 && nores_!=nbin) error("The number of non scaled arguments must be equal to either 0 or the number of bins");
+     216             : 
+     217             :   // maximum value of rescale
+     218             :   std::vector<double> max_rescale;
+     219           0 :   parseVector("MAX_RESCALE", max_rescale);
+     220             :   // check dimension of max_rescale
+     221           0 :   if(max_rescale.size()!=(getNumberOfArguments()-nores_))
+     222           0 :     error("Size of MAX_RESCALE array must be equal to the number of arguments that will to be scaled");
+     223             : 
+     224             :   // calculate exponents
+     225           0 :   double igamma_max = static_cast<double>(nbin);
+     226           0 :   for(unsigned i=0; i<max_rescale.size(); ++i)
+     227           0 :     expo_.push_back(std::log(max_rescale[i])/std::log(igamma_max));
+     228             : 
+     229             :   // allocate gamma grid and set bias to zero
+     230           0 :   for(unsigned i=0; i<nbin; ++i) {
+     231             :     // bias grid
+     232           0 :     bias_.push_back(0.0);
+     233             :     // gamma ladder
+     234           0 :     double gamma = std::exp( static_cast<double>(i) / static_cast<double>(nbin-1) * std::log(igamma_max) );
+     235           0 :     gamma_.push_back(gamma);
+     236             :   }
+     237             :   // print bias to file
+     238           0 :   parse("BSTRIDE", Biasstride_);
+     239           0 :   parse("BFILE",   Biasfilename_);
+     240             : 
+     241             :   // create vectors of shared arguments
+     242             :   // by default they are all shared
+     243           0 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) shared_.push_back(1);
+     244             :   // share across replicas or not
+     245             :   std::vector<unsigned> not_shared;
+     246           0 :   parseVector("NOT_SHARED", not_shared);
+     247             :   // and change the non-shared
+     248           0 :   for(unsigned i=0; i<not_shared.size(); ++i) {
+     249           0 :     if((not_shared[i]-1)>=(getNumberOfArguments()-nores_) && nrep_>1)
+     250           0 :       error("NOT_RESCALED args must always be shared when using multiple replicas");
+     251           0 :     if((not_shared[i]-1)>=getNumberOfArguments())
+     252           0 :       error("NOT_SHARED args should be lower than total number of arguments");
+     253           0 :     shared_[not_shared[i]-1] = 0;
+     254             :   }
+     255             : 
+     256             :   // monte carlo stuff
+     257           0 :   parse("MC_STEPS",MCsteps_);
+     258           0 :   parse("MC_STRIDE",MCstride_);
+     259             :   // adjust for multiple-time steps
+     260           0 :   MCstride_ *= getStride();
+     261             :   // read bias deposition pace
+     262           0 :   parse("PACE", Biaspace_);
+     263             :   // multiply by MCstride
+     264           0 :   Biaspace_ *= MCstride_;
+     265             : 
+     266             :   // get temperature
+     267           0 :   kbt_=getkBT();
+     268             : 
+     269           0 :   checkRead();
+     270             : 
+     271           0 :   log.printf("  temperature of the system in energy unit %f\n",kbt_);
+     272           0 :   log.printf("  name of the SELECTOR use for this action %s\n",selector_.c_str());
+     273           0 :   log.printf("  number of bins in grid %u\n",nbin);
+     274           0 :   log.printf("  number of arguments that will not be scaled %u\n",nores_);
+     275           0 :   if(nrep_>1) log<<"  number of arguments that will not be summed across replicas "<<not_shared.size()<<"\n";
+     276           0 :   log.printf("  biasfactor %f\n",biasf_);
+     277           0 :   log.printf("  initial hills height %f\n",w0_);
+     278           0 :   log.printf("  stride to write bias to file %u\n",Biasstride_);
+     279           0 :   log.printf("  write bias to file : %s\n",Biasfilename_.c_str());
+     280           0 :   log.printf("  number of replicas %u\n",nrep_);
+     281           0 :   log.printf("  number of MC steps %d\n",MCsteps_);
+     282           0 :   log.printf("  do MC every %d steps\n", MCstride_);
+     283           0 :   log.printf("\n");
+     284             : 
+     285           0 :   log << " Bibliography" << plumed.cite("Bonomi, Camilloni, Bioinformatics, 33, 3999 (2017)") << "\n";
+     286             : 
+     287             : 
+     288             :   // add components
+     289           0 :   addComponent("igamma");   componentIsNotPeriodic("igamma");
+     290           0 :   addComponent("accgamma"); componentIsNotPeriodic("accgamma");
+     291           0 :   addComponent("wtbias");   componentIsNotPeriodic("wtbias");
+     292             : 
+     293             :   // initialize random seed
+     294           0 :   srand (time(NULL));
+     295             : 
+     296             :   // read bias if restarting
+     297           0 :   if(getRestart()) read_bias();
+     298           0 : }
+     299             : 
+     300           0 : Rescale::~Rescale()
+     301             : {
+     302           0 :   Biasfile_.close();
+     303           0 : }
+     304             : 
+     305           0 : void Rescale::read_bias()
+     306             : {
+     307             : // open file
+     308             :   auto ifile=Tools::make_unique<IFile>();
+     309           0 :   ifile->link(*this);
+     310           0 :   if(ifile->FileExist(Biasfilename_)) {
+     311           0 :     ifile->open(Biasfilename_);
+     312             :     // read all the lines, store last value of bias
+     313             :     double MDtime;
+     314           0 :     while(ifile->scanField("MD_time",MDtime)) {
+     315           0 :       for(unsigned i=0; i<bias_.size(); ++i) {
+     316             :         // convert i to string
+     317           0 :         std::stringstream ss;
+     318             :         ss << i;
+     319             :         // label
+     320           0 :         std::string label = "b" + ss.str();
+     321             :         // read entry
+     322           0 :         ifile->scanField(label, bias_[i]);
+     323           0 :       }
+     324             :       // new line
+     325           0 :       ifile->scanField();
+     326             :     }
+     327           0 :     ifile->close();
+     328             :   } else {
+     329           0 :     error("Cannot find bias file "+Biasfilename_+"\n");
+     330             :   }
+     331           0 : }
+     332             : 
+     333           0 : unsigned Rescale::proposeMove(unsigned x, unsigned xmin, unsigned xmax)
+     334             : {
+     335           0 :   int xmin_i = static_cast<int>(xmin);
+     336           0 :   int xmax_i = static_cast<int>(xmax);
+     337             :   int dx;
+     338           0 :   int r = rand() % 2;
+     339           0 :   if( r % 2 == 0 ) dx = +1;
+     340             :   else             dx = -1;
+     341             : // new index, integer
+     342           0 :   int x_new = static_cast<int>(x) + dx;
+     343             : // check boundaries
+     344           0 :   if(x_new >= xmax_i) x_new = xmax_i-1;
+     345             :   if(x_new <  xmin_i) x_new = xmin_i;
+     346           0 :   return static_cast<unsigned>(x_new);
+     347             : }
+     348             : 
+     349           0 : bool Rescale::doAccept(double oldE, double newE)
+     350             : {
+     351             :   bool accept = false;
+     352             :   // calculate delta energy
+     353           0 :   double delta = ( newE - oldE ) / kbt_;
+     354             :   // if delta is negative always accept move
+     355           0 :   if( delta < 0.0 ) {
+     356             :     accept = true;
+     357             :   } else {
+     358             :     // otherwise extract random number
+     359           0 :     double s = static_cast<double>(rand()) / RAND_MAX;
+     360           0 :     if( s < std::exp(-delta) ) { accept = true; }
+     361             :   }
+     362           0 :   return accept;
+     363             : }
+     364             : 
+     365           0 : void Rescale::doMonteCarlo(unsigned igamma, double oldE,
+     366             :                            const std::vector<double> & args, const std::vector<double> & bargs)
+     367             : {
+     368             :   double oldB, newB;
+     369             : 
+     370             : // cycle on MC steps
+     371           0 :   for(unsigned i=0; i<MCsteps_; ++i) {
+     372             :     // propose move in igamma
+     373           0 :     unsigned new_igamma = proposeMove(igamma, 0, gamma_.size());
+     374             :     // calculate new energy
+     375             :     double newE = 0.0;
+     376           0 :     for(unsigned j=0; j<args.size(); ++j) {
+     377             :       // calculate energy term
+     378           0 :       double fact = 1.0/pow(gamma_[new_igamma], expo_[j]) - 1.0;
+     379           0 :       newE += args[j] * fact;
+     380             :     }
+     381             :     // calculate contributions from non-rescaled terms
+     382           0 :     if(bargs.size()>0) {
+     383           0 :       oldB = bias_[igamma]+bargs[igamma];
+     384           0 :       newB = bias_[new_igamma]+bargs[new_igamma];
+     385             :     } else {
+     386           0 :       oldB = bias_[igamma];
+     387           0 :       newB = bias_[new_igamma];
+     388             :     }
+     389             :     // accept or reject
+     390           0 :     bool accept = doAccept(oldE+oldB, newE+newB);
+     391           0 :     if(accept) {
+     392           0 :       igamma = new_igamma;
+     393             :       oldE = newE;
+     394           0 :       MCaccgamma_++;
+     395             :     }
+     396             :   }
+     397             : // send values of gamma to all replicas
+     398           0 :   if(comm.Get_rank()==0) {
+     399           0 :     if(multi_sim_comm.Get_rank()!=0) igamma = 0;
+     400           0 :     multi_sim_comm.Sum(&igamma, 1);
+     401             :   } else {
+     402           0 :     igamma = 0;
+     403             :   }
+     404             : // local communication
+     405           0 :   comm.Sum(&igamma, 1);
+     406             : 
+     407             : // set the value of gamma into passMap
+     408           0 :   plumed.passMap[selector_]=static_cast<double>(igamma);
+     409           0 : }
+     410             : 
+     411           0 : void Rescale::print_bias(long long int step)
+     412             : {
+     413             : // if first time open the file
+     414           0 :   if(first_bias_) {
+     415           0 :     first_bias_ = false;
+     416           0 :     Biasfile_.link(*this);
+     417           0 :     Biasfile_.open(Biasfilename_);
+     418             :     Biasfile_.setHeavyFlush();
+     419           0 :     Biasfile_.fmtField("%30.5f");
+     420             :   }
+     421             : 
+     422             : // write fields
+     423           0 :   double MDtime = static_cast<double>(step)*getTimeStep();
+     424           0 :   Biasfile_.printField("MD_time", MDtime);
+     425           0 :   for(unsigned i=0; i<bias_.size(); ++i) {
+     426             :     // convert i to string
+     427           0 :     std::stringstream ss;
+     428             :     ss << i;
+     429             :     // label
+     430           0 :     std::string label = "b" + ss.str();
+     431             :     // print entry
+     432           0 :     Biasfile_.printField(label, bias_[i]);
+     433           0 :   }
+     434           0 :   Biasfile_.printField();
+     435           0 : }
+     436             : 
+     437           0 : void Rescale::calculate()
+     438             : {
+     439             :   // get the current value of the selector
+     440           0 :   unsigned igamma = static_cast<unsigned>(plumed.passMap[selector_]);
+     441             : 
+     442             :   // collect data from other replicas
+     443           0 :   std::vector<double> all_args(getNumberOfArguments(), 0.0);
+     444             :   // first calculate arguments
+     445           0 :   for(unsigned i=0; i<all_args.size(); ++i) {
+     446           0 :     double arg = getArgument(i);
+     447             :     // sum shared arguments across replicas
+     448           0 :     if(shared_[i]==1) {
+     449           0 :       if(comm.Get_rank()==0) multi_sim_comm.Sum(arg);
+     450           0 :       else                   arg = 0.0;
+     451           0 :       if(comm.Get_size()>1)  comm.Sum(arg);
+     452             :     }
+     453             :     // put into all_args
+     454           0 :     all_args[i] = arg;
+     455             :   }
+     456             : 
+     457             :   // now separate terms that should be rescaled
+     458             :   std::vector<double> args;
+     459           0 :   if(getNumberOfArguments()-nores_>0) args.resize(getNumberOfArguments()-nores_);
+     460           0 :   for(unsigned i=0; i<args.size(); ++i)  args[i]  = all_args[i];
+     461             :   // and terms that should not
+     462             :   std::vector<double> bargs;
+     463           0 :   if(nores_>0) bargs.resize(nores_);
+     464           0 :   for(unsigned i=0; i<bargs.size(); ++i) bargs[i] = all_args[i+args.size()];
+     465             : 
+     466             :   // calculate energy and forces, only on rescaled terms
+     467             :   double ene = 0.0;
+     468           0 :   for(unsigned i=0; i<args.size(); ++i) {
+     469             :     // calculate energy term
+     470           0 :     double fact = 1.0/pow(gamma_[igamma], expo_[i]) - 1.0;
+     471           0 :     ene += args[i] * fact;
+     472             :     // add force
+     473           0 :     setOutputForce(i, -fact);
+     474             :   }
+     475             : 
+     476             :   // set to zero on the others
+     477           0 :   for(unsigned i=0; i<bargs.size(); ++i) setOutputForce(i+args.size(), 0.0);
+     478             : 
+     479             :   // set value of the bias
+     480           0 :   setBias(ene);
+     481             :   // set value of the wt-bias
+     482           0 :   getPntrToComponent("wtbias")->set(bias_[igamma]);
+     483             :   // set values of gamma
+     484           0 :   getPntrToComponent("igamma")->set(igamma);
+     485             :   // get time step
+     486           0 :   long long int step = getStep();
+     487           0 :   if(MCfirst_==-1) MCfirst_=step;
+     488             :   // calculate gamma acceptance
+     489           0 :   double MCtrials = std::floor(static_cast<double>(step-MCfirst_) / static_cast<double>(MCstride_))+1.0;
+     490           0 :   double accgamma = static_cast<double>(MCaccgamma_) / static_cast<double>(MCsteps_) / MCtrials;
+     491           0 :   getPntrToComponent("accgamma")->set(accgamma);
+     492             : 
+     493             :   // do MC at the right time step
+     494           0 :   if(step%MCstride_==0&&!getExchangeStep()) doMonteCarlo(igamma, ene, args, bargs);
+     495             : 
+     496             :   // add well-tempered like bias
+     497           0 :   if(step%Biaspace_==0) {
+     498             :     // get updated igamma
+     499           0 :     unsigned igamma = static_cast<unsigned>(plumed.passMap[selector_]);
+     500             :     // add "Gaussian"
+     501           0 :     double kbDT = kbt_ * ( biasf_ - 1.0 );
+     502           0 :     bias_[igamma] += w0_ * std::exp(-bias_[igamma] / kbDT);
+     503             :   }
+     504             : 
+     505             :   // print bias
+     506           0 :   if(step%Biasstride_==0) print_bias(step);
+     507             : 
+     508           0 : }
+     509             : 
+     510             : 
+     511             : }
+     512             : }
+     513             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/SAXS.cpp.func-sort-c.html b/coverage/isdb/SAXS.cpp.func-sort-c.html new file mode 100644 index 000000000000..43ba77f15803 --- /dev/null +++ b/coverage/isdb/SAXS.cpp.func-sort-c.html @@ -0,0 +1,165 @@ + + + + + + + + LCOV - plumed test coverage - isdb/SAXS.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - SAXS.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4919615479.9 %
Date:2024-04-19 12:12:35Functions:212391.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb4SAXS13calculate_gpuERSt6vectorINS_13VectorGenericILj3EEESaIS4_EES7_0
_ZN4PLMD4isdb4SAXSC2ERKNS_13ActionOptionsE0
_ZN4PLMD4isdb4SAXS16calculateAFFsansERKSt6vectorINS_10AtomNumberESaIS3_EERS2_IS2_IeSaIeEESaIS9_EEd2
_ZN4PLMD4isdb4SAXS12calculateAFFERKSt6vectorINS_10AtomNumberESaIS3_EERS2_IS2_IeSaIeEESaIS9_EEd4
_ZN4PLMD4isdb4SAXS19resolution_functionEv4
_ZN4PLMD4isdb4SAXS21getOnebeadparam_sansDERKNS_3PDBERKSt6vectorINS_10AtomNumberESaIS6_EERS5_IS5_IeSaIeEESaISC_EESF_4
_ZN4PLMD4isdb4SAXS21getOnebeadparam_sansHERKNS_3PDBERKSt6vectorINS_10AtomNumberESaIS6_EERS5_IS5_IeSaIeEESaISC_EESF_SF_4
_ZN4PLMD4isdb4SAXS15getOnebeadparamERKNS_3PDBERKSt6vectorINS_10AtomNumberESaIS6_EERS5_IS5_IeSaIeEESaISC_EESF_SF_RKS5_IjSaIjEE6
_ZN4PLMD4isdb4SAXS14sasa_calculateERSt6vectorIbSaIbEE8
_ZN4PLMD4isdb4SAXS17getMartiniFFparamERKSt6vectorINS_10AtomNumberESaIS3_EERS2_IS2_IeSaIeEESaIS9_EE8
_ZN4PLMD4isdb4SAXS9calcNlistERSt6vectorIS2_IiSaIiEESaIS4_EE8
_ZN4PLMD4isdb4SAXS13readLCPOparamERKSt6vectorIS2_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EESaISA_EEj10
_ZN4PLMD4isdb4SAXS14setupLCPOparamB5cxx11Ev10
_ZN4PLMD4isdb4SAXS17getOnebeadMappingERKNS_3PDBERKSt6vectorINS_10AtomNumberESaIS6_EE10
_ZN4PLMD4isdb4SAXSC1ERKNS_13ActionOptionsE32
_ZN4PLMD4isdb4SAXS16registerKeywordsERNS_8KeywordsE36
_ZN4PLMD4isdb4SAXS13calculate_cpuERSt6vectorINS_13VectorGenericILj3EEESaIS4_EES7_192
_ZN4PLMD4isdb4SAXS6updateEv192
_ZN4PLMD4isdb4SAXS9calculateEv192
_ZN4PLMD4isdb4SAXS3i0eEd660
_ZN4PLMD4isdb4SAXS6chbevlEdRKSt6vectorIdSaIdEE660
_ZN4PLMD4isdb4SAXS13spline_coeffsERSt6vectorIdSaIdEES5_814
_ZN4PLMD4isdb4SAXS13interpolationERSt6vectorINS1_12SplineCoeffsESaIS3_EEd134310
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/SAXS.cpp.func.html b/coverage/isdb/SAXS.cpp.func.html new file mode 100644 index 000000000000..f13a79c95aee --- /dev/null +++ b/coverage/isdb/SAXS.cpp.func.html @@ -0,0 +1,165 @@ + + + + + + + + LCOV - plumed test coverage - isdb/SAXS.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - SAXS.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4919615479.9 %
Date:2024-04-19 12:12:35Functions:212391.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb4SAXS12calculateAFFERKSt6vectorINS_10AtomNumberESaIS3_EERS2_IS2_IeSaIeEESaIS9_EEd4
_ZN4PLMD4isdb4SAXS13calculate_cpuERSt6vectorINS_13VectorGenericILj3EEESaIS4_EES7_192
_ZN4PLMD4isdb4SAXS13calculate_gpuERSt6vectorINS_13VectorGenericILj3EEESaIS4_EES7_0
_ZN4PLMD4isdb4SAXS13interpolationERSt6vectorINS1_12SplineCoeffsESaIS3_EEd134310
_ZN4PLMD4isdb4SAXS13readLCPOparamERKSt6vectorIS2_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EESaISA_EEj10
_ZN4PLMD4isdb4SAXS13spline_coeffsERSt6vectorIdSaIdEES5_814
_ZN4PLMD4isdb4SAXS14sasa_calculateERSt6vectorIbSaIbEE8
_ZN4PLMD4isdb4SAXS14setupLCPOparamB5cxx11Ev10
_ZN4PLMD4isdb4SAXS15getOnebeadparamERKNS_3PDBERKSt6vectorINS_10AtomNumberESaIS6_EERS5_IS5_IeSaIeEESaISC_EESF_SF_RKS5_IjSaIjEE6
_ZN4PLMD4isdb4SAXS16calculateAFFsansERKSt6vectorINS_10AtomNumberESaIS3_EERS2_IS2_IeSaIeEESaIS9_EEd2
_ZN4PLMD4isdb4SAXS16registerKeywordsERNS_8KeywordsE36
_ZN4PLMD4isdb4SAXS17getMartiniFFparamERKSt6vectorINS_10AtomNumberESaIS3_EERS2_IS2_IeSaIeEESaIS9_EE8
_ZN4PLMD4isdb4SAXS17getOnebeadMappingERKNS_3PDBERKSt6vectorINS_10AtomNumberESaIS6_EE10
_ZN4PLMD4isdb4SAXS19resolution_functionEv4
_ZN4PLMD4isdb4SAXS21getOnebeadparam_sansDERKNS_3PDBERKSt6vectorINS_10AtomNumberESaIS6_EERS5_IS5_IeSaIeEESaISC_EESF_4
_ZN4PLMD4isdb4SAXS21getOnebeadparam_sansHERKNS_3PDBERKSt6vectorINS_10AtomNumberESaIS6_EERS5_IS5_IeSaIeEESaISC_EESF_SF_4
_ZN4PLMD4isdb4SAXS3i0eEd660
_ZN4PLMD4isdb4SAXS6chbevlEdRKSt6vectorIdSaIdEE660
_ZN4PLMD4isdb4SAXS6updateEv192
_ZN4PLMD4isdb4SAXS9calcNlistERSt6vectorIS2_IiSaIiEESaIS4_EE8
_ZN4PLMD4isdb4SAXS9calculateEv192
_ZN4PLMD4isdb4SAXSC1ERKNS_13ActionOptionsE32
_ZN4PLMD4isdb4SAXSC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/SAXS.cpp.gcov.html b/coverage/isdb/SAXS.cpp.gcov.html new file mode 100644 index 000000000000..f23c73aad1d6 --- /dev/null +++ b/coverage/isdb/SAXS.cpp.gcov.html @@ -0,0 +1,7939 @@ + + + + + + + + LCOV - plumed test coverage - isdb/SAXS.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - SAXS.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4919615479.9 %
Date:2024-04-19 12:12:35Functions:212391.3 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2017-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : /*
+      23             :  This class was originally written by Alexander Jussupow
+      24             :  Arrayfire implementation by Alexander Jussupow and CC
+      25             :  Extension for the middleman algorithm (now removed) by Max Muehlbauer
+      26             :  Refactoring for hySAXS Martini form factors for Nucleic Acids by Cristina Paissoni
+      27             :  Refactoring for hySAS OneBead form factors with solvent correction by Federico Ballabio and Riccardo Capelli
+      28             :  Resolution function by Henrique Musseli Cezar
+      29             : */
+      30             : 
+      31             : #include "MetainferenceBase.h"
+      32             : #include "core/ActionRegister.h"
+      33             : #include "core/ActionSet.h"
+      34             : #include "core/GenericMolInfo.h"
+      35             : #include "tools/MolDataClass.h"
+      36             : #include "tools/Communicator.h"
+      37             : #include "tools/Pbc.h"
+      38             : #include "tools/PDB.h"
+      39             : #include "tools/Tools.h"
+      40             : #include "tools/IFile.h"
+      41             : 
+      42             : #include <map>
+      43             : #include <iterator>
+      44             : #include <iostream>
+      45             : #include <algorithm>
+      46             : #include <cctype>
+      47             : 
+      48             : #ifdef __PLUMED_HAS_ARRAYFIRE
+      49             : #include <arrayfire.h>
+      50             : #include <af/util.h>
+      51             : #ifdef __PLUMED_HAS_ARRAYFIRE_CUDA
+      52             : #include <cuda_runtime.h>
+      53             : #include <cublas_v2.h>
+      54             : #include <af/cuda.h>
+      55             : #elif __PLUMED_HAS_ARRAYFIRE_OCL
+      56             : #include <af/opencl.h>
+      57             : #endif
+      58             : #endif
+      59             : 
+      60             : #ifndef M_PI
+      61             : #define M_PI           3.14159265358979323846
+      62             : #endif
+      63             : 
+      64             : namespace PLMD {
+      65             : namespace isdb {
+      66             : 
+      67             : //+PLUMEDOC ISDB_COLVAR SAXS
+      68             : /*
+      69             : Calculates SAXS intensity.
+      70             : 
+      71             : SAXS intensities are calculated for a set of scattering vectors using QVALUE keywords numbered from 1.
+      72             : Form factors can be assigned either by polynomial expansion of any order by using the PARAMETERS keywords, or
+      73             : automatically matched to atoms using the ATOMISTIC flag by reading a PDB file. Alternatively to the atomistic
+      74             : representation, two types of coarse-grained mapping are available:
+      75             : - MARTINI.
+      76             : - ONEBEAD.
+      77             : 
+      78             : Whether for PARAMETERS, ATOMISTIC, and ONEBEAD the user must provide an all-atom PDB file via MOLINFO before the
+      79             : SAXS instruction. MARTINI requires a mapping scheme consisting of a PDB file that contains both the all-atom
+      80             : and MARTINI representations, and a bead position file (e.g., bead1: CENTER ATOMS=1,5,7,11,12 WEIGHTS=14,12,12,
+      81             : 12,16).
+      82             : 
+      83             : ONEBEAD scheme consists in a single-bead per amino acid residue or three-bead for nucleic acid residue (one for
+      84             : the phosphate group, one for the pentose sugar, one for the nucleobase). PLUMED creates a virtual bead on which
+      85             : the SAXS calculations are performed, centred on the COM of all atoms belonging to the bead. It is possible to
+      86             : account for the contribution of the solvation layer to the SAXS intensity by adding a correction term for the
+      87             : solvent accessible beads only: the form factors of the amino acids / phosphate groups / pentose sugars /
+      88             : nucleobases with a SASA (computed via LCPO algorithm) greater than a threshold are corrected according to an
+      89             : electron density term. Both the surface cut-off threshold and the electron density term can be set by the user
+      90             : with the SASA_CUTOFF and SOLVATION_CORRECTION keywords. Moreover, SASA stride calculation can be modified using
+      91             : SOLVATION_STRIDE, which is set to 10 steps by default.
+      92             : ONEBEAD requires an additional PDB file to perform mapping conversion, which must be provided via TEMPLATE
+      93             : keyword. This PDB file should only include the atoms for which the SAXS intensity will be computed.
+      94             : The AMBER OL3 (RNA) and OL15 (DNA) naming is required for nucleic acids.
+      95             : Two additional bead types are available for DNA and RNA besides phosphate group, pentose sugar, and nucleobase:
+      96             : - 5'-end pentose sugar capped with an hydroxyl moiety at C5' (the residue name in the PDB must be followed by
+      97             : "5", e.g., DC5 or C5 for cytosine in DNA and RNA, respectively);
+      98             : - 3'-end pentose sugar capped with an hydroxyl moiety at C3' (the residue name in the PDB must be followed by
+      99             : "3", e.g., DC3 or C3 for cytosine in DNA and RNA, respectively).
+     100             : 
+     101             : Experimental reference intensities can be added using the EXPINT keywords. All these values must be normalised
+     102             : to the SAXS intensity at q = 0. To facilitate this operation, the SCALE_EXPINT keyword can be used to provide
+     103             : the intensity at q = 0. Each EXPINT is divided by SCALE_EXPINT.
+     104             : The maximum QVALUE for ONEBEAD is set to 0.3 inverse angstroms.
+     105             : The solvent density, that by default is set to 0.334 electrons per cubic angstrom (bulk water), can be modified
+     106             : using the SOLVDENS keyword.
+     107             : 
+     108             : The ABSOLUTE flag can be used in order to calculate intensities in the absolute scale. It is only available for
+     109             : the ATOMISTIC scheme and cannot be used with SCALE_EXPINT.
+     110             : 
+     111             : By default SAXS is calculated using Debye on CPU, by adding the GPU flag it is possible to solve the equation on
+     112             : a GPU if the ARRAYFIRE libraries are installed and correctly linked.
+     113             : \ref METAINFERENCE can be activated using DOSCORE and the other relevant keywords.
+     114             : 
+     115             : \par Examples
+     116             : in the following example the SAXS intensities are calculated using single-bead per residue approximation, with a
+     117             : SASA threshold of 1 square nanometer and a solvation term of 0.04. Each experimental intensity is divided by
+     118             : 1.4002, which is the corresponding theoretical intensity value at q = 0. The form factors are selected according
+     119             : to the PDB file specified by TEMPLATE keyword.
+     120             : 
+     121             : \plumedfile
+     122             : MOLINFO STRUCTURE=template_AA.pdb
+     123             : 
+     124             : SAXS ...
+     125             : LABEL=SAXS
+     126             : ATOMS=1-355
+     127             : ONEBEAD
+     128             : TEMPLATE=template_AA.pdb
+     129             : SOLVDENS=0.334
+     130             : SOLVATION_CORRECTION=0.04
+     131             : SOLVATION_STRIDE=1
+     132             : SASA_CUTOFF=1.0
+     133             : SCALE_EXPINT=1.4002
+     134             : QVALUE1=0.03 EXPINT1=1.0902
+     135             : QVALUE2=0.06 EXPINT2=0.790632
+     136             : QVALUE3=0.09 EXPINT3=0.453808
+     137             : QVALUE4=0.12 EXPINT4=0.254737
+     138             : QVALUE5=0.15 EXPINT5=0.154928
+     139             : QVALUE6=0.18 EXPINT6=0.0921503
+     140             : QVALUE7=0.21 EXPINT7=0.052633
+     141             : QVALUE8=0.24 EXPINT8=0.0276557
+     142             : QVALUE9=0.27 EXPINT9=0.0122775
+     143             : QVALUE10=0.30 EXPINT10=0.00880634
+     144             : ... SAXS
+     145             : 
+     146             : PRINT ARG=(SAXS\.q-.*),(SAXS\.exp-.*) FILE=saxsdata STRIDE=1
+     147             : 
+     148             : \endplumedfile
+     149             : 
+     150             : */
+     151             : //+ENDPLUMEDOC
+     152             : 
+     153             : //+PLUMEDOC ISDB_COLVAR SANS
+     154             : /*
+     155             : Calculates SANS intensity.
+     156             : 
+     157             : SANS intensities are calculated for a set of scattering vectors using QVALUE keywords numbered from 1.
+     158             : Form factors are automatically assigned to atoms using the ATOMISTIC flag by reading a PDB file, by reading
+     159             : the scattering lengths with the PARAMETERS keyword from input or with the PARAMETERSFILE keyword or, alternatively,
+     160             : a ONEBEAD coarse-grained implementation is available.
+     161             : 
+     162             : Both for ATOMISTIC and ONEBEAD the user must provide an all-atom PDB file via MOLINFO before the SANS instruction.
+     163             : 
+     164             : ONEBEAD scheme consists in a single-bead per amino acid residue or three-bead for nucleic acid residue (one for
+     165             : the phosphate group, one for the pentose sugar, one for the nucleobase). PLUMED creates a virtual bead on which
+     166             : the SANS calculations are performed, centred on the COM of all atoms belonging to the bead. It is possible to
+     167             : account for the contribution of the solvation layer to the SAXS intensity by adding a correction term for the
+     168             : solvent accessible beads only: the form factors of the amino acids / phosphate groups / pentose sugars /
+     169             : nucleobases with a SASA (computed via LCPO algorithm) greater than a threshold are corrected according to an
+     170             : electron density term. Both the surface cut-off threshold and the electron density term can be set by the user
+     171             : with the SASA_CUTOFF and SOLVATION_CORRECTION keywords. Moreover, SASA stride calculation can be modified using
+     172             : SOLVATION_STRIDE, which is set to 10 steps by default. The deuteration of the solvent-exposed residues is chosen
+     173             : with a probability equal to the deuterium concentration in the buffer. The deuterated residues are updated with a
+     174             : stride equal to SOLVATION_STRIDE. The fraction of deuterated water can be set with DEUTER_CONC, the default value
+     175             : is 0.
+     176             : ONEBEAD requires an additional PDB file to perform mapping conversion, which must be provided via TEMPLATE
+     177             : keyword. This PDB file should only include the atoms for which the SANS intensity will be computed.
+     178             : The AMBER OL3 (RNA) and OL15 (DNA) naming is required for nucleic acids.
+     179             : Two additional bead types are available for DNA and RNA besides phosphate group, pentose sugar, and nucleobase:
+     180             : - 5'-end pentose sugar capped with an hydroxyl moiety at C5' (the residue name in the PDB must be followed by "5",
+     181             : e.g., DC5 or C5 for cytosine in DNA and RNA, respectively);
+     182             : - 3'-end pentose sugar capped with an hydroxyl moiety at C3' (the residue name in the PDB must be followed by "3",
+     183             : e.g., DC3 or C3 for cytosine in DNA and RNA, respectively).
+     184             : 
+     185             : PLEASE NOTE: at the moment, we DO NOT explicitly take into account deuterated residues in the ATOMISTIC
+     186             : representation, but we correct the solvent contribution via the DEUTER_CONC keyword.
+     187             : 
+     188             : Experimental reference intensities can be added using the EXPINT keywords. All these values must be normalised
+     189             : to the SANS intensity at q = 0. To facilitate this operation, the SCALE_EXPINT keyword can be used to provide
+     190             : the intensity at q = 0. Each EXPINT is divided by SCALE_EXPINT.
+     191             : The maximum QVALUE for ONEBEAD is set to 0.3 inverse angstroms.
+     192             : The solvent density, that by default is set to 0.334 electrons per cubic angstrom (bulk water), can be modified
+     193             : using the SOLVDENS keyword.
+     194             : 
+     195             : The ABSOLUTE flag can be used in order to calculate intensities in the absolute scale. It is only available for
+     196             : the ATOMISTIC scheme and cannot be used with SCALE_EXPINT.
+     197             : 
+     198             : By default SANS is calculated using Debye on CPU, by adding the GPU flag it is possible to solve the equation on a
+     199             : GPU if the ARRAYFIRE libraries are installed and correctly linked.
+     200             : \ref METAINFERENCE can be activated using DOSCORE and the other relevant keywords.
+     201             : 
+     202             : \par Examples
+     203             : in the following example the SANS intensities are calculated at atomistic resolution. The form factors are assigned
+     204             : according to the PDB file specified in the MOLINFO. Each experimental intensity is divided by 1.4002, which is the
+     205             : corresponding theoretical intensity value at q = 0. The deuterated water fraction is set to 48%.
+     206             : 
+     207             : \plumedfile
+     208             : MOLINFO STRUCTURE=template_AA.pdb
+     209             : 
+     210             : SANS ...
+     211             : LABEL=SANS
+     212             : ATOMS=1-355
+     213             : ATOMISTIC
+     214             : SCALE_EXPINT=1.4002
+     215             : DEUTER_CONC=0.48
+     216             : QVALUE1=0.03 EXPINT1=1.0902
+     217             : QVALUE2=0.06 EXPINT2=0.790632
+     218             : QVALUE3=0.09 EXPINT3=0.453808
+     219             : QVALUE4=0.12 EXPINT4=0.254737
+     220             : QVALUE5=0.15 EXPINT5=0.154928
+     221             : QVALUE6=0.18 EXPINT6=0.0921503
+     222             : QVALUE7=0.21 EXPINT7=0.052633
+     223             : QVALUE8=0.24 EXPINT8=0.0276557
+     224             : QVALUE9=0.27 EXPINT9=0.0122775
+     225             : QVALUE10=0.30 EXPINT10=0.00880634
+     226             : ... SANS
+     227             : 
+     228             : PRINT ARG=(SANS\.q-.*),(SANS\.exp-.*) FILE=sansdata STRIDE=1
+     229             : 
+     230             : \endplumedfile
+     231             : 
+     232             : */
+     233             : //+ENDPLUMEDOC
+     234             : 
+     235             : class SAXS :
+     236             :   public MetainferenceBase
+     237             : {
+     238             : private:
+     239             :   enum { H, C, N, O, P, S, NTT };
+     240             :   enum { ALA_BB, ARG_BB, ARG_SC1, ARG_SC2, ASN_BB, ASN_SC1, ASP_BB, ASP_SC1, CYS_BB, CYS_SC1,
+     241             :          GLN_BB, GLN_SC1, GLU_BB, GLU_SC1, GLY_BB, HIS_BB, HIS_SC1, HIS_SC2, HIS_SC3, ILE_BB,
+     242             :          ILE_SC1, LEU_BB, LEU_SC1, LYS_BB, LYS_SC1, LYS_SC2, MET_BB, MET_SC1, PHE_BB, PHE_SC1,
+     243             :          PHE_SC2, PHE_SC3, PRO_BB, PRO_SC1, SER_BB, SER_SC1, THR_BB, THR_SC1, TRP_BB, TRP_SC1,
+     244             :          TRP_SC2, TRP_SC3, TRP_SC4, TYR_BB, TYR_SC1, TYR_SC2, TYR_SC3, VAL_BB, VAL_SC1, A_BB1,
+     245             :          A_BB2, A_BB3, A_SC1, A_SC2, A_SC3, A_SC4, A_3TE, A_5TE, A_TE3, A_TE5, C_BB1, C_BB2,
+     246             :          C_BB3, C_SC1, C_SC2, C_SC3, C_3TE, C_5TE, C_TE3, C_TE5, G_BB1, G_BB2, G_BB3, G_SC1,
+     247             :          G_SC2, G_SC3, G_SC4, G_3TE, G_5TE, G_TE3, G_TE5, U_BB1, U_BB2, U_BB3, U_SC1, U_SC2,
+     248             :          U_SC3, U_3TE, U_5TE, U_TE3, U_TE5, DA_BB1, DA_BB2, DA_BB3, DA_SC1, DA_SC2, DA_SC3,
+     249             :          DA_SC4, DA_3TE, DA_5TE, DA_TE3, DA_TE5, DC_BB1, DC_BB2, DC_BB3, DC_SC1, DC_SC2, DC_SC3,
+     250             :          DC_3TE, DC_5TE, DC_TE3, DC_TE5, DG_BB1, DG_BB2, DG_BB3, DG_SC1, DG_SC2, DG_SC3, DG_SC4,
+     251             :          DG_3TE, DG_5TE, DG_TE3, DG_TE5, DT_BB1, DT_BB2, DT_BB3, DT_SC1, DT_SC2, DT_SC3, DT_3TE,
+     252             :          DT_5TE, DT_TE3, DT_TE5, NMARTINI
+     253             :        };
+     254             :   enum { TRP, TYR, PHE, HIS, HIP, ARG, LYS, CYS, ASP, GLU, ILE, LEU, MET, ASN, PRO, GLN, SER, THR, VAL, ALA, GLY,
+     255             :          BASE_A, BASE_C, BASE_T, BASE_G, BASE_U,
+     256             :          BB_DNA, BB_DNA_5, BB_DNA_3,
+     257             :          BB_RNA, BB_RNA_5, BB_RNA_3,
+     258             :          BB_PO2,
+     259             :          NONEBEAD
+     260             :        };
+     261             :   struct SplineCoeffs {
+     262             :     double a;
+     263             :     double b;
+     264             :     double c;
+     265             :     double d;
+     266             :     double x;
+     267             :   };
+     268             :   bool saxs;
+     269             :   bool absolute;
+     270             :   bool pbc;
+     271             :   bool serial;
+     272             :   bool gpu;
+     273             :   bool onebead;
+     274             :   bool resolution;
+     275             :   bool isFirstStep;
+     276             :   int  deviceid;
+     277             :   unsigned nres;
+     278             :   std::vector<unsigned> atoi;
+     279             :   std::vector<unsigned> atoms_per_bead;
+     280             :   std::vector<double>   atoms_masses;
+     281             :   std::vector<double>   q_list;
+     282             :   std::vector<double>   FF_rank;
+     283             :   std::vector<std::vector<double> > FF_value_vacuum;
+     284             :   std::vector<std::vector<double> > FF_value_solv;
+     285             :   std::vector<std::vector<double> > FF_value_mixed;
+     286             :   std::vector<std::vector<double> > FF_value;
+     287             :   std::vector<std::vector<float> >  FFf_value;
+     288             :   // SANS:
+     289             :   std::vector<std::vector<double> > FF_value_vacuum_H;
+     290             :   std::vector<std::vector<double> > FF_value_solv_H;
+     291             :   std::vector<std::vector<double> > FF_value_mixed_H;
+     292             :   std::vector<std::vector<double> > FF_value_vacuum_D;
+     293             :   std::vector<std::vector<double> > FF_value_mixed_D;
+     294             : 
+     295             :   std::vector<std::vector<double> > LCPOparam;
+     296             :   std::vector<unsigned> residue_atom;
+     297             : 
+     298             :   double rho, rho_corr, sasa_cutoff;
+     299             :   double deuter_conc;
+     300             :   unsigned solv_stride;
+     301             :   std::vector<double> Iq0_vac;
+     302             :   std::vector<double> Iq0_solv;
+     303             :   std::vector<double> Iq0_mix;
+     304             :   double Iq0;
+     305             : 
+     306             :   // SANS:
+     307             :   std::vector<double> Iq0_vac_H;
+     308             :   std::vector<double> Iq0_solv_H;
+     309             :   std::vector<double> Iq0_mix_H;
+     310             :   std::vector<double> Iq0_vac_D;
+     311             :   std::vector<double> Iq0_mix_D;
+     312             :   unsigned int Nj;
+     313             :   std::vector<std::vector<double> > qj_list;
+     314             :   std::vector<std::vector<double> > Rij;
+     315             :   std::vector<double> sigma_res;
+     316             : 
+     317             :   // Chebyshev polynomial coefficients for i0e(x) used for resolution function
+     318             :   // values taken from cephes library
+     319             :   const std::vector<double> A = {
+     320             :     -4.41534164647933937950E-18,
+     321             :       3.33079451882223809783E-17,
+     322             :       -2.43127984654795469359E-16,
+     323             :       1.71539128555513303061E-15,
+     324             :       -1.16853328779934516808E-14,
+     325             :       7.67618549860493561688E-14,
+     326             :       -4.85644678311192946090E-13,
+     327             :       2.95505266312963983461E-12,
+     328             :       -1.72682629144155570723E-11,
+     329             :       9.67580903537323691224E-11,
+     330             :       -5.18979560163526290666E-10,
+     331             :       2.65982372468238665035E-9,
+     332             :       -1.30002500998624804212E-8,
+     333             :       6.04699502254191894932E-8,
+     334             :       -2.67079385394061173391E-7,
+     335             :       1.11738753912010371815E-6,
+     336             :       -4.41673835845875056359E-6,
+     337             :       1.64484480707288970893E-5,
+     338             :       -5.75419501008210370398E-5,
+     339             :       1.88502885095841655729E-4,
+     340             :       -5.76375574538582365885E-4,
+     341             :       1.63947561694133579842E-3,
+     342             :       -4.32430999505057594430E-3,
+     343             :       1.05464603945949983183E-2,
+     344             :       -2.37374148058994688156E-2,
+     345             :       4.93052842396707084878E-2,
+     346             :       -9.49010970480476444210E-2,
+     347             :       1.71620901522208775349E-1,
+     348             :       -3.04682672343198398683E-1,
+     349             :       6.76795274409476084995E-1
+     350             :     };
+     351             :   const std::vector<double> B = {
+     352             :     -7.23318048787475395456E-18,
+     353             :       -4.83050448594418207126E-18,
+     354             :       4.46562142029675999901E-17,
+     355             :       3.46122286769746109310E-17,
+     356             :       -2.82762398051658348494E-16,
+     357             :       -3.42548561967721913462E-16,
+     358             :       1.77256013305652638360E-15,
+     359             :       3.81168066935262242075E-15,
+     360             :       -9.55484669882830764870E-15,
+     361             :       -4.15056934728722208663E-14,
+     362             :       1.54008621752140982691E-14,
+     363             :       3.85277838274214270114E-13,
+     364             :       7.18012445138366623367E-13,
+     365             :       -1.79417853150680611778E-12,
+     366             :       -1.32158118404477131188E-11,
+     367             :       -3.14991652796324136454E-11,
+     368             :       1.18891471078464383424E-11,
+     369             :       4.94060238822496958910E-10,
+     370             :       3.39623202570838634515E-9,
+     371             :       2.26666899049817806459E-8,
+     372             :       2.04891858946906374183E-7,
+     373             :       2.89137052083475648297E-6,
+     374             :       6.88975834691682398426E-5,
+     375             :       3.36911647825569408990E-3,
+     376             :       8.04490411014108831608E-1
+     377             :     };
+     378             : 
+     379             :   void calculate_gpu(std::vector<Vector> &pos, std::vector<Vector> &deriv);
+     380             :   void calculate_cpu(std::vector<Vector> &pos, std::vector<Vector> &deriv);
+     381             :   void getMartiniFFparam(const std::vector<AtomNumber> &atoms, std::vector<std::vector<long double> > &parameter);
+     382             :   void getOnebeadparam(const PDB &pdb, const std::vector<AtomNumber> &atoms, std::vector<std::vector<long double> > &parameter_vac, std::vector<std::vector<long double> > &parameter_mix, std::vector<std::vector<long double> > &parameter_solv, const std::vector<unsigned> & residue_atom);
+     383             :   unsigned getOnebeadMapping(const PDB &pdb, const std::vector<AtomNumber> &atoms);
+     384             :   double calculateAFF(const std::vector<AtomNumber> &atoms, std::vector<std::vector<long double> > &FF_tmp, const double rho);
+     385             :   std::map<std::string, std::vector<double> > setupLCPOparam();
+     386             :   void readLCPOparam(const std::vector<std::vector<std::string> > &AtomResidueName, unsigned natoms);
+     387             :   void calcNlist(std::vector<std::vector<int> > &Nlist);
+     388             :   void sasa_calculate(std::vector<bool> &solv_res);
+     389             :   // SANS:
+     390             :   void getOnebeadparam_sansH(const PDB &pdb, const std::vector<AtomNumber> &atoms, std::vector<std::vector<long double> > &parameter_vac_H, std::vector<std::vector<long double> > &parameter_mix_H, std::vector<std::vector<long double> > &parameter_solv_H);
+     391             :   void getOnebeadparam_sansD(const PDB &pdb, const std::vector<AtomNumber> &atoms, std::vector<std::vector<long double> > &parameter_vac_D, std::vector<std::vector<long double> > &parameter_mix_D);
+     392             :   double calculateAFFsans(const std::vector<AtomNumber> &atoms, std::vector<std::vector<long double> > &FF_tmp, const double deuter_conc);
+     393             :   void resolution_function();
+     394             :   std::vector<SplineCoeffs> spline_coeffs(std::vector<double> &x, std::vector<double> &y);
+     395             :   inline double interpolation(std::vector<SplineCoeffs> &coeffs, double x);
+     396             :   inline double i0e(double x);
+     397             :   double chbevl(double x, const std::vector<double> &coeffs);
+     398             : 
+     399             : public:
+     400             :   static void registerKeywords( Keywords& keys );
+     401             :   explicit SAXS(const ActionOptions&);
+     402             :   void calculate() override;
+     403             :   void update() override;
+     404             : };
+     405             : 
+     406             : PLUMED_REGISTER_ACTION(SAXS,"SAXS")
+     407             : PLUMED_REGISTER_ACTION(SAXS,"SANS")
+     408             : 
+     409          36 : void SAXS::registerKeywords(Keywords& keys) {
+     410          36 :   componentsAreNotOptional(keys);
+     411          36 :   MetainferenceBase::registerKeywords(keys);
+     412          72 :   keys.addFlag("NOPBC",false,"Ignore the periodic boundary conditions when calculating distances");
+     413          72 :   keys.addFlag("SERIAL",false,"Perform the calculation in serial - for debug purpose");
+     414          72 :   keys.add("compulsory","DEVICEID","-1","Identifier of the GPU to be used");
+     415          72 :   keys.addFlag("GPU",false,"Calculate SAXS using ARRAYFIRE on an accelerator device");
+     416          72 :   keys.addFlag("ABSOLUTE",false,"Absolute intensity: the intensities for each q-value are not normalised for the intensity at q=0.");
+     417          72 :   keys.addFlag("ATOMISTIC",false,"Calculate SAXS for an atomistic model");
+     418          72 :   keys.addFlag("MARTINI",false,"Calculate SAXS for a Martini model");
+     419          72 :   keys.addFlag("ONEBEAD",false,"calculate SAXS for a single bead model");
+     420          72 :   keys.add("compulsory","TEMPLATE","template.pdb","A PDB file is required for ONEBEAD mapping");
+     421          72 :   keys.add("atoms","ATOMS","The atoms to be included in the calculation, e.g. the whole protein");
+     422          72 :   keys.add("numbered","QVALUE","Selected scattering lengths in inverse angstroms are given as QVALUE1, QVALUE2, ...");
+     423          72 :   keys.add("numbered","PARAMETERS","Used parameter Keywords like PARAMETERS1, PARAMETERS2. These are used to calculate the form factor for the \\f$i\\f$th atom/bead");
+     424          72 :   keys.add("optional","PARAMETERSFILE","Read the PARAMETERS from a file");
+     425          72 :   keys.add("compulsory","DEUTER_CONC","0.","Fraction of deuterated solvent");
+     426          72 :   keys.add("compulsory","SOLVDENS","0.334","Density of the solvent to be used for the correction of atomistic form factors");
+     427          72 :   keys.add("compulsory","SOLVATION_CORRECTION","0.0","Solvation layer electron density correction (ONEBEAD only)");
+     428          72 :   keys.add("compulsory","SASA_CUTOFF","1.0","SASA value to consider a residue as exposed to the solvent (ONEBEAD only)");
+     429          72 :   keys.add("numbered","EXPINT","Add an experimental value for each q value");
+     430          72 :   keys.add("numbered","SIGMARES","Variance of Gaussian distribution describing the deviation in the scattering angle for each q value");
+     431          72 :   keys.add("compulsory","N","10","Number of points in the resolution function integral");
+     432          72 :   keys.add("compulsory","SOLVATION_STRIDE","10","Number of steps between every new residues solvation estimation via LCPO (ONEBEAD only)");
+     433          72 :   keys.add("compulsory","SCALE_EXPINT","1.0","Scaling value for experimental data normalization");
+     434          72 :   keys.addOutputComponent("q","default","The # SAXS of q");
+     435          72 :   keys.addOutputComponent("exp","EXPINT","The # experimental intensity");
+     436          36 : }
+     437             : 
+     438          32 : SAXS::SAXS(const ActionOptions&ao):
+     439             :   PLUMED_METAINF_INIT(ao),
+     440          32 :   saxs(true),
+     441          32 :   absolute(false),
+     442          32 :   pbc(true),
+     443          32 :   serial(false),
+     444          32 :   gpu(false),
+     445          32 :   onebead(false),
+     446          32 :   isFirstStep(true),
+     447          32 :   deviceid(-1)
+     448             : {
+     449          32 :   if( getName().find("SAXS")!=std::string::npos) { saxs=true; }
+     450          10 :   else if( getName().find("SANS")!=std::string::npos) { saxs=false; }
+     451             : 
+     452             :   std::vector<AtomNumber> atoms;
+     453          64 :   parseAtomList("ATOMS",atoms);
+     454          32 :   unsigned size = atoms.size();
+     455             : 
+     456          32 :   parseFlag("SERIAL",serial);
+     457             : 
+     458          32 :   bool nopbc=!pbc;
+     459          32 :   parseFlag("NOPBC",nopbc);
+     460          32 :   pbc=!nopbc;
+     461          32 :   if(pbc)      log.printf("  using periodic boundary conditions\n");
+     462          16 :   else         log.printf("  without periodic boundary conditions\n");
+     463             : 
+     464          32 :   parseFlag("GPU",gpu);
+     465             : #ifndef  __PLUMED_HAS_ARRAYFIRE
+     466          32 :   if(gpu) error("To use the GPU mode PLUMED must be compiled with ARRAYFIRE");
+     467             : #endif
+     468             : 
+     469          32 :   parse("DEVICEID",deviceid);
+     470             : #ifdef  __PLUMED_HAS_ARRAYFIRE
+     471             :   if(gpu&&comm.Get_rank()==0) {
+     472             :     // if not set try to check the one set by the API
+     473             :     if(deviceid==-1) deviceid=plumed.getGpuDeviceId();
+     474             :     // if still not set use 0
+     475             :     if(deviceid==-1) deviceid=0;
+     476             : #ifdef  __PLUMED_HAS_ARRAYFIRE_CUDA
+     477             :     af::setDevice(afcu::getNativeId(deviceid));
+     478             : #elif   __PLUMED_HAS_ARRAYFIRE_OCL
+     479             :     af::setDevice(afcl::getNativeId(deviceid));
+     480             : #else
+     481             :     af::setDevice(deviceid);
+     482             : #endif
+     483             :     af::info();
+     484             :   }
+     485             : #endif
+     486             : 
+     487          32 :   bool atomistic=false;
+     488          32 :   parseFlag("ATOMISTIC",atomistic);
+     489          32 :   if(atomistic) log.printf("  using ATOMISTIC form factors\n");
+     490          32 :   bool martini=false;
+     491          32 :   parseFlag("MARTINI",martini);
+     492          32 :   if(martini) log.printf("  using MARTINI form factors\n");
+     493          32 :   onebead=false;
+     494          32 :   parseFlag("ONEBEAD",onebead);
+     495          32 :   if(onebead) log.printf("  using ONEBEAD form factors\n");
+     496             :   bool fromfile=false;
+     497             :   std::string parametersfile;
+     498          64 :   parse("PARAMETERSFILE",parametersfile);
+     499          32 :   if (parametersfile.length() != 0) fromfile=true;
+     500           4 :   if(fromfile) log.printf("  will read form factors from file\n");
+     501          32 :   parseFlag("ABSOLUTE",absolute);
+     502             : 
+     503          32 :   if(martini&&atomistic) error("You cannot use MARTINI and ATOMISTIC at the same time");
+     504          32 :   if(martini&&onebead) error("You cannot use MARTINI and ONEBEAD at the same time");
+     505          32 :   if(onebead&&atomistic) error("You cannot use ONEBEAD and ATOMISTIC at the same time");
+     506          32 :   if((martini)&&(!saxs)) error("MARTINI cannot be used with SANS");
+     507          32 :   if((fromfile)&&((atomistic)||(martini)||(onebead))) {
+     508           0 :     error("You cannot read parameters from file and use ATOMISTIC/MARTINI/ONEBEAD");
+     509             :   }
+     510             : 
+     511             :   unsigned ntarget=0;
+     512             :   for(unsigned i=0;; ++i) {
+     513             :     double t_list;
+     514         736 :     if( !parseNumbered( "QVALUE", i+1, t_list) ) break;
+     515         336 :     if(t_list<=0.) error("QVALUE cannot be less or equal to zero!\n");
+     516         336 :     if(onebead&&t_list>0.3) error("ONEBEAD mapping QVALUE must be smaller or equal to 0.3");
+     517         336 :     q_list.push_back(t_list);
+     518         336 :     ntarget++;
+     519         336 :   }
+     520             :   const unsigned numq = ntarget;
+     521             : 
+     522         368 :   for(unsigned i=0; i<numq; ++i) {
+     523         336 :     if(q_list[i]==0.) error("it is not possible to set q=0\n");
+     524         336 :     if(i>0&&q_list[i]<q_list[i-1]) error("QVALUE must be in ascending order");
+     525         336 :     log.printf("  my q: %lf \n",q_list[i]);
+     526             :   }
+     527             : 
+     528          32 :   rho = 0.334;
+     529          32 :   parse("SOLVDENS", rho);
+     530          32 :   log.printf("  Solvent density: %lf\n", rho);
+     531             : 
+     532          32 :   double scale_expint=1.;
+     533          32 :   parse("SCALE_EXPINT",scale_expint);
+     534             : 
+     535          32 :   if((!atomistic&&absolute)||(absolute&&scale_expint!=1)) error("ABSOLUTE can be used only combined with ATOMISTIC without SCALE_EXPINT");
+     536          38 :   if(atomistic) log.printf("  Scale for intensities: %s\n", absolute ? "absolute" : "normalised");
+     537             : 
+     538          32 :   double correction = 0.00;
+     539          32 :   parse("SOLVATION_CORRECTION", correction);
+     540          32 :   rho_corr=rho-correction;
+     541          32 :   if(onebead) log.printf("  Solvation density contribution: %lf\n", correction);
+     542          32 :   if((atomistic||martini||fromfile)&&(rho_corr!=rho)) log.printf("  Solvation density contribution is taken into account in ONEBEAD only\n");
+     543             : 
+     544          32 :   solv_stride = 10;
+     545          32 :   parse("SOLVATION_STRIDE", solv_stride);
+     546          32 :   if(solv_stride < 1.) error("SOLVATION_STRIDE must be greater than 0");
+     547          32 :   if(onebead&&(rho_corr!=rho)) log.printf("  SASA calculation stride: %u\n", solv_stride);
+     548             : 
+     549          32 :   sasa_cutoff = 1.0;
+     550          32 :   parse("SASA_CUTOFF", sasa_cutoff);
+     551          32 :   if(sasa_cutoff <= 0.) error("SASA_CUTOFF must be greater than 0");
+     552             : 
+     553          32 :   deuter_conc = 0.;
+     554          32 :   parse("DEUTER_CONC", deuter_conc);
+     555          32 :   if ((deuter_conc)&&(fromfile)) error("DEUTER_CONC cannot be used with PARAMETERSFILE");
+     556          32 :   if(deuter_conc < 0. || deuter_conc > 1.) error("DEUTER_CONC must be in 0-1 range");
+     557          32 :   if ((atomistic||onebead)&&(!saxs)) log.printf("  Solvent deuterium fraction: %lf/1.000000\n", deuter_conc);
+     558             : 
+     559          32 :   PDB pdb;
+     560          32 :   if(onebead) {
+     561             :     std::string template_name;
+     562          10 :     parse("TEMPLATE",template_name);
+     563          10 :     log.printf("  Template for ONEBEAD mapping conversion: %s\n", template_name.c_str());
+     564          10 :     if( !pdb.read(template_name,usingNaturalUnits(),1.) ) plumed_merror("missing input file " + template_name);
+     565             :   }
+     566             : 
+     567             :   // preliminary mapping for onebead representation
+     568          32 :   if(onebead) {
+     569          10 :     LCPOparam.resize(size);
+     570          10 :     nres = getOnebeadMapping(pdb, atoms);
+     571          10 :     if(saxs) {
+     572           6 :       Iq0_vac.resize(nres);
+     573           6 :       Iq0_solv.resize(nres);
+     574           6 :       Iq0_mix.resize(nres);
+     575             :     } else { // SANS
+     576           4 :       Iq0_vac_H.resize(nres);
+     577           4 :       Iq0_solv_H.resize(nres);
+     578           4 :       Iq0_mix_H.resize(nres);
+     579           4 :       Iq0_vac_D.resize(nres);
+     580           4 :       Iq0_mix_D.resize(nres);
+     581             :     }
+     582          10 :     atoi.resize(nres);
+     583             :   } else {
+     584          22 :     atoi.resize(size);
+     585             :   }
+     586             : 
+     587          32 :   Iq0=0;
+     588             :   std::vector<std::vector<long double> > FF_tmp;
+     589             :   std::vector<std::vector<long double> > FF_tmp_vac;
+     590             :   std::vector<std::vector<long double> > FF_tmp_mix;
+     591             :   std::vector<std::vector<long double> > FF_tmp_solv;
+     592             :   // SANS
+     593             :   std::vector<std::vector<long double> > FF_tmp_vac_H;
+     594             :   std::vector<std::vector<long double> > FF_tmp_mix_H;
+     595             :   std::vector<std::vector<long double> > FF_tmp_solv_H;
+     596             :   std::vector<std::vector<long double> > FF_tmp_vac_D;
+     597             :   std::vector<std::vector<long double> > FF_tmp_mix_D;
+     598             :   std::vector<std::vector<long double> > parameter_H;
+     599             :   std::vector<std::vector<long double> > parameter_D;
+     600             : 
+     601          32 :   if(!atomistic&&!martini&&!onebead&&!fromfile) { // read PARAMETERS from PLUMED file
+     602           4 :     if (saxs) {
+     603             :       // read in parameter std::vector
+     604             :       std::vector<std::vector<long double> > parameter;
+     605           4 :       parameter.resize(size);
+     606             :       ntarget=0;
+     607          36 :       for(unsigned i=0; i<size; ++i) {
+     608          64 :         if( !parseNumberedVector( "PARAMETERS", i+1, parameter[i]) ) break;
+     609          32 :         ntarget++;
+     610             :       }
+     611           4 :       if( ntarget!=size ) error("found wrong number of parameter std::vectors");
+     612           4 :       FF_tmp.resize(numq,std::vector<long double>(size));
+     613          36 :       for(unsigned i=0; i<size; ++i) {
+     614          32 :         atoi[i]=i;
+     615         128 :         for(unsigned k=0; k<numq; ++k) {
+     616         480 :           for(unsigned j=0; j<parameter[i].size(); ++j) {
+     617         384 :             FF_tmp[k][i]+= parameter[i][j]*std::pow(static_cast<long double>(q_list[k]),j);
+     618             :           }
+     619             :         }
+     620             :       }
+     621          36 :       for(unsigned i=0; i<size; ++i) Iq0+=parameter[i][0];
+     622           4 :       Iq0 *= Iq0;
+     623           4 :     }
+     624             :     else { // SANS
+     625             :       std::vector<long double> parameter;
+     626           0 :       parameter.resize(size);
+     627             :       ntarget=0;
+     628           0 :       for(unsigned i=0; i<size; ++i) {
+     629           0 :         if( !parseNumbered( "PARAMETERS", i+1, parameter[i]) ) break;
+     630           0 :         ntarget++;
+     631             :       }
+     632           0 :       if( ntarget!=size ) error("found wrong number of parameter std::vectors");
+     633           0 :       FF_tmp.resize(numq,std::vector<long double>(size));
+     634           0 :       for(unsigned i=0; i<size; ++i) {
+     635           0 :         atoi[i]=i;
+     636           0 :         for(unsigned k=0; k<numq; ++k) {
+     637           0 :           FF_tmp[k][i]+= parameter[i];
+     638             :         }
+     639             :       }
+     640           0 :       for(unsigned i=0; i<size; ++i) Iq0+=parameter[i];
+     641           0 :       Iq0 *= Iq0;
+     642             :     }
+     643          28 :   } else if (fromfile) { // read PARAMETERS from user-provided file
+     644           4 :     log.printf("  Reading PARAMETERS from file: %s\n", parametersfile.c_str());
+     645           4 :     if (saxs) {
+     646           0 :       FF_tmp.resize(numq,std::vector<long double>(size));
+     647             :       std::vector<std::vector<long double> > parameter;
+     648           0 :       parameter.resize(size);
+     649             : 
+     650           0 :       IFile ifile;
+     651           0 :       ifile.open(parametersfile);
+     652             :       std::string line;
+     653             : 
+     654             :       ntarget=0;
+     655           0 :       while(ifile.getline(line)) {
+     656           0 :         Tools::ltrim(line);
+     657           0 :         Tools::trimComments(line);
+     658           0 :         if (line.empty()) continue;
+     659           0 :         if (ntarget > size) error("PARAMETERSFILE has more PARAMETERS than there are scattering centers");
+     660           0 :         std::string num; Tools::convert(ntarget+1,num);
+     661           0 :         std::vector<std::string> lineread{line};
+     662           0 :         if (!Tools::parseVector(lineread, "PARAMETERS"+num, parameter[ntarget], -1)) error("Missing PARAMETERS or PARAMETERS not sorted");
+     663             :         ntarget++;
+     664           0 :       }
+     665           0 :       if( ntarget!=size ) error("found wrong number of PARAMETERS in file");
+     666             : 
+     667           0 :       for(unsigned i=0; i<size; ++i) {
+     668           0 :         atoi[i]=i;
+     669           0 :         for(unsigned k=0; k<numq; ++k) {
+     670           0 :           for(unsigned j=0; j<parameter[i].size(); ++j) {
+     671           0 :             FF_tmp[k][i]+= parameter[i][j]*std::pow(static_cast<long double>(q_list[k]),j);
+     672             :           }
+     673             :         }
+     674             :       }
+     675           0 :       for(unsigned i=0; i<size; ++i) Iq0+=parameter[i][0];
+     676           0 :       Iq0 *= Iq0;
+     677           0 :     } else { // SANS
+     678           4 :       FF_tmp.resize(numq,std::vector<long double>(size));
+     679             : 
+     680           4 :       IFile ifile;
+     681           4 :       ifile.open(parametersfile);
+     682             :       std::string line;
+     683             : 
+     684             :       ntarget=0;
+     685        1084 :       while(ifile.getline(line)) {
+     686        1080 :         Tools::ltrim(line);
+     687        1080 :         Tools::trimComments(line);
+     688        1080 :         if (line.empty()) continue;
+     689        1080 :         if (ntarget > size) error("PARAMETERSFILE has more PARAMETERS than there are scattering centers");
+     690        1080 :         std::string num; Tools::convert(ntarget+1,num);
+     691        2160 :         std::vector<std::string> lineread{line};
+     692             :         long double scatlen;
+     693        1080 :         atoi[ntarget]=ntarget;
+     694        2160 :         if (!Tools::parse(lineread, "PARAMETERS"+num, scatlen, -1)) error("Missing PARAMETERS or PARAMETERS not sorted");
+     695       17280 :         for(unsigned k=0; k<numq; ++k) {
+     696       16200 :           FF_tmp[k][ntarget] = scatlen;
+     697             :         }
+     698             :         ntarget++;
+     699        1080 :       }
+     700           4 :       if( ntarget!=size ) error("found wrong number of PARAMETERS in file");
+     701        1084 :       for(unsigned i=0; i<size; ++i) Iq0+=FF_tmp[0][i];
+     702           4 :       Iq0 *= Iq0;
+     703           4 :     }
+     704          24 :   } else if(onebead) {
+     705          10 :     if(saxs) {
+     706             :       // read built-in ONEBEAD parameters
+     707           6 :       FF_tmp_vac.resize(numq,std::vector<long double>(NONEBEAD));
+     708           6 :       FF_tmp_mix.resize(numq,std::vector<long double>(NONEBEAD));
+     709           6 :       FF_tmp_solv.resize(numq,std::vector<long double>(NONEBEAD));
+     710           6 :       std::vector<std::vector<long double> > parameter_vac(NONEBEAD);
+     711           6 :       std::vector<std::vector<long double> > parameter_mix(NONEBEAD);
+     712           6 :       std::vector<std::vector<long double> > parameter_solv(NONEBEAD);
+     713           6 :       getOnebeadparam(pdb, atoms, parameter_vac, parameter_mix, parameter_solv,residue_atom);
+     714         204 :       for(unsigned i=0; i<NONEBEAD; ++i) {
+     715        1980 :         for(unsigned k=0; k<numq; ++k) {
+     716       14256 :           for(unsigned j=0; j<parameter_vac[i].size(); ++j) {
+     717       12474 :             FF_tmp_vac[k][i]+= parameter_vac[i][j]*std::pow(static_cast<long double>(q_list[k]),j);
+     718             :           }
+     719       14256 :           for(unsigned j=0; j<parameter_mix[i].size(); ++j) {
+     720       12474 :             FF_tmp_mix[k][i]+= parameter_mix[i][j]*std::pow(static_cast<long double>(q_list[k]),j);
+     721             :           }
+     722       14256 :           for(unsigned j=0; j<parameter_solv[i].size(); ++j) {
+     723       12474 :             FF_tmp_solv[k][i]+= parameter_solv[i][j]*std::pow(static_cast<long double>(q_list[k]),j);
+     724             :           }
+     725             :         }
+     726             :       }
+     727        1294 :       for(unsigned i=0; i<nres; ++i) {
+     728        1288 :         Iq0_vac[i]=parameter_vac[atoi[i]][0];
+     729        1288 :         Iq0_mix[i]=parameter_mix[atoi[i]][0];
+     730        1288 :         Iq0_solv[i]=parameter_solv[atoi[i]][0];
+     731             :       }
+     732           6 :     } else { // SANS
+     733             :       // read built-in ONEBEAD parameters
+     734           4 :       FF_tmp_vac_H.resize(numq,std::vector<long double>(NONEBEAD));
+     735           4 :       FF_tmp_mix_H.resize(numq,std::vector<long double>(NONEBEAD));
+     736           4 :       FF_tmp_solv_H.resize(numq,std::vector<long double>(NONEBEAD));
+     737           4 :       FF_tmp_vac_D.resize(numq,std::vector<long double>(NONEBEAD));
+     738           4 :       FF_tmp_mix_D.resize(numq,std::vector<long double>(NONEBEAD));
+     739           4 :       std::vector<std::vector<long double> > parameter_vac_H(NONEBEAD);
+     740           4 :       std::vector<std::vector<long double> > parameter_mix_H(NONEBEAD);
+     741           4 :       std::vector<std::vector<long double> > parameter_solv_H(NONEBEAD);
+     742           4 :       std::vector<std::vector<long double> > parameter_vac_D(NONEBEAD);
+     743           4 :       std::vector<std::vector<long double> > parameter_mix_D(NONEBEAD);
+     744           4 :       getOnebeadparam_sansH(pdb, atoms, parameter_vac_H, parameter_mix_H, parameter_solv_H);
+     745           4 :       getOnebeadparam_sansD(pdb, atoms, parameter_vac_D, parameter_mix_D);
+     746         136 :       for(unsigned i=0; i<NONEBEAD; ++i) {
+     747        1320 :         for(unsigned k=0; k<numq; ++k) {
+     748        9504 :           for(unsigned j=0; j<parameter_vac_H[i].size(); ++j) { // same number of parameters
+     749        8316 :             FF_tmp_vac_H[k][i]+= parameter_vac_H[i][j]*std::pow(static_cast<long double>(q_list[k]),j);
+     750        8316 :             FF_tmp_vac_D[k][i]+= parameter_vac_D[i][j]*std::pow(static_cast<long double>(q_list[k]),j);
+     751             :           }
+     752        9504 :           for(unsigned j=0; j<parameter_mix_H[i].size(); ++j) {
+     753        8316 :             FF_tmp_mix_H[k][i]+= parameter_mix_H[i][j]*std::pow(static_cast<long double>(q_list[k]),j);
+     754        8316 :             FF_tmp_mix_D[k][i]+= parameter_mix_D[i][j]*std::pow(static_cast<long double>(q_list[k]),j);
+     755             :           }
+     756        9504 :           for(unsigned j=0; j<parameter_solv_H[i].size(); ++j) {
+     757        8316 :             FF_tmp_solv_H[k][i]+= parameter_solv_H[i][j]*std::pow(static_cast<long double>(q_list[k]),j);
+     758             :           }
+     759             :         }
+     760             :       }
+     761         880 :       for(unsigned i=0; i<nres; ++i) {
+     762         876 :         Iq0_vac_H[i]=parameter_vac_H[atoi[i]][0];
+     763         876 :         Iq0_mix_H[i]=parameter_mix_H[atoi[i]][0];
+     764         876 :         Iq0_solv_H[i]=parameter_solv_H[atoi[i]][0];
+     765         876 :         Iq0_vac_D[i]=parameter_vac_D[atoi[i]][0];
+     766         876 :         Iq0_mix_D[i]=parameter_mix_D[atoi[i]][0];
+     767             :       }
+     768           4 :     }
+     769          14 :   } else if(martini) {
+     770             :     // read built-in MARTINI parameters
+     771          16 :     FF_tmp.resize(numq,std::vector<long double>(NMARTINI));
+     772             :     std::vector<std::vector<long double> > parameter;
+     773           8 :     parameter.resize(NMARTINI);
+     774           8 :     getMartiniFFparam(atoms, parameter);
+     775        1072 :     for(unsigned i=0; i<NMARTINI; ++i) {
+     776       17024 :       for(unsigned k=0; k<numq; ++k) {
+     777      127680 :         for(unsigned j=0; j<parameter[i].size(); ++j) {
+     778      111720 :           FF_tmp[k][i]+= parameter[i][j]*std::pow(static_cast<long double>(q_list[k]),j);
+     779             :         }
+     780             :       }
+     781             :     }
+     782        8400 :     for(unsigned i=0; i<size; ++i) Iq0+=parameter[atoi[i]][0];
+     783           8 :     Iq0 *= Iq0;
+     784          14 :   } else if(atomistic) {
+     785           6 :     FF_tmp.resize(numq,std::vector<long double>(NTT));
+     786           6 :     if(saxs) Iq0=calculateAFF(atoms, FF_tmp, rho);
+     787           2 :     else Iq0=calculateAFFsans(atoms, FF_tmp, deuter_conc);
+     788           6 :     Iq0 *= Iq0;
+     789             :   }
+     790             : 
+     791             :   std::vector<double> expint;
+     792          32 :   expint.resize( numq );
+     793             :   ntarget=0;
+     794         224 :   for(unsigned i=0; i<numq; ++i) {
+     795         416 :     if( !parseNumbered( "EXPINT", i+1, expint[i] ) ) break;
+     796         192 :     ntarget++;
+     797             :   }
+     798         224 :   std::transform(expint.begin(), expint.begin() + ntarget, expint.begin(), [scale_expint](double x) { return x / scale_expint; });
+     799             :   bool exp=false;
+     800          32 :   if(ntarget!=numq && ntarget!=0) error("found wrong number of EXPINT values");
+     801          32 :   if(ntarget==numq) exp=true;
+     802          32 :   if(getDoScore()&&!exp) error("with DOSCORE you need to set the EXPINT values");
+     803             : 
+     804          32 :   sigma_res.resize( numq );
+     805          32 :   resolution=false;
+     806             :   ntarget=0;
+     807          92 :   for(unsigned i=0; i<numq; ++i) {
+     808         176 :     if( !parseNumbered( "SIGMARES", i+1, sigma_res[i] ) ) break;
+     809          60 :     ntarget++;
+     810             :   }
+     811          32 :   if(ntarget!=numq && ntarget!=0) error("found wrong number of SIGMARES values");
+     812          32 :   if(ntarget==numq) resolution=true;
+     813             : 
+     814          32 :   if(gpu && resolution) error("Resolution function is not supported in GPUs");
+     815             : 
+     816          32 :   Nj = 10;
+     817          32 :   parse("N", Nj);
+     818          32 :   if (Nj < 2) error("N should be larger than 1");
+     819          32 :   if (resolution) log.printf("  Resolution function with N: %d\n", Nj);
+     820             : 
+     821          32 :   if(!gpu) {
+     822          32 :     FF_rank.resize(numq);
+     823             :     unsigned n_atom_types;
+     824          32 :     if(onebead) {
+     825          10 :       FF_value.resize(nres,std::vector<double>(numq));
+     826             :       n_atom_types=NONEBEAD;
+     827          10 :       if(saxs) {
+     828           6 :         FF_value_vacuum.resize(n_atom_types,std::vector<double>(numq));
+     829           6 :         FF_value_solv.resize(n_atom_types,std::vector<double>(numq));
+     830          12 :         FF_value_mixed.resize(n_atom_types,std::vector<double>(numq));
+     831             :       } else {
+     832           4 :         FF_value_vacuum_H.resize(n_atom_types,std::vector<double>(numq));
+     833           4 :         FF_value_solv_H.resize(n_atom_types,std::vector<double>(numq));
+     834           4 :         FF_value_mixed_H.resize(n_atom_types,std::vector<double>(numq));
+     835           4 :         FF_value_vacuum_D.resize(n_atom_types,std::vector<double>(numq));
+     836           8 :         FF_value_mixed_D.resize(n_atom_types,std::vector<double>(numq));
+     837             :       }
+     838             :     } else {
+     839          44 :       FF_value.resize(size,std::vector<double>(numq));
+     840             :     }
+     841         368 :     for(unsigned k=0; k<numq; ++k) {
+     842         336 :       if(!onebead) {
+     843      332970 :         for(unsigned i=0; i<size; ++i) FF_value[i][k] = static_cast<double>(FF_tmp[k][atoi[i]])/(std::sqrt(Iq0));
+     844      332970 :         for(unsigned i=0; i<size; ++i) FF_rank[k] += FF_value[i][k]*FF_value[i][k];
+     845             :       } else {
+     846          90 :         if(saxs) {
+     847        1836 :           for(unsigned i=0; i<n_atom_types; ++i) {
+     848        1782 :             FF_value_vacuum[i][k] = static_cast<double>(FF_tmp_vac[k][i]);
+     849        1782 :             FF_value_mixed[i][k] = static_cast<double>(FF_tmp_mix[k][i]);
+     850        1782 :             FF_value_solv[i][k] = static_cast<double>(FF_tmp_solv[k][i]);
+     851             :           }
+     852             :         } else { // SANS
+     853        1224 :           for(unsigned i=0; i<n_atom_types; ++i) {
+     854        1188 :             FF_value_vacuum_H[i][k] = static_cast<double>(FF_tmp_vac_H[k][i]);
+     855        1188 :             FF_value_mixed_H[i][k] = static_cast<double>(FF_tmp_mix_H[k][i]);
+     856        1188 :             FF_value_solv_H[i][k] = static_cast<double>(FF_tmp_solv_H[k][i]);
+     857        1188 :             FF_value_vacuum_D[i][k] = static_cast<double>(FF_tmp_vac_D[k][i]);
+     858        1188 :             FF_value_mixed_D[i][k] = static_cast<double>(FF_tmp_mix_D[k][i]);
+     859             :           }
+     860             :         }
+     861             :       }
+     862             :     }
+     863             :   } else {
+     864             :     unsigned n_atom_types;
+     865           0 :     if(onebead) {
+     866           0 :       FFf_value.resize(numq,std::vector<float>(nres));
+     867             :       n_atom_types=NONEBEAD;
+     868           0 :       if(saxs) {
+     869           0 :         FF_value_vacuum.resize(n_atom_types,std::vector<double>(numq));
+     870           0 :         FF_value_solv.resize(n_atom_types,std::vector<double>(numq));
+     871           0 :         FF_value_mixed.resize(n_atom_types,std::vector<double>(numq));
+     872             :       } else { // SANS
+     873           0 :         FF_value_vacuum_H.resize(n_atom_types,std::vector<double>(numq));
+     874           0 :         FF_value_solv_H.resize(n_atom_types,std::vector<double>(numq));
+     875           0 :         FF_value_mixed_H.resize(n_atom_types,std::vector<double>(numq));
+     876           0 :         FF_value_vacuum_D.resize(n_atom_types,std::vector<double>(numq));
+     877           0 :         FF_value_mixed_D.resize(n_atom_types,std::vector<double>(numq));
+     878             :       }
+     879             :     } else {
+     880           0 :       FFf_value.resize(numq,std::vector<float>(size));
+     881             :     }
+     882           0 :     for(unsigned k=0; k<numq; ++k) {
+     883           0 :       if(!onebead) {
+     884           0 :         for(unsigned i=0; i<size; ++i) {
+     885           0 :           FFf_value[k][i] = static_cast<float>(FF_tmp[k][atoi[i]])/(std::sqrt(Iq0));
+     886             :         }
+     887             :       } else {
+     888           0 :         if(saxs) {
+     889           0 :           for(unsigned i=0; i<n_atom_types; ++i) {
+     890           0 :             FF_value_vacuum[i][k] = static_cast<double>(FF_tmp_vac[k][i]);
+     891           0 :             FF_value_mixed[i][k] = static_cast<double>(FF_tmp_mix[k][i]);
+     892           0 :             FF_value_solv[i][k] = static_cast<double>(FF_tmp_solv[k][i]);
+     893             :           }
+     894             :         } else { // SANS
+     895           0 :           for(unsigned i=0; i<n_atom_types; ++i) {
+     896           0 :             FF_value_vacuum_H[i][k] = static_cast<double>(FF_tmp_vac_H[k][i]);
+     897           0 :             FF_value_mixed_H[i][k] = static_cast<double>(FF_tmp_mix_H[k][i]);
+     898           0 :             FF_value_solv_H[i][k] = static_cast<double>(FF_tmp_solv_H[k][i]);
+     899           0 :             FF_value_vacuum_D[i][k] = static_cast<double>(FF_tmp_vac_D[k][i]);
+     900           0 :             FF_value_mixed_D[i][k] = static_cast<double>(FF_tmp_mix_D[k][i]);
+     901             :           }
+     902             :         }
+     903             :       }
+     904             :     }
+     905             :   }
+     906             : 
+     907          32 :   if(!getDoScore()) {
+     908         288 :     for(unsigned i=0; i<numq; ++i) {
+     909         264 :       std::string num; Tools::convert(i,num);
+     910         528 :       addComponentWithDerivatives("q-"+num);
+     911         528 :       componentIsNotPeriodic("q-"+num);
+     912             :     }
+     913          24 :     if(exp) {
+     914         128 :       for(unsigned i=0; i<numq; ++i) {
+     915         120 :         std::string num; Tools::convert(i,num);
+     916         240 :         addComponent("exp-"+num);
+     917         120 :         componentIsNotPeriodic("exp-"+num);
+     918         120 :         Value* comp=getPntrToComponent("exp-"+num);
+     919         120 :         comp->set(expint[i]);
+     920             :       }
+     921             :     }
+     922             :   } else {
+     923          80 :     for(unsigned i=0; i<numq; ++i) {
+     924          72 :       std::string num; Tools::convert(i,num);
+     925         144 :       addComponent("q-"+num);
+     926         144 :       componentIsNotPeriodic("q-"+num);
+     927             :     }
+     928          80 :     for(unsigned i=0; i<numq; ++i) {
+     929          72 :       std::string num; Tools::convert(i,num);
+     930         144 :       addComponent("exp-"+num);
+     931          72 :       componentIsNotPeriodic("exp-"+num);
+     932          72 :       Value* comp=getPntrToComponent("exp-"+num);
+     933          72 :       comp->set(expint[i]);
+     934             :     }
+     935             :   }
+     936             : 
+     937             :   // convert units to nm^-1
+     938         368 :   for(unsigned i=0; i<numq; ++i) {
+     939         336 :     q_list[i]=q_list[i]*10.0;    // factor 10 to convert from A^-1 to nm^-1
+     940         336 :     if (resolution) sigma_res[i]=sigma_res[i]*10.0;
+     941             :   }
+     942             : 
+     943             :   // compute resolution function after converting units
+     944          32 :   if (resolution) {
+     945           4 :     qj_list.resize(numq, std::vector<double>(Nj));
+     946           4 :     Rij.resize(numq, std::vector<double>(Nj));
+     947             :     // compute Rij and qj_list
+     948           4 :     resolution_function();
+     949             :   }
+     950             : 
+     951          32 :   log<<"  Bibliography ";
+     952          32 :   if(martini) {
+     953          16 :     log<<plumed.cite("Niebling, Björling, Westenhoff, J Appl Crystallogr 47, 1190–1198 (2014)");
+     954          16 :     log<<plumed.cite("Paissoni, Jussupow, Camilloni, J Appl Crystallogr 52, 394-402 (2019)");
+     955             :   }
+     956          32 :   if(atomistic) {
+     957          12 :     log<<plumed.cite("Fraser, MacRae, Suzuki, J. Appl. Crystallogr., 11, 693–694 (1978)");
+     958          12 :     log<<plumed.cite("Brown, Fox, Maslen, O'Keefe, Willis, International Tables for Crystallography C, 554–595 (International Union of Crystallography, 2006)");
+     959             :   }
+     960          32 :   if(resolution) {
+     961           8 :     log<<plumed.cite("Pedersen, Posselt, Mortensen, J. Appl. Crystallogr., 23, 321–333 (1990)");
+     962             :   }
+     963             : 
+     964          64 :   log<< plumed.cite("Bonomi, Camilloni, Bioinformatics, 33, 3999 (2017)");
+     965          32 :   log<<"\n";
+     966             : 
+     967          32 :   requestAtoms(atoms, false);
+     968             : 
+     969          32 :   if(getDoScore()) {
+     970           8 :     setParameters(expint);
+     971           8 :     Initialise(numq);
+     972             :   }
+     973          32 :   setDerivatives();
+     974          32 :   checkRead();
+     975          64 : }
+     976             : 
+     977             : // calculates SASA neighbor list
+     978           8 : void SAXS::calcNlist(std::vector<std::vector<int> > &Nlist)
+     979             : {
+     980             :   unsigned natoms = getNumberOfAtoms();
+     981       28596 :   for(unsigned i = 0; i < natoms; ++i) {
+     982       28588 :     if (LCPOparam[i].size()>0) {
+     983    24279400 :       for (unsigned j = 0; j < i; ++j) {
+     984    24266020 :         if (LCPOparam[j].size()>0) {
+     985    11213664 :           double Delta_ij_mod = modulo(delta(getPosition(i), getPosition(j)))*10.;
+     986    11213664 :           double overlapD = LCPOparam[i][0]+LCPOparam[j][0];
+     987    11213664 :           if(Delta_ij_mod < overlapD) {
+     988      259140 :             Nlist.at(i).push_back(j);
+     989      259140 :             Nlist.at(j).push_back(i);
+     990             :           }
+     991             :         }
+     992             :       }
+     993             :     }
+     994             :   }
+     995             : 
+     996           8 : }
+     997             : 
+     998             : // calculates SASA according to LCPO algorithm
+     999           8 : void SAXS::sasa_calculate(std::vector<bool> &solv_res) {
+    1000             :   unsigned natoms = getNumberOfAtoms();
+    1001           8 :   std::vector<std::vector<int> > Nlist(natoms);
+    1002           8 :   calcNlist(Nlist);
+    1003           8 :   std::vector<double> sasares(nres, 0.);
+    1004             : 
+    1005           8 :   #pragma omp parallel num_threads(OpenMP::getNumThreads())
+    1006             :   {
+    1007             :     std::vector<double> private_sasares(nres, 0.);
+    1008             :     #pragma omp for
+    1009             :     for (unsigned i = 0; i < natoms; ++i) {
+    1010             :       if (LCPOparam[i].size() > 1 && LCPOparam[i][1] > 0.0) {
+    1011             :         double Aij = 0.0;
+    1012             :         double Aijk = 0.0;
+    1013             :         double Ajk = 0.0;
+    1014             :         double ri = LCPOparam[i][0];
+    1015             :         double S1 = 4.*M_PI*ri*ri;
+    1016             :         for (unsigned j = 0; j < Nlist[i].size(); ++j) {
+    1017             :           double d_ij = modulo(delta( getPosition(i), getPosition(Nlist[i][j]) ))*10.;
+    1018             :           double rj = LCPOparam[Nlist[i][j]][0];
+    1019             :           double Aijt = (2.*M_PI*ri*(ri-d_ij/2.-((ri*ri-rj*rj)/(2.*d_ij))));
+    1020             :           double Ajkt = 0.0;
+    1021             :           for (unsigned k = 0; k < Nlist[Nlist[i][j]].size(); ++k) {
+    1022             :             if (std::find (Nlist[i].begin(), Nlist[i].end(), Nlist[Nlist[i][j]][k]) !=  Nlist[i].end()) {
+    1023             :               double d_jk = modulo(delta( getPosition(Nlist[i][j]), getPosition(Nlist[Nlist[i][j]][k]) ))*10.;
+    1024             :               double rk = LCPOparam[Nlist[Nlist[i][j]][k]][0];
+    1025             :               double sjk =  (2.*M_PI*rj*(rj-d_jk/2.-((rj*rj-rk*rk)/(2.*d_jk))));
+    1026             :               Ajkt += sjk;
+    1027             :             }
+    1028             :           }
+    1029             :           Aijk += (Aijt * Ajkt);
+    1030             :           Aij += Aijt;
+    1031             :           Ajk += Ajkt;
+    1032             :         }
+    1033             :         double sasai = (LCPOparam[i][1]*S1+LCPOparam[i][2]*Aij+LCPOparam[i][3]*Ajk+LCPOparam[i][4]*Aijk);
+    1034             :         if (sasai > 0) {
+    1035             :           private_sasares[residue_atom[i]] += sasai / 100.0;
+    1036             :         }
+    1037             :       }
+    1038             :     }
+    1039             :     #pragma omp critical
+    1040             :     { // combining private_sasares into sasares
+    1041             :       for (unsigned i = 0; i < nres; ++i) {
+    1042             :         sasares[i] += private_sasares[i];
+    1043             :       }
+    1044             :     }
+    1045             :   }
+    1046        1760 :   for(unsigned i=0; i<nres; ++i) { // updating solv_res based on sasares
+    1047        1752 :     if(sasares[i]>sasa_cutoff) solv_res[i] = 1;
+    1048             :     else solv_res[i] = 0;
+    1049             :   }
+    1050           8 : }
+    1051             : 
+    1052           0 : void SAXS::calculate_gpu(std::vector<Vector> &pos, std::vector<Vector> &deriv)
+    1053             : {
+    1054             : #ifdef __PLUMED_HAS_ARRAYFIRE
+    1055             :   unsigned size;
+    1056             :   if(onebead) size = nres;
+    1057             :   else size = getNumberOfAtoms();
+    1058             :   const unsigned numq = q_list.size();
+    1059             : 
+    1060             :   std::vector<float> sum;
+    1061             :   sum.resize(numq);
+    1062             : 
+    1063             :   std::vector<float> dd;
+    1064             :   dd.resize(size*3*numq);
+    1065             : 
+    1066             :   // on gpu only the master rank run the calculation
+    1067             :   if(comm.Get_rank()==0) {
+    1068             :     std::vector<float> posi;
+    1069             :     posi.resize(3*size);
+    1070             :     #pragma omp parallel for num_threads(OpenMP::getNumThreads())
+    1071             :     for (unsigned i=0; i<size; ++i) {
+    1072             :       const Vector tmp = pos[i];
+    1073             :       posi[3*i]   = static_cast<float>(tmp[0]);
+    1074             :       posi[3*i+1] = static_cast<float>(tmp[1]);
+    1075             :       posi[3*i+2] = static_cast<float>(tmp[2]);
+    1076             :     }
+    1077             : 
+    1078             :     // create array a and b containing atomic coordinates
+    1079             : #ifdef  __PLUMED_HAS_ARRAYFIRE_CUDA
+    1080             :     af::setDevice(afcu::getNativeId(deviceid));
+    1081             : #elif   __PLUMED_HAS_ARRAYFIRE_OCL
+    1082             :     af::setDevice(afcl::getNativeId(deviceid));
+    1083             : #else
+    1084             :     af::setDevice(deviceid);
+    1085             : #endif
+    1086             :     // 3,size,1,1
+    1087             :     af::array pos_a = af::array(3, size, &posi.front());
+    1088             :     // size,3,1,1
+    1089             :     pos_a = af::moddims(pos_a.T(), size, 3, 1);
+    1090             :     // size,3,1,1
+    1091             :     af::array pos_b = pos_a(af::span, af::span);
+    1092             :     // size,1,3,1
+    1093             :     pos_a = af::moddims(pos_a, size, 1, 3);
+    1094             :     // 1,size,3,1
+    1095             :     pos_b = af::moddims(pos_b, 1, size, 3);
+    1096             : 
+    1097             :     // size,size,3,1
+    1098             :     af::array pos_a_t = af::tile(pos_a, 1, size, 1);
+    1099             :     // size,size,3,1: for some reason we need this
+    1100             :     pos_a_t = af::moddims(pos_a_t, size, size, 3);
+    1101             :     // size,size,3,1
+    1102             :     af::array pos_b_t = af::tile(pos_b, size, 1, 1);
+    1103             :     // size,size,3,1: for some reason we need this
+    1104             :     pos_b_t = af::moddims(pos_b_t, size, size, 3);
+    1105             :     // size,size,3,1
+    1106             :     af::array xyz_dist = pos_a_t - pos_b_t;
+    1107             :     // size,size,1,1
+    1108             :     af::array square = af::sum(xyz_dist*xyz_dist,2);
+    1109             :     // size,size,1,1
+    1110             :     af::array dist_sqrt = af::sqrt(square);
+    1111             :     // replace the zero of square with one to avoid nan in the derivatives (the number does not matter because this are multiplied by zero)
+    1112             :     af::replace(square,!(af::iszero(square)),1.);
+    1113             :     // size,size,3,1
+    1114             :     xyz_dist = xyz_dist / af::tile(square, 1, 1, 3);
+    1115             :     // numq,1,1,1
+    1116             :     af::array sum_device   = af::constant(0, numq, f32);
+    1117             :     // numq,size,3,1
+    1118             :     af::array deriv_device = af::constant(0, numq, size, 3, f32);
+    1119             : 
+    1120             :     for (unsigned k=0; k<numq; ++k) {
+    1121             :       // calculate FF matrix
+    1122             :       // size,1,1,1
+    1123             :       af::array AFF_value(size, &FFf_value[k].front());
+    1124             :       // size,size,1,1
+    1125             :       af::array FFdist_mod = af::tile(AFF_value(af::span), 1, size)*af::transpose(af::tile(AFF_value(af::span), 1, size));
+    1126             : 
+    1127             :       // get q
+    1128             :       const float qvalue = static_cast<float>(q_list[k]);
+    1129             :       // size,size,1,1
+    1130             :       af::array dist_q = qvalue*dist_sqrt;
+    1131             :       // size,size,1
+    1132             :       af::array dist_sin = af::sin(dist_q)/dist_q;
+    1133             :       af::replace(dist_sin,!(af::isNaN(dist_sin)),1.);
+    1134             :       // 1,1,1,1
+    1135             :       sum_device(k) = af::sum(af::flat(dist_sin)*af::flat(FFdist_mod));
+    1136             : 
+    1137             :       // size,size,1,1
+    1138             :       af::array tmp = FFdist_mod*(dist_sin - af::cos(dist_q));
+    1139             :       // size,size,3,1
+    1140             :       af::array dd_all = af::tile(tmp, 1, 1, 3)*xyz_dist;
+    1141             :       // it should become 1,size,3
+    1142             :       deriv_device(k, af::span, af::span) = af::sum(dd_all,0);
+    1143             :     }
+    1144             : 
+    1145             :     // read out results
+    1146             :     sum_device.host(&sum.front());
+    1147             : 
+    1148             :     deriv_device = af::reorder(deriv_device, 2, 1, 0);
+    1149             :     deriv_device = af::flat(deriv_device);
+    1150             :     deriv_device.host(&dd.front());
+    1151             :   }
+    1152             : 
+    1153             :   comm.Bcast(dd, 0);
+    1154             :   comm.Bcast(sum, 0);
+    1155             : 
+    1156             :   for(unsigned k=0; k<numq; ++k) {
+    1157             :     std::string num; Tools::convert(k,num);
+    1158             :     Value* val=getPntrToComponent("q-"+num);
+    1159             :     val->set(sum[k]);
+    1160             :     if(getDoScore()) setCalcData(k, sum[k]);
+    1161             :     for(unsigned i=0; i<size; ++i) {
+    1162             :       const unsigned di = k*size*3+i*3;
+    1163             :       deriv[k*size+i] = Vector(2.*dd[di+0],2.*dd[di+1],2.*dd[di+2]);
+    1164             :     }
+    1165             :   }
+    1166             : #endif
+    1167           0 : }
+    1168             : 
+    1169         192 : void SAXS::calculate_cpu(std::vector<Vector> &pos, std::vector<Vector> &deriv)
+    1170             : {
+    1171             :   unsigned size;
+    1172         192 :   if(onebead) size = nres;
+    1173             :   else size = getNumberOfAtoms();
+    1174         192 :   const unsigned numq = q_list.size();
+    1175             : 
+    1176         192 :   unsigned stride = comm.Get_size();
+    1177         192 :   unsigned rank   = comm.Get_rank();
+    1178         192 :   if(serial) {
+    1179             :     stride = 1;
+    1180             :     rank   = 0;
+    1181             :   }
+    1182         192 :   std::vector<double> sum(numq,0);
+    1183         192 :   unsigned nt=OpenMP::getNumThreads();
+    1184         192 :   #pragma omp parallel num_threads(nt)
+    1185             :   {
+    1186             :     std::vector<Vector> omp_deriv(deriv.size());
+    1187             :     std::vector<double> omp_sum(numq,0);
+    1188             :     #pragma omp for nowait
+    1189             :     for (unsigned i=rank; i<size-1; i+=stride) {
+    1190             :       Vector posi = pos[i];
+    1191             :       for (unsigned j=i+1; j<size ; ++j) {
+    1192             :         Vector c_distances = delta(posi,pos[j]);
+    1193             :         double m_distances = c_distances.modulo();
+    1194             :         c_distances = c_distances/m_distances/m_distances;
+    1195             :         for (unsigned k=0; k<numq; ++k) {
+    1196             :           unsigned kdx=k*size;
+    1197             :           double qdist = q_list[k]*m_distances;
+    1198             :           double FFF = 2.*FF_value[i][k]*FF_value[j][k];
+    1199             :           double tsq = std::sin(qdist)/qdist;
+    1200             :           double tcq = std::cos(qdist);
+    1201             :           double tmp = FFF*(tcq-tsq);
+    1202             :           Vector dd  = c_distances*tmp;
+    1203             :           if(nt>1) {
+    1204             :             omp_deriv[kdx+i] -=dd;
+    1205             :             omp_deriv[kdx+j] +=dd;
+    1206             :             omp_sum[k] += FFF*tsq;
+    1207             :           } else {
+    1208             :             deriv[kdx+i] -= dd;
+    1209             :             deriv[kdx+j] += dd;
+    1210             :             sum[k] += FFF*tsq;
+    1211             :           }
+    1212             :         }
+    1213             :       }
+    1214             :     }
+    1215             :     #pragma omp critical
+    1216             :     if(nt>1) {
+    1217             :       for(unsigned i=0; i<deriv.size(); ++i) deriv[i]+=omp_deriv[i];
+    1218             :       for(unsigned k=0; k<numq; ++k) sum[k]+=omp_sum[k];
+    1219             :     }
+    1220             :   }
+    1221             : 
+    1222         192 :   if(!serial) {
+    1223         190 :     comm.Sum(&deriv[0][0], 3*deriv.size());
+    1224         190 :     comm.Sum(&sum[0], numq);
+    1225             :   }
+    1226             : 
+    1227         192 :   if (resolution) {
+    1228             :     // get spline for scatering curve
+    1229           4 :     std::vector<SplineCoeffs> scatt_coeffs = spline_coeffs(q_list, sum);
+    1230             : 
+    1231             :     // get spline for the derivatives
+    1232             :     // copy the deriv to a new vector and zero deriv
+    1233           4 :     std::vector<Vector> old_deriv(deriv);
+    1234           4 :     memset(&deriv[0][0], 0.0, deriv.size() * sizeof deriv[0]);
+    1235             : 
+    1236           4 :     unsigned nt=OpenMP::getNumThreads();
+    1237         274 :     for (unsigned i=rank; i<size; i+=stride) {
+    1238         270 :       std::vector<double> deriv_i_x(numq);
+    1239         270 :       std::vector<double> deriv_i_y(numq);
+    1240         270 :       std::vector<double> deriv_i_z(numq);
+    1241             : 
+    1242             :       std::vector<SplineCoeffs> deriv_coeffs_x;
+    1243             :       std::vector<SplineCoeffs> deriv_coeffs_y;
+    1244             :       std::vector<SplineCoeffs> deriv_coeffs_z;
+    1245        4320 :       for (unsigned k=0; k<numq; k++) {
+    1246        4050 :         unsigned kdx = k*size;
+    1247        4050 :         deriv_i_x[k] = old_deriv[kdx+i][0];
+    1248        4050 :         deriv_i_y[k] = old_deriv[kdx+i][1];
+    1249        4050 :         deriv_i_z[k] = old_deriv[kdx+i][2];
+    1250             :       }
+    1251         270 :       deriv_coeffs_x = spline_coeffs(q_list, deriv_i_x);
+    1252         270 :       deriv_coeffs_y = spline_coeffs(q_list, deriv_i_y);
+    1253         270 :       deriv_coeffs_z = spline_coeffs(q_list, deriv_i_z);
+    1254             : 
+    1255             :       // compute derivative with the smearing using the resolution function
+    1256         270 :       #pragma omp parallel for num_threads(nt)
+    1257             :       for (unsigned k=0; k<numq; k++) {
+    1258             :         unsigned kdx = k*size;
+    1259             :         double dq = qj_list[k][1] - qj_list[k][0];
+    1260             :         for (unsigned j=0; j<Nj; j++) {
+    1261             :           deriv[kdx+i][0] += Rij[k][j] * interpolation(deriv_coeffs_x, qj_list[k][j]) * dq;
+    1262             :           deriv[kdx+i][1] += Rij[k][j] * interpolation(deriv_coeffs_y, qj_list[k][j]) * dq;
+    1263             :           deriv[kdx+i][2] += Rij[k][j] * interpolation(deriv_coeffs_z, qj_list[k][j]) * dq;
+    1264             :         }
+    1265             :       }
+    1266             :     }
+    1267             : 
+    1268           4 :     if(!serial) {
+    1269           4 :       comm.Sum(&deriv[0][0], 3*deriv.size());
+    1270             :     }
+    1271             : 
+    1272             :     // compute the smeared spectra using the resolution function
+    1273           4 :     #pragma omp parallel for num_threads(nt)
+    1274             :     for (unsigned i=0; i<numq; i++) {
+    1275             :       sum[i] = 0.;
+    1276             :       double dq = qj_list[i][1] - qj_list[i][0];
+    1277             :       for (unsigned j=0; j<Nj; j++) {
+    1278             :         sum[i] += Rij[i][j] * interpolation(scatt_coeffs, qj_list[i][j]) * dq;
+    1279             :       }
+    1280             :     }
+    1281             :   }
+    1282             : 
+    1283        1968 :   for (unsigned k=0; k<numq; ++k) {
+    1284        1776 :     sum[k]+=FF_rank[k];
+    1285        1776 :     std::string num; Tools::convert(k,num);
+    1286        1776 :     Value* val=getPntrToComponent("q-"+num);
+    1287        1776 :     val->set(sum[k]);
+    1288        1776 :     if(getDoScore()) setCalcData(k, sum[k]);
+    1289             :   }
+    1290         192 : }
+    1291             : 
+    1292         192 : void SAXS::calculate()
+    1293             : {
+    1294         192 :   if(pbc) makeWhole();
+    1295             : 
+    1296         192 :   const size_t size = getNumberOfAtoms();
+    1297             :   const size_t numq = q_list.size();
+    1298             : 
+    1299             :   // these are the derivatives associated to the coarse graining
+    1300         192 :   std::vector<Vector> aa_deriv(size);
+    1301             : 
+    1302             :   size_t beads_size = size;
+    1303         192 :   if(onebead) beads_size = nres;
+    1304             :   // these are the derivatives particle,q
+    1305         192 :   std::vector<Vector> bd_deriv(numq*beads_size);
+    1306             : 
+    1307         192 :   std::vector<Vector> beads_pos(beads_size);
+    1308         192 :   if(onebead) {
+    1309        2174 :     for(unsigned resid=0; resid<nres; resid++) {
+    1310             :       double sum_mass = 0.;
+    1311        2164 :       Vector sum_pos = Vector(0,0,0);
+    1312     7693792 :       for(unsigned atom_id=0; atom_id<size; atom_id++) {
+    1313     7691628 :         if(residue_atom[atom_id] == resid) {
+    1314       35466 :           aa_deriv[atom_id] = Vector(atoms_masses[atom_id],atoms_masses[atom_id],atoms_masses[atom_id]);
+    1315       35466 :           sum_pos += atoms_masses[atom_id] * getPosition(atom_id); // getPosition(first_atom+atom_id)
+    1316       35466 :           sum_mass += atoms_masses[atom_id];
+    1317             :         }
+    1318             :       }
+    1319        2164 :       beads_pos[resid] = sum_pos/sum_mass;
+    1320     7693792 :       for(unsigned atom_id=0; atom_id<size; atom_id++) {
+    1321     7691628 :         if(residue_atom[atom_id] == resid) {
+    1322       35466 :           aa_deriv[atom_id] /= sum_mass;
+    1323             :         }
+    1324             :       }
+    1325             :     }
+    1326             :     // SASA
+    1327          10 :     std::vector<bool> solv_res(nres, 0);
+    1328          10 :     if(saxs) {
+    1329           6 :       if(getStep()%solv_stride == 0 || isFirstStep) {
+    1330           6 :         isFirstStep = 0;
+    1331           6 :         if(rho_corr!=rho) sasa_calculate(solv_res);
+    1332           6 :         Iq0=0.;
+    1333        1294 :         for(unsigned i=0; i<nres; ++i) {
+    1334        1288 :           if(solv_res[i] == 1 ) {
+    1335         182 :             Iq0 += std::sqrt((Iq0_vac[i]+(rho_corr*rho_corr)*Iq0_solv[i]-rho_corr*Iq0_mix[i]));
+    1336             :           } else {
+    1337        1106 :             Iq0 += std::sqrt((Iq0_vac[i]+(rho*rho)*Iq0_solv[i]-rho*Iq0_mix[i]));
+    1338             :           }
+    1339             :         }
+    1340             :         // Form Factors
+    1341          60 :         for(unsigned k=0; k<numq; ++k) {
+    1342       11646 :           for(unsigned i=0; i<nres; ++i) {
+    1343       11592 :             if(!gpu) {
+    1344       11592 :               if(solv_res[i] == 0) { // buried
+    1345        9954 :                 FF_value[i][k] = std::sqrt(std::fabs(FF_value_vacuum[atoi[i]][k] + rho*rho*FF_value_solv[atoi[i]][k] - rho*FF_value_mixed[atoi[i]][k]))/Iq0;
+    1346             :               } else { // surface
+    1347        1638 :                 FF_value[i][k] = std::sqrt(std::fabs(FF_value_vacuum[atoi[i]][k] + rho_corr*rho_corr*FF_value_solv[atoi[i]][k] - rho_corr*FF_value_mixed[atoi[i]][k]))/Iq0;
+    1348             :               }
+    1349             :             } else {
+    1350           0 :               if(solv_res[i] == 0) { // buried
+    1351           0 :                 FFf_value[k][i] = static_cast<float>(std::sqrt(std::fabs(FF_value_vacuum[atoi[i]][k] + rho*rho*FF_value_solv[atoi[i]][k] - rho*FF_value_mixed[atoi[i]][k]))/Iq0);
+    1352             :               } else { // surface
+    1353           0 :                 FFf_value[k][i] = static_cast<float>(std::sqrt(std::fabs(FF_value_vacuum[atoi[i]][k] + rho_corr*rho_corr*FF_value_solv[atoi[i]][k] - rho_corr*FF_value_mixed[atoi[i]][k]))/Iq0);
+    1354             :               }
+    1355             :             }
+    1356             :           }
+    1357             :         }
+    1358           6 :         if(!gpu) {
+    1359          60 :           for(unsigned k=0; k<numq; ++k) {
+    1360          54 :             FF_rank[k]=0.;
+    1361       11646 :             for(unsigned i=0; i<nres; ++i) {
+    1362       11592 :               FF_rank[k]+=FF_value[i][k]*FF_value[i][k];
+    1363             :             }
+    1364             :           }
+    1365             :         }
+    1366             :       }
+    1367             :     } else { // SANS
+    1368           4 :       std::vector<bool> deut_res(nres, 0);
+    1369           4 :       double solv_sc_length = 0.1*(0.580 + 2.*((1. - deuter_conc) * (-0.374) + deuter_conc * 0.667)); // per water electron (10 electrons)
+    1370           4 :       double rho_sans = rho * solv_sc_length;
+    1371           4 :       double rho_sans_corr = rho_corr * solv_sc_length;
+    1372           4 :       if(getStep()%solv_stride == 0 || isFirstStep) {
+    1373           4 :         isFirstStep = 0;
+    1374           4 :         if(deuter_conc!=0.||rho != rho_corr) sasa_calculate(solv_res);
+    1375           4 :         Iq0=0.;
+    1376         880 :         for(unsigned i=0; i<nres; ++i) {
+    1377         876 :           if(solv_res[i] == 1 ) {
+    1378         182 :             if(rand()/RAND_MAX<deuter_conc) {
+    1379           0 :               Iq0 += std::sqrt(std::fabs(Iq0_vac_D[i] + rho_sans_corr*rho_sans_corr*Iq0_solv_H[i] - rho_sans_corr*Iq0_mix_D[i]));
+    1380             :               deut_res[i] = 1;
+    1381             :             } else {
+    1382         182 :               Iq0 += std::sqrt(std::fabs(Iq0_vac_H[i] + rho_sans_corr*rho_sans_corr*Iq0_solv_H[i] - rho_sans_corr*Iq0_mix_H[i]));
+    1383             :             }
+    1384             :           } else {
+    1385         694 :             Iq0 += std::sqrt(std::fabs(Iq0_vac_H[i] + rho_sans*rho_sans*Iq0_solv_H[i] - rho_sans*Iq0_mix_H[i]));
+    1386             :           }
+    1387             :         }
+    1388             :         // Form Factors
+    1389          40 :         for(unsigned k=0; k<numq; ++k) {
+    1390        7920 :           for(unsigned i=0; i<nres; ++i) {
+    1391        7884 :             if(!gpu) {
+    1392        7884 :               if(solv_res[i] == 0) { // hydrogen
+    1393        6246 :                 FF_value[i][k] = std::sqrt(std::fabs(FF_value_vacuum_H[atoi[i]][k] + rho_sans*rho_sans*FF_value_solv_H[atoi[i]][k] - rho_sans*FF_value_mixed_H[atoi[i]][k]))/Iq0;
+    1394             :               } else {
+    1395        1638 :                 if(deut_res[i] == 0) {
+    1396        1638 :                   FF_value[i][k] = std::sqrt(std::fabs(FF_value_vacuum_H[atoi[i]][k] + rho_sans_corr*rho_sans_corr*FF_value_solv_H[atoi[i]][k] - rho_sans_corr*FF_value_mixed_H[atoi[i]][k]))/Iq0;
+    1397             :                 } else {
+    1398           0 :                   FF_value[i][k] = std::sqrt(std::fabs(FF_value_vacuum_D[atoi[i]][k] + rho_sans_corr*rho_sans_corr*FF_value_solv_H[atoi[i]][k] - rho_sans_corr*FF_value_mixed_D[atoi[i]][k]))/Iq0;
+    1399             :                 }
+    1400             :               }
+    1401             :             } else {
+    1402           0 :               if(solv_res[i] == 0) { // hydrogen
+    1403           0 :                 FFf_value[k][i] = static_cast<float>(std::sqrt(std::fabs(FF_value_vacuum_H[atoi[i]][k] + rho_sans*rho_sans*FF_value_solv_H[atoi[i]][k] - rho_sans*FF_value_mixed_H[atoi[i]][k]))/Iq0);
+    1404             :               } else {
+    1405           0 :                 if(deut_res[i] == 0) {
+    1406           0 :                   FFf_value[k][i] = static_cast<float>(std::sqrt(std::fabs(FF_value_vacuum_H[atoi[i]][k] + rho_sans_corr*rho_sans_corr*FF_value_solv_H[atoi[i]][k] - rho_sans_corr*FF_value_mixed_H[atoi[i]][k]))/Iq0);
+    1407             :                 } else {
+    1408           0 :                   FFf_value[k][i] = static_cast<float>(std::sqrt(std::fabs(FF_value_vacuum_D[atoi[i]][k] + rho_sans_corr*rho_sans_corr*FF_value_solv_H[atoi[i]][k] - rho_sans_corr*FF_value_mixed_D[atoi[i]][k]))/Iq0);
+    1409             :                 }
+    1410             :               }
+    1411             :             }
+    1412             :           }
+    1413             :         }
+    1414           4 :         if(!gpu) {
+    1415          40 :           for(unsigned k=0; k<numq; ++k) {
+    1416          36 :             FF_rank[k]=0.;
+    1417        7920 :             for(unsigned i=0; i<nres; ++i) {
+    1418        7884 :               FF_rank[k]+=FF_value[i][k]*FF_value[i][k];
+    1419             :             }
+    1420             :           }
+    1421             :         }
+    1422             :       }
+    1423             :     }
+    1424             :     // not ONEBEAD
+    1425             :   } else {
+    1426       59898 :     for(unsigned i=0; i<size; ++i) {
+    1427       59716 :       beads_pos[i] = getPosition(i);
+    1428             :     }
+    1429         364 :     aa_deriv = std::vector<Vector>(size,(Vector(1,1,1)));
+    1430             :   }
+    1431             : 
+    1432         192 :   if(gpu) calculate_gpu(beads_pos, bd_deriv);
+    1433         192 :   else calculate_cpu(beads_pos, bd_deriv);
+    1434             : 
+    1435         192 :   if(getDoScore()) {
+    1436             :     /* Metainference */
+    1437         168 :     double score = getScore();
+    1438         168 :     setScore(score);
+    1439             :   }
+    1440             : 
+    1441        1968 :   for (unsigned k=0; k<numq; ++k) {
+    1442        1776 :     const unsigned kdx=k*beads_size;
+    1443        1776 :     Tensor deriv_box;
+    1444             :     Value* val;
+    1445        1776 :     if(!getDoScore()) {
+    1446         264 :       std::string num; Tools::convert(k,num);
+    1447         264 :       val=getPntrToComponent("q-"+num);
+    1448             : 
+    1449         264 :       if(onebead) {
+    1450             :         unsigned atom_id=0;
+    1451       19566 :         for(unsigned i=0; i<beads_size; ++i) {
+    1452      338670 :           for(unsigned j=0; j<atoms_per_bead[i]; ++j) {
+    1453      319194 :             setAtomsDerivatives(val, atom_id, Vector(aa_deriv[atom_id][0]*bd_deriv[kdx+i][0], \
+    1454      319194 :                                 aa_deriv[atom_id][1]*bd_deriv[kdx+i][1], \
+    1455      319194 :                                 aa_deriv[atom_id][2]*bd_deriv[kdx+i][2]) );
+    1456      319194 :             deriv_box += Tensor(getPosition(atom_id),Vector(aa_deriv[atom_id][0]*bd_deriv[kdx+i][0], \
+    1457      319194 :                                 aa_deriv[atom_id][1]*bd_deriv[kdx+i][1], \
+    1458      638388 :                                 aa_deriv[atom_id][2]*bd_deriv[kdx+i][2]) );
+    1459      319194 :             atom_id++;
+    1460             :           }
+    1461             :         }
+    1462             :       } else {
+    1463      311502 :         for(unsigned i=0; i<beads_size; ++i) {
+    1464      311328 :           setAtomsDerivatives(val, i, Vector(bd_deriv[kdx+i][0], \
+    1465      311328 :                                              bd_deriv[kdx+i][1], \
+    1466      311328 :                                              bd_deriv[kdx+i][2]) );
+    1467      622656 :           deriv_box += Tensor(getPosition(i),Vector(bd_deriv[kdx+i][0], \
+    1468      311328 :                               bd_deriv[kdx+i][1], \
+    1469      622656 :                               bd_deriv[kdx+i][2]) );
+    1470             :         }
+    1471             :       }
+    1472             :     } else {
+    1473        1512 :       val=getPntrToComponent("score");
+    1474        1512 :       if(onebead) {
+    1475             :         unsigned atom_id=0;
+    1476           0 :         for(unsigned i=0; i<beads_size; ++i) {
+    1477           0 :           for(unsigned j=0; j<atoms_per_bead[i]; ++j) {
+    1478           0 :             setAtomsDerivatives(val, atom_id, Vector(aa_deriv[atom_id][0]*bd_deriv[kdx+i][0]*getMetaDer(k),
+    1479           0 :                                 aa_deriv[atom_id][1]*bd_deriv[kdx+i][1]*getMetaDer(k),
+    1480           0 :                                 aa_deriv[atom_id][2]*bd_deriv[kdx+i][2]*getMetaDer(k)) );
+    1481           0 :             deriv_box += Tensor(getPosition(atom_id),Vector(aa_deriv[atom_id][0]*bd_deriv[kdx+i][0]*getMetaDer(k),
+    1482           0 :                                 aa_deriv[atom_id][1]*bd_deriv[kdx+i][1]*getMetaDer(k),
+    1483           0 :                                 aa_deriv[atom_id][2]*bd_deriv[kdx+i][2]*getMetaDer(k)) );
+    1484           0 :             atom_id++;
+    1485             :           }
+    1486             :         }
+    1487             :       } else {
+    1488      450828 :         for(unsigned i=0; i<beads_size; ++i) {
+    1489      449316 :           setAtomsDerivatives(val, i, Vector(bd_deriv[kdx+i][0]*getMetaDer(k),
+    1490      449316 :                                              bd_deriv[kdx+i][1]*getMetaDer(k),
+    1491      449316 :                                              bd_deriv[kdx+i][2]*getMetaDer(k)) );
+    1492      898632 :           deriv_box += Tensor(getPosition(i),Vector(bd_deriv[kdx+i][0]*getMetaDer(k),
+    1493      449316 :                               bd_deriv[kdx+i][1]*getMetaDer(k),
+    1494      898632 :                               bd_deriv[kdx+i][2]*getMetaDer(k)) );
+    1495             :         }
+    1496             :       }
+    1497             :     }
+    1498        1776 :     setBoxDerivatives(val, -deriv_box);
+    1499             :   }
+    1500         192 : }
+    1501             : 
+    1502         192 : void SAXS::update() {
+    1503             :   // write status file
+    1504         192 :   if(getWstride()>0&& (getStep()%getWstride()==0 || getCPT()) ) writeStatus();
+    1505         192 : }
+    1506             : 
+    1507          10 : unsigned SAXS::getOnebeadMapping(const PDB &pdb, const std::vector<AtomNumber> &atoms) {
+    1508          10 :   std::vector<std::string> chains; pdb.getChainNames( chains );
+    1509             :   std::vector<std::vector<std::string> > AtomResidueName;
+    1510             : 
+    1511          10 :   atoms_masses.resize(atoms.size());
+    1512          10 :   residue_atom.resize(atoms.size());
+    1513             : 
+    1514             :   // cycle over chains
+    1515          24 :   for(unsigned i=0; i<chains.size(); ++i) {
+    1516             :     unsigned start, end;
+    1517             :     std::string errmsg;
+    1518          14 :     pdb.getResidueRange(chains[i], start, end, errmsg);
+    1519          14 :     AtomResidueName.resize(2);
+    1520             :     // cycle over residues
+    1521        2110 :     for(unsigned res=start; res<=end; res++) {
+    1522        2096 :       std::string Rname = pdb.getResidueName(res, chains[i]);
+    1523        2096 :       Rname.erase(std::remove_if(Rname.begin(), Rname.end(), ::isspace),Rname.end());
+    1524        2096 :       std::vector<AtomNumber> res_atoms = pdb.getAtomsInResidue(res, chains[i]);
+    1525             :       unsigned first_time=1;
+    1526        2096 :       std::vector<std::vector<unsigned> > tmp_residue_atom; tmp_residue_atom.resize(3);
+    1527             :       // cycle over atoms
+    1528       37562 :       for(unsigned a=0; a<res_atoms.size(); a++) {
+    1529             :         // operations shared among all beads
+    1530       35466 :         std::string Aname=pdb.getAtomName(res_atoms[a]);
+    1531       35466 :         AtomResidueName[0].push_back(Aname);
+    1532       35466 :         AtomResidueName[1].push_back(Rname);
+    1533             :         char type;
+    1534       35466 :         char first = Aname.at(0);
+    1535             :         // We assume that element symbol is first letter, if not a number
+    1536       35466 :         if (!isdigit(first)) {
+    1537             :           type = first;
+    1538             :           // otherwise is the second
+    1539             :         } else {
+    1540           0 :           type = Aname.at(1);
+    1541             :         }
+    1542       35466 :         if (type == 'H') atoms_masses[res_atoms[a].index()] = 1.008;
+    1543       10384 :         else if(type == 'C') atoms_masses[res_atoms[a].index()] = 12.011;
+    1544        2772 :         else if(type == 'N') atoms_masses[res_atoms[a].index()] = 14.007;
+    1545        3270 :         else if(type == 'O') atoms_masses[res_atoms[a].index()] = 15.999;
+    1546          90 :         else if(type == 'S') atoms_masses[res_atoms[a].index()] = 32.065;
+    1547          32 :         else if(type == 'P') atoms_masses[res_atoms[a].index()] = 30.974;
+    1548             :         else {
+    1549           0 :           error("Unknown element in mass extraction\n");
+    1550             :         }
+    1551       70932 :         if(pdb.allowedResidue("protein",Rname)) {
+    1552       34390 :           if(first_time) {
+    1553        2060 :             atoms_per_bead.push_back(res_atoms.size());
+    1554             :             first_time = 0;
+    1555             :           }
+    1556       34390 :           residue_atom[res_atoms[a].index()] = atoms_per_bead.size()-1;
+    1557             :         } else {
+    1558             :           // check for nucleic acids
+    1559             :           // Pentose bead
+    1560        4840 :           if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  || Aname=="O3'"  ||
+    1561        3940 :               Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  || Aname=="C1'"  || Aname=="H5'"  ||
+    1562        3076 :               Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  || Aname=="H2'"  || Aname=="H2''" ||
+    1563        2660 :               Aname=="H2'2" || Aname=="H1'"  || Aname=="HO5'" || Aname=="HO3'" || Aname=="HO2'" ||
+    1564        3536 :               Aname=="H5'1" || Aname=="H5'2" || Aname=="HO'2" || Aname=="H2'1" || Aname=="H5T"  ||
+    1565             :               Aname=="H3T" ) {
+    1566         584 :             tmp_residue_atom[0].push_back(res_atoms[a].index());
+    1567             :           }
+    1568             :           // Nucleobase bead
+    1569        2172 :           else if(Aname=="N1"  || Aname=="N2"  || Aname=="N3"  || Aname=="N4"  || Aname=="N6"  ||
+    1570        1884 :                   Aname=="N7"  || Aname=="N9"  || Aname=="C2"  || Aname=="C4"  || Aname=="C5"  ||
+    1571        1272 :                   Aname=="C6"  || Aname=="C7"  || Aname=="C8"  || Aname=="O2"  || Aname=="O4"  ||
+    1572         912 :                   Aname=="O6"  || Aname=="H1"  || Aname=="H2"  || Aname=="H3"  || Aname=="H5"  ||
+    1573         480 :                   Aname=="H6"  || Aname=="H8"  || Aname=="H21" || Aname=="H22" || Aname=="H41" ||
+    1574         972 :                   Aname=="H42" || Aname=="H61" || Aname=="H62" || Aname=="H71" || Aname=="H72" ||
+    1575             :                   Aname=="H73" ) {
+    1576         396 :             tmp_residue_atom[1].push_back(res_atoms[a].index());
+    1577             :           }
+    1578             :           // PO2 bead
+    1579          96 :           else if(Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" || Aname=="O1P" ||
+    1580          96 :                   Aname=="O2P" || Aname=="O3P" ) {
+    1581          96 :             tmp_residue_atom[2].push_back(res_atoms[a].index());
+    1582             :           }
+    1583             :           // error
+    1584           0 :           else error("Atom name "+Aname+" cannot be indexed to any bead. Check the PDB.");
+    1585             :         }
+    1586             :       }
+    1587        4192 :       if(!pdb.allowedResidue("protein",Rname)) {
+    1588          36 :         atoms_per_bead.push_back(tmp_residue_atom[0].size());
+    1589         620 :         for(unsigned tmp_i=0; tmp_i<tmp_residue_atom[0].size(); tmp_i++) residue_atom[tmp_residue_atom[0][tmp_i]]=atoms_per_bead.size()-1;
+    1590          36 :         atoms_per_bead.push_back(tmp_residue_atom[1].size());
+    1591         432 :         for(unsigned tmp_i=0; tmp_i<tmp_residue_atom[1].size(); tmp_i++) residue_atom[tmp_residue_atom[1][tmp_i]]=atoms_per_bead.size()-1;
+    1592          36 :         if(tmp_residue_atom[2].size()>0) {
+    1593          32 :           atoms_per_bead.push_back(tmp_residue_atom[2].size());
+    1594         128 :           for(unsigned tmp_i=0; tmp_i<tmp_residue_atom[2].size(); tmp_i++) residue_atom[tmp_residue_atom[2][tmp_i]]=atoms_per_bead.size()-1;
+    1595             :         }
+    1596             :       }
+    1597        2096 :     }
+    1598             :   }
+    1599          10 :   readLCPOparam(AtomResidueName, atoms.size());
+    1600          10 :   return atoms_per_bead.size();
+    1601          10 : }
+    1602             : 
+    1603           8 : void SAXS::getMartiniFFparam(const std::vector<AtomNumber> &atoms, std::vector<std::vector<long double> > &parameter)
+    1604             : {
+    1605           8 :   parameter[ALA_BB].push_back(9.045);
+    1606           8 :   parameter[ALA_BB].push_back(-0.098114);
+    1607           8 :   parameter[ALA_BB].push_back(7.54281);
+    1608           8 :   parameter[ALA_BB].push_back(-1.97438);
+    1609           8 :   parameter[ALA_BB].push_back(-8.32689);
+    1610           8 :   parameter[ALA_BB].push_back(6.09318);
+    1611           8 :   parameter[ALA_BB].push_back(-1.18913);
+    1612             : 
+    1613           8 :   parameter[ARG_BB].push_back(10.729);
+    1614           8 :   parameter[ARG_BB].push_back(-0.0392574);
+    1615           8 :   parameter[ARG_BB].push_back(1.15382);
+    1616           8 :   parameter[ARG_BB].push_back(-0.155999);
+    1617           8 :   parameter[ARG_BB].push_back(-2.43619);
+    1618           8 :   parameter[ARG_BB].push_back(1.72922);
+    1619           8 :   parameter[ARG_BB].push_back(-0.33799);
+    1620             : 
+    1621           8 :   parameter[ARG_SC1].push_back(-2.796);
+    1622           8 :   parameter[ARG_SC1].push_back(0.472403);
+    1623           8 :   parameter[ARG_SC1].push_back(8.07424);
+    1624           8 :   parameter[ARG_SC1].push_back(4.37299);
+    1625           8 :   parameter[ARG_SC1].push_back(-10.7398);
+    1626           8 :   parameter[ARG_SC1].push_back(4.95677);
+    1627           8 :   parameter[ARG_SC1].push_back(-0.725797);
+    1628             : 
+    1629           8 :   parameter[ARG_SC2].push_back(15.396);
+    1630           8 :   parameter[ARG_SC2].push_back(0.0636736);
+    1631           8 :   parameter[ARG_SC2].push_back(-1.258);
+    1632           8 :   parameter[ARG_SC2].push_back(1.93135);
+    1633           8 :   parameter[ARG_SC2].push_back(-4.45031);
+    1634           8 :   parameter[ARG_SC2].push_back(2.49356);
+    1635           8 :   parameter[ARG_SC2].push_back(-0.410721);
+    1636             : 
+    1637           8 :   parameter[ASN_BB].push_back(10.738);
+    1638           8 :   parameter[ASN_BB].push_back(-0.0402162);
+    1639           8 :   parameter[ASN_BB].push_back(1.03007);
+    1640           8 :   parameter[ASN_BB].push_back(-0.254174);
+    1641           8 :   parameter[ASN_BB].push_back(-2.12015);
+    1642           8 :   parameter[ASN_BB].push_back(1.55535);
+    1643           8 :   parameter[ASN_BB].push_back(-0.30963);
+    1644             : 
+    1645           8 :   parameter[ASN_SC1].push_back(9.249);
+    1646           8 :   parameter[ASN_SC1].push_back(-0.0148678);
+    1647           8 :   parameter[ASN_SC1].push_back(5.52169);
+    1648           8 :   parameter[ASN_SC1].push_back(0.00853212);
+    1649           8 :   parameter[ASN_SC1].push_back(-6.71992);
+    1650           8 :   parameter[ASN_SC1].push_back(3.93622);
+    1651           8 :   parameter[ASN_SC1].push_back(-0.64973);
+    1652             : 
+    1653           8 :   parameter[ASP_BB].push_back(10.695);
+    1654           8 :   parameter[ASP_BB].push_back(-0.0410247);
+    1655           8 :   parameter[ASP_BB].push_back(1.03656);
+    1656           8 :   parameter[ASP_BB].push_back(-0.298558);
+    1657           8 :   parameter[ASP_BB].push_back(-2.06064);
+    1658           8 :   parameter[ASP_BB].push_back(1.53495);
+    1659           8 :   parameter[ASP_BB].push_back(-0.308365);
+    1660             : 
+    1661           8 :   parameter[ASP_SC1].push_back(9.476);
+    1662           8 :   parameter[ASP_SC1].push_back(-0.0254664);
+    1663           8 :   parameter[ASP_SC1].push_back(5.57899);
+    1664           8 :   parameter[ASP_SC1].push_back(-0.395027);
+    1665           8 :   parameter[ASP_SC1].push_back(-5.9407);
+    1666           8 :   parameter[ASP_SC1].push_back(3.48836);
+    1667           8 :   parameter[ASP_SC1].push_back(-0.569402);
+    1668             : 
+    1669           8 :   parameter[CYS_BB].push_back(10.698);
+    1670           8 :   parameter[CYS_BB].push_back(-0.0233493);
+    1671           8 :   parameter[CYS_BB].push_back(1.18257);
+    1672           8 :   parameter[CYS_BB].push_back(0.0684464);
+    1673           8 :   parameter[CYS_BB].push_back(-2.792);
+    1674           8 :   parameter[CYS_BB].push_back(1.88995);
+    1675           8 :   parameter[CYS_BB].push_back(-0.360229);
+    1676             : 
+    1677           8 :   parameter[CYS_SC1].push_back(8.199);
+    1678           8 :   parameter[CYS_SC1].push_back(-0.0261569);
+    1679           8 :   parameter[CYS_SC1].push_back(6.79677);
+    1680           8 :   parameter[CYS_SC1].push_back(-0.343845);
+    1681           8 :   parameter[CYS_SC1].push_back(-5.03578);
+    1682           8 :   parameter[CYS_SC1].push_back(2.7076);
+    1683           8 :   parameter[CYS_SC1].push_back(-0.420714);
+    1684             : 
+    1685           8 :   parameter[GLN_BB].push_back(10.728);
+    1686           8 :   parameter[GLN_BB].push_back(-0.0391984);
+    1687           8 :   parameter[GLN_BB].push_back(1.09264);
+    1688           8 :   parameter[GLN_BB].push_back(-0.261555);
+    1689           8 :   parameter[GLN_BB].push_back(-2.21245);
+    1690           8 :   parameter[GLN_BB].push_back(1.62071);
+    1691           8 :   parameter[GLN_BB].push_back(-0.322325);
+    1692             : 
+    1693           8 :   parameter[GLN_SC1].push_back(8.317);
+    1694           8 :   parameter[GLN_SC1].push_back(-0.229045);
+    1695           8 :   parameter[GLN_SC1].push_back(12.6338);
+    1696           8 :   parameter[GLN_SC1].push_back(-7.6719);
+    1697           8 :   parameter[GLN_SC1].push_back(-5.8376);
+    1698           8 :   parameter[GLN_SC1].push_back(5.53784);
+    1699           8 :   parameter[GLN_SC1].push_back(-1.12604);
+    1700             : 
+    1701           8 :   parameter[GLU_BB].push_back(10.694);
+    1702           8 :   parameter[GLU_BB].push_back(-0.0521961);
+    1703           8 :   parameter[GLU_BB].push_back(1.11153);
+    1704           8 :   parameter[GLU_BB].push_back(-0.491995);
+    1705           8 :   parameter[GLU_BB].push_back(-1.86236);
+    1706           8 :   parameter[GLU_BB].push_back(1.45332);
+    1707           8 :   parameter[GLU_BB].push_back(-0.29708);
+    1708             : 
+    1709           8 :   parameter[GLU_SC1].push_back(8.544);
+    1710           8 :   parameter[GLU_SC1].push_back(-0.249555);
+    1711           8 :   parameter[GLU_SC1].push_back(12.8031);
+    1712           8 :   parameter[GLU_SC1].push_back(-8.42696);
+    1713           8 :   parameter[GLU_SC1].push_back(-4.66486);
+    1714           8 :   parameter[GLU_SC1].push_back(4.90004);
+    1715           8 :   parameter[GLU_SC1].push_back(-1.01204);
+    1716             : 
+    1717           8 :   parameter[GLY_BB].push_back(9.977);
+    1718           8 :   parameter[GLY_BB].push_back(-0.0285799);
+    1719           8 :   parameter[GLY_BB].push_back(1.84236);
+    1720           8 :   parameter[GLY_BB].push_back(-0.0315192);
+    1721           8 :   parameter[GLY_BB].push_back(-2.88326);
+    1722           8 :   parameter[GLY_BB].push_back(1.87323);
+    1723           8 :   parameter[GLY_BB].push_back(-0.345773);
+    1724             : 
+    1725           8 :   parameter[HIS_BB].push_back(10.721);
+    1726           8 :   parameter[HIS_BB].push_back(-0.0379337);
+    1727           8 :   parameter[HIS_BB].push_back(1.06028);
+    1728           8 :   parameter[HIS_BB].push_back(-0.236143);
+    1729           8 :   parameter[HIS_BB].push_back(-2.17819);
+    1730           8 :   parameter[HIS_BB].push_back(1.58357);
+    1731           8 :   parameter[HIS_BB].push_back(-0.31345);
+    1732             : 
+    1733           8 :   parameter[HIS_SC1].push_back(-0.424);
+    1734           8 :   parameter[HIS_SC1].push_back(0.665176);
+    1735           8 :   parameter[HIS_SC1].push_back(3.4369);
+    1736           8 :   parameter[HIS_SC1].push_back(2.93795);
+    1737           8 :   parameter[HIS_SC1].push_back(-5.18288);
+    1738           8 :   parameter[HIS_SC1].push_back(2.12381);
+    1739           8 :   parameter[HIS_SC1].push_back(-0.284224);
+    1740             : 
+    1741           8 :   parameter[HIS_SC2].push_back(5.363);
+    1742           8 :   parameter[HIS_SC2].push_back(-0.0176945);
+    1743           8 :   parameter[HIS_SC2].push_back(2.9506);
+    1744           8 :   parameter[HIS_SC2].push_back(-0.387018);
+    1745           8 :   parameter[HIS_SC2].push_back(-1.83951);
+    1746           8 :   parameter[HIS_SC2].push_back(0.9703);
+    1747           8 :   parameter[HIS_SC2].push_back(-0.1458);
+    1748             : 
+    1749           8 :   parameter[HIS_SC3].push_back(5.784);
+    1750           8 :   parameter[HIS_SC3].push_back(-0.0293129);
+    1751           8 :   parameter[HIS_SC3].push_back(2.74167);
+    1752           8 :   parameter[HIS_SC3].push_back(-0.520875);
+    1753           8 :   parameter[HIS_SC3].push_back(-1.62949);
+    1754           8 :   parameter[HIS_SC3].push_back(0.902379);
+    1755           8 :   parameter[HIS_SC3].push_back(-0.139957);
+    1756             : 
+    1757           8 :   parameter[ILE_BB].push_back(10.699);
+    1758           8 :   parameter[ILE_BB].push_back(-0.0188962);
+    1759           8 :   parameter[ILE_BB].push_back(1.217);
+    1760           8 :   parameter[ILE_BB].push_back(0.242481);
+    1761           8 :   parameter[ILE_BB].push_back(-3.13898);
+    1762           8 :   parameter[ILE_BB].push_back(2.07916);
+    1763           8 :   parameter[ILE_BB].push_back(-0.392574);
+    1764             : 
+    1765           8 :   parameter[ILE_SC1].push_back(-4.448);
+    1766           8 :   parameter[ILE_SC1].push_back(1.20996);
+    1767           8 :   parameter[ILE_SC1].push_back(11.5141);
+    1768           8 :   parameter[ILE_SC1].push_back(6.98895);
+    1769           8 :   parameter[ILE_SC1].push_back(-19.1948);
+    1770           8 :   parameter[ILE_SC1].push_back(9.89207);
+    1771           8 :   parameter[ILE_SC1].push_back(-1.60877);
+    1772             : 
+    1773           8 :   parameter[LEU_BB].push_back(10.692);
+    1774           8 :   parameter[LEU_BB].push_back(-0.0414917);
+    1775           8 :   parameter[LEU_BB].push_back(1.1077);
+    1776           8 :   parameter[LEU_BB].push_back(-0.288062);
+    1777           8 :   parameter[LEU_BB].push_back(-2.17187);
+    1778           8 :   parameter[LEU_BB].push_back(1.59879);
+    1779           8 :   parameter[LEU_BB].push_back(-0.318545);
+    1780             : 
+    1781           8 :   parameter[LEU_SC1].push_back(-4.448);
+    1782           8 :   parameter[LEU_SC1].push_back(2.1063);
+    1783           8 :   parameter[LEU_SC1].push_back(6.72381);
+    1784           8 :   parameter[LEU_SC1].push_back(14.6954);
+    1785           8 :   parameter[LEU_SC1].push_back(-23.7197);
+    1786           8 :   parameter[LEU_SC1].push_back(10.7247);
+    1787           8 :   parameter[LEU_SC1].push_back(-1.59146);
+    1788             : 
+    1789           8 :   parameter[LYS_BB].push_back(10.706);
+    1790           8 :   parameter[LYS_BB].push_back(-0.0468629);
+    1791           8 :   parameter[LYS_BB].push_back(1.09477);
+    1792           8 :   parameter[LYS_BB].push_back(-0.432751);
+    1793           8 :   parameter[LYS_BB].push_back(-1.94335);
+    1794           8 :   parameter[LYS_BB].push_back(1.49109);
+    1795           8 :   parameter[LYS_BB].push_back(-0.302589);
+    1796             : 
+    1797           8 :   parameter[LYS_SC1].push_back(-2.796);
+    1798           8 :   parameter[LYS_SC1].push_back(0.508044);
+    1799           8 :   parameter[LYS_SC1].push_back(7.91436);
+    1800           8 :   parameter[LYS_SC1].push_back(4.54097);
+    1801           8 :   parameter[LYS_SC1].push_back(-10.8051);
+    1802           8 :   parameter[LYS_SC1].push_back(4.96204);
+    1803           8 :   parameter[LYS_SC1].push_back(-0.724414);
+    1804             : 
+    1805           8 :   parameter[LYS_SC2].push_back(3.070);
+    1806           8 :   parameter[LYS_SC2].push_back(-0.0101448);
+    1807           8 :   parameter[LYS_SC2].push_back(4.67994);
+    1808           8 :   parameter[LYS_SC2].push_back(-0.792529);
+    1809           8 :   parameter[LYS_SC2].push_back(-2.09142);
+    1810           8 :   parameter[LYS_SC2].push_back(1.02933);
+    1811           8 :   parameter[LYS_SC2].push_back(-0.137787);
+    1812             : 
+    1813           8 :   parameter[MET_BB].push_back(10.671);
+    1814           8 :   parameter[MET_BB].push_back(-0.0433724);
+    1815           8 :   parameter[MET_BB].push_back(1.13784);
+    1816           8 :   parameter[MET_BB].push_back(-0.40768);
+    1817           8 :   parameter[MET_BB].push_back(-2.00555);
+    1818           8 :   parameter[MET_BB].push_back(1.51673);
+    1819           8 :   parameter[MET_BB].push_back(-0.305547);
+    1820             : 
+    1821           8 :   parameter[MET_SC1].push_back(5.85);
+    1822           8 :   parameter[MET_SC1].push_back(-0.0485798);
+    1823           8 :   parameter[MET_SC1].push_back(17.0391);
+    1824           8 :   parameter[MET_SC1].push_back(-3.65327);
+    1825           8 :   parameter[MET_SC1].push_back(-13.174);
+    1826           8 :   parameter[MET_SC1].push_back(8.68286);
+    1827           8 :   parameter[MET_SC1].push_back(-1.56095);
+    1828             : 
+    1829           8 :   parameter[PHE_BB].push_back(10.741);
+    1830           8 :   parameter[PHE_BB].push_back(-0.0317275);
+    1831           8 :   parameter[PHE_BB].push_back(1.15599);
+    1832           8 :   parameter[PHE_BB].push_back(0.0276187);
+    1833           8 :   parameter[PHE_BB].push_back(-2.74757);
+    1834           8 :   parameter[PHE_BB].push_back(1.88783);
+    1835           8 :   parameter[PHE_BB].push_back(-0.363525);
+    1836             : 
+    1837           8 :   parameter[PHE_SC1].push_back(-0.636);
+    1838           8 :   parameter[PHE_SC1].push_back(0.527882);
+    1839           8 :   parameter[PHE_SC1].push_back(6.77612);
+    1840           8 :   parameter[PHE_SC1].push_back(3.18508);
+    1841           8 :   parameter[PHE_SC1].push_back(-8.92826);
+    1842           8 :   parameter[PHE_SC1].push_back(4.29752);
+    1843           8 :   parameter[PHE_SC1].push_back(-0.65187);
+    1844             : 
+    1845           8 :   parameter[PHE_SC2].push_back(-0.424);
+    1846           8 :   parameter[PHE_SC2].push_back(0.389174);
+    1847           8 :   parameter[PHE_SC2].push_back(4.11761);
+    1848           8 :   parameter[PHE_SC2].push_back(2.29527);
+    1849           8 :   parameter[PHE_SC2].push_back(-4.7652);
+    1850           8 :   parameter[PHE_SC2].push_back(1.97023);
+    1851           8 :   parameter[PHE_SC2].push_back(-0.262318);
+    1852             : 
+    1853           8 :   parameter[PHE_SC3].push_back(-0.424);
+    1854           8 :   parameter[PHE_SC3].push_back(0.38927);
+    1855           8 :   parameter[PHE_SC3].push_back(4.11708);
+    1856           8 :   parameter[PHE_SC3].push_back(2.29623);
+    1857           8 :   parameter[PHE_SC3].push_back(-4.76592);
+    1858           8 :   parameter[PHE_SC3].push_back(1.97055);
+    1859           8 :   parameter[PHE_SC3].push_back(-0.262381);
+    1860             : 
+    1861           8 :   parameter[PRO_BB].push_back(11.434);
+    1862           8 :   parameter[PRO_BB].push_back(-0.033323);
+    1863           8 :   parameter[PRO_BB].push_back(0.472014);
+    1864           8 :   parameter[PRO_BB].push_back(-0.290854);
+    1865           8 :   parameter[PRO_BB].push_back(-1.81409);
+    1866           8 :   parameter[PRO_BB].push_back(1.39751);
+    1867           8 :   parameter[PRO_BB].push_back(-0.280407);
+    1868             : 
+    1869           8 :   parameter[PRO_SC1].push_back(-2.796);
+    1870           8 :   parameter[PRO_SC1].push_back(0.95668);
+    1871           8 :   parameter[PRO_SC1].push_back(6.84197);
+    1872           8 :   parameter[PRO_SC1].push_back(6.43774);
+    1873           8 :   parameter[PRO_SC1].push_back(-12.5068);
+    1874           8 :   parameter[PRO_SC1].push_back(5.64597);
+    1875           8 :   parameter[PRO_SC1].push_back(-0.825206);
+    1876             : 
+    1877           8 :   parameter[SER_BB].push_back(10.699);
+    1878           8 :   parameter[SER_BB].push_back(-0.0325828);
+    1879           8 :   parameter[SER_BB].push_back(1.20329);
+    1880           8 :   parameter[SER_BB].push_back(-0.0674351);
+    1881           8 :   parameter[SER_BB].push_back(-2.60749);
+    1882           8 :   parameter[SER_BB].push_back(1.80318);
+    1883           8 :   parameter[SER_BB].push_back(-0.346803);
+    1884             : 
+    1885           8 :   parameter[SER_SC1].push_back(3.298);
+    1886           8 :   parameter[SER_SC1].push_back(-0.0366801);
+    1887           8 :   parameter[SER_SC1].push_back(5.11077);
+    1888           8 :   parameter[SER_SC1].push_back(-1.46774);
+    1889           8 :   parameter[SER_SC1].push_back(-1.48421);
+    1890           8 :   parameter[SER_SC1].push_back(0.800326);
+    1891           8 :   parameter[SER_SC1].push_back(-0.108314);
+    1892             : 
+    1893           8 :   parameter[THR_BB].push_back(10.697);
+    1894           8 :   parameter[THR_BB].push_back(-0.0242955);
+    1895           8 :   parameter[THR_BB].push_back(1.24671);
+    1896           8 :   parameter[THR_BB].push_back(0.146423);
+    1897           8 :   parameter[THR_BB].push_back(-2.97429);
+    1898           8 :   parameter[THR_BB].push_back(1.97513);
+    1899           8 :   parameter[THR_BB].push_back(-0.371479);
+    1900             : 
+    1901           8 :   parameter[THR_SC1].push_back(2.366);
+    1902           8 :   parameter[THR_SC1].push_back(0.0297604);
+    1903           8 :   parameter[THR_SC1].push_back(11.9216);
+    1904           8 :   parameter[THR_SC1].push_back(-9.32503);
+    1905           8 :   parameter[THR_SC1].push_back(1.9396);
+    1906           8 :   parameter[THR_SC1].push_back(0.0804861);
+    1907           8 :   parameter[THR_SC1].push_back(-0.0302721);
+    1908             : 
+    1909           8 :   parameter[TRP_BB].push_back(10.689);
+    1910           8 :   parameter[TRP_BB].push_back(-0.0265879);
+    1911           8 :   parameter[TRP_BB].push_back(1.17819);
+    1912           8 :   parameter[TRP_BB].push_back(0.0386457);
+    1913           8 :   parameter[TRP_BB].push_back(-2.75634);
+    1914           8 :   parameter[TRP_BB].push_back(1.88065);
+    1915           8 :   parameter[TRP_BB].push_back(-0.360217);
+    1916             : 
+    1917           8 :   parameter[TRP_SC1].push_back(0.084);
+    1918           8 :   parameter[TRP_SC1].push_back(0.752407);
+    1919           8 :   parameter[TRP_SC1].push_back(5.3802);
+    1920           8 :   parameter[TRP_SC1].push_back(4.09281);
+    1921           8 :   parameter[TRP_SC1].push_back(-9.28029);
+    1922           8 :   parameter[TRP_SC1].push_back(4.45923);
+    1923           8 :   parameter[TRP_SC1].push_back(-0.689008);
+    1924             : 
+    1925           8 :   parameter[TRP_SC2].push_back(5.739);
+    1926           8 :   parameter[TRP_SC2].push_back(0.0298492);
+    1927           8 :   parameter[TRP_SC2].push_back(4.60446);
+    1928           8 :   parameter[TRP_SC2].push_back(1.34463);
+    1929           8 :   parameter[TRP_SC2].push_back(-5.69968);
+    1930           8 :   parameter[TRP_SC2].push_back(2.84924);
+    1931           8 :   parameter[TRP_SC2].push_back(-0.433781);
+    1932             : 
+    1933           8 :   parameter[TRP_SC3].push_back(-0.424);
+    1934           8 :   parameter[TRP_SC3].push_back(0.388576);
+    1935           8 :   parameter[TRP_SC3].push_back(4.11859);
+    1936           8 :   parameter[TRP_SC3].push_back(2.29485);
+    1937           8 :   parameter[TRP_SC3].push_back(-4.76255);
+    1938           8 :   parameter[TRP_SC3].push_back(1.96849);
+    1939           8 :   parameter[TRP_SC3].push_back(-0.262015);
+    1940             : 
+    1941           8 :   parameter[TRP_SC4].push_back(-0.424);
+    1942           8 :   parameter[TRP_SC4].push_back(0.387685);
+    1943           8 :   parameter[TRP_SC4].push_back(4.12153);
+    1944           8 :   parameter[TRP_SC4].push_back(2.29144);
+    1945           8 :   parameter[TRP_SC4].push_back(-4.7589);
+    1946           8 :   parameter[TRP_SC4].push_back(1.96686);
+    1947           8 :   parameter[TRP_SC4].push_back(-0.261786);
+    1948             : 
+    1949           8 :   parameter[TYR_BB].push_back(10.689);
+    1950           8 :   parameter[TYR_BB].push_back(-0.0193526);
+    1951           8 :   parameter[TYR_BB].push_back(1.18241);
+    1952           8 :   parameter[TYR_BB].push_back(0.207318);
+    1953           8 :   parameter[TYR_BB].push_back(-3.0041);
+    1954           8 :   parameter[TYR_BB].push_back(1.99335);
+    1955           8 :   parameter[TYR_BB].push_back(-0.376482);
+    1956             : 
+    1957           8 :   parameter[TYR_SC1].push_back(-0.636);
+    1958           8 :   parameter[TYR_SC1].push_back(0.528902);
+    1959           8 :   parameter[TYR_SC1].push_back(6.78168);
+    1960           8 :   parameter[TYR_SC1].push_back(3.17769);
+    1961           8 :   parameter[TYR_SC1].push_back(-8.93667);
+    1962           8 :   parameter[TYR_SC1].push_back(4.30692);
+    1963           8 :   parameter[TYR_SC1].push_back(-0.653993);
+    1964             : 
+    1965           8 :   parameter[TYR_SC2].push_back(-0.424);
+    1966           8 :   parameter[TYR_SC2].push_back(0.388811);
+    1967           8 :   parameter[TYR_SC2].push_back(4.11851);
+    1968           8 :   parameter[TYR_SC2].push_back(2.29545);
+    1969           8 :   parameter[TYR_SC2].push_back(-4.7668);
+    1970           8 :   parameter[TYR_SC2].push_back(1.97131);
+    1971           8 :   parameter[TYR_SC2].push_back(-0.262534);
+    1972             : 
+    1973           8 :   parameter[TYR_SC3].push_back(4.526);
+    1974           8 :   parameter[TYR_SC3].push_back(-0.00381305);
+    1975           8 :   parameter[TYR_SC3].push_back(5.8567);
+    1976           8 :   parameter[TYR_SC3].push_back(-0.214086);
+    1977           8 :   parameter[TYR_SC3].push_back(-4.63649);
+    1978           8 :   parameter[TYR_SC3].push_back(2.52869);
+    1979           8 :   parameter[TYR_SC3].push_back(-0.39894);
+    1980             : 
+    1981           8 :   parameter[VAL_BB].push_back(10.691);
+    1982           8 :   parameter[VAL_BB].push_back(-0.0162929);
+    1983           8 :   parameter[VAL_BB].push_back(1.24446);
+    1984           8 :   parameter[VAL_BB].push_back(0.307914);
+    1985           8 :   parameter[VAL_BB].push_back(-3.27446);
+    1986           8 :   parameter[VAL_BB].push_back(2.14788);
+    1987           8 :   parameter[VAL_BB].push_back(-0.403259);
+    1988             : 
+    1989           8 :   parameter[VAL_SC1].push_back(-3.516);
+    1990           8 :   parameter[VAL_SC1].push_back(1.62307);
+    1991           8 :   parameter[VAL_SC1].push_back(5.43064);
+    1992           8 :   parameter[VAL_SC1].push_back(9.28809);
+    1993           8 :   parameter[VAL_SC1].push_back(-14.9927);
+    1994           8 :   parameter[VAL_SC1].push_back(6.6133);
+    1995           8 :   parameter[VAL_SC1].push_back(-0.964977);
+    1996             : 
+    1997           8 :   parameter[A_BB1].push_back(32.88500000);
+    1998           8 :   parameter[A_BB1].push_back(0.08339900);
+    1999           8 :   parameter[A_BB1].push_back(-7.36054400);
+    2000           8 :   parameter[A_BB1].push_back(2.19220300);
+    2001           8 :   parameter[A_BB1].push_back(-3.56523400);
+    2002           8 :   parameter[A_BB1].push_back(2.33326900);
+    2003           8 :   parameter[A_BB1].push_back(-0.39785500);
+    2004             : 
+    2005           8 :   parameter[A_BB2].push_back(3.80600000);
+    2006           8 :   parameter[A_BB2].push_back(-0.10727600);
+    2007           8 :   parameter[A_BB2].push_back(9.58854100);
+    2008           8 :   parameter[A_BB2].push_back(-6.23740500);
+    2009           8 :   parameter[A_BB2].push_back(-0.48267300);
+    2010           8 :   parameter[A_BB2].push_back(1.14119500);
+    2011           8 :   parameter[A_BB2].push_back(-0.21385600);
+    2012             : 
+    2013           8 :   parameter[A_BB3].push_back(3.59400000);
+    2014           8 :   parameter[A_BB3].push_back(0.04537300);
+    2015           8 :   parameter[A_BB3].push_back(9.59178900);
+    2016           8 :   parameter[A_BB3].push_back(-1.29202200);
+    2017           8 :   parameter[A_BB3].push_back(-7.10851000);
+    2018           8 :   parameter[A_BB3].push_back(4.05571200);
+    2019           8 :   parameter[A_BB3].push_back(-0.63372500);
+    2020             : 
+    2021           8 :   parameter[A_SC1].push_back(6.67100000);
+    2022           8 :   parameter[A_SC1].push_back(-0.00855300);
+    2023           8 :   parameter[A_SC1].push_back(1.63222400);
+    2024           8 :   parameter[A_SC1].push_back(-0.06466200);
+    2025           8 :   parameter[A_SC1].push_back(-1.48694200);
+    2026           8 :   parameter[A_SC1].push_back(0.78544600);
+    2027           8 :   parameter[A_SC1].push_back(-0.12083500);
+    2028             : 
+    2029           8 :   parameter[A_SC2].push_back(5.95100000);
+    2030           8 :   parameter[A_SC2].push_back(-0.02606600);
+    2031           8 :   parameter[A_SC2].push_back(2.54399900);
+    2032           8 :   parameter[A_SC2].push_back(-0.48436900);
+    2033           8 :   parameter[A_SC2].push_back(-1.55357400);
+    2034           8 :   parameter[A_SC2].push_back(0.86466900);
+    2035           8 :   parameter[A_SC2].push_back(-0.13509000);
+    2036             : 
+    2037           8 :   parameter[A_SC3].push_back(11.39400000);
+    2038           8 :   parameter[A_SC3].push_back(0.00871300);
+    2039           8 :   parameter[A_SC3].push_back(-0.23891300);
+    2040           8 :   parameter[A_SC3].push_back(0.48919400);
+    2041           8 :   parameter[A_SC3].push_back(-1.75289400);
+    2042           8 :   parameter[A_SC3].push_back(0.99267500);
+    2043           8 :   parameter[A_SC3].push_back(-0.16291300);
+    2044             : 
+    2045           8 :   parameter[A_SC4].push_back(6.45900000);
+    2046           8 :   parameter[A_SC4].push_back(0.01990600);
+    2047           8 :   parameter[A_SC4].push_back(4.17970400);
+    2048           8 :   parameter[A_SC4].push_back(0.97629900);
+    2049           8 :   parameter[A_SC4].push_back(-5.03297800);
+    2050           8 :   parameter[A_SC4].push_back(2.55576700);
+    2051           8 :   parameter[A_SC4].push_back(-0.39150500);
+    2052             : 
+    2053           8 :   parameter[A_3TE].push_back(4.23000000);
+    2054           8 :   parameter[A_3TE].push_back(0.00064800);
+    2055           8 :   parameter[A_3TE].push_back(0.92124600);
+    2056           8 :   parameter[A_3TE].push_back(0.08064300);
+    2057           8 :   parameter[A_3TE].push_back(-0.39054400);
+    2058           8 :   parameter[A_3TE].push_back(0.12429100);
+    2059           8 :   parameter[A_3TE].push_back(-0.01122700);
+    2060             : 
+    2061           8 :   parameter[A_5TE].push_back(4.23000000);
+    2062           8 :   parameter[A_5TE].push_back(0.00039300);
+    2063           8 :   parameter[A_5TE].push_back(0.92305100);
+    2064           8 :   parameter[A_5TE].push_back(0.07747500);
+    2065           8 :   parameter[A_5TE].push_back(-0.38792100);
+    2066           8 :   parameter[A_5TE].push_back(0.12323800);
+    2067           8 :   parameter[A_5TE].push_back(-0.01106600);
+    2068             : 
+    2069           8 :   parameter[A_TE3].push_back(7.82400000);
+    2070           8 :   parameter[A_TE3].push_back(-0.04881000);
+    2071           8 :   parameter[A_TE3].push_back(8.21557900);
+    2072           8 :   parameter[A_TE3].push_back(-0.89491400);
+    2073           8 :   parameter[A_TE3].push_back(-9.54293700);
+    2074           8 :   parameter[A_TE3].push_back(6.33122200);
+    2075           8 :   parameter[A_TE3].push_back(-1.16672900);
+    2076             : 
+    2077           8 :   parameter[A_TE5].push_back(8.03600000);
+    2078           8 :   parameter[A_TE5].push_back(0.01641200);
+    2079           8 :   parameter[A_TE5].push_back(5.14902200);
+    2080           8 :   parameter[A_TE5].push_back(0.83419700);
+    2081           8 :   parameter[A_TE5].push_back(-7.59068300);
+    2082           8 :   parameter[A_TE5].push_back(4.52063200);
+    2083           8 :   parameter[A_TE5].push_back(-0.78260800);
+    2084             : 
+    2085           8 :   parameter[C_BB1].push_back(32.88500000);
+    2086           8 :   parameter[C_BB1].push_back(0.08311100);
+    2087           8 :   parameter[C_BB1].push_back(-7.35432100);
+    2088           8 :   parameter[C_BB1].push_back(2.18610000);
+    2089           8 :   parameter[C_BB1].push_back(-3.55788300);
+    2090           8 :   parameter[C_BB1].push_back(2.32918700);
+    2091           8 :   parameter[C_BB1].push_back(-0.39720000);
+    2092             : 
+    2093           8 :   parameter[C_BB2].push_back(3.80600000);
+    2094           8 :   parameter[C_BB2].push_back(-0.10808100);
+    2095           8 :   parameter[C_BB2].push_back(9.61612600);
+    2096           8 :   parameter[C_BB2].push_back(-6.28595400);
+    2097           8 :   parameter[C_BB2].push_back(-0.45187000);
+    2098           8 :   parameter[C_BB2].push_back(1.13326000);
+    2099           8 :   parameter[C_BB2].push_back(-0.21320300);
+    2100             : 
+    2101           8 :   parameter[C_BB3].push_back(3.59400000);
+    2102           8 :   parameter[C_BB3].push_back(0.04484200);
+    2103           8 :   parameter[C_BB3].push_back(9.61919800);
+    2104           8 :   parameter[C_BB3].push_back(-1.33582800);
+    2105           8 :   parameter[C_BB3].push_back(-7.07200400);
+    2106           8 :   parameter[C_BB3].push_back(4.03952900);
+    2107           8 :   parameter[C_BB3].push_back(-0.63098200);
+    2108             : 
+    2109           8 :   parameter[C_SC1].push_back(5.95100000);
+    2110           8 :   parameter[C_SC1].push_back(-0.02911300);
+    2111           8 :   parameter[C_SC1].push_back(2.59700400);
+    2112           8 :   parameter[C_SC1].push_back(-0.55507700);
+    2113           8 :   parameter[C_SC1].push_back(-1.56344600);
+    2114           8 :   parameter[C_SC1].push_back(0.88956200);
+    2115           8 :   parameter[C_SC1].push_back(-0.14061300);
+    2116             : 
+    2117           8 :   parameter[C_SC2].push_back(11.62100000);
+    2118           8 :   parameter[C_SC2].push_back(0.01366100);
+    2119           8 :   parameter[C_SC2].push_back(-0.25959200);
+    2120           8 :   parameter[C_SC2].push_back(0.48918300);
+    2121           8 :   parameter[C_SC2].push_back(-1.52550500);
+    2122           8 :   parameter[C_SC2].push_back(0.83644100);
+    2123           8 :   parameter[C_SC2].push_back(-0.13407300);
+    2124             : 
+    2125           8 :   parameter[C_SC3].push_back(5.01900000);
+    2126           8 :   parameter[C_SC3].push_back(-0.03276100);
+    2127           8 :   parameter[C_SC3].push_back(5.53776900);
+    2128           8 :   parameter[C_SC3].push_back(-0.95105000);
+    2129           8 :   parameter[C_SC3].push_back(-3.71130800);
+    2130           8 :   parameter[C_SC3].push_back(2.16146000);
+    2131           8 :   parameter[C_SC3].push_back(-0.34918600);
+    2132             : 
+    2133           8 :   parameter[C_3TE].push_back(4.23000000);
+    2134           8 :   parameter[C_3TE].push_back(0.00057300);
+    2135           8 :   parameter[C_3TE].push_back(0.92174800);
+    2136           8 :   parameter[C_3TE].push_back(0.07964500);
+    2137           8 :   parameter[C_3TE].push_back(-0.38965700);
+    2138           8 :   parameter[C_3TE].push_back(0.12392500);
+    2139           8 :   parameter[C_3TE].push_back(-0.01117000);
+    2140             : 
+    2141           8 :   parameter[C_5TE].push_back(4.23000000);
+    2142           8 :   parameter[C_5TE].push_back(0.00071000);
+    2143           8 :   parameter[C_5TE].push_back(0.92082800);
+    2144           8 :   parameter[C_5TE].push_back(0.08150600);
+    2145           8 :   parameter[C_5TE].push_back(-0.39127000);
+    2146           8 :   parameter[C_5TE].push_back(0.12455900);
+    2147           8 :   parameter[C_5TE].push_back(-0.01126300);
+    2148             : 
+    2149           8 :   parameter[C_TE3].push_back(7.82400000);
+    2150           8 :   parameter[C_TE3].push_back(-0.05848300);
+    2151           8 :   parameter[C_TE3].push_back(8.29319900);
+    2152           8 :   parameter[C_TE3].push_back(-1.12563800);
+    2153           8 :   parameter[C_TE3].push_back(-9.42197600);
+    2154           8 :   parameter[C_TE3].push_back(6.35441700);
+    2155           8 :   parameter[C_TE3].push_back(-1.18356900);
+    2156             : 
+    2157           8 :   parameter[C_TE5].push_back(8.03600000);
+    2158           8 :   parameter[C_TE5].push_back(0.00493500);
+    2159           8 :   parameter[C_TE5].push_back(4.92622000);
+    2160           8 :   parameter[C_TE5].push_back(0.64810700);
+    2161           8 :   parameter[C_TE5].push_back(-7.05100000);
+    2162           8 :   parameter[C_TE5].push_back(4.26064400);
+    2163           8 :   parameter[C_TE5].push_back(-0.74819100);
+    2164             : 
+    2165           8 :   parameter[G_BB1].push_back(32.88500000);
+    2166           8 :   parameter[G_BB1].push_back(0.08325400);
+    2167           8 :   parameter[G_BB1].push_back(-7.35736000);
+    2168           8 :   parameter[G_BB1].push_back(2.18914800);
+    2169           8 :   parameter[G_BB1].push_back(-3.56154800);
+    2170           8 :   parameter[G_BB1].push_back(2.33120600);
+    2171           8 :   parameter[G_BB1].push_back(-0.39752300);
+    2172             : 
+    2173           8 :   parameter[G_BB2].push_back(3.80600000);
+    2174           8 :   parameter[G_BB2].push_back(-0.10788300);
+    2175           8 :   parameter[G_BB2].push_back(9.60930800);
+    2176           8 :   parameter[G_BB2].push_back(-6.27402500);
+    2177           8 :   parameter[G_BB2].push_back(-0.46192700);
+    2178           8 :   parameter[G_BB2].push_back(1.13737000);
+    2179           8 :   parameter[G_BB2].push_back(-0.21383100);
+    2180             : 
+    2181           8 :   parameter[G_BB3].push_back(3.59400000);
+    2182           8 :   parameter[G_BB3].push_back(0.04514500);
+    2183           8 :   parameter[G_BB3].push_back(9.61234700);
+    2184           8 :   parameter[G_BB3].push_back(-1.31542100);
+    2185           8 :   parameter[G_BB3].push_back(-7.09150500);
+    2186           8 :   parameter[G_BB3].push_back(4.04706200);
+    2187           8 :   parameter[G_BB3].push_back(-0.63201000);
+    2188             : 
+    2189           8 :   parameter[G_SC1].push_back(6.67100000);
+    2190           8 :   parameter[G_SC1].push_back(-0.00863200);
+    2191           8 :   parameter[G_SC1].push_back(1.63252300);
+    2192           8 :   parameter[G_SC1].push_back(-0.06567200);
+    2193           8 :   parameter[G_SC1].push_back(-1.48680500);
+    2194           8 :   parameter[G_SC1].push_back(0.78565600);
+    2195           8 :   parameter[G_SC1].push_back(-0.12088900);
+    2196             : 
+    2197           8 :   parameter[G_SC2].push_back(11.39400000);
+    2198           8 :   parameter[G_SC2].push_back(0.00912200);
+    2199           8 :   parameter[G_SC2].push_back(-0.22869000);
+    2200           8 :   parameter[G_SC2].push_back(0.49616400);
+    2201           8 :   parameter[G_SC2].push_back(-1.75039000);
+    2202           8 :   parameter[G_SC2].push_back(0.98649200);
+    2203           8 :   parameter[G_SC2].push_back(-0.16141600);
+    2204             : 
+    2205           8 :   parameter[G_SC3].push_back(10.90100000);
+    2206           8 :   parameter[G_SC3].push_back(0.02208700);
+    2207           8 :   parameter[G_SC3].push_back(0.17032800);
+    2208           8 :   parameter[G_SC3].push_back(0.73280800);
+    2209           8 :   parameter[G_SC3].push_back(-1.95292000);
+    2210           8 :   parameter[G_SC3].push_back(0.98357600);
+    2211           8 :   parameter[G_SC3].push_back(-0.14790900);
+    2212             : 
+    2213           8 :   parameter[G_SC4].push_back(6.45900000);
+    2214           8 :   parameter[G_SC4].push_back(0.02023700);
+    2215           8 :   parameter[G_SC4].push_back(4.17655400);
+    2216           8 :   parameter[G_SC4].push_back(0.98731800);
+    2217           8 :   parameter[G_SC4].push_back(-5.04352800);
+    2218           8 :   parameter[G_SC4].push_back(2.56059400);
+    2219           8 :   parameter[G_SC4].push_back(-0.39234300);
+    2220             : 
+    2221           8 :   parameter[G_3TE].push_back(4.23000000);
+    2222           8 :   parameter[G_3TE].push_back(0.00066300);
+    2223           8 :   parameter[G_3TE].push_back(0.92118800);
+    2224           8 :   parameter[G_3TE].push_back(0.08062700);
+    2225           8 :   parameter[G_3TE].push_back(-0.39041600);
+    2226           8 :   parameter[G_3TE].push_back(0.12419400);
+    2227           8 :   parameter[G_3TE].push_back(-0.01120500);
+    2228             : 
+    2229           8 :   parameter[G_5TE].push_back(4.23000000);
+    2230           8 :   parameter[G_5TE].push_back(0.00062800);
+    2231           8 :   parameter[G_5TE].push_back(0.92133500);
+    2232           8 :   parameter[G_5TE].push_back(0.08029900);
+    2233           8 :   parameter[G_5TE].push_back(-0.39015300);
+    2234           8 :   parameter[G_5TE].push_back(0.12411600);
+    2235           8 :   parameter[G_5TE].push_back(-0.01119900);
+    2236             : 
+    2237           8 :   parameter[G_TE3].push_back(7.82400000);
+    2238           8 :   parameter[G_TE3].push_back(-0.05177400);
+    2239           8 :   parameter[G_TE3].push_back(8.34606700);
+    2240           8 :   parameter[G_TE3].push_back(-1.02936300);
+    2241           8 :   parameter[G_TE3].push_back(-9.55211900);
+    2242           8 :   parameter[G_TE3].push_back(6.37776600);
+    2243           8 :   parameter[G_TE3].push_back(-1.17898000);
+    2244             : 
+    2245           8 :   parameter[G_TE5].push_back(8.03600000);
+    2246           8 :   parameter[G_TE5].push_back(0.00525100);
+    2247           8 :   parameter[G_TE5].push_back(4.71070600);
+    2248           8 :   parameter[G_TE5].push_back(0.66746900);
+    2249           8 :   parameter[G_TE5].push_back(-6.72538700);
+    2250           8 :   parameter[G_TE5].push_back(4.03644100);
+    2251           8 :   parameter[G_TE5].push_back(-0.70605700);
+    2252             : 
+    2253           8 :   parameter[U_BB1].push_back(32.88500000);
+    2254           8 :   parameter[U_BB1].push_back(0.08321400);
+    2255           8 :   parameter[U_BB1].push_back(-7.35634900);
+    2256           8 :   parameter[U_BB1].push_back(2.18826800);
+    2257           8 :   parameter[U_BB1].push_back(-3.56047400);
+    2258           8 :   parameter[U_BB1].push_back(2.33064700);
+    2259           8 :   parameter[U_BB1].push_back(-0.39744000);
+    2260             : 
+    2261           8 :   parameter[U_BB2].push_back(3.80600000);
+    2262           8 :   parameter[U_BB2].push_back(-0.10773100);
+    2263           8 :   parameter[U_BB2].push_back(9.60099900);
+    2264           8 :   parameter[U_BB2].push_back(-6.26131900);
+    2265           8 :   parameter[U_BB2].push_back(-0.46668300);
+    2266           8 :   parameter[U_BB2].push_back(1.13698100);
+    2267           8 :   parameter[U_BB2].push_back(-0.21351600);
+    2268             : 
+    2269           8 :   parameter[U_BB3].push_back(3.59400000);
+    2270           8 :   parameter[U_BB3].push_back(0.04544300);
+    2271           8 :   parameter[U_BB3].push_back(9.59625900);
+    2272           8 :   parameter[U_BB3].push_back(-1.29222200);
+    2273           8 :   parameter[U_BB3].push_back(-7.11143200);
+    2274           8 :   parameter[U_BB3].push_back(4.05687700);
+    2275           8 :   parameter[U_BB3].push_back(-0.63382800);
+    2276             : 
+    2277           8 :   parameter[U_SC1].push_back(5.95100000);
+    2278           8 :   parameter[U_SC1].push_back(-0.02924500);
+    2279           8 :   parameter[U_SC1].push_back(2.59668700);
+    2280           8 :   parameter[U_SC1].push_back(-0.56118700);
+    2281           8 :   parameter[U_SC1].push_back(-1.56477100);
+    2282           8 :   parameter[U_SC1].push_back(0.89265100);
+    2283           8 :   parameter[U_SC1].push_back(-0.14130800);
+    2284             : 
+    2285           8 :   parameter[U_SC2].push_back(10.90100000);
+    2286           8 :   parameter[U_SC2].push_back(0.02178900);
+    2287           8 :   parameter[U_SC2].push_back(0.18839000);
+    2288           8 :   parameter[U_SC2].push_back(0.72223100);
+    2289           8 :   parameter[U_SC2].push_back(-1.92581600);
+    2290           8 :   parameter[U_SC2].push_back(0.96654300);
+    2291           8 :   parameter[U_SC2].push_back(-0.14501300);
+    2292             : 
+    2293           8 :   parameter[U_SC3].push_back(5.24600000);
+    2294           8 :   parameter[U_SC3].push_back(-0.04586500);
+    2295           8 :   parameter[U_SC3].push_back(5.89978100);
+    2296           8 :   parameter[U_SC3].push_back(-1.50664700);
+    2297           8 :   parameter[U_SC3].push_back(-3.17054400);
+    2298           8 :   parameter[U_SC3].push_back(1.93717100);
+    2299           8 :   parameter[U_SC3].push_back(-0.31701000);
+    2300             : 
+    2301           8 :   parameter[U_3TE].push_back(4.23000000);
+    2302           8 :   parameter[U_3TE].push_back(0.00067500);
+    2303           8 :   parameter[U_3TE].push_back(0.92102300);
+    2304           8 :   parameter[U_3TE].push_back(0.08100800);
+    2305           8 :   parameter[U_3TE].push_back(-0.39084300);
+    2306           8 :   parameter[U_3TE].push_back(0.12441900);
+    2307           8 :   parameter[U_3TE].push_back(-0.01124900);
+    2308             : 
+    2309           8 :   parameter[U_5TE].push_back(4.23000000);
+    2310           8 :   parameter[U_5TE].push_back(0.00059000);
+    2311           8 :   parameter[U_5TE].push_back(0.92154600);
+    2312           8 :   parameter[U_5TE].push_back(0.07968200);
+    2313           8 :   parameter[U_5TE].push_back(-0.38950100);
+    2314           8 :   parameter[U_5TE].push_back(0.12382500);
+    2315           8 :   parameter[U_5TE].push_back(-0.01115100);
+    2316             : 
+    2317           8 :   parameter[U_TE3].push_back(7.82400000);
+    2318           8 :   parameter[U_TE3].push_back(-0.02968100);
+    2319           8 :   parameter[U_TE3].push_back(7.93783200);
+    2320           8 :   parameter[U_TE3].push_back(-0.33078100);
+    2321           8 :   parameter[U_TE3].push_back(-10.14120200);
+    2322           8 :   parameter[U_TE3].push_back(6.63334700);
+    2323           8 :   parameter[U_TE3].push_back(-1.22111200);
+    2324             : 
+    2325           8 :   parameter[U_TE5].push_back(8.03600000);
+    2326           8 :   parameter[U_TE5].push_back(-0.00909700);
+    2327           8 :   parameter[U_TE5].push_back(4.33193500);
+    2328           8 :   parameter[U_TE5].push_back(0.43416500);
+    2329           8 :   parameter[U_TE5].push_back(-5.80831400);
+    2330           8 :   parameter[U_TE5].push_back(3.52438800);
+    2331           8 :   parameter[U_TE5].push_back(-0.62382400);
+    2332             : 
+    2333           8 :   parameter[DA_BB1].push_back(32.88500000);
+    2334           8 :   parameter[DA_BB1].push_back(0.08179900);
+    2335           8 :   parameter[DA_BB1].push_back(-7.31735900);
+    2336           8 :   parameter[DA_BB1].push_back(2.15614500);
+    2337           8 :   parameter[DA_BB1].push_back(-3.52263200);
+    2338           8 :   parameter[DA_BB1].push_back(2.30604700);
+    2339           8 :   parameter[DA_BB1].push_back(-0.39270100);
+    2340             : 
+    2341           8 :   parameter[DA_BB2].push_back(3.80600000);
+    2342           8 :   parameter[DA_BB2].push_back(-0.10597700);
+    2343           8 :   parameter[DA_BB2].push_back(9.52537500);
+    2344           8 :   parameter[DA_BB2].push_back(-6.12991000);
+    2345           8 :   parameter[DA_BB2].push_back(-0.54092600);
+    2346           8 :   parameter[DA_BB2].push_back(1.15429100);
+    2347           8 :   parameter[DA_BB2].push_back(-0.21503500);
+    2348             : 
+    2349           8 :   parameter[DA_BB3].push_back(-1.35600000);
+    2350           8 :   parameter[DA_BB3].push_back(0.58928300);
+    2351           8 :   parameter[DA_BB3].push_back(6.71894100);
+    2352           8 :   parameter[DA_BB3].push_back(4.14050900);
+    2353           8 :   parameter[DA_BB3].push_back(-9.65859900);
+    2354           8 :   parameter[DA_BB3].push_back(4.43185000);
+    2355           8 :   parameter[DA_BB3].push_back(-0.64657300);
+    2356             : 
+    2357           8 :   parameter[DA_SC1].push_back(6.67100000);
+    2358           8 :   parameter[DA_SC1].push_back(-0.00871400);
+    2359           8 :   parameter[DA_SC1].push_back(1.63289100);
+    2360           8 :   parameter[DA_SC1].push_back(-0.06637700);
+    2361           8 :   parameter[DA_SC1].push_back(-1.48632900);
+    2362           8 :   parameter[DA_SC1].push_back(0.78551800);
+    2363           8 :   parameter[DA_SC1].push_back(-0.12087300);
+    2364             : 
+    2365           8 :   parameter[DA_SC2].push_back(5.95100000);
+    2366           8 :   parameter[DA_SC2].push_back(-0.02634300);
+    2367           8 :   parameter[DA_SC2].push_back(2.54864300);
+    2368           8 :   parameter[DA_SC2].push_back(-0.49015800);
+    2369           8 :   parameter[DA_SC2].push_back(-1.55386900);
+    2370           8 :   parameter[DA_SC2].push_back(0.86630200);
+    2371           8 :   parameter[DA_SC2].push_back(-0.13546200);
+    2372             : 
+    2373           8 :   parameter[DA_SC3].push_back(11.39400000);
+    2374           8 :   parameter[DA_SC3].push_back(0.00859500);
+    2375           8 :   parameter[DA_SC3].push_back(-0.25471400);
+    2376           8 :   parameter[DA_SC3].push_back(0.48718800);
+    2377           8 :   parameter[DA_SC3].push_back(-1.74520000);
+    2378           8 :   parameter[DA_SC3].push_back(0.99246200);
+    2379           8 :   parameter[DA_SC3].push_back(-0.16351900);
+    2380             : 
+    2381           8 :   parameter[DA_SC4].push_back(6.45900000);
+    2382           8 :   parameter[DA_SC4].push_back(0.01991800);
+    2383           8 :   parameter[DA_SC4].push_back(4.17962300);
+    2384           8 :   parameter[DA_SC4].push_back(0.97469100);
+    2385           8 :   parameter[DA_SC4].push_back(-5.02950400);
+    2386           8 :   parameter[DA_SC4].push_back(2.55371800);
+    2387           8 :   parameter[DA_SC4].push_back(-0.39113400);
+    2388             : 
+    2389           8 :   parameter[DA_3TE].push_back(4.23000000);
+    2390           8 :   parameter[DA_3TE].push_back(0.00062600);
+    2391           8 :   parameter[DA_3TE].push_back(0.92142000);
+    2392           8 :   parameter[DA_3TE].push_back(0.08016400);
+    2393           8 :   parameter[DA_3TE].push_back(-0.39000300);
+    2394           8 :   parameter[DA_3TE].push_back(0.12402500);
+    2395           8 :   parameter[DA_3TE].push_back(-0.01117900);
+    2396             : 
+    2397           8 :   parameter[DA_5TE].push_back(4.23000000);
+    2398           8 :   parameter[DA_5TE].push_back(0.00055500);
+    2399           8 :   parameter[DA_5TE].push_back(0.92183900);
+    2400           8 :   parameter[DA_5TE].push_back(0.07907600);
+    2401           8 :   parameter[DA_5TE].push_back(-0.38895100);
+    2402           8 :   parameter[DA_5TE].push_back(0.12359600);
+    2403           8 :   parameter[DA_5TE].push_back(-0.01111600);
+    2404             : 
+    2405           8 :   parameter[DA_TE3].push_back(2.87400000);
+    2406           8 :   parameter[DA_TE3].push_back(0.00112900);
+    2407           8 :   parameter[DA_TE3].push_back(12.51167200);
+    2408           8 :   parameter[DA_TE3].push_back(-7.67548000);
+    2409           8 :   parameter[DA_TE3].push_back(-2.02234000);
+    2410           8 :   parameter[DA_TE3].push_back(2.50837100);
+    2411           8 :   parameter[DA_TE3].push_back(-0.49458500);
+    2412             : 
+    2413           8 :   parameter[DA_TE5].push_back(8.03600000);
+    2414           8 :   parameter[DA_TE5].push_back(0.00473100);
+    2415           8 :   parameter[DA_TE5].push_back(4.65554400);
+    2416           8 :   parameter[DA_TE5].push_back(0.66424100);
+    2417           8 :   parameter[DA_TE5].push_back(-6.62131300);
+    2418           8 :   parameter[DA_TE5].push_back(3.96107400);
+    2419           8 :   parameter[DA_TE5].push_back(-0.69075800);
+    2420             : 
+    2421           8 :   parameter[DC_BB1].push_back(32.88500000);
+    2422           8 :   parameter[DC_BB1].push_back(0.08189900);
+    2423           8 :   parameter[DC_BB1].push_back(-7.32493500);
+    2424           8 :   parameter[DC_BB1].push_back(2.15976900);
+    2425           8 :   parameter[DC_BB1].push_back(-3.52612100);
+    2426           8 :   parameter[DC_BB1].push_back(2.31058600);
+    2427           8 :   parameter[DC_BB1].push_back(-0.39402700);
+    2428             : 
+    2429           8 :   parameter[DC_BB2].push_back(3.80600000);
+    2430           8 :   parameter[DC_BB2].push_back(-0.10559800);
+    2431           8 :   parameter[DC_BB2].push_back(9.52527700);
+    2432           8 :   parameter[DC_BB2].push_back(-6.12131700);
+    2433           8 :   parameter[DC_BB2].push_back(-0.54899400);
+    2434           8 :   parameter[DC_BB2].push_back(1.15592900);
+    2435           8 :   parameter[DC_BB2].push_back(-0.21494500);
+    2436             : 
+    2437           8 :   parameter[DC_BB3].push_back(-1.35600000);
+    2438           8 :   parameter[DC_BB3].push_back(0.55525700);
+    2439           8 :   parameter[DC_BB3].push_back(6.80305500);
+    2440           8 :   parameter[DC_BB3].push_back(4.05924700);
+    2441           8 :   parameter[DC_BB3].push_back(-9.61034700);
+    2442           8 :   parameter[DC_BB3].push_back(4.41253800);
+    2443           8 :   parameter[DC_BB3].push_back(-0.64315100);
+    2444             : 
+    2445           8 :   parameter[DC_SC1].push_back(5.95100000);
+    2446           8 :   parameter[DC_SC1].push_back(-0.02899900);
+    2447           8 :   parameter[DC_SC1].push_back(2.59587800);
+    2448           8 :   parameter[DC_SC1].push_back(-0.55388300);
+    2449           8 :   parameter[DC_SC1].push_back(-1.56395100);
+    2450           8 :   parameter[DC_SC1].push_back(0.88967400);
+    2451           8 :   parameter[DC_SC1].push_back(-0.14062500);
+    2452             : 
+    2453           8 :   parameter[DC_SC2].push_back(11.62100000);
+    2454           8 :   parameter[DC_SC2].push_back(0.01358100);
+    2455           8 :   parameter[DC_SC2].push_back(-0.24913000);
+    2456           8 :   parameter[DC_SC2].push_back(0.48787200);
+    2457           8 :   parameter[DC_SC2].push_back(-1.52867300);
+    2458           8 :   parameter[DC_SC2].push_back(0.83694900);
+    2459           8 :   parameter[DC_SC2].push_back(-0.13395300);
+    2460             : 
+    2461           8 :   parameter[DC_SC3].push_back(5.01900000);
+    2462           8 :   parameter[DC_SC3].push_back(-0.03298400);
+    2463           8 :   parameter[DC_SC3].push_back(5.54242800);
+    2464           8 :   parameter[DC_SC3].push_back(-0.96081500);
+    2465           8 :   parameter[DC_SC3].push_back(-3.71051600);
+    2466           8 :   parameter[DC_SC3].push_back(2.16500200);
+    2467           8 :   parameter[DC_SC3].push_back(-0.35023400);
+    2468             : 
+    2469           8 :   parameter[DC_3TE].push_back(4.23000000);
+    2470           8 :   parameter[DC_3TE].push_back(0.00055700);
+    2471           8 :   parameter[DC_3TE].push_back(0.92181400);
+    2472           8 :   parameter[DC_3TE].push_back(0.07924000);
+    2473           8 :   parameter[DC_3TE].push_back(-0.38916400);
+    2474           8 :   parameter[DC_3TE].push_back(0.12369900);
+    2475           8 :   parameter[DC_3TE].push_back(-0.01113300);
+    2476             : 
+    2477           8 :   parameter[DC_5TE].push_back(4.23000000);
+    2478           8 :   parameter[DC_5TE].push_back(0.00066500);
+    2479           8 :   parameter[DC_5TE].push_back(0.92103900);
+    2480           8 :   parameter[DC_5TE].push_back(0.08064600);
+    2481           8 :   parameter[DC_5TE].push_back(-0.39034900);
+    2482           8 :   parameter[DC_5TE].push_back(0.12417600);
+    2483           8 :   parameter[DC_5TE].push_back(-0.01120600);
+    2484             : 
+    2485           8 :   parameter[DC_TE3].push_back(2.87400000);
+    2486           8 :   parameter[DC_TE3].push_back(-0.05235500);
+    2487           8 :   parameter[DC_TE3].push_back(13.09201200);
+    2488           8 :   parameter[DC_TE3].push_back(-9.48128200);
+    2489           8 :   parameter[DC_TE3].push_back(-0.14958600);
+    2490           8 :   parameter[DC_TE3].push_back(1.75537200);
+    2491           8 :   parameter[DC_TE3].push_back(-0.39347500);
+    2492             : 
+    2493           8 :   parameter[DC_TE5].push_back(8.03600000);
+    2494           8 :   parameter[DC_TE5].push_back(-0.00513600);
+    2495           8 :   parameter[DC_TE5].push_back(4.67705700);
+    2496           8 :   parameter[DC_TE5].push_back(0.48333300);
+    2497           8 :   parameter[DC_TE5].push_back(-6.34511000);
+    2498           8 :   parameter[DC_TE5].push_back(3.83388500);
+    2499           8 :   parameter[DC_TE5].push_back(-0.67367800);
+    2500             : 
+    2501           8 :   parameter[DG_BB1].push_back(32.88500000);
+    2502           8 :   parameter[DG_BB1].push_back(0.08182900);
+    2503           8 :   parameter[DG_BB1].push_back(-7.32133900);
+    2504           8 :   parameter[DG_BB1].push_back(2.15767900);
+    2505           8 :   parameter[DG_BB1].push_back(-3.52369700);
+    2506           8 :   parameter[DG_BB1].push_back(2.30839600);
+    2507           8 :   parameter[DG_BB1].push_back(-0.39348300);
+    2508             : 
+    2509           8 :   parameter[DG_BB2].push_back(3.80600000);
+    2510           8 :   parameter[DG_BB2].push_back(-0.10618100);
+    2511           8 :   parameter[DG_BB2].push_back(9.54169000);
+    2512           8 :   parameter[DG_BB2].push_back(-6.15177600);
+    2513           8 :   parameter[DG_BB2].push_back(-0.53462400);
+    2514           8 :   parameter[DG_BB2].push_back(1.15581300);
+    2515           8 :   parameter[DG_BB2].push_back(-0.21567000);
+    2516             : 
+    2517           8 :   parameter[DG_BB3].push_back(-1.35600000);
+    2518           8 :   parameter[DG_BB3].push_back(0.57489100);
+    2519           8 :   parameter[DG_BB3].push_back(6.75164700);
+    2520           8 :   parameter[DG_BB3].push_back(4.11300900);
+    2521           8 :   parameter[DG_BB3].push_back(-9.63394600);
+    2522           8 :   parameter[DG_BB3].push_back(4.41675400);
+    2523           8 :   parameter[DG_BB3].push_back(-0.64339900);
+    2524             : 
+    2525           8 :   parameter[DG_SC1].push_back(6.67100000);
+    2526           8 :   parameter[DG_SC1].push_back(-0.00886600);
+    2527           8 :   parameter[DG_SC1].push_back(1.63333000);
+    2528           8 :   parameter[DG_SC1].push_back(-0.06892100);
+    2529           8 :   parameter[DG_SC1].push_back(-1.48683500);
+    2530           8 :   parameter[DG_SC1].push_back(0.78670800);
+    2531           8 :   parameter[DG_SC1].push_back(-0.12113900);
+    2532             : 
+    2533           8 :   parameter[DG_SC2].push_back(11.39400000);
+    2534           8 :   parameter[DG_SC2].push_back(0.00907900);
+    2535           8 :   parameter[DG_SC2].push_back(-0.22475500);
+    2536           8 :   parameter[DG_SC2].push_back(0.49535100);
+    2537           8 :   parameter[DG_SC2].push_back(-1.75324900);
+    2538           8 :   parameter[DG_SC2].push_back(0.98767400);
+    2539           8 :   parameter[DG_SC2].push_back(-0.16150800);
+    2540             : 
+    2541           8 :   parameter[DG_SC3].push_back(10.90100000);
+    2542           8 :   parameter[DG_SC3].push_back(0.02207600);
+    2543           8 :   parameter[DG_SC3].push_back(0.17932200);
+    2544           8 :   parameter[DG_SC3].push_back(0.73253200);
+    2545           8 :   parameter[DG_SC3].push_back(-1.95554900);
+    2546           8 :   parameter[DG_SC3].push_back(0.98339900);
+    2547           8 :   parameter[DG_SC3].push_back(-0.14763600);
+    2548             : 
+    2549           8 :   parameter[DG_SC4].push_back(6.45900000);
+    2550           8 :   parameter[DG_SC4].push_back(0.02018400);
+    2551           8 :   parameter[DG_SC4].push_back(4.17705400);
+    2552           8 :   parameter[DG_SC4].push_back(0.98531700);
+    2553           8 :   parameter[DG_SC4].push_back(-5.04354900);
+    2554           8 :   parameter[DG_SC4].push_back(2.56123700);
+    2555           8 :   parameter[DG_SC4].push_back(-0.39249300);
+    2556             : 
+    2557           8 :   parameter[DG_3TE].push_back(4.23000000);
+    2558           8 :   parameter[DG_3TE].push_back(0.00061700);
+    2559           8 :   parameter[DG_3TE].push_back(0.92140100);
+    2560           8 :   parameter[DG_3TE].push_back(0.08016400);
+    2561           8 :   parameter[DG_3TE].push_back(-0.39003500);
+    2562           8 :   parameter[DG_3TE].push_back(0.12406900);
+    2563           8 :   parameter[DG_3TE].push_back(-0.01119200);
+    2564             : 
+    2565           8 :   parameter[DG_5TE].push_back(4.23000000);
+    2566           8 :   parameter[DG_5TE].push_back(0.00064900);
+    2567           8 :   parameter[DG_5TE].push_back(0.92110500);
+    2568           8 :   parameter[DG_5TE].push_back(0.08031500);
+    2569           8 :   parameter[DG_5TE].push_back(-0.38997000);
+    2570           8 :   parameter[DG_5TE].push_back(0.12401200);
+    2571           8 :   parameter[DG_5TE].push_back(-0.01118100);
+    2572             : 
+    2573           8 :   parameter[DG_TE3].push_back(2.87400000);
+    2574           8 :   parameter[DG_TE3].push_back(0.00182000);
+    2575           8 :   parameter[DG_TE3].push_back(12.41507000);
+    2576           8 :   parameter[DG_TE3].push_back(-7.47384800);
+    2577           8 :   parameter[DG_TE3].push_back(-2.11864700);
+    2578           8 :   parameter[DG_TE3].push_back(2.50112600);
+    2579           8 :   parameter[DG_TE3].push_back(-0.48652200);
+    2580             : 
+    2581           8 :   parameter[DG_TE5].push_back(8.03600000);
+    2582           8 :   parameter[DG_TE5].push_back(0.00676400);
+    2583           8 :   parameter[DG_TE5].push_back(4.65989200);
+    2584           8 :   parameter[DG_TE5].push_back(0.78482500);
+    2585           8 :   parameter[DG_TE5].push_back(-6.86460600);
+    2586           8 :   parameter[DG_TE5].push_back(4.11675400);
+    2587           8 :   parameter[DG_TE5].push_back(-0.72249100);
+    2588             : 
+    2589           8 :   parameter[DT_BB1].push_back(32.88500000);
+    2590           8 :   parameter[DT_BB1].push_back(0.08220100);
+    2591           8 :   parameter[DT_BB1].push_back(-7.33006800);
+    2592           8 :   parameter[DT_BB1].push_back(2.16636500);
+    2593           8 :   parameter[DT_BB1].push_back(-3.53465700);
+    2594           8 :   parameter[DT_BB1].push_back(2.31447600);
+    2595           8 :   parameter[DT_BB1].push_back(-0.39445400);
+    2596             : 
+    2597           8 :   parameter[DT_BB2].push_back(3.80600000);
+    2598           8 :   parameter[DT_BB2].push_back(-0.10723000);
+    2599           8 :   parameter[DT_BB2].push_back(9.56675000);
+    2600           8 :   parameter[DT_BB2].push_back(-6.20236100);
+    2601           8 :   parameter[DT_BB2].push_back(-0.49550400);
+    2602           8 :   parameter[DT_BB2].push_back(1.14300600);
+    2603           8 :   parameter[DT_BB2].push_back(-0.21420000);
+    2604             : 
+    2605           8 :   parameter[DT_BB3].push_back(-1.35600000);
+    2606           8 :   parameter[DT_BB3].push_back(0.56737900);
+    2607           8 :   parameter[DT_BB3].push_back(6.76595400);
+    2608           8 :   parameter[DT_BB3].push_back(4.08976100);
+    2609           8 :   parameter[DT_BB3].push_back(-9.61512500);
+    2610           8 :   parameter[DT_BB3].push_back(4.40975100);
+    2611           8 :   parameter[DT_BB3].push_back(-0.64239800);
+    2612             : 
+    2613           8 :   parameter[DT_SC1].push_back(5.95100000);
+    2614           8 :   parameter[DT_SC1].push_back(-0.02926500);
+    2615           8 :   parameter[DT_SC1].push_back(2.59630300);
+    2616           8 :   parameter[DT_SC1].push_back(-0.56152200);
+    2617           8 :   parameter[DT_SC1].push_back(-1.56532600);
+    2618           8 :   parameter[DT_SC1].push_back(0.89322800);
+    2619           8 :   parameter[DT_SC1].push_back(-0.14142900);
+    2620             : 
+    2621           8 :   parameter[DT_SC2].push_back(10.90100000);
+    2622           8 :   parameter[DT_SC2].push_back(0.02183400);
+    2623           8 :   parameter[DT_SC2].push_back(0.19463000);
+    2624           8 :   parameter[DT_SC2].push_back(0.72393000);
+    2625           8 :   parameter[DT_SC2].push_back(-1.93199500);
+    2626           8 :   parameter[DT_SC2].push_back(0.96856300);
+    2627           8 :   parameter[DT_SC2].push_back(-0.14512600);
+    2628             : 
+    2629           8 :   parameter[DT_SC3].push_back(4.31400000);
+    2630           8 :   parameter[DT_SC3].push_back(-0.07745600);
+    2631           8 :   parameter[DT_SC3].push_back(12.49820300);
+    2632           8 :   parameter[DT_SC3].push_back(-7.64994200);
+    2633           8 :   parameter[DT_SC3].push_back(-3.00359600);
+    2634           8 :   parameter[DT_SC3].push_back(3.26263300);
+    2635           8 :   parameter[DT_SC3].push_back(-0.64498600);
+    2636             : 
+    2637           8 :   parameter[DT_3TE].push_back(4.23000000);
+    2638           8 :   parameter[DT_3TE].push_back(0.00062000);
+    2639           8 :   parameter[DT_3TE].push_back(0.92141100);
+    2640           8 :   parameter[DT_3TE].push_back(0.08030900);
+    2641           8 :   parameter[DT_3TE].push_back(-0.39021500);
+    2642           8 :   parameter[DT_3TE].push_back(0.12414000);
+    2643           8 :   parameter[DT_3TE].push_back(-0.01120100);
+    2644             : 
+    2645           8 :   parameter[DT_5TE].push_back(4.23000000);
+    2646           8 :   parameter[DT_5TE].push_back(0.00063700);
+    2647           8 :   parameter[DT_5TE].push_back(0.92130800);
+    2648           8 :   parameter[DT_5TE].push_back(0.08026900);
+    2649           8 :   parameter[DT_5TE].push_back(-0.39007500);
+    2650           8 :   parameter[DT_5TE].push_back(0.12406600);
+    2651           8 :   parameter[DT_5TE].push_back(-0.01118800);
+    2652             : 
+    2653           8 :   parameter[DT_TE3].push_back(2.87400000);
+    2654           8 :   parameter[DT_TE3].push_back(-0.00251200);
+    2655           8 :   parameter[DT_TE3].push_back(12.43576400);
+    2656           8 :   parameter[DT_TE3].push_back(-7.55343800);
+    2657           8 :   parameter[DT_TE3].push_back(-2.07363500);
+    2658           8 :   parameter[DT_TE3].push_back(2.51279300);
+    2659           8 :   parameter[DT_TE3].push_back(-0.49437100);
+    2660             : 
+    2661           8 :   parameter[DT_TE5].push_back(8.03600000);
+    2662           8 :   parameter[DT_TE5].push_back(0.00119900);
+    2663           8 :   parameter[DT_TE5].push_back(4.91762300);
+    2664           8 :   parameter[DT_TE5].push_back(0.65637000);
+    2665           8 :   parameter[DT_TE5].push_back(-7.23392500);
+    2666           8 :   parameter[DT_TE5].push_back(4.44636600);
+    2667           8 :   parameter[DT_TE5].push_back(-0.79467800);
+    2668             : 
+    2669           8 :   auto* moldat=plumed.getActionSet().selectLatest<GenericMolInfo*>(this);
+    2670           8 :   if( moldat ) {
+    2671        8400 :     for(unsigned i=0; i<atoms.size(); ++i) {
+    2672        8392 :       std::string Aname = moldat->getAtomName(atoms[i]);
+    2673        8392 :       std::string Rname = moldat->getResidueName(atoms[i]);
+    2674        8392 :       if(Rname=="ALA") {
+    2675          72 :         if(Aname=="BB") {
+    2676          72 :           atoi[i]=ALA_BB;
+    2677           0 :         } else error("Atom name not known: "+Aname);
+    2678        8320 :       } else if(Rname=="ARG") {
+    2679         420 :         if(Aname=="BB") {
+    2680         140 :           atoi[i]=ARG_BB;
+    2681         280 :         } else if(Aname=="SC1") {
+    2682         140 :           atoi[i]=ARG_SC1;
+    2683         140 :         } else if(Aname=="SC2") {
+    2684         140 :           atoi[i]=ARG_SC2;
+    2685           0 :         } else error("Atom name not known: "+Aname);
+    2686        7900 :       } else if(Rname=="ASN") {
+    2687         240 :         if(Aname=="BB") {
+    2688         120 :           atoi[i]=ASN_BB;
+    2689         120 :         } else if(Aname=="SC1") {
+    2690         120 :           atoi[i]=ASN_SC1;
+    2691           0 :         } else error("Atom name not known: "+Aname);
+    2692        7660 :       } else if(Rname=="ASP") {
+    2693         368 :         if(Aname=="BB") {
+    2694         184 :           atoi[i]=ASP_BB;
+    2695         184 :         } else if(Aname=="SC1") {
+    2696         184 :           atoi[i]=ASP_SC1;
+    2697           0 :         } else error("Atom name not known: "+Aname);
+    2698        7292 :       } else if(Rname=="CYS") {
+    2699          16 :         if(Aname=="BB") {
+    2700           8 :           atoi[i]=CYS_BB;
+    2701           8 :         } else if(Aname=="SC1") {
+    2702           8 :           atoi[i]=CYS_SC1;
+    2703           0 :         } else error("Atom name not known: "+Aname);
+    2704        7276 :       } else if(Rname=="GLN") {
+    2705         224 :         if(Aname=="BB") {
+    2706         112 :           atoi[i]=GLN_BB;
+    2707         112 :         } else if(Aname=="SC1") {
+    2708         112 :           atoi[i]=GLN_SC1;
+    2709           0 :         } else error("Atom name not known: "+Aname);
+    2710        7052 :       } else if(Rname=="GLU") {
+    2711         480 :         if(Aname=="BB") {
+    2712         240 :           atoi[i]=GLU_BB;
+    2713         240 :         } else if(Aname=="SC1") {
+    2714         240 :           atoi[i]=GLU_SC1;
+    2715           0 :         } else error("Atom name not known: "+Aname);
+    2716        6572 :       } else if(Rname=="GLY") {
+    2717         116 :         if(Aname=="BB") {
+    2718         116 :           atoi[i]=GLY_BB;
+    2719           0 :         } else error("Atom name not known: "+Aname);
+    2720        6456 :       } else if(Rname=="HIS") {
+    2721         576 :         if(Aname=="BB") {
+    2722         144 :           atoi[i]=HIS_BB;
+    2723         432 :         } else if(Aname=="SC1") {
+    2724         144 :           atoi[i]=HIS_SC1;
+    2725         288 :         } else if(Aname=="SC2") {
+    2726         144 :           atoi[i]=HIS_SC2;
+    2727         144 :         } else if(Aname=="SC3") {
+    2728         144 :           atoi[i]=HIS_SC3;
+    2729           0 :         } else error("Atom name not known: "+Aname);
+    2730        5880 :       } else if(Rname=="ILE") {
+    2731         584 :         if(Aname=="BB") {
+    2732         292 :           atoi[i]=ILE_BB;
+    2733         292 :         } else if(Aname=="SC1") {
+    2734         292 :           atoi[i]=ILE_SC1;
+    2735           0 :         } else error("Atom name not known: "+Aname);
+    2736        5296 :       } else if(Rname=="LEU") {
+    2737         448 :         if(Aname=="BB") {
+    2738         224 :           atoi[i]=LEU_BB;
+    2739         224 :         } else if(Aname=="SC1") {
+    2740         224 :           atoi[i]=LEU_SC1;
+    2741           0 :         } else error("Atom name not known: "+Aname);
+    2742        4848 :       } else if(Rname=="LYS") {
+    2743         792 :         if(Aname=="BB") {
+    2744         264 :           atoi[i]=LYS_BB;
+    2745         528 :         } else if(Aname=="SC1") {
+    2746         264 :           atoi[i]=LYS_SC1;
+    2747         264 :         } else if(Aname=="SC2") {
+    2748         264 :           atoi[i]=LYS_SC2;
+    2749           0 :         } else error("Atom name not known: "+Aname);
+    2750        4056 :       } else if(Rname=="MET") {
+    2751          80 :         if(Aname=="BB") {
+    2752          40 :           atoi[i]=MET_BB;
+    2753          40 :         } else if(Aname=="SC1") {
+    2754          40 :           atoi[i]=MET_SC1;
+    2755           0 :         } else error("Atom name not known: "+Aname);
+    2756        3976 :       } else if(Rname=="PHE") {
+    2757         512 :         if(Aname=="BB") {
+    2758         128 :           atoi[i]=PHE_BB;
+    2759         384 :         } else if(Aname=="SC1") {
+    2760         128 :           atoi[i]=PHE_SC1;
+    2761         256 :         } else if(Aname=="SC2") {
+    2762         128 :           atoi[i]=PHE_SC2;
+    2763         128 :         } else if(Aname=="SC3") {
+    2764         128 :           atoi[i]=PHE_SC3;
+    2765           0 :         } else error("Atom name not known: "+Aname);
+    2766        3464 :       } else if(Rname=="PRO") {
+    2767         128 :         if(Aname=="BB") {
+    2768          64 :           atoi[i]=PRO_BB;
+    2769          64 :         } else if(Aname=="SC1") {
+    2770          64 :           atoi[i]=PRO_SC1;
+    2771           0 :         } else error("Atom name not known: "+Aname);
+    2772        3336 :       } else if(Rname=="SER") {
+    2773         248 :         if(Aname=="BB") {
+    2774         124 :           atoi[i]=SER_BB;
+    2775         124 :         } else if(Aname=="SC1") {
+    2776         124 :           atoi[i]=SER_SC1;
+    2777           0 :         } else error("Atom name not known: "+Aname);
+    2778        3088 :       } else if(Rname=="THR") {
+    2779         288 :         if(Aname=="BB") {
+    2780         144 :           atoi[i]=THR_BB;
+    2781         144 :         } else if(Aname=="SC1") {
+    2782         144 :           atoi[i]=THR_SC1;
+    2783           0 :         } else error("Atom name not known: "+Aname);
+    2784        2800 :       } else if(Rname=="TRP") {
+    2785           0 :         if(Aname=="BB") {
+    2786           0 :           atoi[i]=TRP_BB;
+    2787           0 :         } else if(Aname=="SC1") {
+    2788           0 :           atoi[i]=TRP_SC1;
+    2789           0 :         } else if(Aname=="SC2") {
+    2790           0 :           atoi[i]=TRP_SC2;
+    2791           0 :         } else if(Aname=="SC3") {
+    2792           0 :           atoi[i]=TRP_SC3;
+    2793           0 :         } else if(Aname=="SC4") {
+    2794           0 :           atoi[i]=TRP_SC4;
+    2795           0 :         } else error("Atom name not known: "+Aname);
+    2796        2800 :       } else if(Rname=="TYR") {
+    2797         544 :         if(Aname=="BB") {
+    2798         136 :           atoi[i]=TYR_BB;
+    2799         408 :         } else if(Aname=="SC1") {
+    2800         136 :           atoi[i]=TYR_SC1;
+    2801         272 :         } else if(Aname=="SC2") {
+    2802         136 :           atoi[i]=TYR_SC2;
+    2803         136 :         } else if(Aname=="SC3") {
+    2804         136 :           atoi[i]=TYR_SC3;
+    2805           0 :         } else error("Atom name not known: "+Aname);
+    2806        2256 :       } else if(Rname=="VAL") {
+    2807         288 :         if(Aname=="BB") {
+    2808         144 :           atoi[i]=VAL_BB;
+    2809         144 :         } else if(Aname=="SC1") {
+    2810         144 :           atoi[i]=VAL_SC1;
+    2811           0 :         } else error("Atom name not known: "+Aname);
+    2812        1968 :       } else if(Rname=="  A") {
+    2813           0 :         if(Aname=="BB1") {
+    2814           0 :           atoi[i]=A_BB1;
+    2815           0 :         } else if(Aname=="BB2") {
+    2816           0 :           atoi[i]=A_BB2;
+    2817           0 :         } else if(Aname=="BB3") {
+    2818           0 :           atoi[i]=A_BB3;
+    2819           0 :         } else if(Aname=="SC1") {
+    2820           0 :           atoi[i]=A_SC1;
+    2821           0 :         } else if(Aname=="SC2") {
+    2822           0 :           atoi[i]=A_SC2;
+    2823           0 :         } else if(Aname=="SC3") {
+    2824           0 :           atoi[i]=A_SC3;
+    2825           0 :         } else if(Aname=="SC4") {
+    2826           0 :           atoi[i]=A_SC4;
+    2827           0 :         } else if(Aname=="3TE") {
+    2828           0 :           atoi[i]=A_3TE;
+    2829           0 :         } else if(Aname=="5TE") {
+    2830           0 :           atoi[i]=A_5TE;
+    2831           0 :         } else if(Aname=="TE3") {
+    2832           0 :           atoi[i]=A_TE3;
+    2833           0 :         } else if(Aname=="TE5") {
+    2834           0 :           atoi[i]=A_TE5;
+    2835           0 :         } else error("Atom name not known: "+Aname);
+    2836        1968 :       } else if(Rname=="  C") {
+    2837           0 :         if(Aname=="BB1") {
+    2838           0 :           atoi[i]=C_BB1;
+    2839           0 :         } else if(Aname=="BB2") {
+    2840           0 :           atoi[i]=C_BB2;
+    2841           0 :         } else if(Aname=="BB3") {
+    2842           0 :           atoi[i]=C_BB3;
+    2843           0 :         } else if(Aname=="SC1") {
+    2844           0 :           atoi[i]=C_SC1;
+    2845           0 :         } else if(Aname=="SC2") {
+    2846           0 :           atoi[i]=C_SC2;
+    2847           0 :         } else if(Aname=="SC3") {
+    2848           0 :           atoi[i]=C_SC3;
+    2849           0 :         } else if(Aname=="3TE") {
+    2850           0 :           atoi[i]=C_3TE;
+    2851           0 :         } else if(Aname=="5TE") {
+    2852           0 :           atoi[i]=C_5TE;
+    2853           0 :         } else if(Aname=="TE3") {
+    2854           0 :           atoi[i]=C_TE3;
+    2855           0 :         } else if(Aname=="TE5") {
+    2856           0 :           atoi[i]=C_TE5;
+    2857           0 :         } else error("Atom name not known: "+Aname);
+    2858        1968 :       } else if(Rname=="  G") {
+    2859           0 :         if(Aname=="BB1") {
+    2860           0 :           atoi[i]=G_BB1;
+    2861           0 :         } else if(Aname=="BB2") {
+    2862           0 :           atoi[i]=G_BB2;
+    2863           0 :         } else if(Aname=="BB3") {
+    2864           0 :           atoi[i]=G_BB3;
+    2865           0 :         } else if(Aname=="SC1") {
+    2866           0 :           atoi[i]=G_SC1;
+    2867           0 :         } else if(Aname=="SC2") {
+    2868           0 :           atoi[i]=G_SC2;
+    2869           0 :         } else if(Aname=="SC3") {
+    2870           0 :           atoi[i]=G_SC3;
+    2871           0 :         } else if(Aname=="SC4") {
+    2872           0 :           atoi[i]=G_SC4;
+    2873           0 :         } else if(Aname=="3TE") {
+    2874           0 :           atoi[i]=G_3TE;
+    2875           0 :         } else if(Aname=="5TE") {
+    2876           0 :           atoi[i]=G_5TE;
+    2877           0 :         } else if(Aname=="TE3") {
+    2878           0 :           atoi[i]=G_TE3;
+    2879           0 :         } else if(Aname=="TE5") {
+    2880           0 :           atoi[i]=G_TE5;
+    2881           0 :         } else error("Atom name not known: "+Aname);
+    2882        1968 :       } else if(Rname=="  U") {
+    2883           0 :         if(Aname=="BB1") {
+    2884           0 :           atoi[i]=U_BB1;
+    2885           0 :         } else if(Aname=="BB2") {
+    2886           0 :           atoi[i]=U_BB2;
+    2887           0 :         } else if(Aname=="BB3") {
+    2888           0 :           atoi[i]=U_BB3;
+    2889           0 :         } else if(Aname=="SC1") {
+    2890           0 :           atoi[i]=U_SC1;
+    2891           0 :         } else if(Aname=="SC2") {
+    2892           0 :           atoi[i]=U_SC2;
+    2893           0 :         } else if(Aname=="SC3") {
+    2894           0 :           atoi[i]=U_SC3;
+    2895           0 :         } else if(Aname=="3TE") {
+    2896           0 :           atoi[i]=U_3TE;
+    2897           0 :         } else if(Aname=="5TE") {
+    2898           0 :           atoi[i]=U_5TE;
+    2899           0 :         } else if(Aname=="TE3") {
+    2900           0 :           atoi[i]=U_TE3;
+    2901           0 :         } else if(Aname=="TE5") {
+    2902           0 :           atoi[i]=U_TE5;
+    2903           0 :         } else error("Atom name not known: "+Aname);
+    2904        1968 :       } else if(Rname==" DA") {
+    2905         696 :         if(Aname=="BB1") {
+    2906          96 :           atoi[i]=DA_BB1;
+    2907         600 :         } else if(Aname=="BB2") {
+    2908          96 :           atoi[i]=DA_BB2;
+    2909         504 :         } else if(Aname=="BB3") {
+    2910          96 :           atoi[i]=DA_BB3;
+    2911         408 :         } else if(Aname=="SC1") {
+    2912         100 :           atoi[i]=DA_SC1;
+    2913         308 :         } else if(Aname=="SC2") {
+    2914         100 :           atoi[i]=DA_SC2;
+    2915         208 :         } else if(Aname=="SC3") {
+    2916         100 :           atoi[i]=DA_SC3;
+    2917         108 :         } else if(Aname=="SC4") {
+    2918         100 :           atoi[i]=DA_SC4;
+    2919           8 :         } else if(Aname=="3TE") {
+    2920           0 :           atoi[i]=DA_3TE;
+    2921           8 :         } else if(Aname=="5TE") {
+    2922           0 :           atoi[i]=DA_5TE;
+    2923           8 :         } else if(Aname=="TE3") {
+    2924           4 :           atoi[i]=DA_TE3;
+    2925           4 :         } else if(Aname=="TE5") {
+    2926           4 :           atoi[i]=DA_TE5;
+    2927           0 :         } else error("Atom name not known: "+Aname);
+    2928        1272 :       } else if(Rname==" DC") {
+    2929         312 :         if(Aname=="BB1") {
+    2930          52 :           atoi[i]=DC_BB1;
+    2931         260 :         } else if(Aname=="BB2") {
+    2932          52 :           atoi[i]=DC_BB2;
+    2933         208 :         } else if(Aname=="BB3") {
+    2934          52 :           atoi[i]=DC_BB3;
+    2935         156 :         } else if(Aname=="SC1") {
+    2936          52 :           atoi[i]=DC_SC1;
+    2937         104 :         } else if(Aname=="SC2") {
+    2938          52 :           atoi[i]=DC_SC2;
+    2939          52 :         } else if(Aname=="SC3") {
+    2940          52 :           atoi[i]=DC_SC3;
+    2941           0 :         } else if(Aname=="3TE") {
+    2942           0 :           atoi[i]=DC_3TE;
+    2943           0 :         } else if(Aname=="5TE") {
+    2944           0 :           atoi[i]=DC_5TE;
+    2945           0 :         } else if(Aname=="TE3") {
+    2946           0 :           atoi[i]=DC_TE3;
+    2947           0 :         } else if(Aname=="TE5") {
+    2948           0 :           atoi[i]=DC_TE5;
+    2949           0 :         } else error("Atom name not known: "+Aname);
+    2950         960 :       } else if(Rname==" DG") {
+    2951         364 :         if(Aname=="BB1") {
+    2952          52 :           atoi[i]=DG_BB1;
+    2953         312 :         } else if(Aname=="BB2") {
+    2954          52 :           atoi[i]=DG_BB2;
+    2955         260 :         } else if(Aname=="BB3") {
+    2956          52 :           atoi[i]=DG_BB3;
+    2957         208 :         } else if(Aname=="SC1") {
+    2958          52 :           atoi[i]=DG_SC1;
+    2959         156 :         } else if(Aname=="SC2") {
+    2960          52 :           atoi[i]=DG_SC2;
+    2961         104 :         } else if(Aname=="SC3") {
+    2962          52 :           atoi[i]=DG_SC3;
+    2963          52 :         } else if(Aname=="SC4") {
+    2964          52 :           atoi[i]=DG_SC4;
+    2965           0 :         } else if(Aname=="3TE") {
+    2966           0 :           atoi[i]=DG_3TE;
+    2967           0 :         } else if(Aname=="5TE") {
+    2968           0 :           atoi[i]=DG_5TE;
+    2969           0 :         } else if(Aname=="TE3") {
+    2970           0 :           atoi[i]=DG_TE3;
+    2971           0 :         } else if(Aname=="TE5") {
+    2972           0 :           atoi[i]=DG_TE5;
+    2973           0 :         } else error("Atom name not known: "+Aname);
+    2974         596 :       } else if(Rname==" DT") {
+    2975         596 :         if(Aname=="BB1") {
+    2976          96 :           atoi[i]=DT_BB1;
+    2977         500 :         } else if(Aname=="BB2") {
+    2978          96 :           atoi[i]=DT_BB2;
+    2979         404 :         } else if(Aname=="BB3") {
+    2980          96 :           atoi[i]=DT_BB3;
+    2981         308 :         } else if(Aname=="SC1") {
+    2982         100 :           atoi[i]=DT_SC1;
+    2983         208 :         } else if(Aname=="SC2") {
+    2984         100 :           atoi[i]=DT_SC2;
+    2985         108 :         } else if(Aname=="SC3") {
+    2986         100 :           atoi[i]=DT_SC3;
+    2987           8 :         } else if(Aname=="3TE") {
+    2988           0 :           atoi[i]=DT_3TE;
+    2989           8 :         } else if(Aname=="5TE") {
+    2990           0 :           atoi[i]=DT_5TE;
+    2991           8 :         } else if(Aname=="TE3") {
+    2992           4 :           atoi[i]=DT_TE3;
+    2993           4 :         } else if(Aname=="TE5") {
+    2994           4 :           atoi[i]=DT_TE5;
+    2995           0 :         } else error("Atom name not known: "+Aname);
+    2996           0 :       } else error("Residue not known: "+Rname);
+    2997             :     }
+    2998             :   } else {
+    2999           0 :     error("MOLINFO DATA not found\n");
+    3000             :   }
+    3001           8 : }
+    3002             : 
+    3003           6 : void SAXS::getOnebeadparam(const PDB &pdb, const std::vector<AtomNumber> &atoms, std::vector<std::vector<long double> > &parameter_vac, std::vector<std::vector<long double> > &parameter_mix, std::vector<std::vector<long double> > &parameter_solv, const std::vector<unsigned> & residue_atom)
+    3004             : {
+    3005             : 
+    3006           6 :   parameter_solv[TRP].push_back(60737.60249988003);
+    3007           6 :   parameter_solv[TRP].push_back(-77.75716755173752);
+    3008           6 :   parameter_solv[TRP].push_back(-205962.98557711052);
+    3009           6 :   parameter_solv[TRP].push_back(-62013.46984155453);
+    3010           6 :   parameter_solv[TRP].push_back(680710.7592231638);
+    3011           6 :   parameter_solv[TRP].push_back(-681336.8777362367);
+    3012           6 :   parameter_solv[TRP].push_back(211473.65530642506);
+    3013             : 
+    3014           6 :   parameter_solv[TYR].push_back(46250.80359987982);
+    3015           6 :   parameter_solv[TYR].push_back(-45.8287864681578);
+    3016           6 :   parameter_solv[TYR].push_back(-143872.91752817619);
+    3017           6 :   parameter_solv[TYR].push_back(-39049.68736409533);
+    3018           6 :   parameter_solv[TYR].push_back(441321.71874090104);
+    3019           6 :   parameter_solv[TYR].push_back(-434478.0972346327);
+    3020           6 :   parameter_solv[TYR].push_back(133179.3694641212);
+    3021             : 
+    3022           6 :   parameter_solv[PHE].push_back(42407.164900118914);
+    3023           6 :   parameter_solv[PHE].push_back(-159.1980754191431);
+    3024           6 :   parameter_solv[PHE].push_back(-123847.86192757386);
+    3025           6 :   parameter_solv[PHE].push_back(-41797.69041575073);
+    3026           6 :   parameter_solv[PHE].push_back(380283.7035277073);
+    3027           6 :   parameter_solv[PHE].push_back(-361432.67247521743);
+    3028           6 :   parameter_solv[PHE].push_back(107750.64978068044);
+    3029             : 
+    3030           6 :   parameter_solv[HIP].push_back(24473.47360011923);
+    3031           6 :   parameter_solv[HIP].push_back(-111.64156672747428);
+    3032           6 :   parameter_solv[HIP].push_back(-65826.16993707925);
+    3033           6 :   parameter_solv[HIP].push_back(-23305.91329798928);
+    3034           6 :   parameter_solv[HIP].push_back(194795.11911635034);
+    3035           6 :   parameter_solv[HIP].push_back(-180454.49458095312);
+    3036           6 :   parameter_solv[HIP].push_back(52699.374196745615);
+    3037             : 
+    3038           6 :   parameter_solv[ARG].push_back(34106.70239988039);
+    3039           6 :   parameter_solv[ARG].push_back(152.7472727640246);
+    3040           6 :   parameter_solv[ARG].push_back(-117086.49392248681);
+    3041           6 :   parameter_solv[ARG].push_back(-19664.229479267167);
+    3042           6 :   parameter_solv[ARG].push_back(364454.0909203641);
+    3043           6 :   parameter_solv[ARG].push_back(-382075.8018312776);
+    3044           6 :   parameter_solv[ARG].push_back(122775.75036605193);
+    3045             : 
+    3046           6 :   parameter_solv[LYS].push_back(32292.090000118922);
+    3047           6 :   parameter_solv[LYS].push_back(-111.97371180593888);
+    3048           6 :   parameter_solv[LYS].push_back(-91953.10997619898);
+    3049           6 :   parameter_solv[LYS].push_back(-30690.807047993283);
+    3050           6 :   parameter_solv[LYS].push_back(282092.40760143084);
+    3051           6 :   parameter_solv[LYS].push_back(-269503.2592457489);
+    3052           6 :   parameter_solv[LYS].push_back(80777.81552915688);
+    3053             : 
+    3054           6 :   parameter_solv[CYS].push_back(11352.902500119093);
+    3055           6 :   parameter_solv[CYS].push_back(-45.5226331859686);
+    3056           6 :   parameter_solv[CYS].push_back(-20925.085562607524);
+    3057           6 :   parameter_solv[CYS].push_back(-5662.685408989286);
+    3058           6 :   parameter_solv[CYS].push_back(38559.10376731146);
+    3059           6 :   parameter_solv[CYS].push_back(-27885.23426006181);
+    3060           6 :   parameter_solv[CYS].push_back(6280.15058191397);
+    3061             : 
+    3062           6 :   parameter_solv[ASP].push_back(13511.73760011933);
+    3063           6 :   parameter_solv[ASP].push_back(-59.929111107656595);
+    3064           6 :   parameter_solv[ASP].push_back(-25849.869639655575);
+    3065           6 :   parameter_solv[ASP].push_back(-7541.669448872824);
+    3066           6 :   parameter_solv[ASP].push_back(50760.92045144903);
+    3067           6 :   parameter_solv[ASP].push_back(-37677.87583269734);
+    3068           6 :   parameter_solv[ASP].push_back(8745.7056219399);
+    3069             : 
+    3070           6 :   parameter_solv[GLU].push_back(20443.280400119456);
+    3071           6 :   parameter_solv[GLU].push_back(-113.77561814283207);
+    3072           6 :   parameter_solv[GLU].push_back(-45587.79314626863);
+    3073           6 :   parameter_solv[GLU].push_back(-16187.556837331254);
+    3074           6 :   parameter_solv[GLU].push_back(112609.65830609271);
+    3075           6 :   parameter_solv[GLU].push_back(-93362.05323205091);
+    3076           6 :   parameter_solv[GLU].push_back(24519.557866124724);
+    3077             : 
+    3078           6 :   parameter_solv[ILE].push_back(27858.948100119596);
+    3079           6 :   parameter_solv[ILE].push_back(-159.27355145839834);
+    3080           6 :   parameter_solv[ILE].push_back(-61571.43463039565);
+    3081           6 :   parameter_solv[ILE].push_back(-21324.879474559468);
+    3082           6 :   parameter_solv[ILE].push_back(144070.7572894681);
+    3083           6 :   parameter_solv[ILE].push_back(-115021.81959095894);
+    3084           6 :   parameter_solv[ILE].push_back(28939.085108838968);
+    3085             : 
+    3086           6 :   parameter_solv[LEU].push_back(27858.948100119596);
+    3087           6 :   parameter_solv[LEU].push_back(-165.61892007509647);
+    3088           6 :   parameter_solv[LEU].push_back(-62564.568746500125);
+    3089           6 :   parameter_solv[LEU].push_back(-22465.332149768525);
+    3090           6 :   parameter_solv[LEU].push_back(151616.79489291538);
+    3091           6 :   parameter_solv[LEU].push_back(-122905.6119395393);
+    3092           6 :   parameter_solv[LEU].push_back(31436.664377885514);
+    3093             : 
+    3094           6 :   parameter_solv[MET].push_back(25609.60090011981);
+    3095           6 :   parameter_solv[MET].push_back(-135.38857843066708);
+    3096           6 :   parameter_solv[MET].push_back(-67771.01108177133);
+    3097           6 :   parameter_solv[MET].push_back(-25228.934337676077);
+    3098           6 :   parameter_solv[MET].push_back(199649.95030712147);
+    3099           6 :   parameter_solv[MET].push_back(-182251.94895101967);
+    3100           6 :   parameter_solv[MET].push_back(52502.88444247481);
+    3101             : 
+    3102           6 :   parameter_solv[ASN].push_back(14376.010000119095);
+    3103           6 :   parameter_solv[ASN].push_back(-67.65579048748472);
+    3104           6 :   parameter_solv[ASN].push_back(-28302.87809850141);
+    3105           6 :   parameter_solv[ASN].push_back(-8577.439830985548);
+    3106           6 :   parameter_solv[ASN].push_back(57532.879075695324);
+    3107           6 :   parameter_solv[ASN].push_back(-43261.79286366774);
+    3108           6 :   parameter_solv[ASN].push_back(10186.448634149085);
+    3109             : 
+    3110           6 :   parameter_solv[PRO].push_back(16866.21690011944);
+    3111           6 :   parameter_solv[PRO].push_back(-70.84327801054884);
+    3112           6 :   parameter_solv[PRO].push_back(-31465.84064925844);
+    3113           6 :   parameter_solv[PRO].push_back(-8653.3693368317);
+    3114           6 :   parameter_solv[PRO].push_back(58032.28250733714);
+    3115           6 :   parameter_solv[PRO].push_back(-41521.01146771431);
+    3116           6 :   parameter_solv[PRO].push_back(9184.530596102064);
+    3117             : 
+    3118           6 :   parameter_solv[GLN].push_back(21503.289600119);
+    3119           6 :   parameter_solv[GLN].push_back(-121.30164008960246);
+    3120           6 :   parameter_solv[GLN].push_back(-50468.580981118175);
+    3121           6 :   parameter_solv[GLN].push_back(-18462.49098408308);
+    3122           6 :   parameter_solv[GLN].push_back(132718.44904081387);
+    3123           6 :   parameter_solv[GLN].push_back(-113787.22666510186);
+    3124           6 :   parameter_solv[GLN].push_back(30920.348610969988);
+    3125             : 
+    3126           6 :   parameter_solv[SER].push_back(9181.472400119354);
+    3127           6 :   parameter_solv[SER].push_back(-28.77519915767741);
+    3128           6 :   parameter_solv[SER].push_back(-15205.543144104717);
+    3129           6 :   parameter_solv[SER].push_back(-3377.782176346411);
+    3130           6 :   parameter_solv[SER].push_back(23345.555771001076);
+    3131           6 :   parameter_solv[SER].push_back(-15312.694356014094);
+    3132           6 :   parameter_solv[SER].push_back(3013.8428466148);
+    3133             : 
+    3134           6 :   parameter_solv[THR].push_back(15020.953600119403);
+    3135           6 :   parameter_solv[THR].push_back(-61.91004832631006);
+    3136           6 :   parameter_solv[THR].push_back(-27814.537889259853);
+    3137           6 :   parameter_solv[THR].push_back(-7532.227289701552);
+    3138           6 :   parameter_solv[THR].push_back(50586.30566118166);
+    3139           6 :   parameter_solv[THR].push_back(-35943.866131120165);
+    3140           6 :   parameter_solv[THR].push_back(7880.093558764326);
+    3141             : 
+    3142           6 :   parameter_solv[VAL].push_back(19647.628900119355);
+    3143           6 :   parameter_solv[VAL].push_back(-89.04983250107853);
+    3144           6 :   parameter_solv[VAL].push_back(-38050.09958470928);
+    3145           6 :   parameter_solv[VAL].push_back(-10921.427112288537);
+    3146           6 :   parameter_solv[VAL].push_back(72774.32322962297);
+    3147           6 :   parameter_solv[VAL].push_back(-52689.060152305225);
+    3148           6 :   parameter_solv[VAL].push_back(11806.492503632868);
+    3149             : 
+    3150           6 :   parameter_solv[ALA].push_back(7515.156100119276);
+    3151           6 :   parameter_solv[ALA].push_back(-20.226381685697746);
+    3152           6 :   parameter_solv[ALA].push_back(-11761.841094237716);
+    3153           6 :   parameter_solv[ALA].push_back(-2341.4929468980367);
+    3154           6 :   parameter_solv[ALA].push_back(16545.385777961936);
+    3155           6 :   parameter_solv[ALA].push_back(-10397.175253025776);
+    3156           6 :   parameter_solv[ALA].push_back(1921.5264606725107);
+    3157             : 
+    3158           6 :   parameter_solv[GLY].push_back(3594.002500119159);
+    3159           6 :   parameter_solv[GLY].push_back(-6.910836154887606);
+    3160           6 :   parameter_solv[GLY].push_back(-4937.354220666574);
+    3161           6 :   parameter_solv[GLY].push_back(-785.4549468992149);
+    3162           6 :   parameter_solv[GLY].push_back(5852.854429532936);
+    3163           6 :   parameter_solv[GLY].push_back(-3391.2927115487832);
+    3164           6 :   parameter_solv[GLY].push_back(552.3280571490722);
+    3165             : 
+    3166           6 :   parameter_solv[HIS].push_back(22888.664100119073);
+    3167           6 :   parameter_solv[HIS].push_back(-133.86265270962434);
+    3168           6 :   parameter_solv[HIS].push_back(-57533.51591635819);
+    3169           6 :   parameter_solv[HIS].push_back(-21767.293192014684);
+    3170           6 :   parameter_solv[HIS].push_back(161255.14120001195);
+    3171           6 :   parameter_solv[HIS].push_back(-142176.64081149307);
+    3172           6 :   parameter_solv[HIS].push_back(39642.61185646193);
+    3173             : 
+    3174           6 :   parameter_mix[TRP].push_back(48294.0117571196);
+    3175           6 :   parameter_mix[TRP].push_back(-205.45879626487798);
+    3176           6 :   parameter_mix[TRP].push_back(-148816.1858118254);
+    3177           6 :   parameter_mix[TRP].push_back(-54968.030079609875);
+    3178           6 :   parameter_mix[TRP].push_back(491793.79967057955);
+    3179           6 :   parameter_mix[TRP].push_back(-476312.9117969879);
+    3180           6 :   parameter_mix[TRP].push_back(144159.96165644142);
+    3181             : 
+    3182           6 :   parameter_mix[TYR].push_back(36984.20240312081);
+    3183           6 :   parameter_mix[TYR].push_back(-83.86380083812203);
+    3184           6 :   parameter_mix[TYR].push_back(-108820.52211887162);
+    3185           6 :   parameter_mix[TYR].push_back(-33934.69818901515);
+    3186           6 :   parameter_mix[TYR].push_back(341504.736372253);
+    3187           6 :   parameter_mix[TYR].push_back(-334008.1748614056);
+    3188           6 :   parameter_mix[TYR].push_back(102033.08077851454);
+    3189             : 
+    3190           6 :   parameter_mix[PHE].push_back(32119.469231338233);
+    3191           6 :   parameter_mix[PHE].push_back(-172.96940450568917);
+    3192           6 :   parameter_mix[PHE].push_back(-85831.4326887122);
+    3193           6 :   parameter_mix[PHE].push_back(-33193.32405438845);
+    3194           6 :   parameter_mix[PHE].push_back(262940.64471909316);
+    3195           6 :   parameter_mix[PHE].push_back(-243540.06898907054);
+    3196           6 :   parameter_mix[PHE].push_back(71084.54387480798);
+    3197             : 
+    3198           6 :   parameter_mix[HIP].push_back(22833.36414923898);
+    3199           6 :   parameter_mix[HIP].push_back(-134.0493955562186);
+    3200           6 :   parameter_mix[HIP].push_back(-55325.55607328898);
+    3201           6 :   parameter_mix[HIP].push_back(-21898.314938881984);
+    3202           6 :   parameter_mix[HIP].push_back(159995.6912885654);
+    3203           6 :   parameter_mix[HIP].push_back(-142968.19796084083);
+    3204           6 :   parameter_mix[HIP].push_back(40417.44581470003);
+    3205             : 
+    3206           6 :   parameter_mix[ARG].push_back(31385.401600920715);
+    3207           6 :   parameter_mix[ARG].push_back(36.114094042884254);
+    3208           6 :   parameter_mix[ARG].push_back(-103730.44467490204);
+    3209           6 :   parameter_mix[ARG].push_back(-27036.249157905615);
+    3210           6 :   parameter_mix[ARG].push_back(347011.0339314942);
+    3211           6 :   parameter_mix[ARG].push_back(-358879.9736802336);
+    3212           6 :   parameter_mix[ARG].push_back(114432.18361399164);
+    3213             : 
+    3214           6 :   parameter_mix[LYS].push_back(25511.35812671878);
+    3215           6 :   parameter_mix[LYS].push_back(-130.4381491986372);
+    3216           6 :   parameter_mix[LYS].push_back(-69258.61236879184);
+    3217           6 :   parameter_mix[LYS].push_back(-27066.36783798707);
+    3218           6 :   parameter_mix[LYS].push_back(220092.65231165203);
+    3219           6 :   parameter_mix[LYS].push_back(-207794.5056092443);
+    3220           6 :   parameter_mix[LYS].push_back(61665.57004630315);
+    3221             : 
+    3222           6 :   parameter_mix[CYS].push_back(11505.517261618916);
+    3223           6 :   parameter_mix[CYS].push_back(-33.60468076978334);
+    3224           6 :   parameter_mix[CYS].push_back(-18328.882710004465);
+    3225           6 :   parameter_mix[CYS].push_back(-3956.9113649567626);
+    3226           6 :   parameter_mix[CYS].push_back(27546.35146501212);
+    3227           6 :   parameter_mix[CYS].push_back(-18024.826330595406);
+    3228           6 :   parameter_mix[CYS].push_back(3551.2207387570024);
+    3229             : 
+    3230           6 :   parameter_mix[ASP].push_back(13713.858501879382);
+    3231           6 :   parameter_mix[ASP].push_back(-51.33286241257164);
+    3232           6 :   parameter_mix[ASP].push_back(-23807.8549764091);
+    3233           6 :   parameter_mix[ASP].push_back(-6153.667315935503);
+    3234           6 :   parameter_mix[ASP].push_back(41296.118377286424);
+    3235           6 :   parameter_mix[ASP].push_back(-28740.28391184026);
+    3236           6 :   parameter_mix[ASP].push_back(6132.671533319127);
+    3237             : 
+    3238           6 :   parameter_mix[GLU].push_back(19156.03660739947);
+    3239           6 :   parameter_mix[GLU].push_back(-110.90600703589246);
+    3240           6 :   parameter_mix[GLU].push_back(-40319.3351514524);
+    3241           6 :   parameter_mix[GLU].push_back(-14679.813393816446);
+    3242           6 :   parameter_mix[GLU].push_back(96769.28565573556);
+    3243           6 :   parameter_mix[GLU].push_back(-77909.09315520026);
+    3244           6 :   parameter_mix[GLU].push_back(19770.047062759568);
+    3245             : 
+    3246           6 :   parameter_mix[ILE].push_back(20693.06215917923);
+    3247           6 :   parameter_mix[ILE].push_back(-102.87208880594848);
+    3248           6 :   parameter_mix[ILE].push_back(-41080.44036311675);
+    3249           6 :   parameter_mix[ILE].push_back(-12874.439649378206);
+    3250           6 :   parameter_mix[ILE].push_back(84947.33147117581);
+    3251           6 :   parameter_mix[ILE].push_back(-63779.07871450237);
+    3252           6 :   parameter_mix[ILE].push_back(14938.919981690511);
+    3253             : 
+    3254           6 :   parameter_mix[LEU].push_back(20693.062159179233);
+    3255           6 :   parameter_mix[LEU].push_back(-114.09539845409269);
+    3256           6 :   parameter_mix[LEU].push_back(-42417.3431074524);
+    3257           6 :   parameter_mix[LEU].push_back(-14393.801090829746);
+    3258           6 :   parameter_mix[LEU].push_back(93640.48403643962);
+    3259           6 :   parameter_mix[LEU].push_back(-71990.10354816525);
+    3260           6 :   parameter_mix[LEU].push_back(17299.01082057651);
+    3261             : 
+    3262           6 :   parameter_mix[MET].push_back(22400.800002738917);
+    3263           6 :   parameter_mix[MET].push_back(-138.14469221559762);
+    3264           6 :   parameter_mix[MET].push_back(-53013.97694299946);
+    3265           6 :   parameter_mix[MET].push_back(-21079.899452619244);
+    3266           6 :   parameter_mix[MET].push_back(148607.1089339919);
+    3267           6 :   parameter_mix[MET].push_back(-129827.63962878387);
+    3268           6 :   parameter_mix[MET].push_back(35882.3297822684);
+    3269             : 
+    3270           6 :   parameter_mix[ASN].push_back(14384.287416519475);
+    3271           6 :   parameter_mix[ASN].push_back(-55.24976731179147);
+    3272           6 :   parameter_mix[ASN].push_back(-25372.978199926372);
+    3273           6 :   parameter_mix[ASN].push_back(-6646.452004616925);
+    3274           6 :   parameter_mix[ASN].push_back(44594.5027556148);
+    3275           6 :   parameter_mix[ASN].push_back(-31202.511764907107);
+    3276           6 :   parameter_mix[ASN].push_back(6703.764135873442);
+    3277             : 
+    3278           6 :   parameter_mix[PRO].push_back(13503.797145659117);
+    3279           6 :   parameter_mix[PRO].push_back(-38.58316011847087);
+    3280           6 :   parameter_mix[PRO].push_back(-21446.17847324053);
+    3281           6 :   parameter_mix[PRO].push_back(-4480.55896170459);
+    3282           6 :   parameter_mix[PRO].push_back(31274.287350083254);
+    3283           6 :   parameter_mix[PRO].push_back(-19984.249229169505);
+    3284           6 :   parameter_mix[PRO].push_back(3782.272312712745);
+    3285             : 
+    3286           6 :   parameter_mix[GLN].push_back(19938.23724683901);
+    3287           6 :   parameter_mix[GLN].push_back(-121.24884503048865);
+    3288           6 :   parameter_mix[GLN].push_back(-43928.589472297834);
+    3289           6 :   parameter_mix[GLN].push_back(-16805.069757865473);
+    3290           6 :   parameter_mix[GLN].push_back(112831.61348476357);
+    3291           6 :   parameter_mix[GLN].push_back(-93979.08819184235);
+    3292           6 :   parameter_mix[GLN].push_back(24741.563493163732);
+    3293             : 
+    3294           6 :   parameter_mix[SER].push_back(8813.67020471935);
+    3295           6 :   parameter_mix[SER].push_back(-18.291615317790175);
+    3296           6 :   parameter_mix[SER].push_back(-12585.074732466266);
+    3297           6 :   parameter_mix[SER].push_back(-2064.454891600786);
+    3298           6 :   parameter_mix[SER].push_back(15273.905065790364);
+    3299           6 :   parameter_mix[SER].push_back(-8813.056005263466);
+    3300           6 :   parameter_mix[SER].push_back(1404.9812302289881);
+    3301             : 
+    3302           6 :   parameter_mix[THR].push_back(13233.997179639062);
+    3303           6 :   parameter_mix[THR].push_back(-39.40454157416847);
+    3304           6 :   parameter_mix[THR].push_back(-21430.58717233547);
+    3305           6 :   parameter_mix[THR].push_back(-4566.332853710876);
+    3306           6 :   parameter_mix[THR].push_back(31717.497780073558);
+    3307           6 :   parameter_mix[THR].push_back(-20299.614304281313);
+    3308           6 :   parameter_mix[THR].push_back(3837.207224537505);
+    3309             : 
+    3310           6 :   parameter_mix[VAL].push_back(15135.438016299158);
+    3311           6 :   parameter_mix[VAL].push_back(-51.415141550353205);
+    3312           6 :   parameter_mix[VAL].push_back(-25859.078442379723);
+    3313           6 :   parameter_mix[VAL].push_back(-6007.697291593915);
+    3314           6 :   parameter_mix[VAL].push_back(40997.969600345634);
+    3315           6 :   parameter_mix[VAL].push_back(-27036.257386814148);
+    3316           6 :   parameter_mix[VAL].push_back(5328.922363811635);
+    3317             : 
+    3318           6 :   parameter_mix[ALA].push_back(6586.942863819189);
+    3319           6 :   parameter_mix[ALA].push_back(-10.96713559950907);
+    3320           6 :   parameter_mix[ALA].push_back(-8758.836131731925);
+    3321           6 :   parameter_mix[ALA].push_back(-1223.1723720922605);
+    3322           6 :   parameter_mix[ALA].push_back(9475.182453543037);
+    3323           6 :   parameter_mix[ALA].push_back(-5124.611191433804);
+    3324           6 :   parameter_mix[ALA].push_back(721.7625962949869);
+    3325             : 
+    3326           6 :   parameter_mix[GLY].push_back(3596.0718542192762);
+    3327           6 :   parameter_mix[GLY].push_back(-4.079285964028122);
+    3328           6 :   parameter_mix[GLY].push_back(-4089.4217504382686);
+    3329           6 :   parameter_mix[GLY].push_back(-450.9650932154967);
+    3330           6 :   parameter_mix[GLY].push_back(3737.026778223427);
+    3331           6 :   parameter_mix[GLY].push_back(-1862.9856575810572);
+    3332           6 :   parameter_mix[GLY].push_back(222.97288276257262);
+    3333             : 
+    3334           6 :   parameter_mix[HIS].push_back(21779.124723299232);
+    3335           6 :   parameter_mix[HIS].push_back(-131.4603421188538);
+    3336           6 :   parameter_mix[HIS].push_back(-49068.74667421681);
+    3337           6 :   parameter_mix[HIS].push_back(-18685.909496392127);
+    3338           6 :   parameter_mix[HIS].push_back(127724.60792384286);
+    3339           6 :   parameter_mix[HIS].push_back(-107419.22159440348);
+    3340           6 :   parameter_mix[HIS].push_back(28577.228634530744);
+    3341             : 
+    3342           6 :   parameter_vac[TRP].push_back(9599.949107368187);
+    3343           6 :   parameter_vac[TRP].push_back(-66.35331786175249);
+    3344           6 :   parameter_vac[TRP].push_back(-26311.640290970638);
+    3345           6 :   parameter_vac[TRP].push_back(-11577.314600529338);
+    3346           6 :   parameter_vac[TRP].push_back(85847.52554160352);
+    3347           6 :   parameter_vac[TRP].push_back(-79417.17065742958);
+    3348           6 :   parameter_vac[TRP].push_back(23090.348430572863);
+    3349             : 
+    3350           6 :   parameter_vac[TYR].push_back(7393.553846412945);
+    3351           6 :   parameter_vac[TYR].push_back(-27.51954035778316);
+    3352           6 :   parameter_vac[TYR].push_back(-20329.10485615286);
+    3353           6 :   parameter_vac[TYR].push_back(-7444.276340508767);
+    3354           6 :   parameter_vac[TYR].push_back(66343.22315132803);
+    3355           6 :   parameter_vac[TYR].push_back(-64470.58721639446);
+    3356           6 :   parameter_vac[TYR].push_back(19614.63563898146);
+    3357             : 
+    3358           6 :   parameter_vac[PHE].push_back(6081.874997705279);
+    3359           6 :   parameter_vac[PHE].push_back(-40.474695969500104);
+    3360           6 :   parameter_vac[PHE].push_back(-14354.627390498901);
+    3361           6 :   parameter_vac[PHE].push_back(-6156.69750315959);
+    3362           6 :   parameter_vac[PHE].push_back(42580.84239395237);
+    3363           6 :   parameter_vac[PHE].push_back(-37704.09749809582);
+    3364           6 :   parameter_vac[PHE].push_back(10543.005717478625);
+    3365             : 
+    3366           6 :   parameter_vac[HIP].push_back(5325.791987063724);
+    3367           6 :   parameter_vac[HIP].push_back(-35.512112257530156);
+    3368           6 :   parameter_vac[HIP].push_back(-11488.443296477566);
+    3369           6 :   parameter_vac[HIP].push_back(-4916.724935318093);
+    3370           6 :   parameter_vac[HIP].push_back(32134.338675979947);
+    3371           6 :   parameter_vac[HIP].push_back(-27388.387595464188);
+    3372           6 :   parameter_vac[HIP].push_back(7359.899986748838);
+    3373             : 
+    3374           6 :   parameter_vac[ARG].push_back(7220.306892248294);
+    3375           6 :   parameter_vac[ARG].push_back(-20.65912886190997);
+    3376           6 :   parameter_vac[ARG].push_back(-22700.70129646048);
+    3377           6 :   parameter_vac[ARG].push_back(-8696.901551172636);
+    3378           6 :   parameter_vac[ARG].push_back(83641.36257312517);
+    3379           6 :   parameter_vac[ARG].push_back(-85237.33676336925);
+    3380           6 :   parameter_vac[ARG].push_back(26899.162688310953);
+    3381             : 
+    3382           6 :   parameter_vac[LYS].push_back(5038.613120729022);
+    3383           6 :   parameter_vac[LYS].push_back(-34.08366887546492);
+    3384           6 :   parameter_vac[LYS].push_back(-12812.921120433106);
+    3385           6 :   parameter_vac[LYS].push_back(-5843.761329082788);
+    3386           6 :   parameter_vac[LYS].push_back(42419.08427856609);
+    3387           6 :   parameter_vac[LYS].push_back(-39460.49038159249);
+    3388           6 :   parameter_vac[LYS].push_back(11542.320830663035);
+    3389             : 
+    3390           6 :   parameter_vac[CYS].push_back(2915.0458981763995);
+    3391           6 :   parameter_vac[CYS].push_back(-5.380571839804511);
+    3392           6 :   parameter_vac[CYS].push_back(-3865.366285883624);
+    3393           6 :   parameter_vac[CYS].push_back(-602.3275271136284);
+    3394           6 :   parameter_vac[CYS].push_back(4524.133086072617);
+    3395           6 :   parameter_vac[CYS].push_back(-2537.87137720241);
+    3396           6 :   parameter_vac[CYS].push_back(381.52870758240016);
+    3397             : 
+    3398           6 :   parameter_vac[ASP].push_back(3479.750728224898);
+    3399           6 :   parameter_vac[ASP].push_back(-10.33897891836596);
+    3400           6 :   parameter_vac[ASP].push_back(-5382.628188436401);
+    3401           6 :   parameter_vac[ASP].push_back(-1183.8060939576694);
+    3402           6 :   parameter_vac[ASP].push_back(8100.082378727997);
+    3403           6 :   parameter_vac[ASP].push_back(-5162.630696148773);
+    3404           6 :   parameter_vac[ASP].push_back(958.993022379732);
+    3405             : 
+    3406           6 :   parameter_vac[GLU].push_back(4487.461543955491);
+    3407           6 :   parameter_vac[GLU].push_back(-26.671865751817936);
+    3408           6 :   parameter_vac[GLU].push_back(-8829.738168429001);
+    3409           6 :   parameter_vac[GLU].push_back(-3297.668395415257);
+    3410           6 :   parameter_vac[GLU].push_back(20686.457747123466);
+    3411           6 :   parameter_vac[GLU].push_back(-16030.814134196151);
+    3412           6 :   parameter_vac[GLU].push_back(3858.4457728083275);
+    3413             : 
+    3414           6 :   parameter_vac[ILE].push_back(3842.5968201937776);
+    3415           6 :   parameter_vac[ILE].push_back(-13.848165050578492);
+    3416           6 :   parameter_vac[ILE].push_back(-6480.062699452774);
+    3417           6 :   parameter_vac[ILE].push_back(-1636.3888925440413);
+    3418           6 :   parameter_vac[ILE].push_back(10967.333210698738);
+    3419           6 :   parameter_vac[ILE].push_back(-7483.704914714421);
+    3420           6 :   parameter_vac[ILE].push_back(1548.5696047594895);
+    3421             : 
+    3422           6 :   parameter_vac[LEU].push_back(3842.5968201937785);
+    3423           6 :   parameter_vac[LEU].push_back(-16.2745108270949);
+    3424           6 :   parameter_vac[LEU].push_back(-6807.110269770606);
+    3425           6 :   parameter_vac[LEU].push_back(-1926.6303434106014);
+    3426           6 :   parameter_vac[LEU].push_back(12577.952756390941);
+    3427           6 :   parameter_vac[LEU].push_back(-8829.40489330961);
+    3428           6 :   parameter_vac[LEU].push_back(1882.919316016889);
+    3429             : 
+    3430           6 :   parameter_vac[MET].push_back(4898.512892967389);
+    3431           6 :   parameter_vac[MET].push_back(-30.588244886468207);
+    3432           6 :   parameter_vac[MET].push_back(-10159.093665859045);
+    3433           6 :   parameter_vac[MET].push_back(-4025.0261508449653);
+    3434           6 :   parameter_vac[MET].push_back(26007.394369425827);
+    3435           6 :   parameter_vac[MET].push_back(-21199.218680206573);
+    3436           6 :   parameter_vac[MET].push_back(5423.004225853842);
+    3437             : 
+    3438           6 :   parameter_vac[ASN].push_back(3598.1423998115492);
+    3439           6 :   parameter_vac[ASN].push_back(-10.357995638888545);
+    3440           6 :   parameter_vac[ASN].push_back(-5565.603011562138);
+    3441           6 :   parameter_vac[ASN].push_back(-1190.3294930971967);
+    3442           6 :   parameter_vac[ASN].push_back(8227.920711951123);
+    3443           6 :   parameter_vac[ASN].push_back(-5222.61541118056);
+    3444           6 :   parameter_vac[ASN].push_back(968.593406702772);
+    3445             : 
+    3446           6 :   parameter_vac[PRO].push_back(2702.925890807494);
+    3447           6 :   parameter_vac[PRO].push_back(-4.11690159421177);
+    3448           6 :   parameter_vac[PRO].push_back(-3395.325331307625);
+    3449           6 :   parameter_vac[PRO].push_back(-458.95242128002894);
+    3450           6 :   parameter_vac[PRO].push_back(3584.3640448715823);
+    3451           6 :   parameter_vac[PRO].push_back(-1921.4140769384692);
+    3452           6 :   parameter_vac[PRO].push_back(267.08577848319516);
+    3453             : 
+    3454           6 :   parameter_vac[GLN].push_back(4621.773132292556);
+    3455           6 :   parameter_vac[GLN].push_back(-29.511778489038818);
+    3456           6 :   parameter_vac[GLN].push_back(-9486.077450010192);
+    3457           6 :   parameter_vac[GLN].push_back(-3768.5756897489828);
+    3458           6 :   parameter_vac[GLN].push_back(23828.07111260487);
+    3459           6 :   parameter_vac[GLN].push_back(-19110.205836780202);
+    3460           6 :   parameter_vac[GLN].push_back(4791.718204894083);
+    3461             : 
+    3462           6 :   parameter_vac[SER].push_back(2115.1504654043965);
+    3463           6 :   parameter_vac[SER].push_back(-2.4158378234251234);
+    3464           6 :   parameter_vac[SER].push_back(-2488.1131972903822);
+    3465           6 :   parameter_vac[SER].push_back(-263.64072945387693);
+    3466           6 :   parameter_vac[SER].push_back(2251.376687850687);
+    3467           6 :   parameter_vac[SER].push_back(-1066.0790768852626);
+    3468           6 :   parameter_vac[SER].push_back(105.5155397911316);
+    3469             : 
+    3470           6 :   parameter_vac[THR].push_back(2914.9061707158835);
+    3471           6 :   parameter_vac[THR].push_back(-5.032844592364407);
+    3472           6 :   parameter_vac[THR].push_back(-3903.2546253886653);
+    3473           6 :   parameter_vac[THR].push_back(-559.4734271244915);
+    3474           6 :   parameter_vac[THR].push_back(4315.044828297787);
+    3475           6 :   parameter_vac[THR].push_back(-2331.211908177365);
+    3476           6 :   parameter_vac[THR].push_back(323.76849758109853);
+    3477             : 
+    3478           6 :   parameter_vac[VAL].push_back(2914.8744247581953);
+    3479           6 :   parameter_vac[VAL].push_back(-5.847217106105881);
+    3480           6 :   parameter_vac[VAL].push_back(-4096.370479502377);
+    3481           6 :   parameter_vac[VAL].push_back(-655.2917606620404);
+    3482           6 :   parameter_vac[VAL].push_back(4888.77261250007);
+    3483           6 :   parameter_vac[VAL].push_back(-2765.7552774385167);
+    3484           6 :   parameter_vac[VAL].push_back(421.9081598033515);
+    3485             : 
+    3486           6 :   parameter_vac[ALA].push_back(1443.3438146824446);
+    3487           6 :   parameter_vac[ALA].push_back(-1.1234573178567506);
+    3488           6 :   parameter_vac[ALA].push_back(-1492.4547663363514);
+    3489           6 :   parameter_vac[ALA].push_back(-121.47935619968672);
+    3490           6 :   parameter_vac[ALA].push_back(1139.689871538201);
+    3491           6 :   parameter_vac[ALA].push_back(-483.8336547914466);
+    3492           6 :   parameter_vac[ALA].push_back(32.48231950404626);
+    3493             : 
+    3494           6 :   parameter_vac[GLY].push_back(899.5356000422925);
+    3495           6 :   parameter_vac[GLY].push_back(-0.5200880084066986);
+    3496           6 :   parameter_vac[GLY].push_back(-787.5892053280859);
+    3497           6 :   parameter_vac[GLY].push_back(-56.07596224884467);
+    3498           6 :   parameter_vac[GLY].push_back(546.4212287680981);
+    3499           6 :   parameter_vac[GLY].push_back(-222.2667666932616);
+    3500           6 :   parameter_vac[GLY].push_back(12.474587265791476);
+    3501             : 
+    3502           6 :   parameter_vac[HIS].push_back(5180.842705000207);
+    3503           6 :   parameter_vac[HIS].push_back(-29.578973475252766);
+    3504           6 :   parameter_vac[HIS].push_back(-10323.417251934066);
+    3505           6 :   parameter_vac[HIS].push_back(-3788.977215582307);
+    3506           6 :   parameter_vac[HIS].push_back(24427.720792289427);
+    3507           6 :   parameter_vac[HIS].push_back(-19307.35836837878);
+    3508           6 :   parameter_vac[HIS].push_back(4780.831414992477);
+    3509             : 
+    3510             :   // NUCLEIC ACIDS
+    3511             : 
+    3512           6 :   parameter_solv[BB_PO2].push_back(575.5201001192197);
+    3513           6 :   parameter_solv[BB_PO2].push_back(-0.6126595489733868);
+    3514           6 :   parameter_solv[BB_PO2].push_back(-623.3371092254897);
+    3515           6 :   parameter_solv[BB_PO2].push_back(-68.05795957022156);
+    3516           6 :   parameter_solv[BB_PO2].push_back(561.8052621243662);
+    3517           6 :   parameter_solv[BB_PO2].push_back(-283.39573309540344);
+    3518           6 :   parameter_solv[BB_PO2].push_back(35.55001698010027);
+    3519             : 
+    3520           6 :   parameter_solv[BB_DNA].push_back(21211.009600118316);
+    3521           6 :   parameter_solv[BB_DNA].push_back(-90.18805990529991);
+    3522           6 :   parameter_solv[BB_DNA].push_back(-39731.1337351215);
+    3523           6 :   parameter_solv[BB_DNA].push_back(-10920.373563712878);
+    3524           6 :   parameter_solv[BB_DNA].push_back(72882.21702424977);
+    3525           6 :   parameter_solv[BB_DNA].push_back(-51747.487078112754);
+    3526           6 :   parameter_solv[BB_DNA].push_back(11308.67842901876);
+    3527             : 
+    3528           6 :   parameter_solv[BB_DNA_5].push_back(22737.624100119025);
+    3529           6 :   parameter_solv[BB_DNA_5].push_back(-102.72714886664163);
+    3530           6 :   parameter_solv[BB_DNA_5].push_back(-43685.329677789705);
+    3531           6 :   parameter_solv[BB_DNA_5].push_back(-12564.259374093454);
+    3532           6 :   parameter_solv[BB_DNA_5].push_back(83454.87540484876);
+    3533           6 :   parameter_solv[BB_DNA_5].push_back(-60367.15652138888);
+    3534           6 :   parameter_solv[BB_DNA_5].push_back(13507.33372986899);
+    3535             : 
+    3536           6 :   parameter_solv[BB_DNA_3].push_back(22737.62410011902);
+    3537           6 :   parameter_solv[BB_DNA_3].push_back(-101.57816684452263);
+    3538           6 :   parameter_solv[BB_DNA_3].push_back(-43488.53670557616);
+    3539           6 :   parameter_solv[BB_DNA_3].push_back(-12345.056184958417);
+    3540           6 :   parameter_solv[BB_DNA_3].push_back(81963.5236411489);
+    3541           6 :   parameter_solv[BB_DNA_3].push_back(-58791.59443618196);
+    3542           6 :   parameter_solv[BB_DNA_3].push_back(13003.199362335576);
+    3543             : 
+    3544           6 :   parameter_solv[BB_RNA].push_back(23953.752900120977);
+    3545           6 :   parameter_solv[BB_RNA].push_back(-117.35779348824401);
+    3546           6 :   parameter_solv[BB_RNA].push_back(-47644.41735332837);
+    3547           6 :   parameter_solv[BB_RNA].push_back(-14641.556643789863);
+    3548           6 :   parameter_solv[BB_RNA].push_back(96893.48627050382);
+    3549           6 :   parameter_solv[BB_RNA].push_back(-72249.62534169314);
+    3550           6 :   parameter_solv[BB_RNA].push_back(16792.05552105538);
+    3551             : 
+    3552           6 :   parameter_solv[BB_RNA_5].push_back(25574.406400119024);
+    3553           6 :   parameter_solv[BB_RNA_5].push_back(-131.99642772933734);
+    3554           6 :   parameter_solv[BB_RNA_5].push_back(-52136.51404531249);
+    3555           6 :   parameter_solv[BB_RNA_5].push_back(-16682.14273917604);
+    3556           6 :   parameter_solv[BB_RNA_5].push_back(110278.019216394);
+    3557           6 :   parameter_solv[BB_RNA_5].push_back(-83715.92027818545);
+    3558           6 :   parameter_solv[BB_RNA_5].push_back(19875.891337706045);
+    3559             : 
+    3560           6 :   parameter_solv[BB_RNA_3].push_back(25574.406400119024);
+    3561           6 :   parameter_solv[BB_RNA_3].push_back(-127.96875237036166);
+    3562           6 :   parameter_solv[BB_RNA_3].push_back(-51407.183917584385);
+    3563           6 :   parameter_solv[BB_RNA_3].push_back(-15922.900669975606);
+    3564           6 :   parameter_solv[BB_RNA_3].push_back(105078.58889106264);
+    3565           6 :   parameter_solv[BB_RNA_3].push_back(-78289.16276190648);
+    3566           6 :   parameter_solv[BB_RNA_3].push_back(18156.83214344118);
+    3567             : 
+    3568           6 :   parameter_solv[BASE_A].push_back(13282.562500119211);
+    3569           6 :   parameter_solv[BASE_A].push_back(-76.45124168404048);
+    3570           6 :   parameter_solv[BASE_A].push_back(-28376.06994108963);
+    3571           6 :   parameter_solv[BASE_A].push_back(-9972.910773722022);
+    3572           6 :   parameter_solv[BASE_A].push_back(65873.86341939073);
+    3573           6 :   parameter_solv[BASE_A].push_back(-52064.33492910885);
+    3574           6 :   parameter_solv[BASE_A].push_back(12931.608989412513);
+    3575             : 
+    3576           6 :   parameter_solv[BASE_C].push_back(10600.76160011891);
+    3577           6 :   parameter_solv[BASE_C].push_back(-49.1670871249108);
+    3578           6 :   parameter_solv[BASE_C].push_back(-20239.818742072875);
+    3579           6 :   parameter_solv[BASE_C].push_back(-6020.278780090207);
+    3580           6 :   parameter_solv[BASE_C].push_back(39632.13288981881);
+    3581           6 :   parameter_solv[BASE_C].push_back(-28954.779736165576);
+    3582           6 :   parameter_solv[BASE_C].push_back(6551.541109526305);
+    3583             : 
+    3584           6 :   parameter_solv[BASE_G].push_back(15470.384400119934);
+    3585           6 :   parameter_solv[BASE_G].push_back(-93.8013620200972);
+    3586           6 :   parameter_solv[BASE_G].push_back(-36188.29687013545);
+    3587           6 :   parameter_solv[BASE_G].push_back(-13717.685098209471);
+    3588           6 :   parameter_solv[BASE_G].push_back(95658.18473657136);
+    3589           6 :   parameter_solv[BASE_G].push_back(-81262.37811451119);
+    3590           6 :   parameter_solv[BASE_G].push_back(21841.903930943085);
+    3591             : 
+    3592           6 :   parameter_solv[BASE_T].push_back(17210.81610011936);
+    3593           6 :   parameter_solv[BASE_T].push_back(-93.10189802920208);
+    3594           6 :   parameter_solv[BASE_T].push_back(-36466.51927689957);
+    3595           6 :   parameter_solv[BASE_T].push_back(-12425.55615716932);
+    3596           6 :   parameter_solv[BASE_T].push_back(83847.427808925);
+    3597           6 :   parameter_solv[BASE_T].push_back(-66735.64997846584);
+    3598           6 :   parameter_solv[BASE_T].push_back(16757.3463987507);
+    3599             : 
+    3600           6 :   parameter_solv[BASE_U].push_back(10909.802500119395);
+    3601           6 :   parameter_solv[BASE_U].push_back(-46.17712672768298);
+    3602           6 :   parameter_solv[BASE_U].push_back(-20149.67695512526);
+    3603           6 :   parameter_solv[BASE_U].push_back(-5590.242961204435);
+    3604           6 :   parameter_solv[BASE_U].push_back(37169.2740983132);
+    3605           6 :   parameter_solv[BASE_U].push_back(-26475.631627167604);
+    3606           6 :   parameter_solv[BASE_U].push_back(5808.201015156168);
+    3607             : 
+    3608           6 :   parameter_mix[BB_PO2].push_back(1487.2888381188868);
+    3609           6 :   parameter_mix[BB_PO2].push_back(-0.6155376265599789);
+    3610           6 :   parameter_mix[BB_PO2].push_back(-1181.5076027691764);
+    3611           6 :   parameter_mix[BB_PO2].push_back(-66.25027450710594);
+    3612           6 :   parameter_mix[BB_PO2].push_back(697.0421991965113);
+    3613           6 :   parameter_mix[BB_PO2].push_back(-261.8559466354847);
+    3614           6 :   parameter_mix[BB_PO2].push_back(9.974337082362194);
+    3615             : 
+    3616           6 :   parameter_mix[BB_DNA].push_back(17766.29474499878);
+    3617           6 :   parameter_mix[BB_DNA].push_back(-48.97330188566253);
+    3618           6 :   parameter_mix[BB_DNA].push_back(-28199.563596327207);
+    3619           6 :   parameter_mix[BB_DNA].push_back(-5623.82085602494);
+    3620           6 :   parameter_mix[BB_DNA].push_back(39646.22954828498);
+    3621           6 :   parameter_mix[BB_DNA].push_back(-24658.81157651943);
+    3622           6 :   parameter_mix[BB_DNA].push_back(4453.73906293146);
+    3623             : 
+    3624           6 :   parameter_mix[BB_DNA_5].push_back(18696.09744203927);
+    3625           6 :   parameter_mix[BB_DNA_5].push_back(-56.29408880833802);
+    3626           6 :   parameter_mix[BB_DNA_5].push_back(-30486.108599707608);
+    3627           6 :   parameter_mix[BB_DNA_5].push_back(-6524.195857141158);
+    3628           6 :   parameter_mix[BB_DNA_5].push_back(45280.80142686446);
+    3629           6 :   parameter_mix[BB_DNA_5].push_back(-29007.98616567993);
+    3630           6 :   parameter_mix[BB_DNA_5].push_back(5488.566965501818);
+    3631             : 
+    3632           6 :   parameter_mix[BB_DNA_3].push_back(18696.097442039274);
+    3633           6 :   parameter_mix[BB_DNA_3].push_back(-55.5645003501971);
+    3634           6 :   parameter_mix[BB_DNA_3].push_back(-30422.262113654506);
+    3635           6 :   parameter_mix[BB_DNA_3].push_back(-6409.659659309089);
+    3636           6 :   parameter_mix[BB_DNA_3].push_back(44605.76043515699);
+    3637           6 :   parameter_mix[BB_DNA_3].push_back(-28295.62152988411);
+    3638           6 :   parameter_mix[BB_DNA_3].push_back(5262.5765863484);
+    3639             : 
+    3640           6 :   parameter_mix[BB_RNA].push_back(21356.177105457366);
+    3641           6 :   parameter_mix[BB_RNA].push_back(-76.73490647754872);
+    3642           6 :   parameter_mix[BB_RNA].push_back(-36845.234814782816);
+    3643           6 :   parameter_mix[BB_RNA].push_back(-9066.559625582728);
+    3644           6 :   parameter_mix[BB_RNA].push_back(61167.998793390485);
+    3645           6 :   parameter_mix[BB_RNA].push_back(-41467.23384423218);
+    3646           6 :   parameter_mix[BB_RNA].push_back(8518.937793863257);
+    3647             : 
+    3648           6 :   parameter_mix[BB_RNA_5].push_back(22386.63276427916);
+    3649           6 :   parameter_mix[BB_RNA_5].push_back(-85.70426456933487);
+    3650           6 :   parameter_mix[BB_RNA_5].push_back(-39490.50298502025);
+    3651           6 :   parameter_mix[BB_RNA_5].push_back(-10223.702594972712);
+    3652           6 :   parameter_mix[BB_RNA_5].push_back(68450.60459618448);
+    3653           6 :   parameter_mix[BB_RNA_5].push_back(-47409.91098159006);
+    3654           6 :   parameter_mix[BB_RNA_5].push_back(10031.136138513202);
+    3655             : 
+    3656           6 :   parameter_mix[BB_RNA_3].push_back(22386.63276427916);
+    3657           6 :   parameter_mix[BB_RNA_3].push_back(-81.93760812351479);
+    3658           6 :   parameter_mix[BB_RNA_3].push_back(-39031.70571520093);
+    3659           6 :   parameter_mix[BB_RNA_3].push_back(-9666.316086142708);
+    3660           6 :   parameter_mix[BB_RNA_3].push_back(65120.07128126262);
+    3661           6 :   parameter_mix[BB_RNA_3].push_back(-44110.13603681317);
+    3662           6 :   parameter_mix[BB_RNA_3].push_back(9036.76498256983);
+    3663             : 
+    3664           6 :   parameter_mix[BASE_A].push_back(15897.31116611889);
+    3665           6 :   parameter_mix[BASE_A].push_back(-67.86385832953485);
+    3666           6 :   parameter_mix[BASE_A].push_back(-28851.754660951636);
+    3667           6 :   parameter_mix[BASE_A].push_back(-8144.431687170413);
+    3668           6 :   parameter_mix[BASE_A].push_back(53606.39082954489);
+    3669           6 :   parameter_mix[BASE_A].push_back(-38083.51243782253);
+    3670           6 :   parameter_mix[BASE_A].push_back(8293.47107993253);
+    3671             : 
+    3672           6 :   parameter_mix[BASE_C].push_back(11733.2828871599);
+    3673           6 :   parameter_mix[BASE_C].push_back(-38.76775400274115);
+    3674           6 :   parameter_mix[BASE_C].push_back(-19318.84666423464);
+    3675           6 :   parameter_mix[BASE_C].push_back(-4507.915522704176);
+    3676           6 :   parameter_mix[BASE_C].push_back(30576.57671286052);
+    3677           6 :   parameter_mix[BASE_C].push_back(-20132.46696910844);
+    3678           6 :   parameter_mix[BASE_C].push_back(3947.8727087996162);
+    3679             : 
+    3680           6 :   parameter_mix[BASE_G].push_back(19146.612417237808);
+    3681           6 :   parameter_mix[BASE_G].push_back(-102.37046638004914);
+    3682           6 :   parameter_mix[BASE_G].push_back(-38718.96478190546);
+    3683           6 :   parameter_mix[BASE_G].push_back(-13238.106081860074);
+    3684           6 :   parameter_mix[BASE_G].push_back(87309.07460288722);
+    3685           6 :   parameter_mix[BASE_G].push_back(-68364.82442984737);
+    3686           6 :   parameter_mix[BASE_G].push_back(16815.362401369);
+    3687             : 
+    3688           6 :   parameter_mix[BASE_T].push_back(17050.440260819163);
+    3689           6 :   parameter_mix[BASE_T].push_back(-76.33750600643376);
+    3690           6 :   parameter_mix[BASE_T].push_back(-31849.539096715005);
+    3691           6 :   parameter_mix[BASE_T].push_back(-9484.498992751434);
+    3692           6 :   parameter_mix[BASE_T].push_back(62881.895771680494);
+    3693           6 :   parameter_mix[BASE_T].push_back(-46531.948557759024);
+    3694           6 :   parameter_mix[BASE_T].push_back(10734.196329884822);
+    3695             : 
+    3696           6 :   parameter_mix[BASE_U].push_back(11904.095265219023);
+    3697           6 :   parameter_mix[BASE_U].push_back(-34.67511054915295);
+    3698           6 :   parameter_mix[BASE_U].push_back(-18842.275003104005);
+    3699           6 :   parameter_mix[BASE_U].push_back(-3993.1174764890684);
+    3700           6 :   parameter_mix[BASE_U].push_back(27663.625106762345);
+    3701           6 :   parameter_mix[BASE_U].push_back(-17577.387831701515);
+    3702           6 :   parameter_mix[BASE_U].push_back(3273.183903219142);
+    3703             : 
+    3704           6 :   parameter_vac[BB_PO2].push_back(960.8822037291127);
+    3705           6 :   parameter_vac[BB_PO2].push_back(-0.09312135742159174);
+    3706           6 :   parameter_vac[BB_PO2].push_back(-469.39643497461844);
+    3707           6 :   parameter_vac[BB_PO2].push_back(-9.779346709041985);
+    3708           6 :   parameter_vac[BB_PO2].push_back(162.1581550003227);
+    3709           6 :   parameter_vac[BB_PO2].push_back(-37.06686233305618);
+    3710           6 :   parameter_vac[BB_PO2].push_back(-4.695586672655664);
+    3711             : 
+    3712           6 :   parameter_vac[BB_DNA].push_back(3720.2522996838984);
+    3713           6 :   parameter_vac[BB_DNA].push_back(-5.4229642176938);
+    3714           6 :   parameter_vac[BB_DNA].push_back(-4800.897672711981);
+    3715           6 :   parameter_vac[BB_DNA].push_back(-597.2274673070993);
+    3716           6 :   parameter_vac[BB_DNA].push_back(4825.908840953665);
+    3717           6 :   parameter_vac[BB_DNA].push_back(-2451.397454446564);
+    3718           6 :   parameter_vac[BB_DNA].push_back(294.93071756645685);
+    3719             : 
+    3720           6 :   parameter_vac[BB_DNA_5].push_back(3843.234214262163);
+    3721           6 :   parameter_vac[BB_DNA_5].push_back(-6.423078416284452);
+    3722           6 :   parameter_vac[BB_DNA_5].push_back(-5112.1216386963115);
+    3723           6 :   parameter_vac[BB_DNA_5].push_back(-713.8373583426668);
+    3724           6 :   parameter_vac[BB_DNA_5].push_back(5547.545382516269);
+    3725           6 :   parameter_vac[BB_DNA_5].push_back(-2973.5659871174225);
+    3726           6 :   parameter_vac[BB_DNA_5].push_back(407.2789106630427);
+    3727             : 
+    3728           6 :   parameter_vac[BB_DNA_3].push_back(3843.234214262163);
+    3729           6 :   parameter_vac[BB_DNA_3].push_back(-6.268636561475645);
+    3730           6 :   parameter_vac[BB_DNA_3].push_back(-5103.192931218086);
+    3731           6 :   parameter_vac[BB_DNA_3].push_back(-693.8705734390547);
+    3732           6 :   parameter_vac[BB_DNA_3].push_back(5443.979645097035);
+    3733           6 :   parameter_vac[BB_DNA_3].push_back(-2871.4337477324893);
+    3734           6 :   parameter_vac[BB_DNA_3].push_back(377.3062915349831);
+    3735             : 
+    3736           6 :   parameter_vac[BB_RNA].push_back(4760.071443398374);
+    3737           6 :   parameter_vac[BB_RNA].push_back(-11.0990475402486);
+    3738           6 :   parameter_vac[BB_RNA].push_back(-6934.713566418421);
+    3739           6 :   parameter_vac[BB_RNA].push_back(-1256.5202524085096);
+    3740           6 :   parameter_vac[BB_RNA].push_back(9024.962587066922);
+    3741           6 :   parameter_vac[BB_RNA].push_back(-5386.842667932241);
+    3742           6 :   parameter_vac[BB_RNA].push_back(907.42947751372);
+    3743             : 
+    3744           6 :   parameter_vac[BB_RNA_5].push_back(4899.051406033406);
+    3745           6 :   parameter_vac[BB_RNA_5].push_back(-12.279240472628238);
+    3746           6 :   parameter_vac[BB_RNA_5].push_back(-7276.273570813667);
+    3747           6 :   parameter_vac[BB_RNA_5].push_back(-1400.9520839250868);
+    3748           6 :   parameter_vac[BB_RNA_5].push_back(9912.215823228895);
+    3749           6 :   parameter_vac[BB_RNA_5].push_back(-6079.2565270404075);
+    3750           6 :   parameter_vac[BB_RNA_5].push_back(1073.53428175472);
+    3751             : 
+    3752           6 :   parameter_vac[BB_RNA_3].push_back(4899.051406033406);
+    3753           6 :   parameter_vac[BB_RNA_3].push_back(-11.642804195148194);
+    3754           6 :   parameter_vac[BB_RNA_3].push_back(-7213.774619570996);
+    3755           6 :   parameter_vac[BB_RNA_3].push_back(-1317.4463949342964);
+    3756           6 :   parameter_vac[BB_RNA_3].push_back(9450.928929264686);
+    3757           6 :   parameter_vac[BB_RNA_3].push_back(-5643.856117200917);
+    3758           6 :   parameter_vac[BB_RNA_3].push_back(949.4698817407918);
+    3759             : 
+    3760           6 :   parameter_vac[BASE_A].push_back(4756.697028810353);
+    3761           6 :   parameter_vac[BASE_A].push_back(-12.158940746852812);
+    3762           6 :   parameter_vac[BASE_A].push_back(-7106.473423744205);
+    3763           6 :   parameter_vac[BASE_A].push_back(-1376.295184173137);
+    3764           6 :   parameter_vac[BASE_A].push_back(9747.132255557788);
+    3765           6 :   parameter_vac[BASE_A].push_back(-5900.026637038756);
+    3766           6 :   parameter_vac[BASE_A].push_back(1004.6226388342955);
+    3767             : 
+    3768           6 :   parameter_vac[BASE_C].push_back(3246.698975674651);
+    3769           6 :   parameter_vac[BASE_C].push_back(-6.125036521218687);
+    3770           6 :   parameter_vac[BASE_C].push_back(-4280.666521437201);
+    3771           6 :   parameter_vac[BASE_C].push_back(-684.0183580843932);
+    3772           6 :   parameter_vac[BASE_C].push_back(5077.062889522692);
+    3773           6 :   parameter_vac[BASE_C].push_back(-2870.3239317750963);
+    3774           6 :   parameter_vac[BASE_C].push_back(434.51551177863547);
+    3775             : 
+    3776           6 :   parameter_vac[BASE_G].push_back(5924.105658596052);
+    3777           6 :   parameter_vac[BASE_G].push_back(-23.097956587232552);
+    3778           6 :   parameter_vac[BASE_G].push_back(-10149.526301285418);
+    3779           6 :   parameter_vac[BASE_G].push_back(-2752.9166169522528);
+    3780           6 :   parameter_vac[BASE_G].push_back(18239.32985385683);
+    3781           6 :   parameter_vac[BASE_G].push_back(-12749.277858800957);
+    3782           6 :   parameter_vac[BASE_G].push_back(2715.354663787367);
+    3783             : 
+    3784           6 :   parameter_vac[BASE_T].push_back(4222.889713694404);
+    3785           6 :   parameter_vac[BASE_T].push_back(-12.15861456306705);
+    3786           6 :   parameter_vac[BASE_T].push_back(-6395.50289789404);
+    3787           6 :   parameter_vac[BASE_T].push_back(-1421.3942549301012);
+    3788           6 :   parameter_vac[BASE_T].push_back(9757.061008720135);
+    3789           6 :   parameter_vac[BASE_T].push_back(-6399.630933839126);
+    3790           6 :   parameter_vac[BASE_T].push_back(1258.9874225605438);
+    3791             : 
+    3792           6 :   parameter_vac[BASE_U].push_back(3247.251361465539);
+    3793           6 :   parameter_vac[BASE_U].push_back(-5.211020853261115);
+    3794           6 :   parameter_vac[BASE_U].push_back(-4125.165310360279);
+    3795           6 :   parameter_vac[BASE_U].push_back(-575.1860235473902);
+    3796           6 :   parameter_vac[BASE_U].push_back(4457.6562621371495);
+    3797           6 :   parameter_vac[BASE_U].push_back(-2368.7250146912766);
+    3798           6 :   parameter_vac[BASE_U].push_back(313.23997718445014);
+    3799             : 
+    3800       21178 :   for(unsigned i=0; i<atoms.size(); ++i) {
+    3801       21172 :     std::string Aname = pdb.getAtomName(atoms[i]);
+    3802       21172 :     std::string Rname = pdb.getResidueName(atoms[i]);
+    3803       21172 :     Rname.erase(std::remove_if(Rname.begin(), Rname.end(), ::isspace),Rname.end());
+    3804       21172 :     if(Rname=="ALA") {
+    3805        1098 :       atoi[residue_atom[i]]=ALA;
+    3806       20074 :     } else if(Rname=="ARG") {
+    3807        1296 :       atoi[residue_atom[i]]=ARG;
+    3808       18778 :     } else if(Rname=="ASN") {
+    3809        1080 :       atoi[residue_atom[i]]=ASN;
+    3810       17698 :     } else if(Rname=="ASP") {
+    3811         936 :       atoi[residue_atom[i]]=ASP;
+    3812       16762 :     } else if(Rname=="CYS") {
+    3813          72 :       atoi[residue_atom[i]]=CYS;
+    3814       16690 :     } else if(Rname=="GLN") {
+    3815        1596 :       atoi[residue_atom[i]]=GLN;
+    3816       15094 :     } else if(Rname=="GLU") {
+    3817         714 :       atoi[residue_atom[i]]=GLU;
+    3818       14380 :     } else if(Rname=="GLY") {
+    3819         972 :       atoi[residue_atom[i]]=GLY;
+    3820       13408 :     } else if(Rname=="HIS") {
+    3821           0 :       atoi[residue_atom[i]]=HIS;
+    3822       13408 :     } else if(Rname=="HID") {
+    3823           0 :       atoi[residue_atom[i]]=HIS;
+    3824       13408 :     } else if(Rname=="HIE") {
+    3825         216 :       atoi[residue_atom[i]]=HIS;
+    3826       13192 :     } else if(Rname=="HIP") {
+    3827           0 :       atoi[residue_atom[i]]=HIP;
+    3828             :       // CHARMM NAMING FOR PROTONATION STATES OF HISTIDINE
+    3829       13192 :     } else if(Rname=="HSD") {
+    3830           0 :       atoi[residue_atom[i]]=HIS;
+    3831       13192 :     } else if(Rname=="HSE") {
+    3832           0 :       atoi[residue_atom[i]]=HIS;
+    3833       13192 :     } else if(Rname=="HSP") {
+    3834           0 :       atoi[residue_atom[i]]=HIP;
+    3835       13192 :     } else if(Rname=="ILE") {
+    3836        1296 :       atoi[residue_atom[i]]=ILE;
+    3837       11896 :     } else if(Rname=="LEU") {
+    3838        2280 :       atoi[residue_atom[i]]=LEU;
+    3839        9616 :     } else if(Rname=="LYS") {
+    3840        1560 :       atoi[residue_atom[i]]=LYS;
+    3841        8056 :     } else if(Rname=="MET") {
+    3842         912 :       atoi[residue_atom[i]]=MET;
+    3843        7144 :     } else if(Rname=="PHE") {
+    3844        1512 :       atoi[residue_atom[i]]=PHE;
+    3845        5632 :     } else if(Rname=="PRO") {
+    3846        1122 :       atoi[residue_atom[i]]=PRO;
+    3847        4510 :     } else if(Rname=="SER") {
+    3848         792 :       atoi[residue_atom[i]]=SER;
+    3849        3718 :     } else if(Rname=="THR") {
+    3850         756 :       atoi[residue_atom[i]]=THR;
+    3851        2962 :     } else if(Rname=="TRP") {
+    3852           0 :       atoi[residue_atom[i]]=TRP;
+    3853        2962 :     } else if(Rname=="TYR") {
+    3854         792 :       atoi[residue_atom[i]]=TYR;
+    3855        2170 :     } else if(Rname=="VAL") {
+    3856        1632 :       atoi[residue_atom[i]]=VAL;
+    3857             :     }
+    3858             :     // NUCLEIC ACIDS
+    3859             :     // nucleobases are not automatically populated as an additional check on the health of the PDB.
+    3860             :     // RNA - G
+    3861         538 :     else if(Rname=="G") {
+    3862           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    3863           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    3864           0 :         atoi [residue_atom[i]]=BB_PO2;
+    3865           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    3866           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    3867           0 :                 Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    3868           0 :                 Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="H3T"  ||
+    3869           0 :                 Aname=="HO5'" || Aname=="HO3'" || Aname=="HO2'" || Aname=="H5'1" ||
+    3870           0 :                 Aname=="H5'2" || Aname=="HO'2" || Aname=="H2'1" || Aname=="H5T" ) {
+    3871           0 :         atoi[residue_atom[i]]=BB_RNA;
+    3872           0 :       } else if( Aname=="N1" || Aname=="C2"  || Aname=="N2" || Aname=="N3" ||
+    3873           0 :                  Aname=="C4" || Aname=="C5"  || Aname=="C6" || Aname=="O6" ||
+    3874           0 :                  Aname=="N7" || Aname=="C8"  || Aname=="N9" || Aname=="H1" ||
+    3875           0 :                  Aname=="H8" || Aname=="H21" || Aname=="H22" ) {
+    3876           0 :         atoi[residue_atom[i]]=BASE_G;
+    3877           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    3878             :       // RNA - G3
+    3879         538 :     } else if(Rname=="G3") {
+    3880           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    3881           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    3882           0 :         atoi [residue_atom[i]]=BB_PO2;
+    3883           0 :       } else if(Aname=="O5'"  || Aname=="C5'" || Aname=="O4'"  || Aname=="C4'"  ||
+    3884           0 :                 Aname=="O3'"  || Aname=="C3'" || Aname=="O2'"  || Aname=="C2'"  ||
+    3885           0 :                 Aname=="C1'"  || Aname=="H5'" || Aname=="H5''" || Aname=="H4'"  ||
+    3886           0 :                 Aname=="H3'"  || Aname=="H2'" || Aname=="H1'"  || Aname=="H3T"  ||
+    3887           0 :                 Aname=="H2'1" || Aname=="HO3'"|| Aname=="HO2'" || Aname=="H5'1" ||
+    3888           0 :                 Aname=="H5'2" || Aname=="HO'2" ) {
+    3889           0 :         atoi[residue_atom[i]]=BB_RNA_3;
+    3890           0 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="N2" || Aname=="N3" ||
+    3891           0 :                 Aname=="C4" || Aname=="C5"  || Aname=="C6" || Aname=="O6" ||
+    3892           0 :                 Aname=="N7" || Aname=="C8"  || Aname=="N9" || Aname=="H1" ||
+    3893           0 :                 Aname=="H8" || Aname=="H21" || Aname=="H22" ) {
+    3894           0 :         atoi[residue_atom[i]]=BASE_G;
+    3895           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    3896             :       // RNA - G5
+    3897         538 :     } else if(Rname=="G5") {
+    3898           0 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    3899           0 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    3900           0 :           Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    3901           0 :           Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="HO5'" ||
+    3902           0 :           Aname=="HO2'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="HO'2" ||
+    3903           0 :           Aname=="H2'1" || Aname=="H5T" ) {
+    3904           0 :         atoi[residue_atom[i]]=BB_RNA_5;
+    3905           0 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="N2" || Aname=="N3" ||
+    3906           0 :                 Aname=="C4" || Aname=="C5"  || Aname=="C6" || Aname=="O6" ||
+    3907           0 :                 Aname=="N7" || Aname=="C8"  || Aname=="N9" || Aname=="H1" ||
+    3908           0 :                 Aname=="H8" || Aname=="H21" || Aname=="H22" ) {
+    3909           0 :         atoi[residue_atom[i]]=BASE_G;
+    3910           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    3911             :       // RNA - U
+    3912         538 :     } else if(Rname=="U") {
+    3913        1554 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    3914        1176 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    3915          42 :         atoi [residue_atom[i]]=BB_PO2;
+    3916        1372 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    3917        1148 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    3918         924 :                 Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    3919         714 :                 Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="H3T"  ||
+    3920         644 :                 Aname=="HO5'" || Aname=="HO3'" || Aname=="HO2'" || Aname=="H5'1" ||
+    3921         840 :                 Aname=="H5'2" || Aname=="HO'2" || Aname=="H2'1" || Aname=="H5T" ) {
+    3922         224 :         atoi[residue_atom[i]]=BB_RNA;
+    3923         476 :       } else if( Aname=="N1" || Aname=="C2"  || Aname=="O2" || Aname=="N3" ||
+    3924         252 :                  Aname=="C4" || Aname=="O4"  || Aname=="C5" || Aname=="C6" ||
+    3925         196 :                  Aname=="H3" || Aname=="H5"  || Aname=="H6") {
+    3926         154 :         atoi[residue_atom[i]]=BASE_U;
+    3927           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    3928             :       // RNA - U3
+    3929         118 :     } else if(Rname=="U3") {
+    3930         230 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    3931         174 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    3932           6 :         atoi [residue_atom[i]]=BB_PO2;
+    3933         204 :       } else if(Aname=="O5'"  || Aname=="C5'" || Aname=="O4'"  || Aname=="C4'"  ||
+    3934         172 :                 Aname=="O3'"  || Aname=="C3'" || Aname=="O2'"  || Aname=="C2'"  ||
+    3935         140 :                 Aname=="C1'"  || Aname=="H5'" || Aname=="H5''" || Aname=="H4'"  ||
+    3936         110 :                 Aname=="H3'"  || Aname=="H2'" || Aname=="H1'"  || Aname=="H3T"  ||
+    3937          94 :                 Aname=="H2'1" || Aname=="HO3'"|| Aname=="HO2'" || Aname=="H5'1" ||
+    3938          78 :                 Aname=="H5'2" || Aname=="HO'2" ) {
+    3939          34 :         atoi[residue_atom[i]]=BB_RNA_3;
+    3940          68 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="O2" || Aname=="N3" ||
+    3941          36 :                 Aname=="C4" || Aname=="O4"  || Aname=="C5" || Aname=="C6" ||
+    3942          28 :                 Aname=="H3" || Aname=="H5"  || Aname=="H6") {
+    3943          22 :         atoi[residue_atom[i]]=BASE_U;
+    3944           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    3945             :       // RNA - U5
+    3946          56 :     } else if(Rname=="U5") {
+    3947         204 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    3948         172 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    3949         140 :           Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    3950         108 :           Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="HO5'" ||
+    3951          88 :           Aname=="HO2'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="HO'2" ||
+    3952          78 :           Aname=="H2'1" || Aname=="H5T" ) {
+    3953          34 :         atoi[residue_atom[i]]=BB_RNA_5;
+    3954          68 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="O2" || Aname=="N3" ||
+    3955          36 :                 Aname=="C4" || Aname=="O4"  || Aname=="C5" || Aname=="C6" ||
+    3956          28 :                 Aname=="H3" || Aname=="H5"  || Aname=="H6") {
+    3957          22 :         atoi[residue_atom[i]]=BASE_U;
+    3958           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    3959             :       // RNA - A
+    3960           0 :     } else if(Rname=="A") {
+    3961           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    3962           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    3963           0 :         atoi [residue_atom[i]]=BB_PO2;
+    3964           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    3965           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    3966           0 :                 Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    3967           0 :                 Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="H3T"  ||
+    3968           0 :                 Aname=="HO5'" || Aname=="HO3'" || Aname=="HO2'" || Aname=="H5'1" ||
+    3969           0 :                 Aname=="H5'2" || Aname=="HO'2" || Aname=="H2'1" || Aname=="H5T" ) {
+    3970           0 :         atoi[residue_atom[i]]=BB_RNA;
+    3971           0 :       } else if(Aname=="N1"  || Aname=="C2" || Aname=="N3" || Aname=="C4" ||
+    3972           0 :                 Aname=="C5"  || Aname=="C6" || Aname=="N6" || Aname=="N7" ||
+    3973           0 :                 Aname=="C8"  || Aname=="N9" || Aname=="H2" || Aname=="H8" ||
+    3974           0 :                 Aname=="H61" || Aname=="H62" ) {
+    3975           0 :         atoi[residue_atom[i]]=BASE_A;
+    3976           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    3977             :       // RNA - A3
+    3978           0 :     } else if(Rname=="A3") {
+    3979           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    3980           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    3981           0 :         atoi [residue_atom[i]]=BB_PO2;
+    3982           0 :       } else if(Aname=="O5'"  || Aname=="C5'" || Aname=="O4'"  || Aname=="C4'"  ||
+    3983           0 :                 Aname=="O3'"  || Aname=="C3'" || Aname=="O2'"  || Aname=="C2'"  ||
+    3984           0 :                 Aname=="C1'"  || Aname=="H5'" || Aname=="H5''" || Aname=="H4'"  ||
+    3985           0 :                 Aname=="H3'"  || Aname=="H2'" || Aname=="H1'"  || Aname=="H3T"  ||
+    3986           0 :                 Aname=="H2'1" || Aname=="HO3'"|| Aname=="HO2'" || Aname=="H5'1" ||
+    3987           0 :                 Aname=="H5'2" || Aname=="HO'2" ) {
+    3988           0 :         atoi[residue_atom[i]]=BB_RNA_3;
+    3989           0 :       } else if(Aname=="N1"  || Aname=="C2" || Aname=="N3" || Aname=="C4" ||
+    3990           0 :                 Aname=="C5"  || Aname=="C6" || Aname=="N6" || Aname=="N7" ||
+    3991           0 :                 Aname=="C8"  || Aname=="N9" || Aname=="H2" || Aname=="H8" ||
+    3992           0 :                 Aname=="H61" || Aname=="H62" ) {
+    3993           0 :         atoi[residue_atom[i]]=BASE_A;
+    3994           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    3995             :       // RNA - A5
+    3996           0 :     } else if(Rname=="A5") {
+    3997           0 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    3998           0 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    3999           0 :           Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    4000           0 :           Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="HO5'" ||
+    4001           0 :           Aname=="HO2'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="HO'2" ||
+    4002           0 :           Aname=="H2'1" || Aname=="H5T" ) {
+    4003           0 :         atoi[residue_atom[i]]=BB_RNA_5;
+    4004           0 :       } else if(Aname=="N1"  || Aname=="C2" || Aname=="N3" || Aname=="C4" ||
+    4005           0 :                 Aname=="C5"  || Aname=="C6" || Aname=="N6" || Aname=="N7" ||
+    4006           0 :                 Aname=="C8"  || Aname=="N9" || Aname=="H2" || Aname=="H8" ||
+    4007           0 :                 Aname=="H61" || Aname=="H62" ) {
+    4008           0 :         atoi[residue_atom[i]]=BASE_A;
+    4009           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    4010             :       // RNA - C
+    4011           0 :     } else if(Rname=="C") {
+    4012           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    4013           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    4014           0 :         atoi [residue_atom[i]]=BB_PO2;
+    4015           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    4016           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    4017           0 :                 Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    4018           0 :                 Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="H3T"  ||
+    4019           0 :                 Aname=="HO5'" || Aname=="HO3'" || Aname=="HO2'" || Aname=="H5'1" ||
+    4020           0 :                 Aname=="H5'2" || Aname=="HO'2" || Aname=="H2'1" || Aname=="H5T" ) {
+    4021           0 :         atoi[residue_atom[i]]=BB_RNA;
+    4022           0 :       } else if(Aname=="N1" || Aname=="C2" || Aname=="O2"  || Aname=="N3" ||
+    4023           0 :                 Aname=="C4" || Aname=="N4" || Aname=="C5"  || Aname=="C6" ||
+    4024           0 :                 Aname=="H5" || Aname=="H6" || Aname=="H41" || Aname=="H42" ) {
+    4025           0 :         atoi[residue_atom[i]]=BASE_C;
+    4026           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    4027             :       // RNA - C3
+    4028           0 :     } else if(Rname=="C3") {
+    4029           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    4030           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    4031           0 :         atoi [residue_atom[i]]=BB_PO2;
+    4032           0 :       } else if(Aname=="O5'"  || Aname=="C5'" || Aname=="O4'"  || Aname=="C4'"  ||
+    4033           0 :                 Aname=="O3'"  || Aname=="C3'" || Aname=="O2'"  || Aname=="C2'"  ||
+    4034           0 :                 Aname=="C1'"  || Aname=="H5'" || Aname=="H5''" || Aname=="H4'"  ||
+    4035           0 :                 Aname=="H3'"  || Aname=="H2'" || Aname=="H1'"  || Aname=="H3T"  ||
+    4036           0 :                 Aname=="H2'1" || Aname=="HO3'"|| Aname=="HO2'" || Aname=="H5'1" ||
+    4037           0 :                 Aname=="H5'2" || Aname=="HO'2" ) {
+    4038           0 :         atoi[residue_atom[i]]=BB_RNA_3;
+    4039           0 :       } else if(Aname=="N1" || Aname=="C2" || Aname=="O2"  || Aname=="N3" ||
+    4040           0 :                 Aname=="C4" || Aname=="N4" || Aname=="C5"  || Aname=="C6" ||
+    4041           0 :                 Aname=="H5" || Aname=="H6" || Aname=="H41" || Aname=="H42" ) {
+    4042           0 :         atoi[residue_atom[i]]=BASE_C;
+    4043           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    4044             :       // RNA - C5
+    4045           0 :     } else if(Rname=="C5") {
+    4046           0 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    4047           0 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    4048           0 :           Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    4049           0 :           Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="HO5'" ||
+    4050           0 :           Aname=="HO2'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="HO'2" ||
+    4051           0 :           Aname=="H2'1" || Aname=="H5T" ) {
+    4052           0 :         atoi[residue_atom[i]]=BB_RNA_5;
+    4053           0 :       } else if(Aname=="N1" || Aname=="C2" || Aname=="O2"  || Aname=="N3" ||
+    4054           0 :                 Aname=="C4" || Aname=="N4" || Aname=="C5"  || Aname=="C6" ||
+    4055           0 :                 Aname=="H5" || Aname=="H6" || Aname=="H41" || Aname=="H42" ) {
+    4056           0 :         atoi[residue_atom[i]]=BASE_C;
+    4057           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    4058             :       // DNA - G
+    4059           0 :     } else if(Rname=="DG") {
+    4060           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    4061           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    4062           0 :         atoi [residue_atom[i]]=BB_PO2;
+    4063           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    4064           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    4065           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    4066           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    4067           0 :                 Aname=="HO3'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" ||
+    4068           0 :                 Aname=="H2'2" || Aname=="H5T"  || Aname=="H3T" ) {
+    4069           0 :         atoi[residue_atom[i]]=BB_DNA;
+    4070           0 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="N2" || Aname=="N3" ||
+    4071           0 :                 Aname=="C4" || Aname=="C5"  || Aname=="C6" || Aname=="O6" ||
+    4072           0 :                 Aname=="N7" || Aname=="C8"  || Aname=="N9" || Aname=="H1" ||
+    4073           0 :                 Aname=="H8" || Aname=="H21" || Aname=="H22" ) {
+    4074           0 :         atoi[residue_atom[i]]=BASE_G;
+    4075           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    4076             :       // DNA - G3
+    4077           0 :     } else if(Rname=="DG3") {
+    4078           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    4079           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    4080           0 :         atoi [residue_atom[i]]=BB_PO2;
+    4081           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    4082           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    4083           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    4084           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO3'" ||
+    4085           0 :                 Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    4086             :                 Aname=="H3T" ) {
+    4087           0 :         atoi[residue_atom[i]]=BB_DNA_3;
+    4088           0 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="N2" || Aname=="N3" ||
+    4089           0 :                 Aname=="C4" || Aname=="C5"  || Aname=="C6" || Aname=="O6" ||
+    4090           0 :                 Aname=="N7" || Aname=="C8"  || Aname=="N9" || Aname=="H1" ||
+    4091           0 :                 Aname=="H8" || Aname=="H21" || Aname=="H22" ) {
+    4092           0 :         atoi[residue_atom[i]]=BASE_G;
+    4093           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    4094             :       // DNA - G5
+    4095           0 :     } else if(Rname=="DG5") {
+    4096           0 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    4097           0 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  ||  Aname=="C1'" ||
+    4098           0 :           Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    4099           0 :           Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    4100           0 :           Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    4101             :           Aname=="H5T" ) {
+    4102           0 :         atoi[residue_atom[i]]=BB_DNA_5;
+    4103           0 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="N2" || Aname=="N3" ||
+    4104           0 :                 Aname=="C4" || Aname=="C5"  || Aname=="C6" || Aname=="O6" ||
+    4105           0 :                 Aname=="N7" || Aname=="C8"  || Aname=="N9" || Aname=="H1" ||
+    4106           0 :                 Aname=="H8" || Aname=="H21" || Aname=="H22" ) {
+    4107           0 :         atoi[residue_atom[i]]=BASE_G;
+    4108           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    4109             :       // DNA - T
+    4110           0 :     } else if(Rname=="DT") {
+    4111           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    4112           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    4113           0 :         atoi [residue_atom[i]]=BB_PO2;
+    4114           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    4115           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    4116           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    4117           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    4118           0 :                 Aname=="HO3'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" ||
+    4119           0 :                 Aname=="H2'2" || Aname=="H5T"  || Aname=="H3T" ) {
+    4120           0 :         atoi[residue_atom[i]]=BB_DNA;
+    4121           0 :       } else if(Aname=="N1"  || Aname=="C2"  || Aname=="O2"  || Aname=="N3"  ||
+    4122           0 :                 Aname=="C4"  || Aname=="O4"  || Aname=="C5"  || Aname=="C6"  ||
+    4123           0 :                 Aname=="C7"  || Aname=="H3"  || Aname=="H6"  || Aname=="H71" ||
+    4124           0 :                 Aname=="H72" || Aname=="H73" ) {
+    4125           0 :         atoi[residue_atom[i]]=BASE_T;
+    4126           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    4127             :       // DNA - T3
+    4128           0 :     } else if(Rname=="DT3") {
+    4129           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    4130           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    4131           0 :         atoi [residue_atom[i]]=BB_PO2;
+    4132           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    4133           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    4134           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    4135           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO3'" ||
+    4136           0 :                 Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    4137             :                 Aname=="H3T" ) {
+    4138           0 :         atoi[residue_atom[i]]=BB_DNA_3;
+    4139           0 :       } else if(Aname=="N1"  || Aname=="C2"  || Aname=="O2"  || Aname=="N3"  ||
+    4140           0 :                 Aname=="C4"  || Aname=="O4"  || Aname=="C5"  || Aname=="C6"  ||
+    4141           0 :                 Aname=="C7"  || Aname=="H3"  || Aname=="H6"  || Aname=="H71" ||
+    4142           0 :                 Aname=="H72" || Aname=="H73" ) {
+    4143           0 :         atoi[residue_atom[i]]=BASE_T;
+    4144           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    4145             :       // DNA - T5
+    4146           0 :     } else if(Rname=="DT5") {
+    4147           0 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    4148           0 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  ||  Aname=="C1'" ||
+    4149           0 :           Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    4150           0 :           Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    4151           0 :           Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    4152             :           Aname=="H5T" ) {
+    4153           0 :         atoi[residue_atom[i]]=BB_DNA_5;
+    4154           0 :       } else if(Aname=="N1"  || Aname=="C2"  || Aname=="O2"  || Aname=="N3"  ||
+    4155           0 :                 Aname=="C4"  || Aname=="O4"  || Aname=="C5"  || Aname=="C6"  ||
+    4156           0 :                 Aname=="C7"  || Aname=="H3"  || Aname=="H6"  || Aname=="H71" ||
+    4157           0 :                 Aname=="H72" || Aname=="H73" ) {
+    4158           0 :         atoi[residue_atom[i]]=BASE_T;
+    4159           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    4160             :       // DNA - A
+    4161           0 :     } else if(Rname=="DA") {
+    4162           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    4163           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    4164           0 :         atoi [residue_atom[i]]=BB_PO2;
+    4165           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    4166           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    4167           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    4168           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    4169           0 :                 Aname=="HO3'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" ||
+    4170           0 :                 Aname=="H2'2" || Aname=="H5T"  || Aname=="H3T" ) {
+    4171           0 :         atoi[residue_atom[i]]=BB_DNA;
+    4172           0 :       } else if(Aname=="N1"  || Aname=="C2" || Aname=="N3" || Aname=="C4" ||
+    4173           0 :                 Aname=="C5"  || Aname=="C6" || Aname=="N6" || Aname=="N7" ||
+    4174           0 :                 Aname=="C8"  || Aname=="N9" || Aname=="H2" || Aname=="H8" ||
+    4175           0 :                 Aname=="H61" || Aname=="H62" ) {
+    4176           0 :         atoi[residue_atom[i]]=BASE_A;
+    4177           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    4178             :       // DNA - A3
+    4179           0 :     } else if(Rname=="DA3") {
+    4180           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    4181           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    4182           0 :         atoi [residue_atom[i]]=BB_PO2;
+    4183           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    4184           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    4185           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    4186           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO3'" ||
+    4187           0 :                 Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    4188             :                 Aname=="H3T" ) {
+    4189           0 :         atoi[residue_atom[i]]=BB_DNA_3;
+    4190           0 :       } else if(Aname=="N1"  || Aname=="C2" || Aname=="N3" || Aname=="C4" ||
+    4191           0 :                 Aname=="C5"  || Aname=="C6" || Aname=="N6" || Aname=="N7" ||
+    4192           0 :                 Aname=="C8"  || Aname=="N9" || Aname=="H2" || Aname=="H8" ||
+    4193           0 :                 Aname=="H61" || Aname=="H62" ) {
+    4194           0 :         atoi[residue_atom[i]]=BASE_A;
+    4195           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    4196             :       // DNA - A5
+    4197           0 :     } else if(Rname=="DA5") {
+    4198           0 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    4199           0 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  ||  Aname=="C1'" ||
+    4200           0 :           Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    4201           0 :           Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    4202           0 :           Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    4203             :           Aname=="H5T" ) {
+    4204           0 :         atoi[residue_atom[i]]=BB_DNA_5;
+    4205           0 :       } else if(Aname=="N1"  || Aname=="C2" || Aname=="N3" || Aname=="C4" ||
+    4206           0 :                 Aname=="C5"  || Aname=="C6" || Aname=="N6" || Aname=="N7" ||
+    4207           0 :                 Aname=="C8"  || Aname=="N9" || Aname=="H2" || Aname=="H8" ||
+    4208           0 :                 Aname=="H61" || Aname=="H62" ) {
+    4209           0 :         atoi[residue_atom[i]]=BASE_A;
+    4210           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    4211             :       // DNA - C
+    4212           0 :     } else if(Rname=="DC") {
+    4213           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    4214           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    4215           0 :         atoi [residue_atom[i]]=BB_PO2;
+    4216           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    4217           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    4218           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    4219           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    4220           0 :                 Aname=="HO3'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" ||
+    4221           0 :                 Aname=="H2'2" || Aname=="H5T"  || Aname=="H3T" ) {
+    4222           0 :         atoi[residue_atom[i]]=BB_DNA;
+    4223           0 :       } else if(Aname=="N1" || Aname=="C2" || Aname=="O2"  || Aname=="N3" ||
+    4224           0 :                 Aname=="C4" || Aname=="N4" || Aname=="C5"  || Aname=="C6" ||
+    4225           0 :                 Aname=="H5" || Aname=="H6" || Aname=="H41" || Aname=="H42" ) {
+    4226           0 :         atoi[residue_atom[i]]=BASE_C;
+    4227           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    4228             :       // DNA - C3
+    4229           0 :     } else if(Rname=="DC3") {
+    4230           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    4231           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    4232           0 :         atoi [residue_atom[i]]=BB_PO2;
+    4233           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    4234           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    4235           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    4236           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO3'" ||
+    4237           0 :                 Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    4238             :                 Aname=="H3T" ) {
+    4239           0 :         atoi[residue_atom[i]]=BB_DNA_3;
+    4240           0 :       } else if(Aname=="N1" || Aname=="C2" || Aname=="O2"  || Aname=="N3" ||
+    4241           0 :                 Aname=="C4" || Aname=="N4" || Aname=="C5"  || Aname=="C6" ||
+    4242           0 :                 Aname=="H5" || Aname=="H6" || Aname=="H41" || Aname=="H42" ) {
+    4243           0 :         atoi[residue_atom[i]]=BASE_C;
+    4244           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    4245             :       // DNA - C5
+    4246           0 :     } else if(Rname=="DC5") {
+    4247           0 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    4248           0 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  ||  Aname=="C1'" ||
+    4249           0 :           Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    4250           0 :           Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    4251           0 :           Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    4252             :           Aname=="H5T" ) {
+    4253           0 :         atoi[residue_atom[i]]=BB_DNA_5;
+    4254           0 :       } else if(Aname=="N1" || Aname=="C2" || Aname=="O2"  || Aname=="N3" ||
+    4255           0 :                 Aname=="C4" || Aname=="N4" || Aname=="C5"  || Aname=="C6" ||
+    4256           0 :                 Aname=="H5" || Aname=="H6" || Aname=="H41" || Aname=="H42" ) {
+    4257           0 :         atoi[residue_atom[i]]=BASE_C;
+    4258           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    4259           0 :     } else error("Residue not known: "+Rname);
+    4260             :   }
+    4261           6 : }
+    4262             : 
+    4263           4 : void SAXS::getOnebeadparam_sansH(const PDB &pdb, const std::vector<AtomNumber> &atoms, std::vector<std::vector<long double> > &parameter_vac_H, std::vector<std::vector<long double> > &parameter_mix_H, std::vector<std::vector<long double> > &parameter_solv_H)
+    4264             : {
+    4265           4 :   parameter_solv_H[TRP].push_back(60737.60249988011);
+    4266           4 :   parameter_solv_H[TRP].push_back(-77.77344118516487);
+    4267           4 :   parameter_solv_H[TRP].push_back(-205962.80436572764);
+    4268           4 :   parameter_solv_H[TRP].push_back(-62014.18523271781);
+    4269           4 :   parameter_solv_H[TRP].push_back(680712.0512548896);
+    4270           4 :   parameter_solv_H[TRP].push_back(-681337.967312983);
+    4271           4 :   parameter_solv_H[TRP].push_back(211474.00338118695);
+    4272             : 
+    4273           4 :   parameter_solv_H[TYR].push_back(46250.803599880084);
+    4274           4 :   parameter_solv_H[TYR].push_back(-45.827646837514614);
+    4275           4 :   parameter_solv_H[TYR].push_back(-143872.94597686914);
+    4276           4 :   parameter_solv_H[TYR].push_back(-39049.51580628132);
+    4277           4 :   parameter_solv_H[TYR].push_back(441321.31246635393);
+    4278           4 :   parameter_solv_H[TYR].push_back(-434477.6826175059);
+    4279           4 :   parameter_solv_H[TYR].push_back(133179.21673104732);
+    4280             : 
+    4281           4 :   parameter_solv_H[PHE].push_back(42407.164900118914);
+    4282           4 :   parameter_solv_H[PHE].push_back(-159.20054549009086);
+    4283           4 :   parameter_solv_H[PHE].push_back(-123847.83591352346);
+    4284           4 :   parameter_solv_H[PHE].push_back(-41797.78884558073);
+    4285           4 :   parameter_solv_H[PHE].push_back(380283.87543872406);
+    4286           4 :   parameter_solv_H[PHE].push_back(-361432.81356389285);
+    4287           4 :   parameter_solv_H[PHE].push_back(107750.69385054041);
+    4288             : 
+    4289           4 :   parameter_solv_H[HIP].push_back(24473.473600119047);
+    4290           4 :   parameter_solv_H[HIP].push_back(-111.6412807124612);
+    4291           4 :   parameter_solv_H[HIP].push_back(-65826.17293437096);
+    4292           4 :   parameter_solv_H[HIP].push_back(-23305.902022201855);
+    4293           4 :   parameter_solv_H[HIP].push_back(194795.09953510275);
+    4294           4 :   parameter_solv_H[HIP].push_back(-180454.47859494278);
+    4295           4 :   parameter_solv_H[HIP].push_back(52699.36922660704);
+    4296             : 
+    4297           4 :   parameter_solv_H[ARG].push_back(34106.70239988039);
+    4298           4 :   parameter_solv_H[ARG].push_back(152.74468231268114);
+    4299           4 :   parameter_solv_H[ARG].push_back(-117086.46040369231);
+    4300           4 :   parameter_solv_H[ARG].push_back(-19664.37512726012);
+    4301           4 :   parameter_solv_H[ARG].push_back(364454.3721646173);
+    4302           4 :   parameter_solv_H[ARG].push_back(-382076.05102190404);
+    4303           4 :   parameter_solv_H[ARG].push_back(122775.83306003918);
+    4304             : 
+    4305           4 :   parameter_solv_H[LYS].push_back(32292.09000011877);
+    4306           4 :   parameter_solv_H[LYS].push_back(-111.97888350941923);
+    4307           4 :   parameter_solv_H[LYS].push_back(-91953.05212591762);
+    4308           4 :   parameter_solv_H[LYS].push_back(-30691.03615444628);
+    4309           4 :   parameter_solv_H[LYS].push_back(282092.82233263896);
+    4310           4 :   parameter_solv_H[LYS].push_back(-269503.6095978623);
+    4311           4 :   parameter_solv_H[LYS].push_back(80777.92760273012);
+    4312             : 
+    4313           4 :   parameter_solv_H[CYS].push_back(11352.902500119093);
+    4314           4 :   parameter_solv_H[CYS].push_back(-45.52255488723637);
+    4315           4 :   parameter_solv_H[CYS].push_back(-20925.086525675117);
+    4316           4 :   parameter_solv_H[CYS].push_back(-5662.681335644281);
+    4317           4 :   parameter_solv_H[CYS].push_back(38559.09602816144);
+    4318           4 :   parameter_solv_H[CYS].push_back(-27885.22747486708);
+    4319           4 :   parameter_solv_H[CYS].push_back(6280.148346561226);
+    4320             : 
+    4321           4 :   parameter_solv_H[ASP].push_back(13511.73760011933);
+    4322           4 :   parameter_solv_H[ASP].push_back(-59.92934247210642);
+    4323           4 :   parameter_solv_H[ASP].push_back(-25849.867077822244);
+    4324           4 :   parameter_solv_H[ASP].push_back(-7541.679510407563);
+    4325           4 :   parameter_solv_H[ASP].push_back(50760.93853987092);
+    4326           4 :   parameter_solv_H[ASP].push_back(-37677.89102528413);
+    4327           4 :   parameter_solv_H[ASP].push_back(8745.710458140105);
+    4328             : 
+    4329           4 :   parameter_solv_H[GLU].push_back(20443.280400119456);
+    4330           4 :   parameter_solv_H[GLU].push_back(-113.77513581661388);
+    4331           4 :   parameter_solv_H[GLU].push_back(-45587.79863958479);
+    4332           4 :   parameter_solv_H[GLU].push_back(-16187.534798976243);
+    4333           4 :   parameter_solv_H[GLU].push_back(112609.61802147207);
+    4334           4 :   parameter_solv_H[GLU].push_back(-93362.01894077536);
+    4335           4 :   parameter_solv_H[GLU].push_back(24519.546829431332);
+    4336             : 
+    4337           4 :   parameter_solv_H[ILE].push_back(27858.948100119596);
+    4338           4 :   parameter_solv_H[ILE].push_back(-159.27394962770595);
+    4339           4 :   parameter_solv_H[ILE].push_back(-61571.43025249802);
+    4340           4 :   parameter_solv_H[ILE].push_back(-21324.89659912433);
+    4341           4 :   parameter_solv_H[ILE].push_back(144070.7880009225);
+    4342           4 :   parameter_solv_H[ILE].push_back(-115021.84534734003);
+    4343           4 :   parameter_solv_H[ILE].push_back(28939.093300284097);
+    4344             : 
+    4345           4 :   parameter_solv_H[LEU].push_back(27858.948100119596);
+    4346           4 :   parameter_solv_H[LEU].push_back(-165.61872365361);
+    4347           4 :   parameter_solv_H[LEU].push_back(-62564.5706162518);
+    4348           4 :   parameter_solv_H[LEU].push_back(-22465.325666767214);
+    4349           4 :   parameter_solv_H[LEU].push_back(151616.7844050042);
+    4350           4 :   parameter_solv_H[LEU].push_back(-122905.60389771541);
+    4351           4 :   parameter_solv_H[LEU].push_back(31436.66201442061);
+    4352             : 
+    4353           4 :   parameter_solv_H[MET].push_back(25609.60090011981);
+    4354           4 :   parameter_solv_H[MET].push_back(-135.38816369794569);
+    4355           4 :   parameter_solv_H[MET].push_back(-67771.01548433342);
+    4356           4 :   parameter_solv_H[MET].push_back(-25228.91756660071);
+    4357           4 :   parameter_solv_H[MET].push_back(199649.92084565928);
+    4358           4 :   parameter_solv_H[MET].push_back(-182251.9246506795);
+    4359           4 :   parameter_solv_H[MET].push_back(52502.876819125115);
+    4360             : 
+    4361           4 :   parameter_solv_H[ASN].push_back(14376.010000119095);
+    4362           4 :   parameter_solv_H[ASN].push_back(-67.65587848183215);
+    4363           4 :   parameter_solv_H[ASN].push_back(-28302.877059425664);
+    4364           4 :   parameter_solv_H[ASN].push_back(-8577.444107282141);
+    4365           4 :   parameter_solv_H[ASN].push_back(57532.88704197217);
+    4366           4 :   parameter_solv_H[ASN].push_back(-43261.79974462857);
+    4367           4 :   parameter_solv_H[ASN].push_back(10186.450874679671);
+    4368             : 
+    4369           4 :   parameter_solv_H[PRO].push_back(16866.21690011944);
+    4370           4 :   parameter_solv_H[PRO].push_back(-70.84312112734995);
+    4371           4 :   parameter_solv_H[PRO].push_back(-31465.8423531932);
+    4372           4 :   parameter_solv_H[PRO].push_back(-8653.362744540535);
+    4373           4 :   parameter_solv_H[PRO].push_back(58032.27079924916);
+    4374           4 :   parameter_solv_H[PRO].push_back(-41521.001733021694);
+    4375           4 :   parameter_solv_H[PRO].push_back(9184.527523759205);
+    4376             : 
+    4377           4 :   parameter_solv_H[GLN].push_back(21503.289600119);
+    4378           4 :   parameter_solv_H[GLN].push_back(-121.3012777474678);
+    4379           4 :   parameter_solv_H[GLN].push_back(-50468.58503443957);
+    4380           4 :   parameter_solv_H[GLN].push_back(-18462.47495329696);
+    4381           4 :   parameter_solv_H[GLN].push_back(132718.42007501892);
+    4382           4 :   parameter_solv_H[GLN].push_back(-113787.20224345029);
+    4383           4 :   parameter_solv_H[GLN].push_back(30920.340813688686);
+    4384             : 
+    4385           4 :   parameter_solv_H[SER].push_back(9181.47240011935);
+    4386           4 :   parameter_solv_H[SER].push_back(-28.775273124392083);
+    4387           4 :   parameter_solv_H[SER].push_back(-15205.54229808512);
+    4388           4 :   parameter_solv_H[SER].push_back(-3377.785599913673);
+    4389           4 :   parameter_solv_H[SER].push_back(23345.562090489493);
+    4390           4 :   parameter_solv_H[SER].push_back(-15312.699787471944);
+    4391           4 :   parameter_solv_H[SER].push_back(3013.844610647712);
+    4392             : 
+    4393           4 :   parameter_solv_H[THR].push_back(15020.953600119403);
+    4394           4 :   parameter_solv_H[THR].push_back(-61.909951810375105);
+    4395           4 :   parameter_solv_H[THR].push_back(-27814.538986050964);
+    4396           4 :   parameter_solv_H[THR].push_back(-7532.222992514079);
+    4397           4 :   parameter_solv_H[THR].push_back(50586.29804970814);
+    4398           4 :   parameter_solv_H[THR].push_back(-35943.85986777198);
+    4399           4 :   parameter_solv_H[THR].push_back(7880.091610023207);
+    4400             : 
+    4401           4 :   parameter_solv_H[VAL].push_back(19647.628900119355);
+    4402           4 :   parameter_solv_H[VAL].push_back(-89.04968136833762);
+    4403           4 :   parameter_solv_H[VAL].push_back(-38050.10118919102);
+    4404           4 :   parameter_solv_H[VAL].push_back(-10921.421066774372);
+    4405           4 :   parameter_solv_H[VAL].push_back(72774.31277743122);
+    4406           4 :   parameter_solv_H[VAL].push_back(-52689.05168504517);
+    4407           4 :   parameter_solv_H[VAL].push_back(11806.48989635518);
+    4408             : 
+    4409           4 :   parameter_solv_H[ALA].push_back(7515.156100119273);
+    4410           4 :   parameter_solv_H[ALA].push_back(-20.226317591188526);
+    4411           4 :   parameter_solv_H[ALA].push_back(-11761.841775007797);
+    4412           4 :   parameter_solv_H[ALA].push_back(-2341.4903622033885);
+    4413           4 :   parameter_solv_H[ALA].push_back(16545.381259883452);
+    4414           4 :   parameter_solv_H[ALA].push_back(-10397.171546969075);
+    4415           4 :   parameter_solv_H[ALA].push_back(1921.5253045340198);
+    4416             : 
+    4417           4 :   parameter_solv_H[GLY].push_back(3594.002500119159);
+    4418           4 :   parameter_solv_H[GLY].push_back(-6.910832388009796);
+    4419           4 :   parameter_solv_H[GLY].push_back(-4937.3542895091905);
+    4420           4 :   parameter_solv_H[GLY].push_back(-785.4545979203357);
+    4421           4 :   parameter_solv_H[GLY].push_back(5852.853693316741);
+    4422           4 :   parameter_solv_H[GLY].push_back(-3391.2920205126734);
+    4423           4 :   parameter_solv_H[GLY].push_back(552.3278183161507);
+    4424             : 
+    4425           4 :   parameter_solv_H[HIS].push_back(22888.664100119073);
+    4426           4 :   parameter_solv_H[HIS].push_back(-133.86281863999585);
+    4427           4 :   parameter_solv_H[HIS].push_back(-57533.51412287858);
+    4428           4 :   parameter_solv_H[HIS].push_back(-21767.300111408193);
+    4429           4 :   parameter_solv_H[HIS].push_back(161255.15347073504);
+    4430           4 :   parameter_solv_H[HIS].push_back(-142176.65100718598);
+    4431           4 :   parameter_solv_H[HIS].push_back(39642.61507384587);
+    4432             : 
+    4433           4 :   parameter_mix_H[TRP].push_back(2974.6515001192306);
+    4434           4 :   parameter_mix_H[TRP].push_back(-18.361939022074825);
+    4435           4 :   parameter_mix_H[TRP].push_back(-7284.637435770752);
+    4436           4 :   parameter_mix_H[TRP].push_back(-2945.7969900381895);
+    4437           4 :   parameter_mix_H[TRP].push_back(21235.01878657283);
+    4438           4 :   parameter_mix_H[TRP].push_back(-18909.7406035548);
+    4439           4 :   parameter_mix_H[TRP].push_back(5324.324204245179);
+    4440             : 
+    4441           4 :   parameter_mix_H[TYR].push_back(2029.7362801192114);
+    4442           4 :   parameter_mix_H[TYR].push_back(-6.983186065527884);
+    4443           4 :   parameter_mix_H[TYR].push_back(-5041.996113037476);
+    4444           4 :   parameter_mix_H[TYR].push_back(-1744.5213085724158);
+    4445           4 :   parameter_mix_H[TYR].push_back(15329.420227814338);
+    4446           4 :   parameter_mix_H[TYR].push_back(-14648.322529889958);
+    4447           4 :   parameter_mix_H[TYR].push_back(4405.608657083287);
+    4448             : 
+    4449           4 :   parameter_mix_H[PHE].push_back(1704.6885401192117);
+    4450           4 :   parameter_mix_H[PHE].push_back(-10.077274979133408);
+    4451           4 :   parameter_mix_H[PHE].push_back(-3769.440088334303);
+    4452           4 :   parameter_mix_H[PHE].push_back(-1574.6255694551546);
+    4453           4 :   parameter_mix_H[PHE].push_back(10996.32497868798);
+    4454           4 :   parameter_mix_H[PHE].push_back(-9840.68281283696);
+    4455           4 :   parameter_mix_H[PHE].push_back(2792.098605716682);
+    4456             : 
+    4457           4 :   parameter_mix_H[HIP].push_back(1376.0462401192394);
+    4458           4 :   parameter_mix_H[HIP].push_back(-8.576320475413144);
+    4459           4 :   parameter_mix_H[HIP].push_back(-2796.8327726392167);
+    4460           4 :   parameter_mix_H[HIP].push_back(-1165.0473128576);
+    4461           4 :   parameter_mix_H[HIP].push_back(7495.063650365717);
+    4462           4 :   parameter_mix_H[HIP].push_back(-6331.20422098132);
+    4463           4 :   parameter_mix_H[HIP].push_back(1692.637366093312);
+    4464             : 
+    4465           4 :   parameter_mix_H[ARG].push_back(1280.940480119178);
+    4466           4 :   parameter_mix_H[ARG].push_back(-7.411214928783748);
+    4467           4 :   parameter_mix_H[ARG].push_back(-3747.6200569785033);
+    4468           4 :   parameter_mix_H[ARG].push_back(-1766.5282176004569);
+    4469           4 :   parameter_mix_H[ARG].push_back(14307.817638456267);
+    4470           4 :   parameter_mix_H[ARG].push_back(-14297.104122885643);
+    4471           4 :   parameter_mix_H[ARG].push_back(4450.526244207772);
+    4472             : 
+    4473           4 :   parameter_mix_H[LYS].push_back(570.7272001192143);
+    4474           4 :   parameter_mix_H[LYS].push_back(-5.371742288956095);
+    4475           4 :   parameter_mix_H[LYS].push_back(-1255.9868267793006);
+    4476           4 :   parameter_mix_H[LYS].push_back(-748.3071074443138);
+    4477           4 :   parameter_mix_H[LYS].push_back(4534.824932304509);
+    4478           4 :   parameter_mix_H[LYS].push_back(-4125.307867230812);
+    4479           4 :   parameter_mix_H[LYS].push_back(1178.781491068295);
+    4480             : 
+    4481           4 :   parameter_mix_H[CYS].push_back(410.21750011921864);
+    4482           4 :   parameter_mix_H[CYS].push_back(-0.7655651758449595);
+    4483           4 :   parameter_mix_H[CYS].push_back(-523.8897033718782);
+    4484           4 :   parameter_mix_H[CYS].push_back(-89.88478273744425);
+    4485           4 :   parameter_mix_H[CYS].push_back(655.3313542467919);
+    4486           4 :   parameter_mix_H[CYS].push_back(-407.87897719750896);
+    4487           4 :   parameter_mix_H[CYS].push_back(76.50541508448237);
+    4488             : 
+    4489           4 :   parameter_mix_H[ASP].push_back(893.6531201192147);
+    4490           4 :   parameter_mix_H[ASP].push_back(-3.0756255172248874);
+    4491           4 :   parameter_mix_H[ASP].push_back(-1453.1760425275006);
+    4492           4 :   parameter_mix_H[ASP].push_back(-365.0424824614137);
+    4493           4 :   parameter_mix_H[ASP].push_back(2443.570600976796);
+    4494           4 :   parameter_mix_H[ASP].push_back(-1679.8996339740277);
+    4495           4 :   parameter_mix_H[ASP].push_back(352.33054461512455);
+    4496             : 
+    4497           4 :   parameter_mix_H[GLU].push_back(1075.4955601191884);
+    4498           4 :   parameter_mix_H[GLU].push_back(-6.917429973203965);
+    4499           4 :   parameter_mix_H[GLU].push_back(-2262.861870389347);
+    4500           4 :   parameter_mix_H[GLU].push_back(-909.8078514527992);
+    4501           4 :   parameter_mix_H[GLU].push_back(5841.923857549836);
+    4502           4 :   parameter_mix_H[GLU].push_back(-4784.620969556751);
+    4503           4 :   parameter_mix_H[GLU].push_back(1230.873134652953);
+    4504             : 
+    4505           4 :   parameter_mix_H[ILE].push_back(466.0127201192081);
+    4506           4 :   parameter_mix_H[ILE].push_back(-0.9323443258150218);
+    4507           4 :   parameter_mix_H[ILE].push_back(-576.7178005955719);
+    4508           4 :   parameter_mix_H[ILE].push_back(-103.03003361062478);
+    4509           4 :   parameter_mix_H[ILE].push_back(706.4269951176641);
+    4510           4 :   parameter_mix_H[ILE].push_back(-420.4412859632717);
+    4511           4 :   parameter_mix_H[ILE].push_back(71.53175726608731);
+    4512             : 
+    4513           4 :   parameter_mix_H[LEU].push_back(466.0127201192081);
+    4514           4 :   parameter_mix_H[LEU].push_back(-1.9793605752606065);
+    4515           4 :   parameter_mix_H[LEU].push_back(-718.3988478701591);
+    4516           4 :   parameter_mix_H[LEU].push_back(-227.36409339012113);
+    4517           4 :   parameter_mix_H[LEU].push_back(1389.2058254917304);
+    4518           4 :   parameter_mix_H[LEU].push_back(-990.0033118748643);
+    4519           4 :   parameter_mix_H[LEU].push_back(213.15736815883042);
+    4520             : 
+    4521           4 :   parameter_mix_H[MET].push_back(562.9855401192196);
+    4522           4 :   parameter_mix_H[MET].push_back(-3.7994094933771643);
+    4523           4 :   parameter_mix_H[MET].push_back(-1139.6331862451661);
+    4524           4 :   parameter_mix_H[MET].push_back(-516.6313269725724);
+    4525           4 :   parameter_mix_H[MET].push_back(3268.957245190869);
+    4526           4 :   parameter_mix_H[MET].push_back(-2809.178864807947);
+    4527           4 :   parameter_mix_H[MET].push_back(761.4832732100416);
+    4528             : 
+    4529           4 :   parameter_mix_H[ASN].push_back(828.7488001191887);
+    4530           4 :   parameter_mix_H[ASN].push_back(-2.1275493073799625);
+    4531           4 :   parameter_mix_H[ASN].push_back(-1222.248291388804);
+    4532           4 :   parameter_mix_H[ASN].push_back(-238.94210659613537);
+    4533           4 :   parameter_mix_H[ASN].push_back(1660.8322402171973);
+    4534           4 :   parameter_mix_H[ASN].push_back(-1008.7934996077323);
+    4535           4 :   parameter_mix_H[ASN].push_back(173.6082238625797);
+    4536             : 
+    4537           4 :   parameter_mix_H[PRO].push_back(578.4409801192146);
+    4538           4 :   parameter_mix_H[PRO].push_back(-0.5379505780909722);
+    4539           4 :   parameter_mix_H[PRO].push_back(-648.146493857212);
+    4540           4 :   parameter_mix_H[PRO].push_back(-56.67223895342921);
+    4541           4 :   parameter_mix_H[PRO].push_back(509.88860586987437);
+    4542           4 :   parameter_mix_H[PRO].push_back(-214.57871784725265);
+    4543           4 :   parameter_mix_H[PRO].push_back(11.99659463759968);
+    4544             : 
+    4545           4 :   parameter_mix_H[GLN].push_back(989.2334401191976);
+    4546           4 :   parameter_mix_H[GLN].push_back(-6.307760694331967);
+    4547           4 :   parameter_mix_H[GLN].push_back(-1971.7067150503622);
+    4548           4 :   parameter_mix_H[GLN].push_back(-791.333088386235);
+    4549           4 :   parameter_mix_H[GLN].push_back(4900.009768434847);
+    4550           4 :   parameter_mix_H[GLN].push_back(-3909.7740976374153);
+    4551           4 :   parameter_mix_H[GLN].push_back(975.4952613244343);
+    4552             : 
+    4553           4 :   parameter_mix_H[SER].push_back(426.39900011920196);
+    4554           4 :   parameter_mix_H[SER].push_back(-0.42304498358319664);
+    4555           4 :   parameter_mix_H[SER].push_back(-484.2066027682147);
+    4556           4 :   parameter_mix_H[SER].push_back(-45.38968988754228);
+    4557           4 :   parameter_mix_H[SER].push_back(401.3420977115044);
+    4558           4 :   parameter_mix_H[SER].push_back(-178.0861461692512);
+    4559           4 :   parameter_mix_H[SER].push_back(13.540349238730284);
+    4560             : 
+    4561           4 :   parameter_mix_H[THR].push_back(525.0470401191992);
+    4562           4 :   parameter_mix_H[THR].push_back(-0.7419102811534484);
+    4563           4 :   parameter_mix_H[THR].push_back(-652.7134808154495);
+    4564           4 :   parameter_mix_H[THR].push_back(-80.39481224407903);
+    4565           4 :   parameter_mix_H[THR].push_back(641.5487902728123);
+    4566           4 :   parameter_mix_H[THR].push_back(-320.4227667104819);
+    4567           4 :   parameter_mix_H[THR].push_back(36.03558531183942);
+    4568             : 
+    4569           4 :   parameter_mix_H[VAL].push_back(414.6228601192123);
+    4570           4 :   parameter_mix_H[VAL].push_back(-0.35889335250521337);
+    4571           4 :   parameter_mix_H[VAL].push_back(-453.11631644097474);
+    4572           4 :   parameter_mix_H[VAL].push_back(-36.402101097644284);
+    4573           4 :   parameter_mix_H[VAL].push_back(336.24049431626804);
+    4574           4 :   parameter_mix_H[VAL].push_back(-127.42235327515239);
+    4575           4 :   parameter_mix_H[VAL].push_back(0.8013280923923705);
+    4576             : 
+    4577           4 :   parameter_mix_H[ALA].push_back(285.21010011920816);
+    4578           4 :   parameter_mix_H[ALA].push_back(-0.1573012439142169);
+    4579           4 :   parameter_mix_H[ALA].push_back(-282.8945838800694);
+    4580           4 :   parameter_mix_H[ALA].push_back(-16.32030056827785);
+    4581           4 :   parameter_mix_H[ALA].push_back(178.065895049598);
+    4582           4 :   parameter_mix_H[ALA].push_back(-60.27423229179658);
+    4583           4 :   parameter_mix_H[ALA].push_back(-1.4695219304131588);
+    4584             : 
+    4585           4 :   parameter_mix_H[GLY].push_back(207.18720011920414);
+    4586           4 :   parameter_mix_H[GLY].push_back(-0.1036587134183235);
+    4587           4 :   parameter_mix_H[GLY].push_back(-185.70794948240638);
+    4588           4 :   parameter_mix_H[GLY].push_back(-11.008101039836257);
+    4589           4 :   parameter_mix_H[GLY].push_back(115.30600405624061);
+    4590           4 :   parameter_mix_H[GLY].push_back(-42.46629718037158);
+    4591           4 :   parameter_mix_H[GLY].push_back(0.9238928987070913);
+    4592             : 
+    4593           4 :   parameter_mix_H[HIS].push_back(1443.9117601192354);
+    4594           4 :   parameter_mix_H[HIS].push_back(-7.478618745973115);
+    4595           4 :   parameter_mix_H[HIS].push_back(-2715.0835155803215);
+    4596           4 :   parameter_mix_H[HIS].push_back(-918.5243015382779);
+    4597           4 :   parameter_mix_H[HIS].push_back(5821.6258431396);
+    4598           4 :   parameter_mix_H[HIS].push_back(-4415.32722209556);
+    4599           4 :   parameter_mix_H[HIS].push_back(1044.7044029209756);
+    4600           4 :   parameter_vac_H[TRP].push_back(36.42122511920832);
+    4601           4 :   parameter_vac_H[TRP].push_back(-0.36925500341767903);
+    4602           4 :   parameter_vac_H[TRP].push_back(-51.34228792835503);
+    4603           4 :   parameter_vac_H[TRP].push_back(-34.10021080004831);
+    4604           4 :   parameter_vac_H[TRP].push_back(132.647034983933);
+    4605           4 :   parameter_vac_H[TRP].push_back(-82.89152328934257);
+    4606           4 :   parameter_vac_H[TRP].push_back(13.029994092013231);
+    4607             : 
+    4608           4 :   parameter_vac_H[TYR].push_back(22.268961119209557);
+    4609           4 :   parameter_vac_H[TYR].push_back(-0.1995573892347673);
+    4610           4 :   parameter_vac_H[TYR].push_back(-36.54202179838511);
+    4611           4 :   parameter_vac_H[TYR].push_back(-23.820801043096694);
+    4612           4 :   parameter_vac_H[TYR].push_back(127.46799692275353);
+    4613           4 :   parameter_vac_H[TYR].push_back(-107.63783234245744);
+    4614           4 :   parameter_vac_H[TYR].push_back(28.180858902960775);
+    4615             : 
+    4616           4 :   parameter_vac_H[PHE].push_back(17.131321119209627);
+    4617           4 :   parameter_vac_H[PHE].push_back(-0.15766725674246446);
+    4618           4 :   parameter_vac_H[PHE].push_back(-19.19964432024534);
+    4619           4 :   parameter_vac_H[PHE].push_back(-12.34326882843138);
+    4620           4 :   parameter_vac_H[PHE].push_back(38.17216645824474);
+    4621           4 :   parameter_vac_H[PHE].push_back(-11.245288857407298);
+    4622           4 :   parameter_vac_H[PHE].push_back(-3.8114731300899343);
+    4623             : 
+    4624           4 :   parameter_vac_H[HIP].push_back(19.34240411920875);
+    4625           4 :   parameter_vac_H[HIP].push_back(-0.13533410292592593);
+    4626           4 :   parameter_vac_H[HIP].push_back(-25.924121027387276);
+    4627           4 :   parameter_vac_H[HIP].push_back(-12.36586927492752);
+    4628           4 :   parameter_vac_H[HIP].push_back(56.75268702111191);
+    4629           4 :   parameter_vac_H[HIP].push_back(-31.126240293638094);
+    4630           4 :   parameter_vac_H[HIP].push_back(2.749811579250848);
+    4631             : 
+    4632           4 :   parameter_vac_H[ARG].push_back(12.027024119209557);
+    4633           4 :   parameter_vac_H[ARG].push_back(-0.41927538341868287);
+    4634           4 :   parameter_vac_H[ARG].push_back(-22.137566939867042);
+    4635           4 :   parameter_vac_H[ARG].push_back(-43.22615008762667);
+    4636           4 :   parameter_vac_H[ARG].push_back(165.77466655520323);
+    4637           4 :   parameter_vac_H[ARG].push_back(-140.68664871425898);
+    4638           4 :   parameter_vac_H[ARG].push_back(36.67401195170306);
+    4639             : 
+    4640           4 :   parameter_vac_H[LYS].push_back(2.5217441192093717);
+    4641           4 :   parameter_vac_H[LYS].push_back(-0.0032825476242835413);
+    4642           4 :   parameter_vac_H[LYS].push_back(14.019071697737793);
+    4643           4 :   parameter_vac_H[LYS].push_back(7.8634074595069245);
+    4644           4 :   parameter_vac_H[LYS].push_back(-82.44639716451474);
+    4645           4 :   parameter_vac_H[LYS].push_back(94.32937851921197);
+    4646           4 :   parameter_vac_H[LYS].push_back(-32.324473823417);
+    4647             : 
+    4648           4 :   parameter_vac_H[CYS].push_back(3.705624880856525);
+    4649           4 :   parameter_vac_H[CYS].push_back(0.005214780840206113);
+    4650           4 :   parameter_vac_H[CYS].push_back(1.25680902661715);
+    4651           4 :   parameter_vac_H[CYS].push_back(0.5779209425501814);
+    4652           4 :   parameter_vac_H[CYS].push_back(-3.716408071089366);
+    4653           4 :   parameter_vac_H[CYS].push_back(2.3947518943233117);
+    4654           4 :   parameter_vac_H[CYS].push_back(-0.40204949737133333);
+    4655             : 
+    4656           4 :   parameter_vac_H[ASP].push_back(14.776336119209605);
+    4657           4 :   parameter_vac_H[ASP].push_back(-0.037351220316916435);
+    4658           4 :   parameter_vac_H[ASP].push_back(-18.556358387626286);
+    4659           4 :   parameter_vac_H[ASP].push_back(-4.1737354794552886);
+    4660           4 :   parameter_vac_H[ASP].push_back(28.424721213037405);
+    4661           4 :   parameter_vac_H[ASP].push_back(-17.51389895324883);
+    4662           4 :   parameter_vac_H[ASP].push_back(2.9729111724708597);
+    4663             : 
+    4664           4 :   parameter_vac_H[GLU].push_back(14.145121119208973);
+    4665           4 :   parameter_vac_H[GLU].push_back(-0.11468766098213011);
+    4666           4 :   parameter_vac_H[GLU].push_back(-26.272637652294613);
+    4667           4 :   parameter_vac_H[GLU].push_back(-13.769758826440151);
+    4668           4 :   parameter_vac_H[GLU].push_back(80.4575683578491);
+    4669           4 :   parameter_vac_H[GLU].push_back(-64.19346347075);
+    4670           4 :   parameter_vac_H[GLU].push_back(15.545440117656236);
+    4671             : 
+    4672           4 :   parameter_vac_H[ILE].push_back(1.9488158808808775);
+    4673           4 :   parameter_vac_H[ILE].push_back(0.05873132133874459);
+    4674           4 :   parameter_vac_H[ILE].push_back(12.032778845884135);
+    4675           4 :   parameter_vac_H[ILE].push_back(7.148416980612881);
+    4676           4 :   parameter_vac_H[ILE].push_back(-41.87377843832961);
+    4677           4 :   parameter_vac_H[ILE].push_back(33.96120749582283);
+    4678           4 :   parameter_vac_H[ILE].push_back(-8.362535852631256);
+    4679             : 
+    4680           4 :   parameter_vac_H[LEU].push_back(1.9488158808977816);
+    4681           4 :   parameter_vac_H[LEU].push_back(0.0778305500414777);
+    4682           4 :   parameter_vac_H[LEU].push_back(12.333370614594);
+    4683           4 :   parameter_vac_H[LEU].push_back(9.449427967560764);
+    4684           4 :   parameter_vac_H[LEU].push_back(-52.65457680603262);
+    4685           4 :   parameter_vac_H[LEU].push_back(44.681877289399615);
+    4686           4 :   parameter_vac_H[LEU].push_back(-11.460498338671227);
+    4687             : 
+    4688           4 :   parameter_vac_H[MET].push_back(3.0940808808117652);
+    4689           4 :   parameter_vac_H[MET].push_back(0.04903755678213222);
+    4690           4 :   parameter_vac_H[MET].push_back(8.981927022922049);
+    4691           4 :   parameter_vac_H[MET].push_back(8.654862771879014);
+    4692           4 :   parameter_vac_H[MET].push_back(-57.09889409156816);
+    4693           4 :   parameter_vac_H[MET].push_back(58.87704775164829);
+    4694           4 :   parameter_vac_H[MET].push_back(-18.60431990258862);
+    4695             : 
+    4696           4 :   parameter_vac_H[ASN].push_back(11.943936119209074);
+    4697           4 :   parameter_vac_H[ASN].push_back(-0.0005000836239497835);
+    4698           4 :   parameter_vac_H[ASN].push_back(-9.581236453763157);
+    4699           4 :   parameter_vac_H[ASN].push_back(0.16244025786232308);
+    4700           4 :   parameter_vac_H[ASN].push_back(2.9276580099749574);
+    4701           4 :   parameter_vac_H[ASN].push_back(2.133535783835143);
+    4702           4 :   parameter_vac_H[ASN].push_back(-1.5709968820975018);
+    4703             : 
+    4704           4 :   parameter_vac_H[PRO].push_back(4.9595288808229245);
+    4705           4 :   parameter_vac_H[PRO].push_back(0.017853932680793515);
+    4706           4 :   parameter_vac_H[PRO].push_back(4.5421559293101605);
+    4707           4 :   parameter_vac_H[PRO].push_back(2.008455612787203);
+    4708           4 :   parameter_vac_H[PRO].push_back(-12.444117841318494);
+    4709           4 :   parameter_vac_H[PRO].push_back(8.511723688836447);
+    4710           4 :   parameter_vac_H[PRO].push_back(-1.6337543903496765);
+    4711             : 
+    4712           4 :   parameter_vac_H[GLN].push_back(11.377129119208574);
+    4713           4 :   parameter_vac_H[GLN].push_back(-0.0674805307761209);
+    4714           4 :   parameter_vac_H[GLN].push_back(-16.56692720411458);
+    4715           4 :   parameter_vac_H[GLN].push_back(-6.477707440126834);
+    4716           4 :   parameter_vac_H[GLN].push_back(34.78232259512621);
+    4717           4 :   parameter_vac_H[GLN].push_back(-19.450886909938312);
+    4718           4 :   parameter_vac_H[GLN].push_back(1.944286925108988);
+    4719             : 
+    4720           4 :   parameter_vac_H[SER].push_back(4.95062488096605);
+    4721           4 :   parameter_vac_H[SER].push_back(0.004676435440506079);
+    4722           4 :   parameter_vac_H[SER].push_back(-0.1896653085608564);
+    4723           4 :   parameter_vac_H[SER].push_back(0.5142284931977218);
+    4724           4 :   parameter_vac_H[SER].push_back(-2.8946087252759893);
+    4725           4 :   parameter_vac_H[SER].push_back(2.1031239401634836);
+    4726           4 :   parameter_vac_H[SER].push_back(-0.38226443516361713);
+    4727             : 
+    4728           4 :   parameter_vac_H[THR].push_back(4.588163880808971);
+    4729           4 :   parameter_vac_H[THR].push_back(0.018587905993982613);
+    4730           4 :   parameter_vac_H[THR].push_back(3.5289861308270214);
+    4731           4 :   parameter_vac_H[THR].push_back(2.0780583604591567);
+    4732           4 :   parameter_vac_H[THR].push_back(-12.3802007068414);
+    4733           4 :   parameter_vac_H[THR].push_back(8.720986674116094);
+    4734           4 :   parameter_vac_H[THR].push_back(-1.683256475122275);
+    4735             : 
+    4736           4 :   parameter_vac_H[VAL].push_back(2.187440880853519);
+    4737           4 :   parameter_vac_H[VAL].push_back(0.028351524826584255);
+    4738           4 :   parameter_vac_H[VAL].push_back(8.36584512491955);
+    4739           4 :   parameter_vac_H[VAL].push_back(3.1686206615123926);
+    4740           4 :   parameter_vac_H[VAL].push_back(-19.81959917770108);
+    4741           4 :   parameter_vac_H[VAL].push_back(13.293003038570571);
+    4742           4 :   parameter_vac_H[VAL].push_back(-2.4595257726774125);
+    4743             : 
+    4744           4 :   parameter_vac_H[ALA].push_back(2.7060248808167935);
+    4745           4 :   parameter_vac_H[ALA].push_back(0.004618897267213416);
+    4746           4 :   parameter_vac_H[ALA].push_back(2.4990261487383947);
+    4747           4 :   parameter_vac_H[ALA].push_back(0.49579332664340864);
+    4748           4 :   parameter_vac_H[ALA].push_back(-3.850400071630347);
+    4749           4 :   parameter_vac_H[ALA].push_back(1.9501161562030942);
+    4750           4 :   parameter_vac_H[ALA].push_back(-0.18332582719788362);
+    4751             : 
+    4752           4 :   parameter_vac_H[GLY].push_back(2.985983880876256);
+    4753           4 :   parameter_vac_H[GLY].push_back(0.0005033131808079042);
+    4754           4 :   parameter_vac_H[GLY].push_back(-0.42250170279962684);
+    4755           4 :   parameter_vac_H[GLY].push_back(0.05620517453257455);
+    4756           4 :   parameter_vac_H[GLY].push_back(-0.16801962822020733);
+    4757           4 :   parameter_vac_H[GLY].push_back(0.23635459648780555);
+    4758           4 :   parameter_vac_H[GLY].push_back(-0.06585244715658795);
+    4759             : 
+    4760           4 :   parameter_vac_H[HIS].push_back(22.77198411920933);
+    4761           4 :   parameter_vac_H[HIS].push_back(-0.06607491006655417);
+    4762           4 :   parameter_vac_H[HIS].push_back(-27.277710268717247);
+    4763           4 :   parameter_vac_H[HIS].push_back(-5.674444390934355);
+    4764           4 :   parameter_vac_H[HIS].push_back(33.4059567406171);
+    4765           4 :   parameter_vac_H[HIS].push_back(-11.60826210271092);
+    4766           4 :   parameter_vac_H[HIS].push_back(-1.7359607560773076);
+    4767             : 
+    4768             :   // NUCLEIC ACIDS
+    4769             : 
+    4770             :   // BB_PO2 H and D parameters are identical as there is no H or D in the bead.
+    4771           4 :   parameter_solv_H[BB_PO2].push_back(575.5201001192197);
+    4772           4 :   parameter_solv_H[BB_PO2].push_back(-0.6126595489733864);
+    4773           4 :   parameter_solv_H[BB_PO2].push_back(-623.3371092254899);
+    4774           4 :   parameter_solv_H[BB_PO2].push_back(-68.05795957022144);
+    4775           4 :   parameter_solv_H[BB_PO2].push_back(561.8052621243661);
+    4776           4 :   parameter_solv_H[BB_PO2].push_back(-283.39573309540276);
+    4777           4 :   parameter_solv_H[BB_PO2].push_back(35.550016980100295);
+    4778             : 
+    4779           4 :   parameter_solv_H[BB_DNA].push_back(21211.009600118316);
+    4780           4 :   parameter_solv_H[BB_DNA].push_back(-90.18805990529991);
+    4781           4 :   parameter_solv_H[BB_DNA].push_back(-39731.13373512149);
+    4782           4 :   parameter_solv_H[BB_DNA].push_back(-10920.373563712872);
+    4783           4 :   parameter_solv_H[BB_DNA].push_back(72882.21702424981);
+    4784           4 :   parameter_solv_H[BB_DNA].push_back(-51747.487078112776);
+    4785           4 :   parameter_solv_H[BB_DNA].push_back(11308.678429018755);
+    4786             : 
+    4787           4 :   parameter_solv_H[BB_DNA_5].push_back(22737.624100119025);
+    4788           4 :   parameter_solv_H[BB_DNA_5].push_back(-102.72714886664161);
+    4789           4 :   parameter_solv_H[BB_DNA_5].push_back(-43685.329677789734);
+    4790           4 :   parameter_solv_H[BB_DNA_5].push_back(-12564.25937409345);
+    4791           4 :   parameter_solv_H[BB_DNA_5].push_back(83454.87540484878);
+    4792           4 :   parameter_solv_H[BB_DNA_5].push_back(-60367.15652138887);
+    4793           4 :   parameter_solv_H[BB_DNA_5].push_back(13507.333729868991);
+    4794             : 
+    4795           4 :   parameter_solv_H[BB_DNA_3].push_back(22737.62410011902);
+    4796           4 :   parameter_solv_H[BB_DNA_3].push_back(-101.57816684452251);
+    4797           4 :   parameter_solv_H[BB_DNA_3].push_back(-43488.536705576145);
+    4798           4 :   parameter_solv_H[BB_DNA_3].push_back(-12345.056184958425);
+    4799           4 :   parameter_solv_H[BB_DNA_3].push_back(81963.52364114887);
+    4800           4 :   parameter_solv_H[BB_DNA_3].push_back(-58791.59443618196);
+    4801           4 :   parameter_solv_H[BB_DNA_3].push_back(13003.199362335583);
+    4802             : 
+    4803           4 :   parameter_solv_H[BB_RNA].push_back(23953.752900120977);
+    4804           4 :   parameter_solv_H[BB_RNA].push_back(-117.35779348824417);
+    4805           4 :   parameter_solv_H[BB_RNA].push_back(-47644.41735332843);
+    4806           4 :   parameter_solv_H[BB_RNA].push_back(-14641.556643789861);
+    4807           4 :   parameter_solv_H[BB_RNA].push_back(96893.48627050371);
+    4808           4 :   parameter_solv_H[BB_RNA].push_back(-72249.62534169303);
+    4809           4 :   parameter_solv_H[BB_RNA].push_back(16792.055521055358);
+    4810             : 
+    4811           4 :   parameter_solv_H[BB_RNA_5].push_back(25574.406400119024);
+    4812           4 :   parameter_solv_H[BB_RNA_5].push_back(-131.99642772933734);
+    4813           4 :   parameter_solv_H[BB_RNA_5].push_back(-52136.51404531251);
+    4814           4 :   parameter_solv_H[BB_RNA_5].push_back(-16682.14273917604);
+    4815           4 :   parameter_solv_H[BB_RNA_5].push_back(110278.01921639398);
+    4816           4 :   parameter_solv_H[BB_RNA_5].push_back(-83715.92027818544);
+    4817           4 :   parameter_solv_H[BB_RNA_5].push_back(19875.89133770605);
+    4818             : 
+    4819           4 :   parameter_solv_H[BB_RNA_3].push_back(25574.406400119027);
+    4820           4 :   parameter_solv_H[BB_RNA_3].push_back(-127.96875237036166);
+    4821           4 :   parameter_solv_H[BB_RNA_3].push_back(-51407.18391758439);
+    4822           4 :   parameter_solv_H[BB_RNA_3].push_back(-15922.900669975606);
+    4823           4 :   parameter_solv_H[BB_RNA_3].push_back(105078.5888910626);
+    4824           4 :   parameter_solv_H[BB_RNA_3].push_back(-78289.16276190645);
+    4825           4 :   parameter_solv_H[BB_RNA_3].push_back(18156.832143441192);
+    4826             : 
+    4827           4 :   parameter_solv_H[BASE_A].push_back(13282.562500119211);
+    4828           4 :   parameter_solv_H[BASE_A].push_back(-76.45124168404048);
+    4829           4 :   parameter_solv_H[BASE_A].push_back(-28376.06994108963);
+    4830           4 :   parameter_solv_H[BASE_A].push_back(-9972.910773722022);
+    4831           4 :   parameter_solv_H[BASE_A].push_back(65873.86341939073);
+    4832           4 :   parameter_solv_H[BASE_A].push_back(-52064.33492910885);
+    4833           4 :   parameter_solv_H[BASE_A].push_back(12931.608989412513);
+    4834             : 
+    4835           4 :   parameter_solv_H[BASE_C].push_back(10600.76160011891);
+    4836           4 :   parameter_solv_H[BASE_C].push_back(-49.1670871249108);
+    4837           4 :   parameter_solv_H[BASE_C].push_back(-20239.818742072875);
+    4838           4 :   parameter_solv_H[BASE_C].push_back(-6020.278780090207);
+    4839           4 :   parameter_solv_H[BASE_C].push_back(39632.13288981881);
+    4840           4 :   parameter_solv_H[BASE_C].push_back(-28954.779736165576);
+    4841           4 :   parameter_solv_H[BASE_C].push_back(6551.541109526305);
+    4842             : 
+    4843           4 :   parameter_solv_H[BASE_G].push_back(15470.384400119934);
+    4844           4 :   parameter_solv_H[BASE_G].push_back(-93.8013620200972);
+    4845           4 :   parameter_solv_H[BASE_G].push_back(-36188.29687013545);
+    4846           4 :   parameter_solv_H[BASE_G].push_back(-13717.685098209471);
+    4847           4 :   parameter_solv_H[BASE_G].push_back(95658.18473657136);
+    4848           4 :   parameter_solv_H[BASE_G].push_back(-81262.37811451119);
+    4849           4 :   parameter_solv_H[BASE_G].push_back(21841.903930943085);
+    4850             : 
+    4851           4 :   parameter_solv_H[BASE_T].push_back(17210.81610011936);
+    4852           4 :   parameter_solv_H[BASE_T].push_back(-93.10189802920208);
+    4853           4 :   parameter_solv_H[BASE_T].push_back(-36466.51927689957);
+    4854           4 :   parameter_solv_H[BASE_T].push_back(-12425.55615716932);
+    4855           4 :   parameter_solv_H[BASE_T].push_back(83847.427808925);
+    4856           4 :   parameter_solv_H[BASE_T].push_back(-66735.64997846584);
+    4857           4 :   parameter_solv_H[BASE_T].push_back(16757.3463987507);
+    4858             : 
+    4859           4 :   parameter_solv_H[BASE_U].push_back(10909.802500119395);
+    4860           4 :   parameter_solv_H[BASE_U].push_back(-46.17712672768298);
+    4861           4 :   parameter_solv_H[BASE_U].push_back(-20149.67695512526);
+    4862           4 :   parameter_solv_H[BASE_U].push_back(-5590.242961204435);
+    4863           4 :   parameter_solv_H[BASE_U].push_back(37169.2740983132);
+    4864           4 :   parameter_solv_H[BASE_U].push_back(-26475.631627167604);
+    4865           4 :   parameter_solv_H[BASE_U].push_back(5808.201015156168);
+    4866             : 
+    4867           4 :   parameter_mix_H[BB_PO2].push_back(80.12660011920252);
+    4868           4 :   parameter_mix_H[BB_PO2].push_back(-0.0278885551982023);
+    4869           4 :   parameter_mix_H[BB_PO2].push_back(-60.532194918222984);
+    4870           4 :   parameter_mix_H[BB_PO2].push_back(-2.976882903409687);
+    4871           4 :   parameter_mix_H[BB_PO2].push_back(33.30645116638125);
+    4872           4 :   parameter_mix_H[BB_PO2].push_back(-11.601573219761374);
+    4873           4 :   parameter_mix_H[BB_PO2].push_back(0.12551046492022422);
+    4874             : 
+    4875           4 :   parameter_mix_H[BB_DNA].push_back(712.7621601191935);
+    4876           4 :   parameter_mix_H[BB_DNA].push_back(-0.3228709821198571);
+    4877           4 :   parameter_mix_H[BB_DNA].push_back(-784.5118228559945);
+    4878           4 :   parameter_mix_H[BB_DNA].push_back(-27.196125702249613);
+    4879           4 :   parameter_mix_H[BB_DNA].push_back(410.0185035102729);
+    4880           4 :   parameter_mix_H[BB_DNA].push_back(-54.453513369320355);
+    4881           4 :   parameter_mix_H[BB_DNA].push_back(-44.85506789237683);
+    4882             : 
+    4883           4 :   parameter_mix_H[BB_DNA_5].push_back(625.175339965785);
+    4884           4 :   parameter_mix_H[BB_DNA_5].push_back(0.2691706617748245);
+    4885           4 :   parameter_mix_H[BB_DNA_5].push_back(-582.8721350420001);
+    4886           4 :   parameter_mix_H[BB_DNA_5].push_back(46.512408351374326);
+    4887           4 :   parameter_mix_H[BB_DNA_5].push_back(-58.93886949899108);
+    4888           4 :   parameter_mix_H[BB_DNA_5].push_back(307.29720336085046);
+    4889           4 :   parameter_mix_H[BB_DNA_5].push_back(-131.71996309259953);
+    4890             : 
+    4891           4 :   parameter_mix_H[BB_DNA_3].push_back(625.1753399401266);
+    4892           4 :   parameter_mix_H[BB_DNA_3].push_back(0.08763234414546289);
+    4893           4 :   parameter_mix_H[BB_DNA_3].push_back(-606.8067575087485);
+    4894           4 :   parameter_mix_H[BB_DNA_3].push_back(20.84427254872218);
+    4895           4 :   parameter_mix_H[BB_DNA_3].push_back(92.53523123608991);
+    4896           4 :   parameter_mix_H[BB_DNA_3].push_back(162.04688035654937);
+    4897           4 :   parameter_mix_H[BB_DNA_3].push_back(-89.13571774638052);
+    4898             : 
+    4899           4 :   parameter_mix_H[BB_RNA].push_back(936.9775801191857);
+    4900           4 :   parameter_mix_H[BB_RNA].push_back(-1.3233686929680253);
+    4901           4 :   parameter_mix_H[BB_RNA].push_back(-1212.1627155263773);
+    4902           4 :   parameter_mix_H[BB_RNA].push_back(-141.35324744384351);
+    4903           4 :   parameter_mix_H[BB_RNA].push_back(1155.8281658363026);
+    4904           4 :   parameter_mix_H[BB_RNA].push_back(-548.9340055857343);
+    4905           4 :   parameter_mix_H[BB_RNA].push_back(50.81734777881503);
+    4906             : 
+    4907           4 :   parameter_mix_H[BB_RNA_5].push_back(848.5355201165631);
+    4908           4 :   parameter_mix_H[BB_RNA_5].push_back(-0.49570338490120175);
+    4909           4 :   parameter_mix_H[BB_RNA_5].push_back(-976.1033073783973);
+    4910           4 :   parameter_mix_H[BB_RNA_5].push_back(-32.943532187986605);
+    4911           4 :   parameter_mix_H[BB_RNA_5].push_back(475.66177061923884);
+    4912           4 :   parameter_mix_H[BB_RNA_5].push_back(17.51955845824258);
+    4913           4 :   parameter_mix_H[BB_RNA_5].push_back(-96.74451972314769);
+    4914             : 
+    4915           4 :   parameter_mix_H[BB_RNA_3].push_back(848.5355201192122);
+    4916           4 :   parameter_mix_H[BB_RNA_3].push_back(-0.8301109354355396);
+    4917           4 :   parameter_mix_H[BB_RNA_3].push_back(-1019.9524389785406);
+    4918           4 :   parameter_mix_H[BB_RNA_3].push_back(-84.1388451424885);
+    4919           4 :   parameter_mix_H[BB_RNA_3].push_back(787.1277245040931);
+    4920           4 :   parameter_mix_H[BB_RNA_3].push_back(-294.67807432795627);
+    4921           4 :   parameter_mix_H[BB_RNA_3].push_back(-1.3214626461251089);
+    4922             : 
+    4923           4 :   parameter_mix_H[BASE_A].push_back(1504.9345001191857);
+    4924           4 :   parameter_mix_H[BASE_A].push_back(-3.5306888452552663);
+    4925           4 :   parameter_mix_H[BASE_A].push_back(-2234.3933572775572);
+    4926           4 :   parameter_mix_H[BASE_A].push_back(-380.0255208494757);
+    4927           4 :   parameter_mix_H[BASE_A].push_back(2726.27802432048);
+    4928           4 :   parameter_mix_H[BASE_A].push_back(-1490.8825754968443);
+    4929           4 :   parameter_mix_H[BASE_A].push_back(199.7501110740159);
+    4930             : 
+    4931           4 :   parameter_mix_H[BASE_C].push_back(939.8188801192172);
+    4932           4 :   parameter_mix_H[BASE_C].push_back(-1.489638186262854);
+    4933           4 :   parameter_mix_H[BASE_C].push_back(-1244.5515798554075);
+    4934           4 :   parameter_mix_H[BASE_C].push_back(-161.3972705672055);
+    4935           4 :   parameter_mix_H[BASE_C].push_back(1276.3568466722545);
+    4936           4 :   parameter_mix_H[BASE_C].push_back(-643.3057776225742);
+    4937           4 :   parameter_mix_H[BASE_C].push_back(72.75963113826273);
+    4938             : 
+    4939           4 :   parameter_mix_H[BASE_G].push_back(1768.434840119199);
+    4940           4 :   parameter_mix_H[BASE_G].push_back(-6.505347007077434);
+    4941           4 :   parameter_mix_H[BASE_G].push_back(-2919.3856777898427);
+    4942           4 :   parameter_mix_H[BASE_G].push_back(-701.2456464463938);
+    4943           4 :   parameter_mix_H[BASE_G].push_back(4464.594230284102);
+    4944           4 :   parameter_mix_H[BASE_G].push_back(-2733.138521295608);
+    4945           4 :   parameter_mix_H[BASE_G].push_back(458.1177706235891);
+    4946             : 
+    4947           4 :   parameter_mix_H[BASE_T].push_back(1179.3981001192033);
+    4948           4 :   parameter_mix_H[BASE_T].push_back(-3.2037849252756527);
+    4949           4 :   parameter_mix_H[BASE_T].push_back(-1821.255498763799);
+    4950           4 :   parameter_mix_H[BASE_T].push_back(-371.01993266441303);
+    4951           4 :   parameter_mix_H[BASE_T].push_back(2604.074226688971);
+    4952           4 :   parameter_mix_H[BASE_T].push_back(-1648.1965787713084);
+    4953           4 :   parameter_mix_H[BASE_T].push_back(307.2962186436368);
+    4954             : 
+    4955           4 :   parameter_mix_H[BASE_U].push_back(956.3442001192266);
+    4956           4 :   parameter_mix_H[BASE_U].push_back(-1.724458000760567);
+    4957           4 :   parameter_mix_H[BASE_U].push_back(-1287.9746970192687);
+    4958           4 :   parameter_mix_H[BASE_U].push_back(-192.74748379510373);
+    4959           4 :   parameter_mix_H[BASE_U].push_back(1459.0789258833893);
+    4960           4 :   parameter_mix_H[BASE_U].push_back(-810.0763075080915);
+    4961           4 :   parameter_mix_H[BASE_U].push_back(119.81810290248339);
+    4962             : 
+    4963           4 :   parameter_vac_H[BB_PO2].push_back(2.7889001116093275);
+    4964           4 :   parameter_vac_H[BB_PO2].push_back(-0.00011178884266113128);
+    4965           4 :   parameter_vac_H[BB_PO2].push_back(-1.1702605818380667);
+    4966           4 :   parameter_vac_H[BB_PO2].push_back(-0.011278044036819933);
+    4967           4 :   parameter_vac_H[BB_PO2].push_back(0.3214006584089025);
+    4968           4 :   parameter_vac_H[BB_PO2].push_back(-0.04097165983591666);
+    4969           4 :   parameter_vac_H[BB_PO2].push_back(-0.017525098100539722);
+    4970             : 
+    4971           4 :   parameter_vac_H[BB_DNA].push_back(5.987809026456476);
+    4972           4 :   parameter_vac_H[BB_DNA].push_back(9.945454528827912e-05);
+    4973           4 :   parameter_vac_H[BB_DNA].push_back(-1.1884708569330031);
+    4974           4 :   parameter_vac_H[BB_DNA].push_back(-0.007457733256362841);
+    4975           4 :   parameter_vac_H[BB_DNA].push_back(0.05666858781418339);
+    4976           4 :   parameter_vac_H[BB_DNA].push_back(-0.15158797629971757);
+    4977           4 :   parameter_vac_H[BB_DNA].push_back(0.11642340861329734);
+    4978             : 
+    4979           4 :   parameter_vac_H[BB_DNA_5].push_back(4.297328944539055);
+    4980           4 :   parameter_vac_H[BB_DNA_5].push_back(0.0014793971885106831);
+    4981           4 :   parameter_vac_H[BB_DNA_5].push_back(1.3961088365255605);
+    4982           4 :   parameter_vac_H[BB_DNA_5].push_back(0.08974639858979384);
+    4983           4 :   parameter_vac_H[BB_DNA_5].push_back(-1.5198099705167643);
+    4984           4 :   parameter_vac_H[BB_DNA_5].push_back(-0.12127122359433733);
+    4985           4 :   parameter_vac_H[BB_DNA_5].push_back(0.4134601046223601);
+    4986             : 
+    4987           4 :   parameter_vac_H[BB_DNA_3].push_back(4.297328886488132);
+    4988           4 :   parameter_vac_H[BB_DNA_3].push_back(0.0041802954281271905);
+    4989           4 :   parameter_vac_H[BB_DNA_3].push_back(1.6065462295705266);
+    4990           4 :   parameter_vac_H[BB_DNA_3].push_back(0.4399805535688805);
+    4991           4 :   parameter_vac_H[BB_DNA_3].push_back(-3.3806711791929804);
+    4992           4 :   parameter_vac_H[BB_DNA_3].push_back(1.6729551563628675);
+    4993           4 :   parameter_vac_H[BB_DNA_3].push_back(-0.10911063067909885);
+    4994             : 
+    4995           4 :   parameter_vac_H[BB_RNA].push_back(9.162728984394093);
+    4996           4 :   parameter_vac_H[BB_RNA].push_back(0.00019952321584579868);
+    4997           4 :   parameter_vac_H[BB_RNA].push_back(-4.744748946331966);
+    4998           4 :   parameter_vac_H[BB_RNA].push_back(0.025106563403946364);
+    4999           4 :   parameter_vac_H[BB_RNA].push_back(1.2302956694109803);
+    5000           4 :   parameter_vac_H[BB_RNA].push_back(0.12359062278096915);
+    5001           4 :   parameter_vac_H[BB_RNA].push_back(-0.1725633367685285);
+    5002             : 
+    5003           4 :   parameter_vac_H[BB_RNA_5].push_back(7.038408898671503);
+    5004           4 :   parameter_vac_H[BB_RNA_5].push_back(0.005106788424920148);
+    5005           4 :   parameter_vac_H[BB_RNA_5].push_back(-0.8981588221803118);
+    5006           4 :   parameter_vac_H[BB_RNA_5].push_back(0.4922588155214312);
+    5007           4 :   parameter_vac_H[BB_RNA_5].push_back(-2.6667853454023644);
+    5008           4 :   parameter_vac_H[BB_RNA_5].push_back(1.533316567240718);
+    5009           4 :   parameter_vac_H[BB_RNA_5].push_back(-0.07199604869737707);
+    5010             : 
+    5011           4 :   parameter_vac_H[BB_RNA_3].push_back(7.038408892621863);
+    5012           4 :   parameter_vac_H[BB_RNA_3].push_back(0.002993083907266898);
+    5013           4 :   parameter_vac_H[BB_RNA_3].push_back(-1.3626596831098492);
+    5014           4 :   parameter_vac_H[BB_RNA_3].push_back(0.3138856961130113);
+    5015           4 :   parameter_vac_H[BB_RNA_3].push_back(-1.684185014289391);
+    5016           4 :   parameter_vac_H[BB_RNA_3].push_back(1.1862168720864616);
+    5017           4 :   parameter_vac_H[BB_RNA_3].push_back(-0.1443894172417523);
+    5018             : 
+    5019           4 :   parameter_vac_H[BASE_A].push_back(42.62784088079008);
+    5020           4 :   parameter_vac_H[BASE_A].push_back(0.02302908536431516);
+    5021           4 :   parameter_vac_H[BASE_A].push_back(-33.22707177297222);
+    5022           4 :   parameter_vac_H[BASE_A].push_back(2.6853748424439834);
+    5023           4 :   parameter_vac_H[BASE_A].push_back(-1.6632902891624768);
+    5024           4 :   parameter_vac_H[BASE_A].push_back(11.905766349515268);
+    5025           4 :   parameter_vac_H[BASE_A].push_back(-4.547083454788805);
+    5026             : 
+    5027           4 :   parameter_vac_H[BASE_C].push_back(20.83009588079022);
+    5028           4 :   parameter_vac_H[BASE_C].push_back(0.017055822321768378);
+    5029           4 :   parameter_vac_H[BASE_C].push_back(-8.349634734370916);
+    5030           4 :   parameter_vac_H[BASE_C].push_back(1.9324634367723073);
+    5031           4 :   parameter_vac_H[BASE_C].push_back(-8.435199734060882);
+    5032           4 :   parameter_vac_H[BASE_C].push_back(8.272798368731268);
+    5033           4 :   parameter_vac_H[BASE_C].push_back(-1.986671440757263);
+    5034             : 
+    5035           4 :   parameter_vac_H[BASE_G].push_back(50.53788088079374);
+    5036           4 :   parameter_vac_H[BASE_G].push_back(0.024035597617780367);
+    5037           4 :   parameter_vac_H[BASE_G].push_back(-47.94916639302998);
+    5038           4 :   parameter_vac_H[BASE_G].push_back(3.143375731466498);
+    5039           4 :   parameter_vac_H[BASE_G].push_back(4.297009866708155);
+    5040           4 :   parameter_vac_H[BASE_G].push_back(15.855448505050578);
+    5041           4 :   parameter_vac_H[BASE_G].push_back(-7.827484135873966);
+    5042             : 
+    5043           4 :   parameter_vac_H[BASE_T].push_back(20.20502488079069);
+    5044           4 :   parameter_vac_H[BASE_T].push_back(0.033659966153300002);
+    5045           4 :   parameter_vac_H[BASE_T].push_back(-6.057999187718758);
+    5046           4 :   parameter_vac_H[BASE_T].push_back(4.146969282504351);
+    5047           4 :   parameter_vac_H[BASE_T].push_back(-20.664315319574357);
+    5048           4 :   parameter_vac_H[BASE_T].push_back(19.982178623201648);
+    5049           4 :   parameter_vac_H[BASE_T].push_back(-5.440921587349456);
+    5050             : 
+    5051           4 :   parameter_vac_H[BASE_U].push_back(20.958084119209754);
+    5052           4 :   parameter_vac_H[BASE_U].push_back(-0.005164660707148803);
+    5053           4 :   parameter_vac_H[BASE_U].push_back(-14.53831312442302);
+    5054           4 :   parameter_vac_H[BASE_U].push_back(-0.5276995756310442);
+    5055           4 :   parameter_vac_H[BASE_U].push_back(7.060900707522138);
+    5056           4 :   parameter_vac_H[BASE_U].push_back(-1.8988408480951036);
+    5057           4 :   parameter_vac_H[BASE_U].push_back(-0.215000567681094);
+    5058             : 
+    5059       14298 :   for(unsigned i=0; i<atoms.size(); ++i) {
+    5060       14294 :     std::string Aname = pdb.getAtomName(atoms[i]);
+    5061       14294 :     std::string Rname = pdb.getResidueName(atoms[i]);
+    5062       14294 :     Rname.erase(std::remove_if(Rname.begin(), Rname.end(), ::isspace),Rname.end());
+    5063       14294 :     if(Rname=="ALA") {
+    5064         732 :       atoi[residue_atom[i]]=ALA;
+    5065       13562 :     } else if(Rname=="ARG") {
+    5066         864 :       atoi[residue_atom[i]]=ARG;
+    5067       12698 :     } else if(Rname=="ASN") {
+    5068         720 :       atoi[residue_atom[i]]=ASN;
+    5069       11978 :     } else if(Rname=="ASP") {
+    5070         624 :       atoi[residue_atom[i]]=ASP;
+    5071       11354 :     } else if(Rname=="CYS") {
+    5072          48 :       atoi[residue_atom[i]]=CYS;
+    5073       11306 :     } else if(Rname=="GLN") {
+    5074        1064 :       atoi[residue_atom[i]]=GLN;
+    5075       10242 :     } else if(Rname=="GLU") {
+    5076         476 :       atoi[residue_atom[i]]=GLU;
+    5077        9766 :     } else if(Rname=="GLY") {
+    5078         648 :       atoi[residue_atom[i]]=GLY;
+    5079        9118 :     } else if(Rname=="HIS") {
+    5080           0 :       atoi[residue_atom[i]]=HIS;
+    5081        9118 :     } else if(Rname=="HID") {
+    5082           0 :       atoi[residue_atom[i]]=HIS;
+    5083        9118 :     } else if(Rname=="HIE") {
+    5084         144 :       atoi[residue_atom[i]]=HIS;
+    5085        8974 :     } else if(Rname=="HIP") {
+    5086           0 :       atoi[residue_atom[i]]=HIP;
+    5087             :       // CHARMM NAMING FOR PROTONATION STATES OF HISTIDINE
+    5088        8974 :     } else if(Rname=="HSD") {
+    5089           0 :       atoi[residue_atom[i]]=HIS;
+    5090        8974 :     } else if(Rname=="HSE") {
+    5091           0 :       atoi[residue_atom[i]]=HIS;
+    5092        8974 :     } else if(Rname=="HSP") {
+    5093           0 :       atoi[residue_atom[i]]=HIP;
+    5094        8974 :     } else if(Rname=="ILE") {
+    5095         864 :       atoi[residue_atom[i]]=ILE;
+    5096        8110 :     } else if(Rname=="LEU") {
+    5097        1520 :       atoi[residue_atom[i]]=LEU;
+    5098        6590 :     } else if(Rname=="LYS") {
+    5099        1040 :       atoi[residue_atom[i]]=LYS;
+    5100        5550 :     } else if(Rname=="MET") {
+    5101         608 :       atoi[residue_atom[i]]=MET;
+    5102        4942 :     } else if(Rname=="PHE") {
+    5103        1008 :       atoi[residue_atom[i]]=PHE;
+    5104        3934 :     } else if(Rname=="PRO") {
+    5105         748 :       atoi[residue_atom[i]]=PRO;
+    5106        3186 :     } else if(Rname=="SER") {
+    5107         528 :       atoi[residue_atom[i]]=SER;
+    5108        2658 :     } else if(Rname=="THR") {
+    5109         504 :       atoi[residue_atom[i]]=THR;
+    5110        2154 :     } else if(Rname=="TRP") {
+    5111           0 :       atoi[residue_atom[i]]=TRP;
+    5112        2154 :     } else if(Rname=="TYR") {
+    5113         528 :       atoi[residue_atom[i]]=TYR;
+    5114        1626 :     } else if(Rname=="VAL") {
+    5115        1088 :       atoi[residue_atom[i]]=VAL;
+    5116             :     }
+    5117             :     // NUCLEIC ACIDS
+    5118             :     // nucleobases are not automatically populated as an additional check on the health of the PDB.
+    5119             :     // RNA - G
+    5120         538 :     else if(Rname=="G") {
+    5121           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    5122           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    5123           0 :         atoi [residue_atom[i]]=BB_PO2;
+    5124           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5125           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    5126           0 :                 Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    5127           0 :                 Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="H3T"  ||
+    5128           0 :                 Aname=="HO5'" || Aname=="HO3'" || Aname=="HO2'" || Aname=="H5'1" ||
+    5129           0 :                 Aname=="H5'2" || Aname=="HO'2" || Aname=="H2'1" || Aname=="H5T" ) {
+    5130           0 :         atoi[residue_atom[i]]=BB_RNA;
+    5131           0 :       } else if( Aname=="N1" || Aname=="C2"  || Aname=="N2" || Aname=="N3" ||
+    5132           0 :                  Aname=="C4" || Aname=="C5"  || Aname=="C6" || Aname=="O6" ||
+    5133           0 :                  Aname=="N7" || Aname=="C8"  || Aname=="N9" || Aname=="H1" ||
+    5134           0 :                  Aname=="H8" || Aname=="H21" || Aname=="H22" ) {
+    5135           0 :         atoi[residue_atom[i]]=BASE_G;
+    5136           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5137             :       // RNA - G3
+    5138         538 :     } else if(Rname=="G3") {
+    5139           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    5140           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    5141           0 :         atoi [residue_atom[i]]=BB_PO2;
+    5142           0 :       } else if(Aname=="O5'"  || Aname=="C5'" || Aname=="O4'"  || Aname=="C4'"  ||
+    5143           0 :                 Aname=="O3'"  || Aname=="C3'" || Aname=="O2'"  || Aname=="C2'"  ||
+    5144           0 :                 Aname=="C1'"  || Aname=="H5'" || Aname=="H5''" || Aname=="H4'"  ||
+    5145           0 :                 Aname=="H3'"  || Aname=="H2'" || Aname=="H1'"  || Aname=="H3T"  ||
+    5146           0 :                 Aname=="H2'1" || Aname=="HO3'"|| Aname=="HO2'" || Aname=="H5'1" ||
+    5147           0 :                 Aname=="H5'2" || Aname=="HO'2" ) {
+    5148           0 :         atoi[residue_atom[i]]=BB_RNA_3;
+    5149           0 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="N2" || Aname=="N3" ||
+    5150           0 :                 Aname=="C4" || Aname=="C5"  || Aname=="C6" || Aname=="O6" ||
+    5151           0 :                 Aname=="N7" || Aname=="C8"  || Aname=="N9" || Aname=="H1" ||
+    5152           0 :                 Aname=="H8" || Aname=="H21" || Aname=="H22" ) {
+    5153           0 :         atoi[residue_atom[i]]=BASE_G;
+    5154           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5155             :       // RNA - G5
+    5156         538 :     } else if(Rname=="G5") {
+    5157           0 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5158           0 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    5159           0 :           Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    5160           0 :           Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="HO5'" ||
+    5161           0 :           Aname=="HO2'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="HO'2" ||
+    5162           0 :           Aname=="H2'1" || Aname=="H5T" ) {
+    5163           0 :         atoi[residue_atom[i]]=BB_RNA_5;
+    5164           0 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="N2" || Aname=="N3" ||
+    5165           0 :                 Aname=="C4" || Aname=="C5"  || Aname=="C6" || Aname=="O6" ||
+    5166           0 :                 Aname=="N7" || Aname=="C8"  || Aname=="N9" || Aname=="H1" ||
+    5167           0 :                 Aname=="H8" || Aname=="H21" || Aname=="H22" ) {
+    5168           0 :         atoi[residue_atom[i]]=BASE_G;
+    5169           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5170             :       // RNA - U
+    5171         538 :     } else if(Rname=="U") {
+    5172        1554 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    5173        1176 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    5174          42 :         atoi [residue_atom[i]]=BB_PO2;
+    5175        1372 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5176        1148 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    5177         924 :                 Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    5178         714 :                 Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="H3T"  ||
+    5179         644 :                 Aname=="HO5'" || Aname=="HO3'" || Aname=="HO2'" || Aname=="H5'1" ||
+    5180         840 :                 Aname=="H5'2" || Aname=="HO'2" || Aname=="H2'1" || Aname=="H5T" ) {
+    5181         224 :         atoi[residue_atom[i]]=BB_RNA;
+    5182         476 :       } else if( Aname=="N1" || Aname=="C2"  || Aname=="O2" || Aname=="N3" ||
+    5183         252 :                  Aname=="C4" || Aname=="O4"  || Aname=="C5" || Aname=="C6" ||
+    5184         196 :                  Aname=="H3" || Aname=="H5"  || Aname=="H6") {
+    5185         154 :         atoi[residue_atom[i]]=BASE_U;
+    5186           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5187             :       // RNA - U3
+    5188         118 :     } else if(Rname=="U3") {
+    5189         230 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    5190         174 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    5191           6 :         atoi [residue_atom[i]]=BB_PO2;
+    5192         204 :       } else if(Aname=="O5'"  || Aname=="C5'" || Aname=="O4'"  || Aname=="C4'"  ||
+    5193         172 :                 Aname=="O3'"  || Aname=="C3'" || Aname=="O2'"  || Aname=="C2'"  ||
+    5194         140 :                 Aname=="C1'"  || Aname=="H5'" || Aname=="H5''" || Aname=="H4'"  ||
+    5195         110 :                 Aname=="H3'"  || Aname=="H2'" || Aname=="H1'"  || Aname=="H3T"  ||
+    5196          94 :                 Aname=="H2'1" || Aname=="HO3'"|| Aname=="HO2'" || Aname=="H5'1" ||
+    5197          78 :                 Aname=="H5'2" || Aname=="HO'2" ) {
+    5198          34 :         atoi[residue_atom[i]]=BB_RNA_3;
+    5199          68 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="O2" || Aname=="N3" ||
+    5200          36 :                 Aname=="C4" || Aname=="O4"  || Aname=="C5" || Aname=="C6" ||
+    5201          28 :                 Aname=="H3" || Aname=="H5"  || Aname=="H6") {
+    5202          22 :         atoi[residue_atom[i]]=BASE_U;
+    5203           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5204             :       // RNA - U5
+    5205          56 :     } else if(Rname=="U5") {
+    5206         204 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5207         172 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    5208         140 :           Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    5209         108 :           Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="HO5'" ||
+    5210          88 :           Aname=="HO2'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="HO'2" ||
+    5211          78 :           Aname=="H2'1" || Aname=="H5T" ) {
+    5212          34 :         atoi[residue_atom[i]]=BB_RNA_5;
+    5213          68 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="O2" || Aname=="N3" ||
+    5214          36 :                 Aname=="C4" || Aname=="O4"  || Aname=="C5" || Aname=="C6" ||
+    5215          28 :                 Aname=="H3" || Aname=="H5"  || Aname=="H6") {
+    5216          22 :         atoi[residue_atom[i]]=BASE_U;
+    5217           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5218             :       // RNA - A
+    5219           0 :     } else if(Rname=="A") {
+    5220           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    5221           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    5222           0 :         atoi [residue_atom[i]]=BB_PO2;
+    5223           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5224           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    5225           0 :                 Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    5226           0 :                 Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="H3T"  ||
+    5227           0 :                 Aname=="HO5'" || Aname=="HO3'" || Aname=="HO2'" || Aname=="H5'1" ||
+    5228           0 :                 Aname=="H5'2" || Aname=="HO'2" || Aname=="H2'1" || Aname=="H5T" ) {
+    5229           0 :         atoi[residue_atom[i]]=BB_RNA;
+    5230           0 :       } else if(Aname=="N1"  || Aname=="C2" || Aname=="N3" || Aname=="C4" ||
+    5231           0 :                 Aname=="C5"  || Aname=="C6" || Aname=="N6" || Aname=="N7" ||
+    5232           0 :                 Aname=="C8"  || Aname=="N9" || Aname=="H2" || Aname=="H8" ||
+    5233           0 :                 Aname=="H61" || Aname=="H62" ) {
+    5234           0 :         atoi[residue_atom[i]]=BASE_A;
+    5235           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5236             :       // RNA - A3
+    5237           0 :     } else if(Rname=="A3") {
+    5238           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    5239           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    5240           0 :         atoi [residue_atom[i]]=BB_PO2;
+    5241           0 :       } else if(Aname=="O5'"  || Aname=="C5'" || Aname=="O4'"  || Aname=="C4'"  ||
+    5242           0 :                 Aname=="O3'"  || Aname=="C3'" || Aname=="O2'"  || Aname=="C2'"  ||
+    5243           0 :                 Aname=="C1'"  || Aname=="H5'" || Aname=="H5''" || Aname=="H4'"  ||
+    5244           0 :                 Aname=="H3'"  || Aname=="H2'" || Aname=="H1'"  || Aname=="H3T"  ||
+    5245           0 :                 Aname=="H2'1" || Aname=="HO3'"|| Aname=="HO2'" || Aname=="H5'1" ||
+    5246           0 :                 Aname=="H5'2" || Aname=="HO'2" ) {
+    5247           0 :         atoi[residue_atom[i]]=BB_RNA_3;
+    5248           0 :       } else if(Aname=="N1"  || Aname=="C2" || Aname=="N3" || Aname=="C4" ||
+    5249           0 :                 Aname=="C5"  || Aname=="C6" || Aname=="N6" || Aname=="N7" ||
+    5250           0 :                 Aname=="C8"  || Aname=="N9" || Aname=="H2" || Aname=="H8" ||
+    5251           0 :                 Aname=="H61" || Aname=="H62" ) {
+    5252           0 :         atoi[residue_atom[i]]=BASE_A;
+    5253           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5254             :       // RNA - A5
+    5255           0 :     } else if(Rname=="A5") {
+    5256           0 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5257           0 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    5258           0 :           Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    5259           0 :           Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="HO5'" ||
+    5260           0 :           Aname=="HO2'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="HO'2" ||
+    5261           0 :           Aname=="H2'1" || Aname=="H5T" ) {
+    5262           0 :         atoi[residue_atom[i]]=BB_RNA_5;
+    5263           0 :       } else if(Aname=="N1"  || Aname=="C2" || Aname=="N3" || Aname=="C4" ||
+    5264           0 :                 Aname=="C5"  || Aname=="C6" || Aname=="N6" || Aname=="N7" ||
+    5265           0 :                 Aname=="C8"  || Aname=="N9" || Aname=="H2" || Aname=="H8" ||
+    5266           0 :                 Aname=="H61" || Aname=="H62" ) {
+    5267           0 :         atoi[residue_atom[i]]=BASE_A;
+    5268           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5269             :       // RNA - C
+    5270           0 :     } else if(Rname=="C") {
+    5271           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    5272           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    5273           0 :         atoi [residue_atom[i]]=BB_PO2;
+    5274           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5275           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    5276           0 :                 Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    5277           0 :                 Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="H3T"  ||
+    5278           0 :                 Aname=="HO5'" || Aname=="HO3'" || Aname=="HO2'" || Aname=="H5'1" ||
+    5279           0 :                 Aname=="H5'2" || Aname=="HO'2" || Aname=="H2'1" || Aname=="H5T" ) {
+    5280           0 :         atoi[residue_atom[i]]=BB_RNA;
+    5281           0 :       } else if(Aname=="N1" || Aname=="C2" || Aname=="O2"  || Aname=="N3" ||
+    5282           0 :                 Aname=="C4" || Aname=="N4" || Aname=="C5"  || Aname=="C6" ||
+    5283           0 :                 Aname=="H5" || Aname=="H6" || Aname=="H41" || Aname=="H42" ) {
+    5284           0 :         atoi[residue_atom[i]]=BASE_C;
+    5285           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5286             :       // RNA - C3
+    5287           0 :     } else if(Rname=="C3") {
+    5288           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    5289           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    5290           0 :         atoi [residue_atom[i]]=BB_PO2;
+    5291           0 :       } else if(Aname=="O5'"  || Aname=="C5'" || Aname=="O4'"  || Aname=="C4'"  ||
+    5292           0 :                 Aname=="O3'"  || Aname=="C3'" || Aname=="O2'"  || Aname=="C2'"  ||
+    5293           0 :                 Aname=="C1'"  || Aname=="H5'" || Aname=="H5''" || Aname=="H4'"  ||
+    5294           0 :                 Aname=="H3'"  || Aname=="H2'" || Aname=="H1'"  || Aname=="H3T"  ||
+    5295           0 :                 Aname=="H2'1" || Aname=="HO3'"|| Aname=="HO2'" || Aname=="H5'1" ||
+    5296           0 :                 Aname=="H5'2" || Aname=="HO'2" ) {
+    5297           0 :         atoi[residue_atom[i]]=BB_RNA_3;
+    5298           0 :       } else if(Aname=="N1" || Aname=="C2" || Aname=="O2"  || Aname=="N3" ||
+    5299           0 :                 Aname=="C4" || Aname=="N4" || Aname=="C5"  || Aname=="C6" ||
+    5300           0 :                 Aname=="H5" || Aname=="H6" || Aname=="H41" || Aname=="H42" ) {
+    5301           0 :         atoi[residue_atom[i]]=BASE_C;
+    5302           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5303             :       // RNA - C5
+    5304           0 :     } else if(Rname=="C5") {
+    5305           0 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5306           0 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    5307           0 :           Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    5308           0 :           Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="HO5'" ||
+    5309           0 :           Aname=="HO2'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="HO'2" ||
+    5310           0 :           Aname=="H2'1" || Aname=="H5T" ) {
+    5311           0 :         atoi[residue_atom[i]]=BB_RNA_5;
+    5312           0 :       } else if(Aname=="N1" || Aname=="C2" || Aname=="O2"  || Aname=="N3" ||
+    5313           0 :                 Aname=="C4" || Aname=="N4" || Aname=="C5"  || Aname=="C6" ||
+    5314           0 :                 Aname=="H5" || Aname=="H6" || Aname=="H41" || Aname=="H42" ) {
+    5315           0 :         atoi[residue_atom[i]]=BASE_C;
+    5316           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5317             :       // DNA - G
+    5318           0 :     } else if(Rname=="DG") {
+    5319           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    5320           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    5321           0 :         atoi [residue_atom[i]]=BB_PO2;
+    5322           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5323           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    5324           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    5325           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    5326           0 :                 Aname=="HO3'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" ||
+    5327           0 :                 Aname=="H2'2" || Aname=="H5T"  || Aname=="H3T" ) {
+    5328           0 :         atoi[residue_atom[i]]=BB_DNA;
+    5329           0 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="N2" || Aname=="N3" ||
+    5330           0 :                 Aname=="C4" || Aname=="C5"  || Aname=="C6" || Aname=="O6" ||
+    5331           0 :                 Aname=="N7" || Aname=="C8"  || Aname=="N9" || Aname=="H1" ||
+    5332           0 :                 Aname=="H8" || Aname=="H21" || Aname=="H22" ) {
+    5333           0 :         atoi[residue_atom[i]]=BASE_G;
+    5334           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5335             :       // DNA - G3
+    5336           0 :     } else if(Rname=="DG3") {
+    5337           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    5338           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    5339           0 :         atoi [residue_atom[i]]=BB_PO2;
+    5340           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5341           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    5342           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    5343           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO3'" ||
+    5344           0 :                 Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    5345             :                 Aname=="H3T" ) {
+    5346           0 :         atoi[residue_atom[i]]=BB_DNA_3;
+    5347           0 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="N2" || Aname=="N3" ||
+    5348           0 :                 Aname=="C4" || Aname=="C5"  || Aname=="C6" || Aname=="O6" ||
+    5349           0 :                 Aname=="N7" || Aname=="C8"  || Aname=="N9" || Aname=="H1" ||
+    5350           0 :                 Aname=="H8" || Aname=="H21" || Aname=="H22" ) {
+    5351           0 :         atoi[residue_atom[i]]=BASE_G;
+    5352           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5353             :       // DNA - G5
+    5354           0 :     } else if(Rname=="DG5") {
+    5355           0 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5356           0 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  ||  Aname=="C1'" ||
+    5357           0 :           Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    5358           0 :           Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    5359           0 :           Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    5360             :           Aname=="H5T" ) {
+    5361           0 :         atoi[residue_atom[i]]=BB_DNA_5;
+    5362           0 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="N2" || Aname=="N3" ||
+    5363           0 :                 Aname=="C4" || Aname=="C5"  || Aname=="C6" || Aname=="O6" ||
+    5364           0 :                 Aname=="N7" || Aname=="C8"  || Aname=="N9" || Aname=="H1" ||
+    5365           0 :                 Aname=="H8" || Aname=="H21" || Aname=="H22" ) {
+    5366           0 :         atoi[residue_atom[i]]=BASE_G;
+    5367           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5368             :       // DNA - T
+    5369           0 :     } else if(Rname=="DT") {
+    5370           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    5371           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    5372           0 :         atoi [residue_atom[i]]=BB_PO2;
+    5373           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5374           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    5375           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    5376           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    5377           0 :                 Aname=="HO3'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" ||
+    5378           0 :                 Aname=="H2'2" || Aname=="H5T"  || Aname=="H3T" ) {
+    5379           0 :         atoi[residue_atom[i]]=BB_DNA;
+    5380           0 :       } else if(Aname=="N1"  || Aname=="C2"  || Aname=="O2"  || Aname=="N3"  ||
+    5381           0 :                 Aname=="C4"  || Aname=="O4"  || Aname=="C5"  || Aname=="C6"  ||
+    5382           0 :                 Aname=="C7"  || Aname=="H3"  || Aname=="H6"  || Aname=="H71" ||
+    5383           0 :                 Aname=="H72" || Aname=="H73" ) {
+    5384           0 :         atoi[residue_atom[i]]=BASE_T;
+    5385           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5386             :       // DNA - T3
+    5387           0 :     } else if(Rname=="DT3") {
+    5388           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    5389           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    5390           0 :         atoi [residue_atom[i]]=BB_PO2;
+    5391           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5392           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    5393           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    5394           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO3'" ||
+    5395           0 :                 Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    5396             :                 Aname=="H3T" ) {
+    5397           0 :         atoi[residue_atom[i]]=BB_DNA_3;
+    5398           0 :       } else if(Aname=="N1"  || Aname=="C2"  || Aname=="O2"  || Aname=="N3"  ||
+    5399           0 :                 Aname=="C4"  || Aname=="O4"  || Aname=="C5"  || Aname=="C6"  ||
+    5400           0 :                 Aname=="C7"  || Aname=="H3"  || Aname=="H6"  || Aname=="H71" ||
+    5401           0 :                 Aname=="H72" || Aname=="H73" ) {
+    5402           0 :         atoi[residue_atom[i]]=BASE_T;
+    5403           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5404             :       // DNA - T5
+    5405           0 :     } else if(Rname=="DT5") {
+    5406           0 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5407           0 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  ||  Aname=="C1'" ||
+    5408           0 :           Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    5409           0 :           Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    5410           0 :           Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    5411             :           Aname=="H5T" ) {
+    5412           0 :         atoi[residue_atom[i]]=BB_DNA_5;
+    5413           0 :       } else if(Aname=="N1"  || Aname=="C2"  || Aname=="O2"  || Aname=="N3"  ||
+    5414           0 :                 Aname=="C4"  || Aname=="O4"  || Aname=="C5"  || Aname=="C6"  ||
+    5415           0 :                 Aname=="C7"  || Aname=="H3"  || Aname=="H6"  || Aname=="H71" ||
+    5416           0 :                 Aname=="H72" || Aname=="H73" ) {
+    5417           0 :         atoi[residue_atom[i]]=BASE_T;
+    5418           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5419             :       // DNA - A
+    5420           0 :     } else if(Rname=="DA") {
+    5421           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    5422           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    5423           0 :         atoi [residue_atom[i]]=BB_PO2;
+    5424           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5425           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    5426           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    5427           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    5428           0 :                 Aname=="HO3'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" ||
+    5429           0 :                 Aname=="H2'2" || Aname=="H5T"  || Aname=="H3T" ) {
+    5430           0 :         atoi[residue_atom[i]]=BB_DNA;
+    5431           0 :       } else if(Aname=="N1"  || Aname=="C2" || Aname=="N3" || Aname=="C4" ||
+    5432           0 :                 Aname=="C5"  || Aname=="C6" || Aname=="N6" || Aname=="N7" ||
+    5433           0 :                 Aname=="C8"  || Aname=="N9" || Aname=="H2" || Aname=="H8" ||
+    5434           0 :                 Aname=="H61" || Aname=="H62" ) {
+    5435           0 :         atoi[residue_atom[i]]=BASE_A;
+    5436           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5437             :       // DNA - A3
+    5438           0 :     } else if(Rname=="DA3") {
+    5439           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    5440           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    5441           0 :         atoi [residue_atom[i]]=BB_PO2;
+    5442           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5443           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    5444           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    5445           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO3'" ||
+    5446           0 :                 Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    5447             :                 Aname=="H3T" ) {
+    5448           0 :         atoi[residue_atom[i]]=BB_DNA_3;
+    5449           0 :       } else if(Aname=="N1"  || Aname=="C2" || Aname=="N3" || Aname=="C4" ||
+    5450           0 :                 Aname=="C5"  || Aname=="C6" || Aname=="N6" || Aname=="N7" ||
+    5451           0 :                 Aname=="C8"  || Aname=="N9" || Aname=="H2" || Aname=="H8" ||
+    5452           0 :                 Aname=="H61" || Aname=="H62" ) {
+    5453           0 :         atoi[residue_atom[i]]=BASE_A;
+    5454           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5455             :       // DNA - A5
+    5456           0 :     } else if(Rname=="DA5") {
+    5457           0 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5458           0 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  ||  Aname=="C1'" ||
+    5459           0 :           Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    5460           0 :           Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    5461           0 :           Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    5462             :           Aname=="H5T" ) {
+    5463           0 :         atoi[residue_atom[i]]=BB_DNA_5;
+    5464           0 :       } else if(Aname=="N1"  || Aname=="C2" || Aname=="N3" || Aname=="C4" ||
+    5465           0 :                 Aname=="C5"  || Aname=="C6" || Aname=="N6" || Aname=="N7" ||
+    5466           0 :                 Aname=="C8"  || Aname=="N9" || Aname=="H2" || Aname=="H8" ||
+    5467           0 :                 Aname=="H61" || Aname=="H62" ) {
+    5468           0 :         atoi[residue_atom[i]]=BASE_A;
+    5469           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5470             :       // DNA - C
+    5471           0 :     } else if(Rname=="DC") {
+    5472           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    5473           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    5474           0 :         atoi [residue_atom[i]]=BB_PO2;
+    5475           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5476           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    5477           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    5478           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    5479           0 :                 Aname=="HO3'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" ||
+    5480           0 :                 Aname=="H2'2" || Aname=="H5T"  || Aname=="H3T" ) {
+    5481           0 :         atoi[residue_atom[i]]=BB_DNA;
+    5482           0 :       } else if(Aname=="N1" || Aname=="C2" || Aname=="O2"  || Aname=="N3" ||
+    5483           0 :                 Aname=="C4" || Aname=="N4" || Aname=="C5"  || Aname=="C6" ||
+    5484           0 :                 Aname=="H5" || Aname=="H6" || Aname=="H41" || Aname=="H42" ) {
+    5485           0 :         atoi[residue_atom[i]]=BASE_C;
+    5486           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5487             :       // DNA - C3
+    5488           0 :     } else if(Rname=="DC3") {
+    5489           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    5490           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    5491           0 :         atoi [residue_atom[i]]=BB_PO2;
+    5492           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5493           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    5494           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    5495           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO3'" ||
+    5496           0 :                 Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    5497             :                 Aname=="H3T" ) {
+    5498           0 :         atoi[residue_atom[i]]=BB_DNA_3;
+    5499           0 :       } else if(Aname=="N1" || Aname=="C2" || Aname=="O2"  || Aname=="N3" ||
+    5500           0 :                 Aname=="C4" || Aname=="N4" || Aname=="C5"  || Aname=="C6" ||
+    5501           0 :                 Aname=="H5" || Aname=="H6" || Aname=="H41" || Aname=="H42" ) {
+    5502           0 :         atoi[residue_atom[i]]=BASE_C;
+    5503           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5504             :       // DNA - C5
+    5505           0 :     } else if(Rname=="DC5") {
+    5506           0 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5507           0 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  ||  Aname=="C1'" ||
+    5508           0 :           Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    5509           0 :           Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    5510           0 :           Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    5511             :           Aname=="H5T" ) {
+    5512           0 :         atoi[residue_atom[i]]=BB_DNA_5;
+    5513           0 :       } else if(Aname=="N1" || Aname=="C2" || Aname=="O2"  || Aname=="N3" ||
+    5514           0 :                 Aname=="C4" || Aname=="N4" || Aname=="C5"  || Aname=="C6" ||
+    5515           0 :                 Aname=="H5" || Aname=="H6" || Aname=="H41" || Aname=="H42" ) {
+    5516           0 :         atoi[residue_atom[i]]=BASE_C;
+    5517           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5518           0 :     } else error("Residue not known: "+Rname);
+    5519             :   }
+    5520           4 : }
+    5521             : 
+    5522           4 : void SAXS::getOnebeadparam_sansD(const PDB &pdb, const std::vector<AtomNumber> &atoms, std::vector<std::vector<long double> > &parameter_vac_D, std::vector<std::vector<long double> > &parameter_mix_D)
+    5523             : { // parameter_solv is identical in SAXS/SANS_H/SANS_D since it depends exclusively on param_v. For that reason we kept param_solv only in SAXS and SANS_H.
+    5524           4 :   parameter_mix_D[TRP].push_back(8105.740500119327);
+    5525           4 :   parameter_mix_D[TRP].push_back(-41.785616935469804);
+    5526           4 :   parameter_mix_D[TRP].push_back(-25456.92790554363);
+    5527           4 :   parameter_mix_D[TRP].push_back(-10058.20599969184);
+    5528           4 :   parameter_mix_D[TRP].push_back(86171.76479108425);
+    5529           4 :   parameter_mix_D[TRP].push_back(-83227.63139882773);
+    5530           4 :   parameter_mix_D[TRP].push_back(25121.390436258724);
+    5531             : 
+    5532           4 :   parameter_mix_D[TYR].push_back(6059.530560118732);
+    5533           4 :   parameter_mix_D[TYR].push_back(-24.522695525705736);
+    5534           4 :   parameter_mix_D[TYR].push_back(-17180.858815360847);
+    5535           4 :   parameter_mix_D[TYR].push_back(-5990.1358528219325);
+    5536           4 :   parameter_mix_D[TYR].push_back(52936.46126637543);
+    5537           4 :   parameter_mix_D[TYR].push_back(-50150.0042622683);
+    5538           4 :   parameter_mix_D[TYR].push_back(14914.553672440441);
+    5539             : 
+    5540           4 :   parameter_mix_D[PHE].push_back(5563.404880119222);
+    5541           4 :   parameter_mix_D[PHE].push_back(-33.609784645922794);
+    5542           4 :   parameter_mix_D[PHE].push_back(-14576.935030777448);
+    5543           4 :   parameter_mix_D[PHE].push_back(-5759.170105553782);
+    5544           4 :   parameter_mix_D[PHE].push_back(43316.895956549866);
+    5545           4 :   parameter_mix_D[PHE].push_back(-39106.58694570862);
+    5546           4 :   parameter_mix_D[PHE].push_back(11143.375742877468);
+    5547             : 
+    5548           4 :   parameter_mix_D[HIP].push_back(3981.7108801192553);
+    5549           4 :   parameter_mix_D[HIP].push_back(-23.788371565946427);
+    5550           4 :   parameter_mix_D[HIP].push_back(-9471.73953776056);
+    5551           4 :   parameter_mix_D[HIP].push_back(-3690.3981577198365);
+    5552           4 :   parameter_mix_D[HIP].push_back(26365.958584217453);
+    5553           4 :   parameter_mix_D[HIP].push_back(-23067.58974902849);
+    5554           4 :   parameter_mix_D[HIP].push_back(6390.507451097114);
+    5555             : 
+    5556           4 :   parameter_mix_D[ARG].push_back(6279.489359881259);
+    5557           4 :   parameter_mix_D[ARG].push_back(1.2061878338083583);
+    5558           4 :   parameter_mix_D[ARG].push_back(-20305.413937989913);
+    5559           4 :   parameter_mix_D[ARG].push_back(-5621.666335222669);
+    5560           4 :   parameter_mix_D[ARG].push_back(67341.96785520067);
+    5561           4 :   parameter_mix_D[ARG].push_back(-68849.15464591733);
+    5562           4 :   parameter_mix_D[ARG].push_back(21773.0630363882);
+    5563             : 
+    5564           4 :   parameter_mix_D[LYS].push_back(5434.487400119193);
+    5565           4 :   parameter_mix_D[LYS].push_back(-29.32356328987909);
+    5566           4 :   parameter_mix_D[LYS].push_back(-14363.66155749977);
+    5567           4 :   parameter_mix_D[LYS].push_back(-5650.383128516514);
+    5568           4 :   parameter_mix_D[LYS].push_back(44573.73888236887);
+    5569           4 :   parameter_mix_D[LYS].push_back(-41515.980945300485);
+    5570           4 :   parameter_mix_D[LYS].push_back(12181.965046747513);
+    5571             : 
+    5572           4 :   parameter_mix_D[CYS].push_back(1519.4030001192032);
+    5573           4 :   parameter_mix_D[CYS].push_back(-3.564386334921097);
+    5574           4 :   parameter_mix_D[CYS].push_back(-2275.813167459516);
+    5575           4 :   parameter_mix_D[CYS].push_back(-409.54431591328125);
+    5576           4 :   parameter_mix_D[CYS].push_back(2969.5412742839258);
+    5577           4 :   parameter_mix_D[CYS].push_back(-1798.3157146799638);
+    5578           4 :   parameter_mix_D[CYS].push_back(314.568167888235);
+    5579             : 
+    5580           4 :   parameter_mix_D[ASP].push_back(1861.6998401191709);
+    5581           4 :   parameter_mix_D[ASP].push_back(-5.349780637260551);
+    5582           4 :   parameter_mix_D[ASP].push_back(-2960.36741510377);
+    5583           4 :   parameter_mix_D[ASP].push_back(-621.8270745040523);
+    5584           4 :   parameter_mix_D[ASP].push_back(4334.798300452934);
+    5585           4 :   parameter_mix_D[ASP].push_back(-2776.8560521554878);
+    5586           4 :   parameter_mix_D[ASP].push_back(527.9777182094936);
+    5587             : 
+    5588           4 :   parameter_mix_D[GLU].push_back(2861.6017201192253);
+    5589           4 :   parameter_mix_D[GLU].push_back(-13.146456903921809);
+    5590           4 :   parameter_mix_D[GLU].push_back(-5393.408563875243);
+    5591           4 :   parameter_mix_D[GLU].push_back(-1646.460570818364);
+    5592           4 :   parameter_mix_D[GLU].push_back(10884.544923253858);
+    5593           4 :   parameter_mix_D[GLU].push_back(-8159.923373048856);
+    5594           4 :   parameter_mix_D[GLU].push_back(1914.545660397314);
+    5595             : 
+    5596           4 :   parameter_mix_D[ILE].push_back(4288.585540119189);
+    5597           4 :   parameter_mix_D[ILE].push_back(-19.937215352880365);
+    5598           4 :   parameter_mix_D[ILE].push_back(-8324.540144463375);
+    5599           4 :   parameter_mix_D[ILE].push_back(-2431.835931316717);
+    5600           4 :   parameter_mix_D[ILE].push_back(16079.9912986194);
+    5601           4 :   parameter_mix_D[ILE].push_back(-11637.693060394462);
+    5602           4 :   parameter_mix_D[ILE].push_back(2600.8258068480495);
+    5603             : 
+    5604           4 :   parameter_mix_D[LEU].push_back(4288.585540119186);
+    5605           4 :   parameter_mix_D[LEU].push_back(-21.50343599461759);
+    5606           4 :   parameter_mix_D[LEU].push_back(-8479.703435720274);
+    5607           4 :   parameter_mix_D[LEU].push_back(-2647.8693829269596);
+    5608           4 :   parameter_mix_D[LEU].push_back(17297.18115838578);
+    5609           4 :   parameter_mix_D[LEU].push_back(-12826.972408323161);
+    5610           4 :   parameter_mix_D[LEU].push_back(2953.1262521615645);
+    5611             : 
+    5612           4 :   parameter_mix_D[MET].push_back(3561.6276801191552);
+    5613           4 :   parameter_mix_D[MET].push_back(-22.19323392975885);
+    5614           4 :   parameter_mix_D[MET].push_back(-8348.33907053846);
+    5615           4 :   parameter_mix_D[MET].push_back(-3323.053272414289);
+    5616           4 :   parameter_mix_D[MET].push_back(23153.238909304255);
+    5617           4 :   parameter_mix_D[MET].push_back(-20091.960440908682);
+    5618           4 :   parameter_mix_D[MET].push_back(5518.759669687693);
+    5619             : 
+    5620           4 :   parameter_mix_D[ASN].push_back(2326.5396001192003);
+    5621           4 :   parameter_mix_D[ASN].push_back(-8.634908921289112);
+    5622           4 :   parameter_mix_D[ASN].push_back(-4057.4552636749636);
+    5623           4 :   parameter_mix_D[ASN].push_back(-1032.743130124821);
+    5624           4 :   parameter_mix_D[ASN].push_back(6957.141592429445);
+    5625           4 :   parameter_mix_D[ASN].push_back(-4808.265318722317);
+    5626           4 :   parameter_mix_D[ASN].push_back(1016.3944815533755);
+    5627             : 
+    5628           4 :   parameter_mix_D[PRO].push_back(2471.1663601191985);
+    5629           4 :   parameter_mix_D[PRO].push_back(-6.360795284260088);
+    5630           4 :   parameter_mix_D[PRO].push_back(-3825.4533158429153);
+    5631           4 :   parameter_mix_D[PRO].push_back(-728.7164844824666);
+    5632           4 :   parameter_mix_D[PRO].push_back(5195.036303827973);
+    5633           4 :   parameter_mix_D[PRO].push_back(-3183.733716480742);
+    5634           4 :   parameter_mix_D[PRO].push_back(563.2376162754107);
+    5635             : 
+    5636           4 :   parameter_mix_D[GLN].push_back(3431.669280119236);
+    5637           4 :   parameter_mix_D[GLN].push_back(-19.412747205646166);
+    5638           4 :   parameter_mix_D[GLN].push_back(-7298.017973002134);
+    5639           4 :   parameter_mix_D[GLN].push_back(-2659.3014182337706);
+    5640           4 :   parameter_mix_D[GLN].push_back(17890.76595805173);
+    5641           4 :   parameter_mix_D[GLN].push_back(-14684.603067192957);
+    5642           4 :   parameter_mix_D[GLN].push_back(3814.338335151394);
+    5643             : 
+    5644           4 :   parameter_mix_D[SER].push_back(1423.885200119192);
+    5645           4 :   parameter_mix_D[SER].push_back(-2.586428606204385);
+    5646           4 :   parameter_mix_D[SER].push_back(-1966.7369507188134);
+    5647           4 :   parameter_mix_D[SER].push_back(-289.17277383434106);
+    5648           4 :   parameter_mix_D[SER].push_back(2209.478296043199);
+    5649           4 :   parameter_mix_D[SER].push_back(-1216.1521614944);
+    5650           4 :   parameter_mix_D[SER].push_back(177.0615931546754);
+    5651             : 
+    5652           4 :   parameter_mix_D[THR].push_back(2311.2364801191825);
+    5653           4 :   parameter_mix_D[THR].push_back(-6.258071321531929);
+    5654           4 :   parameter_mix_D[THR].push_back(-3656.295629081312);
+    5655           4 :   parameter_mix_D[THR].push_back(-716.4013890357804);
+    5656           4 :   parameter_mix_D[THR].push_back(5071.656317108832);
+    5657           4 :   parameter_mix_D[THR].push_back(-3125.8076789667816);
+    5658           4 :   parameter_mix_D[THR].push_back(555.9775741081131);
+    5659             : 
+    5660           4 :   parameter_mix_D[VAL].push_back(3041.128320119224);
+    5661           4 :   parameter_mix_D[VAL].push_back(-9.314034190716423);
+    5662           4 :   parameter_mix_D[VAL].push_back(-5075.684780220629);
+    5663           4 :   parameter_mix_D[VAL].push_back(-1070.7083380665008);
+    5664           4 :   parameter_mix_D[VAL].push_back(7455.654515006894);
+    5665           4 :   parameter_mix_D[VAL].push_back(-4701.19187164774);
+    5666           4 :   parameter_mix_D[VAL].push_back(863.4906179388547);
+    5667             : 
+    5668           4 :   parameter_mix_D[ALA].push_back(1187.65300011922);
+    5669           4 :   parameter_mix_D[ALA].push_back(-1.7011187932116822);
+    5670           4 :   parameter_mix_D[ALA].push_back(-1521.0113615359212);
+    5671           4 :   parameter_mix_D[ALA].push_back(-187.93745840575576);
+    5672           4 :   parameter_mix_D[ALA].push_back(1514.6745873304449);
+    5673           4 :   parameter_mix_D[ALA].push_back(-775.3890045113897);
+    5674           4 :   parameter_mix_D[ALA].push_back(96.41428177656567);
+    5675             : 
+    5676           4 :   parameter_mix_D[GLY].push_back(581.6349001192067);
+    5677           4 :   parameter_mix_D[GLY].push_back(-0.5877833598361395);
+    5678           4 :   parameter_mix_D[GLY].push_back(-640.0421286186524);
+    5679           4 :   parameter_mix_D[GLY].push_back(-64.58515074152534);
+    5680           4 :   parameter_mix_D[GLY].push_back(551.9509853583185);
+    5681           4 :   parameter_mix_D[GLY].push_back(-264.1522021146006);
+    5682           4 :   parameter_mix_D[GLY].push_back(28.36986478439301);
+    5683             : 
+    5684           4 :   parameter_mix_D[HIS].push_back(3648.812220119277);
+    5685           4 :   parameter_mix_D[HIS].push_back(-22.703075403555548);
+    5686           4 :   parameter_mix_D[HIS].push_back(-8260.235189881098);
+    5687           4 :   parameter_mix_D[HIS].push_back(-3190.3176569039265);
+    5688           4 :   parameter_mix_D[HIS].push_back(21589.074332364213);
+    5689           4 :   parameter_mix_D[HIS].push_back(-18108.640157613925);
+    5690           4 :   parameter_mix_D[HIS].push_back(4801.237639634437);
+    5691             : 
+    5692           4 :   parameter_vac_D[TRP].push_back(270.43802511921314);
+    5693           4 :   parameter_vac_D[TRP].push_back(-2.196022464340772);
+    5694           4 :   parameter_vac_D[TRP].push_back(-780.9546710244318);
+    5695           4 :   parameter_vac_D[TRP].push_back(-371.1573508312626);
+    5696           4 :   parameter_vac_D[TRP].push_back(2668.7678731652445);
+    5697           4 :   parameter_vac_D[TRP].push_back(-2478.2920954223678);
+    5698           4 :   parameter_vac_D[TRP].push_back(722.3731624901676);
+    5699             : 
+    5700           4 :   parameter_vac_D[TYR].push_back(198.471744119211);
+    5701           4 :   parameter_vac_D[TYR].push_back(-1.236792846228289);
+    5702           4 :   parameter_vac_D[TYR].push_back(-508.0448711054671);
+    5703           4 :   parameter_vac_D[TYR].push_back(-210.55908129481216);
+    5704           4 :   parameter_vac_D[TYR].push_back(1558.3884734212413);
+    5705           4 :   parameter_vac_D[TYR].push_back(-1418.36319255665);
+    5706           4 :   parameter_vac_D[TYR].push_back(407.21567613893296);
+    5707             : 
+    5708           4 :   parameter_vac_D[PHE].push_back(182.46606411921402);
+    5709           4 :   parameter_vac_D[PHE].push_back(-1.2708008333861447);
+    5710           4 :   parameter_vac_D[PHE].push_back(-424.50905926426054);
+    5711           4 :   parameter_vac_D[PHE].push_back(-177.97207825696387);
+    5712           4 :   parameter_vac_D[PHE].push_back(1180.839971941918);
+    5713           4 :   parameter_vac_D[PHE].push_back(-1004.004765231886);
+    5714           4 :   parameter_vac_D[PHE].push_back(269.34384064610344);
+    5715             : 
+    5716           4 :   parameter_vac_D[HIP].push_back(161.95107611920753);
+    5717           4 :   parameter_vac_D[HIP].push_back(-0.9661246983835707);
+    5718           4 :   parameter_vac_D[HIP].push_back(-332.04673226423995);
+    5719           4 :   parameter_vac_D[HIP].push_back(-125.41755194926544);
+    5720           4 :   parameter_vac_D[HIP].push_back(808.705672166199);
+    5721           4 :   parameter_vac_D[HIP].push_back(-648.8340711218191);
+    5722           4 :   parameter_vac_D[HIP].push_back(163.71251277400307);
+    5723             : 
+    5724           4 :   parameter_vac_D[ARG].push_back(289.0340011192071);
+    5725           4 :   parameter_vac_D[ARG].push_back(-1.4195753436279361);
+    5726           4 :   parameter_vac_D[ARG].push_back(-836.3864005546434);
+    5727           4 :   parameter_vac_D[ARG].push_back(-346.7081039129904);
+    5728           4 :   parameter_vac_D[ARG].push_back(2922.003491580559);
+    5729           4 :   parameter_vac_D[ARG].push_back(-2864.816533173085);
+    5730           4 :   parameter_vac_D[ARG].push_back(877.9525045072293);
+    5731             : 
+    5732           4 :   parameter_vac_D[LYS].push_back(228.64464111920753);
+    5733           4 :   parameter_vac_D[LYS].push_back(-1.686580749083617);
+    5734           4 :   parameter_vac_D[LYS].push_back(-544.8870548339771);
+    5735           4 :   parameter_vac_D[LYS].push_back(-252.11087773186324);
+    5736           4 :   parameter_vac_D[LYS].push_back(1693.784850493428);
+    5737           4 :   parameter_vac_D[LYS].push_back(-1514.2375008160348);
+    5738           4 :   parameter_vac_D[LYS].push_back(427.0713155512121);
+    5739             : 
+    5740           4 :   parameter_vac_D[CYS].push_back(50.836900116324315);
+    5741           4 :   parameter_vac_D[CYS].push_back(-0.040204572899665315);
+    5742           4 :   parameter_vac_D[CYS].push_back(-55.592868149339424);
+    5743           4 :   parameter_vac_D[CYS].push_back(-4.341359624977117);
+    5744           4 :   parameter_vac_D[CYS].push_back(41.55290573185214);
+    5745           4 :   parameter_vac_D[CYS].push_back(-17.248208429078456);
+    5746           4 :   parameter_vac_D[CYS].push_back(1.0736187172140528);
+    5747             : 
+    5748           4 :   parameter_vac_D[ASP].push_back(64.12806411920792);
+    5749           4 :   parameter_vac_D[ASP].push_back(-0.08245818875074411);
+    5750           4 :   parameter_vac_D[ASP].push_back(-78.95500211069523);
+    5751           4 :   parameter_vac_D[ASP].push_back(-9.030157332821238);
+    5752           4 :   parameter_vac_D[ASP].push_back(74.72033164806712);
+    5753           4 :   parameter_vac_D[ASP].push_back(-36.71042192737952);
+    5754           4 :   parameter_vac_D[ASP].push_back(4.0989206257493676);
+    5755             : 
+    5756           4 :   parameter_vac_D[GLU].push_back(100.14004911920799);
+    5757           4 :   parameter_vac_D[GLU].push_back(-0.28685123265362006);
+    5758           4 :   parameter_vac_D[GLU].push_back(-152.44619103423773);
+    5759           4 :   parameter_vac_D[GLU].push_back(-32.99432901288321);
+    5760           4 :   parameter_vac_D[GLU].push_back(225.5853175183811);
+    5761           4 :   parameter_vac_D[GLU].push_back(-144.8489352831419);
+    5762           4 :   parameter_vac_D[GLU].push_back(27.49692658880534);
+    5763             : 
+    5764           4 :   parameter_vac_D[ILE].push_back(165.04540911921134);
+    5765           4 :   parameter_vac_D[ILE].push_back(-0.5061553029227089);
+    5766           4 :   parameter_vac_D[ILE].push_back(-275.1890586090823);
+    5767           4 :   parameter_vac_D[ILE].push_back(-57.288063177375356);
+    5768           4 :   parameter_vac_D[ILE].push_back(398.9780357099449);
+    5769           4 :   parameter_vac_D[ILE].push_back(-245.42678814428692);
+    5770           4 :   parameter_vac_D[ILE].push_back(42.72941025472001);
+    5771             : 
+    5772           4 :   parameter_vac_D[LEU].push_back(165.04540911921134);
+    5773           4 :   parameter_vac_D[LEU].push_back(-0.580034983510499);
+    5774           4 :   parameter_vac_D[LEU].push_back(-281.30910057877514);
+    5775           4 :   parameter_vac_D[LEU].push_back(-66.19427345166183);
+    5776           4 :   parameter_vac_D[LEU].push_back(445.19214155995115);
+    5777           4 :   parameter_vac_D[LEU].push_back(-287.0653610399624);
+    5778           4 :   parameter_vac_D[LEU].push_back(53.86626261066706);
+    5779             : 
+    5780           4 :   parameter_vac_D[MET].push_back(123.83238411920684);
+    5781           4 :   parameter_vac_D[MET].push_back(-0.7698672022751385);
+    5782           4 :   parameter_vac_D[MET].push_back(-251.2481622173618);
+    5783           4 :   parameter_vac_D[MET].push_back(-100.67742019193848);
+    5784           4 :   parameter_vac_D[MET].push_back(641.1563254731632);
+    5785           4 :   parameter_vac_D[MET].push_back(-524.8742634212379);
+    5786           4 :   parameter_vac_D[MET].push_back(135.36487813767542);
+    5787             : 
+    5788           4 :   parameter_vac_D[ASN].push_back(94.12880411921148);
+    5789           4 :   parameter_vac_D[ASN].push_back(-0.22986194121078912);
+    5790           4 :   parameter_vac_D[ASN].push_back(-138.78769705028003);
+    5791           4 :   parameter_vac_D[ASN].push_back(-25.896846049402594);
+    5792           4 :   parameter_vac_D[ASN].push_back(184.55609781654326);
+    5793           4 :   parameter_vac_D[ASN].push_back(-110.14043851975404);
+    5794           4 :   parameter_vac_D[ASN].push_back(18.388834098004153);
+    5795             : 
+    5796           4 :   parameter_vac_D[PRO].push_back(90.51619611920745);
+    5797           4 :   parameter_vac_D[PRO].push_back(-0.0977238494110807);
+    5798           4 :   parameter_vac_D[PRO].push_back(-109.43531311067846);
+    5799           4 :   parameter_vac_D[PRO].push_back(-10.592981104983805);
+    5800           4 :   parameter_vac_D[PRO].push_back(93.64863466237733);
+    5801           4 :   parameter_vac_D[PRO].push_back(-42.348197720920865);
+    5802           4 :   parameter_vac_D[PRO].push_back(3.5854078482704574);
+    5803             : 
+    5804           4 :   parameter_vac_D[GLN].push_back(136.91340111920806);
+    5805           4 :   parameter_vac_D[GLN].push_back(-0.7259026842220699);
+    5806           4 :   parameter_vac_D[GLN].push_back(-257.0347011897067);
+    5807           4 :   parameter_vac_D[GLN].push_back(-89.99600255417684);
+    5808           4 :   parameter_vac_D[GLN].push_back(570.3890595917421);
+    5809           4 :   parameter_vac_D[GLN].push_back(-438.8977029769549);
+    5810           4 :   parameter_vac_D[GLN].push_back(105.48846039376491);
+    5811             : 
+    5812           4 :   parameter_vac_D[SER].push_back(55.20490011583253);
+    5813           4 :   parameter_vac_D[SER].push_back(-0.038078030710377984);
+    5814           4 :   parameter_vac_D[SER].push_back(-58.79085960838952);
+    5815           4 :   parameter_vac_D[SER].push_back(-4.067364063406562);
+    5816           4 :   parameter_vac_D[SER].push_back(41.319899403658475);
+    5817           4 :   parameter_vac_D[SER].push_back(-15.865682241288962);
+    5818           4 :   parameter_vac_D[SER].push_back(0.5028409006168431);
+    5819             : 
+    5820           4 :   parameter_vac_D[THR].push_back(88.90604111920842);
+    5821           4 :   parameter_vac_D[THR].push_back(-0.11566717587697625);
+    5822           4 :   parameter_vac_D[THR].push_back(-114.4541243837681);
+    5823           4 :   parameter_vac_D[THR].push_back(-12.541537413808342);
+    5824           4 :   parameter_vac_D[THR].push_back(106.4974738790947);
+    5825           4 :   parameter_vac_D[THR].push_back(-50.15009912825225);
+    5826           4 :   parameter_vac_D[THR].push_back(4.719349514074467);
+    5827             : 
+    5828           4 :   parameter_vac_D[VAL].push_back(117.67910411920792);
+    5829           4 :   parameter_vac_D[VAL].push_back(-0.18187311248567883);
+    5830           4 :   parameter_vac_D[VAL].push_back(-162.8697844894754);
+    5831           4 :   parameter_vac_D[VAL].push_back(-19.769248288711825);
+    5832           4 :   parameter_vac_D[VAL].push_back(162.59270939168965);
+    5833           4 :   parameter_vac_D[VAL].push_back(-79.37261506441627);
+    5834           4 :   parameter_vac_D[VAL].push_back(8.230771959393175);
+    5835             : 
+    5836           4 :   parameter_vac_D[ALA].push_back(46.92250011448002);
+    5837           4 :   parameter_vac_D[ALA].push_back(-0.020339064649444412);
+    5838           4 :   parameter_vac_D[ALA].push_back(-44.41584945233503);
+    5839           4 :   parameter_vac_D[ALA].push_back(-2.1483754537886113);
+    5840           4 :   parameter_vac_D[ALA].push_back(25.713667829058785);
+    5841           4 :   parameter_vac_D[ALA].push_back(-8.222782061575268);
+    5842           4 :   parameter_vac_D[ALA].push_back(-0.2521732728817875);
+    5843             : 
+    5844           4 :   parameter_vac_D[GLY].push_back(23.532201119209795);
+    5845           4 :   parameter_vac_D[GLY].push_back(-0.00628609590047614);
+    5846           4 :   parameter_vac_D[GLY].push_back(-17.28421910139733);
+    5847           4 :   parameter_vac_D[GLY].push_back(-0.6641226821159686);
+    5848           4 :   parameter_vac_D[GLY].push_back(8.536119110048007);
+    5849           4 :   parameter_vac_D[GLY].push_back(-2.5438638688361466);
+    5850           4 :   parameter_vac_D[GLY].push_back(-0.11165675928832643);
+    5851             : 
+    5852           4 :   parameter_vac_D[HIS].push_back(145.41948111920982);
+    5853           4 :   parameter_vac_D[HIS].push_back(-0.8548328183368781);
+    5854           4 :   parameter_vac_D[HIS].push_back(-290.8653238004162);
+    5855           4 :   parameter_vac_D[HIS].push_back(-107.85375269366395);
+    5856           4 :   parameter_vac_D[HIS].push_back(685.7025818759361);
+    5857           4 :   parameter_vac_D[HIS].push_back(-538.2592043545858);
+    5858           4 :   parameter_vac_D[HIS].push_back(132.17357375729733);
+    5859             : 
+    5860             :   // NUCLEIC ACIDS
+    5861             : 
+    5862           4 :   parameter_mix_D[BB_PO2].push_back(80.12660011920252);
+    5863           4 :   parameter_mix_D[BB_PO2].push_back(-0.02788855519820236);
+    5864           4 :   parameter_mix_D[BB_PO2].push_back(-60.53219491822279);
+    5865           4 :   parameter_mix_D[BB_PO2].push_back(-2.9768829034096806);
+    5866           4 :   parameter_mix_D[BB_PO2].push_back(33.30645116638123);
+    5867           4 :   parameter_mix_D[BB_PO2].push_back(-11.601573219761375);
+    5868           4 :   parameter_mix_D[BB_PO2].push_back(0.12551046492022438);
+    5869             : 
+    5870           4 :   parameter_mix_D[BB_DNA].push_back(2835.3195201193003);
+    5871           4 :   parameter_mix_D[BB_DNA].push_back(-7.954301723608173);
+    5872           4 :   parameter_mix_D[BB_DNA].push_back(-4509.325563460958);
+    5873           4 :   parameter_mix_D[BB_DNA].push_back(-909.1870692311344);
+    5874           4 :   parameter_mix_D[BB_DNA].push_back(6375.156903893768);
+    5875           4 :   parameter_mix_D[BB_DNA].push_back(-3956.4787847570715);
+    5876           4 :   parameter_mix_D[BB_DNA].push_back(708.9872879613656);
+    5877             : 
+    5878           4 :   parameter_mix_D[BB_DNA_5].push_back(3136.73358011921);
+    5879           4 :   parameter_mix_D[BB_DNA_5].push_back(-10.023435855160427);
+    5880           4 :   parameter_mix_D[BB_DNA_5].push_back(-5208.921666368173);
+    5881           4 :   parameter_mix_D[BB_DNA_5].push_back(-1160.4403539440214);
+    5882           4 :   parameter_mix_D[BB_DNA_5].push_back(7962.598421448727);
+    5883           4 :   parameter_mix_D[BB_DNA_5].push_back(-5149.059857691847);
+    5884           4 :   parameter_mix_D[BB_DNA_5].push_back(984.5217027570121);
+    5885             : 
+    5886           4 :   parameter_mix_D[BB_DNA_3].push_back(3136.73358011921);
+    5887           4 :   parameter_mix_D[BB_DNA_3].push_back(-9.618834865806274);
+    5888           4 :   parameter_mix_D[BB_DNA_3].push_back(-5164.249220443828);
+    5889           4 :   parameter_mix_D[BB_DNA_3].push_back(-1103.2721475326382);
+    5890           4 :   parameter_mix_D[BB_DNA_3].push_back(7633.46089052312);
+    5891           4 :   parameter_mix_D[BB_DNA_3].push_back(-4826.171688395644);
+    5892           4 :   parameter_mix_D[BB_DNA_3].push_back(888.1820863683546);
+    5893             : 
+    5894           4 :   parameter_mix_D[BB_RNA].push_back(3192.5955601188807);
+    5895           4 :   parameter_mix_D[BB_RNA].push_back(-11.475781582628308);
+    5896           4 :   parameter_mix_D[BB_RNA].push_back(-5486.264576931735);
+    5897           4 :   parameter_mix_D[BB_RNA].push_back(-1344.2878288415961);
+    5898           4 :   parameter_mix_D[BB_RNA].push_back(9035.26109892441);
+    5899           4 :   parameter_mix_D[BB_RNA].push_back(-6068.471909763036);
+    5900           4 :   parameter_mix_D[BB_RNA].push_back(1226.3696076463866);
+    5901             : 
+    5902           4 :   parameter_mix_D[BB_RNA_5].push_back(3512.1630401192215);
+    5903           4 :   parameter_mix_D[BB_RNA_5].push_back(-14.191020069433975);
+    5904           4 :   parameter_mix_D[BB_RNA_5].push_back(-6293.687102187508);
+    5905           4 :   parameter_mix_D[BB_RNA_5].push_back(-1689.3688494490984);
+    5906           4 :   parameter_mix_D[BB_RNA_5].push_back(11193.448566821942);
+    5907           4 :   parameter_mix_D[BB_RNA_5].push_back(-7806.9064399949375);
+    5908           4 :   parameter_mix_D[BB_RNA_5].push_back(1662.4594983069844);
+    5909             : 
+    5910           4 :   parameter_mix_D[BB_RNA_3].push_back(3512.1630401192215);
+    5911           4 :   parameter_mix_D[BB_RNA_3].push_back(-12.978118135595812);
+    5912           4 :   parameter_mix_D[BB_RNA_3].push_back(-6149.290195451877);
+    5913           4 :   parameter_mix_D[BB_RNA_3].push_back(-1515.8309761505627);
+    5914           4 :   parameter_mix_D[BB_RNA_3].push_back(10176.605450440278);
+    5915           4 :   parameter_mix_D[BB_RNA_3].push_back(-6813.250569884159);
+    5916           4 :   parameter_mix_D[BB_RNA_3].push_back(1366.823518955858);
+    5917             : 
+    5918           4 :   parameter_mix_D[BASE_A].push_back(2464.736500119229);
+    5919           4 :   parameter_mix_D[BASE_A].push_back(-12.127452038444783);
+    5920           4 :   parameter_mix_D[BASE_A].push_back(-4710.661256689607);
+    5921           4 :   parameter_mix_D[BASE_A].push_back(-1462.6964141954452);
+    5922           4 :   parameter_mix_D[BASE_A].push_back(9451.725575888277);
+    5923           4 :   parameter_mix_D[BASE_A].push_back(-6883.018479948857);
+    5924           4 :   parameter_mix_D[BASE_A].push_back(1540.1526599737797);
+    5925             : 
+    5926           4 :   parameter_mix_D[BASE_C].push_back(1797.2697601191685);
+    5927           4 :   parameter_mix_D[BASE_C].push_back(-5.963855532295215);
+    5928           4 :   parameter_mix_D[BASE_C].push_back(-2955.077717756034);
+    5929           4 :   parameter_mix_D[BASE_C].push_back(-689.4543508746372);
+    5930           4 :   parameter_mix_D[BASE_C].push_back(4665.914740532565);
+    5931           4 :   parameter_mix_D[BASE_C].push_back(-3051.4605913706982);
+    5932           4 :   parameter_mix_D[BASE_C].push_back(590.2201952719585);
+    5933             : 
+    5934           4 :   parameter_mix_D[BASE_G].push_back(2804.271480119049);
+    5935           4 :   parameter_mix_D[BASE_G].push_back(-16.928072935469974);
+    5936           4 :   parameter_mix_D[BASE_G].push_back(-5989.82519987899);
+    5937           4 :   parameter_mix_D[BASE_G].push_back(-2275.490326521775);
+    5938           4 :   parameter_mix_D[BASE_G].push_back(15007.832401865428);
+    5939           4 :   parameter_mix_D[BASE_G].push_back(-12287.520690325606);
+    5940           4 :   parameter_mix_D[BASE_G].push_back(3172.98306575258);
+    5941             : 
+    5942           4 :   parameter_mix_D[BASE_T].push_back(2545.0860001192113);
+    5943           4 :   parameter_mix_D[BASE_T].push_back(-10.975141620541738);
+    5944           4 :   parameter_mix_D[BASE_T].push_back(-4636.058358764447);
+    5945           4 :   parameter_mix_D[BASE_T].push_back(-1340.3746388296138);
+    5946           4 :   parameter_mix_D[BASE_T].push_back(8850.604320505428);
+    5947           4 :   parameter_mix_D[BASE_T].push_back(-6421.852532013674);
+    5948           4 :   parameter_mix_D[BASE_T].push_back(1443.371517335904);
+    5949             : 
+    5950           4 :   parameter_mix_D[BASE_U].push_back(1608.7389001192062);
+    5951           4 :   parameter_mix_D[BASE_U].push_back(-3.9816849036181434);
+    5952           4 :   parameter_mix_D[BASE_U].push_back(-2411.056432130769);
+    5953           4 :   parameter_mix_D[BASE_U].push_back(-451.8236361945487);
+    5954           4 :   parameter_mix_D[BASE_U].push_back(3220.4418252803644);
+    5955           4 :   parameter_mix_D[BASE_U].push_back(-1944.2515577994325);
+    5956           4 :   parameter_mix_D[BASE_U].push_back(332.9259542628691);
+    5957             : 
+    5958           4 :   parameter_vac_D[BB_PO2].push_back(2.7889001116093284);
+    5959           4 :   parameter_vac_D[BB_PO2].push_back(-0.00011178884266113128);
+    5960           4 :   parameter_vac_D[BB_PO2].push_back(-1.1702605818380654);
+    5961           4 :   parameter_vac_D[BB_PO2].push_back(-0.011278044036819927);
+    5962           4 :   parameter_vac_D[BB_PO2].push_back(0.3214006584089024);
+    5963           4 :   parameter_vac_D[BB_PO2].push_back(-0.04097165983591666);
+    5964           4 :   parameter_vac_D[BB_PO2].push_back(-0.017525098100539684);
+    5965             : 
+    5966           4 :   parameter_vac_D[BB_DNA].push_back(94.75075611920529);
+    5967           4 :   parameter_vac_D[BB_DNA].push_back(-0.13973533952241124);
+    5968           4 :   parameter_vac_D[BB_DNA].push_back(-123.45402430039046);
+    5969           4 :   parameter_vac_D[BB_DNA].push_back(-15.19494522082691);
+    5970           4 :   parameter_vac_D[BB_DNA].push_back(123.34749914811465);
+    5971           4 :   parameter_vac_D[BB_DNA].push_back(-61.038507985345504);
+    5972           4 :   parameter_vac_D[BB_DNA].push_back(6.601587478585944);
+    5973             : 
+    5974           4 :   parameter_vac_D[BB_DNA_5].push_back(108.18080111920679);
+    5975           4 :   parameter_vac_D[BB_DNA_5].push_back(-0.2055953690887981);
+    5976           4 :   parameter_vac_D[BB_DNA_5].push_back(-150.7924892157235);
+    5977           4 :   parameter_vac_D[BB_DNA_5].push_back(-22.700459516383198);
+    5978           4 :   parameter_vac_D[BB_DNA_5].push_back(172.2599851655527);
+    5979           4 :   parameter_vac_D[BB_DNA_5].push_back(-93.4983124807692);
+    5980           4 :   parameter_vac_D[BB_DNA_5].push_back(12.867661230942868);
+    5981             : 
+    5982           4 :   parameter_vac_D[BB_DNA_3].push_back(108.18080111920537);
+    5983           4 :   parameter_vac_D[BB_DNA_3].push_back(-0.18263717534168372);
+    5984           4 :   parameter_vac_D[BB_DNA_3].push_back(-148.5918817744255);
+    5985           4 :   parameter_vac_D[BB_DNA_3].push_back(-19.90799847398835);
+    5986           4 :   parameter_vac_D[BB_DNA_3].push_back(157.55184203379557);
+    5987           4 :   parameter_vac_D[BB_DNA_3].push_back(-80.28471270058103);
+    5988           4 :   parameter_vac_D[BB_DNA_3].push_back(9.313712500298278);
+    5989             : 
+    5990           4 :   parameter_vac_D[BB_RNA].push_back(106.37859611922117);
+    5991           4 :   parameter_vac_D[BB_RNA].push_back(-0.2380766148121975);
+    5992           4 :   parameter_vac_D[BB_RNA].push_back(-153.74131338570024);
+    5993           4 :   parameter_vac_D[BB_RNA].push_back(-26.415436217574932);
+    5994           4 :   parameter_vac_D[BB_RNA].push_back(191.90585451112776);
+    5995           4 :   parameter_vac_D[BB_RNA].push_back(-109.61737794316868);
+    5996           4 :   parameter_vac_D[BB_RNA].push_back(16.663804191332204);
+    5997             : 
+    5998           4 :   parameter_vac_D[BB_RNA_5].push_back(120.58236111920618);
+    5999           4 :   parameter_vac_D[BB_RNA_5].push_back(-0.340258533619014);
+    6000           4 :   parameter_vac_D[BB_RNA_5].push_back(-186.08333929996334);
+    6001           4 :   parameter_vac_D[BB_RNA_5].push_back(-38.493337147644795);
+    6002           4 :   parameter_vac_D[BB_RNA_5].push_back(266.2262415641144);
+    6003           4 :   parameter_vac_D[BB_RNA_5].push_back(-164.73088478359585);
+    6004           4 :   parameter_vac_D[BB_RNA_5].push_back(29.07014157680879);
+    6005             : 
+    6006           4 :   parameter_vac_D[BB_RNA_3].push_back(120.5823611192099);
+    6007           4 :   parameter_vac_D[BB_RNA_3].push_back(-0.274146129206928);
+    6008           4 :   parameter_vac_D[BB_RNA_3].push_back(-179.24499182395388);
+    6009           4 :   parameter_vac_D[BB_RNA_3].push_back(-30.315729372259426);
+    6010           4 :   parameter_vac_D[BB_RNA_3].push_back(222.2645581367648);
+    6011           4 :   parameter_vac_D[BB_RNA_3].push_back(-125.13581171514033);
+    6012           4 :   parameter_vac_D[BB_RNA_3].push_back(18.350308154920107);
+    6013             : 
+    6014           4 :   parameter_vac_D[BASE_A].push_back(114.34024911921);
+    6015           4 :   parameter_vac_D[BASE_A].push_back(-0.4136665918383359);
+    6016           4 :   parameter_vac_D[BASE_A].push_back(-192.33138384655922);
+    6017           4 :   parameter_vac_D[BASE_A].push_back(-46.74428306691412);
+    6018           4 :   parameter_vac_D[BASE_A].push_back(312.9511030981905);
+    6019           4 :   parameter_vac_D[BASE_A].push_back(-199.6349962647333);
+    6020           4 :   parameter_vac_D[BASE_A].push_back(36.15938693202153);
+    6021             : 
+    6022           4 :   parameter_vac_D[BASE_C].push_back(76.17798411921166);
+    6023           4 :   parameter_vac_D[BASE_C].push_back(-0.1444475142707445);
+    6024           4 :   parameter_vac_D[BASE_C].push_back(-102.66873668949485);
+    6025           4 :   parameter_vac_D[BASE_C].push_back(-15.813768367725821);
+    6026           4 :   parameter_vac_D[BASE_C].push_back(119.63436338715553);
+    6027           4 :   parameter_vac_D[BASE_C].push_back(-64.22251971660583);
+    6028           4 :   parameter_vac_D[BASE_C].push_back(8.351952332828862);
+    6029             : 
+    6030           4 :   parameter_vac_D[BASE_G].push_back(127.08052911921965);
+    6031           4 :   parameter_vac_D[BASE_G].push_back(-0.7137457014712297);
+    6032           4 :   parameter_vac_D[BASE_G].push_back(-239.67686838772786);
+    6033           4 :   parameter_vac_D[BASE_G].push_back(-88.53661981200943);
+    6034           4 :   parameter_vac_D[BASE_G].push_back(556.7254485453866);
+    6035           4 :   parameter_vac_D[BASE_G].push_back(-432.0234649577737);
+    6036           4 :   parameter_vac_D[BASE_G].push_back(104.407200463848);
+    6037             : 
+    6038           4 :   parameter_vac_D[BASE_T].push_back(94.09000011920868);
+    6039           4 :   parameter_vac_D[BASE_T].push_back(-0.27147149980458524);
+    6040           4 :   parameter_vac_D[BASE_T].push_back(-143.65649702254174);
+    6041           4 :   parameter_vac_D[BASE_T].push_back(-30.861235738371892);
+    6042           4 :   parameter_vac_D[BASE_T].push_back(212.3643014774958);
+    6043           4 :   parameter_vac_D[BASE_T].push_back(-133.06675501066275);
+    6044           4 :   parameter_vac_D[BASE_T].push_back(23.951588200687073);
+    6045             : 
+    6046           4 :   parameter_vac_D[BASE_U].push_back(59.30540111665979);
+    6047           4 :   parameter_vac_D[BASE_U].push_back(-0.06146929846591808);
+    6048           4 :   parameter_vac_D[BASE_U].push_back(-67.43680950211682);
+    6049           4 :   parameter_vac_D[BASE_U].push_back(-6.625289749170134);
+    6050           4 :   parameter_vac_D[BASE_U].push_back(58.37012229348065);
+    6051           4 :   parameter_vac_D[BASE_U].push_back(-26.23044613101723);
+    6052           4 :   parameter_vac_D[BASE_U].push_back(2.061238351422343);
+    6053             : 
+    6054       14298 :   for(unsigned i=0; i<atoms.size(); ++i) {
+    6055       14294 :     std::string Aname = pdb.getAtomName(atoms[i]);
+    6056       14294 :     std::string Rname = pdb.getResidueName(atoms[i]);
+    6057       14294 :     Rname.erase(std::remove_if(Rname.begin(), Rname.end(), ::isspace),Rname.end());
+    6058       14294 :     if(Rname=="ALA") {
+    6059         732 :       atoi[residue_atom[i]]=ALA;
+    6060       13562 :     } else if(Rname=="ARG") {
+    6061         864 :       atoi[residue_atom[i]]=ARG;
+    6062       12698 :     } else if(Rname=="ASN") {
+    6063         720 :       atoi[residue_atom[i]]=ASN;
+    6064       11978 :     } else if(Rname=="ASP") {
+    6065         624 :       atoi[residue_atom[i]]=ASP;
+    6066       11354 :     } else if(Rname=="CYS") {
+    6067          48 :       atoi[residue_atom[i]]=CYS;
+    6068       11306 :     } else if(Rname=="GLN") {
+    6069        1064 :       atoi[residue_atom[i]]=GLN;
+    6070       10242 :     } else if(Rname=="GLU") {
+    6071         476 :       atoi[residue_atom[i]]=GLU;
+    6072        9766 :     } else if(Rname=="GLY") {
+    6073         648 :       atoi[residue_atom[i]]=GLY;
+    6074        9118 :     } else if(Rname=="HIS") {
+    6075           0 :       atoi[residue_atom[i]]=HIS;
+    6076        9118 :     } else if(Rname=="HID") {
+    6077           0 :       atoi[residue_atom[i]]=HIS;
+    6078        9118 :     } else if(Rname=="HIE") {
+    6079         144 :       atoi[residue_atom[i]]=HIS;
+    6080        8974 :     } else if(Rname=="HIP") {
+    6081           0 :       atoi[residue_atom[i]]=HIP;
+    6082             :       // CHARMM NAMING FOR PROTONATION STATES OF HISTIDINE
+    6083        8974 :     } else if(Rname=="HSD") {
+    6084           0 :       atoi[residue_atom[i]]=HIS;
+    6085        8974 :     } else if(Rname=="HSE") {
+    6086           0 :       atoi[residue_atom[i]]=HIS;
+    6087        8974 :     } else if(Rname=="HSP") {
+    6088           0 :       atoi[residue_atom[i]]=HIP;
+    6089        8974 :     } else if(Rname=="ILE") {
+    6090         864 :       atoi[residue_atom[i]]=ILE;
+    6091        8110 :     } else if(Rname=="LEU") {
+    6092        1520 :       atoi[residue_atom[i]]=LEU;
+    6093        6590 :     } else if(Rname=="LYS") {
+    6094        1040 :       atoi[residue_atom[i]]=LYS;
+    6095        5550 :     } else if(Rname=="MET") {
+    6096         608 :       atoi[residue_atom[i]]=MET;
+    6097        4942 :     } else if(Rname=="PHE") {
+    6098        1008 :       atoi[residue_atom[i]]=PHE;
+    6099        3934 :     } else if(Rname=="PRO") {
+    6100         748 :       atoi[residue_atom[i]]=PRO;
+    6101        3186 :     } else if(Rname=="SER") {
+    6102         528 :       atoi[residue_atom[i]]=SER;
+    6103        2658 :     } else if(Rname=="THR") {
+    6104         504 :       atoi[residue_atom[i]]=THR;
+    6105        2154 :     } else if(Rname=="TRP") {
+    6106           0 :       atoi[residue_atom[i]]=TRP;
+    6107        2154 :     } else if(Rname=="TYR") {
+    6108         528 :       atoi[residue_atom[i]]=TYR;
+    6109        1626 :     } else if(Rname=="VAL") {
+    6110        1088 :       atoi[residue_atom[i]]=VAL;
+    6111             :     }
+    6112             :     // NUCLEIC ACIDS
+    6113             :     // nucleobases are not automatically populated as an additional check on the health of the PDB.
+    6114             :     // RNA - G
+    6115         538 :     else if(Rname=="G") {
+    6116           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    6117           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    6118           0 :         atoi [residue_atom[i]]=BB_PO2;
+    6119           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    6120           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    6121           0 :                 Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    6122           0 :                 Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="H3T"  ||
+    6123           0 :                 Aname=="HO5'" || Aname=="HO3'" || Aname=="HO2'" || Aname=="H5'1" ||
+    6124           0 :                 Aname=="H5'2" || Aname=="HO'2" || Aname=="H2'1" || Aname=="H5T" ) {
+    6125           0 :         atoi[residue_atom[i]]=BB_RNA;
+    6126           0 :       } else if( Aname=="N1" || Aname=="C2"  || Aname=="N2" || Aname=="N3" ||
+    6127           0 :                  Aname=="C4" || Aname=="C5"  || Aname=="C6" || Aname=="O6" ||
+    6128           0 :                  Aname=="N7" || Aname=="C8"  || Aname=="N9" || Aname=="H1" ||
+    6129           0 :                  Aname=="H8" || Aname=="H21" || Aname=="H22" ) {
+    6130           0 :         atoi[residue_atom[i]]=BASE_G;
+    6131           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6132             :       // RNA - G3
+    6133         538 :     } else if(Rname=="G3") {
+    6134           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    6135           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    6136           0 :         atoi [residue_atom[i]]=BB_PO2;
+    6137           0 :       } else if(Aname=="O5'"  || Aname=="C5'" || Aname=="O4'"  || Aname=="C4'"  ||
+    6138           0 :                 Aname=="O3'"  || Aname=="C3'" || Aname=="O2'"  || Aname=="C2'"  ||
+    6139           0 :                 Aname=="C1'"  || Aname=="H5'" || Aname=="H5''" || Aname=="H4'"  ||
+    6140           0 :                 Aname=="H3'"  || Aname=="H2'" || Aname=="H1'"  || Aname=="H3T"  ||
+    6141           0 :                 Aname=="H2'1" || Aname=="HO3'"|| Aname=="HO2'" || Aname=="H5'1" ||
+    6142           0 :                 Aname=="H5'2" || Aname=="HO'2" ) {
+    6143           0 :         atoi[residue_atom[i]]=BB_RNA_3;
+    6144           0 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="N2" || Aname=="N3" ||
+    6145           0 :                 Aname=="C4" || Aname=="C5"  || Aname=="C6" || Aname=="O6" ||
+    6146           0 :                 Aname=="N7" || Aname=="C8"  || Aname=="N9" || Aname=="H1" ||
+    6147           0 :                 Aname=="H8" || Aname=="H21" || Aname=="H22" ) {
+    6148           0 :         atoi[residue_atom[i]]=BASE_G;
+    6149           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6150             :       // RNA - G5
+    6151         538 :     } else if(Rname=="G5") {
+    6152           0 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    6153           0 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    6154           0 :           Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    6155           0 :           Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="HO5'" ||
+    6156           0 :           Aname=="HO2'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="HO'2" ||
+    6157           0 :           Aname=="H2'1" || Aname=="H5T" ) {
+    6158           0 :         atoi[residue_atom[i]]=BB_RNA_5;
+    6159           0 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="N2" || Aname=="N3" ||
+    6160           0 :                 Aname=="C4" || Aname=="C5"  || Aname=="C6" || Aname=="O6" ||
+    6161           0 :                 Aname=="N7" || Aname=="C8"  || Aname=="N9" || Aname=="H1" ||
+    6162           0 :                 Aname=="H8" || Aname=="H21" || Aname=="H22" ) {
+    6163           0 :         atoi[residue_atom[i]]=BASE_G;
+    6164           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6165             :       // RNA - U
+    6166         538 :     } else if(Rname=="U") {
+    6167        1554 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    6168        1176 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    6169          42 :         atoi [residue_atom[i]]=BB_PO2;
+    6170        1372 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    6171        1148 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    6172         924 :                 Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    6173         714 :                 Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="H3T"  ||
+    6174         644 :                 Aname=="HO5'" || Aname=="HO3'" || Aname=="HO2'" || Aname=="H5'1" ||
+    6175         840 :                 Aname=="H5'2" || Aname=="HO'2" || Aname=="H2'1" || Aname=="H5T" ) {
+    6176         224 :         atoi[residue_atom[i]]=BB_RNA;
+    6177         476 :       } else if( Aname=="N1" || Aname=="C2"  || Aname=="O2" || Aname=="N3" ||
+    6178         252 :                  Aname=="C4" || Aname=="O4"  || Aname=="C5" || Aname=="C6" ||
+    6179         196 :                  Aname=="H3" || Aname=="H5"  || Aname=="H6") {
+    6180         154 :         atoi[residue_atom[i]]=BASE_U;
+    6181           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6182             :       // RNA - U3
+    6183         118 :     } else if(Rname=="U3") {
+    6184         230 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    6185         174 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    6186           6 :         atoi [residue_atom[i]]=BB_PO2;
+    6187         204 :       } else if(Aname=="O5'"  || Aname=="C5'" || Aname=="O4'"  || Aname=="C4'"  ||
+    6188         172 :                 Aname=="O3'"  || Aname=="C3'" || Aname=="O2'"  || Aname=="C2'"  ||
+    6189         140 :                 Aname=="C1'"  || Aname=="H5'" || Aname=="H5''" || Aname=="H4'"  ||
+    6190         110 :                 Aname=="H3'"  || Aname=="H2'" || Aname=="H1'"  || Aname=="H3T"  ||
+    6191          94 :                 Aname=="H2'1" || Aname=="HO3'"|| Aname=="HO2'" || Aname=="H5'1" ||
+    6192          78 :                 Aname=="H5'2" || Aname=="HO'2" ) {
+    6193          34 :         atoi[residue_atom[i]]=BB_RNA_3;
+    6194          68 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="O2" || Aname=="N3" ||
+    6195          36 :                 Aname=="C4" || Aname=="O4"  || Aname=="C5" || Aname=="C6" ||
+    6196          28 :                 Aname=="H3" || Aname=="H5"  || Aname=="H6") {
+    6197          22 :         atoi[residue_atom[i]]=BASE_U;
+    6198           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6199             :       // RNA - U5
+    6200          56 :     } else if(Rname=="U5") {
+    6201         204 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    6202         172 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    6203         140 :           Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    6204         108 :           Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="HO5'" ||
+    6205          88 :           Aname=="HO2'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="HO'2" ||
+    6206          78 :           Aname=="H2'1" || Aname=="H5T" ) {
+    6207          34 :         atoi[residue_atom[i]]=BB_RNA_5;
+    6208          68 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="O2" || Aname=="N3" ||
+    6209          36 :                 Aname=="C4" || Aname=="O4"  || Aname=="C5" || Aname=="C6" ||
+    6210          28 :                 Aname=="H3" || Aname=="H5"  || Aname=="H6") {
+    6211          22 :         atoi[residue_atom[i]]=BASE_U;
+    6212           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6213             :       // RNA - A
+    6214           0 :     } else if(Rname=="A") {
+    6215           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    6216           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    6217           0 :         atoi [residue_atom[i]]=BB_PO2;
+    6218           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    6219           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    6220           0 :                 Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    6221           0 :                 Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="H3T"  ||
+    6222           0 :                 Aname=="HO5'" || Aname=="HO3'" || Aname=="HO2'" || Aname=="H5'1" ||
+    6223           0 :                 Aname=="H5'2" || Aname=="HO'2" || Aname=="H2'1" || Aname=="H5T" ) {
+    6224           0 :         atoi[residue_atom[i]]=BB_RNA;
+    6225           0 :       } else if(Aname=="N1"  || Aname=="C2" || Aname=="N3" || Aname=="C4" ||
+    6226           0 :                 Aname=="C5"  || Aname=="C6" || Aname=="N6" || Aname=="N7" ||
+    6227           0 :                 Aname=="C8"  || Aname=="N9" || Aname=="H2" || Aname=="H8" ||
+    6228           0 :                 Aname=="H61" || Aname=="H62" ) {
+    6229           0 :         atoi[residue_atom[i]]=BASE_A;
+    6230           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6231             :       // RNA - A3
+    6232           0 :     } else if(Rname=="A3") {
+    6233           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    6234           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    6235           0 :         atoi [residue_atom[i]]=BB_PO2;
+    6236           0 :       } else if(Aname=="O5'"  || Aname=="C5'" || Aname=="O4'"  || Aname=="C4'"  ||
+    6237           0 :                 Aname=="O3'"  || Aname=="C3'" || Aname=="O2'"  || Aname=="C2'"  ||
+    6238           0 :                 Aname=="C1'"  || Aname=="H5'" || Aname=="H5''" || Aname=="H4'"  ||
+    6239           0 :                 Aname=="H3'"  || Aname=="H2'" || Aname=="H1'"  || Aname=="H3T"  ||
+    6240           0 :                 Aname=="H2'1" || Aname=="HO3'"|| Aname=="HO2'" || Aname=="H5'1" ||
+    6241           0 :                 Aname=="H5'2" || Aname=="HO'2" ) {
+    6242           0 :         atoi[residue_atom[i]]=BB_RNA_3;
+    6243           0 :       } else if(Aname=="N1"  || Aname=="C2" || Aname=="N3" || Aname=="C4" ||
+    6244           0 :                 Aname=="C5"  || Aname=="C6" || Aname=="N6" || Aname=="N7" ||
+    6245           0 :                 Aname=="C8"  || Aname=="N9" || Aname=="H2" || Aname=="H8" ||
+    6246           0 :                 Aname=="H61" || Aname=="H62" ) {
+    6247           0 :         atoi[residue_atom[i]]=BASE_A;
+    6248           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6249             :       // RNA - A5
+    6250           0 :     } else if(Rname=="A5") {
+    6251           0 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    6252           0 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    6253           0 :           Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    6254           0 :           Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="HO5'" ||
+    6255           0 :           Aname=="HO2'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="HO'2" ||
+    6256           0 :           Aname=="H2'1" || Aname=="H5T" ) {
+    6257           0 :         atoi[residue_atom[i]]=BB_RNA_5;
+    6258           0 :       } else if(Aname=="N1"  || Aname=="C2" || Aname=="N3" || Aname=="C4" ||
+    6259           0 :                 Aname=="C5"  || Aname=="C6" || Aname=="N6" || Aname=="N7" ||
+    6260           0 :                 Aname=="C8"  || Aname=="N9" || Aname=="H2" || Aname=="H8" ||
+    6261           0 :                 Aname=="H61" || Aname=="H62" ) {
+    6262           0 :         atoi[residue_atom[i]]=BASE_A;
+    6263           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6264             :       // RNA - C
+    6265           0 :     } else if(Rname=="C") {
+    6266           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    6267           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    6268           0 :         atoi [residue_atom[i]]=BB_PO2;
+    6269           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    6270           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    6271           0 :                 Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    6272           0 :                 Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="H3T"  ||
+    6273           0 :                 Aname=="HO5'" || Aname=="HO3'" || Aname=="HO2'" || Aname=="H5'1" ||
+    6274           0 :                 Aname=="H5'2" || Aname=="HO'2" || Aname=="H2'1" || Aname=="H5T" ) {
+    6275           0 :         atoi[residue_atom[i]]=BB_RNA;
+    6276           0 :       } else if(Aname=="N1" || Aname=="C2" || Aname=="O2"  || Aname=="N3" ||
+    6277           0 :                 Aname=="C4" || Aname=="N4" || Aname=="C5"  || Aname=="C6" ||
+    6278           0 :                 Aname=="H5" || Aname=="H6" || Aname=="H41" || Aname=="H42" ) {
+    6279           0 :         atoi[residue_atom[i]]=BASE_C;
+    6280           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6281             :       // RNA - C3
+    6282           0 :     } else if(Rname=="C3") {
+    6283           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    6284           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    6285           0 :         atoi [residue_atom[i]]=BB_PO2;
+    6286           0 :       } else if(Aname=="O5'"  || Aname=="C5'" || Aname=="O4'"  || Aname=="C4'"  ||
+    6287           0 :                 Aname=="O3'"  || Aname=="C3'" || Aname=="O2'"  || Aname=="C2'"  ||
+    6288           0 :                 Aname=="C1'"  || Aname=="H5'" || Aname=="H5''" || Aname=="H4'"  ||
+    6289           0 :                 Aname=="H3'"  || Aname=="H2'" || Aname=="H1'"  || Aname=="H3T"  ||
+    6290           0 :                 Aname=="H2'1" || Aname=="HO3'"|| Aname=="HO2'" || Aname=="H5'1" ||
+    6291           0 :                 Aname=="H5'2" || Aname=="HO'2" ) {
+    6292           0 :         atoi[residue_atom[i]]=BB_RNA_3;
+    6293           0 :       } else if(Aname=="N1" || Aname=="C2" || Aname=="O2"  || Aname=="N3" ||
+    6294           0 :                 Aname=="C4" || Aname=="N4" || Aname=="C5"  || Aname=="C6" ||
+    6295           0 :                 Aname=="H5" || Aname=="H6" || Aname=="H41" || Aname=="H42" ) {
+    6296           0 :         atoi[residue_atom[i]]=BASE_C;
+    6297           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6298             :       // RNA - C5
+    6299           0 :     } else if(Rname=="C5") {
+    6300           0 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    6301           0 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    6302           0 :           Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    6303           0 :           Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="HO5'" ||
+    6304           0 :           Aname=="HO2'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="HO'2" ||
+    6305           0 :           Aname=="H2'1" || Aname=="H5T" ) {
+    6306           0 :         atoi[residue_atom[i]]=BB_RNA_5;
+    6307           0 :       } else if(Aname=="N1" || Aname=="C2" || Aname=="O2"  || Aname=="N3" ||
+    6308           0 :                 Aname=="C4" || Aname=="N4" || Aname=="C5"  || Aname=="C6" ||
+    6309           0 :                 Aname=="H5" || Aname=="H6" || Aname=="H41" || Aname=="H42" ) {
+    6310           0 :         atoi[residue_atom[i]]=BASE_C;
+    6311           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6312             :       // DNA - G
+    6313           0 :     } else if(Rname=="DG") {
+    6314           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    6315           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    6316           0 :         atoi [residue_atom[i]]=BB_PO2;
+    6317           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    6318           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    6319           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    6320           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    6321           0 :                 Aname=="HO3'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" ||
+    6322           0 :                 Aname=="H2'2" || Aname=="H5T"  || Aname=="H3T" ) {
+    6323           0 :         atoi[residue_atom[i]]=BB_DNA;
+    6324           0 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="N2" || Aname=="N3" ||
+    6325           0 :                 Aname=="C4" || Aname=="C5"  || Aname=="C6" || Aname=="O6" ||
+    6326           0 :                 Aname=="N7" || Aname=="C8"  || Aname=="N9" || Aname=="H1" ||
+    6327           0 :                 Aname=="H8" || Aname=="H21" || Aname=="H22" ) {
+    6328           0 :         atoi[residue_atom[i]]=BASE_G;
+    6329           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6330             :       // DNA - G3
+    6331           0 :     } else if(Rname=="DG3") {
+    6332           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    6333           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    6334           0 :         atoi [residue_atom[i]]=BB_PO2;
+    6335           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    6336           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    6337           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    6338           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO3'" ||
+    6339           0 :                 Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    6340             :                 Aname=="H3T" ) {
+    6341           0 :         atoi[residue_atom[i]]=BB_DNA_3;
+    6342           0 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="N2" || Aname=="N3" ||
+    6343           0 :                 Aname=="C4" || Aname=="C5"  || Aname=="C6" || Aname=="O6" ||
+    6344           0 :                 Aname=="N7" || Aname=="C8"  || Aname=="N9" || Aname=="H1" ||
+    6345           0 :                 Aname=="H8" || Aname=="H21" || Aname=="H22" ) {
+    6346           0 :         atoi[residue_atom[i]]=BASE_G;
+    6347           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6348             :       // DNA - G5
+    6349           0 :     } else if(Rname=="DG5") {
+    6350           0 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    6351           0 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  ||  Aname=="C1'" ||
+    6352           0 :           Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    6353           0 :           Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    6354           0 :           Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    6355             :           Aname=="H5T" ) {
+    6356           0 :         atoi[residue_atom[i]]=BB_DNA_5;
+    6357           0 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="N2" || Aname=="N3" ||
+    6358           0 :                 Aname=="C4" || Aname=="C5"  || Aname=="C6" || Aname=="O6" ||
+    6359           0 :                 Aname=="N7" || Aname=="C8"  || Aname=="N9" || Aname=="H1" ||
+    6360           0 :                 Aname=="H8" || Aname=="H21" || Aname=="H22" ) {
+    6361           0 :         atoi[residue_atom[i]]=BASE_G;
+    6362           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6363             :       // DNA - T
+    6364           0 :     } else if(Rname=="DT") {
+    6365           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    6366           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    6367           0 :         atoi [residue_atom[i]]=BB_PO2;
+    6368           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    6369           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    6370           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    6371           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    6372           0 :                 Aname=="HO3'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" ||
+    6373           0 :                 Aname=="H2'2" || Aname=="H5T"  || Aname=="H3T" ) {
+    6374           0 :         atoi[residue_atom[i]]=BB_DNA;
+    6375           0 :       } else if(Aname=="N1"  || Aname=="C2"  || Aname=="O2"  || Aname=="N3"  ||
+    6376           0 :                 Aname=="C4"  || Aname=="O4"  || Aname=="C5"  || Aname=="C6"  ||
+    6377           0 :                 Aname=="C7"  || Aname=="H3"  || Aname=="H6"  || Aname=="H71" ||
+    6378           0 :                 Aname=="H72" || Aname=="H73" ) {
+    6379           0 :         atoi[residue_atom[i]]=BASE_T;
+    6380           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6381             :       // DNA - T3
+    6382           0 :     } else if(Rname=="DT3") {
+    6383           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    6384           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    6385           0 :         atoi [residue_atom[i]]=BB_PO2;
+    6386           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    6387           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    6388           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    6389           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO3'" ||
+    6390           0 :                 Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    6391             :                 Aname=="H3T" ) {
+    6392           0 :         atoi[residue_atom[i]]=BB_DNA_3;
+    6393           0 :       } else if(Aname=="N1"  || Aname=="C2"  || Aname=="O2"  || Aname=="N3"  ||
+    6394           0 :                 Aname=="C4"  || Aname=="O4"  || Aname=="C5"  || Aname=="C6"  ||
+    6395           0 :                 Aname=="C7"  || Aname=="H3"  || Aname=="H6"  || Aname=="H71" ||
+    6396           0 :                 Aname=="H72" || Aname=="H73" ) {
+    6397           0 :         atoi[residue_atom[i]]=BASE_T;
+    6398           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6399             :       // DNA - T5
+    6400           0 :     } else if(Rname=="DT5") {
+    6401           0 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    6402           0 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  ||  Aname=="C1'" ||
+    6403           0 :           Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    6404           0 :           Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    6405           0 :           Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    6406             :           Aname=="H5T" ) {
+    6407           0 :         atoi[residue_atom[i]]=BB_DNA_5;
+    6408           0 :       } else if(Aname=="N1"  || Aname=="C2"  || Aname=="O2"  || Aname=="N3"  ||
+    6409           0 :                 Aname=="C4"  || Aname=="O4"  || Aname=="C5"  || Aname=="C6"  ||
+    6410           0 :                 Aname=="C7"  || Aname=="H3"  || Aname=="H6"  || Aname=="H71" ||
+    6411           0 :                 Aname=="H72" || Aname=="H73" ) {
+    6412           0 :         atoi[residue_atom[i]]=BASE_T;
+    6413           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6414             :       // DNA - A
+    6415           0 :     } else if(Rname=="DA") {
+    6416           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    6417           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    6418           0 :         atoi [residue_atom[i]]=BB_PO2;
+    6419           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    6420           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    6421           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    6422           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    6423           0 :                 Aname=="HO3'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" ||
+    6424           0 :                 Aname=="H2'2" || Aname=="H5T"  || Aname=="H3T" ) {
+    6425           0 :         atoi[residue_atom[i]]=BB_DNA;
+    6426           0 :       } else if(Aname=="N1"  || Aname=="C2" || Aname=="N3" || Aname=="C4" ||
+    6427           0 :                 Aname=="C5"  || Aname=="C6" || Aname=="N6" || Aname=="N7" ||
+    6428           0 :                 Aname=="C8"  || Aname=="N9" || Aname=="H2" || Aname=="H8" ||
+    6429           0 :                 Aname=="H61" || Aname=="H62" ) {
+    6430           0 :         atoi[residue_atom[i]]=BASE_A;
+    6431           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6432             :       // DNA - A3
+    6433           0 :     } else if(Rname=="DA3") {
+    6434           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    6435           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    6436           0 :         atoi [residue_atom[i]]=BB_PO2;
+    6437           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    6438           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    6439           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    6440           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO3'" ||
+    6441           0 :                 Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    6442             :                 Aname=="H3T" ) {
+    6443           0 :         atoi[residue_atom[i]]=BB_DNA_3;
+    6444           0 :       } else if(Aname=="N1"  || Aname=="C2" || Aname=="N3" || Aname=="C4" ||
+    6445           0 :                 Aname=="C5"  || Aname=="C6" || Aname=="N6" || Aname=="N7" ||
+    6446           0 :                 Aname=="C8"  || Aname=="N9" || Aname=="H2" || Aname=="H8" ||
+    6447           0 :                 Aname=="H61" || Aname=="H62" ) {
+    6448           0 :         atoi[residue_atom[i]]=BASE_A;
+    6449           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6450             :       // DNA - A5
+    6451           0 :     } else if(Rname=="DA5") {
+    6452           0 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    6453           0 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  ||  Aname=="C1'" ||
+    6454           0 :           Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    6455           0 :           Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    6456           0 :           Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    6457             :           Aname=="H5T" ) {
+    6458           0 :         atoi[residue_atom[i]]=BB_DNA_5;
+    6459           0 :       } else if(Aname=="N1"  || Aname=="C2" || Aname=="N3" || Aname=="C4" ||
+    6460           0 :                 Aname=="C5"  || Aname=="C6" || Aname=="N6" || Aname=="N7" ||
+    6461           0 :                 Aname=="C8"  || Aname=="N9" || Aname=="H2" || Aname=="H8" ||
+    6462           0 :                 Aname=="H61" || Aname=="H62" ) {
+    6463           0 :         atoi[residue_atom[i]]=BASE_A;
+    6464           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6465             :       // DNA - C
+    6466           0 :     } else if(Rname=="DC") {
+    6467           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    6468           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    6469           0 :         atoi [residue_atom[i]]=BB_PO2;
+    6470           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    6471           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    6472           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    6473           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    6474           0 :                 Aname=="HO3'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" ||
+    6475           0 :                 Aname=="H2'2" || Aname=="H5T"  || Aname=="H3T" ) {
+    6476           0 :         atoi[residue_atom[i]]=BB_DNA;
+    6477           0 :       } else if(Aname=="N1" || Aname=="C2" || Aname=="O2"  || Aname=="N3" ||
+    6478           0 :                 Aname=="C4" || Aname=="N4" || Aname=="C5"  || Aname=="C6" ||
+    6479           0 :                 Aname=="H5" || Aname=="H6" || Aname=="H41" || Aname=="H42" ) {
+    6480           0 :         atoi[residue_atom[i]]=BASE_C;
+    6481           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6482             :       // DNA - C3
+    6483           0 :     } else if(Rname=="DC3") {
+    6484           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    6485           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    6486           0 :         atoi [residue_atom[i]]=BB_PO2;
+    6487           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    6488           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    6489           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    6490           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO3'" ||
+    6491           0 :                 Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    6492             :                 Aname=="H3T" ) {
+    6493           0 :         atoi[residue_atom[i]]=BB_DNA_3;
+    6494           0 :       } else if(Aname=="N1" || Aname=="C2" || Aname=="O2"  || Aname=="N3" ||
+    6495           0 :                 Aname=="C4" || Aname=="N4" || Aname=="C5"  || Aname=="C6" ||
+    6496           0 :                 Aname=="H5" || Aname=="H6" || Aname=="H41" || Aname=="H42" ) {
+    6497           0 :         atoi[residue_atom[i]]=BASE_C;
+    6498           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6499             :       // DNA - C5
+    6500           0 :     } else if(Rname=="DC5") {
+    6501           0 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    6502           0 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  ||  Aname=="C1'" ||
+    6503           0 :           Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    6504           0 :           Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    6505           0 :           Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    6506             :           Aname=="H5T" ) {
+    6507           0 :         atoi[residue_atom[i]]=BB_DNA_5;
+    6508           0 :       } else if(Aname=="N1" || Aname=="C2" || Aname=="O2"  || Aname=="N3" ||
+    6509           0 :                 Aname=="C4" || Aname=="N4" || Aname=="C5"  || Aname=="C6" ||
+    6510           0 :                 Aname=="H5" || Aname=="H6" || Aname=="H41" || Aname=="H42" ) {
+    6511           0 :         atoi[residue_atom[i]]=BASE_C;
+    6512           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6513           0 :     } else error("Residue not known: "+Rname);
+    6514             :   }
+    6515           4 : }
+    6516             : 
+    6517           4 : double SAXS::calculateAFF(const std::vector<AtomNumber> &atoms, std::vector<std::vector<long double> > &FF_tmp, const double rho)
+    6518             : {
+    6519             :   std::map<std::string, unsigned> AA_map;
+    6520           4 :   AA_map["H"] = H;
+    6521           4 :   AA_map["C"] = C;
+    6522           4 :   AA_map["N"] = N;
+    6523           4 :   AA_map["O"] = O;
+    6524           4 :   AA_map["P"] = P;
+    6525           4 :   AA_map["S"] = S;
+    6526             : 
+    6527             :   std::vector<std::vector<double> > param_a;
+    6528             :   std::vector<std::vector<double> > param_b;
+    6529             :   std::vector<double> param_c;
+    6530             :   std::vector<double> param_v;
+    6531             : 
+    6532           4 :   param_a.resize(NTT, std::vector<double>(5));
+    6533           4 :   param_b.resize(NTT, std::vector<double>(5));
+    6534           4 :   param_c.resize(NTT);
+    6535           4 :   param_v.resize(NTT);
+    6536             : 
+    6537           4 :   param_a[H][0] = 0.493002; param_b[H][0] = 10.5109; param_c[H] = 0.003038;
+    6538           4 :   param_a[H][1] = 0.322912; param_b[H][1] = 26.1257; param_v[H] = 5.15;
+    6539           4 :   param_a[H][2] = 0.140191; param_b[H][2] = 3.14236;
+    6540           4 :   param_a[H][3] = 0.040810; param_b[H][3] = 57.7997;
+    6541           4 :   param_a[H][4] = 0.0;      param_b[H][4] = 1.0;
+    6542             : 
+    6543           4 :   param_a[C][0] = 2.31000; param_b[C][0] = 20.8439; param_c[C] = 0.215600;
+    6544           4 :   param_a[C][1] = 1.02000; param_b[C][1] = 10.2075; param_v[C] = 16.44;
+    6545           4 :   param_a[C][2] = 1.58860; param_b[C][2] = 0.56870;
+    6546           4 :   param_a[C][3] = 0.86500; param_b[C][3] = 51.6512;
+    6547           4 :   param_a[C][4] = 0.0;     param_b[C][4] = 1.0;
+    6548             : 
+    6549           4 :   param_a[N][0] = 12.2126; param_b[N][0] = 0.00570; param_c[N] = -11.529;
+    6550           4 :   param_a[N][1] = 3.13220; param_b[N][1] = 9.89330; param_v[N] = 2.49;
+    6551           4 :   param_a[N][2] = 2.01250; param_b[N][2] = 28.9975;
+    6552           4 :   param_a[N][3] = 1.16630; param_b[N][3] = 0.58260;
+    6553           4 :   param_a[N][4] = 0.0;     param_b[N][4] = 1.0;
+    6554             : 
+    6555           4 :   param_a[O][0] = 3.04850; param_b[O][0] = 13.2771; param_c[O] = 0.250800 ;
+    6556           4 :   param_a[O][1] = 2.28680; param_b[O][1] = 5.70110; param_v[O] = 9.13;
+    6557           4 :   param_a[O][2] = 1.54630; param_b[O][2] = 0.32390;
+    6558           4 :   param_a[O][3] = 0.86700; param_b[O][3] = 32.9089;
+    6559           4 :   param_a[O][4] = 0.0;     param_b[O][4] = 1.0;
+    6560             : 
+    6561           4 :   param_a[P][0] = 6.43450; param_b[P][0] = 1.90670; param_c[P] = 1.11490;
+    6562           4 :   param_a[P][1] = 4.17910; param_b[P][1] = 27.1570; param_v[P] = 5.73;
+    6563           4 :   param_a[P][2] = 1.78000; param_b[P][2] = 0.52600;
+    6564           4 :   param_a[P][3] = 1.49080; param_b[P][3] = 68.1645;
+    6565           4 :   param_a[P][4] = 0.0;     param_b[P][4] = 1.0;
+    6566             : 
+    6567           4 :   param_a[S][0] = 6.90530; param_b[S][0] = 1.46790; param_c[S] = 0.866900;
+    6568           4 :   param_a[S][1] = 5.20340; param_b[S][1] = 22.2151; param_v[S] = 19.86;
+    6569           4 :   param_a[S][2] = 1.43790; param_b[S][2] = 0.25360;
+    6570           4 :   param_a[S][3] = 1.58630; param_b[S][3] = 56.1720;
+    6571           4 :   param_a[S][4] = 0.0;     param_b[S][4] = 1.0;
+    6572             : 
+    6573           4 :   auto* moldat=plumed.getActionSet().selectLatest<GenericMolInfo*>(this);
+    6574             : 
+    6575             :   double Iq0=0.;
+    6576           4 :   if( moldat ) {
+    6577             :     // cycle over the atom types
+    6578          28 :     for(unsigned i=0; i<NTT; ++i) {
+    6579          24 :       const double volr = std::pow(param_v[i], (2.0/3.0)) /(4. * M_PI);
+    6580             :       // cycle over q
+    6581         240 :       for(unsigned k=0; k<q_list.size(); ++k) {
+    6582         216 :         const double q = q_list[k];
+    6583         216 :         const double s = q / (4. * M_PI);
+    6584         216 :         FF_tmp[k][i] = param_c[i];
+    6585             :         // SUM [a_i * EXP( - b_i * (q/4pi)^2 )] Waasmaier and Kirfel (1995)
+    6586        1080 :         for(unsigned j=0; j<4; ++j) {
+    6587         864 :           FF_tmp[k][i] += param_a[i][j]*std::exp(-param_b[i][j]*s*s);
+    6588             :         }
+    6589             :         // subtract solvation: rho * v_i * EXP( (- v_i^(2/3) / (4pi)) * q^2  ) // since  D in Fraser 1978 is 2*s
+    6590         216 :         FF_tmp[k][i] -= rho*param_v[i]*std::exp(-volr*q*q);
+    6591             :       }
+    6592             :     }
+    6593             :     // cycle over the atoms to assign the atom type and calculate I0
+    6594       14298 :     for(unsigned i=0; i<atoms.size(); ++i) {
+    6595             :       // get atom name
+    6596       14294 :       std::string name = moldat->getAtomName(atoms[i]);
+    6597             :       char type;
+    6598             :       // get atom type
+    6599       14294 :       char first = name.at(0);
+    6600             :       // GOLDEN RULE: type is first letter, if not a number
+    6601       14294 :       if (!isdigit(first)) {
+    6602             :         type = first;
+    6603             :         // otherwise is the second
+    6604             :       } else {
+    6605           0 :         type = name.at(1);
+    6606             :       }
+    6607       14294 :       std::string type_s = std::string(1,type);
+    6608       14294 :       if(AA_map.find(type_s) != AA_map.end()) {
+    6609       14294 :         const unsigned index=AA_map[type_s];
+    6610       14294 :         atoi[i] = AA_map[type_s];
+    6611       71470 :         for(unsigned j=0; j<4; ++j) Iq0 += param_a[index][j];
+    6612       14294 :         Iq0 = Iq0 -rho*param_v[index] + param_c[index];
+    6613             :       } else {
+    6614           0 :         error("Wrong atom type "+type_s+" from atom name "+name+"\n");
+    6615             :       }
+    6616             :     }
+    6617             :   } else {
+    6618           0 :     error("MOLINFO DATA not found\n");
+    6619             :   }
+    6620           4 :   if(absolute) Iq0 = 1;
+    6621             : 
+    6622           4 :   return Iq0;
+    6623           4 : }
+    6624             : 
+    6625           2 : double SAXS::calculateAFFsans(const std::vector<AtomNumber> &atoms, std::vector<std::vector<long double> > &FF_tmp, const double deuter_conc)
+    6626             : {
+    6627             :   std::map<std::string, unsigned> AA_map;
+    6628           2 :   AA_map["H"] = H;
+    6629           2 :   AA_map["C"] = C;
+    6630           2 :   AA_map["N"] = N;
+    6631           2 :   AA_map["O"] = O;
+    6632           2 :   AA_map["P"] = P;
+    6633           2 :   AA_map["S"] = S;
+    6634             : 
+    6635             :   std::vector<double> param_b;
+    6636             :   std::vector<double> param_v;
+    6637             : 
+    6638           2 :   param_b.resize(NTT);
+    6639           2 :   param_v.resize(NTT);
+    6640             : 
+    6641           2 :   param_b[H] = -0.374; param_v[H] = 5.15;
+    6642             :   // param_b[D] = 0.667;
+    6643           2 :   param_b[C] =  0.665;  param_v[C] = 16.44;
+    6644           2 :   param_b[N] =  0.94;   param_v[N] = 2.49;
+    6645           2 :   param_b[O] =  0.580;  param_v[O] = 9.13;
+    6646           2 :   param_b[P] =  0.51;   param_v[P] = 5.73;
+    6647           2 :   param_b[S] =  0.28;   param_v[S] = 19.86;
+    6648             : 
+    6649           2 :   double solv_sc_length = 0.1*(param_b[O] + 2.*((1. - deuter_conc) * param_b[H] + deuter_conc * 0.667)); // per water electron (10 electrons)
+    6650             : 
+    6651           2 :   auto* moldat=plumed.getActionSet().selectLatest<GenericMolInfo*>(this);
+    6652             : 
+    6653             :   double Iq0=0.;
+    6654           2 :   if( moldat ) {
+    6655             :     // cycle over the atom types
+    6656          14 :     for(unsigned i=0; i<NTT; ++i) {
+    6657          12 :       double volr = std::pow(param_v[i], (2.0/3.0)) /(4. * M_PI);
+    6658             :       // cycle over q
+    6659         120 :       for(unsigned k=0; k<q_list.size(); ++k) {
+    6660         108 :         const double q = q_list[k];
+    6661         108 :         FF_tmp[k][i] = param_b[i];
+    6662             :         // subtract solvation: rho * v_i * EXP( (- v_i^(2/3) / (4pi)) * q^2  ) // since  D in Fraser 1978 is 2*s
+    6663         108 :         FF_tmp[k][i] -= solv_sc_length*rho*param_v[i]*std::exp(-volr*q*q);
+    6664             :       }
+    6665             :     }
+    6666             :     // cycle over the atoms to assign the atom type and calculate I0
+    6667        6880 :     for(unsigned i=0; i<atoms.size(); ++i) {
+    6668             :       // get atom name
+    6669        6878 :       std::string name = moldat->getAtomName(atoms[i]);
+    6670             :       char type;
+    6671             :       // get atom type
+    6672        6878 :       char first = name.at(0);
+    6673             :       // GOLDEN RULE: type is first letter, if not a number
+    6674        6878 :       if (!isdigit(first)) {
+    6675             :         type = first;
+    6676             :         // otherwise is the second
+    6677             :       } else {
+    6678           0 :         type = name.at(1);
+    6679             :       }
+    6680        6878 :       std::string type_s = std::string(1,type);
+    6681        6878 :       if(AA_map.find(type_s) != AA_map.end()) {
+    6682        6878 :         const unsigned index=AA_map[type_s];
+    6683        6878 :         atoi[i] = AA_map[type_s];
+    6684        6878 :         Iq0 += param_b[index]-solv_sc_length*rho*param_v[index];
+    6685             :       } else {
+    6686           0 :         error("Wrong atom type "+type_s+" from atom name "+name+"\n");
+    6687             :       }
+    6688             :     }
+    6689             :   } else {
+    6690           0 :     error("MOLINFO DATA not found\n");
+    6691             :   }
+    6692           2 :   if(absolute) Iq0 = 1;
+    6693             : 
+    6694           2 :   return Iq0;
+    6695             : }
+    6696             : 
+    6697          10 : std::map<std::string, std::vector<double> > SAXS::setupLCPOparam() {
+    6698             :   std::map<std::string, std::vector<double> > lcpomap;
+    6699             : 
+    6700             :   // We arbitrarily set OC1/OT1 as the charged oxygen.
+    6701             : 
+    6702          10 :   lcpomap["ALA_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6703          10 :   lcpomap["ALA_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    6704          10 :   lcpomap["ALA_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6705          10 :   lcpomap["ALA_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6706          10 :   lcpomap["ALA_CB"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+    6707          10 :   lcpomap["ALA_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6708          10 :   lcpomap["ALA_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6709          10 :   lcpomap["ALA_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6710          10 :   lcpomap["ALA_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6711          10 :   lcpomap["ALA_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6712             : 
+    6713          10 :   lcpomap["ASP_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6714          10 :   lcpomap["ASP_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    6715          10 :   lcpomap["ASP_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6716          10 :   lcpomap["ASP_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6717          10 :   lcpomap["ASP_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6718          10 :   lcpomap["ASP_CG"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6719          10 :   lcpomap["ASP_OD1"] = { 1.6,  0.77914,  -0.25262,  -0.0016056,  0.00035071};
+    6720          10 :   lcpomap["ASP_OD2"] = { 1.6,  0.77914,  -0.25262,  -0.0016056,  0.00035071};
+    6721          10 :   lcpomap["ASP_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6722          10 :   lcpomap["ASP_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6723          10 :   lcpomap["ASP_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6724          10 :   lcpomap["ASP_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6725          10 :   lcpomap["ASP_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6726             : 
+    6727          10 :   lcpomap["ASN_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6728          10 :   lcpomap["ASN_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    6729          10 :   lcpomap["ASN_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6730          10 :   lcpomap["ASN_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6731          10 :   lcpomap["ASN_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6732          10 :   lcpomap["ASN_CG"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6733          10 :   lcpomap["ASN_OD1"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6734          10 :   lcpomap["ASN_ND2"] = { 1.65,  0.73511,  -0.22116,  -0.00089148,  0.0002523};
+    6735          10 :   lcpomap["ASN_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6736          10 :   lcpomap["ASN_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6737          10 :   lcpomap["ASN_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6738          10 :   lcpomap["ASN_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6739          10 :   lcpomap["ASN_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6740             : 
+    6741          10 :   lcpomap["ARG_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6742          10 :   lcpomap["ARG_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    6743          10 :   lcpomap["ARG_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6744          10 :   lcpomap["ARG_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6745          10 :   lcpomap["ARG_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6746          10 :   lcpomap["ARG_CG"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6747          10 :   lcpomap["ARG_CD"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6748          10 :   lcpomap["ARG_NE"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6749          10 :   lcpomap["ARG_NH1"] = { 1.65,  0.73511,  -0.22116,  -0.00089148,  0.0002523};
+    6750          10 :   lcpomap["ARG_NH2"] = { 1.65,  0.73511,  -0.22116,  -0.00089148,  0.0002523};
+    6751          10 :   lcpomap["ARG_CZ"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6752          10 :   lcpomap["ARG_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6753          10 :   lcpomap["ARG_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6754          10 :   lcpomap["ARG_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6755          10 :   lcpomap["ARG_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6756          10 :   lcpomap["ARG_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6757             : 
+    6758          10 :   lcpomap["CYS_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6759          10 :   lcpomap["CYS_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    6760          10 :   lcpomap["CYS_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6761          10 :   lcpomap["CYS_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6762          10 :   lcpomap["CYS_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6763          10 :   lcpomap["CYS_SG"] = { 1.9,  0.54581,  -0.19477,  -0.0012873,  0.00029247};
+    6764          10 :   lcpomap["CYS_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6765          10 :   lcpomap["CYS_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6766          10 :   lcpomap["CYS_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6767          10 :   lcpomap["CYS_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6768          10 :   lcpomap["CYS_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6769             : 
+    6770          10 :   lcpomap["GLU_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6771          10 :   lcpomap["GLU_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    6772          10 :   lcpomap["GLU_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6773          10 :   lcpomap["GLU_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6774          10 :   lcpomap["GLU_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6775          10 :   lcpomap["GLU_CG"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6776          10 :   lcpomap["GLU_CD"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6777          10 :   lcpomap["GLU_OE1"] = { 1.6,  0.77914,  -0.25262,  -0.0016056,  0.00035071};
+    6778          10 :   lcpomap["GLU_OE2"] = { 1.6,  0.77914,  -0.25262,  -0.0016056,  0.00035071};
+    6779          10 :   lcpomap["GLU_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6780          10 :   lcpomap["GLU_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6781          10 :   lcpomap["GLU_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6782          10 :   lcpomap["GLU_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6783          10 :   lcpomap["GLU_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6784             : 
+    6785          10 :   lcpomap["GLN_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6786          10 :   lcpomap["GLN_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    6787          10 :   lcpomap["GLN_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6788          10 :   lcpomap["GLN_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6789          10 :   lcpomap["GLN_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6790          10 :   lcpomap["GLN_CG"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6791          10 :   lcpomap["GLN_CD"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6792          10 :   lcpomap["GLN_OE1"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6793          10 :   lcpomap["GLN_NE2"] = { 1.65,  0.73511,  -0.22116,  -0.00089148,  0.0002523};
+    6794          10 :   lcpomap["GLN_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6795          10 :   lcpomap["GLN_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6796          10 :   lcpomap["GLN_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6797          10 :   lcpomap["GLN_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6798          10 :   lcpomap["GLN_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6799             : 
+    6800          10 :   lcpomap["GLY_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6801          10 :   lcpomap["GLY_CA"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6802          10 :   lcpomap["GLY_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6803          10 :   lcpomap["GLY_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6804          10 :   lcpomap["GLY_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6805          10 :   lcpomap["GLY_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6806          10 :   lcpomap["GLY_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6807          10 :   lcpomap["GLY_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6808          10 :   lcpomap["GLY_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6809             : 
+    6810          10 :   lcpomap["HIS_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6811          10 :   lcpomap["HIS_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    6812          10 :   lcpomap["HIS_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6813          10 :   lcpomap["HIS_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6814          10 :   lcpomap["HIS_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6815          10 :   lcpomap["HIS_CG"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6816          10 :   lcpomap["HIS_ND1"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6817          10 :   lcpomap["HIS_CE1"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    6818          10 :   lcpomap["HIS_NE2"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6819          10 :   lcpomap["HIS_CD2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    6820          10 :   lcpomap["HIS_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6821          10 :   lcpomap["HIS_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6822          10 :   lcpomap["HIS_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6823             : 
+    6824          10 :   lcpomap["HIE_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6825          10 :   lcpomap["HIE_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    6826          10 :   lcpomap["HIE_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6827          10 :   lcpomap["HIE_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6828          10 :   lcpomap["HIE_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6829          10 :   lcpomap["HIE_CG"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6830          10 :   lcpomap["HIE_ND1"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6831          10 :   lcpomap["HIE_CE1"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    6832          10 :   lcpomap["HIE_NE2"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6833          10 :   lcpomap["HIE_CD2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    6834          10 :   lcpomap["HIE_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6835          10 :   lcpomap["HIE_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6836          10 :   lcpomap["HIE_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6837             : 
+    6838          10 :   lcpomap["HSE_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6839          10 :   lcpomap["HSE_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    6840          10 :   lcpomap["HSE_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6841          10 :   lcpomap["HSE_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6842          10 :   lcpomap["HSE_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6843          10 :   lcpomap["HSE_CG"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6844          10 :   lcpomap["HSE_ND1"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6845          10 :   lcpomap["HSE_CE1"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    6846          10 :   lcpomap["HSE_NE2"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6847          10 :   lcpomap["HSE_CD2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    6848          10 :   lcpomap["HSE_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6849          10 :   lcpomap["HSE_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6850          10 :   lcpomap["HSE_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6851             : 
+    6852          10 :   lcpomap["HID_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6853          10 :   lcpomap["HID_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    6854          10 :   lcpomap["HID_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6855          10 :   lcpomap["HID_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6856          10 :   lcpomap["HID_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6857          10 :   lcpomap["HID_CG"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6858          10 :   lcpomap["HID_ND1"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6859          10 :   lcpomap["HID_CE1"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    6860          10 :   lcpomap["HID_NE2"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6861          10 :   lcpomap["HID_CD2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    6862          10 :   lcpomap["HID_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6863          10 :   lcpomap["HID_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6864          10 :   lcpomap["HID_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6865             : 
+    6866          10 :   lcpomap["HSD_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6867          10 :   lcpomap["HSD_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    6868          10 :   lcpomap["HSD_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6869          10 :   lcpomap["HSD_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6870          10 :   lcpomap["HSD_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6871          10 :   lcpomap["HSD_CG"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6872          10 :   lcpomap["HSD_ND1"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6873          10 :   lcpomap["HSD_CE1"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    6874          10 :   lcpomap["HSD_NE2"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6875          10 :   lcpomap["HSD_CD2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    6876          10 :   lcpomap["HSD_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6877          10 :   lcpomap["HSD_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6878          10 :   lcpomap["HSD_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6879             : 
+    6880          10 :   lcpomap["HIP_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6881          10 :   lcpomap["HIP_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    6882          10 :   lcpomap["HIP_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6883          10 :   lcpomap["HIP_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6884          10 :   lcpomap["HIP_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6885          10 :   lcpomap["HIP_CG"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6886          10 :   lcpomap["HIP_ND1"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6887          10 :   lcpomap["HIP_CE1"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    6888          10 :   lcpomap["HIP_NE2"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6889          10 :   lcpomap["HIP_CD2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    6890          10 :   lcpomap["HIP_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6891          10 :   lcpomap["HIP_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6892          10 :   lcpomap["HIP_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6893             : 
+    6894          10 :   lcpomap["HSP_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6895          10 :   lcpomap["HSP_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    6896          10 :   lcpomap["HSP_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6897          10 :   lcpomap["HSP_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6898          10 :   lcpomap["HSP_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6899          10 :   lcpomap["HSP_CG"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6900          10 :   lcpomap["HSP_ND1"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6901          10 :   lcpomap["HSP_CE1"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    6902          10 :   lcpomap["HSP_NE2"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6903          10 :   lcpomap["HSP_CD2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    6904          10 :   lcpomap["HSP_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6905          10 :   lcpomap["HSP_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6906          10 :   lcpomap["HSP_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6907             : 
+    6908          10 :   lcpomap["ILE_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6909          10 :   lcpomap["ILE_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    6910          10 :   lcpomap["ILE_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6911          10 :   lcpomap["ILE_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6912          10 :   lcpomap["ILE_CB"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    6913          10 :   lcpomap["ILE_CG2"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+    6914          10 :   lcpomap["ILE_CG1"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6915          10 :   lcpomap["ILE_CD1"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+    6916          10 :   lcpomap["ILE_CD"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+    6917          10 :   lcpomap["ILE_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6918          10 :   lcpomap["ILE_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6919          10 :   lcpomap["ILE_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6920          10 :   lcpomap["ILE_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6921          10 :   lcpomap["ILE_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6922             : 
+    6923          10 :   lcpomap["LEU_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6924          10 :   lcpomap["LEU_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    6925          10 :   lcpomap["LEU_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6926          10 :   lcpomap["LEU_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6927          10 :   lcpomap["LEU_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6928          10 :   lcpomap["LEU_CG"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    6929          10 :   lcpomap["LEU_CD1"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+    6930          10 :   lcpomap["LEU_CD2"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+    6931          10 :   lcpomap["LEU_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6932          10 :   lcpomap["LEU_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6933          10 :   lcpomap["LEU_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6934          10 :   lcpomap["LEU_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6935          10 :   lcpomap["LEU_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6936             : 
+    6937          10 :   lcpomap["LYS_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6938          10 :   lcpomap["LYS_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    6939          10 :   lcpomap["LYS_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6940          10 :   lcpomap["LYS_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6941          10 :   lcpomap["LYS_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6942          10 :   lcpomap["LYS_CG"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6943          10 :   lcpomap["LYS_CD"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6944          10 :   lcpomap["LYS_CE"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6945          10 :   lcpomap["LYS_NZ"] = { 1.65,  0.73511,  -0.22116,  -0.00089148,  0.0002523};
+    6946          10 :   lcpomap["LYS_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6947          10 :   lcpomap["LYS_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6948          10 :   lcpomap["LYS_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6949          10 :   lcpomap["LYS_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6950          10 :   lcpomap["LYS_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6951             : 
+    6952          10 :   lcpomap["MET_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6953          10 :   lcpomap["MET_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    6954          10 :   lcpomap["MET_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6955          10 :   lcpomap["MET_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6956          10 :   lcpomap["MET_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6957          10 :   lcpomap["MET_CG"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6958          10 :   lcpomap["MET_SD"] = { 1.9,  0.54581,  -0.19477,  -0.0012873,  0.00029247};
+    6959          10 :   lcpomap["MET_CE"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+    6960          10 :   lcpomap["MET_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6961          10 :   lcpomap["MET_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6962          10 :   lcpomap["MET_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6963          10 :   lcpomap["MET_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6964          10 :   lcpomap["MET_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6965             : 
+    6966          10 :   lcpomap["PHE_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6967          10 :   lcpomap["PHE_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    6968          10 :   lcpomap["PHE_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6969          10 :   lcpomap["PHE_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6970          10 :   lcpomap["PHE_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6971          10 :   lcpomap["PHE_CG"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6972          10 :   lcpomap["PHE_CD1"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    6973          10 :   lcpomap["PHE_CE1"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    6974          10 :   lcpomap["PHE_CZ"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    6975          10 :   lcpomap["PHE_CE2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    6976          10 :   lcpomap["PHE_CD2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    6977          10 :   lcpomap["PHE_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6978          10 :   lcpomap["PHE_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6979          10 :   lcpomap["PHE_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6980          10 :   lcpomap["PHE_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6981          10 :   lcpomap["PHE_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6982             : 
+    6983          10 :   lcpomap["PRO_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6984          10 :   lcpomap["PRO_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    6985          10 :   lcpomap["PRO_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6986          10 :   lcpomap["PRO_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6987          10 :   lcpomap["PRO_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6988          10 :   lcpomap["PRO_CG"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6989          10 :   lcpomap["PRO_CD"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6990          10 :   lcpomap["PRO_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6991          10 :   lcpomap["PRO_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6992          10 :   lcpomap["PRO_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6993          10 :   lcpomap["PRO_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6994          10 :   lcpomap["PRO_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6995             : 
+    6996          10 :   lcpomap["SER_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6997          10 :   lcpomap["SER_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    6998          10 :   lcpomap["SER_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6999          10 :   lcpomap["SER_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7000          10 :   lcpomap["SER_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    7001          10 :   lcpomap["SER_OG"] = { 1.6,  0.77914,  -0.25262,  -0.0016056,  0.00035071};
+    7002          10 :   lcpomap["SER_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7003          10 :   lcpomap["SER_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7004          10 :   lcpomap["SER_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7005          10 :   lcpomap["SER_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7006          10 :   lcpomap["SER_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7007             : 
+    7008          10 :   lcpomap["THR_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    7009          10 :   lcpomap["THR_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    7010          10 :   lcpomap["THR_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    7011          10 :   lcpomap["THR_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7012          10 :   lcpomap["THR_CB"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    7013          10 :   lcpomap["THR_CG2"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+    7014          10 :   lcpomap["THR_OG1"] = { 1.6,  0.77914,  -0.25262,  -0.0016056,  0.00035071};
+    7015          10 :   lcpomap["THR_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7016          10 :   lcpomap["THR_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7017          10 :   lcpomap["THR_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7018          10 :   lcpomap["THR_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7019          10 :   lcpomap["THR_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7020             : 
+    7021          10 :   lcpomap["TRP_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    7022          10 :   lcpomap["TRP_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    7023          10 :   lcpomap["TRP_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    7024          10 :   lcpomap["TRP_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7025          10 :   lcpomap["TRP_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    7026          10 :   lcpomap["TRP_CG"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    7027          10 :   lcpomap["TRP_CD1"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    7028          10 :   lcpomap["TRP_NE1"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    7029          10 :   lcpomap["TRP_CE2"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    7030          10 :   lcpomap["TRP_CZ2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    7031          10 :   lcpomap["TRP_CH2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    7032          10 :   lcpomap["TRP_CZ3"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    7033          10 :   lcpomap["TRP_CE3"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    7034          10 :   lcpomap["TRP_CD2"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    7035          10 :   lcpomap["TRP_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7036          10 :   lcpomap["TRP_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7037          10 :   lcpomap["TRP_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7038          10 :   lcpomap["TRP_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7039          10 :   lcpomap["TRP_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7040             : 
+    7041          10 :   lcpomap["TYR_N"] = { 1.65,  0.062577,  -0.017874,  -8.312e-05,  1.9849e-05};
+    7042          10 :   lcpomap["TYR_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    7043          10 :   lcpomap["TYR_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    7044          10 :   lcpomap["TYR_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7045          10 :   lcpomap["TYR_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    7046          10 :   lcpomap["TYR_CG"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    7047          10 :   lcpomap["TYR_CD1"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    7048          10 :   lcpomap["TYR_CE1"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    7049          10 :   lcpomap["TYR_CZ"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    7050          10 :   lcpomap["TYR_OH"] = { 1.6,  0.77914,  -0.25262,  -0.0016056,  0.00035071};
+    7051          10 :   lcpomap["TYR_CE2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    7052          10 :   lcpomap["TYR_CD2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    7053          10 :   lcpomap["TYR_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7054          10 :   lcpomap["TYR_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7055          10 :   lcpomap["TYR_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7056          10 :   lcpomap["TYR_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7057          10 :   lcpomap["TYR_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7058             : 
+    7059          10 :   lcpomap["VAL_N"] = { 1.65,  0.062577,  -0.017874,  -8.312e-05,  1.9849e-05};
+    7060          10 :   lcpomap["VAL_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    7061          10 :   lcpomap["VAL_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    7062          10 :   lcpomap["VAL_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7063          10 :   lcpomap["VAL_CB"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    7064          10 :   lcpomap["VAL_CG1"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+    7065          10 :   lcpomap["VAL_CG2"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+    7066          10 :   lcpomap["VAL_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7067          10 :   lcpomap["VAL_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7068          10 :   lcpomap["VAL_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7069          10 :   lcpomap["VAL_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7070          10 :   lcpomap["VAL_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7071             : 
+    7072             :   // nucleic acids - WARNING: ONLY AMBER (OL3-rna/ol15-dna) FORMAT
+    7073             : 
+    7074          10 :   lcpomap["A3_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7075          10 :   lcpomap["A3_C2"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7076          10 :   lcpomap["A3_C2'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7077          10 :   lcpomap["A3_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7078          10 :   lcpomap["A3_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7079          10 :   lcpomap["A3_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7080          10 :   lcpomap["A3_C5"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7081          10 :   lcpomap["A3_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7082          10 :   lcpomap["A3_C6"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7083          10 :   lcpomap["A3_C8"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7084          10 :   lcpomap["A3_N1"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7085          10 :   lcpomap["A3_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7086          10 :   lcpomap["A3_N6"]  = { 1.65,  0.73511, -0.22116, -8.9148e-04, 2.523e-04 };
+    7087          10 :   lcpomap["A3_N7"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7088          10 :   lcpomap["A3_N9"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    7089          10 :   lcpomap["A3_O2'"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7090          10 :   lcpomap["A3_O3'"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7091          10 :   lcpomap["A3_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7092          10 :   lcpomap["A3_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7093          10 :   lcpomap["A3_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7094          10 :   lcpomap["A3_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7095          10 :   lcpomap["A3_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7096          10 :   lcpomap["A3_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7097          10 :   lcpomap["A3_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7098          10 :   lcpomap["A3_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7099          10 :   lcpomap["A3_P"] = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    7100             : 
+    7101          10 :   lcpomap["A5_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7102          10 :   lcpomap["A5_C2"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7103          10 :   lcpomap["A5_C2'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7104          10 :   lcpomap["A5_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7105          10 :   lcpomap["A5_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7106          10 :   lcpomap["A5_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7107          10 :   lcpomap["A5_C5"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7108          10 :   lcpomap["A5_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7109          10 :   lcpomap["A5_C6"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7110          10 :   lcpomap["A5_C8"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7111          10 :   lcpomap["A5_N1"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7112          10 :   lcpomap["A5_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7113          10 :   lcpomap["A5_N6"]  = { 1.65,  0.73511, -0.22116, -8.9148e-04, 2.523e-04 };
+    7114          10 :   lcpomap["A5_N7"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7115          10 :   lcpomap["A5_N9"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    7116          10 :   lcpomap["A5_O2'"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7117          10 :   lcpomap["A5_O3'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7118          10 :   lcpomap["A5_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7119          10 :   lcpomap["A5_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7120          10 :   lcpomap["A5_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7121          10 :   lcpomap["A5_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7122          10 :   lcpomap["A5_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7123          10 :   lcpomap["A5_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7124          10 :   lcpomap["A5_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7125          10 :   lcpomap["A5_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7126          10 :   lcpomap["A5_P"] = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    7127             : 
+    7128          10 :   lcpomap["A_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7129          10 :   lcpomap["A_C2"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7130          10 :   lcpomap["A_C2'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7131          10 :   lcpomap["A_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7132          10 :   lcpomap["A_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7133          10 :   lcpomap["A_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7134          10 :   lcpomap["A_C5"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7135          10 :   lcpomap["A_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7136          10 :   lcpomap["A_C6"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7137          10 :   lcpomap["A_C8"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7138          10 :   lcpomap["A_N1"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7139          10 :   lcpomap["A_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7140          10 :   lcpomap["A_N6"]  = { 1.65,  0.73511, -0.22116, -8.9148e-04, 2.523e-04 };
+    7141          10 :   lcpomap["A_N7"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7142          10 :   lcpomap["A_N9"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    7143          10 :   lcpomap["A_O2'"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7144          10 :   lcpomap["A_O3'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7145          10 :   lcpomap["A_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7146          10 :   lcpomap["A_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7147          10 :   lcpomap["A_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7148          10 :   lcpomap["A_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7149          10 :   lcpomap["A_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7150          10 :   lcpomap["A_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7151          10 :   lcpomap["A_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7152          10 :   lcpomap["A_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7153          10 :   lcpomap["A_P"] = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    7154             : 
+    7155          10 :   lcpomap["C3_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7156          10 :   lcpomap["C3_C2"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7157          10 :   lcpomap["C3_C2'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7158          10 :   lcpomap["C3_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7159          10 :   lcpomap["C3_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7160          10 :   lcpomap["C3_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7161          10 :   lcpomap["C3_C5"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7162          10 :   lcpomap["C3_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7163          10 :   lcpomap["C3_C6"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7164          10 :   lcpomap["C3_N1"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    7165          10 :   lcpomap["C3_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7166          10 :   lcpomap["C3_N4"]  = { 1.65,  0.73511, -0.22116, -8.9148e-04, 2.523e-04 };
+    7167          10 :   lcpomap["C3_O2"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    7168          10 :   lcpomap["C3_O2'"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7169          10 :   lcpomap["C3_O3'"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7170          10 :   lcpomap["C3_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7171          10 :   lcpomap["C3_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7172          10 :   lcpomap["C3_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7173          10 :   lcpomap["C3_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7174          10 :   lcpomap["C3_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7175          10 :   lcpomap["C3_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7176          10 :   lcpomap["C3_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7177          10 :   lcpomap["C3_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7178          10 :   lcpomap["C3_P"] = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    7179             : 
+    7180          10 :   lcpomap["C5_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7181          10 :   lcpomap["C5_C2"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7182          10 :   lcpomap["C5_C2'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7183          10 :   lcpomap["C5_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7184          10 :   lcpomap["C5_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7185          10 :   lcpomap["C5_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7186          10 :   lcpomap["C5_C5"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7187          10 :   lcpomap["C5_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7188          10 :   lcpomap["C5_C6"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7189          10 :   lcpomap["C5_N1"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    7190          10 :   lcpomap["C5_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7191          10 :   lcpomap["C5_N4"]  = { 1.65,  0.73511, -0.22116, -8.9148e-04, 2.523e-04 };
+    7192          10 :   lcpomap["C5_O2"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    7193          10 :   lcpomap["C5_O2'"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7194          10 :   lcpomap["C5_O3'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7195          10 :   lcpomap["C5_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7196          10 :   lcpomap["C5_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7197          10 :   lcpomap["C5_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7198          10 :   lcpomap["C5_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7199          10 :   lcpomap["C5_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7200          10 :   lcpomap["C5_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7201          10 :   lcpomap["C5_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7202          10 :   lcpomap["C5_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7203          10 :   lcpomap["C5_P"] = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    7204             : 
+    7205          10 :   lcpomap["C_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7206          10 :   lcpomap["C_C2"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7207          10 :   lcpomap["C_C2'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7208          10 :   lcpomap["C_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7209          10 :   lcpomap["C_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7210          10 :   lcpomap["C_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7211          10 :   lcpomap["C_C5"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7212          10 :   lcpomap["C_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7213          10 :   lcpomap["C_C6"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7214          10 :   lcpomap["C_N1"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    7215          10 :   lcpomap["C_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7216          10 :   lcpomap["C_N4"]  = { 1.65,  0.73511, -0.22116, -8.9148e-04, 2.523e-04 };
+    7217          10 :   lcpomap["C_O2"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    7218          10 :   lcpomap["C_O2'"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7219          10 :   lcpomap["C_O3'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7220          10 :   lcpomap["C_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7221          10 :   lcpomap["C_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7222          10 :   lcpomap["C_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7223          10 :   lcpomap["C_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7224          10 :   lcpomap["C_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7225          10 :   lcpomap["C_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7226          10 :   lcpomap["C_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7227          10 :   lcpomap["C_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7228          10 :   lcpomap["C_P"] = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    7229             : 
+    7230          10 :   lcpomap["DA3_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7231          10 :   lcpomap["DA3_C2"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7232          10 :   lcpomap["DA3_C2'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7233          10 :   lcpomap["DA3_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7234          10 :   lcpomap["DA3_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7235          10 :   lcpomap["DA3_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7236          10 :   lcpomap["DA3_C5"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7237          10 :   lcpomap["DA3_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7238          10 :   lcpomap["DA3_C6"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7239          10 :   lcpomap["DA3_C8"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7240          10 :   lcpomap["DA3_N1"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7241          10 :   lcpomap["DA3_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7242          10 :   lcpomap["DA3_N6"]  = { 1.65,  0.73511, -0.22116, -8.9148e-04, 2.523e-04 };
+    7243          10 :   lcpomap["DA3_N7"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7244          10 :   lcpomap["DA3_N9"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    7245          10 :   lcpomap["DA3_O3'"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7246          10 :   lcpomap["DA3_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7247          10 :   lcpomap["DA3_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7248          10 :   lcpomap["DA3_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7249          10 :   lcpomap["DA3_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7250          10 :   lcpomap["DA3_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7251          10 :   lcpomap["DA3_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7252          10 :   lcpomap["DA3_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7253          10 :   lcpomap["DA3_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7254          10 :   lcpomap["DA3_P"] = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    7255             : 
+    7256          10 :   lcpomap["DA5_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7257          10 :   lcpomap["DA5_C2"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7258          10 :   lcpomap["DA5_C2'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7259          10 :   lcpomap["DA5_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7260          10 :   lcpomap["DA5_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7261          10 :   lcpomap["DA5_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7262          10 :   lcpomap["DA5_C5"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7263          10 :   lcpomap["DA5_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7264          10 :   lcpomap["DA5_C6"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7265          10 :   lcpomap["DA5_C8"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7266          10 :   lcpomap["DA5_N1"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7267          10 :   lcpomap["DA5_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7268          10 :   lcpomap["DA5_N6"]  = { 1.65,  0.73511, -0.22116, -8.9148e-04, 2.523e-04 };
+    7269          10 :   lcpomap["DA5_N7"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7270          10 :   lcpomap["DA5_N9"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    7271          10 :   lcpomap["DA5_O3'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7272          10 :   lcpomap["DA5_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7273          10 :   lcpomap["DA5_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7274          10 :   lcpomap["DA5_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7275          10 :   lcpomap["DA5_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7276          10 :   lcpomap["DA5_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7277          10 :   lcpomap["DA5_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7278          10 :   lcpomap["DA5_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7279          10 :   lcpomap["DA5_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7280          10 :   lcpomap["DA5_P"]   = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    7281             : 
+    7282          10 :   lcpomap["DA_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7283          10 :   lcpomap["DA_C2"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7284          10 :   lcpomap["DA_C2'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7285          10 :   lcpomap["DA_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7286          10 :   lcpomap["DA_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7287          10 :   lcpomap["DA_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7288          10 :   lcpomap["DA_C5"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7289          10 :   lcpomap["DA_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7290          10 :   lcpomap["DA_C6"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7291          10 :   lcpomap["DA_C8"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7292          10 :   lcpomap["DA_N1"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7293          10 :   lcpomap["DA_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7294          10 :   lcpomap["DA_N6"]  = { 1.65,  0.73511, -0.22116, -8.9148e-04, 2.523e-04 };
+    7295          10 :   lcpomap["DA_N7"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7296          10 :   lcpomap["DA_N9"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    7297          10 :   lcpomap["DA_O3'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7298          10 :   lcpomap["DA_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7299          10 :   lcpomap["DA_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7300          10 :   lcpomap["DA_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7301          10 :   lcpomap["DA_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7302          10 :   lcpomap["DA_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7303          10 :   lcpomap["DA_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7304          10 :   lcpomap["DA_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7305          10 :   lcpomap["DA_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7306          10 :   lcpomap["DA_P"] = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    7307             : 
+    7308          10 :   lcpomap["DC3_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7309          10 :   lcpomap["DC3_C2"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7310          10 :   lcpomap["DC3_C2'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7311          10 :   lcpomap["DC3_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7312          10 :   lcpomap["DC3_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7313          10 :   lcpomap["DC3_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7314          10 :   lcpomap["DC3_C5"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7315          10 :   lcpomap["DC3_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7316          10 :   lcpomap["DC3_C6"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7317          10 :   lcpomap["DC3_N1"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    7318          10 :   lcpomap["DC3_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7319          10 :   lcpomap["DC3_N4"]  = { 1.65,  0.73511, -0.22116, -8.9148e-04, 2.523e-04 };
+    7320          10 :   lcpomap["DC3_O2"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    7321          10 :   lcpomap["DC3_O3'"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7322          10 :   lcpomap["DC3_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7323          10 :   lcpomap["DC3_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7324          10 :   lcpomap["DC3_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7325          10 :   lcpomap["DC3_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7326          10 :   lcpomap["DC3_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7327          10 :   lcpomap["DC3_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7328          10 :   lcpomap["DC3_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7329          10 :   lcpomap["DC3_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7330          10 :   lcpomap["DC3_P"] = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    7331             : 
+    7332          10 :   lcpomap["DC5_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7333          10 :   lcpomap["DC5_C2"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7334          10 :   lcpomap["DC5_C2'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7335          10 :   lcpomap["DC5_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7336          10 :   lcpomap["DC5_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7337          10 :   lcpomap["DC5_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7338          10 :   lcpomap["DC5_C5"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7339          10 :   lcpomap["DC5_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7340          10 :   lcpomap["DC5_C6"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7341          10 :   lcpomap["DC5_N1"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    7342          10 :   lcpomap["DC5_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7343          10 :   lcpomap["DC5_N4"]  = { 1.65,  0.73511, -0.22116, -8.9148e-04, 2.523e-04 };
+    7344          10 :   lcpomap["DC5_O2"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    7345          10 :   lcpomap["DC5_O3'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7346          10 :   lcpomap["DC5_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7347          10 :   lcpomap["DC5_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7348          10 :   lcpomap["DC5_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7349          10 :   lcpomap["DC5_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7350          10 :   lcpomap["DC5_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7351          10 :   lcpomap["DC5_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7352          10 :   lcpomap["DC5_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7353          10 :   lcpomap["DC5_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7354          10 :   lcpomap["DC5_P"] = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    7355             : 
+    7356          10 :   lcpomap["DC_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7357          10 :   lcpomap["DC_C2"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7358          10 :   lcpomap["DC_C2'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7359          10 :   lcpomap["DC_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7360          10 :   lcpomap["DC_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7361          10 :   lcpomap["DC_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7362          10 :   lcpomap["DC_C5"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7363          10 :   lcpomap["DC_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7364          10 :   lcpomap["DC_C6"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7365          10 :   lcpomap["DC_N1"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    7366          10 :   lcpomap["DC_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7367          10 :   lcpomap["DC_N4"]  = { 1.65,  0.73511, -0.22116, -8.9148e-04, 2.523e-04 };
+    7368          10 :   lcpomap["DC_O2"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    7369          10 :   lcpomap["DC_O3'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7370          10 :   lcpomap["DC_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7371          10 :   lcpomap["DC_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7372          10 :   lcpomap["DC_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7373          10 :   lcpomap["DC_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7374          10 :   lcpomap["DC_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7375          10 :   lcpomap["DC_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7376          10 :   lcpomap["DC_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7377          10 :   lcpomap["DC_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7378          10 :   lcpomap["DC_P"]   = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    7379             : 
+    7380          10 :   lcpomap["DG3_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7381          10 :   lcpomap["DG3_C2"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7382          10 :   lcpomap["DG3_C2'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7383          10 :   lcpomap["DG3_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7384          10 :   lcpomap["DG3_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7385          10 :   lcpomap["DG3_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7386          10 :   lcpomap["DG3_C5"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7387          10 :   lcpomap["DG3_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7388          10 :   lcpomap["DG3_C6"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7389          10 :   lcpomap["DG3_C8"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7390          10 :   lcpomap["DG3_N1"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7391          10 :   lcpomap["DG3_N2"]  = { 1.65,  0.73511, -0.22116, -8.9148e-04, 2.523e-04 };
+    7392          10 :   lcpomap["DG3_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7393          10 :   lcpomap["DG3_N7"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7394          10 :   lcpomap["DG3_N9"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    7395          10 :   lcpomap["DG3_O3'"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7396          10 :   lcpomap["DG3_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7397          10 :   lcpomap["DG3_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7398          10 :   lcpomap["DG3_O6"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    7399          10 :   lcpomap["DG3_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7400          10 :   lcpomap["DG3_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7401          10 :   lcpomap["DG3_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7402          10 :   lcpomap["DG3_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7403          10 :   lcpomap["DG3_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7404          10 :   lcpomap["DG3_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7405          10 :   lcpomap["DG3_P"]   = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    7406             : 
+    7407          10 :   lcpomap["DG5_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7408          10 :   lcpomap["DG5_C2"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7409          10 :   lcpomap["DG5_C2'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7410          10 :   lcpomap["DG5_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7411          10 :   lcpomap["DG5_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7412          10 :   lcpomap["DG5_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7413          10 :   lcpomap["DG5_C5"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7414          10 :   lcpomap["DG5_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7415          10 :   lcpomap["DG5_C6"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7416          10 :   lcpomap["DG5_C8"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7417          10 :   lcpomap["DG5_N1"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7418          10 :   lcpomap["DG5_N2"]  = { 1.65,  0.73511, -0.22116, -8.9148e-04, 2.523e-04 };
+    7419          10 :   lcpomap["DG5_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7420          10 :   lcpomap["DG5_N7"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7421          10 :   lcpomap["DG5_N9"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    7422          10 :   lcpomap["DG5_O3'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7423          10 :   lcpomap["DG5_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7424          10 :   lcpomap["DG5_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7425          10 :   lcpomap["DG5_O6"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    7426          10 :   lcpomap["DG5_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7427          10 :   lcpomap["DG5_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7428          10 :   lcpomap["DG5_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7429          10 :   lcpomap["DG5_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7430          10 :   lcpomap["DG5_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7431          10 :   lcpomap["DG5_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7432          10 :   lcpomap["DG5_P"]   = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    7433             : 
+    7434          10 :   lcpomap["DG_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7435          10 :   lcpomap["DG_C2"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7436          10 :   lcpomap["DG_C2'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7437          10 :   lcpomap["DG_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7438          10 :   lcpomap["DG_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7439          10 :   lcpomap["DG_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7440          10 :   lcpomap["DG_C5"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7441          10 :   lcpomap["DG_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7442          10 :   lcpomap["DG_C6"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7443          10 :   lcpomap["DG_C8"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7444          10 :   lcpomap["DG_N1"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7445          10 :   lcpomap["DG_N2"]  = { 1.65,  0.73511, -0.22116, -8.9148e-04, 2.523e-04 };
+    7446          10 :   lcpomap["DG_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7447          10 :   lcpomap["DG_N7"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7448          10 :   lcpomap["DG_N9"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    7449          10 :   lcpomap["DG_O3'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7450          10 :   lcpomap["DG_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7451          10 :   lcpomap["DG_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7452          10 :   lcpomap["DG_O6"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    7453          10 :   lcpomap["DG_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7454          10 :   lcpomap["DG_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7455          10 :   lcpomap["DG_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7456          10 :   lcpomap["DG_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7457          10 :   lcpomap["DG_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7458          10 :   lcpomap["DG_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7459          10 :   lcpomap["DG_P"]   = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    7460             : 
+    7461          10 :   lcpomap["DT3_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7462          10 :   lcpomap["DT3_C2"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7463          10 :   lcpomap["DT3_C2'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7464          10 :   lcpomap["DT3_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7465          10 :   lcpomap["DT3_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7466          10 :   lcpomap["DT3_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7467          10 :   lcpomap["DT3_C5"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7468          10 :   lcpomap["DT3_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7469          10 :   lcpomap["DT3_C6"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7470          10 :   lcpomap["DT3_C7"]  = { 1.7,  0.77887, -0.28063, -1.2968e-03, 3.9328e-04 };
+    7471          10 :   lcpomap["DT3_N1"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    7472          10 :   lcpomap["DT3_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7473          10 :   lcpomap["DT3_O2"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    7474          10 :   lcpomap["DT3_O3'"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7475          10 :   lcpomap["DT3_O4"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    7476          10 :   lcpomap["DT3_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7477          10 :   lcpomap["DT3_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7478          10 :   lcpomap["DT3_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7479          10 :   lcpomap["DT3_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7480          10 :   lcpomap["DT3_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7481          10 :   lcpomap["DT3_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7482          10 :   lcpomap["DT3_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7483          10 :   lcpomap["DT3_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7484          10 :   lcpomap["DT3_P"] = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    7485             : 
+    7486          10 :   lcpomap["DT5_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7487          10 :   lcpomap["DT5_C2"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7488          10 :   lcpomap["DT5_C2'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7489          10 :   lcpomap["DT5_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7490          10 :   lcpomap["DT5_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7491          10 :   lcpomap["DT5_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7492          10 :   lcpomap["DT5_C5"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7493          10 :   lcpomap["DT5_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7494          10 :   lcpomap["DT5_C6"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7495          10 :   lcpomap["DT5_C7"]  = { 1.7,  0.77887, -0.28063, -1.2968e-03, 3.9328e-04 };
+    7496          10 :   lcpomap["DT5_N1"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    7497          10 :   lcpomap["DT5_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7498          10 :   lcpomap["DT5_O2"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    7499          10 :   lcpomap["DT5_O3'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7500          10 :   lcpomap["DT5_O4"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    7501          10 :   lcpomap["DT5_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7502          10 :   lcpomap["DT5_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7503          10 :   lcpomap["DT5_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7504          10 :   lcpomap["DT5_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7505          10 :   lcpomap["DT5_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7506          10 :   lcpomap["DT5_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7507          10 :   lcpomap["DT5_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7508          10 :   lcpomap["DT5_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7509          10 :   lcpomap["DT5_P"] = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    7510             : 
+    7511          10 :   lcpomap["DT_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7512          10 :   lcpomap["DT_C2"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7513          10 :   lcpomap["DT_C2'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7514          10 :   lcpomap["DT_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7515          10 :   lcpomap["DT_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7516          10 :   lcpomap["DT_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7517          10 :   lcpomap["DT_C5"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7518          10 :   lcpomap["DT_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7519          10 :   lcpomap["DT_C6"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7520          10 :   lcpomap["DT_C7"]  = { 1.7,  0.77887, -0.28063, -1.2968e-03, 3.9328e-04 };
+    7521          10 :   lcpomap["DT_N1"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    7522          10 :   lcpomap["DT_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7523          10 :   lcpomap["DT_O2"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    7524          10 :   lcpomap["DT_O3'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7525          10 :   lcpomap["DT_O4"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    7526          10 :   lcpomap["DT_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7527          10 :   lcpomap["DT_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7528          10 :   lcpomap["DT_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7529          10 :   lcpomap["DT_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7530          10 :   lcpomap["DT_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7531          10 :   lcpomap["DT_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7532          10 :   lcpomap["DT_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7533          10 :   lcpomap["DT_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7534          10 :   lcpomap["DT_P"] = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    7535             : 
+    7536          10 :   lcpomap["G3_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7537          10 :   lcpomap["G3_C2"] = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7538          10 :   lcpomap["G3_C2'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7539          10 :   lcpomap["G3_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7540          10 :   lcpomap["G3_C4"] = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7541          10 :   lcpomap["G3_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7542          10 :   lcpomap["G3_C5"] = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7543          10 :   lcpomap["G3_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7544          10 :   lcpomap["G3_C6"] = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7545          10 :   lcpomap["G3_C8"] = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7546          10 :   lcpomap["G3_N1"] = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7547          10 :   lcpomap["G3_N2"] = { 1.65,  0.73511, -0.22116, -8.9148e-04, 2.523e-04 };
+    7548          10 :   lcpomap["G3_N3"] = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7549          10 :   lcpomap["G3_N7"] = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7550          10 :   lcpomap["G3_N9"] = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    7551          10 :   lcpomap["G3_O2'"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7552          10 :   lcpomap["G3_O3'"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7553          10 :   lcpomap["G3_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7554          10 :   lcpomap["G3_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7555          10 :   lcpomap["G3_O6"] = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    7556          10 :   lcpomap["G3_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7557          10 :   lcpomap["G3_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7558          10 :   lcpomap["G3_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7559          10 :   lcpomap["G3_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7560          10 :   lcpomap["G3_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7561          10 :   lcpomap["G3_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7562          10 :   lcpomap["G3_P"] = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    7563             : 
+    7564          10 :   lcpomap["G5_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7565          10 :   lcpomap["G5_C2"] = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7566          10 :   lcpomap["G5_C2'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7567          10 :   lcpomap["G5_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7568          10 :   lcpomap["G5_C4"] = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7569          10 :   lcpomap["G5_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7570          10 :   lcpomap["G5_C5"] = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7571          10 :   lcpomap["G5_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7572          10 :   lcpomap["G5_C6"] = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7573          10 :   lcpomap["G5_C8"] = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7574          10 :   lcpomap["G5_N1"] = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7575          10 :   lcpomap["G5_N2"] = { 1.65,  0.73511, -0.22116, -8.9148e-04, 2.523e-04 };
+    7576          10 :   lcpomap["G5_N3"] = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7577          10 :   lcpomap["G5_N7"] = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7578          10 :   lcpomap["G5_N9"] = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    7579          10 :   lcpomap["G5_O2'"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7580          10 :   lcpomap["G5_O3'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7581          10 :   lcpomap["G5_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7582          10 :   lcpomap["G5_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7583          10 :   lcpomap["G5_O6"] = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    7584          10 :   lcpomap["G5_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7585          10 :   lcpomap["G5_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7586          10 :   lcpomap["G5_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7587          10 :   lcpomap["G5_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7588          10 :   lcpomap["G5_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7589          10 :   lcpomap["G5_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7590          10 :   lcpomap["G5_P"] = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    7591             : 
+    7592          10 :   lcpomap["G_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7593          10 :   lcpomap["G_C2"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7594          10 :   lcpomap["G_C2'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7595          10 :   lcpomap["G_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7596          10 :   lcpomap["G_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7597          10 :   lcpomap["G_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7598          10 :   lcpomap["G_C5"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7599          10 :   lcpomap["G_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7600          10 :   lcpomap["G_C6"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7601          10 :   lcpomap["G_C8"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7602          10 :   lcpomap["G_N1"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7603          10 :   lcpomap["G_N2"]  = { 1.65,  0.73511, -0.22116, -8.9148e-04, 2.523e-04 };
+    7604          10 :   lcpomap["G_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7605          10 :   lcpomap["G_N7"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7606          10 :   lcpomap["G_N9"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    7607          10 :   lcpomap["G_O2'"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7608          10 :   lcpomap["G_O3'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7609          10 :   lcpomap["G_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7610          10 :   lcpomap["G_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7611          10 :   lcpomap["G_O6"] = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    7612          10 :   lcpomap["G_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7613          10 :   lcpomap["G_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7614          10 :   lcpomap["G_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7615          10 :   lcpomap["G_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7616          10 :   lcpomap["G_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7617          10 :   lcpomap["G_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7618          10 :   lcpomap["G_P"] = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    7619             : 
+    7620          10 :   lcpomap["U3_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7621          10 :   lcpomap["U3_C2"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7622          10 :   lcpomap["U3_C2'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7623          10 :   lcpomap["U3_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7624          10 :   lcpomap["U3_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7625          10 :   lcpomap["U3_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7626          10 :   lcpomap["U3_C5"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7627          10 :   lcpomap["U3_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7628          10 :   lcpomap["U3_C6"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7629          10 :   lcpomap["U3_N1"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    7630          10 :   lcpomap["U3_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7631          10 :   lcpomap["U3_O2"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    7632          10 :   lcpomap["U3_O2'"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7633          10 :   lcpomap["U3_O3'"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7634          10 :   lcpomap["U3_O4"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    7635          10 :   lcpomap["U3_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7636          10 :   lcpomap["U3_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7637          10 :   lcpomap["U3_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7638          10 :   lcpomap["U3_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7639          10 :   lcpomap["U3_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7640          10 :   lcpomap["U3_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7641          10 :   lcpomap["U3_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7642          10 :   lcpomap["U3_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7643          10 :   lcpomap["U3_P"] = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    7644             : 
+    7645          10 :   lcpomap["U5_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7646          10 :   lcpomap["U5_C2"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7647          10 :   lcpomap["U5_C2'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7648          10 :   lcpomap["U5_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7649          10 :   lcpomap["U5_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7650          10 :   lcpomap["U5_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7651          10 :   lcpomap["U5_C5"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7652          10 :   lcpomap["U5_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7653          10 :   lcpomap["U5_C6"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7654          10 :   lcpomap["U5_N1"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    7655          10 :   lcpomap["U5_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7656          10 :   lcpomap["U5_O2"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    7657          10 :   lcpomap["U5_O2'"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7658          10 :   lcpomap["U5_O3'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7659          10 :   lcpomap["U5_O4"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    7660          10 :   lcpomap["U5_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7661          10 :   lcpomap["U5_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7662          10 :   lcpomap["U5_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7663          10 :   lcpomap["U5_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7664          10 :   lcpomap["U5_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7665          10 :   lcpomap["U5_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7666          10 :   lcpomap["U5_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7667          10 :   lcpomap["U5_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7668          10 :   lcpomap["U5_P"] = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    7669             : 
+    7670          10 :   lcpomap["U_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7671          10 :   lcpomap["U_C2"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7672          10 :   lcpomap["U_C2'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7673          10 :   lcpomap["U_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7674          10 :   lcpomap["U_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7675          10 :   lcpomap["U_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7676          10 :   lcpomap["U_C5"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7677          10 :   lcpomap["U_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7678          10 :   lcpomap["U_C6"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7679          10 :   lcpomap["U_N1"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    7680          10 :   lcpomap["U_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7681          10 :   lcpomap["U_O2"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    7682          10 :   lcpomap["U_O2'"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7683          10 :   lcpomap["U_O3'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7684          10 :   lcpomap["U_O4"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    7685          10 :   lcpomap["U_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7686          10 :   lcpomap["U_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7687          10 :   lcpomap["U_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7688          10 :   lcpomap["U_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7689          10 :   lcpomap["U_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7690          10 :   lcpomap["U_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7691          10 :   lcpomap["U_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7692          10 :   lcpomap["U_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7693          10 :   lcpomap["U_P"] = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    7694             : 
+    7695          10 :   return lcpomap;
+    7696             : }
+    7697             : 
+    7698             : // assigns LCPO parameters to each atom reading from database
+    7699          10 : void SAXS::readLCPOparam(const std::vector<std::vector<std::string> > &AtomResidueName, unsigned natoms)
+    7700             : {
+    7701          10 :   std::map<std::string, std::vector<double> > lcpomap = setupLCPOparam();
+    7702             : 
+    7703       35476 :   for(unsigned i=0; i<natoms; ++i)
+    7704             :   {
+    7705       35466 :     if ((AtomResidueName[0][i][0]=='O') || (AtomResidueName[0][i][0]=='N') || (AtomResidueName[0][i][0]=='C') || (AtomResidueName[0][i][0]=='S' || (AtomResidueName[0][i][0]=='P'))) {
+    7706       16548 :       std::string identifier = AtomResidueName[1][i]+"_"+AtomResidueName[0][i];
+    7707       16548 :       std::vector<double> LCPOparamVector = lcpomap.at(identifier);
+    7708             :       double rs = 0.14;
+    7709       16548 :       LCPOparam[i].push_back(LCPOparamVector[0]+rs*10.);
+    7710       16548 :       LCPOparam[i].push_back(LCPOparamVector[1]);
+    7711       16548 :       LCPOparam[i].push_back(LCPOparamVector[2]);
+    7712       16548 :       LCPOparam[i].push_back(LCPOparamVector[3]);
+    7713       16548 :       LCPOparam[i].push_back(LCPOparamVector[4]);
+    7714             :     }
+    7715             :   }
+    7716             : 
+    7717       35476 :   for(unsigned i=0; i<natoms; ++i) {
+    7718       35466 :     if (LCPOparam[i].size()==0 ) {
+    7719       18918 :       if ((AtomResidueName[0][i][0]=='O') || (AtomResidueName[0][i][0]=='N') || (AtomResidueName[0][i][0]=='C') || (AtomResidueName[0][i][0]=='S') || (AtomResidueName[0][i][0]=='P')) {
+    7720           0 :         std::cout << "Could not find LCPO paramaters for atom " << AtomResidueName[0][i] << " of residue " << AtomResidueName[1][i] << std::endl;
+    7721           0 :         error ("missing LCPO parameters\n");
+    7722             :       }
+    7723             :     }
+    7724             :   }
+    7725             : 
+    7726          10 :   if (AtomResidueName[0][0] == "N") {
+    7727          10 :     LCPOparam[0][1] = 7.3511e-01;
+    7728          10 :     LCPOparam[0][2] = -2.2116e-01;
+    7729          10 :     LCPOparam[0][3] = -8.9148e-04;
+    7730          10 :     LCPOparam[0][4] = 2.5230e-04;
+    7731             :   }
+    7732             : 
+    7733          10 :   if (AtomResidueName[0][natoms-1] == "O") {
+    7734           0 :     LCPOparam[natoms-1][1] = 8.8857e-01;
+    7735           0 :     LCPOparam[natoms-1][2] = -3.3421e-01;
+    7736           0 :     LCPOparam[natoms-1][3] = -1.8683e-03;
+    7737           0 :     LCPOparam[natoms-1][4] = 4.9372e-04;
+    7738             :   }
+    7739          10 : }
+    7740             : 
+    7741           4 : void SAXS::resolution_function()
+    7742             : {
+    7743           4 :   const unsigned numq = q_list.size();
+    7744             : 
+    7745             :   // only OpenMP because numq might be smaller than the number of ranks
+    7746           4 :   #pragma omp parallel for num_threads(OpenMP::getNumThreads())
+    7747             :   for (unsigned i=0; i<numq; i++) {
+    7748             :     double qi = q_list[i];
+    7749             :     double dq = 6*sigma_res[i]/(Nj-1);
+    7750             :     double sigma_sq = sigma_res[i]*sigma_res[i];
+    7751             :     double qstart = qi - 3*sigma_res[i];
+    7752             :     for (unsigned j=0; j<Nj; j++) {
+    7753             :       double qj = qstart + j*dq;
+    7754             :       double I0exp = i0e(qj*qi/sigma_sq);
+    7755             : 
+    7756             :       qj_list[i][j] = qj;
+    7757             :       Rij[i][j] = (qj/sigma_sq)*std::exp(-0.5*(qj - qi)*(qj - qi)/sigma_sq)*I0exp;
+    7758             :     }
+    7759             :   }
+    7760           4 : }
+    7761             : 
+    7762             : // i0e function from cephes
+    7763             : // compute I0(x) * exp (-x), with I0 being the modified Bessel function
+    7764             : // of first kind and zeroth order.
+    7765         660 : inline double SAXS::i0e(double x)
+    7766             : {
+    7767             :   double y = 0.0;
+    7768             : 
+    7769         660 :   if (x < 0)
+    7770           0 :     x = -x;
+    7771         660 :   if (x <= 8.0) {
+    7772           0 :     y = (x/2.0) - 2.0;
+    7773           0 :     return chbevl(y, A);
+    7774             :   }
+    7775             : 
+    7776         660 :   return chbevl(32.0/x - 2.0, B) / sqrt(x);
+    7777             : }
+    7778             : 
+    7779         660 : double SAXS::chbevl(double x, const std::vector<double> &coeffs)
+    7780             : {
+    7781             :   double b0, b1, b2;
+    7782         660 :   unsigned n = coeffs.size();
+    7783             : 
+    7784         660 :   b0 = coeffs[0];
+    7785             :   b1 = 0.0;
+    7786             :   b2 = 0.0;
+    7787             : 
+    7788       16500 :   for (unsigned i = 1; i < n; i++) {
+    7789             :     b2 = b1;
+    7790             :     b1 = b0;
+    7791       15840 :     b0 = x * b1 - b2 + coeffs[i];
+    7792             :   }
+    7793         660 :   return 0.5 * (b0 - b2);
+    7794             : }
+    7795             : 
+    7796      134310 : inline double SAXS::interpolation(std::vector<SplineCoeffs> &coeffs, double x)
+    7797             : {
+    7798             :   unsigned s = 0;
+    7799     1002034 :   while ((x >= q_list[s+1]) && (s+1 < q_list.size()-1)) s++;
+    7800             : 
+    7801      134310 :   double dx = x - coeffs[s].x;
+    7802      134310 :   return coeffs[s].a + coeffs[s].b*dx + coeffs[s].c*dx*dx + coeffs[s].d*dx*dx*dx;
+    7803             : }
+    7804             : 
+    7805             : // natural bc cubic spline implementation from the Wikipedia algorithm
+    7806             : // modified from https://stackoverflow.com/a/19216702/3254658
+    7807         814 : std::vector<SAXS::SplineCoeffs> SAXS::spline_coeffs(std::vector<double> &x, std::vector<double> &y)
+    7808             : {
+    7809         814 :   unsigned n = x.size()-1;
+    7810             :   std::vector<double> a;
+    7811         814 :   a.insert(a.begin(), y.begin(), y.end());
+    7812         814 :   std::vector<double> b(n);
+    7813         814 :   std::vector<double> d(n);
+    7814             :   std::vector<double> h;
+    7815             : 
+    7816       12210 :   for(unsigned i=0; i<n; i++)
+    7817       11396 :     h.push_back(x[i+1]-x[i]);
+    7818             : 
+    7819             :   std::vector<double> alpha;
+    7820         814 :   alpha.push_back(0);
+    7821       11396 :   for(unsigned i=1; i<n; i++)
+    7822       10582 :     alpha.push_back( 3*(a[i+1]-a[i])/h[i] - 3*(a[i]-a[i-1])/h[i-1]  );
+    7823             : 
+    7824         814 :   std::vector<double> c(n+1);
+    7825         814 :   std::vector<double> l(n+1);
+    7826         814 :   std::vector<double> mu(n+1);
+    7827         814 :   std::vector<double> z(n+1);
+    7828         814 :   l[0] = 1;
+    7829         814 :   mu[0] = 0;
+    7830         814 :   z[0] = 0;
+    7831             : 
+    7832       11396 :   for(unsigned i=1; i<n; i++) {
+    7833       10582 :     l[i] = 2 *(x[i+1]-x[i-1])-h[i-1]*mu[i-1];
+    7834       10582 :     mu[i] = h[i]/l[i];
+    7835       10582 :     z[i] = (alpha[i]-h[i-1]*z[i-1])/l[i];
+    7836             :   }
+    7837             : 
+    7838         814 :   l[n] = 1;
+    7839         814 :   z[n] = 0;
+    7840         814 :   c[n] = 0;
+    7841             : 
+    7842       12210 :   for(int j=n-1; j>=0; j--) {
+    7843       11396 :     c[j] = z[j] - mu[j] * c[j+1];
+    7844       11396 :     b[j] = (a[j+1]-a[j])/h[j]-h[j]*(c[j+1]+2*c[j])/3;
+    7845       11396 :     d[j] = (c[j+1]-c[j])/3/h[j];
+    7846             :   }
+    7847             : 
+    7848         814 :   std::vector<SplineCoeffs> output_set(n);
+    7849       12210 :   for(unsigned i=0; i<n; i++) {
+    7850       11396 :     output_set[i].a = a[i];
+    7851       11396 :     output_set[i].b = b[i];
+    7852       11396 :     output_set[i].c = c[i];
+    7853       11396 :     output_set[i].d = d[i];
+    7854       11396 :     output_set[i].x = x[i];
+    7855             :   }
+    7856             : 
+    7857         814 :   return output_set;
+    7858             : }
+    7859             : 
+    7860             : 
+    7861             : }//namespace isdb
+    7862             : }//namespace PLMD
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/Select.cpp.func-sort-c.html b/coverage/isdb/Select.cpp.func-sort-c.html new file mode 100644 index 000000000000..325bd057af8f --- /dev/null +++ b/coverage/isdb/Select.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - isdb/Select.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - Select.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2020100.0 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb6SelectC2ERKNS_13ActionOptionsE0
_ZN4PLMD4isdb6SelectC1ERKNS_13ActionOptionsE2
_ZN4PLMD4isdb6Select16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD4isdb6Select9calculateEv8
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/Select.cpp.func.html b/coverage/isdb/Select.cpp.func.html new file mode 100644 index 000000000000..a167a4d92169 --- /dev/null +++ b/coverage/isdb/Select.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - isdb/Select.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - Select.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2020100.0 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb6Select16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD4isdb6Select9calculateEv8
_ZN4PLMD4isdb6SelectC1ERKNS_13ActionOptionsE2
_ZN4PLMD4isdb6SelectC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/Select.cpp.gcov.html b/coverage/isdb/Select.cpp.gcov.html new file mode 100644 index 000000000000..ab38179de53f --- /dev/null +++ b/coverage/isdb/Select.cpp.gcov.html @@ -0,0 +1,193 @@ + + + + + + + + LCOV - plumed test coverage - isdb/Select.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - Select.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2020100.0 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2017-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : /*
+      23             : 
+      24             : */
+      25             : #include "function/Function.h"
+      26             : #include "core/ActionRegister.h"
+      27             : #include "core/PlumedMain.h"
+      28             : 
+      29             : namespace PLMD {
+      30             : namespace isdb {
+      31             : 
+      32             : //+PLUMEDOC ISDB_FUNCTION SELECT
+      33             : /*
+      34             : Selects an argument based on the value of a \ref SELECTOR.
+      35             : 
+      36             : \par Examples
+      37             : 
+      38             : In this example we use a simulated-tempering like approach activated by the \ref RESCALE action.
+      39             : For each value of the scale parameter, we perform an independent Parallel Bias Metadynamics
+      40             : simulation (see \ref PBMETAD). At each moment of the simulation, only one of the \ref PBMETAD
+      41             : actions is activated, based on the current value of the associated \ref SELECTOR.
+      42             : The \ref SELECT action can then be used to print out the value of the (active) \ref PBMETAD bias potential.
+      43             : 
+      44             : \plumedfile
+      45             : ene:  ENERGY
+      46             : d: DISTANCE ATOMS=1,2
+      47             : 
+      48             : SELECTOR NAME=GAMMA VALUE=0
+      49             : 
+      50             : pbmetad0: PBMETAD ARG=d SELECTOR=GAMMA SELECTOR_ID=0 SIGMA=0.1 PACE=500 HEIGHT=1 BIASFACTOR=8 FILE=HILLS.0
+      51             : pbmetad1: PBMETAD ARG=d SELECTOR=GAMMA SELECTOR_ID=1 SIGMA=0.1 PACE=500 HEIGHT=1 BIASFACTOR=8 FILE=HILLS.1
+      52             : 
+      53             : RESCALE ...
+      54             : LABEL=res ARG=ene,pbmetad0.bias,pbmetad1.bias TEMP=300
+      55             : SELECTOR=GAMMA MAX_RESCALE=1.2 NOT_RESCALED=2 NBIN=2
+      56             : W0=1000 BIASFACTOR=100.0 BSTRIDE=2000 BFILE=bias.dat
+      57             : ...
+      58             : 
+      59             : pbactive: SELECT ARG=pbmetad0.bias,pbmetad1.bias SELECTOR=GAMMA
+      60             : 
+      61             : PRINT ARG=pbactive STRIDE=100 FILE=COLVAR
+      62             : \endplumedfile
+      63             : 
+      64             : */
+      65             : //+ENDPLUMEDOC
+      66             : 
+      67             : class Select : public function::Function
+      68             : {
+      69             :   std::string selector_;
+      70             : 
+      71             : public:
+      72             :   explicit Select(const ActionOptions&);
+      73             :   void calculate();
+      74             :   static void registerKeywords(Keywords& keys);
+      75             : };
+      76             : 
+      77             : PLUMED_REGISTER_ACTION(Select,"SELECT")
+      78             : 
+      79           4 : void Select::registerKeywords(Keywords& keys) {
+      80           4 :   Function::registerKeywords(keys);
+      81           4 :   keys.use("ARG");
+      82           8 :   keys.add("compulsory","SELECTOR","name of the variable used to select");
+      83           4 : }
+      84             : 
+      85           2 : Select::Select(const ActionOptions&ao):
+      86           2 :   Action(ao), Function(ao)
+      87             : {
+      88             :   // name of selector
+      89           2 :   parse("SELECTOR", selector_);
+      90             : 
+      91           2 :   addValueWithDerivatives(); setNotPeriodic();
+      92           2 :   checkRead();
+      93             : 
+      94           2 :   log.printf("  select based on %s\n",selector_.c_str());
+      95           4 :   log << " Bibliography" << plumed.cite("Bonomi, Camilloni, Bioinformatics, 33, 3999 (2017)") << "\n";
+      96             : 
+      97           2 : }
+      98             : 
+      99           8 : void Select::calculate()
+     100             : {
+     101           8 :   unsigned iselect = static_cast<unsigned>(plumed.passMap[selector_]);
+     102             : 
+     103             :   // check if iselect is smaller than the number of arguments
+     104           8 :   if(iselect>=getNumberOfArguments()) error("the value of the SELECTOR is greater than the number of arguments!");
+     105             : 
+     106             :   // put all the derivatives to zero
+     107          24 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) setDerivative(i, 0.0);
+     108             : 
+     109             :   // set value and derivative for selected argument
+     110           8 :   setValue(getArgument(iselect));
+     111           8 :   setDerivative(iselect, 1.0);
+     112           8 : }
+     113             : 
+     114             : }
+     115             : }
+     116             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/Selector.cpp.func-sort-c.html b/coverage/isdb/Selector.cpp.func-sort-c.html new file mode 100644 index 000000000000..8f77b981f9b9 --- /dev/null +++ b/coverage/isdb/Selector.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - isdb/Selector.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - Selector.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:111384.6 %
Date:2024-04-19 12:12:35Functions:2450.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb8Selector5applyEv0
_ZN4PLMD4isdb8Selector9calculateEv0
_ZN4PLMD4isdb8SelectorC2ERKNS_13ActionOptionsE2
_ZN4PLMD4isdb8Selector16registerKeywordsERNS_8KeywordsE4
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/Selector.cpp.func.html b/coverage/isdb/Selector.cpp.func.html new file mode 100644 index 000000000000..f2af6acafffd --- /dev/null +++ b/coverage/isdb/Selector.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - isdb/Selector.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - Selector.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:111384.6 %
Date:2024-04-19 12:12:35Functions:2450.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb8Selector16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD4isdb8Selector5applyEv0
_ZN4PLMD4isdb8Selector9calculateEv0
_ZN4PLMD4isdb8SelectorC2ERKNS_13ActionOptionsE2
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/Selector.cpp.gcov.html b/coverage/isdb/Selector.cpp.gcov.html new file mode 100644 index 000000000000..e4e4bd3a82c7 --- /dev/null +++ b/coverage/isdb/Selector.cpp.gcov.html @@ -0,0 +1,169 @@ + + + + + + + + LCOV - plumed test coverage - isdb/Selector.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - Selector.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:111384.6 %
Date:2024-04-19 12:12:35Functions:2450.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2017-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/Action.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "core/PlumedMain.h"
+      25             : #include <string>
+      26             : 
+      27             : namespace PLMD {
+      28             : namespace isdb {
+      29             : 
+      30             : //+PLUMEDOC ISDB_GENERIC SELECTOR
+      31             : /*
+      32             : Defines a variable (of the type double) inside the PLUMED code that can be used and modified by other actions.
+      33             : 
+      34             : A \ref SELECTOR can be used for example to activate or modify a bias based on its current value.
+      35             : 
+      36             : \par Examples
+      37             : 
+      38             : A typical example is the simulated-tempering like approach activated by \ref RESCALE.
+      39             : In this example the total potential energy of the system is scaled
+      40             : by a parameter defined on a grid of dimension NBIN in the range from 1 to MAX_RESCALE.
+      41             : The value of the scaling parameter is determined by the current value of the \ref SELECTOR GAMMA.
+      42             : The value of the \ref SELECTOR is updated by a MC protocol inside the \ref RESCALE class.
+      43             : A well-tempered metadynamics potential is used to enhance sampling in the \ref SELECTOR space.
+      44             : 
+      45             : \plumedfile
+      46             : ene:  ENERGY
+      47             : 
+      48             : SELECTOR NAME=GAMMA VALUE=0
+      49             : 
+      50             : RESCALE ...
+      51             : LABEL=res ARG=ene TEMP=300
+      52             : SELECTOR=GAMMA MAX_RESCALE=1.2 NBIN=2
+      53             : W0=1000 BIASFACTOR=100.0 BSTRIDE=2000 BFILE=bias.dat
+      54             : ...
+      55             : 
+      56             : PRINT FILE=COLVAR ARG=* STRIDE=100
+      57             : \endplumedfile
+      58             : 
+      59             : */
+      60             : //+ENDPLUMEDOC
+      61             : 
+      62             : class Selector:
+      63             :   public Action
+      64             : {
+      65             : public:
+      66             :   static void registerKeywords( Keywords& keys );
+      67             :   explicit Selector(const ActionOptions&ao);
+      68           0 :   void calculate() override {}
+      69           0 :   void apply() override {}
+      70             : };
+      71             : 
+      72             : PLUMED_REGISTER_ACTION(Selector,"SELECTOR")
+      73             : 
+      74           4 : void Selector::registerKeywords( Keywords& keys ) {
+      75           4 :   Action::registerKeywords(keys);
+      76           8 :   keys.add("compulsory","NAME","name of the SELECTOR");
+      77           8 :   keys.add("compulsory","VALUE","set (initial) value of the SELECTOR");
+      78           4 : }
+      79             : 
+      80           2 : Selector::Selector(const ActionOptions&ao):
+      81           2 :   Action(ao)
+      82             : {
+      83             :   std::string name;
+      84           2 :   parse("NAME", name);
+      85             :   double value;
+      86           2 :   parse("VALUE", value);
+      87           2 :   plumed.passMap[name] = value;
+      88           2 : }
+      89             : 
+      90             : }
+      91             : }
+      92             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/Shadow.cpp.func-sort-c.html b/coverage/isdb/Shadow.cpp.func-sort-c.html new file mode 100644 index 000000000000..4e56c9a06984 --- /dev/null +++ b/coverage/isdb/Shadow.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - isdb/Shadow.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - Shadow.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:65710.5 %
Date:2024-04-19 12:12:35Functions:1520.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb6Shadow16update_referenceEv0
_ZN4PLMD4isdb6Shadow9calculateEv0
_ZN4PLMD4isdb6ShadowC1ERKNS_13ActionOptionsE0
_ZN4PLMD4isdb6ShadowC2ERKNS_13ActionOptionsE0
_ZN4PLMD4isdb6Shadow16registerKeywordsERNS_8KeywordsE2
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/Shadow.cpp.func.html b/coverage/isdb/Shadow.cpp.func.html new file mode 100644 index 000000000000..2f88155221a0 --- /dev/null +++ b/coverage/isdb/Shadow.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - isdb/Shadow.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - Shadow.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:65710.5 %
Date:2024-04-19 12:12:35Functions:1520.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb6Shadow16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD4isdb6Shadow16update_referenceEv0
_ZN4PLMD4isdb6Shadow9calculateEv0
_ZN4PLMD4isdb6ShadowC1ERKNS_13ActionOptionsE0
_ZN4PLMD4isdb6ShadowC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/Shadow.cpp.gcov.html b/coverage/isdb/Shadow.cpp.gcov.html new file mode 100644 index 000000000000..3986b15b1ace --- /dev/null +++ b/coverage/isdb/Shadow.cpp.gcov.html @@ -0,0 +1,301 @@ + + + + + + + + LCOV - plumed test coverage - isdb/Shadow.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - Shadow.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:65710.5 %
Date:2024-04-19 12:12:35Functions:1520.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2017-2022 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "colvar/Colvar.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "core/PlumedMain.h"
+      25             : #include "tools/Communicator.h"
+      26             : #include "tools/Pbc.h"
+      27             : #include "tools/RMSD.h"
+      28             : #include <string>
+      29             : 
+      30             : namespace PLMD {
+      31             : namespace isdb {
+      32             : 
+      33             : //+PLUMEDOC ISDB_COLVAR SHADOW
+      34             : /*
+      35             : Communicate atoms positions among replicas and calculate the \ref RMSD with respect to a mother (reference) simulation.
+      36             : 
+      37             : The option \ref UPDATE allows to specify the stride for communication between mother and replica systems.
+      38             : The flag \ref REFERENCE needs to be specified in the input file of the mother replica.
+      39             : This action must be run in a multi-replica framework (such as the -multi option in GROMACS).
+      40             : 
+      41             : \par Examples
+      42             : 
+      43             : In this example, we perform a simulation of a RNA molecule using two replicas: a mother and a shadow replica.
+      44             : The mother simulation communicates the coordinates of the RNA backbone to the replica every 100 steps.
+      45             : The RMSD of the replica with respect to the mother is calculated on the RNA backbone atoms and an \ref UPPER_WALLS is applied at 0.2 nm.
+      46             : The mother replica contains also the \ref UPPER_WALLS action. However, the forces on the RNA atoms of the mother replica are automatically set to zero
+      47             : inside the \ref SHADOW action.
+      48             : 
+      49             : The input file for the mother simulation looks as follows:
+      50             : 
+      51             : \plumedfile
+      52             : # Reference PDB
+      53             : MOLINFO STRUCTURE=conf_emin_PLUMED.pdb WHOLE
+      54             : # Define RNA nucleic backbone
+      55             : rna: GROUP ATOMS=1,2,5,6,33,36,37,40,41,67,70,71,74,75,98,101,102,105,106,131,134,135,138,139,165,168,169,172,173,198,201,202,205,206,228,231,232,235,236,259,262,263,266,267,289,292,293,296,297,323,326,327,330,331,356,359,360,363,364,390,393,394,397,398,421,424,425,428,429,452,455,456,459,460,482,485,486,489,490,516,519,520,523,524,550,553,554,557,558,584,587,588,591,592,617,620,621,624,625,651,654,655,658,659,682,685,686,689,690,712,715,716,719,720,743,746,747,750,751,773,776,777,780,781,804,807,808,811,812,834,837,838,841,842,868,871,872,875,876,899,902,903,906,907
+      56             : # Reconstruct RNA PBC
+      57             : WHOLEMOLECULES ENTITY0=rna EMST STRIDE=1
+      58             : 
+      59             : # Define shadow RMSD on RNA backbone
+      60             : rmsd: SHADOW ATOMS=rna NOPBC UPDATE=100 REFERENCE
+      61             : # Add upper wall - derivatives are set to zero inside SHADOW action
+      62             : uws: UPPER_WALLS ARG=rmsd AT=0.2 KAPPA=10000.0 STRIDE=1
+      63             : 
+      64             : # Print useful info
+      65             : PRINT FILE=COLVAR STRIDE=500 ARG=rmsd,uws.bias
+      66             : \endplumedfile
+      67             : 
+      68             : while the input file for a shadow replica looks like:
+      69             : 
+      70             : \plumedfile
+      71             : # Reference PDB
+      72             : MOLINFO STRUCTURE=conf_emin_PLUMED.pdb WHOLE
+      73             : # Define RNA nucleic backbone
+      74             : rna: GROUP ATOMS=1,2,5,6,33,36,37,40,41,67,70,71,74,75,98,101,102,105,106,131,134,135,138,139,165,168,169,172,173,198,201,202,205,206,228,231,232,235,236,259,262,263,266,267,289,292,293,296,297,323,326,327,330,331,356,359,360,363,364,390,393,394,397,398,421,424,425,428,429,452,455,456,459,460,482,485,486,489,490,516,519,520,523,524,550,553,554,557,558,584,587,588,591,592,617,620,621,624,625,651,654,655,658,659,682,685,686,689,690,712,715,716,719,720,743,746,747,750,751,773,776,777,780,781,804,807,808,811,812,834,837,838,841,842,868,871,872,875,876,899,902,903,906,907
+      75             : # Reconstruct RNA PBC
+      76             : WHOLEMOLECULES ENTITY0=rna EMST STRIDE=1
+      77             : 
+      78             : # Define shadow RMSD on RNA backbone
+      79             : rmsd: SHADOW ATOMS=rna NOPBC UPDATE=100
+      80             : # Add upper wall
+      81             : uws: UPPER_WALLS ARG=rmsd AT=0.2 KAPPA=10000.0 STRIDE=1
+      82             : 
+      83             : # Print useful info
+      84             : PRINT FILE=COLVAR STRIDE=500 ARG=rmsd,uws.bias
+      85             : \endplumedfile
+      86             : 
+      87             : */
+      88             : //+ENDPLUMEDOC
+      89             : 
+      90             : class Shadow : public Colvar {
+      91             : // private stuff
+      92             :   bool isreference_;
+      93             :   unsigned nupdate_;
+      94             :   bool pbc_;
+      95             :   bool first_time_;
+      96             : // RMSD object
+      97             :   PLMD::RMSD rmsd_;
+      98             : // parallel stuff
+      99             :   unsigned size_;
+     100             :   unsigned rank_;
+     101             : // update reference
+     102             :   void update_reference();
+     103             : 
+     104             : public:
+     105             :   static void registerKeywords( Keywords& keys );
+     106             :   explicit Shadow(const ActionOptions&);
+     107             : // active methods:
+     108             :   void calculate() override;
+     109             : };
+     110             : 
+     111             : PLUMED_REGISTER_ACTION(Shadow,"SHADOW")
+     112             : 
+     113           2 : void Shadow::registerKeywords( Keywords& keys ) {
+     114           2 :   Colvar::registerKeywords( keys );
+     115           4 :   keys.add("atoms","ATOMS","atoms for which we calculate the shadow RMSD");
+     116           4 :   keys.add("compulsory","UPDATE","stride for updating reference coordinates");
+     117           4 :   keys.addFlag("REFERENCE",false,"this is the reference replica");
+     118           2 : }
+     119             : 
+     120           0 : Shadow::Shadow(const ActionOptions&ao):
+     121             :   PLUMED_COLVAR_INIT(ao),
+     122           0 :   isreference_(false), nupdate_(1), pbc_(true), first_time_(true)
+     123             : {
+     124             :   // list of atoms
+     125             :   std::vector<AtomNumber> atoms;
+     126           0 :   parseAtomList("ATOMS",atoms);
+     127             :   // update stride
+     128           0 :   parse("UPDATE",nupdate_);
+     129             : 
+     130             :   // is this the reference replica
+     131           0 :   parseFlag("REFERENCE",isreference_);
+     132             : 
+     133             :   // periodic boundary conditions
+     134           0 :   bool nopbc=!pbc_;
+     135           0 :   parseFlag("NOPBC",nopbc);
+     136           0 :   pbc_=!nopbc;
+     137             : 
+     138             :   // set intra-replica (openmp) parallel stuff
+     139           0 :   size_ = comm.Get_size();
+     140           0 :   rank_ = comm.Get_rank();
+     141             : 
+     142             :   // get number of (MPI) replicas
+     143           0 :   int nrep = 0;
+     144           0 :   int replica = 0;
+     145             :   // only if openmp master
+     146           0 :   if(rank_==0) {
+     147           0 :     nrep    = multi_sim_comm.Get_size();
+     148           0 :     replica = multi_sim_comm.Get_rank();
+     149             :   }
+     150           0 :   comm.Sum(&nrep,1);
+     151           0 :   comm.Sum(&replica,1);
+     152             :   // check number of replicas
+     153             :   //if(nrep<2) error("SHADOW must be used with at least two replicas");
+     154             : 
+     155           0 :   checkRead();
+     156             : 
+     157           0 :   log.printf("  atoms involved : ");
+     158           0 :   for(unsigned i=0; i<atoms.size(); ++i) log.printf("%d ",atoms[i].serial());
+     159           0 :   log.printf("\n");
+     160           0 :   log.printf("  stride for updating reference coordinates : %d\n", nupdate_);
+     161           0 :   log.printf("  number of replicas : %d\n", nrep);
+     162           0 :   log.printf("  replica id : %d\n", replica);
+     163           0 :   if(isreference_) log.printf("  this is the reference replica\n");
+     164             : 
+     165             :   // add value and set periodicity
+     166           0 :   addValueWithDerivatives(); setNotPeriodic();
+     167             : 
+     168             :   // request atoms
+     169           0 :   requestAtoms(atoms);
+     170           0 : }
+     171             : 
+     172           0 : void Shadow::update_reference()
+     173             : {
+     174             : // number of atoms
+     175             :   unsigned natoms = getNumberOfAtoms();
+     176             : // initialize rmsd variables
+     177           0 :   std::vector<double> align(natoms,1.0);
+     178           0 :   std::vector<double> displace(natoms,1.0);
+     179           0 :   std::vector<Vector> reference(natoms);
+     180             : 
+     181             : // first get the reference coordinates
+     182             : // if master openmp task
+     183           0 :   if(rank_==0) {
+     184             :     // if reference replica
+     185           0 :     if(isreference_) reference = getPositions();
+     186             :     // share coordinates
+     187           0 :     multi_sim_comm.Sum(&reference[0][0], 3*natoms);
+     188             :   }
+     189             : // now intra replica (openmp) communication
+     190           0 :   if(size_>1) comm.Sum(&reference[0][0], 3*natoms);
+     191             : 
+     192             : // clear the rmsd object
+     193           0 :   rmsd_.clear();
+     194             : // and initialize it
+     195           0 :   rmsd_.set(align,displace,reference,"OPTIMAL");
+     196           0 : }
+     197             : 
+     198           0 : void Shadow::calculate()
+     199             : {
+     200             :   // make whole
+     201           0 :   if(pbc_) makeWhole();
+     202             : 
+     203             :   // if it is time, update reference coordinates
+     204           0 :   if(first_time_ || getStep()%nupdate_==0) {
+     205           0 :     update_reference();
+     206           0 :     first_time_ = false;
+     207             :   }
+     208             : 
+     209             :   // calculate RMSD and derivatives
+     210           0 :   std::vector<Vector> derivatives(getNumberOfAtoms());
+     211           0 :   double rmsd = rmsd_.calculate(getPositions(), derivatives);
+     212             : 
+     213             :   // set RMSD value
+     214           0 :   setValue(rmsd);
+     215             :   // if this is not the reference replica, add derivatives
+     216           0 :   if(!isreference_) {
+     217           0 :     for(unsigned i=0; i<getNumberOfAtoms(); ++i) setAtomsDerivatives(i, derivatives[i]);
+     218             :   }
+     219             :   // set virial
+     220           0 :   setBoxDerivativesNoPbc();
+     221           0 : }
+     222             : 
+     223             : }
+     224             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/index-sort-f.html b/coverage/isdb/index-sort-f.html new file mode 100644 index 000000000000..cba1d3e86899 --- /dev/null +++ b/coverage/isdb/index-sort-f.html @@ -0,0 +1,254 @@ + + + + + + + + LCOV - plumed test coverage - isdb + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdbHitTotalCoverage
Test:plumed test coverageLines:87831142876.9 %
Date:2024-04-19 12:12:35Functions:16323569.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
EMMIVox.cpp +
5.6%5.6%
+
5.6 %36 / 6483.8 %1 / 26
Rescale.cpp +
11.3%11.3%
+
11.3 %21 / 1868.3 %1 / 12
Shadow.cpp +
10.5%10.5%
+
10.5 %6 / 5720.0 %1 / 5
Selector.cpp +
84.6%84.6%
+
84.6 %11 / 1350.0 %2 / 4
Caliber.cpp +
78.9%78.9%
+
78.9 %116 / 14762.5 %5 / 8
EMMI.cpp +
75.6%75.6%
+
75.6 %589 / 77974.4 %29 / 39
FretEfficiency.cpp +
94.4%94.4%
+
94.4 %34 / 3675.0 %3 / 4
Select.cpp +
100.0%
+
100.0 %20 / 2075.0 %3 / 4
NOE.cpp +
98.1%98.1%
+
98.1 %102 / 10480.0 %4 / 5
PRE.cpp +
92.2%92.2%
+
92.2 %119 / 12980.0 %4 / 5
Jcoupling.cpp +
93.0%93.0%
+
93.0 %160 / 17280.0 %4 / 5
MetainferenceBase.cpp +
85.2%85.2%
+
85.2 %754 / 88582.1 %23 / 28
RDC.cpp +
93.9%93.9%
+
93.9 %170 / 18183.3 %5 / 6
Metainference.cpp +
84.3%84.3%
+
84.3 %739 / 87788.9 %24 / 27
SAXS.cpp +
79.9%79.9%
+
79.9 %4919 / 615491.3 %21 / 23
CS2Backbone.cpp +
94.7%94.7%
+
94.7 %916 / 96795.7 %22 / 23
MetainferenceBase.h +
97.3%97.3%
+
97.3 %71 / 73100.0 %11 / 11
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/index-sort-l.html b/coverage/isdb/index-sort-l.html new file mode 100644 index 000000000000..73a1150629e4 --- /dev/null +++ b/coverage/isdb/index-sort-l.html @@ -0,0 +1,254 @@ + + + + + + + + LCOV - plumed test coverage - isdb + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdbHitTotalCoverage
Test:plumed test coverageLines:87831142876.9 %
Date:2024-04-19 12:12:35Functions:16323569.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
EMMIVox.cpp +
5.6%5.6%
+
5.6 %36 / 6483.8 %1 / 26
Shadow.cpp +
10.5%10.5%
+
10.5 %6 / 5720.0 %1 / 5
Rescale.cpp +
11.3%11.3%
+
11.3 %21 / 1868.3 %1 / 12
EMMI.cpp +
75.6%75.6%
+
75.6 %589 / 77974.4 %29 / 39
Caliber.cpp +
78.9%78.9%
+
78.9 %116 / 14762.5 %5 / 8
SAXS.cpp +
79.9%79.9%
+
79.9 %4919 / 615491.3 %21 / 23
Metainference.cpp +
84.3%84.3%
+
84.3 %739 / 87788.9 %24 / 27
Selector.cpp +
84.6%84.6%
+
84.6 %11 / 1350.0 %2 / 4
MetainferenceBase.cpp +
85.2%85.2%
+
85.2 %754 / 88582.1 %23 / 28
PRE.cpp +
92.2%92.2%
+
92.2 %119 / 12980.0 %4 / 5
Jcoupling.cpp +
93.0%93.0%
+
93.0 %160 / 17280.0 %4 / 5
RDC.cpp +
93.9%93.9%
+
93.9 %170 / 18183.3 %5 / 6
FretEfficiency.cpp +
94.4%94.4%
+
94.4 %34 / 3675.0 %3 / 4
CS2Backbone.cpp +
94.7%94.7%
+
94.7 %916 / 96795.7 %22 / 23
MetainferenceBase.h +
97.3%97.3%
+
97.3 %71 / 73100.0 %11 / 11
NOE.cpp +
98.1%98.1%
+
98.1 %102 / 10480.0 %4 / 5
Select.cpp +
100.0%
+
100.0 %20 / 2075.0 %3 / 4
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/index.html b/coverage/isdb/index.html new file mode 100644 index 000000000000..ba9dca2ead1a --- /dev/null +++ b/coverage/isdb/index.html @@ -0,0 +1,254 @@ + + + + + + + + LCOV - plumed test coverage - isdb + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdbHitTotalCoverage
Test:plumed test coverageLines:87831142876.9 %
Date:2024-04-19 12:12:35Functions:16323569.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
CS2Backbone.cpp +
94.7%94.7%
+
94.7 %916 / 96795.7 %22 / 23
Caliber.cpp +
78.9%78.9%
+
78.9 %116 / 14762.5 %5 / 8
EMMI.cpp +
75.6%75.6%
+
75.6 %589 / 77974.4 %29 / 39
EMMIVox.cpp +
5.6%5.6%
+
5.6 %36 / 6483.8 %1 / 26
FretEfficiency.cpp +
94.4%94.4%
+
94.4 %34 / 3675.0 %3 / 4
Jcoupling.cpp +
93.0%93.0%
+
93.0 %160 / 17280.0 %4 / 5
Metainference.cpp +
84.3%84.3%
+
84.3 %739 / 87788.9 %24 / 27
MetainferenceBase.cpp +
85.2%85.2%
+
85.2 %754 / 88582.1 %23 / 28
MetainferenceBase.h +
97.3%97.3%
+
97.3 %71 / 73100.0 %11 / 11
NOE.cpp +
98.1%98.1%
+
98.1 %102 / 10480.0 %4 / 5
PRE.cpp +
92.2%92.2%
+
92.2 %119 / 12980.0 %4 / 5
RDC.cpp +
93.9%93.9%
+
93.9 %170 / 18183.3 %5 / 6
Rescale.cpp +
11.3%11.3%
+
11.3 %21 / 1868.3 %1 / 12
SAXS.cpp +
79.9%79.9%
+
79.9 %4919 / 615491.3 %21 / 23
Select.cpp +
100.0%
+
100.0 %20 / 2075.0 %3 / 4
Selector.cpp +
84.6%84.6%
+
84.6 %11 / 1350.0 %2 / 4
Shadow.cpp +
10.5%10.5%
+
10.5 %6 / 5720.0 %1 / 5
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/logmfd/LogMFD.cpp.func-sort-c.html b/coverage/logmfd/LogMFD.cpp.func-sort-c.html new file mode 100644 index 000000000000..36a5efdd76f1 --- /dev/null +++ b/coverage/logmfd/LogMFD.cpp.func-sort-c.html @@ -0,0 +1,125 @@ + + + + + + + + LCOV - plumed test coverage - logmfd/LogMFD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - logmfd - LogMFD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:32637187.9 %
Date:2024-04-19 12:12:35Functions:121392.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6logmfd6LogMFDC2ERKNS_13ActionOptionsE0
_ZN4PLMD6logmfd6LogMFDC1ERKNS_13ActionOptionsE3
_ZN4PLMD6logmfd6LogMFD16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD6logmfd6LogMFD8updateVSEv5
_ZN4PLMD6logmfd6LogMFD9updateNVEEv5
_ZN4PLMD6logmfd6LogMFD9updateNVTEv5
_ZN4PLMD6logmfd6LogMFD10updateWorkEv15
_ZN4PLMD6logmfd6LogMFD13calcMeanForceEv15
_ZN4PLMD6logmfd6LogMFD8calcClogEv40
_ZN4PLMD6logmfd6LogMFD8calcFlogEv55
_ZN4PLMD6logmfd6LogMFD8calcEkinEv83
_ZN4PLMD6logmfd6LogMFD6updateEv1500
_ZN4PLMD6logmfd6LogMFD9calculateEv1500
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/logmfd/LogMFD.cpp.func.html b/coverage/logmfd/LogMFD.cpp.func.html new file mode 100644 index 000000000000..21b313635218 --- /dev/null +++ b/coverage/logmfd/LogMFD.cpp.func.html @@ -0,0 +1,125 @@ + + + + + + + + LCOV - plumed test coverage - logmfd/LogMFD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - logmfd - LogMFD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:32637187.9 %
Date:2024-04-19 12:12:35Functions:121392.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6logmfd6LogMFD10updateWorkEv15
_ZN4PLMD6logmfd6LogMFD13calcMeanForceEv15
_ZN4PLMD6logmfd6LogMFD16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD6logmfd6LogMFD6updateEv1500
_ZN4PLMD6logmfd6LogMFD8calcClogEv40
_ZN4PLMD6logmfd6LogMFD8calcEkinEv83
_ZN4PLMD6logmfd6LogMFD8calcFlogEv55
_ZN4PLMD6logmfd6LogMFD8updateVSEv5
_ZN4PLMD6logmfd6LogMFD9calculateEv1500
_ZN4PLMD6logmfd6LogMFD9updateNVEEv5
_ZN4PLMD6logmfd6LogMFD9updateNVTEv5
_ZN4PLMD6logmfd6LogMFDC1ERKNS_13ActionOptionsE3
_ZN4PLMD6logmfd6LogMFDC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/logmfd/LogMFD.cpp.gcov.html b/coverage/logmfd/LogMFD.cpp.gcov.html new file mode 100644 index 000000000000..03d9a0d19f9c --- /dev/null +++ b/coverage/logmfd/LogMFD.cpp.gcov.html @@ -0,0 +1,1317 @@ + + + + + + + + LCOV - plumed test coverage - logmfd/LogMFD.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - logmfd - LogMFD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:32637187.9 %
Date:2024-04-19 12:12:35Functions:121392.3 %
+
+ + + + + + + + +

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

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
LogMFD.cpp +
87.9%87.9%
+
87.9 %326 / 37192.3 %12 / 13
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/logmfd/index-sort-l.html b/coverage/logmfd/index-sort-l.html new file mode 100644 index 000000000000..cf3f3742575d --- /dev/null +++ b/coverage/logmfd/index-sort-l.html @@ -0,0 +1,94 @@ + + + + + + + + LCOV - plumed test coverage - logmfd + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - logmfdHitTotalCoverage
Test:plumed test coverageLines:32637187.9 %
Date:2024-04-19 12:12:35Functions:121392.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
LogMFD.cpp +
87.9%87.9%
+
87.9 %326 / 37192.3 %12 / 13
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/logmfd/index.html b/coverage/logmfd/index.html new file mode 100644 index 000000000000..9849c2237a5e --- /dev/null +++ b/coverage/logmfd/index.html @@ -0,0 +1,94 @@ + + + + + + + + LCOV - plumed test coverage - logmfd + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - logmfdHitTotalCoverage
Test:plumed test coverageLines:32637187.9 %
Date:2024-04-19 12:12:35Functions:121392.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
LogMFD.cpp +
87.9%87.9%
+
87.9 %326 / 37192.3 %12 / 13
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/main/index-sort-f.html b/coverage/main/index-sort-f.html new file mode 100644 index 000000000000..790ed3566a5d --- /dev/null +++ b/coverage/main/index-sort-f.html @@ -0,0 +1,94 @@ + + + + + + + + LCOV - plumed test coverage - main + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mainHitTotalCoverage
Test:plumed test coverageLines:121580.0 %
Date:2024-04-19 12:12:35Functions:11100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
main.cpp +
80.0%80.0%
+
80.0 %12 / 15100.0 %1 / 1
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/main/index-sort-l.html b/coverage/main/index-sort-l.html new file mode 100644 index 000000000000..e79e924e8f43 --- /dev/null +++ b/coverage/main/index-sort-l.html @@ -0,0 +1,94 @@ + + + + + + + + LCOV - plumed test coverage - main + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mainHitTotalCoverage
Test:plumed test coverageLines:121580.0 %
Date:2024-04-19 12:12:35Functions:11100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
main.cpp +
80.0%80.0%
+
80.0 %12 / 15100.0 %1 / 1
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/main/index.html b/coverage/main/index.html new file mode 100644 index 000000000000..1c8fe33d94fb --- /dev/null +++ b/coverage/main/index.html @@ -0,0 +1,94 @@ + + + + + + + + LCOV - plumed test coverage - main + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mainHitTotalCoverage
Test:plumed test coverageLines:121580.0 %
Date:2024-04-19 12:12:35Functions:11100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
main.cpp +
80.0%80.0%
+
80.0 %12 / 15100.0 %1 / 1
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/main/main.cpp.func-sort-c.html b/coverage/main/main.cpp.func-sort-c.html new file mode 100644 index 000000000000..b89ea30e3241 --- /dev/null +++ b/coverage/main/main.cpp.func-sort-c.html @@ -0,0 +1,77 @@ + + + + + + + + LCOV - plumed test coverage - main/main.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - main - main.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:121580.0 %
Date:2024-04-19 12:12:35Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
main5040
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/main/main.cpp.func.html b/coverage/main/main.cpp.func.html new file mode 100644 index 000000000000..bcb8a780a102 --- /dev/null +++ b/coverage/main/main.cpp.func.html @@ -0,0 +1,77 @@ + + + + + + + + LCOV - plumed test coverage - main/main.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - main - main.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:121580.0 %
Date:2024-04-19 12:12:35Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
main5040
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/main/main.cpp.gcov.html b/coverage/main/main.cpp.gcov.html new file mode 100644 index 000000000000..7081e840cbc6 --- /dev/null +++ b/coverage/main/main.cpp.gcov.html @@ -0,0 +1,148 @@ + + + + + + + + LCOV - plumed test coverage - main/main.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - main - main.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:121580.0 %
Date:2024-04-19 12:12:35Functions: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        5040 : int main(int argc,char**argv) {
+      37             : #ifdef __PLUMED_HAS_MPI
+      38             :   bool nompi=false;
+      39       10501 :   for(unsigned iarg=1; iarg<argc; iarg++) {
+      40        9736 :     if(!std::strcmp(argv[iarg],"--no-mpi")) nompi=true;
+      41        9736 :     if(!std::strcmp(argv[iarg],"--mpi"))    nompi=false;
+      42             : // stop at first non-option
+      43        9736 :     if(argv[iarg] && argv[iarg][0]!='-') break;
+      44             :   }
+      45        5040 :   if(!nompi) MPI_Init(&argc,&argv);
+      46             : #endif
+      47        5040 :   int ret=0;
+      48             : 
+      49             :   try {
+      50             :     PLMD::Plumed p;
+      51             :     p.cmd("CLTool setArgc",&argc);
+      52        5040 :     p.cmd("CLTool setArgv",argv);
+      53             : #ifdef __PLUMED_HAS_MPI
+      54        5040 :     if(!nompi) {
+      55             :       MPI_Comm comm;
+      56         344 :       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        5040 :   if(!nompi) MPI_Finalize();
+      69             : #endif
+      70        5040 :   return ret;
+      71             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/AdaptivePath.cpp.func-sort-c.html b/coverage/mapping/AdaptivePath.cpp.func-sort-c.html new file mode 100644 index 000000000000..e079331139a9 --- /dev/null +++ b/coverage/mapping/AdaptivePath.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + 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:495098.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7mapping12AdaptivePathC2ERKNS_13ActionOptionsE0
_ZN4PLMD7mapping12AdaptivePathC1ERKNS_13ActionOptionsE2
_ZN4PLMD7mapping12AdaptivePath16registerKeywordsERNS_8KeywordsE6
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/AdaptivePath.cpp.func.html b/coverage/mapping/AdaptivePath.cpp.func.html new file mode 100644 index 000000000000..cbe9bbebf562 --- /dev/null +++ b/coverage/mapping/AdaptivePath.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + 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:495098.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7mapping12AdaptivePath16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD7mapping12AdaptivePathC1ERKNS_13ActionOptionsE2
_ZN4PLMD7mapping12AdaptivePathC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/AdaptivePath.cpp.gcov.html b/coverage/mapping/AdaptivePath.cpp.gcov.html new file mode 100644 index 000000000000..b7f381cac15f --- /dev/null +++ b/coverage/mapping/AdaptivePath.cpp.gcov.html @@ -0,0 +1,244 @@ + + + + + + + + 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:495098.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2020 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionShortcut.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "core/PlumedMain.h"
+      25             : #include "tools/PDB.h"
+      26             : #include "Path.h"
+      27             : 
+      28             : //+PLUMEDOC COLVAR ADAPTIVE_PATH
+      29             : /*
+      30             : Compute path collective variables that adapt to the lowest free energy path connecting states A and B.
+      31             : 
+      32             : The Path Collective Variables developed by Branduardi and co-workers \cite brand07 allow one
+      33             : to compute the progress along a high-dimensional path and the distance from the high-dimensional
+      34             : path.  The progress along the path (s) is computed using:
+      35             : 
+      36             : \f[
+      37             : 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}
+      38             : \f]
+      39             : 
+      40             : 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,
+      41             : 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
+      42             : vector connecting the closest frame to the second closest frame.  The distance from the path, \f$z\f$ is calculated using:
+      43             : 
+      44             : \f[
+      45             : 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 }
+      46             : \f]
+      47             : 
+      48             : 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
+      49             : 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.
+      50             : To learn more about how the path is adapted we strongly recommend reading this paper.
+      51             : 
+      52             : \par Examples
+      53             : 
+      54             : The input below provides an example that shows how the adaptive path works. The path is updated every 50 steps of
+      55             : MD based on the data accumulated during the preceding 50 time steps.
+      56             : 
+      57             : \plumedfile
+      58             : d1: DISTANCE ATOMS=1,2 COMPONENTS
+      59             : pp: ADAPTIVE_PATH TYPE=EUCLIDEAN FIXED=2,5 UPDATE=50 WFILE=out-path.pdb WSTRIDE=50 REFERENCE=mypath.pdb
+      60             : PRINT ARG=d1.x,d1.y,pp.* FILE=colvar
+      61             : \endplumedfile
+      62             : 
+      63             : 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
+      64             : atoms 1 and 2.  As such an extract from the input reference path (mypath.pdb) would look as follows:
+      65             : 
+      66             : \auxfile{mypath.pdb}
+      67             : REMARK ARG=d1.x,d1.y d1.x=1.12 d1.y=-.60
+      68             : END
+      69             : REMARK ARG=d1.x,d1.y d1.x=.99 d1.y=-.45
+      70             : END
+      71             : REMARK ARG=d1.x,d1.y d1.x=.86 d1.y=-.30
+      72             : END
+      73             : REMARK ARG=d1.x,d1.y d1.x=.73 d1.y=-.15
+      74             : END
+      75             : REMARK ARG=d1.x,d1.y d1.x=.60 d1.y=0
+      76             : END
+      77             : REMARK ARG=d1.x,d1.y d1.x=.47 d1.y=.15
+      78             : END
+      79             : \endauxfile
+      80             : 
+      81             : Notice that one can also use RMSD frames in place of arguments like those above.
+      82             : 
+      83             : */
+      84             : //+ENDPLUMEDOC
+      85             : 
+      86             : namespace PLMD {
+      87             : namespace mapping {
+      88             : 
+      89             : class AdaptivePath : public ActionShortcut {
+      90             : public:
+      91             :   static void registerKeywords( Keywords& keys );
+      92             :   explicit AdaptivePath(const ActionOptions&);
+      93             : };
+      94             : 
+      95             : PLUMED_REGISTER_ACTION(AdaptivePath,"ADAPTIVE_PATH")
+      96             : 
+      97           6 : void AdaptivePath::registerKeywords( Keywords& keys ) {
+      98           6 :   ActionShortcut::registerKeywords( keys ); Path::registerInputFileKeywords( keys );
+      99          12 :   keys.add("optional","PROPERTY","read in path coordinates by finding option with this label in remark of pdb frames");
+     100          12 :   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");
+     101          12 :   keys.add("compulsory","HALFLIFE","-1","the number of MD steps after which a previously measured path distance weighs only 50 percent 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");
+     102          12 :   keys.add("compulsory","UPDATE","the frequency with which the path should be updated");
+     103          12 :   keys.add("compulsory","TOLERANCE","1E-6","the tolerance to use for the path updating algorithm that makes all frames equidistant");
+     104          12 :   keys.add("optional","WFILE","file on which to write out the path");
+     105          12 :   keys.add("compulsory","FMT","%f","the format to use for output files");
+     106          12 :   keys.add("compulsory","WSTRIDE","frequency with which to write out the path");
+     107          12 :   keys.needsAction("GEOMETRIC_PATH"); keys.needsAction("AVERAGE_PATH_DISPLACEMENT");
+     108          12 :   keys.needsAction("REPARAMETERIZE_PATH"); keys.needsAction("DUMPPDB");
+     109          18 :   keys.needsAction("PDB2CONSTANT"); keys.needsAction("DISPLACEMENT"); keys.needsAction("CONSTANT");
+     110           6 : }
+     111             : 
+     112           2 : AdaptivePath::AdaptivePath(const ActionOptions& ao):
+     113             :   Action(ao),
+     114           2 :   ActionShortcut(ao)
+     115             : {
+     116             :   // Read in the arguments
+     117           4 :   std::vector<std::string> argnames; parseVector("ARG",argnames);
+     118           4 :   std::string reference_data, metric, mtype; parse("TYPE", mtype);
+     119           4 :   std::string reference; parse("REFERENCE",reference);
+     120           2 :   FILE* fp=std::fopen(reference.c_str(),"r"); PDB mypdb; if(!fp) error("could not open reference file " + reference );
+     121           2 :   bool do_read=mypdb.readFromFilepointer(fp,false,0.1); if( !do_read ) error("missing file " + reference );
+     122             :   // Create list of reference configurations that PLUMED will use
+     123           2 :   Path::readInputFrames( reference, mtype, argnames, true, this, reference_data );
+     124             :   // Now get coordinates on spath
+     125           4 :   std::vector<std::string> pnames; parseVector("PROPERTY",pnames); Path::readPropertyInformation( pnames, getShortcutLabel(), reference, this );
+     126             :   // Create action that computes the geometric path variablesa
+     127           3 :   std::string propstr = getShortcutLabel() + "_ind"; if( pnames.size()>0 ) propstr = pnames[0] + "_ref";
+     128           3 :   if( argnames.size()>0 ) readInputLine( getShortcutLabel() + ": GEOMETRIC_PATH ARG=" + getShortcutLabel() + "_data " + " PROPERTY=" + propstr + " REFERENCE=" + reference_data + " METRIC={DIFFERENCE}");
+     129             :   else {
+     130           1 :     std::string num, align_str, displace_str; Tools::convert( mypdb.getOccupancy()[0], align_str ); Tools::convert( mypdb.getBeta()[0], displace_str );
+     131          25 :     for(unsigned j=1; j<mypdb.getAtomNumbers().size(); ++j ) { Tools::convert( mypdb.getOccupancy()[j], num ); align_str += "," + num; Tools::convert( mypdb.getBeta()[0], num ); displace_str += "," + num; }
+     132           2 :     metric = "RMSD_VECTOR DISPLACEMENT TYPE=" + mtype + " ALIGN=" + align_str + " DISPLACE=" + displace_str;
+     133           2 :     readInputLine( getShortcutLabel() + ": GEOMETRIC_PATH ARG=" + getShortcutLabel() + "_data.disp " + " PROPERTY=" +  propstr + " REFERENCE=" + reference_data + " METRIC={" + metric + "} METRIC_COMPONENT=disp");
+     134             :   }
+     135             :   // Create the object to accumulate the average path displacements
+     136           8 :   std::string update, halflife; parse("HALFLIFE",halflife); parse("UPDATE",update); std::string refframes = " REFERENCE=" + getShortcutLabel() + "_pos";
+     137           3 :   if( argnames.size()>0 ) readInputLine( getShortcutLabel() + "_disp: AVERAGE_PATH_DISPLACEMENT ARG=" + getShortcutLabel() + "_data HALFLIFE=" + halflife + " CLEAR=" + update + " METRIC={DIFFERENCE} REFERENCE=" + reference_data );
+     138           2 :   else readInputLine( getShortcutLabel() + "_disp: AVERAGE_PATH_DISPLACEMENT ARG=" + getShortcutLabel() + "_data.disp HALFLIFE=" + halflife + " CLEAR=" + update + " METRIC={" + metric + "} METRIC_COMPONENT=disp REFERENCE=" + reference_data );
+     139             : 
+     140             :   // Create the object to update the path
+     141           4 :   std::string fixedn; parse("FIXED",fixedn); std::string component="METRIC_COMPONENT=disp"; if( argnames.size()>0 ) { metric="DIFFERENCE"; component=""; }
+     142           4 :   if( fixedn.length()>0 ) readInputLine("REPARAMETERIZE_PATH DISPLACE_FRAMES=" + getShortcutLabel() + "_disp FIXED=" + fixedn + " STRIDE=" + update + " METRIC={" + metric + "} " + component + " REFERENCE=" + reference_data );
+     143           0 :   else readInputLine("REPARAMETERIZE_PATH DISPLACE_FRAMES=" + getShortcutLabel() + "_disp STRIDE=" + update + " METRIC={" + metric + "} " + component + " REFERENCE=" + reference_data );
+     144             : 
+     145             :   // Information for write out
+     146           4 :   std::string wfilename; parse("WFILE",wfilename);
+     147           2 :   if( wfilename.length()>0 ) {
+     148             :     // This just gets the atom numbers for output
+     149             :     std::string atomstr;
+     150           2 :     if( argnames.size()==0 ) {
+     151           1 :       FILE* fp=std::fopen(reference.c_str(),"r"); double fake_unit=0.1; PDB mypdb; bool do_read=mypdb.readFromFilepointer(fp,false,fake_unit);
+     152           1 :       std::string num; Tools::convert( mypdb.getAtomNumbers()[0].serial(), atomstr );
+     153          13 :       for(unsigned j=1; j<mypdb.getAtomNumbers().size(); ++j ) { Tools::convert( mypdb.getAtomNumbers()[j].serial(), num ); atomstr += "," + num; }
+     154           1 :     }
+     155             : 
+     156           2 :     if( wfilename.find(".pdb")==std::string::npos ) error("output must be to a pdb file");
+     157           6 :     std::string ofmt, pframes, wstride; parse("WSTRIDE",wstride); parse("FMT",ofmt);
+     158           2 :     if( argnames.size()>0 ) {
+     159           3 :       std::string argstr = argnames[0]; for(unsigned i=1; i<argnames.size(); ++i) argstr += "," + argnames[i];
+     160           2 :       readInputLine("DUMPPDB DESCRIPTION=PATH STRIDE=" + wstride + " FMT=" + ofmt + " FILE=" + wfilename + " ARG=" + reference_data );
+     161           2 :     } else readInputLine("DUMPPDB DESCRIPTION=PATH STRIDE=" + wstride + " FMT=" + ofmt + " FILE=" + wfilename + " ATOMS=" + reference_data + " ATOM_INDICES=" + atomstr );
+     162             :   }
+     163           4 :   log<<"  Bibliography "<<plumed.cite("Diaz Leines and Ensing, Phys. Rev. Lett. 109, 020601 (2012)")<<"\n";
+     164           4 : }
+     165             : 
+     166             : }
+     167             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/GeometricPath.cpp.func-sort-c.html b/coverage/mapping/GeometricPath.cpp.func-sort-c.html new file mode 100644 index 000000000000..4a2585156f96 --- /dev/null +++ b/coverage/mapping/GeometricPath.cpp.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - mapping/GeometricPath.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mapping - GeometricPath.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:616298.4 %
Date:2024-04-19 12:12:35Functions:4666.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7mapping13GeometricPathC2ERKNS_13ActionOptionsE0
_ZNK4PLMD7mapping13GeometricPath11performTaskERKjRNS_10MultiValueE0
_ZN4PLMD7mapping13GeometricPathC1ERKNS_13ActionOptionsE4
_ZN4PLMD7mapping13GeometricPath16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD7mapping13GeometricPath9calculateEv1665
_ZN4PLMD7mapping13GeometricPath22getNumberOfDerivativesEv1677
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/GeometricPath.cpp.func.html b/coverage/mapping/GeometricPath.cpp.func.html new file mode 100644 index 000000000000..91543d650618 --- /dev/null +++ b/coverage/mapping/GeometricPath.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - mapping/GeometricPath.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mapping - GeometricPath.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:616298.4 %
Date:2024-04-19 12:12:35Functions:4666.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7mapping13GeometricPath16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD7mapping13GeometricPath22getNumberOfDerivativesEv1677
_ZN4PLMD7mapping13GeometricPath9calculateEv1665
_ZN4PLMD7mapping13GeometricPathC1ERKNS_13ActionOptionsE4
_ZN4PLMD7mapping13GeometricPathC2ERKNS_13ActionOptionsE0
_ZNK4PLMD7mapping13GeometricPath11performTaskERKjRNS_10MultiValueE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/GeometricPath.cpp.gcov.html b/coverage/mapping/GeometricPath.cpp.gcov.html new file mode 100644 index 000000000000..748c485b852b --- /dev/null +++ b/coverage/mapping/GeometricPath.cpp.gcov.html @@ -0,0 +1,216 @@ + + + + + + + + LCOV - plumed test coverage - mapping/GeometricPath.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mapping - GeometricPath.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:616298.4 %
Date:2024-04-19 12:12:35Functions:4666.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016,2017 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received 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/ActionWithVector.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "core/ActionSet.h"
+      25             : #include "PathProjectionCalculator.h"
+      26             : 
+      27             : //+PLUMEDOC COLVAR GEOMETRIC_PATH
+      28             : /*
+      29             : Distance along and from a path calculated using geometric formulas
+      30             : 
+      31             : \par Examples
+      32             : 
+      33             : */
+      34             : //+ENDPLUMEDOC
+      35             : 
+      36             : namespace PLMD {
+      37             : namespace mapping {
+      38             : 
+      39             : class GeometricPath : public ActionWithVector {
+      40             : private:
+      41             :   PathProjectionCalculator path_projector;
+      42             : public:
+      43             :   static void registerKeywords(Keywords& keys);
+      44             :   explicit GeometricPath(const ActionOptions&);
+      45             :   unsigned getNumberOfDerivatives() override ;
+      46             :   void calculate() override ;
+      47           0 :   void performTask( const unsigned& current, MultiValue& myvals ) const override { plumed_error(); }
+      48             : };
+      49             : 
+      50             : PLUMED_REGISTER_ACTION(GeometricPath,"GEOMETRIC_PATH")
+      51             : 
+      52           6 : void GeometricPath::registerKeywords(Keywords& keys) {
+      53           6 :   ActionWithVector::registerKeywords(keys); keys.use("ARG");
+      54           6 :   PathProjectionCalculator::registerKeywords(keys);
+      55          12 :   keys.add("compulsory","PROPERTY","the coordinates we are projecting these points onto");
+      56           6 :   componentsAreNotOptional(keys);
+      57          12 :   keys.addOutputComponent("s","default","the position on the path");
+      58          12 :   keys.addOutputComponent("z","default","the distance from the path");
+      59          12 :   keys.needsAction("GEOMETRIC_PATH"); keys.needsAction("PDB2CONSTANT");
+      60           6 : }
+      61             : 
+      62           4 : GeometricPath::GeometricPath(const ActionOptions&ao):
+      63             :   Action(ao),
+      64             :   ActionWithVector(ao),
+      65           4 :   path_projector(this)
+      66             : {
+      67           4 :   plumed_assert( !actionInChain() );
+      68             :   // Get the coordinates in the low dimensional space
+      69           8 :   std::vector<std::string> pcoord; parseVector("PROPERTY", pcoord ); std::vector<Value*> theprop;
+      70           4 :   ActionWithArguments::interpretArgumentList( pcoord, plumed.getActionSet(), this, theprop );
+      71           4 :   if( theprop.size()!=1 ) error("did not find property to project on");
+      72           4 :   if( theprop[0]->getNumberOfValues()!=getPntrToArgument(0)->getShape()[0] ) error("mismatch between number of frames and property of interest");
+      73           4 :   log.printf("  projecting onto : %s \n", theprop[0]->getName().c_str() );
+      74           4 :   std::vector<Value*> args( getArguments() ); args.push_back( theprop[0] ); requestArguments( args );
+      75             :   // Create the values to store the output
+      76          12 :   addComponentWithDerivatives("s"); componentIsNotPeriodic("s");
+      77          12 :   addComponentWithDerivatives("z"); componentIsNotPeriodic("z");
+      78           4 : }
+      79             : 
+      80        1677 : unsigned GeometricPath::getNumberOfDerivatives() {
+      81        1677 :   return getPntrToArgument(0)->getShape()[0]*getPntrToArgument(0)->getShape()[1] + getPntrToArgument(1)->getShape()[0];
+      82             : }
+      83             : 
+      84        1665 : void GeometricPath::calculate() {
+      85        1665 :   unsigned k=0, iclose1=0, iclose2=0; double v1v1=0, v3v3=0;
+      86        1665 :   unsigned nrows = getPntrToArgument(0)->getShape()[0];
+      87        1665 :   unsigned ncols = getPntrToArgument(0)->getShape()[1];
+      88       79201 :   for(unsigned i=0; i<nrows; ++i) {
+      89             :     double dist = 0;
+      90     1814580 :     for(unsigned j=0; j<ncols; ++j) {
+      91     1737044 :       double tmp = getPntrToArgument(0)->get(k);
+      92     1737044 :       dist += tmp*tmp; k++;
+      93             :     }
+      94       77536 :     if( i==0 ) { v1v1 = dist; iclose1 = 0; }
+      95       75871 :     else if( dist<v1v1 ) { v3v3=v1v1; v1v1=dist; iclose2=iclose1; iclose1=i; }
+      96       45571 :     else if( i==1 ) { v3v3=dist; iclose2=1; }
+      97       45244 :     else if( dist<v3v3 ) { v3v3=dist; iclose2=i; }
+      98             :   }
+      99             :   // And find third closest point
+     100        1665 :   int isign = iclose1 - iclose2;
+     101             :   if( isign>1 ) isign=1; else if( isign<-1 ) isign=-1;
+     102        1665 :   int iclose3 = iclose1 + isign;
+     103        1665 :   unsigned ifrom=iclose1, ito=iclose3; if( iclose3<0 || iclose3>=nrows ) { ifrom=iclose2; ito=iclose1; }
+     104             : 
+     105             :   // And calculate projection of vector connecting current point to closest frame on vector connecting nearest two frames
+     106        1665 :   std::vector<double> displace; path_projector.getDisplaceVector( ifrom, ito, displace );
+     107        1665 :   double v2v2=0, v1v2=0; k=ncols*iclose1;
+     108       42661 :   for(unsigned i=0; i<displace.size(); ++i) { v2v2 += displace[i]*displace[i]; v1v2 += displace[i]*getPntrToArgument(0)->get(k+i); }
+     109             : 
+     110             :   // This computes s value
+     111        1665 :   double spacing = getPntrToArgument(1)->get(iclose1) - getPntrToArgument(1)->get(iclose2);
+     112        1665 :   double root = sqrt( v1v2*v1v2 - v2v2 * ( v1v1 - v3v3) );
+     113        1665 :   double dx = 0.5 * ( (root + v1v2) / v2v2 - 1.);
+     114        1665 :   double path_s = getPntrToArgument(1)->get(iclose1) + spacing * dx;
+     115        1665 :   Value* sp = getPntrToComponent(0); sp->set( path_s );
+     116        1665 :   if( !doNotCalculateDerivatives() ) {
+     117       23478 :     for(unsigned i=0; i<ncols; ++i) {
+     118       22386 :       sp->addDerivative( ncols*iclose1 + i, 0.5*spacing*(v1v2*displace[i]/v2v2 - getPntrToArgument(0)->get(ncols*iclose1 + i))/root + 0.5*spacing*displace[i]/v2v2 );
+     119       22386 :       sp->addDerivative( ncols*iclose2 + i, 0.5*spacing*getPntrToArgument(0)->get(ncols*iclose2 + i)/root );
+     120             :     }
+     121             :   }
+     122             : 
+     123             :   // This computes z value
+     124        1665 :   path_projector.getDisplaceVector( iclose2, iclose1, displace ); double v4v4=0, proj=0; k=ncols*iclose1;
+     125       42661 :   for(unsigned i=0; i<displace.size(); ++i) { v4v4 += displace[i]*displace[i]; proj += displace[i]*getPntrToArgument(0)->get(k+i); }
+     126        1665 :   double path_z = v1v1 + dx*dx*v4v4 - 2*dx*proj; path_z = sqrt(path_z);
+     127        1665 :   Value* zp = getPntrToComponent(1); zp->set( path_z );
+     128        1665 :   if( !doNotCalculateDerivatives() ) {
+     129       23478 :     for(unsigned i=0; i<ncols; ++i) {
+     130       22386 :       zp->addDerivative( ncols*iclose1 + i, (1/path_z)*(getPntrToArgument(0)->get(ncols*iclose1 + i) +
+     131       22386 :                          (v4v4*dx-proj)*sp->getDerivative(ncols*iclose1 + i)/spacing -
+     132       22386 :                          dx*displace[i]) );
+     133       22386 :       zp->addDerivative( ncols*iclose2 + i, (v4v4*dx-proj)*sp->getDerivative(ncols*iclose2 + i)/(path_z*spacing) );
+     134             :     }
+     135             :   }
+     136        1665 : }
+     137             : 
+     138             : }
+     139             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/GeometricPathShortcut.cpp.func-sort-c.html b/coverage/mapping/GeometricPathShortcut.cpp.func-sort-c.html new file mode 100644 index 000000000000..7ea253fadd74 --- /dev/null +++ b/coverage/mapping/GeometricPathShortcut.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - mapping/GeometricPathShortcut.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mapping - GeometricPathShortcut.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2020100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7mapping21GeometricPathShortcutC2ERKNS_13ActionOptionsE0
_ZN4PLMD7mapping21GeometricPathShortcutC1ERKNS_13ActionOptionsE2
_ZN4PLMD7mapping21GeometricPathShortcut16registerKeywordsERNS_8KeywordsE8
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/GeometricPathShortcut.cpp.func.html b/coverage/mapping/GeometricPathShortcut.cpp.func.html new file mode 100644 index 000000000000..4fc5a37874ee --- /dev/null +++ b/coverage/mapping/GeometricPathShortcut.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - mapping/GeometricPathShortcut.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mapping - GeometricPathShortcut.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2020100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7mapping21GeometricPathShortcut16registerKeywordsERNS_8KeywordsE8
_ZN4PLMD7mapping21GeometricPathShortcutC1ERKNS_13ActionOptionsE2
_ZN4PLMD7mapping21GeometricPathShortcutC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/GeometricPathShortcut.cpp.gcov.html b/coverage/mapping/GeometricPathShortcut.cpp.gcov.html new file mode 100644 index 000000000000..37a1b1f7a234 --- /dev/null +++ b/coverage/mapping/GeometricPathShortcut.cpp.gcov.html @@ -0,0 +1,157 @@ + + + + + + + + LCOV - plumed test coverage - mapping/GeometricPathShortcut.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mapping - GeometricPathShortcut.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2020100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2018 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "Path.h"
+      23             : #include "tools/PDB.h"
+      24             : #include "core/ActionRegister.h"
+      25             : 
+      26             : //+PLUMEDOC COLVAR GPATH
+      27             : /*
+      28             : Distance along and from a path calculated using geometric formulas
+      29             : 
+      30             : 
+      31             : \par Examples
+      32             : 
+      33             : */
+      34             : //+ENDPLUMEDOC
+      35             : 
+      36             : namespace PLMD {
+      37             : namespace mapping {
+      38             : 
+      39             : class GeometricPathShortcut : public ActionShortcut {
+      40             : public:
+      41             :   static void registerKeywords(Keywords& keys);
+      42             :   explicit GeometricPathShortcut(const ActionOptions&);
+      43             : };
+      44             : 
+      45             : PLUMED_REGISTER_ACTION(GeometricPathShortcut,"GPATH")
+      46             : 
+      47           8 : void GeometricPathShortcut::registerKeywords( Keywords& keys ) {
+      48           8 :   ActionShortcut::registerKeywords( keys ); Path::registerInputFileKeywords( keys );
+      49          16 :   keys.add("optional","PROPERTY","read in path coordinates by finding option with this label in remark of pdb frames");
+      50          32 :   keys.needsAction("DISPLACEMENT"); keys.needsAction("GEOMETRIC_PATH"); keys.needsAction("PDB2CONSTANT"); keys.needsAction("CONSTANT");
+      51           8 : }
+      52             : 
+      53           2 : GeometricPathShortcut::GeometricPathShortcut( const ActionOptions& ao ):
+      54             :   Action(ao),
+      55           2 :   ActionShortcut(ao)
+      56             : {
+      57           6 :   std::string mtype, reference_data; std::vector<std::string> argnames; parseVector("ARG",argnames); parse("TYPE", mtype);
+      58             :   // Create list of reference configurations that PLUMED will use
+      59           4 :   std::string reference; parse("REFERENCE",reference);
+      60           2 :   FILE* fp=std::fopen(reference.c_str(),"r"); PDB mypdb; if(!fp) error("could not open reference file " + reference );
+      61           2 :   bool do_read=mypdb.readFromFilepointer(fp,false,0.1); if( !do_read ) error("missing file " + reference );
+      62           2 :   Path::readInputFrames( reference, mtype, argnames, true, this, reference_data );
+      63             :   // Now get coordinates on spath
+      64           4 :   std::vector<std::string> pnames; parseVector("PROPERTY",pnames); Path::readPropertyInformation( pnames, getShortcutLabel(), reference, this );
+      65             :   // Create action that computes the geometric path variablesa
+      66           2 :   std::string propstr = getShortcutLabel() + "_ind"; if( pnames.size()>0 ) propstr = pnames[0] + "_ref";
+      67           3 :   if( argnames.size()>0 ) readInputLine( getShortcutLabel() + ": GEOMETRIC_PATH ARG=" + getShortcutLabel() + "_data " + " PROPERTY=" + propstr + " REFERENCE=" + reference_data + " METRIC={DIFFERENCE}");
+      68             :   else {
+      69           1 :     std::string num, align_str, displace_str; Tools::convert( mypdb.getOccupancy()[0], align_str ); Tools::convert( mypdb.getBeta()[0], displace_str );
+      70          25 :     for(unsigned j=1; j<mypdb.getAtomNumbers().size(); ++j ) { Tools::convert( mypdb.getOccupancy()[j], num ); align_str += "," + num; Tools::convert( mypdb.getBeta()[0], num ); displace_str += "," + num; }
+      71           2 :     std::string metric = "RMSD_VECTOR DISPLACEMENT TYPE=" + mtype + " ALIGN=" + align_str + " DISPLACE=" + displace_str;
+      72           2 :     readInputLine( getShortcutLabel() + ": GEOMETRIC_PATH ARG=" + getShortcutLabel() + "_data.disp " + " PROPERTY=" +  propstr + " REFERENCE=" + reference_data + " METRIC={" + metric + "} METRIC_COMPONENT=disp");
+      73             :   }
+      74           6 : }
+      75             : 
+      76             : 
+      77             : }
+      78             : }
+      79             : 
+      80             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/PCAVars.cpp.func-sort-c.html b/coverage/mapping/PCAVars.cpp.func-sort-c.html new file mode 100644 index 000000000000..ee35de556621 --- /dev/null +++ b/coverage/mapping/PCAVars.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + 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:868996.6 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7mapping7PCAVarsC2ERKNS_13ActionOptionsE0
_ZN4PLMD7mapping7PCAVarsC1ERKNS_13ActionOptionsE5
_ZN4PLMD7mapping7PCAVars16registerKeywordsERNS_8KeywordsE9
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/PCAVars.cpp.func.html b/coverage/mapping/PCAVars.cpp.func.html new file mode 100644 index 000000000000..c2eb2d19fd9e --- /dev/null +++ b/coverage/mapping/PCAVars.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + 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:868996.6 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7mapping7PCAVars16registerKeywordsERNS_8KeywordsE9
_ZN4PLMD7mapping7PCAVarsC1ERKNS_13ActionOptionsE5
_ZN4PLMD7mapping7PCAVarsC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/PCAVars.cpp.gcov.html b/coverage/mapping/PCAVars.cpp.gcov.html new file mode 100644 index 000000000000..614919d4d9f3 --- /dev/null +++ b/coverage/mapping/PCAVars.cpp.gcov.html @@ -0,0 +1,377 @@ + + + + + + + + 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:868996.6 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2018 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionShortcut.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "core/PlumedMain.h"
+      25             : #include "core/ActionWithArguments.h"
+      26             : #include "tools/PDB.h"
+      27             : #include "Path.h"
+      28             : 
+      29             : namespace PLMD {
+      30             : namespace mapping {
+      31             : 
+      32             : //+PLUMEDOC COLVAR PCAVARS
+      33             : /*
+      34             : Projection on principal component eigenvectors or other high dimensional linear subspace
+      35             : 
+      36             : The collective variables described in \ref dists allow one to calculate the distance between the
+      37             : instantaneous structure adopted by the system and some high-dimensional, reference configuration.  The
+      38             : problem with doing this is that, as one gets further and further from the reference configuration, the
+      39             : distance from it becomes a progressively poorer and poorer collective variable.  This happens because
+      40             : the ``number" of structures at a distance \f$d\f$ from a reference configuration is proportional to \f$d^N\f$ in
+      41             : an \f$N\f$ dimensional space.  Consequently, when \f$d\f$ is small the distance from the reference configuration
+      42             : may well be a good collective variable.  However, when \f$d\f$ is large it is unlikely that the distance from the reference
+      43             : structure is a good CV.  When the distance is large there will almost certainly be markedly different
+      44             : configuration that have the same CV value and hence barriers in transverse degrees of
+      45             : freedom.
+      46             : 
+      47             : For these reasons dimensionality reduction is often employed so a projection \f$\mathbf{s}\f$ of a high-dimensional configuration
+      48             : \f$\mathbf{X}\f$ in a lower dimensionality space using a function:
+      49             : 
+      50             : \f[
+      51             : \mathbf{s} = F(\mathbf{X}-\mathbf{X}^{ref})
+      52             : \f]
+      53             : 
+      54             : where here we have introduced some high-dimensional reference configuration \f$\mathbf{X}^{ref}\f$.  By far the simplest way to
+      55             : do this is to use some linear operator for \f$F\f$.  That is to say we find a low-dimensional projection
+      56             : by rotating the basis vectors using some linear algebra:
+      57             : 
+      58             : \f[
+      59             : \mathbf{s}_i = \sum_k A_{ik} ( X_{k} - X_{k}^{ref} )
+      60             : \f]
+      61             : 
+      62             : 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
+      63             : the dimensionality of the lower dimensional subspace.  In plumed when this kind of projection you can use the majority
+      64             : of the metrics detailed on \ref dists to calculate the displacement, \f$\mathbf{X}-\mathbf{X}^{ref}\f$, from the reference configuration.
+      65             : The matrix \f$A\f$ can be found by various means including principal component analysis and normal mode analysis.  In both these methods the
+      66             : rows of \f$A\f$ would be the principle eigenvectors of a square matrix.  For PCA the covariance while for normal modes the Hessian.
+      67             : 
+      68             : \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.
+      69             : 
+      70             : \par Examples
+      71             : 
+      72             : The following input calculates a projection on a linear subspace where the displacements
+      73             : from the reference configuration are calculated using the OPTIMAL metric.  Consequently,
+      74             : both translation of the center of mass of the atoms and rotation of the reference
+      75             : frame are removed from these displacements.  The matrix \f$A\f$ and the reference
+      76             : configuration \f$R^{ref}\f$ are specified in the pdb input file reference.pdb and the
+      77             : value of all projections (and the residual) are output to a file called colvar2.
+      78             : 
+      79             : \plumedfile
+      80             : PCAVARS REFERENCE=reference.pdb TYPE=OPTIMAL LABEL=pca2
+      81             : PRINT ARG=pca2.* FILE=colvar2
+      82             : \endplumedfile
+      83             : 
+      84             : The reference configurations can be specified using a pdb file.  The first configuration that you provide is the reference configuration,
+      85             : which is referred to in the above as \f$X^{ref}\f$ subsequent configurations give the directions of row vectors that are contained in
+      86             : the matrix \f$A\f$ above.  These directions are specified by giving a second configuration that describes the components of \f$A\f$ explicitly.
+      87             : 
+      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             : ATOM      9  CA  ALA     2      19.462 -11.088  -8.986  1.00  1.00
+      92             : ATOM     13  HB2 ALA     2      21.112 -10.688 -12.476  1.00  1.00
+      93             : ATOM     15  C   ALA     2      19.422   7.978 -14.536  1.00  1.00
+      94             : ATOM     20 HH31 NME     3      20.122  -9.928 -17.746  1.00  1.00
+      95             : ATOM     21 HH32 NME     3      18.572 -13.148 -16.346  1.00  1.00
+      96             : END
+      97             : REMARK
+      98             : ATOM      2  CH3 ACE     1      0.1414  0.3334 -0.0302  1.00  0.00
+      99             : ATOM      5  C   ACE     1      0.0893 -0.1095 -0.1434  1.00  0.00
+     100             : ATOM      9  CA  ALA     2      0.0207 -0.321   0.0321  1.00  0.00
+     101             : ATOM     13  HB2 ALA     2      0.0317 -0.6085  0.0783  1.00  0.00
+     102             : ATOM     15  C   ALA     2      0.1282 -0.4792  0.0797  1.00  0.00
+     103             : ATOM     20 HH31 NME     3      0.0053 -0.465   0.0309  1.00  0.00
+     104             : ATOM     21 HH32 NME     3     -0.1019 -0.4261 -0.0082  1.00  0.00
+     105             : END
+     106             : \endverbatim
+     107             : 
+     108             : Notice that the PCAVARS command is a shortcut.  If you look at how the shortcut in the above input is expanded you should be able to see how the command works
+     109             : by calculating the RMSD displacement between the instantaneous and reference configuration and how those displacements are then projected on the eigenvector that
+     110             : was specified in the second frame of the pdb input above. Understanding the expanded version of this shortcut command allows you to recognise that you can project
+     111             : the displacement vector on any arbitrary vector.  For example in the input below two reference structures are provided in the pdb file. PLUMED calculates the RMSD
+     112             : distance between these two reference configurations during setup and sets up a unit vector called eig that points along the director connecting the two RMSD structure.
+     113             : During the calculation the vector connecting the instantaneous configuration and the first of the two reference configurations in computed.  This vector is then projected
+     114             : on the unit vector connecting the two initial structures:
+     115             : 
+     116             : \plumedfile
+     117             : # Read in two reference configuratioms from PDB file
+     118             : ref1: PDB2CONSTANT REFERENCE=two-frames.pdb NUMBER=1
+     119             : ref1T: TRANSPOSE ARG=ref1
+     120             : ref2: PDB2CONSTANT REFERENCE=two-frames.pdb NUMBER=2
+     121             : # Calculate the displacement vector that takes you from ref1 to ref2
+     122             : eigu: RMSD_VECTOR ARG=ref1T,ref2 DISPLACEMENT TYPE=OPTIMAL
+     123             : # Normalise the reference vector
+     124             : eigu2: CUSTOM ARG=eigu.disp FUNC=x*x PERIODIC=NO
+     125             : eign2: SUM ARG=eigu2 PERIODIC=NO
+     126             : eig: CUSTOM ARG=eigu.disp,eign2 FUNC=x/sqrt(y) PERIODIC=NO
+     127             : eigT: TRANSPOSE ARG=eig
+     128             : # Everything prior to this point is only done in setup.  From here onwards we have the commands that are done during the main calculate loop.
+     129             : 
+     130             : # Calculate the RMSD displacement between the instaneous structure and the first reference structure
+     131             : rmsd: RMSD REFERENCE=two-frames.pdb NUMBER=1 TYPE=OPTIMAL DISPLACEMENT SQUARED
+     132             : # Project the displacement computed above on the director of the vector that connects reference structure ref1 to refeference structure ref2
+     133             : pca: MATRIX_VECTOR_PRODUCT ARG=eigT,rmsd.disp
+     134             : 
+     135             : # Print the final CV to a file
+     136             : PRINT ARG=pca FILE=colvar
+     137             : \endplumedfile
+     138             : 
+     139             : You also project vectors of differences of arguments on reference vectors.  For example, the input below can be used to look at the projection
+     140             : of the vector connecting the instantanous configuraiton to a reference point in CV on a reference vector that has been specified in the PDB file.
+     141             : 
+     142             : \plumedfile
+     143             : d1: DISTANCE ATOMS=1,2
+     144             : d2: DISTANCE ATOMS=3,4
+     145             : d3: DISTANCE ATOMS=5,6
+     146             : pca: PCAVARS ARG=d1,d2,d3 REFERENCE=epath.pdb
+     147             : PRINT ARG=pca_eig-1,pca_residual FILE=colvar
+     148             : \endplumedfile
+     149             : 
+     150             : The pdb input file for this calculation might look something like this:
+     151             : 
+     152             : \verbatim
+     153             : REMARK d1=0.1221 d2=0.0979 d3=0.1079
+     154             : END
+     155             : REMARK d1=0.078811 d2=-0.945732 d3=-0.315244
+     156             : END
+     157             : \endverbatim
+     158             : 
+     159             : The first set of argument values in this input file are the reference values for the arguments.  The second any subsquent sets of arguments give the
+     160             : coefficients that should be used when constructing linear combinations.
+     161             : 
+     162             : Notice, lastly, that you can also use a combination of argument values and atomic positions when specifying the reference configuration and the reference
+     163             : directions.  If you are doing something this complicated, however, you are perhaps better working with the PLUMED input directly rather than this shortcut
+     164             : as you will need to take special measures to ensure that all your CVs are in the same units.
+     165             : 
+     166             : */
+     167             : //+ENDPLUMEDOC
+     168             : 
+     169             : class PCAVars : public ActionShortcut {
+     170             : public:
+     171             :   static void registerKeywords(Keywords& keys);
+     172             :   explicit PCAVars(const ActionOptions&);
+     173             : };
+     174             : 
+     175             : 
+     176             : PLUMED_REGISTER_ACTION(PCAVars,"PCAVARS")
+     177             : 
+     178           9 : void PCAVars::registerKeywords( Keywords& keys ) {
+     179           9 :   ActionShortcut::registerKeywords( keys );
+     180          18 :   keys.add("compulsory","REFERENCE","a pdb file containing the set of reference configurations");
+     181          18 :   keys.add("compulsory","TYPE","OPTIMAL-FAST","the manner in which distances are calculated. More information on the different "
+     182             :            "metrics that are available in PLUMED can be found in the section of the manual on "
+     183             :            "\\ref dists");
+     184          18 :   keys.add("optional","ARG","if there are arguments to be used specify them here");
+     185          18 :   keys.addFlag("NOPBC",false,"do not use periodic boundary conditions when computing this quantity");
+     186          18 :   keys.addOutputComponent("eig","default","the projections on the eigenvalues");
+     187          18 :   keys.addOutputComponent("residual","default","the residual distance that is not projected on any of the eigenvalues");
+     188          27 :   keys.needsAction("RMSD"); keys.needsAction("PDB2CONSTANT"); keys.needsAction("TRANSPOSE");
+     189          36 :   keys.needsAction("EUCLIDEAN_DISTANCE"); keys.needsAction("CONCATENATE"); keys.needsAction("COMBINE"); keys.needsAction("CONSTANT");
+     190          36 :   keys.needsAction("COMBINE"); keys.needsAction("MATRIX_VECTOR_PRODUCT"); keys.needsAction("CUSTOM"); keys.needsAction("SUM");
+     191           9 :   keys.needsAction("SELECT_COMPONENTS");
+     192           9 : }
+     193             : 
+     194           5 : PCAVars::PCAVars( const ActionOptions& ao ):
+     195             :   Action(ao),
+     196           5 :   ActionShortcut(ao)
+     197             : {
+     198          10 :   std::string reference; parse("REFERENCE",reference);
+     199             :   // Create the object that holds the atomic positions by reading the first frame
+     200           5 :   FILE* fp=std::fopen(reference.c_str(),"r"); PDB pdb; if(!fp) error("could not open reference file " + reference );
+     201           5 :   bool do_read=pdb.readFromFilepointer(fp,false,0.1); if( !do_read ) plumed_merror("missing file " + reference );
+     202           5 :   std::string mtype; parse("TYPE",mtype);
+     203             : 
+     204           5 :   if( pdb.getPositions().size()>0 ) {
+     205             :     // And now create the rmsd object
+     206           3 :     std::string rmsd_line =  getShortcutLabel() + "_at: RMSD DISPLACEMENT SQUARED NUMBER=1 REFERENCE=" + reference;
+     207           6 :     bool nopbc; parseFlag("NOPBC",nopbc); if(nopbc) rmsd_line += " NOPBC";
+     208             :     // Now create the RMSD object
+     209           6 :     readInputLine( rmsd_line + " TYPE=" + mtype );
+     210             :   }
+     211          10 :   std::vector<std::string> argnames; parseVector("ARG",argnames); unsigned nargs=0; std::string instargs, refargs; std::vector<Value*> theargs;
+     212           5 :   if( argnames.size()>0 ) ActionWithArguments::interpretArgumentList( argnames, plumed.getActionSet(), this, theargs );
+     213           9 :   for(unsigned i=0; i<theargs.size(); ++i) {
+     214           4 :     std::string iargn = Path::fixArgumentName( theargs[i]->getName() ); nargs += theargs[i]->getNumberOfValues();
+     215           4 :     if( theargs[i]->getNumberOfValues()>1 ) {
+     216           2 :       readInputLine( getShortcutLabel() + "_ref_" + iargn + "T: PDB2CONSTANT NUMBER=1 REFERENCE=" + reference + " ARG=" + theargs[i]->getName() );
+     217           2 :       readInputLine( getShortcutLabel() + "_ref_" + iargn + ": TRANSPOSE ARG=" + getShortcutLabel() + "_ref_" + iargn + "T");
+     218           6 :     } else readInputLine( getShortcutLabel() + "_ref_" + iargn + ": PDB2CONSTANT NUMBER=1 REFERENCE=" + reference + " ARG=" + theargs[i]->getName() );
+     219           8 :     if( i==0 ) { instargs=" ARG1=" + theargs[i]->getName(); refargs=" ARG2=" + getShortcutLabel() + "_ref_" + iargn; }
+     220           6 :     else { instargs +="," + theargs[i]->getName(); refargs +="," + getShortcutLabel() + "_ref_" + iargn; }
+     221             :   }
+     222           7 :   if( theargs.size()>0 ) readInputLine( getShortcutLabel() + "_argdist: EUCLIDEAN_DISTANCE SQUARED" + instargs + refargs );
+     223           5 :   if( pdb.getPositions().size()>0 && theargs.size()>0 ) {
+     224           0 :     readInputLine( getShortcutLabel() + ": CONCATENATE ARG=" + getShortcutLabel() + "_at.disp," + getShortcutLabel() + "_argdist_diffT");
+     225           0 :     readInputLine( getShortcutLabel() + "_dist: COMBINE ARG=" + getShortcutLabel() + "_at.dist," + getShortcutLabel() + "_argdist PERIODIC=NO");
+     226             :   }
+     227             : 
+     228             :   // Get the displace stuff
+     229           5 :   std::vector<double> displace( pdb.getBeta() ); double dtot = 0;
+     230          26 :   for(unsigned i=0; i<displace.size(); ++i) dtot += displace[i];
+     231          26 :   for(unsigned i=0; i<displace.size(); ++i) displace[i] = displace[i] / dtot;
+     232             : 
+     233             :   // Now read in the directions and create matheval objects to compute the pca components
+     234           5 :   unsigned nfram=0, ncomp=0; std::string pvec;
+     235          13 :   while( do_read ) {
+     236          13 :     std::vector<double> argdir(nargs); PDB mypdb; do_read=mypdb.readFromFilepointer(fp,plumed.usingNaturalUnits(),0.1/plumed.getUnits().getLength());
+     237          13 :     if( do_read ) {
+     238           8 :       nfram++;
+     239             :       // Normalize the eigenvector in the input
+     240             :       double norm=0;
+     241          50 :       for(unsigned i=0; i<mypdb.getPositions().size(); ++i) {
+     242          42 :         norm += mypdb.getPositions()[i][0]*mypdb.getPositions()[i][0];
+     243          42 :         norm += mypdb.getPositions()[i][1]*mypdb.getPositions()[i][1];
+     244          42 :         norm += mypdb.getPositions()[i][2]*mypdb.getPositions()[i][2];
+     245             :       }
+     246             :       unsigned k=0;
+     247          12 :       for(unsigned i=0; i<theargs.size(); ++i) {
+     248           4 :         std::vector<double> argval( theargs[i]->getNumberOfValues() );
+     249           4 :         if( !mypdb.getArgumentValue(theargs[i]->getName(), argval) ) error("argument " + theargs[i]->getName() + " was not set in pdb input");
+     250          10 :         for(unsigned j=0; j<argval.size(); ++j) { argdir[k] = argval[j]; norm += argdir[k]*argdir[k]; k++; }
+     251             :       }
+     252           8 :       norm = sqrt( norm ); std::vector<double> normed_coeffs( 3*mypdb.getPositions().size() );
+     253          50 :       for(unsigned i=0; i<mypdb.getPositions().size(); ++i) {
+     254          42 :         if( mtype=="SIMPLE" ) {
+     255          28 :           normed_coeffs[0*mypdb.getPositions().size()+i] = mypdb.getPositions()[i][0] / norm;
+     256          28 :           normed_coeffs[1*mypdb.getPositions().size()+i] = mypdb.getPositions()[i][1] / norm;
+     257          28 :           normed_coeffs[2*mypdb.getPositions().size()+i] = mypdb.getPositions()[i][2] / norm;
+     258             :         } else {
+     259          14 :           normed_coeffs[0*mypdb.getPositions().size()+i] = sqrt(displace[i])*mypdb.getPositions()[i][0] / norm;
+     260          14 :           normed_coeffs[1*mypdb.getPositions().size()+i] = sqrt(displace[i])*mypdb.getPositions()[i][1] / norm;
+     261          14 :           normed_coeffs[2*mypdb.getPositions().size()+i] = sqrt(displace[i])*mypdb.getPositions()[i][2] / norm;
+     262             :         }
+     263             :       }
+     264             :       std::string coeff1;
+     265           8 :       if( mypdb.getPositions().size()>0 ) {
+     266           6 :         if( nfram==1 ) Tools::convert( normed_coeffs[0], pvec );
+     267           6 :         else { Tools::convert( normed_coeffs[0], coeff1 ); pvec += "," + coeff1; }
+     268         126 :         for(unsigned i=1; i<normed_coeffs.size(); ++i) {
+     269         120 :           Tools::convert( normed_coeffs[i], coeff1 );
+     270         240 :           pvec += "," + coeff1;
+     271             :         }
+     272           6 :         for(unsigned i=0; i<argdir.size(); ++i) { Tools::convert( argdir[i] / norm, coeff1 ); pvec += "," + coeff1; }
+     273           2 :       } else if( theargs.size()>0 ) {
+     274           2 :         if( nfram==1 ) Tools::convert( argdir[0] / norm, pvec );
+     275           0 :         else { Tools::convert( argdir[0] / norm, coeff1 ); pvec += "," + coeff1; }
+     276           6 :         for(unsigned i=1; i<argdir.size(); ++i) { Tools::convert( argdir[i] / norm, coeff1 ); pvec += "," + coeff1; }
+     277             :       }
+     278           8 :       ncomp = 3*mypdb.getPositions().size() + nargs;
+     279             :     } else { break; }
+     280          13 :   }
+     281           5 :   std::fclose(fp); std::string neig, ncols; Tools::convert( nfram, neig ); Tools::convert( ncomp, ncols );
+     282          10 :   readInputLine( getShortcutLabel() + "_peig: CONSTANT VALUES=" + pvec + " NROWS=" + neig + " NCOLS=" + ncols );
+     283           5 :   if( pdb.getPositions().size()>0 && theargs.size()>0 ) readInputLine( getShortcutLabel() + "_eig: MATRIX_VECTOR_PRODUCT ARG=" + getShortcutLabel() + "_peig," + getShortcutLabel() );
+     284           8 :   else if( pdb.getPositions().size()>0 ) readInputLine( getShortcutLabel() + "_eig: MATRIX_VECTOR_PRODUCT ARG=" + getShortcutLabel() + "_peig," + getShortcutLabel() + "_at.disp");
+     285           4 :   else if( theargs.size()>0 ) readInputLine( getShortcutLabel() + "_eig: MATRIX_VECTOR_PRODUCT ARG=" + getShortcutLabel() + "_peig," + getShortcutLabel() + "_argdist_diffT");
+     286          13 :   for(unsigned i=0; i<nfram; ++i) {
+     287           8 :     std::string num; Tools::convert( i+1, num );
+     288          16 :     readInputLine( getShortcutLabel() + "_eig-" + num + ": SELECT_COMPONENTS ARG=" + getShortcutLabel() + "_eig COMPONENTS=" + num );
+     289             :   }
+     290          10 :   readInputLine( getShortcutLabel() + "_eig2: CUSTOM ARG=" + getShortcutLabel() + "_eig FUNC=x*x PERIODIC=NO");
+     291          10 :   readInputLine( getShortcutLabel() + "_eigsum2: SUM ARG=" +  getShortcutLabel() + "_eig2 PERIODIC=NO");
+     292           5 :   if( pdb.getPositions().size()>0 && theargs.size()>0 ) readInputLine( getShortcutLabel() + "_residual: CUSTOM ARG=" + getShortcutLabel() + "_dist," + getShortcutLabel() + "_eigsum2 FUNC=sqrt(x-y) PERIODIC=NO");
+     293           8 :   else if( pdb.getPositions().size()>0 ) readInputLine( getShortcutLabel() + "_residual: CUSTOM ARG=" + getShortcutLabel() + "_at.dist," + getShortcutLabel() + "_eigsum2 FUNC=sqrt(x-y) PERIODIC=NO");
+     294           4 :   else if( theargs.size()>0 ) readInputLine( getShortcutLabel() + "_residual: CUSTOM ARG=" + getShortcutLabel() + "_argdist," + getShortcutLabel() + "_eigsum2 FUNC=sqrt(x-y) PERIODIC=NO");
+     295          15 : }
+     296             : 
+     297             : }
+     298             : }
+     299             : 
+     300             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/Path.cpp.func-sort-c.html b/coverage/mapping/Path.cpp.func-sort-c.html new file mode 100644 index 000000000000..99ae3f43e84b --- /dev/null +++ b/coverage/mapping/Path.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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:9310291.2 %
Date:2024-04-19 12:12:35Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7mapping4PathC2ERKNS_13ActionOptionsE0
_ZN4PLMD7mapping4PathC1ERKNS_13ActionOptionsE10
_ZN4PLMD7mapping4Path15readInputFramesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_RSt6vectorIS7_SaIS7_EERKbPNS_14ActionShortcutERS7_14
_ZN4PLMD7mapping4Path16registerKeywordsERNS_8KeywordsE14
_ZN4PLMD7mapping4Path23readPropertyInformationERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_SE_PNS_14ActionShortcutE15
_ZN4PLMD7mapping4Path15fixArgumentNameERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE19
_ZN4PLMD7mapping4Path25registerInputFileKeywordsERNS_8KeywordsE32
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/Path.cpp.func.html b/coverage/mapping/Path.cpp.func.html new file mode 100644 index 000000000000..1eacd471ba24 --- /dev/null +++ b/coverage/mapping/Path.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:9310291.2 %
Date:2024-04-19 12:12:35Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7mapping4Path15fixArgumentNameERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE19
_ZN4PLMD7mapping4Path15readInputFramesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_RSt6vectorIS7_SaIS7_EERKbPNS_14ActionShortcutERS7_14
_ZN4PLMD7mapping4Path16registerKeywordsERNS_8KeywordsE14
_ZN4PLMD7mapping4Path23readPropertyInformationERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_SE_PNS_14ActionShortcutE15
_ZN4PLMD7mapping4Path25registerInputFileKeywordsERNS_8KeywordsE32
_ZN4PLMD7mapping4PathC1ERKNS_13ActionOptionsE10
_ZN4PLMD7mapping4PathC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/Path.cpp.gcov.html b/coverage/mapping/Path.cpp.gcov.html new file mode 100644 index 000000000000..0931a929fac8 --- /dev/null +++ b/coverage/mapping/Path.cpp.gcov.html @@ -0,0 +1,424 @@ + + + + + + + + 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:9310291.2 %
Date:2024-04-19 12:12:35Functions: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 "Path.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "core/ActionWithValue.h"
+      25             : #include "core/ActionWithArguments.h"
+      26             : #include "core/PlumedMain.h"
+      27             : #include "core/ActionSet.h"
+      28             : #include "tools/PDB.h"
+      29             : 
+      30             : //+PLUMEDOC COLVAR PATH
+      31             : /*
+      32             : Path collective variables with a more flexible framework for the distance metric being used.
+      33             : 
+      34             : The Path Collective Variables developed by Branduardi and co-workers \cite brand07 allow one
+      35             : to compute the progress along a high-dimensional path and the distance from the high-dimensional
+      36             : path.  The progress along the path (s) is computed using:
+      37             : 
+      38             : \f[
+      39             : s = \frac{ \sum_{i=1}^N i \exp( -\lambda R[X - X_i] ) }{ \sum_{i=1}^N \exp( -\lambda R[X - X_i] ) }
+      40             : \f]
+      41             : 
+      42             : while the distance from the path (z) is measured using:
+      43             : 
+      44             : \f[
+      45             : z = -\frac{1}{\lambda} \ln\left[ \sum_{i=1}^N \exp( -\lambda R[X - X_i] ) \right]
+      46             : \f]
+      47             : 
+      48             : In these expressions \f$N\f$ high-dimensional frames (\f$X_i\f$) are used to describe the path in the high-dimensional
+      49             : space. The two expressions above are then functions of the distances from each of the high-dimensional frames \f$R[X - X_i]\f$.
+      50             : Within PLUMED there are multiple ways to define the distance from a high-dimensional configuration.  You could calculate
+      51             : the RMSD distance or you could calculate the amount by which a set of collective variables change.  As such this implementation
+      52             : of the path CV allows one to use all the difference distance metrics that are discussed in \ref dists. This is as opposed to
+      53             : the alternative implementation of path (\ref PATHMSD) which is a bit faster but which only allows one to use the RMSD distance.
+      54             : 
+      55             : The \f$s\f$ and \f$z\f$ variables are calculated using the above formulas by default.  However, there is an alternative method
+      56             : of calculating these collective variables, which is detailed in \cite bernd-path.  This alternative method uses the tools of
+      57             : geometry (as opposed to algebra, which is used in the equations above).  In this alternative formula the progress along the path
+      58             : \f$s\f$ is calculated using:
+      59             : 
+      60             : \f[
+      61             : 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}
+      62             : \f]
+      63             : 
+      64             : 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,
+      65             : 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
+      66             : vector connecting the closest frame to the second closest frame.  The distance from the path, \f$z\f$ is calculated using:
+      67             : 
+      68             : \f[
+      69             : 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 }
+      70             : \f]
+      71             : 
+      72             : 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.
+      73             : The values of \f$s\f$ and \f$z\f$ can then be referenced using the gspath and gzpath labels.
+      74             : 
+      75             : \par Examples
+      76             : 
+      77             : In the example below the path is defined using RMSD distance from frames.
+      78             : 
+      79             : \plumedfile
+      80             : p1: PATH REFERENCE=file.pdb TYPE=OPTIMAL LAMBDA=500.0
+      81             : PRINT ARG=p1.spath,p1.zpath STRIDE=1 FILE=colvar FMT=%8.4f
+      82             : \endplumedfile
+      83             : 
+      84             : The reference frames in the path are defined in the pdb file shown below.  In this frame
+      85             : each configuration in the path is separated by a line containing just the word END.
+      86             : 
+      87             : \auxfile{file.pdb}
+      88             : ATOM      1  CL  ALA     1      -3.171   0.295   2.045  1.00  1.00
+      89             : ATOM      5  CLP ALA     1      -1.819  -0.143   1.679  1.00  1.00
+      90             : ATOM      6  OL  ALA     1      -1.177  -0.889   2.401  1.00  1.00
+      91             : ATOM      7  NL  ALA     1      -1.313   0.341   0.529  1.00  1.00
+      92             : END
+      93             : ATOM      1  CL  ALA     1      -3.175   0.365   2.024  1.00  1.00
+      94             : ATOM      5  CLP ALA     1      -1.814  -0.106   1.685  1.00  1.00
+      95             : ATOM      6  OL  ALA     1      -1.201  -0.849   2.425  1.00  1.00
+      96             : ATOM      7  NL  ALA     1      -1.296   0.337   0.534  1.00  1.00
+      97             : END
+      98             : ATOM      1  CL  ALA     1      -2.990   0.383   2.277  1.00  1.00
+      99             : ATOM      5  CLP ALA     1      -1.664  -0.085   1.831  1.00  1.00
+     100             : ATOM      6  OL  ALA     1      -0.987  -0.835   2.533  1.00  1.00
+     101             : ATOM      7  NL  ALA     1      -1.227   0.364   0.646  1.00  1.00
+     102             : END
+     103             : \endauxfile
+     104             : 
+     105             : In the example below the path is defined using the values of two torsional angles (t1 and t2).
+     106             : In addition, the \f$s\f$ and \f$z\f$ are calculated using the geometric expressions described
+     107             : above rather than the algebraic expressions that are used by default.
+     108             : 
+     109             : \plumedfile
+     110             : t1: TORSION ATOMS=5,7,9,15
+     111             : t2: TORSION ATOMS=7,9,15,17
+     112             : pp: PATH TYPE=EUCLIDEAN REFERENCE=epath.pdb GPATH NOSPATH NOZPATH
+     113             : PRINT ARG=pp.* FILE=colvar
+     114             : \endplumedfile
+     115             : 
+     116             : Notice that the LAMBDA parameter is not required here as we are not calculating \f$s\f$ and \f$s\f$
+     117             : using the algebraic formulas defined earlier.  The positions of the frames in the path are defined
+     118             : in the file epath.pdb.  An extract from this file looks as shown below.
+     119             : 
+     120             : \auxfile{epath.pdb}
+     121             : REMARK ARG=t1,t2 t1=-4.25053  t2=3.88053
+     122             : END
+     123             : REMARK ARG=t1,t2 t1=-4.11     t2=3.75
+     124             : END
+     125             : REMARK ARG=t1,t2 t1=-3.96947  t2=3.61947
+     126             : END
+     127             : \endauxfile
+     128             : 
+     129             : The remarks in this pdb file tell PLUMED the labels that are being used to define the position in the
+     130             : high dimensional space and the values that these arguments have at each point on the path.
+     131             : 
+     132             : */
+     133             : //+ENDPLUMEDOC
+     134             : 
+     135             : //+PLUMEDOC COLVAR GPROPERTYMAP
+     136             : /*
+     137             : Property maps but with a more flexible framework for the distance metric being used.
+     138             : 
+     139             : This colvar calculates a property map using the formalism developed by Spiwok \cite Spiwok:2011ce.
+     140             : In essence if you have the value of some property, \f$X_i\f$, that it takes at a set of high-dimensional
+     141             : positions then you calculate the value of the property at some arbitrary point in the high-dimensional space
+     142             : using:
+     143             : 
+     144             : \f[
+     145             : X=\frac{\sum_i X_i*\exp(-\lambda D_i(x))}{\sum_i  \exp(-\lambda D_i(x))}
+     146             : \f]
+     147             : 
+     148             : Within PLUMED there are multiple ways to define the distance from a high-dimensional configuration, \f$D_i\f$.  You could calculate
+     149             : the RMSD distance or you could calculate the amount by which a set of collective variables change.  As such this implementation
+     150             : of the property map allows one to use all the different distance metric that are discussed in \ref dists. This is as opposed to
+     151             : the alternative implementation \ref PROPERTYMAP which is a bit faster but which only allows one to use the RMSD distance.
+     152             : 
+     153             : \par Examples
+     154             : 
+     155             : The input shown below can be used to calculate the interpolated values of two properties called X and Y based on the values
+     156             : that these properties take at a set of reference configurations and using the formula above.  For this input the distances
+     157             : between the reference configurations and the instantaneous configurations are calculated using the OPTIMAL metric that is
+     158             : discussed at length in the manual pages on \ref RMSD.
+     159             : 
+     160             : \plumedfile
+     161             : p2: GPROPERTYMAP REFERENCE=allv.pdb PROPERTY=X,Y LAMBDA=69087
+     162             : PRINT ARG=p2.X,p2.Y,p2.zpath STRIDE=1 FILE=colvar
+     163             : \endplumedfile
+     164             : 
+     165             : The additional input file for this calculation, which contains the reference frames and the values of X and Y at these reference
+     166             : points has the following format.
+     167             : 
+     168             : \auxfile{allv.pdb}
+     169             : REMARK X=1 Y=2
+     170             : ATOM      1  CL  ALA     1      -3.171   0.295   2.045  1.00  1.00
+     171             : ATOM      5  CLP ALA     1      -1.819  -0.143   1.679  1.00  1.00
+     172             : ATOM      6  OL  ALA     1      -1.177  -0.889   2.401  1.00  1.00
+     173             : ATOM      7  NL  ALA     1      -1.313   0.341   0.529  1.00  1.00
+     174             : ATOM      8  HL  ALA     1      -1.845   0.961  -0.011  1.00  1.00
+     175             : ATOM      9  CA  ALA     1      -0.003  -0.019   0.021  1.00  1.00
+     176             : ATOM     10  HA  ALA     1       0.205  -1.051   0.259  1.00  1.00
+     177             : ATOM     11  CB  ALA     1       0.009   0.135  -1.509  1.00  1.00
+     178             : ATOM     15  CRP ALA     1       1.121   0.799   0.663  1.00  1.00
+     179             : ATOM     16  OR  ALA     1       1.723   1.669   0.043  1.00  1.00
+     180             : ATOM     17  NR  ALA     1       1.423   0.519   1.941  1.00  1.00
+     181             : ATOM     18  HR  ALA     1       0.873  -0.161   2.413  1.00  1.00
+     182             : ATOM     19  CR  ALA     1       2.477   1.187   2.675  1.00  1.00
+     183             : END
+     184             : FIXED
+     185             : REMARK X=2 Y=3
+     186             : ATOM      1  CL  ALA     1      -3.175   0.365   2.024  1.00  1.00
+     187             : ATOM      5  CLP ALA     1      -1.814  -0.106   1.685  1.00  1.00
+     188             : ATOM      6  OL  ALA     1      -1.201  -0.849   2.425  1.00  1.00
+     189             : ATOM      7  NL  ALA     1      -1.296   0.337   0.534  1.00  1.00
+     190             : ATOM      8  HL  ALA     1      -1.807   0.951  -0.044  1.00  1.00
+     191             : ATOM      9  CA  ALA     1       0.009  -0.067   0.033  1.00  1.00
+     192             : ATOM     10  HA  ALA     1       0.175  -1.105   0.283  1.00  1.00
+     193             : ATOM     11  CB  ALA     1       0.027   0.046  -1.501  1.00  1.00
+     194             : ATOM     15  CRP ALA     1       1.149   0.725   0.654  1.00  1.00
+     195             : ATOM     16  OR  ALA     1       1.835   1.491  -0.011  1.00  1.00
+     196             : ATOM     17  NR  ALA     1       1.380   0.537   1.968  1.00  1.00
+     197             : ATOM     18  HR  ALA     1       0.764  -0.060   2.461  1.00  1.00
+     198             : ATOM     19  CR  ALA     1       2.431   1.195   2.683  1.00  1.00
+     199             : END
+     200             : \endauxfile
+     201             : 
+     202             : */
+     203             : //+ENDPLUMEDOC
+     204             : 
+     205             : namespace PLMD {
+     206             : namespace mapping {
+     207             : 
+     208             : PLUMED_REGISTER_ACTION(Path,"PATH")
+     209             : PLUMED_REGISTER_ACTION(Path,"GPROPERTYMAP")
+     210             : 
+     211          14 : void Path::registerKeywords( Keywords& keys ) {
+     212          14 :   ActionShortcut::registerKeywords( keys ); Path::registerInputFileKeywords( keys );
+     213          28 :   keys.add("optional","PROPERTY","the property to be used in the index. This should be in the REMARK of the reference");
+     214          28 :   keys.add("compulsory","LAMBDA","the lambda parameter is needed for smoothing, is in the units of plumed");
+     215          14 : }
+     216             : 
+     217          32 : void Path::registerInputFileKeywords( Keywords& keys ) {
+     218          64 :   keys.add("compulsory","REFERENCE","a pdb file containing the set of reference configurations");
+     219          64 :   keys.add("compulsory","TYPE","OPTIMAL-FAST","the manner in which distances are calculated. More information on the different "
+     220             :            "metrics that are available in PLUMED can be found in the section of the manual on "
+     221             :            "\\ref dists");
+     222          64 :   keys.add("optional","ARG","the list of arguments you would like to use in your definition of the path");
+     223          64 :   keys.add("optional","COEFFICIENTS","the coefficients of the displacements along each argument that should be used when calculating the euclidean distance");
+     224          64 :   keys.addFlag("NOPBC",false,"ignore the periodic boundary conditions when calculating distances");
+     225          64 :   keys.addFlag("NOSPATH",false,"do not calculate the spath CV");
+     226          64 :   keys.addFlag("NOZPATH",false,"do not calculate the zpath CV");
+     227          64 :   keys.addFlag("GPATH",false,"calculate the trigonometric path");
+     228         128 :   keys.needsAction("DRMSD"); keys.needsAction("RMSD"); keys.needsAction("LOWEST"); keys.needsAction("GPATH");
+     229         128 :   keys.needsAction("EUCLIDEAN_DISTANCE"); keys.needsAction("CUSTOM"); keys.needsAction("SUM"); keys.needsAction("COMBINE");
+     230          96 :   keys.needsAction("NORMALIZED_EUCLIDEAN_DISTANCE"); keys.needsAction("PDB2CONSTANT"); keys.needsAction("CONSTANT");
+     231          64 :   keys.addOutputComponent("gspath","GPATH","the position along the path calculated using the geometric formula");
+     232          64 :   keys.addOutputComponent("gzpath","GPATH","the distance from the path calculated using the geometric formula");
+     233          64 :   keys.addOutputComponent("spath","GPATH","the position along the path calculated using the geometric formula");
+     234          64 :   keys.addOutputComponent("zpath","GPATH","the distance from the path calculated using the geometric formula");
+     235          32 : }
+     236             : 
+     237          10 : Path::Path( const ActionOptions& ao ):
+     238             :   Action(ao),
+     239          10 :   ActionShortcut(ao)
+     240             : {
+     241          30 :   bool nospath, nozpath, gpath; parseFlag("NOSPATH",nospath); parseFlag("NOZPATH",nozpath); parseFlag("GPATH",gpath);
+     242          10 :   if( gpath ) {
+     243           0 :     readInputLine( getShortcutLabel() + ": GPATH " + convertInputLineToString() );
+     244           0 :     readInputLine( getShortcutLabel() + "_gspath: COMBINE ARG=" + getShortcutLabel() + ".s PERIODIC=NO");
+     245           0 :     readInputLine( getShortcutLabel() + "_gzpath: COMBINE ARG=" + getShortcutLabel() + ".s PERIODIC=NO");
+     246             :   }
+     247          10 :   if( nospath && nozpath ) return;
+     248             :   // Setup the properties
+     249             :   std::vector<std::string> properties, pnames;
+     250          10 :   if( getName()=="PATH") { properties.resize(1); }
+     251           6 :   else { parseVector("PROPERTY",pnames); properties.resize( pnames.size() ); }
+     252          20 :   std::string type, reference_data, reference; parse("REFERENCE",reference);
+     253          20 :   std::vector<std::string> argnames; parseVector("ARG",argnames); parse("TYPE",type);
+     254          11 :   if( type.find("DRMSD")!=std::string::npos ) readInputLine( getShortcutLabel() + "_data: DRMSD SQUARED TYPE=" + type + " REFERENCE=" + reference );
+     255           9 :   else readInputFrames( reference, type, argnames, false, this, reference_data );
+     256             :   // Find the shortest distance to the frames
+     257          20 :   readInputLine( getShortcutLabel() + "_mindist: LOWEST ARG=" + getShortcutLabel() + "_data");
+     258             :   // Now create all other parts of the calculation
+     259          10 :   std::string lambda; parse("LAMBDA",lambda);
+     260             :   // Now create MATHEVAL object to compute exponential functions
+     261          20 :   readInputLine( getShortcutLabel() + "_weights: CUSTOM ARG=" + getShortcutLabel() + "_data," + getShortcutLabel() + "_mindist FUNC=exp(-(x-y)*" + lambda + ") PERIODIC=NO" );
+     262             :   // Create denominator
+     263          20 :   readInputLine( getShortcutLabel() + "_denom: SUM ARG=" + getShortcutLabel() + "_weights PERIODIC=NO");
+     264             :   // Now compte zpath variable
+     265          10 :   if( !nozpath ) {
+     266          20 :     readInputLine( getShortcutLabel() + "_z: CUSTOM ARG=" + getShortcutLabel() + "_denom," + getShortcutLabel() + "_mindist FUNC=y-log(x)/" + lambda + " PERIODIC=NO");
+     267          20 :     readInputLine( getShortcutLabel() + "_zpath: COMBINE ARG=" + getShortcutLabel() + "_z PERIODIC=NO");
+     268             :   }
+     269             :   // Now get coefficients for properies for spath
+     270          10 :   readPropertyInformation( pnames, getShortcutLabel(), reference, this );
+     271             :   // Now create COMBINE objects to compute numerator of path
+     272          23 :   for(unsigned i=0; i<properties.size(); ++i) {
+     273          13 :     if( pnames.size()>0 ) {
+     274          12 :       readInputLine( pnames[i] + "_numer_prod: CUSTOM ARG=" + getShortcutLabel() + "_weights," + pnames[i] + "_ref FUNC=x*y PERIODIC=NO");
+     275          12 :       readInputLine( pnames[i] + "_numer: SUM ARG=" + pnames[i]  + "_numer_prod PERIODIC=NO");
+     276          12 :       readInputLine( getShortcutLabel() + "_" + pnames[i] + ": CUSTOM ARG=" + pnames[i]  + "_numer," + getShortcutLabel() + "_denom FUNC=x/y PERIODIC=NO");
+     277           7 :     } else if( !nospath ) {
+     278          14 :       readInputLine( getShortcutLabel() + "_s_prod: CUSTOM ARG=" + getShortcutLabel() + "_weights," + getShortcutLabel() + "_ind FUNC=x*y PERIODIC=NO");
+     279          14 :       readInputLine( getShortcutLabel()  + "_numer: SUM ARG=" + getShortcutLabel() + "_s_prod PERIODIC=NO");
+     280          14 :       readInputLine( getShortcutLabel() + "_s: CUSTOM ARG=" + getShortcutLabel() + "_numer," + getShortcutLabel() + "_denom FUNC=x/y PERIODIC=NO");
+     281          14 :       readInputLine( getShortcutLabel() + "_spath: COMBINE ARG=" + getShortcutLabel() + "_s PERIODIC=NO");
+     282             :     }
+     283             :   }
+     284          20 : }
+     285             : 
+     286          19 : std::string Path::fixArgumentName( const std::string& argin ) {
+     287          19 :   std::string argout = argin; std::size_t dot=argin.find(".");
+     288          23 :   if( dot!=std::string::npos ) argout = argin.substr(0,dot) + "_" + argin.substr(dot+1);
+     289          19 :   return argout;
+     290             : }
+     291             : 
+     292          14 : void Path::readInputFrames( const std::string& reference, const std::string& type, std::vector<std::string>& argnames, const bool& displacements, ActionShortcut* action, std::string& reference_data ) {
+     293          14 :   FILE* fp=std::fopen(reference.c_str(),"r"); PDB pdb; if(!fp) action->error("could not open reference file " + reference );
+     294          14 :   bool do_read=pdb.readFromFilepointer(fp,false,0.1); if( !do_read ) action->error("missing file " + reference );
+     295          14 :   if( pdb.getPositions().size()!=0 && argnames.size()==0 ) {
+     296           9 :     reference_data = action->getShortcutLabel() + "_data_ref";
+     297          11 :     if( displacements ) action->readInputLine( action->getShortcutLabel() + "_data: RMSD DISPLACEMENT SQUARED REFERENCE=" + reference + " TYPE=" + type );
+     298          14 :     else action->readInputLine( action->getShortcutLabel() + "_data: RMSD SQUARED REFERENCE=" + reference + " TYPE=" + type );
+     299           5 :   } else if( pdb.getPositions().size()!=0 ) {
+     300           0 :     reference_data = action->getShortcutLabel() + "_atomdata_ref";
+     301           0 :     if( displacements ) action->readInputLine( action->getShortcutLabel() + "_atomdata: RMSD DISPLACEMENT SQUARED REFERENCE=" + reference + " TYPE=" + type );
+     302           0 :     else action->readInputLine( action->getShortcutLabel() + "_atomdata: RMSD SQUARED REFERENCE=" + reference + " TYPE=" + type );
+     303           5 :   } else if( argnames.size()==0 ) {
+     304           0 :     argnames.resize( pdb.getArgumentNames().size() );
+     305           0 :     for(unsigned i=0; i<argnames.size(); ++i) argnames[i] = pdb.getArgumentNames()[i];
+     306             :   }
+     307          14 :   std::vector<Value*> theargs; if( argnames.size()>0 ) ActionWithArguments::interpretArgumentList( argnames, action->plumed.getActionSet(), action, theargs );
+     308             : 
+     309          14 :   if( theargs.size()>0 ) {
+     310             :     std::string instargs, refargs;
+     311          20 :     for(unsigned i=0; i<theargs.size(); ++i) {
+     312          15 :       std::string iargn = fixArgumentName( theargs[i]->getName() );
+     313          30 :       action->readInputLine( action->getShortcutLabel() + "_ref_" + iargn + ": PDB2CONSTANT REFERENCE=" + reference + " ARG=" + theargs[i]->getName() );
+     314          25 :       if( i==0 ) { instargs=" ARG1=" + theargs[i]->getName(); refargs=" ARG2=" + action->getShortcutLabel() + "_ref_" + iargn; }
+     315          30 :       else { instargs +="," + theargs[i]->getName(); refargs +="," + action->getShortcutLabel() + "_ref_" + iargn; }
+     316          20 :       if( pdb.getPositions().size()==0 && i==0 ) reference_data = action->getShortcutLabel() + "_ref_" + iargn;
+     317          20 :       else reference_data += "," + action->getShortcutLabel() + "_ref_" + iargn;
+     318             :     }
+     319          10 :     std::string comname="EUCLIDEAN_DISTANCE SQUARED"; std::string coeffstr; action->parse("COEFFICIENTS",coeffstr);
+     320           5 :     if( coeffstr.length()>0 ) {
+     321           1 :       if( displacements ) action->error("cannot use COEFFICIENTS arguments with GEOMETRIC PATH");
+     322           2 :       action->readInputLine( action->getShortcutLabel() + "_coeff: CONSTANT VALUES=" + coeffstr );
+     323           2 :       action->readInputLine( action->getShortcutLabel() + "_coeff2: CUSTOM ARG=" + action->getShortcutLabel() + "_coeff FUNC=x*x PERIODIC=NO");
+     324           2 :       comname = "NORMALIZED_EUCLIDEAN_DISTANCE SQUARED METRIC=" + action->getShortcutLabel() + "_coeff2";
+     325           4 :     } else if( displacements ) comname = "DISPLACEMENT";
+     326             : 
+     327          10 :     if( pdb.getPositions().size()==0 ) action->readInputLine( action->getShortcutLabel() + "_data: " + comname + instargs + refargs );
+     328           0 :     else action->readInputLine( action->getShortcutLabel() + "_argdata: " + comname + instargs + refargs );
+     329             :   }
+     330          14 : }
+     331             : 
+     332          15 : void Path::readPropertyInformation( const std::vector<std::string>& pnames, const std::string& lab, const std::string& refname, ActionShortcut* action ) {
+     333          15 :   if( pnames.size()>0 ) {
+     334          15 :     for(unsigned i=0; i<pnames.size(); ++i) {
+     335          20 :       action->readInputLine( pnames[i] + ": CONSTANT VALUE=1");
+     336          20 :       action->readInputLine( pnames[i] + "_ref: PDB2CONSTANT REFERENCE=" + refname + " ARG=" + pnames[i] );
+     337             :     }
+     338             :   } else {
+     339          10 :     ActionWithValue* av=action->plumed.getActionSet().selectWithLabel<ActionWithValue*>( lab + "_data" );
+     340          10 :     unsigned nfram = av->copyOutput(0)->getShape()[0]; std::string indices = "VALUES=1";
+     341         850 :     for(unsigned i=1; i<nfram; ++i) { std::string num; Tools::convert( i+1, num ); indices += "," + num; }
+     342          20 :     action->readInputLine( lab + "_ind: CONSTANT " + indices );
+     343             :   }
+     344          15 : }
+     345             : 
+     346             : }
+     347             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/PathDisplacements.cpp.func-sort-c.html b/coverage/mapping/PathDisplacements.cpp.func-sort-c.html new file mode 100644 index 000000000000..58c16a403690 --- /dev/null +++ b/coverage/mapping/PathDisplacements.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - mapping/PathDisplacements.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mapping - PathDisplacements.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:697295.8 %
Date:2024-04-19 12:12:35Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7mapping17PathDisplacements22getNumberOfDerivativesEv0
_ZN4PLMD7mapping17PathDisplacementsC2ERKNS_13ActionOptionsE0
_ZN4PLMD7mapping17PathDisplacementsC1ERKNS_13ActionOptionsE2
_ZN4PLMD7mapping17PathDisplacements16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD7mapping17PathDisplacements16clearDerivativesERKb573
_ZN4PLMD7mapping17PathDisplacements5applyEv573
_ZN4PLMD7mapping17PathDisplacements6updateEv573
_ZN4PLMD7mapping17PathDisplacements9calculateEv573
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/PathDisplacements.cpp.func.html b/coverage/mapping/PathDisplacements.cpp.func.html new file mode 100644 index 000000000000..62c6a2c1a89f --- /dev/null +++ b/coverage/mapping/PathDisplacements.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - mapping/PathDisplacements.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mapping - PathDisplacements.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:697295.8 %
Date:2024-04-19 12:12:35Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7mapping17PathDisplacements16clearDerivativesERKb573
_ZN4PLMD7mapping17PathDisplacements16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD7mapping17PathDisplacements22getNumberOfDerivativesEv0
_ZN4PLMD7mapping17PathDisplacements5applyEv573
_ZN4PLMD7mapping17PathDisplacements6updateEv573
_ZN4PLMD7mapping17PathDisplacements9calculateEv573
_ZN4PLMD7mapping17PathDisplacementsC1ERKNS_13ActionOptionsE2
_ZN4PLMD7mapping17PathDisplacementsC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/PathDisplacements.cpp.gcov.html b/coverage/mapping/PathDisplacements.cpp.gcov.html new file mode 100644 index 000000000000..8c0ab3533258 --- /dev/null +++ b/coverage/mapping/PathDisplacements.cpp.gcov.html @@ -0,0 +1,253 @@ + + + + + + + + LCOV - plumed test coverage - mapping/PathDisplacements.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mapping - PathDisplacements.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:697295.8 %
Date:2024-04-19 12:12:35Functions:6875.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2018 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received 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/ActionPilot.h"
+      24             : #include "core/ActionWithArguments.h"
+      25             : #include "core/ActionRegister.h"
+      26             : #include "tools/Matrix.h"
+      27             : #include "PathProjectionCalculator.h"
+      28             : 
+      29             : //+PLUMEDOC ANALYSIS AVERAGE_PATH_DISPLACEMENT
+      30             : /*
+      31             : Accumulate the distances between the reference frames in the paths and the configurations visited
+      32             : 
+      33             : \par Examples
+      34             : 
+      35             : */
+      36             : //+ENDPLUMEDOC
+      37             : 
+      38             : namespace PLMD {
+      39             : namespace mapping {
+      40             : 
+      41             : class PathDisplacements : public ActionWithValue, public ActionPilot, public ActionWithArguments {
+      42             : private:
+      43             :   bool clearnextstep;
+      44             :   unsigned clearstride;
+      45             :   double fadefact;
+      46             :   std::vector<double> wsum, displace_v;
+      47             :   Matrix<double> displacements;
+      48             :   PathProjectionCalculator path_projector;
+      49             : public:
+      50             :   static void registerKeywords( Keywords& keys );
+      51             :   explicit PathDisplacements(const ActionOptions&);
+      52             :   unsigned getNumberOfDerivatives();
+      53         573 :   void clearDerivatives( const bool& force=false ) {}
+      54         573 :   void calculate() {}
+      55         573 :   void apply() {}
+      56             :   void update();
+      57             : };
+      58             : 
+      59             : PLUMED_REGISTER_ACTION(PathDisplacements,"AVERAGE_PATH_DISPLACEMENT")
+      60             : 
+      61           4 : void PathDisplacements::registerKeywords( Keywords& keys ) {
+      62           4 :   Action::registerKeywords( keys ); ActionWithValue::registerKeywords( keys ); ActionPilot::registerKeywords( keys );
+      63           8 :   ActionWithArguments::registerKeywords( keys ); keys.use("ARG"); PathProjectionCalculator::registerKeywords( keys );
+      64           8 :   keys.add("compulsory","STRIDE","1","the frequency with which the average displacements should be collected and added to the average displacements");
+      65           8 :   keys.add("compulsory","HALFLIFE","-1","the number of MD steps after which a previously measured path distance weighs only 50 percent 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");
+      66           8 :   keys.add("compulsory","CLEAR","0","the frequency with which to clear all the accumulated data.  The default value "
+      67             :            "of 0 implies that all the data will be used and that the grid will never be cleared");
+      68           4 : }
+      69             : 
+      70           2 : PathDisplacements::PathDisplacements(const ActionOptions& ao):
+      71             :   Action(ao),
+      72             :   ActionWithValue(ao),
+      73             :   ActionPilot(ao),
+      74             :   ActionWithArguments(ao),
+      75           2 :   clearnextstep(false),
+      76           2 :   path_projector(this)
+      77             : {
+      78             :   // Read in clear instructions
+      79           2 :   parse("CLEAR",clearstride);
+      80           2 :   if( clearstride>0 ) {
+      81           2 :     if( clearstride%getStride()!=0 ) error("CLEAR parameter must be a multiple of STRIDE");
+      82           2 :     log.printf("  clearing average every %u steps \n",clearstride);
+      83             :   }
+      84           2 :   double halflife; parse("HALFLIFE",halflife);
+      85           2 :   log.printf("  weight of contribution to frame halves every %f steps \n",halflife);
+      86           2 :   if( halflife<0 ) fadefact=1.0;
+      87           0 :   else fadefact = exp( -0.693147180559945 / static_cast<double>(halflife) );
+      88             :   // Now create the weights vector and displacements matrix
+      89           2 :   unsigned nrows = getPntrToArgument(0)->getShape()[0];
+      90           2 :   unsigned ncols = getPntrToArgument(0)->getShape()[1];
+      91           2 :   wsum.resize( nrows ); displacements.resize( nrows, ncols );
+      92          64 :   for(unsigned i=0; i<nrows; ++i) {
+      93        1740 :     wsum[i]=0; for(unsigned j=0; j<ncols; ++j) displacements(i,j)=0;
+      94             :   }
+      95             :   // Add bibliography
+      96           4 :   log<<"  Bibliography "<<plumed.cite("Diaz Leines and Ensing, Phys. Rev. Lett. 109, 020601 (2012)")<<"\n";
+      97             :   // And create a value to hold the displacements
+      98           2 :   std::vector<unsigned> shape(2); shape[0]=nrows; shape[1]=ncols;
+      99           2 :   addValue( shape ); setNotPeriodic();
+     100           2 :   getPntrToComponent(0)->buildDataStore();
+     101           2 :   getPntrToComponent(0)->reshapeMatrixStore( shape[1] );
+     102           2 : }
+     103             : 
+     104           0 : unsigned PathDisplacements::getNumberOfDerivatives() {
+     105           0 :   return 0;
+     106             : }
+     107             : 
+     108         573 : void PathDisplacements::update() {
+     109         573 :   unsigned nrows = getPntrToArgument(0)->getShape()[0];
+     110         573 :   unsigned ncols = getPntrToArgument(0)->getShape()[1];
+     111             : 
+     112         573 :   if( clearnextstep ) {
+     113             :     unsigned k=0;
+     114        1010 :     for(unsigned i=0; i<nrows; ++i) {
+     115       38700 :       for(unsigned j=0; j<ncols; ++j) { displacements(i,j)=0; getPntrToComponent(0)->set(k,0); k++; }
+     116             :     }
+     117          24 :     clearnextstep=false;
+     118             :   }
+     119             : 
+     120             :   unsigned k=0, iclose1=0, iclose2=0; double v1v1=0, v3v3=0;
+     121       22417 :   for(unsigned i=0; i<nrows; ++i) {
+     122             :     double dist = 0;
+     123      799020 :     for(unsigned j=0; j<ncols; ++j) {
+     124      777176 :       double tmp = getPntrToArgument(0)->get(k);
+     125      777176 :       dist += tmp*tmp; k++;
+     126             :     }
+     127       21844 :     if( i==0 ) { v1v1 = dist; iclose1 = 0; }
+     128       21271 :     else if( dist<v1v1 ) { v3v3=v1v1; v1v1=dist; iclose2=iclose1; iclose1=i; }
+     129       10991 :     else if( i==1 ) { v3v3=dist; iclose2=1; }
+     130       10991 :     else if( dist<v3v3 ) { v3v3=dist; iclose2=i; }
+     131             :   }
+     132             :   // And find third closest point
+     133         573 :   int isign = iclose1 - iclose2;
+     134             :   if( isign>1 ) isign=1; else if( isign<-1 ) isign=-1;
+     135         573 :   int iclose3 = iclose1 + isign;
+     136         573 :   unsigned ifrom=iclose1, ito=iclose3; if( iclose3<0 || iclose3>=nrows ) { ifrom=iclose2; ito=iclose1; }
+     137             : 
+     138             :   // Calculate the dot product of v1 with v2
+     139         573 :   path_projector.getDisplaceVector( ifrom, ito, displace_v );
+     140         573 :   double v2v2=0, v1v2=0; unsigned kclose1 = iclose1*ncols;
+     141       19183 :   for(unsigned i=0; i<displace_v.size(); ++i) { v2v2 += displace_v[i]*displace_v[i]; v1v2 += displace_v[i]*getPntrToArgument(0)->get(kclose1+i); }
+     142             : 
+     143         573 :   double root = sqrt( v1v2*v1v2 - v2v2 * ( v1v1 - v3v3) );
+     144         573 :   double dx = 0.5 * ( (root + v1v2) / v2v2 - 1.);
+     145         573 :   double weight2 = -1.* dx; double weight1 = 1.0 + dx;
+     146         573 :   if( weight1>1.0 ) {
+     147             :     weight1=1.0; weight2=0.0;
+     148         573 :   } else if( weight2>1.0 ) {
+     149             :     weight1=0.0; weight2=1.0;
+     150             :   }
+     151             : 
+     152             :   // Accumulate displacements for path
+     153       19183 :   for(unsigned i=0; i<ncols; ++i) {
+     154       18610 :     double displace = getPntrToArgument(0)->get(kclose1+i) - dx*displace_v[i];
+     155       18610 :     displacements(iclose1,i) += weight1 * displace; displacements(iclose2,i) += weight2 * displace;
+     156             :   }
+     157             : 
+     158             :   // Update weight accumulators
+     159         573 :   wsum[iclose1] *= fadefact; wsum[iclose2] *= fadefact;
+     160         573 :   wsum[iclose1] += weight1; wsum[iclose2] += weight2;
+     161             : 
+     162             :   // Update numbers in values
+     163         573 :   if( wsum[iclose1] > epsilon ) {
+     164       19183 :     for(unsigned i=0; i<ncols; ++i) getPntrToComponent(0)->set( kclose1+i, displacements(iclose1,i) / wsum[iclose1] );
+     165             :   }
+     166         573 :   if( wsum[iclose2] > epsilon ) {
+     167         573 :     unsigned kclose2 = iclose2*ncols;
+     168       19183 :     for(unsigned i=0; i<ncols; ++i) getPntrToComponent(0)->set( kclose2+i, displacements(iclose2,i) / wsum[iclose2] );
+     169             :   }
+     170             : 
+     171             :   // Clear if required
+     172         573 :   if( (getStep()>0 && clearstride>0 && getStep()%clearstride==0) ) clearnextstep=true;
+     173         573 : }
+     174             : 
+     175             : }
+     176             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/PathProjectionCalculator.cpp.func-sort-c.html b/coverage/mapping/PathProjectionCalculator.cpp.func-sort-c.html new file mode 100644 index 000000000000..68e36b35b337 --- /dev/null +++ b/coverage/mapping/PathProjectionCalculator.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - mapping/PathProjectionCalculator.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mapping - PathProjectionCalculator.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:808198.8 %
Date:2024-04-19 12:12:35Functions:88100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7mapping24PathProjectionCalculatorC2EPNS_6ActionE10
_ZN4PLMD7mapping24PathProjectionCalculator16registerKeywordsERNS_8KeywordsE16
_ZN4PLMD7mapping24PathProjectionCalculator25updateDepedentRMSDObjectsEv27
_ZNK4PLMD7mapping24PathProjectionCalculator17getNumberOfFramesEv1114
_ZN4PLMD7mapping24PathProjectionCalculator25setReferenceConfigurationERKjRSt6vectorIdSaIdEE4322
_ZN4PLMD7mapping24PathProjectionCalculator17getDisplaceVectorERKjS3_RSt6vectorIdSaIdEE11728
_ZN4PLMD7mapping24PathProjectionCalculator26computeVectorBetweenFramesERKjS3_11728
_ZNK4PLMD7mapping24PathProjectionCalculator25getReferenceConfigurationERKjRSt6vectorIdSaIdEE27778
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/PathProjectionCalculator.cpp.func.html b/coverage/mapping/PathProjectionCalculator.cpp.func.html new file mode 100644 index 000000000000..9acf86045b6b --- /dev/null +++ b/coverage/mapping/PathProjectionCalculator.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - mapping/PathProjectionCalculator.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mapping - PathProjectionCalculator.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:808198.8 %
Date:2024-04-19 12:12:35Functions:88100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7mapping24PathProjectionCalculator16registerKeywordsERNS_8KeywordsE16
_ZN4PLMD7mapping24PathProjectionCalculator17getDisplaceVectorERKjS3_RSt6vectorIdSaIdEE11728
_ZN4PLMD7mapping24PathProjectionCalculator25setReferenceConfigurationERKjRSt6vectorIdSaIdEE4322
_ZN4PLMD7mapping24PathProjectionCalculator25updateDepedentRMSDObjectsEv27
_ZN4PLMD7mapping24PathProjectionCalculator26computeVectorBetweenFramesERKjS3_11728
_ZN4PLMD7mapping24PathProjectionCalculatorC2EPNS_6ActionE10
_ZNK4PLMD7mapping24PathProjectionCalculator17getNumberOfFramesEv1114
_ZNK4PLMD7mapping24PathProjectionCalculator25getReferenceConfigurationERKjRSt6vectorIdSaIdEE27778
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/PathProjectionCalculator.cpp.gcov.html b/coverage/mapping/PathProjectionCalculator.cpp.gcov.html new file mode 100644 index 000000000000..8daacca107b8 --- /dev/null +++ b/coverage/mapping/PathProjectionCalculator.cpp.gcov.html @@ -0,0 +1,220 @@ + + + + + + + + LCOV - plumed test coverage - mapping/PathProjectionCalculator.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mapping - PathProjectionCalculator.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:808198.8 %
Date:2024-04-19 12:12:35Functions:88100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016,2017 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "PathProjectionCalculator.h"
+      23             : #include "core/ActionWithValue.h"
+      24             : #include "core/ActionWithArguments.h"
+      25             : #include "core/ActionRegister.h"
+      26             : #include "core/ActionSet.h"
+      27             : #include "core/PlumedMain.h"
+      28             : 
+      29             : namespace PLMD {
+      30             : namespace mapping {
+      31             : 
+      32          16 : void PathProjectionCalculator::registerKeywords(Keywords& keys) {
+      33          32 :   keys.add("compulsory","METRIC","the method to use for computing the displacement vectors between the reference frames");
+      34          32 :   keys.add("compulsory","METRIC_COMPONENT","if the final action in your metric contains multiple components this keyword is used to specify the component that should be used");
+      35          32 :   keys.add("compulsory","REFERENCE","labels for actions that contain reference coordinates for each point on the path");
+      36          16 : }
+      37             : 
+      38          10 : PathProjectionCalculator::PathProjectionCalculator( Action* act ):
+      39          10 :   mypath_obj(NULL)
+      40             : {
+      41          10 :   ActionWithArguments* aarg=dynamic_cast<ActionWithArguments*>( act );
+      42          10 :   if( aarg ) {
+      43           6 :     mypath_obj = aarg->getPntrToArgument(0);
+      44             :     // Check that we have only one argument as input
+      45           6 :     if( aarg->getNumberOfArguments()!=1 ) act->error("should only have one argument to this function");
+      46             :   }
+      47             :   // Ensure that values are stored in base calculation and that PLUMED doesn't try to calculate this in the stream
+      48          10 :   if( mypath_obj ) mypath_obj->buildDataStore();
+      49             :   // Check that the input is a matrix
+      50          10 :   if( mypath_obj ) if( mypath_obj->getRank()!=2 ) act->error("the input to this action should be a matrix");
+      51             :   // Get the labels for the reference points
+      52          10 :   std::vector<std::string> reference_data; act->parseVector("REFERENCE", reference_data);
+      53          10 :   std::vector<colvar::RMSDVector*> allrmsd = act->plumed.getActionSet().select<colvar::RMSDVector*>();
+      54          10 :   ActionWithArguments::interpretArgumentList( reference_data, act->plumed.getActionSet(), act, refargs );
+      55          26 :   for(unsigned i=0; i<refargs.size(); ++i ) {
+      56          16 :     Action* thisact = refargs[i]->getPntrToAction();
+      57          16 :     for(unsigned j=0; j<allrmsd.size(); ++j) {
+      58           4 :       if( allrmsd[j]->checkForDependency(thisact) ) { rmsd_objects.push_back( allrmsd[j] ); break; }
+      59             :     }
+      60          16 :     if( !refargs[i]->isConstant() ) act->error("input" + refargs[i]->getName() + " is not constant");
+      61          16 :     if( refargs[i]->getRank()==2 && reference_data.size()!=1 ) act->error("should only be one matrix in input to path projection object");
+      62          16 :     if( refargs[i]->getRank()>0 && refargs[i]->getShape()[0]!=refargs[0]->getShape()[0] ) act->error("mismatch in number of reference frames in input to reference_data");
+      63             :   }
+      64             :   // Create a plumed main object to compute distances between reference configurations
+      65          10 :   int s=sizeof(double);
+      66          10 :   metric.cmd("setRealPrecision",&s);
+      67          10 :   metric.cmd("setMDEngine","plumed");
+      68          10 :   int nat=0; metric.cmd("setNatoms",&nat); metric.cmd("setNoVirial");
+      69          10 :   unsigned nargs=refargs.size(); if( refargs[0]->getRank()==2 ) nargs = refargs[0]->getShape()[1];
+      70          10 :   std::string str_nargs; Tools::convert( nargs, str_nargs ); std::string period_str=" PERIODIC=NO";
+      71          11 :   if( mypath_obj && mypath_obj->isPeriodic() ) { std::string min, max; mypath_obj->getDomain( min, max ); period_str=" PERIODIC=" + min + "," + max; }
+      72          20 :   metric.readInputLine("arg1: PUT UNIT=number SHAPE=" + str_nargs + period_str, true);
+      73          20 :   metric.readInputLine("arg2: PUT UNIT=number SHAPE=" + str_nargs + period_str, true);
+      74          10 :   double tstep=1.0; metric.cmd("setTimestep",&tstep);
+      75          20 :   std::string inp; act->parse("METRIC",inp); inp += " ARG=arg2,arg1"; const char* cinp=inp.c_str();
+      76          10 :   std::vector<std::string> input=Tools::getWords(inp);
+      77          10 :   if( input.size()==1 && !actionRegister().check(input[0]) ) {
+      78           0 :     metric.cmd("setPlumedDat",cinp); metric.cmd("init");
+      79             :   } else {
+      80          10 :     metric.cmd("init"); metric.cmd("readInputLine",cinp);
+      81             :   }
+      82             :   // Now setup stuff to retrieve the final displacement
+      83          10 :   unsigned aind = metric.getActionSet().size()-1;
+      84             :   while( true ) {
+      85          15 :     const ActionShortcut* as=dynamic_cast<const ActionShortcut*>( metric.getActionSet()[aind].get() );
+      86          15 :     if( !as ) break ; aind = aind - 1; plumed_assert( aind>=0 );
+      87           5 :   }
+      88          10 :   ActionWithValue* fav = dynamic_cast<ActionWithValue*>( metric.getActionSet()[aind].get() );
+      89          10 :   if( !fav ) act->error("final value should calculate relevant value that you want as reference");
+      90          10 :   std::string name = (fav->copyOutput(0))->getName();
+      91          10 :   if( fav->getNumberOfComponents()>1 ) {
+      92          15 :     std::string comp; act->parse("METRIC_COMPONENT",comp); name = fav->getLabel() + "." + comp;
+      93             :   }
+      94          20 :   long rank; metric.cmd("getDataRank " + name, &rank );
+      95          10 :   if( rank==0 ) rank=1;
+      96          20 :   std::vector<long> ishape( rank ); metric.cmd("getDataShape " + name, &ishape[0] );
+      97          20 :   unsigned nvals=1; for(unsigned i=0; i<ishape.size(); ++i) nvals *= ishape[i];
+      98          30 :   data.resize( nvals ); metric.cmd("setMemoryForData " + name, &data[0] );
+      99          20 : }
+     100             : 
+     101        1114 : unsigned PathProjectionCalculator::getNumberOfFrames() const {
+     102        1114 :   return refargs[0]->getShape()[0];
+     103             : }
+     104             : 
+     105       11728 : void PathProjectionCalculator::computeVectorBetweenFrames( const unsigned& ifrom, const unsigned& ito ) {
+     106       11728 :   int step = 1; metric.cmd("setStep",&step);
+     107       11728 :   std::vector<double> valdata1( data.size() ), valdata2( data.size() );
+     108       11728 :   getReferenceConfiguration( ito, valdata2 ); getReferenceConfiguration( ifrom, valdata1 );
+     109       11728 :   metric.cmd("setValue arg1", &valdata1[0] );
+     110       11728 :   metric.cmd("setValue arg2", &valdata2[0] );
+     111       11728 :   metric.cmd("calc");
+     112       11728 : }
+     113             : 
+     114       11728 : void PathProjectionCalculator::getDisplaceVector( const unsigned& ifrom, const unsigned& ito, std::vector<double>& displace ) {
+     115       11728 :   if( displace.size()!=data.size() ) displace.resize( data.size() );
+     116      404063 :   computeVectorBetweenFrames( ifrom, ito ); for(unsigned i=0; i<data.size(); ++i) displace[i] = data[i];
+     117       11728 : }
+     118             : 
+     119       27778 : void PathProjectionCalculator::getReferenceConfiguration( const unsigned& iframe, std::vector<double>& refpos ) const {
+     120       27778 :   if( refpos.size()!=data.size() ) refpos.resize( data.size() );
+     121       27778 :   if( refargs[0]->getRank()==2 ) {
+     122      962880 :     for(unsigned i=0; i<refpos.size(); ++i) refpos[i] = refargs[0]->get( iframe*refpos.size() + i );
+     123             :   } else {
+     124       11178 :     for(unsigned i=0; i<refpos.size(); ++i) refpos[i] = refargs[i]->get(iframe);
+     125             :   }
+     126       27778 : }
+     127             : 
+     128        4322 : void PathProjectionCalculator::setReferenceConfiguration( const unsigned& iframe, std::vector<double>& refpos ) {
+     129             :   plumed_dbg_assert( refpos.size()==data.size() );
+     130        4322 :   if( refargs[0]->getRank()==2 ) {
+     131      165360 :     for(unsigned i=0; i<refpos.size(); ++i) refargs[0]->set( iframe*refpos.size() + i, refpos[i] );
+     132             :   } else {
+     133         572 :     for(unsigned i=0; i<refpos.size(); ++i) refargs[i]->set( iframe, refpos[i] );
+     134             :   }
+     135        4322 : }
+     136             : 
+     137          27 : void PathProjectionCalculator::updateDepedentRMSDObjects() {
+     138          50 :   for(unsigned i=0; i<rmsd_objects.size(); ++i) rmsd_objects[i]->setReferenceConfigurations();
+     139          27 : }
+     140             : 
+     141             : }
+     142             : }
+     143             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/PathReparameterization.cpp.func-sort-c.html b/coverage/mapping/PathReparameterization.cpp.func-sort-c.html new file mode 100644 index 000000000000..67019b787254 --- /dev/null +++ b/coverage/mapping/PathReparameterization.cpp.func-sort-c.html @@ -0,0 +1,113 @@ + + + + + + + + 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:909495.7 %
Date:2024-04-19 12:12:35Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7mapping22PathReparameterizationC2ERKNS_13ActionOptionsE0
_ZN4PLMD7mapping22PathReparameterizationC1ERKNS_13ActionOptionsE4
_ZN4PLMD7mapping22PathReparameterization16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD7mapping22PathReparameterization5applyEv27
_ZN4PLMD7mapping22PathReparameterization9calculateEv27
_ZN4PLMD7mapping22PathReparameterization6updateEv29
_ZN4PLMD7mapping22PathReparameterization18reparameterizePartERKiS3_RKd33
_ZN4PLMD7mapping22PathReparameterization23calcCurrentPathSpacingsERKiS3_139
_ZN4PLMD7mapping22PathReparameterization14computeSpacingERKjS3_4459
_ZNK4PLMD7mapping22PathReparameterization7loopEndERKiS3_S3_11542
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/PathReparameterization.cpp.func.html b/coverage/mapping/PathReparameterization.cpp.func.html new file mode 100644 index 000000000000..18364b0d341c --- /dev/null +++ b/coverage/mapping/PathReparameterization.cpp.func.html @@ -0,0 +1,113 @@ + + + + + + + + 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:909495.7 %
Date:2024-04-19 12:12:35Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7mapping22PathReparameterization14computeSpacingERKjS3_4459
_ZN4PLMD7mapping22PathReparameterization16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD7mapping22PathReparameterization18reparameterizePartERKiS3_RKd33
_ZN4PLMD7mapping22PathReparameterization23calcCurrentPathSpacingsERKiS3_139
_ZN4PLMD7mapping22PathReparameterization5applyEv27
_ZN4PLMD7mapping22PathReparameterization6updateEv29
_ZN4PLMD7mapping22PathReparameterization9calculateEv27
_ZN4PLMD7mapping22PathReparameterizationC1ERKNS_13ActionOptionsE4
_ZN4PLMD7mapping22PathReparameterizationC2ERKNS_13ActionOptionsE0
_ZNK4PLMD7mapping22PathReparameterization7loopEndERKiS3_S3_11542
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/PathReparameterization.cpp.gcov.html b/coverage/mapping/PathReparameterization.cpp.gcov.html new file mode 100644 index 000000000000..f92747ad7b76 --- /dev/null +++ b/coverage/mapping/PathReparameterization.cpp.gcov.html @@ -0,0 +1,306 @@ + + + + + + + + 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:909495.7 %
Date:2024-04-19 12:12:35Functions:91090.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2020 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received 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/ActionPilot.h"
+      24             : #include "core/ActionRegister.h"
+      25             : #include "core/PlumedMain.h"
+      26             : #include "core/ActionSet.h"
+      27             : #include "tools/Pbc.h"
+      28             : #include "tools/Matrix.h"
+      29             : #include "PathProjectionCalculator.h"
+      30             : 
+      31             : //+PLUMEDOC ANALYSIS REPARAMETERIZE_PATH
+      32             : /*
+      33             : Take an input path with frames that are not equally spaced and make the frames equally spaced
+      34             : 
+      35             : \par Examples
+      36             : 
+      37             : */
+      38             : //+ENDPLUMEDOC
+      39             : 
+      40             : namespace PLMD {
+      41             : namespace mapping {
+      42             : 
+      43             : class PathReparameterization : public ActionPilot {
+      44             : private:
+      45             : /// Number of cycles of the optimization algorithm to run
+      46             :   unsigned maxcycles;
+      47             : /// The points on the path to fix
+      48             :   unsigned ifix1, ifix2;
+      49             : /// Tolerance for the minimization algorithm
+      50             :   double TOL;
+      51             : /// Value containing ammount to displace each reference configuration by
+      52             :   Value* displace_value;
+      53             : /// The action for calculating the distances between the frames
+      54             :   PathProjectionCalculator path_projector;
+      55             : /// Used to store current spacing between frames in path
+      56             :   std::vector<double> data, len, sumlen, sfrac;
+      57             : ///
+      58             :   bool loopEnd( const int& index, const int& end, const int& inc ) const ;
+      59             : ///
+      60             :   double computeSpacing( const unsigned& ifrom, const unsigned& ito );
+      61             : ///
+      62             :   void calcCurrentPathSpacings( const int& istart, const int& iend );
+      63             : ///
+      64             :   void reparameterizePart( const int& istart, const int& iend, const double& target );
+      65             : public:
+      66             :   static void registerKeywords( Keywords& keys );
+      67             :   PathReparameterization(const ActionOptions&);
+      68          27 :   void calculate() {}
+      69          27 :   void apply() {}
+      70             :   void update();
+      71             : };
+      72             : 
+      73             : PLUMED_REGISTER_ACTION(PathReparameterization,"REPARAMETERIZE_PATH")
+      74             : 
+      75           6 : void PathReparameterization::registerKeywords( Keywords& keys ) {
+      76           6 :   Action::registerKeywords( keys ); ActionPilot::registerKeywords( keys );
+      77           6 :   PathProjectionCalculator::registerKeywords(keys);
+      78          12 :   keys.add("compulsory","STRIDE","1","the frequency with which to reparameterize the path");
+      79          12 :   keys.add("compulsory","FIXED","0","the frames in the path to fix");
+      80          12 :   keys.add("compulsory","MAXCYLES","100","number of cycles of the algorithm to run");
+      81          12 :   keys.add("compulsory","TOL","1E-4","the tolerance to use for the path reparameterization algorithm");
+      82          12 :   keys.add("optional","DISPLACE_FRAMES","label of an action that tells us how to displace the frames.  These displacements are applied before "
+      83             :            "running the reparameterization algorith");
+      84           6 : }
+      85             : 
+      86           4 : PathReparameterization::PathReparameterization(const ActionOptions&ao):
+      87             :   Action(ao),
+      88             :   ActionPilot(ao),
+      89           4 :   displace_value(NULL),
+      90           4 :   path_projector(this)
+      91             : {
+      92           8 :   parse("MAXCYLES",maxcycles); parse("TOL",TOL);
+      93           4 :   log.printf("  running till change is less than %f or until there have been %d optimization cycles \n", TOL, maxcycles);
+      94           4 :   len.resize( path_projector.getNumberOfFrames()  ); sumlen.resize( path_projector.getNumberOfFrames() ); sfrac.resize( path_projector.getNumberOfFrames() );
+      95           8 :   std::vector<unsigned> fixed; parseVector("FIXED",fixed);
+      96           4 :   if( fixed.size()==1 ) {
+      97           0 :     if( fixed[0]!=0 ) error("input to FIXED should be two integers");
+      98           0 :     ifix1=0; ifix2=path_projector.getNumberOfFrames()-1;
+      99           4 :   } else if( fixed.size()==2 ) {
+     100           4 :     if( fixed[0]<1 || fixed[1]<1 || fixed[0]>path_projector.getNumberOfFrames() || fixed[1]>path_projector.getNumberOfFrames() ) {
+     101           0 :       error("input to FIXED should be two numbers between 1 and the number of frames");
+     102             :     }
+     103           4 :     ifix1=fixed[0]-1; ifix2=fixed[1]-1;
+     104           0 :   } else error("input to FIXED should be two integers");
+     105           4 :   log.printf("  fixing frames %d and %d when reparameterizing \n", ifix1, ifix2 );
+     106           8 :   std::string dframe; parse("DISPLACE_FRAMES",dframe);
+     107           4 :   if( dframe.length()>0 ) {
+     108           2 :     ActionWithValue* av = plumed.getActionSet().selectWithLabel<ActionWithValue*>( dframe );
+     109           2 :     if( !av ) error("could not find action with label " + dframe + " specified to DISPLACE_FRAMES keyword in input file");
+     110           2 :     if( av->getName()!="AVERAGE_PATH_DISPLACEMENT" ) error("displace object is not of correct type");
+     111           2 :     displace_value = av->copyOutput(0);
+     112             :   }
+     113           4 : }
+     114             : 
+     115       11542 : bool PathReparameterization::loopEnd( const int& index, const int& end, const int& inc ) const {
+     116       11542 :   if( inc>0 && index<end ) return false;
+     117         428 :   else if( inc<0 && index>end ) return false;
+     118             :   return true;
+     119             : }
+     120             : 
+     121        4459 : double PathReparameterization::computeSpacing( const unsigned& ifrom, const unsigned& ito ) {
+     122        4459 :   path_projector.getDisplaceVector( ifrom, ito, data );
+     123      170534 :   double length=0; for(unsigned i=0; i<data.size(); ++i) length += data[i]*data[i];
+     124        4459 :   return sqrt( length );
+     125             : }
+     126             : 
+     127         139 : void PathReparameterization::calcCurrentPathSpacings( const int& istart, const int& iend ) {
+     128             :   plumed_dbg_assert( istart<len.size() && iend<len.size() );
+     129         139 :   len[istart] = sumlen[istart]=0;
+     130             :   //printf("HELLO PATH SPACINGS ARE CURRENTLY \n");
+     131             : 
+     132             :   // Get the spacings given we can go forward and backwards
+     133         139 :   int incr=1; if( istart>iend ) { incr=-1; }
+     134             : 
+     135        4598 :   for(int i=istart+incr; loopEnd(i,iend+incr,incr)==false; i+=incr) {
+     136        4459 :     len[i] = computeSpacing( i-incr, i ); sumlen[i] = sumlen[i-incr] + len[i];
+     137             :     //printf("FRAME %d TO FRAME %d EQUALS %f : %f \n",i-incr,i,len[i],sumlen[i] );
+     138             :   }
+     139         139 : }
+     140             : 
+     141          33 : void PathReparameterization::reparameterizePart( const int& istart, const int& iend, const double& target ) {
+     142          33 :   calcCurrentPathSpacings( istart, iend ); unsigned cfin;
+     143             :   // If a target separation is set we fix where we want the nodes
+     144          33 :   int incr=1; if( istart>iend ) { incr=-1; }
+     145             : 
+     146          33 :   if( target>0 ) {
+     147           6 :     if( iend>istart ) {
+     148          19 :       for(unsigned i=istart; i<iend+1; ++i) sfrac[i] = target*(i-istart);
+     149             :     } else {
+     150          14 :       for(int i=istart-1; i>iend-1; --i) sfrac[i]=target*(istart-i);
+     151             :     }
+     152           6 :     cfin = iend+incr;
+     153             :   } else {
+     154          27 :     cfin = iend;
+     155             :   }
+     156             : 
+     157          33 :   double prevsum=0.; Matrix<double> newmatrix( path_projector.getNumberOfFrames(), data.size() );
+     158         139 :   for(unsigned iter=0; iter<maxcycles; ++iter) {
+     159         139 :     if( fabs(sumlen[iend] - prevsum)<=TOL ) break ;
+     160             :     prevsum = sumlen[iend];
+     161             :     // If no target is set we redistribute length
+     162         106 :     if( target<0 ) {
+     163          94 :       plumed_assert( istart<iend );
+     164          94 :       double dr = sumlen[iend] / static_cast<double>( iend - istart );
+     165        3506 :       for(unsigned i=istart; i<iend; ++i) sfrac[i] = dr*(i-istart);
+     166             :     }
+     167             : 
+     168             :     // Now compute positions of new nodes in path
+     169        3472 :     for(int i=istart+incr; loopEnd(i,cfin,incr)==false; i+=incr) {
+     170        3366 :       int k = istart;
+     171       69429 :       while( !((sumlen[k] < sfrac[i]) && (sumlen[k+incr]>=sfrac[i])) ) {
+     172       66069 :         k+=incr;
+     173       66069 :         if( cfin==iend && k>= iend+1 ) plumed_merror("path reparameterization error");
+     174       66069 :         else if( cfin==(iend+1) && k>=iend ) { k=iend-1; break; }
+     175       66067 :         else if( cfin==(iend-1) && k<=iend ) { k=iend+1; break; }
+     176             :       }
+     177        3366 :       double dr = (sfrac[i]-sumlen[k])/len[k+incr];
+     178             :       // Copy the reference configuration to the row of a matrix
+     179        3366 :       path_projector.getReferenceConfiguration( k, data );
+     180      129024 :       for(unsigned j=0; j<data.size(); ++j) newmatrix(i,j) = data[j];
+     181        3366 :       path_projector.getDisplaceVector( k, k+incr, data );
+     182             :       // Shift the reference configuration by this ammount
+     183      129024 :       for(unsigned j=0; j<data.size(); ++j) newmatrix(i,j) += dr*data[j];
+     184             :     }
+     185             : 
+     186             :     // Copy the positions of the new path to the new paths
+     187        3472 :     for(int i=istart+incr; loopEnd(i,cfin,incr)==false; i+=incr) {
+     188      129024 :       for(unsigned j=0; j<data.size(); ++j) data[j] = newmatrix(i,j);
+     189        3366 :       path_projector.setReferenceConfiguration( i, data );
+     190             :     }
+     191             : 
+     192             :     // Recompute the separations between frames
+     193         106 :     calcCurrentPathSpacings( istart, iend );
+     194             :   }
+     195          33 : }
+     196             : 
+     197          29 : void PathReparameterization::update() {
+     198             :   // We never run this on the first step
+     199          29 :   if( getStep()==0 ) return ;
+     200             : 
+     201             :   // Shift the frames using the displacements
+     202          27 :   if( displace_value ) {
+     203        1031 :     for(unsigned i=0; i<path_projector.getNumberOfFrames(); ++i) {
+     204        1006 :       if( i==ifix1 || i==ifix2 ) continue ;
+     205             :       // Retrieve the current position of the frame
+     206         956 :       path_projector.getReferenceConfiguration( i, data );
+     207             :       // Shift using the averages accumulated in the action that accumulates the displacements
+     208         956 :       unsigned kstart = i*data.size();
+     209       36908 :       for(unsigned j=0; j<data.size(); ++j) data[j] += displace_value->get( kstart + j );
+     210             :       // And now set the new position of the refernce frame
+     211         956 :       path_projector.setReferenceConfiguration( i, data );
+     212             :     }
+     213             :   }
+     214             : 
+     215             :   // First reparameterize the part between the fixed frames
+     216          27 :   reparameterizePart( ifix1, ifix2, -1.0 );
+     217             : 
+     218             :   // Get the separation between frames which we will use to set the remaining frames
+     219          27 :   double target = sumlen[ifix2] / ( ifix2 - ifix1 );
+     220             : 
+     221             :   // And reparameterize the begining and end of the path
+     222          27 :   if( ifix1>0 ) reparameterizePart( ifix1, 0, target );
+     223          27 :   if( ifix2<(path_projector.getNumberOfFrames()-1) ) reparameterizePart( ifix2, path_projector.getNumberOfFrames()-1, target );
+     224             :   // And update any RMSD objects that depend on input values
+     225          27 :   path_projector.updateDepedentRMSDObjects();
+     226             : }
+     227             : 
+     228             : }
+     229             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/PathTools.cpp.func-sort-c.html b/coverage/mapping/PathTools.cpp.func-sort-c.html new file mode 100644 index 000000000000..981aabe173ab --- /dev/null +++ b/coverage/mapping/PathTools.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + 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:22923497.9 %
Date:2024-04-19 12:12:35Functions:88100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7mapping9PathTools11printLambdaERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIS7_SaIS7_EES9_4
_ZN4PLMD7mapping9PathTools4mainEP8_IO_FILES3_RNS_12CommunicatorE4
_ZNK4PLMD7mapping9PathTools11descriptionB5cxx11Ev4
_ZN4PLMD7mapping12_GLOBAL__N_119PathToolsRegisterMe6createERKNS_13CLToolOptionsE8
_ZN4PLMD7mapping9PathToolsC2ERKNS_13CLToolOptionsE8
_ZN4PLMD7mapping12_GLOBAL__N_119PathToolsRegisterMeC2Ev5088
_ZN4PLMD7mapping12_GLOBAL__N_119PathToolsRegisterMeD2Ev5088
_ZN4PLMD7mapping9PathTools16registerKeywordsERNS_8KeywordsE5088
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/PathTools.cpp.func.html b/coverage/mapping/PathTools.cpp.func.html new file mode 100644 index 000000000000..f116fc70cfaa --- /dev/null +++ b/coverage/mapping/PathTools.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + 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:22923497.9 %
Date:2024-04-19 12:12:35Functions:88100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7mapping12_GLOBAL__N_119PathToolsRegisterMe6createERKNS_13CLToolOptionsE8
_ZN4PLMD7mapping12_GLOBAL__N_119PathToolsRegisterMeC2Ev5088
_ZN4PLMD7mapping12_GLOBAL__N_119PathToolsRegisterMeD2Ev5088
_ZN4PLMD7mapping9PathTools11printLambdaERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIS7_SaIS7_EES9_4
_ZN4PLMD7mapping9PathTools16registerKeywordsERNS_8KeywordsE5088
_ZN4PLMD7mapping9PathTools4mainEP8_IO_FILES3_RNS_12CommunicatorE4
_ZN4PLMD7mapping9PathToolsC2ERKNS_13CLToolOptionsE8
_ZNK4PLMD7mapping9PathTools11descriptionB5cxx11Ev4
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/PathTools.cpp.gcov.html b/coverage/mapping/PathTools.cpp.gcov.html new file mode 100644 index 000000000000..b8ae99c9f6d1 --- /dev/null +++ b/coverage/mapping/PathTools.cpp.gcov.html @@ -0,0 +1,521 @@ + + + + + + + + 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:22923497.9 %
Date:2024-04-19 12:12:35Functions:88100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2020 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received 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/CLTool.h"
+      23             : #include "core/CLToolRegister.h"
+      24             : #include "tools/Tools.h"
+      25             : #include "tools/Pbc.h"
+      26             : #include "tools/PDB.h"
+      27             : #include "core/ActionWithValue.h"
+      28             : #include "core/ActionToPutData.h"
+      29             : #include "core/ActionSet.h"
+      30             : #include "core/Value.h"
+      31             : #include "core/PlumedMain.h"
+      32             : #include "Path.h"
+      33             : #include <cstdio>
+      34             : #include <string>
+      35             : #include <vector>
+      36             : #include <iostream>
+      37             : 
+      38             : namespace PLMD {
+      39             : namespace mapping {
+      40             : 
+      41             : //+PLUMEDOC TOOLS pathtools
+      42             : /*
+      43             : pathtools can be used to construct paths from pdb data
+      44             : 
+      45             : The path CVs in PLUMED are curvilinear coordinates through a high dimensional vector space.
+      46             : Enhanced sampling calculations are often run using the progress along the paths and the distance from the path as CVs
+      47             : as this provides a convenient way of defining a reaction coordinate for a complicated process.  This method is explained
+      48             : in the documentation for \ref PATH.
+      49             : 
+      50             : The path itself is an ordered set of equally-spaced, high-dimensional frames the way in which these frames
+      51             : should be constructed will depend on the problem in hand.  In other words, you will need to understand the reaction
+      52             : you wish to study in order to select a sensible set of frames to use in your path CV.  This tool provides two
+      53             : methods that may be useful when it comes to constructing paths; namely:
+      54             : 
+      55             : - A tool that takes in an initial guess path in which the frames are not equally spaced.  This tool adjusts the positions
+      56             : of the frames in order to make them equally spaced so that they can be used as the basis for a path CV.
+      57             : 
+      58             : - A tool that takes two frames as input and that allows you to return a linear path connecting these two frames.  The
+      59             : output from this method may be useful as an initial guess path.  It is arguable that a linear path rather defeats the
+      60             : purpose of the path CV method, however, as the whole purpose is to be able to define non-linear paths.
+      61             : 
+      62             : Notice that you can use these two methods and take advantage of all the ways of measuring \ref dists that are available within
+      63             : PLUMED. The way you do this with each of these tools described above is explained in the example below.
+      64             : 
+      65             : \par Examples
+      66             : 
+      67             : The example below shows how you can take a set of unequally spaced frames from a pdb file named in_path.pdb
+      68             : and use pathtools to make them equally spaced so that they can be used as the basis for a path CV.  The file
+      69             : containing this final path is named final_path.pdb.
+      70             : 
+      71             : \verbatim
+      72             : plumed pathtools --path in_path.pdb --metric EUCLIDEAN --out final_path.pdb
+      73             : \endverbatim
+      74             : 
+      75             : The example below shows how can create an initial linear path connecting the two pdb frames in start.pdb and
+      76             : end.pdb.  In this case the path output to path.pdb will consist of 6 frames: the initial and final frames that
+      77             : were contained in start.pdb and end.pdb as well as four equally spaced frames along the vector connecting
+      78             : start.pdb to end.pdb.
+      79             : 
+      80             : \verbatim
+      81             : plumed pathtools --start start.pdb --end end.pdb --nframes 4 --metric OPTIMAL --out path.pdb
+      82             : \endverbatim
+      83             : 
+      84             : Often the idea with path collective variables is to create a path connecting some initial state A to some final state B.  You would
+      85             : in this case have representative configurations from your A and B states defined in the input files to pathtools
+      86             : that we have called start.pdb and end.pdb in the example above.  Furthermore, it may be useful to have a few frames
+      87             : before your start frame and after your end frame.  You can use path tools to create these extended paths as shown below.
+      88             : In this case the final path would now consist of 8 frames.  Four of these frames would lie on the vector connecting state
+      89             : 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
+      90             : frame just after end.pdb.  All these frames would be equally spaced.
+      91             : 
+      92             : \verbatim
+      93             : plumed pathtools --start start.pdb --end end.pdb --nframes 4 --metric OPTIMAL --out path.pdb --nframes-before-start 2 --nframes-after-end 2
+      94             : \endverbatim
+      95             : 
+      96             : Notice also that when you re-parameterize paths you must choose two frames to fix.  Generally you chose to fix the states
+      97             : that are representative of your states A and B.  By default pathtools will fix the first and last frames.  You can, however,
+      98             : change the states to fix by taking advantage of the fixed flag as shown below.
+      99             : 
+     100             : \verbatim
+     101             : plumed pathtools --path inpath.pdb --metric EUCLIDEAN --out outpath.pdb --fixed 2,12
+     102             : \endverbatim
+     103             : 
+     104             : */
+     105             : //+ENDPLUMEDOC
+     106             : 
+     107             : class PathTools :
+     108             :   public CLTool
+     109             : {
+     110             : public:
+     111             :   static void registerKeywords( Keywords& keys );
+     112             :   explicit PathTools(const CLToolOptions& co );
+     113             :   int main(FILE* in, FILE*out,Communicator& pc);
+     114             :   void printLambda( const std::string& mtype, const std::vector<std::string>& argstr, const std::string& ofile );
+     115           4 :   std::string description()const {
+     116           4 :     return "print out a description of the keywords for an action in html";
+     117             :   }
+     118             : };
+     119             : 
+     120       15272 : PLUMED_REGISTER_CLTOOL(PathTools,"pathtools")
+     121             : 
+     122        5088 : void PathTools::registerKeywords( Keywords& keys ) {
+     123        5088 :   CLTool::registerKeywords( keys );
+     124       10176 :   keys.add("atoms","--start","a pdb file that contains the structure for the initial frame of your path");
+     125       10176 :   keys.add("atoms","--end","a pdb file that contains the structure for the final frame of your path");
+     126       10176 :   keys.add("atoms-1","--path","a pdb file that contains an initial path in which the frames are not equally spaced");
+     127       10176 :   keys.add("optional","--arg","the arguments that should be read in from the pdb files");
+     128       10176 :   keys.add("compulsory","--fixed","0","the frames to fix when constructing the path using --path");
+     129       10176 :   keys.add("compulsory","--metric","the measure to use to calculate the distance between frames");
+     130       10176 :   keys.add("compulsory","--out","the name of the file on which to output your path");
+     131       10176 :   keys.add("compulsory","--arg-fmt","%f","the format to use for argument values in your frames");
+     132       10176 :   keys.add("compulsory","--tolerance","1E-4","the tolerance to use for the algorithm that is used to re-parameterize the path");
+     133       10176 :   keys.add("compulsory","--nframes-before-start","1","the number of frames to include in the path before the first frame");
+     134       10176 :   keys.add("compulsory","--nframes","1","the number of frames between the start and end frames in your path");
+     135       10176 :   keys.add("compulsory","--nframes-after-end","1","the number of frames to put after the last frame of your path");
+     136        5088 : }
+     137             : 
+     138           8 : PathTools::PathTools(const CLToolOptions& co ):
+     139           8 :   CLTool(co)
+     140             : {
+     141           8 :   inputdata=commandline;
+     142           8 : }
+     143             : 
+     144           4 : int PathTools::main(FILE* in, FILE*out,Communicator& pc) {
+     145             :   // Create a PLUMED object
+     146           4 :   PlumedMain plmd; int s=sizeof(double);
+     147           4 :   plmd.cmd("setRealPrecision",&s);
+     148           4 :   plmd.cmd("setMDEngine","pathtools");
+     149             :   // plmd.cmd("setNoVirial");
+     150           4 :   double tstep=1.0; plmd.cmd("setTimestep",&tstep);
+     151           4 :   plmd.cmd("init");
+     152           4 :   int step=1; plmd.cmd("setStep",&step);
+     153             : 
+     154           8 :   std::string mtype; parse("--metric",mtype);
+     155           8 :   std::string ifilename; parse("--path",ifilename);
+     156           8 :   std::string ofmt; parse("--arg-fmt",ofmt);
+     157           8 :   std::string ofilename; parse("--out",ofilename);
+     158           8 :   std::vector<std::string> argstr; parseVector("--arg",argstr);
+     159           4 :   if( ifilename.length()>0 ) {
+     160             :     fprintf(out,"Reparameterising path in file named %s so that all frames are equally spaced \n",ifilename.c_str() );
+     161           2 :     FILE* fp=fopen(ifilename.c_str(),"r"); PDB mypdb; bool do_read=mypdb.readFromFilepointer(fp,false,0.1);
+     162           2 :     std::vector<double> alig( mypdb.getOccupancy() ), disp( mypdb.getBeta() ); std::vector<AtomNumber> indices( mypdb.getAtomNumbers() );
+     163             :     // Count the number of frames in the input file
+     164          20 :     unsigned nfram=1; while ( do_read ) { if( !mypdb.readFromFilepointer(fp,false,0.1) ) break; nfram++; }
+     165           2 :     if( argstr.size()>0 ) {
+     166           3 :       for(unsigned i=0; i<argstr.size(); ++i ) {
+     167           4 :         std::string input = argstr[i] + ": PDB2CONSTANT NOARGS REFERENCE=" + ifilename + " ARG=" + argstr[i];
+     168           2 :         const char* inpt = input.c_str(); plmd.cmd("readInputLine", inpt);
+     169             :       }
+     170             :     } else {
+     171           1 :       std::string input = "data: PDB2CONSTANT REFERENCE=" + ifilename;
+     172           1 :       const char* inpt = input.c_str(); plmd.cmd("readInputLine", inpt );
+     173             :     }
+     174           2 :     std::string reparam_str = "REPARAMETERIZE_PATH REFERENCE=";
+     175           5 :     if( argstr.size()>0 ) { reparam_str += argstr[0]; for(unsigned i=0; i<argstr.size(); ++i ) reparam_str += "," + argstr[i]; }
+     176           4 :     else { reparam_str += "data"; } std::vector<unsigned> fixed; parseVector("--fixed",fixed);
+     177           2 :     if( fixed.size()==1 ) {
+     178           1 :       if( fixed[0]!=0 ) error("input to --fixed should be two integers");
+     179           1 :       fixed.resize(2); fixed[0]=1; fixed[1]=nfram;
+     180           1 :     } else if( fixed.size()==2 ) {
+     181           1 :       if( fixed[0]<1 || fixed[1]<1 || fixed[0]>nfram || fixed[1]>nfram ) {
+     182           0 :         error("input to --fixed should be two numbers between 0 and the number of frames-1");
+     183             :       }
+     184           0 :     } else error("input to --fixed should be two integers");
+     185           2 :     std::string fix1, fix2; Tools::convert( fixed[0], fix1 ); Tools::convert( fixed[1], fix2 );
+     186           4 :     reparam_str += " FIXED=" + fix1 + "," + fix2;
+     187           6 :     std::string tol; parse("--tolerance",tol); reparam_str += " TOL=" + tol;
+     188             : // Now create the metric object
+     189             :     reparam_str += " METRIC=";
+     190           5 :     if( mtype=="OPTIMAL-FAST" || mtype=="OPTIMAL" || mtype=="SIMPLE" ) {
+     191           2 :       reparam_str += "{RMSD_VECTOR DISPLACEMENT SQUARED UNORMALIZED TYPE=" + mtype;
+     192             :       // Get the align values
+     193           1 :       std::string anum; Tools::convert( alig[0], anum ); reparam_str += " ALIGN=" + anum;
+     194          13 :       for(unsigned i=1; i<alig.size(); ++i) { Tools::convert( alig[i], anum ); reparam_str += "," + anum; }
+     195             :       // Get the displace values
+     196           1 :       std::string dnum; Tools::convert( disp[0], dnum ); reparam_str += " DISPLACE=" + dnum;
+     197          13 :       for(unsigned i=1; i<disp.size(); ++i) { Tools::convert( disp[i], dnum ); reparam_str += "," + dnum; }
+     198             :       reparam_str += "} METRIC_COMPONENT=disp";
+     199           1 :     } else if( mtype=="EUCLIDEAN" ) {
+     200             :       reparam_str += "DIFFERENCE";
+     201             :     } else {
+     202             :       // Add functionality to read plumed input here
+     203           0 :       plumed_merror("metric type " + mtype + " has not been implemented");
+     204             :     }
+     205             : 
+     206             :     // Now do the reparameterization
+     207           2 :     const char* icinp= reparam_str.c_str(); plmd.cmd("readInputLine",icinp);
+     208             :     Action* raction = plmd.getActionSet()[plmd.getActionSet().size()-1].get();
+     209           2 :     raction->update();
+     210             : 
+     211             :     // And print the final reference configurations
+     212           4 :     std::string pinput="DUMPPDB STRIDE=1 DESCRIPTION=PATH FILE=" + ofilename + " FMT=" + ofmt;
+     213           2 :     if( argstr.size()>0 ) {
+     214           3 :       pinput += " ARG=" + argstr[0]; for(unsigned i=1; i<argstr.size(); ++i ) pinput += "," + argstr[i];
+     215          14 :     } else { std::string num; Tools::convert( indices[0].serial(), num ); pinput += " ATOMS=data ATOM_INDICES=" + num; for(unsigned i=1; i<indices.size(); ++i ) { Tools::convert( indices[i].serial(), num ); pinput += "," + num; } }
+     216           2 :     const char* pcinp=pinput.c_str(); plmd.cmd("readInputLine",pcinp);
+     217             :     Action* paction = plmd.getActionSet()[plmd.getActionSet().size()-1].get();
+     218           2 :     paction->update();
+     219             : 
+     220             :     // Ouput data on spacings
+     221           2 :     printLambda( mtype, argstr, ofilename );
+     222             :     return 0;
+     223           2 :   }
+     224           4 :   for(unsigned i=0; i<argstr.size(); ++i) {
+     225           2 :     std::string input = argstr[i] + ": CONSTANT VALUE=1";
+     226           2 :     const char* inpt = input.c_str(); plmd.cmd("readInputLine", inpt);
+     227             :   }
+     228             : 
+     229             : // Read in the instructions
+     230             :   unsigned nbefore, nbetween, nafter;
+     231           4 :   std::string istart; parse("--start",istart); std::string iend; parse("--end",iend);
+     232           6 :   parse("--nframes-before-start",nbefore); parse("--nframes",nbetween); parse("--nframes-after-end",nafter);
+     233           2 :   nbetween++;
+     234             :   fprintf(out,"Generating linear path connecting structure in file named %s to structure in file named %s \n",istart.c_str(),iend.c_str() );
+     235           2 :   fprintf(out,"A path consisting of %u equally-spaced frames before the initial structure, %u frames between the initial and final structures "
+     236             :           "and %u frames after the final structure will be created \n",nbefore,nbetween,nafter);
+     237             : 
+     238           2 :   std::vector<double> start_pos( argstr.size() ), end_pos( argstr.size() ); std::vector<AtomNumber> indices;
+     239           2 :   if( argstr.size()>0 ) {
+     240           3 :     for(unsigned i=0; i<argstr.size(); ++i ) {
+     241           4 :       std::string input = argstr[i] + "_start: PDB2CONSTANT REFERENCE=" + istart + " ARG=" + argstr[i];
+     242           2 :       const char* inpt = input.c_str(); plmd.cmd("readInputLine", inpt );
+     243           4 :       long srank; plmd.cmd("getDataRank " + argstr[i] + "_start", &srank );
+     244           2 :       if( srank!=1 ) error("should only be one frame in input pdb");
+     245           4 :       std::vector<long> sshape( 1 ); plmd.cmd("getDataShape " + argstr[i] + "_start", &sshape[0] );
+     246           2 :       if( sshape[0]!=1 ) error("should only be one frame in input pdb");
+     247           4 :       plmd.cmd("setMemoryForData " + argstr[i] + "_start", &start_pos[i] );
+     248           4 :       std::string input2 = argstr[i] + "_end: PDB2CONSTANT REFERENCE=" + iend + " ARG=" + argstr[i];
+     249           2 :       const char* inpt2 = input2.c_str(); plmd.cmd("readInputLine", inpt2 );
+     250           4 :       long erank; plmd.cmd("getDataRank " + argstr[i] + "_end", &erank );
+     251           2 :       if( erank!=1 ) error("should only be one frame in input pdb");
+     252           4 :       std::vector<long> eshape( 1 ); plmd.cmd("getDataShape " + argstr[i] + "_end", &eshape[0] );
+     253           2 :       if( eshape[0]!=1 ) error("should only be one frame in input pdb");
+     254           4 :       plmd.cmd("setMemoryForData " + argstr[i] + "_end", &end_pos[i] );
+     255             :     }
+     256             :   } else {
+     257           1 :     std::string input = "start: PDB2CONSTANT REFERENCE=" + istart;
+     258           1 :     const char* inpt = input.c_str(); plmd.cmd("readInputLine", inpt );
+     259           1 :     FILE* fp=fopen(istart.c_str(),"r"); PDB mypdb; bool do_read=mypdb.readFromFilepointer(fp,false,0.1);
+     260          14 :     indices.resize( mypdb.getAtomNumbers().size() ); for(unsigned i=0; i<indices.size(); ++i) indices[i] = mypdb.getAtomNumbers()[i];
+     261           1 :     long srank; plmd.cmd("getDataRank start", &srank ); if( srank!=2 ) error("should only be one frame in input pdb:" + istart);
+     262           1 :     std::vector<long> sshape( srank ); plmd.cmd("getDataShape start", &sshape[0] ); start_pos.resize( sshape[0]*sshape[1] );
+     263           1 :     if( sshape[0]!=1 ) error("should only be one frame in input pdb: " + istart);
+     264           1 :     plmd.cmd("setMemoryForData start", &start_pos[0] );
+     265           1 :     std::string input2 = "end: PDB2CONSTANT REFERENCE=" + iend;
+     266           1 :     const char* inpt2 = input2.c_str(); plmd.cmd("readInputLine", inpt2 );
+     267           1 :     long erank; plmd.cmd("getDataRank end", &erank ); if( erank!=2 ) error("should only be one frame in input pdb: " + iend);
+     268           1 :     std::vector<long> eshape( erank ); plmd.cmd("getDataShape end", &eshape[0] ); end_pos.resize( eshape[0]*eshape[1] );
+     269           1 :     if( eshape[0]!=1 ) error("should only be one frame in input pdb: " + iend );
+     270           1 :     plmd.cmd("setMemoryForData end", &end_pos[0] );
+     271           1 :   }
+     272             : 
+     273             : // Now create the metric object
+     274           5 :   if( mtype=="OPTIMAL-FAST" || mtype=="OPTIMAL" || mtype=="SIMPLE" ) {
+     275           1 :     std::string trinput = "endT: TRANSPOSE ARG=end";
+     276           1 :     const char* tinp=trinput.c_str(); plmd.cmd("readInputLine",tinp);
+     277           1 :     PDB pdb; pdb.read(istart,false,0.1);
+     278           1 :     std::vector<double> alig( pdb.getOccupancy() ), disp( pdb.getBeta() );
+     279           2 :     std::string minput = "d: RMSD_VECTOR DISPLACEMENT SQUARED UNORMALIZED TYPE=" + mtype + " ARG=endT,start";
+     280             :     // Get the align values
+     281           1 :     std::string anum; Tools::convert( alig[0], anum ); minput += " ALIGN=" + anum;
+     282          13 :     for(unsigned i=1; i<alig.size(); ++i) { Tools::convert( alig[i], anum ); minput += "," + anum; }
+     283             :     // Get the displace values
+     284           1 :     std::string dnum; Tools::convert( disp[0], dnum ); minput += " DISPLACE=" + dnum;
+     285          13 :     for(unsigned i=1; i<disp.size(); ++i) { Tools::convert( disp[i], dnum ); minput += "," + dnum; }
+     286           1 :     const char* mcinp=minput.c_str(); plmd.cmd("readInputLine",mcinp);
+     287           1 :     std::string tinput = "CUSTOM ARG=d.disp FUNC=x PERIODIC=NO"; const char* tcinp=tinput.c_str(); plmd.cmd("readInputLine",tcinp);
+     288           2 :   } else if( mtype=="EUCLIDEAN" ) {
+     289           2 :     std::string end_args="ARG1=" + argstr[0] + "_end", start_args="ARG2=" + argstr[0] + "_start";
+     290           3 :     for(unsigned i=1; i<argstr.size(); ++i ) { end_args += "," + argstr[i] + "_end"; start_args += "," + argstr[i] + "_start"; }
+     291           2 :     std::string minput = "d: DISPLACEMENT " + end_args + " " + start_args; const char* mcinp=minput.c_str(); plmd.cmd("readInputLine",mcinp);
+     292           1 :     std::string tinput = "TRANSPOSE ARG=d"; const char* tcinp=tinput.c_str(); plmd.cmd("readInputLine",tcinp);
+     293             :   } else {
+     294             :     // Add functionality to read plumed input here
+     295           0 :     plumed_merror("metric type " + mtype + " has not been implemented");
+     296             :   }
+     297             : 
+     298             : // Retrieve final displacement vector
+     299           2 :   unsigned aind = plmd.getActionSet().size()-1;
+     300             :   while( true ) {
+     301           3 :     const ActionShortcut* as=dynamic_cast<const ActionShortcut*>( plmd.getActionSet()[aind].get() );
+     302           3 :     if( !as ) break ; aind = aind - 1; plumed_assert( aind>=0 );
+     303           1 :   }
+     304           2 :   ActionWithValue* av = dynamic_cast<ActionWithValue*>( plmd.getActionSet()[aind].get() );
+     305           2 :   if( !av ) error("invalid input for metric" );
+     306           2 :   if( av->getNumberOfComponents()!=1 && av->getName()!="RMSD_VECTOR" ) error("cannot use multi component actions as metric");
+     307           2 :   std::string mydisp = av->copyOutput(0)->getName();
+     308             : // Now add calls so we can grab the data from plumed
+     309           4 :   long rank; plmd.cmd("getDataRank " + mydisp, &rank );
+     310           2 :   if( rank!=1 ) error("displacement must be a vector quantity");
+     311           4 :   std::vector<long> ishape( rank ); plmd.cmd("getDataShape " + mydisp, &ishape[0] );
+     312           4 :   std::vector<double> displacement( ishape[0] ); plmd.cmd("setMemoryForData " + mydisp, &displacement[0] );
+     313             : // And calculate the displacement
+     314           2 :   plmd.cmd("calc");
+     315             : 
+     316             :   // Now read in the initial frame
+     317             : 
+     318             :   // Now create frames
+     319           2 :   double delr = 1.0 / static_cast<double>( nbetween ); std::vector<std::vector<double> > allframes; std::vector<double> frame( displacement.size() );
+     320           4 :   for(int i=0; i<nbefore; ++i) {
+     321          43 :     for(unsigned j=0; j<frame.size(); ++j) frame[j] = start_pos[j] - i*delr*displacement[j];
+     322           2 :     allframes.push_back( frame );
+     323             :   }
+     324           8 :   for(unsigned i=1; i<nbetween; ++i) {
+     325          55 :     for(unsigned j=0; j<frame.size(); ++j) frame[j] = start_pos[j] + i*delr*displacement[j];
+     326           6 :     allframes.push_back( frame );
+     327             :   }
+     328           7 :   for(unsigned i=0; i<nafter; ++i) {
+     329          52 :     for(unsigned j=0; j<frame.size(); ++j) frame[j] = end_pos[j] + i*delr*displacement[j];
+     330           5 :     allframes.push_back( frame );
+     331             :   }
+     332             :   // This prints out our final reference configurations
+     333           4 :   plmd.cmd("clear"); plmd.readInputLine("timestep: PUT UNIT=time PERIODIC=NO CONSTANT");
+     334           2 :   ActionToPutData* ts = plmd.getActionSet().selectWithLabel<ActionToPutData*>("timestep");
+     335           4 :   ts->setValuePointer("timestep", &tstep );
+     336           4 :   std::string pinput="DUMPPDB STRIDE=1 DESCRIPTION=PATH FILE=" + ofilename + " FMT=" + ofmt;
+     337           2 :   if( argstr.size()>0 ) {
+     338           3 :     for(unsigned i=0; i<argstr.size(); ++i) {
+     339           2 :       std::string rnum; Tools::convert( allframes[0][i], rnum );
+     340           2 :       std::string inpt = argstr[i] + ": CONSTANT VALUES=" + rnum;
+     341          20 :       for(unsigned j=1; j<allframes.size(); ++j) { Tools::convert( allframes[j][i], rnum ); inpt += "," + rnum; }
+     342           2 :       const char* icinp=inpt.c_str(); plmd.cmd("readInputLine",icinp);
+     343           4 :       if( i==0 ) pinput += " ARG=" + argstr[i]; else pinput += "," + argstr[i];
+     344             :     }
+     345             :   } else {
+     346           1 :     std::string nc; Tools::convert( frame.size(), nc );
+     347           1 :     std::string nr; Tools::convert( allframes.size(), nr );
+     348           1 :     std::string rnum; Tools::convert( allframes[0][0], rnum );
+     349           2 :     std::string inpt = "atom_data: CONSTANT NROWS=" + nr + " NCOLS=" + nc + " VALUES=" + rnum;
+     350           4 :     for(unsigned i=0; i<allframes.size(); ++i) {
+     351         120 :       for(unsigned j=0; j<allframes[i].size(); ++j) {
+     352         233 :         if( i==0 && j==0 ) continue; Tools::convert( allframes[i][j], rnum ); inpt += "," + rnum;
+     353             :       }
+     354             :     }
+     355           1 :     const char* icinp=inpt.c_str(); plmd.cmd("readInputLine",icinp); std::string num; Tools::convert( indices[0].serial(), num );
+     356          14 :     pinput += " ATOMS=atom_data ATOM_INDICES=" + num; for(unsigned i=1; i<indices.size(); ++i ) { Tools::convert( indices[i].serial(), num ); pinput += "," + num; }
+     357             :   }
+     358           2 :   const char* pcinp=pinput.c_str(); plmd.cmd("readInputLine",pcinp);
+     359             :   Action* paction = plmd.getActionSet()[plmd.getActionSet().size()-1].get();
+     360           2 :   paction->update();
+     361             :   // And output suggestions on the value of Lambda
+     362           2 :   printLambda( mtype, argstr, ofilename );
+     363             :   return 0;
+     364          10 : }
+     365             : 
+     366           4 : void PathTools::printLambda( const std::string& mtype, const std::vector<std::string>& argstr, const std::string& ofile ) {
+     367             :   // Create a PLUMED object
+     368           4 :   PlumedMain plmd; int s=sizeof(double);
+     369           4 :   plmd.cmd("setRealPrecision",&s);
+     370           4 :   plmd.cmd("setMDEngine","pathtools");
+     371           4 :   double tstep=1.0; plmd.cmd("setTimestep",&tstep);
+     372           4 :   plmd.cmd("init");
+     373           4 :   int step=1; plmd.cmd("setStep",&step);
+     374             : 
+     375           4 :   FILE* fp=fopen(ofile.c_str(),"r");
+     376             :   bool do_read=true; unsigned nfram=0;
+     377             :   std::vector<double> alig, disp;
+     378             :   // Read in the argument names
+     379           8 :   for(unsigned i=0; i<argstr.size(); ++i ) {
+     380           4 :     std::string input2 = argstr[i] + ": CONSTANT VALUE=1";
+     381           4 :     const char* inpt2 = input2.c_str(); plmd.cmd("readInputLine", inpt2);
+     382             :   }
+     383          37 :   while (do_read ) {
+     384          37 :     PDB mypdb;
+     385             :     // Read the pdb file
+     386          37 :     do_read=mypdb.readFromFilepointer(fp,false,0.1); if( !do_read ) break;
+     387          33 :     std::string num; Tools::convert( nfram+1, num ); nfram++; std::string iinput;
+     388          33 :     if( argstr.size()>0 ) {
+     389          60 :       for(unsigned i=0; i<argstr.size(); ++i ) {
+     390          80 :         std::string input = "ref_" + num + "_" + argstr[i] + ": PDB2CONSTANT REFERENCE=" + ofile + " ARG=" + argstr[i] + " NUMBER=" + num;
+     391          40 :         const char* inpt = input.c_str(); plmd.cmd("readInputLine", inpt );
+     392             :       }
+     393             :     } else {
+     394          26 :       std::string input = "ref_" + num + ": PDB2CONSTANT REFERENCE=" + ofile + " NUMBER=" + num;
+     395          13 :       const char* inpt = input.c_str(); plmd.cmd("readInputLine", inpt );
+     396             :     }
+     397             : 
+     398          33 :     if( nfram==1 ) {
+     399           4 :       alig.resize( mypdb.getOccupancy().size() );
+     400          30 :       for(unsigned i=0; i<alig.size(); ++i) alig[i]=mypdb.getOccupancy()[i];
+     401           4 :       disp.resize( mypdb.getBeta().size() );
+     402          30 :       for(unsigned i=0; i<disp.size(); ++i) disp[i]=mypdb.getBeta()[i];
+     403             :     }
+     404          37 :   }
+     405             :   // Now create the objects to measure the distances between the frames
+     406           4 :   std::vector<double> data( nfram );
+     407          33 :   for(unsigned j=1; j<nfram; ++j) {
+     408          29 :     std::string istr, jstr; Tools::convert( j, istr); Tools::convert( j+1, jstr );
+     409          76 :     if( mtype=="OPTIMAL-FAST" || mtype=="OPTIMAL" || mtype=="SIMPLE" ) {
+     410          22 :       std::string strv = "ref_" + jstr + "T: TRANSPOSE ARG=ref_" + jstr;
+     411          11 :       const char* cstrv = strv.c_str(); plmd.cmd("readInputLine",cstrv);
+     412          22 :       std::string dstring = "d" + istr + ": RMSD_VECTOR TYPE=" + mtype + " ARG=ref_" + jstr + "T,ref_" + istr;
+     413             :       // Get the align values
+     414          11 :       std::string anum; Tools::convert( alig[0], anum ); dstring += " ALIGN=" + anum;
+     415         143 :       for(unsigned i=1; i<alig.size(); ++i) { Tools::convert( alig[i], anum ); dstring += "," + anum; }
+     416             :       // Get the displace values
+     417          11 :       std::string dnum; Tools::convert( disp[0], dnum ); dstring += " DISPLACE=" + dnum;
+     418         143 :       for(unsigned i=1; i<disp.size(); ++i) { Tools::convert( disp[i], dnum ); dstring += "," + dnum; }
+     419          11 :       const char* icinp=dstring.c_str(); plmd.cmd("readInputLine",icinp);
+     420          18 :     } else if( mtype=="EUCLIDEAN" ) {
+     421          54 :       std::string end_args="ARG1=ref_" + istr + "_" + argstr[0], start_args="ARG2=ref_" + jstr + "_" + argstr[0];
+     422          54 :       for(unsigned i=1; i<argstr.size(); ++i ) { end_args += ",ref_" + istr + "_" + argstr[i]; start_args += ",ref_" + jstr + "_" + argstr[i]; }
+     423          36 :       std::string fstr = "d" + istr + ": EUCLIDEAN_DISTANCE " + end_args + " " + start_args;
+     424          18 :       const char* icinp=fstr.c_str(); plmd.cmd("readInputLine",icinp);
+     425             :     } else {
+     426           0 :       plumed_merror("metric type " + mtype + " has not been implemented");
+     427             :     }
+     428          58 :     long rank; plmd.cmd("getDataRank d" + istr, &rank );
+     429          29 :     if( rank!=1 ) error("distance should be of rank 1");
+     430          58 :     std::vector<long> ishape(1); plmd.cmd("getDataShape d" + istr, &ishape[0] );
+     431          29 :     if( ishape[0]!=1 ) error("distance should be of rank 1");
+     432          58 :     plmd.cmd("setMemoryForData d" + istr, &data[j-1] );
+     433             :   }
+     434           4 :   plmd.cmd("calc"); double mean=0;
+     435             :   printf("N.B. THIS CODE ALWAYS AIMS TO CREATE EQUALLY SPACED FRAMES \n");
+     436             :   printf("THERE MAY BE SMALL DESCREPENCIES IN THE NUMBERS BELOW, HOWEVER, BECAUSE OF ROUNDING ERRORS \n");
+     437          33 :   for(unsigned i=1; i<nfram; ++i) {
+     438          29 :     printf("FINAL DISTANCE BETWEEN FRAME %u AND %u IS %f \n",i-1,i,data[i-1]); mean += data[i-1];
+     439             :   }
+     440           4 :   printf("SUGGESTED LAMBDA PARAMETER IS THUS %f \n",2.3/mean/static_cast<double>( nfram-1 ) );
+     441           4 : }
+     442             : 
+     443             : } // End of namespace
+     444             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/index-sort-f.html b/coverage/mapping/index-sort-f.html new file mode 100644 index 000000000000..ff6e6ebbed0c --- /dev/null +++ b/coverage/mapping/index-sort-f.html @@ -0,0 +1,174 @@ + + + + + + + + LCOV - plumed test coverage - mapping + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mappingHitTotalCoverage
Test:plumed test coverageLines:77780496.6 %
Date:2024-04-19 12:12:35Functions:475683.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
AdaptivePath.cpp +
98.0%98.0%
+
98.0 %49 / 5066.7 %2 / 3
GeometricPathShortcut.cpp +
100.0%
+
100.0 %20 / 2066.7 %2 / 3
PCAVars.cpp +
96.6%96.6%
+
96.6 %86 / 8966.7 %2 / 3
GeometricPath.cpp +
98.4%98.4%
+
98.4 %61 / 6266.7 %4 / 6
PathDisplacements.cpp +
95.8%95.8%
+
95.8 %69 / 7275.0 %6 / 8
Path.cpp +
91.2%91.2%
+
91.2 %93 / 10285.7 %6 / 7
PathReparameterization.cpp +
95.7%95.7%
+
95.7 %90 / 9490.0 %9 / 10
PathProjectionCalculator.cpp +
98.8%98.8%
+
98.8 %80 / 81100.0 %8 / 8
PathTools.cpp +
97.9%97.9%
+
97.9 %229 / 234100.0 %8 / 8
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/index-sort-l.html b/coverage/mapping/index-sort-l.html new file mode 100644 index 000000000000..95533ea9a4a8 --- /dev/null +++ b/coverage/mapping/index-sort-l.html @@ -0,0 +1,174 @@ + + + + + + + + LCOV - plumed test coverage - mapping + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mappingHitTotalCoverage
Test:plumed test coverageLines:77780496.6 %
Date:2024-04-19 12:12:35Functions:475683.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Path.cpp +
91.2%91.2%
+
91.2 %93 / 10285.7 %6 / 7
PathReparameterization.cpp +
95.7%95.7%
+
95.7 %90 / 9490.0 %9 / 10
PathDisplacements.cpp +
95.8%95.8%
+
95.8 %69 / 7275.0 %6 / 8
PCAVars.cpp +
96.6%96.6%
+
96.6 %86 / 8966.7 %2 / 3
PathTools.cpp +
97.9%97.9%
+
97.9 %229 / 234100.0 %8 / 8
AdaptivePath.cpp +
98.0%98.0%
+
98.0 %49 / 5066.7 %2 / 3
GeometricPath.cpp +
98.4%98.4%
+
98.4 %61 / 6266.7 %4 / 6
PathProjectionCalculator.cpp +
98.8%98.8%
+
98.8 %80 / 81100.0 %8 / 8
GeometricPathShortcut.cpp +
100.0%
+
100.0 %20 / 2066.7 %2 / 3
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/index.html b/coverage/mapping/index.html new file mode 100644 index 000000000000..92e85264c3ec --- /dev/null +++ b/coverage/mapping/index.html @@ -0,0 +1,174 @@ + + + + + + + + LCOV - plumed test coverage - mapping + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mappingHitTotalCoverage
Test:plumed test coverageLines:77780496.6 %
Date:2024-04-19 12:12:35Functions:475683.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
AdaptivePath.cpp +
98.0%98.0%
+
98.0 %49 / 5066.7 %2 / 3
GeometricPath.cpp +
98.4%98.4%
+
98.4 %61 / 6266.7 %4 / 6
GeometricPathShortcut.cpp +
100.0%
+
100.0 %20 / 2066.7 %2 / 3
PCAVars.cpp +
96.6%96.6%
+
96.6 %86 / 8966.7 %2 / 3
Path.cpp +
91.2%91.2%
+
91.2 %93 / 10285.7 %6 / 7
PathDisplacements.cpp +
95.8%95.8%
+
95.8 %69 / 7275.0 %6 / 8
PathProjectionCalculator.cpp +
98.8%98.8%
+
98.8 %80 / 81100.0 %8 / 8
PathReparameterization.cpp +
95.7%95.7%
+
95.7 %90 / 9490.0 %9 / 10
PathTools.cpp +
97.9%97.9%
+
97.9 %229 / 234100.0 %8 / 8
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Loss.cpp.func-sort-c.html b/coverage/maze/Loss.cpp.func-sort-c.html new file mode 100644 index 000000000000..ef4a353f78eb --- /dev/null +++ b/coverage/maze/Loss.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - maze/Loss.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Loss.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2323100.0 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze4LossC2ERKNS_13ActionOptionsE0
_ZN4PLMD4maze4LossC1ERKNS_13ActionOptionsE8
_ZN4PLMD4maze4Loss16registerKeywordsERNS_8KeywordsE10
_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 000000000000..9f1a3b289935 --- /dev/null +++ b/coverage/maze/Loss.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - maze/Loss.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Loss.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2323100.0 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_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 000000000000..cf0ca2e72feb --- /dev/null +++ b/coverage/maze/Loss.cpp.gcov.html @@ -0,0 +1,191 @@ + + + + + + + + LCOV - plumed test coverage - maze/Loss.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Loss.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2323100.0 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2019 Jakub Rydzewski (jr@fizyka.umk.pl). All rights reserved.
+       3             : 
+       4             : See http://www.maze-code.github.io for more information.
+       5             : 
+       6             : This file is part of maze.
+       7             : 
+       8             : maze is free software: you can redistribute it and/or modify it under the
+       9             : terms of the GNU Lesser General Public License as published by the Free
+      10             : Software Foundation, either version 3 of the License, or (at your option)
+      11             : any later version.
+      12             : 
+      13             : maze is distributed in the hope that it will be useful, but WITHOUT ANY
+      14             : WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+      15             : FOR A PARTICULAR PURPOSE.
+      16             : 
+      17             : See the GNU Lesser General Public License for more details.
+      18             : 
+      19             : You should have received a copy of the GNU Lesser General Public License
+      20             : along with maze. If not, see <https://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : /**
+      24             :  * @file Loss.cpp
+      25             :  * @author J. Rydzewski (jr@fizyka.umk.pl)
+      26             :  */
+      27             : 
+      28             : #include "Loss.h"
+      29             : #include "core/PlumedMain.h"
+      30             : 
+      31             : namespace PLMD {
+      32             : namespace maze {
+      33             : 
+      34             : //+PLUMEDOC MAZE_LOSS MAZE_LOSS
+      35             : /*
+      36             : 
+      37             : Define a coarse-grained loss function describing interactions in a
+      38             : ligand-protein complex, which is minimized during the simulation to
+      39             : obtain ligand unbinding pathways.
+      40             : 
+      41             : The loss function is the following:
+      42             : \f[
+      43             : \mathcal{L}=
+      44             : \sum_{i=1}^{N_p}
+      45             : r_i^{-\alpha}\text{e}^{-\beta r_i^{-\gamma}},
+      46             : \f]
+      47             : where \f$N_p\f$ is the number of ligand-protein atom pairs, \f$r\f$
+      48             : is a re-scaled distance between the \f$i\f$th pair, and \f$\alpha,
+      49             : \beta, \gamma\f$ are the positive parameters defined in that order by
+      50             : the PARAMS keyword.
+      51             : 
+      52             : \par Examples
+      53             : 
+      54             : The loss function can be defined in the following way:
+      55             : \plumedfile
+      56             : l: MAZE_LOSS PARAMS=1,1,1
+      57             : \endplumedfile
+      58             : 
+      59             : */
+      60             : //+ENDPLUMEDOC
+      61             : 
+      62             : // Registers the LOSS action.
+      63             : PLUMED_REGISTER_ACTION(Loss, "MAZE_LOSS")
+      64             : 
+      65          10 : void Loss::registerKeywords(Keywords& keys) {
+      66          10 :   Colvar::registerKeywords(keys);
+      67             : 
+      68          20 :   keys.add(
+      69             :     "compulsory",
+      70             :     "PARAMS",
+      71             :     "Parameters for the loss function."
+      72             :   );
+      73          10 : }
+      74             : 
+      75           8 : Loss::Loss(const ActionOptions& ao)
+      76           8 :   : PLUMED_COLVAR_INIT(ao)
+      77             : {
+      78          16 :   if (keywords.exists("PARAMS")) {
+      79          16 :     parseVector("PARAMS", params_);
+      80             : 
+      81           8 :     plumed_massert(
+      82             :       params_.size() == 3,
+      83             :       "maze> PARAMS should be of size 3: alpha, beta, gamma\n"
+      84             :     );
+      85             : 
+      86           8 :     plumed_massert(
+      87             :       params_[0] > 0 && params_[1] > 0 && params_[2] > 0,
+      88             :       "maze> Each parameter should be positive\n"
+      89             :     );
+      90             : 
+      91           8 :     log.printf("maze> \t Loss parsed with parameters: ");
+      92          32 :     for (size_t i = 0; i < params_.size(); ++i) {
+      93          24 :       log.printf("%f ", params_[i]);
+      94             :     }
+      95           8 :     log.printf("\n");
+      96             :   }
+      97             : 
+      98           8 :   checkRead();
+      99           8 : }
+     100             : 
+     101    14974890 : double Loss::pairing(double distance) {
+     102    14974890 :   double alpha = params_[0];
+     103    14974890 :   double beta = params_[1];
+     104    14974890 :   double gamma = params_[2];
+     105             : 
+     106    29949780 :   if (getUnits().getLengthString() == "nm") {
+     107    14855760 :     distance *= 10.0;
+     108             :   }
+     109             : 
+     110    14974890 :   return pow(distance, -alpha) * exp(-beta * pow(distance, gamma));
+     111             : }
+     112             : 
+     113             : } // namespace maze
+     114             : } // namespace PLMD
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Loss.h.func-sort-c.html b/coverage/maze/Loss.h.func-sort-c.html new file mode 100644 index 000000000000..c4cce2555141 --- /dev/null +++ b/coverage/maze/Loss.h.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - maze/Loss.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Loss.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1250.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze4Loss9calculateEv0
_ZN4PLMD4maze4LossD0Ev8
_ZN4PLMD4maze4LossD1Ev8
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Loss.h.func.html b/coverage/maze/Loss.h.func.html new file mode 100644 index 000000000000..d1b6ca4fb9d9 --- /dev/null +++ b/coverage/maze/Loss.h.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - maze/Loss.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Loss.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1250.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze4Loss9calculateEv0
_ZN4PLMD4maze4LossD0Ev8
_ZN4PLMD4maze4LossD1Ev8
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Loss.h.gcov.html b/coverage/maze/Loss.h.gcov.html new file mode 100644 index 000000000000..eef6dd022c78 --- /dev/null +++ b/coverage/maze/Loss.h.gcov.html @@ -0,0 +1,163 @@ + + + + + + + + LCOV - plumed test coverage - maze/Loss.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Loss.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1250.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2019 Jakub Rydzewski (jr@fizyka.umk.pl). All rights reserved.
+       3             : 
+       4             : See http://www.maze-code.github.io for more information.
+       5             : 
+       6             : This file is part of maze.
+       7             : 
+       8             : maze is free software: you can redistribute it and/or modify it under the
+       9             : terms of the GNU Lesser General Public License as published by the Free
+      10             : Software Foundation, either version 3 of the License, or (at your option)
+      11             : any later version.
+      12             : 
+      13             : maze is distributed in the hope that it will be useful, but WITHOUT ANY
+      14             : WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+      15             : FOR A PARTICULAR PURPOSE.
+      16             : 
+      17             : See the GNU Lesser General Public License for more details.
+      18             : 
+      19             : You should have received a copy of the GNU Lesser General Public License
+      20             : along with maze. If not, see <https://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_maze_Loss_h
+      23             : #define __PLUMED_maze_Loss_h
+      24             : 
+      25             : /**
+      26             :  * @file Loss.h
+      27             :  *
+      28             :  * @author J. Rydzewski (jr@fizyka.umk.pl)
+      29             :  */
+      30             : 
+      31             : #include "colvar/Colvar.h"
+      32             : #include "core/ActionRegister.h"
+      33             : #include "Core.h"
+      34             : 
+      35             : namespace PLMD {
+      36             : namespace maze {
+      37             : 
+      38             : /**
+      39             :  * @class Loss Loss.h "maze/Loss.h"
+      40             :  *
+      41             :  * @brief Loss function describes a score between a ligand-protein conformation.
+      42             :  *
+      43             :  * Loss function must be defined for an optimizer as it minimizes a loss
+      44             :  * of a ligand-protein conformation in order to simulate the ligand-protein
+      45             :  * dissociation process.
+      46             :  */
+      47             : class Loss: public colvar::Colvar {
+      48             : public:
+      49             :   /**
+      50             :    * PLMD constructor.
+      51             :    *
+      52             :    * @param[in] ao PLMD::ActionOptions&.
+      53             :    */
+      54             :   explicit Loss(const ActionOptions& ao);
+      55             : 
+      56             :   /**
+      57             :    * Destructor.
+      58             :    */
+      59          16 :   ~Loss() { /* Nothing to do. */ }
+      60             : 
+      61             :   /**
+      62             :    * Register PLMD keywords.
+      63             :    *
+      64             :    * @param[in] keys Keywords.
+      65             :    */
+      66             :   static void registerKeywords(Keywords& keys);
+      67             : 
+      68             :   /**
+      69             :    * Calculate a loss of a single pair of ligand-protein atoms.
+      70             :    *
+      71             :    * @param[in] distance Distance between atoms in the pair.
+      72             :    */
+      73             :   double pairing(double distance);
+      74             : 
+      75             :   // Required by the Colvar class.
+      76           0 :   void calculate() override { /* Nothing to do. */ }
+      77             : 
+      78             : protected:
+      79             :   //! Parameters of the loss function.
+      80             :   std::vector<double> params_;
+      81             : };
+      82             : 
+      83             : } // namespace maze
+      84             : } // namespace PLMD
+      85             : 
+      86             : #endif // __PLUMED_maze_Loss_h
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Member.h.func-sort-c.html b/coverage/maze/Member.h.func-sort-c.html new file mode 100644 index 000000000000..9c46fad1f895 --- /dev/null +++ b/coverage/maze/Member.h.func-sort-c.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - maze/Member.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Member.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:55100.0 %
Date:2024-04-19 12:12:35Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze6MemberC2Ev324
_ZN4PLMD4maze7compareERNS0_6MemberES2_416
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Member.h.func.html b/coverage/maze/Member.h.func.html new file mode 100644 index 000000000000..12c6ed08eb9e --- /dev/null +++ b/coverage/maze/Member.h.func.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - maze/Member.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Member.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:55100.0 %
Date:2024-04-19 12:12:35Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze6MemberC2Ev324
_ZN4PLMD4maze7compareERNS0_6MemberES2_416
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Member.h.gcov.html b/coverage/maze/Member.h.gcov.html new file mode 100644 index 000000000000..46ff0909a4f6 --- /dev/null +++ b/coverage/maze/Member.h.gcov.html @@ -0,0 +1,143 @@ + + + + + + + + LCOV - plumed test coverage - maze/Member.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Member.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:55100.0 %
Date:2024-04-19 12:12:35Functions: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         416 : inline bool compare(Member& m, Member& n) {
+      60         416 :   return m.score > n.score;
+      61             : }
+      62             : 
+      63             : } // namespace maze
+      64             : } // namespace PLMD
+      65             : 
+      66             : #endif // __PLUMED_maze_Member_h
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Memetic.cpp.func-sort-c.html b/coverage/maze/Memetic.cpp.func-sort-c.html new file mode 100644 index 000000000000..27d676e9d30b --- /dev/null +++ b/coverage/maze/Memetic.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - maze/Memetic.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Memetic.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:6060100.0 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze7MemeticC2ERKNS_13ActionOptionsE0
_ZN4PLMD4maze7MemeticC1ERKNS_13ActionOptionsE2
_ZN4PLMD4maze7Memetic16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD4maze7Memetic8optimizeEv6
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Memetic.cpp.func.html b/coverage/maze/Memetic.cpp.func.html new file mode 100644 index 000000000000..4927204d03b4 --- /dev/null +++ b/coverage/maze/Memetic.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - maze/Memetic.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Memetic.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:6060100.0 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze7Memetic16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD4maze7Memetic8optimizeEv6
_ZN4PLMD4maze7MemeticC1ERKNS_13ActionOptionsE2
_ZN4PLMD4maze7MemeticC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Memetic.cpp.gcov.html b/coverage/maze/Memetic.cpp.gcov.html new file mode 100644 index 000000000000..c5d0a3cb7804 --- /dev/null +++ b/coverage/maze/Memetic.cpp.gcov.html @@ -0,0 +1,359 @@ + + + + + + + + LCOV - plumed test coverage - maze/Memetic.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Memetic.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:6060100.0 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2019 Jakub Rydzewski (jr@fizyka.umk.pl). All rights reserved.
+       3             : 
+       4             : See http://www.maze-code.github.io for more information.
+       5             : 
+       6             : This file is part of maze.
+       7             : 
+       8             : maze is free software: you can redistribute it and/or modify it under the
+       9             : terms of the GNU Lesser General Public License as published by the Free
+      10             : Software Foundation, either version 3 of the License, or (at your option)
+      11             : any later version.
+      12             : 
+      13             : maze is distributed in the hope that it will be useful, but WITHOUT ANY
+      14             : WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+      15             : FOR A PARTICULAR PURPOSE.
+      16             : 
+      17             : See the GNU Lesser General Public License for more details.
+      18             : 
+      19             : You should have received a copy of the GNU Lesser General Public License
+      20             : along with maze. If not, see <https://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : /**
+      24             :  * @file Memetic.cpp
+      25             :  * @author J. Rydzewski (jr@fizyka.umk.pl)
+      26             :  */
+      27             : 
+      28             : #include "Memetic.h"
+      29             : 
+      30             : namespace PLMD {
+      31             : namespace maze {
+      32             : 
+      33             : //+PLUMEDOC MAZE_OPTIMIZER MAZE_MEMETIC_SAMPLING
+      34             : /*
+      35             : 
+      36             : Calculates the biasing direction along which the ligand unbinds by
+      37             : minimizing the \ref MAZE_LOSS function. The optimal biasing direction is
+      38             : determined by performing a population-based memetics search with local
+      39             : heuristics.
+      40             : 
+      41             : \par Examples
+      42             : 
+      43             : Every optimizer implemented in the maze module needs a loss function as
+      44             : an argument, and it should be passed using the \ref MAZE_LOSS keyword.
+      45             : 
+      46             : \plumedfile
+      47             : MAZE_MEMETIC_SAMPLING ...
+      48             :   LABEL=ma
+      49             : 
+      50             :   LOSS=l
+      51             : 
+      52             :   N_ITER=10
+      53             :   OPTIMIZER_STRIDE=200
+      54             : 
+      55             :   CAPACITY=20
+      56             : 
+      57             :   LOCAL_SEARCH_ON
+      58             :   N_LOCAL_ITER=10
+      59             :   LOCAL_SEARCH_RATE=0.1
+      60             :   LOCAL_SEARCH_TYPE=stochastic_hill_climbing
+      61             : 
+      62             :   MUTATION_RATE=0.1
+      63             :   MATING_RATE=0.7
+      64             :   CAUCHY_ALPHA=0
+      65             :   CAUCHY_BETA=0.1
+      66             : 
+      67             :   LIGAND=2635-2646
+      68             :   PROTEIN=1-2634
+      69             : ... MAZE_MEMETIC_SAMPLING
+      70             : \endplumedfile
+      71             : 
+      72             : As shown above, each optimizer should be provided with the LIGAND and
+      73             : the PROTEIN keywords.
+      74             : 
+      75             : The neighbor list can be turned on by providing the NLIST keyword.
+      76             : 
+      77             : */
+      78             : //+ENDPLUMEDOC
+      79             : 
+      80             : /**
+      81             :  * Register MAZE_MEMETIC_SAMPLING.
+      82             :  */
+      83             : PLUMED_REGISTER_ACTION(Memetic, "MAZE_MEMETIC_SAMPLING")
+      84             : 
+      85           4 : void Memetic::registerKeywords(Keywords& keys) {
+      86           4 :   Optimizer::registerKeywords(keys);
+      87             : 
+      88           8 :   keys.add(
+      89             :     "compulsory",
+      90             :     "CAPACITY",
+      91             :     "Sampling set size."
+      92             :   );
+      93             : 
+      94           8 :   keys.add(
+      95             :     "compulsory",
+      96             :     "MUTATION_RATE",
+      97             :     "Probability of mutation."
+      98             :   );
+      99             : 
+     100           8 :   keys.add(
+     101             :     "compulsory",
+     102             :     "MATING_RATE",
+     103             :     "Probability of mating."
+     104             :   );
+     105             : 
+     106           8 :   keys.add(
+     107             :     "compulsory",
+     108             :     "CAUCHY_ALPHA",
+     109             :     "Mean of Cauchy distribution for sampling."
+     110             :   );
+     111             : 
+     112           8 :   keys.add(
+     113             :     "compulsory",
+     114             :     "CAUCHY_BETA",
+     115             :     "Spread of Cauchy distribution for sampling."
+     116             :   );
+     117             : 
+     118           8 :   keys.addFlag(
+     119             :     "LOCAL_SEARCH_ON",
+     120             :     false,
+     121             :     "Turn local search on."
+     122             :   );
+     123             : 
+     124           8 :   keys.add(
+     125             :     "optional",
+     126             :     "N_LOCAL_ITER",
+     127             :     "Number of local search iterations."
+     128             :   );
+     129             : 
+     130           8 :   keys.add(
+     131             :     "optional",
+     132             :     "LOCAL_SEARCH_RATE",
+     133             :     "Rate of mutation in local search."
+     134             :   );
+     135             : 
+     136           8 :   keys.add(
+     137             :     "optional",
+     138             :     "LOCAL_SEARCH_TYPE",
+     139             :     "Type of local search."
+     140             :   );
+     141           4 : }
+     142             : 
+     143           2 : Memetic::Memetic(const ActionOptions& ao)
+     144             :   : PLUMED_OPT_INIT(ao),
+     145           2 :     bound_(true),
+     146           2 :     score_worst_(0),
+     147           2 :     score_best_(0),
+     148           2 :     adaptation_(true),
+     149           2 :     coding_len_(3),
+     150           2 :     local_search_on_(false)
+     151             : {
+     152           2 :   log.printf("maze> Memetic sampling.\n");
+     153             : 
+     154           4 :   if (keywords.exists("CAPACITY")) {
+     155           2 :     parse("CAPACITY", capacity_);
+     156             : 
+     157           2 :     plumed_massert(
+     158             :       capacity_ > 0,
+     159             :       "maze> CAPACITY should be explicitly specified and positive.\n"
+     160             :     );
+     161             : 
+     162           2 :     log.printf(
+     163             :       "maze> CAPACITY read: %u.\n",
+     164             :       capacity_
+     165             :     );
+     166             :   }
+     167             : 
+     168           4 :   if (keywords.exists("MUTATION_RATE")) {
+     169           2 :     parse("MUTATION_RATE", mutation_rate_);
+     170             : 
+     171           2 :     plumed_massert(
+     172             :       mutation_rate_ > 0 && mutation_rate_ <= 1,
+     173             :       "maze> MUTATION_RATE should be in [0, 1).\n"
+     174             :     );
+     175             : 
+     176           2 :     log.printf(
+     177             :       "maze> MUTATION_RATE read: %f.\n",
+     178             :       mutation_rate_
+     179             :     );
+     180             :   }
+     181             : 
+     182           4 :   if (keywords.exists("MATING_RATE")) {
+     183           2 :     parse("MATING_RATE", mating_rate_);
+     184             : 
+     185           2 :     plumed_massert(
+     186             :       mating_rate_ > 0 && mating_rate_ <= 1,
+     187             :       "maze> MATING_RATE should be in [0, 1).\n"
+     188             :     );
+     189             : 
+     190           2 :     log.printf(
+     191             :       "maze> MATING_RATE read: %f.\n",
+     192             :       mating_rate_
+     193             :     );
+     194             :   }
+     195             : 
+     196           4 :   if (keywords.exists("CAUCHY_ALPHA")) {
+     197           2 :     parse("CAUCHY_ALPHA", cauchy_mean_alpha_);
+     198             : 
+     199           2 :     log.printf(
+     200             :       "maze> CAUCHY_ALPHA read: %f.\n",
+     201             :       cauchy_mean_alpha_
+     202             :     );
+     203             :   }
+     204             : 
+     205           4 :   if (keywords.exists("CAUCHY_BETA")) {
+     206           2 :     parse("CAUCHY_BETA", cauchy_mean_beta_);
+     207             : 
+     208           2 :     plumed_massert(
+     209             :       cauchy_mean_beta_ > 0,
+     210             :       "maze> CAUCHY_BETA should be explicitly specified and positive.\n"
+     211             :     );
+     212             : 
+     213           2 :     log.printf(
+     214             :       "maze> CAUCHY_BETA read: %f.\n",
+     215             :       cauchy_mean_beta_
+     216             :     );
+     217             :   }
+     218             : 
+     219           4 :   if (keywords.exists("LOCAL_SEARCH_ON")) {
+     220           2 :     parseFlag("LOCAL_SEARCH_ON", local_search_on_);
+     221             : 
+     222           2 :     log.printf("maze> LOCAL_SEARCH_ON enabled: %d.\n", local_search_on_);
+     223             :   }
+     224             : 
+     225           2 :   if (local_search_on_) {
+     226           1 :     parse("N_LOCAL_ITER", n_local_iterations_);
+     227             : 
+     228           1 :     plumed_massert(
+     229             :       n_local_iterations_ > 0,
+     230             :       "maze> N_LOCAL_ITER should be explicitly specified and positive.\n"
+     231             :     );
+     232             : 
+     233           1 :     log.printf(
+     234             :       "maze> N_LOCAL_ITER read: %u.\n",
+     235             :       n_local_iterations_
+     236             :     );
+     237             : 
+     238           1 :     parse("LOCAL_SEARCH_RATE", local_search_rate_);
+     239             : 
+     240           1 :     plumed_massert(
+     241             :       local_search_rate_ > 0 && local_search_rate_ <= 1,
+     242             :       "maze> LOCAL_SEARCH_RATE should be in [0, 1).\n"
+     243             :     );
+     244             : 
+     245           1 :     log.printf(
+     246             :       "maze> LOCAL_SEARCH_RATE read: %f.\n",
+     247             :       local_search_rate_
+     248             :     );
+     249             : 
+     250           2 :     parse("LOCAL_SEARCH_TYPE", local_search_type_);
+     251             : 
+     252           1 :     plumed_massert(
+     253             :       local_search_type_ == "stochastic_hill_climbing" ||
+     254             :       local_search_type_ == "adaptive_random_search",
+     255             :       "maze> LOCAL_SEARCH_TYPE should be: "
+     256             :       "stochastic_hill_climbing, or adaptive_random_search.\n"
+     257             :     );
+     258             : 
+     259           1 :     log.printf(
+     260             :       "maze> LOCAL_SEARCH_TYPE read: %s.\n",
+     261             :       local_search_type_.c_str()
+     262             :     );
+     263             :   }
+     264             : 
+     265           2 :   set_n_global_iterations(n_iter_);
+     266             : 
+     267           4 :   set_label("MEMETIC_SAMPLING");
+     268             : 
+     269             :   start_step_0();
+     270             : 
+     271           2 :   checkRead();
+     272           2 : }
+     273             : 
+     274           6 : void Memetic::optimize() {
+     275           6 :   Vector t = solve();
+     276             : 
+     277             :   set_opt(t);
+     278           6 :   set_opt_value(score());
+     279           6 : }
+     280             : 
+     281             : } // namespace maze
+     282             : } // namespace PLMD
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Memetic.h.func-sort-c.html b/coverage/maze/Memetic.h.func-sort-c.html new file mode 100644 index 000000000000..c8266012e9dc --- /dev/null +++ b/coverage/maze/Memetic.h.func-sort-c.html @@ -0,0 +1,153 @@ + + + + + + + + LCOV - plumed test coverage - maze/Memetic.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Memetic.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12320161.2 %
Date:2024-04-19 12:12:35Functions: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_6MemberE74
_ZN4PLMD4maze7Memetic13out_of_boundsEd76
_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 000000000000..5da3397fa714 --- /dev/null +++ b/coverage/maze/Memetic.h.func.html @@ -0,0 +1,153 @@ + + + + + + + + LCOV - plumed test coverage - maze/Memetic.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Memetic.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12320161.2 %
Date:2024-04-19 12:12:35Functions: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_boundsEd76
_ZN4PLMD4maze7Memetic13score_membersEv30
_ZN4PLMD4maze7Memetic18initialize_membersEv6
_ZN4PLMD4maze7Memetic18selection_rouletteEv30
_ZN4PLMD4maze7Memetic22adaptive_random_searchERNS0_6MemberERKSt6vectorIdSaIdEE0
_ZN4PLMD4maze7Memetic24stochastic_hill_climbingERNS0_6MemberERKSt6vectorIdSaIdEE7
_ZN4PLMD4maze7Memetic28random_restart_hill_climbingERNS0_6MemberERKSt6vectorIdSaIdEE0
_ZN4PLMD4maze7Memetic5solveEv6
_ZN4PLMD4maze7Memetic6matingERSt6vectorINS0_6MemberESaIS3_EE30
_ZN4PLMD4maze7Memetic8mutationERNS0_6MemberE74
_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 000000000000..b56eb34ee4b6 --- /dev/null +++ b/coverage/maze/Memetic.h.gcov.html @@ -0,0 +1,883 @@ + + + + + + + + LCOV - plumed test coverage - maze/Memetic.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Memetic.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12320161.2 %
Date:2024-04-19 12:12:35Functions: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         667 :     for (size_t i = 0; i < cum_sum.size(); ++i) {
+     394         667 :       if (cum_sum[i] > probability) {
+     395         180 :         chosen = i;
+     396             : 
+     397         180 :         members_.at(j).score = sel.at(chosen).score;
+     398         180 :         members_.at(j).translation = sel.at(chosen).translation;
+     399             : 
+     400         180 :         break;
+     401             :       }
+     402             :     }
+     403             :   }
+     404          30 : }
+     405             : 
+     406           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          74 : void Memetic::mutation(Member& m) {
+     424          74 :   int which = rnd::next_int(coding_len_);
+     425          74 :   double v = rnd::next_cauchy(cauchy_mean_alpha_, cauchy_mean_beta_);
+     426          74 :   m.translation[which] += v;
+     427          74 :   if (out_of_bounds(m.translation.modulo())) {
+     428          23 :     m.translation[which] -= v;
+     429             :   }
+     430          74 : }
+     431             : 
+     432          30 : void Memetic::mutation(std::vector<Member>& m) {
+     433         210 :   for (std::vector<Member>::iterator it = m.begin(), end = m.end(); it != end; ++it) {
+     434         180 :     double r = rnd::next_double();
+     435         180 :     if (r < mutation_rate_) {
+     436           4 :       mutation(*it);
+     437             :     }
+     438             :   }
+     439          30 : }
+     440             : 
+     441           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          18 :       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         119 :     while (i == j) {
+     615          29 :       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          40 :     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          76 : bool Memetic::out_of_bounds(double v) {
+     651          76 :   double s = sampling_radius();
+     652             : 
+     653          76 :   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 000000000000..9e588b839c60 --- /dev/null +++ b/coverage/maze/Optimizer.cpp.func-sort-c.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - maze/Optimizer.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Optimizer.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:16218090.0 %
Date:2024-04-19 12:12:35Functions: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_radiusEv325
_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 000000000000..405c169d9e70 --- /dev/null +++ b/coverage/maze/Optimizer.cpp.func.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - maze/Optimizer.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Optimizer.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:16218090.0 %
Date:2024-04-19 12:12:35Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze9Optimizer15sampling_radiusEv325
_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 000000000000..4e46e698df18 --- /dev/null +++ b/coverage/maze/Optimizer.cpp.gcov.html @@ -0,0 +1,587 @@ + + + + + + + + LCOV - plumed test coverage - maze/Optimizer.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Optimizer.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:16218090.0 %
Date:2024-04-19 12:12:35Functions:91090.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2019 Jakub Rydzewski (jr@fizyka.umk.pl). All rights reserved.
+       3             : 
+       4             : See http://www.maze-code.github.io for more information.
+       5             : 
+       6             : This file is part of maze.
+       7             : 
+       8             : maze is free software: you can redistribute it and/or modify it under the
+       9             : terms of the GNU Lesser General Public License as published by the Free
+      10             : Software Foundation, either version 3 of the License, or (at your option)
+      11             : any later version.
+      12             : 
+      13             : maze is distributed in the hope that it will be useful, but WITHOUT ANY
+      14             : WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+      15             : FOR A PARTICULAR PURPOSE.
+      16             : 
+      17             : See the GNU Lesser General Public License for more details.
+      18             : 
+      19             : You should have received a copy of the GNU Lesser General Public License
+      20             : along with maze. If not, see <https://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : /**
+      24             :  * @file Optimizer.cpp
+      25             :  *
+      26             :  * @author J. Rydzewski (jr@fizyka.umk.pl)
+      27             :  */
+      28             : 
+      29             : #include "Optimizer.h"
+      30             : #include "core/PlumedMain.h"
+      31             : #include "tools/Tools.h"
+      32             : 
+      33             : namespace PLMD {
+      34             : namespace maze {
+      35             : 
+      36          17 : void Optimizer::registerKeywords(Keywords& keys) {
+      37          17 :   Colvar::registerKeywords(keys);
+      38             : 
+      39          34 :   keys.addFlag(
+      40             :     "SERIAL",
+      41             :     false,
+      42             :     "Perform the simulation in serial -- used only for debugging purposes, "
+      43             :     "should not be used otherwise."
+      44             :   );
+      45             : 
+      46          34 :   keys.addFlag(
+      47             :     "PAIR",
+      48             :     false,
+      49             :     "Pair only the 1st element of the 1st group with the 1st element in the "
+      50             :     "second, etc."
+      51             :   );
+      52             : 
+      53          34 :   keys.addFlag(
+      54             :     "NLIST",
+      55             :     false,
+      56             :     "Use a neighbor list of ligand-protein atom pairs to speed up the "
+      57             :     "calculating of the distances."
+      58             :   );
+      59             : 
+      60          34 :   keys.add(
+      61             :     "optional",
+      62             :     "NL_CUTOFF",
+      63             :     "Neighbor list cut-off for the distances of ligand-protein atom pairs."
+      64             :   );
+      65             : 
+      66          34 :   keys.add(
+      67             :     "optional",
+      68             :     "NL_STRIDE",
+      69             :     "Update stride for the ligand-protein atom pairs in the neighbor list."
+      70             :   );
+      71             : 
+      72          34 :   keys.add(
+      73             :     "compulsory",
+      74             :     "N_ITER",
+      75             :     "Number of optimization steps. Required only for optimizers, do not pass "
+      76             :     "this keyword to the fake optimizers (results in crash) , e.g., random "
+      77             :     "walk, steered MD, or random acceleration MD."
+      78             :   );
+      79             : 
+      80          34 :   keys.add(
+      81             :     "optional",
+      82             :     "LOSS",
+      83             :     "Loss function describing ligand-protein interactions required by every "
+      84             :     "optimizer."
+      85             :   );
+      86             : 
+      87          34 :   keys.add(
+      88             :     "atoms",
+      89             :     "LIGAND",
+      90             :     "Indices of ligand atoms."
+      91             :   );
+      92             : 
+      93          34 :   keys.add(
+      94             :     "atoms",
+      95             :     "PROTEIN",
+      96             :     "Indices of protein atoms."
+      97             :   );
+      98             : 
+      99          34 :   keys.add(
+     100             :     "compulsory",
+     101             :     "OPTIMIZER_STRIDE",
+     102             :     "Optimizer stride. Sets up a callback function that launches the "
+     103             :     "optimization process every OPTIMIZER_STRIDE."
+     104             :   );
+     105             : 
+     106          17 :   componentsAreNotOptional(keys);
+     107             : 
+     108          34 :   keys.addOutputComponent(
+     109             :     "x",
+     110             :     "default",
+     111             :     "Optimal biasing direction; x component."
+     112             :   );
+     113             : 
+     114          34 :   keys.addOutputComponent(
+     115             :     "y",
+     116             :     "default",
+     117             :     "Optimal biasing direction; y component."
+     118             :   );
+     119             : 
+     120          34 :   keys.addOutputComponent(
+     121             :     "z",
+     122             :     "default",
+     123             :     "Optimal biasing direction; z component."
+     124             :   );
+     125             : 
+     126          34 :   keys.addOutputComponent(
+     127             :     "loss",
+     128             :     "default",
+     129             :     "Loss function value defined by the provided pairing function."
+     130             :   );
+     131             : 
+     132          34 :   keys.addOutputComponent(
+     133             :     "sr",
+     134             :     "default",
+     135             :     "Sampling radius. Reduces sampling to the local proximity of the ligand "
+     136             :     "position."
+     137             :   );
+     138          17 : }
+     139             : 
+     140           7 : Optimizer::Optimizer(const ActionOptions& ao)
+     141             :   : PLUMED_COLVAR_INIT(ao),
+     142           7 :     first_step_(true),
+     143           7 :     opt_value_(0.0),
+     144           7 :     pbc_(true),
+     145           7 :     sampling_r_(0.0),
+     146           7 :     serial_(false),
+     147           7 :     validate_list_(true),
+     148           7 :     first_time_(true)
+     149             : {
+     150           7 :   parseFlag("SERIAL", serial_);
+     151             : 
+     152          14 :   if (keywords.exists("LOSS")) {
+     153           7 :     std::vector<std::string> loss_labels(0);
+     154          14 :     parseVector("LOSS", loss_labels);
+     155             : 
+     156           7 :     plumed_massert(
+     157             :       loss_labels.size() > 0,
+     158             :       "maze> Something went wrong with the LOSS keyword.\n"
+     159             :     );
+     160             : 
+     161           7 :     std::string error_msg = "";
+     162           7 :     vec_loss_ = tls::get_pointers_labels<Loss*>(
+     163             :                   loss_labels,
+     164           7 :                   plumed.getActionSet(),
+     165             :                   error_msg
+     166             :                 );
+     167             : 
+     168           7 :     if (error_msg.size() > 0) {
+     169           0 :       plumed_merror(
+     170             :         "maze> Error in the LOSS keyword " + getName() + ": " + error_msg
+     171             :       );
+     172             :     }
+     173             : 
+     174           7 :     loss_ = vec_loss_[0];
+     175           7 :     log.printf("maze> Loss function linked to the optimizer.\n");
+     176           7 :   }
+     177             : 
+     178          14 :   if (keywords.exists("N_ITER")) {
+     179           3 :     parse("N_ITER", n_iter_);
+     180             : 
+     181           3 :     plumed_massert(
+     182             :       n_iter_ > 0,
+     183             :       "maze> N_ITER should be explicitly specified and positive.\n"
+     184             :     );
+     185             : 
+     186           3 :     log.printf(
+     187             :       "maze> Optimizer will run %u iterations once launched.\n",
+     188             :       n_iter_
+     189             :     );
+     190             :   }
+     191             : 
+     192             :   std::vector<AtomNumber> ga_list, gb_list;
+     193           7 :   parseAtomList("LIGAND", ga_list);
+     194           7 :   parseAtomList("PROTEIN", gb_list);
+     195             : 
+     196           7 :   bool nopbc = !pbc_;
+     197           7 :   parseFlag("NOPBC", nopbc);
+     198             : 
+     199           7 :   bool do_pair = false;
+     200           7 :   parseFlag("PAIR", do_pair);
+     201             : 
+     202           7 :   nl_stride_ = 0;
+     203           7 :   bool do_neigh = false;
+     204           7 :   parseFlag("NLIST", do_neigh);
+     205             : 
+     206           7 :   if (do_neigh) {
+     207          14 :     if (keywords.exists("NL_CUTOFF")) {
+     208           7 :       parse("NL_CUTOFF", nl_cutoff_);
+     209             : 
+     210           7 :       plumed_massert(
+     211             :         nl_cutoff_ > 0,
+     212             :         "maze> NL_CUTOFF should be explicitly specified and positive.\n"
+     213             :       );
+     214             :     }
+     215             : 
+     216          14 :     if (keywords.exists("NL_STRIDE")) {
+     217           7 :       parse("NL_STRIDE", nl_stride_);
+     218             : 
+     219           7 :       plumed_massert(
+     220             :         nl_stride_ > 0,
+     221             :         "maze> NL_STRIDE should be explicitly specified and positive.\n"
+     222             :       );
+     223             :     }
+     224             :   }
+     225             : 
+     226           7 :   if (gb_list.size() > 0) {
+     227           7 :     if (do_neigh) {
+     228           7 :       neighbor_list_ = Tools::make_unique<NeighborList>(
+     229             :                          ga_list,
+     230             :                          gb_list,
+     231             :                          serial_,
+     232             :                          do_pair,
+     233           7 :                          pbc_,
+     234             :                          getPbc(),
+     235             :                          comm,
+     236           7 :                          nl_cutoff_,
+     237           7 :                          nl_stride_
+     238             :                        );
+     239             :     }
+     240             :     else {
+     241           0 :       neighbor_list_=Tools::make_unique<NeighborList>(
+     242             :                        ga_list,
+     243             :                        gb_list,
+     244             :                        serial_,
+     245             :                        do_pair,
+     246           0 :                        pbc_,
+     247             :                        getPbc(),
+     248             :                        comm
+     249             :                      );
+     250             :     }
+     251             :   }
+     252             :   else {
+     253           0 :     if (do_neigh) {
+     254           0 :       neighbor_list_ = Tools::make_unique<NeighborList>(
+     255             :                          ga_list,
+     256             :                          serial_,
+     257           0 :                          pbc_,
+     258             :                          getPbc(),
+     259             :                          comm,
+     260           0 :                          nl_cutoff_,
+     261           0 :                          nl_stride_
+     262             :                        );
+     263             :     }
+     264             :     else {
+     265           0 :       neighbor_list_=Tools::make_unique<NeighborList>(
+     266             :                        ga_list,
+     267             :                        serial_,
+     268           0 :                        pbc_,
+     269             :                        getPbc(),
+     270             :                        comm
+     271             :                      );
+     272             :     }
+     273             :   }
+     274             : 
+     275           7 :   requestAtoms(neighbor_list_->getFullAtomList());
+     276             : 
+     277           7 :   log.printf(
+     278             :     "maze> Loss will be calculated between two groups of %u and %u atoms.\n",
+     279             :     static_cast<unsigned>(ga_list.size()),
+     280             :     static_cast<unsigned>(gb_list.size())
+     281             :   );
+     282             : 
+     283           7 :   log.printf(
+     284             :     "maze> First group (LIGAND): from %d to %d.\n",
+     285             :     ga_list[0].serial(),
+     286             :     ga_list[ga_list.size()-1].serial()
+     287             :   );
+     288             : 
+     289           7 :   if (gb_list.size() > 0) {
+     290           7 :     log.printf(
+     291             :       "maze> Second group (PROTEIN): from %d to %d.\n",
+     292             :       gb_list[0].serial(),
+     293             :       gb_list[gb_list.size()-1].serial()
+     294             :     );
+     295             :   }
+     296             : 
+     297           7 :   if (pbc_) {
+     298           7 :     log.printf("maze> Using periodic boundary conditions.\n");
+     299             :   }
+     300             :   else {
+     301           0 :     log.printf("maze> Without periodic boundary conditions.\n");
+     302             :   }
+     303             : 
+     304           7 :   if (do_pair) {
+     305           0 :     log.printf("maze> With PAIR option.\n");
+     306             :   }
+     307             : 
+     308           7 :   if (do_neigh) {
+     309           7 :     log.printf(
+     310             :       "maze> Using neighbor lists updated every %d steps and cutoff %f.\n",
+     311             :       nl_stride_,
+     312             :       nl_cutoff_
+     313             :     );
+     314             :   }
+     315             : 
+     316             :   // OpenMP
+     317           7 :   stride_ = comm.Get_size();
+     318           7 :   rank_ = comm.Get_rank();
+     319             : 
+     320           7 :   n_threads_ = OpenMP::getNumThreads();
+     321           7 :   unsigned int nn = neighbor_list_->size();
+     322             : 
+     323           7 :   if (n_threads_ * stride_ * 10 > nn) {
+     324           0 :     n_threads_ = nn / stride_ / 10;
+     325             :   }
+     326             : 
+     327           7 :   if (n_threads_ == 0) {
+     328           0 :     n_threads_ = 1;
+     329             :   }
+     330             : 
+     331          14 :   if (keywords.exists("OPTIMIZER_STRIDE")) {
+     332           7 :     parse("OPTIMIZER_STRIDE", optimizer_stride_);
+     333             : 
+     334           7 :     plumed_massert(
+     335             :       optimizer_stride_,
+     336             :       "maze> OPTIMIZER_STRIDE should be explicitly specified and positive.\n"
+     337             :     );
+     338             : 
+     339           7 :     log.printf(
+     340             :       "maze> Launching optimization every %u steps.\n",
+     341             :       optimizer_stride_
+     342             :     );
+     343             :   }
+     344             : 
+     345           7 :   rnd::randomize();
+     346             : 
+     347           7 :   opt_.zero();
+     348             : 
+     349          14 :   addComponentWithDerivatives("x");
+     350          14 :   componentIsNotPeriodic("x");
+     351             : 
+     352          14 :   addComponentWithDerivatives("y");
+     353          14 :   componentIsNotPeriodic("y");
+     354             : 
+     355          14 :   addComponentWithDerivatives("z");
+     356          14 :   componentIsNotPeriodic("z");
+     357             : 
+     358          14 :   addComponent("loss");
+     359          14 :   componentIsNotPeriodic("loss");
+     360             : 
+     361          14 :   addComponent("sr");
+     362           7 :   componentIsNotPeriodic("sr");
+     363             : 
+     364           7 :   value_x_ = getPntrToComponent("x");
+     365           7 :   value_y_ = getPntrToComponent("y");
+     366           7 :   value_z_ = getPntrToComponent("z");
+     367           7 :   value_action_ = getPntrToComponent("loss");
+     368           7 :   value_sampling_radius_ = getPntrToComponent("sr");
+     369           7 : }
+     370             : 
+     371    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         325 : double Optimizer::sampling_radius()
+     454             : {
+     455         325 :   const unsigned nl_size=neighbor_list_->size();
+     456         325 :   Vector d;
+     457             :   double min=std::numeric_limits<int>::max();
+     458             : 
+     459     8484745 :   for (unsigned int i = 0; i < nl_size; ++i) {
+     460     8484420 :     unsigned i0 = neighbor_list_->getClosePair(i).first;
+     461     8484420 :     unsigned i1 = neighbor_list_->getClosePair(i).second;
+     462             : 
+     463     8484420 :     if (getAbsoluteIndex(i0) == getAbsoluteIndex(i1)) {
+     464           0 :       continue;
+     465             :     }
+     466             : 
+     467     8484420 :     if (pbc_) {
+     468     8484420 :       d = pbcDistance(getPosition(i0), getPosition(i1));
+     469             :     }
+     470             :     else {
+     471           0 :       d = delta(getPosition(i0), getPosition(i1));
+     472             :     }
+     473             : 
+     474     8484420 :     double dist = d.modulo();
+     475             : 
+     476     8484420 :     if(dist < min) {
+     477             :       min = dist;
+     478             :     }
+     479             :   }
+     480             : 
+     481         325 :   return min;
+     482             : }
+     483             : 
+     484         210 : void Optimizer::calculate() {
+     485         210 :   update_nl();
+     486             : 
+     487         210 :   if (getStep() % optimizer_stride_ == 0 && !first_step_) {
+     488          19 :     optimize();
+     489             : 
+     490          19 :     value_x_->set(opt_[0]);
+     491          19 :     value_y_->set(opt_[1]);
+     492          19 :     value_z_->set(opt_[2]);
+     493             : 
+     494          19 :     value_action_->set(score());
+     495          19 :     value_sampling_radius_->set(sampling_radius());
+     496             :   }
+     497             :   else {
+     498         191 :     first_step_=false;
+     499             : 
+     500         191 :     value_x_->set(opt_[0]);
+     501         191 :     value_y_->set(opt_[1]);
+     502         191 :     value_z_->set(opt_[2]);
+     503             : 
+     504         191 :     value_action_->set(score());
+     505         191 :     value_sampling_radius_->set(sampling_radius());
+     506             :   }
+     507         210 : }
+     508             : 
+     509             : } // namespace maze
+     510             : } // namespace PLMD
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Optimizer.h.func-sort-c.html b/coverage/maze/Optimizer.h.func-sort-c.html new file mode 100644 index 000000000000..25f252c1259f --- /dev/null +++ b/coverage/maze/Optimizer.h.func-sort-c.html @@ -0,0 +1,77 @@ + + + + + + + + LCOV - plumed test coverage - maze/Optimizer.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Optimizer.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1313100.0 %
Date:2024-04-19 12:12:35Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze9OptimizerD2Ev7
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Optimizer.h.gcov.html b/coverage/maze/Optimizer.h.gcov.html new file mode 100644 index 000000000000..22e25bd5db7d --- /dev/null +++ b/coverage/maze/Optimizer.h.gcov.html @@ -0,0 +1,434 @@ + + + + + + + + LCOV - plumed test coverage - maze/Optimizer.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Optimizer.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1313100.0 %
Date:2024-04-19 12:12:35Functions: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             : // cppcheck-suppress passedByValue
+     330             : inline void Optimizer::set_opt(Vector opt) {
+     331          44 :   opt_=opt;
+     332             : }
+     333             : 
+     334             : inline Vector Optimizer::get_opt() const {
+     335           3 :   return opt_;
+     336             : }
+     337             : 
+     338             : inline void Optimizer::set_label(const std::string& label) {
+     339           7 :   label_=label;
+     340           7 : }
+     341             : 
+     342             : inline std::string Optimizer::get_label() const {
+     343           1 :   return label_;
+     344             : }
+     345             : 
+     346             : inline void Optimizer::start_step_0() {
+     347           5 :   first_step_=false;
+     348             : }
+     349             : 
+     350             : inline void Optimizer::start_step_stride() {
+     351           2 :   first_step_=true;
+     352             : }
+     353             : 
+     354             : } // namespace maze
+     355             : } // namespace PLMD
+     356             : 
+     357             : #endif // __PLUMED_maze_Optimizer_h
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Optimizer_Bias.cpp.func-sort-c.html b/coverage/maze/Optimizer_Bias.cpp.func-sort-c.html new file mode 100644 index 000000000000..73846cafd66c --- /dev/null +++ b/coverage/maze/Optimizer_Bias.cpp.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - maze/Optimizer_Bias.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Optimizer_Bias.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:959797.9 %
Date:2024-04-19 12:12:35Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze13OptimizerBiasC2ERKNS_13ActionOptionsE0
_ZN4PLMD4maze13OptimizerBiasC1ERKNS_13ActionOptionsE1
_ZN4PLMD4maze13OptimizerBiasD0Ev1
_ZN4PLMD4maze13OptimizerBiasD1Ev1
_ZN4PLMD4maze13OptimizerBias16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD4maze13OptimizerBias9calculateEv30
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Optimizer_Bias.cpp.func.html b/coverage/maze/Optimizer_Bias.cpp.func.html new file mode 100644 index 000000000000..b084cae3305e --- /dev/null +++ b/coverage/maze/Optimizer_Bias.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - maze/Optimizer_Bias.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Optimizer_Bias.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:959797.9 %
Date:2024-04-19 12:12:35Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze13OptimizerBias16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD4maze13OptimizerBias9calculateEv30
_ZN4PLMD4maze13OptimizerBiasC1ERKNS_13ActionOptionsE1
_ZN4PLMD4maze13OptimizerBiasC2ERKNS_13ActionOptionsE0
_ZN4PLMD4maze13OptimizerBiasD0Ev1
_ZN4PLMD4maze13OptimizerBiasD1Ev1
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Optimizer_Bias.cpp.gcov.html b/coverage/maze/Optimizer_Bias.cpp.gcov.html new file mode 100644 index 000000000000..cbcc9b63f77f --- /dev/null +++ b/coverage/maze/Optimizer_Bias.cpp.gcov.html @@ -0,0 +1,511 @@ + + + + + + + + LCOV - plumed test coverage - maze/Optimizer_Bias.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Optimizer_Bias.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:959797.9 %
Date:2024-04-19 12:12:35Functions:5683.3 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2019 Jakub Rydzewski (jr@fizyka.umk.pl). All rights reserved.
+       3             : 
+       4             : See http://www.maze-code.github.io for more information.
+       5             : 
+       6             : This file is part of maze.
+       7             : 
+       8             : maze is free software: you can redistribute it and/or modify it under the
+       9             : terms of the GNU Lesser General Public License as published by the Free
+      10             : Software Foundation, either version 3 of the License, or (at your option)
+      11             : any later version.
+      12             : 
+      13             : maze is distributed in the hope that it will be useful, but WITHOUT ANY
+      14             : WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+      15             : FOR A PARTICULAR PURPOSE.
+      16             : 
+      17             : See the GNU Lesser General Public License for more details.
+      18             : 
+      19             : You should have received a copy of the GNU Lesser General Public License
+      20             : along with maze. If not, see <https://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : /**
+      24             :  * @file Optimizer_Bias.cpp
+      25             :  *
+      26             :  * @author J. Rydzewski (jr@fizyka.umk.pl)
+      27             :  *
+      28             :  * @code
+      29             :  * @article{rydzewski2018finding,
+      30             :  *   title={Finding Multiple Reaction Pathways of Ligand Unbinding},
+      31             :  *   author={Rydzewski, J and Valsson, O},
+      32             :  *   journal={arXiv preprint arXiv:1808.08089},
+      33             :  *   year={2018}
+      34             :  * }
+      35             :  * @endcode
+      36             :  */
+      37             : 
+      38             : #include "core/ActionRegister.h"
+      39             : #include "core/PlumedMain.h"
+      40             : 
+      41             : #include "bias/Bias.h"
+      42             : 
+      43             : #include "Optimizer.h"
+      44             : #include "Tools.h"
+      45             : 
+      46             : namespace PLMD {
+      47             : namespace maze {
+      48             : 
+      49             : //+PLUMEDOC MAZE_BIAS MAZE_OPTIMIZER_BIAS
+      50             : /*
+      51             : 
+      52             : Biases the ligand along the direction calculated by the chosen \ref MAZE_OPTIMIZER.
+      53             : 
+      54             : OptimizerBias is a class deriving from Bias, and it is used to adaptively
+      55             : bias a ligand-protein system toward an optimal solution found by the chosen
+      56             : optimizer.
+      57             : 
+      58             : Remember to define the loss function (\ref MAZE_LOSS) and the optimizer
+      59             : (\ref MAZE_OPTIMIZER) prior to the adaptive bias for the optimizer.
+      60             : 
+      61             : The adaptive bias potential is the following:
+      62             : \f[
+      63             :   V({\bf x}_t)=\alpha
+      64             :     \left(wt -
+      65             :       ({\bf x} - {\bf x}^*_{t-\tau})
+      66             :       \cdot
+      67             :       \frac{{\bf x}^*_t - {\bf x}_t}{\|{\bf x}^*_t-{\bf x}_t\|}
+      68             :     \right)^2,
+      69             : \f]
+      70             : where \f${\bf x}^*_t\f$ is the optimal solution at time \f$t\f$, \f$w\f$ is the
+      71             : biasing rate, \f$\tau\f$ is the interval at which the loss function is minimized,
+      72             : and \f$\alpha\f$ is a scaled force constant.
+      73             : 
+      74             : \par Examples
+      75             : 
+      76             : In the following example the bias potential biases a ligand atom (which have to be
+      77             : given as an argument) with the biasing rate equal to 0.02 A/ps, and the biasing
+      78             : constant equal to 3.6 kcal/(mol A). It also takes an optimizer (see
+      79             : \ref MAZE_OPTIMIZER).
+      80             : 
+      81             : \plumedfile
+      82             : UNITS LENGTH=A TIME=ps ENERGY=kcal/mol
+      83             : 
+      84             : p: POSITION ATOM=2635 NOPBC
+      85             : 
+      86             : MAZE_OPTIMIZER_BIAS ...
+      87             :   LABEL=bias
+      88             : 
+      89             :   ARG=p.x,p.y,p.z
+      90             : 
+      91             :   BIASING_RATE=0.02
+      92             :   ALPHA=3.6
+      93             : 
+      94             :   OPTIMIZER=opt
+      95             : ... MAZE_OPTIMIZER_BIAS
+      96             : \endplumedfile
+      97             : 
+      98             : */
+      99             : //+ENDPLUMEDOC
+     100             : 
+     101             : /**
+     102             :  * @class OptimizerBias OptimizerBias.cpp "maze/OptimizerBias.cpp"
+     103             :  *
+     104             :  * @brief Adaptive bias for the maze optimizers.
+     105             :  *
+     106             :  * OptimizerBias is a class deriving from Bias, and it is used to adaptively
+     107             :  * bias a system toward an optimal solution found by an optimizer.
+     108             :  */
+     109             : class OptimizerBias: public bias::Bias {
+     110             : public:
+     111             :   /**
+     112             :    * Standard PLUMED2 constructor.
+     113             :    *
+     114             :    * @param ao ActionOptions&.
+     115             :    */
+     116             :   explicit OptimizerBias(const ActionOptions& ao);
+     117             : 
+     118             :   /**
+     119             :    * Destructor.
+     120             :    */
+     121           3 :   ~OptimizerBias() { /* Nothing to do. */ }
+     122             : 
+     123             :   /**
+     124             :    * Register PLUMED2 keywords.
+     125             :    *
+     126             :    * @param keys Keywords.
+     127             :    */
+     128             :   static void registerKeywords(Keywords& keys);
+     129             : 
+     130             :   /**
+     131             :    * Calculate the adaptive biasing potential for ligand unbinding.
+     132             :    */
+     133             :   void calculate();
+     134             : 
+     135             : private:
+     136             :   /**
+     137             :    * Biased collective variable with Cartesian components, i.e., position,
+     138             :    * center of mass.
+     139             :    */
+     140             :   std::vector<Value*> args_;
+     141             : 
+     142             :   /**
+     143             :    * Pointer to the optimizer used to minimize the collective variable for
+     144             :    * ligand unbinding.
+     145             :    */
+     146             :   Optimizer* optimizer_;
+     147             :   std::vector<Optimizer*> opt_pntrs_;
+     148             : 
+     149             :   //! Adaptive bias potential and the corresponding force.
+     150             :   double bias_;
+     151             :   double force_;
+     152             : 
+     153             :   /*
+     154             :    * Parameters of the adaptive biasing potential:
+     155             :    *  alpha_            rescaled force constant
+     156             :    *  biasing_speed     biasing rate
+     157             :    *  biasing_stride    biasing stride
+     158             :    *  biasing_direction biasing direction
+     159             :    */
+     160             : 
+     161             :   //! Rescaled force constant.
+     162             :   double alpha_;
+     163             :   //! Biasing rate.
+     164             :   double biasing_speed_;
+     165             :   //! Biasing stride.
+     166             :   int biasing_stride_;
+     167             : 
+     168             :   /**
+     169             :    * Biasing direction is approximated by an optimal solution found by an
+     170             :    * optimizer.
+     171             :    */
+     172             :   Vector biasing_direction_;
+     173             : 
+     174             :   //! Total distance traveled by biased atoms.
+     175             :   double total_distance_;
+     176             : 
+     177             :   //! Previous value of the collective variable.
+     178             :   Vector cv0_;
+     179             : 
+     180             :   /*
+     181             :    * Pointers to PLUMED2 output components.
+     182             :    */
+     183             : 
+     184             :   //! Biased collective variable components.
+     185             :   Value* value_dir_x_;
+     186             :   Value* value_dir_y_;
+     187             :   Value* value_dir_z_;
+     188             : 
+     189             :   //! Values of the bias and its force.
+     190             :   Value* value_bias_;
+     191             :   Value* value_force_;
+     192             : 
+     193             :   //! Total distance.
+     194             :   Value* value_total_distance_;
+     195             : };
+     196             : 
+     197             : // Register OPTIMIZER_BIAS as a keyword for PLUMED2 input files.
+     198             : PLUMED_REGISTER_ACTION(OptimizerBias, "MAZE_OPTIMIZER_BIAS")
+     199             : 
+     200           3 : void OptimizerBias::registerKeywords(Keywords& keys) {
+     201           3 :   Bias::registerKeywords(keys);
+     202             : 
+     203           3 :   keys.use("ARG");
+     204             : 
+     205           6 :   keys.add(
+     206             :     "compulsory",
+     207             :     "BIASING_RATE",
+     208             :     "Biasing rate."
+     209             :   );
+     210             : 
+     211           6 :   keys.add(
+     212             :     "compulsory",
+     213             :     "ALPHA",
+     214             :     "Rescaled force constant."
+     215             :   );
+     216             : 
+     217           6 :   keys.add(
+     218             :     "compulsory",
+     219             :     "OPTIMIZER",
+     220             :     "Optimization technique to minimize the collective variable for ligand\
+     221             :      unbinding: RANDOM_WALK,\
+     222             :                 STEERED_MD,\
+     223             :                 RANDOM_ACCELERATION_MD,\
+     224             :                 SIMULATED_ANNEALING,\
+     225             :                 MEMETIC_SAMPLING"
+     226             :   );
+     227             : 
+     228           3 :   componentsAreNotOptional(keys);
+     229             : 
+     230           6 :   keys.addOutputComponent(
+     231             :     "force2",
+     232             :     "default",
+     233             :     "Square of the biasing force."
+     234             :   );
+     235             : 
+     236           6 :   keys.addOutputComponent(
+     237             :     "x",
+     238             :     "default",
+     239             :     "Optimal biasing direction: x component."
+     240             :   );
+     241             : 
+     242           6 :   keys.addOutputComponent(
+     243             :     "y",
+     244             :     "default",
+     245             :     "Optimal biasing direction: y component."
+     246             :   );
+     247             : 
+     248           6 :   keys.addOutputComponent(
+     249             :     "z",
+     250             :     "default",
+     251             :     "Optimal biasing direction: z component."
+     252             :   );
+     253             : 
+     254           6 :   keys.addOutputComponent(
+     255             :     "tdist",
+     256             :     "default",
+     257             :     "Total distance traveled by biased atoms."
+     258             :   );
+     259           3 : }
+     260             : 
+     261           1 : OptimizerBias::OptimizerBias(const ActionOptions& ao)
+     262             :   : PLUMED_BIAS_INIT(ao),
+     263           1 :     bias_(0.0),
+     264           1 :     force_(0.0),
+     265           1 :     total_distance_(0.0)
+     266             : {
+     267           1 :   log.printf(
+     268             :     "maze> You are using the maze module of PLUMED2,\
+     269             :     please read and cite "
+     270             :   );
+     271             : 
+     272           2 :   log << plumed.cite("Rydzewski J. and Valsson O., arXiv:1808.08089, 2018");
+     273           1 :   log.printf("\n");
+     274             : 
+     275           1 :   args_ = getArguments();
+     276           1 :   log.printf(
+     277             :     "maze> Number of args %zu\n",
+     278             :     args_.size()
+     279             :   );
+     280             : 
+     281           1 :   if (!args_.empty()) {
+     282           1 :     log.printf("maze> With arguments");
+     283           4 :     for (unsigned i = 0; i < args_.size(); i++) {
+     284           3 :       log.printf(" %s", args_[i]->getName().c_str());
+     285             :     }
+     286           1 :     log.printf("\n");
+     287             :   }
+     288             : 
+     289           2 :   if (keywords.exists("ALPHA")) {
+     290           1 :     parse("ALPHA", alpha_);
+     291             : 
+     292           1 :     plumed_massert(
+     293             :       alpha_>0,
+     294             :       "maze> ALPHA should be explicitly specified and positive.\n"
+     295             :     );
+     296             : 
+     297           1 :     log.printf(
+     298             :       "maze> ALPHA read: %f [kcal/mol/A].\n",
+     299             :       alpha_
+     300             :     );
+     301             :   }
+     302             : 
+     303           2 :   if (keywords.exists("BIASING_RATE")) {
+     304           1 :     parse("BIASING_RATE", biasing_speed_);
+     305             : 
+     306           1 :     plumed_massert(
+     307             :       biasing_speed_>0,
+     308             :       "maze> BIASING_RATE should be explicitly specified and positive.\n"
+     309             :     );
+     310             : 
+     311           1 :     log.printf(
+     312             :       "maze> BIASING_RATE read: %f [A/ps].\n",
+     313             :       biasing_speed_
+     314             :     );
+     315             :   }
+     316             : 
+     317           2 :   if (keywords.exists("OPTIMIZER")) {
+     318           1 :     std::vector<std::string> opt_labels(0);
+     319           2 :     parseVector("OPTIMIZER", opt_labels);
+     320             : 
+     321           1 :     plumed_massert(
+     322             :       opt_labels.size() > 0,
+     323             :       "maze> Problem with OPTIMIZER keyword.\n"
+     324             :     );
+     325             : 
+     326           1 :     std::string error_msg = "";
+     327           2 :     opt_pntrs_ = tls::get_pointers_labels<Optimizer*>(
+     328             :                    opt_labels,
+     329           1 :                    plumed.getActionSet(),
+     330             :                    error_msg
+     331             :                  );
+     332             : 
+     333           1 :     if (error_msg.size() > 0) {
+     334           0 :       plumed_merror(
+     335             :         "maze> Error in keyword OPTIMIZER of " + getName() + ": " + error_msg
+     336             :       );
+     337             :     }
+     338             : 
+     339           1 :     optimizer_ = opt_pntrs_[0];
+     340           1 :     log.printf(
+     341             :       "maze> Optimizer linked: %s.\n",
+     342           0 :       optimizer_->get_label().c_str()
+     343             :     );
+     344             : 
+     345           1 :     biasing_stride_=optimizer_->get_optimizer_stride();
+     346           1 :   }
+     347             : 
+     348           1 :   checkRead();
+     349             : 
+     350           2 :   addComponent("force2");
+     351           2 :   componentIsNotPeriodic("force2");
+     352             : 
+     353           2 :   addComponent("x");
+     354           2 :   componentIsNotPeriodic("x");
+     355             : 
+     356           2 :   addComponent("y");
+     357           2 :   componentIsNotPeriodic("y");
+     358             : 
+     359           2 :   addComponent("z");
+     360           2 :   componentIsNotPeriodic("z");
+     361             : 
+     362           2 :   addComponent("tdist");
+     363           1 :   componentIsNotPeriodic("tdist");
+     364             : 
+     365           1 :   biasing_direction_.zero();
+     366           1 :   cv0_.zero();
+     367             : 
+     368           1 :   value_bias_ = getPntrToComponent("bias");
+     369           1 :   value_force_ = getPntrToComponent("force2");
+     370             : 
+     371           1 :   value_dir_x_ = getPntrToComponent("x");
+     372           1 :   value_dir_y_ = getPntrToComponent("y");
+     373           1 :   value_dir_z_ = getPntrToComponent("z");
+     374             : 
+     375           1 :   value_total_distance_=getPntrToComponent("tdist");
+     376           1 : }
+     377             : 
+     378          30 : void OptimizerBias::calculate() {
+     379             :   // Unpack arguments and optimizers.
+     380             :   Vector cv(
+     381             :     args_[0]->get(),
+     382             :     args_[1]->get(),
+     383             :     args_[2]->get()
+     384          30 :   );
+     385             : 
+     386             :   Vector opt_direction(
+     387          30 :     optimizer_->value_x_->get(),
+     388          30 :     optimizer_->value_y_->get(),
+     389          30 :     optimizer_->value_z_->get()
+     390          30 :   );
+     391             : 
+     392          30 :   if (getStep() == 0) {
+     393           1 :     cv0_=cv;
+     394             :   }
+     395             : 
+     396             :   /*
+     397             :    * For details see a paper by Rydzewski and Valsson.
+     398             :    */
+     399          30 :   double dot = dotProduct(cv - cv0_, biasing_direction_);
+     400          30 :   double delta_cv = biasing_speed_ * getTime() - (dot + total_distance_);
+     401             : 
+     402          30 :   double sign = tls::sgn(delta_cv);
+     403             : 
+     404          30 :   bias_ = alpha_ * delta_cv * delta_cv;
+     405          30 :   force_ = 2.0 * sign * alpha_ * fabs(delta_cv);
+     406             : 
+     407          30 :   if (getStep() % biasing_stride_ == 0) {
+     408           3 :     biasing_direction_ = opt_direction;
+     409           3 :     cv0_ = cv;
+     410           3 :     total_distance_ += dot;
+     411             :   }
+     412             : 
+     413             :   /*
+     414             :    * Return the biasing force to MD engine.
+     415             :    */
+     416          30 :   setOutputForce(0, force_ * biasing_direction_[0]);
+     417          30 :   setOutputForce(1, force_ * biasing_direction_[1]);
+     418          30 :   setOutputForce(2, force_ * biasing_direction_[2]);
+     419             : 
+     420             :   /*
+     421             :    * Set values for PLUMED2 outputs.
+     422             :    */
+     423          30 :   value_bias_->set(bias_);
+     424          30 :   value_force_->set(force_);
+     425             : 
+     426          30 :   value_total_distance_->set(total_distance_);
+     427             : 
+     428          30 :   value_dir_x_->set(biasing_direction_[0]);
+     429          30 :   value_dir_y_->set(biasing_direction_[1]);
+     430          30 :   value_dir_z_->set(biasing_direction_[2]);
+     431          30 : }
+     432             : 
+     433             : } // namespace maze
+     434             : } // namespace PLMD
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Random_Acceleration_MD.cpp.func-sort-c.html b/coverage/maze/Random_Acceleration_MD.cpp.func-sort-c.html new file mode 100644 index 000000000000..f10db357e99e --- /dev/null +++ b/coverage/maze/Random_Acceleration_MD.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - maze/Random_Acceleration_MD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Random_Acceleration_MD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:394195.1 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze22Random_Acceleration_MDC2ERKNS_13ActionOptionsE0
_ZN4PLMD4maze22Random_Acceleration_MDC1ERKNS_13ActionOptionsE1
_ZN4PLMD4maze22Random_Acceleration_MD8optimizeEv2
_ZN4PLMD4maze22Random_Acceleration_MD16registerKeywordsERNS_8KeywordsE3
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Random_Acceleration_MD.cpp.func.html b/coverage/maze/Random_Acceleration_MD.cpp.func.html new file mode 100644 index 000000000000..33e43be97a7d --- /dev/null +++ b/coverage/maze/Random_Acceleration_MD.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - maze/Random_Acceleration_MD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Random_Acceleration_MD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:394195.1 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze22Random_Acceleration_MD16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD4maze22Random_Acceleration_MD8optimizeEv2
_ZN4PLMD4maze22Random_Acceleration_MDC1ERKNS_13ActionOptionsE1
_ZN4PLMD4maze22Random_Acceleration_MDC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Random_Acceleration_MD.cpp.gcov.html b/coverage/maze/Random_Acceleration_MD.cpp.gcov.html new file mode 100644 index 000000000000..6b7b7f42c4d6 --- /dev/null +++ b/coverage/maze/Random_Acceleration_MD.cpp.gcov.html @@ -0,0 +1,280 @@ + + + + + + + + LCOV - plumed test coverage - maze/Random_Acceleration_MD.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Random_Acceleration_MD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:394195.1 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2019 Jakub Rydzewski (jr@fizyka.umk.pl). All rights reserved.
+       3             : 
+       4             : See http://www.maze-code.github.io for more information.
+       5             : 
+       6             : This file is part of maze.
+       7             : 
+       8             : maze is free software: you can redistribute it and/or modify it under the
+       9             : terms of the GNU Lesser General Public License as published by the Free
+      10             : Software Foundation, either version 3 of the License, or (at your option)
+      11             : any later version.
+      12             : 
+      13             : maze is distributed in the hope that it will be useful, but WITHOUT ANY
+      14             : WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+      15             : FOR A PARTICULAR PURPOSE.
+      16             : 
+      17             : See the GNU Lesser General Public License for more details.
+      18             : 
+      19             : You should have received a copy of the GNU Lesser General Public License
+      20             : along with maze. If not, see <https://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : /**
+      24             :  * @file Random_Acceleration_MD.cpp
+      25             :  *
+      26             :  * @author J. Rydzewski (jr@fizyka.umk.pl)
+      27             :  */
+      28             : 
+      29             : #include "core/ActionRegister.h"
+      30             : #include "Optimizer.h"
+      31             : 
+      32             : namespace PLMD {
+      33             : namespace maze {
+      34             : 
+      35             : //+PLUMEDOC MAZE_OPTIMIZER MAZE_RANDOM_ACCELERATION_MD
+      36             : /*
+      37             : 
+      38             : Performs random acceleration MD within the protein matrix.
+      39             : 
+      40             : \par Examples
+      41             : 
+      42             : Every optimizer implemented in the maze module needs a loss function as
+      43             : an argument, and it should be passed using the \ref MAZE_LOSS keyword.
+      44             : 
+      45             : \plumedfile
+      46             : MAZE_RANDOM_ACCELERATION_MD ...
+      47             :   LABEL=rw
+      48             : 
+      49             :   OPTIMIZER_STRIDE=_
+      50             :   LOSS=l
+      51             :   RMIN=_
+      52             : 
+      53             :   LIGAND=2635-2646
+      54             :   PROTEIN=1-2634
+      55             : ... MAZE_RANDOM_ACCELERATION_MD
+      56             : \endplumedfile
+      57             : 
+      58             : As shown above, each optimizer should be provided with the LIGAND and
+      59             : the PROTEIN keywords.
+      60             : 
+      61             : */
+      62             : //+ENDPLUMEDOC
+      63             : 
+      64             : /**
+      65             :  * @class Random_Acceleration_MD Random_Acceleration_MD.cpp
+      66             :  *  "maze/Random_Acceleration_MD.cpp"
+      67             :  *
+      68             :  * @brief Perform RAMD simulation.
+      69             :  */
+      70             : class Random_Acceleration_MD: public Optimizer {
+      71             : public:
+      72             :   /**
+      73             :    * PLMD constructor.
+      74             :    *
+      75             :    * @param[in] ao PLMD::ActionOptions&
+      76             :    */
+      77             :   explicit Random_Acceleration_MD(const ActionOptions&);
+      78             : 
+      79             :   /**
+      80             :    * Registers PLMD keywords.
+      81             :    *
+      82             :    * @param[in] keys PLMD keywords
+      83             :    */
+      84             :   static void registerKeywords(Keywords&);
+      85             : 
+      86             :   /**
+      87             :    * Each class deriving from Optimizer needs to override this function.
+      88             :    */
+      89             :   void optimize() override;
+      90             : 
+      91             : private:
+      92             :   //! Threshold distance that the ligand needs to pass.
+      93             :   double r_min_;
+      94             : 
+      95             :   //! Total distance.
+      96             :   double total_dist_;
+      97             : 
+      98             :   //! Distance.
+      99             :   double dist_;
+     100             : 
+     101             :   //! Ligand center of mass.
+     102             :   Vector com_;
+     103             : 
+     104             :   //! PLMD value for distance.
+     105             :   Value* value_dist_;
+     106             : 
+     107             :   //! PLMD value for total distance.
+     108             :   Value* value_total_dist_;
+     109             : };
+     110             : 
+     111             : // Register MAZE_RANDOM_ACCELERATION_MD.
+     112             : PLUMED_REGISTER_ACTION(Random_Acceleration_MD, "MAZE_RANDOM_ACCELERATION_MD")
+     113             : 
+     114           3 : void Random_Acceleration_MD::registerKeywords(Keywords& keys) {
+     115           3 :   Optimizer::registerKeywords(keys);
+     116             : 
+     117           3 :   keys.remove("N_ITER");
+     118             : 
+     119           6 :   keys.add(
+     120             :     "compulsory",
+     121             :     "R_MIN",
+     122             :     "Minimal distance traveled before sampling a new direction of biasing."
+     123             :   );
+     124             : 
+     125           6 :   keys.addOutputComponent(
+     126             :     "dist",
+     127             :     "default",
+     128             :     "Distance traveled in one sampling interval."
+     129             :   );
+     130             : 
+     131           6 :   keys.addOutputComponent(
+     132             :     "tdist",
+     133             :     "default",
+     134             :     "Total distance traveled by biased atoms."
+     135             :   );
+     136           3 : }
+     137             : 
+     138           1 : Random_Acceleration_MD::Random_Acceleration_MD(const ActionOptions& ao)
+     139             :   : PLUMED_OPT_INIT(ao),
+     140           1 :     total_dist_(0.0),
+     141           1 :     dist_(0.0) {
+     142           1 :   log.printf("maze> Random accelerated molecular dynamics.\n");
+     143             : 
+     144           2 :   if(keywords.exists("R_MIN")) {
+     145           1 :     parse("R_MIN", r_min_);
+     146             : 
+     147           1 :     plumed_massert(
+     148             :       r_min_ > 0,
+     149             :       "maze> R_MIN should be explicitly specified and positive.\n"
+     150             :     );
+     151             : 
+     152           1 :     log.printf(
+     153             :       "maze> R_MIN read: %f [A].\n",
+     154             :       r_min_
+     155             :     );
+     156             :   }
+     157             : 
+     158           1 :   set_label("RANDOM_ACCELERATION_MD");
+     159           1 :   set_opt(rnd::next_plmd_vector());
+     160             :   set_opt_value(0.0);
+     161             : 
+     162             :   start_step_stride();
+     163             : 
+     164           1 :   checkRead();
+     165             : 
+     166           1 :   com_ = center_of_mass();
+     167             : 
+     168           2 :   addComponent("dist");
+     169           1 :   componentIsNotPeriodic("dist");
+     170           1 :   value_dist_ = getPntrToComponent("dist");
+     171             : 
+     172           2 :   addComponent("tdist");
+     173           1 :   componentIsNotPeriodic("tdist");
+     174           1 :   value_total_dist_ = getPntrToComponent("tdist");
+     175           1 : }
+     176             : 
+     177           2 : void Random_Acceleration_MD::optimize() {
+     178           2 :   Vector c = center_of_mass();
+     179           2 :   Vector d;
+     180             : 
+     181           2 :   if (pbc_) {
+     182           2 :     d = pbcDistance(c, com_);
+     183             :   }
+     184             :   else {
+     185           0 :     d = delta(c, com_);
+     186             :   }
+     187             : 
+     188           2 :   dist_ = d.modulo();
+     189           2 :   total_dist_ += dist_;
+     190             : 
+     191           2 :   if(dist_ < r_min_) {
+     192           0 :     set_opt(rnd::next_plmd_vector());
+     193             :   }
+     194             : 
+     195           2 :   set_opt_value(score());
+     196           2 :   com_ = c;
+     197             : 
+     198           2 :   value_dist_->set(dist_);
+     199           2 :   value_total_dist_->set(total_dist_);
+     200           2 : }
+     201             : 
+     202             : } // namespace maze
+     203             : } // namespace PLMD
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Random_MT.cpp.func-sort-c.html b/coverage/maze/Random_MT.cpp.func-sort-c.html new file mode 100644 index 000000000000..ae03f22e6464 --- /dev/null +++ b/coverage/maze/Random_MT.cpp.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - maze/Random_MT.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Random_MT.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2020100.0 %
Date:2024-04-19 12:12:35Functions:66100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze3rnd8next_intEii1
_ZN4PLMD4maze3rnd11next_cauchyEdd74
_ZN4PLMD4maze3rnd11next_doubleEdd246
_ZN4PLMD4maze3rnd8next_intEi283
_ZN4PLMD4maze3rnd11next_doubleEv536
_ZN4PLMD4maze3rnd6mt_engEv1147
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Random_MT.cpp.func.html b/coverage/maze/Random_MT.cpp.func.html new file mode 100644 index 000000000000..2e079b6a8c7a --- /dev/null +++ b/coverage/maze/Random_MT.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - maze/Random_MT.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Random_MT.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2020100.0 %
Date:2024-04-19 12:12:35Functions:66100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze3rnd11next_cauchyEdd74
_ZN4PLMD4maze3rnd11next_doubleEdd246
_ZN4PLMD4maze3rnd11next_doubleEv536
_ZN4PLMD4maze3rnd6mt_engEv1147
_ZN4PLMD4maze3rnd8next_intEi283
_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 000000000000..77e18ac940c3 --- /dev/null +++ b/coverage/maze/Random_MT.cpp.gcov.html @@ -0,0 +1,158 @@ + + + + + + + + LCOV - plumed test coverage - maze/Random_MT.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Random_MT.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2020100.0 %
Date:2024-04-19 12:12:35Functions: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        1147 : std::mt19937_64& rnd::mt_eng() {
+      37        1154 :   static std::mt19937_64 mt{};
+      38             : 
+      39        1147 :   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         283 : int rnd::next_int(int e) {
+      59         283 :   static std::uniform_int_distribution<int> dist_int(0, e-1);
+      60         283 :   std::uniform_int_distribution<int>::param_type p(0, e-1);
+      61             :   dist_int.param(p);
+      62             : 
+      63         283 :   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          74 : double rnd::next_cauchy(double m, double s) {
+      75          74 :   static std::cauchy_distribution<double> dist_cauchy(m, s);
+      76             : 
+      77          74 :   return dist_cauchy(mt_eng());
+      78             : }
+      79             : 
+      80             : } // namespace maze
+      81             : } // namespace PLMD
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Random_MT.h.func-sort-c.html b/coverage/maze/Random_MT.h.func-sort-c.html new file mode 100644 index 000000000000..7a3e252026aa --- /dev/null +++ b/coverage/maze/Random_MT.h.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - maze/Random_MT.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Random_MT.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:121770.6 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze3rnd11next_doubleEddm0
_ZN4PLMD4maze3rnd9randomizeEv7
_ZN4PLMD4maze3rnd16next_plmd_vectorEd66
_ZN4PLMD4maze3rnd16next_plmd_vectorEv73
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Random_MT.h.func.html b/coverage/maze/Random_MT.h.func.html new file mode 100644 index 000000000000..b64c4976a323 --- /dev/null +++ b/coverage/maze/Random_MT.h.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - maze/Random_MT.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Random_MT.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:121770.6 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze3rnd11next_doubleEddm0
_ZN4PLMD4maze3rnd16next_plmd_vectorEd66
_ZN4PLMD4maze3rnd16next_plmd_vectorEv73
_ZN4PLMD4maze3rnd9randomizeEv7
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Random_MT.h.gcov.html b/coverage/maze/Random_MT.h.gcov.html new file mode 100644 index 000000000000..d9288a72a5a2 --- /dev/null +++ b/coverage/maze/Random_MT.h.gcov.html @@ -0,0 +1,233 @@ + + + + + + + + LCOV - plumed test coverage - maze/Random_MT.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Random_MT.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:121770.6 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2019 Jakub Rydzewski (jr@fizyka.umk.pl). All rights reserved.
+       3             : 
+       4             : See http://www.maze-code.github.io for more information.
+       5             : 
+       6             : This file is part of maze.
+       7             : 
+       8             : maze is free software: you can redistribute it and/or modify it under the
+       9             : terms of the GNU Lesser General Public License as published by the Free
+      10             : Software Foundation, either version 3 of the License, or (at your option)
+      11             : any later version.
+      12             : 
+      13             : maze is distributed in the hope that it will be useful, but WITHOUT ANY
+      14             : WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+      15             : FOR A PARTICULAR PURPOSE.
+      16             : 
+      17             : See the GNU Lesser General Public License for more details.
+      18             : 
+      19             : You should have received a copy of the GNU Lesser General Public License
+      20             : along with maze. If not, see <https://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_maze_Random_MT_h
+      23             : #define __PLUMED_maze_Random_MT_h
+      24             : 
+      25             : /**
+      26             :  * @file Random_MT.h
+      27             :  *
+      28             :  * @author J. Rydzewski (jr@fizyka.umk.pl)
+      29             :  */
+      30             : 
+      31             : #include "Core.h"
+      32             : 
+      33             : namespace PLMD {
+      34             : namespace maze {
+      35             : 
+      36             : /**
+      37             :  * @class rnd Random_MT.h "maze/Random_MT.h"
+      38             :  *
+      39             :  * @brief Mersenne Twister sampler for random variables.
+      40             :  *
+      41             :  * Supports generating integers, doubles, and std::vectors and PLMD::Vectors
+      42             :  * within a given range.
+      43             :  */
+      44             : class rnd {
+      45             : public:
+      46             :   /**
+      47             :    * Initialize MT sampler engine based on std::mt19937_64.
+      48             :    */
+      49             :   static std::mt19937_64& mt_eng();
+      50             : 
+      51             :   /**
+      52             :    * Feed a random seed.
+      53             :    */
+      54             :   static void randomize();
+      55             : 
+      56             :   /**
+      57             :    * Returns a random double from the Cauchy distribution.
+      58             :    *
+      59             :    * @param m mean
+      60             :    * @param s spread
+      61             :    */
+      62             :   static double next_cauchy(double m, double s);
+      63             : 
+      64             :   /**
+      65             :    * Returns a random int from the uniform distribution from a [f, e) range.
+      66             :    *
+      67             :    * @param f begin
+      68             :    * @param e end
+      69             :    */
+      70             :   static int next_int(int f, int e);
+      71             :   static int next_int(int e);
+      72             : 
+      73             :   /**
+      74             :    * Returns a random double from the uniform distribution from a [f, e) range.
+      75             :    */
+      76             :   static double next_double(double f, double e);
+      77             :   static double next_double(double e);
+      78             :   static double next_double();
+      79             : 
+      80             :   /**
+      81             :    * Returns a random vector<double> from the uniform distribution from a [f, e)
+      82             :    * range of length n.
+      83             :    */
+      84             :   static std::vector<double> next_double(double f, double e, std::size_t n);
+      85             : 
+      86             :   /**
+      87             :    * Returns a random PLMD::Vector of length r.
+      88             :    */
+      89             :   static Vector next_plmd_vector();
+      90             :   static Vector next_plmd_vector(double r);
+      91             : 
+      92             :   /**
+      93             :    * Returns a random std::vector of length r.
+      94             :    */
+      95             :   static std::vector<double> next_std_vector();
+      96             :   static std::vector<double> next_std_vector(double r);
+      97             : };
+      98             : 
+      99          66 : inline Vector rnd::next_plmd_vector(double r) {
+     100          66 :   return next_plmd_vector() * r;
+     101             : }
+     102             : 
+     103             : inline std::vector<double> rnd::next_std_vector(double r) {
+     104             :   double t = next_double() * 2.0 * pi;
+     105             :   double p = next_double() * pi;
+     106             : 
+     107             :   return std::vector<double> {
+     108             :     r * std::sin(p) * std::cos(t),
+     109             :     r * std::sin(t) * std::sin(p),
+     110             :     r * std::cos(p)
+     111             :   };
+     112             : }
+     113             : 
+     114           0 : inline std::vector<double> rnd::next_double(double f, double e, size_t n) {
+     115           0 :   std::vector<double> t(n);
+     116           0 :   for (std::size_t i=0; i < n; ++i) {
+     117           0 :     t[i] = next_double(f, e);
+     118             :   }
+     119             : 
+     120           0 :   return t;
+     121             : }
+     122             : 
+     123          73 : inline Vector rnd::next_plmd_vector() {
+     124          73 :   double t = next_double() * 2.0 * pi;
+     125          73 :   double p = next_double() * pi;
+     126             : 
+     127             :   return Vector(
+     128          73 :            std::sin(p) * std::cos(t),
+     129          73 :            std::sin(t) * std::sin(p),
+     130             :            std::cos(p)
+     131          73 :          );
+     132             : }
+     133             : 
+     134             : inline std::vector<double> rnd::next_std_vector() {
+     135             :   double t = next_double() * 2.0 * pi;
+     136             :   double p = next_double() * pi;
+     137             : 
+     138             :   return std::vector<double> {
+     139             :     std::sin(p) * std::cos(t),
+     140             :     std::sin(t) * std::sin(p),
+     141             :     std::cos(p)
+     142             :   };
+     143             : }
+     144             : 
+     145             : inline double rnd::next_double(double e) {
+     146         246 :   return next_double(0, e);
+     147             : }
+     148             : 
+     149           7 : inline void rnd::randomize() {
+     150           7 :   mt_eng().seed(time(0));
+     151           7 : }
+     152             : 
+     153             : } // namespace maze
+     154             : } // namespace PLMD
+     155             : 
+     156             : #endif // __PLUMED_maze_Random_MT_h
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Random_Walk.cpp.func-sort-c.html b/coverage/maze/Random_Walk.cpp.func-sort-c.html new file mode 100644 index 000000000000..d7e15adb8b72 --- /dev/null +++ b/coverage/maze/Random_Walk.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - maze/Random_Walk.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Random_Walk.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1414100.0 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze11Random_WalkC2ERKNS_13ActionOptionsE0
_ZN4PLMD4maze11Random_WalkC1ERKNS_13ActionOptionsE2
_ZN4PLMD4maze11Random_Walk16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD4maze11Random_Walk8optimizeEv6
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Random_Walk.cpp.func.html b/coverage/maze/Random_Walk.cpp.func.html new file mode 100644 index 000000000000..95bf2edb019b --- /dev/null +++ b/coverage/maze/Random_Walk.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - maze/Random_Walk.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Random_Walk.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1414100.0 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze11Random_Walk16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD4maze11Random_Walk8optimizeEv6
_ZN4PLMD4maze11Random_WalkC1ERKNS_13ActionOptionsE2
_ZN4PLMD4maze11Random_WalkC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Random_Walk.cpp.gcov.html b/coverage/maze/Random_Walk.cpp.gcov.html new file mode 100644 index 000000000000..1c993edb24e7 --- /dev/null +++ b/coverage/maze/Random_Walk.cpp.gcov.html @@ -0,0 +1,201 @@ + + + + + + + + LCOV - plumed test coverage - maze/Random_Walk.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Random_Walk.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1414100.0 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2019 Jakub Rydzewski (jr@fizyka.umk.pl). All rights reserved.
+       3             : 
+       4             : See http://www.maze-code.github.io for more information.
+       5             : 
+       6             : This file is part of maze.
+       7             : 
+       8             : maze is free software: you can redistribute it and/or modify it under the
+       9             : terms of the GNU Lesser General Public License as published by the Free
+      10             : Software Foundation, either version 3 of the License, or (at your option)
+      11             : any later version.
+      12             : 
+      13             : maze is distributed in the hope that it will be useful, but WITHOUT ANY
+      14             : WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+      15             : FOR A PARTICULAR PURPOSE.
+      16             : 
+      17             : See the GNU Lesser General Public License for more details.
+      18             : 
+      19             : You should have received a copy of the GNU Lesser General Public License
+      20             : along with maze. If not, see <https://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : /**
+      24             :  * @file Random_Walk.cpp
+      25             :  *
+      26             :  * @author J. Rydzewski (jr@fizyka.umk.pl)
+      27             :  */
+      28             : 
+      29             : #include "core/ActionRegister.h"
+      30             : #include "Optimizer.h"
+      31             : 
+      32             : namespace PLMD {
+      33             : namespace maze {
+      34             : 
+      35             : //+PLUMEDOC MAZE_OPTIMIZER MAZE_RANDOM_WALK
+      36             : /*
+      37             : 
+      38             : Fake optimizer that can be used for debugging.
+      39             : 
+      40             : This is dummy optimizer that can be used for debugging and monitoring
+      41             : purposes. It returns a random direction of biasing, changed every
+      42             : OPTIMIZER_STRIDE.
+      43             : 
+      44             : Performs a random walk within the protein matrix.
+      45             : 
+      46             : \par Examples
+      47             : 
+      48             : Every optimizer implemented in the maze module needs a loss function as
+      49             : an argument, and it should be passed using the \ref MAZE_LOSS keyword.
+      50             : 
+      51             : \plumedfile
+      52             : MAZE_RANDOM_WALK ...
+      53             :   LABEL=rw
+      54             : 
+      55             :   LOSS=l
+      56             :   OPTIMIZER_STRIDE=200
+      57             : 
+      58             :   LIGAND=2635-2646
+      59             :   PROTEIN=1-2634
+      60             : ... MAZE_RANDOM_WALK
+      61             : \endplumedfile
+      62             : 
+      63             : As shown above, each optimizer should be provided with the LIGAND and
+      64             : the PROTEIN keywords.
+      65             : 
+      66             : */
+      67             : //+ENDPLUMEDOC
+      68             : 
+      69             : /**
+      70             :  * @class Random_Walk Random_Walk.cpp "maze/Random_Walk.cpp"
+      71             :  *
+      72             :  * @brief Perform a random walk within the protein matrix.
+      73             :  */
+      74             : class Random_Walk: public Optimizer {
+      75             : public:
+      76             :   /**
+      77             :    * PLMD constructor.
+      78             :    *
+      79             :    * @param[in] ao PLMD::ActionOptions&
+      80             :    */
+      81             :   explicit Random_Walk(const ActionOptions& ao);
+      82             : 
+      83             :   /**
+      84             :    * Registers PLMD keywords.
+      85             :    *
+      86             :    * @param[in] keys PLMD keywords
+      87             :    */
+      88             :   static void registerKeywords(Keywords&);
+      89             : 
+      90             :   /**
+      91             :    * Each class deriving from Optimizer needs to override this function.
+      92             :    */
+      93             :   void optimize() override;
+      94             : };
+      95             : 
+      96             : // Register MAZE_RANDOM_WALK.
+      97             : PLUMED_REGISTER_ACTION(Random_Walk, "MAZE_RANDOM_WALK")
+      98             : 
+      99           4 : void Random_Walk::registerKeywords(Keywords& keys) {
+     100           4 :   Optimizer::registerKeywords(keys);
+     101             : 
+     102           4 :   keys.remove("N_ITER");
+     103           4 : }
+     104             : 
+     105           2 : Random_Walk::Random_Walk(const ActionOptions& ao)
+     106           2 :   : PLUMED_OPT_INIT(ao)
+     107             : {
+     108           2 :   log.printf("maze> Fake optimizer that returns a next step as random,\
+     109             :     can be used to monitor loss, and for debugging and regtests purposes.\n");
+     110             : 
+     111           4 :   set_label("RANDOM_WALK");
+     112             : 
+     113             :   start_step_0();
+     114             : 
+     115           2 :   checkRead();
+     116           2 : }
+     117             : 
+     118           6 : void Random_Walk::optimize() {
+     119           6 :   set_opt(rnd::next_plmd_vector());
+     120           6 :   set_opt_value(score());
+     121           6 : }
+     122             : 
+     123             : } // namespace maze
+     124             : } // namespace PLMD
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Simulated_Annealing.cpp.func-sort-c.html b/coverage/maze/Simulated_Annealing.cpp.func-sort-c.html new file mode 100644 index 000000000000..71c1c4fd9da0 --- /dev/null +++ b/coverage/maze/Simulated_Annealing.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - maze/Simulated_Annealing.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Simulated_Annealing.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:434987.8 %
Date:2024-04-19 12:12:35Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze19Simulated_AnnealingC2ERKNS_13ActionOptionsE0
_ZN4PLMD4maze19Simulated_AnnealingC1ERKNS_13ActionOptionsE1
_ZN4PLMD4maze19Simulated_Annealing16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD4maze19Simulated_Annealing8optimizeEv3
_ZN4PLMD4maze19Simulated_Annealing20decrease_probabilityEj30
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Simulated_Annealing.cpp.func.html b/coverage/maze/Simulated_Annealing.cpp.func.html new file mode 100644 index 000000000000..b6d7a3cfb8b5 --- /dev/null +++ b/coverage/maze/Simulated_Annealing.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - maze/Simulated_Annealing.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Simulated_Annealing.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:434987.8 %
Date:2024-04-19 12:12:35Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze19Simulated_Annealing16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD4maze19Simulated_Annealing20decrease_probabilityEj30
_ZN4PLMD4maze19Simulated_Annealing8optimizeEv3
_ZN4PLMD4maze19Simulated_AnnealingC1ERKNS_13ActionOptionsE1
_ZN4PLMD4maze19Simulated_AnnealingC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Simulated_Annealing.cpp.gcov.html b/coverage/maze/Simulated_Annealing.cpp.gcov.html new file mode 100644 index 000000000000..039719c04020 --- /dev/null +++ b/coverage/maze/Simulated_Annealing.cpp.gcov.html @@ -0,0 +1,352 @@ + + + + + + + + LCOV - plumed test coverage - maze/Simulated_Annealing.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Simulated_Annealing.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:434987.8 %
Date:2024-04-19 12:12:35Functions:4580.0 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze10Steered_MDC2ERKNS_13ActionOptionsE0
_ZN4PLMD4maze10Steered_MDC1ERKNS_13ActionOptionsE1
_ZN4PLMD4maze10Steered_MD8optimizeEv2
_ZN4PLMD4maze10Steered_MD16registerKeywordsERNS_8KeywordsE3
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Steered_MD.cpp.func.html b/coverage/maze/Steered_MD.cpp.func.html new file mode 100644 index 000000000000..f0eee9b879cd --- /dev/null +++ b/coverage/maze/Steered_MD.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - maze/Steered_MD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Steered_MD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:313296.9 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze10Steered_MD16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD4maze10Steered_MD8optimizeEv2
_ZN4PLMD4maze10Steered_MDC1ERKNS_13ActionOptionsE1
_ZN4PLMD4maze10Steered_MDC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Steered_MD.cpp.gcov.html b/coverage/maze/Steered_MD.cpp.gcov.html new file mode 100644 index 000000000000..7c5c9a0b5150 --- /dev/null +++ b/coverage/maze/Steered_MD.cpp.gcov.html @@ -0,0 +1,253 @@ + + + + + + + + LCOV - plumed test coverage - maze/Steered_MD.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Steered_MD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:313296.9 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2019 Jakub Rydzewski (jr@fizyka.umk.pl). All rights reserved.
+       3             : 
+       4             : See http://www.maze-code.github.io for more information.
+       5             : 
+       6             : This file is part of maze.
+       7             : 
+       8             : maze is free software: you can redistribute it and/or modify it under the
+       9             : terms of the GNU Lesser General Public License as published by the Free
+      10             : Software Foundation, either version 3 of the License, or (at your option)
+      11             : any later version.
+      12             : 
+      13             : maze is distributed in the hope that it will be useful, but WITHOUT ANY
+      14             : WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+      15             : FOR A PARTICULAR PURPOSE.
+      16             : 
+      17             : See the GNU Lesser General Public License for more details.
+      18             : 
+      19             : You should have received a copy of the GNU Lesser General Public License
+      20             : along with maze. If not, see <https://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : /**
+      24             :  * @file Steered_MD.cpp
+      25             :  *
+      26             :  * @author J. Rydzewski (jr@fizyka.umk.pl)
+      27             :  */
+      28             : 
+      29             : #include "core/ActionRegister.h"
+      30             : #include "Optimizer.h"
+      31             : 
+      32             : namespace PLMD {
+      33             : namespace maze {
+      34             : 
+      35             : //+PLUMEDOC MAZE_OPTIMIZER MAZE_STEERED_MD
+      36             : /*
+      37             : 
+      38             : Performs a linear unbinding along a predefined biasing direction that
+      39             : needs to be provided using the PULLING keyword.
+      40             : 
+      41             : \par Examples
+      42             : 
+      43             : Every optimizer implemented in the maze module needs a loss function as
+      44             : an argument, and it should be passed using the \ref MAZE_LOSS keyword.
+      45             : 
+      46             : \plumedfile
+      47             : MAZE_STEERED_MD ...
+      48             :   LABEL=smd
+      49             : 
+      50             :   LOSS=l
+      51             :   PULLING=0.3,0.3,0.3
+      52             :   OPTIMIZER_STRIDE=_
+      53             : 
+      54             :   LIGAND=2635-2646
+      55             :   PROTEIN=1-2634
+      56             : ... MAZE_STEERED_MD
+      57             : \endplumedfile
+      58             : 
+      59             : As shown above, each optimizer should be provided with the LIGAND and
+      60             : the PROTEIN keywords.
+      61             : 
+      62             : */
+      63             : //+ENDPLUMEDOC
+      64             : 
+      65             : /**
+      66             :  * @class Steered_MD Steered_MD.cpp "maze/Steered_MD.cpp"
+      67             :  * @brief Performs steered MD simulation.
+      68             :  */
+      69             : class Steered_MD: public Optimizer {
+      70             : public:
+      71             :   /**
+      72             :    * PLMD constructor.
+      73             :    *
+      74             :    * @param[in] ao PLMD::ActionOptions&
+      75             :    */
+      76             :   explicit Steered_MD(const ActionOptions& ao);
+      77             : 
+      78             :   /**
+      79             :    * Registers PLMD keywords.
+      80             :    *
+      81             :    * @param[in] keys PLMD keywords
+      82             :    */
+      83             :   static void registerKeywords(Keywords&);
+      84             : 
+      85             :   /**
+      86             :    * Each class deriving from Optimizer needs to override this function.
+      87             :    */
+      88             :   void optimize() override;
+      89             : 
+      90             : private:
+      91             :   //! Total distance traveled by the ligand.
+      92             :   double total_dist_;
+      93             : 
+      94             :   //! Ligand center of mass.
+      95             :   Vector com_;
+      96             : 
+      97             :   //! Constant direction of biasing.
+      98             :   Vector pulling_;
+      99             : 
+     100             :   //! PLMD::Value of total distance.
+     101             :   Value* value_total_dist_;
+     102             : };
+     103             : 
+     104             : // Register MAZE_STEERED_MD.
+     105             : PLUMED_REGISTER_ACTION(Steered_MD, "MAZE_STEERED_MD")
+     106             : 
+     107           3 : void Steered_MD::registerKeywords(Keywords& keys) {
+     108           3 :   Optimizer::registerKeywords(keys);
+     109             : 
+     110           3 :   keys.remove("N_ITER");
+     111             : 
+     112           6 :   keys.add(
+     113             :     "compulsory",
+     114             :     "PULLING",
+     115             :     "Constant biasing direction."
+     116             :   );
+     117             : 
+     118           6 :   keys.addOutputComponent(
+     119             :     "tdist",
+     120             :     "default",
+     121             :     "Total distance traveled by biased atoms."
+     122             :   );
+     123           3 : }
+     124             : 
+     125           1 : Steered_MD::Steered_MD(const ActionOptions& ao)
+     126             :   : PLUMED_OPT_INIT(ao),
+     127           1 :     total_dist_(0.0)
+     128             : {
+     129           1 :   log.printf("maze> Steered MD.\n");
+     130             : 
+     131           2 :   if (keywords.exists("PULLING")) {
+     132             :     std::vector<double> v;
+     133           1 :     parseVector("PULLING", v);
+     134           1 :     pulling_ = tls::vector2Vector(v);
+     135             : 
+     136           1 :     log.printf("maze> PULLING read.\n");
+     137             :   }
+     138             : 
+     139           2 :   set_label("STEERED_MD");
+     140             :   set_opt(pulling_);
+     141             :   set_opt_value(0.0);
+     142             : 
+     143             :   start_step_stride();
+     144             : 
+     145           1 :   checkRead();
+     146             : 
+     147           1 :   com_ = center_of_mass();
+     148             : 
+     149           2 :   addComponent("tdist");
+     150           1 :   componentIsNotPeriodic("tdist");
+     151           1 :   value_total_dist_ = getPntrToComponent("tdist");
+     152           1 : }
+     153             : 
+     154           2 : void Steered_MD::optimize() {
+     155           2 :   Vector c = center_of_mass();
+     156           2 :   Vector d;
+     157             : 
+     158           2 :   if (pbc_) {
+     159           2 :     d = pbcDistance(c, com_);
+     160             :   }
+     161             :   else {
+     162           0 :     d = delta(c, com_);
+     163             :   }
+     164             : 
+     165           2 :   double dist = d.modulo();
+     166           2 :   total_dist_ += dist;
+     167             : 
+     168             :   set_opt(pulling_);
+     169           2 :   set_opt_value(score());
+     170           2 :   com_ = c;
+     171             : 
+     172           2 :   value_total_dist_->set(total_dist_);
+     173           2 : }
+     174             : 
+     175             : } // namespace maze
+     176             : } // namespace PLMD
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Tools.h.func-sort-c.html b/coverage/maze/Tools.h.func-sort-c.html new file mode 100644 index 000000000000..6af2c8a213d3 --- /dev/null +++ b/coverage/maze/Tools.h.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - maze/Tools.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Tools.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:131492.9 %
Date:2024-04-19 12:12:35Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze3tls13vector2VectorIdEENS_13VectorGenericILj3EEERKSt6vectorIT_SaIS6_EE1
_ZN4PLMD4maze3tls19get_pointers_labelsIPNS0_9OptimizerEEESt6vectorIT_SaIS6_EERKS5_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISE_EERKNS_9ActionSetERSE_1
_ZN4PLMD4maze3tls19get_pointers_labelsIPNS0_4LossEEESt6vectorIT_SaIS6_EERKS5_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISE_EERKNS_9ActionSetERSE_7
_ZN4PLMD4maze3tls3sgnIdEEiT_30
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Tools.h.func.html b/coverage/maze/Tools.h.func.html new file mode 100644 index 000000000000..b66d1885c358 --- /dev/null +++ b/coverage/maze/Tools.h.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - maze/Tools.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Tools.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:131492.9 %
Date:2024-04-19 12:12:35Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze3tls13vector2VectorIdEENS_13VectorGenericILj3EEERKSt6vectorIT_SaIS6_EE1
_ZN4PLMD4maze3tls19get_pointers_labelsIPNS0_4LossEEESt6vectorIT_SaIS6_EERKS5_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISE_EERKNS_9ActionSetERSE_7
_ZN4PLMD4maze3tls19get_pointers_labelsIPNS0_9OptimizerEEESt6vectorIT_SaIS6_EERKS5_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISE_EERKNS_9ActionSetERSE_1
_ZN4PLMD4maze3tls3sgnIdEEiT_30
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Tools.h.gcov.html b/coverage/maze/Tools.h.gcov.html new file mode 100644 index 000000000000..435a3f7ac875 --- /dev/null +++ b/coverage/maze/Tools.h.gcov.html @@ -0,0 +1,257 @@ + + + + + + + + LCOV - plumed test coverage - maze/Tools.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Tools.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:131492.9 %
Date:2024-04-19 12:12:35Functions:44100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2019 Jakub Rydzewski (jr@fizyka.umk.pl). All rights reserved.
+       3             : 
+       4             : See http://www.maze-code.github.io for more information.
+       5             : 
+       6             : This file is part of maze.
+       7             : 
+       8             : maze is free software: you can redistribute it and/or modify it under the
+       9             : terms of the GNU Lesser General Public License as published by the Free
+      10             : Software Foundation, either version 3 of the License, or (at your option)
+      11             : any later version.
+      12             : 
+      13             : maze is distributed in the hope that it will be useful, but WITHOUT ANY
+      14             : WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+      15             : FOR A PARTICULAR PURPOSE.
+      16             : 
+      17             : See the GNU Lesser General Public License for more details.
+      18             : 
+      19             : You should have received a copy of the GNU Lesser General Public License
+      20             : along with maze. If not, see <https://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_maze_Tools_h
+      23             : #define __PLUMED_maze_Tools_h
+      24             : 
+      25             : /**
+      26             :  * @file Tools.h
+      27             :  *
+      28             :  * @author J. Rydzewski
+      29             :  */
+      30             : 
+      31             : #include "core/ActionSet.h"
+      32             : #include "tools/Vector.h"
+      33             : #include "Core.h"
+      34             : 
+      35             : namespace PLMD {
+      36             : namespace maze {
+      37             : 
+      38             : /**
+      39             :  * @class tls Tools.h "maze/Tools.h"
+      40             :  *
+      41             :  * @brief Helper functions.
+      42             :  */
+      43             : class tls {
+      44             : public:
+      45             :   template<typename T> static int sgn(T val);
+      46             : 
+      47             :   template<typename T>
+      48             :   static std::vector<std::string> get_labels_actions(const ActionSet&);
+      49             : 
+      50             :   template<typename T>
+      51             :   static T get_pointer_label(
+      52             :     const std::string&,
+      53             :     const ActionSet&, std::string&
+      54             :   );
+      55             : 
+      56             :   template<typename T>
+      57             :   static std::vector<T> get_pointers_labels(
+      58             :     const std::vector<std::string>&,
+      59             :     const ActionSet&, std::string&
+      60             :   );
+      61             : 
+      62             :   template<typename T>
+      63             :   static std::vector<T> Vector2vector(const Vector&);
+      64             : 
+      65             :   template<typename T>
+      66             :   static Vector vector2Vector(const std::vector<T>&);
+      67             : 
+      68             :   template<typename T>
+      69             :   static T vector_l(const std::vector<T>&);
+      70             : 
+      71             :   template<typename T>
+      72             :   static std::vector<T> vector_n(const std::vector<T>&);
+      73             : 
+      74             :   template<typename T>
+      75             :   static T mean(const std::vector<T>&);
+      76             : 
+      77             :   template<typename T>
+      78             :   static T std(const std::vector<T>&);
+      79             : 
+      80             :   struct delete_ptr {
+      81             :     template<typename T> void operator()(T t) {
+      82             :       delete t;
+      83             :     }
+      84             :   };
+      85             : };
+      86             : 
+      87             : template<typename T>
+      88             : T tls::std(const std::vector<T>& v) {
+      89             :   T m=mean(v);
+      90             :   T sq_sum=std::inner_product(v.begin(), v.end(), v.begin(), 0.0);
+      91             : 
+      92             :   return std::sqrt(sq_sum/v.size()-m*m);
+      93             : }
+      94             : 
+      95             : template<typename T>
+      96             : T tls::mean(const std::vector<T>& v) {
+      97             :   return std::accumulate(v.begin(), v.end(), 0.0)/v.size();
+      98             : }
+      99             : 
+     100             : template<typename T>
+     101             : T tls::vector_l(const std::vector<T>& v) {
+     102             :   return std::sqrt(std::inner_product(v.begin(), v.end(), v.begin(), 0.0));
+     103             : }
+     104             : 
+     105             : template<typename T>
+     106             : std::vector<T> tls::vector_n(const std::vector<T>& v) {
+     107             :   double l=vector_l(v);
+     108             :   std::vector<double> n;
+     109             :   for(std::size_t i=0; i<v.size(); ++i)
+     110             :     n.push_back(v[i]/l);
+     111             : 
+     112             :   return n;
+     113             : }
+     114             : 
+     115             : template<typename T>
+     116             : std::vector<T> tls::Vector2vector(const Vector& v) {
+     117             :   std::vector<T> t= {v[0], v[1], v[2]};
+     118             : 
+     119             :   return t;
+     120             : }
+     121             : 
+     122             : template<typename T>
+     123           1 : Vector tls::vector2Vector(const std::vector<T>& v) {
+     124           1 :   Vector t(v[0], v[1], v[2]);
+     125             : 
+     126           1 :   return t;
+     127             : }
+     128             : 
+     129             : template<typename T>
+     130          30 : int tls::sgn(T val) {
+     131          30 :   return (T(0)<val)-(val<T(0));
+     132             : }
+     133             : 
+     134             : template<typename T>
+     135             : std::vector<std::string> tls::get_labels_actions(const ActionSet& actionset) {
+     136             :   std::vector<std::string> action_str(0);
+     137             :   std::vector<T> action_pntrs=actionset.select<T>();
+     138             : 
+     139             :   for(unsigned int i=0; i<action_pntrs.size(); i++)
+     140             :     action_str.push_back(action_pntrs[i]->getLabel());
+     141             : 
+     142             :   return action_str;
+     143             : }
+     144             : 
+     145             : template<typename T> T
+     146             : tls::get_pointer_label(
+     147             :   const std::string& action_label,
+     148             :   const ActionSet& actionset,
+     149             :   std::string& error_msg) {
+     150             : 
+     151             :   std::vector<std::string> action_labels(1);
+     152             :   action_labels[0]=action_label;
+     153             :   std::vector<T> action_pntrs=get_pointers_labels<T>(action_labels, actionset, error_msg);
+     154             : 
+     155             :   return action_pntrs[0];
+     156             : }
+     157             : 
+     158             : template<typename T>
+     159           8 : std::vector<T> tls::get_pointers_labels(
+     160             :   const std::vector<std::string>& action_labels,
+     161             :   const ActionSet& actionset,
+     162             :   std::string& error_msg) {
+     163             : 
+     164           8 :   std::vector<T> action_pntrs(action_labels.size(), NULL);
+     165             :   error_msg="";
+     166           8 :   std::vector<std::string> missing(0);
+     167             : 
+     168          16 :   for(unsigned int i=0; i<action_labels.size(); i++) {
+     169           8 :     action_pntrs[i]=actionset.selectWithLabel<T>(action_labels[i]);
+     170           8 :     if(action_pntrs[i]==NULL)
+     171           0 :       missing.push_back(action_labels[i]);
+     172             :   }
+     173             : 
+     174           8 :   return action_pntrs;
+     175           8 : }
+     176             : 
+     177             : } // namespace maze
+     178             : } // namespace PLMD
+     179             : 
+     180             : #endif // __PLUMED_maze_Tools_h
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/index-sort-f.html b/coverage/maze/index-sort-f.html new file mode 100644 index 000000000000..7e753332b9a8 --- /dev/null +++ b/coverage/maze/index-sort-f.html @@ -0,0 +1,234 @@ + + + + + + + + LCOV - plumed test coverage - maze + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mazeHitTotalCoverage
Test:plumed test coverageLines:65476885.2 %
Date:2024-04-19 12:12:35Functions:658180.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Loss.h +
50.0%50.0%
+
50.0 %1 / 266.7 %2 / 3
Memetic.h +
61.2%61.2%
+
61.2 %123 / 20170.0 %14 / 20
Memetic.cpp +
100.0%
+
100.0 %60 / 6075.0 %3 / 4
Loss.cpp +
100.0%
+
100.0 %23 / 2375.0 %3 / 4
Steered_MD.cpp +
96.9%96.9%
+
96.9 %31 / 3275.0 %3 / 4
Random_Walk.cpp +
100.0%
+
100.0 %14 / 1475.0 %3 / 4
Random_Acceleration_MD.cpp +
95.1%95.1%
+
95.1 %39 / 4175.0 %3 / 4
Random_MT.h +
70.6%70.6%
+
70.6 %12 / 1775.0 %3 / 4
Simulated_Annealing.cpp +
87.8%87.8%
+
87.8 %43 / 4980.0 %4 / 5
Optimizer_Bias.cpp +
97.9%97.9%
+
97.9 %95 / 9783.3 %5 / 6
Optimizer.cpp +
90.0%90.0%
+
90.0 %162 / 18090.0 %9 / 10
Optimizer.h +
100.0%
+
100.0 %13 / 13100.0 %1 / 1
Member.h +
100.0%
+
100.0 %5 / 5100.0 %2 / 2
Tools.h +
92.9%92.9%
+
92.9 %13 / 14100.0 %4 / 4
Random_MT.cpp +
100.0%
+
100.0 %20 / 20100.0 %6 / 6
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/index-sort-l.html b/coverage/maze/index-sort-l.html new file mode 100644 index 000000000000..045032700eaa --- /dev/null +++ b/coverage/maze/index-sort-l.html @@ -0,0 +1,234 @@ + + + + + + + + LCOV - plumed test coverage - maze + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mazeHitTotalCoverage
Test:plumed test coverageLines:65476885.2 %
Date:2024-04-19 12:12:35Functions:658180.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Loss.h +
50.0%50.0%
+
50.0 %1 / 266.7 %2 / 3
Memetic.h +
61.2%61.2%
+
61.2 %123 / 20170.0 %14 / 20
Random_MT.h +
70.6%70.6%
+
70.6 %12 / 1775.0 %3 / 4
Simulated_Annealing.cpp +
87.8%87.8%
+
87.8 %43 / 4980.0 %4 / 5
Optimizer.cpp +
90.0%90.0%
+
90.0 %162 / 18090.0 %9 / 10
Tools.h +
92.9%92.9%
+
92.9 %13 / 14100.0 %4 / 4
Random_Acceleration_MD.cpp +
95.1%95.1%
+
95.1 %39 / 4175.0 %3 / 4
Steered_MD.cpp +
96.9%96.9%
+
96.9 %31 / 3275.0 %3 / 4
Optimizer_Bias.cpp +
97.9%97.9%
+
97.9 %95 / 9783.3 %5 / 6
Member.h +
100.0%
+
100.0 %5 / 5100.0 %2 / 2
Optimizer.h +
100.0%
+
100.0 %13 / 13100.0 %1 / 1
Random_Walk.cpp +
100.0%
+
100.0 %14 / 1475.0 %3 / 4
Random_MT.cpp +
100.0%
+
100.0 %20 / 20100.0 %6 / 6
Loss.cpp +
100.0%
+
100.0 %23 / 2375.0 %3 / 4
Memetic.cpp +
100.0%
+
100.0 %60 / 6075.0 %3 / 4
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/index.html b/coverage/maze/index.html new file mode 100644 index 000000000000..95e0b4d8422f --- /dev/null +++ b/coverage/maze/index.html @@ -0,0 +1,234 @@ + + + + + + + + LCOV - plumed test coverage - maze + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mazeHitTotalCoverage
Test:plumed test coverageLines:65476885.2 %
Date:2024-04-19 12:12:35Functions:658180.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Loss.cpp +
100.0%
+
100.0 %23 / 2375.0 %3 / 4
Loss.h +
50.0%50.0%
+
50.0 %1 / 266.7 %2 / 3
Member.h +
100.0%
+
100.0 %5 / 5100.0 %2 / 2
Memetic.cpp +
100.0%
+
100.0 %60 / 6075.0 %3 / 4
Memetic.h +
61.2%61.2%
+
61.2 %123 / 20170.0 %14 / 20
Optimizer.cpp +
90.0%90.0%
+
90.0 %162 / 18090.0 %9 / 10
Optimizer.h +
100.0%
+
100.0 %13 / 13100.0 %1 / 1
Optimizer_Bias.cpp +
97.9%97.9%
+
97.9 %95 / 9783.3 %5 / 6
Random_Acceleration_MD.cpp +
95.1%95.1%
+
95.1 %39 / 4175.0 %3 / 4
Random_MT.cpp +
100.0%
+
100.0 %20 / 20100.0 %6 / 6
Random_MT.h +
70.6%70.6%
+
70.6 %12 / 1775.0 %3 / 4
Random_Walk.cpp +
100.0%
+
100.0 %14 / 1475.0 %3 / 4
Simulated_Annealing.cpp +
87.8%87.8%
+
87.8 %43 / 4980.0 %4 / 5
Steered_MD.cpp +
96.9%96.9%
+
96.9 %31 / 3275.0 %3 / 4
Tools.h +
92.9%92.9%
+
92.9 %13 / 14100.0 %4 / 4
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/membranefusion/FusionPoreExpansionP.cpp.func-sort-c.html b/coverage/membranefusion/FusionPoreExpansionP.cpp.func-sort-c.html new file mode 100644 index 000000000000..1af3fc36df78 --- /dev/null +++ b/coverage/membranefusion/FusionPoreExpansionP.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - membranefusion/FusionPoreExpansionP.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - membranefusion - FusionPoreExpansionP.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:13715787.3 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14membranefusion20fusionPoreExpansionPC2ERKNS_13ActionOptionsE0
_ZN4PLMD14membranefusion20fusionPoreExpansionPC1ERKNS_13ActionOptionsE1
_ZN4PLMD14membranefusion20fusionPoreExpansionP16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD14membranefusion20fusionPoreExpansionP9calculateEv4
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/membranefusion/FusionPoreExpansionP.cpp.func.html b/coverage/membranefusion/FusionPoreExpansionP.cpp.func.html new file mode 100644 index 000000000000..6705bc1958fc --- /dev/null +++ b/coverage/membranefusion/FusionPoreExpansionP.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - membranefusion/FusionPoreExpansionP.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - membranefusion - FusionPoreExpansionP.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:13715787.3 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14membranefusion20fusionPoreExpansionP16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD14membranefusion20fusionPoreExpansionP9calculateEv4
_ZN4PLMD14membranefusion20fusionPoreExpansionPC1ERKNS_13ActionOptionsE1
_ZN4PLMD14membranefusion20fusionPoreExpansionPC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/membranefusion/FusionPoreExpansionP.cpp.gcov.html b/coverage/membranefusion/FusionPoreExpansionP.cpp.gcov.html new file mode 100644 index 000000000000..2f03451e8829 --- /dev/null +++ b/coverage/membranefusion/FusionPoreExpansionP.cpp.gcov.html @@ -0,0 +1,682 @@ + + + + + + + + LCOV - plumed test coverage - membranefusion/FusionPoreExpansionP.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - membranefusion - FusionPoreExpansionP.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:13715787.3 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14membranefusion21fusionPoreNucleationPC2ERKNS_13ActionOptionsE0
_ZN4PLMD14membranefusion21fusionPoreNucleationPC1ERKNS_13ActionOptionsE1
_ZN4PLMD14membranefusion21fusionPoreNucleationP16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD14membranefusion21fusionPoreNucleationP9calculateEv4
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/membranefusion/FusionPoreNucleationP.cpp.func.html b/coverage/membranefusion/FusionPoreNucleationP.cpp.func.html new file mode 100644 index 000000000000..a0be7ad01fe9 --- /dev/null +++ b/coverage/membranefusion/FusionPoreNucleationP.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - membranefusion/FusionPoreNucleationP.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - membranefusion - FusionPoreNucleationP.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:18320788.4 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14membranefusion21fusionPoreNucleationP16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD14membranefusion21fusionPoreNucleationP9calculateEv4
_ZN4PLMD14membranefusion21fusionPoreNucleationPC1ERKNS_13ActionOptionsE1
_ZN4PLMD14membranefusion21fusionPoreNucleationPC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/membranefusion/FusionPoreNucleationP.cpp.gcov.html b/coverage/membranefusion/FusionPoreNucleationP.cpp.gcov.html new file mode 100644 index 000000000000..2d02f9904a2d --- /dev/null +++ b/coverage/membranefusion/FusionPoreNucleationP.cpp.gcov.html @@ -0,0 +1,884 @@ + + + + + + + + LCOV - plumed test coverage - membranefusion/FusionPoreNucleationP.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - membranefusion - FusionPoreNucleationP.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:18320788.4 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14membranefusion10memFusionPC2ERKNS_13ActionOptionsE0
_ZN4PLMD14membranefusion10memFusionPC1ERKNS_13ActionOptionsE1
_ZN4PLMD14membranefusion10memFusionP16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD14membranefusion10memFusionP9calculateEv3
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/membranefusion/MemFusionP.cpp.func.html b/coverage/membranefusion/MemFusionP.cpp.func.html new file mode 100644 index 000000000000..e26109b2dbe6 --- /dev/null +++ b/coverage/membranefusion/MemFusionP.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - membranefusion/MemFusionP.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - membranefusion - MemFusionP.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:13315088.7 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14membranefusion10memFusionP16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD14membranefusion10memFusionP9calculateEv3
_ZN4PLMD14membranefusion10memFusionPC1ERKNS_13ActionOptionsE1
_ZN4PLMD14membranefusion10memFusionPC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/membranefusion/MemFusionP.cpp.gcov.html b/coverage/membranefusion/MemFusionP.cpp.gcov.html new file mode 100644 index 000000000000..dc5a39339668 --- /dev/null +++ b/coverage/membranefusion/MemFusionP.cpp.gcov.html @@ -0,0 +1,685 @@ + + + + + + + + LCOV - plumed test coverage - membranefusion/MemFusionP.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - membranefusion - MemFusionP.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:13315088.7 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ + + + + + + + +

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

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
FusionPoreNucleationP.cpp +
88.4%88.4%
+
88.4 %183 / 20775.0 %3 / 4
FusionPoreExpansionP.cpp +
87.3%87.3%
+
87.3 %137 / 15775.0 %3 / 4
MemFusionP.cpp +
88.7%88.7%
+
88.7 %133 / 15075.0 %3 / 4
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/membranefusion/index-sort-l.html b/coverage/membranefusion/index-sort-l.html new file mode 100644 index 000000000000..c18214466655 --- /dev/null +++ b/coverage/membranefusion/index-sort-l.html @@ -0,0 +1,114 @@ + + + + + + + + LCOV - plumed test coverage - membranefusion + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - membranefusionHitTotalCoverage
Test:plumed test coverageLines:45351488.1 %
Date:2024-04-19 12:12:35Functions:91275.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
FusionPoreExpansionP.cpp +
87.3%87.3%
+
87.3 %137 / 15775.0 %3 / 4
FusionPoreNucleationP.cpp +
88.4%88.4%
+
88.4 %183 / 20775.0 %3 / 4
MemFusionP.cpp +
88.7%88.7%
+
88.7 %133 / 15075.0 %3 / 4
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/membranefusion/index.html b/coverage/membranefusion/index.html new file mode 100644 index 000000000000..d4a90651154d --- /dev/null +++ b/coverage/membranefusion/index.html @@ -0,0 +1,114 @@ + + + + + + + + LCOV - plumed test coverage - membranefusion + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - membranefusionHitTotalCoverage
Test:plumed test coverageLines:45351488.1 %
Date:2024-04-19 12:12:35Functions:91275.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
FusionPoreExpansionP.cpp +
87.3%87.3%
+
87.3 %137 / 15775.0 %3 / 4
FusionPoreNucleationP.cpp +
88.4%88.4%
+
88.4 %183 / 20775.0 %3 / 4
MemFusionP.cpp +
88.7%88.7%
+
88.7 %133 / 15075.0 %3 / 4
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/AlphaBeta.cpp.func-sort-c.html b/coverage/multicolvar/AlphaBeta.cpp.func-sort-c.html new file mode 100644 index 000000000000..c8e53ce88e4c --- /dev/null +++ b/coverage/multicolvar/AlphaBeta.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + 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:353989.7 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar9AlphaBetaC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar9AlphaBetaC1ERKNS_13ActionOptionsE2
_ZN4PLMD11multicolvar9AlphaBeta16registerKeywordsERNS_8KeywordsE4
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/AlphaBeta.cpp.func.html b/coverage/multicolvar/AlphaBeta.cpp.func.html new file mode 100644 index 000000000000..994591799b73 --- /dev/null +++ b/coverage/multicolvar/AlphaBeta.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + 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:353989.7 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar9AlphaBeta16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD11multicolvar9AlphaBetaC1ERKNS_13ActionOptionsE2
_ZN4PLMD11multicolvar9AlphaBetaC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/AlphaBeta.cpp.gcov.html b/coverage/multicolvar/AlphaBeta.cpp.gcov.html new file mode 100644 index 000000000000..1faade405caa --- /dev/null +++ b/coverage/multicolvar/AlphaBeta.cpp.gcov.html @@ -0,0 +1,187 @@ + + + + + + + + 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:353989.7 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionShortcut.h"
+      23             : #include "core/ActionWithValue.h"
+      24             : #include "core/ActionRegister.h"
+      25             : #include "core/PlumedMain.h"
+      26             : #include "core/ActionSet.h"
+      27             : #include <string>
+      28             : #include <cmath>
+      29             : 
+      30             : //+PLUMEDOC MCOLVAR ALPHABETA
+      31             : /*
+      32             : Calculate the alpha beta CV
+      33             : 
+      34             : \par Examples
+      35             : 
+      36             : 
+      37             : */
+      38             : //+ENDPLUMEDOC
+      39             : 
+      40             : namespace PLMD {
+      41             : namespace multicolvar {
+      42             : 
+      43             : class AlphaBeta : public ActionShortcut {
+      44             : public:
+      45             :   static void registerKeywords(Keywords& keys);
+      46             :   explicit AlphaBeta(const ActionOptions&);
+      47             : };
+      48             : 
+      49             : PLUMED_REGISTER_ACTION(AlphaBeta,"ALPHABETA")
+      50             : 
+      51           4 : void AlphaBeta::registerKeywords(Keywords& keys) {
+      52           4 :   ActionShortcut::registerKeywords( keys );
+      53           8 :   keys.addFlag("NOPBC",false,"ignore the periodic boundary conditions when calculating distances");
+      54           8 :   keys.add("numbered","ATOMS","the atoms involved for each of the torsions you wish to calculate. "
+      55             :            "Keywords like ATOMS1, ATOMS2, ATOMS3,... should be listed and one torsion will be "
+      56             :            "calculated for each ATOM keyword you specify");
+      57           8 :   keys.reset_style("ATOMS","atoms");
+      58           8 :   keys.add("numbered","REFERENCE","the reference values for each of the torsional angles.  If you use a single REFERENCE value the "
+      59             :            "same reference value is used for all torsions");
+      60           8 :   keys.add("numbered","COEFFICIENT","the coefficient for each of the torsional angles.  If you use a single COEFFICIENT value the "
+      61             :            "same reference value is used for all torsional angles");
+      62          20 :   keys.needsAction("CONSTANT"); keys.needsAction("TORSION"); keys.needsAction("COMBINE"); keys.needsAction("CUSTOM"); keys.needsAction("SUM");
+      63           4 : }
+      64             : 
+      65           2 : AlphaBeta::AlphaBeta(const ActionOptions& ao):
+      66             :   Action(ao),
+      67           2 :   ActionShortcut(ao)
+      68             : {
+      69             :   // Read in the reference value
+      70           4 :   std::string refstr; parse("REFERENCE",refstr); unsigned nref=0;
+      71           2 :   if( refstr.length()==0 ) {
+      72             :     for(unsigned i=0;; ++i) {
+      73             :       std::string refval;
+      74          18 :       if( !parseNumbered( "REFERENCE", i+1, refval ) ) break;
+      75          15 :       if( i==0 ) refstr = refval; else refstr += "," + refval;
+      76           8 :       nref++;
+      77           8 :     }
+      78             :   }
+      79           4 :   std::string coeffstr; parse("COEFFICIENT",coeffstr); unsigned ncoeff=0;
+      80           2 :   if( coeffstr.length()==0 ) {
+      81             :     for(unsigned i=0;; ++i) {
+      82             :       std::string coeff;
+      83           4 :       if( !parseNumbered( "COEFFICIENT", i+1, coeff) ) break;
+      84           0 :       if( i==0 ) coeffstr = coeff; else coeffstr += "," + coeff;
+      85           0 :       ncoeff++;
+      86           0 :     }
+      87             :   }
+      88           2 :   if( coeffstr.length()==0 ) coeffstr="1";
+      89             :   // Calculate angles
+      90           4 :   readInputLine( getShortcutLabel() + "_torsions: TORSION " + convertInputLineToString() );
+      91           2 :   ActionWithValue* av = plumed.getActionSet().selectWithLabel<ActionWithValue*>( getShortcutLabel() + "_torsions" );
+      92           2 :   plumed_assert( av && (av->copyOutput(0))->getRank()==1 );
+      93           2 :   if( nref==0 ) {
+      94           8 :     std::string refval=refstr; for(unsigned i=1; i<(av->copyOutput(0))->getShape()[0]; ++i) refstr += "," + refval;
+      95           1 :   } else if( nref!=(av->copyOutput(0))->getShape()[0] ) error("mismatch between number of reference values and number of ATOMS specified");
+      96           2 :   if( ncoeff==0 ) {
+      97          16 :     std::string coeff=coeffstr; for(unsigned i=1; i<(av->copyOutput(0))->getShape()[0]; ++i) coeffstr += "," + coeff;
+      98           0 :   } else if( ncoeff!=(av->copyOutput(0))->getShape()[0] ) error("mismatch between number of coefficients and number of ATOMS specified");
+      99           4 :   readInputLine( getShortcutLabel() + "_ref: CONSTANT VALUES=" + refstr );
+     100           4 :   readInputLine( getShortcutLabel() + "_coeff: CONSTANT VALUES=" + coeffstr );
+     101             :   // Caculate difference from reference using combine
+     102           4 :   readInputLine( getShortcutLabel() + "_comb: COMBINE ARG=" + getShortcutLabel() + "_torsions," + getShortcutLabel() + "_ref COEFFICIENTS=1,-1 PERIODIC=NO" );
+     103             :   // Now matheval for cosine bit
+     104           4 :   readInputLine( getShortcutLabel() + "_cos: CUSTOM ARG=" + getShortcutLabel() + "_comb," + getShortcutLabel() + "_coeff FUNC=y*(0.5+0.5*cos(x)) PERIODIC=NO");
+     105             :   // And combine to get final value
+     106           4 :   readInputLine( getShortcutLabel() + ": SUM ARG=" + getShortcutLabel() + "_cos PERIODIC=NO");
+     107           2 : }
+     108             : 
+     109             : }
+     110             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/Angles.cpp.func-sort-c.html b/coverage/multicolvar/Angles.cpp.func-sort-c.html new file mode 100644 index 000000000000..0e98220e459b --- /dev/null +++ b/coverage/multicolvar/Angles.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + 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:304961.2 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar6AnglesC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar6AnglesC1ERKNS_13ActionOptionsE1
_ZN4PLMD11multicolvar6Angles16registerKeywordsERNS_8KeywordsE4
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/Angles.cpp.func.html b/coverage/multicolvar/Angles.cpp.func.html new file mode 100644 index 000000000000..8f58f612e800 --- /dev/null +++ b/coverage/multicolvar/Angles.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + 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:304961.2 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar6Angles16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD11multicolvar6AnglesC1ERKNS_13ActionOptionsE1
_ZN4PLMD11multicolvar6AnglesC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/Angles.cpp.gcov.html b/coverage/multicolvar/Angles.cpp.gcov.html new file mode 100644 index 000000000000..31f33970ba3b --- /dev/null +++ b/coverage/multicolvar/Angles.cpp.gcov.html @@ -0,0 +1,252 @@ + + + + + + + + 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:304961.2 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionShortcut.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "MultiColvarShortcuts.h"
+      25             : 
+      26             : #include <string>
+      27             : #include <cmath>
+      28             : 
+      29             : namespace PLMD {
+      30             : namespace multicolvar {
+      31             : 
+      32             : //+PLUMEDOC COLVAR ANGLES
+      33             : /*
+      34             : Calculate an angle.
+      35             : 
+      36             : This command can be used to compute the angle between three atoms. Alternatively
+      37             : if four atoms appear in the atom
+      38             : specification it calculates the angle between
+      39             : two vectors identified by two pairs of atoms.
+      40             : 
+      41             : If _three_ atoms are given, the angle is defined as:
+      42             : \f[
+      43             : \theta=\arccos\left(\frac{ {\bf r}_{21}\cdot {\bf r}_{23}}{
+      44             : |{\bf r}_{21}| |{\bf r}_{23}|}\right)
+      45             : \f]
+      46             : Here \f$ {\bf r}_{ij}\f$ is the distance vector among the
+      47             : i-th and the j-th listed atom.
+      48             : 
+      49             : If _four_ atoms are given, the angle is defined as:
+      50             : \f[
+      51             : \theta=\arccos\left(\frac{ {\bf r}_{21}\cdot {\bf r}_{34}}{
+      52             : |{\bf r}_{21}| |{\bf r}_{34}|}\right)
+      53             : \f]
+      54             : 
+      55             : Notice that angles defined in this way are non-periodic variables and
+      56             : their value is limited by definition between 0 and \f$\pi\f$.
+      57             : 
+      58             : The vectors \f$ {\bf r}_{ij}\f$ are by default evaluated taking
+      59             : periodic boundary conditions into account.
+      60             : This behavior can be changed with the NOPBC flag.
+      61             : 
+      62             : \par Examples
+      63             : 
+      64             : This command tells plumed to calculate the angle between the vector connecting atom 1 to atom 2 and
+      65             : the vector connecting atom 2 to atom 3 and to print it on file COLVAR1. At the same time,
+      66             : the angle between vector connecting atom 1 to atom 2 and the vector connecting atom 3 to atom 4 is printed
+      67             : on file COLVAR2.
+      68             : \plumedfile
+      69             : 
+      70             : a: ANGLE ATOMS=1,2,3
+      71             : # equivalently one could state:
+      72             : # a: ANGLE ATOMS=1,2,2,3
+      73             : 
+      74             : b: ANGLE ATOMS=1,2,3,4
+      75             : 
+      76             : PRINT ARG=a FILE=COLVAR1
+      77             : PRINT ARG=b FILE=COLVAR2
+      78             : \endplumedfile
+      79             : 
+      80             : This final example instructs plumed to calculate all the angles in the first coordination
+      81             : spheres of the atoms. The bins for a normalized histogram of the distribution is then output
+      82             : 
+      83             : \plumedfile
+      84             : ANGLES GROUP=1-38 HISTOGRAM={GAUSSIAN LOWER=0.0 UPPER=pi NBINS=20} SWITCH={GAUSSIAN R_0=1.0} LABEL=a1
+      85             : PRINT ARG=a1.* FILE=colvar
+      86             : \endplumedfile
+      87             : 
+      88             : 
+      89             : */
+      90             : //+ENDPLUMEDOC
+      91             : 
+      92             : class Angles : public ActionShortcut {
+      93             : public:
+      94             :   explicit Angles(const ActionOptions&);
+      95             :   static void registerKeywords( Keywords& keys );
+      96             : };
+      97             : 
+      98             : PLUMED_REGISTER_ACTION(Angles,"ANGLES")
+      99             : 
+     100           4 : void Angles::registerKeywords( Keywords& keys ) {
+     101           4 :   ActionShortcut::registerKeywords( keys );
+     102           8 :   keys.add("atoms-1","GROUP","Calculate angles for each distinct set of three atoms in the group");
+     103           8 :   keys.add("atoms-2","GROUPA","A group of central atoms about which angles should be calculated");
+     104           8 :   keys.add("atoms-2","GROUPB","When used in conjunction with GROUPA this keyword instructs plumed "
+     105             :            "to calculate all distinct angles involving one atom from GROUPA "
+     106             :            "and two atoms from GROUPB. The atom from GROUPA is the central atom.");
+     107           8 :   keys.add("atoms-3","GROUPC","This must be used in conjunction with GROUPA and GROUPB.  All angles "
+     108             :            "involving one atom from GROUPA, one atom from GROUPB and one atom from "
+     109             :            "GROUPC are calculated. The GROUPA atoms are assumed to be the central "
+     110             :            "atoms");
+     111           8 :   keys.add("optional","SWITCH","the switching function specifies that only those bonds that have a length that is less than a certain threshold are considered");
+     112           8 :   MultiColvarShortcuts::shortcutKeywords( keys ); keys.needsAction("ANGLE"); keys.needsAction("COORD_ANGLES");
+     113           4 : }
+     114             : 
+     115           1 : Angles::Angles(const ActionOptions&ao):
+     116             :   Action(ao),
+     117           1 :   ActionShortcut(ao)
+     118             : {
+     119           2 :   std::string swit; parse("SWITCH",swit);
+     120           1 :   if( swit.length()>0 ) {
+     121           0 :     std::string cat, grp; parse("GROUPA",cat); parse("GROUPB",grp);
+     122           0 :     if( cat.length()==0 || grp.length()==0 ) error("must use GROUPA/GROUPB when using SWITCH");
+     123           0 :     readInputLine( getShortcutLabel() + ": COORD_ANGLES SWITCH={" +  swit + "} CATOMS=" + cat + " GROUP=" + grp + " " + convertInputLineToString() );
+     124             :     return;
+     125             :   }
+     126           2 :   std::vector<std::string> group; parseVector("GROUP",group);
+     127           2 :   std::vector<std::string> groupa; parseVector("GROUPA",groupa);
+     128           2 :   std::vector<std::string> groupb; parseVector("GROUPB",groupb);
+     129           2 :   std::vector<std::string> groupc; parseVector("GROUPC",groupc);
+     130           1 :   if( group.size()>0 ) {
+     131           0 :     if( groupa.size()>0 || groupb.size()>0 || groupc.size()>0 ) error("should only be GROUP keyword in input not GROUPA/GROUPB/GROUPC");
+     132           0 :     Tools::interpretRanges( group ); std::string ainput = getShortcutLabel() + ": ANGLE"; unsigned n=1;
+     133             :     // Not sure if this triple sum makes any sense
+     134           0 :     for(unsigned i=2; i<group.size(); ++i ) {
+     135           0 :       for(unsigned j=1; j<i; ++j ) {
+     136           0 :         for(unsigned k=0; k<j; ++k) {
+     137           0 :           std::string str_n; Tools::convert( n, str_n );
+     138           0 :           ainput += " ATOMS" + str_n + "=" + group[i] + "," + group[j] + "," + group[k]; n++;
+     139             :         }
+     140             :       }
+     141             :     }
+     142           0 :     readInputLine( ainput );
+     143           1 :   } else if( groupc.size()>0 ) {
+     144           0 :     Tools::interpretRanges( groupa ); Tools::interpretRanges( groupb ); Tools::interpretRanges( groupc );
+     145           0 :     unsigned n=1; std::string ainput = getShortcutLabel() + ": ANGLE";
+     146           0 :     for(unsigned i=0; i<groupa.size(); ++i ) {
+     147           0 :       for(unsigned j=0; j<groupb.size(); ++j ) {
+     148           0 :         for(unsigned k=0; k<groupc.size(); ++k) {
+     149           0 :           std::string str_n; Tools::convert( n, str_n );
+     150           0 :           ainput += " ATOMS" + str_n + "=" + groupb[j] + "," + groupa[i] + "," + groupc[k]; n++;
+     151             :         }
+     152             :       }
+     153             :     }
+     154           0 :     readInputLine( ainput );
+     155           1 :   } else if( groupa.size()>0 ) {
+     156           1 :     Tools::interpretRanges( groupa ); Tools::interpretRanges( groupb );
+     157           1 :     unsigned n=1; std::string ainput; ainput = getShortcutLabel() + ": ANGLE";
+     158           2 :     for(unsigned i=0; i<groupa.size(); ++i ) {
+     159           9 :       for(unsigned j=1; j<groupb.size(); ++j ) {
+     160          44 :         for(unsigned k=0; k<j; ++k) {
+     161          36 :           std::string str_n; Tools::convert( n, str_n );
+     162          72 :           ainput += " ATOMS" + str_n + "=" + groupb[j] + "," + groupa[i] + "," + groupb[k]; n++;
+     163             :         }
+     164             :       }
+     165             :     }
+     166           1 :     readInputLine( ainput );
+     167             :   }
+     168           1 :   MultiColvarShortcuts::expandFunctions( getShortcutLabel(), getShortcutLabel(), "", this );
+     169           1 : }
+     170             : 
+     171             : }
+     172             : }
+     173             : 
+     174             : 
+     175             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/CoordAngles.cpp.func-sort-c.html b/coverage/multicolvar/CoordAngles.cpp.func-sort-c.html new file mode 100644 index 000000000000..b34f675dbda1 --- /dev/null +++ b/coverage/multicolvar/CoordAngles.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/CoordAngles.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - CoordAngles.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4242100.0 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar11CoordAnglesC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar11CoordAnglesC1ERKNS_13ActionOptionsE2
_ZN4PLMD11multicolvar11CoordAngles16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD11multicolvar11CoordAngles14pruneShortcutsERNS_8KeywordsE8
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/CoordAngles.cpp.func.html b/coverage/multicolvar/CoordAngles.cpp.func.html new file mode 100644 index 000000000000..f9f812987fb1 --- /dev/null +++ b/coverage/multicolvar/CoordAngles.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/CoordAngles.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - CoordAngles.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4242100.0 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar11CoordAngles14pruneShortcutsERNS_8KeywordsE8
_ZN4PLMD11multicolvar11CoordAngles16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD11multicolvar11CoordAnglesC1ERKNS_13ActionOptionsE2
_ZN4PLMD11multicolvar11CoordAnglesC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/CoordAngles.cpp.gcov.html b/coverage/multicolvar/CoordAngles.cpp.gcov.html new file mode 100644 index 000000000000..129b2c4b47c6 --- /dev/null +++ b/coverage/multicolvar/CoordAngles.cpp.gcov.html @@ -0,0 +1,185 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/CoordAngles.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - CoordAngles.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4242100.0 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2018 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionShortcut.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "MultiColvarShortcuts.h"
+      25             : 
+      26             : //+PLUMEDOC MCOLVAR COORD_ANGLES
+      27             : /*
+      28             : Calculate all the angles between bonds in the first coordination spheres of a set of atoms
+      29             : 
+      30             : \par Examples
+      31             : 
+      32             : 
+      33             : */
+      34             : //+ENDPLUMEDOC
+      35             : 
+      36             : namespace PLMD {
+      37             : namespace multicolvar {
+      38             : 
+      39             : class CoordAngles : public ActionShortcut {
+      40             : public:
+      41             :   static void registerKeywords(Keywords& keys);
+      42             :   static void pruneShortcuts(Keywords& keys);
+      43             :   explicit CoordAngles(const ActionOptions&);
+      44             : };
+      45             : 
+      46             : PLUMED_REGISTER_ACTION(CoordAngles,"COORD_ANGLES")
+      47             : 
+      48           6 : void CoordAngles::registerKeywords(Keywords& keys) {
+      49           6 :   ActionShortcut::registerKeywords( keys );
+      50          12 :   keys.add("atoms","CATOMS","all the angles between the bonds that radiate out from these central atom are computed");
+      51          12 :   keys.add("atoms","GROUP","a list of angls between pairs of bonds connecting one of the atoms specified using the CATOM command and two of the atoms specified here are computed");
+      52          12 :   keys.add("compulsory","SWITCH","the switching function specifies that only those bonds that have a length that is less than a certain threshold are considered");
+      53           6 :   MultiColvarShortcuts::shortcutKeywords( keys ); pruneShortcuts( keys );
+      54          18 :   keys.needsAction("DISTANCE"); keys.needsAction("COMBINE"); keys.needsAction("CUSTOM");
+      55          12 :   keys.needsAction("VSTACK"); keys.needsAction("TRANSPOSE");
+      56          12 :   keys.needsAction("OUTER_PRODUCT"); keys.needsAction("MATRIX_PRODUCT");
+      57           6 : }
+      58             : 
+      59           8 : void CoordAngles::pruneShortcuts(Keywords& keys) {
+      60          40 :   keys.remove("ALT_MIN"); keys.remove("MIN"); keys.remove("MAX"); keys.remove("HIGHEST"); keys.remove("LOWEST");
+      61           8 : }
+      62             : 
+      63           2 : CoordAngles::CoordAngles(const ActionOptions& ao):
+      64             :   Action(ao),
+      65           2 :   ActionShortcut(ao)
+      66             : {
+      67             :   // Parse the central atoms
+      68           4 :   std::vector<std::string> catoms; parseVector("CATOMS",catoms); Tools::interpretRanges(catoms);
+      69             :   // Parse the coordination sphere
+      70           4 :   std::vector<std::string> group; parseVector("GROUP",group); Tools::interpretRanges(group);
+      71             :   // Create the list of atoms
+      72           2 :   std::string atlist; unsigned k=1;
+      73           4 :   for(unsigned i=0; i<catoms.size(); ++i) {
+      74         200 :     for(unsigned j=0; j<group.size(); ++j) { std::string num; Tools::convert( k, num ); atlist += " ATOMS" + num + "=" + catoms[i] + "," + group[j]; k++; }
+      75             :   }
+      76             :   // Calculate the distances
+      77           4 :   readInputLine( getShortcutLabel() + "_dd: DISTANCE" + atlist );
+      78             :   // Transform with the switching function
+      79           2 :   std::string switch_input; parse("SWITCH",switch_input);
+      80           4 :   readInputLine( getShortcutLabel() + "_sw: LESS_THAN ARG=" + getShortcutLabel() + "_dd SWITCH={" + switch_input +"}");
+      81             :   // Now get the normalised vectors
+      82           4 :   readInputLine( getShortcutLabel() + "_comp: DISTANCE" + atlist + " COMPONENTS");
+      83           4 :   readInputLine( getShortcutLabel() + "_norm2: COMBINE ARG=" + getShortcutLabel() + "_comp.x" + "," + getShortcutLabel() + "_comp.y," + getShortcutLabel() + "_comp.z POWERS=2,2,2 PERIODIC=NO");
+      84           4 :   readInputLine( getShortcutLabel() + "_norm: CUSTOM ARG=" + getShortcutLabel() + "_norm2 FUNC=sqrt(x) PERIODIC=NO");
+      85           4 :   readInputLine( getShortcutLabel() + "_norm_x: CUSTOM ARG=" + getShortcutLabel() + "_comp.x," + getShortcutLabel() + "_norm FUNC=x/y PERIODIC=NO");
+      86           4 :   readInputLine( getShortcutLabel() + "_norm_y: CUSTOM ARG=" + getShortcutLabel() + "_comp.y," + getShortcutLabel() + "_norm FUNC=x/y PERIODIC=NO");
+      87           4 :   readInputLine( getShortcutLabel() + "_norm_z: CUSTOM ARG=" + getShortcutLabel() + "_comp.z," + getShortcutLabel() + "_norm FUNC=x/y PERIODIC=NO");
+      88           4 :   readInputLine( getShortcutLabel() + "_stack: VSTACK ARG=" + getShortcutLabel() + "_norm_x" + "," + getShortcutLabel() + "_norm_y," + getShortcutLabel() + "_norm_z");
+      89           4 :   readInputLine( getShortcutLabel() + "_stackT: TRANSPOSE ARG=" + getShortcutLabel() + "_stack");
+      90             :   // Create the matrix of weights
+      91           4 :   readInputLine( getShortcutLabel() + "_swd: OUTER_PRODUCT ELEMENTS_ON_DIAGONAL_ARE_ZERO ARG=" + getShortcutLabel() + "_sw," + getShortcutLabel() + "_sw");
+      92             :   // Avoid double counting
+      93           4 :   readInputLine( getShortcutLabel() + "_wmat: CUSTOM ARG=" + getShortcutLabel() + "_swd FUNC=0.5*x PERIODIC=NO");
+      94             :   // And the matrix of dot products and the angles
+      95           4 :   readInputLine( getShortcutLabel() + "_dpmat: MATRIX_PRODUCT ARG=" + getShortcutLabel() + "_stack," + getShortcutLabel() + "_stackT");
+      96           4 :   readInputLine( getShortcutLabel() + "_angles: CUSTOM ARG=" + getShortcutLabel() + "_dpmat FUNC=acos(x) PERIODIC=NO");
+      97             :   // Read the input
+      98           4 :   Keywords keys; MultiColvarShortcuts::shortcutKeywords( keys ); pruneShortcuts( keys ); bool do_mean; parseFlag("MEAN",do_mean);
+      99           4 :   std::map<std::string,std::string> keymap; readShortcutKeywords( keys, keymap ); if( do_mean ) keymap.insert(std::pair<std::string,std::string>("SUM",""));
+     100           4 :   MultiColvarShortcuts::expandFunctions( getShortcutLabel(), getShortcutLabel() + "_angles", getShortcutLabel() + "_wmat", keymap, this );
+     101           2 :   if( do_mean ) {
+     102           4 :     readInputLine( getShortcutLabel() + "_denom: SUM ARG=" + getShortcutLabel() + "_wmat PERIODIC=NO");
+     103           4 :     readInputLine( getShortcutLabel() + "_mean: CUSTOM ARG=" + getShortcutLabel() + "_sum," + getShortcutLabel() + "_denom FUNC=x/y PERIODIC=NO");
+     104             :   }
+     105           4 : }
+     106             : 
+     107             : }
+     108             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/Dihcor.cpp.func-sort-c.html b/coverage/multicolvar/Dihcor.cpp.func-sort-c.html new file mode 100644 index 000000000000..8c2b005d6bcc --- /dev/null +++ b/coverage/multicolvar/Dihcor.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/Dihcor.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - Dihcor.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1111100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar6DihcorC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar6DihcorC1ERKNS_13ActionOptionsE1
_ZN4PLMD11multicolvar6Dihcor16registerKeywordsERNS_8KeywordsE5
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/Dihcor.cpp.func.html b/coverage/multicolvar/Dihcor.cpp.func.html new file mode 100644 index 000000000000..03919c8c9202 --- /dev/null +++ b/coverage/multicolvar/Dihcor.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/Dihcor.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - Dihcor.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1111100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar6Dihcor16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD11multicolvar6DihcorC1ERKNS_13ActionOptionsE1
_ZN4PLMD11multicolvar6DihcorC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/Dihcor.cpp.gcov.html b/coverage/multicolvar/Dihcor.cpp.gcov.html new file mode 100644 index 000000000000..b29d5a968ed8 --- /dev/null +++ b/coverage/multicolvar/Dihcor.cpp.gcov.html @@ -0,0 +1,183 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/Dihcor.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - Dihcor.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1111100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2020 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "MultiColvarShortcuts.h"
+      23             : #include "core/ActionRegister.h"
+      24             : 
+      25             : #include <string>
+      26             : #include <cmath>
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace multicolvar {
+      30             : 
+      31             : //+PLUMEDOC COLVAR DIHCOR
+      32             : /*
+      33             : Measures the degree of similarity between dihedral angles.
+      34             : 
+      35             : This colvar calculates the following quantity.
+      36             : 
+      37             : \f[
+      38             : s = \frac{1}{2} \sum_i \left[ 1 + \cos( \phi_i - \psi_i ) \right]
+      39             : \f]
+      40             : 
+      41             : where the \f$\phi_i\f$ and \f$\psi\f$ values and the instantaneous values for the \ref TORSION angles of interest.
+      42             : 
+      43             : \par Examples
+      44             : 
+      45             : The following provides an example input for the DIHCOR action
+      46             : 
+      47             : \plumedfile
+      48             : DIHCOR ...
+      49             :   ATOMS1=1,2,3,4,5,6,7,8
+      50             :   ATOMS2=5,6,7,8,9,10,11,12
+      51             :   LABEL=dih
+      52             : ... DIHCOR
+      53             : PRINT ARG=dih FILE=colvar STRIDE=10
+      54             : \endplumedfile
+      55             : 
+      56             : In the above input we are calculating the correlation between the torsion angle involving atoms 1, 2, 3 and 4 and the torsion angle
+      57             : 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
+      58             : correlation angle involving atoms 9, 10, 11 and 12.
+      59             : 
+      60             : 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
+      61             : can avoid this by using the \ref MOLINFO command.  PLUMED uses the pdb file that you provide to this command to learn
+      62             : about the topology of the protein molecule.  This means that you can specify torsion angles using the following syntax:
+      63             : 
+      64             : \plumedfile
+      65             : #SETTINGS MOLFILE=regtest/basic/rt32/helix.pdb
+      66             : MOLINFO MOLTYPE=protein STRUCTURE=myprotein.pdb
+      67             : dih: DIHCOR ...
+      68             : ATOMS1=@phi-3,@psi-3
+      69             : ATOMS2=@psi-3,@phi-4
+      70             : ATOMS3=@phi-4,@psi-4
+      71             : ...
+      72             : PRINT ARG=dih FILE=colvar STRIDE=10
+      73             : \endplumedfile
+      74             : 
+      75             : Here, \@phi-3 tells plumed that you would like to calculate the \f$\phi\f$ angle in the third residue of the protein.
+      76             : Similarly \@psi-4 tells plumed that you want to calculate the \f$\psi\f$ angle of the fourth residue of the protein.
+      77             : 
+      78             : */
+      79             : //+ENDPLUMEDOC
+      80             : 
+      81             : // We have a little helper class here to ensure that we actually do what is required by this action
+      82             : class Dihcor : public ActionShortcut {
+      83             : public:
+      84             :   static void registerKeywords( Keywords& keys );
+      85             :   Dihcor(const ActionOptions&);
+      86             : };
+      87             : 
+      88             : PLUMED_REGISTER_ACTION(Dihcor,"DIHCOR")
+      89             : 
+      90           5 : void Dihcor::registerKeywords( Keywords& keys ) {
+      91           5 :   ActionShortcut::registerKeywords( keys );
+      92          10 :   keys.needsAction("DIHEDRAL_CORRELATION"); keys.needsAction("SUM");
+      93          10 :   keys.add("atoms","ATOMS","the set of 8 atoms that are being used each of the dihedral correlation values");
+      94          10 :   keys.addFlag("NOPBC",false,"ignore the periodic boundary conditions when calculating distances");
+      95           5 : }
+      96             : 
+      97           1 : Dihcor::Dihcor(const ActionOptions&ao):
+      98             :   Action(ao),
+      99           1 :   ActionShortcut(ao)
+     100             : {
+     101           2 :   readInputLine( getShortcutLabel() +"_data: DIHEDRAL_CORRELATION " + convertInputLineToString() );
+     102           2 :   readInputLine( getShortcutLabel() + ": SUM ARG=" + getShortcutLabel() + "_data PERIODIC=NO");
+     103           1 : }
+     104             : 
+     105             : }
+     106             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/Distances.cpp.func-sort-c.html b/coverage/multicolvar/Distances.cpp.func-sort-c.html new file mode 100644 index 000000000000..c8dee9e4a253 --- /dev/null +++ b/coverage/multicolvar/Distances.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + 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:7474100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar9DistancesC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar9DistancesC1ERKNS_13ActionOptionsE56
_ZN4PLMD11multicolvar9Distances16registerKeywordsERNS_8KeywordsE113
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/Distances.cpp.func.html b/coverage/multicolvar/Distances.cpp.func.html new file mode 100644 index 000000000000..1d376930d81b --- /dev/null +++ b/coverage/multicolvar/Distances.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + 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:7474100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar9Distances16registerKeywordsERNS_8KeywordsE113
_ZN4PLMD11multicolvar9DistancesC1ERKNS_13ActionOptionsE56
_ZN4PLMD11multicolvar9DistancesC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/Distances.cpp.gcov.html b/coverage/multicolvar/Distances.cpp.gcov.html new file mode 100644 index 000000000000..3a7f1a19655c --- /dev/null +++ b/coverage/multicolvar/Distances.cpp.gcov.html @@ -0,0 +1,364 @@ + + + + + + + + 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:7474100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionShortcut.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "MultiColvarShortcuts.h"
+      25             : #include <string>
+      26             : #include <cmath>
+      27             : 
+      28             : //+PLUMEDOC MCOLVAR DISTANCES
+      29             : /*
+      30             : Calculate the distances between multiple piars of atoms
+      31             : 
+      32             : \par Examples
+      33             : 
+      34             : */
+      35             : //+ENDPLUMEDOC
+      36             : 
+      37             : //+PLUMEDOC MCOLVAR XDISTANCES
+      38             : /*
+      39             : Calculate the x components of the vectors connecting one or many pairs of atoms.
+      40             : You can then calculate functions of the distribution of values such as the minimum, the number less than a certain quantity and so on.
+      41             : 
+      42             : \par Examples
+      43             : 
+      44             : The following input tells plumed to calculate the x-component of the vector connecting atom 3 to atom 5 and
+      45             : the x-component of the vector connecting atom 1 to atom 2.  The minimum of these two quantities is then
+      46             : printed
+      47             : \plumedfile
+      48             : d1: XDISTANCES ATOMS1=3,5 ATOMS2=1,2 MIN={BETA=0.1}
+      49             : PRINT ARG=d1.min
+      50             : \endplumedfile
+      51             : (See also \ref PRINT).
+      52             : 
+      53             : 
+      54             : The following input tells plumed to calculate the x-component of the vector connecting atom 3 to atom 5 and
+      55             : the x-component of the vector connecting atom 1 to atom 2.  The number of values that are
+      56             : less than 0.1nm is then printed to a file.
+      57             : \plumedfile
+      58             : d1: XDISTANCES ATOMS1=3,5 ATOMS2=1,2 LESS_THAN={RATIONAL R_0=0.1}
+      59             : PRINT ARG=d1.lessthan
+      60             : \endplumedfile
+      61             : (See also \ref PRINT \ref switchingfunction).
+      62             : 
+      63             : The following input tells plumed to calculate the x-components of all the distinct vectors that can be created
+      64             : between atoms 1, 2 and 3 (i.e. the vectors between atoms 1 and 2, atoms 1 and 3 and atoms 2 and 3).
+      65             : The average of these quantities is then calculated.
+      66             : \plumedfile
+      67             : d1: XDISTANCES GROUP=1-3 MEAN
+      68             : PRINT ARG=d1.mean
+      69             : \endplumedfile
+      70             : (See also \ref PRINT)
+      71             : 
+      72             : The following input tells plumed to calculate all the vectors connecting the the atoms in GROUPA to the atoms in GROUPB.
+      73             : In other words the vector between atoms 1 and 2 and the vector between atoms 1 and 3.  The number of values
+      74             : more than 0.1 is then printed to a file.
+      75             : \plumedfile
+      76             : d1: XDISTANCES GROUPA=1 GROUPB=2,3 MORE_THAN={RATIONAL R_0=0.1}
+      77             : PRINT ARG=d1.morethan
+      78             : \endplumedfile
+      79             : (See also \ref PRINT \ref switchingfunction)
+      80             : */
+      81             : //+ENDPLUMEDOC
+      82             : 
+      83             : 
+      84             : //+PLUMEDOC MCOLVAR YDISTANCES
+      85             : /*
+      86             : Calculate the y components of the vectors connecting one or many pairs of atoms.
+      87             : You can then calculate functions of the distribution of values such as the minimum, the number less than a certain quantity and so on.
+      88             : 
+      89             : \par Examples
+      90             : 
+      91             : The following input tells plumed to calculate the y-component of the vector connecting atom 3 to atom 5 and
+      92             : the y-component of the vector connecting atom 1 to atom 2.  The minimum of these two quantities is then
+      93             : printed
+      94             : \plumedfile
+      95             : d1: YDISTANCES ATOMS1=3,5 ATOMS2=1,2 MIN={BETA=0.1}
+      96             : PRINT ARG=d1.min
+      97             : \endplumedfile
+      98             : (See also \ref PRINT).
+      99             : 
+     100             : 
+     101             : The following input tells plumed to calculate the y-component of the vector connecting atom 3 to atom 5 and
+     102             : the y-component of the vector connecting atom 1 to atom 2.  The number of values that are
+     103             : less than 0.1nm is then printed to a file.
+     104             : \plumedfile
+     105             : d1: YDISTANCES ATOMS1=3,5 ATOMS2=1,2 LESS_THAN={RATIONAL R_0=0.1}
+     106             : PRINT ARG=d1.lessthan
+     107             : \endplumedfile
+     108             : (See also \ref PRINT \ref switchingfunction).
+     109             : 
+     110             : The following input tells plumed to calculate the y-components of all the distinct vectors that can be created
+     111             : between atoms 1, 2 and 3 (i.e. the vectors between atoms 1 and 2, atoms 1 and 3 and atoms 2 and 3).
+     112             : The average of these quantities is then calculated.
+     113             : \plumedfile
+     114             : d1: YDISTANCES GROUP=1-3 MEAN
+     115             : PRINT ARG=d1.mean
+     116             : \endplumedfile
+     117             : (See also \ref PRINT)
+     118             : 
+     119             : The following input tells plumed to calculate all the vectors connecting the the atoms in GROUPA to the atoms in GROUPB.
+     120             : In other words the vector between atoms 1 and 2 and the vector between atoms 1 and 3.  The number of values
+     121             : more than 0.1 is then printed to a file.
+     122             : \plumedfile
+     123             : d1: YDISTANCES GROUPA=1 GROUPB=2,3 MORE_THAN={RATIONAL R_0=0.1}
+     124             : PRINT ARG=d1.morethan
+     125             : \endplumedfile
+     126             : (See also \ref PRINT \ref switchingfunction)
+     127             : 
+     128             : */
+     129             : //+ENDPLUMEDOC
+     130             : 
+     131             : //+PLUMEDOC MCOLVAR ZDISTANCES
+     132             : /*
+     133             : Calculate the z components of the vectors connecting one or many pairs of atoms.
+     134             : You can then calculate functions of the distribution of values such as the minimum, the number less than a certain quantity and so on.
+     135             : 
+     136             : \par Examples
+     137             : 
+     138             : The following input tells plumed to calculate the z-component of the vector connecting atom 3 to atom 5 and
+     139             : the z-component of the vector connecting atom 1 to atom 2.  The minimum of these two quantities is then
+     140             : printed
+     141             : \plumedfile
+     142             : d1: ZDISTANCES ATOMS1=3,5 ATOMS2=1,2 MIN={BETA=0.1}
+     143             : PRINT ARG=d1.min
+     144             : \endplumedfile
+     145             : (See also \ref PRINT).
+     146             : 
+     147             : 
+     148             : The following input tells plumed to calculate the z-component of the vector connecting atom 3 to atom 5 and
+     149             : the z-component of the vector connecting atom 1 to atom 2.  The number of values that are
+     150             : less than 0.1nm is then printed to a file.
+     151             : \plumedfile
+     152             : d1: ZDISTANCES ATOMS1=3,5 ATOMS2=1,2 LESS_THAN={RATIONAL R_0=0.1}
+     153             : PRINT ARG=d1.lessthan
+     154             : \endplumedfile
+     155             : (See also \ref PRINT \ref switchingfunction).
+     156             : 
+     157             : The following input tells plumed to calculate the z-components of all the distinct vectors that can be created
+     158             : between atoms 1, 2 and 3 (i.e. the vectors between atoms 1 and 2, atoms 1 and 3 and atoms 2 and 3).
+     159             : The average of these quantities is then calculated.
+     160             : \plumedfile
+     161             : d1: ZDISTANCES GROUP=1-3 MEAN
+     162             : PRINT ARG=d1.mean
+     163             : \endplumedfile
+     164             : (See also \ref PRINT)
+     165             : 
+     166             : The following input tells plumed to calculate all the vectors connecting the the atoms in GROUPA to the atoms in GROUPB.
+     167             : In other words the vector between atoms 1 and 2 and the vector between atoms 1 and 3.  The number of values
+     168             : more than 0.1 is then printed to a file.
+     169             : \plumedfile
+     170             : d1: ZDISTANCES GROUPA=1 GROUPB=2,3 MORE_THAN={RATIONAL R_0=0.1}
+     171             : PRINT ARG=d1.morethan
+     172             : \endplumedfile
+     173             : (See also \ref PRINT \ref switchingfunction)
+     174             : 
+     175             : */
+     176             : //+ENDPLUMEDOC
+     177             : 
+     178             : 
+     179             : namespace PLMD {
+     180             : namespace multicolvar {
+     181             : 
+     182             : class Distances : public ActionShortcut {
+     183             : public:
+     184             :   static void registerKeywords(Keywords& keys);
+     185             :   explicit Distances(const ActionOptions&);
+     186             : };
+     187             : 
+     188             : PLUMED_REGISTER_ACTION(Distances,"DISTANCES")
+     189             : PLUMED_REGISTER_ACTION(Distances,"XDISTANCES")
+     190             : PLUMED_REGISTER_ACTION(Distances,"YDISTANCES")
+     191             : PLUMED_REGISTER_ACTION(Distances,"ZDISTANCES")
+     192             : 
+     193         113 : void Distances::registerKeywords(Keywords& keys) {
+     194         113 :   ActionShortcut::registerKeywords( keys );
+     195         226 :   keys.add("atoms-1","GROUP","Calculate the distance between each distinct pair of atoms in the group");
+     196         226 :   keys.add("atoms-2","GROUPA","Calculate the distances between all the atoms in GROUPA and all "
+     197             :            "the atoms in GROUPB. This must be used in conjunction with GROUPB.");
+     198         226 :   keys.add("atoms-2","GROUPB","Calculate the distances between all the atoms in GROUPA and all the atoms "
+     199             :            "in GROUPB. This must be used in conjunction with GROUPA.");
+     200         226 :   keys.add("numbered","ATOMS","the pairs of atoms that you would like to calculate the angles for");
+     201         226 :   keys.addFlag("NOPBC",false,"ignore the periodic boundary conditions when calculating distances");
+     202         226 :   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");
+     203         226 :   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");
+     204         226 :   keys.addFlag("LOWMEM",false,"this flag does nothing and is present only to ensure back-compatibility");
+     205         226 :   keys.reset_style("ATOMS","atoms"); MultiColvarShortcuts::shortcutKeywords( keys );
+     206         226 :   keys.add("atoms","ORIGIN","calculate the distance of all the atoms specified using the ATOMS keyword from this point");
+     207         226 :   keys.add("numbered","LOCATION","the location at which the CV is assumed to be in space");
+     208         226 :   keys.reset_style("LOCATION","atoms");
+     209         226 :   keys.addOutputComponent("x","COMPONENTS","the x-components of the distance vectors");
+     210         226 :   keys.addOutputComponent("y","COMPONENTS","the y-components of the distance vectors");
+     211         226 :   keys.addOutputComponent("z","COMPONENTS","the z-components of the distance vectors");
+     212         339 :   keys.needsAction("GROUP"); keys.needsAction("DISTANCE"); keys.needsAction("CENTER");
+     213         113 : }
+     214             : 
+     215          56 : Distances::Distances(const ActionOptions& ao):
+     216             :   Action(ao),
+     217          56 :   ActionShortcut(ao)
+     218             : {
+     219             :   // Create distances
+     220          56 :   bool lowmem; parseFlag("LOWMEM",lowmem);
+     221          56 :   if( lowmem ) warning("LOWMEM flag is deprecated and is no longer required for this action");
+     222          56 :   std::string dline = getShortcutLabel() + ": DISTANCE";
+     223         112 :   bool nopbc; parseFlag("NOPBC",nopbc); if( nopbc ) dline += " NOPBC";
+     224          56 :   if( getName()=="DISTANCES" ) {
+     225         106 :     bool comp; parseFlag("COMPONENTS",comp); if( comp ) dline += " COMPONENTS";
+     226         106 :     bool scomp; parseFlag("SCALED_COMPONENTS",scomp); if( scomp ) dline += " SCALED_COMPONENTS";
+     227             :   } else dline += " COMPONENTS";
+     228             :   // Parse origin
+     229         112 :   std::string num, ostr; parse("ORIGIN",ostr);
+     230          56 :   if( ostr.length()>0 ) {
+     231             :     // Parse atoms
+     232          22 :     std::vector<std::string> afstr; MultiColvarShortcuts::parseAtomList("ATOMS",afstr,this);
+     233       11933 :     for(unsigned i=0; i<afstr.size(); ++i) { Tools::convert( i+1, num ); dline += " ATOMS" + num + "=" + ostr + "," + afstr[i]; }
+     234          22 :   } else {
+     235          68 :     std::vector<std::string> grp; MultiColvarShortcuts::parseAtomList("GROUP",grp,this);
+     236          68 :     std::vector<std::string> grpa; MultiColvarShortcuts::parseAtomList("GROUPA",grpa,this);
+     237          34 :     if( grp.size()>0 ) {
+     238           3 :       if( grpa.size()>0 ) error("should not be using GROUPA in tandem with GROUP");
+     239             :       unsigned n=0;
+     240         203 :       for(unsigned i=1; i<grp.size(); ++i) {
+     241       10103 :         for(unsigned j=0; j<i; ++j) {
+     242        9903 :           std::string num; Tools::convert( n+1, num ); n++;
+     243       19806 :           dline += " ATOMS" + num + "=" + grp[i] + "," + grp[j];
+     244             :         }
+     245             :       }
+     246          31 :     } else if( grpa.size()>0 ) {
+     247           2 :       std::vector<std::string> grpb; MultiColvarShortcuts::parseAtomList("GROUPB",grpb,this);
+     248           1 :       if( grpb.size()==0 ) error("found GROUPA but no corresponding GROUPB");
+     249           1 :       std::string grpstr = getShortcutLabel() + "_grp: GROUP ATOMS=";
+     250           4 :       for(unsigned i=0; i<grpa.size(); ++i) {
+     251         294 :         for(unsigned j=0; j<grpb.size(); ++j) {
+     252         291 :           std::string num; Tools::convert( i*grpb.size() + j + 1, num );
+     253         582 :           dline += " ATOMS" + num + "=" + grpa[i] + "," + grpb[j];
+     254         582 :           readInputLine( getShortcutLabel() + "_vatom" + num + ": CENTER ATOMS=" + grpa[i] + "," + grpb[j] );
+     255         582 :           if( i+j==0 ) grpstr += getShortcutLabel() + "_vatom" + num; else grpstr += "," + getShortcutLabel() + "_vatom" + num;
+     256             :         }
+     257             :       }
+     258           1 :       readInputLine( grpstr );
+     259           1 :     } else {
+     260          30 :       std::string grpstr = getShortcutLabel() + "_grp: GROUP ATOMS=";
+     261          30 :       for(unsigned i=1;; ++i) {
+     262        1836 :         std::string atstring; parseNumbered("ATOMS",i,atstring);
+     263         918 :         if( atstring.length()==0 ) break;
+     264        1776 :         std::string locstr; parseNumbered("LOCATION",i,locstr);
+     265         888 :         if( locstr.length()==0 ) {
+     266         278 :           std::string num; Tools::convert( i, num );
+     267         556 :           readInputLine( getShortcutLabel() + "_vatom" + num + ": CENTER ATOMS=" + atstring );
+     268         556 :           if( i==1 ) grpstr += getShortcutLabel() + "_vatom" + num; else grpstr += "," + getShortcutLabel() + "_vatom" + num;
+     269             :         } else {
+     270        1216 :           if( i==1 ) grpstr += locstr; else grpstr += "," + locstr;
+     271             :         }
+     272         888 :         std::string num; Tools::convert( i, num );
+     273        1776 :         dline += " ATOMS" + num + "=" + atstring;
+     274         888 :       }
+     275          30 :       readInputLine( grpstr );
+     276             :     }
+     277          34 :   }
+     278          56 :   readInputLine( dline );
+     279             :   // Add shortcuts to label
+     280         109 :   if( getName()=="DISTANCES" ) MultiColvarShortcuts::expandFunctions( getShortcutLabel(), getShortcutLabel(), "", this );
+     281           4 :   else if( getName()=="XDISTANCES" ) MultiColvarShortcuts::expandFunctions( getShortcutLabel(), getShortcutLabel() + ".x", "", this );
+     282           3 :   else if( getName()=="YDISTANCES" ) MultiColvarShortcuts::expandFunctions( getShortcutLabel(), getShortcutLabel() + ".y", "", this );
+     283           2 :   else if( getName()=="ZDISTANCES" ) MultiColvarShortcuts::expandFunctions( getShortcutLabel(), getShortcutLabel() + ".z", "", this );
+     284          56 : }
+     285             : 
+     286             : }
+     287             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/DumpMultiColvar.cpp.func-sort-c.html b/coverage/multicolvar/DumpMultiColvar.cpp.func-sort-c.html new file mode 100644 index 000000000000..2a57ab89b71f --- /dev/null +++ b/coverage/multicolvar/DumpMultiColvar.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + 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:61250.0 %
Date:2024-04-19 12:12:35Functions:1333.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar15DumpMultiColvarC1ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar15DumpMultiColvarC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar15DumpMultiColvar16registerKeywordsERNS_8KeywordsE2
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/DumpMultiColvar.cpp.func.html b/coverage/multicolvar/DumpMultiColvar.cpp.func.html new file mode 100644 index 000000000000..803f4fe4c775 --- /dev/null +++ b/coverage/multicolvar/DumpMultiColvar.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + 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:61250.0 %
Date:2024-04-19 12:12:35Functions:1333.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar15DumpMultiColvar16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD11multicolvar15DumpMultiColvarC1ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar15DumpMultiColvarC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/DumpMultiColvar.cpp.gcov.html b/coverage/multicolvar/DumpMultiColvar.cpp.gcov.html new file mode 100644 index 000000000000..45e7f1749e9e --- /dev/null +++ b/coverage/multicolvar/DumpMultiColvar.cpp.gcov.html @@ -0,0 +1,142 @@ + + + + + + + + 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:61250.0 %
Date:2024-04-19 12:12:35Functions:1333.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 "core/ActionShortcut.h"
+      23             : #include "core/ActionRegister.h"
+      24             : 
+      25             : //+PLUMEDOC MCOLVAR DUMPMULTICOLVAR
+      26             : /*
+      27             : Basically equivalent to DUMPATOMS
+      28             : 
+      29             : This action has been depracated
+      30             : 
+      31             : \par Examples
+      32             : 
+      33             : 
+      34             : */
+      35             : //+ENDPLUMEDOC
+      36             : 
+      37             : namespace PLMD {
+      38             : namespace multicolvar {
+      39             : 
+      40             : class DumpMultiColvar : public ActionShortcut {
+      41             : public:
+      42             :   static void registerKeywords(Keywords& keys);
+      43             :   explicit DumpMultiColvar(const ActionOptions&);
+      44             : };
+      45             : 
+      46             : PLUMED_REGISTER_ACTION(DumpMultiColvar,"DUMPMULTICOLVAR")
+      47             : 
+      48           2 : void DumpMultiColvar::registerKeywords(Keywords& keys) {
+      49           2 :   ActionShortcut::registerKeywords( keys );
+      50           4 :   keys.add("compulsory","DATA","the vector you wish to transform");
+      51           4 :   keys.add("compulsory","FILE","the file that you would like to output the data to");
+      52           2 :   keys.needsAction("DUMPATOMS");
+      53           2 : }
+      54             : 
+      55           0 : DumpMultiColvar::DumpMultiColvar(const ActionOptions& ao):
+      56             :   Action(ao),
+      57           0 :   ActionShortcut(ao)
+      58             : {
+      59           0 :   warning("This action has been depracated.  Look at the log to see how the same result is achieved with the new syntax");
+      60           0 :   std::string dd; parse("DATA",dd);
+      61           0 :   readInputLine("DUMPATOMS ATOMS=" + dd + "_grp ARG=" + dd + " " + convertInputLineToString() );
+      62           0 : }
+      63             : 
+      64             : }
+      65             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/InPlaneDistances.cpp.func-sort-c.html b/coverage/multicolvar/InPlaneDistances.cpp.func-sort-c.html new file mode 100644 index 000000000000..aed4349bb022 --- /dev/null +++ b/coverage/multicolvar/InPlaneDistances.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + 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:2424100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar16InPlaneDistancesC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar16InPlaneDistancesC1ERKNS_13ActionOptionsE1
_ZN4PLMD11multicolvar16InPlaneDistances16registerKeywordsERNS_8KeywordsE3
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/InPlaneDistances.cpp.func.html b/coverage/multicolvar/InPlaneDistances.cpp.func.html new file mode 100644 index 000000000000..5586ceec35d8 --- /dev/null +++ b/coverage/multicolvar/InPlaneDistances.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + 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:2424100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar16InPlaneDistances16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD11multicolvar16InPlaneDistancesC1ERKNS_13ActionOptionsE1
_ZN4PLMD11multicolvar16InPlaneDistancesC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/InPlaneDistances.cpp.gcov.html b/coverage/multicolvar/InPlaneDistances.cpp.gcov.html new file mode 100644 index 000000000000..30722ec4281a --- /dev/null +++ b/coverage/multicolvar/InPlaneDistances.cpp.gcov.html @@ -0,0 +1,158 @@ + + + + + + + + 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:2424100.0 %
Date:2024-04-19 12:12:35Functions:2366.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/ActionShortcut.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "MultiColvarShortcuts.h"
+      25             : 
+      26             : #include <string>
+      27             : #include <cmath>
+      28             : 
+      29             : //+PLUMEDOC MCOLVAR INPLANEDISTANCES
+      30             : /*
+      31             : Calculate the distance between a pair of atoms in the plane
+      32             : 
+      33             : \par Examples
+      34             : 
+      35             : */
+      36             : //+ENDPLUMEDOC
+      37             : 
+      38             : namespace PLMD {
+      39             : namespace multicolvar {
+      40             : 
+      41             : class InPlaneDistances : public ActionShortcut {
+      42             : public:
+      43             :   explicit InPlaneDistances(const ActionOptions&);
+      44             :   static void registerKeywords( Keywords& keys );
+      45             : };
+      46             : 
+      47             : PLUMED_REGISTER_ACTION(InPlaneDistances,"INPLANEDISTANCES")
+      48             : 
+      49           3 : void InPlaneDistances::registerKeywords( Keywords& keys ) {
+      50           3 :   ActionShortcut::registerKeywords( keys );
+      51           6 :   keys.add("atoms","GROUP","calculate distance for each distinct set of three atoms in the group");
+      52           6 :   keys.add("atoms","VECTORSTART","The first atom position that is used to define the normal to the plane of interest");
+      53           6 :   keys.add("atoms","VECTOREND","The second atom position that is used to defin the normal to the plane of interest");
+      54           3 :   MultiColvarShortcuts::shortcutKeywords( keys );
+      55           6 :   keys.needsAction("DISTANCE"); keys.needsAction("ANGLE");
+      56           3 : }
+      57             : 
+      58           1 : InPlaneDistances::InPlaneDistances(const ActionOptions&ao):
+      59             :   Action(ao),
+      60           1 :   ActionShortcut(ao)
+      61             : {
+      62           2 :   std::vector<std::string> str_atomsA; parseVector("VECTORSTART",str_atomsA); Tools::interpretRanges( str_atomsA );
+      63           2 :   std::vector<std::string> str_atomsB; parseVector("VECTOREND",str_atomsB); Tools::interpretRanges( str_atomsB );
+      64           2 :   std::vector<std::string> str_atomsC; parseVector("GROUP",str_atomsC); Tools::interpretRanges( str_atomsC );
+      65           1 :   unsigned n=1; std::string dinput= getShortcutLabel() + "_dis: DISTANCE", ainput = getShortcutLabel() + "_ang: ANGLE";
+      66           2 :   for(unsigned i=0; i<str_atomsA.size(); ++i ) {
+      67           2 :     for(unsigned j=0; j<str_atomsB.size(); ++j ) {
+      68           9 :       for(unsigned k=0; k<str_atomsC.size(); ++k) {
+      69           8 :         std::string str_n; Tools::convert( n, str_n ); n++;
+      70          16 :         dinput += " ATOMS" + str_n + "=" + str_atomsA[j] + "," + str_atomsC[k];
+      71          16 :         ainput += " ATOMS" + str_n + "=" + str_atomsB[j] + "," + str_atomsA[i] + "," + str_atomsC[k];
+      72             :       }
+      73             :     }
+      74             :   }
+      75           1 :   readInputLine( dinput ); readInputLine( ainput );
+      76           2 :   readInputLine( getShortcutLabel() + ": CUSTOM PERIODIC=NO FUNC=x*sin(y) ARG=" + getShortcutLabel() + "_dis," + getShortcutLabel() + "_ang");
+      77           2 :   MultiColvarShortcuts::expandFunctions( getShortcutLabel(), getShortcutLabel(), "", this );
+      78           1 : }
+      79             : 
+      80             : }
+      81             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/MFilterLess.cpp.func-sort-c.html b/coverage/multicolvar/MFilterLess.cpp.func-sort-c.html new file mode 100644 index 000000000000..5868c76c8187 --- /dev/null +++ b/coverage/multicolvar/MFilterLess.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/MFilterLess.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - MFilterLess.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:61442.9 %
Date:2024-04-19 12:12:35Functions:1333.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar11MFilterLessC1ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar11MFilterLessC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar11MFilterLess16registerKeywordsERNS_8KeywordsE2
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/MFilterLess.cpp.func.html b/coverage/multicolvar/MFilterLess.cpp.func.html new file mode 100644 index 000000000000..0ba70db8d3b4 --- /dev/null +++ b/coverage/multicolvar/MFilterLess.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/MFilterLess.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - MFilterLess.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:61442.9 %
Date:2024-04-19 12:12:35Functions:1333.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar11MFilterLess16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD11multicolvar11MFilterLessC1ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar11MFilterLessC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/MFilterLess.cpp.gcov.html b/coverage/multicolvar/MFilterLess.cpp.gcov.html new file mode 100644 index 000000000000..107de58c3fb0 --- /dev/null +++ b/coverage/multicolvar/MFilterLess.cpp.gcov.html @@ -0,0 +1,144 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/MFilterLess.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - MFilterLess.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:61442.9 %
Date:2024-04-19 12:12:35Functions:1333.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 "core/ActionShortcut.h"
+      23             : #include "core/ActionRegister.h"
+      24             : 
+      25             : //+PLUMEDOC MCOLVAR MFILTER_LESS
+      26             : /*
+      27             : Basically equivalent to LESS_THAN.
+      28             : 
+      29             : This action has been depracated
+      30             : 
+      31             : \par Examples
+      32             : 
+      33             : 
+      34             : */
+      35             : //+ENDPLUMEDOC
+      36             : 
+      37             : namespace PLMD {
+      38             : namespace multicolvar {
+      39             : 
+      40             : class MFilterLess : public ActionShortcut {
+      41             : public:
+      42             :   static void registerKeywords(Keywords& keys);
+      43             :   explicit MFilterLess(const ActionOptions&);
+      44             : };
+      45             : 
+      46             : PLUMED_REGISTER_ACTION(MFilterLess,"MFILTER_LESS")
+      47             : 
+      48           2 : void MFilterLess::registerKeywords(Keywords& keys) {
+      49           2 :   ActionShortcut::registerKeywords( keys );
+      50           4 :   keys.add("compulsory","DATA","the vector you wish to transform");
+      51           4 :   keys.add("compulsory","SWITCH","the switching function that transform");
+      52           4 :   keys.needsAction("GROUP"); keys.needsAction("LESS_THAN");
+      53           2 : }
+      54             : 
+      55           0 : MFilterLess::MFilterLess(const ActionOptions& ao):
+      56             :   Action(ao),
+      57           0 :   ActionShortcut(ao)
+      58             : {
+      59           0 :   warning("This action has been depracated.  Look at the log to see how the same result is achieved with the new syntax");
+      60           0 :   std::string dd; parse("DATA",dd);
+      61           0 :   std::string swit; parse("SWITCH",swit);
+      62           0 :   readInputLine( getShortcutLabel() + "_grp: GROUP ATOMS=" + dd + "_grp");
+      63           0 :   readInputLine( getShortcutLabel() + ": LESS_THAN ARG=" + dd + " SWITCH={" + swit + "}");
+      64           0 : }
+      65             : 
+      66             : }
+      67             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/MFilterMore.cpp.func-sort-c.html b/coverage/multicolvar/MFilterMore.cpp.func-sort-c.html new file mode 100644 index 000000000000..36ba0b83093b --- /dev/null +++ b/coverage/multicolvar/MFilterMore.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/MFilterMore.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - MFilterMore.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:102441.7 %
Date:2024-04-19 12:12:35Functions:1333.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar11MFilterMoreC1ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar11MFilterMoreC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar11MFilterMore16registerKeywordsERNS_8KeywordsE2
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/MFilterMore.cpp.func.html b/coverage/multicolvar/MFilterMore.cpp.func.html new file mode 100644 index 000000000000..93cb788412bf --- /dev/null +++ b/coverage/multicolvar/MFilterMore.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/MFilterMore.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - MFilterMore.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:102441.7 %
Date:2024-04-19 12:12:35Functions:1333.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar11MFilterMore16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD11multicolvar11MFilterMoreC1ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar11MFilterMoreC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/MFilterMore.cpp.gcov.html b/coverage/multicolvar/MFilterMore.cpp.gcov.html new file mode 100644 index 000000000000..fe6e71816017 --- /dev/null +++ b/coverage/multicolvar/MFilterMore.cpp.gcov.html @@ -0,0 +1,155 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/MFilterMore.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - MFilterMore.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:102441.7 %
Date:2024-04-19 12:12:35Functions:1333.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 "core/ActionShortcut.h"
+      23             : #include "core/ActionRegister.h"
+      24             : 
+      25             : //+PLUMEDOC MCOLVAR MFILTER_MORE
+      26             : /*
+      27             : Basically equivalent to MORE_THAN.
+      28             : 
+      29             : This action has been depracated
+      30             : 
+      31             : \par Examples
+      32             : 
+      33             : 
+      34             : */
+      35             : //+ENDPLUMEDOC
+      36             : 
+      37             : namespace PLMD {
+      38             : namespace multicolvar {
+      39             : 
+      40             : class MFilterMore : public ActionShortcut {
+      41             : public:
+      42             :   static void registerKeywords(Keywords& keys);
+      43             :   explicit MFilterMore(const ActionOptions&);
+      44             : };
+      45             : 
+      46             : PLUMED_REGISTER_ACTION(MFilterMore,"MFILTER_MORE")
+      47             : 
+      48           2 : void MFilterMore::registerKeywords(Keywords& keys) {
+      49           2 :   ActionShortcut::registerKeywords( keys );
+      50           4 :   keys.add("compulsory","DATA","the vector you wish to transform");
+      51           4 :   keys.add("compulsory","SWITCH","the switching function that transform");
+      52           4 :   keys.addFlag("LOWMEM",false,"this flag does nothing and is present only to ensure back-compatibility");
+      53           4 :   keys.addFlag("HIGHEST",false,"this flag allows you to recover the highest of these variables.");
+      54           4 :   keys.addOutputComponent("highest","HIGHEST","the largest of the colvars");
+      55           4 :   keys.needsAction("CUSTOM"); keys.needsAction("GROUP");
+      56           4 :   keys.needsAction("MORE_THAN"); keys.needsAction("HIGHEST");
+      57           2 : }
+      58             : 
+      59           0 : MFilterMore::MFilterMore(const ActionOptions& ao):
+      60             :   Action(ao),
+      61           0 :   ActionShortcut(ao)
+      62             : {
+      63           0 :   warning("This action has been depracated.  Look at the log to see how the same result is achieved with the new syntax");
+      64           0 :   bool lowmem; parseFlag("LOWMEM",lowmem);
+      65           0 :   if( lowmem ) warning("LOWMEM flag is deprecated and is no longer required for this action");
+      66           0 :   std::string dd; parse("DATA",dd);
+      67           0 :   std::string swit; parse("SWITCH",swit);
+      68           0 :   readInputLine( getShortcutLabel() + "_grp: GROUP ATOMS=" + dd + "_grp");
+      69           0 :   readInputLine( getShortcutLabel() + ": MORE_THAN ARG=" + dd + " SWITCH={" + swit + "}");
+      70           0 :   bool highest; parseFlag("HIGHEST",highest);
+      71           0 :   if( highest ) {
+      72           0 :     readInputLine( getShortcutLabel() + "_filtered: CUSTOM ARG=" + dd + "," + getShortcutLabel() + " FUNC=x*y PERIODIC=NO");
+      73           0 :     readInputLine( getShortcutLabel() + "_highest: HIGHEST ARG=" + getShortcutLabel() + "_filtered");
+      74             :   }
+      75           0 : }
+      76             : 
+      77             : }
+      78             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/MultiColvarShortcuts.cpp.func-sort-c.html b/coverage/multicolvar/MultiColvarShortcuts.cpp.func-sort-c.html new file mode 100644 index 000000000000..da41134f20e4 --- /dev/null +++ b/coverage/multicolvar/MultiColvarShortcuts.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/MultiColvarShortcuts.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - MultiColvarShortcuts.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:14516190.1 %
Date:2024-04-19 12:12:35Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar20MultiColvarShortcuts13parseAtomListERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIS7_SaIS7_EEPNS_14ActionShortcutE91
_ZN4PLMD11multicolvar20MultiColvarShortcuts15expandFunctionsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_S9_PNS_14ActionShortcutE122
_ZN4PLMD11multicolvar20MultiColvarShortcuts20readShortcutKeywordsERSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_St4lessIS8_ESaISt4pairIKS8_S8_EEEPNS_14ActionShortcutE227
_ZN4PLMD11multicolvar20MultiColvarShortcuts15expandFunctionsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_S9_RKSt3mapIS7_S7_St4lessIS7_ESaISt4pairIS8_S7_EEEPNS_14ActionShortcutE236
_ZN4PLMD11multicolvar20MultiColvarShortcuts16shortcutKeywordsERNS_8KeywordsE709
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/MultiColvarShortcuts.cpp.func.html b/coverage/multicolvar/MultiColvarShortcuts.cpp.func.html new file mode 100644 index 000000000000..9ed8a7e34874 --- /dev/null +++ b/coverage/multicolvar/MultiColvarShortcuts.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/MultiColvarShortcuts.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - MultiColvarShortcuts.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:14516190.1 %
Date:2024-04-19 12:12:35Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar20MultiColvarShortcuts13parseAtomListERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIS7_SaIS7_EEPNS_14ActionShortcutE91
_ZN4PLMD11multicolvar20MultiColvarShortcuts15expandFunctionsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_S9_PNS_14ActionShortcutE122
_ZN4PLMD11multicolvar20MultiColvarShortcuts15expandFunctionsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_S9_RKSt3mapIS7_S7_St4lessIS7_ESaISt4pairIS8_S7_EEEPNS_14ActionShortcutE236
_ZN4PLMD11multicolvar20MultiColvarShortcuts16shortcutKeywordsERNS_8KeywordsE709
_ZN4PLMD11multicolvar20MultiColvarShortcuts20readShortcutKeywordsERSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_St4lessIS8_ESaISt4pairIKS8_S8_EEEPNS_14ActionShortcutE227
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/MultiColvarShortcuts.cpp.gcov.html b/coverage/multicolvar/MultiColvarShortcuts.cpp.gcov.html new file mode 100644 index 000000000000..2cb6d75c80b8 --- /dev/null +++ b/coverage/multicolvar/MultiColvarShortcuts.cpp.gcov.html @@ -0,0 +1,328 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/MultiColvarShortcuts.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - MultiColvarShortcuts.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:14516190.1 %
Date:2024-04-19 12:12:35Functions: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 "MultiColvarShortcuts.h"
+      23             : #include "core/PlumedMain.h"
+      24             : #include "core/ActionSet.h"
+      25             : #include "core/Group.h"
+      26             : 
+      27             : namespace PLMD {
+      28             : namespace multicolvar {
+      29             : 
+      30         709 : void MultiColvarShortcuts::shortcutKeywords( Keywords& keys ) {
+      31        1418 :   keys.add("numbered","LESS_THAN","calculate the number of variables that are less than a certain target value. "
+      32             :            "This quantity is calculated using \\f$\\sum_i \\sigma(s_i)\\f$, where \\f$\\sigma(s)\\f$ "
+      33             :            "is a \\ref switchingfunction.");
+      34        1418 :   keys.addOutputComponent("lessthan","LESS_THAN","the number of colvars that have a value less than a threshold");
+      35        1418 :   keys.add("numbered","MORE_THAN","calculate the number of variables that are more than a certain target value. "
+      36             :            "This quantity is calculated using \\f$\\sum_i 1 - \\sigma(s_i)\\f$, where \\f$\\sigma(s)\\f$ "
+      37             :            "is a \\ref switchingfunction.");
+      38        1418 :   keys.addOutputComponent("morethan","MORE_THAN","the number of colvars that have a value more than a threshold");
+      39        1418 :   keys.add("optional","ALT_MIN","calculate the minimum value. "
+      40             :            "To make this quantity continuous the minimum is calculated using "
+      41             :            "\\f$ \\textrm{min} = -\\frac{1}{\\beta} \\log \\sum_i \\exp\\left( -\\beta s_i \\right)  \\f$ "
+      42             :            "The value of \\f$\\beta\\f$ in this function is specified using (BETA=\\f$\\beta\\f$).");
+      43        1418 :   keys.addOutputComponent("altmin","ALT_MIN","the minimum value of the cv");
+      44        1418 :   keys.add("optional","MIN","calculate the minimum value. "
+      45             :            "To make this quantity continuous the minimum is calculated using "
+      46             :            "\\f$ \\textrm{min} = \\frac{\\beta}{ \\log \\sum_i \\exp\\left( \\frac{\\beta}{s_i} \\right) } \\f$ "
+      47             :            "The value of \\f$\\beta\\f$ in this function is specified using (BETA=\\f$\\beta\\f$)");
+      48        1418 :   keys.addOutputComponent("min","MIN","the minimum colvar");
+      49        1418 :   keys.add("optional","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        1418 :   keys.addOutputComponent("max","MAX","the maximum colvar");
+      54        1418 :   keys.add("numbered","BETWEEN","calculate the number of values that are within a certain range. "
+      55             :            "These quantities are calculated using kernel density estimation as described on "
+      56             :            "\\ref histogrambead.");
+      57        1418 :   keys.addOutputComponent("between","BETWEEN","the number of colvars that have a value that lies in a particular interval");
+      58        1418 :   keys.addFlag("HIGHEST",false,"this flag allows you to recover the highest of these variables.");
+      59        1418 :   keys.addOutputComponent("highest","HIGHEST","the largest of the colvars");
+      60        1418 :   keys.add("optional","HISTOGRAM","calculate a discretized histogram of the distribution of values. "
+      61             :            "This shortcut allows you to calculates NBIN quantites like BETWEEN.");
+      62        1418 :   keys.addFlag("LOWEST",false,"this flag allows you to recover the lowest of these variables.");
+      63        1418 :   keys.addOutputComponent("lowest","LOWEST","the smallest of the colvars");
+      64        1418 :   keys.addFlag("SUM",false,"calculate the sum of all the quantities.");
+      65        1418 :   keys.addOutputComponent("sum","SUM","the sum of the colvars");
+      66        1418 :   keys.addFlag("MEAN",false,"calculate the mean of all the quantities.");
+      67        1418 :   keys.addOutputComponent("mean","MEAN","the mean of the colvars");
+      68        3545 :   keys.needsAction("SUM"); keys.needsAction("MEAN"); keys.needsAction("CUSTOM"); keys.needsAction("HIGHEST"); keys.needsAction("LOWEST");
+      69        2127 :   keys.needsAction("LESS_THAN"); keys.needsAction("MORE_THAN"); keys.needsAction("BETWEEN");
+      70         709 : }
+      71             : 
+      72         122 : void MultiColvarShortcuts::expandFunctions( const std::string& labout, const std::string& argin, const std::string& weights, ActionShortcut* action ) {
+      73         122 :   std::map<std::string,std::string> keymap; readShortcutKeywords( keymap, action ); expandFunctions( labout, argin, weights, keymap, action );
+      74         122 : }
+      75             : 
+      76         227 : void MultiColvarShortcuts::readShortcutKeywords( std::map<std::string,std::string>& keymap, ActionShortcut* action ) {
+      77         227 :   Keywords keys; shortcutKeywords( keys ); action->readShortcutKeywords( keys, keymap );
+      78         227 : }
+      79             : 
+      80          91 : void MultiColvarShortcuts::parseAtomList( const std::string& key, std::vector<std::string>& atoms, ActionShortcut* action ) {
+      81          91 :   std::vector<std::string> astr; action->parseVector(key,astr); if( astr.size()==0 ) return ;
+      82          27 :   Tools::interpretRanges( astr );
+      83        1263 :   for(unsigned i=0; i<astr.size(); ++i) {
+      84        1236 :     Group* mygr=action->plumed.getActionSet().selectWithLabel<Group*>(astr[i]);
+      85        1236 :     if( mygr ) {
+      86           1 :       std::vector<std::string> grstr( mygr->getGroupAtoms() );
+      87         101 :       for(unsigned j=0; j<grstr.size(); ++j) atoms.push_back(grstr[j]);
+      88           1 :     } else {
+      89        1235 :       Group* mygr2=action->plumed.getActionSet().selectWithLabel<Group*>(astr[i] + "_grp");
+      90        1235 :       if( mygr2 ) {
+      91           9 :         std::vector<std::string> grstr( mygr2->getGroupAtoms() );
+      92       10897 :         for(unsigned j=0; j<grstr.size(); ++j) atoms.push_back(grstr[j]);
+      93        1235 :       } else atoms.push_back(astr[i]);
+      94             :     }
+      95             :   }
+      96          91 : }
+      97             : 
+      98         236 : void MultiColvarShortcuts::expandFunctions( const std::string& labout, const std::string& argin, const std::string& weights,
+      99             :     const std::map<std::string,std::string>& keymap, ActionShortcut* action ) {
+     100         236 :   if( keymap.empty() ) return;
+     101             :   // Parse LESS_THAN
+     102         292 :   if( keymap.count("LESS_THAN") ) {
+     103          16 :     std::string sum_arg = labout + "_lt", lt_string = keymap.find("LESS_THAN")->second;
+     104          16 :     action->readInputLine( labout + "_lt: LESS_THAN ARG=" + argin + " SWITCH={" + lt_string + "}");
+     105           8 :     if( weights.length()>0 ) {
+     106           1 :       sum_arg = labout + "_wlt";
+     107           2 :       action->readInputLine( labout + "_wlt: CUSTOM ARG=" + weights + "," + labout + "_lt FUNC=x*y PERIODIC=NO");
+     108             :     }
+     109          16 :     action->readInputLine( labout + "_lessthan: SUM ARG=" + sum_arg + " PERIODIC=NO");
+     110             :   }
+     111         292 :   if( keymap.count("LESS_THAN1") ) {
+     112           1 :     for(unsigned i=1;; ++i) {
+     113           3 :       std::string istr; Tools::convert( i, istr );
+     114           6 :       if( !keymap.count("LESS_THAN" + istr ) ) { break; }
+     115           6 :       std::string sum_arg = labout + "_lt" + istr, lt_string1 = keymap.find("LESS_THAN" + istr)->second;
+     116           4 :       action->readInputLine( labout + "_lt" + istr + ": LESS_THAN ARG=" + argin + " SWITCH={" + lt_string1 + "}");
+     117           2 :       if( weights.length()>0 ) {
+     118           0 :         sum_arg = labout + "_wlt" + istr;
+     119           0 :         action->readInputLine( labout + "_wlt" + istr + ": CUSTOM ARG=" + weights + "," + labout + "_lt" + istr + " FUNC=x*y PERIODIC=NO");
+     120             :       }
+     121           4 :       action->readInputLine( labout + "_lessthan-" + istr + ": SUM ARG=" + sum_arg + " PERIODIC=NO");
+     122           2 :     }
+     123             :   }
+     124             :   // Parse MORE_THAN
+     125         292 :   if( keymap.count("MORE_THAN") ) {
+     126          48 :     std::string sum_arg=labout + "_mt", mt_string = keymap.find("MORE_THAN")->second;
+     127          48 :     action->readInputLine( labout + "_mt: MORE_THAN ARG=" + argin + " SWITCH={" + mt_string + "}");
+     128          24 :     if( weights.length()>0 ) {
+     129           1 :       sum_arg = labout + "_wmt";
+     130           2 :       action->readInputLine( labout + "_wmt: CUSTOM ARG=" + weights + "," + labout + "_mt FUNC=x*y PERIODIC=NO" );
+     131             :     }
+     132          48 :     action->readInputLine( labout + "_morethan: SUM ARG=" + sum_arg + " PERIODIC=NO");
+     133             :   }
+     134         292 :   if(  keymap.count("MORE_THAN1") ) {
+     135           0 :     for(unsigned i=1;; ++i) {
+     136           0 :       std::string istr; Tools::convert( i, istr );
+     137           0 :       if( !keymap.count("MORE_THAN" + istr ) ) { break; }
+     138           0 :       std::string sum_arg = labout + "_mt" + istr, mt_string1 = keymap.find("MORE_THAN" + istr)->second;
+     139           0 :       action->readInputLine( labout + "_mt" + istr + ": MORE_THAN ARG=" + argin + " SWITCH={" + mt_string1 + "}");
+     140           0 :       if( weights.length()>0 ) {
+     141           0 :         sum_arg = labout + "_wmt" + istr;
+     142           0 :         action->readInputLine( labout + "_wmt" + istr + ": CUSTOM ARG=" + weights + "," + labout + "_lt" + istr + " FUNC=x*y PERIODIC=NO");
+     143             :       }
+     144           0 :       action->readInputLine( labout + "_morethan-" + istr + ": SUM ARG=" + sum_arg + " PERIODIC=NO");
+     145           0 :     }
+     146             :   }
+     147             :   // Parse ALT_MIN
+     148         292 :   if( keymap.count("ALT_MIN") ) {
+     149           1 :     if( weights.length()>0 ) plumed_merror("cannot use ALT_MIN with this shortcut");
+     150           2 :     std::string amin_string = keymap.find("ALT_MIN")->second;
+     151           1 :     std::size_t dd = amin_string.find("BETA"); std::string beta_str = amin_string.substr(dd+5);
+     152           1 :     beta_str.erase(std::remove_if(beta_str.begin(), beta_str.end(), ::isspace), beta_str.end());
+     153           2 :     action->readInputLine( labout + "_me_altmin: CUSTOM ARG=" + argin + " FUNC=exp(-x*" + beta_str + ") PERIODIC=NO");
+     154           2 :     action->readInputLine( labout + "_mec_altmin: SUM ARG=" + labout + "_me_altmin PERIODIC=NO");
+     155           2 :     action->readInputLine( labout + "_altmin: CUSTOM ARG=" + labout + "_mec_altmin FUNC=-log(x)/" + beta_str + " PERIODIC=NO");
+     156             :   }
+     157             :   // Parse MIN
+     158         292 :   if( keymap.count("MIN") ) {
+     159           1 :     if( weights.length()>0 ) plumed_merror("cannot use MIN with this shortcut");
+     160           2 :     std::string min_string = keymap.find("MIN")->second;
+     161           1 :     std::size_t dd = min_string.find("BETA"); std::string beta_str = min_string.substr(dd+5);
+     162           1 :     beta_str.erase(std::remove_if(beta_str.begin(), beta_str.end(), ::isspace), beta_str.end());
+     163           2 :     action->readInputLine( labout + "_me_min: CUSTOM ARG=" + argin + " FUNC=exp(" + beta_str + "/x) PERIODIC=NO");
+     164           2 :     action->readInputLine( labout + "_mec_min: SUM ARG=" + labout + "_me_min PERIODIC=NO");
+     165           2 :     action->readInputLine( labout + "_min: CUSTOM ARG=" + labout + "_mec_min FUNC=" + beta_str + "/log(x) PERIODIC=NO");
+     166             :   }
+     167             :   // Parse MAX
+     168         292 :   if( keymap.count("MAX") ) {
+     169           3 :     if( weights.length()>0 ) plumed_merror("cannot use MAX with this shortcut");
+     170           6 :     std::string max_string = keymap.find("MAX")->second;
+     171           3 :     std::size_t dd = max_string.find("BETA"); std::string beta_str = max_string.substr(dd+5);
+     172           3 :     beta_str.erase(std::remove_if(beta_str.begin(), beta_str.end(), ::isspace), beta_str.end());
+     173           6 :     action->readInputLine( labout + "_me_max: CUSTOM ARG=" + argin + " FUNC=exp(x/" + beta_str + ") PERIODIC=NO");
+     174           6 :     action->readInputLine( labout + "_mec_max: SUM ARG=" + labout + "_me_max PERIODIC=NO");
+     175           6 :     action->readInputLine( labout + "_max: CUSTOM ARG=" + labout + "_mec_max FUNC=" + beta_str  + "*log(x) PERIODIC=NO");
+     176             :   }
+     177             :   // Parse HIGHEST
+     178         292 :   if( keymap.count("HIGHEST") ) {
+     179           8 :     if( weights.length()>0 ) plumed_merror("cannot use HIGHEST with this shortcut");
+     180          16 :     action->readInputLine( labout + "_highest: HIGHEST ARG=" + argin );
+     181             :   }
+     182             :   // Parse LOWEST
+     183         292 :   if( keymap.count("LOWEST") ) {
+     184           2 :     if( weights.length()>0 ) plumed_merror("cannot use LOWEST with this shortcut");
+     185           4 :     action->readInputLine( labout + "_lowest: LOWEST ARG=" + argin );
+     186             :   }
+     187             :   // Parse SUM
+     188         292 :   if( keymap.count("SUM") ) {
+     189          44 :     std::string sum_arg=argin;
+     190          44 :     if( weights.length()>0 ) {
+     191          22 :       sum_arg = labout + "_wsum";
+     192          44 :       action->readInputLine( labout + "_wsum: CUSTOM ARG=" + weights + "," + argin + " FUNC=x*y PERIODIC=NO");
+     193             :     }
+     194          88 :     action->readInputLine( labout + "_sum: SUM ARG=" + sum_arg + " PERIODIC=NO");
+     195             :   }
+     196             :   // Parse MEAN
+     197         292 :   if( keymap.count("MEAN") ) {
+     198          63 :     if( weights.length()>0 ) plumed_merror("cannot use MEAN with this shortcut");
+     199         126 :     action->readInputLine( labout + "_mean: MEAN ARG=" + argin + " PERIODIC=NO");
+     200             :   }
+     201             :   // Parse BETWEEN
+     202         292 :   if( keymap.count("BETWEEN") ) {
+     203          16 :     std::string sum_arg=labout + "_bt", bt_string = keymap.find("BETWEEN")->second;
+     204          16 :     action->readInputLine( labout + "_bt: BETWEEN ARG=" + argin + " SWITCH={" + bt_string + "}" );
+     205           8 :     if( weights.length()>0 ) {
+     206           0 :       sum_arg = labout + "_wbt";
+     207           0 :       action->readInputLine( labout + "_wbt: CUSTOM ARG=" + weights + "," + labout + "_bt FUNC=x*y PERIODIC=NO");
+     208             :     }
+     209          16 :     action->readInputLine( labout + "_between: SUM ARG=" + sum_arg + " PERIODIC=NO");
+     210             :   }
+     211             :   std::string bt_string1;
+     212         292 :   if( keymap.count("BETWEEN1") ) {
+     213           6 :     for(unsigned i=1;; ++i) {
+     214          17 :       std::string istr; Tools::convert( i, istr );
+     215          34 :       if( !keymap.count("BETWEEN" + istr) ) break;
+     216          33 :       std::string sum_arg=labout + "_bt" + istr, bt_string1 = keymap.find("BETWEEN" + istr)->second;
+     217          22 :       action->readInputLine( labout + "_bt" + istr + ": BETWEEN ARG=" + argin + " SWITCH={" + bt_string1 + "}" );
+     218          11 :       if( weights.length()>0 ) {
+     219           2 :         sum_arg = labout + "_wbt" + istr;
+     220           2 :         action->readInputLine( labout + "_wbt" + istr + ": CUSTOM ARG=" + weights + "," + labout + "_bt" + istr + " FUNC=x*y PERIODIC=NO");
+     221             :       }
+     222          22 :       action->readInputLine( labout + "_between-" + istr + ": SUM ARG=" + sum_arg + " PERIODIC=NO");
+     223          11 :     }
+     224             :   }
+     225             :   // Parse HISTOGRAM
+     226         292 :   if( keymap.count("HISTOGRAM") ) {
+     227          24 :     std::vector<std::string> words=Tools::getWords( keymap.find("HISTOGRAM")->second );
+     228          12 :     unsigned nbins; bool found=Tools::parse(words,"NBINS",nbins,0); // Need replica index
+     229          12 :     if( !found ) plumed_merror("did not find NBINS in specification for HISTOGRAM");
+     230          12 :     double lower; found=Tools::parse(words,"LOWER",lower,0);
+     231          12 :     if( !found ) plumed_merror("did not find LOWER in specification for HISTOGRAM");
+     232          12 :     double upper; found=Tools::parse(words,"UPPER",upper,0);
+     233          12 :     if( !found ) plumed_merror("did not find UPPER in specification for HISTOGRAM");
+     234          12 :     double delr = ( upper - lower ) / static_cast<double>( nbins );
+     235          12 :     double smear=0.5; found=Tools::parse(words,"SMEAR",smear,0);
+     236          12 :     if( !found ) smear = 0.5;
+     237          41 :     for(unsigned i=0; i<nbins; ++i) {
+     238          58 :       std::string smstr, istr; Tools::convert( i+1, istr ); Tools::convert( smear, smstr ); std::string sum_arg=labout + "_bt" + istr;
+     239          29 :       std::string low_str, high_str; Tools::convert( lower + i*delr, low_str ); Tools::convert( lower + (i+1)*delr, high_str );
+     240          58 :       action->readInputLine( labout + "_bt" + istr + ": BETWEEN ARG=" + argin + " SWITCH={" + words[0] + " LOWER=" + low_str + " UPPER=" + high_str + " SMEAR=" + smstr + "}");
+     241          29 :       if( weights.length()>0 ) {
+     242           0 :         sum_arg = labout + "_wbt" + istr;
+     243           0 :         action->readInputLine( labout + "_wbt" + istr + ": CUSTOM ARG=" + weights + "," + labout + "_bt" + istr + " FUNC=x*y PERIODIC=NO");
+     244             :       }
+     245          58 :       action->readInputLine( labout + "_between-" + istr + ": SUM ARG=" + sum_arg + " PERIODIC=NO");
+     246             :     }
+     247          12 :   }
+     248             : }
+     249             : 
+     250             : }
+     251             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/Planes.cpp.func-sort-c.html b/coverage/multicolvar/Planes.cpp.func-sort-c.html new file mode 100644 index 000000000000..15dcd5db43d5 --- /dev/null +++ b/coverage/multicolvar/Planes.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/Planes.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - Planes.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:404588.9 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar13PlaneShortcutC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar13PlaneShortcut21createVectorNormInputERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_S9_1
_ZN4PLMD11multicolvar13PlaneShortcutC1ERKNS_13ActionOptionsE1
_ZN4PLMD11multicolvar13PlaneShortcut16registerKeywordsERNS_8KeywordsE3
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/Planes.cpp.func.html b/coverage/multicolvar/Planes.cpp.func.html new file mode 100644 index 000000000000..103d5ec0fcc8 --- /dev/null +++ b/coverage/multicolvar/Planes.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/Planes.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - Planes.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:404588.9 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar13PlaneShortcut16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD11multicolvar13PlaneShortcut21createVectorNormInputERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_S9_1
_ZN4PLMD11multicolvar13PlaneShortcutC1ERKNS_13ActionOptionsE1
_ZN4PLMD11multicolvar13PlaneShortcutC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/Planes.cpp.gcov.html b/coverage/multicolvar/Planes.cpp.gcov.html new file mode 100644 index 000000000000..08aac79e059f --- /dev/null +++ b/coverage/multicolvar/Planes.cpp.gcov.html @@ -0,0 +1,189 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/Planes.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - Planes.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:404588.9 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2017 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "MultiColvarShortcuts.h"
+      23             : #include "core/ActionShortcut.h"
+      24             : #include "core/ActionRegister.h"
+      25             : #include "tools/Pbc.h"
+      26             : 
+      27             : #include <string>
+      28             : #include <cmath>
+      29             : 
+      30             : //+PLUMEDOC MCOLVAR PLANES
+      31             : /*
+      32             : Calculate the components of the normal to the plane containing three atoms
+      33             : 
+      34             : \par Examples
+      35             : 
+      36             : */
+      37             : //+ENDPLUMEDOC
+      38             : 
+      39             : namespace PLMD {
+      40             : namespace multicolvar {
+      41             : 
+      42             : class PlaneShortcut : public ActionShortcut {
+      43             : private:
+      44             :   void createVectorNormInput( const std::string& ilab, const std::string& olab, const std::string& vlab );
+      45             : public:
+      46             :   static void registerKeywords( Keywords& keys );
+      47             :   PlaneShortcut(const ActionOptions&);
+      48             : };
+      49             : 
+      50             : PLUMED_REGISTER_ACTION(PlaneShortcut,"PLANES")
+      51             : 
+      52           3 : void PlaneShortcut::registerKeywords( Keywords& keys ) {
+      53           3 :   ActionShortcut::registerKeywords( keys );
+      54           3 :   MultiColvarShortcuts::shortcutKeywords( keys );
+      55           6 :   keys.add("numbered","ATOMS","the sets of atoms that you would like to calculate the planes for");
+      56           6 :   keys.add("numbered","LOCATION","the location at which the CV is assumed to be in space");
+      57           6 :   keys.reset_style("LOCATION","atoms");
+      58           6 :   keys.addFlag("VMEAN",false,"calculate the norm of the mean vector.");
+      59           6 :   keys.addOutputComponent("_vmean","VMEAN","the norm of the mean vector");
+      60           6 :   keys.addFlag("VSUM",false,"calculate the norm of the sum of all the vectors");
+      61           6 :   keys.addOutputComponent("_vsum","VSUM","the norm of the mean vector");
+      62           9 :   keys.needsAction("CENTER"); keys.needsAction("GROUP"); keys.needsAction("PLANE");
+      63          12 :   keys.needsAction("MEAN"); keys.needsAction("SUM"); keys.needsAction("COMBINE"); keys.needsAction("CUSTOM");
+      64           3 : }
+      65             : 
+      66           1 : PlaneShortcut::PlaneShortcut(const ActionOptions&ao):
+      67             :   Action(ao),
+      68           1 :   ActionShortcut(ao)
+      69             : {
+      70           3 :   bool vmean, vsum; parseFlag("VMEAN",vmean); parseFlag("VSUM",vsum); std::string dline;
+      71           1 :   std::string grpstr = getShortcutLabel() + "_grp: GROUP ATOMS=";
+      72           1 :   for(unsigned i=1;; ++i) {
+      73          18 :     std::string atstring; parseNumbered("ATOMS",i,atstring);
+      74           9 :     if( atstring.length()==0 ) break;
+      75          16 :     std::string locstr; parseNumbered("LOCATION",i,locstr);
+      76           8 :     if( locstr.length()==0 ) {
+      77           8 :       std::string num; Tools::convert( i, num );
+      78          16 :       readInputLine( getShortcutLabel() + "_vatom" + num + ": CENTER ATOMS=" + atstring );
+      79          16 :       if( i==1 ) grpstr += getShortcutLabel() + "_vatom" + num; else grpstr += "," + getShortcutLabel() + "_vatom" + num;
+      80             :     } else {
+      81           0 :       if( i==1 ) grpstr += locstr; else grpstr += "," + locstr;
+      82             :     }
+      83           8 :     std::string num; Tools::convert( i, num );
+      84          16 :     dline += " ATOMS" + num + "=" + atstring;
+      85           8 :   }
+      86           2 :   readInputLine( grpstr ); readInputLine( getShortcutLabel() + ": PLANE " + dline + " " + convertInputLineToString() );
+      87           1 :   if( vmean ) {
+      88           2 :     readInputLine( getShortcutLabel() + "_xs: MEAN ARG=" + getShortcutLabel() + ".x PERIODIC=NO");
+      89           2 :     readInputLine( getShortcutLabel() + "_ys: MEAN ARG=" + getShortcutLabel() + ".y PERIODIC=NO");
+      90           2 :     readInputLine( getShortcutLabel() + "_zs: MEAN ARG=" + getShortcutLabel() + ".z PERIODIC=NO");
+      91             :     // Now calculate the total length of the vector
+      92           2 :     createVectorNormInput( getShortcutLabel(), getShortcutLabel() + "_vmean", "s" );
+      93             :   }
+      94           1 :   if( vsum ) {
+      95           0 :     readInputLine( getShortcutLabel() + "_xz: SUM ARG=" + getShortcutLabel() + ".x PERIODIC=NO");
+      96           0 :     readInputLine( getShortcutLabel() + "_yz: SUM ARG=" + getShortcutLabel() + ".y PERIODIC=NO");
+      97           0 :     readInputLine( getShortcutLabel() + "_zz: SUM ARG=" + getShortcutLabel() + ".z PERIODIC=NO");
+      98             :     // Now calculate the total length of the vector
+      99           0 :     createVectorNormInput( getShortcutLabel(), getShortcutLabel() + "_vsum", "z" );
+     100             :   }
+     101           1 : }
+     102             : 
+     103           1 : void PlaneShortcut::createVectorNormInput( const std::string& ilab, const std::string& olab, const std::string& vlab ) {
+     104           2 :   readInputLine( olab + "2: COMBINE ARG=" + ilab + "_x" + vlab + "," + ilab + "_y" + vlab + "," + ilab + "_z" + vlab + " POWERS=2,2,2 PERIODIC=NO");
+     105           2 :   readInputLine( olab + ": CUSTOM ARG=" + olab + "2 FUNC=sqrt(x) PERIODIC=NO");
+     106           1 : }
+     107             : 
+     108             : }
+     109             : }
+     110             : 
+     111             : 
+     112             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/Torsions.cpp.func-sort-c.html b/coverage/multicolvar/Torsions.cpp.func-sort-c.html new file mode 100644 index 000000000000..582e97630564 --- /dev/null +++ b/coverage/multicolvar/Torsions.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + 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:1111100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar8TorsionsC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar8TorsionsC1ERKNS_13ActionOptionsE6
_ZN4PLMD11multicolvar8Torsions16registerKeywordsERNS_8KeywordsE8
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/Torsions.cpp.func.html b/coverage/multicolvar/Torsions.cpp.func.html new file mode 100644 index 000000000000..e14791864231 --- /dev/null +++ b/coverage/multicolvar/Torsions.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + 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:1111100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar8Torsions16registerKeywordsERNS_8KeywordsE8
_ZN4PLMD11multicolvar8TorsionsC1ERKNS_13ActionOptionsE6
_ZN4PLMD11multicolvar8TorsionsC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/Torsions.cpp.gcov.html b/coverage/multicolvar/Torsions.cpp.gcov.html new file mode 100644 index 000000000000..2262aa18e183 --- /dev/null +++ b/coverage/multicolvar/Torsions.cpp.gcov.html @@ -0,0 +1,174 @@ + + + + + + + + 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:1111100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2014-2020 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionShortcut.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "MultiColvarShortcuts.h"
+      25             : 
+      26             : //+PLUMEDOC MCOLVAR TORSIONS
+      27             : /*
+      28             : Calculate whether or not a set of torsional angles are within a particular range.
+      29             : 
+      30             : \par Examples
+      31             : 
+      32             : The following provides an example of the input for the TORSIONS command
+      33             : 
+      34             : \plumedfile
+      35             : TORSIONS ...
+      36             : ATOMS1=168,170,172,188
+      37             : ATOMS2=170,172,188,190
+      38             : ATOMS3=188,190,192,230
+      39             : BETWEEN={GAUSSIAN LOWER=0 UPPER=pi SMEAR=0.1}
+      40             : LABEL=ab
+      41             : ... TORSIONS
+      42             : PRINT ARG=ab.* FILE=colvar STRIDE=10
+      43             : \endplumedfile
+      44             : 
+      45             : 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
+      46             : can avoid this by using the \ref MOLINFO command.  PLUMED uses the pdb file that you provide to this command to learn
+      47             : about the topology of the protein molecule.  This means that you can specify torsion angles using the following syntax:
+      48             : 
+      49             : \plumedfile
+      50             : #SETTINGS MOLFILE=regtest/basic/rt32/helix.pdb
+      51             : MOLINFO MOLTYPE=protein STRUCTURE=myprotein.pdb
+      52             : TORSIONS ...
+      53             : ATOMS1=@phi-3
+      54             : ATOMS2=@psi-3
+      55             : ATOMS3=@phi-4
+      56             : BETWEEN={GAUSSIAN LOWER=0 UPPER=pi SMEAR=0.1}
+      57             : LABEL=ab
+      58             : ... TORSIONS
+      59             : PRINT ARG=ab.* FILE=colvar STRIDE=10
+      60             : \endplumedfile
+      61             : 
+      62             : Here, \@phi-3 tells plumed that you would like to calculate the \f$\phi\f$ angle in the third residue of the protein.
+      63             : Similarly \@psi-4 tells plumed that you want to calculate the \f$\psi\f$ angle of the fourth residue of the protein.
+      64             : 
+      65             : 
+      66             : */
+      67             : //+ENDPLUMEDOC
+      68             : 
+      69             : namespace PLMD {
+      70             : namespace multicolvar {
+      71             : 
+      72             : class Torsions : public ActionShortcut {
+      73             : public:
+      74             :   static void registerKeywords(Keywords& keys);
+      75             :   explicit Torsions(const ActionOptions&);
+      76             : };
+      77             : 
+      78             : PLUMED_REGISTER_ACTION(Torsions,"TORSIONS")
+      79             : 
+      80           8 : void Torsions::registerKeywords(Keywords& keys) {
+      81           8 :   ActionShortcut::registerKeywords( keys ); MultiColvarShortcuts::shortcutKeywords( keys );
+      82           8 :   keys.needsAction("TORSION");
+      83           8 : }
+      84             : 
+      85           6 : Torsions::Torsions(const ActionOptions& ao):
+      86             :   Action(ao),
+      87           6 :   ActionShortcut(ao)
+      88             : {
+      89           6 :   log.printf("Action TORSION\n");
+      90           6 :   log.printf("  with label %s \n", getShortcutLabel().c_str() );
+      91          12 :   readInputLine( getShortcutLabel() + ": TORSION " + convertInputLineToString() );
+      92             :   // Add shortcuts to label
+      93           6 :   MultiColvarShortcuts::expandFunctions( getShortcutLabel(), getShortcutLabel(), "", this );
+      94           6 : }
+      95             : 
+      96             : }
+      97             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/UWalls.cpp.func-sort-c.html b/coverage/multicolvar/UWalls.cpp.func-sort-c.html new file mode 100644 index 000000000000..6e442834e7c6 --- /dev/null +++ b/coverage/multicolvar/UWalls.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/UWalls.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - UWalls.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:152075.0 %
Date:2024-04-19 12:12:35Functions:1333.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar6UWallsC1ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar6UWallsC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar6UWalls16registerKeywordsERNS_8KeywordsE2
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/UWalls.cpp.func.html b/coverage/multicolvar/UWalls.cpp.func.html new file mode 100644 index 000000000000..fceb42648226 --- /dev/null +++ b/coverage/multicolvar/UWalls.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/UWalls.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - UWalls.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:152075.0 %
Date:2024-04-19 12:12:35Functions:1333.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar6UWalls16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD11multicolvar6UWallsC1ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar6UWallsC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/UWalls.cpp.gcov.html b/coverage/multicolvar/UWalls.cpp.gcov.html new file mode 100644 index 000000000000..7db2d23ebc6c --- /dev/null +++ b/coverage/multicolvar/UWalls.cpp.gcov.html @@ -0,0 +1,151 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/UWalls.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - UWalls.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:152075.0 %
Date:2024-04-19 12:12:35Functions:1333.3 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2018 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionShortcut.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "MultiColvarShortcuts.h"
+      25             : 
+      26             : //+PLUMEDOC MCOLVAR UWALLS
+      27             : /*
+      28             : Add lower walls to a vector of quantities
+      29             : 
+      30             : Depracated action: use UPPER_WALLS
+      31             : 
+      32             : \par Examples
+      33             : 
+      34             : 
+      35             : */
+      36             : //+ENDPLUMEDOC
+      37             : 
+      38             : namespace PLMD {
+      39             : namespace multicolvar {
+      40             : 
+      41             : class UWalls : public ActionShortcut {
+      42             : public:
+      43             :   static void registerKeywords(Keywords& keys);
+      44             :   explicit UWalls(const ActionOptions&);
+      45             : };
+      46             : 
+      47             : PLUMED_REGISTER_ACTION(UWalls,"UWALLS")
+      48             : 
+      49           2 : void UWalls::registerKeywords(Keywords& keys) {
+      50           2 :   ActionShortcut::registerKeywords( keys );
+      51           4 :   keys.add("compulsory","DATA","the values you want to restrain");
+      52           4 :   keys.add("compulsory","AT","the radius of the sphere");
+      53           4 :   keys.add("compulsory","KAPPA","the force constant for the wall.  The k_i in the expression for a wall.");
+      54           4 :   keys.add("compulsory","OFFSET","0.0","the offset for the start of the wall.  The o_i in the expression for a wall.");
+      55           4 :   keys.add("compulsory","EXP","2.0","the powers for the walls.  The e_i in the expression for a wall.");
+      56           4 :   keys.add("compulsory","EPS","1.0","the values for s_i in the expression for a wall");
+      57           4 :   keys.add("atoms","CATOMS","all the angles between the bonds that radiate out from these central atom are computed");
+      58           4 :   keys.add("atoms","GROUP","a list of angls between pairs of bonds connecting one of the atoms specified using the CATOM command and two of the atoms specified here are computed");
+      59           4 :   keys.add("compulsory","SWITCH","the switching function specifies that only those bonds that have a length that is less than a certain threshold are considered");
+      60           4 :   keys.addOutputComponent("bias","default","the instantaneous value of the bias potential");
+      61           4 :   keys.addOutputComponent("force2","default","the instantaneous value of the squared force due to this bias potential");
+      62           2 :   keys.needsAction("UPPER_WALLS");
+      63           2 : }
+      64             : 
+      65           0 : UWalls::UWalls(const ActionOptions& ao):
+      66             :   Action(ao),
+      67           0 :   ActionShortcut(ao)
+      68             : {
+      69           0 :   std::string data; parse("DATA",data);
+      70           0 :   readInputLine( getShortcutLabel() + ": UPPER_WALLS ARG=" + data + " " + convertInputLineToString() );
+      71           0 : }
+      72             : 
+      73             : }
+      74             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/XAngle.cpp.func-sort-c.html b/coverage/multicolvar/XAngle.cpp.func-sort-c.html new file mode 100644 index 000000000000..110391c73250 --- /dev/null +++ b/coverage/multicolvar/XAngle.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + 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:2626100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar6XAngleC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar6XAngleC1ERKNS_13ActionOptionsE1
_ZN4PLMD11multicolvar6XAngle16registerKeywordsERNS_8KeywordsE9
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/XAngle.cpp.func.html b/coverage/multicolvar/XAngle.cpp.func.html new file mode 100644 index 000000000000..53a5debcb222 --- /dev/null +++ b/coverage/multicolvar/XAngle.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + 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:2626100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar6XAngle16registerKeywordsERNS_8KeywordsE9
_ZN4PLMD11multicolvar6XAngleC1ERKNS_13ActionOptionsE1
_ZN4PLMD11multicolvar6XAngleC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/XAngle.cpp.gcov.html b/coverage/multicolvar/XAngle.cpp.gcov.html new file mode 100644 index 000000000000..9f096b4b6513 --- /dev/null +++ b/coverage/multicolvar/XAngle.cpp.gcov.html @@ -0,0 +1,179 @@ + + + + + + + + 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:2626100.0 %
Date:2024-04-19 12:12:35Functions: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 "core/ActionShortcut.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "MultiColvarShortcuts.h"
+      25             : 
+      26             : //+PLUMEDOC COLVAR XANGLES
+      27             : /*
+      28             : Calculate the angle between an arbitrary vector and the positive x direction
+      29             : 
+      30             : \par Examples
+      31             : 
+      32             : */
+      33             : //+ENDPLUMEDOC
+      34             : 
+      35             : //+PLUMEDOC COLVAR YANGLES
+      36             : /*
+      37             : Calculate the angle between an arbitrary vector and the positive y direction
+      38             : 
+      39             : \par Examples
+      40             : 
+      41             : */
+      42             : //+ENDPLUMEDOC
+      43             : 
+      44             : //+PLUMEDOC COLVAR ZANGLES
+      45             : /*
+      46             : Calculate the angle between an arbitrary vector and the positive z direction
+      47             : 
+      48             : \par Examples
+      49             : 
+      50             : */
+      51             : //+ENDPLUMEDOC
+      52             : 
+      53             : 
+      54             : namespace PLMD {
+      55             : namespace multicolvar {
+      56             : 
+      57             : class XAngle : public ActionShortcut {
+      58             : public:
+      59             :   static void registerKeywords(Keywords& keys);
+      60             :   explicit XAngle(const ActionOptions&);
+      61             : };
+      62             : 
+      63             : PLUMED_REGISTER_ACTION(XAngle,"XANGLES")
+      64             : PLUMED_REGISTER_ACTION(XAngle,"YANGLES")
+      65             : PLUMED_REGISTER_ACTION(XAngle,"ZANGLES")
+      66             : 
+      67           9 : void XAngle::registerKeywords(Keywords& keys) {
+      68           9 :   ActionShortcut::registerKeywords( keys );
+      69          18 :   keys.add("numbered","ATOMS","the pairs of atoms that you would like to calculate the angles for");
+      70          18 :   keys.reset_style("ATOMS","atoms"); MultiColvarShortcuts::shortcutKeywords( keys );
+      71          27 :   keys.needsAction("DISTANCE"); keys.needsAction("COMBINE"); keys.needsAction("CUSTOM");
+      72           9 : }
+      73             : 
+      74           1 : XAngle::XAngle(const ActionOptions& ao):
+      75             :   Action(ao),
+      76           1 :   ActionShortcut(ao)
+      77             : {
+      78             :   // Create distances
+      79           1 :   std::string dline = getShortcutLabel() + ": DISTANCE COMPONENTS";
+      80           1 :   for(unsigned i=1;; ++i) {
+      81           6 :     std::string atstring; parseNumbered("ATOMS",i,atstring);
+      82           3 :     if( atstring.length()==0 ) break;
+      83           2 :     std::string num; Tools::convert( i, num );
+      84           4 :     dline += " ATOMS" + num + "=" + atstring;
+      85           2 :   }
+      86           1 :   readInputLine( dline );
+      87             :   // Normalize the vectors
+      88           2 :   readInputLine( getShortcutLabel() + "_norm2: COMBINE ARG=" + getShortcutLabel() + ".x" + "," + getShortcutLabel() + ".y," + getShortcutLabel() + ".z POWERS=2,2,2 PERIODIC=NO");
+      89           2 :   readInputLine( getShortcutLabel() + "_norm: CUSTOM ARG=" + getShortcutLabel() + "_norm2 FUNC=sqrt(x) PERIODIC=NO");
+      90           2 :   readInputLine( getShortcutLabel() + "_norm_x: CUSTOM ARG=" + getShortcutLabel() + ".x," + getShortcutLabel() + "_norm FUNC=x/y PERIODIC=NO");
+      91           2 :   readInputLine( getShortcutLabel() + "_norm_y: CUSTOM ARG=" + getShortcutLabel() + ".y," + getShortcutLabel() + "_norm FUNC=x/y PERIODIC=NO");
+      92           2 :   readInputLine( getShortcutLabel() + "_norm_z: CUSTOM ARG=" + getShortcutLabel() + ".z," + getShortcutLabel() + "_norm FUNC=x/y PERIODIC=NO");
+      93             :   // Now compute the angles with matheval
+      94           2 :   if( getName()=="XANGLES" ) readInputLine( getShortcutLabel() + "_ang: CUSTOM FUNC=acos(x) PERIODIC=NO ARG=" + getShortcutLabel() + "_norm_x");
+      95           1 :   if( getName()=="YANGLES" ) readInputLine( getShortcutLabel() + "_ang: CUSTOM FUNC=acos(x) PERIODIC=NO ARG=" + getShortcutLabel() + "_norm_y");
+      96           1 :   if( getName()=="ZANGLES" ) readInputLine( getShortcutLabel() + "_ang: CUSTOM FUNC=acos(x) PERIODIC=NO ARG=" + getShortcutLabel() + "_norm_z");
+      97             :   // Add shortcuts to label
+      98           2 :   MultiColvarShortcuts::expandFunctions( getShortcutLabel(), getShortcutLabel() + "_ang", "", this );
+      99           1 : }
+     100             : 
+     101             : }
+     102             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/XYTorsions.cpp.func-sort-c.html b/coverage/multicolvar/XYTorsions.cpp.func-sort-c.html new file mode 100644 index 000000000000..8d357bc5d0ee --- /dev/null +++ b/coverage/multicolvar/XYTorsions.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/XYTorsions.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - XYTorsions.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:293974.4 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar10XYTorsionsC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar10XYTorsionsC1ERKNS_13ActionOptionsE1
_ZN4PLMD11multicolvar10XYTorsions16registerKeywordsERNS_8KeywordsE15
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/XYTorsions.cpp.func.html b/coverage/multicolvar/XYTorsions.cpp.func.html new file mode 100644 index 000000000000..55d56a604195 --- /dev/null +++ b/coverage/multicolvar/XYTorsions.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/XYTorsions.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - XYTorsions.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:293974.4 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar10XYTorsions16registerKeywordsERNS_8KeywordsE15
_ZN4PLMD11multicolvar10XYTorsionsC1ERKNS_13ActionOptionsE1
_ZN4PLMD11multicolvar10XYTorsionsC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/XYTorsions.cpp.gcov.html b/coverage/multicolvar/XYTorsions.cpp.gcov.html new file mode 100644 index 000000000000..4eb2621e6736 --- /dev/null +++ b/coverage/multicolvar/XYTorsions.cpp.gcov.html @@ -0,0 +1,227 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/XYTorsions.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - XYTorsions.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:293974.4 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2018 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionShortcut.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "MultiColvarShortcuts.h"
+      25             : 
+      26             : //+PLUMEDOC COLVAR XYTORSIONS
+      27             : /*
+      28             : Calculate the torsional angle around the x axis between an arbitrary vector and the positive y direction
+      29             : 
+      30             : \par Examples
+      31             : 
+      32             : */
+      33             : //+ENDPLUMEDOC
+      34             : 
+      35             : //+PLUMEDOC COLVAR XZTORSIONS
+      36             : /*
+      37             : Calculate the torsional angle around the x axis between an arbitrary vector and the positive z direction
+      38             : 
+      39             : \par Examples
+      40             : 
+      41             : */
+      42             : //+ENDPLUMEDOC
+      43             : 
+      44             : //+PLUMEDOC COLVAR YXTORSIONS
+      45             : /*
+      46             : Calculate the torsional angle around the y axis between an arbitrary vector and the positive x direction
+      47             : 
+      48             : \par Examples
+      49             : 
+      50             : */
+      51             : //+ENDPLUMEDOC
+      52             : 
+      53             : //+PLUMEDOC COLVAR YZTORSIONS
+      54             : /*
+      55             : Calculate the torsional angle around the y axis between an arbitrary vector and the positive z direction
+      56             : 
+      57             : \par Examples
+      58             : 
+      59             : */
+      60             : //+ENDPLUMEDOC
+      61             : 
+      62             : //+PLUMEDOC COLVAR ZXTORSIONS
+      63             : /*
+      64             : Calculate the torsional angle around the z axis between an arbitrary vector and the positive x direction
+      65             : 
+      66             : \par Examples
+      67             : 
+      68             : */
+      69             : //+ENDPLUMEDOC
+      70             : 
+      71             : //+PLUMEDOC COLVAR ZYTORSIONS
+      72             : /*
+      73             : Calculate the torsional angle around the z axis between an arbitrary vector and the positive y direction
+      74             : 
+      75             : \par Examples
+      76             : 
+      77             : */
+      78             : //+ENDPLUMEDOC
+      79             : 
+      80             : namespace PLMD {
+      81             : namespace multicolvar {
+      82             : 
+      83             : class XYTorsions : public ActionShortcut {
+      84             : public:
+      85             :   static void registerKeywords(Keywords& keys);
+      86             :   explicit XYTorsions(const ActionOptions&);
+      87             : };
+      88             : 
+      89             : PLUMED_REGISTER_ACTION(XYTorsions,"XYTORSIONS")
+      90             : PLUMED_REGISTER_ACTION(XYTorsions,"XZTORSIONS")
+      91             : PLUMED_REGISTER_ACTION(XYTorsions,"YXTORSIONS")
+      92             : PLUMED_REGISTER_ACTION(XYTorsions,"YZTORSIONS")
+      93             : PLUMED_REGISTER_ACTION(XYTorsions,"ZXTORSIONS")
+      94             : PLUMED_REGISTER_ACTION(XYTorsions,"ZYTORSIONS")
+      95             : 
+      96          15 : void XYTorsions::registerKeywords(Keywords& keys) {
+      97          15 :   ActionShortcut::registerKeywords( keys );
+      98          30 :   keys.add("numbered","ATOMS","the pairs of atoms that you would like to calculate the angles for");
+      99          30 :   keys.reset_style("ATOMS","atoms"); MultiColvarShortcuts::shortcutKeywords( keys );
+     100          30 :   keys.needsAction("FIXEDATOM"); keys.needsAction("TORSION");
+     101          15 : }
+     102             : 
+     103           1 : XYTorsions::XYTorsions(const ActionOptions& ao):
+     104             :   Action(ao),
+     105           1 :   ActionShortcut(ao)
+     106             : {
+     107           2 :   std::string vdir = getShortcutLabel() + "_vec2," + getShortcutLabel() + "_origin";
+     108           2 :   std::string adir = getShortcutLabel() + "_axis," + getShortcutLabel() + "_origin";
+     109             :   // Create action for position of origin
+     110           2 :   readInputLine( getShortcutLabel() + "_origin: FIXEDATOM AT=0,0,0");
+     111           1 :   if( getName()=="XYTORSIONS" ) {
+     112           0 :     readInputLine( getShortcutLabel() + "_axis: FIXEDATOM AT=1,0,0");
+     113           0 :     readInputLine( getShortcutLabel() + "_vec2: FIXEDATOM AT=0,1,0");
+     114             :   }
+     115           1 :   if( getName()=="XZTORSIONS" ) {
+     116           0 :     readInputLine( getShortcutLabel() + "_axis: FIXEDATOM AT=1,0,0");
+     117           0 :     readInputLine( getShortcutLabel() + "_vec2: FIXEDATOM AT=0,0,1");
+     118             :   }
+     119           1 :   if( getName()=="YXTORSIONS" ) {
+     120           0 :     readInputLine( getShortcutLabel() + "_axis: FIXEDATOM AT=0,1,0");
+     121           0 :     readInputLine( getShortcutLabel() + "_vec2: FIXEDATOM AT=1,0,0");
+     122             :   }
+     123           1 :   if( getName()=="YZTORSIONS" ) {
+     124           0 :     readInputLine( getShortcutLabel() + "_axis: FIXEDATOM AT=0,1,0");
+     125           0 :     readInputLine( getShortcutLabel() + "_vec2: FIXEDATOM AT=0,0,1");
+     126             :   }
+     127           1 :   if( getName()=="ZXTORSIONS" ) {
+     128           0 :     readInputLine( getShortcutLabel() + "_axis: FIXEDATOM AT=0,0,1");
+     129           0 :     readInputLine( getShortcutLabel() + "_vec2: FIXEDATOM AT=1,0,0");
+     130             :   }
+     131           1 :   if( getName()=="ZYTORSIONS" ) {
+     132           1 :     readInputLine( getShortcutLabel() + "_axis: FIXEDATOM AT=0,0,1");
+     133           2 :     readInputLine( getShortcutLabel() + "_vec2: FIXEDATOM AT=0,1,0");
+     134             :   }
+     135             : 
+     136             :   // Now create action to compute all torsions
+     137           1 :   std::string torsions_str = getShortcutLabel() + ": TORSION";
+     138           1 :   for(unsigned i=1;; ++i) {
+     139           6 :     std::string atstring; parseNumbered("ATOMS",i,atstring);
+     140           3 :     if( atstring.length()==0 ) break;
+     141           2 :     std::string num; Tools::convert( i, num );
+     142           4 :     torsions_str += " VECTORA" + num + "=" + atstring + " VECTORB" + num + "=" + vdir + " AXIS" + num + "=" + adir;
+     143           2 :   }
+     144           1 :   readInputLine( torsions_str );
+     145             :   // Add shortcuts to label
+     146           2 :   MultiColvarShortcuts::expandFunctions( getShortcutLabel(), getShortcutLabel(), "", this );
+     147           1 : }
+     148             : 
+     149             : }
+     150             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/index-sort-f.html b/coverage/multicolvar/index-sort-f.html new file mode 100644 index 000000000000..1412bc6c9158 --- /dev/null +++ b/coverage/multicolvar/index-sort-f.html @@ -0,0 +1,234 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvarHitTotalCoverage
Test:plumed test coverageLines:50459185.3 %
Date:2024-04-19 12:12:35Functions:314963.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
MFilterLess.cpp +
42.9%42.9%
+
42.9 %6 / 1433.3 %1 / 3
DumpMultiColvar.cpp +
50.0%50.0%
+
50.0 %6 / 1233.3 %1 / 3
UWalls.cpp +
75.0%75.0%
+
75.0 %15 / 2033.3 %1 / 3
MFilterMore.cpp +
41.7%41.7%
+
41.7 %10 / 2433.3 %1 / 3
Torsions.cpp +
100.0%
+
100.0 %11 / 1166.7 %2 / 3
Distances.cpp +
100.0%
+
100.0 %74 / 7466.7 %2 / 3
InPlaneDistances.cpp +
100.0%
+
100.0 %24 / 2466.7 %2 / 3
AlphaBeta.cpp +
89.7%89.7%
+
89.7 %35 / 3966.7 %2 / 3
Dihcor.cpp +
100.0%
+
100.0 %11 / 1166.7 %2 / 3
XYTorsions.cpp +
74.4%74.4%
+
74.4 %29 / 3966.7 %2 / 3
Angles.cpp +
61.2%61.2%
+
61.2 %30 / 4966.7 %2 / 3
XAngle.cpp +
100.0%
+
100.0 %26 / 2666.7 %2 / 3
Planes.cpp +
88.9%88.9%
+
88.9 %40 / 4575.0 %3 / 4
CoordAngles.cpp +
100.0%
+
100.0 %42 / 4275.0 %3 / 4
MultiColvarShortcuts.cpp +
90.1%90.1%
+
90.1 %145 / 161100.0 %5 / 5
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/index-sort-l.html b/coverage/multicolvar/index-sort-l.html new file mode 100644 index 000000000000..23399dc5c025 --- /dev/null +++ b/coverage/multicolvar/index-sort-l.html @@ -0,0 +1,234 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvarHitTotalCoverage
Test:plumed test coverageLines:50459185.3 %
Date:2024-04-19 12:12:35Functions:314963.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
MFilterMore.cpp +
41.7%41.7%
+
41.7 %10 / 2433.3 %1 / 3
MFilterLess.cpp +
42.9%42.9%
+
42.9 %6 / 1433.3 %1 / 3
DumpMultiColvar.cpp +
50.0%50.0%
+
50.0 %6 / 1233.3 %1 / 3
Angles.cpp +
61.2%61.2%
+
61.2 %30 / 4966.7 %2 / 3
XYTorsions.cpp +
74.4%74.4%
+
74.4 %29 / 3966.7 %2 / 3
UWalls.cpp +
75.0%75.0%
+
75.0 %15 / 2033.3 %1 / 3
Planes.cpp +
88.9%88.9%
+
88.9 %40 / 4575.0 %3 / 4
AlphaBeta.cpp +
89.7%89.7%
+
89.7 %35 / 3966.7 %2 / 3
MultiColvarShortcuts.cpp +
90.1%90.1%
+
90.1 %145 / 161100.0 %5 / 5
Torsions.cpp +
100.0%
+
100.0 %11 / 1166.7 %2 / 3
Dihcor.cpp +
100.0%
+
100.0 %11 / 1166.7 %2 / 3
InPlaneDistances.cpp +
100.0%
+
100.0 %24 / 2466.7 %2 / 3
XAngle.cpp +
100.0%
+
100.0 %26 / 2666.7 %2 / 3
CoordAngles.cpp +
100.0%
+
100.0 %42 / 4275.0 %3 / 4
Distances.cpp +
100.0%
+
100.0 %74 / 7466.7 %2 / 3
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/index.html b/coverage/multicolvar/index.html new file mode 100644 index 000000000000..22071e39c69d --- /dev/null +++ b/coverage/multicolvar/index.html @@ -0,0 +1,234 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvarHitTotalCoverage
Test:plumed test coverageLines:50459185.3 %
Date:2024-04-19 12:12:35Functions:314963.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
AlphaBeta.cpp +
89.7%89.7%
+
89.7 %35 / 3966.7 %2 / 3
Angles.cpp +
61.2%61.2%
+
61.2 %30 / 4966.7 %2 / 3
CoordAngles.cpp +
100.0%
+
100.0 %42 / 4275.0 %3 / 4
Dihcor.cpp +
100.0%
+
100.0 %11 / 1166.7 %2 / 3
Distances.cpp +
100.0%
+
100.0 %74 / 7466.7 %2 / 3
DumpMultiColvar.cpp +
50.0%50.0%
+
50.0 %6 / 1233.3 %1 / 3
InPlaneDistances.cpp +
100.0%
+
100.0 %24 / 2466.7 %2 / 3
MFilterLess.cpp +
42.9%42.9%
+
42.9 %6 / 1433.3 %1 / 3
MFilterMore.cpp +
41.7%41.7%
+
41.7 %10 / 2433.3 %1 / 3
MultiColvarShortcuts.cpp +
90.1%90.1%
+
90.1 %145 / 161100.0 %5 / 5
Planes.cpp +
88.9%88.9%
+
88.9 %40 / 4575.0 %3 / 4
Torsions.cpp +
100.0%
+
100.0 %11 / 1166.7 %2 / 3
UWalls.cpp +
75.0%75.0%
+
75.0 %15 / 2033.3 %1 / 3
XAngle.cpp +
100.0%
+
100.0 %26 / 2666.7 %2 / 3
XYTorsions.cpp +
74.4%74.4%
+
74.4 %29 / 3966.7 %2 / 3
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/ECVcustom.cpp.func-sort-c.html b/coverage/opes/ECVcustom.cpp.func-sort-c.html new file mode 100644 index 000000000000..0290283f55e0 --- /dev/null +++ b/coverage/opes/ECVcustom.cpp.func-sort-c.html @@ -0,0 +1,117 @@ + + + + + + + + LCOV - plumed test coverage - opes/ECVcustom.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - opes - ECVcustom.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:9210092.0 %
Date:2024-04-19 12:12:35Functions:101190.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4opes9ECVcustomC2ERKNS_13ActionOptionsE0
_ZN4PLMD4opes9ECVcustom15initECVs_observERKSt6vectorIdSaIdEEjj1
_ZN4PLMD4opes9ECVcustom16initECVs_restartERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EE1
_ZN4PLMD4opes9ECVcustom8initECVsEv2
_ZN4PLMD4opes9ECVcustomC1ERKNS_13ActionOptionsE2
_ZNK4PLMD4opes9ECVcustom10getIndex_kEv2
_ZNK4PLMD4opes9ECVcustom10getLambdasB5cxx11Ev2
_ZN4PLMD4opes9ECVcustom13getPntrToECVsEj4
_ZN4PLMD4opes9ECVcustom16getPntrToDerECVsEj4
_ZN4PLMD4opes9ECVcustom16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD4opes9ECVcustom13calculateECVsEPKd91
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/ECVcustom.cpp.func.html b/coverage/opes/ECVcustom.cpp.func.html new file mode 100644 index 000000000000..13ffa67b06e5 --- /dev/null +++ b/coverage/opes/ECVcustom.cpp.func.html @@ -0,0 +1,117 @@ + + + + + + + + LCOV - plumed test coverage - opes/ECVcustom.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - opes - ECVcustom.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:9210092.0 %
Date:2024-04-19 12:12:35Functions:101190.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4opes9ECVcustom13calculateECVsEPKd91
_ZN4PLMD4opes9ECVcustom13getPntrToECVsEj4
_ZN4PLMD4opes9ECVcustom15initECVs_observERKSt6vectorIdSaIdEEjj1
_ZN4PLMD4opes9ECVcustom16getPntrToDerECVsEj4
_ZN4PLMD4opes9ECVcustom16initECVs_restartERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EE1
_ZN4PLMD4opes9ECVcustom16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD4opes9ECVcustom8initECVsEv2
_ZN4PLMD4opes9ECVcustomC1ERKNS_13ActionOptionsE2
_ZN4PLMD4opes9ECVcustomC2ERKNS_13ActionOptionsE0
_ZNK4PLMD4opes9ECVcustom10getIndex_kEv2
_ZNK4PLMD4opes9ECVcustom10getLambdasB5cxx11Ev2
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/ECVcustom.cpp.gcov.html b/coverage/opes/ECVcustom.cpp.gcov.html new file mode 100644 index 000000000000..abc7f86f34d8 --- /dev/null +++ b/coverage/opes/ECVcustom.cpp.gcov.html @@ -0,0 +1,315 @@ + + + + + + + + LCOV - plumed test coverage - opes/ECVcustom.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - opes - ECVcustom.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:9210092.0 %
Date:2024-04-19 12:12:35Functions:101190.9 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2020-2021 of Michele Invernizzi.
+       3             : 
+       4             :    This file is part of the OPES plumed module.
+       5             : 
+       6             :    The OPES plumed module is free software: you can redistribute it and/or modify
+       7             :    it under the terms of the GNU Lesser General Public License as published by
+       8             :    the Free Software Foundation, either version 3 of the License, or
+       9             :    (at your option) any later version.
+      10             : 
+      11             :    The OPES plumed module is distributed in the hope that it will be useful,
+      12             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      13             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      14             :    GNU Lesser General Public License for more details.
+      15             : 
+      16             :    You should have received a copy of the GNU Lesser General Public License
+      17             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      18             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      19             : #include "ExpansionCVs.h"
+      20             : #include "core/ActionRegister.h"
+      21             : 
+      22             : namespace PLMD {
+      23             : namespace opes {
+      24             : 
+      25             : //+PLUMEDOC OPES_EXPANSION_CV ECV_CUSTOM
+      26             : /*
+      27             : Use some given CVs as a set of expansion collective variables (ECVs).
+      28             : 
+      29             : This can be useful e.g. for quickly testing new ECVs, but from a performance point of view it is probably better to implement a new ECV class.
+      30             : 
+      31             : By default the ARGs are expeted to be energies, \f$\Delta U_i\f$, and are then multiplied by the inverse temperature \f$\beta\f$
+      32             : \f[
+      33             :   \Delta u_i=\beta \Delta U_i\, .
+      34             : \f]
+      35             : Use the DIMENSIONLESS flag to avoid this multiplication.
+      36             : 
+      37             : The flag ADD_P0 adds also the unbiased distribution to the target.
+      38             : It is possible to specify a BARRIER as in \ref ECV_UMBRELLAS_LINE, to avoid a too high initial bias.
+      39             : 
+      40             : \par Examples
+      41             : 
+      42             : \plumedfile
+      43             : ene: ENERGY
+      44             : t1: CUSTOM PERIODIC=NO ARG=ene FUNC=(300/500-1)*x
+      45             : t2: CUSTOM PERIODIC=NO ARG=ene FUNC=(300/1000-1)*x
+      46             : ecv: ECV_CUSTOM ARG=t1,t2 TEMP=300 ADD_P0
+      47             : opes: OPES_EXPANDED ARG=ecv.* PACE=500
+      48             : \endplumedfile
+      49             : 
+      50             : It is equivalent to the following:
+      51             : 
+      52             : \plumedfile
+      53             : ene: ENERGY
+      54             : ecv: ECV_MULTITHERMAL ARG=ene TEMP=300 TEMP_SET_ALL=300,500,1000
+      55             : opes: OPES_EXPANDED ARG=ecv.* PACE=500
+      56             : \endplumedfile
+      57             : 
+      58             : */
+      59             : //+ENDPLUMEDOC
+      60             : 
+      61             : class ECVcustom :
+      62             :   public ExpansionCVs
+      63             : {
+      64             : private:
+      65             :   unsigned P0_contribution_;
+      66             :   double barrier_;
+      67             :   double beta0_;
+      68             : 
+      69             :   std::vector< std::vector<double> > ECVs_;
+      70             :   std::vector< std::vector<double> > derECVs_;
+      71             :   void initECVs();
+      72             : 
+      73             : public:
+      74             :   explicit ECVcustom(const ActionOptions&);
+      75             :   static void registerKeywords(Keywords& keys);
+      76             :   void calculateECVs(const double *) override;
+      77             :   const double * getPntrToECVs(unsigned) override;
+      78             :   const double * getPntrToDerECVs(unsigned) override;
+      79             :   std::vector< std::vector<unsigned> > getIndex_k() const override;
+      80             :   std::vector<std::string> getLambdas() const override;
+      81             :   void initECVs_observ(const std::vector<double>&,const unsigned,const unsigned) override;
+      82             :   void initECVs_restart(const std::vector<std::string>&) override;
+      83             : };
+      84             : 
+      85             : PLUMED_REGISTER_ACTION(ECVcustom,"ECV_CUSTOM")
+      86             : 
+      87           4 : void ECVcustom::registerKeywords(Keywords& keys)
+      88             : {
+      89           4 :   ExpansionCVs::registerKeywords(keys);
+      90           4 :   keys.remove("ARG");
+      91           8 :   keys.add("compulsory","ARG","the labels of the single ECVs. \\f$\\Delta U_i\\f$, in energy units");
+      92           8 :   keys.addFlag("ADD_P0",false,"add the unbiased Boltzmann distribution to the target distribution, to make sure to sample it");
+      93           8 :   keys.addFlag("DIMENSIONLESS",false,"consider ARG as dimensionless rather than an energy, thus do not multiply it by \\f$\\beta\\f$");
+      94           8 :   keys.add("optional","BARRIER","a guess of the free energy barrier to be overcome (better to stay higher than lower)");
+      95           4 : }
+      96             : 
+      97           2 : ECVcustom::ECVcustom(const ActionOptions&ao)
+      98             :   : Action(ao)
+      99             :   , ExpansionCVs(ao)
+     100           2 :   , beta0_(1./kbt_)
+     101             : {
+     102             : //set beta0_
+     103             :   bool dimensionless;
+     104           2 :   parseFlag("DIMENSIONLESS",dimensionless);
+     105           2 :   if(dimensionless)
+     106           0 :     beta0_=1;
+     107             : 
+     108             : //set P0_contribution_
+     109           2 :   bool add_P0=false;
+     110           2 :   parseFlag("ADD_P0",add_P0);
+     111           2 :   if(add_P0)
+     112           2 :     P0_contribution_=1;
+     113             :   else
+     114           0 :     P0_contribution_=0;
+     115             : 
+     116             : //set barrier_
+     117           2 :   barrier_=std::numeric_limits<double>::infinity();
+     118           2 :   parse("BARRIER",barrier_);
+     119             : 
+     120           2 :   checkRead();
+     121             : 
+     122             : //set ECVs stuff
+     123           2 :   totNumECVs_=getNumberOfArguments()+P0_contribution_;
+     124           2 :   ECVs_.resize(getNumberOfArguments(),std::vector<double>(totNumECVs_));
+     125           2 :   derECVs_.resize(getNumberOfArguments(),std::vector<double>(totNumECVs_));
+     126           6 :   for(unsigned j=0; j<getNumberOfArguments(); j++)
+     127           4 :     derECVs_[j][j+P0_contribution_]=beta0_; //always constant
+     128             : 
+     129             : //print some info
+     130           2 :   if(dimensionless)
+     131           0 :     log.printf(" -- DIMENSIONLESS: the ARG is not multiplied by beta\n");
+     132           2 :   if(barrier_!=std::numeric_limits<double>::infinity())
+     133             :   {
+     134           0 :     log.printf("  guess for free energy BARRIER = %g\n",barrier_);
+     135           0 :     if(dimensionless)
+     136           0 :       log.printf("    also the BARRIER is considered to be DIMENSIONLESS\n");
+     137             :   }
+     138           2 :   if(P0_contribution_==1)
+     139           2 :     log.printf(" -- ADD_P0: the target includes also the unbiased probability itself\n");
+     140           2 : }
+     141             : 
+     142          91 : void ECVcustom::calculateECVs(const double * cv)
+     143             : {
+     144         273 :   for(unsigned j=0; j<getNumberOfArguments(); j++)
+     145         182 :     ECVs_[j][j+P0_contribution_]=beta0_*cv[j];
+     146             :   //derivative is constant
+     147          91 : }
+     148             : 
+     149           4 : const double * ECVcustom::getPntrToECVs(unsigned j)
+     150             : {
+     151           4 :   plumed_massert(isReady_,"cannot access ECVs before initialization");
+     152           4 :   plumed_massert(j<getNumberOfArguments(),getName()+" has fewer CVs");
+     153           4 :   return &ECVs_[j][0];
+     154             : }
+     155             : 
+     156           4 : const double * ECVcustom::getPntrToDerECVs(unsigned j)
+     157             : {
+     158           4 :   plumed_massert(isReady_,"cannot access ECVs before initialization");
+     159           4 :   plumed_massert(j<getNumberOfArguments(),getName()+" has fewer CVs");
+     160           4 :   return &derECVs_[j][0];
+     161             : }
+     162             : 
+     163           2 : std::vector< std::vector<unsigned> > ECVcustom::getIndex_k() const
+     164             : {
+     165           2 :   plumed_massert(isReady_ && totNumECVs_>0,"cannot access getIndex_k() of ECV before initialization");
+     166           2 :   std::vector< std::vector<unsigned> > index_k(totNumECVs_,std::vector<unsigned>(getNumberOfArguments()));
+     167           8 :   for(unsigned k=0; k<totNumECVs_; k++)
+     168          18 :     for(unsigned j=0; j<getNumberOfArguments(); j++)
+     169          12 :       if(k==j+P0_contribution_)
+     170           4 :         index_k[k][j]=k;
+     171           2 :   return index_k;
+     172           0 : }
+     173             : 
+     174           2 : std::vector<std::string> ECVcustom::getLambdas() const
+     175             : {
+     176           2 :   std::vector<std::string> lambdas(totNumECVs_);
+     177           2 :   if(P0_contribution_==1)
+     178             :   {
+     179           2 :     std::ostringstream subs;
+     180           2 :     subs<<"P0";
+     181           4 :     for(unsigned j=1; j<getNumberOfArguments(); j++)
+     182           2 :       subs<<"_P0";
+     183           2 :     lambdas[0]=subs.str();
+     184           2 :   }
+     185           6 :   for(unsigned k=P0_contribution_; k<totNumECVs_; k++)
+     186             :   {
+     187           4 :     const unsigned kk=k-P0_contribution_;
+     188           4 :     std::ostringstream subs;
+     189             : //the getLambdas method is const, so it complains if one tries to access a non-const pointer, hence the const_cast
+     190           4 :     if(kk==0)
+     191             :       subs<<const_cast<ECVcustom *>(this)->getPntrToArgument(kk)->getName();
+     192             :     else
+     193           2 :       subs<<"NaN";
+     194           8 :     for(unsigned j=1; j<getNumberOfArguments(); j++)
+     195             :     {
+     196           4 :       if(kk==j)
+     197           2 :         subs<<"_"<<const_cast<ECVcustom *>(this)->getPntrToArgument(kk)->getName();
+     198             :       else
+     199           2 :         subs<<"_NaN";
+     200             :     }
+     201           4 :     lambdas[k]=subs.str();
+     202           4 :   }
+     203           2 :   return lambdas;
+     204           0 : }
+     205             : 
+     206           2 : void ECVcustom::initECVs()
+     207             : {
+     208           2 :   plumed_massert(!isReady_,"initialization should not be called twice");
+     209           2 :   isReady_=true;
+     210           2 :   log.printf("  *%4u ECVs for %s\n",totNumECVs_,getName().c_str());
+     211           2 : }
+     212             : 
+     213           1 : void ECVcustom::initECVs_observ(const std::vector<double>& all_obs_cvs,const unsigned ncv,const unsigned index_j)
+     214             : {
+     215           1 :   initECVs();
+     216           1 :   calculateECVs(&all_obs_cvs[index_j]);
+     217           3 :   for(unsigned j=0; j<getNumberOfArguments(); j++)
+     218           4 :     ECVs_[j][j+P0_contribution_]=std::min(barrier_*beta0_,ECVs_[j][j+P0_contribution_]);
+     219           1 : }
+     220             : 
+     221           1 : void ECVcustom::initECVs_restart(const std::vector<std::string>& lambdas)
+     222             : {
+     223             :   std::size_t pos=0;
+     224           2 :   for(unsigned j=0; j<getNumberOfArguments()-1; j++)
+     225           1 :     pos=lambdas[0].find("_",pos+1); //checking only lambdas[0] is hopefully enough
+     226           1 :   plumed_massert(pos<lambdas[0].length(),"this should not happen, fewer '_' than expected in "+getName());
+     227           1 :   pos=lambdas[0].find("_",pos+1);
+     228           1 :   plumed_massert(pos>lambdas[0].length(),"this should not happen, more '_' than expected in "+getName());
+     229             : 
+     230           1 :   std::vector<std::string> myLambdas=getLambdas();
+     231           1 :   plumed_massert(myLambdas.size()==lambdas.size(),"RESTART - mismatch in number of "+getName());
+     232           1 :   plumed_massert(std::equal(myLambdas.begin(),myLambdas.end(),lambdas.begin()),"RESTART - mismatch in lambda values of "+getName());
+     233             : 
+     234           1 :   initECVs();
+     235           1 : }
+     236             : 
+     237             : }
+     238             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/ECVlinear.cpp.func-sort-c.html b/coverage/opes/ECVlinear.cpp.func-sort-c.html new file mode 100644 index 000000000000..9bdae4044c19 --- /dev/null +++ b/coverage/opes/ECVlinear.cpp.func-sort-c.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - opes/ECVlinear.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - opes - ECVlinear.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11411995.8 %
Date:2024-04-19 12:12:35Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4opes9ECVlinearC2ERKNS_13ActionOptionsE0
_ZN4PLMD4opes9ECVlinear16initECVs_restartERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EE1
_ZN4PLMD4opes9ECVlinear15initECVs_observERKSt6vectorIdSaIdEEjj3
_ZN4PLMD4opes9ECVlinear13getPntrToECVsEj4
_ZN4PLMD4opes9ECVlinear16getPntrToDerECVsEj4
_ZN4PLMD4opes9ECVlinear8initECVsEv4
_ZN4PLMD4opes9ECVlinearC1ERKNS_13ActionOptionsE4
_ZNK4PLMD4opes9ECVlinear10getLambdasB5cxx11Ev4
_ZN4PLMD4opes9ECVlinear16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD4opes9ECVlinear13calculateECVsEPKd182
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/ECVlinear.cpp.func.html b/coverage/opes/ECVlinear.cpp.func.html new file mode 100644 index 000000000000..42a62fd18c98 --- /dev/null +++ b/coverage/opes/ECVlinear.cpp.func.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - opes/ECVlinear.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - opes - ECVlinear.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11411995.8 %
Date:2024-04-19 12:12:35Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4opes9ECVlinear13calculateECVsEPKd182
_ZN4PLMD4opes9ECVlinear13getPntrToECVsEj4
_ZN4PLMD4opes9ECVlinear15initECVs_observERKSt6vectorIdSaIdEEjj3
_ZN4PLMD4opes9ECVlinear16getPntrToDerECVsEj4
_ZN4PLMD4opes9ECVlinear16initECVs_restartERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EE1
_ZN4PLMD4opes9ECVlinear16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD4opes9ECVlinear8initECVsEv4
_ZN4PLMD4opes9ECVlinearC1ERKNS_13ActionOptionsE4
_ZN4PLMD4opes9ECVlinearC2ERKNS_13ActionOptionsE0
_ZNK4PLMD4opes9ECVlinear10getLambdasB5cxx11Ev4
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/ECVlinear.cpp.gcov.html b/coverage/opes/ECVlinear.cpp.gcov.html new file mode 100644 index 000000000000..5940808094c0 --- /dev/null +++ b/coverage/opes/ECVlinear.cpp.gcov.html @@ -0,0 +1,345 @@ + + + + + + + + LCOV - plumed test coverage - opes/ECVlinear.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - opes - ECVlinear.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11411995.8 %
Date:2024-04-19 12:12:35Functions:91090.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2020-2021 of Michele Invernizzi.
+       3             : 
+       4             :    This file is part of the OPES plumed module.
+       5             : 
+       6             :    The OPES plumed module is free software: you can redistribute it and/or modify
+       7             :    it under the terms of the GNU Lesser General Public License as published by
+       8             :    the Free Software Foundation, either version 3 of the License, or
+       9             :    (at your option) any later version.
+      10             : 
+      11             :    The OPES plumed module is distributed in the hope that it will be useful,
+      12             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      13             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      14             :    GNU Lesser General Public License for more details.
+      15             : 
+      16             :    You should have received a copy of the GNU Lesser General Public License
+      17             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      18             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      19             : #include "ExpansionCVs.h"
+      20             : #include "core/ActionRegister.h"
+      21             : 
+      22             : namespace PLMD {
+      23             : namespace opes {
+      24             : 
+      25             : //+PLUMEDOC OPES_EXPANSION_CV ECV_LINEAR
+      26             : /*
+      27             : Linear expansion, according to a parameter lambda.
+      28             : 
+      29             : This can be used e.g. for thermodynamic integration, or for multibaric simulations, in which case lambda=pressure.
+      30             : It can also be used for multithermal simulations, but for simplicity it is more convenient to use \ref ECV_MULTITHERMAL.
+      31             : 
+      32             : The difference in Hamiltonian \f$\Delta U\f$ is expected as ARG.
+      33             : \f[
+      34             :   \Delta u_\lambda=\beta \lambda \Delta U\, .
+      35             : \f]
+      36             : Use the DIMENSIONLESS flag to avoid multiplying for the inverse temperature \f$\beta\f$.
+      37             : 
+      38             : By defauly the needed steps in lambda are automatically guessed from few initial unbiased MD steps, as descibed in \cite Invernizzi2020unified.
+      39             : Otherwise one can set this number with LAMBDA_STEPS.
+      40             : In both cases the steps will be uniformly distriuted.
+      41             : Finally, one can use instead the keyword LAMBDA_SET_ALL and explicitly provide each lambda value.
+      42             : 
+      43             : \par Examples
+      44             : 
+      45             : Typical multibaric simulation:
+      46             : 
+      47             : \plumedfile
+      48             : vol: VOLUME
+      49             : ecv: ECV_LINEAR ...
+      50             :   ARG=vol
+      51             :   TEMP=300
+      52             :   LAMBDA=0.06022140857*2000 #2 kbar
+      53             :   LAMBDA_MIN=0.06022140857  #1 bar
+      54             :   LAMBDA_MAX=0.06022140857*4000 #4 kbar
+      55             : ...
+      56             : opes: OPES_EXPANDED ARG=ecv.vol PACE=500
+      57             : \endplumedfile
+      58             : 
+      59             : Typical thermodynamic integration:
+      60             : 
+      61             : \plumedfile
+      62             : DeltaU: EXTRACV NAME=energy_difference
+      63             : ecv: ECV_LINEAR ARG=DeltaU TEMP=300
+      64             : opes: OPES_EXPANDED ARG=ecv.* PACE=100
+      65             : \endplumedfile
+      66             : 
+      67             : Notice that by defauly LAMBDA=0, LAMBDA_MIN=0 and LAMBDA_MAX=1, which is the typical case for thermodynamic integration.
+      68             : 
+      69             : */
+      70             : //+ENDPLUMEDOC
+      71             : 
+      72             : class ECVlinear :
+      73             :   public ExpansionCVs
+      74             : {
+      75             : private:
+      76             :   bool todoAutomatic_;
+      77             :   bool geom_spacing_;
+      78             :   double beta0_;
+      79             :   double lambda0_;
+      80             :   std::vector<double> ECVs_;
+      81             :   std::vector<double> derECVs_; //beta0*(lambda_k-lambda0)
+      82             :   void initECVs();
+      83             : 
+      84             : public:
+      85             :   explicit ECVlinear(const ActionOptions&);
+      86             :   static void registerKeywords(Keywords& keys);
+      87             :   void calculateECVs(const double *) override;
+      88             :   const double * getPntrToECVs(unsigned) override;
+      89             :   const double * getPntrToDerECVs(unsigned) override;
+      90             :   std::vector<std::string> getLambdas() const override;
+      91             :   void initECVs_observ(const std::vector<double>&,const unsigned,const unsigned) override;
+      92             :   void initECVs_restart(const std::vector<std::string>&) override;
+      93             : };
+      94             : 
+      95             : PLUMED_REGISTER_ACTION(ECVlinear,"ECV_LINEAR")
+      96             : 
+      97           6 : void ECVlinear::registerKeywords(Keywords& keys)
+      98             : {
+      99           6 :   ExpansionCVs::registerKeywords(keys);
+     100           6 :   keys.remove("ARG");
+     101          12 :   keys.add("compulsory","ARG","the label of the Hamiltonian difference. \\f$\\Delta U\\f$");
+     102          12 :   keys.add("compulsory","LAMBDA","0","the lambda at which the underlying simulation runs");
+     103          12 :   keys.add("optional","LAMBDA_MIN","( default=0 ) the minimum of the lambda range");
+     104          12 :   keys.add("optional","LAMBDA_MAX","( default=1 ) the maximum of the lambda range");
+     105          12 :   keys.add("optional","LAMBDA_STEPS","uniformly place the lambda values, for a total of LAMBDA_STEPS");
+     106          12 :   keys.add("optional","LAMBDA_SET_ALL","manually set all the lamdbas");
+     107          12 :   keys.addFlag("DIMENSIONLESS",false,"ARG is considered dimensionless rather than an energy, thus is not multiplied by \\f$\\beta\\f$");
+     108          12 :   keys.addFlag("GEOM_SPACING",false,"use geometrical spacing in lambda instead of linear spacing");
+     109           6 : }
+     110             : 
+     111           4 : ECVlinear::ECVlinear(const ActionOptions&ao)
+     112             :   : Action(ao)
+     113             :   , ExpansionCVs(ao)
+     114           4 :   , todoAutomatic_(false)
+     115           4 :   , beta0_(1./kbt_)
+     116             : {
+     117           4 :   plumed_massert(getNumberOfArguments()==1,"only DeltaU should be given as ARG");
+     118             : 
+     119             : //set beta0_
+     120             :   bool dimensionless;
+     121           4 :   parseFlag("DIMENSIONLESS",dimensionless);
+     122           4 :   if(dimensionless)
+     123           1 :     beta0_=1;
+     124             : 
+     125             : //parse lambda info
+     126           4 :   parse("LAMBDA",lambda0_);
+     127             :   const double myNone=std::numeric_limits<double>::lowest(); //quiet_NaN is not supported by some intel compiler
+     128           4 :   double lambda_min=myNone;
+     129           4 :   double lambda_max=myNone;
+     130           4 :   parse("LAMBDA_MIN",lambda_min);
+     131           4 :   parse("LAMBDA_MAX",lambda_max);
+     132           4 :   unsigned lambda_steps=0;
+     133           8 :   parse("LAMBDA_STEPS",lambda_steps);
+     134             :   std::vector<double> lambdas;
+     135           4 :   parseVector("LAMBDA_SET_ALL",lambdas);
+     136           4 :   parseFlag("GEOM_SPACING",geom_spacing_);
+     137             : 
+     138           4 :   checkRead();
+     139             : 
+     140             : //set the diff vector using lambdas
+     141           4 :   if(lambdas.size()>0)
+     142             :   {
+     143           1 :     plumed_massert(lambda_steps==0,"cannot set both LAMBDA_STEPS and LAMBDA_SET_ALL");
+     144           1 :     plumed_massert(lambda_min==myNone && lambda_max==myNone,"cannot set both LAMBDA_SET_ALL and LAMBDA_MIN/MAX");
+     145           1 :     plumed_massert(lambdas.size()>=2,"set at least 2 lambdas with LAMBDA_SET_ALL");
+     146           4 :     for(unsigned k=0; k<lambdas.size()-1; k++)
+     147           3 :       plumed_massert(lambdas[k]<=lambdas[k+1],"LAMBDA_SET_ALL must be properly ordered");
+     148           1 :     lambda_min=lambdas[0];
+     149           1 :     lambda_max=lambdas[lambdas.size()-1];
+     150           1 :     derECVs_.resize(lambdas.size());
+     151           5 :     for(unsigned k=0; k<derECVs_.size(); k++)
+     152           4 :       derECVs_[k]=beta0_*(lambdas[k]-lambda0_);
+     153             :   }
+     154             :   else
+     155             :   { //get LAMBDA_MIN and LAMBDA_MAX
+     156           3 :     if(lambda_min==myNone)
+     157             :     {
+     158           0 :       lambda_min=0;
+     159           0 :       log.printf("  no LAMBDA_MIN provided, using LAMBDA_MIN = %g\n",lambda_min);
+     160             :     }
+     161           3 :     if(lambda_max==myNone)
+     162             :     {
+     163           1 :       lambda_max=1;
+     164           1 :       log.printf("  no LAMBDA_MAX provided, using LAMBDA_MAX = %g\n",lambda_max);
+     165             :     }
+     166           3 :     plumed_massert(lambda_max>=lambda_min,"LAMBDA_MAX should be bigger than LAMBDA_MIN");
+     167           3 :     derECVs_.resize(2);
+     168           3 :     derECVs_[0]=beta0_*(lambda_min-lambda0_);
+     169           3 :     derECVs_[1]=beta0_*(lambda_max-lambda0_);
+     170           3 :     if(lambda_min==lambda_max && lambda_steps==0)
+     171           0 :       lambda_steps=1;
+     172           3 :     if(lambda_steps>0)
+     173           2 :       derECVs_=getSteps(derECVs_[0],derECVs_[1],lambda_steps,"LAMBDA",geom_spacing_,beta0_*lambda0_);
+     174             :     else
+     175           2 :       todoAutomatic_=true;
+     176             :   }
+     177           4 :   if(lambda0_<lambda_min || lambda0_>lambda_max)
+     178           1 :     log.printf(" +++ WARNING +++ running at LAMBDA=%g which is outside the chosen lambda range\n",lambda0_);
+     179             : 
+     180             : //print some info
+     181           4 :   log.printf("  running at LAMBDA=%g\n",lambda0_);
+     182           4 :   log.printf("  targeting a lambda range from LAMBDA_MIN=%g to LAMBDA_MAX=%g\n",lambda_min,lambda_max);
+     183           4 :   if(dimensionless)
+     184           1 :     log.printf(" -- DIMENSIONLESS: the ARG is not multiplied by beta\n");
+     185           4 :   if(geom_spacing_)
+     186           1 :     log.printf(" -- GEOM_SPACING: lambdas will be geometrically spaced\n");
+     187           4 : }
+     188             : 
+     189         182 : void ECVlinear::calculateECVs(const double * DeltaU)
+     190             : {
+     191        1587 :   for(unsigned k=0; k<derECVs_.size(); k++)
+     192        1405 :     ECVs_[k]=derECVs_[k]*DeltaU[0];
+     193             : // derivatives never change: derECVs_k=beta0*(lambda_k-lambda0)
+     194         182 : }
+     195             : 
+     196           4 : const double * ECVlinear::getPntrToECVs(unsigned j)
+     197             : {
+     198           4 :   plumed_massert(isReady_,"cannot access ECVs before initialization");
+     199           4 :   plumed_massert(j==0,getName()+" has only one CV, the DeltaU");
+     200           4 :   return &ECVs_[0];
+     201             : }
+     202             : 
+     203           4 : const double * ECVlinear::getPntrToDerECVs(unsigned j)
+     204             : {
+     205           4 :   plumed_massert(isReady_,"cannot access ECVs before initialization");
+     206           4 :   plumed_massert(j==0,getName()+" has only one CV, the DeltaU");
+     207           4 :   return &derECVs_[0];
+     208             : }
+     209             : 
+     210           4 : std::vector<std::string> ECVlinear::getLambdas() const
+     211             : {
+     212           4 :   plumed_massert(!todoAutomatic_,"cannot access lambdas before initializing them");
+     213           4 :   std::vector<std::string> lambdas(derECVs_.size());
+     214          35 :   for(unsigned k=0; k<derECVs_.size(); k++)
+     215             :   {
+     216          31 :     std::ostringstream subs;
+     217          31 :     subs<<derECVs_[k]/beta0_+lambda0_; //lambda_k
+     218          31 :     lambdas[k]=subs.str();
+     219          31 :   }
+     220           4 :   return lambdas;
+     221           0 : }
+     222             : 
+     223           4 : void ECVlinear::initECVs()
+     224             : {
+     225           4 :   plumed_massert(!isReady_,"initialization should not be called twice");
+     226           4 :   plumed_massert(!todoAutomatic_,"this should not happen");
+     227           4 :   totNumECVs_=derECVs_.size();
+     228           4 :   ECVs_.resize(derECVs_.size());
+     229           4 :   isReady_=true;
+     230           4 :   log.printf("  *%4lu lambdas for %s\n",derECVs_.size(),getName().c_str());
+     231           4 : }
+     232             : 
+     233           3 : void ECVlinear::initECVs_observ(const std::vector<double>& all_obs_cvs,const unsigned ncv,const unsigned index_j)
+     234             : {
+     235           3 :   if(todoAutomatic_) //estimate the steps in lambda from observations
+     236             :   {
+     237           1 :     plumed_massert(all_obs_cvs.size()%ncv==0 && index_j<ncv,"initECVs_observ parameters are inconsistent");
+     238           1 :     std::vector<double> obs_cv(all_obs_cvs.size()/ncv); //copy only useful observation (would be better not to copy...)
+     239          11 :     for(unsigned t=0; t<obs_cv.size(); t++)
+     240          10 :       obs_cv[t]=all_obs_cvs[t*ncv+index_j];
+     241           1 :     const unsigned lambda_steps=estimateNumSteps(derECVs_[0],derECVs_[1],obs_cv,"LAMBDA");
+     242           1 :     if(beta0_!=1)
+     243           0 :       log.printf("    (spacing is in beta0 units)\n");
+     244           2 :     derECVs_=getSteps(derECVs_[0],derECVs_[1],lambda_steps,"LAMBDA",geom_spacing_,beta0_*lambda0_);
+     245           1 :     todoAutomatic_=false;
+     246             :   }
+     247           3 :   initECVs();
+     248           3 :   calculateECVs(&all_obs_cvs[index_j]);
+     249           3 : }
+     250             : 
+     251           1 : void ECVlinear::initECVs_restart(const std::vector<std::string>& lambdas)
+     252             : {
+     253           1 :   std::size_t pos=lambdas[0].find("_");
+     254           1 :   plumed_massert(pos==std::string::npos,"this should not happen, only one CV is used in "+getName());
+     255           1 :   if(todoAutomatic_)
+     256             :   {
+     257           2 :     derECVs_=getSteps(derECVs_[0],derECVs_[1],lambdas.size(),"LAMBDA",geom_spacing_,beta0_*lambda0_);
+     258           1 :     todoAutomatic_=false;
+     259             :   }
+     260           1 :   std::vector<std::string> myLambdas=getLambdas();
+     261           1 :   plumed_massert(myLambdas.size()==lambdas.size(),"RESTART - mismatch in number of "+getName());
+     262           1 :   plumed_massert(std::equal(myLambdas.begin(),myLambdas.end(),lambdas.begin()),"RESTART - mismatch in lambda values of "+getName());
+     263             : 
+     264           1 :   initECVs();
+     265           1 : }
+     266             : 
+     267             : }
+     268             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/ECVmultiThermal.cpp.func-sort-c.html b/coverage/opes/ECVmultiThermal.cpp.func-sort-c.html new file mode 100644 index 000000000000..93a186bbafce --- /dev/null +++ b/coverage/opes/ECVmultiThermal.cpp.func-sort-c.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - opes/ECVmultiThermal.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - opes - ECVmultiThermal.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10711295.5 %
Date:2024-04-19 12:12:35Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4opes15ECVmultiThermalC2ERKNS_13ActionOptionsE0
_ZN4PLMD4opes15ECVmultiThermal16initECVs_restartERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EE3
_ZN4PLMD4opes15ECVmultiThermal15initECVs_observERKSt6vectorIdSaIdEEjj8
_ZN4PLMD4opes15ECVmultiThermal13getPntrToECVsEj11
_ZN4PLMD4opes15ECVmultiThermal16getPntrToDerECVsEj11
_ZN4PLMD4opes15ECVmultiThermal8initECVsEv11
_ZN4PLMD4opes15ECVmultiThermalC1ERKNS_13ActionOptionsE11
_ZNK4PLMD4opes15ECVmultiThermal10getLambdasB5cxx11Ev11
_ZN4PLMD4opes15ECVmultiThermal16registerKeywordsERNS_8KeywordsE13
_ZN4PLMD4opes15ECVmultiThermal13calculateECVsEPKd586
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/ECVmultiThermal.cpp.func.html b/coverage/opes/ECVmultiThermal.cpp.func.html new file mode 100644 index 000000000000..9210acbb90fc --- /dev/null +++ b/coverage/opes/ECVmultiThermal.cpp.func.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - opes/ECVmultiThermal.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - opes - ECVmultiThermal.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10711295.5 %
Date:2024-04-19 12:12:35Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4opes15ECVmultiThermal13calculateECVsEPKd586
_ZN4PLMD4opes15ECVmultiThermal13getPntrToECVsEj11
_ZN4PLMD4opes15ECVmultiThermal15initECVs_observERKSt6vectorIdSaIdEEjj8
_ZN4PLMD4opes15ECVmultiThermal16getPntrToDerECVsEj11
_ZN4PLMD4opes15ECVmultiThermal16initECVs_restartERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EE3
_ZN4PLMD4opes15ECVmultiThermal16registerKeywordsERNS_8KeywordsE13
_ZN4PLMD4opes15ECVmultiThermal8initECVsEv11
_ZN4PLMD4opes15ECVmultiThermalC1ERKNS_13ActionOptionsE11
_ZN4PLMD4opes15ECVmultiThermalC2ERKNS_13ActionOptionsE0
_ZNK4PLMD4opes15ECVmultiThermal10getLambdasB5cxx11Ev11
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/ECVmultiThermal.cpp.gcov.html b/coverage/opes/ECVmultiThermal.cpp.gcov.html new file mode 100644 index 000000000000..df949a491d08 --- /dev/null +++ b/coverage/opes/ECVmultiThermal.cpp.gcov.html @@ -0,0 +1,345 @@ + + + + + + + + LCOV - plumed test coverage - opes/ECVmultiThermal.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - opes - ECVmultiThermal.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10711295.5 %
Date:2024-04-19 12:12:35Functions:91090.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2020-2021 of Michele Invernizzi.
+       3             : 
+       4             :    This file is part of the OPES plumed module.
+       5             : 
+       6             :    The OPES plumed module is free software: you can redistribute it and/or modify
+       7             :    it under the terms of the GNU Lesser General Public License as published by
+       8             :    the Free Software Foundation, either version 3 of the License, or
+       9             :    (at your option) any later version.
+      10             : 
+      11             :    The OPES plumed module is distributed in the hope that it will be useful,
+      12             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      13             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      14             :    GNU Lesser General Public License for more details.
+      15             : 
+      16             :    You should have received a copy of the GNU Lesser General Public License
+      17             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      18             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      19             : #include "ExpansionCVs.h"
+      20             : #include "core/ActionRegister.h"
+      21             : 
+      22             : namespace PLMD {
+      23             : namespace opes {
+      24             : 
+      25             : //+PLUMEDOC OPES_EXPANSION_CV ECV_MULTITHERMAL
+      26             : /*
+      27             : Expand a simulation to sample multiple temperatures simultaneously.
+      28             : 
+      29             : The internal energy \f$U\f$ of of the system should be used as ARG.
+      30             : \f[
+      31             :   \Delta u_{\beta'}=(\beta'-\beta) U\, ,
+      32             : \f]
+      33             : where \f$\beta'\f$ are the temperatures to be sampled and \f$\beta\f$ is the temperature at which the simulation is conducted.
+      34             : In case of fixed volume, the internal energy is simply the potential energy given by the \ref ENERGY colvar\f$U=E\f$, and you will run a multicanonical simulation.
+      35             : If instead the simulation is at fixed pressure \f$p\f$, the contribution of the volume must be added \f$U=E+pV\f$ (see example below).
+      36             : 
+      37             : By defauly the needed steps in temperatures are automatically guessed from few initial unbiased MD steps, as descibed in \cite Invernizzi2020unified.
+      38             : Otherwise you can manually set this number with TEMP_STEPS.
+      39             : In both cases the steps will be geometrically spaced in temperature.
+      40             : Use instead the keyword NO_GEOM_SPACING for a linear spacing in the inverse temperature (beta), that typically increases the focus on lower temperatures.
+      41             : Finally, you can use instead the keyword TEMP_SET_ALL and explicitly provide each temperature.
+      42             : 
+      43             : You can reweight the resulting simulation at any temperature in the chosen range, using e.g. \ref REWEIGHT_TEMP_PRESS.
+      44             : A similar target distribution can be sampled using \ref TD_MULTICANONICAL.
+      45             : 
+      46             : 
+      47             : \par Examples
+      48             : 
+      49             : Fixed volume, multicanonical simulation:
+      50             : 
+      51             : \plumedfile
+      52             : ene: ENERGY
+      53             : ecv: ECV_MULTITHERMAL ARG=ene TEMP=300 TEMP_MIN=300 TEMP_MAX=800
+      54             : opes: OPES_EXPANDED ARG=ecv.ene PACE=500
+      55             : \endplumedfile
+      56             : 
+      57             : which, if your MD code passes the temperature to PLUMED, is equivalent to:
+      58             : 
+      59             : \plumedfile
+      60             : ene: ENERGY
+      61             : ecv: ECV_MULTITHERMAL ARG=ene TEMP_MAX=800
+      62             : opes: OPES_EXPANDED ARG=ecv.ene PACE=500
+      63             : \endplumedfile
+      64             : 
+      65             : If instead the pressure is fixed and the volume changes, you shuld calculate the internal energy first, \f$U=E+pV\f$
+      66             : 
+      67             : \plumedfile
+      68             : ene: ENERGY
+      69             : vol: VOLUME
+      70             : intEne: CUSTOM PERIODIC=NO ARG=ene,vol FUNC=x+0.06022140857*y
+      71             : ecv: ECV_MULTITHERMAL ARG=intEne TEMP_MAX=800
+      72             : opes: OPES_EXPANDED ARG=ecv.intEne PACE=500
+      73             : \endplumedfile
+      74             : 
+      75             : Notice that \f$p=0.06022140857\f$ corresponds to 1 bar when using the default PLUMED units.
+      76             : 
+      77             : */
+      78             : //+ENDPLUMEDOC
+      79             : 
+      80             : class ECVmultiThermal :
+      81             :   public ExpansionCVs
+      82             : {
+      83             : private:
+      84             :   bool todoAutomatic_;
+      85             :   bool geom_spacing_;
+      86             :   std::vector<double> ECVs_;
+      87             :   std::vector<double> derECVs_; //(beta_k-beta0) or (temp0/temp_k-1)/kbt
+      88             :   void initECVs();
+      89             : 
+      90             : public:
+      91             :   explicit ECVmultiThermal(const ActionOptions&);
+      92             :   static void registerKeywords(Keywords& keys);
+      93             :   void calculateECVs(const double *) override;
+      94             :   const double * getPntrToECVs(unsigned) override;
+      95             :   const double * getPntrToDerECVs(unsigned) override;
+      96             :   std::vector<std::string> getLambdas() const override;
+      97             :   void initECVs_observ(const std::vector<double>&,const unsigned,const unsigned) override;
+      98             :   void initECVs_restart(const std::vector<std::string>&) override;
+      99             : };
+     100             : 
+     101             : PLUMED_REGISTER_ACTION(ECVmultiThermal,"ECV_MULTITHERMAL")
+     102             : 
+     103          13 : void ECVmultiThermal::registerKeywords(Keywords& keys)
+     104             : {
+     105          13 :   ExpansionCVs::registerKeywords(keys);
+     106          13 :   keys.remove("ARG");
+     107          26 :   keys.add("compulsory","ARG","the label of the internal energy of the system. If volume is fixed it is calculated by the \\ref ENERGY colvar");
+     108          26 :   keys.add("optional","TEMP_MIN","the minimum of the temperature range");
+     109          26 :   keys.add("optional","TEMP_MAX","the maximum of the temperature range");
+     110          26 :   keys.add("optional","TEMP_STEPS","the number of steps in temperature");
+     111          26 :   keys.add("optional","TEMP_SET_ALL","manually set all the temperatures");
+     112          26 :   keys.addFlag("NO_GEOM_SPACING",false,"do not use geometrical spacing in temperature, but instead linear spacing in inverse temperature");
+     113          13 : }
+     114             : 
+     115          11 : ECVmultiThermal::ECVmultiThermal(const ActionOptions&ao)
+     116             :   : Action(ao)
+     117             :   , ExpansionCVs(ao)
+     118          11 :   , todoAutomatic_(false)
+     119             : {
+     120          11 :   plumed_massert(getNumberOfArguments()==1,"only the internal energy should be given as ARG");
+     121             : 
+     122             : //set temp0
+     123          11 :   const double temp0=kbt_/getKBoltzmann();
+     124             : 
+     125             : //parse temp range
+     126          11 :   double temp_min=-1;
+     127          11 :   double temp_max=-1;
+     128          11 :   parse("TEMP_MIN",temp_min);
+     129          11 :   parse("TEMP_MAX",temp_max);
+     130          11 :   unsigned temp_steps=0;
+     131          22 :   parse("TEMP_STEPS",temp_steps);
+     132             :   std::vector<double> temps;
+     133          11 :   parseVector("TEMP_SET_ALL",temps);
+     134          11 :   parseFlag("NO_GEOM_SPACING",geom_spacing_);
+     135          11 :   geom_spacing_=!geom_spacing_;
+     136             : 
+     137          11 :   checkRead();
+     138             : 
+     139             : //set the intermediate temperatures
+     140          11 :   if(temps.size()>0)
+     141             :   {
+     142           2 :     plumed_massert(temp_steps==0,"cannot set both TEMP_STEPS and TEMP_SET_ALL");
+     143           2 :     plumed_massert(temp_min==-1 && temp_max==-1,"cannot set both TEMP_SET_ALL and TEMP_MIN/MAX");
+     144           2 :     plumed_massert(temps.size()>=2,"set at least 2 temperatures");
+     145           2 :     temp_min=temps[0];
+     146           2 :     temp_max=temps[temps.size()-1];
+     147           2 :     derECVs_.resize(temps.size());
+     148          10 :     for(unsigned k=0; k<derECVs_.size(); k++)
+     149             :     {
+     150           8 :       derECVs_[k]=(temp0/temps[k]-1.)/kbt_;
+     151           8 :       if(k<derECVs_.size()-1)
+     152           6 :         plumed_massert(temps[k]<=temps[k+1],"TEMP_SET_ALL must be properly ordered");
+     153             :     }
+     154             :   }
+     155             :   else
+     156             :   { //get TEMP_MIN and TEMP_MAX
+     157           9 :     plumed_massert(temp_min!=-1 || temp_max!=-1,"TEMP_MIN, TEMP_MAX or both, should be set");
+     158           9 :     if(temp_min==-1)
+     159             :     {
+     160           2 :       temp_min=temp0;
+     161           2 :       log.printf("  no TEMP_MIN provided, using TEMP_MIN=TEMP\n");
+     162             :     }
+     163           9 :     if(temp_max==-1)
+     164             :     {
+     165           0 :       temp_max=temp0;
+     166           0 :       log.printf("  no TEMP_MAX provided, using TEMP_MAX=TEMP\n");
+     167             :     }
+     168           9 :     plumed_massert(temp_max>=temp_min,"TEMP_MAX should be bigger than TEMP_MIN");
+     169           9 :     derECVs_.resize(2);
+     170           9 :     derECVs_[0]=(temp0/temp_min-1.)/kbt_;
+     171           9 :     derECVs_[1]=(temp0/temp_max-1.)/kbt_;
+     172           9 :     if(temp_min==temp_max && temp_steps==0)
+     173           0 :       temp_steps=1;
+     174           9 :     if(temp_steps>0)
+     175          14 :       derECVs_=getSteps(derECVs_[0],derECVs_[1],temp_steps,"TEMP",geom_spacing_,1./kbt_);
+     176             :     else
+     177           2 :       todoAutomatic_=true;
+     178             :   }
+     179             :   const double tol=1e-3; //if temp is taken from MD engine it might be numerically slightly different
+     180          11 :   if(temp0<(1-tol)*temp_min || temp0>(1+tol)*temp_max)
+     181           0 :     log.printf(" +++ WARNING +++ running at TEMP=%g which is outside the chosen temperature range\n",temp0);
+     182             : 
+     183             : //print some info
+     184          11 :   log.printf("  targeting a temperature range from TEMP_MIN=%g to TEMP_MAX=%g\n",temp_min,temp_max);
+     185          11 :   if(!geom_spacing_)
+     186           1 :     log.printf(" -- NO_GEOM_SPACING: inverse temperatures will be linearly spaced\n");
+     187          11 : }
+     188             : 
+     189         586 : void ECVmultiThermal::calculateECVs(const double * ene)
+     190             : {
+     191        3618 :   for(unsigned k=0; k<derECVs_.size(); k++)
+     192        3032 :     ECVs_[k]=derECVs_[k]*ene[0];
+     193             : // derivatives never change: derECVs_k=(beta_k-beta0)
+     194         586 : }
+     195             : 
+     196          11 : const double * ECVmultiThermal::getPntrToECVs(unsigned j)
+     197             : {
+     198          11 :   plumed_massert(isReady_,"cannot access ECVs before initialization");
+     199          11 :   plumed_massert(j==0,getName()+" has only one CV, the ENERGY");
+     200          11 :   return &ECVs_[0];
+     201             : }
+     202             : 
+     203          11 : const double * ECVmultiThermal::getPntrToDerECVs(unsigned j)
+     204             : {
+     205          11 :   plumed_massert(isReady_,"cannot access ECVs before initialization");
+     206          11 :   plumed_massert(j==0,getName()+" has only one CV, the ENERGY");
+     207          11 :   return &derECVs_[0];
+     208             : }
+     209             : 
+     210          11 : std::vector<std::string> ECVmultiThermal::getLambdas() const
+     211             : {
+     212          11 :   plumed_massert(!todoAutomatic_,"cannot access lambdas before initializing them");
+     213          11 :   const double temp0=kbt_/getKBoltzmann();
+     214          11 :   std::vector<std::string> lambdas(derECVs_.size());
+     215          70 :   for(unsigned k=0; k<derECVs_.size(); k++)
+     216             :   {
+     217          59 :     std::ostringstream subs;
+     218          59 :     subs<<temp0/(derECVs_[k]*kbt_+1); //temp_k
+     219          59 :     lambdas[k]=subs.str();
+     220          59 :   }
+     221          11 :   return lambdas;
+     222           0 : }
+     223             : 
+     224          11 : void ECVmultiThermal::initECVs()
+     225             : {
+     226          11 :   plumed_massert(!isReady_,"initialization should not be called twice");
+     227          11 :   plumed_massert(!todoAutomatic_,"this should not happen");
+     228          11 :   totNumECVs_=derECVs_.size();
+     229          11 :   ECVs_.resize(derECVs_.size());
+     230          11 :   isReady_=true;
+     231          11 :   log.printf("  *%4lu temperatures for %s\n",derECVs_.size(),getName().c_str());
+     232          11 : }
+     233             : 
+     234           8 : void ECVmultiThermal::initECVs_observ(const std::vector<double>& all_obs_cvs,const unsigned ncv,const unsigned index_j)
+     235             : {
+     236           8 :   if(todoAutomatic_) //estimate the steps in beta from observations
+     237             :   {
+     238           1 :     plumed_massert(all_obs_cvs.size()%ncv==0 && index_j<ncv,"initECVs_observ parameters are inconsistent");
+     239           1 :     std::vector<double> obs_ene(all_obs_cvs.size()/ncv); //copy only useful observation (would be better not to copy...)
+     240          11 :     for(unsigned t=0; t<obs_ene.size(); t++)
+     241          10 :       obs_ene[t]=all_obs_cvs[t*ncv+index_j];
+     242           1 :     const unsigned temp_steps=estimateNumSteps(derECVs_[0],derECVs_[1],obs_ene,"TEMP");
+     243           1 :     log.printf("    (spacing is in beta, not in temperature)\n");
+     244           2 :     derECVs_=getSteps(derECVs_[0],derECVs_[1],temp_steps,"TEMP",geom_spacing_,1./kbt_);
+     245           1 :     todoAutomatic_=false;
+     246             :   }
+     247           8 :   initECVs();
+     248           8 :   calculateECVs(&all_obs_cvs[index_j]);
+     249           8 : }
+     250             : 
+     251           3 : void ECVmultiThermal::initECVs_restart(const std::vector<std::string>& lambdas)
+     252             : {
+     253           3 :   std::size_t pos=lambdas[0].find("_");
+     254           3 :   plumed_massert(pos==std::string::npos,"this should not happen, only one CV is used in "+getName());
+     255           3 :   if(todoAutomatic_)
+     256             :   {
+     257           2 :     derECVs_=getSteps(derECVs_[0],derECVs_[1],lambdas.size(),"TEMP",geom_spacing_,1./kbt_);
+     258           1 :     todoAutomatic_=false;
+     259             :   }
+     260           3 :   std::vector<std::string> myLambdas=getLambdas();
+     261           3 :   plumed_massert(myLambdas.size()==lambdas.size(),"RESTART - mismatch in number of "+getName());
+     262           3 :   plumed_massert(std::equal(myLambdas.begin(),myLambdas.end(),lambdas.begin()),"RESTART - mismatch in lambda values of "+getName());
+     263             : 
+     264           3 :   initECVs();
+     265           3 : }
+     266             : 
+     267             : }
+     268             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/ECVmultiThermalBaric.cpp.func-sort-c.html b/coverage/opes/ECVmultiThermalBaric.cpp.func-sort-c.html new file mode 100644 index 000000000000..52e4ec9504f5 --- /dev/null +++ b/coverage/opes/ECVmultiThermalBaric.cpp.func-sort-c.html @@ -0,0 +1,121 @@ + + + + + + + + LCOV - plumed test coverage - opes/ECVmultiThermalBaric.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - opes - ECVmultiThermalBaric.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:26327296.7 %
Date:2024-04-19 12:12:35Functions:111291.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4opes20ECVmultiThermalBaricC2ERKNS_13ActionOptionsE0
_ZN4PLMD4opes20ECVmultiThermalBaric16initECVs_restartERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EE3
_ZN4PLMD4opes20ECVmultiThermalBaric15initECVs_observERKSt6vectorIdSaIdEEjj6
_ZN4PLMD4opes20ECVmultiThermalBaric8initECVsEv9
_ZN4PLMD4opes20ECVmultiThermalBaricC1ERKNS_13ActionOptionsE9
_ZNK4PLMD4opes20ECVmultiThermalBaric10getIndex_kEv9
_ZN4PLMD4opes20ECVmultiThermalBaric16registerKeywordsERNS_8KeywordsE11
_ZN4PLMD4opes20ECVmultiThermalBaric13getPntrToECVsEj18
_ZN4PLMD4opes20ECVmultiThermalBaric16getPntrToDerECVsEj18
_ZNK4PLMD4opes20ECVmultiThermalBaric10getLambdasB5cxx11Ev18
_ZZN4PLMD4opes20ECVmultiThermalBaric16initECVs_restartERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EEENKUljE_clEj230
_ZN4PLMD4opes20ECVmultiThermalBaric13calculateECVsEPKd463
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/ECVmultiThermalBaric.cpp.func.html b/coverage/opes/ECVmultiThermalBaric.cpp.func.html new file mode 100644 index 000000000000..ccf44e3ba425 --- /dev/null +++ b/coverage/opes/ECVmultiThermalBaric.cpp.func.html @@ -0,0 +1,121 @@ + + + + + + + + LCOV - plumed test coverage - opes/ECVmultiThermalBaric.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - opes - ECVmultiThermalBaric.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:26327296.7 %
Date:2024-04-19 12:12:35Functions:111291.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4opes20ECVmultiThermalBaric13calculateECVsEPKd463
_ZN4PLMD4opes20ECVmultiThermalBaric13getPntrToECVsEj18
_ZN4PLMD4opes20ECVmultiThermalBaric15initECVs_observERKSt6vectorIdSaIdEEjj6
_ZN4PLMD4opes20ECVmultiThermalBaric16getPntrToDerECVsEj18
_ZN4PLMD4opes20ECVmultiThermalBaric16initECVs_restartERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EE3
_ZN4PLMD4opes20ECVmultiThermalBaric16registerKeywordsERNS_8KeywordsE11
_ZN4PLMD4opes20ECVmultiThermalBaric8initECVsEv9
_ZN4PLMD4opes20ECVmultiThermalBaricC1ERKNS_13ActionOptionsE9
_ZN4PLMD4opes20ECVmultiThermalBaricC2ERKNS_13ActionOptionsE0
_ZNK4PLMD4opes20ECVmultiThermalBaric10getIndex_kEv9
_ZNK4PLMD4opes20ECVmultiThermalBaric10getLambdasB5cxx11Ev18
_ZZN4PLMD4opes20ECVmultiThermalBaric16initECVs_restartERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EEENKUljE_clEj230
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/ECVmultiThermalBaric.cpp.gcov.html b/coverage/opes/ECVmultiThermalBaric.cpp.gcov.html new file mode 100644 index 000000000000..fe0deb42394b --- /dev/null +++ b/coverage/opes/ECVmultiThermalBaric.cpp.gcov.html @@ -0,0 +1,607 @@ + + + + + + + + LCOV - plumed test coverage - opes/ECVmultiThermalBaric.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - opes - ECVmultiThermalBaric.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:26327296.7 %
Date:2024-04-19 12:12:35Functions:111291.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2020-2021 of Michele Invernizzi.
+       3             : 
+       4             :    This file is part of the OPES plumed module.
+       5             : 
+       6             :    The OPES plumed module is free software: you can redistribute it and/or modify
+       7             :    it under the terms of the GNU Lesser General Public License as published by
+       8             :    the Free Software Foundation, either version 3 of the License, or
+       9             :    (at your option) any later version.
+      10             : 
+      11             :    The OPES plumed module is distributed in the hope that it will be useful,
+      12             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      13             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      14             :    GNU Lesser General Public License for more details.
+      15             : 
+      16             :    You should have received a copy of the GNU Lesser General Public License
+      17             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      18             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      19             : #include "ExpansionCVs.h"
+      20             : #include "core/ActionRegister.h"
+      21             : 
+      22             : namespace PLMD {
+      23             : namespace opes {
+      24             : 
+      25             : //+PLUMEDOC OPES_EXPANSION_CV ECV_MULTITHERMAL_MULTIBARIC
+      26             : /*
+      27             : Expand a simulation to sample multiple temperatures and pressures.
+      28             : 
+      29             : The potential \ref ENERGY, \f$E\f$, and the \ref VOLUME, \f$V\f$, of the system should be used as ARG.
+      30             : \f[
+      31             :   \Delta u_{\beta',p'}=(\beta'-\beta) E + (\beta' p' -\beta p) V\, ,
+      32             : \f]
+      33             : where \f$\beta', p'\f$ are the temperatures and pressures to be sampled, while \f$\beta, p\f$ is the temperature and pressure at which the simulation is conducted.
+      34             : 
+      35             : If instead you wish to sample multiple temperatures and a single pressure, you should use \ref ECV_MULTITHERMAL with as ARG the internal energy \f$U=E+pV\f$.
+      36             : 
+      37             : The TEMP_STEPS and PRESSURE_STEPS are automatically guessed from the initial unbiased steps (see OBSERVATION_STEPS in \ref OPES_EXPANDED), unless explicitly set.
+      38             : The algorithm for this guess is described in \cite Invernizzi2020unified should provide a rough estimate useful for most applications.
+      39             : The pressures are uniformely spaced, while the temperatures steps are geometrically spaced.
+      40             : Use instead the keyword NO_GEOM_SPACING for a linear spacing in inverse temperature (beta).
+      41             : For more detailed control you can use instead TEMP_SET_ALL and/or PRESSURE_SET_ALL to explicitly set all of them.
+      42             : The temperatures and pressures are then combined in a 2D grid.
+      43             : 
+      44             : You can use CUT_CORNER to avoid a high-temperature/low-pressure region.
+      45             : This can be useful e.g. to increase the temperature for greater ergodicity, while avoiding water to vaporize, as in Ref.\cite Invernizzi2020unified.
+      46             : 
+      47             : You can reweight the resulting simulation at any temperature and pressure in chosen target, using e.g. \ref REWEIGHT_TEMP_PRESS.
+      48             : A similar target distribution can be sampled using \ref TD_MULTITHERMAL_MULTIBARIC.
+      49             : 
+      50             : \par Examples
+      51             : 
+      52             : \plumedfile
+      53             : ene: ENERGY
+      54             : vol: VOLUME
+      55             : ecv: ECV_MULTITHERMAL_MULTIBARIC ...
+      56             :   ARG=ene,vol
+      57             :   TEMP=500
+      58             :   TEMP_MIN=270
+      59             :   TEMP_MAX=800
+      60             :   PRESSURE=0.06022140857*2000 #2 kbar
+      61             :   PRESSURE_MIN=0.06022140857  #1 bar
+      62             :   PRESSURE_MAX=0.06022140857*4000 #4 kbar
+      63             :   CUT_CORNER=500,0.06022140857,800,0.06022140857*1000
+      64             : ...
+      65             : opes: OPES_EXPANDED ARG=ecv.* FILE=DeltaF.data PACE=500 WALKERS_MPI
+      66             : \endplumedfile
+      67             : 
+      68             : Notice that \f$p=0.06022140857\f$ corresponds to 1 bar only when using the default PLUMED units.
+      69             : If you modify them via the \ref UNITS command, then the pressure has to be rescaled accordingly.
+      70             : 
+      71             : */
+      72             : //+ENDPLUMEDOC
+      73             : 
+      74             : class ECVmultiThermalBaric :
+      75             :   public ExpansionCVs
+      76             : {
+      77             : private:
+      78             :   bool todoAutomatic_beta_;
+      79             :   bool todoAutomatic_pres_;
+      80             :   bool geom_spacing_;
+      81             :   double pres0_;
+      82             :   std::vector<double> pres_;
+      83             :   std::vector<double> ECVs_beta_;
+      84             :   std::vector<double> ECVs_pres_;
+      85             :   std::vector<double> derECVs_beta_; //(beta_k-beta0) or (temp0/temp_k-1)/kbt
+      86             :   std::vector<double> derECVs_pres_; //(beta_k*pres_kk-beta0*pres0) or (temp0/temp_k*pres_kk-pres0)/kbt
+      87             :   void initECVs();
+      88             : 
+      89             : //CUT_CORNER stuff
+      90             :   double coeff_;
+      91             :   double pres_low_;
+      92             :   double kB_temp_low_;
+      93             : //SET_ALL_TEMP_PRESSURE stuff
+      94             :   std::vector<std::string> custom_lambdas_;
+      95             : 
+      96             : public:
+      97             :   explicit ECVmultiThermalBaric(const ActionOptions&);
+      98             :   static void registerKeywords(Keywords& keys);
+      99             :   void calculateECVs(const double *) override;
+     100             :   const double * getPntrToECVs(unsigned) override;
+     101             :   const double * getPntrToDerECVs(unsigned) override;
+     102             :   std::vector< std::vector<unsigned> > getIndex_k() const override;
+     103             :   std::vector<std::string> getLambdas() const override;
+     104             :   void initECVs_observ(const std::vector<double>&,const unsigned,const unsigned) override;
+     105             :   void initECVs_restart(const std::vector<std::string>&) override;
+     106             : };
+     107             : 
+     108             : PLUMED_REGISTER_ACTION(ECVmultiThermalBaric,"ECV_MULTITHERMAL_MULTIBARIC")
+     109             : 
+     110          11 : void ECVmultiThermalBaric::registerKeywords(Keywords& keys)
+     111             : {
+     112          11 :   ExpansionCVs::registerKeywords(keys);
+     113          11 :   keys.remove("ARG");
+     114          22 :   keys.add("compulsory","ARG","the labels of the potential energy and of the volume of the system. You can calculate them with \\ref ENERGY and \\ref VOLUME respectively");
+     115             : //temperature
+     116          22 :   keys.add("optional","TEMP_MIN","the minimum of the temperature range");
+     117          22 :   keys.add("optional","TEMP_MAX","the maximum of the temperature range");
+     118          22 :   keys.add("optional","TEMP_STEPS","the number of steps in temperature");
+     119          22 :   keys.add("optional","TEMP_SET_ALL","manually set all the temperatures");
+     120          22 :   keys.addFlag("NO_GEOM_SPACING",false,"do not use geometrical spacing in temperature, but instead linear spacing in inverse temperature");
+     121             : //pressure
+     122          22 :   keys.add("compulsory","PRESSURE","pressure. Use the proper units");
+     123          22 :   keys.add("optional","PRESSURE_MIN","the minimum of the pressure range");
+     124          22 :   keys.add("optional","PRESSURE_MAX","the maximum of the pressure range");
+     125          22 :   keys.add("optional","PRESSURE_STEPS","the number of steps in pressure");
+     126          22 :   keys.add("optional","PRESSURE_SET_ALL","manually set all the pressures");
+     127             : //other
+     128          22 :   keys.add("optional","SET_ALL_TEMP_PRESSURE","manually set all the target temperature_pressure pairs. An underscore separates temperature and pressure, while different points are comma-separated, e.g.: temp1_pres1,temp1_pres2,...");
+     129          22 :   keys.add("optional","CUT_CORNER","avoid region of high temperature and low pressure. Exclude all points below a line in the temperature-pressure plane, defined by two points: \\f$T_{\\text{low}},P_{\\text{low}},T_{\\text{high}},P_{\\text{high}}\\f$");
+     130          11 : }
+     131             : 
+     132           9 : ECVmultiThermalBaric::ECVmultiThermalBaric(const ActionOptions&ao)
+     133             :   : Action(ao)
+     134             :   , ExpansionCVs(ao)
+     135           9 :   , todoAutomatic_beta_(false)
+     136           9 :   , todoAutomatic_pres_(false)
+     137           9 :   , coeff_(0)
+     138           9 :   , pres_low_(0)
+     139           9 :   , kB_temp_low_(0)
+     140             : {
+     141           9 :   plumed_massert(getNumberOfArguments()==2,"ENERGY and VOLUME should be given as ARG");
+     142             : 
+     143             : //set temp0
+     144           9 :   const double kB=getKBoltzmann();
+     145           9 :   const double temp0=kbt_/kB;
+     146             : 
+     147             : //parse temp range
+     148           9 :   double temp_min=-1;
+     149           9 :   double temp_max=-1;
+     150           9 :   parse("TEMP_MIN",temp_min);
+     151           9 :   parse("TEMP_MAX",temp_max);
+     152           9 :   unsigned temp_steps=0;
+     153          18 :   parse("TEMP_STEPS",temp_steps);
+     154             :   std::vector<double> temps;
+     155           9 :   parseVector("TEMP_SET_ALL",temps);
+     156           9 :   parseFlag("NO_GEOM_SPACING",geom_spacing_);
+     157           9 :   geom_spacing_=!geom_spacing_;
+     158             : //parse pressures
+     159           9 :   parse("PRESSURE",pres0_);
+     160             :   const double myNone=std::numeric_limits<double>::lowest(); //quiet_NaN is not supported by some intel compiler
+     161           9 :   double pres_min=myNone; //-1 might be a meaningful pressure
+     162           9 :   double pres_max=myNone;
+     163           9 :   parse("PRESSURE_MIN",pres_min);
+     164           9 :   parse("PRESSURE_MAX",pres_max);
+     165           9 :   unsigned pres_steps=0;
+     166           9 :   parse("PRESSURE_STEPS",pres_steps);
+     167          18 :   parseVector("PRESSURE_SET_ALL",pres_);
+     168             : //other
+     169             :   std::vector<double> cut_corner;
+     170           9 :   parseVector("CUT_CORNER",cut_corner);
+     171           9 :   parseVector("SET_ALL_TEMP_PRESSURE",custom_lambdas_);
+     172             : 
+     173           9 :   checkRead();
+     174             : 
+     175           9 :   if(custom_lambdas_.size()>0)
+     176             :   {
+     177             :     //make sure no incompatible options are used
+     178           2 :     plumed_massert(temps.size()==0,"cannot set both SET_ALL_TEMP_PRESSURE and TEMP_SET_ALL");
+     179           2 :     plumed_massert(pres_.size()==0,"cannot set both SET_ALL_TEMP_PRESSURE and PRESSURE_SET_ALL");
+     180           2 :     plumed_massert(temp_steps==0,"cannot set both SET_ALL_TEMP_PRESSURE and TEMP_STEPS");
+     181           2 :     plumed_massert(pres_steps==0,"cannot set both SET_ALL_TEMP_PRESSURE and PRESSURE_STEPS");
+     182           2 :     plumed_massert(temp_min==-1 && temp_max==-1,"cannot set both SET_ALL_TEMP_PRESSURE and TEMP_MIN/MAX");
+     183           2 :     plumed_massert(pres_min==myNone && pres_max==myNone,"cannot set both SET_ALL_TEMP_PRESSURE and PRESSURE_MIN/MAX");
+     184           2 :     plumed_massert(cut_corner.size()==0,"cannot set both SET_ALL_TEMP_PRESSURE and CUT_CORNER");
+     185             : //setup the target temperature-pressure grid
+     186           2 :     derECVs_beta_.resize(custom_lambdas_.size());
+     187           2 :     derECVs_pres_.resize(custom_lambdas_.size());
+     188           2 :     const std::string error_msg="SET_ALL_TEMP_PRESSURE: two underscore-separated values are expected for each comma-separated point, cannot understand: ";
+     189          22 :     for(unsigned i=0; i<custom_lambdas_.size(); i++)
+     190             :     {
+     191             :       try
+     192             :       {
+     193             :         std::size_t pos1;
+     194             :         const double temp_i=std::stod(custom_lambdas_[i],&pos1);
+     195          20 :         plumed_massert(pos1+1<custom_lambdas_[i].size(),error_msg+custom_lambdas_[i]);
+     196          20 :         plumed_massert(custom_lambdas_[i][pos1]=='_',error_msg+custom_lambdas_[i]);
+     197             :         std::size_t pos2;
+     198          20 :         const double pres_i=std::stod(custom_lambdas_[i].substr(pos1+1),&pos2);
+     199          20 :         plumed_massert(pos1+1+pos2==custom_lambdas_[i].size(),error_msg+custom_lambdas_[i]);
+     200             : 
+     201          20 :         derECVs_beta_[i]=(temp0/temp_i-1.)/kbt_;
+     202          20 :         derECVs_pres_[i]=(temp0/temp_i*pres_i-pres0_)/kbt_;
+     203             :       }
+     204           0 :       catch (std::exception &ex)
+     205             :       {
+     206           0 :         plumed_merror(error_msg+custom_lambdas_[i]);
+     207           0 :       }
+     208             :     }
+     209             :   }
+     210             :   else
+     211             :   {
+     212             :     //set the intermediate temperatures
+     213           7 :     if(temps.size()>0)
+     214             :     {
+     215           1 :       plumed_massert(temp_steps==0,"cannot set both TEMP_STEPS and TEMP_SET_ALL");
+     216           1 :       plumed_massert(temp_min==-1 && temp_max==-1,"cannot set both TEMP_SET_ALL and TEMP_MIN/MAX");
+     217           1 :       plumed_massert(temps.size()>=2,"set at least 2 temperatures");
+     218           1 :       temp_min=temps[0];
+     219           1 :       temp_max=temps[temps.size()-1];
+     220           1 :       derECVs_beta_.resize(temps.size());
+     221           5 :       for(unsigned k=0; k<derECVs_beta_.size(); k++)
+     222             :       {
+     223           4 :         derECVs_beta_[k]=(temp0/temps[k]-1.)/kbt_;
+     224           4 :         if(k<derECVs_beta_.size()-1)
+     225           3 :           plumed_massert(temps[k]<=temps[k+1],"TEMP_SET_ALL must be properly ordered");
+     226             :       }
+     227             :     }
+     228             :     else
+     229             :     { //get TEMP_MIN and TEMP_MAX
+     230           6 :       if(temp_min==-1)
+     231             :       {
+     232           0 :         temp_min=temp0;
+     233           0 :         log.printf("  no TEMP_MIN provided, using TEMP_MIN=TEMP\n");
+     234             :       }
+     235           6 :       if(temp_max==-1)
+     236             :       {
+     237           1 :         temp_max=temp0;
+     238           1 :         log.printf("  no TEMP_MAX provided, using TEMP_MAX=TEMP\n");
+     239             :       }
+     240           6 :       plumed_massert(temp_max>=temp_min,"TEMP_MAX should be bigger than TEMP_MIN");
+     241           6 :       derECVs_beta_.resize(2);
+     242           6 :       derECVs_beta_[0]=(temp0/temp_min-1.)/kbt_;
+     243           6 :       derECVs_beta_[1]=(temp0/temp_max-1.)/kbt_;
+     244           6 :       if(temp_min==temp_max && temp_steps==0)
+     245           0 :         temp_steps=1;
+     246           6 :       if(temp_steps>0)
+     247           4 :         derECVs_beta_=getSteps(derECVs_beta_[0],derECVs_beta_[1],temp_steps,"TEMP",geom_spacing_,1./kbt_);
+     248             :       else
+     249           4 :         todoAutomatic_beta_=true;
+     250             :     }
+     251             :     const double tol=1e-3; //if temp is taken from MD engine it might be numerically slightly different
+     252           7 :     if(temp0<(1-tol)*temp_min || temp0>(1+tol)*temp_max)
+     253           1 :       log.printf(" +++ WARNING +++ running at TEMP=%g which is outside the chosen temperature range\n",temp0);
+     254             : 
+     255             :     //set the intermediate pressures
+     256           7 :     if(pres_.size()>0)
+     257             :     {
+     258           1 :       plumed_massert(pres_steps==0,"cannot set both PRESSURE_STEPS and PRESSURE_SET_ALL");
+     259           1 :       plumed_massert(pres_min==myNone && pres_max==myNone,"cannot set both PRESSURE_SET_ALL and PRESSURE_MIN/MAX");
+     260           1 :       plumed_massert(pres_.size()>=2,"set at least 2 pressures");
+     261           6 :       for(unsigned kk=0; kk<pres_.size()-1; kk++)
+     262           5 :         plumed_massert(pres_[kk]<=pres_[kk+1],"PRESSURE_SET_ALL must be properly ordered");
+     263           1 :       pres_min=pres_[0];
+     264           1 :       pres_max=pres_[pres_.size()-1];
+     265             :     }
+     266             :     else
+     267             :     { //get PRESSURE_MIN and PRESSURE_MAX
+     268           6 :       if(pres_min==myNone)
+     269             :       {
+     270           3 :         pres_min=pres0_;
+     271           3 :         log.printf("  no PRESSURE_MIN provided, using PRESSURE_MIN=PRESSURE\n");
+     272             :       }
+     273           6 :       if(pres_max==myNone)
+     274             :       {
+     275           2 :         pres_max=pres0_;
+     276           2 :         log.printf("  no PRESSURE_MAX provided, using PRESSURE_MAX=PRESSURE\n");
+     277             :       }
+     278           6 :       plumed_massert(pres_max>=pres_min,"PRESSURE_MAX should be bigger than PRESSURE_MIN");
+     279           6 :       if(pres_min==pres_max && pres_steps==0)
+     280           0 :         pres_steps=1;
+     281           6 :       if(pres_steps>0)
+     282           4 :         pres_=getSteps(pres_min,pres_max,pres_steps,"PRESSURE",false,0);
+     283             :       else
+     284             :       {
+     285           4 :         pres_.resize(2);
+     286           4 :         pres_[0]=pres_min;
+     287           4 :         pres_[1]=pres_max;
+     288           4 :         todoAutomatic_pres_=true;
+     289             :       }
+     290             :     }
+     291           7 :     if(pres0_<pres_min || pres0_>pres_max)
+     292           0 :       log.printf(" +++ WARNING +++ running at PRESSURE=%g which is outside the chosen pressure range\n",pres0_);
+     293             : 
+     294             :     //set CUT_CORNER
+     295           7 :     std::string cc_usage("CUT_CORNER=temp_low,pres_low,temp_high,pres_high");
+     296           7 :     if(cut_corner.size()==4)
+     297             :     {
+     298           6 :       const double temp_low=cut_corner[0];
+     299           6 :       const double pres_low=cut_corner[1];
+     300           6 :       const double temp_high=cut_corner[2];
+     301           6 :       const double pres_high=cut_corner[3];
+     302           6 :       plumed_massert(temp_low<temp_high,"temp_low="+std::to_string(temp_low)+" should be smaller than temp_high="+std::to_string(temp_high)+", "+cc_usage);
+     303           6 :       plumed_massert(temp_low>=temp_min && temp_low<=temp_max,"temp_low="+std::to_string(temp_low)+" is out of temperature range. "+cc_usage);
+     304           6 :       plumed_massert(temp_high>=temp_min && temp_high<=temp_max,"temp_high="+std::to_string(temp_high)+" is out of temperature range. "+cc_usage);
+     305           6 :       plumed_massert(pres_low<pres_high,"pres_low="+std::to_string(pres_low)+" should be smaller than pres_high="+std::to_string(pres_high)+", "+cc_usage);
+     306           6 :       plumed_massert(pres_low>=pres_min && pres_low<=pres_max,"pres_low="+std::to_string(pres_low)+" is out of pressure range. "+cc_usage);
+     307           6 :       plumed_massert(pres_high>=pres_min && pres_high<=pres_max,"pres_high="+std::to_string(pres_high)+" is out of pressure range. "+cc_usage);
+     308           6 :       kB_temp_low_=kB*temp_low;
+     309           6 :       coeff_=(pres_high-pres_low)/(temp_high-temp_low)/kB;
+     310           6 :       plumed_massert(coeff_!=0,"this should not be possible");
+     311           6 :       const double small_value=(temp_high-pres_low)/1e4;
+     312           6 :       pres_low_=pres_low-small_value; //make sure pres_max is included
+     313           6 :       plumed_massert(pres_max>=coeff_*(kB*temp_max-kB_temp_low_)+pres_low_,"please chose a pres_high slightly smaller than PRESSURE_MAX in "+cc_usage);
+     314             :     }
+     315             :     else
+     316             :     {
+     317           1 :       plumed_massert(cut_corner.size()==0,"expected 4 values: "+cc_usage);
+     318             :     }
+     319             :   }
+     320             : 
+     321             : //print some info
+     322           9 :   log.printf("  running at TEMP=%g and PRESSURE=%g\n",temp0,pres0_);
+     323           9 :   log.printf("  targeting a temperature range from TEMP_MIN=%g to TEMP_MAX=%g\n",temp_min,temp_max);
+     324           9 :   if(temp_min==temp_max)
+     325           2 :     log.printf(" +++ WARNING +++ if you only need a multibaric simulation it is more efficient to set it up with ECV_LINEAR\n");
+     326           9 :   log.printf("   and a pressure range from PRESSURE_MIN=%g to PRESSURE_MAX=%g\n",pres_min,pres_max);
+     327           9 :   if(pres_min==pres_max)
+     328           2 :     log.printf(" +++ WARNING +++ if you only need a multithermal simulation it is more efficient to set it up with ECV_MULTITHERMAL\n");
+     329           9 :   if(!geom_spacing_)
+     330           1 :     log.printf(" -- NO_GEOM_SPACING: inverse temperatures will be linearly spaced\n");
+     331           9 :   if(coeff_!=0)
+     332           6 :     log.printf(" -- CUT_CORNER: ignoring some high temperature and low pressure values\n");
+     333           9 : }
+     334             : 
+     335         463 : void ECVmultiThermalBaric::calculateECVs(const double * ene_vol)
+     336             : {
+     337        5925 :   for(unsigned k=0; k<derECVs_beta_.size(); k++)
+     338        5462 :     ECVs_beta_[k]=derECVs_beta_[k]*ene_vol[0];
+     339       50075 :   for(unsigned i=0; i<derECVs_pres_.size(); i++)
+     340       49612 :     ECVs_pres_[i]=derECVs_pres_[i]*ene_vol[1];
+     341             : // derivatives are constant, as usual in linear expansions
+     342         463 : }
+     343             : 
+     344          18 : const double * ECVmultiThermalBaric::getPntrToECVs(unsigned j)
+     345             : {
+     346          18 :   plumed_massert(isReady_,"cannot access ECVs before initialization");
+     347          18 :   plumed_massert(j==0 || j==1,getName()+" has only two CVs, the ENERGY and the VOLUME");
+     348          18 :   if(j==0)
+     349           9 :     return &ECVs_beta_[0];
+     350             :   else //if (j==1)
+     351           9 :     return &ECVs_pres_[0];
+     352             : }
+     353             : 
+     354          18 : const double * ECVmultiThermalBaric::getPntrToDerECVs(unsigned j)
+     355             : {
+     356          18 :   plumed_massert(isReady_,"cannot access ECVs before initialization");
+     357          18 :   plumed_massert(j==0 || j==1,getName()+" has only two CVs, the ENERGY and the VOLUME");
+     358          18 :   if(j==0)
+     359           9 :     return &derECVs_beta_[0];
+     360             :   else //if (j==1)
+     361           9 :     return &derECVs_pres_[0];
+     362             : }
+     363             : 
+     364           9 : std::vector< std::vector<unsigned> > ECVmultiThermalBaric::getIndex_k() const
+     365             : {
+     366           9 :   plumed_massert(isReady_ && totNumECVs_>0,"cannot access getIndex_k() of ECV before initialization");
+     367             :   std::vector< std::vector<unsigned> > index_k;
+     368           9 :   if(custom_lambdas_.size()>0)
+     369             :   { //same as default getIndex_k() function
+     370           2 :     plumed_massert(totNumECVs_==custom_lambdas_.size(),"this should not happen");
+     371          22 :     for(unsigned i=0; i<totNumECVs_; i++)
+     372          40 :       index_k.emplace_back(std::vector<unsigned> {i,i});
+     373             :   }
+     374             :   else
+     375             :   {
+     376             :     unsigned i=0;
+     377         146 :     for(unsigned k=0; k<derECVs_beta_.size(); k++)
+     378             :     {
+     379         139 :       const double kB_temp_k=kbt_/(derECVs_beta_[k]*kbt_+1);
+     380         139 :       const double line_k=coeff_*(kB_temp_k-kB_temp_low_)+pres_low_;
+     381        2594 :       for(unsigned kk=0; kk<pres_.size(); kk++)
+     382             :       {
+     383        2455 :         if(coeff_==0 || pres_[kk]>=line_k) //important to be inclusive, thus >=, not just >
+     384             :         {
+     385        2254 :           index_k.emplace_back(std::vector<unsigned> {k,i});
+     386        2254 :           i++;
+     387             :         }
+     388             :       }
+     389             :     }
+     390           7 :     plumed_massert(totNumECVs_==index_k.size(),"this should not happen, is something wrong with CUT_CORNER ?");
+     391             :   }
+     392           9 :   return index_k;
+     393           0 : }
+     394             : 
+     395          18 : std::vector<std::string> ECVmultiThermalBaric::getLambdas() const
+     396             : {
+     397          18 :   if(custom_lambdas_.size()>0)
+     398           4 :     return custom_lambdas_;
+     399             : 
+     400          14 :   plumed_massert(!todoAutomatic_beta_ && !todoAutomatic_pres_,"cannot access lambdas before initializing them");
+     401             :   std::vector<std::string> lambdas;
+     402          14 :   const double kB=getKBoltzmann();
+     403         292 :   for(unsigned k=0; k<derECVs_beta_.size(); k++)
+     404             :   {
+     405         278 :     const double kB_temp_k=kbt_/(derECVs_beta_[k]*kbt_+1);
+     406         278 :     const double line_k=coeff_*(kB_temp_k-kB_temp_low_)+pres_low_;
+     407        5188 :     for(unsigned kk=0; kk<pres_.size(); kk++)
+     408             :     {
+     409        4910 :       if(coeff_==0 || pres_[kk]>=line_k)
+     410             :       {
+     411        4508 :         std::ostringstream subs;
+     412        4508 :         subs<<kB_temp_k/kB<<"_"<<pres_[kk];
+     413        4508 :         lambdas.emplace_back(subs.str());
+     414        4508 :       }
+     415             :     }
+     416             :   }
+     417             :   return lambdas;
+     418          14 : }
+     419             : 
+     420           9 : void ECVmultiThermalBaric::initECVs()
+     421             : {
+     422           9 :   plumed_massert(!isReady_,"initialization should not be called twice");
+     423           9 :   plumed_massert(!todoAutomatic_beta_ && !todoAutomatic_pres_,"this should not happen");
+     424           9 :   totNumECVs_=getLambdas().size(); //slow, but runs only once
+     425           9 :   if(custom_lambdas_.size()>0)
+     426             :   {
+     427           2 :     log.printf("  *%4lu temperatures for %s\n",derECVs_beta_.size(),getName().c_str());
+     428           2 :     log.printf("  *%4lu beta-pressures for %s\n",derECVs_pres_.size(),getName().c_str());
+     429           2 :     log.printf("    -- SET_ALL_TEMP_PRESSURE: total number of temp-pres points is %u\n",totNumECVs_);
+     430             :   }
+     431             :   else
+     432             :   {
+     433           7 :     plumed_massert(derECVs_beta_.size()*pres_.size()>=totNumECVs_,"this should not happen, is something wrong with CUT_CORNER ?");
+     434           7 :     derECVs_pres_.resize(totNumECVs_); //pres is mixed with temp (beta*p*V), thus we need to store all possible
+     435             :     //initialize the derECVs.
+     436             :     //this could be done before and one could avoid storing also beta0, beta_k, etc. but this way the code should be more readable
+     437             :     unsigned i=0;
+     438         146 :     for(unsigned k=0; k<derECVs_beta_.size(); k++)
+     439             :     {
+     440         139 :       const double kB_temp_k=kbt_/(derECVs_beta_[k]*kbt_+1);
+     441         139 :       const double line_k=coeff_*(kB_temp_k-kB_temp_low_)+pres_low_;
+     442        2594 :       for(unsigned kk=0; kk<pres_.size(); kk++)
+     443             :       {
+     444        2455 :         if(coeff_==0 || pres_[kk]>=line_k)
+     445             :         {
+     446        2254 :           derECVs_pres_[i]=(pres_[kk]/kB_temp_k-pres0_/kbt_);
+     447        2254 :           i++;
+     448             :         }
+     449             :       }
+     450             :     }
+     451           7 :     log.printf("  *%4lu temperatures for %s\n",derECVs_beta_.size(),getName().c_str());
+     452           7 :     log.printf("  *%4lu pressures for %s\n",pres_.size(),getName().c_str());
+     453           7 :     if(coeff_!=0)
+     454           6 :       log.printf("    -- CUT_CORNER: %lu temp-pres points were excluded, thus total is %u\n",derECVs_beta_.size()*pres_.size()-totNumECVs_,totNumECVs_);
+     455             :   }
+     456           9 :   ECVs_beta_.resize(derECVs_beta_.size());
+     457           9 :   ECVs_pres_.resize(derECVs_pres_.size());
+     458           9 :   isReady_=true;
+     459           9 : }
+     460             : 
+     461           6 : void ECVmultiThermalBaric::initECVs_observ(const std::vector<double>& all_obs_cvs,const unsigned ncv,const unsigned index_j)
+     462             : {
+     463           6 :   if(todoAutomatic_beta_) //estimate the steps in beta from observations
+     464             :   {
+     465           2 :     plumed_massert(all_obs_cvs.size()%ncv==0 && index_j<ncv,"initECVs_observ parameters are inconsistent");
+     466           2 :     std::vector<double> obs_ene(all_obs_cvs.size()/ncv); //copy only useful observations
+     467          17 :     for(unsigned t=0; t<obs_ene.size(); t++)
+     468          15 :       obs_ene[t]=all_obs_cvs[t*ncv+index_j]+pres0_*all_obs_cvs[t*ncv+index_j+1]; //U=E+pV
+     469           2 :     const unsigned temp_steps=estimateNumSteps(derECVs_beta_[0],derECVs_beta_[1],obs_ene,"TEMP");
+     470           2 :     log.printf("    (spacing is on beta, not on temperature)\n");
+     471           4 :     derECVs_beta_=getSteps(derECVs_beta_[0],derECVs_beta_[1],temp_steps,"TEMP",geom_spacing_,1./kbt_);
+     472           2 :     todoAutomatic_beta_=false;
+     473             :   }
+     474           6 :   if(todoAutomatic_pres_) //estimate the steps in pres from observations
+     475             :   {
+     476           2 :     plumed_massert(all_obs_cvs.size()%ncv==0 && index_j+1<ncv,"initECVs_observ parameters are inconsistent");
+     477           2 :     std::vector<double> obs_vol(all_obs_cvs.size()/ncv); //copy only useful observations
+     478          17 :     for(unsigned t=0; t<obs_vol.size(); t++)
+     479          15 :       obs_vol[t]=all_obs_cvs[t*ncv+index_j+1];
+     480           2 :     const unsigned pres_steps=estimateNumSteps((pres_[0]-pres0_)/kbt_,(pres_[1]-pres0_)/kbt_,obs_vol,"PRESSURE");
+     481           2 :     log.printf("    (spacing is in beta0 units)\n");
+     482           4 :     pres_=getSteps(pres_[0],pres_[1],pres_steps,"PRESSURE",false,0);
+     483           2 :     todoAutomatic_pres_=false;
+     484             :   }
+     485           6 :   initECVs();
+     486           6 :   calculateECVs(&all_obs_cvs[index_j]);
+     487           6 : }
+     488             : 
+     489           3 : void ECVmultiThermalBaric::initECVs_restart(const std::vector<std::string>& lambdas)
+     490             : {
+     491           3 :   std::size_t pos=lambdas[0].find("_");
+     492           3 :   plumed_massert(pos!=std::string::npos,"this should not happen, two CVs are used in "+getName()+", not less");
+     493           3 :   pos=lambdas[0].find("_",pos+1);
+     494           3 :   plumed_massert(pos==std::string::npos,"this should not happen, two CVs are used in "+getName()+", not more");
+     495             : 
+     496         230 :   auto getPres=[&lambdas](const unsigned i) {return lambdas[i].substr(lambdas[i].find("_")+1);};
+     497           3 :   if(todoAutomatic_pres_)
+     498             :   {
+     499             :     unsigned pres_steps=1;
+     500           2 :     std::string pres_min=getPres(0);
+     501          20 :     for(unsigned i=1; i<lambdas.size(); i++) //pres is second, thus increas by 1
+     502             :     {
+     503          20 :       if(getPres(i)==pres_min)
+     504             :         break;
+     505          18 :       pres_steps++;
+     506             :     }
+     507           4 :     pres_=getSteps(pres_[0],pres_[1],pres_steps,"PRESSURE",false,0);
+     508           2 :     todoAutomatic_pres_=false;
+     509             :   }
+     510           3 :   if(todoAutomatic_beta_)
+     511             :   {
+     512             :     unsigned temp_steps=1;
+     513           2 :     std::string pres_max=getPres(pres_.size()-1);
+     514         208 :     for(unsigned i=pres_.size(); i<lambdas.size(); i++)
+     515             :     { //even if CUT_CORNER, the max pressures are all present, for each temp
+     516         206 :       if(getPres(i)==pres_max)
+     517          24 :         temp_steps++;
+     518             :     }
+     519           4 :     derECVs_beta_=getSteps(derECVs_beta_[0],derECVs_beta_[1],temp_steps,"TEMP",geom_spacing_,1./kbt_);
+     520           2 :     todoAutomatic_beta_=false;
+     521             :   }
+     522           3 :   std::vector<std::string> myLambdas=getLambdas();
+     523           3 :   plumed_assert(myLambdas.size()==lambdas.size())<<"RESTART - mismatch in number of "<<getName()<<".\nFrom "<<lambdas.size()<<" labels "<<derECVs_beta_.size()<<" temperatures and "<<pres_.size()<<" pressures were found, for a total of "<<myLambdas.size()<<" estimated steps.\nCheck if the CUT_CORNER or the SET_ALL_TEMP_PRESSURE options are consistent\n";
+     524           3 :   plumed_massert(std::equal(myLambdas.begin(),myLambdas.end(),lambdas.begin()),"RESTART - mismatch in lambda values of "+getName());
+     525             : 
+     526           3 :   initECVs();
+     527           3 : }
+     528             : 
+     529             : }
+     530             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/ECVumbrellasFile.cpp.func-sort-c.html b/coverage/opes/ECVumbrellasFile.cpp.func-sort-c.html new file mode 100644 index 000000000000..d96731757bdd --- /dev/null +++ b/coverage/opes/ECVumbrellasFile.cpp.func-sort-c.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - opes/ECVumbrellasFile.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - opes - ECVumbrellasFile.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11812098.3 %
Date:2024-04-19 12:12:35Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4opes16ECVumbrellasFileC2ERKNS_13ActionOptionsE0
_ZN4PLMD4opes16ECVumbrellasFile16initECVs_restartERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EE1
_ZN4PLMD4opes16ECVumbrellasFile15initECVs_observERKSt6vectorIdSaIdEEjj2
_ZN4PLMD4opes16ECVumbrellasFile8initECVsEv3
_ZN4PLMD4opes16ECVumbrellasFileC1ERKNS_13ActionOptionsE3
_ZNK4PLMD4opes16ECVumbrellasFile10getLambdasB5cxx11Ev3
_ZN4PLMD4opes16ECVumbrellasFile16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD4opes16ECVumbrellasFile13getPntrToECVsEj6
_ZN4PLMD4opes16ECVumbrellasFile16getPntrToDerECVsEj6
_ZN4PLMD4opes16ECVumbrellasFile13calculateECVsEPKd131
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/ECVumbrellasFile.cpp.func.html b/coverage/opes/ECVumbrellasFile.cpp.func.html new file mode 100644 index 000000000000..6f29499cd89c --- /dev/null +++ b/coverage/opes/ECVumbrellasFile.cpp.func.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - opes/ECVumbrellasFile.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - opes - ECVumbrellasFile.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11812098.3 %
Date:2024-04-19 12:12:35Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4opes16ECVumbrellasFile13calculateECVsEPKd131
_ZN4PLMD4opes16ECVumbrellasFile13getPntrToECVsEj6
_ZN4PLMD4opes16ECVumbrellasFile15initECVs_observERKSt6vectorIdSaIdEEjj2
_ZN4PLMD4opes16ECVumbrellasFile16getPntrToDerECVsEj6
_ZN4PLMD4opes16ECVumbrellasFile16initECVs_restartERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EE1
_ZN4PLMD4opes16ECVumbrellasFile16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD4opes16ECVumbrellasFile8initECVsEv3
_ZN4PLMD4opes16ECVumbrellasFileC1ERKNS_13ActionOptionsE3
_ZN4PLMD4opes16ECVumbrellasFileC2ERKNS_13ActionOptionsE0
_ZNK4PLMD4opes16ECVumbrellasFile10getLambdasB5cxx11Ev3
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/ECVumbrellasFile.cpp.gcov.html b/coverage/opes/ECVumbrellasFile.cpp.gcov.html new file mode 100644 index 000000000000..7cc5ca07eb29 --- /dev/null +++ b/coverage/opes/ECVumbrellasFile.cpp.gcov.html @@ -0,0 +1,372 @@ + + + + + + + + LCOV - plumed test coverage - opes/ECVumbrellasFile.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - opes - ECVumbrellasFile.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11812098.3 %
Date:2024-04-19 12:12:35Functions:91090.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2020-2021 of Michele Invernizzi.
+       3             : 
+       4             :    This file is part of the OPES plumed module.
+       5             : 
+       6             :    The OPES plumed module is free software: you can redistribute it and/or modify
+       7             :    it under the terms of the GNU Lesser General Public License as published by
+       8             :    the Free Software Foundation, either version 3 of the License, or
+       9             :    (at your option) any later version.
+      10             : 
+      11             :    The OPES plumed module is distributed in the hope that it will be useful,
+      12             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      13             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      14             :    GNU Lesser General Public License for more details.
+      15             : 
+      16             :    You should have received a copy of the GNU Lesser General Public License
+      17             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      18             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      19             : #include "ExpansionCVs.h"
+      20             : #include "core/ActionRegister.h"
+      21             : #include "tools/File.h"
+      22             : 
+      23             : namespace PLMD {
+      24             : namespace opes {
+      25             : 
+      26             : //+PLUMEDOC OPES_EXPANSION_CV ECV_UMBRELLAS_FILE
+      27             : /*
+      28             : Target a multiumbrella ensemble, by combining systems each with a parabolic bias potential at a different location.
+      29             : 
+      30             : Any set of collective variables \f$\mathbf{s}\f$ can be used as ARG.
+      31             : The positions \f$\mathbf{s}_i\f$ and dimension \f$\mathbf{\sigma}_i\f$ of the umbrellas are read from file.
+      32             : \f[
+      33             :   \Delta u_{\mathbf{s}_i}(\mathbf{s})=\sum_j^{\text{dim}}\frac{([s]_j-[s_i]_j)^2}{2[\sigma_i]_j^2}\, .
+      34             : \f]
+      35             : Notice that \f$\mathbf{\sigma}_i\f$ is diagonal, thus only one SIGMA per CV has to be specified for each umbrella.
+      36             : You can choose the umbrellas manually, or place them on a grid, or along a path, similar to \ref PATH.
+      37             : They must cover all the CV space that one wishes to sample.
+      38             : 
+      39             : The first column of the umbrellas file is always ignored and must be called "time".
+      40             : You can also use as input file a STATE file from an earlier \ref OPES_METAD run (or an \ref OPES_MEAD_EXPLORE run, if you combine it with other ECVs).
+      41             : 
+      42             : Similarly to \ref ECV_UMBRELLAS_LINE, you should set the flag ADD_P0 if you think your umbrellas might not properly cover all the CV region relevant for the unbiased distribution.
+      43             : You can also use BARRIER to set the maximum barrier height to be explored, and avoid huge biases at the beginning of your simulation.
+      44             : See also Appendix B of Ref.\cite Invernizzi2020unified for more details on these last two options.
+      45             : 
+      46             : \par Examples
+      47             : 
+      48             : \plumedfile
+      49             : cv1: DISTANCE ATOMS=1,2
+      50             : cv2: DISTANCE ATOMS=3,4
+      51             : cv3: DISTANCE ATOMS=4,1
+      52             : ecv: ECV_UMBRELLAS_FILE ARG=cv1,cv2,cv3 FILE=Umbrellas.data ADD_P0 BARRIER=70
+      53             : opes: OPES_EXPANDED ARG=ecv.* PACE=500
+      54             : PRINT FILE=COLVAR STRIDE=500 ARG=cv1,cv2,cv3,opes.bias
+      55             : \endplumedfile
+      56             : 
+      57             : The umbrellas file might look like this:
+      58             : \auxfile{Umbrellas.data}
+      59             : #! FIELDS time cv1 cv2 cv3 sigma_cv1 sigma_cv2 sigma_cv3
+      60             : 1  1.17958  2.93697  1.06109  0.19707  0.28275  0.32427
+      61             : 2  2.04023  2.69714  1.84770  0.22307  0.25933  0.31783
+      62             : 3  1.99693  1.10299  1.13351  0.19517  0.26260  0.37427
+      63             : 4  1.15954  1.37447  2.25975  0.20096  0.27168  0.33353
+      64             : 5  1.10126  2.45936  2.40260  0.19747  0.24215  0.35523
+      65             : \endauxfile
+      66             : 
+      67             : */
+      68             : //+ENDPLUMEDOC
+      69             : 
+      70             : class ECVumbrellasFile :
+      71             :   public ExpansionCVs
+      72             : {
+      73             : private:
+      74             :   double barrier_;
+      75             :   unsigned P0_contribution_;
+      76             :   bool lower_only_;
+      77             : 
+      78             :   std::vector< std::vector<double> > centers_;
+      79             :   std::vector< std::vector<double> > sigmas_;
+      80             : 
+      81             :   std::vector< std::vector<double> > ECVs_;
+      82             :   std::vector< std::vector<double> > derECVs_;
+      83             :   void initECVs();
+      84             : 
+      85             : public:
+      86             :   explicit ECVumbrellasFile(const ActionOptions&);
+      87             :   static void registerKeywords(Keywords& keys);
+      88             :   void calculateECVs(const double *) override;
+      89             :   const double * getPntrToECVs(unsigned) override;
+      90             :   const double * getPntrToDerECVs(unsigned) override;
+      91             :   std::vector<std::string> getLambdas() const override;
+      92             :   void initECVs_observ(const std::vector<double>&,const unsigned,const unsigned) override;
+      93             :   void initECVs_restart(const std::vector<std::string>&) override;
+      94             : };
+      95             : 
+      96             : PLUMED_REGISTER_ACTION(ECVumbrellasFile,"ECV_UMBRELLAS_FILE")
+      97             : 
+      98           5 : void ECVumbrellasFile::registerKeywords(Keywords& keys)
+      99             : {
+     100           5 :   ExpansionCVs::registerKeywords(keys);
+     101           5 :   keys.use("ARG");
+     102          10 :   keys.add("compulsory","FILE","the name of the file containing the umbrellas");
+     103          10 :   keys.add("optional","BARRIER","a guess of the free energy barrier to be overcome (better to stay higher than lower)");
+     104          10 :   keys.addFlag("ADD_P0",false,"add the unbiased Boltzmann distribution to the target distribution, to make sure to sample it");
+     105          10 :   keys.addFlag("LOWER_HALF_ONLY",false,"use only the lower half of each umbrella potentials");
+     106           5 : }
+     107             : 
+     108           3 : ECVumbrellasFile::ECVumbrellasFile(const ActionOptions&ao):
+     109             :   Action(ao),
+     110           3 :   ExpansionCVs(ao)
+     111             : {
+     112             : //get number of CVs
+     113             :   const unsigned ncv=getNumberOfArguments();
+     114           3 :   centers_.resize(ncv);
+     115           3 :   sigmas_.resize(ncv);
+     116             : 
+     117             : //set P0_contribution_
+     118           3 :   bool add_P0=false;
+     119           3 :   parseFlag("ADD_P0",add_P0);
+     120           3 :   if(add_P0)
+     121           2 :     P0_contribution_=1;
+     122             :   else
+     123           1 :     P0_contribution_=0;
+     124             : 
+     125             : //set barrier_
+     126           3 :   barrier_=std::numeric_limits<double>::infinity();
+     127           3 :   parse("BARRIER",barrier_);
+     128           6 :   parseFlag("LOWER_HALF_ONLY",lower_only_);
+     129             : 
+     130             : //set umbrellas
+     131             :   std::string umbrellasFileName;
+     132           3 :   parse("FILE",umbrellasFileName);
+     133           3 :   IFile ifile;
+     134           3 :   ifile.link(*this);
+     135           3 :   if(ifile.FileExist(umbrellasFileName))
+     136             :   {
+     137           3 :     log.printf("  reading from FILE '%s'\n",umbrellasFileName.c_str());
+     138           3 :     ifile.open(umbrellasFileName);
+     139           3 :     ifile.allowIgnoredFields();
+     140             :     double time; //first field is ignored
+     141        1332 :     while(ifile.scanField("time",time))
+     142             :     {
+     143        1989 :       for(unsigned j=0; j<ncv; j++)
+     144             :       {
+     145             :         double centers_j;
+     146        1326 :         ifile.scanField(getPntrToArgument(j)->getName(),centers_j);
+     147        1326 :         centers_[j].push_back(centers_j); //this might be slow
+     148             :       }
+     149        1989 :       for(unsigned j=0; j<ncv; j++)
+     150             :       {
+     151             :         double sigmas_j;
+     152        2652 :         ifile.scanField("sigma_"+getPntrToArgument(j)->getName(),sigmas_j);
+     153        1326 :         sigmas_[j].push_back(sigmas_j);
+     154             :       }
+     155         663 :       ifile.scanField();
+     156             :     }
+     157             :   }
+     158             :   else
+     159           0 :     plumed_merror("Umbrellas FILE '"+umbrellasFileName+"' not found");
+     160             : 
+     161           3 :   checkRead();
+     162             : 
+     163             : //extra consistency checks
+     164           3 :   const unsigned sizeUmbrellas=centers_[0].size();
+     165           9 :   for(unsigned j=0; j<ncv; j++)
+     166             :   {
+     167           6 :     plumed_massert(centers_[j].size()==sizeUmbrellas,"mismatch in the number of centers read from file");
+     168           6 :     plumed_massert(sigmas_[j].size()==sizeUmbrellas,"mismatch in the number of sigmas read from file");
+     169             :   }
+     170             : 
+     171             : //set ECVs stuff
+     172           3 :   totNumECVs_=sizeUmbrellas+P0_contribution_;
+     173           3 :   ECVs_.resize(ncv,std::vector<double>(totNumECVs_));
+     174           3 :   derECVs_.resize(ncv,std::vector<double>(totNumECVs_));
+     175             : 
+     176             : //printing some info
+     177           3 :   log.printf("  total number of umbrellas = %u\n",sizeUmbrellas);
+     178           3 :   if(barrier_!=std::numeric_limits<double>::infinity())
+     179           1 :     log.printf("  guess for free energy BARRIER = %g\n",barrier_);
+     180           3 :   if(P0_contribution_==1)
+     181           2 :     log.printf(" -- ADD_P0: the target includes also the unbiased probability itself\n");
+     182           3 :   if(lower_only_)
+     183           1 :     log.printf(" -- LOWER_HALF_ONLY: the ECVs are set to zero for values of the CV above the respective center\n");
+     184           6 : }
+     185             : 
+     186         131 : void ECVumbrellasFile::calculateECVs(const double * cv)
+     187             : {
+     188         131 :   if(lower_only_)
+     189             :   {
+     190         153 :     for(unsigned j=0; j<getNumberOfArguments(); j++)
+     191             :     {
+     192       22644 :       for(unsigned k=P0_contribution_; k<totNumECVs_; k++) //if ADD_P0, the first ECVs=0
+     193             :       {
+     194       22542 :         const unsigned kk=k-P0_contribution_;
+     195       22542 :         const double dist_jk=difference(j,centers_[j][kk],cv[j])/sigmas_[j][kk]; //PBC might be present
+     196       22542 :         if(dist_jk>=0)
+     197             :         {
+     198       11483 :           ECVs_[j][k]=0;
+     199       11483 :           derECVs_[j][k]=0;
+     200             :         }
+     201             :         else
+     202             :         {
+     203       11059 :           ECVs_[j][k]=0.5*std::pow(dist_jk,2);
+     204       11059 :           derECVs_[j][k]=dist_jk/sigmas_[j][kk];
+     205             :         }
+     206             :       }
+     207             :     }
+     208             :   }
+     209             :   else
+     210             :   {
+     211         240 :     for(unsigned j=0; j<getNumberOfArguments(); j++)
+     212             :     {
+     213       35520 :       for(unsigned k=P0_contribution_; k<totNumECVs_; k++) //if ADD_P0, the first ECVs=0
+     214             :       {
+     215       35360 :         const unsigned kk=k-P0_contribution_;
+     216       35360 :         const double dist_jk=difference(j,centers_[j][kk],cv[j])/sigmas_[j][kk]; //PBC might be present
+     217       35360 :         ECVs_[j][k]=0.5*std::pow(dist_jk,2);
+     218       35360 :         derECVs_[j][k]=dist_jk/sigmas_[j][kk];
+     219             :       }
+     220             :     }
+     221             :   }
+     222         131 : }
+     223             : 
+     224           6 : const double * ECVumbrellasFile::getPntrToECVs(unsigned j)
+     225             : {
+     226           6 :   plumed_massert(isReady_,"cannot access ECVs before initialization");
+     227           6 :   plumed_massert(j<getNumberOfArguments(),getName()+" has fewer CVs");
+     228           6 :   return &ECVs_[j][0];
+     229             : }
+     230             : 
+     231           6 : const double * ECVumbrellasFile::getPntrToDerECVs(unsigned j)
+     232             : {
+     233           6 :   plumed_massert(isReady_,"cannot access ECVs before initialization");
+     234           6 :   plumed_massert(j<getNumberOfArguments(),getName()+" has fewer CVs");
+     235           6 :   return &derECVs_[j][0];
+     236             : }
+     237             : 
+     238           3 : std::vector<std::string> ECVumbrellasFile::getLambdas() const
+     239             : { //notice that sigmas are not considered!
+     240           3 :   std::vector<std::string> lambdas(totNumECVs_);
+     241           3 :   if(P0_contribution_==1)
+     242             :   {
+     243           2 :     std::ostringstream subs;
+     244           2 :     subs<<"P0";
+     245           4 :     for(unsigned j=1; j<getNumberOfArguments(); j++)
+     246           2 :       subs<<"_P0";
+     247           2 :     lambdas[0]=subs.str();
+     248           2 :   }
+     249         666 :   for(unsigned k=P0_contribution_; k<totNumECVs_; k++)
+     250             :   {
+     251         663 :     const unsigned kk=k-P0_contribution_;
+     252         663 :     std::ostringstream subs;
+     253         663 :     subs<<centers_[0][kk];
+     254        1326 :     for(unsigned j=1; j<getNumberOfArguments(); j++)
+     255         663 :       subs<<"_"<<centers_[j][kk];
+     256         663 :     lambdas[k]=subs.str();
+     257         663 :   }
+     258           3 :   return lambdas;
+     259           0 : }
+     260             : 
+     261           3 : void ECVumbrellasFile::initECVs()
+     262             : {
+     263           3 :   plumed_massert(!isReady_,"initialization should not be called twice");
+     264           3 :   isReady_=true;
+     265           3 :   log.printf("  *%4u windows for %s\n",totNumECVs_,getName().c_str());
+     266           3 : }
+     267             : 
+     268           2 : void ECVumbrellasFile::initECVs_observ(const std::vector<double>& all_obs_cvs,const unsigned ncv,const unsigned index_j)
+     269             : {
+     270             :   //this non-linear exansion never uses automatic initialization
+     271           2 :   initECVs();
+     272           2 :   calculateECVs(&all_obs_cvs[index_j]); //use only first obs point
+     273           6 :   for(unsigned j=0; j<getNumberOfArguments(); j++)
+     274         888 :     for(unsigned k=P0_contribution_; k<totNumECVs_; k++)
+     275        1680 :       ECVs_[j][k]=std::min(barrier_/kbt_,ECVs_[j][k]);
+     276           2 : }
+     277             : 
+     278           1 : void ECVumbrellasFile::initECVs_restart(const std::vector<std::string>& lambdas)
+     279             : {
+     280             :   std::size_t pos=0;
+     281           2 :   for(unsigned j=0; j<getNumberOfArguments()-1; j++)
+     282           1 :     pos=lambdas[0].find("_",pos+1); //checking only lambdas[0] is hopefully enough
+     283           1 :   plumed_massert(pos<lambdas[0].length(),"this should not happen, fewer '_' than expected in "+getName());
+     284           1 :   pos=lambdas[0].find("_",pos+1);
+     285           1 :   plumed_massert(pos>lambdas[0].length(),"this should not happen, more '_' than expected in "+getName());
+     286             : 
+     287           1 :   std::vector<std::string> myLambdas=getLambdas();
+     288           1 :   plumed_massert(myLambdas.size()==lambdas.size(),"RESTART - mismatch in number of "+getName());
+     289           1 :   plumed_massert(std::equal(myLambdas.begin(),myLambdas.end(),lambdas.begin()),"RESTART - mismatch in lambda values of "+getName());
+     290             : 
+     291           1 :   initECVs();
+     292           1 : }
+     293             : 
+     294             : }
+     295             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/ECVumbrellasLine.cpp.func-sort-c.html b/coverage/opes/ECVumbrellasLine.cpp.func-sort-c.html new file mode 100644 index 000000000000..a7b2996b8558 --- /dev/null +++ b/coverage/opes/ECVumbrellasLine.cpp.func-sort-c.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - opes/ECVumbrellasLine.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - opes - ECVumbrellasLine.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12913198.5 %
Date:2024-04-19 12:12:35Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4opes16ECVumbrellasLineC2ERKNS_13ActionOptionsE0
_ZN4PLMD4opes16ECVumbrellasLine16initECVs_restartERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EE3
_ZN4PLMD4opes16ECVumbrellasLine15initECVs_observERKSt6vectorIdSaIdEEjj5
_ZN4PLMD4opes16ECVumbrellasLine8initECVsEv8
_ZN4PLMD4opes16ECVumbrellasLineC1ERKNS_13ActionOptionsE8
_ZNK4PLMD4opes16ECVumbrellasLine10getLambdasB5cxx11Ev8
_ZN4PLMD4opes16ECVumbrellasLine13getPntrToECVsEj10
_ZN4PLMD4opes16ECVumbrellasLine16getPntrToDerECVsEj10
_ZN4PLMD4opes16ECVumbrellasLine16registerKeywordsERNS_8KeywordsE10
_ZN4PLMD4opes16ECVumbrellasLine13calculateECVsEPKd433
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/ECVumbrellasLine.cpp.func.html b/coverage/opes/ECVumbrellasLine.cpp.func.html new file mode 100644 index 000000000000..d2ac3c01eb1d --- /dev/null +++ b/coverage/opes/ECVumbrellasLine.cpp.func.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - opes/ECVumbrellasLine.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - opes - ECVumbrellasLine.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12913198.5 %
Date:2024-04-19 12:12:35Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4opes16ECVumbrellasLine13calculateECVsEPKd433
_ZN4PLMD4opes16ECVumbrellasLine13getPntrToECVsEj10
_ZN4PLMD4opes16ECVumbrellasLine15initECVs_observERKSt6vectorIdSaIdEEjj5
_ZN4PLMD4opes16ECVumbrellasLine16getPntrToDerECVsEj10
_ZN4PLMD4opes16ECVumbrellasLine16initECVs_restartERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EE3
_ZN4PLMD4opes16ECVumbrellasLine16registerKeywordsERNS_8KeywordsE10
_ZN4PLMD4opes16ECVumbrellasLine8initECVsEv8
_ZN4PLMD4opes16ECVumbrellasLineC1ERKNS_13ActionOptionsE8
_ZN4PLMD4opes16ECVumbrellasLineC2ERKNS_13ActionOptionsE0
_ZNK4PLMD4opes16ECVumbrellasLine10getLambdasB5cxx11Ev8
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/ECVumbrellasLine.cpp.gcov.html b/coverage/opes/ECVumbrellasLine.cpp.gcov.html new file mode 100644 index 000000000000..fd34dae79de7 --- /dev/null +++ b/coverage/opes/ECVumbrellasLine.cpp.gcov.html @@ -0,0 +1,378 @@ + + + + + + + + LCOV - plumed test coverage - opes/ECVumbrellasLine.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - opes - ECVumbrellasLine.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12913198.5 %
Date:2024-04-19 12:12:35Functions:91090.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2020-2021 of Michele Invernizzi.
+       3             : 
+       4             :    This file is part of the OPES plumed module.
+       5             : 
+       6             :    The OPES plumed module is free software: you can redistribute it and/or modify
+       7             :    it under the terms of the GNU Lesser General Public License as published by
+       8             :    the Free Software Foundation, either version 3 of the License, or
+       9             :    (at your option) any later version.
+      10             : 
+      11             :    The OPES plumed module is distributed in the hope that it will be useful,
+      12             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      13             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      14             :    GNU Lesser General Public License for more details.
+      15             : 
+      16             :    You should have received a copy of the GNU Lesser General Public License
+      17             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      18             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      19             : #include "ExpansionCVs.h"
+      20             : #include "core/ActionRegister.h"
+      21             : 
+      22             : namespace PLMD {
+      23             : namespace opes {
+      24             : 
+      25             : //+PLUMEDOC OPES_EXPANSION_CV ECV_UMBRELLAS_LINE
+      26             : /*
+      27             : Target a multiumbrella ensemble, by combining systems each with a parabolic bias potential at a different location.
+      28             : 
+      29             : Any set of collective variables \f$\mathbf{s}\f$ can be used as ARG.
+      30             : \f[
+      31             :   \Delta u_{\mathbf{s}_i}(\mathbf{s})=\sum_j^{\text{dim}}\frac{([s]_j-[s_i]_j)^2}{2\sigma^2}\, .
+      32             : \f]
+      33             : The Gaussian umbrellas are placed along a line, from CV_MIN to CV_MAX.
+      34             : The umbrellas are placed at a distance SIGMA*SPACING from each other, if you need more flexibility use \ref ECV_UMBRELLAS_FILE.
+      35             : The unbiased fluctuations in the basin usually are a reasonable guess for the value of SIGMA.
+      36             : Typically, a SPACING greater than 1 can lead to faster convergence, by reducing the total number of umbrellas.
+      37             : The umbrellas can be multidimensional, but the CVs dimensions should be rescaled since a single SIGMA must be used.
+      38             : 
+      39             : The keyword BARRIER can be helpful to avoid breaking your system due to a too strong initial bias.
+      40             : If you think the placed umbrellas will not cover the whole unbiased probability distribution you should add it explicitly to the target, with the flag ADD_P0, for more robust convergence.
+      41             : See also Appendix B of Ref.\cite Invernizzi2020unified for more details on these last two options.
+      42             : 
+      43             : The flag LOWER_HALF_ONLY modifies the ECVs so that they are set to zero when \f$\mathbf{s}>\mathbf{s}_i\f$, as in \ref LOWER_WALLS.
+      44             : This can be useful e.g. when the CV used is the \ref ENERGY and one wants to sample a broad range of high energy values, similar to \ref ECV_MULTITHERMAL but with a flat energy distribution as target.
+      45             : By pushing only from below one can avoid too extreme forces that could crash the simulation.
+      46             : 
+      47             : \par Examples
+      48             : 
+      49             : \plumedfile
+      50             : cv: DISTANCE ATOMS=1,2
+      51             : ecv: ECV_UMBRELLAS_LINE ARG=cv CV_MIN=1.2 CV_MAX=4.3 SIGMA=0.5 SPACING=1.5
+      52             : opes: OPES_EXPANDED ARG=ecv.* PACE=500
+      53             : \endplumedfile
+      54             : 
+      55             : It is also possible to combine different ECV_UMBRELLAS_LINE to build a grid of CV values that will be sampled.
+      56             : For example the following code will sample a whole 2D region of cv1 and cv2.
+      57             : 
+      58             : \plumedfile
+      59             : cv1: DISTANCE ATOMS=1,2
+      60             : ecv2: ECV_UMBRELLAS_LINE ARG=cv1 CV_MIN=1.2 CV_MAX=4.3 SIGMA=0.5
+      61             : 
+      62             : cv2: DISTANCE ATOMS=3,4
+      63             : ecv1: ECV_UMBRELLAS_LINE ARG=cv2 CV_MIN=13.8 CV_MAX=21.4 SIGMA=4.3
+      64             : 
+      65             : opes: OPES_EXPANDED ARG=ecv1.*,ecv2.* PACE=500
+      66             : \endplumedfile
+      67             : 
+      68             : */
+      69             : //+ENDPLUMEDOC
+      70             : 
+      71             : class ECVumbrellasLine :
+      72             :   public ExpansionCVs
+      73             : {
+      74             : private:
+      75             :   double barrier_;
+      76             :   unsigned P0_contribution_;
+      77             :   bool lower_only_;
+      78             : 
+      79             :   std::vector< std::vector<double> > centers_;
+      80             :   double sigma_;
+      81             : 
+      82             :   std::vector< std::vector<double> > ECVs_;
+      83             :   std::vector< std::vector<double> > derECVs_;
+      84             :   void initECVs();
+      85             : 
+      86             : public:
+      87             :   explicit ECVumbrellasLine(const ActionOptions&);
+      88             :   static void registerKeywords(Keywords& keys);
+      89             :   void calculateECVs(const double *) override;
+      90             :   const double * getPntrToECVs(unsigned) override;
+      91             :   const double * getPntrToDerECVs(unsigned) override;
+      92             :   std::vector<std::string> getLambdas() const override;
+      93             :   void initECVs_observ(const std::vector<double>&,const unsigned,const unsigned) override;
+      94             :   void initECVs_restart(const std::vector<std::string>&) override;
+      95             : };
+      96             : 
+      97             : PLUMED_REGISTER_ACTION(ECVumbrellasLine,"ECV_UMBRELLAS_LINE")
+      98             : 
+      99          10 : void ECVumbrellasLine::registerKeywords(Keywords& keys)
+     100             : {
+     101          10 :   ExpansionCVs::registerKeywords(keys);
+     102          10 :   keys.use("ARG");
+     103          20 :   keys.add("compulsory","CV_MIN","the minimum of the CV range to be explored");
+     104          20 :   keys.add("compulsory","CV_MAX","the maximum of the CV range to be explored");
+     105          20 :   keys.add("compulsory","SIGMA","sigma of the umbrella Gaussians");
+     106          20 :   keys.add("compulsory","SPACING","1","the distance between umbrellas, in units of SIGMA");
+     107          20 :   keys.add("optional","BARRIER","a guess of the free energy barrier to be overcome (better to stay higher than lower)");
+     108          20 :   keys.addFlag("ADD_P0",false,"add the unbiased Boltzmann distribution to the target distribution, to make sure to sample it");
+     109          20 :   keys.addFlag("LOWER_HALF_ONLY",false,"use only the lower half of each umbrella potentials");
+     110          10 : }
+     111             : 
+     112           8 : ECVumbrellasLine::ECVumbrellasLine(const ActionOptions&ao):
+     113             :   Action(ao),
+     114           8 :   ExpansionCVs(ao)
+     115             : {
+     116             : //set P0_contribution_
+     117           8 :   bool add_P0=false;
+     118           8 :   parseFlag("ADD_P0",add_P0);
+     119           8 :   if(add_P0)
+     120           2 :     P0_contribution_=1;
+     121             :   else
+     122           6 :     P0_contribution_=0;
+     123             : 
+     124             : //set barrier_
+     125           8 :   barrier_=std::numeric_limits<double>::infinity();
+     126           8 :   parse("BARRIER",barrier_);
+     127           8 :   parseFlag("LOWER_HALF_ONLY",lower_only_);
+     128             : 
+     129             : //set umbrellas
+     130          16 :   parse("SIGMA",sigma_);
+     131             :   std::vector<double> cv_min;
+     132             :   std::vector<double> cv_max;
+     133           8 :   parseVector("CV_MIN",cv_min);
+     134          16 :   parseVector("CV_MAX",cv_max);
+     135           8 :   plumed_massert(cv_min.size()==getNumberOfArguments(),"wrong number of CV_MINs");
+     136           8 :   plumed_massert(cv_max.size()==getNumberOfArguments(),"wrong number of CV_MAXs");
+     137             :   double spacing;
+     138           8 :   parse("SPACING",spacing);
+     139             :   double length=0;
+     140          18 :   for(unsigned j=0; j<getNumberOfArguments(); j++)
+     141          10 :     length+=std::pow(cv_max[j]-cv_min[j],2);
+     142           8 :   length=std::sqrt(length);
+     143           8 :   unsigned sizeUmbrellas=1+std::round(length/(sigma_*spacing));
+     144           8 :   centers_.resize(getNumberOfArguments()); //centers_[cv][umbrellas]
+     145             :   unsigned full_period=0;
+     146          18 :   for(unsigned j=0; j<getNumberOfArguments(); j++)
+     147             :   {
+     148          10 :     centers_[j].resize(sizeUmbrellas);
+     149          10 :     if(sizeUmbrellas>1)
+     150         140 :       for(unsigned k=0; k<sizeUmbrellas; k++)
+     151         130 :         centers_[j][k]=cv_min[j]+k*(cv_max[j]-cv_min[j])/(sizeUmbrellas-1);
+     152             :     else
+     153           0 :       centers_[j][0]=(cv_min[j]+cv_max[j])/2.;
+     154          10 :     if(getPntrToArgument(j)->isPeriodic())
+     155             :     {
+     156             :       double min,max;
+     157             :       std::string min_str,max_str;
+     158          10 :       getPntrToArgument(j)->getDomain(min,max);
+     159          10 :       getPntrToArgument(j)->getDomain(min_str,max_str);
+     160          10 :       plumed_massert(cv_min[j]>=min,"ARG "+std::to_string(j)+": CV_MIN cannot be smaller than the periodic bound "+min_str);
+     161          10 :       plumed_massert(cv_max[j]<=max,"ARG "+std::to_string(j)+": CV_MAX cannot be greater than the periodic bound "+max_str);
+     162          10 :       if(cv_min[j]==min && cv_max[j]==max)
+     163           6 :         full_period++;
+     164             :     }
+     165             :   }
+     166           8 :   if(full_period==getNumberOfArguments() && sizeUmbrellas>1) //first and last are the same point
+     167             :   {
+     168           6 :     sizeUmbrellas--;
+     169          12 :     for(unsigned j=0; j<getNumberOfArguments(); j++)
+     170           6 :       centers_[j].pop_back();
+     171             :   }
+     172             : 
+     173           8 :   checkRead();
+     174             : 
+     175             : //set ECVs stuff
+     176           8 :   totNumECVs_=sizeUmbrellas+P0_contribution_;
+     177           8 :   ECVs_.resize(getNumberOfArguments(),std::vector<double>(totNumECVs_));
+     178           8 :   derECVs_.resize(getNumberOfArguments(),std::vector<double>(totNumECVs_));
+     179             : 
+     180             : //printing some info
+     181           8 :   log.printf("  total number of umbrellas = %u\n",sizeUmbrellas);
+     182           8 :   log.printf("    with SIGMA = %g\n",sigma_);
+     183           8 :   log.printf("    and SPACING = %g\n",spacing);
+     184           8 :   if(barrier_!=std::numeric_limits<double>::infinity())
+     185           2 :     log.printf("  guess for free energy BARRIER = %g\n",barrier_);
+     186           8 :   if(P0_contribution_==1)
+     187           2 :     log.printf(" -- ADD_P0: the target includes also the unbiased probability itself\n");
+     188           8 :   if(lower_only_)
+     189           1 :     log.printf(" -- LOWER_HALF_ONLY: the ECVs are set to zero for values of the CV above the respective center\n");
+     190           8 : }
+     191             : 
+     192         433 : void ECVumbrellasLine::calculateECVs(const double * cv)
+     193             : {
+     194         433 :   if(lower_only_)
+     195             :   {
+     196         153 :     for(unsigned j=0; j<getNumberOfArguments(); j++)
+     197             :     {
+     198        2040 :       for(unsigned k=P0_contribution_; k<totNumECVs_; k++) //if ADD_P0, the first ECVs=0
+     199             :       {
+     200        1938 :         const unsigned kk=k-P0_contribution_;
+     201        1938 :         const double dist_jk=difference(j,centers_[j][kk],cv[j])/sigma_; //PBC might be present
+     202        1938 :         if(dist_jk>=0)
+     203             :         {
+     204         933 :           ECVs_[j][k]=0;
+     205         933 :           derECVs_[j][k]=0;
+     206             :         }
+     207             :         else
+     208             :         {
+     209        1005 :           ECVs_[j][k]=0.5*std::pow(dist_jk,2);
+     210        1005 :           derECVs_[j][k]=dist_jk/sigma_;
+     211             :         }
+     212             :       }
+     213             :     }
+     214             :   }
+     215             :   else
+     216             :   {
+     217         804 :     for(unsigned j=0; j<getNumberOfArguments(); j++)
+     218             :     {
+     219        4678 :       for(unsigned k=P0_contribution_; k<totNumECVs_; k++) //if ADD_P0, the first ECVs=0
+     220             :       {
+     221        4256 :         const unsigned kk=k-P0_contribution_;
+     222        4256 :         const double dist_jk=difference(j,centers_[j][kk],cv[j])/sigma_; //PBC might be present
+     223        4256 :         ECVs_[j][k]=0.5*std::pow(dist_jk,2);
+     224        4256 :         derECVs_[j][k]=dist_jk/sigma_;
+     225             :       }
+     226             :     }
+     227             :   }
+     228         433 : }
+     229             : 
+     230          10 : const double * ECVumbrellasLine::getPntrToECVs(unsigned j)
+     231             : {
+     232          10 :   plumed_massert(isReady_,"cannot access ECVs before initialization");
+     233          10 :   plumed_massert(j<getNumberOfArguments(),getName()+" has fewer CVs");
+     234          10 :   return &ECVs_[j][0];
+     235             : }
+     236             : 
+     237          10 : const double * ECVumbrellasLine::getPntrToDerECVs(unsigned j)
+     238             : {
+     239          10 :   plumed_massert(isReady_,"cannot access ECVs before initialization");
+     240          10 :   plumed_massert(j<getNumberOfArguments(),getName()+" has fewer CVs");
+     241          10 :   return &derECVs_[j][0];
+     242             : }
+     243             : 
+     244           8 : std::vector<std::string> ECVumbrellasLine::getLambdas() const
+     245             : {
+     246           8 :   std::vector<std::string> lambdas(totNumECVs_);
+     247           8 :   if(P0_contribution_==1)
+     248             :   {
+     249           2 :     std::ostringstream subs;
+     250           2 :     subs<<"P0";
+     251           4 :     for(unsigned j=1; j<getNumberOfArguments(); j++)
+     252           2 :       subs<<"_P0";
+     253           2 :     lambdas[0]=subs.str();
+     254           2 :   }
+     255          94 :   for(unsigned k=P0_contribution_; k<totNumECVs_; k++)
+     256             :   {
+     257          86 :     const unsigned kk=k-P0_contribution_;
+     258          86 :     std::ostringstream subs;
+     259          86 :     subs<<centers_[0][kk];
+     260         124 :     for(unsigned j=1; j<getNumberOfArguments(); j++)
+     261          38 :       subs<<"_"<<centers_[j][kk];
+     262          86 :     lambdas[k]=subs.str();
+     263          86 :   }
+     264           8 :   return lambdas;
+     265           0 : }
+     266             : 
+     267           8 : void ECVumbrellasLine::initECVs()
+     268             : {
+     269           8 :   plumed_massert(!isReady_,"initialization should not be called twice");
+     270           8 :   isReady_=true;
+     271           8 :   log.printf("  *%4u windows for %s\n",totNumECVs_,getName().c_str());
+     272           8 : }
+     273             : 
+     274           5 : void ECVumbrellasLine::initECVs_observ(const std::vector<double>& all_obs_cvs,const unsigned ncv,const unsigned index_j)
+     275             : {
+     276             :   //this non-linear exansion never uses automatic initialization
+     277           5 :   initECVs();
+     278           5 :   calculateECVs(&all_obs_cvs[index_j]); //use only first obs point
+     279          11 :   for(unsigned j=0; j<getNumberOfArguments(); j++)
+     280          76 :     for(unsigned k=P0_contribution_; k<totNumECVs_; k++)
+     281         123 :       ECVs_[j][k]=std::min(barrier_/kbt_,ECVs_[j][k]);
+     282           5 : }
+     283             : 
+     284           3 : void ECVumbrellasLine::initECVs_restart(const std::vector<std::string>& lambdas)
+     285             : {
+     286             :   std::size_t pos=0;
+     287           4 :   for(unsigned j=0; j<getNumberOfArguments()-1; j++)
+     288           1 :     pos=lambdas[0].find("_",pos+1); //checking only lambdas[0] is hopefully enough
+     289           3 :   plumed_massert(pos<lambdas[0].length(),"this should not happen, fewer '_' than expected in "+getName());
+     290           3 :   pos=lambdas[0].find("_",pos+1);
+     291           3 :   plumed_massert(pos>lambdas[0].length(),"this should not happen, more '_' than expected in "+getName());
+     292             : 
+     293           3 :   std::vector<std::string> myLambdas=getLambdas();
+     294           3 :   plumed_massert(myLambdas.size()==lambdas.size(),"RESTART - mismatch in number of "+getName());
+     295           3 :   plumed_massert(std::equal(myLambdas.begin(),myLambdas.end(),lambdas.begin()),"RESTART - mismatch in lambda values of "+getName());
+     296             : 
+     297           3 :   initECVs();
+     298           3 : }
+     299             : 
+     300             : }
+     301             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/ExpansionCVs.cpp.func-sort-c.html b/coverage/opes/ExpansionCVs.cpp.func-sort-c.html new file mode 100644 index 000000000000..00992a96ef3b --- /dev/null +++ b/coverage/opes/ExpansionCVs.cpp.func-sort-c.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - opes/ExpansionCVs.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - opes - ExpansionCVs.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:9610492.3 %
Date:2024-04-19 12:12:35Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4opes12ExpansionCVsC1ERKNS_13ActionOptionsE0
_ZNK4PLMD4opes12ExpansionCVs16estimateNumStepsEddRKSt6vectorIdSaIdEERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE6
_ZZNK4PLMD4opes12ExpansionCVs16estimateNumStepsEddRKSt6vectorIdSaIdEERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEENKUldS6_E_clEdS6_9
_ZNK4PLMD4opes12ExpansionCVs8getStepsEddjRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbd24
_ZNK4PLMD4opes12ExpansionCVs10getIndex_kEv26
_ZN4PLMD4opes12ExpansionCVsC2ERKNS_13ActionOptionsE37
_ZN4PLMD4opes12ExpansionCVs16registerKeywordsERNS_8KeywordsE49
_ZZZNK4PLMD4opes12ExpansionCVs16estimateNumStepsEddRKSt6vectorIdSaIdEERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEENKUldS6_E_clEdS6_ENKUldS6_E_clEdS6_109
_ZN4PLMD4opes12ExpansionCVs5applyEv1847
_ZN4PLMD4opes12ExpansionCVs9calculateEv1847
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/ExpansionCVs.cpp.func.html b/coverage/opes/ExpansionCVs.cpp.func.html new file mode 100644 index 000000000000..93d76f821371 --- /dev/null +++ b/coverage/opes/ExpansionCVs.cpp.func.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - opes/ExpansionCVs.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - opes - ExpansionCVs.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:9610492.3 %
Date:2024-04-19 12:12:35Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4opes12ExpansionCVs16registerKeywordsERNS_8KeywordsE49
_ZN4PLMD4opes12ExpansionCVs5applyEv1847
_ZN4PLMD4opes12ExpansionCVs9calculateEv1847
_ZN4PLMD4opes12ExpansionCVsC1ERKNS_13ActionOptionsE0
_ZN4PLMD4opes12ExpansionCVsC2ERKNS_13ActionOptionsE37
_ZNK4PLMD4opes12ExpansionCVs10getIndex_kEv26
_ZNK4PLMD4opes12ExpansionCVs16estimateNumStepsEddRKSt6vectorIdSaIdEERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE6
_ZNK4PLMD4opes12ExpansionCVs8getStepsEddjRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbd24
_ZZNK4PLMD4opes12ExpansionCVs16estimateNumStepsEddRKSt6vectorIdSaIdEERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEENKUldS6_E_clEdS6_9
_ZZZNK4PLMD4opes12ExpansionCVs16estimateNumStepsEddRKSt6vectorIdSaIdEERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEENKUldS6_E_clEdS6_ENKUldS6_E_clEdS6_109
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/ExpansionCVs.cpp.gcov.html b/coverage/opes/ExpansionCVs.cpp.gcov.html new file mode 100644 index 000000000000..b299e397e60b --- /dev/null +++ b/coverage/opes/ExpansionCVs.cpp.gcov.html @@ -0,0 +1,299 @@ + + + + + + + + LCOV - plumed test coverage - opes/ExpansionCVs.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - opes - ExpansionCVs.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:9610492.3 %
Date:2024-04-19 12:12:35Functions:91090.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2020-2021 of Michele Invernizzi.
+       3             : 
+       4             :    This file is part of the OPES plumed module.
+       5             : 
+       6             :    The OPES plumed module is free software: you can redistribute it and/or modify
+       7             :    it under the terms of the GNU Lesser General Public License as published by
+       8             :    the Free Software Foundation, either version 3 of the License, or
+       9             :    (at your option) any later version.
+      10             : 
+      11             :    The OPES plumed module is distributed in the hope that it will be useful,
+      12             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      13             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      14             :    GNU Lesser General Public License for more details.
+      15             : 
+      16             :    You should have received a copy of the GNU Lesser General Public License
+      17             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      18             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      19             : #include "ExpansionCVs.h"
+      20             : 
+      21             : #include "tools/OpenMP.h"
+      22             : 
+      23             : namespace PLMD {
+      24             : namespace opes {
+      25             : 
+      26          49 : void ExpansionCVs::registerKeywords(Keywords& keys)
+      27             : {
+      28          49 :   Action::registerKeywords(keys);
+      29          49 :   ActionWithValue::registerKeywords(keys);
+      30          49 :   ActionWithArguments::registerKeywords(keys);
+      31          49 :   ActionWithValue::useCustomisableComponents(keys);
+      32          98 :   keys.add("compulsory","TEMP","-1","temperature. If not specified tries to get it from MD engine");
+      33          49 : }
+      34             : 
+      35          37 : ExpansionCVs::ExpansionCVs(const ActionOptions&ao)
+      36             :   : Action(ao)
+      37             :   , ActionWithValue(ao)
+      38             :   , ActionWithArguments(ao)
+      39          37 :   , isReady_(false)
+      40          37 :   , totNumECVs_(0)
+      41             : {
+      42             : //set kbt_
+      43          37 :   const double kB=getKBoltzmann();
+      44          37 :   kbt_=getkBT();
+      45          37 :   log.printf("  temperature = %g, beta = %g\n",kbt_/kB,1./kbt_);
+      46             : 
+      47             : //set components
+      48          37 :   plumed_massert( getNumberOfArguments()!=0, "you must specify the underlying CV");
+      49          90 :   for(unsigned j=0; j<getNumberOfArguments(); j++)
+      50             :   {
+      51          53 :     std::string name_j=getPntrToArgument(j)->getName();
+      52          53 :     ActionWithValue::addComponentWithDerivatives(name_j);
+      53          53 :     getPntrToComponent(j)->resizeDerivatives(1);
+      54          53 :     if(getPntrToArgument(j)->isPeriodic()) //it should not be necessary, but why not
+      55             :     {
+      56             :       std::string min,max;
+      57          17 :       getPntrToArgument(j)->getDomain(min,max);
+      58          17 :       getPntrToComponent(j)->setDomain(min,max);
+      59             :     }
+      60             :     else
+      61          36 :       getPntrToComponent(j)->setNotPeriodic();
+      62             :   }
+      63          37 :   plumed_massert((int)getNumberOfArguments()==getNumberOfComponents(),"Expansion CVs have same number of arguments and components");
+      64          37 : }
+      65             : 
+      66        1847 : void ExpansionCVs::calculate()
+      67             : {
+      68        1847 :   std::vector<double> args(getNumberOfArguments());
+      69        4470 :   for(unsigned j=0; j<getNumberOfArguments(); j++)
+      70             :   {
+      71        2623 :     args[j]=getArgument(j);
+      72        2623 :     getPntrToComponent(j)->set(args[j]); //components are equal to arguments
+      73        2623 :     getPntrToComponent(j)->addDerivative(0,1.); //the derivative of the identity is 1
+      74             :   }
+      75        1847 :   if(isReady_)
+      76        1417 :     calculateECVs(&args[0]);
+      77        1847 : }
+      78             : 
+      79        1847 : void ExpansionCVs::apply()
+      80             : {
+      81        4470 :   for(unsigned j=0; j<getNumberOfArguments(); j++)
+      82             :   {
+      83        2623 :     std::vector<double> force_j(1);
+      84        2623 :     if(getPntrToComponent(j)->applyForce(force_j)) //a bias is applied?
+      85        2623 :       getPntrToArgument(j)->addForce(force_j[0]); //just tell it to the CV!
+      86             :   }
+      87        1847 : }
+      88             : 
+      89          26 : std::vector< std::vector<unsigned> > ExpansionCVs::getIndex_k() const
+      90             : {
+      91          26 :   plumed_massert(isReady_ && totNumECVs_>0,"cannot access getIndex_k() of ECV before initialization");
+      92          26 :   std::vector< std::vector<unsigned> > index_k(totNumECVs_,std::vector<unsigned>(getNumberOfArguments()));
+      93         869 :   for(unsigned k=0; k<totNumECVs_; k++)
+      94        2391 :     for(unsigned j=0; j<getNumberOfArguments(); j++)
+      95        1548 :       index_k[k][j]=k; //each CV gives rise to the same number of ECVs
+      96          26 :   return index_k;
+      97           0 : }
+      98             : 
+      99             : //following methods are meant to be used only in case of linear expansions
+     100          24 : std::vector<double> ExpansionCVs::getSteps(double lambda_min,double lambda_max,const unsigned lambda_steps,const std::string& msg,const bool geom_spacing, const double shift) const
+     101             : {
+     102          24 :   plumed_massert(!(lambda_min==lambda_max && lambda_steps>1),"cannot have multiple "+msg+"_STEPS if "+msg+"_MIN=="+msg+"_MAX");
+     103          24 :   std::vector<double> lambda(lambda_steps);
+     104          24 :   if(lambda_steps==1)
+     105             :   {
+     106           0 :     lambda[0]=(lambda_min+lambda_max)/2.;
+     107           0 :     log.printf(" +++ WARNING +++ using one single %s as target = %g\n",msg.c_str(),lambda[0]);
+     108             :   }
+     109             :   else
+     110             :   {
+     111          24 :     if(geom_spacing) //geometric spacing
+     112             :     { //this way lambda[k]/lambda[k+1] is constant
+     113          14 :       lambda_min+=shift;
+     114          14 :       lambda_max+=shift;
+     115          14 :       plumed_massert(lambda_min>0,"cannot use GEOM_SPACING when %s_MIN is not greater than zero");
+     116          14 :       plumed_massert(lambda_max>0,"cannot use GEOM_SPACING when %s_MAX is not greater than zero");
+     117          14 :       const double log_lambda_min=std::log(lambda_min);
+     118          14 :       const double log_lambda_max=std::log(lambda_max);
+     119         196 :       for(unsigned k=0; k<lambda.size(); k++)
+     120         182 :         lambda[k]=std::exp(log_lambda_min+k*(log_lambda_max-log_lambda_min)/(lambda_steps-1))-shift;
+     121             :     }
+     122             :     else //linear spacing
+     123         108 :       for(unsigned k=0; k<lambda.size(); k++)
+     124          98 :         lambda[k]=lambda_min+k*(lambda_max-lambda_min)/(lambda_steps-1);
+     125             :   }
+     126          24 :   return lambda;
+     127             : }
+     128             : 
+     129           6 : unsigned ExpansionCVs::estimateNumSteps(const double left_side,const double right_side,const std::vector<double>& obs,const std::string& msg) const
+     130             : { //for linear expansions only, it uses effective sample size (Neff) to estimate the grid spacing
+     131           6 :   if(left_side==0 && right_side==0)
+     132             :   {
+     133           0 :     log.printf(" +++ WARNING +++ %s_MIN and %s_MAX are equal to %s, using single step\n",msg.c_str(),msg.c_str(),msg.c_str());
+     134           0 :     return 1;
+     135             :   }
+     136           9 :   auto get_neff_HWHM=[](const double side,const std::vector<double>& obs) //HWHM = half width at half maximum. neff is in general not symmetric
+     137             :   {
+     138             :     //func: Neff/N-0.5 is a function between -0.5 and 0.5
+     139         109 :     auto func=[](const double delta,const std::vector<double>& obs)
+     140             :     {
+     141             :       double sum_w=0;
+     142             :       double sum_w2=0;
+     143             :       //we could avoid recomputing safe_shift every time, but here speed is not a concern
+     144         218 :       const double safe_shift=delta<0?*std::max_element(obs.begin(),obs.end()):*std::min_element(obs.begin(),obs.end());
+     145         899 :       for(unsigned t=0; t<obs.size(); t++)
+     146             :       {
+     147         790 :         const double w=std::exp(-delta*(obs[t]-safe_shift)); //robust to overflow
+     148         790 :         sum_w+=w;
+     149         790 :         sum_w2+=w*w;
+     150             :       }
+     151         109 :       return sum_w*sum_w/sum_w2/obs.size()-0.5;
+     152             :     };
+     153             :     //here we find the root of func using the regula falsi (false position) method
+     154             :     //but any method would be OK, not much precision is needed. src/tools/RootFindingBase.h looked complicated
+     155             :     const double tolerance=1e-4; //seems to be a good default
+     156             :     double a=0; //default is right side case
+     157             :     double func_a=0.5;
+     158             :     double b=side;
+     159           9 :     double func_b=func(side,obs);
+     160           9 :     if(func_b>=0)
+     161             :       return 0.0; //no zero is present!
+     162           9 :     if(b<0) //left side case
+     163             :     {
+     164             :       std::swap(a,b);
+     165             :       std::swap(func_a,func_b);
+     166             :     }
+     167             :     double c=a;
+     168             :     double func_c=func_a;
+     169         109 :     while(std::abs(func_c)>tolerance)
+     170             :     {
+     171         100 :       if(func_a*func_c>0)
+     172             :       {
+     173             :         a=c;
+     174             :         func_a=func_c;
+     175             :       }
+     176             :       else
+     177             :       {
+     178             :         b=c;
+     179             :         func_b=func_c;
+     180             :       }
+     181         100 :       c=(a*func_b-b*func_a)/(func_b-func_a);
+     182         100 :       func_c=func(c,obs); //func is evaluated only here, it might be expensive
+     183             :     }
+     184           9 :     return std::abs(c);
+     185             :   };
+     186             : 
+     187             : //estimation
+     188             :   double left_HWHM=0;
+     189           6 :   if(left_side!=0)
+     190           4 :     left_HWHM=get_neff_HWHM(left_side,obs);
+     191             :   double right_HWHM=0;
+     192           6 :   if(right_side!=0)
+     193           5 :     right_HWHM=get_neff_HWHM(right_side,obs);
+     194           6 :   if(left_HWHM==0)
+     195             :   {
+     196           2 :     right_HWHM*=2;
+     197           2 :     if(left_side==0)
+     198           2 :       log.printf(" --- %s_MIN is equal to %s\n",msg.c_str(),msg.c_str());
+     199             :     else
+     200           0 :       log.printf(" +++ WARNING +++ %s_MIN is very close to %s\n",msg.c_str(),msg.c_str());
+     201             :   }
+     202           6 :   if(right_HWHM==0)
+     203             :   {
+     204           1 :     left_HWHM*=2;
+     205           1 :     if(right_side==0)
+     206           1 :       log.printf(" --- %s_MAX is equal to %s\n",msg.c_str(),msg.c_str());
+     207             :     else
+     208           0 :       log.printf(" +++ WARNING +++ %s_MAX is very close to %s\n",msg.c_str(),msg.c_str());
+     209             :   }
+     210           6 :   const double grid_spacing=left_HWHM+right_HWHM;
+     211           6 :   log.printf("   estimated %s spacing = %g\n",msg.c_str(),grid_spacing);
+     212           6 :   unsigned steps=std::ceil(std::abs(right_side-left_side)/grid_spacing);
+     213           6 :   if(steps<2 || grid_spacing==0)
+     214             :   {
+     215           0 :     log.printf(" +++ WARNING +++ %s range is very narrow, using %s_MIN and %s_MAX as only steps\n",msg.c_str(),msg.c_str(),msg.c_str());
+     216             :     steps=2;
+     217             :   }
+     218             :   return steps;
+     219             : }
+     220             : 
+     221             : }
+     222             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/ExpansionCVs.h.func-sort-c.html b/coverage/opes/ExpansionCVs.h.func-sort-c.html new file mode 100644 index 000000000000..ac6c7461ebb0 --- /dev/null +++ b/coverage/opes/ExpansionCVs.h.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - opes/ExpansionCVs.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - opes - ExpansionCVs.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:44100.0 %
Date:2024-04-19 12:12:35Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4opes12ExpansionCVsD2Ev37
_ZNK4PLMD4opes12ExpansionCVs13getTotNumECVsEv50
_ZN4PLMD4opes12ExpansionCVs22getNumberOfDerivativesEv138
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/ExpansionCVs.h.func.html b/coverage/opes/ExpansionCVs.h.func.html new file mode 100644 index 000000000000..04f4ee9242fe --- /dev/null +++ b/coverage/opes/ExpansionCVs.h.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - opes/ExpansionCVs.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - opes - ExpansionCVs.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:44100.0 %
Date:2024-04-19 12:12:35Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4opes12ExpansionCVs22getNumberOfDerivativesEv138
_ZN4PLMD4opes12ExpansionCVsD2Ev37
_ZNK4PLMD4opes12ExpansionCVs13getTotNumECVsEv50
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/ExpansionCVs.h.gcov.html b/coverage/opes/ExpansionCVs.h.gcov.html new file mode 100644 index 000000000000..c27e8b42c83b --- /dev/null +++ b/coverage/opes/ExpansionCVs.h.gcov.html @@ -0,0 +1,149 @@ + + + + + + + + LCOV - plumed test coverage - opes/ExpansionCVs.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - opes - ExpansionCVs.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:44100.0 %
Date:2024-04-19 12:12:35Functions: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         138 :   inline unsigned getNumberOfDerivatives() override {return 1;};
+      55             : 
+      56          67 :   inline double getKbT() const {return kbt_;};
+      57          50 :   inline unsigned getTotNumECVs() const {plumed_massert(isReady_,"cannot ask for totNumECVs before ECV isReady"); return totNumECVs_;};
+      58             :   virtual std::vector< std::vector<unsigned> > getIndex_k() const; //might need to override this
+      59             : 
+      60             :   virtual void calculateECVs(const double *) = 0;
+      61             :   virtual const double * getPntrToECVs(unsigned) = 0;
+      62             :   virtual const double * getPntrToDerECVs(unsigned) = 0;
+      63             :   virtual std::vector<std::string> getLambdas() const = 0;
+      64             :   virtual void initECVs_observ(const std::vector<double>&,const unsigned,const unsigned) = 0; //arg: all the observed CVs, the total numer of CVs, the first CV index referring to this ECV
+      65             :   virtual void initECVs_restart(const std::vector<std::string>&) = 0; //arg: the lambdas read from DeltaF_name relative to this ECV
+      66             : };
+      67             : 
+      68             : }
+      69             : }
+      70             : 
+      71             : #endif
+      72             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/OPESexpanded.cpp.func-sort-c.html b/coverage/opes/OPESexpanded.cpp.func-sort-c.html new file mode 100644 index 000000000000..07a8a1e96f47 --- /dev/null +++ b/coverage/opes/OPESexpanded.cpp.func-sort-c.html @@ -0,0 +1,125 @@ + + + + + + + + LCOV - plumed test coverage - opes/OPESexpanded.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - opes - OPESexpanded.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:43144397.3 %
Date:2024-04-19 12:12:35Functions:121392.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4opes12OPESexpandedC2ERKNS_13ActionOptionsE0
_ZN4PLMD4opes12OPESexpanded15dumpStateToFileEv11
_ZN4PLMD4opes12OPESexpanded12init_fromObsEv20
_ZN4PLMD4opes12OPESexpanded13init_linkECVsEv30
_ZN4PLMD4opes12OPESexpanded20init_pntrToECVsClassEv30
_ZN4PLMD4opes12OPESexpandedC1ERKNS_13ActionOptionsE30
_ZN4PLMD4opes12OPESexpanded16registerKeywordsERNS_8KeywordsE32
_ZN4PLMD4opes12OPESexpanded11printDeltaFEv64
_ZZN4PLMD4opes12OPESexpandedC4ERKNS_13ActionOptionsEENKUlRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEjjE_clESC_jj525
_ZN4PLMD4opes12OPESexpanded12updateDeltaFEd660
_ZN4PLMD4opes12OPESexpanded6updateEv1490
_ZN4PLMD4opes12OPESexpanded9calculateEv1490
_ZNK4PLMD4opes12OPESexpanded12getExpansionEj644469
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/OPESexpanded.cpp.func.html b/coverage/opes/OPESexpanded.cpp.func.html new file mode 100644 index 000000000000..ad820e896d5e --- /dev/null +++ b/coverage/opes/OPESexpanded.cpp.func.html @@ -0,0 +1,125 @@ + + + + + + + + LCOV - plumed test coverage - opes/OPESexpanded.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - opes - OPESexpanded.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:43144397.3 %
Date:2024-04-19 12:12:35Functions:121392.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4opes12OPESexpanded11printDeltaFEv64
_ZN4PLMD4opes12OPESexpanded12init_fromObsEv20
_ZN4PLMD4opes12OPESexpanded12updateDeltaFEd660
_ZN4PLMD4opes12OPESexpanded13init_linkECVsEv30
_ZN4PLMD4opes12OPESexpanded15dumpStateToFileEv11
_ZN4PLMD4opes12OPESexpanded16registerKeywordsERNS_8KeywordsE32
_ZN4PLMD4opes12OPESexpanded20init_pntrToECVsClassEv30
_ZN4PLMD4opes12OPESexpanded6updateEv1490
_ZN4PLMD4opes12OPESexpanded9calculateEv1490
_ZN4PLMD4opes12OPESexpandedC1ERKNS_13ActionOptionsE30
_ZN4PLMD4opes12OPESexpandedC2ERKNS_13ActionOptionsE0
_ZNK4PLMD4opes12OPESexpanded12getExpansionEj644469
_ZZN4PLMD4opes12OPESexpandedC4ERKNS_13ActionOptionsEENKUlRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEjjE_clESC_jj525
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/OPESexpanded.cpp.gcov.html b/coverage/opes/OPESexpanded.cpp.gcov.html new file mode 100644 index 000000000000..afac7aa23942 --- /dev/null +++ b/coverage/opes/OPESexpanded.cpp.gcov.html @@ -0,0 +1,1021 @@ + + + + + + + + LCOV - plumed test coverage - opes/OPESexpanded.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - opes - OPESexpanded.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:43144397.3 %
Date:2024-04-19 12:12:35Functions:121392.3 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2020-2021 of Michele Invernizzi.
+       3             : 
+       4             :    This file is part of the OPES plumed module.
+       5             : 
+       6             :    The OPES plumed module is free software: you can redistribute it and/or modify
+       7             :    it under the terms of the GNU Lesser General Public License as published by
+       8             :    the Free Software Foundation, either version 3 of the License, or
+       9             :    (at your option) any later version.
+      10             : 
+      11             :    The OPES plumed module is distributed in the hope that it will be useful,
+      12             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      13             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      14             :    GNU Lesser General Public License for more details.
+      15             : 
+      16             :    You should have received a copy of the GNU Lesser General Public License
+      17             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      18             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      19             : #include "bias/Bias.h"
+      20             : #include "core/PlumedMain.h"
+      21             : #include "core/ActionRegister.h"
+      22             : #include "core/ActionSet.h"
+      23             : #include "tools/Communicator.h"
+      24             : #include "tools/File.h"
+      25             : #include "tools/OpenMP.h"
+      26             : 
+      27             : #include "ExpansionCVs.h"
+      28             : 
+      29             : namespace PLMD {
+      30             : namespace opes {
+      31             : 
+      32             : //+PLUMEDOC OPES_BIAS OPES_EXPANDED
+      33             : /*
+      34             : On-the-fly probability enhanced sampling with expanded ensembles for the target distribution.
+      35             : 
+      36             : This method is similar to the OPES method (\ref OPES "OPES") with expanded ensembles target distribution (replica-exchange-like) \cite Invernizzi2020unified.
+      37             : 
+      38             : An expanded ensemble is obtained by summing a set of ensembles at slightly different termodynamic conditions, or with slightly different Hamiltonians.
+      39             : Such ensembles can be sampled via methods like replica exchange, or this \ref OPES_EXPANDED bias action.
+      40             : A typical example is a multicanonical simulation, in which a whole range of temperatures is sampled instead of a single one.
+      41             : 
+      42             : In oreder to define an expanded target ensemble we use \ref EXPANSION_CV "expansion collective variables" (ECVs), \f$\Delta u_\lambda(\mathbf{x})\f$.
+      43             : The bias at step \f$n\f$ is
+      44             : \f[
+      45             :   V_n(\mathbf{x})=-\frac{1}{\beta}\log \left(\frac{1}{N_{\{\lambda\}}}\sum_\lambda e^{-\Delta u_\lambda(\mathbf{x})+\beta\Delta F_n(\lambda)}\right)\, .
+      46             : \f]
+      47             : See Ref.\cite Invernizzi2020unified for more details on the method.
+      48             : 
+      49             : Notice that the estimates in the DELTAFS file are expressed in energy units, and should be multiplied by \f$\beta\f$ to be dimensionless as in Ref.\cite Invernizzi2020unified.
+      50             : The DELTAFS file also contains an estimate of \f$c(t)=\frac{1}{\beta} \log \langle e^{\beta V}\rangle\f$.
+      51             : Similarly to \ref OPES_METAD, it is printed only for reference, since \f$c(t)\f$ reaches a fixed value as the bias converges, and should NOT be used for reweighting.
+      52             : Its value is also needed for restarting a simulation.
+      53             : 
+      54             : You can store the instantaneous \f$\Delta F_n(\lambda)\f$ estimates also in a more readable format using STATE_WFILE and STATE_WSTRIDE.
+      55             : Restart can be done either from a DELTAFS file or from a STATE_RFILE, it is equivalent.
+      56             : 
+      57             : Contrary to \ref OPES_METAD, \ref OPES_EXPANDED does not use kernel density estimation.
+      58             : 
+      59             : \par Examples
+      60             : 
+      61             : \plumedfile
+      62             : # simulate multiple temperatures, as in parallel tempering
+      63             : ene: ENERGY
+      64             : ecv: ECV_MULTITHERMAL ARG=ene TEMP_MAX=1000
+      65             : opes: OPES_EXPANDED ARG=ecv.* PACE=500
+      66             : PRINT FILE=COLVAR STRIDE=500 ARG=ene,opes.bias
+      67             : \endplumedfile
+      68             : 
+      69             : You can easily combine multiple ECVs.
+      70             : The \ref OPES_EXPANDED bias will create a multidimensional target grid to sample all the combinations.
+      71             : 
+      72             : \plumedfile
+      73             : # simulate multiple temperatures while biasing a CV
+      74             : ene: ENERGY
+      75             : dst: DISTANCE ATOMS=1,2
+      76             : 
+      77             : ecv1: ECV_MULTITHERMAL ARG=ene TEMP_SET_ALL=200,300,500,1000
+      78             : ecv2: ECV_UMBRELLAS_LINE ARG=dst CV_MIN=1.2 CV_MAX=4.3 SIGMA=0.5
+      79             : opes: OPES_EXPANDED ARG=ecv1.*,ecv2.* PACE=500 OBSERVATION_STEPS=1
+      80             : 
+      81             : PRINT FILE=COLVAR STRIDE=500 ARG=ene,dst,opes.bias
+      82             : \endplumedfile
+      83             : 
+      84             : If an ECV is based on more than one CV you must provide all the output component, in the proper order.
+      85             : You can use \ref Regex for that, like in the following example.
+      86             : 
+      87             : \plumedfile
+      88             : # simulate multiple temperatures and pressures while biasing a two-CVs linear path
+      89             : ene: ENERGY
+      90             : vol: VOLUME
+      91             : ecv_mtp: ECV_MULTITHERMAL_MULTIBARIC ...
+      92             :   ARG=ene,vol
+      93             :   TEMP=300
+      94             :   TEMP_MIN=200
+      95             :   TEMP_MAX=800
+      96             :   PRESSURE=0.06022140857*1000 #1 kbar
+      97             :   PRESSURE_MIN=0
+      98             :   PRESSURE_MAX=0.06022140857*2000 #2 kbar
+      99             : ...
+     100             : 
+     101             : cv1: DISTANCE ATOMS=1,2
+     102             : cv2: DISTANCE ATOMS=3,4
+     103             : ecv_umb: ECV_UMBRELLAS_LINE ARG=cv1,cv2 TEMP=300 CV_MIN=0.1,0.1 CV_MAX=1.5,1.5 SIGMA=0.2 BARRIER=70
+     104             : 
+     105             : opes: OPES_EXPANDED ARG=(ecv_.*) PACE=500 WALKERS_MPI PRINT_STRIDE=1000
+     106             : 
+     107             : PRINT FILE=COLVAR STRIDE=500 ARG=ene,vol,cv1,cv2,opes.bias
+     108             : \endplumedfile
+     109             : 
+     110             : 
+     111             : */
+     112             : //+ENDPLUMEDOC
+     113             : 
+     114             : class OPESexpanded : public bias::Bias {
+     115             : 
+     116             : private:
+     117             :   bool isFirstStep_;
+     118             :   unsigned NumOMP_;
+     119             :   unsigned NumParallel_;
+     120             :   unsigned rank_;
+     121             :   unsigned NumWalkers_;
+     122             :   unsigned walker_rank_;
+     123             :   unsigned long long counter_;
+     124             :   std::size_t ncv_;
+     125             : 
+     126             :   std::vector<const double *> ECVs_;
+     127             :   std::vector<const double *> derECVs_;
+     128             :   std::vector<opes::ExpansionCVs*> pntrToECVsClass_;
+     129             :   std::vector< std::vector<unsigned> > index_k_;
+     130             : // A note on indexes usage:
+     131             : //  j -> underlying CVs
+     132             : //  i -> DeltaFs
+     133             : //  k -> single ECVs, which might not be trivially numbered
+     134             : //  l -> groups of ECVs, pntrToECVsClass
+     135             : //  h -> subgroups of ECVs, arguments in ECVsClass
+     136             : //  w -> walkers
+     137             : 
+     138             :   double kbt_;
+     139             :   unsigned stride_;
+     140             :   unsigned deltaF_size_; //different from deltaF_.size() if NumParallel_>1
+     141             :   std::vector<double> deltaF_;
+     142             :   std::vector<double> diff_;
+     143             :   double rct_;
+     144             : 
+     145             :   std::vector<double> all_deltaF_;
+     146             :   std::vector<int> all_size_;
+     147             :   std::vector<int> disp_;
+     148             : 
+     149             :   unsigned obs_steps_;
+     150             :   std::vector<double> obs_cvs_;
+     151             : 
+     152             :   bool calc_work_;
+     153             :   double work_;
+     154             : 
+     155             :   unsigned print_stride_;
+     156             :   OFile deltaFsOfile_;
+     157             :   std::vector<std::string> deltaF_name_;
+     158             : 
+     159             :   OFile stateOfile_;
+     160             :   int wStateStride_;
+     161             :   bool storeOldStates_;
+     162             : 
+     163             :   void init_pntrToECVsClass();
+     164             :   void init_linkECVs();
+     165             :   void init_fromObs();
+     166             : 
+     167             :   void printDeltaF();
+     168             :   void dumpStateToFile();
+     169             :   void updateDeltaF(double);
+     170             :   double getExpansion(const unsigned) const;
+     171             : 
+     172             : public:
+     173             :   explicit OPESexpanded(const ActionOptions&);
+     174             :   void calculate() override;
+     175             :   void update() override;
+     176             :   static void registerKeywords(Keywords& keys);
+     177             : };
+     178             : 
+     179             : PLUMED_REGISTER_ACTION(OPESexpanded,"OPES_EXPANDED")
+     180             : 
+     181          32 : void OPESexpanded::registerKeywords(Keywords& keys)
+     182             : {
+     183          32 :   Bias::registerKeywords(keys);
+     184          32 :   keys.remove("ARG");
+     185          64 :   keys.add("compulsory","ARG","the label of the ECVs that define the expansion. You can use an * to make sure all the output components of the ECVs are used, as in the examples above");
+     186          64 :   keys.add("compulsory","PACE","how often the bias is updated");
+     187          64 :   keys.add("compulsory","OBSERVATION_STEPS","100","number of unbiased initial PACE steps to collect statistics for initialization");
+     188             : //DeltaFs and state files
+     189          64 :   keys.add("compulsory","FILE","DELTAFS","a file with the estimate of the relative Delta F for each component of the target and of the global c(t)");
+     190          64 :   keys.add("compulsory","PRINT_STRIDE","100","stride for printing to DELTAFS file, in units of PACE");
+     191          64 :   keys.add("optional","FMT","specify format for DELTAFS file");
+     192          64 :   keys.add("optional","STATE_RFILE","read from this file the Delta F estimates and all the info needed to RESTART the simulation");
+     193          64 :   keys.add("optional","STATE_WFILE","write to this file the Delta F estimates and all the info needed to RESTART the simulation");
+     194          64 :   keys.add("optional","STATE_WSTRIDE","number of MD steps between writing the STATE_WFILE. Default is only on CPT events (but not all MD codes set them)");
+     195          64 :   keys.addFlag("STORE_STATES",false,"append to STATE_WFILE instead of ovewriting it each time");
+     196             : //miscellaneous
+     197          64 :   keys.addFlag("CALC_WORK",false,"calculate the total accumulated work done by the bias since last restart");
+     198          64 :   keys.addFlag("WALKERS_MPI",false,"switch on MPI version of multiple walkers");
+     199          64 :   keys.addFlag("SERIAL",false,"perform calculations in serial");
+     200          32 :   keys.use("RESTART");
+     201          32 :   keys.use("UPDATE_FROM");
+     202          32 :   keys.use("UPDATE_UNTIL");
+     203             : 
+     204             : //output components
+     205          32 :   componentsAreNotOptional(keys);
+     206          64 :   keys.addOutputComponent("work","CALC_WORK","total accumulated work done by the bias");
+     207          32 : }
+     208             : 
+     209          30 : OPESexpanded::OPESexpanded(const ActionOptions&ao)
+     210             :   : PLUMED_BIAS_INIT(ao)
+     211          30 :   , isFirstStep_(true)
+     212          30 :   , counter_(0)
+     213          30 :   , ncv_(getNumberOfArguments())
+     214          30 :   , deltaF_size_(0)
+     215          30 :   , rct_(0)
+     216          30 :   , work_(0)
+     217             : {
+     218             : //set pace
+     219          30 :   parse("PACE",stride_);
+     220          30 :   parse("OBSERVATION_STEPS",obs_steps_);
+     221          30 :   plumed_massert(obs_steps_!=0,"minimum is OBSERVATION_STEPS=1");
+     222          30 :   obs_cvs_.resize(obs_steps_*ncv_);
+     223             : 
+     224             : //deltaFs file
+     225             :   std::string deltaFsFileName;
+     226          30 :   parse("FILE",deltaFsFileName);
+     227          60 :   parse("PRINT_STRIDE",print_stride_);
+     228             :   std::string fmt;
+     229          60 :   parse("FMT",fmt);
+     230             : //output checkpoint of current state
+     231             :   std::string restartFileName;
+     232          60 :   parse("STATE_RFILE",restartFileName);
+     233             :   std::string stateFileName;
+     234          30 :   parse("STATE_WFILE",stateFileName);
+     235          30 :   wStateStride_=0;
+     236          30 :   parse("STATE_WSTRIDE",wStateStride_);
+     237          30 :   storeOldStates_=false;
+     238          30 :   parseFlag("STORE_STATES",storeOldStates_);
+     239          30 :   if(wStateStride_!=0 || storeOldStates_)
+     240           5 :     plumed_massert(stateFileName.length()>0,"filename for storing simulation status not specified, use STATE_WFILE");
+     241          30 :   if(wStateStride_>0)
+     242           5 :     plumed_massert(wStateStride_>=(int)stride_,"STATE_WSTRIDE is in units of MD steps, thus should be a multiple of PACE");
+     243          30 :   if(stateFileName.length()>0 && wStateStride_==0)
+     244           1 :     wStateStride_=-1;//will print only on CPT events (checkpoints set by some MD engines, like gromacs)
+     245             : 
+     246             : //work flag
+     247          30 :   parseFlag("CALC_WORK",calc_work_);
+     248             : 
+     249             : //multiple walkers //external MW for cp2k not supported, but anyway cp2k cannot put bias on energy!
+     250          30 :   bool walkers_mpi=false;
+     251          30 :   parseFlag("WALKERS_MPI",walkers_mpi);
+     252          30 :   if(walkers_mpi)
+     253             :   {
+     254             :     //If this Action is not compiled with MPI the user is informed and we exit gracefully
+     255           4 :     plumed_massert(Communicator::plumedHasMPI(),"Invalid walkers configuration: WALKERS_MPI flag requires MPI compilation");
+     256           4 :     plumed_massert(Communicator::initialized(),"Invalid walkers configuration: WALKERS_MPI needs the communicator correctly initialized.");
+     257             : 
+     258           4 :     if(comm.Get_rank()==0) //multi_sim_comm works on first rank only
+     259             :     {
+     260           4 :       NumWalkers_=multi_sim_comm.Get_size();
+     261           4 :       walker_rank_=multi_sim_comm.Get_rank();
+     262             :     }
+     263           4 :     comm.Bcast(NumWalkers_,0); //if each walker has more than one processor update them all
+     264           4 :     comm.Bcast(walker_rank_,0);
+     265             :   }
+     266             :   else
+     267             :   {
+     268          26 :     NumWalkers_=1;
+     269          26 :     walker_rank_=0;
+     270             :   }
+     271             : 
+     272             : //parallelization stuff
+     273          30 :   NumOMP_=OpenMP::getNumThreads();
+     274          30 :   NumParallel_=comm.Get_size();
+     275          30 :   rank_=comm.Get_rank();
+     276          30 :   bool serial=false;
+     277          30 :   parseFlag("SERIAL",serial);
+     278          30 :   if(serial)
+     279             :   {
+     280           5 :     NumOMP_=1;
+     281           5 :     NumParallel_=1;
+     282           5 :     rank_=0;
+     283             :   }
+     284             : 
+     285          30 :   checkRead();
+     286             : 
+     287             : //check ECVs and link them
+     288          30 :   init_pntrToECVsClass();
+     289             : //set kbt_
+     290          30 :   kbt_=pntrToECVsClass_[0]->getKbT();
+     291          67 :   for(unsigned l=0; l<pntrToECVsClass_.size(); l++)
+     292          37 :     plumed_massert(std::abs(kbt_-pntrToECVsClass_[l]->getKbT())<1e-4,"must set same TEMP for each ECV");
+     293             : 
+     294             : //restart if needed
+     295          30 :   if(getRestart())
+     296             :   {
+     297             :     bool stateRestart=true;
+     298          10 :     if(restartFileName.length()==0)
+     299             :     {
+     300             :       stateRestart=false;
+     301             :       restartFileName=deltaFsFileName;
+     302             :     }
+     303          10 :     IFile ifile;
+     304          10 :     ifile.link(*this);
+     305          10 :     if(ifile.FileExist(restartFileName))
+     306             :     {
+     307          10 :       log.printf("  RESTART - make sure all ECVs used are the same as before\n");
+     308          10 :       log.printf("    restarting from: %s\n",restartFileName.c_str());
+     309          10 :       ifile.open(restartFileName);
+     310          10 :       if(stateRestart) //get all info
+     311             :       {
+     312           2 :         log.printf("    it should be a STATE file (not a DELTAFS file)\n");
+     313             :         double time; //not used
+     314           2 :         ifile.scanField("time",time);
+     315           2 :         ifile.scanField("counter",counter_);
+     316           4 :         ifile.scanField("rct",rct_);
+     317             :         std::string tmp_lambda;
+     318          66 :         while(ifile.scanField(getPntrToArgument(0)->getName(),tmp_lambda))
+     319             :         {
+     320          64 :           std::string subs="DeltaF_"+tmp_lambda;
+     321         128 :           for(unsigned jj=1; jj<ncv_; jj++)
+     322             :           {
+     323             :             tmp_lambda.clear();
+     324          64 :             ifile.scanField(getPntrToArgument(jj)->getName(),tmp_lambda);
+     325         128 :             subs+="_"+tmp_lambda;
+     326             :           }
+     327          64 :           deltaF_name_.push_back(subs);
+     328             :           double tmp_deltaF;
+     329          64 :           ifile.scanField("DeltaF",tmp_deltaF);
+     330          64 :           deltaF_.push_back(tmp_deltaF);
+     331          64 :           ifile.scanField();
+     332             :           tmp_lambda.clear();
+     333             :         }
+     334           2 :         log.printf("  successfully read %lu DeltaF values\n",deltaF_name_.size());
+     335           2 :         if(NumParallel_>1)
+     336           2 :           all_deltaF_=deltaF_;
+     337             :       }
+     338             :       else //get just deltaFs names
+     339             :       {
+     340           8 :         ifile.scanFieldList(deltaF_name_);
+     341           8 :         plumed_massert(deltaF_name_.size()>=4,"RESTART - fewer than expected FIELDS found in '"+deltaFsFileName+"' file");
+     342           8 :         plumed_massert(deltaF_name_[deltaF_name_.size()-1]=="print_stride","RESTART - coult not find expected FIELDS in '"+deltaFsFileName+"' file");
+     343           8 :         plumed_massert(deltaF_name_[0]=="time","RESTART - coult not find expected FIELDS in '"+deltaFsFileName+"' file");
+     344           8 :         plumed_massert(deltaF_name_[1]=="rct","RESTART - coult not find expected FIELDS in '"+deltaFsFileName+"' file");
+     345             :         deltaF_name_.pop_back();
+     346             :         deltaF_name_.erase(deltaF_name_.begin(),deltaF_name_.begin()+2);
+     347             :         std::size_t pos=5; //each name starts with "DeltaF"
+     348          22 :         for(unsigned j=0; j<ncv_; j++)
+     349          14 :           pos=deltaF_name_[0].find("_",pos+1); //checking only first one, hopefully is enough
+     350           8 :         plumed_massert(pos<deltaF_name_[0].length(),"RESTART - fewer '_' than expected in DeltaF fields: did you remove any CV?");
+     351           8 :         pos=deltaF_name_[0].find("_",pos+1);
+     352           8 :         plumed_massert(pos>deltaF_name_[0].length(),"RESTART - more '_' than expected in DeltaF fields: did you add new CV?");
+     353             :       }
+     354             :       //get lambdas, init ECVs and Link them
+     355          10 :       deltaF_size_=deltaF_name_.size();
+     356         525 :       auto getLambdaName=[](const std::string& name,const unsigned start,const unsigned dim)
+     357             :       {
+     358             :         std::size_t pos_start=5; //each name starts with "DeltaF"
+     359        1068 :         for(unsigned j=0; j<=start; j++)
+     360         543 :           pos_start=name.find("_",pos_start+1);
+     361             :         std::size_t pos_end=pos_start;
+     362        1527 :         for(unsigned j=0; j<dim; j++)
+     363        1002 :           pos_end=name.find("_",pos_end+1);
+     364         525 :         pos_start++; //do not include heading "_"
+     365         525 :         return name.substr(pos_start,pos_end-pos_start);
+     366             :       };
+     367          10 :       unsigned index_j=ncv_;
+     368             :       unsigned sizeSkip=1;
+     369          22 :       for(int l=pntrToECVsClass_.size()-1; l>=0; l--)
+     370             :       {
+     371          12 :         const unsigned dim_l=pntrToECVsClass_[l]->getNumberOfArguments();
+     372          12 :         index_j-=dim_l;
+     373          12 :         std::vector<std::string> lambdas_l(1);
+     374          12 :         lambdas_l[0]=getLambdaName(deltaF_name_[0],index_j,dim_l);
+     375         523 :         for(unsigned i=sizeSkip; i<deltaF_size_; i+=sizeSkip)
+     376             :         {
+     377         513 :           std::string tmp_lambda=getLambdaName(deltaF_name_[i],index_j,dim_l);
+     378         513 :           if(tmp_lambda==lambdas_l[0])
+     379             :             break;
+     380         511 :           lambdas_l.push_back(tmp_lambda);
+     381             :         }
+     382          12 :         pntrToECVsClass_[l]->initECVs_restart(lambdas_l);
+     383          12 :         sizeSkip*=lambdas_l.size();
+     384          12 :       }
+     385          10 :       plumed_massert(sizeSkip==deltaF_size_,"RESTART - this should not happen");
+     386          10 :       init_linkECVs(); //link ECVs and initializes index_k_
+     387          10 :       log.printf(" ->%4u DeltaFs in total\n",deltaF_size_);
+     388          10 :       obs_steps_=0; //avoid initializing again
+     389          10 :       if(stateRestart)
+     390             :       {
+     391           2 :         if(NumParallel_>1)
+     392             :         {
+     393           2 :           const unsigned start=(deltaF_size_/NumParallel_)*rank_+std::min(rank_,deltaF_size_%NumParallel_);
+     394             :           unsigned iter=0;
+     395          34 :           for(unsigned i=start; i<start+deltaF_.size(); i++)
+     396          32 :             deltaF_[iter++]=all_deltaF_[i];
+     397             :         }
+     398             :       }
+     399             :       else //read each step
+     400             :       {
+     401           8 :         counter_=1;
+     402             :         unsigned count_lines=0;
+     403           8 :         ifile.allowIgnoredFields(); //this allows for multiple restart, but without checking for consistency between them!
+     404             :         double time;
+     405          48 :         while(ifile.scanField("time",time)) //only number of lines and last line is important
+     406             :         {
+     407             :           unsigned restart_stride;
+     408          16 :           ifile.scanField("print_stride",restart_stride);
+     409          16 :           ifile.scanField("rct",rct_);
+     410          16 :           if(NumParallel_==1)
+     411             :           {
+     412        1014 :             for(unsigned i=0; i<deltaF_size_; i++)
+     413         998 :               ifile.scanField(deltaF_name_[i],deltaF_[i]);
+     414             :           }
+     415             :           else
+     416             :           {
+     417           0 :             const unsigned start=(deltaF_size_/NumParallel_)*rank_+std::min(rank_,deltaF_size_%NumParallel_);
+     418             :             unsigned iter=0;
+     419           0 :             for(unsigned i=start; i<start+deltaF_.size(); i++)
+     420           0 :               ifile.scanField(deltaF_name_[i],deltaF_[iter++]);
+     421             :           }
+     422          16 :           ifile.scanField();
+     423          16 :           if(count_lines>0)
+     424           8 :             counter_+=restart_stride;
+     425          16 :           count_lines++;
+     426             :         }
+     427           8 :         counter_*=NumWalkers_;
+     428           8 :         log.printf("  successfully read %u lines, up to t=%g\n",count_lines,time);
+     429             :       }
+     430          10 :       ifile.reset(false);
+     431          10 :       ifile.close();
+     432             :     }
+     433             :     else //same behaviour as METAD
+     434           0 :       plumed_merror("RESTART requested, but file '"+restartFileName+"' was not found!\n  Set RESTART=NO or provide a restart file");
+     435          10 :     if(NumWalkers_>1) //make sure that all walkers are doing the same thing
+     436             :     {
+     437           2 :       std::vector<unsigned long long> all_counter(NumWalkers_);
+     438           2 :       if(comm.Get_rank()==0)
+     439           2 :         multi_sim_comm.Allgather(counter_,all_counter);
+     440           2 :       comm.Bcast(all_counter,0);
+     441             :       bool same_number_of_steps=true;
+     442           4 :       for(unsigned w=1; w<NumWalkers_; w++)
+     443           2 :         if(all_counter[0]!=all_counter[w])
+     444             :           same_number_of_steps=false;
+     445           2 :       plumed_massert(same_number_of_steps,"RESTART - not all walkers are reading the same file!");
+     446             :     }
+     447          10 :   }
+     448          20 :   else if(restartFileName.length()>0)
+     449           0 :     log.printf(" +++ WARNING +++ the provided STATE_RFILE will be ignored, since RESTART was not requested\n");
+     450             : 
+     451             : //sync all walkers to avoid opening files before reding is over (see also METAD)
+     452          30 :   comm.Barrier();
+     453          30 :   if(comm.Get_rank()==0 && walkers_mpi)
+     454           4 :     multi_sim_comm.Barrier();
+     455             : 
+     456             : //setup DeltaFs file
+     457          30 :   deltaFsOfile_.link(*this);
+     458          30 :   if(NumWalkers_>1)
+     459             :   {
+     460           4 :     if(walker_rank_>0)
+     461             :       deltaFsFileName="/dev/null"; //only first walker writes on file
+     462           8 :     deltaFsOfile_.enforceSuffix("");
+     463             :   }
+     464          30 :   deltaFsOfile_.open(deltaFsFileName);
+     465          30 :   if(fmt.length()>0)
+     466          60 :     deltaFsOfile_.fmtField(" "+fmt);
+     467             :   deltaFsOfile_.setHeavyFlush(); //do I need it?
+     468          30 :   deltaFsOfile_.addConstantField("print_stride");
+     469          30 :   deltaFsOfile_.printField("print_stride",print_stride_);
+     470             : 
+     471             : //open file for storing state
+     472          30 :   if(wStateStride_!=0)
+     473             :   {
+     474           6 :     stateOfile_.link(*this);
+     475           6 :     if(NumWalkers_>1)
+     476             :     {
+     477           0 :       if(walker_rank_>0)
+     478             :         stateFileName="/dev/null"; //only first walker writes on file
+     479           0 :       stateOfile_.enforceSuffix("");
+     480             :     }
+     481           6 :     stateOfile_.open(stateFileName);
+     482           6 :     if(fmt.length()>0)
+     483          12 :       stateOfile_.fmtField(" "+fmt);
+     484             :   }
+     485             : 
+     486             : //add output components
+     487          30 :   if(calc_work_)
+     488             :   {
+     489          12 :     addComponent("work");
+     490          12 :     componentIsNotPeriodic("work");
+     491             :   }
+     492             : 
+     493             : //printing some info
+     494          30 :   log.printf("  updating the bias with PACE = %u\n",stride_);
+     495          30 :   log.printf("  initial unbiased OBSERVATION_STEPS = %u (in units of PACE)\n",obs_steps_);
+     496          30 :   if(wStateStride_>0)
+     497           5 :     log.printf("  state checkpoints are written on file %s every %d MD steps\n",stateFileName.c_str(),wStateStride_);
+     498          30 :   if(wStateStride_==-1)
+     499           1 :     log.printf("  state checkpoints are written on file '%s' only on CPT events (or never if MD code does define them!)\n",stateFileName.c_str());
+     500          30 :   if(walkers_mpi)
+     501           4 :     log.printf(" -- WALKERS_MPI: if multiple replicas are present, they will share the same bias via MPI\n");
+     502          30 :   if(NumWalkers_>1)
+     503             :   {
+     504           4 :     log.printf("  using multiple walkers\n");
+     505           4 :     log.printf("    number of walkers: %u\n",NumWalkers_);
+     506           4 :     log.printf("    walker rank: %u\n",walker_rank_);
+     507             :   }
+     508          30 :   int mw_warning=0;
+     509          30 :   if(!walkers_mpi && comm.Get_rank()==0 && multi_sim_comm.Get_size()>(int)NumWalkers_)
+     510           0 :     mw_warning=1;
+     511          30 :   comm.Bcast(mw_warning,0);
+     512          30 :   if(mw_warning) //log.printf messes up with comm, so never use it without Bcast!
+     513           0 :     log.printf(" +++ WARNING +++ multiple replicas will NOT communicate unless the flag WALKERS_MPI is used\n");
+     514          30 :   if(NumParallel_>1)
+     515           2 :     log.printf("  using multiple MPI processes per simulation: %u\n",NumParallel_);
+     516          30 :   if(NumOMP_>1)
+     517          25 :     log.printf("  using multiple OpenMP threads per simulation: %u\n",NumOMP_);
+     518          30 :   if(serial)
+     519           5 :     log.printf(" -- SERIAL: no loop parallelization, despite %d MPI processes and %u OpenMP threads available\n",comm.Get_size(),OpenMP::getNumThreads());
+     520          30 :   log.printf("  Bibliography: ");
+     521          60 :   log<<plumed.cite("M. Invernizzi, P.M. Piaggi, and M. Parrinello, Phys. Rev. X 10, 041034 (2020)");
+     522          30 :   log.printf("\n");
+     523          30 : }
+     524             : 
+     525        1490 : void OPESexpanded::calculate()
+     526             : {
+     527        1490 :   if(deltaF_size_==0) //no bias before initialization
+     528         325 :     return;
+     529             : 
+     530             : //get diffMax, to avoid over/underflow
+     531        1165 :   double diffMax=-std::numeric_limits<double>::max();
+     532        1165 :   #pragma omp parallel num_threads(NumOMP_)
+     533             :   {
+     534             :     #pragma omp for reduction(max:diffMax)
+     535             :     for(unsigned i=0; i<deltaF_.size(); i++)
+     536             :     {
+     537             :       diff_[i]=(-getExpansion(i)+deltaF_[i]/kbt_);
+     538             :       if(diff_[i]>diffMax)
+     539             :         diffMax=diff_[i];
+     540             :     }
+     541             :   }
+     542        1165 :   if(NumParallel_>1)
+     543         102 :     comm.Max(diffMax);
+     544             : 
+     545             : //calculate the bias and the forces
+     546        1165 :   double sum=0;
+     547        1165 :   std::vector<double> der_sum_cv(ncv_,0);
+     548        1165 :   if(NumOMP_==1)
+     549             :   {
+     550        2730 :     for(unsigned i=0; i<deltaF_.size(); i++)
+     551             :     {
+     552        2520 :       double add_i=std::exp(diff_[i]-diffMax);
+     553        2520 :       sum+=add_i;
+     554             :       //set derivatives
+     555        6960 :       for(unsigned j=0; j<ncv_; j++)
+     556        4440 :         der_sum_cv[j]-=derECVs_[j][index_k_[i][j]]*add_i;
+     557             :     }
+     558             :   }
+     559             :   else
+     560             :   {
+     561         955 :     #pragma omp parallel num_threads(NumOMP_)
+     562             :     {
+     563             :       std::vector<double> omp_der_sum_cv(ncv_,0);
+     564             :       #pragma omp for reduction(+:sum) nowait
+     565             :       for(unsigned i=0; i<deltaF_.size(); i++)
+     566             :       {
+     567             :         double add_i=std::exp(diff_[i]-diffMax);
+     568             :         sum+=add_i;
+     569             :         //set derivatives
+     570             :         for(unsigned j=0; j<ncv_; j++)
+     571             :           omp_der_sum_cv[j]-=derECVs_[j][index_k_[i][j]]*add_i;
+     572             :       }
+     573             :       #pragma omp critical
+     574             :       for(unsigned j=0; j<ncv_; j++)
+     575             :         der_sum_cv[j]+=omp_der_sum_cv[j];
+     576             :     }
+     577             :   }
+     578        1165 :   if(NumParallel_>1)
+     579             :   { //each MPI process has part of the full deltaF_ vector, so must Sum
+     580         102 :     comm.Sum(sum);
+     581         102 :     comm.Sum(der_sum_cv);
+     582             :   }
+     583             : 
+     584             : //set bias and forces
+     585        1165 :   const double bias=-kbt_*(diffMax+std::log(sum/deltaF_size_));
+     586        1165 :   setBias(bias);
+     587        3163 :   for(unsigned j=0; j<ncv_; j++)
+     588        1998 :     setOutputForce(j,kbt_*der_sum_cv[j]/sum);
+     589             : }
+     590             : 
+     591        1490 : void OPESexpanded::update()
+     592             : {
+     593        1490 :   if(isFirstStep_) //skip very first step, as in METAD
+     594             :   {
+     595          30 :     isFirstStep_=false;
+     596          30 :     if(obs_steps_!=1) //if obs_steps_==1 go on with initialization
+     597             :       return;
+     598             :   }
+     599        1464 :   if(getStep()%stride_==0)
+     600             :   {
+     601         739 :     if(obs_steps_>0)
+     602             :     {
+     603         463 :       for(unsigned j=0; j<ncv_; j++)
+     604         304 :         obs_cvs_[counter_*ncv_+j]=getArgument(j);
+     605         159 :       counter_++;
+     606         159 :       if(counter_==obs_steps_)
+     607             :       {
+     608          20 :         log.printf("\nAction %s\n",getName().c_str());
+     609          20 :         init_fromObs();
+     610          20 :         log.printf("Finished initialization\n\n");
+     611          20 :         counter_=NumWalkers_; //all preliminary observations count 1
+     612          20 :         obs_steps_=0; //no more observation
+     613             :       }
+     614         159 :       return;
+     615             :     }
+     616             : 
+     617             :     //update averages
+     618         580 :     const double current_bias=getOutputQuantity(0); //the first value is always the bias
+     619         580 :     if(NumWalkers_==1)
+     620         500 :       updateDeltaF(current_bias);
+     621             :     else
+     622             :     {
+     623          80 :       std::vector<double> cvs(ncv_);
+     624         240 :       for(unsigned j=0; j<ncv_; j++)
+     625         160 :         cvs[j]=getArgument(j);
+     626          80 :       std::vector<double> all_bias(NumWalkers_);
+     627          80 :       std::vector<double> all_cvs(NumWalkers_*ncv_);
+     628          80 :       if(comm.Get_rank()==0)
+     629             :       {
+     630          80 :         multi_sim_comm.Allgather(current_bias,all_bias);
+     631          80 :         multi_sim_comm.Allgather(cvs,all_cvs);
+     632             :       }
+     633          80 :       comm.Bcast(all_bias,0);
+     634          80 :       comm.Bcast(all_cvs,0);
+     635         240 :       for(unsigned w=0; w<NumWalkers_; w++)
+     636             :       {
+     637             :         //calculate ECVs
+     638         160 :         unsigned index_wj=w*ncv_;
+     639         380 :         for(unsigned k=0; k<pntrToECVsClass_.size(); k++)
+     640             :         {
+     641         220 :           pntrToECVsClass_[k]->calculateECVs(&all_cvs[index_wj]);
+     642         220 :           index_wj+=pntrToECVsClass_[k]->getNumberOfArguments();
+     643             :         }
+     644         160 :         updateDeltaF(all_bias[w]);
+     645             :       }
+     646             :     }
+     647             : 
+     648             :     //write DeltaFs to file
+     649         580 :     if((counter_/NumWalkers_-1)%print_stride_==0)
+     650          44 :       printDeltaF();
+     651             : 
+     652             :     //calculate work if requested
+     653         580 :     if(calc_work_)
+     654             :     { //some copy and paste from calculate()
+     655             :       //get diffMax, to avoid over/underflow
+     656         110 :       double diffMax=-std::numeric_limits<double>::max();
+     657         110 :       #pragma omp parallel num_threads(NumOMP_)
+     658             :       {
+     659             :         #pragma omp for reduction(max:diffMax)
+     660             :         for(unsigned i=0; i<deltaF_.size(); i++)
+     661             :         {
+     662             :           diff_[i]=(-getExpansion(i)+deltaF_[i]/kbt_);
+     663             :           if(diff_[i]>diffMax)
+     664             :             diffMax=diff_[i];
+     665             :         }
+     666             :       }
+     667         110 :       if(NumParallel_>1)
+     668          50 :         comm.Max(diffMax);
+     669             :       //calculate the bias
+     670         110 :       double sum=0;
+     671         110 :       #pragma omp parallel num_threads(NumOMP_)
+     672             :       {
+     673             :         #pragma omp for reduction(+:sum) nowait
+     674             :         for(unsigned i=0; i<deltaF_.size(); i++)
+     675             :           sum+=std::exp(diff_[i]-diffMax);
+     676             :       }
+     677         110 :       if(NumParallel_>1)
+     678          50 :         comm.Sum(sum);
+     679         110 :       const double new_bias=-kbt_*(diffMax+std::log(sum/deltaF_size_));
+     680             :       //accumulate work
+     681         110 :       work_+=new_bias-current_bias;
+     682         220 :       getPntrToComponent("work")->set(work_);
+     683             :     }
+     684             :   }
+     685             : 
+     686             : //dump state if requested
+     687        1305 :   if( (wStateStride_>0 && getStep()%wStateStride_==0) || (wStateStride_==-1 && getCPT()) )
+     688          11 :     dumpStateToFile();
+     689             : }
+     690             : 
+     691          30 : void OPESexpanded::init_pntrToECVsClass()
+     692             : {
+     693          30 :   std::vector<opes::ExpansionCVs*> all_pntrToECVsClass=plumed.getActionSet().select<opes::ExpansionCVs*>();
+     694          30 :   plumed_massert(all_pntrToECVsClass.size()>0,"no Expansion CVs found");
+     695          67 :   for(unsigned j=0; j<ncv_; j++)
+     696             :   {
+     697          74 :     std::string error_notECV("all the ARGs of "+getName()+" must be Expansion Collective Variables (ECV)");
+     698          37 :     const unsigned dot_pos=getPntrToArgument(j)->getName().find(".");
+     699          37 :     plumed_massert(dot_pos<getPntrToArgument(j)->getName().size(),error_notECV+", thus contain a dot in the name");
+     700          37 :     unsigned foundECV_l=all_pntrToECVsClass.size();
+     701          44 :     for(unsigned l=0; l<all_pntrToECVsClass.size(); l++)
+     702             :     {
+     703          44 :       if(getPntrToArgument(j)->getName().substr(0,dot_pos)==all_pntrToECVsClass[l]->getLabel())
+     704             :       {
+     705             :         foundECV_l=l;
+     706          37 :         pntrToECVsClass_.push_back(all_pntrToECVsClass[l]);
+     707          37 :         std::string missing_arg="some ECV component is missing from ARG";
+     708          37 :         plumed_massert(j+all_pntrToECVsClass[l]->getNumberOfArguments()<=getNumberOfArguments(),missing_arg);
+     709          90 :         for(unsigned h=0; h<all_pntrToECVsClass[l]->getNumberOfArguments(); h++)
+     710             :         {
+     711          53 :           std::string argName=getPntrToArgument(j+h)->getName();
+     712          53 :           std::string expectedECVname=all_pntrToECVsClass[l]->getComponentsVector()[h];
+     713          53 :           plumed_massert(argName==expectedECVname,missing_arg+", or is in wrong order: given ARG="+argName+" expected ARG="+expectedECVname);
+     714             :         }
+     715          37 :         j+=all_pntrToECVsClass[l]->getNumberOfArguments()-1;
+     716             :         break;
+     717             :       }
+     718             :     }
+     719          37 :     plumed_massert(foundECV_l<all_pntrToECVsClass.size(),error_notECV);
+     720             :   }
+     721          67 :   for(unsigned l=0; l<pntrToECVsClass_.size(); l++)
+     722          44 :     for(unsigned ll=l+1; ll<pntrToECVsClass_.size(); ll++)
+     723           7 :       plumed_massert(pntrToECVsClass_[l]->getLabel()!=pntrToECVsClass_[ll]->getLabel(),"cannot use same ECV twice");
+     724          30 : }
+     725             : 
+     726          30 : void OPESexpanded::init_linkECVs()
+     727             : {
+     728             :   //TODO It should be possible to make all of this more straightforward (and probably also faster):
+     729             :   //     - get rid of index_k_, making it trivial for each ECV
+     730             :   //     - store the ECVs_ and derECVs_ vectors here as a contiguous vector, and use pointers in the ECV classes
+     731             :   //     Some caveats:
+     732             :   //     - ECVmultiThermalBaric has a nontrivial index_k_ to avoid duplicates. use duplicates instead
+     733             :   //     - can the ECVs be MPI parallel or it's too complicated?
+     734          30 :   plumed_massert(deltaF_size_>0,"must set deltaF_size_ before calling init_linkECVs()");
+     735          30 :   if(NumParallel_==1)
+     736          28 :     deltaF_.resize(deltaF_size_);
+     737             :   else
+     738             :   {
+     739           2 :     const unsigned extra=(rank_<(deltaF_size_%NumParallel_)?1:0);
+     740           2 :     deltaF_.resize(deltaF_size_/NumParallel_+extra);
+     741             :     //these are used when printing deltaF_ to file
+     742           2 :     all_deltaF_.resize(deltaF_size_);
+     743           2 :     all_size_.resize(NumParallel_,deltaF_size_/NumParallel_);
+     744           2 :     disp_.resize(NumParallel_);
+     745           4 :     for(unsigned r=0; r<NumParallel_-1; r++)
+     746             :     {
+     747           2 :       if(r<deltaF_size_%NumParallel_)
+     748           0 :         all_size_[r]++;
+     749           2 :       disp_[r+1]=disp_[r]+all_size_[r];
+     750             :     }
+     751             :   }
+     752          30 :   diff_.resize(deltaF_.size());
+     753          30 :   ECVs_.resize(ncv_);
+     754          30 :   derECVs_.resize(ncv_);
+     755          30 :   index_k_.resize(deltaF_.size(),std::vector<unsigned>(ncv_));
+     756             :   unsigned index_j=0;
+     757          30 :   unsigned sizeSkip=deltaF_size_;
+     758          67 :   for(unsigned l=0; l<pntrToECVsClass_.size(); l++)
+     759             :   {
+     760          37 :     std::vector< std::vector<unsigned> > l_index_k(pntrToECVsClass_[l]->getIndex_k());
+     761          37 :     plumed_massert(deltaF_size_%l_index_k.size()==0,"buggy ECV: mismatch between getTotNumECVs() and getIndex_k().size()");
+     762          37 :     plumed_massert(l_index_k[0].size()==pntrToECVsClass_[l]->getNumberOfArguments(),"buggy ECV: mismatch between number of ARG and underlying CVs");
+     763          37 :     sizeSkip/=l_index_k.size();
+     764          90 :     for(unsigned h=0; h<pntrToECVsClass_[l]->getNumberOfArguments(); h++)
+     765             :     {
+     766          53 :       ECVs_[index_j+h]=pntrToECVsClass_[l]->getPntrToECVs(h);
+     767          53 :       derECVs_[index_j+h]=pntrToECVsClass_[l]->getPntrToDerECVs(h);
+     768          53 :       if(NumParallel_==1)
+     769             :       {
+     770       45589 :         for(unsigned i=0; i<deltaF_size_; i++)
+     771       45540 :           index_k_[i][index_j+h]=l_index_k[(i/sizeSkip)%l_index_k.size()][h];
+     772             :       }
+     773             :       else
+     774             :       {
+     775           4 :         const unsigned start=(deltaF_size_/NumParallel_)*rank_+std::min(rank_,deltaF_size_%NumParallel_);
+     776             :         unsigned iter=0;
+     777          68 :         for(unsigned i=start; i<start+deltaF_.size(); i++)
+     778          64 :           index_k_[iter++][index_j+h]=l_index_k[(i/sizeSkip)%l_index_k.size()][h];
+     779             :       }
+     780             :     }
+     781          37 :     index_j+=pntrToECVsClass_[l]->getNumberOfArguments();
+     782          37 :   }
+     783          30 :   plumed_massert(sizeSkip==1,"this should not happen!");
+     784          30 : }
+     785             : 
+     786          20 : void OPESexpanded::init_fromObs() //This could probably be faster and/or require less memory...
+     787             : {
+     788             : //in case of multiple walkers gather all the statistics
+     789          20 :   if(NumWalkers_>1)
+     790             :   {
+     791           2 :     std::vector<double> all_obs_cv(ncv_*obs_steps_*NumWalkers_);
+     792           2 :     if(comm.Get_rank()==0)
+     793           2 :       multi_sim_comm.Allgather(obs_cvs_,all_obs_cv);
+     794           2 :     comm.Bcast(all_obs_cv,0);
+     795           2 :     obs_cvs_=all_obs_cv; //could this lead to memory issues?
+     796           2 :     obs_steps_*=NumWalkers_;
+     797             :   }
+     798             : 
+     799             : //initialize ECVs from observations
+     800             :   unsigned index_j=0;
+     801          20 :   deltaF_size_=1;
+     802          45 :   for(unsigned l=0; l<pntrToECVsClass_.size(); l++)
+     803             :   {
+     804          25 :     pntrToECVsClass_[l]->initECVs_observ(obs_cvs_,ncv_,index_j);
+     805          25 :     deltaF_size_*=pntrToECVsClass_[l]->getTotNumECVs(); //ECVs from different exansions will be combined
+     806          25 :     index_j+=pntrToECVsClass_[l]->getNumberOfArguments();
+     807             :   }
+     808          20 :   plumed_massert(index_j==getNumberOfArguments(),"mismatch between number of linked CVs and number of ARG");
+     809             : //link ECVs and initialize index_k_, mapping each deltaF to a single ECVs set
+     810          20 :   init_linkECVs();
+     811             : 
+     812             : //initialize deltaF_ from obs
+     813             : //for the first point, t=0, the ECVs are calculated by initECVs_observ, setting also any initial guess
+     814             :   index_j=0;
+     815       12379 :   for(unsigned i=0; i<deltaF_.size(); i++)
+     816       56923 :     for(unsigned j=0; j<ncv_; j++)
+     817       44564 :       deltaF_[i]+=kbt_*ECVs_[j][index_k_[i][j]];
+     818         179 :   for(unsigned t=1; t<obs_steps_; t++) //starts from t=1
+     819             :   {
+     820             :     unsigned index_j=0;
+     821         383 :     for(unsigned l=0; l<pntrToECVsClass_.size(); l++)
+     822             :     {
+     823         224 :       pntrToECVsClass_[l]->calculateECVs(&obs_cvs_[t*ncv_+index_j]);
+     824         224 :       index_j+=pntrToECVsClass_[l]->getNumberOfArguments();
+     825             :     }
+     826      102677 :     for(unsigned i=0; i<deltaF_.size(); i++)
+     827             :     {
+     828      102518 :       const double diff_i=(-getExpansion(i)+deltaF_[i]/kbt_-std::log(t));
+     829      102518 :       if(diff_i>0) //save exp from overflow
+     830       16071 :         deltaF_[i]-=kbt_*(diff_i+std::log1p(std::exp(-diff_i))+std::log1p(-1./(1.+t)));
+     831             :       else
+     832       86447 :         deltaF_[i]-=kbt_*(std::log1p(std::exp(diff_i))+std::log1p(-1./(1.+t)));
+     833             :     }
+     834             :   }
+     835             :   obs_cvs_.clear();
+     836             : 
+     837             : //set deltaF_name_
+     838          20 :   deltaF_name_.resize(deltaF_size_,"DeltaF");
+     839          20 :   unsigned sizeSkip=deltaF_size_;
+     840          45 :   for(unsigned l=0; l<pntrToECVsClass_.size(); l++)
+     841             :   {
+     842          25 :     std::vector<std::string> lambdas_l=pntrToECVsClass_[l]->getLambdas();
+     843          25 :     plumed_massert(lambdas_l.size()==pntrToECVsClass_[l]->getTotNumECVs(),"buggy ECV: mismatch between getTotNumECVs() and getLambdas().size()");
+     844          25 :     sizeSkip/=lambdas_l.size();
+     845       22457 :     for(unsigned i=0; i<deltaF_size_; i++)
+     846       44864 :       deltaF_name_[i]+="_"+lambdas_l[(i/sizeSkip)%lambdas_l.size()];
+     847          25 :   }
+     848             : 
+     849             : //print initialization to file
+     850          20 :   log.printf(" ->%4u DeltaFs in total\n",deltaF_size_);
+     851          20 :   printDeltaF();
+     852          20 : }
+     853             : 
+     854          64 : void OPESexpanded::printDeltaF()
+     855             : {
+     856          64 :   deltaFsOfile_.printField("time",getTime());
+     857          64 :   deltaFsOfile_.printField("rct",rct_);
+     858          64 :   if(NumParallel_==1)
+     859             :   {
+     860       23988 :     for(unsigned i=0; i<deltaF_.size(); i++)
+     861       23926 :       deltaFsOfile_.printField(deltaF_name_[i],deltaF_[i]);
+     862             :   }
+     863             :   else
+     864             :   {
+     865           2 :     comm.Allgatherv(deltaF_,all_deltaF_,&all_size_[0],&disp_[0]); //can we avoid using this big vector?
+     866          66 :     for(unsigned i=0; i<deltaF_size_; i++)
+     867          64 :       deltaFsOfile_.printField(deltaF_name_[i],all_deltaF_[i]);
+     868             :   }
+     869          64 :   deltaFsOfile_.printField();
+     870          64 : }
+     871             : 
+     872          11 : void OPESexpanded::dumpStateToFile()
+     873             : {
+     874             : //rewrite header or rewind file
+     875          11 :   if(storeOldStates_)
+     876           3 :     stateOfile_.clearFields();
+     877           8 :   else if(walker_rank_==0)
+     878           8 :     stateOfile_.rewind();
+     879             : //define fields
+     880          11 :   stateOfile_.addConstantField("time");
+     881          11 :   stateOfile_.addConstantField("counter");
+     882          11 :   stateOfile_.addConstantField("rct");
+     883             : //print
+     884          11 :   stateOfile_.printField("time",getTime());
+     885          11 :   stateOfile_.printField("counter",counter_);
+     886          11 :   stateOfile_.printField("rct",rct_);
+     887          11 :   if(NumParallel_>1)
+     888           0 :     comm.Allgatherv(deltaF_,all_deltaF_,&all_size_[0],&disp_[0]); //can we avoid using this big vector?
+     889         240 :   for(unsigned i=0; i<deltaF_size_; i++)
+     890             :   {
+     891             :     std::size_t pos_start=7; //skip "DeltaF_"
+     892         687 :     for(unsigned j=0; j<ncv_; j++)
+     893             :     {
+     894             :       plumed_dbg_massert(pos_start>6,"not enought _ in deltaF_name_"+std::to_string(i-1)+" string?");
+     895         458 :       const std::size_t pos_end=deltaF_name_[i].find("_",pos_start);
+     896         916 :       stateOfile_.printField(getPntrToArgument(j)->getName(),"  "+deltaF_name_[i].substr(pos_start,pos_end-pos_start));
+     897         458 :       pos_start=pos_end+1;
+     898             :     }
+     899         229 :     if(NumParallel_==1)
+     900         458 :       stateOfile_.printField("DeltaF",deltaF_[i]);
+     901             :     else
+     902           0 :       stateOfile_.printField("DeltaF",all_deltaF_[i]);
+     903         229 :     stateOfile_.printField();
+     904             :   }
+     905             : //make sure file is written even if small
+     906          11 :   if(!storeOldStates_)
+     907           8 :     stateOfile_.flush();
+     908          11 : }
+     909             : 
+     910         660 : void OPESexpanded::updateDeltaF(double bias)
+     911             : {
+     912             :   plumed_dbg_massert(counter_>0,"deltaF_ must be initialized");
+     913         660 :   counter_++;
+     914         660 :   const double arg=(bias-rct_)/kbt_-std::log(counter_-1.);
+     915             :   double increment;
+     916         660 :   if(arg>0) //save exp from overflow
+     917          28 :     increment=kbt_*(arg+std::log1p(std::exp(-arg)));
+     918             :   else
+     919         632 :     increment=kbt_*(std::log1p(std::exp(arg)));
+     920         660 :   #pragma omp parallel num_threads(NumOMP_)
+     921             :   {
+     922             :     #pragma omp for
+     923             :     for(unsigned i=0; i<deltaF_.size(); i++)
+     924             :     {
+     925             :       const double diff_i=(-getExpansion(i)+(bias-rct_+deltaF_[i])/kbt_-std::log(counter_-1.));
+     926             :       if(diff_i>0) //save exp from overflow
+     927             :         deltaF_[i]+=increment-kbt_*(diff_i+std::log1p(std::exp(-diff_i)));
+     928             :       else
+     929             :         deltaF_[i]+=increment-kbt_*std::log1p(std::exp(diff_i));
+     930             :     }
+     931             :   }
+     932         660 :   rct_+=increment+kbt_*std::log1p(-1./counter_);
+     933         660 : }
+     934             : 
+     935      644469 : double OPESexpanded::getExpansion(unsigned i) const
+     936             : {
+     937             :   double expansion=0;
+     938     3003062 :   for(unsigned j=0; j<ncv_; j++)
+     939     2358593 :     expansion+=ECVs_[j][index_k_[i][j]]; //the index_k could be trivially guessed for most ECVs, but unfourtunately not all
+     940      644469 :   return expansion;
+     941             : }
+     942             : 
+     943             : }
+     944             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/OPESmetad.cpp.func-sort-c.html b/coverage/opes/OPESmetad.cpp.func-sort-c.html new file mode 100644 index 000000000000..996d8a27350b --- /dev/null +++ b/coverage/opes/OPESmetad.cpp.func-sort-c.html @@ -0,0 +1,185 @@ + + + + + + + + LCOV - plumed test coverage - opes/OPESmetad.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - opes - OPESmetad.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:78982495.8 %
Date:2024-04-19 12:12:35Functions:272896.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4opes9OPESmetadINS0_11explorationEE11updateNlistERKSt6vectorIdSaIdEE0
_ZN4PLMD4opes9OPESmetadINS0_11explorationEEC1ERKNS_13ActionOptionsE7
_ZN4PLMD4opes9OPESmetadINS0_11explorationEE15dumpStateToFileEv8
_ZN4PLMD4opes9OPESmetadINS0_11explorationEE16registerKeywordsERNS_8KeywordsE9
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEE15dumpStateToFileEv10
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEEC1ERKNS_13ActionOptionsE14
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEE16registerKeywordsERNS_8KeywordsE16
_ZN4PLMD4opes9OPESmetadINS0_11explorationEE9addKernelEdRKSt6vectorIdSaIdEES8_d106
_ZN4PLMD4opes9OPESmetadINS0_11explorationEE12mergeKernelsERNS3_6kernelERKS4_111
_ZN4PLMD4opes9OPESmetadINS0_11explorationEE9addKernelEdRKSt6vectorIdSaIdEES8_126
_ZNK4PLMD4opes9OPESmetadINS0_11explorationEE14evaluateKernelERKNS3_6kernelERKSt6vectorIdSaIdEE148
_ZN4PLMD4opes9OPESmetadINS0_11explorationEE18getMergeableKernelERKSt6vectorIdSaIdEEj196
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEE11updateNlistERKSt6vectorIdSaIdEE250
_ZN4PLMD4opes9OPESmetadINS0_11explorationEE6kernelC2EdRKSt6vectorIdSaIdEES9_256
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEE12mergeKernelsERNS3_6kernelERKS4_277
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEE9addKernelEdRKSt6vectorIdSaIdEES8_d277
_ZN4PLMD4opes9OPESmetadINS0_11explorationEE6updateEv357
_ZN4PLMD4opes9OPESmetadINS0_11explorationEE9calculateEv357
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEE9addKernelEdRKSt6vectorIdSaIdEES8_387
_ZN4PLMD4opes9OPESmetadINS0_11explorationEE21getProbAndDerivativesERKSt6vectorIdSaIdEERS6_387
_ZN4PLMD4opes9OPESmetadINS0_11explorationEE14evaluateKernelERKNS3_6kernelERKSt6vectorIdSaIdEERS9_SC_604
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEE18getMergeableKernelERKSt6vectorIdSaIdEEj654
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEE6updateEv714
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEE9calculateEv714
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEE21getProbAndDerivativesERKSt6vectorIdSaIdEERS6_754
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEE6kernelC2EdRKSt6vectorIdSaIdEES9_794
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEE14evaluateKernelERKNS3_6kernelERKSt6vectorIdSaIdEERS9_SC_2760
_ZNK4PLMD4opes9OPESmetadINS0_11convergenceEE14evaluateKernelERKNS3_6kernelERKSt6vectorIdSaIdEE5821
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/OPESmetad.cpp.func.html b/coverage/opes/OPESmetad.cpp.func.html new file mode 100644 index 000000000000..5b70dc4d38ad --- /dev/null +++ b/coverage/opes/OPESmetad.cpp.func.html @@ -0,0 +1,185 @@ + + + + + + + + LCOV - plumed test coverage - opes/OPESmetad.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - opes - OPESmetad.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:78982495.8 %
Date:2024-04-19 12:12:35Functions:272896.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEE11updateNlistERKSt6vectorIdSaIdEE250
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEE12mergeKernelsERNS3_6kernelERKS4_277
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEE14evaluateKernelERKNS3_6kernelERKSt6vectorIdSaIdEERS9_SC_2760
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEE15dumpStateToFileEv10
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEE16registerKeywordsERNS_8KeywordsE16
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEE18getMergeableKernelERKSt6vectorIdSaIdEEj654
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEE21getProbAndDerivativesERKSt6vectorIdSaIdEERS6_754
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEE6kernelC2EdRKSt6vectorIdSaIdEES9_794
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEE6updateEv714
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEE9addKernelEdRKSt6vectorIdSaIdEES8_387
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEE9addKernelEdRKSt6vectorIdSaIdEES8_d277
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEE9calculateEv714
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEEC1ERKNS_13ActionOptionsE14
_ZN4PLMD4opes9OPESmetadINS0_11explorationEE11updateNlistERKSt6vectorIdSaIdEE0
_ZN4PLMD4opes9OPESmetadINS0_11explorationEE12mergeKernelsERNS3_6kernelERKS4_111
_ZN4PLMD4opes9OPESmetadINS0_11explorationEE14evaluateKernelERKNS3_6kernelERKSt6vectorIdSaIdEERS9_SC_604
_ZN4PLMD4opes9OPESmetadINS0_11explorationEE15dumpStateToFileEv8
_ZN4PLMD4opes9OPESmetadINS0_11explorationEE16registerKeywordsERNS_8KeywordsE9
_ZN4PLMD4opes9OPESmetadINS0_11explorationEE18getMergeableKernelERKSt6vectorIdSaIdEEj196
_ZN4PLMD4opes9OPESmetadINS0_11explorationEE21getProbAndDerivativesERKSt6vectorIdSaIdEERS6_387
_ZN4PLMD4opes9OPESmetadINS0_11explorationEE6kernelC2EdRKSt6vectorIdSaIdEES9_256
_ZN4PLMD4opes9OPESmetadINS0_11explorationEE6updateEv357
_ZN4PLMD4opes9OPESmetadINS0_11explorationEE9addKernelEdRKSt6vectorIdSaIdEES8_126
_ZN4PLMD4opes9OPESmetadINS0_11explorationEE9addKernelEdRKSt6vectorIdSaIdEES8_d106
_ZN4PLMD4opes9OPESmetadINS0_11explorationEE9calculateEv357
_ZN4PLMD4opes9OPESmetadINS0_11explorationEEC1ERKNS_13ActionOptionsE7
_ZNK4PLMD4opes9OPESmetadINS0_11convergenceEE14evaluateKernelERKNS3_6kernelERKSt6vectorIdSaIdEE5821
_ZNK4PLMD4opes9OPESmetadINS0_11explorationEE14evaluateKernelERKNS3_6kernelERKSt6vectorIdSaIdEE148
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/OPESmetad.cpp.gcov.html b/coverage/opes/OPESmetad.cpp.gcov.html new file mode 100644 index 000000000000..f88a1869266b --- /dev/null +++ b/coverage/opes/OPESmetad.cpp.gcov.html @@ -0,0 +1,1829 @@ + + + + + + + + LCOV - plumed test coverage - opes/OPESmetad.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - opes - OPESmetad.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:78982495.8 %
Date:2024-04-19 12:12:35Functions:272896.4 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2020-2021 of Michele Invernizzi.
+       3             : 
+       4             :    This file is part of the OPES plumed module.
+       5             : 
+       6             :    The OPES plumed module is free software: you can redistribute it and/or modify
+       7             :    it under the terms of the GNU Lesser General Public License as published by
+       8             :    the Free Software Foundation, either version 3 of the License, or
+       9             :    (at your option) any later version.
+      10             : 
+      11             :    The OPES plumed module is distributed in the hope that it will be useful,
+      12             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      13             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      14             :    GNU Lesser General Public License for more details.
+      15             : 
+      16             :    You should have received a copy of the GNU Lesser General Public License
+      17             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      18             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      19             : #include "bias/Bias.h"
+      20             : #include "core/PlumedMain.h"
+      21             : #include "core/ActionRegister.h"
+      22             : #include "tools/Communicator.h"
+      23             : #include "tools/File.h"
+      24             : #include "tools/OpenMP.h"
+      25             : 
+      26             : namespace PLMD {
+      27             : namespace opes {
+      28             : 
+      29             : //+PLUMEDOC OPES_BIAS OPES_METAD
+      30             : /*
+      31             : On-the-fly probability enhanced sampling with metadynamics-like target distribution.
+      32             : 
+      33             : This On-the-fly probability enhanced sampling (\ref OPES "OPES") method with metadynamics-like target distribution is described in \cite Invernizzi2020rethinking.
+      34             : 
+      35             : This \ref OPES_METAD action samples target distributions defined via their marginal \f$p^{\text{tg}}(\mathbf{s})\f$ over some collective variables (CVs), \f$\mathbf{s}=\mathbf{s}(\mathbf{x})\f$.
+      36             : By default \ref OPES_METAD targets the well-tempered distribution, \f$p^{\text{WT}}(\mathbf{s})\propto [P(\mathbf{s})]^{1/\gamma}\f$, where \f$\gamma\f$ is known as BIASFACTOR.
+      37             : Similarly to \ref METAD, \ref OPES_METAD optimizes the bias on-the-fly, with a given PACE.
+      38             : It does so by reweighting via kernel density estimation the unbiased distribution in the CV space, \f$P(\mathbf{s})\f$.
+      39             : A compression algorithm is used to prevent the number of kernels from growing linearly with the simulation time.
+      40             : The bias at step \f$n\f$ is
+      41             : \f[
+      42             : V_n(\mathbf{s}) = (1-1/\gamma)\frac{1}{\beta}\log\left(\frac{P_n(\mathbf{s})}{Z_n}+\epsilon\right)\, .
+      43             : \f]
+      44             : See Ref.\cite Invernizzi2020rethinking for a complete description of the method.
+      45             : 
+      46             : As an intuitive picture, rather than gradually filling the metastable basins, \ref OPES_METAD quickly tries to get a coarse idea of the full free energy surface (FES), and then slowly refines its details.
+      47             : It has a fast initial exploration phase, and then becomes extremely conservative and does not significantly change the shape of the deposited bias any more, reaching a regime of quasi-static bias.
+      48             : For this reason, it is possible to use standard umbrella sampling reweighting (see \ref REWEIGHT_BIAS) to analyse the trajectory.
+      49             : At <a href="https://github.com/invemichele/opes/tree/master/postprocessing">this link</a> you can find some python scripts that work in a similar way to \ref sum_hills, but the preferred way to obtain a FES with OPES is via reweighting (see \ref opes-metad).
+      50             : The estimated \f$c(t)\f$ is printed for reference only, since it should converge to a fixed value as the bias converges.
+      51             : This \f$c(t)\f$ should NOT be used for reweighting.
+      52             : Similarly, the \f$Z_n\f$ factor is printed only for reference, and it should converge when no new region of the CV-space is explored.
+      53             : 
+      54             : Notice that \ref OPES_METAD is more sensitive to degenerate CVs than \ref METAD.
+      55             : If the employed CVs map different metastable basins onto the same CV-space region, then \ref OPES_METAD will remain stuck rather than completely reshaping the bias.
+      56             : This can be useful to diagnose problems with your collective variable.
+      57             : If it is not possible to improve the set of CVs and remove this degeneracy, then you might instead consider to use \ref OPES_METAD_EXPLORE or \ref METAD.
+      58             : In this way you will be able to obtain an estimate of the FES, but be aware that you most likely will not reach convergence and thus this estimate will be subjected to systematic errors (see e.g. Fig.3 in \cite Pietrucci2017review).
+      59             : On the contrary, if your CVs are not degenerate but only suboptimal, you should converge faster by using \ref OPES_METAD instead of \ref METAD \cite Invernizzi2020rethinking.
+      60             : 
+      61             : The parameter BARRIER should be set to be at least equal to the highest free energy barrier you wish to overcome.
+      62             : If it is much lower than that, you will not cross the barrier, if it is much higher, convergence might take a little longer.
+      63             : If the system has a basin that is clearly more stable than the others, it is better to start the simulation from there.
+      64             : 
+      65             : By default, the kernels SIGMA is adaptive, estimated from the fluctuations over ADAPTIVE_SIGMA_STRIDE simulation steps (similar to \ref METAD ADAPTIVE=DIFF, but contrary to that, no artifacts are introduced and the bias will converge to the correct one).
+      66             : However, notice that depending on the system this might not be the optimal choice for SIGMA.
+      67             : 
+      68             : You can target a uniform flat distribution by explicitly setting BIASFACTOR=inf.
+      69             : However, this should be useful only in very specific cases.
+      70             : 
+      71             : It is possible to take into account also of other bias potentials besides the one of \ref OPES_METAD during the internal reweighting for \f$P(\mathbf{s})\f$ estimation.
+      72             : To do so, one has to add those biases with the EXTRA_BIAS keyword, as in the example below.
+      73             : This allows one to define a custom target distribution by adding another bias potential equal to the desired target free energy and setting BIASFACTOR=inf (see example below).
+      74             : Another possible usage of EXTRA_BIAS is to make sure that \ref OPES_METAD does not push against another fixed bias added to restrain the CVs range (e.g. \ref UPPER_WALLS).
+      75             : 
+      76             : Through the EXCLUDED_REGION keywork, it is possible to specify a region of CV space where no kernels will be deposited.
+      77             : This can be useful for example for making sure the bias does not modify the transition region, thus allowing for rate calculation.
+      78             : See below for an example of how to use this keyword.
+      79             : 
+      80             : Restart can be done from a KERNELS file, but it might be not perfect (due to limited precision when printing kernels to file, or if adaptive SIGMA is used).
+      81             : For an exact restart you must use STATE_RFILE to read a checkpoint with all the needed info.
+      82             : To save such checkpoints, define a STATE_WFILE and choose how often to print them with STATE_WSTRIDE.
+      83             : By default this file is overwritten, but you can instead append to it using the flag STORE_STATES.
+      84             : 
+      85             : Multiple walkers are supported only with MPI communication, via the keyword WALKERS_MPI.
+      86             : 
+      87             : \par Examples
+      88             : 
+      89             : Several examples can be found on the <a href="https://www.plumed-nest.org/browse.html">PLUMED-NEST website</a>, by searching for the OPES keyword.
+      90             : The \ref opes-metad can also be useful to get started with the method.
+      91             : 
+      92             : The following is a minimal working example:
+      93             : 
+      94             : \plumedfile
+      95             : cv: DISTANCE ATOMS=1,2
+      96             : opes: OPES_METAD ARG=cv PACE=200 BARRIER=40
+      97             : PRINT STRIDE=200 FILE=COLVAR ARG=*
+      98             : \endplumedfile
+      99             : 
+     100             : Another more articulated one:
+     101             : 
+     102             : \plumedfile
+     103             : phi: TORSION ATOMS=5,7,9,15
+     104             : psi: TORSION ATOMS=7,9,15,17
+     105             : opes: OPES_METAD ...
+     106             :   FILE=Kernels.data
+     107             :   TEMP=300
+     108             :   ARG=phi,psi
+     109             :   PACE=500
+     110             :   BARRIER=50
+     111             :   SIGMA=0.15,0.15
+     112             :   SIGMA_MIN=0.01,0.01
+     113             :   STATE_RFILE=Restart.data
+     114             :   STATE_WFILE=State.data
+     115             :   STATE_WSTRIDE=500*100
+     116             :   STORE_STATES
+     117             :   WALKERS_MPI
+     118             :   NLIST
+     119             : ...
+     120             : PRINT FMT=%g STRIDE=500 FILE=Colvar.data ARG=phi,psi,opes.*
+     121             : \endplumedfile
+     122             : 
+     123             : Next is an example of how to define a custom target distribution different from the well-tempered one.
+     124             : Here we chose to focus more on the transition state, that is around \f$\phi=0\f$.
+     125             : Our target distribution is a Gaussian centered there, thus the target free energy we want to sample is a parabola, \f$F^{\text{tg}}(\mathbf{s})=-\frac{1}{\beta} \log [p^{\text{tg}}(\mathbf{s})]\f$.
+     126             : 
+     127             : \plumedfile
+     128             : phi: TORSION ATOMS=5,7,9,15
+     129             : FtgValue: CUSTOM ARG=phi PERIODIC=NO FUNC=(x/0.4)^2
+     130             : Ftg: BIASVALUE ARG=FtgValue
+     131             : opes: OPES_METAD ...
+     132             :   ARG=phi
+     133             :   PACE=500
+     134             :   BARRIER=50
+     135             :   SIGMA=0.2
+     136             :   BIASFACTOR=inf
+     137             :   EXTRA_BIAS=Ftg.bias
+     138             : ...
+     139             : PRINT FMT=%g STRIDE=500 FILE=COLVAR ARG=phi,Ftg.bias,opes.bias
+     140             : \endplumedfile
+     141             : 
+     142             : Notice that in order to reweight for the unbiased \f$P(\mathbf{s})\f$ during postprocessing, the total bias `Ftg.bias+opes.bias` must be used.
+     143             : 
+     144             : Finally, an example of how to use the EXCLUDED_REGION keyword.
+     145             : It expects a characteristic function that is different from zero in the region to be excluded.
+     146             : You can use \ref CUSTOM and a combination of the step function to define it.
+     147             : With the following input no kernel is deposited in the transition state region of alanine dipeptide, defined by the interval \f$\phi \in [-0.6, 0.7]\f$:
+     148             : 
+     149             : \plumedfile
+     150             : phi: TORSION ATOMS=5,7,9,15
+     151             : psi: TORSION ATOMS=7,9,15,17
+     152             : xx: CUSTOM PERIODIC=NO ARG=phi FUNC=step(x+0.6)-step(x-0.7)
+     153             : opes: OPES_METAD ...
+     154             :   ARG=phi,psi
+     155             :   PACE=500
+     156             :   BARRIER=30
+     157             :   EXCLUDED_REGION=xx
+     158             :   NLIST
+     159             : ...
+     160             : PRINT FMT=%g STRIDE=500 FILE=COLVAR ARG=phi,psi,xx,opes.*
+     161             : \endplumedfile
+     162             : 
+     163             : */
+     164             : //+ENDPLUMEDOC
+     165             : 
+     166             : template <class mode>
+     167             : class OPESmetad : public bias::Bias {
+     168             : 
+     169             : private:
+     170             :   bool isFirstStep_;
+     171             :   unsigned NumOMP_;
+     172             :   unsigned NumParallel_;
+     173             :   unsigned rank_;
+     174             :   unsigned NumWalkers_;
+     175             :   unsigned walker_rank_;
+     176             :   unsigned long long counter_;
+     177             :   std::size_t ncv_;
+     178             : 
+     179             :   double kbt_;
+     180             :   double biasfactor_;
+     181             :   double bias_prefactor_;
+     182             :   unsigned stride_;
+     183             :   std::vector<double> sigma0_;
+     184             :   std::vector<double> sigma_min_;
+     185             :   unsigned adaptive_sigma_stride_;
+     186             :   unsigned long long adaptive_counter_;
+     187             :   std::vector<double> av_cv_;
+     188             :   std::vector<double> av_M2_;
+     189             :   bool fixed_sigma_;
+     190             :   bool adaptive_sigma_;
+     191             :   double epsilon_;
+     192             :   double sum_weights_;
+     193             :   double sum_weights2_;
+     194             : 
+     195             :   bool no_Zed_;
+     196             :   double Zed_;
+     197             :   double KDEnorm_;
+     198             : 
+     199             :   double threshold2_;
+     200             :   bool recursive_merge_;
+     201             : //kernels are truncated diagonal Gaussians
+     202        1050 :   struct kernel
+     203             :   {
+     204             :     double height;
+     205             :     std::vector<double> center;
+     206             :     std::vector<double> sigma;
+     207        1050 :     kernel(double h, const std::vector<double>& c,const std::vector<double>& s):
+     208        1050 :       height(h),center(c),sigma(s) {}
+     209             :   };
+     210             :   double cutoff2_;
+     211             :   double val_at_cutoff_;
+     212             :   void mergeKernels(kernel&,const kernel&); //merge the second one into the first one
+     213             :   double evaluateKernel(const kernel&,const std::vector<double>&) const;
+     214             :   double evaluateKernel(const kernel&,const std::vector<double>&,std::vector<double>&,std::vector<double>&);
+     215             :   std::vector<kernel> kernels_; //all compressed kernels
+     216             :   OFile kernelsOfile_;
+     217             : //neighbour list stuff
+     218             :   bool nlist_;
+     219             :   double nlist_param_[2];
+     220             :   std::vector<unsigned> nlist_index_;
+     221             :   std::vector<double> nlist_center_;
+     222             :   std::vector<double> nlist_dev2_;
+     223             :   unsigned nlist_steps_;
+     224             :   bool nlist_update_;
+     225             :   bool nlist_pace_reset_;
+     226             : 
+     227             :   bool calc_work_;
+     228             :   double work_;
+     229             :   double old_KDEnorm_;
+     230             :   std::vector<kernel> delta_kernels_;
+     231             : 
+     232             :   Value* excluded_region_;
+     233             :   std::vector<Value*> extra_biases_;
+     234             : 
+     235             :   OFile stateOfile_;
+     236             :   int wStateStride_;
+     237             :   bool storeOldStates_;
+     238             : 
+     239             :   double getProbAndDerivatives(const std::vector<double>&,std::vector<double>&);
+     240             :   void addKernel(const double,const std::vector<double>&,const std::vector<double>&);
+     241             :   void addKernel(const double,const std::vector<double>&,const std::vector<double>&,const double); //also print to file
+     242             :   unsigned getMergeableKernel(const std::vector<double>&,const unsigned);
+     243             :   void updateNlist(const std::vector<double>&);
+     244             :   void dumpStateToFile();
+     245             : 
+     246             : public:
+     247             :   explicit OPESmetad(const ActionOptions&);
+     248             :   void calculate() override;
+     249             :   void update() override;
+     250             :   static void registerKeywords(Keywords& keys);
+     251             : };
+     252             : 
+     253             : struct convergence { static const bool explore=false; };
+     254             : typedef OPESmetad<convergence> OPESmetad_c;
+     255             : PLUMED_REGISTER_ACTION(OPESmetad_c,"OPES_METAD")
+     256             : 
+     257             : //OPES_METAD_EXPLORE is very similar from the point of view of the code,
+     258             : //but conceptually it is better to make it a separate BIAS action
+     259             : 
+     260             : //+PLUMEDOC OPES_BIAS OPES_METAD_EXPLORE
+     261             : /*
+     262             : On-the-fly probability enhanced sampling with well-tempered target distribution in exploreation mode.
+     263             : 
+     264             : On-the-fly probability enhanced sampling with well-tempered target distribution (\ref OPES "OPES") with well-tempered target distribution, exploration mode \cite Invernizzi2022explore .
+     265             : 
+     266             : This \ref OPES_METAD_EXPLORE action samples the well-tempered target distribution, that is defined via its marginal \f$p^{\text{WT}}(\mathbf{s})\propto [P(\mathbf{s})]^{1/\gamma}\f$ over some collective variables (CVs), \f$\mathbf{s}=\mathbf{s}(\mathbf{x})\f$.
+     267             : While \ref OPES_METAD does so by estimating the unbiased distribution \f$P(\mathbf{s})\f$, \ref OPES_METAD_EXPLORE instead estimates on-the-fly the target \f$p^{\text{WT}}(\mathbf{s})\f$ and uses it to define the bias.
+     268             : The bias at step \f$n\f$ is
+     269             : \f[
+     270             : V_n(\mathbf{s}) = (\gamma-1)\frac{1}{\beta}\log\left(\frac{p^{\text{WT}}_n(\mathbf{s})}{Z_n}+\epsilon\right)\, .
+     271             : \f]
+     272             : See Ref.\cite Invernizzi2022explore for a complete description of the method.
+     273             : 
+     274             : Intuitively, while \ref OPES_METAD aims at quickly converging the reweighted free energy, \ref OPES_METAD_EXPLORE aims at quickly sampling the target well-tempered distribution.
+     275             : Given enough simulation time, both will converge to the same bias potential but they do so in a qualitatively different way.
+     276             : Compared to \ref OPES_METAD, \ref OPES_METAD_EXPLORE is more similar to \ref METAD, because it allows the bias to vary significantly, thus enhancing exploration.
+     277             : This goes at the expenses of a typically slower convergence of the reweight estimate.
+     278             : \ref OPES_METAD_EXPLORE can be useful e.g.~for simulating a new system with an unknown BARRIER, or for quickly testing the effectiveness of a new CV that might be degenerate.
+     279             : 
+     280             : Similarly to \ref OPES_METAD, also \ref OPES_METAD_EXPLORE uses a kernel density estimation with the same on-the-fly compression algorithm.
+     281             : The only difference is that the kernels are not weighted, since it estimates the sampled distribution and not the reweighted unbiased one.
+     282             : 
+     283             : All the options of \ref OPES_METAD are also available in \ref OPES_METAD_EXPLORE, except for those that modify the target distribution, since only a well-tempered target is allowed in this case.
+     284             : 
+     285             : \par Examples
+     286             : 
+     287             : The following is a minimal working example:
+     288             : 
+     289             : \plumedfile
+     290             : cv: DISTANCE ATOMS=1,2
+     291             : opes: OPES_METAD_EXPLORE ARG=cv PACE=500 BARRIER=40
+     292             : PRINT STRIDE=100 FILE=COLVAR ARG=cv,opes.*
+     293             : \endplumedfile
+     294             : */
+     295             : //+ENDPLUMEDOC
+     296             : 
+     297             : struct exploration { static const bool explore=true; };
+     298             : typedef OPESmetad<exploration> OPESmetad_e;
+     299             : PLUMED_REGISTER_ACTION(OPESmetad_e,"OPES_METAD_EXPLORE")
+     300             : 
+     301             : template <class mode>
+     302          25 : void OPESmetad<mode>::registerKeywords(Keywords& keys)
+     303             : {
+     304          25 :   Bias::registerKeywords(keys);
+     305          25 :   keys.use("ARG");
+     306          50 :   keys.add("compulsory","TEMP","-1","temperature. If not set, it is taken from MD engine, but not all MD codes provide it");
+     307          50 :   keys.add("compulsory","PACE","the frequency for kernel deposition");
+     308          25 :   std::string info_sigma("the initial widths of the kernels");
+     309             :   if(mode::explore)
+     310             :     info_sigma+=", divided by the square root of gamma";
+     311             :   info_sigma+=". If not set, an adaptive sigma will be used with the given ADAPTIVE_SIGMA_STRIDE";
+     312          50 :   keys.add("compulsory","SIGMA","ADAPTIVE",info_sigma);
+     313          50 :   keys.add("compulsory","BARRIER","the free energy barrier to be overcome. It is used to set BIASFACTOR, EPSILON, and KERNEL_CUTOFF to reasonable values");
+     314          50 :   keys.add("compulsory","COMPRESSION_THRESHOLD","1","merge kernels if closer than this threshold, in units of sigma");
+     315             : //extra options
+     316          50 :   keys.add("optional","ADAPTIVE_SIGMA_STRIDE","number of steps for measuring adaptive sigma. Default is 10xPACE");
+     317          50 :   keys.add("optional","SIGMA_MIN","never reduce SIGMA below this value");
+     318          25 :   std::string info_biasfactor("the gamma bias factor used for the well-tempered target distribution. ");
+     319             :   if(mode::explore)
+     320             :     info_biasfactor+="Cannot be 'inf'";
+     321             :   else
+     322             :     info_biasfactor+="Set to 'inf' for uniform flat target";
+     323          50 :   keys.add("optional","BIASFACTOR",info_biasfactor);
+     324          50 :   keys.add("optional","EPSILON","the value of the regularization constant for the probability");
+     325          50 :   keys.add("optional","KERNEL_CUTOFF","truncate kernels at this distance, in units of sigma");
+     326          50 :   keys.add("optional","NLIST_PARAMETERS","( default=3.0,0.5 ) the two cutoff parameters for the kernels neighbor list");
+     327          50 :   keys.addFlag("NLIST",false,"use neighbor list for kernels summation, faster but experimental");
+     328          50 :   keys.addFlag("NLIST_PACE_RESET",false,"force the reset of the neighbor list at each PACE. Can be useful with WALKERS_MPI");
+     329          50 :   keys.addFlag("FIXED_SIGMA",false,"do not decrease sigma as the simulation proceeds. Can be added in a RESTART, to keep in check the number of compressed kernels");
+     330          50 :   keys.addFlag("RECURSIVE_MERGE_OFF",false,"do not recursively attempt kernel merging when a new one is added");
+     331          50 :   keys.addFlag("NO_ZED",false,"do not normalize over the explored CV space, Z_n=1");
+     332             : //kernels and state files
+     333          50 :   keys.add("compulsory","FILE","KERNELS","a file in which the list of all deposited kernels is stored");
+     334          50 :   keys.add("optional","FMT","specify format for KERNELS file");
+     335          50 :   keys.add("optional","STATE_RFILE","read from this file the compressed kernels and all the info needed to RESTART the simulation");
+     336          50 :   keys.add("optional","STATE_WFILE","write to this file the compressed kernels and all the info needed to RESTART the simulation");
+     337          50 :   keys.add("optional","STATE_WSTRIDE","number of MD steps between writing the STATE_WFILE. Default is only on CPT events (but not all MD codes set them)");
+     338          50 :   keys.addFlag("STORE_STATES",false,"append to STATE_WFILE instead of ovewriting it each time");
+     339             : //miscellaneous
+     340          50 :   keys.add("optional","EXCLUDED_REGION","kernels are not deposited when the action provided here has a nonzero value, see example above");
+     341             :   if(!mode::explore)
+     342          32 :     keys.add("optional","EXTRA_BIAS","consider also these other bias potentials for the internal reweighting. This can be used e.g. for sampling a custom target distribution (see example above)");
+     343          50 :   keys.addFlag("CALC_WORK",false,"calculate the total accumulated work done by the bias since last restart");
+     344          50 :   keys.addFlag("WALKERS_MPI",false,"switch on MPI version of multiple walkers");
+     345          50 :   keys.addFlag("SERIAL",false,"perform calculations in serial");
+     346          25 :   keys.use("RESTART");
+     347          25 :   keys.use("UPDATE_FROM");
+     348          25 :   keys.use("UPDATE_UNTIL");
+     349             : 
+     350             : //output components
+     351          50 :   keys.addOutputComponent("rct","default","estimate of c(t). \\f$\\frac{1}{\\beta}\\log \\langle e^{\\beta V} \\rangle\\f$, should become flat as the simulation converges. Do NOT use for reweighting");
+     352          50 :   keys.addOutputComponent("zed","default","estimate of Z_n. should become flat once no new CV-space region is explored");
+     353          50 :   keys.addOutputComponent("neff","default","effective sample size");
+     354          50 :   keys.addOutputComponent("nker","default","total number of compressed kernels used to represent the bias");
+     355          50 :   keys.addOutputComponent("work","CALC_WORK","total accumulated work done by the bias");
+     356          50 :   keys.addOutputComponent("nlker","NLIST","number of kernels in the neighbor list");
+     357          50 :   keys.addOutputComponent("nlsteps","NLIST","number of steps from last neighbor list update");
+     358          25 : }
+     359             : 
+     360             : template <class mode>
+     361          21 : OPESmetad<mode>::OPESmetad(const ActionOptions& ao)
+     362             :   : PLUMED_BIAS_INIT(ao)
+     363          21 :   , isFirstStep_(true)
+     364          21 :   , counter_(1)
+     365          21 :   , ncv_(getNumberOfArguments())
+     366          21 :   , Zed_(1)
+     367          21 :   , work_(0)
+     368          21 :   , excluded_region_(NULL)
+     369             : {
+     370          42 :   std::string error_in_input1("Error in input in action "+getName()+" with label "+getLabel()+": the keyword ");
+     371          21 :   std::string error_in_input2(" could not be read correctly");
+     372             : 
+     373             : //set kbt_
+     374          21 :   const double kB=getKBoltzmann();
+     375          21 :   kbt_=getkBT();
+     376             : 
+     377             : //other compulsory input
+     378          21 :   parse("PACE",stride_);
+     379             : 
+     380          21 :   double barrier=0;
+     381          21 :   parse("BARRIER",barrier);
+     382          21 :   plumed_massert(barrier>=0,"the BARRIER should be greater than zero");
+     383             : 
+     384          21 :   biasfactor_=barrier/kbt_;
+     385             :   std::string biasfactor_str;
+     386          42 :   parse("BIASFACTOR",biasfactor_str);
+     387          38 :   if(biasfactor_str=="inf" || biasfactor_str=="INF")
+     388             :   {
+     389           4 :     biasfactor_=std::numeric_limits<double>::infinity();
+     390           4 :     bias_prefactor_=1;
+     391             :   }
+     392             :   else
+     393             :   {
+     394          17 :     if(biasfactor_str.length()>0)
+     395           3 :       plumed_massert(Tools::convertNoexcept(biasfactor_str,biasfactor_),error_in_input1+"BIASFACTOR"+error_in_input2);
+     396          17 :     plumed_massert(biasfactor_>1,"BIASFACTOR must be greater than one (use 'inf' for uniform target)");
+     397          17 :     bias_prefactor_=1-1./biasfactor_;
+     398             :   }
+     399             :   if(mode::explore)
+     400             :   {
+     401           7 :     plumed_massert(!std::isinf(biasfactor_),"BIASFACTOR=inf is not compatible with EXPLORE mode");
+     402           7 :     bias_prefactor_=biasfactor_-1;
+     403             :   }
+     404             : 
+     405          21 :   adaptive_sigma_=false;
+     406          21 :   adaptive_sigma_stride_=0;
+     407          42 :   parse("ADAPTIVE_SIGMA_STRIDE",adaptive_sigma_stride_);
+     408             :   std::vector<std::string> sigma_str;
+     409          21 :   parseVector("SIGMA",sigma_str);
+     410          21 :   sigma0_.resize(ncv_);
+     411             :   double dummy;
+     412          21 :   if(sigma_str.size()==1 && !Tools::convertNoexcept(sigma_str[0],dummy))
+     413             :   {
+     414          11 :     plumed_massert(sigma_str[0]=="ADAPTIVE" || sigma_str[0]=="adaptive",error_in_input1+"SIGMA"+error_in_input2);
+     415          11 :     plumed_massert(!std::isinf(biasfactor_),"cannot use BIASFACTOR=inf with adaptive SIGMA");
+     416          11 :     adaptive_counter_=0;
+     417          11 :     if(adaptive_sigma_stride_==0)
+     418           2 :       adaptive_sigma_stride_=10*stride_; //NB: this is arbitrary, chosen from few tests
+     419          11 :     av_cv_.resize(ncv_,0);
+     420          11 :     av_M2_.resize(ncv_,0);
+     421          11 :     plumed_massert(adaptive_sigma_stride_>=stride_,"better to chose ADAPTIVE_SIGMA_STRIDE > PACE");
+     422          11 :     adaptive_sigma_=true;
+     423             :   }
+     424             :   else
+     425             :   {
+     426          10 :     plumed_massert(sigma_str.size()==ncv_,"number of SIGMA parameters does not match number of arguments");
+     427          10 :     plumed_massert(adaptive_sigma_stride_==0,"if SIGMA is not ADAPTIVE you cannot set an ADAPTIVE_SIGMA_STRIDE");
+     428          29 :     for(unsigned i=0; i<ncv_; i++)
+     429             :     {
+     430          19 :       plumed_massert(Tools::convertNoexcept(sigma_str[i],sigma0_[i]),error_in_input1+"SIGMA"+error_in_input2);
+     431             :       if(mode::explore)
+     432           6 :         sigma0_[i]*=std::sqrt(biasfactor_); //the sigma of the target is broader Ftg(s)=1/gamma*F(s)
+     433             :     }
+     434             :   }
+     435          42 :   parseVector("SIGMA_MIN",sigma_min_);
+     436          21 :   plumed_massert(sigma_min_.size()==0 || sigma_min_.size()==ncv_,"number of SIGMA_MIN does not match number of arguments");
+     437          21 :   if(sigma_min_.size()>0 && !adaptive_sigma_)
+     438             :   {
+     439           3 :     for(unsigned i=0; i<ncv_; i++)
+     440           2 :       plumed_massert(sigma_min_[i]<=sigma0_[i],"SIGMA_MIN should be smaller than SIGMA");
+     441             :   }
+     442             : 
+     443          21 :   epsilon_=std::exp(-barrier/bias_prefactor_/kbt_);
+     444          21 :   parse("EPSILON",epsilon_);
+     445          21 :   plumed_massert(epsilon_>0,"you must choose a value for EPSILON greater than zero. Is your BARRIER too high?");
+     446          21 :   sum_weights_=std::pow(epsilon_,bias_prefactor_); //to avoid NANs we start with counter_=1 and w0=exp(beta*V0)
+     447          21 :   sum_weights2_=sum_weights_*sum_weights_;
+     448             : 
+     449          21 :   double cutoff=sqrt(2.*barrier/bias_prefactor_/kbt_);
+     450             :   if(mode::explore)
+     451           7 :     cutoff=sqrt(2.*barrier/kbt_); //otherwise it is too small
+     452          21 :   parse("KERNEL_CUTOFF",cutoff);
+     453          21 :   plumed_massert(cutoff>0,"you must choose a value for KERNEL_CUTOFF greater than zero");
+     454          21 :   cutoff2_=cutoff*cutoff;
+     455          21 :   val_at_cutoff_=std::exp(-0.5*cutoff2_);
+     456             : 
+     457          21 :   threshold2_=1;
+     458          21 :   parse("COMPRESSION_THRESHOLD",threshold2_);
+     459          21 :   threshold2_*=threshold2_;
+     460          21 :   if(threshold2_!=0)
+     461          21 :     plumed_massert(threshold2_>0 && threshold2_<cutoff2_,"COMPRESSION_THRESHOLD cannot be bigger than the KERNEL_CUTOFF");
+     462             : 
+     463             : //setup neighbor list
+     464          21 :   nlist_=false;
+     465          21 :   parseFlag("NLIST",nlist_);
+     466          21 :   nlist_pace_reset_=false;
+     467          21 :   parseFlag("NLIST_PACE_RESET",nlist_pace_reset_);
+     468          21 :   if(nlist_pace_reset_)
+     469           2 :     nlist_=true;
+     470             :   std::vector<double> nlist_param;
+     471          42 :   parseVector("NLIST_PARAMETERS",nlist_param);
+     472          21 :   if(nlist_param.size()==0)
+     473             :   {
+     474          17 :     nlist_param_[0]=3.0;//*cutoff2_ -> max distance of neighbors
+     475          17 :     nlist_param_[1]=0.5;//*nlist_dev2_[i] -> condition for rebuilding
+     476             :   }
+     477             :   else
+     478             :   {
+     479           4 :     nlist_=true;
+     480           4 :     plumed_massert(nlist_param.size()==2,"two cutoff parameters are needed for the neighbor list");
+     481           4 :     plumed_massert(nlist_param[0]>1.0,"the first of NLIST_PARAMETERS must be greater than 1. The smaller the first, the smaller should be the second as well");
+     482           4 :     const double min_PARAM_1=(1.-1./std::sqrt(nlist_param[0]))+0.16;
+     483           4 :     plumed_massert(nlist_param[1]>0,"the second of NLIST_PARAMETERS must be greater than 0");
+     484           4 :     plumed_massert(nlist_param[1]<=min_PARAM_1,"the second of NLIST_PARAMETERS must be smaller to avoid systematic errors. Largest suggested value is: 1.16-1/sqrt(PARAM_0) = "+std::to_string(min_PARAM_1));
+     485           4 :     nlist_param_[0]=nlist_param[0];
+     486           4 :     nlist_param_[1]=nlist_param[1];
+     487             :   }
+     488          21 :   nlist_center_.resize(ncv_);
+     489          21 :   nlist_dev2_.resize(ncv_,0.);
+     490          21 :   nlist_steps_=0;
+     491          21 :   nlist_update_=true;
+     492             : 
+     493             : //optional stuff
+     494          21 :   no_Zed_=false;
+     495          21 :   parseFlag("NO_ZED",no_Zed_);
+     496          21 :   if(no_Zed_)
+     497             :   { //this makes it more gentle in the initial phase
+     498           6 :     sum_weights_=1;
+     499           6 :     sum_weights2_=1;
+     500             :   }
+     501          21 :   fixed_sigma_=false;
+     502          21 :   parseFlag("FIXED_SIGMA",fixed_sigma_);
+     503          21 :   bool recursive_merge_off=false;
+     504          21 :   parseFlag("RECURSIVE_MERGE_OFF",recursive_merge_off);
+     505          21 :   recursive_merge_=!recursive_merge_off;
+     506          42 :   parseFlag("CALC_WORK",calc_work_);
+     507             : 
+     508             : //options involving extra arguments
+     509             :   std::vector<Value*> args;
+     510          42 :   parseArgumentList("EXCLUDED_REGION",args);
+     511          21 :   if(args.size()>0)
+     512             :   {
+     513           2 :     plumed_massert(args.size()==1,"only one characteristic function should define the region to be excluded");
+     514           2 :     requestExtraDependencies(args);
+     515           2 :     excluded_region_=args[0];
+     516             :   }
+     517             :   if(!mode::explore)
+     518             :   {
+     519          28 :     parseArgumentList("EXTRA_BIAS",extra_biases_);
+     520          14 :     if(extra_biases_.size()>0)
+     521           2 :       requestExtraDependencies(extra_biases_);
+     522             :   }
+     523             : 
+     524             : //kernels file
+     525             :   std::string kernelsFileName;
+     526          42 :   parse("FILE",kernelsFileName);
+     527             :   std::string fmt;
+     528          42 :   parse("FMT",fmt);
+     529             : 
+     530             : //output checkpoint of current state
+     531             :   std::string restartFileName;
+     532          42 :   parse("STATE_RFILE",restartFileName);
+     533             :   std::string stateFileName;
+     534          21 :   parse("STATE_WFILE",stateFileName);
+     535          21 :   wStateStride_=0;
+     536          21 :   parse("STATE_WSTRIDE",wStateStride_);
+     537          21 :   storeOldStates_=false;
+     538          21 :   parseFlag("STORE_STATES",storeOldStates_);
+     539          21 :   if(wStateStride_!=0 || storeOldStates_)
+     540          10 :     plumed_massert(stateFileName.length()>0,"filename for storing simulation status not specified, use STATE_WFILE");
+     541          21 :   if(wStateStride_>0)
+     542          10 :     plumed_massert(wStateStride_>=(int)stride_,"STATE_WSTRIDE is in units of MD steps, thus it is suggested to use a multiple of PACE");
+     543          21 :   if(stateFileName.length()>0 && wStateStride_==0)
+     544           1 :     wStateStride_=-1;//will print only on CPT events (checkpoints set by some MD engines, like gromacs)
+     545             : 
+     546             : //multiple walkers //TODO implement also external mw for cp2k
+     547          21 :   bool walkers_mpi=false;
+     548          21 :   parseFlag("WALKERS_MPI",walkers_mpi);
+     549          21 :   if(walkers_mpi)
+     550             :   {
+     551             :     //If this Action is not compiled with MPI the user is informed and we exit gracefully
+     552          10 :     plumed_massert(Communicator::plumedHasMPI(),"Invalid walkers configuration: WALKERS_MPI flag requires MPI compilation");
+     553          10 :     plumed_massert(Communicator::initialized(),"Invalid walkers configuration: WALKERS_MPI needs the communicator correctly initialized.");
+     554             : 
+     555          10 :     if(comm.Get_rank()==0)//multi_sim_comm works on first rank only
+     556             :     {
+     557          10 :       NumWalkers_=multi_sim_comm.Get_size();
+     558          10 :       walker_rank_=multi_sim_comm.Get_rank();
+     559             :     }
+     560          10 :     comm.Bcast(NumWalkers_,0); //if each walker has more than one processor update them all
+     561          10 :     comm.Bcast(walker_rank_,0);
+     562             :   }
+     563             :   else
+     564             :   {
+     565          11 :     NumWalkers_=1;
+     566          11 :     walker_rank_=0;
+     567             :   }
+     568             : 
+     569             : //parallelization stuff
+     570          21 :   NumOMP_=OpenMP::getNumThreads();
+     571          21 :   NumParallel_=comm.Get_size();
+     572          21 :   rank_=comm.Get_rank();
+     573          21 :   bool serial=false;
+     574          21 :   parseFlag("SERIAL",serial);
+     575          21 :   if(serial)
+     576             :   {
+     577           4 :     NumOMP_=1;
+     578           4 :     NumParallel_=1;
+     579           4 :     rank_=0;
+     580             :   }
+     581             : 
+     582          21 :   checkRead();
+     583             : 
+     584             : //restart if needed
+     585             :   bool convertKernelsToState=false;
+     586          21 :   if(getRestart())
+     587             :   {
+     588             :     bool stateRestart=true;
+     589          11 :     if(restartFileName.length()==0)
+     590             :     {
+     591             :       stateRestart=false;
+     592             :       restartFileName=kernelsFileName;
+     593             :     }
+     594          11 :     IFile ifile;
+     595          11 :     ifile.link(*this);
+     596          11 :     if(ifile.FileExist(restartFileName))
+     597             :     {
+     598          11 :       bool tmp_nlist=nlist_;
+     599          11 :       nlist_=false; // NLIST is not needed while restarting
+     600          11 :       ifile.open(restartFileName);
+     601          11 :       log.printf("  RESTART - make sure all used options are compatible\n");
+     602          11 :       log.printf("    restarting from: %s\n",restartFileName.c_str());
+     603          11 :       std::string action_name=getName();
+     604          11 :       if(stateRestart)
+     605             :       {
+     606           6 :         log.printf("    it should be a STATE file (not a KERNELS file)\n");
+     607             :         action_name+="_state";
+     608             :       }
+     609             :       else
+     610             :       {
+     611           5 :         log.printf(" +++ WARNING +++ RESTART from KERNELS might be approximate, use STATE_WFILE and STATE_RFILE to restart from the exact state\n");
+     612             :         action_name+="_kernels";
+     613             :       }
+     614             :       std::string old_action_name;
+     615          11 :       ifile.scanField("action",old_action_name);
+     616          11 :       plumed_massert(action_name==old_action_name,"RESTART - mismatch between old and new action name. Expected '"+action_name+"', but found '"+old_action_name+"'");
+     617             :       std::string old_biasfactor_str;
+     618          22 :       ifile.scanField("biasfactor",old_biasfactor_str);
+     619          21 :       if(old_biasfactor_str=="inf" || old_biasfactor_str=="INF")
+     620             :       {
+     621           1 :         if(!std::isinf(biasfactor_))
+     622           0 :           log.printf(" +++ WARNING +++ previous bias factor was inf while now it is %g\n",biasfactor_);
+     623             :       }
+     624             :       else
+     625             :       {
+     626             :         double old_biasfactor;
+     627          10 :         ifile.scanField("biasfactor",old_biasfactor);
+     628          10 :         if(std::abs(biasfactor_-old_biasfactor)>1e-6*biasfactor_)
+     629           0 :           log.printf(" +++ WARNING +++ previous bias factor was %g while now it is %g. diff = %g\n",old_biasfactor,biasfactor_,biasfactor_-old_biasfactor);
+     630             :       }
+     631             :       double old_epsilon;
+     632          11 :       ifile.scanField("epsilon",old_epsilon);
+     633          11 :       if(std::abs(epsilon_-old_epsilon)>1e-6*epsilon_)
+     634           8 :         log.printf(" +++ WARNING +++ previous epsilon was %g while now it is %g. diff = %g\n",old_epsilon,epsilon_,epsilon_-old_epsilon);
+     635             :       double old_cutoff;
+     636          11 :       ifile.scanField("kernel_cutoff",old_cutoff);
+     637          11 :       if(std::abs(cutoff-old_cutoff)>1e-6*cutoff)
+     638           0 :         log.printf(" +++ WARNING +++ previous kernel_cutoff was %g while now it is %g. diff = %g\n",old_cutoff,cutoff,cutoff-old_cutoff);
+     639             :       double old_threshold;
+     640          11 :       const double threshold=sqrt(threshold2_);
+     641          11 :       ifile.scanField("compression_threshold",old_threshold);
+     642          11 :       if(std::abs(threshold-old_threshold)>1e-6*threshold)
+     643           0 :         log.printf(" +++ WARNING +++ previous compression_threshold was %g while now it is %g. diff = %g\n",old_threshold,threshold,threshold-old_threshold);
+     644          11 :       if(stateRestart)
+     645             :       {
+     646           6 :         ifile.scanField("zed",Zed_);
+     647           6 :         ifile.scanField("sum_weights",sum_weights_);
+     648           6 :         ifile.scanField("sum_weights2",sum_weights2_);
+     649           6 :         ifile.scanField("counter",counter_);
+     650           6 :         if(adaptive_sigma_)
+     651             :         {
+     652           6 :           ifile.scanField("adaptive_counter",adaptive_counter_);
+     653           6 :           if(NumWalkers_==1)
+     654             :           {
+     655           6 :             for(unsigned i=0; i<ncv_; i++)
+     656             :             {
+     657           8 :               ifile.scanField("sigma0_"+getPntrToArgument(i)->getName(),sigma0_[i]);
+     658           8 :               ifile.scanField("av_cv_"+getPntrToArgument(i)->getName(),av_cv_[i]);
+     659           8 :               ifile.scanField("av_M2_"+getPntrToArgument(i)->getName(),av_M2_[i]);
+     660             :             }
+     661             :           }
+     662             :           else
+     663             :           {
+     664          12 :             for(unsigned w=0; w<NumWalkers_; w++)
+     665          24 :               for(unsigned i=0; i<ncv_; i++)
+     666             :               {
+     667             :                 double tmp0,tmp1,tmp2;
+     668          32 :                 const std::string arg_iw=getPntrToArgument(i)->getName()+"_"+std::to_string(w);
+     669          16 :                 ifile.scanField("sigma0_"+arg_iw,tmp0);
+     670          16 :                 ifile.scanField("av_cv_"+arg_iw,tmp1);
+     671          16 :                 ifile.scanField("av_M2_"+arg_iw,tmp2);
+     672          16 :                 if(w==walker_rank_)
+     673             :                 {
+     674           8 :                   sigma0_[i]=tmp0;
+     675           8 :                   av_cv_[i]=tmp1;
+     676           8 :                   av_M2_[i]=tmp2;
+     677             :                 }
+     678             :               }
+     679             :           }
+     680             :         }
+     681             :       }
+     682          33 :       for(unsigned i=0; i<ncv_; i++)
+     683             :       {
+     684          22 :         if(getPntrToArgument(i)->isPeriodic())
+     685             :         {
+     686             :           std::string arg_min,arg_max;
+     687          22 :           getPntrToArgument(i)->getDomain(arg_min,arg_max);
+     688             :           std::string file_min,file_max;
+     689          44 :           ifile.scanField("min_"+getPntrToArgument(i)->getName(),file_min);
+     690          22 :           ifile.scanField("max_"+getPntrToArgument(i)->getName(),file_max);
+     691          22 :           plumed_massert(file_min==arg_min,"RESTART - mismatch between old and new ARG periodicity");
+     692          22 :           plumed_massert(file_max==arg_max,"RESTART - mismatch between old and new ARG periodicity");
+     693             :         }
+     694             :       }
+     695          11 :       if(stateRestart)
+     696             :       {
+     697             :         double time;
+     698          60 :         while(ifile.scanField("time",time))
+     699             :         {
+     700          24 :           std::vector<double> center(ncv_);
+     701          24 :           std::vector<double> sigma(ncv_);
+     702             :           double height;
+     703          72 :           for(unsigned i=0; i<ncv_; i++)
+     704          48 :             ifile.scanField(getPntrToArgument(i)->getName(),center[i]);
+     705          72 :           for(unsigned i=0; i<ncv_; i++)
+     706          96 :             ifile.scanField("sigma_"+getPntrToArgument(i)->getName(),sigma[i]);
+     707          24 :           ifile.scanField("height",height);
+     708          24 :           ifile.scanField();
+     709          24 :           kernels_.emplace_back(height,center,sigma);
+     710             :         }
+     711           6 :         log.printf("    a total of %lu kernels where read\n",kernels_.size());
+     712             :       }
+     713             :       else
+     714             :       {
+     715           5 :         ifile.allowIgnoredFields(); //this allows for multiple restart, but without checking for consistency between them!
+     716             :         double time;
+     717         270 :         while(ifile.scanField("time",time))
+     718             :         {
+     719         130 :           std::vector<double> center(ncv_);
+     720         130 :           std::vector<double> sigma(ncv_);
+     721             :           double height;
+     722             :           double logweight;
+     723         390 :           for(unsigned i=0; i<ncv_; i++)
+     724         260 :             ifile.scanField(getPntrToArgument(i)->getName(),center[i]);
+     725         390 :           for(unsigned i=0; i<ncv_; i++)
+     726         520 :             ifile.scanField("sigma_"+getPntrToArgument(i)->getName(),sigma[i]);
+     727         130 :           if(counter_==(1+walker_rank_) && adaptive_sigma_)
+     728           0 :             sigma0_=sigma;
+     729         130 :           ifile.scanField("height",height);
+     730         130 :           ifile.scanField("logweight",logweight);
+     731         130 :           ifile.scanField();
+     732         130 :           addKernel(height,center,sigma);
+     733         130 :           const double weight=std::exp(logweight);
+     734         130 :           sum_weights_+=weight; //this sum is slightly inaccurate, because when printing some precision is lost
+     735         130 :           sum_weights2_+=weight*weight;
+     736         130 :           counter_++;
+     737             :         }
+     738           5 :         KDEnorm_=mode::explore?counter_:sum_weights_;
+     739           5 :         if(!no_Zed_)
+     740             :         {
+     741           2 :           double sum_uprob=0;
+     742          48 :           for(unsigned k=rank_; k<kernels_.size(); k+=NumParallel_)
+     743        1104 :             for(unsigned kk=0; kk<kernels_.size(); kk++)
+     744        1058 :               sum_uprob+=evaluateKernel(kernels_[kk],kernels_[k].center);
+     745           2 :           if(NumParallel_>1)
+     746           0 :             comm.Sum(sum_uprob);
+     747           2 :           Zed_=sum_uprob/KDEnorm_/kernels_.size();
+     748             :         }
+     749           5 :         log.printf("    a total of %llu kernels where read, and compressed to %lu\n",counter_-1,kernels_.size());
+     750             :         convertKernelsToState=true;
+     751             :       }
+     752          11 :       ifile.reset(false);
+     753          11 :       ifile.close();
+     754          11 :       nlist_=tmp_nlist;
+     755             :     }
+     756             :     else //same behaviour as METAD
+     757           0 :       plumed_merror("RESTART requested, but file '"+restartFileName+"' was not found!\n  Set RESTART=NO or provide a restart file");
+     758          11 :     if(NumWalkers_>1) //make sure that all walkers are doing the same thing
+     759             :     {
+     760           6 :       const unsigned kernels_size=kernels_.size();
+     761           6 :       std::vector<unsigned> all_kernels_size(NumWalkers_);
+     762           6 :       if(comm.Get_rank()==0)
+     763           6 :         multi_sim_comm.Allgather(kernels_size,all_kernels_size);
+     764           6 :       comm.Bcast(all_kernels_size,0);
+     765             :       bool same_number_of_kernels=true;
+     766          12 :       for(unsigned w=1; w<NumWalkers_; w++)
+     767           6 :         if(all_kernels_size[0]!=all_kernels_size[w])
+     768             :           same_number_of_kernels=false;
+     769           6 :       plumed_massert(same_number_of_kernels,"RESTART - not all walkers are reading the same file!");
+     770             :     }
+     771          11 :   }
+     772          10 :   else if(restartFileName.length()>0)
+     773           4 :     log.printf(" +++ WARNING +++ the provided STATE_RFILE will be ignored, since RESTART was not requested\n");
+     774             : 
+     775             : //sync all walkers to avoid opening files before reading is over (see also METAD)
+     776          21 :   comm.Barrier();
+     777          21 :   if(comm.Get_rank()==0 && walkers_mpi)
+     778          10 :     multi_sim_comm.Barrier();
+     779             : 
+     780             : //setup output kernels file
+     781          21 :   kernelsOfile_.link(*this);
+     782          21 :   if(NumWalkers_>1)
+     783             :   {
+     784          10 :     if(walker_rank_>0)
+     785             :       kernelsFileName="/dev/null"; //only first walker writes on file
+     786          20 :     kernelsOfile_.enforceSuffix("");
+     787             :   }
+     788          21 :   kernelsOfile_.open(kernelsFileName);
+     789          21 :   if(fmt.length()>0)
+     790          42 :     kernelsOfile_.fmtField(" "+fmt);
+     791             :   kernelsOfile_.setHeavyFlush(); //do I need it?
+     792             :   //define and set const fields
+     793          21 :   kernelsOfile_.addConstantField("action");
+     794          21 :   kernelsOfile_.addConstantField("biasfactor");
+     795          21 :   kernelsOfile_.addConstantField("epsilon");
+     796          21 :   kernelsOfile_.addConstantField("kernel_cutoff");
+     797          21 :   kernelsOfile_.addConstantField("compression_threshold");
+     798          61 :   for(unsigned i=0; i<ncv_; i++)
+     799          40 :     kernelsOfile_.setupPrintValue(getPntrToArgument(i));
+     800          42 :   kernelsOfile_.printField("action",getName()+"_kernels");
+     801          21 :   kernelsOfile_.printField("biasfactor",biasfactor_);
+     802          21 :   kernelsOfile_.printField("epsilon",epsilon_);
+     803          21 :   kernelsOfile_.printField("kernel_cutoff",sqrt(cutoff2_));
+     804          21 :   kernelsOfile_.printField("compression_threshold",sqrt(threshold2_));
+     805             : 
+     806             : //open file for storing state
+     807          21 :   if(wStateStride_!=0)
+     808             :   {
+     809          11 :     stateOfile_.link(*this);
+     810          11 :     if(NumWalkers_>1)
+     811             :     {
+     812           8 :       if(walker_rank_>0)
+     813             :         stateFileName="/dev/null"; //only first walker writes on file
+     814          16 :       stateOfile_.enforceSuffix("");
+     815             :     }
+     816          11 :     stateOfile_.open(stateFileName);
+     817          11 :     if(fmt.length()>0)
+     818          22 :       stateOfile_.fmtField(" "+fmt);
+     819          11 :     if(convertKernelsToState)
+     820           0 :       dumpStateToFile();
+     821             :   }
+     822             : 
+     823             : //set initial old values
+     824          21 :   KDEnorm_=mode::explore?counter_:sum_weights_;
+     825          21 :   old_KDEnorm_=KDEnorm_;
+     826             : 
+     827             : //add and set output components
+     828          42 :   addComponent("rct");
+     829          21 :   componentIsNotPeriodic("rct");
+     830          42 :   getPntrToComponent("rct")->set(kbt_*std::log(sum_weights_/counter_));
+     831          42 :   addComponent("zed");
+     832          21 :   componentIsNotPeriodic("zed");
+     833          42 :   getPntrToComponent("zed")->set(Zed_);
+     834          42 :   addComponent("neff");
+     835          21 :   componentIsNotPeriodic("neff");
+     836          42 :   getPntrToComponent("neff")->set(std::pow(1+sum_weights_,2)/(1+sum_weights2_));
+     837          42 :   addComponent("nker");
+     838          21 :   componentIsNotPeriodic("nker");
+     839          21 :   getPntrToComponent("nker")->set(kernels_.size());
+     840          21 :   if(calc_work_)
+     841             :   {
+     842          14 :     addComponent("work");
+     843          14 :     componentIsNotPeriodic("work");
+     844             :   }
+     845          21 :   if(nlist_)
+     846             :   {
+     847          10 :     addComponent("nlker");
+     848          10 :     componentIsNotPeriodic("nlker");
+     849          10 :     addComponent("nlsteps");
+     850          10 :     componentIsNotPeriodic("nlsteps");
+     851             :   }
+     852             : 
+     853             : //printing some info
+     854          21 :   log.printf("  temperature = %g\n",kbt_/kB);
+     855          21 :   log.printf("  beta = %g\n",1./kbt_);
+     856          21 :   log.printf("  depositing new kernels with PACE = %u\n",stride_);
+     857          21 :   log.printf("  expected BARRIER is %g\n",barrier);
+     858          21 :   log.printf("  using target distribution with BIASFACTOR gamma = %g\n",biasfactor_);
+     859          21 :   if(std::isinf(biasfactor_))
+     860           4 :     log.printf("    (thus a uniform flat target distribution, no well-tempering)\n");
+     861          21 :   if(excluded_region_!=NULL)
+     862           2 :     log.printf(" -- EXCLUDED_REGION: kernels will be deposited only when '%s' is equal to zero\n",excluded_region_->getName().c_str());
+     863          21 :   if(extra_biases_.size()>0)
+     864             :   {
+     865           2 :     log.printf(" -- EXTRA_BIAS: ");
+     866           5 :     for(unsigned e=0; e<extra_biases_.size(); e++)
+     867           3 :       log.printf("%s ",extra_biases_[e]->getName().c_str());
+     868           2 :     log.printf("will be reweighted\n");
+     869             :   }
+     870          21 :   if(adaptive_sigma_)
+     871             :   {
+     872          11 :     log.printf("  adaptive SIGMA will be used, with ADAPTIVE_SIGMA_STRIDE = %u\n",adaptive_sigma_stride_);
+     873          11 :     unsigned x=std::ceil(adaptive_sigma_stride_/stride_);
+     874          11 :     log.printf("    thus the first x kernel depositions will be skipped, x = ADAPTIVE_SIGMA_STRIDE/PACE = %u\n",x);
+     875             :   }
+     876             :   else
+     877             :   {
+     878          10 :     log.printf("  kernels have initial SIGMA = ");
+     879          29 :     for(unsigned i=0; i<ncv_; i++)
+     880          19 :       log.printf(" %g",sigma0_[i]);
+     881          10 :     log.printf("\n");
+     882             :   }
+     883          21 :   if(sigma_min_.size()>0)
+     884             :   {
+     885           3 :     log.printf("  kernels have a SIGMA_MIN = ");
+     886           9 :     for(unsigned i=0; i<ncv_; i++)
+     887           6 :       log.printf(" %g",sigma_min_[i]);
+     888           3 :     log.printf("\n");
+     889             :   }
+     890          21 :   if(fixed_sigma_)
+     891           6 :     log.printf(" -- FIXED_SIGMA: sigma will not decrease as the simulation proceeds\n");
+     892          21 :   log.printf("  kernels are truncated with KERNELS_CUTOFF = %g\n",cutoff);
+     893          21 :   if(cutoff<3.5)
+     894           0 :     log.printf(" +++ WARNING +++ probably kernels are truncated too much\n");
+     895          21 :   log.printf("  the value at cutoff is = %g\n",val_at_cutoff_);
+     896          21 :   log.printf("  regularization EPSILON = %g\n",epsilon_);
+     897          21 :   if(val_at_cutoff_>epsilon_*(1+1e-6))
+     898           0 :     log.printf(" +++ WARNING +++ the KERNEL_CUTOFF might be too small for the given EPSILON\n");
+     899          21 :   log.printf("  kernels will be compressed when closer than COMPRESSION_THRESHOLD = %g\n",sqrt(threshold2_));
+     900          21 :   if(threshold2_==0)
+     901           0 :     log.printf(" +++ WARNING +++ kernels will never merge, expect slowdowns\n");
+     902          21 :   if(!recursive_merge_)
+     903           6 :     log.printf(" -- RECURSIVE_MERGE_OFF: only one merge for each new kernel will be attempted. This is faster only if total number of kernels does not grow too much\n");
+     904          21 :   if(nlist_)
+     905           5 :     log.printf(" -- NLIST: using neighbor list for kernels, with parameters: %g,%g\n",nlist_param_[0],nlist_param_[1]);
+     906          21 :   if(nlist_pace_reset_)
+     907           2 :     log.printf(" -- NLIST_PACE_RESET: forcing the neighbor list to update every PACE\n");
+     908          21 :   if(no_Zed_)
+     909           6 :     log.printf(" -- NO_ZED: using fixed normalization factor = %g\n",Zed_);
+     910          21 :   if(wStateStride_>0)
+     911          10 :     log.printf("  state checkpoints are written on file %s every %d MD steps\n",stateFileName.c_str(),wStateStride_);
+     912          21 :   if(wStateStride_==-1)
+     913           1 :     log.printf("  state checkpoints are written on file %s only on CPT events (or never if MD code does define them!)\n",stateFileName.c_str());
+     914          21 :   if(walkers_mpi)
+     915          10 :     log.printf(" -- WALKERS_MPI: if multiple replicas are present, they will share the same bias via MPI\n");
+     916          21 :   if(NumWalkers_>1)
+     917             :   {
+     918          10 :     log.printf("  using multiple walkers\n");
+     919          10 :     log.printf("    number of walkers: %u\n",NumWalkers_);
+     920          10 :     log.printf("    walker rank: %u\n",walker_rank_);
+     921             :   }
+     922          21 :   int mw_warning=0;
+     923          21 :   if(!walkers_mpi && comm.Get_rank()==0 && multi_sim_comm.Get_size()>(int)NumWalkers_)
+     924           0 :     mw_warning=1;
+     925          21 :   comm.Bcast(mw_warning,0);
+     926          21 :   if(mw_warning) //log.printf messes up with comm, so never use it without Bcast!
+     927           0 :     log.printf(" +++ WARNING +++ multiple replicas will NOT communicate unless the flag WALKERS_MPI is used\n");
+     928          21 :   if(NumParallel_>1)
+     929           4 :     log.printf("  using multiple MPI processes per simulation: %u\n",NumParallel_);
+     930          21 :   if(NumOMP_>1)
+     931          17 :     log.printf("  using multiple OpenMP threads per simulation: %u\n",NumOMP_);
+     932          21 :   if(serial)
+     933           4 :     log.printf(" -- SERIAL: no loop parallelization, despite %d MPI processes and %u OpenMP threads available\n",comm.Get_size(),OpenMP::getNumThreads());
+     934          21 :   log.printf("  Bibliography: ");
+     935          42 :   log<<plumed.cite("M. Invernizzi and M. Parrinello, J. Phys. Chem. Lett. 11, 2731-2736 (2020)");
+     936          14 :   if(mode::explore || adaptive_sigma_)
+     937          28 :     log<<plumed.cite("M. Invernizzi and M. Parrinello, J. Chem. Theory Comput. 18, 3988-3996 (2022)");
+     938          21 :   log.printf("\n");
+     939          42 : }
+     940             : 
+     941             : template <class mode>
+     942        1071 : void OPESmetad<mode>::calculate()
+     943             : {
+     944             : //get cv
+     945        1071 :   std::vector<double> cv(ncv_);
+     946        3111 :   for(unsigned i=0; i<ncv_; i++)
+     947        2040 :     cv[i]=getArgument(i);
+     948             : 
+     949             : //check neighbor list
+     950        1071 :   if(nlist_)
+     951             :   {
+     952         255 :     nlist_steps_++;
+     953         255 :     if(getExchangeStep())
+     954           0 :       nlist_update_=true;
+     955             :     else
+     956             :     {
+     957         275 :       for(unsigned i=0; i<ncv_; i++)
+     958             :       {
+     959         270 :         const double diff_i=difference(i,cv[i],nlist_center_[i]);
+     960         270 :         if(diff_i*diff_i>nlist_param_[1]*nlist_dev2_[i])
+     961             :         {
+     962         250 :           nlist_update_=true;
+     963         250 :           break;
+     964             :         }
+     965             :       }
+     966             :     }
+     967         255 :     if(nlist_update_)
+     968         250 :       updateNlist(cv);
+     969             :   }
+     970             : 
+     971             : //set bias and forces
+     972        1071 :   std::vector<double> der_prob(ncv_,0);
+     973        1071 :   const double prob=getProbAndDerivatives(cv,der_prob);
+     974        1071 :   const double bias=kbt_*bias_prefactor_*std::log(prob/Zed_+epsilon_);
+     975        1071 :   setBias(bias);
+     976        3111 :   for(unsigned i=0; i<ncv_; i++)
+     977        2040 :     setOutputForce(i,-kbt_*bias_prefactor_/(prob/Zed_+epsilon_)*der_prob[i]/Zed_);
+     978        1071 : }
+     979             : 
+     980             : template <class mode>
+     981        1071 : void OPESmetad<mode>::update()
+     982             : {
+     983        1071 :   if(isFirstStep_)//same in MetaD, useful for restarts?
+     984             :   {
+     985          21 :     isFirstStep_=false;
+     986          21 :     return;
+     987             :   }
+     988             : 
+     989             : //update variance if adaptive sigma
+     990        1050 :   if(adaptive_sigma_)
+     991             :   {
+     992         550 :     adaptive_counter_++;
+     993         550 :     unsigned tau=adaptive_sigma_stride_;
+     994         550 :     if(adaptive_counter_<adaptive_sigma_stride_)
+     995          45 :       tau=adaptive_counter_;
+     996        1600 :     for(unsigned i=0; i<ncv_; i++)
+     997             :     { //Welford's online algorithm for standard deviation
+     998        1050 :       const double cv_i=getArgument(i);
+     999        1050 :       const double diff_i=difference(i,av_cv_[i],cv_i);
+    1000        1050 :       av_cv_[i]+=diff_i/tau; //exponentially decaying average
+    1001        1050 :       av_M2_[i]+=diff_i*difference(i,av_cv_[i],cv_i);
+    1002             :     }
+    1003         550 :     if(adaptive_counter_<adaptive_sigma_stride_ && counter_==1) //counter_>1 if restarting
+    1004             :       return; //do not apply bias before having measured sigma
+    1005             :   }
+    1006             : 
+    1007             : //do update
+    1008        1005 :   if(getStep()%stride_==0 && (excluded_region_==NULL || excluded_region_->get()==0))
+    1009             :   {
+    1010         257 :     old_KDEnorm_=KDEnorm_;
+    1011         257 :     delta_kernels_.clear();
+    1012         257 :     unsigned old_nker=kernels_.size();
+    1013             : 
+    1014             :     //get new kernel height
+    1015         257 :     double log_weight=getOutputQuantity(0)/kbt_; //first value is always the current bias
+    1016         277 :     for(unsigned e=0; e<extra_biases_.size(); e++)
+    1017          20 :       log_weight+=extra_biases_[e]->get()/kbt_; //extra biases contribute to the weight
+    1018         257 :     double height=std::exp(log_weight);
+    1019             : 
+    1020             :     //update sum_weights_ and neff
+    1021         257 :     double sum_heights=height;
+    1022         257 :     double sum_heights2=height*height;
+    1023         257 :     if(NumWalkers_>1)
+    1024             :     {
+    1025         126 :       if(comm.Get_rank()==0)
+    1026             :       {
+    1027         126 :         multi_sim_comm.Sum(sum_heights);
+    1028         126 :         multi_sim_comm.Sum(sum_heights2);
+    1029             :       }
+    1030         126 :       comm.Bcast(sum_heights,0);
+    1031         126 :       comm.Bcast(sum_heights2,0);
+    1032             :     }
+    1033         257 :     counter_+=NumWalkers_;
+    1034         257 :     sum_weights_+=sum_heights;
+    1035         257 :     sum_weights2_+=sum_heights2;
+    1036         257 :     const double neff=std::pow(1+sum_weights_,2)/(1+sum_weights2_); //adding 1 makes it more robust at the start
+    1037         257 :     getPntrToComponent("rct")->set(kbt_*std::log(sum_weights_/counter_));
+    1038         257 :     getPntrToComponent("neff")->set(neff);
+    1039             :     if(mode::explore)
+    1040             :     {
+    1041          68 :       KDEnorm_=counter_;
+    1042          68 :       height=1; //plain KDE, bias reweight does not enter here
+    1043             :     }
+    1044             :     else
+    1045         189 :       KDEnorm_=sum_weights_;
+    1046             : 
+    1047             :     //if needed, rescale sigma and height
+    1048         257 :     std::vector<double> sigma=sigma0_;
+    1049         257 :     if(adaptive_sigma_)
+    1050             :     {
+    1051          93 :       const double factor=mode::explore?1:biasfactor_;
+    1052         131 :       if(counter_==1+NumWalkers_) //first time only
+    1053             :       {
+    1054          14 :         for(unsigned i=0; i<ncv_; i++)
+    1055           9 :           av_M2_[i]*=biasfactor_; //from unbiased, thus must be adjusted
+    1056          14 :         for(unsigned i=0; i<ncv_; i++)
+    1057           9 :           sigma0_[i]=std::sqrt(av_M2_[i]/adaptive_counter_/factor);
+    1058           5 :         if(sigma_min_.size()==0)
+    1059             :         {
+    1060          14 :           for(unsigned i=0; i<ncv_; i++)
+    1061           9 :             plumed_massert(sigma0_[i]>1e-6,"ADAPTIVE SIGMA is suspiciously small for CV i="+std::to_string(i)+"\nManually provide SIGMA or set a safe SIGMA_MIN to avoid possible issues");
+    1062             :         }
+    1063             :         else
+    1064             :         {
+    1065           0 :           for(unsigned i=0; i<ncv_; i++)
+    1066           0 :             sigma0_[i]=std::max(sigma0_[i],sigma_min_[i]);
+    1067             :         }
+    1068             :       }
+    1069         388 :       for(unsigned i=0; i<ncv_; i++)
+    1070         257 :         sigma[i]=std::sqrt(av_M2_[i]/adaptive_counter_/factor);
+    1071         131 :       if(sigma_min_.size()==0)
+    1072             :       {
+    1073         238 :         for(unsigned i=0; i<ncv_; i++)
+    1074             :         {
+    1075         157 :           if(sigma[i]<1e-6)
+    1076             :           {
+    1077           0 :             log.printf("+++ WARNING +++ the ADAPTIVE SIGMA is suspiciously small, you should set a safe SIGMA_MIN. 1e-6 will be used here\n");
+    1078           0 :             sigma[i]=1e-6;
+    1079           0 :             sigma_min_.resize(ncv_,1e-6);
+    1080             :           }
+    1081             :         }
+    1082             :       }
+    1083             :       else
+    1084             :       {
+    1085         150 :         for(unsigned i=0; i<ncv_; i++)
+    1086         100 :           sigma[i]=std::max(sigma[i],sigma_min_[i]);
+    1087             :       }
+    1088             :     }
+    1089         257 :     if(!fixed_sigma_)
+    1090             :     {
+    1091          38 :       const double size=mode::explore?counter_:neff; //for EXPLORE neff is not relevant
+    1092         197 :       const double s_rescaling=std::pow(size*(ncv_+2.)/4.,-1./(4+ncv_));
+    1093         576 :       for(unsigned i=0; i<ncv_; i++)
+    1094         379 :         sigma[i]*=s_rescaling;
+    1095         197 :       if(sigma_min_.size()>0)
+    1096             :       {
+    1097         150 :         for(unsigned i=0; i<ncv_; i++)
+    1098         100 :           sigma[i]=std::max(sigma[i],sigma_min_[i]);
+    1099             :       }
+    1100             :     }
+    1101             :     //the height should be divided by sqrt(2*pi)*sigma0_,
+    1102             :     //but this overall factor would be canceled when dividing by Zed
+    1103             :     //thus we skip it altogether, but keep any other sigma rescaling
+    1104         756 :     for(unsigned i=0; i<ncv_; i++)
+    1105         499 :       height*=(sigma0_[i]/sigma[i]);
+    1106             : 
+    1107             :     //get new kernel center
+    1108         257 :     std::vector<double> center(ncv_);
+    1109         756 :     for(unsigned i=0; i<ncv_; i++)
+    1110         499 :       center[i]=getArgument(i);
+    1111             : 
+    1112             :     //add new kernel(s)
+    1113         257 :     if(NumWalkers_==1)
+    1114         131 :       addKernel(height,center,sigma,log_weight);
+    1115             :     else
+    1116             :     {
+    1117         126 :       std::vector<double> all_height(NumWalkers_,0.0);
+    1118         126 :       std::vector<double> all_center(NumWalkers_*ncv_,0.0);
+    1119         126 :       std::vector<double> all_sigma(NumWalkers_*ncv_,0.0);
+    1120         126 :       std::vector<double> all_logweight(NumWalkers_,0.0);
+    1121         126 :       if(comm.Get_rank()==0)
+    1122             :       {
+    1123         126 :         multi_sim_comm.Allgather(height,all_height);
+    1124         126 :         multi_sim_comm.Allgather(center,all_center);
+    1125         126 :         multi_sim_comm.Allgather(sigma,all_sigma);
+    1126         126 :         multi_sim_comm.Allgather(log_weight,all_logweight);
+    1127             :       }
+    1128         126 :       comm.Bcast(all_height,0);
+    1129         126 :       comm.Bcast(all_center,0);
+    1130         126 :       comm.Bcast(all_sigma,0);
+    1131         126 :       comm.Bcast(all_logweight,0);
+    1132         126 :       if(nlist_)
+    1133             :       { //gather all the nlist_index_, so merging can be done using it
+    1134          50 :         std::vector<int> all_nlist_size(NumWalkers_);
+    1135          50 :         if(comm.Get_rank()==0)
+    1136             :         {
+    1137          50 :           all_nlist_size[walker_rank_]=nlist_index_.size();
+    1138          50 :           multi_sim_comm.Sum(all_nlist_size);
+    1139             :         }
+    1140          50 :         comm.Bcast(all_nlist_size,0);
+    1141             :         unsigned tot_size=0;
+    1142         150 :         for(unsigned w=0; w<NumWalkers_; w++)
+    1143         100 :           tot_size+=all_nlist_size[w];
+    1144          50 :         if(tot_size>0)
+    1145             :         {
+    1146          50 :           std::vector<int> disp(NumWalkers_);
+    1147         100 :           for(unsigned w=0; w<NumWalkers_-1; w++)
+    1148          50 :             disp[w+1]=disp[w]+all_nlist_size[w];
+    1149          50 :           std::vector<unsigned> all_nlist_index(tot_size);
+    1150          50 :           if(comm.Get_rank()==0)
+    1151          50 :             multi_sim_comm.Allgatherv(nlist_index_,all_nlist_index,&all_nlist_size[0],&disp[0]);
+    1152          50 :           comm.Bcast(all_nlist_index,0);
+    1153          50 :           std::set<unsigned> nlist_index_set(all_nlist_index.begin(),all_nlist_index.end()); //remove duplicates and sort
+    1154          50 :           nlist_index_.assign(nlist_index_set.begin(),nlist_index_set.end());
+    1155             :         }
+    1156             :       }
+    1157         378 :       for(unsigned w=0; w<NumWalkers_; w++)
+    1158             :       {
+    1159         252 :         std::vector<double> center_w(all_center.begin()+ncv_*w,all_center.begin()+ncv_*(w+1));
+    1160         252 :         std::vector<double> sigma_w(all_sigma.begin()+ncv_*w,all_sigma.begin()+ncv_*(w+1));
+    1161         252 :         addKernel(all_height[w],center_w,sigma_w,all_logweight[w]);
+    1162             :       }
+    1163             :     }
+    1164         257 :     getPntrToComponent("nker")->set(kernels_.size());
+    1165         257 :     if(nlist_)
+    1166             :     {
+    1167         106 :       getPntrToComponent("nlker")->set(nlist_index_.size());
+    1168         106 :       if(nlist_pace_reset_)
+    1169          50 :         nlist_update_=true;
+    1170             :     }
+    1171             : 
+    1172             :     //update Zed_
+    1173         257 :     if(!no_Zed_)
+    1174             :     {
+    1175         197 :       double sum_uprob=0;
+    1176         197 :       const unsigned ks=kernels_.size();
+    1177         197 :       const unsigned ds=delta_kernels_.size();
+    1178         197 :       const bool few_kernels=(ks*ks<(3*ks*ds+2*ds*ds*NumParallel_+100)); //this seems reasonable, but is not rigorous...
+    1179         197 :       if(few_kernels) //really needed? Probably is almost always false
+    1180             :       {
+    1181         147 :         #pragma omp parallel num_threads(NumOMP_)
+    1182             :         {
+    1183             :           #pragma omp for reduction(+:sum_uprob) nowait
+    1184             :           for(unsigned k=rank_; k<kernels_.size(); k+=NumParallel_)
+    1185             :             for(unsigned kk=0; kk<kernels_.size(); kk++)
+    1186             :               sum_uprob+=evaluateKernel(kernels_[kk],kernels_[k].center);
+    1187             :         }
+    1188         147 :         if(NumParallel_>1)
+    1189          50 :           comm.Sum(sum_uprob);
+    1190             :       }
+    1191             :       else
+    1192             :       {
+    1193             :         // Here instead of redoing the full summation, we add only the changes, knowing that
+    1194             :         // uprob = old_uprob + delta_uprob
+    1195             :         // and we also need to consider that in the new sum there are some novel centers and some disappeared ones
+    1196          50 :         double delta_sum_uprob=0;
+    1197          50 :         if(!nlist_)
+    1198             :         {
+    1199           0 :           #pragma omp parallel num_threads(NumOMP_)
+    1200             :           {
+    1201             :             #pragma omp for reduction(+:delta_sum_uprob) nowait
+    1202             :             for(unsigned k=rank_; k<kernels_.size(); k+=NumParallel_)
+    1203             :             {
+    1204             :               for(unsigned d=0; d<delta_kernels_.size(); d++)
+    1205             :               {
+    1206             :                 const double sign=delta_kernels_[d].height<0?-1:1; //take away contribution from kernels that are gone, and add the one from new ones
+    1207             :                 delta_sum_uprob+=evaluateKernel(delta_kernels_[d],kernels_[k].center)+sign*evaluateKernel(kernels_[k],delta_kernels_[d].center);
+    1208             :               }
+    1209             :             }
+    1210             :           }
+    1211             :         }
+    1212             :         else
+    1213             :         {
+    1214          50 :           #pragma omp parallel num_threads(NumOMP_)
+    1215             :           {
+    1216             :             #pragma omp for reduction(+:delta_sum_uprob) nowait
+    1217             :             for(unsigned nk=rank_; nk<nlist_index_.size(); nk+=NumParallel_)
+    1218             :             {
+    1219             :               const unsigned k=nlist_index_[nk];
+    1220             :               for(unsigned d=0; d<delta_kernels_.size(); d++)
+    1221             :               {
+    1222             :                 const double sign=delta_kernels_[d].height<0?-1:1; //take away contribution from kernels that are gone, and add the one from new ones
+    1223             :                 delta_sum_uprob+=evaluateKernel(delta_kernels_[d],kernels_[k].center)+sign*evaluateKernel(kernels_[k],delta_kernels_[d].center);
+    1224             :               }
+    1225             :             }
+    1226             :           }
+    1227             :         }
+    1228          50 :         if(NumParallel_>1)
+    1229           0 :           comm.Sum(delta_sum_uprob);
+    1230          50 :         #pragma omp parallel num_threads(NumOMP_)
+    1231             :         {
+    1232             :           #pragma omp for reduction(+:delta_sum_uprob)
+    1233             :           for(unsigned d=0; d<delta_kernels_.size(); d++)
+    1234             :           {
+    1235             :             for(unsigned dd=0; dd<delta_kernels_.size(); dd++)
+    1236             :             { //now subtract the delta_uprob added before, but not needed
+    1237             :               const double sign=delta_kernels_[d].height<0?-1:1;
+    1238             :               delta_sum_uprob-=sign*evaluateKernel(delta_kernels_[dd],delta_kernels_[d].center);
+    1239             :             }
+    1240             :           }
+    1241             :         }
+    1242          50 :         sum_uprob=Zed_*old_KDEnorm_*old_nker+delta_sum_uprob;
+    1243             :       }
+    1244         197 :       Zed_=sum_uprob/KDEnorm_/kernels_.size();
+    1245         394 :       getPntrToComponent("zed")->set(Zed_);
+    1246             :     }
+    1247             : 
+    1248             :     //calculate work if requested
+    1249         257 :     if(calc_work_)
+    1250             :     {
+    1251          70 :       std::vector<double> dummy(ncv_); //derivatives are not actually needed
+    1252          70 :       const double prob=getProbAndDerivatives(center,dummy);
+    1253          70 :       const double new_bias=kbt_*bias_prefactor_*std::log(prob/Zed_+epsilon_);
+    1254          70 :       work_+=new_bias-getOutputQuantity(0);
+    1255         140 :       getPntrToComponent("work")->set(work_);
+    1256             :     }
+    1257             :   }
+    1258             : 
+    1259             : //dump state if requested
+    1260        1005 :   if( (wStateStride_>0 && getStep()%wStateStride_==0) || (wStateStride_==-1 && getCPT()) )
+    1261          18 :     dumpStateToFile();
+    1262             : }
+    1263             : 
+    1264             : template <class mode>
+    1265        1141 : double OPESmetad<mode>::getProbAndDerivatives(const std::vector<double>& cv,std::vector<double>& der_prob)
+    1266             : {
+    1267        1141 :   double prob=0.0;
+    1268        1141 :   if(!nlist_)
+    1269             :   {
+    1270         886 :     if(NumOMP_==1 || (unsigned)kernels_.size()<2*NumOMP_*NumParallel_)
+    1271             :     {
+    1272             :       // for performances and thread safety
+    1273         707 :       std::vector<double> dist(ncv_);
+    1274        2647 :       for(unsigned k=rank_; k<kernels_.size(); k+=NumParallel_)
+    1275        1940 :         prob+=evaluateKernel(kernels_[k],cv,der_prob,dist);
+    1276             :     }
+    1277             :     else
+    1278             :     {
+    1279         179 :       #pragma omp parallel num_threads(NumOMP_)
+    1280             :       {
+    1281             :         std::vector<double> omp_deriv(der_prob.size(),0.);
+    1282             :         // for performances and thread safety
+    1283             :         std::vector<double> dist(ncv_);
+    1284             :         #pragma omp for reduction(+:prob) nowait
+    1285             :         for(unsigned k=rank_; k<kernels_.size(); k+=NumParallel_)
+    1286             :           prob+=evaluateKernel(kernels_[k],cv,omp_deriv,dist);
+    1287             :         #pragma omp critical
+    1288             :         for(unsigned i=0; i<ncv_; i++)
+    1289             :           der_prob[i]+=omp_deriv[i];
+    1290             :       }
+    1291             :     }
+    1292             :   }
+    1293             :   else
+    1294             :   {
+    1295         255 :     if(NumOMP_==1 || (unsigned)nlist_index_.size()<2*NumOMP_*NumParallel_)
+    1296             :     {
+    1297             :       // for performances and thread safety
+    1298         230 :       std::vector<double> dist(ncv_);
+    1299         660 :       for(unsigned nk=rank_; nk<nlist_index_.size(); nk+=NumParallel_)
+    1300         430 :         prob+=evaluateKernel(kernels_[nlist_index_[nk]],cv,der_prob,dist);
+    1301             :     }
+    1302             :     else
+    1303             :     {
+    1304          25 :       #pragma omp parallel num_threads(NumOMP_)
+    1305             :       {
+    1306             :         std::vector<double> omp_deriv(der_prob.size(),0.);
+    1307             :         // for performances and thread safety
+    1308             :         std::vector<double> dist(ncv_);
+    1309             :         #pragma omp for reduction(+:prob) nowait
+    1310             :         for(unsigned nk=rank_; nk<nlist_index_.size(); nk+=NumParallel_)
+    1311             :           prob+=evaluateKernel(kernels_[nlist_index_[nk]],cv,omp_deriv,dist);
+    1312             :         #pragma omp critical
+    1313             :         for(unsigned i=0; i<ncv_; i++)
+    1314             :           der_prob[i]+=omp_deriv[i];
+    1315             :       }
+    1316             :     }
+    1317             :   }
+    1318        1141 :   if(NumParallel_>1)
+    1319             :   {
+    1320         224 :     comm.Sum(prob);
+    1321         224 :     comm.Sum(der_prob);
+    1322             :   }
+    1323             : //normalize the estimate
+    1324        1141 :   prob/=KDEnorm_;
+    1325        3311 :   for(unsigned i=0; i<ncv_; i++)
+    1326        2170 :     der_prob[i]/=KDEnorm_;
+    1327             : 
+    1328        1141 :   return prob;
+    1329             : }
+    1330             : 
+    1331             : template <class mode>
+    1332         513 : void OPESmetad<mode>::addKernel(const double height,const std::vector<double>& center,const std::vector<double>& sigma)
+    1333             : {
+    1334             :   bool no_match=true;
+    1335         513 :   if(threshold2_!=0)
+    1336             :   {
+    1337         513 :     unsigned taker_k=getMergeableKernel(center,kernels_.size());
+    1338         513 :     if(taker_k<kernels_.size())
+    1339             :     {
+    1340             :       no_match=false;
+    1341         388 :       delta_kernels_.emplace_back(-1*kernels_[taker_k].height,kernels_[taker_k].center,kernels_[taker_k].sigma);
+    1342         776 :       mergeKernels(kernels_[taker_k],kernel(height,center,sigma));
+    1343         388 :       delta_kernels_.push_back(kernels_[taker_k]);
+    1344         388 :       if(recursive_merge_) //the overhead is worth it if it keeps low the total number of kernels
+    1345             :       {
+    1346             :         unsigned giver_k=taker_k;
+    1347         337 :         taker_k=getMergeableKernel(kernels_[giver_k].center,giver_k);
+    1348         337 :         while(taker_k<kernels_.size())
+    1349             :         {
+    1350           0 :           delta_kernels_.pop_back();
+    1351           0 :           delta_kernels_.emplace_back(-1*kernels_[taker_k].height,kernels_[taker_k].center,kernels_[taker_k].sigma);
+    1352           0 :           if(taker_k>giver_k) //saves time when erasing
+    1353             :             std::swap(taker_k,giver_k);
+    1354           0 :           mergeKernels(kernels_[taker_k],kernels_[giver_k]);
+    1355           0 :           delta_kernels_.push_back(kernels_[taker_k]);
+    1356           0 :           kernels_.erase(kernels_.begin()+giver_k);
+    1357           0 :           if(nlist_)
+    1358             :           {
+    1359             :             unsigned giver_nk=0;
+    1360             :             bool found_giver=false;
+    1361           0 :             for(unsigned nk=0; nk<nlist_index_.size(); nk++)
+    1362             :             {
+    1363           0 :               if(found_giver)
+    1364           0 :                 nlist_index_[nk]--; //all the indexes shift due to erase
+    1365           0 :               if(nlist_index_[nk]==giver_k)
+    1366             :               {
+    1367             :                 giver_nk=nk;
+    1368             :                 found_giver=true;
+    1369             :               }
+    1370             :             }
+    1371             :             plumed_dbg_massert(found_giver,"problem with merging and NLIST");
+    1372           0 :             nlist_index_.erase(nlist_index_.begin()+giver_nk);
+    1373             :           }
+    1374             :           giver_k=taker_k;
+    1375           0 :           taker_k=getMergeableKernel(kernels_[giver_k].center,giver_k);
+    1376             :         }
+    1377             :       }
+    1378             :     }
+    1379             :   }
+    1380             :   if(no_match)
+    1381             :   {
+    1382         125 :     kernels_.emplace_back(height,center,sigma);
+    1383         125 :     delta_kernels_.emplace_back(height,center,sigma);
+    1384         125 :     if(nlist_)
+    1385          12 :       nlist_index_.push_back(kernels_.size()-1);
+    1386             :   }
+    1387         513 : }
+    1388             : 
+    1389             : template <class mode>
+    1390         383 : void OPESmetad<mode>::addKernel(const double height,const std::vector<double>& center,const std::vector<double>& sigma,const double logweight)
+    1391             : {
+    1392         383 :   addKernel(height,center,sigma);
+    1393             : //write to file
+    1394         383 :   kernelsOfile_.printField("time",getTime());
+    1395        1134 :   for(unsigned i=0; i<ncv_; i++)
+    1396         751 :     kernelsOfile_.printField(getPntrToArgument(i),center[i]);
+    1397        1134 :   for(unsigned i=0; i<ncv_; i++)
+    1398        1502 :     kernelsOfile_.printField("sigma_"+getPntrToArgument(i)->getName(),sigma[i]);
+    1399         383 :   kernelsOfile_.printField("height",height);
+    1400         383 :   kernelsOfile_.printField("logweight",logweight);
+    1401         383 :   kernelsOfile_.printField();
+    1402         383 : }
+    1403             : 
+    1404             : template <class mode>
+    1405         850 : unsigned OPESmetad<mode>::getMergeableKernel(const std::vector<double>& giver_center,const unsigned giver_k)
+    1406             : { //returns kernels_.size() if no match is found
+    1407         850 :   unsigned min_k=kernels_.size();
+    1408         850 :   double min_norm2=threshold2_;
+    1409         850 :   if(!nlist_)
+    1410             :   {
+    1411         550 :     #pragma omp parallel num_threads(NumOMP_)
+    1412             :     {
+    1413             :       unsigned min_k_omp = min_k;
+    1414             :       double min_norm2_omp = threshold2_;
+    1415             :       #pragma omp for nowait
+    1416             :       for(unsigned k=rank_; k<kernels_.size(); k+=NumParallel_)
+    1417             :       {
+    1418             :         if(k==giver_k) //a kernel should not be merged with itself
+    1419             :           continue;
+    1420             :         double norm2=0;
+    1421             :         for(unsigned i=0; i<ncv_; i++)
+    1422             :         {
+    1423             :           const double dist_i=difference(i,giver_center[i],kernels_[k].center[i])/kernels_[k].sigma[i];
+    1424             :           norm2+=dist_i*dist_i;
+    1425             :           if(norm2>=min_norm2_omp)
+    1426             :             break;
+    1427             :         }
+    1428             :         if(norm2<min_norm2_omp)
+    1429             :         {
+    1430             :           min_norm2_omp=norm2;
+    1431             :           min_k_omp=k;
+    1432             :         }
+    1433             :       }
+    1434             :       #pragma omp critical
+    1435             :       {
+    1436             :         if(min_norm2_omp < min_norm2)
+    1437             :         {
+    1438             :           min_norm2 = min_norm2_omp;
+    1439             :           min_k = min_k_omp;
+    1440             :         }
+    1441             :       }
+    1442             :     }
+    1443             :   }
+    1444             :   else
+    1445             :   {
+    1446         300 :     #pragma omp parallel num_threads(NumOMP_)
+    1447             :     {
+    1448             :       unsigned min_k_omp = min_k;
+    1449             :       double min_norm2_omp = threshold2_;
+    1450             :       #pragma omp for nowait
+    1451             :       for(unsigned nk=rank_; nk<nlist_index_.size(); nk+=NumParallel_)
+    1452             :       {
+    1453             :         const unsigned k=nlist_index_[nk];
+    1454             :         if(k==giver_k) //a kernel should not be merged with itself
+    1455             :           continue;
+    1456             :         double norm2=0;
+    1457             :         for(unsigned i=0; i<ncv_; i++)
+    1458             :         {
+    1459             :           const double dist_i=difference(i,giver_center[i],kernels_[k].center[i])/kernels_[k].sigma[i];
+    1460             :           norm2+=dist_i*dist_i;
+    1461             :           if(norm2>=min_norm2)
+    1462             :             break;
+    1463             :         }
+    1464             :         if(norm2<min_norm2_omp)
+    1465             :         {
+    1466             :           min_norm2_omp=norm2;
+    1467             :           min_k_omp=k;
+    1468             :         }
+    1469             :       }
+    1470             :       #pragma omp critical
+    1471             :       {
+    1472             :         if(min_norm2_omp < min_norm2)
+    1473             :         {
+    1474             :           min_norm2 = min_norm2_omp;
+    1475             :           min_k = min_k_omp;
+    1476             :         }
+    1477             :       }
+    1478             :     }
+    1479             :   }
+    1480         850 :   if(NumParallel_>1)
+    1481             :   {
+    1482         134 :     std::vector<double> all_min_norm2(NumParallel_);
+    1483         134 :     std::vector<unsigned> all_min_k(NumParallel_);
+    1484         134 :     comm.Allgather(min_norm2,all_min_norm2);
+    1485         134 :     comm.Allgather(min_k,all_min_k);
+    1486             :     const unsigned best=std::distance(std::begin(all_min_norm2),std::min_element(std::begin(all_min_norm2),std::end(all_min_norm2)));
+    1487         134 :     min_k=all_min_k[best];
+    1488             :   }
+    1489         850 :   return min_k;
+    1490             : }
+    1491             : 
+    1492             : template <class mode>
+    1493         250 : void OPESmetad<mode>::updateNlist(const std::vector<double>& new_center)
+    1494             : {
+    1495         250 :   if(kernels_.size()==0) //no need to check for neighbors
+    1496           6 :     return;
+    1497             : 
+    1498         244 :   nlist_center_=new_center;
+    1499         244 :   nlist_index_.clear();
+    1500             :   //first we gather all the nlist_index
+    1501         244 :   if(NumOMP_==1 || (unsigned)kernels_.size()<2*NumOMP_*NumParallel_)
+    1502             :   {
+    1503         198 :     for(unsigned k=rank_; k<kernels_.size(); k+=NumParallel_)
+    1504             :     {
+    1505             :       double norm2_k=0;
+    1506         444 :       for(unsigned i=0; i<ncv_; i++)
+    1507             :       {
+    1508         296 :         const double dist_ik=difference(i,nlist_center_[i],kernels_[k].center[i])/kernels_[k].sigma[i];
+    1509         296 :         norm2_k+=dist_ik*dist_ik;
+    1510             :       }
+    1511         148 :       if(norm2_k<=nlist_param_[0]*cutoff2_)
+    1512         104 :         nlist_index_.push_back(k);
+    1513             :     }
+    1514             :   }
+    1515             :   else
+    1516             :   {
+    1517         194 :     #pragma omp parallel num_threads(NumOMP_)
+    1518             :     {
+    1519             :       std::vector<unsigned> private_nlist_index;
+    1520             :       #pragma omp for nowait
+    1521             :       for(unsigned k=rank_; k<kernels_.size(); k+=NumParallel_)
+    1522             :       {
+    1523             :         double norm2_k=0;
+    1524             :         for(unsigned i=0; i<ncv_; i++)
+    1525             :         {
+    1526             :           const double dist_ik=difference(i,nlist_center_[i],kernels_[k].center[i])/kernels_[k].sigma[i];
+    1527             :           norm2_k+=dist_ik*dist_ik;
+    1528             :         }
+    1529             :         if(norm2_k<=nlist_param_[0]*cutoff2_)
+    1530             :           private_nlist_index.push_back(k);
+    1531             :       }
+    1532             :       #pragma omp critical
+    1533             :       nlist_index_.insert(nlist_index_.end(),private_nlist_index.begin(),private_nlist_index.end());
+    1534             :     }
+    1535         194 :     if(recursive_merge_)
+    1536         194 :       std::sort(nlist_index_.begin(),nlist_index_.end());
+    1537             :   }
+    1538         244 :   if(NumParallel_>1)
+    1539             :   {
+    1540         100 :     std::vector<int> all_nlist_size(NumParallel_);
+    1541         100 :     all_nlist_size[rank_]=nlist_index_.size();
+    1542         100 :     comm.Sum(all_nlist_size);
+    1543             :     unsigned tot_size=0;
+    1544         300 :     for(unsigned r=0; r<NumParallel_; r++)
+    1545         200 :       tot_size+=all_nlist_size[r];
+    1546         100 :     if(tot_size>0)
+    1547             :     {
+    1548         100 :       std::vector<int> disp(NumParallel_);
+    1549         200 :       for(unsigned r=0; r<NumParallel_-1; r++)
+    1550         100 :         disp[r+1]=disp[r]+all_nlist_size[r];
+    1551         100 :       std::vector<unsigned> local_nlist_index=nlist_index_;
+    1552         100 :       nlist_index_.resize(tot_size);
+    1553         100 :       comm.Allgatherv(local_nlist_index,nlist_index_,&all_nlist_size[0],&disp[0]);
+    1554         100 :       if(recursive_merge_)
+    1555         100 :         std::sort(nlist_index_.begin(),nlist_index_.end());
+    1556             :     }
+    1557             :   }
+    1558             :   //calculate the square deviation
+    1559         244 :   std::vector<double> dev2(ncv_,0.);
+    1560         773 :   for(unsigned k=rank_; k<nlist_index_.size(); k+=NumParallel_)
+    1561             :   {
+    1562        1587 :     for(unsigned i=0; i<ncv_; i++)
+    1563             :     {
+    1564        1058 :       const double diff_ik=difference(i,nlist_center_[i],kernels_[nlist_index_[k]].center[i]);
+    1565        1058 :       dev2[i]+=diff_ik*diff_ik;
+    1566             :     }
+    1567             :   }
+    1568         244 :   if(NumParallel_>1)
+    1569         100 :     comm.Sum(dev2);
+    1570         732 :   for(unsigned i=0; i<ncv_; i++)
+    1571             :   {
+    1572         488 :     if(dev2[i]==0) //e.g. if nlist_index_.size()==0
+    1573          56 :       nlist_dev2_[i]=std::pow(kernels_.back().sigma[i],2);
+    1574             :     else
+    1575         432 :       nlist_dev2_[i]=dev2[i]/nlist_index_.size();
+    1576             :   }
+    1577         244 :   getPntrToComponent("nlker")->set(nlist_index_.size());
+    1578         244 :   getPntrToComponent("nlsteps")->set(nlist_steps_);
+    1579         244 :   nlist_steps_=0;
+    1580         244 :   nlist_update_=false;
+    1581             : }
+    1582             : 
+    1583             : template <class mode>
+    1584          18 : void OPESmetad<mode>::dumpStateToFile()
+    1585             : {
+    1586             : //gather adaptive sigma info if needed
+    1587             : //doing this while writing to file can lead to misterious slowdowns
+    1588             :   std::vector<double> all_sigma0;
+    1589             :   std::vector<double> all_av_cv;
+    1590             :   std::vector<double> all_av_M2;
+    1591          18 :   if(adaptive_sigma_ && NumWalkers_>1)
+    1592             :   {
+    1593          16 :     all_sigma0.resize(NumWalkers_*ncv_);
+    1594          16 :     all_av_cv.resize(NumWalkers_*ncv_);
+    1595          16 :     all_av_M2.resize(NumWalkers_*ncv_);
+    1596          16 :     if(comm.Get_rank()==0)
+    1597             :     {
+    1598          16 :       multi_sim_comm.Allgather(sigma0_,all_sigma0);
+    1599          16 :       multi_sim_comm.Allgather(av_cv_,all_av_cv);
+    1600          16 :       multi_sim_comm.Allgather(av_M2_,all_av_M2);
+    1601             :     }
+    1602          16 :     comm.Bcast(all_sigma0,0);
+    1603          16 :     comm.Bcast(all_av_cv,0);
+    1604          16 :     comm.Bcast(all_av_M2,0);
+    1605             :   }
+    1606             : 
+    1607             : //rewrite header or rewind file
+    1608          18 :   if(storeOldStates_)
+    1609          16 :     stateOfile_.clearFields();
+    1610           2 :   else if(walker_rank_==0)
+    1611           2 :     stateOfile_.rewind();
+    1612             : //define fields
+    1613          18 :   stateOfile_.addConstantField("action");
+    1614          18 :   stateOfile_.addConstantField("biasfactor");
+    1615          18 :   stateOfile_.addConstantField("epsilon");
+    1616          18 :   stateOfile_.addConstantField("kernel_cutoff");
+    1617          18 :   stateOfile_.addConstantField("compression_threshold");
+    1618          18 :   stateOfile_.addConstantField("zed");
+    1619          18 :   stateOfile_.addConstantField("sum_weights");
+    1620          18 :   stateOfile_.addConstantField("sum_weights2");
+    1621          18 :   stateOfile_.addConstantField("counter");
+    1622          18 :   if(adaptive_sigma_)
+    1623             :   {
+    1624          18 :     stateOfile_.addConstantField("adaptive_counter");
+    1625          18 :     if(NumWalkers_==1)
+    1626             :     {
+    1627           6 :       for(unsigned i=0; i<ncv_; i++)
+    1628             :       {
+    1629           8 :         stateOfile_.addConstantField("sigma0_"+getPntrToArgument(i)->getName());
+    1630           8 :         stateOfile_.addConstantField("av_cv_"+getPntrToArgument(i)->getName());
+    1631           8 :         stateOfile_.addConstantField("av_M2_"+getPntrToArgument(i)->getName());
+    1632             :       }
+    1633             :     }
+    1634             :     else
+    1635             :     {
+    1636          48 :       for(unsigned w=0; w<NumWalkers_; w++)
+    1637          96 :         for(unsigned i=0; i<ncv_; i++)
+    1638             :         {
+    1639         128 :           const std::string arg_iw=getPntrToArgument(i)->getName()+"_"+std::to_string(w);
+    1640          64 :           stateOfile_.addConstantField("sigma0_"+arg_iw);
+    1641          64 :           stateOfile_.addConstantField("av_cv_"+arg_iw);
+    1642         128 :           stateOfile_.addConstantField("av_M2_"+arg_iw);
+    1643             :         }
+    1644             :     }
+    1645             :   }
+    1646             : //print fields
+    1647          54 :   for(unsigned i=0; i<ncv_; i++) //periodicity of CVs
+    1648          36 :     stateOfile_.setupPrintValue(getPntrToArgument(i));
+    1649          36 :   stateOfile_.printField("action",getName()+"_state");
+    1650          18 :   stateOfile_.printField("biasfactor",biasfactor_);
+    1651          18 :   stateOfile_.printField("epsilon",epsilon_);
+    1652          18 :   stateOfile_.printField("kernel_cutoff",sqrt(cutoff2_));
+    1653          18 :   stateOfile_.printField("compression_threshold",sqrt(threshold2_));
+    1654          18 :   stateOfile_.printField("zed",Zed_);
+    1655          18 :   stateOfile_.printField("sum_weights",sum_weights_);
+    1656          18 :   stateOfile_.printField("sum_weights2",sum_weights2_);
+    1657          18 :   stateOfile_.printField("counter",counter_);
+    1658          18 :   if(adaptive_sigma_)
+    1659             :   {
+    1660          18 :     stateOfile_.printField("adaptive_counter",adaptive_counter_);
+    1661          18 :     if(NumWalkers_==1)
+    1662             :     {
+    1663           6 :       for(unsigned i=0; i<ncv_; i++)
+    1664             :       {
+    1665           8 :         stateOfile_.printField("sigma0_"+getPntrToArgument(i)->getName(),sigma0_[i]);
+    1666           8 :         stateOfile_.printField("av_cv_"+getPntrToArgument(i)->getName(),av_cv_[i]);
+    1667           8 :         stateOfile_.printField("av_M2_"+getPntrToArgument(i)->getName(),av_M2_[i]);
+    1668             :       }
+    1669             :     }
+    1670             :     else
+    1671             :     {
+    1672          48 :       for(unsigned w=0; w<NumWalkers_; w++)
+    1673          96 :         for(unsigned i=0; i<ncv_; i++)
+    1674             :         {
+    1675         128 :           const std::string arg_iw=getPntrToArgument(i)->getName()+"_"+std::to_string(w);
+    1676          64 :           stateOfile_.printField("sigma0_"+arg_iw,all_sigma0[w*ncv_+i]);
+    1677          64 :           stateOfile_.printField("av_cv_"+arg_iw,all_av_cv[w*ncv_+i]);
+    1678         128 :           stateOfile_.printField("av_M2_"+arg_iw,all_av_M2[w*ncv_+i]);
+    1679             :         }
+    1680             :     }
+    1681             :   }
+    1682             : //print kernels
+    1683          82 :   for(unsigned k=0; k<kernels_.size(); k++)
+    1684             :   {
+    1685          64 :     stateOfile_.printField("time",getTime()); //this is not very usefull
+    1686         192 :     for(unsigned i=0; i<ncv_; i++)
+    1687         128 :       stateOfile_.printField(getPntrToArgument(i),kernels_[k].center[i]);
+    1688         192 :     for(unsigned i=0; i<ncv_; i++)
+    1689         256 :       stateOfile_.printField("sigma_"+getPntrToArgument(i)->getName(),kernels_[k].sigma[i]);
+    1690          64 :     stateOfile_.printField("height",kernels_[k].height);
+    1691          64 :     stateOfile_.printField();
+    1692             :   }
+    1693             : //make sure file is written even if small
+    1694          18 :   if(!storeOldStates_)
+    1695           2 :     stateOfile_.flush();
+    1696          18 : }
+    1697             : 
+    1698             : template <class mode>
+    1699        5969 : inline double OPESmetad<mode>::evaluateKernel(const kernel& G,const std::vector<double>& x) const
+    1700             : { //NB: cannot be a method of kernel class, because uses external variables (for cutoff)
+    1701             :   double norm2=0;
+    1702       13923 :   for(unsigned i=0; i<ncv_; i++)
+    1703             :   {
+    1704       10288 :     const double dist_i=difference(i,G.center[i],x[i])/G.sigma[i];
+    1705       10288 :     norm2+=dist_i*dist_i;
+    1706       10288 :     if(norm2>=cutoff2_)
+    1707             :       return 0;
+    1708             :   }
+    1709        3635 :   return G.height*(std::exp(-0.5*norm2)-val_at_cutoff_);
+    1710             : }
+    1711             : 
+    1712             : template <class mode>
+    1713        3364 : inline double OPESmetad<mode>::evaluateKernel(const kernel& G,const std::vector<double>& x, std::vector<double>& acc_der, std::vector<double>& dist)
+    1714             : { //NB: cannot be a method of kernel class, because uses external variables (for cutoff)
+    1715             :   double norm2=0;
+    1716        7483 :   for(unsigned i=0; i<ncv_; i++)
+    1717             :   {
+    1718        5578 :     dist[i]=difference(i,G.center[i],x[i])/G.sigma[i];
+    1719        5578 :     norm2+=dist[i]*dist[i];
+    1720        5578 :     if(norm2>=cutoff2_)
+    1721             :       return 0;
+    1722             :   }
+    1723        1905 :   const double val=G.height*(std::exp(-0.5*norm2)-val_at_cutoff_);
+    1724        5576 :   for(unsigned i=0; i<ncv_; i++)
+    1725        3671 :     acc_der[i]-=dist[i]/G.sigma[i]*val; //NB: we accumulate the derivative into der
+    1726             :   return val;
+    1727             : }
+    1728             : 
+    1729             : template <class mode>
+    1730         388 : inline void OPESmetad<mode>::mergeKernels(kernel& k1,const kernel& k2)
+    1731             : {
+    1732         388 :   const double h=k1.height+k2.height;
+    1733        1159 :   for(unsigned i=0; i<k1.center.size(); i++)
+    1734             :   {
+    1735         771 :     const bool isPeriodic_i=getPntrToArgument(i)->isPeriodic();
+    1736         771 :     if(isPeriodic_i)
+    1737         771 :       k1.center[i]=k2.center[i]+difference(i,k2.center[i],k1.center[i]); //fix PBC
+    1738         771 :     const double c_i=(k1.height*k1.center[i]+k2.height*k2.center[i])/h;
+    1739         771 :     const double ss_k1_part=k1.height*(k1.sigma[i]*k1.sigma[i]+k1.center[i]*k1.center[i]);
+    1740         771 :     const double ss_k2_part=k2.height*(k2.sigma[i]*k2.sigma[i]+k2.center[i]*k2.center[i]);
+    1741         771 :     const double ss_i=(ss_k1_part+ss_k2_part)/h-c_i*c_i;
+    1742         771 :     if(isPeriodic_i)
+    1743         771 :       k1.center[i]=bringBackInPbc(i,c_i);
+    1744             :     else
+    1745           0 :       k1.center[i]=c_i;
+    1746         771 :     k1.sigma[i]=sqrt(ss_i);
+    1747             :   }
+    1748         388 :   k1.height=h;
+    1749         388 : }
+    1750             : 
+    1751             : }
+    1752             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/index-sort-f.html b/coverage/opes/index-sort-f.html new file mode 100644 index 000000000000..1e023994b247 --- /dev/null +++ b/coverage/opes/index-sort-f.html @@ -0,0 +1,184 @@ + + + + + + + + LCOV - plumed test coverage - opes + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - opesHitTotalCoverage
Test:plumed test coverageLines:2143222996.1 %
Date:2024-04-19 12:12:35Functions:10811792.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
ECVumbrellasLine.cpp +
98.5%98.5%
+
98.5 %129 / 13190.0 %9 / 10
ECVumbrellasFile.cpp +
98.3%98.3%
+
98.3 %118 / 12090.0 %9 / 10
ECVmultiThermal.cpp +
95.5%95.5%
+
95.5 %107 / 11290.0 %9 / 10
ExpansionCVs.cpp +
92.3%92.3%
+
92.3 %96 / 10490.0 %9 / 10
ECVlinear.cpp +
95.8%95.8%
+
95.8 %114 / 11990.0 %9 / 10
ECVcustom.cpp +
92.0%92.0%
+
92.0 %92 / 10090.9 %10 / 11
ECVmultiThermalBaric.cpp +
96.7%96.7%
+
96.7 %263 / 27291.7 %11 / 12
OPESexpanded.cpp +
97.3%97.3%
+
97.3 %431 / 44392.3 %12 / 13
OPESmetad.cpp +
95.8%95.8%
+
95.8 %789 / 82496.4 %27 / 28
ExpansionCVs.h +
100.0%
+
100.0 %4 / 4100.0 %3 / 3
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/index-sort-l.html b/coverage/opes/index-sort-l.html new file mode 100644 index 000000000000..effaeb190b93 --- /dev/null +++ b/coverage/opes/index-sort-l.html @@ -0,0 +1,184 @@ + + + + + + + + LCOV - plumed test coverage - opes + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - opesHitTotalCoverage
Test:plumed test coverageLines:2143222996.1 %
Date:2024-04-19 12:12:35Functions:10811792.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
ECVcustom.cpp +
92.0%92.0%
+
92.0 %92 / 10090.9 %10 / 11
ExpansionCVs.cpp +
92.3%92.3%
+
92.3 %96 / 10490.0 %9 / 10
ECVmultiThermal.cpp +
95.5%95.5%
+
95.5 %107 / 11290.0 %9 / 10
ECVlinear.cpp +
95.8%95.8%
+
95.8 %114 / 11990.0 %9 / 10
OPESmetad.cpp +
95.8%95.8%
+
95.8 %789 / 82496.4 %27 / 28
ECVmultiThermalBaric.cpp +
96.7%96.7%
+
96.7 %263 / 27291.7 %11 / 12
OPESexpanded.cpp +
97.3%97.3%
+
97.3 %431 / 44392.3 %12 / 13
ECVumbrellasFile.cpp +
98.3%98.3%
+
98.3 %118 / 12090.0 %9 / 10
ECVumbrellasLine.cpp +
98.5%98.5%
+
98.5 %129 / 13190.0 %9 / 10
ExpansionCVs.h +
100.0%
+
100.0 %4 / 4100.0 %3 / 3
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/index.html b/coverage/opes/index.html new file mode 100644 index 000000000000..bb669bf6e21c --- /dev/null +++ b/coverage/opes/index.html @@ -0,0 +1,184 @@ + + + + + + + + LCOV - plumed test coverage - opes + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - opesHitTotalCoverage
Test:plumed test coverageLines:2143222996.1 %
Date:2024-04-19 12:12:35Functions:10811792.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
ECVcustom.cpp +
92.0%92.0%
+
92.0 %92 / 10090.9 %10 / 11
ECVlinear.cpp +
95.8%95.8%
+
95.8 %114 / 11990.0 %9 / 10
ECVmultiThermal.cpp +
95.5%95.5%
+
95.5 %107 / 11290.0 %9 / 10
ECVmultiThermalBaric.cpp +
96.7%96.7%
+
96.7 %263 / 27291.7 %11 / 12
ECVumbrellasFile.cpp +
98.3%98.3%
+
98.3 %118 / 12090.0 %9 / 10
ECVumbrellasLine.cpp +
98.5%98.5%
+
98.5 %129 / 13190.0 %9 / 10
ExpansionCVs.cpp +
92.3%92.3%
+
92.3 %96 / 10490.0 %9 / 10
ExpansionCVs.h +
100.0%
+
100.0 %4 / 4100.0 %3 / 3
OPESexpanded.cpp +
97.3%97.3%
+
97.3 %431 / 44392.3 %12 / 13
OPESmetad.cpp +
95.8%95.8%
+
95.8 %789 / 82496.4 %27 / 28
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/pamm/HBPammMatrix.cpp.func-sort-c.html b/coverage/pamm/HBPammMatrix.cpp.func-sort-c.html new file mode 100644 index 000000000000..21427978e918 --- /dev/null +++ b/coverage/pamm/HBPammMatrix.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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:10611393.8 %
Date:2024-04-19 12:12:35Functions:5771.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4pamm12HBPammMatrixC2ERKNS_13ActionOptionsE0
_ZN4PLMD4pamm14HBPammShortcutC2ERKNS_13ActionOptionsE0
_ZN4PLMD4pamm12HBPammMatrixC1ERKNS_13ActionOptionsE6
_ZN4PLMD4pamm14HBPammShortcutC1ERKNS_13ActionOptionsE6
_ZN4PLMD4pamm14HBPammShortcut16registerKeywordsERNS_8KeywordsE17
_ZN4PLMD4pamm12HBPammMatrix16registerKeywordsERNS_8KeywordsE25
_ZNK4PLMD4pamm12HBPammMatrix15calculateWeightERKNS_13VectorGenericILj3EEES5_RKjRNS_10MultiValueE16286
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/pamm/HBPammMatrix.cpp.func.html b/coverage/pamm/HBPammMatrix.cpp.func.html new file mode 100644 index 000000000000..e129cf9e6ce9 --- /dev/null +++ b/coverage/pamm/HBPammMatrix.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:10611393.8 %
Date:2024-04-19 12:12:35Functions:5771.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4pamm12HBPammMatrix16registerKeywordsERNS_8KeywordsE25
_ZN4PLMD4pamm12HBPammMatrixC1ERKNS_13ActionOptionsE6
_ZN4PLMD4pamm12HBPammMatrixC2ERKNS_13ActionOptionsE0
_ZN4PLMD4pamm14HBPammShortcut16registerKeywordsERNS_8KeywordsE17
_ZN4PLMD4pamm14HBPammShortcutC1ERKNS_13ActionOptionsE6
_ZN4PLMD4pamm14HBPammShortcutC2ERKNS_13ActionOptionsE0
_ZNK4PLMD4pamm12HBPammMatrix15calculateWeightERKNS_13VectorGenericILj3EEES5_RKjRNS_10MultiValueE16286
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/pamm/HBPammMatrix.cpp.gcov.html b/coverage/pamm/HBPammMatrix.cpp.gcov.html new file mode 100644 index 000000000000..c62a07285f73 --- /dev/null +++ b/coverage/pamm/HBPammMatrix.cpp.gcov.html @@ -0,0 +1,335 @@ + + + + + + + + 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:10611393.8 %
Date:2024-04-19 12:12:35Functions:5771.4 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2020 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received 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/MultiColvarShortcuts.h"
+      24             : #include "core/ActionRegister.h"
+      25             : #include "core/ActionShortcut.h"
+      26             : #include "core/PlumedMain.h"
+      27             : #include "core/ActionSet.h"
+      28             : #include "tools/IFile.h"
+      29             : 
+      30             : //+PLUMEDOC MATRIX HBPAMM_MATRIX
+      31             : /*
+      32             : Adjacency matrix in which two electronegative atoms are adjacent if they are hydrogen bonded
+      33             : 
+      34             : \par Examples
+      35             : 
+      36             : */
+      37             : //+ENDPLUMEDOC
+      38             : 
+      39             : //+PLUMEDOC COLVAR HBPAMM_SA
+      40             : /*
+      41             : Calculate the number of hydrogen bonds each acceptor participates in using the HBPamm method
+      42             : 
+      43             : \par Examples
+      44             : 
+      45             : */
+      46             : //+ENDPLUMEDOC
+      47             : 
+      48             : //+PLUMEDOC COLVAR HBPAMM_SD
+      49             : /*
+      50             : Calculate the number of hydrogen bonds each donor participates in using the HBPamm method
+      51             : 
+      52             : \par Examples
+      53             : 
+      54             : */
+      55             : //+ENDPLUMEDOC
+      56             : 
+      57             : //+PLUMEDOC COLVAR HBPAMM_SH
+      58             : /*
+      59             : Calculate the number of hydrogen bonds each hydrogen participates in using the HBPamm method
+      60             : 
+      61             : \par Examples
+      62             : 
+      63             : */
+      64             : //+ENDPLUMEDOC
+      65             : 
+      66             : namespace PLMD {
+      67             : namespace pamm {
+      68             : 
+      69             : class HBPammMatrix : public adjmat::AdjacencyMatrixBase {
+      70             : private:
+      71             :   double regulariser;
+      72             :   Tensor incoord_to_hbcoord;
+      73             :   std::vector<double> weight;
+      74             :   std::vector<Vector> centers;
+      75             :   std::vector<Tensor> kmat;
+      76             : public:
+      77             : /// Create manual
+      78             :   static void registerKeywords( Keywords& keys );
+      79             : /// Constructor
+      80             :   explicit HBPammMatrix(const ActionOptions&);
+      81             : ///
+      82             :   double calculateWeight( const Vector& pos1, const Vector& pos2, const unsigned& natoms, MultiValue& myvals ) const ;
+      83             : };
+      84             : 
+      85             : PLUMED_REGISTER_ACTION(HBPammMatrix,"HBPAMM_MATRIX")
+      86             : 
+      87          25 : void HBPammMatrix::registerKeywords( Keywords& keys ) {
+      88          25 :   adjmat::AdjacencyMatrixBase::registerKeywords( keys ); keys.use("GROUPC");
+      89          50 :   keys.add("compulsory","ORDER","dah","the order in which the groups are specified in the input.  Can be dah (donor/acceptor/hydrogens), "
+      90             :            "adh (acceptor/donor/hydrogens) or hda (hydrogens/donor/hydrogens");
+      91          50 :   keys.add("compulsory","CLUSTERS","the name of the file that contains the definitions of all the kernels for PAMM");
+      92          50 :   keys.add("compulsory","REGULARISE","0.001","don't allow the denominator to be smaller then this value");
+      93          50 :   keys.add("compulsory","GAUSS_CUTOFF","6.25","the cutoff at which to stop evaluating the kernel function is set equal to sqrt(2*x)*(max(adc)+cov(adc))");
+      94          75 :   keys.needsAction("PAMM"); keys.needsAction("ONES"); keys.needsAction("MATRIX_VECTOR_PRODUCT");
+      95          25 : }
+      96             : 
+      97           6 : HBPammMatrix::HBPammMatrix(const ActionOptions& ao):
+      98             :   Action(ao),
+      99           6 :   AdjacencyMatrixBase(ao)
+     100             : {
+     101          18 :   double DP2CUTOFF; parse("GAUSS_CUTOFF",DP2CUTOFF); std::string sorder; parse("ORDER",sorder);
+     102           6 :   if( sorder=="dah" ) {
+     103           2 :     incoord_to_hbcoord(0,0)=1; incoord_to_hbcoord(0,1)=-1; incoord_to_hbcoord(0,2)=0;
+     104           2 :     incoord_to_hbcoord(1,0)=1; incoord_to_hbcoord(1,1)=1; incoord_to_hbcoord(1,2)=0;
+     105           2 :     incoord_to_hbcoord(2,0)=0; incoord_to_hbcoord(2,1)=0; incoord_to_hbcoord(2,2)=1;
+     106           2 :     log.printf("  GROUPA is list of donor atoms \n");
+     107           4 :   } else if( sorder=="adh" ) {
+     108           2 :     incoord_to_hbcoord(0,0)=-1; incoord_to_hbcoord(0,1)=1; incoord_to_hbcoord(0,2)=0;
+     109           2 :     incoord_to_hbcoord(1,0)=1; incoord_to_hbcoord(1,1)=1; incoord_to_hbcoord(1,2)=0;
+     110           2 :     incoord_to_hbcoord(2,0)=0; incoord_to_hbcoord(2,1)=0; incoord_to_hbcoord(2,2)=1;
+     111           2 :     log.printf("  GROUPA is list of acceptor atoms \n");
+     112           2 :   } else if( sorder=="hda" ) {
+     113           2 :     incoord_to_hbcoord(0,0)=-1; incoord_to_hbcoord(0,1)=0; incoord_to_hbcoord(0,2)=1;
+     114           2 :     incoord_to_hbcoord(1,0)=1; incoord_to_hbcoord(1,1)=0; incoord_to_hbcoord(1,2)=1;
+     115           2 :     incoord_to_hbcoord(2,0)=0; incoord_to_hbcoord(2,1)=1; incoord_to_hbcoord(2,2)=0;
+     116           2 :     log.printf("  GROUPA is list of hydrogen atoms \n");
+     117           0 :   } else plumed_error();
+     118             :   // Read in the regularisation parameter
+     119          12 :   parse("REGULARISE",regulariser);
+     120             : 
+     121             :   // Read in the kernels
+     122             :   double sqr2pi = sqrt(2*pi); double sqrt2pi3 = sqr2pi*sqr2pi*sqr2pi;
+     123          12 :   std::string fname; parse("CLUSTERS", fname); double sfmax=0, ww; Vector cent; Tensor covar;
+     124           6 :   IFile ifile; ifile.open(fname); ifile.allowIgnoredFields();
+     125             :   for(unsigned k=0;; ++k) {
+     126         144 :     if( !ifile.scanField("height",ww) ) break;
+     127         198 :     ifile.scanField("ptc",cent[0]); ifile.scanField("ssc",cent[1]); ifile.scanField("adc",cent[2]);
+     128         198 :     ifile.scanField("sigma_ptc_ptc",covar[0][0]); ifile.scanField("sigma_ptc_ssc",covar[0][1]); ifile.scanField("sigma_ptc_adc",covar[0][2]);
+     129         132 :     covar[1][0] = covar[0][1]; ifile.scanField("sigma_ssc_ssc",covar[1][1]); ifile.scanField("sigma_ssc_adc",covar[1][2]);
+     130          66 :     covar[2][0] = covar[0][2]; covar[2][1] = covar[1][2]; ifile.scanField("sigma_adc_adc",covar[2][2]);
+     131          66 :     weight.push_back( ww / ( sqrt2pi3 * sqrt(covar.determinant()) ) );
+     132          66 :     centers.push_back( cent ); kmat.push_back( covar.inverse() );
+     133             : 
+     134          66 :     Vector eigval; Tensor eigvec; diagMatSym( covar, eigval, eigvec );
+     135          66 :     unsigned ind_maxeval=0; double max_eval=eigval[0];
+     136         198 :     for(unsigned i=1; i<3; ++i) {
+     137         132 :       if( eigval[i]>max_eval ) { max_eval=eigval[i]; ind_maxeval=i; }
+     138             :     }
+     139          66 :     double rcut = cent[2] + sqrt(2.0*DP2CUTOFF)*fabs(sqrt(max_eval)*eigvec(2,ind_maxeval));
+     140          66 :     if( rcut > sfmax ) sfmax = rcut;
+     141          66 :     ifile.scanField();
+     142          66 :   }
+     143           6 :   ifile.close(); setLinkCellCutoff( false, sfmax );
+     144          12 : }
+     145             : 
+     146       16286 : double HBPammMatrix::calculateWeight( const Vector& pos1, const Vector& pos2, const unsigned& natoms, MultiValue& myvals ) const {
+     147       16286 :   Vector ddij, ddik, ddin, in_dists, hb_pamm_dists, hb_pamm_ders, real_ders;
+     148       16286 :   ddin = pbcDistance( pos1, pos2 ); in_dists[2] = ddin.modulo();
+     149       16286 :   if( in_dists[2]<epsilon ) return 0;
+     150             : 
+     151       16286 :   double tot=0; Vector disp, der, tmp_der;
+     152     1572892 :   for(unsigned i=0; i<natoms; ++i) {
+     153     1556606 :     ddij = getPosition(i,myvals); in_dists[0] = ddij.modulo();
+     154     1556606 :     ddik = pbcDistance( pos2, getPosition(i,myvals) ); in_dists[1] = ddik.modulo();
+     155     1556606 :     if( in_dists[1]<epsilon ) continue;
+     156             : 
+     157     1548396 :     hb_pamm_dists = matmul( incoord_to_hbcoord, in_dists );
+     158     1548396 :     disp = hb_pamm_dists - centers[0]; der = matmul( kmat[0], disp );
+     159     1548396 :     double vv = weight[0]*exp( -dotProduct( disp, der ) / 2. ); der *= -vv;
+     160             : 
+     161     6193584 :     double denom = regulariser + vv; for(unsigned j=0; j<3; ++j) hb_pamm_ders[j] = der[j];
+     162    17032356 :     for(unsigned k=1; k<weight.size(); ++k) {
+     163    15483960 :       disp = hb_pamm_dists - centers[k]; tmp_der = matmul( kmat[k], disp );
+     164    15483960 :       double tval = weight[k]*exp( -dotProduct( disp, tmp_der ) / 2. );
+     165    15483960 :       denom += tval; hb_pamm_ders += -tmp_der*tval;
+     166             :     }
+     167     1548396 :     double vf = vv / denom; tot += vf;
+     168     1548396 :     if( fabs(vf)<epsilon ) continue;
+     169             :     // Now get derivatives
+     170        2241 :     real_ders = matmul( der / denom - vf*hb_pamm_ders/denom, incoord_to_hbcoord );
+     171             : 
+     172             :     // And add the derivatives to the underlying atoms
+     173        2241 :     addAtomDerivatives( 0, -(real_ders[0]/in_dists[0])*ddij - (real_ders[2]/in_dists[2])*ddin, myvals );
+     174        2241 :     addAtomDerivatives( 1, -(real_ders[1]/in_dists[1])*ddik + (real_ders[2]/in_dists[2])*ddin, myvals );
+     175        2241 :     addThirdAtomDerivatives( i, (real_ders[0]/in_dists[0])*ddij + (real_ders[1]/in_dists[1])*ddik, myvals );
+     176        4482 :     addBoxDerivatives( -(real_ders[0]/in_dists[0])*Tensor( ddij, ddij )
+     177        4482 :                        -(real_ders[1]/in_dists[1])*Tensor( ddik, ddik )
+     178        6723 :                        -(real_ders[2]/in_dists[2])*Tensor( ddin, ddin ), myvals );
+     179             :   }
+     180       16286 :   return tot;
+     181             : }
+     182             : 
+     183             : class HBPammShortcut : public ActionShortcut {
+     184             : public:
+     185             :   static void registerKeywords( Keywords& keys );
+     186             :   HBPammShortcut(const ActionOptions&);
+     187             : };
+     188             : 
+     189             : PLUMED_REGISTER_ACTION(HBPammShortcut,"HBPAMM_SD")
+     190             : PLUMED_REGISTER_ACTION(HBPammShortcut,"HBPAMM_SA")
+     191             : PLUMED_REGISTER_ACTION(HBPammShortcut,"HBPAMM_SH")
+     192             : 
+     193          17 : void HBPammShortcut::registerKeywords( Keywords& keys ) {
+     194          68 :   HBPammMatrix::registerKeywords( keys ); keys.remove("GROUP"); keys.remove("GROUPA"); keys.remove("GROUPB"); keys.remove("COMPONENTS");
+     195          34 :   keys.add("optional","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 "
+     196             :            "hydrogen bond is assumed to be the same as the set of atoms that can form hydrogen bonds.  The atoms involved must be specified"
+     197             :            "as a list of labels of \\ref mcolv or labels of a \\ref multicolvarfunction actions.  If you would just like to use "
+     198             :            "the atomic positions you can use a \\ref DENSITY command to specify a group of atoms.  Specifying your atomic positions using labels of "
+     199             :            "other \\ref mcolv or \\ref multicolvarfunction commands is useful, however, as you can then exploit a much wider "
+     200             :            "variety of functions of the contact matrix as described in \\ref contactmatrix");
+     201          34 :   keys.add("optional","DONORS","The list of atoms which can donate a hydrogen bond.  The atoms involved must be specified "
+     202             :            "as a list of labels of \\ref mcolv or labels of a \\ref multicolvarfunction actions.  If you would just like to use "
+     203             :            "the atomic positions you can use a \\ref DENSITY command to specify a group of atoms.  Specifying your atomic positions using labels of "
+     204             :            "other \\ref mcolv or \\ref multicolvarfunction commands is useful, however, as you can then exploit a much wider "
+     205             :            "variety of functions of the contact matrix as described in \\ref contactmatrix");
+     206          34 :   keys.add("optional","ACCEPTORS","The list of atoms which can accept a hydrogen bond.  The atoms involved must be specified "
+     207             :            "as a list of labels of \\ref mcolv or labels of a \\ref multicolvarfunction actions.  If you would just like to use "
+     208             :            "the atomic positions you can use a \\ref DENSITY command to specify a group of atoms.  Specifying your atomic positions using labels of "
+     209             :            "other \\ref mcolv or \\ref multicolvarfunction commands is useful, however, as you can then exploit a much wider "
+     210             :            "variety of functions of the contact matrix as described in \\ref contactmatrix");
+     211          34 :   keys.add("compulsory","HYDROGENS","The list of hydrogen atoms that can form part of a hydrogen bond.  The atoms must be specified using a comma separated list, "
+     212             :            "an index range or by using a \\ref GROUP");
+     213          17 :   multicolvar::MultiColvarShortcuts::shortcutKeywords( keys ); keys.needsAction("HBPAMM_MATRIX");
+     214          17 : }
+     215             : 
+     216           6 : HBPammShortcut::HBPammShortcut(const ActionOptions&ao):
+     217             :   Action(ao),
+     218           6 :   ActionShortcut(ao)
+     219             : {
+     220           6 :   std::string mwords = getShortcutLabel() + "_mat: HBPAMM_MATRIX";
+     221           6 :   if( getName()=="HBPAMM_SD" ) {
+     222           4 :     std::string site_str; parse("SITES",site_str);
+     223           4 :     if( site_str.length()>0 ) mwords += " GROUP=" + site_str;
+     224             :     else {
+     225           0 :       std::string d_str; parse("DONORS",d_str); mwords += " GROUPA=" + d_str;
+     226           0 :       std::string a_str; parse("ACCEPTORS",a_str); mwords += " GROUPB=" + a_str;
+     227             :     }
+     228           6 :     std::string h_str; parse("HYDROGENS",h_str); mwords += " GROUPC=" + h_str + " ORDER=dah";
+     229           4 :   } else if( getName()=="HBPAMM_SA" ) {
+     230           4 :     std::string site_str; parse("SITES",site_str);
+     231           4 :     if( site_str.length()>0 ) mwords += " GROUP=" + site_str;
+     232             :     else {
+     233           0 :       std::string a_str; parse("ACCEPTORS",a_str); mwords += " GROUPA=" + a_str;
+     234           0 :       std::string d_str; parse("DONORS",d_str); mwords += " GROUPB=" + d_str;
+     235             :     }
+     236           6 :     std::string h_str; parse("HYDROGENS",h_str); mwords += " GROUPC=" + h_str + " ORDER=adh";
+     237           2 :   } else if( getName()=="HBPAMM_SH" ) {
+     238           6 :     std::string h_str; parse("HYDROGENS",h_str); mwords += " GROUPA=" + h_str + " ORDER=hda";
+     239           4 :     std::string site_str; parse("SITES",site_str);
+     240           2 :     if( site_str.length()>0 ) {
+     241           2 :       mwords += " GROUPB=" + site_str;
+     242           4 :       mwords += " GROUPC=" + site_str;
+     243             :     } else {
+     244           0 :       std::string d_str; parse("DONORS",d_str); mwords += " GROUPB=" + d_str;
+     245           0 :       std::string a_str; parse("ACCEPTORS",a_str); mwords += " GROUPC=" + a_str;
+     246             :     }
+     247             :   }
+     248           6 :   std::map<std::string,std::string> keymap; multicolvar::MultiColvarShortcuts::readShortcutKeywords( keymap, this );
+     249          12 :   readInputLine( mwords + " " + convertInputLineToString() );
+     250           6 :   ActionWithValue* mb=plumed.getActionSet().selectWithLabel<ActionWithValue*>( getShortcutLabel() + "_mat");
+     251           6 :   plumed_assert( mb ); std::string nsize; Tools::convert( (mb->copyOutput(getShortcutLabel() + "_mat"))->getShape()[1], nsize );
+     252          12 :   readInputLine( getShortcutLabel() + "_ones: ONES SIZE=" + nsize );
+     253          12 :   readInputLine( getShortcutLabel() + ": MATRIX_VECTOR_PRODUCT ARG=" + getShortcutLabel() + "_mat," + getShortcutLabel() + "_ones");
+     254          12 :   multicolvar::MultiColvarShortcuts::expandFunctions( getShortcutLabel(), getShortcutLabel(), "", keymap, this );
+     255           6 : }
+     256             : 
+     257             : }
+     258             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/pamm/PAMM.cpp.func-sort-c.html b/coverage/pamm/PAMM.cpp.func-sort-c.html new file mode 100644 index 000000000000..360b51b010fa --- /dev/null +++ b/coverage/pamm/PAMM.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + 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:384388.4 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4pamm4PAMMC2ERKNS_13ActionOptionsE0
_ZN4PLMD4pamm4PAMMC1ERKNS_13ActionOptionsE2
_ZN4PLMD4pamm4PAMM16registerKeywordsERNS_8KeywordsE4
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/pamm/PAMM.cpp.func.html b/coverage/pamm/PAMM.cpp.func.html new file mode 100644 index 000000000000..3f01e4aa4170 --- /dev/null +++ b/coverage/pamm/PAMM.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + 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:384388.4 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4pamm4PAMM16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD4pamm4PAMMC1ERKNS_13ActionOptionsE2
_ZN4PLMD4pamm4PAMMC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/pamm/PAMM.cpp.gcov.html b/coverage/pamm/PAMM.cpp.gcov.html new file mode 100644 index 000000000000..2dbe754a5f28 --- /dev/null +++ b/coverage/pamm/PAMM.cpp.gcov.html @@ -0,0 +1,264 @@ + + + + + + + + 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:384388.4 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2020 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received 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/ActionShortcut.h"
+      24             : #include "multicolvar/MultiColvarShortcuts.h"
+      25             : #include "tools/IFile.h"
+      26             : #include "core/ActionSetup.h"
+      27             : 
+      28             : //+PLUMEDOC MCOLVARF PAMM
+      29             : /*
+      30             : Probabilistic analysis of molecular motifs.
+      31             : 
+      32             : Probabilistic analysis of molecular motifs (PAMM) was introduced in this paper \cite pamm.
+      33             : The essence of this approach involves calculating some large set of collective variables
+      34             : for a set of atoms in a short trajectory and fitting this data using a Gaussian Mixture Model.
+      35             : The idea is that modes in these distributions can be used to identify features such as hydrogen bonds or
+      36             : secondary structure types.
+      37             : 
+      38             : The assumption within this implementation is that the fitting of the Gaussian mixture model has been
+      39             : done elsewhere by a separate code.  You thus provide an input file to this action which contains the
+      40             : means, covariance matrices and weights for a set of Gaussian kernels, \f$\{ \phi \}\f$.  The values and
+      41             : derivatives for the following set of quantities is then computed:
+      42             : 
+      43             : \f[
+      44             : s_k = \frac{ \phi_k}{ \sum_i \phi_i }
+      45             : \f]
+      46             : 
+      47             : Each of the \f$\phi_k\f$ is a Gaussian function that acts on a set of quantities calculated within
+      48             : a \ref mcolv .  These might be \ref TORSIONS, \ref DISTANCES, \ref ANGLES or any one of the many
+      49             : symmetry functions that are available within \ref mcolv actions.  These quantities are then inserted into
+      50             : the set of \f$n\f$ kernels that are in the the input file.   This will be done for multiple sets of values
+      51             : for the input quantities and a final quantity will be calculated by summing the above \f$s_k\f$ values or
+      52             : some transformation of the above.  This sounds less complicated than it is and is best understood by
+      53             : looking through the example given below.
+      54             : 
+      55             : \warning Mixing \ref mcolv actions that are periodic with variables that are not periodic has not been tested
+      56             : 
+      57             : \par Examples
+      58             : 
+      59             : In this example I will explain in detail what the following input is computing:
+      60             : 
+      61             : \plumedfile
+      62             : #SETTINGS MOLFILE=regtest/basic/rt32/helix.pdb
+      63             : MOLINFO MOLTYPE=protein STRUCTURE=M1d.pdb
+      64             : psi: TORSIONS ATOMS1=@psi-2 ATOMS2=@psi-3 ATOMS3=@psi-4
+      65             : phi: TORSIONS ATOMS1=@phi-2 ATOMS2=@phi-3 ATOMS3=@phi-4
+      66             : p: PAMM DATA=phi,psi CLUSTERS=clusters.pamm MEAN1={COMPONENT=1} MEAN2={COMPONENT=2}
+      67             : PRINT ARG=p.mean-1,p.mean-2 FILE=colvar
+      68             : \endplumedfile
+      69             : 
+      70             : The best place to start our explanation is to look at the contents of the clusters.pamm file
+      71             : 
+      72             : \auxfile{clusters.pamm}
+      73             : #! FIELDS height phi psi sigma_phi_phi sigma_phi_psi sigma_psi_phi sigma_psi_psi
+      74             : #! SET multivariate von-misses
+      75             : #! SET kerneltype gaussian
+      76             :       2.97197455E-0001     -1.91983118E+0000      2.25029540E+0000      2.45960237E-0001     -1.30615381E-0001     -1.30615381E-0001      2.40239117E-0001
+      77             :       2.29131448E-0002      1.39809354E+0000      9.54585380E-0002      9.61755708E-0002     -3.55657919E-0002     -3.55657919E-0002      1.06147253E-0001
+      78             :       5.06676398E-0001     -1.09648066E+0000     -7.17867907E-0001      1.40523052E-0001     -1.05385552E-0001     -1.05385552E-0001      1.63290557E-0001
+      79             : \endauxfile
+      80             : 
+      81             : This files contains the parameters of two two-dimensional Gaussian functions.  Each of these Gaussian kernels has a weight, \f$w_k\f$,
+      82             : 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
+      83             : we use to calculate our PAMM components are thus:
+      84             : 
+      85             : \f[
+      86             : \phi_k = \frac{w_k}{N_k} \exp\left( -(\mathbf{s} - \mathbf{c}_k)^T \Sigma^{-1}_k (\mathbf{s} - \mathbf{c}_k) \right)
+      87             : \f]
+      88             : 
+      89             : 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
+      90             : 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
+      91             : 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
+      92             : angles in a protein (Note the use of \ref MOLINFO to make specification of atoms straightforward).  We thus calculate the values of our
+      93             : 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,
+      94             : 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
+      95             : 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
+      96             : over these three residues for the quantities:
+      97             : \f[
+      98             : s_1 = \frac{ \phi_1}{ \phi_1 + \phi_2 }
+      99             : \f]
+     100             : and
+     101             : \f[
+     102             : s_2 = \frac{ \phi_2}{ \phi_1 + \phi_2 }
+     103             : \f]
+     104             : 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
+     105             : and compute these PAMM variables and we can transform the PAMM variables themselves in a large number of different ways when computing these sums.
+     106             : */
+     107             : //+ENDPLUMEDOC
+     108             : 
+     109             : namespace PLMD {
+     110             : namespace pamm {
+     111             : 
+     112             : class PAMM : public ActionShortcut {
+     113             : public:
+     114             :   static void registerKeywords( Keywords& keys );
+     115             :   explicit PAMM(const ActionOptions&);
+     116             : };
+     117             : 
+     118             : PLUMED_REGISTER_ACTION(PAMM,"PAMM")
+     119             : 
+     120           4 : void PAMM::registerKeywords( Keywords& keys ) {
+     121           4 :   ActionShortcut::registerKeywords( keys );
+     122           8 :   keys.add("compulsory","ARG","the vectors from which the pamm coordinates are calculated");
+     123           8 :   keys.add("compulsory","CLUSTERS","the name of the file that contains the definitions of all the clusters");
+     124           8 :   keys.add("compulsory","REGULARISE","0.001","don't allow the denominator to be smaller then this value");
+     125           8 :   keys.add("compulsory","KERNELS","all","which kernels are we computing the PAMM values for");
+     126           4 :   multicolvar::MultiColvarShortcuts::shortcutKeywords( keys );
+     127           8 :   keys.needsAction("KERNEL"); keys.needsAction("COMBINE");
+     128           4 : }
+     129             : 
+     130           2 : PAMM::PAMM(const ActionOptions& ao) :
+     131             :   Action(ao),
+     132           2 :   ActionShortcut(ao)
+     133             : {
+     134             :   // Must get list of input value names
+     135           4 :   std::vector<std::string> valnames; parseVector("ARG",valnames);
+     136             :   // Create input values
+     137           2 :   std::string argstr=" ARG=" + valnames[0];
+     138           3 :   for(unsigned j=1; j<valnames.size(); ++j) argstr += "," + valnames[j];
+     139             : 
+     140             :   // Create actions to calculate all pamm kernels
+     141             :   unsigned nkernels = 0;  double h;
+     142           2 :   std::string fname; parse("CLUSTERS",fname);
+     143           2 :   IFile ifile; ifile.open(fname); ifile.allowIgnoredFields();
+     144             :   for(unsigned k=0;; ++k) {
+     145          22 :     if( !ifile.scanField("height",h) ) break;
+     146             :     // Create a kernel for this cluster
+     147           9 :     std::string num, wstr, ktype; Tools::convert( k+1, num ); Tools::convert(h,wstr); ifile.scanField("kerneltype",ktype);
+     148          18 :     readInputLine( getShortcutLabel() + "_kernel-" + num + ": KERNEL NORMALIZED" + argstr  + " NUMBER=" + num + " REFERENCE=" + fname + " WEIGHT=" + wstr + " TYPE=" + ktype );
+     149           9 :     nkernels++; ifile.scanField();
+     150           9 :   }
+     151           2 :   ifile.close();
+     152             : 
+     153             :   // And add on the regularization
+     154           4 :   std::string regparam; parse("REGULARISE",regparam);
+     155             :   // Now combine all the PAMM objects with the regparam
+     156           2 :   std::string paramstr, cinput = getShortcutLabel() + "_ksum: COMBINE PERIODIC=NO";
+     157          11 :   for(unsigned k=0; k<nkernels; ++k) {
+     158           9 :     std::string num; Tools::convert( k+1, num );
+     159           9 :     if( k==0 ) {
+     160           4 :       cinput += " ARG="; paramstr=" PARAMETERS=-" + regparam;
+     161             :     } else {
+     162             :       cinput += ","; paramstr += ",0";
+     163             :     }
+     164          18 :     cinput += getShortcutLabel() + "_kernel-" + num;
+     165             :   }
+     166           4 :   readInputLine( cinput + paramstr );
+     167             : 
+     168             :   // And now compute all the pamm kernels
+     169           4 :   std::string kchoice; parse("KERNELS",kchoice);
+     170           2 :   std::map<std::string,std::string> keymap; multicolvar::MultiColvarShortcuts::readShortcutKeywords( keymap, this );
+     171           2 :   if( kchoice=="all" ) {
+     172          11 :     for(unsigned k=0; k<nkernels; ++k) {
+     173           9 :       std::string num; Tools::convert( k+1, num );
+     174          18 :       readInputLine( getShortcutLabel() + "-" + num + ": CUSTOM ARG=" + getShortcutLabel() + "_kernel-" + num + "," + getShortcutLabel() + "_ksum FUNC=x/y PERIODIC=NO");
+     175          18 :       multicolvar::MultiColvarShortcuts::expandFunctions( getShortcutLabel() + "-" + num, getShortcutLabel() + "-" + num, "", keymap, this );
+     176             :     }
+     177             :   } else {
+     178           0 :     std::vector<std::string> awords=Tools::getWords(kchoice,"\t\n ,"); Tools::interpretRanges( awords );
+     179           0 :     for(unsigned k=0; k<awords.size(); ++k) {
+     180           0 :       readInputLine( getShortcutLabel() + "-" + awords[k] + ": CUSTOM ARG=" + getShortcutLabel() + "_kernel-" + awords[k] + "," + getShortcutLabel() + "_ksum FUNC=x/y PERIODIC=NO");
+     181           0 :       multicolvar::MultiColvarShortcuts::expandFunctions( getShortcutLabel() + "-" + awords[k], getShortcutLabel() + "-" + awords[k], "", keymap, this );
+     182             :     }
+     183           0 :   }
+     184           4 : }
+     185             : 
+     186             : }
+     187             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/pamm/index-sort-f.html b/coverage/pamm/index-sort-f.html new file mode 100644 index 000000000000..27bea4714676 --- /dev/null +++ b/coverage/pamm/index-sort-f.html @@ -0,0 +1,104 @@ + + + + + + + + LCOV - plumed test coverage - pamm + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - pammHitTotalCoverage
Test:plumed test coverageLines:14415692.3 %
Date:2024-04-19 12:12:35Functions:71070.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
PAMM.cpp +
88.4%88.4%
+
88.4 %38 / 4366.7 %2 / 3
HBPammMatrix.cpp +
93.8%93.8%
+
93.8 %106 / 11371.4 %5 / 7
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/pamm/index-sort-l.html b/coverage/pamm/index-sort-l.html new file mode 100644 index 000000000000..402a87056f2a --- /dev/null +++ b/coverage/pamm/index-sort-l.html @@ -0,0 +1,104 @@ + + + + + + + + LCOV - plumed test coverage - pamm + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - pammHitTotalCoverage
Test:plumed test coverageLines:14415692.3 %
Date:2024-04-19 12:12:35Functions:71070.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
PAMM.cpp +
88.4%88.4%
+
88.4 %38 / 4366.7 %2 / 3
HBPammMatrix.cpp +
93.8%93.8%
+
93.8 %106 / 11371.4 %5 / 7
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/pamm/index.html b/coverage/pamm/index.html new file mode 100644 index 000000000000..4146f234fa31 --- /dev/null +++ b/coverage/pamm/index.html @@ -0,0 +1,104 @@ + + + + + + + + LCOV - plumed test coverage - pamm + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - pammHitTotalCoverage
Test:plumed test coverageLines:14415692.3 %
Date:2024-04-19 12:12:35Functions:71070.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
HBPammMatrix.cpp +
93.8%93.8%
+
93.8 %106 / 11371.4 %5 / 7
PAMM.cpp +
88.4%88.4%
+
88.4 %38 / 4366.7 %2 / 3
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/piv/PIV.cpp.func-sort-c.html b/coverage/piv/PIV.cpp.func-sort-c.html new file mode 100644 index 000000000000..9a08731aedc1 --- /dev/null +++ b/coverage/piv/PIV.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - piv/PIV.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - piv - PIV.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:42759571.8 %
Date:2024-04-19 12:12:35Functions:3560.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3piv3PIV18checkFieldsAllowedEv0
_ZN4PLMD3piv3PIVC2ERKNS_13ActionOptionsE0
_ZN4PLMD3piv3PIVC1ERKNS_13ActionOptionsE12
_ZN4PLMD3piv3PIV16registerKeywordsERNS_8KeywordsE14
_ZN4PLMD3piv3PIV9calculateEv327
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/piv/PIV.cpp.func.html b/coverage/piv/PIV.cpp.func.html new file mode 100644 index 000000000000..2b73ec907bbb --- /dev/null +++ b/coverage/piv/PIV.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - piv/PIV.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - piv - PIV.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:42759571.8 %
Date:2024-04-19 12:12:35Functions:3560.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3piv3PIV16registerKeywordsERNS_8KeywordsE14
_ZN4PLMD3piv3PIV18checkFieldsAllowedEv0
_ZN4PLMD3piv3PIV9calculateEv327
_ZN4PLMD3piv3PIVC1ERKNS_13ActionOptionsE12
_ZN4PLMD3piv3PIVC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/piv/PIV.cpp.gcov.html b/coverage/piv/PIV.cpp.gcov.html new file mode 100644 index 000000000000..6d6ef2446b4c --- /dev/null +++ b/coverage/piv/PIV.cpp.gcov.html @@ -0,0 +1,1340 @@ + + + + + + + + LCOV - plumed test coverage - piv/PIV.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - piv - PIV.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:42759571.8 %
Date:2024-04-19 12:12:35Functions:3560.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2017 of Pipolo Silvio and Fabio Pietrucci.
+       3             : 
+       4             : The piv module is free software: you can redistribute it and/or modify
+       5             : it under the terms of the GNU Lesser General Public License as published by
+       6             : the Free Software Foundation, either version 3 of the License, or
+       7             : (at your option) any later version.
+       8             : 
+       9             : The piv module is distributed in the hope that it will be useful,
+      10             : but WITHOUT ANY WARRANTY; without even the implied warranty of
+      11             : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      12             : GNU Lesser General Public License for more details.
+      13             : 
+      14             : You should have received a copy of the GNU Lesser General Public License
+      15             : along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      16             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      17             : #include "colvar/Colvar.h"
+      18             : #include "core/ActionRegister.h"
+      19             : #include "core/PlumedMain.h"
+      20             : #include "core/ActionWithVirtualAtom.h"
+      21             : #include "tools/NeighborList.h"
+      22             : #include "tools/SwitchingFunction.h"
+      23             : #include "tools/PDB.h"
+      24             : #include "tools/Pbc.h"
+      25             : #include "tools/Communicator.h"
+      26             : #include "tools/Stopwatch.h"
+      27             : #include "core/ActionSet.h"
+      28             : 
+      29             : #include <string>
+      30             : #include <cmath>
+      31             : #include <iostream>
+      32             : 
+      33             : using namespace std;
+      34             : 
+      35             : namespace PLMD
+      36             : {
+      37             : namespace piv
+      38             : {
+      39             : 
+      40             : //+PLUMEDOC PIVMOD_COLVAR PIV
+      41             : /*
+      42             : Calculates the PIV-distance.
+      43             : 
+      44             : PIV distance is the squared Cartesian distance between the PIV \cite gallet2013structural \cite pipolo2017navigating
+      45             : associated to the configuration of the system during the dynamics and a reference configuration provided
+      46             : as input (PDB file format).
+      47             : PIV can be used together with \ref FUNCPATHMSD to define a path in the PIV space.
+      48             : 
+      49             : \par Examples
+      50             : 
+      51             : The following example calculates PIV-distances from three reference configurations in Ref1.pdb, Ref2.pdb and Ref3.pdb
+      52             : and prints the results in a file named colvar.
+      53             : Three atoms (PIVATOMS=3) with names (pdb file) A B and C are used to construct the PIV and all PIV blocks (AA, BB, CC, AB, AC, BC) are considered.
+      54             : SFACTOR is a scaling factor that multiplies the contribution to the PIV-distance given by the single PIV block.
+      55             : NLIST sets the use of neighbor lists for calculating atom-atom distances.
+      56             : The SWITCH keyword specifies the parameters of the switching function that transforms atom-atom distances.
+      57             : SORT=1 means that the PIV block elements are sorted (SORT=0 no sorting.)
+      58             : Values for SORT, SFACTOR and the neighbor list parameters have to be specified for each block.
+      59             : The order is the following: AA,BB,CC,AB,AC,BC. If ONLYDIRECT (ONLYCROSS) is used the order is AA,BB,CC (AB,AC,BC).
+      60             : The sorting operation within each PIV block is performed using the counting sort algorithm, PRECISION specifies the size of the counting array.
+      61             : 
+      62             : \plumedfile
+      63             : PIV ...
+      64             : LABEL=Pivd1
+      65             : PRECISION=1000
+      66             : NLIST
+      67             : REF_FILE=Ref1.pdb
+      68             : PIVATOMS=3
+      69             : ATOMTYPES=A,B,C
+      70             : SFACTOR=0.3,0.5,1.0,0.2,0.2,0.2
+      71             : SORT=1,1,1,1,1,1
+      72             : SWITCH1={RATIONAL R_0=0.6 MM=12 NN=4}
+      73             : SWITCH2={RATIONAL R_0=0.4 MM=10 NN=5}
+      74             : SWITCH3={RATIONAL R_0=0.4 MM=10 NN=5}
+      75             : SWITCH4={RATIONAL R_0=0.5 MM=12 NN=6}
+      76             : SWITCH5={RATIONAL R_0=0.5 MM=12 NN=6}
+      77             : SWITCH6={RATIONAL R_0=0.5 MM=12 NN=6}
+      78             : NL_CUTOFF=0.8,0.6,0.6,0.7,0.7,0.7
+      79             : NL_STRIDE=10,10,10,10,10,10
+      80             : NL_SKIN=0.1,0.1,0.1,0.1,0.1,0.1
+      81             : ... PIV
+      82             : PIV ...
+      83             : LABEL=Pivd2
+      84             : PRECISION=1000
+      85             : NLIST
+      86             : REF_FILE=Ref2.pdb
+      87             : PIVATOMS=3
+      88             : ATOMTYPES=A,B,C
+      89             : SFACTOR=0.3,0.5,1.0,0.2,0.2,0.2
+      90             : SORT=1,1,1,1,1,1
+      91             : SWITCH1={RATIONAL R_0=0.6 MM=12 NN=4}
+      92             : SWITCH2={RATIONAL R_0=0.4 MM=10 NN=5}
+      93             : SWITCH3={RATIONAL R_0=0.4 MM=10 NN=5}
+      94             : SWITCH4={RATIONAL R_0=0.5 MM=12 NN=6}
+      95             : SWITCH5={RATIONAL R_0=0.5 MM=12 NN=6}
+      96             : SWITCH6={RATIONAL R_0=0.5 MM=12 NN=6}
+      97             : NL_CUTOFF=0.8,0.6,0.6,0.7,0.7,0.7
+      98             : NL_STRIDE=10,10,10,10,10,10
+      99             : NL_SKIN=0.1,0.1,0.1,0.1,0.1,0.1
+     100             : ... PIV
+     101             : PIV ...
+     102             : LABEL=Pivd3
+     103             : PRECISION=1000
+     104             : NLIST
+     105             : REF_FILE=Ref3.pdb
+     106             : PIVATOMS=3
+     107             : ATOMTYPES=A,B,C
+     108             : SFACTOR=0.3,0.5,1.0,0.2,0.2,0.2
+     109             : SORT=1,1,1,1,1,1
+     110             : SWITCH1={RATIONAL R_0=0.6 MM=12 NN=4}
+     111             : SWITCH2={RATIONAL R_0=0.4 MM=10 NN=5}
+     112             : SWITCH3={RATIONAL R_0=0.4 MM=10 NN=5}
+     113             : SWITCH4={RATIONAL R_0=0.5 MM=12 NN=6}
+     114             : SWITCH5={RATIONAL R_0=0.5 MM=12 NN=6}
+     115             : SWITCH6={RATIONAL R_0=0.5 MM=12 NN=6}
+     116             : NL_CUTOFF=0.8,0.6,0.6,0.7,0.7,0.7
+     117             : NL_STRIDE=10,10,10,10,10,10
+     118             : NL_SKIN=0.1,0.1,0.1,0.1,0.1,0.1
+     119             : ... PIV
+     120             : 
+     121             : PRINT ARG=Pivd1,Pivd2,Pivd3 FILE=colvar
+     122             : \endplumedfile
+     123             : 
+     124             : WARNING:
+     125             : Both the "CRYST" and "ATOM" lines of the PDB files must conform precisely to the official pdb format, including the width of each alphanumerical field:
+     126             : 
+     127             : \verbatim
+     128             : CRYST1   31.028   36.957   23.143  89.93  92.31  89.99 P 1           1
+     129             : ATOM      1  OW1 wate    1      15.630  19.750   1.520  1.00  0.00
+     130             : \endverbatim
+     131             : 
+     132             : In each pdb frame, atoms must be numbered in the same order and with the same element symbol as in the input of the MD program.
+     133             : 
+     134             : The following example calculates the PIV-distances from two reference configurations Ref1.pdb and Ref2.pdb
+     135             : and uses PIV-distances to define a Path Collective Variable (\ref FUNCPATHMSD) with only two references (Ref1.pdb and Ref2.pdb).
+     136             : With the VOLUME keyword one scales the atom-atom distances by the cubic root of the ratio between the specified value and the box volume of the initial step of the trajectory file.
+     137             : 
+     138             : \plumedfile
+     139             : PIV ...
+     140             : LABEL=c1
+     141             : PRECISION=1000
+     142             : VOLUME=12.15
+     143             : NLIST
+     144             : REF_FILE=Ref1.pdb
+     145             : PIVATOMS=2
+     146             : ATOMTYPES=A,B
+     147             : ONLYDIRECT
+     148             : SFACTOR=1.0,0.2
+     149             : SORT=1,1
+     150             : SWITCH1={RATIONAL R_0=0.6 MM=12 NN=4}
+     151             : SWITCH2={RATIONAL R_0=0.5 MM=10 NN=5}
+     152             : NL_CUTOFF=1.2,1.2
+     153             : NL_STRIDE=10,10
+     154             : NL_SKIN=0.1,0.1
+     155             : ... PIV
+     156             : PIV ...
+     157             : LABEL=c2
+     158             : PRECISION=1000
+     159             : VOLUME=12.15
+     160             : NLIST
+     161             : REF_FILE=Ref2.pdb
+     162             : PIVATOMS=2
+     163             : ATOMTYPES=A,B
+     164             : ONLYDIRECT
+     165             : SFACTOR=1.0,0.2
+     166             : SORT=1,1
+     167             : SWITCH1={RATIONAL R_0=0.6 MM=12 NN=4}
+     168             : SWITCH2={RATIONAL R_0=0.4 MM=10 NN=5}
+     169             : NL_CUTOFF=1.2,1.2
+     170             : NL_STRIDE=10,10
+     171             : NL_SKIN=0.1,0.1
+     172             : ... PIV
+     173             : 
+     174             : p1: FUNCPATHMSD ARG=c1,c2 LAMBDA=0.180338
+     175             : METAD ARG=p1.s,p1.z SIGMA=0.01,0.2 HEIGHT=0.8 PACE=500   LABEL=res
+     176             : PRINT ARG=c1,c2,p1.s,p1.z,res.bias STRIDE=500  FILE=colvar FMT=%15.6f
+     177             : \endplumedfile
+     178             : 
+     179             : When using PIV please cite \cite pipolo2017navigating .
+     180             : 
+     181             : (See also \ref PRINT)
+     182             : 
+     183             : */
+     184             : //+ENDPLUMEDOC
+     185             : 
+     186             : class PIV      : public Colvar
+     187             : {
+     188             : private:
+     189             :   bool pbc, serial, timer;
+     190             :   ForwardDecl<Stopwatch> stopwatch_fwd;
+     191             :   Stopwatch& stopwatch=*stopwatch_fwd;
+     192             :   int updatePIV;
+     193             :   size_t Nprec;
+     194             :   unsigned Natm,Nlist,NLsize;
+     195             :   double Fvol,Vol0,m_PIVdistance;
+     196             :   std::string ref_file;
+     197             :   std::unique_ptr<NeighborList> nlall;
+     198             :   std::vector<SwitchingFunction> sfs;
+     199             :   std::vector<std:: vector<double> > rPIV;
+     200             :   std::vector<double> scaling,r00;
+     201             :   std::vector<double> nl_skin;
+     202             :   std::vector<double> fmass;
+     203             :   std::vector<bool> dosort;
+     204             :   std::vector<Vector> compos;
+     205             :   std::vector<string> sw;
+     206             :   std::vector<std::unique_ptr<NeighborList>> nl;
+     207             :   std::vector<std::unique_ptr<NeighborList>> nlcom;
+     208             :   std::vector<Vector> m_deriv;
+     209             :   Tensor m_virial;
+     210             :   bool Svol,cross,direct,doneigh,test,CompDer,com;
+     211             : 
+     212             :   /// Local structure, used to store data that should be
+     213             :   /// shared across multiple PIV instances
+     214           6 :   struct SharedData {
+     215             :     int prev_stp=-1;
+     216             :     int init_stp=1;
+     217             :     std:: vector<std:: vector<Vector> > prev_pos;
+     218             :     std:: vector<std:: vector<double> > cPIV;
+     219             :     std:: vector<std:: vector<int> > Atom0;
+     220             :     std:: vector<std:: vector<int> > Atom1;
+     221             :   };
+     222             :   /// Owning pointer. Will only be allocated by the first PIV instance
+     223             :   std::unique_ptr<SharedData> sharedData_unique;
+     224             :   /// Raw pointer. Will have the same value for all PIV instances
+     225             :   SharedData* sharedData=nullptr;
+     226             : 
+     227             : public:
+     228             :   static void registerKeywords( Keywords& keys );
+     229             :   explicit PIV(const ActionOptions&);
+     230             :   // active methods:
+     231             :   virtual void calculate();
+     232           0 :   void checkFieldsAllowed() {}
+     233             : };
+     234             : 
+     235             : PLUMED_REGISTER_ACTION(PIV,"PIV")
+     236             : 
+     237          14 : void PIV::registerKeywords( Keywords& keys )
+     238             : {
+     239          14 :   Colvar::registerKeywords( keys );
+     240          28 :   keys.add("numbered","SWITCH","The switching functions parameter."
+     241             :            "You should specify a Switching function for all PIV blocks."
+     242             :            "Details of the various switching "
+     243             :            "functions you can use are provided on \\ref switchingfunction.");
+     244          28 :   keys.add("compulsory","PRECISION","the precision for approximating reals with integers in sorting.");
+     245          28 :   keys.add("compulsory","REF_FILE","PDB file name that contains the \\f$i\\f$th reference structure.");
+     246          28 :   keys.add("compulsory","PIVATOMS","Number of atoms to use for PIV.");
+     247          28 :   keys.add("compulsory","SORT","Whether to sort or not the PIV block.");
+     248          28 :   keys.add("compulsory","ATOMTYPES","The atom types to use for PIV.");
+     249          28 :   keys.add("optional","SFACTOR","Scale the PIV-distance by such block-specific factor");
+     250          28 :   keys.add("optional","VOLUME","Scale atom-atom distances by the cubic root of the cell volume. The input volume is used to scale the R_0 value of the switching function. ");
+     251          28 :   keys.add("optional","UPDATEPIV","Frequency (in steps) at which the PIV is updated.");
+     252          28 :   keys.addFlag("TEST",false,"Print the actual and reference PIV and exit");
+     253          28 :   keys.addFlag("COM",false,"Use centers of mass of groups of atoms instead of atoms as specified in the Pdb file");
+     254          28 :   keys.addFlag("ONLYCROSS",false,"Use only cross-terms (A-B, A-C, B-C, ...) in PIV");
+     255          28 :   keys.addFlag("ONLYDIRECT",false,"Use only direct-terms (A-A, B-B, C-C, ...) in PIV");
+     256          28 :   keys.addFlag("DERIVATIVES",false,"Activate the calculation of the PIV for every class (needed for numerical derivatives).");
+     257          28 :   keys.addFlag("NLIST",false,"Use a neighbor list for distance calculations.");
+     258          28 :   keys.addFlag("SERIAL",false,"Perform the calculation in serial - for debug purpose");
+     259          28 :   keys.addFlag("TIMER",false,"Perform timing analysis on heavy loops.");
+     260          28 :   keys.add("optional","NL_CUTOFF","Neighbor lists cutoff.");
+     261          28 :   keys.add("optional","NL_STRIDE","Update neighbor lists every NL_STRIDE steps.");
+     262          28 :   keys.add("optional","NL_SKIN","The maximum atom displacement tolerated for the neighbor lists update.");
+     263          28 :   keys.reset_style("SWITCH","compulsory");
+     264          14 : }
+     265             : 
+     266          12 : PIV::PIV(const ActionOptions&ao):
+     267             :   PLUMED_COLVAR_INIT(ao),
+     268          12 :   pbc(true),
+     269          12 :   serial(false),
+     270          12 :   timer(false),
+     271          12 :   updatePIV(1),
+     272          12 :   Nprec(1000),
+     273          12 :   Natm(1),
+     274          12 :   Nlist(1),
+     275          12 :   NLsize(1),
+     276          12 :   Fvol(1.),
+     277          12 :   Vol0(0.),
+     278          12 :   m_PIVdistance(0.),
+     279          12 :   rPIV(std:: vector<std:: vector<double> >(Nlist)),
+     280          12 :   scaling(std:: vector<double>(Nlist)),
+     281          12 :   r00(std:: vector<double>(Nlist)),
+     282          12 :   nl_skin(std:: vector<double>(Nlist)),
+     283          12 :   fmass(std:: vector<double>(Nlist)),
+     284          12 :   dosort(std:: vector<bool>(Nlist)),
+     285          12 :   compos(std:: vector<Vector>(NLsize)),
+     286          12 :   sw(std:: vector<string>(Nlist)),
+     287          12 :   nl(Nlist),
+     288          12 :   nlcom(NLsize),
+     289          12 :   m_deriv(std:: vector<Vector>(1)),
+     290          12 :   Svol(false),
+     291          12 :   cross(true),
+     292          12 :   direct(true),
+     293          12 :   doneigh(false),
+     294          12 :   test(false),
+     295          12 :   CompDer(false),
+     296          24 :   com(false)
+     297             : {
+     298          12 :   log << "Starting PIV Constructor\n";
+     299             : 
+     300             :   {
+     301             :     // look for another PIV instance previously allocated
+     302          12 :     auto* previous=plumed.getActionSet().selectLatest<PIV*>(this);
+     303             : 
+     304             :     // Uncommenting the following line, it is possible to force
+     305             :     // a separate object per instance of the PIB object.
+     306             :     // Results are unaffected, but performance is worse.
+     307             :     // I think this is the expected behavior. GB
+     308             :     // previous=nullptr;
+     309             : 
+     310          12 :     if(!previous) {
+     311             :       // if not found, allocate the shared data struct
+     312           6 :       sharedData_unique=Tools::make_unique<SharedData>();
+     313             :       // then set the raw pointer
+     314           6 :       sharedData=sharedData_unique.get();
+     315             :     } else {
+     316             :       // if found, use the previous raw pointer
+     317           6 :       sharedData=previous->sharedData;
+     318           6 :       log << "(a previous PIV action was found)\n";
+     319             :     }
+     320             :   }
+     321             : 
+     322             :   // Precision on the real-to-integer transformation for the sorting
+     323          12 :   parse("PRECISION",Nprec);
+     324          12 :   if(Nprec<2) error("Precision must be => 2");
+     325             : 
+     326             :   // PBC
+     327          12 :   bool nopbc=!pbc;
+     328          12 :   parseFlag("NOPBC",nopbc);
+     329          12 :   pbc=!nopbc;
+     330          12 :   if(pbc) {
+     331          12 :     log << "Using Periodic Boundary Conditions\n";
+     332             :   } else  {
+     333           0 :     log << "Isolated System (NO PBC)\n";
+     334             :   }
+     335             : 
+     336             :   // SERIAL/PARALLEL
+     337          12 :   parseFlag("SERIAL",serial);
+     338          12 :   if(serial) {
+     339           0 :     log << "Serial PIV construction\n";
+     340             :   } else     {
+     341          12 :     log << "Parallel PIV construction\n";
+     342             :   }
+     343             : 
+     344             :   // Derivatives
+     345          12 :   parseFlag("DERIVATIVES",CompDer);
+     346          12 :   if(CompDer) log << "Computing Derivatives\n";
+     347             : 
+     348             :   // Timing
+     349          12 :   parseFlag("TIMER",timer);
+     350          12 :   if(timer) {
+     351           1 :     log << "Timing analysis\n";
+     352           1 :     stopwatch.start();
+     353           1 :     stopwatch.pause();
+     354             :   }
+     355             : 
+     356             :   // Test
+     357          12 :   parseFlag("TEST",test);
+     358             : 
+     359             :   // UPDATEPIV
+     360          24 :   if(keywords.exists("UPDATEPIV")) {
+     361          24 :     parse("UPDATEPIV",updatePIV);
+     362             :   }
+     363             : 
+     364             :   // Test
+     365          12 :   parseFlag("COM",com);
+     366          12 :   if(com) log << "Building PIV using COMs\n";
+     367             : 
+     368             :   // Volume Scaling
+     369          12 :   parse("VOLUME",Vol0);
+     370          12 :   if (Vol0>0) {
+     371          12 :     Svol=true;
+     372             :   }
+     373             : 
+     374             :   // PIV direct and cross blocks
+     375          12 :   bool oc=false,od=false;
+     376          12 :   parseFlag("ONLYCROSS",oc);
+     377          12 :   parseFlag("ONLYDIRECT",od);
+     378          12 :   if (oc&&od) {
+     379           0 :     error("ONLYCROSS and ONLYDIRECT are incompatible options!");
+     380             :   }
+     381          12 :   if(oc) {
+     382           4 :     direct=false;
+     383           4 :     log << "Using only CROSS-PIV blocks\n";
+     384             :   }
+     385          12 :   if(od) {
+     386           4 :     cross=false;
+     387           4 :     log << "Using only DIRECT-PIV blocks\n";
+     388             :   }
+     389             : 
+     390             :   // Atoms for PIV
+     391          12 :   parse("PIVATOMS",Natm);
+     392          12 :   std:: vector<string> atype(Natm);
+     393          12 :   parseVector("ATOMTYPES",atype);
+     394             :   //if(atype.size()!=getNumberOfArguments() && atype.size()!=0) error("not enough values for ATOMTYPES");
+     395             : 
+     396             :   // Reference PDB file
+     397          12 :   parse("REF_FILE",ref_file);
+     398          12 :   PDB mypdb;
+     399          12 :   FILE* fp=fopen(ref_file.c_str(),"r");
+     400          12 :   if (fp!=NULL) {
+     401          12 :     log<<"Opening PDB file with reference frame: "<<ref_file.c_str()<<"\n";
+     402          12 :     mypdb.readFromFilepointer(fp,usingNaturalUnits(),0.1/getUnits().getLength());
+     403          12 :     fclose (fp);
+     404             :   } else {
+     405           0 :     error("Error in reference PDB file");
+     406             :   }
+     407             : 
+     408             :   // Build COM/Atom lists of AtomNumbers (this might be done in PBC.cpp)
+     409             :   // Atomlist or Plist used to build pair lists
+     410          12 :   std:: vector<std:: vector<AtomNumber> > Plist(Natm);
+     411             :   // Atomlist used to build list of atoms for each COM
+     412          12 :   std:: vector<std:: vector<AtomNumber> > comatm(1);
+     413             :   // NLsize is the number of atoms in the pdb cell
+     414          12 :   NLsize=mypdb.getAtomNumbers().size();
+     415             :   // In the following P stands for Point (either an Atom or a COM)
+     416             :   unsigned resnum=0;
+     417             :   // Presind (array size: number of residues) contains the contains the residue number
+     418             :   //   this is because the residue numbers may not always be ordered from 1 to resnum
+     419             :   std:: vector<unsigned> Presind;
+     420             :   // Build Presind
+     421       19404 :   for (unsigned i=0; i<mypdb.getAtomNumbers().size(); i++) {
+     422       19392 :     unsigned rind=mypdb.getResidueNumber(mypdb.getAtomNumbers()[i]);
+     423             :     bool oldres=false;
+     424     7705008 :     for (unsigned j=0; j<Presind.size(); j++) {
+     425     7685616 :       if(rind==Presind[j]) {
+     426             :         oldres=true;
+     427             :       }
+     428             :     }
+     429       19392 :     if(!oldres) {
+     430        4848 :       Presind.push_back(rind);
+     431             :     }
+     432             :   }
+     433          12 :   resnum=Presind.size();
+     434             : 
+     435             :   // Pind0 is the atom/COM used in Nlists (for COM Pind0 is the first atom in the pdb belonging to that COM)
+     436             :   unsigned Pind0size;
+     437          12 :   if(com) {
+     438             :     Pind0size=resnum;
+     439             :   } else {
+     440          12 :     Pind0size=NLsize;
+     441             :   }
+     442          12 :   std:: vector<unsigned> Pind0(Pind0size);
+     443             :   // If COM resize important arrays
+     444          12 :   comatm.resize(NLsize);
+     445          12 :   if(com) {
+     446           0 :     nlcom.resize(NLsize);
+     447           0 :     compos.resize(NLsize);
+     448           0 :     fmass.resize(NLsize,0.);
+     449             :   }
+     450          12 :   log << "Total COM/Atoms: " << Natm*resnum << " \n";
+     451             :   // Build lists of Atoms/COMs for NLists
+     452             :   //   comatm filled also for non_COM calculation for analysis purposes
+     453          36 :   for (unsigned j=0; j<Natm; j++) {
+     454             :     unsigned oind;
+     455       38808 :     for (unsigned i=0; i<Pind0.size(); i++) {
+     456       38784 :       Pind0[i]=0;
+     457             :     }
+     458       38808 :     for (unsigned i=0; i<mypdb.getAtomNumbers().size(); i++) {
+     459             :       // Residue/Atom AtomNumber: used to build NL for COMS/Atoms pairs.
+     460       38784 :       AtomNumber anum=mypdb.getAtomNumbers()[i];
+     461             :       // ResidueName/Atomname associated to atom
+     462       38784 :       string rname=mypdb.getResidueName(anum);
+     463       38784 :       string aname=mypdb.getAtomName(anum);
+     464             :       // Index associated to residue/atom: used to separate COM-lists
+     465       38784 :       unsigned rind=mypdb.getResidueNumber(anum);
+     466             :       unsigned aind=anum.index();
+     467             :       // This builds lists for NL
+     468             :       string Pname;
+     469             :       unsigned Pind;
+     470       38784 :       if(com) {
+     471             :         Pname=rname;
+     472           0 :         for(unsigned l=0; l<resnum; l++) {
+     473           0 :           if(rind==Presind[l]) {
+     474             :             Pind=l;
+     475             :           }
+     476             :         }
+     477             :       } else {
+     478             :         Pname=aname;
+     479             :         Pind=aind;
+     480             :       }
+     481       38784 :       if(Pname==atype[j]) {
+     482       14544 :         if(Pind0[Pind]==0) {
+     483             :           // adding the atomnumber to the atom/COM list for pairs
+     484       14544 :           Plist[j].push_back(anum);
+     485       14544 :           Pind0[Pind]=aind+1;
+     486             :           oind=Pind;
+     487             :         }
+     488             :         // adding the atomnumber to list of atoms for every COM/Atoms
+     489       14544 :         comatm[Pind0[Pind]-1].push_back(anum);
+     490             :       }
+     491             :     }
+     492             :     // Output Lists
+     493          24 :     log << "  Groups of type  " << j << ": " << Plist[j].size() << " \n";
+     494             :     string gname;
+     495             :     unsigned gsize;
+     496          24 :     if(com) {
+     497           0 :       gname=mypdb.getResidueName(comatm[Pind0[oind]-1][0]);
+     498           0 :       gsize=comatm[Pind0[oind]-1].size();
+     499             :     } else {
+     500          48 :       gname=mypdb.getAtomName(comatm[Pind0[oind]-1][0]);
+     501             :       gsize=1;
+     502             :     }
+     503          24 :     log.printf("    %6s %3s %13s %10i %6s\n", "type  ", gname.c_str(),"   containing ",gsize," atoms");
+     504             :   }
+     505             : 
+     506             :   // This is to build the list with all the atoms
+     507             :   std:: vector<AtomNumber> listall;
+     508       19404 :   for (unsigned i=0; i<mypdb.getAtomNumbers().size(); i++) {
+     509       19392 :     listall.push_back(mypdb.getAtomNumbers()[i]);
+     510             :   }
+     511             : 
+     512             :   // PIV blocks and Neighbour Lists
+     513          12 :   Nlist=0;
+     514             :   // Direct adds the A-A ad B-B blocks (N)
+     515          12 :   if(direct) {
+     516           8 :     Nlist=Nlist+unsigned(Natm);
+     517             :   }
+     518             :   // Cross adds the A-B blocks (N*(N-1)/2)
+     519          12 :   if(cross) {
+     520           8 :     Nlist=Nlist+unsigned(double(Natm*(Natm-1))/2.);
+     521             :   }
+     522             :   // Resize vectors according to Nlist
+     523          12 :   rPIV.resize(Nlist);
+     524             : 
+     525             :   // PIV scaled option
+     526          12 :   scaling.resize(Nlist);
+     527          36 :   for(unsigned j=0; j<Nlist; j++) {
+     528          24 :     scaling[j]=1.;
+     529             :   }
+     530          24 :   if(keywords.exists("SFACTOR")) {
+     531          24 :     parseVector("SFACTOR",scaling);
+     532             :     //if(scaling.size()!=getNumberOfArguments() && scaling.size()!=0) error("not enough values for SFACTOR");
+     533             :   }
+     534             :   // Neighbour Lists option
+     535          12 :   parseFlag("NLIST",doneigh);
+     536          12 :   nl.resize(Nlist);
+     537          12 :   nl_skin.resize(Nlist);
+     538          12 :   if(doneigh) {
+     539          12 :     std:: vector<double> nl_cut(Nlist,0.);
+     540          12 :     std:: vector<int> nl_st(Nlist,0);
+     541          12 :     parseVector("NL_CUTOFF",nl_cut);
+     542             :     //if(nl_cut.size()!=getNumberOfArguments() && nl_cut.size()!=0) error("not enough values for NL_CUTOFF");
+     543          12 :     parseVector("NL_STRIDE",nl_st);
+     544             :     //if(nl_st.size()!=getNumberOfArguments() && nl_st.size()!=0) error("not enough values for NL_STRIDE");
+     545          12 :     parseVector("NL_SKIN",nl_skin);
+     546             :     //if(nl_skin.size()!=getNumberOfArguments() && nl_skin.size()!=0) error("not enough values for NL_SKIN");
+     547          36 :     for (unsigned j=0; j<Nlist; j++) {
+     548          24 :       if(nl_cut[j]<=0.0) error("NL_CUTOFF should be explicitly specified and positive");
+     549          24 :       if(nl_st[j]<=0) error("NL_STRIDE should be explicitly specified and positive");
+     550          24 :       if(nl_skin[j]<=0.) error("NL_SKIN should be explicitly specified and positive");
+     551          24 :       nl_cut[j]=nl_cut[j]+nl_skin[j];
+     552             :     }
+     553          12 :     log << "Creating Neighbor Lists \n";
+     554             :     // WARNING: is nl_cut meaningful here?
+     555          24 :     nlall= Tools::make_unique<NeighborList>(listall,true,pbc,getPbc(),comm,nl_cut[0],nl_st[0]);
+     556          12 :     if(com) {
+     557             :       //Build lists of Atoms for every COM
+     558           0 :       for (unsigned i=0; i<compos.size(); i++) {
+     559             :         // WARNING: is nl_cut meaningful here?
+     560           0 :         nlcom[i] = Tools::make_unique<NeighborList>(comatm[i],true,pbc,getPbc(),comm,nl_cut[0],nl_st[0]);
+     561             :       }
+     562             :     }
+     563             :     unsigned ncnt=0;
+     564             :     // Direct blocks AA, BB, CC, ...
+     565          12 :     if(direct) {
+     566          24 :       for (unsigned j=0; j<Natm; j++) {
+     567          16 :         nl[ncnt]= Tools::make_unique<NeighborList>(Plist[j],true,pbc,getPbc(),comm,nl_cut[j],nl_st[j]);
+     568          16 :         ncnt+=1;
+     569             :       }
+     570             :     }
+     571             :     // Cross blocks AB, AC, BC, ...
+     572          12 :     if(cross) {
+     573          24 :       for (unsigned j=0; j<Natm; j++) {
+     574          24 :         for (unsigned i=j+1; i<Natm; i++) {
+     575          16 :           nl[ncnt]= Tools::make_unique<NeighborList>(Plist[i],Plist[j],true,false,pbc,getPbc(),comm,nl_cut[ncnt],nl_st[ncnt]);
+     576           8 :           ncnt+=1;
+     577             :         }
+     578             :       }
+     579             :     }
+     580             :   } else {
+     581           0 :     log << "WARNING: Neighbor List not activated this has not been tested!!  \n";
+     582           0 :     nlall= Tools::make_unique<NeighborList>(listall,true,pbc,getPbc(),comm);
+     583           0 :     for (unsigned j=0; j<Nlist; j++) {
+     584           0 :       nl[j]= Tools::make_unique<NeighborList>(Plist[j],Plist[j],true,true,pbc,getPbc(),comm);
+     585             :     }
+     586             :   }
+     587             :   // Output Nlist
+     588          12 :   log << "Total Nlists: " << Nlist << " \n";
+     589          36 :   for (unsigned j=0; j<Nlist; j++) {
+     590          24 :     log << "  list " << j+1 << "   size " << nl[j]->size() << " \n";
+     591             :   }
+     592             :   // Calculate COM masses once and for all from lists
+     593          12 :   if(com) {
+     594           0 :     for(unsigned j=0; j<compos.size(); j++) {
+     595             :       double commass=0.;
+     596           0 :       for(unsigned i=0; i<nlcom[j]->getFullAtomList().size(); i++) {
+     597           0 :         unsigned andx=nlcom[j]->getFullAtomList()[i].index();
+     598           0 :         commass+=mypdb.getOccupancy()[andx];
+     599             :       }
+     600           0 :       for(unsigned i=0; i<nlcom[j]->getFullAtomList().size(); i++) {
+     601           0 :         unsigned andx=nlcom[j]->getFullAtomList()[i].index();
+     602           0 :         if(commass>0.) {
+     603           0 :           fmass[andx]=mypdb.getOccupancy()[andx]/commass;
+     604             :         } else {
+     605           0 :           fmass[andx]=1.;
+     606             :         }
+     607             :       }
+     608             :     }
+     609             :   }
+     610             : 
+     611             :   // Sorting
+     612          12 :   dosort.resize(Nlist);
+     613          12 :   std:: vector<int> ynsort(Nlist);
+     614          12 :   parseVector("SORT",ynsort);
+     615          36 :   for (unsigned i=0; i<Nlist; i++) {
+     616          24 :     if(ynsort[i]==0||CompDer) {
+     617             :       dosort[i]=false;
+     618             :     } else {
+     619             :       dosort[i]=true;
+     620             :     }
+     621             :   }
+     622             : 
+     623             :   //build box vectors and correct for pbc
+     624          12 :   log << "Building the box from PDB data ... \n";
+     625          12 :   Tensor Box=mypdb.getBoxVec();
+     626          12 :   log << "  Done! A,B,C vectors in Cartesian space:  \n";
+     627          12 :   log.printf("  A:  %12.6f%12.6f%12.6f\n", Box[0][0],Box[0][1],Box[0][2]);
+     628          12 :   log.printf("  B:  %12.6f%12.6f%12.6f\n", Box[1][0],Box[1][1],Box[1][2]);
+     629          12 :   log.printf("  C:  %12.6f%12.6f%12.6f\n", Box[2][0],Box[2][1],Box[2][2]);
+     630          12 :   log << "Changing the PBC according to the new box \n";
+     631          12 :   Pbc mypbc;
+     632          12 :   mypbc.setBox(Box);
+     633          12 :   log << "The box volume is " << mypbc.getBox().determinant() << " \n";
+     634             : 
+     635             :   //Compute scaling factor
+     636          12 :   if(Svol) {
+     637          12 :     Fvol=cbrt(Vol0/mypbc.getBox().determinant());
+     638          12 :     log << "Scaling atom distances by  " << Fvol << " \n";
+     639             :   } else {
+     640           0 :     log << "Using unscaled atom distances \n";
+     641             :   }
+     642             : 
+     643          12 :   r00.resize(Nlist);
+     644          12 :   sw.resize(Nlist);
+     645          36 :   for (unsigned j=0; j<Nlist; j++) {
+     646          48 :     if( !parseNumbered( "SWITCH", j+1, sw[j] ) ) break;
+     647             :   }
+     648          12 :   if(CompDer) {
+     649             :     // Set switching function parameters here only if computing derivatives
+     650             :     //   now set at the beginning of the dynamics to solve the r0 issue
+     651           6 :     log << "Switching Function Parameters \n";
+     652           6 :     sfs.resize(Nlist);
+     653             :     std::string errors;
+     654          18 :     for (unsigned j=0; j<Nlist; j++) {
+     655          12 :       if(Svol) {
+     656             :         double r0;
+     657             :         std::string old_r0;
+     658          12 :         vector<string> data=Tools::getWords(sw[j]);
+     659             :         data.erase(data.begin());
+     660          12 :         Tools::parse(data,"R_0",old_r0);
+     661          12 :         Tools::convert(old_r0,r0);
+     662          12 :         r0*=Fvol;
+     663          12 :         std::string new_r0; Tools::convert(r0,new_r0);
+     664          12 :         std::size_t pos = sw[j].find("R_0");
+     665          12 :         sw[j].replace(pos+4,old_r0.size(),new_r0);
+     666          12 :       }
+     667          12 :       sfs[j].set(sw[j],errors);
+     668             :       std::string num;
+     669          12 :       Tools::convert(j+1, num);
+     670          12 :       if( errors.length()!=0 ) error("problem reading SWITCH" + num + " keyword : " + errors );
+     671          12 :       r00[j]=sfs[j].get_r0();
+     672          12 :       log << "  Swf: " << j << "  r0=" << (sfs[j].description()).c_str() << " \n";
+     673             :     }
+     674             :   }
+     675             : 
+     676             :   // build COMs from positions if requested
+     677          12 :   if(com) {
+     678           0 :     for(unsigned j=0; j<compos.size(); j++) {
+     679           0 :       compos[j][0]=0.;
+     680           0 :       compos[j][1]=0.;
+     681           0 :       compos[j][2]=0.;
+     682           0 :       for(unsigned i=0; i<nlcom[j]->getFullAtomList().size(); i++) {
+     683           0 :         unsigned andx=nlcom[j]->getFullAtomList()[i].index();
+     684           0 :         compos[j]+=fmass[andx]*mypdb.getPositions()[andx];
+     685             :       }
+     686             :     }
+     687             :   }
+     688             :   // build the rPIV distances (transformation and sorting is done afterwards)
+     689          12 :   if(CompDer) {
+     690           6 :     log << "  PIV  |  block   |     Size      |     Zeros     |     Ones      |" << " \n";
+     691             :   }
+     692          36 :   for(unsigned j=0; j<Nlist; j++) {
+     693    11516328 :     for(unsigned i=0; i<nl[j]->size(); i++) {
+     694    11516304 :       unsigned i0=(nl[j]->getClosePairAtomNumber(i).first).index();
+     695    11516304 :       unsigned i1=(nl[j]->getClosePairAtomNumber(i).second).index();
+     696             :       //calculate/get COM position of centers i0 and i1
+     697    11516304 :       Vector Pos0,Pos1;
+     698    11516304 :       if(com) {
+     699             :         //if(pbc) makeWhole();
+     700           0 :         Pos0=compos[i0];
+     701           0 :         Pos1=compos[i1];
+     702             :       } else {
+     703    11516304 :         Pos0=mypdb.getPositions()[i0];
+     704    11516304 :         Pos1=mypdb.getPositions()[i1];
+     705             :       }
+     706    11516304 :       Vector ddist;
+     707    11516304 :       if(pbc) {
+     708    11516304 :         ddist=mypbc.distance(Pos0,Pos1);
+     709             :       } else {
+     710           0 :         ddist=delta(Pos0,Pos1);
+     711             :       }
+     712    11516304 :       double df=0.;
+     713             :       // Transformation and sorting done at the first timestep to solve the r0 definition issue
+     714    11516304 :       if(CompDer) {
+     715        1104 :         rPIV[j].push_back(sfs[j].calculate(ddist.modulo()*Fvol, df));
+     716             :       } else {
+     717    11515200 :         rPIV[j].push_back(ddist.modulo()*Fvol);
+     718             :       }
+     719             :     }
+     720          24 :     if(CompDer) {
+     721          12 :       if(dosort[j]) {
+     722           0 :         std::sort(rPIV[j].begin(),rPIV[j].end());
+     723             :       }
+     724             :       int lmt0=0;
+     725             :       int lmt1=0;
+     726        1116 :       for(unsigned i=0; i<rPIV[j].size(); i++) {
+     727        1104 :         if(int(rPIV[j][i]*double(Nprec-1))==0) {
+     728           0 :           lmt0+=1;
+     729             :         }
+     730        1104 :         if(int(rPIV[j][i]*double(Nprec-1))==1) {
+     731           0 :           lmt1+=1;
+     732             :         }
+     733             :       }
+     734          12 :       log.printf("       |%10i|%15zu|%15i|%15i|\n", j, rPIV[j].size(), lmt0, lmt1);
+     735             :     }
+     736             :   }
+     737             : 
+     738          12 :   checkRead();
+     739             :   // From the plumed manual on how to build-up a new Colvar
+     740          24 :   addValueWithDerivatives();
+     741          12 :   requestAtoms(nlall->getFullAtomList());
+     742          12 :   setNotPeriodic();
+     743             :   // getValue()->setPeridodicity(false);
+     744             :   // set size of derivative vector
+     745          12 :   m_deriv.resize(getNumberOfAtoms());
+     746          12 : }
+     747             : 
+     748         327 : void PIV::calculate()
+     749             : {
+     750             : 
+     751             :   // Local variables
+     752             : 
+     753         327 :   if(sharedData_unique) {
+     754             :     // This is executed by the first PIV instance.
+     755             :     // We initialize variables with the correct Nlist.
+     756         321 :     sharedData_unique->prev_pos.resize(Nlist);
+     757         321 :     sharedData_unique->cPIV.resize(Nlist);
+     758         321 :     sharedData_unique->Atom0.resize(Nlist);
+     759         321 :     sharedData_unique->Atom1.resize(Nlist);
+     760             :   }
+     761             : 
+     762             :   // create references to minimize the impact of the code below
+     763         327 :   auto & prev_stp(sharedData->prev_stp);
+     764             :   auto & init_stp(sharedData->init_stp);
+     765             :   auto & prev_pos(sharedData->prev_pos);
+     766             :   auto & cPIV(sharedData->cPIV);
+     767             :   auto & Atom0(sharedData->Atom0);
+     768             :   auto & Atom1(sharedData->Atom1);
+     769             : 
+     770         327 :   std:: vector<std:: vector<int> > A0(Nprec);
+     771         327 :   std:: vector<std:: vector<int> > A1(Nprec);
+     772             :   size_t stride=1;
+     773             :   unsigned rank=0;
+     774             : 
+     775         327 :   if(!serial) {
+     776         327 :     stride=comm.Get_size();
+     777         327 :     rank=comm.Get_rank();
+     778             :   } else {
+     779             :     stride=1;
+     780             :     rank=0;
+     781             :   }
+     782             : 
+     783             :   // Transform (and sort) the rPIV before starting the dynamics
+     784         327 :   if (((prev_stp==-1) || (init_stp==1)) &&!CompDer) {
+     785           6 :     if(prev_stp!=-1) {init_stp=0;}
+     786             :     // Calculate the volume scaling factor
+     787           6 :     if(Svol) {
+     788           6 :       Fvol=cbrt(Vol0/getBox().determinant());
+     789             :     }
+     790             :     //Set switching function parameters
+     791           6 :     log << "\n";
+     792           6 :     log << "REFERENCE PDB # " << prev_stp+2 << " \n";
+     793             :     // Set switching function parameters here only if computing derivatives
+     794             :     //   now set at the beginning of the dynamics to solve the r0 issue
+     795           6 :     log << "Switching Function Parameters \n";
+     796           6 :     sfs.resize(Nlist);
+     797             :     std::string errors;
+     798          18 :     for (unsigned j=0; j<Nlist; j++) {
+     799          12 :       if(Svol) {
+     800             :         double r0;
+     801             :         std::string old_r0;
+     802          12 :         vector<string> data=Tools::getWords(sw[j]);
+     803             :         data.erase(data.begin());
+     804          12 :         Tools::parse(data,"R_0",old_r0);
+     805          12 :         Tools::convert(old_r0,r0);
+     806          12 :         r0*=Fvol;
+     807          12 :         std::string new_r0; Tools::convert(r0,new_r0);
+     808          12 :         std::size_t pos = sw[j].find("R_0");
+     809          12 :         sw[j].replace(pos+4,old_r0.size(),new_r0);
+     810          12 :       }
+     811          12 :       sfs[j].set(sw[j],errors);
+     812             :       std::string num;
+     813          12 :       Tools::convert(j+1, num);
+     814          12 :       if( errors.length()!=0 ) error("problem reading SWITCH" + num + " keyword : " + errors );
+     815          12 :       r00[j]=sfs[j].get_r0();
+     816          12 :       log << "  Swf: " << j << "  r0=" << (sfs[j].description()).c_str() << " \n";
+     817             :     }
+     818             :     //Transform and sort
+     819           6 :     log << "Building Reference PIV Vector \n";
+     820           6 :     log << "  PIV  |  block   |     Size      |     Zeros     |     Ones      |" << " \n";
+     821           6 :     double df=0.;
+     822          18 :     for (unsigned j=0; j<Nlist; j++) {
+     823    11515212 :       for (unsigned i=0; i<rPIV[j].size(); i++) {
+     824    11515200 :         rPIV[j][i]=sfs[j].calculate(rPIV[j][i], df);
+     825             :       }
+     826          12 :       if(dosort[j]) {
+     827          12 :         std::sort(rPIV[j].begin(),rPIV[j].end());
+     828             :       }
+     829             :       int lmt0=0;
+     830             :       int lmt1=0;
+     831    11515212 :       for(unsigned i=0; i<rPIV[j].size(); i++) {
+     832    11515200 :         if(int(rPIV[j][i]*double(Nprec-1))==0) {
+     833          26 :           lmt0+=1;
+     834             :         }
+     835    11515200 :         if(int(rPIV[j][i]*double(Nprec-1))==1) {
+     836       63358 :           lmt1+=1;
+     837             :         }
+     838             :       }
+     839          12 :       log.printf("       |%10i|%15zu|%15i|%15i|\n", j, rPIV[j].size(), lmt0, lmt1);
+     840             :     }
+     841           6 :     log << "\n";
+     842             :   }
+     843             :   // Do the sorting only once per timestep to avoid building the PIV N times for N rPIV PDB structures!
+     844         327 :   if ((getStep()>prev_stp&&getStep()%updatePIV==0)||CompDer) {
+     845         324 :     if (CompDer) log << " Step " << getStep() << "  Computing Derivatives NON-SORTED PIV \n";
+     846             :     //
+     847             :     // build COMs from positions if requested
+     848         324 :     if(com) {
+     849           0 :       if(pbc) makeWhole();
+     850           0 :       for(unsigned j=0; j<compos.size(); j++) {
+     851           0 :         compos[j][0]=0.;
+     852           0 :         compos[j][1]=0.;
+     853           0 :         compos[j][2]=0.;
+     854           0 :         for(unsigned i=0; i<nlcom[j]->getFullAtomList().size(); i++) {
+     855           0 :           unsigned andx=nlcom[j]->getFullAtomList()[i].index();
+     856           0 :           compos[j]+=fmass[andx]*getPosition(andx);
+     857             :         }
+     858             :       }
+     859             :     }
+     860             :     // update neighbor lists when an atom moves out of the Neighbor list skin
+     861         324 :     if (doneigh) {
+     862             :       bool doupdate=false;
+     863             :       // For the first step build previous positions = actual positions
+     864         324 :       if (prev_stp==-1) {
+     865           6 :         bool docom=com;
+     866          18 :         for (unsigned j=0; j<Nlist; j++) {
+     867        9708 :           for (unsigned i=0; i<nl[j]->getFullAtomList().size(); i++) {
+     868        9696 :             Vector Pos;
+     869        9696 :             if(docom) {
+     870           0 :               Pos=compos[i];
+     871             :             } else {
+     872        9696 :               Pos=getPosition(nl[j]->getFullAtomList()[i].index());
+     873             :             }
+     874        9696 :             prev_pos[j].push_back(Pos);
+     875             :           }
+     876             :         }
+     877             :         doupdate=true;
+     878             :       }
+     879             :       // Decide whether to update lists based on atom displacement, every stride
+     880         324 :       std:: vector<std:: vector<Vector> > tmp_pos(Nlist);
+     881         324 :       if (getStep() % nlall->getStride() ==0) {
+     882         324 :         bool docom=com;
+     883         972 :         for (unsigned j=0; j<Nlist; j++) {
+     884       20520 :           for (unsigned i=0; i<nl[j]->getFullAtomList().size(); i++) {
+     885       19872 :             Vector Pos;
+     886       19872 :             if(docom) {
+     887           0 :               Pos=compos[i];
+     888             :             } else {
+     889       19872 :               Pos=getPosition(nl[j]->getFullAtomList()[i].index());
+     890             :             }
+     891       19872 :             tmp_pos[j].push_back(Pos);
+     892       19872 :             if (pbcDistance(tmp_pos[j][i],prev_pos[j][i]).modulo()>=nl_skin[j]) {
+     893             :               doupdate=true;
+     894             :             }
+     895             :           }
+     896             :         }
+     897             :       }
+     898             :       // Update Nlists if needed
+     899         324 :       if (doupdate==true) {
+     900          18 :         for (unsigned j=0; j<Nlist; j++) {
+     901        9708 :           for (unsigned i=0; i<nl[j]->getFullAtomList().size(); i++) {
+     902        9696 :             prev_pos[j][i]=tmp_pos[j][i];
+     903             :           }
+     904          12 :           nl[j]->update(prev_pos[j]);
+     905          12 :           log << " Step " << getStep() << "  Neighbour lists updated " << nl[j]->size() << " \n";
+     906             :         }
+     907             :       }
+     908         324 :     }
+     909             :     // Calculate the volume scaling factor
+     910         324 :     if(Svol) {
+     911         324 :       Fvol=cbrt(Vol0/getBox().determinant());
+     912             :     }
+     913         324 :     Vector ddist;
+     914             :     // Global to local variables
+     915         324 :     bool doserial=serial;
+     916             :     // Build "Nlist" PIV blocks
+     917         972 :     for(unsigned j=0; j<Nlist; j++) {
+     918         648 :       if(dosort[j]) {
+     919             :         // from global to local variables to speedup the for loop with if statements
+     920           6 :         bool docom=com;
+     921           6 :         bool dopbc=pbc;
+     922             :         // Vectors collecting occupancies: OrdVec one rank, OrdVecAll all ranks
+     923           6 :         std:: vector<int> OrdVec(Nprec,0);
+     924           6 :         cPIV[j].resize(0);
+     925           6 :         Atom0[j].resize(0);
+     926           6 :         Atom1[j].resize(0);
+     927             :         // Building distances for the PIV vector at time t
+     928           6 :         if(timer) stopwatch.start("1 Build cPIV");
+     929     5757606 :         for(unsigned i=rank; i<nl[j]->size(); i+=stride) {
+     930     5757600 :           unsigned i0=(nl[j]->getClosePairAtomNumber(i).first).index();
+     931     5757600 :           unsigned i1=(nl[j]->getClosePairAtomNumber(i).second).index();
+     932     5757600 :           Vector Pos0,Pos1;
+     933     5757600 :           if(docom) {
+     934           0 :             Pos0=compos[i0];
+     935           0 :             Pos1=compos[i1];
+     936             :           } else {
+     937     5757600 :             Pos0=getPosition(i0);
+     938     5757600 :             Pos1=getPosition(i1);
+     939             :           }
+     940     5757600 :           if(dopbc) {
+     941     5757600 :             ddist=pbcDistance(Pos0,Pos1);
+     942             :           } else {
+     943           0 :             ddist=delta(Pos0,Pos1);
+     944             :           }
+     945     5757600 :           double df=0.;
+     946             :           //Integer sorting ... faster!
+     947             :           //Transforming distances with the Switching function + real to integer transformation
+     948     5757600 :           int Vint=int(sfs[j].calculate(ddist.modulo()*Fvol, df)*double(Nprec-1)+0.5);
+     949             :           //Integer transformed distance values as index of the Ordering Vector OrdVec
+     950     5757600 :           OrdVec[Vint]+=1;
+     951             :           //Keeps track of atom indices for force and virial calculations
+     952     5757600 :           A0[Vint].push_back(i0);
+     953     5757600 :           A1[Vint].push_back(i1);
+     954             :         }
+     955           6 :         if(timer) stopwatch.stop("1 Build cPIV");
+     956           6 :         if(timer) stopwatch.start("2 Sort cPIV");
+     957           6 :         if(!doserial && comm.initialized()) {
+     958             :           // Vectors keeping track of the dimension and the starting-position of the rank-specific pair vector in the big pair vector.
+     959           0 :           std:: vector<int> Vdim(stride,0);
+     960           0 :           std:: vector<int> Vpos(stride,0);
+     961             :           // Vectors collecting occupancies: OrdVec one rank, OrdVecAll all ranks
+     962           0 :           std:: vector<int> OrdVecAll(stride*Nprec);
+     963             :           // Big vectors containing all Atom indexes for every occupancy (Atom0O(Nprec,n) and Atom1O(Nprec,n) matrices in one vector)
+     964             :           std:: vector<int> Atom0F;
+     965             :           std:: vector<int> Atom1F;
+     966             :           // Vector used to reconstruct arrays
+     967           0 :           std:: vector<unsigned> k(stride,0);
+     968             :           // Zeros might be many, this slows down a lot due to MPI communication
+     969             :           // Avoid passing the zeros (i=1) for atom indices
+     970           0 :           for(unsigned i=1; i<Nprec; i++) {
+     971             :             // Building long vectors with all atom indexes for occupancies ordered from i=1 to i=Nprec-1
+     972             :             // Can this be avoided ???
+     973           0 :             Atom0F.insert(Atom0F.end(),A0[i].begin(),A0[i].end());
+     974           0 :             Atom1F.insert(Atom1F.end(),A1[i].begin(),A1[i].end());
+     975           0 :             A0[i].resize(0);
+     976           0 :             A1[i].resize(0);
+     977             :           }
+     978             :           // Resize partial arrays to fill up for the next PIV block
+     979           0 :           A0[0].resize(0);
+     980           0 :           A1[0].resize(0);
+     981           0 :           A0[Nprec-1].resize(0);
+     982           0 :           A1[Nprec-1].resize(0);
+     983             :           // Avoid passing the zeros (i=1) for atom indices
+     984           0 :           OrdVec[0]=0;
+     985           0 :           OrdVec[Nprec-1]=0;
+     986             : 
+     987             :           // Wait for all ranks before communication of Vectors
+     988           0 :           comm.Barrier();
+     989             : 
+     990             :           // pass the array sizes before passing the arrays
+     991           0 :           int dim=Atom0F.size();
+     992             :           // Vdim and Vpos keep track of the dimension and the starting-position of the rank-specific pair vector in the big pair vector.
+     993           0 :           comm.Allgather(&dim,1,&Vdim[0],1);
+     994             : 
+     995             :           // TO BE IMPROVED: the following may be done by the rank 0 (now every rank does it)
+     996             :           int Fdim=0;
+     997           0 :           for(unsigned i=1; i<stride; i++) {
+     998           0 :             Vpos[i]=Vpos[i-1]+Vdim[i-1];
+     999           0 :             Fdim+=Vdim[i];
+    1000             :           }
+    1001           0 :           Fdim+=Vdim[0];
+    1002             :           // build big vectors for atom pairs on all ranks for all ranks
+    1003           0 :           std:: vector<int> Atom0FAll(Fdim);
+    1004           0 :           std:: vector<int> Atom1FAll(Fdim);
+    1005             :           // TO BE IMPROVED: Allgathers may be substituted by gathers by proc 0
+    1006             :           //   Moreover vectors are gathered head-to-tail and assembled later-on in a serial step.
+    1007             :           // Gather the full Ordering Vector (occupancies). This is what we need to build the PIV
+    1008           0 :           comm.Allgather(&OrdVec[0],Nprec,&OrdVecAll[0],Nprec);
+    1009             :           // Gather the vectors of atom pairs to keep track of the idexes for the forces
+    1010           0 :           comm.Allgatherv(Atom0F.data(),Atom0F.size(),&Atom0FAll[0],&Vdim[0],&Vpos[0]);
+    1011           0 :           comm.Allgatherv(Atom1F.data(),Atom1F.size(),&Atom1FAll[0],&Vdim[0],&Vpos[0]);
+    1012             : 
+    1013             :           // Reconstruct the full vectors from collections of Allgathered parts (this is a serial step)
+    1014             :           // This is the tricky serial step, to assemble together PIV and atom-pair info from head-tail big vectors
+    1015             :           // Loop before on l and then on i would be better but the allgather should be modified
+    1016             :           // Loop on blocks
+    1017             :           //for(unsigned m=0;m<Nlist;m++) {
+    1018             :           // Loop on Ordering Vector size excluding zeros (i=1)
+    1019           0 :           if(timer) stopwatch.stop("2 Sort cPIV");
+    1020           0 :           if(timer) stopwatch.start("3 Reconstruct cPIV");
+    1021           0 :           for(unsigned i=1; i<Nprec; i++) {
+    1022             :             // Loop on the ranks
+    1023           0 :             for(unsigned l=0; l<stride; l++) {
+    1024             :               // Loop on the number of head-to-tail pieces
+    1025           0 :               for(unsigned m=0; m<OrdVecAll[i+l*Nprec]; m++) {
+    1026             :                 // cPIV is the current PIV at time t
+    1027           0 :                 cPIV[j].push_back(double(i)/double(Nprec-1));
+    1028           0 :                 Atom0[j].push_back(Atom0FAll[k[l]+Vpos[l]]);
+    1029           0 :                 Atom1[j].push_back(Atom1FAll[k[l]+Vpos[l]]);
+    1030           0 :                 k[l]+=1;
+    1031             :               }
+    1032             :             }
+    1033             :           }
+    1034           0 :           if(timer) stopwatch.stop("3 Reconstruct cPIV");
+    1035             :         } else {
+    1036     6000000 :           for(unsigned i=1; i<Nprec; i++) {
+    1037    11757594 :             for(unsigned m=0; m<OrdVec[i]; m++) {
+    1038     5757600 :               cPIV[j].push_back(double(i)/double(Nprec-1));
+    1039     5757600 :               Atom0[j].push_back(A0[i][m]);
+    1040     5757600 :               Atom1[j].push_back(A1[i][m]);
+    1041             :             }
+    1042             :           }
+    1043             :         }
+    1044             :       }
+    1045             :     }
+    1046             :   }
+    1047         327 :   Vector distance;
+    1048         327 :   double dfunc=0.;
+    1049             :   // Calculate volume scaling factor
+    1050         327 :   if(Svol) {
+    1051         327 :     Fvol=cbrt(Vol0/getBox().determinant());
+    1052             :   }
+    1053             : 
+    1054             :   // This test may be run by specifying the TEST keyword as input, it pritnts rPIV and cPIV and quits
+    1055         327 :   if(test) {
+    1056             :     unsigned limit=0;
+    1057           0 :     for(unsigned j=0; j<Nlist; j++) {
+    1058           0 :       if(dosort[j]) {
+    1059           0 :         limit = cPIV[j].size();
+    1060             :       } else {
+    1061           0 :         limit = rPIV[j].size();
+    1062             :       }
+    1063           0 :       log.printf("PIV Block:  %6i %12s %6i \n", j, "      Size:", limit);
+    1064           0 :       log.printf("%6s%6s%12s%12s%36s\n","     i","     j", "    c-PIV   ","    r-PIV   ","   i-j distance vector       ");
+    1065           0 :       for(unsigned i=0; i<limit; i++) {
+    1066             :         unsigned i0=0;
+    1067             :         unsigned i1=0;
+    1068           0 :         if(dosort[j]) {
+    1069           0 :           i0=Atom0[j][i];
+    1070           0 :           i1=Atom1[j][i];
+    1071             :         } else {
+    1072           0 :           i0=(nl[j]->getClosePairAtomNumber(i).first).index();
+    1073           0 :           i1=(nl[j]->getClosePairAtomNumber(i).second).index();
+    1074             :         }
+    1075           0 :         Vector Pos0,Pos1;
+    1076           0 :         if(com) {
+    1077           0 :           Pos0=compos[i0];
+    1078           0 :           Pos1=compos[i1];
+    1079             :         } else {
+    1080           0 :           Pos0=getPosition(i0);
+    1081           0 :           Pos1=getPosition(i1);
+    1082             :         }
+    1083           0 :         if(pbc) {
+    1084           0 :           distance=pbcDistance(Pos0,Pos1);
+    1085             :         } else {
+    1086           0 :           distance=delta(Pos0,Pos1);
+    1087             :         }
+    1088           0 :         dfunc=0.;
+    1089             :         double cP,rP;
+    1090           0 :         if(dosort[j]) {
+    1091           0 :           cP = cPIV[j][i];
+    1092           0 :           rP = rPIV[j][rPIV[j].size()-cPIV[j].size()+i];
+    1093             :         } else {
+    1094           0 :           double dm=distance.modulo();
+    1095           0 :           cP = sfs[j].calculate(dm*Fvol, dfunc);
+    1096           0 :           rP = rPIV[j][i];
+    1097             :         }
+    1098           0 :         log.printf("%6i%6i%12.6f%12.6f%12.6f%12.6f%12.6f\n",i0,i1,cP,rP,distance[0],distance[1],distance[2]);
+    1099             :       }
+    1100             :     }
+    1101           0 :     log.printf("This was a test, now exit \n");
+    1102           0 :     exit();
+    1103             :   }
+    1104             : 
+    1105         327 :   if(timer) stopwatch.start("4 Build For Derivatives");
+    1106             :   // non-global variables Nder and Scalevol defined to speedup if structures in cycles
+    1107         327 :   bool Nder=CompDer;
+    1108         327 :   bool Scalevol=Svol;
+    1109         327 :   if(getStep()%updatePIV==0) {
+    1110             :     // set to zero PIVdistance, derivatives and virial when they are calculated
+    1111       29799 :     for(unsigned j=0; j<m_deriv.size(); j++) {
+    1112      117888 :       for(unsigned k=0; k<3; k++) {m_deriv[j][k]=0.;}
+    1113             :     }
+    1114        1308 :     for(unsigned j=0; j<3; j++) {
+    1115        3924 :       for(unsigned k=0; k<3; k++) {
+    1116        2943 :         m_virial[j][k]=0.;
+    1117             :       }
+    1118             :     }
+    1119         327 :     m_PIVdistance=0.;
+    1120             :     // Re-compute atomic distances for derivatives and compute PIV-PIV distance
+    1121         981 :     for(unsigned j=0; j<Nlist; j++) {
+    1122             :       unsigned limit=0;
+    1123             :       // dosorting definition is to speedup if structure in cycles with non-global variables
+    1124         654 :       bool dosorting=dosort[j];
+    1125         654 :       bool docom=com;
+    1126         654 :       bool dopbc=pbc;
+    1127         654 :       if(dosorting) {
+    1128          12 :         limit = cPIV[j].size();
+    1129             :       } else {
+    1130         642 :         limit = rPIV[j].size();
+    1131             :       }
+    1132    11574918 :       for(unsigned i=rank; i<limit; i+=stride) {
+    1133             :         unsigned i0=0;
+    1134             :         unsigned i1=0;
+    1135    11574264 :         if(dosorting) {
+    1136    11515200 :           i0=Atom0[j][i];
+    1137    11515200 :           i1=Atom1[j][i];
+    1138             :         } else {
+    1139       59064 :           i0=(nl[j]->getClosePairAtomNumber(i).first).index();
+    1140       59064 :           i1=(nl[j]->getClosePairAtomNumber(i).second).index();
+    1141             :         }
+    1142    11574264 :         Vector Pos0,Pos1;
+    1143    11574264 :         if(docom) {
+    1144           0 :           Pos0=compos[i0];
+    1145           0 :           Pos1=compos[i1];
+    1146             :         } else {
+    1147    11574264 :           Pos0=getPosition(i0);
+    1148    11574264 :           Pos1=getPosition(i1);
+    1149             :         }
+    1150    11574264 :         if(dopbc) {
+    1151    11574264 :           distance=pbcDistance(Pos0,Pos1);
+    1152             :         } else {
+    1153           0 :           distance=delta(Pos0,Pos1);
+    1154             :         }
+    1155    11574264 :         dfunc=0.;
+    1156             :         // this is needed for dfunc and dervatives
+    1157    11574264 :         double dm=distance.modulo();
+    1158    11574264 :         double tPIV = sfs[j].calculate(dm*Fvol, dfunc);
+    1159             :         // PIV distance
+    1160             :         double coord=0.;
+    1161    11574264 :         if(!dosorting||Nder) {
+    1162       59064 :           coord = tPIV - rPIV[j][i];
+    1163             :         } else {
+    1164    11515200 :           coord = cPIV[j][i] - rPIV[j][rPIV[j].size()-cPIV[j].size()+i];
+    1165             :         }
+    1166             :         // Calculate derivatives, virial, and variable=sum_j (scaling[j] *(cPIV-rPIV)_j^2)
+    1167             :         // WARNING: dfunc=dswf/(Fvol*dm)  (this may change in future Plumed versions)
+    1168    11574264 :         double tmp = 2.*scaling[j]*coord*Fvol*Fvol*dfunc;
+    1169    11574264 :         Vector tmpder = tmp*distance;
+    1170             :         // 0.5*(x_i-x_k)*f_ik         (force on atom k due to atom i)
+    1171    11574264 :         if(docom) {
+    1172           0 :           Vector dist;
+    1173           0 :           for(unsigned k=0; k<nlcom[i0]->getFullAtomList().size(); k++) {
+    1174           0 :             unsigned x0=nlcom[i0]->getFullAtomList()[k].index();
+    1175           0 :             m_deriv[x0] -= tmpder*fmass[x0];
+    1176           0 :             for(unsigned l=0; l<3; l++) {
+    1177           0 :               dist[l]=0.;
+    1178             :             }
+    1179           0 :             Vector P0=getPosition(x0);
+    1180           0 :             for(unsigned l=0; l<nlcom[i0]->getFullAtomList().size(); l++) {
+    1181           0 :               unsigned x1=nlcom[i0]->getFullAtomList()[l].index();
+    1182           0 :               Vector P1=getPosition(x1);
+    1183           0 :               if(dopbc) {
+    1184           0 :                 dist+=pbcDistance(P0,P1);
+    1185             :               } else {
+    1186           0 :                 dist+=delta(P0,P1);
+    1187             :               }
+    1188             :             }
+    1189           0 :             for(unsigned l=0; l<nlcom[i1]->getFullAtomList().size(); l++) {
+    1190           0 :               unsigned x1=nlcom[i1]->getFullAtomList()[l].index();
+    1191           0 :               Vector P1=getPosition(x1);
+    1192           0 :               if(dopbc) {
+    1193           0 :                 dist+=pbcDistance(P0,P1);
+    1194             :               } else {
+    1195           0 :                 dist+=delta(P0,P1);
+    1196             :               }
+    1197             :             }
+    1198           0 :             m_virial    -= 0.25*fmass[x0]*Tensor(dist,tmpder);
+    1199             :           }
+    1200           0 :           for(unsigned k=0; k<nlcom[i1]->getFullAtomList().size(); k++) {
+    1201           0 :             unsigned x1=nlcom[i1]->getFullAtomList()[k].index();
+    1202           0 :             m_deriv[x1] += tmpder*fmass[x1];
+    1203           0 :             for(unsigned l=0; l<3; l++) {
+    1204           0 :               dist[l]=0.;
+    1205             :             }
+    1206           0 :             Vector P1=getPosition(x1);
+    1207           0 :             for(unsigned l=0; l<nlcom[i1]->getFullAtomList().size(); l++) {
+    1208           0 :               unsigned x0=nlcom[i1]->getFullAtomList()[l].index();
+    1209           0 :               Vector P0=getPosition(x0);
+    1210           0 :               if(dopbc) {
+    1211           0 :                 dist+=pbcDistance(P1,P0);
+    1212             :               } else {
+    1213           0 :                 dist+=delta(P1,P0);
+    1214             :               }
+    1215             :             }
+    1216           0 :             for(unsigned l=0; l<nlcom[i0]->getFullAtomList().size(); l++) {
+    1217           0 :               unsigned x0=nlcom[i0]->getFullAtomList()[l].index();
+    1218           0 :               Vector P0=getPosition(x0);
+    1219           0 :               if(dopbc) {
+    1220           0 :                 dist+=pbcDistance(P1,P0);
+    1221             :               } else {
+    1222           0 :                 dist+=delta(P1,P0);
+    1223             :               }
+    1224             :             }
+    1225           0 :             m_virial    += 0.25*fmass[x1]*Tensor(dist,tmpder);
+    1226             :           }
+    1227             :         } else {
+    1228    11574264 :           m_deriv[i0] -= tmpder;
+    1229    11574264 :           m_deriv[i1] += tmpder;
+    1230    11574264 :           m_virial    -= tmp*Tensor(distance,distance);
+    1231             :         }
+    1232    11574264 :         if(Scalevol) {
+    1233    11574264 :           m_virial+=1./3.*tmp*dm*dm*Tensor::identity();
+    1234             :         }
+    1235    11574264 :         m_PIVdistance    += scaling[j]*coord*coord;
+    1236             :       }
+    1237             :     }
+    1238             : 
+    1239         327 :     if (!serial && comm.initialized()) {
+    1240           0 :       comm.Barrier();
+    1241           0 :       comm.Sum(&m_PIVdistance,1);
+    1242           0 :       if(!m_deriv.empty()) comm.Sum(&m_deriv[0][0],3*m_deriv.size());
+    1243           0 :       comm.Sum(&m_virial[0][0],9);
+    1244             :     }
+    1245             :   }
+    1246         327 :   prev_stp=getStep();
+    1247             : 
+    1248             :   //Timing
+    1249         327 :   if(timer) stopwatch.stop("4 Build For Derivatives");
+    1250         327 :   if(timer) {
+    1251           1 :     log.printf("Timings for action %s with label %s \n", getName().c_str(), getLabel().c_str() );
+    1252           1 :     log<<stopwatch;
+    1253             :   }
+    1254             : 
+    1255             :   // Update derivatives, virial, and variable (PIV-distance^2)
+    1256       29799 :   for(unsigned i=0; i<m_deriv.size(); ++i) setAtomsDerivatives(i,m_deriv[i]);
+    1257         327 :   setValue           (m_PIVdistance);
+    1258         327 :   setBoxDerivatives  (m_virial);
+    1259         327 : }
+    1260             : //Close Namespaces at the very beginning
+    1261             : }
+    1262             : }
+    1263             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/piv/index-sort-f.html b/coverage/piv/index-sort-f.html new file mode 100644 index 000000000000..2b3c37cec82e --- /dev/null +++ b/coverage/piv/index-sort-f.html @@ -0,0 +1,94 @@ + + + + + + + + LCOV - plumed test coverage - piv + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - pivHitTotalCoverage
Test:plumed test coverageLines:42759571.8 %
Date:2024-04-19 12:12:35Functions:3560.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
PIV.cpp +
71.8%71.8%
+
71.8 %427 / 59560.0 %3 / 5
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/piv/index-sort-l.html b/coverage/piv/index-sort-l.html new file mode 100644 index 000000000000..01396253e5dd --- /dev/null +++ b/coverage/piv/index-sort-l.html @@ -0,0 +1,94 @@ + + + + + + + + LCOV - plumed test coverage - piv + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - pivHitTotalCoverage
Test:plumed test coverageLines:42759571.8 %
Date:2024-04-19 12:12:35Functions:3560.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
PIV.cpp +
71.8%71.8%
+
71.8 %427 / 59560.0 %3 / 5
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/piv/index.html b/coverage/piv/index.html new file mode 100644 index 000000000000..58e56814a869 --- /dev/null +++ b/coverage/piv/index.html @@ -0,0 +1,94 @@ + + + + + + + + LCOV - plumed test coverage - piv + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - pivHitTotalCoverage
Test:plumed test coverageLines:42759571.8 %
Date:2024-04-19 12:12:35Functions:3560.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
PIV.cpp +
71.8%71.8%
+
71.8 %427 / 59560.0 %3 / 5
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/pytorch/PytorchModel.cpp.func-sort-c.html b/coverage/pytorch/PytorchModel.cpp.func-sort-c.html new file mode 100644 index 000000000000..17bd83d063fb --- /dev/null +++ b/coverage/pytorch/PytorchModel.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - pytorch/PytorchModel.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - pytorch - PytorchModel.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:626989.9 %
Date:2024-04-19 12:12:35Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function7pytorch12PytorchModelC2ERKNS_13ActionOptionsE0
_ZN4PLMD8function7pytorch12PytorchModelC1ERKNS_13ActionOptionsE4
_ZN4PLMD8function7pytorch12PytorchModel16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD8function7pytorch12PytorchModel9calculateEv44
_ZN4PLMD8function7pytorch12PytorchModel16tensor_to_vectorERKN2at6TensorE103
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/pytorch/PytorchModel.cpp.func.html b/coverage/pytorch/PytorchModel.cpp.func.html new file mode 100644 index 000000000000..62aa4c0a3bcb --- /dev/null +++ b/coverage/pytorch/PytorchModel.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - pytorch/PytorchModel.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - pytorch - PytorchModel.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:626989.9 %
Date:2024-04-19 12:12:35Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function7pytorch12PytorchModel16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD8function7pytorch12PytorchModel16tensor_to_vectorERKN2at6TensorE103
_ZN4PLMD8function7pytorch12PytorchModel9calculateEv44
_ZN4PLMD8function7pytorch12PytorchModelC1ERKNS_13ActionOptionsE4
_ZN4PLMD8function7pytorch12PytorchModelC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/pytorch/PytorchModel.cpp.gcov.html b/coverage/pytorch/PytorchModel.cpp.gcov.html new file mode 100644 index 000000000000..f4559f36fc71 --- /dev/null +++ b/coverage/pytorch/PytorchModel.cpp.gcov.html @@ -0,0 +1,321 @@ + + + + + + + + LCOV - plumed test coverage - pytorch/PytorchModel.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - pytorch - PytorchModel.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:626989.9 %
Date:2024-04-19 12:12:35Functions:4580.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2022-2023 of Luigi Bonati and Enrico Trizio.
+       3             : 
+       4             : The pytorch module is free software: you can redistribute it and/or modify
+       5             : it under the terms of the GNU Lesser General Public License as published by
+       6             : the Free Software Foundation, either version 3 of the License, or
+       7             : (at your option) any later version.
+       8             : 
+       9             : The pytorch module is distributed in the hope that it will be useful,
+      10             : but WITHOUT ANY WARRANTY; without even the implied warranty of
+      11             : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      12             : GNU Lesser General Public License for more details.
+      13             : 
+      14             : You should have received a copy of the GNU Lesser General Public License
+      15             : along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      16             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      17             : 
+      18             : #ifdef __PLUMED_HAS_LIBTORCH
+      19             : // convert LibTorch version to string
+      20             : //#define STRINGIFY(x) #x
+      21             : //#define TOSTR(x) STRINGIFY(x)
+      22             : //#define LIBTORCH_VERSION TO_STR(TORCH_VERSION_MAJOR) "." TO_STR(TORCH_VERSION_MINOR) "." TO_STR(TORCH_VERSION_PATCH)
+      23             : 
+      24             : #include "core/PlumedMain.h"
+      25             : #include "function/Function.h"
+      26             : #include "core/ActionRegister.h"
+      27             : 
+      28             : #include <torch/torch.h>
+      29             : #include <torch/script.h>
+      30             : 
+      31             : #include <fstream>
+      32             : #include <cmath>
+      33             : 
+      34             : // Note: Freezing a ScriptModule (torch::jit::freeze) works only in >=1.11
+      35             : // For 1.8 <= versions <=1.10 we need a hack
+      36             : // (see https://discuss.pytorch.org/t/how-to-check-libtorch-version/77709/4 and also
+      37             : // https://github.com/pytorch/pytorch/blob/dfbd030854359207cb3040b864614affeace11ce/torch/csrc/jit/api/module.cpp#L479)
+      38             : // adapted from NequIP https://github.com/mir-group/nequip
+      39             : #if ( TORCH_VERSION_MAJOR == 2 || TORCH_VERSION_MAJOR == 1 && TORCH_VERSION_MINOR <= 10 )
+      40             : #define DO_TORCH_FREEZE_HACK
+      41             : // For the hack, need more headers:
+      42             : #include <torch/csrc/jit/passes/freeze_module.h>
+      43             : #include <torch/csrc/jit/passes/frozen_graph_optimizations.h>
+      44             : #endif
+      45             : 
+      46             : using namespace std;
+      47             : 
+      48             : namespace PLMD {
+      49             : namespace function {
+      50             : namespace pytorch {
+      51             : 
+      52             : //+PLUMEDOC PYTORCH_FUNCTION PYTORCH_MODEL
+      53             : /*
+      54             : Load a PyTorch model compiled with TorchScript.
+      55             : 
+      56             : This can be a function defined in Python or a more complex model, such as a neural network optimized on a set of data. In both cases the derivatives of the outputs with respect to the inputs are computed using the automatic differentiation (autograd) feature of Pytorch.
+      57             : 
+      58             : By default it is assumed that the model is saved as: `model.ptc`, unless otherwise indicated by the `FILE` keyword. The function automatically checks for the number of output dimensions and creates a component for each of them. The outputs are called node-i with i between 0 and N-1 for N outputs.
+      59             : 
+      60             : Note that this function requires \ref installation-libtorch LibTorch C++ library. Check the instructions in the \ref PYTORCH page to enable the module.
+      61             : 
+      62             : \par Examples
+      63             : Load a model called `torch_model.ptc` that takes as input two dihedral angles and returns two outputs.
+      64             : 
+      65             : \plumedfile
+      66             : #SETTINGS AUXFILE=regtest/pytorch/rt-pytorch_model_2d/torch_model.ptc
+      67             : phi: TORSION ATOMS=5,7,9,15
+      68             : psi: TORSION ATOMS=7,9,15,17
+      69             : model: PYTORCH_MODEL FILE=torch_model.ptc ARG=phi,psi
+      70             : PRINT FILE=COLVAR ARG=model.node-0,model.node-1
+      71             : \endplumedfile
+      72             : 
+      73             : */
+      74             : //+ENDPLUMEDOC
+      75             : 
+      76             : 
+      77             : class PytorchModel :
+      78             :   public Function
+      79             : {
+      80             :   unsigned _n_in;
+      81             :   unsigned _n_out;
+      82             :   torch::jit::script::Module _model;
+      83             :   torch::Device device = torch::kCPU;
+      84             : 
+      85             : public:
+      86             :   explicit PytorchModel(const ActionOptions&);
+      87             :   void calculate();
+      88             :   static void registerKeywords(Keywords& keys);
+      89             : 
+      90             :   std::vector<float> tensor_to_vector(const torch::Tensor& x);
+      91             : };
+      92             : 
+      93             : PLUMED_REGISTER_ACTION(PytorchModel,"PYTORCH_MODEL")
+      94             : 
+      95           6 : void PytorchModel::registerKeywords(Keywords& keys) {
+      96           6 :   Function::registerKeywords(keys);
+      97           6 :   keys.use("ARG");
+      98          12 :   keys.add("optional","FILE","Filename of the PyTorch compiled model");
+      99          12 :   keys.addOutputComponent("node", "default", "Model outputs");
+     100           6 : }
+     101             : 
+     102             : // Auxiliary function to transform torch tensors in std vectors
+     103         103 : std::vector<float> PytorchModel::tensor_to_vector(const torch::Tensor& x) {
+     104         206 :   return std::vector<float>(x.data_ptr<float>(), x.data_ptr<float>() + x.numel());
+     105             : }
+     106             : 
+     107           4 : PytorchModel::PytorchModel(const ActionOptions&ao):
+     108             :   Action(ao),
+     109           4 :   Function(ao)
+     110             : {
+     111             :   // print libtorch version
+     112           4 :   std::stringstream ss;
+     113           4 :   ss << TORCH_VERSION_MAJOR << "." << TORCH_VERSION_MINOR << "." << TORCH_VERSION_PATCH;
+     114             :   std::string version;
+     115           4 :   ss >> version; // extract into the string.
+     116           8 :   log.printf(("  LibTorch version: "+version+"\n").data());
+     117             : 
+     118             :   //number of inputs of the model
+     119           4 :   _n_in=getNumberOfArguments();
+     120             : 
+     121             :   //parse model name
+     122           4 :   std::string fname="model.ptc";
+     123           8 :   parse("FILE",fname);
+     124             : 
+     125             :   //deserialize the model from file
+     126             :   try {
+     127           4 :     _model = torch::jit::load(fname, device);
+     128             :   }
+     129             : 
+     130             :   //if an error is thrown check if the file exists or not
+     131           0 :   catch (const c10::Error& e) {
+     132           0 :     std::ifstream infile(fname);
+     133             :     bool exist = infile.good();
+     134           0 :     infile.close();
+     135           0 :     if (exist) {
+     136           0 :       plumed_merror("Cannot load FILE: '"+fname+"'. Please check that it is a Pytorch compiled model (exported with 'torch.jit.trace' or 'torch.jit.script').");
+     137             :     }
+     138             :     else {
+     139           0 :       plumed_merror("The FILE: '"+fname+"' does not exist.");
+     140             :     }
+     141           0 :   }
+     142           4 :   checkRead();
+     143             : 
+     144             : // Optimize model
+     145             :   _model.eval();
+     146             : #ifdef DO_TORCH_FREEZE_HACK
+     147             :   // Do the hack
+     148             :   // Copied from the implementation of torch::jit::freeze,
+     149             :   // except without the broken check
+     150             :   // See https://github.com/pytorch/pytorch/blob/dfbd030854359207cb3040b864614affeace11ce/torch/csrc/jit/api/module.cpp
+     151             :   bool optimize_numerics = true;  // the default
+     152             :   // the {} is preserved_attrs
+     153             :   auto out_mod = torch::jit::freeze_module(
+     154             :                    _model, {}
+     155           4 :                  );
+     156             :   // See 1.11 bugfix in https://github.com/pytorch/pytorch/pull/71436
+     157           8 :   auto graph = out_mod.get_method("forward").graph();
+     158           4 :   OptimizeFrozenGraph(graph, optimize_numerics);
+     159           4 :   _model = out_mod;
+     160             : #else
+     161             :   // Do it normally
+     162             :   _model = torch::jit::freeze(_model);
+     163             : #endif
+     164             : 
+     165             : // Optimize model for inference
+     166             : #if (TORCH_VERSION_MAJOR == 2 || TORCH_VERSION_MAJOR == 1 && TORCH_VERSION_MINOR >= 10)
+     167           4 :   _model = torch::jit::optimize_for_inference(_model);
+     168             : #endif
+     169             : 
+     170             :   //check the dimension of the output
+     171           4 :   log.printf("  Checking output dimension:\n");
+     172           4 :   std::vector<float> input_test (_n_in);
+     173           4 :   torch::Tensor single_input = torch::tensor(input_test).view({1,_n_in});
+     174           8 :   single_input = single_input.to(device);
+     175             :   std::vector<torch::jit::IValue> inputs;
+     176           4 :   inputs.push_back( single_input );
+     177           8 :   torch::Tensor output = _model.forward( inputs ).toTensor();
+     178           4 :   vector<float> cvs = this->tensor_to_vector (output);
+     179           4 :   _n_out=cvs.size();
+     180             : 
+     181             :   //create components
+     182           9 :   for(unsigned j=0; j<_n_out; j++) {
+     183           5 :     string name_comp = "node-"+std::to_string(j);
+     184           5 :     addComponentWithDerivatives( name_comp );
+     185           5 :     componentIsNotPeriodic( name_comp );
+     186             :   }
+     187             : 
+     188             :   //print log
+     189           4 :   log.printf("  Number of input: %d \n",_n_in);
+     190           4 :   log.printf("  Number of outputs: %d \n",_n_out);
+     191           4 :   log.printf("  Bibliography: ");
+     192           8 :   log<<plumed.cite("Bonati, Trizio, Rizzi and Parrinello, J. Chem. Phys. 159, 014801 (2023)");
+     193           8 :   log<<plumed.cite("Bonati, Rizzi and Parrinello, J. Phys. Chem. Lett. 11, 2998-3004 (2020)");
+     194           4 :   log.printf("\n");
+     195             : 
+     196          12 : }
+     197             : 
+     198             : 
+     199          44 : void PytorchModel::calculate() {
+     200             : 
+     201             :   // retrieve arguments
+     202          44 :   vector<float> current_S(_n_in);
+     203          99 :   for(unsigned i=0; i<_n_in; i++)
+     204          55 :     current_S[i]=getArgument(i);
+     205             :   //convert to tensor
+     206          44 :   torch::Tensor input_S = torch::tensor(current_S).view({1,_n_in}).to(device);
+     207             :   input_S.set_requires_grad(true);
+     208             :   //convert to Ivalue
+     209             :   std::vector<torch::jit::IValue> inputs;
+     210          44 :   inputs.push_back( input_S );
+     211             :   //calculate output
+     212          88 :   torch::Tensor output = _model.forward( inputs ).toTensor();
+     213             : 
+     214             : 
+     215          99 :   for(unsigned j=0; j<_n_out; j++) {
+     216          55 :     auto grad_output = torch::ones({1}).expand({1, 1}).to(device);
+     217         440 :     auto gradient = torch::autograd::grad({output.slice(/*dim=*/1, /*start=*/j, /*end=*/j+1)},
+     218             :     {input_S},
+     219             :     /*grad_outputs=*/ {grad_output},
+     220             :     /*retain_graph=*/true,
+     221             :     /*create_graph=*/false)[0]; // the [0] is to get a tensor and not a vector<at::tensor>
+     222             : 
+     223          55 :     vector<float> der = this->tensor_to_vector ( gradient );
+     224          55 :     string name_comp = "node-"+std::to_string(j);
+     225             :     //set derivatives of component j
+     226         132 :     for(unsigned i=0; i<_n_in; i++)
+     227          77 :       setDerivative( getPntrToComponent(name_comp),i, der[i] );
+     228             :   }
+     229             : 
+     230             :   //set CV values
+     231          44 :   vector<float> cvs = this->tensor_to_vector (output);
+     232          99 :   for(unsigned j=0; j<_n_out; j++) {
+     233          55 :     string name_comp = "node-"+std::to_string(j);
+     234          55 :     getPntrToComponent(name_comp)->set(cvs[j]);
+     235             :   }
+     236             : 
+     237          88 : }
+     238             : 
+     239             : 
+     240             : } //PLMD
+     241             : } //function
+     242             : } //pytorch
+     243             : 
+     244             : #endif //PLUMED_HAS_LIBTORCH
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/pytorch/index-sort-f.html b/coverage/pytorch/index-sort-f.html new file mode 100644 index 000000000000..f5aa5448e20c --- /dev/null +++ b/coverage/pytorch/index-sort-f.html @@ -0,0 +1,94 @@ + + + + + + + + LCOV - plumed test coverage - pytorch + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - pytorchHitTotalCoverage
Test:plumed test coverageLines:626989.9 %
Date:2024-04-19 12:12:35Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
PytorchModel.cpp +
89.9%89.9%
+
89.9 %62 / 6980.0 %4 / 5
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/pytorch/index-sort-l.html b/coverage/pytorch/index-sort-l.html new file mode 100644 index 000000000000..b6a8d3003d72 --- /dev/null +++ b/coverage/pytorch/index-sort-l.html @@ -0,0 +1,94 @@ + + + + + + + + LCOV - plumed test coverage - pytorch + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - pytorchHitTotalCoverage
Test:plumed test coverageLines:626989.9 %
Date:2024-04-19 12:12:35Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
PytorchModel.cpp +
89.9%89.9%
+
89.9 %62 / 6980.0 %4 / 5
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/pytorch/index.html b/coverage/pytorch/index.html new file mode 100644 index 000000000000..52bf9dc14355 --- /dev/null +++ b/coverage/pytorch/index.html @@ -0,0 +1,94 @@ + + + + + + + + LCOV - plumed test coverage - pytorch + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - pytorchHitTotalCoverage
Test:plumed test coverageLines:626989.9 %
Date:2024-04-19 12:12:35Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
PytorchModel.cpp +
89.9%89.9%
+
89.9 %62 / 6980.0 %4 / 5
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/refdist/Difference.cpp.func-sort-c.html b/coverage/refdist/Difference.cpp.func-sort-c.html new file mode 100644 index 000000000000..54d2ce8b6c55 --- /dev/null +++ b/coverage/refdist/Difference.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - refdist/Difference.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - refdist - Difference.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:243080.0 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7refdist10Difference16registerKeywordsERNS_8KeywordsE0
_ZN4PLMD7refdist10Difference24setPeriodicityForOutputsEPNS_15ActionWithValueE184
_ZN4PLMD7refdist10Difference4readEPNS_19ActionWithArgumentsE184
_ZNK4PLMD7refdist10Difference4calcEPKNS_19ActionWithArgumentsERKSt6vectorIdSaIdEERS7_RNS_6MatrixIdEE2877849
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/refdist/Difference.cpp.func.html b/coverage/refdist/Difference.cpp.func.html new file mode 100644 index 000000000000..b8a7af2460cd --- /dev/null +++ b/coverage/refdist/Difference.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - refdist/Difference.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - refdist - Difference.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:243080.0 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7refdist10Difference16registerKeywordsERNS_8KeywordsE0
_ZN4PLMD7refdist10Difference24setPeriodicityForOutputsEPNS_15ActionWithValueE184
_ZN4PLMD7refdist10Difference4readEPNS_19ActionWithArgumentsE184
_ZNK4PLMD7refdist10Difference4calcEPKNS_19ActionWithArgumentsERKSt6vectorIdSaIdEERS7_RNS_6MatrixIdEE2877849
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/refdist/Difference.cpp.gcov.html b/coverage/refdist/Difference.cpp.gcov.html new file mode 100644 index 000000000000..db8c079a43e4 --- /dev/null +++ b/coverage/refdist/Difference.cpp.gcov.html @@ -0,0 +1,196 @@ + + + + + + + + LCOV - plumed test coverage - refdist/Difference.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - refdist - Difference.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:243080.0 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2017 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received 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/FunctionShortcut.h"
+      23             : #include "function/FunctionOfScalar.h"
+      24             : #include "function/FunctionOfVector.h"
+      25             : #include "core/ActionRegister.h"
+      26             : #include "function/FunctionTemplateBase.h"
+      27             : 
+      28             : #include <cmath>
+      29             : 
+      30             : namespace PLMD {
+      31             : namespace refdist {
+      32             : 
+      33             : //+PLUMEDOC FUNCTION DIFFERENCE
+      34             : /*
+      35             : Calculate the differences between two scalars
+      36             : 
+      37             : \par Examples
+      38             : 
+      39             : */
+      40             : //+ENDPLUMEDOC
+      41             : 
+      42             : //+PLUMEDOC FUNCTION DIFFERENCE_SCALAR
+      43             : /*
+      44             : Calculate the differences between two scalars
+      45             : 
+      46             : \par Examples
+      47             : 
+      48             : */
+      49             : //+ENDPLUMEDOC
+      50             : 
+      51             : //+PLUMEDOC FUNCTION DIFFERENCE_VECTOR
+      52             : /*
+      53             : Calculate the differences between the elements of two vectors
+      54             : 
+      55             : \par Examples
+      56             : 
+      57             : */
+      58             : //+ENDPLUMEDOC
+      59             : 
+      60             : 
+      61         742 : class Difference : public function::FunctionTemplateBase {
+      62             : private:
+      63             :   bool periodic;
+      64             :   std::string min0, max0;
+      65             : public:
+      66           0 :   void registerKeywords(Keywords& keys) override {}
+      67             :   void read( ActionWithArguments* action ) override;
+      68             :   void setPeriodicityForOutputs( ActionWithValue* action ) override;
+      69             :   void calc( const ActionWithArguments* action, const std::vector<double>& args, std::vector<double>& vals, Matrix<double>& derivatives ) const override;
+      70             : };
+      71             : 
+      72             : 
+      73             : typedef function::FunctionShortcut<Difference> DifferenceShortcut;
+      74             : PLUMED_REGISTER_ACTION(DifferenceShortcut,"DIFFERENCE")
+      75             : typedef function::FunctionOfScalar<Difference> ScalarDifference;
+      76             : PLUMED_REGISTER_ACTION(ScalarDifference,"DIFFERENCE_SCALAR")
+      77             : typedef function::FunctionOfVector<Difference> VectorDifference;
+      78             : PLUMED_REGISTER_ACTION(VectorDifference,"DIFFERENCE_VECTOR")
+      79             : 
+      80         184 : void Difference::read( ActionWithArguments* action ) {
+      81         184 :   if( action->getNumberOfArguments()!=2 ) action->error("should be two arguments to this action");
+      82         184 :   if( action->getPntrToArgument(0)->getRank()==action->getPntrToArgument(1)->getRank() ) {
+      83          51 :     std::vector<unsigned> shape( action->getPntrToArgument(0)->getShape() );
+      84          61 :     for(unsigned i=0; i<shape.size(); ++i) {
+      85          10 :       if( shape[i]!=action->getPntrToArgument(1)->getShape()[i] ) action->error("shapes of input actions do not match");
+      86             :     }
+      87             :   }
+      88             : 
+      89         184 :   periodic=false;
+      90         184 :   if( action->getPntrToArgument(0)->isPeriodic() ) {
+      91          43 :     periodic=true; action->getPntrToArgument(0)->getDomain( min0, max0 );
+      92          43 :     if( !action->getPntrToArgument(1)->isConstant() && !action->getPntrToArgument(1)->isPeriodic() ) {
+      93           0 :       action->error("period for input variables " + action->getPntrToArgument(0)->getName() + " and " + action->getPntrToArgument(1)->getName() + " should be the same 0");
+      94             :     }
+      95          43 :     if( !action->getPntrToArgument(1)->isConstant() ) {
+      96           1 :       std::string min1, max1; action->getPntrToArgument(1)->getDomain( min1, max1 );
+      97           1 :       if( min0!=min0 || max0!=max1 ) action->error("domain for input variables should be the same");
+      98          42 :     } else action->getPntrToArgument(1)->setDomain( min0, max0 );
+      99         141 :   } else if( action->getPntrToArgument(1)->isPeriodic() ) {
+     100           0 :     periodic=true; action->getPntrToArgument(1)->getDomain( min0, max0 );
+     101           0 :     if( !action->getPntrToArgument(1)->isConstant() ) {
+     102           0 :       action->error("period for input variables " + action->getPntrToArgument(0)->getName() + " and " + action->getPntrToArgument(1)->getName() + " should be the same 1");
+     103           0 :     } else action->getPntrToArgument(0)->setDomain( min0, max0 );
+     104             :   }
+     105         184 : }
+     106             : 
+     107         184 : void Difference::setPeriodicityForOutputs( ActionWithValue* action ) {
+     108         184 :   if( periodic ) action->setPeriodic( min0, max0 );
+     109         141 :   else action->setNotPeriodic();
+     110         184 : }
+     111             : 
+     112     2877849 : void Difference::calc( const ActionWithArguments* action, const std::vector<double>& args, std::vector<double>& vals, Matrix<double>& derivatives ) const {
+     113     2877849 :   plumed_dbg_assert( args.size()==2 ); vals[0] = action->getPntrToArgument(0)->difference( args[1], args[0] ); derivatives(0,0) = 1.0; derivatives(0,1)=-1;
+     114     2877849 : }
+     115             : 
+     116             : }
+     117             : }
+     118             : 
+     119             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/refdist/Displacement.cpp.func-sort-c.html b/coverage/refdist/Displacement.cpp.func-sort-c.html new file mode 100644 index 000000000000..9497c63ab506 --- /dev/null +++ b/coverage/refdist/Displacement.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - refdist/Displacement.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - refdist - Displacement.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3232100.0 %
Date:2024-04-19 12:12:35Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7refdist12DisplacementC2ERKNS_13ActionOptionsE0
_ZN4PLMD7refdist12DisplacementC1ERKNS_13ActionOptionsE52
_ZN4PLMD7refdist12Displacement16registerKeywordsERNS_8KeywordsE54
_ZNK4PLMD7refdist12Displacement17getValueWithLabelERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE59
_ZN4PLMD7refdist12Displacement14fixArgumentDotERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE354
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/refdist/Displacement.cpp.func.html b/coverage/refdist/Displacement.cpp.func.html new file mode 100644 index 000000000000..905c84d8e916 --- /dev/null +++ b/coverage/refdist/Displacement.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - refdist/Displacement.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - refdist - Displacement.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3232100.0 %
Date:2024-04-19 12:12:35Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7refdist12Displacement14fixArgumentDotERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE354
_ZN4PLMD7refdist12Displacement16registerKeywordsERNS_8KeywordsE54
_ZN4PLMD7refdist12DisplacementC1ERKNS_13ActionOptionsE52
_ZN4PLMD7refdist12DisplacementC2ERKNS_13ActionOptionsE0
_ZNK4PLMD7refdist12Displacement17getValueWithLabelERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE59
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/refdist/Displacement.cpp.gcov.html b/coverage/refdist/Displacement.cpp.gcov.html new file mode 100644 index 000000000000..2582f5203211 --- /dev/null +++ b/coverage/refdist/Displacement.cpp.gcov.html @@ -0,0 +1,174 @@ + + + + + + + + LCOV - plumed test coverage - refdist/Displacement.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - refdist - Displacement.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3232100.0 %
Date:2024-04-19 12:12:35Functions:4580.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2018 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received 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 "core/ActionShortcut.h"
+      26             : #include "core/ActionWithValue.h"
+      27             : 
+      28             : //+PLUMEDOC MCOLVAR DISPLACEMENT
+      29             : /*
+      30             : Calculate the displacement vector between the pair of input vectors
+      31             : 
+      32             : \par Examples
+      33             : 
+      34             : 
+      35             : */
+      36             : //+ENDPLUMEDOC
+      37             : 
+      38             : namespace PLMD {
+      39             : namespace refdist {
+      40             : 
+      41             : class Displacement : public ActionShortcut {
+      42             : public:
+      43             :   static std::string fixArgumentDot( const std::string& argin );
+      44             :   static void registerKeywords( Keywords& keys );
+      45             :   Value* getValueWithLabel( const std::string& name ) const ;
+      46             :   explicit Displacement(const ActionOptions&ao);
+      47             : };
+      48             : 
+      49             : PLUMED_REGISTER_ACTION(Displacement,"DISPLACEMENT")
+      50             : 
+      51          54 : void Displacement::registerKeywords( Keywords& keys ) {
+      52          54 :   ActionShortcut::registerKeywords(keys);
+      53         108 :   keys.add("compulsory","ARG1","The point that we are calculating the distance from");
+      54         108 :   keys.add("compulsory","ARG2","The point that we are calculating the distance to");
+      55         162 :   keys.needsAction("DIFFERENCE"); keys.needsAction("TRANSPOSE"); keys.needsAction("VSTACK");
+      56          54 : }
+      57             : 
+      58         354 : std::string Displacement::fixArgumentDot( const std::string& argin ) {
+      59         354 :   std::string argout = argin; std::size_t dot=argin.find(".");
+      60         362 :   if( dot!=std::string::npos ) argout = argin.substr(0,dot) + "_" + argin.substr(dot+1);
+      61         354 :   return argout;
+      62             : }
+      63             : 
+      64          52 : Displacement::Displacement( const ActionOptions& ao):
+      65             :   Action(ao),
+      66          52 :   ActionShortcut(ao)
+      67             : {
+      68             :   // Read in argument names
+      69         156 :   std::vector<std::string> arg1f, arg2f; parseVector("ARG1",arg1f); parseVector("ARG2",arg2f);
+      70             :   // Check if one of the input arguments is a reference cluster
+      71          52 :   if( arg1f.size()!=arg2f.size() ) error("number of arguments specified to ARG1 should be same as number for ARG2");
+      72             : 
+      73          52 :   Value* val1=getValueWithLabel( arg1f[0] );
+      74          52 :   if( arg1f.size()==1 && val1->getRank()!=0 ) {
+      75           7 :     Value* val2=getValueWithLabel( arg2f[0] );
+      76           7 :     if( val1->getNumberOfValues()==val2->getNumberOfValues() ) {
+      77          10 :       readInputLine( getShortcutLabel() + "_" + fixArgumentDot(arg1f[0]) + "_diff: DIFFERENCE ARG=" + arg1f[0] + "," + arg2f[0] );
+      78          10 :       readInputLine( getShortcutLabel() + ": TRANSPOSE ARG=" + getShortcutLabel() + "_" + fixArgumentDot(arg1f[0]) + "_diff");
+      79           4 :     } else readInputLine( getShortcutLabel() + ": DIFFERENCE ARG=" + arg1f[0] + "," + arg2f[0] );
+      80             :   } else {
+      81         217 :     for(unsigned i=0; i<arg1f.size(); ++i) readInputLine( getShortcutLabel() + "_" + fixArgumentDot(arg1f[i]) + "_diff: DIFFERENCE ARG=" + arg1f[i] + "," + arg2f[i] );
+      82         217 :     std::string argdat = "ARG=" + getShortcutLabel() + "_" + fixArgumentDot(arg1f[0]) + "_diff"; for(unsigned i=1; i<arg1f.size(); ++i) argdat += "," +  getShortcutLabel() + "_" + fixArgumentDot(arg1f[i]) + "_diff";
+      83          90 :     readInputLine( getShortcutLabel() + ": VSTACK " + argdat );
+      84             :   }
+      85          52 : }
+      86             : 
+      87          59 : Value* Displacement::getValueWithLabel( const std::string& name ) const {
+      88          59 :   std::size_t dot=name.find("."); std::string sname = name.substr(0,dot);
+      89          59 :   ActionWithValue* vv=plumed.getActionSet().selectWithLabel<ActionWithValue*>( sname );
+      90          59 :   if( !vv ) error("cannot find value with name " + name );
+      91          59 :   if( dot==std::string::npos ) return vv->copyOutput(0);
+      92           2 :   if( !vv->exists(name) ) error("cannot find value with name " + name );
+      93           2 :   return vv->copyOutput( name );
+      94             : }
+      95             : 
+      96             : }
+      97             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/refdist/EuclideanDistance.cpp.func-sort-c.html b/coverage/refdist/EuclideanDistance.cpp.func-sort-c.html new file mode 100644 index 000000000000..07d58580b83b --- /dev/null +++ b/coverage/refdist/EuclideanDistance.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - refdist/EuclideanDistance.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - refdist - EuclideanDistance.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:192095.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7refdist17EuclideanDistanceC2ERKNS_13ActionOptionsE0
_ZN4PLMD7refdist17EuclideanDistanceC1ERKNS_13ActionOptionsE28
_ZN4PLMD7refdist17EuclideanDistance16registerKeywordsERNS_8KeywordsE30
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/refdist/EuclideanDistance.cpp.func.html b/coverage/refdist/EuclideanDistance.cpp.func.html new file mode 100644 index 000000000000..5f8ea569dd94 --- /dev/null +++ b/coverage/refdist/EuclideanDistance.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - refdist/EuclideanDistance.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - refdist - EuclideanDistance.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:192095.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7refdist17EuclideanDistance16registerKeywordsERNS_8KeywordsE30
_ZN4PLMD7refdist17EuclideanDistanceC1ERKNS_13ActionOptionsE28
_ZN4PLMD7refdist17EuclideanDistanceC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/refdist/EuclideanDistance.cpp.gcov.html b/coverage/refdist/EuclideanDistance.cpp.gcov.html new file mode 100644 index 000000000000..72f0cf9e5ece --- /dev/null +++ b/coverage/refdist/EuclideanDistance.cpp.gcov.html @@ -0,0 +1,157 @@ + + + + + + + + LCOV - plumed test coverage - refdist/EuclideanDistance.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - refdist - EuclideanDistance.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:192095.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2018 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received 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/ActionShortcut.h"
+      24             : #include "core/PlumedMain.h"
+      25             : #include "core/ActionSet.h"
+      26             : #include "core/ActionWithValue.h"
+      27             : 
+      28             : //+PLUMEDOC MCOLVAR EUCLIDEAN_DISTANCE
+      29             : /*
+      30             : Calculate the euclidean distance between two vectors of arguments
+      31             : 
+      32             : \par Examples
+      33             : 
+      34             : */
+      35             : //+ENDPLUMEDOC
+      36             : 
+      37             : namespace PLMD {
+      38             : namespace refdist {
+      39             : 
+      40             : class EuclideanDistance : public ActionShortcut {
+      41             : public:
+      42             :   static void registerKeywords( Keywords& keys );
+      43             :   explicit EuclideanDistance(const ActionOptions&ao);
+      44             : };
+      45             : 
+      46             : PLUMED_REGISTER_ACTION(EuclideanDistance,"EUCLIDEAN_DISTANCE")
+      47             : 
+      48          30 : void EuclideanDistance::registerKeywords( Keywords& keys ) {
+      49          30 :   ActionShortcut::registerKeywords(keys);
+      50          60 :   keys.add("compulsory","ARG1","The poin that we are calculating the distance from");
+      51          60 :   keys.add("compulsory","ARG2","The point that we are calculating the distance to");
+      52          60 :   keys.addFlag("SQUARED",false,"The squared distance should be calculated");
+      53          60 :   keys.needsAction("DISPLACEMENT"); keys.needsAction("CUSTOM");
+      54          60 :   keys.needsAction("TRANSPOSE"); keys.needsAction("MATRIX_PRODUCT_DIAGONAL");
+      55          30 : }
+      56             : 
+      57          28 : EuclideanDistance::EuclideanDistance( const ActionOptions& ao):
+      58             :   Action(ao),
+      59          28 :   ActionShortcut(ao)
+      60             : {
+      61          56 :   std::string arg1, arg2; parse("ARG1",arg1); parse("ARG2",arg2);
+      62             :   // Vectors are in rows here
+      63          56 :   readInputLine( getShortcutLabel() + "_diff: DISPLACEMENT ARG1=" + arg1 + " ARG2=" + arg2 );
+      64             :   // Get the action that computes the differences
+      65          56 :   ActionWithValue* av = plumed.getActionSet().selectWithLabel<ActionWithValue*>( getShortcutLabel() + "_diff"); plumed_assert( av );
+      66             :   // Check if squared
+      67          56 :   bool squared; parseFlag("SQUARED",squared); std::string olab = getShortcutLabel(); if( !squared ) olab += "_2";
+      68             :   // Deal with an annoying corner case when displacement has a single argument
+      69          28 :   if( av->copyOutput(0)->getRank()==0 ) {
+      70           0 :     readInputLine( olab + ": CUSTOM ARG=" + getShortcutLabel() + "_diff FUNC=x*x PERIODIC=NO");
+      71             :   } else {
+      72             :     // Notice that the vectors are in the columns here
+      73          56 :     readInputLine( getShortcutLabel() + "_diffT: TRANSPOSE ARG=" + getShortcutLabel() + "_diff");
+      74          56 :     readInputLine( olab + ": MATRIX_PRODUCT_DIAGONAL ARG=" + getShortcutLabel() + "_diff," + getShortcutLabel() + "_diffT");
+      75             :   }
+      76          51 :   if( !squared ) readInputLine( getShortcutLabel() + ": CUSTOM ARG=" + getShortcutLabel() + "_2 FUNC=sqrt(x) PERIODIC=NO");
+      77          28 : }
+      78             : 
+      79             : }
+      80             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/refdist/Kernel.cpp.func-sort-c.html b/coverage/refdist/Kernel.cpp.func-sort-c.html new file mode 100644 index 000000000000..49215b6fc799 --- /dev/null +++ b/coverage/refdist/Kernel.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - refdist/Kernel.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - refdist - Kernel.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:8310678.3 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7refdist6KernelC2ERKNS_13ActionOptionsE0
_ZN4PLMD7refdist6KernelC1ERKNS_13ActionOptionsE9
_ZN4PLMD7refdist6Kernel16registerKeywordsERNS_8KeywordsE11
_ZN4PLMD7refdist6Kernel14fixArgumentDotERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE32
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/refdist/Kernel.cpp.func.html b/coverage/refdist/Kernel.cpp.func.html new file mode 100644 index 000000000000..1862f1da79ec --- /dev/null +++ b/coverage/refdist/Kernel.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - refdist/Kernel.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - refdist - Kernel.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:8310678.3 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7refdist6Kernel14fixArgumentDotERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE32
_ZN4PLMD7refdist6Kernel16registerKeywordsERNS_8KeywordsE11
_ZN4PLMD7refdist6KernelC1ERKNS_13ActionOptionsE9
_ZN4PLMD7refdist6KernelC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/refdist/Kernel.cpp.gcov.html b/coverage/refdist/Kernel.cpp.gcov.html new file mode 100644 index 000000000000..78ae25dfe1dd --- /dev/null +++ b/coverage/refdist/Kernel.cpp.gcov.html @@ -0,0 +1,290 @@ + + + + + + + + LCOV - plumed test coverage - refdist/Kernel.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - refdist - Kernel.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:8310678.3 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2017 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received 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/PlumedMain.h"
+      24             : #include "core/ActionSet.h"
+      25             : #include "core/ActionRegister.h"
+      26             : #include "core/ActionWithValue.h"
+      27             : #include "tools/IFile.h"
+      28             : 
+      29             : #include <cmath>
+      30             : 
+      31             : namespace PLMD {
+      32             : namespace refdist {
+      33             : 
+      34             : //+PLUMEDOC FUNCTION KERNEL
+      35             : /*
+      36             : Use a switching function to determine how many of the input variables are less than a certain cutoff.
+      37             : 
+      38             : \par Examples
+      39             : 
+      40             : */
+      41             : //+ENDPLUMEDOC
+      42             : 
+      43             : 
+      44             : class Kernel : public ActionShortcut {
+      45             : public:
+      46             :   static std::string fixArgumentDot( const std::string& argin );
+      47             :   explicit Kernel(const ActionOptions&);
+      48             :   static void registerKeywords(Keywords& keys);
+      49             : };
+      50             : 
+      51             : 
+      52             : PLUMED_REGISTER_ACTION(Kernel,"KERNEL")
+      53             : 
+      54          11 : void Kernel::registerKeywords(Keywords& keys) {
+      55          11 :   ActionShortcut::registerKeywords( keys );
+      56          22 :   keys.add("numbered","ARG","the arguments that should be used as input to this method");
+      57          22 :   keys.add("compulsory","TYPE","gaussian","the type of kernel to use");
+      58          22 :   keys.add("compulsory","CENTER","the position of the center of the kernel");
+      59          22 :   keys.add("optional","SIGMA","square root of variance of the cluster");
+      60          22 :   keys.add("compulsory","COVAR","the covariance of the kernel");
+      61          22 :   keys.add("compulsory","WEIGHT","1.0","the weight to multiply this kernel function by");
+      62          22 :   keys.add("optional","REFERENCE","the file from which to read the kernel parameters");
+      63          22 :   keys.add("compulsory","NUMBER","1","if there are multiple sets of kernel parameters in the input file which set of kernel parameters would you like to read in here");
+      64          22 :   keys.addFlag("NORMALIZED",false,"would you like the kernel function to be normalized");
+      65          33 :   keys.needsAction("CONSTANT"); keys.needsAction("CUSTOM"); keys.needsAction("NORMALIZED_EUCLIDEAN_DISTANCE");
+      66          33 :   keys.needsAction("PRODUCT"); keys.needsAction("INVERT_MATRIX"); keys.needsAction("MAHALANOBIS_DISTANCE");
+      67          33 :   keys.needsAction("DIAGONALIZE"); keys.needsAction("CONCATENATE"); keys.needsAction("DETERMINANT");
+      68          11 :   keys.needsAction("BESSEL");
+      69          11 : }
+      70             : 
+      71          32 : std::string Kernel::fixArgumentDot( const std::string& argin ) {
+      72          32 :   std::string argout = argin; std::size_t dot=argin.find(".");
+      73          32 :   if( dot!=std::string::npos ) argout = argin.substr(0,dot) + "_" + argin.substr(dot+1);
+      74          32 :   return argout;
+      75             : }
+      76             : 
+      77           9 : Kernel::Kernel(const ActionOptions&ao):
+      78             :   Action(ao),
+      79           9 :   ActionShortcut(ao)
+      80             : {
+      81             :   // Read in the arguments
+      82          18 :   std::vector<std::string> argnames; parseVector("ARG",argnames);
+      83           9 :   if( argnames.size()==0 ) error("no arguments were specified");
+      84             :   // Now sort out the parameters
+      85          18 :   double weight; std::string fname; parse("REFERENCE",fname); bool usemahalanobis=false;
+      86           9 :   if( fname.length()>0 ) {
+      87           9 :     IFile ifile; ifile.open(fname); ifile.allowIgnoredFields();
+      88           9 :     unsigned number; parse("NUMBER",number); bool readline=false;
+      89             :     // Create actions to hold the position of the center
+      90          31 :     for(unsigned line=0; line<number; ++line) {
+      91          90 :       for(unsigned i=0; i<argnames.size(); ++i) {
+      92          59 :         std::string val; ifile.scanField(argnames[i], val);
+      93          75 :         if( line==number-1 ) readInputLine( getShortcutLabel() + "_" + fixArgumentDot(argnames[i]) + "_ref: CONSTANT VALUES=" + val );
+      94             :       }
+      95          62 :       if( ifile.FieldExist("sigma_" + argnames[0]) ) {
+      96             :         std::string varstr;
+      97           0 :         for(unsigned i=0; i<argnames.size(); ++i) {
+      98           0 :           std::string val; ifile.scanField("sigma_" + argnames[i], val);
+      99           0 :           if( i==0 ) varstr = val; else varstr += "," + val;
+     100             :         }
+     101           0 :         if( line==number-1 ) readInputLine( getShortcutLabel() + "_var: CONSTANT VALUES=" + varstr );
+     102             :       } else {
+     103          31 :         std::string varstr, nvals; Tools::convert( argnames.size(), nvals ); usemahalanobis=(argnames.size()>1);
+     104          90 :         for(unsigned i=0; i<argnames.size(); ++i) {
+     105         174 :           for(unsigned j=0; j<argnames.size(); j++) {
+     106         230 :             std::string val; ifile.scanField("sigma_" +argnames[i] + "_" + argnames[j], val );
+     107         199 :             if(i==0 && j==0 ) varstr = val; else varstr += "," + val;
+     108             :           }
+     109             :         }
+     110          31 :         if( line==number-1 ) {
+     111          11 :           if( !usemahalanobis ) readInputLine( getShortcutLabel() + "_var: CONSTANT VALUES=" + varstr );
+     112          14 :           else readInputLine( getShortcutLabel() + "_cov: CONSTANT NCOLS=" + nvals + " NROWS=" + nvals + " VALUES=" + varstr );
+     113             :         }
+     114             :       }
+     115          31 :       if( line==number-1 ) { readline=true; break; }
+     116          22 :       ifile.scanField();
+     117             :     }
+     118           9 :     if( !readline ) error("could not read reference configuration");
+     119           9 :     ifile.scanField(); ifile.close();
+     120           9 :   } else {
+     121             :     // Create actions to hold the position of the center
+     122           0 :     std::vector<std::string> center(argnames.size()); parseVector("CENTER",center);
+     123           0 :     for(unsigned i=0; i<argnames.size(); ++i) readInputLine( getShortcutLabel() + "_" + fixArgumentDot(argnames[i]) + "_ref: CONSTANT VALUES=" + center[i] );
+     124           0 :     std::vector<std::string> sig; parseVector("SIGMA",sig);
+     125           0 :     if( sig.size()==0 ) {
+     126             :       // Create actions to hold the covariance
+     127           0 :       std::string cov; parse("COVAR",cov); usemahalanobis=(argnames.size()>1);
+     128           0 :       if( !usemahalanobis ) {
+     129           0 :         readInputLine( getShortcutLabel() + "_var: CONSTANT VALUES=" + cov );
+     130             :       } else {
+     131           0 :         std::string nvals; Tools::convert( argnames.size(), nvals );
+     132           0 :         readInputLine( getShortcutLabel() + "_cov: CONSTANT NCOLS=" + nvals + " NROWS=" + nvals + " VALUES=" + cov );
+     133             :       }
+     134           0 :     } else if( sig.size()==argnames.size() ) {
+     135             :       // And actions to hold the standard deviation
+     136           0 :       std::string valstr = sig[0]; for(unsigned i=1; i<sig.size(); ++i) valstr += "," + sig[i];
+     137           0 :       readInputLine( getShortcutLabel() + "_sigma: CONSTANT VALUES=" + valstr );
+     138           0 :       readInputLine( getShortcutLabel() + "_var: CUSTOM ARG=" + getShortcutLabel() + "_sigma FUNC=x*x PERIODIC=NO");
+     139           0 :     } else error("sigma has wrong length");
+     140           0 :   }
+     141             : 
+     142             :   // Create the reference point and arguments
+     143             :   std::string refpoint, argstr;
+     144          25 :   for(unsigned i=0; i<argnames.size(); ++i) {
+     145          34 :     if( i==0 ) { argstr = argnames[0]; refpoint = getShortcutLabel() + "_" + fixArgumentDot(argnames[i]) + "_ref"; }
+     146          21 :     else { argstr += "," + argnames[1]; refpoint += "," + getShortcutLabel() + "_" + fixArgumentDot(argnames[i]) + "_ref"; }
+     147             :   }
+     148             : 
+     149             :   // Get the information on the kernel type
+     150          18 :   std::string func_str, ktype; parse("TYPE",ktype);
+     151          16 :   if( ktype=="gaussian" || ktype=="von-misses" ) func_str = "exp(-x/2)";
+     152           0 :   else if( ktype=="triangular" ) func_str = "step(1.-sqrt(x))*(1.-sqrt(x))";
+     153             :   else func_str = ktype;
+     154           9 :   std::string vm_str=""; if(  ktype=="von-misses" ) vm_str=" VON_MISSES";
+     155             : 
+     156           9 :   unsigned nvals = argnames.size(); bool norm; parseFlag("NORMALIZED",norm);
+     157           9 :   if( !usemahalanobis ) {
+     158             :     // Invert the variance
+     159           4 :     readInputLine( getShortcutLabel() + "_icov: CUSTOM ARG=" + getShortcutLabel() + "_var FUNC=1/x PERIODIC=NO");
+     160             :     // Compute the distance between the center of the basin and the current configuration
+     161           4 :     readInputLine( getShortcutLabel() + "_dist_2: NORMALIZED_EUCLIDEAN_DISTANCE SQUARED" + vm_str +" ARG1=" + argstr + " ARG2=" + refpoint + " METRIC=" + getShortcutLabel() + "_icov");
+     162             :     // And compute a determinent for the input covariance matrix if it is required
+     163           2 :     if( norm ) {
+     164           2 :       if( ktype=="von-misses" ) readInputLine( getShortcutLabel() + "_vec: CUSTOM ARG=" + getShortcutLabel() + "_icov FUNC=x PERIODIC=NO" );
+     165           4 :       else readInputLine( getShortcutLabel() + "_det: PRODUCT ARG=" + getShortcutLabel() + "_var");
+     166             :     }
+     167             :   } else {
+     168             :     // Invert the input covariance matrix
+     169          14 :     readInputLine( getShortcutLabel() + "_icov: INVERT_MATRIX ARG=" + getShortcutLabel() + "_cov" );
+     170             :     // Compute the distance between the center of the basin and the current configuration
+     171          14 :     readInputLine( getShortcutLabel() + "_dist_2: MAHALANOBIS_DISTANCE SQUARED ARG1=" + argstr + " ARG2=" + refpoint + " METRIC=" + getShortcutLabel() + "_icov " + vm_str );
+     172             :     // And compute a determinent for the input covariance matrix if it is required
+     173           7 :     if( norm ) {
+     174           7 :       if( ktype=="von-misses" ) {
+     175          14 :         readInputLine( getShortcutLabel() + "_det: DIAGONALIZE ARG=" + getShortcutLabel() + "_cov VECTORS=all" );
+     176           7 :         std::string num, argnames= getShortcutLabel() + "_det.vals-1";
+     177          14 :         for(unsigned i=1; i<nvals; ++i) { Tools::convert( i+1, num ); argnames += "," + getShortcutLabel() + "_det.vals-" + num; }
+     178          14 :         readInputLine( getShortcutLabel() + "_comp: CONCATENATE ARG=" + argnames );
+     179          14 :         readInputLine( getShortcutLabel() + "_vec: CUSTOM ARG=" + getShortcutLabel() + "_comp FUNC=1/x PERIODIC=NO");
+     180             :       } else {
+     181           0 :         readInputLine( getShortcutLabel() + "_det: DETERMINANT ARG=" + getShortcutLabel() + "_cov");
+     182             :       }
+     183             :     }
+     184             :   }
+     185             : 
+     186             :   // Compute the Gaussian
+     187           9 :   std::string wstr; parse("WEIGHT",wstr);
+     188           9 :   if( norm ) {
+     189           9 :     if( ktype=="gaussian" ) {
+     190           2 :       std::string pstr; Tools::convert( sqrt(pow(2*pi,nvals)), pstr );
+     191           4 :       readInputLine( getShortcutLabel() + "_vol: CUSTOM ARG=" + getShortcutLabel() + "_det FUNC=(sqrt(x)*" + pstr + ") PERIODIC=NO");
+     192           7 :     } else if( ktype=="von-misses" ) {
+     193             :       std::string wstr, min, max;
+     194          14 :       ActionWithValue* av=plumed.getActionSet().selectWithLabel<ActionWithValue*>( getShortcutLabel() + "_dist_2_diff" ); plumed_assert( av );
+     195           7 :       if( !av->copyOutput(0)->isPeriodic() ) error("VON_MISSES only works with periodic variables");
+     196           7 :       av->copyOutput(0)->getDomain(min,max);
+     197          14 :       readInputLine( getShortcutLabel() + "_bes: BESSEL ORDER=0 ARG=" + getShortcutLabel() + "_vec");
+     198          14 :       readInputLine( getShortcutLabel() + "_cc: CUSTOM ARG=" + getShortcutLabel() + "_bes FUNC=("+max+"-"+min+")*x PERIODIC=NO");
+     199          14 :       readInputLine( getShortcutLabel() + "_vol: PRODUCT ARG=" + getShortcutLabel() + "_cc");
+     200           0 :     } else error("only gaussian and von-misses kernels are normalizable");
+     201             :     // And the (suitably normalized) kernel
+     202          18 :     readInputLine( getShortcutLabel() + ": CUSTOM ARG=" + getShortcutLabel() + "_dist_2," + getShortcutLabel() + "_vol FUNC=" + wstr + "*exp(-x/2)/y PERIODIC=NO");
+     203             :   } else {
+     204           0 :     readInputLine( getShortcutLabel() + ": CUSTOM ARG1=" + getShortcutLabel() + "_dist_2 FUNC=" + wstr + "*" + func_str + " PERIODIC=NO");
+     205             :   }
+     206           9 :   checkRead();
+     207             : 
+     208           9 : }
+     209             : 
+     210             : }
+     211             : }
+     212             : 
+     213             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/refdist/MahalanobisDistance.cpp.func-sort-c.html b/coverage/refdist/MahalanobisDistance.cpp.func-sort-c.html new file mode 100644 index 000000000000..33e45b6fa7ec --- /dev/null +++ b/coverage/refdist/MahalanobisDistance.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - refdist/MahalanobisDistance.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - refdist - MahalanobisDistance.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:6060100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7refdist19MahalanobisDistanceC2ERKNS_13ActionOptionsE0
_ZN4PLMD7refdist19MahalanobisDistanceC1ERKNS_13ActionOptionsE12
_ZN4PLMD7refdist19MahalanobisDistance16registerKeywordsERNS_8KeywordsE14
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/refdist/MahalanobisDistance.cpp.func.html b/coverage/refdist/MahalanobisDistance.cpp.func.html new file mode 100644 index 000000000000..0df1edf01f74 --- /dev/null +++ b/coverage/refdist/MahalanobisDistance.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - refdist/MahalanobisDistance.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - refdist - MahalanobisDistance.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:6060100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7refdist19MahalanobisDistance16registerKeywordsERNS_8KeywordsE14
_ZN4PLMD7refdist19MahalanobisDistanceC1ERKNS_13ActionOptionsE12
_ZN4PLMD7refdist19MahalanobisDistanceC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/refdist/MahalanobisDistance.cpp.gcov.html b/coverage/refdist/MahalanobisDistance.cpp.gcov.html new file mode 100644 index 000000000000..2e3d391353ba --- /dev/null +++ b/coverage/refdist/MahalanobisDistance.cpp.gcov.html @@ -0,0 +1,209 @@ + + + + + + + + LCOV - plumed test coverage - refdist/MahalanobisDistance.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - refdist - MahalanobisDistance.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:6060100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2018 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received 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 "core/ActionShortcut.h"
+      26             : #include "core/ActionWithValue.h"
+      27             : 
+      28             : //+PLUMEDOC FUNCTION MAHALANOBIS_DISTANCE
+      29             : /*
+      30             : Calculate the mahalanobis distance between two points in CV space
+      31             : 
+      32             : \par Examples
+      33             : 
+      34             : */
+      35             : //+ENDPLUMEDOC
+      36             : 
+      37             : namespace PLMD {
+      38             : namespace refdist {
+      39             : 
+      40             : class MahalanobisDistance : public ActionShortcut {
+      41             : public:
+      42             :   static void registerKeywords( Keywords& keys );
+      43             :   explicit MahalanobisDistance(const ActionOptions&ao);
+      44             : };
+      45             : 
+      46             : PLUMED_REGISTER_ACTION(MahalanobisDistance,"MAHALANOBIS_DISTANCE")
+      47             : 
+      48          14 : void MahalanobisDistance::registerKeywords( Keywords& keys ) {
+      49          14 :   ActionShortcut::registerKeywords(keys);
+      50          28 :   keys.add("compulsory","ARG1","The point that we are calculating the distance from");
+      51          28 :   keys.add("compulsory","ARG2","The point that we are calculating the distance to");
+      52          28 :   keys.add("compulsory","METRIC","The inverse covariance matrix that should be used when calculating the distance");
+      53          28 :   keys.addFlag("SQUARED",false,"The squared distance should be calculated");
+      54          28 :   keys.addFlag("VON_MISSES",false,"Compute the mahalanobis distance in a way that is more sympathetic to the periodic boundary conditions");
+      55          42 :   keys.needsAction("DISPLACEMENT"); keys.needsAction("CUSTOM"); keys.needsAction("OUTER_PRODUCT");
+      56          42 :   keys.needsAction("TRANSPOSE"); keys.needsAction("MATRIX_PRODUCT_DIAGONAL"); keys.needsAction("CONSTANT");
+      57          42 :   keys.needsAction("MATRIX_VECTOR_PRODUCT"); keys.needsAction("MATRIX_PRODUCT"); keys.needsAction("COMBINE");
+      58          14 : }
+      59             : 
+      60          12 : MahalanobisDistance::MahalanobisDistance( const ActionOptions& ao):
+      61             :   Action(ao),
+      62          12 :   ActionShortcut(ao)
+      63             : {
+      64          36 :   std::string arg1, arg2, metstr; parse("ARG1",arg1); parse("ARG2",arg2); parse("METRIC",metstr);
+      65             :   // Check on input metric
+      66          12 :   ActionWithValue* mav=plumed.getActionSet().selectWithLabel<ActionWithValue*>( metstr );
+      67          12 :   if( !mav ) error("could not find action named " + metstr + " to use for metric");
+      68          12 :   if( mav->copyOutput(0)->getRank()!=2 ) error("metric has incorrect rank");
+      69             : 
+      70          24 :   readInputLine( getShortcutLabel() + "_diff: DISPLACEMENT ARG1=" + arg1 + " ARG2=" + arg2 );
+      71          24 :   readInputLine( getShortcutLabel() + "_diffT: TRANSPOSE ARG=" + getShortcutLabel() + "_diff");
+      72          24 :   bool von_miss, squared; parseFlag("VON_MISSES",von_miss); parseFlag("SQUARED",squared);
+      73          12 :   if( von_miss ) {
+      74           7 :     unsigned nrows = mav->copyOutput(0)->getShape()[0];
+      75           7 :     if( mav->copyOutput(0)->getShape()[1]!=nrows ) error("metric is not symmetric");
+      76             :     // Create a matrix that can be used to compute the off diagonal elements
+      77             :     std::string valstr, nrstr;
+      78           7 :     Tools::convert( mav->copyOutput(0)->get(0), valstr ); Tools::convert( nrows, nrstr );
+      79           7 :     std::string diagmet = getShortcutLabel() + "_diagmet: CONSTANT VALUES=" + valstr;
+      80          14 :     std::string offdiagmet = getShortcutLabel() + "_offdiagmet: CONSTANT NROWS=" + nrstr + " NCOLS=" + nrstr + " VALUES=0";
+      81          21 :     for(unsigned i=0; i<nrows; ++i) {
+      82          42 :       for(unsigned j=0; j<nrows; ++j) {
+      83          28 :         Tools::convert( mav->copyOutput(0)->get(i*nrows+j), valstr );
+      84          42 :         if( i==j && i>0 ) { offdiagmet += ",0"; diagmet += "," + valstr; }
+      85          35 :         else if( i!=j ) { offdiagmet += "," + valstr; }
+      86             :       }
+      87             :     }
+      88           7 :     readInputLine( diagmet ); readInputLine( offdiagmet );
+      89             :     // Compute distances scaled by periods
+      90          14 :     ActionWithValue* av=plumed.getActionSet().selectWithLabel<ActionWithValue*>( getShortcutLabel() + "_diff" ); plumed_assert( av );
+      91           7 :     if( !av->copyOutput(0)->isPeriodic() ) error("VON_MISSES only works with periodic variables");
+      92           7 :     std::string min, max; av->copyOutput(0)->getDomain(min,max);
+      93          14 :     readInputLine( getShortcutLabel() + "_scaled: CUSTOM ARG=" + getShortcutLabel() + "_diffT FUNC=2*pi*x/(" + max +"-" + min + ") PERIODIC=NO");
+      94             :     // We start calculating off-diagonal elements by computing the sines of the scaled differences (this is a column vector)
+      95          14 :     readInputLine( getShortcutLabel() + "_sinediffT: CUSTOM ARG=" + getShortcutLabel() + "_scaled FUNC=sin(x) PERIODIC=NO");
+      96             :     // Transpose sines to get a row vector
+      97          14 :     readInputLine( getShortcutLabel() + "_sinediff: TRANSPOSE ARG=" + getShortcutLabel() + "_sinediffT");
+      98             :     // Compute the off diagonal elements
+      99          14 :     readInputLine( getShortcutLabel() + "_matvec: MATRIX_PRODUCT ARG=" + getShortcutLabel() + "_offdiagmet," + getShortcutLabel() +"_sinediffT");
+     100          14 :     readInputLine( getShortcutLabel() + "_offdiag: MATRIX_PRODUCT_DIAGONAL ARG=" + getShortcutLabel() + "_sinediff," + getShortcutLabel() +"_matvec");
+     101             :     // Sort out the metric for the diagonal elements
+     102           7 :     std::string metstr2 = getShortcutLabel() + "_diagmet";
+     103             :     // If this is a matrix we need create a matrix to multiply by
+     104           7 :     if( av->copyOutput(0)->getShape()[0]>1 ) {
+     105             :       // Create some ones
+     106          21 :       std::string ones=" VALUES=1"; for(unsigned i=1; i<av->copyOutput(0)->getShape()[0]; ++i ) ones += ",1";
+     107          14 :       readInputLine( getShortcutLabel() + "_ones: CONSTANT " + ones );
+     108             :       // Now do some multiplication to create a matrix that can be multiplied by our "inverse variance" vector
+     109          14 :       readInputLine( getShortcutLabel() + "_" + metstr + ": OUTER_PRODUCT ARG=" + metstr2 + "," + getShortcutLabel() + "_ones");
+     110          14 :       metstr2 = getShortcutLabel() + "_" + metstr;
+     111             :     }
+     112             :     // Compute the diagonal elements
+     113          14 :     readInputLine( getShortcutLabel() + "_prod: CUSTOM ARG=" + getShortcutLabel() + "_scaled," + metstr2 + " FUNC=2*(1-cos(x))*y PERIODIC=NO");
+     114           7 :     std::string ncstr; Tools::convert( nrows, ncstr ); Tools::convert( av->copyOutput(0)->getShape()[0], nrstr );
+     115          42 :     std::string ones=" VALUES=1"; for(unsigned i=1; i<av->copyOutput(0)->getNumberOfValues(); ++i) ones += ",1";
+     116          14 :     readInputLine( getShortcutLabel() + "_matones: CONSTANT NROWS=" + nrstr + " NCOLS=" + ncstr + ones );
+     117          14 :     readInputLine( getShortcutLabel() + "_diag: MATRIX_PRODUCT_DIAGONAL ARG=" + getShortcutLabel() + "_matones," + getShortcutLabel() + "_prod");
+     118             :     // Sum everything
+     119           7 :     if( !squared ) readInputLine( getShortcutLabel() + "_2: COMBINE ARG=" + getShortcutLabel() + "_offdiag," + getShortcutLabel() + "_diag PERIODIC=NO");
+     120          14 :     else readInputLine( getShortcutLabel() + ": COMBINE ARG=" + getShortcutLabel() + "_offdiag," + getShortcutLabel() + "_diag PERIODIC=NO");
+     121             :   } else {
+     122          10 :     ActionWithValue* av=plumed.getActionSet().selectWithLabel<ActionWithValue*>( getShortcutLabel() + "_diffT" ); plumed_assert( av && av->getNumberOfComponents()==1 );
+     123           9 :     if( (av->copyOutput(0))->getRank()==1 ) readInputLine( getShortcutLabel() + "_matvec: MATRIX_VECTOR_PRODUCT ARG=" + metstr + "," + getShortcutLabel() +"_diffT");
+     124           2 :     else readInputLine( getShortcutLabel() + "_matvec: MATRIX_PRODUCT ARG=" + metstr + "," + getShortcutLabel() +"_diffT");
+     125           5 :     std::string olab = getShortcutLabel(); if( !squared ) olab += "_2";
+     126          10 :     readInputLine( olab + ": MATRIX_PRODUCT_DIAGONAL ARG=" + getShortcutLabel() + "_diff," + getShortcutLabel() +"_matvec");
+     127             :   }
+     128          17 :   if( !squared ) readInputLine( getShortcutLabel() + ": CUSTOM ARG=" + getShortcutLabel() + "_2 FUNC=sqrt(x) PERIODIC=NO");
+     129          12 : }
+     130             : 
+     131             : }
+     132             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/refdist/MatrixProductDiagonal.cpp.func-sort-c.html b/coverage/refdist/MatrixProductDiagonal.cpp.func-sort-c.html new file mode 100644 index 000000000000..05f17680dc2d --- /dev/null +++ b/coverage/refdist/MatrixProductDiagonal.cpp.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - refdist/MatrixProductDiagonal.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - refdist - MatrixProductDiagonal.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:5959100.0 %
Date:2024-04-19 12:12:35Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7refdist21MatrixProductDiagonalC2ERKNS_13ActionOptionsE0
_ZN4PLMD7refdist21MatrixProductDiagonalC1ERKNS_13ActionOptionsE55
_ZN4PLMD7refdist21MatrixProductDiagonal16registerKeywordsERNS_8KeywordsE57
_ZN4PLMD7refdist21MatrixProductDiagonal22getNumberOfDerivativesEv2418
_ZN4PLMD7refdist21MatrixProductDiagonal9calculateEv2792
_ZNK4PLMD7refdist21MatrixProductDiagonal11performTaskERKjRNS_10MultiValueE119881
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/refdist/MatrixProductDiagonal.cpp.func.html b/coverage/refdist/MatrixProductDiagonal.cpp.func.html new file mode 100644 index 000000000000..78ed878d927c --- /dev/null +++ b/coverage/refdist/MatrixProductDiagonal.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - refdist/MatrixProductDiagonal.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - refdist - MatrixProductDiagonal.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:5959100.0 %
Date:2024-04-19 12:12:35Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7refdist21MatrixProductDiagonal16registerKeywordsERNS_8KeywordsE57
_ZN4PLMD7refdist21MatrixProductDiagonal22getNumberOfDerivativesEv2418
_ZN4PLMD7refdist21MatrixProductDiagonal9calculateEv2792
_ZN4PLMD7refdist21MatrixProductDiagonalC1ERKNS_13ActionOptionsE55
_ZN4PLMD7refdist21MatrixProductDiagonalC2ERKNS_13ActionOptionsE0
_ZNK4PLMD7refdist21MatrixProductDiagonal11performTaskERKjRNS_10MultiValueE119881
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/refdist/MatrixProductDiagonal.cpp.gcov.html b/coverage/refdist/MatrixProductDiagonal.cpp.gcov.html new file mode 100644 index 000000000000..14d52db70438 --- /dev/null +++ b/coverage/refdist/MatrixProductDiagonal.cpp.gcov.html @@ -0,0 +1,216 @@ + + + + + + + + LCOV - plumed test coverage - refdist/MatrixProductDiagonal.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - refdist - MatrixProductDiagonal.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:5959100.0 %
Date:2024-04-19 12:12:35Functions: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/ActionWithVector.h"
+      23             : #include "core/ActionRegister.h"
+      24             : 
+      25             : //+PLUMEDOC FUNCTION MATRIX_PRODUCT_DIAGONAL
+      26             : /*
+      27             : Calculate the product of two matrices and return a vector that contains the diagonal elements of the ouptut vector
+      28             : 
+      29             : \par Examples
+      30             : 
+      31             : */
+      32             : //+ENDPLUMEDOC
+      33             : 
+      34             : namespace PLMD {
+      35             : namespace refdist {
+      36             : 
+      37             : class MatrixProductDiagonal : public ActionWithVector {
+      38             : private:
+      39             : public:
+      40             :   static void registerKeywords( Keywords& keys );
+      41             :   explicit MatrixProductDiagonal(const ActionOptions&);
+      42             :   unsigned getNumberOfDerivatives() override ;
+      43             :   void calculate() override ;
+      44             :   void performTask( const unsigned& task_index, MultiValue& myvals ) const override ;
+      45             : };
+      46             : 
+      47             : PLUMED_REGISTER_ACTION(MatrixProductDiagonal,"MATRIX_PRODUCT_DIAGONAL")
+      48             : 
+      49          57 : void MatrixProductDiagonal::registerKeywords( Keywords& keys ) {
+      50          57 :   ActionWithVector::registerKeywords(keys); keys.use("ARG");
+      51          57 : }
+      52             : 
+      53          55 : MatrixProductDiagonal::MatrixProductDiagonal(const ActionOptions&ao):
+      54             :   Action(ao),
+      55          55 :   ActionWithVector(ao)
+      56             : {
+      57          55 :   if( getNumberOfArguments()!=2 ) error("should be two arguments to this action, a matrix and a vector");
+      58             : 
+      59             :   unsigned ncols;
+      60          55 :   if( getPntrToArgument(0)->getRank()==1 ) {
+      61           2 :     if( getPntrToArgument(0)->hasDerivatives() ) error("first argument to this action should be a vector or matrix");
+      62             :     ncols = 1;
+      63          53 :   } else if( getPntrToArgument(0)->getRank()==2 ) {
+      64          53 :     if( getPntrToArgument(0)->hasDerivatives() ) error("first argument to this action should be a matrix");
+      65          53 :     ncols = getPntrToArgument(0)->getShape()[1];
+      66             :   }
+      67             : 
+      68          55 :   if( getPntrToArgument(1)->getRank()==1 ) {
+      69          32 :     if( getPntrToArgument(1)->hasDerivatives() ) error("second argument to this action should be a vector or matrix");
+      70          32 :     if( ncols!=getPntrToArgument(1)->getShape()[0] ) error("number of columns in first matrix does not equal number of elements in vector");
+      71          32 :     if( getPntrToArgument(0)->getShape()[0]!=1 ) error("matrix output by this action must be square");
+      72          64 :     addValueWithDerivatives(); setNotPeriodic();
+      73             :   } else {
+      74          23 :     if( getPntrToArgument(1)->getRank()!=2 || getPntrToArgument(1)->hasDerivatives() ) error("second argument to this action should be a vector or a matrix");
+      75          23 :     if( ncols!=getPntrToArgument(1)->getShape()[0] ) error("number of columns in first matrix does not equal number of rows in second matrix");
+      76          23 :     if( getPntrToArgument(0)->getShape()[0]!=getPntrToArgument(1)->getShape()[1] ) error("matrix output by this action must be square");
+      77          23 :     std::vector<unsigned> shape(1); shape[0]=getPntrToArgument(0)->getShape()[0];
+      78          23 :     addValue( shape ); setNotPeriodic();
+      79             :   }
+      80          55 :   getPntrToArgument(0)->buildDataStore(); getPntrToArgument(1)->buildDataStore();
+      81          55 : }
+      82             : 
+      83        2418 : unsigned MatrixProductDiagonal::getNumberOfDerivatives() {
+      84        2418 :   if( doNotCalculateDerivatives() ) return 0;
+      85         108 :   return getPntrToArgument(0)->getNumberOfValues() + getPntrToArgument(1)->getNumberOfValues();;
+      86             : }
+      87             : 
+      88      119881 : void MatrixProductDiagonal::performTask( const unsigned& task_index, MultiValue& myvals ) const {
+      89      119881 :   unsigned ostrn = getConstPntrToComponent(0)->getPositionInStream();
+      90             :   Value* arg1 = getPntrToArgument(0); Value* arg2 = getPntrToArgument(1);
+      91      119881 :   if( arg1->getRank()==1 ) {
+      92          40 :     double val1 = arg1->get( task_index );
+      93          40 :     double val2 = arg2->get( task_index );
+      94          40 :     myvals.addValue( ostrn, val1*val2 );
+      95             : 
+      96          40 :     if( doNotCalculateDerivatives() ) return;
+      97             : 
+      98          40 :     myvals.addDerivative( ostrn, task_index, val2 );
+      99          40 :     myvals.updateIndex( ostrn, task_index );
+     100          40 :     unsigned nvals = getPntrToArgument(0)->getNumberOfValues();
+     101          40 :     myvals.addDerivative( ostrn, nvals + task_index, val1 );
+     102          40 :     myvals.updateIndex( ostrn, nvals + task_index );
+     103             :   } else {
+     104             :     unsigned nmult = arg1->getRowLength(task_index);
+     105      119841 :     unsigned nrowsA = getPntrToArgument(0)->getShape()[1];
+     106      119841 :     unsigned nrowsB = 1; if( getPntrToArgument(1)->getRank()>1 ) nrowsB = getPntrToArgument(1)->getShape()[1];
+     107      119841 :     unsigned nvals1 = getPntrToArgument(0)->getNumberOfValues();
+     108             : 
+     109             :     double matval = 0;
+     110     3025572 :     for(unsigned i=0; i<nmult; ++i) {
+     111             :       unsigned kind = arg1->getRowIndex( task_index, i );
+     112     2905731 :       double val1 = arg1->get( task_index*nrowsA + kind );
+     113     2905731 :       double val2 = arg2->get( kind*nrowsB + task_index );
+     114     2905731 :       matval += val1*val2;
+     115             : 
+     116     2905731 :       if( doNotCalculateDerivatives() ) continue;
+     117             : 
+     118     2836839 :       myvals.addDerivative( ostrn, task_index*nrowsA + kind, val2 );
+     119     2836839 :       myvals.updateIndex( ostrn, task_index*nrowsA + kind );
+     120     2836839 :       myvals.addDerivative( ostrn, nvals1 + kind*nrowsB + task_index, val1 );
+     121     2836839 :       myvals.updateIndex( ostrn, nvals1 + kind*nrowsB + task_index );
+     122             :     }
+     123             :     // And add this part of the product
+     124      119841 :     myvals.addValue( ostrn, matval );
+     125             :   }
+     126             : }
+     127             : 
+     128        2792 : void MatrixProductDiagonal::calculate() {
+     129        2792 :   if( getPntrToArgument(1)->getRank()==1 ) {
+     130        1179 :     unsigned nder = getNumberOfDerivatives();
+     131        1179 :     MultiValue myvals( 1, nder, 0, 0, 0 ); performTask( 0, myvals );
+     132             : 
+     133        1179 :     Value* myval=getPntrToComponent(0); myval->set( myvals.get(0) );
+     134        1329 :     for(unsigned i=0; i<nder; ++i) myval->setDerivative( i, myvals.getDerivative(0,i) );
+     135        2792 :   } else runAllTasks();
+     136        2792 : }
+     137             : 
+     138             : }
+     139             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/refdist/NormalizedEuclideanDistance.cpp.func-sort-c.html b/coverage/refdist/NormalizedEuclideanDistance.cpp.func-sort-c.html new file mode 100644 index 000000000000..3f2e82e9bcd4 --- /dev/null +++ b/coverage/refdist/NormalizedEuclideanDistance.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - refdist/NormalizedEuclideanDistance.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - refdist - NormalizedEuclideanDistance.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2828100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7refdist27NormalizedEuclideanDistanceC2ERKNS_13ActionOptionsE0
_ZN4PLMD7refdist27NormalizedEuclideanDistanceC1ERKNS_13ActionOptionsE8
_ZN4PLMD7refdist27NormalizedEuclideanDistance16registerKeywordsERNS_8KeywordsE10
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/refdist/NormalizedEuclideanDistance.cpp.func.html b/coverage/refdist/NormalizedEuclideanDistance.cpp.func.html new file mode 100644 index 000000000000..4bd6db7f243d --- /dev/null +++ b/coverage/refdist/NormalizedEuclideanDistance.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - refdist/NormalizedEuclideanDistance.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - refdist - NormalizedEuclideanDistance.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2828100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7refdist27NormalizedEuclideanDistance16registerKeywordsERNS_8KeywordsE10
_ZN4PLMD7refdist27NormalizedEuclideanDistanceC1ERKNS_13ActionOptionsE8
_ZN4PLMD7refdist27NormalizedEuclideanDistanceC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/refdist/NormalizedEuclideanDistance.cpp.gcov.html b/coverage/refdist/NormalizedEuclideanDistance.cpp.gcov.html new file mode 100644 index 000000000000..dcf97b83ac9a --- /dev/null +++ b/coverage/refdist/NormalizedEuclideanDistance.cpp.gcov.html @@ -0,0 +1,166 @@ + + + + + + + + LCOV - plumed test coverage - refdist/NormalizedEuclideanDistance.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - refdist - NormalizedEuclideanDistance.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2828100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2018 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received 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/ActionShortcut.h"
+      24             : #include "core/ActionWithValue.h"
+      25             : #include "core/PlumedMain.h"
+      26             : #include "core/ActionSet.h"
+      27             : 
+      28             : //+PLUMEDOC FUNCTION NORMALIZED_EUCLIDEAN_DISTANCE
+      29             : /*
+      30             : Calculate the normalised euclidean distance between two points in CV space
+      31             : 
+      32             : \par Examples
+      33             : 
+      34             : */
+      35             : //+ENDPLUMEDOC
+      36             : 
+      37             : namespace PLMD {
+      38             : namespace refdist {
+      39             : 
+      40             : class NormalizedEuclideanDistance : public ActionShortcut {
+      41             : public:
+      42             :   static void registerKeywords( Keywords& keys );
+      43             :   explicit NormalizedEuclideanDistance(const ActionOptions&ao);
+      44             : };
+      45             : 
+      46             : PLUMED_REGISTER_ACTION(NormalizedEuclideanDistance,"NORMALIZED_EUCLIDEAN_DISTANCE")
+      47             : 
+      48          10 : void NormalizedEuclideanDistance::registerKeywords( Keywords& keys ) {
+      49          10 :   ActionShortcut::registerKeywords(keys);
+      50          20 :   keys.add("compulsory","ARG1","The poin that we are calculating the distance from");
+      51          20 :   keys.add("compulsory","ARG2","The point that we are calculating the distance to");
+      52          20 :   keys.add("compulsory","METRIC","The inverse covariance matrix that should be used when calculating the distance");
+      53          20 :   keys.addFlag("SQUARED",false,"The squared distance should be calculated");
+      54          30 :   keys.needsAction("DISPLACEMENT"); keys.needsAction("CUSTOM"); keys.needsAction("OUTER_PRODUCT");
+      55          30 :   keys.needsAction("TRANSPOSE"); keys.needsAction("MATRIX_PRODUCT_DIAGONAL"); keys.needsAction("ONES");
+      56          10 : }
+      57             : 
+      58           8 : NormalizedEuclideanDistance::NormalizedEuclideanDistance( const ActionOptions& ao):
+      59             :   Action(ao),
+      60           8 :   ActionShortcut(ao)
+      61             : {
+      62          24 :   std::string arg1, arg2, metstr; parse("ARG1",arg1); parse("ARG2",arg2); parse("METRIC",metstr);
+      63             :   // Vectors are in rows here
+      64          16 :   readInputLine( getShortcutLabel() + "_diff: DISPLACEMENT ARG1=" + arg1 + " ARG2=" + arg2 );
+      65             :   // Vectors are in columns here
+      66          16 :   readInputLine( getShortcutLabel() + "_diffT: TRANSPOSE ARG=" + getShortcutLabel() + "_diff");
+      67             :   // Get the action that computes the differences
+      68          16 :   ActionWithValue* av = plumed.getActionSet().selectWithLabel<ActionWithValue*>( getShortcutLabel() + "_diffT"); plumed_assert( av );
+      69             :   // If this is a matrix we need create a matrix to multiply by
+      70           8 :   if( av->copyOutput(0)->getRank()==2 ) {
+      71             :     // Create some ones
+      72           4 :     std::string nones; Tools::convert( av->copyOutput(0)->getShape()[1], nones );
+      73           8 :     readInputLine( getShortcutLabel() + "_ones: ONES SIZE=" + nones);
+      74             :     // Now do some multiplication to create a matrix that can be multiplied by our "inverse variance" vector
+      75           4 :     if( av->copyOutput(0)->getShape()[0]==1 ) {
+      76           4 :       readInputLine( getShortcutLabel() + "_" + metstr + "T: CUSTOM ARG=" + metstr + "," + getShortcutLabel() + "_ones FUNC=x*y PERIODIC=NO");
+      77           4 :       readInputLine( getShortcutLabel() + "_" + metstr + ": TRANSPOSE ARG=" + getShortcutLabel() + "_" + metstr + "T");
+      78           4 :     } else readInputLine( getShortcutLabel() + "_" + metstr + ": OUTER_PRODUCT ARG=" + metstr + "," + getShortcutLabel() + "_ones");
+      79           8 :     metstr = getShortcutLabel() + "_" + metstr;
+      80             :   }
+      81             :   // Now do the multiplication
+      82          16 :   readInputLine( getShortcutLabel() + "_sdiff: CUSTOM ARG=" + metstr + "," + getShortcutLabel() +"_diffT FUNC=x*y PERIODIC=NO");
+      83          16 :   bool squared; parseFlag("SQUARED",squared); std::string olab = getShortcutLabel(); if( !squared ) olab += "_2";
+      84          16 :   readInputLine( olab + ": MATRIX_PRODUCT_DIAGONAL ARG=" + getShortcutLabel() +"_diff," + getShortcutLabel() + "_sdiff");
+      85          13 :   if( !squared ) readInputLine( getShortcutLabel() + ": CUSTOM ARG=" + getShortcutLabel() + "_2 FUNC=sqrt(x) PERIODIC=NO");
+      86           8 : }
+      87             : 
+      88             : }
+      89             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/refdist/index-sort-f.html b/coverage/refdist/index-sort-f.html new file mode 100644 index 000000000000..adb1cda8b03e --- /dev/null +++ b/coverage/refdist/index-sort-f.html @@ -0,0 +1,154 @@ + + + + + + + + LCOV - plumed test coverage - refdist + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - refdistHitTotalCoverage
Test:plumed test coverageLines:30533591.0 %
Date:2024-04-19 12:12:35Functions:212875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
NormalizedEuclideanDistance.cpp +
100.0%
+
100.0 %28 / 2866.7 %2 / 3
EuclideanDistance.cpp +
95.0%95.0%
+
95.0 %19 / 2066.7 %2 / 3
MahalanobisDistance.cpp +
100.0%
+
100.0 %60 / 6066.7 %2 / 3
Kernel.cpp +
78.3%78.3%
+
78.3 %83 / 10675.0 %3 / 4
Difference.cpp +
80.0%80.0%
+
80.0 %24 / 3075.0 %3 / 4
Displacement.cpp +
100.0%
+
100.0 %32 / 3280.0 %4 / 5
MatrixProductDiagonal.cpp +
100.0%
+
100.0 %59 / 5983.3 %5 / 6
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/refdist/index-sort-l.html b/coverage/refdist/index-sort-l.html new file mode 100644 index 000000000000..59fb9cd7bd2c --- /dev/null +++ b/coverage/refdist/index-sort-l.html @@ -0,0 +1,154 @@ + + + + + + + + LCOV - plumed test coverage - refdist + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - refdistHitTotalCoverage
Test:plumed test coverageLines:30533591.0 %
Date:2024-04-19 12:12:35Functions:212875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Kernel.cpp +
78.3%78.3%
+
78.3 %83 / 10675.0 %3 / 4
Difference.cpp +
80.0%80.0%
+
80.0 %24 / 3075.0 %3 / 4
EuclideanDistance.cpp +
95.0%95.0%
+
95.0 %19 / 2066.7 %2 / 3
NormalizedEuclideanDistance.cpp +
100.0%
+
100.0 %28 / 2866.7 %2 / 3
Displacement.cpp +
100.0%
+
100.0 %32 / 3280.0 %4 / 5
MatrixProductDiagonal.cpp +
100.0%
+
100.0 %59 / 5983.3 %5 / 6
MahalanobisDistance.cpp +
100.0%
+
100.0 %60 / 6066.7 %2 / 3
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/refdist/index.html b/coverage/refdist/index.html new file mode 100644 index 000000000000..bedecccc302a --- /dev/null +++ b/coverage/refdist/index.html @@ -0,0 +1,154 @@ + + + + + + + + LCOV - plumed test coverage - refdist + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - refdistHitTotalCoverage
Test:plumed test coverageLines:30533591.0 %
Date:2024-04-19 12:12:35Functions:212875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Difference.cpp +
80.0%80.0%
+
80.0 %24 / 3075.0 %3 / 4
Displacement.cpp +
100.0%
+
100.0 %32 / 3280.0 %4 / 5
EuclideanDistance.cpp +
95.0%95.0%
+
95.0 %19 / 2066.7 %2 / 3
Kernel.cpp +
78.3%78.3%
+
78.3 %83 / 10675.0 %3 / 4
MahalanobisDistance.cpp +
100.0%
+
100.0 %60 / 6066.7 %2 / 3
MatrixProductDiagonal.cpp +
100.0%
+
100.0 %59 / 5983.3 %5 / 6
NormalizedEuclideanDistance.cpp +
100.0%
+
100.0 %28 / 2866.7 %2 / 3
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ruby.png b/coverage/ruby.png new file mode 100644 index 0000000000000000000000000000000000000000..991b6d4ec9e78be165e3ef757eed1aada287364d GIT binary patch literal 141 zcmeAS@N?(olHy`uVBq!ia0vp^j3CU&3?x-=hn)ga>?NMQuI!iC1^FceV#7`HfI^%F z9+AZi4BSE>%y{W;-5;PJOS+@4BLl<6e(pbstUx|nfKQ0)e^Y%R^MdiLxj>4`)5S5Q b;#P73kj=!v_*DHKNFRfztDnm{r-UW|iOwIS literal 0 HcmV?d00001 diff --git a/coverage/s2cm/S2ContactModel.cpp.func-sort-c.html b/coverage/s2cm/S2ContactModel.cpp.func-sort-c.html new file mode 100644 index 000000000000..2e3ef8cd39ba --- /dev/null +++ b/coverage/s2cm/S2ContactModel.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - s2cm/S2ContactModel.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - s2cm - S2ContactModel.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:15116591.5 %
Date:2024-04-19 12:12:35Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4s2cm14S2ContactModelC2ERKNS_13ActionOptionsE0
_ZN4PLMD4s2cm14S2ContactModelD2Ev0
_ZN4PLMD4s2cm14S2ContactModelC1ERKNS_13ActionOptionsE24
_ZN4PLMD4s2cm14S2ContactModelD0Ev24
_ZN4PLMD4s2cm14S2ContactModelD1Ev24
_ZN4PLMD4s2cm14S2ContactModel16registerKeywordsERNS_8KeywordsE26
_ZN4PLMD4s2cm14S2ContactModel7prepareEv48
_ZN4PLMD4s2cm14S2ContactModel9calculateEv5952
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/s2cm/S2ContactModel.cpp.func.html b/coverage/s2cm/S2ContactModel.cpp.func.html new file mode 100644 index 000000000000..76aebac9e802 --- /dev/null +++ b/coverage/s2cm/S2ContactModel.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - s2cm/S2ContactModel.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - s2cm - S2ContactModel.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:15116591.5 %
Date:2024-04-19 12:12:35Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4s2cm14S2ContactModel16registerKeywordsERNS_8KeywordsE26
_ZN4PLMD4s2cm14S2ContactModel7prepareEv48
_ZN4PLMD4s2cm14S2ContactModel9calculateEv5952
_ZN4PLMD4s2cm14S2ContactModelC1ERKNS_13ActionOptionsE24
_ZN4PLMD4s2cm14S2ContactModelC2ERKNS_13ActionOptionsE0
_ZN4PLMD4s2cm14S2ContactModelD0Ev24
_ZN4PLMD4s2cm14S2ContactModelD1Ev24
_ZN4PLMD4s2cm14S2ContactModelD2Ev0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/s2cm/S2ContactModel.cpp.gcov.html b/coverage/s2cm/S2ContactModel.cpp.gcov.html new file mode 100644 index 000000000000..a3815eb93eb1 --- /dev/null +++ b/coverage/s2cm/S2ContactModel.cpp.gcov.html @@ -0,0 +1,402 @@ + + + + + + + + LCOV - plumed test coverage - s2cm/S2ContactModel.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - s2cm - S2ContactModel.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:15116591.5 %
Date:2024-04-19 12:12:35Functions:6875.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2017-2021 Omar Valsson
+       3             : 
+       4             :    This file is part of S2 contact model module
+       5             : 
+       6             :    The S2 contact model module is free software: you can redistribute it and/or modify
+       7             :    it under the terms of the GNU Lesser General Public License as published by
+       8             :    the Free Software Foundation, either version 3 of the License, or
+       9             :    (at your option) any later version.
+      10             : 
+      11             :    The S2 contact model module is distributed in the hope that it will be useful,
+      12             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      13             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      14             :    GNU Lesser General Public License for more details.
+      15             : 
+      16             :    You should have received a copy of the GNU Lesser General Public License
+      17             :    along with the S2 contact model module.  If not, see <http://www.gnu.org/licenses/>.
+      18             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      19             : 
+      20             : #include "colvar/Colvar.h"
+      21             : #include "tools/NeighborList.h"
+      22             : #include "tools/Communicator.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "core/PlumedMain.h"
+      25             : 
+      26             : 
+      27             : #include <string>
+      28             : #include <cmath>
+      29             : 
+      30             : namespace PLMD {
+      31             : namespace s2cm {
+      32             : 
+      33             : 
+      34             : //
+      35             : 
+      36             : //+PLUMEDOC S2CMMOD_COLVAR S2CM
+      37             : /*
+      38             : S2 contact model CV.
+      39             : 
+      40             : This CV was used in \cite Palazzesi_s2_2017, based on NH order parameter from \cite Zhang_s2_2002 and methyl order parameter from \cite Ming_s2_2004. Input parameters can be found in the relevant papers.
+      41             : 
+      42             : \par Examples
+      43             : 
+      44             : 
+      45             : */
+      46             : //+ENDPLUMEDOC
+      47             : 
+      48             : 
+      49             : 
+      50             : 
+      51             : 
+      52             : 
+      53             : 
+      54             : class S2ContactModel : public Colvar {
+      55             :   bool pbc_;
+      56             :   bool serial_;
+      57             :   std::unique_ptr<NeighborList> nl;
+      58             :   bool invalidateList;
+      59             :   bool firsttime;
+      60             :   //
+      61             :   double r_eff_;
+      62             :   double inv_r_eff_;
+      63             :   double prefactor_a_;
+      64             :   double exp_b_;
+      65             :   double offset_c_;
+      66             :   double n_i_;
+      67             :   double total_prefactor_;
+      68             :   double r_globalshift_;
+      69             : 
+      70             :   enum ModelType {methyl,nh} modeltype_;
+      71             : 
+      72             :   //
+      73             : public:
+      74             :   explicit S2ContactModel(const ActionOptions&);
+      75             :   ~S2ContactModel();
+      76             :   virtual void calculate();
+      77             :   virtual void prepare();
+      78             :   static void registerKeywords( Keywords& keys );
+      79             : };
+      80             : 
+      81             : PLUMED_REGISTER_ACTION(S2ContactModel,"S2CM")
+      82             : 
+      83          26 : void S2ContactModel::registerKeywords( Keywords& keys ) {
+      84          26 :   Colvar::registerKeywords(keys);
+      85          52 :   keys.addFlag("SERIAL",false,"Perform the calculation in serial - for debug purpose");
+      86          52 :   keys.addFlag("NLIST",false,"Use a neighbour list to speed up the calculation");
+      87          52 :   keys.add("optional","NL_CUTOFF","The cutoff for the neighbour list");
+      88          52 :   keys.add("optional","NL_STRIDE","The frequency with which we are updating the atoms in the neighbour list");
+      89          52 :   keys.add("atoms","METHYL_ATOM","the methyl carbon atom of the residue (i)");
+      90          52 :   keys.add("atoms","NH_ATOMS","the hydrogen atom of the NH group of the residue (i) and carbonyl oxygen of the preceding residue (i-1)");
+      91          52 :   keys.add("atoms","HEAVY_ATOMS","the heavy atoms to be included in the calculation");
+      92             :   //
+      93          52 :   keys.add("compulsory","R_EFF","the effective distance, r_eff in the equation, given in nm.");
+      94          52 :   keys.add("compulsory","PREFACTOR_A","the prefactor, a in the equation");
+      95          52 :   keys.add("compulsory","EXPONENT_B","the exponent, b in the equation");
+      96          52 :   keys.add("compulsory","OFFSET_C","the offset, c in the equation");
+      97          52 :   keys.add("compulsory","N_I"," n_i in the equation");
+      98          52 :   keys.add("optional","R_SHIFT","shift all distances by given amount");
+      99          26 : }
+     100             : 
+     101          24 : S2ContactModel::S2ContactModel(const ActionOptions&ao):
+     102             :   PLUMED_COLVAR_INIT(ao),
+     103          24 :   pbc_(true),
+     104          24 :   serial_(false),
+     105          24 :   invalidateList(true),
+     106          24 :   firsttime(true),
+     107          24 :   r_eff_(0.0),
+     108          24 :   inv_r_eff_(0.0),
+     109          24 :   prefactor_a_(0.0),
+     110          24 :   exp_b_(0.0),
+     111          24 :   offset_c_(0.0),
+     112          24 :   n_i_(0.0),
+     113          24 :   total_prefactor_(0.0),
+     114          24 :   r_globalshift_(0.0),
+     115          24 :   modeltype_(methyl)
+     116             : {
+     117             : 
+     118          48 :   parseFlag("SERIAL",serial_);
+     119             : 
+     120             :   std::vector<AtomNumber> methyl_atom;
+     121          48 :   parseAtomList("METHYL_ATOM",methyl_atom);
+     122             :   std::vector<AtomNumber> nh_atoms;
+     123          48 :   parseAtomList("NH_ATOMS",nh_atoms);
+     124             : 
+     125          24 :   if(methyl_atom.size()==0 && nh_atoms.size()==0) {
+     126           0 :     error("you have to give either METHYL_ATOM or NH_ATOMS");
+     127             :   }
+     128          24 :   if(methyl_atom.size()>0 && nh_atoms.size()>0) {
+     129           0 :     error("you cannot give both METHYL_ATOM or NH_ATOMS");
+     130             :   }
+     131          24 :   if(methyl_atom.size()>0 && methyl_atom.size()!=1) {
+     132           0 :     error("you should give one atom in METHYL_ATOM, the methyl carbon atom of the residue");
+     133             :   }
+     134          24 :   if(nh_atoms.size()>0 && nh_atoms.size()!=2) {
+     135           0 :     error("you should give two atoms in NH_ATOMS, the hydrogen atom of the NH group of the residue (i) and carbonyl oxygen of the preceding residue (i-1)");
+     136             :   }
+     137             : 
+     138             :   std::vector<AtomNumber> heavy_atoms;
+     139          48 :   parseAtomList("HEAVY_ATOMS",heavy_atoms);
+     140          24 :   if(heavy_atoms.size()==0) {
+     141           0 :     error("HEAVY_ATOMS is not given");
+     142             :   }
+     143             : 
+     144             :   std::vector<AtomNumber> main_atoms;
+     145          24 :   if(methyl_atom.size()>0) {
+     146           0 :     modeltype_= methyl;
+     147           0 :     main_atoms = methyl_atom;
+     148          24 :   } else if(nh_atoms.size()>0) {
+     149          24 :     modeltype_= nh;
+     150          24 :     main_atoms = nh_atoms;
+     151             :   }
+     152             : 
+     153          24 :   bool nopbc=!pbc_;
+     154          24 :   parseFlag("NOPBC",nopbc);
+     155          24 :   pbc_=!nopbc;
+     156             : 
+     157             :   // neighbor list stuff
+     158          24 :   bool doneigh=false;
+     159          24 :   double nl_cut=0.0;
+     160          24 :   int nl_st=0;
+     161          24 :   parseFlag("NLIST",doneigh);
+     162          24 :   if(doneigh) {
+     163          12 :     parse("NL_CUTOFF",nl_cut);
+     164          12 :     if(nl_cut<=0.0) error("NL_CUTOFF should be explicitly specified and positive");
+     165          12 :     parse("NL_STRIDE",nl_st);
+     166          12 :     if(nl_st<=0) error("NL_STRIDE should be explicitly specified and positive");
+     167             :   }
+     168             : 
+     169          24 :   parse("R_EFF",r_eff_);
+     170          24 :   inv_r_eff_ = 1.0/r_eff_;
+     171          24 :   parse("PREFACTOR_A",prefactor_a_);
+     172          24 :   parse("EXPONENT_B",exp_b_);
+     173          24 :   parse("OFFSET_C",offset_c_);
+     174             :   unsigned int n_i_int;
+     175          24 :   parse("N_I",n_i_int);
+     176          24 :   n_i_ = static_cast<double>(n_i_int);
+     177          24 :   total_prefactor_ = prefactor_a_/pow(n_i_,exp_b_);
+     178             :   //
+     179          24 :   parse("R_SHIFT",r_globalshift_);
+     180             : 
+     181          24 :   checkRead();
+     182             : 
+     183          24 :   addValueWithDerivatives();
+     184          24 :   setNotPeriodic();
+     185             : 
+     186          24 :   bool dopair=false;
+     187          24 :   if(doneigh) {
+     188          24 :     nl=Tools::make_unique<NeighborList>(main_atoms,heavy_atoms,serial_,dopair,pbc_,getPbc(),comm,nl_cut,nl_st);
+     189             :   }
+     190             :   else {
+     191          24 :     nl=Tools::make_unique<NeighborList>(main_atoms,heavy_atoms,serial_,dopair,pbc_,getPbc(),comm);
+     192             :   }
+     193             : 
+     194          24 :   requestAtoms(nl->getFullAtomList());
+     195             : 
+     196             : 
+     197          24 :   log.printf("  NMR S2 contact model CV, please read and cite ");
+     198          48 :   log << plumed.cite("Palazzesi, Valsson, and Parrinello, J. Phys. Chem. Lett. 8, 4752 (2017) - DOI:10.1021/acs.jpclett.7b01770");
+     199             : 
+     200          24 :   if(modeltype_==methyl) {
+     201           0 :     log << plumed.cite("Ming and Bruschweiler, J. Biomol. NMR, 29, 363 (2004) - DOI:10.1023/B:JNMR.0000032612.70767.35");
+     202           0 :     log.printf("\n");
+     203           0 :     log.printf("  calculation of methyl order parameter using atom %d \n",methyl_atom[0].serial());
+     204             :   }
+     205          24 :   else if(modeltype_==nh) {
+     206          48 :     log << plumed.cite("Zhang and Bruschweiler, J. Am. Chem. Soc. 124, 12654 (2002) - DOI:10.1021/ja027847a");
+     207          24 :     log.printf("\n");
+     208          24 :     log.printf("  calculation of NH order parameter using atoms %d and %d\n",nh_atoms[0].serial(),nh_atoms[1].serial());
+     209             :   }
+     210          24 :   log.printf("  heavy atoms used in the calculation (%u in total):\n",static_cast<unsigned int>(heavy_atoms.size()));
+     211        1872 :   for(unsigned int i=0; i<heavy_atoms.size(); ++i) {
+     212        1848 :     if( (i+1) % 25 == 0 ) {log.printf("  \n");}
+     213        1848 :     log.printf("  %d", heavy_atoms[i].serial());
+     214             :   }
+     215          24 :   log.printf("  \n");
+     216          24 :   log.printf("  total number of distances: %u\n",nl->size());
+     217             :   //
+     218          24 :   log.printf("  using parameters");
+     219          24 :   log.printf(" r_eff=%f,",r_eff_);
+     220          24 :   log.printf(" a=%f,",prefactor_a_);
+     221          24 :   log.printf(" b=%f,",exp_b_);
+     222          24 :   log.printf(" c=%f,",offset_c_);
+     223          24 :   log.printf(" n_i=%u",n_i_int);
+     224          24 :   if(r_globalshift_!=0.0) {
+     225           4 :     log.printf(", r_shift=%f",r_globalshift_);
+     226             :   }
+     227          24 :   log.printf("\n");
+     228          24 :   if(pbc_) {
+     229          12 :     log.printf("  using periodic boundary conditions\n");
+     230             :   } else {
+     231          12 :     log.printf("  without periodic boundary conditions\n");
+     232             :   }
+     233          24 :   if(doneigh) {
+     234          12 :     log.printf("  using neighbor lists with\n");
+     235          12 :     log.printf("  update every %d steps and cutoff %f\n",nl_st,nl_cut);
+     236             :   }
+     237          24 :   if(serial_) {
+     238           0 :     log.printf("  calculation done in serial\n");
+     239             :   }
+     240          24 : }
+     241             : 
+     242          48 : S2ContactModel::~S2ContactModel() {
+     243          48 : }
+     244             : 
+     245          48 : void S2ContactModel::prepare() {
+     246          48 :   if(nl->getStride()>0) {
+     247          24 :     if(firsttime || (getStep()%nl->getStride()==0)) {
+     248          24 :       requestAtoms(nl->getFullAtomList());
+     249          24 :       invalidateList=true;
+     250          24 :       firsttime=false;
+     251             :     } else {
+     252           0 :       requestAtoms(nl->getReducedAtomList());
+     253           0 :       invalidateList=false;
+     254           0 :       if(getExchangeStep()) error("Neighbor lists should be updated on exchange steps - choose a NL_STRIDE which divides the exchange stride!");
+     255             :     }
+     256          24 :     if(getExchangeStep()) firsttime=true;
+     257             :   }
+     258          48 : }
+     259             : 
+     260             : // calculator
+     261        5952 : void S2ContactModel::calculate() {
+     262             : 
+     263        5952 :   Tensor virial;
+     264        5952 :   std::vector<Vector> deriv(getNumberOfAtoms());
+     265             : 
+     266        5952 :   if(nl->getStride()>0 && invalidateList) {
+     267        2976 :     nl->update(getPositions());
+     268             :   }
+     269             : 
+     270        5952 :   unsigned int stride=comm.Get_size();
+     271        5952 :   unsigned int rank=comm.Get_rank();
+     272        5952 :   if(serial_) {
+     273             :     stride=1;
+     274             :     rank=0;
+     275             :   }
+     276             : 
+     277        5952 :   double contact_sum = 0.0;
+     278             : 
+     279        5952 :   const unsigned int nn=nl->size();
+     280             : 
+     281      321408 :   for(unsigned int i=rank; i<nn; i+=stride) {
+     282      315456 :     Vector distance;
+     283      315456 :     unsigned int i0=nl->getClosePair(i).first;
+     284      315456 :     unsigned int i1=nl->getClosePair(i).second;
+     285      315456 :     if(getAbsoluteIndex(i0)==getAbsoluteIndex(i1)) {continue;}
+     286             : 
+     287      315456 :     if(pbc_) {
+     288       86304 :       distance=pbcDistance(getPosition(i0),getPosition(i1));
+     289             :     } else {
+     290      229152 :       distance=delta(getPosition(i0),getPosition(i1));
+     291             :     }
+     292             : 
+     293      315456 :     double exp_arg = exp(-(distance.modulo()-r_globalshift_)*inv_r_eff_);
+     294      315456 :     contact_sum += exp_arg;
+     295             : 
+     296      315456 :     exp_arg /= distance.modulo();
+     297      315456 :     Vector dd(exp_arg*distance);
+     298      315456 :     Tensor vv(dd,distance);
+     299      315456 :     deriv[i0]-=dd;
+     300      315456 :     deriv[i1]+=dd;
+     301      315456 :     virial-=vv;
+     302             :   }
+     303             : 
+     304        5952 :   if(!serial_) {
+     305        5952 :     comm.Sum(contact_sum);
+     306        5952 :     if(!deriv.empty()) {
+     307        5952 :       comm.Sum(&deriv[0][0],3*deriv.size());
+     308             :     }
+     309        5952 :     comm.Sum(virial);
+     310             :   }
+     311             : 
+     312        5952 :   double value = tanh(total_prefactor_*contact_sum);
+     313             :   // using that d/dx[tanh(x)]= 1-[tanh(x)]^2
+     314        5952 :   double deriv_f = -inv_r_eff_*total_prefactor_*(1.0-value*value);
+     315        5952 :   value -= offset_c_;
+     316             : 
+     317      476160 :   for(unsigned int i=0; i<deriv.size(); ++i) {
+     318      470208 :     setAtomsDerivatives(i,deriv_f*deriv[i]);
+     319             :   }
+     320        5952 :   setValue(value);
+     321       11904 :   setBoxDerivatives(deriv_f*virial);
+     322             : 
+     323        5952 : }
+     324             : }
+     325             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/s2cm/index-sort-f.html b/coverage/s2cm/index-sort-f.html new file mode 100644 index 000000000000..e15fc6e91992 --- /dev/null +++ b/coverage/s2cm/index-sort-f.html @@ -0,0 +1,94 @@ + + + + + + + + LCOV - plumed test coverage - s2cm + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - s2cmHitTotalCoverage
Test:plumed test coverageLines:15116591.5 %
Date:2024-04-19 12:12:35Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
S2ContactModel.cpp +
91.5%91.5%
+
91.5 %151 / 16575.0 %6 / 8
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/s2cm/index-sort-l.html b/coverage/s2cm/index-sort-l.html new file mode 100644 index 000000000000..4b7c510040b2 --- /dev/null +++ b/coverage/s2cm/index-sort-l.html @@ -0,0 +1,94 @@ + + + + + + + + LCOV - plumed test coverage - s2cm + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - s2cmHitTotalCoverage
Test:plumed test coverageLines:15116591.5 %
Date:2024-04-19 12:12:35Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
S2ContactModel.cpp +
91.5%91.5%
+
91.5 %151 / 16575.0 %6 / 8
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/s2cm/index.html b/coverage/s2cm/index.html new file mode 100644 index 000000000000..7529ebf3d500 --- /dev/null +++ b/coverage/s2cm/index.html @@ -0,0 +1,94 @@ + + + + + + + + LCOV - plumed test coverage - s2cm + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - s2cmHitTotalCoverage
Test:plumed test coverageLines:15116591.5 %
Date:2024-04-19 12:12:35Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
S2ContactModel.cpp +
91.5%91.5%
+
91.5 %151 / 16575.0 %6 / 8
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/sasa/index-sort-f.html b/coverage/sasa/index-sort-f.html new file mode 100644 index 000000000000..4abbd9483fe0 --- /dev/null +++ b/coverage/sasa/index-sort-f.html @@ -0,0 +1,104 @@ + + + + + + + + LCOV - plumed test coverage - sasa + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - sasaHitTotalCoverage
Test:plumed test coverageLines:996121582.0 %
Date:2024-04-19 12:12:35Functions:212680.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
sasa_LCPO.cpp +
82.2%82.2%
+
82.2 %518 / 63076.9 %10 / 13
sasa_HASEL.cpp +
81.7%81.7%
+
81.7 %478 / 58584.6 %11 / 13
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/sasa/index-sort-l.html b/coverage/sasa/index-sort-l.html new file mode 100644 index 000000000000..548d55d6e739 --- /dev/null +++ b/coverage/sasa/index-sort-l.html @@ -0,0 +1,104 @@ + + + + + + + + LCOV - plumed test coverage - sasa + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - sasaHitTotalCoverage
Test:plumed test coverageLines:996121582.0 %
Date:2024-04-19 12:12:35Functions:212680.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
sasa_HASEL.cpp +
81.7%81.7%
+
81.7 %478 / 58584.6 %11 / 13
sasa_LCPO.cpp +
82.2%82.2%
+
82.2 %518 / 63076.9 %10 / 13
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/sasa/index.html b/coverage/sasa/index.html new file mode 100644 index 000000000000..ca809ddd981a --- /dev/null +++ b/coverage/sasa/index.html @@ -0,0 +1,104 @@ + + + + + + + + LCOV - plumed test coverage - sasa + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - sasaHitTotalCoverage
Test:plumed test coverageLines:996121582.0 %
Date:2024-04-19 12:12:35Functions:212680.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
sasa_HASEL.cpp +
81.7%81.7%
+
81.7 %478 / 58584.6 %11 / 13
sasa_LCPO.cpp +
82.2%82.2%
+
82.2 %518 / 63076.9 %10 / 13
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/sasa/sasa_HASEL.cpp.func-sort-c.html b/coverage/sasa/sasa_HASEL.cpp.func-sort-c.html new file mode 100644 index 000000000000..ce4c99b6bb8d --- /dev/null +++ b/coverage/sasa/sasa_HASEL.cpp.func-sort-c.html @@ -0,0 +1,125 @@ + + + + + + + + LCOV - plumed test coverage - sasa/sasa_HASEL.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - sasa - sasa_HASEL.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:47858581.7 %
Date:2024-04-19 12:12:35Functions:111384.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4sasa10SASA_HASEL13computeDeltaGEv0
_ZN4PLMD4sasa10SASA_HASELC2ERKNS_13ActionOptionsE0
_ZN4PLMD4sasa10SASA_HASEL10readDeltaGEv1
_ZN4PLMD4sasa10SASA_HASEL11readMaxSurfEv1
_ZN4PLMD4sasa10SASA_HASEL15setupMaxSurfMapB5cxx11Ev1
_ZN4PLMD4sasa10SASA_HASEL13readSASAparamEv2
_ZN4PLMD4sasa10SASA_HASEL15setupHASELparamB5cxx11Ev2
_ZN4PLMD4sasa10SASA_HASEL7readPDBEv2
_ZN4PLMD4sasa10SASA_HASELC1ERKNS_13ActionOptionsE2
_ZN4PLMD4sasa10SASA_HASEL16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD4sasa10SASA_HASEL9calcNlistEv24
_ZN4PLMD4sasa10SASA_HASEL9calculateEv24
_ZN4PLMD4sasa5splitISt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EEEEvRKS8_RT_42
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/sasa/sasa_HASEL.cpp.func.html b/coverage/sasa/sasa_HASEL.cpp.func.html new file mode 100644 index 000000000000..3829da01f36d --- /dev/null +++ b/coverage/sasa/sasa_HASEL.cpp.func.html @@ -0,0 +1,125 @@ + + + + + + + + LCOV - plumed test coverage - sasa/sasa_HASEL.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - sasa - sasa_HASEL.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:47858581.7 %
Date:2024-04-19 12:12:35Functions:111384.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4sasa10SASA_HASEL10readDeltaGEv1
_ZN4PLMD4sasa10SASA_HASEL11readMaxSurfEv1
_ZN4PLMD4sasa10SASA_HASEL13computeDeltaGEv0
_ZN4PLMD4sasa10SASA_HASEL13readSASAparamEv2
_ZN4PLMD4sasa10SASA_HASEL15setupHASELparamB5cxx11Ev2
_ZN4PLMD4sasa10SASA_HASEL15setupMaxSurfMapB5cxx11Ev1
_ZN4PLMD4sasa10SASA_HASEL16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD4sasa10SASA_HASEL7readPDBEv2
_ZN4PLMD4sasa10SASA_HASEL9calcNlistEv24
_ZN4PLMD4sasa10SASA_HASEL9calculateEv24
_ZN4PLMD4sasa10SASA_HASELC1ERKNS_13ActionOptionsE2
_ZN4PLMD4sasa10SASA_HASELC2ERKNS_13ActionOptionsE0
_ZN4PLMD4sasa5splitISt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EEEEvRKS8_RT_42
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/sasa/sasa_HASEL.cpp.gcov.html b/coverage/sasa/sasa_HASEL.cpp.gcov.html new file mode 100644 index 000000000000..7eccd68974ef --- /dev/null +++ b/coverage/sasa/sasa_HASEL.cpp.gcov.html @@ -0,0 +1,1089 @@ + + + + + + + + LCOV - plumed test coverage - sasa/sasa_HASEL.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - sasa - sasa_HASEL.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:47858581.7 %
Date:2024-04-19 12:12:35Functions:111384.6 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2021, Andrea Arsiccio
+       3             : 
+       4             : This software is provided 'as-is', without any express or implied
+       5             : warranty. In no event will the authors be held liable for any damages
+       6             : arising from the use of this software.
+       7             : 
+       8             : Permission is granted to anyone to use this software for any purpose,
+       9             : including commercial applications, and to alter it and redistribute it
+      10             : freely, subject to the following restrictions:
+      11             : 
+      12             : 1. The origin of this software must not be misrepresented; you must not
+      13             :    claim that you wrote the original software. If you use this software
+      14             :    in a product, an acknowledgment in the product documentation would be
+      15             :    appreciated but is not required.
+      16             : 2. Altered source versions must be plainly marked as such, and must not be
+      17             :    misrepresented as being the original software.
+      18             : 3. This notice may not be removed or altered from any source distribution.
+      19             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      20             : 
+      21             : #include "Sasa.h"
+      22             : #include "core/ActionRegister.h"
+      23             : #include "core/PlumedMain.h"
+      24             : #include "core/GenericMolInfo.h"
+      25             : #include "core/ActionSet.h"
+      26             : #include <cstdio>
+      27             : #include <iostream>
+      28             : #include <string>
+      29             : #include <cmath>
+      30             : #include <sstream>
+      31             : #include <algorithm>
+      32             : #include <iterator>
+      33             : #include <fstream>
+      34             : 
+      35             : 
+      36             : using namespace std;
+      37             : 
+      38             : namespace PLMD {
+      39             : namespace sasa {
+      40             : 
+      41             : //+PLUMEDOC SASAMOD_COLVAR SASA_HASEL
+      42             : /*
+      43             : Calculates the solvent accessible surface area (SASA) of a protein molecule, or other properties related to it.
+      44             : 
+      45             : The atoms for which the SASA is desired should be indicated with the keyword ATOMS, and a pdb file of the protein must be provided in input with the MOLINFO keyword. The algorithm described in \cite Hasel1988 is used for the calculation. The radius of the solvent is assumed to be 0.14 nm, which is the radius of water molecules. Using the keyword NL_STRIDE it is also possible to specify the frequency with which the neighbor list for the calculation of SASA is updated (the default is every 10 steps).
+      46             : 
+      47             : Different properties can be calculated and selected using the TYPE keyword:
+      48             : 
+      49             : 1) the total SASA (TOTAL);
+      50             : 
+      51             : 2) the free energy of transfer for the protein according to the transfer model (TRANSFER). This keyword can be used, for instance, to compute the transfer of a protein to different temperatures, as detailed in \cite Arsiccio-T-SASA-2021, or to different pressures, as detailed in \cite Arsiccio-P-SASA-2021, or to different osmolyte solutions, as detailed in \cite Arsiccio-C-SASA-2022.
+      52             : 
+      53             : 
+      54             : When the TRANSFER keyword is used, a file with the free energy of transfer values for the sidechains and backbone atoms should be provided (using the keyword DELTAGFILE). Such file should have the following format:
+      55             : 
+      56             : \verbatim
+      57             : 
+      58             : ----------------Sample DeltaG.dat file---------------------
+      59             : ALA     0.711019999999962
+      60             : ARG     -2.24832799999996
+      61             : ASN     -2.74838799999999
+      62             : ASP     -2.5626376
+      63             : CYS     3.89864000000006
+      64             : GLN     -1.76192
+      65             : GLU     -2.38664400000002
+      66             : GLY     0
+      67             : HIS     -3.58152799999999
+      68             : ILE     2.42634399999986
+      69             : LEU     1.77233599999988
+      70             : LYS     -1.92576400000002
+      71             : MET     -0.262827999999956
+      72             : PHE     1.62028800000007
+      73             : PRO     -2.15598800000001
+      74             : SER     -1.60934800000004
+      75             : THR     -0.591559999999987
+      76             : TRP     1.22936000000027
+      77             : TYR     0.775547999999958
+      78             : VAL     2.12779200000011
+      79             : BACKBONE        1.00066920000002
+      80             : -----------------------------------------------------------
+      81             : \endverbatim
+      82             : 
+      83             : where the second column is the free energy of transfer for each sidechain/backbone, in kJ/mol.
+      84             : 
+      85             : A Python script for the computation of free energy of transfer values to describe the effect of osmolyte concentration, temperature and pressure (according to \cite Arsiccio-C-SASA-2022, \cite Arsiccio-T-SASA-2021 and \cite Arsiccio-P-SASA-2021) is freely available at https://github.com/andrea-arsiccio/DeltaG-calculation. The script automatically outputs a DeltaG.dat file compatible with this SASA module.
+      86             : 
+      87             : 
+      88             : If the DELTAGFILE is not provided, the program computes the free energy of transfer values as if they had to take into account the effect of temperature according to approaches 2 or 3 in the paper \cite Arsiccio-T-SASA-2021. Please read and cite this paper if using the transfer model for computing the effect of temperature in implicit solvent simulations. For this purpose, the keyword APPROACH should be added, and set to either 2 or 3.
+      89             : 
+      90             : The SASA usually makes sense when atoms used for the calculation are all part of the same molecule. When running with periodic boundary conditions, the atoms should be in the proper periodic image. This is done automatically since PLUMED 2.2, by considering the ordered list of atoms and rebuilding the broken entities using a procedure that is equivalent to that done in \ref WHOLEMOLECULES. Notice that rebuilding is local to this action. This is different from \ref WHOLEMOLECULES which actually modifies the coordinates stored in PLUMED.
+      91             : 
+      92             : In case you want to recover the old behavior you should use the NOPBC flag.
+      93             : In that case you need to take care that atoms are in the correct periodic image.
+      94             : 
+      95             : The SASA may also be computed using the SASA_LCPO collective variable, which makes use of the LCPO algorithm \cite Weiser1999. SASA_LCPO is more accurate then SASA_HASEL, but the computation is slower.
+      96             : 
+      97             : 
+      98             : \par Examples
+      99             : 
+     100             : The following input tells plumed to print the total SASA for atoms 10 to 20 in a protein chain.
+     101             : \plumedfile
+     102             : SASA_HASEL TYPE=TOTAL ATOMS=10-20 NL_STRIDE=10 LABEL=sasa
+     103             : PRINT ARG=sasa STRIDE=1 FILE=colvar
+     104             : \endplumedfile
+     105             : 
+     106             : 
+     107             : The following input tells plumed to compute the transfer free energy for the protein chain containing atoms 10 to 20. Such transfer free energy is then used as a bias in the simulation (e.g., implicit solvent simulations). The free energy of transfer values are read from a file called DeltaG.dat.
+     108             : 
+     109             : \plumedfile
+     110             : SASA_HASEL TYPE=TRANSFER ATOMS=10-20 NL_STRIDE=10 DELTAGFILE=DeltaG.dat LABEL=sasa
+     111             : 
+     112             : bias: BIASVALUE ARG=sasa
+     113             : 
+     114             : PRINT ARG=sasa,bias.* STRIDE=1 FILE=colvar
+     115             : \endplumedfile
+     116             : 
+     117             : The following input tells plumed to compute the transfer free energy for the protein chain containing atoms 10 to 20. Such transfer free energy is then used as a bias in the simulation (e.g., implicit solvent simulations). The free energy of transfer values are computed according to \cite Arsiccio-T-SASA-2021, and take into account the effect of temperature using approach 2 as described in the paper.
+     118             : 
+     119             : \plumedfile
+     120             : SASA_HASEL TYPE=TRANSFER ATOMS=10-20 NL_STRIDE=10 APPROACH=2 LABEL=sasa
+     121             : 
+     122             : bias: BIASVALUE ARG=sasa
+     123             : 
+     124             : PRINT ARG=sasa,bias.* STRIDE=1 FILE=colvar
+     125             : \endplumedfile
+     126             : 
+     127             : */
+     128             : //+ENDPLUMEDOC
+     129             : 
+     130             : class SASA_HASEL : public Colvar {
+     131             : private:
+     132             :   enum CV_TYPE {TOTAL, TRANSFER};
+     133             :   int sasa_type;
+     134             :   bool nopbc;
+     135             :   double rs;
+     136             :   string DeltaGValues;
+     137             :   int approach;
+     138             :   unsigned stride;
+     139             :   unsigned nl_update;
+     140             :   int firstStepFlag;
+     141             :   double Ti;
+     142             :   // cppcheck-suppress duplInheritedMember
+     143             :   std::vector<AtomNumber> atoms;
+     144             :   vector < vector < std::string > > AtomResidueName;
+     145             :   vector < vector < double > > SASAparam;
+     146             :   vector < vector < std::string > > CONNECTparam;
+     147             :   unsigned natoms;
+     148             :   vector < vector < double > > MaxSurf;
+     149             :   vector < vector < double > > DeltaG;
+     150             :   vector < vector < int > > Nlist;
+     151             : public:
+     152             :   static void registerKeywords(Keywords& keys);
+     153             :   explicit SASA_HASEL(const ActionOptions&);
+     154             :   void readPDB();
+     155             :   map<string, vector<std::string> > setupHASELparam();
+     156             :   void readSASAparam();
+     157             :   void calcNlist();
+     158             :   map<string, vector<double> > setupMaxSurfMap();
+     159             :   void readMaxSurf();
+     160             :   void readDeltaG();
+     161             :   void computeDeltaG();
+     162             :   virtual void calculate();
+     163             : };
+     164             : 
+     165             : PLUMED_REGISTER_ACTION(SASA_HASEL,"SASA_HASEL")
+     166             : 
+     167           4 : void SASA_HASEL::registerKeywords(Keywords& keys) {
+     168           4 :   Colvar::registerKeywords(keys);
+     169           8 :   keys.add("atoms","ATOMS","the group of atoms that you are calculating the SASA for");
+     170           8 :   keys.add("compulsory","TYPE","TOTAL","The type of calculation you want to perform. Can be TOTAL or TRANSFER");
+     171           8 :   keys.add("compulsory", "NL_STRIDE", "The frequency with which the neighbor list for the calculation of SASA is updated.");
+     172           8 :   keys.add("optional","DELTAGFILE","a file containing the free energy of transfer values for backbone and sidechains atoms. Necessary only if TYPE = TRANSFER. A Python script for the computation of free energy of transfer values to describe the effect of osmolyte concentration, temperature and pressure is freely available at https://github.com/andrea-arsiccio/DeltaG-calculation. The script automatically outputs a DeltaG.dat file compatible with this SASA module. If TYPE = TRANSFER and no DELTAGFILE is provided, the free energy values are those describing the effect of temperature, and are computed using the temperature value passed by the MD engine");
+     173           8 :   keys.add("optional","APPROACH","either approach 2 or 3. Necessary only if TYPE = TRANSFER and no DELTAGFILE is provided. If TYPE = TRANSFER and no DELTAGFILE is provided, the free energy values are those describing the effect of temperature, and the program must know if approach 2 or 3 (as described in Arsiccio and Shea, Protein Cold Denaturation in Implicit Solvent Simulations: A Transfer Free Energy Approach, J. Phys. Chem. B, 2021) needs to be used to compute them");
+     174           4 : }
+     175             : 
+     176             : 
+     177           2 : SASA_HASEL::SASA_HASEL(const ActionOptions&ao):
+     178             :   PLUMED_COLVAR_INIT(ao),
+     179           2 :   nopbc(false),
+     180           2 :   stride(10),
+     181           2 :   nl_update(0),
+     182           4 :   DeltaGValues("absent"),
+     183           2 :   Ti(0),
+     184           2 :   firstStepFlag(0)
+     185             : {
+     186           2 :   rs = 0.14;
+     187           2 :   parse("DELTAGFILE",DeltaGValues);
+     188           2 :   parse("APPROACH", approach);
+     189           4 :   parseAtomList("ATOMS",atoms);
+     190           2 :   if(atoms.size()==0) error("no atoms specified");
+     191             :   std::string Type;
+     192           2 :   parse("TYPE",Type);
+     193           2 :   parse("NL_STRIDE", stride);
+     194           2 :   parseFlag("NOPBC",nopbc);
+     195           2 :   checkRead();
+     196             : 
+     197           2 :   if(Type=="TOTAL") sasa_type=TOTAL;
+     198           1 :   else if(Type=="TRANSFER") sasa_type=TRANSFER;
+     199           0 :   else error("Unknown SASA type");
+     200             : 
+     201           2 :   switch(sasa_type)
+     202             :   {
+     203           1 :   case TOTAL:   log.printf("  TOTAL SASA;"); break;
+     204           1 :   case TRANSFER: log.printf("  TRANSFER MODEL;"); break;
+     205             :   }
+     206             : 
+     207           2 :   log.printf("  atoms involved : ");
+     208         242 :   for(unsigned i=0; i<atoms.size(); ++i) {
+     209         240 :     if(i%25==0) log<<"\n";
+     210         240 :     log.printf("%d ",atoms[i].serial());
+     211             :   }
+     212           2 :   log.printf("\n");
+     213             : 
+     214           2 :   if(nopbc) {
+     215           0 :     log<<"  PBC will be ignored\n";
+     216             :   } else {
+     217           2 :     log<<"  broken molecules will be rebuilt assuming atoms are in the proper order\n";
+     218             :   }
+     219             : 
+     220             : 
+     221           4 :   addValueWithDerivatives(); setNotPeriodic();
+     222           2 :   requestAtoms(atoms);
+     223             : 
+     224           2 :   natoms = getNumberOfAtoms();
+     225           2 :   AtomResidueName.resize(2);
+     226           2 :   SASAparam.resize(natoms);
+     227           2 :   CONNECTparam.resize(natoms);
+     228           2 :   MaxSurf.resize(natoms);
+     229           2 :   DeltaG.resize(natoms+1);
+     230           2 :   Nlist.resize(natoms);
+     231             : 
+     232             : 
+     233           2 : }
+     234             : 
+     235             : 
+     236             : //splits strings into tokens. Used to read into SASA parameters file and into reference pdb file
+     237             : template <class Container>
+     238          42 : void split(const std::string& str, Container& cont)
+     239             : {
+     240          42 :   std::istringstream iss(str);
+     241          84 :   std::copy(std::istream_iterator<std::string>(iss),
+     242          42 :             std::istream_iterator<std::string>(),
+     243             :             std::back_inserter(cont));
+     244          42 : }
+     245             : 
+     246             : 
+     247             : //reads input PDB file provided with MOLINFO, and assigns atom and residue names to each atom involved in the CV
+     248             : 
+     249           2 : void SASA_HASEL::readPDB() {
+     250           2 :   auto* moldat = plumed.getActionSet().selectLatest<GenericMolInfo*>(this);
+     251           2 :   if( ! moldat ) error("Unable to find MOLINFO in input");
+     252             :   AtomResidueName[0].clear();
+     253             :   AtomResidueName[1].clear();
+     254             : 
+     255         242 :   for(unsigned i=0; i<natoms; i++) {
+     256         240 :     string Aname = moldat->getAtomName(atoms[i]);
+     257         240 :     string Rname = moldat->getResidueName(atoms[i]);
+     258         240 :     AtomResidueName[0].push_back (Aname);
+     259         240 :     AtomResidueName[1].push_back (Rname);
+     260             :   }
+     261             : 
+     262           2 : }
+     263             : 
+     264             : 
+     265             : //Hasel et al. parameters database
+     266           2 : map<string, vector<std::string> > SASA_HASEL::setupHASELparam() {
+     267             :   map<string, vector<std::string> > haselmap;
+     268          16 :   haselmap["ALA_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     269          16 :   haselmap["ALA_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     270          16 :   haselmap["ALA_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     271          16 :   haselmap["ALA_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     272          16 :   haselmap["ALA_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     273          16 :   haselmap["ALA_CB"] = { "2.0",  "0.88",  "CA",  "Z",  "Z",  "Z", };
+     274          16 :   haselmap["ASP_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     275          16 :   haselmap["ASP_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     276          16 :   haselmap["ASP_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     277          16 :   haselmap["ASP_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     278          16 :   haselmap["ASP_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     279          16 :   haselmap["ASP_CB"] = { "1.9",  "1.045",  "CA",  "CG",  "Z",  "Z", };
+     280          16 :   haselmap["ASP_CG"] = { "1.72",  "1.554",  "CB",  "OD1",  "OD2",  "Z", };
+     281          16 :   haselmap["ASP_OD1"] = { "1.5",  "0.926",  "CG",  "Z",  "Z",  "Z", };
+     282          16 :   haselmap["ASP_OD2"] = { "1.7",  "0.922",  "CG",  "Z",  "Z",  "Z", };
+     283          16 :   haselmap["ASN_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     284          16 :   haselmap["ASN_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     285          16 :   haselmap["ASN_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     286          16 :   haselmap["ASN_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     287          16 :   haselmap["ASN_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     288          16 :   haselmap["ASN_CB"] = { "1.9",  "1.045",  "CA",  "CG",  "Z",  "Z", };
+     289          16 :   haselmap["ASN_CG"] = { "1.7",  "2.149",  "CB",  "OD1",  "ND2",  "Z", };
+     290          16 :   haselmap["ASN_OD1"] = { "1.5",  "0.926",  "CG",  "Z",  "Z",  "Z", };
+     291          16 :   haselmap["ASN_ND2"] = { "1.6",  "1.215",  "CG",  "1HD2",  "1HD2",  "Z", };
+     292          16 :   haselmap["ASN_1HD2"] = { "1.1",  "1.128",  "ND2",  "Z",  "Z",  "Z", };
+     293          16 :   haselmap["ASN_2HD2"] = { "1.1",  "1.128",  "ND2",  "Z",  "Z",  "Z", };
+     294          16 :   haselmap["ARG_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     295          16 :   haselmap["ARG_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     296          16 :   haselmap["ARG_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     297          16 :   haselmap["ARG_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     298          16 :   haselmap["ARG_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     299          16 :   haselmap["ARG_CB"] = { "1.9",  "1.045",  "CA",  "CG",  "Z",  "Z", };
+     300          16 :   haselmap["ARG_CG"] = { "1.9",  "1.045",  "CB",  "CD",  "Z",  "Z", };
+     301          16 :   haselmap["ARG_CD"] = { "1.9",  "1.045",  "CG",  "NE",  "Z",  "Z", };
+     302          16 :   haselmap["ARG_NE"] = { "1.55",  "1.028",  "CD",  "HE",  "CZ",  "Z", };
+     303          16 :   haselmap["ARG_NH1"] = { "1.55",  "1.028",  "CZ",  "1HH1",  "2HH1",  "Z", };
+     304          16 :   haselmap["ARG_NH2"] = { "1.55",  "1.028",  "CZ",  "1HH2",  "2HH2",  "Z", };
+     305          16 :   haselmap["ARG_CZ"] = { "1.72",  "1.554",  "NE",  "NH1",  "NH2",  "Z", };
+     306          16 :   haselmap["ARG_HE"] = { "1.1",  "1.128",  "NE",  "Z",  "Z",  "Z", };
+     307          16 :   haselmap["ARG_1HH2"] = { "1.1",  "1.128",  "NH2",  "Z",  "Z",  "Z", };
+     308          16 :   haselmap["ARG_2HH2"] = { "1.1",  "1.128",  "NH2",  "Z",  "Z",  "Z", };
+     309          16 :   haselmap["ARG_2HH1"] = { "1.1",  "1.128",  "NH1",  "Z",  "Z",  "Z", };
+     310          16 :   haselmap["ARG_1HH1"] = { "1.1",  "1.128",  "NH1",  "Z",  "Z",  "Z", };
+     311          16 :   haselmap["CYS_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     312          16 :   haselmap["CYS_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     313          16 :   haselmap["CYS_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     314          16 :   haselmap["CYS_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     315          16 :   haselmap["CYS_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     316          16 :   haselmap["CYS_CB"] = { "1.9",  "1.045",  "CA",  "SG",  "Z",  "Z", };
+     317          16 :   haselmap["CYS_SG"] = { "1.8",  "1.121",  "CB",  "HG",  "Z",  "Z", };
+     318          16 :   haselmap["CYS_HG"] = { "1.2",  "0.928",  "SG",  "Z",  "Z",  "Z", };
+     319          16 :   haselmap["GLU_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     320          16 :   haselmap["GLU_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     321          16 :   haselmap["GLU_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     322          16 :   haselmap["GLU_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     323          16 :   haselmap["GLU_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     324          16 :   haselmap["GLU_CB"] = { "1.9",  "1.045",  "CA",  "CG",  "Z",  "Z", };
+     325          16 :   haselmap["GLU_CG"] = { "1.9",  "1.045",  "CB",  "CD",  "Z",  "Z", };
+     326          16 :   haselmap["GLU_CD"] = { "1.72",  "1.554",  "CG",  "OE1",  "OE2",  "Z", };
+     327          16 :   haselmap["GLU_OE1"] = { "1.5",  "0.926",  "CD",  "Z",  "Z",  "Z", };
+     328          16 :   haselmap["GLU_OE2"] = { "1.7",  "0.922",  "CD",  "Z",  "Z",  "Z", };
+     329          16 :   haselmap["GLN_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     330          16 :   haselmap["GLN_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     331          16 :   haselmap["GLN_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     332          16 :   haselmap["GLN_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     333          16 :   haselmap["GLN_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     334          16 :   haselmap["GLN_CB"] = { "1.9",  "1.045",  "CA",  "CG",  "Z",  "Z", };
+     335          16 :   haselmap["GLN_CG"] = { "1.9",  "1.045",  "CB",  "CD",  "Z",  "Z", };
+     336          16 :   haselmap["GLN_CD"] = { "1.72",  "1.554",  "CG",  "OE1",  "NE2",  "Z", };
+     337          16 :   haselmap["GLN_OE1"] = { "1.5",  "0.926",  "CD",  "Z",  "Z",  "Z", };
+     338          16 :   haselmap["GLN_NE2"] = { "1.6",  "1.215",  "CD",  "2HE2",  "1HE2",  "Z", };
+     339          16 :   haselmap["GLN_2HE2"] = { "1.1",  "1.128",  "NE2",  "Z",  "Z",  "Z", };
+     340          16 :   haselmap["GLN_1HE2"] = { "1.1",  "1.128",  "NE2",  "Z",  "Z",  "Z", };
+     341          16 :   haselmap["GLY_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     342          16 :   haselmap["GLY_CA"] = { "1.7",  "2.149",  "N",  "C",  "Z",  "Z", };
+     343          16 :   haselmap["GLY_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     344          16 :   haselmap["GLY_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     345          16 :   haselmap["GLY_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     346          16 :   haselmap["HIS_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     347          16 :   haselmap["HIS_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     348          16 :   haselmap["HIS_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     349          16 :   haselmap["HIS_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     350          16 :   haselmap["HIS_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     351          16 :   haselmap["HIS_CB"] = { "1.9",  "1.045",  "CA",  "CG",  "Z",  "Z", };
+     352          16 :   haselmap["HIS_CG"] = { "1.72",  "1.554",  "CB",  "CD2",  "ND1",  "Z", };
+     353          16 :   haselmap["HIS_ND1"] = { "1.55",  "1.028",  "CG",  "CE1",  "Z",  "Z", };
+     354          16 :   haselmap["HIS_CE1"] = { "1.8",  "1.073",  "ND1",  "NE2",  "Z",  "Z", };
+     355          16 :   haselmap["HIS_NE2"] = { "1.55",  "1.413",  "CE1",  "2HE",  "CD2",  "Z", };
+     356          16 :   haselmap["HIS_CD2"] = { "1.8",  "1.073",  "NE2",  "CG",  "Z",  "Z", };
+     357          16 :   haselmap["HIS_2HE"] = { "1.1",  "1.128",  "NE2",  "Z",  "Z",  "Z", };
+     358          16 :   haselmap["ILE_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     359          16 :   haselmap["ILE_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     360          16 :   haselmap["ILE_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     361          16 :   haselmap["ILE_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     362          16 :   haselmap["ILE_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     363          16 :   haselmap["ILE_CB"] = { "1.8",  "1.276",  "CA",  "CG2",  "CG1",  "Z", };
+     364          16 :   haselmap["ILE_CG2"] = { "2.0",  "0.88",  "CB",  "Z",  "Z",  "Z", };
+     365          16 :   haselmap["ILE_CG1"] = { "1.9",  "1.045",  "CB",  "CD1",  "Z",  "Z", };
+     366          16 :   haselmap["ILE_CD1"] = { "2.0",  "0.88",  "CG1",  "Z",  "Z",  "Z", };
+     367          16 :   haselmap["LEU_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     368          16 :   haselmap["LEU_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     369          16 :   haselmap["LEU_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     370          16 :   haselmap["LEU_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     371          16 :   haselmap["LEU_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     372          16 :   haselmap["LEU_CB"] = { "1.9",  "1.045",  "CA",  "CG",  "Z",  "Z", };
+     373          16 :   haselmap["LEU_CG"] = { "1.8",  "1.276",  "CB",  "CD1",  "CD2",  "Z", };
+     374          16 :   haselmap["LEU_CD1"] = { "2.0",  "0.88",  "CG",  "Z",  "Z",  "Z", };
+     375          16 :   haselmap["LEU_CD2"] = { "2.0",  "0.88",  "CG",  "Z",  "Z",  "Z", };
+     376          16 :   haselmap["LYS_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     377          16 :   haselmap["LYS_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     378          16 :   haselmap["LYS_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     379          16 :   haselmap["LYS_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     380          16 :   haselmap["LYS_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     381          16 :   haselmap["LYS_CB"] = { "1.9",  "1.045",  "CA",  "CG",  "Z",  "Z", };
+     382          16 :   haselmap["LYS_CG"] = { "1.9",  "1.045",  "CB",  "CD",  "Z",  "Z", };
+     383          16 :   haselmap["LYS_CD"] = { "1.9",  "1.045",  "CG",  "CE",  "Z",  "Z", };
+     384          16 :   haselmap["LYS_CE"] = { "1.9",  "1.045",  "CD",  "NZ",  "Z",  "Z", };
+     385          16 :   haselmap["LYS_NZ"] = { "1.6",  "1.215",  "CE",  "1HZ",  "2HZ",  "3HZ", };
+     386          16 :   haselmap["LYS_1HZ"] = { "1.1",  "1.128",  "NZ",  "Z",  "Z",  "Z", };
+     387          16 :   haselmap["LYS_2HZ"] = { "1.1",  "1.128",  "NZ",  "Z",  "Z",  "Z", };
+     388          16 :   haselmap["LYS_3HZ"] = { "1.1",  "1.128",  "NZ",  "Z",  "Z",  "Z", };
+     389          16 :   haselmap["MET_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     390          16 :   haselmap["MET_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     391          16 :   haselmap["MET_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     392          16 :   haselmap["MET_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     393          16 :   haselmap["MET_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     394          16 :   haselmap["MET_CB"] = { "1.9",  "1.045",  "CA",  "CG",  "Z",  "Z", };
+     395          16 :   haselmap["MET_CG"] = { "1.9",  "1.045",  "CB",  "SD",  "Z",  "Z", };
+     396          16 :   haselmap["MET_SD"] = { "1.8",  "1.121",  "CG",  "CE",  "Z",  "Z", };
+     397          16 :   haselmap["MET_CE"] = { "2.0",  "0.88",  "SD",  "Z",  "Z",  "Z", };
+     398          16 :   haselmap["PHE_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     399          16 :   haselmap["PHE_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     400          16 :   haselmap["PHE_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     401          16 :   haselmap["PHE_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     402          16 :   haselmap["PHE_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     403          16 :   haselmap["PHE_CB"] = { "1.9",  "1.045",  "CA",  "CG",  "Z",  "Z", };
+     404          16 :   haselmap["PHE_CG"] = { "1.72",  "1.554",  "CB",  "CD1",  "CD2",  "Z", };
+     405          16 :   haselmap["PHE_CD1"] = { "1.8",  "1.073",  "CG",  "CE1",  "Z",  "Z", };
+     406          16 :   haselmap["PHE_CE1"] = { "1.8",  "1.073",  "CD1",  "CZ",  "Z",  "Z", };
+     407          16 :   haselmap["PHE_CZ"] = { "1.8",  "1.073",  "CE1",  "CE2",  "Z",  "Z", };
+     408          16 :   haselmap["PHE_CE2"] = { "1.8",  "1.073",  "CZ",  "CD2",  "Z",  "Z", };
+     409          16 :   haselmap["PHE_CD2"] = { "1.8",  "1.073",  "CE2",  "CG",  "Z",  "Z", };
+     410          16 :   haselmap["PRO_N"] = { "1.55",  "1.028",  "CD",  "CA",  "Z",  "Z", };
+     411          16 :   haselmap["PRO_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     412          16 :   haselmap["PRO_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     413          16 :   haselmap["PRO_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     414          16 :   haselmap["PRO_CB"] = { "1.9",  "1.045",  "CA",  "CG",  "Z",  "Z", };
+     415          16 :   haselmap["PRO_CG"] = { "1.9",  "1.045",  "CB",  "CD",  "Z",  "Z", };
+     416          16 :   haselmap["PRO_CD"] = { "1.9",  "1.045",  "CG",  "N",  "Z",  "Z", };
+     417          16 :   haselmap["SER_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     418          16 :   haselmap["SER_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     419          16 :   haselmap["SER_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     420          16 :   haselmap["SER_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     421          16 :   haselmap["SER_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     422          16 :   haselmap["SER_CB"] = { "1.9",  "1.045",  "CA",  "OG",  "Z",  "Z", };
+     423          16 :   haselmap["SER_OG"] = { "1.52",  "1.08",  "CB",  "HG",  "Z",  "Z", };
+     424          16 :   haselmap["SER_HG"] = { "1.0",  "0.944",  "OG",  "Z",  "Z",  "Z", };
+     425          16 :   haselmap["THR_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     426          16 :   haselmap["THR_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     427          16 :   haselmap["THR_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     428          16 :   haselmap["THR_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     429          16 :   haselmap["THR_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     430          16 :   haselmap["THR_CB"] = { "1.8",  "1.276",  "CA",  "CG2",  "OG1",  "Z", };
+     431          16 :   haselmap["THR_CG2"] = { "2.0",  "0.88",  "CB",  "Z",  "Z",  "Z", };
+     432          16 :   haselmap["THR_OG1"] = { "1.52",  "1.08",  "1HG",  "CB",  "Z",  "Z", };
+     433          16 :   haselmap["THR_1HG"] = { "1.0",  "0.944",  "OG1",  "Z",  "Z",  "Z", };
+     434          16 :   haselmap["TRP_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     435          16 :   haselmap["TRP_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     436          16 :   haselmap["TRP_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     437          16 :   haselmap["TRP_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     438          16 :   haselmap["TRP_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     439          16 :   haselmap["TRP_CB"] = { "1.9",  "1.045",  "CA",  "CG",  "Z",  "Z", };
+     440          16 :   haselmap["TRP_CG"] = { "1.72",  "1.554",  "CB",  "CD2",  "CD1",  "Z", };
+     441          16 :   haselmap["TRP_CD1"] = { "1.8",  "1.073",  "CG",  "NE1",  "Z",  "Z", };
+     442          16 :   haselmap["TRP_NE1"] = { "1.55",  "1.413",  "CD1",  "CE2",  "1HE",  "Z", };
+     443          16 :   haselmap["TRP_CE2"] = { "1.72",  "1.554",  "NE1",  "CD2",  "CZ2",  "Z", };
+     444          16 :   haselmap["TRP_CZ2"] = { "1.8",  "1.073",  "CE2",  "CH2",  "Z",  "Z", };
+     445          16 :   haselmap["TRP_CH2"] = { "1.8",  "1.073",  "CZ2",  "CZ3",  "Z",  "Z", };
+     446          16 :   haselmap["TRP_CZ3"] = { "1.8",  "1.073",  "CH2",  "CE3",  "Z",  "Z", };
+     447          16 :   haselmap["TRP_CE3"] = { "1.8",  "1.073",  "CZ3",  "CD2",  "Z",  "Z", };
+     448          16 :   haselmap["TRP_CD2"] = { "1.72",  "1.554",  "CE3",  "CE2",  "CG",  "Z", };
+     449          16 :   haselmap["TRP_1HE"] = { "1.1",  "1.128",  "NE1",  "Z",  "Z",  "Z", };
+     450          16 :   haselmap["TYR_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     451          16 :   haselmap["TYR_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     452          16 :   haselmap["TYR_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     453          16 :   haselmap["TYR_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     454          16 :   haselmap["TYR_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     455          16 :   haselmap["TYR_CB"] = { "1.9",  "1.045",  "CA",  "CG",  "Z",  "Z", };
+     456          16 :   haselmap["TYR_CG"] = { "1.72",  "1.554",  "CB",  "CD1",  "CD2",  "Z", };
+     457          16 :   haselmap["TYR_CD1"] = { "1.8",  "1.073",  "CG",  "CE1",  "Z",  "Z", };
+     458          16 :   haselmap["TYR_CE1"] = { "1.8",  "1.073",  "CD1",  "CZ",  "Z",  "Z", };
+     459          16 :   haselmap["TYR_CZ"] = { "1.72",  "1.554",  "CE1",  "OH",  "CE2",  "Z", };
+     460          16 :   haselmap["TYR_OH"] = { "1.52",  "1.08",  "CZ",  "HH",  "Z",  "Z", };
+     461          16 :   haselmap["TYR_HH"] = { "1.0",  "0.944",  "OH",  "Z",  "Z",  "Z", };
+     462          16 :   haselmap["TYR_CE2"] = { "1.8",  "1.073",  "CZ",  "CD2",  "Z",  "Z", };
+     463          16 :   haselmap["TYR_CD2"] = { "1.8",  "1.073",  "CE2",  "CG",  "Z",  "Z", };
+     464          16 :   haselmap["VAL_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     465          16 :   haselmap["VAL_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     466          16 :   haselmap["VAL_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     467          16 :   haselmap["VAL_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     468          16 :   haselmap["VAL_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     469          16 :   haselmap["VAL_CB"] = { "1.8",  "1.276",  "CA",  "CG1",  "CG2",  "Z", };
+     470          16 :   haselmap["VAL_CG1"] = { "2.0",  "0.88",  "CB",  "Z",  "Z",  "Z", };
+     471          16 :   haselmap["VAL_CG2"] = { "2.0",  "0.88",  "CB",  "Z",  "Z",  "Z", };
+     472           2 :   return haselmap;
+     473             : }
+     474             : 
+     475             : //assigns SASA parameters to each atom reading from HASEL parameter database
+     476           2 : void SASA_HASEL::readSASAparam() {
+     477             : 
+     478         242 :   for(unsigned i=0; i<natoms; i++) {
+     479         240 :     SASAparam[i].clear();
+     480             :     CONNECTparam[i].clear();
+     481             :   }
+     482             : 
+     483             :   map<string, vector<std::string> > haselmap;
+     484           4 :   haselmap = setupHASELparam();
+     485             :   vector<std::string> HASELparamVector;
+     486             :   string identifier;
+     487             : 
+     488             : 
+     489         242 :   for(unsigned i=0; i<natoms; i++) {
+     490         480 :     identifier = AtomResidueName[1][i]+"_"+AtomResidueName[0][i];
+     491         240 :     if (haselmap.find(identifier)!=haselmap.end()) {
+     492         144 :       HASELparamVector = haselmap.at(identifier);
+     493         144 :       SASAparam[i].push_back (std::atof(HASELparamVector[0].c_str())+rs*10);
+     494         144 :       SASAparam[i].push_back (std::atof(HASELparamVector[1].c_str()));
+     495         288 :       CONNECTparam[i].push_back (HASELparamVector[2].c_str());
+     496         288 :       CONNECTparam[i].push_back (HASELparamVector[3].c_str());
+     497         288 :       CONNECTparam[i].push_back (HASELparamVector[4].c_str());
+     498         288 :       CONNECTparam[i].push_back (HASELparamVector[5].c_str());
+     499             :     }
+     500             :   }
+     501             : 
+     502             : 
+     503         242 :   for(unsigned i=0; i<natoms; i++) {
+     504         240 :     if (SASAparam[i].size()==0 ) {
+     505          96 :       if ((AtomResidueName[0][i][0]=='O') || (AtomResidueName[0][i][0]=='N') || (AtomResidueName[0][i][0]=='C') || (AtomResidueName[0][i][0]=='S')) {
+     506           0 :         cout << "Could not find SASA paramaters for atom " << AtomResidueName[0][i] << " of residue " << AtomResidueName[1][i] << endl;
+     507           0 :         error ("missing SASA parameters\n");
+     508             :       }
+     509             :     }
+     510             :   }
+     511             : 
+     512             : 
+     513           4 : }
+     514             : 
+     515             : 
+     516             : 
+     517             : //Max Surf values, used only if TYPE=TRANSFER
+     518           1 : map<string, vector<double> > SASA_HASEL::setupMaxSurfMap() {
+     519             :   // Max Surface Area for backbone and sidechain, in nm2
+     520             :   map<string, vector<double> > valuemap;
+     521           1 :   valuemap ["ALA"]= {0.56425,0.584851,};
+     522           1 :   valuemap ["ARG"]= {0.498656,1.808093,};
+     523           1 :   valuemap ["ASN"]= {0.473409,0.818394,};
+     524           1 :   valuemap ["ASP"]= {0.477057,0.977303,};
+     525           1 :   valuemap ["CYS"]= {0.507512,0.791483,};
+     526           1 :   valuemap ["GLN"]= {0.485859,1.281534,};
+     527           1 :   valuemap ["GLU"]= {0.495054,1.464718,};
+     528           1 :   valuemap ["GLY"]= {0.658632,0,};
+     529           1 :   valuemap ["HIS"]= {0.48194,1.118851,};
+     530           1 :   valuemap ["ILE"]= {0.461283,1.450569,};
+     531           1 :   valuemap ["LEU"]= {0.476315,1.498843,};
+     532           1 :   valuemap ["LYS"]= {0.493533,1.619731,};
+     533           1 :   valuemap ["MET"]= {0.507019,1.631904,};
+     534           1 :   valuemap ["PHE"]= {0.457462, 1.275125,};
+     535           1 :   valuemap ["PRO"]= {0.315865,0.859456,};
+     536           1 :   valuemap ["SER"]= {0.48636,0.627233,};
+     537           1 :   valuemap ["THR"]= {0.45064,0.91088,};
+     538           1 :   valuemap ["TRP"]= {0.45762,1.366369,};
+     539           1 :   valuemap ["TYR"]= {0.461826,1.425822,};
+     540           1 :   valuemap ["VAL"]= {0.477054,1.149101,};
+     541           1 :   return valuemap;
+     542             : }
+     543             : 
+     544             : 
+     545             : 
+     546             : //reads maximum surface values per residue type and assigns values to each atom, only used if sasa_type = TRANSFER
+     547             : 
+     548           1 : void SASA_HASEL::readMaxSurf() {
+     549             :   map<string, vector<double> > valuemap;
+     550           2 :   valuemap = setupMaxSurfMap();
+     551             :   vector<double> MaxSurfVector;
+     552             : 
+     553         121 :   for(unsigned i=0; i<natoms; i++) {
+     554         120 :     MaxSurf[i].clear();
+     555         120 :     MaxSurfVector = valuemap.at(AtomResidueName[1][i]);
+     556         120 :     MaxSurf[i].push_back (MaxSurfVector[0]*100);
+     557         120 :     MaxSurf[i].push_back (MaxSurfVector[1]*100);
+     558             :   }
+     559           1 : }
+     560             : 
+     561             : //reads file with free energy values for sidechains and for the backbone, and assigns values to each atom. Only used if sasa_type = TRANSFER
+     562             : 
+     563           1 : void SASA_HASEL::readDeltaG() {
+     564             : 
+     565         121 :   for(unsigned i=0; i<natoms; i++) {
+     566         120 :     DeltaG[i].clear();
+     567             :   }
+     568             : 
+     569             :   string DeltaGline;
+     570           1 :   fstream DeltaGFile;
+     571           1 :   DeltaGFile.open(DeltaGValues);
+     572           1 :   if (DeltaGFile) {
+     573             :     int backboneflag = 0;
+     574          23 :     while(getline(DeltaGFile, DeltaGline)) {
+     575          22 :       if(!DeltaGline.empty()) {
+     576             :         std::vector<std::string> DeltaGtoken;
+     577          21 :         split(DeltaGline, DeltaGtoken);
+     578        2541 :         for(unsigned i=0; i<natoms; i++) {
+     579        2520 :           if (DeltaGtoken[0].compare(AtomResidueName[1][i])==0 ) {
+     580         120 :             DeltaG[i].push_back (std::atof(DeltaGtoken[1].c_str()));
+     581             :           }
+     582             :         }
+     583          21 :         if (DeltaGtoken[0].compare("BACKBONE")==0 ) {
+     584             :           backboneflag = 1;
+     585           1 :           DeltaG[natoms].push_back (std::atof(DeltaGtoken[1].c_str()));
+     586             :         }
+     587          21 :       }
+     588             :     }
+     589           1 :     if ( backboneflag == 0) error("Cannot find backbone value in Delta G parameters file\n");
+     590             :   }
+     591           0 :   else error("Cannot open DeltaG file");
+     592             : 
+     593         121 :   for(unsigned i=0; i<natoms; i++) {
+     594         120 :     if (DeltaG[i].size()==0 ) {
+     595           0 :       cout << "Delta G value for residue " << AtomResidueName[1][i] << " not found " << endl;
+     596           0 :       error ("missing Delta G parameter\n");
+     597             :     }
+     598             :   }
+     599             : 
+     600           2 : }
+     601             : 
+     602             : //computes free energy values for the sidechains and for the backbone, and assigns values to each atom. Only used if sasa_type = TRANSFER, and if no DELTAGFILE is provided. In this case, the free energy values are those describing the effect of temperature, and the program must know if approach 2 or 3 (as described in Arsiccio and Shea, Protein Cold Denaturation in Implicit Solvent Simulations: A Transfer Free Energy Approach, JPCB, 2021) needs to be used to compute them.
+     603             : 
+     604           0 : void SASA_HASEL::computeDeltaG() {
+     605             : 
+     606           0 :   for(unsigned i=0; i<natoms; i++) {
+     607           0 :     DeltaG[i].clear();
+     608             :   }
+     609             : 
+     610             :   double T;
+     611           0 :   T = getkBT()/getKBoltzmann();
+     612             : 
+     613           0 :   if (T != Ti) {
+     614           0 :     for(unsigned i=0; i<natoms; i++) {
+     615           0 :       if (approach==2) {
+     616           0 :         if (AtomResidueName[1][i].compare("ALA")==0) {
+     617           0 :           DeltaG[i].push_back (-2.995/1000*std::pow(T,2)+1.808*T-272.895);
+     618             :         }
+     619           0 :         if (AtomResidueName[1][i].compare("ARG")==0) {
+     620           0 :           DeltaG[i].push_back (-3.182/1000*std::pow(T,2)+1.894*T-282.032);
+     621             :         }
+     622           0 :         if (AtomResidueName[1][i].compare("ASN")==0) {
+     623           0 :           DeltaG[i].push_back (-1.047/1000*std::pow(T,2)+0.6068*T-87.846);
+     624             :         }
+     625           0 :         if (AtomResidueName[1][i].compare("ASP")==0) {
+     626           0 :           DeltaG[i].push_back (-0.1794/1000*std::pow(T,2)+0.1091*T-16.526);
+     627             :         }
+     628           0 :         if (AtomResidueName[1][i].compare("CYS")==0) {
+     629           0 :           DeltaG[i].push_back (-3.09/1000*std::pow(T,2)+1.835*T-272.26);
+     630             :         }
+     631           0 :         if (AtomResidueName[1][i].compare("GLN")==0) {
+     632           0 :           DeltaG[i].push_back (-2.23/1000*std::pow(T,2)+1.335*T-199.707);
+     633             :         }
+     634           0 :         if (AtomResidueName[1][i].compare("GLU")==0) {
+     635           0 :           DeltaG[i].push_back (-1.511/1000*std::pow(T,2)+0.8904*T-131.168);
+     636             :         }
+     637           0 :         if (AtomResidueName[1][i].compare("GLY")==0) {
+     638           0 :           DeltaG[i].push_back (0);
+     639             :         }
+     640           0 :         if (AtomResidueName[1][i].compare("HIS")==0) {
+     641           0 :           DeltaG[i].push_back (-3.482/1000*std::pow(T,2)+2.084*T-311.694);
+     642             :         }
+     643           0 :         if (AtomResidueName[1][i].compare("ILE")==0) {
+     644           0 :           DeltaG[i].push_back (-6.364/1000*std::pow(T,2)+3.8*T-567.444);
+     645             :         }
+     646           0 :         if (AtomResidueName[1][i].compare("LEU")==0) {
+     647           0 :           DeltaG[i].push_back (-7.466/1000*std::pow(T,2)+4.417*T-653.394);
+     648             :         }
+     649           0 :         if (AtomResidueName[1][i].compare("LYS")==0) {
+     650           0 :           DeltaG[i].push_back (-2.091/1000*std::pow(T,2)+1.2458*T-185.549);
+     651             :         }
+     652           0 :         if (AtomResidueName[1][i].compare("MET")==0) {
+     653           0 :           DeltaG[i].push_back (-3.807/1000*std::pow(T,2)+2.272*T-339.007);
+     654             :         }
+     655           0 :         if (AtomResidueName[1][i].compare("PHE")==0) {
+     656           0 :           DeltaG[i].push_back (-7.828/1000*std::pow(T,2)+4.644*T-688.874);
+     657             :         }
+     658           0 :         if (AtomResidueName[1][i].compare("PRO")==0) {
+     659           0 :           DeltaG[i].push_back (-2.347/1000*std::pow(T,2)+1.411*T-212.059);
+     660             :         }
+     661           0 :         if (AtomResidueName[1][i].compare("SER")==0) {
+     662           0 :           DeltaG[i].push_back (1.813/1000*std::pow(T,2)-1.05*T+151.957);
+     663             :         }
+     664           0 :         if (AtomResidueName[1][i].compare("THR")==0) {
+     665           0 :           DeltaG[i].push_back (-2.64/1000*std::pow(T,2)+1.591*T-239.516);
+     666             :         }
+     667           0 :         if (AtomResidueName[1][i].compare("TRP")==0) {
+     668           0 :           DeltaG[i].push_back (-11.66/1000*std::pow(T,2)+6.916*T-1025.293);
+     669             :         }
+     670           0 :         if (AtomResidueName[1][i].compare("TYR")==0) {
+     671           0 :           DeltaG[i].push_back (-7.513/1000*std::pow(T,2)+4.478*T-667.261);
+     672             :         }
+     673           0 :         if (AtomResidueName[1][i].compare("VAL")==0) {
+     674           0 :           DeltaG[i].push_back (-4.902/1000*std::pow(T,2)+2.921*T-435.309);
+     675             :         }
+     676           0 :         DeltaG[natoms].push_back (-0.6962/1000*std::pow(T,2)+0.4426*T-70.015);
+     677             :       }
+     678           0 :       if (approach==3) {
+     679           0 :         if (AtomResidueName[1][i].compare("ALA")==0) {
+     680           0 :           DeltaG[i].push_back (-2.995/1000*std::pow(T,2)+1.808*T-272.105);
+     681             :         }
+     682           0 :         if (AtomResidueName[1][i].compare("ARG")==0) {
+     683           0 :           DeltaG[i].push_back (-3.182/1000*std::pow(T,2)+1.894*T-284.086);
+     684             :         }
+     685           0 :         if (AtomResidueName[1][i].compare("ASN")==0) {
+     686           0 :           DeltaG[i].push_back (-1.047/1000*std::pow(T,2)+0.6068*T-90.597);
+     687             :         }
+     688           0 :         if (AtomResidueName[1][i].compare("ASP")==0) {
+     689           0 :           DeltaG[i].push_back (-0.1794/1000*std::pow(T,2)+0.1091*T-19.143);
+     690             :         }
+     691           0 :         if (AtomResidueName[1][i].compare("CYS")==0) {
+     692           0 :           DeltaG[i].push_back (-3.09/1000*std::pow(T,2)+1.835*T-268.527);
+     693             :         }
+     694           0 :         if (AtomResidueName[1][i].compare("GLN")==0) {
+     695           0 :           DeltaG[i].push_back (-2.23/1000*std::pow(T,2)+1.335*T-201.559);
+     696             :         }
+     697           0 :         if (AtomResidueName[1][i].compare("GLU")==0) {
+     698           0 :           DeltaG[i].push_back (-1.511/1000*std::pow(T,2)+0.8904*T-133.543);
+     699             :         }
+     700           0 :         if (AtomResidueName[1][i].compare("GLY")==0) {
+     701           0 :           DeltaG[i].push_back (0);
+     702             :         }
+     703           0 :         if (AtomResidueName[1][i].compare("HIS")==0) {
+     704           0 :           DeltaG[i].push_back (-3.482/1000*std::pow(T,2)+2.084*T-315.398);
+     705             :         }
+     706           0 :         if (AtomResidueName[1][i].compare("ILE")==0) {
+     707           0 :           DeltaG[i].push_back (-6.364/1000*std::pow(T,2)+3.8*T-564.825);
+     708             :         }
+     709           0 :         if (AtomResidueName[1][i].compare("LEU")==0) {
+     710           0 :           DeltaG[i].push_back (-7.466/1000*std::pow(T,2)+4.417*T-651.483);
+     711             :         }
+     712           0 :         if (AtomResidueName[1][i].compare("LYS")==0) {
+     713           0 :           DeltaG[i].push_back (-2.091/1000*std::pow(T,2)+1.2458*T-187.485);
+     714             :         }
+     715           0 :         if (AtomResidueName[1][i].compare("MET")==0) {
+     716           0 :           DeltaG[i].push_back (-3.807/1000*std::pow(T,2)+2.272*T-339.242);
+     717             :         }
+     718           0 :         if (AtomResidueName[1][i].compare("PHE")==0) {
+     719           0 :           DeltaG[i].push_back (-7.828/1000*std::pow(T,2)+4.644*T-687.134);
+     720             :         }
+     721           0 :         if (AtomResidueName[1][i].compare("PRO")==0) {
+     722           0 :           DeltaG[i].push_back (-2.347/1000*std::pow(T,2)+1.411*T-214.211);
+     723             :         }
+     724           0 :         if (AtomResidueName[1][i].compare("SER")==0) {
+     725           0 :           DeltaG[i].push_back (1.813/1000*std::pow(T,2)-1.05*T+150.289);
+     726             :         }
+     727           0 :         if (AtomResidueName[1][i].compare("THR")==0) {
+     728           0 :           DeltaG[i].push_back (-2.64/1000*std::pow(T,2)+1.591*T-240.267);
+     729             :         }
+     730           0 :         if (AtomResidueName[1][i].compare("TRP")==0) {
+     731           0 :           DeltaG[i].push_back (-11.66/1000*std::pow(T,2)+6.916*T-1024.284);
+     732             :         }
+     733           0 :         if (AtomResidueName[1][i].compare("TYR")==0) {
+     734           0 :           DeltaG[i].push_back (-7.513/1000*std::pow(T,2)+4.478*T-666.484);
+     735             :         }
+     736           0 :         if (AtomResidueName[1][i].compare("VAL")==0) {
+     737           0 :           DeltaG[i].push_back (-4.902/1000*std::pow(T,2)+2.921*T-433.013);
+     738             :         }
+     739           0 :         DeltaG[natoms].push_back (-0.6927/1000*std::pow(T,2)+0.4404*T-68.724);
+     740             :       }
+     741             :     }
+     742             :   }
+     743             : 
+     744           0 :   Ti = T;
+     745             : 
+     746           0 :   if (firstStepFlag ==0) {
+     747           0 :     if (approach!=2 && approach!=3) {
+     748           0 :       cout << "Unknown approach " << approach << endl;
+     749             :     }
+     750           0 :     for(unsigned i=0; i<natoms; i++) {
+     751           0 :       if (DeltaG[i].size()==0 ) {
+     752           0 :         cout << "Delta G value for residue " << AtomResidueName[1][i] << " not found " << endl;
+     753           0 :         error ("missing Delta G parameter\n");
+     754             :       }
+     755             :     }
+     756             :   }
+     757           0 : }
+     758             : 
+     759             : 
+     760             : //calculates neighbor list
+     761          24 : void SASA_HASEL::calcNlist() {
+     762          24 :   if(!nopbc) makeWhole();
+     763             : 
+     764        2904 :   for(unsigned i = 0; i < natoms; i++) {
+     765        2880 :     Nlist[i].clear();
+     766             :   }
+     767             : 
+     768        2904 :   for(unsigned i = 0; i < natoms; i++) {
+     769        2880 :     if (SASAparam[i].size()>0) {
+     770      103680 :       for (unsigned j = 0; j < i; j++) {
+     771      101952 :         if (SASAparam[j].size()>0) {
+     772       61344 :           const Vector Delta_ij_vec = delta( getPosition(i), getPosition(j) );
+     773       61344 :           double Delta_ij_mod = Delta_ij_vec.modulo()*10;
+     774       61344 :           double overlapD = SASAparam[i][0]+SASAparam[j][0];
+     775       61344 :           if (Delta_ij_mod < overlapD) {
+     776       26748 :             Nlist.at(i).push_back (j);
+     777       26748 :             Nlist.at(j).push_back (i);
+     778             :           }
+     779             :         }
+     780             :       }
+     781             :     }
+     782             :   }
+     783          24 : }
+     784             : 
+     785             : 
+     786             : //calculates SASA according to Hasel et al., Tetrahedron Computer Methodology Vol. 1, No. 2, pp. 103-116, 1988
+     787          24 : void SASA_HASEL::calculate() {
+     788          24 :   if(!nopbc) makeWhole();
+     789             : 
+     790          24 :   if(getExchangeStep()) nl_update = 0;
+     791          24 :   if (firstStepFlag ==0) {
+     792           2 :     readPDB();
+     793           2 :     readSASAparam();
+     794             :   }
+     795          24 :   if (nl_update == 0) {
+     796          24 :     calcNlist();
+     797             :   }
+     798             : 
+     799             : 
+     800          24 :   auto* moldat = plumed.getActionSet().selectLatest<GenericMolInfo*>(this);
+     801          24 :   if( ! moldat ) error("Unable to find MOLINFO in input");
+     802             :   double Si, sasai, bij;
+     803          24 :   double sasa = 0;
+     804          24 :   vector<Vector> derivatives( natoms );
+     805        2904 :   for(unsigned i = 0; i < natoms; i++) {
+     806        2880 :     derivatives[i][0] = 0.;
+     807        2880 :     derivatives[i][1] = 0.;
+     808        2880 :     derivatives[i][2] = 0.;
+     809             :   }
+     810             : 
+     811          24 :   Tensor virial;
+     812          24 :   vector <double> ddij_di(3);
+     813          24 :   vector <double> dbij_di(3);
+     814          24 :   vector <double> dAijt_di(3);
+     815             : 
+     816          24 :   if( sasa_type==TOTAL ) {
+     817        1452 :     for(unsigned i = 0; i < natoms; i++) {
+     818        1440 :       if(SASAparam[i].size() > 0) {
+     819         864 :         double ri = SASAparam[i][0];
+     820         864 :         Si = 4*M_PI*ri*ri;
+     821             :         sasai = 1.0;
+     822             : 
+     823        1728 :         vector <vector <double> > derTerm( Nlist[i].size(), vector <double>(3));
+     824             : 
+     825         864 :         dAijt_di[0] = 0;
+     826         864 :         dAijt_di[1] = 0;
+     827         864 :         dAijt_di[2] = 0;
+     828         864 :         int NumRes_i = moldat->getResidueNumber(atoms[i]);
+     829             : 
+     830       27612 :         for (unsigned j = 0; j < Nlist[i].size(); j++) {
+     831             :           double pij = 0.3516;
+     832             : 
+     833       26748 :           int NumRes_j = moldat->getResidueNumber(atoms[Nlist[i][j]]);
+     834       26748 :           if (NumRes_i==NumRes_j) {
+     835        4320 :             if (CONNECTparam[i][0].compare(AtomResidueName[0][Nlist[i][j]])==0 || CONNECTparam[i][1].compare(AtomResidueName[0][Nlist[i][j]])==0 || CONNECTparam[i][2].compare(AtomResidueName[0][Nlist[i][j]])==0 || CONNECTparam[i][3].compare(AtomResidueName[0][Nlist[i][j]])==0) {
+     836             :               pij = 0.8875;
+     837             :             }
+     838             :           }
+     839       26748 :           if ( abs(NumRes_i-NumRes_j) == 1 ) {
+     840       10380 :             if ((AtomResidueName[0][i] == "N"  && AtomResidueName[0][Nlist[i][j]]== "CA") || (AtomResidueName[0][Nlist[i][j]] == "N"  && AtomResidueName[0][i]== "CA")) {
+     841             :               pij = 0.8875;
+     842             :             }
+     843             :           }
+     844             : 
+     845       26748 :           const Vector d_ij_vec = delta( getPosition(i), getPosition(Nlist[i][j]) );
+     846       26748 :           double d_ij = d_ij_vec.modulo()*10;
+     847             : 
+     848       26748 :           double rj = SASAparam[Nlist[i][j]][0];
+     849       26748 :           bij = M_PI*ri*(ri+rj-d_ij)*(1+(rj-ri)/d_ij); //Angstrom2
+     850             : 
+     851       26748 :           sasai = sasai*(1-SASAparam[i][1]*pij*bij/Si); //nondimensional
+     852             : 
+     853       26748 :           ddij_di[0] = -10*(getPosition(Nlist[i][j])[0]-getPosition(i)[0])/d_ij; //nondimensional
+     854       26748 :           ddij_di[1] = -10*(getPosition(Nlist[i][j])[1]-getPosition(i)[1])/d_ij;
+     855       26748 :           ddij_di[2] = -10*(getPosition(Nlist[i][j])[2]-getPosition(i)[2])/d_ij;
+     856             : 
+     857       26748 :           dbij_di[0] = -M_PI*ri*ddij_di[0]*(1+(ri+rj)*(rj-ri)/(d_ij*d_ij)); //Angstrom
+     858       26748 :           dbij_di[1] = -M_PI*ri*ddij_di[1]*(1+(ri+rj)*(rj-ri)/(d_ij*d_ij));
+     859       26748 :           dbij_di[2] = -M_PI*ri*ddij_di[2]*(1+(ri+rj)*(rj-ri)/(d_ij*d_ij));
+     860             : 
+     861       26748 :           dAijt_di[0] += -1/(Si/(SASAparam[i][1]*pij)-bij)*dbij_di[0]; //Angstrom-1
+     862       26748 :           dAijt_di[1] += -1/(Si/(SASAparam[i][1]*pij)-bij)*dbij_di[1];
+     863       26748 :           dAijt_di[2] += -1/(Si/(SASAparam[i][1]*pij)-bij)*dbij_di[2];
+     864             : 
+     865       26748 :           derTerm[j][0] = 1/(Si/(SASAparam[i][1]*pij)-bij)*dbij_di[0]; //Angstrom-1
+     866       26748 :           derTerm[j][1] = 1/(Si/(SASAparam[i][1]*pij)-bij)*dbij_di[1];
+     867       26748 :           derTerm[j][2] = 1/(Si/(SASAparam[i][1]*pij)-bij)*dbij_di[2];
+     868             : 
+     869             :         }
+     870             : 
+     871         864 :         sasa += Si*sasai/100; //nm2
+     872             : 
+     873         864 :         derivatives[i][0] += Si*sasai/10*dAijt_di[0]; //nm
+     874         864 :         derivatives[i][1] += Si*sasai/10*dAijt_di[1];
+     875         864 :         derivatives[i][2] += Si*sasai/10*dAijt_di[2];
+     876             : 
+     877       27612 :         for (unsigned j = 0; j < Nlist[i].size(); j++) {
+     878       26748 :           derivatives[Nlist[i][j]][0] += Si*sasai/10*derTerm[j][0]; //nm
+     879       26748 :           derivatives[Nlist[i][j]][1] += Si*sasai/10*derTerm[j][1];
+     880       26748 :           derivatives[Nlist[i][j]][2] += Si*sasai/10*derTerm[j][2];
+     881             :         }
+     882         864 :       }
+     883             :     }
+     884             :   }
+     885             : 
+     886             : 
+     887          24 :   if( sasa_type==TRANSFER ) {
+     888             : 
+     889          12 :     if (firstStepFlag ==0) {
+     890           1 :       readMaxSurf();
+     891             :     }
+     892             : 
+     893          12 :     if (firstStepFlag ==0 && DeltaGValues != "absent") {
+     894           1 :       readDeltaG();
+     895             :     }
+     896             : 
+     897          12 :     if (DeltaGValues == "absent") {
+     898           0 :       computeDeltaG();
+     899             :     }
+     900             : 
+     901             : 
+     902        1452 :     for(unsigned i = 0; i < natoms; i++) {
+     903             : 
+     904             : 
+     905             : 
+     906        1440 :       if(SASAparam[i].size() > 0) {
+     907         864 :         double ri = SASAparam[i][0];
+     908         864 :         Si = 4*M_PI*ri*ri;
+     909             :         sasai = 1.0;
+     910             : 
+     911        1728 :         vector <vector <double> > derTerm( Nlist[i].size(), vector <double>(3));
+     912             : 
+     913         864 :         dAijt_di[0] = 0;
+     914         864 :         dAijt_di[1] = 0;
+     915         864 :         dAijt_di[2] = 0;
+     916         864 :         int NumRes_i = moldat->getResidueNumber(atoms[i]);
+     917             : 
+     918       27612 :         for (unsigned j = 0; j < Nlist[i].size(); j++) {
+     919             :           double pij = 0.3516;
+     920             : 
+     921       26748 :           int NumRes_j = moldat->getResidueNumber(atoms[Nlist[i][j]]);
+     922       26748 :           if (NumRes_i==NumRes_j) {
+     923        4320 :             if (CONNECTparam[i][0].compare(AtomResidueName[0][Nlist[i][j]])==0 || CONNECTparam[i][1].compare(AtomResidueName[0][Nlist[i][j]])==0 || CONNECTparam[i][2].compare(AtomResidueName[0][Nlist[i][j]])==0 || CONNECTparam[i][3].compare(AtomResidueName[0][Nlist[i][j]])==0) {
+     924             :               pij = 0.8875;
+     925             :             }
+     926             :           }
+     927       26748 :           if ( abs(NumRes_i-NumRes_j) == 1 ) {
+     928       10380 :             if ((AtomResidueName[0][i] == "N"  && AtomResidueName[0][Nlist[i][j]]== "CA") || (AtomResidueName[0][Nlist[i][j]] == "N"  && AtomResidueName[0][i]== "CA")) {
+     929             :               pij = 0.8875;
+     930             :             }
+     931             :           }
+     932             : 
+     933       26748 :           const Vector d_ij_vec = delta( getPosition(i), getPosition(Nlist[i][j]) );
+     934       26748 :           double d_ij = d_ij_vec.modulo()*10;
+     935             : 
+     936       26748 :           double rj = SASAparam[Nlist[i][j]][0];
+     937       26748 :           bij = M_PI*ri*(ri+rj-d_ij)*(1+(rj-ri)/d_ij); //Angstrom2
+     938             : 
+     939       26748 :           sasai = sasai*(1-SASAparam[i][1]*pij*bij/Si); //nondimensional
+     940             : 
+     941       26748 :           ddij_di[0] = -10*(getPosition(Nlist[i][j])[0]-getPosition(i)[0])/d_ij; //nondimensional
+     942       26748 :           ddij_di[1] = -10*(getPosition(Nlist[i][j])[1]-getPosition(i)[1])/d_ij;
+     943       26748 :           ddij_di[2] = -10*(getPosition(Nlist[i][j])[2]-getPosition(i)[2])/d_ij;
+     944             : 
+     945       26748 :           dbij_di[0] = -M_PI*ri*ddij_di[0]*(1+(ri+rj)*(rj-ri)/(d_ij*d_ij)); //Angstrom
+     946       26748 :           dbij_di[1] = -M_PI*ri*ddij_di[1]*(1+(ri+rj)*(rj-ri)/(d_ij*d_ij));
+     947       26748 :           dbij_di[2] = -M_PI*ri*ddij_di[2]*(1+(ri+rj)*(rj-ri)/(d_ij*d_ij));
+     948             : 
+     949       26748 :           dAijt_di[0] += -1/(Si/(SASAparam[i][1]*pij)-bij)*dbij_di[0]; //Angstrom-1
+     950       26748 :           dAijt_di[1] += -1/(Si/(SASAparam[i][1]*pij)-bij)*dbij_di[1];
+     951       26748 :           dAijt_di[2] += -1/(Si/(SASAparam[i][1]*pij)-bij)*dbij_di[2];
+     952             : 
+     953       26748 :           derTerm[j][0] = 1/(Si/(SASAparam[i][1]*pij)-bij)*dbij_di[0]; //Angstrom-1
+     954       26748 :           derTerm[j][1] = 1/(Si/(SASAparam[i][1]*pij)-bij)*dbij_di[1];
+     955       26748 :           derTerm[j][2] = 1/(Si/(SASAparam[i][1]*pij)-bij)*dbij_di[2];
+     956             : 
+     957             :         }
+     958             : 
+     959        2880 :         if (AtomResidueName[0][i] == "N" || AtomResidueName[0][i] == "CA"  || AtomResidueName[0][i] == "C" || AtomResidueName[0][i] == "O" || AtomResidueName[0][i] == "H") {
+     960             : 
+     961         720 :           sasa += Si*sasai/MaxSurf[i][0]*DeltaG[natoms][0]; //kJ/mol
+     962             : 
+     963             : 
+     964         720 :           derivatives[i][0] += Si*sasai*dAijt_di[0]/MaxSurf[i][0]*DeltaG[natoms][0]*10; //kJ/mol/nm
+     965         720 :           derivatives[i][1] += Si*sasai*dAijt_di[1]/MaxSurf[i][0]*DeltaG[natoms][0]*10;
+     966         720 :           derivatives[i][2] += Si*sasai*dAijt_di[2]/MaxSurf[i][0]*DeltaG[natoms][0]*10;
+     967             :         }
+     968             : 
+     969        2880 :         if (AtomResidueName[0][i] != "N" && AtomResidueName[0][i] != "CA"  && AtomResidueName[0][i] != "C" && AtomResidueName[0][i] != "O" && AtomResidueName[0][i] != "H") {
+     970         144 :           sasa += Si*sasai/MaxSurf[i][1]*DeltaG[i][0]; //kJ/mol
+     971             : 
+     972         144 :           derivatives[i][0] += Si*sasai*dAijt_di[0]/MaxSurf[i][1]*DeltaG[i][0]*10; //kJ/mol/nm
+     973         144 :           derivatives[i][1] += Si*sasai*dAijt_di[1]/MaxSurf[i][1]*DeltaG[i][0]*10;
+     974         144 :           derivatives[i][2] += Si*sasai*dAijt_di[2]/MaxSurf[i][1]*DeltaG[i][0]*10;
+     975             :         }
+     976             : 
+     977             : 
+     978       27612 :         for (unsigned j = 0; j < Nlist[i].size(); j++) {
+     979       86883 :           if (AtomResidueName[0][i] == "N" || AtomResidueName[0][i] == "CA"  || AtomResidueName[0][i] == "C" || AtomResidueName[0][i] == "O" || AtomResidueName[0][i] == "H") {
+     980       22438 :             derivatives[Nlist[i][j]][0] += Si*sasai*10*derTerm[j][0]/MaxSurf[i][0]*DeltaG[natoms][0]; //kJ/mol/nm
+     981       22438 :             derivatives[Nlist[i][j]][1] += Si*sasai*10*derTerm[j][1]/MaxSurf[i][0]*DeltaG[natoms][0];
+     982       22438 :             derivatives[Nlist[i][j]][2] += Si*sasai*10*derTerm[j][2]/MaxSurf[i][0]*DeltaG[natoms][0];
+     983             :           }
+     984             : 
+     985       86883 :           if (AtomResidueName[0][i] != "N" && AtomResidueName[0][i] != "CA"  && AtomResidueName[0][i] != "C" && AtomResidueName[0][i] != "O" && AtomResidueName[0][i] != "H") {
+     986        4310 :             derivatives[Nlist[i][j]][0] += Si*sasai*10*derTerm[j][0]/MaxSurf[i][1]*DeltaG[i][0]; //kJ/mol/nm
+     987        4310 :             derivatives[Nlist[i][j]][1] += Si*sasai*10*derTerm[j][1]/MaxSurf[i][1]*DeltaG[i][0];
+     988        4310 :             derivatives[Nlist[i][j]][2] += Si*sasai*10*derTerm[j][2]/MaxSurf[i][1]*DeltaG[i][0];
+     989             :           }
+     990             :         }
+     991         864 :       }
+     992             :     }
+     993             :   }
+     994             : 
+     995             : 
+     996        2904 :   for(unsigned i=0; i<natoms; i++) {
+     997        2880 :     setAtomsDerivatives(i,derivatives[i]);
+     998        2880 :     virial -= Tensor(getPosition(i),derivatives[i]);
+     999             :   }
+    1000             : 
+    1001          24 :   setBoxDerivatives(virial);
+    1002          24 :   setValue(sasa);
+    1003          24 :   firstStepFlag = 1;
+    1004          24 :   ++nl_update;
+    1005          24 :   if (nl_update == stride) {
+    1006          24 :     nl_update = 0;
+    1007             :   }
+    1008             : // setBoxDerivativesNoPbc();
+    1009          24 : }
+    1010             : 
+    1011             : }//namespace sasa
+    1012             : }//namespace PLMD
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/sasa/sasa_LCPO.cpp.func-sort-c.html b/coverage/sasa/sasa_LCPO.cpp.func-sort-c.html new file mode 100644 index 000000000000..5548b61d8f31 --- /dev/null +++ b/coverage/sasa/sasa_LCPO.cpp.func-sort-c.html @@ -0,0 +1,125 @@ + + + + + + + + LCOV - plumed test coverage - sasa/sasa_LCPO.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - sasa - sasa_LCPO.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:51863082.2 %
Date:2024-04-19 12:12:35Functions:101376.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4sasa5splitISt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EEEEvRKS8_RT_0
_ZN4PLMD4sasa9SASA_LCPO13computeDeltaGEv0
_ZN4PLMD4sasa9SASA_LCPOC2ERKNS_13ActionOptionsE0
_ZN4PLMD4sasa9SASA_LCPO10readDeltaGEv1
_ZN4PLMD4sasa9SASA_LCPO11readMaxSurfEv1
_ZN4PLMD4sasa9SASA_LCPO15setupMaxSurfMapB5cxx11Ev1
_ZN4PLMD4sasa9SASA_LCPO13readLCPOparamEv2
_ZN4PLMD4sasa9SASA_LCPO14setupLCPOparamB5cxx11Ev2
_ZN4PLMD4sasa9SASA_LCPO7readPDBEv2
_ZN4PLMD4sasa9SASA_LCPOC1ERKNS_13ActionOptionsE2
_ZN4PLMD4sasa9SASA_LCPO16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD4sasa9SASA_LCPO9calcNlistEv24
_ZN4PLMD4sasa9SASA_LCPO9calculateEv24
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/sasa/sasa_LCPO.cpp.func.html b/coverage/sasa/sasa_LCPO.cpp.func.html new file mode 100644 index 000000000000..c5230ec18b85 --- /dev/null +++ b/coverage/sasa/sasa_LCPO.cpp.func.html @@ -0,0 +1,125 @@ + + + + + + + + LCOV - plumed test coverage - sasa/sasa_LCPO.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - sasa - sasa_LCPO.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:51863082.2 %
Date:2024-04-19 12:12:35Functions:101376.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4sasa5splitISt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EEEEvRKS8_RT_0
_ZN4PLMD4sasa9SASA_LCPO10readDeltaGEv1
_ZN4PLMD4sasa9SASA_LCPO11readMaxSurfEv1
_ZN4PLMD4sasa9SASA_LCPO13computeDeltaGEv0
_ZN4PLMD4sasa9SASA_LCPO13readLCPOparamEv2
_ZN4PLMD4sasa9SASA_LCPO14setupLCPOparamB5cxx11Ev2
_ZN4PLMD4sasa9SASA_LCPO15setupMaxSurfMapB5cxx11Ev1
_ZN4PLMD4sasa9SASA_LCPO16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD4sasa9SASA_LCPO7readPDBEv2
_ZN4PLMD4sasa9SASA_LCPO9calcNlistEv24
_ZN4PLMD4sasa9SASA_LCPO9calculateEv24
_ZN4PLMD4sasa9SASA_LCPOC1ERKNS_13ActionOptionsE2
_ZN4PLMD4sasa9SASA_LCPOC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/sasa/sasa_LCPO.cpp.gcov.html b/coverage/sasa/sasa_LCPO.cpp.gcov.html new file mode 100644 index 000000000000..7961621eb77d --- /dev/null +++ b/coverage/sasa/sasa_LCPO.cpp.gcov.html @@ -0,0 +1,1157 @@ + + + + + + + + LCOV - plumed test coverage - sasa/sasa_LCPO.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - sasa - sasa_LCPO.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:51863082.2 %
Date:2024-04-19 12:12:35Functions:101376.9 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2021, Andrea Arsiccio
+       3             : 
+       4             : This software is provided 'as-is', without any express or implied
+       5             : warranty. In no event will the authors be held liable for any damages
+       6             : arising from the use of this software.
+       7             : 
+       8             : Permission is granted to anyone to use this software for any purpose,
+       9             : including commercial applications, and to alter it and redistribute it
+      10             : freely, subject to the following restrictions:
+      11             : 
+      12             : 1. The origin of this software must not be misrepresented; you must not
+      13             :    claim that you wrote the original software. If you use this software
+      14             :    in a product, an acknowledgment in the product documentation would be
+      15             :    appreciated but is not required.
+      16             : 2. Altered source versions must be plainly marked as such, and must not be
+      17             :    misrepresented as being the original software.
+      18             : 3. This notice may not be removed or altered from any source distribution.
+      19             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      20             : 
+      21             : #include "Sasa.h"
+      22             : #include "core/ActionRegister.h"
+      23             : #include "core/PlumedMain.h"
+      24             : #include "core/GenericMolInfo.h"
+      25             : #include "core/ActionSet.h"
+      26             : #include <cstdio>
+      27             : #include <iostream>
+      28             : #include <string>
+      29             : #include <cmath>
+      30             : #include <sstream>
+      31             : #include <algorithm>
+      32             : #include <iterator>
+      33             : #include <fstream>
+      34             : 
+      35             : 
+      36             : using namespace std;
+      37             : 
+      38             : namespace PLMD {
+      39             : namespace sasa {
+      40             : 
+      41             : //+PLUMEDOC SASAMOD_COLVAR SASA_LCPO
+      42             : /*
+      43             : Calculates the solvent accessible surface area (SASA) of a protein molecule, or other properties related to it.
+      44             : 
+      45             : The atoms for which the SASA is desired should be indicated with the keyword ATOMS, and a pdb file of the protein must be provided in input with the MOLINFO keyword. The LCPO algorithm is used for the calculation (please, read and cite \cite Weiser1999). The radius of the solvent is assumed to be 0.14 nm, which is the radius of water molecules. Using the keyword NL_STRIDE it is also possible to specify the frequency with which the neighbor list for the calculation of the SASA is updated (the default is every 10 steps).
+      46             : 
+      47             : Different properties can be calculated and selected using the TYPE keyword:
+      48             : 
+      49             : 1) the total SASA (TOTAL);
+      50             : 
+      51             : 2) the free energy of transfer for the protein according to the transfer model (TRANSFER). This keyword can be used, for instance, to compute the transfer of a protein to different temperatures, as detailed in \cite Arsiccio-T-SASA-2021, or to different pressures, as detailed in \cite Arsiccio-P-SASA-2021, or to different osmolyte solutions, as detailed in \cite Arsiccio-C-SASA-2022.
+      52             : 
+      53             : 
+      54             : When the TRANSFER keyword is used, a file with the free energy of transfer values for the sidechains and backbone atoms should be provided (using the keyword DELTAGFILE). Such file should have the following format:
+      55             : 
+      56             : \verbatim
+      57             : ----------------Sample DeltaG.dat file---------------------
+      58             : ALA     0.711019999999962
+      59             : ARG     -2.24832799999996
+      60             : ASN     -2.74838799999999
+      61             : ASP     -2.5626376
+      62             : CYS     3.89864000000006
+      63             : GLN     -1.76192
+      64             : GLU     -2.38664400000002
+      65             : GLY     0
+      66             : HIS     -3.58152799999999
+      67             : ILE     2.42634399999986
+      68             : LEU     1.77233599999988
+      69             : LYS     -1.92576400000002
+      70             : MET     -0.262827999999956
+      71             : PHE     1.62028800000007
+      72             : PRO     -2.15598800000001
+      73             : SER     -1.60934800000004
+      74             : THR     -0.591559999999987
+      75             : TRP     1.22936000000027
+      76             : TYR     0.775547999999958
+      77             : VAL     2.12779200000011
+      78             : BACKBONE        1.00066920000002
+      79             : -----------------------------------------------------------
+      80             : \endverbatim
+      81             : 
+      82             : where the second column is the free energy of transfer for each sidechain/backbone, in kJ/mol.
+      83             : 
+      84             : A Python script for the computation of free energy of transfer values to describe the effect of osmolyte concentration, temperature and pressure (according to \cite Arsiccio-C-SASA-2022, \cite Arsiccio-T-SASA-2021 and \cite Arsiccio-P-SASA-2021) is freely available at https://github.com/andrea-arsiccio/DeltaG-calculation. The script automatically outputs a DeltaG.dat file compatible with this SASA module.
+      85             : 
+      86             : If the DELTAGFILE is not provided, the program computes the free energy of transfer values as if they had to take into account the effect of temperature according to approaches 2 or 3 in the paper \cite Arsiccio-T-SASA-2021. Please read and cite this paper if using the transfer model for computing the effect of temperature in implicit solvent simulations. For this purpose, the keyword APPROACH should be added, and set to either 2 or 3.
+      87             : 
+      88             : The SASA usually makes sense when atoms used for the calculation are all part of the same molecule. When running with periodic boundary conditions, the atoms should be in the proper periodic image. This is done automatically since PLUMED 2.2, by considering the ordered list of atoms and rebuilding the broken entities using a procedure that is equivalent to that done in \ref WHOLEMOLECULES. Notice that rebuilding is local to this action. This is different from \ref WHOLEMOLECULES which actually modifies the coordinates stored in PLUMED.
+      89             : 
+      90             : In case you want to recover the old behavior you should use the NOPBC flag.
+      91             : In that case you need to take care that atoms are in the correct periodic image.
+      92             : 
+      93             : The SASA may also be computed using the SASA_HASEL collective variable, which makes use of the algorithm described in \cite Hasel1988. SASA_HASEL is less accurate then SASA_LCPO, but the computation is faster.
+      94             : 
+      95             : 
+      96             : 
+      97             : \par Examples
+      98             : 
+      99             : The following input tells plumed to print the total SASA for atoms 10 to 20 in a protein chain.
+     100             : \plumedfile
+     101             : SASA_LCPO TYPE=TOTAL ATOMS=10-20 NL_STRIDE=10 LABEL=sasa
+     102             : PRINT ARG=sasa STRIDE=1 FILE=colvar
+     103             : \endplumedfile
+     104             : 
+     105             : 
+     106             : The following input tells plumed to compute the transfer free energy for the protein chain containing atoms 10 to 20. Such transfer free energy is then used as a bias in the simulation (e.g., implicit solvent simulations). The free energy of transfer values are read from a file called DeltaG.dat.
+     107             : 
+     108             : \plumedfile
+     109             : SASA_LCPO TYPE=TRANSFER ATOMS=10-20 NL_STRIDE=10 DELTAGFILE=DeltaG.dat LABEL=sasa
+     110             : 
+     111             : bias: BIASVALUE ARG=sasa
+     112             : 
+     113             : PRINT ARG=sasa,bias.* STRIDE=1 FILE=colvar
+     114             : \endplumedfile
+     115             : 
+     116             : The following input tells plumed to compute the transfer free energy for the protein chain containing atoms 10 to 20. Such transfer free energy is then used as a bias in the simulation (e.g., implicit solvent simulations). The free energy of transfer values are computed according to \cite Arsiccio-T-SASA-2021, and take into account the effect of temperature using approach 2 as described in the paper.
+     117             : 
+     118             : \plumedfile
+     119             : SASA_LCPO TYPE=TRANSFER ATOMS=10-20 NL_STRIDE=10 APPROACH=2 LABEL=sasa
+     120             : 
+     121             : bias: BIASVALUE ARG=sasa
+     122             : 
+     123             : PRINT ARG=sasa,bias.* STRIDE=1 FILE=colvar
+     124             : \endplumedfile
+     125             : 
+     126             : */
+     127             : //+ENDPLUMEDOC
+     128             : 
+     129             : class SASA_LCPO : public Colvar {
+     130             : private:
+     131             :   enum CV_TYPE {TOTAL, TRANSFER};
+     132             :   int sasa_type;
+     133             :   bool nopbc;
+     134             :   double rs;
+     135             :   string DeltaGValues;
+     136             :   int approach;
+     137             :   unsigned stride;
+     138             :   unsigned nl_update;
+     139             :   int firstStepFlag;
+     140             :   double Ti;
+     141             :   // cppcheck-suppress duplInheritedMember
+     142             :   std::vector<AtomNumber> atoms;
+     143             :   vector < vector < std::string > > AtomResidueName;
+     144             :   vector < vector < double > > LCPOparam;
+     145             :   unsigned natoms;
+     146             :   vector < vector < double > > MaxSurf;
+     147             :   vector < vector < double > > DeltaG;
+     148             :   vector < vector < int > > Nlist;
+     149             : public:
+     150             :   static void registerKeywords(Keywords& keys);
+     151             :   explicit SASA_LCPO(const ActionOptions&);
+     152             :   void readPDB();
+     153             :   map<string, vector<double> > setupLCPOparam();
+     154             :   void readLCPOparam();
+     155             :   void calcNlist();
+     156             :   map<string, vector<double> > setupMaxSurfMap();
+     157             :   void readMaxSurf();
+     158             :   void readDeltaG();
+     159             :   void computeDeltaG();
+     160             :   virtual void calculate();
+     161             : };
+     162             : 
+     163             : PLUMED_REGISTER_ACTION(SASA_LCPO,"SASA_LCPO")
+     164             : 
+     165           4 : void SASA_LCPO::registerKeywords(Keywords& keys) {
+     166           4 :   Colvar::registerKeywords(keys);
+     167           8 :   keys.add("atoms","ATOMS","the group of atoms that you are calculating the SASA for");
+     168           8 :   keys.add("compulsory","TYPE","TOTAL","The type of calculation you want to perform. Can be TOTAL or TRANSFER");
+     169           8 :   keys.add("compulsory", "NL_STRIDE", "The frequency with which the neighbor list is updated.");
+     170           8 :   keys.add("optional","DELTAGFILE","a file containing the free energy values for backbone and sidechains. Necessary only if TYPE = TRANSFER. A Python script for the computation of free energy of transfer values to describe the effect of osmolyte concentration, temperature and pressure is freely available at https://github.com/andrea-arsiccio/DeltaG-calculation. The script automatically outputs a DeltaG.dat file compatible with this SASA module. If TYPE = TRANSFER and no DELTAGFILE is provided, the free energy values are those describing the effect of temperature, and are computed using the temperature value passed by the MD engine");
+     171           8 :   keys.add("optional","APPROACH","either approach 2 or 3. Necessary only if TYPE = TRANSFER and no DELTAGFILE is provided. If TYPE = TRANSFER and no DELTAGFILE is provided, the free energy values are those describing the effect of temperature, and the program must know if approach 2 or 3 (as described in Arsiccio and Shea, Protein Cold Denaturation in Implicit Solvent Simulations: A Transfer Free Energy Approach, J. Phys. Chem. B, 2021) needs to be used to compute them");
+     172           4 : }
+     173             : 
+     174             : 
+     175           2 : SASA_LCPO::SASA_LCPO(const ActionOptions&ao):
+     176             :   PLUMED_COLVAR_INIT(ao),
+     177           2 :   nopbc(false),
+     178           4 :   DeltaGValues("absent"),
+     179           2 :   Ti(0),
+     180           2 :   stride(10),
+     181           2 :   nl_update(0),
+     182           2 :   firstStepFlag(0)
+     183             : {
+     184           2 :   rs = 0.14;
+     185           2 :   parse("DELTAGFILE",DeltaGValues);
+     186           2 :   parse("APPROACH", approach);
+     187           4 :   parseAtomList("ATOMS",atoms);
+     188           2 :   if(atoms.size()==0) error("no atoms specified");
+     189             :   std::string Type;
+     190           2 :   parse("TYPE",Type);
+     191           2 :   parse("NL_STRIDE", stride);
+     192           2 :   parseFlag("NOPBC",nopbc);
+     193           2 :   checkRead();
+     194             : 
+     195           2 :   if(Type=="TOTAL") sasa_type=TOTAL;
+     196           1 :   else if(Type=="TRANSFER") sasa_type=TRANSFER;
+     197           0 :   else error("Unknown SASA type");
+     198             : 
+     199           2 :   switch(sasa_type)
+     200             :   {
+     201           1 :   case TOTAL:   log.printf("  TOTAL SASA;"); break;
+     202           1 :   case TRANSFER: log.printf("  TRANSFER MODEL;"); break;
+     203             :   }
+     204             : 
+     205           2 :   log.printf("  atoms involved : ");
+     206         242 :   for(unsigned i=0; i<atoms.size(); ++i) {
+     207         240 :     if(i%25==0) log<<"\n";
+     208         240 :     log.printf("%d ",atoms[i].serial());
+     209             :   }
+     210           2 :   log.printf("\n");
+     211             : 
+     212           2 :   if(nopbc) {
+     213           0 :     log<<"  PBC will be ignored\n";
+     214             :   } else {
+     215           2 :     log<<"  broken molecules will be rebuilt assuming atoms are in the proper order\n";
+     216             :   }
+     217             : 
+     218             : 
+     219           4 :   addValueWithDerivatives(); setNotPeriodic();
+     220           2 :   requestAtoms(atoms);
+     221             : 
+     222           2 :   natoms = getNumberOfAtoms();
+     223           2 :   AtomResidueName.resize(2);
+     224           2 :   LCPOparam.resize(natoms);
+     225           2 :   MaxSurf.resize(natoms);
+     226           2 :   DeltaG.resize(natoms+1);
+     227           2 :   Nlist.resize(natoms);
+     228             : 
+     229             : 
+     230           2 : }
+     231             : 
+     232             : 
+     233             : //splits strings into tokens. Used to read into LCPO parameters file and into reference pdb file
+     234             : template <class Container>
+     235           0 : void split(const std::string& str, Container& cont)
+     236             : {
+     237           0 :   std::istringstream iss(str);
+     238           0 :   std::copy(std::istream_iterator<std::string>(iss),
+     239           0 :             std::istream_iterator<std::string>(),
+     240             :             std::back_inserter(cont));
+     241           0 : }
+     242             : 
+     243             : 
+     244             : //reads input PDB file provided with MOLINFO, and assigns atom and residue names to each atom involved in the CV
+     245             : 
+     246           2 : void SASA_LCPO::readPDB() {
+     247           2 :   auto* moldat = plumed.getActionSet().selectLatest<GenericMolInfo*>(this);
+     248           2 :   if( ! moldat ) error("Unable to find MOLINFO in input");
+     249             :   AtomResidueName[0].clear();
+     250             :   AtomResidueName[1].clear();
+     251             : 
+     252         242 :   for(unsigned i=0; i<natoms; i++) {
+     253         240 :     string Aname = moldat->getAtomName(atoms[i]);
+     254         240 :     string Rname = moldat->getResidueName(atoms[i]);
+     255         240 :     AtomResidueName[0].push_back (Aname);
+     256         240 :     AtomResidueName[1].push_back (Rname);
+     257             :   }
+     258             : 
+     259           2 : }
+     260             : 
+     261             : //LCPO parameters database
+     262           2 : map<string, vector<double> > SASA_LCPO::setupLCPOparam() {
+     263             :   map<string, vector<double> > lcpomap;
+     264           2 :   lcpomap["ALA_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     265           2 :   lcpomap["ALA_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     266           2 :   lcpomap["ALA_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     267           2 :   lcpomap["ALA_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     268           2 :   lcpomap["ALA_CB"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+     269           2 :   lcpomap["ASP_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     270           2 :   lcpomap["ASP_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     271           2 :   lcpomap["ASP_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     272           2 :   lcpomap["ASP_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     273           2 :   lcpomap["ASP_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     274           2 :   lcpomap["ASP_CG"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     275           2 :   lcpomap["ASP_OD1"] = { 1.6,  0.77914,  -0.25262,  -0.0016056,  0.00035071};
+     276           2 :   lcpomap["ASP_OD2"] = { 1.6,  0.77914,  -0.25262,  -0.0016056,  0.00035071};
+     277           2 :   lcpomap["ASN_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     278           2 :   lcpomap["ASN_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     279           2 :   lcpomap["ASN_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     280           2 :   lcpomap["ASN_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     281           2 :   lcpomap["ASN_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     282           2 :   lcpomap["ASN_CG"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     283           2 :   lcpomap["ASN_OD1"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     284           2 :   lcpomap["ASN_ND2"] = { 1.65,  0.73511,  -0.22116,  -0.00089148,  0.0002523};
+     285           2 :   lcpomap["ARG_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     286           2 :   lcpomap["ARG_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     287           2 :   lcpomap["ARG_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     288           2 :   lcpomap["ARG_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     289           2 :   lcpomap["ARG_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     290           2 :   lcpomap["ARG_CG"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     291           2 :   lcpomap["ARG_CD"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     292           2 :   lcpomap["ARG_NE"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     293           2 :   lcpomap["ARG_NH1"] = { 1.65,  0.73511,  -0.22116,  -0.00089148,  0.0002523};
+     294           2 :   lcpomap["ARG_NH2"] = { 1.65,  0.73511,  -0.22116,  -0.00089148,  0.0002523};
+     295           2 :   lcpomap["ARG_CZ"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     296           2 :   lcpomap["CYS_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     297           2 :   lcpomap["CYS_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     298           2 :   lcpomap["CYS_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     299           2 :   lcpomap["CYS_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     300           2 :   lcpomap["CYS_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     301           2 :   lcpomap["CYS_SG"] = { 1.9,  0.54581,  -0.19477,  -0.0012873,  0.00029247};
+     302           2 :   lcpomap["GLU_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     303           2 :   lcpomap["GLU_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     304           2 :   lcpomap["GLU_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     305           2 :   lcpomap["GLU_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     306           2 :   lcpomap["GLU_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     307           2 :   lcpomap["GLU_CG"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     308           2 :   lcpomap["GLU_CD"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     309           2 :   lcpomap["GLU_OE1"] = { 1.6,  0.77914,  -0.25262,  -0.0016056,  0.00035071};
+     310           2 :   lcpomap["GLU_OE2"] = { 1.6,  0.77914,  -0.25262,  -0.0016056,  0.00035071};
+     311           2 :   lcpomap["GLN_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     312           2 :   lcpomap["GLN_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     313           2 :   lcpomap["GLN_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     314           2 :   lcpomap["GLN_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     315           2 :   lcpomap["GLN_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     316           2 :   lcpomap["GLN_CG"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     317           2 :   lcpomap["GLN_CD"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     318           2 :   lcpomap["GLN_OE1"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     319           2 :   lcpomap["GLN_NE2"] = { 1.65,  0.73511,  -0.22116,  -0.00089148,  0.0002523};
+     320           2 :   lcpomap["GLY_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     321           2 :   lcpomap["GLY_CA"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     322           2 :   lcpomap["GLY_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     323           2 :   lcpomap["GLY_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     324           2 :   lcpomap["HIS_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     325           2 :   lcpomap["HIS_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     326           2 :   lcpomap["HIS_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     327           2 :   lcpomap["HIS_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     328           2 :   lcpomap["HIS_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     329           2 :   lcpomap["HIS_CG"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     330           2 :   lcpomap["HIS_ND1"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     331           2 :   lcpomap["HIS_CE1"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+     332           2 :   lcpomap["HIS_NE2"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     333           2 :   lcpomap["HIS_CD2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+     334           2 :   lcpomap["ILE_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     335           2 :   lcpomap["ILE_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     336           2 :   lcpomap["ILE_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     337           2 :   lcpomap["ILE_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     338           2 :   lcpomap["ILE_CB"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     339           2 :   lcpomap["ILE_CG2"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+     340           2 :   lcpomap["ILE_CG1"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     341           2 :   lcpomap["ILE_CD1"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+     342           2 :   lcpomap["LEU_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     343           2 :   lcpomap["LEU_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     344           2 :   lcpomap["LEU_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     345           2 :   lcpomap["LEU_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     346           2 :   lcpomap["LEU_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     347           2 :   lcpomap["LEU_CG"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     348           2 :   lcpomap["LEU_CD1"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+     349           2 :   lcpomap["LEU_CD2"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+     350           2 :   lcpomap["LYS_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     351           2 :   lcpomap["LYS_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     352           2 :   lcpomap["LYS_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     353           2 :   lcpomap["LYS_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     354           2 :   lcpomap["LYS_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     355           2 :   lcpomap["LYS_CG"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     356           2 :   lcpomap["LYS_CD"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     357           2 :   lcpomap["LYS_CE"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     358           2 :   lcpomap["LYS_NZ"] = { 1.65,  0.73511,  -0.22116,  -0.00089148,  0.0002523};
+     359           2 :   lcpomap["MET_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     360           2 :   lcpomap["MET_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     361           2 :   lcpomap["MET_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     362           2 :   lcpomap["MET_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     363           2 :   lcpomap["MET_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     364           2 :   lcpomap["MET_CG"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     365           2 :   lcpomap["MET_SD"] = { 1.9,  0.54581,  -0.19477,  -0.0012873,  0.00029247};
+     366           2 :   lcpomap["MET_CE"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+     367           2 :   lcpomap["PHE_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     368           2 :   lcpomap["PHE_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     369           2 :   lcpomap["PHE_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     370           2 :   lcpomap["PHE_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     371           2 :   lcpomap["PHE_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     372           2 :   lcpomap["PHE_CG"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     373           2 :   lcpomap["PHE_CD1"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+     374           2 :   lcpomap["PHE_CE1"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+     375           2 :   lcpomap["PHE_CZ"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+     376           2 :   lcpomap["PHE_CE2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+     377           2 :   lcpomap["PHE_CD2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+     378           2 :   lcpomap["PRO_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     379           2 :   lcpomap["PRO_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     380           2 :   lcpomap["PRO_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     381           2 :   lcpomap["PRO_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     382           2 :   lcpomap["PRO_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     383           2 :   lcpomap["PRO_CG"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     384           2 :   lcpomap["PRO_CD"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     385           2 :   lcpomap["SER_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     386           2 :   lcpomap["SER_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     387           2 :   lcpomap["SER_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     388           2 :   lcpomap["SER_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     389           2 :   lcpomap["SER_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     390           2 :   lcpomap["SER_OG"] = { 1.6,  0.77914,  -0.25262,  -0.0016056,  0.00035071};
+     391           2 :   lcpomap["THR_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     392           2 :   lcpomap["THR_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     393           2 :   lcpomap["THR_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     394           2 :   lcpomap["THR_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     395           2 :   lcpomap["THR_CB"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     396           2 :   lcpomap["THR_CG2"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+     397           2 :   lcpomap["THR_OG1"] = { 1.6,  0.77914,  -0.25262,  -0.0016056,  0.00035071};
+     398           2 :   lcpomap["TRP_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     399           2 :   lcpomap["TRP_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     400           2 :   lcpomap["TRP_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     401           2 :   lcpomap["TRP_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     402           2 :   lcpomap["TRP_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     403           2 :   lcpomap["TRP_CG"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     404           2 :   lcpomap["TRP_CD1"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+     405           2 :   lcpomap["TRP_NE1"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     406           2 :   lcpomap["TRP_CE2"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     407           2 :   lcpomap["TRP_CZ2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+     408           2 :   lcpomap["TRP_CH2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+     409           2 :   lcpomap["TRP_CZ3"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+     410           2 :   lcpomap["TRP_CE3"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+     411           2 :   lcpomap["TRP_CD2"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     412           2 :   lcpomap["TYR_N"] = { 1.65,  0.062577,  -0.017874,  -8.312e-05,  1.9849e-05};
+     413           2 :   lcpomap["TYR_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     414           2 :   lcpomap["TYR_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     415           2 :   lcpomap["TYR_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     416           2 :   lcpomap["TYR_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     417           2 :   lcpomap["TYR_CG"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     418           2 :   lcpomap["TYR_CD1"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+     419           2 :   lcpomap["TYR_CE1"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+     420           2 :   lcpomap["TYR_CZ"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     421           2 :   lcpomap["TYR_OH"] = { 1.6,  0.77914,  -0.25262,  -0.0016056,  0.00035071};
+     422           2 :   lcpomap["TYR_CE2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+     423           2 :   lcpomap["TYR_CD2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+     424           2 :   lcpomap["VAL_N"] = { 1.65,  0.062577,  -0.017874,  -8.312e-05,  1.9849e-05};
+     425           2 :   lcpomap["VAL_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     426           2 :   lcpomap["VAL_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     427           2 :   lcpomap["VAL_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     428           2 :   lcpomap["VAL_CB"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     429           2 :   lcpomap["VAL_CG1"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+     430           2 :   lcpomap["VAL_CG2"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+     431           2 :   return lcpomap;
+     432             : }
+     433             : 
+     434             : //assigns LCPO parameters to each atom reading from database
+     435           2 : void SASA_LCPO::readLCPOparam() {
+     436             : 
+     437         242 :   for(unsigned i=0; i<natoms; i++) {
+     438         240 :     LCPOparam[i].clear();
+     439             :   }
+     440             : 
+     441             :   map<string, vector<double> > lcpomap;
+     442           4 :   lcpomap = setupLCPOparam();
+     443             :   vector<double> LCPOparamVector;
+     444             :   string identifier;
+     445         242 :   for(unsigned i=0; i<natoms; i++) {
+     446         240 :     if ((AtomResidueName[0][i][0]=='O') || (AtomResidueName[0][i][0]=='N') || (AtomResidueName[0][i][0]=='C') || (AtomResidueName[0][i][0]=='S')) {
+     447         240 :       identifier = AtomResidueName[1][i]+"_"+AtomResidueName[0][i];
+     448         120 :       LCPOparamVector = lcpomap.at(identifier);
+     449         120 :       LCPOparam[i].push_back (LCPOparamVector[0]+rs*10);
+     450         120 :       LCPOparam[i].push_back (LCPOparamVector[1]);
+     451         120 :       LCPOparam[i].push_back (LCPOparamVector[2]);
+     452         120 :       LCPOparam[i].push_back (LCPOparamVector[3]);
+     453         120 :       LCPOparam[i].push_back (LCPOparamVector[4]);
+     454             :     }
+     455             :   }
+     456             : 
+     457             : 
+     458         242 :   for(unsigned i=0; i<natoms; i++) {
+     459         240 :     if (LCPOparam[i].size()==0 ) {
+     460         120 :       if ((AtomResidueName[0][i][0]=='O') || (AtomResidueName[0][i][0]=='N') || (AtomResidueName[0][i][0]=='C') || (AtomResidueName[0][i][0]=='S')) {
+     461           0 :         cout << "Could not find LCPO paramaters for atom " << AtomResidueName[0][i] << " of residue " << AtomResidueName[1][i] << endl;
+     462           0 :         error ("missing LCPO parameters\n");
+     463             :       }
+     464             :     }
+     465             :   }
+     466             : 
+     467           2 :   if (AtomResidueName[0][0] == "N") {
+     468           2 :     LCPOparam[0][1] = 7.3511e-01;
+     469           2 :     LCPOparam[0][2] = -2.2116e-01;
+     470           2 :     LCPOparam[0][3] = -8.9148e-04;
+     471           2 :     LCPOparam[0][4] = 2.5230e-04;
+     472             :   }
+     473             : 
+     474           2 :   if (AtomResidueName[0][natoms-1] == "O") {
+     475           2 :     LCPOparam[natoms-1][1] = 8.8857e-01;
+     476           2 :     LCPOparam[natoms-1][2] = -3.3421e-01;
+     477           2 :     LCPOparam[natoms-1][3] = -1.8683e-03;
+     478           2 :     LCPOparam[natoms-1][4] = 4.9372e-04;
+     479             :   }
+     480           2 : }
+     481             : 
+     482             : 
+     483             : //Max Surf values, used only if TYPE=TRANSFER
+     484           1 : map<string, vector<double> > SASA_LCPO::setupMaxSurfMap() {
+     485             :   // Max Surface Area for backbone and sidechain, in nm2
+     486             :   map<string, vector<double> > valuemap;
+     487           1 :   valuemap ["ALA"]= {0.671446,0.420263,};
+     488           1 :   valuemap ["ARG"]= {0.578582,1.95454,};
+     489           1 :   valuemap ["ASN"]= {0.559411,1.07102,};
+     490           1 :   valuemap ["ASP"]= {0.558363,1.03971,};
+     491           1 :   valuemap ["CYS"]= {0.609271,0.657612,};
+     492           1 :   valuemap ["GLN"]= {0.565651,1.433031,};
+     493           1 :   valuemap ["GLU"]= {0.572399,1.41848,};
+     494           1 :   valuemap ["GLY"]= {0.861439,0,};
+     495           1 :   valuemap ["HIS"]= {0.559929,1.143827,};
+     496           1 :   valuemap ["ILE"]= {0.553491,1.25334,};
+     497           1 :   valuemap ["LEU"]= {0.570103,1.260459,};
+     498           1 :   valuemap ["LYS"]= {0.580304,1.687487,};
+     499           1 :   valuemap ["MET"]= {0.5856,1.498954,};
+     500           1 :   valuemap ["PHE"]= {0.54155,1.394861,};
+     501           1 :   valuemap ["PRO"]= {0.456048,0.849461,};
+     502           1 :   valuemap ["SER"]= {0.59074,0.714538,};
+     503           1 :   valuemap ["THR"]= {0.559116,0.951644,};
+     504           1 :   valuemap ["TRP"]= {0.55536,1.59324,};
+     505           1 :   valuemap ["TYR"]= {0.451171,1.566918,};
+     506           1 :   valuemap ["VAL"]= {0.454809,0.928685,};
+     507           1 :   return valuemap;
+     508             : }
+     509             : 
+     510             : 
+     511             : 
+     512             : //reads maximum surface values per residue type and assigns values to each atom, only used if sasa_type = TRANSFER
+     513             : 
+     514           1 : void SASA_LCPO::readMaxSurf() {
+     515             :   map<string, vector<double> > valuemap;
+     516           2 :   valuemap = setupMaxSurfMap();
+     517             :   vector<double> MaxSurfVector;
+     518             : 
+     519         121 :   for(unsigned i=0; i<natoms; i++) {
+     520         120 :     MaxSurf[i].clear();
+     521         120 :     MaxSurfVector = valuemap.at(AtomResidueName[1][i]);
+     522         120 :     MaxSurf[i].push_back (MaxSurfVector[0]*100);
+     523         120 :     MaxSurf[i].push_back (MaxSurfVector[1]*100);
+     524             :   }
+     525           1 : }
+     526             : 
+     527             : //reads file with free energy values for sidechains and for the backbone, and assigns values to each atom. Only used if sasa_type = TRANSFER
+     528             : 
+     529           1 : void SASA_LCPO::readDeltaG() {
+     530             : 
+     531         121 :   for(unsigned i=0; i<natoms; i++) {
+     532         120 :     DeltaG[i].clear();
+     533             :   }
+     534             : 
+     535             :   string DeltaGline;
+     536           1 :   fstream DeltaGFile;
+     537           1 :   DeltaGFile.open(DeltaGValues);
+     538           1 :   if (DeltaGFile) {
+     539             :     int backboneflag = 0;
+     540          23 :     while(getline(DeltaGFile, DeltaGline)) {
+     541          22 :       if(!DeltaGline.empty()) {
+     542             :         std::vector<std::string> DeltaGtoken;
+     543          21 :         split(DeltaGline, DeltaGtoken);
+     544        2541 :         for(unsigned i=0; i<natoms; i++) {
+     545        2520 :           if (DeltaGtoken[0].compare(AtomResidueName[1][i])==0 ) {
+     546         120 :             DeltaG[i].push_back (std::atof(DeltaGtoken[1].c_str()));
+     547             :           }
+     548             :         }
+     549          21 :         if (DeltaGtoken[0].compare("BACKBONE")==0 ) {
+     550             :           backboneflag = 1;
+     551           1 :           DeltaG[natoms].push_back (std::atof(DeltaGtoken[1].c_str()));
+     552             :         }
+     553          21 :       }
+     554             :     }
+     555           1 :     if ( backboneflag == 0) error("Cannot find backbone value in Delta G parameters file\n");
+     556             :   }
+     557           0 :   else error("Cannot open DeltaG file");
+     558             : 
+     559         121 :   for(unsigned i=0; i<natoms; i++) {
+     560         120 :     if (DeltaG[i].size()==0 ) {
+     561           0 :       cout << "Delta G value for residue " << AtomResidueName[1][i] << " not found " << endl;
+     562           0 :       error ("missing Delta G parameter\n");
+     563             :     }
+     564             :   }
+     565             : 
+     566           2 : }
+     567             : 
+     568             : //computes free energy values for the sidechains and for the backbone, and assigns values to each atom. Only used if sasa_type = TRANSFER, and if no DELTAGFILE is provided. In this case, the free energy values are those describing the effect of temperature, and the program must know if approach 2 or 3 (as described in Arsiccio and Shea, Protein Cold Denaturation in Implicit Solvent Simulations: A Transfer Free Energy Approach, JPCB, 2021) needs to be used to compute them.
+     569             : 
+     570           0 : void SASA_LCPO::computeDeltaG() {
+     571             : 
+     572           0 :   for(unsigned i=0; i<natoms; i++) {
+     573           0 :     DeltaG[i].clear();
+     574             :   }
+     575             : 
+     576             :   double T;
+     577           0 :   T = getkBT()/getKBoltzmann();
+     578             : 
+     579           0 :   if (T != Ti) {
+     580           0 :     for(unsigned i=0; i<natoms; i++) {
+     581           0 :       if (approach==2) {
+     582           0 :         if (AtomResidueName[1][i].compare("ALA")==0) {
+     583           0 :           DeltaG[i].push_back (-2.995/1000*std::pow(T,2)+1.808*T-272.895);
+     584             :         }
+     585           0 :         if (AtomResidueName[1][i].compare("ARG")==0) {
+     586           0 :           DeltaG[i].push_back (-3.182/1000*std::pow(T,2)+1.894*T-282.032);
+     587             :         }
+     588           0 :         if (AtomResidueName[1][i].compare("ASN")==0) {
+     589           0 :           DeltaG[i].push_back (-1.047/1000*std::pow(T,2)+0.6068*T-87.846);
+     590             :         }
+     591           0 :         if (AtomResidueName[1][i].compare("ASP")==0) {
+     592           0 :           DeltaG[i].push_back (-0.1794/1000*std::pow(T,2)+0.1091*T-16.526);
+     593             :         }
+     594           0 :         if (AtomResidueName[1][i].compare("CYS")==0) {
+     595           0 :           DeltaG[i].push_back (-3.09/1000*std::pow(T,2)+1.835*T-272.26);
+     596             :         }
+     597           0 :         if (AtomResidueName[1][i].compare("GLN")==0) {
+     598           0 :           DeltaG[i].push_back (-2.23/1000*std::pow(T,2)+1.335*T-199.707);
+     599             :         }
+     600           0 :         if (AtomResidueName[1][i].compare("GLU")==0) {
+     601           0 :           DeltaG[i].push_back (-1.511/1000*std::pow(T,2)+0.8904*T-131.168);
+     602             :         }
+     603           0 :         if (AtomResidueName[1][i].compare("GLY")==0) {
+     604           0 :           DeltaG[i].push_back (0);
+     605             :         }
+     606           0 :         if (AtomResidueName[1][i].compare("HIS")==0) {
+     607           0 :           DeltaG[i].push_back (-3.482/1000*std::pow(T,2)+2.084*T-311.694);
+     608             :         }
+     609           0 :         if (AtomResidueName[1][i].compare("ILE")==0) {
+     610           0 :           DeltaG[i].push_back (-6.364/1000*std::pow(T,2)+3.8*T-567.444);
+     611             :         }
+     612           0 :         if (AtomResidueName[1][i].compare("LEU")==0) {
+     613           0 :           DeltaG[i].push_back (-7.466/1000*std::pow(T,2)+4.417*T-653.394);
+     614             :         }
+     615           0 :         if (AtomResidueName[1][i].compare("LYS")==0) {
+     616           0 :           DeltaG[i].push_back (-2.091/1000*std::pow(T,2)+1.2458*T-185.549);
+     617             :         }
+     618           0 :         if (AtomResidueName[1][i].compare("MET")==0) {
+     619           0 :           DeltaG[i].push_back (-3.807/1000*std::pow(T,2)+2.272*T-339.007);
+     620             :         }
+     621           0 :         if (AtomResidueName[1][i].compare("PHE")==0) {
+     622           0 :           DeltaG[i].push_back (-7.828/1000*std::pow(T,2)+4.644*T-688.874);
+     623             :         }
+     624           0 :         if (AtomResidueName[1][i].compare("PRO")==0) {
+     625           0 :           DeltaG[i].push_back (-2.347/1000*std::pow(T,2)+1.411*T-212.059);
+     626             :         }
+     627           0 :         if (AtomResidueName[1][i].compare("SER")==0) {
+     628           0 :           DeltaG[i].push_back (1.813/1000*std::pow(T,2)-1.05*T+151.957);
+     629             :         }
+     630           0 :         if (AtomResidueName[1][i].compare("THR")==0) {
+     631           0 :           DeltaG[i].push_back (-2.64/1000*std::pow(T,2)+1.591*T-239.516);
+     632             :         }
+     633           0 :         if (AtomResidueName[1][i].compare("TRP")==0) {
+     634           0 :           DeltaG[i].push_back (-11.66/1000*std::pow(T,2)+6.916*T-1025.293);
+     635             :         }
+     636           0 :         if (AtomResidueName[1][i].compare("TYR")==0) {
+     637           0 :           DeltaG[i].push_back (-7.513/1000*std::pow(T,2)+4.478*T-667.261);
+     638             :         }
+     639           0 :         if (AtomResidueName[1][i].compare("VAL")==0) {
+     640           0 :           DeltaG[i].push_back (-4.902/1000*std::pow(T,2)+2.921*T-435.309);
+     641             :         }
+     642           0 :         DeltaG[natoms].push_back (-0.6962/1000*std::pow(T,2)+0.4426*T-70.015);
+     643             :       }
+     644           0 :       if (approach==3) {
+     645           0 :         if (AtomResidueName[1][i].compare("ALA")==0) {
+     646           0 :           DeltaG[i].push_back (-2.995/1000*std::pow(T,2)+1.808*T-272.105);
+     647             :         }
+     648           0 :         if (AtomResidueName[1][i].compare("ARG")==0) {
+     649           0 :           DeltaG[i].push_back (-3.182/1000*std::pow(T,2)+1.894*T-284.086);
+     650             :         }
+     651           0 :         if (AtomResidueName[1][i].compare("ASN")==0) {
+     652           0 :           DeltaG[i].push_back (-1.047/1000*std::pow(T,2)+0.6068*T-90.597);
+     653             :         }
+     654           0 :         if (AtomResidueName[1][i].compare("ASP")==0) {
+     655           0 :           DeltaG[i].push_back (-0.1794/1000*std::pow(T,2)+0.1091*T-19.143);
+     656             :         }
+     657           0 :         if (AtomResidueName[1][i].compare("CYS")==0) {
+     658           0 :           DeltaG[i].push_back (-3.09/1000*std::pow(T,2)+1.835*T-268.527);
+     659             :         }
+     660           0 :         if (AtomResidueName[1][i].compare("GLN")==0) {
+     661           0 :           DeltaG[i].push_back (-2.23/1000*std::pow(T,2)+1.335*T-201.559);
+     662             :         }
+     663           0 :         if (AtomResidueName[1][i].compare("GLU")==0) {
+     664           0 :           DeltaG[i].push_back (-1.511/1000*std::pow(T,2)+0.8904*T-133.543);
+     665             :         }
+     666           0 :         if (AtomResidueName[1][i].compare("GLY")==0) {
+     667           0 :           DeltaG[i].push_back (0);
+     668             :         }
+     669           0 :         if (AtomResidueName[1][i].compare("HIS")==0) {
+     670           0 :           DeltaG[i].push_back (-3.482/1000*std::pow(T,2)+2.084*T-315.398);
+     671             :         }
+     672           0 :         if (AtomResidueName[1][i].compare("ILE")==0) {
+     673           0 :           DeltaG[i].push_back (-6.364/1000*std::pow(T,2)+3.8*T-564.825);
+     674             :         }
+     675           0 :         if (AtomResidueName[1][i].compare("LEU")==0) {
+     676           0 :           DeltaG[i].push_back (-7.466/1000*std::pow(T,2)+4.417*T-651.483);
+     677             :         }
+     678           0 :         if (AtomResidueName[1][i].compare("LYS")==0) {
+     679           0 :           DeltaG[i].push_back (-2.091/1000*std::pow(T,2)+1.2458*T-187.485);
+     680             :         }
+     681           0 :         if (AtomResidueName[1][i].compare("MET")==0) {
+     682           0 :           DeltaG[i].push_back (-3.807/1000*std::pow(T,2)+2.272*T-339.242);
+     683             :         }
+     684           0 :         if (AtomResidueName[1][i].compare("PHE")==0) {
+     685           0 :           DeltaG[i].push_back (-7.828/1000*std::pow(T,2)+4.644*T-687.134);
+     686             :         }
+     687           0 :         if (AtomResidueName[1][i].compare("PRO")==0) {
+     688           0 :           DeltaG[i].push_back (-2.347/1000*std::pow(T,2)+1.411*T-214.211);
+     689             :         }
+     690           0 :         if (AtomResidueName[1][i].compare("SER")==0) {
+     691           0 :           DeltaG[i].push_back (1.813/1000*std::pow(T,2)-1.05*T+150.289);
+     692             :         }
+     693           0 :         if (AtomResidueName[1][i].compare("THR")==0) {
+     694           0 :           DeltaG[i].push_back (-2.64/1000*std::pow(T,2)+1.591*T-240.267);
+     695             :         }
+     696           0 :         if (AtomResidueName[1][i].compare("TRP")==0) {
+     697           0 :           DeltaG[i].push_back (-11.66/1000*std::pow(T,2)+6.916*T-1024.284);
+     698             :         }
+     699           0 :         if (AtomResidueName[1][i].compare("TYR")==0) {
+     700           0 :           DeltaG[i].push_back (-7.513/1000*std::pow(T,2)+4.478*T-666.484);
+     701             :         }
+     702           0 :         if (AtomResidueName[1][i].compare("VAL")==0) {
+     703           0 :           DeltaG[i].push_back (-4.902/1000*std::pow(T,2)+2.921*T-433.013);
+     704             :         }
+     705           0 :         DeltaG[natoms].push_back (-0.6927/1000*std::pow(T,2)+0.4404*T-68.724);
+     706             :       }
+     707             :     }
+     708             :   }
+     709             : 
+     710           0 :   Ti = T;
+     711             : 
+     712           0 :   if (firstStepFlag ==0) {
+     713           0 :     if (approach!=2 && approach!=3) {
+     714           0 :       cout << "Unknown approach " << approach << endl;
+     715             :     }
+     716           0 :     for(unsigned i=0; i<natoms; i++) {
+     717           0 :       if (DeltaG[i].size()==0 ) {
+     718           0 :         cout << "Delta G value for residue " << AtomResidueName[1][i] << " not found " << endl;
+     719           0 :         error ("missing Delta G parameter\n");
+     720             :       }
+     721             :     }
+     722             :   }
+     723           0 : }
+     724             : 
+     725             : 
+     726             : //calculates neighbor list
+     727          24 : void SASA_LCPO::calcNlist() {
+     728          24 :   if(!nopbc) makeWhole();
+     729             : 
+     730        2904 :   for(unsigned i = 0; i < natoms; i++) {
+     731        2880 :     Nlist[i].clear();
+     732             :   }
+     733             : 
+     734        2904 :   for(unsigned i = 0; i < natoms; i++) {
+     735        2880 :     if (LCPOparam[i].size()>0) {
+     736       87264 :       for (unsigned j = 0; j < i; j++) {
+     737       85824 :         if (LCPOparam[j].size()>0) {
+     738       42480 :           const Vector Delta_ij_vec = delta( getPosition(i), getPosition(j) );
+     739       42480 :           double Delta_ij_mod = Delta_ij_vec.modulo()*10;
+     740       42480 :           double overlapD = LCPOparam[i][0]+LCPOparam[j][0];
+     741       42480 :           if (Delta_ij_mod < overlapD) {
+     742       19030 :             Nlist.at(i).push_back (j);
+     743       19030 :             Nlist.at(j).push_back (i);
+     744             :           }
+     745             :         }
+     746             :       }
+     747             :     }
+     748             :   }
+     749          24 : }
+     750             : 
+     751             : 
+     752             : //calculates SASA according to LCPO algorithm
+     753          24 : void SASA_LCPO::calculate() {
+     754          24 :   if(!nopbc) makeWhole();
+     755             : 
+     756          24 :   if(getExchangeStep()) nl_update = 0;
+     757          24 :   if (firstStepFlag ==0) {
+     758           2 :     readPDB();
+     759           2 :     readLCPOparam();
+     760             :   }
+     761          24 :   if (nl_update == 0) {
+     762          24 :     calcNlist();
+     763             :   }
+     764             : 
+     765             : 
+     766             : 
+     767             :   double S1, Aij, Ajk, Aijk, Aijt, Ajkt, Aikt;
+     768             :   double dAdd;
+     769          24 :   double sasa = 0;
+     770          24 :   vector<Vector> derivatives( natoms );
+     771          24 :   Tensor virial;
+     772          24 :   vector <double> dAijdc_2t(3);
+     773          24 :   vector <double> dSASA_2_neigh_dc(3);
+     774          24 :   vector <double> ddij_di(3);
+     775          24 :   vector <double> ddik_di(3);
+     776             : 
+     777          24 :   if( sasa_type==TOTAL ) {
+     778        1452 :     for(unsigned i = 0; i < natoms; i++) {
+     779        1440 :       derivatives[i][0] = 0.;
+     780        1440 :       derivatives[i][1] = 0.;
+     781        1440 :       derivatives[i][2] = 0.;
+     782        1440 :       if ( LCPOparam[i].size()>1) {
+     783         720 :         if (LCPOparam[i][1]>0.0) {
+     784             :           Aij = 0.0;
+     785             :           Aijk = 0.0;
+     786             :           Ajk = 0.0;
+     787         720 :           double ri = LCPOparam[i][0];
+     788         720 :           S1 = 4*M_PI*ri*ri;
+     789         720 :           vector <double> dAijdc_2(3, 0);
+     790         720 :           vector <double> dAijdc_4(3, 0);
+     791             : 
+     792             : 
+     793       19750 :           for (unsigned j = 0; j < Nlist[i].size(); j++) {
+     794       19030 :             const Vector d_ij_vec = delta( getPosition(i), getPosition(Nlist[i][j]) );
+     795       19030 :             double d_ij = d_ij_vec.modulo()*10;
+     796             : 
+     797       19030 :             double rj = LCPOparam[Nlist[i][j]][0];
+     798       19030 :             Aijt = (2*M_PI*ri*(ri-d_ij/2-((ri*ri-rj*rj)/(2*d_ij))));
+     799       19030 :             double sji = (2*M_PI*rj*(rj-d_ij/2+((ri*ri-rj*rj)/(2*d_ij))));
+     800             : 
+     801       19030 :             dAdd = M_PI*rj*(-(ri*ri-rj*rj)/(d_ij*d_ij)-1);
+     802             : 
+     803       19030 :             ddij_di[0] = -10*(getPosition(Nlist[i][j])[0]-getPosition(i)[0])/d_ij;
+     804       19030 :             ddij_di[1] = -10*(getPosition(Nlist[i][j])[1]-getPosition(i)[1])/d_ij;
+     805       19030 :             ddij_di[2] = -10*(getPosition(Nlist[i][j])[2]-getPosition(i)[2])/d_ij;
+     806             : 
+     807             :             Ajkt = 0.0;
+     808             :             Aikt = 0.0;
+     809             : 
+     810       19030 :             vector <double> dSASA_3_neigh_dc(3, 0.0);
+     811       19030 :             vector <double> dSASA_4_neigh_dc(3, 0.0);
+     812       19030 :             vector <double> dSASA_3_neigh_dc2(3, 0.0);
+     813       19030 :             vector <double> dSASA_4_neigh_dc2(3, 0.0);
+     814             : 
+     815       19030 :             dSASA_2_neigh_dc[0] = dAdd * ddij_di[0];
+     816       19030 :             dSASA_2_neigh_dc[1] = dAdd * ddij_di[1];
+     817       19030 :             dSASA_2_neigh_dc[2] = dAdd * ddij_di[2];
+     818             : 
+     819       19030 :             dAdd = M_PI*ri*((ri*ri-rj*rj)/(d_ij*d_ij)-1);
+     820             : 
+     821             : 
+     822       19030 :             dAijdc_2t[0] = dAdd * ddij_di[0];
+     823       19030 :             dAijdc_2t[1] = dAdd * ddij_di[1];
+     824       19030 :             dAijdc_2t[2] = dAdd * ddij_di[2];
+     825             : 
+     826      560038 :             for (unsigned k = 0; k < Nlist[Nlist[i][j]].size(); k++) {
+     827      541008 :               if (std::find (Nlist[i].begin(), Nlist[i].end(), Nlist[Nlist[i][j]][k]) !=  Nlist[i].end()) {
+     828      370872 :                 const Vector d_jk_vec = delta( getPosition(Nlist[i][j]), getPosition(Nlist[Nlist[i][j]][k]) );
+     829      370872 :                 const Vector d_ik_vec = delta( getPosition(i), getPosition(Nlist[Nlist[i][j]][k]) );
+     830             : 
+     831      370872 :                 double d_jk = d_jk_vec.modulo()*10;
+     832      370872 :                 double d_ik = d_ik_vec.modulo()*10;
+     833             : 
+     834      370872 :                 double rk = LCPOparam[Nlist[Nlist[i][j]][k]][0];
+     835      370872 :                 double sjk =  (2*M_PI*rj*(rj-d_jk/2-((rj*rj-rk*rk)/(2*d_jk))));
+     836      370872 :                 Ajkt += sjk;
+     837      370872 :                 Aikt += (2*M_PI*ri*(ri-d_ik/2-((ri*ri-rk*rk)/(2*d_ik))));
+     838             : 
+     839      370872 :                 dAdd = M_PI*ri*((ri*ri-rk*rk)/(d_ik*d_ik)-1);
+     840             : 
+     841      370872 :                 ddik_di[0] = -10*(getPosition(Nlist[Nlist[i][j]][k])[0]-getPosition(i)[0])/d_ik;
+     842      370872 :                 ddik_di[1] = -10*(getPosition(Nlist[Nlist[i][j]][k])[1]-getPosition(i)[1])/d_ik;
+     843      370872 :                 ddik_di[2] = -10*(getPosition(Nlist[Nlist[i][j]][k])[2]-getPosition(i)[2])/d_ik;
+     844             : 
+     845             : 
+     846      370872 :                 dSASA_3_neigh_dc[0] += dAdd*ddik_di[0];
+     847      370872 :                 dSASA_3_neigh_dc[1] += dAdd*ddik_di[1];
+     848      370872 :                 dSASA_3_neigh_dc[2] += dAdd*ddik_di[2];
+     849             : 
+     850      370872 :                 dAdd = M_PI*rk*(-(ri*ri-rk*rk)/(d_ik*d_ik)-1);
+     851             : 
+     852      370872 :                 dSASA_3_neigh_dc2[0] += dAdd*ddik_di[0];
+     853      370872 :                 dSASA_3_neigh_dc2[1] += dAdd*ddik_di[1];
+     854      370872 :                 dSASA_3_neigh_dc2[2] += dAdd*ddik_di[2];
+     855             : 
+     856      370872 :                 dSASA_4_neigh_dc2[0] += sjk*dAdd*ddik_di[0];
+     857      370872 :                 dSASA_4_neigh_dc2[1] += sjk*dAdd*ddik_di[1];
+     858      370872 :                 dSASA_4_neigh_dc2[2] += sjk*dAdd*ddik_di[2];
+     859             : 
+     860             :               }
+     861             :             }
+     862       19030 :             dSASA_4_neigh_dc[0] = sji*dSASA_3_neigh_dc[0] + dSASA_4_neigh_dc2[0];
+     863       19030 :             dSASA_4_neigh_dc[1] = sji*dSASA_3_neigh_dc[1] + dSASA_4_neigh_dc2[1];
+     864       19030 :             dSASA_4_neigh_dc[2] = sji*dSASA_3_neigh_dc[2] + dSASA_4_neigh_dc2[2];
+     865             : 
+     866       19030 :             dSASA_3_neigh_dc[0] += dSASA_3_neigh_dc2[0];
+     867       19030 :             dSASA_3_neigh_dc[1] += dSASA_3_neigh_dc2[1];
+     868       19030 :             dSASA_3_neigh_dc[2] += dSASA_3_neigh_dc2[2];
+     869             : 
+     870       19030 :             dSASA_4_neigh_dc[0] += dSASA_2_neigh_dc[0] * Aikt;
+     871       19030 :             dSASA_4_neigh_dc[1] += dSASA_2_neigh_dc[1] * Aikt;
+     872       19030 :             dSASA_4_neigh_dc[2] += dSASA_2_neigh_dc[2] * Aikt;
+     873             : 
+     874             : 
+     875       19030 :             derivatives[i][0] += (dSASA_2_neigh_dc[0]*LCPOparam[Nlist[i][j]][2] + dSASA_3_neigh_dc[0]*LCPOparam[Nlist[i][j]][3]+dSASA_4_neigh_dc[0]*LCPOparam[Nlist[i][j]][4])/10;
+     876       19030 :             derivatives[i][1] += (dSASA_2_neigh_dc[1]*LCPOparam[Nlist[i][j]][2] + dSASA_3_neigh_dc[1]*LCPOparam[Nlist[i][j]][3]+dSASA_4_neigh_dc[1]*LCPOparam[Nlist[i][j]][4])/10;
+     877       19030 :             derivatives[i][2] += (dSASA_2_neigh_dc[2]*LCPOparam[Nlist[i][j]][2] + dSASA_3_neigh_dc[2]*LCPOparam[Nlist[i][j]][3]+dSASA_4_neigh_dc[2]*LCPOparam[Nlist[i][j]][4])/10;
+     878             : 
+     879             : 
+     880       19030 :             Aijk += (Aijt * Ajkt);
+     881       19030 :             Aij += Aijt;
+     882       19030 :             Ajk += Ajkt;
+     883             : 
+     884       19030 :             dAijdc_2[0] += dAijdc_2t[0];
+     885       19030 :             dAijdc_2[1] += dAijdc_2t[1];
+     886       19030 :             dAijdc_2[2] += dAijdc_2t[2];
+     887             : 
+     888             : 
+     889       19030 :             dAijdc_4[0] += Ajkt*dAijdc_2t[0];
+     890       19030 :             dAijdc_4[1] += Ajkt*dAijdc_2t[1];
+     891       19030 :             dAijdc_4[2] += Ajkt*dAijdc_2t[2];
+     892             : 
+     893             : 
+     894             :           }
+     895         720 :           double sasai = (LCPOparam[i][1]*S1+LCPOparam[i][2]*Aij+LCPOparam[i][3]*Ajk+LCPOparam[i][4]*Aijk);
+     896         720 :           if (sasai > 0 ) sasa += sasai/100;
+     897         720 :           derivatives[i][0] += (dAijdc_2[0]*LCPOparam[i][2]+dAijdc_4[0]*LCPOparam[i][4])/10;
+     898         720 :           derivatives[i][1] += (dAijdc_2[1]*LCPOparam[i][2]+dAijdc_4[1]*LCPOparam[i][4])/10;
+     899         720 :           derivatives[i][2] += (dAijdc_2[2]*LCPOparam[i][2]+dAijdc_4[2]*LCPOparam[i][4])/10;
+     900             :         }
+     901             :       }
+     902        1440 :       virial -= Tensor(getPosition(i),derivatives[i]);
+     903             :     }
+     904             :   }
+     905             : 
+     906             : 
+     907             : 
+     908          24 :   if( sasa_type==TRANSFER ) {
+     909             : 
+     910          12 :     if (firstStepFlag ==0) {
+     911           1 :       readMaxSurf();
+     912             :     }
+     913             : 
+     914          12 :     if (firstStepFlag ==0 && DeltaGValues != "absent") {
+     915           1 :       readDeltaG();
+     916             :     }
+     917             : 
+     918          12 :     if (DeltaGValues == "absent") {
+     919           0 :       computeDeltaG();
+     920             :     }
+     921             : 
+     922             : 
+     923        1452 :     for(unsigned i = 0; i < natoms; i++) {
+     924             : 
+     925             : 
+     926             : 
+     927        1440 :       derivatives[i][0] = 0.;
+     928        1440 :       derivatives[i][1] = 0.;
+     929        1440 :       derivatives[i][2] = 0.;
+     930             : 
+     931        1440 :       if ( LCPOparam[i].size()>1) {
+     932         720 :         if (LCPOparam[i][1]>0.0) {
+     933             :           Aij = 0.0;
+     934             :           Aijk = 0.0;
+     935             :           Ajk = 0.0;
+     936         720 :           double ri = LCPOparam[i][0];
+     937         720 :           S1 = 4*M_PI*ri*ri;
+     938         720 :           vector <double> dAijdc_2(3, 0);
+     939         720 :           vector <double> dAijdc_4(3, 0);
+     940             : 
+     941             : 
+     942       19750 :           for (unsigned j = 0; j < Nlist[i].size(); j++) {
+     943       19030 :             const Vector d_ij_vec = delta( getPosition(i), getPosition(Nlist[i][j]) );
+     944       19030 :             double d_ij = d_ij_vec.modulo()*10;
+     945             : 
+     946       19030 :             double rj = LCPOparam[Nlist[i][j]][0];
+     947       19030 :             Aijt = (2*M_PI*ri*(ri-d_ij/2-((ri*ri-rj*rj)/(2*d_ij))));
+     948       19030 :             double sji = (2*M_PI*rj*(rj-d_ij/2+((ri*ri-rj*rj)/(2*d_ij))));
+     949             : 
+     950       19030 :             dAdd = M_PI*rj*(-(ri*ri-rj*rj)/(d_ij*d_ij)-1);
+     951       19030 :             ddij_di[0] = -10*(getPosition(Nlist[i][j])[0]-getPosition(i)[0])/d_ij;
+     952       19030 :             ddij_di[1] = -10*(getPosition(Nlist[i][j])[1]-getPosition(i)[1])/d_ij;
+     953       19030 :             ddij_di[2] = -10*(getPosition(Nlist[i][j])[2]-getPosition(i)[2])/d_ij;
+     954             : 
+     955             :             Ajkt = 0.0;
+     956             :             Aikt = 0.0;
+     957             : 
+     958       19030 :             vector <double> dSASA_3_neigh_dc(3, 0.0);
+     959       19030 :             vector <double> dSASA_4_neigh_dc(3, 0.0);
+     960       19030 :             vector <double> dSASA_3_neigh_dc2(3, 0.0);
+     961       19030 :             vector <double> dSASA_4_neigh_dc2(3, 0.0);
+     962             : 
+     963       19030 :             dSASA_2_neigh_dc[0] = dAdd * ddij_di[0];
+     964       19030 :             dSASA_2_neigh_dc[1] = dAdd * ddij_di[1];
+     965       19030 :             dSASA_2_neigh_dc[2] = dAdd * ddij_di[2];
+     966             : 
+     967       19030 :             dAdd = M_PI*ri*((ri*ri-rj*rj)/(d_ij*d_ij)-1);
+     968             : 
+     969       19030 :             dAijdc_2t[0] = dAdd * ddij_di[0];
+     970       19030 :             dAijdc_2t[1] = dAdd * ddij_di[1];
+     971       19030 :             dAijdc_2t[2] = dAdd * ddij_di[2];
+     972             : 
+     973      560038 :             for (unsigned k = 0; k < Nlist[Nlist[i][j]].size(); k++) {
+     974      541008 :               if (std::find (Nlist[i].begin(), Nlist[i].end(), Nlist[Nlist[i][j]][k]) !=  Nlist[i].end()) {
+     975      370872 :                 const Vector d_jk_vec = delta( getPosition(Nlist[i][j]), getPosition(Nlist[Nlist[i][j]][k]) );
+     976      370872 :                 const Vector d_ik_vec = delta( getPosition(i), getPosition(Nlist[Nlist[i][j]][k]) );
+     977             : 
+     978      370872 :                 double d_jk = d_jk_vec.modulo()*10;
+     979      370872 :                 double d_ik = d_ik_vec.modulo()*10;
+     980             : 
+     981      370872 :                 double rk = LCPOparam[Nlist[Nlist[i][j]][k]][0];
+     982      370872 :                 double sjk =  (2*M_PI*rj*(rj-d_jk/2-((rj*rj-rk*rk)/(2*d_jk))));
+     983      370872 :                 Ajkt += sjk;
+     984      370872 :                 Aikt += (2*M_PI*ri*(ri-d_ik/2-((ri*ri-rk*rk)/(2*d_ik))));
+     985             : 
+     986      370872 :                 dAdd = M_PI*ri*((ri*ri-rk*rk)/(d_ik*d_ik)-1);
+     987             : 
+     988      370872 :                 ddik_di[0] = -10*(getPosition(Nlist[Nlist[i][j]][k])[0]-getPosition(i)[0])/d_ik;
+     989      370872 :                 ddik_di[1] = -10*(getPosition(Nlist[Nlist[i][j]][k])[1]-getPosition(i)[1])/d_ik;
+     990      370872 :                 ddik_di[2] = -10*(getPosition(Nlist[Nlist[i][j]][k])[2]-getPosition(i)[2])/d_ik;
+     991             : 
+     992             : 
+     993      370872 :                 dSASA_3_neigh_dc[0] += dAdd*ddik_di[0];
+     994      370872 :                 dSASA_3_neigh_dc[1] += dAdd*ddik_di[1];
+     995      370872 :                 dSASA_3_neigh_dc[2] += dAdd*ddik_di[2];
+     996             : 
+     997      370872 :                 dAdd = M_PI*rk*(-(ri*ri-rk*rk)/(d_ik*d_ik)-1);
+     998             : 
+     999      370872 :                 dSASA_3_neigh_dc2[0] += dAdd*ddik_di[0];
+    1000      370872 :                 dSASA_3_neigh_dc2[1] += dAdd*ddik_di[1];
+    1001      370872 :                 dSASA_3_neigh_dc2[2] += dAdd*ddik_di[2];
+    1002             : 
+    1003      370872 :                 dSASA_4_neigh_dc2[0] += sjk*dAdd*ddik_di[0];
+    1004      370872 :                 dSASA_4_neigh_dc2[1] += sjk*dAdd*ddik_di[1];
+    1005      370872 :                 dSASA_4_neigh_dc2[2] += sjk*dAdd*ddik_di[2];
+    1006             : 
+    1007             :               }
+    1008             :             }
+    1009       19030 :             dSASA_4_neigh_dc[0] = sji*dSASA_3_neigh_dc[0] + dSASA_4_neigh_dc2[0];
+    1010       19030 :             dSASA_4_neigh_dc[1] = sji*dSASA_3_neigh_dc[1] + dSASA_4_neigh_dc2[1];
+    1011       19030 :             dSASA_4_neigh_dc[2] = sji*dSASA_3_neigh_dc[2] + dSASA_4_neigh_dc2[2];
+    1012             : 
+    1013       19030 :             dSASA_3_neigh_dc[0] += dSASA_3_neigh_dc2[0];
+    1014       19030 :             dSASA_3_neigh_dc[1] += dSASA_3_neigh_dc2[1];
+    1015       19030 :             dSASA_3_neigh_dc[2] += dSASA_3_neigh_dc2[2];
+    1016             : 
+    1017       19030 :             dSASA_4_neigh_dc[0] += dSASA_2_neigh_dc[0] * Aikt;
+    1018       19030 :             dSASA_4_neigh_dc[1] += dSASA_2_neigh_dc[1] * Aikt;
+    1019       19030 :             dSASA_4_neigh_dc[2] += dSASA_2_neigh_dc[2] * Aikt;
+    1020             : 
+    1021       19030 :             if (AtomResidueName[0][Nlist[i][j]] == "N" || AtomResidueName[0][Nlist[i][j]] == "CA"  || AtomResidueName[0][Nlist[i][j]] == "C" || AtomResidueName[0][Nlist[i][j]] == "O") {
+    1022       15720 :               derivatives[i][0] += ((dSASA_2_neigh_dc[0]*LCPOparam[Nlist[i][j]][2] + dSASA_3_neigh_dc[0]*LCPOparam[Nlist[i][j]][3]+dSASA_4_neigh_dc[0]*LCPOparam[Nlist[i][j]][4])/MaxSurf[Nlist[i][j]][0]*DeltaG[natoms][0])*10;
+    1023       15720 :               derivatives[i][1] += ((dSASA_2_neigh_dc[1]*LCPOparam[Nlist[i][j]][2] + dSASA_3_neigh_dc[1]*LCPOparam[Nlist[i][j]][3]+dSASA_4_neigh_dc[1]*LCPOparam[Nlist[i][j]][4])/MaxSurf[Nlist[i][j]][0]*DeltaG[natoms][0])*10;
+    1024       15720 :               derivatives[i][2] += ((dSASA_2_neigh_dc[2]*LCPOparam[Nlist[i][j]][2] + dSASA_3_neigh_dc[2]*LCPOparam[Nlist[i][j]][3]+dSASA_4_neigh_dc[2]*LCPOparam[Nlist[i][j]][4])/MaxSurf[Nlist[i][j]][0]*DeltaG[natoms][0])*10;
+    1025             :             }
+    1026             : 
+    1027       19030 :             if (AtomResidueName[0][Nlist[i][j]] != "N" && AtomResidueName[0][Nlist[i][j]] != "CA"  && AtomResidueName[0][Nlist[i][j]] != "C" && AtomResidueName[0][Nlist[i][j]] != "O") {
+    1028        3310 :               derivatives[i][0] += ((dSASA_2_neigh_dc[0]*LCPOparam[Nlist[i][j]][2] + dSASA_3_neigh_dc[0]*LCPOparam[Nlist[i][j]][3]+dSASA_4_neigh_dc[0]*LCPOparam[Nlist[i][j]][4])/MaxSurf[Nlist[i][j]][1]*DeltaG[Nlist[i][j]][0])*10;
+    1029        3310 :               derivatives[i][1] += ((dSASA_2_neigh_dc[1]*LCPOparam[Nlist[i][j]][2] + dSASA_3_neigh_dc[1]*LCPOparam[Nlist[i][j]][3]+dSASA_4_neigh_dc[1]*LCPOparam[Nlist[i][j]][4])/MaxSurf[Nlist[i][j]][1]*DeltaG[Nlist[i][j]][0])*10;
+    1030        3310 :               derivatives[i][2] += ((dSASA_2_neigh_dc[2]*LCPOparam[Nlist[i][j]][2] + dSASA_3_neigh_dc[2]*LCPOparam[Nlist[i][j]][3]+dSASA_4_neigh_dc[2]*LCPOparam[Nlist[i][j]][4])/MaxSurf[Nlist[i][j]][1]*DeltaG[Nlist[i][j]][0])*10;
+    1031             :             }
+    1032             : 
+    1033       19030 :             Aijk += (Aijt * Ajkt);
+    1034       19030 :             Aij += Aijt;
+    1035       19030 :             Ajk += Ajkt;
+    1036             : 
+    1037       19030 :             dAijdc_2[0] += dAijdc_2t[0];
+    1038       19030 :             dAijdc_2[1] += dAijdc_2t[1];
+    1039       19030 :             dAijdc_2[2] += dAijdc_2t[2];
+    1040             : 
+    1041       19030 :             dAijdc_4[0] += Ajkt*dAijdc_2t[0];
+    1042       19030 :             dAijdc_4[1] += Ajkt*dAijdc_2t[1];
+    1043       19030 :             dAijdc_4[2] += Ajkt*dAijdc_2t[2];
+    1044             : 
+    1045             :           }
+    1046             :           double sasai = (LCPOparam[i][1]*S1+LCPOparam[i][2]*Aij+LCPOparam[i][3]*Ajk+LCPOparam[i][4]*Aijk);
+    1047             : 
+    1048        2016 :           if (AtomResidueName[0][i] == "N" || AtomResidueName[0][i] == "CA"  || AtomResidueName[0][i] == "C" || AtomResidueName[0][i] == "O") {
+    1049         576 :             if (sasai > 0 ) sasa += (sasai/MaxSurf[i][0]*DeltaG[natoms][0]);
+    1050         576 :             derivatives[i][0] += ((dAijdc_2[0]*LCPOparam[i][2]+dAijdc_4[0]*LCPOparam[i][4])/MaxSurf[i][0]*DeltaG[natoms][0])*10;
+    1051         576 :             derivatives[i][1] += ((dAijdc_2[1]*LCPOparam[i][2]+dAijdc_4[1]*LCPOparam[i][4])/MaxSurf[i][0]*DeltaG[natoms][0])*10;
+    1052         576 :             derivatives[i][2] += ((dAijdc_2[2]*LCPOparam[i][2]+dAijdc_4[2]*LCPOparam[i][4])/MaxSurf[i][0]*DeltaG[natoms][0])*10;
+    1053             :           }
+    1054             : 
+    1055        2016 :           if (AtomResidueName[0][i] != "N" && AtomResidueName[0][i] != "CA"  && AtomResidueName[0][i] != "C" && AtomResidueName[0][i] != "O") {
+    1056         144 :             if (sasai > 0. ) sasa += (sasai/MaxSurf[i][1]*DeltaG[i][0]);
+    1057         144 :             derivatives[i][0] += ((dAijdc_2[0]*LCPOparam[i][2]+dAijdc_4[0]*LCPOparam[i][4])/MaxSurf[i][1]*DeltaG[i][0])*10;
+    1058         144 :             derivatives[i][1] += ((dAijdc_2[1]*LCPOparam[i][2]+dAijdc_4[1]*LCPOparam[i][4])/MaxSurf[i][1]*DeltaG[i][0])*10;
+    1059         144 :             derivatives[i][2] += ((dAijdc_2[2]*LCPOparam[i][2]+dAijdc_4[2]*LCPOparam[i][4])/MaxSurf[i][1]*DeltaG[i][0])*10;
+    1060             :           }
+    1061             :         }
+    1062             :       }
+    1063        1440 :       virial -= Tensor(getPosition(i),derivatives[i]);
+    1064             :     }
+    1065             :   }
+    1066             : 
+    1067             : 
+    1068        2904 :   for(unsigned i=0; i<natoms; i++) { setAtomsDerivatives(i,derivatives[i]);}
+    1069          24 :   setBoxDerivatives(virial);
+    1070          24 :   setValue(sasa);
+    1071          24 :   firstStepFlag = 1;
+    1072          24 :   ++nl_update;
+    1073          24 :   if (nl_update == stride) {
+    1074          24 :     nl_update = 0;
+    1075             :   }
+    1076             : // setBoxDerivativesNoPbc();
+    1077          24 : }
+    1078             : 
+    1079             : }//namespace sasa
+    1080             : }//namespace PLMD
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/secondarystructure/AlphaRMSD.cpp.func-sort-c.html b/coverage/secondarystructure/AlphaRMSD.cpp.func-sort-c.html new file mode 100644 index 000000000000..785bd7e615cc --- /dev/null +++ b/coverage/secondarystructure/AlphaRMSD.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - secondarystructure/AlphaRMSD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - secondarystructure - AlphaRMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:6262100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18secondarystructure9AlphaRMSDC2ERKNS_13ActionOptionsE0
_ZN4PLMD18secondarystructure9AlphaRMSDC1ERKNS_13ActionOptionsE3
_ZN4PLMD18secondarystructure9AlphaRMSD16registerKeywordsERNS_8KeywordsE9
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/secondarystructure/AlphaRMSD.cpp.func.html b/coverage/secondarystructure/AlphaRMSD.cpp.func.html new file mode 100644 index 000000000000..da29bcff8b93 --- /dev/null +++ b/coverage/secondarystructure/AlphaRMSD.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - secondarystructure/AlphaRMSD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - secondarystructure - AlphaRMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:6262100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18secondarystructure9AlphaRMSD16registerKeywordsERNS_8KeywordsE9
_ZN4PLMD18secondarystructure9AlphaRMSDC1ERKNS_13ActionOptionsE3
_ZN4PLMD18secondarystructure9AlphaRMSDC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/secondarystructure/AlphaRMSD.cpp.gcov.html b/coverage/secondarystructure/AlphaRMSD.cpp.gcov.html new file mode 100644 index 000000000000..d32f522fdf08 --- /dev/null +++ b/coverage/secondarystructure/AlphaRMSD.cpp.gcov.html @@ -0,0 +1,252 @@ + + + + + + + + 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:6262100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "SecondaryStructureRMSD.h"
+      23             : #include "core/ActionShortcut.h"
+      24             : #include "core/ActionRegister.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 ActionShortcut {
+      89             : public:
+      90             :   static void registerKeywords( Keywords& keys );
+      91             :   explicit AlphaRMSD(const ActionOptions&);
+      92             : };
+      93             : 
+      94             : PLUMED_REGISTER_ACTION(AlphaRMSD,"ALPHARMSD")
+      95             : 
+      96           9 : void AlphaRMSD::registerKeywords( Keywords& keys ) {
+      97           9 :   SecondaryStructureRMSD::registerKeywords( keys );
+      98          36 :   keys.remove("ATOMS"); keys.remove("SEGMENT"); keys.remove("BONDLENGTH"); keys.remove("CUTOFF_ATOMS");
+      99          27 :   keys.remove("NO_ACTION_LOG"); keys.remove("STRANDS_CUTOFF"); keys.remove("STRUCTURE");
+     100           9 : }
+     101             : 
+     102           3 : AlphaRMSD::AlphaRMSD(const ActionOptions&ao):
+     103             :   Action(ao),
+     104           3 :   ActionShortcut(ao)
+     105             : {
+     106             :   // Read in the input and create a string that describes how to compute the less than
+     107           3 :   std::string ltmap; bool uselessthan=SecondaryStructureRMSD::readShortcutWords( ltmap, this );
+     108             :   // read in the backbone atoms
+     109           3 :   std::vector<unsigned> chains; std::string atoms; SecondaryStructureRMSD::readBackboneAtoms( this, plumed, "protein", chains, atoms );
+     110             : 
+     111             :   // This constructs all conceivable sections of alpha helix in the backbone of the chains
+     112           3 :   unsigned nprevious=0, segno=1; std::string seglist;
+     113           6 :   for(unsigned i=0; i<chains.size(); ++i) {
+     114           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");
+     115           3 :     unsigned nres=chains[i]/5;
+     116           3 :     if( chains[i]%5!=0 ) error("backbone segment received does not contain a multiple of five residues");
+     117          18 :     for(unsigned ires=0; ires<nres-5; ires++) {
+     118          15 :       unsigned accum=nprevious + 5*ires; std::string strval, num; Tools::convert( segno, num );
+     119          30 :       Tools::convert( accum, strval ); seglist += " SEGMENT" + num + "=" + strval;
+     120         450 :       for(unsigned k=1; k<30; ++k) { Tools::convert( accum+k, strval ); seglist += "," + strval; }
+     121          15 :       segno++;
+     122             :     }
+     123           3 :     nprevious+=chains[i];
+     124             :   }
+     125             : 
+     126             :   // Build the reference structure ( in angstroms )
+     127           3 :   std::vector<Vector> reference(30);
+     128           3 :   reference[0] = Vector( 0.733,  0.519,  5.298 ); // N    i
+     129           3 :   reference[1] = Vector( 1.763,  0.810,  4.301 ); // CA
+     130           3 :   reference[2] = Vector( 3.166,  0.543,  4.881 ); // CB
+     131           3 :   reference[3] = Vector( 1.527, -0.045,  3.053 ); // C
+     132           3 :   reference[4] = Vector( 1.646,  0.436,  1.928 ); // O
+     133           3 :   reference[5] = Vector( 1.180, -1.312,  3.254 ); // N    i+1
+     134           3 :   reference[6] = Vector( 0.924, -2.203,  2.126 ); // CA
+     135           3 :   reference[7] = Vector( 0.650, -3.626,  2.626 ); // CB
+     136           3 :   reference[8] = Vector(-0.239, -1.711,  1.261 ); // C
+     137           3 :   reference[9] = Vector(-0.190, -1.815,  0.032 ); // O
+     138           3 :   reference[10] = Vector(-1.280, -1.172,  1.891 ); // N    i+2
+     139           3 :   reference[11] = Vector(-2.416, -0.661,  1.127 ); // CA
+     140           3 :   reference[12] = Vector(-3.548, -0.217,  2.056 ); // CB
+     141           3 :   reference[13] = Vector(-1.964,  0.529,  0.276 ); // C
+     142           3 :   reference[14] = Vector(-2.364,  0.659, -0.880 ); // O
+     143           3 :   reference[15] = Vector(-1.130,  1.391,  0.856 ); // N    i+3
+     144           3 :   reference[16] = Vector(-0.620,  2.565,  0.148 ); // CA
+     145           3 :   reference[17] = Vector( 0.228,  3.439,  1.077 ); // CB
+     146           3 :   reference[18] = Vector( 0.231,  2.129, -1.032 ); // C
+     147           3 :   reference[19] = Vector( 0.179,  2.733, -2.099 ); // O
+     148           3 :   reference[20] = Vector( 1.028,  1.084, -0.833 ); // N    i+4
+     149           3 :   reference[21] = Vector( 1.872,  0.593, -1.919 ); // CA
+     150           3 :   reference[22] = Vector( 2.850, -0.462, -1.397 ); // CB
+     151           3 :   reference[23] = Vector( 1.020,  0.020, -3.049 ); // C
+     152           3 :   reference[24] = Vector( 1.317,  0.227, -4.224 ); // O
+     153           3 :   reference[25] = Vector(-0.051, -0.684, -2.696 ); // N    i+5
+     154           3 :   reference[26] = Vector(-0.927, -1.261, -3.713 ); // CA
+     155           3 :   reference[27] = Vector(-1.933, -2.219, -3.074 ); // CB
+     156           3 :   reference[28] = Vector(-1.663, -0.171, -4.475 ); // C
+     157           3 :   reference[29] = Vector(-1.916, -0.296, -5.673 ); // O
+     158             :   std::string ref0, ref1, ref2;
+     159           3 :   Tools::convert(  reference[0][0], ref0 );
+     160           3 :   Tools::convert(  reference[0][1], ref1 );
+     161           3 :   Tools::convert(  reference[0][2], ref2 );
+     162           6 :   std::string structure=" STRUCTURE1=" + ref0 + "," + ref1 + "," + ref2;
+     163          90 :   for(unsigned i=1; i<30; ++i) {
+     164         348 :     for(unsigned k=0; k<3; ++k) { Tools::convert( reference[i][k], ref0 ); structure += "," + ref0; }
+     165             :   }
+     166             : 
+     167           6 :   std::string type; parse("TYPE",type); std::string lab = getShortcutLabel() + "_rmsd"; if( uselessthan ) lab = getShortcutLabel();
+     168           6 :   std::string nopbcstr=""; bool nopbc; parseFlag("NOPBC",nopbc); if( nopbc ) nopbcstr = " NOPBC";
+     169           6 :   readInputLine( lab + ": SECONDARY_STRUCTURE_RMSD BONDLENGTH=0.17" + seglist + structure + " " + atoms + " TYPE=" + type + nopbcstr );
+     170             :   // Create the less than object
+     171           3 :   if( ltmap.length()>0 ) SecondaryStructureRMSD::expandShortcut( uselessthan, getShortcutLabel(), lab, ltmap, this );
+     172           3 : }
+     173             : 
+     174             : }
+     175             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/secondarystructure/AntibetaRMSD.cpp.func-sort-c.html b/coverage/secondarystructure/AntibetaRMSD.cpp.func-sort-c.html new file mode 100644 index 000000000000..4deaaa0ddc1f --- /dev/null +++ b/coverage/secondarystructure/AntibetaRMSD.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - secondarystructure/AntibetaRMSD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - secondarystructure - AntibetaRMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:949697.9 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18secondarystructure12AntibetaRMSDC2ERKNS_13ActionOptionsE0
_ZN4PLMD18secondarystructure12AntibetaRMSDC1ERKNS_13ActionOptionsE11
_ZN4PLMD18secondarystructure12AntibetaRMSD16registerKeywordsERNS_8KeywordsE61
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/secondarystructure/AntibetaRMSD.cpp.func.html b/coverage/secondarystructure/AntibetaRMSD.cpp.func.html new file mode 100644 index 000000000000..7a0e39691b35 --- /dev/null +++ b/coverage/secondarystructure/AntibetaRMSD.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - secondarystructure/AntibetaRMSD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - secondarystructure - AntibetaRMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:949697.9 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18secondarystructure12AntibetaRMSD16registerKeywordsERNS_8KeywordsE61
_ZN4PLMD18secondarystructure12AntibetaRMSDC1ERKNS_13ActionOptionsE11
_ZN4PLMD18secondarystructure12AntibetaRMSDC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/secondarystructure/AntibetaRMSD.cpp.gcov.html b/coverage/secondarystructure/AntibetaRMSD.cpp.gcov.html new file mode 100644 index 000000000000..9aa6a3127a2f --- /dev/null +++ b/coverage/secondarystructure/AntibetaRMSD.cpp.gcov.html @@ -0,0 +1,309 @@ + + + + + + + + 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:949697.9 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "SecondaryStructureRMSD.h"
+      23             : #include "core/ActionShortcut.h"
+      24             : #include "core/ActionRegister.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 ActionShortcut {
+      90             : public:
+      91             :   static void registerKeywords( Keywords& keys );
+      92             :   explicit AntibetaRMSD(const ActionOptions&);
+      93             : };
+      94             : 
+      95             : PLUMED_REGISTER_ACTION(AntibetaRMSD,"ANTIBETARMSD")
+      96             : 
+      97          61 : void AntibetaRMSD::registerKeywords( Keywords& keys ) {
+      98          61 :   SecondaryStructureRMSD::registerKeywords( keys );
+      99         183 :   keys.remove("ATOMS"); keys.remove("SEGMENT"); keys.remove("BONDLENGTH");
+     100         183 :   keys.remove("NO_ACTION_LOG"); keys.remove("CUTOFF_ATOMS"); keys.remove("STRUCTURE");
+     101         122 :   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 "
+     102             :            "chain configuration with the appropriate geometry are counted.  If STYLE=inter "
+     103             :            "only sheet-like configurations involving two chains are counted, while if STYLE=intra "
+     104             :            "only sheet-like configurations involving a single chain are counted");
+     105          61 : }
+     106             : 
+     107          11 : AntibetaRMSD::AntibetaRMSD(const ActionOptions&ao):
+     108             :   Action(ao),
+     109          11 :   ActionShortcut(ao)
+     110             : {
+     111             :   // Read in the input and create a string that describes how to compute the less than
+     112          11 :   std::string ltmap; bool uselessthan=SecondaryStructureRMSD::readShortcutWords( ltmap, this );
+     113             :   // read in the backbone atoms
+     114          22 :   std::vector<unsigned> chains; std::string atoms; SecondaryStructureRMSD::readBackboneAtoms( this, plumed, "protein", chains, atoms );
+     115             : 
+     116             :   bool intra_chain(false), inter_chain(false);
+     117          11 :   std::string style; parse("STYLE",style);
+     118          22 :   if( Tools::caseInSensStringCompare(style, "all") ) {
+     119             :     intra_chain=true; inter_chain=true;
+     120           2 :   } else if( Tools::caseInSensStringCompare(style, "inter") ) {
+     121             :     intra_chain=false; inter_chain=true;
+     122           0 :   } else if( Tools::caseInSensStringCompare(style, "intra") ) {
+     123             :     intra_chain=true; inter_chain=false;
+     124             :   } else {
+     125           0 :     error( style + " is not a valid directive for the STYLE keyword");
+     126             :   }
+     127             : 
+     128             :   // This constructs all conceivable sections of antibeta sheet in the backbone of the chains
+     129          11 :   std::string seglist; unsigned k=1;
+     130          11 :   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         330 :       for(unsigned ires=0; ires<nres-7; ires++) {
+     138         344 :         for(unsigned jres=ires+7; jres<nres; jres++) {
+     139        2832 :           for(unsigned k=0; k<15; ++k) {
+     140        2655 :             nlist[k]=nprevious + ires*5+k;
+     141        2655 :             nlist[k+15]=nprevious + (jres-2)*5+k;
+     142             :           }
+     143             :           std::string nlstr, num;
+     144         177 :           Tools::convert( nlist[0], nlstr );
+     145         177 :           Tools::convert(k, num); k++;
+     146         354 :           seglist += " SEGMENT" + num + "=" + nlstr;
+     147        5310 :           for(unsigned kk=1; kk<nlist.size(); ++kk ) { Tools::convert( nlist[kk], nlstr ); seglist += "," + nlstr; }
+     148             :         }
+     149             :       }
+     150         163 :       nprevious+=chains[i];
+     151             :     }
+     152             :   }
+     153          11 :   if( inter_chain ) {
+     154          12 :     if( chains.size()==1 && style!="all" ) error("there is only one chain defined so cannot use inter_chain option");
+     155          11 :     std::vector<unsigned> nlist(30);
+     156         165 :     for(unsigned ichain=1; ichain<chains.size(); ++ichain) {
+     157        1532 :       unsigned iprev=0; for(unsigned i=0; i<ichain; ++i) iprev+=chains[i];
+     158         154 :       unsigned inres=chains[ichain]/5;
+     159         154 :       if( chains[ichain]%5!=0 ) error("backbone segment received does not contain a multiple of five residues");
+     160        1073 :       for(unsigned ires=0; ires<inres-2; ++ires) {
+     161        9182 :         for(unsigned jchain=0; jchain<ichain; ++jchain) {
+     162       52327 :           unsigned jprev=0; for(unsigned i=0; i<jchain; ++i) jprev+=chains[i];
+     163        8263 :           unsigned jnres=chains[jchain]/5;
+     164        8263 :           if( chains[jchain]%5!=0 ) error("backbone segment received does not contain a multiple of five residues");
+     165       57836 :           for(unsigned jres=0; jres<jnres-2; ++jres) {
+     166      793168 :             for(unsigned k=0; k<15; ++k) {
+     167      743595 :               nlist[k]=iprev+ ires*5+k;
+     168      743595 :               nlist[k+15]=jprev+ jres*5+k;
+     169             :             }
+     170             :             std::string nlstr, num;
+     171       49573 :             Tools::convert( nlist[0], nlstr );
+     172       49573 :             Tools::convert(k, num); k++;
+     173       99146 :             seglist += " SEGMENT" + num + "=" + nlstr;
+     174     1487190 :             for(unsigned kk=1; kk<nlist.size(); ++kk ) { Tools::convert( nlist[kk], nlstr ); seglist += "," + nlstr; }
+     175             :           }
+     176             :         }
+     177             :       }
+     178             :     }
+     179             :   }
+     180             : 
+     181             :   // Build the reference structure ( in angstroms )
+     182          11 :   std::vector<Vector> reference(30);
+     183          11 :   reference[0]=Vector( 2.263, -3.795,  1.722); // N    i
+     184          11 :   reference[1]=Vector( 2.493, -2.426,  2.263); // CA
+     185          11 :   reference[2]=Vector( 3.847, -1.838,  1.761); // CB
+     186          11 :   reference[3]=Vector( 1.301, -1.517,  1.921); // C
+     187          11 :   reference[4]=Vector( 0.852, -1.504,  0.739); // O
+     188          11 :   reference[5]=Vector( 0.818, -0.738,  2.917); // N    i+1
+     189          11 :   reference[6]=Vector(-0.299,  0.243,  2.748); // CA
+     190          11 :   reference[7]=Vector(-1.421, -0.076,  3.757); // CB
+     191          11 :   reference[8]=Vector( 0.273,  1.680,  2.854); // C
+     192          11 :   reference[9]=Vector( 0.902,  1.993,  3.888); // O
+     193          11 :   reference[10]=Vector( 0.119,  2.532,  1.813); // N    i+2
+     194          11 :   reference[11]=Vector( 0.683,  3.916,  1.680); // CA
+     195          11 :   reference[12]=Vector( 1.580,  3.940,  0.395); // CB
+     196          11 :   reference[13]=Vector(-0.394,  5.011,  1.630); // C
+     197          11 :   reference[14]=Vector(-1.459,  4.814,  0.982); // O
+     198          11 :   reference[15]=Vector(-2.962,  3.559, -1.359); // N    j-2
+     199          11 :   reference[16]=Vector(-2.439,  2.526, -2.287); // CA
+     200          11 :   reference[17]=Vector(-1.189,  3.006, -3.087); // CB
+     201          11 :   reference[18]=Vector(-2.081,  1.231, -1.520); // C
+     202          11 :   reference[19]=Vector(-1.524,  1.324, -0.409); // O
+     203          11 :   reference[20]=Vector(-2.326,  0.037, -2.095); // N    j-1
+     204          11 :   reference[21]=Vector(-1.858, -1.269, -1.554); // CA
+     205          11 :   reference[22]=Vector(-3.053, -2.199, -1.291); // CB
+     206          11 :   reference[23]=Vector(-0.869, -1.949, -2.512); // C
+     207          11 :   reference[24]=Vector(-1.255, -2.070, -3.710); // O
+     208          11 :   reference[25]=Vector( 0.326, -2.363, -2.072); // N    j
+     209          11 :   reference[26]=Vector( 1.405, -2.992, -2.872); // CA
+     210          11 :   reference[27]=Vector( 2.699, -2.129, -2.917); // CB
+     211          11 :   reference[28]=Vector( 1.745, -4.399, -2.330); // C
+     212          11 :   reference[29]=Vector( 1.899, -4.545, -1.102); // O
+     213             :   std::string ref0, ref1, ref2;
+     214          11 :   Tools::convert(  reference[0][0], ref0 );
+     215          11 :   Tools::convert(  reference[0][1], ref1 );
+     216          11 :   Tools::convert(  reference[0][2], ref2 );
+     217          22 :   std::string structure=" STRUCTURE1=" + ref0 + "," + ref1 + "," + ref2;
+     218         330 :   for(unsigned i=1; i<30; ++i) {
+     219        1276 :     for(unsigned k=0; k<3; ++k) { Tools::convert( reference[i][k], ref0 ); structure += "," + ref0; }
+     220             :   }
+     221             : 
+     222          22 :   std::string strands_cutoff; parse("STRANDS_CUTOFF",strands_cutoff);
+     223          21 :   if( strands_cutoff.length()>0 ) strands_cutoff=" CUTOFF_ATOMS=6,21 STRANDS_CUTOFF="+strands_cutoff;
+     224          22 :   std::string type; parse("TYPE",type); std::string lab = getShortcutLabel() + "_rmsd"; if( uselessthan ) lab = getShortcutLabel();
+     225          22 :   std::string nopbcstr=""; bool nopbc; parseFlag("NOPBC",nopbc); if( nopbc ) nopbcstr = " NOPBC";
+     226          22 :   readInputLine( lab + ": SECONDARY_STRUCTURE_RMSD BONDLENGTH=0.17" + seglist + structure + " " + atoms + " TYPE=" + type + strands_cutoff + nopbcstr );
+     227             :   // Create the less than object
+     228          11 :   if( ltmap.length()>0 ) SecondaryStructureRMSD::expandShortcut( uselessthan, getShortcutLabel(), lab, ltmap, this );
+     229          11 : }
+     230             : 
+     231             : }
+     232             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/secondarystructure/ParabetaRMSD.cpp.func-sort-c.html b/coverage/secondarystructure/ParabetaRMSD.cpp.func-sort-c.html new file mode 100644 index 000000000000..bde64f60725e --- /dev/null +++ b/coverage/secondarystructure/ParabetaRMSD.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - secondarystructure/ParabetaRMSD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - secondarystructure - ParabetaRMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:13013397.7 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18secondarystructure12ParabetaRMSDC2ERKNS_13ActionOptionsE0
_ZN4PLMD18secondarystructure12ParabetaRMSDC1ERKNS_13ActionOptionsE12
_ZN4PLMD18secondarystructure12ParabetaRMSD16registerKeywordsERNS_8KeywordsE60
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/secondarystructure/ParabetaRMSD.cpp.func.html b/coverage/secondarystructure/ParabetaRMSD.cpp.func.html new file mode 100644 index 000000000000..9126b90c5c02 --- /dev/null +++ b/coverage/secondarystructure/ParabetaRMSD.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - secondarystructure/ParabetaRMSD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - secondarystructure - ParabetaRMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:13013397.7 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18secondarystructure12ParabetaRMSD16registerKeywordsERNS_8KeywordsE60
_ZN4PLMD18secondarystructure12ParabetaRMSDC1ERKNS_13ActionOptionsE12
_ZN4PLMD18secondarystructure12ParabetaRMSDC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/secondarystructure/ParabetaRMSD.cpp.gcov.html b/coverage/secondarystructure/ParabetaRMSD.cpp.gcov.html new file mode 100644 index 000000000000..6ffbd88f6b70 --- /dev/null +++ b/coverage/secondarystructure/ParabetaRMSD.cpp.gcov.html @@ -0,0 +1,355 @@ + + + + + + + + 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:13013397.7 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "SecondaryStructureRMSD.h"
+      23             : #include "core/ActionShortcut.h"
+      24             : #include "core/ActionRegister.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 ActionShortcut {
+      91             : public:
+      92             :   static void registerKeywords( Keywords& keys );
+      93             :   explicit ParabetaRMSD(const ActionOptions&);
+      94             : };
+      95             : 
+      96             : PLUMED_REGISTER_ACTION(ParabetaRMSD,"PARABETARMSD")
+      97             : 
+      98          60 : void ParabetaRMSD::registerKeywords( Keywords& keys ) {
+      99          60 :   SecondaryStructureRMSD::registerKeywords( keys );
+     100         180 :   keys.remove("ATOMS"); keys.remove("SEGMENT"); keys.remove("BONDLENGTH");
+     101         180 :   keys.remove("NO_ACTION_LOG"); keys.remove("CUTOFF_ATOMS"); keys.remove("STRUCTURE");
+     102         120 :   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 "
+     103             :            "chain configuration with the appropriate geometry are counted.  If STYLE=inter "
+     104             :            "only sheet-like configurations involving two chains are counted, while if STYLE=intra "
+     105             :            "only sheet-like configurations involving a single chain are counted");
+     106          60 :   keys.needsAction("LOWEST");
+     107          60 : }
+     108             : 
+     109          12 : ParabetaRMSD::ParabetaRMSD(const ActionOptions&ao):
+     110             :   Action(ao),
+     111          12 :   ActionShortcut(ao)
+     112             : {
+     113             :   // Read in the input and create a string that describes how to compute the less than
+     114          12 :   std::string ltmap; bool uselessthan=SecondaryStructureRMSD::readShortcutWords( ltmap, this );
+     115             :   // read in the backbone atoms
+     116          24 :   std::vector<unsigned> chains; std::string atoms; SecondaryStructureRMSD::readBackboneAtoms( this, plumed, "protein", chains, atoms );
+     117             : 
+     118             :   bool intra_chain(false), inter_chain(false); std::string seglist;
+     119          12 :   std::string style; parse("STYLE",style); unsigned jjkk=1;
+     120          24 :   if( Tools::caseInSensStringCompare(style, "all") ) {
+     121             :     intra_chain=true; inter_chain=true;
+     122           0 :   } else if( Tools::caseInSensStringCompare(style, "inter") ) {
+     123             :     intra_chain=false; inter_chain=true;
+     124           0 :   } else if( Tools::caseInSensStringCompare(style, "intra") ) {
+     125             :     intra_chain=true; inter_chain=false;
+     126             :   } else {
+     127           0 :     error( style + " is not a valid directive for the STYLE keyword");
+     128             :   }
+     129             : 
+     130             :   // This constructs all conceivable sections of antibeta sheet in the backbone of the chains
+     131             :   if( intra_chain ) {
+     132          12 :     unsigned nprevious=0; std::vector<unsigned> nlist(30);
+     133         177 :     for(unsigned i=0; i<chains.size(); ++i) {
+     134         165 :       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");
+     135             :       // Loop over all possible triples in each 8 residue segment of protein
+     136         165 :       unsigned nres=chains[i]/5;
+     137         165 :       if( chains[i]%5!=0 ) error("backbone segment received does not contain a multiple of five residues");
+     138         177 :       for(unsigned ires=0; ires<nres-8; ires++) {
+     139          42 :         for(unsigned jres=ires+6; jres<nres-2; jres++) {
+     140         480 :           for(unsigned k=0; k<15; ++k) {
+     141         450 :             nlist[k]=nprevious + ires*5+k;
+     142         450 :             nlist[k+15]=nprevious + jres*5+k;
+     143             :           }
+     144             :           std::string nlstr, num;
+     145          30 :           Tools::convert( nlist[0], nlstr );
+     146          30 :           Tools::convert(jjkk, num); jjkk++;
+     147          60 :           seglist += " SEGMENT" + num + "=" + nlstr;
+     148         900 :           for(unsigned kk=1; kk<nlist.size(); ++kk ) { Tools::convert( nlist[kk], nlstr ); seglist += "," + nlstr; }
+     149             :         }
+     150             :       }
+     151         165 :       nprevious+=chains[i];
+     152             :     }
+     153             :   }
+     154             :   // This constructs all conceivable sections of antibeta sheet that form between chains
+     155          12 :   if( inter_chain ) {
+     156          18 :     if( chains.size()==1 && !Tools::caseInSensStringCompare(style, "all") ) error("there is only one chain defined so cannot use inter_chain option");
+     157          12 :     std::vector<unsigned> nlist(30);
+     158         165 :     for(unsigned ichain=1; ichain<chains.size(); ++ichain) {
+     159        1530 :       unsigned iprev=0; for(unsigned i=0; i<ichain; ++i) iprev+=chains[i];
+     160         153 :       unsigned inres=chains[ichain]/5;
+     161         153 :       if( chains[ichain]%5!=0 ) error("backbone segment received does not contain a multiple of five residues");
+     162        1071 :       for(unsigned ires=0; ires<inres-2; ++ires) {
+     163        9180 :         for(unsigned jchain=0; jchain<ichain; ++jchain) {
+     164       52326 :           unsigned jprev=0; for(unsigned i=0; i<jchain; ++i) jprev+=chains[i];
+     165        8262 :           unsigned jnres=chains[jchain]/5;
+     166        8262 :           if( chains[jchain]%5!=0 ) error("backbone segment received does not contain a multiple of five residues");
+     167       57834 :           for(unsigned jres=0; jres<jnres-2; ++jres) {
+     168      793152 :             for(unsigned k=0; k<15; ++k) {
+     169      743580 :               nlist[k]=iprev + ires*5+k;
+     170      743580 :               nlist[k+15]=jprev + jres*5+k;
+     171             :             }
+     172             :             std::string nlstr, num;
+     173       49572 :             Tools::convert( nlist[0], nlstr );
+     174       49572 :             Tools::convert(jjkk, num); jjkk++;
+     175       99144 :             seglist += " SEGMENT" + num + "=" + nlstr;
+     176     1487160 :             for(unsigned kk=1; kk<nlist.size(); ++kk ) { Tools::convert( nlist[kk], nlstr ); seglist += "," + nlstr; }
+     177             :           }
+     178             :         }
+     179             :       }
+     180             :     }
+     181             :   }
+     182             : 
+     183             :   // Build the reference structure ( in angstroms )
+     184          12 :   std::vector<Vector> reference(30);
+     185          12 :   reference[0]=Vector( 1.244, -4.620, -2.127); // N    i
+     186          12 :   reference[1]=Vector(-0.016, -4.500, -1.395); // CA
+     187          12 :   reference[2]=Vector( 0.105, -5.089,  0.024); // CB
+     188          12 :   reference[3]=Vector(-0.287, -3.000, -1.301); // C
+     189          12 :   reference[4]=Vector( 0.550, -2.245, -0.822); // O
+     190          12 :   reference[5]=Vector(-1.445, -2.551, -1.779); // N    i+1
+     191          12 :   reference[6]=Vector(-1.752, -1.130, -1.677); // CA
+     192          12 :   reference[7]=Vector(-2.113, -0.550, -3.059); // CB
+     193          12 :   reference[8]=Vector(-2.906, -0.961, -0.689); // C
+     194          12 :   reference[9]=Vector(-3.867, -1.738, -0.695); // O
+     195          12 :   reference[10]=Vector(-2.774,  0.034,  0.190); // N    i+2
+     196          12 :   reference[11]=Vector(-3.788,  0.331,  1.201); // CA
+     197          12 :   reference[12]=Vector(-3.188,  0.300,  2.624); // CB
+     198          12 :   reference[13]=Vector(-4.294,  1.743,  0.937); // C
+     199          12 :   reference[14]=Vector(-3.503,  2.671,  0.821); // O
+     200          12 :   reference[15]=Vector( 4.746, -2.363,  0.188); // N    j
+     201          12 :   reference[16]=Vector( 3.427, -1.839,  0.545); // CA
+     202          12 :   reference[17]=Vector( 3.135, -1.958,  2.074); // CB
+     203          12 :   reference[18]=Vector( 3.346, -0.365,  0.181); // C
+     204          12 :   reference[19]=Vector( 4.237,  0.412,  0.521); // O
+     205          12 :   reference[20]=Vector( 2.261,  0.013, -0.487); // N    j+1
+     206          12 :   reference[21]=Vector( 2.024,  1.401, -0.875); // CA
+     207          12 :   reference[22]=Vector( 1.489,  1.514, -2.313); // CB
+     208          12 :   reference[23]=Vector( 0.914,  1.902,  0.044); // C
+     209          12 :   reference[24]=Vector(-0.173,  1.330,  0.052); // O
+     210          12 :   reference[25]=Vector( 1.202,  2.940,  0.828); // N    j+2
+     211          12 :   reference[26]=Vector( 0.190,  3.507,  1.718); // CA
+     212          12 :   reference[27]=Vector( 0.772,  3.801,  3.104); // CB
+     213          12 :   reference[28]=Vector(-0.229,  4.791,  1.038); // C
+     214          12 :   reference[29]=Vector( 0.523,  5.771,  0.996); // O
+     215             :   // Store the secondary structure ( last number makes sure we convert to internal units nm )
+     216             :   std::string ref0, ref1, ref2;
+     217          12 :   Tools::convert(  reference[0][0], ref0 );
+     218          12 :   Tools::convert(  reference[0][1], ref1 );
+     219          12 :   Tools::convert(  reference[0][2], ref2 );
+     220          24 :   std::string structure=" STRUCTURE1=" + ref0 + "," + ref1 + "," + ref2;
+     221         360 :   for(unsigned i=1; i<30; ++i) {
+     222        1392 :     for(unsigned k=0; k<3; ++k) { Tools::convert( reference[i][k], ref0 ); structure += "," + ref0; }
+     223             :   }
+     224             : 
+     225          12 :   reference[0]=Vector(-1.439, -5.122, -1.144); // N    i
+     226          12 :   reference[1]=Vector(-0.816, -3.803, -1.013); // CA
+     227          12 :   reference[2]=Vector( 0.099, -3.509, -2.206); // CB
+     228          12 :   reference[3]=Vector(-1.928, -2.770, -0.952); // C
+     229          12 :   reference[4]=Vector(-2.991, -2.970, -1.551); // O
+     230          12 :   reference[5]=Vector(-1.698, -1.687, -0.215); // N    i+1
+     231          12 :   reference[6]=Vector(-2.681, -0.613, -0.143); // CA
+     232          12 :   reference[7]=Vector(-3.323, -0.477,  1.267); // CB
+     233          12 :   reference[8]=Vector(-1.984,  0.681, -0.574); // C
+     234          12 :   reference[9]=Vector(-0.807,  0.921, -0.273); // O
+     235          12 :   reference[10]=Vector(-2.716,  1.492, -1.329); // N    i+2
+     236          12 :   reference[11]=Vector(-2.196,  2.731, -1.883); // CA
+     237          12 :   reference[12]=Vector(-2.263,  2.692, -3.418); // CB
+     238          12 :   reference[13]=Vector(-2.989,  3.949, -1.433); // C
+     239          12 :   reference[14]=Vector(-4.214,  3.989, -1.583); // O
+     240          12 :   reference[15]=Vector( 2.464, -4.352,  2.149); // N    j
+     241          12 :   reference[16]=Vector( 3.078, -3.170,  1.541); // CA
+     242          12 :   reference[17]=Vector( 3.398, -3.415,  0.060); // CB
+     243          12 :   reference[18]=Vector( 2.080, -2.021,  1.639); // C
+     244          12 :   reference[19]=Vector( 0.938, -2.178,  1.225); // O
+     245          12 :   reference[20]=Vector( 2.525, -0.886,  2.183); // N    j+1
+     246          12 :   reference[21]=Vector( 1.692,  0.303,  2.346); // CA
+     247          12 :   reference[22]=Vector( 1.541,  0.665,  3.842); // CB
+     248          12 :   reference[23]=Vector( 2.420,  1.410,  1.608); // C
+     249          12 :   reference[24]=Vector( 3.567,  1.733,  1.937); // O
+     250          12 :   reference[25]=Vector( 1.758,  1.976,  0.600); // N    j+2
+     251          12 :   reference[26]=Vector( 2.373,  2.987, -0.238); // CA
+     252          12 :   reference[27]=Vector( 2.367,  2.527, -1.720); // CB
+     253          12 :   reference[28]=Vector( 1.684,  4.331, -0.148); // C
+     254          12 :   reference[29]=Vector( 0.486,  4.430, -0.415); // O
+     255             :   // Store the secondary structure ( last number makes sure we convert to internal units nm )
+     256          12 :   Tools::convert(  reference[0][0], ref0 );
+     257          12 :   Tools::convert(  reference[0][1], ref1 );
+     258          12 :   Tools::convert(  reference[0][2], ref2 );
+     259          24 :   structure +=" STRUCTURE2=" + ref0 + "," + ref1 + "," + ref2;
+     260         360 :   for(unsigned i=1; i<30; ++i) {
+     261        1392 :     for(unsigned k=0; k<3; ++k) { Tools::convert( reference[i][k], ref0 ); structure += "," + ref0; }
+     262             :   }
+     263             : 
+     264          12 :   std::string strands_cutoff; parse("STRANDS_CUTOFF",strands_cutoff);
+     265          24 :   std::string nopbcstr=""; bool nopbc; parseFlag("NOPBC",nopbc); if( nopbc ) nopbcstr = " NOPBC";
+     266          22 :   if( strands_cutoff.length()>0 ) strands_cutoff=" CUTOFF_ATOMS=6,21 STRANDS_CUTOFF="+strands_cutoff;
+     267          24 :   std::string type; parse("TYPE",type); std::string lab = getShortcutLabel() + "_low"; if( uselessthan ) lab = getShortcutLabel();
+     268          24 :   readInputLine( getShortcutLabel() + "_both: SECONDARY_STRUCTURE_RMSD BONDLENGTH=0.17" + seglist + structure + " " + atoms + " TYPE=" + type + strands_cutoff + nopbcstr );
+     269          12 :   if( ltmap.length()>0 ) {
+     270             :     // Create the lowest line
+     271          24 :     readInputLine( lab + ": LOWEST ARG=" + getShortcutLabel() + "_both.struct-1," + getShortcutLabel() + "_both.struct-2" );
+     272             :     // Create the less than object
+     273          12 :     SecondaryStructureRMSD::expandShortcut( uselessthan, getShortcutLabel(), lab, ltmap, this );
+     274             :   }
+     275          12 : }
+     276             : 
+     277             : }
+     278             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/secondarystructure/SecondaryStructureRMSD.cpp.func-sort-c.html b/coverage/secondarystructure/SecondaryStructureRMSD.cpp.func-sort-c.html new file mode 100644 index 000000000000..1d52f4267f33 --- /dev/null +++ b/coverage/secondarystructure/SecondaryStructureRMSD.cpp.func-sort-c.html @@ -0,0 +1,113 @@ + + + + + + + + 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:17918994.7 %
Date:2024-04-19 12:12:35Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18secondarystructure22SecondaryStructureRMSDC2ERKNS_13ActionOptionsE0
_ZN4PLMD18secondarystructure22SecondaryStructureRMSD14expandShortcutERKbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESB_SB_PNS_14ActionShortcutE26
_ZN4PLMD18secondarystructure22SecondaryStructureRMSD17readBackboneAtomsEPNS_14ActionShortcutERNS_10PlumedMainERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIjSaIjEERSB_26
_ZN4PLMD18secondarystructure22SecondaryStructureRMSD17readShortcutWordsERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPNS_14ActionShortcutE26
_ZN4PLMD18secondarystructure22SecondaryStructureRMSDC1ERKNS_13ActionOptionsE26
_ZN4PLMD18secondarystructure22SecondaryStructureRMSD19areAllTasksRequiredERSt6vectorIPNS_16ActionWithVectorESaIS4_EE64
_ZN4PLMD18secondarystructure22SecondaryStructureRMSD16registerKeywordsERNS_8KeywordsE158
_ZN4PLMD18secondarystructure22SecondaryStructureRMSD9calculateEv204
_ZNK4PLMD18secondarystructure22SecondaryStructureRMSD11performTaskERKjRNS_10MultiValueE37042
_ZNK4PLMD18secondarystructure22SecondaryStructureRMSD15checkTaskStatusERKjRi397524
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/secondarystructure/SecondaryStructureRMSD.cpp.func.html b/coverage/secondarystructure/SecondaryStructureRMSD.cpp.func.html new file mode 100644 index 000000000000..e2f04e26c4a1 --- /dev/null +++ b/coverage/secondarystructure/SecondaryStructureRMSD.cpp.func.html @@ -0,0 +1,113 @@ + + + + + + + + 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:17918994.7 %
Date:2024-04-19 12:12:35Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18secondarystructure22SecondaryStructureRMSD14expandShortcutERKbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESB_SB_PNS_14ActionShortcutE26
_ZN4PLMD18secondarystructure22SecondaryStructureRMSD16registerKeywordsERNS_8KeywordsE158
_ZN4PLMD18secondarystructure22SecondaryStructureRMSD17readBackboneAtomsEPNS_14ActionShortcutERNS_10PlumedMainERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIjSaIjEERSB_26
_ZN4PLMD18secondarystructure22SecondaryStructureRMSD17readShortcutWordsERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPNS_14ActionShortcutE26
_ZN4PLMD18secondarystructure22SecondaryStructureRMSD19areAllTasksRequiredERSt6vectorIPNS_16ActionWithVectorESaIS4_EE64
_ZN4PLMD18secondarystructure22SecondaryStructureRMSD9calculateEv204
_ZN4PLMD18secondarystructure22SecondaryStructureRMSDC1ERKNS_13ActionOptionsE26
_ZN4PLMD18secondarystructure22SecondaryStructureRMSDC2ERKNS_13ActionOptionsE0
_ZNK4PLMD18secondarystructure22SecondaryStructureRMSD11performTaskERKjRNS_10MultiValueE37042
_ZNK4PLMD18secondarystructure22SecondaryStructureRMSD15checkTaskStatusERKjRi397524
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/secondarystructure/SecondaryStructureRMSD.cpp.gcov.html b/coverage/secondarystructure/SecondaryStructureRMSD.cpp.gcov.html new file mode 100644 index 000000000000..a305dfd11d3c --- /dev/null +++ b/coverage/secondarystructure/SecondaryStructureRMSD.cpp.gcov.html @@ -0,0 +1,405 @@ + + + + + + + + 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:17918994.7 %
Date:2024-04-19 12:12:35Functions:91090.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2020 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received 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/ActionShortcut.h"
+      27             : #include "core/ActionRegister.h"
+      28             : 
+      29             : //+PLUMEDOC MCOLVAR SECONDARY_STRUCTURE_RMSD
+      30             : /*
+      31             : Calclulate the distance between segments of a protein and a reference structure of interest
+      32             : 
+      33             : \par Examples
+      34             : 
+      35             : */
+      36             : //+ENDPLUMEDOC
+      37             : 
+      38             : namespace PLMD {
+      39             : namespace secondarystructure {
+      40             : 
+      41             : PLUMED_REGISTER_ACTION(SecondaryStructureRMSD,"SECONDARY_STRUCTURE_RMSD");
+      42             : 
+      43          26 : bool SecondaryStructureRMSD::readShortcutWords( std::string& ltmap, ActionShortcut* action ) {
+      44          52 :   action->parse("LESS_THAN",ltmap);
+      45          26 :   if( ltmap.length()==0 ) {
+      46           6 :     std::string nn, mm, d_0, r_0; action->parse("R_0",r_0);
+      47           3 :     if( r_0.length()==0 ) r_0="0.08";
+      48           9 :     action->parse("NN",nn); action->parse("D_0",d_0); action->parse("MM",mm);
+      49           6 :     ltmap = "RATIONAL R_0=" + r_0 + " D_0=" + d_0 + " NN=" + nn + " MM=" + mm;
+      50             :     return false;
+      51             :   }
+      52             :   return true;
+      53             : }
+      54             : 
+      55          26 : void SecondaryStructureRMSD::expandShortcut( const bool& uselessthan, const std::string& labout, const std::string& labin, const std::string& ltmap, ActionShortcut* action ) {
+      56          52 :   action->readInputLine( labout + "_lt: LESS_THAN ARG=" + labin + " SWITCH={" + ltmap  +"}");
+      57          49 :   if( uselessthan ) action->readInputLine( labout + "_lessthan: SUM ARG=" + labout + "_lt PERIODIC=NO");
+      58           6 :   else action->readInputLine( labout + ": SUM ARG=" + labout + "_lt PERIODIC=NO");
+      59          26 : }
+      60             : 
+      61         158 : void SecondaryStructureRMSD::registerKeywords( Keywords& keys ) {
+      62         158 :   ActionWithVector::registerKeywords( keys );
+      63         316 :   keys.addFlag("NOPBC",false,"ignore the periodic boundary conditions");
+      64         316 :   keys.add("residues","RESIDUES","this command is used to specify the set of residues that could conceivably form part of the secondary structure. "
+      65             :            "It is possible to use residues numbers as the various chains and residues should have been identified else using an instance of the "
+      66             :            "\\ref MOLINFO action. If you wish to use all the residues from all the chains in your system you can do so by "
+      67             :            "specifying all. Alternatively, if you wish to use a subset of the residues you can specify the particular residues "
+      68             :            "you are interested in as a list of numbers. Please be aware that to form secondary structure elements your chain "
+      69             :            "must contain at least N residues, where N is dependent on the particular secondary structure you are interested in. "
+      70             :            "As such if you define portions of the chain with fewer than N residues the code will crash.");
+      71         316 :   keys.add("atoms","ATOMS","this is the full list of atoms that we are investigating");
+      72         316 :   keys.add("numbered","SEGMENT","this is the lists of atoms in the segment that are being considered");
+      73         316 :   keys.add("compulsory","BONDLENGTH","the length to use for bonds");
+      74         316 :   keys.add("numbered","STRUCTURE","the reference structure");
+      75         316 :   keys.add("compulsory","TYPE","DRMSD","the manner in which RMSD alignment is performed. Should be OPTIMAL, SIMPLE or DRMSD. "
+      76             :            "For more details on the OPTIMAL and SIMPLE methods see \\ref RMSD. For more details on the "
+      77             :            "DRMSD method see \\ref DRMSD.");
+      78         316 :   keys.add("optional","STRANDS_CUTOFF","If in a segment of protein the two strands are further apart then the calculation "
+      79             :            "of the actual RMSD is skipped as the structure is very far from being beta-sheet like. "
+      80             :            "This keyword speeds up the calculation enormously when you are using the LESS_THAN option. "
+      81             :            "However, if you are using some other option, then this cannot be used");
+      82         316 :   keys.add("optional","CUTOFF_ATOMS","the pair of atoms that are used to calculate the strand cutoff");
+      83         316 :   keys.addFlag("VERBOSE",false,"write a more detailed output");
+      84         316 :   keys.add("optional","LESS_THAN","calculate the number of a residue segments that are within a certain target distance of this secondary structure type. "
+      85             :            "This quantity is calculated using \\f$\\sum_i \\sigma(s_i)\\f$, where \\f$\\sigma(s)\\f$ is a \\ref switchingfunction.");
+      86         316 :   keys.add("optional","R_0","The r_0 parameter of the switching function.");
+      87         316 :   keys.add("compulsory","D_0","0.0","The d_0 parameter of the switching function");
+      88         316 :   keys.add("compulsory","NN","8","The n parameter of the switching function");
+      89         316 :   keys.add("compulsory","MM","12","The m parameter of the switching function");
+      90         316 :   keys.add("hidden","NO_ACTION_LOG","suppresses printing from action on the log");
+      91         316 :   keys.addOutputComponent("struct","default","the vectors containing the rmsd distances between the residues and each of the reference structures");
+      92         316 :   keys.addOutputComponent("lessthan","default","the number blocks of residues that have an RMSD from the secondary structure that is less than the threshold");
+      93         474 :   keys.needsAction("SECONDARY_STRUCTURE_RMSD"); keys.needsAction("LESS_THAN"); keys.needsAction("SUM");
+      94         158 : }
+      95             : 
+      96          26 : void SecondaryStructureRMSD::readBackboneAtoms( ActionShortcut* action, PlumedMain& plumed, const std::string& moltype, std::vector<unsigned>& chain_lengths, std::string& all_atoms ) {
+      97          26 :   auto* moldat=plumed.getActionSet().selectLatest<GenericMolInfo*>(action);
+      98          26 :   if( ! moldat ) action->error("Unable to find MOLINFO in input");
+      99             : 
+     100          52 :   std::vector<std::string> resstrings; action->parseVector( "RESIDUES", resstrings );
+     101          26 :   if(resstrings.size()==0) action->error("residues are not defined, check the keyword RESIDUES");
+     102          52 :   else if( Tools::caseInSensStringCompare(resstrings[0], "all") ) {
+     103             :     resstrings[0]="all";
+     104          24 :     action->log.printf("  examining all possible secondary structure combinations\n");
+     105             :   } else {
+     106           2 :     action->log.printf("  examining secondary structure in residue positions : %s ",resstrings[0].c_str() );
+     107           3 :     for(unsigned i=1; i<resstrings.size(); ++i) action->log.printf(", %s",resstrings[i].c_str() );
+     108           2 :     action->log.printf("\n");
+     109             :   }
+     110             :   std::vector< std::vector<AtomNumber> > backatoms;
+     111          26 :   moldat->getBackbone( resstrings, moltype, backatoms );
+     112             : 
+     113          26 :   chain_lengths.resize( backatoms.size() );
+     114         359 :   for(unsigned i=0; i<backatoms.size(); ++i) {
+     115         333 :     chain_lengths[i]=backatoms[i].size();
+     116       13713 :     for(unsigned j=0; j<backatoms[i].size(); ++j) {
+     117       13380 :       std::string bat_str; Tools::convert( backatoms[i][j].serial(), bat_str );
+     118       13406 :       if( i==0 && j==0 ) all_atoms = "ATOMS=" + bat_str;
+     119       26708 :       else all_atoms += "," + bat_str;
+     120             :     }
+     121             :   }
+     122          26 : }
+     123             : 
+     124             : 
+     125          26 : SecondaryStructureRMSD::SecondaryStructureRMSD(const ActionOptions&ao):
+     126             :   Action(ao),
+     127             :   ActionWithVector(ao),
+     128          26 :   nopbc(false),
+     129          26 :   align_strands(false),
+     130          26 :   s_cutoff2(0),
+     131          26 :   align_atom_1(0),
+     132          26 :   align_atom_2(0)
+     133             : {
+     134          26 :   if( plumed.usingNaturalUnits() ) error("cannot use this collective variable when using natural units");
+     135             : 
+     136          52 :   parse("TYPE",alignType); parseFlag("NOPBC",nopbc);
+     137          26 :   log.printf("  distances from secondary structure elements are calculated using %s algorithm\n",alignType.c_str() );
+     138          52 :   log<<"  Bibliography "<<plumed.cite("Pietrucci and Laio, J. Chem. Theory Comput. 5, 2197 (2009)"); log<<"\n";
+     139             : 
+     140          26 :   parseFlag("VERBOSE",verbose_output);
+     141             : 
+     142          52 :   if( keywords.exists("STRANDS_CUTOFF") ) {
+     143          26 :     double s_cutoff = 0;
+     144          26 :     parse("STRANDS_CUTOFF",s_cutoff); align_strands=true;
+     145          26 :     if( s_cutoff>0) {
+     146          20 :       log.printf("  ignoring contributions from strands that are more than %f apart\n",s_cutoff);
+     147          40 :       std::vector<unsigned> cutatoms; parseVector("CUTOFF_ATOMS",cutatoms);
+     148          20 :       if( cutatoms.size()==2 ) {
+     149          20 :         align_atom_1=cutatoms[0]; align_atom_2=cutatoms[1];
+     150           0 :       } else error("did not find CUTOFF_ATOMS in input");
+     151             :     }
+     152          26 :     s_cutoff2=s_cutoff*s_cutoff;
+     153             :   }
+     154             : 
+     155             :   // Read in the atoms
+     156          52 :   std::vector<AtomNumber> all_atoms; parseAtomList("ATOMS",all_atoms); requestAtoms( all_atoms );
+     157             : 
+     158       99367 :   for(unsigned i=1;; ++i) {
+     159             :     std::vector<unsigned> newatoms;
+     160      198786 :     if( !parseNumberedVector("SEGMENT",i,newatoms) ) break;
+     161       99367 :     if( verbose_output ) {
+     162           0 :       log.printf("  Secondary structure segment %u contains atoms : ", static_cast<unsigned>(colvar_atoms.size()+1));
+     163           0 :       for(unsigned i=0; i<newatoms.size(); ++i) log.printf("%d ",all_atoms[newatoms[i]].serial() );
+     164           0 :       log.printf("\n");
+     165             :     }
+     166       99367 :     colvar_atoms.push_back( newatoms );
+     167       99367 :   }
+     168             : 
+     169          52 :   double bondlength; parse("BONDLENGTH",bondlength); bondlength=bondlength/getUnits().getLength();
+     170             : 
+     171             :   // Read in the reference structure
+     172          38 :   for(unsigned ii=1;; ++ii) {
+     173             :     std::vector<double> cstruct;
+     174         128 :     if( !parseNumberedVector("STRUCTURE",ii,cstruct) ) break ;
+     175          38 :     plumed_assert( cstruct.size()%3==0 && cstruct.size()/3==colvar_atoms[0].size() );
+     176          38 :     std::vector<Vector> structure( cstruct.size()/3 );
+     177        1178 :     for(unsigned i=0; i<structure.size(); ++i) {
+     178        4560 :       for(unsigned j=0; j<3; ++j) structure[i][j] = 0.1*cstruct[3*i+j]/getUnits().getLength();
+     179             :     }
+     180          38 :     if( alignType=="DRMSD" ) {
+     181             :       std::map<std::pair<unsigned,unsigned>, double> targets;
+     182         570 :       for(unsigned i=0; i<structure.size()-1; ++i) {
+     183        8816 :         for(unsigned j=i+1; j<structure.size(); ++j) {
+     184        8265 :           double distance = delta( structure[i], structure[j] ).modulo();
+     185        8265 :           if(distance > bondlength) targets[std::make_pair(i,j)] = distance;
+     186             :         }
+     187             :       }
+     188          19 :       drmsd_targets.push_back( targets );
+     189             :     } else {
+     190          19 :       Vector center; std::vector<double> align( structure.size(), 1.0 ), displace( structure.size(), 1.0 );
+     191         589 :       for(unsigned i=0; i<structure.size(); ++i) center+=structure[i]*align[i];
+     192         589 :       for(unsigned i=0; i<structure.size(); ++i) structure[i] -= center;
+     193          19 :       RMSD newrmsd; newrmsd.clear();
+     194          19 :       newrmsd.set(align,displace,structure,alignType,true,true);
+     195          19 :       myrmsd.push_back( newrmsd );
+     196          19 :     }
+     197          38 :   }
+     198             : 
+     199             :   // And create values to hold everything
+     200          26 :   unsigned nref = myrmsd.size(); if( alignType=="DRMSD" ) nref=drmsd_targets.size();
+     201          26 :   plumed_assert( nref>0 );
+     202          26 :   std::vector<unsigned> shape(1); shape[0]=colvar_atoms.size();
+     203          26 :   if( nref==1 ) { addValue( shape ); setNotPeriodic(); }
+     204             :   else {
+     205             :     std::string num;
+     206          36 :     for(unsigned i=0; i<nref; ++i) {
+     207          24 :       Tools::convert( i+1, num ); addComponent( "struct-" + num, shape );
+     208          48 :       componentIsNotPeriodic( "struct-" + num );
+     209             :     }
+     210             :   }
+     211          26 : }
+     212             : 
+     213          64 : void SecondaryStructureRMSD::areAllTasksRequired( std::vector<ActionWithVector*>& task_reducing_actions ) {
+     214          64 :   if( s_cutoff2>0 ) task_reducing_actions.push_back(this);
+     215          64 : }
+     216             : 
+     217      397524 : int SecondaryStructureRMSD::checkTaskStatus( const unsigned& taskno, int& flag ) const {
+     218      397524 :   if( s_cutoff2>0 ) {
+     219      397524 :     Vector distance=pbcDistance( ActionAtomistic::getPosition( getAtomIndex(taskno,align_atom_1) ),
+     220             :                                  ActionAtomistic::getPosition( getAtomIndex(taskno,align_atom_2) ) );
+     221      397524 :     if( distance.modulo2()<s_cutoff2 ) return 1;
+     222      360914 :     return 0;
+     223           0 :   } return flag;
+     224             : }
+     225             : 
+     226         204 : void SecondaryStructureRMSD::calculate() {
+     227         204 :   runAllTasks();
+     228         204 : }
+     229             : 
+     230       37042 : void SecondaryStructureRMSD::performTask( const unsigned& current, MultiValue& myvals ) const {
+     231             :   // Resize the derivatives if need be
+     232       37042 :   unsigned nderi = 3*getNumberOfAtoms()+9;
+     233       37042 :   if( myvals.getNumberOfDerivatives()!=nderi ) myvals.resize( myvals.getNumberOfValues(), nderi, 0, 0 );
+     234             :   // Retrieve the positions
+     235       37042 :   const unsigned natoms = colvar_atoms[current].size();
+     236       37042 :   std::vector<Vector> pos( natoms ), deriv( natoms );
+     237     1148302 :   for(unsigned i=0; i<natoms; ++i) pos[i]=ActionAtomistic::getPosition( getAtomIndex(current,i) );
+     238             : 
+     239             :   // This aligns the two strands if this is required
+     240       37042 :   Vector distance=pbcDistance( pos[align_atom_1],pos[align_atom_2] );
+     241       37042 :   if( align_strands ) {
+     242       37042 :     Vector origin_old, origin_new; origin_old=pos[align_atom_2];
+     243       37042 :     origin_new=pos[align_atom_1]+distance;
+     244      592672 :     for(unsigned i=15; i<30; ++i) {
+     245      555630 :       pos[i]+=( origin_new - origin_old );
+     246             :     }
+     247           0 :   } else if( !nopbc ) {
+     248           0 :     for(unsigned i=0; i<natoms-1; ++i) {
+     249           0 :       const Vector & first (pos[i]);
+     250           0 :       Vector & second (pos[i+1]);
+     251           0 :       second=first+pbcDistance(first,second);
+     252             :     }
+     253             :   }
+     254             :   // Create a holder for the derivatives
+     255       37042 :   if( alignType=="DRMSD" ) {
+     256             :     // And now calculate the DRMSD
+     257       12758 :     const unsigned rs = drmsd_targets.size();
+     258       31895 :     for(unsigned i=0; i<rs; ++i) {
+     259       19137 :       double drmsd=0; Vector distance; Tensor vir; vir.zero();
+     260      593247 :       for(unsigned j=0; j<natoms; ++j) deriv[j].zero();
+     261     7807716 :       for(const auto & it : drmsd_targets[i] ) {
+     262     7788579 :         const unsigned k=it.first.first;
+     263     7788579 :         const unsigned j=it.first.second;
+     264             : 
+     265     7788579 :         distance=delta( pos[k], pos[j] );
+     266     7788579 :         const double len = distance.modulo();
+     267     7788579 :         const double diff = len - it.second;
+     268     7788579 :         const double der = diff / len;
+     269     7788579 :         drmsd += diff*diff;
+     270             : 
+     271     7788579 :         if( !doNotCalculateDerivatives() ) {
+     272     7559115 :           deriv[k] += -der*distance; deriv[j] += der*distance;
+     273     7559115 :           vir += -der*Tensor(distance,distance);
+     274             :         }
+     275             :       }
+     276             : 
+     277       19137 :       const double inpairs = 1./static_cast<double>(drmsd_targets[i].size());
+     278       19137 :       unsigned ostrn = getConstPntrToComponent(i)->getPositionInStream();
+     279       19137 :       drmsd = sqrt(inpairs*drmsd); myvals.setValue( ostrn, drmsd );
+     280             : 
+     281       19137 :       if( !doNotCalculateDerivatives() ) {
+     282       18573 :         double scalef = inpairs / drmsd;
+     283      575763 :         for(unsigned j=0; j<natoms; ++j) {
+     284             :           const unsigned ja = getAtomIndex( current, j );
+     285      557190 :           myvals.addDerivative( ostrn, 3*ja + 0, scalef*deriv[j][0] ); myvals.updateIndex( ostrn, 3*ja+0 );
+     286      557190 :           myvals.addDerivative( ostrn, 3*ja + 1, scalef*deriv[j][1] ); myvals.updateIndex( ostrn, 3*ja+1 );
+     287      557190 :           myvals.addDerivative( ostrn, 3*ja + 2, scalef*deriv[j][2] ); myvals.updateIndex( ostrn, 3*ja+2 );
+     288             :         }
+     289       18573 :         unsigned nbase = myvals.getNumberOfDerivatives() - 9;
+     290       74292 :         for(unsigned k=0; k<3; ++k) {
+     291      222876 :           for(unsigned j=0; j<3; ++j) {
+     292      167157 :             myvals.addDerivative( ostrn, nbase + 3*k + j, scalef*vir(k,j) );
+     293      167157 :             myvals.updateIndex( ostrn, nbase + 3*k + j );
+     294             :           }
+     295             :         }
+     296             :       }
+     297             :     }
+     298             :   } else {
+     299       24284 :     const unsigned rs = myrmsd.size();
+     300       60688 :     for(unsigned i=0; i<rs; ++i) {
+     301       36404 :       double nr = myrmsd[i].calculate( pos, deriv, false );
+     302       36404 :       unsigned ostrn = getConstPntrToComponent(i)->getPositionInStream();
+     303       36404 :       myvals.setValue( ostrn, nr );
+     304             : 
+     305       36404 :       if( !doNotCalculateDerivatives() ) {
+     306       36404 :         Tensor vir; vir.zero();
+     307     1128524 :         for(unsigned j=0; j<natoms; ++j) {
+     308             :           const unsigned ja = getAtomIndex( current, j );
+     309     1092120 :           myvals.addDerivative( ostrn, 3*ja + 0, deriv[j][0] ); myvals.updateIndex( ostrn, 3*colvar_atoms[current][j]+0 );
+     310     1092120 :           myvals.addDerivative( ostrn, 3*ja + 1, deriv[j][1] ); myvals.updateIndex( ostrn, 3*colvar_atoms[current][j]+1 );
+     311     1092120 :           myvals.addDerivative( ostrn, 3*ja + 2, deriv[j][2] ); myvals.updateIndex( ostrn, 3*colvar_atoms[current][j]+2 );
+     312     1092120 :           vir+=(-1.0*Tensor( pos[j], deriv[j] ));
+     313             :         }
+     314       36404 :         unsigned nbase = myvals.getNumberOfDerivatives() - 9;
+     315      145616 :         for(unsigned k=0; k<3; ++k) {
+     316      436848 :           for(unsigned j=0; j<3; ++j) {
+     317      327636 :             myvals.addDerivative( ostrn, nbase + 3*k + j, vir(k,j) );
+     318      327636 :             myvals.updateIndex( ostrn, nbase + 3*k + j );
+     319             :           }
+     320             :         }
+     321             :       }
+     322             :     }
+     323             :   }
+     324       37042 :   return;
+     325             : }
+     326             : 
+     327             : }
+     328             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/secondarystructure/SecondaryStructureRMSD.h.func-sort-c.html b/coverage/secondarystructure/SecondaryStructureRMSD.h.func-sort-c.html new file mode 100644 index 000000000000..e6b915b47b77 --- /dev/null +++ b/coverage/secondarystructure/SecondaryStructureRMSD.h.func-sort-c.html @@ -0,0 +1,77 @@ + + + + + + + + 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:33100.0 %
Date:2024-04-19 12:12:35Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18secondarystructure22SecondaryStructureRMSD22getNumberOfDerivativesEv86
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/secondarystructure/SecondaryStructureRMSD.h.func.html b/coverage/secondarystructure/SecondaryStructureRMSD.h.func.html new file mode 100644 index 000000000000..fa16164bf687 --- /dev/null +++ b/coverage/secondarystructure/SecondaryStructureRMSD.h.func.html @@ -0,0 +1,77 @@ + + + + + + + + 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:33100.0 %
Date:2024-04-19 12:12:35Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18secondarystructure22SecondaryStructureRMSD22getNumberOfDerivativesEv86
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/secondarystructure/SecondaryStructureRMSD.h.gcov.html b/coverage/secondarystructure/SecondaryStructureRMSD.h.gcov.html new file mode 100644 index 000000000000..1fc3179a911d --- /dev/null +++ b/coverage/secondarystructure/SecondaryStructureRMSD.h.gcov.html @@ -0,0 +1,162 @@ + + + + + + + + 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:33100.0 %
Date:2024-04-19 12:12:35Functions:11100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2020 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a 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/ActionWithVector.h"
+      26             : #include "tools/RMSD.h"
+      27             : #include <vector>
+      28             : 
+      29             : namespace PLMD {
+      30             : 
+      31             : class ActionShortcut;
+      32             : 
+      33             : namespace secondarystructure {
+      34             : 
+      35             : /// Base action for calculating things like AlphRMSD, AntibetaRMSD, etc
+      36             : 
+      37             : class SecondaryStructureRMSD : public ActionWithVector {
+      38             : private:
+      39             : /// Are we operating without periodic boundary conditions
+      40             :   bool nopbc;
+      41             : /// The type of rmsd we are calculating
+      42             :   std::string alignType;
+      43             : /// List of all the atoms we require
+      44             :   std::vector<AtomNumber> all_atoms;
+      45             : /// The list of tasks that we need to do on the round
+      46             :   std::vector<unsigned> ss_tasks;
+      47             : /// The atoms involved in each of the secondary structure segments
+      48             :   std::vector< std::vector<unsigned> > colvar_atoms;
+      49             : /// The list of reference configurations
+      50             :   std::vector<RMSD> myrmsd;
+      51             :   std::vector<std::map<std::pair<unsigned,unsigned>, double> > drmsd_targets;
+      52             : /// Variables for strands cutoff
+      53             :   bool align_strands;
+      54             :   double s_cutoff2;
+      55             :   unsigned align_atom_1, align_atom_2;
+      56             :   bool verbose_output;
+      57             : /// Get the index of an atom
+      58             :   unsigned getAtomIndex( const unsigned& current, const unsigned& iatom ) const ;
+      59             : public:
+      60             :   static void registerKeywords( Keywords& keys );
+      61             :   static void readBackboneAtoms( ActionShortcut* action, PlumedMain& plumed, const std::string& backnames, std::vector<unsigned>& chain_lengths, std::string& all_atoms );
+      62             :   static bool readShortcutWords( std::string& ltmap, ActionShortcut* action );
+      63             :   static void expandShortcut( const bool& uselessthan, const std::string& labout, const std::string& labin, const std::string& ltmap, ActionShortcut* action );
+      64             :   explicit SecondaryStructureRMSD(const ActionOptions&);
+      65             :   unsigned getNumberOfDerivatives() override ;
+      66             :   void areAllTasksRequired( std::vector<ActionWithVector*>& task_reducing_actions ) override;
+      67             :   int checkTaskStatus( const unsigned& taskno, int& flag ) const override;
+      68             :   void calculate() override;
+      69             :   void performTask( const unsigned&, MultiValue& ) const override;
+      70             : };
+      71             : 
+      72             : inline
+      73          86 : unsigned SecondaryStructureRMSD::getNumberOfDerivatives() {
+      74          86 :   return 3*getNumberOfAtoms()+9;
+      75             : }
+      76             : 
+      77             : inline
+      78             : unsigned SecondaryStructureRMSD::getAtomIndex( const unsigned& current, const unsigned& iatom ) const {
+      79     3158094 :   return colvar_atoms[current][iatom];
+      80             : }
+      81             : 
+      82             : }
+      83             : }
+      84             : 
+      85             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/secondarystructure/index-sort-f.html b/coverage/secondarystructure/index-sort-f.html new file mode 100644 index 000000000000..3038abd57dae --- /dev/null +++ b/coverage/secondarystructure/index-sort-f.html @@ -0,0 +1,134 @@ + + + + + + + + LCOV - plumed test coverage - secondarystructure + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - secondarystructureHitTotalCoverage
Test:plumed test coverageLines:46848396.9 %
Date:2024-04-19 12:12:35Functions:162080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
AlphaRMSD.cpp +
100.0%
+
100.0 %62 / 6266.7 %2 / 3
AntibetaRMSD.cpp +
97.9%97.9%
+
97.9 %94 / 9666.7 %2 / 3
ParabetaRMSD.cpp +
97.7%97.7%
+
97.7 %130 / 13366.7 %2 / 3
SecondaryStructureRMSD.cpp +
94.7%94.7%
+
94.7 %179 / 18990.0 %9 / 10
SecondaryStructureRMSD.h +
100.0%
+
100.0 %3 / 3100.0 %1 / 1
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/secondarystructure/index-sort-l.html b/coverage/secondarystructure/index-sort-l.html new file mode 100644 index 000000000000..c578a282767d --- /dev/null +++ b/coverage/secondarystructure/index-sort-l.html @@ -0,0 +1,134 @@ + + + + + + + + LCOV - plumed test coverage - secondarystructure + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - secondarystructureHitTotalCoverage
Test:plumed test coverageLines:46848396.9 %
Date:2024-04-19 12:12:35Functions:162080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
SecondaryStructureRMSD.cpp +
94.7%94.7%
+
94.7 %179 / 18990.0 %9 / 10
ParabetaRMSD.cpp +
97.7%97.7%
+
97.7 %130 / 13366.7 %2 / 3
AntibetaRMSD.cpp +
97.9%97.9%
+
97.9 %94 / 9666.7 %2 / 3
SecondaryStructureRMSD.h +
100.0%
+
100.0 %3 / 3100.0 %1 / 1
AlphaRMSD.cpp +
100.0%
+
100.0 %62 / 6266.7 %2 / 3
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/secondarystructure/index.html b/coverage/secondarystructure/index.html new file mode 100644 index 000000000000..70bcbb30f562 --- /dev/null +++ b/coverage/secondarystructure/index.html @@ -0,0 +1,134 @@ + + + + + + + + LCOV - plumed test coverage - secondarystructure + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - secondarystructureHitTotalCoverage
Test:plumed test coverageLines:46848396.9 %
Date:2024-04-19 12:12:35Functions:162080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
AlphaRMSD.cpp +
100.0%
+
100.0 %62 / 6266.7 %2 / 3
AntibetaRMSD.cpp +
97.9%97.9%
+
97.9 %94 / 9666.7 %2 / 3
ParabetaRMSD.cpp +
97.7%97.7%
+
97.7 %130 / 13366.7 %2 / 3
SecondaryStructureRMSD.cpp +
94.7%94.7%
+
94.7 %179 / 18990.0 %9 / 10
SecondaryStructureRMSD.h +
100.0%
+
100.0 %3 / 3100.0 %1 / 1
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/setup/Load.cpp.func-sort-c.html b/coverage/setup/Load.cpp.func-sort-c.html new file mode 100644 index 000000000000..d8a3b53d0b64 --- /dev/null +++ b/coverage/setup/Load.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - setup/Load.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - setup - Load.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1010100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5setup4LoadC2ERKNS_13ActionOptionsE0
_ZN4PLMD5setup4LoadC1ERKNS_13ActionOptionsE42
_ZN4PLMD5setup4Load16registerKeywordsERNS_8KeywordsE44
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/setup/Load.cpp.func.html b/coverage/setup/Load.cpp.func.html new file mode 100644 index 000000000000..a4ad8e4814cb --- /dev/null +++ b/coverage/setup/Load.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - setup/Load.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - setup - Load.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1010100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5setup4Load16registerKeywordsERNS_8KeywordsE44
_ZN4PLMD5setup4LoadC1ERKNS_13ActionOptionsE42
_ZN4PLMD5setup4LoadC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/setup/Load.cpp.gcov.html b/coverage/setup/Load.cpp.gcov.html new file mode 100644 index 000000000000..57febd7477c6 --- /dev/null +++ b/coverage/setup/Load.cpp.gcov.html @@ -0,0 +1,223 @@ + + + + + + + + LCOV - plumed test coverage - setup/Load.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - setup - Load.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1010100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionAnyorder.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             : Starting with PLUMED 2.10, the LOAD action can be placed in any point of the input
+      93             : file, and will only affect commands that are placed after the LOAD action.
+      94             : In other words, you can create a file named `Distance.cpp` and that reimplement
+      95             : the \ref DISTANCE action and use it like this:
+      96             : 
+      97             : \plumedfile
+      98             : # compute standard distance
+      99             : d: DISTANCE ATOMS=1,10
+     100             : # load the new definition
+     101             : LOAD FILE=Distance.so
+     102             : # compute modified distance
+     103             : d2: DISTANCE ATOMS=1,10
+     104             : # print them on a file
+     105             : PRINT ARG=d,d2 FILE=compare-them
+     106             : \endplumedfile
+     107             : 
+     108             : In addition, starting with PLUMED 2.10 the LOAD action can be used in contexts where
+     109             : multiple Plumed objects exist. A possible example is multithreading: loading an action
+     110             : from a Plumed object used in one thread will not affect other threads.
+     111             : Another example is if multiple Plumed objects are created in the C/C++ or Python interface.
+     112             : If a LOAD command is used in one of these objects, the loaded action will not affect
+     113             : the other objects.
+     114             : 
+     115             : 
+     116             : */
+     117             : //+ENDPLUMEDOC
+     118             : 
+     119             : class Load :
+     120             :   public virtual ActionAnyorder
+     121             : {
+     122             : public:
+     123             :   static void registerKeywords( Keywords& keys );
+     124             :   explicit Load(const ActionOptions&ao);
+     125             : };
+     126             : 
+     127             : PLUMED_REGISTER_ACTION(Load,"LOAD")
+     128             : 
+     129          44 : void Load::registerKeywords( Keywords& keys ) {
+     130          44 :   ActionAnyorder::registerKeywords(keys);
+     131          88 :   keys.add("compulsory","FILE","file to be loaded");
+     132          44 : }
+     133             : 
+     134          42 : Load::Load(const ActionOptions&ao):
+     135             :   Action(ao),
+     136          42 :   ActionAnyorder(ao)
+     137             : {
+     138             :   std::string f;
+     139          43 :   parse("FILE",f);
+     140          42 :   checkRead();
+     141          42 :   plumed.load(f);
+     142          42 : }
+     143             : 
+     144             : }
+     145             : }
+     146             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/setup/Restart.cpp.func-sort-c.html b/coverage/setup/Restart.cpp.func-sort-c.html new file mode 100644 index 000000000000..7a35f5b3a16e --- /dev/null +++ b/coverage/setup/Restart.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - setup/Restart.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - setup - Restart.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1818100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5setup7RestartC2ERKNS_13ActionOptionsE0
_ZN4PLMD5setup7RestartC1ERKNS_13ActionOptionsE56
_ZN4PLMD5setup7Restart16registerKeywordsERNS_8KeywordsE58
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/setup/Restart.cpp.func.html b/coverage/setup/Restart.cpp.func.html new file mode 100644 index 000000000000..0fd6ed1dd3e2 --- /dev/null +++ b/coverage/setup/Restart.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - setup/Restart.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - setup - Restart.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1818100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5setup7Restart16registerKeywordsERNS_8KeywordsE58
_ZN4PLMD5setup7RestartC1ERKNS_13ActionOptionsE56
_ZN4PLMD5setup7RestartC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/setup/Restart.cpp.gcov.html b/coverage/setup/Restart.cpp.gcov.html new file mode 100644 index 000000000000..085ce75b94ec --- /dev/null +++ b/coverage/setup/Restart.cpp.gcov.html @@ -0,0 +1,202 @@ + + + + + + + + LCOV - plumed test coverage - setup/Restart.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - setup - Restart.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1818100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionSetup.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "core/PlumedMain.h"
+      25             : #include "tools/Exception.h"
+      26             : 
+      27             : namespace PLMD {
+      28             : namespace setup {
+      29             : 
+      30             : //+PLUMEDOC GENERIC RESTART
+      31             : /*
+      32             : Activate restart.
+      33             : 
+      34             : This is a Setup directive and, as such, should appear
+      35             : at the beginning of the input file. It influences the way
+      36             : PLUMED treat files open for writing (see also \ref Files).
+      37             : 
+      38             : Notice that it is also possible to enable or disable restart on a per-action
+      39             : basis using the RESTART keyword on a single action. In this case,
+      40             : the keyword should be assigned a value. RESTART=AUTO means that global
+      41             : settings are used, RESTART=YES or RESTART=NO respectively enable
+      42             : and disable restart for that single action.
+      43             : 
+      44             : \attention
+      45             : This directive can have also other side effects, e.g. on \ref METAD
+      46             : and \ref PBMETAD and on some analysis action.
+      47             : 
+      48             : \par Examples
+      49             : 
+      50             : Using the following input:
+      51             : \plumedfile
+      52             : d: DISTANCE ATOMS=1,2
+      53             : PRINT ARG=d FILE=out
+      54             : \endplumedfile
+      55             : a new 'out' file will be created. If an old one is on the way, it will be automatically backed up.
+      56             : 
+      57             : On the other hand, using the following input:
+      58             : \plumedfile
+      59             : RESTART
+      60             : d: DISTANCE ATOMS=1,2
+      61             : PRINT ARG=d FILE=out
+      62             : \endplumedfile
+      63             : the file 'out' will be appended.
+      64             : 
+      65             : In the following case, file out1 will be backed up and file out2 will be concatenated
+      66             : \plumedfile
+      67             : RESTART
+      68             : d1: DISTANCE ATOMS=1,2
+      69             : d2: DISTANCE ATOMS=1,2
+      70             : PRINT ARG=d1 FILE=out1 RESTART=NO
+      71             : PRINT ARG=d2 FILE=out2
+      72             : \endplumedfile
+      73             : 
+      74             : In the following case, file out will backed up even if the MD code thinks that we
+      75             : are restarting. Notice that not all the MD code send to PLUMED information about restarts.
+      76             : If you are not sure, always put `RESTART` when you are restarting and nothing when you aren't
+      77             : \plumedfile
+      78             : RESTART NO
+      79             : d1: DISTANCE ATOMS=1,2
+      80             : PRINT ARG=d1 FILE=out1
+      81             : \endplumedfile
+      82             : 
+      83             : 
+      84             : 
+      85             : 
+      86             : 
+      87             : */
+      88             : //+ENDPLUMEDOC
+      89             : 
+      90             : class Restart :
+      91             :   public virtual ActionSetup
+      92             : {
+      93             : public:
+      94             :   static void registerKeywords( Keywords& keys );
+      95             :   explicit Restart(const ActionOptions&ao);
+      96             : };
+      97             : 
+      98             : PLUMED_REGISTER_ACTION(Restart,"RESTART")
+      99             : 
+     100          58 : void Restart::registerKeywords( Keywords& keys ) {
+     101          58 :   ActionSetup::registerKeywords(keys);
+     102         116 :   keys.addFlag("NO",false,"switch off restart - can be used to override the behavior of the MD engine");
+     103          58 : }
+     104             : 
+     105          56 : Restart::Restart(const ActionOptions&ao):
+     106             :   Action(ao),
+     107          56 :   ActionSetup(ao)
+     108             : {
+     109          56 :   bool no=false;
+     110          56 :   parseFlag("NO",no);
+     111          56 :   bool md=plumed.getRestart();
+     112         111 :   log<<"  MD code "<<(md?"did":"didn't")<<" require restart\n";
+     113          56 :   if(no) {
+     114           1 :     if(md) log<<"  Switching off restart\n";
+     115           1 :     plumed.setRestart(false);
+     116           1 :     log<<"  Not restarting simulation: files will be backed up\n";
+     117             :   } else {
+     118          55 :     if(!md) log<<"  Switching on restart\n";
+     119          55 :     plumed.setRestart(true);
+     120          55 :     log<<"  Restarting simulation: files will be appended\n";
+     121             :   }
+     122          56 : }
+     123             : 
+     124             : }
+     125             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/setup/Units.cpp.func-sort-c.html b/coverage/setup/Units.cpp.func-sort-c.html new file mode 100644 index 000000000000..61d753dcb924 --- /dev/null +++ b/coverage/setup/Units.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - setup/Units.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - setup - Units.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:545696.4 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5setup5UnitsC2ERKNS_13ActionOptionsE0
_ZN4PLMD5setup5UnitsC1ERKNS_13ActionOptionsE28
_ZN4PLMD5setup5Units16registerKeywordsERNS_8KeywordsE30
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/setup/Units.cpp.func.html b/coverage/setup/Units.cpp.func.html new file mode 100644 index 000000000000..b5d94be3b03e --- /dev/null +++ b/coverage/setup/Units.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - setup/Units.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - setup - Units.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:545696.4 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5setup5Units16registerKeywordsERNS_8KeywordsE30
_ZN4PLMD5setup5UnitsC1ERKNS_13ActionOptionsE28
_ZN4PLMD5setup5UnitsC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/setup/Units.cpp.gcov.html b/coverage/setup/Units.cpp.gcov.html new file mode 100644 index 000000000000..99238cfe9943 --- /dev/null +++ b/coverage/setup/Units.cpp.gcov.html @@ -0,0 +1,275 @@ + + + + + + + + LCOV - plumed test coverage - setup/Units.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - setup - Units.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:545696.4 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionSetup.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "core/PlumedMain.h"
+      25             : #include "tools/Exception.h"
+      26             : 
+      27             : namespace PLMD {
+      28             : namespace setup {
+      29             : 
+      30             : //+PLUMEDOC GENERIC UNITS
+      31             : /*
+      32             : This command sets the internal units for the code.
+      33             : 
+      34             : A new unit can be set by either
+      35             : specifying a conversion factor from the plumed default unit or by using a string
+      36             : corresponding to one of the defined units given below.  This directive MUST
+      37             : appear at the BEGINNING of the plumed.dat file.  The same units must be used
+      38             : throughout the plumed.dat file.
+      39             : 
+      40             : Notice that all input/output will then be made using the specified units.
+      41             : That is: all the input parameters, all the output files, etc. The only
+      42             : exceptions are file formats for which there is a specific convention concerning
+      43             : the units. For example, trajectories written in .gro format (with \ref DUMPATOMS)
+      44             : are going to be always in nm.
+      45             : 
+      46             : The following strings can be used to specify units. Note that the strings are
+      47             : case sensitive.
+      48             : - LENGTH: nm (default), A (for Angstrom), um (for micrometer), Bohr (0.052917721067 nm)
+      49             : - ENERGY: kj/mol (default), j/mol, kcal/mol (4.184 kj/mol), eV (96.48530749925792 kj/mol), Ha (for Hartree, 2625.499638 kj/mol)
+      50             : - TIME: ps (default), fs, ns, atomic (2.418884326509e-5 ps)
+      51             : - MASS: amu (default)
+      52             : - CHARGE: e (default)
+      53             : 
+      54             : 
+      55             : \par Examples
+      56             : 
+      57             : \plumedfile
+      58             : # this is using Angstrom - kj/mol - fs
+      59             : UNITS LENGTH=A TIME=fs
+      60             : 
+      61             : # compute distance between atoms 1 and 4
+      62             : d: DISTANCE ATOMS=1,4
+      63             : 
+      64             : # print time and distance on a COLVAR file
+      65             : PRINT ARG=d FILE=COLVAR
+      66             : 
+      67             : # dump atoms 1 to 100 on a 'out.gro' file
+      68             : DUMPATOMS FILE=out.gro STRIDE=10 ATOMS=1-100
+      69             : 
+      70             : # dump atoms 1 to 100 on a 'out.xyz' file
+      71             : DUMPATOMS FILE=out.xyz STRIDE=10 ATOMS=1-100
+      72             : \endplumedfile
+      73             : 
+      74             : In the `COLVAR` file, time and distance will appear in fs and A respectively, *irrespective* of which units
+      75             : you are using in the host MD code. The coordinates in the `out.gro` file will be expressed in nm,
+      76             : since `gro` files are by convention written in nm. The coordinates in the `out.xyz` file
+      77             : will be written in Angstrom *since we used the UNITS command setting Angstrom units*.
+      78             : Indeed, within PLUMED xyz files are using internal PLUMED units and not necessarily Angstrom!
+      79             : 
+      80             : If a number, x, is found instead of a string, the new unit is equal to x times the default units.
+      81             : Using the following command as first line of the previous example would have lead to an identical result:
+      82             : \plumedfile
+      83             : UNITS LENGTH=0.1 TIME=0.001
+      84             : \endplumedfile
+      85             : 
+      86             : */
+      87             : //+ENDPLUMEDOC
+      88             : 
+      89             : class Units :
+      90             :   public virtual ActionSetup
+      91             : {
+      92             : public:
+      93             :   static void registerKeywords( Keywords& keys );
+      94             :   explicit Units(const ActionOptions&ao);
+      95             : };
+      96             : 
+      97             : PLUMED_REGISTER_ACTION(Units,"UNITS")
+      98             : 
+      99          30 : void Units::registerKeywords( Keywords& keys ) {
+     100          30 :   ActionSetup::registerKeywords(keys);
+     101          60 :   keys.add("optional","LENGTH","the units of lengths.  Either specify a conversion factor from the default, nm, or use one of the defined units, A (for angstroms), um (for micrometer), and Bohr.");
+     102          60 :   keys.add("optional","ENERGY","the units of energy.  Either specify a conversion factor from the default, kj/mol, or use one of the defined units, j/mol, kcal/mol and Ha (for Hartree)");
+     103          60 :   keys.add("optional","TIME","the units of time.  Either specify a conversion factor from the default, ps, or use one of the defined units, ns, fs, and atomic");
+     104          60 :   keys.add("optional","MASS","the units of masses.  Specify a conversion factor from the default, amu");
+     105          60 :   keys.add("optional","CHARGE","the units of charges.  Specify a conversion factor from the default, e");
+     106          60 :   keys.addFlag("NATURAL",false,"use natural units");
+     107          30 : }
+     108             : 
+     109          28 : Units::Units(const ActionOptions&ao):
+     110             :   Action(ao),
+     111          28 :   ActionSetup(ao)
+     112             : {
+     113          28 :   PLMD::Units u;
+     114             : 
+     115             :   std::string s;
+     116             : 
+     117             :   s="";
+     118          56 :   parse("LENGTH",s);
+     119          28 :   if(s.length()>0) u.setLength(s);
+     120          54 :   if(u.getLengthString().length()>0 && u.getLengthString()=="nm") {
+     121           8 :     log.printf("  length: %s\n",u.getLengthString().c_str());
+     122             :   }
+     123          38 :   else if(u.getLengthString().length()>0 && u.getLengthString()!="nm") {
+     124          18 :     log.printf("  length: %s = %g nm\n",u.getLengthString().c_str(),u.getLength());
+     125             :   }
+     126             :   else {
+     127           2 :     log.printf("  length: %g nm\n",u.getLength());
+     128             :   }
+     129             : 
+     130             :   s="";
+     131          56 :   parse("ENERGY",s);
+     132          28 :   if(s.length()>0) u.setEnergy(s);
+     133          54 :   if(u.getEnergyString().length()>0 && u.getEnergyString()=="kj/mol") {
+     134          21 :     log.printf("  energy: %s\n",u.getEnergyString().c_str());
+     135             :   }
+     136          12 :   else if(u.getEnergyString().length()>0 && u.getEnergyString()!="kj/mol") {
+     137           5 :     log.printf("  energy: %s = %g kj/mol\n",u.getEnergyString().c_str(),u.getEnergy());
+     138             :   }
+     139             :   else {
+     140           2 :     log.printf("  energy: %g kj/mol\n",u.getEnergy());
+     141             :   }
+     142             : 
+     143             :   s="";
+     144          56 :   parse("TIME",s);
+     145          28 :   if(s.length()>0) u.setTime(s);
+     146          54 :   if(u.getTimeString().length()>0 && u.getTimeString()=="ps") {
+     147          23 :     log.printf("  time: %s\n",u.getTimeString().c_str());
+     148             :   }
+     149           8 :   else if(u.getTimeString().length()>0 && u.getTimeString()!="ps") {
+     150           3 :     log.printf("  time: %s = %g ps\n",u.getTimeString().c_str(),u.getTime());
+     151             :   }
+     152             :   else {
+     153           2 :     log.printf("  time: %g ps\n",u.getTime());
+     154             :   }
+     155             : 
+     156             :   s="";
+     157          56 :   parse("CHARGE",s);
+     158          28 :   if(s.length()>0) u.setCharge(s);
+     159          54 :   if(u.getChargeString().length()>0 && u.getChargeString()=="e") {
+     160          26 :     log.printf("  charge: %s\n",u.getChargeString().c_str());
+     161             :   }
+     162           2 :   else if(u.getChargeString().length()>0 && u.getChargeString()!="e") {
+     163           0 :     log.printf("  charge: %s = %g e\n",u.getChargeString().c_str(),u.getCharge());
+     164             :   }
+     165             :   else {
+     166           2 :     log.printf("  charge: %g e\n",u.getCharge());
+     167             :   }
+     168             : 
+     169             :   s="";
+     170          56 :   parse("MASS",s);
+     171          28 :   if(s.length()>0) u.setMass(s);
+     172          55 :   if(u.getMassString().length()>0 && u.getMassString()=="amu") {
+     173          27 :     log.printf("  mass: %s\n",u.getMassString().c_str());
+     174             :   }
+     175           1 :   else if(u.getMassString().length()>0 && u.getMassString()!="amu") {
+     176           0 :     log.printf("  mass: %s = %g amu\n",u.getMassString().c_str(),u.getMass());
+     177             :   }
+     178             :   else {
+     179           1 :     log.printf("  mass: %g amu\n",u.getMass());
+     180             :   }
+     181             : 
+     182          28 :   bool natural=false;
+     183          28 :   parseFlag("NATURAL",natural);
+     184             : 
+     185          28 :   checkRead();
+     186             : 
+     187          28 :   if(natural) {
+     188           6 :     log.printf("  using natural units\n");
+     189             :   } else {
+     190          22 :     log.printf("  using physical units\n");
+     191             :   }
+     192          28 :   log.printf("  inside PLUMED, Boltzmann constant is %g\n",getKBoltzmann());
+     193             : 
+     194          28 :   plumed.setUnits(natural,u);
+     195          28 : }
+     196             : 
+     197             : }
+     198             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/setup/index-sort-f.html b/coverage/setup/index-sort-f.html new file mode 100644 index 000000000000..8478985e73b5 --- /dev/null +++ b/coverage/setup/index-sort-f.html @@ -0,0 +1,114 @@ + + + + + + + + LCOV - plumed test coverage - setup + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - setupHitTotalCoverage
Test:plumed test coverageLines:828497.6 %
Date:2024-04-19 12:12:35Functions:6966.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Units.cpp +
96.4%96.4%
+
96.4 %54 / 5666.7 %2 / 3
Restart.cpp +
100.0%
+
100.0 %18 / 1866.7 %2 / 3
Load.cpp +
100.0%
+
100.0 %10 / 1066.7 %2 / 3
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/setup/index-sort-l.html b/coverage/setup/index-sort-l.html new file mode 100644 index 000000000000..472eb119f8a4 --- /dev/null +++ b/coverage/setup/index-sort-l.html @@ -0,0 +1,114 @@ + + + + + + + + LCOV - plumed test coverage - setup + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - setupHitTotalCoverage
Test:plumed test coverageLines:828497.6 %
Date:2024-04-19 12:12:35Functions:6966.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Units.cpp +
96.4%96.4%
+
96.4 %54 / 5666.7 %2 / 3
Load.cpp +
100.0%
+
100.0 %10 / 1066.7 %2 / 3
Restart.cpp +
100.0%
+
100.0 %18 / 1866.7 %2 / 3
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/setup/index.html b/coverage/setup/index.html new file mode 100644 index 000000000000..6086537f4999 --- /dev/null +++ b/coverage/setup/index.html @@ -0,0 +1,114 @@ + + + + + + + + LCOV - plumed test coverage - setup + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - setupHitTotalCoverage
Test:plumed test coverageLines:828497.6 %
Date:2024-04-19 12:12:35Functions:6966.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Load.cpp +
100.0%
+
100.0 %10 / 1066.7 %2 / 3
Restart.cpp +
100.0%
+
100.0 %18 / 1866.7 %2 / 3
Units.cpp +
96.4%96.4%
+
96.4 %54 / 5666.7 %2 / 3
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/small_vector/index-sort-f.html b/coverage/small_vector/index-sort-f.html new file mode 100644 index 000000000000..f05af533708e --- /dev/null +++ b/coverage/small_vector/index-sort-f.html @@ -0,0 +1,94 @@ + + + + + + + + LCOV - plumed test coverage - small_vector + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - small_vectorHitTotalCoverage
Test:plumed test coverageLines:9110586.7 %
Date:2024-04-19 12:12:35Functions:314372.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
small_vector.h +
86.7%86.7%
+
86.7 %91 / 10572.1 %31 / 43
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/small_vector/index-sort-l.html b/coverage/small_vector/index-sort-l.html new file mode 100644 index 000000000000..0b82ab2b7fea --- /dev/null +++ b/coverage/small_vector/index-sort-l.html @@ -0,0 +1,94 @@ + + + + + + + + LCOV - plumed test coverage - small_vector + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - small_vectorHitTotalCoverage
Test:plumed test coverageLines:9110586.7 %
Date:2024-04-19 12:12:35Functions:314372.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
small_vector.h +
86.7%86.7%
+
86.7 %91 / 10572.1 %31 / 43
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/small_vector/index.html b/coverage/small_vector/index.html new file mode 100644 index 000000000000..d445dfb22331 --- /dev/null +++ b/coverage/small_vector/index.html @@ -0,0 +1,94 @@ + + + + + + + + LCOV - plumed test coverage - small_vector + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - small_vectorHitTotalCoverage
Test:plumed test coverageLines:9110586.7 %
Date:2024-04-19 12:12:35Functions:314372.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
small_vector.h +
86.7%86.7%
+
86.7 %91 / 10572.1 %31 / 43
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/small_vector/small_vector.h.func-sort-c.html b/coverage/small_vector/small_vector.h.func-sort-c.html new file mode 100644 index 000000000000..5d0f8fdbab2f --- /dev/null +++ b/coverage/small_vector/small_vector.h.func-sort-c.html @@ -0,0 +1,245 @@ + + + + + + + + LCOV - plumed test coverage - small_vector/small_vector.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - small_vector - small_vector.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:9110586.7 %
Date:2024-04-19 12:12:35Functions:314372.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3gch6detail17small_vector_baseISaINS_13VectorGenericILj3EEEELj6EE18allocation_end_ptrEv0
_ZN4PLMD3gch6detail17small_vector_baseISaINS_13VectorGenericILj3EEEELj6EE27throw_allocation_size_errorEv0
_ZN4PLMD3gch6detail17small_vector_baseISaINS_13VectorGenericILj3EEEELj6EE29emplace_into_reallocation_endIJS4_EEEPS4_DpOT_0
_ZN4PLMD3gch6detail17small_vector_baseISaIPKSt6vectorINS_10AtomNumberESaIS4_EEELj32EE18allocation_end_ptrEv0
_ZN4PLMD3gch6detail17small_vector_baseISaIPKSt6vectorINS_10AtomNumberESaIS4_EEELj32EE27throw_allocation_size_errorEv0
_ZN4PLMD3gch6detail17small_vector_baseISaIPKSt6vectorINS_10AtomNumberESaIS4_EEELj32EE29emplace_into_reallocation_endIJS8_EEEPS8_DpOT_0
_ZN4PLMD3gch6detail17small_vector_baseISaISt17basic_string_viewIcSt11char_traitsIcEEELj2EE27throw_allocation_size_errorEv0
_ZN4PLMD3gch6detail17small_vector_baseISaIZNS_16mergeVectorToolsL18mergeSortedVectorsISt6vectorINS_10AtomNumberESaIS6_EEEEvPKPKT_mRS5_INS9_10value_typeESaISE_EEE5EntryELj32EE27throw_allocation_size_errorEv0
_ZN4PLMD3gch6detail17small_vector_baseISaImELj16EE16checked_allocateEm0
_ZN4PLMD3gch6detail17small_vector_baseISaImELj16EE27throw_allocation_size_errorEv0
_ZN4PLMD3gch6detail19allocator_interfaceISaINS_13VectorGenericILj3EEEEE18uninitialized_copyIPS4_Lb1EEES8_T_S9_S8_0
_ZNK4PLMD3gch6detail17small_vector_baseISaINS_13VectorGenericILj3EEEELj6EE18allocation_end_ptrEv0
_ZN4PLMD3gch6detail17small_vector_baseISaISt17basic_string_viewIcSt11char_traitsIcEEELj2EE18allocation_end_ptrEv172
_ZN4PLMD3gch6detail17small_vector_baseISaISt17basic_string_viewIcSt11char_traitsIcEEELj2EE29emplace_into_reallocation_endIJRPKcRmEEEPS6_DpOT_172
_ZN4PLMD3gch6detail19allocator_interfaceISaISt17basic_string_viewIcSt11char_traitsIcEEEE18uninitialized_copyIPS6_Lb1EEESA_T_SB_SA_172
_ZN4PLMD3gch6detail17small_vector_baseISaIZNS_16mergeVectorToolsL18mergeSortedVectorsISt6vectorINS_10AtomNumberESaIS6_EEEEvPKPKT_mRS5_INS9_10value_typeESaISE_EEE5EntryELj32EE18allocation_end_ptrEv1141
_ZN4PLMD3gch6detail17small_vector_baseISaIZNS_16mergeVectorToolsL18mergeSortedVectorsISt6vectorINS_10AtomNumberESaIS6_EEEEvPKPKT_mRS5_INS9_10value_typeESaISE_EEE5EntryELj32EE29emplace_into_reallocation_endIJSI_EEEPSI_DpOT_1141
_ZN4PLMD3gch6detail19allocator_interfaceISaIZNS_16mergeVectorToolsL18mergeSortedVectorsISt6vectorINS_10AtomNumberESaIS6_EEEEvPKPKT_mRS5_INS9_10value_typeESaISE_EEE5EntryEE18uninitialized_copyIPSI_Lb1EEESM_S9_S9_SM_1141
_ZN4PLMD3gch6detail19allocator_interfaceISaIPKSt6vectorINS_10AtomNumberESaIS4_EEEE18uninitialized_copyIPS8_Lb1EEESC_T_SD_SC_2344
_ZNK4PLMD3gch6detail17small_vector_baseISaIPKSt6vectorINS_10AtomNumberESaIS4_EEELj32EE30checked_calculate_new_capacityEm2344
_ZN4PLMD3gch6detail17small_vector_baseISaImELj16EE4wipeEv3711
_ZN4PLMD3gch6detail17small_vector_baseISaImELj16EE7end_ptrEv3711
_ZN4PLMD3gch6detail17small_vector_baseISaImELj16EEC2EmRKS3_3711
_ZN4PLMD3gch6detail19allocator_interfaceISaINS_13VectorGenericILj3EEEEE18uninitialized_copyIPKS4_Lb1EEEPS4_T_SB_SA_20256
_ZN4PLMD3gch6detail17small_vector_baseISaIZNS_16mergeVectorToolsL18mergeSortedVectorsISt6vectorINS_10AtomNumberESaIS6_EEEEvPKPKT_mRS5_INS9_10value_typeESaISE_EEE5EntryELj32EE4wipeEv47710
_ZN4PLMD3gch6detail17small_vector_baseISaIPKSt6vectorINS_10AtomNumberESaIS4_EEELj32EE16request_capacityEm49613
_ZN4PLMD3gch6detail17small_vector_baseISaIPKSt6vectorINS_10AtomNumberESaIS4_EEELj32EE4wipeEv51957
_ZN4PLMD3gch6detail17small_vector_baseISaIZNS_16mergeVectorToolsL18mergeSortedVectorsISt6vectorINS_10AtomNumberESaIS6_EEEEvPKPKT_mRS5_INS9_10value_typeESaISE_EEE5EntryELj32EE24emplace_into_current_endIJSI_EEEPSI_DpOT_134064
_ZN4PLMD3gch6detail17small_vector_baseISaIZNS_16mergeVectorToolsL18mergeSortedVectorsISt6vectorINS_10AtomNumberESaIS6_EEEEvPKPKT_mRS5_INS9_10value_typeESaISE_EEE5EntryELj32EE14append_elementIJSI_EEEPSI_DpOT_135205
_ZN4PLMD3gch6detail17small_vector_baseISaIPKSt6vectorINS_10AtomNumberESaIS4_EEELj32EE14append_elementIJS8_EEEPS8_DpOT_139953
_ZN4PLMD3gch6detail17small_vector_baseISaIPKSt6vectorINS_10AtomNumberESaIS4_EEELj32EE24emplace_into_current_endIJS8_EEEPS8_DpOT_139953
_ZN4PLMD3gch6detail17small_vector_baseISaINS_13VectorGenericILj3EEEELj6EE4wipeEv160968
_ZN4PLMD3gch6detail17small_vector_baseISaIPKSt6vectorINS_10AtomNumberESaIS4_EEELj32EE7end_ptrEv334207
_ZN4PLMD3gch6detail17small_vector_baseISaINS_13VectorGenericILj3EEEELj6EE14append_elementIJS4_EEEPS4_DpOT_475288
_ZN4PLMD3gch6detail17small_vector_baseISaINS_13VectorGenericILj3EEEELj6EE24emplace_into_current_endIJS4_EEEPS4_DpOT_475288
_ZN4PLMD3gch6detail17small_vector_baseISaISt17basic_string_viewIcSt11char_traitsIcEEELj2EE4wipeEv1343354
_ZN4PLMD3gch6detail17small_vector_baseISaISt17basic_string_viewIcSt11char_traitsIcEEELj2EE24emplace_into_current_endIJRPKcRmEEEPS6_DpOT_1383994
_ZN4PLMD3gch6detail17small_vector_baseISaISt17basic_string_viewIcSt11char_traitsIcEEELj2EE14append_elementIJRPKcRmEEEPS6_DpOT_1384166
_ZN4PLMD3gch6detail17small_vector_baseISaINS_13VectorGenericILj3EEEELj6EE19copy_assign_defaultILj6EEERS6_RKNS2_IS5_XT_EEE4192048
_ZNK4PLMD3gch6detail17small_vector_baseISaINS_13VectorGenericILj3EEEELj6EE7end_ptrEv4192048
_ZN4PLMD3gch6detail17small_vector_baseISaIZNS_16mergeVectorToolsL18mergeSortedVectorsISt6vectorINS_10AtomNumberESaIS6_EEEEvPKPKT_mRS5_INS9_10value_typeESaISE_EEE5EntryELj32EE7end_ptrEv5316298
_ZN4PLMD3gch6detail17small_vector_baseISaISt17basic_string_viewIcSt11char_traitsIcEEELj2EE7end_ptrEv5454696
_ZN4PLMD3gch6detail17small_vector_baseISaINS_13VectorGenericILj3EEEELj6EE7end_ptrEv5463408
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/small_vector/small_vector.h.func.html b/coverage/small_vector/small_vector.h.func.html new file mode 100644 index 000000000000..4cc5f652307d --- /dev/null +++ b/coverage/small_vector/small_vector.h.func.html @@ -0,0 +1,245 @@ + + + + + + + + LCOV - plumed test coverage - small_vector/small_vector.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - small_vector - small_vector.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:9110586.7 %
Date:2024-04-19 12:12:35Functions:314372.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3gch6detail17small_vector_baseISaINS_13VectorGenericILj3EEEELj6EE14append_elementIJS4_EEEPS4_DpOT_475288
_ZN4PLMD3gch6detail17small_vector_baseISaINS_13VectorGenericILj3EEEELj6EE18allocation_end_ptrEv0
_ZN4PLMD3gch6detail17small_vector_baseISaINS_13VectorGenericILj3EEEELj6EE19copy_assign_defaultILj6EEERS6_RKNS2_IS5_XT_EEE4192048
_ZN4PLMD3gch6detail17small_vector_baseISaINS_13VectorGenericILj3EEEELj6EE24emplace_into_current_endIJS4_EEEPS4_DpOT_475288
_ZN4PLMD3gch6detail17small_vector_baseISaINS_13VectorGenericILj3EEEELj6EE27throw_allocation_size_errorEv0
_ZN4PLMD3gch6detail17small_vector_baseISaINS_13VectorGenericILj3EEEELj6EE29emplace_into_reallocation_endIJS4_EEEPS4_DpOT_0
_ZN4PLMD3gch6detail17small_vector_baseISaINS_13VectorGenericILj3EEEELj6EE4wipeEv160968
_ZN4PLMD3gch6detail17small_vector_baseISaINS_13VectorGenericILj3EEEELj6EE7end_ptrEv5463408
_ZN4PLMD3gch6detail17small_vector_baseISaIPKSt6vectorINS_10AtomNumberESaIS4_EEELj32EE14append_elementIJS8_EEEPS8_DpOT_139953
_ZN4PLMD3gch6detail17small_vector_baseISaIPKSt6vectorINS_10AtomNumberESaIS4_EEELj32EE16request_capacityEm49613
_ZN4PLMD3gch6detail17small_vector_baseISaIPKSt6vectorINS_10AtomNumberESaIS4_EEELj32EE18allocation_end_ptrEv0
_ZN4PLMD3gch6detail17small_vector_baseISaIPKSt6vectorINS_10AtomNumberESaIS4_EEELj32EE24emplace_into_current_endIJS8_EEEPS8_DpOT_139953
_ZN4PLMD3gch6detail17small_vector_baseISaIPKSt6vectorINS_10AtomNumberESaIS4_EEELj32EE27throw_allocation_size_errorEv0
_ZN4PLMD3gch6detail17small_vector_baseISaIPKSt6vectorINS_10AtomNumberESaIS4_EEELj32EE29emplace_into_reallocation_endIJS8_EEEPS8_DpOT_0
_ZN4PLMD3gch6detail17small_vector_baseISaIPKSt6vectorINS_10AtomNumberESaIS4_EEELj32EE4wipeEv51957
_ZN4PLMD3gch6detail17small_vector_baseISaIPKSt6vectorINS_10AtomNumberESaIS4_EEELj32EE7end_ptrEv334207
_ZN4PLMD3gch6detail17small_vector_baseISaISt17basic_string_viewIcSt11char_traitsIcEEELj2EE14append_elementIJRPKcRmEEEPS6_DpOT_1384166
_ZN4PLMD3gch6detail17small_vector_baseISaISt17basic_string_viewIcSt11char_traitsIcEEELj2EE18allocation_end_ptrEv172
_ZN4PLMD3gch6detail17small_vector_baseISaISt17basic_string_viewIcSt11char_traitsIcEEELj2EE24emplace_into_current_endIJRPKcRmEEEPS6_DpOT_1383994
_ZN4PLMD3gch6detail17small_vector_baseISaISt17basic_string_viewIcSt11char_traitsIcEEELj2EE27throw_allocation_size_errorEv0
_ZN4PLMD3gch6detail17small_vector_baseISaISt17basic_string_viewIcSt11char_traitsIcEEELj2EE29emplace_into_reallocation_endIJRPKcRmEEEPS6_DpOT_172
_ZN4PLMD3gch6detail17small_vector_baseISaISt17basic_string_viewIcSt11char_traitsIcEEELj2EE4wipeEv1343354
_ZN4PLMD3gch6detail17small_vector_baseISaISt17basic_string_viewIcSt11char_traitsIcEEELj2EE7end_ptrEv5454696
_ZN4PLMD3gch6detail17small_vector_baseISaIZNS_16mergeVectorToolsL18mergeSortedVectorsISt6vectorINS_10AtomNumberESaIS6_EEEEvPKPKT_mRS5_INS9_10value_typeESaISE_EEE5EntryELj32EE14append_elementIJSI_EEEPSI_DpOT_135205
_ZN4PLMD3gch6detail17small_vector_baseISaIZNS_16mergeVectorToolsL18mergeSortedVectorsISt6vectorINS_10AtomNumberESaIS6_EEEEvPKPKT_mRS5_INS9_10value_typeESaISE_EEE5EntryELj32EE18allocation_end_ptrEv1141
_ZN4PLMD3gch6detail17small_vector_baseISaIZNS_16mergeVectorToolsL18mergeSortedVectorsISt6vectorINS_10AtomNumberESaIS6_EEEEvPKPKT_mRS5_INS9_10value_typeESaISE_EEE5EntryELj32EE24emplace_into_current_endIJSI_EEEPSI_DpOT_134064
_ZN4PLMD3gch6detail17small_vector_baseISaIZNS_16mergeVectorToolsL18mergeSortedVectorsISt6vectorINS_10AtomNumberESaIS6_EEEEvPKPKT_mRS5_INS9_10value_typeESaISE_EEE5EntryELj32EE27throw_allocation_size_errorEv0
_ZN4PLMD3gch6detail17small_vector_baseISaIZNS_16mergeVectorToolsL18mergeSortedVectorsISt6vectorINS_10AtomNumberESaIS6_EEEEvPKPKT_mRS5_INS9_10value_typeESaISE_EEE5EntryELj32EE29emplace_into_reallocation_endIJSI_EEEPSI_DpOT_1141
_ZN4PLMD3gch6detail17small_vector_baseISaIZNS_16mergeVectorToolsL18mergeSortedVectorsISt6vectorINS_10AtomNumberESaIS6_EEEEvPKPKT_mRS5_INS9_10value_typeESaISE_EEE5EntryELj32EE4wipeEv47710
_ZN4PLMD3gch6detail17small_vector_baseISaIZNS_16mergeVectorToolsL18mergeSortedVectorsISt6vectorINS_10AtomNumberESaIS6_EEEEvPKPKT_mRS5_INS9_10value_typeESaISE_EEE5EntryELj32EE7end_ptrEv5316298
_ZN4PLMD3gch6detail17small_vector_baseISaImELj16EE16checked_allocateEm0
_ZN4PLMD3gch6detail17small_vector_baseISaImELj16EE27throw_allocation_size_errorEv0
_ZN4PLMD3gch6detail17small_vector_baseISaImELj16EE4wipeEv3711
_ZN4PLMD3gch6detail17small_vector_baseISaImELj16EE7end_ptrEv3711
_ZN4PLMD3gch6detail17small_vector_baseISaImELj16EEC2EmRKS3_3711
_ZN4PLMD3gch6detail19allocator_interfaceISaINS_13VectorGenericILj3EEEEE18uninitialized_copyIPKS4_Lb1EEEPS4_T_SB_SA_20256
_ZN4PLMD3gch6detail19allocator_interfaceISaINS_13VectorGenericILj3EEEEE18uninitialized_copyIPS4_Lb1EEES8_T_S9_S8_0
_ZN4PLMD3gch6detail19allocator_interfaceISaIPKSt6vectorINS_10AtomNumberESaIS4_EEEE18uninitialized_copyIPS8_Lb1EEESC_T_SD_SC_2344
_ZN4PLMD3gch6detail19allocator_interfaceISaISt17basic_string_viewIcSt11char_traitsIcEEEE18uninitialized_copyIPS6_Lb1EEESA_T_SB_SA_172
_ZN4PLMD3gch6detail19allocator_interfaceISaIZNS_16mergeVectorToolsL18mergeSortedVectorsISt6vectorINS_10AtomNumberESaIS6_EEEEvPKPKT_mRS5_INS9_10value_typeESaISE_EEE5EntryEE18uninitialized_copyIPSI_Lb1EEESM_S9_S9_SM_1141
_ZNK4PLMD3gch6detail17small_vector_baseISaINS_13VectorGenericILj3EEEELj6EE18allocation_end_ptrEv0
_ZNK4PLMD3gch6detail17small_vector_baseISaINS_13VectorGenericILj3EEEELj6EE7end_ptrEv4192048
_ZNK4PLMD3gch6detail17small_vector_baseISaIPKSt6vectorINS_10AtomNumberESaIS4_EEELj32EE30checked_calculate_new_capacityEm2344
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/small_vector/small_vector.h.gcov.html b/coverage/small_vector/small_vector.h.gcov.html new file mode 100644 index 000000000000..9e13a7d47154 --- /dev/null +++ b/coverage/small_vector/small_vector.h.gcov.html @@ -0,0 +1,6560 @@ + + + + + + + + LCOV - plumed test coverage - small_vector/small_vector.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - small_vector - small_vector.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:9110586.7 %
Date:2024-04-19 12:12:35Functions:314372.1 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :  * An implementation of `small_vector` (a vector with a small
+       3             :  * buffer optimization). I would probably have preferred to
+       4             :  * call this `inline_vector`, but I'll just go with the canonical
+       5             :  * name for now.
+       6             :  *
+       7             :  * Copyright © 2020-2021 Gene Harvey
+       8             :  *
+       9             :  * This software may be modified and distributed under the terms
+      10             :  * of the MIT license. See the LICENSE file for details.
+      11             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      12             : #ifndef __PLUMED_small_vector_small_vector_h
+      13             : #define __PLUMED_small_vector_small_vector_h
+      14             : /** small_vector.hpp
+      15             :  * An implementation of `small_vector` (a vector with a small
+      16             :  * buffer optimization). I would probably have preferred to
+      17             :  * call this `inline_vector`, but I'll just go with the canonical
+      18             :  * name for now.
+      19             :  *
+      20             :  * Copyright © 2020-2021 Gene Harvey
+      21             :  *
+      22             :  * This software may be modified and distributed under the terms
+      23             :  * of the MIT license. See the LICENSE file for details.
+      24             :  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+      25             : 
+      26             : #ifndef PLUMED_GCH_SMALL_VECTOR_HPP
+      27             : #define PLUMED_GCH_SMALL_VECTOR_HPP
+      28             : 
+      29             : #ifdef __clang__
+      30             : #  ifndef PLUMED_GCH_CLANG
+      31             : #    define PLUMED_GCH_CLANG
+      32             : #  endif
+      33             : #  if defined (__cplusplus) && __cplusplus >= 201103L
+      34             : #    ifndef PLUMED_GCH_CLANG_11
+      35             : #      define PLUMED_GCH_CLANG_11
+      36             : #    endif
+      37             : #  endif
+      38             : #  if defined (__cplusplus) && __cplusplus >= 201402L
+      39             : #    ifndef PLUMED_GCH_CLANG_14
+      40             : #      define PLUMED_GCH_CLANG_14
+      41             : #    endif
+      42             : #  endif
+      43             : #  if defined (__cplusplus) && __cplusplus >= 201703L
+      44             : #    ifndef PLUMED_GCH_CLANG_17
+      45             : #      define PLUMED_GCH_CLANG_17
+      46             : #    endif
+      47             : #  endif
+      48             : #  if defined (__cplusplus) && __cplusplus >= 202002L
+      49             : #    ifndef PLUMED_GCH_CLANG_20
+      50             : #      define PLUMED_GCH_CLANG_20
+      51             : #    endif
+      52             : #  endif
+      53             : #endif
+      54             : 
+      55             : #ifndef PLUMED_GCH_CPP14_CONSTEXPR
+      56             : #  if defined (__cpp_constexpr) && __cpp_constexpr >= 201304L
+      57             : #    define PLUMED_GCH_CPP14_CONSTEXPR constexpr
+      58             : #    ifndef PLUMED_GCH_HAS_CPP14_CONSTEXPR
+      59             : #      define PLUMED_GCH_HAS_CPP14_CONSTEXPR
+      60             : #    endif
+      61             : #  else
+      62             : #    define PLUMED_GCH_CPP14_CONSTEXPR
+      63             : #  endif
+      64             : #endif
+      65             : 
+      66             : #ifndef PLUMED_GCH_CPP17_CONSTEXPR
+      67             : #  if defined (__cpp_constexpr) && __cpp_constexpr >= 201603L
+      68             : #    define PLUMED_GCH_CPP17_CONSTEXPR constexpr
+      69             : #    ifndef PLUMED_GCH_HAS_CPP17_CONSTEXPR
+      70             : #      define PLUMED_GCH_HAS_CPP17_CONSTEXPR
+      71             : #    endif
+      72             : #  else
+      73             : #    define PLUMED_GCH_CPP17_CONSTEXPR
+      74             : #  endif
+      75             : #endif
+      76             : 
+      77             : #ifndef PLUMED_GCH_CPP20_CONSTEXPR
+      78             : #  if defined (__cpp_constexpr) && __cpp_constexpr >= 201907L
+      79             : #    define PLUMED_GCH_CPP20_CONSTEXPR constexpr
+      80             : #    ifndef PLUMED_GCH_HAS_CPP20_CONSTEXPR
+      81             : #      define PLUMED_GCH_HAS_CPP20_CONSTEXPR
+      82             : #    endif
+      83             : #  else
+      84             : #    define PLUMED_GCH_CPP20_CONSTEXPR
+      85             : #  endif
+      86             : #endif
+      87             : 
+      88             : #ifndef PLUMED_GCH_NORETURN
+      89             : #  if defined (__has_cpp_attribute) && __has_cpp_attribute (noreturn) >= 200809L
+      90             : #    define PLUMED_GCH_NORETURN [[noreturn]]
+      91             : #  else
+      92             : #    define PLUMED_GCH_NORETURN
+      93             : #  endif
+      94             : #endif
+      95             : 
+      96             : #ifndef PLUMED_GCH_NODISCARD
+      97             : #  if defined (__has_cpp_attribute) && __has_cpp_attribute (nodiscard) >= 201603L
+      98             : #    if ! defined (__clang__) || defined (PLUMED_GCH_CLANG_17)
+      99             : #      define PLUMED_GCH_NODISCARD [[nodiscard]]
+     100             : #    else
+     101             : #      define PLUMED_GCH_NODISCARD
+     102             : #    endif
+     103             : #  else
+     104             : #    define PLUMED_GCH_NODISCARD
+     105             : #  endif
+     106             : #endif
+     107             : 
+     108             : #ifndef PLUMED_GCH_INLINE_VARIABLE
+     109             : #  if defined (__cpp_inline_variables) && __cpp_inline_variables >= 201606L
+     110             : #    define PLUMED_GCH_INLINE_VARIABLE inline
+     111             : #  else
+     112             : #    define PLUMED_GCH_INLINE_VARIABLE
+     113             : #  endif
+     114             : #endif
+     115             : 
+     116             : #ifndef PLUMED_GCH_EMPTY_BASE
+     117             : #  if defined (_MSC_FULL_VER) && _MSC_FULL_VER >= 190023918L
+     118             : #    define PLUMED_GCH_EMPTY_BASE __declspec (empty_bases)
+     119             : #  else
+     120             : #    define PLUMED_GCH_EMPTY_BASE
+     121             : #  endif
+     122             : #endif
+     123             : 
+     124             : #ifndef PLUMED_GCH_IMPLICIT_CONVERSION
+     125             : #  if defined (__cpp_conditional_explicit) && __cpp_conditional_explicit >= 201806L
+     126             : #    define PLUMED_GCH_IMPLICIT_CONVERSION explicit (false)
+     127             : #  else
+     128             : #    define PLUMED_GCH_IMPLICIT_CONVERSION /* implicit */
+     129             : #  endif
+     130             : #endif
+     131             : 
+     132             : #if defined (__cpp_variable_templates) && __cpp_variable_templates >= 201304L
+     133             : #  ifndef PLUMED_GCH_VARIABLE_TEMPLATES
+     134             : #    define PLUMED_GCH_VARIABLE_TEMPLATES
+     135             : #  endif
+     136             : #endif
+     137             : 
+     138             : #if defined (__cpp_deduction_guides) && __cpp_deduction_guides >= 201703L
+     139             : #  ifndef PLUMED_GCH_CTAD_SUPPORT
+     140             : #    define PLUMED_GCH_CTAD_SUPPORT
+     141             : #  endif
+     142             : #endif
+     143             : 
+     144             : #if defined (__cpp_if_constexpr) && __cpp_if_constexpr >= 201606L
+     145             : #  ifndef PLUMED_GCH_CONSTEXPR_IF
+     146             : #    define PLUMED_GCH_CONSTEXPR_IF
+     147             : #  endif
+     148             : #endif
+     149             : 
+     150             : #if defined (__cpp_exceptions) && __cpp_exceptions >= 199711L
+     151             : #  ifndef PLUMED_GCH_EXCEPTIONS
+     152             : #    define PLUMED_GCH_EXCEPTIONS
+     153             : #  endif
+     154             : #endif
+     155             : 
+     156             : #ifndef PLUMED_GCH_TRY
+     157             : #  ifdef PLUMED_GCH_EXCEPTIONS
+     158             : #    define PLUMED_GCH_TRY try
+     159             : #  else
+     160             : #    ifdef PLUMED_GCH_CONSTEXPR_IF
+     161             : #      define PLUMED_GCH_TRY if constexpr (true)
+     162             : #    else
+     163             : #      define PLUMED_GCH_TRY if (true)
+     164             : #    endif
+     165             : #  endif
+     166             : #endif
+     167             : 
+     168             : #ifndef PLUMED_GCH_CATCH
+     169             : #  ifdef PLUMED_GCH_EXCEPTIONS
+     170             : #    define PLUMED_GCH_CATCH(...) catch (__VA_ARGS__)
+     171             : #  else
+     172             : #    ifdef PLUMED_GCH_CONSTEXPR_IF
+     173             : #      define PLUMED_GCH_CATCH(...) else if constexpr (false)
+     174             : #    else
+     175             : #      define PLUMED_GCH_CATCH(...) else if (false)
+     176             : #    endif
+     177             : #  endif
+     178             : #endif
+     179             : 
+     180             : #ifndef PLUMED_GCH_THROW
+     181             : #  ifdef PLUMED_GCH_EXCEPTIONS
+     182             : #    define PLUMED_GCH_THROW throw
+     183             : #  else
+     184             : #    define PLUMED_GCH_THROW
+     185             : #  endif
+     186             : #endif
+     187             : 
+     188             : #ifndef PLUMED_GCH_CONSTEVAL
+     189             : #  if defined (__cpp_consteval) && __cpp_consteval >= 201811L
+     190             : #    define PLUMED_GCH_CONSTEVAL consteval
+     191             : #    ifndef PLUMED_GCH_HAS_CONSTEVAL
+     192             : #      define PLUMED_GCH_HAS_CONSTEVAL
+     193             : #    endif
+     194             : #  else
+     195             : #    define PLUMED_GCH_CONSTEVAL constexpr
+     196             : #  endif
+     197             : #endif
+     198             : 
+     199             : #if defined (__cpp_impl_three_way_comparison) && __cpp_impl_three_way_comparison >= 201907L
+     200             : #  ifndef PLUMED_GCH_IMPL_THREE_WAY_COMPARISON
+     201             : #    define PLUMED_GCH_IMPL_THREE_WAY_COMPARISON
+     202             : #  endif
+     203             : #endif
+     204             : 
+     205             : #if defined (__cpp_concepts) && __cpp_concepts >= 201907L
+     206             : #  ifndef PLUMED_GCH_CONCEPTS
+     207             : #    define PLUMED_GCH_CONCEPTS
+     208             : #  endif
+     209             : #endif
+     210             : 
+     211             : #include <algorithm>
+     212             : #include <cassert>
+     213             : #include <cstddef>
+     214             : #include <cstdint>
+     215             : #include <cstring>
+     216             : #include <initializer_list>
+     217             : #include <iterator>
+     218             : #include <limits>
+     219             : #include <memory>
+     220             : #include <new>
+     221             : #include <type_traits>
+     222             : #include <utility>
+     223             : 
+     224             : #ifdef PLUMED_GCH_IMPL_THREE_WAY_COMPARISON
+     225             : #  if defined (__has_include) && __has_include (<compare>)
+     226             : #    include <compare>
+     227             : #  endif
+     228             : #endif
+     229             : 
+     230             : #ifdef PLUMED_GCH_CONCEPTS
+     231             : #  if defined (__has_include) && __has_include (<concepts>)
+     232             : #    include <concepts>
+     233             : #  endif
+     234             : #endif
+     235             : 
+     236             : #ifdef PLUMED_GCH_STDLIB_INTEROP
+     237             : #  include <array>
+     238             : #  include <valarray>
+     239             : #  include <vector>
+     240             : #endif
+     241             : 
+     242             : #ifdef PLUMED_GCH_EXCEPTIONS
+     243             : #  include <stdexcept>
+     244             : #else
+     245             : #  include <cstdio>
+     246             : #  include <cstdlib>
+     247             : #endif
+     248             : 
+     249             : #if defined (__cpp_lib_three_way_comparison) && __cpp_lib_three_way_comparison >= 201907L
+     250             : #  ifndef PLUMED_GCH_LIB_THREE_WAY_COMPARISON
+     251             : #    define PLUMED_GCH_LIB_THREE_WAY_COMPARISON
+     252             : #  endif
+     253             : #endif
+     254             : 
+     255             : #if defined (__cpp_lib_concepts) && __cpp_lib_concepts >= 202002L
+     256             : #  if ! defined (PLUMED_GCH_LIB_CONCEPTS) && ! defined (PLUMED_GCH_DISABLE_CONCEPTS)
+     257             : #    define PLUMED_GCH_LIB_CONCEPTS
+     258             : #  endif
+     259             : #endif
+     260             : 
+     261             : #if defined (__cpp_lib_is_final) && __cpp_lib_is_final >= 201402L
+     262             : #  ifndef PLUMED_GCH_LIB_IS_FINAL
+     263             : #    define PLUMED_GCH_LIB_IS_FINAL
+     264             : #  endif
+     265             : #endif
+     266             : 
+     267             : #if defined (__cpp_lib_is_constant_evaluated) && __cpp_lib_is_constant_evaluated >= 201811L
+     268             : #  ifndef PLUMED_GCH_LIB_IS_CONSTANT_EVALUATED
+     269             : #    define PLUMED_GCH_LIB_IS_CONSTANT_EVALUATED
+     270             : #  endif
+     271             : #endif
+     272             : 
+     273             : #if defined (__cpp_lib_is_swappable) && __cpp_lib_is_swappable >= 201603L
+     274             : #  ifndef PLUMED_GCH_LIB_IS_SWAPPABLE
+     275             : #    define PLUMED_GCH_LIB_IS_SWAPPABLE
+     276             : #  endif
+     277             : #endif
+     278             : 
+     279             : #if defined (__cpp_lib_allocator_traits_is_always_equal)
+     280             : #  if __cpp_lib_allocator_traits_is_always_equal >= 201411L
+     281             : #    ifndef PLUMED_GCH_LIB_IS_ALWAYS_EQUAL
+     282             : #      define PLUMED_GCH_LIB_IS_ALWAYS_EQUAL
+     283             : #    endif
+     284             : #  endif
+     285             : #endif
+     286             : 
+     287             : #if defined (__cpp_lib_constexpr_memory) && __cpp_lib_constexpr_memory >= 201811L
+     288             : #  ifndef PLUMED_GCH_LIB_CONSTEXPR_MEMORY
+     289             : #    define PLUMED_GCH_LIB_CONSTEXPR_MEMORY
+     290             : #  endif
+     291             : #endif
+     292             : 
+     293             : // TODO:
+     294             : //   Make sure we don't need any laundering in the internal class functions.
+     295             : //   I also need some sort of test case to actually show where UB is occurring,
+     296             : //   because it's still a bit unclear to me.
+     297             : #if defined (__cpp_lib_launder) && __cpp_lib_launder >= 201606L
+     298             : #  ifndef PLUMED_GCH_LIB_LAUNDER
+     299             : #    define PLUMED_GCH_LIB_LAUNDER
+     300             : #  endif
+     301             : #endif
+     302             : 
+     303             : // defined if the entire thing is available for constexpr
+     304             : #ifndef PLUMED_GCH_SMALL_VECTOR_CONSTEXPR
+     305             : #  if defined (PLUMED_GCH_HAS_CPP20_CONSTEXPR) && defined (PLUMED_GCH_LIB_IS_CONSTANT_EVALUATED) \
+     306             :                                         && defined (PLUMED_GCH_LIB_CONSTEXPR_MEMORY)
+     307             : #    define PLUMED_GCH_SMALL_VECTOR_CONSTEXPR constexpr
+     308             : #    ifndef PLUMED_GCH_HAS_CONSTEXPR_SMALL_VECTOR
+     309             : #      define PLUMED_GCH_HAS_CONSTEXPR_SMALL_VECTOR
+     310             : #    endif
+     311             : #  else
+     312             : #    define PLUMED_GCH_SMALL_VECTOR_CONSTEXPR
+     313             : #  endif
+     314             : #endif
+     315             : 
+     316             : #ifndef PLUMED_GCH_SMALL_VECTOR_DEFAULT_SIZE
+     317             : #  define PLUMED_GCH_SMALL_VECTOR_DEFAULT_SIZE 64
+     318             : #endif
+     319             : 
+     320             : namespace PLMD {
+     321             : namespace gch
+     322             : {
+     323             : 
+     324             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+     325             : 
+     326             : namespace concepts
+     327             : {
+     328             : 
+     329             : template <typename T>
+     330             : concept Complete = requires { sizeof (T); };
+     331             : 
+     332             : // Note: this mirrors the named requirements, not the standard concepts, so we don't require
+     333             : // the destructor to be noexcept for Destructible.
+     334             : template <typename T>
+     335             : concept Destructible = std::is_destructible<T>::value;
+     336             : 
+     337             : template <typename T>
+     338             : concept TriviallyDestructible = std::is_trivially_destructible<T>::value;
+     339             : 
+     340             : template <typename T>
+     341             : concept NoThrowDestructible = std::is_nothrow_destructible<T>::value;
+     342             : 
+     343             : // Note: this mirrors the named requirements, not the standard library concepts,
+     344             : // so we don't require Destructible here.
+     345             : 
+     346             : template <typename T, typename... Args>
+     347             : concept ConstructibleFrom = std::is_constructible<T, Args...>::value;
+     348             : 
+     349             : template <typename T, typename... Args>
+     350             : concept NoThrowConstructibleFrom = std::is_nothrow_constructible<T, Args...>::value;
+     351             : 
+     352             : template <typename From, typename To>
+     353             : concept ConvertibleTo =
+     354             :   std::is_convertible<From, To>::value
+     355             :   &&  requires (typename std::add_rvalue_reference<From>::type (&f) (void))
+     356             : {
+     357             :   static_cast<To> (f ());
+     358             : };
+     359             : 
+     360             : template <typename From, typename To>
+     361             : concept NoThrowConvertibleTo =
+     362             :   std::is_nothrow_convertible<From, To>::value
+     363             :   &&  requires (typename std::add_rvalue_reference<From>::type (&f) (void) noexcept)
+     364             : {
+     365             :   { static_cast<To> (f ()) } noexcept;
+     366             : };
+     367             : 
+     368             : // Note: std::default_initializable requires std::destructible.
+     369             : template <typename T>
+     370             : concept DefaultConstructible =
+     371             :   ConstructibleFrom<T>
+     372             :   &&  requires { T { }; }
+     373             :   &&  requires { ::new (static_cast<void *> (nullptr)) T; };
+     374             : 
+     375             : template <typename T>
+     376             : concept MoveAssignable = std::assignable_from<T&, T>;
+     377             : 
+     378             : template <typename T>
+     379             : concept CopyAssignable =
+     380             :   MoveAssignable<T>
+     381             :   &&  std::assignable_from<T&, T&>
+     382             :   &&  std::assignable_from<T&, const T&>
+     383             :   &&  std::assignable_from<T&, const T>;
+     384             : 
+     385             : template <typename T>
+     386             : concept MoveConstructible = ConstructibleFrom<T, T> && ConvertibleTo<T, T>;
+     387             : 
+     388             : template <typename T>
+     389             : concept NoThrowMoveConstructible =
+     390             :   NoThrowConstructibleFrom<T, T>
+     391             :   &&  NoThrowConvertibleTo<T, T>;
+     392             : 
+     393             : template <typename T>
+     394             : concept CopyConstructible =
+     395             :   MoveConstructible<T>
+     396             :   &&  ConstructibleFrom<T,       T&> && ConvertibleTo<      T&, T>
+     397             :   &&  ConstructibleFrom<T, const T&> && ConvertibleTo<const T&, T>
+     398             :   &&  ConstructibleFrom<T, const T > && ConvertibleTo<const T, T>;
+     399             : 
+     400             : template <typename T>
+     401             : concept NoThrowCopyConstructible =
+     402             :   NoThrowMoveConstructible<T>
+     403             :   &&  NoThrowConstructibleFrom<T,       T&> && NoThrowConvertibleTo<      T&, T>
+     404             :   &&  NoThrowConstructibleFrom<T, const T&> && NoThrowConvertibleTo<const T&, T>
+     405             :   &&  NoThrowConstructibleFrom<T, const T > && NoThrowConvertibleTo<const T, T>;
+     406             : 
+     407             : template <typename T>
+     408             : concept Swappable = std::swappable<T>;
+     409             : 
+     410             : template <typename T>
+     411             : concept EqualityComparable = std::equality_comparable<T>;
+     412             : 
+     413             : // T is a type
+     414             : // X is a Container
+     415             : // A is an Allocator
+     416             : // if X::allocator_type then
+     417             : //   std::same_as<typename X::allocator_type,
+     418             : //                typename std::allocator_traits<A>::template rebind_alloc<T>>
+     419             : // otherwise
+     420             : //   no condition; we use std::allocator<T> regardless of A
+     421             : //
+     422             : // see [22.2.1].16
+     423             : template <typename T, typename X, typename A, typename ...Args>
+     424             : concept EmplaceConstructible =
+     425             :   std::same_as<typename X::value_type, T>
+     426             :   &&  (  (  requires { typename X::allocator_type; } // only perform this check if X is
+     427             :             &&  std::same_as<typename X::allocator_type, // allocator-aware
+     428             :             typename std::allocator_traits<A>::template rebind_alloc<T>>
+     429             :             &&  (  requires (A m, T *p, Args&&... args)
+     430             : {
+     431             :   m.construct (p, std::forward<Args> (args)...);
+     432             : }
+     433             : ||  requires (T *p, Args&&... args)
+     434             : {
+     435             : #if __cplusplus >= 202002L // c++20 fully featured
+     436             :   { std::construct_at (p, std::forward<Args> (args)...) } -> std::same_as<T *>;
+     437             : #else
+     438             :   ::new (std::declval<void *> ()) T (std::declval<Args> ()...);
+     439             : #endif
+     440             : }))
+     441             : ||  (! requires { typename X::allocator_type; }
+     442             :      &&  requires (T *p, Args&&... args)
+     443             : {
+     444             : #if __cplusplus >= 202002L // c++20 fully featured
+     445             :   { std::construct_at (p, std::forward<Args> (args)...) } -> std::same_as<T *>;
+     446             : #else
+     447             :   ::new (std::declval<void *> ()) T (std::declval<Args> ()...);
+     448             : #endif
+     449             : }));
+     450             : 
+     451             : template <typename T, typename X,
+     452             : typename A = typename std::conditional<requires { typename X::allocator_type; },
+     453             :          typename X::allocator_type,
+     454             :          std::allocator<T>>::type>
+     455             :          concept DefaultInsertable = EmplaceConstructible<T, X, A>;
+     456             : 
+     457             : template <typename T, typename X,
+     458             : typename A = typename std::conditional<requires { typename X::allocator_type; },
+     459             :          typename X::allocator_type,
+     460             :          std::allocator<T>>::type>
+     461             :          concept MoveInsertable = EmplaceConstructible<T, X, A, T>;
+     462             : 
+     463             : template <typename T, typename X,
+     464             : typename A = typename std::conditional<requires { typename X::allocator_type; },
+     465             :          typename X::allocator_type,
+     466             :          std::allocator<T>>::type>
+     467             :          concept CopyInsertable = MoveInsertable<T, X, A>
+     468             :                                   &&  EmplaceConstructible<T, X, A,       T&>
+     469             :                                   &&  EmplaceConstructible<T, X, A, const T&>;
+     470             : 
+     471             : // same method as with EmplaceConstructible
+     472             : template <typename T, typename X,
+     473             : typename A = typename std::conditional<requires { typename X::allocator_type; },
+     474             :          typename X::allocator_type,
+     475             :          std::allocator<T>>::type>
+     476             :          concept Erasable =
+     477             :            std::same_as<typename X::value_type, T>
+     478             :            &&  (  (  requires { typename X::allocator_type; } // if X is allocator aware
+     479             :                      &&  std::same_as<typename X::allocator_type,
+     480             :                      typename std::allocator_traits<A>::template rebind_alloc<T>>
+     481             :                   &&  (  requires (A m, T *p)
+     482             : {
+     483             :   m.destroy (p);
+     484             : }
+     485             : ||   std::is_destructible<T>::value))
+     486             : ||  (! requires { typename X::allocator_type; }
+     487             :      &&  std::is_destructible<T>::value));
+     488             : 
+     489             : template <typename T>
+     490             : concept ContextuallyConvertibleToBool = std::constructible_from<bool, T>;
+     491             : 
+     492             : template <typename T>
+     493             : concept BoolConstant = std::derived_from<T, std::true_type>
+     494             : || std::derived_from<T, std::false_type>;
+     495             : 
+     496             : template <typename T>
+     497             : concept NullablePointer =
+     498             : EqualityComparable<T>
+     499             : &&  DefaultConstructible<T>
+     500             : &&  CopyConstructible<T>
+     501             : &&  CopyAssignable<T>
+     502             : &&  Destructible<T>
+     503             : &&  ConstructibleFrom<T, std::nullptr_t>
+     504             : &&  ConvertibleTo<std::nullptr_t, T>
+     505             : &&  requires (T p, T q, std::nullptr_t np)
+     506             : {
+     507             :   T (np);
+     508             :   { p = np   } -> std::same_as<T&>;
+     509             :   { p  != q  } -> ContextuallyConvertibleToBool;
+     510             :   { p  == np } -> ContextuallyConvertibleToBool;
+     511             :   { np == p  } -> ContextuallyConvertibleToBool;
+     512             :   { p  != np } -> ContextuallyConvertibleToBool;
+     513             :   { np != p  } -> ContextuallyConvertibleToBool;
+     514             : };
+     515             : 
+     516             : static_assert (  NullablePointer<int *>);
+     517             : static_assert (! NullablePointer<int>);
+     518             : 
+     519             : template <typename A, typename T, typename U = T *>
+     520             : concept AllocatorFor =
+     521             : NoThrowCopyConstructible<A>
+     522             : &&  requires (A a,
+     523             :               typename std::allocator_traits<A>::template rebind_alloc<U> b,
+     524             :               U xp,
+     525             :               typename std::allocator_traits<A>::pointer p,
+     526             :               typename std::allocator_traits<A>::const_pointer cp,
+     527             :               typename std::allocator_traits<A>::void_pointer vp,
+     528             :               typename std::allocator_traits<A>::const_void_pointer cvp,
+     529             :               typename std::allocator_traits<A>::value_type& r,
+     530             :               typename std::allocator_traits<A>::size_type n)
+     531             : {
+     532             :   /** Inner types **/
+     533             :   // A::pointer
+     534             :   requires NullablePointer<            typename std::allocator_traits<A>::pointer>;
+     535             :   requires std::random_access_iterator<typename std::allocator_traits<A>::pointer>;
+     536             :   requires std::contiguous_iterator<   typename std::allocator_traits<A>::pointer>;
+     537             : 
+     538             :   // A::const_pointer
+     539             :   requires NullablePointer<            typename std::allocator_traits<A>::const_pointer>;
+     540             :   requires std::random_access_iterator<typename std::allocator_traits<A>::const_pointer>;
+     541             :   requires std::contiguous_iterator<   typename std::allocator_traits<A>::const_pointer>;
+     542             : 
+     543             :   requires std::convertible_to<typename std::allocator_traits<A>::pointer,
+     544             :            typename std::allocator_traits<A>::const_pointer>;
+     545             : 
+     546             :   // A::void_pointer
+     547             :   requires NullablePointer<typename std::allocator_traits<A>::void_pointer>;
+     548             : 
+     549             :   requires std::convertible_to<typename std::allocator_traits<A>::pointer,
+     550             :            typename std::allocator_traits<A>::void_pointer>;
+     551             : 
+     552             :   requires std::same_as<typename std::allocator_traits<A>::void_pointer,
+     553             :            typename std::allocator_traits<decltype (b)>::void_pointer>;
+     554             : 
+     555             :   // A::const_void_pointer
+     556             :   requires NullablePointer<typename std::allocator_traits<A>::const_void_pointer>;
+     557             : 
+     558             :   requires std::convertible_to<typename std::allocator_traits<A>::pointer,
+     559             :            typename std::allocator_traits<A>::const_void_pointer>;
+     560             : 
+     561             :   requires std::convertible_to<typename std::allocator_traits<A>::const_pointer,
+     562             :            typename std::allocator_traits<A>::const_void_pointer>;
+     563             : 
+     564             :   requires std::convertible_to<typename std::allocator_traits<A>::void_pointer,
+     565             :            typename std::allocator_traits<A>::const_void_pointer>;
+     566             : 
+     567             :   requires std::same_as<typename std::allocator_traits<A>::const_void_pointer,
+     568             :            typename std::allocator_traits<decltype (b)>::const_void_pointer>;
+     569             : 
+     570             :   // A::value_type
+     571             :   typename A::value_type;
+     572             :   requires std::same_as<typename A::value_type, T>;
+     573             :   requires std::same_as<typename A::value_type,
+     574             :            typename std::allocator_traits<A>::value_type>;
+     575             : 
+     576             :   // A::size_type
+     577             :   requires std::unsigned_integral<typename std::allocator_traits<A>::size_type>;
+     578             : 
+     579             :   // A::difference_type
+     580             :   requires std::signed_integral<typename std::allocator_traits<A>::difference_type>;
+     581             : 
+     582             :   // A::template rebind<U>::other [optional]
+     583             :   requires ! requires { typename A::template rebind<U>::other; }
+     584             :   ||  requires
+     585             :   {
+     586             :     requires std::same_as<decltype (b), typename A::template rebind<U>::other>;
+     587             :     requires std::same_as<A, typename decltype (b)::template rebind<T>::other>;
+     588             :   };
+     589             : 
+     590             :   /** Operations on pointers **/
+     591             :   { *p  } -> std::same_as<typename A::value_type&>;
+     592             :   { *cp } -> std::same_as<const typename A::value_type&>;
+     593             : 
+     594             :   // Language in the standard implies that `decltype (p)` must either
+     595             :   // be a raw pointer or implement `operator->`. There is no mention
+     596             :   // of `std::to_address` or `std::pointer_traits<Ptr>::to_address`.
+     597             :   requires std::same_as<decltype (p), typename A::value_type *>
+     598             :   ||  requires
+     599             :   {
+     600             :     { p.operator-> () } -> std::same_as<typename A::value_type *>;
+     601             :   };
+     602             : 
+     603             :   requires std::same_as<decltype (cp), const typename A::value_type *>
+     604             :   ||  requires
+     605             :   {
+     606             :     { cp.operator-> () } -> std::same_as<const typename A::value_type *>;
+     607             :   };
+     608             : 
+     609             :   { static_cast<decltype (p)> (vp)   } -> std::same_as<decltype (p)>;
+     610             :   { static_cast<decltype (cp)> (cvp) } -> std::same_as<decltype (cp)>;
+     611             : 
+     612             :   { std::pointer_traits<decltype (p)>::pointer_to (r) } -> std::same_as<decltype (p)>;
+     613             : 
+     614             :   /** Storage and lifetime operations **/
+     615             :   // a.allocate (n)
+     616             :   { a.allocate (n) } -> std::same_as<decltype (p)>;
+     617             : 
+     618             :   // a.allocate (n, cvp) [optional]
+     619             :   requires ! requires { a.allocate (n, cvp); }
+     620             :   ||  requires { { a.allocate (n, cvp) } -> std::same_as<decltype (p)>; };
+     621             : 
+     622             :   // a.deallocate (p, n)
+     623             :   { a.deallocate (p, n) } -> std::convertible_to<void>;
+     624             : 
+     625             :   // a.max_size () [optional]
+     626             :   requires ! requires { a.max_size (); }
+     627             :   ||  requires { { a.max_size () } -> std::same_as<decltype (n)>; };
+     628             : 
+     629             :   // a.construct (xp, args) [optional]
+     630             :   requires ! requires { a.construct (xp); }
+     631             :   ||  requires { { a.construct (xp) } -> std::convertible_to<void>; };
+     632             : 
+     633             :   // a.destroy (xp) [optional]
+     634             :   requires ! requires { a.destroy (xp); }
+     635             :   ||  requires { { a.destroy (xp) } -> std::convertible_to<void>; };
+     636             : 
+     637             :   /** Relationship between instances **/
+     638             :   requires NoThrowConstructibleFrom<A, decltype (b)>;
+     639             :   requires NoThrowConstructibleFrom<A, decltype (std::move (b))>;
+     640             : 
+     641             :   requires BoolConstant<typename std::allocator_traits<A>::is_always_equal>;
+     642             : 
+     643             :   /** Influence on container operations **/
+     644             :   // a.select_on_container_copy_construction () [optional]
+     645             :   requires ! requires { a.select_on_container_copy_construction (); }
+     646             :   ||  requires
+     647             :   {
+     648             :     { a.select_on_container_copy_construction () } -> std::same_as<A>;
+     649             :   };
+     650             : 
+     651             :   requires BoolConstant<
+     652             :   typename std::allocator_traits<A>::propagate_on_container_copy_assignment>;
+     653             : 
+     654             :   requires BoolConstant<
+     655             :   typename std::allocator_traits<A>::propagate_on_container_move_assignment>;
+     656             : 
+     657             :   requires BoolConstant<
+     658             :   typename std::allocator_traits<A>::propagate_on_container_swap>;
+     659             : 
+     660             :   { a == b } -> std::same_as<bool>;
+     661             :   { a != b } -> std::same_as<bool>;
+     662             : }
+     663             : &&  requires (A a1, A a2)
+     664             : {
+     665             :   { a1 == a2 } -> std::same_as<bool>;
+     666             :   { a1 != a2 } -> std::same_as<bool>;
+     667             : };
+     668             : 
+     669             : static_assert (AllocatorFor<std::allocator<int>, int>,
+     670             :                "std::allocator<int> failed to meet Allocator concept requirements.");
+     671             : 
+     672             : template <typename A>
+     673             : concept Allocator = AllocatorFor<A, typename A::value_type>;
+     674             : 
+     675             : namespace small_vector
+     676             : {
+     677             : 
+     678             : // Basically, these shut off the concepts if we have an incomplete type.
+     679             : // This namespace is only needed because of issues on Clang
+     680             : // preventing us from short-circuiting for incomplete types.
+     681             : 
+     682             : template <typename T>
+     683             : concept Destructible =
+     684             : ! concepts::Complete<T> || concepts::Destructible<T>;
+     685             : 
+     686             : template <typename T>
+     687             : concept MoveAssignable =
+     688             : ! concepts::Complete<T> || concepts::MoveAssignable<T>;
+     689             : 
+     690             : template <typename T>
+     691             : concept CopyAssignable =
+     692             : ! concepts::Complete<T> || concepts::CopyAssignable<T>;
+     693             : 
+     694             : template <typename T>
+     695             : concept MoveConstructible =
+     696             : ! concepts::Complete<T> || concepts::MoveConstructible<T>;
+     697             : 
+     698             : template <typename T>
+     699             : concept CopyConstructible =
+     700             : ! concepts::Complete<T> || concepts::CopyConstructible<T>;
+     701             : 
+     702             : template <typename T>
+     703             : concept Swappable =
+     704             : ! concepts::Complete<T> || concepts::Swappable<T>;
+     705             : 
+     706             : template <typename T, typename SmallVector, typename Alloc>
+     707             : concept DefaultInsertable =
+     708             : ! concepts::Complete<T> || concepts::DefaultInsertable<T, SmallVector, Alloc>;
+     709             : 
+     710             : template <typename T, typename SmallVector, typename Alloc>
+     711             : concept MoveInsertable =
+     712             : ! concepts::Complete<T> || concepts::MoveInsertable<T, SmallVector, Alloc>;
+     713             : 
+     714             : template <typename T, typename SmallVector, typename Alloc>
+     715             : concept CopyInsertable =
+     716             : ! concepts::Complete<T> || concepts::CopyInsertable<T, SmallVector, Alloc>;
+     717             : 
+     718             : template <typename T, typename SmallVector, typename Alloc>
+     719             : concept Erasable =
+     720             : ! concepts::Complete<T> || concepts::Erasable<T, SmallVector, Alloc>;
+     721             : 
+     722             : template <typename T, typename SmallVector, typename Alloc, typename ...Args>
+     723             : concept EmplaceConstructible =
+     724             : ! concepts::Complete<T> || concepts::EmplaceConstructible<T, SmallVector, Alloc, Args...>;
+     725             : 
+     726             : template <typename Alloc, typename T>
+     727             : concept AllocatorFor =
+     728             : ! concepts::Complete<T> || concepts::AllocatorFor<Alloc, T>;
+     729             : 
+     730             : template <typename Alloc>
+     731             : concept Allocator = AllocatorFor<Alloc, typename Alloc::value_type>;
+     732             : 
+     733             : } // namespace gch::concepts::small_vector
+     734             : 
+     735             : } // namespace gch::concepts
+     736             : 
+     737             : #endif
+     738             : 
+     739             : template <typename Allocator>
+     740             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+     741             : requires concepts::small_vector::Allocator<Allocator>
+     742             : #endif
+     743             : struct default_buffer_size;
+     744             : 
+     745             : template <typename T,
+     746             :           unsigned InlineCapacity = default_buffer_size<std::allocator<T>>::value,
+     747             :           typename Allocator      = std::allocator<T>>
+     748             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+     749             : requires concepts::small_vector::AllocatorFor<Allocator, T>
+     750             : #endif
+     751             : class small_vector;
+     752             : 
+     753             : template <typename Allocator>
+     754             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+     755             : requires concepts::small_vector::Allocator<Allocator>
+     756             : #endif
+     757             : struct default_buffer_size
+     758             : {
+     759             : private:
+     760             :   template <typename, typename Enable = void>
+     761             :   struct is_complete
+     762             : : std::false_type
+     763             :   { };
+     764             : 
+     765             :   template <typename U>
+     766             :   struct is_complete<U, decltype (static_cast<void> (sizeof (U)))>
+     767             : : std::true_type
+     768             :   { };
+     769             : 
+     770             : public:
+     771             :   using allocator_type     = Allocator;
+     772             :   using value_type         = typename std::allocator_traits<allocator_type>::value_type;
+     773             :   using empty_small_vector = small_vector<value_type, 0, allocator_type>;
+     774             : 
+     775             :   static_assert (is_complete<value_type>::value,
+     776             :                  "Calculation of a default number of elements requires that `T` be complete.");
+     777             : 
+     778             :   static constexpr
+     779             :   unsigned
+     780             :   buffer_max = 256;
+     781             : 
+     782             :   static constexpr
+     783             :   unsigned
+     784             :   ideal_total = PLUMED_GCH_SMALL_VECTOR_DEFAULT_SIZE;
+     785             : 
+     786             : #ifndef PLUMED_GCH_UNRESTRICTED_DEFAULT_BUFFER_SIZE
+     787             : 
+     788             :   // FIXME: Some compilers will not emit the error from this static_assert
+     789             :   //        while instantiating a small_vector, and attribute the mistake
+     790             :   //        to some random other function.
+     791             :   // static_assert (sizeof (value_type) <= buffer_max, "`sizeof (T)` too large");
+     792             : 
+     793             : #endif
+     794             : 
+     795             :   static constexpr
+     796             :   unsigned
+     797             :   ideal_buffer = ideal_total - sizeof (empty_small_vector);
+     798             : 
+     799             :   static_assert (sizeof (empty_small_vector) != 0,
+     800             :                  "Empty `small_vector` should not have size 0.");
+     801             : 
+     802             :   static_assert (ideal_buffer < ideal_total,
+     803             :                  "Empty `small_vector` is larger than ideal_total.");
+     804             : 
+     805             :   static constexpr
+     806             :   unsigned
+     807             :   value = (sizeof (value_type) <= ideal_buffer) ? (ideal_buffer / sizeof (value_type)) : 1;
+     808             : };
+     809             : 
+     810             : #ifdef PLUMED_GCH_VARIABLE_TEMPLATES
+     811             : 
+     812             : template <typename Allocator>
+     813             : PLUMED_GCH_INLINE_VARIABLE constexpr
+     814             : unsigned
+     815             : default_buffer_size_v = default_buffer_size<Allocator>::value;
+     816             : 
+     817             : #endif
+     818             : 
+     819             : template <typename Pointer, typename DifferenceType>
+     820             : class small_vector_iterator
+     821             : {
+     822             : public:
+     823             :   using difference_type   = DifferenceType;
+     824             :   using value_type        = typename std::iterator_traits<Pointer>::value_type;
+     825             :   using pointer           = typename std::iterator_traits<Pointer>::pointer;
+     826             :   using reference         = typename std::iterator_traits<Pointer>::reference;
+     827             :   using iterator_category = typename std::iterator_traits<Pointer>::iterator_category;
+     828             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+     829             :   using iterator_concept  = std::contiguous_iterator_tag;
+     830             : #endif
+     831             : 
+     832             : //  small_vector_iterator            (void)                             = impl;
+     833             :   small_vector_iterator            (const small_vector_iterator&)     = default;
+     834             :   small_vector_iterator            (small_vector_iterator&&) noexcept = default;
+     835             :   small_vector_iterator& operator= (const small_vector_iterator&)     = default;
+     836             :   small_vector_iterator& operator= (small_vector_iterator&&) noexcept = default;
+     837             :   ~small_vector_iterator           (void)                             = default;
+     838             : 
+     839             : #ifdef NDEBUG
+     840             :   small_vector_iterator (void) = default;
+     841             : #else
+     842             :   constexpr
+     843             :   small_vector_iterator (void) noexcept
+     844             :     : m_ptr ()
+     845             :   { }
+     846             : #endif
+     847             : 
+     848             :   constexpr explicit
+     849             :   small_vector_iterator (const Pointer& p) noexcept
+     850             :     : m_ptr (p)
+     851             :   { }
+     852             : 
+     853             :   template <typename U, typename D,
+     854             :             typename std::enable_if<std::is_convertible<U, Pointer>::value>::type * = nullptr>
+     855             :   constexpr PLUMED_GCH_IMPLICIT_CONVERSION
+     856             :   small_vector_iterator (const small_vector_iterator<U, D>& other) noexcept
+     857             :     : m_ptr (other.base ())
+     858             :   { }
+     859             : 
+     860             :   PLUMED_GCH_CPP14_CONSTEXPR
+     861             :   small_vector_iterator&
+     862             :   operator++ (void) noexcept
+     863             :   {
+     864             :     ++m_ptr;
+     865             :     return *this;
+     866             :   }
+     867             : 
+     868             :   PLUMED_GCH_CPP14_CONSTEXPR
+     869             :   small_vector_iterator
+     870             :   operator++ (int) noexcept
+     871             :   {
+     872             :     return small_vector_iterator (m_ptr++);
+     873             :   }
+     874             : 
+     875             :   PLUMED_GCH_CPP14_CONSTEXPR
+     876             :   small_vector_iterator&
+     877             :   operator-- (void) noexcept
+     878             :   {
+     879     1757960 :     --m_ptr;
+     880             :     return *this;
+     881             :   }
+     882             : 
+     883             :   PLUMED_GCH_CPP14_CONSTEXPR
+     884             :   small_vector_iterator
+     885             :   operator-- (int) noexcept
+     886             :   {
+     887             :     return small_vector_iterator (m_ptr--);
+     888             :   }
+     889             : 
+     890             :   PLUMED_GCH_CPP14_CONSTEXPR
+     891             :   small_vector_iterator&
+     892             :   operator+= (difference_type n) noexcept
+     893             :   {
+     894             :     m_ptr += n;
+     895             :     return *this;
+     896             :   }
+     897             : 
+     898             :   constexpr
+     899             :   small_vector_iterator
+     900             :   operator+ (difference_type n) const noexcept
+     901             :   {
+     902    12534005 :     return small_vector_iterator (m_ptr + n);
+     903             :   }
+     904             : 
+     905             :   PLUMED_GCH_CPP14_CONSTEXPR
+     906             :   small_vector_iterator&
+     907             :   operator-= (difference_type n) noexcept
+     908             :   {
+     909             :     m_ptr -= n;
+     910             :     return *this;
+     911             :   }
+     912             : 
+     913             :   constexpr
+     914             :   small_vector_iterator
+     915             :   operator- (difference_type n) const noexcept
+     916             :   {
+     917     2341170 :     return small_vector_iterator (m_ptr - n);
+     918             :   }
+     919             : 
+     920             :   constexpr
+     921             :   reference
+     922             :   operator* (void) const noexcept
+     923             :   {
+     924             : #ifdef PLUMED_GCH_LIB_LAUNDER
+     925             :     return launder_and_dereference (m_ptr);
+     926             : #else
+     927             :     return *m_ptr;
+     928             : #endif
+     929             :   }
+     930             : 
+     931             :   constexpr
+     932             :   pointer
+     933             :   operator-> (void) const noexcept
+     934             :   {
+     935             :     return get_pointer (m_ptr);
+     936             :   }
+     937             : 
+     938             :   constexpr
+     939             :   reference
+     940             :   operator[] (difference_type n) const noexcept
+     941             :   {
+     942             : #ifdef PLUMED_GCH_LIB_LAUNDER
+     943   142027184 :     return launder_and_dereference (m_ptr + n);
+     944             : #else
+     945             :     return m_ptr[n];
+     946             : #endif
+     947             :   }
+     948             : 
+     949             :   constexpr
+     950             :   const Pointer&
+     951             :   base (void) const noexcept
+     952             :   {
+     953             :     return m_ptr;
+     954             :   }
+     955             : 
+     956             : private:
+     957             :   template <typename Ptr = Pointer,
+     958             :             typename std::enable_if<std::is_pointer<Ptr>::value, bool>::type = true>
+     959             :   static constexpr
+     960             :   pointer
+     961             :   get_pointer (Pointer ptr) noexcept
+     962             :   {
+     963             :     return ptr;
+     964             :   }
+     965             : 
+     966             :   template <typename Ptr = Pointer,
+     967             :             typename std::enable_if<! std::is_pointer<Ptr>::value, bool>::type = false>
+     968             :   static constexpr
+     969             :   pointer
+     970             :   get_pointer (Pointer ptr) noexcept
+     971             :   {
+     972             :     // Given the requirements for Allocator, Pointer must either be a raw pointer, or
+     973             :     // have a defined operator-> which returns a raw pointer.
+     974             :     return ptr.operator-> ();
+     975             :   }
+     976             : 
+     977             : #ifdef PLUMED_GCH_LIB_LAUNDER
+     978             : 
+     979             :   template <typename Ptr = Pointer,
+     980             :             typename std::enable_if<std::is_pointer<Ptr>::value, bool>::type = true>
+     981             :   static constexpr
+     982             :   reference
+     983             :   launder_and_dereference (Pointer ptr) noexcept
+     984             :   {
+     985             :     return *std::launder (ptr);
+     986             :   }
+     987             : 
+     988             :   template <typename Ptr = Pointer,
+     989             :             typename std::enable_if<! std::is_pointer<Ptr>::value, bool>::type = false>
+     990             :   static constexpr
+     991             :   reference
+     992             :   launder_and_dereference (Pointer ptr) noexcept
+     993             :   {
+     994             :     return *ptr;
+     995             :   }
+     996             : 
+     997             : #endif
+     998             : 
+     999             :   Pointer m_ptr;
+    1000             : };
+    1001             : 
+    1002             : #ifdef PLUMED_GCH_LIB_THREE_WAY_COMPARISON
+    1003             : 
+    1004             : template <typename PointerLHS, typename DifferenceTypeLHS,
+    1005             :           typename PointerRHS, typename DifferenceTypeRHS>
+    1006             : constexpr
+    1007             : bool
+    1008             : operator== (const small_vector_iterator<PointerLHS, DifferenceTypeLHS>& lhs,
+    1009             :             const small_vector_iterator<PointerRHS, DifferenceTypeRHS>& rhs)
+    1010             : noexcept (noexcept (lhs.base () == rhs.base ()))
+    1011             : requires requires { { lhs.base () == rhs.base () } -> std::convertible_to<bool>; }
+    1012             : {
+    1013             :   return lhs.base () == rhs.base ();
+    1014             : }
+    1015             : 
+    1016             : template <typename Pointer, typename DifferenceType>
+    1017             : constexpr
+    1018             : bool
+    1019             : operator== (const small_vector_iterator<Pointer, DifferenceType>& lhs,
+    1020             :             const small_vector_iterator<Pointer, DifferenceType>& rhs)
+    1021             : noexcept (noexcept (lhs.base () == rhs.base ()))
+    1022             : requires requires { { lhs.base () == rhs.base () } -> std::convertible_to<bool>; }
+    1023             : {
+    1024             :   return lhs.base () == rhs.base ();
+    1025             : }
+    1026             : 
+    1027             : template <typename PointerLHS, typename DifferenceTypeLHS,
+    1028             :           typename PointerRHS, typename DifferenceTypeRHS>
+    1029             : requires std::three_way_comparable_with<PointerLHS, PointerRHS>
+    1030             : constexpr
+    1031             : auto
+    1032             : operator<=> (const small_vector_iterator<PointerLHS, DifferenceTypeLHS>& lhs,
+    1033             :              const small_vector_iterator<PointerRHS, DifferenceTypeRHS>& rhs)
+    1034             : noexcept (noexcept (lhs.base () <=> rhs.base ()))
+    1035             : {
+    1036             :   return lhs.base () <=> rhs.base ();
+    1037             : }
+    1038             : 
+    1039             : template <typename Pointer, typename DifferenceType>
+    1040             : requires std::three_way_comparable<Pointer>
+    1041             : constexpr
+    1042             : auto
+    1043             : operator<=> (const small_vector_iterator<Pointer, DifferenceType>& lhs,
+    1044             :              const small_vector_iterator<Pointer, DifferenceType>& rhs)
+    1045             : noexcept (noexcept (lhs.base () <=> rhs.base ()))
+    1046             : {
+    1047             :   return lhs.base () <=> rhs.base ();
+    1048             : }
+    1049             : 
+    1050             : template <typename PointerLHS, typename DifferenceTypeLHS,
+    1051             :           typename PointerRHS, typename DifferenceTypeRHS>
+    1052             : constexpr
+    1053             : auto
+    1054             : operator<=> (const small_vector_iterator<PointerLHS, DifferenceTypeLHS>& lhs,
+    1055             :              const small_vector_iterator<PointerRHS, DifferenceTypeRHS>& rhs)
+    1056             : noexcept (noexcept (lhs.base () < rhs.base ()) && noexcept (rhs.base () < lhs.base ()))
+    1057             : {
+    1058             :   using ordering = std::weak_ordering;
+    1059             :   return (lhs.base () < rhs.base ()) ? ordering::less
+    1060             :          : (rhs.base () < lhs.base ()) ? ordering::greater
+    1061             :          : ordering::equivalent;
+    1062             : }
+    1063             : 
+    1064             : template <typename Pointer, typename DifferenceType>
+    1065             : constexpr
+    1066             : auto
+    1067             : operator<=> (const small_vector_iterator<Pointer, DifferenceType>& lhs,
+    1068             :              const small_vector_iterator<Pointer, DifferenceType>& rhs)
+    1069             : noexcept (noexcept (lhs.base () < rhs.base ()) && noexcept (rhs.base () < lhs.base ()))
+    1070             : {
+    1071             :   using ordering = std::weak_ordering;
+    1072             :   return (lhs.base () < rhs.base ()) ? ordering::less
+    1073             :          : (rhs.base () < lhs.base ()) ? ordering::greater
+    1074             :          : ordering::equivalent;
+    1075             : }
+    1076             : 
+    1077             : #else
+    1078             : 
+    1079             : // Note: Passing this on from "Gaby" in stl_iterator.h -- templated
+    1080             : //       comparisons in generic code should have overloads for both
+    1081             : //       homogenous and heterogeneous types. This is because we get
+    1082             : //       ambiguous overload resolution when std::rel_ops is visible
+    1083             : //       (ie. `using namespace std::rel_ops`).
+    1084             : 
+    1085             : template <typename PointerLHS, typename DifferenceTypeLHS,
+    1086             :           typename PointerRHS, typename DifferenceTypeRHS>
+    1087             : constexpr
+    1088             : bool
+    1089             : operator== (const small_vector_iterator<PointerLHS, DifferenceTypeLHS>& lhs,
+    1090             :             const small_vector_iterator<PointerRHS, DifferenceTypeRHS>& rhs) noexcept
+    1091             : {
+    1092             :   return lhs.base () == rhs.base ();
+    1093             : }
+    1094             : 
+    1095             : template <typename Pointer, typename DifferenceType>
+    1096             : constexpr
+    1097             : bool
+    1098             : operator== (const small_vector_iterator<Pointer, DifferenceType>& lhs,
+    1099             :             const small_vector_iterator<Pointer, DifferenceType>& rhs) noexcept
+    1100             : {
+    1101             :   return lhs.base () == rhs.base ();
+    1102             : }
+    1103             : 
+    1104             : template <typename PointerLHS, typename DifferenceTypeLHS,
+    1105             :           typename PointerRHS, typename DifferenceTypeRHS>
+    1106             : constexpr
+    1107             : bool
+    1108             : operator!= (const small_vector_iterator<PointerLHS, DifferenceTypeLHS>& lhs,
+    1109             :             const small_vector_iterator<PointerRHS, DifferenceTypeRHS>& rhs) noexcept
+    1110             : {
+    1111             :   return lhs.base () != rhs.base ();
+    1112             : }
+    1113             : 
+    1114             : template <typename Pointer, typename DifferenceType>
+    1115             : constexpr
+    1116             : bool
+    1117             : operator!= (const small_vector_iterator<Pointer, DifferenceType>& lhs,
+    1118             :             const small_vector_iterator<Pointer, DifferenceType>& rhs) noexcept
+    1119             : {
+    1120             :   return lhs.base () != rhs.base ();
+    1121             : }
+    1122             : 
+    1123             : template <typename PointerLHS, typename DifferenceTypeLHS,
+    1124             :           typename PointerRHS, typename DifferenceTypeRHS>
+    1125             : constexpr
+    1126             : bool
+    1127             : operator< (const small_vector_iterator<PointerLHS, DifferenceTypeLHS>& lhs,
+    1128             :            const small_vector_iterator<PointerRHS, DifferenceTypeRHS>& rhs) noexcept
+    1129             : {
+    1130             :   return lhs.base () < rhs.base ();
+    1131             : }
+    1132             : 
+    1133             : template <typename Pointer, typename DifferenceType>
+    1134             : constexpr
+    1135             : bool
+    1136             : operator< (const small_vector_iterator<Pointer, DifferenceType>& lhs,
+    1137             :            const small_vector_iterator<Pointer, DifferenceType>& rhs) noexcept
+    1138             : {
+    1139             :   return lhs.base () < rhs.base ();
+    1140             : }
+    1141             : 
+    1142             : template <typename PointerLHS, typename DifferenceTypeLHS,
+    1143             :           typename PointerRHS, typename DifferenceTypeRHS>
+    1144             : constexpr
+    1145             : bool
+    1146             : operator>= (const small_vector_iterator<PointerLHS, DifferenceTypeLHS>& lhs,
+    1147             :             const small_vector_iterator<PointerRHS, DifferenceTypeRHS>& rhs) noexcept
+    1148             : {
+    1149             :   return lhs.base () >= rhs.base ();
+    1150             : }
+    1151             : 
+    1152             : template <typename Pointer, typename DifferenceType>
+    1153             : constexpr
+    1154             : bool
+    1155             : operator>= (const small_vector_iterator<Pointer, DifferenceType>& lhs,
+    1156             :             const small_vector_iterator<Pointer, DifferenceType>& rhs) noexcept
+    1157             : {
+    1158             :   return lhs.base () >= rhs.base ();
+    1159             : }
+    1160             : 
+    1161             : template <typename PointerLHS, typename DifferenceTypeLHS,
+    1162             :           typename PointerRHS, typename DifferenceTypeRHS>
+    1163             : constexpr
+    1164             : bool
+    1165             : operator> (const small_vector_iterator<PointerLHS, DifferenceTypeLHS>& lhs,
+    1166             :            const small_vector_iterator<PointerRHS, DifferenceTypeRHS>& rhs) noexcept
+    1167             : {
+    1168             :   return lhs.base () > rhs.base ();
+    1169             : }
+    1170             : 
+    1171             : template <typename Pointer, typename DifferenceType>
+    1172             : constexpr
+    1173             : bool
+    1174             : operator> (const small_vector_iterator<Pointer, DifferenceType>& lhs,
+    1175             :            const small_vector_iterator<Pointer, DifferenceType>& rhs) noexcept
+    1176             : {
+    1177             :   return lhs.base () > rhs.base ();
+    1178             : }
+    1179             : 
+    1180             : template <typename PointerLHS, typename DifferenceTypeLHS,
+    1181             :           typename PointerRHS, typename DifferenceTypeRHS>
+    1182             : constexpr
+    1183             : bool
+    1184             : operator<= (const small_vector_iterator<PointerLHS, DifferenceTypeLHS>& lhs,
+    1185             :             const small_vector_iterator<PointerRHS, DifferenceTypeRHS>& rhs) noexcept
+    1186             : {
+    1187             :   return lhs.base () <= rhs.base ();
+    1188             : }
+    1189             : 
+    1190             : template <typename Pointer, typename DifferenceType>
+    1191             : constexpr
+    1192             : bool
+    1193             : operator<= (const small_vector_iterator<Pointer, DifferenceType>& lhs,
+    1194             :             const small_vector_iterator<Pointer, DifferenceType>& rhs) noexcept
+    1195             : {
+    1196             :   return lhs.base () <= rhs.base ();
+    1197             : }
+    1198             : 
+    1199             : #endif
+    1200             : 
+    1201             : template <typename PointerLHS, typename PointerRHS, typename DifferenceType>
+    1202             : constexpr
+    1203             : DifferenceType
+    1204             : operator- (const small_vector_iterator<PointerLHS, DifferenceType>& lhs,
+    1205             :            const small_vector_iterator<PointerRHS, DifferenceType>& rhs) noexcept
+    1206             : {
+    1207             :   return static_cast<DifferenceType> (lhs.base () - rhs.base ());
+    1208             : }
+    1209             : 
+    1210             : template <typename Pointer, typename DifferenceType>
+    1211             : constexpr
+    1212             : DifferenceType
+    1213             : operator- (const small_vector_iterator<Pointer, DifferenceType>& lhs,
+    1214             :            const small_vector_iterator<Pointer, DifferenceType>& rhs) noexcept
+    1215             : {
+    1216     6622074 :   return static_cast<DifferenceType> (lhs.base () - rhs.base ());
+    1217             : }
+    1218             : 
+    1219             : template <typename Pointer, typename DifferenceType>
+    1220             : constexpr
+    1221             : small_vector_iterator<Pointer, DifferenceType>
+    1222             : operator+ (DifferenceType n, const small_vector_iterator<Pointer, DifferenceType>& it) noexcept
+    1223             : {
+    1224             :   return it + n;
+    1225             : }
+    1226             : 
+    1227             : namespace detail
+    1228             : {
+    1229             : 
+    1230             : #ifndef PLUMED_GCH_LIB_IS_SWAPPABLE
+    1231             : 
+    1232             : namespace small_vector_adl
+    1233             : {
+    1234             : 
+    1235             : using std::swap;
+    1236             : 
+    1237             : template <typename T, typename Enable = void>
+    1238             : struct is_nothrow_swappable
+    1239             : : std::false_type
+    1240             : { };
+    1241             : 
+    1242             : template <typename T>
+    1243             : struct is_nothrow_swappable<T, decltype (swap (std::declval<T&> (), std::declval<T&> ()))>
+    1244             : : std::integral_constant<bool, noexcept (swap (std::declval<T&> (), std::declval<T&> ()))>
+    1245             : { };
+    1246             : 
+    1247             : }
+    1248             : 
+    1249             : #endif
+    1250             : 
+    1251             : template <typename T, unsigned InlineCapacity>
+    1252             : class inline_storage
+    1253             : {
+    1254             : public:
+    1255             :   using value_ty = T;
+    1256             : 
+    1257             :   inline_storage            (void)                      = default;
+    1258             :   inline_storage            (const inline_storage&)     = delete;
+    1259             :   inline_storage            (inline_storage&&) noexcept = delete;
+    1260             :   inline_storage& operator= (const inline_storage&)     = delete;
+    1261             :   inline_storage& operator= (inline_storage&&) noexcept = delete;
+    1262             :   ~inline_storage           (void)                      = default;
+    1263             : 
+    1264             :   PLUMED_GCH_NODISCARD PLUMED_GCH_CPP14_CONSTEXPR
+    1265             :   value_ty *
+    1266             :   get_inline_ptr (void) noexcept
+    1267             :   {
+    1268      212711 :     return static_cast<value_ty *> (static_cast<void *> (std::addressof (*m_data)));
+    1269             :   }
+    1270             : 
+    1271             :   PLUMED_GCH_NODISCARD constexpr
+    1272             :   const value_ty *
+    1273             :   get_inline_ptr (void) const noexcept
+    1274             :   {
+    1275             :     return static_cast<const value_ty *> (static_cast<const void *> (std::addressof (*m_data)));
+    1276             :   }
+    1277             : 
+    1278             :   static constexpr
+    1279             :   std::size_t
+    1280             :   element_size (void) noexcept
+    1281             :   {
+    1282             :     return sizeof (value_ty);
+    1283             :   }
+    1284             : 
+    1285             :   static constexpr
+    1286             :   std::size_t
+    1287             :   alignment (void) noexcept
+    1288             :   {
+    1289             :     return alignof (value_ty);
+    1290             :   }
+    1291             : 
+    1292             :   static constexpr
+    1293             :   unsigned
+    1294             :   num_elements (void) noexcept
+    1295             :   {
+    1296             :     return InlineCapacity;
+    1297             :   }
+    1298             : 
+    1299             :   static constexpr
+    1300             :   std::size_t
+    1301             :   num_bytes (void) noexcept
+    1302             :   {
+    1303             :     return num_elements () * element_size ();
+    1304             :   }
+    1305             : 
+    1306             : private:
+    1307             :   typename std::aligned_storage<element_size (), alignment ()>::type m_data[num_elements ()];
+    1308             : };
+    1309             : 
+    1310             : template <typename T>
+    1311             : class PLUMED_GCH_EMPTY_BASE inline_storage<T, 0>
+    1312             : {
+    1313             : public:
+    1314             :   using value_ty = T;
+    1315             : 
+    1316             :   inline_storage            (void)                      = default;
+    1317             :   inline_storage            (const inline_storage&)     = delete;
+    1318             :   inline_storage            (inline_storage&&) noexcept = delete;
+    1319             :   inline_storage& operator= (const inline_storage&)     = delete;
+    1320             :   inline_storage& operator= (inline_storage&&) noexcept = delete;
+    1321             :   ~inline_storage           (void)                      = default;
+    1322             : 
+    1323             :   PLUMED_GCH_NODISCARD PLUMED_GCH_CPP14_CONSTEXPR
+    1324             :   value_ty *
+    1325             :   get_inline_ptr (void) noexcept
+    1326             :   {
+    1327             :     return nullptr;
+    1328             :   }
+    1329             : 
+    1330             :   PLUMED_GCH_NODISCARD constexpr
+    1331             :   const value_ty *
+    1332             :   get_inline_ptr (void) const noexcept
+    1333             :   {
+    1334             :     return nullptr;
+    1335             :   }
+    1336             : 
+    1337             :   static constexpr
+    1338             :   std::size_t
+    1339             :   element_size (void) noexcept
+    1340             :   {
+    1341             :     return sizeof (value_ty);
+    1342             :   }
+    1343             : 
+    1344             :   static constexpr
+    1345             :   std::size_t
+    1346             :   alignment (void) noexcept
+    1347             :   {
+    1348             :     return alignof (value_ty);
+    1349             :   }
+    1350             : 
+    1351             :   static constexpr
+    1352             :   unsigned
+    1353             :   num_elements (void) noexcept
+    1354             :   {
+    1355             :     return 0;
+    1356             :   }
+    1357             : 
+    1358             :   static constexpr
+    1359             :   std::size_t
+    1360             :   num_bytes (void) noexcept
+    1361             :   {
+    1362             :     return 0;
+    1363             :   }
+    1364             : };
+    1365             : 
+    1366             : template <typename Allocator, bool AvailableForEBO = std::is_empty<Allocator>::value
+    1367             : #ifdef PLUMED_GCH_LIB_IS_FINAL
+    1368             :           &&! std::is_final<Allocator>::value
+    1369             : #endif // If you are using this with C++11 just don't use an allocator marked as final :P
+    1370             :           >
+    1371             : class allocator_inliner;
+    1372             : 
+    1373             : template <typename Allocator>
+    1374             : class PLUMED_GCH_EMPTY_BASE allocator_inliner<Allocator, true>
+    1375             : : private Allocator
+    1376             : {
+    1377             :   using alloc_traits = std::allocator_traits<Allocator>;
+    1378             : 
+    1379             :   static constexpr
+    1380             :   bool
+    1381             :   copy_assign_is_noop = ! alloc_traits::propagate_on_container_copy_assignment::value;
+    1382             : 
+    1383             :   static constexpr
+    1384             :   bool
+    1385             :   move_assign_is_noop = ! alloc_traits::propagate_on_container_move_assignment::value;
+    1386             : 
+    1387             :   static constexpr
+    1388             :   bool
+    1389             :   swap_is_noop = ! alloc_traits::propagate_on_container_swap::value;
+    1390             : 
+    1391             :   template <bool IsNoOp = copy_assign_is_noop,
+    1392             :             typename std::enable_if<IsNoOp, bool>::type = true>
+    1393             :   PLUMED_GCH_CPP20_CONSTEXPR
+    1394             :   void
+    1395             :   maybe_assign (const allocator_inliner&) noexcept { }
+    1396             : 
+    1397             :   template <bool IsNoOp = copy_assign_is_noop,
+    1398             :             typename std::enable_if<! IsNoOp, bool>::type = false>
+    1399             :   PLUMED_GCH_CPP20_CONSTEXPR
+    1400             :   void
+    1401             :   maybe_assign (const allocator_inliner& other)
+    1402             :   noexcept (noexcept (std::declval<Allocator&> ().operator= (other)))
+    1403             :   {
+    1404             :     Allocator::operator= (other);
+    1405             :   }
+    1406             : 
+    1407             :   template <bool IsNoOp = move_assign_is_noop,
+    1408             :             typename std::enable_if<IsNoOp, bool>::type = true>
+    1409             :   PLUMED_GCH_CPP20_CONSTEXPR
+    1410             :   void
+    1411             :   maybe_assign (allocator_inliner&&) noexcept { }
+    1412             : 
+    1413             :   template <bool IsNoOp = move_assign_is_noop,
+    1414             :             typename std::enable_if<! IsNoOp, bool>::type = false>
+    1415             :   PLUMED_GCH_CPP20_CONSTEXPR
+    1416             :   void
+    1417             :   maybe_assign (allocator_inliner&& other)
+    1418             :   noexcept (noexcept (std::declval<Allocator&> ().operator= (std::move (other))))
+    1419             :   {
+    1420             :     Allocator::operator= (std::move (other));
+    1421             :   }
+    1422             : 
+    1423             : public:
+    1424             :   allocator_inliner            (void)                         = default;
+    1425             :   allocator_inliner            (const allocator_inliner&)     = default;
+    1426             :   allocator_inliner            (allocator_inliner&&) noexcept = default;
+    1427             : //    allocator_inliner& operator= (const allocator_inliner&)     = impl;
+    1428             : //    allocator_inliner& operator= (allocator_inliner&&) noexcept = impl;
+    1429             :   ~allocator_inliner           (void)                         = default;
+    1430             : 
+    1431             :   constexpr explicit
+    1432             :   allocator_inliner (const Allocator& alloc) noexcept
+    1433             :     : Allocator (alloc)
+    1434             :   { }
+    1435             : 
+    1436             :   PLUMED_GCH_CPP20_CONSTEXPR
+    1437             :   allocator_inliner&
+    1438             :   operator= (const allocator_inliner& other)
+    1439             :   noexcept (noexcept (std::declval<allocator_inliner&> ().maybe_assign (other)))
+    1440             :   {
+    1441             :     assert (&other != this
+    1442             :             &&  "`allocator_inliner` should not participate in self-copy-assignment.");
+    1443             :     maybe_assign (other);
+    1444             :     return *this;
+    1445             :   }
+    1446             : 
+    1447             :   PLUMED_GCH_CPP20_CONSTEXPR
+    1448             :   allocator_inliner&
+    1449             :   operator= (allocator_inliner&& other)
+    1450             :   noexcept (noexcept (std::declval<allocator_inliner&> ().maybe_assign (std::move (other))))
+    1451             :   {
+    1452             :     assert (&other != this
+    1453             :             &&  "`allocator_inliner` should not participate in self-move-assignment.");
+    1454             :     maybe_assign (std::move (other));
+    1455             :     return *this;
+    1456             :   }
+    1457             : 
+    1458             :   PLUMED_GCH_CPP14_CONSTEXPR
+    1459             :   Allocator&
+    1460             :   allocator_ref (void) noexcept
+    1461             :   {
+    1462             :     return *this;
+    1463             :   }
+    1464             : 
+    1465             :   constexpr
+    1466             :   const Allocator&
+    1467             :   allocator_ref (void) const noexcept
+    1468             :   {
+    1469             :     return *this;
+    1470             :   }
+    1471             : 
+    1472             :   template <bool IsNoOp = swap_is_noop,
+    1473             :             typename std::enable_if<IsNoOp, bool>::type = true>
+    1474             :   PLUMED_GCH_CPP20_CONSTEXPR
+    1475             :   void
+    1476             :   swap (allocator_inliner&)
+    1477             :   { }
+    1478             : 
+    1479             :   template <bool IsNoOp = swap_is_noop,
+    1480             :             typename std::enable_if<! IsNoOp, bool>::type = false>
+    1481             :   PLUMED_GCH_CPP20_CONSTEXPR
+    1482             :   void
+    1483             :   swap (allocator_inliner& other)
+    1484             :   {
+    1485             :     using std::swap;
+    1486             :     swap (static_cast<Allocator&> (*this), static_cast<Allocator&> (other));
+    1487             :   }
+    1488             : };
+    1489             : 
+    1490             : template <typename Allocator>
+    1491             : class allocator_inliner<Allocator, false>
+    1492             : {
+    1493             :   using alloc_traits = std::allocator_traits<Allocator>;
+    1494             : 
+    1495             :   static constexpr
+    1496             :   bool
+    1497             :   copy_assign_is_noop = ! alloc_traits::propagate_on_container_copy_assignment::value;
+    1498             : 
+    1499             :   static constexpr
+    1500             :   bool
+    1501             :   move_assign_is_noop = ! alloc_traits::propagate_on_container_move_assignment::value;
+    1502             : 
+    1503             :   static constexpr
+    1504             :   bool
+    1505             :   swap_is_noop = ! alloc_traits::propagate_on_container_swap::value;
+    1506             : 
+    1507             :   template <bool IsNoOp = copy_assign_is_noop,
+    1508             :             typename std::enable_if<IsNoOp, bool>::type = true>
+    1509             :   PLUMED_GCH_CPP20_CONSTEXPR
+    1510             :   void
+    1511             :   maybe_assign (const allocator_inliner&) noexcept { }
+    1512             : 
+    1513             :   template <bool IsNoOp = copy_assign_is_noop,
+    1514             :             typename std::enable_if<! IsNoOp, bool>::type = false>
+    1515             :   PLUMED_GCH_CPP20_CONSTEXPR
+    1516             :   void
+    1517             :   maybe_assign (const allocator_inliner& other)
+    1518             :   noexcept (noexcept (std::declval<decltype (other.m_alloc)&> () = other.m_alloc))
+    1519             :   {
+    1520             :     m_alloc = other.m_alloc;
+    1521             :   }
+    1522             : 
+    1523             :   template <bool IsNoOp = move_assign_is_noop,
+    1524             :             typename std::enable_if<IsNoOp, bool>::type = true>
+    1525             :   PLUMED_GCH_CPP20_CONSTEXPR
+    1526             :   void
+    1527             :   maybe_assign (allocator_inliner&&) noexcept { }
+    1528             : 
+    1529             :   template <bool IsNoOp = move_assign_is_noop,
+    1530             :             typename std::enable_if<! IsNoOp, bool>::type = false>
+    1531             :   PLUMED_GCH_CPP20_CONSTEXPR
+    1532             :   void
+    1533             :   maybe_assign (allocator_inliner&& other)
+    1534             :   noexcept (noexcept (std::declval<decltype (other.m_alloc)&> () = std::move (other.m_alloc)))
+    1535             :   {
+    1536             :     m_alloc = std::move (other.m_alloc);
+    1537             :   }
+    1538             : 
+    1539             : public:
+    1540             :   allocator_inliner            (void)                         = default;
+    1541             :   allocator_inliner            (const allocator_inliner&)     = default;
+    1542             :   allocator_inliner            (allocator_inliner&&) noexcept = default;
+    1543             : //    allocator_inliner& operator= (const allocator_inliner&)     = impl;
+    1544             : //    allocator_inliner& operator= (allocator_inliner&&) noexcept = impl;
+    1545             :   ~allocator_inliner           (void)                         = default;
+    1546             : 
+    1547             :   PLUMED_GCH_CPP20_CONSTEXPR explicit
+    1548             :   allocator_inliner (const Allocator& alloc) noexcept
+    1549             :     : m_alloc (alloc)
+    1550             :   { }
+    1551             : 
+    1552             :   PLUMED_GCH_CPP20_CONSTEXPR
+    1553             :   allocator_inliner&
+    1554             :   operator= (const allocator_inliner& other)
+    1555             :   noexcept (noexcept (std::declval<allocator_inliner&> ().maybe_assign (other)))
+    1556             :   {
+    1557             :     assert (&other != this
+    1558             :             &&  "`allocator_inliner` should not participate in self-copy-assignment.");
+    1559             :     maybe_assign (other);
+    1560             :     return *this;
+    1561             :   }
+    1562             : 
+    1563             :   PLUMED_GCH_CPP20_CONSTEXPR
+    1564             :   allocator_inliner&
+    1565             :   operator= (allocator_inliner&& other)
+    1566             :   noexcept (noexcept (std::declval<allocator_inliner&> ().maybe_assign (std::move (other))))
+    1567             :   {
+    1568             :     assert (&other != this
+    1569             :             &&  "`allocator_inliner` should not participate in self-move-assignment.");
+    1570             :     maybe_assign (std::move (other));
+    1571             :     return *this;
+    1572             :   }
+    1573             : 
+    1574             :   PLUMED_GCH_CPP14_CONSTEXPR
+    1575             :   Allocator&
+    1576             :   allocator_ref (void) noexcept
+    1577             :   {
+    1578             :     return m_alloc;
+    1579             :   }
+    1580             : 
+    1581             :   constexpr
+    1582             :   const Allocator&
+    1583             :   allocator_ref (void) const noexcept
+    1584             :   {
+    1585             :     return m_alloc;
+    1586             :   }
+    1587             : 
+    1588             :   template <bool IsNoOp = swap_is_noop,
+    1589             :             typename std::enable_if<IsNoOp, bool>::type = true>
+    1590             :   PLUMED_GCH_CPP20_CONSTEXPR
+    1591             :   void
+    1592             :   swap (allocator_inliner&)
+    1593             :   { }
+    1594             : 
+    1595             :   template <bool IsNoOp = swap_is_noop,
+    1596             :             typename std::enable_if<! IsNoOp, bool>::type = false>
+    1597             :   PLUMED_GCH_CPP20_CONSTEXPR
+    1598             :   void
+    1599             :   swap (allocator_inliner& other)
+    1600             :   {
+    1601             :     using std::swap;
+    1602             :     swap (m_alloc, other.m_alloc);
+    1603             :   }
+    1604             : 
+    1605             : private:
+    1606             :   Allocator m_alloc;
+    1607             : };
+    1608             : 
+    1609             : template <typename Allocator>
+    1610             : class PLUMED_GCH_EMPTY_BASE allocator_interface
+    1611             : : public allocator_inliner<Allocator>
+    1612             : {
+    1613             : public:
+    1614             :   template <typename, typename = void>
+    1615             :   struct is_complete
+    1616             : : std::false_type
+    1617             :   { };
+    1618             : 
+    1619             :   template <typename U>
+    1620             :   struct is_complete<U, decltype (static_cast<void> (sizeof (U)))>
+    1621             : : std::true_type
+    1622             :   { };
+    1623             : 
+    1624             :   using size_type = typename std::allocator_traits<Allocator>::size_type;
+    1625             : 
+    1626             :   // If difference_type is larger than size_type then we need
+    1627             :   // to rectify that problem.
+    1628             :   using difference_type = typename std::conditional<
+    1629             :                           (
+    1630             :                             static_cast<std::size_t> ((std::numeric_limits<size_type>::max) ())
+    1631             :                             < // less-than
+    1632             :                             static_cast<std::size_t> ((std::numeric_limits<
+    1633             :                                 typename std::allocator_traits<Allocator>::difference_type>::max) ())
+    1634             :                           ),
+    1635             :                           typename std::make_signed<size_type>::type,
+    1636             :                           typename std::allocator_traits<Allocator>::difference_type>::type;
+    1637             : 
+    1638             : private:
+    1639             :   using alloc_base = allocator_inliner<Allocator>;
+    1640             : 
+    1641             : protected:
+    1642             :   using alloc_ty     = Allocator;
+    1643             :   using alloc_traits = std::allocator_traits<alloc_ty>;
+    1644             :   using value_ty     = typename alloc_traits::value_type;
+    1645             :   using ptr          = typename alloc_traits::pointer;
+    1646             :   using cptr         = typename alloc_traits::const_pointer;
+    1647             :   using vptr         = typename alloc_traits::void_pointer;
+    1648             :   using cvptr        = typename alloc_traits::const_void_pointer;
+    1649             : 
+    1650             :   // Select the fastest types larger than the user-facing types. These are only intended for
+    1651             :   // internal computations, and should not have any memory footprint visible to consumers.
+    1652             :   using size_ty =
+    1653             :     typename std::conditional<
+    1654             :     (sizeof (size_type) <= sizeof (std::uint8_t)),
+    1655             :     std::uint_fast8_t,
+    1656             :     typename std::conditional<
+    1657             :     (sizeof (size_type) <= sizeof (std::uint16_t)),
+    1658             :     std::uint_fast16_t,
+    1659             :     typename std::conditional<
+    1660             :     (sizeof (size_type) <= sizeof (std::uint32_t)),
+    1661             :     std::uint_fast32_t,
+    1662             :     typename std::conditional<
+    1663             :     (sizeof (size_type) <= sizeof (std::uint64_t)),
+    1664             :     std::uint_fast64_t,
+    1665             :     size_type
+    1666             :     >::type
+    1667             :     >::type
+    1668             :     >::type
+    1669             :     >::type;
+    1670             : 
+    1671             :   using diff_ty =
+    1672             :     typename std::conditional<
+    1673             :     (sizeof (difference_type) <= sizeof (std::int8_t)),
+    1674             :     std::int_fast8_t,
+    1675             :     typename std::conditional<
+    1676             :     (sizeof (difference_type) <= sizeof (std::int16_t)),
+    1677             :     std::int_fast16_t,
+    1678             :     typename std::conditional<
+    1679             :     (sizeof (difference_type) <= sizeof (std::int32_t)),
+    1680             :     std::int_fast32_t,
+    1681             :     typename std::conditional<
+    1682             :     (sizeof (difference_type) <= sizeof (std::int64_t)),
+    1683             :     std::int_fast64_t,
+    1684             :     difference_type
+    1685             :     >::type
+    1686             :     >::type
+    1687             :     >::type
+    1688             :     >::type;
+    1689             : 
+    1690             :   using alloc_base::allocator_ref;
+    1691             : 
+    1692             : private:
+    1693             :   template <typename ...>
+    1694             :   using void_t = void;
+    1695             : 
+    1696             :   template <bool B>
+    1697             :   using bool_constant = std::integral_constant<bool, B>;
+    1698             : 
+    1699             :   template <typename V, typename Enable = void>
+    1700             :   struct is_trivially_destructible
+    1701             : : std::false_type
+    1702             :   { };
+    1703             : 
+    1704             :   template <typename V>
+    1705             :   struct is_trivially_destructible<V, typename std::enable_if<is_complete<V>::value>::type>
+    1706             : : std::is_trivially_destructible<V>
+    1707             :   { };
+    1708             : 
+    1709             :   template <typename Void, typename T, typename ...Args>
+    1710             :   struct is_trivially_constructible_impl
+    1711             : : std::false_type
+    1712             :   { };
+    1713             : 
+    1714             :   template <typename V, typename ...Args>
+    1715             :   struct is_trivially_constructible_impl<
+    1716             :     typename std::enable_if<is_complete<V>::value>::type,
+    1717             :     V, Args...>
+    1718             : : std::is_trivially_constructible<V, Args...>
+    1719             :   { };
+    1720             : 
+    1721             :   template <typename V, typename ...Args>
+    1722             :   struct is_trivially_constructible
+    1723             : : is_trivially_constructible_impl<void, V, Args...>
+    1724             :   { };
+    1725             : 
+    1726             :   template <typename T, typename Enable = void>
+    1727             :   struct underlying_if_enum
+    1728             :   {
+    1729             :     using type = T;
+    1730             :   };
+    1731             : 
+    1732             :   template <typename T>
+    1733             :   struct underlying_if_enum<T, typename std::enable_if<std::is_enum<T>::value>::type>
+    1734             : : std::underlying_type<T>
+    1735             :   { };
+    1736             : 
+    1737             :   template <typename T>
+    1738             :   using underlying_if_enum_t = typename underlying_if_enum<T>::type;
+    1739             : 
+    1740             :   template <typename, typename = void>
+    1741             :   struct has_ptr_traits_to_address
+    1742             : : std::false_type
+    1743             :   { };
+    1744             : 
+    1745             :   template <typename P>
+    1746             :   struct has_ptr_traits_to_address<P,
+    1747             :                                    void_t<decltype (std::pointer_traits<P>::to_address (std::declval<P> ()))>>
+    1748             : : std::true_type
+    1749             :   { };
+    1750             : 
+    1751             :   template <typename Void, typename A, typename V, typename ...Args>
+    1752             :   struct has_alloc_construct_check
+    1753             : : std::false_type
+    1754             :   { };
+    1755             : 
+    1756             :   template <typename A, typename V, typename ...Args>
+    1757             :   struct has_alloc_construct_check<
+    1758             :     void_t<decltype (std::declval<A&> ().construct (std::declval<V *> (),
+    1759             :                      std::declval<Args> ()...))>,
+    1760             :     A, V, Args...>
+    1761             : : std::true_type
+    1762             :   { };
+    1763             : 
+    1764             :   template <typename Void, typename A, typename V, typename ...Args>
+    1765             :   struct has_alloc_construct_impl
+    1766             : : std::false_type
+    1767             :   { };
+    1768             : 
+    1769             :   template <typename A, typename V, typename ...Args>
+    1770             :   struct has_alloc_construct_impl<typename std::enable_if<is_complete<V>::value>::type,
+    1771             :                                   A, V, Args...>
+    1772             : : has_alloc_construct_check<void, A, V, Args...>
+    1773             :   { };
+    1774             : 
+    1775             :   template <typename A, typename V, typename ...Args>
+    1776             :   struct has_alloc_construct
+    1777             : : has_alloc_construct_impl<void, A, V, Args...>
+    1778             :   { };
+    1779             : 
+    1780             :   template <typename A, typename V, typename ...Args>
+    1781             :   struct must_use_alloc_construct
+    1782             : : bool_constant<! std::is_same<A, std::allocator<V>>::value
+    1783             :                   &&  has_alloc_construct<A, V, Args...>::value>
+    1784             :   { };
+    1785             : 
+    1786             :   template <typename Void, typename A, typename V>
+    1787             :   struct has_alloc_destroy_impl
+    1788             : : std::false_type
+    1789             :   { };
+    1790             : 
+    1791             :   template <typename A, typename V>
+    1792             :   struct has_alloc_destroy_impl<
+    1793             :     void_t<decltype (std::declval<A&> ().destroy (std::declval<V *> ()))>,
+    1794             :     A, V>
+    1795             : : std::true_type
+    1796             :   { };
+    1797             : 
+    1798             :   template <typename A, typename V, typename Enable = void>
+    1799             :   struct has_alloc_destroy
+    1800             : : std::false_type
+    1801             :   { };
+    1802             : 
+    1803             :   template <typename A, typename V>
+    1804             :   struct has_alloc_destroy<A, V, typename std::enable_if<is_complete<V>::value>::type>
+    1805             : : has_alloc_destroy_impl<void, A, V>
+    1806             :   { };
+    1807             : 
+    1808             :   template <typename A, typename V>
+    1809             :   struct must_use_alloc_destroy
+    1810             : : bool_constant<! std::is_same<A, std::allocator<V>>::value
+    1811             :                   &&  has_alloc_destroy<A, V>::value>
+    1812             :   { };
+    1813             : 
+    1814             : public:
+    1815             :   allocator_interface (void)                           = default;
+    1816             : //    allocator_interface (const allocator_interface&)     = impl;
+    1817             :   allocator_interface (allocator_interface&&) noexcept = default;
+    1818             : 
+    1819             :   PLUMED_GCH_CPP20_CONSTEXPR
+    1820             :   allocator_interface&
+    1821             :   operator= (const allocator_interface&) = default;
+    1822             : 
+    1823             :   PLUMED_GCH_CPP20_CONSTEXPR
+    1824             :   allocator_interface&
+    1825             :   operator= (allocator_interface&&) noexcept = default;
+    1826             : 
+    1827             :   ~allocator_interface (void) = default;
+    1828             : 
+    1829             :   PLUMED_GCH_CPP20_CONSTEXPR
+    1830             :   allocator_interface (const allocator_interface& other) noexcept
+    1831             :     : alloc_base (alloc_traits::select_on_container_copy_construction (other.allocator_ref ()))
+    1832             :   { }
+    1833             : 
+    1834             :   constexpr explicit
+    1835             :   allocator_interface (const alloc_ty& alloc) noexcept
+    1836             :     : alloc_base (alloc)
+    1837             :   { }
+    1838             : 
+    1839             :   template <typename T>
+    1840             :   constexpr explicit
+    1841             :   allocator_interface (T&&, const alloc_ty& alloc) noexcept
+    1842             :     : allocator_interface (alloc)
+    1843             :   { }
+    1844             : 
+    1845             :   template <typename, typename, typename = void>
+    1846             :   struct is_memcpyable_integral
+    1847             : : std::false_type
+    1848             :   { };
+    1849             : 
+    1850             :   template <typename From, typename To>
+    1851             :   struct is_memcpyable_integral<From, To,
+    1852             :                                 typename std::enable_if<is_complete<From>::value>::type>
+    1853             :   {
+    1854             :     using from = underlying_if_enum_t<From>;
+    1855             :     using to   = underlying_if_enum_t<To>;
+    1856             : 
+    1857             :     static constexpr
+    1858             :     bool
+    1859             :     value = (sizeof (from) == sizeof (to))
+    1860             :     &&  (std::is_same<bool, from>::value == std::is_same<bool, to>::value)
+    1861             :     &&  std::is_integral<from>::value
+    1862             :     &&  std::is_integral<to>::value;
+    1863             :                         };
+    1864             : 
+    1865             :   template <typename From, typename To>
+    1866             :   struct is_convertible_pointer
+    1867             : : bool_constant<std::is_pointer<From>::value
+    1868             :                   &&  std::is_pointer<To>::value
+    1869             :                   &&  std::is_convertible<From, To>::value>
+    1870             :   { };
+    1871             : 
+    1872             :   // Memcpyable assignment.
+    1873             :   template <typename QualifiedFrom, typename QualifiedTo = value_ty, typename Enable = void>
+    1874             :   struct is_memcpyable
+    1875             : : std::false_type
+    1876             :   { };
+    1877             : 
+    1878             :   template <typename QualifiedFrom, typename QualifiedTo>
+    1879             :   struct is_memcpyable<QualifiedFrom, QualifiedTo,
+    1880             :                        typename std::enable_if<is_complete<QualifiedFrom>::value>::type>
+    1881             :   {
+    1882             :     static_assert (! std::is_reference<QualifiedTo>::value,
+    1883             :                    "QualifiedTo must not be a reference.");
+    1884             : 
+    1885             :     using from = typename std::remove_reference<
+    1886             :       typename std::remove_cv<QualifiedFrom>::type>::type;
+    1887             : 
+    1888             :     using to = typename std::remove_cv<QualifiedTo>::type;
+    1889             : 
+    1890             :     static constexpr
+    1891             :     bool
+    1892             :     value = std::is_trivially_assignable<QualifiedTo&, QualifiedFrom>::value
+    1893             :     &&  std::is_trivially_copyable<to>::value
+    1894             :     &&  (  std::is_same<typename std::remove_cv<from>::type, to>::value
+    1895             :            ||  is_memcpyable_integral<from, to>::value
+    1896             :            ||  is_convertible_pointer<from, to>::value);
+    1897             :                                      };
+    1898             : 
+    1899             :   // Memcpyable construction.
+    1900             :   template <typename QualifiedFrom, typename QualifiedTo>
+    1901             :   struct is_uninitialized_memcpyable_impl
+    1902             :   {
+    1903             :     static_assert (! std::is_reference<QualifiedTo>::value,
+    1904             :                    "QualifiedTo must not be a reference.");
+    1905             : 
+    1906             :     using from = typename std::remove_reference<
+    1907             :       typename std::remove_cv<QualifiedFrom>::type>::type;
+    1908             : 
+    1909             :     using to = typename std::remove_cv<QualifiedTo>::type;
+    1910             : 
+    1911             :     static constexpr
+    1912             :     bool
+    1913             :     value = std::is_trivially_constructible<QualifiedTo, QualifiedFrom>::value
+    1914             :     &&  std::is_trivially_copyable<to>::value
+    1915             :     &&  (  std::is_same<typename std::remove_cv<from>::type, to>::value
+    1916             :            ||  is_memcpyable_integral<from, to>::value
+    1917             :            ||  is_convertible_pointer<from, to>::value)
+    1918             :     &&  (! must_use_alloc_construct<alloc_ty, value_ty, from>::value
+    1919             :          &&! must_use_alloc_destroy<alloc_ty, value_ty>::value);
+    1920             :                                    };
+    1921             : 
+    1922             :   template <typename To, typename ...Args>
+    1923             :   struct is_uninitialized_memcpyable
+    1924             : : std::false_type
+    1925             :   { };
+    1926             : 
+    1927             :   template <typename To, typename From>
+    1928             :   struct is_uninitialized_memcpyable<To, From>
+    1929             : : is_uninitialized_memcpyable_impl<From, To>
+    1930             :   { };
+    1931             : 
+    1932             :   template <typename Iterator>
+    1933             :   struct is_small_vector_iterator
+    1934             : : std::false_type
+    1935             :   { };
+    1936             : 
+    1937             :   template <typename ...Ts>
+    1938             :   struct is_small_vector_iterator<small_vector_iterator<Ts...>>
+    1939             : : std::true_type
+    1940             :   { };
+    1941             : 
+    1942             :   template <typename InputIt>
+    1943             :   struct is_contiguous_iterator
+    1944             : : bool_constant<
+    1945             :     std::is_same<InputIt, ptr>::value
+    1946             :     ||  std::is_same<InputIt, cptr>::value
+    1947             :     ||  is_small_vector_iterator<InputIt>::value
+    1948             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    1949             :     ||  std::contiguous_iterator<InputIt>
+    1950             : #endif
+    1951             : #ifdef PLUMED_GCH_STDLIB_INTEROP
+    1952             :     ||  std::is_same<InputIt, typename std::array<value_ty>::iterator>::value
+    1953             :     ||  std::is_same<InputIt, typename std::array<value_ty>::const_iterator>::value
+    1954             :     ||  (! std::is_same<value_ty, bool>
+    1955             :          &&  (  std::is_same<InputIt, typename std::vector<value_ty>::iterator>::value
+    1956             :                 ||  std::is_same<InputIt, typename std::vector<value_ty>::const_iterator>::value)
+    1957             :                                 )
+    1958             :     ||  std::is_same<InputIt,
+    1959             :                      decltype (std::begin (std::declval<std::valarray<value_ty>&> ()))>::value
+    1960             :     ||  std::is_same<InputIt,
+    1961             :                      decltype (std::begin (std::declval<const std::valarray<value_ty>&> ()))>::value
+    1962             : #endif
+    1963             :     >
+    1964             :   { };
+    1965             : 
+    1966             :   template <typename InputIt>
+    1967             :   struct is_memcpyable_iterator
+    1968             : : bool_constant<is_memcpyable<decltype (*std::declval<InputIt> ())>::value
+    1969             :                   &&  is_contiguous_iterator<InputIt>::value>
+    1970             :   { };
+    1971             : 
+    1972             :   // Unwrap `move_iterator`s.
+    1973             :   template <typename InputIt>
+    1974             :   struct is_memcpyable_iterator<std::move_iterator<InputIt>>
+    1975             : : is_memcpyable_iterator<InputIt>
+    1976             :   { };
+    1977             : 
+    1978             :   template <typename InputIt, typename V = value_ty>
+    1979             :   struct is_uninitialized_memcpyable_iterator
+    1980             : : bool_constant<is_uninitialized_memcpyable<V, decltype (*std::declval<InputIt> ())>::value
+    1981             :                   &&  is_contiguous_iterator<InputIt>::value>
+    1982             :   { };
+    1983             : 
+    1984             :   // unwrap move_iterators
+    1985             :   template <typename U, typename V>
+    1986             :   struct is_uninitialized_memcpyable_iterator<std::move_iterator<U>, V>
+    1987             : : is_uninitialized_memcpyable_iterator<U, V>
+    1988             :   { };
+    1989             : 
+    1990             :   PLUMED_GCH_NORETURN
+    1991             :   static PLUMED_GCH_CPP20_CONSTEXPR
+    1992             :   void
+    1993             :   throw_range_length_error (void)
+    1994             :   {
+    1995             : #ifdef PLUMED_GCH_EXCEPTIONS
+    1996             :     throw std::length_error ("The specified range is too long.");
+    1997             : #else
+    1998             :     std::fprintf (stderr, "[gch::small_vector] The specified range is too long.");
+    1999             :     std::abort ();
+    2000             : #endif
+    2001             :   }
+    2002             : 
+    2003             :   static constexpr
+    2004             :   value_ty *
+    2005             :   to_address (value_ty *p) noexcept
+    2006             :   {
+    2007             :     static_assert (! std::is_function<value_ty>::value, "value_ty is a function pointer.");
+    2008             :     return p;
+    2009             :   }
+    2010             : 
+    2011             :   static constexpr
+    2012             :   const value_ty *
+    2013             :   to_address (const value_ty *p) noexcept
+    2014             :   {
+    2015             :     static_assert (! std::is_function<value_ty>::value, "value_ty is a function pointer.");
+    2016             :     return p;
+    2017             :   }
+    2018             : 
+    2019             :   template <typename Pointer,
+    2020             :             typename std::enable_if<has_ptr_traits_to_address<Pointer>::value>::type * = nullptr>
+    2021             :   static constexpr
+    2022             :   auto
+    2023             :   to_address (const Pointer& p) noexcept
+    2024             :   -> decltype (std::pointer_traits<Pointer>::to_address (p))
+    2025             :   {
+    2026             :     return std::pointer_traits<Pointer>::to_address (p);
+    2027             :   }
+    2028             : 
+    2029             :   template <typename Pointer,
+    2030             :             typename std::enable_if<! has_ptr_traits_to_address<Pointer>::value>::type * = nullptr>
+    2031             :   static constexpr
+    2032             :   auto
+    2033             :   to_address (const Pointer& p) noexcept
+    2034             :   -> decltype (to_address (p.operator-> ()))
+    2035             :   {
+    2036             :     return to_address (p.operator-> ());
+    2037             :   }
+    2038             : 
+    2039             :   template <typename Integer>
+    2040             :   PLUMED_GCH_NODISCARD
+    2041             :   static PLUMED_GCH_CONSTEVAL
+    2042             :   std::size_t
+    2043             :   numeric_max (void) noexcept
+    2044             :   {
+    2045             :     static_assert (0 <= (std::numeric_limits<Integer>::max) (), "Integer is nonpositive.");
+    2046             :     return static_cast<std::size_t> ((std::numeric_limits<Integer>::max) ());
+    2047             :   }
+    2048             : 
+    2049             :   PLUMED_GCH_NODISCARD
+    2050             :   static PLUMED_GCH_CPP17_CONSTEXPR
+    2051             :   size_ty
+    2052             :   internal_range_length (cptr first, cptr last) noexcept
+    2053             :   {
+    2054             :     // This is guaranteed to be less than or equal to max size_ty.
+    2055             :     return static_cast<size_ty> (last - first);
+    2056             :   }
+    2057             : 
+    2058             :   template <typename RandomIt>
+    2059             :   PLUMED_GCH_NODISCARD
+    2060             :   static PLUMED_GCH_CPP17_CONSTEXPR
+    2061             :   size_ty
+    2062             :   external_range_length_impl (RandomIt first, RandomIt last, std::random_access_iterator_tag)
+    2063             :   {
+    2064             :     assert (0 <= (last - first) && "Invalid range.");
+    2065             :     const auto len = static_cast<std::size_t> (last - first);
+    2066             : #ifndef NDEBUG
+    2067             :     if (numeric_max<size_ty> () < len)
+    2068             :       throw_range_length_error ();
+    2069             : #endif
+    2070             :     return static_cast<size_ty> (len);
+    2071             :   }
+    2072             : 
+    2073             :   template <typename ForwardIt>
+    2074             :   PLUMED_GCH_NODISCARD
+    2075             :   static PLUMED_GCH_CPP17_CONSTEXPR
+    2076             :   size_ty
+    2077             :   external_range_length_impl (ForwardIt first, ForwardIt last, std::forward_iterator_tag)
+    2078             :   {
+    2079             : #ifdef PLUMED_GCH_LIB_IS_CONSTANT_EVALUATED
+    2080             :     if (std::is_constant_evaluated ())
+    2081             :     {
+    2082             :       // Make sure constexpr doesn't get broken by `using namespace std::rel_ops`.
+    2083             :       typename std::iterator_traits<ForwardIt>::difference_type len = 0;
+    2084             :       for (; ! (first == last); ++first)
+    2085             :         ++len;
+    2086             :       assert (static_cast<std::size_t> (len) <= numeric_max<size_ty> ());
+    2087             :       return static_cast<size_ty> (len);
+    2088             :     }
+    2089             : #endif
+    2090             : 
+    2091             :     const auto len = static_cast<std::size_t> (std::distance (first, last));
+    2092             : #ifndef NDEBUG
+    2093             :     if (numeric_max<size_ty> () < len)
+    2094             :       throw_range_length_error ();
+    2095             : #endif
+    2096             :     return static_cast<size_ty> (len);
+    2097             :   }
+    2098             : 
+    2099             :   template <typename ForwardIt,
+    2100             :             typename ItDiffT = typename std::iterator_traits<ForwardIt>::difference_type,
+    2101             :             typename std::enable_if<(numeric_max<size_ty> () < numeric_max<ItDiffT> ()),
+    2102             :                                      bool>::type = true>
+    2103             :             PLUMED_GCH_NODISCARD
+    2104             :             static PLUMED_GCH_CPP17_CONSTEXPR
+    2105             :             size_ty
+    2106             :             external_range_length (ForwardIt first, ForwardIt last)
+    2107             :   {
+    2108             :     using iterator_cat = typename std::iterator_traits<ForwardIt>::iterator_category;
+    2109             :     return external_range_length_impl (first, last, iterator_cat { });
+    2110             :   }
+    2111             : 
+    2112             :   template <typename ForwardIt,
+    2113             :             typename ItDiffT = typename std::iterator_traits<ForwardIt>::difference_type,
+    2114             :             typename std::enable_if<! (numeric_max<size_ty> () < numeric_max<ItDiffT> ()),
+    2115             :                                        bool>::type = false>
+    2116             :             PLUMED_GCH_NODISCARD
+    2117             :             static PLUMED_GCH_CPP17_CONSTEXPR
+    2118             :             size_ty
+    2119             :             external_range_length (ForwardIt first, ForwardIt last) noexcept
+    2120             :   {
+    2121             : #ifdef PLUMED_GCH_LIB_IS_CONSTANT_EVALUATED
+    2122             :     if (std::is_constant_evaluated ())
+    2123             :     {
+    2124             :       // Make sure constexpr doesn't get broken by `using namespace std::rel_ops`.
+    2125             :       size_ty len = 0;
+    2126             :       for (; ! (first == last); ++first)
+    2127             :         ++len;
+    2128             :       return len;
+    2129             :     }
+    2130             : #endif
+    2131             : 
+    2132       23913 :     return static_cast<size_ty> (std::distance (first, last));
+    2133             :   }
+    2134             : 
+    2135             :   template <typename Iterator,
+    2136             :             typename IteratorDiffT = typename std::iterator_traits<Iterator>::difference_type,
+    2137             :             typename Integer = IteratorDiffT>
+    2138             :   PLUMED_GCH_NODISCARD
+    2139             :   static PLUMED_GCH_CPP17_CONSTEXPR
+    2140             :   Iterator
+    2141             :   unchecked_next (Iterator pos, Integer n = 1) noexcept
+    2142             :   {
+    2143    20790961 :     unchecked_advance (pos, static_cast<IteratorDiffT> (n));
+    2144    20814874 :     return pos;
+    2145             :   }
+    2146             : 
+    2147             :   template <typename Iterator,
+    2148             :             typename IteratorDiffT = typename std::iterator_traits<Iterator>::difference_type,
+    2149             :             typename Integer = IteratorDiffT>
+    2150             :   PLUMED_GCH_NODISCARD
+    2151             :   static PLUMED_GCH_CPP17_CONSTEXPR
+    2152             :   Iterator
+    2153             :   unchecked_prev (Iterator pos, Integer n = 1) noexcept
+    2154             :   {
+    2155             :     unchecked_advance (pos, -static_cast<IteratorDiffT> (n));
+    2156     2133299 :     return pos;
+    2157             :   }
+    2158             : 
+    2159             :   template <typename Iterator,
+    2160             :             typename IteratorDiffT = typename std::iterator_traits<Iterator>::difference_type,
+    2161             :             typename Integer = IteratorDiffT>
+    2162             :   static PLUMED_GCH_CPP17_CONSTEXPR
+    2163             :   void
+    2164             :   unchecked_advance (Iterator& pos, Integer n) noexcept
+    2165             :   {
+    2166             :     std::advance (pos, static_cast<IteratorDiffT> (n));
+    2167             :   }
+    2168             : 
+    2169             :   PLUMED_GCH_NODISCARD PLUMED_GCH_CPP20_CONSTEXPR
+    2170             :   size_ty
+    2171             :   get_max_size (void) const noexcept
+    2172             :   {
+    2173             :     // This is protected from max/min macros.
+    2174             :     return (std::min) (static_cast<size_ty> (alloc_traits::max_size (allocator_ref ())),
+    2175             :                        static_cast<size_ty> (numeric_max<difference_type> ()));
+    2176             :   }
+    2177             : 
+    2178             :   PLUMED_GCH_NODISCARD PLUMED_GCH_CPP20_CONSTEXPR
+    2179             :   ptr
+    2180             :   allocate (size_ty n)
+    2181             :   {
+    2182             :     return alloc_traits::allocate (allocator_ref (), static_cast<size_type> (n));
+    2183             :   }
+    2184             : 
+    2185             :   PLUMED_GCH_NODISCARD PLUMED_GCH_CPP20_CONSTEXPR
+    2186             :   ptr
+    2187             :   allocate_with_hint (size_ty n, cptr hint)
+    2188             :   {
+    2189             :     return alloc_traits::allocate (allocator_ref (), static_cast<size_type> (n), hint);
+    2190             :   }
+    2191             : 
+    2192             :   PLUMED_GCH_CPP20_CONSTEXPR
+    2193             :   void
+    2194             :   deallocate (ptr p, size_ty n)
+    2195             :   {
+    2196             :     alloc_traits::deallocate (allocator_ref (), to_address (p),
+    2197             :                               static_cast<size_type> (n));
+    2198        3657 :   }
+    2199             : 
+    2200             :   template <typename U,
+    2201             :             typename std::enable_if<
+    2202             :               is_uninitialized_memcpyable<value_ty, U>::value>::type * = nullptr>
+    2203             :   PLUMED_GCH_CPP20_CONSTEXPR
+    2204             :   void
+    2205             :   construct (ptr p, U&& val) noexcept
+    2206             :   {
+    2207             : #ifdef PLUMED_GCH_LIB_IS_CONSTANT_EVALUATED
+    2208             :     if (std::is_constant_evaluated ())
+    2209             :     {
+    2210             :       alloc_traits::construct (allocator_ref (), to_address (p), std::forward<U> (val));
+    2211             :       return;
+    2212             :     }
+    2213             : #endif
+    2214             :     std::memcpy (to_address (p), &val, sizeof (value_ty));
+    2215             :   }
+    2216             : 
+    2217             :   // basically alloc_traits::construct
+    2218             :   // all this is so we can replicate C++20 behavior in the other overload
+    2219             :   template <typename A = alloc_ty, typename V = value_ty, typename ...Args,
+    2220             :             typename std::enable_if<(  sizeof...(Args) != 1
+    2221             :                                        ||! is_uninitialized_memcpyable<V, Args...>::value)
+    2222             :                                     &&  has_alloc_construct<A, V, Args...>::value>::type * = nullptr>
+    2223             :   PLUMED_GCH_CPP20_CONSTEXPR
+    2224             :   void
+    2225             :   construct (ptr p, Args&&... args)
+    2226             :   noexcept (noexcept (alloc_traits::construct (std::declval<alloc_ty&> (),
+    2227             :                       std::declval<value_ty *> (),
+    2228             :                       std::forward<Args> (args)...)))
+    2229             :   {
+    2230             :     alloc_traits::construct (allocator_ref (), to_address (p), std::forward<Args> (args)...);
+    2231             :   }
+    2232             : 
+    2233             :   template <typename A = alloc_ty, typename V = value_ty, typename ...Args,
+    2234             :             void_t<typename std::enable_if<(  sizeof...(Args) != 1
+    2235             :                    ||! is_uninitialized_memcpyable<V, Args...>::value)
+    2236             :                    &&! has_alloc_construct<A, V, Args...>::value>::type,
+    2237             :                    decltype (::new (std::declval<void *> ()) V (std::declval<Args> ()...))
+    2238             :                    > * = nullptr>
+    2239             :   PLUMED_GCH_CPP20_CONSTEXPR
+    2240             :   void
+    2241             :   construct (ptr p, Args&&... args)
+    2242             :   noexcept (noexcept (::new (std::declval<void *> ()) value_ty (std::declval<Args> ()...)))
+    2243             :   {
+    2244             :     construct_at (to_address (p), std::forward<Args> (args)...);
+    2245             :   }
+    2246             : 
+    2247             :   template <typename A = alloc_ty, typename V = value_ty,
+    2248             :             typename std::enable_if<is_trivially_destructible<V>::value
+    2249             :                                     &&! must_use_alloc_destroy<A, V>::value>::type * = nullptr>
+    2250             :   PLUMED_GCH_CPP20_CONSTEXPR
+    2251             :   void
+    2252             :   destroy (ptr) const noexcept
+    2253             :   { }
+    2254             : 
+    2255             :   template <typename A = alloc_ty, typename V = value_ty,
+    2256             :             typename std::enable_if<(! is_trivially_destructible<V>::value
+    2257             :                                      ||  must_use_alloc_destroy<A, V>::value)
+    2258             :                                     &&  has_alloc_destroy<A, V>::value>::type * = nullptr>
+    2259             :   PLUMED_GCH_CPP20_CONSTEXPR
+    2260             :   void
+    2261             :   destroy (ptr p) noexcept
+    2262             :   {
+    2263             :     alloc_traits::destroy (allocator_ref (), to_address (p));
+    2264             :   }
+    2265             : 
+    2266             :   // defined so we match C++20 behavior in all cases.
+    2267             :   template <typename A = alloc_ty, typename V = value_ty,
+    2268             :             typename std::enable_if<(! is_trivially_destructible<V>::value
+    2269             :                                      ||  must_use_alloc_destroy<A, V>::value)
+    2270             :                                     &&! has_alloc_destroy<A, V>::value>::type * = nullptr>
+    2271             :   PLUMED_GCH_CPP20_CONSTEXPR
+    2272             :   void
+    2273             :   destroy (ptr p) noexcept
+    2274             :   {
+    2275             :     destroy_at (to_address (p));
+    2276             :   }
+    2277             : 
+    2278             :   template <typename A = alloc_ty, typename V = value_ty,
+    2279             :             typename std::enable_if<is_trivially_destructible<V>::value
+    2280             :                                     &&! must_use_alloc_destroy<A, V>::value>::type * = nullptr>
+    2281             :   PLUMED_GCH_CPP14_CONSTEXPR
+    2282             :   void
+    2283             :   destroy_range (ptr, ptr) const noexcept
+    2284             :   { }
+    2285             : 
+    2286             :   template <typename A = alloc_ty, typename V = value_ty,
+    2287             :             typename std::enable_if<! is_trivially_destructible<V>::value
+    2288             :                                     ||  must_use_alloc_destroy<A, V>::value>::type * = nullptr>
+    2289             :   PLUMED_GCH_CPP20_CONSTEXPR
+    2290             :   void
+    2291             :   destroy_range (ptr first, ptr last) noexcept
+    2292             :   {
+    2293             :     for (; ! (first == last); ++first)
+    2294             :       destroy (first);
+    2295             :   }
+    2296             : 
+    2297             :   // allowed if trivially copyable and we use the standard allocator
+    2298             :   // and InputIt is a contiguous iterator
+    2299             :   template <typename ForwardIt,
+    2300             :             typename std::enable_if<
+    2301             :               is_uninitialized_memcpyable_iterator<ForwardIt>::value, bool>::type = true>
+    2302             :   PLUMED_GCH_CPP20_CONSTEXPR
+    2303             :   ptr
+    2304       23913 :   uninitialized_copy (ForwardIt first, ForwardIt last, ptr dest) noexcept
+    2305             :   {
+    2306             :     static_assert (std::is_constructible<value_ty, decltype (*first)>::value,
+    2307             :                    "`value_type` must be copy constructible.");
+    2308             : 
+    2309             : #ifdef PLUMED_GCH_LIB_IS_CONSTANT_EVALUATED
+    2310             :     if (std::is_constant_evaluated ())
+    2311             :       return default_uninitialized_copy (first, last, dest);
+    2312             : #endif
+    2313             : 
+    2314             :     const size_ty num_copy = external_range_length (first, last);
+    2315       23913 :     if (num_copy != 0)
+    2316       21569 :       std::memcpy (to_address (dest), to_address (first), num_copy * sizeof (value_ty));
+    2317       23913 :     return unchecked_next (dest, num_copy);
+    2318             :   }
+    2319             : 
+    2320             :   template <typename ForwardIt,
+    2321             :             typename std::enable_if<
+    2322             :               is_uninitialized_memcpyable_iterator<ForwardIt>::value, bool>::type = true>
+    2323             :   PLUMED_GCH_CPP20_CONSTEXPR
+    2324             :   ptr
+    2325             :   uninitialized_copy (std::move_iterator<ForwardIt> first,
+    2326             :                       std::move_iterator<ForwardIt> last,
+    2327             :                       ptr dest) noexcept
+    2328             :   {
+    2329        3657 :     return uninitialized_copy (first.base (), last.base (), dest);
+    2330             :   }
+    2331             : 
+    2332             :   template <typename InputIt,
+    2333             :             typename std::enable_if<
+    2334             :               ! is_uninitialized_memcpyable_iterator<InputIt>::value, bool>::type = false>
+    2335             :   PLUMED_GCH_CPP20_CONSTEXPR
+    2336             :   ptr
+    2337             :   uninitialized_copy (InputIt first, InputIt last, ptr d_first)
+    2338             :   {
+    2339             :     return default_uninitialized_copy (first, last, d_first);
+    2340             :   }
+    2341             : 
+    2342             :   template <typename InputIt>
+    2343             :   PLUMED_GCH_CPP20_CONSTEXPR
+    2344             :   ptr
+    2345             :   default_uninitialized_copy (InputIt first, InputIt last, ptr d_first)
+    2346             :   {
+    2347             :     ptr d_last = d_first;
+    2348             :     PLUMED_GCH_TRY
+    2349             :     {
+    2350             :       // Note: Not != because `using namespace std::rel_ops` can break constexpr.
+    2351             :       for (; ! (first == last); ++first, static_cast<void> (++d_last))
+    2352             :         construct (d_last, *first);
+    2353             :       return d_last;
+    2354             :     }
+    2355             :     PLUMED_GCH_CATCH (...)
+    2356             :     {
+    2357             :       destroy_range (d_first, d_last);
+    2358             :       PLUMED_GCH_THROW;
+    2359             :     }
+    2360             :   }
+    2361             : 
+    2362             :   template <typename A = alloc_ty, typename V = value_ty,
+    2363             :             typename std::enable_if<is_trivially_constructible<V>::value
+    2364             :                                     &&! must_use_alloc_construct<A, V>::value>::type * = nullptr>
+    2365             :   PLUMED_GCH_CPP20_CONSTEXPR
+    2366             :   ptr
+    2367             :   uninitialized_value_construct (ptr first, ptr last)
+    2368             :   {
+    2369             : #ifdef PLUMED_GCH_LIB_IS_CONSTANT_EVALUATED
+    2370             :     if (std::is_constant_evaluated ())
+    2371             :       return default_uninitialized_value_construct (first, last);
+    2372             : #endif
+    2373             :     std::fill (first, last, value_ty ());
+    2374             :     return last;
+    2375             :   }
+    2376             : 
+    2377             :   template <typename A = alloc_ty, typename V = value_ty,
+    2378             :             typename std::enable_if<! is_trivially_constructible<V>::value
+    2379             :                                     ||  must_use_alloc_construct<A, V>::value>::type * = nullptr>
+    2380             :   PLUMED_GCH_CPP20_CONSTEXPR
+    2381             :   ptr
+    2382             :   uninitialized_value_construct (ptr first, ptr last)
+    2383             :   {
+    2384             :     return default_uninitialized_value_construct (first, last);
+    2385             :   }
+    2386             : 
+    2387             :   PLUMED_GCH_CPP20_CONSTEXPR
+    2388             :   ptr
+    2389             :   default_uninitialized_value_construct (ptr first, ptr last)
+    2390             :   {
+    2391             :     ptr curr = first;
+    2392             :     PLUMED_GCH_TRY
+    2393             :     {
+    2394             :       for (; ! (curr == last); ++curr)
+    2395             :         construct (curr);
+    2396             :       return curr;
+    2397             :     }
+    2398             :     PLUMED_GCH_CATCH (...)
+    2399             :     {
+    2400             :       destroy_range (first, curr);
+    2401             :       PLUMED_GCH_THROW;
+    2402             :     }
+    2403             :   }
+    2404             : 
+    2405             :   PLUMED_GCH_CPP20_CONSTEXPR
+    2406             :   ptr
+    2407             :   uninitialized_fill (ptr first, ptr last)
+    2408             :   {
+    2409             :     return uninitialized_value_construct (first, last);
+    2410             :   }
+    2411             : 
+    2412             :   PLUMED_GCH_CPP20_CONSTEXPR
+    2413             :   ptr
+    2414             :   uninitialized_fill (ptr first, ptr last, const value_ty& val)
+    2415             :   {
+    2416             :     ptr curr = first;
+    2417             :     PLUMED_GCH_TRY
+    2418             :     {
+    2419             :       for (; ! (curr == last); ++curr)
+    2420             :         construct (curr, val);
+    2421             :       return curr;
+    2422             :     }
+    2423             :     PLUMED_GCH_CATCH (...)
+    2424             :     {
+    2425             :       destroy_range (first, curr);
+    2426             :       PLUMED_GCH_THROW;
+    2427             :     }
+    2428             :   }
+    2429             : 
+    2430             : private:
+    2431             :   // If value_ty is an array, replicate C++20 behavior (I don't think that value_ty can
+    2432             :   // actually be an array because of the Erasable requirement, but there shouldn't
+    2433             :   // be any runtime cost for being defensive here).
+    2434             :   template <typename V = value_ty,
+    2435             :             typename std::enable_if<std::is_array<V>::value, bool>::type = true>
+    2436             :   static PLUMED_GCH_CPP20_CONSTEXPR
+    2437             :   void
+    2438             :   destroy_at (value_ty *p) noexcept
+    2439             :   {
+    2440             :     for (auto& e : *p)
+    2441             :       destroy_at (std::addressof (e));
+    2442             :   }
+    2443             : 
+    2444             :   template <typename V = value_ty,
+    2445             :             typename std::enable_if<! std::is_array<V>::value, bool>::type = false>
+    2446             :   static PLUMED_GCH_CPP20_CONSTEXPR
+    2447             :   void
+    2448             :   destroy_at (value_ty *p) noexcept
+    2449             :   {
+    2450             :     p->~value_ty ();
+    2451             :   }
+    2452             : 
+    2453             :   template <typename V = value_ty, typename ...Args>
+    2454             :   static PLUMED_GCH_CPP20_CONSTEXPR
+    2455             :   auto
+    2456             :   construct_at (value_ty *p, Args&&... args)
+    2457             :   noexcept (noexcept (::new (std::declval<void *> ()) V (std::declval<Args> ()...)))
+    2458             :   -> decltype (::new (std::declval<void *> ()) V (std::declval<Args> ()...))
+    2459             :   {
+    2460             : #if defined (PLUMED_GCH_LIB_IS_CONSTANT_EVALUATED) && defined (PLUMED_GCH_LIB_CONSTEXPR_MEMORY)
+    2461             :     if (std::is_constant_evaluated ())
+    2462             :       return std::construct_at (p, std::forward<Args> (args)...);
+    2463             : #endif
+    2464             :     void *vp = const_cast<void *> (static_cast<const volatile void *> (p));
+    2465             :     return ::new (vp) value_ty (std::forward<Args>(args)...);
+    2466             :   }
+    2467             : };
+    2468             : 
+    2469             : template <typename Pointer, typename SizeT>
+    2470             : class small_vector_data_base
+    2471             : {
+    2472             : public:
+    2473             :   using ptr     = Pointer;
+    2474             :   using size_ty = SizeT;
+    2475             : 
+    2476             :   small_vector_data_base            (void)                              = default;
+    2477             :   small_vector_data_base            (const small_vector_data_base&)     = default;
+    2478             :   small_vector_data_base            (small_vector_data_base&&) noexcept = default;
+    2479             :   small_vector_data_base& operator= (const small_vector_data_base&)     = default;
+    2480             :   small_vector_data_base& operator= (small_vector_data_base&&) noexcept = default;
+    2481             :   ~small_vector_data_base           (void)                              = default;
+    2482             : 
+    2483   149970449 :   constexpr ptr     data_ptr (void) const noexcept { return m_data_ptr; }
+    2484     7988943 :   constexpr size_ty capacity (void) const noexcept { return m_capacity; }
+    2485   183387338 :   constexpr size_ty size     (void) const noexcept { return m_size; }
+    2486             : 
+    2487     1630692 :   PLUMED_GCH_CPP20_CONSTEXPR void set_data_ptr (ptr     data_ptr) noexcept { m_data_ptr = data_ptr; }
+    2488     1630692 :   PLUMED_GCH_CPP20_CONSTEXPR void set_capacity (size_ty capacity) noexcept { m_capacity = capacity; }
+    2489     7523616 :   PLUMED_GCH_CPP20_CONSTEXPR void set_size     (size_ty size)     noexcept { m_size     = size;     }
+    2490             : 
+    2491             :   PLUMED_GCH_CPP20_CONSTEXPR
+    2492             :   void
+    2493             :   set (ptr data_ptr, size_ty capacity, size_ty size)
+    2494             :   {
+    2495        1313 :     m_data_ptr = data_ptr;
+    2496        1313 :     m_capacity = capacity;
+    2497        1313 :     m_size     = size;
+    2498             :   }
+    2499             : 
+    2500             :   PLUMED_GCH_CPP20_CONSTEXPR
+    2501             :   void
+    2502             :   swap_data_ptr (small_vector_data_base& other) noexcept
+    2503             :   {
+    2504             :     using std::swap;
+    2505             :     swap (m_data_ptr, other.m_data_ptr);
+    2506             :   }
+    2507             : 
+    2508             :   PLUMED_GCH_CPP20_CONSTEXPR
+    2509             :   void
+    2510             :   swap_capacity (small_vector_data_base& other) noexcept
+    2511             :   {
+    2512             :     using std::swap;
+    2513             :     swap (m_capacity, other.m_capacity);
+    2514             :   }
+    2515             : 
+    2516             :   PLUMED_GCH_CPP20_CONSTEXPR
+    2517             :   void
+    2518             :   swap_size (small_vector_data_base& other) noexcept
+    2519             :   {
+    2520             :     using std::swap;
+    2521             :     swap (m_size, other.m_size);
+    2522             :   }
+    2523             : 
+    2524             :   PLUMED_GCH_CPP20_CONSTEXPR
+    2525             :   void
+    2526             :   swap (small_vector_data_base& other) noexcept
+    2527             :   {
+    2528             :     using std::swap;
+    2529             :     swap (m_data_ptr, other.m_data_ptr);
+    2530             :     swap (m_capacity, other.m_capacity);
+    2531             :     swap (m_size,     other.m_size);
+    2532             :   }
+    2533             : 
+    2534             : private:
+    2535             :   ptr     m_data_ptr;
+    2536             :   size_ty m_capacity;
+    2537             :   size_ty m_size;
+    2538             : };
+    2539             : 
+    2540             : template <typename Pointer, typename SizeT, typename T, unsigned InlineCapacity>
+    2541             : class small_vector_data
+    2542             : : public small_vector_data_base<Pointer, SizeT>
+    2543             : {
+    2544             : public:
+    2545             :   using value_ty = T;
+    2546             : 
+    2547             :   small_vector_data            (void)                         = default;
+    2548             :   small_vector_data            (const small_vector_data&)     = delete;
+    2549             :   small_vector_data            (small_vector_data&&) noexcept = delete;
+    2550             :   small_vector_data& operator= (const small_vector_data&)     = delete;
+    2551             :   small_vector_data& operator= (small_vector_data&&) noexcept = delete;
+    2552             :   ~small_vector_data           (void)                         = default;
+    2553             : 
+    2554             :   PLUMED_GCH_CPP14_CONSTEXPR
+    2555             :   value_ty *
+    2556             :   storage (void) noexcept
+    2557             :   {
+    2558             :     return m_storage.get_inline_ptr ();
+    2559             :   }
+    2560             : 
+    2561             :   constexpr
+    2562             :   const value_ty *
+    2563             :   storage (void) const noexcept
+    2564             :   {
+    2565             :     return m_storage.get_inline_ptr ();
+    2566             :   }
+    2567             : 
+    2568             : private:
+    2569             :   inline_storage<value_ty, InlineCapacity> m_storage;
+    2570             : };
+    2571             : 
+    2572             : template <typename Pointer, typename SizeT, typename T>
+    2573             : class PLUMED_GCH_EMPTY_BASE small_vector_data<Pointer, SizeT, T, 0>
+    2574             : : public  small_vector_data_base<Pointer, SizeT>,
+    2575             : private inline_storage<T, 0>
+    2576             : {
+    2577             :   using base = inline_storage<T, 0>;
+    2578             : 
+    2579             : public:
+    2580             :   using value_ty = T;
+    2581             : 
+    2582             :   small_vector_data            (void)                         = default;
+    2583             :   small_vector_data            (const small_vector_data&)     = delete;
+    2584             :   small_vector_data            (small_vector_data&&) noexcept = delete;
+    2585             :   small_vector_data& operator= (const small_vector_data&)     = delete;
+    2586             :   small_vector_data& operator= (small_vector_data&&) noexcept = delete;
+    2587             :   ~small_vector_data           (void)                         = default;
+    2588             : 
+    2589             :   PLUMED_GCH_CPP14_CONSTEXPR
+    2590             :   value_ty *
+    2591             :   storage (void) noexcept
+    2592             :   {
+    2593             :     return base::get_inline_ptr ();
+    2594             :   }
+    2595             : 
+    2596             :   constexpr
+    2597             :   const value_ty *
+    2598             :   storage (void) const noexcept
+    2599             :   {
+    2600             :     return base::get_inline_ptr ();
+    2601             :   }
+    2602             : };
+    2603             : 
+    2604             : template <typename Allocator, unsigned InlineCapacity>
+    2605             : class small_vector_base
+    2606             : : public allocator_interface<Allocator>
+    2607             : {
+    2608             : public:
+    2609             :   using size_type       = typename allocator_interface<Allocator>::size_type;
+    2610             :   using difference_type = typename allocator_interface<Allocator>::difference_type;
+    2611             : 
+    2612             :   template <typename SameAllocator, unsigned DifferentInlineCapacity>
+    2613             :   friend class small_vector_base;
+    2614             : 
+    2615             : protected:
+    2616             :   using alloc_interface = allocator_interface<Allocator>;
+    2617             :   using alloc_traits    = typename alloc_interface::alloc_traits;
+    2618             :   using alloc_ty        = Allocator;
+    2619             : 
+    2620             :   using value_ty        = typename alloc_interface::value_ty;
+    2621             :   using ptr             = typename alloc_interface::ptr;
+    2622             :   using cptr            = typename alloc_interface::cptr;
+    2623             :   using size_ty         = typename alloc_interface::size_ty;
+    2624             :   using diff_ty         = typename alloc_interface::diff_ty;
+    2625             : 
+    2626             :   static_assert (alloc_interface::template is_complete<value_ty>::value || InlineCapacity == 0,
+    2627             :                  "`value_type` must be complete for instantiation of a non-zero number "
+    2628             :                  "of inline elements.");
+    2629             : 
+    2630             :   template <typename T>
+    2631             :   using is_complete = typename alloc_interface::template is_complete<T>;
+    2632             : 
+    2633             :   using alloc_interface::allocator_ref;
+    2634             :   using alloc_interface::construct;
+    2635             :   using alloc_interface::deallocate;
+    2636             :   using alloc_interface::destroy;
+    2637             :   using alloc_interface::destroy_range;
+    2638             :   using alloc_interface::external_range_length;
+    2639             :   using alloc_interface::get_max_size;
+    2640             :   using alloc_interface::internal_range_length;
+    2641             :   using alloc_interface::to_address;
+    2642             :   using alloc_interface::unchecked_advance;
+    2643             :   using alloc_interface::unchecked_next;
+    2644             :   using alloc_interface::unchecked_prev;
+    2645             :   using alloc_interface::uninitialized_copy;
+    2646             :   using alloc_interface::uninitialized_fill;
+    2647             :   using alloc_interface::uninitialized_value_construct;
+    2648             : 
+    2649             :   template <typename Integer>
+    2650             :   PLUMED_GCH_NODISCARD
+    2651             :   static PLUMED_GCH_CONSTEVAL
+    2652             :   std::size_t
+    2653             :   numeric_max (void) noexcept
+    2654             :   {
+    2655             :     return alloc_interface::template numeric_max<Integer> ();
+    2656             :   }
+    2657             : 
+    2658             :   PLUMED_GCH_NODISCARD
+    2659             :   static PLUMED_GCH_CONSTEVAL
+    2660             :   size_ty
+    2661             :   get_inline_capacity (void) noexcept
+    2662             :   {
+    2663             :     return static_cast<size_ty> (InlineCapacity);
+    2664             :   }
+    2665             : 
+    2666             :   template <typename ...>
+    2667             :   using void_t = void;
+    2668             : 
+    2669             :   template <bool B>
+    2670             :   using bool_constant = std::integral_constant<bool, B>;
+    2671             : 
+    2672             :   template <typename Void, typename AI, typename V, typename ...Args>
+    2673             :   struct is_emplace_constructible_impl
+    2674             : : std::false_type
+    2675             :   {
+    2676             :     using nothrow = std::false_type;
+    2677             :   };
+    2678             : 
+    2679             :   template <typename AI, typename V, typename ...Args>
+    2680             :   struct is_emplace_constructible_impl<
+    2681             :     void_t<typename std::enable_if<is_complete<V>::value>::type,
+    2682             :            decltype (std::declval<AI&> ().construct (std::declval<V *> (),
+    2683             :                      std::declval<Args> ()...))>,
+    2684             :     AI, V, Args...>
+    2685             : : std::true_type
+    2686             :   {
+    2687             :     using nothrow =
+    2688             :     bool_constant<noexcept (std::declval<AI&> ().construct (std::declval<V *> (),
+    2689             :                             std::declval<Args> ()...))>;
+    2690             :                                                            };
+    2691             : 
+    2692             :   template <typename ...Args>
+    2693             :   struct is_emplace_constructible
+    2694             : : is_emplace_constructible_impl<void, alloc_interface, value_ty, Args...>
+    2695             :   { };
+    2696             : 
+    2697             :   template <typename ...Args>
+    2698             :   struct is_nothrow_emplace_constructible
+    2699             : : is_emplace_constructible_impl<void, alloc_interface, value_ty, Args...>::nothrow
+    2700             :   { };
+    2701             : 
+    2702             :   template <typename V = value_ty>
+    2703             :   struct is_explicitly_move_insertable
+    2704             : : is_emplace_constructible<V&&>
+    2705             :   { };
+    2706             : 
+    2707             :   template <typename V = value_ty>
+    2708             :   struct is_explicitly_nothrow_move_insertable
+    2709             : : is_nothrow_emplace_constructible<V&&>
+    2710             :   { };
+    2711             : 
+    2712             :   template <typename V = value_ty>
+    2713             :   struct is_explicitly_copy_insertable
+    2714             : : std::integral_constant<bool, is_emplace_constructible<V&>::value
+    2715             :                            &&  is_emplace_constructible<const V&>::value>
+    2716             :   { };
+    2717             : 
+    2718             :   template <typename V = value_ty>
+    2719             :   struct is_explicitly_nothrow_copy_insertable
+    2720             : : std::integral_constant<bool, is_nothrow_emplace_constructible<V&>::value
+    2721             :                            &&  is_nothrow_emplace_constructible<const V&>::value>
+    2722             :   { };
+    2723             : 
+    2724             :   template <typename AI, typename Enable = void>
+    2725             :   struct is_eraseable
+    2726             : : std::false_type
+    2727             :   { };
+    2728             : 
+    2729             :   template <typename AI>
+    2730             :   struct is_eraseable<AI,
+    2731             :                       void_t<decltype (std::declval<AI&> ().destroy (std::declval<value_ty *> ()))>>
+    2732             : : std::true_type
+    2733             :   { };
+    2734             : 
+    2735             :   template <typename V>
+    2736             :   struct relocate_with_move
+    2737             : #ifdef PLUMED_GCH_NO_STRONG_EXCEPTION_GUARANTEES
+    2738             : : std::true_type
+    2739             : #else
+    2740             : : bool_constant<std::is_nothrow_move_constructible<V>::value
+    2741             :                   ||! is_explicitly_copy_insertable<V>::value>
+    2742             : #endif
+    2743             :   { };
+    2744             : 
+    2745             :   template <typename A>
+    2746             :   struct allocations_are_movable
+    2747             : : bool_constant<std::is_same<std::allocator<value_ty>, A>::value
+    2748             :                   ||  std::allocator_traits<A>::propagate_on_container_move_assignment::value
+    2749             : #ifdef PLUMED_GCH_LIB_IS_ALWAYS_EQUAL
+    2750             :                   ||  std::allocator_traits<A>::is_always_equal::value
+    2751             : #endif
+    2752             :                   >
+    2753             :   { };
+    2754             : 
+    2755             :   template <typename A>
+    2756             :   struct allocations_are_swappable
+    2757             : : bool_constant<std::is_same<std::allocator<value_ty>, A>::value
+    2758             :                   ||  std::allocator_traits<A>::propagate_on_container_swap::value
+    2759             : #ifdef PLUMED_GCH_LIB_IS_ALWAYS_EQUAL
+    2760             :                   ||  std::allocator_traits<A>::is_always_equal::value
+    2761             : #endif
+    2762             :                   >
+    2763             :   { };
+    2764             : 
+    2765             :   template <typename ...Args>
+    2766             :   using is_memcpyable = typename alloc_interface::template is_memcpyable<Args...>;
+    2767             : 
+    2768             :   template <typename ...Args>
+    2769             :   using is_memcpyable_iterator =
+    2770             :   typename alloc_interface::template is_memcpyable_iterator<Args...>;
+    2771             : 
+    2772             :   PLUMED_GCH_NORETURN
+    2773             :   static PLUMED_GCH_CPP20_CONSTEXPR
+    2774             :   void
+    2775             :   throw_overflow_error (void)
+    2776             :   {
+    2777             : #ifdef PLUMED_GCH_EXCEPTIONS
+    2778             :     throw std::overflow_error ("The requested conversion would overflow.");
+    2779             : #else
+    2780             :     std::fprintf (stderr, "[gch::small_vector] The requested conversion would overflow.\n");
+    2781             :     std::abort ();
+    2782             : #endif
+    2783             :   }
+    2784             : 
+    2785             :   PLUMED_GCH_NORETURN
+    2786             :   static PLUMED_GCH_CPP20_CONSTEXPR
+    2787             :   void
+    2788             :   throw_index_error (void)
+    2789             :   {
+    2790             : #ifdef PLUMED_GCH_EXCEPTIONS
+    2791             :     throw std::out_of_range ("The requested index was out of range.");
+    2792             : #else
+    2793             :     std::fprintf (stderr, "[gch::small_vector] The requested index was out of range.\n");
+    2794             :     std::abort ();
+    2795             : #endif
+    2796             :   }
+    2797             : 
+    2798             :   PLUMED_GCH_NORETURN
+    2799             :   static PLUMED_GCH_CPP20_CONSTEXPR
+    2800             :   void
+    2801             :   throw_increment_error (void)
+    2802             :   {
+    2803             : #ifdef PLUMED_GCH_EXCEPTIONS
+    2804             :     throw std::domain_error ("The requested increment was outside of the allowed range.");
+    2805             : #else
+    2806             :     std::fprintf (
+    2807             :       stderr,
+    2808             :       "[gch::small_vector] The requested increment was outside of the allowed range.\n");
+    2809             :     std::abort ();
+    2810             : #endif
+    2811             :   }
+    2812             : 
+    2813             :   PLUMED_GCH_NORETURN
+    2814             :   static PLUMED_GCH_CPP20_CONSTEXPR
+    2815             :   void
+    2816           0 :   throw_allocation_size_error (void)
+    2817             :   {
+    2818             : #ifdef PLUMED_GCH_EXCEPTIONS
+    2819           0 :     throw std::length_error ("The required allocation exceeds the maximum size.");
+    2820             : #else
+    2821             :     std::fprintf (
+    2822             :       stderr,
+    2823             :       "[gch::small_vector] The required allocation exceeds the maximum size.\n");
+    2824             :     std::abort ();
+    2825             : #endif
+    2826             :   }
+    2827             : 
+    2828             :   PLUMED_GCH_NODISCARD PLUMED_GCH_CPP14_CONSTEXPR
+    2829             :   ptr
+    2830             :   ptr_cast (const small_vector_iterator<cptr, diff_ty>& it) noexcept
+    2831             :   {
+    2832             :     return unchecked_next (begin_ptr (), it.base () - begin_ptr ());
+    2833             :   }
+    2834             : 
+    2835             : private:
+    2836             :   class stack_temporary
+    2837             :   {
+    2838             :   public:
+    2839             :     stack_temporary            (void)                       = delete;
+    2840             :     stack_temporary            (const stack_temporary&)     = delete;
+    2841             :     stack_temporary            (stack_temporary&&) noexcept = delete;
+    2842             :     stack_temporary& operator= (const stack_temporary&)     = delete;
+    2843             :     stack_temporary& operator= (stack_temporary&&) noexcept = delete;
+    2844             : //      ~stack_temporary           (void)                       = impl;
+    2845             : 
+    2846             :     template <typename ...Args>
+    2847             :     PLUMED_GCH_CPP20_CONSTEXPR explicit
+    2848             :     stack_temporary (alloc_interface& alloc_iface, Args&&... args)
+    2849             :       : m_interface (alloc_iface)
+    2850             :     {
+    2851             :       m_interface.construct (get_pointer (), std::forward<Args> (args)...);
+    2852             :     }
+    2853             : 
+    2854             :     PLUMED_GCH_CPP20_CONSTEXPR
+    2855             :     ~stack_temporary (void)
+    2856             :     {
+    2857             :       m_interface.destroy (get_pointer ());
+    2858             :     }
+    2859             : 
+    2860             :     PLUMED_GCH_NODISCARD PLUMED_GCH_CPP20_CONSTEXPR
+    2861             :     const value_ty&
+    2862             :     get (void) const noexcept
+    2863             :     {
+    2864             :       return *get_pointer ();
+    2865             :     }
+    2866             : 
+    2867             :     PLUMED_GCH_NODISCARD PLUMED_GCH_CPP20_CONSTEXPR
+    2868             :     value_ty&&
+    2869             :     release (void) noexcept
+    2870             :     {
+    2871             :       return std::move (*get_pointer ());
+    2872             :     }
+    2873             : 
+    2874             :   private:
+    2875             :     PLUMED_GCH_NODISCARD PLUMED_GCH_CPP20_CONSTEXPR
+    2876             :     cptr
+    2877             :     get_pointer (void) const noexcept
+    2878             :     {
+    2879             :       return static_cast<cptr> (static_cast<const void *> (std::addressof (m_data)));
+    2880             :     }
+    2881             : 
+    2882             :     PLUMED_GCH_NODISCARD PLUMED_GCH_CPP20_CONSTEXPR
+    2883             :     ptr
+    2884             :     get_pointer (void) noexcept
+    2885             :     {
+    2886             :       return static_cast<ptr> (static_cast<void *> (std::addressof (m_data)));
+    2887             :     }
+    2888             : 
+    2889             :     alloc_interface& m_interface;
+    2890             :     typename std::aligned_storage<sizeof (value_ty), alignof (value_ty)>::type m_data;
+    2891             :   };
+    2892             : 
+    2893             : #ifdef PLUMED_GCH_LIB_IS_CONSTANT_EVALUATED
+    2894             : 
+    2895             :   class heap_temporary
+    2896             :   {
+    2897             :   public:
+    2898             :     heap_temporary            (void)                      = delete;
+    2899             :     heap_temporary            (const heap_temporary&)     = delete;
+    2900             :     heap_temporary            (heap_temporary&&) noexcept = delete;
+    2901             :     heap_temporary& operator= (const heap_temporary&)     = delete;
+    2902             :     heap_temporary& operator= (heap_temporary&&) noexcept = delete;
+    2903             : //      ~heap_temporary           (void)                      = impl;
+    2904             : 
+    2905             :     template <typename ...Args>
+    2906             :     PLUMED_GCH_CPP20_CONSTEXPR explicit
+    2907             :     heap_temporary (alloc_interface& alloc_iface, Args&&... args)
+    2908             :       : m_interface (alloc_iface),
+    2909             :         m_data_ptr  (alloc_iface.allocate (sizeof (value_ty)))
+    2910             :     {
+    2911             :       PLUMED_GCH_TRY
+    2912             :       {
+    2913             :         m_interface.construct (m_data_ptr, std::forward<Args> (args)...);
+    2914             :       }
+    2915             :       PLUMED_GCH_CATCH (...)
+    2916             :       {
+    2917             :         m_interface.deallocate (m_data_ptr, sizeof (value_ty));
+    2918             :         PLUMED_GCH_THROW;
+    2919             :       }
+    2920             :     }
+    2921             : 
+    2922             :     PLUMED_GCH_CPP20_CONSTEXPR
+    2923             :     ~heap_temporary (void)
+    2924             :     {
+    2925             :       m_interface.destroy (m_data_ptr);
+    2926             :       m_interface.deallocate (m_data_ptr, sizeof (value_ty));
+    2927             :     }
+    2928             : 
+    2929             :     PLUMED_GCH_NODISCARD PLUMED_GCH_CPP20_CONSTEXPR
+    2930             :     const value_ty&
+    2931             :     get (void) const noexcept
+    2932             :     {
+    2933             :       return *m_data_ptr;
+    2934             :     }
+    2935             : 
+    2936             :     PLUMED_GCH_NODISCARD PLUMED_GCH_CPP20_CONSTEXPR
+    2937             :     value_ty&&
+    2938             :     release (void) noexcept
+    2939             :     {
+    2940             :       return std::move (*m_data_ptr);
+    2941             :     }
+    2942             : 
+    2943             :   private:
+    2944             :     alloc_interface& m_interface;
+    2945             :     ptr              m_data_ptr;
+    2946             :   };
+    2947             : 
+    2948             : #endif
+    2949             : 
+    2950             :   PLUMED_GCH_CPP20_CONSTEXPR
+    2951             :   void
+    2952     1607700 :   wipe (void)
+    2953             :   {
+    2954     1607700 :     destroy_range (begin_ptr (), end_ptr ());
+    2955     1607700 :     if (has_allocation ())
+    2956             :       deallocate (data_ptr (), get_capacity ());
+    2957     1607700 :   }
+    2958             : 
+    2959             :   PLUMED_GCH_CPP20_CONSTEXPR
+    2960             :   void
+    2961             :   set_data_ptr (ptr data_ptr) noexcept
+    2962             :   {
+    2963             :     m_data.set_data_ptr (data_ptr);
+    2964             :   }
+    2965             : 
+    2966             :   PLUMED_GCH_CPP20_CONSTEXPR
+    2967             :   void
+    2968             :   set_capacity (size_ty capacity) noexcept
+    2969             :   {
+    2970             :     m_data.set_capacity (static_cast<size_type> (capacity));
+    2971        2344 :   }
+    2972             : 
+    2973             :   PLUMED_GCH_CPP20_CONSTEXPR
+    2974             :   void
+    2975             :   set_size (size_ty size) noexcept
+    2976             :   {
+    2977             :     m_data.set_size (static_cast<size_type> (size));
+    2978     4192048 :   }
+    2979             : 
+    2980             :   PLUMED_GCH_CPP20_CONSTEXPR
+    2981             :   void
+    2982             :   set_data (ptr data_ptr, size_ty capacity, size_ty size) noexcept
+    2983             :   {
+    2984             :     m_data.set (data_ptr, static_cast<size_type> (capacity), static_cast<size_type> (size));
+    2985             :   }
+    2986             : 
+    2987             :   PLUMED_GCH_CPP20_CONSTEXPR
+    2988             :   void
+    2989             :   swap_data_ptr (small_vector_base& other) noexcept
+    2990             :   {
+    2991             :     m_data.swap_data_ptr (other.m_data);
+    2992             :   }
+    2993             : 
+    2994             :   PLUMED_GCH_CPP20_CONSTEXPR
+    2995             :   void
+    2996             :   swap_capacity (small_vector_base& other) noexcept
+    2997             :   {
+    2998             :     m_data.swap_capacity (other.m_data);
+    2999             :   }
+    3000             : 
+    3001             :   PLUMED_GCH_CPP20_CONSTEXPR
+    3002             :   void
+    3003             :   swap_size (small_vector_base& other) noexcept
+    3004             :   {
+    3005             :     m_data.swap_size (other.m_data);
+    3006             :   }
+    3007             : 
+    3008             :   PLUMED_GCH_CPP20_CONSTEXPR
+    3009             :   void
+    3010             :   swap_allocation (small_vector_base& other) noexcept
+    3011             :   {
+    3012             :     m_data.swap (other.m_data);
+    3013             :   }
+    3014             : 
+    3015             :   PLUMED_GCH_CPP20_CONSTEXPR
+    3016             :   void
+    3017             :   reset_data (ptr data_ptr, size_ty capacity, size_ty size)
+    3018             :   {
+    3019        1313 :     wipe ();
+    3020             :     m_data.set (data_ptr, static_cast<size_type> (capacity), static_cast<size_type> (size));
+    3021           0 :   }
+    3022             : 
+    3023             :   PLUMED_GCH_CPP20_CONSTEXPR
+    3024             :   void
+    3025             :   increase_size (size_ty n) noexcept
+    3026             :   {
+    3027     2133299 :     m_data.set_size (get_size () + n);
+    3028             :   }
+    3029             : 
+    3030             :   PLUMED_GCH_CPP20_CONSTEXPR
+    3031             :   void
+    3032             :   decrease_size (size_ty n) noexcept
+    3033             :   {
+    3034      135205 :     m_data.set_size (get_size () - n);
+    3035             :   }
+    3036             : 
+    3037             :   PLUMED_GCH_CPP20_CONSTEXPR
+    3038             :   ptr
+    3039             :   unchecked_allocate (size_ty n)
+    3040             :   {
+    3041             :     assert (InlineCapacity < n && "Allocated capacity should be greater than InlineCapacity.");
+    3042             :     return alloc_interface::allocate (n);
+    3043             :   }
+    3044             : 
+    3045             :   PLUMED_GCH_CPP20_CONSTEXPR
+    3046             :   ptr
+    3047             :   unchecked_allocate (size_ty n, cptr hint)
+    3048             :   {
+    3049             :     assert (InlineCapacity < n && "Allocated capacity should be greater than InlineCapacity.");
+    3050             :     return alloc_interface::allocate_with_hint (n, hint);
+    3051             :   }
+    3052             : 
+    3053             :   PLUMED_GCH_CPP20_CONSTEXPR
+    3054             :   ptr
+    3055           0 :   checked_allocate (size_ty n)
+    3056             :   {
+    3057           0 :     if (get_max_size () < n)
+    3058           0 :       throw_allocation_size_error ();
+    3059           0 :     return unchecked_allocate (n);
+    3060             :   }
+    3061             : 
+    3062             : protected:
+    3063             :   PLUMED_GCH_NODISCARD PLUMED_GCH_CPP14_CONSTEXPR
+    3064             :   size_ty
+    3065             :   unchecked_calculate_new_capacity (const size_ty minimum_required_capacity) const noexcept
+    3066             :   {
+    3067             :     const size_ty current_capacity = get_capacity ();
+    3068             : 
+    3069             :     assert (current_capacity < minimum_required_capacity);
+    3070             : 
+    3071        2516 :     if (get_max_size () - current_capacity <= current_capacity)
+    3072             :       return get_max_size ();
+    3073             : 
+    3074             :     // Note: This growth factor might be theoretically superior, but in testing it falls flat:
+    3075             :     // size_ty new_capacity = current_capacity + (current_capacity / 2);
+    3076             : 
+    3077        3657 :     const size_ty new_capacity = 2 * current_capacity;
+    3078             :     if (new_capacity < minimum_required_capacity)
+    3079             :       return minimum_required_capacity;
+    3080             :     return new_capacity;
+    3081             :   }
+    3082             : 
+    3083             :   PLUMED_GCH_NODISCARD PLUMED_GCH_CPP14_CONSTEXPR
+    3084             :   size_ty
+    3085        2344 :   checked_calculate_new_capacity (const size_ty minimum_required_capacity) const
+    3086             :   {
+    3087        2344 :     if (get_max_size () < minimum_required_capacity)
+    3088           0 :       throw_allocation_size_error ();
+    3089        2344 :     return unchecked_calculate_new_capacity (minimum_required_capacity);
+    3090             :   }
+    3091             : 
+    3092             :   template <unsigned I>
+    3093             :   PLUMED_GCH_CPP20_CONSTEXPR
+    3094             :   small_vector_base&
+    3095     4192048 :   copy_assign_default (const small_vector_base<Allocator, I>& other)
+    3096             :   {
+    3097     4192048 :     if (get_capacity () < other.get_size ())
+    3098             :     {
+    3099             :       // Reallocate.
+    3100             :       size_ty new_capacity = unchecked_calculate_new_capacity (other.get_size ());
+    3101           0 :       ptr     new_data_ptr = unchecked_allocate (new_capacity, other.allocation_end_ptr ());
+    3102             : 
+    3103             :       PLUMED_GCH_TRY
+    3104             :       {
+    3105           0 :         uninitialized_copy (other.begin_ptr (), other.end_ptr (), new_data_ptr);
+    3106             :       }
+    3107             :       PLUMED_GCH_CATCH (...)
+    3108             :       {
+    3109             :         deallocate (new_data_ptr, new_capacity);
+    3110             :         PLUMED_GCH_THROW;
+    3111             :       }
+    3112             : 
+    3113             :       reset_data (new_data_ptr, new_capacity, other.get_size ());
+    3114             :     }
+    3115             :     else
+    3116             :     {
+    3117     4192048 :       if (get_size () < other.get_size ())
+    3118             :       {
+    3119             :         // No reallocation, partially in uninitialized space.
+    3120       20256 :         std::copy_n (other.begin_ptr (), get_size (), begin_ptr ());
+    3121       40512 :         uninitialized_copy (
+    3122             :           unchecked_next (other.begin_ptr (), get_size ()),
+    3123             :           other.end_ptr (),
+    3124             :           end_ptr ());
+    3125             :       }
+    3126             :       else
+    3127             :       {
+    3128     4171792 :         destroy_range (copy_range (other.begin_ptr (), other.end_ptr (), begin_ptr ()),
+    3129             :                        end_ptr ());
+    3130             :       }
+    3131             : 
+    3132             :       // data_ptr and capacity do not change in this case.
+    3133             :       set_size (other.get_size ());
+    3134             :     }
+    3135             : 
+    3136             :     alloc_interface::operator= (other);
+    3137     4192048 :     return *this;
+    3138             :   }
+    3139             : 
+    3140             :   template <unsigned I, typename AT = alloc_traits,
+    3141             :             typename std::enable_if<AT::propagate_on_container_copy_assignment::value
+    3142             : #ifdef PLUMED_GCH_LIB_IS_ALWAYS_EQUAL
+    3143             :                                     &&! AT::is_always_equal::value
+    3144             : #endif
+    3145             :                                     >::type * = nullptr>
+    3146             :   PLUMED_GCH_CPP20_CONSTEXPR
+    3147             :   small_vector_base&
+    3148             :   copy_assign (const small_vector_base<Allocator, I>& other)
+    3149             :   {
+    3150             :     if (other.allocator_ref () == allocator_ref ())
+    3151             :       return copy_assign_default (other);
+    3152             : 
+    3153             :     if (InlineCapacity < other.get_size ())
+    3154             :     {
+    3155             :       alloc_interface new_alloc (other);
+    3156             : 
+    3157             :       const size_ty new_capacity = other.get_size ();
+    3158             :       const ptr new_data_ptr = new_alloc.allocate_with_hint (
+    3159             :                                  new_capacity,
+    3160             :                                  other.allocation_end_ptr ());
+    3161             : 
+    3162             :       PLUMED_GCH_TRY
+    3163             :       {
+    3164             :         uninitialized_copy (other.begin_ptr (), other.end_ptr (), new_data_ptr);
+    3165             :       }
+    3166             :       PLUMED_GCH_CATCH (...)
+    3167             :       {
+    3168             :         new_alloc.deallocate (new_data_ptr, new_capacity);
+    3169             :         PLUMED_GCH_THROW;
+    3170             :       }
+    3171             : 
+    3172             :       reset_data (new_data_ptr, new_capacity, other.get_size ());
+    3173             :       alloc_interface::operator= (new_alloc);
+    3174             :     }
+    3175             :     else
+    3176             :     {
+    3177             :       if (has_allocation ())
+    3178             :       {
+    3179             : #ifdef PLUMED_GCH_LIB_IS_CONSTANT_EVALUATED
+    3180             :         ptr new_data_ptr;
+    3181             :         if (std::is_constant_evaluated ())
+    3182             :         {
+    3183             :           alloc_interface new_alloc (other);
+    3184             :           new_data_ptr = new_alloc.allocate (InlineCapacity);
+    3185             :         }
+    3186             :         else
+    3187             :           new_data_ptr = storage_ptr ();
+    3188             : #else
+    3189             :         const ptr new_data_ptr = storage_ptr ();
+    3190             : #endif
+    3191             : 
+    3192             :         uninitialized_copy (other.begin_ptr (), other.end_ptr (), new_data_ptr);
+    3193             :         destroy_range (begin_ptr (), end_ptr ());
+    3194             :         deallocate (data_ptr (), get_capacity ());
+    3195             :         set_data_ptr (new_data_ptr);
+    3196             :         set_capacity (InlineCapacity);
+    3197             :       }
+    3198             :       else if (get_size () < other.get_size ())
+    3199             :       {
+    3200             :         std::copy_n (other.begin_ptr (), get_size (), begin_ptr ());
+    3201             :         uninitialized_copy (
+    3202             :           unchecked_next (other.begin_ptr (), get_size ()),
+    3203             :           other.end_ptr (),
+    3204             :           end_ptr ());
+    3205             :       }
+    3206             :       else
+    3207             :       {
+    3208             :         destroy_range (copy_range (other.begin_ptr (), other.end_ptr (), begin_ptr ()),
+    3209             :                        end_ptr ());
+    3210             :       }
+    3211             :       set_size (other.get_size ());
+    3212             :       alloc_interface::operator= (other);
+    3213             :     }
+    3214             : 
+    3215             :     return *this;
+    3216             :   }
+    3217             : 
+    3218             :   template <unsigned I, typename AT = alloc_traits,
+    3219             :             typename std::enable_if<! AT::propagate_on_container_copy_assignment::value
+    3220             : #ifdef PLUMED_GCH_LIB_IS_ALWAYS_EQUAL
+    3221             :                                     ||  AT::is_always_equal::value
+    3222             : #endif
+    3223             :                                     >::type * = nullptr>
+    3224             :   PLUMED_GCH_CPP20_CONSTEXPR
+    3225             :   small_vector_base&
+    3226             :   copy_assign (const small_vector_base<Allocator, I>& other)
+    3227             :   {
+    3228             :     return copy_assign_default (other);
+    3229             :   }
+    3230             : 
+    3231             :   template <unsigned I>
+    3232             :   PLUMED_GCH_CPP20_CONSTEXPR
+    3233             :   void
+    3234             :   move_allocation_pointer (small_vector_base<alloc_ty, I>&& other) noexcept
+    3235             :   {
+    3236             :     reset_data (other.data_ptr (), other.get_capacity (), other.get_size ());
+    3237             :     other.set_default ();
+    3238             :   }
+    3239             : 
+    3240             :   template <unsigned N = InlineCapacity, typename std::enable_if<N == 0>::type * = nullptr>
+    3241             :   PLUMED_GCH_CPP20_CONSTEXPR
+    3242             :   small_vector_base&
+    3243             :   move_assign_default (small_vector_base&& other) noexcept
+    3244             :   {
+    3245             :     move_allocation_pointer (std::move (other));
+    3246             :     alloc_interface::operator= (std::move (other));
+    3247             :     return *this;
+    3248             :   }
+    3249             : 
+    3250             :   template <unsigned LessEqualI,
+    3251             :             typename std::enable_if<(LessEqualI <= InlineCapacity)>::type * = nullptr>
+    3252             :             PLUMED_GCH_CPP20_CONSTEXPR
+    3253             :             small_vector_base&
+    3254             :             move_assign_default (small_vector_base<Allocator, LessEqualI>&& other)
+    3255             :             noexcept (std::is_nothrow_move_assignable<value_ty>::value
+    3256             :                       &&  std::is_nothrow_move_constructible<value_ty>::value)
+    3257             :   {
+    3258             :     // We only move the allocation pointer over if it has strictly greater capacity than
+    3259             :     // the inline capacity of `*this` because allocations can never have a smaller capacity
+    3260             :     // than the inline capacity.
+    3261             :     if (InlineCapacity < other.get_capacity ())
+    3262             :           move_allocation_pointer (std::move (other));
+    3263             :     else
+    3264             :     {
+    3265             :       // We are guaranteed to have sufficient capacity to store the elements.
+    3266             :       if (InlineCapacity < get_capacity ())
+    3267             :       {
+    3268             : #ifdef PLUMED_GCH_LIB_IS_CONSTANT_EVALUATED
+    3269             :         ptr new_data_ptr;
+    3270             :         if (std::is_constant_evaluated ())
+    3271             :           new_data_ptr = other.allocate (InlineCapacity);
+    3272             :         else
+    3273             :           new_data_ptr = storage_ptr ();
+    3274             : #else
+    3275             :         const ptr new_data_ptr = storage_ptr ();
+    3276             : #endif
+    3277             : 
+    3278             :         uninitialized_move (other.begin_ptr (), other.end_ptr (), new_data_ptr);
+    3279             :         destroy_range (begin_ptr (), end_ptr ());
+    3280             :         deallocate (data_ptr (), get_capacity ());
+    3281             :         set_data_ptr (new_data_ptr);
+    3282             :         set_capacity (InlineCapacity);
+    3283             :       }
+    3284             :       else if (get_size () < other.get_size ())
+    3285             :       {
+    3286             :         // There are more elements in `other`.
+    3287             :         // Overwrite the existing range and uninitialized move the rest.
+    3288             :         ptr other_pivot = unchecked_next (other.begin_ptr (), get_size ());
+    3289             :         std::move (other.begin_ptr (), other_pivot, begin_ptr ());
+    3290             :         uninitialized_move (other_pivot, other.end_ptr (), end_ptr ());
+    3291             :       }
+    3292             :       else
+    3293             :       {
+    3294             :         // There are the same number or fewer elements in `other`.
+    3295             :         // Overwrite part of the existing range and destroy the rest.
+    3296             :         ptr new_end = std::move (other.begin_ptr (), other.end_ptr (), begin_ptr ());
+    3297             :         destroy_range (new_end, end_ptr ());
+    3298             :       }
+    3299             : 
+    3300             :       set_size (other.get_size ());
+    3301             : 
+    3302             :       // Note: We do not need to deallocate any allocations in `other` because the value of
+    3303             :       //       an object meeting the Allocator named requirements does not change value after
+    3304             :       //       a move.
+    3305             :     }
+    3306             : 
+    3307             :     alloc_interface::operator= (std::move (other));
+    3308             :     return *this;
+    3309             :   }
+    3310             : 
+    3311             :   template <unsigned GreaterI,
+    3312             :             typename std::enable_if<(InlineCapacity < GreaterI)>::type * = nullptr>
+    3313             :             PLUMED_GCH_CPP20_CONSTEXPR
+    3314             :             small_vector_base&
+    3315             :             move_assign_default (small_vector_base<Allocator, GreaterI>&& other)
+    3316             :   {
+    3317             :     if (other.has_allocation ())
+    3318             :       move_allocation_pointer (std::move (other));
+    3319             :     else if (get_capacity () < other.get_size ()
+    3320             :              ||  (has_allocation () && ! (other.allocator_ref () == allocator_ref ())))
+    3321             :     {
+    3322             :       // Reallocate.
+    3323             : 
+    3324             :       // The compiler should be able to optimize this.
+    3325             :       size_ty new_capacity =
+    3326             :         get_capacity () < other.get_size ()
+    3327             :         ? unchecked_calculate_new_capacity (other.get_size ())
+    3328             :         : get_capacity ();
+    3329             : 
+    3330             :       ptr new_data_ptr = other.allocate_with_hint (new_capacity, other.allocation_end_ptr ());
+    3331             : 
+    3332             :       PLUMED_GCH_TRY
+    3333             :       {
+    3334             :         uninitialized_move (other.begin_ptr (), other.end_ptr (), new_data_ptr);
+    3335             :       }
+    3336             :       PLUMED_GCH_CATCH (...)
+    3337             :       {
+    3338             :         other.deallocate (new_data_ptr, new_capacity);
+    3339             :         PLUMED_GCH_THROW;
+    3340             :       }
+    3341             : 
+    3342             :       reset_data (new_data_ptr, new_capacity, other.get_size ());
+    3343             :     }
+    3344             :     else
+    3345             :     {
+    3346             :       if (get_size () < other.get_size ())
+    3347             :       {
+    3348             :         // There are more elements in `other`.
+    3349             :         // Overwrite the existing range and uninitialized move the rest.
+    3350             :         ptr other_pivot = unchecked_next (other.begin_ptr (), get_size ());
+    3351             :         std::move (other.begin_ptr (), other_pivot, begin_ptr ());
+    3352             :         uninitialized_move (other_pivot, other.end_ptr (), end_ptr ());
+    3353             :       }
+    3354             :       else
+    3355             :       {
+    3356             :         // fewer elements in other
+    3357             :         // overwrite part of the existing range and destroy the rest
+    3358             :         ptr new_end = std::move (other.begin_ptr (), other.end_ptr (), begin_ptr ());
+    3359             :         destroy_range (new_end, end_ptr ());
+    3360             :       }
+    3361             : 
+    3362             :       // `data_ptr` and `capacity` do not change in this case.
+    3363             :       set_size (other.get_size ());
+    3364             :     }
+    3365             : 
+    3366             :     alloc_interface::operator= (std::move (other));
+    3367             :     return *this;
+    3368             :   }
+    3369             : 
+    3370             :   template <unsigned I>
+    3371             :   PLUMED_GCH_CPP20_CONSTEXPR
+    3372             :   small_vector_base&
+    3373             :   move_assign_unequal_no_propagate (small_vector_base<Allocator, I>&& other)
+    3374             :   {
+    3375             :     if (get_capacity () < other.get_size ())
+    3376             :     {
+    3377             :       // Reallocate.
+    3378             :       size_ty new_capacity = unchecked_calculate_new_capacity (other.get_size ());
+    3379             :       ptr     new_data_ptr = unchecked_allocate (new_capacity, other.allocation_end_ptr ());
+    3380             : 
+    3381             :       PLUMED_GCH_TRY
+    3382             :       {
+    3383             :         uninitialized_move (other.begin_ptr (), other.end_ptr (), new_data_ptr);
+    3384             :       }
+    3385             :       PLUMED_GCH_CATCH (...)
+    3386             :       {
+    3387             :         deallocate (new_data_ptr, new_capacity);
+    3388             :         PLUMED_GCH_THROW;
+    3389             :       }
+    3390             : 
+    3391             :       reset_data (new_data_ptr, new_capacity, other.get_size ());
+    3392             :     }
+    3393             :     else
+    3394             :     {
+    3395             :       if (get_size () < other.get_size ())
+    3396             :       {
+    3397             :         // There are more elements in `other`.
+    3398             :         // Overwrite the existing range and uninitialized move the rest.
+    3399             :         ptr other_pivot = unchecked_next (other.begin_ptr (), get_size ());
+    3400             :         std::move (other.begin_ptr (), other_pivot, begin_ptr ());
+    3401             :         uninitialized_move (other_pivot, other.end_ptr (), end_ptr ());
+    3402             :       }
+    3403             :       else
+    3404             :       {
+    3405             :         // There are fewer elements in `other`.
+    3406             :         // Overwrite part of the existing range and destroy the rest.
+    3407             :         destroy_range (
+    3408             :           std::move (other.begin_ptr (), other.end_ptr (), begin_ptr ()),
+    3409             :           end_ptr ());
+    3410             :       }
+    3411             : 
+    3412             :       // data_ptr and capacity do not change in this case
+    3413             :       set_size (other.get_size ());
+    3414             :     }
+    3415             : 
+    3416             :     alloc_interface::operator= (std::move (other));
+    3417             :     return *this;
+    3418             :   }
+    3419             : 
+    3420             :   template <unsigned I, typename A = alloc_ty,
+    3421             :             typename std::enable_if<allocations_are_movable<A>::value>::type * = nullptr>
+    3422             :   PLUMED_GCH_CPP20_CONSTEXPR
+    3423             :   small_vector_base&
+    3424             :   move_assign (small_vector_base<Allocator, I>&& other)
+    3425             :   noexcept (noexcept (
+    3426             :               std::declval<small_vector_base&> ().move_assign_default (std::move (other))))
+    3427             :   {
+    3428             :     return move_assign_default (std::move (other));
+    3429             :   }
+    3430             : 
+    3431             :   template <unsigned I, typename A = alloc_ty,
+    3432             :             typename std::enable_if<! allocations_are_movable<A>::value>::type * = nullptr>
+    3433             :   PLUMED_GCH_CPP20_CONSTEXPR
+    3434             :   small_vector_base&
+    3435             :   move_assign (small_vector_base<Allocator, I>&& other)
+    3436             :   {
+    3437             :     if (other.allocator_ref () == allocator_ref ())
+    3438             :       return move_assign_default (std::move (other));
+    3439             :     return move_assign_unequal_no_propagate (std::move (other));
+    3440             :   }
+    3441             : 
+    3442             :   template <unsigned I = InlineCapacity,
+    3443             :             typename std::enable_if<I == 0>::type * = nullptr>
+    3444             :   PLUMED_GCH_CPP20_CONSTEXPR
+    3445             :   void
+    3446             :   move_initialize (small_vector_base&& other) noexcept
+    3447             :   {
+    3448             :     set_data (other.data_ptr (), other.get_capacity (), other.get_size ());
+    3449             :     other.set_default ();
+    3450             :   }
+    3451             : 
+    3452             :   template <unsigned LessEqualI,
+    3453             :             typename std::enable_if<(LessEqualI <= InlineCapacity)>::type * = nullptr>
+    3454             :             PLUMED_GCH_CPP20_CONSTEXPR
+    3455             :             void
+    3456             :             move_initialize (small_vector_base<Allocator, LessEqualI>&& other)
+    3457             :             noexcept (std::is_nothrow_move_constructible<value_ty>::value)
+    3458             :   {
+    3459             :     if (InlineCapacity < other.get_capacity ())
+    3460             :     {
+    3461             :       set_data (other.data_ptr (), other.get_capacity (), other.get_size ());
+    3462             :       other.set_default ();
+    3463             :     }
+    3464             :     else
+    3465             :     {
+    3466             :       set_to_inline_storage ();
+    3467             :       uninitialized_move (other.begin_ptr (), other.end_ptr (), data_ptr ());
+    3468             :       set_size (other.get_size ());
+    3469             :     }
+    3470             :   }
+    3471             : 
+    3472             :   template <unsigned GreaterI,
+    3473             :             typename std::enable_if<(InlineCapacity < GreaterI)>::type * = nullptr>
+    3474             :             PLUMED_GCH_CPP20_CONSTEXPR
+    3475             :             void
+    3476             :             move_initialize (small_vector_base<Allocator, GreaterI>&& other)
+    3477             :   {
+    3478             :     if (other.has_allocation ())
+    3479             :     {
+    3480             :       set_data (other.data_ptr (), other.get_capacity (), other.get_size ());
+    3481             :       other.set_default ();
+    3482             :     }
+    3483             :     else
+    3484             :     {
+    3485             :       if (InlineCapacity < other.get_size ())
+    3486             :       {
+    3487             :         // We may throw in this case.
+    3488             :         set_data_ptr (unchecked_allocate (other.get_size (), other.allocation_end_ptr ()));
+    3489             :         set_capacity (other.get_size ());
+    3490             : 
+    3491             :         PLUMED_GCH_TRY
+    3492             :         {
+    3493             :           uninitialized_move (other.begin_ptr (), other.end_ptr (), data_ptr ());
+    3494             :         }
+    3495             :         PLUMED_GCH_CATCH (...)
+    3496             :         {
+    3497             :           deallocate (data_ptr (), get_capacity ());
+    3498             :           PLUMED_GCH_THROW;
+    3499             :         }
+    3500             :       }
+    3501             :       else
+    3502             :       {
+    3503             :         set_to_inline_storage ();
+    3504             :         uninitialized_move (other.begin_ptr (), other.end_ptr (), data_ptr ());
+    3505             :       }
+    3506             : 
+    3507             :       set_size (other.get_size ());
+    3508             :     }
+    3509             :   }
+    3510             : 
+    3511             : public:
+    3512             : //    small_vector_base            (void)                         = impl;
+    3513             :   small_vector_base            (const small_vector_base&)     = delete;
+    3514             :   small_vector_base            (small_vector_base&&) noexcept = delete;
+    3515             :   small_vector_base& operator= (const small_vector_base&)     = delete;
+    3516             :   small_vector_base& operator= (small_vector_base&&) noexcept = delete;
+    3517             : //    ~small_vector_base           (void)                         = impl;
+    3518             : 
+    3519             :   PLUMED_GCH_CPP20_CONSTEXPR
+    3520     1600910 :   small_vector_base (void) noexcept
+    3521             :   {
+    3522             :     set_default ();
+    3523             :   }
+    3524             : 
+    3525             :   static constexpr struct bypass_tag { } bypass { };
+    3526             : 
+    3527             :   template <unsigned I, typename ...MaybeAlloc>
+    3528             :   PLUMED_GCH_CPP20_CONSTEXPR
+    3529             :   small_vector_base (bypass_tag,
+    3530             :                      const small_vector_base<Allocator, I>& other,
+    3531             :                      const MaybeAlloc&... alloc)
+    3532             :     : alloc_interface (other, alloc...)
+    3533             :   {
+    3534             :     if (InlineCapacity < other.get_size ())
+    3535             :     {
+    3536             :       set_data_ptr (unchecked_allocate (other.get_size (), other.allocation_end_ptr ()));
+    3537             :       set_capacity (other.get_size ());
+    3538             : 
+    3539             :       PLUMED_GCH_TRY
+    3540             :       {
+    3541             :         uninitialized_copy (other.begin_ptr (), other.end_ptr (), data_ptr ());
+    3542             :       }
+    3543             :       PLUMED_GCH_CATCH (...)
+    3544             :       {
+    3545             :         deallocate (data_ptr (), get_capacity ());
+    3546             :         PLUMED_GCH_THROW;
+    3547             :       }
+    3548             :     }
+    3549             :     else
+    3550             :     {
+    3551             :       set_to_inline_storage ();
+    3552             :       uninitialized_copy (other.begin_ptr (), other.end_ptr (), data_ptr ());
+    3553             :     }
+    3554             : 
+    3555             :     set_size (other.get_size ());
+    3556             :   }
+    3557             : 
+    3558             :   template <unsigned I>
+    3559             :   PLUMED_GCH_CPP20_CONSTEXPR
+    3560             :   small_vector_base (bypass_tag, small_vector_base<Allocator, I>&& other)
+    3561             :   noexcept (std::is_nothrow_move_constructible<value_ty>::value
+    3562             :             ||  (I == 0 && I == InlineCapacity))
+    3563             :     : alloc_interface (std::move (other))
+    3564             :   {
+    3565             :     move_initialize (std::move (other));
+    3566             :   }
+    3567             : 
+    3568             :   template <unsigned I, typename A = alloc_ty,
+    3569             :             typename std::enable_if<std::is_same<std::allocator<value_ty>, A>::value
+    3570             : #ifdef PLUMED_GCH_LIB_IS_ALWAYS_EQUAL
+    3571             :                                     ||  std::allocator_traits<A>::is_always_equal::value
+    3572             : #endif
+    3573             :                                     >::type * = nullptr>
+    3574             :   PLUMED_GCH_CPP20_CONSTEXPR
+    3575             :   small_vector_base (bypass_tag, small_vector_base<Allocator, I>&& other, const alloc_ty&)
+    3576             :   noexcept (noexcept (small_vector_base (bypass, std::move (other))))
+    3577             :     : small_vector_base (bypass, std::move (other))
+    3578             :   { }
+    3579             : 
+    3580             :   template <unsigned I, typename A = alloc_ty,
+    3581             :             typename std::enable_if<! (std::is_same<std::allocator<value_ty>, A>::value
+    3582             : #ifdef PLUMED_GCH_LIB_IS_ALWAYS_EQUAL
+    3583             :                                        ||  std::allocator_traits<A>::is_always_equal::value
+    3584             : #endif
+    3585             :                                                                 )>::type * = nullptr>
+    3586             :   PLUMED_GCH_CPP20_CONSTEXPR
+    3587             :   small_vector_base (bypass_tag, small_vector_base<Allocator, I>&& other, const alloc_ty& alloc)
+    3588             :     : alloc_interface (alloc)
+    3589             :   {
+    3590             :     if (other.allocator_ref () == alloc)
+    3591             :     {
+    3592             :       move_initialize (std::move (other));
+    3593             :       return;
+    3594             :     }
+    3595             : 
+    3596             :     if (InlineCapacity < other.get_size ())
+    3597             :     {
+    3598             :       // We may throw in this case.
+    3599             :       set_data_ptr (unchecked_allocate (other.get_size (), other.allocation_end_ptr ()));
+    3600             :       set_capacity (other.get_size ());
+    3601             : 
+    3602             :       PLUMED_GCH_TRY
+    3603             :       {
+    3604             :         uninitialized_move (other.begin_ptr (), other.end_ptr (), data_ptr ());
+    3605             :       }
+    3606             :       PLUMED_GCH_CATCH (...)
+    3607             :       {
+    3608             :         deallocate (data_ptr (), get_capacity ());
+    3609             :         PLUMED_GCH_THROW;
+    3610             :       }
+    3611             :     }
+    3612             :     else
+    3613             :     {
+    3614             :       set_to_inline_storage ();
+    3615             :       uninitialized_move (other.begin_ptr (), other.end_ptr (), data_ptr ());
+    3616             :     }
+    3617             : 
+    3618             :     set_size (other.get_size ());
+    3619             :   }
+    3620             : 
+    3621             :   PLUMED_GCH_CPP20_CONSTEXPR explicit
+    3622             :   small_vector_base (const alloc_ty& alloc) noexcept
+    3623             :     : alloc_interface (alloc)
+    3624             :   {
+    3625             :     set_default ();
+    3626             :   }
+    3627             : 
+    3628             :   PLUMED_GCH_CPP20_CONSTEXPR
+    3629        3711 :   small_vector_base (size_ty count, const alloc_ty& alloc)
+    3630             :     : alloc_interface (alloc)
+    3631             :   {
+    3632        3711 :     if (InlineCapacity < count)
+    3633             :     {
+    3634           0 :       set_data_ptr (checked_allocate (count));
+    3635             :       set_capacity (count);
+    3636             :     }
+    3637             :     else
+    3638             :       set_to_inline_storage ();
+    3639             : 
+    3640             :     PLUMED_GCH_TRY
+    3641             :     {
+    3642        3711 :       uninitialized_value_construct (begin_ptr (), unchecked_next (begin_ptr (), count));
+    3643             :     }
+    3644             :     PLUMED_GCH_CATCH (...)
+    3645             :     {
+    3646             :       if (has_allocation ())
+    3647             :         deallocate (data_ptr (), get_capacity ());
+    3648             :       PLUMED_GCH_THROW;
+    3649             :     }
+    3650             :     set_size (count);
+    3651        3711 :   }
+    3652             : 
+    3653             :   PLUMED_GCH_CPP20_CONSTEXPR
+    3654             :   small_vector_base (size_ty count, const value_ty& val, const alloc_ty& alloc)
+    3655             :     : alloc_interface (alloc)
+    3656             :   {
+    3657             :     if (InlineCapacity < count)
+    3658             :     {
+    3659             :       set_data_ptr (checked_allocate (count));
+    3660             :       set_capacity (count);
+    3661             :     }
+    3662             :     else
+    3663             :       set_to_inline_storage ();
+    3664             : 
+    3665             :     PLUMED_GCH_TRY
+    3666             :     {
+    3667             :       uninitialized_fill (begin_ptr (), unchecked_next (begin_ptr (), count), val);
+    3668             :     }
+    3669             :     PLUMED_GCH_CATCH (...)
+    3670             :     {
+    3671             :       if (has_allocation ())
+    3672             :         deallocate (data_ptr (), get_capacity ());
+    3673             :       PLUMED_GCH_THROW;
+    3674             :     }
+    3675             :     set_size (count);
+    3676             :   }
+    3677             : 
+    3678             :   template <typename Generator>
+    3679             :   PLUMED_GCH_CPP20_CONSTEXPR
+    3680             :   small_vector_base (size_ty count, Generator& g, const alloc_ty& alloc)
+    3681             :     : alloc_interface (alloc)
+    3682             :   {
+    3683             :     if (InlineCapacity < count)
+    3684             :     {
+    3685             :       set_data_ptr (checked_allocate (count));
+    3686             :       set_capacity (count);
+    3687             :     }
+    3688             :     else
+    3689             :       set_to_inline_storage ();
+    3690             : 
+    3691             :     ptr curr = begin_ptr ();
+    3692             :     const ptr new_end = unchecked_next (begin_ptr (), count);
+    3693             :     PLUMED_GCH_TRY
+    3694             :     {
+    3695             :       for (; ! (curr == new_end); ++curr)
+    3696             :         construct (curr, g ());
+    3697             :     }
+    3698             :     PLUMED_GCH_CATCH (...)
+    3699             :     {
+    3700             :       destroy_range (begin_ptr (), curr);
+    3701             :       if (has_allocation ())
+    3702             :         deallocate (data_ptr (), get_capacity ());
+    3703             :       PLUMED_GCH_THROW;
+    3704             :     }
+    3705             :     set_size (count);
+    3706             :   }
+    3707             : 
+    3708             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    3709             :   template <std::input_iterator InputIt>
+    3710             : #else
+    3711             :   template <typename InputIt>
+    3712             : #endif
+    3713             :   PLUMED_GCH_CPP20_CONSTEXPR
+    3714             :   small_vector_base (InputIt first, InputIt last, std::input_iterator_tag,
+    3715             :                      const alloc_ty& alloc)
+    3716             :     : small_vector_base (alloc)
+    3717             :   {
+    3718             :     using iterator_cat = typename std::iterator_traits<InputIt>::iterator_category;
+    3719             :     append_range (first, last, iterator_cat { });
+    3720             :   }
+    3721             : 
+    3722             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    3723             :   template <std::forward_iterator ForwardIt>
+    3724             : #else
+    3725             :   template <typename ForwardIt>
+    3726             : #endif
+    3727             :   PLUMED_GCH_CPP20_CONSTEXPR
+    3728             :   small_vector_base (ForwardIt first, ForwardIt last, std::forward_iterator_tag,
+    3729             :                      const alloc_ty& alloc)
+    3730             :     : alloc_interface (alloc)
+    3731             :   {
+    3732             :     size_ty count = external_range_length (first, last);
+    3733             :     if (InlineCapacity < count)
+    3734             :     {
+    3735             :       set_data_ptr (unchecked_allocate (count));
+    3736             :       set_capacity (count);
+    3737             :       PLUMED_GCH_TRY
+    3738             :       {
+    3739             :         uninitialized_copy (first, last, begin_ptr ());
+    3740             :       }
+    3741             :       PLUMED_GCH_CATCH (...)
+    3742             :       {
+    3743             :         deallocate (data_ptr (), get_capacity ());
+    3744             :         PLUMED_GCH_THROW;
+    3745             :       }
+    3746             :     }
+    3747             :     else
+    3748             :     {
+    3749             :       set_to_inline_storage ();
+    3750             :       uninitialized_copy (first, last, begin_ptr ());
+    3751             :     }
+    3752             : 
+    3753             :     set_size (count);
+    3754             :   }
+    3755             : 
+    3756             :   PLUMED_GCH_CPP20_CONSTEXPR
+    3757             :   ~small_vector_base (void) noexcept
+    3758             :   {
+    3759             :     assert (InlineCapacity <= get_capacity () && "Invalid capacity.");
+    3760     1422020 :     wipe ();
+    3761             :   }
+    3762             : 
+    3763             : protected:
+    3764             : 
+    3765             :   PLUMED_GCH_CPP20_CONSTEXPR
+    3766             :   void
+    3767             :   set_to_inline_storage (void)
+    3768             :   {
+    3769             :     set_capacity (InlineCapacity);
+    3770             : #ifdef PLUMED_GCH_LIB_IS_CONSTANT_EVALUATED
+    3771             :     if (std::is_constant_evaluated ())
+    3772             :       return set_data_ptr (alloc_interface::allocate (InlineCapacity));
+    3773             : #endif
+    3774             :     set_data_ptr (storage_ptr ());
+    3775        3711 :   }
+    3776             : 
+    3777             :   PLUMED_GCH_CPP20_CONSTEXPR
+    3778             :   void
+    3779             :   assign_with_copies (size_ty count, const value_ty& val)
+    3780             :   {
+    3781             :     if (get_capacity () < count)
+    3782             :     {
+    3783             :       size_ty new_capacity = checked_calculate_new_capacity (count);
+    3784             :       ptr     new_begin    = unchecked_allocate (new_capacity);
+    3785             : 
+    3786             :       PLUMED_GCH_TRY
+    3787             :       {
+    3788             :         uninitialized_fill (new_begin, unchecked_next (new_begin, count), val);
+    3789             :       }
+    3790             :       PLUMED_GCH_CATCH (...)
+    3791             :       {
+    3792             :         deallocate (new_begin, new_capacity);
+    3793             :         PLUMED_GCH_THROW;
+    3794             :       }
+    3795             : 
+    3796             :       reset_data (new_begin, new_capacity, count);
+    3797             :     }
+    3798             :     else if (get_size () < count)
+    3799             :     {
+    3800             :       std::fill (begin_ptr (), end_ptr (), val);
+    3801             :       uninitialized_fill (end_ptr (), unchecked_next (begin_ptr (), count), val);
+    3802             :       set_size (count);
+    3803             :     }
+    3804             :     else
+    3805             :       erase_range (std::fill_n (begin_ptr (), count, val), end_ptr ());
+    3806             :   }
+    3807             : 
+    3808             :   template <typename InputIt,
+    3809             :             typename std::enable_if<std::is_assignable<
+    3810             :                                       value_ty&,
+    3811             :                                       decltype (*std::declval<InputIt> ())>::value>::type * = nullptr>
+    3812             :   PLUMED_GCH_CPP20_CONSTEXPR
+    3813             :   void
+    3814             :   assign_with_range (InputIt first, InputIt last, std::input_iterator_tag)
+    3815             :   {
+    3816             :     using iterator_cat = typename std::iterator_traits<InputIt>::iterator_category;
+    3817             : 
+    3818             :     ptr curr = begin_ptr ();
+    3819             :     for (; ! (end_ptr () == curr || first == last); ++curr, static_cast<void> (++first))
+    3820             :       *curr = *first;
+    3821             : 
+    3822             :     if (first == last)
+    3823             :       erase_to_end (curr);
+    3824             :     else
+    3825             :       append_range (first, last, iterator_cat { });
+    3826             :   }
+    3827             : 
+    3828             :   template <typename ForwardIt,
+    3829             :             typename std::enable_if<std::is_assignable<
+    3830             :                                       value_ty&,
+    3831             :                                       decltype (*std::declval<ForwardIt> ())>::value>::type * = nullptr>
+    3832             :   PLUMED_GCH_CPP20_CONSTEXPR
+    3833             :   void
+    3834             :   assign_with_range (ForwardIt first, ForwardIt last, std::forward_iterator_tag)
+    3835             :   {
+    3836             :     const size_ty count = external_range_length (first, last);
+    3837             :     if (get_capacity () < count)
+    3838             :     {
+    3839             :       size_ty new_capacity = checked_calculate_new_capacity (count);
+    3840             :       ptr     new_begin    = unchecked_allocate (new_capacity);
+    3841             : 
+    3842             :       PLUMED_GCH_TRY
+    3843             :       {
+    3844             :         uninitialized_copy (first, last, new_begin);
+    3845             :       }
+    3846             :       PLUMED_GCH_CATCH (...)
+    3847             :       {
+    3848             :         deallocate (new_begin, new_capacity);
+    3849             :         PLUMED_GCH_THROW;
+    3850             :       }
+    3851             : 
+    3852             :       reset_data (new_begin, new_capacity, count);
+    3853             :     }
+    3854             :     else if (get_size () < count)
+    3855             :     {
+    3856             :       ForwardIt pivot = copy_n_return_in (first, get_size (), begin_ptr ());
+    3857             :       uninitialized_copy (pivot, last, end_ptr ());
+    3858             :       set_size (count);
+    3859             :     }
+    3860             :     else
+    3861             :       erase_range (copy_range (first, last, begin_ptr ()), end_ptr ());
+    3862             :   }
+    3863             : 
+    3864             :   template <typename InputIt,
+    3865             :             typename std::enable_if<! std::is_assignable<
+    3866             :                                       value_ty&,
+    3867             :                                       decltype (*std::declval<InputIt> ())>::value>::type * = nullptr>
+    3868             :   PLUMED_GCH_CPP20_CONSTEXPR
+    3869             :   void
+    3870             :   assign_with_range (InputIt first, InputIt last, std::input_iterator_tag)
+    3871             :   {
+    3872             :     using iterator_cat = typename std::iterator_traits<InputIt>::iterator_category;
+    3873             : 
+    3874             :     // If not assignable then destroy all elements and append.
+    3875             :     erase_all ();
+    3876             :     append_range (first, last, iterator_cat { });
+    3877             :   }
+    3878             : 
+    3879             :   // Ie. move-if-noexcept.
+    3880             :   struct strong_exception_policy
+    3881             :   { };
+    3882             : 
+    3883             :   template <typename Policy = void, typename V = value_ty,
+    3884             :             typename std::enable_if<is_explicitly_move_insertable<V>::value
+    3885             :                                     &&  (! std::is_same<Policy, strong_exception_policy>::value
+    3886             :                                          ||  relocate_with_move<V>::value),
+    3887             :                                     bool>::type = true>
+    3888             :   PLUMED_GCH_CPP20_CONSTEXPR
+    3889             :   ptr
+    3890             :   uninitialized_move (ptr first, ptr last, ptr d_first)
+    3891             :   noexcept (std::is_nothrow_move_constructible<value_ty>::value)
+    3892             :   {
+    3893             :     return uninitialized_copy (std::make_move_iterator (first),
+    3894             :                                std::make_move_iterator (last),
+    3895             :                                d_first);
+    3896             :   }
+    3897             : 
+    3898             :   template <typename Policy = void, typename V = value_ty,
+    3899             :             typename std::enable_if<! is_explicitly_move_insertable<V>::value
+    3900             :                                     ||  (  std::is_same<Policy, strong_exception_policy>::value
+    3901             :                                         &&! relocate_with_move<V>::value),
+    3902             :                                     bool>::type = false>
+    3903             :   PLUMED_GCH_CPP20_CONSTEXPR
+    3904             :   ptr
+    3905             :   uninitialized_move (ptr first, ptr last, ptr d_first)
+    3906             :   noexcept (alloc_interface::template is_uninitialized_memcpyable_iterator<ptr>::value)
+    3907             :   {
+    3908             :     return uninitialized_copy (first, last, d_first);
+    3909             :   }
+    3910             : 
+    3911             :   PLUMED_GCH_CPP20_CONSTEXPR
+    3912             :   ptr
+    3913             :   shift_into_uninitialized (ptr pos, size_ty n_shift)
+    3914             :   {
+    3915             :     // Shift elements over to the right into uninitialized space.
+    3916             :     // Returns the start of the shifted range.
+    3917             :     // Precondition: shift < end_ptr () - pos
+    3918             :     assert (n_shift != 0 && "The value of `n_shift` should not be 0.");
+    3919             : 
+    3920             :     const ptr original_end = end_ptr ();
+    3921             :     const ptr pivot        = unchecked_prev (original_end, n_shift);
+    3922             : 
+    3923             :     uninitialized_move (pivot, original_end, original_end);
+    3924             :     increase_size (n_shift);
+    3925             :     return move_right (pos, pivot, original_end);
+    3926             :   }
+    3927             : 
+    3928             :   template <typename ...Args>
+    3929             :   PLUMED_GCH_CPP20_CONSTEXPR
+    3930             :   ptr
+    3931     2134612 :   append_element (Args&&... args)
+    3932             :   {
+    3933     2134612 :     if (get_size () < get_capacity ())
+    3934     2133299 :           return emplace_into_current_end (std::forward<Args> (args)...);
+    3935        1313 :     return emplace_into_reallocation_end (std::forward<Args> (args)...);
+    3936             :   }
+    3937             : 
+    3938             :   PLUMED_GCH_CPP20_CONSTEXPR
+    3939             :   ptr
+    3940             :   append_copies (size_ty count, const value_ty& val)
+    3941             :   {
+    3942             :     if (num_uninitialized () < count)
+    3943             :     {
+    3944             :       // Reallocate.
+    3945             :       if (get_max_size () - get_size () < count)
+    3946             :         throw_allocation_size_error ();
+    3947             : 
+    3948             :       size_ty original_size = get_size ();
+    3949             :       size_ty new_size      = get_size () + count;
+    3950             : 
+    3951             :       // The check is handled by the if-guard.
+    3952             :       size_ty new_capacity = unchecked_calculate_new_capacity (new_size);
+    3953             :       ptr     new_data_ptr = unchecked_allocate (new_capacity, allocation_end_ptr ());
+    3954             :       ptr     new_last     = unchecked_next (new_data_ptr, original_size);
+    3955             : 
+    3956             :       PLUMED_GCH_TRY
+    3957             :       {
+    3958             :         new_last = uninitialized_fill (new_last, unchecked_next (new_last, count), val);
+    3959             :         uninitialized_move (begin_ptr (), end_ptr (), new_data_ptr);
+    3960             :       }
+    3961             :       PLUMED_GCH_CATCH (...)
+    3962             :       {
+    3963             :         destroy_range (unchecked_next (new_data_ptr, original_size), new_last);
+    3964             :         deallocate (new_data_ptr, new_capacity);
+    3965             :         PLUMED_GCH_THROW;
+    3966             :       }
+    3967             : 
+    3968             :       reset_data (new_data_ptr, new_capacity, new_size);
+    3969             :       return unchecked_next (new_data_ptr, original_size);
+    3970             :     }
+    3971             :     else
+    3972             :     {
+    3973             :       const ptr ret = end_ptr ();
+    3974             :       uninitialized_fill (ret, unchecked_next (ret, count), val);
+    3975             :       increase_size (count);
+    3976             :       return ret;
+    3977             :     }
+    3978             :   }
+    3979             : 
+    3980             :   template <typename MovePolicy, typename InputIt,
+    3981             :             typename std::enable_if<
+    3982             :               std::is_same<MovePolicy, strong_exception_policy>::value, bool>::type = true>
+    3983             :   PLUMED_GCH_CPP20_CONSTEXPR
+    3984             :   ptr
+    3985             :   append_range (InputIt first, InputIt last, std::input_iterator_tag)
+    3986             :   {
+    3987             :     // Append with a strong exception guarantee.
+    3988             :     size_ty original_size = get_size ();
+    3989             :     for (; ! (first == last); ++first)
+    3990             :     {
+    3991             :       PLUMED_GCH_TRY
+    3992             :       {
+    3993             :         append_element (*first);
+    3994             :       }
+    3995             :       PLUMED_GCH_CATCH (...)
+    3996             :       {
+    3997             :         erase_range (unchecked_next (begin_ptr (), original_size), end_ptr ());
+    3998             :         PLUMED_GCH_THROW;
+    3999             :       }
+    4000             :     }
+    4001             :     return unchecked_next (begin_ptr (), original_size);
+    4002             :   }
+    4003             : 
+    4004             :   template <typename MovePolicy = void, typename InputIt,
+    4005             :             typename std::enable_if<
+    4006             :               ! std::is_same<MovePolicy, strong_exception_policy>::value, bool>::type = false>
+    4007             :   PLUMED_GCH_CPP20_CONSTEXPR
+    4008             :   ptr
+    4009             :   append_range (InputIt first, InputIt last, std::input_iterator_tag)
+    4010             :   {
+    4011             :     size_ty original_size = get_size ();
+    4012             :     for (; ! (first == last); ++first)
+    4013             :       append_element (*first);
+    4014             :     return unchecked_next (begin_ptr (), original_size);
+    4015             :   }
+    4016             : 
+    4017             :   template <typename MovePolicy = void, typename ForwardIt>
+    4018             :   PLUMED_GCH_CPP20_CONSTEXPR
+    4019             :   ptr
+    4020             :   append_range (ForwardIt first, ForwardIt last, std::forward_iterator_tag)
+    4021             :   {
+    4022             :     const size_ty num_insert = external_range_length (first, last);
+    4023             : 
+    4024             :     if (num_uninitialized () < num_insert)
+    4025             :     {
+    4026             :       // Reallocate.
+    4027             :       if (get_max_size () - get_size () < num_insert)
+    4028             :         throw_allocation_size_error ();
+    4029             : 
+    4030             :       size_ty original_size = get_size ();
+    4031             :       size_ty new_size      = get_size () + num_insert;
+    4032             : 
+    4033             :       // The check is handled by the if-guard.
+    4034             :       size_ty new_capacity = unchecked_calculate_new_capacity (new_size);
+    4035             :       ptr     new_data_ptr = unchecked_allocate (new_capacity, allocation_end_ptr ());
+    4036             :       ptr     new_last     = unchecked_next (new_data_ptr, original_size);
+    4037             : 
+    4038             :       PLUMED_GCH_TRY
+    4039             :       {
+    4040             :         new_last = uninitialized_copy (first, last, new_last);
+    4041             :         uninitialized_move<MovePolicy> (begin_ptr (), end_ptr (), new_data_ptr);
+    4042             :       }
+    4043             :       PLUMED_GCH_CATCH (...)
+    4044             :       {
+    4045             :         destroy_range (unchecked_next (new_data_ptr, original_size), new_last);
+    4046             :         deallocate (new_data_ptr, new_capacity);
+    4047             :         PLUMED_GCH_THROW;
+    4048             :       }
+    4049             : 
+    4050             :       reset_data (new_data_ptr, new_capacity, new_size);
+    4051             :       return unchecked_next (new_data_ptr, original_size);
+    4052             :     }
+    4053             :     else
+    4054             :     {
+    4055             :       ptr ret = end_ptr ();
+    4056             :       uninitialized_copy (first, last, ret);
+    4057             :       increase_size (num_insert);
+    4058             :       return ret;
+    4059             :     }
+    4060             :   }
+    4061             : 
+    4062             :   template <typename ...Args>
+    4063             :   PLUMED_GCH_CPP20_CONSTEXPR
+    4064             :   ptr
+    4065             :   emplace_at (ptr pos, Args&&... args)
+    4066             :   {
+    4067             :     assert (get_size () <= get_capacity () && "size was greater than capacity");
+    4068             : 
+    4069             :     if (get_size () < get_capacity ())
+    4070             :       return emplace_into_current (pos, std::forward<Args> (args)...);
+    4071             :     return emplace_into_reallocation (pos, std::forward<Args> (args)...);
+    4072             :   }
+    4073             : 
+    4074             :   PLUMED_GCH_CPP20_CONSTEXPR
+    4075             :   ptr
+    4076             :   insert_copies (ptr pos, size_ty count, const value_ty& val)
+    4077             :   {
+    4078             :     if (0 == count)
+    4079             :       return pos;
+    4080             : 
+    4081             :     if (end_ptr () == pos)
+    4082             :     {
+    4083             :       if (1 == count)
+    4084             :         return append_element (val);
+    4085             :       return append_copies (count, val);
+    4086             :     }
+    4087             : 
+    4088             :     if (num_uninitialized () < count)
+    4089             :     {
+    4090             :       // Reallocate.
+    4091             :       if (get_max_size () - get_size () < count)
+    4092             :         throw_allocation_size_error ();
+    4093             : 
+    4094             :       const size_ty offset = internal_range_length (begin_ptr (), pos);
+    4095             : 
+    4096             :       const size_ty new_size = get_size () + count;
+    4097             : 
+    4098             :       // The check is handled by the if-guard.
+    4099             :       const size_ty new_capacity = unchecked_calculate_new_capacity (new_size);
+    4100             :       ptr new_data_ptr           = unchecked_allocate (new_capacity, allocation_end_ptr ());
+    4101             :       ptr new_first              = unchecked_next (new_data_ptr, offset);
+    4102             :       ptr new_last               = new_first;
+    4103             : 
+    4104             :       PLUMED_GCH_TRY
+    4105             :       {
+    4106             :         uninitialized_fill (new_first, unchecked_next (new_first, count), val);
+    4107             :         unchecked_advance  (new_last, count);
+    4108             : 
+    4109             :         uninitialized_move (begin_ptr (), pos, new_data_ptr);
+    4110             :         new_first = new_data_ptr;
+    4111             :         uninitialized_move (pos, end_ptr (), new_last);
+    4112             :       }
+    4113             :       PLUMED_GCH_CATCH (...)
+    4114             :       {
+    4115             :         destroy_range (new_first, new_last);
+    4116             :         deallocate (new_data_ptr, new_capacity);
+    4117             :         PLUMED_GCH_THROW;
+    4118             :       }
+    4119             : 
+    4120             :       reset_data (new_data_ptr, new_capacity, new_size);
+    4121             :       return unchecked_next (begin_ptr (), offset);
+    4122             :     }
+    4123             :     else
+    4124             :     {
+    4125             :       // If we have fewer to insert than tailing elements after `pos`, we shift into
+    4126             :       // uninitialized and then copy over.
+    4127             : 
+    4128             :       const size_ty tail_size = internal_range_length (pos, end_ptr ());
+    4129             :       if (tail_size < count)
+    4130             :       {
+    4131             :         // The number inserted is larger than the number after `pos`,
+    4132             :         // so part of the input will be used to construct new elements,
+    4133             :         // and another part of it will assign existing ones.
+    4134             :         // In order:
+    4135             :         //   Construct new elements immediately after end_ptr () using the input.
+    4136             :         //   Move-construct existing elements over to the tail.
+    4137             :         //   Assign existing elements using the input.
+    4138             : 
+    4139             :         ptr original_end = end_ptr ();
+    4140             : 
+    4141             :         // Place a portion of the input into the uninitialized section.
+    4142             :         size_ty num_val_tail = count - tail_size;
+    4143             : 
+    4144             : #ifdef PLUMED_GCH_LIB_IS_CONSTANT_EVALUATED
+    4145             :         if (std::is_constant_evaluated ())
+    4146             :         {
+    4147             :           uninitialized_fill (end_ptr (), unchecked_next (end_ptr (), num_val_tail), val);
+    4148             :           increase_size (num_val_tail);
+    4149             : 
+    4150             :           const heap_temporary tmp (*this, val);
+    4151             : 
+    4152             :           uninitialized_move (pos, original_end, end_ptr ());
+    4153             :           increase_size (tail_size);
+    4154             : 
+    4155             :           std::fill_n (pos, tail_size, tmp.get ());
+    4156             : 
+    4157             :           return pos;
+    4158             :         }
+    4159             : #endif
+    4160             : 
+    4161             :         uninitialized_fill (end_ptr (), unchecked_next (end_ptr (), num_val_tail), val);
+    4162             :         increase_size (num_val_tail);
+    4163             : 
+    4164             :         PLUMED_GCH_TRY
+    4165             :         {
+    4166             :           // We need to handle possible aliasing here.
+    4167             :           const stack_temporary tmp (*this, val);
+    4168             : 
+    4169             :           // Now, move the tail to the end.
+    4170             :           uninitialized_move (pos, original_end, end_ptr ());
+    4171             :           increase_size (tail_size);
+    4172             : 
+    4173             :           PLUMED_GCH_TRY
+    4174             :           {
+    4175             :             // Finally, try to copy the rest of the elements over.
+    4176             :             std::fill_n (pos, tail_size, tmp.get ());
+    4177             :           }
+    4178             :           PLUMED_GCH_CATCH (...)
+    4179             :           {
+    4180             :             // Attempt to roll back and destroy the tail if we fail.
+    4181             :             ptr inserted_end = unchecked_prev (end_ptr (), tail_size);
+    4182             :             move_left (inserted_end, end_ptr (), pos);
+    4183             :             destroy_range (inserted_end, end_ptr ());
+    4184             :             decrease_size (tail_size);
+    4185             :             PLUMED_GCH_THROW;
+    4186             :           }
+    4187             :         }
+    4188             :         PLUMED_GCH_CATCH (...)
+    4189             :         {
+    4190             :           // Destroy the elements constructed from the input.
+    4191             :           destroy_range (original_end, end_ptr ());
+    4192             :           decrease_size (internal_range_length (original_end, end_ptr ()));
+    4193             :           PLUMED_GCH_THROW;
+    4194             :         }
+    4195             :       }
+    4196             :       else
+    4197             :       {
+    4198             : #ifdef PLUMED_GCH_LIB_IS_CONSTANT_EVALUATED
+    4199             :         if (std::is_constant_evaluated ())
+    4200             :         {
+    4201             :           const heap_temporary tmp (*this, val);
+    4202             : 
+    4203             :           ptr inserted_end = shift_into_uninitialized (pos, count);
+    4204             :           std::fill (pos, inserted_end, tmp.get ());
+    4205             : 
+    4206             :           return pos;
+    4207             :         }
+    4208             : #endif
+    4209             :         const stack_temporary tmp (*this, val);
+    4210             : 
+    4211             :         ptr inserted_end = shift_into_uninitialized (pos, count);
+    4212             : 
+    4213             :         // Attempt to copy over the elements.
+    4214             :         // If we fail we'll attempt a full roll-back.
+    4215             :         PLUMED_GCH_TRY
+    4216             :         {
+    4217             :           std::fill (pos, inserted_end, tmp.get ());
+    4218             :         }
+    4219             :         PLUMED_GCH_CATCH (...)
+    4220             :         {
+    4221             :           ptr original_end = move_left (inserted_end, end_ptr (), pos);
+    4222             :           destroy_range (original_end, end_ptr ());
+    4223             :           decrease_size (count);
+    4224             :           PLUMED_GCH_THROW;
+    4225             :         }
+    4226             :       }
+    4227             :       return pos;
+    4228             :     }
+    4229             :   }
+    4230             : 
+    4231             :   template <typename ForwardIt>
+    4232             :   PLUMED_GCH_CPP20_CONSTEXPR
+    4233             :   ptr
+    4234             :   insert_range_helper (ptr pos, ForwardIt first, ForwardIt last)
+    4235             :   {
+    4236             :     assert (! (first == last) && "The range should not be empty.");
+    4237             :     assert (! (end_ptr () == pos) && "`pos` should not be at the end.");
+    4238             : 
+    4239             :     const size_ty num_insert = external_range_length (first, last);
+    4240             :     if (num_uninitialized () < num_insert)
+    4241             :     {
+    4242             :       // Reallocate.
+    4243             :       if (get_max_size () - get_size () < num_insert)
+    4244             :         throw_allocation_size_error ();
+    4245             : 
+    4246             :       const size_ty offset   = internal_range_length (begin_ptr (), pos);
+    4247             :       const size_ty new_size = get_size () + num_insert;
+    4248             : 
+    4249             :       // The check is handled by the if-guard.
+    4250             :       const size_ty new_capacity = unchecked_calculate_new_capacity (new_size);
+    4251             :       const ptr     new_data_ptr = unchecked_allocate (new_capacity, allocation_end_ptr ());
+    4252             :       ptr           new_first    = unchecked_next (new_data_ptr, offset);
+    4253             :       ptr           new_last     = new_first;
+    4254             : 
+    4255             :       PLUMED_GCH_TRY
+    4256             :       {
+    4257             :         uninitialized_copy (first, last, new_first);
+    4258             :         unchecked_advance  (new_last, num_insert);
+    4259             : 
+    4260             :         uninitialized_move (begin_ptr (), pos, new_data_ptr);
+    4261             :         new_first = new_data_ptr;
+    4262             :         uninitialized_move (pos, end_ptr (), new_last);
+    4263             :       }
+    4264             :       PLUMED_GCH_CATCH (...)
+    4265             :       {
+    4266             :         destroy_range (new_first, new_last);
+    4267             :         deallocate (new_data_ptr, new_capacity);
+    4268             :         PLUMED_GCH_THROW;
+    4269             :       }
+    4270             : 
+    4271             :       reset_data (new_data_ptr, new_capacity, new_size);
+    4272             :       return unchecked_next (begin_ptr (), offset);
+    4273             :     }
+    4274             :     else
+    4275             :     {
+    4276             :       // if we have fewer to insert than tailing elements after
+    4277             :       // `pos` we shift into uninitialized and then copy over
+    4278             :       const size_ty tail_size = internal_range_length (pos, end_ptr ());
+    4279             :       if (tail_size < num_insert)
+    4280             :       {
+    4281             :         // Use the same method as insert_copies.
+    4282             :         ptr original_end = end_ptr ();
+    4283             :         ForwardIt pivot  = unchecked_next (first, tail_size);
+    4284             : 
+    4285             :         // Place a portion of the input into the uninitialized section.
+    4286             :         uninitialized_copy (pivot, last, end_ptr ());
+    4287             :         increase_size (num_insert - tail_size);
+    4288             : 
+    4289             :         PLUMED_GCH_TRY
+    4290             :         {
+    4291             :           // Now move the tail to the end.
+    4292             :           uninitialized_move (pos, original_end, end_ptr ());
+    4293             :           increase_size (tail_size);
+    4294             : 
+    4295             :           PLUMED_GCH_TRY
+    4296             :           {
+    4297             :             // Finally, try to copy the rest of the elements over.
+    4298             :             copy_range (first, pivot, pos);
+    4299             :           }
+    4300             :           PLUMED_GCH_CATCH (...)
+    4301             :           {
+    4302             :             // Attempt to roll back and destroy the tail if we fail.
+    4303             :             ptr inserted_end = unchecked_prev (end_ptr (), tail_size);
+    4304             :             move_left (inserted_end, end_ptr (), pos);
+    4305             :             destroy_range (inserted_end, end_ptr ());
+    4306             :             decrease_size (tail_size);
+    4307             :             PLUMED_GCH_THROW;
+    4308             :           }
+    4309             :         }
+    4310             :         PLUMED_GCH_CATCH (...)
+    4311             :         {
+    4312             :           // If we throw, destroy the first copy we made.
+    4313             :           destroy_range (original_end, end_ptr ());
+    4314             :           decrease_size (internal_range_length (original_end, end_ptr ()));
+    4315             :           PLUMED_GCH_THROW;
+    4316             :         }
+    4317             :       }
+    4318             :       else
+    4319             :       {
+    4320             :         shift_into_uninitialized (pos, num_insert);
+    4321             : 
+    4322             :         // Attempt to copy over the elements.
+    4323             :         // If we fail we'll attempt a full roll-back.
+    4324             :         PLUMED_GCH_TRY
+    4325             :         {
+    4326             :           copy_range (first, last, pos);
+    4327             :         }
+    4328             :         PLUMED_GCH_CATCH (...)
+    4329             :         {
+    4330             :           ptr inserted_end = unchecked_next (pos, num_insert);
+    4331             :           ptr original_end = move_left (inserted_end, end_ptr (), pos);
+    4332             :           destroy_range (original_end, end_ptr ());
+    4333             :           decrease_size (num_insert);
+    4334             :           PLUMED_GCH_THROW;
+    4335             :         }
+    4336             :       }
+    4337             :       return pos;
+    4338             :     }
+    4339             :   }
+    4340             : 
+    4341             :   template <typename InputIt>
+    4342             :   PLUMED_GCH_CPP20_CONSTEXPR
+    4343             :   ptr
+    4344             :   insert_range (ptr pos, InputIt first, InputIt last, std::input_iterator_tag)
+    4345             :   {
+    4346             :     assert (! (first == last) && "The range should not be empty.");
+    4347             : 
+    4348             :     // Ensure we use this specific overload to give a strong exception guarantee for 1 element.
+    4349             :     if (end_ptr () == pos)
+    4350             :       return append_range (first, last, std::input_iterator_tag { });
+    4351             : 
+    4352             :     using iterator_cat = typename std::iterator_traits<InputIt>::iterator_category;
+    4353             :     small_vector_base tmp (first, last, iterator_cat { }, allocator_ref ());
+    4354             : 
+    4355             :     return insert_range_helper (
+    4356             :              pos,
+    4357             :              std::make_move_iterator (tmp.begin_ptr ()),
+    4358             :              std::make_move_iterator (tmp.end_ptr ()));
+    4359             :   }
+    4360             : 
+    4361             :   template <typename ForwardIt>
+    4362             :   PLUMED_GCH_CPP20_CONSTEXPR
+    4363             :   ptr
+    4364             :   insert_range (ptr pos, ForwardIt first, ForwardIt last, std::forward_iterator_tag)
+    4365             :   {
+    4366             :     if (! (end_ptr () == pos))
+    4367             :       return insert_range_helper (pos, first, last);
+    4368             : 
+    4369             :     if (unchecked_next (first) == last)
+    4370             :       return append_element (*first);
+    4371             : 
+    4372             :     using iterator_cat = typename std::iterator_traits<ForwardIt>::iterator_category;
+    4373             :     return append_range (first, last, iterator_cat { });
+    4374             :   }
+    4375             : 
+    4376             :   template <typename ...Args>
+    4377             :   PLUMED_GCH_CPP20_CONSTEXPR
+    4378             :   ptr
+    4379     2133299 :   emplace_into_current_end (Args&&... args)
+    4380             :   {
+    4381     2133299 :     construct (end_ptr (), std::forward<Args> (args)...);
+    4382             :     increase_size (1);
+    4383     2133299 :     return unchecked_prev (end_ptr ());
+    4384             :   }
+    4385             : 
+    4386             :   template <typename V = value_ty,
+    4387             :             typename std::enable_if<
+    4388             :               std::is_nothrow_move_constructible<V>::value>::type * = nullptr>
+    4389             :   PLUMED_GCH_CPP20_CONSTEXPR
+    4390             :   ptr
+    4391             :   emplace_into_current (ptr pos, value_ty&& val)
+    4392             :   {
+    4393             :     if (pos == end_ptr ())
+    4394             :       return emplace_into_current_end (std::move (val));
+    4395             : 
+    4396             :     // In the special case of value_ty&& we don't make a copy because behavior is unspecified
+    4397             :     // when it is an internal element. Hence, we'll take the opportunity to optimize and assume
+    4398             :     // that it isn't an internal element.
+    4399             :     shift_into_uninitialized (pos, 1);
+    4400             :     destroy (pos);
+    4401             :     construct (pos, std::move (val));
+    4402             :     return pos;
+    4403             :   }
+    4404             : 
+    4405             :   template <typename ...Args>
+    4406             :   PLUMED_GCH_CPP20_CONSTEXPR
+    4407             :   ptr
+    4408             :   emplace_into_current (ptr pos, Args&&... args)
+    4409             :   {
+    4410             :     if (pos == end_ptr ())
+    4411             :       return emplace_into_current_end (std::forward<Args> (args)...);
+    4412             : 
+    4413             : #ifdef PLUMED_GCH_LIB_IS_CONSTANT_EVALUATED
+    4414             :     if (std::is_constant_evaluated ())
+    4415             :     {
+    4416             :       heap_temporary tmp (*this, std::forward<Args> (args)...);
+    4417             :       shift_into_uninitialized (pos, 1);
+    4418             :       *pos = tmp.release ();
+    4419             :       return pos;
+    4420             :     }
+    4421             : #endif
+    4422             : 
+    4423             :     // This is necessary because of possible aliasing.
+    4424             :     stack_temporary tmp (*this, std::forward<Args> (args)...);
+    4425             :     shift_into_uninitialized (pos, 1);
+    4426             :     *pos = tmp.release ();
+    4427             :     return pos;
+    4428             :   }
+    4429             : 
+    4430             :   template <typename ...Args>
+    4431             :   PLUMED_GCH_CPP20_CONSTEXPR
+    4432             :   ptr
+    4433        1313 :   emplace_into_reallocation_end (Args&&... args)
+    4434             :   {
+    4435             :     // Appending; strong exception guarantee.
+    4436        1313 :     if (get_max_size () == get_size ())
+    4437           0 :       throw_allocation_size_error ();
+    4438             : 
+    4439        1313 :     const size_ty new_size = get_size () + 1;
+    4440             : 
+    4441             :     // The check is handled by the if-guard.
+    4442             :     const size_ty new_capacity = unchecked_calculate_new_capacity (new_size);
+    4443        1313 :     const ptr     new_data_ptr = unchecked_allocate (new_capacity, allocation_end_ptr ());
+    4444        1313 :     const ptr     emplace_pos  = unchecked_next (new_data_ptr, get_size ());
+    4445             : 
+    4446             :     PLUMED_GCH_TRY
+    4447             :     {
+    4448             :       construct (emplace_pos, std::forward<Args> (args)...);
+    4449             :       PLUMED_GCH_TRY
+    4450             :       {
+    4451        1313 :         uninitialized_move<strong_exception_policy> (begin_ptr (), end_ptr (), new_data_ptr);
+    4452             :       }
+    4453             :       PLUMED_GCH_CATCH (...)
+    4454             :       {
+    4455             :         destroy (emplace_pos);
+    4456             :         PLUMED_GCH_THROW;
+    4457             :       }
+    4458             :     }
+    4459             :     PLUMED_GCH_CATCH (...)
+    4460             :     {
+    4461             :       deallocate (new_data_ptr, new_capacity);
+    4462             :       PLUMED_GCH_THROW;
+    4463             :     }
+    4464             : 
+    4465             :     reset_data (new_data_ptr, new_capacity, new_size);
+    4466        1313 :     return emplace_pos;
+    4467             :   }
+    4468             : 
+    4469             :   template <typename ...Args>
+    4470             :   PLUMED_GCH_CPP20_CONSTEXPR
+    4471             :   ptr
+    4472             :   emplace_into_reallocation (ptr pos, Args&&... args)
+    4473             :   {
+    4474             :     const size_ty offset = internal_range_length (begin_ptr (), pos);
+    4475             :     if (offset == get_size ())
+    4476             :       return emplace_into_reallocation_end (std::forward<Args> (args)...);
+    4477             : 
+    4478             :     if (get_max_size () == get_size ())
+    4479             :       throw_allocation_size_error ();
+    4480             : 
+    4481             :     const size_ty new_size = get_size () + 1;
+    4482             : 
+    4483             :     // The check is handled by the if-guard.
+    4484             :     const size_ty new_capacity = unchecked_calculate_new_capacity (new_size);
+    4485             :     const ptr     new_data_ptr = unchecked_allocate (new_capacity, allocation_end_ptr ());
+    4486             :     ptr           new_first    = unchecked_next (new_data_ptr, offset);
+    4487             :     ptr           new_last     = new_first;
+    4488             : 
+    4489             :     PLUMED_GCH_TRY
+    4490             :     {
+    4491             :       construct (new_first, std::forward<Args> (args)...);
+    4492             :       unchecked_advance (new_last, 1);
+    4493             : 
+    4494             :       uninitialized_move (begin_ptr (), pos, new_data_ptr);
+    4495             :       new_first = new_data_ptr;
+    4496             :       uninitialized_move (pos, end_ptr (), new_last);
+    4497             :     }
+    4498             :     PLUMED_GCH_CATCH (...)
+    4499             :     {
+    4500             :       destroy_range (new_first, new_last);
+    4501             :       deallocate (new_data_ptr, new_capacity);
+    4502             :       PLUMED_GCH_THROW;
+    4503             :     }
+    4504             : 
+    4505             :     reset_data (new_data_ptr, new_capacity, new_size);
+    4506             :     return unchecked_next (begin_ptr (), offset);
+    4507             :   }
+    4508             : 
+    4509             :   PLUMED_GCH_CPP20_CONSTEXPR
+    4510             :   ptr
+    4511             :   shrink_to_size (void)
+    4512             :   {
+    4513             :     if (! has_allocation () || get_size () == get_capacity ())
+    4514             :       return begin_ptr ();
+    4515             : 
+    4516             :     // The rest runs only if allocated.
+    4517             : 
+    4518             :     size_ty new_capacity;
+    4519             :     ptr     new_data_ptr;
+    4520             : 
+    4521             :     if (InlineCapacity < get_size ())
+    4522             :     {
+    4523             :       new_capacity = get_size ();
+    4524             :       new_data_ptr = unchecked_allocate (new_capacity, allocation_end_ptr ());
+    4525             :     }
+    4526             :     else
+    4527             :     {
+    4528             :       // We move to inline storage.
+    4529             :       new_capacity = InlineCapacity;
+    4530             : #ifdef PLUMED_GCH_LIB_IS_CONSTANT_EVALUATED
+    4531             :       if (std::is_constant_evaluated ())
+    4532             :         new_data_ptr = alloc_interface::allocate (InlineCapacity);
+    4533             :       else
+    4534             :         new_data_ptr = storage_ptr ();
+    4535             : #else
+    4536             :       new_data_ptr = storage_ptr ();
+    4537             : #endif
+    4538             :     }
+    4539             : 
+    4540             :     uninitialized_move (begin_ptr (), end_ptr (), new_data_ptr);
+    4541             : 
+    4542             :     destroy_range (begin_ptr (), end_ptr ());
+    4543             :     deallocate (data_ptr (), get_capacity ());
+    4544             : 
+    4545             :     set_data_ptr (new_data_ptr);
+    4546             :     set_capacity (new_capacity);
+    4547             : 
+    4548             :     return begin_ptr ();
+    4549             :   }
+    4550             : 
+    4551             :   template <typename ...ValueT>
+    4552             :   PLUMED_GCH_CPP20_CONSTEXPR
+    4553             :   void
+    4554             :   resize_with (size_ty new_size, const ValueT&... val)
+    4555             :   {
+    4556             :     // ValueT... should either be value_ty or empty.
+    4557             : 
+    4558             :     if (new_size == 0)
+    4559             :       erase_all ();
+    4560             : 
+    4561             :     if (get_capacity () < new_size)
+    4562             :     {
+    4563             :       // Reallocate.
+    4564             : 
+    4565             :       if (get_max_size () < new_size)
+    4566             :         throw_allocation_size_error ();
+    4567             : 
+    4568             :       const size_ty original_size = get_size ();
+    4569             : 
+    4570             :       // The check is handled by the if-guard.
+    4571             :       const size_ty new_capacity = unchecked_calculate_new_capacity (new_size);
+    4572             :       ptr           new_data_ptr = unchecked_allocate (new_capacity, allocation_end_ptr ());
+    4573             :       ptr           new_last     = unchecked_next (new_data_ptr, original_size);
+    4574             : 
+    4575             :       PLUMED_GCH_TRY
+    4576             :       {
+    4577             :         new_last = uninitialized_fill (
+    4578             :           new_last,
+    4579             :           unchecked_next (new_data_ptr, new_size),
+    4580             :           val...);
+    4581             : 
+    4582             :         // Strong exception guarantee.
+    4583             :         uninitialized_move<strong_exception_policy> (begin_ptr (), end_ptr (), new_data_ptr);
+    4584             :       }
+    4585             :       PLUMED_GCH_CATCH (...)
+    4586             :       {
+    4587             :         destroy_range (unchecked_next (new_data_ptr, original_size), new_last);
+    4588             :         deallocate (new_data_ptr, new_capacity);
+    4589             :         PLUMED_GCH_THROW;
+    4590             :       }
+    4591             : 
+    4592             :       reset_data (new_data_ptr, new_capacity, new_size);
+    4593             :     }
+    4594             :     else if (get_size () < new_size)
+    4595             :     {
+    4596             :       // Construct in the uninitialized section.
+    4597             :       uninitialized_fill (end_ptr (), unchecked_next (begin_ptr (), new_size), val...);
+    4598             :       set_size (new_size);
+    4599             :     }
+    4600             :     else
+    4601             :       erase_range (unchecked_next (begin_ptr (), new_size), end_ptr ());
+    4602             : 
+    4603             :     // Do nothing if the count is the same as the current size.
+    4604             :   }
+    4605             : 
+    4606             :   PLUMED_GCH_CPP20_CONSTEXPR
+    4607             :   void
+    4608       49613 :   request_capacity (size_ty request)
+    4609             :   {
+    4610       49613 :     if (request <= get_capacity ())
+    4611             :       return;
+    4612             : 
+    4613        2344 :     size_ty new_capacity = checked_calculate_new_capacity (request);
+    4614             :     ptr     new_begin    = unchecked_allocate (new_capacity);
+    4615             : 
+    4616             :     PLUMED_GCH_TRY
+    4617             :     {
+    4618        2344 :       uninitialized_move<strong_exception_policy> (begin_ptr (), end_ptr (), new_begin);
+    4619             :     }
+    4620             :     PLUMED_GCH_CATCH (...)
+    4621             :     {
+    4622             :       deallocate (new_begin, new_capacity);
+    4623             :       PLUMED_GCH_THROW;
+    4624             :     }
+    4625             : 
+    4626        2344 :     wipe ();
+    4627             : 
+    4628             :     set_data_ptr (new_begin);
+    4629             :     set_capacity (new_capacity);
+    4630             :   }
+    4631             : 
+    4632             :   PLUMED_GCH_CPP20_CONSTEXPR
+    4633             :   ptr
+    4634             :   erase_at (ptr pos)
+    4635             :   {
+    4636             :     move_left (unchecked_next (pos), end_ptr (), pos);
+    4637             :     erase_last ();
+    4638             :     return pos;
+    4639             :   }
+    4640             : 
+    4641             :   PLUMED_GCH_CPP20_CONSTEXPR
+    4642             :   void
+    4643             :   erase_last (void)
+    4644             :   {
+    4645             :     decrease_size (1);
+    4646             : 
+    4647             :     // The element located at end_ptr is still alive since the size decreased.
+    4648      135205 :     destroy (end_ptr ());
+    4649             :   }
+    4650             : 
+    4651             :   PLUMED_GCH_CPP20_CONSTEXPR
+    4652             :   ptr
+    4653             :   erase_range (ptr first, ptr last)
+    4654             :   {
+    4655             :     if (! (first == last))
+    4656             :       erase_to_end (move_left (last, end_ptr (), first));
+    4657             :     return first;
+    4658             :   }
+    4659             : 
+    4660             :   PLUMED_GCH_CPP20_CONSTEXPR
+    4661             :   void
+    4662             :   erase_to_end (ptr pos)
+    4663             :   {
+    4664             :     assert (0 <= (end_ptr () - pos) && "`pos` was in the uninitialized range");
+    4665             :     if (size_ty change = internal_range_length (pos, end_ptr ()))
+    4666             :     {
+    4667             :       decrease_size (change);
+    4668             :       destroy_range (pos, unchecked_next (pos, change));
+    4669             :     }
+    4670             :   }
+    4671             : 
+    4672             :   PLUMED_GCH_CPP20_CONSTEXPR
+    4673             :   void
+    4674             :   erase_all (void)
+    4675             :   {
+    4676     1502998 :     ptr curr_end = end_ptr ();
+    4677             :     set_size (0);
+    4678             :     destroy_range (begin_ptr (), curr_end);
+    4679             :   }
+    4680             : 
+    4681             :   PLUMED_GCH_CPP20_CONSTEXPR
+    4682             :   void
+    4683             :   swap_elements (small_vector_base& other)
+    4684             :   noexcept (std::is_nothrow_move_constructible<value_ty>::value
+    4685             : #ifdef PLUMED_GCH_LIB_IS_SWAPPABLE
+    4686             :             &&  std::is_nothrow_swappable<value_ty>::value
+    4687             : #else
+    4688             :             &&  detail::small_vector_adl::is_nothrow_swappable<value_ty>::value
+    4689             : #endif
+    4690             :            )
+    4691             :   {
+    4692             :     assert (get_size () <= other.get_size ());
+    4693             : 
+    4694             :     const ptr other_tail = std::swap_ranges (begin_ptr (), end_ptr (), other.begin_ptr ());
+    4695             :     uninitialized_move (other_tail, other.end_ptr (), end_ptr ());
+    4696             :     destroy_range (other_tail, other.end_ptr ());
+    4697             : 
+    4698             :     swap_size (other);
+    4699             :   }
+    4700             : 
+    4701             :   PLUMED_GCH_CPP20_CONSTEXPR
+    4702             :   void
+    4703             :   swap_default (small_vector_base& other)
+    4704             :   noexcept (std::is_nothrow_move_constructible<value_ty>::value
+    4705             : #ifdef PLUMED_GCH_LIB_IS_SWAPPABLE
+    4706             :             &&  std::is_nothrow_swappable<value_ty>::value
+    4707             : #else
+    4708             :             &&  detail::small_vector_adl::is_nothrow_swappable<value_ty>::value
+    4709             : #endif
+    4710             :            )
+    4711             :   {
+    4712             :     // This function is used when:
+    4713             :     //   We are using the standard allocator.
+    4714             :     //   The allocators propagate and are equal.
+    4715             :     //   The allocators are always equal.
+    4716             :     //   The allocators do not propagate and are equal.
+    4717             :     //   The allocators propagate and are not equal.
+    4718             : 
+    4719             :     // Not handled:
+    4720             :     //   The allocators do not propagate and are not equal.
+    4721             : 
+    4722             :     assert (get_capacity () <= other.get_capacity ());
+    4723             : 
+    4724             :     if (has_allocation ()) // Implies that `other` also has an allocation.
+    4725             :       swap_allocation (other);
+    4726             :     else if (other.has_allocation ())
+    4727             :     {
+    4728             :       // Note: This will never be constant evaluated because both are always allocated.
+    4729             :       uninitialized_move (begin_ptr (), end_ptr (), other.storage_ptr ());
+    4730             :       destroy_range (begin_ptr (), end_ptr ());
+    4731             : 
+    4732             :       set_data_ptr (other.data_ptr ());
+    4733             :       set_capacity (other.get_capacity ());
+    4734             : 
+    4735             :       other.set_data_ptr (other.storage_ptr ());
+    4736             :       other.set_capacity (InlineCapacity);
+    4737             : 
+    4738             :       swap_size (other);
+    4739             :     }
+    4740             :     else if (get_size () < other.get_size ())
+    4741             :       swap_elements (other);
+    4742             :     else
+    4743             :       other.swap_elements (*this);
+    4744             : 
+    4745             :     alloc_interface::swap (other);
+    4746             :   }
+    4747             : 
+    4748             :   PLUMED_GCH_CPP20_CONSTEXPR
+    4749             :   void
+    4750             :   swap_unequal_no_propagate (small_vector_base& other)
+    4751             :   {
+    4752             :     assert (get_capacity () <= other.get_capacity ());
+    4753             : 
+    4754             :     if (get_capacity () < other.get_size ())
+    4755             :     {
+    4756             :       // Reallocation required.
+    4757             :       // We should always be able to reuse the allocation of `other`.
+    4758             :       const size_ty new_capacity = unchecked_calculate_new_capacity (other.get_size ());
+    4759             :       const ptr     new_data_ptr = unchecked_allocate (new_capacity, end_ptr ());
+    4760             : 
+    4761             :       PLUMED_GCH_TRY
+    4762             :       {
+    4763             :         uninitialized_move (other.begin_ptr (), other.end_ptr (), new_data_ptr);
+    4764             :         PLUMED_GCH_TRY
+    4765             :         {
+    4766             :           destroy_range (
+    4767             :             std::move (begin_ptr (), end_ptr (), other.begin_ptr ()),
+    4768             :             other.end_ptr ());
+    4769             :         }
+    4770             :         PLUMED_GCH_CATCH (...)
+    4771             :         {
+    4772             :           destroy_range (new_data_ptr, unchecked_next (new_data_ptr, other.get_size ()));
+    4773             :           PLUMED_GCH_THROW;
+    4774             :         }
+    4775             :       }
+    4776             :       PLUMED_GCH_CATCH (...)
+    4777             :       {
+    4778             :         deallocate (new_data_ptr, new_capacity);
+    4779             :         PLUMED_GCH_THROW;
+    4780             :       }
+    4781             : 
+    4782             :       destroy_range (begin_ptr (), end_ptr ());
+    4783             :       if (has_allocation ())
+    4784             :         deallocate (data_ptr (), get_capacity ());
+    4785             : 
+    4786             :       set_data_ptr (new_data_ptr);
+    4787             :       set_capacity (new_capacity);
+    4788             :       swap_size (other);
+    4789             :     }
+    4790             :     else if (get_size () < other.get_size ())
+    4791             :       swap_elements (other);
+    4792             :     else
+    4793             :       other.swap_elements (*this);
+    4794             : 
+    4795             :     // This should have no effect.
+    4796             :     alloc_interface::swap (other);
+    4797             :   }
+    4798             : 
+    4799             :   template <typename A = alloc_ty,
+    4800             :             typename std::enable_if<allocations_are_swappable<A>::value
+    4801             :                                     &&  InlineCapacity == 0>::type * = nullptr>
+    4802             :   PLUMED_GCH_CPP20_CONSTEXPR
+    4803             :   void
+    4804             :   swap (small_vector_base& other) noexcept
+    4805             :   {
+    4806             :     swap_allocation (other);
+    4807             :     alloc_interface::swap (other);
+    4808             :   }
+    4809             : 
+    4810             :   template <typename A = alloc_ty,
+    4811             :             typename std::enable_if<allocations_are_swappable<A>::value
+    4812             :                                     &&  InlineCapacity != 0>::type * = nullptr>
+    4813             :   PLUMED_GCH_CPP20_CONSTEXPR
+    4814             :   void
+    4815             :   swap (small_vector_base& other)
+    4816             :   noexcept (std::is_nothrow_move_constructible<value_ty>::value
+    4817             : #ifdef PLUMED_GCH_LIB_IS_SWAPPABLE
+    4818             :             &&  std::is_nothrow_swappable<value_ty>::value
+    4819             : #else
+    4820             :             &&  detail::small_vector_adl::is_nothrow_swappable<value_ty>::value
+    4821             : #endif
+    4822             :                                          )
+    4823             :   {
+    4824             :     if (get_capacity () < other.get_capacity ())
+    4825             :           swap_default (other);
+    4826             :     else
+    4827             :       other.swap_default (*this);
+    4828             :   }
+    4829             : 
+    4830             :   template <typename A = alloc_ty,
+    4831             :             typename std::enable_if<! allocations_are_swappable<A>::value>::type * = nullptr>
+    4832             :   PLUMED_GCH_CPP20_CONSTEXPR
+    4833             :   void
+    4834             :   swap (small_vector_base& other)
+    4835             :   {
+    4836             :     if (get_capacity () < other.get_capacity ())
+    4837             :     {
+    4838             :       if (other.allocator_ref () == allocator_ref ())
+    4839             :         swap_default (other);
+    4840             :       else
+    4841             :         swap_unequal_no_propagate (other);
+    4842             :     }
+    4843             :     else
+    4844             :     {
+    4845             :       if (other.allocator_ref () == allocator_ref ())
+    4846             :         other.swap_default (*this);
+    4847             :       else
+    4848             :         other.swap_unequal_no_propagate (*this);
+    4849             :     }
+    4850             :   }
+    4851             : 
+    4852             : #ifdef __GLIBCXX__
+    4853             : 
+    4854             :   // These are compatibility fixes for libstdc++ because std::copy doesn't work for
+    4855             :   // `move_iterator`s when constant evaluated.
+    4856             : 
+    4857             :   template <typename InputIt>
+    4858             :   static PLUMED_GCH_CPP20_CONSTEXPR
+    4859             :   InputIt
+    4860             :   unmove_iterator (InputIt it)
+    4861             :   {
+    4862             :     return it;
+    4863             :   }
+    4864             : 
+    4865             :   template <typename InputIt>
+    4866             :   static PLUMED_GCH_CPP20_CONSTEXPR
+    4867             :   auto
+    4868             :   unmove_iterator (std::move_iterator<InputIt> it)
+    4869             :   -> decltype (unmove_iterator (it.base ()))
+    4870             :   {
+    4871             :     return unmove_iterator (it.base ());
+    4872             :   }
+    4873             : 
+    4874             :   template <typename InputIt>
+    4875             :   static PLUMED_GCH_CPP20_CONSTEXPR
+    4876             :   auto
+    4877             :   unmove_iterator (std::reverse_iterator<InputIt> it)
+    4878             :   -> std::reverse_iterator<decltype (unmove_iterator (it.base ()))>
+    4879             :   {
+    4880             :     return std::reverse_iterator<decltype (unmove_iterator (it.base ()))> (
+    4881             :       unmove_iterator (it.base ()));
+    4882             :                                 }
+    4883             : 
+    4884             : #endif
+    4885             : 
+    4886             :   template <typename InputIt>
+    4887             :   PLUMED_GCH_CPP20_CONSTEXPR
+    4888             :   ptr
+    4889             :   copy_range (InputIt first, InputIt last, ptr dest)
+    4890             :   {
+    4891             : #if defined (PLUMED_GCH_LIB_IS_CONSTANT_EVALUATED) && defined (__GLIBCXX__)
+    4892             :     if (    std::is_constant_evaluated ()
+    4893             :             &&! std::is_same<decltype (unmove_iterator (std::declval<InputIt> ())),
+    4894             :                              InputIt>::value)
+    4895             :     {
+    4896             :       return std::move (unmove_iterator (first), unmove_iterator (last), dest);
+    4897             :     }
+    4898             : #endif
+    4899             : 
+    4900             :     return std::copy (first, last, dest);
+    4901             :   }
+    4902             : 
+    4903             :   template <typename InputIt,
+    4904             :             typename std::enable_if<
+    4905             :               is_memcpyable_iterator<InputIt>::value>::type * = nullptr>
+    4906             :   PLUMED_GCH_CPP20_CONSTEXPR
+    4907             :   InputIt
+    4908             :   copy_n_return_in (InputIt first, size_ty count, ptr dest) noexcept
+    4909             :   {
+    4910             : #ifdef PLUMED_GCH_LIB_IS_CONSTANT_EVALUATED
+    4911             :     if (std::is_constant_evaluated ())
+    4912             :     {
+    4913             :       std::copy_n (first, count, dest);
+    4914             :       return unchecked_next (first, count);
+    4915             :     }
+    4916             : #endif
+    4917             : 
+    4918             :     if (count != 0)
+    4919             :       std::memcpy (to_address (dest), to_address (first), count * sizeof (value_ty));
+    4920             :     // Note: The unsafe cast here should be proven to be safe in the caller function.
+    4921             :     return unchecked_next (first, count);
+    4922             :   }
+    4923             : 
+    4924             :   template <typename InputIt,
+    4925             :             typename std::enable_if<
+    4926             :               is_memcpyable_iterator<InputIt>::value>::type * = nullptr>
+    4927             :   PLUMED_GCH_CPP20_CONSTEXPR
+    4928             :   std::move_iterator<InputIt>
+    4929             :   copy_n_return_in (std::move_iterator<InputIt> first, size_ty count, ptr dest) noexcept
+    4930             :   {
+    4931             :     return std::move_iterator<InputIt> (copy_n_return_in (first.base (), count, dest));
+    4932             :   }
+    4933             : 
+    4934             :   template <typename RandomIt,
+    4935             :             typename std::enable_if<
+    4936             :               ! is_memcpyable_iterator<RandomIt>::value
+    4937             :               &&  std::is_base_of<std::random_access_iterator_tag,
+    4938             :                                   typename std::iterator_traits<RandomIt>::iterator_category>::value
+    4939             :               >::type * = nullptr>
+    4940             :   PLUMED_GCH_CPP20_CONSTEXPR
+    4941             :   RandomIt
+    4942             :   copy_n_return_in (RandomIt first, size_ty count, ptr dest)
+    4943             :   {
+    4944             : #if defined (PLUMED_GCH_LIB_IS_CONSTANT_EVALUATED) && defined (__GLIBCXX__)
+    4945             :     if (    std::is_constant_evaluated ()
+    4946             :             &&! std::is_same<decltype (unmove_iterator (std::declval<RandomIt> ())),
+    4947             :                              RandomIt>::value)
+    4948             :     {
+    4949             :       auto bfirst = unmove_iterator (first);
+    4950             :       auto blast  = unchecked_next (bfirst, count);
+    4951             :       std::move (bfirst, blast, dest);
+    4952             :       return unchecked_next (first, count);
+    4953             :     }
+    4954             : #endif
+    4955             : 
+    4956             :     std::copy_n (first, count, dest);
+    4957             :     // Note: This unsafe cast should be proven safe in the caller function.
+    4958             :     return unchecked_next (first, count);
+    4959             :   }
+    4960             : 
+    4961             :   template <typename InputIt,
+    4962             :             typename std::enable_if<
+    4963             :               ! is_memcpyable_iterator<InputIt>::value
+    4964             :               &&! std::is_base_of<std::random_access_iterator_tag,
+    4965             :                                   typename std::iterator_traits<InputIt>::iterator_category>::value
+    4966             :               >::type * = nullptr>
+    4967             :   PLUMED_GCH_CPP20_CONSTEXPR
+    4968             :   InputIt
+    4969             :   copy_n_return_in (InputIt first, size_ty count, ptr dest)
+    4970             :   {
+    4971             : 
+    4972             :     for (; count != 0; --count, static_cast<void> (++dest), static_cast<void> (++first))
+    4973             :       *dest = *first;
+    4974             :     return first;
+    4975             :   }
+    4976             : 
+    4977             :   template <typename V = value_ty,
+    4978             :             typename std::enable_if<is_memcpyable<V>::value>::type * = nullptr>
+    4979             :   PLUMED_GCH_CPP20_CONSTEXPR
+    4980             :   ptr
+    4981             :   move_left (ptr first, ptr last, ptr d_first)
+    4982             :   {
+    4983             :     // Shift initialized elements to the left.
+    4984             : 
+    4985             : #ifdef PLUMED_GCH_LIB_IS_CONSTANT_EVALUATED
+    4986             :     if (std::is_constant_evaluated ())
+    4987             :       return std::move (first, last, d_first);
+    4988             : #endif
+    4989             : 
+    4990             :     const size_ty num_moved = internal_range_length (first, last);
+    4991             :     if (num_moved != 0)
+    4992             :       std::memmove (to_address (d_first), to_address (first), num_moved * sizeof (value_ty));
+    4993             :     return unchecked_next (d_first, num_moved);
+    4994             :   }
+    4995             : 
+    4996             :   template <typename V = value_ty,
+    4997             :             typename std::enable_if<! is_memcpyable<V>::value>::type * = nullptr>
+    4998             :   PLUMED_GCH_CPP20_CONSTEXPR
+    4999             :   ptr
+    5000             :   move_left (ptr first, ptr last, ptr d_first)
+    5001             :   {
+    5002             :     // Shift initialized elements to the left.
+    5003             :     return std::move (first, last, d_first);
+    5004             :   }
+    5005             : 
+    5006             :   template <typename V = value_ty,
+    5007             :             typename std::enable_if<is_memcpyable<V>::value, bool>::type = true>
+    5008             :   PLUMED_GCH_CPP20_CONSTEXPR
+    5009             :   ptr
+    5010             :   move_right (ptr first, ptr last, ptr d_last)
+    5011             :   {
+    5012             :     // Move initialized elements to the right.
+    5013             : 
+    5014             : #ifdef PLUMED_GCH_LIB_IS_CONSTANT_EVALUATED
+    5015             :     if (std::is_constant_evaluated ())
+    5016             :       return std::move_backward (first, last, d_last);
+    5017             : #endif
+    5018             : 
+    5019             :     const size_ty num_moved = internal_range_length (first, last);
+    5020             :     const ptr     dest      = unchecked_prev (d_last, num_moved);
+    5021             :     if (num_moved != 0)
+    5022             :       std::memmove (to_address (dest), to_address (first), num_moved * sizeof (value_ty));
+    5023             :     return dest;
+    5024             :   }
+    5025             : 
+    5026             :   template <typename V = value_ty,
+    5027             :             typename std::enable_if<! is_memcpyable<V>::value, bool>::type = false>
+    5028             :   PLUMED_GCH_CPP20_CONSTEXPR
+    5029             :   ptr
+    5030             :   move_right (ptr first, ptr last, ptr d_last)
+    5031             :   {
+    5032             :     // move initialized elements to the right
+    5033             :     // n should not be 0
+    5034             :     return std::move_backward (first, last, d_last);
+    5035             :   }
+    5036             : 
+    5037             : public:
+    5038             :   PLUMED_GCH_CPP20_CONSTEXPR
+    5039             :   void
+    5040             :   set_default (void)
+    5041             :   {
+    5042             :     set_to_inline_storage ();
+    5043             :     set_size (0);
+    5044             :   }
+    5045             : 
+    5046             :   PLUMED_GCH_NODISCARD PLUMED_GCH_CPP14_CONSTEXPR
+    5047             :   ptr
+    5048             :   data_ptr (void) noexcept
+    5049             :   {
+    5050             :     return m_data.data_ptr ();
+    5051             :   }
+    5052             : 
+    5053             :   PLUMED_GCH_NODISCARD constexpr
+    5054             :   cptr
+    5055             :   data_ptr (void) const noexcept
+    5056             :   {
+    5057             :     return m_data.data_ptr ();
+    5058             :   }
+    5059             : 
+    5060             :   PLUMED_GCH_NODISCARD constexpr
+    5061             :   size_ty
+    5062             :   get_capacity (void) const noexcept
+    5063             :   {
+    5064             :     return m_data.capacity ();
+    5065             :   }
+    5066             : 
+    5067             :   PLUMED_GCH_NODISCARD constexpr
+    5068             :   size_ty
+    5069             :   get_size (void) const noexcept
+    5070             :   {
+    5071             :     return m_data.size ();
+    5072             :   }
+    5073             : 
+    5074             :   PLUMED_GCH_NODISCARD constexpr
+    5075             :   size_ty
+    5076             :   num_uninitialized (void) const noexcept
+    5077             :   {
+    5078             :     return get_capacity () - get_size ();
+    5079             :   }
+    5080             : 
+    5081             :   PLUMED_GCH_NODISCARD PLUMED_GCH_CPP14_CONSTEXPR
+    5082             :   ptr
+    5083             :   begin_ptr (void) noexcept
+    5084             :   {
+    5085             :     return data_ptr ();
+    5086             :   }
+    5087             : 
+    5088             :   PLUMED_GCH_NODISCARD
+    5089             :   constexpr
+    5090             :   cptr
+    5091             :   begin_ptr (void) const noexcept
+    5092             :   {
+    5093             :     return data_ptr ();
+    5094             :   }
+    5095             : 
+    5096             :   PLUMED_GCH_NODISCARD PLUMED_GCH_CPP14_CONSTEXPR
+    5097             :   ptr
+    5098    16572320 :   end_ptr (void) noexcept
+    5099             :   {
+    5100    16572320 :     return unchecked_next (begin_ptr (), get_size ());
+    5101             :   }
+    5102             : 
+    5103             :   PLUMED_GCH_NODISCARD constexpr
+    5104             :   cptr
+    5105     4192048 :   end_ptr (void) const noexcept
+    5106             :   {
+    5107     4192048 :     return unchecked_next (begin_ptr (), get_size ());
+    5108             :   }
+    5109             : 
+    5110             :   PLUMED_GCH_NODISCARD PLUMED_GCH_CPP14_CONSTEXPR
+    5111             :   ptr
+    5112        1313 :   allocation_end_ptr (void) noexcept
+    5113             :   {
+    5114        1313 :     return unchecked_next (begin_ptr (), get_capacity ());
+    5115             :   }
+    5116             : 
+    5117             :   PLUMED_GCH_NODISCARD constexpr
+    5118             :   cptr
+    5119           0 :   allocation_end_ptr (void) const noexcept
+    5120             :   {
+    5121           0 :     return unchecked_next (begin_ptr (), get_capacity ());
+    5122             :   }
+    5123             : 
+    5124             :   PLUMED_GCH_NODISCARD constexpr
+    5125             :   alloc_ty
+    5126             :   copy_allocator (void) const noexcept
+    5127             :   {
+    5128             :     return alloc_ty (allocator_ref ());
+    5129             :   }
+    5130             : 
+    5131             :   PLUMED_GCH_NODISCARD PLUMED_GCH_CPP14_CONSTEXPR
+    5132             :   ptr
+    5133             :   storage_ptr (void) noexcept
+    5134             :   {
+    5135             :     return m_data.storage ();
+    5136             :   }
+    5137             : 
+    5138             :   PLUMED_GCH_NODISCARD constexpr
+    5139             :   cptr
+    5140             :   storage_ptr (void) const noexcept
+    5141             :   {
+    5142             :     return m_data.storage ();
+    5143             :   }
+    5144             : 
+    5145             :   PLUMED_GCH_NODISCARD constexpr
+    5146             :   bool
+    5147             :   has_allocation (void) const noexcept
+    5148             :   {
+    5149             : #ifdef PLUMED_GCH_LIB_IS_CONSTANT_EVALUATED
+    5150             :     if (std::is_constant_evaluated ())
+    5151             :       return true;
+    5152             : #endif
+    5153             :     return InlineCapacity < get_capacity ();
+    5154             :   }
+    5155             : 
+    5156             :   PLUMED_GCH_NODISCARD constexpr
+    5157             :   bool
+    5158             :   is_inlinable (void) const noexcept
+    5159             :   {
+    5160             :     return get_size () <= InlineCapacity;
+    5161             :   }
+    5162             : 
+    5163             : private:
+    5164             :   small_vector_data<ptr, size_type, value_ty, InlineCapacity> m_data;
+    5165             : };
+    5166             : 
+    5167             : } // namespace gch::detail
+    5168             : 
+    5169             : template <typename T, unsigned InlineCapacity, typename Allocator>
+    5170             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5171             : requires concepts::small_vector::AllocatorFor<Allocator, T>
+    5172             : #endif
+    5173             : class small_vector
+    5174             : : private detail::small_vector_base<Allocator, InlineCapacity>
+    5175             : {
+    5176             :   using base = detail::small_vector_base<Allocator, InlineCapacity>;
+    5177             : 
+    5178             : public:
+    5179             :   static_assert (std::is_same<T, typename Allocator::value_type>::value,
+    5180             :                  "`Allocator::value_type` must be the same as `T`.");
+    5181             : 
+    5182             :   template <typename SameT, unsigned DifferentInlineCapacity, typename SameAllocator>
+    5183             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5184             :   requires concepts::small_vector::AllocatorFor<SameAllocator, SameT>
+    5185             : #endif
+    5186             :   friend class small_vector;
+    5187             : 
+    5188             :   using value_type             = T;
+    5189             :   using allocator_type         = Allocator;
+    5190             :   using size_type              = typename base::size_type;
+    5191             :   using difference_type        = typename base::difference_type;
+    5192             :   using reference              =       value_type&;
+    5193             :   using const_reference        = const value_type&;
+    5194             :   using pointer                = typename std::allocator_traits<allocator_type>::pointer;
+    5195             :   using const_pointer          = typename std::allocator_traits<allocator_type>::const_pointer;
+    5196             : 
+    5197             :   using iterator               = small_vector_iterator<pointer, difference_type>;
+    5198             :   using const_iterator         = small_vector_iterator<const_pointer, difference_type>;
+    5199             :   using reverse_iterator       = std::reverse_iterator<iterator>;
+    5200             :   using const_reverse_iterator = std::reverse_iterator<const_iterator>;
+    5201             : 
+    5202             :   static_assert (InlineCapacity <= (std::numeric_limits<size_type>::max) (),
+    5203             :                  "InlineCapacity must be less than or equal to the maximum value of size_type.");
+    5204             : 
+    5205             :   static constexpr
+    5206             :   unsigned
+    5207             :   inline_capacity_v = InlineCapacity;
+    5208             : 
+    5209             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5210             : 
+    5211             : private:
+    5212             :   static constexpr
+    5213             :   bool
+    5214             :   Destructible = concepts::small_vector::Destructible<value_type>;
+    5215             : 
+    5216             :   static constexpr
+    5217             :   bool
+    5218             :   MoveAssignable = concepts::small_vector::MoveAssignable<value_type>;
+    5219             : 
+    5220             :   static constexpr
+    5221             :   bool
+    5222             :   CopyAssignable = concepts::small_vector::CopyAssignable<value_type>;
+    5223             : 
+    5224             :   static constexpr
+    5225             :   bool
+    5226             :   MoveConstructible = concepts::small_vector::MoveConstructible<value_type>;
+    5227             : 
+    5228             :   static constexpr
+    5229             :   bool
+    5230             :   CopyConstructible = concepts::small_vector::CopyConstructible<value_type>;
+    5231             : 
+    5232             :   static constexpr
+    5233             :   bool
+    5234             :   Swappable = concepts::small_vector::Swappable<value_type>;
+    5235             : 
+    5236             :   static constexpr
+    5237             :   bool
+    5238             :   DefaultInsertable = concepts::small_vector::DefaultInsertable<value_type, small_vector,
+    5239             :   allocator_type>;
+    5240             : 
+    5241             :   static constexpr
+    5242             :   bool
+    5243             :   MoveInsertable = concepts::small_vector::MoveInsertable<value_type, small_vector,
+    5244             :   allocator_type>;
+    5245             : 
+    5246             :   static constexpr
+    5247             :   bool
+    5248             :   CopyInsertable = concepts::small_vector::CopyInsertable<value_type, small_vector,
+    5249             :   allocator_type>;
+    5250             : 
+    5251             :   static constexpr
+    5252             :   bool
+    5253             :   Erasable = concepts::small_vector::Erasable<value_type, small_vector, allocator_type>;
+    5254             : 
+    5255             :   template <typename ...Args>
+    5256             :   struct EmplaceConstructible
+    5257             :   {
+    5258             :     static constexpr
+    5259             :     bool
+    5260             :     value = concepts::small_vector::EmplaceConstructible<value_type, small_vector,
+    5261             :         allocator_type, Args...>;
+    5262             :                                                         };
+    5263             : 
+    5264             : public:
+    5265             : 
+    5266             : #endif
+    5267             : 
+    5268             :   PLUMED_GCH_CPP20_CONSTEXPR
+    5269             :   small_vector (void)
+    5270             :   noexcept (noexcept (allocator_type ()))
+    5271             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5272             :   requires concepts::DefaultConstructible<allocator_type>
+    5273             : #endif
+    5274             :     = default;
+    5275             : 
+    5276             :   PLUMED_GCH_CPP20_CONSTEXPR
+    5277             :   small_vector (const small_vector& other)
+    5278             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5279             :   requires CopyInsertable
+    5280             : #endif
+    5281             : : base (base::bypass, other)
+    5282             :   { }
+    5283             : 
+    5284             :   PLUMED_GCH_CPP20_CONSTEXPR
+    5285             :   small_vector (small_vector&& other)
+    5286             :   noexcept (std::is_nothrow_move_constructible<value_type>::value || InlineCapacity == 0)
+    5287             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5288             :   requires MoveInsertable
+    5289             : #endif
+    5290             : : base (base::bypass, std::move (other))
+    5291             :   { }
+    5292             : 
+    5293             :   PLUMED_GCH_CPP20_CONSTEXPR explicit
+    5294             :   small_vector (const allocator_type& alloc) noexcept
+    5295             :     : base (alloc)
+    5296             :   { }
+    5297             : 
+    5298             :   PLUMED_GCH_CPP20_CONSTEXPR
+    5299             :   small_vector (const small_vector& other, const allocator_type& alloc)
+    5300             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5301             :   requires CopyInsertable
+    5302             : #endif
+    5303             : : base (base::bypass, other, alloc)
+    5304             :   { }
+    5305             : 
+    5306             :   PLUMED_GCH_CPP20_CONSTEXPR
+    5307             :   small_vector (small_vector&& other, const allocator_type& alloc)
+    5308             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5309             :   requires MoveInsertable
+    5310             : #endif
+    5311             : : base (base::bypass, std::move (other), alloc)
+    5312             :   { }
+    5313             : 
+    5314             :   PLUMED_GCH_CPP20_CONSTEXPR explicit
+    5315        3711 :   small_vector (size_type count, const allocator_type& alloc = allocator_type ())
+    5316             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5317             :   requires DefaultInsertable
+    5318             : #endif
+    5319        3711 : : base (count, alloc)
+    5320             :   { }
+    5321             : 
+    5322             :   PLUMED_GCH_CPP20_CONSTEXPR
+    5323             :   small_vector (size_type count, const_reference value,
+    5324             :                 const allocator_type& alloc = allocator_type ())
+    5325             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5326             :   requires CopyInsertable
+    5327             : #endif
+    5328             : : base (count, value, alloc)
+    5329             :   { }
+    5330             : 
+    5331             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5332             :   template <typename Generator>
+    5333             :   requires std::invocable<Generator&>
+    5334             :   &&  EmplaceConstructible<std::invoke_result_t<Generator&>>::value
+    5335             : #else
+    5336             :   template <typename Generator,
+    5337             :             typename std::enable_if<
+    5338             :               ! std::is_convertible<Generator, const_reference>::value>::type * = nullptr>
+    5339             : #endif
+    5340             :   PLUMED_GCH_CPP20_CONSTEXPR
+    5341             :   small_vector (size_type count, Generator g, const allocator_type& alloc = allocator_type ())
+    5342             :     : base (count, g, alloc)
+    5343             :   { }
+    5344             : 
+    5345             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5346             :   template <std::input_iterator InputIt>
+    5347             :   requires EmplaceConstructible<std::iter_reference_t<InputIt>>::value
+    5348             :   &&  (std::forward_iterator<InputIt> || MoveInsertable)
+    5349             : #else
+    5350             :   template <typename InputIt,
+    5351             :             typename std::enable_if<
+    5352             :               std::is_base_of<
+    5353             :                 std::input_iterator_tag,
+    5354             :                 typename std::iterator_traits<InputIt>::iterator_category>::value
+    5355             :               >::type * = nullptr>
+    5356             : #endif
+    5357             :   PLUMED_GCH_CPP20_CONSTEXPR
+    5358             :   small_vector (InputIt first, InputIt last, const allocator_type& alloc = allocator_type ())
+    5359             :     : base (first, last, typename std::iterator_traits<InputIt>::iterator_category { }, alloc)
+    5360             :   { }
+    5361             : 
+    5362             :   PLUMED_GCH_CPP20_CONSTEXPR
+    5363             :   small_vector (std::initializer_list<value_type> init,
+    5364             :                 const allocator_type& alloc = allocator_type ())
+    5365             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5366             :   requires EmplaceConstructible<const_reference>::value
+    5367             : #endif
+    5368             : : small_vector (init.begin (), init.end (), alloc)
+    5369             :   { }
+    5370             : 
+    5371             :   template <unsigned I>
+    5372             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5373             :   requires CopyInsertable
+    5374             : #endif
+    5375             :   PLUMED_GCH_CPP20_CONSTEXPR explicit
+    5376             :   small_vector (const small_vector<T, I, Allocator>& other)
+    5377             :     : base (base::bypass, other)
+    5378             :   { }
+    5379             : 
+    5380             :   template <unsigned I>
+    5381             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5382             :   requires MoveInsertable
+    5383             : #endif
+    5384             :   PLUMED_GCH_CPP20_CONSTEXPR explicit
+    5385             :   small_vector (small_vector<T, I, Allocator>&& other)
+    5386             :   noexcept (std::is_nothrow_move_constructible<value_type>::value && I < InlineCapacity)
+    5387             :               : base (base::bypass, std::move (other))
+    5388             :   { }
+    5389             : 
+    5390             :   template <unsigned I>
+    5391             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5392             :   requires CopyInsertable
+    5393             : #endif
+    5394             :   PLUMED_GCH_CPP20_CONSTEXPR
+    5395             :   small_vector (const small_vector<T, I, Allocator>& other, const allocator_type& alloc)
+    5396             :     : base (base::bypass, other, alloc)
+    5397             :   { }
+    5398             : 
+    5399             :   template <unsigned I>
+    5400             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5401             :   requires MoveInsertable
+    5402             : #endif
+    5403             :   PLUMED_GCH_CPP20_CONSTEXPR
+    5404             :   small_vector (small_vector<T, I, Allocator>&& other, const allocator_type& alloc)
+    5405             :     : base (base::bypass, std::move (other), alloc)
+    5406             :   { }
+    5407             : 
+    5408             :   PLUMED_GCH_CPP20_CONSTEXPR
+    5409     1422020 :   ~small_vector (void)
+    5410             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5411             :   requires Erasable
+    5412             : #endif
+    5413             :     = default;
+    5414             : 
+    5415             :   PLUMED_GCH_CPP20_CONSTEXPR
+    5416             :   small_vector&
+    5417             :   operator= (const small_vector& other)
+    5418             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5419             :   requires CopyInsertable && CopyAssignable
+    5420             : #endif
+    5421             :   {
+    5422             :     assign (other);
+    5423             :     return *this;
+    5424             :   }
+    5425             : 
+    5426             :   PLUMED_GCH_CPP20_CONSTEXPR
+    5427             :   small_vector&
+    5428             :   operator= (small_vector&& other)
+    5429             :   noexcept (  (  std::is_same<std::allocator<value_type>, Allocator>::value
+    5430             :                  ||  std::allocator_traits<Allocator>::propagate_on_container_move_assignment::value
+    5431             : #ifdef PLUMED_GCH_LIB_IS_ALWAYS_EQUAL
+    5432             :                  ||  std::allocator_traits<Allocator>::is_always_equal::value
+    5433             : #endif
+    5434             :               )
+    5435             :               &&  (  (  std::is_nothrow_move_assignable<value_type>::value
+    5436             :                         &&  std::is_nothrow_move_constructible<value_type>::value
+    5437             :                      )
+    5438             :                      ||  InlineCapacity == 0
+    5439             :                   )
+    5440             :            )
+    5441             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5442             :   // Note: The standard says here that
+    5443             :   // std::allocator_traits<allocator_type>::propagate_on_container_move_assignment == false
+    5444             :   // implies MoveInsertable && MoveAssignable, but since we have inline storage we must always
+    5445             :   // require moves [tab:container.alloc.req].
+    5446             :   requires MoveInsertable && MoveAssignable
+    5447             : #endif
+    5448             :   {
+    5449             :     assign (std::move (other));
+    5450             :     return *this;
+    5451             :   }
+    5452             : 
+    5453             :   PLUMED_GCH_CPP20_CONSTEXPR
+    5454             :   small_vector&
+    5455             :   operator= (std::initializer_list<value_type> ilist)
+    5456             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5457             :   requires CopyInsertable && CopyAssignable
+    5458             : #endif
+    5459             :   {
+    5460             :     assign (ilist);
+    5461             :     return *this;
+    5462             :   }
+    5463             : 
+    5464             :   PLUMED_GCH_CPP20_CONSTEXPR
+    5465             :   void
+    5466             :   assign (size_type count, const_reference value)
+    5467             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5468             :   requires CopyInsertable && CopyAssignable
+    5469             : #endif
+    5470             :   {
+    5471             :     base::assign_with_copies (count, value);
+    5472             :   }
+    5473             : 
+    5474             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5475             :   template <std::input_iterator InputIt>
+    5476             :   requires EmplaceConstructible<std::iter_reference_t<InputIt>>::value
+    5477             :   &&  (std::forward_iterator<InputIt> || MoveInsertable)
+    5478             : #else
+    5479             :   template <typename InputIt,
+    5480             :             typename std::enable_if<std::is_base_of<
+    5481             :                                       std::input_iterator_tag,
+    5482             :                                       typename std::iterator_traits<InputIt>::iterator_category
+    5483             :                                       >::value>::type * = nullptr>
+    5484             : #endif
+    5485             :   PLUMED_GCH_CPP20_CONSTEXPR
+    5486             :   void
+    5487             :   assign (InputIt first, InputIt last)
+    5488             :   {
+    5489             :     using iterator_cat = typename std::iterator_traits<InputIt>::iterator_category;
+    5490             :     base::assign_with_range (first, last, iterator_cat { });
+    5491             :   }
+    5492             : 
+    5493             :   PLUMED_GCH_CPP20_CONSTEXPR
+    5494             :   void
+    5495             :   assign (std::initializer_list<value_type> ilist)
+    5496             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5497             :   requires EmplaceConstructible<const_reference>::value
+    5498             : #endif
+    5499             :   {
+    5500             :     assign (ilist.begin (), ilist.end ());
+    5501             :   }
+    5502             : 
+    5503             :   PLUMED_GCH_CPP20_CONSTEXPR
+    5504             :   void
+    5505             :   assign (const small_vector& other)
+    5506             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5507             :   requires CopyInsertable && CopyAssignable
+    5508             : #endif
+    5509             :   {
+    5510             :     if (&other != this)
+    5511             :       base::copy_assign (other);
+    5512             :   }
+    5513             : 
+    5514             :   template <unsigned I>
+    5515             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5516             :   requires CopyInsertable && CopyAssignable
+    5517             : #endif
+    5518             :   PLUMED_GCH_CPP20_CONSTEXPR
+    5519             :   void
+    5520             :   assign (const small_vector<T, I, Allocator>& other)
+    5521             :   {
+    5522             :     base::copy_assign (other);
+    5523             :   }
+    5524             : 
+    5525             :   PLUMED_GCH_CPP20_CONSTEXPR
+    5526             :   void
+    5527             :   assign (small_vector&& other)
+    5528             :   noexcept (  (  std::is_same<std::allocator<value_type>, Allocator>::value
+    5529             :                  ||  std::allocator_traits<Allocator>::propagate_on_container_move_assignment::value
+    5530             : #ifdef PLUMED_GCH_LIB_IS_ALWAYS_EQUAL
+    5531             :                  ||  std::allocator_traits<Allocator>::is_always_equal::value
+    5532             : #endif
+    5533             :               )
+    5534             :               &&  (  (  std::is_nothrow_move_assignable<value_type>::value
+    5535             :                         &&  std::is_nothrow_move_constructible<value_type>::value
+    5536             :                      )
+    5537             :                      ||  InlineCapacity == 0
+    5538             :                   )
+    5539             :            )
+    5540             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5541             :   requires MoveInsertable && MoveAssignable
+    5542             : #endif
+    5543             :   {
+    5544             :     if (&other != this)
+    5545             :       base::move_assign (std::move (other));
+    5546             :   }
+    5547             : 
+    5548             :   template <unsigned I>
+    5549             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5550             :   requires MoveInsertable && MoveAssignable
+    5551             : #endif
+    5552             :   PLUMED_GCH_CPP20_CONSTEXPR
+    5553             :   void
+    5554             :   assign (small_vector<T, I, Allocator>&& other)
+    5555             :   noexcept (  I <= InlineCapacity
+    5556             :                  &&  (  std::is_same<std::allocator<value_type>, Allocator>::value
+    5557             :                         ||  std::allocator_traits<Allocator>::propagate_on_container_move_assignment::value
+    5558             : #ifdef PLUMED_GCH_LIB_IS_ALWAYS_EQUAL
+    5559             :                         ||  std::allocator_traits<Allocator>::is_always_equal::value
+    5560             : #endif
+    5561             :                                                  )
+    5562             :                  &&  std::is_nothrow_move_assignable<value_type>::value
+    5563             :                  &&  std::is_nothrow_move_constructible<value_type>::value
+    5564             :                                                        )
+    5565             :   {
+    5566             :     base::move_assign (std::move (other));
+    5567             :   }
+    5568             : 
+    5569             : #ifndef PLUMED_GCH_LIB_CONCEPTS
+    5570             :   template <typename ValueType = value_type,
+    5571             :             typename std::enable_if<
+    5572             :               (  std::is_move_constructible<ValueType>::value
+    5573             :                  &&  std::is_move_assignable<ValueType>::value
+    5574             : #ifdef PLUMED_GCH_LIB_IS_SWAPPABLE
+    5575             :                  &&  std::is_swappable<ValueType>::value
+    5576             : #endif
+    5577             :                                       )
+    5578             :               ||  (  (  std::is_same<std::allocator<value_type>, Allocator>::value
+    5579             :                         ||  std::allocator_traits<Allocator>::propagate_on_container_swap::value
+    5580             : #ifdef PLUMED_GCH_LIB_IS_ALWAYS_EQUAL
+    5581             :                         ||  std::allocator_traits<Allocator>::is_always_equal::value
+    5582             : #endif
+    5583             :                                                  )
+    5584             :                      &&  InlineCapacity == 0
+    5585             :                                                  )
+    5586             :               >::type * = nullptr>
+    5587             : #endif
+    5588             :   PLUMED_GCH_CPP20_CONSTEXPR
+    5589             :   void
+    5590             :   swap (small_vector& other)
+    5591             :   noexcept (  (  std::is_same<std::allocator<value_type>, Allocator>::value
+    5592             :                  ||  std::allocator_traits<Allocator>::propagate_on_container_swap::value
+    5593             : #ifdef PLUMED_GCH_LIB_IS_ALWAYS_EQUAL
+    5594             :                  ||  std::allocator_traits<Allocator>::is_always_equal::value
+    5595             : #endif
+    5596             :                                           )
+    5597             :               &&  (  (  std::is_nothrow_move_constructible<value_type>::value
+    5598             :                         &&  std::is_nothrow_move_assignable<value_type>::value
+    5599             : #ifdef PLUMED_GCH_LIB_IS_SWAPPABLE
+    5600             :                         &&  std::is_nothrow_swappable<value_type>::value
+    5601             : #else
+    5602             :                         &&  detail::small_vector_adl::is_nothrow_swappable<value_type>::value
+    5603             : #endif
+    5604             :                                                      )
+    5605             :                      ||  InlineCapacity == 0
+    5606             :                                                            )
+    5607             :                                                           )
+    5608             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5609             :   requires (MoveInsertable && MoveAssignable && Swappable)
+    5610             :   ||  (  (  std::is_same<std::allocator<value_type>, Allocator>::value
+    5611             :             ||  std::allocator_traits<Allocator>::propagate_on_container_swap::value
+    5612             : #ifdef PLUMED_GCH_LIB_IS_ALWAYS_EQUAL
+    5613             :             ||  std::allocator_traits<Allocator>::is_always_equal::value
+    5614             : #endif
+    5615             :                                      )
+    5616             :          &&  InlineCapacity == 0
+    5617             :                                      )
+    5618             : #endif
+    5619             :   {
+    5620             :     base::swap (other);
+    5621             :   }
+    5622             : 
+    5623             :   PLUMED_GCH_CPP14_CONSTEXPR
+    5624             :   iterator
+    5625             :   begin (void) noexcept
+    5626             :   {
+    5627             :     return iterator { base::begin_ptr () };
+    5628             :   }
+    5629             : 
+    5630             :   constexpr
+    5631             :   const_iterator
+    5632             :   begin (void) const noexcept
+    5633             :   {
+    5634             :     return const_iterator { base::begin_ptr () };
+    5635             :   }
+    5636             : 
+    5637             :   constexpr
+    5638             :   const_iterator
+    5639             :   cbegin (void) const noexcept
+    5640             :   {
+    5641             :     return begin ();
+    5642             :   }
+    5643             : 
+    5644             :   PLUMED_GCH_CPP14_CONSTEXPR
+    5645             :   iterator
+    5646             :   end (void) noexcept
+    5647             :   {
+    5648     4864114 :     return iterator { base::end_ptr () };
+    5649             :   }
+    5650             : 
+    5651             :   constexpr
+    5652             :   const_iterator
+    5653             :   end (void) const noexcept
+    5654             :   {
+    5655             :     return const_iterator { base::end_ptr () };
+    5656             :   }
+    5657             : 
+    5658             :   constexpr
+    5659             :   const_iterator
+    5660             :   cend (void) const noexcept
+    5661             :   {
+    5662             :     return end ();
+    5663             :   }
+    5664             : 
+    5665             :   PLUMED_GCH_CPP14_CONSTEXPR
+    5666             :   reverse_iterator
+    5667             :   rbegin (void) noexcept
+    5668             :   {
+    5669             :     return reverse_iterator { end () };
+    5670             :   }
+    5671             : 
+    5672             :   constexpr
+    5673             :   const_reverse_iterator
+    5674             :   rbegin (void) const noexcept
+    5675             :   {
+    5676             :     return const_reverse_iterator { end () };
+    5677             :   }
+    5678             : 
+    5679             :   constexpr
+    5680             :   const_reverse_iterator
+    5681             :   crbegin (void) const noexcept
+    5682             :   {
+    5683             :     return rbegin ();
+    5684             :   }
+    5685             : 
+    5686             :   PLUMED_GCH_CPP14_CONSTEXPR
+    5687             :   reverse_iterator
+    5688             :   rend (void) noexcept
+    5689             :   {
+    5690             :     return reverse_iterator { begin () };
+    5691             :   }
+    5692             : 
+    5693             :   constexpr
+    5694             :   const_reverse_iterator
+    5695             :   rend (void) const noexcept
+    5696             :   {
+    5697             :     return const_reverse_iterator { begin () };
+    5698             :   }
+    5699             : 
+    5700             :   constexpr
+    5701             :   const_reverse_iterator
+    5702             :   crend (void) const noexcept
+    5703             :   {
+    5704             :     return rend ();
+    5705             :   }
+    5706             : 
+    5707             :   PLUMED_GCH_CPP14_CONSTEXPR
+    5708             :   reference
+    5709             :   at (size_type pos)
+    5710             :   {
+    5711             :     if (size () <= pos)
+    5712             :       base::throw_index_error ();
+    5713             :     return begin ()[static_cast<difference_type> (pos)];
+    5714             :   }
+    5715             : 
+    5716             :   PLUMED_GCH_CPP14_CONSTEXPR
+    5717             :   const_reference
+    5718             :   at (size_type pos) const
+    5719             :   {
+    5720             :     if (size () <= pos)
+    5721             :       base::throw_index_error ();
+    5722             :     return begin ()[static_cast<difference_type> (pos)];
+    5723             :   }
+    5724             : 
+    5725             :   PLUMED_GCH_CPP14_CONSTEXPR
+    5726             :   reference
+    5727             :   operator[] (size_type pos)
+    5728             :   {
+    5729             : #ifdef _GLIBCXX_DEBUG
+    5730             :     if (size () <= pos) base::throw_index_error ();
+    5731             : #endif
+    5732             :     return begin ()[static_cast<difference_type> (pos)];
+    5733             :   }
+    5734             : 
+    5735             :   constexpr
+    5736             :   const_reference
+    5737             :   operator[] (size_type pos) const
+    5738             :   {
+    5739             : #ifdef _GLIBCXX_DEBUG
+    5740             :     if (size () <= pos) base::throw_index_error ();
+    5741             : #endif
+    5742             :     return begin ()[static_cast<difference_type> (pos)];
+    5743             :   }
+    5744             : 
+    5745             :   PLUMED_GCH_CPP14_CONSTEXPR
+    5746             :   reference
+    5747             :   front (void)
+    5748             :   {
+    5749             :     return (*this)[0];
+    5750             :   }
+    5751             : 
+    5752             :   constexpr
+    5753             :   const_reference
+    5754             :   front (void) const
+    5755             :   {
+    5756             :     return (*this)[0];
+    5757             :   }
+    5758             : 
+    5759             :   PLUMED_GCH_CPP14_CONSTEXPR
+    5760             :   reference
+    5761             :   back (void)
+    5762             :   {
+    5763     2476375 :     return (*this)[size () - 1];
+    5764             :   }
+    5765             : 
+    5766             :   constexpr
+    5767             :   const_reference
+    5768             :   back (void) const
+    5769             :   {
+    5770             :     return (*this)[size () - 1];
+    5771             :   }
+    5772             : 
+    5773             :   PLUMED_GCH_CPP14_CONSTEXPR
+    5774             :   pointer
+    5775             :   data (void) noexcept
+    5776             :   {
+    5777             :     return base::begin_ptr ();
+    5778             :   }
+    5779             : 
+    5780             :   constexpr
+    5781             :   const_pointer
+    5782             :   data (void) const noexcept
+    5783             :   {
+    5784             :     return base::begin_ptr ();
+    5785             :   }
+    5786             : 
+    5787             :   constexpr
+    5788             :   size_type
+    5789             :   size (void) const noexcept
+    5790             :   {
+    5791             :     return static_cast<size_type> (base::get_size ());
+    5792             :   }
+    5793             : 
+    5794             :   PLUMED_GCH_NODISCARD constexpr
+    5795             :   bool
+    5796             :   empty (void) const noexcept
+    5797             :   {
+    5798             :     return size () == 0;
+    5799             :   }
+    5800             : 
+    5801             :   PLUMED_GCH_CPP14_CONSTEXPR
+    5802             :   size_type
+    5803             :   max_size (void) const noexcept
+    5804             :   {
+    5805             :     return static_cast<size_type> (base::get_max_size ());
+    5806             :   }
+    5807             : 
+    5808             :   constexpr
+    5809             :   size_type
+    5810             :   capacity (void) const noexcept
+    5811             :   {
+    5812             :     return static_cast<size_type> (base::get_capacity ());
+    5813             :   }
+    5814             : 
+    5815             :   constexpr
+    5816             :   allocator_type
+    5817             :   get_allocator (void) const noexcept
+    5818             :   {
+    5819             :     return base::copy_allocator ();
+    5820             :   }
+    5821             : 
+    5822             :   PLUMED_GCH_CPP20_CONSTEXPR
+    5823             :   iterator
+    5824             :   insert (const_iterator pos, const_reference value)
+    5825             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5826             :   requires CopyInsertable && CopyAssignable
+    5827             : #endif
+    5828             :   {
+    5829             :     return emplace (pos, value);
+    5830             :   }
+    5831             : 
+    5832             :   PLUMED_GCH_CPP20_CONSTEXPR
+    5833             :   iterator
+    5834             :   insert (const_iterator pos, value_type&& value)
+    5835             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5836             :   requires MoveInsertable && MoveAssignable
+    5837             : #endif
+    5838             :   {
+    5839             :     return emplace (pos, std::move (value));
+    5840             :   }
+    5841             : 
+    5842             :   PLUMED_GCH_CPP20_CONSTEXPR
+    5843             :   iterator
+    5844             :   insert (const_iterator pos, size_type count, const_reference value)
+    5845             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5846             :   requires CopyInsertable && CopyAssignable
+    5847             : #endif
+    5848             :   {
+    5849             :     return iterator (base::insert_copies (base::ptr_cast (pos), count, value));
+    5850             :   }
+    5851             : 
+    5852             :   // Note: Unlike std::vector, this does not require MoveConstructible because we
+    5853             :   //       don't use std::rotate (as was the reason for the change in C++17).
+    5854             :   //       Relevant: https://cplusplus.github.io/LWG/issue2266).
+    5855             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5856             :   template <std::input_iterator InputIt>
+    5857             :   requires EmplaceConstructible<std::iter_reference_t<InputIt>>::value
+    5858             :   &&  MoveInsertable
+    5859             :   &&  MoveAssignable
+    5860             : #else
+    5861             :   template <typename InputIt,
+    5862             :             typename std::enable_if<std::is_base_of<
+    5863             :                                       std::input_iterator_tag,
+    5864             :                                       typename std::iterator_traits<InputIt>::iterator_category
+    5865             :                                       >::value>::type * = nullptr>
+    5866             : #endif
+    5867             :   PLUMED_GCH_CPP20_CONSTEXPR
+    5868             :   iterator
+    5869             :   insert (const_iterator pos, InputIt first, InputIt last)
+    5870             :   {
+    5871             :     if (first == last)
+    5872             :       return iterator (base::ptr_cast (pos));
+    5873             : 
+    5874             :     using iterator_cat = typename std::iterator_traits<InputIt>::iterator_category;
+    5875             :     return iterator (base::insert_range (base::ptr_cast (pos), first, last, iterator_cat { }));
+    5876             :   }
+    5877             : 
+    5878             :   PLUMED_GCH_CPP20_CONSTEXPR
+    5879             :   iterator
+    5880             :   insert (const_iterator pos, std::initializer_list<value_type> ilist)
+    5881             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5882             :   requires EmplaceConstructible<const_reference>::value
+    5883             :   &&  MoveInsertable
+    5884             :   &&  MoveAssignable
+    5885             : #endif
+    5886             :   {
+    5887             :     return insert (pos, ilist.begin (), ilist.end ());
+    5888             :   }
+    5889             : 
+    5890             :   template <typename ...Args>
+    5891             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5892             :   requires EmplaceConstructible<Args...>::value
+    5893             :   &&  MoveInsertable
+    5894             :   &&  MoveAssignable
+    5895             : #endif
+    5896             :   PLUMED_GCH_CPP20_CONSTEXPR
+    5897             :   iterator
+    5898             :   emplace (const_iterator pos, Args&&... args)
+    5899             :   {
+    5900             :     return iterator (base::emplace_at (base::ptr_cast (pos), std::forward<Args> (args)...));
+    5901             :   }
+    5902             : 
+    5903             :   PLUMED_GCH_CPP20_CONSTEXPR
+    5904             :   iterator
+    5905             :   erase (const_iterator pos)
+    5906             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5907             :   requires MoveAssignable && Erasable
+    5908             : #endif
+    5909             :   {
+    5910             :     assert (0 <= (pos    - begin ()) && "`pos` is out of bounds (before `begin ()`)."   );
+    5911             :     assert (0 <  (end () - pos)      && "`pos` is out of bounds (at or after `end ()`).");
+    5912             : 
+    5913             :     return iterator (base::erase_at (base::ptr_cast (pos)));
+    5914             :   }
+    5915             : 
+    5916             :   PLUMED_GCH_CPP20_CONSTEXPR
+    5917             :   iterator
+    5918             :   erase (const_iterator first, const_iterator last)
+    5919             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5920             :   requires MoveAssignable && Erasable
+    5921             : #endif
+    5922             :   {
+    5923             :     assert (0 <= (last   - first)    && "Invalid range.");
+    5924             :     assert (0 <= (first  - begin ()) && "`first` is out of bounds (before `begin ()`)."  );
+    5925             :     assert (0 <= (end () - last)     && "`last` is out of bounds (after `end ()`).");
+    5926             : 
+    5927             :     return iterator (base::erase_range (base::ptr_cast (first), base::ptr_cast (last)));
+    5928             :   }
+    5929             : 
+    5930             :   PLUMED_GCH_CPP20_CONSTEXPR
+    5931             :   void
+    5932             :   push_back (const_reference value)
+    5933             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5934             :   requires CopyInsertable
+    5935             : #endif
+    5936             :   {
+    5937             :     emplace_back (value);
+    5938             :   }
+    5939             : 
+    5940             :   PLUMED_GCH_CPP20_CONSTEXPR
+    5941             :   void
+    5942             :   push_back (value_type&& value)
+    5943             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5944             :   requires MoveInsertable
+    5945             : #endif
+    5946             :   {
+    5947             :     emplace_back (std::move (value));
+    5948      139953 :   }
+    5949             : 
+    5950             :   template <typename ...Args>
+    5951             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5952             :   requires EmplaceConstructible<Args...>::value && MoveInsertable
+    5953             : #endif
+    5954             :   PLUMED_GCH_CPP20_CONSTEXPR
+    5955             :   reference
+    5956             :   emplace_back (Args&&... args)
+    5957             :   {
+    5958     2134612 :     return *base::append_element (std::forward<Args> (args)...);
+    5959             :   }
+    5960             : 
+    5961             :   PLUMED_GCH_CPP20_CONSTEXPR
+    5962             :   void
+    5963             :   pop_back (void)
+    5964             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5965             :   requires Erasable
+    5966             : #endif
+    5967             :   {
+    5968             :     assert (! empty () && "`pop_back ()` called on an empty `small_vector`.");
+    5969             :     base::erase_last ();
+    5970      135205 :   }
+    5971             : 
+    5972             :   PLUMED_GCH_CPP20_CONSTEXPR
+    5973             :   void
+    5974             :   reserve (size_type new_capacity)
+    5975             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5976             :   requires MoveInsertable
+    5977             : #endif
+    5978             :   {
+    5979       49613 :     base::request_capacity (new_capacity);
+    5980       49613 :   }
+    5981             : 
+    5982             :   PLUMED_GCH_CPP20_CONSTEXPR
+    5983             :   void
+    5984             :   shrink_to_fit (void)
+    5985             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5986             :   requires MoveInsertable
+    5987             : #endif
+    5988             :   {
+    5989             :     base::shrink_to_size ();
+    5990             :   }
+    5991             : 
+    5992             :   PLUMED_GCH_CPP20_CONSTEXPR
+    5993             :   void
+    5994             :   clear (void) noexcept
+    5995             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5996             :   requires Erasable
+    5997             : #endif
+    5998             :   {
+    5999     1502998 :     base::erase_all ();
+    6000             :   }
+    6001             : 
+    6002             :   PLUMED_GCH_CPP20_CONSTEXPR
+    6003             :   void
+    6004             :   resize (size_type count)
+    6005             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    6006             :   requires MoveInsertable && DefaultInsertable
+    6007             : #endif
+    6008             :   {
+    6009             :     base::resize_with (count);
+    6010             :   }
+    6011             : 
+    6012             :   PLUMED_GCH_CPP20_CONSTEXPR
+    6013             :   void
+    6014             :   resize (size_type count, const_reference value)
+    6015             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    6016             :   requires CopyInsertable
+    6017             : #endif
+    6018             :   {
+    6019             :     base::resize_with (count, value);
+    6020             :   }
+    6021             : 
+    6022             :   PLUMED_GCH_NODISCARD constexpr
+    6023             :   bool
+    6024             :   inlined (void) const noexcept
+    6025             :   {
+    6026             :     return ! base::has_allocation ();
+    6027             :   }
+    6028             : 
+    6029             :   PLUMED_GCH_NODISCARD constexpr
+    6030             :   bool
+    6031             :   inlinable (void) const noexcept
+    6032             :   {
+    6033             :     return base::is_inlinable ();
+    6034             :   }
+    6035             : 
+    6036             :   PLUMED_GCH_NODISCARD
+    6037             :   static PLUMED_GCH_CONSTEVAL
+    6038             :   size_type
+    6039             :   inline_capacity (void) noexcept
+    6040             :   {
+    6041             :     return static_cast<size_type> (inline_capacity_v);
+    6042             :   }
+    6043             : 
+    6044             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    6045             :   template <std::input_iterator InputIt>
+    6046             :   requires EmplaceConstructible<std::iter_reference_t<InputIt>>::value
+    6047             :   &&  MoveInsertable
+    6048             : #else
+    6049             :   template <typename InputIt,
+    6050             :             typename std::enable_if<std::is_base_of<
+    6051             :                                       std::input_iterator_tag,
+    6052             :                                       typename std::iterator_traits<InputIt>::iterator_category
+    6053             :                                       >::value>::type * = nullptr>
+    6054             : #endif
+    6055             :   PLUMED_GCH_CPP20_CONSTEXPR
+    6056             :   small_vector&
+    6057             :   append (InputIt first, InputIt last)
+    6058             :   {
+    6059             :     using policy = typename base::strong_exception_policy;
+    6060             :     using iterator_cat = typename std::iterator_traits<InputIt>::iterator_category;
+    6061             :     base::template append_range<policy> (first, last, iterator_cat { });
+    6062             :     return *this;
+    6063             :   }
+    6064             : 
+    6065             :   PLUMED_GCH_CPP20_CONSTEXPR
+    6066             :   small_vector&
+    6067             :   append (std::initializer_list<value_type> ilist)
+    6068             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    6069             :   requires EmplaceConstructible<const_reference>::value
+    6070             :   &&  MoveInsertable
+    6071             : #endif
+    6072             :   {
+    6073             :     return append (ilist.begin (), ilist.end ());
+    6074             :   }
+    6075             : 
+    6076             :   template <unsigned I>
+    6077             :   PLUMED_GCH_CPP20_CONSTEXPR
+    6078             :   small_vector&
+    6079             :   append (const small_vector<T, I, Allocator>& other)
+    6080             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    6081             :   requires CopyInsertable
+    6082             : #endif
+    6083             :   {
+    6084             :     return append (other.begin (), other.end ());
+    6085             :   }
+    6086             : 
+    6087             :   template <unsigned I>
+    6088             :   PLUMED_GCH_CPP20_CONSTEXPR
+    6089             :   small_vector&
+    6090             :   append (small_vector<T, I, Allocator>&& other)
+    6091             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    6092             :   requires MoveInsertable
+    6093             : #endif
+    6094             :   {
+    6095             :     // Provide a strong exception guarantee for `other` as well.
+    6096             :     using move_iter_type = typename std::conditional<
+    6097             :       base::template relocate_with_move<value_type>::value,
+    6098             :       std::move_iterator<iterator>,
+    6099             :       iterator>::type;
+    6100             : 
+    6101             :     append (move_iter_type { other.begin () }, move_iter_type { other.end () });
+    6102             :     other.clear ();
+    6103             :     return *this;
+    6104             :   }
+    6105             : };
+    6106             : 
+    6107             : template <typename T, unsigned InlineCapacityLHS, unsigned InlineCapacityRHS, typename Allocator>
+    6108             : inline PLUMED_GCH_CPP20_CONSTEXPR
+    6109             : bool
+    6110             : operator== (const small_vector<T, InlineCapacityLHS, Allocator>& lhs,
+    6111             :             const small_vector<T, InlineCapacityRHS, Allocator>& rhs)
+    6112             : {
+    6113             :   return lhs.size () == rhs.size () && std::equal (lhs.begin (), lhs.end (), rhs.begin ());
+    6114             : }
+    6115             : 
+    6116             : template <typename T, unsigned InlineCapacity, typename Allocator>
+    6117             : inline PLUMED_GCH_CPP20_CONSTEXPR
+    6118             : bool
+    6119             : operator== (const small_vector<T, InlineCapacity, Allocator>& lhs,
+    6120             :             const small_vector<T, InlineCapacity, Allocator>& rhs)
+    6121             : {
+    6122             :   return lhs.size () == rhs.size () && std::equal (lhs.begin (), lhs.end (), rhs.begin ());
+    6123             : }
+    6124             : 
+    6125             : #ifdef PLUMED_GCH_LIB_THREE_WAY_COMPARISON
+    6126             : 
+    6127             : template <typename T, unsigned InlineCapacityLHS, unsigned InlineCapacityRHS, typename Allocator>
+    6128             : requires std::three_way_comparable<T>
+    6129             : constexpr
+    6130             : auto
+    6131             : operator<=> (const small_vector<T, InlineCapacityLHS, Allocator>& lhs,
+    6132             :              const small_vector<T, InlineCapacityRHS, Allocator>& rhs)
+    6133             : {
+    6134             :   return std::lexicographical_compare_three_way (
+    6135             :     lhs.begin (), lhs.end (),
+    6136             :     rhs.begin (), rhs.end (),
+    6137             :     std::compare_three_way { });
+    6138             : }
+    6139             : 
+    6140             : template <typename T, unsigned InlineCapacity, typename Allocator>
+    6141             : requires std::three_way_comparable<T>
+    6142             : constexpr
+    6143             : auto
+    6144             : operator<=> (const small_vector<T, InlineCapacity, Allocator>& lhs,
+    6145             :              const small_vector<T, InlineCapacity, Allocator>& rhs)
+    6146             : {
+    6147             :   return std::lexicographical_compare_three_way (
+    6148             :     lhs.begin (), lhs.end (),
+    6149             :     rhs.begin (), rhs.end (),
+    6150             :     std::compare_three_way { });
+    6151             : }
+    6152             : 
+    6153             : template <typename T, unsigned InlineCapacityLHS, unsigned InlineCapacityRHS, typename Allocator>
+    6154             : constexpr
+    6155             : auto
+    6156             : operator<=> (const small_vector<T, InlineCapacityLHS, Allocator>& lhs,
+    6157             :              const small_vector<T, InlineCapacityRHS, Allocator>& rhs)
+    6158             : {
+    6159             :   constexpr auto comparison = [](const T& l, const T& r) {
+    6160             :     return (l < r) ? std::weak_ordering::less
+    6161             :             : (r < l) ? std::weak_ordering::greater
+    6162             :                : std::weak_ordering::equivalent;
+    6163             :   };
+    6164             : 
+    6165             :   return std::lexicographical_compare_three_way (
+    6166             :            lhs.begin (), lhs.end (),
+    6167             :            rhs.begin (), rhs.end (),
+    6168             :            comparison);
+    6169             : }
+    6170             : 
+    6171             : template <typename T, unsigned InlineCapacity, typename Allocator>
+    6172             : constexpr
+    6173             : auto
+    6174             : operator<=> (const small_vector<T, InlineCapacity, Allocator>& lhs,
+    6175             :              const small_vector<T, InlineCapacity, Allocator>& rhs)
+    6176             : {
+    6177             :   constexpr auto comparison = [](const T& l, const T& r) {
+    6178             :     return (l < r) ? std::weak_ordering::less
+    6179             :             : (r < l) ? std::weak_ordering::greater
+    6180             :                : std::weak_ordering::equivalent;
+    6181             :   };
+    6182             : 
+    6183             :   return std::lexicographical_compare_three_way (
+    6184             :            lhs.begin (), lhs.end (),
+    6185             :            rhs.begin (), rhs.end (),
+    6186             :            comparison);
+    6187             : }
+    6188             : 
+    6189             : #else
+    6190             : 
+    6191             : template <typename T, unsigned InlineCapacityLHS, unsigned InlineCapacityRHS, typename Allocator>
+    6192             : inline PLUMED_GCH_CPP20_CONSTEXPR
+    6193             : bool
+    6194             : operator!= (const small_vector<T, InlineCapacityLHS, Allocator>& lhs,
+    6195             :             const small_vector<T, InlineCapacityRHS, Allocator>& rhs)
+    6196             : {
+    6197             :   return ! (lhs == rhs);
+    6198             : }
+    6199             : 
+    6200             : template <typename T, unsigned InlineCapacity, typename Allocator>
+    6201             : inline PLUMED_GCH_CPP20_CONSTEXPR
+    6202             : bool
+    6203             : operator!= (const small_vector<T, InlineCapacity, Allocator>& lhs,
+    6204             :             const small_vector<T, InlineCapacity, Allocator>& rhs)
+    6205             : {
+    6206             :   return ! (lhs == rhs);
+    6207             : }
+    6208             : 
+    6209             : template <typename T, unsigned InlineCapacityLHS, unsigned InlineCapacityRHS, typename Allocator>
+    6210             : inline PLUMED_GCH_CPP20_CONSTEXPR
+    6211             : bool
+    6212             : operator<  (const small_vector<T, InlineCapacityLHS, Allocator>& lhs,
+    6213             :             const small_vector<T, InlineCapacityRHS, Allocator>& rhs)
+    6214             : {
+    6215             :   return std::lexicographical_compare (lhs.begin (), lhs.end (), rhs.begin (), rhs.end ());
+    6216             : }
+    6217             : 
+    6218             : template <typename T, unsigned InlineCapacity, typename Allocator>
+    6219             : inline PLUMED_GCH_CPP20_CONSTEXPR
+    6220             : bool
+    6221             : operator<  (const small_vector<T, InlineCapacity, Allocator>& lhs,
+    6222             :             const small_vector<T, InlineCapacity, Allocator>& rhs)
+    6223             : {
+    6224             :   return std::lexicographical_compare (lhs.begin (), lhs.end (), rhs.begin (), rhs.end ());
+    6225             : }
+    6226             : 
+    6227             : template <typename T, unsigned InlineCapacityLHS, unsigned InlineCapacityRHS, typename Allocator>
+    6228             : inline PLUMED_GCH_CPP20_CONSTEXPR
+    6229             : bool
+    6230             : operator>= (const small_vector<T, InlineCapacityLHS, Allocator>& lhs,
+    6231             :             const small_vector<T, InlineCapacityRHS, Allocator>& rhs)
+    6232             : {
+    6233             :   return ! (lhs < rhs);
+    6234             : }
+    6235             : 
+    6236             : template <typename T, unsigned InlineCapacity, typename Allocator>
+    6237             : inline PLUMED_GCH_CPP20_CONSTEXPR
+    6238             : bool
+    6239             : operator>= (const small_vector<T, InlineCapacity, Allocator>& lhs,
+    6240             :             const small_vector<T, InlineCapacity, Allocator>& rhs)
+    6241             : {
+    6242             :   return ! (lhs < rhs);
+    6243             : }
+    6244             : 
+    6245             : template <typename T, unsigned InlineCapacityLHS, unsigned InlineCapacityRHS, typename Allocator>
+    6246             : inline PLUMED_GCH_CPP20_CONSTEXPR
+    6247             : bool
+    6248             : operator>  (const small_vector<T, InlineCapacityLHS, Allocator>& lhs,
+    6249             :             const small_vector<T, InlineCapacityRHS, Allocator>& rhs)
+    6250             : {
+    6251             :   return rhs < lhs;
+    6252             : }
+    6253             : 
+    6254             : template <typename T, unsigned InlineCapacity, typename Allocator>
+    6255             : inline PLUMED_GCH_CPP20_CONSTEXPR
+    6256             : bool
+    6257             : operator>  (const small_vector<T, InlineCapacity, Allocator>& lhs,
+    6258             :             const small_vector<T, InlineCapacity, Allocator>& rhs)
+    6259             : {
+    6260             :   return rhs < lhs;
+    6261             : }
+    6262             : 
+    6263             : template <typename T, unsigned InlineCapacityLHS, unsigned InlineCapacityRHS, typename Allocator>
+    6264             : inline PLUMED_GCH_CPP20_CONSTEXPR
+    6265             : bool
+    6266             : operator<= (const small_vector<T, InlineCapacityLHS, Allocator>& lhs,
+    6267             :             const small_vector<T, InlineCapacityRHS, Allocator>& rhs)
+    6268             : {
+    6269             :   return rhs >= lhs;
+    6270             : }
+    6271             : 
+    6272             : template <typename T, unsigned InlineCapacity, typename Allocator>
+    6273             : inline PLUMED_GCH_CPP20_CONSTEXPR
+    6274             : bool
+    6275             : operator<= (const small_vector<T, InlineCapacity, Allocator>& lhs,
+    6276             :             const small_vector<T, InlineCapacity, Allocator>& rhs)
+    6277             : {
+    6278             :   return rhs >= lhs;
+    6279             : }
+    6280             : 
+    6281             : #endif
+    6282             : 
+    6283             : template <typename T, unsigned InlineCapacity, typename Allocator
+    6284             : #ifndef PLUMED_GCH_LIB_CONCEPTS
+    6285             :           , typename std::enable_if<std::is_move_constructible<T>::value
+    6286             :                                     &&  std::is_move_assignable<T>::value
+    6287             : #ifdef PLUMED_GCH_LIB_IS_SWAPPABLE
+    6288             :                                     &&  std::is_swappable<T>::value
+    6289             : #endif
+    6290             :                                     >::type * = nullptr
+    6291             : #endif
+    6292             :           >
+    6293             : inline PLUMED_GCH_CPP20_CONSTEXPR
+    6294             : void
+    6295             : swap (small_vector<T, InlineCapacity, Allocator>& lhs,
+    6296             :       small_vector<T, InlineCapacity, Allocator>& rhs)
+    6297             : noexcept (noexcept (lhs.swap (rhs)))
+    6298             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    6299             : requires concepts::MoveInsertable<T, small_vector<T, InlineCapacity, Allocator>, Allocator>
+    6300             : && concepts::Swappable<T>
+    6301             : #endif
+    6302             : {
+    6303             :   lhs.swap (rhs);
+    6304             : }
+    6305             : 
+    6306             : template <typename T, unsigned InlineCapacity, typename Allocator, typename U>
+    6307             : inline PLUMED_GCH_CPP20_CONSTEXPR
+    6308             : typename small_vector<T, InlineCapacity, Allocator>::size_type
+    6309             : erase (small_vector<T, InlineCapacity, Allocator>& v, const U& value)
+    6310             : {
+    6311             :   const auto original_size = v.size ();
+    6312             :   v.erase (std::remove (v.begin (), v.end (), value), v.end ());
+    6313             :   return original_size - v.size ();
+    6314             : }
+    6315             : 
+    6316             : template <typename T, unsigned InlineCapacity, typename Allocator, typename Pred>
+    6317             : inline PLUMED_GCH_CPP20_CONSTEXPR
+    6318             : typename small_vector<T, InlineCapacity, Allocator>::size_type
+    6319             : erase_if (small_vector<T, InlineCapacity, Allocator>& v, Pred pred)
+    6320             : {
+    6321             :   const auto original_size = v.size ();
+    6322             :   v.erase (std::remove_if (v.begin (), v.end (), pred), v.end ());
+    6323             :   return original_size - v.size ();
+    6324             : }
+    6325             : 
+    6326             : template <typename T, unsigned InlineCapacity, typename Allocator>
+    6327             : constexpr
+    6328             : typename small_vector<T, InlineCapacity, Allocator>::iterator
+    6329             : begin (small_vector<T, InlineCapacity, Allocator>& v) noexcept
+    6330             : {
+    6331             :   return v.begin ();
+    6332             : }
+    6333             : 
+    6334             : template <typename T, unsigned InlineCapacity, typename Allocator>
+    6335             : constexpr
+    6336             : typename small_vector<T, InlineCapacity, Allocator>::const_iterator
+    6337             : begin (const small_vector<T, InlineCapacity, Allocator>& v) noexcept
+    6338             : {
+    6339             :   return v.begin ();
+    6340             : }
+    6341             : 
+    6342             : template <typename T, unsigned InlineCapacity, typename Allocator>
+    6343             : constexpr
+    6344             : typename small_vector<T, InlineCapacity, Allocator>::const_iterator
+    6345             : cbegin (const small_vector<T, InlineCapacity, Allocator>& v) noexcept
+    6346             : {
+    6347             :   return begin (v);
+    6348             : }
+    6349             : 
+    6350             : template <typename T, unsigned InlineCapacity, typename Allocator>
+    6351             : constexpr
+    6352             : typename small_vector<T, InlineCapacity, Allocator>::iterator
+    6353             : end (small_vector<T, InlineCapacity, Allocator>& v) noexcept
+    6354             : {
+    6355             :   return v.end ();
+    6356             : }
+    6357             : 
+    6358             : template <typename T, unsigned InlineCapacity, typename Allocator>
+    6359             : constexpr
+    6360             : typename small_vector<T, InlineCapacity, Allocator>::const_iterator
+    6361             : end (const small_vector<T, InlineCapacity, Allocator>& v) noexcept
+    6362             : {
+    6363             :   return v.end ();
+    6364             : }
+    6365             : 
+    6366             : template <typename T, unsigned InlineCapacity, typename Allocator>
+    6367             : constexpr
+    6368             : typename small_vector<T, InlineCapacity, Allocator>::const_iterator
+    6369             : cend (const small_vector<T, InlineCapacity, Allocator>& v) noexcept
+    6370             : {
+    6371             :   return end (v);
+    6372             : }
+    6373             : 
+    6374             : template <typename T, unsigned InlineCapacity, typename Allocator>
+    6375             : constexpr
+    6376             : typename small_vector<T, InlineCapacity, Allocator>::reverse_iterator
+    6377             : rbegin (small_vector<T, InlineCapacity, Allocator>& v) noexcept
+    6378             : {
+    6379             :   return v.rbegin ();
+    6380             : }
+    6381             : 
+    6382             : template <typename T, unsigned InlineCapacity, typename Allocator>
+    6383             : constexpr
+    6384             : typename small_vector<T, InlineCapacity, Allocator>::const_reverse_iterator
+    6385             : rbegin (const small_vector<T, InlineCapacity, Allocator>& v) noexcept
+    6386             : {
+    6387             :   return v.rbegin ();
+    6388             : }
+    6389             : 
+    6390             : template <typename T, unsigned InlineCapacity, typename Allocator>
+    6391             : constexpr
+    6392             : typename small_vector<T, InlineCapacity, Allocator>::const_reverse_iterator
+    6393             : crbegin (const small_vector<T, InlineCapacity, Allocator>& v) noexcept
+    6394             : {
+    6395             :   return rbegin (v);
+    6396             : }
+    6397             : 
+    6398             : template <typename T, unsigned InlineCapacity, typename Allocator>
+    6399             : constexpr
+    6400             : typename small_vector<T, InlineCapacity, Allocator>::reverse_iterator
+    6401             : rend (small_vector<T, InlineCapacity, Allocator>& v) noexcept
+    6402             : {
+    6403             :   return v.rend ();
+    6404             : }
+    6405             : 
+    6406             : template <typename T, unsigned InlineCapacity, typename Allocator>
+    6407             : constexpr
+    6408             : typename small_vector<T, InlineCapacity, Allocator>::const_reverse_iterator
+    6409             : rend (const small_vector<T, InlineCapacity, Allocator>& v) noexcept
+    6410             : {
+    6411             :   return v.rend ();
+    6412             : }
+    6413             : 
+    6414             : template <typename T, unsigned InlineCapacity, typename Allocator>
+    6415             : constexpr
+    6416             : typename small_vector<T, InlineCapacity, Allocator>::const_reverse_iterator
+    6417             : crend (const small_vector<T, InlineCapacity, Allocator>& v) noexcept
+    6418             : {
+    6419             :   return rend (v);
+    6420             : }
+    6421             : 
+    6422             : template <typename T, unsigned InlineCapacity, typename Allocator>
+    6423             : constexpr
+    6424             : typename small_vector<T, InlineCapacity, Allocator>::size_type
+    6425             : size (const small_vector<T, InlineCapacity, Allocator>& v) noexcept
+    6426             : {
+    6427             :   return v.size ();
+    6428             : }
+    6429             : 
+    6430             : template <typename T, unsigned InlineCapacity, typename Allocator>
+    6431             : constexpr
+    6432             : typename std::common_type<
+    6433             :   std::ptrdiff_t,
+    6434             :   typename std::make_signed<
+    6435             :     typename small_vector<T, InlineCapacity, Allocator>::size_type>::type>::type
+    6436             : ssize (const small_vector<T, InlineCapacity, Allocator>& v) noexcept
+    6437             : {
+    6438             :   using ret_type = typename std::common_type<
+    6439             :     std::ptrdiff_t,
+    6440             :     typename std::make_signed<decltype (v.size ())>::type>::type;
+    6441             :   return static_cast<ret_type> (v.size ());
+    6442             : }
+    6443             : 
+    6444             : template <typename T, unsigned InlineCapacity, typename Allocator>
+    6445             : PLUMED_GCH_NODISCARD constexpr
+    6446             : bool
+    6447             : empty (const small_vector<T, InlineCapacity, Allocator>& v) noexcept
+    6448             : {
+    6449             :   return v.empty ();
+    6450             : }
+    6451             : 
+    6452             : template <typename T, unsigned InlineCapacity, typename Allocator>
+    6453             : constexpr
+    6454             : typename small_vector<T, InlineCapacity, Allocator>::pointer
+    6455             : data (small_vector<T, InlineCapacity, Allocator>& v) noexcept
+    6456             : {
+    6457             :   return v.data ();
+    6458             : }
+    6459             : 
+    6460             : template <typename T, unsigned InlineCapacity, typename Allocator>
+    6461             : constexpr
+    6462             : typename small_vector<T, InlineCapacity, Allocator>::const_pointer
+    6463             : data (const small_vector<T, InlineCapacity, Allocator>& v) noexcept
+    6464             : {
+    6465             :   return v.data ();
+    6466             : }
+    6467             : 
+    6468             : #ifdef PLUMED_GCH_CTAD_SUPPORT
+    6469             : 
+    6470             : template <typename InputIt,
+    6471             :           unsigned InlineCapacity = default_buffer_size<
+    6472             :             std::allocator<typename std::iterator_traits<InputIt>::value_type>>::value,
+    6473             :           typename Allocator = std::allocator<typename std::iterator_traits<InputIt>::value_type>>
+    6474             : small_vector (InputIt, InputIt, Allocator = Allocator ())
+    6475             : -> small_vector<typename std::iterator_traits<InputIt>::value_type, InlineCapacity, Allocator>;
+    6476             : 
+    6477             : #endif
+    6478             : 
+    6479             : } // namespace gch
+    6480             : } // namespace PLMD
+    6481             : 
+    6482             : #endif // PLUMED_GCH_SMALL_VECTOR_HPP
+    6483             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/snow.png b/coverage/snow.png new file mode 100644 index 0000000000000000000000000000000000000000..2cdae107fceec6e7f02ac7acb4a34a82a540caa5 GIT binary patch literal 141 zcmeAS@N?(olHy`uVBq!ia0vp^j3CU&3?x-=hn)ga>?NMQuI!iC1^MM!lvI6;R0X`wF|Ns97GD8ntt^-nBo-U3d c6}OTTfNUlP#;5A{K>8RwUHx3vIVCg!071?oo&W#< literal 0 HcmV?d00001 diff --git a/coverage/symfunc/AngularTetra.cpp.func-sort-c.html b/coverage/symfunc/AngularTetra.cpp.func-sort-c.html new file mode 100644 index 000000000000..58c8fbfef094 --- /dev/null +++ b/coverage/symfunc/AngularTetra.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - symfunc/AngularTetra.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - symfunc - AngularTetra.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:222684.6 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7symfunc12AngularTetraC2ERKNS_13ActionOptionsE0
_ZN4PLMD7symfunc12AngularTetraC1ERKNS_13ActionOptionsE1
_ZN4PLMD7symfunc12AngularTetra16registerKeywordsERNS_8KeywordsE3
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/symfunc/AngularTetra.cpp.func.html b/coverage/symfunc/AngularTetra.cpp.func.html new file mode 100644 index 000000000000..5f625104fd33 --- /dev/null +++ b/coverage/symfunc/AngularTetra.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - symfunc/AngularTetra.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - symfunc - AngularTetra.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:222684.6 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7symfunc12AngularTetra16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD7symfunc12AngularTetraC1ERKNS_13ActionOptionsE1
_ZN4PLMD7symfunc12AngularTetraC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/symfunc/AngularTetra.cpp.gcov.html b/coverage/symfunc/AngularTetra.cpp.gcov.html new file mode 100644 index 000000000000..f565807aa6f6 --- /dev/null +++ b/coverage/symfunc/AngularTetra.cpp.gcov.html @@ -0,0 +1,162 @@ + + + + + + + + LCOV - plumed test coverage - symfunc/AngularTetra.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - symfunc - AngularTetra.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:222684.6 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2018 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received 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/ActionShortcut.h"
+      24             : #include "CoordinationNumbers.h"
+      25             : #include "multicolvar/MultiColvarShortcuts.h"
+      26             : 
+      27             : //+PLUMEDOC MCOLVAR TETRA_ANGULAR
+      28             : /*
+      29             : Calculate the angular tetra CV
+      30             : 
+      31             : \par Examples
+      32             : 
+      33             : */
+      34             : //+ENDPLUMEDOC
+      35             : 
+      36             : namespace PLMD {
+      37             : namespace symfunc {
+      38             : 
+      39             : class AngularTetra : public ActionShortcut {
+      40             : public:
+      41             :   static void registerKeywords( Keywords& keys );
+      42             :   explicit AngularTetra(const ActionOptions&ao);
+      43             : };
+      44             : 
+      45             : PLUMED_REGISTER_ACTION(AngularTetra,"TETRA_ANGULAR")
+      46             : 
+      47           3 : void AngularTetra::registerKeywords( Keywords& keys ) {
+      48           3 :   CoordinationNumbers::shortcutKeywords( keys );
+      49           6 :   keys.addFlag("NOPBC",false,"ignore the periodic boundary conditions when calculating distances");
+      50           6 :   keys.add("compulsory","CUTOFF","-1","ignore distances that have a value larger than this cutoff");
+      51          15 :   keys.remove("NN"); keys.remove("MM"); keys.remove("D_0"); keys.remove("R_0"); keys.remove("SWITCH");
+      52           6 :   keys.needsAction("DISTANCE_MATRIX"); keys.needsAction("NEIGHBORS");
+      53           6 :   keys.needsAction("GSYMFUNC_THREEBODY"); keys.needsAction("CUSTOM");
+      54           3 : }
+      55             : 
+      56           1 : AngularTetra::AngularTetra( const ActionOptions& ao):
+      57             :   Action(ao),
+      58           1 :   ActionShortcut(ao)
+      59             : {
+      60           1 :   bool nopbc; parseFlag("NOPBC",nopbc);
+      61           1 :   std::string pbcstr=""; if( nopbc ) pbcstr = " NOPBC";
+      62             :   // Read species input and create the matrix
+      63           3 :   std::string sp_str, rcut; parse("SPECIES",sp_str); parse("CUTOFF",rcut);
+      64           1 :   if( sp_str.length()>0 ) {
+      65           2 :     readInputLine( getShortcutLabel() + "_mat: DISTANCE_MATRIX COMPONENTS GROUP=" + sp_str + " CUTOFF=" + rcut + pbcstr );
+      66             :   } else {
+      67           0 :     std::string specA, specB; parse("SPECIESA",specA); parse("SPECIESB",specB);
+      68           0 :     if( specA.length()==0 ) error("missing input atoms");
+      69           0 :     if( specB.length()==0 ) error("missing SPECIESB keyword");
+      70           0 :     readInputLine( getShortcutLabel() + "_mat: DISTANCE_MATRIX COMPONENTS GROUPA=" + specA + " GROUPB=" + specB + " CUTOFF=" + rcut + pbcstr );
+      71             :   }
+      72             :   // Get the neighbors matrix
+      73           2 :   readInputLine( getShortcutLabel() + "_neigh: NEIGHBORS ARG=" + getShortcutLabel() + "_mat.w NLOWEST=4");
+      74             :   // Now construct the symmetry function (sum of cos(a) + 1/3)
+      75           3 :   readInputLine( getShortcutLabel() + "_g8: GSYMFUNC_THREEBODY WEIGHT=" + getShortcutLabel() + "_neigh " +
+      76           3 :                  "ARG=" + getShortcutLabel() + "_mat.x," + getShortcutLabel() + "_mat.y," + getShortcutLabel() + "_mat.z FUNCTION1={FUNC=(cos(ajik)+1/3)^2 LABEL=g8}");
+      77             :   // Now evaluate the actual per atom CV
+      78           2 :   readInputLine( getShortcutLabel() + ": CUSTOM ARG=" + getShortcutLabel() + "_g8.g8 FUNC=(1-(3*x/8)) PERIODIC=NO");
+      79             :   // And get the things to do with the quantities we have computed
+      80           1 :   std::map<std::string,std::string> keymap; multicolvar::MultiColvarShortcuts::readShortcutKeywords( keymap, this );
+      81           2 :   multicolvar::MultiColvarShortcuts::expandFunctions( getShortcutLabel(), getShortcutLabel(), "", keymap, this );
+      82           1 : }
+      83             : 
+      84             : }
+      85             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/symfunc/AtomicSMAC.cpp.func-sort-c.html b/coverage/symfunc/AtomicSMAC.cpp.func-sort-c.html new file mode 100644 index 000000000000..91e2c846a09b --- /dev/null +++ b/coverage/symfunc/AtomicSMAC.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - symfunc/AtomicSMAC.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - symfunc - AtomicSMAC.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:424691.3 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7symfunc10AtomicSMACC2ERKNS_13ActionOptionsE0
_ZN4PLMD7symfunc10AtomicSMACC1ERKNS_13ActionOptionsE1
_ZN4PLMD7symfunc10AtomicSMAC16registerKeywordsERNS_8KeywordsE5
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/symfunc/AtomicSMAC.cpp.func.html b/coverage/symfunc/AtomicSMAC.cpp.func.html new file mode 100644 index 000000000000..8592e60be5d0 --- /dev/null +++ b/coverage/symfunc/AtomicSMAC.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - symfunc/AtomicSMAC.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - symfunc - AtomicSMAC.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:424691.3 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7symfunc10AtomicSMAC16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD7symfunc10AtomicSMACC1ERKNS_13ActionOptionsE1
_ZN4PLMD7symfunc10AtomicSMACC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/symfunc/AtomicSMAC.cpp.gcov.html b/coverage/symfunc/AtomicSMAC.cpp.gcov.html new file mode 100644 index 000000000000..2c76a57cedef --- /dev/null +++ b/coverage/symfunc/AtomicSMAC.cpp.gcov.html @@ -0,0 +1,188 @@ + + + + + + + + LCOV - plumed test coverage - symfunc/AtomicSMAC.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - symfunc - AtomicSMAC.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:424691.3 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionShortcut.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "core/PlumedMain.h"
+      25             : #include "core/ActionSet.h"
+      26             : #include "core/ActionWithValue.h"
+      27             : #include "multicolvar/MultiColvarShortcuts.h"
+      28             : 
+      29             : //+PLUMEDOC MCOLVAR ATOMIC_SMAC
+      30             : /*
+      31             : Calculate the atomic smac CV
+      32             : 
+      33             : \par Examples
+      34             : 
+      35             : */
+      36             : //+ENDPLUMEDOC
+      37             : 
+      38             : namespace PLMD {
+      39             : namespace symfunc {
+      40             : 
+      41             : class AtomicSMAC : public ActionShortcut {
+      42             : public:
+      43             :   static void registerKeywords(Keywords& keys);
+      44             :   explicit AtomicSMAC(const ActionOptions&);
+      45             : };
+      46             : 
+      47             : PLUMED_REGISTER_ACTION(AtomicSMAC,"ATOMIC_SMAC")
+      48             : 
+      49           5 : void AtomicSMAC::registerKeywords(Keywords& keys) {
+      50           5 :   ActionShortcut::registerKeywords( keys );
+      51          10 :   keys.add("optional","SPECIES","");
+      52          10 :   keys.add("optional","SPECIESA","");
+      53          10 :   keys.add("optional","SPECIESB","");
+      54          10 :   keys.add("optional","SWITCH","This keyword is used if you want to employ an alternative to the continuous swiching function defined above. "
+      55             :            "The following provides information on the \\ref switchingfunction that are available. "
+      56             :            "When this keyword is present you no longer need the NN, MM, D_0 and R_0 keywords.");
+      57          10 :   keys.add("numbered","KERNEL","The kernels used in the function of the angle");
+      58          10 :   keys.add("optional","SWITCH_COORD","This keyword is used to define the coordination switching function.");
+      59          10 :   keys.reset_style("KERNEL","optional");
+      60           5 :   multicolvar::MultiColvarShortcuts::shortcutKeywords( keys );
+      61          15 :   keys.needsAction("CONTACT_MATRIX"); keys.needsAction("GSYMFUNC_THREEBODY"); keys.needsAction("ONES");
+      62           5 :   keys.needsAction("MATRIX_VECTOR_PRODUCT");
+      63           5 : }
+      64             : 
+      65           1 : AtomicSMAC::AtomicSMAC(const ActionOptions& ao):
+      66             :   Action(ao),
+      67           1 :   ActionShortcut(ao)
+      68             : {
+      69             :   // Create the matrices
+      70           2 :   std::string sw_input; parse("SWITCH",sw_input);
+      71           2 :   std::string sp_lab, sp_laba; parse("SPECIES",sp_lab); parse("SPECIESA",sp_laba);
+      72           1 :   std::string cmap_input = getShortcutLabel() + "_cmap: CONTACT_MATRIX";
+      73           1 :   if( sp_lab.length()>0 ) {
+      74           2 :     readInputLine( getShortcutLabel() + "_cmap: CONTACT_MATRIX GROUP=" + sp_lab + " COMPONENTS SWITCH={" + sw_input + "}");
+      75           0 :   } else if( sp_laba.length()>0 ) {
+      76           0 :     std::string sp_labb; parse("SPECIESB",sp_labb);
+      77           0 :     readInputLine( getShortcutLabel() + "_cmap: CONTACT_MATRIX GROUPA=" + sp_laba + " GROUPB=" + sp_labb + " COMPONENTS SWITCH={" + sw_input + "}");
+      78             :   }
+      79             :   // Now need the Gaussians
+      80             :   std::string mykernels;
+      81           1 :   for(unsigned i=1;; ++i) {
+      82           3 :     std::string kstr_inpt, istr, kern_str; Tools::convert( i, istr );
+      83           6 :     if( !parseNumbered("KERNEL",i,kstr_inpt ) ) { break; }
+      84           2 :     std::vector<std::string> words = Tools::getWords(kstr_inpt);
+      85           2 :     if( words[0]=="GAUSSIAN" ) kern_str="gaussian";
+      86           0 :     else error("unknown kernel type");
+      87           6 :     std::string center, var; Tools::parse(words,"CENTER",center); Tools::parse(words,"SIGMA",var);
+      88           3 :     if( mykernels.length()==0 ) mykernels = "exp(-(ajik-" + center + ")^2/(2*" + var + "*" + var + "))";
+      89           2 :     else mykernels = mykernels + "+exp(-(ajik-" + center + ")^2/(2*" + var + "*" + var + "))";
+      90           4 :   }
+      91             :   // Hard coded switching function on minimum distance here -- should be improved
+      92           3 :   readInputLine( getShortcutLabel() + "_ksum: GSYMFUNC_THREEBODY WEIGHT=" + getShortcutLabel() + "_cmap.w " +
+      93           3 :                  "ARG=" + getShortcutLabel() + "_cmap.x," + getShortcutLabel() + "_cmap.y," + getShortcutLabel() + "_cmap.z"
+      94           2 :                  " FUNCTION1={FUNC=" + mykernels + " LABEL=n} FUNCTION2={FUNC=1 LABEL=d}" );
+      95             :   // And just the sum of the coordination numbers
+      96           1 :   ActionWithValue* av = plumed.getActionSet().selectWithLabel<ActionWithValue*>( getShortcutLabel() + "_cmap");
+      97           1 :   plumed_assert( av && av->getNumberOfComponents()>0 && (av->copyOutput(0))->getRank()==2 );
+      98           1 :   std::string size; Tools::convert( (av->copyOutput(0))->getShape()[1], size );
+      99           2 :   readInputLine( getShortcutLabel() + "_ones: ONES SIZE=" + size );
+     100           2 :   readInputLine( getShortcutLabel() + "_denom: MATRIX_VECTOR_PRODUCT ARG=" + getShortcutLabel() + "_cmap.w," + getShortcutLabel() + "_ones");
+     101             :   // And the transformed switching functions
+     102           1 :   std::string swcoord_str; parse("SWITCH_COORD",swcoord_str);
+     103           2 :   readInputLine( getShortcutLabel() + "_mtdenom: MORE_THAN ARG=" + getShortcutLabel() + "_denom SWITCH={" + swcoord_str +"}");
+     104             :   // And matheval to get the final quantity
+     105           2 :   readInputLine( getShortcutLabel() + "_smac: CUSTOM ARG=" + getShortcutLabel() + "_ksum.n," + getShortcutLabel() + "_mtdenom," + getShortcutLabel() + "_ksum.d FUNC=x*y/z PERIODIC=NO");
+     106             :   // And this expands everything
+     107           2 :   multicolvar::MultiColvarShortcuts::expandFunctions( getShortcutLabel(), getShortcutLabel() + "_smac", "", this );
+     108           1 : }
+     109             : 
+     110             : }
+     111             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/symfunc/CoordShellVectorFunction.cpp.func-sort-c.html b/coverage/symfunc/CoordShellVectorFunction.cpp.func-sort-c.html new file mode 100644 index 000000000000..30fca3e9ffca --- /dev/null +++ b/coverage/symfunc/CoordShellVectorFunction.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - symfunc/CoordShellVectorFunction.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - symfunc - CoordShellVectorFunction.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:516578.5 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7symfunc24CoordShellVectorFunctionC2ERKNS_13ActionOptionsE0
_ZN4PLMD7symfunc24CoordShellVectorFunctionC1ERKNS_13ActionOptionsE8
_ZN4PLMD7symfunc24CoordShellVectorFunction16registerKeywordsERNS_8KeywordsE21
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/symfunc/CoordShellVectorFunction.cpp.func.html b/coverage/symfunc/CoordShellVectorFunction.cpp.func.html new file mode 100644 index 000000000000..d3602ae746b1 --- /dev/null +++ b/coverage/symfunc/CoordShellVectorFunction.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - symfunc/CoordShellVectorFunction.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - symfunc - CoordShellVectorFunction.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:516578.5 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7symfunc24CoordShellVectorFunction16registerKeywordsERNS_8KeywordsE21
_ZN4PLMD7symfunc24CoordShellVectorFunctionC1ERKNS_13ActionOptionsE8
_ZN4PLMD7symfunc24CoordShellVectorFunctionC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/symfunc/CoordShellVectorFunction.cpp.gcov.html b/coverage/symfunc/CoordShellVectorFunction.cpp.gcov.html new file mode 100644 index 000000000000..d9d40484aacb --- /dev/null +++ b/coverage/symfunc/CoordShellVectorFunction.cpp.gcov.html @@ -0,0 +1,307 @@ + + + + + + + + LCOV - plumed test coverage - symfunc/CoordShellVectorFunction.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - symfunc - CoordShellVectorFunction.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:516578.5 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2014-2020 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "CoordinationNumbers.h"
+      23             : #include "multicolvar/MultiColvarShortcuts.h"
+      24             : #include "core/ActionWithValue.h"
+      25             : #include "core/ActionShortcut.h"
+      26             : #include "core/ActionRegister.h"
+      27             : #include "core/PlumedMain.h"
+      28             : #include "core/ActionSet.h"
+      29             : 
+      30             : #include <string>
+      31             : #include <cmath>
+      32             : 
+      33             : namespace PLMD {
+      34             : namespace symfunc {
+      35             : 
+      36             : //+PLUMEDOC MCOLVAR COORDINATION_SHELL_FUNCTION
+      37             : /*
+      38             : Calculate an arbitrary function of all the bond vectors in the first coordination sphere of an atom
+      39             : 
+      40             : \par Examples
+      41             : 
+      42             : 
+      43             : */
+      44             : //+ENDPLUMEDOC
+      45             : 
+      46             : //+PLUMEDOC MCOLVAR COORDINATION_SHELL_AVERAGE
+      47             : /*
+      48             : Calculate an arbitrary function of all the bond vectors in the first coordination sphere of an atom and take an average
+      49             : 
+      50             : \par Examples
+      51             : 
+      52             : 
+      53             : */
+      54             : //+ENDPLUMEDOC
+      55             : 
+      56             : //+PLUMEDOC MCOLVAR SIMPLECUBIC
+      57             : /*
+      58             : Calculate whether or not the coordination spheres of atoms are arranged as they would be in a simple cubic structure.
+      59             : 
+      60             : We can measure how similar the environment around atom \f$i\f$ is to a simple cubic structure is by evaluating
+      61             : the following quantity:
+      62             : 
+      63             : \f[
+      64             : 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}) }
+      65             : \f]
+      66             : 
+      67             : 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
+      68             : 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
+      69             : over all of the other atoms in the system ensures that we are calculating an average
+      70             : 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$.
+      71             : This quantity is once again a multicolvar so you can compute it for multiple atoms using a single PLUMED action and then compute
+      72             : 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
+      73             : so on.  Notice also that you can rotate the reference frame if you are using a non-standard unit cell.
+      74             : 
+      75             : 
+      76             : \par Examples
+      77             : 
+      78             : The following input tells plumed to calculate the simple cubic parameter for the atoms 1-100 with themselves.
+      79             : The mean value is then calculated.
+      80             : \plumedfile
+      81             : SIMPLECUBIC SPECIES=1-100 R_0=1.0 MEAN
+      82             : \endplumedfile
+      83             : 
+      84             : The following input tells plumed to look at the ways atoms 1-100 are within 3.0 are arranged about atoms
+      85             : from 101-110.  The number of simple cubic parameters that are greater than 0.8 is then output
+      86             : \plumedfile
+      87             : 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}
+      88             : \endplumedfile
+      89             : 
+      90             : */
+      91             : //+ENDPLUMEDOC
+      92             : 
+      93             : //+PLUMEDOC MCOLVAR TETRAHEDRAL
+      94             : /*
+      95             : Calculate the degree to which the environment about ions has a tetrahedral order.
+      96             : 
+      97             : We can measure the degree to which the atoms in the first coordination shell around any atom, \f$i\f$ is
+      98             : is arranged like a tetrahedron using the following function.
+      99             : 
+     100             : \f[
+     101             :  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} +
+     102             :                                                                         \frac{(x_{ij} - y_{ij} - z_{ij})^3}{r_{ij}^3} +
+     103             :                                                                         \frac{(-x_{ij} + y_{ij} - z_{ij})^3}{r_{ij}^3} +
+     104             :                                                                         \frac{(-x_{ij} - y_{ij} + z_{ij})^3}{r_{ij}^3} \right]
+     105             : \f]
+     106             : 
+     107             : 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$
+     108             : are its three components.  The function  \f$\sigma( r_{ij} )\f$ is a \ref switchingfunction that acts on the distance between
+     109             : atoms \f$i\f$ and \f$j\f$.  The parameters of this function should be set so that the function is equal to one
+     110             : when atom \f$j\f$ is in the first coordination sphere of atom \f$i\f$ and is zero otherwise.
+     111             : 
+     112             : \par Examples
+     113             : 
+     114             : The following command calculates the average value of the TETRAHEDRAL parameter for a set of 64 atoms all of the same type
+     115             : and outputs this quantity to a file called colvar.
+     116             : 
+     117             : \plumedfile
+     118             : tt: TETRAHEDRAL SPECIES=1-64 SWITCH={RATIONAL D_0=1.3 R_0=0.2} MEAN
+     119             : PRINT ARG=tt.mean FILE=colvar
+     120             : \endplumedfile
+     121             : 
+     122             : The following command calculates the number of TETRAHEDRAL parameters that are greater than 0.8 in a set of 10 atoms.
+     123             : In this calculation it is assumed that there are two atom types A and B and that the first coordination sphere of the
+     124             : 10 atoms of type A contains atoms of type B.  The formula above is thus calculated for ten different A atoms and within
+     125             : it the sum over \f$j\f$ runs over 40 atoms of type B that could be in the first coordination sphere.
+     126             : 
+     127             : \plumedfile
+     128             : 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}
+     129             : PRINT ARG=tt.* FILE=colvar
+     130             : \endplumedfile
+     131             : 
+     132             : */
+     133             : //+ENDPLUMEDOC
+     134             : 
+     135             : class CoordShellVectorFunction : public ActionShortcut {
+     136             : public:
+     137             :   static void registerKeywords(Keywords& keys);
+     138             :   explicit CoordShellVectorFunction(const ActionOptions&);
+     139             : };
+     140             : 
+     141             : PLUMED_REGISTER_ACTION(CoordShellVectorFunction,"FCCUBIC")
+     142             : PLUMED_REGISTER_ACTION(CoordShellVectorFunction,"TETRAHEDRAL")
+     143             : PLUMED_REGISTER_ACTION(CoordShellVectorFunction,"SIMPLECUBIC")
+     144             : PLUMED_REGISTER_ACTION(CoordShellVectorFunction,"COORDINATION_SHELL_FUNCTION")
+     145             : PLUMED_REGISTER_ACTION(CoordShellVectorFunction,"COORDINATION_SHELL_AVERAGE")
+     146             : 
+     147          21 : void CoordShellVectorFunction::registerKeywords( Keywords& keys ) {
+     148          21 :   CoordinationNumbers::shortcutKeywords( keys );
+     149          42 :   keys.add("compulsory","FUNCTION","the function of the bond vectors that you would like to evaluate");
+     150          42 :   keys.add("compulsory","PHI","0.0","The Euler rotational angle phi");
+     151          42 :   keys.add("compulsory","THETA","0.0","The Euler rotational angle theta");
+     152          42 :   keys.add("compulsory","PSI","0.0","The Euler rotational angle psi");
+     153          42 :   keys.add("compulsory","ALPHA","3.0","The alpha parameter of the angular function that is used for FCCUBIC");
+     154          42 :   keys.addFlag("LOWMEM",false,"this flag does nothing and is present only to ensure back-compatibility");
+     155          63 :   keys.needsAction("CONTACT_MATRIX"); keys.needsAction("FCCUBIC_FUNC"); keys.needsAction("CUSTOM");
+     156          42 :   keys.needsAction("ONES"); keys.needsAction("MATRIX_VECTOR_PRODUCT");
+     157          21 : }
+     158             : 
+     159           8 : CoordShellVectorFunction::CoordShellVectorFunction(const ActionOptions& ao):
+     160             :   Action(ao),
+     161           8 :   ActionShortcut(ao)
+     162             : {
+     163           8 :   std::string matlab, sp_str, specA, specB; bool lowmem; parseFlag("LOWMEM",lowmem);
+     164           8 :   if( lowmem ) warning("LOWMEM flag is deprecated and is no longer required for this action");
+     165          32 :   parse("SPECIES",sp_str); parse("SPECIESA",specA); parse("SPECIESB",specB);
+     166           8 :   if( sp_str.length()>0 || specA.length()>0 ) {
+     167           8 :     matlab = getShortcutLabel() + "_mat";
+     168           8 :     CoordinationNumbers::expandMatrix( true, getShortcutLabel(),  sp_str, specA, specB, this );
+     169           0 :   } else error("found no input atoms use SPECIES/SPECIESA");
+     170          24 :   double phi, theta, psi; parse("PHI",phi); parse("THETA",theta); parse("PSI",psi);
+     171           8 :   std::vector<std::string> rotelements(9); std::string xvec = matlab + ".x", yvec = matlab + ".y", zvec = matlab + ".z";
+     172           8 :   if( phi!=0 || theta!=0 || psi!=0 ) {
+     173           0 :     Tools::convert( std::cos(psi)*std::cos(phi)-std::cos(theta)*std::sin(phi)*std::sin(psi), rotelements[0] );
+     174           0 :     Tools::convert( std::cos(psi)*std::sin(phi)+std::cos(theta)*std::cos(phi)*std::sin(psi), rotelements[1] );
+     175           0 :     Tools::convert( std::sin(psi)*std::sin(theta), rotelements[2] );
+     176             : 
+     177           0 :     Tools::convert( -std::sin(psi)*std::cos(phi)-std::cos(theta)*std::sin(phi)*std::cos(psi), rotelements[3] );
+     178           0 :     Tools::convert( -std::sin(psi)*std::sin(phi)+std::cos(theta)*std::cos(phi)*std::cos(psi), rotelements[4] );
+     179           0 :     Tools::convert( std::cos(psi)*std::sin(theta), rotelements[5] );
+     180             : 
+     181           0 :     Tools::convert( std::sin(theta)*std::sin(phi), rotelements[6] );
+     182           0 :     Tools::convert( -std::sin(theta)*std::cos(phi), rotelements[7] );
+     183           0 :     Tools::convert( std::cos(theta), rotelements[8] );
+     184           0 :     readInputLine( getShortcutLabel() + "_xrot: CUSTOM ARG=" + matlab + ".x," + matlab + ".y," + matlab + ".z FUNC=" + rotelements[0] + "*x+" + rotelements[1] + "*y+" + rotelements[2] + "*z PERIODIC=NO");
+     185           0 :     readInputLine( getShortcutLabel() + "_yrot: CUSTOM ARG=" + matlab + ".x," + matlab + ".y," + matlab + ".z FUNC=" + rotelements[3] + "*x+" + rotelements[4] + "*y+" + rotelements[5] + "*z PERIODIC=NO");
+     186           0 :     readInputLine( getShortcutLabel() + "_zrot: CUSTOM ARG=" + matlab + ".x," + matlab + ".y," + matlab + ".z FUNC=" + rotelements[6] + "*x+" + rotelements[7] + "*y+" + rotelements[8] + "*z PERIODIC=NO");
+     187             :   }
+     188             :   // Calculate FCC cubic function from bond vectors
+     189           8 :   if( getName()=="FCCUBIC" ) {
+     190           4 :     std::string alpha; parse("ALPHA",alpha);
+     191           8 :     readInputLine( getShortcutLabel() + "_vfunc: FCCUBIC_FUNC ARG=" + xvec + "," + yvec + "," + zvec+ " ALPHA=" + alpha);
+     192           4 :   } else if( getName()=="TETRAHEDRAL" ) {
+     193           2 :     readInputLine( getShortcutLabel() + "_r: CUSTOM ARG=" + xvec + "," + yvec + "," + zvec + " PERIODIC=NO FUNC=sqrt(x*x+y*y+z*z)");
+     194           3 :     readInputLine( getShortcutLabel() + "_vfunc: CUSTOM ARG=" + xvec + "," + yvec + "," + zvec + "," + getShortcutLabel() + "_r"
+     195           2 :                    + " VAR=x,y,z,r PERIODIC=NO FUNC=((x+y+z)/r)^3+((x-y-z)/r)^3+((-x+y-z)/r)^3+((-x-y+z)/r)^3" );
+     196           3 :   } else if( getName()=="SIMPLECUBIC" ) {
+     197           2 :     readInputLine( getShortcutLabel() + "_r: CUSTOM ARG=" + xvec + "," + yvec + "," + zvec + " PERIODIC=NO FUNC=sqrt(x*x+y*y+z*z)");
+     198           3 :     readInputLine( getShortcutLabel() + "_vfunc: CUSTOM ARG=" + xvec + "," + yvec + "," + zvec + "," + getShortcutLabel() + "_r"
+     199           2 :                    + " VAR=x,y,z,r PERIODIC=NO FUNC=(x^4+y^4+z^4)/(r^4)" );
+     200             :   } else {
+     201           2 :     std::string myfunc; parse("FUNCTION",myfunc);
+     202           2 :     if( myfunc.find("r")!=std::string::npos ) {
+     203           4 :       readInputLine( getShortcutLabel() + "_r: CUSTOM ARG=" + xvec + "," + yvec + "," + zvec + " PERIODIC=NO FUNC=sqrt(x*x+y*y+z*z)");
+     204           4 :       readInputLine( getShortcutLabel() + "_vfunc: CUSTOM ARG=" + xvec + "," + yvec + "," + zvec + "," + getShortcutLabel() + "_r VAR=x,y,z,r PERIODIC=NO FUNC=" + myfunc );
+     205           0 :     } else readInputLine( getShortcutLabel() + "_vfunc: CUSTOM ARG=" + xvec + "," + yvec + "," + zvec + " PERIODIC=NO FUNC=" + myfunc );
+     206             :   }
+     207             :   // Hadamard product of function above and weights
+     208          16 :   readInputLine( getShortcutLabel() + "_wvfunc: CUSTOM ARG=" + getShortcutLabel() + "_vfunc," + matlab + ".w FUNC=x*y PERIODIC=NO");
+     209             :   // And coordination numbers
+     210           8 :   ActionWithValue* av = plumed.getActionSet().selectWithLabel<ActionWithValue*>( getShortcutLabel() + "_mat");
+     211           8 :   plumed_assert( av && av->getNumberOfComponents()>0 && (av->copyOutput(0))->getRank()==2 );
+     212           8 :   std::string size; Tools::convert( (av->copyOutput(0))->getShape()[1], size );
+     213          16 :   readInputLine( getShortcutLabel() + "_ones: ONES SIZE=" + size );
+     214          16 :   readInputLine( getShortcutLabel() + ": MATRIX_VECTOR_PRODUCT ARG=" + getShortcutLabel() + "_wvfunc," + getShortcutLabel() + "_ones");
+     215           8 :   std::string olab=getShortcutLabel();
+     216           8 :   if( getName()!="COORDINATION_SHELL_FUNCTION" ) {
+     217           6 :     olab = getShortcutLabel() + "_n";
+     218             :     // Calculate coordination numbers for denominator
+     219          12 :     readInputLine( getShortcutLabel() + "_denom: MATRIX_VECTOR_PRODUCT ARG=" + matlab + ".w," + getShortcutLabel() + "_ones");
+     220             :     // And normalise
+     221          12 :     readInputLine( getShortcutLabel() + "_n: CUSTOM ARG=" + getShortcutLabel() + "," + getShortcutLabel() + "_denom FUNC=x/y PERIODIC=NO");
+     222             :   }
+     223             :   // And expand the functions
+     224           8 :   std::map<std::string,std::string> keymap; multicolvar::MultiColvarShortcuts::readShortcutKeywords( keymap, this );
+     225          16 :   multicolvar::MultiColvarShortcuts::expandFunctions( getShortcutLabel(), olab, "", keymap, this );
+     226          16 : }
+     227             : 
+     228             : }
+     229             : }
+     230             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/symfunc/CoordinationNumbers.cpp.func-sort-c.html b/coverage/symfunc/CoordinationNumbers.cpp.func-sort-c.html new file mode 100644 index 000000000000..627f28f0318c --- /dev/null +++ b/coverage/symfunc/CoordinationNumbers.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - symfunc/CoordinationNumbers.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - symfunc - CoordinationNumbers.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:686998.6 %
Date:2024-04-19 12:12:35Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7symfunc19CoordinationNumbersC2ERKNS_13ActionOptionsE0
_ZN4PLMD7symfunc19CoordinationNumbersC1ERKNS_13ActionOptionsE45
_ZN4PLMD7symfunc19CoordinationNumbers16registerKeywordsERNS_8KeywordsE67
_ZN4PLMD7symfunc19CoordinationNumbers12expandMatrixERKbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESB_SB_SB_PNS_14ActionShortcutE106
_ZN4PLMD7symfunc19CoordinationNumbers16shortcutKeywordsERNS_8KeywordsE172
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/symfunc/CoordinationNumbers.cpp.func.html b/coverage/symfunc/CoordinationNumbers.cpp.func.html new file mode 100644 index 000000000000..c2fb9c497e09 --- /dev/null +++ b/coverage/symfunc/CoordinationNumbers.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - symfunc/CoordinationNumbers.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - symfunc - CoordinationNumbers.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:686998.6 %
Date:2024-04-19 12:12:35Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7symfunc19CoordinationNumbers12expandMatrixERKbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESB_SB_SB_PNS_14ActionShortcutE106
_ZN4PLMD7symfunc19CoordinationNumbers16registerKeywordsERNS_8KeywordsE67
_ZN4PLMD7symfunc19CoordinationNumbers16shortcutKeywordsERNS_8KeywordsE172
_ZN4PLMD7symfunc19CoordinationNumbersC1ERKNS_13ActionOptionsE45
_ZN4PLMD7symfunc19CoordinationNumbersC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/symfunc/CoordinationNumbers.cpp.gcov.html b/coverage/symfunc/CoordinationNumbers.cpp.gcov.html new file mode 100644 index 000000000000..588c51f99a12 --- /dev/null +++ b/coverage/symfunc/CoordinationNumbers.cpp.gcov.html @@ -0,0 +1,272 @@ + + + + + + + + LCOV - plumed test coverage - symfunc/CoordinationNumbers.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - symfunc - CoordinationNumbers.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:686998.6 %
Date:2024-04-19 12:12:35Functions:4580.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "CoordinationNumbers.h"
+      23             : #include "multicolvar/MultiColvarShortcuts.h"
+      24             : #include "core/ActionWithValue.h"
+      25             : #include "core/ActionRegister.h"
+      26             : #include "core/PlumedMain.h"
+      27             : #include "core/ActionSet.h"
+      28             : 
+      29             : #include <string>
+      30             : #include <cmath>
+      31             : 
+      32             : namespace PLMD {
+      33             : namespace symfunc {
+      34             : 
+      35             : //+PLUMEDOC MCOLVAR COORDINATIONNUMBER
+      36             : /*
+      37             : Calculate the coordination numbers of atoms so that you can then calculate functions of the distribution of
+      38             :  coordination numbers such as the minimum, the number less than a certain quantity and so on.
+      39             : 
+      40             : So that the calculated coordination numbers have continuous derivatives the following function is used:
+      41             : 
+      42             : \f[
+      43             : s = \frac{ 1 - \left(\frac{r-d_0}{r_0}\right)^n } { 1 - \left(\frac{r-d_0}{r_0}\right)^m }
+      44             : \f]
+      45             : 
+      46             : If R_POWER is set, this will use the product of pairwise distance
+      47             : raised to the R_POWER with the coordination number function defined
+      48             : above. This was used in White and Voth \cite white2014efficient as a
+      49             : way of indirectly biasing radial distribution functions. Note that in
+      50             : that reference this function is referred to as moments of coordination
+      51             : number, but here we call them powers to distinguish from the existing
+      52             : MOMENTS keyword of Multicolvars.
+      53             : 
+      54             : \par Examples
+      55             : 
+      56             : The following input tells plumed to calculate the coordination numbers of atoms 1-100 with themselves.
+      57             : The minimum coordination number is then calculated.
+      58             : \plumedfile
+      59             : COORDINATIONNUMBER SPECIES=1-100 R_0=1.0 MIN={BETA=0.1}
+      60             : \endplumedfile
+      61             : 
+      62             : The following input tells plumed to calculate how many atoms from 1-100 are within 3.0 of each of the atoms
+      63             : from 101-110.  In the first 101 is the central atom, in the second 102 is the central atom and so on.  The
+      64             : number of coordination numbers more than 6 is then computed.
+      65             : \plumedfile
+      66             : 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}
+      67             : \endplumedfile
+      68             : 
+      69             : The following input tells plumed to calculate the mean coordination number of all atoms with themselves
+      70             : and its powers. An explicit cutoff is set for each of 8.
+      71             : \plumedfile
+      72             : cn0: COORDINATIONNUMBER SPECIES=1-10 SWITCH={RATIONAL R_0=1.0 D_MAX=8} MEAN
+      73             : cn1: COORDINATIONNUMBER SPECIES=1-10 SWITCH={RATIONAL R_0=1.0 D_MAX=8} R_POWER=1 MEAN
+      74             : cn2: COORDINATIONNUMBER SPECIES=1-10 SWITCH={RATIONAL R_0=1.0 D_MAX=8} R_POWER=2 MEAN
+      75             : PRINT ARG=cn0.mean,cn1.mean,cn2.mean STRIDE=1 FILE=cn_out
+      76             : \endplumedfile
+      77             : 
+      78             : */
+      79             : //+ENDPLUMEDOC
+      80             : 
+      81             : //+PLUMEDOC MCOLVAR COORDINATION_MOMENTS
+      82             : /*
+      83             : Calculate moments of the distribution of distances in the first coordination sphere
+      84             : 
+      85             : \par Examples
+      86             : 
+      87             : */
+      88             : //+ENDPLUMEDOC
+      89             : 
+      90             : 
+      91             : PLUMED_REGISTER_ACTION(CoordinationNumbers,"COORDINATIONNUMBER")
+      92             : PLUMED_REGISTER_ACTION(CoordinationNumbers,"COORDINATION_MOMENTS")
+      93             : 
+      94         172 : void CoordinationNumbers::shortcutKeywords( Keywords& keys ) {
+      95         172 :   ActionShortcut::registerKeywords( keys );
+      96         344 :   keys.add("atoms-3","SPECIES","this keyword is used for colvars such as coordination number. In that context it specifies that plumed should calculate "
+      97             :            "one coordination number for each of the atoms specified.  Each of these coordination numbers specifies how many of the "
+      98             :            "other specified atoms are within a certain cutoff of the central atom.  You can specify the atoms here as another multicolvar "
+      99             :            "action or using a MultiColvarFilter or ActionVolume action.  When you do so the quantity is calculated for those atoms specified "
+     100             :            "in the previous multicolvar.  This is useful if you would like to calculate the Steinhardt parameter for those atoms that have a "
+     101             :            "coordination number more than four for example");
+     102         344 :   keys.add("atoms-4","SPECIESA","this keyword is used for colvars such as the coordination number.  In that context it species that plumed should calculate "
+     103             :            "one coordination number for each of the atoms specified in SPECIESA.  Each of these cooordination numbers specifies how many "
+     104             :            "of the atoms specifies using SPECIESB is within the specified cutoff.  As with the species keyword the input can also be specified "
+     105             :            "using the label of another multicolvar");
+     106         344 :   keys.add("atoms-4","SPECIESB","this keyword is used for colvars such as the coordination number.  It must appear with SPECIESA.  For a full explanation see "
+     107             :            "the documentation for that keyword");
+     108         344 :   keys.add("compulsory","NN","6","The n parameter of the switching function ");
+     109         344 :   keys.add("compulsory","MM","0","The m parameter of the switching function; 0 implies 2*NN");
+     110         344 :   keys.add("compulsory","D_0","0.0","The d_0 parameter of the switching function");
+     111         344 :   keys.add("compulsory","R_0","The r_0 parameter of the switching function");
+     112         344 :   keys.add("optional","SWITCH","the switching function that it used in the construction of the contact matrix");
+     113         172 :   multicolvar::MultiColvarShortcuts::shortcutKeywords( keys );
+     114         344 :   keys.needsAction("CONTACT_MATRIX"); keys.needsAction("GROUP");
+     115         172 : }
+     116             : 
+     117         106 : void CoordinationNumbers::expandMatrix( const bool& components, const std::string& lab, const std::string& sp_str,
+     118             :                                         const std::string& spa_str, const std::string& spb_str, ActionShortcut* action ) {
+     119         106 :   if( sp_str.length()==0 && spa_str.length()==0 ) return;
+     120             : 
+     121         106 :   std::string matinp = lab  + "_mat: CONTACT_MATRIX";
+     122         106 :   if( sp_str.length()>0 ) {
+     123          67 :     matinp += " GROUP=" + sp_str;
+     124         134 :     action->readInputLine( lab + "_grp: GROUP ATOMS=" + sp_str );
+     125          39 :   } else if( spa_str.length()>0 ) {
+     126          78 :     matinp += " GROUPA=" + spa_str + " GROUPB=" + spb_str;
+     127          78 :     action->readInputLine( lab + "_grp: GROUP ATOMS=" + spa_str );
+     128             :   }
+     129             : 
+     130         212 :   std::string sw_str; action->parse("SWITCH",sw_str);
+     131         106 :   if( sw_str.length()>0 ) {
+     132         158 :     matinp += " SWITCH={" + sw_str + "}";
+     133             :   } else {
+     134          81 :     std::string r0; action->parse("R_0",r0); std::string d0; action->parse("D_0",d0);
+     135          27 :     if( r0.length()==0 ) action->error("missing switching function parameters use SWITCH/R_0");
+     136          54 :     std::string nn; action->parse("NN",nn); std::string mm; action->parse("MM",mm);
+     137          54 :     matinp += " R_0=" + r0 + " D_0=" + d0 + " NN=" + nn + " MM=" + mm;
+     138             :   }
+     139         106 :   if( components ) matinp += " COMPONENTS";
+     140         106 :   action->readInputLine( matinp );
+     141             : }
+     142             : 
+     143          67 : void CoordinationNumbers::registerKeywords( Keywords& keys ) {
+     144          67 :   shortcutKeywords( keys );
+     145         134 :   keys.add("compulsory","R_POWER","the power to which you want to raise the distance");
+     146         134 :   keys.addFlag("LOWMEM",false,"this flag does nothing and is present only to ensure back-compatibility");
+     147         134 :   keys.add("optional","MOMENTS","the list of moments that you would like to calculate");
+     148         134 :   keys.addOutputComponent("moment","MOMENT","the moments of the distribution");
+     149         201 :   keys.needsAction("MATRIX_VECTOR_PRODUCT"); keys.needsAction("ONES"); keys.needsAction("MOMENTS");
+     150          67 : }
+     151             : 
+     152          45 : CoordinationNumbers::CoordinationNumbers(const ActionOptions& ao):
+     153             :   Action(ao),
+     154          45 :   ActionShortcut(ao)
+     155             : {
+     156          45 :   bool lowmem; parseFlag("LOWMEM",lowmem);
+     157          45 :   if( lowmem ) warning("LOWMEM flag is deprecated and is no longer required for this action");
+     158             :   // Setup the contract matrix if that is what is needed
+     159             :   std::string matlab, sp_str, specA, specB;
+     160         180 :   parse("SPECIES",sp_str); parse("SPECIESA",specA); parse("SPECIESB",specB);
+     161          45 :   if( sp_str.length()>0 || specA.length()>0 ) {
+     162          90 :     matlab = getShortcutLabel() + "_mat"; bool comp=false;
+     163          48 :     if( getName()=="COORDINATION_MOMENTS" ) { comp=true; matlab = getShortcutLabel() + "_mat"; }
+     164          45 :     expandMatrix( comp, getShortcutLabel(), sp_str, specA, specB, this );
+     165           0 :   } else error("missing atoms input use SPECIES or SPECIESA/SPECIESB");
+     166          45 :   ActionWithValue* mb=plumed.getActionSet().selectWithLabel<ActionWithValue*>( matlab );
+     167          45 :   if( !mb ) error("could not find action with name " + matlab );
+     168          45 :   Value*  arg=mb->copyOutput(0);
+     169          45 :   if( arg->getRank()!=2 || arg->hasDerivatives() ) error("the input to this action should be a matrix or scalar");
+     170             :   // Create vector of ones to multiply input matrix by
+     171          45 :   std::string nones; Tools::convert( arg->getShape()[1], nones );
+     172          90 :   readInputLine( getShortcutLabel() + "_ones: ONES SIZE=" + nones );
+     173          45 :   if( getName()=="COORDINATION_MOMENTS" ) {
+     174             :     // Calculate the lengths of the vectors
+     175           3 :     std::string r_power; parse("R_POWER",r_power);
+     176           9 :     readInputLine( getShortcutLabel() + "_pow: CUSTOM ARG=" + matlab + ".x," + matlab + ".y," + matlab + ".z," + matlab + ".w VAR=x,y,z,w "
+     177           6 :                    + "PERIODIC=NO FUNC=w*(sqrt(x*x+y*y+z*z)^" + r_power +")");
+     178           6 :     matlab = getShortcutLabel() + "_pow";
+     179             :   }
+     180             :   // Calcualte coordination numbers as matrix vector times vector of ones
+     181          90 :   readInputLine( getShortcutLabel() + ": MATRIX_VECTOR_PRODUCT  ARG=" + matlab + "," + getShortcutLabel() + "_ones");
+     182          90 :   std::vector<std::string> moments; parseVector("MOMENTS",moments); Tools::interpretRanges( moments );
+     183          90 :   readInputLine( getShortcutLabel() + "_caverage: MEAN ARG=" + getShortcutLabel() + " PERIODIC=NO");
+     184          47 :   for(unsigned i=0; i<moments.size(); ++i) {
+     185           4 :     readInputLine( getShortcutLabel() + "_diffpow-" + moments[i] + ": CUSTOM ARG=" + getShortcutLabel() + "," + getShortcutLabel() + "_caverage PERIODIC=NO FUNC=(x-y)^" + moments[i] );
+     186           4 :     readInputLine( getShortcutLabel() + "_moment-" + moments[i] + ": MEAN ARG=" + getShortcutLabel() + "_diffpow-" + moments[i] + " PERIODIC=NO");
+     187             :   }
+     188             :   // Read in all the shortcut stuff
+     189          45 :   std::map<std::string,std::string> keymap; multicolvar::MultiColvarShortcuts::readShortcutKeywords( keymap, this );
+     190          90 :   multicolvar::MultiColvarShortcuts::expandFunctions( getShortcutLabel(), getShortcutLabel(), "", keymap, this );
+     191          90 : }
+     192             : 
+     193             : 
+     194             : }
+     195             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/symfunc/CylindricalHarmonic.cpp.func-sort-c.html b/coverage/symfunc/CylindricalHarmonic.cpp.func-sort-c.html new file mode 100644 index 000000000000..51f65b5a1ce4 --- /dev/null +++ b/coverage/symfunc/CylindricalHarmonic.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - symfunc/CylindricalHarmonic.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - symfunc - CylindricalHarmonic.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2424100.0 %
Date:2024-04-19 12:12:35Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7symfunc19CylindricalHarmonic24setPeriodicityForOutputsEPNS_15ActionWithValueE2
_ZN4PLMD7symfunc19CylindricalHarmonic4readEPNS_19ActionWithArgumentsE2
_ZN4PLMD7symfunc19CylindricalHarmonic16registerKeywordsERNS_8KeywordsE7
_ZNK4PLMD7symfunc19CylindricalHarmonic4calcEPKNS_19ActionWithArgumentsERKSt6vectorIdSaIdEERS7_RNS_6MatrixIdEE943610
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/symfunc/CylindricalHarmonic.cpp.func.html b/coverage/symfunc/CylindricalHarmonic.cpp.func.html new file mode 100644 index 000000000000..e8b4c0858742 --- /dev/null +++ b/coverage/symfunc/CylindricalHarmonic.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - symfunc/CylindricalHarmonic.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - symfunc - CylindricalHarmonic.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2424100.0 %
Date:2024-04-19 12:12:35Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7symfunc19CylindricalHarmonic16registerKeywordsERNS_8KeywordsE7
_ZN4PLMD7symfunc19CylindricalHarmonic24setPeriodicityForOutputsEPNS_15ActionWithValueE2
_ZN4PLMD7symfunc19CylindricalHarmonic4readEPNS_19ActionWithArgumentsE2
_ZNK4PLMD7symfunc19CylindricalHarmonic4calcEPKNS_19ActionWithArgumentsERKSt6vectorIdSaIdEERS7_RNS_6MatrixIdEE943610
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/symfunc/CylindricalHarmonic.cpp.gcov.html b/coverage/symfunc/CylindricalHarmonic.cpp.gcov.html new file mode 100644 index 000000000000..a0fc1840a415 --- /dev/null +++ b/coverage/symfunc/CylindricalHarmonic.cpp.gcov.html @@ -0,0 +1,174 @@ + + + + + + + + LCOV - plumed test coverage - symfunc/CylindricalHarmonic.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - symfunc - CylindricalHarmonic.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2424100.0 %
Date:2024-04-19 12:12:35Functions:44100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2017 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received 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/FunctionTemplateBase.h"
+      23             : #include "function/FunctionShortcut.h"
+      24             : #include "adjmat/FunctionOfMatrix.h"
+      25             : #include "core/ActionRegister.h"
+      26             : 
+      27             : #include <complex>
+      28             : 
+      29             : namespace PLMD {
+      30             : namespace symfunc {
+      31             : 
+      32             : //+PLUMEDOC MCOLVAR CYLINDRICAL_HARMONIC
+      33             : /*
+      34             : Calculate the cylindrical harmonic function
+      35             : 
+      36             : \par Examples
+      37             : 
+      38             : 
+      39             : */
+      40             : //+ENDPLUMEDOC
+      41             : 
+      42             : //+PLUMEDOC MCOLVAR CYLINDRICAL_HARMONIC_MATRIX
+      43             : /*
+      44             : Calculate the cylindrical harmonic function from the elements in two input matrices
+      45             : 
+      46             : \par Examples
+      47             : 
+      48             : 
+      49             : */
+      50             : //+ENDPLUMEDOC
+      51             : 
+      52             : 
+      53          10 : class CylindricalHarmonic : public function::FunctionTemplateBase {
+      54             : private:
+      55             :   int tmom;
+      56             : public:
+      57             :   void registerKeywords( Keywords& keys ) override;
+      58             :   void read( ActionWithArguments* action ) override;
+      59             :   void setPeriodicityForOutputs( ActionWithValue* action ) override;
+      60             :   void calc( const ActionWithArguments* action, const std::vector<double>& args, std::vector<double>& vals, Matrix<double>& derivatives ) const override;
+      61             : };
+      62             : 
+      63             : typedef function::FunctionShortcut<CylindricalHarmonic> CyHarmShortcut;
+      64             : PLUMED_REGISTER_ACTION(CyHarmShortcut,"CYLINDRICAL_HARMONIC")
+      65             : typedef adjmat::FunctionOfMatrix<CylindricalHarmonic> MatrixCyHarm;
+      66             : PLUMED_REGISTER_ACTION(MatrixCyHarm,"CYLINDRICAL_HARMONIC_MATRIX")
+      67             : 
+      68           7 : void CylindricalHarmonic::registerKeywords( Keywords& keys ) {
+      69          14 :   keys.add("compulsory","DEGREE","the value of the n parameter in the equation above");
+      70          14 :   keys.addOutputComponent("rm","default","the real part of the cylindrical harmonic");
+      71          14 :   keys.addOutputComponent("im","default","the imaginary part of the cylindrical harmonic");
+      72           7 : }
+      73             : 
+      74           2 : void CylindricalHarmonic::read( ActionWithArguments* action ) {
+      75           2 :   parse(action,"DEGREE",tmom);
+      76           2 :   action->log.printf("  calculating %dth order cylindrical harmonic with %s and %s as input \n", tmom, action->getPntrToArgument(0)->getName().c_str(), action->getPntrToArgument(1)->getName().c_str() );
+      77           2 :   if( action->getNumberOfArguments()==3 ) action->log.printf("  multiplying cylindrical harmonic by weight from %s \n", action->getPntrToArgument(2)->getName().c_str() );
+      78           2 : }
+      79             : 
+      80           2 : void CylindricalHarmonic::setPeriodicityForOutputs( ActionWithValue* action ) {
+      81           4 :   action->componentIsNotPeriodic("rm"); action->componentIsNotPeriodic("im");
+      82           2 : }
+      83             : 
+      84      943610 : void CylindricalHarmonic::calc( const ActionWithArguments* action, const std::vector<double>& args, std::vector<double>& vals, Matrix<double>& derivatives ) const {
+      85      943610 :   double dlen2 = args[0]*args[0] + args[1]*args[1]; double dlen = sqrt( dlen2 ); double dlen3 = dlen2*dlen;
+      86      943610 :   std::complex<double> com1( args[0]/dlen,args[1]/dlen ); double weight=1; if( args.size()==3 ) weight=args[2];
+      87      943610 :   std::complex<double> ppp = pow( com1, tmom-1 ), ii( 0, 1 ); double real_z = real( ppp*com1 ), imag_z = imag( ppp*com1 );
+      88      943610 :   std::complex<double> dp_x = static_cast<double>(tmom)*ppp*( (1.0/dlen)-(args[0]*args[0])/dlen3-ii*(args[0]*args[1])/dlen3 );
+      89      943610 :   std::complex<double> dp_y = static_cast<double>(tmom)*ppp*( ii*(1.0/dlen)-(args[0]*args[1])/dlen3-ii*(args[1]*args[1])/dlen3 );
+      90      943610 :   vals[0] = weight*real_z; derivatives(0,0) = weight*real(dp_x); derivatives(0,1) = weight*real(dp_y);
+      91      943610 :   vals[1] = weight*imag_z; derivatives(1,0) = weight*imag(dp_x); derivatives(1,1) = weight*imag(dp_y);
+      92      943610 :   if( args.size()==3 ) { derivatives(0,2) = real_z; derivatives(1,2) = imag_z; }
+      93      943610 : }
+      94             : 
+      95             : }
+      96             : }
+      97             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/symfunc/Fccubic.cpp.func-sort-c.html b/coverage/symfunc/Fccubic.cpp.func-sort-c.html new file mode 100644 index 000000000000..c9ca702f3672 --- /dev/null +++ b/coverage/symfunc/Fccubic.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - symfunc/Fccubic.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - symfunc - Fccubic.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2929100.0 %
Date:2024-04-19 12:12:35Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7symfunc7Fccubic4readEPNS_19ActionWithArgumentsE5
_ZN4PLMD7symfunc7Fccubic16registerKeywordsERNS_8KeywordsE14
_ZNK4PLMD7symfunc7Fccubic4calcEPKNS_19ActionWithArgumentsERKSt6vectorIdSaIdEERS7_RNS_6MatrixIdEE2486314
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/symfunc/Fccubic.cpp.func.html b/coverage/symfunc/Fccubic.cpp.func.html new file mode 100644 index 000000000000..6df393fa94eb --- /dev/null +++ b/coverage/symfunc/Fccubic.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - symfunc/Fccubic.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - symfunc - Fccubic.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2929100.0 %
Date:2024-04-19 12:12:35Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7symfunc7Fccubic16registerKeywordsERNS_8KeywordsE14
_ZN4PLMD7symfunc7Fccubic4readEPNS_19ActionWithArgumentsE5
_ZNK4PLMD7symfunc7Fccubic4calcEPKNS_19ActionWithArgumentsERKSt6vectorIdSaIdEERS7_RNS_6MatrixIdEE2486314
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/symfunc/Fccubic.cpp.gcov.html b/coverage/symfunc/Fccubic.cpp.gcov.html new file mode 100644 index 000000000000..78d27f7fe0df --- /dev/null +++ b/coverage/symfunc/Fccubic.cpp.gcov.html @@ -0,0 +1,226 @@ + + + + + + + + LCOV - plumed test coverage - symfunc/Fccubic.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - symfunc - Fccubic.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2929100.0 %
Date:2024-04-19 12:12:35Functions:33100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2014-2020 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received 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/FunctionTemplateBase.h"
+      23             : #include "function/FunctionShortcut.h"
+      24             : #include "adjmat/FunctionOfMatrix.h"
+      25             : #include "core/ActionRegister.h"
+      26             : 
+      27             : #include <string>
+      28             : #include <cmath>
+      29             : 
+      30             : namespace PLMD {
+      31             : namespace symfunc {
+      32             : 
+      33             : //+PLUMEDOC MCOLVAR FCCUBIC_FUNC
+      34             : /*
+      35             : Measure how similar the environment around atoms is to that found in a FCC structure.
+      36             : 
+      37             : \par Examples
+      38             : 
+      39             : */
+      40             : //+ENDPLUMEDOC
+      41             : 
+      42             : //+PLUMEDOC MCOLVAR FCCUBIC_FUNC_MATRIX
+      43             : /*
+      44             : Measure how similar the environment around atoms is to that found in a FCC structure.
+      45             : 
+      46             : \par Examples
+      47             : 
+      48             : */
+      49             : //+ENDPLUMEDOC
+      50             : 
+      51             : //+PLUMEDOC MCOLVAR FCCUBIC
+      52             : /*
+      53             : Measure how similar the environment around atoms is to that found in a FCC structure.
+      54             : 
+      55             : This CV was introduced in this article \cite fcc-michele-1 and again in this article \cite fcc-michele-2
+      56             : This CV essentially determines whether the environment around any given atom is similar to that found in
+      57             : the FCC structure or not.  The function that is used to make this determination is as follows:
+      58             : 
+      59             : \f[
+      60             : 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}) }
+      61             : \f]
+      62             : 
+      63             : 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
+      64             : 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
+      65             : 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
+      66             : over all of the other atoms in the system ensures that we are calculating an average
+      67             : 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$
+      68             : 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:
+      69             : 
+      70             : \f[
+      71             : a = \frac{ 80080}{ 2717 + 16 \alpha} \qquad \textrm{and} \qquad b = \frac{ 16(\alpha - 143) }{2717 + 16\alpha}
+      72             : \f]
+      73             : 
+      74             : This quantity is once again a multicolvar so you can compute it for multiple atoms using a single PLUMED action and then compute
+      75             : 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
+      76             : so on.  Notice also that you can rotate the reference frame if you are using a non-standard unit cell.
+      77             : 
+      78             : \par Examples
+      79             : 
+      80             : The following input calculates the FCCUBIC parameter for the 64 atoms in the system
+      81             : and then calculates and prints the average value for this quantity.
+      82             : 
+      83             : \plumedfile
+      84             : FCCUBIC SPECIES=1-64 SWITCH={RATIONAL D_0=3.0 R_0=1.5} MEAN LABEL=d
+      85             : PRINT ARG=d.* FILE=colv
+      86             : \endplumedfile
+      87             : 
+      88             : */
+      89             : //+ENDPLUMEDOC
+      90             : 
+      91             : 
+      92          24 : class Fccubic : public function::FunctionTemplateBase {
+      93             : private:
+      94             :   double alpha, a1, b1;
+      95             : public:
+      96             :   void registerKeywords( Keywords& keys ) override;
+      97             :   void read( ActionWithArguments* action ) override;
+      98             :   void calc( const ActionWithArguments* action, const std::vector<double>& args, std::vector<double>& vals, Matrix<double>& derivatives ) const override;
+      99             : };
+     100             : 
+     101             : typedef function::FunctionShortcut<Fccubic> FccubicShortcut;
+     102             : PLUMED_REGISTER_ACTION(FccubicShortcut,"FCCUBIC_FUNC")
+     103             : typedef adjmat::FunctionOfMatrix<Fccubic> MatrixFccubic;
+     104             : PLUMED_REGISTER_ACTION(MatrixFccubic,"FCCUBIC_FUNC_MATRIX")
+     105             : 
+     106          14 : void Fccubic::registerKeywords( Keywords& keys ) {
+     107          28 :   keys.add("compulsory","ALPHA","3.0","The alpha parameter of the angular function");
+     108          14 : }
+     109             : 
+     110           5 : void Fccubic::read( ActionWithArguments* action ) {
+     111             :   // Scaling factors such that '1' corresponds to fcc lattice
+     112             :   // and '0' corresponds to isotropic (liquid)
+     113           5 :   parse(action,"ALPHA",alpha);
+     114           5 :   a1 = 80080. / (2717. + 16*alpha); b1 = 16.*(alpha-143)/(2717+16*alpha);
+     115           5 :   action->log.printf("  setting alpha paramter equal to %f \n",alpha);
+     116           5 : }
+     117             : 
+     118     2486314 : void Fccubic::calc( const ActionWithArguments* action, const std::vector<double>& args, std::vector<double>& vals, Matrix<double>& derivatives ) const {
+     119     2486314 :   double x2 = args[0]*args[0];
+     120     2486314 :   double x4 = x2*x2;
+     121             : 
+     122     2486314 :   double y2 = args[1]*args[1];
+     123     2486314 :   double y4 = y2*y2;
+     124             : 
+     125     2486314 :   double z2 = args[2]*args[2];
+     126     2486314 :   double z4 = z2*z2;
+     127             : 
+     128     2486314 :   double d2 = x2 + y2 + z2;
+     129     2486314 :   double r8 = pow( d2, 4 );
+     130     2486314 :   double r12 = pow( d2, 6 );
+     131             : 
+     132     2486314 :   double tmp = ((x4*y4)+(x4*z4)+(y4*z4))/r8-alpha*x4*y4*z4/r12;
+     133             : 
+     134     2486314 :   double t0 = (x2*y4+x2*z4)/r8-alpha*x2*y4*z4/r12;
+     135     2486314 :   double t1 = (y2*x4+y2*z4)/r8-alpha*y2*x4*z4/r12;
+     136     2486314 :   double t2 = (z2*x4+z2*y4)/r8-alpha*z2*x4*y4/r12;
+     137     2486314 :   double t3 = (2*tmp-alpha*x4*y4*z4/r12)/d2;
+     138             : 
+     139     2486314 :   derivatives(0,0)=4*a1*args[0]*(t0-t3);
+     140     2486314 :   derivatives(0,1)=4*a1*args[1]*(t1-t3);
+     141     2486314 :   derivatives(0,2)=4*a1*args[2]*(t2-t3);
+     142             : 
+     143             :   // Set the value and the derivatives
+     144     2486314 :   vals[0] = (a1*tmp+b1);
+     145     2486314 : }
+     146             : 
+     147             : }
+     148             : }
+     149             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/symfunc/HexaticParameter.cpp.func-sort-c.html b/coverage/symfunc/HexaticParameter.cpp.func-sort-c.html new file mode 100644 index 000000000000..0eb9eb0870b9 --- /dev/null +++ b/coverage/symfunc/HexaticParameter.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - symfunc/HexaticParameter.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - symfunc - HexaticParameter.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:384977.6 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7symfunc17HexacticParameterC2ERKNS_13ActionOptionsE0
_ZN4PLMD7symfunc17HexacticParameter21createVectorNormInputERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_S9_1
_ZN4PLMD7symfunc17HexacticParameterC1ERKNS_13ActionOptionsE1
_ZN4PLMD7symfunc17HexacticParameter16registerKeywordsERNS_8KeywordsE5
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/symfunc/HexaticParameter.cpp.func.html b/coverage/symfunc/HexaticParameter.cpp.func.html new file mode 100644 index 000000000000..091b3f6ad923 --- /dev/null +++ b/coverage/symfunc/HexaticParameter.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - symfunc/HexaticParameter.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - symfunc - HexaticParameter.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:384977.6 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7symfunc17HexacticParameter16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD7symfunc17HexacticParameter21createVectorNormInputERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_S9_1
_ZN4PLMD7symfunc17HexacticParameterC1ERKNS_13ActionOptionsE1
_ZN4PLMD7symfunc17HexacticParameterC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/symfunc/HexaticParameter.cpp.gcov.html b/coverage/symfunc/HexaticParameter.cpp.gcov.html new file mode 100644 index 000000000000..256e5802a1c8 --- /dev/null +++ b/coverage/symfunc/HexaticParameter.cpp.gcov.html @@ -0,0 +1,206 @@ + + + + + + + + LCOV - plumed test coverage - symfunc/HexaticParameter.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - symfunc - HexaticParameter.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:384977.6 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2017 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received 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 "multicolvar/MultiColvarShortcuts.h"
+      24             : #include "core/PlumedMain.h"
+      25             : #include "core/ActionSet.h"
+      26             : #include "core/ActionRegister.h"
+      27             : #include "core/ActionWithValue.h"
+      28             : #include "CoordinationNumbers.h"
+      29             : 
+      30             : #include <complex>
+      31             : 
+      32             : namespace PLMD {
+      33             : namespace symfunc {
+      34             : 
+      35             : //+PLUMEDOC MCOLVAR HEXACTIC_PARAMETER
+      36             : /*
+      37             : 
+      38             : \bug Virial is not working currently
+      39             : 
+      40             : \par Examples
+      41             : 
+      42             : 
+      43             : */
+      44             : //+ENDPLUMEDOC
+      45             : 
+      46             : 
+      47             : class HexacticParameter : public ActionShortcut {
+      48             : private:
+      49             :   void createVectorNormInput( const std::string& ilab, const std::string& olab, const std::string& vlab );
+      50             : public:
+      51             :   static void registerKeywords( Keywords& keys );
+      52             :   explicit HexacticParameter(const ActionOptions&);
+      53             : };
+      54             : 
+      55             : PLUMED_REGISTER_ACTION(HexacticParameter,"HEXACTIC_PARAMETER")
+      56             : 
+      57           5 : void HexacticParameter::registerKeywords( Keywords& keys ) {
+      58           5 :   CoordinationNumbers::shortcutKeywords( keys );
+      59          10 :   keys.add("compulsory","PLANE","the plane to use when calculating the value of the order parameter should be xy, xz or yz");
+      60          10 :   keys.addFlag("VMEAN",false,"calculate the norm of the mean vector.");
+      61          10 :   keys.addOutputComponent("_vmean","VMEAN","the norm of the mean vector");
+      62          10 :   keys.addFlag("VSUM",false,"calculate the norm of the sum of all the vectors");
+      63          10 :   keys.addOutputComponent("_vsum","VSUM","the norm of the mean vector");
+      64          10 :   keys.needsAction("CYLINDRICAL_HARMONIC_MATRIX"); keys.needsAction("ONES");
+      65          10 :   keys.needsAction("MATRIX_VECTOR_PRODUCT"); keys.needsAction("CUSTOM");
+      66          15 :   keys.needsAction("MEAN"); keys.needsAction("SUM"); keys.needsAction("COMBINE");
+      67           5 : }
+      68             : 
+      69           1 : HexacticParameter::HexacticParameter( const ActionOptions& ao):
+      70             :   Action(ao),
+      71           1 :   ActionShortcut(ao)
+      72             : {
+      73           3 :   std::string sp_str, specA, specB; parse("SPECIES",sp_str); parse("SPECIESA",specA); parse("SPECIESB",specB);
+      74           1 :   CoordinationNumbers::expandMatrix( true, getShortcutLabel(), sp_str, specA, specB, this );
+      75           2 :   std::string myplane; parse("PLANE",myplane);
+      76           1 :   if( myplane=="xy" ) {
+      77           2 :     readInputLine( getShortcutLabel() + ": CYLINDRICAL_HARMONIC_MATRIX DEGREE=6 ARG=" + getShortcutLabel() + "_mat.x," + getShortcutLabel() + "_mat.y," + getShortcutLabel() + "_mat.w" );
+      78           0 :   } else if( myplane=="xz" ) {
+      79           0 :     readInputLine( getShortcutLabel() + ": CYLINDRICAL_HARMONIC_MATRIX DEGREE=6 ARG=" + getShortcutLabel() + "_mat.x," + getShortcutLabel() + "_mat.z," + getShortcutLabel() + "_mat.w" );
+      80           0 :   } else if( myplane=="yz" ) {
+      81           0 :     readInputLine( getShortcutLabel() + ": CYLINDRICAL_HARMONIC_MATRIX DEGREE=6 ARG=" + getShortcutLabel() + "_mat.y," + getShortcutLabel() + "_mat.z," + getShortcutLabel() + "_mat.w" );
+      82           0 :   } else error("invalid input for plane -- should be xy, xz or yz");
+      83             :   // And coordination number
+      84           1 :   ActionWithValue* av = plumed.getActionSet().selectWithLabel<ActionWithValue*>( getShortcutLabel() + "_mat");
+      85           1 :   plumed_assert( av && av->getNumberOfComponents()>0 && (av->copyOutput(0))->getRank()==2 );
+      86           1 :   std::string size; Tools::convert( (av->copyOutput(0))->getShape()[1], size );
+      87           2 :   readInputLine( getShortcutLabel() + "_ones: ONES SIZE=" + size );
+      88           2 :   readInputLine( getShortcutLabel() + "_rm: MATRIX_VECTOR_PRODUCT ARG=" + getShortcutLabel() + ".rm," + getShortcutLabel() + "_ones");
+      89           2 :   readInputLine( getShortcutLabel() + "_im: MATRIX_VECTOR_PRODUCT ARG=" + getShortcutLabel() + ".im," + getShortcutLabel() + "_ones");
+      90             :   // Input for denominator (coord)
+      91           2 :   readInputLine( getShortcutLabel() + "_denom: MATRIX_VECTOR_PRODUCT ARG=" + getShortcutLabel() + "_mat.w," + getShortcutLabel() + "_ones");
+      92             :   // Divide real part by coordination numbers
+      93           2 :   readInputLine( getShortcutLabel() + "_rmn: CUSTOM ARG=" + getShortcutLabel() + "_rm," + getShortcutLabel() + "_denom FUNC=x/y PERIODIC=NO");
+      94             :   // Devide imaginary part by coordination number
+      95           2 :   readInputLine( getShortcutLabel() + "_imn: CUSTOM ARG=" + getShortcutLabel() + "_im," + getShortcutLabel() + "_denom FUNC=x/y PERIODIC=NO");
+      96             : 
+      97             :   // If we are doing VMEAN determine sum of vector components
+      98           1 :   bool do_vmean; parseFlag("VMEAN",do_vmean);
+      99           1 :   if( do_vmean ) {
+     100             :     // Real part
+     101           0 :     readInputLine( getShortcutLabel() + "_rms: MEAN ARG=" + getShortcutLabel() + "_rmn PERIODIC=NO");
+     102             :     // Imaginary part
+     103           0 :     readInputLine( getShortcutLabel() + "_ims: MEAN ARG=" + getShortcutLabel() + "_imn PERIODIC=NO");
+     104             :     // Now calculate the total length of the vector
+     105           0 :     createVectorNormInput( getShortcutLabel(), getShortcutLabel() + "_vmean", "ms" );
+     106             :   }
+     107           1 :   bool do_vsum; parseFlag("VSUM",do_vsum);
+     108           1 :   if( do_vsum ) {
+     109             :     // Real part
+     110           0 :     readInputLine( getShortcutLabel() + "_rmz: SUM ARG=" + getShortcutLabel() + "_rmn PERIODIC=NO");
+     111             :     // Imaginary part
+     112           0 :     readInputLine( getShortcutLabel() + "_imz: SUM ARG=" + getShortcutLabel() + "_imn PERIODIC=NO");
+     113             :     // Now calculate the total length of the vector
+     114           0 :     createVectorNormInput( getShortcutLabel(), getShortcutLabel() + "_vsum", "mz" );
+     115             :   }
+     116             : 
+     117             :   // Now calculate the total length of the vector
+     118           2 :   createVectorNormInput( getShortcutLabel(), getShortcutLabel() + "_norm", "mn" );
+     119           2 :   multicolvar::MultiColvarShortcuts::expandFunctions( getShortcutLabel(), getShortcutLabel() + "_norm", "", this );
+     120           1 : }
+     121             : 
+     122           1 : void HexacticParameter::createVectorNormInput( const std::string& ilab, const std::string& olab, const std::string& vlab ) {
+     123           2 :   readInputLine( olab + "2: COMBINE PERIODIC=NO ARG=" + ilab + "_r" + vlab + "," + ilab + "_i" + vlab + " POWERS=2,2" );
+     124           2 :   readInputLine( olab + ": CUSTOM ARG=" + olab + "2 FUNC=sqrt(x) PERIODIC=NO");
+     125           1 : }
+     126             : 
+     127             : }
+     128             : }
+     129             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/symfunc/LocalAverage.cpp.func-sort-c.html b/coverage/symfunc/LocalAverage.cpp.func-sort-c.html new file mode 100644 index 000000000000..ee22c625b5d7 --- /dev/null +++ b/coverage/symfunc/LocalAverage.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - symfunc/LocalAverage.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - symfunc - LocalAverage.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:5353100.0 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7symfunc12LocalAverageC2ERKNS_13ActionOptionsE0
_ZN4PLMD7symfunc12LocalAverageC1ERKNS_13ActionOptionsE10
_ZN4PLMD7symfunc12LocalAverage16registerKeywordsERNS_8KeywordsE12
_ZNK4PLMD7symfunc12LocalAverage17getMomentumSymbolB5cxx11ERKi97
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/symfunc/LocalAverage.cpp.func.html b/coverage/symfunc/LocalAverage.cpp.func.html new file mode 100644 index 000000000000..0d041fe2459c --- /dev/null +++ b/coverage/symfunc/LocalAverage.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - symfunc/LocalAverage.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - symfunc - LocalAverage.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:5353100.0 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7symfunc12LocalAverage16registerKeywordsERNS_8KeywordsE12
_ZN4PLMD7symfunc12LocalAverageC1ERKNS_13ActionOptionsE10
_ZN4PLMD7symfunc12LocalAverageC2ERKNS_13ActionOptionsE0
_ZNK4PLMD7symfunc12LocalAverage17getMomentumSymbolB5cxx11ERKi97
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/symfunc/LocalAverage.cpp.gcov.html b/coverage/symfunc/LocalAverage.cpp.gcov.html new file mode 100644 index 000000000000..b28669f12813 --- /dev/null +++ b/coverage/symfunc/LocalAverage.cpp.gcov.html @@ -0,0 +1,247 @@ + + + + + + + + LCOV - plumed test coverage - symfunc/LocalAverage.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - symfunc - LocalAverage.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:5353100.0 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2017 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionShortcut.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "core/ActionWithValue.h"
+      25             : #include "multicolvar/MultiColvarShortcuts.h"
+      26             : #include "core/PlumedMain.h"
+      27             : #include "core/ActionSet.h"
+      28             : #include "CoordinationNumbers.h"
+      29             : #include <string>
+      30             : #include <cmath>
+      31             : 
+      32             : namespace PLMD {
+      33             : namespace symfunc {
+      34             : 
+      35             : //+PLUMEDOC MCOLVARF LOCAL_AVERAGE
+      36             : /*
+      37             : Calculate averages over spherical regions centered on atoms
+      38             : 
+      39             : As is explained in <a href="http://www.youtube.com/watch?v=iDvZmbWE5ps"> this video </a> certain multicolvars
+      40             : calculate one scalar quantity or one vector for each of the atoms in the system.  For example
+      41             : \ref COORDINATIONNUMBER measures the coordination number of each of the atoms in the system and \ref Q4 measures
+      42             : the 4th order Steinhardt parameter for each of the atoms in the system.  These quantities provide tell us something about
+      43             : the disposition of the atoms in the first coordination sphere of each of the atoms of interest.  Lechner and Dellago \cite dellago-q6
+      44             : have suggested that one can probe local order in a system by taking the average value of such symmetry functions over
+      45             : the atoms within a spherical cutoff of each of these atoms in the systems.  When this is done with Steinhardt parameters
+      46             : they claim this gives a coordinate that is better able to distinguish solid and liquid configurations of Lennard-Jones atoms.
+      47             : 
+      48             : You can calculate such locally averaged quantities within plumed by using the LOCAL_AVERAGE command.  This command calculates
+      49             : the following atom-centered quantities:
+      50             : 
+      51             : \f[
+      52             : s_i = \frac{ c_i + \sum_j \sigma(r_{ij})c_j }{ 1 + \sum_j \sigma(r_{ij}) }
+      53             : \f]
+      54             : 
+      55             : 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
+      56             : multicolvars.  The function \f$\sigma( r_{ij} )\f$ is a \ref switchingfunction that acts on the distance between
+      57             : 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
+      58             : when atom \f$j\f$ is in the first coordination sphere of atom \f$i\f$ and is zero otherwise.
+      59             : 
+      60             : The \f$s_i\f$ quantities calculated using the above command can be again thought of as atom-centred symmetry functions.  They
+      61             : thus operate much like multicolvars.  You can thus calculate properties of the distribution of \f$s_i\f$ values using MEAN, LESS_THAN, HISTOGRAM
+      62             : 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
+      63             : \ref AROUND command.
+      64             : 
+      65             : \par Examples
+      66             : 
+      67             : This example input calculates the coordination numbers for all the atoms in the system.  These coordination numbers are then averaged over
+      68             : spherical regions.  The number of averaged coordination numbers that are greater than 4 is then output to a file.
+      69             : 
+      70             : \plumedfile
+      71             : COORDINATIONNUMBER SPECIES=1-64 D_0=1.3 R_0=0.2 LABEL=d1
+      72             : LOCAL_AVERAGE ARG=d1 SWITCH={RATIONAL D_0=1.3 R_0=0.2} MORE_THAN={RATIONAL R_0=4} LABEL=la
+      73             : PRINT ARG=la.* FILE=colvar
+      74             : \endplumedfile
+      75             : 
+      76             : 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
+      77             : component by component over a spherical region.  The average value for this quantity is then outputeed to a file.  This calculates the
+      78             : quantities that were used in the paper by Lechner and Dellago \cite dellago-q6
+      79             : 
+      80             : \plumedfile
+      81             : Q4 SPECIES=1-64 SWITCH={RATIONAL D_0=1.3 R_0=0.2} LABEL=q4
+      82             : LOCAL_AVERAGE ARG=q4 SWITCH={RATIONAL D_0=1.3 R_0=0.2} MEAN LABEL=la
+      83             : PRINT ARG=la.* FILE=colvar
+      84             : \endplumedfile
+      85             : 
+      86             : */
+      87             : //+ENDPLUMEDOC
+      88             : 
+      89             : class LocalAverage : public ActionShortcut {
+      90             : private:
+      91             :   std::string getMomentumSymbol( const int& m ) const ;
+      92             : public:
+      93             :   static void registerKeywords( Keywords& keys );
+      94             :   explicit LocalAverage(const ActionOptions&);
+      95             : };
+      96             : 
+      97             : PLUMED_REGISTER_ACTION(LocalAverage,"LOCAL_AVERAGE")
+      98             : 
+      99          12 : void LocalAverage::registerKeywords( Keywords& keys ) {
+     100          12 :   CoordinationNumbers::shortcutKeywords( keys );
+     101          24 :   keys.needsAction("ONES"); keys.needsAction("MATRIX_VECTOR_PRODUCT");
+     102          36 :   keys.needsAction("VSTACK"); keys.needsAction("CUSTOM"); keys.needsAction("OUTER_PRODUCT");
+     103          12 : }
+     104             : 
+     105          10 : LocalAverage::LocalAverage(const ActionOptions&ao):
+     106             :   Action(ao),
+     107          10 :   ActionShortcut(ao)
+     108             : {
+     109          30 :   std::string sp_str, specA, specB; parse("SPECIES",sp_str); parse("SPECIESA",specA); parse("SPECIESB",specB);
+     110          10 :   CoordinationNumbers::expandMatrix( false, getShortcutLabel(), sp_str, specA, specB, this );
+     111          10 :   std::map<std::string,std::string> keymap; multicolvar::MultiColvarShortcuts::readShortcutKeywords( keymap, this );
+     112          10 :   if( sp_str.length()>0 ) specA=specB=sp_str;
+     113             :   // Calculate the coordination numbers
+     114          10 :   ActionWithValue* av = plumed.getActionSet().selectWithLabel<ActionWithValue*>( getShortcutLabel() + "_mat");
+     115          10 :   plumed_assert( av && av->getNumberOfComponents()>0 && (av->copyOutput(0))->getRank()==2 );
+     116          10 :   std::string size; Tools::convert( (av->copyOutput(0))->getShape()[1], size );
+     117          20 :   readInputLine( getShortcutLabel() + "_ones: ONES SIZE=" + size );
+     118          20 :   readInputLine( getShortcutLabel() + "_coord: MATRIX_VECTOR_PRODUCT ARG=" + getShortcutLabel() + "_mat," + getShortcutLabel() + "_ones" );
+     119             : 
+     120          10 :   int l=-1; std::vector<ActionShortcut*> shortcuts=plumed.getActionSet().select<ActionShortcut*>();
+     121          73 :   for(unsigned i=0; i<shortcuts.size(); ++i) {
+     122          72 :     if( specA==shortcuts[i]->getShortcutLabel() ) {
+     123          19 :       std::string sname = shortcuts[i]->getName();
+     124          79 :       if( sname=="Q1" || sname=="Q3" || sname=="Q4" || sname=="Q6" ) { Tools::convert( sname.substr(1), l ); break; }
+     125             :     }
+     126             :   }
+     127             : 
+     128          10 :   if( l>0 ) {
+     129           9 :     std::string vargs, svargs, sargs = "ARG=" + getShortcutLabel() + "_mat";
+     130         106 :     for(int i=-l; i<=l; ++i) {
+     131          97 :       std::string num = getMomentumSymbol(i);
+     132         194 :       if( !plumed.getActionSet().selectWithLabel<ActionWithValue*>(specB + "_rmn-" + num) ) {
+     133         194 :         readInputLine( specB + "_rmn-" + num + ": CUSTOM ARG=" + specB + "_sp.rm-" + num + "," + specB + "_denom FUNC=x/y PERIODIC=NO");
+     134             :       }
+     135         194 :       if( !plumed.getActionSet().selectWithLabel<ActionWithValue*>(specB + "_imn-" + num) ) {
+     136         194 :         readInputLine( specB  + "_imn-" + num + ": CUSTOM ARG=" + specB + "_sp.im-" + num + "," + specB  + "_denom FUNC=x/y PERIODIC=NO");
+     137             :       }
+     138         115 :       if( i==-l ) { vargs = "ARG=" + specB + "_rmn-" + num + "," + specB + "_imn-" + num; svargs = "ARG=" + getShortcutLabel() + "_prod." + specB + "_rmn-" + num + "," + getShortcutLabel() + "_prod." + specB + "_imn-" + num; }
+     139         264 :       else { vargs += "," +  specB + "_rmn-" + num + "," + specB + "_imn-" + num; svargs += "," + getShortcutLabel() + "_prod." + specB + "_rmn-" + num + "," + getShortcutLabel() + "_prod." + specB + "_imn-" + num; }
+     140         194 :       sargs += "," + specB + "_rmn-" + num + "," + specB  + "_imn-" + num;
+     141             :     }
+     142          18 :     readInputLine( getShortcutLabel() + "_vstack: VSTACK " + vargs );
+     143          18 :     readInputLine( getShortcutLabel() + "_prod: MATRIX_VECTOR_PRODUCT " + sargs );
+     144          18 :     readInputLine( getShortcutLabel() + "_vpstack: VSTACK " + svargs );
+     145          18 :     std::string twolplusone; Tools::convert( 2*(2*l+1), twolplusone ); readInputLine( getShortcutLabel() + "_lones: ONES SIZE=" + twolplusone );
+     146          18 :     readInputLine( getShortcutLabel() + "_unorm: OUTER_PRODUCT ARG=" + getShortcutLabel() + "_coord," + getShortcutLabel() + "_lones" );
+     147          18 :     readInputLine( getShortcutLabel() + "_av: CUSTOM ARG=" + getShortcutLabel() + "_vpstack," + getShortcutLabel() + "_vstack," + getShortcutLabel() + "_unorm FUNC=(x+y)/(1+z) PERIODIC=NO");
+     148          18 :     readInputLine( getShortcutLabel() + "_av2: CUSTOM ARG=" + getShortcutLabel() + "_av FUNC=x*x PERIODIC=NO");
+     149          18 :     readInputLine( getShortcutLabel() + "_2: MATRIX_VECTOR_PRODUCT ARG=" + getShortcutLabel() + "_av2," + getShortcutLabel() + "_lones");
+     150          18 :     readInputLine( getShortcutLabel() + ": CUSTOM ARG=" + getShortcutLabel() + "_2 FUNC=sqrt(x) PERIODIC=NO");
+     151             :   } else {
+     152           2 :     readInputLine( getShortcutLabel() + "_prod: MATRIX_VECTOR_PRODUCT ARG=" + getShortcutLabel() + "_mat," + sp_str + " " + convertInputLineToString() );
+     153           2 :     readInputLine( getShortcutLabel() + ": CUSTOM ARG=" + getShortcutLabel() + "_prod," + sp_str + "," + getShortcutLabel() + "_coord  FUNC=(x+y)/(1+z) PERIODIC=NO");
+     154             :   }
+     155          20 :   multicolvar::MultiColvarShortcuts::expandFunctions( getShortcutLabel(), getShortcutLabel(), "", keymap, this );
+     156          10 : }
+     157             : 
+     158          97 : std::string LocalAverage::getMomentumSymbol( const int& m ) const {
+     159          97 :   if( m<0 ) {
+     160          44 :     std::string num; Tools::convert( -1*m, num );
+     161          44 :     return "n" + num;
+     162          53 :   } else if( m>0 ) {
+     163          44 :     std::string num; Tools::convert( m, num );
+     164          44 :     return "p" + num;
+     165             :   }
+     166           9 :   return "0";
+     167             : }
+     168             : 
+     169             : }
+     170             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/symfunc/LocalCrystalinity.cpp.func-sort-c.html b/coverage/symfunc/LocalCrystalinity.cpp.func-sort-c.html new file mode 100644 index 000000000000..e6a1f177b035 --- /dev/null +++ b/coverage/symfunc/LocalCrystalinity.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - symfunc/LocalCrystalinity.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - symfunc - LocalCrystalinity.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3535100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7symfunc18LocalCrystallinityC2ERKNS_13ActionOptionsE0
_ZN4PLMD7symfunc18LocalCrystallinityC1ERKNS_13ActionOptionsE1
_ZN4PLMD7symfunc18LocalCrystallinity16registerKeywordsERNS_8KeywordsE3
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/symfunc/LocalCrystalinity.cpp.func.html b/coverage/symfunc/LocalCrystalinity.cpp.func.html new file mode 100644 index 000000000000..8b292d75f17c --- /dev/null +++ b/coverage/symfunc/LocalCrystalinity.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - symfunc/LocalCrystalinity.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - symfunc - LocalCrystalinity.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3535100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7symfunc18LocalCrystallinity16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD7symfunc18LocalCrystallinityC1ERKNS_13ActionOptionsE1
_ZN4PLMD7symfunc18LocalCrystallinityC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/symfunc/LocalCrystalinity.cpp.gcov.html b/coverage/symfunc/LocalCrystalinity.cpp.gcov.html new file mode 100644 index 000000000000..9866c1426dcc --- /dev/null +++ b/coverage/symfunc/LocalCrystalinity.cpp.gcov.html @@ -0,0 +1,183 @@ + + + + + + + + LCOV - plumed test coverage - symfunc/LocalCrystalinity.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - symfunc - LocalCrystalinity.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3535100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2017 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionShortcut.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "core/PlumedMain.h"
+      25             : #include "core/ActionSet.h"
+      26             : #include "core/ActionWithValue.h"
+      27             : #include "CoordinationNumbers.h"
+      28             : #include "multicolvar/MultiColvarShortcuts.h"
+      29             : 
+      30             : #include <complex>
+      31             : 
+      32             : namespace PLMD {
+      33             : namespace symfunc {
+      34             : 
+      35             : //+PLUMEDOC MCOLVAR LOCAL_CRYSTALINITY
+      36             : /*
+      37             : Calculate the local crystalinity symmetry function
+      38             : 
+      39             : \par Examples
+      40             : 
+      41             : 
+      42             : */
+      43             : //+ENDPLUMEDOC
+      44             : 
+      45             : 
+      46             : class LocalCrystallinity : public ActionShortcut {
+      47             : public:
+      48             :   static void registerKeywords( Keywords& keys );
+      49             :   explicit LocalCrystallinity(const ActionOptions&);
+      50             : };
+      51             : 
+      52             : PLUMED_REGISTER_ACTION(LocalCrystallinity,"LOCAL_CRYSTALINITY")
+      53             : 
+      54           3 : void LocalCrystallinity::registerKeywords( Keywords& keys ) {
+      55           3 :   CoordinationNumbers::shortcutKeywords( keys );
+      56           6 :   keys.add("numbered","GVECTOR","the coefficients of the linear combinations to compute for the CV");
+      57           6 :   keys.needsAction("ONES"); keys.needsAction("MATRIX_VECTOR_PRODUCT");
+      58           6 :   keys.needsAction("COMBINE"); keys.needsAction("CUSTOM");
+      59           3 : }
+      60             : 
+      61           1 : LocalCrystallinity::LocalCrystallinity( const ActionOptions& ao):
+      62             :   Action(ao),
+      63           1 :   ActionShortcut(ao)
+      64             : {
+      65             :   // This builds an adjacency matrix
+      66           3 :   std::string sp_str, specA, specB; parse("SPECIES",sp_str); parse("SPECIESA",specA); parse("SPECIESB",specB);
+      67           1 :   CoordinationNumbers::expandMatrix( true, getShortcutLabel(), sp_str, specA, specB, this );
+      68             :   // Input for denominator (coord)
+      69           1 :   ActionWithValue* av = plumed.getActionSet().selectWithLabel<ActionWithValue*>( getShortcutLabel() + "_mat");
+      70           1 :   plumed_assert( av && av->getNumberOfComponents()>0 && (av->copyOutput(0))->getRank()==2 );
+      71           1 :   std::string size; Tools::convert( (av->copyOutput(0))->getShape()[1], size );
+      72           2 :   readInputLine( getShortcutLabel() + "_ones: ONES SIZE=" + size );
+      73           2 :   readInputLine( getShortcutLabel() + "_denom: MATRIX_VECTOR_PRODUCT ARG=" + getShortcutLabel() + "_mat.w," + getShortcutLabel() + "_ones");
+      74             :   // Input for numerator
+      75           1 :   std::string finput = "";
+      76           1 :   for(unsigned i=1;; ++i) {
+      77           4 :     std::vector<std::string> gvec; std::string istr; Tools::convert( i, istr );
+      78           8 :     if( !parseNumberedVector("GVECTOR",i,gvec) ) { break; }
+      79           3 :     if( gvec.size()!=3 ) error("gvectors should have size 3");
+      80             :     // This is the dot product between the input gvector and the bond vector
+      81           9 :     readInputLine( getShortcutLabel() + "_dot" + istr + ": COMBINE ARG=" + getShortcutLabel() + "_mat.x," + getShortcutLabel() + "_mat.y," + getShortcutLabel() + "_mat.z "
+      82           6 :                    "PERIODIC=NO COEFFICIENTS=" + gvec[0] + "," + gvec[1] + "," + gvec[2] );
+      83             :     // Now calculate the sine and cosine of the dot product
+      84           6 :     readInputLine( getShortcutLabel() + "_cos" + istr + ": CUSTOM ARG=" + getShortcutLabel() +"_mat.w," + getShortcutLabel() + "_dot" + istr + " FUNC=x*cos(y) PERIODIC=NO");
+      85           6 :     readInputLine( getShortcutLabel() + "_sin" + istr + ": CUSTOM ARG=" + getShortcutLabel() +"_mat.w," + getShortcutLabel() + "_dot" + istr + " FUNC=x*sin(y) PERIODIC=NO");
+      86             :     // And sum up the sine and cosine over the coordination spheres
+      87           6 :     readInputLine( getShortcutLabel() + "_cossum" + istr + ": MATRIX_VECTOR_PRODUCT ARG=" + getShortcutLabel() + "_cos" + istr + "," + getShortcutLabel() + "_ones");
+      88           6 :     readInputLine( getShortcutLabel() + "_sinsum" + istr + ": MATRIX_VECTOR_PRODUCT ARG=" + getShortcutLabel() + "_sin" + istr + "," + getShortcutLabel() + "_ones");
+      89             :     // And average the sine and cosine over the number of bonds
+      90           6 :     readInputLine( getShortcutLabel() + "_cosmean" + istr + ": CUSTOM FUNC=x/y PERIODIC=NO ARG=" + getShortcutLabel() + "_cossum" + istr + "," + getShortcutLabel() + "_denom");
+      91           6 :     readInputLine( getShortcutLabel() + "_sinmean" + istr + ": CUSTOM FUNC=x/y PERIODIC=NO ARG=" + getShortcutLabel() + "_sinsum" + istr + "," + getShortcutLabel() + "_denom");
+      92             :     // And work out the square modulus of this complex number
+      93           6 :     readInputLine( getShortcutLabel() + "_" + istr + ": CUSTOM FUNC=x*x+y*y PERIODIC=NO ARG=" + getShortcutLabel() + "_cosmean" + istr + "," + getShortcutLabel() + "_sinmean" + istr);
+      94             :     // These are all the kvectors that we are adding together in the final combine for the final CV
+      95           3 :     if( i>1 ) finput += ",";
+      96           6 :     finput += getShortcutLabel() + "_" + istr;
+      97           4 :   }
+      98             :   // This computes the final CV
+      99           2 :   readInputLine( getShortcutLabel() + ": COMBINE NORMALIZE PERIODIC=NO ARG=" + finput );
+     100             :   // Now calculate the total length of the vector
+     101           2 :   multicolvar::MultiColvarShortcuts::expandFunctions( getShortcutLabel(), getShortcutLabel(), "", this );
+     102           1 : }
+     103             : 
+     104             : }
+     105             : }
+     106             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/symfunc/LocalSteinhardt.cpp.func-sort-c.html b/coverage/symfunc/LocalSteinhardt.cpp.func-sort-c.html new file mode 100644 index 000000000000..fa465fbbe317 --- /dev/null +++ b/coverage/symfunc/LocalSteinhardt.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - symfunc/LocalSteinhardt.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - symfunc - LocalSteinhardt.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:8310678.3 %
Date:2024-04-19 12:12:35Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7symfunc15LocalSteinhardtC2ERKNS_13ActionOptionsE0
_ZN4PLMD7symfunc15LocalSteinhardtC1ERKNS_13ActionOptionsE7
_ZNK4PLMD7symfunc15LocalSteinhardt15getArgsForStackERKiRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE9
_ZN4PLMD7symfunc15LocalSteinhardt16registerKeywordsERNS_8KeywordsE20
_ZNK4PLMD7symfunc15LocalSteinhardt9getSymbolB5cxx11ERKi98
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/symfunc/LocalSteinhardt.cpp.func.html b/coverage/symfunc/LocalSteinhardt.cpp.func.html new file mode 100644 index 000000000000..34e67e3412a9 --- /dev/null +++ b/coverage/symfunc/LocalSteinhardt.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - symfunc/LocalSteinhardt.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - symfunc - LocalSteinhardt.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:8310678.3 %
Date:2024-04-19 12:12:35Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7symfunc15LocalSteinhardt16registerKeywordsERNS_8KeywordsE20
_ZN4PLMD7symfunc15LocalSteinhardtC1ERKNS_13ActionOptionsE7
_ZN4PLMD7symfunc15LocalSteinhardtC2ERKNS_13ActionOptionsE0
_ZNK4PLMD7symfunc15LocalSteinhardt15getArgsForStackERKiRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE9
_ZNK4PLMD7symfunc15LocalSteinhardt9getSymbolB5cxx11ERKi98
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/symfunc/LocalSteinhardt.cpp.gcov.html b/coverage/symfunc/LocalSteinhardt.cpp.gcov.html new file mode 100644 index 000000000000..5d9b966c41b8 --- /dev/null +++ b/coverage/symfunc/LocalSteinhardt.cpp.gcov.html @@ -0,0 +1,522 @@ + + + + + + + + LCOV - plumed test coverage - symfunc/LocalSteinhardt.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - symfunc - LocalSteinhardt.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:8310678.3 %
Date:2024-04-19 12:12:35Functions:4580.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2017 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionShortcut.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "multicolvar/MultiColvarShortcuts.h"
+      25             : #include "core/PlumedMain.h"
+      26             : #include "core/ActionSet.h"
+      27             : #include "core/ActionWithValue.h"
+      28             : 
+      29             : namespace PLMD {
+      30             : namespace symfunc {
+      31             : 
+      32             : //+PLUMEDOC MCOLVARF LOCAL_Q1
+      33             : /*
+      34             : Calculate the local degree of order around an atoms by taking the average dot product between the \f$q_1\f$ vector on the central atom and the \f$q_3\f$ vector on the atoms in the first coordination sphere.
+      35             : 
+      36             : \par Examples
+      37             : 
+      38             : */
+      39             : //+ENDPLUMEDOC
+      40             : 
+      41             : //+PLUMEDOC MCOLVARF LOCAL_Q3
+      42             : /*
+      43             : Calculate the local degree of order around an atoms by taking the average dot product between the \f$q_3\f$ vector on the central atom and the \f$q_3\f$ vector on the atoms in the first coordination sphere.
+      44             : 
+      45             : 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
+      46             : 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
+      47             : 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
+      48             : 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
+      49             : 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
+      50             : 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
+      51             : because the number of atoms is relatively small.
+      52             : 
+      53             : When the average \ref Q3 parameter is used to bias the dynamics a problems
+      54             : can occur. These averaged coordinates cannot distinguish between the correct,
+      55             : single-nucleus pathway and a concerted pathway in which all the atoms rearrange
+      56             : themselves into their solid-like configuration simultaneously. This second type
+      57             : of pathway would be impossible in reality because there is a large entropic
+      58             : barrier that prevents concerted processes like this from happening.  However,
+      59             : in the finite sized systems that are commonly simulated this barrier is reduced
+      60             : substantially. As a result in simulations where average Steinhardt parameters
+      61             : are biased there are often quite dramatic system size effects
+      62             : 
+      63             : If one wants to simulate nucleation using some form on
+      64             : biased dynamics what is really required is an order parameter that measures:
+      65             : 
+      66             : - Whether or not the coordination spheres around atoms are ordered
+      67             : - Whether or not the atoms that are ordered are clustered together in a crystalline nucleus
+      68             : 
+      69             : \ref LOCAL_AVERAGE and \ref NLINKS are variables that can be combined with the Steinhardt parameters allow to calculate variables that satisfy these requirements.
+      70             : 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
+      71             : 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
+      72             : quantity for each of the atoms in the system:
+      73             : 
+      74             : \f[
+      75             :  s_i = \frac{ \sum_j \sigma( r_{ij} ) \sum_{m=-3}^3 q_{3m}^{*}(i)q_{3m}(j) }{ \sum_j \sigma( r_{ij} ) }
+      76             : \f]
+      77             : 
+      78             : 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
+      79             : conjugation.  The function
+      80             : \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
+      81             : 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
+      82             : 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
+      83             : adjacent atoms is correlated.
+      84             : 
+      85             : \par Examples
+      86             : 
+      87             : 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
+      88             : quantity to a file called colvar.
+      89             : 
+      90             : \plumedfile
+      91             : Q3 SPECIES=1-64 D_0=1.3 R_0=0.2 LABEL=q3
+      92             : LOCAL_Q3 SPECIES=q3 SWITCH={RATIONAL D_0=1.3 R_0=0.2} MEAN LABEL=lq3
+      93             : PRINT ARG=lq3.mean FILE=colvar
+      94             : \endplumedfile
+      95             : 
+      96             : The following input calculates the distribution of LOCAL_Q3 parameters at any given time and outputs this information to a file.
+      97             : 
+      98             : \plumedfile
+      99             : Q3 SPECIES=1-64 D_0=1.3 R_0=0.2 LABEL=q3
+     100             : 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
+     101             : PRINT ARG=lq3.* FILE=colvar
+     102             : \endplumedfile
+     103             : 
+     104             : 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
+     105             : are done with those of all the other atoms in the system.  The final quantity is the average and is outputted to a file
+     106             : 
+     107             : \plumedfile
+     108             : Q3 SPECIESA=1-5 SPECIESB=1-64 D_0=1.3 R_0=0.2 LABEL=q3a
+     109             : Q3 SPECIESA=6-64 SPECIESB=1-64 D_0=1.3 R_0=0.2 LABEL=q3b
+     110             : 
+     111             : LOCAL_Q3 SPECIES=q3a,q3b SWITCH={RATIONAL D_0=1.3 R_0=0.2} MEAN LOWMEM LABEL=w3
+     112             : PRINT ARG=w3.* FILE=colvar
+     113             : \endplumedfile
+     114             : 
+     115             : */
+     116             : //+ENDPLUMEDOC
+     117             : 
+     118             : //+PLUMEDOC MCOLVARF LOCAL_Q4
+     119             : /*
+     120             : Calculate the local degree of order around an atoms by taking the average dot product between the \f$q_4\f$ vector on the central atom and the \f$q_4\f$ vector on the atoms in the first coordination sphere.
+     121             : 
+     122             : 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
+     123             : 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
+     124             : 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
+     125             : 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
+     126             : 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
+     127             : 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
+     128             : because the number of atoms is relatively small.
+     129             : 
+     130             : When the average \ref Q4 parameter is used to bias the dynamics a problems
+     131             : can occur. These averaged coordinates cannot distinguish between the correct,
+     132             : single-nucleus pathway and a concerted pathway in which all the atoms rearrange
+     133             : themselves into their solid-like configuration simultaneously. This second type
+     134             : of pathway would be impossible in reality because there is a large entropic
+     135             : barrier that prevents concerted processes like this from happening.  However,
+     136             : in the finite sized systems that are commonly simulated this barrier is reduced
+     137             : substantially. As a result in simulations where average Steinhardt parameters
+     138             : are biased there are often quite dramatic system size effects
+     139             : 
+     140             : If one wants to simulate nucleation using some form on
+     141             : biased dynamics what is really required is an order parameter that measures:
+     142             : 
+     143             : - Whether or not the coordination spheres around atoms are ordered
+     144             : - Whether or not the atoms that are ordered are clustered together in a crystalline nucleus
+     145             : 
+     146             : \ref LOCAL_AVERAGE and \ref NLINKS are variables that can be combined with the Steinhardt parameters allow to calculate variables that satisfy these requirements.
+     147             : 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
+     148             : 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
+     149             : quantity for each of the atoms in the system:
+     150             : 
+     151             : \f[
+     152             :  s_i = \frac{ \sum_j \sigma( r_{ij} ) \sum_{m=-4}^4 q_{4m}^{*}(i)q_{4m}(j) }{ \sum_j \sigma( r_{ij} ) }
+     153             : \f]
+     154             : 
+     155             : 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
+     156             : complex conjugation.  The function
+     157             : \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
+     158             : 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
+     159             : 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
+     160             : adjacent atoms is correlated.
+     161             : 
+     162             : \par Examples
+     163             : 
+     164             : 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
+     165             : quantity to a file called colvar.
+     166             : 
+     167             : \plumedfile
+     168             : Q4 SPECIES=1-64 D_0=1.3 R_0=0.2 LABEL=q4
+     169             : LOCAL_Q4 SPECIES=q4 SWITCH={RATIONAL D_0=1.3 R_0=0.2} MEAN LABEL=lq4
+     170             : PRINT ARG=lq4.mean FILE=colvar
+     171             : \endplumedfile
+     172             : 
+     173             : The following input calculates the distribution of LOCAL_Q4 parameters at any given time and outputs this information to a file.
+     174             : 
+     175             : \plumedfile
+     176             : Q4 SPECIES=1-64 D_0=1.3 R_0=0.2 LABEL=q4
+     177             : 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
+     178             : PRINT ARG=lq4.* FILE=colvar
+     179             : \endplumedfile
+     180             : 
+     181             : 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
+     182             : are done with those of all the other atoms in the system.  The final quantity is the average and is outputted to a file
+     183             : 
+     184             : \plumedfile
+     185             : Q4 SPECIESA=1-5 SPECIESB=1-64 D_0=1.3 R_0=0.2 LABEL=q4a
+     186             : Q4 SPECIESA=6-64 SPECIESB=1-64 D_0=1.3 R_0=0.2 LABEL=q4b
+     187             : 
+     188             : LOCAL_Q4 SPECIES=q4a,q4b SWITCH={RATIONAL D_0=1.3 R_0=0.2} MEAN LOWMEM LABEL=w4
+     189             : PRINT ARG=w4.* FILE=colvar
+     190             : \endplumedfile
+     191             : 
+     192             : */
+     193             : //+ENDPLUMEDOC
+     194             : 
+     195             : //+PLUMEDOC MCOLVARF LOCAL_Q6
+     196             : /*
+     197             : Calculate the local degree of order around an atoms by taking the average dot product between the \f$q_6\f$ vector on the central atom and the \f$q_6\f$ vector on the atoms in the first coordination sphere.
+     198             : 
+     199             : 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
+     200             : 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
+     201             : 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
+     202             : 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
+     203             : 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
+     204             : 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
+     205             : because the number of atoms is relatively small.
+     206             : 
+     207             : When the average \ref Q6 parameter is used to bias the dynamics a problems
+     208             : can occur. These averaged coordinates cannot distinguish between the correct,
+     209             : single-nucleus pathway and a concerted pathway in which all the atoms rearrange
+     210             : themselves into their solid-like configuration simultaneously. This second type
+     211             : of pathway would be impossible in reality because there is a large entropic
+     212             : barrier that prevents concerted processes like this from happening.  However,
+     213             : in the finite sized systems that are commonly simulated this barrier is reduced
+     214             : substantially. As a result in simulations where average Steinhardt parameters
+     215             : are biased there are often quite dramatic system size effects
+     216             : 
+     217             : If one wants to simulate nucleation using some form on
+     218             : biased dynamics what is really required is an order parameter that measures:
+     219             : 
+     220             : - Whether or not the coordination spheres around atoms are ordered
+     221             : - Whether or not the atoms that are ordered are clustered together in a crystalline nucleus
+     222             : 
+     223             : \ref LOCAL_AVERAGE and \ref NLINKS are variables that can be combined with the Steinhardt parameters allow to calculate variables that satisfy these requirements.
+     224             : 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
+     225             : 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
+     226             : quantity for each of the atoms in the system:
+     227             : 
+     228             : \f[
+     229             :  s_i = \frac{ \sum_j \sigma( r_{ij} ) \sum_{m=-6}^6 q_{6m}^{*}(i)q_{6m}(j) }{ \sum_j \sigma( r_{ij} ) }
+     230             : \f]
+     231             : 
+     232             : 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
+     233             : complex conjugation.  The function
+     234             : \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
+     235             : 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
+     236             : 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
+     237             : adjacent atoms is correlated.
+     238             : 
+     239             : \par Examples
+     240             : 
+     241             : 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
+     242             : quantity to a file called colvar.
+     243             : 
+     244             : \plumedfile
+     245             : Q6 SPECIES=1-64 D_0=1.3 R_0=0.2 LABEL=q6
+     246             : LOCAL_Q6 SPECIES=q6 SWITCH={RATIONAL D_0=1.3 R_0=0.2} MEAN LABEL=lq6
+     247             : PRINT ARG=lq6.mean FILE=colvar
+     248             : \endplumedfile
+     249             : 
+     250             : The following input calculates the distribution of LOCAL_Q6 parameters at any given time and outputs this information to a file.
+     251             : 
+     252             : \plumedfile
+     253             : Q6 SPECIES=1-64 D_0=1.3 R_0=0.2 LABEL=q6
+     254             : 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
+     255             : PRINT ARG=lq6.* FILE=colvar
+     256             : \endplumedfile
+     257             : 
+     258             : 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
+     259             : are done with those of all the other atoms in the system.  The final quantity is the average and is outputted to a file
+     260             : 
+     261             : \plumedfile
+     262             : Q6 SPECIESA=1-5 SPECIESB=1-64 D_0=1.3 R_0=0.2 LABEL=q6a
+     263             : Q6 SPECIESA=6-64 SPECIESB=1-64 D_0=1.3 R_0=0.2 LABEL=q6b
+     264             : 
+     265             : LOCAL_Q6 SPECIES=q6a,q6b SWITCH={RATIONAL D_0=1.3 R_0=0.2} MEAN LOWMEM LABEL=w6
+     266             : PRINT ARG=w6.* FILE=colvar
+     267             : \endplumedfile
+     268             : 
+     269             : */
+     270             : //+ENDPLUMEDOC
+     271             : 
+     272             : class LocalSteinhardt : public ActionShortcut {
+     273             : private:
+     274             :   std::string getSymbol( const int& m ) const ;
+     275             :   std::string getArgsForStack( const int& l, const std::string& lab ) const;
+     276             : public:
+     277             :   static void registerKeywords( Keywords& keys );
+     278             :   explicit LocalSteinhardt(const ActionOptions&);
+     279             : };
+     280             : 
+     281             : PLUMED_REGISTER_ACTION(LocalSteinhardt,"LOCAL_Q1")
+     282             : PLUMED_REGISTER_ACTION(LocalSteinhardt,"LOCAL_Q3")
+     283             : PLUMED_REGISTER_ACTION(LocalSteinhardt,"LOCAL_Q4")
+     284             : PLUMED_REGISTER_ACTION(LocalSteinhardt,"LOCAL_Q6")
+     285             : 
+     286          20 : void LocalSteinhardt::registerKeywords( Keywords& keys ) {
+     287          20 :   ActionShortcut::registerKeywords( keys );
+     288          40 :   keys.add("optional","SPECIES","");
+     289          40 :   keys.add("optional","SPECIESA","");
+     290          40 :   keys.add("optional","SPECIESB","");
+     291          40 :   keys.add("optional","SWITCH","This keyword is used if you want to employ an alternative to the continuous swiching function defined above. "
+     292             :            "The following provides information on the \\ref switchingfunction that are available. "
+     293             :            "When this keyword is present you no longer need the NN, MM, D_0 and R_0 keywords.");
+     294          40 :   keys.addFlag("LOWMEM",false,"this flag does nothing and is present only to ensure back-compatibility");
+     295          20 :   multicolvar::MultiColvarShortcuts::shortcutKeywords( keys );
+     296          60 :   keys.needsAction("CONTACT_MATRIX"); keys.needsAction("MATRIX_PRODUCT"); keys.needsAction("GROUP");
+     297          60 :   keys.needsAction("ONES"); keys.needsAction("OUTER_PRODUCT"); keys.needsAction("VSTACK");
+     298          60 :   keys.needsAction("CONCATENATE"); keys.needsAction("CUSTOM"); keys.needsAction("TRANSPOSE");
+     299          20 :   keys.needsAction("MATRIX_VECTOR_PRODUCT");
+     300          20 : }
+     301             : 
+     302          98 : std::string LocalSteinhardt::getSymbol( const int& m ) const {
+     303          98 :   if( m<0 ) {
+     304          40 :     std::string num; Tools::convert( -1*m, num );
+     305          40 :     return "n" + num;
+     306          58 :   } else if( m>0 ) {
+     307          49 :     std::string num; Tools::convert( m, num );
+     308          49 :     return "p" + num;
+     309             :   }
+     310           9 :   return "0";
+     311             : }
+     312             : 
+     313           9 : std::string LocalSteinhardt::getArgsForStack( const int& l, const std::string& sp_lab ) const {
+     314           9 :   std::string numstr; Tools::convert( l, numstr );
+     315          18 :   std::string data_mat = " ARG=" + sp_lab + "_sp.rm-n" + numstr + "," + sp_lab + "_sp.im-n" + numstr;
+     316         107 :   for(int i=-l+1; i<=l; ++i) {
+     317          98 :     numstr = getSymbol( i );
+     318         196 :     data_mat += "," + sp_lab + "_sp.rm-" + numstr + "," + sp_lab + "_sp.im-" + numstr;
+     319             :   }
+     320           9 :   return data_mat;
+     321             : }
+     322             : 
+     323           7 : LocalSteinhardt::LocalSteinhardt(const ActionOptions& ao):
+     324             :   Action(ao),
+     325           7 :   ActionShortcut(ao)
+     326             : {
+     327           7 :   bool lowmem; parseFlag("LOWMEM",lowmem);
+     328           7 :   if( lowmem ) warning("LOWMEM flag is deprecated and is no longer required for this action");
+     329             :   // Get the Q value
+     330          14 :   int l; Tools::convert( getName().substr(7), l);
+     331             :   // Create a vector filled with ones
+     332           7 :   std::string twolplusone; Tools::convert( 2*(2*l+1), twolplusone );
+     333          14 :   readInputLine( getShortcutLabel() + "_uvec: ONES SIZE=" + twolplusone );
+     334             :   // Read in species keyword
+     335          14 :   std::string sp_str; parse("SPECIES",sp_str);
+     336          14 :   std::string spa_str; parse("SPECIESA",spa_str);
+     337           7 :   if( sp_str.length()>0 ) {
+     338             :     // Create a group with these atoms
+     339          12 :     readInputLine( getShortcutLabel() + "_grp: GROUP ATOMS=" + sp_str );
+     340           6 :     std::vector<std::string> sp_lab = Tools::getWords(sp_str, "\t\n ,");
+     341             :     // This creates the stash to hold all the vectors
+     342           6 :     if( sp_lab.size()==1 ) {
+     343             :       // The lengths of all the vectors in a vector
+     344          12 :       readInputLine( getShortcutLabel() + "_nmat: OUTER_PRODUCT ARG=" + sp_lab[0] + "_norm," + getShortcutLabel() + "_uvec");
+     345             :       // The unormalised vectors
+     346          12 :       readInputLine( getShortcutLabel() + "_uvecs: VSTACK" + getArgsForStack( l, sp_lab[0] ) );
+     347             :     } else {
+     348           0 :       std::string len_vec = getShortcutLabel() + "_mags: CONCATENATE ARG=" + sp_lab[0] + "_norm";
+     349           0 :       for(unsigned i=1; i<sp_lab.size(); ++i) len_vec += "," + sp_lab[i] + "_norm";
+     350             :       // This is the vector that contains all the magnitudes
+     351           0 :       readInputLine( len_vec );
+     352           0 :       std::string concat_str = getShortcutLabel() + "_uvecs: CONCATENATE";
+     353           0 :       for(unsigned i=0; i<sp_lab.size(); ++i) {
+     354           0 :         std::string snum; Tools::convert( i+1, snum );
+     355           0 :         concat_str += " MATRIX" + snum + "1=" + getShortcutLabel() + "_uvecs" + snum;
+     356           0 :         readInputLine( getShortcutLabel() + "_uvecs" + snum + ": VSTACK" + getArgsForStack( l, sp_lab[i] ) );
+     357             :       }
+     358             :       // And the normalising matrix by taking the column vector of magnitudes and multiplying by the row vector of ones
+     359           0 :       readInputLine( getShortcutLabel() + "_nmat: OUTER_PRODUCT ARG=" + getShortcutLabel() + "_mags," + getShortcutLabel() + "_uvec");
+     360             :       // The unormalised vectors
+     361           0 :       readInputLine( concat_str );
+     362             :     }
+     363             :     // Now normalise all the vectors by doing Hadammard "product" with normalising matrix
+     364          12 :     readInputLine( getShortcutLabel() + "_vecs: CUSTOM ARG=" + getShortcutLabel() + "_uvecs," + getShortcutLabel() + "_nmat FUNC=x/y PERIODIC=NO");
+     365             :     // And transpose the matrix
+     366          12 :     readInputLine( getShortcutLabel() + "_vecsT: TRANSPOSE ARG=" + getShortcutLabel() + "_vecs" );
+     367          18 :     std::string sw_str; parse("SWITCH",sw_str); readInputLine( getShortcutLabel() + "_cmap: CONTACT_MATRIX GROUP=" + sp_str + " SWITCH={" + sw_str + "}");
+     368             :     // And the matrix of dot products
+     369          12 :     readInputLine( getShortcutLabel() + "_dpmat: MATRIX_PRODUCT ARG=" + getShortcutLabel() + "_vecs," + getShortcutLabel() + "_vecsT" );
+     370           7 :   } else if( spa_str.length()>0 ) {
+     371             :     // Create a group with these atoms
+     372           2 :     readInputLine( getShortcutLabel() + "_grp: GROUP ATOMS=" + spa_str );
+     373           2 :     std::string spb_str; parse("SPECIESB",spb_str);
+     374           1 :     if( spb_str.length()==0 ) plumed_merror("need both SPECIESA and SPECIESB in input");
+     375           1 :     std::vector<std::string> sp_laba = Tools::getWords(spa_str, "\t\n ,");
+     376           1 :     std::vector<std::string> sp_labb = Tools::getWords(spb_str, "\t\n ,");
+     377           1 :     if( sp_laba.size()==1 ) {
+     378             :       // The matrix that is used for normalising
+     379           2 :       readInputLine( getShortcutLabel() + "_nmatA: OUTER_PRODUCT ARG=" +  sp_laba[0] + "_norm," + getShortcutLabel() + "_uvec");
+     380             :       // The unormalised vectors
+     381           2 :       readInputLine( getShortcutLabel() + "_uvecsA: VSTACK" + getArgsForStack( l, sp_laba[0] ) );
+     382             :     } else {
+     383           0 :       std::string len_vec = getShortcutLabel() + "_magsA: CONCATENATE ARG=" + sp_laba[0] + "_norm";
+     384           0 :       for(unsigned i=1; i<sp_laba.size(); ++i) len_vec += "," + sp_laba[i] + "_norm";
+     385             :       //  This is the vector that contains all the magnitudes
+     386           0 :       readInputLine( len_vec );
+     387           0 :       std::string concat_str = getShortcutLabel() + "_uvecsA: CONCATENATE";
+     388           0 :       for(unsigned i=0; i<sp_laba.size(); ++i) {
+     389           0 :         std::string snum; Tools::convert( i+1, snum );
+     390           0 :         concat_str += " MATRIX" + snum + "1=" + getShortcutLabel() + "_uvecsA" + snum;
+     391           0 :         readInputLine( getShortcutLabel() + "_uvecsA" + snum + ": VSTACK" + getArgsForStack( l, sp_laba[i] ) );
+     392             :       }
+     393             :       // And the normalising matrix by taking the column vector of magnitudes and multiplying by the row vector of ones
+     394           0 :       readInputLine( getShortcutLabel() + "_nmatA: OUTER_PRODUCT ARG=" + getShortcutLabel() + "_magsA," + getShortcutLabel() + "_uvec");
+     395             :       // The unormalised vector
+     396           0 :       readInputLine( concat_str );
+     397             :     }
+     398             :     // Now normalise all the vectors by doing Hadammard "product" with normalising matrix
+     399           2 :     readInputLine( getShortcutLabel() + "_vecsA: CUSTOM ARG=" + getShortcutLabel() + "_uvecsA," + getShortcutLabel() + "_nmatA FUNC=x/y PERIODIC=NO");
+     400             :     // Now do second matrix
+     401           1 :     if( sp_labb.size()==1 ) {
+     402           0 :       readInputLine( getShortcutLabel() + "_nmatB: OUTER_PRODUCT ARG=" +  sp_laba[0] + "_norm," + getShortcutLabel() + "_uvec");
+     403           0 :       readInputLine( getShortcutLabel() + "_uvecsBT: VSTACK" + getArgsForStack( l, sp_labb[0] ) );
+     404           0 :       readInputLine( getShortcutLabel() + "_uvecsB: TRANSPOSE ARG=" + getShortcutLabel() + "_uvecsBT");
+     405             :     } else {
+     406           2 :       std::string len_vec = getShortcutLabel() + "_magsB: CONCATENATE ARG=" +  sp_labb[0] + "_norm";
+     407           2 :       for(unsigned i=1; i<sp_labb.size(); ++i) len_vec += "," + sp_labb[i] + "_norm";
+     408             :       //  This is the vector that contains all the magnitudes
+     409           1 :       readInputLine( len_vec );
+     410           1 :       std::string concat_str = getShortcutLabel() + "_uvecsB: CONCATENATE";
+     411           3 :       for(unsigned i=0; i<sp_labb.size(); ++i) {
+     412           2 :         std::string snum; Tools::convert( i+1, snum );
+     413           4 :         concat_str += " MATRIX1" + snum + "=" + getShortcutLabel() + "_uvecsB" + snum;
+     414           4 :         readInputLine( getShortcutLabel() + "_uvecsBT" + snum + ": VSTACK" + getArgsForStack( l, sp_labb[i] ) );
+     415           4 :         readInputLine( getShortcutLabel() + "_uvecsB" + snum + ": TRANSPOSE ARG=" + getShortcutLabel() + "_uvecsBT" + snum );
+     416             :       }
+     417             :       // And the normalising matrix
+     418           2 :       readInputLine( getShortcutLabel() + "_nmatB: OUTER_PRODUCT ARG=" + getShortcutLabel() + "_uvec," + getShortcutLabel() + "_magsB");
+     419             :       // The unormalised vectors
+     420           1 :       readInputLine( concat_str );
+     421             :     }
+     422             :     // Now normalise all the vectors by doing Hadammard "product" with normalising matrix
+     423           2 :     readInputLine( getShortcutLabel() + "_vecsB: CUSTOM ARG=" + getShortcutLabel() + "_uvecsB," + getShortcutLabel() + "_nmatB FUNC=x/y PERIODIC=NO");
+     424           3 :     std::string sw_str; parse("SWITCH",sw_str); readInputLine( getShortcutLabel() + "_cmap: CONTACT_MATRIX GROUPA=" + spa_str + " GROUPB=" + spb_str + " SWITCH={" + sw_str + "}");
+     425           2 :     readInputLine( getShortcutLabel() + "_dpmat: MATRIX_PRODUCT ARG=" + getShortcutLabel() + "_vecsA," + getShortcutLabel() + "_vecsB" );
+     426           1 :   }
+     427             : 
+     428             :   // Now create the product matrix
+     429          14 :   readInputLine( getShortcutLabel() + "_prod: CUSTOM ARG=" + getShortcutLabel() + "_cmap," + getShortcutLabel() + "_dpmat FUNC=x*y PERIODIC=NO");
+     430             :   // Now the sum of coordination numbers times the switching functions
+     431           7 :   ActionWithValue* av = plumed.getActionSet().selectWithLabel<ActionWithValue*>( getShortcutLabel() + "_cmap");
+     432           7 :   plumed_assert( av && av->getNumberOfComponents()>0 && (av->copyOutput(0))->getRank()==2 );
+     433           7 :   std::string size; Tools::convert( (av->copyOutput(0))->getShape()[1], size );
+     434          14 :   readInputLine( getShortcutLabel() + "_ones: ONES SIZE=" + size );
+     435          14 :   readInputLine( getShortcutLabel() + ": MATRIX_VECTOR_PRODUCT ARG=" + getShortcutLabel() +"_prod," + getShortcutLabel() +"_ones");
+     436             :   // And just the sum of the coordination numbers
+     437          14 :   readInputLine( getShortcutLabel() + "_denom: MATRIX_VECTOR_PRODUCT ARG=" + getShortcutLabel() + "_cmap," + getShortcutLabel() +"_ones");
+     438             :   // And matheval to get the final quantity
+     439          14 :   readInputLine( getShortcutLabel() + "_av: CUSTOM ARG=" + getShortcutLabel() + "," + getShortcutLabel() + "_denom FUNC=x/y PERIODIC=NO");
+     440             :   // And this expands everything
+     441          14 :   multicolvar::MultiColvarShortcuts::expandFunctions( getShortcutLabel(), getShortcutLabel() + "_av", "", this );
+     442           7 : }
+     443             : 
+     444             : }
+     445             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/symfunc/RadialTetra.cpp.func-sort-c.html b/coverage/symfunc/RadialTetra.cpp.func-sort-c.html new file mode 100644 index 000000000000..ba80ca750202 --- /dev/null +++ b/coverage/symfunc/RadialTetra.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - symfunc/RadialTetra.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - symfunc - RadialTetra.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:303488.2 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7symfunc11RadialTetraC2ERKNS_13ActionOptionsE0
_ZN4PLMD7symfunc11RadialTetraC1ERKNS_13ActionOptionsE1
_ZN4PLMD7symfunc11RadialTetra16registerKeywordsERNS_8KeywordsE3
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/symfunc/RadialTetra.cpp.func.html b/coverage/symfunc/RadialTetra.cpp.func.html new file mode 100644 index 000000000000..729226e985b3 --- /dev/null +++ b/coverage/symfunc/RadialTetra.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - symfunc/RadialTetra.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - symfunc - RadialTetra.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:303488.2 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7symfunc11RadialTetra16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD7symfunc11RadialTetraC1ERKNS_13ActionOptionsE1
_ZN4PLMD7symfunc11RadialTetraC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/symfunc/RadialTetra.cpp.gcov.html b/coverage/symfunc/RadialTetra.cpp.gcov.html new file mode 100644 index 000000000000..4e9a1d87cae9 --- /dev/null +++ b/coverage/symfunc/RadialTetra.cpp.gcov.html @@ -0,0 +1,178 @@ + + + + + + + + LCOV - plumed test coverage - symfunc/RadialTetra.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - symfunc - RadialTetra.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:303488.2 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2018 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received 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/ActionShortcut.h"
+      24             : #include "core/ActionWithValue.h"
+      25             : #include "CoordinationNumbers.h"
+      26             : #include "multicolvar/MultiColvarShortcuts.h"
+      27             : #include "core/PlumedMain.h"
+      28             : #include "core/ActionSet.h"
+      29             : 
+      30             : //+PLUMEDOC MCOLVAR TETRA_RADIAL
+      31             : /*
+      32             : Calculate the radial tetra CV
+      33             : 
+      34             : \par Examples
+      35             : 
+      36             : */
+      37             : //+ENDPLUMEDOC
+      38             : 
+      39             : namespace PLMD {
+      40             : namespace symfunc {
+      41             : 
+      42             : class RadialTetra : public ActionShortcut {
+      43             : public:
+      44             :   static void registerKeywords( Keywords& keys );
+      45             :   explicit RadialTetra(const ActionOptions&ao);
+      46             : };
+      47             : 
+      48             : PLUMED_REGISTER_ACTION(RadialTetra,"TETRA_RADIAL")
+      49             : 
+      50           3 : void RadialTetra::registerKeywords( Keywords& keys ) {
+      51           3 :   CoordinationNumbers::shortcutKeywords( keys );
+      52           6 :   keys.addFlag("NOPBC",false,"ignore the periodic boundary conditions when calculating distances");
+      53           6 :   keys.add("compulsory","CUTOFF","-1","ignore distances that have a value larger than this cutoff");
+      54          15 :   keys.remove("NN"); keys.remove("MM"); keys.remove("D_0"); keys.remove("R_0"); keys.remove("SWITCH");
+      55           6 :   keys.needsAction("DISTANCE_MATRIX"); keys.needsAction("NEIGHBORS");
+      56           6 :   keys.needsAction("CUSTOM"); keys.needsAction("ONES");
+      57           3 :   keys.needsAction("MATRIX_VECTOR_PRODUCT");
+      58           3 : }
+      59             : 
+      60           1 : RadialTetra::RadialTetra( const ActionOptions& ao):
+      61             :   Action(ao),
+      62           1 :   ActionShortcut(ao)
+      63             : {
+      64             :   // Read species input and create the matrix
+      65           1 :   bool nopbc; parseFlag("NOPBC",nopbc);
+      66           1 :   std::string pbcstr=""; if( nopbc ) pbcstr = " NOPBC";
+      67           3 :   std::string sp_str, rcut; parse("SPECIES",sp_str); parse("CUTOFF",rcut);
+      68           1 :   if( sp_str.length()>0 ) {
+      69           2 :     readInputLine( getShortcutLabel() + "_mat: DISTANCE_MATRIX GROUP=" + sp_str + " CUTOFF=" + rcut + pbcstr );
+      70             :   } else {
+      71           0 :     std::string specA, specB; parse("SPECIESA",specA); parse("SPECIESB",specB);
+      72           0 :     if( specA.length()==0 ) error("missing input atoms");
+      73           0 :     if( specB.length()==0 ) error("missing SPECIESB keyword");
+      74           0 :     readInputLine( getShortcutLabel() + "_mat: DISTANCE_MATRIX GROUPA=" + specA + " GROUPB=" + specB + " CUTOFF=" + rcut + pbcstr);
+      75             :   }
+      76             :   // Get the neighbors matrix
+      77           2 :   readInputLine( getShortcutLabel() + "_neigh: NEIGHBORS ARG=" + getShortcutLabel() + "_mat NLOWEST=4");
+      78             :   // Now get distance matrix that just contains four nearest distances
+      79           2 :   readInputLine( getShortcutLabel() + "_near4: CUSTOM ARG=" + getShortcutLabel() + "_mat," + getShortcutLabel() + "_neigh FUNC=x*y PERIODIC=NO");
+      80             :   //Now compute sum of four nearest distances
+      81           1 :   ActionWithValue* av = plumed.getActionSet().selectWithLabel<ActionWithValue*>( getShortcutLabel() + "_mat");
+      82           1 :   plumed_assert( av && av->getNumberOfComponents()>0 && (av->copyOutput(0))->getRank()==2 );
+      83           1 :   std::string size; Tools::convert( (av->copyOutput(0))->getShape()[1], size );
+      84           2 :   readInputLine( getShortcutLabel() + "_ones: ONES SIZE=" + size );
+      85           2 :   readInputLine( getShortcutLabel() + "_sum4: MATRIX_VECTOR_PRODUCT ARG=" + getShortcutLabel() + "_near4," + getShortcutLabel() + "_ones");
+      86             :   // Now compute squares of four nearest distance
+      87           2 :   readInputLine( getShortcutLabel() + "_near4_2: CUSTOM ARG=" + getShortcutLabel() + "_near4 FUNC=x*x PERIODIC=NO");
+      88             :   // Now compute sum of the squares of the four nearest distances
+      89           2 :   readInputLine( getShortcutLabel() + "_sum4_2: MATRIX_VECTOR_PRODUCT ARG=" + getShortcutLabel() + "_near4_2," + getShortcutLabel() + "_ones");
+      90             :   // Evaluate the average distance to the four nearest neighbors
+      91           2 :   readInputLine( getShortcutLabel() + "_meanr: CUSTOM ARG=" + getShortcutLabel() + "_sum4 FUNC=0.25*x PERIODIC=NO");
+      92             :   // Now evaluate the actual per atom CV
+      93           2 :   readInputLine( getShortcutLabel() + ": CUSTOM ARG=" + getShortcutLabel() + "_sum4," + getShortcutLabel() + "_sum4_2," + getShortcutLabel() + "_meanr " +
+      94             :                  "FUNC=(1-(y-x*z)/(12*z*z)) PERIODIC=NO");
+      95             :   // And get the things to do with the quantities we have computed
+      96           1 :   std::map<std::string,std::string> keymap; multicolvar::MultiColvarShortcuts::readShortcutKeywords( keymap, this );
+      97           2 :   multicolvar::MultiColvarShortcuts::expandFunctions( getShortcutLabel(), getShortcutLabel(), "", keymap, this );
+      98           1 : }
+      99             : 
+     100             : }
+     101             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/symfunc/SMAC.cpp.func-sort-c.html b/coverage/symfunc/SMAC.cpp.func-sort-c.html new file mode 100644 index 000000000000..b6db307a6629 --- /dev/null +++ b/coverage/symfunc/SMAC.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - symfunc/SMAC.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - symfunc - SMAC.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:565798.2 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7symfunc4SMACC2ERKNS_13ActionOptionsE0
_ZN4PLMD7symfunc4SMACC1ERKNS_13ActionOptionsE5
_ZN4PLMD7symfunc4SMAC16registerKeywordsERNS_8KeywordsE13
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/symfunc/SMAC.cpp.func.html b/coverage/symfunc/SMAC.cpp.func.html new file mode 100644 index 000000000000..d8a04cbaa596 --- /dev/null +++ b/coverage/symfunc/SMAC.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - symfunc/SMAC.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - symfunc - SMAC.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:565798.2 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7symfunc4SMAC16registerKeywordsERNS_8KeywordsE13
_ZN4PLMD7symfunc4SMACC1ERKNS_13ActionOptionsE5
_ZN4PLMD7symfunc4SMACC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/symfunc/SMAC.cpp.gcov.html b/coverage/symfunc/SMAC.cpp.gcov.html new file mode 100644 index 000000000000..b2eaeeaa1b12 --- /dev/null +++ b/coverage/symfunc/SMAC.cpp.gcov.html @@ -0,0 +1,200 @@ + + + + + + + + LCOV - plumed test coverage - symfunc/SMAC.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - symfunc - SMAC.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:565798.2 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionShortcut.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "core/ActionWithValue.h"
+      25             : #include "core/PlumedMain.h"
+      26             : #include "core/ActionSet.h"
+      27             : #include "multicolvar/MultiColvarShortcuts.h"
+      28             : 
+      29             : //+PLUMEDOC MCOLVAR SMAC
+      30             : /*
+      31             : Calculate the SMAC order parameter for a set of molecules
+      32             : 
+      33             : \par Examples
+      34             : 
+      35             : 
+      36             : */
+      37             : //+ENDPLUMEDOC
+      38             : 
+      39             : namespace PLMD {
+      40             : namespace symfunc {
+      41             : 
+      42             : class SMAC : public ActionShortcut {
+      43             : public:
+      44             :   static void registerKeywords(Keywords& keys);
+      45             :   explicit SMAC(const ActionOptions&);
+      46             : };
+      47             : 
+      48             : PLUMED_REGISTER_ACTION(SMAC,"SMAC")
+      49             : 
+      50          13 : void SMAC::registerKeywords(Keywords& keys) {
+      51          13 :   ActionShortcut::registerKeywords( keys );
+      52          26 :   keys.add("optional","SPECIES","");
+      53          26 :   keys.add("optional","SPECIESA","");
+      54          26 :   keys.add("optional","SPECIESB","");
+      55          26 :   keys.add("optional","SWITCH","This keyword is used if you want to employ an alternative to the continuous swiching function defined above. "
+      56             :            "The following provides information on the \\ref switchingfunction that are available. "
+      57             :            "When this keyword is present you no longer need the NN, MM, D_0 and R_0 keywords.");
+      58          26 :   keys.add("numbered","KERNEL","The kernels used in the function of the angle");
+      59          26 :   keys.add("optional","SWITCH_COORD","This keyword is used to define the coordination switching function.");
+      60          26 :   keys.reset_style("KERNEL","optional");
+      61          13 :   multicolvar::MultiColvarShortcuts::shortcutKeywords( keys );
+      62          39 :   keys.needsAction("VSTACK"); keys.needsAction("TRANSPOSE"); keys.needsAction("CONTACT_MATRIX");
+      63          39 :   keys.needsAction("TORSIONS_MATRIX"); keys.needsAction("COMBINE"); keys.needsAction("CUSTOM");
+      64          39 :   keys.needsAction("ONES"); keys.needsAction("MATRIX_VECTOR_PRODUCT"); keys.needsAction("MORE_THAN");
+      65          13 : }
+      66             : 
+      67           5 : SMAC::SMAC(const ActionOptions& ao):
+      68             :   Action(ao),
+      69           5 :   ActionShortcut(ao)
+      70             : {
+      71             :   // Create the matrices
+      72          10 :   std::string sw_input; parse("SWITCH",sw_input);
+      73          15 :   std::string sp_lab, sp_laba; parse("SPECIES",sp_lab); parse("SPECIESA",sp_laba);
+      74           5 :   if( sp_lab.length()>0 ) {
+      75           8 :     readInputLine( getShortcutLabel() + "_vecs: VSTACK ARG=" + sp_lab + ".x," + sp_lab + ".y," + sp_lab + ".z" );
+      76           8 :     readInputLine( getShortcutLabel() + "_vecsT: TRANSPOSE ARG=" + getShortcutLabel() + "_vecs" );
+      77           8 :     readInputLine( getShortcutLabel() + "_cmap: CONTACT_MATRIX GROUP=" + sp_lab + " SWITCH={" + sw_input + "}");
+      78           8 :     readInputLine( getShortcutLabel() + "_tpmat: TORSIONS_MATRIX ARG=" + getShortcutLabel() + "_vecs," + getShortcutLabel() + "_vecsT POSITIONS1=" + sp_lab + " POSITIONS2=" + sp_lab );
+      79           1 :   } else if( sp_laba.length()>0 ) {
+      80           1 :     std::string sp_labb; parse("SPECIESB",sp_labb);
+      81           2 :     readInputLine( getShortcutLabel() + "_vecsa: VSTACK ARG=" + sp_laba + ".x," + sp_laba + ".y," + sp_laba + ".z" );
+      82           2 :     readInputLine( getShortcutLabel() + "_vecsb: VSTACK ARG=" + sp_labb + ".x," + sp_labb + ".y," + sp_labb + ".z" );
+      83           2 :     readInputLine( getShortcutLabel() + "_vecsbT: TRANSPOSE ARG=" + getShortcutLabel() + "_vecsb" );
+      84           2 :     readInputLine( getShortcutLabel() + "_cmap: CONTACT_MATRIX GROUPA=" + sp_laba + " GROUPB=" + sp_labb + " SWITCH={" + sw_input + "}");
+      85           2 :     readInputLine( getShortcutLabel() + "_tpmat: TORSIONS_MATRIX ARG=" + getShortcutLabel() + "_vecsa," + getShortcutLabel() + "_vecsbT POSITIONS1=" + sp_laba + " POSITIONS2=" + sp_labb );
+      86             :   }
+      87             :   // Now need the Gaussians
+      88           5 :   std::string kmap_input= getShortcutLabel() + "_ksum: COMBINE PERIODIC=NO";
+      89           5 :   for(unsigned i=1;; ++i) {
+      90          15 :     std::string kstr_inpt, istr; Tools::convert( i, istr );
+      91          30 :     if( !parseNumbered("KERNEL",i,kstr_inpt ) ) { break; }
+      92          10 :     std::vector<std::string> words = Tools::getWords(kstr_inpt);
+      93          20 :     std::string center, var; Tools::parse(words,"CENTER",center); Tools::parse(words,"SIGMA",var);
+      94          10 :     double nsig; Tools::convert( var, nsig ); std::string coeff; Tools::convert( 1/(nsig*nsig), coeff );
+      95          20 :     readInputLine( getShortcutLabel() + "_kf" + istr + "_r2: COMBINE PERIODIC=NO ARG=" + getShortcutLabel() + "_tpmat COEFFICIENTS=" + coeff + " PARAMETERS=" + center + " POWERS=2");
+      96          18 :     if( words[0]=="GAUSSIAN" ) readInputLine( getShortcutLabel() + "_kf" + istr + ": CUSTOM PERIODIC=NO FUNC=exp(-x/2) ARG=" +  getShortcutLabel() + "_kf" + istr + "_r2" );
+      97           4 :     else if( words[0]=="TRIANGULAR" ) readInputLine( getShortcutLabel() + "_kf" + istr + ": CUSTOM PERIODIC=NO FUNC=step(1-sqrt(x))*(1-sqrt(x)) ARG=" + getShortcutLabel() + "_kf" + istr + "_r2" );
+      98           0 :     else readInputLine( getShortcutLabel() + "_kf" + istr + ": CUSTOM PERIODIC=NO FUNC=" + words[0] + " ARG=" + getShortcutLabel() + "_kf" + istr + "_r2" );
+      99          15 :     if( i==1 ) kmap_input += " ARG=" + getShortcutLabel() + "_kf" + istr;
+     100          10 :     else kmap_input += "," + getShortcutLabel() + "_kf" + istr;
+     101          20 :   }
+     102           5 :   readInputLine( kmap_input );
+     103             :   // Now create the product matrix
+     104          10 :   readInputLine( getShortcutLabel() + "_prod: CUSTOM ARG=" + getShortcutLabel() + "_cmap," + getShortcutLabel() + "_ksum FUNC=x*y PERIODIC=NO");
+     105             :   // Now the sum of coordination numbers times the switching functions
+     106           5 :   ActionWithValue* av = plumed.getActionSet().selectWithLabel<ActionWithValue*>( getShortcutLabel() + "_cmap");
+     107           5 :   plumed_assert( av && av->getNumberOfComponents()>0 && (av->copyOutput(0))->getRank()==2 );
+     108           5 :   std::string size; Tools::convert( (av->copyOutput(0))->getShape()[1], size );
+     109          10 :   readInputLine( getShortcutLabel() + "_ones: ONES SIZE=" + size );
+     110          10 :   readInputLine( getShortcutLabel() + ": MATRIX_VECTOR_PRODUCT ARG=" + getShortcutLabel() + "_prod," + getShortcutLabel() + "_ones");
+     111             :   // And just the sum of the coordination numbers
+     112          10 :   readInputLine( getShortcutLabel() + "_denom: MATRIX_VECTOR_PRODUCT ARG=" + getShortcutLabel() + "_cmap," + getShortcutLabel() + "_ones");
+     113             :   // And the transformed switching functions
+     114           5 :   std::string swcoord_str; parse("SWITCH_COORD",swcoord_str);
+     115          10 :   readInputLine( getShortcutLabel() + "_mtdenom: MORE_THAN ARG=" + getShortcutLabel() + "_denom SWITCH={" + swcoord_str +"}");
+     116             : // And matheval to get the final quantity
+     117          10 :   readInputLine( getShortcutLabel() + "_smac: CUSTOM ARG=" + getShortcutLabel() + "," + getShortcutLabel() + "_mtdenom," + getShortcutLabel() + "_denom FUNC=(x*y)/z PERIODIC=NO");
+     118             :   // And this expands everything
+     119          10 :   multicolvar::MultiColvarShortcuts::expandFunctions( getShortcutLabel(), getShortcutLabel() + "_smac", "", this );
+     120           5 : }
+     121             : 
+     122             : }
+     123             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/symfunc/SphericalHarmonic.cpp.func-sort-c.html b/coverage/symfunc/SphericalHarmonic.cpp.func-sort-c.html new file mode 100644 index 000000000000..6c9b83c50653 --- /dev/null +++ b/coverage/symfunc/SphericalHarmonic.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - symfunc/SphericalHarmonic.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - symfunc - SphericalHarmonic.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:9310093.0 %
Date:2024-04-19 12:12:35Functions:88100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7symfunc17SphericalHarmonic24setPeriodicityForOutputsEPNS_15ActionWithValueE41
_ZN4PLMD7symfunc17SphericalHarmonic4readEPNS_19ActionWithArgumentsE41
_ZNK4PLMD7symfunc17SphericalHarmonic21getComponentsPerLabelB5cxx11Ev82
_ZN4PLMD7symfunc17SphericalHarmonic16registerKeywordsERNS_8KeywordsE127
_ZNK4PLMD7symfunc17SphericalHarmonic9factorialERKj1853
_ZNK4PLMD7symfunc17SphericalHarmonic4calcEPKNS_19ActionWithArgumentsERKSt6vectorIdSaIdEERS7_RNS_6MatrixIdEE1742755
_ZNK4PLMD7symfunc17SphericalHarmonic10deriv_polyERKjRKdRd1794050
_ZNK4PLMD7symfunc17SphericalHarmonic20addVectorDerivativesERKjRKNS_13VectorGenericILj3EEERNS_6MatrixIdEE6353585
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/symfunc/SphericalHarmonic.cpp.func.html b/coverage/symfunc/SphericalHarmonic.cpp.func.html new file mode 100644 index 000000000000..c8161aa2c500 --- /dev/null +++ b/coverage/symfunc/SphericalHarmonic.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - symfunc/SphericalHarmonic.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - symfunc - SphericalHarmonic.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:9310093.0 %
Date:2024-04-19 12:12:35Functions:88100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7symfunc17SphericalHarmonic16registerKeywordsERNS_8KeywordsE127
_ZN4PLMD7symfunc17SphericalHarmonic24setPeriodicityForOutputsEPNS_15ActionWithValueE41
_ZN4PLMD7symfunc17SphericalHarmonic4readEPNS_19ActionWithArgumentsE41
_ZNK4PLMD7symfunc17SphericalHarmonic10deriv_polyERKjRKdRd1794050
_ZNK4PLMD7symfunc17SphericalHarmonic20addVectorDerivativesERKjRKNS_13VectorGenericILj3EEERNS_6MatrixIdEE6353585
_ZNK4PLMD7symfunc17SphericalHarmonic21getComponentsPerLabelB5cxx11Ev82
_ZNK4PLMD7symfunc17SphericalHarmonic4calcEPKNS_19ActionWithArgumentsERKSt6vectorIdSaIdEERS7_RNS_6MatrixIdEE1742755
_ZNK4PLMD7symfunc17SphericalHarmonic9factorialERKj1853
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/symfunc/SphericalHarmonic.cpp.gcov.html b/coverage/symfunc/SphericalHarmonic.cpp.gcov.html new file mode 100644 index 000000000000..fdce592f65db --- /dev/null +++ b/coverage/symfunc/SphericalHarmonic.cpp.gcov.html @@ -0,0 +1,314 @@ + + + + + + + + LCOV - plumed test coverage - symfunc/SphericalHarmonic.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - symfunc - SphericalHarmonic.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:9310093.0 %
Date:2024-04-19 12:12:35Functions:88100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2017 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received 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/FunctionTemplateBase.h"
+      23             : #include "function/FunctionShortcut.h"
+      24             : #include "adjmat/FunctionOfMatrix.h"
+      25             : #include "core/ActionRegister.h"
+      26             : 
+      27             : #include <complex>
+      28             : 
+      29             : namespace PLMD {
+      30             : namespace symfunc {
+      31             : 
+      32             : //+PLUMEDOC MCOLVAR SPHERICAL_HARMONIC
+      33             : /*
+      34             : Calculate the values of all the spherical harmonic funtions for a particular value of l.
+      35             : 
+      36             : \par Examples
+      37             : 
+      38             : 
+      39             : */
+      40             : //+ENDPLUMEDOC
+      41             : 
+      42             : //+PLUMEDOC MCOLVAR SPHERICAL_HARMONIC_MATRIX
+      43             : /*
+      44             : Calculate the values of all the spherical harmonic funtions for a particular value of l for all the elements of a set of three input matrices
+      45             : 
+      46             : \par Examples
+      47             : 
+      48             : 
+      49             : */
+      50             : //+ENDPLUMEDOC
+      51             : 
+      52         209 : class SphericalHarmonic : public function::FunctionTemplateBase {
+      53             : private:
+      54             :   int tmom;
+      55             :   std::vector<double> coeff_poly;
+      56             :   std::vector<double> normaliz;
+      57             :   unsigned factorial( const unsigned& n ) const ;
+      58             :   double deriv_poly( const unsigned& m, const double& val, double& df ) const ;
+      59             :   void addVectorDerivatives( const unsigned& ival, const Vector& der, Matrix<double>& derivatives ) const ;
+      60             : public:
+      61             :   void registerKeywords( Keywords& keys ) override;
+      62             :   void read( ActionWithArguments* action ) override;
+      63             :   std::vector<std::string> getComponentsPerLabel() const override;
+      64             :   void setPeriodicityForOutputs( ActionWithValue* action ) override;
+      65             :   void calc( const ActionWithArguments* action, const std::vector<double>& args, std::vector<double>& vals, Matrix<double>& derivatives ) const override;
+      66             : };
+      67             : 
+      68             : typedef function::FunctionShortcut<SphericalHarmonic> SpHarmShortcut;
+      69             : PLUMED_REGISTER_ACTION(SpHarmShortcut,"SPHERICAL_HARMONIC")
+      70             : typedef adjmat::FunctionOfMatrix<SphericalHarmonic> MatrixSpHarm;
+      71             : PLUMED_REGISTER_ACTION(MatrixSpHarm,"SPHERICAL_HARMONIC_MATRIX")
+      72             : 
+      73         127 : void SphericalHarmonic::registerKeywords( Keywords& keys ) {
+      74         254 :   keys.add("compulsory","L","the value of the angular momentum");
+      75         254 :   keys.addOutputComponent("rm","default","the real parts of the spherical harmonic values with the m value given");
+      76         254 :   keys.addOutputComponent("im","default","the real parts of the spherical harmonic values with the m value given");
+      77         127 : }
+      78             : 
+      79        1853 : unsigned SphericalHarmonic::factorial( const unsigned& n ) const {
+      80        1853 :   return (n == 1 || n == 0) ? 1 : factorial(n - 1) * n;
+      81             : }
+      82             : 
+      83          41 : void SphericalHarmonic::read( ActionWithArguments* action ) {
+      84          41 :   parse(action,"L",tmom);
+      85          41 :   action->log.printf("  calculating %dth order spherical harmonic with %s, %s and %s as input \n", tmom, action->getPntrToArgument(0)->getName().c_str(), action->getPntrToArgument(1)->getName().c_str(), action->getPntrToArgument(2)->getName().c_str() );
+      86          41 :   if( action->getNumberOfArguments()==4 ) action->log.printf("  multiplying cylindrical harmonic by weight from %s \n", action->getPntrToArgument(3)->getName().c_str() );
+      87             : 
+      88          41 :   normaliz.resize( tmom+1 );
+      89         229 :   for(unsigned i=0; i<=tmom; ++i) {
+      90         188 :     normaliz[i] = sqrt( (2*tmom+1)*factorial(tmom-i)/(4*pi*factorial(tmom+i)) );
+      91         188 :     if( i%2==1 ) normaliz[i]*=-1;
+      92             :   }
+      93             : 
+      94          41 :   coeff_poly.resize( tmom+1 );
+      95          41 :   if( tmom==1 ) {
+      96             :     // Legendre polynomial coefficients of order one
+      97          18 :     coeff_poly[0]=0; coeff_poly[1]=1.0;
+      98             :   } else if( tmom==2 ) {
+      99             :     // Legendre polynomial coefficients of order two
+     100           0 :     coeff_poly[0]=-0.5; coeff_poly[1]=0.0;
+     101           0 :     coeff_poly[2]=1.5;
+     102             :   } else if( tmom==3 ) {
+     103             :     // Legendre polynomial coefficients of order three
+     104           1 :     coeff_poly[0]=0.0; coeff_poly[1]=-1.5;
+     105           1 :     coeff_poly[2]=0.0; coeff_poly[3]=2.5;
+     106             :   } else if( tmom==4 ) {
+     107             :     // Legendre polynomial coefficients of order four
+     108           3 :     coeff_poly[0]=0.375; coeff_poly[1]=0.0;
+     109           3 :     coeff_poly[2]=-3.75; coeff_poly[3]=0.0;
+     110           3 :     coeff_poly[4]=4.375;
+     111             :   } else if( tmom==5 ) {
+     112             :     // Legendre polynomial coefficients of order five
+     113           0 :     coeff_poly[0]=0.0; coeff_poly[1]=1.875;
+     114           0 :     coeff_poly[2]=0.0; coeff_poly[3]=-8.75;
+     115           0 :     coeff_poly[4]=0.0; coeff_poly[5]=7.875;
+     116             :   } else if( tmom==6 ) {
+     117             :     // Legendre polynomial coefficients of order six
+     118          19 :     coeff_poly[0]=-0.3125; coeff_poly[1]=0.0;
+     119          19 :     coeff_poly[2]=6.5625; coeff_poly[3]=0.0;
+     120          19 :     coeff_poly[4]=-19.6875; coeff_poly[5]=0.0;
+     121          19 :     coeff_poly[6]=14.4375;
+     122             :   } else {
+     123           0 :     action->error("Insert Legendre polynomial coefficients into SphericalHarmonics code");
+     124             :   }
+     125          41 : }
+     126             : 
+     127          82 : std::vector<std::string> SphericalHarmonic::getComponentsPerLabel() const {
+     128             :   std::vector<std::string> comp; std::string num;
+     129         752 :   for(int i=-tmom; i<=tmom; ++i) {
+     130         670 :     Tools::convert(fabs(i),num);
+     131         964 :     if( i<0 ) comp.push_back( "-n" + num );
+     132         670 :     else if( i>0 ) comp.push_back( "-p" + num );
+     133         164 :     else comp.push_back( "-0");
+     134             :   }
+     135          82 :   return comp;
+     136           0 : }
+     137             : 
+     138          41 : void SphericalHarmonic::setPeriodicityForOutputs( ActionWithValue* action ) {
+     139          41 :   std::vector<std::string> comp( getComponentsPerLabel() );
+     140         711 :   for(unsigned i=0; i<comp.size(); ++i) { action->componentIsNotPeriodic("rm" + comp[i]); action->componentIsNotPeriodic("im" + comp[i]); }
+     141          41 : }
+     142             : 
+     143     1742755 : void SphericalHarmonic::calc( const ActionWithArguments* action, const std::vector<double>& args, std::vector<double>& vals, Matrix<double>& derivatives ) const {
+     144     1742755 :   double weight=1; if( args.size()==4 ) weight = args[3];
+     145     1742755 :   if( weight<epsilon ) return;
+     146             : 
+     147      274205 :   double dlen2 = args[0]*args[0]+args[1]*args[1]+args[2]*args[2];
+     148      274205 :   double dlen = sqrt( dlen2 ); double dlen3 = dlen2*dlen;
+     149      274205 :   double dpoly_ass, poly_ass=deriv_poly( 0, args[2]/dlen, dpoly_ass );
+     150             :   // Derivatives of z/r wrt x, y, z
+     151      274205 :   Vector dz;
+     152      274205 :   dz[0] = -( args[2] / dlen3 )*args[0];
+     153      274205 :   dz[1] = -( args[2] / dlen3 )*args[1];
+     154      274205 :   dz[2] = -( args[2] / dlen3 )*args[2] + (1.0 / dlen);
+     155             :   // Accumulate for m=0
+     156      274205 :   vals[tmom] = weight*poly_ass;
+     157      274205 :   addVectorDerivatives( tmom, weight*dpoly_ass*dz, derivatives );
+     158      274205 :   if( args.size()==4 ) derivatives(tmom, 3) = poly_ass;
+     159             : 
+     160             :   // The complex number of which we have to take powers
+     161      274205 :   std::complex<double> com1( args[0]/dlen,args[1]/dlen ), dp_x, dp_y, dp_z;
+     162             :   std::complex<double> powered = std::complex<double>(1.0,0.0); std::complex<double> ii( 0.0, 1.0 );
+     163      274205 :   Vector myrealvec, myimagvec, real_dz, imag_dz;
+     164             :   // Do stuff for all other m values
+     165     1794050 :   for(unsigned m=1; m<=tmom; ++m) {
+     166             :     // Calculate Legendre Polynomial
+     167     1519845 :     poly_ass=deriv_poly( m, args[2]/dlen, dpoly_ass );
+     168             :     // Real and imaginary parts of z
+     169             :     double real_z = real(com1*powered), imag_z = imag(com1*powered);
+     170             : 
+     171             :     // Calculate steinhardt parameter
+     172     1519845 :     double tq6=poly_ass*real_z;   // Real part of steinhardt parameter
+     173     1519845 :     double itq6=poly_ass*imag_z;  // Imaginary part of steinhardt parameter
+     174             : 
+     175             :     // Derivatives wrt ( x/r + iy )^m
+     176     1519845 :     double md=static_cast<double>(m);
+     177     1519845 :     dp_x = md*powered*( (1.0/dlen)-(args[0]*args[0])/dlen3-ii*(args[0]*args[1])/dlen3 );
+     178     1519845 :     dp_y = md*powered*( ii*(1.0/dlen)-(args[0]*args[1])/dlen3-ii*(args[1]*args[1])/dlen3 );
+     179     1519845 :     dp_z = md*powered*( -(args[0]*args[2])/dlen3-ii*(args[1]*args[2])/dlen3 );
+     180             : 
+     181             :     // Derivatives of real and imaginary parts of above
+     182     1519845 :     real_dz[0] = real( dp_x ); real_dz[1] = real( dp_y ); real_dz[2] = real( dp_z );
+     183     1519845 :     imag_dz[0] = imag( dp_x ); imag_dz[1] = imag( dp_y ); imag_dz[2] = imag( dp_z );
+     184             : 
+     185             :     // Complete derivative of steinhardt parameter
+     186     1519845 :     myrealvec = weight*dpoly_ass*real_z*dz + weight*poly_ass*real_dz;
+     187     1519845 :     myimagvec = weight*dpoly_ass*imag_z*dz + weight*poly_ass*imag_dz;
+     188             : 
+     189             :     // Real part
+     190     1519845 :     vals[tmom+m] = weight*tq6;
+     191     1519845 :     addVectorDerivatives( tmom+m, myrealvec, derivatives );
+     192             :     // Imaginary part
+     193     1519845 :     vals[3*tmom+1+m] = weight*itq6;
+     194     1519845 :     addVectorDerivatives( 3*tmom+1+m, myimagvec, derivatives );
+     195             :     // Store -m part of vector
+     196     1519845 :     double pref=pow(-1.0,m);
+     197             :     // -m part of vector is just +m part multiplied by (-1.0)**m and multiplied by complex
+     198             :     // conjugate of Legendre polynomial
+     199             :     // Real part
+     200     1519845 :     vals[tmom-m] = pref*weight*tq6;
+     201     1519845 :     addVectorDerivatives( tmom-m, pref*myrealvec, derivatives );
+     202             :     // Imaginary part
+     203     1519845 :     vals[3*tmom+1-m] = -pref*weight*itq6;
+     204     1519845 :     addVectorDerivatives( 3*tmom+1-m, -pref*myimagvec, derivatives );
+     205     1519845 :     if( args.size()==4 ) {
+     206     1519845 :       derivatives(tmom+m,3)=tq6; derivatives(3*tmom+1+m, 3)=itq6;
+     207     1519845 :       derivatives(tmom-m,3)=pref*tq6; derivatives(3*tmom+1-m, 3)=-pref*itq6;
+     208             :     }
+     209             :     // Calculate next power of complex number
+     210             :     powered *= com1;
+     211             :   }
+     212             : }
+     213             : 
+     214     1794050 : double SphericalHarmonic::deriv_poly( const unsigned& m, const double& val, double& df ) const {
+     215             :   double fact=1.0;
+     216     7004030 :   for(unsigned j=1; j<=m; ++j) fact=fact*j;
+     217     1794050 :   double res=coeff_poly[m]*fact;
+     218             : 
+     219     1794050 :   double pow=1.0, xi=val, dxi=1.0; df=0.0;
+     220     7004030 :   for(int i=m+1; i<=tmom; ++i) {
+     221             :     fact=1.0;
+     222    13759570 :     for(unsigned j=i-m+1; j<=i; ++j) fact=fact*j;
+     223     5209980 :     res=res+coeff_poly[i]*fact*xi;
+     224     5209980 :     df = df + pow*coeff_poly[i]*fact*dxi;
+     225     5209980 :     xi=xi*val; dxi=dxi*val; pow+=1.0;
+     226             :   }
+     227     1794050 :   df = df*normaliz[m];
+     228     1794050 :   return normaliz[m]*res;
+     229             : }
+     230             : 
+     231     6353585 : void SphericalHarmonic::addVectorDerivatives( const unsigned& ival, const Vector& der, Matrix<double>& derivatives ) const {
+     232    25414340 :   for(unsigned j=0; j<3; ++j) derivatives(ival,j) = der[j];
+     233     6353585 : }
+     234             : 
+     235             : }
+     236             : }
+     237             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/symfunc/Steinhardt.cpp.func-sort-c.html b/coverage/symfunc/Steinhardt.cpp.func-sort-c.html new file mode 100644 index 000000000000..14b775ee9236 --- /dev/null +++ b/coverage/symfunc/Steinhardt.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - symfunc/Steinhardt.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - symfunc - Steinhardt.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:677391.8 %
Date:2024-04-19 12:12:35Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7symfunc10SteinhardtC2ERKNS_13ActionOptionsE0
_ZN4PLMD7symfunc10SteinhardtC1ERKNS_13ActionOptionsE41
_ZN4PLMD7symfunc10Steinhardt21createVectorNormInputERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_RKiS9_S9_42
_ZN4PLMD7symfunc10Steinhardt16registerKeywordsERNS_8KeywordsE58
_ZNK4PLMD7symfunc10Steinhardt9getSymbolB5cxx11ERKi374
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/symfunc/Steinhardt.cpp.func.html b/coverage/symfunc/Steinhardt.cpp.func.html new file mode 100644 index 000000000000..1e19adc09c4b --- /dev/null +++ b/coverage/symfunc/Steinhardt.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - symfunc/Steinhardt.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - symfunc - Steinhardt.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:677391.8 %
Date:2024-04-19 12:12:35Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7symfunc10Steinhardt16registerKeywordsERNS_8KeywordsE58
_ZN4PLMD7symfunc10Steinhardt21createVectorNormInputERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_RKiS9_S9_42
_ZN4PLMD7symfunc10SteinhardtC1ERKNS_13ActionOptionsE41
_ZN4PLMD7symfunc10SteinhardtC2ERKNS_13ActionOptionsE0
_ZNK4PLMD7symfunc10Steinhardt9getSymbolB5cxx11ERKi374
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/symfunc/Steinhardt.cpp.gcov.html b/coverage/symfunc/Steinhardt.cpp.gcov.html new file mode 100644 index 000000000000..0b8aac6ec1e9 --- /dev/null +++ b/coverage/symfunc/Steinhardt.cpp.gcov.html @@ -0,0 +1,469 @@ + + + + + + + + LCOV - plumed test coverage - symfunc/Steinhardt.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - symfunc - Steinhardt.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:677391.8 %
Date:2024-04-19 12:12:35Functions:4580.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2017 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "CoordinationNumbers.h"
+      23             : #include "core/ActionShortcut.h"
+      24             : #include "multicolvar/MultiColvarShortcuts.h"
+      25             : #include "core/ActionWithValue.h"
+      26             : #include "core/PlumedMain.h"
+      27             : #include "core/ActionSet.h"
+      28             : #include "core/ActionRegister.h"
+      29             : 
+      30             : #include <complex>
+      31             : 
+      32             : namespace PLMD {
+      33             : namespace symfunc {
+      34             : 
+      35             : //+PLUMEDOC MCOLVAR Q1
+      36             : /*
+      37             : Calculate 1st order Steinhardt parameters
+      38             : 
+      39             : \par Examples
+      40             : 
+      41             : */
+      42             : //+ENDPLUMEDOC
+      43             : 
+      44             : //+PLUMEDOC MCOLVAR Q3
+      45             : /*
+      46             : Calculate 3rd order Steinhardt parameters.
+      47             : 
+      48             : The 3rd order Steinhardt parameters allow us to measure the degree to which the first coordination shell
+      49             : around an atom is ordered.  The Steinhardt parameter for atom, \f$i\f$ is complex vector whose components are
+      50             : calculated using the following formula:
+      51             : 
+      52             : \f[
+      53             : q_{3m}(i) = \frac{\sum_j \sigma( r_{ij} ) Y_{3m}(\mathbf{r}_{ij}) }{\sum_j \sigma( r_{ij} ) }
+      54             : \f]
+      55             : 
+      56             : 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
+      57             : \f$+3\f$.  The function \f$\sigma( r_{ij} )\f$ is a \ref switchingfunction that acts on the distance between
+      58             : 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
+      59             : when atom \f$j\f$ is in the first coordination sphere of atom \f$i\f$ and is zero otherwise.
+      60             : 
+      61             : The Steinhardt parameters can be used to measure the degree of order in the system in a variety of different ways.  The
+      62             : simplest way of measuring whether or not the coordination sphere is ordered is to simply take the norm of the above vector i.e.
+      63             : 
+      64             : \f[
+      65             : Q_3(i) = \sqrt{ \sum_{m=-3}^3 q_{3m}(i)^{*} q_{3m}(i) }
+      66             : \f]
+      67             : 
+      68             : This norm is small when the coordination shell is disordered and larger when the coordination shell is ordered. Furthermore, when
+      69             : the keywords LESS_THAN, MIN, MAX, HISTOGRAM, MEAN and so on are used with this colvar it is the distribution of these normed quantities
+      70             : that is investigated.
+      71             : 
+      72             : 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
+      73             : the \f$q_{3}\f$ vectors on adjacent atoms.  More information on these variables can be found in the documentation for \ref LOCAL_Q3,
+      74             : \ref LOCAL_AVERAGE and \ref NLINKS.
+      75             : 
+      76             : \par Examples
+      77             : 
+      78             : The following command calculates the average Q3 parameter for the 64 atoms in a box of Lennard Jones and prints this
+      79             : quantity to a file called colvar:
+      80             : 
+      81             : \plumedfile
+      82             : Q3 SPECIES=1-64 D_0=1.3 R_0=0.2 MEAN LABEL=q3
+      83             : PRINT ARG=q3.mean FILE=colvar
+      84             : \endplumedfile
+      85             : 
+      86             : The following command calculates the histogram of Q3 parameters for the 64 atoms in a box of Lennard Jones and prints these
+      87             : quantities to a file called colvar:
+      88             : 
+      89             : \plumedfile
+      90             : 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
+      91             : PRINT ARG=q3.* FILE=colvar
+      92             : \endplumedfile
+      93             : 
+      94             : The following command could be used to measure the Q3 parameters that describe the arrangement of chlorine ions around the
+      95             : sodium atoms in sodium chloride.  The imagined system here is composed of 64 NaCl formula units and the atoms are arranged in the input
+      96             : 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
+      97             : file called colvar
+      98             : 
+      99             : \plumedfile
+     100             : Q3 SPECIESA=1-64 SPECIESB=65-128 D_0=1.3 R_0=0.2 MEAN LABEL=q3
+     101             : PRINT ARG=q3.mean FILE=colvar
+     102             : \endplumedfile
+     103             : 
+     104             : 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
+     105             : command \ref DUMPATOMS as shown in the example below.  The following output file will output a file in an extended xyz format
+     106             : 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
+     107             : 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
+     108             : 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.
+     109             : 
+     110             : \plumedfile
+     111             : q3: Q3 SPECIESA=1-64 SPECIESB=65-128 D_0=1.3 R_0=0.2 MEAN
+     112             : DUMPATOMS ATOMS=q3 ARG=q3_anorm FILE=q3.xyz
+     113             : \endplumedfile
+     114             : 
+     115             : */
+     116             : //+ENDPLUMEDOC
+     117             : 
+     118             : //+PLUMEDOC MCOLVAR Q4
+     119             : /*
+     120             : Calculate fourth order Steinhardt parameters.
+     121             : 
+     122             : The fourth order Steinhardt parameters allow us to measure the degree to which the first coordination shell
+     123             : around an atom is ordered.  The Steinhardt parameter for atom, \f$i\f$ is complex vector whose components are
+     124             : calculated using the following formula:
+     125             : 
+     126             : \f[
+     127             : q_{4m}(i) = \frac{\sum_j \sigma( r_{ij} ) Y_{4m}(\mathbf{r}_{ij}) }{\sum_j \sigma( r_{ij} ) }
+     128             : \f]
+     129             : 
+     130             : 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
+     131             : \f$+4\f$.  The function \f$\sigma( r_{ij} )\f$ is a \ref switchingfunction that acts on the distance between
+     132             : 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
+     133             : when atom \f$j\f$ is in the first coordination sphere of atom \f$i\f$ and is zero otherwise.
+     134             : 
+     135             : The Steinhardt parameters can be used to measure the degree of order in the system in a variety of different ways.  The
+     136             : simplest way of measuring whether or not the coordination sphere is ordered is to simply take the norm of the above vector i.e.
+     137             : 
+     138             : \f[
+     139             : Q_4(i) = \sqrt{ \sum_{m=-4}^4 q_{4m}(i)^{*} q_{4m}(i) }
+     140             : \f]
+     141             : 
+     142             : This norm is small when the coordination shell is disordered and larger when the coordination shell is ordered. Furthermore, when
+     143             : the keywords LESS_THAN, MIN, MAX, HISTOGRAM, MEAN and so on are used with this colvar it is the distribution of these normed quantities
+     144             : that is investigated.
+     145             : 
+     146             : 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
+     147             : the \f$q_{4}\f$ vectors on adjacent atoms.  More information on these variables can be found in the documentation for \ref LOCAL_Q4,
+     148             : \ref LOCAL_AVERAGE and \ref NLINKS.
+     149             : 
+     150             : \par Examples
+     151             : 
+     152             : The following command calculates the average Q4 parameter for the 64 atoms in a box of Lennard Jones and prints this
+     153             : quantity to a file called colvar:
+     154             : 
+     155             : \plumedfile
+     156             : Q4 SPECIES=1-64 D_0=1.3 R_0=0.2 MEAN LABEL=q4
+     157             : PRINT ARG=q4.mean FILE=colvar
+     158             : \endplumedfile
+     159             : 
+     160             : The following command calculates the histogram of Q4 parameters for the 64 atoms in a box of Lennard Jones and prints these
+     161             : quantities to a file called colvar:
+     162             : 
+     163             : \plumedfile
+     164             : 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
+     165             : PRINT ARG=q4.* FILE=colvar
+     166             : \endplumedfile
+     167             : 
+     168             : The following command could be used to measure the Q4 parameters that describe the arrangement of chlorine ions around the
+     169             : sodium atoms in sodium chloride.  The imagined system here is composed of 64 NaCl formula units and the atoms are arranged in the input
+     170             : 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
+     171             : file called colvar
+     172             : 
+     173             : \plumedfile
+     174             : Q4 SPECIESA=1-64 SPECIESB=65-128 D_0=1.3 R_0=0.2 MEAN LABEL=q4
+     175             : PRINT ARG=q4.mean FILE=colvar
+     176             : \endplumedfile
+     177             : 
+     178             : 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
+     179             : command \ref DUMPATOMS as shown in the example below.  The following output file will output a file in an extended xyz format
+     180             : 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
+     181             : 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
+     182             : 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.
+     183             : 
+     184             : \plumedfile
+     185             : q4: Q4 SPECIESA=1-64 SPECIESB=65-128 D_0=1.3 R_0=0.2 MEAN
+     186             : DUMPATOMS ATOMS=q4 ARG=q4_anorm FILE=q4.xyz
+     187             : \endplumedfile
+     188             : 
+     189             : */
+     190             : //+ENDPLUMEDOC
+     191             : 
+     192             : //+PLUMEDOC MCOLVAR Q6
+     193             : /*
+     194             : Calculate sixth order Steinhardt parameters.
+     195             : 
+     196             : The sixth order Steinhardt parameters allow us to measure the degree to which the first coordination shell
+     197             : around an atom is ordered.  The Steinhardt parameter for atom, \f$i\f$ is complex vector whose components are
+     198             : calculated using the following formula:
+     199             : 
+     200             : \f[
+     201             : q_{6m}(i) = \frac{\sum_j \sigma( r_{ij} ) Y_{6m}(\mathbf{r}_{ij}) }{\sum_j \sigma( r_{ij} ) }
+     202             : \f]
+     203             : 
+     204             : 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
+     205             : \f$+6\f$.  The function \f$\sigma( r_{ij} )\f$ is a \ref switchingfunction that acts on the distance between
+     206             : 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
+     207             : when atom \f$j\f$ is in the first coordination sphere of atom \f$i\f$ and is zero otherwise.
+     208             : 
+     209             : The Steinhardt parameters can be used to measure the degree of order in the system in a variety of different ways.  The
+     210             : simplest way of measuring whether or not the coordination sphere is ordered is to simply take the norm of the above vector i.e.
+     211             : 
+     212             : \f[
+     213             : Q_6(i) = \sqrt{ \sum_{m=-6}^6 q_{6m}(i)^{*} q_{6m}(i) }
+     214             : \f]
+     215             : 
+     216             : This norm is small when the coordination shell is disordered and larger when the coordination shell is ordered. Furthermore, when
+     217             : the keywords LESS_THAN, MIN, MAX, HISTOGRAM, MEAN and so on are used with this colvar it is the distribution of these normed quantities
+     218             : that is investigated.
+     219             : 
+     220             : 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
+     221             : the \f$q_{6}\f$ vectors on adjacent atoms.  More information on these variables can be found in the documentation for \ref LOCAL_Q6,
+     222             : \ref LOCAL_AVERAGE and \ref NLINKS.
+     223             : 
+     224             : \par Examples
+     225             : 
+     226             : The following command calculates the average Q6 parameter for the 64 atoms in a box of Lennard Jones and prints this
+     227             : quantity to a file called colvar:
+     228             : 
+     229             : \plumedfile
+     230             : Q6 SPECIES=1-64 D_0=1.3 R_0=0.2 MEAN LABEL=q6
+     231             : PRINT ARG=q6.mean FILE=colvar
+     232             : \endplumedfile
+     233             : 
+     234             : The following command calculates the histogram of Q6 parameters for the 64 atoms in a box of Lennard Jones and prints these
+     235             : quantities to a file called colvar:
+     236             : 
+     237             : \plumedfile
+     238             : 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
+     239             : PRINT ARG=q6.* FILE=colvar
+     240             : \endplumedfile
+     241             : 
+     242             : The following command could be used to measure the Q6 parameters that describe the arrangement of chlorine ions around the
+     243             : sodium atoms in sodium chloride.  The imagined system here is composed of 64 NaCl formula units and the atoms are arranged in the input
+     244             : 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
+     245             : file called colvar
+     246             : 
+     247             : \plumedfile
+     248             : Q6 SPECIESA=1-64 SPECIESB=65-128 D_0=1.3 R_0=0.2 MEAN LABEL=q6
+     249             : PRINT ARG=q6.mean FILE=colvar
+     250             : \endplumedfile
+     251             : 
+     252             : 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
+     253             : command \ref DUMPATOMS as shown in the example below.  The following output file will output a file in an extended xyz format
+     254             : 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
+     255             : 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
+     256             : 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.
+     257             : 
+     258             : \plumedfile
+     259             : q6: Q6 SPECIESA=1-64 SPECIESB=65-128 D_0=1.3 R_0=0.2 MEAN
+     260             : DUMPATOMS ARG=q6_anorm ATOMS=q6 FILE=q6.xyz
+     261             : \endplumedfile
+     262             : 
+     263             : */
+     264             : //+ENDPLUMEDOC
+     265             : 
+     266             : class Steinhardt : public ActionShortcut {
+     267             : private:
+     268             :   std::string getSymbol( const int& m ) const ;
+     269             :   void createVectorNormInput( const std::string& ilab, const std::string& olab, const int& l, const std::string& sep, const std::string& vlab );
+     270             : public:
+     271             :   static void registerKeywords( Keywords& keys );
+     272             :   explicit Steinhardt(const ActionOptions&);
+     273             : };
+     274             : 
+     275             : PLUMED_REGISTER_ACTION(Steinhardt,"Q1")
+     276             : PLUMED_REGISTER_ACTION(Steinhardt,"Q3")
+     277             : PLUMED_REGISTER_ACTION(Steinhardt,"Q4")
+     278             : PLUMED_REGISTER_ACTION(Steinhardt,"Q6")
+     279             : 
+     280          58 : void Steinhardt::registerKeywords( Keywords& keys ) {
+     281          58 :   CoordinationNumbers::shortcutKeywords( keys );
+     282         116 :   keys.addFlag("LOWMEM",false,"this flag does nothing and is present only to ensure back-compatibility");
+     283         116 :   keys.addFlag("VMEAN",false,"calculate the norm of the mean vector.");
+     284         116 :   keys.addOutputComponent("_vmean","VMEAN","the norm of the mean vector");
+     285         116 :   keys.addFlag("VSUM",false,"calculate the norm of the sum of all the vectors");
+     286         116 :   keys.addOutputComponent("_vsum","VSUM","the norm of the mean vector");
+     287         232 :   keys.needsAction("GROUP"); keys.needsAction("CONTACT_MATRIX"); keys.needsAction("SPHERICAL_HARMONIC"); keys.needsAction("ONES");
+     288         290 :   keys.needsAction("MATRIX_VECTOR_PRODUCT"); keys.needsAction("COMBINE"); keys.needsAction("CUSTOM"); keys.needsAction("MEAN"); keys.needsAction("SUM");
+     289          58 : }
+     290             : 
+     291          41 : Steinhardt::Steinhardt( const ActionOptions& ao):
+     292             :   Action(ao),
+     293          41 :   ActionShortcut(ao)
+     294             : {
+     295          41 :   bool lowmem; parseFlag("LOWMEM",lowmem);
+     296          41 :   if( lowmem ) warning("LOWMEM flag is deprecated and is no longer required for this action");
+     297         123 :   std::string sp_str, specA, specB; parse("SPECIES",sp_str); parse("SPECIESA",specA); parse("SPECIESB",specB);
+     298          41 :   CoordinationNumbers::expandMatrix( true, getShortcutLabel(), sp_str, specA, specB, this ); int l;
+     299          82 :   std::string sph_input = getShortcutLabel() + "_sh: SPHERICAL_HARMONIC ARG=" + getShortcutLabel() + "_mat.x," + getShortcutLabel() + "_mat.y," + getShortcutLabel() + "_mat.z," + getShortcutLabel() + "_mat.w";
+     300             : 
+     301          41 :   if( getName()=="Q1" ) {
+     302          18 :     sph_input +=" L=1"; l=1;
+     303          23 :   } else if( getName()=="Q3" ) {
+     304           1 :     sph_input += " L=3"; l=3;
+     305          22 :   } else if( getName()=="Q4" ) {
+     306           3 :     sph_input += " L=4"; l=4;
+     307          19 :   } else if( getName()=="Q6" ) {
+     308          19 :     sph_input += " L=6"; l=6;
+     309             :   } else {
+     310           0 :     plumed_merror("invalid input");
+     311             :   }
+     312          41 :   readInputLine( sph_input );
+     313             : 
+     314             :   // Input for denominator (coord)
+     315          41 :   ActionWithValue* av = plumed.getActionSet().selectWithLabel<ActionWithValue*>( getShortcutLabel() + "_mat");
+     316          41 :   plumed_assert( av && av->getNumberOfComponents()>0 && (av->copyOutput(0))->getRank()==2 );
+     317          41 :   std::string size; Tools::convert( (av->copyOutput(0))->getShape()[1], size );
+     318          82 :   readInputLine( getShortcutLabel() + "_denom_ones: ONES SIZE=" + size );
+     319          82 :   readInputLine( getShortcutLabel() + "_denom: MATRIX_VECTOR_PRODUCT ARG=" + getShortcutLabel() + "_mat.w," + getShortcutLabel() + "_denom_ones" );
+     320          82 :   readInputLine( getShortcutLabel() + "_sp: MATRIX_VECTOR_PRODUCT ARG=" + getShortcutLabel() + "_sh.*," + getShortcutLabel() + "_denom_ones");
+     321             : 
+     322             :   // If we are doing VMEAN determine sum of vector components
+     323             :   std::string snum;
+     324          41 :   bool do_vmean; parseFlag("VMEAN",do_vmean);
+     325          41 :   bool do_vsum; parseFlag("VSUM",do_vsum);
+     326          41 :   if( do_vmean || do_vsum ) {
+     327             :     // Divide all components by coordination numbers
+     328          14 :     for(int i=-l; i<=l; ++i) {
+     329          13 :       snum = getSymbol( i );
+     330             :       // Real part
+     331          26 :       readInputLine( getShortcutLabel() + "_rmn-" + snum + ": CUSTOM ARG=" + getShortcutLabel() + "_sp.rm-" + snum + "," + getShortcutLabel() + "_denom FUNC=x/y PERIODIC=NO");
+     332             :       // Imaginary part
+     333          26 :       readInputLine( getShortcutLabel() + "_imn-" + snum + ": CUSTOM ARG=" + getShortcutLabel() + "_sp.im-" + snum + "," + getShortcutLabel() + "_denom FUNC=x/y PERIODIC=NO");
+     334             :     }
+     335             :   }
+     336             : 
+     337          41 :   if( do_vmean ) {
+     338          14 :     for(int i=-l; i<=l; ++i) {
+     339          13 :       snum = getSymbol( i );
+     340             :       // Real part
+     341          26 :       readInputLine( getShortcutLabel() + "_rms-" + snum + ": MEAN ARG=" + getShortcutLabel() + "_rmn-" + snum + " PERIODIC=NO");
+     342             :       // Imaginary part
+     343          26 :       readInputLine( getShortcutLabel() + "_ims-" + snum + ": MEAN ARG=" + getShortcutLabel() + "_imn-" + snum + " PERIODIC=NO");
+     344             :     }
+     345             :     // Now calculate the total length of the vector
+     346           2 :     createVectorNormInput( getShortcutLabel(), getShortcutLabel() + "_vmean", l, "_", "ms" );
+     347             :   }
+     348          41 :   if( do_vsum ) {
+     349           0 :     for(int i=-l; i<=l; ++i) {
+     350           0 :       snum = getSymbol( i );
+     351             :       // Real part
+     352           0 :       readInputLine( getShortcutLabel() + "_rmz-" + snum + ": SUM ARG=" + getShortcutLabel() + "_rmn-" + snum + " PERIODIC=NO");
+     353             :       // Imaginary part
+     354           0 :       readInputLine( getShortcutLabel() + "_imz-" + snum + ": SUM ARG=" + getShortcutLabel() + "_imn-" + snum + " PERIODIC=NO");
+     355             :     }
+     356             :     // Now calculate the total length of the vector
+     357           0 :     createVectorNormInput( getShortcutLabel(), getShortcutLabel() + "_vsum", l, "_", "mz" );
+     358             :   }
+     359             : 
+     360             :   // Now calculate the total length of the vector
+     361          82 :   createVectorNormInput( getShortcutLabel() + "_sp", getShortcutLabel() + "_norm", l, ".", "m" );
+     362             :   // And take average
+     363          82 :   readInputLine( getShortcutLabel() + ": CUSTOM ARG=" + getShortcutLabel() + "_norm," + getShortcutLabel() + "_denom FUNC=x/y PERIODIC=NO");
+     364          82 :   multicolvar::MultiColvarShortcuts::expandFunctions( getShortcutLabel(), getShortcutLabel(), "", this );
+     365          41 : }
+     366             : 
+     367          42 : void Steinhardt::createVectorNormInput( const std::string& ilab, const std::string& olab, const int& l, const std::string& sep, const std::string& vlab ) {
+     368          42 :   std::string arg_inp, norm_input = olab + "2: COMBINE PERIODIC=NO POWERS=2,2"; std::string snum = getSymbol( -l );
+     369          84 :   arg_inp = " ARG=" + ilab + sep + "r" + vlab + "-" + snum +"," + ilab + sep + "i" + vlab + "-" + snum;
+     370         348 :   for(int i=-l+1; i<=l; ++i) {
+     371         306 :     snum = getSymbol( i );
+     372         612 :     arg_inp += "," + ilab + sep + "r" + vlab + "-" + snum + "," + ilab + sep + "i" + vlab + "-" + snum;
+     373             :     norm_input += ",2,2";
+     374             :   }
+     375          42 :   readInputLine( norm_input + arg_inp );
+     376          84 :   readInputLine( olab + ": CUSTOM ARG=" + olab + "2 FUNC=sqrt(x) PERIODIC=NO");
+     377          42 : }
+     378             : 
+     379         374 : std::string Steinhardt::getSymbol( const int& m ) const {
+     380         374 :   if( m<0 ) {
+     381         165 :     std::string num; Tools::convert( -1*m, num );
+     382         165 :     return "n" + num;
+     383         209 :   } else if( m>0 ) {
+     384         165 :     std::string num; Tools::convert( m, num );
+     385         165 :     return "p" + num;
+     386             :   }
+     387          44 :   return "0";
+     388             : }
+     389             : 
+     390             : }
+     391             : }
+     392             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/symfunc/ThreeBodyGFunctions.cpp.func-sort-c.html b/coverage/symfunc/ThreeBodyGFunctions.cpp.func-sort-c.html new file mode 100644 index 000000000000..1811610c127f --- /dev/null +++ b/coverage/symfunc/ThreeBodyGFunctions.cpp.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - symfunc/ThreeBodyGFunctions.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - symfunc - ThreeBodyGFunctions.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:9090100.0 %
Date:2024-04-19 12:12:35Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7symfunc19ThreeBodyGFunctionsC2ERKNS_13ActionOptionsE0
_ZN4PLMD7symfunc19ThreeBodyGFunctionsC1ERKNS_13ActionOptionsE5
_ZN4PLMD7symfunc19ThreeBodyGFunctions16registerKeywordsERNS_8KeywordsE7
_ZN4PLMD7symfunc19ThreeBodyGFunctions9calculateEv19
_ZN4PLMD7symfunc19ThreeBodyGFunctions22getNumberOfDerivativesEv36
_ZNK4PLMD7symfunc19ThreeBodyGFunctions11performTaskERKjRNS_10MultiValueE472
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/symfunc/ThreeBodyGFunctions.cpp.func.html b/coverage/symfunc/ThreeBodyGFunctions.cpp.func.html new file mode 100644 index 000000000000..444d30ccec4d --- /dev/null +++ b/coverage/symfunc/ThreeBodyGFunctions.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - symfunc/ThreeBodyGFunctions.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - symfunc - ThreeBodyGFunctions.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:9090100.0 %
Date:2024-04-19 12:12:35Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7symfunc19ThreeBodyGFunctions16registerKeywordsERNS_8KeywordsE7
_ZN4PLMD7symfunc19ThreeBodyGFunctions22getNumberOfDerivativesEv36
_ZN4PLMD7symfunc19ThreeBodyGFunctions9calculateEv19
_ZN4PLMD7symfunc19ThreeBodyGFunctionsC1ERKNS_13ActionOptionsE5
_ZN4PLMD7symfunc19ThreeBodyGFunctionsC2ERKNS_13ActionOptionsE0
_ZNK4PLMD7symfunc19ThreeBodyGFunctions11performTaskERKjRNS_10MultiValueE472
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/symfunc/ThreeBodyGFunctions.cpp.gcov.html b/coverage/symfunc/ThreeBodyGFunctions.cpp.gcov.html new file mode 100644 index 000000000000..d1d6c30e20d8 --- /dev/null +++ b/coverage/symfunc/ThreeBodyGFunctions.cpp.gcov.html @@ -0,0 +1,254 @@ + + + + + + + + LCOV - plumed test coverage - symfunc/ThreeBodyGFunctions.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - symfunc - ThreeBodyGFunctions.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:9090100.0 %
Date:2024-04-19 12:12:35Functions:5683.3 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2017 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received 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/ActionWithVector.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "tools/LeptonCall.h"
+      25             : #include "tools/Angle.h"
+      26             : 
+      27             : namespace PLMD {
+      28             : namespace symfunc {
+      29             : 
+      30             : //+PLUMEDOC COLVAR GSYMFUNC_THREEBODY
+      31             : /*
+      32             : Calculate functions of the coordinates of the coordinates of all pairs of bonds in the first coordination sphere of an atom
+      33             : 
+      34             : \par Examples
+      35             : 
+      36             : */
+      37             : //+ENDPLUMEDOC
+      38             : 
+      39             : class ThreeBodyGFunctions : public ActionWithVector {
+      40             : private:
+      41             :   std::vector<LeptonCall> functions;
+      42             : public:
+      43             :   static void registerKeywords( Keywords& keys );
+      44             :   explicit ThreeBodyGFunctions(const ActionOptions&);
+      45             :   void calculate() override ;
+      46             :   unsigned getNumberOfDerivatives() override;
+      47             :   void performTask( const unsigned& task_index, MultiValue& myvals ) const override ;
+      48             : };
+      49             : 
+      50             : PLUMED_REGISTER_ACTION(ThreeBodyGFunctions,"GSYMFUNC_THREEBODY")
+      51             : 
+      52           7 : void ThreeBodyGFunctions::registerKeywords( Keywords& keys ) {
+      53           7 :   ActionWithVector::registerKeywords( keys ); keys.use("ARG");
+      54          14 :   keys.add("compulsory","WEIGHT","the matrix that contains the weights that should be used for each connection");
+      55          14 :   keys.add("numbered","FUNCTION","the parameters of the function you would like to compute");
+      56           7 :   ActionWithValue::useCustomisableComponents( keys );
+      57           7 : }
+      58             : 
+      59           5 : ThreeBodyGFunctions::ThreeBodyGFunctions(const ActionOptions&ao):
+      60             :   Action(ao),
+      61           5 :   ActionWithVector(ao)
+      62             : {
+      63           5 :   if( getNumberOfArguments()!=3 ) error("found wrong number of arguments in input");
+      64          10 :   std::vector<Value*> wval; parseArgumentList("WEIGHT",wval);
+      65           5 :   if( wval.size()!=1 ) error("keyword WEIGHT should be provided with the label of a single action");
+      66             : 
+      67          20 :   for(unsigned i=0; i<3; ++i) {
+      68          15 :     if( getPntrToArgument(i)->getRank()!=2 ) error("input argument should be a matrix");
+      69          15 :     if( wval[0]->getShape()[0]!=getPntrToArgument(i)->getShape()[0] || wval[0]->getShape()[1]!=getPntrToArgument(i)->getShape()[1] ) error("mismatched shapes of matrices in input");
+      70             :   }
+      71           5 :   log.printf("  using bond weights from matrix labelled %s \n",wval[0]->getName().c_str() );
+      72             :   // Rerequest the arguments
+      73           5 :   std::vector<Value*> myargs( getArguments() ); myargs.push_back( wval[0] ); requestArguments( myargs );
+      74          25 :   for(unsigned i=0; i<myargs.size(); ++i) myargs[i]->buildDataStore();
+      75           5 :   std::vector<unsigned> shape(1); shape[0] = getPntrToArgument(0)->getShape()[0];
+      76             : 
+      77             :   // And now read the functions to compute
+      78           5 :   for(int i=1;; i++) {
+      79          14 :     std::string myfunc, mystr, lab, num; Tools::convert(i,num);
+      80          28 :     if( !parseNumbered("FUNCTION",i,mystr ) ) break;
+      81           9 :     std::vector<std::string> data=Tools::getWords(mystr);
+      82          18 :     if( !Tools::parse(data,"LABEL",lab ) ) error("found no LABEL in FUNCTION" + num + " specification");
+      83           9 :     addComponent( lab, shape ); componentIsNotPeriodic( lab );
+      84          18 :     if( !Tools::parse(data,"FUNC",myfunc) ) error("found no FUNC in FUNCTION" + num + " specification");
+      85           9 :     log.printf("  component labelled %s is computed using %s \n",lab.c_str(), myfunc.c_str() );
+      86           9 :     functions.push_back( LeptonCall() ); std::vector<std::string> argnames(1); argnames[0]="ajik";
+      87          13 :     if( myfunc.find("rij")!=std::string::npos ) argnames.push_back("rij");
+      88           9 :     if( myfunc.find("rik")!=std::string::npos ) {
+      89           4 :       if( argnames.size()<2 ) error("if you have a function of rik it must also be a function of rij -- email gareth.tribello@gmail.com if this is a problem");
+      90           8 :       argnames.push_back("rik");
+      91             :     }
+      92           9 :     if( myfunc.find("rjk")!=std::string::npos ) {
+      93           3 :       if( argnames.size()<2 ) error("if you have a function of rjk it must also be a function of rij and rik -- email gareth.tribello@gmail.com if this is a problem");
+      94           6 :       argnames.push_back("rjk");
+      95             :     }
+      96           9 :     functions[i-1].set( myfunc, argnames, this, true );
+      97          18 :   }
+      98           5 :   checkRead();
+      99           5 : }
+     100             : 
+     101          36 : unsigned ThreeBodyGFunctions::getNumberOfDerivatives() {
+     102          36 :   return 0;
+     103             : }
+     104             : 
+     105          19 : void ThreeBodyGFunctions::calculate() {
+     106          19 :   runAllTasks();
+     107          19 : }
+     108             : 
+     109         472 : void ThreeBodyGFunctions::performTask( const unsigned& task_index, MultiValue& myvals ) const {
+     110             :   const Value* wval = getPntrToArgument(3);
+     111             :   const Value* xval = getPntrToArgument(0);
+     112             :   const Value* yval = getPntrToArgument(1);
+     113             :   const Value* zval = getPntrToArgument(2);
+     114         472 :   Angle angle; Vector disti, distj; unsigned matsize = wval->getNumberOfValues();
+     115         472 :   std::vector<double> values(4); std::vector<Vector> der_i(4), der_j(4);
+     116         472 :   unsigned nbonds = wval->getRowLength( task_index ), ncols = wval->getShape()[1];
+     117       13880 :   for(unsigned i=0; i<nbonds; ++i) {
+     118       13408 :     unsigned ipos = ncols*task_index + wval->getRowIndex( task_index, i );
+     119       13408 :     double weighti = wval->get( ipos );
+     120       13408 :     if( weighti<epsilon ) continue ;
+     121        6824 :     disti[0] = xval->get( ipos );
+     122        6824 :     disti[1] = yval->get( ipos );
+     123        6824 :     disti[2] = zval->get( ipos );
+     124        6824 :     values[1] = disti.modulo2(); der_i[1]=2*disti; der_i[2].zero();
+     125      189327 :     for(unsigned j=0; j<i; ++j) {
+     126      182503 :       unsigned jpos = ncols*task_index + wval->getRowIndex( task_index, j );
+     127      182503 :       double weightj = wval->get( jpos );
+     128      182503 :       if( weightj<epsilon ) continue ;
+     129      137009 :       distj[0] = xval->get( jpos );
+     130      137009 :       distj[1] = yval->get( jpos );
+     131      137009 :       distj[2] = zval->get( jpos );
+     132      137009 :       values[2] = distj.modulo2(); der_j[1].zero(); der_j[2]=2*distj;
+     133      137009 :       der_i[3] = ( disti - distj ); values[3] = der_i[3].modulo2();
+     134      137009 :       der_i[3] = 2*der_i[3]; der_j[3] = -der_i[3];
+     135             :       // Compute angle between bonds
+     136      137009 :       values[0] = angle.compute( disti, distj, der_i[0], der_j[0] );
+     137             :       // Compute product of weights
+     138      137009 :       double weightij = weighti*weightj;
+     139             :       // Now compute all symmetry functions
+     140      414532 :       for(unsigned n=0; n<functions.size(); ++n) {
+     141      277523 :         unsigned ostrn = getConstPntrToComponent(n)->getPositionInStream();
+     142      277523 :         double nonweight = functions[n].evaluate( values ); myvals.addValue( ostrn, nonweight*weightij );
+     143      277523 :         if( doNotCalculateDerivatives() ) continue;
+     144             : 
+     145      567230 :         for(unsigned m=0; m<functions[n].getNumberOfArguments(); ++m) {
+     146      296550 :           double der = weightij*functions[n].evaluateDeriv( m, values );
+     147      296550 :           myvals.addDerivative( ostrn, ipos, der*der_i[m][0] );
+     148      296550 :           myvals.addDerivative( ostrn, matsize+ipos, der*der_i[m][1] );
+     149      296550 :           myvals.addDerivative( ostrn, 2*matsize+ipos, der*der_i[m][2] );
+     150      296550 :           myvals.addDerivative( ostrn, jpos, der*der_j[m][0] );
+     151      296550 :           myvals.addDerivative( ostrn, matsize+jpos, der*der_j[m][1] );
+     152      296550 :           myvals.addDerivative( ostrn, 2*matsize+jpos, der*der_j[m][2] );
+     153             :         }
+     154      270680 :         myvals.addDerivative( ostrn, 3*matsize+ipos, nonweight*weightj );
+     155      270680 :         myvals.addDerivative( ostrn, 3*matsize+jpos, nonweight*weighti );
+     156             :       }
+     157             :     }
+     158             :   }
+     159         472 :   if( doNotCalculateDerivatives() ) return ;
+     160             : 
+     161             :   // And update the elements that have derivatives
+     162             :   // Needs a separate loop here as there may be forces from j
+     163        8320 :   for(unsigned i=0; i<nbonds; ++i) {
+     164        8192 :     unsigned ipos = ncols*task_index + wval->getRowIndex( task_index, i );
+     165        8192 :     double weighti = wval->get( ipos );
+     166        8192 :     if( weighti<epsilon ) continue ;
+     167             : 
+     168       16286 :     for(unsigned n=0; n<functions.size(); ++n) {
+     169       11416 :       unsigned ostrn = getConstPntrToComponent(n)->getPositionInStream();
+     170       11416 :       myvals.updateIndex( ostrn, ipos ); myvals.updateIndex( ostrn, matsize+ipos );
+     171       11416 :       myvals.updateIndex( ostrn, 2*matsize+ipos ); myvals.updateIndex( ostrn, 3*matsize+ipos );
+     172             :     }
+     173             :   }
+     174             : }
+     175             : 
+     176             : }
+     177             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/symfunc/index-sort-f.html b/coverage/symfunc/index-sort-f.html new file mode 100644 index 000000000000..f001c3ae438e --- /dev/null +++ b/coverage/symfunc/index-sort-f.html @@ -0,0 +1,234 @@ + + + + + + + + LCOV - plumed test coverage - symfunc + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - symfuncHitTotalCoverage
Test:plumed test coverageLines:78185691.2 %
Date:2024-04-19 12:12:35Functions:506280.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
SMAC.cpp +
98.2%98.2%
+
98.2 %56 / 5766.7 %2 / 3
AngularTetra.cpp +
84.6%84.6%
+
84.6 %22 / 2666.7 %2 / 3
CoordShellVectorFunction.cpp +
78.5%78.5%
+
78.5 %51 / 6566.7 %2 / 3
LocalCrystalinity.cpp +
100.0%
+
100.0 %35 / 3566.7 %2 / 3
RadialTetra.cpp +
88.2%88.2%
+
88.2 %30 / 3466.7 %2 / 3
AtomicSMAC.cpp +
91.3%91.3%
+
91.3 %42 / 4666.7 %2 / 3
LocalAverage.cpp +
100.0%
+
100.0 %53 / 5375.0 %3 / 4
HexaticParameter.cpp +
77.6%77.6%
+
77.6 %38 / 4975.0 %3 / 4
CoordinationNumbers.cpp +
98.6%98.6%
+
98.6 %68 / 6980.0 %4 / 5
Steinhardt.cpp +
91.8%91.8%
+
91.8 %67 / 7380.0 %4 / 5
LocalSteinhardt.cpp +
78.3%78.3%
+
78.3 %83 / 10680.0 %4 / 5
ThreeBodyGFunctions.cpp +
100.0%
+
100.0 %90 / 9083.3 %5 / 6
Fccubic.cpp +
100.0%
+
100.0 %29 / 29100.0 %3 / 3
CylindricalHarmonic.cpp +
100.0%
+
100.0 %24 / 24100.0 %4 / 4
SphericalHarmonic.cpp +
93.0%93.0%
+
93.0 %93 / 100100.0 %8 / 8
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/symfunc/index-sort-l.html b/coverage/symfunc/index-sort-l.html new file mode 100644 index 000000000000..f7f8b14ecdc3 --- /dev/null +++ b/coverage/symfunc/index-sort-l.html @@ -0,0 +1,234 @@ + + + + + + + + LCOV - plumed test coverage - symfunc + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - symfuncHitTotalCoverage
Test:plumed test coverageLines:78185691.2 %
Date:2024-04-19 12:12:35Functions:506280.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
HexaticParameter.cpp +
77.6%77.6%
+
77.6 %38 / 4975.0 %3 / 4
LocalSteinhardt.cpp +
78.3%78.3%
+
78.3 %83 / 10680.0 %4 / 5
CoordShellVectorFunction.cpp +
78.5%78.5%
+
78.5 %51 / 6566.7 %2 / 3
AngularTetra.cpp +
84.6%84.6%
+
84.6 %22 / 2666.7 %2 / 3
RadialTetra.cpp +
88.2%88.2%
+
88.2 %30 / 3466.7 %2 / 3
AtomicSMAC.cpp +
91.3%91.3%
+
91.3 %42 / 4666.7 %2 / 3
Steinhardt.cpp +
91.8%91.8%
+
91.8 %67 / 7380.0 %4 / 5
SphericalHarmonic.cpp +
93.0%93.0%
+
93.0 %93 / 100100.0 %8 / 8
SMAC.cpp +
98.2%98.2%
+
98.2 %56 / 5766.7 %2 / 3
CoordinationNumbers.cpp +
98.6%98.6%
+
98.6 %68 / 6980.0 %4 / 5
CylindricalHarmonic.cpp +
100.0%
+
100.0 %24 / 24100.0 %4 / 4
Fccubic.cpp +
100.0%
+
100.0 %29 / 29100.0 %3 / 3
LocalCrystalinity.cpp +
100.0%
+
100.0 %35 / 3566.7 %2 / 3
LocalAverage.cpp +
100.0%
+
100.0 %53 / 5375.0 %3 / 4
ThreeBodyGFunctions.cpp +
100.0%
+
100.0 %90 / 9083.3 %5 / 6
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/symfunc/index.html b/coverage/symfunc/index.html new file mode 100644 index 000000000000..f7e64ff73bc3 --- /dev/null +++ b/coverage/symfunc/index.html @@ -0,0 +1,234 @@ + + + + + + + + LCOV - plumed test coverage - symfunc + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - symfuncHitTotalCoverage
Test:plumed test coverageLines:78185691.2 %
Date:2024-04-19 12:12:35Functions:506280.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
AngularTetra.cpp +
84.6%84.6%
+
84.6 %22 / 2666.7 %2 / 3
AtomicSMAC.cpp +
91.3%91.3%
+
91.3 %42 / 4666.7 %2 / 3
CoordShellVectorFunction.cpp +
78.5%78.5%
+
78.5 %51 / 6566.7 %2 / 3
CoordinationNumbers.cpp +
98.6%98.6%
+
98.6 %68 / 6980.0 %4 / 5
CylindricalHarmonic.cpp +
100.0%
+
100.0 %24 / 24100.0 %4 / 4
Fccubic.cpp +
100.0%
+
100.0 %29 / 29100.0 %3 / 3
HexaticParameter.cpp +
77.6%77.6%
+
77.6 %38 / 4975.0 %3 / 4
LocalAverage.cpp +
100.0%
+
100.0 %53 / 5375.0 %3 / 4
LocalCrystalinity.cpp +
100.0%
+
100.0 %35 / 3566.7 %2 / 3
LocalSteinhardt.cpp +
78.3%78.3%
+
78.3 %83 / 10680.0 %4 / 5
RadialTetra.cpp +
88.2%88.2%
+
88.2 %30 / 3466.7 %2 / 3
SMAC.cpp +
98.2%98.2%
+
98.2 %56 / 5766.7 %2 / 3
SphericalHarmonic.cpp +
93.0%93.0%
+
93.0 %93 / 100100.0 %8 / 8
Steinhardt.cpp +
91.8%91.8%
+
91.8 %67 / 7380.0 %4 / 5
ThreeBodyGFunctions.cpp +
100.0%
+
100.0 %90 / 9083.3 %5 / 6
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Angle.cpp.func-sort-c.html b/coverage/tools/Angle.cpp.func-sort-c.html new file mode 100644 index 000000000000..4bbc06534508 --- /dev/null +++ b/coverage/tools/Angle.cpp.func-sort-c.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - tools/Angle.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Angle.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2626100.0 %
Date:2024-04-19 12:12:35Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD5Angle7computeERKNS_13VectorGenericILj3EEES4_2
_ZNK4PLMD5Angle7computeERKNS_13VectorGenericILj3EEES4_RS2_S5_653698
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Angle.cpp.func.html b/coverage/tools/Angle.cpp.func.html new file mode 100644 index 000000000000..263e22743063 --- /dev/null +++ b/coverage/tools/Angle.cpp.func.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - tools/Angle.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Angle.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2626100.0 %
Date:2024-04-19 12:12:35Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD5Angle7computeERKNS_13VectorGenericILj3EEES4_2
_ZNK4PLMD5Angle7computeERKNS_13VectorGenericILj3EEES4_RS2_S5_653698
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Angle.cpp.gcov.html b/coverage/tools/Angle.cpp.gcov.html new file mode 100644 index 000000000000..7adab97a9423 --- /dev/null +++ b/coverage/tools/Angle.cpp.gcov.html @@ -0,0 +1,145 @@ + + + + + + + + LCOV - plumed test coverage - tools/Angle.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Angle.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2626100.0 %
Date:2024-04-19 12:12:35Functions: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      653698 : double Angle::compute(const Vector& v1,const Vector& v2,Vector& d1,Vector& d2)const {
+      33      653698 :   const double dp(dotProduct(v1,v2));
+      34             :   const Vector& dp_dv1(v2);
+      35             :   const Vector& dp_dv2(v1);
+      36      653698 :   const double sv1(v1.modulo2());
+      37      653698 :   const double sv2(v2.modulo2());
+      38      653698 :   const Vector dsv1_dv1(2*v1);
+      39      653698 :   const Vector dsv2_dv2(2*v2);
+      40      653698 :   const double nn(1.0/std::sqrt(sv1*sv2));
+      41      653698 :   const Vector dnn_dv1(-0.5*nn/sv1*dsv1_dv1);
+      42      653698 :   const Vector dnn_dv2(-0.5*nn/sv2*dsv2_dv2);
+      43             : 
+      44      653698 :   const double dpnn(dp*nn);
+      45             : 
+      46      653698 :   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      653697 :   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      653696 :   const Vector ddpnn_dv1(dp*dnn_dv1+dp_dv1*nn);
+      57      653696 :   const Vector ddpnn_dv2(dp*dnn_dv2+dp_dv2*nn);
+      58             : 
+      59      653696 :   const double x(-1.0/std::sqrt(1-dpnn*dpnn));
+      60             : 
+      61      653696 :   d1=x*ddpnn_dv1;
+      62      653696 :   d2=x*ddpnn_dv2;
+      63             : 
+      64             : 
+      65      653696 :   return std::acos(dpnn);
+      66             : }
+      67             : 
+      68             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/AtomNumber.h.func-sort-c.html b/coverage/tools/AtomNumber.h.func-sort-c.html new file mode 100644 index 000000000000..db11275b1789 --- /dev/null +++ b/coverage/tools/AtomNumber.h.func-sort-c.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - tools/AtomNumber.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - AtomNumber.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1717100.0 %
Date:2024-04-19 12:12:35Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10AtomNumber6serialEj348
_ZN4PLMD10AtomNumber9setSerialEj1439706
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/AtomNumber.h.func.html b/coverage/tools/AtomNumber.h.func.html new file mode 100644 index 000000000000..ddf746f96832 --- /dev/null +++ b/coverage/tools/AtomNumber.h.func.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - tools/AtomNumber.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - AtomNumber.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1717100.0 %
Date:2024-04-19 12:12:35Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10AtomNumber6serialEj348
_ZN4PLMD10AtomNumber9setSerialEj1439706
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/AtomNumber.h.gcov.html b/coverage/tools/AtomNumber.h.gcov.html new file mode 100644 index 000000000000..7a804203e640 --- /dev/null +++ b/coverage/tools/AtomNumber.h.gcov.html @@ -0,0 +1,229 @@ + + + + + + + + LCOV - plumed test coverage - tools/AtomNumber.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - AtomNumber.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1717100.0 %
Date:2024-04-19 12:12:35Functions: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    11728246 : AtomNumber::AtomNumber() {
+      75    11728198 :   index_=0;
+      76             : }
+      77             : 
+      78             : inline
+      79             : AtomNumber::AtomNumber(unsigned i) {
+      80             :   index_=i;
+      81             : }
+      82             : 
+      83             : inline
+      84             : unsigned AtomNumber::serial()const {
+      85     1126359 :   return index_+1;
+      86             : }
+      87             : 
+      88             : inline
+      89             : unsigned AtomNumber::index()const {
+      90    32231573 :   return index_;
+      91             : }
+      92             : 
+      93             : inline
+      94     1439706 : AtomNumber & AtomNumber::setSerial(unsigned i) {
+      95     1439706 :   plumed_massert(i>0,"serial of an atom cannot be zero");
+      96     1439706 :   plumed_massert(i<std::numeric_limits<unsigned>::max()/2,"serial cannot be negative");
+      97     1439706 :   index_=i-1;
+      98     1439706 :   return *this;
+      99             : }
+     100             : 
+     101             : inline
+     102             : AtomNumber & AtomNumber::setIndex(unsigned i) {
+     103          56 :   index_=i;
+     104             :   return *this;
+     105             : }
+     106             : 
+     107             : inline
+     108         348 : AtomNumber AtomNumber::serial(unsigned i) {
+     109         348 :   plumed_massert(i>0,"serial of an atom cannot be zero");
+     110         348 :   plumed_massert(i<std::numeric_limits<unsigned>::max()/2,"serial cannot be negative");
+     111         348 :   return AtomNumber(i-1);
+     112             : }
+     113             : 
+     114             : inline
+     115             : AtomNumber AtomNumber::index(unsigned i) {
+     116             :   return AtomNumber(i);
+     117             : }
+     118             : 
+     119             : inline
+     120             : bool operator<(const AtomNumber&a,const AtomNumber&b) {
+     121   375715728 :   return a.index_<b.index_;
+     122             : }
+     123             : 
+     124             : inline
+     125             : bool operator>(const AtomNumber&a,const AtomNumber&b) {
+     126     7525314 :   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   170464208 :   return a.index_==b.index_;
+     142             : }
+     143             : 
+     144             : inline
+     145             : bool operator!=(const AtomNumber&a,const AtomNumber&b) {
+     146             :   return a.index_!=b.index_;
+     147             : }
+     148             : 
+     149             : }
+     150             : 
+     151             : #endif
+     152             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/BiasRepresentation.cpp.func-sort-c.html b/coverage/tools/BiasRepresentation.cpp.func-sort-c.html new file mode 100644 index 000000000000..a32365312d49 --- /dev/null +++ b/coverage/tools/BiasRepresentation.cpp.func-sort-c.html @@ -0,0 +1,149 @@ + + + + + + + + LCOV - plumed test coverage - tools/BiasRepresentation.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - BiasRepresentation.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12917075.9 %
Date:2024-04-19 12:12:35Functions:121963.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18BiasRepresentation13getPtrToValueEj0
_ZN4PLMD18BiasRepresentation14getPtrToValuesEv0
_ZN4PLMD18BiasRepresentation16isRescaledToBiasEv0
_ZN4PLMD18BiasRepresentation21getNumberOfDimensionsEv0
_ZN4PLMD18BiasRepresentation5clearEv0
_ZN4PLMD18BiasRepresentation7getNameB5cxx11Ej0
_ZN4PLMD18BiasRepresentation8getNamesB5cxx11Ev0
_ZN4PLMD18BiasRepresentation17setRescaledToBiasEb1
_ZN4PLMD18BiasRepresentationC2ERKSt6vectorIPNS_5ValueESaIS3_EERNS_12CommunicatorERKS1_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISF_EESJ_RKS1_IjSaIjEERKS1_IdSaIdEE1
_ZN4PLMD18BiasRepresentationC2ERKSt6vectorIPNS_5ValueESaIS3_EERNS_12CommunicatorERKS1_IdSaIdEE1
_ZN4PLMD18BiasRepresentationC2ERKSt6vectorIPNS_5ValueESaIS3_EERNS_12CommunicatorE4
_ZN4PLMD18BiasRepresentation12getMinMaxBinERSt6vectorIdSaIdEES4_RS1_IjSaIjEE5
_ZN4PLMD18BiasRepresentationC2ERKSt6vectorIPNS_5ValueESaIS3_EERNS_12CommunicatorERKS1_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISF_EESJ_RKS1_IjSaIjEEbdd8
_ZN4PLMD18BiasRepresentation7addGridERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EESB_RKS1_IjSaIjEE9
_ZN4PLMD18BiasRepresentation10getGridPtrEv10
_ZN4PLMD18BiasRepresentation13readFromPointEPNS_5IFileE1092
_ZN4PLMD18BiasRepresentation10pushKernelEPNS_5IFileE5563
_ZN4PLMD18BiasRepresentation15hasSigmaInInputEv5563
_ZN4PLMD18BiasRepresentation18getNumberOfKernelsEv5578
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/BiasRepresentation.cpp.func.html b/coverage/tools/BiasRepresentation.cpp.func.html new file mode 100644 index 000000000000..b3f6cb587bbf --- /dev/null +++ b/coverage/tools/BiasRepresentation.cpp.func.html @@ -0,0 +1,149 @@ + + + + + + + + LCOV - plumed test coverage - tools/BiasRepresentation.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - BiasRepresentation.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12917075.9 %
Date:2024-04-19 12:12:35Functions:121963.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18BiasRepresentation10getGridPtrEv10
_ZN4PLMD18BiasRepresentation10pushKernelEPNS_5IFileE5563
_ZN4PLMD18BiasRepresentation12getMinMaxBinERSt6vectorIdSaIdEES4_RS1_IjSaIjEE5
_ZN4PLMD18BiasRepresentation13getPtrToValueEj0
_ZN4PLMD18BiasRepresentation13readFromPointEPNS_5IFileE1092
_ZN4PLMD18BiasRepresentation14getPtrToValuesEv0
_ZN4PLMD18BiasRepresentation15hasSigmaInInputEv5563
_ZN4PLMD18BiasRepresentation16isRescaledToBiasEv0
_ZN4PLMD18BiasRepresentation17setRescaledToBiasEb1
_ZN4PLMD18BiasRepresentation18getNumberOfKernelsEv5578
_ZN4PLMD18BiasRepresentation21getNumberOfDimensionsEv0
_ZN4PLMD18BiasRepresentation5clearEv0
_ZN4PLMD18BiasRepresentation7addGridERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EESB_RKS1_IjSaIjEE9
_ZN4PLMD18BiasRepresentation7getNameB5cxx11Ej0
_ZN4PLMD18BiasRepresentation8getNamesB5cxx11Ev0
_ZN4PLMD18BiasRepresentationC2ERKSt6vectorIPNS_5ValueESaIS3_EERNS_12CommunicatorE4
_ZN4PLMD18BiasRepresentationC2ERKSt6vectorIPNS_5ValueESaIS3_EERNS_12CommunicatorERKS1_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISF_EESJ_RKS1_IjSaIjEERKS1_IdSaIdEE1
_ZN4PLMD18BiasRepresentationC2ERKSt6vectorIPNS_5ValueESaIS3_EERNS_12CommunicatorERKS1_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISF_EESJ_RKS1_IjSaIjEEbdd8
_ZN4PLMD18BiasRepresentationC2ERKSt6vectorIPNS_5ValueESaIS3_EERNS_12CommunicatorERKS1_IdSaIdEE1
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/BiasRepresentation.cpp.gcov.html b/coverage/tools/BiasRepresentation.cpp.gcov.html new file mode 100644 index 000000000000..487f4e9f8b1b --- /dev/null +++ b/coverage/tools/BiasRepresentation.cpp.gcov.html @@ -0,0 +1,364 @@ + + + + + + + + LCOV - plumed test coverage - tools/BiasRepresentation.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - BiasRepresentation.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12917075.9 %
Date:2024-04-19 12:12:35Functions:121963.2 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "BiasRepresentation.h"
+      23             : #include "core/Value.h"
+      24             : #include "Communicator.h"
+      25             : #include <iostream>
+      26             : #include "KernelFunctions.h"
+      27             : #include "File.h"
+      28             : #include "Grid.h"
+      29             : 
+      30             : namespace PLMD {
+      31             : 
+      32             : /// the constructor here
+      33           4 : BiasRepresentation::BiasRepresentation(const std::vector<Value*> & tmpvalues, Communicator &cc ):hasgrid(false),rescaledToBias(false),mycomm(cc) {
+      34           4 :   lowI_=0.0;
+      35           4 :   uppI_=0.0;
+      36           4 :   doInt_=false;
+      37           4 :   ndim=tmpvalues.size();
+      38          12 :   for(int i=0; i<ndim; i++) {
+      39           8 :     values.push_back(tmpvalues[i]);
+      40           8 :     names.push_back(values[i]->getName());
+      41             :   }
+      42           4 : }
+      43             : 
+      44             : /// overload the constructor: add the sigma  at constructor time
+      45           1 : BiasRepresentation::BiasRepresentation(const std::vector<Value*> & tmpvalues, Communicator &cc, const std::vector<double> & sigma ):
+      46           1 :   hasgrid(false), rescaledToBias(false), histosigma(sigma),mycomm(cc)
+      47             : {
+      48           1 :   lowI_=0.0;
+      49           1 :   uppI_=0.0;
+      50           1 :   doInt_=false;
+      51           1 :   ndim=tmpvalues.size();
+      52           3 :   for(int i=0; i<ndim; i++) {
+      53           2 :     values.push_back(tmpvalues[i]);
+      54           2 :     names.push_back(values[i]->getName());
+      55             :   }
+      56           1 : }
+      57             : 
+      58             : /// overload the constructor: add the grid at constructor time
+      59           8 : BiasRepresentation::BiasRepresentation(const std::vector<Value*> & tmpvalues, Communicator &cc, const std::vector<std::string> & gmin, const std::vector<std::string> & gmax,
+      60           8 :                                        const std::vector<unsigned> & nbin, bool doInt, double lowI, double uppI):
+      61           8 :   hasgrid(false), rescaledToBias(false), mycomm(cc)
+      62             : {
+      63           8 :   ndim=tmpvalues.size();
+      64          23 :   for(int i=0; i<ndim; i++) {
+      65          15 :     values.push_back(tmpvalues[i]);
+      66          15 :     names.push_back(values[i]->getName());
+      67             :   }
+      68           8 :   doInt_=doInt;
+      69           8 :   lowI_=lowI;
+      70           8 :   uppI_=uppI;
+      71             :   // initialize the grid
+      72           8 :   addGrid(gmin,gmax,nbin);
+      73           8 : }
+      74             : 
+      75             : /// overload the constructor with some external sigmas: needed for histogram
+      76           1 : BiasRepresentation::BiasRepresentation(const std::vector<Value*> & tmpvalues, Communicator &cc, const std::vector<std::string> & gmin, const std::vector<std::string> & gmax,
+      77           1 :                                        const std::vector<unsigned> & nbin, const std::vector<double> & sigma):
+      78           1 :   hasgrid(false), rescaledToBias(false),histosigma(sigma),mycomm(cc)
+      79             : {
+      80           1 :   lowI_=0.0;
+      81           1 :   uppI_=0.0;
+      82           1 :   doInt_=false;
+      83           1 :   ndim=tmpvalues.size();
+      84           3 :   for(int  i=0; i<ndim; i++) {
+      85           2 :     values.push_back(tmpvalues[i]);
+      86           2 :     names.push_back(values[i]->getName());
+      87             :   }
+      88             :   // initialize the grid
+      89           1 :   addGrid(gmin,gmax,nbin);
+      90           1 : }
+      91             : 
+      92           9 : void BiasRepresentation::addGrid(const std::vector<std::string> & gmin, const std::vector<std::string> & gmax, const std::vector<unsigned> & nbin ) {
+      93           9 :   plumed_massert(hills.size()==0,"you can set the grid before loading the hills");
+      94           9 :   plumed_massert(hasgrid==false,"to build the grid you should not having the grid in this bias representation");
+      95             :   std::string ss; ss="file.free";
+      96          26 :   std::vector<Value*> vv; for(unsigned i=0; i<values.size(); i++) vv.push_back(values[i]);
+      97          18 :   BiasGrid_=Tools::make_unique<Grid>(ss,vv,gmin,gmax,nbin,false,true);
+      98           9 :   hasgrid=true;
+      99           9 : }
+     100             : 
+     101        5563 : bool BiasRepresentation::hasSigmaInInput() {
+     102        5563 :   if(histosigma.size()==0) {return false;} else {return true;}
+     103             : }
+     104             : 
+     105           1 : void BiasRepresentation::setRescaledToBias(bool rescaled) {
+     106           1 :   plumed_massert(hills.size()==0,"you can set the rescaling function only before loading hills");
+     107           1 :   rescaledToBias=rescaled;
+     108           1 : }
+     109             : 
+     110           0 : const bool & BiasRepresentation::isRescaledToBias() {
+     111           0 :   return rescaledToBias;
+     112             : }
+     113             : 
+     114           0 : unsigned BiasRepresentation::getNumberOfDimensions() {
+     115           0 :   return values.size();
+     116             : }
+     117             : 
+     118           0 : std::vector<std::string> BiasRepresentation::getNames() {
+     119           0 :   return names;
+     120             : }
+     121             : 
+     122           0 : const std::string & BiasRepresentation::getName(unsigned i) {
+     123           0 :   return names[i];
+     124             : }
+     125             : 
+     126           0 : const std::vector<Value*>& BiasRepresentation::getPtrToValues() {
+     127           0 :   return values;
+     128             : }
+     129             : 
+     130           0 : Value*  BiasRepresentation::getPtrToValue(unsigned i) {
+     131           0 :   return values[i];
+     132             : }
+     133             : 
+     134        1092 : std::unique_ptr<KernelFunctions> BiasRepresentation::readFromPoint(IFile *ifile) {
+     135        1092 :   std::vector<double> cc( names.size() );
+     136        3276 :   for(unsigned i=0; i<names.size(); ++i) {
+     137        2184 :     ifile->scanField(names[i],cc[i]);
+     138             :   }
+     139        1092 :   double h=1.0;
+     140        2184 :   return Tools::make_unique<KernelFunctions>(cc,histosigma,"stretched-gaussian","DIAGONAL",h);
+     141             : }
+     142             : 
+     143        5563 : void BiasRepresentation::pushKernel( IFile *ifile ) {
+     144        5563 :   std::unique_ptr<KernelFunctions> kk;
+     145             :   // here below the reading of the kernel is completely hidden
+     146        5563 :   if(histosigma.size()==0) {
+     147        4471 :     ifile->allowIgnoredFields();
+     148        8942 :     kk=KernelFunctions::read(ifile,true,names);
+     149             :   } else {
+     150             :     // when doing histogram assume gaussian with a given diagonal sigma
+     151             :     // and neglect all the rest
+     152        2184 :     kk=readFromPoint(ifile);
+     153             :   }
+     154             :   // the bias factor is not something about the kernels but
+     155             :   // must be stored to keep the  bias/free energy duality
+     156             :   std::string dummy; double dummyd;
+     157       11126 :   if(ifile->FieldExist("biasf")) {
+     158        5563 :     ifile->scanField("biasf",dummy);
+     159        5563 :     Tools::convert(dummy,dummyd);
+     160           0 :   } else {dummyd=1.0;}
+     161        5563 :   biasf.push_back(dummyd);
+     162             :   // the domain does not pertain to the kernel but to the values here defined
+     163             :   std::string mins,maxs,minv,maxv,mini,maxi; mins="min_"; maxs="max_";
+     164       16688 :   for(int i=0 ; i<ndim; i++) {
+     165       11125 :     if(values[i]->isPeriodic()) {
+     166       22216 :       ifile->scanField(mins+names[i],minv);
+     167       22216 :       ifile->scanField(maxs+names[i],maxv);
+     168             :       // verify that the domain is correct
+     169       11108 :       values[i]->getDomain(mini,maxi);
+     170       11108 :       plumed_massert(mini==minv,"the input periodicity in hills and in value definition does not match"  );
+     171       11108 :       plumed_massert(maxi==maxv,"the input periodicity in hills and in value definition does not match"  );
+     172             :     }
+     173             :   }
+     174             :   // if grid is defined then it should be added on the grid
+     175             :   //cerr<<"now with "<<hills.size()<<endl;
+     176        5563 :   if(hasgrid) {
+     177             :     std::vector<unsigned> nneighb;
+     178        3375 :     if(doInt_&&(kk->getCenter()[0]+kk->getContinuousSupport()[0] > uppI_ || kk->getCenter()[0]-kk->getContinuousSupport()[0] < lowI_ )) {
+     179           0 :       nneighb=BiasGrid_->getNbin();
+     180        6750 :     } else nneighb=kk->getSupport(BiasGrid_->getDx());
+     181        3375 :     std::vector<Grid::index_t> neighbors=BiasGrid_->getNeighbors(kk->getCenter(),nneighb);
+     182        3375 :     std::vector<double> der(ndim);
+     183        3375 :     std::vector<double> xx(ndim);
+     184        3375 :     if(mycomm.Get_size()==1) {
+     185     1027680 :       for(unsigned i=0; i<neighbors.size(); ++i) {
+     186     1024305 :         Grid::index_t ineigh=neighbors[i];
+     187     3072823 :         for(int j=0; j<ndim; ++j) {der[j]=0.0;}
+     188     1024305 :         BiasGrid_->getPoint(ineigh,xx);
+     189             :         // assign xx to a new vector of values
+     190     3072823 :         for(int j=0; j<ndim; ++j) {values[j]->set(xx[j]);}
+     191             :         double bias;
+     192     1024305 :         if(doInt_) bias=kk->evaluate(values,der,true,doInt_,lowI_,uppI_);
+     193     1024305 :         else bias=kk->evaluate(values,der,true);
+     194     1024305 :         if(rescaledToBias) {
+     195       45234 :           double f=(biasf.back()-1.)/(biasf.back());
+     196       45234 :           bias*=f;
+     197      135702 :           for(int j=0; j<ndim; ++j) {der[j]*=f;}
+     198             :         }
+     199     1024305 :         BiasGrid_->addValueAndDerivatives(ineigh,bias,der);
+     200             :       }
+     201             :     } else {
+     202           0 :       unsigned stride=mycomm.Get_size();
+     203           0 :       unsigned rank=mycomm.Get_rank();
+     204           0 :       std::vector<double> allder(ndim*neighbors.size(),0.0);
+     205           0 :       std::vector<double> allbias(neighbors.size(),0.0);
+     206           0 :       std::vector<double> tmpder(ndim);
+     207           0 :       for(unsigned i=rank; i<neighbors.size(); i+=stride) {
+     208           0 :         Grid::index_t ineigh=neighbors[i];
+     209           0 :         BiasGrid_->getPoint(ineigh,xx);
+     210           0 :         for(int j=0; j<ndim; ++j) {values[j]->set(xx[j]);}
+     211           0 :         if(doInt_) allbias[i]=kk->evaluate(values,der,true,doInt_,lowI_,uppI_);
+     212           0 :         else allbias[i]=kk->evaluate(values,der,true);
+     213           0 :         if(rescaledToBias) {
+     214           0 :           double f=(biasf.back()-1.)/(biasf.back());
+     215           0 :           allbias[i]*=f;
+     216           0 :           for(int j=0; j<ndim; ++j) {tmpder[j]*=f;}
+     217             :         }
+     218             :         // this solution with the temporary vector is rather bad, probably better to take
+     219             :         // a pointer of double as it was in old gaussian
+     220           0 :         for(int j=0; j<ndim; ++j) { allder[ndim*i+j]=tmpder[j]; tmpder[j]=0.;}
+     221             :       }
+     222           0 :       mycomm.Sum(allbias);
+     223           0 :       mycomm.Sum(allder);
+     224           0 :       for(unsigned i=0; i<neighbors.size(); ++i) {
+     225           0 :         Grid::index_t ineigh=neighbors[i];
+     226           0 :         for(int j=0; j<ndim; ++j) {der[j]=allder[ndim*i+j];}
+     227           0 :         BiasGrid_->addValueAndDerivatives(ineigh,allbias[i],der);
+     228             :       }
+     229             :     }
+     230             :   }
+     231        5563 :   hills.emplace_back(std::move(kk));
+     232        5563 : }
+     233             : 
+     234        5578 : int BiasRepresentation::getNumberOfKernels() {
+     235        5578 :   return hills.size();
+     236             : }
+     237             : 
+     238          10 : Grid* BiasRepresentation::getGridPtr() {
+     239          10 :   plumed_massert(hasgrid,"if you want the grid pointer then you should have defined a grid before");
+     240          10 :   return BiasGrid_.get();
+     241             : }
+     242             : 
+     243           5 : void BiasRepresentation::getMinMaxBin(std::vector<double> &vmin, std::vector<double> &vmax, std::vector<unsigned> &vbin) {
+     244             :   std::vector<double> ss,cc,binsize;
+     245           5 :   vmin.clear(); vmin.resize(ndim,10.e20);
+     246           5 :   vmax.clear(); vmax.resize(ndim,-10.e20);
+     247           5 :   vbin.clear(); vbin.resize(ndim);
+     248           5 :   binsize.clear(); binsize.resize(ndim,10.e20);
+     249             :   int ndiv=10; // adjustable parameter: division per support
+     250        2193 :   for(unsigned i=0; i<hills.size(); i++) {
+     251        2188 :     if(histosigma.size()!=0) {
+     252         546 :       ss=histosigma;
+     253             :     } else {
+     254        3284 :       ss=hills[i]->getContinuousSupport();
+     255             :     }
+     256        2188 :     cc=hills[i]->getCenter();
+     257        6564 :     for(int j=0; j<ndim; j++) {
+     258        4376 :       double dmin=cc[j]-ss[j];
+     259        4376 :       double dmax=cc[j]+ss[j];
+     260        4376 :       double ddiv=ss[j]/double(ndiv);
+     261        4376 :       if(dmin<vmin[j])vmin[j]=dmin;
+     262        4376 :       if(dmax>vmax[j])vmax[j]=dmax;
+     263        4376 :       if(ddiv<binsize[j])binsize[j]=ddiv;
+     264             :     }
+     265             :   }
+     266          15 :   for(int j=0; j<ndim; j++) {
+     267             :     // reset to periodicity
+     268          10 :     if(values[j]->isPeriodic()) {
+     269             :       double minv,maxv;
+     270           8 :       values[j]->getDomain(minv,maxv);
+     271           8 :       if(minv>vmin[j])vmin[j]=minv;
+     272           8 :       if(maxv<vmax[j])vmax[j]=maxv;
+     273             :     }
+     274          10 :     vbin[j]=static_cast<unsigned>(std::ceil((vmax[j]-vmin[j])/binsize[j]) );
+     275             :   }
+     276           5 : }
+     277             : 
+     278           0 : void BiasRepresentation::clear() {
+     279           0 :   hills.clear();
+     280             :   // clear the grid
+     281           0 :   if(hasgrid) {
+     282           0 :     BiasGrid_->clear();
+     283             :   }
+     284           0 : }
+     285             : 
+     286             : 
+     287             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Brent1DRootSearch.h.func-sort-c.html b/coverage/tools/Brent1DRootSearch.h.func-sort-c.html new file mode 100644 index 000000000000..8e1bc1f54959 --- /dev/null +++ b/coverage/tools/Brent1DRootSearch.h.func-sort-c.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - tools/Brent1DRootSearch.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Brent1DRootSearch.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:383997.4 %
Date:2024-04-19 12:12:35Functions: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_7contour23DistanceFromContourBaseEEEE6searchEMS4_FdRKdE291
_ZN4PLMD17Brent1DRootSearchINS_5F1dimINS_7contour23DistanceFromContourBaseEEEE7bracketERKdS7_MS4_FdS7_E291
_ZN4PLMD17Brent1DRootSearchINS_5F1dimINS_7contour23DistanceFromContourBaseEEEEC2ERKS4_RKd291
_ZN4PLMD17Brent1DRootSearchINS_5F1dimINS_7contour18ContourFindingBaseEEEE6searchEMS4_FdRKdE1896
_ZN4PLMD17Brent1DRootSearchINS_5F1dimINS_7contour18ContourFindingBaseEEEE7bracketERKdS7_MS4_FdS7_E1896
_ZN4PLMD17Brent1DRootSearchINS_5F1dimINS_7contour18ContourFindingBaseEEEEC2ERKS4_RKd1896
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Brent1DRootSearch.h.func.html b/coverage/tools/Brent1DRootSearch.h.func.html new file mode 100644 index 000000000000..ede8c639b07e --- /dev/null +++ b/coverage/tools/Brent1DRootSearch.h.func.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - tools/Brent1DRootSearch.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Brent1DRootSearch.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:383997.4 %
Date:2024-04-19 12:12:35Functions: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_7contour18ContourFindingBaseEEEE6searchEMS4_FdRKdE1896
_ZN4PLMD17Brent1DRootSearchINS_5F1dimINS_7contour18ContourFindingBaseEEEE7bracketERKdS7_MS4_FdS7_E1896
_ZN4PLMD17Brent1DRootSearchINS_5F1dimINS_7contour18ContourFindingBaseEEEEC2ERKS4_RKd1896
_ZN4PLMD17Brent1DRootSearchINS_5F1dimINS_7contour23DistanceFromContourBaseEEEE6searchEMS4_FdRKdE291
_ZN4PLMD17Brent1DRootSearchINS_5F1dimINS_7contour23DistanceFromContourBaseEEEE7bracketERKdS7_MS4_FdS7_E291
_ZN4PLMD17Brent1DRootSearchINS_5F1dimINS_7contour23DistanceFromContourBaseEEEEC2ERKS4_RKd291
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Brent1DRootSearch.h.gcov.html b/coverage/tools/Brent1DRootSearch.h.gcov.html new file mode 100644 index 000000000000..f84052513edf --- /dev/null +++ b/coverage/tools/Brent1DRootSearch.h.gcov.html @@ -0,0 +1,197 @@ + + + + + + + + LCOV - plumed test coverage - tools/Brent1DRootSearch.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Brent1DRootSearch.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:383997.4 %
Date:2024-04-19 12:12:35Functions: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        2187 : 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        2187 :   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        2187 : Brent1DRootSearch<FCLASS>::Brent1DRootSearch( const FCLASS& pf, const double& t ):
+      64        2187 :   bracketed(false),
+      65        2187 :   tol(t),
+      66        2187 :   ITMAX(100),
+      67        2187 :   EPS(3.0E-8),
+      68        2187 :   EXPAND(1.6),
+      69        2187 :   ax(0), bx(0),
+      70        2187 :   fa(0), fb(0),
+      71        2187 :   myclass_func(pf)
+      72             : {
+      73        2187 : }
+      74             : 
+      75             : template <class FCLASS>
+      76        2187 : void Brent1DRootSearch<FCLASS>::bracket( const double& a, const double& b, eng_pointer eng ) {
+      77        2187 :   plumed_assert( a!=b ); ax=a; bx=b; fa=(myclass_func.*eng)(a); fb=(myclass_func.*eng)(b);
+      78        2187 :   if ((fa > 0.0 && fb > 0.0) || (fa < 0.0 && fb < 0.0)) plumed_merror("input points do not bracket root");
+      79        2187 :   bracketed=true;
+      80        2187 : }
+      81             : 
+      82             : template <class FCLASS>
+      83        2187 : double Brent1DRootSearch<FCLASS>::search( eng_pointer eng ) {
+      84             :   plumed_dbg_assert( bracketed );
+      85             : 
+      86        2187 :   double cx=bx, d, e, min1, min2, fc=fb, p, q, r, s, tol1, xm;
+      87       13534 :   for(unsigned iter=0; iter<ITMAX; iter++) {
+      88       13534 :     if ( (fb>0.0 && fc>0.0) || (fb<0.0 && fc<0.0) ) { cx=ax; fc=fa; e=d=bx-ax; }
+      89       13534 :     if( std::fabs(fc) < std::fabs(fb) ) { ax=bx; bx=cx; cx=ax; fa=fb; fb=fc; fc=fa; }
+      90       13534 :     tol1=2*EPS*std::fabs(bx)+0.5*tol; xm=0.5*(cx-bx);
+      91       13534 :     if( std::fabs(xm) <= tol1 || fb == 0.0 ) return bx;
+      92       11347 :     if( std::fabs(e) >= tol1 && std::fabs(fa) > std::fabs(fb) ) {
+      93       11219 :       s=fb/fa;
+      94       11219 :       if( ax==cx ) {
+      95        7754 :         p=2.0*xm*s; q=1.0-s;
+      96             :       } else {
+      97        3465 :         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       11219 :       if (p > 0.0) q = -q;
+     100       11219 :       p=std::fabs(p); min1=3.0*xm*q-std::fabs(tol1*q); min2=std::fabs(e*q);
+     101       21784 :       if (2.0*p < (min1 < min2 ? min1 : min2)) {
+     102       10537 :         e=d; d=p/q;
+     103             :       } else {
+     104             :         d=xm; e=d;
+     105             :       }
+     106             :     } else {
+     107             :       d=xm; e=d;
+     108             :     }
+     109       11347 :     ax=bx; fa=fb;
+     110       11347 :     if( std::fabs(d) > tol1 ) bx+=d;
+     111        2047 :     else if(xm<0 ) bx -= std::fabs(tol1); // SIGN(tol1,xm);
+     112        1031 :     else bx += tol1;
+     113       11347 :     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/CheckInRange.cpp.func-sort-c.html b/coverage/tools/CheckInRange.cpp.func-sort-c.html new file mode 100644 index 000000000000..caa961115927 --- /dev/null +++ b/coverage/tools/CheckInRange.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - tools/CheckInRange.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - CheckInRange.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:314077.5 %
Date:2024-04-19 12:12:35Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD12CheckInRange6reportERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EE17
_ZN4PLMD12CheckInRange9setBoundsERKjRKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EESD_RS9_43
_ZNK4PLMD12CheckInRange7wereSetEv43
_ZNK4PLMD12CheckInRange5checkERKSt6vectorIdSaIdEE139082
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/CheckInRange.cpp.func.html b/coverage/tools/CheckInRange.cpp.func.html new file mode 100644 index 000000000000..c2e54a891307 --- /dev/null +++ b/coverage/tools/CheckInRange.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - tools/CheckInRange.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - CheckInRange.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:314077.5 %
Date:2024-04-19 12:12:35Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12CheckInRange9setBoundsERKjRKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EESD_RS9_43
_ZNK4PLMD12CheckInRange5checkERKSt6vectorIdSaIdEE139082
_ZNK4PLMD12CheckInRange6reportERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EE17
_ZNK4PLMD12CheckInRange7wereSetEv43
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/CheckInRange.cpp.gcov.html b/coverage/tools/CheckInRange.cpp.gcov.html new file mode 100644 index 000000000000..afcefd7a918b --- /dev/null +++ b/coverage/tools/CheckInRange.cpp.gcov.html @@ -0,0 +1,165 @@ + + + + + + + + LCOV - plumed test coverage - tools/CheckInRange.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - CheckInRange.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:314077.5 %
Date:2024-04-19 12:12:35Functions: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             : #include "CheckInRange.h"
+      23             : #include "Tools.h"
+      24             : 
+      25             : namespace PLMD {
+      26             : 
+      27          43 : bool CheckInRange::setBounds( const unsigned& n, const std::vector<std::string>& str_lower, const std::vector<std::string>& str_upper, std::string& errors ) {
+      28          43 :   if( str_upper.size()!=n && str_upper.size()>0 ) { errors="wrong number of arguments for LESS_THAN_OR_EQUAL keyword"; return false; }
+      29          43 :   if( str_lower.size()!=n && str_lower.size()>0 ) { errors="wrong number of arguments for GREATER_THAN_OR_EQUAL keyword"; return false; }
+      30          43 :   if( str_upper.size()>0 && str_lower.size()>0 ) {
+      31          14 :     lower.resize( str_lower.size() ); upper.resize( str_upper.size() );
+      32          28 :     for(unsigned i=0; i<upper.size(); ++i) {
+      33          14 :       if( str_lower[i]=="none" ) lower[i] = -std::numeric_limits<double>::max();
+      34          14 :       else Tools::convert( str_lower[i], lower[i] );
+      35          14 :       if( str_upper[i]=="none" ) upper[i] = std::numeric_limits<double>::max();
+      36          14 :       else Tools::convert( str_upper[i], upper[i] );
+      37             :     }
+      38          29 :   } else if( str_upper.size()>0 ) {
+      39           0 :     upper.resize( str_upper.size() );
+      40           0 :     for(unsigned i=0; i<upper.size(); ++i) {
+      41           0 :       if( str_upper[i]=="none" ) upper[i] = std::numeric_limits<double>::max();
+      42           0 :       else Tools::convert( str_upper[i], upper[i] );
+      43             :     }
+      44          29 :   } else if( str_lower.size()>0 ) {
+      45           3 :     lower.resize( str_lower.size() );
+      46           6 :     for(unsigned i=0; i<lower.size(); ++i) {
+      47           3 :       if( str_lower[i]=="none" ) lower[i] = -std::numeric_limits<double>::max();
+      48           3 :       else Tools::convert( str_lower[i], lower[i] );
+      49             :     }
+      50             :   }
+      51             :   return true;
+      52             : }
+      53             : 
+      54          43 : bool CheckInRange::wereSet() const {
+      55          43 :   return lower.size()>0 || upper.size()>0;
+      56             : }
+      57             : 
+      58          17 : std::string CheckInRange::report( const std::vector<std::string>& a ) const {
+      59          17 :   if( upper.size()>0 && lower.size()>0 ) {
+      60          14 :     std::string str_l, str_u; Tools::convert( upper[0], str_u ); Tools::convert( lower[0], str_l );
+      61          28 :     std::string out="only printing indices of atoms that have " + str_l + " <= " + a[0] + " <=" + str_u;
+      62          14 :     for(unsigned i=1; i<upper.size(); ++i) {
+      63           0 :       Tools::convert( upper[i], str_u ); Tools::convert( lower[i], str_l );
+      64           0 :       out += " and " + str_l + " <= " + a[i] + " <=" + str_u;
+      65             :     }
+      66             :     return out;
+      67             :   }
+      68           3 :   if( upper.size()>0 ) {
+      69           0 :     std::string str_u; Tools::convert( upper[0], str_u );
+      70           0 :     std::string out="only printing indices of atoms that have " + a[0] + " <= " + str_u;
+      71           0 :     for(unsigned i=1; i<upper.size(); ++i) { Tools::convert( upper[i], str_u ); out += " and " + a[i] + " <= " + str_u; }
+      72             :     return out;
+      73             :   }
+      74           3 :   std::string str_l; Tools::convert( lower[0], str_l );
+      75           6 :   std::string out="only printing indices of atoms that have " + str_l + " <= " + a[0];
+      76           3 :   for(unsigned i=1; i<lower.size(); ++i) { Tools::convert( lower[i], str_l ); out += " and " + str_l + " <= " + a[i]; }
+      77             :   return out;
+      78             : }
+      79             : 
+      80      139082 : bool CheckInRange::check( const std::vector<double>& vals ) const {
+      81      191430 :   for(unsigned j=0; j<vals.size(); ++j) {
+      82       67788 :     if( upper.size()>0 && vals[j]>upper[j] ) return false;
+      83       58176 :     if( lower.size()>0 && vals[j]<lower[j] ) return false;
+      84             :   }
+      85             :   return true;
+      86             : }
+      87             : 
+      88             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/CheckInRange.h.func-sort-c.html b/coverage/tools/CheckInRange.h.func-sort-c.html new file mode 100644 index 000000000000..b1cb085b2179 --- /dev/null +++ b/coverage/tools/CheckInRange.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage - tools/CheckInRange.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - CheckInRange.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-04-19 12:12:35Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/CheckInRange.h.func.html b/coverage/tools/CheckInRange.h.func.html new file mode 100644 index 000000000000..f6e5f52f9a05 --- /dev/null +++ b/coverage/tools/CheckInRange.h.func.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage - tools/CheckInRange.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - CheckInRange.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-04-19 12:12:35Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/CheckInRange.h.gcov.html b/coverage/tools/CheckInRange.h.gcov.html new file mode 100644 index 000000000000..ed04cb0fea95 --- /dev/null +++ b/coverage/tools/CheckInRange.h.gcov.html @@ -0,0 +1,121 @@ + + + + + + + + LCOV - plumed test coverage - tools/CheckInRange.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - CheckInRange.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-04-19 12:12:35Functions: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_CheckInRange_h
+      23             : #define __PLUMED_tools_CheckInRange_h
+      24             : 
+      25             : #include <vector>
+      26             : #include <string>
+      27             : 
+      28             : namespace PLMD {
+      29             : 
+      30             : /// \ingroup TOOLBOX
+      31         209 : class CheckInRange {
+      32             : private:
+      33             :   std::vector<double> lower;
+      34             :   std::vector<double> upper;
+      35             : public:
+      36             :   bool setBounds( const unsigned& n, const std::vector<std::string>& str_lower, const std::vector<std::string>& str_upper, std::string& errors );
+      37             :   bool wereSet() const ;
+      38             :   std::string report( const std::vector<std::string>& a ) const ;
+      39             :   bool check( const std::vector<double>& vals ) const ;
+      40             : };
+      41             : 
+      42             : }
+      43             : 
+      44             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Citations.cpp.func-sort-c.html b/coverage/tools/Citations.cpp.func-sort-c.html new file mode 100644 index 000000000000..47ad07e8cd3b --- /dev/null +++ b/coverage/tools/Citations.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - tools/Citations.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Citations.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1616100.0 %
Date:2024-04-19 12:12:35Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMDlsERSoRKNS_9CitationsE1663
_ZN4PLMD9Citations4citeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE4420
_ZNK4PLMD9Citations5emptyEv31439
_ZN4PLMD9Citations5clearEv31494
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Citations.cpp.func.html b/coverage/tools/Citations.cpp.func.html new file mode 100644 index 000000000000..063c1fc8d62a --- /dev/null +++ b/coverage/tools/Citations.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - tools/Citations.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Citations.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1616100.0 %
Date:2024-04-19 12:12:35Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9Citations4citeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE4420
_ZN4PLMD9Citations5clearEv31494
_ZN4PLMDlsERSoRKNS_9CitationsE1663
_ZNK4PLMD9Citations5emptyEv31439
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Citations.cpp.gcov.html b/coverage/tools/Citations.cpp.gcov.html new file mode 100644 index 000000000000..1a569d430b0f --- /dev/null +++ b/coverage/tools/Citations.cpp.gcov.html @@ -0,0 +1,133 @@ + + + + + + + + LCOV - plumed test coverage - tools/Citations.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Citations.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1616100.0 %
Date:2024-04-19 12:12:35Functions: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        4420 : std::string Citations::cite(const std::string & item) {
+      30             :   unsigned i;
+      31        8481 :   for(i=0; i<items.size(); ++i) if(items[i]==item) break;
+      32        4420 :   if(i==items.size()) items.push_back(item);
+      33        4420 :   plumed_assert(i<items.size());
+      34             :   std::string ret;
+      35        4420 :   Tools::convert(i+1,ret);
+      36        8840 :   ret="["+ret+"]";
+      37        4420 :   return ret;
+      38             : }
+      39             : 
+      40        1663 : std::ostream & operator<<(std::ostream &log,const Citations&cit) {
+      41        4068 :   for(unsigned i=0; i<cit.items.size(); ++i)
+      42        4810 :     log<<"  ["<<i+1<<"] "<<cit.items[i]<<"\n";
+      43        1663 :   return log;
+      44             : }
+      45             : 
+      46       31494 : void Citations::clear() {
+      47       31494 :   items.clear();
+      48       31494 : }
+      49             : 
+      50       31439 : bool Citations::empty()const {
+      51       31439 :   return items.empty();
+      52             : }
+      53             : 
+      54             : }
+      55             : 
+      56             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Citations.h.func-sort-c.html b/coverage/tools/Citations.h.func-sort-c.html new file mode 100644 index 000000000000..503a13284144 --- /dev/null +++ b/coverage/tools/Citations.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage - tools/Citations.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Citations.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-04-19 12:12:35Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Citations.h.func.html b/coverage/tools/Citations.h.func.html new file mode 100644 index 000000000000..c9d9140bfc07 --- /dev/null +++ b/coverage/tools/Citations.h.func.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage - tools/Citations.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Citations.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-04-19 12:12:35Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Citations.h.gcov.html b/coverage/tools/Citations.h.gcov.html new file mode 100644 index 000000000000..4e45881cb064 --- /dev/null +++ b/coverage/tools/Citations.h.gcov.html @@ -0,0 +1,151 @@ + + + + + + + + LCOV - plumed test coverage - tools/Citations.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Citations.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-04-19 12:12:35Functions: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      806370 : class Citations {
+      55             :   std::vector<std::string> items;
+      56             : public:
+      57             : /// Add a citation.
+      58             : /// It returns a string containing the reference number, something like "[10]"
+      59             :   std::string cite(const std::string &);
+      60             : /// Dumps the bibliography.
+      61             : /// It writes on the ostream the list of all the bibliographic items
+      62             : /// prefixed with their reference number
+      63             :   friend std::ostream &operator<<(std::ostream &,const Citations&);
+      64             : /// Delete all references
+      65             :   void clear();
+      66             : /// Check if bibliography is empty
+      67             :   bool empty()const;
+      68             : };
+      69             : 
+      70             : std::ostream & operator<<(std::ostream &,const Citations&);
+      71             : 
+      72             : }
+      73             : 
+      74             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Communicator.cpp.func-sort-c.html b/coverage/tools/Communicator.cpp.func-sort-c.html new file mode 100644 index 000000000000..c0c5b6c1b544 --- /dev/null +++ b/coverage/tools/Communicator.cpp.func-sort-c.html @@ -0,0 +1,217 @@ + + + + + + + + LCOV - plumed test coverage - tools/Communicator.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Communicator.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10212283.6 %
Date:2024-04-19 12:12:35Functions:303683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12Communicator10getMPITypeIeEEP15ompi_datatype_tv0
_ZN4PLMD12Communicator10getMPITypeIfEEP15ompi_datatype_tv0
_ZN4PLMD12Communicator5AbortEi0
_ZN4PLMD12Communicator9Set_fcommERKNS_11TypesafePtrE0
_ZN4PLMD12CommunicatorC2ERKS0_0
_ZN4PLMD12CommunicatoraSERKS0_0
_ZN4PLMD12Communicator3MinENS0_4DataE3
_ZN4PLMD12Communicator4ProdENS0_4DataE3
_ZN4PLMD12Communicator10getMPITypeIyEEP15ompi_datatype_tv6
_ZN4PLMD12Communicator10getMPITypeINS_10AtomNumberEEEP15ompi_datatype_tv8
_ZN4PLMD12Communicator12plumedHasMPIEv54
_ZN4PLMD12Communicator3MaxENS0_4DataE155
_ZN4PLMD12Communicator10getMPITypeIcEEP15ompi_datatype_tv295
_ZNK4PLMD12Communicator5SplitEiiRS0_406
_ZN4PLMD12Communicator8Set_commERKNS_11TypesafePtrE1211
_ZN4PLMD12Communicator8Get_commEv1841
_ZN4PLMD12Communicator8Set_commEP19ompi_communicator_t2345
_ZN4PLMD12Communicator9AllgatherENS0_9ConstDataENS0_4DataE5850
_ZNK4PLMD12Communicator6Status9Get_countEP15ompi_datatype_t7587
_ZN4PLMD12Communicator7Request4waitERNS0_6StatusE14898
_ZN4PLMD12Communicator4RecvENS0_4DataEiiRNS0_6StatusE15298
_ZN4PLMD12Communicator5IsendENS0_9ConstDataEii15298
_ZN4PLMD12Communicator10AllgathervENS0_9ConstDataENS0_4DataEPKiS4_19063
_ZN4PLMD12Communicator10getMPITypeIjEEP15ompi_datatype_tv79540
_ZN4PLMD12Communicator10getMPITypeIiEEP15ompi_datatype_tv96336
_ZN4PLMD12CommunicatorD0Ev1618288
_ZN4PLMD12CommunicatorC2Ev1621376
_ZN4PLMD12CommunicatorD2Ev1621376
_ZNK4PLMD12Communicator8Get_sizeEv2971228
_ZN4PLMD12Communicator3SumENS0_4DataE4530796
_ZN4PLMD12Communicator10getMPITypeIdEEP15ompi_datatype_tv4774303
_ZN4PLMD12Communicator10getMPITypeImEEP15ompi_datatype_tv4868719
_ZNK4PLMD12Communicator7BarrierEv4874511
_ZN4PLMD12Communicator5BcastENS0_4DataEi5200241
_ZNK4PLMD12Communicator8Get_rankEv7433494
_ZN4PLMD12Communicator11initializedEv26719595
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Communicator.cpp.func.html b/coverage/tools/Communicator.cpp.func.html new file mode 100644 index 000000000000..269a6566e10c --- /dev/null +++ b/coverage/tools/Communicator.cpp.func.html @@ -0,0 +1,217 @@ + + + + + + + + LCOV - plumed test coverage - tools/Communicator.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Communicator.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10212283.6 %
Date:2024-04-19 12:12:35Functions:303683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12Communicator10AllgathervENS0_9ConstDataENS0_4DataEPKiS4_19063
_ZN4PLMD12Communicator10getMPITypeINS_10AtomNumberEEEP15ompi_datatype_tv8
_ZN4PLMD12Communicator10getMPITypeIcEEP15ompi_datatype_tv295
_ZN4PLMD12Communicator10getMPITypeIdEEP15ompi_datatype_tv4774303
_ZN4PLMD12Communicator10getMPITypeIeEEP15ompi_datatype_tv0
_ZN4PLMD12Communicator10getMPITypeIfEEP15ompi_datatype_tv0
_ZN4PLMD12Communicator10getMPITypeIiEEP15ompi_datatype_tv96336
_ZN4PLMD12Communicator10getMPITypeIjEEP15ompi_datatype_tv79540
_ZN4PLMD12Communicator10getMPITypeImEEP15ompi_datatype_tv4868719
_ZN4PLMD12Communicator10getMPITypeIyEEP15ompi_datatype_tv6
_ZN4PLMD12Communicator11initializedEv26719595
_ZN4PLMD12Communicator12plumedHasMPIEv54
_ZN4PLMD12Communicator3MaxENS0_4DataE155
_ZN4PLMD12Communicator3MinENS0_4DataE3
_ZN4PLMD12Communicator3SumENS0_4DataE4530796
_ZN4PLMD12Communicator4ProdENS0_4DataE3
_ZN4PLMD12Communicator4RecvENS0_4DataEiiRNS0_6StatusE15298
_ZN4PLMD12Communicator5AbortEi0
_ZN4PLMD12Communicator5BcastENS0_4DataEi5200241
_ZN4PLMD12Communicator5IsendENS0_9ConstDataEii15298
_ZN4PLMD12Communicator7Request4waitERNS0_6StatusE14898
_ZN4PLMD12Communicator8Get_commEv1841
_ZN4PLMD12Communicator8Set_commEP19ompi_communicator_t2345
_ZN4PLMD12Communicator8Set_commERKNS_11TypesafePtrE1211
_ZN4PLMD12Communicator9AllgatherENS0_9ConstDataENS0_4DataE5850
_ZN4PLMD12Communicator9Set_fcommERKNS_11TypesafePtrE0
_ZN4PLMD12CommunicatorC2ERKS0_0
_ZN4PLMD12CommunicatorC2Ev1621376
_ZN4PLMD12CommunicatorD0Ev1618288
_ZN4PLMD12CommunicatorD2Ev1621376
_ZN4PLMD12CommunicatoraSERKS0_0
_ZNK4PLMD12Communicator5SplitEiiRS0_406
_ZNK4PLMD12Communicator6Status9Get_countEP15ompi_datatype_t7587
_ZNK4PLMD12Communicator7BarrierEv4874511
_ZNK4PLMD12Communicator8Get_rankEv7433494
_ZNK4PLMD12Communicator8Get_sizeEv2971228
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Communicator.cpp.gcov.html b/coverage/tools/Communicator.cpp.gcov.html new file mode 100644 index 000000000000..4437c6401a54 --- /dev/null +++ b/coverage/tools/Communicator.cpp.gcov.html @@ -0,0 +1,395 @@ + + + + + + + + LCOV - plumed test coverage - tools/Communicator.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Communicator.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10212283.6 %
Date:2024-04-19 12:12:35Functions: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     1621376 : Communicator::Communicator()
+      40             : #ifdef __PLUMED_HAS_MPI
+      41     1621376 :   : communicator(MPI_COMM_SELF)
+      42             : #endif
+      43             : {
+      44     1621376 : }
+      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     7433494 : int Communicator::Get_rank()const {
+      60     7433494 :   int r=0;
+      61             : #ifdef __PLUMED_HAS_MPI
+      62     7433494 :   if(initialized()) MPI_Comm_rank(communicator,&r);
+      63             : #endif
+      64     7433494 :   return r;
+      65             : }
+      66             : 
+      67     2971228 : int Communicator::Get_size()const {
+      68     2971228 :   int s=1;
+      69             : #ifdef __PLUMED_HAS_MPI
+      70     2971228 :   if(initialized()) MPI_Comm_size(communicator,&s);
+      71             : #endif
+      72     2971228 :   return s;
+      73             : }
+      74             : 
+      75        2345 : void Communicator::Set_comm(MPI_Comm c) {
+      76             : #ifdef __PLUMED_HAS_MPI
+      77        2345 :   if(initialized()) {
+      78        1737 :     if(communicator!=MPI_COMM_SELF && communicator!=MPI_COMM_WORLD) MPI_Comm_free(&communicator);
+      79        1737 :     if(c!=MPI_COMM_SELF) MPI_Comm_dup(c,&communicator);
+      80             :   }
+      81             : #else
+      82             :   (void) c;
+      83             : #endif
+      84        2345 : }
+      85             : 
+      86     3239664 : Communicator::~Communicator() {
+      87             : #ifdef __PLUMED_HAS_MPI
+      88     1621376 :   if(initialized() && communicator!=MPI_COMM_SELF && communicator!=MPI_COMM_WORLD) MPI_Comm_free(&communicator);
+      89             : #endif
+      90     3239664 : }
+      91             : 
+      92        1211 : void Communicator::Set_comm(const TypesafePtr & val) {
+      93             : #ifdef __PLUMED_HAS_MPI
+      94        1211 :   plumed_massert(initialized(),"you are trying to use an MPI function, but MPI is not initialized");
+      95        2422 :   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        1211 : }
+     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     5200241 : void Communicator::Bcast(Data data,int root) {
+     126             : #if defined(__PLUMED_HAS_MPI)
+     127     5200241 :   if(initialized()) MPI_Bcast(data.pointer,data.size,data.type,root,communicator);
+     128             : #else
+     129             :   (void) data;
+     130             :   (void) root;
+     131             : #endif
+     132     5200241 : }
+     133             : 
+     134     4530796 : void Communicator::Sum(Data data) {
+     135             : #if defined(__PLUMED_HAS_MPI)
+     136     4530796 :   if(initialized()) MPI_Allreduce(MPI_IN_PLACE,data.pointer,data.size,data.type,MPI_SUM,communicator);
+     137             : #else
+     138             :   (void) data;
+     139             : #endif
+     140     4530796 : }
+     141             : 
+     142           3 : void Communicator::Prod(Data data) {
+     143             : #if defined(__PLUMED_HAS_MPI)
+     144           3 :   if(initialized()) MPI_Allreduce(MPI_IN_PLACE,data.pointer,data.size,data.type,MPI_PROD,communicator);
+     145             : #else
+     146             :   (void) data;
+     147             : #endif
+     148           3 : }
+     149             : 
+     150         155 : void Communicator::Max(Data data) {
+     151             : #if defined(__PLUMED_HAS_MPI)
+     152         155 :   if(initialized()) MPI_Allreduce(MPI_IN_PLACE,data.pointer,data.size,data.type,MPI_MAX,communicator);
+     153             : #else
+     154             :   (void) data;
+     155             : #endif
+     156         155 : }
+     157             : 
+     158           3 : void Communicator::Min(Data data) {
+     159             : #if defined(__PLUMED_HAS_MPI)
+     160           3 :   if(initialized()) MPI_Allreduce(MPI_IN_PLACE,data.pointer,data.size,data.type,MPI_MIN,communicator);
+     161             : #else
+     162             :   (void) data;
+     163             : #endif
+     164           3 : }
+     165             : 
+     166       15298 : Communicator::Request Communicator::Isend(ConstData data,int source,int tag) {
+     167             :   Request req;
+     168             : #ifdef __PLUMED_HAS_MPI
+     169       15298 :   plumed_massert(initialized(),"you are trying to use an MPI function, but MPI is not initialized");
+     170       15298 :   void*s=const_cast<void*>((const void*)data.pointer);
+     171       15298 :   MPI_Isend(s,data.size,data.type,source,tag,communicator,&req.r);
+     172             : #else
+     173             :   (void) data;
+     174             :   (void) source;
+     175             :   (void) tag;
+     176             :   plumed_merror("you are trying to use an MPI function, but PLUMED has been compiled without MPI support");
+     177             : #endif
+     178       15298 :   return req;
+     179             : }
+     180             : 
+     181       19063 : void Communicator::Allgatherv(ConstData in,Data out,const int*recvcounts,const int*displs) {
+     182       19063 :   void*s=const_cast<void*>((const void*)in.pointer);
+     183       19063 :   void*r=const_cast<void*>((const void*)out.pointer);
+     184             :   int*rc=const_cast<int*>(recvcounts);
+     185             :   int*di=const_cast<int*>(displs);
+     186             : #if defined(__PLUMED_HAS_MPI)
+     187       19063 :   if(initialized()) {
+     188       19062 :     if(s==NULL)s=MPI_IN_PLACE;
+     189       19062 :     MPI_Allgatherv(s,in.size,in.type,r,rc,di,out.type,communicator);
+     190             :   } else {
+     191           1 :     plumed_assert(in.nbytes==out.nbytes);
+     192           1 :     plumed_assert(in.size==out.size);
+     193           1 :     plumed_assert(rc);
+     194           1 :     plumed_assert(rc[0]==in.size);
+     195           1 :     plumed_assert(di);
+     196           1 :     if(s) std::memcpy(static_cast<char*>(r)+displs[0]*in.nbytes,s,size_t(in.size)*in.nbytes);
+     197             :   }
+     198             : #else
+     199             :   plumed_assert(in.nbytes==out.nbytes);
+     200             :   plumed_assert(in.size==out.size);
+     201             :   plumed_assert(rc);
+     202             :   plumed_assert(rc[0]==in.size);
+     203             :   plumed_assert(di);
+     204             :   if(s) std::memcpy(static_cast<char*>(r)+displs[0]*in.nbytes,s,size_t(in.size)*in.nbytes);
+     205             : #endif
+     206       19063 : }
+     207             : 
+     208        5850 : void Communicator::Allgather(ConstData in,Data out) {
+     209        5850 :   void*s=const_cast<void*>((const void*)in.pointer);
+     210        5850 :   void*r=const_cast<void*>((const void*)out.pointer);
+     211             : #if defined(__PLUMED_HAS_MPI)
+     212        5850 :   if(initialized()) {
+     213        5849 :     if(s==NULL)s=MPI_IN_PLACE;
+     214        5849 :     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        5850 : }
+     226             : 
+     227       15298 : void Communicator::Recv(Data data,int source,int tag,Status&status) {
+     228             : #ifdef __PLUMED_HAS_MPI
+     229       15298 :   plumed_massert(initialized(),"you are trying to use an MPI function, but MPI is not initialized");
+     230       15298 :   if(&status==&StatusIgnore) MPI_Recv(data.pointer,data.size,data.type,source,tag,communicator,MPI_STATUS_IGNORE);
+     231        7587 :   else                       MPI_Recv(data.pointer,data.size,data.type,source,tag,communicator,&status.s);
+     232             : #else
+     233             :   (void) data;
+     234             :   (void) source;
+     235             :   (void) tag;
+     236             :   (void) status;
+     237             :   plumed_merror("you are trying to use an MPI function, but PLUMED has been compiled without MPI support");
+     238             : #endif
+     239       15298 : }
+     240             : 
+     241     4874511 : void Communicator::Barrier()const {
+     242             : #ifdef __PLUMED_HAS_MPI
+     243     4874511 :   if(initialized()) MPI_Barrier(communicator);
+     244             : #endif
+     245     4874511 : }
+     246             : 
+     247        1841 : MPI_Comm & Communicator::Get_comm() {
+     248        1841 :   return communicator;
+     249             : }
+     250             : 
+     251    26719595 : bool Communicator::initialized() {
+     252             : #if defined(__PLUMED_HAS_MPI)
+     253    26719595 :   int flag=0;
+     254    26719595 :   MPI_Initialized(&flag);
+     255    26719595 :   if(flag) return true;
+     256    17330817 :   else return false;
+     257             : #endif
+     258             :   return false;
+     259             : }
+     260             : 
+     261       14898 : void Communicator::Request::wait(Status&s) {
+     262             : #ifdef __PLUMED_HAS_MPI
+     263       14898 :   plumed_massert(initialized(),"you are trying to use an MPI function, but MPI is not initialized");
+     264       14898 :   if(&s==&StatusIgnore) MPI_Wait(&r,MPI_STATUS_IGNORE);
+     265           1 :   else MPI_Wait(&r,&s.s);
+     266             : #else
+     267             :   (void) s;
+     268             :   plumed_merror("you are trying to use an MPI function, but PLUMED has been compiled without MPI support");
+     269             : #endif
+     270       14898 : }
+     271             : 
+     272             : #ifdef __PLUMED_HAS_MPI
+     273           0 : template<> MPI_Datatype Communicator::getMPIType<float>() { return MPI_FLOAT;}
+     274     4774303 : template<> MPI_Datatype Communicator::getMPIType<double>() { return MPI_DOUBLE;}
+     275       96336 : template<> MPI_Datatype Communicator::getMPIType<int>()   { return MPI_INT;}
+     276         295 : template<> MPI_Datatype Communicator::getMPIType<char>()   { return MPI_CHAR;}
+     277       79540 : template<> MPI_Datatype Communicator::getMPIType<unsigned>()   { return MPI_UNSIGNED;}
+     278           8 : template<> MPI_Datatype Communicator::getMPIType<AtomNumber>()   { return MPI_UNSIGNED;}
+     279     4868719 : template<> MPI_Datatype Communicator::getMPIType<long unsigned>()   { return MPI_UNSIGNED_LONG;}
+     280           6 : template<> MPI_Datatype Communicator::getMPIType<long long unsigned>() { return MPI_UNSIGNED_LONG_LONG;}
+     281           0 : template<> MPI_Datatype Communicator::getMPIType<long double>()   { return MPI_LONG_DOUBLE;}
+     282             : #else
+     283             : template<> MPI_Datatype Communicator::getMPIType<float>() { return MPI_Datatype();}
+     284             : template<> MPI_Datatype Communicator::getMPIType<double>() { return MPI_Datatype();}
+     285             : template<> MPI_Datatype Communicator::getMPIType<int>() { return MPI_Datatype();}
+     286             : template<> MPI_Datatype Communicator::getMPIType<char>() { return MPI_Datatype();}
+     287             : template<> MPI_Datatype Communicator::getMPIType<unsigned>() { return MPI_Datatype();}
+     288             : template<> MPI_Datatype Communicator::getMPIType<AtomNumber>()   { return MPI_Datatype();}
+     289             : template<> MPI_Datatype Communicator::getMPIType<long unsigned>() { return MPI_Datatype();}
+     290             : template<> MPI_Datatype Communicator::getMPIType<long long unsigned>() { return MPI_Datatype();}
+     291             : template<> MPI_Datatype Communicator::getMPIType<long double>() { return MPI_Datatype();}
+     292             : #endif
+     293             : 
+     294         406 : void Communicator::Split(int color,int key,Communicator&pc)const {
+     295             : #ifdef __PLUMED_HAS_MPI
+     296         406 :   MPI_Comm_split(communicator,color,key,&pc.communicator);
+     297             : #else
+     298             :   (void) color;
+     299             :   (void) key;
+     300             :   (void) pc;
+     301             :   plumed_merror("you are trying to use an MPI function, but PLUMED has been compiled without MPI support");
+     302             : #endif
+     303         406 : }
+     304             : 
+     305        7587 : int Communicator::Status::Get_count(MPI_Datatype type)const {
+     306             :   int i;
+     307             : #ifdef __PLUMED_HAS_MPI
+     308        7587 :   plumed_massert(initialized(),"you are trying to use an MPI function, but MPI is not initialized");
+     309        7587 :   MPI_Get_count(const_cast<MPI_Status*>(&s),type,&i);
+     310             : #else
+     311             :   i=0;
+     312             :   plumed_merror("you are trying to use an MPI function, but PLUMED has been compiled without MPI support");
+     313             : #endif
+     314        7587 :   return i;
+     315             : }
+     316             : 
+     317             : }
+     318             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Communicator.h.func-sort-c.html b/coverage/tools/Communicator.h.func-sort-c.html new file mode 100644 index 000000000000..3cd28eaa10c0 --- /dev/null +++ b/coverage/tools/Communicator.h.func-sort-c.html @@ -0,0 +1,313 @@ + + + + + + + + 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:404393.0 %
Date:2024-04-19 12:12:35Functions:566093.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12Communicator3MinIdEEvRT_0
_ZN4PLMD12Communicator3SumISt6vectorIfSaIfEEEEvRT_0
_ZN4PLMD12Communicator4DataC2IfEERSt6vectorIT_SaIS4_EE0
_ZN4PLMD12Communicator5BcastISt6vectorIfSaIfEEEEvRT_i0
_ZN4PLMD12Communicator10AllgathervISt6vectorIdSaIdEES4_EEvRKT_RT0_PKiSB_2
_ZN4PLMD12Communicator5BcastISt6vectorIySaIyEEEEvRT_i2
_ZN4PLMD12Communicator9AllgatherIySt6vectorIySaIyEEEEvRKT_RT0_2
_ZN4PLMD12Communicator4DataC2IyEERSt6vectorIT_SaIS4_EE4
_ZN4PLMD12Communicator4DataC2INS_10AtomNumberEEERSt6vectorIT_SaIS5_EE8
_ZN4PLMD12Communicator5BcastISt6vectorINS_10AtomNumberESaIS3_EEEEvRT_i8
_ZN4PLMD12Communicator3SumISt6vectorINS_13TensorGenericILj3ELj3EEESaIS4_EEEEvRT_16
_ZN4PLMD12Communicator4DataC2INS_13TensorGenericILj3ELj3EEEEERSt6vectorIT_SaIS6_EE16
_ZN4PLMD12Communicator5BcastISt6vectorIjSaIjEEEEvRT_i56
_ZN4PLMD12Communicator4RecvISt6vectorIcSaIcEEEEvRT_iiRNS0_6StatusE57
_ZN4PLMD12Communicator4RecvIdEEvRT_iiRNS0_6StatusE57
_ZN4PLMD12Communicator5IsendINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEENS0_7RequestERKT_ii57
_ZN4PLMD12Communicator5IsendIdEENS0_7RequestERKT_ii57
_ZN4PLMD12Communicator9ConstDataC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE57
_ZN4PLMD12Communicator4DataC2ERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE61
_ZN4PLMD12Communicator5BcastINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRT_i61
_ZN4PLMD12Communicator5BcastISt6vectorIcSaIcEEEEvRT_i114
_ZN4PLMD12Communicator9AllgatherIiSt6vectorIiSaIiEEEEvRKT_RT0_131
_ZN4PLMD12Communicator5BcastINS_13TensorGenericILj3ELj3EEEEEvRT_i134
_ZN4PLMD12Communicator9AllgatherIjSt6vectorIjSaIjEEEEvRKT_RT0_140
_ZN4PLMD12Communicator10AllgathervISt6vectorIjSaIjEES4_EEvRKT_RT0_PKiSB_150
_ZN4PLMD12Communicator9ConstDataC2IjEERKSt6vectorIT_SaIS4_EE150
_ZN4PLMD12Communicator3MaxIdEEvRT_152
_ZN4PLMD12Communicator3SumIiEEvRT_204
_ZN4PLMD12Communicator9AllgatherIiiEEvPKT_iPT0_i204
_ZN4PLMD12Communicator10AllgathervIddEEvPKT_iPT0_PKiS8_224
_ZN4PLMD12Communicator10AllgathervIiiEEvPKT_iPT0_PKiS8_224
_ZN4PLMD12Communicator5BcastIjEEvRT_i430
_ZN4PLMD12Communicator5BcastIdEEvRT_i500
_ZN4PLMD12Communicator3SumIjEEvPT_i553
_ZN4PLMD12Communicator9AllgatherIdSt6vectorIdSaIdEEEEvRKT_RT0_565
_ZN4PLMD12Communicator5BcastISt6vectorIiSaIiEEEEvRT_i580
_ZN4PLMD12Communicator3SumIjEEvRT_1074
_ZN4PLMD12Communicator3SumISt6vectorIiSaIiEEEEvRT_1499
_ZN4PLMD12Communicator4DataC2IiEERSt6vectorIT_SaIS4_EE2210
_ZN4PLMD12Communicator9AllgatherISt6vectorIdSaIdEES4_EEvRKT_RT0_4804
_ZN4PLMD12Communicator9ConstDataC2IdEERKSt6vectorIT_SaIS4_EE4806
_ZN4PLMD12Communicator4RecvIdEEvPT_iiiRNS0_6StatusE7586
_ZN4PLMD12Communicator4RecvIiEEvPT_iiiRNS0_6StatusE7586
_ZN4PLMD12Communicator5IsendIdEENS0_7RequestEPKT_iii7586
_ZN4PLMD12Communicator5IsendIiEENS0_7RequestEPKT_iii7586
_ZNK4PLMD12Communicator6Status9Get_countIiEEiv7586
_ZN4PLMD12Communicator3SumISt6vectorINS_13VectorGenericILj3EEESaIS4_EEEEvRT_11179
_ZN4PLMD12Communicator4DataC2INS_13VectorGenericILj3EEEEERSt6vectorIT_SaIS6_EE11179
_ZN4PLMD12Communicator10AllgathervIjjEEvPKT_iPT0_PKiS8_18459
_ZN4PLMD12Communicator3SumIiEEvPT_i19481
_ZN4PLMD12Communicator3SumINS_13TensorGenericILj3ELj3EEEEEvRT_20641
_ZN4PLMD12Communicator3SumISt6vectorIjSaIjEEEEvRT_39929
_ZN4PLMD12Communicator4DataC2IjEERSt6vectorIT_SaIS4_EE40275
_ZN4PLMD12Communicator5BcastIiEEvRT_i50659
_ZN4PLMD12Communicator3SumIdEEvPT_i88315
_ZN4PLMD12Communicator5BcastISt6vectorIdSaIdEEEEvRT_i278969
_ZN4PLMD12Communicator3SumIdEEvRT_2034363
_ZN4PLMD12Communicator3SumISt6vectorIdSaIdEEEEvRT_2313538
_ZN4PLMD12Communicator4DataC2IdEERSt6vectorIT_SaIS4_EE2597878
_ZN4PLMD12Communicator5BcastImEEvRT_i4868719
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Communicator.h.func.html b/coverage/tools/Communicator.h.func.html new file mode 100644 index 000000000000..ea21f169d7b5 --- /dev/null +++ b/coverage/tools/Communicator.h.func.html @@ -0,0 +1,313 @@ + + + + + + + + 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:404393.0 %
Date:2024-04-19 12:12:35Functions:566093.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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_20641
_ZN4PLMD12Communicator3SumISt6vectorINS_13TensorGenericILj3ELj3EEESaIS4_EEEEvRT_16
_ZN4PLMD12Communicator3SumISt6vectorINS_13VectorGenericILj3EEESaIS4_EEEEvRT_11179
_ZN4PLMD12Communicator3SumISt6vectorIdSaIdEEEEvRT_2313538
_ZN4PLMD12Communicator3SumISt6vectorIfSaIfEEEEvRT_0
_ZN4PLMD12Communicator3SumISt6vectorIiSaIiEEEEvRT_1499
_ZN4PLMD12Communicator3SumISt6vectorIjSaIjEEEEvRT_39929
_ZN4PLMD12Communicator3SumIdEEvPT_i88315
_ZN4PLMD12Communicator3SumIdEEvRT_2034363
_ZN4PLMD12Communicator3SumIiEEvPT_i19481
_ZN4PLMD12Communicator3SumIiEEvRT_204
_ZN4PLMD12Communicator3SumIjEEvPT_i553
_ZN4PLMD12Communicator3SumIjEEvRT_1074
_ZN4PLMD12Communicator4DataC2ERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE61
_ZN4PLMD12Communicator4DataC2INS_10AtomNumberEEERSt6vectorIT_SaIS5_EE8
_ZN4PLMD12Communicator4DataC2INS_13TensorGenericILj3ELj3EEEEERSt6vectorIT_SaIS6_EE16
_ZN4PLMD12Communicator4DataC2INS_13VectorGenericILj3EEEEERSt6vectorIT_SaIS6_EE11179
_ZN4PLMD12Communicator4DataC2IdEERSt6vectorIT_SaIS4_EE2597878
_ZN4PLMD12Communicator4DataC2IfEERSt6vectorIT_SaIS4_EE0
_ZN4PLMD12Communicator4DataC2IiEERSt6vectorIT_SaIS4_EE2210
_ZN4PLMD12Communicator4DataC2IjEERSt6vectorIT_SaIS4_EE40275
_ZN4PLMD12Communicator4DataC2IyEERSt6vectorIT_SaIS4_EE4
_ZN4PLMD12Communicator4RecvISt6vectorIcSaIcEEEEvRT_iiRNS0_6StatusE57
_ZN4PLMD12Communicator4RecvIdEEvPT_iiiRNS0_6StatusE7586
_ZN4PLMD12Communicator4RecvIdEEvRT_iiRNS0_6StatusE57
_ZN4PLMD12Communicator4RecvIiEEvPT_iiiRNS0_6StatusE7586
_ZN4PLMD12Communicator5BcastINS_13TensorGenericILj3ELj3EEEEEvRT_i134
_ZN4PLMD12Communicator5BcastINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRT_i61
_ZN4PLMD12Communicator5BcastISt6vectorINS_10AtomNumberESaIS3_EEEEvRT_i8
_ZN4PLMD12Communicator5BcastISt6vectorIcSaIcEEEEvRT_i114
_ZN4PLMD12Communicator5BcastISt6vectorIdSaIdEEEEvRT_i278969
_ZN4PLMD12Communicator5BcastISt6vectorIfSaIfEEEEvRT_i0
_ZN4PLMD12Communicator5BcastISt6vectorIiSaIiEEEEvRT_i580
_ZN4PLMD12Communicator5BcastISt6vectorIjSaIjEEEEvRT_i56
_ZN4PLMD12Communicator5BcastISt6vectorIySaIyEEEEvRT_i2
_ZN4PLMD12Communicator5BcastIdEEvRT_i500
_ZN4PLMD12Communicator5BcastIiEEvRT_i50659
_ZN4PLMD12Communicator5BcastIjEEvRT_i430
_ZN4PLMD12Communicator5BcastImEEvRT_i4868719
_ZN4PLMD12Communicator5IsendINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEENS0_7RequestERKT_ii57
_ZN4PLMD12Communicator5IsendIdEENS0_7RequestEPKT_iii7586
_ZN4PLMD12Communicator5IsendIdEENS0_7RequestERKT_ii57
_ZN4PLMD12Communicator5IsendIiEENS0_7RequestEPKT_iii7586
_ZN4PLMD12Communicator9AllgatherISt6vectorIdSaIdEES4_EEvRKT_RT0_4804
_ZN4PLMD12Communicator9AllgatherIdSt6vectorIdSaIdEEEEvRKT_RT0_565
_ZN4PLMD12Communicator9AllgatherIiSt6vectorIiSaIiEEEEvRKT_RT0_131
_ZN4PLMD12Communicator9AllgatherIiiEEvPKT_iPT0_i204
_ZN4PLMD12Communicator9AllgatherIjSt6vectorIjSaIjEEEEvRKT_RT0_140
_ZN4PLMD12Communicator9AllgatherIySt6vectorIySaIyEEEEvRKT_RT0_2
_ZN4PLMD12Communicator9ConstDataC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE57
_ZN4PLMD12Communicator9ConstDataC2IdEERKSt6vectorIT_SaIS4_EE4806
_ZN4PLMD12Communicator9ConstDataC2IjEERKSt6vectorIT_SaIS4_EE150
_ZNK4PLMD12Communicator6Status9Get_countIiEEiv7586
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Communicator.h.gcov.html b/coverage/tools/Communicator.h.gcov.html new file mode 100644 index 000000000000..3cefe4c90420 --- /dev/null +++ b/coverage/tools/Communicator.h.gcov.html @@ -0,0 +1,329 @@ + + + + + + + + LCOV - plumed test coverage - tools/Communicator.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Communicator.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:404393.0 %
Date:2024-04-19 12:12:35Functions:566093.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             : #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     2917660 :     template <typename T> Data(T*p,int s): pointer(p), size(s), nbytes(sizeof(T)), type(getMPIType<T>()) {}
+      73             : /// Init from reference
+      74    13912316 :     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       41550 :     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     2651570 :     template <typename T> explicit Data(std::vector<T>&v) {
+      85     2651741 :       Data d(v.data(),v.size()); pointer=d.pointer; size=d.size; type=d.type;
+      86     2651570 :     }
+      87             : /// Init from reference to PLMD::Matrix
+      88             :     template <typename T> explicit Data(Matrix<T>&m ) {
+      89             :       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             :       else { pointer=NULL; size=0; }
+      91             :     }
+      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       24124 :     template <typename T> explicit ConstData(const T*p,int s): pointer(p), size(s), nbytes(sizeof(T)), type(getMPIType<T>()) {}
+     106         952 :     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        4956 :     template <typename T> explicit ConstData(const std::vector<T>&v) {
+     112        4956 :       ConstData d(v.data(),v.size()); pointer=d.pointer; size=d.size; type=d.type;
+     113        4956 :     }
+     114             :     template <typename T> explicit ConstData(const Matrix<T>&m ) {
+     115             :       if(m.nrows()*m.ncols()>0) { ConstData d(&m(0,0),m.nrows()*m.ncols()); pointer=d.pointer; size=d.size; type=d.type; }
+     116             :       else { pointer=NULL; size=0; }
+     117             :     }
+     118          57 :     explicit ConstData(const std::string&s) {
+     119          57 :       if(s.size()>0) { ConstData d(&s[0],s.size()); pointer=d.pointer; size=d.size; type=d.type; }
+     120           0 :       else { pointer=NULL; size=0; }
+     121          57 :     }
+     122             :   };
+     123             : public:
+     124             :   ///Runtime acces to the __PLUMED_HAS_MPI definition
+     125             :   static bool plumedHasMPI();
+     126             : 
+     127             : /// Wrapper class for MPI_Status
+     128             :   class Status {
+     129             :     int Get_count(MPI_Datatype)const;
+     130             :   public:
+     131             :     MPI_Status s;
+     132             :     template <class T>
+     133        7586 :     int Get_count()const {return Get_count(getMPIType<T>());}
+     134             :   };
+     135             : /// Special status used when status should be ignored.
+     136             : /// E.g. `Recv(a,0,1,Communicator::StatusIgnore);`
+     137             : /// Notice that this is the default for Recv, so this is equivalent to
+     138             : /// `Recv(a,0,1);`
+     139             :   static Status StatusIgnore;
+     140             : /// Wrapper class for MPI_Request
+     141             :   class Request {
+     142             :   public:
+     143             :     MPI_Request r;
+     144             :     void wait(Status&s=StatusIgnore);
+     145             :   };
+     146             : /// Default constructor
+     147             :   Communicator();
+     148             : /// Copy constructor.
+     149             : /// It effectively "clones" the communicator, providing a new one acting on the same group
+     150             :   Communicator(const Communicator&);
+     151             : /// Assignment operator.
+     152             : /// It effectively "clones" the communicator, providing a new one acting on the same group
+     153             :   Communicator& operator=(const Communicator&);
+     154             : /// Destructor
+     155             :   virtual ~Communicator();
+     156             : /// Obtain the rank of the present process
+     157             :   int Get_rank()const;
+     158             : /// Obtain the number of processes
+     159             :   int Get_size()const;
+     160             : /// Set from a real MPI communicator.
+     161             : /// \param comm MPI communicator
+     162             :   void Set_comm(MPI_Comm comm);
+     163             : /// Reference to MPI communicator
+     164             :   MPI_Comm & Get_comm();
+     165             : /// Set from a pointer to a real MPI communicator (C).
+     166             : /// \param comm Pointer to a C MPI communicator
+     167             :   void Set_comm(const TypesafePtr & comm);
+     168             : /// Set from a pointer to a real MPI communicator (FORTRAN).
+     169             : /// \param comm Pointer to a FORTRAN MPI communicator (INTEGER)
+     170             :   void Set_fcomm(const TypesafePtr & comm);
+     171             : /// Wrapper to MPI_Abort.
+     172             : /// \param code Error code
+     173             :   void Abort(int code);
+     174             : /// Wrapper to MPI_Barrier
+     175             :   void Barrier()const;
+     176             : /// Tests if MPI library is initialized
+     177             :   static bool initialized();
+     178             : /// Wrapper for MPI_Allreduce with MPI_SUM (data struct)
+     179             :   void Sum(Data);
+     180             : /// Wrapper for MPI_Allreduce with MPI_SUM (pointer)
+     181      108349 :   template <class T> void Sum(T*buf,int count) {Sum(Data(buf,count));}
+     182             : /// Wrapper for MPI_Allreduce with MPI_SUM (reference)
+     183     4422443 :   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     5200232 :   template <class T> void Bcast(T&buf,int root) {Bcast(Data(buf),root);}
+     209             : 
+     210             : /// Wrapper for MPI_Isend (data struct)
+     211             :   Request Isend(ConstData,int,int);
+     212             : /// Wrapper for MPI_Isend (pointer)
+     213       15172 :   template <class T> Request Isend(const T*buf,int count,int source,int tag) {return Isend(ConstData(buf,count),source,tag);}
+     214             : /// Wrapper for MPI_Isend (reference)
+     215         114 :   template <class T> Request Isend(const T&buf,int source,int tag) {return Isend(ConstData(buf),source,tag);}
+     216             : 
+     217             : /// Wrapper for MPI_Allgatherv (data struct)
+     218             :   void Allgatherv(ConstData in,Data out,const int*,const int*);
+     219             : /// Wrapper for MPI_Allgatherv (pointer)
+     220       18907 :   template <class T,class S> void Allgatherv(const T*sendbuf,int sendcount,S*recvbuf,const int*recvcounts,const int*displs) {
+     221       18907 :     Allgatherv(ConstData(sendbuf,sendcount),Data(recvbuf,0),recvcounts,displs);
+     222       18907 :   }
+     223             : /// Wrapper for MPI_Allgatherv (reference)
+     224         152 :   template <class T,class S> void Allgatherv(const T&sendbuf,S&recvbuf,const int*recvcounts,const int*displs) {
+     225         152 :     Allgatherv(ConstData(sendbuf),Data(recvbuf),recvcounts,displs);
+     226         152 :   }
+     227             : 
+     228             : /// Wrapper for MPI_Allgather (data struct)
+     229             :   void Allgather(ConstData in,Data out);
+     230             : /// Wrapper for MPI_Allgatherv (pointer)
+     231         204 :   template <class T,class S> void Allgather(const T*sendbuf,int sendcount,S*recvbuf,int recvcount) {
+     232         408 :     Allgather(ConstData(sendbuf,sendcount),Data(recvbuf,recvcount*Get_size()));
+     233         204 :   }
+     234             : /// Wrapper for MPI_Allgatherv (reference)
+     235        5642 :   template <class T,class S> void Allgather(const T&sendbuf,S&recvbuf) {
+     236        6480 :     Allgather(ConstData(sendbuf),Data(recvbuf));
+     237        5642 :   }
+     238             : 
+     239             : /// Wrapper for MPI_Recv (data struct)
+     240             :   void Recv(Data,int,int,Status&s=StatusIgnore);
+     241             : /// Wrapper for MPI_Recv (pointer)
+     242       15172 :   template <class T> void Recv(T*buf,int count,int source,int tag,Status&s=StatusIgnore) {Recv(Data(buf,count),source,tag,s);}
+     243             : /// Wrapper for MPI_Recv (reference)
+     244         114 :   template <class T> void Recv(T&buf,int source,int tag,Status&s=StatusIgnore) {Recv(Data(buf),source,tag,s);}
+     245             : 
+     246             : /// Wrapper to MPI_Comm_split
+     247             :   void Split(int,int,Communicator&)const;
+     248             : };
+     249             : 
+     250             : }
+     251             : 
+     252             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/ConjugateGradient.h.func-sort-c.html b/coverage/tools/ConjugateGradient.h.func-sort-c.html new file mode 100644 index 000000000000..267040241674 --- /dev/null +++ b/coverage/tools/ConjugateGradient.h.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - tools/ConjugateGradient.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - ConjugateGradient.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:131492.9 %
Date:2024-04-19 12:12:35Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD17ConjugateGradientINS_9gridtools15FindGridOptimumEE8minimiseERKdRSt6vectorIdSaIdEEMS2_FdRKS8_S9_E2
_ZNK4PLMD17ConjugateGradientINS_6dimred13ArrangePointsEE8minimiseERKdRSt6vectorIdSaIdEEMS2_FdRKS8_S9_E27
_ZNK4PLMD17ConjugateGradientINS_6dimred13ProjectPointsEE8minimiseERKdRSt6vectorIdSaIdEEMS2_FdRKS8_S9_E668
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/ConjugateGradient.h.func.html b/coverage/tools/ConjugateGradient.h.func.html new file mode 100644 index 000000000000..ae584ea7a25c --- /dev/null +++ b/coverage/tools/ConjugateGradient.h.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - tools/ConjugateGradient.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - ConjugateGradient.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:131492.9 %
Date:2024-04-19 12:12:35Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD17ConjugateGradientINS_6dimred13ArrangePointsEE8minimiseERKdRSt6vectorIdSaIdEEMS2_FdRKS8_S9_E27
_ZNK4PLMD17ConjugateGradientINS_6dimred13ProjectPointsEE8minimiseERKdRSt6vectorIdSaIdEEMS2_FdRKS8_S9_E668
_ZNK4PLMD17ConjugateGradientINS_9gridtools15FindGridOptimumEE8minimiseERKdRSt6vectorIdSaIdEEMS2_FdRKS8_S9_E2
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/ConjugateGradient.h.gcov.html b/coverage/tools/ConjugateGradient.h.gcov.html new file mode 100644 index 000000000000..c2f3b4bce298 --- /dev/null +++ b/coverage/tools/ConjugateGradient.h.gcov.html @@ -0,0 +1,143 @@ + + + + + + + + LCOV - plumed test coverage - tools/ConjugateGradient.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - ConjugateGradient.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:131492.9 %
Date:2024-04-19 12:12:35Functions: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          11 :   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 ) const ;
+      40             : };
+      41             : 
+      42             : template <class FCLASS>
+      43         697 : void ConjugateGradient<FCLASS>::minimise( const double& ftol, std::vector<double>& p, engf_pointer myfunc ) const {
+      44         697 :   std::vector<double> xi( p.size() ), g( p.size() ), h( p.size() );
+      45         697 :   double fp = this->calcDerivatives( p, xi, myfunc );
+      46        7436 :   for(unsigned j=0; j<p.size(); ++j) { g[j] = -xi[j]; xi[j]=h[j]=g[j]; }
+      47             : 
+      48        1192 :   for(unsigned its=0; its<ITMAX; ++its) {
+      49        1192 :     double fret=this->linemin( xi, p, myfunc );
+      50             :     // The exit condition
+      51        1192 :     if( 2.0*std::fabs(fret-fp) <= ftol*(std::fabs(fret)+std::fabs(fp)+EPS)) { return; }
+      52         495 :     fp = fret; this->calcDerivatives( p, xi, myfunc );
+      53             :     double ddg=0., gg=0.;
+      54       13270 :     for(unsigned j=0; j<p.size(); ++j) { gg += g[j]*g[j]; ddg += (xi[j]+g[j])*xi[j]; }
+      55             : 
+      56         495 :     if( gg==0.0 ) return;
+      57             : 
+      58         495 :     double gam=ddg/gg;
+      59       13270 :     for(unsigned j=0; j<p.size(); ++j) { g[j] = -xi[j]; xi[j]=h[j]=g[j]+gam*h[j]; }
+      60             :   }
+      61           0 :   plumed_merror("Too many interactions in conjugate gradient");
+      62             : }
+      63             : 
+      64             : }
+      65             : 
+      66             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/DLLoader.cpp.func-sort-c.html b/coverage/tools/DLLoader.cpp.func-sort-c.html new file mode 100644 index 000000000000..7f5f1401a3d5 --- /dev/null +++ b/coverage/tools/DLLoader.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + 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:223562.9 %
Date:2024-04-19 12:12:35Functions:5862.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8DLLoader14isPlumedGlobalEv0
_ZN4PLMD8DLLoader18EnsureGlobalDLOpenC2EPKv0
_ZN4PLMD8DLLoader18EnsureGlobalDLOpenD2Ev0
_ZN4PLMD8DLLoader9installedEv42
_ZN4PLMD8DLLoader4loadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE51
_ZNK4PLMD8DLLoader10getHandlesEv53403
_ZN4PLMD8DLLoaderC2Ev811510
_ZN4PLMD8DLLoaderD2Ev811510
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/DLLoader.cpp.func.html b/coverage/tools/DLLoader.cpp.func.html new file mode 100644 index 000000000000..5f072d651c24 --- /dev/null +++ b/coverage/tools/DLLoader.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + 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:223562.9 %
Date:2024-04-19 12:12:35Functions:5862.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8DLLoader14isPlumedGlobalEv0
_ZN4PLMD8DLLoader18EnsureGlobalDLOpenC2EPKv0
_ZN4PLMD8DLLoader18EnsureGlobalDLOpenD2Ev0
_ZN4PLMD8DLLoader4loadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE51
_ZN4PLMD8DLLoader9installedEv42
_ZN4PLMD8DLLoaderC2Ev811510
_ZN4PLMD8DLLoaderD2Ev811510
_ZNK4PLMD8DLLoader10getHandlesEv53403
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/DLLoader.cpp.gcov.html b/coverage/tools/DLLoader.cpp.gcov.html new file mode 100644 index 000000000000..112cc8833992 --- /dev/null +++ b/coverage/tools/DLLoader.cpp.gcov.html @@ -0,0 +1,217 @@ + + + + + + + + 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:223562.9 %
Date:2024-04-19 12:12:35Functions:5862.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 "DLLoader.h"
+      23             : 
+      24             : #include "Exception.h"
+      25             : #include <cstdlib>
+      26             : #include <iostream>
+      27             : #include "core/ActionRegister.h"
+      28             : #include "core/CLToolRegister.h"
+      29             : 
+      30             : #ifdef __PLUMED_HAS_DLOPEN
+      31             : #include <dlfcn.h>
+      32             : #endif
+      33             : 
+      34             : namespace PLMD {
+      35             : 
+      36          42 : bool DLLoader::installed() {
+      37             : #ifdef __PLUMED_HAS_DLOPEN
+      38          42 :   return true;
+      39             : #else
+      40             :   return false;
+      41             : #endif
+      42             : }
+      43             : 
+      44             : 
+      45          51 : void* DLLoader::load(const std::string&s) {
+      46             : #ifdef __PLUMED_HAS_DLOPEN
+      47          51 :   auto lockerAction=Register::registrationLock(s);
+      48          51 :   void* p=dlopen(s.c_str(),RTLD_NOW|RTLD_LOCAL);
+      49          51 :   if(!p) plumed_error()<<"Could not load library "<<s<<"\n"<<dlerror();
+      50          51 :   handles.push_back(p);
+      51          51 :   Register::completeAllRegistrations(p);
+      52          51 :   return p;
+      53             : #else
+      54             :   plumed_error()<<"you are trying to use dlopen but it's not configured on your system";
+      55             : #endif
+      56          51 : }
+      57             : 
+      58      811510 : DLLoader::~DLLoader() {
+      59      811510 :   auto debug=std::getenv("PLUMED_LOAD_DEBUG");
+      60             : #ifdef __PLUMED_HAS_DLOPEN
+      61      811510 :   if(debug) std::fprintf(stderr,"delete dlloader\n");
+      62      811561 :   while(!handles.empty()) {
+      63          51 :     int ret=dlclose(handles.back());
+      64          51 :     if(ret) {
+      65           0 :       std::fprintf(stderr,"+++ error reported by dlclose: %s\n",dlerror());
+      66             :     }
+      67             :     handles.pop_back();
+      68             :   }
+      69      811510 :   if(debug) std::fprintf(stderr,"end delete dlloader\n");
+      70             : #endif
+      71      811510 : }
+      72             : 
+      73      811510 : DLLoader::DLLoader() {
+      74             :   // do nothing
+      75      811510 : }
+      76             : 
+      77       53403 : const std::vector<void*> & DLLoader::getHandles() const noexcept {
+      78       53403 :   return handles;
+      79             : }
+      80             : 
+      81           0 : DLLoader::EnsureGlobalDLOpen::EnsureGlobalDLOpen(const void *symbol) noexcept {
+      82             : #ifdef __PLUMED_HAS_DLOPEN
+      83             : #ifdef __PLUMED_HAS_DLADDR
+      84             :   Dl_info info;
+      85             :   // from the manual:
+      86             :   // If the address specified in addr could not be matched to a shared
+      87             :   //      object, then these functions return 0.  In this case, an error
+      88             :   //      message is not available via dlerror(3).
+      89           0 :   int zeroIsError=dladdr(symbol, &info);
+      90           0 :   if(zeroIsError!=0) {
+      91             :     //This "promotes" to GLOBAL the object with the symbol pointed by ptr
+      92           0 :     handle_ = dlopen(info.dli_fname, RTLD_GLOBAL | RTLD_NOW);
+      93             :   } else {
+      94           0 :     std::fprintf(stderr,
+      95             :                  "+++WARNING+++"
+      96             :                  "Failure in finding any object that contains the symbol %p.\n",
+      97             :                  symbol);
+      98             :   }
+      99             : #else
+     100             :   std::fprintf(stderr,
+     101             :                "+++WARNING+++"
+     102             :                "I can't use dladdr for promoting the library containing the symbol %p.\n"
+     103             :                "This system seems not to support dladdr",
+     104             :                symbol);
+     105             : #endif //__PLUMED_HAS_DLADDR
+     106             : #endif //__PLUMED_HAS_DLOPEN
+     107           0 : }
+     108             : 
+     109           0 : DLLoader::EnsureGlobalDLOpen::~EnsureGlobalDLOpen() {
+     110             : #ifdef __PLUMED_HAS_DLOPEN
+     111           0 :   if (handle_) {
+     112           0 :     dlclose(handle_);
+     113             :   }
+     114             : #endif //__PLUMED_HAS_DLOPEN
+     115           0 : }
+     116             : 
+     117           0 : bool DLLoader::isPlumedGlobal() {
+     118             : #if defined(__APPLE__)
+     119             :   bool result;
+     120             : #ifdef __PLUMED_HAS_DLOPEN
+     121             :   void* handle;
+     122             : #if defined(__PLUMED_HAS_RTLD_DEFAULT)
+     123             :   handle=RTLD_DEFAULT;
+     124             : #else
+     125             :   handle=dlopen(NULL,RTLD_LOCAL);
+     126             : #endif
+     127             :   // we check for two variants, see wrapper/Plumed.h for an explanation:
+     128             :   result=dlsym(handle,"plumed_plumedmain_create") || dlsym(handle,"plumedmain_create");
+     129             :   if(handle) dlclose(handle);
+     130             : #else
+     131             :   // if a system cannot use dlopen, we assume plumed is globally available
+     132             :   result=true;
+     133             : #endif //__PLUMED_HAS_DLOPEN
+     134             :   return result;
+     135             : #else
+     136           0 :   plumed_error()<<"DLLoader::isPlumedGlobal() is only functional with APPLE dlsym";
+     137             : #endif
+     138             : }
+     139             : 
+     140             : } // namespace PLMD
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/DynamicList.h.func-sort-c.html b/coverage/tools/DynamicList.h.func-sort-c.html new file mode 100644 index 000000000000..e34796914d37 --- /dev/null +++ b/coverage/tools/DynamicList.h.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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:132944.8 %
Date:2024-04-19 12:12:35Functions:3742.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11DynamicListIjE13deactivateAllEv0
_ZN4PLMD11DynamicListIjE19updateActiveMembersEv0
_ZNK4PLMD11DynamicListIjE14updateCompleteEv0
_ZNK4PLMD11DynamicListIjE15getNumberActiveEv0
_ZN4PLMD11DynamicListIjE5clearEv36
_ZN4PLMD11DynamicListIjE25createIndexListFromVectorERKSt6vectorIjSaIjEE344817
_ZN4PLMD11DynamicListIjE8activateEj1192882771
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/DynamicList.h.func.html b/coverage/tools/DynamicList.h.func.html new file mode 100644 index 000000000000..b933729fc154 --- /dev/null +++ b/coverage/tools/DynamicList.h.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:132944.8 %
Date:2024-04-19 12:12:35Functions:3742.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11DynamicListIjE13deactivateAllEv0
_ZN4PLMD11DynamicListIjE19updateActiveMembersEv0
_ZN4PLMD11DynamicListIjE25createIndexListFromVectorERKSt6vectorIjSaIjEE344817
_ZN4PLMD11DynamicListIjE5clearEv36
_ZN4PLMD11DynamicListIjE8activateEj1192882771
_ZNK4PLMD11DynamicListIjE14updateCompleteEv0
_ZNK4PLMD11DynamicListIjE15getNumberActiveEv0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/DynamicList.h.gcov.html b/coverage/tools/DynamicList.h.gcov.html new file mode 100644 index 000000000000..6759c595808d --- /dev/null +++ b/coverage/tools/DynamicList.h.gcov.html @@ -0,0 +1,456 @@ + + + + + + + + LCOV - plumed test coverage - tools/DynamicList.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - DynamicList.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:132944.8 %
Date:2024-04-19 12:12:35Functions: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             : #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      344781 :   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           0 :     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          36 : void DynamicList<T>::clear() {
+     219          36 :   all.resize(0);
+     220          36 :   onoff.resize(0); active.resize(0);
+     221          36 : }
+     222             : 
+     223             : template <typename T>
+     224             : bool DynamicList<T>::isActive( const unsigned& i ) const {
+     225             :   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           0 : unsigned DynamicList<T>::getNumberActive() const {
+     235           0 :   return nactive;
+     236             : }
+     237             : 
+     238             : template <typename T>
+     239             : void DynamicList<T>::addIndexToList( const T & ii ) {
+     240             :   all.push_back(ii); active.resize( all.size() ); onoff.push_back(0);
+     241             : }
+     242             : 
+     243             : template <typename T>
+     244      344817 : void DynamicList<T>::createIndexListFromVector( const std::vector<T>& myind ) {
+     245      344817 :   plumed_dbg_assert( all.size()==0 ); onoff.resize( myind.size(), 0 );
+     246      344817 :   active.resize( myind.size() );
+     247      344817 :   all.insert( all.end(), myind.begin(), myind.end() );
+     248      344817 : }
+     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           0 : void DynamicList<T>::deactivateAll() {
+     275           0 :   allWereDeactivated=true; allWereActivated=false;
+     276           0 :   for(unsigned i=0; i<nactive; ++i) onoff[ active[i] ]= 0;
+     277           0 :   nactive=0;
+     278             : #ifndef NDEBUG
+     279             :   for(unsigned i=0; i<onoff.size(); ++i) plumed_dbg_assert( onoff[i]==0 );
+     280             : #endif
+     281           0 : }
+     282             : 
+     283             : template <typename T>
+     284  1192882771 : 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  1192882771 :   onoff[ii]=nprocessors;
+     288  1192882771 : }
+     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           0 : void DynamicList<T>::updateActiveMembers() {
+     308             :   plumed_dbg_assert( allWereActivated || allWereDeactivated );
+     309           0 :   unsigned kk=0; allWereActivated=allWereDeactivated=false;
+     310           0 :   for(unsigned i=0; i<all.size(); ++i) {
+     311           0 :     if( onoff[i]>0 && onoff[i]%nprocessors==0 ) { active[kk]=i; kk++; }
+     312             :   }
+     313           0 :   nactive=kk;
+     314           0 : }
+     315             : 
+     316             : template <typename T>
+     317             : void DynamicList<T>::emptyActiveMembers() {
+     318             :   plumed_dbg_assert( allWereActivated || allWereDeactivated );
+     319             :   nactive=0;
+     320             : }
+     321             : 
+     322             : template <typename T>
+     323             : 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             :   active[nactive]=ii; nactive++;
+     327             : }
+     328             : 
+     329             : template <typename T>
+     330             : void DynamicList<T>::completeUpdate() {
+     331             :   plumed_dbg_assert( allWereActivated || allWereDeactivated );
+     332             :   allWereActivated=allWereDeactivated=false;
+     333             : }
+     334             : 
+     335             : template <typename T>
+     336             : void DynamicList<T>::sortActiveList() {
+     337             :   plumed_dbg_assert( allWereActivated || allWereDeactivated );
+     338             :   allWereActivated=allWereDeactivated=false;
+     339             :   std::sort( active.begin(), active.begin()+nactive );
+     340             : }
+     341             : 
+     342             : template <typename T>
+     343           0 : bool DynamicList<T>::updateComplete() const {
+     344           0 :   if( !allWereActivated && !allWereDeactivated ) return true;
+     345             :   return false;
+     346             : }
+     347             : 
+     348             : template <typename U>
+     349             : void mpi_gatherActiveMembers(Communicator& comm, std::vector< DynamicList<U> >& ll ) {
+     350             :   // Setup an array to hold all data
+     351             :   unsigned bufsize=0; unsigned size=comm.Get_size();
+     352             :   for(unsigned i=0; i<ll.size(); ++i) {
+     353             :     plumed_dbg_massert( ll[i].nprocessors==size, "missing a call to DynamicList::setupMPICommunication" );
+     354             :     bufsize+=ll[i].onoff.size();
+     355             :   }
+     356             :   std::vector<unsigned> buffer( bufsize );
+     357             :   // Gather all onoff data into a single array
+     358             :   bufsize=0;
+     359             :   for(unsigned i=0; i<ll.size(); ++i) {
+     360             :     for(unsigned j=0; j<ll[i].onoff.size(); ++j) { buffer[bufsize]=ll[i].onoff[j]; bufsize++; }
+     361             :   }
+     362             :   // GATHER from all nodes
+     363             :   comm.Sum(&buffer[0],buffer.size());
+     364             :   // distribute back to original lists
+     365             :   bufsize=0;
+     366             :   for(unsigned i=0; i<ll.size(); ++i) {
+     367             :     for(unsigned j=0; j<ll[i].onoff.size(); ++j) {
+     368             :       if( buffer[bufsize]>0 && buffer[bufsize]%size==0 ) ll[i].onoff[j]=size;
+     369             :       else ll[i].onoff[j]=size-1;
+     370             :       bufsize++;
+     371             :     }
+     372             :   }
+     373             :   for(unsigned i=0; i<ll.size(); ++i) ll[i].updateActiveMembers();
+     374             : }
+     375             : 
+     376             : }
+     377             : 
+     378             : #endif
+     379             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/ERMSD.cpp.func-sort-c.html b/coverage/tools/ERMSD.cpp.func-sort-c.html new file mode 100644 index 000000000000..dfeb70559924 --- /dev/null +++ b/coverage/tools/ERMSD.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - tools/ERMSD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - ERMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12012298.4 %
Date:2024-04-19 12:12:35Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5ERMSD5clearEv0
_ZN4PLMD5ERMSD12setReferenceERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKS1_IjSaIjEEd4
_ZN4PLMD5ERMSD9calculateERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKNS_3PbcERS5_RNS_13TensorGenericILj3ELj3EEE222
_ZN4PLMD5ERMSD7calcMatERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKNS_3PbcERS1_INS2_ILj4EEESaISB_EERS1_INS_13TensorGenericILj4ELj3EEESaISG_EE226
_ZN4PLMD5ERMSD6inPairEjj1139266
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/ERMSD.cpp.func.html b/coverage/tools/ERMSD.cpp.func.html new file mode 100644 index 000000000000..67360a687091 --- /dev/null +++ b/coverage/tools/ERMSD.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - tools/ERMSD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - ERMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12012298.4 %
Date:2024-04-19 12:12:35Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5ERMSD12setReferenceERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKS1_IjSaIjEEd4
_ZN4PLMD5ERMSD5clearEv0
_ZN4PLMD5ERMSD6inPairEjj1139266
_ZN4PLMD5ERMSD7calcMatERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKNS_3PbcERS1_INS2_ILj4EEESaISB_EERS1_INS_13TensorGenericILj4ELj3EEESaISG_EE226
_ZN4PLMD5ERMSD9calculateERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKNS_3PbcERS5_RNS_13TensorGenericILj3ELj3EEE222
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/ERMSD.cpp.gcov.html b/coverage/tools/ERMSD.cpp.gcov.html new file mode 100644 index 000000000000..fb9fc1cffb25 --- /dev/null +++ b/coverage/tools/ERMSD.cpp.gcov.html @@ -0,0 +1,380 @@ + + + + + + + + LCOV - plumed test coverage - tools/ERMSD.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - ERMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12012298.4 %
Date:2024-04-19 12:12:35Functions:4580.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : /*
+      24             :  This vast majority of the source code in this file was writting by
+      25             :  Sandro Bottaro with some help from Giovanni Bussi
+      26             : */
+      27             : 
+      28             : #include "ERMSD.h"
+      29             : #include "PDB.h"
+      30             : #include "Matrix.h"
+      31             : #include "Tensor.h"
+      32             : 
+      33             : #include "Pbc.h"
+      34             : #include <cmath>
+      35             : #include <iostream>
+      36             : 
+      37             : 
+      38             : namespace PLMD {
+      39             : 
+      40           0 : void ERMSD::clear() {
+      41             :   reference_mat.clear();
+      42           0 : }
+      43             : 
+      44             : //void ERMSD::calcLcs(const vector<Vector> & positions, vector<Vector> &)
+      45             : 
+      46           4 : void ERMSD::setReference(const std::vector<Vector> & reference, const std::vector<unsigned> & pairs_vec, double mycutoff) {
+      47             : 
+      48           4 :   natoms = reference.size();
+      49           4 :   nresidues = natoms/3;
+      50           4 :   unsigned npairs = pairs_vec.size()/2;
+      51           4 :   pairs.resize(npairs);
+      52          16 :   for(unsigned i=0; i<npairs; ++i) {
+      53             : 
+      54          12 :     pairs[i].first = pairs_vec[2*i];
+      55          12 :     pairs[i].second = pairs_vec[2*i+1];
+      56             :   }
+      57             : 
+      58           4 :   cutoff = mycutoff;
+      59             :   std::vector<TensorGeneric<4,3> > deri;
+      60           4 :   deri.resize(natoms*natoms);
+      61           4 :   reference_mat.resize(nresidues*nresidues);
+      62           4 :   Pbc fake_pbc;
+      63             : 
+      64           4 :   calcMat(reference,fake_pbc,reference_mat,deri);
+      65             : 
+      66           4 : }
+      67             : 
+      68     1139266 : bool ERMSD::inPair(unsigned i, unsigned j) {
+      69             : 
+      70     1139266 :   if(pairs.size()==0) return true;
+      71     3982685 :   for(unsigned idx=0; idx<pairs.size(); idx++) {
+      72     3414408 :     if(pairs[idx].first == i && pairs[idx].second == j) return true;
+      73     3413730 :     if(pairs[idx].second == i && pairs[idx].first == j) return true;
+      74             :   }
+      75             :   return false;
+      76             : }
+      77             : 
+      78         226 : void ERMSD::calcMat(const std::vector<Vector> & positions,const Pbc& pbc, std::vector<Vector4d> &mat, std::vector<TensorGeneric<4,3> > &Gderi) {
+      79             : 
+      80             :   std::vector<Vector3d> pos;
+      81         226 :   pos.resize(3*nresidues);
+      82             : 
+      83             :   std::vector<Tensor3d> deri;
+      84         226 :   deri.resize(nresidues*9);
+      85             : 
+      86             :   std::vector<Vector> centers;
+      87         226 :   centers.resize(nresidues);
+      88             : 
+      89             :   unsigned idx_deri = 0;
+      90             : 
+      91         226 :   Tensor da_dxa = (2./3.)*Tensor::identity();
+      92         226 :   Tensor da_dxb = -(1./3.)*Tensor::identity();
+      93         226 :   Tensor da_dxc = -(1./3.)*Tensor::identity();
+      94             : 
+      95         226 :   Tensor db_dxa = -(1./3.)*Tensor::identity();
+      96         226 :   Tensor db_dxb = (2./3.)*Tensor::identity();
+      97         226 :   Tensor db_dxc = -(1./3.)*Tensor::identity();
+      98             : 
+      99             :   // Form factors - should this be somewhere else?
+     100             : 
+     101             :   double w = 1./3.;
+     102         226 :   Vector form_factor = Vector(2.0,2.0,1.0/0.3);
+     103             : 
+     104       16272 :   for(unsigned res_idx=0; res_idx<natoms/3; res_idx++) {
+     105             : 
+     106             : 
+     107       16046 :     const unsigned at_idx = 3*res_idx;
+     108             :     //center
+     109       64184 :     for (unsigned j=0; j<3; j++) {
+     110       48138 :       centers[res_idx] += w*positions[at_idx+j];
+     111             :     }
+     112             : 
+     113       16046 :     Vector3d a = delta(centers[res_idx],positions[at_idx]);
+     114       16046 :     Vector3d b = delta(centers[res_idx],positions[at_idx+1]);
+     115       16046 :     Vector3d d = crossProduct(a,b);
+     116       16046 :     double ianorm = 1./a.modulo();
+     117       16046 :     double idnorm = 1./d.modulo();
+     118             : 
+     119             :     // X vector: COM-C2
+     120       16046 :     pos[at_idx] = a*ianorm;
+     121             :     // Z versor: C2 x (COM-C4/C6)
+     122       16046 :     pos[at_idx+2] = d*idnorm;
+     123             :     // Y versor: Z x Y
+     124       16046 :     pos[at_idx+1] = crossProduct(pos[at_idx+2],pos[at_idx]);
+     125             : 
+     126             :     // Derivatives ////////
+     127       16046 :     Tensor3d t1 = ianorm*(Tensor::identity()-extProduct(pos[at_idx],pos[at_idx]));
+     128             :     // dv1/dxa
+     129       16046 :     deri[idx_deri] = (2./3. )*t1;
+     130             :     // dv1/dxb
+     131       16046 :     deri[idx_deri+3] = -(1./3.)*t1;
+     132             :     // dv1/dxc
+     133       16046 :     deri[idx_deri+6] = -(1./3.)*t1;
+     134             : 
+     135       16046 :     Tensor dd_dxa =  VcrossTensor(a,db_dxa) -VcrossTensor(b,da_dxa);
+     136       16046 :     Tensor dd_dxb =  VcrossTensor(a,db_dxb)-VcrossTensor(b,da_dxb);
+     137       16046 :     Tensor dd_dxc =  VcrossTensor(a,db_dxc)-VcrossTensor(b,da_dxc);
+     138             : 
+     139             :     // dv3/dxa
+     140       16046 :     deri[idx_deri+2] = deriNorm(d,dd_dxa);
+     141             :     // dv3/dxb
+     142       16046 :     deri[idx_deri+5] = deriNorm(d,dd_dxb);
+     143             :     // dv3/dxc
+     144       16046 :     deri[idx_deri+8] = deriNorm(d,dd_dxc);
+     145             : 
+     146             :     // dv2/dxa = dv3/dxa cross v1 + v3 cross dv1/dxa
+     147       32092 :     deri[idx_deri+1] =  (VcrossTensor(deri[idx_deri+2],pos[at_idx]) + \
+     148       32092 :                          VcrossTensor(pos[at_idx+2],deri[idx_deri]));
+     149             :     // dv2/dxb
+     150       32092 :     deri[idx_deri+4] =  (VcrossTensor(deri[idx_deri+5],pos[at_idx]) + \
+     151       32092 :                          VcrossTensor(pos[at_idx+2],deri[idx_deri+3]));
+     152             :     // dv2/dxc
+     153       32092 :     deri[idx_deri+7] =  (VcrossTensor(deri[idx_deri+8],pos[at_idx]) + \
+     154       32092 :                          VcrossTensor(pos[at_idx+2],deri[idx_deri+6]));
+     155             : 
+     156       16046 :     idx_deri += 9;
+     157             :     // End derivatives ///////
+     158             : 
+     159             :   }
+     160             : 
+     161             : 
+     162             :   // Initialization (unnecessary?)
+     163     1139492 :   for (unsigned i1=0; i1<nresidues*nresidues; i1++) {
+     164     5696330 :     for (unsigned i2=0; i2<4; i2++) {
+     165     4557064 :       mat[i1][i2] = 0.0;
+     166             :     }
+     167             :   }
+     168             : 
+     169         226 :   double maxdist = cutoff/form_factor[0];
+     170         226 :   double gamma = pi/cutoff;
+     171             :   unsigned idx;
+     172             :   unsigned idx1 = 0;
+     173             :   // Calculate mat
+     174       16272 :   for (unsigned i=0; i<nresidues; i++) {
+     175     1155312 :     for (unsigned j=0; j<nresidues; j++) {
+     176             : 
+     177             :       // skip i==j
+     178     1139266 :       if(inPair(i,j) and i != j) {
+     179             :         //if(i!=j){
+     180             : 
+     181             : 
+     182             :         // Calculate normal distance first
+     183      562966 :         Vector diff = delta(centers[i],centers[j]);
+     184      562966 :         double d1 = diff.modulo();
+     185      562966 :         if(d1<maxdist) {
+     186             : 
+     187             :           // calculate r_tilde_ij
+     188       85382 :           Vector3d rtilde;
+     189      341528 :           for (unsigned k=0; k<3; k++) {
+     190     1024584 :             for (unsigned l=0; l<3; l++) {
+     191      768438 :               rtilde[l] += pos[3*i+l][k]*diff[k]*form_factor[l];
+     192             :             }
+     193             :           }
+     194       85382 :           double rtilde_norm = rtilde.modulo();
+     195             : 
+     196       85382 :           double irnorm = 1./rtilde_norm;
+     197             : 
+     198             :           // ellipsoidal cutoff
+     199       85382 :           if(rtilde_norm < cutoff) {
+     200       53822 :             idx = i*nresidues + j;
+     201             : 
+     202             : 
+     203             :             // fill 4d matrix
+     204       53822 :             double dummy = std::sin(gamma*rtilde_norm)/(rtilde_norm*gamma);
+     205       53822 :             mat[idx][0] = dummy*rtilde[0];
+     206       53822 :             mat[idx][1] = dummy*rtilde[1];
+     207       53822 :             mat[idx][2] = dummy*rtilde[2];
+     208       53822 :             mat[idx][3] = (1.+ std::cos(gamma*rtilde_norm))/gamma;
+     209             : 
+     210             :             // Derivative (drtilde_dx)
+     211             :             std::vector<Tensor3d> drtilde_dx;
+     212       53822 :             drtilde_dx.resize(6);
+     213       53822 :             unsigned pos_idx = 3*i;
+     214       53822 :             unsigned deri_idx = 9*i;
+     215      215288 :             for (unsigned at=0; at<3; at++) {
+     216      645864 :               for (unsigned l=0; l<3; l++) {
+     217      484398 :                 Vector3d rvec = form_factor[l]*((pos[pos_idx+l])/3.);
+     218      484398 :                 Vector3d vvec = form_factor[l]*(matmul(deri[deri_idx+3*at+l],diff));
+     219      484398 :                 drtilde_dx[at].setRow(l,vvec-rvec);
+     220      484398 :                 drtilde_dx[at+3].setRow(l,rvec);
+     221             :               }
+     222             :             }
+     223             : 
+     224       53822 :             double dummy1 = (std::cos(gamma*rtilde_norm) - dummy);
+     225             : 
+     226       53822 :             idx1 = i*nresidues*6 + j*6;
+     227             : 
+     228      376754 :             for (unsigned l=0; l<6; l++) {
+     229             :               //std::cout << i << " " << j << " " << idx1 << " " << idx1+l << "\n";
+     230             : 
+     231             :               // components 1,2,3
+     232             :               // std::sin(gamma*|rtilde|)/gamma*|rtilde|*d_rtilde +
+     233             :               // + ((d_rtilde*r_tilde/r_tilde^2) out r_tilde)*
+     234             :               // (std::cos(gamma*|rtilde| - std::sin(gamma*|rtilde|)/gamma*|rtilde|))
+     235      322932 :               Vector3d rdr = matmul(rtilde,drtilde_dx[l]);
+     236      322932 :               Tensor tt = dummy*drtilde_dx[l] + (dummy1*irnorm*irnorm)*Tensor(rtilde,rdr);
+     237     1291728 :               for (unsigned m=0; m<3; m++) {
+     238             :                 // Transpose here
+     239             :                 //dG_dx[l].setRow(m,tt.getRow(m));
+     240      968796 :                 Gderi[idx1+l].setRow(m,tt.getRow(m));
+     241             :               }
+     242             :               // component 4
+     243             :               // - std::sin(gamma*|rtilde|)/|rtilde|*(r_tilde*d_rtilde)
+     244             :               //dG_dx[l].setRow(3,-dummy*gamma*rdr);
+     245      322932 :               Gderi[idx1+l].setRow(3,-dummy*gamma*rdr);
+     246             :             }
+     247             : 
+     248             : 
+     249             : 
+     250             : 
+     251             :           }
+     252             :         }
+     253             :       }
+     254             : 
+     255             :     }
+     256             :   }
+     257             : 
+     258         226 : }
+     259             : 
+     260             : 
+     261         222 : double ERMSD::calculate(const std::vector<Vector> & positions,const Pbc& pbc,\
+     262             :                         std::vector<Vector> &derivatives, Tensor& virial) {
+     263             : 
+     264             : 
+     265             :   double ermsd=0.;
+     266             :   std::vector<Vector4d> mat;
+     267         222 :   mat.resize(nresidues*nresidues);
+     268             : 
+     269             :   std::vector<TensorGeneric<4,3> > Gderi;
+     270         222 :   Gderi.resize(natoms*natoms);
+     271             : 
+     272         222 :   calcMat(positions,pbc,mat,Gderi);
+     273             : 
+     274             :   unsigned idx1 = 0;
+     275       15984 :   for(unsigned i=0; i<nresidues; i++) {
+     276     1134864 :     for(unsigned j=0; j<nresidues; j++) {
+     277     1119102 :       unsigned ii = i*nresidues + j;
+     278             : 
+     279     1119102 :       Vector4d dd = delta(reference_mat[ii],mat[ii]);
+     280     1119102 :       double val = dd.modulo2();
+     281             : 
+     282     1119102 :       if(val>0.0 && i!=j) {
+     283             : 
+     284      256596 :         for(unsigned k=0; k<3; k++) {
+     285      192447 :           idx1 = i*nresidues*6 + j*6 + k;
+     286             : 
+     287      192447 :           derivatives[3*i+k] += matmul(dd,Gderi[idx1]);
+     288      192447 :           derivatives[3*j+k] += matmul(dd,Gderi[idx1+3]);
+     289             :         }
+     290       64149 :         ermsd += val;
+     291             :       }
+     292             :     }
+     293             :   }
+     294             : 
+     295         222 :   ermsd = std::sqrt(ermsd/nresidues);
+     296         222 :   double iermsd = 1.0/(ermsd*nresidues);
+     297       47508 :   for(unsigned i=0; i<natoms; ++i) {derivatives[i] *= iermsd;}
+     298             : 
+     299         222 :   return ermsd;
+     300             : }
+     301             : 
+     302             : 
+     303             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/ERMSD.h.func-sort-c.html b/coverage/tools/ERMSD.h.func-sort-c.html new file mode 100644 index 000000000000..1bf381eceddf --- /dev/null +++ b/coverage/tools/ERMSD.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage - tools/ERMSD.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - ERMSD.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1250.0 %
Date:2024-04-19 12:12:35Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/ERMSD.h.func.html b/coverage/tools/ERMSD.h.func.html new file mode 100644 index 000000000000..d7c2851a98d0 --- /dev/null +++ b/coverage/tools/ERMSD.h.func.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage - tools/ERMSD.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - ERMSD.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1250.0 %
Date:2024-04-19 12:12:35Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/ERMSD.h.gcov.html b/coverage/tools/ERMSD.h.gcov.html new file mode 100644 index 000000000000..6b2b4483944e --- /dev/null +++ b/coverage/tools/ERMSD.h.gcov.html @@ -0,0 +1,150 @@ + + + + + + + + LCOV - plumed test coverage - tools/ERMSD.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - ERMSD.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1250.0 %
Date:2024-04-19 12:12:35Functions:00-
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_tools_ERMSD_h
+      23             : #define __PLUMED_tools_ERMSD_h
+      24             : 
+      25             : #include "Tensor.h"
+      26             : #include "Vector.h"
+      27             : #include <vector>
+      28             : #include <limits>
+      29             : #include <string>
+      30             : #include <map>
+      31             : #include <utility>
+      32             : #include <cstddef>
+      33             : 
+      34             : namespace PLMD {
+      35             : 
+      36             : class PDB;
+      37             : class Pbc;
+      38             : 
+      39             : /// A class that implements ERMSD calculations
+      40           0 : class ERMSD {
+      41             :   //std::map< std::pair <unsigned,unsigned> , double> targets;
+      42             :   //unsigned natoms;
+      43             :   std::vector<Vector4d> reference_mat;
+      44             :   std::size_t natoms;
+      45             :   std::size_t nresidues;
+      46             :   std::vector<std::pair <unsigned,unsigned> > pairs;
+      47             :   double cutoff;
+      48             : 
+      49             : public:
+      50             : /// Constructor
+      51           4 :   ERMSD(): natoms(0),nresidues(0), cutoff(0.0) {}
+      52             : 
+      53             : /// clear the structure
+      54             :   void clear();
+      55             : 
+      56             :   bool inPair(unsigned i, unsigned j);
+      57             : 
+      58             : /// set reference coordinates
+      59             :   void setReference(const std::vector<Vector> & reference, const std::vector<unsigned> & pairs_vec,double mycutoff=0.24);
+      60             : 
+      61             :   void calcMat(const std::vector<Vector> & positions, const Pbc& pbc,std::vector<Vector4d> &mat,std::vector<TensorGeneric<4,3> > & Gderivatives);
+      62             : 
+      63             : /// Compute ermsd ( no pbc )
+      64             : //  double calculate(const std::vector<Vector> & positions,
+      65             : //                   std::vector<Vector> &derivatives, Tensor& virial) const ;
+      66             : /// Compute ermsd ( with pbc )
+      67             :   double calculate(const std::vector<Vector>& positions, const Pbc& pbc,std::vector<Vector> &derivatives, Tensor& virial);
+      68             : };
+      69             : 
+      70             : }
+      71             : 
+      72             : #endif
+      73             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Exception.cpp.func-sort-c.html b/coverage/tools/Exception.cpp.func-sort-c.html new file mode 100644 index 000000000000..820b9b2bc9f9 --- /dev/null +++ b/coverage/tools/Exception.cpp.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - tools/Exception.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Exception.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:485194.1 %
Date:2024-04-19 12:12:35Functions:66100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD9Exception5stackEv4
_ZN4PLMD9ExceptionlsERKNS0_9AssertionE13
_ZN4PLMD12_GLOBAL__N_18simplifyERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE57
_ZN4PLMD9ExceptionlsERKNS0_8LocationE57
_ZN4PLMD9ExceptionC2Ev96
_ZN4PLMD9ExceptionlsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE147
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Exception.cpp.func.html b/coverage/tools/Exception.cpp.func.html new file mode 100644 index 000000000000..7992b71a8a61 --- /dev/null +++ b/coverage/tools/Exception.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - tools/Exception.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Exception.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:485194.1 %
Date:2024-04-19 12:12:35Functions:66100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12_GLOBAL__N_18simplifyERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE57
_ZN4PLMD9ExceptionC2Ev96
_ZN4PLMD9ExceptionlsERKNS0_8LocationE57
_ZN4PLMD9ExceptionlsERKNS0_9AssertionE13
_ZN4PLMD9ExceptionlsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE147
_ZNK4PLMD9Exception5stackEv4
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Exception.cpp.gcov.html b/coverage/tools/Exception.cpp.gcov.html new file mode 100644 index 000000000000..df8e75053527 --- /dev/null +++ b/coverage/tools/Exception.cpp.gcov.html @@ -0,0 +1,233 @@ + + + + + + + + LCOV - plumed test coverage - tools/Exception.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Exception.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:485194.1 %
Date:2024-04-19 12:12:35Functions:66100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "Exception.h"
+      23             : 
+      24             : #if defined(__PLUMED_HAS_EXECINFO)
+      25             : #include <execinfo.h>
+      26             : #endif
+      27             : 
+      28             : #include <cstdio>
+      29             : #include <cstring>
+      30             : #include <cstdlib>
+      31             : #include <vector>
+      32             : 
+      33             : namespace PLMD {
+      34             : 
+      35             : namespace {
+      36             : // see https://www.geeksforgeeks.org/simplify-directory-path-unix-like/
+      37             : 
+      38             : // function to simplify a Unix - styled
+      39             : // absolute path
+      40          57 : std::string simplify(const std::string & path)
+      41             : {
+      42             :   // using vector in place of stack
+      43             :   std::vector<std::string> v;
+      44          57 :   int n = path.length();
+      45             :   std::string ans;
+      46         185 :   for (int i = 0; i < n; i++) {
+      47         128 :     std::string dir = "";
+      48             :     // forming the current directory.
+      49        1135 :     while (i < n && path[i] != '/') {
+      50        1007 :       dir += path[i];
+      51        1007 :       i++;
+      52             :     }
+      53             : 
+      54             :     // if ".." , we pop.
+      55         128 :     if (dir == "..") {
+      56           4 :       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         176 :   for (const auto & i : v) {
+      71         119 :     if(!first) ans += "/";
+      72             :     first=false;
+      73             :     ans += i;
+      74             :   }
+      75             : 
+      76             :   // vector is empty
+      77          57 :   if (ans == "")
+      78           0 :     return "/";
+      79             : 
+      80             :   return ans;
+      81          57 : }
+      82             : 
+      83             : }
+      84             : 
+      85          96 : Exception::Exception()
+      86             : {
+      87             :   callstack.fill(nullptr);
+      88             : #ifdef __PLUMED_HAS_EXECINFO
+      89          96 :   callstack_n = backtrace(&callstack[0], callstack.size()-1);
+      90          96 :   const char* env=std::getenv("PLUMED_STACK_TRACE");
+      91          96 :   if(env && !std::strcmp(env,"yes")) {
+      92             :     msg+="\n\n********** STACK DUMP **********\n";
+      93           4 :     msg+=stack();
+      94             :     msg+="\n********** END STACK DUMP **********\n";
+      95             :   }
+      96             : #endif
+      97          96 : }
+      98             : 
+      99         147 : Exception& Exception::operator<<(const std::string&msg)
+     100             : {
+     101         147 :   if(msg.length()>0) {
+     102         147 :     if(note) this->msg +="\n";
+     103         147 :     this->msg +=msg;
+     104         147 :     note=false;
+     105             :   }
+     106         147 :   return *this;
+     107             : }
+     108             : 
+     109          57 : Exception& Exception::operator<<(const Location&loc)
+     110             : {
+     111          57 :   if(loc.file) {
+     112             :     const std::size_t clinelen=1000;
+     113             :     char cline[clinelen];
+     114          57 :     std::snprintf(cline,clinelen,"%u",loc.line);
+     115          57 :     this->msg += "\n(";
+     116             :     try {
+     117         114 :       this->msg += simplify(loc.file);
+     118           0 :     } catch(...) {
+     119             :       // ignore
+     120           0 :     }
+     121             :     this->msg += ":";
+     122             :     this->msg += cline;
+     123             :     this->msg += ")";
+     124          57 :     if(loc.pretty && loc.pretty[0]) {
+     125             :       this->msg += " ";
+     126          57 :       this->msg += loc.pretty;
+     127             :     }
+     128             :   }
+     129          57 :   note=true;
+     130          57 :   return *this;
+     131             : }
+     132             : 
+     133          13 : Exception& Exception::operator<<(const Assertion&as)
+     134             : {
+     135          13 :   if(as.assertion) {
+     136          13 :     this->msg += "\n+++ assertion failed: ";
+     137          13 :     this->msg += as.assertion;
+     138             :   }
+     139          13 :   note=true;
+     140          13 :   return *this;
+     141             : }
+     142             : 
+     143           4 : const char* Exception::stack() const {
+     144             : #ifdef __PLUMED_HAS_EXECINFO
+     145           4 :   if(stackTrace.length()==0) {
+     146           4 :     char** strs = backtrace_symbols(&callstack[0], callstack_n);
+     147          39 :     for (int i = 0; i < callstack_n; ++i) {stackTrace+=strs[i]; stackTrace+="\n";}
+     148           4 :     free(strs);
+     149             :   }
+     150             : #endif
+     151           4 :   return stackTrace.c_str();
+     152             : }
+     153             : 
+     154             : }
+     155             : 
+     156             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Exception.h.func-sort-c.html b/coverage/tools/Exception.h.func-sort-c.html new file mode 100644 index 000000000000..53d35aba4fea --- /dev/null +++ b/coverage/tools/Exception.h.func-sort-c.html @@ -0,0 +1,621 @@ + + + + + + + + LCOV - plumed test coverage - tools/Exception.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Exception.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:333691.7 %
Date:2024-04-19 12:12:35Functions:2413717.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9ExceptionD0Ev0
_ZN4PLMD9ExceptionlsIA100_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA102_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA103_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA104_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA108_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA110_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA111_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA113_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA115_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA116_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA118_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA119_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA124_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA129_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA12_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA130_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA131_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA133_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA134_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA13_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA140_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA145_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA148_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA14_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA155_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA156_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA15_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA165_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA166_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA171_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA17_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA20_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA21_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA22_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA24_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA256_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA25_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA26_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA27_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA28_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA29_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA32_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA33_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA34_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA36_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA37_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA38_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA39_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA40_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA41_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA42_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA44_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA45_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA46_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA47_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA48_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA49_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA500_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA51_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA52_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA53_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA54_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA55_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA56_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA57_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA58_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA59_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA60_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA61_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA62_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA63_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA64_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA65_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA67_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA68_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
_ZN4PLMD9ExceptionlsIA96_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA98_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsINS_13TensorGenericILj3ELj3EEEEERS0_RKT_0
_ZN4PLMD9ExceptionlsINS_13TensorGenericILj4ELj4EEEEERS0_RKT_0
_ZN4PLMD9ExceptionlsIPKcEERS0_RKT_0
_ZN4PLMD9ExceptionlsIPcEERS0_RKT_0
_ZN4PLMD9ExceptionlsIcEERS0_RKT_0
_ZN4PLMD9ExceptionlsIdEERS0_RKT_0
_ZN4PLMD9ExceptionlsIiEERS0_RKT_0
_ZN4PLMD9ExceptionlsIjEERS0_RKT_0
_ZN4PLMD9ExceptionlsIlEERS0_RKT_0
_ZN4PLMD9ExceptionlsIxEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA105_cEERS0_RKT_1
_ZN4PLMD9ExceptionlsIA2_cEERS0_RKT_1
_ZN4PLMD9ExceptionlsIA35_cEERS0_RKT_1
_ZN4PLMD9ExceptionlsIA43_cEERS0_RKT_1
_ZN4PLMD9ExceptionlsIA83_cEERS0_RKT_1
_ZN4PLMD9ExceptionlsIA89_cEERS0_RKT_1
_ZN4PLMD9Exception5ThrowlSIRNS_14ExceptionErrorEEEvOT_2
_ZN4PLMD9ExceptionlsIA18_cEERS0_RKT_2
_ZN4PLMD9ExceptionlsIA19_cEERS0_RKT_2
_ZN4PLMD9ExceptionlsIA94_cEERS0_RKT_2
_ZN4PLMD9ExceptionlsIA95_cEERS0_RKT_2
_ZN4PLMD9ExceptionlsIA31_cEERS0_RKT_3
_ZN4PLMD9ExceptionlsIA3_cEERS0_RKT_3
_ZN4PLMD9ExceptionlsIA30_cEERS0_RKT_4
_ZN4PLMD9ExceptionlsImEERS0_RKT_4
_ZN4PLMD9ExceptionlsIA50_cEERS0_RKT_5
_ZN4PLMD9ExceptionlsIA9_cEERS0_RKT_5
_ZN4PLMD9ExceptionlsIA23_cEERS0_RKT_6
_ZN4PLMD9ExceptionlsIA66_cEERS0_RKT_7
_ZN4PLMD9ExceptionlsISt17basic_string_viewIcSt11char_traitsIcEEEERS0_RKT_10
_ZN4PLMD9ExceptionC2ERKS0_26
_ZN4PLMD9ExceptionC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE31
_ZNK4PLMD9Exception4whatEv39
_ZN4PLMD9ExceptionD2Ev56
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Exception.h.func.html b/coverage/tools/Exception.h.func.html new file mode 100644 index 000000000000..44669f7289fc --- /dev/null +++ b/coverage/tools/Exception.h.func.html @@ -0,0 +1,621 @@ + + + + + + + + LCOV - plumed test coverage - tools/Exception.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Exception.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:333691.7 %
Date:2024-04-19 12:12:35Functions:2413717.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9Exception5ThrowlSIRNS_14ExceptionErrorEEEvOT_2
_ZN4PLMD9ExceptionC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE31
_ZN4PLMD9ExceptionC2ERKS0_26
_ZN4PLMD9ExceptionD0Ev0
_ZN4PLMD9ExceptionD2Ev56
_ZN4PLMD9ExceptionlsIA100_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA102_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA103_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA104_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA105_cEERS0_RKT_1
_ZN4PLMD9ExceptionlsIA108_cEERS0_RKT_0
_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
_ZN4PLMD9ExceptionlsIA124_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA129_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA12_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA130_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA131_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA133_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA134_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA13_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA140_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA145_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA148_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA14_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA155_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA156_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA15_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA165_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA166_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA171_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA17_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA18_cEERS0_RKT_2
_ZN4PLMD9ExceptionlsIA19_cEERS0_RKT_2
_ZN4PLMD9ExceptionlsIA20_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA21_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA22_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA23_cEERS0_RKT_6
_ZN4PLMD9ExceptionlsIA24_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA256_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA25_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA26_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA27_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA28_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA29_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA2_cEERS0_RKT_1
_ZN4PLMD9ExceptionlsIA30_cEERS0_RKT_4
_ZN4PLMD9ExceptionlsIA31_cEERS0_RKT_3
_ZN4PLMD9ExceptionlsIA32_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA33_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA34_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA35_cEERS0_RKT_1
_ZN4PLMD9ExceptionlsIA36_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA37_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA38_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA39_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA3_cEERS0_RKT_3
_ZN4PLMD9ExceptionlsIA40_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA41_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA42_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA43_cEERS0_RKT_1
_ZN4PLMD9ExceptionlsIA44_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA45_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA46_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA47_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA48_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA49_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA500_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA50_cEERS0_RKT_5
_ZN4PLMD9ExceptionlsIA51_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA52_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA53_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA54_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA55_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA56_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA57_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA58_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA59_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA60_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA61_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA62_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA63_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA64_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA65_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA66_cEERS0_RKT_7
_ZN4PLMD9ExceptionlsIA67_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA68_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
_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_2
_ZN4PLMD9ExceptionlsIA95_cEERS0_RKT_2
_ZN4PLMD9ExceptionlsIA96_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA98_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA9_cEERS0_RKT_5
_ZN4PLMD9ExceptionlsINS_13TensorGenericILj3ELj3EEEEERS0_RKT_0
_ZN4PLMD9ExceptionlsINS_13TensorGenericILj4ELj4EEEEERS0_RKT_0
_ZN4PLMD9ExceptionlsIPKcEERS0_RKT_0
_ZN4PLMD9ExceptionlsIPcEERS0_RKT_0
_ZN4PLMD9ExceptionlsISt17basic_string_viewIcSt11char_traitsIcEEEERS0_RKT_10
_ZN4PLMD9ExceptionlsIcEERS0_RKT_0
_ZN4PLMD9ExceptionlsIdEERS0_RKT_0
_ZN4PLMD9ExceptionlsIiEERS0_RKT_0
_ZN4PLMD9ExceptionlsIjEERS0_RKT_0
_ZN4PLMD9ExceptionlsIlEERS0_RKT_0
_ZN4PLMD9ExceptionlsImEERS0_RKT_4
_ZN4PLMD9ExceptionlsIxEERS0_RKT_0
_ZNK4PLMD9Exception4whatEv39
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Exception.h.gcov.html b/coverage/tools/Exception.h.gcov.html new file mode 100644 index 000000000000..ecc07dbbfcc2 --- /dev/null +++ b/coverage/tools/Exception.h.gcov.html @@ -0,0 +1,480 @@ + + + + + + + + LCOV - plumed test coverage - tools/Exception.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Exception.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:333691.7 %
Date:2024-04-19 12:12:35Functions:2413717.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             : #ifndef __PLUMED_tools_Exception_h
+      23             : #define __PLUMED_tools_Exception_h
+      24             : 
+      25             : #include <exception>
+      26             : #include <string>
+      27             : #include <stdexcept>
+      28             : #include <sstream>
+      29             : #include <array>
+      30             : 
+      31             : namespace PLMD {
+      32             : 
+      33             : /**
+      34             : \ingroup TOOLBOX
+      35             : Class to deal with Plumed runtime errors.
+      36             : 
+      37             : This class and the related macros can be used to detect programming
+      38             : errors. Typical cases are internal inconsistencies or errors in the plumed<->MD
+      39             : interface. Mistakes made by final users (i.e. in the `plumed.dat` file)
+      40             : should probably be documented in some better way (e.g. printing parts of the manual in the output).
+      41             : However, also this class allows for significant information to be attached.
+      42             : Let's try to make error messages as informative as possible!
+      43             : 
+      44             : \note This class has been rewritten in PLUMED 2.5. It works in a backward compatible manner,
+      45             : but is much more flexible. The main novelty is that we can use insertion operators to
+      46             : add arbitrary messages, as in `plumed_error()<<"check this vector "<<v;`
+      47             : See below for more details.
+      48             : 
+      49             : To throw an error, just throw a c++ exception
+      50             : \verbatim
+      51             :   if(something_bad) throw Exception();
+      52             : \endverbatim
+      53             : or better add an error message to that
+      54             : \verbatim
+      55             :   if(something_bad) throw Exception("describe the error here");
+      56             : \endverbatim
+      57             : 
+      58             : As of PLUMED 2.5 you can add multiple messages, they will just be concatenated,
+      59             : but to do se you should use the insertion operator. Notice that anything that
+      60             : can be formatted with an insertion operator can go to the exception, even a \ref Vector
+      61             : \verbatim
+      62             :   Vector v;
+      63             :   if(something_bad) throw Exception()<<"problem with this "<<v;
+      64             : \endverbatim
+      65             : In principle you can mix the two syntax (add a message as an argument and insert others with `<<`),
+      66             : however it is not very clear and should be avoided.
+      67             : We only allow using arguments in parenthesis in order to keep backward compatibility.
+      68             : 
+      69             : \par Using macros
+      70             : 
+      71             : In order to provide more context, especially for debugging, it might be useful to know where the exception
+      72             : originated from. The macros below add information about the exact location of the error in the file (filename, line
+      73             : and, when available, function name). Macros ending in "error" unconditionally throw
+      74             : the exception, whereas macros ending in "assert" first perform a conditional check
+      75             : (similarly to standard assert()).
+      76             : An extra `m` in the name (e.g. `plumed_merror`) indicates a macro that provides a message as its argument.
+      77             : However, as of PLUMED 2.5 we should prefer adding messages using insertion operators.
+      78             : \verbatim
+      79             : // this is correct but not recommended. add a message please!
+      80             :   plumed_assert(a>0);
+      81             : 
+      82             : // this is the old syntax (with argument).
+      83             : // this syntax is basically available for backward compatibility.
+      84             :   plumed_massert(a>0,"a should be larger than zero);
+      85             : 
+      86             : // this is the recommended syntax, with insertion operators.
+      87             : // it allows to easily insert multiple objects
+      88             :   plumed_assert(a>0)<<"a should be larger than zero. a="<<a;
+      89             : 
+      90             : // same as above, but the test is made explicitly:
+      91             :   if(a<=0) plumed_error();
+      92             :   if(a<=0) plumed_error("a should be larger than zero);
+      93             :   if(a<=0) plumed_error()<<"a should be larger than zero. a="<<a;
+      94             : \endverbatim
+      95             : 
+      96             : The additional macros
+      97             : plumed_dbg_assert() and plumed_dbg_massert() are similar
+      98             : to plumed_assert() and plumed_massert() respectively, but the corresponding
+      99             : check is only performed when NDEBUG macro is not defined. They should
+     100             : be used when the check is expensive and should be skipped in production
+     101             : code. So, for instance, in the following case:
+     102             : \verbatim
+     103             :   plumed_dbg_assert(expensive_function(i)>0)<<"message";
+     104             : \endverbatim
+     105             : `expensive_function()` is not called in the production code.
+     106             : Notice that the compiler should be able to completely optimize away the
+     107             : whole statement including functions used to produce the message as in this example:
+     108             : \verbatim
+     109             :   plumed_dbg_assert(expensive_function(i)>0)<<"I did this check "<<other_expensive_function(i);
+     110             : \endverbatim
+     111             : 
+     112             : Finally, notice that there is another macro available, \ref plumed_here.
+     113             : In can be used in order to create an exception with information about the
+     114             : line/file coordinates without trowing it. That is, the two following syntaxes
+     115             : are equivalent
+     116             : \verbatim
+     117             : // First way, all at once
+     118             : plumed_error()<<"some message";
+     119             : /////////////////////////////////
+     120             : // Second way, one step at a time
+     121             : // Create exception
+     122             : Exception e;
+     123             : // Append information about line and file
+     124             : e<<plumed_here;
+     125             : // Append some other message
+     126             : e<<"some message";
+     127             : // Throw the resulting exception
+     128             : throw e;
+     129             : \endverbatim
+     130             : 
+     131             : Exceptions can be caught within plumed or outside of it.
+     132             : E.g., in an external c++ code using PLUMED as a library, one can type
+     133             : \verbatim
+     134             :   try{
+     135             :     plumed.cmd("setPrecision",n);
+     136             :   } catch (const std::exception & e) {
+     137             :     std::printf("ee %s",e.what());
+     138             :     exit(1);
+     139             :   }
+     140             : \endverbatim
+     141             : This can be useful if an external code wants to exit in a controlled manner
+     142             : (e.g. flushing files, printing the error message in a specific file, etc.)
+     143             : but is anyway limited to c++ codes. Moreover,
+     144             : since these errors are expected to be unrecoverable, the MD code will
+     145             : usually not be able to do something more clever than exiting.
+     146             : 
+     147             : \note
+     148             : We store message and stack trace in growing strings. This is in
+     149             : principle not recommended, since copying the exception might fail if
+     150             : copying the string throw another exception. However, this has been like
+     151             : this in all previous PLUMED versions. In case it is necessary, we can replace
+     152             : it later with a fixed size array placed on the stack.
+     153             : 
+     154             : */
+     155             : class Exception : public std::exception
+     156             : {
+     157             : /// Reported message. Can be updated.
+     158             :   std::string msg;
+     159             : /// Flag to remember if we have to write the `+++ message follows +++` string.
+     160             : /// Needed so that the string appears only at the beginning of the message.
+     161             :   bool note=true;
+     162             : /// Stream used to insert objects.
+     163             : /// It is not copied when the Exception is copied.
+     164             :   std::stringstream stream;
+     165             : /// Stack trace, computed at construction
+     166             :   std::array<void*,128> callstack;
+     167             : /// Number of frames in stack, computed at construction
+     168             :   int callstack_n=0;
+     169             : /// Parsed stack trace. Built at first use, thus mutable.
+     170             :   mutable std::string stackTrace;
+     171             : 
+     172             : public:
+     173             : 
+     174             : /// Auxiliary containing the location of the exception in the file.
+     175             : /// Typically used from the macros below.
+     176             :   class Location {
+     177             :   public:
+     178             :     const char*file;
+     179             :     const unsigned line;
+     180             :     const char* pretty;
+     181          56 :     explicit Location(const char*file,unsigned line,const char* pretty=nullptr):
+     182          56 :       file(file),
+     183          56 :       line(line),
+     184          56 :       pretty(pretty)
+     185             :     {}
+     186             :   };
+     187             : 
+     188             : /// Auxiliary containing the failed assertion.
+     189             : /// Typically used from the macros below.
+     190             :   class Assertion {
+     191             :   public:
+     192             :     const char*assertion;
+     193          12 :     explicit Assertion(const char*assertion=nullptr):
+     194          12 :       assertion(assertion)
+     195             :     {}
+     196             :   };
+     197             : 
+     198             : /// Auxiliary class used to throw exceptions.
+     199             : /// It just defines <<= operator so that:
+     200             : /// - exceptions can be thrown calling std::throw_with_nested
+     201             : ///   with a "throw like" syntax
+     202             : /// - precedence is the same as the throw operator
+     203             : /// (see https://en.cppreference.com/w/cpp/language/operator_precedence)
+     204             :   class Throw {
+     205             :   public:
+     206             :     template <typename E>
+     207           2 :     [[noreturn]] void operator <<=(E&&e) {
+     208           4 :       if(std::current_exception()) {
+     209           2 :         std::throw_with_nested(e);
+     210             :       } else {
+     211             :         // if not nested, avoid modifying the exception type
+     212           0 :         throw e;
+     213             :       }
+     214             :     }
+     215             :   };
+     216             : 
+     217             : /// Default constructor with no message.
+     218             : /// Only records the stack trace.
+     219             :   Exception();
+     220             : 
+     221             : /// Constructor compatible with PLUMED <=2.4.
+     222          31 :   explicit Exception(const std::string & msg):
+     223          31 :     Exception()
+     224             :   {
+     225          31 :     *this << msg;
+     226          31 :   }
+     227             : 
+     228             : /// Copy constructor.
+     229             : /// Needed to make sure stream is not copied
+     230          26 :   Exception(const Exception & e):
+     231          26 :     msg(e.msg),
+     232          26 :     note(e.note),
+     233          26 :     callstack(e.callstack),
+     234          26 :     callstack_n(e.callstack_n),
+     235          26 :     stackTrace(e.stackTrace)
+     236             :   {
+     237          26 :   }
+     238             : 
+     239             : /// Assignment.
+     240             : /// Needed to make sure stream is not copied
+     241             :   Exception & operator=(const Exception & e) {
+     242             :     msg=e.msg;
+     243             :     note=e.note;
+     244             :     callstack=e.callstack;
+     245             :     callstack_n=e.callstack_n;
+     246             :     stackTrace=e.stackTrace;
+     247             :     stream.str("");
+     248             :     return *this;
+     249             :   }
+     250             : 
+     251             : /// Returns the error message.
+     252             : /// In case the environment variable PLUMED_STACK_TRACE was defined
+     253             : /// and equal to `yes` when the exception was raised,
+     254             : /// the error message will contain the stack trace as well.
+     255          39 :   const char* what() const noexcept override {return msg.c_str();}
+     256             : 
+     257             : /// Returns the stack trace as a string.
+     258             : /// This function is slow as it requires building a parsed string.
+     259             : /// If storing the stack for later usage, you might prefer to use trace().
+     260             :   const char* stack() const;
+     261             : 
+     262             : /// Returns the callstack.
+     263             :   const std::array<void*,128> & trace() const noexcept {return callstack;}
+     264             : 
+     265             : /// Returns the number of elements in the trace array
+     266             :   int trace_n() const noexcept {return callstack_n;}
+     267             : 
+     268             : /// Destructor should be defined and should not throw other exceptions
+     269          56 :   ~Exception() noexcept override {}
+     270             : 
+     271             : /// Insert location.
+     272             : /// Format the location properly.
+     273             :   Exception& operator<<(const Location&);
+     274             : 
+     275             : /// Insert assertion.
+     276             : /// Format the assertion properly
+     277             :   Exception& operator<<(const Assertion&);
+     278             : 
+     279             : /// Insert string.
+     280             : /// Append this string to the message.
+     281             :   Exception& operator<<(const std::string&);
+     282             : 
+     283             : /// Insert anything else.
+     284             : /// This allows to dump also other types (e.g. double, or even Vector).
+     285             : /// Anything that can be written on a stream can go here.
+     286             :   template<typename T>
+     287          61 :   Exception& operator<<(const T & x) {
+     288          61 :     stream<<x;
+     289          61 :     (*this)<<stream.str();
+     290          61 :     stream.str("");
+     291          61 :     return *this;
+     292             :   }
+     293             : };
+     294             : 
+     295             : /// Class representing a generic error
+     296         147 : class ExceptionError :
+     297             :   public Exception {
+     298             : public:
+     299           1 :   using Exception::Exception;
+     300             :   template<typename T>
+     301             :   ExceptionError& operator<<(const T & x) {
+     302          91 :     *static_cast<Exception*>(this) <<x;
+     303             :     return *this;
+     304             :   }
+     305             : };
+     306             : 
+     307             : /// Class representing a debug error (can only be thrown when using debug options)
+     308           0 : class ExceptionDebug :
+     309             :   public Exception {
+     310             : public:
+     311           1 :   using Exception::Exception;
+     312             :   template<typename T>
+     313             :   ExceptionDebug& operator<<(const T & x) {
+     314             :     *static_cast<Exception*>(this) <<x;
+     315             :     return *this;
+     316             :   }
+     317             : };
+     318             : 
+     319             : /// Class representing a type error in the PLMD::Plumed interface
+     320          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 if constexpr(false) gurarantees that the compiler will optimize away the assertion
+     385             : // We are not using an empty macro becasue the user may want to use the << operator
+     386             : 
+     387             : #define plumed_dbg_assert(test) if constexpr(false) plumed_assert(true)
+     388             : #define plumed_dbg_massert(test,msg) if constexpr(false) plumed_massert(true,msg)
+     389             : 
+     390             : #else
+     391             : 
+     392             : /// \relates PLMD::Exception
+     393             : /// Same as \ref plumed_assert, but only evaluates the condition if NDEBUG is not defined.
+     394             : #define plumed_dbg_assert(test) if(!(test)) PLMD::Exception::Throw() <<= PLMD::ExceptionDebug() << plumed_here << PLMD::Exception::Assertion(#test) << "(this check is enabled only in debug builds)\n"
+     395             : 
+     396             : /// \relates PLMD::Exception
+     397             : /// Same as \ref plumed_massert, but only evaluates the condition if NDEBUG is not defined.
+     398             : #define plumed_dbg_massert(test,msg) plumed_dbg_assert(test) << msg
+     399             : 
+     400             : #endif
+     401             : 
+     402             : }
+     403             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/FileBase.cpp.func-sort-c.html b/coverage/tools/FileBase.cpp.func-sort-c.html new file mode 100644 index 000000000000..0b5811c0bfb1 --- /dev/null +++ b/coverage/tools/FileBase.cpp.func-sort-c.html @@ -0,0 +1,133 @@ + + + + + + + + LCOV - plumed test coverage - tools/FileBase.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - FileBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:8080100.0 %
Date:2024-04-19 12:12:35Functions:141593.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8FileBaseD0Ev0
_ZN4PLMD8FileBase13enforceSuffixERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE258
_ZN4PLMD8FileBase5closeEv984
_ZN4PLMD8FileBase4linkEP8_IO_FILE1154
_ZN4PLMD8FileBase9FileExistERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1982
_ZN4PLMD8FileBase4linkERNS_6ActionE4178
_ZN4PLMD8FileBase4linkERNS_10PlumedMainE5190
_ZN4PLMD8FileBase5flushEv5472
_ZNK4PLMD8FileBase9getSuffixB5cxx11Ev5894
_ZN4PLMD8FileBase12appendSuffixERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_7089
_ZN4PLMD8FileBase4linkERNS_12CommunicatorE811775
_ZN4PLMD8FileBaseC2Ev813165
_ZN4PLMD8FileBaseD2Ev813165
_ZN4PLMD8FileBase6isOpenEv813830
_ZNK4PLMD8FileBasecvbEv31271684
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/FileBase.cpp.func.html b/coverage/tools/FileBase.cpp.func.html new file mode 100644 index 000000000000..0535f83e43ae --- /dev/null +++ b/coverage/tools/FileBase.cpp.func.html @@ -0,0 +1,133 @@ + + + + + + + + LCOV - plumed test coverage - tools/FileBase.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - FileBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:8080100.0 %
Date:2024-04-19 12:12:35Functions:141593.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8FileBase12appendSuffixERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_7089
_ZN4PLMD8FileBase13enforceSuffixERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE258
_ZN4PLMD8FileBase4linkEP8_IO_FILE1154
_ZN4PLMD8FileBase4linkERNS_10PlumedMainE5190
_ZN4PLMD8FileBase4linkERNS_12CommunicatorE811775
_ZN4PLMD8FileBase4linkERNS_6ActionE4178
_ZN4PLMD8FileBase5closeEv984
_ZN4PLMD8FileBase5flushEv5472
_ZN4PLMD8FileBase6isOpenEv813830
_ZN4PLMD8FileBase9FileExistERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1982
_ZN4PLMD8FileBaseC2Ev813165
_ZN4PLMD8FileBaseD0Ev0
_ZN4PLMD8FileBaseD2Ev813165
_ZNK4PLMD8FileBase9getSuffixB5cxx11Ev5894
_ZNK4PLMD8FileBasecvbEv31271684
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/FileBase.cpp.gcov.html b/coverage/tools/FileBase.cpp.gcov.html new file mode 100644 index 000000000000..a02018bebdca --- /dev/null +++ b/coverage/tools/FileBase.cpp.gcov.html @@ -0,0 +1,252 @@ + + + + + + + + LCOV - plumed test coverage - tools/FileBase.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - FileBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:8080100.0 %
Date:2024-04-19 12:12:35Functions: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        1154 : FileBase& FileBase::link(FILE*fp) {
+      43        1154 :   plumed_massert(!this->fp,"cannot link an already open file");
+      44        1154 :   this->fp=fp;
+      45        1154 :   cloned=true;
+      46        1154 :   return *this;
+      47             : }
+      48             : 
+      49        5472 : FileBase& FileBase::flush() {
+      50        5472 :   if(fp) fflush(fp);
+      51        5472 :   return *this;
+      52             : }
+      53             : 
+      54      811775 : FileBase& FileBase::link(Communicator&comm) {
+      55      811775 :   plumed_massert(!fp,"cannot link an already open file");
+      56      811775 :   this->comm=&comm;
+      57      811775 :   return *this;
+      58             : }
+      59             : 
+      60        5190 : FileBase& FileBase::link(PlumedMain&plumed) {
+      61        5190 :   plumed_massert(!fp,"cannot link an already open file");
+      62        5190 :   this->plumed=&plumed;
+      63        5190 :   link(plumed.comm);
+      64        5190 :   return *this;
+      65             : }
+      66             : 
+      67        4178 : FileBase& FileBase::link(Action&action) {
+      68        4178 :   plumed_massert(!fp,"cannot link an already open file");
+      69        4178 :   this->action=&action;
+      70        4178 :   link(action.plumed);
+      71        4178 :   return *this;
+      72             : }
+      73             : 
+      74        1982 : bool FileBase::FileExist(const std::string& path) {
+      75             :   bool do_exist=false;
+      76        3964 :   this->path=appendSuffix(path,getSuffix());
+      77        1982 :   mode="r";
+      78             :   // first try with suffix
+      79        1982 :   FILE *ff=std::fopen(const_cast<char*>(this->path.c_str()),"r");
+      80             : // call fclose when ff goes out of scope
+      81        1480 :   auto deleter=[](auto f) { if(f) std::fclose(f); };
+      82             :   std::unique_ptr<FILE,decltype(deleter)> fp_deleter(ff,deleter);
+      83             : 
+      84        1982 :   if(!ff) {
+      85             :     this->path=path;
+      86             :     // then try without suffic
+      87         502 :     ff=std::fopen(const_cast<char*>(this->path.c_str()),"r");
+      88             :     mode="r";
+      89             :   }
+      90        1982 :   if(ff) do_exist=true;
+      91        1982 :   if(comm) comm->Barrier();
+      92        1982 :   return do_exist;
+      93             : }
+      94             : 
+      95      813830 : bool FileBase::isOpen() {
+      96             :   bool isopen=false;
+      97      813830 :   if(fp) isopen=true;
+      98      813830 :   return isopen;
+      99             : }
+     100             : 
+     101         984 : void        FileBase::close() {
+     102         984 :   plumed_assert(!cloned);
+     103         984 :   eof=false;
+     104         984 :   err=false;
+     105         984 :   if(fp)   std::fclose(fp);
+     106             : #ifdef __PLUMED_HAS_ZLIB
+     107         984 :   if(gzfp) gzclose(gzFile(gzfp));
+     108             : #endif
+     109         984 :   fp=NULL;
+     110         984 :   gzfp=NULL;
+     111         984 : }
+     112             : 
+     113      813165 : FileBase::FileBase():
+     114      813165 :   fp(NULL),
+     115      813165 :   gzfp(NULL),
+     116      813165 :   comm(NULL),
+     117      813165 :   plumed(NULL),
+     118      813165 :   action(NULL),
+     119      813165 :   cloned(false),
+     120      813165 :   eof(false),
+     121      813165 :   err(false),
+     122      813165 :   heavyFlush(false),
+     123      813165 :   enforcedSuffix_(false)
+     124             : {
+     125      813165 : }
+     126             : 
+     127      813165 : FileBase::~FileBase()
+     128             : {
+     129      813165 :   if(plumed) plumed->eraseFile(*this);
+     130      813165 :   if(!cloned && fp)   std::fclose(fp);
+     131             : #ifdef __PLUMED_HAS_ZLIB
+     132      813165 :   if(!cloned && gzfp) gzclose(gzFile(gzfp));
+     133             : #endif
+     134      813165 : }
+     135             : 
+     136    31271684 : FileBase::operator bool()const {
+     137    31271684 :   return !eof;
+     138             : }
+     139             : 
+     140        7089 : std::string FileBase::appendSuffix(const std::string&path,const std::string&suffix) {
+     141        7089 :   if(path=="/dev/null") return path; // do not append a suffix to /dev/null
+     142        6914 :   std::string ret=path;
+     143        6914 :   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        6914 :   if(ext.length()>0) {
+     154        4911 :     int l=path.length()-(ext.length()+1);
+     155        4911 :     plumed_assert(l>=0);
+     156        4911 :     ret.resize(l);
+     157             :   }
+     158             :   ret+=suffix;
+     159       11825 :   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        5894 : std::string FileBase::getSuffix()const {
+     170        5894 :   if(enforcedSuffix_) return enforcedSuffix;
+     171        5630 :   if(plumed) return plumed->getSuffix();
+     172         571 :   return "";
+     173             : }
+     174             : 
+     175             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/FileBase.h.func-sort-c.html b/coverage/tools/FileBase.h.func-sort-c.html new file mode 100644 index 000000000000..fb3c4803d84a --- /dev/null +++ b/coverage/tools/FileBase.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage - tools/FileBase.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - FileBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:66100.0 %
Date:2024-04-19 12:12:35Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/FileBase.h.func.html b/coverage/tools/FileBase.h.func.html new file mode 100644 index 000000000000..3368a666d7e6 --- /dev/null +++ b/coverage/tools/FileBase.h.func.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage - tools/FileBase.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - FileBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:66100.0 %
Date:2024-04-19 12:12:35Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/FileBase.h.gcov.html b/coverage/tools/FileBase.h.gcov.html new file mode 100644 index 000000000000..57dcbe5f5739 --- /dev/null +++ b/coverage/tools/FileBase.h.gcov.html @@ -0,0 +1,229 @@ + + + + + + + + LCOV - plumed test coverage - tools/FileBase.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - FileBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:66100.0 %
Date:2024-04-19 12:12:35Functions: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    17671542 :   class FieldBase {
+      48             : // everything is public to simplify usage
+      49             :   public:
+      50             :     std::string name;
+      51             :     std::string value;
+      52             :     bool constant;
+      53    16382968 :     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         633 :   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         856 :   return path;
+     138             : }
+     139             : 
+     140             : inline
+     141             : std::string FileBase::getMode()const {
+     142         205 :   return mode;
+     143             : }
+     144             : 
+     145             : inline
+     146             : FILE* FileBase::getFILE()const {
+     147          18 :   return fp;
+     148             : }
+     149             : 
+     150             : }
+     151             : 
+     152             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/ForwardDecl.h.func-sort-c.html b/coverage/tools/ForwardDecl.h.func-sort-c.html new file mode 100644 index 000000000000..64aa92ad36eb --- /dev/null +++ b/coverage/tools/ForwardDecl.h.func-sort-c.html @@ -0,0 +1,125 @@ + + + + + + + + LCOV - plumed test coverage - tools/ForwardDecl.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - ForwardDecl.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:44100.0 %
Date:2024-04-19 12:12:35Functions:1313100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11ForwardDeclINS_9StopwatchEEC2IJEEEDpOT_12
_ZN4PLMD11ForwardDeclINS_3PDBEEC2IJEEEDpOT_91
_ZN4PLMD11ForwardDeclINS_3PbcEEC2IJEEEDpOT_19138
_ZN4PLMD11ForwardDeclINS_10PlumedMain15DeprecatedAtomsEEC2IJRS1_EEEDpOT_806370
_ZN4PLMD11ForwardDeclINS_11TypesafePtrEEC2IJEEEDpOT_806370
_ZN4PLMD11ForwardDeclINS_16ExchangePatternsEEC2IJEEEDpOT_806370
_ZN4PLMD11ForwardDeclINS_3LogEEC2IJEEEDpOT_806370
_ZN4PLMD11ForwardDeclINS_6RandomEEC2IJEEEDpOT_806370
_ZN4PLMD11ForwardDeclINS_8DLLoaderEEC2IJEEEDpOT_806370
_ZN4PLMD11ForwardDeclINS_9ActionSetEEC2IJRNS_10PlumedMainEEEEDpOT_806370
_ZN4PLMD11ForwardDeclINS_9CitationsEEC2IJEEEDpOT_806370
_ZN4PLMD11ForwardDeclINS_9StopwatchEEC2IJRNS_3LogEEEEDpOT_806370
_ZN4PLMD11ForwardDeclINS_12CommunicatorEEC2IJEEEDpOT_1618288
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/ForwardDecl.h.func.html b/coverage/tools/ForwardDecl.h.func.html new file mode 100644 index 000000000000..63b3d05f7661 --- /dev/null +++ b/coverage/tools/ForwardDecl.h.func.html @@ -0,0 +1,125 @@ + + + + + + + + LCOV - plumed test coverage - tools/ForwardDecl.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - ForwardDecl.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:44100.0 %
Date:2024-04-19 12:12:35Functions:1313100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11ForwardDeclINS_10PlumedMain15DeprecatedAtomsEEC2IJRS1_EEEDpOT_806370
_ZN4PLMD11ForwardDeclINS_11TypesafePtrEEC2IJEEEDpOT_806370
_ZN4PLMD11ForwardDeclINS_12CommunicatorEEC2IJEEEDpOT_1618288
_ZN4PLMD11ForwardDeclINS_16ExchangePatternsEEC2IJEEEDpOT_806370
_ZN4PLMD11ForwardDeclINS_3LogEEC2IJEEEDpOT_806370
_ZN4PLMD11ForwardDeclINS_3PDBEEC2IJEEEDpOT_91
_ZN4PLMD11ForwardDeclINS_3PbcEEC2IJEEEDpOT_19138
_ZN4PLMD11ForwardDeclINS_6RandomEEC2IJEEEDpOT_806370
_ZN4PLMD11ForwardDeclINS_8DLLoaderEEC2IJEEEDpOT_806370
_ZN4PLMD11ForwardDeclINS_9ActionSetEEC2IJRNS_10PlumedMainEEEEDpOT_806370
_ZN4PLMD11ForwardDeclINS_9CitationsEEC2IJEEEDpOT_806370
_ZN4PLMD11ForwardDeclINS_9StopwatchEEC2IJEEEDpOT_12
_ZN4PLMD11ForwardDeclINS_9StopwatchEEC2IJRNS_3LogEEEEDpOT_806370
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/ForwardDecl.h.gcov.html b/coverage/tools/ForwardDecl.h.gcov.html new file mode 100644 index 000000000000..5798028f69dc --- /dev/null +++ b/coverage/tools/ForwardDecl.h.gcov.html @@ -0,0 +1,132 @@ + + + + + + + + LCOV - plumed test coverage - tools/ForwardDecl.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - ForwardDecl.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:44100.0 %
Date:2024-04-19 12:12:35Functions: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     3248962 : 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     8894859 : ForwardDecl<T>::ForwardDecl(Args &&...args):
+      49     8088489 :   std::unique_ptr<T>(std::make_unique<T>(std::forward<Args>(args)...))
+      50     8894859 : {}
+      51             : 
+      52             : 
+      53             : }
+      54             : 
+      55             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Grid.cpp.func-sort-c.html b/coverage/tools/Grid.cpp.func-sort-c.html new file mode 100644 index 000000000000..fb3efec045b8 --- /dev/null +++ b/coverage/tools/Grid.cpp.func-sort-c.html @@ -0,0 +1,713 @@ + + + + + + + + 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:42060569.4 %
Date:2024-04-19 12:12:35Functions:6016037.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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
_ZNK4PLMD11AcceleratorILj10EE10getIndicesERKSt6vectorIdSaIdEES6_S6_Pjm0
_ZNK4PLMD11AcceleratorILj10EE10getIndicesERKSt6vectorIjSaIjEEmPjm0
_ZNK4PLMD11AcceleratorILj10EE12getDimensionEv0
_ZNK4PLMD11AcceleratorILj10EE12getNeighborsERKNS_8GridBaseERKSt6vectorIjSaIjEERKS5_IbSaIbEEPKjmS9_0
_ZNK4PLMD11AcceleratorILj10EE8getIndexERKNS_8GridBaseERKSt6vectorIjSaIjEEPKjm0
_ZNK4PLMD11AcceleratorILj10EE8getPointERKSt6vectorIdSaIdEES6_PKjmPdm0
_ZNK4PLMD11AcceleratorILj11EE10getIndicesERKSt6vectorIdSaIdEES6_S6_Pjm0
_ZNK4PLMD11AcceleratorILj11EE10getIndicesERKSt6vectorIjSaIjEEmPjm0
_ZNK4PLMD11AcceleratorILj11EE12getDimensionEv0
_ZNK4PLMD11AcceleratorILj11EE12getNeighborsERKNS_8GridBaseERKSt6vectorIjSaIjEERKS5_IbSaIbEEPKjmS9_0
_ZNK4PLMD11AcceleratorILj11EE8getIndexERKNS_8GridBaseERKSt6vectorIjSaIjEEPKjm0
_ZNK4PLMD11AcceleratorILj11EE8getPointERKSt6vectorIdSaIdEES6_PKjmPdm0
_ZNK4PLMD11AcceleratorILj12EE10getIndicesERKSt6vectorIdSaIdEES6_S6_Pjm0
_ZNK4PLMD11AcceleratorILj12EE10getIndicesERKSt6vectorIjSaIjEEmPjm0
_ZNK4PLMD11AcceleratorILj12EE12getDimensionEv0
_ZNK4PLMD11AcceleratorILj12EE12getNeighborsERKNS_8GridBaseERKSt6vectorIjSaIjEERKS5_IbSaIbEEPKjmS9_0
_ZNK4PLMD11AcceleratorILj12EE8getIndexERKNS_8GridBaseERKSt6vectorIjSaIjEEPKjm0
_ZNK4PLMD11AcceleratorILj12EE8getPointERKSt6vectorIdSaIdEES6_PKjmPdm0
_ZNK4PLMD11AcceleratorILj13EE10getIndicesERKSt6vectorIdSaIdEES6_S6_Pjm0
_ZNK4PLMD11AcceleratorILj13EE10getIndicesERKSt6vectorIjSaIjEEmPjm0
_ZNK4PLMD11AcceleratorILj13EE12getDimensionEv0
_ZNK4PLMD11AcceleratorILj13EE12getNeighborsERKNS_8GridBaseERKSt6vectorIjSaIjEERKS5_IbSaIbEEPKjmS9_0
_ZNK4PLMD11AcceleratorILj13EE8getIndexERKNS_8GridBaseERKSt6vectorIjSaIjEEPKjm0
_ZNK4PLMD11AcceleratorILj13EE8getPointERKSt6vectorIdSaIdEES6_PKjmPdm0
_ZNK4PLMD11AcceleratorILj14EE10getIndicesERKSt6vectorIdSaIdEES6_S6_Pjm0
_ZNK4PLMD11AcceleratorILj14EE10getIndicesERKSt6vectorIjSaIjEEmPjm0
_ZNK4PLMD11AcceleratorILj14EE12getDimensionEv0
_ZNK4PLMD11AcceleratorILj14EE12getNeighborsERKNS_8GridBaseERKSt6vectorIjSaIjEERKS5_IbSaIbEEPKjmS9_0
_ZNK4PLMD11AcceleratorILj14EE8getIndexERKNS_8GridBaseERKSt6vectorIjSaIjEEPKjm0
_ZNK4PLMD11AcceleratorILj14EE8getPointERKSt6vectorIdSaIdEES6_PKjmPdm0
_ZNK4PLMD11AcceleratorILj15EE10getIndicesERKSt6vectorIdSaIdEES6_S6_Pjm0
_ZNK4PLMD11AcceleratorILj15EE10getIndicesERKSt6vectorIjSaIjEEmPjm0
_ZNK4PLMD11AcceleratorILj15EE12getDimensionEv0
_ZNK4PLMD11AcceleratorILj15EE12getNeighborsERKNS_8GridBaseERKSt6vectorIjSaIjEERKS5_IbSaIbEEPKjmS9_0
_ZNK4PLMD11AcceleratorILj15EE8getIndexERKNS_8GridBaseERKSt6vectorIjSaIjEEPKjm0
_ZNK4PLMD11AcceleratorILj15EE8getPointERKSt6vectorIdSaIdEES6_PKjmPdm0
_ZNK4PLMD11AcceleratorILj16EE10getIndicesERKSt6vectorIdSaIdEES6_S6_Pjm0
_ZNK4PLMD11AcceleratorILj16EE10getIndicesERKSt6vectorIjSaIjEEmPjm0
_ZNK4PLMD11AcceleratorILj16EE12getDimensionEv0
_ZNK4PLMD11AcceleratorILj16EE12getNeighborsERKNS_8GridBaseERKSt6vectorIjSaIjEERKS5_IbSaIbEEPKjmS9_0
_ZNK4PLMD11AcceleratorILj16EE8getIndexERKNS_8GridBaseERKSt6vectorIjSaIjEEPKjm0
_ZNK4PLMD11AcceleratorILj16EE8getPointERKSt6vectorIdSaIdEES6_PKjmPdm0
_ZNK4PLMD11AcceleratorILj3EE10getIndicesERKSt6vectorIdSaIdEES6_S6_Pjm0
_ZNK4PLMD11AcceleratorILj3EE12getNeighborsERKNS_8GridBaseERKSt6vectorIjSaIjEERKS5_IbSaIbEEPKjmS9_0
_ZNK4PLMD11AcceleratorILj4EE10getIndicesERKSt6vectorIdSaIdEES6_S6_Pjm0
_ZNK4PLMD11AcceleratorILj4EE10getIndicesERKSt6vectorIjSaIjEEmPjm0
_ZNK4PLMD11AcceleratorILj4EE12getDimensionEv0
_ZNK4PLMD11AcceleratorILj4EE12getNeighborsERKNS_8GridBaseERKSt6vectorIjSaIjEERKS5_IbSaIbEEPKjmS9_0
_ZNK4PLMD11AcceleratorILj4EE8getIndexERKNS_8GridBaseERKSt6vectorIjSaIjEEPKjm0
_ZNK4PLMD11AcceleratorILj4EE8getPointERKSt6vectorIdSaIdEES6_PKjmPdm0
_ZNK4PLMD11AcceleratorILj5EE10getIndicesERKSt6vectorIdSaIdEES6_S6_Pjm0
_ZNK4PLMD11AcceleratorILj5EE10getIndicesERKSt6vectorIjSaIjEEmPjm0
_ZNK4PLMD11AcceleratorILj5EE12getDimensionEv0
_ZNK4PLMD11AcceleratorILj5EE12getNeighborsERKNS_8GridBaseERKSt6vectorIjSaIjEERKS5_IbSaIbEEPKjmS9_0
_ZNK4PLMD11AcceleratorILj5EE8getIndexERKNS_8GridBaseERKSt6vectorIjSaIjEEPKjm0
_ZNK4PLMD11AcceleratorILj5EE8getPointERKSt6vectorIdSaIdEES6_PKjmPdm0
_ZNK4PLMD11AcceleratorILj6EE10getIndicesERKSt6vectorIdSaIdEES6_S6_Pjm0
_ZNK4PLMD11AcceleratorILj6EE10getIndicesERKSt6vectorIjSaIjEEmPjm0
_ZNK4PLMD11AcceleratorILj6EE12getDimensionEv0
_ZNK4PLMD11AcceleratorILj6EE12getNeighborsERKNS_8GridBaseERKSt6vectorIjSaIjEERKS5_IbSaIbEEPKjmS9_0
_ZNK4PLMD11AcceleratorILj6EE8getIndexERKNS_8GridBaseERKSt6vectorIjSaIjEEPKjm0
_ZNK4PLMD11AcceleratorILj6EE8getPointERKSt6vectorIdSaIdEES6_PKjmPdm0
_ZNK4PLMD11AcceleratorILj7EE10getIndicesERKSt6vectorIdSaIdEES6_S6_Pjm0
_ZNK4PLMD11AcceleratorILj7EE10getIndicesERKSt6vectorIjSaIjEEmPjm0
_ZNK4PLMD11AcceleratorILj7EE12getDimensionEv0
_ZNK4PLMD11AcceleratorILj7EE12getNeighborsERKNS_8GridBaseERKSt6vectorIjSaIjEERKS5_IbSaIbEEPKjmS9_0
_ZNK4PLMD11AcceleratorILj7EE8getIndexERKNS_8GridBaseERKSt6vectorIjSaIjEEPKjm0
_ZNK4PLMD11AcceleratorILj7EE8getPointERKSt6vectorIdSaIdEES6_PKjmPdm0
_ZNK4PLMD11AcceleratorILj8EE10getIndicesERKSt6vectorIdSaIdEES6_S6_Pjm0
_ZNK4PLMD11AcceleratorILj8EE10getIndicesERKSt6vectorIjSaIjEEmPjm0
_ZNK4PLMD11AcceleratorILj8EE12getDimensionEv0
_ZNK4PLMD11AcceleratorILj8EE12getNeighborsERKNS_8GridBaseERKSt6vectorIjSaIjEERKS5_IbSaIbEEPKjmS9_0
_ZNK4PLMD11AcceleratorILj8EE8getIndexERKNS_8GridBaseERKSt6vectorIjSaIjEEPKjm0
_ZNK4PLMD11AcceleratorILj8EE8getPointERKSt6vectorIdSaIdEES6_PKjmPdm0
_ZNK4PLMD11AcceleratorILj9EE10getIndicesERKSt6vectorIdSaIdEES6_S6_Pjm0
_ZNK4PLMD11AcceleratorILj9EE10getIndicesERKSt6vectorIjSaIjEEmPjm0
_ZNK4PLMD11AcceleratorILj9EE12getDimensionEv0
_ZNK4PLMD11AcceleratorILj9EE12getNeighborsERKNS_8GridBaseERKSt6vectorIjSaIjEERKS5_IbSaIbEEPKjmS9_0
_ZNK4PLMD11AcceleratorILj9EE8getIndexERKNS_8GridBaseERKSt6vectorIjSaIjEEPKjm0
_ZNK4PLMD11AcceleratorILj9EE8getPointERKSt6vectorIdSaIdEES6_PKjmPdm0
_ZNK4PLMD4Grid24getDifferenceFromContourERKSt6vectorIdSaIdEERS3_0
_ZNK4PLMD8GridBase19getNearestNeighborsERKSt6vectorIjSaIjEE0
_ZN4PLMD4Grid36applyFunctionAllValuesAndDerivativesEPFddES2_1
_ZN4PLMD4Grid5clearEv1
_ZN4PLMD4Grid8addValueEmd1
_ZNK4PLMD11AcceleratorILj3EE12getDimensionEv4
_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
_ZNK4PLMD10SparseGrid22getValueAndDerivativesEmPdm200
_ZN4PLMD8GridBase22findMaximalPathMinimumERKSt6vectorIdSaIdEES5_273
_ZNK4PLMD11AcceleratorILj2EE12getDimensionEv287
_ZNK4PLMD8GridBase6getMaxB5cxx11Ev343
_ZNK4PLMD8GridBase8getValueERKSt6vectorIdSaIdEE345
_ZNK4PLMD11AcceleratorILj1EE12getNeighborsERKNS_8GridBaseERKSt6vectorIjSaIjEERKS5_IbSaIbEEPKjmS9_500
_ZN4PLMD4Grid28scaleAllValuesAndDerivativesERKd594
_ZNK4PLMD4Grid11getMaxValueEv629
_ZNK4PLMD4Grid11getMinValueEv861
_ZN4PLMD4Grid11writeToFileERNS_5OFileE1147
_ZN4PLMD8GridBase11writeHeaderERNS_5OFileE1147
_ZNK4PLMD11AcceleratorILj1EE12getDimensionEv1213
_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
_ZN4PLMD8GridBase15AcceleratorBase6createEj2959
_ZNK4PLMD8GridBase18getSplineNeighborsEPKjmPmm3711
_ZNK4PLMD8GridBase22getValueAndDerivativesERKSt6vectorIdSaIdEERS3_3711
_ZNK4PLMD11AcceleratorILj1EE10getIndicesERKSt6vectorIdSaIdEES6_S6_Pjm7740
_ZNK4PLMD8GridBase11getArgNamesB5cxx11Ev9436
_ZNK4PLMD8GridBase19getNearestNeighborsEm9577
_ZNK4PLMD8GridBase5getDxEm11890
_ZN4PLMD10SparseGrid22addValueAndDerivativesEmdRSt6vectorIdSaIdEE19999
_ZNK4PLMD11AcceleratorILj2EE12getNeighborsERKNS_8GridBaseERKSt6vectorIjSaIjEERKS5_IbSaIbEEPKjmS9_22864
_ZN4PLMD10indexed_ltERKSt4pairImdES3_59573
_ZNK4PLMD11AcceleratorILj3EE8getIndexERKNS_8GridBaseERKSt6vectorIjSaIjEEPKjm436350
_ZNK4PLMD11AcceleratorILj1EE10getIndicesERKSt6vectorIjSaIjEEmPjm835428
_ZN4PLMD4Grid21projectOnLowDimensionERdRSt6vectorIiSaIiEEPNS_10WeightBaseE1010062
_ZNK4PLMD8GridBase7getNbinEv1012510
_ZNK4PLMD11AcceleratorILj2EE10getIndicesERKSt6vectorIdSaIdEES6_S6_Pjm1100252
_ZN4PLMD4Grid22addValueAndDerivativesEmdRSt6vectorIdSaIdEE1171742
_ZNK4PLMD8GridBase8getValueERKSt6vectorIjSaIjEE1193613
_ZNK4PLMD8GridBase5getDxEv1319573
_ZNK4PLMD8GridBase6getMinB5cxx11Ev1360394
_ZNK4PLMD8GridBase22getValueAndDerivativesERKSt6vectorIjSaIjEERS1_IdSaIdEE2527708
_ZN4PLMD4Grid22setValueAndDerivativesEmdRSt6vectorIdSaIdEE2552369
_ZNK4PLMD11AcceleratorILj1EE8getIndexERKNS_8GridBaseERKSt6vectorIjSaIjEEPKjm2554415
_ZNK4PLMD11AcceleratorILj1EE8getPointERKSt6vectorIdSaIdEES6_PKjmPdm3025877
_ZNK4PLMD8GridBase22getValueAndDerivativesEmRSt6vectorIdSaIdEE3071066
_ZNK4PLMD4Grid22getValueAndDerivativesEmPdm3079776
_ZNK4PLMD11AcceleratorILj2EE8getIndexERKNS_8GridBaseERKSt6vectorIjSaIjEEPKjm4155034
_ZN4PLMD4Grid8setValueEmd6444104
_ZNK4PLMD11AcceleratorILj2EE8getPointERKSt6vectorIdSaIdEES6_PKjmPdm12783713
_ZNK4PLMD11AcceleratorILj3EE8getPointERKSt6vectorIdSaIdEES6_PKjmPdm16846842
_ZNK4PLMD11AcceleratorILj3EE10getIndicesERKSt6vectorIjSaIjEEmPjm16948709
_ZNK4PLMD8GridBase12getDimensionEv18321217
_ZNK4PLMD11AcceleratorILj2EE10getIndicesERKSt6vectorIjSaIjEEmPjm20054258
_ZNK4PLMD4Grid8getValueEm27284983
_ZNK4PLMD4Grid7getSizeEv28865222
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Grid.cpp.func.html b/coverage/tools/Grid.cpp.func.html new file mode 100644 index 000000000000..8ba3cc15a282 --- /dev/null +++ b/coverage/tools/Grid.cpp.func.html @@ -0,0 +1,713 @@ + + + + + + + + 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:42060569.4 %
Date:2024-04-19 12:12:35Functions:6016037.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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
_ZN4PLMD8GridBase15AcceleratorBase6createEj2959
_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
_ZNK4PLMD10SparseGrid22getValueAndDerivativesEmPdm200
_ZNK4PLMD10SparseGrid7getSizeEv0
_ZNK4PLMD10SparseGrid8getValueEm0
_ZNK4PLMD11AcceleratorILj10EE10getIndicesERKSt6vectorIdSaIdEES6_S6_Pjm0
_ZNK4PLMD11AcceleratorILj10EE10getIndicesERKSt6vectorIjSaIjEEmPjm0
_ZNK4PLMD11AcceleratorILj10EE12getDimensionEv0
_ZNK4PLMD11AcceleratorILj10EE12getNeighborsERKNS_8GridBaseERKSt6vectorIjSaIjEERKS5_IbSaIbEEPKjmS9_0
_ZNK4PLMD11AcceleratorILj10EE8getIndexERKNS_8GridBaseERKSt6vectorIjSaIjEEPKjm0
_ZNK4PLMD11AcceleratorILj10EE8getPointERKSt6vectorIdSaIdEES6_PKjmPdm0
_ZNK4PLMD11AcceleratorILj11EE10getIndicesERKSt6vectorIdSaIdEES6_S6_Pjm0
_ZNK4PLMD11AcceleratorILj11EE10getIndicesERKSt6vectorIjSaIjEEmPjm0
_ZNK4PLMD11AcceleratorILj11EE12getDimensionEv0
_ZNK4PLMD11AcceleratorILj11EE12getNeighborsERKNS_8GridBaseERKSt6vectorIjSaIjEERKS5_IbSaIbEEPKjmS9_0
_ZNK4PLMD11AcceleratorILj11EE8getIndexERKNS_8GridBaseERKSt6vectorIjSaIjEEPKjm0
_ZNK4PLMD11AcceleratorILj11EE8getPointERKSt6vectorIdSaIdEES6_PKjmPdm0
_ZNK4PLMD11AcceleratorILj12EE10getIndicesERKSt6vectorIdSaIdEES6_S6_Pjm0
_ZNK4PLMD11AcceleratorILj12EE10getIndicesERKSt6vectorIjSaIjEEmPjm0
_ZNK4PLMD11AcceleratorILj12EE12getDimensionEv0
_ZNK4PLMD11AcceleratorILj12EE12getNeighborsERKNS_8GridBaseERKSt6vectorIjSaIjEERKS5_IbSaIbEEPKjmS9_0
_ZNK4PLMD11AcceleratorILj12EE8getIndexERKNS_8GridBaseERKSt6vectorIjSaIjEEPKjm0
_ZNK4PLMD11AcceleratorILj12EE8getPointERKSt6vectorIdSaIdEES6_PKjmPdm0
_ZNK4PLMD11AcceleratorILj13EE10getIndicesERKSt6vectorIdSaIdEES6_S6_Pjm0
_ZNK4PLMD11AcceleratorILj13EE10getIndicesERKSt6vectorIjSaIjEEmPjm0
_ZNK4PLMD11AcceleratorILj13EE12getDimensionEv0
_ZNK4PLMD11AcceleratorILj13EE12getNeighborsERKNS_8GridBaseERKSt6vectorIjSaIjEERKS5_IbSaIbEEPKjmS9_0
_ZNK4PLMD11AcceleratorILj13EE8getIndexERKNS_8GridBaseERKSt6vectorIjSaIjEEPKjm0
_ZNK4PLMD11AcceleratorILj13EE8getPointERKSt6vectorIdSaIdEES6_PKjmPdm0
_ZNK4PLMD11AcceleratorILj14EE10getIndicesERKSt6vectorIdSaIdEES6_S6_Pjm0
_ZNK4PLMD11AcceleratorILj14EE10getIndicesERKSt6vectorIjSaIjEEmPjm0
_ZNK4PLMD11AcceleratorILj14EE12getDimensionEv0
_ZNK4PLMD11AcceleratorILj14EE12getNeighborsERKNS_8GridBaseERKSt6vectorIjSaIjEERKS5_IbSaIbEEPKjmS9_0
_ZNK4PLMD11AcceleratorILj14EE8getIndexERKNS_8GridBaseERKSt6vectorIjSaIjEEPKjm0
_ZNK4PLMD11AcceleratorILj14EE8getPointERKSt6vectorIdSaIdEES6_PKjmPdm0
_ZNK4PLMD11AcceleratorILj15EE10getIndicesERKSt6vectorIdSaIdEES6_S6_Pjm0
_ZNK4PLMD11AcceleratorILj15EE10getIndicesERKSt6vectorIjSaIjEEmPjm0
_ZNK4PLMD11AcceleratorILj15EE12getDimensionEv0
_ZNK4PLMD11AcceleratorILj15EE12getNeighborsERKNS_8GridBaseERKSt6vectorIjSaIjEERKS5_IbSaIbEEPKjmS9_0
_ZNK4PLMD11AcceleratorILj15EE8getIndexERKNS_8GridBaseERKSt6vectorIjSaIjEEPKjm0
_ZNK4PLMD11AcceleratorILj15EE8getPointERKSt6vectorIdSaIdEES6_PKjmPdm0
_ZNK4PLMD11AcceleratorILj16EE10getIndicesERKSt6vectorIdSaIdEES6_S6_Pjm0
_ZNK4PLMD11AcceleratorILj16EE10getIndicesERKSt6vectorIjSaIjEEmPjm0
_ZNK4PLMD11AcceleratorILj16EE12getDimensionEv0
_ZNK4PLMD11AcceleratorILj16EE12getNeighborsERKNS_8GridBaseERKSt6vectorIjSaIjEERKS5_IbSaIbEEPKjmS9_0
_ZNK4PLMD11AcceleratorILj16EE8getIndexERKNS_8GridBaseERKSt6vectorIjSaIjEEPKjm0
_ZNK4PLMD11AcceleratorILj16EE8getPointERKSt6vectorIdSaIdEES6_PKjmPdm0
_ZNK4PLMD11AcceleratorILj1EE10getIndicesERKSt6vectorIdSaIdEES6_S6_Pjm7740
_ZNK4PLMD11AcceleratorILj1EE10getIndicesERKSt6vectorIjSaIjEEmPjm835428
_ZNK4PLMD11AcceleratorILj1EE12getDimensionEv1213
_ZNK4PLMD11AcceleratorILj1EE12getNeighborsERKNS_8GridBaseERKSt6vectorIjSaIjEERKS5_IbSaIbEEPKjmS9_500
_ZNK4PLMD11AcceleratorILj1EE8getIndexERKNS_8GridBaseERKSt6vectorIjSaIjEEPKjm2554415
_ZNK4PLMD11AcceleratorILj1EE8getPointERKSt6vectorIdSaIdEES6_PKjmPdm3025877
_ZNK4PLMD11AcceleratorILj2EE10getIndicesERKSt6vectorIdSaIdEES6_S6_Pjm1100252
_ZNK4PLMD11AcceleratorILj2EE10getIndicesERKSt6vectorIjSaIjEEmPjm20054258
_ZNK4PLMD11AcceleratorILj2EE12getDimensionEv287
_ZNK4PLMD11AcceleratorILj2EE12getNeighborsERKNS_8GridBaseERKSt6vectorIjSaIjEERKS5_IbSaIbEEPKjmS9_22864
_ZNK4PLMD11AcceleratorILj2EE8getIndexERKNS_8GridBaseERKSt6vectorIjSaIjEEPKjm4155034
_ZNK4PLMD11AcceleratorILj2EE8getPointERKSt6vectorIdSaIdEES6_PKjmPdm12783713
_ZNK4PLMD11AcceleratorILj3EE10getIndicesERKSt6vectorIdSaIdEES6_S6_Pjm0
_ZNK4PLMD11AcceleratorILj3EE10getIndicesERKSt6vectorIjSaIjEEmPjm16948709
_ZNK4PLMD11AcceleratorILj3EE12getDimensionEv4
_ZNK4PLMD11AcceleratorILj3EE12getNeighborsERKNS_8GridBaseERKSt6vectorIjSaIjEERKS5_IbSaIbEEPKjmS9_0
_ZNK4PLMD11AcceleratorILj3EE8getIndexERKNS_8GridBaseERKSt6vectorIjSaIjEEPKjm436350
_ZNK4PLMD11AcceleratorILj3EE8getPointERKSt6vectorIdSaIdEES6_PKjmPdm16846842
_ZNK4PLMD11AcceleratorILj4EE10getIndicesERKSt6vectorIdSaIdEES6_S6_Pjm0
_ZNK4PLMD11AcceleratorILj4EE10getIndicesERKSt6vectorIjSaIjEEmPjm0
_ZNK4PLMD11AcceleratorILj4EE12getDimensionEv0
_ZNK4PLMD11AcceleratorILj4EE12getNeighborsERKNS_8GridBaseERKSt6vectorIjSaIjEERKS5_IbSaIbEEPKjmS9_0
_ZNK4PLMD11AcceleratorILj4EE8getIndexERKNS_8GridBaseERKSt6vectorIjSaIjEEPKjm0
_ZNK4PLMD11AcceleratorILj4EE8getPointERKSt6vectorIdSaIdEES6_PKjmPdm0
_ZNK4PLMD11AcceleratorILj5EE10getIndicesERKSt6vectorIdSaIdEES6_S6_Pjm0
_ZNK4PLMD11AcceleratorILj5EE10getIndicesERKSt6vectorIjSaIjEEmPjm0
_ZNK4PLMD11AcceleratorILj5EE12getDimensionEv0
_ZNK4PLMD11AcceleratorILj5EE12getNeighborsERKNS_8GridBaseERKSt6vectorIjSaIjEERKS5_IbSaIbEEPKjmS9_0
_ZNK4PLMD11AcceleratorILj5EE8getIndexERKNS_8GridBaseERKSt6vectorIjSaIjEEPKjm0
_ZNK4PLMD11AcceleratorILj5EE8getPointERKSt6vectorIdSaIdEES6_PKjmPdm0
_ZNK4PLMD11AcceleratorILj6EE10getIndicesERKSt6vectorIdSaIdEES6_S6_Pjm0
_ZNK4PLMD11AcceleratorILj6EE10getIndicesERKSt6vectorIjSaIjEEmPjm0
_ZNK4PLMD11AcceleratorILj6EE12getDimensionEv0
_ZNK4PLMD11AcceleratorILj6EE12getNeighborsERKNS_8GridBaseERKSt6vectorIjSaIjEERKS5_IbSaIbEEPKjmS9_0
_ZNK4PLMD11AcceleratorILj6EE8getIndexERKNS_8GridBaseERKSt6vectorIjSaIjEEPKjm0
_ZNK4PLMD11AcceleratorILj6EE8getPointERKSt6vectorIdSaIdEES6_PKjmPdm0
_ZNK4PLMD11AcceleratorILj7EE10getIndicesERKSt6vectorIdSaIdEES6_S6_Pjm0
_ZNK4PLMD11AcceleratorILj7EE10getIndicesERKSt6vectorIjSaIjEEmPjm0
_ZNK4PLMD11AcceleratorILj7EE12getDimensionEv0
_ZNK4PLMD11AcceleratorILj7EE12getNeighborsERKNS_8GridBaseERKSt6vectorIjSaIjEERKS5_IbSaIbEEPKjmS9_0
_ZNK4PLMD11AcceleratorILj7EE8getIndexERKNS_8GridBaseERKSt6vectorIjSaIjEEPKjm0
_ZNK4PLMD11AcceleratorILj7EE8getPointERKSt6vectorIdSaIdEES6_PKjmPdm0
_ZNK4PLMD11AcceleratorILj8EE10getIndicesERKSt6vectorIdSaIdEES6_S6_Pjm0
_ZNK4PLMD11AcceleratorILj8EE10getIndicesERKSt6vectorIjSaIjEEmPjm0
_ZNK4PLMD11AcceleratorILj8EE12getDimensionEv0
_ZNK4PLMD11AcceleratorILj8EE12getNeighborsERKNS_8GridBaseERKSt6vectorIjSaIjEERKS5_IbSaIbEEPKjmS9_0
_ZNK4PLMD11AcceleratorILj8EE8getIndexERKNS_8GridBaseERKSt6vectorIjSaIjEEPKjm0
_ZNK4PLMD11AcceleratorILj8EE8getPointERKSt6vectorIdSaIdEES6_PKjmPdm0
_ZNK4PLMD11AcceleratorILj9EE10getIndicesERKSt6vectorIdSaIdEES6_S6_Pjm0
_ZNK4PLMD11AcceleratorILj9EE10getIndicesERKSt6vectorIjSaIjEEmPjm0
_ZNK4PLMD11AcceleratorILj9EE12getDimensionEv0
_ZNK4PLMD11AcceleratorILj9EE12getNeighborsERKNS_8GridBaseERKSt6vectorIjSaIjEERKS5_IbSaIbEEPKjmS9_0
_ZNK4PLMD11AcceleratorILj9EE8getIndexERKNS_8GridBaseERKSt6vectorIjSaIjEEPKjm0
_ZNK4PLMD11AcceleratorILj9EE8getPointERKSt6vectorIdSaIdEES6_PKjmPdm0
_ZNK4PLMD4Grid11getMaxValueEv629
_ZNK4PLMD4Grid11getMinValueEv861
_ZNK4PLMD4Grid22getValueAndDerivativesEmPdm3079776
_ZNK4PLMD4Grid24getDifferenceFromContourERKSt6vectorIdSaIdEERS3_0
_ZNK4PLMD4Grid7getSizeEv28865222
_ZNK4PLMD4Grid8getValueEm27284983
_ZNK4PLMD8GridBase11getArgNamesB5cxx11Ev9436
_ZNK4PLMD8GridBase12getBinVolumeEv37
_ZNK4PLMD8GridBase12getDimensionEv18321217
_ZNK4PLMD8GridBase13getIsPeriodicEv2240
_ZNK4PLMD8GridBase18getSplineNeighborsEPKjmPmm3711
_ZNK4PLMD8GridBase19getNearestNeighborsERKSt6vectorIjSaIjEE0
_ZNK4PLMD8GridBase19getNearestNeighborsEm9577
_ZNK4PLMD8GridBase22getValueAndDerivativesERKSt6vectorIdSaIdEERS3_3711
_ZNK4PLMD8GridBase22getValueAndDerivativesERKSt6vectorIjSaIjEERS1_IdSaIdEE2527708
_ZNK4PLMD8GridBase22getValueAndDerivativesEmRSt6vectorIdSaIdEE3071066
_ZNK4PLMD8GridBase5getDxEm11890
_ZNK4PLMD8GridBase5getDxEv1319573
_ZNK4PLMD8GridBase6getMaxB5cxx11Ev343
_ZNK4PLMD8GridBase6getMinB5cxx11Ev1360394
_ZNK4PLMD8GridBase7getNbinEv1012510
_ZNK4PLMD8GridBase8getValueERKSt6vectorIdSaIdEE345
_ZNK4PLMD8GridBase8getValueERKSt6vectorIjSaIjEE1193613
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Grid.cpp.gcov.html b/coverage/tools/Grid.cpp.gcov.html new file mode 100644 index 000000000000..9b5be0e12163 --- /dev/null +++ b/coverage/tools/Grid.cpp.gcov.html @@ -0,0 +1,1190 @@ + + + + + + + + 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:42060569.4 %
Date:2024-04-19 12:12:35Functions:6016037.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             : 
+      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             : #include "small_vector/small_vector.h"
+      32             : 
+      33             : #include <vector>
+      34             : #include <cmath>
+      35             : #include <iostream>
+      36             : #include <sstream>
+      37             : #include <cstdio>
+      38             : #include <cfloat>
+      39             : #include <array>
+      40             : 
+      41             : namespace PLMD {
+      42             : 
+      43             : constexpr std::size_t GridBase::maxdim;
+      44             : 
+      45             : template<unsigned dimension_>
+      46        2959 : class Accelerator final:
+      47             :   public Grid::AcceleratorBase
+      48             : {
+      49             : 
+      50             : public:
+      51             : 
+      52        1504 :   unsigned getDimension() const override {
+      53        1504 :     return dimension_;
+      54             :   }
+      55             : 
+      56       23364 :   std::vector<GridBase::index_t> getNeighbors(const GridBase& grid, const std::vector<unsigned> & nbin_,const std::vector<bool> & pbc_,const unsigned* indices,std::size_t indices_size,const std::vector<unsigned> &nneigh)const override {
+      57             :     plumed_dbg_assert(indices_size==dimension_ && nneigh.size()==dimension_);
+      58             : 
+      59             :     std::vector<Grid::index_t> neighbors;
+      60             :     std::array<unsigned,dimension_> small_bin;
+      61             :     std::array<unsigned,dimension_> small_indices;
+      62             :     std::array<unsigned,dimension_> tmp_indices;
+      63             : 
+      64             :     unsigned small_nbin=1;
+      65       69592 :     for(unsigned j=0; j<dimension_; ++j) {
+      66       46228 :       small_bin[j]=(2*nneigh[j]+1);
+      67       46228 :       small_nbin*=small_bin[j];
+      68             :     }
+      69       23364 :     neighbors.reserve(small_nbin);
+      70             : 
+      71       69592 :     for(unsigned j=0; j<dimension_; j++) small_indices[j]=0;
+      72             : 
+      73     1291958 :     for(unsigned index=0; index<small_nbin; ++index) {
+      74             :       unsigned ll=0;
+      75     3792754 :       for(unsigned i=0; i<dimension_; ++i) {
+      76     2524160 :         int i0=small_indices[i]-nneigh[i]+indices[i];
+      77     2524160 :         if(!pbc_[i] && i0<0)         continue;
+      78     2504438 :         if(!pbc_[i] && i0>=static_cast<int>(nbin_[i])) continue;
+      79     2483466 :         if( pbc_[i] && i0<0)         i0=nbin_[i]-(-i0)%nbin_[i];
+      80     2483466 :         if( pbc_[i] && i0>=static_cast<int>(nbin_[i])) i0%=nbin_[i];
+      81     2483466 :         tmp_indices[ll]=static_cast<unsigned>(i0);
+      82     2483466 :         ll++;
+      83             :       }
+      84     1268594 :       if(ll==dimension_) {neighbors.push_back(getIndex(grid,nbin_,&tmp_indices[0],dimension_));}
+      85             : 
+      86     1268594 :       small_indices[0]++;
+      87     2511132 :       for(unsigned j=0; j<dimension_-1; j++) if(small_indices[j]==small_bin[j]) {
+      88       95464 :           small_indices[j]=0;
+      89       95464 :           small_indices[j+1]++;
+      90             :         }
+      91             :     }
+      92       23364 :     return neighbors;
+      93             :   }
+      94             : 
+      95             :   // we are flattening arrays using a column-major order
+      96     7145799 :   GridBase::index_t getIndex(const GridBase& grid, const std::vector<unsigned> & nbin_,const unsigned* indices,std::size_t indices_size) const override {
+      97    19319332 :     for(unsigned int i=0; i<dimension_; i++)
+      98    12173533 :       if(indices[i]>=nbin_[i]) plumed_error() << "Looking for a value outside the grid along the " << i << " dimension (arg name: "<<grid.getArgNames()[i]<<")";
+      99     7145799 :     auto index=indices[dimension_-1];
+     100     9619118 :     for(unsigned int i=dimension_-1; i>0; --i) {
+     101     5027734 :       index=index*nbin_[i-1]+indices[i-1];
+     102             :     }
+     103     7145799 :     return index;
+     104             :   }
+     105             : 
+     106    32656432 :   void getPoint(const std::vector<double> & min_,const std::vector<double> & dx_, const unsigned* indices,std::size_t indices_size,double* point,std::size_t point_size) const override {
+     107   111790261 :     for(unsigned int i=0; i<dimension_; ++i) {
+     108    79133829 :       point[i]=min_[i]+(double)(indices[i])*dx_[i];
+     109             :     }
+     110    32656432 :   }
+     111             : 
+     112     1107992 :   void getIndices(const std::vector<double> & min_,const std::vector<double> & dx_, const std::vector<double> & x, unsigned* rindex_data,std::size_t rindex_size) const override {
+     113             :     plumed_dbg_assert(x.size()==dimension_);
+     114             :     plumed_dbg_assert(rindex_size==dimension_);
+     115     3316236 :     for(unsigned int i=0; i<dimension_; ++i) {
+     116     2208244 :       rindex_data[i] = unsigned(std::floor((x[i]-min_[i])/dx_[i]));
+     117             :     }
+     118     1107992 :   }
+     119             : 
+     120             : 
+     121             :   // we are flattening arrays using a column-major order
+     122    37838395 :   void getIndices(const std::vector<unsigned> & nbin_, GridBase::index_t index, unsigned* indices, std::size_t indices_size) const override {
+     123    37838395 :     plumed_assert(indices_size==dimension_)<<indices_size;
+     124    90954643 :     for(unsigned int i=0; i<dimension_-1; ++i) {
+     125    53951676 :       indices[i]=index%nbin_[i];
+     126    53951676 :       index/=nbin_[i];
+     127             :     }
+     128    37838395 :     indices[dimension_-1]=index;
+     129    37838395 :   }
+     130             : 
+     131             : };
+     132             : 
+     133        2959 : std::unique_ptr<Grid::AcceleratorBase> Grid::AcceleratorBase::create(unsigned dim) {
+     134             : // I do this by enumeration.
+     135             : // Maybe can be simplified using the preprocessor, but I am not sure it's worth it
+     136        2393 :   if(dim==1) return std::make_unique<Accelerator<1>>();
+     137         558 :   if(dim==2) return std::make_unique<Accelerator<2>>();
+     138           8 :   if(dim==3) return std::make_unique<Accelerator<3>>();
+     139           0 :   if(dim==4) return std::make_unique<Accelerator<4>>();
+     140           0 :   if(dim==5) return std::make_unique<Accelerator<5>>();
+     141           0 :   if(dim==6) return std::make_unique<Accelerator<6>>();
+     142           0 :   if(dim==7) return std::make_unique<Accelerator<7>>();
+     143           0 :   if(dim==8) return std::make_unique<Accelerator<8>>();
+     144           0 :   if(dim==9) return std::make_unique<Accelerator<9>>();
+     145           0 :   if(dim==10) return std::make_unique<Accelerator<10>>();
+     146           0 :   if(dim==11) return std::make_unique<Accelerator<11>>();
+     147           0 :   if(dim==12) return std::make_unique<Accelerator<12>>();
+     148           0 :   if(dim==13) return std::make_unique<Accelerator<13>>();
+     149           0 :   if(dim==14) return std::make_unique<Accelerator<14>>();
+     150           0 :   if(dim==15) return std::make_unique<Accelerator<15>>();
+     151           0 :   if(dim==16) return std::make_unique<Accelerator<16>>();
+     152             : // no need to go beyond this
+     153           0 :   plumed_error();
+     154             : }
+     155             : 
+     156        1327 : GridBase::GridBase(const std::string& funcl, const std::vector<Value*> & args, const std::vector<std::string> & gmin,
+     157        1327 :                    const std::vector<std::string> & gmax, const std::vector<unsigned> & nbin, bool dospline, bool usederiv) {
+     158             : // various checks
+     159        1327 :   plumed_assert(args.size()<=maxdim) << "grid dim cannot exceed "<<maxdim;
+     160        1327 :   plumed_massert(args.size()==gmin.size(),"grid min dimensions in input do not match number of arguments");
+     161        1327 :   plumed_massert(args.size()==nbin.size(),"number of bins on input do not match number of arguments");
+     162        1327 :   plumed_massert(args.size()==gmax.size(),"grid max dimensions in input do not match number of arguments");
+     163        1327 :   unsigned dim=gmax.size();
+     164             :   std::vector<std::string> names;
+     165             :   std::vector<bool> isperiodic;
+     166             :   std::vector<std::string> pmin,pmax;
+     167        1327 :   names.resize( dim );
+     168        1327 :   isperiodic.resize( dim );
+     169        1327 :   pmin.resize( dim );
+     170        1327 :   pmax.resize( dim );
+     171        2933 :   for(unsigned int i=0; i<dim; ++i) {
+     172        1606 :     names[i]=args[i]->getName();
+     173        1606 :     if( args[i]->isPeriodic() ) {
+     174             :       isperiodic[i]=true;
+     175         502 :       args[i]->getDomain( pmin[i], pmax[i] );
+     176             :     } else {
+     177             :       isperiodic[i]=false;
+     178             :       pmin[i]="0.";
+     179             :       pmax[i]="0.";
+     180             :     }
+     181             :   }
+     182             : // this is a value-independent initializator
+     183        1327 :   Init(funcl,names,gmin,gmax,nbin,dospline,usederiv,isperiodic,pmin,pmax);
+     184        2654 : }
+     185             : 
+     186         128 : GridBase::GridBase(const std::string& funcl, const std::vector<std::string> &names, const std::vector<std::string> & gmin,
+     187             :                    const std::vector<std::string> & gmax, const std::vector<unsigned> & nbin, bool dospline, bool usederiv,
+     188         128 :                    const std::vector<bool> &isperiodic, const std::vector<std::string> &pmin, const std::vector<std::string> &pmax ) {
+     189             : // this calls the initializator
+     190         128 :   Init(funcl,names,gmin,gmax,nbin,dospline,usederiv,isperiodic,pmin,pmax);
+     191         128 : }
+     192             : 
+     193        1455 : void GridBase::Init(const std::string& funcl, const std::vector<std::string> &names, const std::vector<std::string> & gmin,
+     194             :                     const std::vector<std::string> & gmax, const std::vector<unsigned> & nbin, bool dospline, bool usederiv,
+     195             :                     const std::vector<bool> &isperiodic, const std::vector<std::string> &pmin, const std::vector<std::string> &pmax ) {
+     196        1455 :   fmt_="%14.9f";
+     197             : // various checks
+     198        1455 :   plumed_assert(names.size()<=maxdim) << "grid size cannot exceed "<<maxdim;
+     199        1455 :   plumed_massert(names.size()==gmin.size(),"grid dimensions in input do not match number of arguments");
+     200        1455 :   plumed_massert(names.size()==nbin.size(),"grid dimensions in input do not match number of arguments");
+     201        1455 :   plumed_massert(names.size()==gmax.size(),"grid dimensions in input do not match number of arguments");
+     202        1455 :   dimension_=gmax.size();
+     203        1455 :   accelerator=AcceleratorHandler(dimension_);
+     204        1455 :   str_min_=gmin; str_max_=gmax;
+     205        1455 :   argnames.resize( dimension_ );
+     206        1455 :   min_.resize( dimension_ );
+     207        1455 :   max_.resize( dimension_ );
+     208        1455 :   pbc_.resize( dimension_ );
+     209        3189 :   for(unsigned int i=0; i<dimension_; ++i) {
+     210        1734 :     argnames[i]=names[i];
+     211        1734 :     if( isperiodic[i] ) {
+     212             :       pbc_[i]=true;
+     213             :       str_min_[i]=pmin[i];
+     214             :       str_max_[i]=pmax[i];
+     215             :     } else {
+     216             :       pbc_[i]=false;
+     217             :     }
+     218        1734 :     Tools::convert(str_min_[i],min_[i]);
+     219        1734 :     Tools::convert(str_max_[i],max_[i]);
+     220        1734 :     funcname=funcl;
+     221        1734 :     plumed_massert(max_[i]>min_[i],"maximum in grid must be larger than minimum");
+     222        1734 :     plumed_massert(nbin[i]>0,"number of grid points must be greater than zero");
+     223             :   }
+     224        1455 :   nbin_=nbin;
+     225        1455 :   dospline_=dospline;
+     226        1455 :   usederiv_=usederiv;
+     227        1455 :   if(dospline_) plumed_assert(dospline_==usederiv_);
+     228        1455 :   maxsize_=1;
+     229        3189 :   for(unsigned int i=0; i<dimension_; ++i) {
+     230        1734 :     dx_.push_back( (max_[i]-min_[i])/static_cast<double>( nbin_[i] ) );
+     231        1734 :     if( !pbc_[i] ) { max_[i] += dx_[i]; nbin_[i] += 1; }
+     232        1734 :     maxsize_*=nbin_[i];
+     233             :   }
+     234        1455 : }
+     235             : 
+     236     1360394 : std::vector<std::string> GridBase::getMin() const {
+     237     1360394 :   return str_min_;
+     238             : }
+     239             : 
+     240         343 : std::vector<std::string> GridBase::getMax() const {
+     241         343 :   return str_max_;
+     242             : }
+     243             : 
+     244     1319573 : std::vector<double> GridBase::getDx() const {
+     245     1319573 :   return dx_;
+     246             : }
+     247             : 
+     248       11890 : double GridBase::getDx(index_t j) const {
+     249       11890 :   return dx_[j];
+     250             : }
+     251             : 
+     252          37 : double GridBase::getBinVolume() const {
+     253             :   double vol=1.;
+     254         102 :   for(unsigned i=0; i<dx_.size(); ++i) vol*=dx_[i];
+     255          37 :   return vol;
+     256             : }
+     257             : 
+     258        2240 : std::vector<bool> GridBase::getIsPeriodic() const {
+     259        2240 :   return pbc_;
+     260             : }
+     261             : 
+     262     1012510 : std::vector<unsigned> GridBase::getNbin() const {
+     263     1012510 :   return nbin_;
+     264             : }
+     265             : 
+     266        9436 : std::vector<std::string> GridBase::getArgNames() const {
+     267        9436 :   return argnames;
+     268             : }
+     269             : 
+     270    18321217 : unsigned GridBase::getDimension() const {
+     271    18321217 :   return dimension_;
+     272             : }
+     273             : 
+     274        3711 : unsigned GridBase::getSplineNeighbors(const unsigned* indices, std::size_t indices_size, index_t* neighbors, std::size_t neighbors_size)const {
+     275        3711 :   plumed_assert(indices_size==dimension_);
+     276        3711 :   unsigned nneigh=1<<dimension_; // same as unsigned(pow(2.0,dimension_));
+     277        3711 :   plumed_assert(neighbors_size==nneigh);
+     278             : 
+     279             :   unsigned nneighbors = 0;
+     280             : 
+     281             :   std::array<unsigned,maxdim> nindices;
+     282             :   unsigned inind;
+     283       12623 :   for(unsigned int i=0; i<nneigh; ++i) {
+     284             :     unsigned tmp=i; inind=0;
+     285       20804 :     for(unsigned int j=0; j<dimension_; ++j) {
+     286       11892 :       unsigned i0=tmp%2+indices[j];
+     287       11892 :       tmp/=2;
+     288       11892 :       if(!pbc_[j] && i0==nbin_[j]) continue;
+     289       11890 :       if( pbc_[j] && i0==nbin_[j]) i0=0;
+     290       11890 :       nindices[inind++]=i0;
+     291             :     }
+     292        8912 :     if(inind==dimension_) neighbors[nneighbors++]=getIndex(nindices.data(),dimension_);
+     293             :   }
+     294        3711 :   return nneighbors;
+     295             : }
+     296             : 
+     297        9577 : std::vector<GridBase::index_t> GridBase::getNearestNeighbors(const index_t index) const {
+     298        9577 :   std::vector<index_t> nearest_neighs = std::vector<index_t>();
+     299       28730 :   for (unsigned i = 0; i < dimension_; i++) {
+     300       19153 :     std::vector<unsigned> neighsneeded = std::vector<unsigned>(dimension_, 0);
+     301       19153 :     neighsneeded[i] = 1;
+     302       19153 :     std::vector<index_t> singledim_nearest_neighs = getNeighbors(index, neighsneeded);
+     303       74978 :     for (unsigned j = 0; j < singledim_nearest_neighs.size(); j++) {
+     304       55825 :       index_t neigh = singledim_nearest_neighs[j];
+     305       55825 :       if (neigh != index) {
+     306       36672 :         nearest_neighs.push_back(neigh);
+     307             :       }
+     308             :     }
+     309             :   }
+     310        9577 :   return nearest_neighs;
+     311             : }
+     312             : 
+     313           0 : std::vector<GridBase::index_t> GridBase::getNearestNeighbors(const std::vector<unsigned> &indices) const {
+     314             :   plumed_dbg_assert(indices.size() == dimension_);
+     315           0 :   return getNearestNeighbors(getIndex(indices));
+     316             : }
+     317             : 
+     318           0 : void GridBase::addKernel( const KernelFunctions& kernel ) {
+     319             :   plumed_dbg_assert( kernel.ndim()==dimension_ );
+     320           0 :   std::vector<unsigned> nneighb=kernel.getSupport( dx_ );
+     321           0 :   std::vector<index_t> neighbors=getNeighbors( kernel.getCenter(), nneighb );
+     322           0 :   std::vector<double> xx( dimension_ );
+     323           0 :   std::vector<std::unique_ptr<Value>> vv( dimension_ );
+     324             :   std::string str_min, str_max;
+     325           0 :   for(unsigned i=0; i<dimension_; ++i) {
+     326           0 :     vv[i]=Tools::make_unique<Value>();
+     327           0 :     if( pbc_[i] ) {
+     328           0 :       Tools::convert(min_[i],str_min);
+     329           0 :       Tools::convert(max_[i],str_max);
+     330           0 :       vv[i]->setDomain( str_min, str_max );
+     331             :     } else {
+     332           0 :       vv[i]->setNotPeriodic();
+     333             :     }
+     334             :   }
+     335             : 
+     336             : // vv_ptr contains plain pointers obtained from vv.
+     337             : // this is the simplest way to replace a unique_ptr here.
+     338             : // perhaps the interface of kernel.evaluate() should be changed
+     339             : // in order to accept a std::vector<std::unique_ptr<Value>>
+     340           0 :   auto vv_ptr=Tools::unique2raw(vv);
+     341             : 
+     342           0 :   std::vector<double> der( dimension_ );
+     343           0 :   for(unsigned i=0; i<neighbors.size(); ++i) {
+     344           0 :     index_t ineigh=neighbors[i];
+     345           0 :     getPoint( ineigh, xx );
+     346           0 :     for(unsigned j=0; j<dimension_; ++j) vv[j]->set(xx[j]);
+     347           0 :     double newval = kernel.evaluate( vv_ptr, der, usederiv_ );
+     348           0 :     if( usederiv_ ) addValueAndDerivatives( ineigh, newval, der );
+     349           0 :     else addValue( ineigh, newval );
+     350             :   }
+     351           0 : }
+     352             : 
+     353     1193613 : double GridBase::getValue(const std::vector<unsigned> & indices) const {
+     354     1193613 :   return getValue(getIndex(indices));
+     355             : }
+     356             : 
+     357         345 : double GridBase::getValue(const std::vector<double> & x) const {
+     358         345 :   if(!dospline_) {
+     359          18 :     return getValue(getIndex(x));
+     360             :   } else {
+     361         327 :     std::vector<double> der(dimension_);
+     362         327 :     return getValueAndDerivatives(x,der);
+     363             :   }
+     364             : }
+     365             : 
+     366     3071066 : double GridBase::getValueAndDerivatives(index_t index, std::vector<double>& der) const {
+     367             :   plumed_dbg_assert(index<maxsize_ && usederiv_ && der.size()==dimension_);
+     368     3071066 :   der.resize(dimension_);
+     369     3071066 :   return getValueAndDerivatives(index,der.data(),der.size());
+     370             : }
+     371             : 
+     372     2527708 : double GridBase::getValueAndDerivatives(const std::vector<unsigned> & indices, std::vector<double>& der) const {
+     373     2527708 :   return getValueAndDerivatives(getIndex(indices),der);
+     374             : }
+     375             : 
+     376        3711 : double GridBase::getValueAndDerivatives(const std::vector<double> & x, std::vector<double>& der) const {
+     377             :   plumed_dbg_assert(der.size()==dimension_ && usederiv_);
+     378             : 
+     379        3711 :   if(dospline_) {
+     380             :     double X,X2,X3,value;
+     381             :     std::array<double,maxdim> fd, C, D;
+     382             :     std::array<double,maxdim> dder;
+     383             : // reset
+     384             :     value=0.0;
+     385        8167 :     for(unsigned int i=0; i<dimension_; ++i) der[i]=0.0;
+     386             : 
+     387             :     std::array<unsigned,maxdim> indices;
+     388        3711 :     getIndices(x, indices.data(),dimension_);
+     389             :     std::array<double,maxdim> xfloor;
+     390        3711 :     getPoint(indices.data(), dimension_, xfloor.data(),dimension_);
+     391        3711 :     gch::small_vector<index_t,16> neigh(1<<dimension_); // pow(2,dimension_); up to dimension 4 will stay on stack
+     392        3711 :     auto nneigh = getSplineNeighbors(indices.data(),dimension_, neigh.data(), neigh.size());
+     393             : 
+     394             : // loop over neighbors
+     395             :     std::array<unsigned,maxdim> nindices;
+     396       12621 :     for(unsigned int ipoint=0; ipoint<nneigh; ++ipoint) {
+     397        8910 :       double grid=getValueAndDerivatives(neigh[ipoint],dder.data(),dimension_);
+     398        8910 :       getIndices(neigh[ipoint], nindices.data(), dimension_);
+     399             :       double ff=1.0;
+     400             : 
+     401       20800 :       for(unsigned j=0; j<dimension_; ++j) {
+     402             :         int x0=1;
+     403       11890 :         if(nindices[j]==indices[j]) x0=0;
+     404       11890 :         double dx=getDx(j);
+     405       11890 :         X=std::abs((x[j]-xfloor[j])/dx-(double)x0);
+     406       11890 :         X2=X*X;
+     407       11890 :         X3=X2*X;
+     408             :         double yy;
+     409       11890 :         if(std::abs(grid)<0.0000001) yy=0.0;
+     410        8996 :         else yy=-dder[j]/grid;
+     411       11890 :         C[j]=(1.0-3.0*X2+2.0*X3) - (x0?-1.0:1.0)*yy*(X-2.0*X2+X3)*dx;
+     412       11890 :         D[j]=( -6.0*X +6.0*X2) - (x0?-1.0:1.0)*yy*(1.0-4.0*X +3.0*X2)*dx;
+     413       11890 :         D[j]*=(x0?-1.0:1.0)/dx;
+     414       11890 :         ff*=C[j];
+     415             :       }
+     416       20800 :       for(unsigned j=0; j<dimension_; ++j) {
+     417       11890 :         fd[j]=D[j];
+     418       29740 :         for(unsigned i=0; i<dimension_; ++i) if(i!=j) fd[j]*=C[i];
+     419             :       }
+     420        8910 :       value+=grid*ff;
+     421       20800 :       for(unsigned j=0; j<dimension_; ++j) der[j]+=grid*fd[j];
+     422             :     }
+     423             :     return value;
+     424             :   } else {
+     425           0 :     return getValueAndDerivatives(getIndex(x),der);
+     426             :   }
+     427             : }
+     428             : 
+     429           0 : void GridBase::setValue(const std::vector<unsigned> & indices, double value) {
+     430           0 :   setValue(getIndex(indices),value);
+     431           0 : }
+     432             : 
+     433           0 : void GridBase::setValueAndDerivatives(const std::vector<unsigned> & indices, double value, std::vector<double>& der) {
+     434           0 :   setValueAndDerivatives(getIndex(indices),value,der);
+     435           0 : }
+     436             : 
+     437           0 : void GridBase::addValue(const std::vector<unsigned> & indices, double value) {
+     438           0 :   addValue(getIndex(indices),value);
+     439           0 : }
+     440             : 
+     441           0 : void GridBase::addValueAndDerivatives(const std::vector<unsigned> & indices, double value, std::vector<double>& der) {
+     442           0 :   addValueAndDerivatives(getIndex(indices),value,der);
+     443           0 : }
+     444             : 
+     445        1147 : void GridBase::writeHeader(OFile& ofile) {
+     446        2611 :   for(unsigned i=0; i<dimension_; ++i) {
+     447        2928 :     ofile.addConstantField("min_" + argnames[i]);
+     448        2928 :     ofile.addConstantField("max_" + argnames[i]);
+     449        2928 :     ofile.addConstantField("nbins_" + argnames[i]);
+     450        2928 :     ofile.addConstantField("periodic_" + argnames[i]);
+     451             :   }
+     452        1147 : }
+     453             : 
+     454           1 : void Grid::clear() {
+     455           1 :   grid_.assign(maxsize_,0.0);
+     456           1 :   if(usederiv_) der_.assign(maxsize_*dimension_,0.0);
+     457           1 : }
+     458             : 
+     459        1147 : void Grid::writeToFile(OFile& ofile) {
+     460        1147 :   std::vector<double> xx(dimension_);
+     461        1147 :   std::vector<double> der(dimension_);
+     462             :   double f;
+     463        1147 :   writeHeader(ofile);
+     464     2533412 :   for(index_t i=0; i<getSize(); ++i) {
+     465     2532265 :     xx=getPoint(i);
+     466     2532265 :     if(usederiv_) {f=getValueAndDerivatives(i,der);}
+     467     1989707 :     else {f=getValue(i);}
+     468     4914902 :     if(i>0 && dimension_>1 && getIndices(i)[dimension_-2]==0) ofile.printf("\n");
+     469     7484524 :     for(unsigned j=0; j<dimension_; ++j) {
+     470     9904518 :       ofile.printField("min_" + argnames[j], str_min_[j] );
+     471     9904518 :       ofile.printField("max_" + argnames[j], str_max_[j] );
+     472     9904518 :       ofile.printField("nbins_" + argnames[j], static_cast<int>(nbin_[j]) );
+     473     6986607 :       if( pbc_[j] ) ofile.printField("periodic_" + argnames[j], "true" );
+     474     5835822 :       else          ofile.printField("periodic_" + argnames[j], "false" );
+     475             :     }
+     476     7484524 :     for(unsigned j=0; j<dimension_; ++j) { ofile.fmtField(" "+fmt_); ofile.printField(argnames[j],xx[j]); }
+     477     5064530 :     ofile.fmtField(" "+fmt_); ofile.printField(funcname,f);
+     478     5194297 :     if(usederiv_) for(unsigned j=0; j<dimension_; ++j) { ofile.fmtField(" "+fmt_); ofile.printField("der_" + argnames[j],der[j]); }
+     479     2532265 :     ofile.printField();
+     480             :   }
+     481        1147 : }
+     482             : 
+     483           0 : void GridBase::writeCubeFile(OFile& ofile, const double& lunit) {
+     484           0 :   plumed_assert( dimension_==3 );
+     485           0 :   ofile.printf("PLUMED CUBE FILE\n");
+     486           0 :   ofile.printf("OUTER LOOP: X, MIDDLE LOOP: Y, INNER LOOP: Z\n");
+     487             :   // Number of atoms followed by position of origin (origin set so that center of grid is in center of cell)
+     488           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]));
+     489           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
+     490           0 :   ofile.printf("%u %f %f %f\n",nbin_[1],0.0,lunit*dx_[1],0.0);  // shape of voxel
+     491           0 :   ofile.printf("%u %f %f %f\n",nbin_[2],0.0,0.0,lunit*dx_[2]);
+     492           0 :   ofile.printf("%d %f %f %f\n",1,0.0,0.0,0.0); // Fake atom otherwise VMD doesn't work
+     493           0 :   std::vector<unsigned> pp(3);
+     494           0 :   for(pp[0]=0; pp[0]<nbin_[0]; ++pp[0]) {
+     495           0 :     for(pp[1]=0; pp[1]<nbin_[1]; ++pp[1]) {
+     496           0 :       for(pp[2]=0; pp[2]<nbin_[2]; ++pp[2]) {
+     497           0 :         ofile.printf("%f ",getValue(pp) );
+     498           0 :         if(pp[2]%6==5) ofile.printf("\n");
+     499             :       }
+     500           0 :       ofile.printf("\n");
+     501             :     }
+     502             :   }
+     503           0 : }
+     504             : 
+     505          20 : std::unique_ptr<GridBase> GridBase::create(const std::string& funcl, const std::vector<Value*> & args, IFile& ifile,
+     506             :     const std::vector<std::string> & gmin,const std::vector<std::string> & gmax,
+     507             :     const std::vector<unsigned> & nbin,bool dosparse, bool dospline, bool doder) {
+     508          20 :   std::unique_ptr<GridBase> grid=GridBase::create(funcl,args,ifile,dosparse,dospline,doder);
+     509          20 :   std::vector<unsigned> cbin( grid->getNbin() );
+     510          20 :   std::vector<std::string> cmin( grid->getMin() ), cmax( grid->getMax() );
+     511          49 :   for(unsigned i=0; i<args.size(); ++i) {
+     512          29 :     plumed_massert( cmin[i]==gmin[i], "mismatched grid min" );
+     513          29 :     plumed_massert( cmax[i]==gmax[i], "mismatched grid max" );
+     514          29 :     if( args[i]->isPeriodic() ) {
+     515           8 :       plumed_massert( cbin[i]==nbin[i], "mismatched grid nbins" );
+     516             :     } else {
+     517          21 :       plumed_massert( (cbin[i]-1)==nbin[i], "mismatched grid nbins");
+     518             :     }
+     519             :   }
+     520          20 :   return grid;
+     521          20 : }
+     522             : 
+     523          70 : std::unique_ptr<GridBase> GridBase::create(const std::string& funcl, const std::vector<Value*> & args, IFile& ifile, bool dosparse, bool dospline, bool doder)
+     524             : {
+     525          70 :   std::unique_ptr<GridBase> grid;
+     526          70 :   unsigned nvar=args.size(); bool hasder=false; std::string pstring;
+     527          70 :   std::vector<int> gbin1(nvar); std::vector<unsigned> gbin(nvar);
+     528          70 :   std::vector<std::string> labels(nvar),gmin(nvar),gmax(nvar);
+     529          70 :   std::vector<std::string> fieldnames; ifile.scanFieldList( fieldnames );
+     530             : 
+     531             : // Retrieve names for fields
+     532         158 :   for(unsigned i=0; i<args.size(); ++i) {
+     533          88 :     labels[i]=args[i]->getName(); bool found=false;
+     534         106 :     for(unsigned j=0; j<fieldnames.size(); ++j) {
+     535         106 :       if( labels[i]==fieldnames[j] ) { found=true; break; }
+     536             :     }
+     537             :     // This is a change to ensure that we can deal with old style names for multicolvars
+     538          88 :     std::size_t und = labels[i].find_first_of("_");
+     539          88 :     if( !found && und!=std::string::npos ) {
+     540           0 :       labels[i] = labels[i].substr(0,und) + "." + labels[i].substr(und+1);
+     541           0 :       for(unsigned j=0; j<fieldnames.size(); ++j) {
+     542           0 :         if( labels[i]==fieldnames[j] ) { found=true; break; }
+     543             :       }
+     544             :     }
+     545             :   }
+     546             : // And read the stuff from the header
+     547          70 :   plumed_massert( ifile.FieldExist( funcl ), "no column labelled " + funcl + " in in grid input");
+     548         158 :   for(unsigned i=0; i<args.size(); ++i) {
+     549         176 :     ifile.scanField( "min_" + labels[i], gmin[i]);
+     550         176 :     ifile.scanField( "max_" + labels[i], gmax[i]);
+     551         176 :     ifile.scanField( "periodic_" + labels[i], pstring );
+     552         176 :     ifile.scanField( "nbins_" + labels[i], gbin1[i]);
+     553          88 :     plumed_assert( gbin1[i]>0 );
+     554          88 :     if( args[i]->isPeriodic() ) {
+     555          26 :       plumed_massert( pstring=="true", "input value is periodic but grid is not");
+     556             :       std::string pmin, pmax;
+     557          26 :       args[i]->getDomain( pmin, pmax ); gbin[i]=gbin1[i];
+     558          26 :       if( pmin!=gmin[i] || pmax!=gmax[i] ) plumed_merror("mismatch between grid boundaries and periods of values");
+     559             :     } else {
+     560          62 :       gbin[i]=gbin1[i]-1;  // Note header in grid file indicates one more bin that there should be when data is not periodic
+     561          62 :       plumed_massert( pstring=="false", "input value is not periodic but grid is");
+     562             :     }
+     563          88 :     hasder=ifile.FieldExist( "der_" + labels[i] );
+     564          88 :     if( doder && !hasder ) plumed_merror("missing derivatives from grid file");
+     565         106 :     for(unsigned j=0; j<fieldnames.size(); ++j) {
+     566         124 :       for(unsigned k=i+1; k<args.size(); ++k) {
+     567          18 :         if( fieldnames[j]==labels[k] ) plumed_merror("arguments in input are not in same order as in grid file");
+     568             :       }
+     569         106 :       if( fieldnames[j]==labels[i] ) break;
+     570             :     }
+     571             :   }
+     572             : 
+     573         140 :   if(!dosparse) {grid=Tools::make_unique<Grid>(funcl,args,gmin,gmax,gbin,dospline,doder);}
+     574           0 :   else {grid=Tools::make_unique<SparseGrid>(funcl,args,gmin,gmax,gbin,dospline,doder);}
+     575             : 
+     576          70 :   std::vector<double> xx(nvar),dder(nvar);
+     577          70 :   std::vector<double> dx=grid->getDx();
+     578             :   double f,x;
+     579     1099575 :   while( ifile.scanField(funcl,f) ) {
+     580     3294553 :     for(unsigned i=0; i<nvar; ++i) {
+     581     2195048 :       ifile.scanField(labels[i],x); xx[i]=x+dx[i]/2.0;
+     582     4390096 :       ifile.scanField( "min_" + labels[i], gmin[i]);
+     583     4390096 :       ifile.scanField( "max_" + labels[i], gmax[i]);
+     584     4390096 :       ifile.scanField( "nbins_" + labels[i], gbin1[i]);
+     585     4390096 :       ifile.scanField( "periodic_" + labels[i], pstring );
+     586             :     }
+     587     3211140 :     if(hasder) { for(unsigned i=0; i<nvar; ++i) { ifile.scanField( "der_" + labels[i], dder[i] ); } }
+     588     1099505 :     index_t index=grid->getIndex(xx);
+     589     1099505 :     if(doder) {grid->setValueAndDerivatives(index,f,dder);}
+     590       42717 :     else {grid->setValue(index,f);}
+     591     1099505 :     ifile.scanField();
+     592             :   }
+     593          70 :   return grid;
+     594          70 : }
+     595             : 
+     596         861 : double Grid::getMinValue() const {
+     597             :   double minval;
+     598             :   minval=DBL_MAX;
+     599     2258311 :   for(index_t i=0; i<grid_.size(); ++i) {
+     600     2257450 :     if(grid_[i]<minval)minval=grid_[i];
+     601             :   }
+     602         861 :   return minval;
+     603             : }
+     604             : 
+     605         629 : double Grid::getMaxValue() const {
+     606             :   double maxval;
+     607             :   maxval=DBL_MIN;
+     608     3755246 :   for(index_t i=0; i<grid_.size(); ++i) {
+     609     3754617 :     if(grid_[i]>maxval)maxval=grid_[i];
+     610             :   }
+     611         629 :   return maxval;
+     612             : }
+     613             : 
+     614         594 : void Grid::scaleAllValuesAndDerivatives( const double& scalef ) {
+     615         594 :   if(usederiv_) {
+     616       21474 :     for(index_t i=0; i<grid_.size(); ++i) {
+     617       21463 :       grid_[i]*=scalef;
+     618       63888 :       for(unsigned j=0; j<dimension_; ++j) der_[i*dimension_+j]*=scalef;
+     619             :     }
+     620             :   } else {
+     621     1572834 :     for(index_t i=0; i<grid_.size(); ++i) grid_[i]*=scalef;
+     622             :   }
+     623         594 : }
+     624             : 
+     625           0 : void Grid::logAllValuesAndDerivatives( const double& scalef ) {
+     626           0 :   if(usederiv_) {
+     627           0 :     for(index_t i=0; i<grid_.size(); ++i) {
+     628           0 :       grid_[i] = scalef*std::log(grid_[i]);
+     629           0 :       for(unsigned j=0; j<dimension_; ++j) der_[i*dimension_+j] = scalef/der_[i*dimension_+j];
+     630             :     }
+     631             :   } else {
+     632           0 :     for(index_t i=0; i<grid_.size(); ++i) grid_[i] = scalef*std::log(grid_[i]);
+     633             :   }
+     634           0 : }
+     635             : 
+     636        1329 : void Grid::setMinToZero() {
+     637        1329 :   double min=grid_[0];
+     638     3518541 :   for(index_t i=1; i<grid_.size(); ++i) if(grid_[i]<min) min=grid_[i];
+     639     3519870 :   for(index_t i=0; i<grid_.size(); ++i) grid_[i] -= min;
+     640        1329 : }
+     641             : 
+     642           1 : void Grid::applyFunctionAllValuesAndDerivatives( double (*func)(double val), double (*funcder)(double valder) ) {
+     643           1 :   if(usederiv_) {
+     644         901 :     for(index_t i=0; i<grid_.size(); ++i) {
+     645         900 :       grid_[i]=func(grid_[i]);
+     646        2700 :       for(unsigned j=0; j<dimension_; ++j) der_[i*dimension_+j]=funcder(der_[i*dimension_+j]);
+     647             :     }
+     648             :   } else {
+     649           0 :     for(index_t i=0; i<grid_.size(); ++i) grid_[i]=func(grid_[i]);
+     650             :   }
+     651           1 : }
+     652             : 
+     653           0 : double Grid::getDifferenceFromContour( const std::vector<double>& x, std::vector<double>& der ) const {
+     654           0 :   return getValueAndDerivatives( x, der ) - contour_location;
+     655             : }
+     656             : 
+     657           0 : void Grid::findSetOfPointsOnContour(const double& target, const std::vector<bool>& nosearch,
+     658             :                                     unsigned& npoints, std::vector<std::vector<double> >& points ) {
+     659             : // Set contour location for function
+     660           0 :   contour_location=target;
+     661             : // Resize points to maximum possible value
+     662           0 :   points.resize( dimension_*maxsize_ );
+     663             : 
+     664             : // Two points for search
+     665           0 :   std::vector<unsigned> ind(dimension_);
+     666           0 :   std::vector<double> direction( dimension_, 0 );
+     667             : 
+     668             : // Run over whole grid
+     669           0 :   npoints=0; RootFindingBase<Grid> mymin( this );
+     670           0 :   for(unsigned i=0; i<maxsize_; ++i) {
+     671           0 :     for(unsigned j=0; j<dimension_; ++j) ind[j]=getIndices(i)[j];
+     672             : 
+     673             :     // Get the value of a point on the grid
+     674           0 :     double val1=getValue(i) - target;
+     675             : 
+     676             :     // Now search for contour in each direction
+     677             :     bool edge=false;
+     678           0 :     for(unsigned j=0; j<dimension_; ++j) {
+     679           0 :       if( nosearch[j] ) continue ;
+     680             :       // Make sure we don't search at the edge of the grid
+     681           0 :       if( !pbc_[j] && (ind[j]+1)==nbin_[j] ) continue;
+     682           0 :       else if( (ind[j]+1)==nbin_[j] ) { edge=true; ind[j]=0; }
+     683           0 :       else ind[j]+=1;
+     684           0 :       double val2=getValue(ind) - target;
+     685           0 :       if( val1*val2<0 ) {
+     686             :         // Use initial point location as first guess for search
+     687           0 :         points[npoints].resize(dimension_); for(unsigned k=0; k<dimension_; ++k) points[npoints][k]=getPoint(i)[k];
+     688             :         // Setup direction vector
+     689           0 :         direction[j]=0.999999999*dx_[j];
+     690             :         // And do proper search for contour point
+     691           0 :         mymin.linesearch( direction, points[npoints], &Grid::getDifferenceFromContour );
+     692           0 :         direction[j]=0.0; npoints++;
+     693             :       }
+     694           0 :       if( pbc_[j] && edge ) { edge=false; ind[j]=nbin_[j]-1; }
+     695           0 :       else ind[j]-=1;
+     696             :     }
+     697             :   }
+     698           0 : }
+     699             : 
+     700             : /// OVERRIDES ARE BELOW
+     701             : 
+     702    28865222 : Grid::index_t Grid::getSize() const {
+     703    28865222 :   return maxsize_;
+     704             : }
+     705             : 
+     706    27284983 : double Grid::getValue(index_t index) const {
+     707             :   plumed_dbg_assert(index<maxsize_);
+     708    27284983 :   return grid_[index];
+     709             : }
+     710             : 
+     711     3079776 : double Grid::getValueAndDerivatives(index_t index, double* der,std::size_t der_size) const {
+     712             :   plumed_dbg_assert(index<maxsize_ && usederiv_ && der_size==dimension_);
+     713     6679531 :   for(unsigned i=0; i<dimension_; i++) der[i]=der_[dimension_*index+i];
+     714     3079776 :   return grid_[index];
+     715             : }
+     716             : 
+     717     6444104 : void Grid::setValue(index_t index, double value) {
+     718             :   plumed_dbg_assert(index<maxsize_ && !usederiv_);
+     719     6444104 :   grid_[index]=value;
+     720     6444104 : }
+     721             : 
+     722     2552369 : void Grid::setValueAndDerivatives(index_t index, double value, std::vector<double>& der) {
+     723             :   plumed_dbg_assert(index<maxsize_ && usederiv_ && der.size()==dimension_);
+     724     2552369 :   grid_[index]=value;
+     725     7609163 :   for(unsigned i=0; i<dimension_; i++) der_[dimension_*index+i]=der[i];
+     726     2552369 : }
+     727             : 
+     728           1 : void Grid::addValue(index_t index, double value) {
+     729             :   plumed_dbg_assert(index<maxsize_ && !usederiv_);
+     730           1 :   grid_[index]+=value;
+     731           1 : }
+     732             : 
+     733     1171742 : void Grid::addValueAndDerivatives(index_t index, double value, std::vector<double>& der) {
+     734             :   plumed_dbg_assert(index<maxsize_ && usederiv_ && der.size()==dimension_);
+     735     1171742 :   grid_[index]+=value;
+     736     3500479 :   for(unsigned int i=0; i<dimension_; ++i) der_[index*dimension_+i]+=der[i];
+     737     1171742 : }
+     738             : 
+     739           0 : Grid::index_t SparseGrid::getSize() const {
+     740           0 :   return map_.size();
+     741             : }
+     742             : 
+     743           0 : Grid::index_t SparseGrid::getMaxSize() const {
+     744           0 :   return maxsize_;
+     745             : }
+     746             : 
+     747           0 : double SparseGrid::getValue(index_t index)const {
+     748           0 :   plumed_assert(index<maxsize_);
+     749             :   double value=0.0;
+     750             :   const auto it=map_.find(index);
+     751           0 :   if(it!=map_.end()) value=it->second;
+     752           0 :   return value;
+     753             : }
+     754             : 
+     755         200 : double SparseGrid::getValueAndDerivatives(index_t index, double* der, std::size_t der_size)const {
+     756         200 :   plumed_assert(index<maxsize_ && usederiv_ && der_size==dimension_);
+     757             :   double value=0.0;
+     758         580 :   for(unsigned int i=0; i<dimension_; ++i) der[i]=0.0;
+     759             :   const auto it=map_.find(index);
+     760         200 :   if(it!=map_.end()) value=it->second;
+     761             :   const auto itder=der_.find(index);
+     762         200 :   if(itder!=der_.end()) {
+     763             :     const auto & second(itder->second);
+     764         384 :     for(unsigned i=0; i<second.size(); i++) der[i]=itder->second[i];
+     765             :   }
+     766         200 :   return value;
+     767             : }
+     768             : 
+     769           0 : void SparseGrid::setValue(index_t index, double value) {
+     770           0 :   plumed_assert(index<maxsize_ && !usederiv_);
+     771           0 :   map_[index]=value;
+     772           0 : }
+     773             : 
+     774           0 : void SparseGrid::setValueAndDerivatives(index_t index, double value, std::vector<double>& der) {
+     775           0 :   plumed_assert(index<maxsize_ && usederiv_ && der.size()==dimension_);
+     776           0 :   map_[index]=value;
+     777           0 :   der_[index]=der;
+     778           0 : }
+     779             : 
+     780           0 : void SparseGrid::addValue(index_t index, double value) {
+     781           0 :   plumed_assert(index<maxsize_ && !usederiv_);
+     782           0 :   map_[index]+=value;
+     783           0 : }
+     784             : 
+     785       19999 : void SparseGrid::addValueAndDerivatives(index_t index, double value, std::vector<double>& der) {
+     786       19999 :   plumed_assert(index<maxsize_ && usederiv_ && der.size()==dimension_);
+     787       19999 :   map_[index]+=value;
+     788       19999 :   der_[index].resize(dimension_);
+     789       59682 :   for(unsigned int i=0; i<dimension_; ++i) der_[index][i]+=der[i];
+     790       19999 : }
+     791             : 
+     792           0 : void SparseGrid::writeToFile(OFile& ofile) {
+     793           0 :   std::vector<double> xx(dimension_);
+     794           0 :   std::vector<double> der(dimension_);
+     795             :   double f;
+     796           0 :   writeHeader(ofile);
+     797           0 :   ofile.fmtField(" "+fmt_);
+     798           0 :   for(const auto & it : map_) {
+     799           0 :     index_t i=it.first;
+     800           0 :     xx=getPoint(i);
+     801           0 :     if(usederiv_) {f=getValueAndDerivatives(i,der);}
+     802           0 :     else {f=getValue(i);}
+     803           0 :     if(i>0 && dimension_>1 && getIndices(i)[dimension_-2]==0) ofile.printf("\n");
+     804           0 :     for(unsigned j=0; j<dimension_; ++j) {
+     805           0 :       ofile.printField("min_" + argnames[j], str_min_[j] );
+     806           0 :       ofile.printField("max_" + argnames[j], str_max_[j] );
+     807           0 :       ofile.printField("nbins_" + argnames[j], static_cast<int>(nbin_[j]) );
+     808           0 :       if( pbc_[j] ) ofile.printField("periodic_" + argnames[j], "true" );
+     809           0 :       else          ofile.printField("periodic_" + argnames[j], "false" );
+     810             :     }
+     811           0 :     for(unsigned j=0; j<dimension_; ++j) ofile.printField(argnames[j],xx[j]);
+     812           0 :     ofile.printField(funcname, f);
+     813           0 :     if(usederiv_) { for(unsigned j=0; j<dimension_; ++j) ofile.printField("der_" + argnames[j],der[j]); }
+     814           0 :     ofile.printField();
+     815             :   }
+     816           0 : }
+     817             : 
+     818           0 : double SparseGrid::getMinValue() const {
+     819             :   double minval;
+     820             :   minval=0.0;
+     821           0 :   for(auto const & i : map_) {
+     822           0 :     if(i.second<minval) minval=i.second;
+     823             :   }
+     824           0 :   return minval;
+     825             : }
+     826             : 
+     827           9 : double SparseGrid::getMaxValue() const {
+     828             :   double maxval;
+     829             :   maxval=0.0;
+     830         590 :   for(auto const & i : map_) {
+     831         581 :     if(i.second>maxval) maxval=i.second;
+     832             :   }
+     833           9 :   return maxval;
+     834             : }
+     835             : 
+     836     1010062 : void Grid::projectOnLowDimension(double &val, std::vector<int> &vHigh, WeightBase * ptr2obj ) {
+     837             :   unsigned i=0;
+     838     3016945 :   for(i=0; i<vHigh.size(); i++) {
+     839     2015726 :     if(vHigh[i]<0) { // this bin needs to be integrated out
+     840             :       // parallelize here???
+     841     1010062 :       for(unsigned j=0; j<(getNbin())[i]; j++) {
+     842     1001219 :         vHigh[i]=int(j);
+     843     1001219 :         projectOnLowDimension(val,vHigh,ptr2obj); // recursive function: this is the core of the mechanism
+     844     1001219 :         vHigh[i]=-1;
+     845             :       }
+     846             :       return; //
+     847             :     }
+     848             :   }
+     849             :   // when there are no more bin to dig in then retrieve the value
+     850     1001219 :   if(i==vHigh.size()) {
+     851             :     //std::cerr<<"POINT: ";
+     852             :     //for(unsigned j=0;j<vHigh.size();j++){
+     853             :     //   std::cerr<<vHigh[j]<<" ";
+     854             :     //}
+     855     1001219 :     std::vector<unsigned> vv(vHigh.size());
+     856     3003657 :     for(unsigned j=0; j<vHigh.size(); j++)vv[j]=unsigned(vHigh[j]);
+     857             :     //
+     858             :     // this is the real assignment !!!!! (hack this to have bias or other stuff)
+     859             :     //
+     860             : 
+     861             :     // this case: produce fes
+     862             :     //val+=exp(beta*getValue(vv)) ;
+     863     1001219 :     double myv=getValue(vv);
+     864     1001219 :     val=ptr2obj->projectInnerLoop(val,myv) ;
+     865             :     // to be added: bias (same as before without negative sign)
+     866             :     //std::cerr<<" VAL: "<<val <<endl;
+     867             :   }
+     868             : }
+     869             : 
+     870          81 : Grid Grid::project(const std::vector<std::string> & proj, WeightBase *ptr2obj ) {
+     871             :   // find extrema only for the projection
+     872             :   std::vector<std::string>   smallMin,smallMax;
+     873             :   std::vector<unsigned> smallBin;
+     874             :   std::vector<unsigned> dimMapping;
+     875             :   std::vector<bool> smallIsPeriodic;
+     876             :   std::vector<std::string> smallName;
+     877             : 
+     878             :   // check if the two key methods are there
+     879             :   WeightBase* pp = dynamic_cast<WeightBase*>(ptr2obj);
+     880          81 :   if (!pp)plumed_merror("This WeightBase is not complete: you need a projectInnerLoop and projectOuterLoop ");
+     881             : 
+     882         162 :   for(unsigned j=0; j<proj.size(); j++) {
+     883         120 :     for(unsigned i=0; i<getArgNames().size(); i++) {
+     884         120 :       if(proj[j]==getArgNames()[i]) {
+     885             :         unsigned offset;
+     886             :         // note that at sizetime the non periodic dimension get a bin more
+     887         162 :         if(getIsPeriodic()[i]) {offset=0;} else {offset=1;}
+     888          81 :         smallMax.push_back(getMax()[i]);
+     889          81 :         smallMin.push_back(getMin()[i]);
+     890          81 :         smallBin.push_back(getNbin()[i]-offset);
+     891         162 :         smallIsPeriodic.push_back(getIsPeriodic()[i]);
+     892          81 :         dimMapping.push_back(i);
+     893          81 :         smallName.push_back(getArgNames()[i]);
+     894          81 :         break;
+     895             :       }
+     896             :     }
+     897             :   }
+     898          81 :   Grid smallgrid("projection",smallName,smallMin,smallMax,smallBin,false,false,smallIsPeriodic,smallMin,smallMax);
+     899             :   // check that the two grids are commensurate
+     900         162 :   for(unsigned i=0; i<dimMapping.size(); i++) {
+     901          81 :     plumed_massert(  (smallgrid.getMax())[i] == (getMax())[dimMapping[i]],  "the two input grids are not compatible in max"   );
+     902          81 :     plumed_massert(  (smallgrid.getMin())[i] == (getMin())[dimMapping[i]],  "the two input grids are not compatible in min"   );
+     903          81 :     plumed_massert(  (smallgrid.getNbin())[i]== (getNbin())[dimMapping[i]], "the two input grids are not compatible in bin"   );
+     904             :   }
+     905             :   std::vector<unsigned> toBeIntegrated;
+     906         243 :   for(unsigned i=0; i<getArgNames().size(); i++) {
+     907             :     bool doappend=true;
+     908         243 :     for(unsigned j=0; j<dimMapping.size(); j++) {
+     909         162 :       if(dimMapping[j]==i) {doappend=false; break;}
+     910             :     }
+     911         162 :     if(doappend)toBeIntegrated.push_back(i);
+     912             :   }
+     913             : 
+     914             :   // loop over all the points in the Grid, find the corresponding fixed index, rotate over all the other ones
+     915        8924 :   for(unsigned i=0; i<smallgrid.getSize(); i++) {
+     916             :     std::vector<unsigned> v;
+     917        8843 :     v=smallgrid.getIndices(i);
+     918        8843 :     std::vector<int> vHigh((getArgNames()).size(),-1);
+     919       17686 :     for(unsigned j=0; j<dimMapping.size(); j++)vHigh[dimMapping[j]]=int(v[j]);
+     920             :     // the vector vhigh now contains at the beginning the index of the low dimension and -1 for the values that need to be integrated
+     921        8843 :     double initval=0.;
+     922        8843 :     projectOnLowDimension(initval,vHigh, ptr2obj);
+     923        8843 :     smallgrid.setValue(i,ptr2obj->projectOuterLoop(initval));
+     924             :   }
+     925             : 
+     926          81 :   return smallgrid;
+     927         162 : }
+     928             : 
+     929           0 : double Grid::integrate( std::vector<unsigned>& npoints ) {
+     930           0 :   plumed_dbg_assert( npoints.size()==dimension_ ); plumed_assert( dospline_ );
+     931             : 
+     932             :   unsigned ntotgrid=1; double box_vol=1.0;
+     933           0 :   std::vector<double> ispacing( npoints.size() );
+     934           0 :   for(unsigned j=0; j<dimension_; ++j) {
+     935           0 :     if( !pbc_[j] ) {
+     936           0 :       ispacing[j] = ( max_[j] - dx_[j] - min_[j] ) / static_cast<double>( npoints[j] );
+     937           0 :       npoints[j]+=1;
+     938             :     } else {
+     939           0 :       ispacing[j] = ( max_[j] - min_[j] ) / static_cast<double>( npoints[j] );
+     940             :     }
+     941           0 :     ntotgrid*=npoints[j]; box_vol*=ispacing[j];
+     942             :   }
+     943             : 
+     944           0 :   std::vector<double> vals( dimension_ );
+     945           0 :   std::vector<unsigned> t_index( dimension_ ); double integral=0.0;
+     946           0 :   for(unsigned i=0; i<ntotgrid; ++i) {
+     947           0 :     t_index[0]=(i%npoints[0]);
+     948             :     unsigned kk=i;
+     949           0 :     for(unsigned j=1; j<dimension_-1; ++j) { kk=(kk-t_index[j-1])/npoints[j-1]; t_index[j]=(kk%npoints[j]); }
+     950           0 :     if( dimension_>=2 ) t_index[dimension_-1]=((kk-t_index[dimension_-2])/npoints[dimension_-2]);
+     951             : 
+     952           0 :     for(unsigned j=0; j<dimension_; ++j) vals[j]=min_[j] + t_index[j]*ispacing[j];
+     953             : 
+     954           0 :     integral += getValue( vals );
+     955             :   }
+     956             : 
+     957           0 :   return box_vol*integral;
+     958             : }
+     959             : 
+     960           0 : void Grid::mpiSumValuesAndDerivatives( Communicator& comm ) {
+     961           0 :   comm.Sum( grid_ ); for(unsigned i=0; i<der_.size(); ++i) comm.Sum( der_[i] );
+     962           0 : }
+     963             : 
+     964             : 
+     965       59573 : bool indexed_lt(std::pair<Grid::index_t, double> const &x, std::pair<Grid::index_t, double> const   &y) {
+     966       59573 :   return x.second < y.second;
+     967             : }
+     968             : 
+     969         273 : double GridBase::findMaximalPathMinimum(const std::vector<double> &source, const std::vector<double> &sink) {
+     970             :   plumed_dbg_assert(source.size() == dimension_);
+     971             :   plumed_dbg_assert(sink.size() == dimension_);
+     972             :   // Start and end indices
+     973         273 :   index_t source_idx = getIndex(source);
+     974         273 :   index_t sink_idx = getIndex(sink);
+     975             :   // Path cost
+     976             :   double maximal_minimum = 0;
+     977             :   // In one dimension, path searching is very easy--either go one way if it's not periodic,
+     978             :   // or go both ways if it is periodic. There's no reason to pay the cost of Dijkstra.
+     979         273 :   if (dimension_ == 1) {
+     980             :     // Do a search from the grid source to grid sink that does not
+     981             :     // cross the grid boundary.
+     982         147 :     double curr_min_bias = getValue(source_idx);
+     983             :     // Either search from a high source to a low sink.
+     984         147 :     if (source_idx > sink_idx) {
+     985         735 :       for (index_t i = source_idx; i >= sink_idx; i--) {
+     986         588 :         if (curr_min_bias == 0.0) {
+     987             :           break;
+     988             :         }
+     989         588 :         curr_min_bias = fmin(curr_min_bias, getValue(i));
+     990             :       }
+     991             :       // Or search from a low source to a high sink.
+     992           0 :     } else if (source_idx < sink_idx) {
+     993           0 :       for (index_t i = source_idx; i <= sink_idx; i++) {
+     994           0 :         if (curr_min_bias == 0.0) {
+     995             :           break;
+     996             :         }
+     997           0 :         curr_min_bias = fmin(curr_min_bias, getValue(i));
+     998             :       }
+     999             :     }
+    1000             :     maximal_minimum = curr_min_bias;
+    1001             :     // If the grid is periodic, also do the search that crosses
+    1002             :     // the grid boundary.
+    1003         147 :     if (pbc_[0]) {
+    1004          42 :       double curr_min_bias = getValue(source_idx);
+    1005             :       // Either go from a high source to the upper boundary and
+    1006             :       // then from the bottom boundary to the sink
+    1007          42 :       if (source_idx > sink_idx) {
+    1008         210 :         for (index_t i = source_idx; i < maxsize_; i++) {
+    1009         168 :           if (curr_min_bias == 0.0) {
+    1010             :             break;
+    1011             :           }
+    1012         168 :           curr_min_bias = fmin(curr_min_bias, getValue(i));
+    1013             :         }
+    1014         210 :         for (index_t i = 0; i <= sink_idx; i++) {
+    1015         168 :           if (curr_min_bias == 0.0) {
+    1016             :             break;
+    1017             :           }
+    1018         168 :           curr_min_bias = fmin(curr_min_bias, getValue(i));
+    1019             :         }
+    1020             :         // Or go from a low source to the bottom boundary and
+    1021             :         // then from the high boundary to the sink
+    1022           0 :       } else if (source_idx < sink_idx) {
+    1023           0 :         for (index_t i = source_idx; i > 0; i--) {
+    1024           0 :           if (curr_min_bias == 0.0) {
+    1025             :             break;
+    1026             :           }
+    1027           0 :           curr_min_bias = fmin(curr_min_bias, getValue(i));
+    1028             :         }
+    1029           0 :         curr_min_bias = fmin(curr_min_bias, getValue(0));
+    1030           0 :         for (index_t i = maxsize_ - 1; i <= sink_idx; i--) {
+    1031           0 :           if (curr_min_bias == 0.0) {
+    1032             :             break;
+    1033             :           }
+    1034           0 :           curr_min_bias = fmin(curr_min_bias, getValue(i));
+    1035             :         }
+    1036             :       }
+    1037             :       // If the boundary crossing paths was more biased, it's
+    1038             :       // minimal bias replaces the non-boundary-crossing path's
+    1039             :       // minimum.
+    1040          42 :       maximal_minimum = fmax(maximal_minimum, curr_min_bias);
+    1041             :     }
+    1042             :     // The one dimensional path search is complete.
+    1043         147 :     return maximal_minimum;
+    1044             :     // In two or more dimensions, path searching isn't trivial and we really
+    1045             :     // do need to use a path search algorithm. Dijkstra is the simplest decent
+    1046             :     // one. Using it we've never found the path search to be performance
+    1047             :     // limiting in any solvated biomolecule test system, but faster options are
+    1048             :     // easy to imagine if they become necessary. NB-In this case, we're actually
+    1049             :     // using a greedy variant of Dijkstra's algorithm where the first possible
+    1050             :     // path to a point always controls the path cost to that point. The structure
+    1051             :     // of the cost function in this case guarantees that the calculated costs will
+    1052             :     // be correct using this variant even though fine details of the paths may not
+    1053             :     // match a normal Dijkstra search.
+    1054         126 :   } else if (dimension_ > 1) {
+    1055             :     // Prepare calculation temporaries for Dijkstra's algorithm.
+    1056             :     // Minimal path costs from source to a given grid point
+    1057         126 :     std::vector<double> mins_from_source = std::vector<double>(maxsize_, -1.0);
+    1058             :     // Heap for tracking available steps, steps are recorded as std::pairs of
+    1059             :     // an index and a value.
+    1060             :     std::vector< std::pair<index_t, double> > next_steps;
+    1061             :     std::pair<index_t, double> curr_indexed_val;
+    1062         126 :     std::make_heap(next_steps.begin(), next_steps.end(), indexed_lt);
+    1063             :     // The search begins at the source index.
+    1064         252 :     next_steps.push_back(std::pair<index_t, double>(source_idx, getValue(source_idx)));
+    1065         126 :     std::push_heap(next_steps.begin(), next_steps.end(), indexed_lt);
+    1066             :     // At first no points have been examined and the optimal path has not been found.
+    1067             :     index_t n_examined = 0;
+    1068             :     bool path_not_found = true;
+    1069             :     // Until a path is found,
+    1070             :     while (path_not_found) {
+    1071             :       // Examine the grid point currently most accessible from
+    1072             :       // the set of all previously explored grid points by popping
+    1073             :       // it from the top of the heap.
+    1074        9702 :       std::pop_heap(next_steps.begin(), next_steps.end(), indexed_lt);
+    1075             :       curr_indexed_val = next_steps.back();
+    1076             :       next_steps.pop_back();
+    1077             :       n_examined++;
+    1078             :       // Check if this point is the sink point, and if so
+    1079             :       // finish the loop.
+    1080        9702 :       if (curr_indexed_val.first == sink_idx) {
+    1081             :         path_not_found = false;
+    1082             :         maximal_minimum = curr_indexed_val.second;
+    1083         126 :         break;
+    1084             :         // Check if this point has reached the worst possible
+    1085             :         // value, and if so stop looking for paths.
+    1086        9576 :       } else if (curr_indexed_val.second == 0.0) {
+    1087             :         maximal_minimum = 0.0;
+    1088             :         break;
+    1089             :       }
+    1090             :       // If the search is not over, add this grid point's neighbors to the
+    1091             :       // possible next points to search for the sink.
+    1092        9576 :       std::vector<index_t> neighs = getNearestNeighbors(curr_indexed_val.first);
+    1093       46246 :       for (unsigned k = 0; k < neighs.size(); k++) {
+    1094       36670 :         index_t i = neighs[k];
+    1095             :         // If the neighbor has not already been added to the list of possible next steps,
+    1096       36670 :         if (mins_from_source[i] == -1.0) {
+    1097             :           // Set the cost to reach it via a path through the current point being examined.
+    1098       12284 :           mins_from_source[i] = fmin(curr_indexed_val.second, getValue(i));
+    1099             :           // Add the neighboring point to the heap of potential next steps.
+    1100       12284 :           next_steps.push_back(std::pair<index_t, double>(i, mins_from_source[i]));
+    1101       12284 :           std::push_heap(next_steps.begin(), next_steps.end(), indexed_lt);
+    1102             :         }
+    1103             :       }
+    1104             :       // Move on to the next best looking step along any of the paths
+    1105             :       // growing from the source.
+    1106             :     }
+    1107             :     // The multidimensional path search is now complete.
+    1108             :     return maximal_minimum;
+    1109             :   }
+    1110             :   return 0.0;
+    1111             : }
+    1112             : 
+    1113             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Grid.h.func-sort-c.html b/coverage/tools/Grid.h.func-sort-c.html new file mode 100644 index 000000000000..ab56b087d5c0 --- /dev/null +++ b/coverage/tools/Grid.h.func-sort-c.html @@ -0,0 +1,173 @@ + + + + + + + + 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:8888100.0 %
Date:2024-04-19 12:12:35Functions:242596.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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
_ZN4PLMD8GridBase18AcceleratorHandlerC2ERKS1_49
_ZN4PLMD4GridC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIS6_SaIS6_EESD_SD_RKS9_IjSaIjEEbbRKS9_IbSaIbEESD_SD_128
_ZN4PLMD10BiasWeight16projectOuterLoopERd187
_ZN4PLMD4GridC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIPNS_5ValueESaISB_EERKS9_IS6_SaIS6_EESJ_RKS9_IjSaIjEEbb1321
_ZN4PLMD8GridBase18AcceleratorHandleraSERKS1_1455
_ZN4PLMD8GridBaseD2Ev1504
_ZNK4PLMD8GridBase12getNeighborsERKSt6vectorIdSaIdEERKS1_IjSaIjEE4211
_ZN4PLMD10BiasWeight16projectInnerLoopERdS1_13603
_ZNK4PLMD8GridBase12getNeighborsEmRKSt6vectorIjSaIjEE19153
_ZNK4PLMD8GridBase8getIndexERKSt6vectorIdSaIdEE1100069
_ZNK4PLMD8GridBase10getIndicesERKSt6vectorIdSaIdEEPjm1103780
_ZNK4PLMD8GridBase8getPointERKSt6vectorIjSaIjEE2720102
_ZNK4PLMD8GridBase8getPointERKSt6vectorIjSaIjEERS1_IdSaIdEE2720102
_ZNK4PLMD8GridBase8getIndexERKSt6vectorIjSaIjEE4791554
_ZNK4PLMD8GridBase8getIndexEPKjm5900533
_ZNK4PLMD8GridBase10getIndicesEm7877712
_ZNK4PLMD8GridBase8getPointEm28822337
_ZNK4PLMD8GridBase8getPointEPKjmRSt6vectorIdSaIdEE29932618
_ZNK4PLMD8GridBase8getPointEmRSt6vectorIdSaIdEE29932618
_ZNK4PLMD8GridBase8getPointEPKjmPdm32656431
_ZNK4PLMD8GridBase10getIndicesEmPjm37819240
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Grid.h.func.html b/coverage/tools/Grid.h.func.html new file mode 100644 index 000000000000..3f76ae97f58f --- /dev/null +++ b/coverage/tools/Grid.h.func.html @@ -0,0 +1,173 @@ + + + + + + + + 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:8888100.0 %
Date:2024-04-19 12:12:35Functions:242596.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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
_ZN4PLMD8GridBase18AcceleratorHandlerC2ERKS1_49
_ZN4PLMD8GridBase18AcceleratorHandleraSERKS1_1455
_ZN4PLMD8GridBaseD0Ev0
_ZN4PLMD8GridBaseD2Ev1504
_ZNK4PLMD8GridBase10getIndicesERKSt6vectorIdSaIdEEPjm1103780
_ZNK4PLMD8GridBase10getIndicesEm7877712
_ZNK4PLMD8GridBase10getIndicesEmPjm37819240
_ZNK4PLMD8GridBase12getNeighborsERKSt6vectorIdSaIdEERKS1_IjSaIjEE4211
_ZNK4PLMD8GridBase12getNeighborsEmRKSt6vectorIjSaIjEE19153
_ZNK4PLMD8GridBase8getIndexEPKjm5900533
_ZNK4PLMD8GridBase8getIndexERKSt6vectorIdSaIdEE1100069
_ZNK4PLMD8GridBase8getIndexERKSt6vectorIjSaIjEE4791554
_ZNK4PLMD8GridBase8getPointEPKjmPdm32656431
_ZNK4PLMD8GridBase8getPointEPKjmRSt6vectorIdSaIdEE29932618
_ZNK4PLMD8GridBase8getPointERKSt6vectorIjSaIjEE2720102
_ZNK4PLMD8GridBase8getPointERKSt6vectorIjSaIjEERS1_IdSaIdEE2720102
_ZNK4PLMD8GridBase8getPointEm28822337
_ZNK4PLMD8GridBase8getPointEmRSt6vectorIdSaIdEE29932618
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Grid.h.gcov.html b/coverage/tools/Grid.h.gcov.html new file mode 100644 index 000000000000..1889bab2d0c4 --- /dev/null +++ b/coverage/tools/Grid.h.gcov.html @@ -0,0 +1,696 @@ + + + + + + + + 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:8888100.0 %
Date:2024-04-19 12:12:35Functions:242596.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_Grid_h
+      23             : #define __PLUMED_tools_Grid_h
+      24             : 
+      25             : #include <vector>
+      26             : #include <array>
+      27             : #include <string>
+      28             : #include <map>
+      29             : #include <cmath>
+      30             : #include <memory>
+      31             : #include <cstddef>
+      32             : 
+      33             : #include "Exception.h"
+      34             : 
+      35             : namespace PLMD {
+      36             : 
+      37             : 
+      38             : // simple function to enable various weighting
+      39             : 
+      40             : class WeightBase {
+      41             : public:
+      42             :   virtual double projectInnerLoop(double &input, double &v)=0;
+      43             :   virtual double projectOuterLoop(double &v)=0;
+      44             :   virtual ~WeightBase() {}
+      45             : };
+      46             : 
+      47           3 : class BiasWeight:public WeightBase {
+      48             : public:
+      49             :   double beta,invbeta;
+      50             :   double shift=0.0;
+      51           3 :   explicit BiasWeight(double v) {beta=v; invbeta=1./beta;}
+      52             :   //double projectInnerLoop(double &input, double &v) override {return  input+exp(beta*v);}
+      53             :   //double projectOuterLoop(double &v) override {return -invbeta*std::log(v);}
+      54       13603 :   double projectInnerLoop(double &input, double &v) override {
+      55       13603 :     auto betav=beta*v;
+      56       13603 :     auto x=betav-shift;
+      57       13603 :     if(x>0) {
+      58        1187 :       shift=betav;
+      59        1187 :       return input*std::exp(-x)+1;
+      60             :     } else {
+      61       12416 :       return input+std::exp(x);
+      62             :     }
+      63             :   }
+      64         187 :   double projectOuterLoop(double &v) override {
+      65         187 :     auto res=-invbeta*(std::log(v)+shift);
+      66         187 :     shift=0.0;
+      67         187 :     return res;
+      68             :   }
+      69             : };
+      70             : 
+      71             : class ProbWeight:public WeightBase {
+      72             : public:
+      73             :   double beta,invbeta;
+      74             :   explicit ProbWeight(double v) {beta=v; invbeta=1./beta;}
+      75             :   double projectInnerLoop(double &input, double &v) override {return  input+v;}
+      76             :   double projectOuterLoop(double &v) override {return -invbeta*std::log(v);}
+      77             : };
+      78             : 
+      79             : 
+      80             : 
+      81             : 
+      82             : 
+      83             : 
+      84             : class Value;
+      85             : class IFile;
+      86             : class OFile;
+      87             : class KernelFunctions;
+      88             : class Communicator;
+      89             : 
+      90             : /// \ingroup TOOLBOX
+      91             : class GridBase
+      92             : {
+      93             : public:
+      94             : // we use a size_t here
+      95             : // should be 8 bytes on all 64-bit machines
+      96             : // and more portable than "unsigned long long"
+      97             :   typedef std::size_t index_t;
+      98             : // to restore old implementation (unsigned) use the following instead:
+      99             : // typedef unsigned index_t;
+     100             : /// Maximum dimension (exaggerated value).
+     101             : /// Can be used to replace local std::vectors with std::arrays (allocated on stack).
+     102             :   static constexpr std::size_t maxdim=16;
+     103             : 
+     104             : 
+     105             :   /**
+     106             :   Auxiliary class for accelerating grid calculations.
+     107             : 
+     108             :   Many functions in the Grid class have loops running over the dimensions.
+     109             :   These loops are always with a little number of iterations, so would likely
+     110             :   benefit unrolling. Even better, if the compiler knew the dimension a priori
+     111             :   it could remove the loops in most common cases (e.g. dimension=1 or 2).
+     112             : 
+     113             :   To obtain this, I added this AcceleratorBase class. Specifically:
+     114             :   - Any method in the Grid class that is a bottleneck in performance and
+     115             :     has a loop can be moved to this auxiliary class.
+     116             :   - The method should be declared here as a pure virtual function
+     117             :     of class AcceleratorBase. The implementation instead goes in
+     118             :     class Accelerator
+     119             :   - Class Accelerator is derived from AcceleratorBase but depends on
+     120             :     dimension as a template variable.
+     121             :   - The function AcceleratorBase::create takes case of constructing
+     122             :     accelerators for each possible value of dimension.
+     123             : 
+     124             :   The trick works because we don't expect dimension to ever be very
+     125             :   high. By restricting it to <=16, we can have a limited number of
+     126             :   compiled instances. The compiler will choose at runtime which one should
+     127             :   be used.
+     128             : 
+     129             :   This class, as well as the derived classes, are expected to be
+     130             :   empty. In other words, they only contain the pointer to a virtual
+     131             :   table that the compiler will use to call the proper implementation
+     132             :   variant, with the correct dimension.
+     133             : 
+     134             :   \warning
+     135             :   Interface might change at any time.
+     136             :   Do not use this outside of class GridBase and children.
+     137             :   */
+     138             :   class AcceleratorBase {
+     139             :   public:
+     140             :     /// Creates an accelerator with proper dimension
+     141             :     static std::unique_ptr<AcceleratorBase> create(unsigned dim);
+     142             :     virtual ~AcceleratorBase() = default;
+     143             :     /// Can be used to check which value of dimension was used
+     144             :     virtual unsigned getDimension() const=0;
+     145             :     virtual std::vector<GridBase::index_t> getNeighbors(const GridBase& grid, const std::vector<unsigned> & nbin_,const std::vector<bool> & pbc_,const unsigned* indices,std::size_t indices_size, const std::vector<unsigned> &nneigh) const=0;
+     146             :     virtual GridBase::index_t getIndex(const GridBase& grid, const std::vector<unsigned> & nbin_, const unsigned* indices,std::size_t indices_size) const=0;
+     147             :     virtual void getPoint(const std::vector<double> & min_,const std::vector<double> & dx_, const unsigned* indices,std::size_t indices_size,double* point,std::size_t point_size) const=0;
+     148             :     virtual void getIndices(const std::vector<unsigned> & nbin_, GridBase::index_t index, unsigned* indices, std::size_t indices_size) const=0;
+     149             :     virtual void getIndices(const std::vector<double> & min_,const std::vector<double> & dx_, const std::vector<double> & x, unsigned* rindex_data,std::size_t rindex_size) const=0;
+     150             :   };
+     151             : 
+     152             :   /**
+     153             :   Auxiliary class for managing AcceleratorBase.
+     154             : 
+     155             :   class GridBase should contain a std::unique_ptr<AcceleratorBase>, which
+     156             :   can be used to access the specialized versions. However, this would
+     157             :   make a GridBase object not copyable. Instead of redefining
+     158             :   copy constructor and copy assignment for GridBase, which has a lot of
+     159             :   members, we use this wrapper class that just manages the lifetime
+     160             :   of the underlying Accelerator object.
+     161             : 
+     162             :   The underlying object is made accessible through the -> operator,
+     163             :   so that one can simply call functions as accelerator->function.
+     164             : 
+     165             :   \warning
+     166             :   Interface might change at any time.
+     167             :   Do not use this outside of class GridBase and children.
+     168             :   */
+     169        2959 :   class AcceleratorHandler {
+     170             :     /// This is the underlying pointer.
+     171             :     std::unique_ptr<AcceleratorBase> ptr;
+     172             :   public:
+     173             :     /// Enable access to methods of AcceleratorBase
+     174             :     const AcceleratorBase* operator->() const {
+     175             :       return ptr.get();
+     176             :     }
+     177             :     /// Enable access to methods of AcceleratorBase
+     178             :     AcceleratorBase* operator->() {
+     179             :       return ptr.get();
+     180             :     }
+     181             :     /// Conversion to bool allows to check if the ptr has been set
+     182             :     explicit operator bool() const noexcept {
+     183             :       return bool(ptr);
+     184             :     }
+     185             :     /// Move constructor
+     186          49 :     AcceleratorHandler(const AcceleratorHandler& other):
+     187          49 :       ptr((other.ptr?AcceleratorBase::create(other->getDimension()):nullptr))
+     188          49 :     {}
+     189             :     /// Move assignment
+     190        1455 :     AcceleratorHandler & operator=(const AcceleratorHandler & other) {
+     191        1455 :       if(this!=&other) {
+     192             :         ptr.reset();
+     193        2910 :         if(other.ptr) ptr=AcceleratorBase::create(other->getDimension());
+     194             :       }
+     195        1455 :       return *this;
+     196             :     }
+     197             :     /// Constructor without arguments result in a non-usable accelerator (dimension is unspecified)
+     198             :     AcceleratorHandler() = default;
+     199             :     /// Constructor with an argument creates an accelerator with a fixed dimensionality
+     200        1455 :     AcceleratorHandler(unsigned dimension):
+     201        1455 :       ptr(AcceleratorBase::create(dimension))
+     202             :     {}
+     203             :   };
+     204             : 
+     205             : protected:
+     206             :   AcceleratorHandler accelerator;
+     207             :   std::string funcname;
+     208             :   std::vector<std::string> argnames;
+     209             :   std::vector<std::string> str_min_, str_max_;
+     210             :   std::vector<double> min_,max_,dx_;
+     211             :   std::vector<unsigned> nbin_;
+     212             :   std::vector<bool> pbc_;
+     213             :   index_t maxsize_;
+     214             :   unsigned dimension_;
+     215             :   bool dospline_, usederiv_;
+     216             :   std::string fmt_; // format for output
+     217             : /// get "neighbors" for spline
+     218             :   unsigned getSplineNeighbors(const unsigned* indices, std::size_t indices_size, index_t* neighbors, std::size_t neighbors_size)const;
+     219             : // std::vector<index_t> getSplineNeighbors(const std::vector<unsigned> & indices)const;
+     220             : 
+     221             : 
+     222             : public:
+     223             : /// this constructor here is Value-aware
+     224             :   GridBase(const std::string& funcl, const std::vector<Value*> & args, const std::vector<std::string> & gmin,
+     225             :            const std::vector<std::string> & gmax, const std::vector<unsigned> & nbin, bool dospline,
+     226             :            bool usederiv);
+     227             : /// this constructor here is not Value-aware
+     228             :   GridBase(const std::string& funcl, const std::vector<std::string> &names, const std::vector<std::string> & gmin,
+     229             :            const std::vector<std::string> & gmax, const std::vector<unsigned> & nbin, bool dospline,
+     230             :            bool usederiv, const std::vector<bool> &isperiodic, const std::vector<std::string> &pmin,
+     231             :            const std::vector<std::string> &pmax );
+     232             : /// this is the real initializator
+     233             :   void Init(const std::string & funcl, const std::vector<std::string> &names, const std::vector<std::string> & gmin,
+     234             :             const std::vector<std::string> & gmax, const std::vector<unsigned> & nbin, bool dospline, bool usederiv,
+     235             :             const std::vector<bool> &isperiodic, const std::vector<std::string> &pmin, const std::vector<std::string> &pmax);
+     236             : /// get lower boundary
+     237             :   std::vector<std::string> getMin() const;
+     238             : /// get upper boundary
+     239             :   std::vector<std::string> getMax() const;
+     240             : /// get bin size
+     241             :   std::vector<double> getDx() const;
+     242             :   double getDx(index_t j) const ;
+     243             : /// get bin volume
+     244             :   double getBinVolume() const;
+     245             : /// get number of bins
+     246             :   std::vector<unsigned> getNbin() const;
+     247             : /// get if periodic
+     248             :   std::vector<bool> getIsPeriodic() const;
+     249             : /// get grid dimension
+     250             :   unsigned getDimension() const;
+     251             : /// get argument names  of this grid
+     252             :   std::vector<std::string> getArgNames() const;
+     253             : /// get if the grid has derivatives
+     254     1986398 :   bool hasDerivatives() const {return usederiv_;}
+     255             : 
+     256             : /// methods to handle grid indices
+     257             :   void getIndices(index_t index, std::vector<unsigned>& rindex) const;
+     258             :   void getIndices(index_t index, unsigned* rindex_data, std::size_t rindex_size) const;
+     259             :   void getIndices(const std::vector<double> & x, std::vector<unsigned>& rindex) const;
+     260             :   void getIndices(const std::vector<double> & x, unsigned* rindex_data,std::size_t rindex_size) const;
+     261             :   std::vector<unsigned> getIndices(index_t index) const;
+     262             :   std::vector<unsigned> getIndices(const std::vector<double> & x) const;
+     263             :   index_t getIndex(const unsigned* indices,std::size_t indices_size) const;
+     264             :   index_t getIndex(const std::vector<unsigned> & indices) const;
+     265             :   index_t getIndex(const std::vector<double> & x) const;
+     266             :   std::vector<double> getPoint(index_t index) const;
+     267             :   std::vector<double> getPoint(const std::vector<unsigned> & indices) const;
+     268             :   std::vector<double> getPoint(const std::vector<double> & x) const;
+     269             : /// faster versions relying on preallocated vectors
+     270             :   void getPoint(index_t index,std::vector<double> & point) const;
+     271             :   void getPoint(const std::vector<unsigned> & indices,std::vector<double> & point) const;
+     272             :   void getPoint(const std::vector<double> & x,std::vector<double> & point) const;
+     273             :   void getPoint(const unsigned* indices_data,std::size_t indices_size,std::vector<double> & point) const;
+     274             :   void getPoint(const unsigned* indices_data,std::size_t indices_size,double* point,std::size_t point_size) const;
+     275             : 
+     276             : /// get neighbors
+     277             :   std::vector<index_t> getNeighbors(index_t index,const std::vector<unsigned> & neigh) const;
+     278             :   std::vector<index_t> getNeighbors(const std::vector<unsigned> & indices,const std::vector<unsigned> & neigh) const;
+     279             :   std::vector<index_t> getNeighbors(const std::vector<double> & x,const std::vector<unsigned> & neigh) const;
+     280             : /// get nearest neighbors (those separated by exactly one lattice unit)
+     281             :   std::vector<index_t> getNearestNeighbors(const index_t index) const;
+     282             :   std::vector<index_t> getNearestNeighbors(const std::vector<unsigned> &indices) const;
+     283             : 
+     284             : /// write header for grid file
+     285             :   void writeHeader(OFile& file);
+     286             : 
+     287             : /// read grid from file
+     288             :   static std::unique_ptr<GridBase> create(const std::string&,const std::vector<Value*>&,IFile&,bool,bool,bool);
+     289             : /// read grid from file and check boundaries are what is expected from input
+     290             :   static std::unique_ptr<GridBase> create(const std::string&,const std::vector<Value*>&, IFile&,
+     291             :                                           const std::vector<std::string>&,const std::vector<std::string>&,
+     292             :                                           const std::vector<unsigned>&,bool,bool,bool);
+     293             : /// get grid size
+     294             :   virtual index_t getSize() const=0;
+     295             : /// get grid value
+     296             :   virtual double getValue(index_t index) const=0;
+     297             :   double getValue(const std::vector<unsigned> & indices) const;
+     298             :   double getValue(const std::vector<double> & x) const;
+     299             : /// get grid value and derivatives
+     300             :   virtual double getValueAndDerivatives(index_t index, double* der, std::size_t der_size) const=0;
+     301             :   double getValueAndDerivatives(index_t index, std::vector<double>& der) const;
+     302             :   double getValueAndDerivatives(const std::vector<unsigned> & indices, std::vector<double>& der) const;
+     303             :   double getValueAndDerivatives(const std::vector<double> & x, std::vector<double>& der) const;
+     304             : 
+     305             : /// set grid value
+     306             :   virtual void setValue(index_t index, double value)=0;
+     307             :   void setValue(const std::vector<unsigned> & indices, double value);
+     308             : /// set grid value and derivatives
+     309             :   virtual void setValueAndDerivatives(index_t index, double value, std::vector<double>& der)=0;
+     310             :   void setValueAndDerivatives(const std::vector<unsigned> & indices, double value, std::vector<double>& der);
+     311             : /// add to grid value
+     312             :   virtual void addValue(index_t index, double value)=0;
+     313             :   void addValue(const std::vector<unsigned> & indices, double value);
+     314             : /// add to grid value and derivatives
+     315             :   virtual void addValueAndDerivatives(index_t index, double value, std::vector<double>& der)=0;
+     316             :   void addValueAndDerivatives(const std::vector<unsigned> & indices, double value, std::vector<double>& der);
+     317             : /// add a kernel function to the grid
+     318             :   void addKernel( const KernelFunctions& kernel );
+     319             : 
+     320             : /// get minimum value
+     321             :   virtual double getMinValue() const = 0;
+     322             : /// get maximum value
+     323             :   virtual double getMaxValue() const = 0;
+     324             : 
+     325             : /// dump grid on file
+     326             :   virtual void writeToFile(OFile&)=0;
+     327             : /// dump grid to gaussian cube file
+     328             :   void writeCubeFile(OFile&, const double& lunit);
+     329             : 
+     330        3008 :   virtual ~GridBase() = default;
+     331             : 
+     332             : /// set output format
+     333         197 :   void setOutputFmt(const std::string & ss) {fmt_=ss;}
+     334             : /// reset output format to the default %14.9f format
+     335             :   void resetToDefaultOutputFmt() {fmt_="%14.9f";}
+     336             : ///
+     337             : /// Find the maximum over paths of the minimum value of the gridded function along the paths
+     338             : /// for all paths of neighboring grid lattice points from a source point to a sink point.
+     339             :   double findMaximalPathMinimum(const std::vector<double> &source, const std::vector<double> &sink);
+     340             : };
+     341             : 
+     342             : class Grid : public GridBase
+     343             : {
+     344             :   std::vector<double> grid_;
+     345             :   std::vector<double> der_;
+     346             :   double contour_location=0.0;
+     347             : public:
+     348        1321 :   Grid(const std::string& funcl, const std::vector<Value*> & args, const std::vector<std::string> & gmin,
+     349             :        const std::vector<std::string> & gmax,
+     350        1321 :        const std::vector<unsigned> & nbin, bool dospline, bool usederiv):
+     351        1321 :     GridBase(funcl,args,gmin,gmax,nbin,dospline,usederiv)
+     352             :   {
+     353        1321 :     grid_.assign(maxsize_,0.0);
+     354        1321 :     if(usederiv_) der_.assign(maxsize_*dimension_,0.0);
+     355        1321 :   }
+     356             : /// this constructor here is not Value-aware
+     357         128 :   Grid(const std::string& funcl, const std::vector<std::string> &names, const std::vector<std::string> & gmin,
+     358             :        const std::vector<std::string> & gmax, const std::vector<unsigned> & nbin, bool dospline,
+     359             :        bool usederiv, const std::vector<bool> &isperiodic, const std::vector<std::string> &pmin,
+     360         128 :        const std::vector<std::string> &pmax ):
+     361         128 :     GridBase(funcl,names,gmin,gmax,nbin,dospline,usederiv,isperiodic,pmin,pmax)
+     362             :   {
+     363         128 :     grid_.assign(maxsize_,0.0);
+     364         128 :     if(usederiv_) der_.assign(maxsize_*dimension_,0.0);
+     365         128 :   }
+     366             :   index_t getSize() const override;
+     367             : /// this is to access to Grid:: version of these methods (allowing overloading of virtual methods)
+     368             :   using GridBase::getValue;
+     369             :   using GridBase::getValueAndDerivatives;
+     370             :   using GridBase::setValue;
+     371             :   using GridBase::setValueAndDerivatives;
+     372             :   using GridBase::addValue;
+     373             :   using GridBase::addValueAndDerivatives;
+     374             : /// get grid value
+     375             :   double getValue(index_t index) const override;
+     376             : /// get grid value and derivatives
+     377             :   double getValueAndDerivatives(index_t index, double* der, std::size_t der_size) const override;
+     378             : /// set grid value
+     379             :   void setValue(index_t index, double value) override;
+     380             : /// set grid value and derivatives
+     381             :   void setValueAndDerivatives(index_t index, double value, std::vector<double>& der) override;
+     382             : /// add to grid value
+     383             :   void addValue(index_t index, double value) override;
+     384             : /// add to grid value and derivatives
+     385             :   void addValueAndDerivatives(index_t index, double value, std::vector<double>& der) override;
+     386             : 
+     387             : /// get minimum value
+     388             :   double getMinValue() const override;
+     389             : /// get maximum value
+     390             :   double getMaxValue() const override;
+     391             : /// Scale all grid values and derivatives by a constant factor
+     392             :   void scaleAllValuesAndDerivatives( const double& scalef );
+     393             : /// Takes the scalef times the logarithm of all grid values and derivatives
+     394             :   void logAllValuesAndDerivatives( const double& scalef );
+     395             : /// dump grid on file
+     396             :   void writeToFile(OFile&) override;
+     397             : 
+     398             : /// Set the minimum value of the grid to zero and translates accordingly
+     399             :   void setMinToZero();
+     400             : /// apply function: takes  pointer to  function that accepts a double and apply
+     401             :   void applyFunctionAllValuesAndDerivatives( double (*func)(double val), double (*funcder)(double valder) );
+     402             : /// Get the difference from the contour
+     403             :   double getDifferenceFromContour(const std::vector<double> & x, std::vector<double>& der) const ;
+     404             : /// Find a set of points on a contour in the function
+     405             :   void findSetOfPointsOnContour(const double& target, const std::vector<bool>& nosearch, unsigned& npoints, std::vector<std::vector<double> >& points );
+     406             : /// Since this method returns a concrete Grid, it should be here and not in GridBase - GB
+     407             : /// project a high dimensional grid onto a low dimensional one: this should be changed at some time
+     408             : /// to enable many types of weighting
+     409             :   Grid project( const std::vector<std::string> & proj, WeightBase *ptr2obj  );
+     410             :   void projectOnLowDimension(double &val, std::vector<int> &varHigh, WeightBase* ptr2obj );
+     411             :   void mpiSumValuesAndDerivatives( Communicator& comm );
+     412             : /// Integrate the function calculated on the grid
+     413             :   double integrate( std::vector<unsigned>& npoints );
+     414             :   void clear();
+     415             : };
+     416             : 
+     417             : 
+     418             : class SparseGrid : public GridBase
+     419             : {
+     420             : 
+     421             :   std::map<index_t,double> map_;
+     422             :   std::map< index_t,std::vector<double> > der_;
+     423             : 
+     424             : public:
+     425           6 :   SparseGrid(const std::string& funcl, const std::vector<Value*> & args, const std::vector<std::string> & gmin,
+     426             :              const std::vector<std::string> & gmax,
+     427           6 :              const std::vector<unsigned> & nbin, bool dospline, bool usederiv):
+     428           6 :     GridBase(funcl,args,gmin,gmax,nbin,dospline,usederiv) {}
+     429             : 
+     430             :   index_t getSize() const override;
+     431             :   index_t getMaxSize() const;
+     432             : 
+     433             : /// this is to access to Grid:: version of these methods (allowing overloading of virtual methods)
+     434             :   using GridBase::getValue;
+     435             :   using GridBase::getValueAndDerivatives;
+     436             :   using GridBase::setValue;
+     437             :   using GridBase::setValueAndDerivatives;
+     438             :   using GridBase::addValue;
+     439             :   using GridBase::addValueAndDerivatives;
+     440             : 
+     441             : /// get grid value
+     442             :   double getValue(index_t index) const override;
+     443             : /// get grid value and derivatives
+     444             :   double getValueAndDerivatives(index_t index, double* der, std::size_t der_size) const override;
+     445             : 
+     446             : /// set grid value
+     447             :   void setValue(index_t index, double value) override;
+     448             : /// set grid value and derivatives
+     449             :   void setValueAndDerivatives(index_t index, double value, std::vector<double>& der) override;
+     450             : /// add to grid value
+     451             :   void addValue(index_t index, double value) override;
+     452             : /// add to grid value and derivatives
+     453             :   void addValueAndDerivatives(index_t index, double value, std::vector<double>& der) override;
+     454             : 
+     455             : /// get minimum value
+     456             :   double getMinValue() const override;
+     457             : /// get maximum value
+     458             :   double getMaxValue() const override;
+     459             : /// dump grid on file
+     460             :   void writeToFile(OFile&) override;
+     461             : 
+     462          18 :   virtual ~SparseGrid() = default;
+     463             : };
+     464             : 
+     465             : 
+     466             : inline
+     467     5900533 : GridBase::index_t GridBase::getIndex(const unsigned* indices,std::size_t indices_size) const {
+     468             :   plumed_dbg_assert(accelerator);
+     469     5900533 :   return accelerator->getIndex(*this,nbin_,indices,indices_size);
+     470             : }
+     471             : 
+     472             : inline
+     473     4791554 : GridBase::index_t GridBase::getIndex(const std::vector<unsigned> & indices) const {
+     474             :   plumed_dbg_assert(indices.size()==dimension_);
+     475     4791554 :   return getIndex(indices.data(),indices.size());
+     476             : }
+     477             : 
+     478             : inline
+     479     1100069 : GridBase::index_t GridBase::getIndex(const std::vector<double> & x) const {
+     480             :   plumed_dbg_assert(x.size()==dimension_);
+     481             :   std::array<unsigned,maxdim> indices;
+     482     1100069 :   getIndices(x,indices.data(),dimension_);
+     483     1100069 :   return getIndex(indices.data(),dimension_);
+     484             : }
+     485             : 
+     486             : inline
+     487     7877712 : std::vector<unsigned> GridBase::getIndices(index_t index) const {
+     488     7877712 :   std::vector<unsigned> indices(dimension_);
+     489     7877712 :   getIndices(index,indices.data(),indices.size());
+     490     7877712 :   return indices;
+     491             : }
+     492             : 
+     493             : inline
+     494    37819240 : void GridBase::getIndices(index_t index, unsigned* indices, std::size_t indices_size) const {
+     495    37819240 :   plumed_assert(indices_size==dimension_);
+     496    37819240 :   plumed_assert(accelerator);
+     497    37819240 :   accelerator->getIndices(nbin_,index,indices,dimension_);
+     498    37819240 : }
+     499             : 
+     500             : inline
+     501             : void GridBase::getIndices(index_t index, std::vector<unsigned>& indices) const {
+     502             :   if (indices.size()!=dimension_) indices.resize(dimension_);
+     503             :   getIndices(index,indices.data(),indices.size());
+     504             : }
+     505             : 
+     506             : inline
+     507             : std::vector<unsigned> GridBase::getIndices(const std::vector<double> & x) const {
+     508             :   plumed_dbg_assert(x.size()==dimension_);
+     509             :   std::vector<unsigned> indices(dimension_);
+     510             :   getIndices(x,indices);
+     511             :   return indices;
+     512             : }
+     513             : 
+     514             : inline
+     515             : void GridBase::getIndices(const std::vector<double> & x, std::vector<unsigned>& indices) const {
+     516             :   indices.resize(dimension_);
+     517             :   getIndices(x,indices.data(),indices.size());
+     518             : }
+     519             : 
+     520             : inline
+     521     1103780 : void GridBase::getIndices(const std::vector<double> & x, unsigned* rindex_data,std::size_t rindex_size) const {
+     522             :   plumed_dbg_assert(x.size()==dimension_);
+     523             :   plumed_dbg_assert(rindex_size==dimension_);
+     524     1103780 :   accelerator->getIndices(min_,dx_,x,rindex_data,rindex_size);
+     525     1103780 : }
+     526             : 
+     527             : inline
+     528    32656431 : void GridBase::getPoint(const unsigned* indices,std::size_t indices_size,double* point,std::size_t point_size) const {
+     529             :   plumed_dbg_assert(indices_size==dimension_);
+     530             :   plumed_dbg_assert(point_size==dimension_);
+     531             :   plumed_dbg_assert(accelerator);
+     532    32656431 :   accelerator->getPoint(min_,dx_,indices,indices_size,point,point_size);
+     533    32656431 : }
+     534             : 
+     535             : inline
+     536     2720102 : std::vector<double> GridBase::getPoint(const std::vector<unsigned> & indices) const {
+     537             :   plumed_dbg_assert(indices.size()==dimension_);
+     538     2720102 :   std::vector<double> x(dimension_);
+     539     2720102 :   getPoint(indices,x);
+     540     2720102 :   return x;
+     541             : }
+     542             : 
+     543             : inline
+     544    28822337 : std::vector<double> GridBase::getPoint(index_t index) const {
+     545             :   plumed_dbg_assert(index<maxsize_);
+     546    28822337 :   std::vector<double> x(dimension_);
+     547    28822337 :   getPoint(index,x);
+     548    28822337 :   return x;
+     549             : }
+     550             : 
+     551             : inline
+     552             : std::vector<double> GridBase::getPoint(const std::vector<double> & x) const {
+     553             :   plumed_dbg_assert(x.size()==dimension_);
+     554             :   std::vector<double> r(dimension_);
+     555             :   getPoint(x,r);
+     556             :   return r;
+     557             : }
+     558             : 
+     559             : inline
+     560    29932618 : void GridBase::getPoint(index_t index,std::vector<double> & point) const {
+     561             :   plumed_dbg_assert(index<maxsize_);
+     562             :   std::array<unsigned,maxdim> indices;
+     563    29932618 :   getIndices(index,indices.data(),dimension_);
+     564    29932618 :   getPoint(indices.data(),dimension_,point);
+     565    29932618 : }
+     566             : 
+     567             : inline
+     568     2720102 : void GridBase::getPoint(const std::vector<unsigned> & indices,std::vector<double> & point) const {
+     569             :   plumed_dbg_assert(indices.size()==dimension_);
+     570             :   plumed_dbg_assert(point.size()==dimension_);
+     571     2720102 :   getPoint(indices.data(),indices.size(),point.data(),point.size());
+     572     2720102 : }
+     573             : 
+     574             : inline
+     575    29932618 : void GridBase::getPoint(const unsigned* indices_data,std::size_t indices_size,std::vector<double> & point) const {
+     576             :   plumed_dbg_assert(indices_size==dimension_);
+     577             :   plumed_dbg_assert(point.size()==dimension_);
+     578    29932618 :   getPoint(indices_data,indices_size,point.data(),point.size());
+     579    29932618 : }
+     580             : 
+     581             : inline
+     582             : void GridBase::getPoint(const std::vector<double> & x,std::vector<double> & point) const {
+     583             :   plumed_dbg_assert(x.size()==dimension_);
+     584             :   std::array<unsigned,maxdim> indices;
+     585             :   getIndices(x,indices.data(),dimension_);
+     586             :   getPoint(indices.data(),dimension_,point.data(),point.size());
+     587             : }
+     588             : 
+     589             : inline
+     590             : std::vector<GridBase::index_t> GridBase::getNeighbors(const std::vector<unsigned> &indices,const std::vector<unsigned> &nneigh)const {
+     591             :   plumed_dbg_assert(accelerator);
+     592             :   return accelerator->getNeighbors(*this,nbin_,pbc_,indices.data(),indices.size(),nneigh);
+     593             : }
+     594             : 
+     595             : inline
+     596        4211 : std::vector<GridBase::index_t> GridBase::getNeighbors(const std::vector<double> & x,const std::vector<unsigned> & nneigh)const {
+     597             :   plumed_dbg_assert(x.size()==dimension_ && nneigh.size()==dimension_);
+     598             :   std::array<unsigned,maxdim> indices;
+     599             :   plumed_dbg_assert(accelerator);
+     600        4211 :   accelerator->getIndices(min_,dx_,x,indices.data(),dimension_);
+     601        4211 :   return accelerator->getNeighbors(*this,nbin_,pbc_,indices.data(),dimension_,nneigh);
+     602             : }
+     603             : 
+     604             : inline
+     605       19153 : std::vector<GridBase::index_t> GridBase::getNeighbors(index_t index,const std::vector<unsigned> & nneigh)const {
+     606             :   plumed_dbg_assert(index<maxsize_ && nneigh.size()==dimension_);
+     607             :   std::array<unsigned,maxdim> indices;
+     608             :   plumed_dbg_assert(accelerator);
+     609       19153 :   accelerator->getIndices(nbin_,index,indices.data(),dimension_);
+     610       19153 :   return accelerator->getNeighbors(*this,nbin_,pbc_,indices.data(),dimension_,nneigh);
+     611             : }
+     612             : 
+     613             : 
+     614             : 
+     615             : 
+     616             : 
+     617             : }
+     618             : 
+     619             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/HistogramBead.cpp.func-sort-c.html b/coverage/tools/HistogramBead.cpp.func-sort-c.html new file mode 100644 index 000000000000..a7375280f933 --- /dev/null +++ b/coverage/tools/HistogramBead.cpp.func-sort-c.html @@ -0,0 +1,117 @@ + + + + + + + + LCOV - plumed test coverage - tools/HistogramBead.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - HistogramBead.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:7011859.3 %
Date:2024-04-19 12:12:35Functions:91181.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD13HistogramBead12generateBinsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIS6_SaIS6_EE0
_ZN4PLMD13HistogramBead16registerKeywordsERNS_8KeywordsE0
_ZN4PLMD13HistogramBead3setERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS6_53
_ZNK4PLMD13HistogramBead11descriptionB5cxx11Ev53
_ZNK4PLMD13HistogramBead16lboundDerivativeERKd4680
_ZNK4PLMD13HistogramBead16uboundDerivativeERKd4680
_ZNK4PLMD13HistogramBead9calculateEdRd251184
_ZN4PLMD13HistogramBead13setKernelTypeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE260148
_ZN4PLMD13HistogramBeadC2Ev260366
_ZNK4PLMD13HistogramBead19calculateWithCutoffEdRd920596
_ZN4PLMD13HistogramBead3setEddd2668474
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/HistogramBead.cpp.func.html b/coverage/tools/HistogramBead.cpp.func.html new file mode 100644 index 000000000000..49b1d784bc1f --- /dev/null +++ b/coverage/tools/HistogramBead.cpp.func.html @@ -0,0 +1,117 @@ + + + + + + + + LCOV - plumed test coverage - tools/HistogramBead.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - HistogramBead.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:7011859.3 %
Date:2024-04-19 12:12:35Functions:91181.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD13HistogramBead12generateBinsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIS6_SaIS6_EE0
_ZN4PLMD13HistogramBead13setKernelTypeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE260148
_ZN4PLMD13HistogramBead16registerKeywordsERNS_8KeywordsE0
_ZN4PLMD13HistogramBead3setERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS6_53
_ZN4PLMD13HistogramBead3setEddd2668474
_ZN4PLMD13HistogramBeadC2Ev260366
_ZNK4PLMD13HistogramBead11descriptionB5cxx11Ev53
_ZNK4PLMD13HistogramBead16lboundDerivativeERKd4680
_ZNK4PLMD13HistogramBead16uboundDerivativeERKd4680
_ZNK4PLMD13HistogramBead19calculateWithCutoffEdRd920596
_ZNK4PLMD13HistogramBead9calculateEdRd251184
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/HistogramBead.cpp.gcov.html b/coverage/tools/HistogramBead.cpp.gcov.html new file mode 100644 index 000000000000..977409e0ad71 --- /dev/null +++ b/coverage/tools/HistogramBead.cpp.gcov.html @@ -0,0 +1,342 @@ + + + + + + + + LCOV - plumed test coverage - tools/HistogramBead.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - HistogramBead.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:7011859.3 %
Date:2024-04-19 12:12:35Functions:91181.8 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "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           0 : void HistogramBead::registerKeywords( Keywords& keys ) {
+      88           0 :   keys.add("compulsory","LOWER","the lower boundary for this particular bin");
+      89           0 :   keys.add("compulsory","UPPER","the upper boundary for this particular bin");
+      90           0 :   keys.add("compulsory","SMEAR","0.5","the amount to smear the Gaussian for each value in the distribution");
+      91           0 : }
+      92             : 
+      93      260366 : HistogramBead::HistogramBead():
+      94      260366 :   init(false),
+      95      260366 :   lowb(0.0),
+      96      260366 :   highb(0.0),
+      97      260366 :   width(0.0),
+      98      260366 :   cutoff(std::numeric_limits<double>::max()),
+      99      260366 :   type(gaussian),
+     100      260366 :   periodicity(unset),
+     101      260366 :   min(0.0),
+     102      260366 :   max(0.0),
+     103      260366 :   max_minus_min(0.0),
+     104      260366 :   inv_max_minus_min(0.0)
+     105             : {
+     106      260366 : }
+     107             : 
+     108          53 : std::string HistogramBead::description() const {
+     109          53 :   std::ostringstream ostr;
+     110          53 :   ostr<<"between "<<lowb<<" and "<<highb<<" width of gaussian window equals "<<width;
+     111          53 :   return ostr.str();
+     112          53 : }
+     113             : 
+     114           0 : void HistogramBead::generateBins( const std::string& params, std::vector<std::string>& bins ) {
+     115           0 :   std::vector<std::string> data=Tools::getWords(params);
+     116           0 :   plumed_massert(data.size()>=1,"There is no input for this keyword");
+     117             : 
+     118           0 :   std::string name=data[0];
+     119             : 
+     120           0 :   unsigned nbins; std::vector<double> range(2); std::string smear;
+     121           0 :   bool found_nb=Tools::parse(data,"NBINS",nbins);
+     122           0 :   plumed_massert(found_nb,"Number of bins in histogram not found");
+     123           0 :   bool found_r=Tools::parse(data,"LOWER",range[0]);
+     124           0 :   plumed_massert(found_r,"Lower bound for histogram not specified");
+     125           0 :   found_r=Tools::parse(data,"UPPER",range[1]);
+     126           0 :   plumed_massert(found_r,"Upper bound for histogram not specified");
+     127           0 :   plumed_massert(range[0]<range[1],"Range specification is dubious");
+     128           0 :   bool found_b=Tools::parse(data,"SMEAR",smear);
+     129           0 :   if(!found_b) { Tools::convert(0.5,smear); }
+     130             : 
+     131           0 :   std::string lb,ub; double delr = ( range[1]-range[0] ) / static_cast<double>( nbins );
+     132           0 :   for(unsigned i=0; i<nbins; ++i) {
+     133           0 :     Tools::convert( range[0]+i*delr, lb );
+     134           0 :     Tools::convert( range[0]+(i+1)*delr, ub );
+     135           0 :     bins.push_back( name + " " +  "LOWER=" + lb + " " + "UPPER=" + ub + " " + "SMEAR=" + smear );
+     136             :   }
+     137           0 :   plumed_assert(bins.size()==nbins);
+     138           0 : }
+     139             : 
+     140          53 : void HistogramBead::set( const std::string& params, std::string& errormsg ) {
+     141          53 :   std::vector<std::string> data=Tools::getWords(params);
+     142          53 :   if(data.size()<1) {
+     143             :     errormsg="No input has been specified";
+     144             :     return;
+     145             :   }
+     146             : 
+     147          53 :   std::string name=data[0]; const double DP2CUTOFF=6.25;
+     148          53 :   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          53 :   bool found_r=Tools::parse(data,"LOWER",lowb);
+     154          53 :   if( !found_r ) errormsg="Lower bound has not been specified use LOWER";
+     155          53 :   found_r=Tools::parse(data,"UPPER",highb);
+     156          53 :   if( !found_r ) errormsg="Upper bound has not been specified use UPPER";
+     157          53 :   if( lowb>=highb ) errormsg="Lower bound is higher than upper bound";
+     158             : 
+     159          53 :   smear=0.5; Tools::parse(data,"SMEAR",smear);
+     160          53 :   width=smear*(highb-lowb); init=true;
+     161          53 : }
+     162             : 
+     163     2668474 : void HistogramBead::set( double l, double h, double w) {
+     164     2668474 :   init=true; lowb=l; highb=h; width=w;
+     165             :   const double DP2CUTOFF=6.25;
+     166     2668474 :   if( type==gaussian ) cutoff=std::sqrt(2.0*DP2CUTOFF);
+     167     1935352 :   else if( type==triangular ) cutoff=1.;
+     168           0 :   else plumed_error();
+     169     2668474 : }
+     170             : 
+     171      260148 : void HistogramBead::setKernelType( const std::string& ktype ) {
+     172      260148 :   if(ktype=="gaussian") type=gaussian;
+     173       26252 :   else if(ktype=="triangular") type=triangular;
+     174           0 :   else plumed_merror("cannot understand kernel type " + ktype );
+     175      260148 : }
+     176             : 
+     177      251184 : double HistogramBead::calculate( double x, double& df ) const {
+     178             :   plumed_dbg_assert(init && periodicity!=unset );
+     179             :   double lowB, upperB, f;
+     180      251184 :   if( type==gaussian ) {
+     181      251184 :     lowB = difference( x, lowb ) / ( std::sqrt(2.0) * width );
+     182      251184 :     upperB = difference( x, highb ) / ( std::sqrt(2.0) * width );
+     183      251184 :     df = ( exp( -lowB*lowB ) - exp( -upperB*upperB ) ) / ( std::sqrt(2*pi)*width );
+     184      251184 :     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      251184 :   return f;
+     203             : }
+     204             : 
+     205      920596 : double HistogramBead::calculateWithCutoff( double x, double& df ) const {
+     206             :   plumed_dbg_assert(init && periodicity!=unset );
+     207             : 
+     208             :   double lowB, upperB, f;
+     209      920596 :   lowB = difference( x, lowb ) / width ; upperB = difference( x, highb ) / width;
+     210      920596 :   if( upperB<=-cutoff || lowB>=cutoff ) { df=0; return 0; }
+     211             : 
+     212      832917 :   if( type==gaussian ) {
+     213      446395 :     lowB /= std::sqrt(2.0); upperB /= std::sqrt(2.0);
+     214      446395 :     df = ( exp( -lowB*lowB ) - exp( -upperB*upperB ) ) / ( std::sqrt(2*pi)*width );
+     215      446395 :     f = 0.5*( erf( upperB ) - erf( lowB ) );
+     216      386522 :   } else if( type==triangular ) {
+     217      386522 :     df=0;
+     218      386522 :     if( std::fabs(lowB)<1. ) df = (1 - std::fabs(lowB)) / width;
+     219      386522 :     if( std::fabs(upperB)<1. ) df -= (1 - std::fabs(upperB)) / width;
+     220      386522 :     if (upperB<=-1. || lowB >=1.) {
+     221             :       f=0.;
+     222             :     } else {
+     223             :       double ia, ib;
+     224      386522 :       if( lowB>-1.0 ) { ia=lowB; } else { ia=-1.0; }
+     225      386522 :       if( upperB<1.0 ) { ib=upperB; } else { ib=1.0; }
+     226      386522 :       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        4680 : double HistogramBead::lboundDerivative( const double& x ) const {
+     235        4680 :   if( type==gaussian ) {
+     236        4680 :     double lowB = difference( x, lowb ) / ( std::sqrt(2.0) * width );
+     237        4680 :     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        4680 : double HistogramBead::uboundDerivative( const double& x ) const {
+     250             :   plumed_dbg_assert(init && periodicity!=unset );
+     251        4680 :   if( type==gaussian ) {
+     252        4680 :     double upperB = difference( x, highb ) / ( std::sqrt(2.0) * width );
+     253        4680 :     return exp( -upperB*upperB ) / ( std::sqrt(2*pi)*width );
+     254           0 :   } else if ( type==triangular ) {
+     255           0 :     plumed_error();
+     256             : //      upperB = fabs( difference( x, highb ) / width );
+     257             : //      if( upperB<1 ) return ( 1 - (upperB) ) / 2*width;
+     258             : //      else return 0;
+     259             :   } else {
+     260           0 :     plumed_merror("function type does not exist");
+     261             :   }
+     262             :   return 0;
+     263             : }
+     264             : 
+     265             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/HistogramBead.h.func-sort-c.html b/coverage/tools/HistogramBead.h.func-sort-c.html new file mode 100644 index 000000000000..47823c5a5fbb --- /dev/null +++ b/coverage/tools/HistogramBead.h.func-sort-c.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - tools/HistogramBead.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - HistogramBead.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:171894.4 %
Date:2024-04-19 12:12:35Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD13HistogramBead10isPeriodicERKdS2_133401
_ZNK4PLMD13HistogramBead10differenceERKdS2_2352920
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/HistogramBead.h.func.html b/coverage/tools/HistogramBead.h.func.html new file mode 100644 index 000000000000..80ca90d238e6 --- /dev/null +++ b/coverage/tools/HistogramBead.h.func.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - tools/HistogramBead.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - HistogramBead.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:171894.4 %
Date:2024-04-19 12:12:35Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD13HistogramBead10isPeriodicERKdS2_133401
_ZNK4PLMD13HistogramBead10differenceERKdS2_2352920
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/HistogramBead.h.gcov.html b/coverage/tools/HistogramBead.h.gcov.html new file mode 100644 index 000000000000..0d02acbce0ec --- /dev/null +++ b/coverage/tools/HistogramBead.h.gcov.html @@ -0,0 +1,191 @@ + + + + + + + + LCOV - plumed test coverage - tools/HistogramBead.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - HistogramBead.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:171894.4 %
Date:2024-04-19 12:12:35Functions: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      126782 :   periodicity=notperiodic;
+      79          52 : }
+      80             : 
+      81             : inline
+      82      133401 : void HistogramBead::isPeriodic( const double& mlow, const double& mhigh ) {
+      83      133401 :   periodicity=periodic; min=mlow; max=mhigh;
+      84      133401 :   max_minus_min=max-min;
+      85      133401 :   plumed_massert(max_minus_min>0, "your function has a very strange domain?");
+      86      133401 :   inv_max_minus_min=1.0/max_minus_min;
+      87      133401 : }
+      88             : 
+      89             : inline
+      90             : double HistogramBead::getlowb() const { return lowb; }
+      91             : 
+      92             : inline
+      93             : double HistogramBead::getbigb() const { return highb; }
+      94             : 
+      95             : inline
+      96     1937582 : double HistogramBead::getCutoff() const { return cutoff*width; }
+      97             : 
+      98             : inline
+      99     2352920 : double HistogramBead::difference( const double& d1, const double& d2 ) const {
+     100     2352920 :   if(periodicity==notperiodic) {
+     101     1285700 :     return d2-d1;
+     102     1067220 :   } else if(periodicity==periodic) {
+     103             :     // Make sure the point is in the target range
+     104     1067220 :     double newx=d1*inv_max_minus_min;
+     105     1067220 :     newx=Tools::pbc(newx);
+     106     1067220 :     newx*=max_minus_min;
+     107     1067220 :     return d2-newx;
+     108           0 :   } else plumed_merror("periodicty was not set");
+     109             :   return 0;
+     110             : }
+     111             : 
+     112             : }
+     113             : 
+     114             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/IFile.cpp.func-sort-c.html b/coverage/tools/IFile.cpp.func-sort-c.html new file mode 100644 index 000000000000..ffcd426fce42 --- /dev/null +++ b/coverage/tools/IFile.cpp.func-sort-c.html @@ -0,0 +1,173 @@ + + + + + + + + LCOV - plumed test coverage - tools/IFile.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - IFile.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:14515196.0 %
Date:2024-04-19 12:12:35Functions: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
_ZN4PLMD5IFile10allowNoEOLEv1012
_ZN4PLMD5IFile4openERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1485
_ZN4PLMD5IFileC1Ev1776
_ZN4PLMD5IFileD1Ev1776
_ZN4PLMD5IFile18allowIgnoredFieldsEv5789
_ZN4PLMD5IFile5resetEb6133
_ZN4PLMD5IFile9scanFieldEPNS_5ValueE1103520
_ZN4PLMD5IFile10FieldExistERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1142741
_ZN4PLMD5IFile13scanFieldListERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EE1142844
_ZN4PLMD5IFile9scanFieldEv1569177
_ZN4PLMD5IFile12advanceFieldEv1575602
_ZN4PLMD5IFile7getlineERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1728954
_ZN4PLMD5IFile9scanFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERi2466867
_ZN4PLMD5IFile9scanFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERd7524296
_ZNK4PLMD5IFile9findFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE16619485
_ZN4PLMD5IFile9scanFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS6_16625845
_ZN4PLMD5IFile6llreadEPcm113804054
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/IFile.cpp.func.html b/coverage/tools/IFile.cpp.func.html new file mode 100644 index 000000000000..8cb09bdc942e --- /dev/null +++ b/coverage/tools/IFile.cpp.func.html @@ -0,0 +1,173 @@ + + + + + + + + LCOV - plumed test coverage - tools/IFile.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - IFile.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:14515196.0 %
Date:2024-04-19 12:12:35Functions:222588.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5IFile10FieldExistERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1142741
_ZN4PLMD5IFile10allowNoEOLEv1012
_ZN4PLMD5IFile12advanceFieldEv1575602
_ZN4PLMD5IFile13scanFieldListERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EE1142844
_ZN4PLMD5IFile18allowIgnoredFieldsEv5789
_ZN4PLMD5IFile4openERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1485
_ZN4PLMD5IFile5resetEb6133
_ZN4PLMD5IFile6llreadEPcm113804054
_ZN4PLMD5IFile7getlineERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1728954
_ZN4PLMD5IFile9scanFieldEPNS_5ValueE1103520
_ZN4PLMD5IFile9scanFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS6_16625845
_ZN4PLMD5IFile9scanFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERd7524296
_ZN4PLMD5IFile9scanFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERi2466867
_ZN4PLMD5IFile9scanFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERj17
_ZN4PLMD5IFile9scanFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERl1
_ZN4PLMD5IFile9scanFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERm1
_ZN4PLMD5IFile9scanFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERx0
_ZN4PLMD5IFile9scanFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERy14
_ZN4PLMD5IFile9scanFieldEv1569177
_ZN4PLMD5IFileC1Ev1776
_ZN4PLMD5IFileC2Ev0
_ZN4PLMD5IFileD0Ev348
_ZN4PLMD5IFileD1Ev1776
_ZN4PLMD5IFileD2Ev0
_ZNK4PLMD5IFile9findFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE16619485
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/IFile.cpp.gcov.html b/coverage/tools/IFile.cpp.gcov.html new file mode 100644 index 000000000000..1a827de6099a --- /dev/null +++ b/coverage/tools/IFile.cpp.gcov.html @@ -0,0 +1,372 @@ + + + + + + + + LCOV - plumed test coverage - tools/IFile.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - IFile.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:14515196.0 %
Date:2024-04-19 12:12:35Functions: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   113804054 : size_t IFile::llread(char*ptr,size_t s) {
+      42   113804054 :   plumed_assert(fp);
+      43             :   size_t r;
+      44   113804054 :   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   113800532 :     if(std::feof(fp))   eof=true;
+      56   113800532 :     if(std::ferror(fp)) err=true;
+      57             :   }
+      58   113804054 :   return r;
+      59             : }
+      60             : 
+      61     1575602 : IFile& IFile::advanceField() {
+      62     1575602 :   plumed_assert(!inMiddleOfField);
+      63             :   std::string line;
+      64             :   bool done=false;
+      65     3153048 :   while(!done) {
+      66     1583882 :     getline(line);
+      67             : // using explicit conversion not to confuse cppcheck 1.86
+      68     1583882 :     if(!bool(*this)) {return *this;}
+      69     1577446 :     std::vector<std::string> words=Tools::getWords(line);
+      70     3154703 :     if(words.size()>=2 && words[0]=="#!" && words[1]=="FIELDS") {
+      71         743 :       fields.clear();
+      72        4931 :       for(unsigned i=2; i<words.size(); i++) {
+      73             :         Field field;
+      74             :         field.name=words[i];
+      75        4188 :         fields.push_back(field);
+      76             :       }
+      77     1598433 :     } else if(words.size()==4 && words[0]=="#!" && words[1]=="SET") {
+      78             :       Field field;
+      79             :       field.name=words[2];
+      80             :       field.value=words[3];
+      81        3279 :       field.constant=true;
+      82        3279 :       fields.push_back(field);
+      83             :     } else {
+      84             :       unsigned nf=0;
+      85    18117010 :       for(unsigned i=0; i<fields.size(); i++) if(!fields[i].constant) nf++;
+      86     1573424 :       Tools::trimComments(line);
+      87     3146848 :       words=Tools::getWords(line);
+      88     1573424 :       if( words.size()==nf ) {
+      89             :         unsigned j=0;
+      90    18062383 :         for(unsigned i=0; i<fields.size(); i++) {
+      91    16493217 :           if(fields[i].constant) continue;
+      92     7622986 :           fields[i].value=words[j];
+      93     7622986 :           fields[i].read=false;
+      94     7622986 :           j++;
+      95             :         }
+      96             :         done=true;
+      97        4258 :       } 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     1577446 :   }
+     102     1569166 :   inMiddleOfField=true;
+     103     1569166 :   return *this;
+     104             : }
+     105             : 
+     106        1485 : IFile& IFile::open(const std::string&path) {
+     107        1485 :   plumed_massert(!cloned,"file "+path+" appears to be cloned");
+     108        1485 :   eof=false;
+     109        1485 :   err=false;
+     110        1485 :   fp=NULL;
+     111        1485 :   gzfp=NULL;
+     112        1485 :   bool do_exist=FileExist(path);
+     113        1487 :   plumed_massert(do_exist,"file " + path + " cannot be found");
+     114        1484 :   fp=std::fopen(const_cast<char*>(this->path.c_str()),"r");
+     115        2968 :   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        1484 :   if(plumed) plumed->insertFile(*this);
+     123        1484 :   return *this;
+     124             : }
+     125             : 
+     126     1142844 : IFile& IFile::scanFieldList(std::vector<std::string>&s) {
+     127     1142844 :   if(!inMiddleOfField) advanceField();
+     128             : // using explicit conversion not to confuse cppcheck 1.86
+     129     1142844 :   if(!bool(*this)) return *this;
+     130             :   s.clear();
+     131     9243480 :   for(unsigned i=0; i<fields.size(); i++)
+     132     8100712 :     s.push_back(fields[i].name);
+     133             :   return *this;
+     134             : }
+     135             : 
+     136     1142741 : bool IFile::FieldExist(const std::string& s) {
+     137             :   std::vector<std::string> slist;
+     138     1142741 :   scanFieldList(slist);
+     139     1142741 :   int mycount = (int) std::count(slist.begin(), slist.end(), s);
+     140     1142741 :   if(mycount>0) return true;
+     141     1118056 :   else return false;
+     142     1142741 : }
+     143             : 
+     144    16625845 : IFile& IFile::scanField(const std::string&name,std::string&str) {
+     145    16625845 :   if(!inMiddleOfField) advanceField();
+     146             : // using explicit conversion not to confuse cppcheck 1.86
+     147    16625845 :   if(!bool(*this)) return *this;
+     148    16619485 :   unsigned i=findField(name);
+     149    16619485 :   str=fields[i].value;
+     150    16619485 :   fields[i].read=true;
+     151    16619485 :   return *this;
+     152             : }
+     153             : 
+     154     7524296 : IFile& IFile::scanField(const std::string&name,double &x) {
+     155             :   std::string str;
+     156     7524296 :   scanField(name,str);
+     157     7524296 :   if(*this) Tools::convert(str,x);
+     158     7524296 :   return *this;
+     159             : }
+     160             : 
+     161     2466867 : IFile& IFile::scanField(const std::string&name,int &x) {
+     162             :   std::string str;
+     163     2466867 :   scanField(name,str);
+     164     2466867 :   if(*this) Tools::convert(str,x);
+     165     2466867 :   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     1103520 : IFile& IFile::scanField(Value* val) {
+     204     1103520 :   double ff=std::numeric_limits<double>::quiet_NaN(); // this is to be sure a NaN value is replaced upon failure
+     205     1103520 :   scanField(  val->getName(), ff );
+     206     1103520 :   val->set( ff );
+     207     2207040 :   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     1100211 :     val->setNotPeriodic();
+     214             :   }
+     215     1103520 :   return *this;
+     216             : }
+     217             : 
+     218     1569177 : IFile& IFile::scanField() {
+     219     1569177 :   if(!ignoreFields) {
+     220    16359709 :     for(unsigned i=0; i<fields.size(); i++) {
+     221    15004852 :       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     1569177 :   inMiddleOfField=false;
+     225     1569177 :   return *this;
+     226             : }
+     227             : 
+     228        1776 : IFile::IFile():
+     229        1776 :   inMiddleOfField(false),
+     230        1776 :   ignoreFields(false),
+     231        1776 :   noEOL(false)
+     232             : {
+     233        1776 : }
+     234             : 
+     235        2124 : IFile::~IFile() {
+     236        1776 :   if(inMiddleOfField) std::cerr<<"WARNING: IFile closed in the middle of reading. seems strange!\n";
+     237        2124 : }
+     238             : 
+     239     1728954 : IFile& IFile::getline(std::string &str) {
+     240     1728954 :   char tmp=0;
+     241             :   str="";
+     242             :   fpos_t pos;
+     243     1728954 :   fgetpos(fp,&pos);
+     244   113804001 :   while(llread(&tmp,1)==1 && tmp && tmp!='\n' && tmp!='\r' && !eof && !err) {
+     245   112075047 :     str+=tmp;
+     246             :   }
+     247     1728954 :   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     1728954 :   if(eof && noEOL) {
+     252         997 :     if(str.length()>0) eof=false;
+     253     1727957 :   } else if(eof || err || tmp!='\n') {
+     254        6470 :     eof = true;
+     255             :     str="";
+     256        6470 :     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     1728954 :   return *this;
+     266             : }
+     267             : 
+     268    16619485 : unsigned IFile::findField(const std::string&name)const {
+     269             :   unsigned i;
+     270   106774015 :   for(i=0; i<fields.size(); i++) if(fields[i].name==name) break;
+     271    16619485 :   if(i>=fields.size()) {
+     272           0 :     plumed_merror("file " + getPath() + ": field " + name + " cannot be found");
+     273             :   }
+     274    16619485 :   return i;
+     275             : }
+     276             : 
+     277        6133 : void IFile::reset(bool reset) {
+     278        6133 :   eof = reset;
+     279        6133 :   err = reset;
+     280        6133 :   if(!reset && fp) clearerr(fp);
+     281             : #ifdef __PLUMED_HAS_ZLIB
+     282        6133 :   if(!reset && gzfp) gzclearerr(gzFile(gzfp));
+     283             : #endif
+     284        6133 :   return;
+     285             : }
+     286             : 
+     287        5789 : void IFile::allowIgnoredFields() {
+     288        5789 :   ignoreFields=true;
+     289        5789 : }
+     290             : 
+     291        1012 : void IFile::allowNoEOL() {
+     292        1012 :   noEOL=true;
+     293        1012 : }
+     294             : 
+     295             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/IFile.h.func-sort-c.html b/coverage/tools/IFile.h.func-sort-c.html new file mode 100644 index 000000000000..53f7ca85906a --- /dev/null +++ b/coverage/tools/IFile.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage - tools/IFile.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - IFile.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22100.0 %
Date:2024-04-19 12:12:35Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/IFile.h.func.html b/coverage/tools/IFile.h.func.html new file mode 100644 index 000000000000..7e84119468d0 --- /dev/null +++ b/coverage/tools/IFile.h.func.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage - tools/IFile.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - IFile.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22100.0 %
Date:2024-04-19 12:12:35Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/IFile.h.gcov.html b/coverage/tools/IFile.h.gcov.html new file mode 100644 index 000000000000..a85fdac95b57 --- /dev/null +++ b/coverage/tools/IFile.h.gcov.html @@ -0,0 +1,194 @@ + + + + + + + + LCOV - plumed test coverage - tools/IFile.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - IFile.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22100.0 %
Date:2024-04-19 12:12:35Functions: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       19428 :   class Field:
+      45             :     public FieldBase {
+      46             :   public:
+      47             :     bool read;
+      48        7467 :     Field(): read(false) {}
+      49             :   };
+      50             : /// Low-level read.
+      51             : /// Note: in parallel, all processes read
+      52             :   std::size_t llread(char*,std::size_t);
+      53             : /// All the defined fields
+      54             :   std::vector<Field> fields;
+      55             : /// Flag set in the middle of a field reading
+      56             :   bool inMiddleOfField;
+      57             : /// Set to true if you want to allow fields to be ignored in the read in file
+      58             :   bool ignoreFields;
+      59             : /// Set to true to allow files without end-of-line at the end
+      60             :   bool noEOL;
+      61             : /// Advance to next field (= read one line)
+      62             :   IFile& advanceField();
+      63             : /// Find field index by name
+      64             :   unsigned findField(const std::string&name)const;
+      65             : public:
+      66             : /// Constructor
+      67             :   IFile();
+      68             : /// Destructor
+      69             :   ~IFile();
+      70             : /// Opens the file
+      71             :   IFile& open(const std::string&name) override;
+      72             : /// Gets the list of all fields
+      73             :   IFile& scanFieldList(std::vector<std::string>&);
+      74             : /// Read a double field
+      75             :   IFile& scanField(const std::string&,double&);
+      76             : /// Read a int field
+      77             :   IFile& scanField(const std::string&,int&);
+      78             : /// Read a long int field
+      79             :   IFile& scanField(const std::string&,long int&);
+      80             : /// Read a long long int field
+      81             :   IFile& scanField(const std::string&,long long int&);
+      82             : /// Read a unsigned field
+      83             :   IFile& scanField(const std::string&,unsigned&);
+      84             : /// Read a long unsigned field
+      85             :   IFile& scanField(const std::string&,long unsigned&);
+      86             : /// Read a long long unsigned field
+      87             :   IFile& scanField(const std::string&,long long unsigned&);
+      88             : /// Read a string field
+      89             :   IFile& scanField(const std::string&,std::string&);
+      90             :   /**
+      91             :    Ends a field-formatted line.
+      92             : 
+      93             :   Typically used as
+      94             :   \verbatim
+      95             :     if.scanField("a",a).scanField("b",b).scanField();
+      96             :   \endverbatim
+      97             :   */
+      98             :   IFile& scanField();
+      99             : /// Get a full line as a string
+     100             :   IFile& getline(std::string&);
+     101             : /// Reset end of file
+     102             :   void reset(bool);
+     103             : /// Check if a field exist
+     104             :   bool FieldExist(const std::string& s);
+     105             : /// Read in a value
+     106             :   IFile& scanField(Value* val);
+     107             : /// Allow some of the fields in the input to be ignored
+     108             :   void allowIgnoredFields();
+     109             : /// Allow files without EOL at the end.
+     110             : /// This in practice should be only used when opening
+     111             : /// plumed input files
+     112             :   void allowNoEOL();
+     113             : };
+     114             : 
+     115             : }
+     116             : 
+     117             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/KernelFunctions.cpp.func-sort-c.html b/coverage/tools/KernelFunctions.cpp.func-sort-c.html new file mode 100644 index 000000000000..f7022c5649c6 --- /dev/null +++ b/coverage/tools/KernelFunctions.cpp.func-sort-c.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - tools/KernelFunctions.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - KernelFunctions.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:9022240.5 %
Date:2024-04-19 12:12:35Functions:71070.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15KernelFunctions9normalizeERKSt6vectorIPNS_5ValueESaIS3_EE0
_ZN4PLMD15KernelFunctionsC2EPKS0_0
_ZN4PLMD15KernelFunctionsC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZNK4PLMD15KernelFunctions10getSupportERKSt6vectorIdSaIdEE3375
_ZN4PLMD15KernelFunctions4readEPNS_5IFileERKbRKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISB_EE4471
_ZNK4PLMD15KernelFunctions20getContinuousSupportEv5017
_ZN4PLMD15KernelFunctions7setDataERKSt6vectorIdSaIdEES5_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESD_RKd5563
_ZN4PLMD15KernelFunctionsC2ERKSt6vectorIdSaIdEES5_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESD_RKd5563
_ZNK4PLMD15KernelFunctions9getCutoffERKd10033
_ZNK4PLMD15KernelFunctions8evaluateERKSt6vectorIPNS_5ValueESaIS3_EERS1_IdSaIdEEbbdd1024305
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/KernelFunctions.cpp.func.html b/coverage/tools/KernelFunctions.cpp.func.html new file mode 100644 index 000000000000..df903ea2bef5 --- /dev/null +++ b/coverage/tools/KernelFunctions.cpp.func.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - tools/KernelFunctions.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - KernelFunctions.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:9022240.5 %
Date:2024-04-19 12:12:35Functions:71070.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15KernelFunctions4readEPNS_5IFileERKbRKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISB_EE4471
_ZN4PLMD15KernelFunctions7setDataERKSt6vectorIdSaIdEES5_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESD_RKd5563
_ZN4PLMD15KernelFunctions9normalizeERKSt6vectorIPNS_5ValueESaIS3_EE0
_ZN4PLMD15KernelFunctionsC2EPKS0_0
_ZN4PLMD15KernelFunctionsC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD15KernelFunctionsC2ERKSt6vectorIdSaIdEES5_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESD_RKd5563
_ZNK4PLMD15KernelFunctions10getSupportERKSt6vectorIdSaIdEE3375
_ZNK4PLMD15KernelFunctions20getContinuousSupportEv5017
_ZNK4PLMD15KernelFunctions8evaluateERKSt6vectorIPNS_5ValueESaIS3_EERS1_IdSaIdEEbbdd1024305
_ZNK4PLMD15KernelFunctions9getCutoffERKd10033
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/KernelFunctions.cpp.gcov.html b/coverage/tools/KernelFunctions.cpp.gcov.html new file mode 100644 index 000000000000..9776d42f3930 --- /dev/null +++ b/coverage/tools/KernelFunctions.cpp.gcov.html @@ -0,0 +1,532 @@ + + + + + + + + LCOV - plumed test coverage - tools/KernelFunctions.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - KernelFunctions.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:9022240.5 %
Date:2024-04-19 12:12:35Functions:71070.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           0 : KernelFunctions::KernelFunctions( const std::string& input ) {
+      96             : 
+      97           0 :   if(!dp2cutoffNoStretch()) {
+      98           0 :     stretchA=dp2cutoffA;
+      99           0 :     stretchB=dp2cutoffB;
+     100             :   }
+     101             : 
+     102           0 :   std::vector<std::string> data=Tools::getWords(input);
+     103           0 :   std::string name=data[0];
+     104             :   data.erase(data.begin());
+     105             : 
+     106             :   std::vector<double> at;
+     107           0 :   bool foundc = Tools::parseVector(data,"CENTER",at);
+     108           0 :   if(!foundc) plumed_merror("failed to find center keyword in definition of kernel");
+     109             :   std::vector<double> sig;
+     110           0 :   bool founds = Tools::parseVector(data,"SIGMA",sig);
+     111           0 :   if(!founds) plumed_merror("failed to find sigma keyword in definition of kernel");
+     112             : 
+     113           0 :   bool multi=false; Tools::parseFlag(data,"MULTIVARIATE",multi);
+     114           0 :   bool vonmises=false; Tools::parseFlag(data,"VON-MISSES",vonmises);
+     115           0 :   if( center.size()==1 && multi ) plumed_merror("one dimensional kernel cannot be multivariate");
+     116           0 :   if( center.size()==1 && vonmises ) plumed_merror("one dimensional kernal cannot be von-misses");
+     117           0 :   if( center.size()==1 && sig.size()!=1 ) plumed_merror("size mismatch between center size and sigma size");
+     118           0 :   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           0 :   if( !multi && center.size()>1 && sig.size()!=center.size() ) plumed_merror("size mismatch between center size and sigma size");
+     120             : 
+     121             :   double h;
+     122           0 :   bool foundh = Tools::parse(data,"HEIGHT",h);
+     123           0 :   if( !foundh) h=1.0;
+     124             : 
+     125           0 :   if( multi ) setData( at, sig, name, "MULTIVARIATE", h );
+     126           0 :   else if( vonmises ) setData( at, sig, name, "VON-MISSES", h );
+     127           0 :   else setData( at, sig, name, "DIAGONAL", h );
+     128           0 : }
+     129             : 
+     130        5563 : 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        5563 :   if(!dp2cutoffNoStretch()) {
+     133        5563 :     stretchA=dp2cutoffA;
+     134        5563 :     stretchB=dp2cutoffB;
+     135             :   }
+     136             : 
+     137        5563 :   setData( at, sig, type, mtype, w );
+     138        5563 : }
+     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        5563 : 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        5563 :   height=w;
+     156       16688 :   center.resize( at.size() ); for(unsigned i=0; i<at.size(); ++i) center[i]=at[i];
+     157       21056 :   width.resize( sig.size() ); for(unsigned i=0; i<sig.size(); ++i) width[i]=sig[i];
+     158        5563 :   if( mtype=="MULTIVARIATE" ) dtype=multi;
+     159        1195 :   else if( mtype=="VON-MISSES" ) dtype=vonmises;
+     160        1195 :   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       11126 :   if(type=="GAUSSIAN" || type=="gaussian" ) {
+     165           0 :     ktype=gaussian;
+     166       11126 :   } else if(type=="STRETCHED-GAUSSIAN" || type=="stretched-gaussian" ) {
+     167        5563 :     ktype=stretchedgaussian;
+     168           0 :   } else if(type=="TRUNCATED-GAUSSIAN" || type=="truncated-gaussian" ) {
+     169           0 :     ktype=truncatedgaussian;
+     170           0 :   } else if(type=="UNIFORM" || type=="uniform") {
+     171           0 :     ktype=uniform;
+     172           0 :   } else if(type=="TRIANGULAR" || type=="triangular") {
+     173           0 :     ktype=triangular;
+     174             :   } else {
+     175           0 :     plumed_merror(type+" is an invalid kernel type\n");
+     176             :   }
+     177        5563 : }
+     178             : 
+     179           0 : void KernelFunctions::normalize( const std::vector<Value*>& myvals ) {
+     180             : 
+     181             :   double det=1.;
+     182             :   unsigned ncv=ndim();
+     183           0 :   if(dtype==diagonal) {
+     184           0 :     for(unsigned i=0; i<width.size(); ++i) det*=width[i]*width[i];
+     185           0 :   } else if(dtype==multi) {
+     186           0 :     Matrix<double> mymatrix( getMatrix() ), myinv( ncv, ncv );
+     187           0 :     Invert(mymatrix,myinv); double logd;
+     188           0 :     logdet( myinv, logd );
+     189           0 :     det=std::exp(logd);
+     190             :   }
+     191           0 :   if( dtype==diagonal || dtype==multi ) {
+     192             :     double volume;
+     193           0 :     if( ktype==gaussian || ktype==stretchedgaussian ) {
+     194           0 :       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           0 :     height /= volume;
+     215           0 :     return;
+     216             :   }
+     217           0 :   plumed_assert( dtype==vonmises && ktype==gaussian );
+     218             :   // Now calculate determinant for aperiodic variables
+     219             :   unsigned naper=0;
+     220           0 :   for(unsigned i=0; i<ncv; ++i) {
+     221           0 :     if( !myvals[i]->isPeriodic() ) naper++;
+     222             :   }
+     223             :   // Now construct sub matrix
+     224             :   double volume=1;
+     225           0 :   if( naper>0 ) {
+     226             :     unsigned isub=0;
+     227           0 :     Matrix<double> mymatrix( getMatrix() ), mysub( naper, naper );
+     228           0 :     for(unsigned i=0; i<ncv; ++i) {
+     229           0 :       if( myvals[i]->isPeriodic() ) continue;
+     230             :       unsigned jsub=0;
+     231           0 :       for(unsigned j=0; j<ncv; ++j) {
+     232           0 :         if( myvals[j]->isPeriodic() ) continue;
+     233           0 :         mysub( isub, jsub ) = mymatrix( i, j ); jsub++;
+     234             :       }
+     235           0 :       isub++;
+     236             :     }
+     237             :     Matrix<double> myisub( naper, naper ); double logd;
+     238           0 :     Invert( mysub, myisub ); logdet( myisub, logd );
+     239           0 :     det=std::exp(logd);
+     240           0 :     volume=pow( 2*pi, 0.5*ncv ) * pow( det, 0.5 );
+     241             :   }
+     242             : 
+     243             :   // Calculate volume of periodic variables
+     244             :   unsigned nper=0;
+     245           0 :   for(unsigned i=0; i<ncv; ++i) {
+     246           0 :     if( myvals[i]->isPeriodic() ) nper++;
+     247             :   }
+     248             : 
+     249             :   // Now construct sub matrix
+     250           0 :   if( nper>0 ) {
+     251             :     unsigned isub=0;
+     252           0 :     Matrix<double> mymatrix( getMatrix() ),  mysub( nper, nper );
+     253           0 :     for(unsigned i=0; i<ncv; ++i) {
+     254           0 :       if( !myvals[i]->isPeriodic() ) continue;
+     255             :       unsigned jsub=0;
+     256           0 :       for(unsigned j=0; j<ncv; ++j) {
+     257           0 :         if( !myvals[j]->isPeriodic() ) continue;
+     258           0 :         mysub( isub, jsub ) = mymatrix( i, j ); jsub++;
+     259             :       }
+     260           0 :       isub++;
+     261             :     }
+     262             :     Matrix<double>  eigvec( nper, nper );
+     263           0 :     std::vector<double> eigval( nper );
+     264           0 :     diagMat( mysub, eigval, eigvec );
+     265             :     unsigned iper=0; volume=1;
+     266           0 :     for(unsigned i=0; i<ncv; ++i) {
+     267           0 :       if( myvals[i]->isPeriodic() ) {
+     268           0 :         volume *= myvals[i]->getMaxMinusMin()*Tools::bessel0(eigval[iper])*std::exp(-eigval[iper]);
+     269           0 :         iper++;
+     270             :       }
+     271             :     }
+     272             :   }
+     273           0 :   height /= volume;
+     274             : }
+     275             : 
+     276       10033 : double KernelFunctions::getCutoff( const double& width ) const {
+     277             :   const double DP2CUTOFF=6.25;
+     278       10033 :   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        5017 : std::vector<double> KernelFunctions::getContinuousSupport( ) const {
+     286             :   unsigned ncv=ndim();
+     287        5017 :   std::vector<double> support( ncv );
+     288        5017 :   if(dtype==diagonal) {
+     289        1946 :     for(unsigned i=0; i<ncv; ++i) support[i]=getCutoff(width[i]);
+     290        4368 :   } else if(dtype==multi) {
+     291        4368 :     Matrix<double> mymatrix( getMatrix() ), myinv( ncv,ncv );
+     292        4368 :     Invert(mymatrix,myinv);
+     293        4368 :     Matrix<double> myautovec(ncv,ncv); std::vector<double> myautoval(ncv);
+     294        4368 :     diagMat(myinv,myautoval,myautovec);
+     295             :     double maxautoval=0.;
+     296             :     unsigned ind_maxautoval=0;
+     297       13104 :     for (unsigned i=0; i<ncv; i++) {
+     298        8736 :       if(myautoval[i]>maxautoval) {maxautoval=myautoval[i]; ind_maxautoval=i;}
+     299             :     }
+     300       13104 :     for(unsigned i=0; i<ncv; ++i) {
+     301        8736 :       double extent=std::fabs(std::sqrt(maxautoval)*myautovec(i,ind_maxautoval));
+     302        8736 :       support[i]=getCutoff( extent );
+     303             :     }
+     304             :   } else {
+     305           0 :     plumed_merror("cannot find support if metric is not multi or diagonal type");
+     306             :   }
+     307        5017 :   return support;
+     308             : }
+     309             : 
+     310        3375 : std::vector<unsigned> KernelFunctions::getSupport( const std::vector<double>& dx ) const {
+     311        3375 :   plumed_assert( ndim()==dx.size() );
+     312        3375 :   std::vector<unsigned> support( dx.size() );
+     313        3375 :   std::vector<double> vv=getContinuousSupport( );
+     314       10124 :   for(unsigned i=0; i<dx.size(); ++i) support[i]=static_cast<unsigned>(ceil( vv[i]/dx[i] ));
+     315        3375 :   return support;
+     316             : }
+     317             : 
+     318     1024305 : 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     1024305 :   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     1024305 :   if(dtype==diagonal) {
+     330      161311 :     for(unsigned i=0; i<ndim(); ++i) {
+     331      107510 :       derivatives[i]=-pos[i]->difference( center[i] ) / width[i];
+     332      107510 :       r2+=derivatives[i]*derivatives[i];
+     333      107510 :       derivatives[i] /= width[i];
+     334             :     }
+     335      970504 :   } else if(dtype==multi) {
+     336      970504 :     Matrix<double> mymatrix( getMatrix() );
+     337     2911512 :     for(unsigned i=0; i<mymatrix.nrows(); ++i) {
+     338     1941008 :       double dp_i, dp_j; derivatives[i]=0;
+     339     1941008 :       dp_i=-pos[i]->difference( center[i] );
+     340     5823024 :       for(unsigned j=0; j<mymatrix.ncols(); ++j) {
+     341     3882016 :         if(i==j) dp_j=dp_i;
+     342     1941008 :         else dp_j=-pos[j]->difference( center[j] );
+     343             : 
+     344     3882016 :         derivatives[i]+=mymatrix(i,j)*dp_j;
+     345     3882016 :         r2+=dp_i*dp_j*mymatrix(i,j);
+     346             :       }
+     347             :     }
+     348           0 :   } else if(dtype==vonmises) {
+     349           0 :     std::vector<double> costmp( ndim() ), sintmp( ndim() ), sinout( ndim(), 0.0 );
+     350           0 :     for(unsigned i=0; i<ndim(); ++i) {
+     351           0 :       if( pos[i]->isPeriodic() ) {
+     352           0 :         sintmp[i]=std::sin( 2.*pi*(pos[i]->get() - center[i])/pos[i]->getMaxMinusMin() );
+     353           0 :         costmp[i]=std::cos( 2.*pi*(pos[i]->get() - center[i])/pos[i]->getMaxMinusMin() );
+     354             :       } else {
+     355           0 :         sintmp[i]=pos[i]->get() - center[i];
+     356           0 :         costmp[i]=1.0;
+     357             :       }
+     358             :     }
+     359             : 
+     360           0 :     Matrix<double> mymatrix( getMatrix() );
+     361           0 :     for(unsigned i=0; i<mymatrix.nrows(); ++i) {
+     362           0 :       derivatives[i]=0;
+     363           0 :       if( pos[i]->isPeriodic() ) {
+     364           0 :         r2+=2*( 1 - costmp[i] )*mymatrix(i,i);
+     365             :       } else {
+     366           0 :         r2+=sintmp[i]*sintmp[i]*mymatrix(i,i);
+     367             :       }
+     368           0 :       for(unsigned j=0; j<mymatrix.ncols(); ++j) {
+     369           0 :         if( i!=j ) sinout[i]+=mymatrix(i,j)*sintmp[j];
+     370             :       }
+     371           0 :       derivatives[i] = mymatrix(i,i)*sintmp[i] + sinout[i]*costmp[i];
+     372           0 :       if( pos[i]->isPeriodic() ) derivatives[i] *= (2*pi/pos[i]->getMaxMinusMin());
+     373             :     }
+     374           0 :     for(unsigned i=0; i<sinout.size(); ++i) r2+=sintmp[i]*sinout[i];
+     375             :   }
+     376             :   double kderiv, kval;
+     377     1024305 :   if(ktype==gaussian || ktype==truncatedgaussian) {
+     378           0 :     kval=height*std::exp(-0.5*r2); kderiv=-kval;
+     379     1024305 :   } 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           0 :     double r=std::sqrt(r2);
+     391           0 :     if(ktype==triangular) {
+     392           0 :       if( r<1.0 ) {
+     393             :         if(r==0) kderiv=0;
+     394           0 :         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           0 :     kderiv*=height / r ;
+     406             :   }
+     407     3072823 :   for(unsigned i=0; i<ndim(); ++i) derivatives[i]*=kderiv;
+     408     1024305 :   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     1024305 :   return kval;
+     412             : }
+     413             : 
+     414        4471 : std::unique_ptr<KernelFunctions> KernelFunctions::read( IFile* ifile, const bool& cholesky, const std::vector<std::string>& valnames ) {
+     415             :   double h;
+     416        8942 :   if( !ifile->scanField("height",h) ) return NULL;;
+     417             : 
+     418        4471 :   std::string sss; ifile->scanField("multivariate",sss);
+     419       12321 :   std::string ktype="stretched-gaussian"; if( ifile->FieldExist("kerneltype") ) ifile->scanField("kerneltype",ktype);
+     420        8839 :   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        4471 :   std::vector<double> cc( valnames.size() );
+     424       13412 :   for(unsigned i=0; i<valnames.size(); ++i) ifile->scanField(valnames[i],cc[i]);
+     425             : 
+     426             :   std::vector<double> sig;
+     427        4471 :   if( sss=="false" ) {
+     428         103 :     sig.resize( valnames.size() );
+     429         308 :     for(unsigned i=0; i<valnames.size(); ++i) {
+     430         205 :       ifile->scanField("sigma_"+valnames[i],sig[i]);
+     431         205 :       if( !cholesky ) sig[i]=std::sqrt(sig[i]);
+     432             :     }
+     433             :     return Tools::make_unique<KernelFunctions>(cc, sig, ktype, "DIAGONAL", h);
+     434             :   }
+     435             : 
+     436        4368 :   unsigned ncv=valnames.size();
+     437        4368 :   sig.resize( (ncv*(ncv+1))/2 );
+     438             :   Matrix<double> upper(ncv,ncv), lower(ncv,ncv), mymult( ncv, ncv ), invmatrix(ncv,ncv);
+     439       13104 :   for(unsigned i=0; i<ncv; ++i) {
+     440       21840 :     for(unsigned j=0; j<ncv-i; j++) {
+     441       26208 :       ifile->scanField("sigma_" +valnames[j+i] + "_" + valnames[j], lower(j+i,j) );
+     442       13104 :       upper(j,j+i)=lower(j+i,j); mymult(j+i,j)=mymult(j,j+i)=lower(j+i,j);
+     443             :     }
+     444             :   }
+     445        4368 :   if( cholesky ) mult(lower,upper,mymult);
+     446        4368 :   Invert( mymult, invmatrix );
+     447             :   unsigned k=0;
+     448       13104 :   for(unsigned i=0; i<ncv; i++) {
+     449       21840 :     for(unsigned j=i; j<ncv; j++) { sig[k]=invmatrix(i,j); k++; }
+     450             :   }
+     451        4368 :   if( sss=="true" ) return Tools::make_unique<KernelFunctions>(cc, sig, ktype, "MULTIVARIATE", h);
+     452             :   return Tools::make_unique<KernelFunctions>( cc, sig, ktype, "VON-MISSES", h );
+     453             : }
+     454             : 
+     455             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/KernelFunctions.h.func-sort-c.html b/coverage/tools/KernelFunctions.h.func-sort-c.html new file mode 100644 index 000000000000..2d6306fc103f --- /dev/null +++ b/coverage/tools/KernelFunctions.h.func-sort-c.html @@ -0,0 +1,77 @@ + + + + + + + + LCOV - plumed test coverage - tools/KernelFunctions.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - KernelFunctions.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:99100.0 %
Date:2024-04-19 12:12:35Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD15KernelFunctions9getMatrixEv974872
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/KernelFunctions.h.func.html b/coverage/tools/KernelFunctions.h.func.html new file mode 100644 index 000000000000..0a832385c4d5 --- /dev/null +++ b/coverage/tools/KernelFunctions.h.func.html @@ -0,0 +1,77 @@ + + + + + + + + LCOV - plumed test coverage - tools/KernelFunctions.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - KernelFunctions.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:99100.0 %
Date:2024-04-19 12:12:35Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD15KernelFunctions9getMatrixEv974872
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/KernelFunctions.h.gcov.html b/coverage/tools/KernelFunctions.h.gcov.html new file mode 100644 index 000000000000..f5b5c795c753 --- /dev/null +++ b/coverage/tools/KernelFunctions.h.gcov.html @@ -0,0 +1,174 @@ + + + + + + + + LCOV - plumed test coverage - tools/KernelFunctions.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - KernelFunctions.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:99100.0 %
Date:2024-04-19 12:12:35Functions: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        5563 : 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      974872 : Matrix<double> KernelFunctions::getMatrix() const {
+      76             :   unsigned k=0, ncv=ndim(); Matrix<double> mymatrix(ncv,ncv);
+      77     2924616 :   for(unsigned i=0; i<ncv; i++) {
+      78     4874360 :     for(unsigned j=i; j<ncv; j++) {
+      79     2924616 :       mymatrix(i,j)=mymatrix(j,i)=width[k]; // recompose the full inverse matrix
+      80     2924616 :       k++;
+      81             :     }
+      82             :   }
+      83      974872 :   return mymatrix;
+      84             : }
+      85             : 
+      86             : inline
+      87             : unsigned KernelFunctions::ndim() const {
+      88     4214023 :   return center.size();
+      89             : }
+      90             : 
+      91             : inline
+      92             : std::vector<double> KernelFunctions::getCenter() const {
+      93        5563 :   return center;
+      94             : }
+      95             : 
+      96             : }
+      97             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Keywords.cpp.func-sort-c.html b/coverage/tools/Keywords.cpp.func-sort-c.html new file mode 100644 index 000000000000..efd3c59d0bc7 --- /dev/null +++ b/coverage/tools/Keywords.cpp.func-sort-c.html @@ -0,0 +1,249 @@ + + + + + + + + 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:21440353.1 %
Date:2024-04-19 12:12:35Functions:334475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8Keywords11destroyDataEv0
_ZN4PLMD8Keywords15removeComponentERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD8Keywords3addERKS0_0
_ZNK4PLMD8Keywords10getTooltipERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZNK4PLMD8Keywords10print_htmlEv0
_ZNK4PLMD8Keywords14print_spellingEv0
_ZNK4PLMD8Keywords14print_templateERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEb0
_ZNK4PLMD8Keywords15print_html_itemERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZNK4PLMD8Keywords5printEP8_IO_FILE0
_ZNK4PLMD8Keywords5printERNS_3LogE0
_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_0
_ZNK4PLMD8Keywords9print_vimEv434
_ZNK4PLMD8Keywords29getOutputComponentDescriptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE548
_ZNK4PLMD8Keywords17getNeededKeywordsB5cxx11Ev555
_ZN4PLMD8Keywords7KeyType8setStyleERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE680
_ZNK4PLMD8Keywords22getOutputComponentFlagERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE773
_ZNK4PLMD8Keywords13getHelpStringB5cxx11Ev868
_ZN4PLMD8Keywords11reserveFlagERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbS8_1322
_ZNK4PLMD8Keywords21getKeywordDescriptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE4880
_ZNK4PLMD8Keywords19getOutputComponentsB5cxx11Ev5418
_ZN4PLMD8Keywords11reset_styleERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_6348
_ZNK4PLMD8Keywords14getKeywordDocsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE7892
_ZN4PLMD8Keywords6removeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE8763
_ZNK4PLMD8Keywords10getKeywordB5cxx11Ej19520
_ZNK4PLMD8Keywords15getDefaultValueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS6_22246
_ZN4PLMD8Keywords25setComponentsIntroductionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE23468
_ZN4PLMD8Keywords3useERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE28292
_ZN4PLMD8Keywords19addActionNameSuffixERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE30863
_ZN4PLMD8Keywords11needsActionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE70614
_ZNK4PLMD8Keywords17getLogicalDefaultERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERb80716
_ZN4PLMD8Keywords18addOutputComponentERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_S8_82066
_ZNK4PLMD8Keywords21outputComponentExistsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKb169844
_ZNK4PLMD8Keywords8numberedERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE174849
_ZN4PLMD8Keywords7reserveERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_S8_175563
_ZN4PLMD8Keywords7addFlagERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbS8_384382
_ZN4PLMD8Keywords3addERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_S8_S8_407776
_ZNK4PLMD8Keywords3getB5cxx11Ej528183
_ZN4PLMD8Keywords3addERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_S8_822223
_ZNK4PLMD8Keywords4sizeEv1118946
_ZNK4PLMD8Keywords5styleERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_1594169
_ZNK4PLMD8Keywords8getStyleERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1599049
_ZN4PLMD8Keywords7KeyTypeC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1791266
_ZNK4PLMD8Keywords8reservedERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1819558
_ZNK4PLMD8Keywords6existsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2852678
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Keywords.cpp.func.html b/coverage/tools/Keywords.cpp.func.html new file mode 100644 index 000000000000..1fa4068ad38f --- /dev/null +++ b/coverage/tools/Keywords.cpp.func.html @@ -0,0 +1,249 @@ + + + + + + + + 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:21440353.1 %
Date:2024-04-19 12:12:35Functions:334475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8Keywords11destroyDataEv0
_ZN4PLMD8Keywords11needsActionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE70614
_ZN4PLMD8Keywords11reserveFlagERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbS8_1322
_ZN4PLMD8Keywords11reset_styleERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_6348
_ZN4PLMD8Keywords15removeComponentERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD8Keywords18addOutputComponentERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_S8_82066
_ZN4PLMD8Keywords19addActionNameSuffixERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE30863
_ZN4PLMD8Keywords25setComponentsIntroductionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE23468
_ZN4PLMD8Keywords3addERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_S8_822223
_ZN4PLMD8Keywords3addERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_S8_S8_407776
_ZN4PLMD8Keywords3addERKS0_0
_ZN4PLMD8Keywords3useERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE28292
_ZN4PLMD8Keywords6removeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE8763
_ZN4PLMD8Keywords7KeyType8setStyleERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE680
_ZN4PLMD8Keywords7KeyTypeC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1791266
_ZN4PLMD8Keywords7addFlagERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbS8_384382
_ZN4PLMD8Keywords7reserveERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_S8_175563
_ZNK4PLMD8Keywords10getKeywordB5cxx11Ej19520
_ZNK4PLMD8Keywords10getTooltipERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZNK4PLMD8Keywords10print_htmlEv0
_ZNK4PLMD8Keywords13getHelpStringB5cxx11Ev868
_ZNK4PLMD8Keywords14getKeywordDocsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE7892
_ZNK4PLMD8Keywords14print_spellingEv0
_ZNK4PLMD8Keywords14print_templateERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEb0
_ZNK4PLMD8Keywords15getDefaultValueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS6_22246
_ZNK4PLMD8Keywords15print_html_itemERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZNK4PLMD8Keywords17getLogicalDefaultERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERb80716
_ZNK4PLMD8Keywords17getNeededKeywordsB5cxx11Ev555
_ZNK4PLMD8Keywords19getOutputComponentsB5cxx11Ev5418
_ZNK4PLMD8Keywords21getKeywordDescriptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE4880
_ZNK4PLMD8Keywords21outputComponentExistsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKb169844
_ZNK4PLMD8Keywords22getOutputComponentFlagERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE773
_ZNK4PLMD8Keywords29getOutputComponentDescriptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE548
_ZNK4PLMD8Keywords3getB5cxx11Ej528183
_ZNK4PLMD8Keywords4sizeEv1118946
_ZNK4PLMD8Keywords5printEP8_IO_FILE0
_ZNK4PLMD8Keywords5printERNS_3LogE0
_ZNK4PLMD8Keywords5styleERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_1594169
_ZNK4PLMD8Keywords6existsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2852678
_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_0
_ZNK4PLMD8Keywords8getStyleERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1599049
_ZNK4PLMD8Keywords8numberedERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE174849
_ZNK4PLMD8Keywords8reservedERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1819558
_ZNK4PLMD8Keywords9print_vimEv434
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Keywords.cpp.gcov.html b/coverage/tools/Keywords.cpp.gcov.html new file mode 100644 index 000000000000..c9265c90c38a --- /dev/null +++ b/coverage/tools/Keywords.cpp.gcov.html @@ -0,0 +1,755 @@ + + + + + + + + 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:21440353.1 %
Date:2024-04-19 12:12:35Functions:334475.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     1791266 : Keywords::KeyType::KeyType( const std::string& type ) {
+      31     1791266 :   if( type=="compulsory" ) {
+      32      518719 :     style=compulsory;
+      33     1272547 :   } else if( type=="flag" ) {
+      34      385704 :     style=flag;
+      35      886843 :   } else if( type=="optional" ) {
+      36      535002 :     style=optional;
+      37      351841 :   } else if( type.find("atoms")!=std::string::npos || type.find("residues")!=std::string::npos ) {
+      38      193867 :     style=atoms;
+      39      157974 :   } else if( type=="hidden" ) {
+      40      157974 :     style=hidden;
+      41           0 :   } else if( type=="vessel" ) {
+      42           0 :     style=vessel;
+      43             :   } else {
+      44           0 :     plumed_massert(false,"invalid keyword specifier " + type);
+      45             :   }
+      46     1791266 : }
+      47             : 
+      48         680 : void Keywords::KeyType::setStyle( const std::string& type ) {
+      49         680 :   if( type=="compulsory" ) {
+      50         257 :     style=compulsory;
+      51         423 :   } else if( type=="flag" ) {
+      52           0 :     style=flag;
+      53         423 :   } else if( type=="optional" ) {
+      54          24 :     style=optional;
+      55         399 :   } else if( type.find("atoms")!=std::string::npos || type.find("residues")!=std::string::npos ) {
+      56         399 :     style=atoms;
+      57           0 :   } else if( type=="hidden" ) {
+      58           0 :     style=hidden;
+      59           0 :   } else if( type=="vessel" ) {
+      60           0 :     style=vessel;
+      61             :   } else {
+      62           0 :     plumed_massert(false,"invalid keyword specifier " + type);
+      63             :   }
+      64         680 : }
+      65             : 
+      66     1599049 : std::string Keywords::getStyle( const std::string & k ) const {
+      67           0 :   plumed_massert( types.count(k), "Did not find keyword " + k );
+      68     1599049 :   return (types.find(k)->second).toString();
+      69             : }
+      70             : 
+      71           0 : void Keywords::add( const Keywords& newkeys ) {
+      72           0 :   newkeys.copyData( keys, reserved_keys, types, allowmultiple, documentation, booldefs, numdefs, atomtags, cnames, ckey, cdocs  );
+      73           0 : }
+      74             : 
+      75           0 : 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           0 :   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           0 :   for(unsigned i=0; i<reserved_keys.size(); ++i) {
+      95           0 :     std::string thiskey=reserved_keys[i];
+      96           0 :     for(unsigned j=0; j<kk.size(); ++j) plumed_massert( thiskey!=kk[j], "keyword " + thiskey + " is in twice" );
+      97           0 :     for(unsigned j=0; j<rk.size(); ++j) plumed_massert( thiskey!=rk[j], "keyword " + thiskey + " is in twice" );
+      98           0 :     rk.push_back( thiskey );
+      99           0 :     plumed_massert( types.count( thiskey ), "no type data on keyword " + thiskey + " to copy" );
+     100           0 :     tt.insert( std::pair<std::string,KeyType>( thiskey,types.find(thiskey)->second) );
+     101           0 :     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           0 :     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           0 :     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           0 :   for(unsigned i=0; i<cnames.size(); ++i) {
+     110           0 :     std::string thisnam=cnames[i];
+     111           0 :     for(unsigned j=0; j<cnam.size(); ++j) plumed_massert( thisnam!=cnam[j], "component " + thisnam + " is in twice" );
+     112           0 :     cnam.push_back( thisnam );
+     113           0 :     plumed_massert( ckey.count( thisnam ), "no keyword data on component " + thisnam + " to copy" );
+     114           0 :     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           0 :     cd.insert( std::pair<std::string,std::string>( thisnam, cdocs.find(thisnam)->second) );
+     117             :   }
+     118           0 : }
+     119             : 
+     120      175563 : void Keywords::reserve( const std::string & t, const std::string & k, const std::string & d ) {
+     121      175563 :   plumed_assert( !exists(k) && !reserved(k) );
+     122      175563 :   std::string fd, lowkey=k;
+     123             :   // Convert to lower case
+     124     1851809 :   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      280441 :     std::size_t num=lowkey.find_first_of("_");
+     128      280441 :     if( num==std::string::npos ) break;
+     129      104878 :     lowkey.erase( lowkey.begin() + num, lowkey.begin() + num + 1 );
+     130      104878 :   }
+     131      175563 :   if( t=="vessel" ) {
+     132           0 :     fd = d + " The final value can be referenced using <em>label</em>." + lowkey;
+     133           0 :     if(d.find("flag")==std::string::npos) fd += ".  You can use multiple instances of this keyword i.e. " +
+     134           0 :           k +"1, " + k + "2, " + k + "3...  The corresponding values are then "
+     135           0 :           "referenced using <em>label</em>."+ lowkey +"-1,  <em>label</em>." + lowkey +
+     136           0 :           "-2,  <em>label</em>." + lowkey + "-3...";
+     137           0 :     allowmultiple.insert( std::pair<std::string,bool>(k,true) );
+     138           0 :     types.insert( std::pair<std::string,KeyType>(k,KeyType("vessel")) );
+     139      175563 :   } else if( t=="numbered" ) {
+     140       20684 :     fd = d + ". You can use multiple instances of this keyword i.e. " + k +"1, " + k + "2, " + k + "3...";
+     141       10342 :     allowmultiple.insert( std::pair<std::string,bool>(k,true) );
+     142       20684 :     types.insert( std::pair<std::string,KeyType>(k,KeyType("optional")) );
+     143             :   } else {
+     144             :     fd = d;
+     145      165574 :     if( t=="atoms" && isaction ) fd = d + ".  For more information on how to specify lists of atoms see \\ref Group";
+     146      165221 :     allowmultiple.insert( std::pair<std::string,bool>(k,false) );
+     147      330442 :     types.insert( std::pair<std::string,KeyType>(k,KeyType(t)) );
+     148      165574 :     if( (types.find(k)->second).isAtomList() ) atomtags.insert( std::pair<std::string,std::string>(k,t) );
+     149             :   }
+     150      175563 :   documentation.insert( std::pair<std::string,std::string>(k,fd) );
+     151      175563 :   reserved_keys.push_back(k);
+     152      175563 : }
+     153             : 
+     154        1322 : void Keywords::reserveFlag( const std::string & k, const bool def, const std::string & d ) {
+     155        1322 :   plumed_assert( !exists(k) && !reserved(k) );
+     156             :   std::string defstr;
+     157        1322 :   if( def ) { defstr="( default=on ) "; } else { defstr="( default=off ) "; }
+     158        2644 :   types.insert( std::pair<std::string,KeyType>(k,KeyType("flag")) );
+     159       19563 :   std::string fd,lowkey=k; std::transform(lowkey.begin(),lowkey.end(),lowkey.begin(),[](unsigned char c) { return std::tolower(c); });
+     160        1322 :   fd=defstr + d;
+     161        2644 :   documentation.insert( std::pair<std::string,std::string>(k,fd) );
+     162        1322 :   allowmultiple.insert( std::pair<std::string,bool>(k,false) );
+     163           0 :   booldefs.insert( std::pair<std::string,bool>(k,def) );
+     164        1322 :   reserved_keys.push_back(k);
+     165        1322 : }
+     166             : 
+     167       28292 : void Keywords::use( const std::string & k ) {
+     168       28292 :   plumed_massert( reserved(k), "the " + k + " keyword is not reserved");
+     169      175133 :   for(unsigned i=0; i<reserved_keys.size(); ++i) {
+     170      146841 :     if(reserved_keys[i]==k) keys.push_back( reserved_keys[i] );
+     171             :   }
+     172       28292 : }
+     173             : 
+     174        6348 : void Keywords::reset_style( const std::string & k, const std::string & style ) {
+     175        6348 :   plumed_massert( exists(k) || reserved(k), "no " + k + " keyword" );
+     176        6348 :   if( style=="numbered" ) { allowmultiple[k]=true; return; }
+     177         680 :   (types.find(k)->second).setStyle(style);
+     178         680 :   if( (types.find(k)->second).isVessel() ) allowmultiple[k]=true;
+     179        1079 :   if( (types.find(k)->second).isAtomList() ) atomtags.insert( std::pair<std::string,std::string>(k,style) );
+     180             : }
+     181             : 
+     182      822223 : void Keywords::add( const std::string & t, const std::string & k, const std::string & d ) {
+     183     2466669 :   plumed_massert( !exists(k) && t!="flag" && !reserved(k) && t!="vessel", "keyword " + k + " has already been registered");
+     184             :   std::string fd;
+     185      822223 :   if( t=="numbered" ) {
+     186       30544 :     fd=d + ". You can use multiple instances of this keyword i.e. " + k +"1, " + k + "2, " + k + "3...";
+     187       15272 :     allowmultiple.insert( std::pair<std::string,bool>(k,true) );
+     188       30544 :     types.insert( std::pair<std::string,KeyType>(k, KeyType("optional")) );
+     189             :   } else {
+     190             :     fd=d;
+     191      806951 :     allowmultiple.insert( std::pair<std::string,bool>(k,false) );
+     192     1613902 :     types.insert( std::pair<std::string,KeyType>(k,KeyType(t)) );
+     193     1000465 :     if( (types.find(k)->second).isAtomList() ) atomtags.insert( std::pair<std::string,std::string>(k,t) );
+     194             :   }
+     195      857836 :   if( t=="atoms" && isaction ) fd = d + ".  For more information on how to specify lists of atoms see \\ref Group";
+     196      822223 :   documentation.insert( std::pair<std::string,std::string>(k,fd) );
+     197      822223 :   keys.push_back(k);
+     198      822223 : }
+     199             : 
+     200      407776 : void Keywords::add( const std::string & t, const std::string & k, const std::string &  def, const std::string & d ) {
+     201      815788 :   plumed_assert( !exists(k) && !reserved(k) &&  (t=="compulsory" || t=="hidden" )); // An optional keyword can't have a default
+     202      407776 :   types.insert(  std::pair<std::string,KeyType>(k, KeyType(t)) );
+     203      815552 :   documentation.insert( std::pair<std::string,std::string>(k,"( default=" + def + " ) " + d) );
+     204      407776 :   allowmultiple.insert( std::pair<std::string,bool>(k,false) );
+     205      407776 :   numdefs.insert( std::pair<std::string,std::string>(k,def) );
+     206      407776 :   keys.push_back(k);
+     207      407776 : }
+     208             : 
+     209      384382 : void Keywords::addFlag( const std::string & k, const bool def, const std::string & d ) {
+     210      384382 :   plumed_massert( !exists(k) && !reserved(k), "keyword " + k + " has already been registered");
+     211      384382 :   std::string defstr; plumed_massert( !def, "the second argument to addFlag must be false " + k );
+     212             :   defstr="( default=off ) ";
+     213      768764 :   types.insert( std::pair<std::string,KeyType>(k,KeyType("flag")) );
+     214      768764 :   documentation.insert( std::pair<std::string,std::string>(k,defstr + d) );
+     215      384382 :   allowmultiple.insert( std::pair<std::string,bool>(k,false) );
+     216           0 :   booldefs.insert( std::pair<std::string,bool>(k,def) );
+     217      384382 :   keys.push_back(k);
+     218      384382 : }
+     219             : 
+     220        8763 : void Keywords::remove( const std::string & k ) {
+     221             :   bool found=false; unsigned j=0, n=0;
+     222             : 
+     223             :   while(true) {
+     224       96495 :     for(j=0; j<keys.size(); j++) if(keys[j]==k)break;
+     225       73750 :     for(n=0; n<reserved_keys.size(); n++) if(reserved_keys[n]==k)break;
+     226       17879 :     if(j<keys.size()) {
+     227        8624 :       keys.erase(keys.begin()+j);
+     228             :       found=true;
+     229        9255 :     } else if(n<reserved_keys.size()) {
+     230         492 :       reserved_keys.erase(reserved_keys.begin()+n);
+     231             :       found=true;
+     232             :     } else break;
+     233             :   }
+     234             :   // Delete documentation, type and so on from the description
+     235             :   types.erase(k); documentation.erase(k); allowmultiple.erase(k); booldefs.erase(k); numdefs.erase(k);
+     236        8763 :   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
+     237        8763 : }
+     238             : 
+     239      174849 : bool Keywords::numbered( const std::string & k ) const {
+     240      349698 :   if( style( k,"atoms") ) return true;
+     241           0 :   plumed_massert( allowmultiple.count(k), "Did not find keyword " + k );
+     242      138735 :   return allowmultiple.find(k)->second;
+     243             : }
+     244             : 
+     245     1594169 : bool Keywords::style( const std::string & k, const std::string & t ) const {
+     246     1594169 :   if( getStyle(k)==t ) return true;
+     247             :   return false;
+     248             : }
+     249             : 
+     250     1118946 : unsigned Keywords::size() const {
+     251     1118946 :   return keys.size();
+     252             : }
+     253             : 
+     254       19520 : std::string Keywords::getKeyword( const unsigned i ) const {
+     255       19520 :   plumed_assert( i<size() );
+     256       19520 :   return keys[i];
+     257             : }
+     258             : 
+     259     2852678 : bool Keywords::exists( const std::string & k ) const {
+     260    25530604 :   for(unsigned i=0; i<keys.size(); ++i) {
+     261    23396064 :     if( keys[i]==k ) return true;
+     262             :   }
+     263             :   return false;
+     264             : }
+     265             : 
+     266     1819558 : bool Keywords::reserved( const std::string & k ) const {
+     267     3410891 :   for(unsigned i=0; i<reserved_keys.size(); ++i) {
+     268     1619625 :     if( reserved_keys[i]==k ) return true;
+     269             :   }
+     270             :   return false;
+     271             : }
+     272             : 
+     273           0 : void Keywords::print_template(const std::string& actionname, bool include_optional) const {
+     274             :   unsigned nkeys=0;
+     275             :   std::printf("%s",actionname.c_str());
+     276           0 :   for(unsigned i=0; i<keys.size(); ++i) {
+     277           0 :     if ( (types.find(keys[i])->second).isAtomList() ) nkeys++;
+     278             :   }
+     279           0 :   if( nkeys>0 ) {
+     280           0 :     std::string prevtag="start";
+     281           0 :     for(unsigned i=0; i<keys.size(); ++i) {
+     282           0 :       if( (types.find(keys[i])->second).isAtomList() ) {
+     283           0 :         plumed_massert( atomtags.count(keys[i]), "keyword " + keys[i] + " allegedly specifies atoms but no tag has been specified. Please email Gareth Tribello");
+     284           0 :         if( prevtag!="start" && prevtag!=atomtags.find(keys[i])->second ) break;
+     285           0 :         if( (atomtags.find(keys[i])->second).find("residues")!=std::string::npos) std::printf(" %s=<residue selection>", keys[i].c_str() );
+     286             :         else std::printf(" %s=<atom selection>", keys[i].c_str() );
+     287           0 :         prevtag=atomtags.find(keys[i])->second;
+     288             :       }
+     289             :     }
+     290             :   }
+     291             :   nkeys=0;
+     292           0 :   for(unsigned i=0; i<keys.size(); ++i) {
+     293           0 :     if ( include_optional || \
+     294           0 :          (types.find(keys[i])->second).isCompulsory() ) nkeys++;
+     295             :   }
+     296           0 :   if( nkeys>0 ) {
+     297           0 :     for(unsigned i=0; i<keys.size(); ++i) {
+     298           0 :       if ( (types.find(keys[i])->second).isCompulsory() ) {
+     299             :         std::string def;
+     300           0 :         if( getDefaultValue( keys[i], def) ) {
+     301             :           std::printf(" %s=%s ", keys[i].c_str(), def.c_str() );
+     302             :         } else {
+     303             :           std::printf(" %s=    ", keys[i].c_str() );
+     304             :         }
+     305           0 :       } else if (include_optional) {
+     306             :         // TG no defaults for optional keywords?
+     307             :         std::printf(" [%s]", keys[i].c_str() );
+     308             :       }
+     309             :     }
+     310             :   }
+     311             :   std::printf("\n");
+     312             :   std::flush(std::cout);
+     313           0 : }
+     314             : 
+     315         434 : void Keywords::print_vim() const {
+     316        5314 :   for(unsigned i=0; i<keys.size(); ++i) {
+     317        4880 :     if( (types.find(keys[i])->second).isFlag() ) {
+     318             :       std::printf( ",flag:%s", keys[i].c_str() );
+     319             :     } else {
+     320        3890 :       if( allowmultiple.find(keys[i])->second ) std::printf(",numbered:%s",keys[i].c_str() );
+     321             :       else std::printf(",option:%s",keys[i].c_str() );
+     322             :     }
+     323             :   }
+     324         434 :   std::fprintf(stdout, "\n%s", getHelpString().c_str() );
+     325         434 : }
+     326             : 
+     327           0 : void Keywords::print_html() const {
+     328             : 
+     329             : // This is the part that outputs the details of the components
+     330           0 :   if( cnames.size()>0 ) {
+     331             :     unsigned ndef=0;
+     332           0 :     for(unsigned i=0; i<cnames.size(); ++i) {
+     333           0 :       if(ckey.find(cnames[i])->second=="default") ndef++;
+     334             :     }
+     335             : 
+     336           0 :     if( ndef>0 ) {
+     337           0 :       std::cout<<"\\par Description of components\n\n";
+     338           0 :       std::cout<<cstring<<"\n\n";
+     339           0 :       std::cout<<" <table align=center frame=void width=95%% cellpadding=5%%> \n";
+     340             :       std::printf("<tr> <td width=5%%> <b> Quantity </b> </td> <td> <b> Description </b> </td> </tr>\n");
+     341             :       unsigned nndef=0;
+     342           0 :       for(unsigned i=0; i<cnames.size(); ++i) {
+     343             :         //plumed_assert( ckey.find(cnames[i])->second=="default" );
+     344           0 :         if( ckey.find(cnames[i])->second!="default" ) { nndef++; continue; }
+     345             :         std::printf("<tr>\n");
+     346             :         std::printf("<td width=15%%> <b> %s </b></td>\n",cnames[i].c_str() );
+     347             :         std::printf("<td> %s </td>\n",(cdocs.find(cnames[i])->second).c_str() );
+     348             :         std::printf("</tr>\n");
+     349             :       }
+     350           0 :       std::cout<<"</table>\n\n";
+     351           0 :       if( nndef>0 ) {
+     352           0 :         std::cout<<"In addition the following quantities can be calculated by employing the keywords listed below"<<std::endl;
+     353           0 :         std::cout<<"\n\n";
+     354           0 :         std::cout<<" <table align=center frame=void width=95%% cellpadding=5%%> \n";
+     355             :         std::printf("<tr> <td width=5%%> <b> Quantity </b> </td> <td> <b> Keyword </b> </td> <td> <b> Description </b> </td> </tr>\n");
+     356           0 :         for(unsigned i=0; i<cnames.size(); ++i) {
+     357           0 :           if( ckey.find(cnames[i])->second!="default") {
+     358             :             std::printf("<tr>\n");
+     359             :             std::printf("<td width=5%%> <b> %s </b></td> <td width=10%%> <b> %s </b> </td> \n",
+     360             :                         cnames[i].c_str(),(ckey.find(cnames[i])->second).c_str() );
+     361             :             std::printf("<td> %s </td>\n",(cdocs.find(cnames[i])->second).c_str() );
+     362             :             std::printf("</tr>\n");
+     363             :           }
+     364             :         }
+     365           0 :         std::cout<<"</table>\n\n";
+     366             :       }
+     367             :     } else {
+     368             :       unsigned nregs=0;
+     369           0 :       for(unsigned i=0; i<cnames.size(); ++i) {
+     370           0 :         if( exists(ckey.find(cnames[i])->second) ) nregs++;
+     371             :       }
+     372           0 :       if( nregs>0 ) {
+     373           0 :         std::cout<<"\\par Description of components\n\n";
+     374           0 :         std::cout<<cstring<<"\n\n";
+     375           0 :         std::cout<<" <table align=center frame=void width=95%% cellpadding=5%%> \n";
+     376             :         std::printf("<tr> <td width=5%%> <b> Quantity </b> </td> <td> <b> Keyword </b> </td> <td> <b> Description </b> </td> </tr>\n");
+     377           0 :         for(unsigned i=0; i<cnames.size(); ++i) {
+     378           0 :           if( exists(ckey.find(cnames[i])->second) ) {
+     379             :             std::printf("<tr>\n");
+     380             :             std::printf("<td width=5%%> <b> %s </b></td> <td width=10%%> <b> %s </b> </td> \n",
+     381             :                         cnames[i].c_str(),(ckey.find(cnames[i])->second).c_str() );
+     382             :             std::printf("<td> %s </td>\n",(cdocs.find(cnames[i])->second).c_str() );
+     383             :             std::printf("</tr>\n");
+     384             :           }
+     385             :         }
+     386           0 :         std::cout<<"</table>\n\n";
+     387             :       }
+     388             :     }
+     389             :   }
+     390             : 
+     391             :   unsigned nkeys=0;
+     392           0 :   for(unsigned i=0; i<keys.size(); ++i) {
+     393           0 :     if ( (types.find(keys[i])->second).isAtomList() ) nkeys++;
+     394             :   }
+     395           0 :   if( nkeys>0 ) {
+     396           0 :     if(isaction && isatoms) std::cout<<"\\par The atoms involved can be specified using\n\n";
+     397           0 :     else if(isaction) std::cout<<"\\par The data to analyze can be the output from another analysis algorithm\n\n";
+     398           0 :     else std::cout<<"\\par The input trajectory is specified using one of the following\n\n";
+     399           0 :     std::cout<<" <table align=center frame=void width=95%% cellpadding=5%%> \n";
+     400           0 :     std::string prevtag="start"; unsigned counter=0;
+     401           0 :     for(unsigned i=0; i<keys.size(); ++i) {
+     402           0 :       if ( (types.find(keys[i])->second).isAtomList() ) {
+     403           0 :         plumed_massert( atomtags.count(keys[i]), "keyword " + keys[i] + " allegedly specifies atoms but no tag has been specified. Please email Gareth Tribello");
+     404           0 :         if( prevtag!="start" && prevtag!=atomtags.find(keys[i])->second && isaction ) {
+     405           0 :           std::cout<<"</table>\n\n";
+     406           0 :           if( isatoms ) std::cout<<"\\par Or alternatively by using\n\n";
+     407           0 :           else if( counter==0 ) { std::cout<<"\\par Alternatively data can be collected from the trajectory using \n\n"; counter++; }
+     408           0 :           else std::cout<<"\\par Lastly data collected in a previous analysis action can be reanalyzed by using the keyword \n\n";
+     409           0 :           std::cout<<" <table align=center frame=void width=95%% cellpadding=5%%> \n";
+     410             :         }
+     411           0 :         print_html_item( keys[i] );
+     412           0 :         prevtag=atomtags.find(keys[i])->second;
+     413             :       }
+     414             :     }
+     415           0 :     std::cout<<"</table>\n\n";
+     416             :   }
+     417             :   nkeys=0;
+     418           0 :   for(unsigned i=0; i<keys.size(); ++i) {
+     419           0 :     if ( (types.find(keys[i])->second).isCompulsory() ) nkeys++;
+     420             :   }
+     421           0 :   if( nkeys>0 ) {
+     422           0 :     if(isaction) std::cout<< "\\par Compulsory keywords\n\n";
+     423           0 :     else std::cout<<"\\par The following must be present\n\n";
+     424           0 :     std::cout<<" <table align=center frame=void width=95%% cellpadding=5%%> \n";
+     425           0 :     for(unsigned i=0; i<keys.size(); ++i) {
+     426           0 :       if ( (types.find(keys[i])->second).isCompulsory() ) print_html_item( keys[i] );
+     427             :     }
+     428           0 :     std::cout<<"</table>\n\n";
+     429             :   }
+     430             :   nkeys=0;
+     431           0 :   for(unsigned i=0; i<keys.size(); ++i) {
+     432           0 :     if ( (types.find(keys[i])->second).isFlag() || (types.find(keys[i])->second).isOptional() || (types.find(keys[i])->second).isVessel() ) nkeys++;
+     433             :   }
+     434           0 :   if( nkeys>0 ) {
+     435           0 :     if(isaction) std::cout<<"\\par Options\n\n";
+     436           0 :     else std::cout<<"\\par The following options are available\n\n";
+     437           0 :     std::cout<<" <table align=center frame=void width=95%% cellpadding=5%%> \n";
+     438           0 :     for(unsigned i=0; i<keys.size(); ++i) {
+     439           0 :       if ( (types.find(keys[i])->second).isFlag() ) print_html_item( keys[i] );
+     440             :     }
+     441           0 :     std::cout<<"\n";
+     442             :   }
+     443             :   nkeys=0;
+     444           0 :   for(unsigned i=0; i<keys.size(); ++i) {
+     445           0 :     if ( (types.find(keys[i])->second).isOptional() || (types.find(keys[i])->second).isVessel() ) nkeys++;
+     446             :   }
+     447           0 :   if( nkeys>0 ) {
+     448           0 :     for(unsigned i=0; i<keys.size(); ++i) {
+     449           0 :       if ( (types.find(keys[i])->second).isOptional() || (types.find(keys[i])->second).isVessel() ) print_html_item( keys[i] );
+     450             :     }
+     451             :   }
+     452           0 :   std::cout<<"</table>\n\n";
+     453           0 : }
+     454             : 
+     455           0 : void Keywords::print_spelling() const {
+     456           0 :   for(unsigned i=0; i<keys.size(); ++i) std::printf("%s\n", keys[i].c_str() );
+     457           0 :   for(unsigned i=0; i<cnames.size(); ++i) std::printf("%s\n",cnames[i].c_str() );
+     458           0 : }
+     459             : 
+     460        7892 : std::string Keywords::getKeywordDocs( const std::string& key ) const {
+     461        7892 :   bool killdot=( (documentation.find(key)->second).find("\\f$")!=std::string::npos ); // Check for latex
+     462        7892 :   std::vector<std::string> w=Tools::getWords( documentation.find(key)->second );
+     463       15784 :   std::stringstream sstr; sstr<<std::setw(23)<<key<<" - ";
+     464        7892 :   unsigned nl=0; std::string blank=" ";
+     465      189268 :   for(unsigned i=0; i<w.size(); ++i) {
+     466      181886 :     nl+=w[i].length() + 1;
+     467      181886 :     if( nl>60 ) {
+     468       39540 :       sstr<<"\n"<<std::setw(23)<<blank<<"   "<<w[i]<<" "; nl=0;
+     469      168706 :     } else sstr<<w[i]<<" ";
+     470      181886 :     if( killdot && w[i].find(".")!=std::string::npos ) break; // If there is latex only write up to first dot
+     471             :   }
+     472       15784 :   sstr<<"\n"; return sstr.str();
+     473        7892 : }
+     474             : 
+     475         868 : std::string Keywords::getHelpString() const {
+     476             :   std::string helpstr; unsigned nkeys=0;
+     477       10628 :   for(unsigned i=0; i<keys.size(); ++i) {
+     478        9760 :     if ( (types.find(keys[i])->second).isAtomList() ) nkeys++;
+     479             :   }
+     480         868 :   if( nkeys>0 ) {
+     481             :     helpstr += "The input trajectory can be in any of the following formats: \n\n";
+     482        4962 :     for(unsigned i=0; i<keys.size(); ++i) {
+     483        5312 :       if ( (types.find(keys[i])->second).isAtomList() ) helpstr += getKeywordDocs( keys[i] );
+     484             :     }
+     485             :   }
+     486             :   nkeys=0;
+     487       10628 :   for(unsigned i=0; i<keys.size(); ++i) {
+     488        9760 :     if ( (types.find(keys[i])->second).isCompulsory() ) nkeys++;
+     489             :   }
+     490             :   unsigned ncompulsory=nkeys;
+     491         868 :   if( nkeys>0 ) {
+     492             :     helpstr += "\nThe following arguments are compulsory: \n\n";
+     493        8612 :     for(unsigned i=0; i<keys.size(); ++i) {
+     494       10184 :       if ( (types.find(keys[i])->second).isCompulsory() ) helpstr += getKeywordDocs( keys[i] );
+     495             :     }
+     496             :   }
+     497             :   nkeys=0;
+     498       10628 :   for(unsigned i=0; i<keys.size(); ++i) {
+     499        9760 :     if ( (types.find(keys[i])->second).isFlag() ) nkeys++;
+     500             :   }
+     501         868 :   if( nkeys>0 ) {
+     502         694 :     if(ncompulsory>0) helpstr += "\nIn addition you may use the following options: \n\n";
+     503             :     else helpstr += "\nThe following options are available\n\n";
+     504        9428 :     for(unsigned i=0; i<keys.size(); ++i) {
+     505       10714 :       if ( (types.find(keys[i])->second).isFlag() ) helpstr += getKeywordDocs( keys[i] ).c_str();
+     506             :     }
+     507             :   }
+     508             :   nkeys=0;
+     509       10628 :   for(unsigned i=0; i<keys.size(); ++i) {
+     510       16488 :     if ( (types.find(keys[i])->second).isOptional() || (types.find(keys[i])->second).isVessel() ) nkeys++;
+     511             :   }
+     512         868 :   if( nkeys>0 ) {
+     513        9164 :     for(unsigned i=0; i<keys.size(); ++i) {
+     514       16996 :       if ( (types.find(keys[i])->second).isOptional() || (types.find(keys[i])->second).isVessel() ) helpstr += getKeywordDocs( keys[i] );
+     515             :     }
+     516             :     helpstr += "\n";
+     517             :   }
+     518         868 :   return helpstr;
+     519             : }
+     520             : 
+     521           0 : void Keywords::print( Log& log ) const {
+     522           0 :   log.printf("%s", getHelpString().c_str() );
+     523           0 : }
+     524             : 
+     525           0 : void Keywords::print( FILE* out ) const {
+     526           0 :   fprintf( out,"%s", getHelpString().c_str() );
+     527           0 : }
+     528             : 
+     529           0 : std::string Keywords::getTooltip( const std::string& name ) const {
+     530           0 :   std::size_t dd=name.find_first_of("0123456789"); std::string kname=name.substr(0,dd);
+     531           0 :   if( !exists(kname) ) return "<b> could not find this keyword </b>";
+     532           0 :   std::string mystring, docstr = documentation.find(kname)->second;
+     533           0 :   if( types.find(kname)->second.isCompulsory() ) {
+     534             :     mystring += "<b>compulsory keyword ";
+     535           0 :     if( docstr.find("default")!=std::string::npos ) {
+     536           0 :       std::size_t bra = docstr.find_first_of(")"); mystring += docstr.substr(0,bra+1); docstr = docstr.substr(bra+1);
+     537             :     }
+     538             :     mystring += "</b>\n";
+     539             :   }
+     540           0 :   std::vector<std::string> w=Tools::getWords( docstr ); unsigned nl=0;
+     541           0 :   for(unsigned i=0; i<w.size(); ++i) {
+     542           0 :     nl+=w[i].length() + 1;
+     543           0 :     if( nl>80 ) { mystring += w[i] + "\n"; nl=0; }
+     544           0 :     else { mystring += w[i] + " "; }
+     545           0 :     if( w[i].find(".")!=std::string::npos ) break; // Only write up the the first dot
+     546             :   }
+     547             :   return mystring;
+     548           0 : }
+     549             : 
+     550           0 : void Keywords::print_html_item( const std::string& key ) const {
+     551             :   std::printf("<tr>\n");
+     552             :   std::printf("<td width=15%%> <b> %s </b></td>\n",key.c_str() );
+     553             :   std::printf("<td> %s </td>\n",(documentation.find(key)->second).c_str() );
+     554             :   std::printf("</tr>\n");
+     555           0 : }
+     556             : 
+     557      528183 : std::string Keywords::get( const unsigned k ) const {
+     558      528183 :   plumed_assert( k<size() );
+     559      528183 :   return keys[k];
+     560             : }
+     561             : 
+     562       80716 : bool Keywords::getLogicalDefault(const std::string & key, bool& def ) const {
+     563       80716 :   if( booldefs.find(key)!=booldefs.end() ) {
+     564       80716 :     def=booldefs.find(key)->second;
+     565       80716 :     return true;
+     566             :   } else {
+     567             :     return false;
+     568             :   }
+     569             : }
+     570             : 
+     571       22246 : bool Keywords::getDefaultValue(const std::string & key, std::string& def ) const {
+     572       32720 :   plumed_assert( style(key,"compulsory") || style(key,"hidden") );
+     573             : 
+     574       22246 :   if( numdefs.find(key)!=numdefs.end() ) {
+     575       17010 :     def=numdefs.find(key)->second;
+     576       17010 :     return true;
+     577             :   } else {
+     578             :     return false;
+     579             :   }
+     580             : }
+     581             : 
+     582           0 : void Keywords::destroyData() {
+     583           0 :   keys.clear(); reserved_keys.clear(); types.clear();
+     584             :   allowmultiple.clear(); documentation.clear();
+     585             :   booldefs.clear(); numdefs.clear(); atomtags.clear();
+     586             :   ckey.clear(); cdocs.clear(); ckey.clear();
+     587           0 : }
+     588             : 
+     589       23468 : void Keywords::setComponentsIntroduction( const std::string& instr ) {
+     590       23468 :   cstring = instr;
+     591       23468 : }
+     592             : 
+     593       82066 : void Keywords::addOutputComponent( const std::string& name, const std::string& key, const std::string& descr ) {
+     594       82066 :   plumed_assert( !outputComponentExists( name, false ) );
+     595       82066 :   plumed_massert( name.find("-")==std::string::npos,"dash is reseved character in component names" );
+     596             : 
+     597       82066 :   std::size_t num2=name.find_first_of("_");
+     598       82066 :   if( num2!=std::string::npos ) {
+     599         633 :     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");
+     600         633 :     plumed_massert( num2==0, "underscore is reserved character in component names that has special meaning");
+     601             :   }
+     602             : 
+     603       82066 :   ckey.insert( std::pair<std::string,std::string>(name,key) );
+     604       82066 :   cdocs.insert( std::pair<std::string,std::string>(name,descr) );
+     605       82066 :   cnames.push_back(name);
+     606       82066 : }
+     607             : 
+     608      169844 : bool Keywords::outputComponentExists( const std::string& name, const bool& custom ) const {
+     609      169844 :   if( custom && cstring.find("customize")!=std::string::npos ) return true;
+     610             : 
+     611             :   std::string sname;
+     612      165809 :   std::size_t num=name.find_first_of("-");
+     613      165809 :   std::size_t num2=name.find_last_of("_");
+     614             : 
+     615      168264 :   if( num2!=std::string::npos ) sname=name.substr(num2);
+     616      190218 :   else if( num!=std::string::npos ) sname=name.substr(0,num);
+     617             :   else sname=name;
+     618             : 
+     619      777997 :   for(unsigned i=0; i<cnames.size(); ++i) {
+     620      695931 :     if( sname==cnames[i] ) return true;
+     621             :   }
+     622             :   return false;
+     623             : }
+     624             : 
+     625         773 : std::string Keywords::getOutputComponentFlag( const std::string& name ) const {
+     626         773 :   return ckey.find(name)->second;
+     627             : }
+     628             : 
+     629         548 : std::string Keywords::getOutputComponentDescription( const std::string& name ) const {
+     630         548 :   if( cstring.find("customized")!=std::string::npos ) return "the label of this action is set by user in the input. See documentation above.";
+     631             : 
+     632             :   bool found=false;
+     633        5406 :   for(unsigned i=0; i<cnames.size(); ++i) {
+     634        4859 :     if( name==cnames[i] ) found=true;
+     635             :   }
+     636         547 :   if( !found ) plumed_merror("could not find output component named " + name );
+     637         547 :   return cdocs.find(name)->second;
+     638             : }
+     639             : 
+     640           0 : void Keywords::removeComponent( const std::string& name ) {
+     641             :   bool found=false;
+     642             : 
+     643             :   while(true) {
+     644             :     unsigned j;
+     645           0 :     for(j=0; j<cnames.size(); j++) if(cnames[j]==name)break;
+     646           0 :     if(j<cnames.size()) {
+     647           0 :       cnames.erase(cnames.begin()+j);
+     648             :       found=true;
+     649             :     } else break;
+     650           0 :   }
+     651             :   // Delete documentation, type and so on from the description
+     652             :   cdocs.erase(name); ckey.erase(name);
+     653           0 :   plumed_massert(found,"You are trying to remove " + name + " a component that isn't there");
+     654           0 : }
+     655             : 
+     656        5418 : std::vector<std::string> Keywords::getOutputComponents() const {
+     657        5418 :   return cnames;
+     658             : }
+     659             : 
+     660        4880 : std::string Keywords::getKeywordDescription( const std::string& key ) const {
+     661        9760 :   plumed_assert( exists( key ) ); return documentation.find(key)->second;
+     662             : }
+     663             : 
+     664       70614 : void Keywords::needsAction( const std::string& name ) {
+     665       70614 :   if( std::find(neededActions.begin(), neededActions.end(), name )!=neededActions.end() ) return;
+     666       70013 :   neededActions.push_back( name );
+     667             : }
+     668             : 
+     669         555 : const std::vector<std::string>& Keywords::getNeededKeywords() const {
+     670         555 :   return neededActions;
+     671             : }
+     672             : 
+     673       30863 : void Keywords::addActionNameSuffix( const std::string& suffix ) {
+     674       30863 :   if( std::find(actionNameSuffixes.begin(), actionNameSuffixes.end(), suffix )!=actionNameSuffixes.end() ) return;
+     675       30863 :   actionNameSuffixes.push_back( suffix );
+     676             : }
+     677             : 
+     678             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Keywords.h.func-sort-c.html b/coverage/tools/Keywords.h.func-sort-c.html new file mode 100644 index 000000000000..f231aa59f2e0 --- /dev/null +++ b/coverage/tools/Keywords.h.func-sort-c.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - tools/Keywords.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Keywords.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:131681.2 %
Date:2024-04-19 12:12:35Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8KeywordsC2Ev158110
_ZNK4PLMD8Keywords7KeyType8toStringB5cxx11Ev1599049
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Keywords.h.func.html b/coverage/tools/Keywords.h.func.html new file mode 100644 index 000000000000..2aa33026d618 --- /dev/null +++ b/coverage/tools/Keywords.h.func.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - tools/Keywords.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Keywords.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:131681.2 %
Date:2024-04-19 12:12:35Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8KeywordsC2Ev158110
_ZNK4PLMD8Keywords7KeyType8toStringB5cxx11Ev1599049
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Keywords.h.gcov.html b/coverage/tools/Keywords.h.gcov.html new file mode 100644 index 000000000000..ff9b3459a736 --- /dev/null +++ b/coverage/tools/Keywords.h.gcov.html @@ -0,0 +1,272 @@ + + + + + + + + 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:131681.2 %
Date:2024-04-19 12:12:35Functions: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       17720 :     bool isCompulsory() const { return (style==compulsory); }
+      44       23374 :     bool isFlag() const { return (style==flag); }
+      45       18258 :     bool isOptional() const { return (style==optional); }
+      46      987268 :     bool isAtomList() const { return (style==atoms); }
+      47       12874 :     bool isVessel() const { return (style==vessel); }
+      48     1599049 :     std::string toString() const {
+      49     1599049 :       if(style==compulsory) return "compulsory";
+      50      508263 :       else if(style==optional) return "optional";
+      51      290805 :       else if(style==atoms) return "atoms";
+      52      608349 :       else if(style==flag) return "flag";
+      53       86687 :       else if(style==hidden) return "hidden";
+      54           0 :       else if(style==vessel) return "vessel";
+      55           0 :       else plumed_assert(0);
+      56             :       return "";
+      57             :     }
+      58             :   };
+      59             :   friend class Action;
+      60             :   friend class ActionShortcut;
+      61             : private:
+      62             : /// Is this an action or driver (this bool affects what style==atoms does in print)
+      63             :   bool isaction;
+      64             : /// This allows us to overwrite the behavior of the atoms type in analysis actions
+      65             :   bool isatoms;
+      66             : /// The names of the allowed keywords
+      67             :   std::vector<std::string> keys;
+      68             : /// The names of the reserved keywords
+      69             :   std::vector<std::string> reserved_keys;
+      70             : /// Whether the keyword is compulsory, optional...
+      71             :   std::map<std::string,KeyType> types;
+      72             : /// Do we allow stuff like key1, key2 etc
+      73             :   std::map<std::string,bool> allowmultiple;
+      74             : /// The documentation for the keywords
+      75             :   std::map<std::string,std::string> documentation;
+      76             : /// The default values for the flags (are they on or of)
+      77             :   std::map<std::string,bool> booldefs;
+      78             : /// The default values (if there are default values) for compulsory keywords
+      79             :   std::map<std::string,std::string> numdefs;
+      80             : /// The tags for atoms - we use this so the manual can differentiate between different ways of specifying atoms
+      81             :   std::map<std::string,std::string> atomtags;
+      82             : /// The string that should be printed out to describe how the components work for this particular action
+      83             :   std::string cstring;
+      84             : /// The names of all the possible components for an action
+      85             :   std::vector<std::string> cnames;
+      86             : /// The keyword that turns on a particular component
+      87             :   std::map<std::string,std::string> ckey;
+      88             : /// The documentation for a particular component
+      89             :   std::map<std::string,std::string> cdocs;
+      90             : /// The list of actions that are needed by this action
+      91             :   std::vector<std::string> neededActions;
+      92             : /// List of suffixes that can be used with this action
+      93             :   std::vector<std::string> actionNameSuffixes;
+      94             : /// Print the documentation for the jth keyword in html
+      95             :   void print_html_item( const std::string& ) const;
+      96             : public:
+      97             : /// Constructor
+      98      158110 :   Keywords() : isaction(true), isatoms(true) {}
+      99             : ///
+     100       10176 :   void isDriver() { isaction=false; }
+     101             : ///
+     102             :   void isAnalysis() { isatoms=false; }
+     103             : /// find out whether flag key is on or off by default.
+     104             :   bool getLogicalDefault(const std::string & key, bool& def ) const ;
+     105             : /// Get the value of the default for the keyword named key
+     106             :   bool getDefaultValue(const std::string & key, std::string& def ) const ;
+     107             : /// Return the number of defined keywords
+     108             :   unsigned size() const;
+     109             : /// Check if numbered keywords are allowed for this action
+     110             :   bool numbered( const std::string & k ) const ;
+     111             : /// Return the ith keyword
+     112             :   std::string getKeyword( const unsigned i ) const ;
+     113             : /// Get the documentation for a particular keyword
+     114             :   std::string getKeywordDocs( const std::string& key ) const ;
+     115             : /// Print the documentation to the log file (used by PLMD::Action::error)
+     116             :   void print( Log& log ) const ;
+     117             : /// Print the documentation to a file (use by PLUMED::CLTool::readCommandLineArgs)
+     118             :   void print( FILE* out ) const ;
+     119             : /// Get the help string
+     120             :   std::string getHelpString() const ;
+     121             : /// Print a file containing the list of keywords for a particular action (used for spell checking)
+     122             :   void print_spelling() const ;
+     123             : /// Reserve a keyword
+     124             :   void reserve( const std::string & t, const std::string & k, const std::string & d );
+     125             : /// Reserve a flag
+     126             :   void reserveFlag( const std::string & k, const bool def, const std::string & d );
+     127             : /// Use one of the reserved keywords
+     128             :   void use( const std::string  & k );
+     129             : /// Get the ith keyword
+     130             :   std::string get( const unsigned k ) const ;
+     131             : /// Add a new keyword of type t with name k and description d
+     132             :   void add( const std::string & t, const std::string & k, const std::string & d );
+     133             : /// Add a new compulsory keyword (t must equal compulsory) with name k, default value def and description d
+     134             :   void add( const std::string & t, const std::string & k, const std::string & def, const std::string & d );
+     135             : /// 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
+     136             :   void addFlag( const std::string & k, const bool def, const std::string & d );
+     137             : /// Remove the keyword with name k
+     138             :   void remove( const std::string & k );
+     139             : /// Check if there is a keyword with name k
+     140             :   bool exists( const std::string & k ) const ;
+     141             : /// Check the keyword k has been reserved
+     142             :   bool reserved( const std::string & k ) const ;
+     143             : /// Get the type for the keyword with string k
+     144             :   std::string getStyle( const std::string & k ) const ;
+     145             : /// Check if the keyword with name k has style t
+     146             :   bool style( const std::string & k, const std::string & t ) const ;
+     147             : /// Print an html version of the documentation
+     148             :   void print_html() const ;
+     149             : /// Print keywords in form readable by vim
+     150             :   void print_vim() const ;
+     151             : /// Print the template version for the documentation
+     152             :   void print_template( const std::string& actionname, bool include_optional) const ;
+     153             : /// Change the style of a keyword
+     154             :   void reset_style( const std::string & k, const std::string & style );
+     155             : /// Add keywords from one keyword object to another
+     156             :   void add( const Keywords& keys );
+     157             : /// Copy the keywords data
+     158             :   void copyData( std::vector<std::string>& kk, std::vector<std::string>& rk, std::map<std::string,KeyType>& tt, std::map<std::string,bool>& am,
+     159             :                  std::map<std::string,std::string>& docs, std::map<std::string,bool>& bools, std::map<std::string,std::string>& nums,
+     160             :                  std::map<std::string,std::string>& atags, std::vector<std::string>& cnam, std::map<std::string,std::string>& ck,
+     161             :                  std::map<std::string,std::string>& cd ) const ;
+     162             : /// Clear everything from the keywords object.
+     163             : /// Not actually needed if your Keywords object is going out of scope.
+     164             :   void destroyData();
+     165             : /// Set the text that introduces how the components for this action are introduced
+     166             :   void setComponentsIntroduction( const std::string& instr );
+     167             : /// Add a potential component which can be output by this particular action
+     168             :   void addOutputComponent( const std::string& name, const std::string& key, const std::string& descr );
+     169             : /// Has a component with this name been added?
+     170             :   bool outputComponentExists( const std::string& name, const bool& custom ) const ;
+     171             : /// Get the flag that forces this component to be calculated
+     172             :   std::string getOutputComponentFlag( const std::string& name ) const ;
+     173             : /// Get the description of this component
+     174             :   std::string getOutputComponentDescription( const std::string& name ) const ;
+     175             : /// Get the full list of output components
+     176             :   std::vector<std::string> getOutputComponents() const ;
+     177             : /// Get the description of a particular keyword
+     178             :   std::string getKeywordDescription( const std::string& name ) const ;
+     179             : /// Remove a component with a particular name from the keywords
+     180             :   void removeComponent( const std::string& name );
+     181             : /// Reference to keys
+     182           0 :   std::vector<std::string> getKeys() const { return keys; }
+     183             : /// Get the description of a particular keyword
+     184             :   std::string getTooltip( const std::string& name ) const ;
+     185             : /// Note that another actions is required to create this shortcut
+     186             :   void needsAction( const std::string& name );
+     187             : /// Add a suffix to the list of action name suffixes to test for
+     188             :   void addActionNameSuffix( const std::string& suffix );
+     189             : /// Get the list of keywords that are needed by this action
+     190             :   const std::vector<std::string>& getNeededKeywords() const ;
+     191             : };
+     192             : 
+     193             : }
+     194             : 
+     195             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/LatticeReduction.cpp.func-sort-c.html b/coverage/tools/LatticeReduction.cpp.func-sort-c.html new file mode 100644 index 000000000000..abaf490dc363 --- /dev/null +++ b/coverage/tools/LatticeReduction.cpp.func-sort-c.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - tools/LatticeReduction.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - LatticeReduction.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10212382.9 %
Date:2024-04-19 12:12:35Functions: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_13TensorGenericILj3ELj3EEE19979
_ZN4PLMD16LatticeReduction10reduceFastERNS_13TensorGenericILj3ELj3EEE19980
_ZN4PLMD16LatticeReduction6reduceERNS_13VectorGenericILj3EEES3_34722
_ZN4PLMD16LatticeReduction4sortEPNS_13VectorGenericILj3EEE54696
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/LatticeReduction.cpp.func.html b/coverage/tools/LatticeReduction.cpp.func.html new file mode 100644 index 000000000000..e41a2d882b7a --- /dev/null +++ b/coverage/tools/LatticeReduction.cpp.func.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - tools/LatticeReduction.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - LatticeReduction.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10212382.9 %
Date:2024-04-19 12:12:35Functions:81080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD16LatticeReduction10isReduced2ERKNS_13VectorGenericILj3EEES4_S4_0
_ZN4PLMD16LatticeReduction10reduceFastERNS_13TensorGenericILj3ELj3EEE19980
_ZN4PLMD16LatticeReduction10reduceSlowERNS_13TensorGenericILj3ELj3EEE1
_ZN4PLMD16LatticeReduction4sortEPNS_13VectorGenericILj3EEE54696
_ZN4PLMD16LatticeReduction6reduceERNS_13TensorGenericILj3ELj3EEE19979
_ZN4PLMD16LatticeReduction6reduceERNS_13VectorGenericILj3EEES3_34722
_ZN4PLMD16LatticeReduction7reduce2ERNS_13TensorGenericILj3ELj3EEE0
_ZN4PLMD16LatticeReduction7reduce2ERNS_13VectorGenericILj3EEES3_S3_1
_ZN4PLMD16LatticeReduction9isReducedERKNS_13TensorGenericILj3ELj3EEE2
_ZN4PLMD16LatticeReduction9isReducedERKNS_13VectorGenericILj3EEES4_11
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/LatticeReduction.cpp.gcov.html b/coverage/tools/LatticeReduction.cpp.gcov.html new file mode 100644 index 000000000000..c23b1ede8d47 --- /dev/null +++ b/coverage/tools/LatticeReduction.cpp.gcov.html @@ -0,0 +1,292 @@ + + + + + + + + LCOV - plumed test coverage - tools/LatticeReduction.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - LatticeReduction.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10212382.9 %
Date:2024-04-19 12:12:35Functions: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       54696 : void LatticeReduction::sort(Vector v[3]) {
+      32             :   const double onePlusEpsilon=(1.0+epsilon);
+      33             :   double m[3];
+      34       54696 :   m[0]=modulo2(v[0]);
+      35       54696 :   m[1]=modulo2(v[1]);
+      36       54696 :   m[2]=modulo2(v[2]);
+      37      382872 :   for(int i=0; i<3; i++) for(int j=i+1; j<3; j++) if(m[i]>m[j]) {
+      38       11751 :         std::swap(v[i],v[j]);
+      39             :         std::swap(m[i],m[j]);
+      40             :       }
+      41       54696 :   plumed_assert(m[0]<=m[1]*onePlusEpsilon);
+      42       54696 :   plumed_assert(m[1]<=m[2]*onePlusEpsilon);
+      43       54696 : }
+      44             : 
+      45       34722 : void LatticeReduction::reduce(Vector&a,Vector&b) {
+      46             :   const double onePlusEpsilon=(1.0+epsilon);
+      47       34722 :   double ma=modulo2(a);
+      48       34722 :   double mb=modulo2(b);
+      49             :   unsigned counter=0;
+      50             :   while(true) {
+      51       35283 :     if(mb>ma) {
+      52             :       std::swap(a,b);
+      53             :       std::swap(ma,mb);
+      54             :     }
+      55       35283 :     a-=b*floor(dotProduct(a,b)/mb+0.5);
+      56       35283 :     ma=modulo2(a);
+      57       35283 :     if(mb<=ma*onePlusEpsilon) break;
+      58         561 :     counter++;
+      59         561 :     if(counter%100==0) { // only test rarely since this might be expensive
+      60           0 :       plumed_assert(!std::isnan(ma));
+      61           0 :       plumed_assert(!std::isnan(mb));
+      62             :     }
+      63         561 :     if(counter%10000==0) std::fprintf(stderr,"WARNING: LatticeReduction::reduce stuck after %u iterations\n",counter);
+      64             :   }
+      65             : 
+      66             :   std::swap(a,b);
+      67       34722 : }
+      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       19979 : void LatticeReduction::reduce(Tensor&t) {
+     112       19979 :   reduceFast(t);
+     113       19979 : }
+     114             : 
+     115       19980 : void LatticeReduction::reduceFast(Tensor&t) {
+     116             :   const double onePlusEpsilon=(1.0+epsilon);
+     117       79920 :   Vector v[3];
+     118       19980 :   v[0]=t.getRow(0);
+     119       19980 :   v[1]=t.getRow(1);
+     120       19980 :   v[2]=t.getRow(2);
+     121             :   unsigned counter=0;
+     122             :   while(true) {
+     123       34715 :     sort(v);
+     124       34715 :     reduce(v[0],v[1]);
+     125       34715 :     double b11=modulo2(v[0]);
+     126       34715 :     double b22=modulo2(v[1]);
+     127       34715 :     double b12=dotProduct(v[0],v[1]);
+     128       34715 :     double b13=dotProduct(v[0],v[2]);
+     129       34715 :     double b23=dotProduct(v[1],v[2]);
+     130       34715 :     double z=b11*b22-b12*b12;
+     131       34715 :     double y2=-(b11*b23-b12*b13)/z;
+     132       34715 :     double y1=-(b22*b13-b12*b23)/z;
+     133       34715 :     int x1min=floor(y1);
+     134       34715 :     int x1max=x1min+1;
+     135       34715 :     int x2min=floor(y2);
+     136       34715 :     int x2max=x2min+1;
+     137             :     bool first=true;
+     138             :     double mbest,mtrial;
+     139       34715 :     Vector trial,best;
+     140      104145 :     for(int x1=x1min; x1<=x1max; x1++)
+     141      208290 :       for(int x2=x2min; x2<=x2max; x2++) {
+     142      138860 :         trial=v[2]+x2*v[1]+x1*v[0];
+     143      138860 :         mtrial=modulo2(trial);
+     144      138860 :         if(first || mtrial<mbest) {
+     145             :           mbest=mtrial;
+     146       41808 :           best=trial;
+     147             :           first=false;
+     148             :         }
+     149             :       }
+     150       34715 :     if(modulo2(best)*onePlusEpsilon>=modulo2(v[2])) break;
+     151       14735 :     counter++;
+     152       14735 :     if(counter%10000==0) std::fprintf(stderr,"WARNING: LatticeReduction::reduceFast stuck after %u iterations\n",counter);
+     153       14735 :     v[2]=best;
+     154       14735 :   }
+     155       19980 :   sort(v);
+     156       19980 :   t.setRow(0,v[0]);
+     157       19980 :   t.setRow(1,v[1]);
+     158       19980 :   t.setRow(2,v[2]);
+     159       19980 : }
+     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/LeptonCall.cpp.func-sort-c.html b/coverage/tools/LeptonCall.cpp.func-sort-c.html new file mode 100644 index 000000000000..d35a61f46a3c --- /dev/null +++ b/coverage/tools/LeptonCall.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - tools/LeptonCall.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - LeptonCall.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:384095.0 %
Date:2024-04-19 12:12:35Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10LeptonCall3setERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIS6_SaIS6_EEPNS_6ActionERKb3066
_ZNK4PLMD10LeptonCall8evaluateERKSt6vectorIdSaIdEE22961957
_ZNK4PLMD10LeptonCall13evaluateDerivERKjRKSt6vectorIdSaIdEE32179565
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/LeptonCall.cpp.func.html b/coverage/tools/LeptonCall.cpp.func.html new file mode 100644 index 000000000000..bf83c11b9265 --- /dev/null +++ b/coverage/tools/LeptonCall.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - tools/LeptonCall.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - LeptonCall.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:384095.0 %
Date:2024-04-19 12:12:35Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10LeptonCall3setERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIS6_SaIS6_EEPNS_6ActionERKb3066
_ZNK4PLMD10LeptonCall13evaluateDerivERKjRKSt6vectorIdSaIdEE32179565
_ZNK4PLMD10LeptonCall8evaluateERKSt6vectorIdSaIdEE22961957
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/LeptonCall.cpp.gcov.html b/coverage/tools/LeptonCall.cpp.gcov.html new file mode 100644 index 000000000000..c8b3634ede9a --- /dev/null +++ b/coverage/tools/LeptonCall.cpp.gcov.html @@ -0,0 +1,168 @@ + + + + + + + + LCOV - plumed test coverage - tools/LeptonCall.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - LeptonCall.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:384095.0 %
Date:2024-04-19 12:12:35Functions: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 "LeptonCall.h"
+      23             : #include "OpenMP.h"
+      24             : 
+      25             : namespace PLMD {
+      26             : 
+      27        3066 : void LeptonCall::set(const std::string & func, const std::vector<std::string>& var, Action* action, const bool& a ) {
+      28        3066 :   unsigned nth=OpenMP::getNumThreads(); expression.resize(nth); expression_deriv.resize(var.size());
+      29             :   // Resize the expression for the derivatives
+      30        8031 :   for(unsigned i=0; i<expression_deriv.size(); ++i) expression_deriv[i].resize(OpenMP::getNumThreads());
+      31        3066 :   allow_extra_args=a; nargs=var.size();
+      32             : 
+      33        3066 :   lepton_ref.resize(nth*nargs,nullptr);
+      34        3066 :   lepton::ParsedExpression pe=lepton::Parser::parse(func).optimize(lepton::Constants()); unsigned nt=0;
+      35        3066 :   if( action ) action->log<<"  function as parsed by lepton: "<<pe<<"\n";
+      36        9198 :   for(auto & e : expression) {
+      37        6132 :     e=pe.createCompiledExpression();
+      38       16062 :     for(unsigned j=0; j<var.size(); ++j) {
+      39             :       try {
+      40        9930 :         lepton_ref[nt*var.size()+j]=&const_cast<lepton::CompiledExpression*>(&expression[nt])->getVariableReference(var[j]);
+      41          88 :       } catch(const PLMD::lepton::Exception& exc) {
+      42             : // this is necessary since in some cases lepton things a variable is not present even though it is present
+      43             : // e.g. func=0*x
+      44          88 :       }
+      45             :     }
+      46        6132 :     nt++;
+      47             :   }
+      48        7987 :   for(auto & p : expression[0].getVariables()) {
+      49        4921 :     if(std::find(var.begin(),var.end(),p)==var.end()) {
+      50           0 :       if( action ) action->error("variable " + p + " is not defined");
+      51           0 :       else plumed_merror("variable " + p + " is not defined in lepton function");
+      52             :     }
+      53             :   }
+      54        3066 :   if( action ) action->log<<"  derivatives as computed by lepton:\n";
+      55        3066 :   lepton_ref_deriv.resize(nth*nargs*nargs,nullptr);
+      56        8031 :   for(unsigned i=0; i<var.size(); i++) {
+      57        9930 :     lepton::ParsedExpression pe=lepton::Parser::parse(func).differentiate(var[i]).optimize(lepton::Constants()); nt=0; if( action ) action->log<<"    "<<pe<<"\n";
+      58       14895 :     for(auto & e : expression_deriv[i]) {
+      59        9930 :       e=pe.createCompiledExpression();
+      60       28800 :       for(unsigned j=0; j<var.size(); ++j) {
+      61             :         try {
+      62       18870 :           lepton_ref_deriv[i*OpenMP::getNumThreads()*var.size() + nt*var.size()+j]=&const_cast<lepton::CompiledExpression*>(&expression_deriv[i][nt])->getVariableReference(var[j]);
+      63        6100 :         } catch(const PLMD::lepton::Exception& exc) {
+      64             : // this is necessary since in some cases lepton things a variable is not present even though it is present
+      65             : // e.g. func=0*x
+      66        6100 :         }
+      67             :       }
+      68        9930 :       nt++;
+      69             :     }
+      70             :   }
+      71        3066 : }
+      72             : 
+      73    22961957 : double LeptonCall::evaluate( const std::vector<double>& args ) const {
+      74             :   plumed_dbg_assert( allow_extra_args || args.size()==nargs );
+      75    22961957 :   const unsigned t=OpenMP::getThreadNum(), tbas=t*nargs;
+      76    67568815 :   for(unsigned i=0; i<nargs; ++i) {
+      77    44606858 :     if( lepton_ref[tbas+i] ) *lepton_ref[tbas+i] = args[i];
+      78             :   }
+      79    22961957 :   return expression[t].evaluate();
+      80             : }
+      81             : 
+      82    32179565 : double LeptonCall::evaluateDeriv( const unsigned& ider, const std::vector<double>& args ) const {
+      83             :   plumed_dbg_assert( allow_extra_args || args.size()==nargs ); plumed_dbg_assert( ider<nargs );
+      84    32179565 :   const unsigned t=OpenMP::getThreadNum(), dbas = ider*OpenMP::getNumThreads()*nargs + t*nargs;
+      85   106781812 :   for(unsigned j=0; j<nargs; j++) {
+      86    74602247 :     if(lepton_ref_deriv[dbas+j] ) *lepton_ref_deriv[dbas+j] = args[j];
+      87             :   }
+      88    32179565 :   return expression_deriv[ider][t].evaluate();
+      89             : }
+      90             : 
+      91             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/LeptonCall.h.func-sort-c.html b/coverage/tools/LeptonCall.h.func-sort-c.html new file mode 100644 index 000000000000..665c9e2c128f --- /dev/null +++ b/coverage/tools/LeptonCall.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage - tools/LeptonCall.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - LeptonCall.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-04-19 12:12:35Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/LeptonCall.h.func.html b/coverage/tools/LeptonCall.h.func.html new file mode 100644 index 000000000000..478585871f89 --- /dev/null +++ b/coverage/tools/LeptonCall.h.func.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage - tools/LeptonCall.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - LeptonCall.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-04-19 12:12:35Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/LeptonCall.h.gcov.html b/coverage/tools/LeptonCall.h.gcov.html new file mode 100644 index 000000000000..15305c308405 --- /dev/null +++ b/coverage/tools/LeptonCall.h.gcov.html @@ -0,0 +1,135 @@ + + + + + + + + LCOV - plumed test coverage - tools/LeptonCall.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - LeptonCall.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-04-19 12:12:35Functions: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_LeptonCall_h
+      23             : #define __PLUMED_tools_LeptonCall_h
+      24             : 
+      25             : #include "core/Action.h"
+      26             : #include "lepton/Lepton.h"
+      27             : 
+      28             : namespace PLMD {
+      29             : 
+      30             : /// \ingroup TOOLBOX
+      31             : class LeptonCall {
+      32             : private:
+      33             :   unsigned nargs;
+      34             :   bool allow_extra_args;
+      35             : /// Lepton expression.
+      36             : /// \warning Since lepton::CompiledExpression is mutable, a vector is necessary for multithreading!
+      37             :   std::vector<lepton::CompiledExpression> expression;
+      38             : /// Lepton expression for derivative
+      39             : /// \warning Since lepton::CompiledExpression is mutable, a vector is necessary for multithreading!
+      40             :   std::vector<std::vector<lepton::CompiledExpression> > expression_deriv;
+      41             :   std::vector<double*> lepton_ref;
+      42             :   std::vector<double*> lepton_ref_deriv;
+      43             : public:
+      44             :   void set(const std::string & func, const std::vector<std::string>& var, Action* action=NULL, const bool& a=false );
+      45             :   unsigned getNumberOfArguments() const ;
+      46             :   double evaluate( const std::vector<double>& args ) const ;
+      47             :   double evaluateDeriv( const unsigned& ider, const std::vector<double>& args ) const ;
+      48             : };
+      49             : 
+      50             : inline
+      51             : unsigned LeptonCall::getNumberOfArguments() const {
+      52      567230 :   return nargs;
+      53             : }
+      54             : 
+      55             : }
+      56             : 
+      57             : #endif
+      58             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/LinkCells.cpp.func-sort-c.html b/coverage/tools/LinkCells.cpp.func-sort-c.html new file mode 100644 index 000000000000..89e71ac3d525 --- /dev/null +++ b/coverage/tools/LinkCells.cpp.func-sort-c.html @@ -0,0 +1,117 @@ + + + + + + + + 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:878898.9 %
Date:2024-04-19 12:12:35Functions:1111100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD9LinkCells9getCutoffEv510
_ZN4PLMD9LinkCells9setCutoffERKd650
_ZN4PLMD9LinkCellsC2ERNS_12CommunicatorE650
_ZNK4PLMD9LinkCells24retrieveNeighboringAtomsERKNS_13VectorGenericILj3EEERSt6vectorIjSaIjEERjS8_3375
_ZNK4PLMD9LinkCells12getMaxInCellEv11750
_ZN4PLMD9LinkCells14buildCellListsERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKS1_IjSaIjEERKNS_3PbcE11969
_ZNK4PLMD9LinkCells16addRequiredCellsERKSt5arrayIjLm3EERjRSt6vectorIjSaIjEE262786
_ZNK4PLMD9LinkCells20retrieveAtomsInCellsERKjRKSt6vectorIjSaIjEERjRS5_262786
_ZNK4PLMD9LinkCells21convertIndicesToIndexERKjS2_S2_1183357
_ZNK4PLMD9LinkCells8findCellERKNS_13VectorGenericILj3EEE1183357
_ZNK4PLMD9LinkCells10findMyCellERKNS_13VectorGenericILj3EEE1446143
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/LinkCells.cpp.func.html b/coverage/tools/LinkCells.cpp.func.html new file mode 100644 index 000000000000..6513001fd329 --- /dev/null +++ b/coverage/tools/LinkCells.cpp.func.html @@ -0,0 +1,117 @@ + + + + + + + + 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:878898.9 %
Date:2024-04-19 12:12:35Functions:1111100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9LinkCells14buildCellListsERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKS1_IjSaIjEERKNS_3PbcE11969
_ZN4PLMD9LinkCells9setCutoffERKd650
_ZN4PLMD9LinkCellsC2ERNS_12CommunicatorE650
_ZNK4PLMD9LinkCells10findMyCellERKNS_13VectorGenericILj3EEE1446143
_ZNK4PLMD9LinkCells12getMaxInCellEv11750
_ZNK4PLMD9LinkCells16addRequiredCellsERKSt5arrayIjLm3EERjRSt6vectorIjSaIjEE262786
_ZNK4PLMD9LinkCells20retrieveAtomsInCellsERKjRKSt6vectorIjSaIjEERjRS5_262786
_ZNK4PLMD9LinkCells21convertIndicesToIndexERKjS2_S2_1183357
_ZNK4PLMD9LinkCells24retrieveNeighboringAtomsERKNS_13VectorGenericILj3EEERSt6vectorIjSaIjEERjS8_3375
_ZNK4PLMD9LinkCells8findCellERKNS_13VectorGenericILj3EEE1183357
_ZNK4PLMD9LinkCells9getCutoffEv510
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/LinkCells.cpp.gcov.html b/coverage/tools/LinkCells.cpp.gcov.html new file mode 100644 index 000000000000..89de9d8fe7bb --- /dev/null +++ b/coverage/tools/LinkCells.cpp.gcov.html @@ -0,0 +1,259 @@ + + + + + + + + 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:878898.9 %
Date:2024-04-19 12:12:35Functions:1111100.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         650 : LinkCells::LinkCells( Communicator& cc ) :
+      29         650 :   comm(cc),
+      30         650 :   cutoffwasset(false),
+      31         650 :   link_cutoff(0.0),
+      32         650 :   ncells(3),
+      33        1300 :   nstride(3)
+      34             : {
+      35         650 : }
+      36             : 
+      37         650 : void LinkCells::setCutoff( const double& lcut ) {
+      38         650 :   cutoffwasset=true; link_cutoff=lcut;
+      39         650 : }
+      40             : 
+      41         510 : double LinkCells::getCutoff() const {
+      42         510 :   plumed_assert( cutoffwasset ); return link_cutoff;
+      43             : }
+      44             : 
+      45       11969 : void LinkCells::buildCellLists( const std::vector<Vector>& pos, const std::vector<unsigned>& indices, const Pbc& pbc ) {
+      46       11969 :   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       11969 :   mypbc.setBox( pbc.getBox() );
+      52             : 
+      53             :   // Setup the lists
+      54       11969 :   if( pos.size()!=allcells.size() ) {
+      55         460 :     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       11969 :     Tensor reciprocal(transpose(mypbc.getInvBox()));
+      63       11969 :     ncells[0] = std::floor( 1.0/ reciprocal.getRow(0).modulo() / link_cutoff );
+      64       11969 :     if( ncells[0]==0 ) ncells[0]=1;
+      65       11969 :     ncells[1] = std::floor( 1.0/ reciprocal.getRow(1).modulo() / link_cutoff );
+      66       11969 :     if( ncells[1]==0 ) ncells[1]=1;
+      67       11969 :     ncells[2] = std::floor( 1.0/ reciprocal.getRow(2).modulo() / link_cutoff );
+      68       11969 :     if( ncells[2]==0 ) ncells[2]=1;
+      69             :   }
+      70             :   // Setup the strides
+      71       11969 :   nstride[0]=1; nstride[1]=ncells[0]; nstride[2]=ncells[0]*ncells[1];
+      72             : 
+      73             :   // Setup the storage for link cells
+      74       11969 :   unsigned ncellstot=ncells[0]*ncells[1]*ncells[2];
+      75       11969 :   if( lcell_tots.size()!=ncellstot ) {
+      76         462 :     lcell_tots.resize( ncellstot ); lcell_starts.resize( ncellstot );
+      77             :   }
+      78             :   // Clear nlcells
+      79     1543036 :   for(unsigned i=0; i<ncellstot; ++i) lcell_tots[i]=0;
+      80             :   // Clear allcells
+      81       11969 :   allcells.assign( allcells.size(), 0 );
+      82             : 
+      83             :   // Find out what cell everyone is in
+      84       11969 :   unsigned rank=comm.Get_rank(), size=comm.Get_size();
+      85     1195326 :   for(unsigned i=rank; i<pos.size(); i+=size) {
+      86     1183357 :     allcells[i]=findCell( pos[i] );
+      87     1183357 :     lcell_tots[allcells[i]]++;
+      88             :   }
+      89             :   // And gather all this information on every node
+      90       11969 :   comm.Sum( allcells ); comm.Sum( lcell_tots );
+      91             : 
+      92             :   // Now prepare the link cell lists
+      93             :   unsigned tot=0;
+      94     1543036 :   for(unsigned i=0; i<lcell_tots.size(); ++i) { lcell_starts[i]=tot; tot+=lcell_tots[i]; lcell_tots[i]=0; }
+      95       11969 :   plumed_assert( tot==pos.size() );
+      96             : 
+      97             :   // And setup the link cells properly
+      98     1267732 :   for(unsigned j=0; j<pos.size(); ++j) {
+      99     1255763 :     unsigned myind = lcell_starts[ allcells[j] ] + lcell_tots[ allcells[j] ];
+     100     1255763 :     lcell_lists[ myind ] = indices[j];
+     101     1255763 :     lcell_tots[allcells[j]]++;
+     102             :   }
+     103       11969 : }
+     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      262786 : 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     1369765 :   for(int nx=LINKC_MIN(ncells[0]); nx<LINKC_MAX(ncells[0]); ++nx) {
+     113      459037 :     int xval = celn[0] + nx;
+     114      459037 :     xval=LINKC_PBC(xval,ncells[0])*nstride[0];
+     115     3113069 :     for(int ny=LINKC_MIN(ncells[1]); ny<LINKC_MAX(ncells[1]); ++ny) {
+     116     1042887 :       int yval = celn[1] + ny;
+     117     1042887 :       yval=LINKC_PBC(yval,ncells[1])*nstride[1];
+     118     8298276 :       for(int nz=LINKC_MIN(ncells[2]); nz<LINKC_MAX(ncells[2]); ++nz) {
+     119     2777298 :         int zval = celn[2] + nz;
+     120     2777298 :         zval=LINKC_PBC(zval,ncells[2])*nstride[2];
+     121             : 
+     122     2777298 :         unsigned mybox=xval+yval+zval; bool added=false;
+     123     2777298 :         for(unsigned k=0; k<ncells_required; ++k) {
+     124           0 :           if( mybox==cells_required[k] ) { added=true; break; }
+     125             :         }
+     126     2777298 :         if( !added ) { cells_required[ncells_required+nnew_cells]=mybox; nnew_cells++; }
+     127             :       }
+     128             :     }
+     129             :   }
+     130      262786 :   ncells_required += nnew_cells;
+     131      262786 : }
+     132             : 
+     133        3375 : void LinkCells::retrieveNeighboringAtoms( const Vector& pos, std::vector<unsigned>& cell_list,
+     134             :     unsigned& natomsper, std::vector<unsigned>& atoms ) const {
+     135        3375 :   if( cell_list.size()!=getNumberOfCells() ) cell_list.resize( getNumberOfCells() );
+     136        3375 :   unsigned ncellt=0; addRequiredCells( findMyCell( pos ), ncellt, cell_list );
+     137        3375 :   retrieveAtomsInCells( ncellt, cell_list, natomsper, atoms );
+     138        3375 : }
+     139             : 
+     140      262786 : void LinkCells::retrieveAtomsInCells( const unsigned& ncells_required,
+     141             :                                       const std::vector<unsigned>& cells_required,
+     142             :                                       unsigned& natomsper, std::vector<unsigned>& atoms ) const {
+     143     3040084 :   for(unsigned i=0; i<ncells_required; ++i) {
+     144     2777298 :     unsigned mybox=cells_required[i];
+     145    26085213 :     for(unsigned k=0; k<lcell_tots[mybox]; ++k) {
+     146    23307915 :       unsigned myatom = lcell_lists[lcell_starts[mybox]+k];
+     147    23307915 :       if( myatom!=atoms[0] ) { // Ideally would provide an option to not do this
+     148    23054122 :         atoms[natomsper]=myatom;
+     149    23054122 :         natomsper++;
+     150             :       }
+     151             :     }
+     152             :   }
+     153      262786 : }
+     154             : 
+     155     1446143 : std::array<unsigned,3> LinkCells::findMyCell( const Vector& pos ) const {
+     156     1446143 :   Vector fpos=mypbc.realToScaled( pos );
+     157             :   std::array<unsigned,3> celn;
+     158     5784572 :   for(unsigned j=0; j<3; ++j) {
+     159     4338429 :     celn[j] = std::floor( ( Tools::pbc(fpos[j]) + 0.5 ) * ncells[j] );
+     160     4338429 :     plumed_assert( celn[j]>=0 && celn[j]<ncells[j] ); // Check that atom is in box
+     161             :   }
+     162     1446143 :   return celn;
+     163             : }
+     164             : 
+     165     1183357 : unsigned LinkCells::convertIndicesToIndex( const unsigned& nx, const unsigned& ny, const unsigned& nz ) const {
+     166     1183357 :   return nx*nstride[0] + ny*nstride[1] + nz*nstride[2];
+     167             : }
+     168             : 
+     169     1183357 : unsigned LinkCells::findCell( const Vector& pos ) const {
+     170     1183357 :   std::array<unsigned,3> celn( findMyCell(pos ) );
+     171     1183357 :   return convertIndicesToIndex( celn[0], celn[1], celn[2] );
+     172             : }
+     173             : 
+     174       11750 : unsigned LinkCells::getMaxInCell() const {
+     175       11750 :   unsigned maxn = lcell_tots[0];
+     176     1527421 :   for(unsigned i=1; i<lcell_tots.size(); ++i) {
+     177     1515671 :     if( lcell_tots[i]>maxn ) { maxn=lcell_tots[i]; }
+     178             :   }
+     179       11750 :   return maxn;
+     180             : }
+     181             : 
+     182             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/LinkCells.h.func-sort-c.html b/coverage/tools/LinkCells.h.func-sort-c.html new file mode 100644 index 000000000000..69e947f4459a --- /dev/null +++ b/coverage/tools/LinkCells.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage - tools/LinkCells.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - LinkCells.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-04-19 12:12:35Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/LinkCells.h.func.html b/coverage/tools/LinkCells.h.func.html new file mode 100644 index 000000000000..bc923dfada8f --- /dev/null +++ b/coverage/tools/LinkCells.h.func.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage - tools/LinkCells.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - LinkCells.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-04-19 12:12:35Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/LinkCells.h.gcov.html b/coverage/tools/LinkCells.h.gcov.html new file mode 100644 index 000000000000..f8c4998e6a7d --- /dev/null +++ b/coverage/tools/LinkCells.h.gcov.html @@ -0,0 +1,178 @@ + + + + + + + + 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:11100.0 %
Date:2024-04-19 12:12:35Functions: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             : /// Get the nuumber of atoms in the cell that contains the most atoms
+      69             :   unsigned getMaxInCell() const ;
+      70             : /// Build the link cell lists
+      71             :   void buildCellLists( const std::vector<Vector>& pos, const std::vector<unsigned>& indices, const Pbc& pbc );
+      72             : /// Take three indices and return the index of the corresponding cell
+      73             :   unsigned convertIndicesToIndex( const unsigned& nx, const unsigned& ny, const unsigned& nz ) const ;
+      74             : /// Find the cell index in which this position is contained
+      75             :   unsigned findCell( const Vector& pos ) const ;
+      76             : /// Find the cell in which this position is contained
+      77             :   std::array<unsigned,3> findMyCell( const Vector& pos ) const ;
+      78             : /// Get the list of cells we need to surround the a particular cell
+      79             :   void addRequiredCells( const std::array<unsigned,3>& celn, unsigned& ncells_required,
+      80             :                          std::vector<unsigned>& cells_required ) const ;
+      81             : /// Retrieve the atoms in a list of cells
+      82             :   void retrieveAtomsInCells( const unsigned& ncells_required,
+      83             :                              const std::vector<unsigned>& cells_required,
+      84             :                              unsigned& natomsper, std::vector<unsigned>& atoms ) const ;
+      85             : /// Retrieve the atoms we need to consider
+      86             :   void retrieveNeighboringAtoms( const Vector& pos, std::vector<unsigned>& cell_list, unsigned& natomsper, std::vector<unsigned>& atoms ) const ;
+      87             : };
+      88             : 
+      89             : inline
+      90             : bool LinkCells::enabled() const {
+      91             :   return cutoffwasset;
+      92             : }
+      93             : 
+      94             : inline
+      95             : unsigned LinkCells::getNumberOfCells() const {
+      96        5295 :   return ncells[0]*ncells[1]*ncells[2];
+      97             : }
+      98             : 
+      99             : }
+     100             : 
+     101             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/LoopUnroller.h.func-sort-c.html b/coverage/tools/LoopUnroller.h.func-sort-c.html new file mode 100644 index 000000000000..cf732eb60534 --- /dev/null +++ b/coverage/tools/LoopUnroller.h.func-sort-c.html @@ -0,0 +1,285 @@ + + + + + + + + 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-04-19 12:12:35Functions:5353100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12LoopUnrollerILj4EE4_negEPdPKd250599
_ZN4PLMD12LoopUnrollerILj5EE4_negEPdPKd250599
_ZN4PLMD12LoopUnrollerILj6EE4_negEPdPKd250599
_ZN4PLMD12LoopUnrollerILj7EE4_negEPdPKd250599
_ZN4PLMD12LoopUnrollerILj8EE4_negEPdPKd250599
_ZN4PLMD12LoopUnrollerILj9EE4_negEPdPKd250599
_ZN4PLMD12LoopUnrollerILj4EE5_sum2EPKd1119102
_ZN4PLMD12LoopUnrollerILj13EE5_zeroEPd1471790
_ZN4PLMD12LoopUnrollerILj14EE5_zeroEPd1471790
_ZN4PLMD12LoopUnrollerILj15EE5_zeroEPd1471790
_ZN4PLMD12LoopUnrollerILj16EE5_zeroEPd1471790
_ZN4PLMD12LoopUnrollerILj10EE5_zeroEPd11725184
_ZN4PLMD12LoopUnrollerILj11EE5_zeroEPd11725184
_ZN4PLMD12LoopUnrollerILj12EE5_zeroEPd11725184
_ZN4PLMD12LoopUnrollerILj4EE4_dotEPKdS3_12203712
_ZN4PLMD12LoopUnrollerILj5EE4_subEPdPKd49150794
_ZN4PLMD12LoopUnrollerILj6EE4_subEPdPKd49150794
_ZN4PLMD12LoopUnrollerILj7EE4_subEPdPKd49150794
_ZN4PLMD12LoopUnrollerILj8EE4_subEPdPKd49150794
_ZN4PLMD12LoopUnrollerILj9EE4_subEPdPKd49150794
_ZN4PLMD12LoopUnrollerILj4EE4_subEPdPKd50269896
_ZN4PLMD12LoopUnrollerILj4EE4_addEPdPKd54927498
_ZN4PLMD12LoopUnrollerILj5EE4_addEPdPKd54927498
_ZN4PLMD12LoopUnrollerILj6EE4_addEPdPKd54927498
_ZN4PLMD12LoopUnrollerILj7EE4_addEPdPKd54927498
_ZN4PLMD12LoopUnrollerILj8EE4_addEPdPKd54927498
_ZN4PLMD12LoopUnrollerILj9EE4_addEPdPKd54927498
_ZN4PLMD12LoopUnrollerILj7EE5_zeroEPd58145638
_ZN4PLMD12LoopUnrollerILj8EE5_zeroEPd58145642
_ZN4PLMD12LoopUnrollerILj9EE5_zeroEPd58145642
_ZN4PLMD12LoopUnrollerILj5EE5_zeroEPd58149642
_ZN4PLMD12LoopUnrollerILj6EE5_zeroEPd58149642
_ZN4PLMD12LoopUnrollerILj4EE5_zeroEPd72748004
_ZN4PLMD12LoopUnrollerILj4EE4_mulEPdd79564663
_ZN4PLMD12LoopUnrollerILj5EE4_mulEPdd79564663
_ZN4PLMD12LoopUnrollerILj6EE4_mulEPdd79564663
_ZN4PLMD12LoopUnrollerILj7EE4_mulEPdd79564663
_ZN4PLMD12LoopUnrollerILj8EE4_mulEPdd79564663
_ZN4PLMD12LoopUnrollerILj9EE4_mulEPdd79564663
_ZN4PLMD12LoopUnrollerILj2EE4_negEPdPKd206692156
_ZN4PLMD12LoopUnrollerILj3EE4_negEPdPKd206692156
_ZN4PLMD12LoopUnrollerILj2EE4_dotEPKdS3_263181135
_ZN4PLMD12LoopUnrollerILj3EE4_dotEPKdS3_263181135
_ZN4PLMD12LoopUnrollerILj2EE5_zeroEPd720969700
_ZN4PLMD12LoopUnrollerILj3EE5_zeroEPd720969700
_ZN4PLMD12LoopUnrollerILj2EE5_sum2EPKd1063823658
_ZN4PLMD12LoopUnrollerILj3EE5_sum2EPKd1063823658
_ZN4PLMD12LoopUnrollerILj2EE4_subEPdPKd1688487345
_ZN4PLMD12LoopUnrollerILj3EE4_subEPdPKd1688487345
_ZN4PLMD12LoopUnrollerILj2EE4_addEPdPKd1776169815
_ZN4PLMD12LoopUnrollerILj3EE4_addEPdPKd1776169815
_ZN4PLMD12LoopUnrollerILj2EE4_mulEPdd2236722808
_ZN4PLMD12LoopUnrollerILj3EE4_mulEPdd2236722808
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/LoopUnroller.h.func.html b/coverage/tools/LoopUnroller.h.func.html new file mode 100644 index 000000000000..9a8d84c010e8 --- /dev/null +++ b/coverage/tools/LoopUnroller.h.func.html @@ -0,0 +1,285 @@ + + + + + + + + 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-04-19 12:12:35Functions:5353100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12LoopUnrollerILj10EE5_zeroEPd11725184
_ZN4PLMD12LoopUnrollerILj11EE5_zeroEPd11725184
_ZN4PLMD12LoopUnrollerILj12EE5_zeroEPd11725184
_ZN4PLMD12LoopUnrollerILj13EE5_zeroEPd1471790
_ZN4PLMD12LoopUnrollerILj14EE5_zeroEPd1471790
_ZN4PLMD12LoopUnrollerILj15EE5_zeroEPd1471790
_ZN4PLMD12LoopUnrollerILj16EE5_zeroEPd1471790
_ZN4PLMD12LoopUnrollerILj2EE4_addEPdPKd1776169815
_ZN4PLMD12LoopUnrollerILj2EE4_dotEPKdS3_263181135
_ZN4PLMD12LoopUnrollerILj2EE4_mulEPdd2236722808
_ZN4PLMD12LoopUnrollerILj2EE4_negEPdPKd206692156
_ZN4PLMD12LoopUnrollerILj2EE4_subEPdPKd1688487345
_ZN4PLMD12LoopUnrollerILj2EE5_sum2EPKd1063823658
_ZN4PLMD12LoopUnrollerILj2EE5_zeroEPd720969700
_ZN4PLMD12LoopUnrollerILj3EE4_addEPdPKd1776169815
_ZN4PLMD12LoopUnrollerILj3EE4_dotEPKdS3_263181135
_ZN4PLMD12LoopUnrollerILj3EE4_mulEPdd2236722808
_ZN4PLMD12LoopUnrollerILj3EE4_negEPdPKd206692156
_ZN4PLMD12LoopUnrollerILj3EE4_subEPdPKd1688487345
_ZN4PLMD12LoopUnrollerILj3EE5_sum2EPKd1063823658
_ZN4PLMD12LoopUnrollerILj3EE5_zeroEPd720969700
_ZN4PLMD12LoopUnrollerILj4EE4_addEPdPKd54927498
_ZN4PLMD12LoopUnrollerILj4EE4_dotEPKdS3_12203712
_ZN4PLMD12LoopUnrollerILj4EE4_mulEPdd79564663
_ZN4PLMD12LoopUnrollerILj4EE4_negEPdPKd250599
_ZN4PLMD12LoopUnrollerILj4EE4_subEPdPKd50269896
_ZN4PLMD12LoopUnrollerILj4EE5_sum2EPKd1119102
_ZN4PLMD12LoopUnrollerILj4EE5_zeroEPd72748004
_ZN4PLMD12LoopUnrollerILj5EE4_addEPdPKd54927498
_ZN4PLMD12LoopUnrollerILj5EE4_mulEPdd79564663
_ZN4PLMD12LoopUnrollerILj5EE4_negEPdPKd250599
_ZN4PLMD12LoopUnrollerILj5EE4_subEPdPKd49150794
_ZN4PLMD12LoopUnrollerILj5EE5_zeroEPd58149642
_ZN4PLMD12LoopUnrollerILj6EE4_addEPdPKd54927498
_ZN4PLMD12LoopUnrollerILj6EE4_mulEPdd79564663
_ZN4PLMD12LoopUnrollerILj6EE4_negEPdPKd250599
_ZN4PLMD12LoopUnrollerILj6EE4_subEPdPKd49150794
_ZN4PLMD12LoopUnrollerILj6EE5_zeroEPd58149642
_ZN4PLMD12LoopUnrollerILj7EE4_addEPdPKd54927498
_ZN4PLMD12LoopUnrollerILj7EE4_mulEPdd79564663
_ZN4PLMD12LoopUnrollerILj7EE4_negEPdPKd250599
_ZN4PLMD12LoopUnrollerILj7EE4_subEPdPKd49150794
_ZN4PLMD12LoopUnrollerILj7EE5_zeroEPd58145638
_ZN4PLMD12LoopUnrollerILj8EE4_addEPdPKd54927498
_ZN4PLMD12LoopUnrollerILj8EE4_mulEPdd79564663
_ZN4PLMD12LoopUnrollerILj8EE4_negEPdPKd250599
_ZN4PLMD12LoopUnrollerILj8EE4_subEPdPKd49150794
_ZN4PLMD12LoopUnrollerILj8EE5_zeroEPd58145642
_ZN4PLMD12LoopUnrollerILj9EE4_addEPdPKd54927498
_ZN4PLMD12LoopUnrollerILj9EE4_mulEPdd79564663
_ZN4PLMD12LoopUnrollerILj9EE4_negEPdPKd250599
_ZN4PLMD12LoopUnrollerILj9EE4_subEPdPKd49150794
_ZN4PLMD12LoopUnrollerILj9EE5_zeroEPd58145642
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/LoopUnroller.h.gcov.html b/coverage/tools/LoopUnroller.h.gcov.html new file mode 100644 index 000000000000..1193ffc109d8 --- /dev/null +++ b/coverage/tools/LoopUnroller.h.gcov.html @@ -0,0 +1,237 @@ + + + + + + + + LCOV - plumed test coverage - tools/LoopUnroller.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - LoopUnroller.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3131100.0 %
Date:2024-04-19 12:12:35Functions:5353100.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  1846486322 : void LoopUnroller<n>::_zero(double*d) {
+      78  1125516622 :   LoopUnroller<n-1>::_zero(d);
+      79  1846486322 :   d[n-1]=0.0;
+      80  1846486322 : }
+      81             : 
+      82             : template<>
+      83             : inline
+      84             : void LoopUnroller<1>::_zero(double*d) {
+      85   721516026 :   d[0]=0.0;
+      86             : }
+      87             : 
+      88             : template<unsigned n>
+      89  3881904618 : void LoopUnroller<n>::_add(double*d,const double*a) {
+      90  2105734803 :   LoopUnroller<n-1>::_add(d,a);
+      91  3881904618 :   d[n-1]+=a[n-1];
+      92  3881904618 : }
+      93             : 
+      94             : template<>
+      95             : inline
+      96             : void LoopUnroller<1>::_add(double*d,const double*a) {
+      97  1776169815 :   d[0]+=a[0];
+      98             : }
+      99             : 
+     100             : template<unsigned n>
+     101  3672998556 : void LoopUnroller<n>::_sub(double*d,const double*a) {
+     102  1984511211 :   LoopUnroller<n-1>::_sub(d,a);
+     103  3672998556 :   d[n-1]-=a[n-1];
+     104  3672998556 : }
+     105             : 
+     106             : template<>
+     107             : inline
+     108             : void LoopUnroller<1>::_sub(double*d,const double*a) {
+     109  1688487345 :   d[0]-=a[0];
+     110             : }
+     111             : 
+     112             : template<unsigned n>
+     113  4950833594 : void LoopUnroller<n>::_mul(double*d,const double s) {
+     114  2714110786 :   LoopUnroller<n-1>::_mul(d,s);
+     115  4950833594 :   d[n-1]*=s;
+     116  4950833594 : }
+     117             : 
+     118             : template<>
+     119             : inline
+     120             : void LoopUnroller<1>::_mul(double*d,const double s) {
+     121  2236722808 :   d[0]*=s;
+     122             : }
+     123             : 
+     124             : template<unsigned n>
+     125   414887906 : void LoopUnroller<n>::_neg(double*d,const double*a ) {
+     126   208195750 :   LoopUnroller<n-1>::_neg(d,a);
+     127   414887906 :   d[n-1]=-a[n-1];
+     128   414887906 : }
+     129             : 
+     130             : template<>
+     131             : inline
+     132             : void LoopUnroller<1>::_neg(double*d,const double*a) {
+     133   206692156 :   d[0]=-a[0];
+     134             : }
+     135             : 
+     136             : template<unsigned n>
+     137  2128766418 : double LoopUnroller<n>::_sum2(const double*d) {
+     138  2128766418 :   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  1063823658 :   return d[0]*d[0];
+     145             : }
+     146             : 
+     147             : template<unsigned n>
+     148   538565982 : double LoopUnroller<n>::_dot(const double*d,const double*v) {
+     149   538565982 :   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   263181135 :   return d[0]*v[0];
+     156             : }
+     157             : 
+     158             : }
+     159             : 
+     160             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Matrix.h.func-sort-c.html b/coverage/tools/Matrix.h.func-sort-c.html new file mode 100644 index 000000000000..b0cdd80618ec --- /dev/null +++ b/coverage/tools/Matrix.h.func-sort-c.html @@ -0,0 +1,109 @@ + + + + + + + + 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:11713586.7 %
Date:2024-04-19 12:12:35Functions:8988.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6logdetIdEEiRKNS_6MatrixIT_EERd0
_ZN4PLMD12pseudoInvertIdEEiRKNS_6MatrixIT_EERNS1_IdEE1
_ZN4PLMD6MatrixIdEmLERKd100
_ZN4PLMD8choleskyIdEEvRKNS_6MatrixIT_EERS3_446
_ZN4PLMD4multIdEEvRKNS_6MatrixIT_EES5_RS3_13590
_ZN4PLMD7diagMatIdEEiRKNS_6MatrixIT_EERSt6vectorIdSaIdEERNS1_IdEE14055
_ZN4PLMD4multIdEEvRKNS_6MatrixIT_EERKSt6vectorIS2_SaIS2_EERS8_18594
_ZN4PLMD6InvertIdEEiRKNS_6MatrixIT_EERNS1_IdEE25702
_ZNK4PLMD6MatrixIdE11isSymmetricEv40203
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Matrix.h.func.html b/coverage/tools/Matrix.h.func.html new file mode 100644 index 000000000000..1d63ecf4c218 --- /dev/null +++ b/coverage/tools/Matrix.h.func.html @@ -0,0 +1,109 @@ + + + + + + + + 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:11713586.7 %
Date:2024-04-19 12:12:35Functions:8988.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12pseudoInvertIdEEiRKNS_6MatrixIT_EERNS1_IdEE1
_ZN4PLMD4multIdEEvRKNS_6MatrixIT_EERKSt6vectorIS2_SaIS2_EERS8_18594
_ZN4PLMD4multIdEEvRKNS_6MatrixIT_EES5_RS3_13590
_ZN4PLMD6InvertIdEEiRKNS_6MatrixIT_EERNS1_IdEE25702
_ZN4PLMD6MatrixIdEmLERKd100
_ZN4PLMD6logdetIdEEiRKNS_6MatrixIT_EERd0
_ZN4PLMD7diagMatIdEEiRKNS_6MatrixIT_EERSt6vectorIdSaIdEERNS1_IdEE14055
_ZN4PLMD8choleskyIdEEvRKNS_6MatrixIT_EERS3_446
_ZNK4PLMD6MatrixIdE11isSymmetricEv40203
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Matrix.h.gcov.html b/coverage/tools/Matrix.h.gcov.html new file mode 100644 index 000000000000..5481052923e4 --- /dev/null +++ b/coverage/tools/Matrix.h.gcov.html @@ -0,0 +1,491 @@ + + + + + + + + LCOV - plumed test coverage - tools/Matrix.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Matrix.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11713586.7 %
Date:2024-04-19 12:12:35Functions: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_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    36819138 : 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    36815792 :   explicit Matrix(const unsigned nr=0, const unsigned nc=0 )  : sz(nr*nc), rw(nr), cl(nc), data(nr*nc) {}
+      91         247 :   Matrix(const Matrix<T>& t) : sz(t.sz), rw(t.rw), cl(t.cl), data(t.data) {}
+      92             :   /// Resize the matrix
+      93         138 :   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     3018313 :   inline unsigned nrows() const { return rw; }
+      96             :   /// Return the number of columns
+      97    11457512 :   inline unsigned ncols() const { return cl; }
+      98             :   /// Return the contents of the matrix as a vector of length rw*cl
+      99             :   inline std::vector<T>& getVector() { return data; }
+     100             :   /// Set the matrix from a vector input
+     101             :   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  2013865279 :   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   660313313 :   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     4713018 :     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       56904 :     sz=m.sz;
+     114       56904 :     rw=m.rw;
+     115       56904 :     cl=m.cl;
+     116       56904 :     data=m.data;
+     117       56904 :     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         100 :   Matrix<T> operator*=(const T& v) {
+     132       53288 :     for(unsigned i=0; i<sz; ++i) { data[i]*=v; }
+     133         100 :     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       40203 :   unsigned isSymmetric() const {
+     154       40203 :     if (rw!=cl) { return 0; }
+     155             :     unsigned sym=1;
+     156      291278 :     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             : template <typename T> Matrix<T> operator*(T& v, const Matrix<T>& m ) {
+     163             :   Matrix<T> new_m(m);
+     164             :   new_m*=v;
+     165             :   return new_m;
+     166             : }
+     167             : 
+     168       13590 : template <typename T> void mult( const Matrix<T>& A, const Matrix<T>& B, Matrix<T>& C ) {
+     169       13590 :   plumed_assert(A.cl==B.rw);
+     170       13590 :   if( A.rw !=C.rw  || B.cl !=C.cl ) { C.resize( A.rw, B.cl ); } C=static_cast<T>( 0 );
+     171  2011229279 :   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       13590 : }
+     173             : 
+     174       18594 : template <typename T> void mult( const Matrix<T>& A, const std::vector<T>& B, std::vector<T>& C) {
+     175       18594 :   plumed_assert( A.cl==B.size() );
+     176       18594 :   if( C.size()!=A.rw  ) { C.resize(A.rw); }
+     177       86682 :   for(unsigned i=0; i<A.rw; ++i) { C[i]= static_cast<T>( 0 ); }
+     178      796630 :   for(unsigned i=0; i<A.rw; ++i) for(unsigned k=0; k<A.cl; ++k) C[i]+=A(i,k)*B[k] ;
+     179       18594 : }
+     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       14055 : 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       14055 :   plumed_assert( A.rw==A.cl ); plumed_assert( A.isSymmetric()==1 );
+     210       14055 :   std::vector<double> da(A.sz);
+     211             :   unsigned k=0;
+     212       14055 :   std::vector<double> evals(A.cl);
+     213             :   // Transfer the matrix to the local array
+     214      475053 :   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       14055 :   int n=A.cl; int lwork=-1, liwork=-1, m, info, one=1;
+     217       14055 :   std::vector<double> work(A.cl);
+     218       14055 :   std::vector<int> iwork(A.cl);
+     219       14055 :   double vl, vu, abstol=0.0;
+     220       14055 :   std::vector<int> isup(2*A.cl);
+     221       14055 :   std::vector<double> evecs(A.sz);
+     222             : 
+     223       14055 :   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       14055 :   if (info!=0) return info;
+     227             : 
+     228             :   // Retrieve correct sizes for work and iwork then reallocate
+     229       14055 :   liwork=iwork[0]; iwork.resize(liwork);
+     230       14055 :   lwork=static_cast<int>( work[0] ); work.resize(lwork);
+     231             : 
+     232       14055 :   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       14055 :   if (info!=0) return info;
+     236             : 
+     237       14055 :   if( eigenvals.size()!=A.cl ) { eigenvals.resize( A.cl ); }
+     238       14055 :   if( eigenvecs.rw!=A.rw || eigenvecs.cl!=A.cl ) { eigenvecs.resize( A.rw, A.cl ); }
+     239             :   k=0;
+     240       43814 :   for(unsigned i=0; i<A.cl; ++i) {
+     241       29759 :     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      460998 :     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       43814 :   for(int i=0; i<n; ++i) {
+     253             :     int j;
+     254       30984 :     for(j=0; j<n; j++) if(eigenvecs(i,j)*eigenvecs(i,j)>1e-14) break;
+     255      217054 :     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       25702 : template <typename T> int Invert( const Matrix<T>& A, Matrix<double>& inverse ) {
+     308             : 
+     309       25702 :   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        9191 :     std::vector<double> eval(A.rw); Matrix<double> evec(A.rw,A.cl), tevec(A.rw,A.cl);
+     314        9191 :     int err; err=diagMat( A, eval, evec );
+     315        9191 :     if(err!=0) return err;
+     316       63179 :     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        9191 :     mult(tevec,evec,inverse);
+     318             :   } else {
+     319       16511 :     std::vector<double> da(A.sz);
+     320       16511 :     std::vector<int> ipiv(A.cl);
+     321       16511 :     unsigned k=0; int n=A.rw, info;
+     322      115601 :     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       16511 :     plumed_lapack_dgetrf(&n,&n,da.data(),&n,ipiv.data(),&info);
+     325       16511 :     if(info!=0) return info;
+     326             : 
+     327       16511 :     int lwork=-1;
+     328       16511 :     std::vector<double> work(A.cl);
+     329       16511 :     plumed_lapack_dgetri(&n,da.data(),&n,ipiv.data(),work.data(),&lwork,&info);
+     330       16511 :     if(info!=0) return info;
+     331             : 
+     332       16511 :     lwork=static_cast<int>( work[0] ); work.resize(lwork);
+     333       16511 :     plumed_lapack_dgetri(&n,da.data(),&n,ipiv.data(),work.data(),&lwork,&info);
+     334       16511 :     if(info!=0) return info;
+     335             : 
+     336       16511 :     if( inverse.cl!=A.cl || inverse.rw!=A.rw ) { inverse.resize(A.rw,A.cl); }
+     337      115601 :     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           0 : template <typename T> int logdet( const Matrix<T>& M, double& ldet ) {
+     376             :   // Check matrix is square and symmetric
+     377           0 :   plumed_assert( M.rw==M.cl || M.isSymmetric() );
+     378             : 
+     379           0 :   std::vector<double> da(M.sz);
+     380             :   unsigned k=0;
+     381           0 :   std::vector<double> evals(M.cl);
+     382             :   // Transfer the matrix to the local array
+     383           0 :   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           0 :   int n=M.cl; int lwork=-1, liwork=-1, info, m, one=1;
+     386           0 :   std::vector<double> work(M.rw);
+     387           0 :   std::vector<int> iwork(M.rw);
+     388           0 :   double vl, vu, abstol=0.0;
+     389           0 :   std::vector<int> isup(2*M.rw);
+     390           0 :   std::vector<double> evecs(M.sz);
+     391           0 :   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           0 :   if (info!=0) return info;
+     395             : 
+     396             :   // Retrieve correct sizes for work and iwork then reallocate
+     397           0 :   lwork=static_cast<int>( work[0] ); work.resize(lwork);
+     398           0 :   liwork=iwork[0]; iwork.resize(liwork);
+     399             : 
+     400           0 :   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           0 :   if (info!=0) return info;
+     404             : 
+     405             :   // Transfer the eigenvalues and eigenvectors to the output
+     406           0 :   ldet=0; for(unsigned i=0; i<M.cl; i++) { ldet+=log(evals[i]); }
+     407             : 
+     408             :   return 0;
+     409             : }
+     410             : 
+     411             : 
+     412             : 
+     413             : }
+     414             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/MatrixSquareBracketsAccess.h.func-sort-c.html b/coverage/tools/MatrixSquareBracketsAccess.h.func-sort-c.html new file mode 100644 index 000000000000..62be9bb3677b --- /dev/null +++ b/coverage/tools/MatrixSquareBracketsAccess.h.func-sort-c.html @@ -0,0 +1,145 @@ + + + + + + + + LCOV - plumed test coverage - tools/MatrixSquareBracketsAccess.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - MatrixSquareBracketsAccess.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1212100.0 %
Date:2024-04-19 12:12:35Functions:1818100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD26MatrixSquareBracketsAccessINS_6MatrixIdEEdjjE3RowC2ERS3_j30474
_ZN4PLMD26MatrixSquareBracketsAccessINS_6MatrixIdEEdjjE3RowixEj30474
_ZN4PLMD26MatrixSquareBracketsAccessINS_6MatrixIdEEdjjEixEj30474
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj1ELj4EEEdjjE3RowC2ERS3_j2731630
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj1ELj4EEEdjjE3RowixEj2731630
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj1ELj4EEEdjjEixEj2731630
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj3ELj3EEEdjjE9Const_rowC2ERKS3_j3523191
_ZNK4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj3ELj3EEEdjjE9Const_rowixEj3523191
_ZNK4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj3ELj3EEEdjjEixEj3523191
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj3ELj3EEEdjjE3RowC2ERS3_j35426484
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj3ELj3EEEdjjE3RowixEj35426484
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj3ELj3EEEdjjEixEj35426484
_ZN4PLMD26MatrixSquareBracketsAccessINS_6MatrixISt6vectorINS_13VectorGenericILj3EEESaIS4_EEEES6_jjE3RowC2ERS8_j41729715
_ZN4PLMD26MatrixSquareBracketsAccessINS_6MatrixISt6vectorINS_13VectorGenericILj3EEESaIS4_EEEES6_jjE3RowixEj41729715
_ZN4PLMD26MatrixSquareBracketsAccessINS_6MatrixISt6vectorINS_13VectorGenericILj3EEESaIS4_EEEES6_jjEixEj41729715
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj4ELj4EEEdjjE3RowC2ERS3_j48062578
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj4ELj4EEEdjjE3RowixEj48062578
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj4ELj4EEEdjjEixEj48062578
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/MatrixSquareBracketsAccess.h.func.html b/coverage/tools/MatrixSquareBracketsAccess.h.func.html new file mode 100644 index 000000000000..b32ce6c7e094 --- /dev/null +++ b/coverage/tools/MatrixSquareBracketsAccess.h.func.html @@ -0,0 +1,145 @@ + + + + + + + + LCOV - plumed test coverage - tools/MatrixSquareBracketsAccess.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - MatrixSquareBracketsAccess.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1212100.0 %
Date:2024-04-19 12:12:35Functions:1818100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj1ELj4EEEdjjE3RowC2ERS3_j2731630
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj1ELj4EEEdjjE3RowixEj2731630
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj1ELj4EEEdjjEixEj2731630
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj3ELj3EEEdjjE3RowC2ERS3_j35426484
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj3ELj3EEEdjjE3RowixEj35426484
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj3ELj3EEEdjjE9Const_rowC2ERKS3_j3523191
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj3ELj3EEEdjjEixEj35426484
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj4ELj4EEEdjjE3RowC2ERS3_j48062578
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj4ELj4EEEdjjE3RowixEj48062578
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj4ELj4EEEdjjEixEj48062578
_ZN4PLMD26MatrixSquareBracketsAccessINS_6MatrixISt6vectorINS_13VectorGenericILj3EEESaIS4_EEEES6_jjE3RowC2ERS8_j41729715
_ZN4PLMD26MatrixSquareBracketsAccessINS_6MatrixISt6vectorINS_13VectorGenericILj3EEESaIS4_EEEES6_jjE3RowixEj41729715
_ZN4PLMD26MatrixSquareBracketsAccessINS_6MatrixISt6vectorINS_13VectorGenericILj3EEESaIS4_EEEES6_jjEixEj41729715
_ZN4PLMD26MatrixSquareBracketsAccessINS_6MatrixIdEEdjjE3RowC2ERS3_j30474
_ZN4PLMD26MatrixSquareBracketsAccessINS_6MatrixIdEEdjjE3RowixEj30474
_ZN4PLMD26MatrixSquareBracketsAccessINS_6MatrixIdEEdjjEixEj30474
_ZNK4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj3ELj3EEEdjjE9Const_rowixEj3523191
_ZNK4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj3ELj3EEEdjjEixEj3523191
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/MatrixSquareBracketsAccess.h.gcov.html b/coverage/tools/MatrixSquareBracketsAccess.h.gcov.html new file mode 100644 index 000000000000..b301a3031ed4 --- /dev/null +++ b/coverage/tools/MatrixSquareBracketsAccess.h.gcov.html @@ -0,0 +1,215 @@ + + + + + + + + LCOV - plumed test coverage - tools/MatrixSquareBracketsAccess.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - MatrixSquareBracketsAccess.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1212100.0 %
Date:2024-04-19 12:12:35Functions: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     3523191 : MatrixSquareBracketsAccess<T,C,I,J>::Const_row::Const_row(const MatrixSquareBracketsAccess&t,I i):
+     101     3523191 :   t(t),i(i) {}
+     102             : 
+     103             : template<class T,class C,class I,class J>
+     104   127980881 : MatrixSquareBracketsAccess<T,C,I,J>::Row::Row(MatrixSquareBracketsAccess&t,I i):
+     105   127980881 :   t(t),i(i) {}
+     106             : 
+     107             : template<class T,class C,class I,class J>
+     108     3523191 : 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     3523191 :   return (*static_cast<const T*>(&t))(i,j);
+     113             : }
+     114             : 
+     115             : template<class T,class C,class I,class J>
+     116   127980881 : 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   127980881 :   return (*static_cast<T*>(&t))(i,j);
+     121             : }
+     122             : 
+     123             : template<class T,class C,class I,class J>
+     124   127980881 : typename MatrixSquareBracketsAccess<T,C,I,J>::Row MatrixSquareBracketsAccess<T,C,I,J>::operator[] (I i) {
+     125   127980881 :   return Row(*this,i);
+     126             : }
+     127             : 
+     128             : template<class T,class C,class I,class J>
+     129     3523191 : typename MatrixSquareBracketsAccess<T,C,I,J>::Const_row MatrixSquareBracketsAccess<T,C,I,J>::operator[] (I i)const {
+     130     3523191 :   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/MergeVectorTools.h.func-sort-c.html b/coverage/tools/MergeVectorTools.h.func-sort-c.html new file mode 100644 index 000000000000..73e68ffd6508 --- /dev/null +++ b/coverage/tools/MergeVectorTools.h.func-sort-c.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - tools/MergeVectorTools.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - MergeVectorTools.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2525100.0 %
Date:2024-04-19 12:12:35Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD16mergeVectorTools18mergeSortedVectorsINS_3gch12small_vectorIPKSt6vectorINS_10AtomNumberESaIS5_EELj32ESaIS9_EEES5_EENSt9enable_ifIXsrNS0_17has_size_and_dataIT_vEE5valueEvE4typeERSE_RS4_IT0_SaISJ_EE49613
_ZN4PLMD16mergeVectorToolsL18mergeSortedVectorsISt6vectorINS_10AtomNumberESaIS3_EEEEvPKPKT_mRS2_INS6_10value_typeESaISB_EE49613
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/MergeVectorTools.h.func.html b/coverage/tools/MergeVectorTools.h.func.html new file mode 100644 index 000000000000..76a275977993 --- /dev/null +++ b/coverage/tools/MergeVectorTools.h.func.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - tools/MergeVectorTools.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - MergeVectorTools.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2525100.0 %
Date:2024-04-19 12:12:35Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD16mergeVectorTools18mergeSortedVectorsINS_3gch12small_vectorIPKSt6vectorINS_10AtomNumberESaIS5_EELj32ESaIS9_EEES5_EENSt9enable_ifIXsrNS0_17has_size_and_dataIT_vEE5valueEvE4typeERSE_RS4_IT0_SaISJ_EE49613
_ZN4PLMD16mergeVectorToolsL18mergeSortedVectorsISt6vectorINS_10AtomNumberESaIS3_EEEEvPKPKT_mRS2_INS6_10value_typeESaISB_EE49613
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/MergeVectorTools.h.gcov.html b/coverage/tools/MergeVectorTools.h.gcov.html new file mode 100644 index 000000000000..977ea0079a43 --- /dev/null +++ b/coverage/tools/MergeVectorTools.h.gcov.html @@ -0,0 +1,211 @@ + + + + + + + + LCOV - plumed test coverage - tools/MergeVectorTools.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - MergeVectorTools.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2525100.0 %
Date:2024-04-19 12:12:35Functions: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_MergeVectorTools_h
+      23             : #define __PLUMED_tools_MergeVectorTools_h
+      24             : 
+      25             : #include "small_vector/small_vector.h"
+      26             : #include <vector>
+      27             : #include <algorithm>
+      28             : #include <type_traits>
+      29             : 
+      30             : namespace PLMD {
+      31             : 
+      32             : namespace mergeVectorTools {
+      33             : 
+      34             : /// Merge sorted vectors.
+      35             : /// Takes a vector of pointers to containers and merge them.
+      36             : /// Containers should be already sorted.
+      37             : /// The content is appended to the result vector.
+      38             : /// Optionally, uses a priority_queue implementation.
+      39             : template<class C>
+      40       49613 : static void mergeSortedVectors(const C* const* vecs, std::size_t size, std::vector<typename C::value_type> & result) {
+      41             : 
+      42             :   /// local class storing the range of remaining objects to be pushed
+      43             :   class Entry
+      44             :   {
+      45             :     typename C::const_iterator fwdIt,endIt;
+      46             : 
+      47             :   public:
+      48      135205 :     explicit Entry(C const& v) : fwdIt(v.begin()), endIt(v.end()) {}
+      49             :     /// check if this vector still contains something to be pushed
+      50             :     bool empty() const { return fwdIt == endIt; }
+      51             :     /// to allow using a priority_queu, which selects the highest element.
+      52             :     /// we here (counterintuitively) define < as >
+      53             :     bool operator< (Entry const& rhs) const { return top() > rhs.top(); }
+      54             :     const auto & top() const { return *fwdIt; }
+      55             :     void next() { ++fwdIt;};
+      56             :   };
+      57             : 
+      58             :   // preprocessing
+      59             :   {
+      60       49613 :     std::size_t maxsize=0;
+      61      189566 :     for(unsigned i=0; i<size; i++) {
+      62             :       // find the largest
+      63      190562 :       maxsize=std::max(maxsize,vecs[i]->size());
+      64             :     }
+      65             :     // this is just to decrease the number of reallocations on push_back
+      66       49613 :     result.reserve(maxsize);
+      67             :     // if vectors are empty we are done
+      68       49613 :     if(maxsize==0) return;
+      69             :   }
+      70             : 
+      71             :   // start
+      72             :   // heap containing the ranges to be pushed
+      73             :   // avoid allocations when it's small
+      74             :   gch::small_vector<Entry,32> heap;
+      75             : 
+      76             :   {
+      77      184821 :     for(unsigned i=0; i<size; i++) {
+      78      138252 :       if(!vecs[i]->empty()) {
+      79             :         // add entry at the end of the array
+      80      135205 :         heap.emplace_back(Entry(*vecs[i]));
+      81             :       }
+      82             :     }
+      83             :     // make a sorted heap
+      84       46569 :     std::make_heap(std::begin(heap),std::end(heap));
+      85             :   }
+      86             : 
+      87             :   // first iteration, to avoid an extra "if" in main iteration
+      88             :   // explanations are below
+      89             :   {
+      90       46569 :     std::pop_heap(std::begin(heap), std::end(heap));
+      91             :     auto & tmp=heap.back();
+      92       46569 :     const auto val=tmp.top();
+      93             :     // here, we append inconditionally
+      94       46569 :     result.push_back(val);
+      95             :     tmp.next();
+      96       46569 :     if(tmp.empty()) heap.pop_back();
+      97       44024 :     else std::push_heap(std::begin(heap), std::end(heap));
+      98             :   }
+      99             : 
+     100     2476375 :   while(!heap.empty()) {
+     101             :     // move entry with the smallest element to the back of the array
+     102     2429806 :     std::pop_heap(std::begin(heap), std::end(heap));
+     103             :     // entry
+     104             :     auto & tmp=heap.back();
+     105             :     // element
+     106     2429806 :     const auto val=tmp.top();
+     107             :     // if the element is larger than the current largest element,
+     108             :     // push it to result
+     109     2429806 :     if(val > result.back()) result.push_back(val);
+     110             :     // move forward the used entry
+     111             :     tmp.next();
+     112             :     // if this entry is exhausted, remove it from the array
+     113     2429806 :     if(tmp.empty()) heap.pop_back();
+     114             :     // otherwise, sort again the array
+     115     2297146 :     else std::push_heap(std::begin(heap), std::end(heap));
+     116             :   }
+     117             : }
+     118             : 
+     119             : template<typename T, typename = void>
+     120             : struct has_size_and_data : std::false_type {};
+     121             : 
+     122             : template<typename T>
+     123             : struct has_size_and_data<T, std::void_t<decltype(std::declval<T>().size()), decltype(std::declval<T>().data())>> : std::true_type {};
+     124             : 
+     125             : template<class C, class D>
+     126       49613 : auto mergeSortedVectors(C& vecs, std::vector<D> & result) -> typename std::enable_if<has_size_and_data<C>::value, void>::type {
+     127       49613 :   mergeSortedVectors(vecs.data(),vecs.size(),result);
+     128       49613 : }
+     129             : 
+     130             : }
+     131             : }
+     132             : 
+     133             : #endif
+     134             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Minimise1DBrent.h.func-sort-c.html b/coverage/tools/Minimise1DBrent.h.func-sort-c.html new file mode 100644 index 000000000000..bde5bc8f5628 --- /dev/null +++ b/coverage/tools/Minimise1DBrent.h.func-sort-c.html @@ -0,0 +1,121 @@ + + + + + + + + LCOV - plumed test coverage - tools/Minimise1DBrent.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Minimise1DBrent.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:828398.8 %
Date:2024-04-19 12:12:35Functions:1212100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15Minimise1DBrentINS_5F1dimINS_9gridtools15FindGridOptimumEEEE7bracketERKdS7_MS4_FdS7_E10
_ZN4PLMD15Minimise1DBrentINS_5F1dimINS_9gridtools15FindGridOptimumEEEE8minimiseEMS4_FdRKdE10
_ZN4PLMD15Minimise1DBrentINS_5F1dimINS_9gridtools15FindGridOptimumEEEEC2ERKS4_RKd10
_ZNK4PLMD15Minimise1DBrentINS_5F1dimINS_9gridtools15FindGridOptimumEEEE15getMinimumValueEv10
_ZN4PLMD15Minimise1DBrentINS_5F1dimINS_6dimred13ArrangePointsEEEE7bracketERKdS7_MS4_FdS7_E84
_ZN4PLMD15Minimise1DBrentINS_5F1dimINS_6dimred13ArrangePointsEEEE8minimiseEMS4_FdRKdE84
_ZN4PLMD15Minimise1DBrentINS_5F1dimINS_6dimred13ArrangePointsEEEEC2ERKS4_RKd84
_ZNK4PLMD15Minimise1DBrentINS_5F1dimINS_6dimred13ArrangePointsEEEE15getMinimumValueEv84
_ZN4PLMD15Minimise1DBrentINS_5F1dimINS_6dimred13ProjectPointsEEEE7bracketERKdS7_MS4_FdS7_E1098
_ZN4PLMD15Minimise1DBrentINS_5F1dimINS_6dimred13ProjectPointsEEEE8minimiseEMS4_FdRKdE1098
_ZN4PLMD15Minimise1DBrentINS_5F1dimINS_6dimred13ProjectPointsEEEEC2ERKS4_RKd1098
_ZNK4PLMD15Minimise1DBrentINS_5F1dimINS_6dimred13ProjectPointsEEEE15getMinimumValueEv1098
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Minimise1DBrent.h.func.html b/coverage/tools/Minimise1DBrent.h.func.html new file mode 100644 index 000000000000..8aab4d773052 --- /dev/null +++ b/coverage/tools/Minimise1DBrent.h.func.html @@ -0,0 +1,121 @@ + + + + + + + + LCOV - plumed test coverage - tools/Minimise1DBrent.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Minimise1DBrent.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:828398.8 %
Date:2024-04-19 12:12:35Functions:1212100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15Minimise1DBrentINS_5F1dimINS_6dimred13ArrangePointsEEEE7bracketERKdS7_MS4_FdS7_E84
_ZN4PLMD15Minimise1DBrentINS_5F1dimINS_6dimred13ArrangePointsEEEE8minimiseEMS4_FdRKdE84
_ZN4PLMD15Minimise1DBrentINS_5F1dimINS_6dimred13ArrangePointsEEEEC2ERKS4_RKd84
_ZN4PLMD15Minimise1DBrentINS_5F1dimINS_6dimred13ProjectPointsEEEE7bracketERKdS7_MS4_FdS7_E1098
_ZN4PLMD15Minimise1DBrentINS_5F1dimINS_6dimred13ProjectPointsEEEE8minimiseEMS4_FdRKdE1098
_ZN4PLMD15Minimise1DBrentINS_5F1dimINS_6dimred13ProjectPointsEEEEC2ERKS4_RKd1098
_ZN4PLMD15Minimise1DBrentINS_5F1dimINS_9gridtools15FindGridOptimumEEEE7bracketERKdS7_MS4_FdS7_E10
_ZN4PLMD15Minimise1DBrentINS_5F1dimINS_9gridtools15FindGridOptimumEEEE8minimiseEMS4_FdRKdE10
_ZN4PLMD15Minimise1DBrentINS_5F1dimINS_9gridtools15FindGridOptimumEEEEC2ERKS4_RKd10
_ZNK4PLMD15Minimise1DBrentINS_5F1dimINS_6dimred13ArrangePointsEEEE15getMinimumValueEv84
_ZNK4PLMD15Minimise1DBrentINS_5F1dimINS_6dimred13ProjectPointsEEEE15getMinimumValueEv1098
_ZNK4PLMD15Minimise1DBrentINS_5F1dimINS_9gridtools15FindGridOptimumEEEE15getMinimumValueEv10
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Minimise1DBrent.h.gcov.html b/coverage/tools/Minimise1DBrent.h.gcov.html new file mode 100644 index 000000000000..2c4d0d5fd84e --- /dev/null +++ b/coverage/tools/Minimise1DBrent.h.gcov.html @@ -0,0 +1,272 @@ + + + + + + + + LCOV - plumed test coverage - tools/Minimise1DBrent.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Minimise1DBrent.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:828398.8 %
Date:2024-04-19 12:12:35Functions: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        1192 : 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        1192 :   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        1192 : Minimise1DBrent<FCLASS>::Minimise1DBrent( const FCLASS& pf, const double& t ):
+      74        1192 :   bracketed(false),
+      75        1192 :   minimised(false),
+      76        1192 :   tol(t),
+      77        1192 :   GOLD(1.618034),
+      78        1192 :   GLIMIT(100.0),
+      79        1192 :   TINY(1.0E-20),
+      80        1192 :   ITMAX(100),
+      81        1192 :   CGOLD(0.3819660),
+      82        1192 :   ZEPS(epsilon*1.0E-3),
+      83        1192 :   ax(0),bx(0),cx(0),
+      84        1192 :   fa(0),fb(0),fc(0),
+      85        1192 :   fmin(0),
+      86        1192 :   myclass_func(pf)
+      87             : {
+      88        1192 : }
+      89             : 
+      90             : template <class FCLASS>
+      91        1192 : void Minimise1DBrent<FCLASS>::bracket( const double& a, const double& b, eng_pointer eng ) {
+      92        1192 :   ax=a; bx=b; double fu;
+      93        1192 :   fa=(myclass_func.*eng)(ax); fb=(myclass_func.*eng)(bx);
+      94        1192 :   if( fb>fa ) {
+      95             :     double tmp;
+      96         155 :     tmp=ax; ax=bx; bx=tmp;
+      97         155 :     tmp=fa; fa=fb; fb=tmp;
+      98             :   }
+      99        1192 :   cx=bx+GOLD*(bx-ax);
+     100        1192 :   fc=(myclass_func.*eng)(cx);
+     101        2638 :   while ( fb > fc ) {
+     102        1521 :     double r=(bx-ax)*(fb-fc);
+     103        1521 :     double q=(bx-cx)*(fb-fa);
+     104        1521 :     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        1521 :     double ulim=bx+GLIMIT*(cx-bx);
+     106        1521 :     if((bx-u)*(u-cx) > 0.0 ) {
+     107         151 :       fu=(myclass_func.*eng)(u);
+     108         151 :       if( fu < fc ) {
+     109          75 :         ax=bx; bx=u; fa=fb; fb=fu; bracketed=true; return;
+     110          84 :       } else if( fu > fb ) {
+     111           8 :         cx=u; fc=fu; bracketed=true; return;
+     112             :       }
+     113          76 :       u=cx+GOLD*(cx-bx); fu=(myclass_func.*eng)(u);
+     114        1370 :     } else if((cx-u)*(u-ulim) > 0.0 ) {
+     115        1052 :       fu=(myclass_func.*eng)(u);
+     116        1052 :       if( fu<fc ) {
+     117        1041 :         bx=cx; cx=u; u+=GOLD*(u-bx);
+     118        1041 :         fb=fc; fc=fu; fu=(myclass_func.*eng)(u);
+     119             :       }
+     120         318 :     } else if( (u-ulim)*(ulim-cx) >= 0.0 ) {
+     121         283 :       u=ulim;
+     122         283 :       fu=(myclass_func.*eng)(u);
+     123             :     } else {
+     124          35 :       u=cx+GOLD*(cx-bx);
+     125          35 :       fu=(myclass_func.*eng)(u);
+     126             :     }
+     127        1446 :     ax=bx; bx=cx; cx=u;
+     128        1446 :     fa=fb; fb=fc; fc=fu;
+     129             :   }
+     130        1117 :   bracketed=true;
+     131             : }
+     132             : 
+     133             : template <class FCLASS>
+     134        1192 : 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        1192 :   a=(ax < cx ? ax : cx );
+     142        1192 :   b=(ax >= cx ? ax : cx );
+     143        1192 :   x=w=v=bx;
+     144        1192 :   fw=fv=fx=(myclass_func.*eng)(x);
+     145       18942 :   for(unsigned iter=0; iter<ITMAX; ++iter) {
+     146       18942 :     xm=0.5*(a+b);
+     147       18942 :     tol2=2.0*(tol1=tol*std::fabs(x)+ZEPS);
+     148       18942 :     if( std::fabs(x-xm) <= (tol2-0.5*(b-a))) {
+     149        1192 :       fmin=fx; minimised=true; return x;
+     150             :     }
+     151       17750 :     if( std::fabs(e) > tol1 ) {
+     152       16377 :       r=(x-w)*(fx-fv);
+     153       16377 :       q=(x-v)*(fx-fw);
+     154       16377 :       p=(x-v)*q-(x-w)*r;
+     155       16377 :       q=2.0*(q-r);
+     156       16377 :       if( q > 0.0 ) p = -p;
+     157       16377 :       q=std::fabs(q);
+     158             :       etemp=e;
+     159             :       e=d;
+     160       16377 :       if( std::fabs(p) >= std::fabs(0.5*q*etemp) || p <= q*(a-x) || p >= q*(b-x) ) {
+     161        7607 :         d = CGOLD*(e=(x >= xm ? a-x : b-x ));
+     162             :       } else {
+     163        8770 :         d=p/q; u=x+d;
+     164        8770 :         if(u-a < tol2 || b-u < tol2 ) d=(xm-x>=0?std::fabs(tol1):-std::fabs(tol1));
+     165             :       }
+     166             :     } else {
+     167        1373 :       d=CGOLD*(e=( x >= xm ? a-x : b-x ));
+     168             :     }
+     169       17750 :     if( std::fabs(d)>=tol1) u=x+d; else u=x+(d>=0?std::fabs(tol1):-std::fabs(tol1));
+     170       17750 :     fu=(myclass_func.*eng)(u);
+     171       17750 :     if( fu <= fx ) {
+     172        5911 :       if( u >= x ) a=x; else b=x;
+     173             :       v=w; fv=fw;
+     174             :       w=x; fw=fx;
+     175        5911 :       x=u; fx=fu;
+     176             :     } else {
+     177       11839 :       if( u < x ) a=u; else b=u;
+     178       11839 :       if( fu <=fw || w==x ) {
+     179             :         v=w; w=u; fv=fw; fw=fu;
+     180        7526 :       } 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        1192 : double Minimise1DBrent<FCLASS>::getMinimumValue() const {
+     190             :   plumed_dbg_assert( minimised );
+     191        1192 :   return fmin;
+     192             : }
+     193             : 
+     194             : }
+     195             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/MinimiseBase.h.func-sort-c.html b/coverage/tools/MinimiseBase.h.func-sort-c.html new file mode 100644 index 000000000000..b3a2245c397c --- /dev/null +++ b/coverage/tools/MinimiseBase.h.func-sort-c.html @@ -0,0 +1,145 @@ + + + + + + + + LCOV - plumed test coverage - tools/MinimiseBase.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - MinimiseBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2626100.0 %
Date:2024-04-19 12:12:35Functions: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
_ZN4PLMD5F1dimINS_9gridtools15FindGridOptimumEEC2ERKSt6vectorIdSaIdEES8_PS2_MS2_KFdS8_RS6_EMS2_FdS8_SA_E10
_ZNK4PLMD12MinimiseBaseINS_9gridtools15FindGridOptimumEE15calcDerivativesERKSt6vectorIdSaIdEERS6_MS2_FdS8_S9_E10
_ZNK4PLMD12MinimiseBaseINS_9gridtools15FindGridOptimumEE7lineminERKSt6vectorIdSaIdEERS6_MS2_FdS8_S9_E10
_ZN4PLMD5F1dimINS_6dimred13ArrangePointsEEC2ERKSt6vectorIdSaIdEES8_PS2_MS2_KFdS8_RS6_EMS2_FdS8_SA_E84
_ZNK4PLMD12MinimiseBaseINS_6dimred13ArrangePointsEE15calcDerivativesERKSt6vectorIdSaIdEERS6_MS2_FdS8_S9_E84
_ZNK4PLMD12MinimiseBaseINS_6dimred13ArrangePointsEE7lineminERKSt6vectorIdSaIdEERS6_MS2_FdS8_S9_E84
_ZN4PLMD5F1dimINS_9gridtools15FindGridOptimumEE6getEngERKd226
_ZN4PLMD5F1dimINS_7contour23DistanceFromContourBaseEEC2ERKSt6vectorIdSaIdEES8_PS2_MS2_KFdS8_RS6_EMS2_FdS8_SA_E291
_ZN4PLMD5F1dimINS_6dimred13ProjectPointsEEC2ERKSt6vectorIdSaIdEES8_PS2_MS2_KFdS8_RS6_EMS2_FdS8_SA_E1098
_ZNK4PLMD12MinimiseBaseINS_6dimred13ProjectPointsEE15calcDerivativesERKSt6vectorIdSaIdEERS6_MS2_FdS8_S9_E1098
_ZNK4PLMD12MinimiseBaseINS_6dimred13ProjectPointsEE7lineminERKSt6vectorIdSaIdEERS6_MS2_FdS8_S9_E1098
_ZN4PLMD5F1dimINS_6dimred13ArrangePointsEE6getEngERKd1848
_ZN4PLMD5F1dimINS_7contour18ContourFindingBaseEEC2ERKSt6vectorIdSaIdEES8_PS2_MS2_KFdS8_RS6_EMS2_FdS8_SA_E1896
_ZN4PLMD5F1dimINS_7contour23DistanceFromContourBaseEE6getEngERKd2642
_ZN4PLMD5F1dimINS_7contour18ContourFindingBaseEE6getEngERKd13079
_ZN4PLMD5F1dimINS_6dimred13ProjectPointsEE6getEngERKd23082
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/MinimiseBase.h.func.html b/coverage/tools/MinimiseBase.h.func.html new file mode 100644 index 000000000000..aa393b02bfaf --- /dev/null +++ b/coverage/tools/MinimiseBase.h.func.html @@ -0,0 +1,145 @@ + + + + + + + + LCOV - plumed test coverage - tools/MinimiseBase.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - MinimiseBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2626100.0 %
Date:2024-04-19 12:12:35Functions: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
_ZN4PLMD5F1dimINS_6dimred13ArrangePointsEE6getEngERKd1848
_ZN4PLMD5F1dimINS_6dimred13ArrangePointsEEC2ERKSt6vectorIdSaIdEES8_PS2_MS2_KFdS8_RS6_EMS2_FdS8_SA_E84
_ZN4PLMD5F1dimINS_6dimred13ProjectPointsEE6getEngERKd23082
_ZN4PLMD5F1dimINS_6dimred13ProjectPointsEEC2ERKSt6vectorIdSaIdEES8_PS2_MS2_KFdS8_RS6_EMS2_FdS8_SA_E1098
_ZN4PLMD5F1dimINS_7contour18ContourFindingBaseEE6getEngERKd13079
_ZN4PLMD5F1dimINS_7contour18ContourFindingBaseEEC2ERKSt6vectorIdSaIdEES8_PS2_MS2_KFdS8_RS6_EMS2_FdS8_SA_E1896
_ZN4PLMD5F1dimINS_7contour23DistanceFromContourBaseEE6getEngERKd2642
_ZN4PLMD5F1dimINS_7contour23DistanceFromContourBaseEEC2ERKSt6vectorIdSaIdEES8_PS2_MS2_KFdS8_RS6_EMS2_FdS8_SA_E291
_ZN4PLMD5F1dimINS_9gridtools15FindGridOptimumEE6getEngERKd226
_ZN4PLMD5F1dimINS_9gridtools15FindGridOptimumEEC2ERKSt6vectorIdSaIdEES8_PS2_MS2_KFdS8_RS6_EMS2_FdS8_SA_E10
_ZNK4PLMD12MinimiseBaseINS_6dimred13ArrangePointsEE15calcDerivativesERKSt6vectorIdSaIdEERS6_MS2_FdS8_S9_E84
_ZNK4PLMD12MinimiseBaseINS_6dimred13ArrangePointsEE7lineminERKSt6vectorIdSaIdEERS6_MS2_FdS8_S9_E84
_ZNK4PLMD12MinimiseBaseINS_6dimred13ProjectPointsEE15calcDerivativesERKSt6vectorIdSaIdEERS6_MS2_FdS8_S9_E1098
_ZNK4PLMD12MinimiseBaseINS_6dimred13ProjectPointsEE7lineminERKSt6vectorIdSaIdEERS6_MS2_FdS8_S9_E1098
_ZNK4PLMD12MinimiseBaseINS_9gridtools15FindGridOptimumEE15calcDerivativesERKSt6vectorIdSaIdEERS6_MS2_FdS8_S9_E10
_ZNK4PLMD12MinimiseBaseINS_9gridtools15FindGridOptimumEE7lineminERKSt6vectorIdSaIdEERS6_MS2_FdS8_S9_E10
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/MinimiseBase.h.gcov.html b/coverage/tools/MinimiseBase.h.gcov.html new file mode 100644 index 000000000000..816c9e855322 --- /dev/null +++ b/coverage/tools/MinimiseBase.h.gcov.html @@ -0,0 +1,192 @@ + + + + + + + + LCOV - plumed test coverage - tools/MinimiseBase.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - MinimiseBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2626100.0 %
Date:2024-04-19 12:12:35Functions: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        3379 : 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        3379 : F1dim<FCLASS>::F1dim( const std::vector<double>& pp, const std::vector<double>& dd, FCLASS* ff, engf_pointer cc, engfnc_pointer cc2 ):
+      58        3379 :   p(pp),
+      59        3379 :   dir(dd),
+      60        3379 :   pt(pp.size()),
+      61        3379 :   fake_der(pp.size()),
+      62        3379 :   func(ff),
+      63        3379 :   calc(cc),
+      64        3379 :   calc2(cc2)
+      65             : {
+      66        3379 :   plumed_assert( calc || calc2 );
+      67        3379 : }
+      68             : 
+      69             : template <class FCLASS>
+      70       40877 : double F1dim<FCLASS>::getEng( const double& xt ) {
+      71      503273 :   for(unsigned j=0; j<pt.size(); ++j) pt[j] = p[j] + xt*dir[j];
+      72       40877 :   if( calc ) return (func->*calc)(pt,fake_der);
+      73       27798 :   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 ) const ;
+      87             : public:
+      88          11 :   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 ) const ;
+      91             : };
+      92             : 
+      93             : template <class FCLASS>
+      94        1192 : double MinimiseBase<FCLASS>::linemin( const std::vector<double>& dir, std::vector<double>& p, engf_pointer myfunc ) const {
+      95             :   // Construct the object that turns points on a line into vectors
+      96        1192 :   F1dim<FCLASS> f1dim( p, dir, myclass_func, NULL, myfunc );
+      97             : 
+      98             :   // Construct an object that will do the line search for the minimum
+      99        1192 :   Minimise1DBrent<F1dim<FCLASS> > bb(f1dim);
+     100             : 
+     101             :   // This does the actual line minimisation
+     102        1192 :   double ax=0.0, xx=1.0;
+     103        1192 :   bb.bracket( ax, xx, &F1dim<FCLASS>::getEng );
+     104        1192 :   double xmin=bb.minimise( &F1dim<FCLASS>::getEng );
+     105       20706 :   for(unsigned i=0; i<p.size(); ++i) p[i] += xmin*dir[i];
+     106        2384 :   return bb.getMinimumValue();
+     107             : }
+     108             : 
+     109             : template <class FCLASS>
+     110        1192 : double MinimiseBase<FCLASS>::calcDerivatives( const std::vector<double>& p, std::vector<double>& der, engf_pointer myfunc ) const {
+     111        1192 :   return (myclass_func->*myfunc)( p, der );
+     112             : }
+     113             : 
+     114             : }
+     115             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/MolDataClass.cpp.func-sort-c.html b/coverage/tools/MolDataClass.cpp.func-sort-c.html new file mode 100644 index 000000000000..0730ea0fd7a7 --- /dev/null +++ b/coverage/tools/MolDataClass.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - tools/MolDataClass.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - MolDataClass.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:40647785.1 %
Date:2024-04-19 12:12:35Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12MolDataClass33numberOfAtomsPerResidueInBackboneERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE26
_ZN4PLMD12MolDataClass13specialSymbolERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_RKNS_3PDBERSt6vectorINS_10AtomNumberESaISD_EE627
_ZN4PLMD12MolDataClass21getBackboneForResidueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjRKNS_3PDBERSt6vectorINS_10AtomNumberESaISF_EE2676
_ZN4PLMD12MolDataClass15isTerminalGroupERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_3481
_ZN4PLMD12MolDataClass14allowedResidueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_8211
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/MolDataClass.cpp.func.html b/coverage/tools/MolDataClass.cpp.func.html new file mode 100644 index 000000000000..0fe09811ec94 --- /dev/null +++ b/coverage/tools/MolDataClass.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - tools/MolDataClass.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - MolDataClass.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:40647785.1 %
Date:2024-04-19 12:12:35Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12MolDataClass13specialSymbolERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_RKNS_3PDBERSt6vectorINS_10AtomNumberESaISD_EE627
_ZN4PLMD12MolDataClass14allowedResidueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_8211
_ZN4PLMD12MolDataClass15isTerminalGroupERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_3481
_ZN4PLMD12MolDataClass21getBackboneForResidueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjRKNS_3PDBERSt6vectorINS_10AtomNumberESaISF_EE2676
_ZN4PLMD12MolDataClass33numberOfAtomsPerResidueInBackboneERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE26
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/MolDataClass.cpp.gcov.html b/coverage/tools/MolDataClass.cpp.gcov.html new file mode 100644 index 000000000000..9d8b28e07a07 --- /dev/null +++ b/coverage/tools/MolDataClass.cpp.gcov.html @@ -0,0 +1,664 @@ + + + + + + + + LCOV - plumed test coverage - tools/MolDataClass.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - MolDataClass.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:40647785.1 %
Date:2024-04-19 12:12:35Functions: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          26 : unsigned MolDataClass::numberOfAtomsPerResidueInBackbone( const std::string& type ) {
+      30          26 :   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        8211 : bool MolDataClass::allowedResidue( const std::string& type, const std::string& residuename ) {
+      37        8211 :   if( type=="protein" ) {
+      38        6104 :     if(residuename=="ALA") return true;
+      39        5792 :     else if(residuename=="ARG") return true;
+      40        5792 :     else if(residuename=="ASN") return true;
+      41        5792 :     else if(residuename=="ASP") return true;
+      42        5780 :     else if(residuename=="CYS") return true;
+      43        5780 :     else if(residuename=="GLN") return true;
+      44        5780 :     else if(residuename=="GLU") return true;
+      45        5768 :     else if(residuename=="GLY") return true;
+      46        5758 :     else if(residuename=="HIS") return true;
+      47        5758 :     else if(residuename=="ILE") return true;
+      48        5754 :     else if(residuename=="LEU") return true;
+      49        5754 :     else if(residuename=="LYS") return true;
+      50        5748 :     else if(residuename=="MET") return true;
+      51        5748 :     else if(residuename=="PHE") return true;
+      52        5742 :     else if(residuename=="PRO") return true;
+      53        5735 :     else if(residuename=="SER") return true;
+      54        5731 :     else if(residuename=="THR") return true;
+      55        5701 :     else if(residuename=="TRP") return true;
+      56        5687 :     else if(residuename=="TYR") return true;
+      57        5681 :     else if(residuename=="VAL") return true;
+      58             : // Terminal groups
+      59         491 :     else if(residuename=="ACE") return true;
+      60         485 :     else if(residuename=="NME") return true;
+      61         479 :     else if(residuename=="NH2") return true;
+      62             : // Alternative residue names in common force fields
+      63         479 :     else if(residuename=="GLH") return true; // neutral GLU
+      64         479 :     else if(residuename=="ASH") return true; // neutral ASP
+      65         479 :     else if(residuename=="HID") return true; // HIS-D amber
+      66         479 :     else if(residuename=="HSD") return true; // HIS-D charmm
+      67         479 :     else if(residuename=="HIE") return true; // HIS-E amber
+      68         479 :     else if(residuename=="HSE") return true; // HIS-E charmm
+      69         479 :     else if(residuename=="HIP") return true; // HIS-P amber
+      70         479 :     else if(residuename=="HSP") return true; // HIS-P charmm
+      71             : // Weird amino acids
+      72         479 :     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        2676 : void MolDataClass::getBackboneForResidue( const std::string& type, const unsigned& residuenum, const PDB& mypdb, std::vector<AtomNumber>& atoms ) {
+     164        2676 :   std::string residuename=mypdb.getResidueName( residuenum );
+     165        2676 :   plumed_massert( MolDataClass::allowedResidue( type, residuename ), "residue " + residuename + " unrecognized for molecule type " + type );
+     166        2676 :   if( type=="protein" ) {
+     167        2676 :     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        2676 :     } else if( residuename=="ACE") {
+     175           0 :       atoms.resize(1);
+     176           0 :       atoms[0]=mypdb.getNamedAtomFromResidue("C",residuenum);
+     177        5352 :     } else if( residuename=="NME"||residuename=="NH2") {
+     178           0 :       atoms.resize(1);
+     179           0 :       atoms[0]=mypdb.getNamedAtomFromResidue("N",residuenum);
+     180             :     } else {
+     181        2676 :       atoms.resize(5);
+     182        2676 :       atoms[0]=mypdb.getNamedAtomFromResidue("N",residuenum);
+     183        2676 :       atoms[1]=mypdb.getNamedAtomFromResidue("CA",residuenum);
+     184        2676 :       atoms[2]=mypdb.getNamedAtomFromResidue("CB",residuenum);
+     185        2676 :       atoms[3]=mypdb.getNamedAtomFromResidue("C",residuenum);
+     186        2676 :       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        2676 : }
+     201             : 
+     202        3481 : bool MolDataClass::isTerminalGroup( const std::string& type, const std::string& residuename ) {
+     203        3481 :   if( type=="protein" ) {
+     204        3481 :     if( residuename=="ACE" ) return true;
+     205        3151 :     else if( residuename=="NME" ) return true;
+     206        2821 :     else if( residuename=="NH2" ) return true;
+     207        2821 :     else return false;
+     208             :   } else {
+     209           0 :     plumed_merror(type + " is not a valid molecule type");
+     210             :   }
+     211             :   return false;
+     212             : }
+     213             : 
+     214         627 : void MolDataClass::specialSymbol( const std::string& type, const std::string& symbol, const PDB& mypdb, std::vector<AtomNumber>& numbers ) {
+     215         857 :   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         627 :     numbers.resize(0);
+     222             : 
+     223             : // special cases:
+     224         627 :     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         626 :     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         624 :     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         623 :     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         622 :     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         621 :     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         620 :     if(dash==std::string::npos) plumed_error() << "Unrecognized symbol "<<symbol;
+     289             : 
+     290         620 :     std::size_t firstunderscore=symbol.find_first_of('_',dash+1);
+     291         620 :     std::size_t firstnum=symbol.find_first_of("0123456789",dash+1);
+     292         620 :     std::string name=symbol.substr(0,dash);
+     293             :     unsigned resnum;
+     294             :     std::string resname;
+     295             :     std::string chainid;
+     296         620 :     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         614 :     } else if(firstnum==dash+1) {
+     300        1208 :       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         620 :     resname= mypdb.getResidueName(resnum,chainid);
+     308         620 :     Tools::stripLeadingAndTrailingBlanks(resname);
+     309        1240 :     if(allowedResidue("protein",resname)) {
+     310         202 :       if( name=="phi" && !isTerminalGroup("protein",resname) ) {
+     311         114 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C",resnum-1,chainid));
+     312         114 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("N",resnum,chainid));
+     313         114 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("CA",resnum,chainid));
+     314         114 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C",resnum,chainid));
+     315         171 :       } else if( name=="psi" && !isTerminalGroup("protein",resname) ) {
+     316         166 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("N",resnum,chainid));
+     317         166 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("CA",resnum,chainid));
+     318         166 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C",resnum,chainid));
+     319         166 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("N",resnum+1,chainid));
+     320           6 :       } else if( name=="omega" && !isTerminalGroup("protein",resname) ) {
+     321           2 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("CA",resnum-1,chainid));
+     322           2 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C",resnum-1,chainid));
+     323           2 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("N",resnum,chainid));
+     324           2 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("CA",resnum,chainid));
+     325           5 :       } else if( name=="chi1" && !isTerminalGroup("protein",resname) ) {
+     326           3 :         if ( resname=="GLY" || resname=="ALA" || resname=="SFO" ) plumed_merror("chi-1 is not defined for ALA, GLY and SFO");
+     327           2 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("N",resnum,chainid));
+     328           2 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("CA",resnum,chainid));
+     329           2 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("CB",resnum,chainid));
+     330           2 :         if(resname=="ILE"||resname=="VAL") {
+     331           0 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("CG1",resnum,chainid));
+     332           1 :         } else if(resname=="CYS") {
+     333           0 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("SG",resnum,chainid));
+     334           1 :         } else if(resname=="THR") {
+     335           0 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("OG1",resnum,chainid));
+     336           1 :         } else if(resname=="SER") {
+     337           0 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("OG",resnum,chainid));
+     338             :         } else {
+     339           2 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("CG",resnum,chainid));
+     340             :         }
+     341           4 :       } else if( name=="chi2" && !isTerminalGroup("protein",resname) ) {
+     342           5 :         if ( resname=="GLY" || resname=="ALA" || resname=="SFO" || resname=="CYS" || resname=="SER" ||
+     343           2 :              resname=="THR" || resname=="VAL" ) plumed_merror("chi-2 is not defined for ALA, GLY, CYS, SER, THR, VAL and SFO");
+     344           2 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("CA",resnum,chainid));
+     345           2 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("CB",resnum,chainid));
+     346             : 
+     347           1 :         if(resname=="ILE") {
+     348           0 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("CG1",resnum,chainid));
+     349             :         } else {
+     350           2 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("CG",resnum,chainid));
+     351             :         }
+     352           2 :         if(resname=="ASN" || resname=="ASP") {
+     353           0 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("OD1",resnum,chainid));
+     354           1 :         } else if(resname=="HIS") {
+     355           0 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("ND1",resnum,chainid));
+     356           4 :         } else if(resname=="LEU" || resname=="PHE" || resname=="TRP" || resname=="TYR") {
+     357           0 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("CD1",resnum,chainid));
+     358           1 :         } else if(resname=="MET") {
+     359           0 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("SD",resnum,chainid));
+     360             :         } else {
+     361           2 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("CD",resnum,chainid));
+     362             :         }
+     363           2 :       } else if( name=="chi3" && !isTerminalGroup("protein",resname) ) {
+     364           0 :         if (!( resname=="ARG" || resname=="GLN" || resname=="GLU" || resname=="LYS" ||
+     365           0 :                resname=="MET" )) plumed_merror("chi-3 is defined only for ARG, GLN, GLU, LYS and MET");
+     366           0 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("CB",resnum,chainid));
+     367           0 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("CG",resnum,chainid));
+     368             : 
+     369           0 :         if(resname=="MET") {
+     370           0 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("SD",resnum,chainid));
+     371             :         } else {
+     372           0 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("CD",resnum,chainid));
+     373             :         }
+     374           0 :         if(resname=="GLN" || resname=="GLU") {
+     375           0 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("OE1",resnum,chainid));
+     376           0 :         } else if(resname=="LYS" || resname=="MET") {
+     377           0 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("CE",resnum,chainid));
+     378             :         } else {
+     379           0 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("NE",resnum,chainid));
+     380             :         }
+     381           2 :       } else if( name=="chi4" && !isTerminalGroup("protein",resname) ) {
+     382           0 :         if (!( resname=="ARG" || resname=="LYS" )) plumed_merror("chi-4 is defined only for ARG and LYS");
+     383           0 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("CG",resnum,chainid));
+     384           0 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("CD",resnum,chainid));
+     385             : 
+     386           0 :         if(resname=="ARG") {
+     387           0 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("NE",resnum,chainid));
+     388           0 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("CZ",resnum,chainid));
+     389             :         } else {
+     390           0 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("CE",resnum,chainid));
+     391           0 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("NZ",resnum,chainid));
+     392             :         }
+     393           2 :       } else if( name=="chi5" && !isTerminalGroup("protein",resname) ) {
+     394           0 :         if (!( resname=="ARG" )) plumed_merror("chi-5 is defined only for ARG");
+     395           0 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("CD",resnum,chainid));
+     396           0 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("NE",resnum,chainid));
+     397           0 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("CZ",resnum,chainid));
+     398           0 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("NH1",resnum,chainid));
+     399           3 :       } else if( name=="sidechain" && !isTerminalGroup("protein",resname) ) {
+     400           1 :         if(resname=="GLY") plumed_merror("sidechain is not defined for GLY");
+     401           1 :         std::vector<AtomNumber> tmpnum1(mypdb.getAtomsInResidue(resnum,chainid));
+     402          15 :         for(unsigned i=0; i<tmpnum1.size(); i++) {
+     403          66 :           if(mypdb.getAtomName(tmpnum1[i])!="N"&&mypdb.getAtomName(tmpnum1[i])!="CA"&&
+     404          70 :               mypdb.getAtomName(tmpnum1[i])!="C"&&mypdb.getAtomName(tmpnum1[i])!="O"&&
+     405          61 :               mypdb.getAtomName(tmpnum1[i])!="HA"&&mypdb.getAtomName(tmpnum1[i])!="H"&&
+     406          59 :               mypdb.getAtomName(tmpnum1[i])!="HN"&&mypdb.getAtomName(tmpnum1[i])!="H1"&&
+     407          59 :               mypdb.getAtomName(tmpnum1[i])!="H2"&&mypdb.getAtomName(tmpnum1[i])!="H3"&&
+     408          59 :               mypdb.getAtomName(tmpnum1[i])!="OXT"&&mypdb.getAtomName(tmpnum1[i])!="OT1"&&
+     409          73 :               mypdb.getAtomName(tmpnum1[i])!="OT2"&&mypdb.getAtomName(tmpnum1[i])!="OC1"&&
+     410          32 :               mypdb.getAtomName(tmpnum1[i])!="OC2") {
+     411           9 :             numbers.push_back( tmpnum1[i] );
+     412             :           }
+     413             :         }
+     414           2 :       } else if( name=="back" && !isTerminalGroup("protein",resname) ) {
+     415           1 :         std::vector<AtomNumber> tmpnum1(mypdb.getAtomsInResidue(resnum,chainid));
+     416          15 :         for(unsigned i=0; i<tmpnum1.size(); i++) {
+     417          66 :           if(mypdb.getAtomName(tmpnum1[i])=="N"||mypdb.getAtomName(tmpnum1[i])=="CA"||
+     418          70 :               mypdb.getAtomName(tmpnum1[i])=="C"||mypdb.getAtomName(tmpnum1[i])=="O"||
+     419          61 :               mypdb.getAtomName(tmpnum1[i])=="HA"||mypdb.getAtomName(tmpnum1[i])=="H"||
+     420          59 :               mypdb.getAtomName(tmpnum1[i])=="HN"||mypdb.getAtomName(tmpnum1[i])=="H1"||
+     421          59 :               mypdb.getAtomName(tmpnum1[i])=="H2"||mypdb.getAtomName(tmpnum1[i])=="H3"||
+     422          59 :               mypdb.getAtomName(tmpnum1[i])=="OXT"||mypdb.getAtomName(tmpnum1[i])=="OT1"||
+     423          59 :               mypdb.getAtomName(tmpnum1[i])=="OT2"||mypdb.getAtomName(tmpnum1[i])=="OC1"||
+     424          59 :               mypdb.getAtomName(tmpnum1[i])=="OC2"||mypdb.getAtomName(tmpnum1[i])=="HA1"||
+     425          63 :               mypdb.getAtomName(tmpnum1[i])=="HA2"||mypdb.getAtomName(tmpnum1[i])=="HA3") {
+     426           5 :             numbers.push_back( tmpnum1[i] );
+     427             :           }
+     428             :         }
+     429           0 :       } else numbers.push_back(mypdb.getNamedAtomFromResidueAndChain(name,resnum,chainid));
+     430             : 
+     431         488 :     } else if( allowedResidue("rna",resname) || allowedResidue("dna",resname)) {
+     432             :       std::string basetype;
+     433         474 :       if(resname.find_first_of("A")!=std::string::npos) basetype+="A";
+     434         474 :       if(resname.find_first_of("U")!=std::string::npos) basetype+="U";
+     435         474 :       if(resname.find_first_of("T")!=std::string::npos) basetype+="T";
+     436         474 :       if(resname.find_first_of("C")!=std::string::npos) basetype+="C";
+     437         474 :       if(resname.find_first_of("G")!=std::string::npos) basetype+="G";
+     438         474 :       plumed_massert(basetype.length()==1,"cannot find type of rna/dna residue "+resname+" "+basetype);
+     439         474 :       if( name=="chi" ) {
+     440          68 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("O4\'",resnum,chainid));
+     441          68 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C1\'",resnum,chainid));
+     442          99 :         if(basetype=="T" || basetype=="U" || basetype=="C") {
+     443          18 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("N1",resnum,chainid));
+     444          18 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C2",resnum,chainid));
+     445          47 :         } else if(basetype=="G" || basetype=="A") {
+     446          50 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("N9",resnum,chainid));
+     447          50 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C4",resnum,chainid));
+     448           0 :         } else plumed_error();
+     449         440 :       } else if( name=="alpha" ) {
+     450          14 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("O3\'",resnum-1,chainid));
+     451          14 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("P",resnum,chainid));
+     452          14 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("O5\'",resnum,chainid));
+     453          14 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C5\'",resnum,chainid));
+     454         433 :       } else if( name=="beta" ) {
+     455          14 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("P",resnum,chainid));
+     456          14 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("O5\'",resnum,chainid));
+     457          14 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C5\'",resnum,chainid));
+     458          14 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C4\'",resnum,chainid));
+     459         426 :       } else if( name=="gamma" ) {
+     460          54 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("O5\'",resnum,chainid));
+     461          54 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C5\'",resnum,chainid));
+     462          54 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C4\'",resnum,chainid));
+     463          54 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C3\'",resnum,chainid));
+     464         399 :       } else if( name=="delta" ) {
+     465           2 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C5\'",resnum,chainid));
+     466           2 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C4\'",resnum,chainid));
+     467           2 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C3\'",resnum,chainid));
+     468           2 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("O3\'",resnum,chainid));
+     469         398 :       } else if( name=="epsilon" ) {
+     470          16 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C4\'",resnum,chainid));
+     471          16 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C3\'",resnum,chainid));
+     472          16 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("O3\'",resnum,chainid));
+     473          16 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("P",resnum+1,chainid));
+     474         390 :       } else if( name=="zeta" ) {
+     475          14 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C3\'",resnum,chainid));
+     476          14 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("O3\'",resnum,chainid));
+     477          14 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("P",resnum+1,chainid));
+     478          14 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("O5\'",resnum+1,chainid));
+     479         383 :       } else if( name=="v0" ) {
+     480           6 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C4\'",resnum,chainid));
+     481           6 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("O4\'",resnum,chainid));
+     482           6 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C1\'",resnum,chainid));
+     483           6 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C2\'",resnum,chainid));
+     484         380 :       } else if( name=="v1" ) {
+     485           6 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("O4\'",resnum,chainid));
+     486           6 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C1\'",resnum,chainid));
+     487           6 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C2\'",resnum,chainid));
+     488           6 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C3\'",resnum,chainid));
+     489         377 :       } else if( name=="v2" ) {
+     490           6 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C1\'",resnum,chainid));
+     491           6 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C2\'",resnum,chainid));
+     492           6 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C3\'",resnum,chainid));
+     493           6 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C4\'",resnum,chainid));
+     494         374 :       } else if( name=="v3" ) {
+     495           6 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C2\'",resnum,chainid));
+     496           6 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C3\'",resnum,chainid));
+     497           6 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C4\'",resnum,chainid));
+     498           6 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("O4\'",resnum,chainid));
+     499         371 :       } else if( name=="v4" ) {
+     500           6 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C3\'",resnum,chainid));
+     501           6 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C4\'",resnum,chainid));
+     502           6 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("O4\'",resnum,chainid));
+     503           6 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C1\'",resnum,chainid));
+     504         368 :       } else if( name=="back" ) {
+     505           2 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("P",resnum,chainid));
+     506           2 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("O5\'",resnum,chainid));
+     507           2 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C5\'",resnum,chainid));
+     508           2 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C4\'",resnum,chainid));
+     509           2 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C3\'",resnum,chainid));
+     510           2 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("O3\'",resnum,chainid));
+     511         367 :       } else if( name=="sugar" ) {
+     512         104 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C4\'",resnum,chainid));
+     513         104 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("O4\'",resnum,chainid));
+     514         104 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C1\'",resnum,chainid));
+     515         104 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C2\'",resnum,chainid));
+     516         104 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C3\'",resnum,chainid));
+     517         315 :       } else if( name=="base" ) {
+     518          25 :         if(basetype=="C") {
+     519          18 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("N1",resnum,chainid));
+     520          18 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C2",resnum,chainid));
+     521          18 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("O2",resnum,chainid));
+     522          18 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("N3",resnum,chainid));
+     523          18 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C4",resnum,chainid));
+     524          18 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("N4",resnum,chainid));
+     525          18 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C5",resnum,chainid));
+     526          18 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C6",resnum,chainid));
+     527          16 :         } else if(basetype=="U") {
+     528           4 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("N1",resnum,chainid));
+     529           4 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C2",resnum,chainid));
+     530           4 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("O2",resnum,chainid));
+     531           4 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("N3",resnum,chainid));
+     532           4 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C4",resnum,chainid));
+     533           4 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("O4",resnum,chainid));
+     534           4 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C5",resnum,chainid));
+     535           4 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C6",resnum,chainid));
+     536          14 :         } else if(basetype=="T") {
+     537           0 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("N1",resnum,chainid));
+     538           0 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C2",resnum,chainid));
+     539           0 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("O2",resnum,chainid));
+     540           0 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("N3",resnum,chainid));
+     541           0 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C4",resnum,chainid));
+     542           0 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("O4",resnum,chainid));
+     543           0 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C5",resnum,chainid));
+     544           0 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C7",resnum,chainid));
+     545           0 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C6",resnum,chainid));
+     546          14 :         } else if(basetype=="G") {
+     547           6 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("N9",resnum,chainid));
+     548           6 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C4",resnum,chainid));
+     549           6 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("N3",resnum,chainid));
+     550           6 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C2",resnum,chainid));
+     551           6 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("N2",resnum,chainid));
+     552           6 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("N1",resnum,chainid));
+     553           6 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C6",resnum,chainid));
+     554           6 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("O6",resnum,chainid));
+     555           6 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C5",resnum,chainid));
+     556           6 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("N7",resnum,chainid));
+     557           6 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C8",resnum,chainid));
+     558          11 :         } else if(basetype=="A") {
+     559          22 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("N9",resnum,chainid));
+     560          22 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C4",resnum,chainid));
+     561          22 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("N1",resnum,chainid));
+     562          22 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C2",resnum,chainid));
+     563          22 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("N3",resnum,chainid));
+     564          22 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C6",resnum,chainid));
+     565          22 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("N6",resnum,chainid));
+     566          22 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C5",resnum,chainid));
+     567          22 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("N7",resnum,chainid));
+     568          22 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C8",resnum,chainid));
+     569           0 :         } else plumed_error();
+     570         290 :       } else if( name=="lcs" ) {
+     571         568 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C2",resnum,chainid));
+     572         752 :         if(basetype=="T" || basetype=="U" || basetype=="C") {
+     573         296 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C4",resnum,chainid));
+     574         296 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C6",resnum,chainid));
+     575         216 :         } else if(basetype=="G" || basetype=="A") {
+     576         272 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C6",resnum,chainid));
+     577         272 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C4",resnum,chainid));
+     578           0 :         } else plumed_error();
+     579          12 :       } else numbers.push_back(mypdb.getNamedAtomFromResidueAndChain(name,resnum,chainid));
+     580           2 :     } else numbers.push_back(mypdb.getNamedAtomFromResidueAndChain(name,resnum,chainid));
+     581             :   }
+     582             :   else {
+     583           0 :     plumed_merror(type + " is not a valid molecule type");
+     584             :   }
+     585             : }
+     586             : 
+     587             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/MultiValue.cpp.func-sort-c.html b/coverage/tools/MultiValue.cpp.func-sort-c.html new file mode 100644 index 000000000000..9b2bd1b142f8 --- /dev/null +++ b/coverage/tools/MultiValue.cpp.func-sort-c.html @@ -0,0 +1,113 @@ + + + + + + + + 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:499153.8 %
Date:2024-04-19 12:12:35Functions:41040.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10MultiValue12quotientRuleERKjS2_0
_ZN4PLMD10MultiValue15copyDerivativesERS0_0
_ZN4PLMD10MultiValue23clearTemporyDerivativesEv0
_ZN4PLMD10MultiValue5clearERKj0
_ZN4PLMD10MultiValue9chainRuleERKjS2_S2_S2_RKdS2_RSt6vectorIdSaIdEE0
_ZNK4PLMD10MultiValue10copyValuesERS0_0
_ZN4PLMD10MultiValue6resizeERKmS2_S2_S2_S2_36
_ZN4PLMD10MultiValueC2ERKmS2_S2_S2_S2_344781
_ZN4PLMD10MultiValue8clearAllERKb6791208
_ZN4PLMD10MultiValue16clearDerivativesERKj152002731
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/MultiValue.cpp.func.html b/coverage/tools/MultiValue.cpp.func.html new file mode 100644 index 000000000000..fc57223fde55 --- /dev/null +++ b/coverage/tools/MultiValue.cpp.func.html @@ -0,0 +1,113 @@ + + + + + + + + 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:499153.8 %
Date:2024-04-19 12:12:35Functions:41040.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10MultiValue12quotientRuleERKjS2_0
_ZN4PLMD10MultiValue15copyDerivativesERS0_0
_ZN4PLMD10MultiValue16clearDerivativesERKj152002731
_ZN4PLMD10MultiValue23clearTemporyDerivativesEv0
_ZN4PLMD10MultiValue5clearERKj0
_ZN4PLMD10MultiValue6resizeERKmS2_S2_S2_S2_36
_ZN4PLMD10MultiValue8clearAllERKb6791208
_ZN4PLMD10MultiValue9chainRuleERKjS2_S2_S2_RKdS2_RSt6vectorIdSaIdEE0
_ZN4PLMD10MultiValueC2ERKmS2_S2_S2_S2_344781
_ZNK4PLMD10MultiValue10copyValuesERS0_0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/MultiValue.cpp.gcov.html b/coverage/tools/MultiValue.cpp.gcov.html new file mode 100644 index 000000000000..427e6e6a9a0c --- /dev/null +++ b/coverage/tools/MultiValue.cpp.gcov.html @@ -0,0 +1,253 @@ + + + + + + + + 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:499153.8 %
Date:2024-04-19 12:12:35Functions:41040.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      344781 : MultiValue::MultiValue( const size_t& nvals, const size_t& nder, const size_t& nmat, const size_t& maxcol, const size_t& nbook ):
+      27      344781 :   task_index(0),
+      28      344781 :   task2_index(0),
+      29      344781 :   values(nvals),
+      30      344781 :   nderivatives(nder),
+      31      344781 :   derivatives(nvals*nder),
+      32      344781 :   hasderiv(nvals*nder,false),
+      33      344781 :   tmpval(0),
+      34      344781 :   nactive(nvals),
+      35      344781 :   active_list(nvals*nder),
+      36      344781 :   tmpder(nder),
+      37      344781 :   atLeastOneSet(false),
+      38      344781 :   vector_call(false),
+      39      344781 :   nindices(0),
+      40      344781 :   nsplit(0),
+      41      344781 :   nmatrix_cols(maxcol),
+      42      344781 :   matrix_row_stash(nmat*maxcol,0),
+      43      344781 :   matrix_force_stash(nder*nmat),
+      44      344781 :   matrix_bookeeping(nbook,0),
+      45      344781 :   matrix_row_nderivatives(nmat,0),
+      46      689562 :   matrix_row_derivative_indices(nmat)
+      47             : {
+      48      388531 :   for(unsigned i=0; i<nmat; ++i) matrix_row_derivative_indices[i].resize( nder );
+      49             :   // This is crap that will be deleted in future
+      50      344781 :   std::vector<unsigned> myind( nder );
+      51    99612551 :   for(unsigned i=0; i<nder; ++i) myind[i]=i;
+      52      344781 :   hasDerivatives.createIndexListFromVector( myind );
+      53      344781 : }
+      54             : 
+      55          36 : void MultiValue::resize( const size_t& nvals, const size_t& nder, const size_t& nmat, const size_t& maxcol, const size_t& nbook ) {
+      56          36 :   values.resize(nvals); nderivatives=nder; derivatives.resize( nvals*nder );
+      57          36 :   hasderiv.resize(nvals*nder,false); nactive.resize(nvals); active_list.resize(nvals*nder);
+      58          36 :   nmatrix_cols=maxcol; matrix_row_stash.resize(nmat*maxcol,0); matrix_force_stash.resize(nmat*nder,0); matrix_bookeeping.resize(nbook, 0);
+      59          36 :   matrix_row_nderivatives.resize(nmat,0); matrix_row_derivative_indices.resize(nmat); atLeastOneSet=false;
+      60          36 :   for(unsigned i=0; i<nmat; ++i) matrix_row_derivative_indices[i].resize( nder );
+      61             :   // All crap from here onwards
+      62          36 :   tmpder.resize( nder ); hasDerivatives.clear(); std::vector<unsigned> myind( nder );
+      63        6840 :   for(unsigned i=0; i<nder; ++i) myind[i]=i;
+      64          36 :   hasDerivatives.createIndexListFromVector( myind );
+      65          36 : }
+      66             : 
+      67     6791208 : void MultiValue::clearAll( const bool& newversion ) {
+      68     6791208 :   if( newversion ) {
+      69    36480348 :     for(unsigned i=0; i<values.size(); ++i) values[i]=0;
+      70             :     // Clear matrix row
+      71             :     std::fill( matrix_row_stash.begin(), matrix_row_stash.end(), 0 );
+      72             :     // Clear matrix derivative indices
+      73             :     std::fill( matrix_row_nderivatives.begin(), matrix_row_nderivatives.end(), 0 );
+      74             :     // Clear matrix forces
+      75             :     std::fill(matrix_force_stash.begin(),matrix_force_stash.end(),0);
+      76     6791208 :     if( !atLeastOneSet ) return;
+      77    29313028 :     for(unsigned i=0; i<values.size(); ++i) clearDerivatives(i);
+      78     5503175 :     atLeastOneSet=false;
+      79             :   } else {
+      80             :     // This should be deleted once old MultiColvar has gone
+      81           0 :     if( atLeastOneSet && !hasDerivatives.updateComplete() ) hasDerivatives.updateActiveMembers();
+      82           0 :     for(unsigned i=0; i<values.size(); ++i) clear(i);
+      83           0 :     clearTemporyDerivatives(); hasDerivatives.deactivateAll(); atLeastOneSet=false;
+      84             :   }
+      85             : }
+      86             : 
+      87   152002731 : void MultiValue::clearDerivatives( const unsigned& ival ) {
+      88   152002731 :   values[ival]=0;
+      89   152002731 :   if( !atLeastOneSet ) return;
+      90    75174339 :   unsigned base=ival*nderivatives;
+      91   752607746 :   for(unsigned i=0; i<nactive[ival]; ++i) {
+      92   677433407 :     unsigned k = base+active_list[base+i]; derivatives[k]=0.; hasderiv[k]=false;
+      93             :   }
+      94    75174339 :   nactive[ival]=0;
+      95             : #ifndef NDEBUG
+      96             :   for(unsigned i=0; i<nderivatives; ++i) {
+      97             :     if( hasderiv[base+i] ) {
+      98             :       std::string num1, num2;
+      99             :       Tools::convert(ival,num1); Tools::convert(i,num2);
+     100             :       plumed_merror("FAILING TO CLEAR VALUE " + num1 + " DERIVATIVE " + num2 + " IS PROBLEMATIC");
+     101             :     }
+     102             :     // As this is debugging code we hard code an escape here otherwise this check is really expensive
+     103             :     if( i>1000 ) return;
+     104             :   }
+     105             : #endif
+     106             : }
+     107             : 
+     108             : // This should be deleted once old MultiColvar has gone
+     109           0 : void MultiValue::clear( const unsigned& ival ) {
+     110           0 :   values[ival]=0;
+     111           0 :   unsigned base=ival*nderivatives, ndert=hasDerivatives.getNumberActive();
+     112           0 :   for(unsigned i=0; i<ndert; ++i) derivatives[ base+hasDerivatives[i] ]=0.;
+     113           0 : }
+     114             : 
+     115           0 : void MultiValue::clearTemporyDerivatives() {
+     116           0 :   unsigned ndert=hasDerivatives.getNumberActive(); tmpval=0.;
+     117           0 :   for(unsigned i=0; i<ndert; ++i) tmpder[ hasDerivatives[i] ]=0.;
+     118           0 : }
+     119             : 
+     120           0 : void MultiValue::chainRule( const unsigned& ival, const unsigned& iout, const unsigned& stride, const unsigned& off,
+     121             :                             const double& df, const unsigned& bufstart, std::vector<double>& buffer ) {
+     122           0 :   if( !hasDerivatives.updateComplete() ) hasDerivatives.updateActiveMembers();
+     123             : 
+     124             :   plumed_dbg_assert( off<stride );
+     125           0 :   unsigned base=nderivatives*ival, ndert=hasDerivatives.getNumberActive();
+     126           0 :   unsigned start=bufstart+stride*(nderivatives+1)*iout + stride;
+     127           0 :   for(unsigned i=0; i<ndert; ++i) {
+     128             :     unsigned jder=hasDerivatives[i];
+     129           0 :     buffer[start+jder*stride] += df*derivatives[base+jder];
+     130             :   }
+     131           0 : }
+     132             : 
+     133           0 : void MultiValue::copyValues( MultiValue& outvals ) const {
+     134             :   plumed_dbg_assert( values.size()<=outvals.getNumberOfValues() );
+     135           0 :   for(unsigned i=0; i<values.size(); ++i) outvals.setValue( i, values[i] );
+     136             : 
+     137           0 : }
+     138             : 
+     139           0 : void MultiValue::copyDerivatives( MultiValue& outvals ) {
+     140             :   plumed_dbg_assert( values.size()<=outvals.getNumberOfValues() && nderivatives<=outvals.getNumberOfDerivatives() );
+     141           0 :   if( !hasDerivatives.updateComplete() ) hasDerivatives.updateActiveMembers();
+     142             : 
+     143           0 :   outvals.atLeastOneSet=true; unsigned ndert=hasDerivatives.getNumberActive();
+     144           0 :   for(unsigned j=0; j<ndert; ++j) {
+     145           0 :     unsigned jder=hasDerivatives[j]; outvals.hasDerivatives.activate(jder);
+     146             :   }
+     147             : 
+     148             :   unsigned base=0, obase=0;
+     149           0 :   for(unsigned i=0; i<values.size(); ++i) {
+     150           0 :     for(unsigned j=0; j<ndert; ++j) {
+     151             :       unsigned jder=hasDerivatives[j];
+     152           0 :       outvals.derivatives[obase+jder] += derivatives[base+jder];
+     153             :     }
+     154           0 :     obase+=outvals.nderivatives; base+=nderivatives;
+     155             :   }
+     156           0 : }
+     157             : 
+     158           0 : void MultiValue::quotientRule( const unsigned& nder, const unsigned& oder ) {
+     159             :   plumed_dbg_assert( nder<values.size() && oder<values.size() );
+     160           0 :   if( !hasDerivatives.updateComplete() ) hasDerivatives.updateActiveMembers();
+     161             : 
+     162           0 :   unsigned ndert=hasDerivatives.getNumberActive(); double wpref;
+     163           0 :   unsigned obase=oder*nderivatives, nbase=nder*nderivatives;
+     164             : 
+     165           0 :   if( std::fabs(tmpval)>epsilon ) { wpref=1.0/tmpval; }
+     166             :   else { wpref=1.0; }
+     167             : 
+     168           0 :   double pref = values[nder]*wpref*wpref;
+     169           0 :   for(unsigned j=0; j<ndert; ++j) {
+     170             :     unsigned jder=hasDerivatives[j];
+     171           0 :     derivatives[obase+jder] = wpref*derivatives[nbase+jder]  - pref*tmpder[jder];
+     172             :   }
+     173           0 :   values[oder] = wpref*values[nder];
+     174           0 : }
+     175             : 
+     176             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/MultiValue.h.func-sort-c.html b/coverage/tools/MultiValue.h.func-sort-c.html new file mode 100644 index 000000000000..06c0168de707 --- /dev/null +++ b/coverage/tools/MultiValue.h.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - tools/MultiValue.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - MultiValue.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4343100.0 %
Date:2024-04-19 12:12:35Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10MultiValue19resizeTemporyVectorERKj490140
_ZN4PLMD10MultiValue18stashMatrixElementERKjS2_S2_RKd8280289
_ZN4PLMD10MultiValue13addDerivativeERKmS2_RKd1192882771
_ZN4PLMD10MultiValue11updateIndexERKmS2_2053353621
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/MultiValue.h.func.html b/coverage/tools/MultiValue.h.func.html new file mode 100644 index 000000000000..06d36106553c --- /dev/null +++ b/coverage/tools/MultiValue.h.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - tools/MultiValue.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - MultiValue.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4343100.0 %
Date:2024-04-19 12:12:35Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10MultiValue11updateIndexERKmS2_2053353621
_ZN4PLMD10MultiValue13addDerivativeERKmS2_RKd1192882771
_ZN4PLMD10MultiValue18stashMatrixElementERKjS2_S2_RKd8280289
_ZN4PLMD10MultiValue19resizeTemporyVectorERKj490140
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/MultiValue.h.gcov.html b/coverage/tools/MultiValue.h.gcov.html new file mode 100644 index 000000000000..2f69caf30b1a --- /dev/null +++ b/coverage/tools/MultiValue.h.gcov.html @@ -0,0 +1,537 @@ + + + + + + + + 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:4343100.0 %
Date:2024-04-19 12:12:35Functions: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             :   friend class ActionWithVector;
+      34             : private:
+      35             : /// The index of the task we are currently performing
+      36             :   std::size_t task_index, task2_index;
+      37             : /// Used to ensure rapid accumulation of derivatives
+      38             :   DynamicList<unsigned> hasDerivatives;
+      39             : /// Values of quantities
+      40             :   std::vector<double> values;
+      41             : /// Number of derivatives per value
+      42             :   unsigned nderivatives;
+      43             : /// Derivatives
+      44             :   std::vector<double> derivatives;
+      45             : /// Matrix asserting which values have derivatives
+      46             :   std::vector<bool> hasderiv;
+      47             : /// Tempory value
+      48             :   double tmpval;
+      49             : /// Lists of active variables
+      50             :   std::vector<unsigned> nactive, active_list;
+      51             : /// Tempory vector of derivatives (used for calculating quotients
+      52             :   std::vector<double> tmpder;
+      53             : /// Logical to check if any derivatives were set
+      54             :   bool atLeastOneSet;
+      55             : /// Are we in this for a call on vectors
+      56             :   bool vector_call;
+      57             :   unsigned nindices, nsplit;
+      58             : /// This allows us to store matrix elements
+      59             :   unsigned nmatrix_cols;
+      60             :   std::vector<double> matrix_row_stash;
+      61             :   std::vector<double> matrix_force_stash;
+      62             :   std::vector<unsigned> matrix_bookeeping;
+      63             : /// These are used to store the indices that have derivatives wrt to at least one
+      64             : /// of the elements in a matrix
+      65             :   std::vector<unsigned> matrix_row_nderivatives;
+      66             :   std::vector<std::vector<unsigned> > matrix_row_derivative_indices;
+      67             : /// This is a fudge to save on vector resizing in MultiColvar
+      68             :   std::vector<unsigned> indices, sort_indices;
+      69             :   std::vector<Vector> tmp_atoms;
+      70             :   std::vector<std::vector<Vector> > tmp_atom_der;
+      71             :   std::vector<Tensor> tmp_atom_virial;
+      72             :   std::vector<std::vector<double> > tmp_vectors;
+      73             : public:
+      74       26332 :   MultiValue( const std::size_t& nvals, const std::size_t& nder, const std::size_t& nmat=0, const std::size_t& maxcol=0, const std::size_t& nbook=0 );
+      75          36 :   void resize( const std::size_t& nvals, const std::size_t& nder, const std::size_t& nmat=0, const std::size_t& maxcol=0, const std::size_t& nbook=0 );
+      76             : /// Set the task index prior to the loop
+      77             :   void setTaskIndex( const std::size_t& tindex );
+      78             : ///
+      79             :   std::size_t getTaskIndex() const ;
+      80             : ///
+      81             :   void setSecondTaskIndex( const std::size_t& tindex );
+      82             : /// Get the task index
+      83             :   std::size_t getSecondTaskIndex() const ;
+      84             : ///
+      85             :   void setSplitIndex( const std::size_t& nat );
+      86             :   std::size_t getSplitIndex() const ;
+      87             : ///
+      88             :   void setNumberOfIndices( const std::size_t& nat );
+      89             :   std::size_t getNumberOfIndices() const ;
+      90             : ///
+      91             :   std::vector<unsigned>& getIndices();
+      92             :   std::vector<unsigned>& getSortIndices();
+      93             :   std::vector<Vector>& getAtomVector();
+      94             : /// Get the number of values in the stash
+      95             :   unsigned getNumberOfValues() const ;
+      96             : /// Get the number of derivatives in the stash
+      97             :   unsigned getNumberOfDerivatives() const ;
+      98             : /// Get references to some memory. These vectors allow us to
+      99             : /// avoid doing lots of resizing of vectors in MultiColvarTemplate
+     100             :   std::vector<Vector>& getFirstAtomVector();
+     101             :   std::vector<std::vector<Vector> >& getFirstAtomDerivativeVector();
+     102             :   const std::vector<std::vector<Vector> >& getConstFirstAtomDerivativeVector() const ;
+     103             :   std::vector<Tensor>& getFirstAtomVirialVector();
+     104             :   void resizeTemporyVector(const unsigned& n );
+     105             :   std::vector<double>& getTemporyVector(const unsigned& ind );
+     106             : ///
+     107             :   bool inVectorCall() const ;
+     108             : /// Set value numbered
+     109             :   void setValue( const std::size_t&,  const double& );
+     110             : /// Add value numbered
+     111             :   void addValue( const std::size_t&,  const double& );
+     112             : /// Add derivative
+     113             :   void addDerivative( const std::size_t&, const std::size_t&, const double& );
+     114             : /// Add to the tempory value
+     115             :   void addTemporyValue( const double& val );
+     116             : /// Add tempory derivatives - this is used for calculating quotients
+     117             :   void addTemporyDerivative( const unsigned& jder, const double& der );
+     118             : /// Set the value of the derivative
+     119             :   void setDerivative( const std::size_t& ival, const std::size_t& jder, const double& der);
+     120             : /// Return the ith value
+     121             :   double get( const std::size_t& ) const ;
+     122             : /// Return a derivative value
+     123             :   double getDerivative( const std::size_t&, const std::size_t& ) const ;
+     124             : /// Get one of the tempory derivatives
+     125             :   double getTemporyDerivative( const unsigned& jder ) const ;
+     126             : /// Clear all values
+     127             :   void clearAll( const bool& newversion=false );
+     128             : /// Clear the derivatives
+     129             :   void clearDerivatives( const unsigned& );
+     130             : /// Clear the tempory derivatives
+     131             :   void clearTemporyDerivatives();
+     132             : /// Clear a value
+     133             :   void clear( const unsigned& );
+     134             : /// Functions for accessing active list
+     135             :   bool updateComplete();
+     136             :   void emptyActiveMembers();
+     137             :   void putIndexInActiveArray( const unsigned & );
+     138             :   void updateIndex( const unsigned& );
+     139             : ///
+     140             :   void updateIndex( const std::size_t&, const std::size_t& );
+     141             : ///
+     142             :   unsigned getNumberActive( const std::size_t& ) const ;
+     143             : ///
+     144             :   unsigned getActiveIndex( const std::size_t&, const std::size_t& ) const ;
+     145             : ///
+     146             :   void clearActiveMembers( const std::size_t& ival );
+     147             :   void sortActiveList();
+     148             :   void completeUpdate();
+     149             :   void updateDynamicList();
+     150             :   bool isActive( const unsigned& ind ) const ;
+     151             : ///
+     152             :   unsigned getNumberActive() const ;
+     153             : ///
+     154             :   unsigned getActiveIndex( const unsigned& ) const ;
+     155             : /// Transfer derivatives to buffer
+     156             :   void chainRule( const unsigned&, const unsigned&, const unsigned&, const unsigned&, const double&, const unsigned&, std::vector<double>& buffer );
+     157             : ///
+     158             :   void copyValues( MultiValue& ) const ;
+     159             : ///
+     160             :   void copyDerivatives( MultiValue& );
+     161             : ///
+     162             :   void quotientRule( const unsigned& nder, const unsigned& oder );
+     163             : /// Get the matrix bookeeping array
+     164             :   const std::vector<unsigned> & getMatrixBookeeping() const ;
+     165             :   void stashMatrixElement( const unsigned& nmat, const unsigned& rowstart, const unsigned& jcol, const double& val );
+     166             :   double getStashedMatrixElement( const unsigned& nmat, const unsigned& jcol ) const ;
+     167             : /// Get the bookeeping stuff for the derivatives wrt to rows of matrix
+     168             :   void setNumberOfMatrixRowDerivatives( const unsigned& nmat, const unsigned& nind );
+     169             :   unsigned getNumberOfMatrixRowDerivatives( const unsigned& nmat ) const ;
+     170             :   std::vector<unsigned>& getMatrixRowDerivativeIndices( const unsigned& nmat );
+     171             : /// Stash the forces on the matrix
+     172             :   void addMatrixForce( const unsigned& imat, const unsigned& jind, const double& f );
+     173             :   double getStashedMatrixForce( const unsigned& imat, const unsigned& jind ) const ;
+     174             : };
+     175             : 
+     176             : inline
+     177             : unsigned MultiValue::getNumberOfValues() const {
+     178             :   return values.size();
+     179             : }
+     180             : 
+     181             : inline
+     182             : unsigned MultiValue::getNumberOfDerivatives() const {
+     183      118351 :   return nderivatives; //derivatives.ncols();
+     184             : }
+     185             : 
+     186             : inline
+     187             : double MultiValue::get( const std::size_t& ival ) const {
+     188             :   plumed_dbg_assert( ival<=values.size() );
+     189   311004047 :   return values[ival];
+     190             : }
+     191             : 
+     192             : inline
+     193             : void MultiValue::setValue( const std::size_t& ival,  const double& val) {
+     194             :   plumed_dbg_assert( ival<=values.size() );
+     195    17874821 :   values[ival]=val;
+     196             : }
+     197             : 
+     198             : inline
+     199             : void MultiValue::addValue( const std::size_t& ival,  const double& val) {
+     200             :   plumed_dbg_assert( ival<=values.size() );
+     201   187501318 :   values[ival]+=val;
+     202             : }
+     203             : 
+     204             : inline
+     205  1192882771 : void MultiValue::addDerivative( const std::size_t& ival, const std::size_t& jder, const double& der) {
+     206  1192882771 :   plumed_dbg_assert( ival<=values.size() && jder<nderivatives ); atLeastOneSet=true;
+     207  1192882771 :   hasderiv[nderivatives*ival+jder]=true; hasDerivatives.activate(jder); derivatives[nderivatives*ival+jder] += der;
+     208  1192882771 : }
+     209             : 
+     210             : inline
+     211             : void MultiValue::addTemporyValue( const double& val ) {
+     212             :   tmpval += val;
+     213             : }
+     214             : 
+     215             : inline
+     216             : void MultiValue::addTemporyDerivative( const unsigned& jder, const double& der ) {
+     217             :   plumed_dbg_assert( jder<nderivatives ); atLeastOneSet=true;
+     218             :   hasDerivatives.activate(jder); tmpder[jder] += der;
+     219             : }
+     220             : 
+     221             : 
+     222             : inline
+     223             : void MultiValue::setDerivative( const std::size_t& ival, const std::size_t& jder, const double& der) {
+     224             :   plumed_dbg_assert( ival<=values.size() && jder<nderivatives ); atLeastOneSet=true;
+     225             :   hasderiv[nderivatives*ival+jder]=true; hasDerivatives.activate(jder); derivatives[nderivatives*ival+jder]=der;
+     226             : }
+     227             : 
+     228             : 
+     229             : inline
+     230             : double MultiValue::getDerivative( const std::size_t& ival, const std::size_t& jder ) const {
+     231             :   plumed_dbg_assert( ival<values.size() && jder<nderivatives );
+     232             :   // if( !hasderiv[nderivatives*ival+jder] ) return 0.0;
+     233  1024236540 :   return derivatives[nderivatives*ival+jder];
+     234             : }
+     235             : 
+     236             : inline
+     237             : double MultiValue::getTemporyDerivative( const unsigned& jder ) const {
+     238             :   plumed_dbg_assert( jder<nderivatives && hasDerivatives.isActive(jder) );
+     239             :   return tmpder[jder];
+     240             : }
+     241             : 
+     242             : inline
+     243             : bool MultiValue::updateComplete() {
+     244             :   return hasDerivatives.updateComplete();
+     245             : }
+     246             : 
+     247             : inline
+     248             : void MultiValue::emptyActiveMembers() {
+     249             :   hasDerivatives.emptyActiveMembers();
+     250             : }
+     251             : 
+     252             : inline
+     253             : void MultiValue::putIndexInActiveArray( const unsigned& ind ) {
+     254             :   hasDerivatives.putIndexInActiveArray( ind );
+     255             : }
+     256             : 
+     257             : inline
+     258             : void MultiValue::updateIndex( const unsigned& ind ) {
+     259             :   if( hasDerivatives.isActive(ind) ) hasDerivatives.putIndexInActiveArray( ind );
+     260             : }
+     261             : 
+     262             : inline
+     263  2053353621 : void MultiValue::updateIndex( const std::size_t& ival, const std::size_t& jder ) {
+     264             :   plumed_dbg_assert( ival<values.size() && jder<nderivatives );
+     265             : #ifdef DNDEBUG
+     266             :   for(unsigned i=0; i<nactive[ival]; ++i) plumed_dbg_assert( active_list[nderivatives*ival+nactive[ival]]!=jder );
+     267             : #endif
+     268  2053353621 :   if( hasderiv[nderivatives*ival+jder] ) {
+     269             :     plumed_dbg_assert( nactive[ival]<nderivatives);
+     270   677433557 :     active_list[nderivatives*ival+nactive[ival]]=jder;
+     271   677433557 :     nactive[ival]++;
+     272             :   }
+     273  2053353621 : }
+     274             : 
+     275             : inline
+     276             : unsigned MultiValue::getNumberActive( const std::size_t& ival ) const {
+     277             :   plumed_dbg_assert( ival<nactive.size() );
+     278  1468313215 :   return nactive[ival];
+     279             : }
+     280             : 
+     281             : inline
+     282             : unsigned MultiValue::getActiveIndex( const std::size_t& ival, const std::size_t& ind ) const {
+     283             :   plumed_dbg_assert( ind<nactive[ival] );
+     284  1269708589 :   return active_list[nderivatives*ival+ind];
+     285             : }
+     286             : 
+     287             : inline
+     288             : void MultiValue::setSplitIndex( const std::size_t& nat ) {
+     289      662493 :   nsplit = nat;
+     290             : }
+     291             : 
+     292             : inline
+     293             : std::size_t MultiValue::getSplitIndex() const {
+     294   246929570 :   return nsplit;
+     295             : }
+     296             : 
+     297             : inline
+     298             : void MultiValue::setNumberOfIndices( const std::size_t& nat ) {
+     299      405876 :   nindices = nat;
+     300             : }
+     301             : 
+     302             : inline
+     303             : std::size_t MultiValue::getNumberOfIndices() const {
+     304    28540953 :   return nindices;
+     305             : }
+     306             : 
+     307             : 
+     308             : inline
+     309             : bool MultiValue::inVectorCall() const {
+     310             :   return (matrix_row_nderivatives.size()>0 && vector_call);
+     311             : }
+     312             : 
+     313             : inline
+     314             : void MultiValue::clearActiveMembers( const std::size_t& ival ) {
+     315             :   nactive[ival]=0;
+     316             : }
+     317             : 
+     318             : inline
+     319             : void MultiValue::sortActiveList() {
+     320             :   hasDerivatives.sortActiveList();
+     321             : }
+     322             : 
+     323             : inline
+     324             : void MultiValue::completeUpdate() {
+     325             :   hasDerivatives.completeUpdate();
+     326             : }
+     327             : 
+     328             : inline
+     329             : unsigned MultiValue::getNumberActive() const {
+     330             :   return hasDerivatives.getNumberActive();
+     331             : }
+     332             : 
+     333             : inline
+     334             : unsigned MultiValue::getActiveIndex( const unsigned& ind ) const {
+     335             :   plumed_dbg_assert( ind<hasDerivatives.getNumberActive() );
+     336             :   return hasDerivatives[ind];
+     337             : }
+     338             : 
+     339             : inline
+     340             : void MultiValue::setTaskIndex( const std::size_t& tindex ) {
+     341    98287010 :   task_index = tindex;
+     342             : }
+     343             : 
+     344             : inline
+     345             : std::size_t MultiValue::getTaskIndex() const {
+     346    17449808 :   return task_index;
+     347             : }
+     348             : 
+     349             : inline
+     350             : void MultiValue::setSecondTaskIndex( const std::size_t& tindex ) {
+     351    88127811 :   task2_index = tindex;
+     352             : }
+     353             : 
+     354             : inline
+     355             : std::size_t MultiValue::getSecondTaskIndex() const {
+     356     6403164 :   return task2_index;
+     357             : }
+     358             : 
+     359             : 
+     360             : inline
+     361             : void MultiValue::updateDynamicList() {
+     362             :   if( atLeastOneSet ) hasDerivatives.updateActiveMembers();
+     363             : }
+     364             : 
+     365             : inline
+     366             : std::vector<unsigned>& MultiValue::getIndices() {
+     367     1378263 :   return indices;
+     368             : }
+     369             : 
+     370             : inline
+     371             : std::vector<unsigned>& MultiValue::getSortIndices() {
+     372             :   return sort_indices;
+     373             : }
+     374             : 
+     375             : inline
+     376             : std::vector<Vector>& MultiValue::getAtomVector() {
+     377      405876 :   return tmp_atoms;
+     378             : }
+     379             : 
+     380             : inline
+     381             : bool MultiValue::isActive( const unsigned& ind ) const {
+     382             :   return hasDerivatives.isActive( ind );
+     383             : }
+     384             : 
+     385             : inline
+     386             : std::vector<Vector>& MultiValue::getFirstAtomVector() {
+     387      670728 :   return tmp_atoms;
+     388             : }
+     389             : 
+     390             : inline
+     391             : std::vector<std::vector<Vector> >& MultiValue::getFirstAtomDerivativeVector() {
+     392     1076604 :   return tmp_atom_der;
+     393             : }
+     394             : 
+     395             : inline
+     396             : const std::vector<std::vector<Vector> >& MultiValue::getConstFirstAtomDerivativeVector() const {
+     397             :   return tmp_atom_der;
+     398             : }
+     399             : 
+     400             : inline
+     401             : std::vector<Tensor>& MultiValue::getFirstAtomVirialVector() {
+     402      490140 :   return tmp_atom_virial;
+     403             : }
+     404             : 
+     405             : inline
+     406      490140 : void MultiValue::resizeTemporyVector(const unsigned& n ) {
+     407      490140 :   if( n>tmp_vectors.size() ) tmp_vectors.resize(n);
+     408      490140 : }
+     409             : 
+     410             : inline
+     411             : std::vector<double>& MultiValue::getTemporyVector(const unsigned& ind ) {
+     412             :   plumed_dbg_assert( ind<tmp_vectors.size() );
+     413             :   return tmp_vectors[ind];
+     414             : }
+     415             : 
+     416             : inline
+     417     8280289 : void MultiValue::stashMatrixElement( const unsigned& nmat, const unsigned& rowstart, const unsigned& jcol, const double& val ) {
+     418             :   plumed_dbg_assert( jcol<nmatrix_cols && rowstart + matrix_bookeeping[rowstart]<matrix_bookeeping.size() && nmatrix_cols*nmat + matrix_bookeeping[rowstart]<matrix_row_stash.size() );
+     419     8280289 :   matrix_bookeeping[rowstart]++; matrix_bookeeping[rowstart + matrix_bookeeping[rowstart]]=jcol; matrix_row_stash[ nmatrix_cols*nmat + jcol] = val;
+     420     8280289 : }
+     421             : 
+     422             : inline
+     423             : double MultiValue::getStashedMatrixElement( const unsigned& nmat, const unsigned& jcol ) const {
+     424             :   plumed_dbg_assert( nmatrix_cols*nmat + jcol<matrix_row_stash.size() );
+     425     6887434 :   return matrix_row_stash[ nmatrix_cols*nmat + jcol ];
+     426             : }
+     427             : 
+     428             : inline
+     429             : const std::vector<unsigned> & MultiValue::getMatrixBookeeping() const {
+     430             :   return matrix_bookeeping;
+     431             : }
+     432             : 
+     433             : inline
+     434             : void MultiValue::setNumberOfMatrixRowDerivatives( const unsigned& nmat, const unsigned& nind ) {
+     435             :   plumed_dbg_assert( nmat<matrix_row_nderivatives.size() && nind<=matrix_row_derivative_indices[nmat].size() );
+     436    12992400 :   matrix_row_nderivatives[nmat]=nind;
+     437             : }
+     438             : 
+     439             : inline
+     440             : unsigned MultiValue::getNumberOfMatrixRowDerivatives( const unsigned& nmat ) const {
+     441   108296955 :   plumed_dbg_assert( nmat<matrix_row_nderivatives.size() ); return matrix_row_nderivatives[nmat];
+     442             : }
+     443             : 
+     444             : inline
+     445             : std::vector<unsigned>& MultiValue::getMatrixRowDerivativeIndices( const unsigned& nmat ) {
+     446     1978950 :   plumed_dbg_assert( nmat<matrix_row_nderivatives.size() ); return matrix_row_derivative_indices[nmat];
+     447             : }
+     448             : 
+     449             : inline
+     450             : void MultiValue::addMatrixForce( const unsigned& imat, const unsigned& jind, const double& f ) {
+     451    34492675 :   matrix_force_stash[imat*nderivatives + jind]+=f;
+     452             : }
+     453             : 
+     454             : inline
+     455             : double MultiValue::getStashedMatrixForce( const unsigned& imat, const unsigned& jind ) const {
+     456   842633458 :   return matrix_force_stash[imat*nderivatives + jind];
+     457             : }
+     458             : 
+     459             : }
+     460             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/NeighborList.cpp.func-sort-c.html b/coverage/tools/NeighborList.cpp.func-sort-c.html new file mode 100644 index 000000000000..cbf7c7d687f9 --- /dev/null +++ b/coverage/tools/NeighborList.cpp.func-sort-c.html @@ -0,0 +1,137 @@ + + + + + + + + LCOV - plumed test coverage - tools/NeighborList.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - NeighborList.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11812991.5 %
Date:2024-04-19 12:12:35Functions:141687.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12NeighborList12getNeighborsEj0
_ZN4PLMD12NeighborList13setLastUpdateEj0
_ZNK4PLMD12NeighborList13getLastUpdateEv24
_ZN4PLMD12NeighborListC2ERKSt6vectorINS_10AtomNumberESaIS2_EERKbS8_RKNS_3PbcERNS_12CommunicatorERKdRKj44
_ZN4PLMD12NeighborList18getReducedAtomListEv240
_ZN4PLMD12NeighborListC2ERKSt6vectorINS_10AtomNumberESaIS2_EES6_RKbS8_S8_RKNS_3PbcERNS_12CommunicatorERKdRKj300
_ZN4PLMD12NeighborListD2Ev342
_ZN4PLMD12NeighborList10initializeEv344
_ZN4PLMD12NeighborList14setRequestListEv3138
_ZN4PLMD12NeighborList6updateERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EE3138
_ZNK4PLMD12NeighborList9getStrideEv14950
_ZN4PLMD12NeighborList15getFullAtomListEv70008
_ZNK4PLMD12NeighborList4sizeEv23715425
_ZNK4PLMD12NeighborList22getClosePairAtomNumberEj34665936
_ZN4PLMD12NeighborList12getIndexPairEj234387479
_ZNK4PLMD12NeighborList12getClosePairEj262118600
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/NeighborList.cpp.func.html b/coverage/tools/NeighborList.cpp.func.html new file mode 100644 index 000000000000..21e8534b06bf --- /dev/null +++ b/coverage/tools/NeighborList.cpp.func.html @@ -0,0 +1,137 @@ + + + + + + + + LCOV - plumed test coverage - tools/NeighborList.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - NeighborList.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11812991.5 %
Date:2024-04-19 12:12:35Functions:141687.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12NeighborList10initializeEv344
_ZN4PLMD12NeighborList12getIndexPairEj234387479
_ZN4PLMD12NeighborList12getNeighborsEj0
_ZN4PLMD12NeighborList13setLastUpdateEj0
_ZN4PLMD12NeighborList14setRequestListEv3138
_ZN4PLMD12NeighborList15getFullAtomListEv70008
_ZN4PLMD12NeighborList18getReducedAtomListEv240
_ZN4PLMD12NeighborList6updateERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EE3138
_ZN4PLMD12NeighborListC2ERKSt6vectorINS_10AtomNumberESaIS2_EERKbS8_RKNS_3PbcERNS_12CommunicatorERKdRKj44
_ZN4PLMD12NeighborListC2ERKSt6vectorINS_10AtomNumberESaIS2_EES6_RKbS8_S8_RKNS_3PbcERNS_12CommunicatorERKdRKj300
_ZN4PLMD12NeighborListD2Ev342
_ZNK4PLMD12NeighborList12getClosePairEj262118600
_ZNK4PLMD12NeighborList13getLastUpdateEv24
_ZNK4PLMD12NeighborList22getClosePairAtomNumberEj34665936
_ZNK4PLMD12NeighborList4sizeEv23715425
_ZNK4PLMD12NeighborList9getStrideEv14950
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/NeighborList.cpp.gcov.html b/coverage/tools/NeighborList.cpp.gcov.html new file mode 100644 index 000000000000..15ffe5436d5d --- /dev/null +++ b/coverage/tools/NeighborList.cpp.gcov.html @@ -0,0 +1,371 @@ + + + + + + + + LCOV - plumed test coverage - tools/NeighborList.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - NeighborList.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11812991.5 %
Date:2024-04-19 12:12:35Functions:141687.5 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "NeighborList.h"
+      23             : #include "Vector.h"
+      24             : #include "Pbc.h"
+      25             : #include "AtomNumber.h"
+      26             : #include "Communicator.h"
+      27             : #include "OpenMP.h"
+      28             : #include "Tools.h"
+      29             : #include <vector>
+      30             : #include <algorithm>
+      31             : #include <numeric>
+      32             : 
+      33             : #ifdef __APPLE__
+      34             : //we are using getenv to give the user the opporunity of suppressing
+      35             : //the too many memory killswitch while compiling on mac
+      36             : #include <cstdlib>
+      37             : #endif //__APPLE__
+      38             : namespace PLMD {
+      39             : 
+      40         300 : NeighborList::NeighborList(const std::vector<AtomNumber>& list0,
+      41             :                            const std::vector<AtomNumber>& list1,
+      42             :                            const bool& serial,
+      43             :                            const bool& do_pair,
+      44             :                            const bool& do_pbc,
+      45             :                            const Pbc& pbc,
+      46             :                            Communicator& cm,
+      47             :                            const double& distance,
+      48         300 :                            const unsigned& stride)
+      49         300 :   : reduced(false),
+      50         300 :     serial_(serial),
+      51         300 :     do_pair_(do_pair),
+      52         300 :     do_pbc_(do_pbc),
+      53         300 :     twolists_(true),
+      54         300 :     pbc_(&pbc),
+      55         300 :     comm(cm),
+      56             :     //copy-initialize fullatomlist_
+      57         300 :     fullatomlist_(list0),
+      58         300 :     distance_(distance),
+      59         300 :     nlist0_(list0.size()),
+      60         300 :     nlist1_(list1.size()),
+      61         300 :     stride_(stride) {
+      62             :   // store the rest of the atoms into fullatomlist_
+      63         301 :   fullatomlist_.insert(fullatomlist_.end(),list1.begin(),list1.end());
+      64         300 :   if(!do_pair) {
+      65         271 :     nallpairs_=nlist0_*nlist1_;
+      66             :   } else {
+      67          29 :     plumed_assert(nlist0_==nlist1_)
+      68             :         << "when using PAIR option, the two groups should have the same number"
+      69             :         " of elements\n" << "the groups you specified have size "
+      70           0 :         <<nlist0_<<" and "<<nlist1_;
+      71          29 :     nallpairs_=nlist0_;
+      72             :   }
+      73         300 :   initialize();
+      74         299 : }
+      75             : 
+      76          44 : NeighborList::NeighborList(const std::vector<AtomNumber>& list0,
+      77             :                            const bool& serial, const bool& do_pbc,
+      78             :                            const Pbc& pbc,
+      79             :                            Communicator& cm,
+      80             :                            const double& distance,
+      81          44 :                            const unsigned& stride)
+      82          44 :   : reduced(false),
+      83          44 :     serial_(serial),
+      84          44 :     do_pbc_(do_pbc),
+      85          44 :     twolists_(false),
+      86          44 :     pbc_(&pbc),
+      87          44 :     comm(cm),
+      88             :     //copy-initialize fullatomlist_
+      89          44 :     fullatomlist_(list0),
+      90          44 :     distance_(distance),
+      91          44 :     nlist0_(list0.size()),
+      92          44 :     nallpairs_(nlist0_*(nlist0_-1)/2),
+      93          44 :     stride_(stride) {
+      94          44 :   initialize();
+      95          43 : }
+      96             : 
+      97         342 : NeighborList::~NeighborList()=default;
+      98             : 
+      99         344 : void NeighborList::initialize() {
+     100             : #ifdef __APPLE__
+     101             :   //this mac-only error is here because on my experience the mac tries to page
+     102             :   //the memory on the hdd instead of throwing a memory error
+     103             :   if(!std::getenv("PLUMED_IGNORE_NL_MEMORY_ERROR")) {
+     104             :     //blocking memory allocation on slightly more than 10 GB of memory
+     105             :     //that is about 1296000000 pairs (36000 atoms)
+     106             :     //36000 * 36000= 1296000000
+     107             :     //each pairIDs occupies 64 bit (where unsigned are 32bit integers)
+     108             :     //4294967296 is max(uint32)+1 and is more than 34 GB (correspond to a system of 65536 atoms)
+     109             :     if(nallpairs_ > 1296000000 )
+     110             :       plumed_merror("An error happened while allocating the neighbor "
+     111             :                     "list, please decrease the number of atoms used");
+     112             :   }
+     113             : #endif // __APPLE__
+     114             :   try {
+     115         344 :     neighbors_.resize(nallpairs_);
+     116           2 :   } catch (...) {
+     117           4 :     plumed_error_nested() << "An error happened while allocating the neighbor "
+     118             :                           "list, please decrease the number of atoms used";
+     119           2 :   }
+     120             :   //TODO: test if this is feasible for accelerating the loop
+     121             :   //#pragma omp parallel for default(shared)
+     122   228150101 :   for(unsigned int i=0; i<nallpairs_; ++i)
+     123   228149759 :     neighbors_[i]=getIndexPair(i);
+     124         342 : }
+     125             : 
+     126       70008 : std::vector<AtomNumber>& NeighborList::getFullAtomList() {
+     127       70008 :   return fullatomlist_;
+     128             : }
+     129             : 
+     130   234387479 : NeighborList::pairIDs NeighborList::getIndexPair(const unsigned ipair) {
+     131             :   pairIDs index;
+     132   234387479 :   if(twolists_ && do_pair_)
+     133       12236 :     index=pairIDs(ipair,ipair+nlist0_);
+     134   234375243 :   else if (twolists_ && !do_pair_)
+     135   143426597 :     index=pairIDs(ipair/nlist1_,ipair%nlist1_+nlist0_);
+     136    90948646 :   else if (!twolists_) {
+     137    90948646 :     unsigned ii = nallpairs_-1-ipair;
+     138    90948646 :     unsigned  K = unsigned(std::floor((std::sqrt(double(8*ii+1))+1)/2));
+     139    90948646 :     unsigned jj = ii-K*(K-1)/2;
+     140    90948646 :     index=pairIDs(nlist0_-1-K,nlist0_-1-jj);
+     141             :   }
+     142   234387479 :   return index;
+     143             : }
+     144             : 
+     145        3138 : void NeighborList::update(const std::vector<Vector>& positions) {
+     146        3138 :   neighbors_.clear();
+     147        3138 :   const double d2=distance_*distance_;
+     148             :   // check if positions array has the correct length
+     149        3138 :   plumed_assert(positions.size()==fullatomlist_.size());
+     150             : 
+     151        3138 :   unsigned stride=comm.Get_size();
+     152        3138 :   unsigned rank=comm.Get_rank();
+     153        3138 :   unsigned nt=OpenMP::getNumThreads();
+     154        3138 :   if(serial_) {
+     155             :     stride=1;
+     156             :     rank=0;
+     157             :     nt=1;
+     158             :   }
+     159             :   std::vector<unsigned> local_flat_nl;
+     160             : 
+     161        3138 :   #pragma omp parallel num_threads(nt)
+     162             :   {
+     163             :     std::vector<unsigned> private_flat_nl;
+     164             :     #pragma omp for nowait
+     165             :     for(unsigned int i=rank; i<nallpairs_; i+=stride) {
+     166             :       pairIDs index=getIndexPair(i);
+     167             :       unsigned index0=index.first;
+     168             :       unsigned index1=index.second;
+     169             :       Vector distance;
+     170             :       if(do_pbc_) {
+     171             :         distance=pbc_->distance(positions[index0],positions[index1]);
+     172             :       } else {
+     173             :         distance=delta(positions[index0],positions[index1]);
+     174             :       }
+     175             :       double value=modulo2(distance);
+     176             :       if(value<=d2) {
+     177             :         private_flat_nl.push_back(index0);
+     178             :         private_flat_nl.push_back(index1);
+     179             :       }
+     180             :     }
+     181             :     #pragma omp critical
+     182             :     local_flat_nl.insert(local_flat_nl.end(),
+     183             :                          private_flat_nl.begin(),
+     184             :                          private_flat_nl.end());
+     185             :   }
+     186             : 
+     187             :   // find total dimension of neighborlist
+     188        3138 :   std::vector <int> local_nl_size(stride, 0);
+     189        3138 :   local_nl_size[rank] = local_flat_nl.size();
+     190        3138 :   if(!serial_)
+     191        3126 :     comm.Sum(&local_nl_size[0], stride);
+     192             :   int tot_size = std::accumulate(local_nl_size.begin(), local_nl_size.end(), 0);
+     193        3138 :   if(tot_size==0) {
+     194          18 :     setRequestList();
+     195             :     return;
+     196             :   }
+     197             :   // merge
+     198        3120 :   std::vector<unsigned> merge_nl(tot_size, 0);
+     199             :   // calculate vector of displacement
+     200        3120 :   std::vector<int> disp(stride);
+     201        3120 :   disp[0] = 0;
+     202             :   int rank_size = 0;
+     203        9216 :   for(unsigned i=0; i<stride-1; ++i) {
+     204        6096 :     rank_size += local_nl_size[i];
+     205        6096 :     disp[i+1] = rank_size;
+     206             :   }
+     207             :   // Allgather neighbor list
+     208        3120 :   if(comm.initialized()&&!serial_) {
+     209        4181 :     comm.Allgatherv((!local_flat_nl.empty()?&local_flat_nl[0]:NULL),
+     210             :                     local_nl_size[rank],
+     211             :                     &merge_nl[0],
+     212             :                     &local_nl_size[0],
+     213             :                     &disp[0]);
+     214             :   } else
+     215        1016 :     merge_nl = local_flat_nl;
+     216             :   // resize neighbor stuff
+     217        3120 :   neighbors_.resize(tot_size/2);
+     218     6114036 :   for(unsigned i=0; i<tot_size/2; i++) {
+     219     6110916 :     unsigned j=2*i;
+     220     6110916 :     neighbors_[i] = std::make_pair(merge_nl[j],merge_nl[j+1]);
+     221             :   }
+     222             : 
+     223        3120 :   setRequestList();
+     224             : }
+     225             : 
+     226        3138 : void NeighborList::setRequestList() {
+     227        3138 :   requestlist_.clear();
+     228     6114054 :   for(unsigned int i=0; i<size(); ++i) {
+     229     6110916 :     requestlist_.push_back(fullatomlist_[neighbors_[i].first]);
+     230     6110916 :     requestlist_.push_back(fullatomlist_[neighbors_[i].second]);
+     231             :   }
+     232        3138 :   Tools::removeDuplicates(requestlist_);
+     233        3138 :   reduced=false;
+     234        3138 : }
+     235             : 
+     236         240 : std::vector<AtomNumber>& NeighborList::getReducedAtomList() {
+     237         240 :   if(!reduced) {
+     238      168162 :     for(unsigned int i=0; i<size(); ++i) {
+     239      168119 :       AtomNumber index0=fullatomlist_[neighbors_[i].first];
+     240      168119 :       AtomNumber index1=fullatomlist_[neighbors_[i].second];
+     241             : // I exploit the fact that requestlist_ is an ordered vector
+     242      168119 :       auto p = std::find(requestlist_.begin(), requestlist_.end(), index0);
+     243             :       plumed_dbg_assert(p!=requestlist_.end());
+     244      168119 :       unsigned newindex0=p-requestlist_.begin();
+     245      168119 :       p = std::find(requestlist_.begin(), requestlist_.end(), index1);
+     246             :       plumed_dbg_assert(p!=requestlist_.end());
+     247      168119 :       unsigned newindex1=p-requestlist_.begin();
+     248             :       neighbors_[i]=pairIDs(newindex0,newindex1);
+     249             :     }
+     250             :   }
+     251         240 :   reduced=true;
+     252         240 :   return requestlist_;
+     253             : }
+     254             : 
+     255       14950 : unsigned NeighborList::getStride() const {
+     256       14950 :   return stride_;
+     257             : }
+     258             : 
+     259          24 : unsigned NeighborList::getLastUpdate() const {
+     260          24 :   return lastupdate_;
+     261             : }
+     262             : 
+     263           0 : void NeighborList::setLastUpdate(const unsigned step) {
+     264           0 :   lastupdate_=step;
+     265           0 : }
+     266             : 
+     267    23715425 : unsigned NeighborList::size() const {
+     268    23715425 :   return neighbors_.size();
+     269             : }
+     270             : 
+     271   262118600 : NeighborList::pairIDs NeighborList::getClosePair(const unsigned i) const {
+     272   262118600 :   return neighbors_[i];
+     273             : }
+     274             : 
+     275             : NeighborList::pairAtomNumbers
+     276    34665936 : NeighborList::getClosePairAtomNumber(const unsigned i) const {
+     277             :   pairAtomNumbers Aneigh=pairAtomNumbers(
+     278    34665936 :                            fullatomlist_[neighbors_[i].first],
+     279    34665936 :                            fullatomlist_[neighbors_[i].second]);
+     280    34665936 :   return Aneigh;
+     281             : }
+     282             : 
+     283           0 : std::vector<unsigned> NeighborList::getNeighbors(const unsigned index) {
+     284             :   std::vector<unsigned> neighbors;
+     285           0 :   for(unsigned int i=0; i<size(); ++i) {
+     286           0 :     if(neighbors_[i].first==index)
+     287           0 :       neighbors.push_back(neighbors_[i].second);
+     288           0 :     if(neighbors_[i].second==index)
+     289           0 :       neighbors.push_back(neighbors_[i].first);
+     290             :   }
+     291           0 :   return neighbors;
+     292             : }
+     293             : 
+     294             : } // namespace PLMD
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/NeighborList.h.func-sort-c.html b/coverage/tools/NeighborList.h.func-sort-c.html new file mode 100644 index 000000000000..0c143790d4a8 --- /dev/null +++ b/coverage/tools/NeighborList.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage - tools/NeighborList.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - NeighborList.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:44100.0 %
Date:2024-04-19 12:12:35Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/NeighborList.h.func.html b/coverage/tools/NeighborList.h.func.html new file mode 100644 index 000000000000..b12f557c0c85 --- /dev/null +++ b/coverage/tools/NeighborList.h.func.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage - tools/NeighborList.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - NeighborList.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:44100.0 %
Date:2024-04-19 12:12:35Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/NeighborList.h.gcov.html b/coverage/tools/NeighborList.h.gcov.html new file mode 100644 index 000000000000..f57e84b5b55c --- /dev/null +++ b/coverage/tools/NeighborList.h.gcov.html @@ -0,0 +1,189 @@ + + + + + + + + LCOV - plumed test coverage - tools/NeighborList.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - NeighborList.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:44100.0 %
Date:2024-04-19 12:12:35Functions:00-
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_tools_NeighborList_h //{
+      23             : #define __PLUMED_tools_NeighborList_h
+      24             : 
+      25             : #include "Vector.h"
+      26             : #include "AtomNumber.h"
+      27             : 
+      28             : #include <vector>
+      29             : 
+      30             : namespace PLMD {
+      31             : 
+      32             : class Pbc;
+      33             : class Communicator;
+      34             : 
+      35             : /// \ingroup TOOLBOX
+      36             : /// A class that implements neighbor lists from two lists or a single list of atoms
+      37             : class NeighborList {
+      38             : public:
+      39             :   using pairIDs=std::pair<unsigned,unsigned>;
+      40             :   using pairAtomNumbers=std::pair<PLMD::AtomNumber,PLMD::AtomNumber>;
+      41             : private:
+      42             :   bool reduced=false;
+      43             :   bool serial_;
+      44             :   bool do_pair_;
+      45             :   bool do_pbc_;
+      46             :   bool twolists_;
+      47             :   const PLMD::Pbc* pbc_;
+      48             :   Communicator& comm;
+      49             :   std::vector<PLMD::AtomNumber> fullatomlist_{};
+      50             :   std::vector<PLMD::AtomNumber> requestlist_{};
+      51             :   std::vector<pairIDs > neighbors_{};
+      52             :   double distance_;
+      53             :   size_t nlist0_=0;
+      54             :   size_t nlist1_=0;
+      55             :   size_t nallpairs_;
+      56             :   unsigned stride_=0;
+      57             :   unsigned lastupdate_=0;
+      58             : /// Initialize the neighbor list with all possible pairs
+      59             :   void initialize();
+      60             : /// Return the pair of indexes in the positions array
+      61             : /// of the two atoms forming the i-th pair among all possible pairs
+      62             :   pairIDs getIndexPair(unsigned i);
+      63             : /// Extract the list of atoms from the current list of close pairs
+      64             :   void setRequestList();
+      65             : public:
+      66             :   NeighborList(const std::vector<PLMD::AtomNumber>& list0,
+      67             :                const std::vector<PLMD::AtomNumber>& list1,
+      68             :                const bool& serial,
+      69             :                const bool& do_pair,
+      70             :                const bool& do_pbc,
+      71             :                const PLMD::Pbc& pbc,
+      72             :                Communicator &cm,
+      73         456 :                const double& distance=1.0e+30,
+      74         456 :                const unsigned& stride=0);
+      75             :   NeighborList(const std::vector<PLMD::AtomNumber>& list0,
+      76             :                const bool& serial,
+      77             :                const bool& do_pbc,
+      78             :                const PLMD::Pbc& pbc,
+      79             :                Communicator &cm,
+      80          22 :                const double& distance=1.0e+30,
+      81          22 :                const unsigned& stride=0);
+      82             :   ~NeighborList();
+      83             : /// Return the list of all atoms. These are needed to rebuild the neighbor list.
+      84             :   std::vector<PLMD::AtomNumber>& getFullAtomList();
+      85             : /// Update the indexes in the neighbor list to match the
+      86             : /// ordering in the new positions array
+      87             : /// and return the new list of atoms that must be requested to the main code
+      88             :   std::vector<PLMD::AtomNumber>& getReducedAtomList();
+      89             : /// Update the neighbor list and prepare the new
+      90             : /// list of atoms that will be requested to the main code
+      91             :   void update(const std::vector<PLMD::Vector>& positions);
+      92             : /// Get the update stride of the neighbor list
+      93             :   unsigned getStride() const;
+      94             : /// Get the last step in which the neighbor list was updated
+      95             :   unsigned getLastUpdate() const;
+      96             : /// Set the step of the last update
+      97             :   void setLastUpdate(unsigned step);
+      98             : /// Get the size of the neighbor list
+      99             :   unsigned size() const;
+     100             : /// Get the distance used to create the neighbor list
+     101             :   double distance() const;
+     102             : /// Get the i-th pair of the neighbor list
+     103             :   pairIDs getClosePair(unsigned i) const;
+     104             : /// Get the list of neighbors of the i-th atom
+     105             :   std::vector<unsigned> getNeighbors(unsigned i);
+     106             : /// Get the i-th pair of AtomNumbers from the neighbor list
+     107             :   pairAtomNumbers getClosePairAtomNumber(unsigned i) const;
+     108             : };
+     109             : 
+     110             : } // namespace PLMD
+     111             : 
+     112             : #endif //__PLUMED_tools_NeighborList_h }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/OFile.cpp.func-sort-c.html b/coverage/tools/OFile.cpp.func-sort-c.html new file mode 100644 index 000000000000..bb8d6e3e4365 --- /dev/null +++ b/coverage/tools/OFile.cpp.func-sort-c.html @@ -0,0 +1,193 @@ + + + + + + + + LCOV - plumed test coverage - tools/OFile.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - OFile.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:21022792.5 %
Date:2024-04-19 12:12:35Functions:283093.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5OFile10printFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEx0
_ZN4PLMD5OFile14backupAllFilesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD5OFile10printFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEl1
_ZN4PLMD5OFile10printFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEm1
_ZN4PLMD5OFile14enforceRestartEv11
_ZN4PLMD5OFile4linkERS0_11
_ZN4PLMD5OFile10printFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEj31
_ZN4PLMD5OFile10printFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEy47
_ZN4PLMD5OFile6rewindEv135
_ZN4PLMD5OFile15setBackupStringERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE194
_ZN4PLMD5OFile13enforceBackupEv1144
_ZN4PLMD5OFile11clearFieldsEv3202
_ZN4PLMD5OFile10backupFileERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_3619
_ZN4PLMD5OFile4openERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3912
_ZNK4PLMD5OFile12checkRestartEv3912
_ZN4PLMD5OFileC1Ev5019
_ZN4PLMD5OFile15setupPrintValueEPNS_5ValueE6478
_ZN4PLMD5OFile10printFieldEPNS_5ValueERKd7274
_ZN4PLMD5OFile5flushEv9194
_ZN4PLMD5OFile16addConstantFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE28062
_ZN4PLMD5OFile13setLinePrefixERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE806370
_ZN4PLMD5OFileC2Ev806370
_ZN4PLMD5OFile8fmtFieldEv817260
_ZN4PLMD5OFile10printFieldEv3796546
_ZN4PLMD5OFile7llwriteEPKcm5730756
_ZN4PLMD5OFile10printFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEi6095847
_ZN4PLMD5OFile8fmtFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE13881866
_ZN4PLMD5OFile10printFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEd15375278
_ZN4PLMD5OFile6printfEPKcz24394113
_ZN4PLMD5OFile10printFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_38092461
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/OFile.cpp.func.html b/coverage/tools/OFile.cpp.func.html new file mode 100644 index 000000000000..5e3736c22d39 --- /dev/null +++ b/coverage/tools/OFile.cpp.func.html @@ -0,0 +1,193 @@ + + + + + + + + LCOV - plumed test coverage - tools/OFile.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - OFile.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:21022792.5 %
Date:2024-04-19 12:12:35Functions:283093.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5OFile10backupFileERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_3619
_ZN4PLMD5OFile10printFieldEPNS_5ValueERKd7274
_ZN4PLMD5OFile10printFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_38092461
_ZN4PLMD5OFile10printFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEd15375278
_ZN4PLMD5OFile10printFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEi6095847
_ZN4PLMD5OFile10printFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEj31
_ZN4PLMD5OFile10printFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEl1
_ZN4PLMD5OFile10printFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEm1
_ZN4PLMD5OFile10printFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEx0
_ZN4PLMD5OFile10printFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEy47
_ZN4PLMD5OFile10printFieldEv3796546
_ZN4PLMD5OFile11clearFieldsEv3202
_ZN4PLMD5OFile13enforceBackupEv1144
_ZN4PLMD5OFile13setLinePrefixERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE806370
_ZN4PLMD5OFile14backupAllFilesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD5OFile14enforceRestartEv11
_ZN4PLMD5OFile15setBackupStringERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE194
_ZN4PLMD5OFile15setupPrintValueEPNS_5ValueE6478
_ZN4PLMD5OFile16addConstantFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE28062
_ZN4PLMD5OFile4linkERS0_11
_ZN4PLMD5OFile4openERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3912
_ZN4PLMD5OFile5flushEv9194
_ZN4PLMD5OFile6printfEPKcz24394113
_ZN4PLMD5OFile6rewindEv135
_ZN4PLMD5OFile7llwriteEPKcm5730756
_ZN4PLMD5OFile8fmtFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE13881866
_ZN4PLMD5OFile8fmtFieldEv817260
_ZN4PLMD5OFileC1Ev5019
_ZN4PLMD5OFileC2Ev806370
_ZNK4PLMD5OFile12checkRestartEv3912
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/OFile.cpp.gcov.html b/coverage/tools/OFile.cpp.gcov.html new file mode 100644 index 000000000000..4dd0f67b585f --- /dev/null +++ b/coverage/tools/OFile.cpp.gcov.html @@ -0,0 +1,513 @@ + + + + + + + + LCOV - plumed test coverage - tools/OFile.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - OFile.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:21022792.5 %
Date:2024-04-19 12:12:35Functions:283093.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 "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     5730756 : size_t OFile::llwrite(const char*ptr,size_t s) {
+      47             :   size_t r;
+      48     5730756 :   if(linked) return linked->llwrite(ptr,s);
+      49     5730704 :   if(! (comm && comm->Get_rank()>0)) {
+      50     4879188 :     if(!fp) plumed_merror("writing on uninitialized File");
+      51     4879188 :     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     4877925 :       r=std::fwrite(ptr,1,s,fp);
+      59             :     }
+      60             :   }
+      61     5730704 :   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     4868677 :     comm->Barrier();
+      69     4868677 :     comm->Bcast(r,0);
+      70             :   }
+      71             : 
+      72     5730704 :   return r;
+      73             : }
+      74             : 
+      75      811389 : OFile::OFile():
+      76      811389 :   linked(NULL),
+      77      811389 :   fieldChanged(false),
+      78      811389 :   backstring("bck"),
+      79      811389 :   enforceRestart_(false),
+      80      811389 :   enforceBackup_(false)
+      81             : {
+      82      811389 :   fmtField();
+      83      811389 :   buflen=1;
+      84      811389 :   actual_buffer_length=0;
+      85      811389 :   buffer.resize(buflen);
+      86             : // these are set to zero to avoid valgrind errors
+      87     1622778 :   for(int i=0; i<buflen; ++i) buffer[i]=0;
+      88             : // these are set to zero to avoid valgrind errors
+      89      811389 :   buffer_string.resize(1000,0);
+      90      811389 : }
+      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      806370 : OFile& OFile::setLinePrefix(const std::string&l) {
+     100      806370 :   linePrefix=l;
+     101      806370 :   return *this;
+     102             : }
+     103             : 
+     104    24394113 : int OFile::printf(const char*fmt,...) {
+     105             :   va_list arg;
+     106    24394113 :   va_start(arg, fmt);
+     107    24394113 :   int r=std::vsnprintf(&buffer[actual_buffer_length],buflen-actual_buffer_length,fmt,arg);
+     108    24394113 :   va_end(arg);
+     109    24394113 :   if(r>=buflen-actual_buffer_length) {
+     110             :     int newlen=buflen;
+     111       52799 :     while(newlen<=r+actual_buffer_length) newlen*=2;
+     112       17591 :     std::vector<char> newbuf(newlen);
+     113       17591 :     std::memmove(newbuf.data(),buffer.data(),buflen);
+     114    13733426 :     for(int k=buflen; k<newlen; k++) newbuf[k]=0;
+     115             :     std::swap(buffer,newbuf);
+     116       17591 :     buflen=newlen;
+     117             :     va_list arg;
+     118       17591 :     va_start(arg, fmt);
+     119       17591 :     r=std::vsnprintf(&buffer[actual_buffer_length],buflen-actual_buffer_length,fmt,arg);
+     120       17591 :     va_end(arg);
+     121             :   }
+     122    24394113 :   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    24394113 :   char*psearch=p1+actual_buffer_length;
+     129    24394113 :   actual_buffer_length+=r;
+     130    29679090 :   while((p2=std::strchr(psearch,'\n'))) {
+     131     5284977 :     if(linePrefix.length()>0) llwrite(linePrefix.c_str(),linePrefix.length());
+     132     5284977 :     llwrite(p1,p2-p1+1);
+     133     5284977 :     actual_buffer_length-=(p2-p1)+1;
+     134     5284977 :     p1=p2+1;
+     135             :     psearch=p1;
+     136             :   };
+     137    24394113 :   if(buffer.data()!=p1) std::memmove(buffer.data(),p1,actual_buffer_length);
+     138    24394113 :   return r;
+     139             : }
+     140             : 
+     141       28062 : OFile& OFile::addConstantField(const std::string&name) {
+     142             :   Field f;
+     143             :   f.name=name;
+     144       28062 :   const_fields.push_back(f);
+     145       28062 :   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    13881866 : OFile& OFile::fmtField(const std::string&fmt) {
+     157    13881866 :   this->fieldFmt=fmt;
+     158    13881866 :   return *this;
+     159             : }
+     160             : 
+     161      817260 : OFile& OFile::fmtField() {
+     162      817260 :   this->fieldFmt="%23.16lg";
+     163      817260 :   return *this;
+     164             : }
+     165             : 
+     166    15375278 : 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    15375278 :   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    15375278 :   printField(name,buffer_string.data());
+     173    15375278 :   return *this;
+     174             : }
+     175             : 
+     176     6095847 : OFile& OFile::printField(const std::string&name,int v) {
+     177             :   std::snprintf(buffer_string.data(),buffer_string.size()," %d",v);
+     178     6095847 :   printField(name,buffer_string.data());
+     179     6095847 :   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    38092461 : OFile& OFile::printField(const std::string&name,const std::string & v) {
+     213             :   unsigned i;
+     214   200893813 :   for(i=0; i<const_fields.size(); i++) if(const_fields[i].name==name) break;
+     215    38092461 :   if(i>=const_fields.size()) {
+     216             :     Field field;
+     217             :     field.name=name;
+     218             :     field.value=v;
+     219    16347439 :     fields.push_back(field);
+     220             :   } else {
+     221    21745022 :     if(const_fields[i].value!=v) fieldChanged=true;
+     222             :     const_fields[i].value=v;
+     223             :   }
+     224    38092461 :   return *this;
+     225             : }
+     226             : 
+     227        6478 : OFile& OFile::setupPrintValue( Value *val ) {
+     228        6478 :   if( val->isPeriodic() ) {
+     229         506 :     addConstantField("min_" + val->getName() );
+     230        1012 :     addConstantField("max_" + val->getName() );
+     231             :   }
+     232        6478 :   return *this;
+     233             : }
+     234             : 
+     235        7274 : OFile& OFile::printField( Value* val, const double& v ) {
+     236        7274 :   printField( val->getName(), v );
+     237        7274 :   if( val->isPeriodic() ) {
+     238        1586 :     std::string min, max; val->getDomain( min, max );
+     239        1586 :     printField( "min_" + val->getName(), min );
+     240        3172 :     printField("max_" + val->getName(), max );
+     241             :   }
+     242        7274 :   return *this;
+     243             : }
+     244             : 
+     245     3796546 : OFile& OFile::printField() {
+     246             :   bool reprint=false;
+     247     3796546 :   if(fieldChanged || fields.size()!=previous_fields.size()) {
+     248             :     reprint=true;
+     249    19549520 :   } else for(unsigned i=0; i<fields.size(); i++) {
+     250    15759173 :       if( previous_fields[i].name!=fields[i].name ||
+     251    15759171 :           (fields[i].constant && fields[i].value!=previous_fields[i].value) ) {
+     252             :         reprint=true;
+     253             :         break;
+     254             :       }
+     255             :     }
+     256     3796546 :   if(reprint) {
+     257        6199 :     printf("#! FIELDS");
+     258      594469 :     for(unsigned i=0; i<fields.size(); i++) printf(" %s",fields[i].name.c_str());
+     259        6199 :     printf("\n");
+     260       34197 :     for(unsigned i=0; i<const_fields.size(); i++) {
+     261       27998 :       printf("#! SET %s %s",const_fields[i].name.c_str(),const_fields[i].value.c_str());
+     262       27998 :       printf("\n");
+     263             :     }
+     264             :   }
+     265    20143985 :   for(unsigned i=0; i<fields.size(); i++) printf("%s",fields[i].value.c_str());
+     266     3796546 :   printf("\n");
+     267     3796546 :   previous_fields=fields;
+     268     3796546 :   fields.clear();
+     269     3796546 :   fieldChanged=false;
+     270     3796546 :   return *this;
+     271             : }
+     272             : 
+     273         194 : void OFile::setBackupString( const std::string& str ) {
+     274         194 :   backstring=str;
+     275         194 : }
+     276             : 
+     277           0 : void OFile::backupAllFiles( const std::string& str ) {
+     278           0 :   if(str=="/dev/null") return;
+     279           0 :   plumed_assert( backstring!="bck" && !checkRestart());
+     280           0 :   size_t found=str.find_last_of("/\\");
+     281           0 :   std::string filename = appendSuffix(str,getSuffix());
+     282           0 :   std::string directory=filename.substr(0,found+1);
+     283           0 :   std::string file=filename.substr(found+1);
+     284           0 :   if( FileExist(filename) ) backupFile("bck", filename);
+     285           0 :   for(int i=0;; i++) {
+     286           0 :     std::string num; Tools::convert(i,num);
+     287           0 :     std::string filestr = directory + backstring + "." + num + "." + file;
+     288           0 :     if( !FileExist(filestr) ) break;
+     289           0 :     backupFile( "bck", filestr);
+     290           0 :   }
+     291             : }
+     292             : 
+     293        3619 : void OFile::backupFile( const std::string& bstring, const std::string& fname ) {
+     294        3619 :   if(fname=="/dev/null") return;
+     295        3465 :   int maxbackup=100;
+     296        3465 :   if(std::getenv("PLUMED_MAXBACKUP")) Tools::convert(std::getenv("PLUMED_MAXBACKUP"),maxbackup);
+     297        3465 :   if(maxbackup>0 && (!comm || comm->Get_rank()==0)) {
+     298        2999 :     FILE* ff=std::fopen(const_cast<char*>(fname.c_str()),"r");
+     299        2999 :     if(ff) {
+     300             :       // no exception here
+     301         121 :       std::fclose(ff);
+     302             :       std::string backup;
+     303         121 :       size_t found=fname.find_last_of("/\\");
+     304         121 :       std::string directory=fname.substr(0,found+1);
+     305         121 :       std::string file=fname.substr(found+1);
+     306         121 :       for(int i=0;; i++) {
+     307             :         std::string num;
+     308         170 :         Tools::convert(i,num);
+     309         170 :         if(i>maxbackup) plumed_merror("cannot backup file "+file+" maximum number of backup is "+num+"\n");
+     310         340 :         backup=directory+bstring +"."+num+"."+file;
+     311         170 :         FILE* fff=std::fopen(backup.c_str(),"r");
+     312             :         // no exception here
+     313         170 :         if(!fff) break;
+     314          49 :         else std::fclose(fff);
+     315          49 :       }
+     316         121 :       int check=rename(fname.c_str(),backup.c_str());
+     317         121 :       plumed_massert(check==0,"renaming "+fname+" into "+backup+" failed for reason: "+std::strerror(errno));
+     318             :     }
+     319             :   }
+     320             : }
+     321             : 
+     322        3912 : OFile& OFile::open(const std::string&path) {
+     323        3912 :   plumed_assert(!cloned);
+     324        3912 :   eof=false;
+     325        3912 :   err=false;
+     326        3912 :   fp=NULL;
+     327        3912 :   gzfp=NULL;
+     328        3912 :   this->path=path;
+     329        7824 :   this->path=appendSuffix(path,getSuffix());
+     330        3912 :   if(checkRestart()) {
+     331         293 :     fp=std::fopen(const_cast<char*>(this->path.c_str()),"a");
+     332         293 :     mode="a";
+     333         586 :     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        3619 :     backupFile( backstring, this->path );
+     342        3619 :     if(comm)comm->Barrier();
+     343        3619 :     fp=std::fopen(const_cast<char*>(this->path.c_str()),"w");
+     344        3619 :     mode="w";
+     345        7238 :     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        3912 :   if(plumed) plumed->insertFile(*this);
+     354        3912 :   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        9194 : FileBase& OFile::flush() {
+     391        9194 :   if(heavyFlush) {
+     392        3906 :     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        3897 :       std::fclose(fp);
+     400             :       // no exception here
+     401        3897 :       fp=std::fopen(const_cast<char*>(path.c_str()),"a");
+     402             :     }
+     403             :   } else {
+     404        5288 :     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        5288 :     if(gzfp) gzflush(gzFile(gzfp),Z_FULL_FLUSH);
+     410             : #endif
+     411             :   }
+     412        9194 :   return *this;
+     413             : }
+     414             : 
+     415        3912 : bool OFile::checkRestart()const {
+     416        3912 :   if(enforceRestart_) return true;
+     417        3901 :   else if(enforceBackup_) return false;
+     418        2757 :   else if(action) return action->getRestart();
+     419         256 :   else if(plumed) return plumed->getRestart();
+     420             :   else return false;
+     421             : }
+     422             : 
+     423          11 : OFile& OFile::enforceRestart() {
+     424          11 :   enforceRestart_=true;
+     425          11 :   enforceBackup_=false;
+     426          11 :   return *this;
+     427             : }
+     428             : 
+     429        1144 : OFile& OFile::enforceBackup() {
+     430        1144 :   enforceBackup_=true;
+     431        1144 :   enforceRestart_=false;
+     432        1144 :   return *this;
+     433             : }
+     434             : 
+     435             : 
+     436             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/OFile.h.func-sort-c.html b/coverage/tools/OFile.h.func-sort-c.html new file mode 100644 index 000000000000..f6ec0d343ad6 --- /dev/null +++ b/coverage/tools/OFile.h.func-sort-c.html @@ -0,0 +1,505 @@ + + + + + + + + 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-04-19 12:12:35Functions:9610888.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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
_ZN4PLMDlsIA46_cEERNS_5OFileES3_RKT_0
_ZN4PLMDlsIA47_cEERNS_5OFileES3_RKT_0
_ZN4PLMDlsIA52_cEERNS_5OFileES3_RKT_0
_ZN4PLMDlsIA67_cEERNS_5OFileES3_RKT_0
_ZN4PLMDlsIA72_cEERNS_5OFileES3_RKT_0
_ZN4PLMDlsIA88_cEERNS_5OFileES3_RKT_0
_ZN4PLMDlsIA90_cEERNS_5OFileES3_RKT_0
_ZN4PLMDlsIA50_cEERNS_5OFileES3_RKT_1
_ZN4PLMDlsIA54_cEERNS_5OFileES3_RKT_1
_ZN4PLMDlsIA63_cEERNS_5OFileES3_RKT_1
_ZN4PLMDlsIA65_cEERNS_5OFileES3_RKT_1
_ZN4PLMDlsIA81_cEERNS_5OFileES3_RKT_1
_ZN4PLMDlsIA34_cEERNS_5OFileES3_RKT_3
_ZN4PLMDlsIA48_cEERNS_5OFileES3_RKT_5
_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
_ZN4PLMDlsIA9_cEERNS_5OFileES3_RKT_31
_ZN4PLMDlsIA55_cEERNS_5OFileES3_RKT_33
_ZN4PLMDlsIA25_cEERNS_5OFileES3_RKT_34
_ZN4PLMDlsIA43_cEERNS_5OFileES3_RKT_36
_ZN4PLMDlsIA32_cEERNS_5OFileES3_RKT_37
_ZN4PLMDlsIA116_cEERNS_5OFileES3_RKT_38
_ZN4PLMDlsIA21_cEERNS_5OFileES3_RKT_39
_ZN4PLMDlsIPvEERNS_5OFileES3_RKT_41
_ZN4PLMDlsIA31_cEERNS_5OFileES3_RKT_47
_ZN4PLMDlsIA49_cEERNS_5OFileES3_RKT_55
_ZN4PLMDlsIA45_cEERNS_5OFileES3_RKT_100
_ZN4PLMDlsIA23_cEERNS_5OFileES3_RKT_102
_ZN4PLMDlsIA83_cEERNS_5OFileES3_RKT_108
_ZN4PLMDlsIA22_cEERNS_5OFileES3_RKT_130
_ZN4PLMDlsIA27_cEERNS_5OFileES3_RKT_146
_ZN4PLMDlsIA40_cEERNS_5OFileES3_RKT_160
_ZN4PLMDlsIA6_cEERNS_5OFileES3_RKT_160
_ZN4PLMDlsIA73_cEERNS_5OFileES3_RKT_197
_ZN4PLMDlsIiEERNS_5OFileES2_RKT_206
_ZN4PLMDlsIPKcEERNS_5OFileES4_RKT_209
_ZN4PLMDlsIA36_cEERNS_5OFileES3_RKT_236
_ZN4PLMDlsIA19_cEERNS_5OFileES3_RKT_275
_ZN4PLMDlsIA30_cEERNS_5OFileES3_RKT_278
_ZN4PLMDlsIcEERNS_5OFileES2_RKT_510
_ZN4PLMDlsIA29_cEERNS_5OFileES3_RKT_700
_ZN4PLMDlsIA11_cEERNS_5OFileES3_RKT_1087
_ZN4PLMDlsIA51_cEERNS_5OFileES3_RKT_1092
_ZN4PLMDlsIA12_cEERNS_5OFileES3_RKT_1146
_ZN4PLMDlsIA10_cEERNS_5OFileES3_RKT_1190
_ZN4PLMDlsIA74_cEERNS_5OFileES3_RKT_1193
_ZN4PLMDlsINS_9StopwatchEEERNS_5OFileES3_RKT_1196
_ZN4PLMDlsIA44_cEERNS_5OFileES3_RKT_1201
_ZN4PLMDlsIA28_cEERNS_5OFileES3_RKT_1213
_ZN4PLMDlsIA13_cEERNS_5OFileES3_RKT_1435
_ZN4PLMDlsImEERNS_5OFileES2_RKT_1452
_ZN4PLMDlsIA3_cEERNS_5OFileES3_RKT_1544
_ZN4PLMDlsINS_9CitationsEEERNS_5OFileES3_RKT_1663
_ZN4PLMDlsIA24_cEERNS_5OFileES3_RKT_1805
_ZN4PLMDlsIA17_cEERNS_5OFileES3_RKT_1909
_ZN4PLMDlsIA41_cEERNS_5OFileES3_RKT_2081
_ZN4PLMDlsIA16_cEERNS_5OFileES3_RKT_2136
_ZN4PLMDlsIA20_cEERNS_5OFileES3_RKT_2385
_ZN4PLMDlsIA14_cEERNS_5OFileES3_RKT_2400
_ZN4PLMDlsIA7_cEERNS_5OFileES3_RKT_2735
_ZN4PLMDlsIA38_cEERNS_5OFileES3_RKT_3077
_ZN4PLMDlsIA33_cEERNS_5OFileES3_RKT_3208
_ZN4PLMDlsINS_6lepton16ParsedExpressionEEERNS_5OFileES4_RKT_8057
_ZN4PLMDlsIA75_cEERNS_5OFileES3_RKT_9555
_ZN4PLMDlsIfEERNS_5OFileES2_RKT_45192
_ZN4PLMDlsIA4_cEERNS_5OFileES3_RKT_45204
_ZN4PLMDlsIA35_cEERNS_5OFileES3_RKT_45222
_ZN4PLMDlsIxEERNS_5OFileES2_RKT_45552
_ZN4PLMDlsIA18_cEERNS_5OFileES3_RKT_46644
_ZN4PLMDlsIA8_cEERNS_5OFileES3_RKT_47652
_ZN4PLMDlsIA5_cEERNS_5OFileES3_RKT_51407
_ZN4PLMDlsIA15_cEERNS_5OFileES3_RKT_52492
_ZN4PLMDlsIdEERNS_5OFileES2_RKT_91822
_ZN4PLMDlsIPcEERNS_5OFileES3_RKT_100109
_ZN4PLMDlsINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEERNS_5OFileES8_RKT_216449
_ZN4PLMDlsIjEERNS_5OFileES2_RKT_398466
_ZN4PLMDlsIA2_cEERNS_5OFileES3_RKT_510950
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/OFile.h.func.html b/coverage/tools/OFile.h.func.html new file mode 100644 index 000000000000..b44005bdf6e9 --- /dev/null +++ b/coverage/tools/OFile.h.func.html @@ -0,0 +1,505 @@ + + + + + + + + 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-04-19 12:12:35Functions:9610888.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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_1190
_ZN4PLMDlsIA110_cEERNS_5OFileES3_RKT_0
_ZN4PLMDlsIA116_cEERNS_5OFileES3_RKT_38
_ZN4PLMDlsIA11_cEERNS_5OFileES3_RKT_1087
_ZN4PLMDlsIA120_cEERNS_5OFileES3_RKT_0
_ZN4PLMDlsIA127_cEERNS_5OFileES3_RKT_12
_ZN4PLMDlsIA129_cEERNS_5OFileES3_RKT_0
_ZN4PLMDlsIA12_cEERNS_5OFileES3_RKT_1146
_ZN4PLMDlsIA134_cEERNS_5OFileES3_RKT_12
_ZN4PLMDlsIA13_cEERNS_5OFileES3_RKT_1435
_ZN4PLMDlsIA14_cEERNS_5OFileES3_RKT_2400
_ZN4PLMDlsIA15_cEERNS_5OFileES3_RKT_52492
_ZN4PLMDlsIA16_cEERNS_5OFileES3_RKT_2136
_ZN4PLMDlsIA17_cEERNS_5OFileES3_RKT_1909
_ZN4PLMDlsIA18_cEERNS_5OFileES3_RKT_46644
_ZN4PLMDlsIA19_cEERNS_5OFileES3_RKT_275
_ZN4PLMDlsIA20_cEERNS_5OFileES3_RKT_2385
_ZN4PLMDlsIA21_cEERNS_5OFileES3_RKT_39
_ZN4PLMDlsIA22_cEERNS_5OFileES3_RKT_130
_ZN4PLMDlsIA23_cEERNS_5OFileES3_RKT_102
_ZN4PLMDlsIA24_cEERNS_5OFileES3_RKT_1805
_ZN4PLMDlsIA25_cEERNS_5OFileES3_RKT_34
_ZN4PLMDlsIA26_cEERNS_5OFileES3_RKT_24
_ZN4PLMDlsIA27_cEERNS_5OFileES3_RKT_146
_ZN4PLMDlsIA28_cEERNS_5OFileES3_RKT_1213
_ZN4PLMDlsIA29_cEERNS_5OFileES3_RKT_700
_ZN4PLMDlsIA2_cEERNS_5OFileES3_RKT_510950
_ZN4PLMDlsIA30_cEERNS_5OFileES3_RKT_278
_ZN4PLMDlsIA31_cEERNS_5OFileES3_RKT_47
_ZN4PLMDlsIA32_cEERNS_5OFileES3_RKT_37
_ZN4PLMDlsIA33_cEERNS_5OFileES3_RKT_3208
_ZN4PLMDlsIA34_cEERNS_5OFileES3_RKT_3
_ZN4PLMDlsIA35_cEERNS_5OFileES3_RKT_45222
_ZN4PLMDlsIA36_cEERNS_5OFileES3_RKT_236
_ZN4PLMDlsIA37_cEERNS_5OFileES3_RKT_17
_ZN4PLMDlsIA38_cEERNS_5OFileES3_RKT_3077
_ZN4PLMDlsIA39_cEERNS_5OFileES3_RKT_19
_ZN4PLMDlsIA3_cEERNS_5OFileES3_RKT_1544
_ZN4PLMDlsIA40_cEERNS_5OFileES3_RKT_160
_ZN4PLMDlsIA41_cEERNS_5OFileES3_RKT_2081
_ZN4PLMDlsIA42_cEERNS_5OFileES3_RKT_8
_ZN4PLMDlsIA43_cEERNS_5OFileES3_RKT_36
_ZN4PLMDlsIA44_cEERNS_5OFileES3_RKT_1201
_ZN4PLMDlsIA45_cEERNS_5OFileES3_RKT_100
_ZN4PLMDlsIA46_cEERNS_5OFileES3_RKT_0
_ZN4PLMDlsIA47_cEERNS_5OFileES3_RKT_0
_ZN4PLMDlsIA48_cEERNS_5OFileES3_RKT_5
_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_51407
_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_197
_ZN4PLMDlsIA74_cEERNS_5OFileES3_RKT_1193
_ZN4PLMDlsIA75_cEERNS_5OFileES3_RKT_9555
_ZN4PLMDlsIA77_cEERNS_5OFileES3_RKT_11
_ZN4PLMDlsIA78_cEERNS_5OFileES3_RKT_12
_ZN4PLMDlsIA79_cEERNS_5OFileES3_RKT_21
_ZN4PLMDlsIA7_cEERNS_5OFileES3_RKT_2735
_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_47652
_ZN4PLMDlsIA90_cEERNS_5OFileES3_RKT_0
_ZN4PLMDlsIA92_cEERNS_5OFileES3_RKT_11
_ZN4PLMDlsIA96_cEERNS_5OFileES3_RKT_12
_ZN4PLMDlsIA99_cEERNS_5OFileES3_RKT_12
_ZN4PLMDlsIA9_cEERNS_5OFileES3_RKT_31
_ZN4PLMDlsIFRSt8ios_baseS2_EEERNS_5OFileES5_RKT_19
_ZN4PLMDlsINS_6lepton16ParsedExpressionEEERNS_5OFileES4_RKT_8057
_ZN4PLMDlsINS_9CitationsEEERNS_5OFileES3_RKT_1663
_ZN4PLMDlsINS_9StopwatchEEERNS_5OFileES3_RKT_1196
_ZN4PLMDlsINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEERNS_5OFileES8_RKT_216449
_ZN4PLMDlsIPKcEERNS_5OFileES4_RKT_209
_ZN4PLMDlsIPcEERNS_5OFileES3_RKT_100109
_ZN4PLMDlsIPvEERNS_5OFileES3_RKT_41
_ZN4PLMDlsISt13_SetprecisionEERNS_5OFileES3_RKT_19
_ZN4PLMDlsIcEERNS_5OFileES2_RKT_510
_ZN4PLMDlsIdEERNS_5OFileES2_RKT_91822
_ZN4PLMDlsIfEERNS_5OFileES2_RKT_45192
_ZN4PLMDlsIiEERNS_5OFileES2_RKT_206
_ZN4PLMDlsIjEERNS_5OFileES2_RKT_398466
_ZN4PLMDlsImEERNS_5OFileES2_RKT_1452
_ZN4PLMDlsIxEERNS_5OFileES2_RKT_45552
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/OFile.h.gcov.html b/coverage/tools/OFile.h.gcov.html new file mode 100644 index 000000000000..0bd79e26d08a --- /dev/null +++ b/coverage/tools/OFile.h.gcov.html @@ -0,0 +1,363 @@ + + + + + + + + LCOV - plumed test coverage - tools/OFile.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - OFile.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:66100.0 %
Date:2024-04-19 12:12:35Functions:9610888.9 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_tools_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    50382521 :   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     1756227 : OFile& operator<<(OFile&of,const T &t) {
+     277     1756227 :   of.oss<<t;
+     278     1756227 :   of.printf("%s",of.oss.str().c_str());
+     279     1756227 :   of.oss.str("");
+     280     1756227 :   return of;
+     281             : }
+     282             : 
+     283             : 
+     284             : }
+     285             : 
+     286             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/OpenMP.cpp.func-sort-c.html b/coverage/tools/OpenMP.cpp.func-sort-c.html new file mode 100644 index 000000000000..4d317267d4ea --- /dev/null +++ b/coverage/tools/OpenMP.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - tools/OpenMP.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - OpenMP.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1717100.0 %
Date:2024-04-19 12:12:35Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6OpenMP13setNumThreadsEj1
_ZN4PLMD6OpenMP16getCachelineSizeEv353656
_ZN4PLMD6OpenMP13getNumThreadsEv35058390
_ZN4PLMD6OpenMP12getThreadNumEv61682155
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/OpenMP.cpp.func.html b/coverage/tools/OpenMP.cpp.func.html new file mode 100644 index 000000000000..5f167d11bff4 --- /dev/null +++ b/coverage/tools/OpenMP.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - tools/OpenMP.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - OpenMP.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1717100.0 %
Date:2024-04-19 12:12:35Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6OpenMP12getThreadNumEv61682155
_ZN4PLMD6OpenMP13getNumThreadsEv35058390
_ZN4PLMD6OpenMP13setNumThreadsEj1
_ZN4PLMD6OpenMP16getCachelineSizeEv353656
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/OpenMP.cpp.gcov.html b/coverage/tools/OpenMP.cpp.gcov.html new file mode 100644 index 000000000000..3734b3f9ae19 --- /dev/null +++ b/coverage/tools/OpenMP.cpp.gcov.html @@ -0,0 +1,159 @@ + + + + + + + + LCOV - plumed test coverage - tools/OpenMP.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - OpenMP.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1717100.0 %
Date:2024-04-19 12:12:35Functions:44100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2014-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "OpenMP.h"
+      24             : #include "Tools.h"
+      25             : #include <cstdlib>
+      26             : #if defined(_OPENMP)
+      27             : #include <omp.h>
+      28             : #endif
+      29             : 
+      30             : namespace PLMD {
+      31             : 
+      32             : namespace OpenMP {
+      33             : ///singleton struct to treat the openMP setting as a global variables, but with a layer of encapsulation
+      34             : struct OpenMPVars {
+      35             :   unsigned cacheline_size=512;
+      36             :   bool cache_set=false;
+      37             :   unsigned num_threads=1;
+      38             :   bool nt_env_set=false;
+      39             :   static OpenMPVars & get() {
+      40             :     static OpenMPVars vars;
+      41             :     return vars;
+      42             :   }
+      43             : private:
+      44             :   OpenMPVars()=default;
+      45             :   OpenMPVars(OpenMPVars&)=delete;
+      46             :   OpenMPVars& operator=(OpenMPVars&&)=delete;
+      47             : };
+      48             : 
+      49           1 : void setNumThreads(const unsigned nt) {
+      50           1 :   OpenMPVars::get().num_threads=nt;
+      51           1 : }
+      52             : 
+      53      353656 : unsigned getCachelineSize() {
+      54      353656 :   if(!OpenMPVars::get().cache_set) {
+      55         939 :     if(std::getenv("PLUMED_CACHELINE_SIZE")) {
+      56           1 :       Tools::convert(std::getenv("PLUMED_CACHELINE_SIZE"),OpenMPVars::get().cacheline_size);
+      57             :     }
+      58         939 :     OpenMPVars::get().cache_set = true;
+      59             :   }
+      60      353656 :   return OpenMPVars::get().cacheline_size;
+      61             : }
+      62             : 
+      63    35058390 : unsigned getNumThreads() {
+      64    35058390 :   if(!OpenMPVars::get().nt_env_set) {
+      65         939 :     if(std::getenv("PLUMED_NUM_THREADS")) {
+      66         939 :       Tools::convert(std::getenv("PLUMED_NUM_THREADS"),OpenMPVars::get().num_threads);
+      67             :     }
+      68         939 :     OpenMPVars::get().nt_env_set = true;
+      69             :   }
+      70    35058390 :   return OpenMPVars::get().num_threads;
+      71             : }
+      72             : 
+      73    61682155 : unsigned getThreadNum() {
+      74             : #if defined(_OPENMP)
+      75    61682155 :   return omp_get_thread_num();
+      76             : #else
+      77             :   return 0;
+      78             : #endif
+      79             : }
+      80             : 
+      81             : }//namespace OpenMP
+      82             : }//namespace PLMD
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/OpenMP.h.func-sort-c.html b/coverage/tools/OpenMP.h.func-sort-c.html new file mode 100644 index 000000000000..674ea4a9c626 --- /dev/null +++ b/coverage/tools/OpenMP.h.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - tools/OpenMP.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - OpenMP.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:88100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6OpenMP17getGoodNumThreadsIfEEjPKT_j0
_ZN4PLMD6OpenMP17getGoodNumThreadsIdEEjRKSt6vectorIT_SaIS3_EE1350
_ZN4PLMD6OpenMP17getGoodNumThreadsIdEEjPKT_j352465
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/OpenMP.h.func.html b/coverage/tools/OpenMP.h.func.html new file mode 100644 index 000000000000..0175662fdffb --- /dev/null +++ b/coverage/tools/OpenMP.h.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - tools/OpenMP.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - OpenMP.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:88100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6OpenMP17getGoodNumThreadsIdEEjPKT_j352465
_ZN4PLMD6OpenMP17getGoodNumThreadsIdEEjRKSt6vectorIT_SaIS3_EE1350
_ZN4PLMD6OpenMP17getGoodNumThreadsIfEEjPKT_j0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/OpenMP.h.gcov.html b/coverage/tools/OpenMP.h.gcov.html new file mode 100644 index 000000000000..3da07c6ce38c --- /dev/null +++ b/coverage/tools/OpenMP.h.gcov.html @@ -0,0 +1,149 @@ + + + + + + + + LCOV - plumed test coverage - tools/OpenMP.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - OpenMP.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:88100.0 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2014-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_tools_OpenMP_h
+      23             : #define __PLUMED_tools_OpenMP_h
+      24             : 
+      25             : #include <vector>
+      26             : 
+      27             : namespace PLMD {
+      28             : 
+      29             : namespace OpenMP {
+      30             : 
+      31             : /// Set number of threads that can be used by openMP
+      32             : void setNumThreads(const unsigned nt);
+      33             : 
+      34             : /// Get number of threads that can be used by openMP
+      35             : unsigned getNumThreads();
+      36             : 
+      37             : /// Returns a unique thread identification number within the current team
+      38             : unsigned getThreadNum();
+      39             : 
+      40             : /// get cacheline size
+      41             : unsigned getCachelineSize();
+      42             : 
+      43             : /// Get a reasonable number of threads so as to access to an array of size s located at x
+      44             : template<typename T>
+      45      352465 : unsigned getGoodNumThreads(const T* /*getTheType*/,unsigned n) {
+      46             :   // this is more or less the equivalent of writing "unsigned getGoodNumThreads<T>(unsigned n)"
+      47             : 
+      48             :   // a factor two is necessary since there is no guarantee that x is aligned
+      49             :   // to cache line boundary
+      50      352465 :   unsigned m=n*sizeof(T)/(2*getCachelineSize());
+      51      352465 :   unsigned numThreads=getNumThreads();
+      52      352465 :   if(m>=numThreads) {
+      53             :     m=numThreads;
+      54             :   } else {
+      55             :     //it is better to use either all the active threads or only one
+      56             :     //this solves a performance problem as explained in issue #415
+      57             :     m=1;
+      58             :   }
+      59      352465 :   return m;
+      60             : }
+      61             : 
+      62             : /// Get a reasonable number of threads so as to access to vector v
+      63             : template<typename T>
+      64        1350 : unsigned getGoodNumThreads(const std::vector<T> & v) {
+      65        1350 :   if(v.size()==0) return 1;
+      66        1314 :   else return getGoodNumThreads(&v[0],v.size());
+      67             : }
+      68             : 
+      69             : }//namespace OpenMP
+      70             : }//namespace PLMD
+      71             : 
+      72             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/PDB.cpp.func-sort-c.html b/coverage/tools/PDB.cpp.func-sort-c.html new file mode 100644 index 000000000000..fcbf06b4e732 --- /dev/null +++ b/coverage/tools/PDB.cpp.func-sort-c.html @@ -0,0 +1,249 @@ + + + + + + + + LCOV - plumed test coverage - tools/PDB.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - PDB.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:21941752.5 %
Date:2024-04-19 12:12:35Functions:274461.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3PDB11addBlockEndERKj0
_ZN4PLMD3PDB12setPositionsERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EE0
_ZN4PLMD3PDB14setAtomNumbersERKSt6vectorINS_10AtomNumberESaIS2_EE0
_ZN4PLMD3PDB16setArgumentNamesERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EE0
_ZN4PLMD3PDB16setArgumentValueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKd0
_ZN4PLMD3PDB16setAtomPositionsERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EE0
_ZN4PLMD3PDB5printERKdPNS_14GenericMolInfoERNS_5OFileERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMDlsERNS_3LogERKNS_3PDBE0
_ZNK4PLMD3PDB10getChainIDB5cxx11ENS_10AtomNumberE0
_ZNK4PLMD3PDB12checkForAtomERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZNK4PLMD3PDB15checkForResidueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZNK4PLMD3PDB15getAtomsInChainERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZNK4PLMD3PDB16getArgumentNamesB5cxx11Ev0
_ZNK4PLMD3PDB7hasFlagERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZNK4PLMD3PDB8getMtypeB5cxx11Ev0
_ZNK4PLMD3PDB9getBoxAngEv0
_ZNK4PLMD3PDB9getBoxAxsEv0
_ZNK4PLMD3PDB21getNumberOfAtomBlocksEv3
_ZNK4PLMD3PDB16getAtomBlockEndsEv6
_ZNK4PLMD3PDB9getBoxVecEv12
_ZNK4PLMD3PDB12getAtomRangeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERNS_10AtomNumberESA_RS6_165
_ZNK4PLMD3PDB12checkForAtomENS_10AtomNumberE249
_ZNK4PLMD3PDB13getChainNamesERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EE251
_ZN4PLMD3PDB4readERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbd422
_ZNK4PLMD3PDB11getPositionENS_10AtomNumberE1038
_ZNK4PLMD3PDB16getArgumentValueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIdSaIdEE2148
_ZNK4PLMD3PDB31getNamedAtomFromResidueAndChainERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjS8_2352
_ZN4PLMD3PDB19readFromFilepointerEP8_IO_FILEbd4547
_ZN4PLMD3PDB9addRemarkERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EE4601
_ZNK4PLMD3PDB10getChainIDB5cxx11ERKj4686
_ZNK4PLMD3PDB14getResidueNameB5cxx11ERKj6012
_ZNK4PLMD3PDB15getResidueRangeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjS9_RS6_11615
_ZNK4PLMD3PDB23getNamedAtomFromResidueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKj13380
_ZNK4PLMD3PDB17getAtomsInResidueERKjRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE34246
_ZNK4PLMD3PDB14allowedResidueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_37562
_ZNK4PLMD3PDB14getResidueNameERKjRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE48724
_ZNK4PLMD3PDB14getResidueNameB5cxx11ENS_10AtomNumberE151160
_ZNK4PLMD3PDB7getBetaEv152208
_ZNK4PLMD3PDB12getOccupancyEv153875
_ZNK4PLMD3PDB16getResidueNumberENS_10AtomNumberE165477
_ZNK4PLMD3PDB14getAtomNumbersEv314586
_ZNK4PLMD3PDB11getAtomNameB5cxx11ENS_10AtomNumberE6870209
_ZNK4PLMD3PDB12getPositionsEv23575319
_ZNK4PLMD3PDB4sizeEv216623991
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/PDB.cpp.func.html b/coverage/tools/PDB.cpp.func.html new file mode 100644 index 000000000000..9b12af1191a6 --- /dev/null +++ b/coverage/tools/PDB.cpp.func.html @@ -0,0 +1,249 @@ + + + + + + + + LCOV - plumed test coverage - tools/PDB.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - PDB.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:21941752.5 %
Date:2024-04-19 12:12:35Functions:274461.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3PDB11addBlockEndERKj0
_ZN4PLMD3PDB12setPositionsERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EE0
_ZN4PLMD3PDB14setAtomNumbersERKSt6vectorINS_10AtomNumberESaIS2_EE0
_ZN4PLMD3PDB16setArgumentNamesERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EE0
_ZN4PLMD3PDB16setArgumentValueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKd0
_ZN4PLMD3PDB16setAtomPositionsERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EE0
_ZN4PLMD3PDB19readFromFilepointerEP8_IO_FILEbd4547
_ZN4PLMD3PDB4readERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbd422
_ZN4PLMD3PDB5printERKdPNS_14GenericMolInfoERNS_5OFileERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD3PDB9addRemarkERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EE4601
_ZN4PLMDlsERNS_3LogERKNS_3PDBE0
_ZNK4PLMD3PDB10getChainIDB5cxx11ENS_10AtomNumberE0
_ZNK4PLMD3PDB10getChainIDB5cxx11ERKj4686
_ZNK4PLMD3PDB11getAtomNameB5cxx11ENS_10AtomNumberE6870209
_ZNK4PLMD3PDB11getPositionENS_10AtomNumberE1038
_ZNK4PLMD3PDB12checkForAtomENS_10AtomNumberE249
_ZNK4PLMD3PDB12checkForAtomERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZNK4PLMD3PDB12getAtomRangeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERNS_10AtomNumberESA_RS6_165
_ZNK4PLMD3PDB12getOccupancyEv153875
_ZNK4PLMD3PDB12getPositionsEv23575319
_ZNK4PLMD3PDB13getChainNamesERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EE251
_ZNK4PLMD3PDB14allowedResidueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_37562
_ZNK4PLMD3PDB14getAtomNumbersEv314586
_ZNK4PLMD3PDB14getResidueNameB5cxx11ENS_10AtomNumberE151160
_ZNK4PLMD3PDB14getResidueNameB5cxx11ERKj6012
_ZNK4PLMD3PDB14getResidueNameERKjRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE48724
_ZNK4PLMD3PDB15checkForResidueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZNK4PLMD3PDB15getAtomsInChainERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZNK4PLMD3PDB15getResidueRangeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjS9_RS6_11615
_ZNK4PLMD3PDB16getArgumentNamesB5cxx11Ev0
_ZNK4PLMD3PDB16getArgumentValueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIdSaIdEE2148
_ZNK4PLMD3PDB16getAtomBlockEndsEv6
_ZNK4PLMD3PDB16getResidueNumberENS_10AtomNumberE165477
_ZNK4PLMD3PDB17getAtomsInResidueERKjRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE34246
_ZNK4PLMD3PDB21getNumberOfAtomBlocksEv3
_ZNK4PLMD3PDB23getNamedAtomFromResidueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKj13380
_ZNK4PLMD3PDB31getNamedAtomFromResidueAndChainERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjS8_2352
_ZNK4PLMD3PDB4sizeEv216623991
_ZNK4PLMD3PDB7getBetaEv152208
_ZNK4PLMD3PDB7hasFlagERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZNK4PLMD3PDB8getMtypeB5cxx11Ev0
_ZNK4PLMD3PDB9getBoxAngEv0
_ZNK4PLMD3PDB9getBoxAxsEv0
_ZNK4PLMD3PDB9getBoxVecEv12
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/PDB.cpp.gcov.html b/coverage/tools/PDB.cpp.gcov.html new file mode 100644 index 000000000000..b87b02f4bce7 --- /dev/null +++ b/coverage/tools/PDB.cpp.gcov.html @@ -0,0 +1,835 @@ + + + + + + + + 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:21941752.5 %
Date:2024-04-19 12:12:35Functions:274461.4 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "PDB.h"
+      23             : #include "Tools.h"
+      24             : #include "Log.h"
+      25             : #include "h36.h"
+      26             : #include <cstdio>
+      27             : #include <iostream>
+      28             : #include "core/GenericMolInfo.h"
+      29             : #include "Tensor.h"
+      30             : 
+      31             : //+PLUMEDOC INTERNAL pdbreader
+      32             : /*
+      33             : PLUMED can use the PDB format in several places
+      34             : 
+      35             : - To read molecular structure (\ref MOLINFO).
+      36             : - To read reference conformations (\ref RMSD, but also many other methods in \ref dists, \ref FIT_TO_TEMPLATE, etc).
+      37             : 
+      38             : The implemented PDB reader expects a file formatted correctly according to the
+      39             : [PDB standard](http://www.wwpdb.org/documentation/file-format-content/format33/v3.3.html).
+      40             : In particular, the following columns are read from ATOM records
+      41             : \verbatim
+      42             : columns | content
+      43             : 1-6     | record name (ATOM or HETATM)
+      44             : 7-11    | serial number of the atom (starting from 1)
+      45             : 13-16   | atom name
+      46             : 18-20   | residue name
+      47             : 22      | chain id
+      48             : 23-26   | residue number
+      49             : 31-38   | x coordinate
+      50             : 39-46   | y coordinate
+      51             : 47-54   | z coordinate
+      52             : 55-60   | occupancy
+      53             : 61-66   | beta factor
+      54             : \endverbatim
+      55             : PLUMED parser is slightly more permissive than the official PDB format
+      56             : in the fact that the format of real numbers is not fixed. In other words,
+      57             : any real number that can be parsed is OK and the dot can be placed anywhere. However,
+      58             : __columns are interpret strictly__. A sample PDB should look like the following
+      59             : \verbatim
+      60             : ATOM      2  CH3 ACE     1      12.932 -14.718  -6.016  1.00  1.00
+      61             : ATOM      5  C   ACE     1      21.312  -9.928  -5.946  1.00  1.00
+      62             : ATOM      9  CA  ALA     2      19.462 -11.088  -8.986  1.00  1.00
+      63             : \endverbatim
+      64             : 
+      65             : Notice that serial numbers need not to be consecutive. In the three-line example above,
+      66             : only the coordinates of three atoms are provided. This is perfectly legal and indicates PLUMED
+      67             : that information about these atoms only is available. This could be both for structural
+      68             : information in \ref MOLINFO, where the other atoms would have no name assigned, and for
+      69             : reference structures used in \ref RMSD, where only the provided atoms would be used to compute RMSD.
+      70             : 
+      71             : \par Occupancy and beta factors
+      72             : 
+      73             : PLUMED reads also occupancy and beta factors that however are given a very special meaning.
+      74             : In cases where the PDB structure is used as a reference for an alignment (that's the case
+      75             : for instance in \ref RMSD and in \ref FIT_TO_TEMPLATE), the occupancy column is used
+      76             : to provide the weight of each atom in the alignment. In cases where, perhaps after alignment,
+      77             : the displacement between running coordinates and the provided PDB is computed, the beta factors
+      78             : are used as weight for the displacement.
+      79             : Since setting the weights to zero is the same as __not__ including an atom in the alignment or
+      80             : displacement calculation, the two following reference files would be equivalent when used in an \ref RMSD
+      81             : calculation. First file:
+      82             : \verbatim
+      83             : ATOM      2  CH3 ACE     1      12.932 -14.718  -6.016  1.00  1.00
+      84             : ATOM      5  C   ACE     1      21.312  -9.928  -5.946  1.00  1.00
+      85             : ATOM      9  CA  ALA     2      19.462 -11.088  -8.986  0.00  0.00
+      86             : \endverbatim
+      87             : Second file:
+      88             : \verbatim
+      89             : ATOM      2  CH3 ACE     1      12.932 -14.718  -6.016  1.00  1.00
+      90             : ATOM      5  C   ACE     1      21.312  -9.928  -5.946  1.00  1.00
+      91             : \endverbatim
+      92             : However notice that many extra atoms with zero weight might slow down the calculation, so
+      93             : removing lines is better than setting their weights to zero.
+      94             : In addition, weights for alignment need not to be equivalent to weights for displacement.
+      95             : Starting with PLUMED 2.7, if all the weights are set to zero they will be normalized to be equal to the
+      96             : inverse of the number of involved atoms. This means that it will be possible to use files with
+      97             : the weight columns set to zero obtaining a meaningful result. In previous PLUMED versions,
+      98             : setting all weights to zero was resulting in an error instead.
+      99             : 
+     100             : 
+     101             : \par Systems with more than 100k atoms
+     102             : 
+     103             : Notice that it very likely does not make any sense to compute the \ref RMSD or any other structural
+     104             : deviation __using__ so many atoms. However, if the protein for which you want to compute \ref RMSD
+     105             : has atoms with large serial numbers (e.g. because it is located __after__ solvent in the sorted list of atoms)
+     106             : you might end up with troubles with the limitations of the PDB format. Indeed, since there are 5
+     107             : columns available for atom serial number, this number cannot be larger than 99999.
+     108             : In addition, providing \ref MOLINFO with names associated to atoms with a serial larger than 99999 would be impossible.
+     109             : 
+     110             : Since PLUMED 2.4 we allow [hybrid 36](http://cci.lbl.gov/hybrid_36/) format to be used to specify atom numbers.
+     111             : This format is not particularly widespread, but has the nice feature that it provides a one-to-one mapping
+     112             : between numbers up to approximately 80 millions and strings with 5 characters, plus it is backward compatible
+     113             : for numbers smaller than 100000. This is not true for notations like the hex notation exported by VMD.
+     114             : Using the hybrid 36 format, the ATOM records for atom ranging from 99997 to 100002 would read like these:
+     115             : \verbatim
+     116             : ATOM  99997  Ar      X   1      45.349  38.631  15.116  1.00  1.00
+     117             : ATOM  99998  Ar      X   1      46.189  38.631  15.956  1.00  1.00
+     118             : ATOM  99999  Ar      X   1      46.189  39.471  15.116  1.00  1.00
+     119             : ATOM  A0000  Ar      X   1      45.349  39.471  15.956  1.00  1.00
+     120             : ATOM  A0000  Ar      X   1      45.349  38.631  16.796  1.00  1.00
+     121             : ATOM  A0001  Ar      X   1      46.189  38.631  17.636  1.00  1.00
+     122             : \endverbatim
+     123             : There are tools that can be found to translate from integers to strings and back using hybrid 36 format
+     124             : (a simple python script can be found [here](https://sourceforge.net/p/cctbx/code/HEAD/tree/trunk/iotbx/pdb/hybrid_36.py)).
+     125             : In addition, as of PLUMED 2.5, we provide a \ref pdbrenumber "command line tool" that can be used to renumber atoms in a PDB file.
+     126             : 
+     127             : */
+     128             : //+ENDPLUMEDOC
+     129             : 
+     130             : 
+     131             : namespace PLMD {
+     132             : 
+     133           0 : void PDB::setAtomNumbers( const std::vector<AtomNumber>& atoms ) {
+     134           0 :   positions.resize( atoms.size() ); occupancy.resize( atoms.size() );
+     135           0 :   beta.resize( atoms.size() ); numbers.resize( atoms.size() );
+     136           0 :   for(unsigned i=0; i<atoms.size(); ++i) { numbers[i]=atoms[i]; beta[i]=1.0; occupancy[i]=1.0; }
+     137           0 : }
+     138             : 
+     139           0 : void PDB::setArgumentNames( const std::vector<std::string>& argument_names ) {
+     140           0 :   argnames.resize( argument_names.size() ); std::vector<double> tmp(1,0);
+     141           0 :   for(unsigned i=0; i<argument_names.size(); ++i) {
+     142             :     argnames[i]=argument_names[i];
+     143           0 :     arg_data.insert( std::pair<std::string,std::vector<double> >( argnames[i], tmp ) );
+     144             :   }
+     145           0 : }
+     146             : 
+     147        2148 : bool PDB::getArgumentValue( const std::string& name, std::vector<double>& value ) const {
+     148             :   std::map<std::string,std::vector<double> >::const_iterator it = arg_data.find(name);
+     149        2148 :   if( it!=arg_data.end() ) {
+     150        2148 :     if( value.size()!=it->second.size() ) return false;
+     151        4300 :     for(unsigned i=0; i<value.size(); ++i) value[i] = it->second[i];
+     152             :     return true;
+     153             :   }
+     154             :   return false;
+     155             : }
+     156             : 
+     157           0 : void PDB::setAtomPositions( const std::vector<Vector>& pos ) {
+     158           0 :   plumed_assert( pos.size()==positions.size() );
+     159           0 :   for(unsigned i=0; i<positions.size(); ++i) positions[i]=pos[i];
+     160           0 : }
+     161             : 
+     162           0 : void PDB::setArgumentValue( const std::string& argname, const double& val ) {
+     163             :   // First set the value of the value of the argument in the map
+     164           0 :   arg_data.find(argname)->second.resize(1);
+     165           0 :   arg_data.find(argname)->second[0] = val;
+     166           0 : }
+     167             : 
+     168             : // bool PDB::hasRequiredProperties( const std::vector<std::string>& inproperties ){
+     169             : //   bool hasprop=false;
+     170             : //   for(unsigned i=0;i<remark.size();++i){
+     171             : //       if( remark[i].find("PROPERTIES=")!=std::string::npos){ hasprop=true; break; }
+     172             : //   }
+     173             : //   if( !hasprop ){
+     174             : //       std::string mypropstr="PROPERTIES=" + inproperties[0];
+     175             : //       for(unsigned i=1;i<inproperties.size();++i) mypropstr += "," + inproperties[i];
+     176             : //       remark.push_back( mypropstr );
+     177             : //   }
+     178             : //   // Now check that all required properties are there
+     179             : //   for(unsigned i=0;i<inproperties.size();++i){
+     180             : //       hasprop=false;
+     181             : //       for(unsigned j=0;j<remark.size();++j){
+     182             : //           if( remark[j].find(inproperties[i]+"=")!=std::string::npos){ hasprop=true; break; }
+     183             : //       }
+     184             : //       if( !hasprop ) return false;
+     185             : //   }
+     186             : //   return true;
+     187             : // }
+     188             : 
+     189           0 : void PDB::addBlockEnd( const unsigned& end ) {
+     190           0 :   block_ends.push_back( end );
+     191           0 : }
+     192             : 
+     193           3 : unsigned PDB::getNumberOfAtomBlocks()const {
+     194           3 :   return block_ends.size();
+     195             : }
+     196             : 
+     197           6 : const std::vector<unsigned> & PDB::getAtomBlockEnds()const {
+     198           6 :   return block_ends;
+     199             : }
+     200             : 
+     201    23575319 : const std::vector<Vector> & PDB::getPositions()const {
+     202    23575319 :   return positions;
+     203             : }
+     204             : 
+     205           0 : void PDB::setPositions(const std::vector<Vector> &v ) {
+     206           0 :   plumed_assert( v.size()==positions.size() );
+     207           0 :   positions=v;
+     208           0 : }
+     209             : 
+     210      153875 : const std::vector<double> & PDB::getOccupancy()const {
+     211      153875 :   return occupancy;
+     212             : }
+     213             : 
+     214      152208 : const std::vector<double> & PDB::getBeta()const {
+     215      152208 :   return beta;
+     216             : }
+     217             : 
+     218        4601 : void PDB::addRemark( std::vector<std::string>& v1 ) {
+     219        4601 :   Tools::parse(v1,"TYPE",mtype);
+     220        4601 :   Tools::parseVector(v1,"ARG",argnames);
+     221       12357 :   for(unsigned i=0; i<v1.size(); ++i) {
+     222        7756 :     if( v1[i].find("=")!=std::string::npos ) {
+     223             :       std::size_t eq=v1[i].find_first_of('=');
+     224        7164 :       std::string name=v1[i].substr(0,eq);
+     225        7164 :       std::string sval=v1[i].substr(eq+1);
+     226             :       // double val; Tools::convert( sval, val );
+     227        7164 :       std::vector<std::string> words=Tools::getWords(sval,"\t\n ,");
+     228        7164 :       std::vector<double> val( words.size() );
+     229       14336 :       for(unsigned i=0; i<val.size(); ++i) Tools::convert( words[i], val[i] );
+     230       14328 :       arg_data.insert( std::pair<std::string,std::vector<double> >( name, val ) );
+     231        7164 :     } else {
+     232         592 :       flags.push_back(v1[i]);
+     233             :     }
+     234             :   }
+     235        4601 : }
+     236             : 
+     237           0 : bool PDB::hasFlag( const std::string& fname ) const {
+     238           0 :   for(unsigned i=0; i<flags.size(); ++i) {
+     239           0 :     if( flags[i]==fname ) return true;
+     240             :   }
+     241             :   return false;
+     242             : }
+     243             : 
+     244             : 
+     245      314586 : const std::vector<AtomNumber> & PDB::getAtomNumbers()const {
+     246      314586 :   return numbers;
+     247             : }
+     248             : 
+     249           0 : const Vector & PDB::getBoxAxs()const {
+     250           0 :   return BoxXYZ;
+     251             : }
+     252             : 
+     253           0 : const Vector & PDB::getBoxAng()const {
+     254           0 :   return BoxABG;
+     255             : }
+     256             : 
+     257          12 : const Tensor & PDB::getBoxVec()const {
+     258          12 :   return Box;
+     259             : }
+     260             : 
+     261     6870209 : std::string PDB::getAtomName(AtomNumber a)const {
+     262             :   const auto p=number2index.find(a);
+     263     6870209 :   if(p==number2index.end()) {
+     264           0 :     std::string num; Tools::convert( a.serial(), num );
+     265           0 :     plumed_merror("Name of atom " + num + " not found" );
+     266     6870209 :   } else return atomsymb[p->second];
+     267             : }
+     268             : 
+     269      165477 : unsigned PDB::getResidueNumber(AtomNumber a)const {
+     270             :   const auto p=number2index.find(a);
+     271      165477 :   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      165477 :   } else return residue[p->second];
+     275             : }
+     276             : 
+     277      151160 : std::string PDB::getResidueName(AtomNumber a) const {
+     278             :   const auto p=number2index.find(a);
+     279      151160 :   if(p==number2index.end()) {
+     280           0 :     std::string num; Tools::convert( a.serial(), num );
+     281           0 :     plumed_merror("Residue for atom " + num + " not found" );
+     282      151160 :   } else return residuenames[p->second];
+     283             : }
+     284             : 
+     285   216623991 : unsigned PDB::size()const {
+     286   216623991 :   return positions.size();
+     287             : }
+     288             : 
+     289        4547 : bool PDB::readFromFilepointer(FILE *fp,bool naturalUnits,double scale) {
+     290             :   //cerr<<file<<endl;
+     291             :   bool file_is_alive=false;
+     292        4547 :   if(naturalUnits) scale=1.0;
+     293             :   std::string line;
+     294             :   fpos_t pos; bool between_ters=true;
+     295      425866 :   while(Tools::getline(fp,line)) {
+     296             :     //cerr<<line<<"\n";
+     297      425369 :     fgetpos (fp,&pos);
+     298     2880275 :     while(line.length()<80) line.push_back(' ');
+     299      425369 :     std::string record=line.substr(0,6);
+     300      425369 :     std::string serial=line.substr(6,5);
+     301      425369 :     std::string atomname=line.substr(12,4);
+     302      425369 :     std::string residuename=line.substr(17,3);
+     303      425369 :     std::string chainID=line.substr(21,1);
+     304      425369 :     std::string resnum=line.substr(22,4);
+     305      425369 :     std::string x=line.substr(30,8);
+     306      425369 :     std::string y=line.substr(38,8);
+     307      425369 :     std::string z=line.substr(46,8);
+     308      425369 :     std::string occ=line.substr(54,6);
+     309      425369 :     std::string bet=line.substr(60,6);
+     310      425369 :     std::string BoxX=line.substr(6,9);
+     311      425369 :     std::string BoxY=line.substr(15,9);
+     312      425369 :     std::string BoxZ=line.substr(24,9);
+     313      425369 :     std::string BoxA=line.substr(33,7);
+     314      425369 :     std::string BoxB=line.substr(40,7);
+     315      425369 :     std::string BoxG=line.substr(47,7);
+     316      425369 :     Tools::trim(record);
+     317      425369 :     if(record=="TER") { between_ters=false; block_ends.push_back( positions.size() ); }
+     318      425369 :     if(record=="END") { file_is_alive=true;  break;}
+     319      421460 :     if(record=="ENDMDL") { file_is_alive=true;  break;}
+     320      421319 :     if(record=="REMARK") {
+     321        9202 :       std::vector<std::string> v1;  v1=Tools::getWords(line.substr(6));
+     322        4601 :       addRemark( v1 );
+     323        4601 :     }
+     324      421319 :     if(record=="CRYST1") {
+     325          76 :       Tools::convert(BoxX,BoxXYZ[0]);
+     326          76 :       Tools::convert(BoxY,BoxXYZ[1]);
+     327          76 :       Tools::convert(BoxZ,BoxXYZ[2]);
+     328          76 :       Tools::convert(BoxA,BoxABG[0]);
+     329          76 :       Tools::convert(BoxB,BoxABG[1]);
+     330          76 :       Tools::convert(BoxG,BoxABG[2]);
+     331          76 :       BoxXYZ*=scale;
+     332          76 :       double cosA=std::cos(BoxABG[0]*pi/180.);
+     333          76 :       double cosB=std::cos(BoxABG[1]*pi/180.);
+     334          76 :       double cosG=std::cos(BoxABG[2]*pi/180.);
+     335          76 :       double sinG=std::sin(BoxABG[2]*pi/180.);
+     336         304 :       for (unsigned i=0; i<3; i++) {Box[i][0]=0.; Box[i][1]=0.; Box[i][2]=0.;}
+     337          76 :       Box[0][0]=BoxXYZ[0];
+     338          76 :       Box[1][0]=BoxXYZ[1]*cosG;
+     339          76 :       Box[1][1]=BoxXYZ[1]*sinG;
+     340          76 :       Box[2][0]=BoxXYZ[2]*cosB;
+     341          76 :       Box[2][1]=(BoxXYZ[2]*BoxXYZ[1]*cosA-Box[2][0]*Box[1][0])/Box[1][1];
+     342          76 :       Box[2][2]=std::sqrt(BoxXYZ[2]*BoxXYZ[2]-Box[2][0]*Box[2][0]-Box[2][1]*Box[2][1]);
+     343             :     }
+     344      427175 :     if(record=="ATOM" || record=="HETATM") {
+     345             :       between_ters=true;
+     346             :       AtomNumber a;
+     347      415463 :       unsigned resno=0; // GB: when resnum string is not present, we set res number to zero
+     348             :       double o,b;
+     349      415463 :       Vector p;
+     350             :       {
+     351             :         int result;
+     352      415463 :         auto trimmed=serial;
+     353      415463 :         Tools::trim(trimmed);
+     354      415525 :         while(trimmed.length()<5) trimmed = std::string(" ") + trimmed;
+     355      415463 :         const char* errmsg = h36::hy36decode(5, trimmed.c_str(),trimmed.length(), &result);
+     356      415463 :         if(errmsg) {
+     357           0 :           std::string msg(errmsg);
+     358           0 :           plumed_merror(msg);
+     359             :         }
+     360      415463 :         a.setSerial(result);
+     361             :       }
+     362             : 
+     363             :       // allow skipping residue number
+     364             :       {
+     365      415463 :         auto trimmed=resnum;
+     366      415463 :         Tools::trim(trimmed);
+     367      415463 :         if(trimmed.length()>0) {
+     368             :           int result;
+     369      415463 :           while(trimmed.length()<4) trimmed = std::string(" ") + trimmed;
+     370      415463 :           const char* errmsg = h36::hy36decode(4, trimmed.c_str(),trimmed.length(), &result);
+     371      415463 :           if(errmsg) {
+     372           0 :             std::string msg(errmsg);
+     373           0 :             plumed_merror(msg);
+     374             :           }
+     375      415463 :           resno=result;
+     376             :         }
+     377             :       }
+     378             : 
+     379      415463 :       Tools::convert(occ,o);
+     380      415463 :       Tools::convert(bet,b);
+     381      415463 :       Tools::convert(x,p[0]);
+     382      415463 :       Tools::convert(y,p[1]);
+     383      415463 :       Tools::convert(z,p[2]);
+     384             :       // scale into nm
+     385      415463 :       p*=scale;
+     386      415463 :       numbers.push_back(a);
+     387      415463 :       number2index[a]=positions.size();
+     388      415463 :       std::size_t startpos=atomname.find_first_not_of(" \t");
+     389      415463 :       std::size_t endpos=atomname.find_last_not_of(" \t");
+     390      415463 :       atomsymb.push_back( atomname.substr(startpos, endpos-startpos+1) );
+     391      415463 :       residue.push_back(resno);
+     392      415463 :       chain.push_back(chainID);
+     393      415463 :       occupancy.push_back(o);
+     394      415463 :       beta.push_back(b);
+     395      415463 :       positions.push_back(p);
+     396      415463 :       residuenames.push_back(residuename);
+     397             :     }
+     398             :   }
+     399        4547 :   if( between_ters ) block_ends.push_back( positions.size() );
+     400        4547 :   return file_is_alive;
+     401             : }
+     402             : 
+     403         422 : bool PDB::read(const std::string&file,bool naturalUnits,double scale) {
+     404         422 :   FILE* fp=std::fopen(file.c_str(),"r");
+     405         422 :   if(!fp) return false;
+     406             : // call fclose when exiting this function
+     407         421 :   auto deleter=[](auto f) { std::fclose(f); };
+     408             :   std::unique_ptr<FILE,decltype(deleter)> fp_deleter(fp,deleter);
+     409         421 :   readFromFilepointer(fp,naturalUnits,scale);
+     410             :   return true;
+     411             : }
+     412             : 
+     413         251 : void PDB::getChainNames( std::vector<std::string>& chains ) const {
+     414         251 :   chains.resize(0);
+     415         251 :   chains.push_back( chain[0] );
+     416      502828 :   for(unsigned i=1; i<size(); ++i) {
+     417      502577 :     if( chains[chains.size()-1]!=chain[i] ) chains.push_back( chain[i] );
+     418             :   }
+     419         251 : }
+     420             : 
+     421       11615 : void PDB::getResidueRange( const std::string& chainname, unsigned& res_start, unsigned& res_end, std::string& errmsg ) const {
+     422             :   bool inres=false, foundchain=false;
+     423    30323369 :   for(unsigned i=0; i<size(); ++i) {
+     424    30311754 :     if( chain[i]==chainname ) {
+     425    26642392 :       if(!inres) {
+     426       11615 :         if(foundchain) errmsg="found second start of chain named " + chainname;
+     427       11615 :         res_start=residue[i];
+     428             :       }
+     429             :       inres=true; foundchain=true;
+     430     3669362 :     } else if( inres && chain[i]!=chainname ) {
+     431             :       inres=false;
+     432       11094 :       res_end=residue[i-1];
+     433             :     }
+     434             :   }
+     435       11615 :   if(inres) res_end=residue[size()-1];
+     436       11615 : }
+     437             : 
+     438         165 : void PDB::getAtomRange( const std::string& chainname, AtomNumber& a_start, AtomNumber& a_end, std::string& errmsg ) const {
+     439             :   bool inres=false, foundchain=false;
+     440      435477 :   for(unsigned i=0; i<size(); ++i) {
+     441      435312 :     if( chain[i]==chainname ) {
+     442       92098 :       if(!inres) {
+     443         165 :         if(foundchain) errmsg="found second start of chain named " + chainname;
+     444         165 :         a_start=numbers[i];
+     445             :       }
+     446             :       inres=true; foundchain=true;
+     447      343214 :     } else if( inres && chain[i]!=chainname ) {
+     448             :       inres=false;
+     449          74 :       a_end=numbers[i-1];
+     450             :     }
+     451             :   }
+     452         165 :   if(inres) a_end=numbers[size()-1];
+     453         165 : }
+     454             : 
+     455        6012 : std::string PDB::getResidueName( const unsigned& resnum ) const {
+     456     7321440 :   for(unsigned i=0; i<size(); ++i) {
+     457     7321440 :     if( residue[i]==resnum ) return residuenames[i];
+     458             :   }
+     459           0 :   std::string num; Tools::convert( resnum, num );
+     460           0 :   plumed_merror("residue " + num + " not found" );
+     461             : }
+     462             : 
+     463       48724 : std::string PDB::getResidueName(const unsigned& resnum,const std::string& chainid ) const {
+     464    62795785 :   for(unsigned i=0; i<size(); ++i) {
+     465    62844689 :     if( residue[i]==resnum && ( chainid=="*" || chain[i]==chainid) ) return residuenames[i];
+     466             :   }
+     467           0 :   std::string num; Tools::convert( resnum, num );
+     468           0 :   plumed_merror("residue " + num + " not found in chain " + chainid );
+     469             : }
+     470             : 
+     471             : 
+     472       13380 : AtomNumber PDB::getNamedAtomFromResidue( const std::string& aname, const unsigned& resnum ) const {
+     473    16356372 :   for(unsigned i=0; i<size(); ++i) {
+     474    16356372 :     if( residue[i]==resnum && atomsymb[i]==aname ) return numbers[i];
+     475             :   }
+     476           0 :   std::string num; Tools::convert( resnum, num );
+     477           0 :   plumed_merror("residue " + num + " does not contain an atom named " + aname );
+     478             : }
+     479             : 
+     480        2352 : AtomNumber PDB::getNamedAtomFromResidueAndChain( const std::string& aname, const unsigned& resnum, const std::string& chainid ) const {
+     481     1086648 :   for(unsigned i=0; i<size(); ++i) {
+     482     1089000 :     if( residue[i]==resnum && atomsymb[i]==aname && ( chainid=="*" || chain[i]==chainid) ) return numbers[i];
+     483             :   }
+     484           0 :   std::string num; Tools::convert( resnum, num );
+     485           0 :   plumed_merror("residue " + num + " from chain " + chainid + " does not contain an atom named " + aname );
+     486             : }
+     487             : 
+     488       34246 : std::vector<AtomNumber> PDB::getAtomsInResidue(const unsigned& resnum,const std::string& chainid)const {
+     489             :   std::vector<AtomNumber> tmp;
+     490    91444766 :   for(unsigned i=0; i<size(); ++i) {
+     491    91931870 :     if( residue[i]==resnum && ( chainid=="*" || chain[i]==chainid) ) tmp.push_back(numbers[i]);
+     492             :   }
+     493       34246 :   if(tmp.size()==0) {
+     494           0 :     std::string num; Tools::convert( resnum, num );
+     495           0 :     plumed_merror("Cannot find residue " + num + " from chain " + chainid  );
+     496             :   }
+     497       34246 :   return tmp;
+     498             : }
+     499             : 
+     500           0 : std::vector<AtomNumber> PDB::getAtomsInChain(const std::string& chainid)const {
+     501             :   std::vector<AtomNumber> tmp;
+     502           0 :   for(unsigned i=0; i<size(); ++i) {
+     503           0 :     if( chainid=="*" || chain[i]==chainid ) tmp.push_back(numbers[i]);
+     504             :   }
+     505           0 :   if(tmp.size()==0) {
+     506           0 :     plumed_merror("Cannot find atoms from chain " + chainid  );
+     507             :   }
+     508           0 :   return tmp;
+     509             : }
+     510             : 
+     511        4686 : std::string PDB::getChainID(const unsigned& resnumber) const {
+     512     5692528 :   for(unsigned i=0; i<size(); ++i) {
+     513     5692528 :     if(resnumber==residue[i]) return chain[i];
+     514             :   }
+     515           0 :   plumed_merror("Not enough residues in pdb input file");
+     516             : }
+     517             : 
+     518           0 : std::string PDB::getChainID(AtomNumber a) const {
+     519             :   const auto p=number2index.find(a);
+     520           0 :   if(p==number2index.end()) {
+     521           0 :     std::string num; Tools::convert( a.serial(), num );
+     522           0 :     plumed_merror("Chain for atom " + num + " not found" );
+     523             :   }
+     524           0 :   return chain[p->second];
+     525             : }
+     526             : 
+     527           0 : bool PDB::checkForResidue( const std::string& name ) const {
+     528           0 :   for(unsigned i=0; i<size(); ++i) {
+     529           0 :     if( residuenames[i]==name ) return true;
+     530             :   }
+     531             :   return false;
+     532             : }
+     533             : 
+     534           0 : bool PDB::checkForAtom( const std::string& name ) const {
+     535           0 :   for(unsigned i=0; i<size(); ++i) {
+     536           0 :     if( atomsymb[i]==name ) return true;
+     537             :   }
+     538             :   return false;
+     539             : }
+     540             : 
+     541         249 : bool PDB::checkForAtom( AtomNumber a ) const {
+     542             :   const auto p=number2index.find(a);
+     543         249 :   return (p!=number2index.end());
+     544             : }
+     545             : 
+     546           0 : Log& operator<<(Log& ostr, const PDB&  pdb) {
+     547             :   const std::size_t bufferlen=1000;
+     548             :   char buffer[bufferlen];
+     549           0 :   for(unsigned i=0; i<pdb.positions.size(); i++) {
+     550           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]);
+     551           0 :     ostr<<buffer;
+     552             :   }
+     553           0 :   return ostr;
+     554             : }
+     555             : 
+     556        1038 : Vector PDB::getPosition(AtomNumber a)const {
+     557             :   const auto p=number2index.find(a);
+     558        1038 :   if(p==number2index.end()) plumed_merror("atom not available");
+     559        1038 :   else return positions[p->second];
+     560             : }
+     561             : 
+     562           0 : std::vector<std::string> PDB::getArgumentNames()const {
+     563           0 :   return argnames;
+     564             : }
+     565             : 
+     566           0 : std::string PDB::getMtype() const {
+     567           0 :   return mtype;
+     568             : }
+     569             : 
+     570           0 : void PDB::print( const double& lunits, GenericMolInfo* mymoldat, OFile& ofile, const std::string& fmt ) {
+     571           0 :   if( argnames.size()>0 ) {
+     572           0 :     ofile.printf("REMARK ARG=%s", argnames[0].c_str() );
+     573           0 :     for(unsigned i=1; i<argnames.size(); ++i) ofile.printf(",%s",argnames[i].c_str() );
+     574           0 :     ofile.printf("\n"); ofile.printf("REMARK ");
+     575             :   }
+     576             :   std::string descr2;
+     577           0 :   if(fmt.find("-")!=std::string::npos) {
+     578           0 :     descr2="%s=" + fmt + " ";
+     579             :   } else {
+     580             :     // This ensures numbers are left justified (i.e. next to the equals sign
+     581           0 :     std::size_t psign=fmt.find("%");
+     582           0 :     plumed_assert( psign!=std::string::npos );
+     583           0 :     descr2="%s=%-" + fmt.substr(psign+1) + " ";
+     584             :   }
+     585           0 :   for(std::map<std::string,std::vector<double> >::iterator it=arg_data.begin(); it!=arg_data.end(); ++it) ofile.printf( descr2.c_str(),it->first.c_str(), it->second[0] );
+     586           0 :   if( argnames.size()>0 ) ofile.printf("\n");
+     587           0 :   if( !mymoldat ) {
+     588           0 :     for(unsigned i=0; i<positions.size(); ++i) {
+     589             :       std::array<char,6> at;
+     590             :       {
+     591           0 :         const char* msg = h36::hy36encode(5,numbers[i].serial(),&at[0]);
+     592           0 :         plumed_assert(msg==nullptr) << msg;
+     593           0 :         at[5]=0;
+     594             :       }
+     595             :       std::array<char,5> res;
+     596             :       {
+     597           0 :         const char* msg = h36::hy36encode(4,i,&res[0]);
+     598           0 :         plumed_assert(msg==nullptr) << msg;
+     599           0 :         res[4]=0;
+     600             :       }
+     601           0 :       ofile.printf("ATOM  %s  X   RES  %s    %8.3f%8.3f%8.3f%6.2f%6.2f\n",
+     602             :                    &at[0], &res[0],
+     603           0 :                    lunits*positions[i][0], lunits*positions[i][1], lunits*positions[i][2],
+     604             :                    occupancy[i], beta[i] );
+     605             :     }
+     606             :   } else {
+     607           0 :     for(unsigned i=0; i<positions.size(); ++i) {
+     608             :       std::array<char,6> at;
+     609             :       {
+     610           0 :         const char* msg = h36::hy36encode(5,numbers[i].serial(),&at[0]);
+     611           0 :         plumed_assert(msg==nullptr) << msg;
+     612           0 :         at[5]=0;
+     613             :       }
+     614             :       std::array<char,5> res;
+     615             :       {
+     616           0 :         const char* msg = h36::hy36encode(4,mymoldat->getResidueNumber(numbers[i]),&res[0]);
+     617           0 :         plumed_assert(msg==nullptr) << msg;
+     618           0 :         res[4]=0;
+     619             :       }
+     620           0 :       ofile.printf("ATOM  %s %-4s %3s  %s    %8.3f%8.3f%8.3f%6.2f%6.2f\n",
+     621           0 :                    &at[0], mymoldat->getAtomName(numbers[i]).c_str(),
+     622           0 :                    mymoldat->getResidueName(numbers[i]).c_str(), &res[0],
+     623           0 :                    lunits*positions[i][0], lunits*positions[i][1], lunits*positions[i][2],
+     624             :                    occupancy[i], beta[i] );
+     625             :     }
+     626             :   }
+     627           0 :   ofile.printf("END\n");
+     628           0 : }
+     629             : 
+     630       37562 : bool PDB::allowedResidue( const std::string& type, const std::string& residuename ) const {
+     631       37562 :   if( type=="protein" ) {
+     632       37562 :     if(residuename=="ALA") return true;
+     633       35552 :     else if(residuename=="ARG") return true;
+     634       33312 :     else if(residuename=="ASN") return true;
+     635       31392 :     else if(residuename=="ASP") return true;
+     636       29712 :     else if(residuename=="CYS") return true;
+     637       29582 :     else if(residuename=="GLN") return true;
+     638       26782 :     else if(residuename=="GLU") return true;
+     639       25522 :     else if(residuename=="GLY") return true;
+     640       23702 :     else if(residuename=="HIS") return true;
+     641       23702 :     else if(residuename=="ILE") return true;
+     642       21452 :     else if(residuename=="LEU") return true;
+     643       17462 :     else if(residuename=="LYS") return true;
+     644       14762 :     else if(residuename=="MET") return true;
+     645       13162 :     else if(residuename=="PHE") return true;
+     646       10522 :     else if(residuename=="PRO") return true;
+     647        8542 :     else if(residuename=="SER") return true;
+     648        7112 :     else if(residuename=="THR") return true;
+     649        5762 :     else if(residuename=="TRP") return true;
+     650        5762 :     else if(residuename=="TYR") return true;
+     651        4382 :     else if(residuename=="VAL") return true;
+     652             : // Terminal groups
+     653        1492 :     else if(residuename=="ACE") return true;
+     654        1492 :     else if(residuename=="NME") return true;
+     655        1492 :     else if(residuename=="NH2") return true;
+     656             : // Alternative residue names in common force fields
+     657        1492 :     else if(residuename=="GLH") return true; // neutral GLU
+     658        1492 :     else if(residuename=="ASH") return true; // neutral ASP
+     659        1492 :     else if(residuename=="HID") return true; // HIS-D amber
+     660        1492 :     else if(residuename=="HSD") return true; // HIS-D charmm
+     661        1492 :     else if(residuename=="HIE") return true; // HIS-E amber
+     662        1112 :     else if(residuename=="HSE") return true; // HIS-E charmm
+     663        1112 :     else if(residuename=="HIP") return true; // HIS-P amber
+     664        1112 :     else if(residuename=="HSP") return true; // HIS-P charmm
+     665             : // Weird amino acids
+     666        1112 :     else if(residuename=="NLE") return true;
+     667        1112 :     else if(residuename=="SFO") return true;
+     668        1112 :     else return false;
+     669           0 :   } else if( type=="dna" ) {
+     670           0 :     if(residuename=="A") return true;
+     671           0 :     else if(residuename=="A5") return true;
+     672           0 :     else if(residuename=="A3") return true;
+     673           0 :     else if(residuename=="AN") return true;
+     674           0 :     else if(residuename=="G") return true;
+     675           0 :     else if(residuename=="G5") return true;
+     676           0 :     else if(residuename=="G3") return true;
+     677           0 :     else if(residuename=="GN") return true;
+     678           0 :     else if(residuename=="T") return true;
+     679           0 :     else if(residuename=="T5") return true;
+     680           0 :     else if(residuename=="T3") return true;
+     681           0 :     else if(residuename=="TN") return true;
+     682           0 :     else if(residuename=="C") return true;
+     683           0 :     else if(residuename=="C5") return true;
+     684           0 :     else if(residuename=="C3") return true;
+     685           0 :     else if(residuename=="CN") return true;
+     686           0 :     else if(residuename=="DA") return true;
+     687           0 :     else if(residuename=="DA5") return true;
+     688           0 :     else if(residuename=="DA3") return true;
+     689           0 :     else if(residuename=="DAN") return true;
+     690           0 :     else if(residuename=="DG") return true;
+     691           0 :     else if(residuename=="DG5") return true;
+     692           0 :     else if(residuename=="DG3") return true;
+     693           0 :     else if(residuename=="DGN") return true;
+     694           0 :     else if(residuename=="DT") return true;
+     695           0 :     else if(residuename=="DT5") return true;
+     696           0 :     else if(residuename=="DT3") return true;
+     697           0 :     else if(residuename=="DTN") return true;
+     698           0 :     else if(residuename=="DC") return true;
+     699           0 :     else if(residuename=="DC5") return true;
+     700           0 :     else if(residuename=="DC3") return true;
+     701           0 :     else if(residuename=="DCN") return true;
+     702           0 :     else return false;
+     703           0 :   } else if( type=="rna" ) {
+     704           0 :     if(residuename=="A") return true;
+     705           0 :     else if(residuename=="A5") return true;
+     706           0 :     else if(residuename=="A3") return true;
+     707           0 :     else if(residuename=="AN") return true;
+     708           0 :     else if(residuename=="G") return true;
+     709           0 :     else if(residuename=="G5") return true;
+     710           0 :     else if(residuename=="G3") return true;
+     711           0 :     else if(residuename=="GN") return true;
+     712           0 :     else if(residuename=="U") return true;
+     713           0 :     else if(residuename=="U5") return true;
+     714           0 :     else if(residuename=="U3") return true;
+     715           0 :     else if(residuename=="UN") return true;
+     716           0 :     else if(residuename=="C") return true;
+     717           0 :     else if(residuename=="C5") return true;
+     718           0 :     else if(residuename=="C3") return true;
+     719           0 :     else if(residuename=="CN") return true;
+     720           0 :     else if(residuename=="RA") return true;
+     721           0 :     else if(residuename=="RA5") return true;
+     722           0 :     else if(residuename=="RA3") return true;
+     723           0 :     else if(residuename=="RAN") return true;
+     724           0 :     else if(residuename=="RG") return true;
+     725           0 :     else if(residuename=="RG5") return true;
+     726           0 :     else if(residuename=="RG3") return true;
+     727           0 :     else if(residuename=="RGN") return true;
+     728           0 :     else if(residuename=="RU") return true;
+     729           0 :     else if(residuename=="RU5") return true;
+     730           0 :     else if(residuename=="RU3") return true;
+     731           0 :     else if(residuename=="RUN") return true;
+     732           0 :     else if(residuename=="RC") return true;
+     733           0 :     else if(residuename=="RC5") return true;
+     734           0 :     else if(residuename=="RC3") return true;
+     735           0 :     else if(residuename=="RCN") return true;
+     736           0 :     else return false;
+     737           0 :   } else if( type=="water" ) {
+     738           0 :     if(residuename=="SOL") return true;
+     739           0 :     if(residuename=="WAT") return true;
+     740           0 :     return false;
+     741           0 :   } else if( type=="ion" ) {
+     742           0 :     if(residuename=="IB+") return true;
+     743           0 :     if(residuename=="CA") return true;
+     744           0 :     if(residuename=="CL") return true;
+     745           0 :     if(residuename=="NA") return true;
+     746           0 :     if(residuename=="MG") return true;
+     747           0 :     if(residuename=="K") return true;
+     748           0 :     if(residuename=="RB") return true;
+     749           0 :     if(residuename=="CS") return true;
+     750           0 :     if(residuename=="LI") return true;
+     751           0 :     if(residuename=="ZN") return true;
+     752           0 :     return false;
+     753             :   }
+     754             :   return false;
+     755             : }
+     756             : 
+     757             : }
+     758             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Pbc.cpp.func-sort-c.html b/coverage/tools/Pbc.cpp.func-sort-c.html new file mode 100644 index 000000000000..446c11cb2595 --- /dev/null +++ b/coverage/tools/Pbc.cpp.func-sort-c.html @@ -0,0 +1,125 @@ + + + + + + + + LCOV - plumed test coverage - tools/Pbc.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Pbc.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12412996.1 %
Date:2024-04-19 12:12:35Functions:121392.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD3Pbc8distanceEbRKNS_13VectorGenericILj3EEES4_0
_ZNK4PLMD3Pbc13isOrthorombicEv8566
_ZNK4PLMD3Pbc11buildShiftsEPA2_A2_NS_3gch12small_vectorINS_13VectorGenericILj3EEELj6ESaIS4_EEE19977
_ZN4PLMD3PbcC2Ev26125
_ZNK4PLMD3Pbc6getBoxEv28503
_ZNK4PLMD3Pbc9getInvBoxEv45429
_ZN4PLMD3Pbc6setBoxERKNS_13TensorGenericILj3ELj3EEE90597
_ZNK4PLMD3Pbc12scaledToRealERKNS_13VectorGenericILj3EEE201929
_ZNK4PLMD3Pbc5applyENS_12mdMemoryViewILm18446744073709551615ELm3EEEj405876
_ZNK4PLMD3Pbc5applyERSt6vectorINS_13VectorGenericILj3EEESaIS3_EEj405876
_ZNK4PLMD3Pbc10fullSearchERNS_13VectorGenericILj3EEE600000
_ZNK4PLMD3Pbc12realToScaledERKNS_13VectorGenericILj3EEE1958610
_ZNK4PLMD3Pbc8distanceERKNS_13VectorGenericILj3EEES4_Pi556163753
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Pbc.cpp.func.html b/coverage/tools/Pbc.cpp.func.html new file mode 100644 index 000000000000..05f275731f3d --- /dev/null +++ b/coverage/tools/Pbc.cpp.func.html @@ -0,0 +1,125 @@ + + + + + + + + LCOV - plumed test coverage - tools/Pbc.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Pbc.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12412996.1 %
Date:2024-04-19 12:12:35Functions:121392.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3Pbc6setBoxERKNS_13TensorGenericILj3ELj3EEE90597
_ZN4PLMD3PbcC2Ev26125
_ZNK4PLMD3Pbc10fullSearchERNS_13VectorGenericILj3EEE600000
_ZNK4PLMD3Pbc11buildShiftsEPA2_A2_NS_3gch12small_vectorINS_13VectorGenericILj3EEELj6ESaIS4_EEE19977
_ZNK4PLMD3Pbc12realToScaledERKNS_13VectorGenericILj3EEE1958610
_ZNK4PLMD3Pbc12scaledToRealERKNS_13VectorGenericILj3EEE201929
_ZNK4PLMD3Pbc13isOrthorombicEv8566
_ZNK4PLMD3Pbc5applyENS_12mdMemoryViewILm18446744073709551615ELm3EEEj405876
_ZNK4PLMD3Pbc5applyERSt6vectorINS_13VectorGenericILj3EEESaIS3_EEj405876
_ZNK4PLMD3Pbc6getBoxEv28503
_ZNK4PLMD3Pbc8distanceERKNS_13VectorGenericILj3EEES4_Pi556163753
_ZNK4PLMD3Pbc8distanceEbRKNS_13VectorGenericILj3EEES4_0
_ZNK4PLMD3Pbc9getInvBoxEv45429
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Pbc.cpp.gcov.html b/coverage/tools/Pbc.cpp.gcov.html new file mode 100644 index 000000000000..78bc9d0371a6 --- /dev/null +++ b/coverage/tools/Pbc.cpp.gcov.html @@ -0,0 +1,368 @@ + + + + + + + + LCOV - plumed test coverage - tools/Pbc.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Pbc.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12412996.1 %
Date:2024-04-19 12:12:35Functions:121392.3 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "Pbc.h"
+      23             : #include "Tools.h"
+      24             : #include "Exception.h"
+      25             : #include "LatticeReduction.h"
+      26             : #include <iostream>
+      27             : #include "Random.h"
+      28             : #include <cmath>
+      29             : 
+      30             : namespace PLMD {
+      31             : 
+      32       26125 : Pbc::Pbc():
+      33      391875 :   type(unset)
+      34             : {
+      35       26125 :   box.zero();
+      36       26125 :   invBox.zero();
+      37       26125 : }
+      38             : 
+      39       19977 : void Pbc::buildShifts(gch::small_vector<Vector,maxshiftsize> shifts[2][2][2])const {
+      40             :   const double small=1e-28;
+      41             : 
+      42             : // clear all shifts
+      43      299655 :   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      799080 :   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      539379 :         const int ishift[3]= {l,m,n};
+      51      539379 :         Vector dshift(l,m,n);
+      52             : 
+      53             : // count how many components are != 0
+      54             :         unsigned count=0;
+      55     2157516 :         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      618683 :         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      359586 :         Vector cosdir=matmul(reduced,transpose(reduced),dshift);
+      66      359586 :         double dp=dotProduct(dshift,cosdir);
+      67      359586 :         double ref=modulo2(dshift)*modulo2(cosdir);
+      68      359586 :         if(std::fabs(ref-dp*dp)<small) continue;
+      69             : 
+      70             : // here we start pruning depending on the sign of the scaled coordinate
+      71     4204230 :         for(int i=0; i<2; i++) for(int j=0; j<2; j++) for(int k=0; k<2; k++) {
+      72             : 
+      73     2242256 :               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     8969024 :               for(int s=0; s<3; s++) if(ishift[s]*block[s]>0) skip=true;
+      78     2533180 :               if(skip) continue;
+      79             :               skip=true;
+      80     3064848 :               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     2298636 :                 if(((1-ishift[s]*ishift[s])*block[s])*cosdir[s]<-small) skip=false;
+      84             :               }
+      85      766212 :               if(skip)continue;
+      86             : 
+      87             : // if we arrive to this point, shift is eligible and is added to the list
+      88      950576 :               shifts[i][j][k].push_back(matmul(transpose(reduced),dshift));
+      89             :             }
+      90             :       }
+      91       19977 : }
+      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       90597 : void Pbc::setBox(const Tensor&b) {
+     116       90597 :   box=b;
+     117             : // detect type:
+     118             :   const double epsilon=1e-28;
+     119             : 
+     120       90597 :   type=unset;
+     121       90597 :   double det=box.determinant();
+     122       90597 :   if(det*det<epsilon) return;
+     123             : 
+     124             :   bool cxy=false;
+     125             :   bool cxz=false;
+     126             :   bool cyz=false;
+     127       88596 :   if(box(0,1)*box(0,1)<epsilon && box(1,0)*box(1,0)<epsilon) cxy=true;
+     128       88596 :   if(box(0,2)*box(0,2)<epsilon && box(2,0)*box(2,0)<epsilon) cxz=true;
+     129       88596 :   if(box(1,2)*box(1,2)<epsilon && box(2,1)*box(2,1)<epsilon) cyz=true;
+     130             : 
+     131       88596 :   invBox=box.inverse();
+     132             : 
+     133       88596 :   if(cxy && cxz && cyz) type=orthorombic;
+     134       19977 :   else type=generic;
+     135             : 
+     136       88596 :   if(type==orthorombic) {
+     137       68619 :     reduced=box;
+     138       68619 :     invReduced=inverse(reduced);
+     139      274476 :     for(unsigned i=0; i<3; i++) {
+     140      205857 :       diag[i]=box[i][i];
+     141      205857 :       hdiag[i]=0.5*box[i][i];
+     142      205857 :       mdiag[i]=-0.5*box[i][i];
+     143             :     }
+     144             :   } else {
+     145       19977 :     reduced=box;
+     146       19977 :     LatticeReduction::reduce(reduced);
+     147       19977 :     invReduced=inverse(reduced);
+     148       19977 :     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      405876 : void Pbc::apply(std::vector<Vector>& dlist, unsigned max_index) const {
+     159      405876 :   apply(VectorView(&dlist[0][0],dlist.size()),max_index);
+     160      405876 : }
+     161             : 
+     162      405876 : void Pbc::apply(VectorView dlist, unsigned max_index) const {
+     163      405876 :   if (max_index==0) max_index=dlist.size();
+     164      405876 :   if(type==unset) {
+     165             :     // do nothing
+     166      405872 :   } else if(type==orthorombic) {
+     167             : #ifdef __PLUMED_PBC_WHILE
+     168             :     for(unsigned k=0; k<max_index; ++k) {
+     169             :       while(dlist[k][0]>hdiag[0])   dlist[k][0]-=diag[0];
+     170             :       while(dlist[k][0]<=mdiag[0])  dlist[k][0]+=diag[0];
+     171             :       while(dlist[k][1]>hdiag[1])   dlist[k][1]-=diag[1];
+     172             :       while(dlist[k][1]<=mdiag[1])  dlist[k][1]+=diag[1];
+     173             :       while(dlist[k][2]>hdiag[2])   dlist[k][2]-=diag[2];
+     174             :       while(dlist[k][2]<=mdiag[2])  dlist[k][2]+=diag[2];
+     175             :     }
+     176             : #else
+     177    26205115 :     for(unsigned k=0; k<max_index; ++k) {
+     178   103197924 :       for(int i=0; i<3; i++) {
+     179    77398443 :         dlist[k][i]=Tools::pbc(dlist[k][i]*invBox(i,i))*box(i,i);
+     180             :       }
+     181             :     }
+     182             : #endif
+     183         238 :   } else if(type==generic) {
+     184       21116 :     for(unsigned k=0; k<max_index; ++k) {
+     185             :       //Inlining by hand this part of function from distance speeds up by about 20-30%
+     186             :       //against the previos version, and 60-80% agains this version non inlined.
+     187             :       //I do not think is the `if(nshifts) *nshifts+=myshifts.size();`,
+     188             :       //but that the compiler now see how we are juggling with the memory and it
+     189             :       //does its magic
+     190             : 
+     191             :       //I tried writing VectorGeneric<3> matmul(const MemoryView<3UL> a,const TensorGeneric<3,3>&b)
+     192             :       // by copy-pasting the original vector-tensor, but slows down this method by 10%... (on gcc9)
+     193       20878 :       Vector s=matmul(Vector{dlist[k][0],dlist[k][1],dlist[k][2]},invReduced);
+     194             :       // bring to -0.5,+0.5 region in scaled coordinates:
+     195       83512 :       for(int i=0; i<3; ++i) {
+     196       62634 :         s[i]=Tools::pbc(s[i]);
+     197             :       }
+     198       20878 :       Vector best(matmul(s,reduced));
+     199             :       // check if shifts have to be attempted:
+     200       20878 :       if((std::fabs(s[0])+std::fabs(s[1])+std::fabs(s[2])>0.5)) {
+     201             :         // list of shifts is specific for that "octant" (depends on signs of s[i]):
+     202       34605 :         const auto & myshifts(shifts[(s[0]>0?1:0)][(s[1]>0?1:0)][(s[2]>0?1:0)]);
+     203       17298 :         Vector reference = best;
+     204       17298 :         double lbest(modulo2(best));
+     205             :         // loop over possible shifts:
+     206       81547 :         for(unsigned i=0; i<myshifts.size(); ++i) {
+     207       64249 :           Vector trial=reference+myshifts[i];
+     208       64249 :           double ltrial=modulo2(trial);
+     209       64249 :           if(ltrial<lbest) {
+     210             :             lbest=ltrial;
+     211        1433 :             best=trial;
+     212             :           }
+     213             :         }
+     214             :       }
+     215       20878 :       dlist[k][0]  = best[0];
+     216       20878 :       dlist[k][1]  = best[1];
+     217       20878 :       dlist[k][2]  = best[2];
+     218             :     }
+     219           0 :   } else plumed_merror("unknown pbc type");
+     220      405876 : }
+     221             : 
+     222   556163753 : Vector Pbc::distance(const Vector&v1,const Vector&v2,int*nshifts)const {
+     223   556163753 :   Vector d=delta(v1,v2);
+     224   556163753 :   if(type==unset) {
+     225             :     // do nothing
+     226   532404721 :   } else if(type==orthorombic) {
+     227             : #ifdef __PLUMED_PBC_WHILE
+     228             :     for(unsigned i=0; i<3; i++) {
+     229             :       while(d[i]>hdiag[i]) d[i]-=diag[i];
+     230             :       while(d[i]<=mdiag[i]) d[i]+=diag[i];
+     231             :     }
+     232             : #else
+     233  1936724808 :     for(int i=0; i<3; i++) d[i]=Tools::pbc(d[i]*invBox(i,i))*box(i,i);
+     234             : #endif
+     235    48223519 :   } else if(type==generic) {
+     236    48223519 :     Vector s=matmul(d,invReduced);
+     237             : // check if images have to be computed:
+     238             : //    if((std::fabs(s[0])+std::fabs(s[1])+std::fabs(s[2])>0.5)){
+     239             : // NOTICE: the check in the previous line, albeit correct, is breaking many regtest
+     240             : //         since it does not apply Tools::pbc in many cases. Moreover, it does not
+     241             : //         introduce a significant gain. I thus leave it out for the moment.
+     242             :     if constexpr (true) {
+     243             : // bring to -0.5,+0.5 region in scaled coordinates:
+     244   192894076 :       for(int i=0; i<3; i++) {
+     245   144670557 :         s[i]=Tools::pbc(s[i]);
+     246             :       }
+     247    48223519 :       d=matmul(s,reduced);
+     248             : // check if shifts have to be attempted:
+     249    48223519 :       if((std::fabs(s[0])+std::fabs(s[1])+std::fabs(s[2])>0.5)) {
+     250             : // list of shifts is specific for that "octant" (depends on signs of s[i]):
+     251    78664302 :         const auto & myshifts(shifts[(s[0]>0?1:0)][(s[1]>0?1:0)][(s[2]>0?1:0)]);
+     252    39816653 :         Vector best(d);
+     253    39816653 :         double lbest(modulo2(best));
+     254             : // loop over possible shifts:
+     255    39816653 :         if(nshifts) *nshifts+=myshifts.size();
+     256   179244081 :         for(unsigned i=0; i<myshifts.size(); i++) {
+     257   139427428 :           Vector trial=d+myshifts[i];
+     258   139427428 :           double ltrial=modulo2(trial);
+     259   139427428 :           if(ltrial<lbest) {
+     260             :             lbest=ltrial;
+     261     3759325 :             best=trial;
+     262             :           }
+     263             :         }
+     264    39816653 :         d=best;
+     265             :       }
+     266             :     }
+     267           0 :   } else plumed_merror("unknown pbc type");
+     268   556163753 :   return d;
+     269             : }
+     270             : 
+     271     1958610 : Vector Pbc::realToScaled(const Vector&d)const {
+     272     1958610 :   return matmul(invBox.transpose(),d);
+     273             : }
+     274             : 
+     275      201929 : Vector Pbc::scaledToReal(const Vector&d)const {
+     276      201929 :   return matmul(box.transpose(),d);
+     277             : }
+     278             : 
+     279        8566 : bool Pbc::isOrthorombic()const {
+     280        8566 :   return type==orthorombic;
+     281             : }
+     282             : 
+     283       28503 : const Tensor& Pbc::getBox()const {
+     284       28503 :   return box;
+     285             : }
+     286             : 
+     287       45429 : const Tensor& Pbc::getInvBox()const {
+     288       45429 :   return invBox;
+     289             : }
+     290             : 
+     291             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Pbc.h.func-sort-c.html b/coverage/tools/Pbc.h.func-sort-c.html new file mode 100644 index 000000000000..e46292af398f --- /dev/null +++ b/coverage/tools/Pbc.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage - tools/Pbc.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Pbc.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:5683.3 %
Date:2024-04-19 12:12:35Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Pbc.h.func.html b/coverage/tools/Pbc.h.func.html new file mode 100644 index 000000000000..09230546ed7e --- /dev/null +++ b/coverage/tools/Pbc.h.func.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage - tools/Pbc.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Pbc.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:5683.3 %
Date:2024-04-19 12:12:35Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Pbc.h.gcov.html b/coverage/tools/Pbc.h.gcov.html new file mode 100644 index 000000000000..62202da8e7b3 --- /dev/null +++ b/coverage/tools/Pbc.h.gcov.html @@ -0,0 +1,225 @@ + + + + + + + + LCOV - plumed test coverage - tools/Pbc.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Pbc.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:5683.3 %
Date:2024-04-19 12:12:35Functions:00-
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_tools_Pbc_h
+      23             : #define __PLUMED_tools_Pbc_h
+      24             : 
+      25             : #include "Vector.h"
+      26             : #include "Tensor.h"
+      27             : #include "small_vector/small_vector.h"
+      28             : #include <vector>
+      29             : #include <cstddef>
+      30             : 
+      31             : namespace PLMD {
+      32             : 
+      33             : //this more or less mocks c++20 span with fixed size
+      34             : template < std::size_t N=3>
+      35             : class MemoryView {
+      36             :   double *ptr_;
+      37             : public:
+      38             :   MemoryView(double* p) :ptr_(p) {}
+      39             :   constexpr size_t size()const {return N;}
+      40             :   static constexpr size_t extent = N;
+      41    77398443 :   double & operator[](size_t i) { return ptr_[i];}
+      42             :   const double & operator[](size_t i) const { return ptr_[i];}
+      43             : };
+      44             : 
+      45             : namespace helpers {
+      46             : inline constexpr std::size_t dynamic_extent = -1;
+      47             : }
+      48             : //this more or less mocks c++23 mdspan without the fancy multi-indexed operator[]
+      49             : //the idea is to take an address that you know to be strided in a certain way and
+      50             : //make it avaiable to any interface (like using the data from a nunmpy.ndarray in
+      51             : //a function thought for a std::vector<PLMD::Vector> )
+      52             : //the N=-1 is there for mocking the run time size from the span (where a
+      53             : //dynamic extent is size_t(-))
+      54             : template < std::size_t N=helpers::dynamic_extent, std::size_t STRIDE=3>
+      55             : class mdMemoryView {
+      56             :   double *ptr_;
+      57             :   size_t size_;
+      58             : public:
+      59      405876 :   mdMemoryView(double* p, size_t s) :ptr_(p), size_(s) {}
+      60           0 :   size_t size()const {return size_;}
+      61             :   static constexpr size_t extent = N;
+      62             :   static constexpr size_t stride = STRIDE;
+      63    77419321 :   MemoryView<STRIDE> operator[](size_t i) { return MemoryView<STRIDE>(ptr_ + i * STRIDE);}
+      64             : };
+      65             : 
+      66             : using VectorView = mdMemoryView<helpers::dynamic_extent, 3>;
+      67             : 
+      68             : /*
+      69             : Tool to deal with periodic boundary conditions.
+      70             : 
+      71             : This class is useful to apply periodic boundary conditions on interatomic
+      72             : distances. It stores privately information about reduced lattice vectors
+      73             : */
+      74        3006 : class Pbc {
+      75             : /// Type of box
+      76             :   enum {unset,orthorombic,generic} type;
+      77             : /// This is the maximum expected size for general boxes.
+      78             : /// I found this empirically by manually modifying regtest basic/rt-make-1
+      79             : /// Since it uses randomly generated boxes it should be correct.
+      80             : /// In any case, this is just used as a hint for small_vector,
+      81             : /// which will then switch to heap allocations if more shifts are needed
+      82             :   static constexpr unsigned maxshiftsize=6;
+      83             : /// Box
+      84             :   Tensor box;
+      85             : /// Inverse box
+      86             :   Tensor invBox;
+      87             : /// Reduced box.
+      88             : /// This is a set of lattice vectors generating the same lattice
+      89             : /// but "minimally skewed". Useful to optimize image search.
+      90             :   Tensor reduced;
+      91             : /// Inverse of the reduced box
+      92             :   Tensor invReduced;
+      93             : /// List of shifts that should be attempted.
+      94             : /// Depending on the sign of the scaled coordinates representing
+      95             : /// a distance vector, a different set of shifts must be tried.
+      96             :   gch::small_vector<Vector,maxshiftsize> shifts[2][2][2];
+      97             : /// Alternative representation for orthorombic cells.
+      98             : /// Not really used, but could be used to optimize search in
+      99             : /// orthorombic cells.
+     100             :   Vector diag,hdiag,mdiag;
+     101             : /// Build list of shifts.
+     102             : /// This is expensive, and must be called only when box is
+     103             : /// reset. It allows building a minimal set of shifts
+     104             : /// depending on the sign of the scaled coordinates representing
+     105             : /// a distance vector.
+     106             :   void buildShifts(gch::small_vector<Vector,maxshiftsize> shifts[2][2][2])const;
+     107             : public:
+     108             : /// Constructor
+     109             :   Pbc();
+     110             : /// Compute modulo of (v2-v1), using or not pbc depending on bool pbc.
+     111             :   double distance( const bool pbc, const Vector& v1, const Vector& v2 ) const;
+     112             : /// Computes v2-v1, using minimal image convention
+     113             : /// if specified, also returns the number of attempted shifts
+     114             :   Vector distance(const Vector&, const Vector&,int*nshifts=nullptr)const;
+     115             : /// Apply PBC to a set of positions or distance vectors
+     116             :   void apply(VectorView dlist, unsigned max_index=0) const;
+     117             :   void apply(std::vector<Vector>&dlist, unsigned max_index=0) const;
+     118             : /// Set the lattice vectors.
+     119             : /// b[i][j] is the j-th component of the i-th vector
+     120             :   void setBox(const Tensor&b);
+     121             : /// Returns the box
+     122             :   const Tensor& getBox()const;
+     123             : /// Returns the inverse matrix of box.
+     124             : /// Thus: pbc.getInvBox() == inverse(pbc.getBox()).
+     125             :   const Tensor& getInvBox()const;
+     126             : /// Transform a vector in real space to a vector in scaled coordinates.
+     127             : /// Thus:pbc.realToScaled(v) == matmul(transpose(inverse(pbc.getBox(),v)));
+     128             :   Vector realToScaled(const Vector&)const;
+     129             : /// Transform a vector in scaled coordinates to a vector in real space.
+     130             : /// Thus:pbc.scaledToRead(v) == matmul(transpose(pbc.getBox()),v);
+     131             :   Vector scaledToReal(const Vector&)const;
+     132             : /// Returns true if the box vectors are orthogonal
+     133             :   bool isOrthorombic()const;
+     134             : /// Full search (for testing).
+     135             : /// Perform a full search on vector
+     136             :   void fullSearch(Vector&)const;
+     137             : /// Returns true if box is set and non zero
+     138             :   bool isSet()const;
+     139             : };
+     140             : 
+     141             : inline
+     142             : bool Pbc::isSet()const {
+     143       33420 :   return type!=unset;
+     144             : }
+     145             : 
+     146             : }
+     147             : 
+     148             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/PlumedHandle.cpp.func-sort-c.html b/coverage/tools/PlumedHandle.cpp.func-sort-c.html new file mode 100644 index 000000000000..f3c1696231da --- /dev/null +++ b/coverage/tools/PlumedHandle.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - tools/PlumedHandle.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - PlumedHandle.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:233663.9 %
Date:2024-04-19 12:12:35Functions:5862.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12PlumedHandleC2EOS0_0
_ZN4PLMD12PlumedHandleD0Ev0
_ZN4PLMD12PlumedHandleaSEOS0_0
_ZN4PLMD12PlumedHandle6dlopenEPKc1
_ZN4PLMD12PlumedHandleC2EPKc1
_ZN4PLMD12PlumedHandleC2Ev11
_ZN4PLMD12PlumedHandleD2Ev12
_ZN4PLMD12PlumedHandle3cmdESt17basic_string_viewIcSt11char_traitsIcEERKNS_11TypesafePtrE1476
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/PlumedHandle.cpp.func.html b/coverage/tools/PlumedHandle.cpp.func.html new file mode 100644 index 000000000000..a77eb5705e47 --- /dev/null +++ b/coverage/tools/PlumedHandle.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - tools/PlumedHandle.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - PlumedHandle.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:233663.9 %
Date:2024-04-19 12:12:35Functions:5862.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12PlumedHandle3cmdESt17basic_string_viewIcSt11char_traitsIcEERKNS_11TypesafePtrE1476
_ZN4PLMD12PlumedHandle6dlopenEPKc1
_ZN4PLMD12PlumedHandleC2EOS0_0
_ZN4PLMD12PlumedHandleC2EPKc1
_ZN4PLMD12PlumedHandleC2Ev11
_ZN4PLMD12PlumedHandleD0Ev0
_ZN4PLMD12PlumedHandleD2Ev12
_ZN4PLMD12PlumedHandleaSEOS0_0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/PlumedHandle.cpp.gcov.html b/coverage/tools/PlumedHandle.cpp.gcov.html new file mode 100644 index 000000000000..7929dfc02ce7 --- /dev/null +++ b/coverage/tools/PlumedHandle.cpp.gcov.html @@ -0,0 +1,185 @@ + + + + + + + + LCOV - plumed test coverage - tools/PlumedHandle.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - PlumedHandle.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:233663.9 %
Date:2024-04-19 12:12:35Functions:5862.5 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2018-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "PlumedHandle.h"
+      23             : #include "core/PlumedMain.h"
+      24             : #include "Tools.h"
+      25             : #include "lepton/Exception.h"
+      26             : #include <cstring>
+      27             : #ifdef __PLUMED_HAS_DLOPEN
+      28             : #include <dlfcn.h>
+      29             : #endif
+      30             : 
+      31             : // Including Plumed.h in this manner allows to create a local
+      32             : // implementation of the wrapper in an anonymous namespace.
+      33             : // This allows to avoid recoding all the Plumed.h stuff here
+      34             : // and at the same time avoids possible conflicts.
+      35             : #define __PLUMED_WRAPPER_IMPLEMENTATION 1
+      36             : #define __PLUMED_WRAPPER_EXTERN 0
+      37             : #define __PLUMED_WRAPPER_CXX_ANONYMOUS_NAMESPACE 1
+      38             : #define __PLUMED_WRAPPER_CXX_ANONYMOUS_NAMESPACE_PLMD_EXCEPTIONS 1
+      39             : #include "../wrapper/Plumed.h"
+      40             : 
+      41             : namespace PLMD
+      42             : {
+      43             : 
+      44             : 
+      45          11 : PlumedHandle::PlumedHandle():
+      46          11 :   local(Tools::make_unique<PlumedMain>())
+      47             : {
+      48          11 : }
+      49             : 
+      50           1 : PlumedHandle::PlumedHandle(const char* kernel)
+      51             : #ifdef __PLUMED_HAS_DLOPEN
+      52             :   :
+      53           1 :   loaded(plumed_c2v(plumed_create_dlopen(kernel)))
+      54             : {
+      55             :   if(!plumed_valid(plumed_v2c(loaded))) {
+      56             :     // this is necessary to make sure loaded is properly destroyed
+      57           0 :     plumed_finalize(plumed_v2c(loaded));
+      58           0 :     plumed_error() << "You are trying to dynamically load a kernel, but the path " << kernel <<" could not be opened";
+      59             :   }
+      60           1 : }
+      61             : #else
+      62             : {
+      63             :   plumed_error() << "You are trying to dynamically load a kernel, but PLUMED was compiled without dlopen";
+      64             : }
+      65             : #endif
+      66             : 
+      67          12 : PlumedHandle::~PlumedHandle() {
+      68          12 :   if(loaded) plumed_finalize(plumed_v2c(loaded));
+      69          12 : }
+      70             : 
+      71           1 : PlumedHandle PlumedHandle::dlopen(const char* path) {
+      72           1 :   return PlumedHandle(path);
+      73             : }
+      74             : 
+      75        1476 : void PlumedHandle::cmd(std::string_view key,const TypesafePtr & ptr) {
+      76        1476 :   if(local) {
+      77        1254 :     local->cmd(key,ptr);
+      78         222 :   } else if(loaded) {
+      79             :     plumed_safeptr safe;
+      80         222 :     safe.ptr=ptr.getRaw();
+      81         222 :     safe.nelem=ptr.getNelem();
+      82         222 :     safe.shape=const_cast<std::size_t*>(ptr.getShape());
+      83         222 :     safe.flags=ptr.getFlags();
+      84         222 :     safe.opt=nullptr;
+      85             :     // this is to ensure the string_view is null terminated
+      86         222 :     auto key_string=std::string(key);
+      87         222 :     plumed_cmd(plumed_v2c(loaded),key_string.c_str(),safe);
+      88           0 :   } else plumed_error() << "should never arrive here (either one or the other should work)";
+      89        1476 : }
+      90             : 
+      91           0 : PlumedHandle::PlumedHandle(PlumedHandle && other) noexcept:
+      92             :   local(std::move(other.local)),
+      93           0 :   loaded(other.loaded)
+      94             : {
+      95           0 :   other.loaded=nullptr;
+      96           0 : }
+      97             : 
+      98           0 : PlumedHandle & PlumedHandle::operator=(PlumedHandle && other) noexcept {
+      99           0 :   if(this!=&other) {
+     100           0 :     if(loaded) plumed_finalize(plumed_v2c(loaded));
+     101             :     local=std::move(other.local);
+     102           0 :     loaded=other.loaded;
+     103           0 :     other.loaded=nullptr;
+     104             :   }
+     105           0 :   return *this;
+     106             : }
+     107             : 
+     108             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/RMSD.cpp.func-sort-c.html b/coverage/tools/RMSD.cpp.func-sort-c.html new file mode 100644 index 000000000000..c2d92c008c01 --- /dev/null +++ b/coverage/tools/RMSD.cpp.func-sort-c.html @@ -0,0 +1,393 @@ + + + + + + + + LCOV - plumed test coverage - tools/RMSD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - RMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:55673575.6 %
Date:2024-04-19 12:12:35Functions:448055.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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_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
_ZNK4PLMD4RMSD20optimalAlignment_PCAILb1ELb0EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_SD_SD_RNS_13TensorGenericILj3ELj3EEESD_RNS_6MatrixISA_EEb39
_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
_ZN4PLMD12RMSDCoreData18getPositionsCenterEv210
_ZN4PLMD4RMSD16calc_FitElementsERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERNS_13TensorGenericILj3ELj3EEERNS_6MatrixIS5_EERS5_RS3_RKb210
_ZN4PLMD4RMSD8calc_RotERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERS5_RNS_13TensorGenericILj3ELj3EEEb672
_ZNK4PLMD4RMSD20optimalAlignment_RotILb1ELb1EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_RNS_13TensorGenericILj3ELj3EEEb672
_ZNK4PLMD4RMSD15simpleAlignmentERKSt6vectorIdSaIdEES5_RKS1_INS_13VectorGenericILj3EEESaIS7_EESB_RS9_SC_b774
_ZN4PLMD4RMSD18calc_Rot_DRotDRr01ERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERNS_13TensorGenericILj3ELj3EEERSt5arrayISB_IS9_Lm3EELm3EEb1092
_ZNK4PLMD12RMSDCoreData17getDRotationDRr01Ev1092
_ZNK4PLMD4RMSD30optimalAlignment_Rot_DRotDRr01ILb1ELb1EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RNS_13TensorGenericILj3ELj3EEERSt5arrayISG_ISE_Lm3EELm3EEb1092
_ZN4PLMD4RMSD3setERKNS_3PDBERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbb1189
_ZN4PLMD12RMSDCoreData37getRotationMatrixReferenceToPositionsEv1764
_ZNK4PLMD4RMSD20optimalAlignment_PCAILb1ELb1EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_SD_SD_RNS_13TensorGenericILj3ELj3EEESD_RNS_6MatrixISA_EEb2863
_ZN4PLMD4RMSD5clearEv11982
_ZN4PLMD4RMSD11setDisplaceERKSt6vectorIdSaIdEEb13167
_ZN4PLMD4RMSD3setERKSt6vectorIdSaIdEES5_RKS1_INS_13VectorGenericILj3EEESaIS7_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbb13167
_ZN4PLMD4RMSD8setAlignERKSt6vectorIdSaIdEEbb13167
_ZN4PLMD12RMSDCoreData28doCoreCalcWithCloseStructureEbbRKNS_13TensorGenericILj3ELj3EEES4_RSt5arrayIS5_IS2_Lm3EELm3EE45192
_ZN4PLMD4RMSD27calculateWithCloseStructureERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERS5_RKNS_13TensorGenericILj3ELj3EEESC_RSt5arrayISD_ISA_Lm3EELm3EEb45192
_ZNK4PLMD4RMSD34optimalAlignmentWithCloseStructureILb1ELb1EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_RKNS_13TensorGenericILj3ELj3EEESH_RSt5arrayISI_ISF_Lm3EELm3EEb45192
_ZN4PLMD4RMSDC2Ev46859
_ZNK4PLMD4RMSD20optimalAlignment_PCAILb0ELb1EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_SD_SD_RNS_13TensorGenericILj3ELj3EEESD_RNS_6MatrixISA_EEb53779
_ZN4PLMD12RMSDCoreData20getCenteredReferenceEv56681
_ZN4PLMD12RMSDCoreData30getAlignedPositionsToReferenceEv56681
_ZNK4PLMD4RMSD16calc_PCAelementsERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERS5_RNS_13TensorGenericILj3ELj3EEERNS_6MatrixIS5_EES8_S8_S8_RKb56681
_ZN4PLMD12RMSDCoreData20getCenteredPositionsEv56891
_ZN4PLMD12RMSDCoreData22getDRotationDPositionsEb56891
_ZN4PLMD12RMSDCoreData37getRotationMatrixPositionsToReferenceEv56891
_ZN4PLMD4RMSD7setTypeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE58359
_ZN4PLMD4RMSD12setReferenceERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EE58375
_ZN4PLMD12RMSDCoreData10doCoreCalcEbbb58656
_ZNK4PLMD4RMSD12getReferenceEv101427
_ZN4PLMD12RMSDCoreData22getDDistanceDPositionsEv102546
_ZN4PLMD12RMSDCoreData11getDistanceEb103848
_ZNK4PLMD4RMSD16optimalAlignmentILb0ELb1EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_b188510
_ZNK4PLMD4RMSD16optimalAlignmentILb1ELb1EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_b357816
_ZNK4PLMD4RMSD9calculateERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERS5_b546568
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/RMSD.cpp.func.html b/coverage/tools/RMSD.cpp.func.html new file mode 100644 index 000000000000..6cc9666bb865 --- /dev/null +++ b/coverage/tools/RMSD.cpp.func.html @@ -0,0 +1,393 @@ + + + + + + + + LCOV - plumed test coverage - tools/RMSD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - RMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:55673575.6 %
Date:2024-04-19 12:12:35Functions:448055.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12RMSDCoreData10doCoreCalcEbbb58656
_ZN4PLMD12RMSDCoreData11getDistanceEb103848
_ZN4PLMD12RMSDCoreData18getPositionsCenterEv210
_ZN4PLMD12RMSDCoreData18getReferenceCenterEv0
_ZN4PLMD12RMSDCoreData20getCenteredPositionsEv56891
_ZN4PLMD12RMSDCoreData20getCenteredReferenceEv56681
_ZN4PLMD12RMSDCoreData22getDDistanceDPositionsEv102546
_ZN4PLMD12RMSDCoreData22getDDistanceDReferenceEv1
_ZN4PLMD12RMSDCoreData22getDRotationDPositionsEb56891
_ZN4PLMD12RMSDCoreData22getDRotationDReferenceEb0
_ZN4PLMD12RMSDCoreData26getDDistanceDReferenceSOMAEv0
_ZN4PLMD12RMSDCoreData28doCoreCalcWithCloseStructureEbbRKNS_13TensorGenericILj3ELj3EEES4_RSt5arrayIS5_IS2_Lm3EELm3EE45192
_ZN4PLMD12RMSDCoreData30getAlignedPositionsToReferenceEv56681
_ZN4PLMD12RMSDCoreData30getAlignedReferenceToPositionsEv0
_ZN4PLMD12RMSDCoreData37getRotationMatrixPositionsToReferenceEv56891
_ZN4PLMD12RMSDCoreData37getRotationMatrixReferenceToPositionsEv1764
_ZN4PLMD4RMSD11getDisplaceEv0
_ZN4PLMD4RMSD11setDisplaceERKSt6vectorIdSaIdEEb13167
_ZN4PLMD4RMSD12setReferenceERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EE58375
_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_traitsIcESaIcEEEbb1189
_ZN4PLMD4RMSD3setERKSt6vectorIdSaIdEES5_RKS1_INS_13VectorGenericILj3EEESaIS7_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbb13167
_ZN4PLMD4RMSD5clearEv11982
_ZN4PLMD4RMSD7setTypeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE58359
_ZN4PLMD4RMSD8calc_RotERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERS5_RNS_13TensorGenericILj3ELj3EEEb672
_ZN4PLMD4RMSD8getAlignEv0
_ZN4PLMD4RMSD8setAlignERKSt6vectorIdSaIdEEbb13167
_ZN4PLMD4RMSD9calc_SOMAERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERS5_S8_b0
_ZN4PLMD4RMSD9getMethodB5cxx11Ev5
_ZN4PLMD4RMSDC2Ev46859
_ZNK4PLMD12RMSDCoreData17getDRotationDRr01Ev1092
_ZNK4PLMD4RMSD12getReferenceEv101427
_ZNK4PLMD4RMSD15simpleAlignmentERKSt6vectorIdSaIdEES5_RKS1_INS_13VectorGenericILj3EEESaIS7_EESB_RS9_SC_b774
_ZNK4PLMD4RMSD16calc_PCAelementsERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERS5_RNS_13TensorGenericILj3ELj3EEERNS_6MatrixIS5_EES8_S8_S8_RKb56681
_ZNK4PLMD4RMSD16optimalAlignmentILb0ELb0EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_b2
_ZNK4PLMD4RMSD16optimalAlignmentILb0ELb1EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_b188510
_ZNK4PLMD4RMSD16optimalAlignmentILb1ELb0EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_b112
_ZNK4PLMD4RMSD16optimalAlignmentILb1ELb1EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_b357816
_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_EEb53779
_ZNK4PLMD4RMSD20optimalAlignment_PCAILb1ELb0EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_SD_SD_RNS_13TensorGenericILj3ELj3EEESD_RNS_6MatrixISA_EEb39
_ZNK4PLMD4RMSD20optimalAlignment_PCAILb1ELb1EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_SD_SD_RNS_13TensorGenericILj3ELj3EEESD_RNS_6MatrixISA_EEb2863
_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_b546568
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/RMSD.cpp.gcov.html b/coverage/tools/RMSD.cpp.gcov.html new file mode 100644 index 000000000000..1507d77ad398 --- /dev/null +++ b/coverage/tools/RMSD.cpp.gcov.html @@ -0,0 +1,1549 @@ + + + + + + + + LCOV - plumed test coverage - tools/RMSD.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - RMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:55673575.6 %
Date:2024-04-19 12:12:35Functions:448055.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 "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       46859 : 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        1189 : void RMSD::set(const PDB&pdb, const std::string & mytype, bool remove_center, bool normalize_weights ) {
+      39             : 
+      40        1189 :   set(pdb.getOccupancy(),pdb.getBeta(),pdb.getPositions(),mytype,remove_center,normalize_weights);
+      41             : 
+      42        1189 : }
+      43       13167 : 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       13167 :   setReference(reference); // this by default remove the com and assumes uniform weights
+      46       13167 :   setAlign(align, normalize_weights, remove_center); // this recalculates the com with weights. If remove_center=false then it restore the center back
+      47       13167 :   setDisplace(displace, normalize_weights);  // this is does not affect any calculation of the weights
+      48       13167 :   setType(mytype);
+      49             : 
+      50       13167 : }
+      51             : 
+      52       58359 : void RMSD::setType(const std::string & mytype) {
+      53             : 
+      54       58359 :   alignmentMethod=SIMPLE; // initialize with the simplest case: no rotation
+      55       58359 :   if (mytype=="SIMPLE") {
+      56          39 :     alignmentMethod=SIMPLE;
+      57             :   }
+      58       58320 :   else if (mytype=="OPTIMAL") {
+      59       47028 :     alignmentMethod=OPTIMAL;
+      60             :   }
+      61       11292 :   else if (mytype=="OPTIMAL-FAST") {
+      62       11292 :     alignmentMethod=OPTIMAL_FAST;
+      63             :   }
+      64           0 :   else plumed_merror("unknown RMSD type" + mytype);
+      65             : 
+      66       58359 : }
+      67             : 
+      68       11982 : void RMSD::clear() {
+      69             :   reference.clear();
+      70       11982 :   reference_center.zero();
+      71       11982 :   reference_center_is_calculated=false;
+      72       11982 :   reference_center_is_removed=false;
+      73             :   align.clear();
+      74             :   displace.clear();
+      75       11982 :   positions_center.zero();
+      76       11982 :   positions_center_is_calculated=false;
+      77       11982 :   positions_center_is_removed=false;
+      78       11982 : }
+      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       58375 : void RMSD::setReference(const std::vector<Vector> & reference) {
+      94       58375 :   unsigned n=reference.size();
+      95       58375 :   this->reference=reference;
+      96       58375 :   plumed_massert(align.empty(),"you should first clear() an RMSD object, then set a new reference");
+      97       58375 :   plumed_massert(displace.empty(),"you should first clear() an RMSD object, then set a new reference");
+      98       58375 :   align.resize(n,1.0/n);
+      99       58375 :   displace.resize(n,1.0/n);
+     100      842214 :   for(unsigned i=0; i<n; i++) reference_center+=this->reference[i]*align[i];
+     101             :   #pragma omp simd
+     102      783839 :   for(unsigned i=0; i<n; i++) this->reference[i]-=reference_center;
+     103       58375 :   reference_center_is_calculated=true;
+     104       58375 :   reference_center_is_removed=true;
+     105       58375 : }
+     106      101427 : const std::vector<Vector>& RMSD::getReference() const {
+     107      101427 :   return reference;
+     108             : }
+     109             : ///
+     110             : /// the alignment weights are here normalized to 1 and  the center of the reference is removed accordingly
+     111             : ///
+     112       13167 : void RMSD::setAlign(const std::vector<double> & align, bool normalize_weights, bool remove_center) {
+     113       13167 :   unsigned n=reference.size();
+     114       13167 :   plumed_massert(this->align.size()==align.size(),"mismatch in dimension of align/displace arrays");
+     115       13167 :   this->align=align;
+     116       13167 :   if(normalize_weights) {
+     117             :     double w=0.0;
+     118       26246 :     #pragma omp simd reduction(+:w)
+     119      195603 :     for(unsigned i=0; i<n; i++) w+=this->align[i];
+     120       13123 :     if(w>epsilon) {
+     121       13121 :       double inv=1.0/w;
+     122             :       #pragma omp simd
+     123      195573 :       for(unsigned i=0; i<n; i++) this->align[i]*=inv;
+     124             :     } else {
+     125           2 :       double inv=1.0/n;
+     126             :       #pragma omp simd
+     127          30 :       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       13167 :   if(reference_center_is_removed) {
+     134       13167 :     plumed_massert(reference_center_is_calculated," seems that the reference center has been removed but not calculated and stored!");
+     135       13167 :     addCenter(reference,reference_center);
+     136             :   }
+     137       13167 :   reference_center=calculateCenter(reference,this->align);
+     138       13167 :   reference_center_is_calculated=true;
+     139       13167 :   if(remove_center) {
+     140       13162 :     removeCenter(reference,reference_center);
+     141       13162 :     reference_center_is_removed=true;
+     142             :   } else {
+     143           5 :     reference_center_is_removed=false;
+     144             :   }
+     145       13167 : }
+     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       13167 : void RMSD::setDisplace(const std::vector<double> & displace, bool normalize_weights) {
+     153       13167 :   unsigned n=reference.size();
+     154       13167 :   plumed_massert(this->displace.size()==displace.size(),"mismatch in dimension of align/displace arrays");
+     155       13167 :   this->displace=displace;
+     156       13167 :   if(normalize_weights) {
+     157             :     double w=0.0;
+     158       26246 :     #pragma omp simd reduction(+:w)
+     159      195603 :     for(unsigned i=0; i<n; i++) w+=this->displace[i];
+     160       13123 :     if(w>epsilon) {
+     161       13121 :       double inv=1.0/w;
+     162             :       #pragma omp simd
+     163      195573 :       for(unsigned i=0; i<n; i++) this->displace[i]*=inv;
+     164             :     } else {
+     165           2 :       double inv=1.0/n;
+     166             :       #pragma omp simd
+     167          30 :       for(unsigned i=0; i<n; i++) this->displace[i]=inv;
+     168             :     }
+     169             :   }
+     170       13167 : }
+     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      546568 : double RMSD::calculate(const std::vector<Vector> & positions,std::vector<Vector> &derivatives, bool squared)const {
+     178             : 
+     179             :   double ret=0.;
+     180             : 
+     181      546568 :   switch(alignmentMethod) {
+     182             :   case SIMPLE : {
+     183             :     //  do a simple alignment without rotation
+     184         128 :     std::vector<Vector> displacement( derivatives.size() );
+     185         128 :     ret=simpleAlignment(align,displace,positions,reference,derivatives,displacement,squared);
+     186             :     break;
+     187      188512 :   } case OPTIMAL_FAST : {
+     188             :     // this is calling the fastest option:
+     189      188512 :     if(align==displace) ret=optimalAlignment<false,true>(align,displace,positions,reference,derivatives,squared);
+     190           2 :     else                ret=optimalAlignment<false,false>(align,displace,positions,reference,derivatives,squared);
+     191             :     break;
+     192             : 
+     193      357928 :   } case OPTIMAL : {
+     194             :     // this is the fast routine but in the "safe" mode, which gives less numerical error:
+     195      357928 :     if(align==displace) ret=optimalAlignment<true,true>(align,displace,positions,reference,derivatives,squared);
+     196         112 :     else ret=optimalAlignment<true,false>(align,displace,positions,reference,derivatives,squared);
+     197             :     break;
+     198             :   }
+     199             :   }
+     200             : 
+     201      546568 :   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       56681 : 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       56681 :   switch(alignmentMethod) {
+     340           0 :   case SIMPLE:
+     341           0 :     plumed_merror("derivative of the refreence frame not implemented for SIMPLE alignmentMethod \n");
+     342             :     break;
+     343       53779 :   case OPTIMAL_FAST:
+     344       53779 :     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        2902 :   case OPTIMAL:
+     348        2902 :     if(align==displace) ret=optimalAlignment_PCA<true,true>(align,displace,positions,reference, alignedpositions, centeredpositions,centeredreference,Rotation,DDistDPos,DRotDPos,squared);
+     349          39 :     else                ret=optimalAlignment_PCA<true,false>(align,displace,positions,reference, alignedpositions, centeredpositions,centeredreference,Rotation,DDistDPos,DRotDPos,squared);
+     350             :     break;
+     351             :   }
+     352       56681 :   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         774 : 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         774 :   unsigned n=reference.size();
+     389             : 
+     390         774 :   Vector apositions;
+     391         774 :   Vector areference;
+     392         774 :   Vector dpositions;
+     393         774 :   Vector dreference;
+     394             : 
+     395       11471 :   for(unsigned i=0; i<n; i++) {
+     396       10697 :     double aw=align[i];
+     397       10697 :     double dw=displace[i];
+     398       10697 :     apositions+=positions[i]*aw;
+     399       10697 :     areference+=reference[i]*aw;
+     400       10697 :     dpositions+=positions[i]*dw;
+     401       10697 :     dreference+=reference[i]*dw;
+     402             :   }
+     403             : 
+     404         774 :   Vector shift=((apositions-areference)-(dpositions-dreference));
+     405       11471 :   for(unsigned i=0; i<n; i++) {
+     406       10697 :     displacement[i]=(positions[i]-apositions)-(reference[i]-areference);
+     407       10697 :     dist+=displace[i]*displacement[i].modulo2();
+     408       10697 :     derivatives[i]=2*(displace[i]*displacement[i]+align[i]*shift);
+     409             :   }
+     410             : 
+     411         774 :   if(!squared) {
+     412             :     // sqrt
+     413         141 :     dist=std::sqrt(dist);
+     414             :     ///// sqrt on derivatives
+     415        3826 :     for(unsigned i=0; i<n; i++) {derivatives[i]*=(0.5/dist);}
+     416             :   }
+     417         774 :   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      546440 : 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      546440 :   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      546440 :   Tensor rr01;
+     438             : 
+     439      546440 :   derivatives.resize(n);
+     440             : 
+     441      546440 :   Vector cpositions;
+     442             : 
+     443             : // first expensive loop: compute centers
+     444    22308358 :   for(unsigned iat=0; iat<n; iat++) {
+     445    21761918 :     double w=align[iat];
+     446    21761918 :     cpositions+=positions[iat]*w;
+     447             :   }
+     448             : 
+     449             : // second expensive loop: compute second moments wrt centers
+     450    22308358 :   for(unsigned iat=0; iat<n; iat++) {
+     451    21761918 :     double w=align[iat];
+     452    21761918 :     rr00+=dotProduct(positions[iat]-cpositions,positions[iat]-cpositions)*w;
+     453    21759742 :     rr11+=dotProduct(reference[iat],reference[iat])*w;
+     454    21761918 :     rr01+=Tensor(positions[iat]-cpositions,reference[iat])*w;
+     455             :   }
+     456             : 
+     457      546440 :   Tensor4d m;
+     458             : 
+     459      546440 :   m[0][0]=2.0*(-rr01[0][0]-rr01[1][1]-rr01[2][2]);
+     460      546440 :   m[1][1]=2.0*(-rr01[0][0]+rr01[1][1]+rr01[2][2]);
+     461      546440 :   m[2][2]=2.0*(+rr01[0][0]-rr01[1][1]+rr01[2][2]);
+     462      546440 :   m[3][3]=2.0*(+rr01[0][0]+rr01[1][1]-rr01[2][2]);
+     463      546440 :   m[0][1]=2.0*(-rr01[1][2]+rr01[2][1]);
+     464      546440 :   m[0][2]=2.0*(+rr01[0][2]-rr01[2][0]);
+     465      546440 :   m[0][3]=2.0*(-rr01[0][1]+rr01[1][0]);
+     466      546440 :   m[1][2]=2.0*(-rr01[0][1]-rr01[1][0]);
+     467      546440 :   m[1][3]=2.0*(-rr01[0][2]-rr01[2][0]);
+     468      546440 :   m[2][3]=2.0*(-rr01[1][2]-rr01[2][1]);
+     469      546440 :   m[1][0] = m[0][1];
+     470      546440 :   m[2][0] = m[0][2];
+     471      546440 :   m[2][1] = m[1][2];
+     472      546440 :   m[3][0] = m[0][3];
+     473      546440 :   m[3][1] = m[1][3];
+     474      546440 :   m[3][2] = m[2][3];
+     475             : 
+     476    11475240 :   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      546440 :   Vector4d q;
+     498             : 
+     499     2732200 :   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      546326 :     VectorGeneric<1> eigenvals;
+     523      546326 :     TensorGeneric<1,4> eigenvecs;
+     524      546326 :     diagMatSym(m, eigenvals, eigenvecs );
+     525      546326 :     dist=eigenvals[0]+rr00+rr11;
+     526      546326 :     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      546440 :   Tensor rotation;
+     534      546440 :   rotation[0][0]=q[0]*q[0]+q[1]*q[1]-q[2]*q[2]-q[3]*q[3];
+     535      546440 :   rotation[1][1]=q[0]*q[0]-q[1]*q[1]+q[2]*q[2]-q[3]*q[3];
+     536      546440 :   rotation[2][2]=q[0]*q[0]-q[1]*q[1]-q[2]*q[2]+q[3]*q[3];
+     537      546440 :   rotation[0][1]=2*(+q[0]*q[3]+q[1]*q[2]);
+     538      546440 :   rotation[0][2]=2*(-q[0]*q[2]+q[1]*q[3]);
+     539      546440 :   rotation[1][2]=2*(+q[0]*q[1]+q[2]*q[3]);
+     540      546440 :   rotation[1][0]=2*(-q[0]*q[3]+q[1]*q[2]);
+     541      546440 :   rotation[2][0]=2*(+q[0]*q[2]+q[1]*q[3]);
+     542      546440 :   rotation[2][1]=2*(-q[0]*q[1]+q[2]*q[3]);
+     543             : 
+     544             : 
+     545      546440 :   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      546326 :   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      546440 :   Tensor ddist_drotation;
+     570      546440 :   Vector ddist_dcpositions;
+     571             : 
+     572             : // third expensive loop: derivatives
+     573    22308358 :   for(unsigned iat=0; iat<n; iat++) {
+     574    21761918 :     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    21759742 :       derivatives[iat]= prefactor*align[iat]*d;
+     579     4951700 :       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      546440 :   if(!squared) {
+     603       75702 :     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      546440 :   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       56681 : 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       56681 :   RMSDCoreData cd(align,displace,positions,reference);
+     892             :   // transfer the settings for the center to let the CoreCalc deal with it
+     893       56681 :   cd.setPositionsCenterIsRemoved(positions_center_is_removed);
+     894       56681 :   if(positions_center_is_calculated) {cd.setPositionsCenter(positions_center);}
+     895       56681 :   else {cd.calcPositionsCenter();};
+     896             : 
+     897       56681 :   cd.setReferenceCenterIsRemoved(reference_center_is_removed);
+     898       56681 :   if(!reference_center_is_calculated) {cd.calcReferenceCenter();}
+     899       56681 :   else {cd.setReferenceCenter(reference_center);}
+     900             : 
+     901             :   // Perform the diagonalization and all the needed stuff
+     902       56681 :   cd.doCoreCalc(safe,alEqDis);
+     903             :   // make the core calc distance
+     904       56681 :   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       56681 :   DDistDPos=cd.getDDistanceDPositions();
+     907             :   // get the rotation matrix
+     908       56681 :   Rotation=cd.getRotationMatrixPositionsToReference();
+     909             :   // get its derivative
+     910       56681 :   DRotDPos=cd.getDRotationDPositions(true); // this gives back the inverse
+     911             :   // get aligned positions
+     912       56681 :   alignedpositions=cd.getAlignedPositionsToReference();
+     913             :   // get centered positions
+     914       56681 :   centeredpositions=cd.getCenteredPositions();
+     915             :   // get centered reference
+     916      113362 :   centeredreference=cd.getCenteredReference();
+     917       56681 :   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       58656 : void RMSDCoreData::doCoreCalc(bool safe,bool alEqDis, bool only_rotation) {
+     969             : 
+     970       58656 :   retrieve_only_rotation=only_rotation;
+     971       58656 :   const unsigned n=static_cast<unsigned int>(reference.size());
+     972             : 
+     973       58656 :   plumed_massert(creference_is_calculated,"the center of the reference frame must be already provided at this stage");
+     974       58656 :   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       58656 :   rr00=0.;
+     978       58656 :   rr11=0.;
+     979             : // This is positions*reference
+     980       58656 :   Tensor rr01;
+     981             : // center of mass managing: must subtract the center from the position or not?
+     982       58656 :   Vector cp; cp.zero(); if(!cpositions_is_removed)cp=cpositions;
+     983       58656 :   Vector cr; cr.zero(); if(!creference_is_removed)cr=creference;
+     984             : // second expensive loop: compute second moments wrt centers
+     985     1306665 :   for(unsigned iat=0; iat<n; iat++) {
+     986     1248009 :     double w=align[iat];
+     987     1248009 :     rr00+=dotProduct(positions[iat]-cp,positions[iat]-cp)*w;
+     988     1248009 :     rr11+=dotProduct(reference[iat]-cr,reference[iat]-cr)*w;
+     989     1248009 :     rr01+=Tensor(positions[iat]-cp,reference[iat]-cr)*w;
+     990             :   }
+     991             : 
+     992             : // the quaternion matrix: this is internal
+     993       58656 :   Tensor4d m;
+     994             : 
+     995       58656 :   m[0][0]=2.0*(-rr01[0][0]-rr01[1][1]-rr01[2][2]);
+     996       58656 :   m[1][1]=2.0*(-rr01[0][0]+rr01[1][1]+rr01[2][2]);
+     997       58656 :   m[2][2]=2.0*(+rr01[0][0]-rr01[1][1]+rr01[2][2]);
+     998       58656 :   m[3][3]=2.0*(+rr01[0][0]+rr01[1][1]-rr01[2][2]);
+     999       58656 :   m[0][1]=2.0*(-rr01[1][2]+rr01[2][1]);
+    1000       58656 :   m[0][2]=2.0*(+rr01[0][2]-rr01[2][0]);
+    1001       58656 :   m[0][3]=2.0*(-rr01[0][1]+rr01[1][0]);
+    1002       58656 :   m[1][2]=2.0*(-rr01[0][1]-rr01[1][0]);
+    1003       58656 :   m[1][3]=2.0*(-rr01[0][2]-rr01[2][0]);
+    1004       58656 :   m[2][3]=2.0*(-rr01[1][2]-rr01[2][1]);
+    1005       58656 :   m[1][0] = m[0][1];
+    1006       58656 :   m[2][0] = m[0][2];
+    1007       58656 :   m[2][1] = m[1][2];
+    1008       58656 :   m[3][0] = m[0][3];
+    1009       58656 :   m[3][1] = m[1][3];
+    1010       58656 :   m[3][2] = m[2][3];
+    1011             : 
+    1012             : 
+    1013     1231776 :   Tensor dm_drr01[4][4];
+    1014       58656 :   if(!alEqDis or !retrieve_only_rotation) {
+    1015       58656 :     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       58656 :     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       58656 :     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       58656 :     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       58656 :     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       58656 :     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       58656 :     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       58656 :     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       58656 :     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       58656 :     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       58656 :     dm_drr01[1][0] = dm_drr01[0][1];
+    1026       58656 :     dm_drr01[2][0] = dm_drr01[0][2];
+    1027       58656 :     dm_drr01[2][1] = dm_drr01[1][2];
+    1028       58656 :     dm_drr01[3][0] = dm_drr01[0][3];
+    1029       58656 :     dm_drr01[3][1] = dm_drr01[1][3];
+    1030       58656 :     dm_drr01[3][2] = dm_drr01[2][3];
+    1031             :   }
+    1032             : 
+    1033             : 
+    1034       58656 :   Vector4d q;
+    1035             : 
+    1036      293280 :   Tensor dq_drr01[4];
+    1037       58656 :   if(!alEqDis or !only_rotation) {
+    1038       58656 :     diagMatSym(m, eigenvals, eigenvecs );
+    1039       58656 :     q=Vector4d(eigenvecs[0][0],eigenvecs[0][1],eigenvecs[0][2],eigenvecs[0][3]);
+    1040             :     double dq_dm[4][4][4];
+    1041     4985760 :     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    15015936 :           for(unsigned l=1; l<4; l++) tmp+=eigenvecs[l][j]*eigenvecs[l][i]/(eigenvals[0]-eigenvals[l])*eigenvecs[0][k];
+    1045     3753984 :           dq_dm[i][j][k]=tmp;
+    1046             :         }
+    1047             : // propagation to _drr01
+    1048      293280 :     for(unsigned i=0; i<4; i++) {
+    1049      234624 :       Tensor tmp;
+    1050     4927104 :       for(unsigned j=0; j<4; j++) for(unsigned k=0; k<4; k++) {
+    1051     3753984 :           tmp+=dq_dm[i][j][k]*dm_drr01[j][k];
+    1052             :         }
+    1053      234624 :       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       58656 :   rotation[0][0]=q[0]*q[0]+q[1]*q[1]-q[2]*q[2]-q[3]*q[3];
+    1068       58656 :   rotation[1][1]=q[0]*q[0]-q[1]*q[1]+q[2]*q[2]-q[3]*q[3];
+    1069       58656 :   rotation[2][2]=q[0]*q[0]-q[1]*q[1]-q[2]*q[2]+q[3]*q[3];
+    1070       58656 :   rotation[0][1]=2*(+q[0]*q[3]+q[1]*q[2]);
+    1071       58656 :   rotation[0][2]=2*(-q[0]*q[2]+q[1]*q[3]);
+    1072       58656 :   rotation[1][2]=2*(+q[0]*q[1]+q[2]*q[3]);
+    1073       58656 :   rotation[1][0]=2*(-q[0]*q[3]+q[1]*q[2]);
+    1074       58656 :   rotation[2][0]=2*(+q[0]*q[2]+q[1]*q[3]);
+    1075       58656 :   rotation[2][1]=2*(-q[0]*q[1]+q[2]*q[3]);
+    1076             : 
+    1077             : 
+    1078       58656 :   if(!alEqDis or !only_rotation) {
+    1079       58656 :     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       58656 :     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       58656 :     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       58656 :     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       58656 :     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       58656 :     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       58656 :     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       58656 :     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       58656 :     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       58656 :   d.resize(n);
+    1091             : 
+    1092             :   // calculate rotation matrix derivatives and components distances needed for components only when align!=displacement
+    1093       58656 :   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     1306665 :   for(unsigned iat=0; iat<n; iat++) {
+    1099             :     // components differences: this is useful externally
+    1100     1248009 :     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       58656 :   if(!alEqDis or !only_rotation) {
+    1105     1306665 :     for (unsigned iat=0; iat<n; iat++)
+    1106     1248009 :       ddist_drotation+=-2*displace[iat]*extProduct(d[iat],reference[iat]-cr);
+    1107             : 
+    1108       58656 :     ddist_drr01.zero();
+    1109      762528 :     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       58656 :   this->alEqDis=alEqDis;
+    1113       58656 :   this->safe=safe;
+    1114       58656 :   isInitialized=true;
+    1115             : 
+    1116       58656 : }
+    1117             : /// just retrieve the distance already calculated
+    1118      103848 : double RMSDCoreData::getDistance( bool squared) {
+    1119             : 
+    1120      103848 :   if(!isInitialized)plumed_merror("getDistance cannot calculate the distance without being initialized first by doCoreCalc ");
+    1121             : 
+    1122             :   double localDist=0.0;
+    1123      103848 :   const unsigned n=static_cast<unsigned int>(reference.size());
+    1124      103848 :   if(safe || !alEqDis) localDist=0.0;
+    1125             :   else
+    1126       53779 :     localDist=eigenvals[0]+rr00+rr11;
+    1127      207696 :   #pragma omp simd reduction(+:localDist)
+    1128             :   for(unsigned iat=0; iat<n; iat++) {
+    1129     1835505 :     if(alEqDis) {
+    1130     1833843 :       if(safe) localDist+=align[iat]*modulo2(d[iat]);
+    1131             :     } else {
+    1132        1662 :       localDist+=displace[iat]*modulo2(d[iat]);
+    1133             :     }
+    1134             :   }
+    1135      103848 :   if(!squared) {
+    1136       10004 :     dist=std::sqrt(localDist);
+    1137       10004 :     distanceIsMSD=false;
+    1138             :   } else {
+    1139       93844 :     dist=localDist;
+    1140       93844 :     distanceIsMSD=true;
+    1141             :   }
+    1142      103848 :   hasDistance=true;
+    1143      103848 :   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      102546 : std::vector<Vector> RMSDCoreData::getDDistanceDPositions() {
+    1182             :   std::vector<Vector>  derivatives;
+    1183      102546 :   const unsigned n=static_cast<unsigned int>(reference.size());
+    1184      102546 :   Vector ddist_dcpositions;
+    1185      102546 :   derivatives.resize(n);
+    1186             :   double prefactor=1.0;
+    1187      102546 :   if(!distanceIsMSD) prefactor*=0.5/dist;
+    1188      102546 :   plumed_massert(!retrieve_only_rotation,"You used  only_rotation=true in doCoreCalc therefore you cannot retrieve this information now");
+    1189      102546 :   if(!hasDistance)plumed_merror("getDPositionsDerivatives needs to calculate the distance via getDistance first !");
+    1190      102546 :   if(!isInitialized)plumed_merror("getDPositionsDerivatives needs to initialize the coreData first!");
+    1191      102546 :   Vector csum;
+    1192     1437855 :   for(unsigned iat=0; iat<n; iat++) {
+    1193     1335309 :     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     1333947 :       derivatives[iat]= 2*prefactor*align[iat]*d[iat];
+    1197             :     } else {
+    1198             : // these are the derivatives assuming the roto-translation as frozen
+    1199        1362 :       Vector tmp1=2*displace[iat]*d[iat];
+    1200        1362 :       derivatives[iat]=tmp1;
+    1201             : // derivative of cpositions
+    1202        1362 :       ddist_dcpositions+=-tmp1;
+    1203             :       // these needed for com corrections
+    1204        1362 :       Vector tmp2=matmul(ddist_drr01,reference[iat]-creference)*align[iat];
+    1205        1362 :       derivatives[iat]+=tmp2;
+    1206        1362 :       csum+=tmp2;
+    1207             :     }
+    1208             :   }
+    1209             : 
+    1210      102546 :   if(!alEqDis)
+    1211             :     #pragma omp simd
+    1212        1362 :     for(unsigned iat=0; iat<n; iat++) {derivatives[iat]= prefactor*(derivatives[iat]+(ddist_dcpositions-csum)*align[iat]); }
+    1213             : 
+    1214      102546 :   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       56891 : Matrix<std::vector<Vector> >  RMSDCoreData::getDRotationDPositions( bool inverseTransform ) {
+    1306       56891 :   const unsigned n=static_cast<unsigned int>(reference.size());
+    1307       56891 :   plumed_massert(!retrieve_only_rotation,"You used  only_rotation=true in doCoreCalc therefore you cannot retrieve this information now");
+    1308       56891 :   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       56891 :   std::vector<Vector> v(n);
+    1313       56891 :   Vector csum;
+    1314             :   // these below could probably be calculated in the main routine
+    1315       56891 :   Vector cp; cp.zero(); if(!cpositions_is_removed)cp=cpositions;
+    1316       56891 :   Vector cr; cr.zero(); if(!creference_is_removed)cr=creference;
+    1317     1281113 :   for(unsigned iat=0; iat<n; iat++) csum+=(reference[iat]-cr)*align[iat];
+    1318     1281113 :   for(unsigned iat=0; iat<n; iat++) v[iat]=(reference[iat]-cr-csum)*align[iat];
+    1319      227564 :   for(unsigned a=0; a<3; a++) {
+    1320      682692 :     for(unsigned b=0; b<3; b++) {
+    1321      512019 :       if(inverseTransform) {
+    1322      512019 :         DRotDPos[b][a].resize(n);
+    1323    11530017 :         for(unsigned iat=0; iat<n; iat++) {
+    1324    11017998 :           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       56891 :   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       56681 : std::vector<Vector> RMSDCoreData::getAlignedPositionsToReference() {
+    1389             :   std::vector<Vector> alignedpos;
+    1390       56681 :   if(!isInitialized)plumed_merror("getAlignedPostionsToReference needs to initialize the coreData first!");
+    1391       56681 :   const unsigned n=static_cast<unsigned int>(positions.size());
+    1392       56681 :   alignedpos.resize(n);
+    1393       56681 :   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      794903 :   for(unsigned iat=0; iat<n; iat++)alignedpos[iat]=matmul(rotation.transpose(),positions[iat]-cp);
+    1396       56681 :   return alignedpos;
+    1397             : }
+    1398             : 
+    1399             : 
+    1400       56891 : std::vector<Vector> RMSDCoreData::getCenteredPositions() {
+    1401             :   std::vector<Vector> centeredpos;
+    1402       56891 :   const unsigned n=static_cast<unsigned int>(reference.size());
+    1403       56891 :   centeredpos.resize(n);
+    1404       56891 :   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     1281113 :   for(unsigned iat=0; iat<n; iat++)centeredpos[iat]=positions[iat]-cpositions;
+    1407       56891 :   return centeredpos;
+    1408             : }
+    1409             : 
+    1410       56681 : std::vector<Vector> RMSDCoreData::getCenteredReference() {
+    1411             :   std::vector<Vector> centeredref;
+    1412       56681 :   const unsigned n=static_cast<unsigned int>(reference.size());
+    1413       56681 :   centeredref.resize(n);
+    1414       56681 :   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       56681 :   Vector cr; cr.zero(); if(!creference_is_removed)cr=creference;
+    1417      794903 :   for(unsigned iat=0; iat<n; iat++)centeredref[iat]=reference[iat]-cr;
+    1418       56681 :   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       56891 : Tensor RMSDCoreData::getRotationMatrixPositionsToReference() {
+    1438       56891 :   if(!isInitialized)plumed_merror("getRotationMatrixReferenceToPositions needs to initialize the coreData first!");
+    1439       56891 :   return rotation.transpose();
+    1440             : }
+    1441             : 
+    1442        1092 : const std::array<std::array<Tensor,3>,3> &  RMSDCoreData::getDRotationDRr01() const {
+    1443        1092 :   if(!isInitialized)plumed_merror("getDRotationDRr01 needs to initialize the coreData first!");
+    1444        1092 :   return drotation_drr01;
+    1445             : }
+    1446             : 
+    1447             : 
+    1448             : 
+    1449             : template double RMSD::optimalAlignment<true,true>(const  std::vector<double>  & align,
+    1450             :     const  std::vector<double>  & displace,
+    1451             :     const std::vector<Vector> & positions,
+    1452             :     const std::vector<Vector> & reference,
+    1453             :     std::vector<Vector>  & derivatives, bool squared)const;
+    1454             : template double RMSD::optimalAlignment<true,false>(const  std::vector<double>  & align,
+    1455             :     const  std::vector<double>  & displace,
+    1456             :     const std::vector<Vector> & positions,
+    1457             :     const std::vector<Vector> & reference,
+    1458             :     std::vector<Vector>  & derivatives, bool squared)const;
+    1459             : template double RMSD::optimalAlignment<false,true>(const  std::vector<double>  & align,
+    1460             :     const  std::vector<double>  & displace,
+    1461             :     const std::vector<Vector> & positions,
+    1462             :     const std::vector<Vector> & reference,
+    1463             :     std::vector<Vector>  & derivatives, bool squared)const;
+    1464             : template double RMSD::optimalAlignment<false,false>(const  std::vector<double>  & align,
+    1465             :     const  std::vector<double>  & displace,
+    1466             :     const std::vector<Vector> & positions,
+    1467             :     const std::vector<Vector> & reference,
+    1468             :     std::vector<Vector>  & derivatives, bool squared)const;
+    1469             : 
+    1470             : 
+    1471             : 
+    1472             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/RMSD.h.func-sort-c.html b/coverage/tools/RMSD.h.func-sort-c.html new file mode 100644 index 000000000000..dbfb1f9b7b12 --- /dev/null +++ b/coverage/tools/RMSD.h.func-sort-c.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - tools/RMSD.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - RMSD.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:303585.7 %
Date:2024-04-19 12:12:35Functions:7977.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12RMSDCoreData18setPositionsCenterENS_13VectorGenericILj3EEE0
_ZN4PLMD12RMSDCoreData19calcReferenceCenterEv0
_ZN4PLMD4RMSD17getMatrixFromDRotERKNS_6MatrixISt6vectorINS_13VectorGenericILj3EEESaIS4_EEEERKjSB_900
_ZN4PLMD4RMSD15calculateCenterERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKS1_IdSaIdEE13167
_ZN4PLMD4RMSD9addCenterERSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKS3_13167
_ZN4PLMD4RMSD12removeCenterERSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKS3_26329
_ZN4PLMD12RMSDCoreData18setReferenceCenterENS_13VectorGenericILj3EEE103848
_ZN4PLMD12RMSDCoreData19calcPositionsCenterEv103848
_ZN4PLMD12RMSDCoreDataC2ERKSt6vectorIdSaIdEES5_RKS1_INS_13VectorGenericILj3EEESaIS7_EESB_103848
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/RMSD.h.func.html b/coverage/tools/RMSD.h.func.html new file mode 100644 index 000000000000..3ed7d46ff30a --- /dev/null +++ b/coverage/tools/RMSD.h.func.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - tools/RMSD.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - RMSD.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:303585.7 %
Date:2024-04-19 12:12:35Functions:7977.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12RMSDCoreData18setPositionsCenterENS_13VectorGenericILj3EEE0
_ZN4PLMD12RMSDCoreData18setReferenceCenterENS_13VectorGenericILj3EEE103848
_ZN4PLMD12RMSDCoreData19calcPositionsCenterEv103848
_ZN4PLMD12RMSDCoreData19calcReferenceCenterEv0
_ZN4PLMD12RMSDCoreDataC2ERKSt6vectorIdSaIdEES5_RKS1_INS_13VectorGenericILj3EEESaIS7_EESB_103848
_ZN4PLMD4RMSD12removeCenterERSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKS3_26329
_ZN4PLMD4RMSD15calculateCenterERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKS1_IdSaIdEE13167
_ZN4PLMD4RMSD17getMatrixFromDRotERKNS_6MatrixISt6vectorINS_13VectorGenericILj3EEESaIS4_EEEERKjSB_900
_ZN4PLMD4RMSD9addCenterERSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKS3_13167
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/RMSD.h.gcov.html b/coverage/tools/RMSD.h.gcov.html new file mode 100644 index 000000000000..f3ba7f04bc1c --- /dev/null +++ b/coverage/tools/RMSD.h.gcov.html @@ -0,0 +1,453 @@ + + + + + + + + LCOV - plumed test coverage - tools/RMSD.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - RMSD.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:303585.7 %
Date:2024-04-19 12:12:35Functions: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       13167 :   Vector calculateCenter(const std::vector<Vector> &p,const std::vector<double> &w) {
+      84       13167 :     plumed_massert(p.size()==w.size(),"mismatch in dimension of position/align arrays while calculating the center");
+      85       13167 :     unsigned n; n=p.size();
+      86       13167 :     Vector c; c.zero();
+      87      209302 :     for(unsigned i=0; i<n; i++)c+=p[i]*w[i];
+      88       13167 :     return c;
+      89             :   };
+      90             : // removes the center for the position provided
+      91       26329 :   void removeCenter(std::vector<Vector> &p, const Vector &c) {
+      92       26329 :     unsigned n; n=p.size();
+      93      418574 :     for(unsigned i=0; i<n; i++)p[i]-=c;
+      94       26329 :   };
+      95             : // add center
+      96       13167 :   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             :   const std::vector<Vector>& getReference() const ;
+     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      103848 : 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      103848 :   RMSDCoreData(const std::vector<double> &a,const std::vector<double> &d,const std::vector<Vector> &p, const std::vector<Vector> &r):
+     309      103848 :     alEqDis(false),distanceIsMSD(false),hasDistance(false),isInitialized(false),safe(false),
+     310      103848 :     creference_is_calculated(false),creference_is_removed(false),
+     311      103848 :     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      103848 :   {cpositions.zero(); creference.zero();};
+     313             : 
+     314             :   // set the center on the fly without subtracting
+     315      103848 :   void calcPositionsCenter() {
+     316      103848 :     plumed_massert(!cpositions_is_calculated,"the center was already calculated");
+     317     1939353 :     cpositions.zero(); for(unsigned i=0; i<positions.size(); i++) {cpositions+=positions[i]*align[i];} cpositions_is_calculated=true;
+     318      103848 :   }
+     319           0 :   void calcReferenceCenter() {
+     320           0 :     plumed_massert(!creference_is_calculated,"the center was already calculated");
+     321           0 :     creference.zero(); for(unsigned i=0; i<reference.size(); i++) {creference+=reference[i]*align[i];} creference_is_calculated=true;
+     322           0 :   };
+     323             :   // assume the center is given externally
+     324             :   // cppcheck-suppress passedByValue
+     325           0 :   void setPositionsCenter(Vector v) {plumed_massert(!cpositions_is_calculated,"You are setting the center two times!"); cpositions=v; cpositions_is_calculated=true;};
+     326             :   // cppcheck-suppress passedByValue
+     327      103848 :   void setReferenceCenter(Vector v) {plumed_massert(!creference_is_calculated,"You are setting the center two times!"); creference=v; creference_is_calculated=true;};
+     328             :   // the center is already removed
+     329      103848 :   void setPositionsCenterIsRemoved(bool t) {cpositions_is_removed=t;};
+     330      103848 :   void setReferenceCenterIsRemoved(bool t) {creference_is_removed=t;};
+     331             :   bool getPositionsCenterIsRemoved() {return cpositions_is_removed;};
+     332             :   bool getReferenceCenterIsRemoved() {return creference_is_removed;};
+     333             :   //  does the core calc : first thing to call after the constructor:
+     334             :   // only_rotation=true does not retrieve the derivatives, just retrieve the optimal rotation (the same calc cannot be exploit further)
+     335             :   void doCoreCalc(bool safe,bool alEqDis, bool only_rotation=false);
+     336             :   // do calculation with close structure data structures
+     337             :   void doCoreCalcWithCloseStructure(bool safe,bool alEqDis, const Tensor & rotationPosClose, const Tensor & rotationRefClose, std::array<std::array<Tensor,3>,3> & drotationPosCloseDrr01);
+     338             :   // retrieve the distance if required after doCoreCalc
+     339             :   double getDistance(bool squared);
+     340             :   // retrieve the derivative of the distance respect to the position
+     341             :   std::vector<Vector> getDDistanceDPositions();
+     342             :   // retrieve the derivative of the distance respect to the reference
+     343             :   std::vector<Vector> getDDistanceDReference();
+     344             :   // specific version for SOMA calculation (i.e. does not need derivative respect to rotation matrix)
+     345             :   std::vector<Vector> getDDistanceDReferenceSOMA();
+     346             :   // get aligned reference onto position
+     347             :   std::vector<Vector> getAlignedReferenceToPositions();
+     348             :   // get aligned position onto reference
+     349             :   std::vector<Vector> getAlignedPositionsToReference();
+     350             :   // get centered positions
+     351             :   std::vector<Vector> getCenteredPositions();
+     352             :   // get centered reference
+     353             :   std::vector<Vector> getCenteredReference();
+     354             :   // get center of positions
+     355             :   Vector getPositionsCenter();
+     356             :   // get center of reference
+     357             :   Vector getReferenceCenter();
+     358             :   // get rotation matrix (reference ->positions)
+     359             :   Tensor getRotationMatrixReferenceToPositions();
+     360             :   // get rotation matrix (positions -> reference)
+     361             :   Tensor getRotationMatrixPositionsToReference();
+     362             :   // get the derivative of the rotation matrix respect to positions
+     363             :   // note that the this transformation overlap the  reference onto position
+     364             :   // if inverseTransform=true then aligns the positions onto reference
+     365             :   Matrix<std::vector<Vector> > getDRotationDPositions( bool inverseTransform=false );
+     366             :   // get the derivative of the rotation matrix respect to reference
+     367             :   // note that the this transformation overlap the  reference onto position
+     368             :   // if inverseTransform=true then aligns the positions onto reference
+     369             :   Matrix<std::vector<Vector> >  getDRotationDReference(bool inverseTransform=false );
+     370             :   const std::array<std::array<Tensor,3>,3> & getDRotationDRr01() const;
+     371             : };
+     372             : 
+     373             : }
+     374             : 
+     375             : #endif
+     376             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Random.cpp.func-sort-c.html b/coverage/tools/Random.cpp.func-sort-c.html new file mode 100644 index 000000000000..23e785470ffd --- /dev/null +++ b/coverage/tools/Random.cpp.func-sort-c.html @@ -0,0 +1,117 @@ + + + + + + + + LCOV - plumed test coverage - tools/Random.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Random.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:768391.6 %
Date:2024-04-19 12:12:35Functions: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_traitsIcESaIcEEE808443
_ZN4PLMD6Random7setSeedEi809459
_ZN4PLMD6Random8GaussianEv1219087
_ZN4PLMD6Random7RandU01Ev1552983
_ZN4PLMD6Random3U01Ev5566333
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Random.cpp.func.html b/coverage/tools/Random.cpp.func.html new file mode 100644 index 000000000000..b259b6a1ec34 --- /dev/null +++ b/coverage/tools/Random.cpp.func.html @@ -0,0 +1,117 @@ + + + + + + + + LCOV - plumed test coverage - tools/Random.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Random.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:768391.6 %
Date:2024-04-19 12:12:35Functions:101190.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6Random10fromStringERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZN4PLMD6Random13ReadStateFullERSi0
_ZN4PLMD6Random3U01Ev5566333
_ZN4PLMD6Random4U01dEv2
_ZN4PLMD6Random7RandU01Ev1552983
_ZN4PLMD6Random7ShuffleERSt6vectorIjSaIjEE2
_ZN4PLMD6Random7setSeedEi809459
_ZN4PLMD6Random8GaussianEv1219087
_ZN4PLMD6RandomC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE808443
_ZNK4PLMD6Random14WriteStateFullERSo1
_ZNK4PLMD6Random8toStringERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Random.cpp.gcov.html b/coverage/tools/Random.cpp.gcov.html new file mode 100644 index 000000000000..fb63d26560fd --- /dev/null +++ b/coverage/tools/Random.cpp.gcov.html @@ -0,0 +1,246 @@ + + + + + + + + LCOV - plumed test coverage - tools/Random.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Random.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:768391.6 %
Date:2024-04-19 12:12:35Functions: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      808443 : Random::Random(const std::string & name):
+      39      808443 :   switchGaussian(false),
+      40      808443 :   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      808443 :   name(&name!=&noname?name:"noname")
+      47             : {
+      48      808443 :   iy=0;
+      49    26678619 :   for(unsigned i=0; i<NTAB; i++) iv[i]=0;
+      50      808443 :   setSeed(0);
+      51      808443 : }
+      52             : 
+      53      809459 : void Random::setSeed(int idum_) {
+      54      809459 :   if(idum_>0) idum_=-idum_;
+      55      809459 :   idum=idum_;
+      56      809459 :   incPrec=false;
+      57      809459 : }
+      58             : 
+      59     1552983 : double Random::RandU01 ()
+      60             : {
+      61     1552983 :   if (incPrec)
+      62           1 :     return U01d();
+      63             :   else
+      64     1552982 :     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     5566333 : double Random::U01() {
+      77             :   int j,k;
+      78             :   double temp;
+      79     5566333 :   if (idum <= 0 || !iy) {
+      80        1622 :     if (-idum < 1) idum=1;
+      81         795 :     else idum = -idum;
+      82       66502 :     for (j=NTAB+7; j>=0; j--) {
+      83       64880 :       k=idum/IQ;
+      84       64880 :       idum=IA*(idum-k*IQ)-IR*k;
+      85       64880 :       if (idum < 0) idum += IM;
+      86       64880 :       if (j < NTAB) iv[j] = idum;
+      87             :     }
+      88        1622 :     iy=iv[0];
+      89             :   }
+      90     5566333 :   k=idum/IQ;
+      91     5566333 :   idum=IA*(idum-k*IQ)-IR*k;
+      92     5566333 :   if (idum < 0) idum += IM;
+      93     5566333 :   j=iy/NDIV;
+      94     5566333 :   iy=iv[j];
+      95     5566333 :   iv[j] = idum;
+      96     5566333 :   if ((temp=AM*iy) > RNMX) return RNMX;
+      97     5566333 :   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     1219087 : double Random::Gaussian() {
+     143             :   double v1,v2,rsq;
+     144     1219087 :   if(switchGaussian) {
+     145      609517 :     switchGaussian=false;
+     146      609517 :     return saveGaussian;
+     147             :   }
+     148             :   while(true) {
+     149      775817 :     v1=2.0*RandU01()-1.0;
+     150      775817 :     v2=2.0*RandU01()-1.0;
+     151      775817 :     rsq=v1*v1+v2*v2;
+     152      775817 :     if(rsq<1.0 && rsq>0.0) break;
+     153             :   }
+     154      609570 :   double fac=std::sqrt(-2.*std::log(rsq)/rsq);
+     155      609570 :   saveGaussian=v1*fac;
+     156      609570 :   switchGaussian=true;
+     157      609570 :   return v2*fac;
+     158             : }
+     159             : 
+     160           2 : void Random::Shuffle(std::vector<unsigned>& vec) {
+     161             :   std::iterator_traits<std::vector<unsigned>::iterator >::difference_type i, n;
+     162             :   n = vec.end() - vec.begin();
+     163           6 :   for(i=n-1; i>0; --i) {
+     164           4 :     std::swap(vec[i], vec[(int)round(RandU01() * IM) % i]);
+     165             :   }
+     166           2 : }
+     167             : 
+     168             : 
+     169             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Random.h.func-sort-c.html b/coverage/tools/Random.h.func-sort-c.html new file mode 100644 index 000000000000..78c3946159de --- /dev/null +++ b/coverage/tools/Random.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage - tools/Random.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Random.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-04-19 12:12:35Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Random.h.func.html b/coverage/tools/Random.h.func.html new file mode 100644 index 000000000000..6adbbb2e64a0 --- /dev/null +++ b/coverage/tools/Random.h.func.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage - tools/Random.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Random.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-04-19 12:12:35Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Random.h.gcov.html b/coverage/tools/Random.h.gcov.html new file mode 100644 index 000000000000..a28ca28b1995 --- /dev/null +++ b/coverage/tools/Random.h.gcov.html @@ -0,0 +1,149 @@ + + + + + + + + LCOV - plumed test coverage - tools/Random.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Random.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-04-19 12:12:35Functions: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      808378 : class Random {
+      33             :   static const int IA=16807,IM=2147483647,IQ=127773,IR=2836,NTAB=32;
+      34             :   static const int NDIV=(1+(IM-1)/NTAB);
+      35             :   static const double EPS;
+      36             :   static const double AM;
+      37             :   static const double RNMX;
+      38             :   static const double fact;
+      39             :   static const std::string noname;
+      40             :   bool incPrec;
+      41             :   bool switchGaussian;
+      42             :   double saveGaussian;
+      43             :   int iy;
+      44             :   int iv[NTAB];
+      45             :   int idum;
+      46             :   std::string name;
+      47             : public:
+      48             :   explicit Random(const std::string & name=noname);
+      49             :   void setSeed(int idum);
+      50             :   double RandU01();
+      51             :   double U01();
+      52             :   double U01d();
+      53             :   int RandInt(int i);
+      54             :   void Shuffle(std::vector<unsigned>& vec);
+      55             :   void WriteStateFull(std::ostream &)const;
+      56             :   void ReadStateFull (std::istream &);
+      57             :   void fromString(const std::string & str);
+      58             :   void toString(std::string & str)const;
+      59             :   friend std::ostream & operator<<(std::ostream & out,const Random & rng) {
+      60             :     rng.WriteStateFull(out); return out;
+      61             :   }
+      62             :   friend std::istream & operator>>(std::istream & in,Random & rng) {
+      63             :     rng.ReadStateFull(in); return in;
+      64             :   }
+      65             :   double Gaussian();
+      66             :   void IncreasedPrecis(bool i) {incPrec=i;}
+      67             : };
+      68             : 
+      69             : }
+      70             : 
+      71             : #endif
+      72             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/RootFindingBase.h.func-sort-c.html b/coverage/tools/RootFindingBase.h.func-sort-c.html new file mode 100644 index 000000000000..4e60b8ccd910 --- /dev/null +++ b/coverage/tools/RootFindingBase.h.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - tools/RootFindingBase.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - RootFindingBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1616100.0 %
Date:2024-04-19 12:12:35Functions: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_7contour23DistanceFromContourBaseEE7lsearchERKSt6vectorIdSaIdEERS6_MS2_FdS8_S9_E291
_ZNK4PLMD15RootFindingBaseINS_7contour23DistanceFromContourBaseEE8doSearchERKSt6vectorIdSaIdEERS6_RNS_5F1dimIS2_EE291
_ZNK4PLMD15RootFindingBaseINS_7contour18ContourFindingBaseEE10linesearchERKSt6vectorIdSaIdEERS6_MS2_KFdS8_S9_E1896
_ZNK4PLMD15RootFindingBaseINS_7contour18ContourFindingBaseEE8doSearchERKSt6vectorIdSaIdEERS6_RNS_5F1dimIS2_EE1896
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/RootFindingBase.h.func.html b/coverage/tools/RootFindingBase.h.func.html new file mode 100644 index 000000000000..40238af24e5e --- /dev/null +++ b/coverage/tools/RootFindingBase.h.func.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - tools/RootFindingBase.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - RootFindingBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1616100.0 %
Date:2024-04-19 12:12:35Functions: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_7contour18ContourFindingBaseEE10linesearchERKSt6vectorIdSaIdEERS6_MS2_KFdS8_S9_E1896
_ZNK4PLMD15RootFindingBaseINS_7contour18ContourFindingBaseEE8doSearchERKSt6vectorIdSaIdEERS6_RNS_5F1dimIS2_EE1896
_ZNK4PLMD15RootFindingBaseINS_7contour23DistanceFromContourBaseEE7lsearchERKSt6vectorIdSaIdEERS6_MS2_FdS8_S9_E291
_ZNK4PLMD15RootFindingBaseINS_7contour23DistanceFromContourBaseEE8doSearchERKSt6vectorIdSaIdEERS6_RNS_5F1dimIS2_EE291
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/RootFindingBase.h.gcov.html b/coverage/tools/RootFindingBase.h.gcov.html new file mode 100644 index 000000000000..f118d1ee2503 --- /dev/null +++ b/coverage/tools/RootFindingBase.h.gcov.html @@ -0,0 +1,154 @@ + + + + + + + + LCOV - plumed test coverage - tools/RootFindingBase.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - RootFindingBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1616100.0 %
Date:2024-04-19 12:12:35Functions: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           5 :   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        2187 : 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        2187 :   Brent1DRootSearch<F1dim<FCLASS> > bb(f1dim);
+      52             : 
+      53             :   // This does the actual search for the root
+      54        2187 :   double ax=0.0, xx=1.0;
+      55        2187 :   bb.bracket( ax, xx, &F1dim<FCLASS>::getEng );
+      56        2187 :   double xmin=bb.search( &F1dim<FCLASS>::getEng );
+      57        8748 :   for(unsigned i=0; i<p.size(); ++i) p[i] += xmin*dir[i];
+      58        2187 : }
+      59             : 
+      60             : template <class FCLASS>
+      61        1896 : 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        1896 :   F1dim<FCLASS> f1dim( p, dir, myclass_func, myfunc, NULL );
+      64             :   // Actually do the search
+      65        1896 :   doSearch( dir, p, f1dim );
+      66        1896 : }
+      67             : 
+      68             : template <class FCLASS>
+      69         291 : 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         291 :   F1dim<FCLASS> f1dim( p, dir, myclass_func, NULL, myfunc );
+      72             :   // Actually do the search
+      73         291 :   doSearch( dir, p, f1dim );
+      74         291 : }
+      75             : 
+      76             : }
+      77             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Stopwatch.cpp.func-sort-c.html b/coverage/tools/Stopwatch.cpp.func-sort-c.html new file mode 100644 index 000000000000..2c66c2475a7e --- /dev/null +++ b/coverage/tools/Stopwatch.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - tools/Stopwatch.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Stopwatch.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2121100.0 %
Date:2024-04-19 12:12:35Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMDlsERSoRKNS_9StopwatchE1198
_ZNK4PLMD9Stopwatch3logERSo1198
_ZN4PLMD9StopwatchD2Ev806394
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Stopwatch.cpp.func.html b/coverage/tools/Stopwatch.cpp.func.html new file mode 100644 index 000000000000..aaa7138f9dd2 --- /dev/null +++ b/coverage/tools/Stopwatch.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - tools/Stopwatch.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Stopwatch.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2121100.0 %
Date:2024-04-19 12:12:35Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9StopwatchD2Ev806394
_ZN4PLMDlsERSoRKNS_9StopwatchE1198
_ZNK4PLMD9Stopwatch3logERSo1198
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Stopwatch.cpp.gcov.html b/coverage/tools/Stopwatch.cpp.gcov.html new file mode 100644 index 000000000000..50cc4c13f9cc --- /dev/null +++ b/coverage/tools/Stopwatch.cpp.gcov.html @@ -0,0 +1,155 @@ + + + + + + + + LCOV - plumed test coverage - tools/Stopwatch.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Stopwatch.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2121100.0 %
Date:2024-04-19 12:12:35Functions: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        1198 : std::ostream& operator<<(std::ostream&os,const Stopwatch&sw) {
+      36        1198 :   return sw.log(os);
+      37             : }
+      38             : 
+      39      806394 : Stopwatch::~Stopwatch() {
+      40      806394 :   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        9061 :     for(auto & w : watches) {
+      45        7866 :       if(w.second.state==Watch::State::paused) w.second.start().stop();
+      46             :     }
+      47        1195 :     *mylog << *this;
+      48             :   }
+      49      806394 : }
+      50             : 
+      51        1198 : std::ostream& Stopwatch::log(std::ostream&os)const {
+      52             :   const std::size_t bufferlen=1000;
+      53             :   char buffer[bufferlen];
+      54        1198 :   buffer[0]=0;
+      55       49118 :   for(unsigned i=0; i<40; i++) os<<" ";
+      56        1198 :   os<<"      Cycles        Total      Average      Minimum      Maximum\n";
+      57             : 
+      58             :   std::vector<std::string> names;
+      59        9070 :   for(const auto & it : watches) names.emplace_back(it.first);
+      60        1198 :   std::sort(names.begin(),names.end());
+      61             : 
+      62             :   const double frac=1.0/1000000000.0;
+      63             : 
+      64        9070 :   for(const auto & name : names) {
+      65        7872 :     const Watch&t(watches.find(name)->second);
+      66             :     os<<name;
+      67      194421 :     for(unsigned i=name.length(); i<40; i++) os<<" ";
+      68        7872 :     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        7872 :     os<<buffer;
+      70             :   }
+      71        1198 :   return os;
+      72        1198 : }
+      73             : 
+      74             : }
+      75             : 
+      76             : 
+      77             : 
+      78             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Stopwatch.h.func-sort-c.html b/coverage/tools/Stopwatch.h.func-sort-c.html new file mode 100644 index 000000000000..aace4473eb50 --- /dev/null +++ b/coverage/tools/Stopwatch.h.func-sort-c.html @@ -0,0 +1,117 @@ + + + + + + + + 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:536581.5 %
Date:2024-04-19 12:12:35Functions:101190.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9StopwatchaSEOS0_0
_ZN4PLMD9Stopwatch5pauseERKSt17basic_string_viewIcSt11char_traitsIcEE1
_ZN4PLMD9Stopwatch4stopERKSt17basic_string_viewIcSt11char_traitsIcEE4
_ZN4PLMD9Stopwatch5startERKSt17basic_string_viewIcSt11char_traitsIcEE8
_ZN4PLMD9Stopwatch7HandleraSEOS1_5075
_ZN4PLMD9Stopwatch10startPauseERKSt17basic_string_viewIcSt11char_traitsIcEE1326408
_ZN4PLMDL20StopwatchEmptyStringEv1326410
_ZN4PLMD9Stopwatch9startStopERKSt17basic_string_viewIcSt11char_traitsIcEE1698224
_ZN4PLMD9Stopwatch5Watch4stopEv1699414
_ZN4PLMD9Stopwatch5Watch5pauseEv3025669
_ZN4PLMD9Stopwatch7HandlerD2Ev8534801
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Stopwatch.h.func.html b/coverage/tools/Stopwatch.h.func.html new file mode 100644 index 000000000000..57553c43b6ba --- /dev/null +++ b/coverage/tools/Stopwatch.h.func.html @@ -0,0 +1,117 @@ + + + + + + + + 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:536581.5 %
Date:2024-04-19 12:12:35Functions:101190.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9Stopwatch10startPauseERKSt17basic_string_viewIcSt11char_traitsIcEE1326408
_ZN4PLMD9Stopwatch4stopERKSt17basic_string_viewIcSt11char_traitsIcEE4
_ZN4PLMD9Stopwatch5Watch4stopEv1699414
_ZN4PLMD9Stopwatch5Watch5pauseEv3025669
_ZN4PLMD9Stopwatch5pauseERKSt17basic_string_viewIcSt11char_traitsIcEE1
_ZN4PLMD9Stopwatch5startERKSt17basic_string_viewIcSt11char_traitsIcEE8
_ZN4PLMD9Stopwatch7HandlerD2Ev8534801
_ZN4PLMD9Stopwatch7HandleraSEOS1_5075
_ZN4PLMD9Stopwatch9startStopERKSt17basic_string_viewIcSt11char_traitsIcEE1698224
_ZN4PLMD9StopwatchaSEOS0_0
_ZN4PLMDL20StopwatchEmptyStringEv1326410
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Stopwatch.h.gcov.html b/coverage/tools/Stopwatch.h.gcov.html new file mode 100644 index 000000000000..82dae0627794 --- /dev/null +++ b/coverage/tools/Stopwatch.h.gcov.html @@ -0,0 +1,543 @@ + + + + + + + + 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:536581.5 %
Date:2024-04-19 12:12:35Functions: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             : #ifndef __PLUMED_tools_Stopwatch_h
+      23             : #define __PLUMED_tools_Stopwatch_h
+      24             : 
+      25             : #include "Exception.h"
+      26             : #include "Tools.h"
+      27             : #include <string>
+      28             : #include <iosfwd>
+      29             : #include <chrono>
+      30             : 
+      31             : namespace PLMD {
+      32             : 
+      33             : /**
+      34             : \ingroup TOOLBOX
+      35             : Class implementing stopwatch to time execution.
+      36             : 
+      37             : Each instance of this class is a container which
+      38             : can keep track of several named stopwatches at
+      39             : the same time. Access to the stopwatches
+      40             : is obtained using start(), stop(), pause() methods,
+      41             : giving as a parameter the name of the specific stopwatch.
+      42             : Also an empty string can be used (un-named stopwatch).
+      43             : Finally, all the times can be logged using << operator
+      44             : 
+      45             : \verbatim
+      46             : #include "Stopwatch.h"
+      47             : 
+      48             : int main(){
+      49             :   Stopwatch sw;
+      50             :   sw.start();
+      51             : 
+      52             :   sw.start("initialization");
+      53             : // do initialization ...
+      54             :   sw.stop("initialization");
+      55             : 
+      56             :   for(int i=0;i<100;i++){
+      57             :     sw.start("loop");
+      58             : // do calculation
+      59             :     sw.stop("loop");
+      60             :   }
+      61             : 
+      62             :   sw.stop();
+      63             :   return 0;
+      64             : }
+      65             : 
+      66             : \endverbatim
+      67             : 
+      68             : Using pause a stopwatch can be put on hold until
+      69             : the next start:
+      70             : 
+      71             : \verbatim
+      72             : #include "Stopwatch.h"
+      73             : 
+      74             : int main(){
+      75             :   Stopwatch sw;
+      76             :   sw.start();
+      77             : 
+      78             :   sw.start("initialization");
+      79             : // do initialization ...
+      80             :   sw.stop("initialization");
+      81             : 
+      82             :   for(int i=0;i<100;i++){
+      83             :     sw.start("loop");
+      84             : // do calculation
+      85             :     sw.pause("loop");
+      86             : // here goes something that we do not want to include
+      87             :     sw.start("loop");
+      88             : // do calculation
+      89             :     sw.stop("loop");
+      90             :   }
+      91             : 
+      92             :   sw.stop();
+      93             :   return 0;
+      94             : }
+      95             : 
+      96             : \endverbatim
+      97             : 
+      98             : Notice that as of PLUMED 2.5 it is possible to use a slightly modified
+      99             : interface that allow for exception safety. In practice,
+     100             : one can replace a pair of calls to Stopwatch::start() and Stopwatch::stop()
+     101             : with a single call to Stopwatch::startStop(). This call will return an object
+     102             : that, when goes out of scope, will stop the timer.
+     103             : 
+     104             : \notice The exception safety interace is highly recommended since it allows
+     105             : to make sure that stopwatches are started and stopped consistently.
+     106             : 
+     107             : For instance the following
+     108             : code
+     109             : \verbatim
+     110             :   {
+     111             :     sw.start("A");
+     112             :   // any code
+     113             :     sw.stop("A");
+     114             :   }
+     115             : \endverbatim
+     116             : can be replaced with
+     117             : \verbatim
+     118             :   {
+     119             :     auto sww=sw.startStop("A");
+     120             :   // any code
+     121             : 
+     122             :   // stopwatch is stopped when sww goes out of scope
+     123             :   }
+     124             : \endverbatim
+     125             : Similarly, Stopwatch::startPause() can be used to replace a pair of
+     126             : Stopwatch::start() and Stopwatch::pause().
+     127             : 
+     128             : The older syntax (explicitly calling `Stopwatch::start()` and `Stopwatch::pause()`) is still
+     129             : allowed for backward compatibility.
+     130             : 
+     131             : Notice that the returned object is of type `Stopwatch::Handler`.
+     132             : You might be willing to explicitly declare a `Stopwatch::Handler` (instead of using `auto`)
+     133             : when you want to conditionally start the stopwatch. For instance:
+     134             : \verbatim
+     135             :   {
+     136             :     Stopwatch::Handler handler;
+     137             :     if(you_want_to_time_this) handler=sw.startStop();
+     138             :     ... do something ...
+     139             :   }
+     140             :   // in case it was started, the stopwatch will stop here, at the end of the block
+     141             :   // in case it was not started, nothing will happen
+     142             : \endverbatim
+     143             : 
+     144             : A `Stopwatch::Handler` can not be copied but it can be moved (it behaves like a unique_ptr).
+     145             : Moving it explicitly allows one to transfer it to another `Stopwatch::Handler` with a different scope.
+     146             : For instance, in case you want to conditionally stop the stopwatch you might use something like this:
+     147             : \verbatim
+     148             :   {
+     149             :     Stopwatch::Handler handler;
+     150             :     if(you_want_to_time_this) handler=sw.startStop();
+     151             :     ... do something ...
+     152             :     if(you_want_to_stop_here) auto h2=std::move(handler);
+     153             :     // the previous instruction moves handler to h2 that is then destroyed, stopping the watch
+     154             :     // notice that if the stop was not started it will not stop.
+     155             :     ... do something else ...
+     156             :   }
+     157             :   // in case it is running, the stopwatch will stop here, at the end of the block
+     158             : \endverbatim
+     159             : 
+     160             : Finally, notice that in order to write the timers on an output file when the
+     161             : Stopwatch is destroyed, one can store a reference to a PLMD::Log by passing it
+     162             : to the Stopwatch constructor.
+     163             : This will make sure timers are written also in case of a premature end.
+     164             : */
+     165             : 
+     166             : class Log;
+     167             : 
+     168             : /// Return an empty string.
+     169             : /// Inline static so that it can store a static variable (for quicker access)
+     170             : /// without adding a unique global symbol to a library including this header file.
+     171     1326410 : inline static const std::string & StopwatchEmptyString() noexcept {
+     172     1326410 :   const static std::string s;
+     173     1326410 :   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       13029 :   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             : /// last lap
+     228             :     long long int lastLap = 0;
+     229             : /// keep track of state
+     230             :     State state = State::stopped;
+     231             : /// Allows access to internal data
+     232             :     friend class Stopwatch;
+     233             :   public:
+     234             : /// start the watch
+     235             :     Watch & start();
+     236             : /// stop the watch
+     237             :     Watch & stop();
+     238             : /// pause the watch
+     239             :     Watch & pause();
+     240             : /// returns a start-stop handler
+     241             :     Handler startStop();
+     242             : /// returns a start-pause handler
+     243             :     Handler startPause();
+     244             : /// returns the time for the last cycle
+     245             :     long long int getLastCycle() noexcept;
+     246             : /// returns the total time
+     247             :     long long int getTotal() noexcept;
+     248             :   };
+     249             : 
+     250             : private:
+     251             : 
+     252             : /// Pointer to a log file.
+     253             : /// If set, the stopwatch is logged in its destructor.
+     254             :   Log*mylog=nullptr;
+     255             : 
+     256             : /// List of watches.
+     257             : /// Each watch is labeled with a string.
+     258             :   Tools::FastStringUnorderedMap<Watch> watches;
+     259             : 
+     260             : /// Log over stream os.
+     261             :   std::ostream& log(std::ostream& os)const;
+     262             : 
+     263             : public:
+     264             : // Constructor.
+     265             :   explicit Stopwatch() = default;
+     266             : // Constructor.
+     267             : // When destructing, stopwatch is logged.
+     268             : // Make sure that log survives stopwatch. Typically, it should be declared earlier, in order
+     269             : // to be destroyed later.
+     270      806379 :   explicit Stopwatch(Log&log): mylog(&log) {}
+     271             : // Destructor.
+     272             :   ~Stopwatch();
+     273             : /// Deleted copy
+     274             :   Stopwatch(const Stopwatch&) = delete;
+     275             : /// Deleted assignment
+     276             :   Stopwatch& operator=(const Stopwatch&) = delete;
+     277             : /// Move constructor
+     278             :   Stopwatch(Stopwatch&&) noexcept;
+     279             : /// Move assignment
+     280             :   Stopwatch& operator=(Stopwatch&&) noexcept;
+     281             : /// Start timer named "name"
+     282             :   Stopwatch& start(const std::string_view&name=StopwatchEmptyString());
+     283             : /// Stop timer named "name"
+     284             :   Stopwatch& stop(const std::string_view&name=StopwatchEmptyString());
+     285             : /// Pause timer named "name"
+     286             :   Stopwatch& pause(const std::string_view&name=StopwatchEmptyString());
+     287             : /// Dump all timers on an ostream
+     288             :   friend std::ostream& operator<<(std::ostream&,const Stopwatch&);
+     289             : /// Start with exception safety, then stop.
+     290             : /// Starts the Stopwatch and returns an object that, when goes out of scope,
+     291             : /// stops the watch. This allows Stopwatch to be started and stopped in
+     292             : /// an exception safe manner.
+     293             :   Handler startStop(const std::string_view&name=StopwatchEmptyString());
+     294             : /// Start with exception safety, then pause.
+     295             : /// Starts the Stopwatch and returns an object that, when goes out of scope,
+     296             : /// pauses the watch. This allows Stopwatch to be started and paused in
+     297             : /// an exception safe manner.
+     298             :   Handler startPause(const std::string_view&name=StopwatchEmptyString());
+     299             : /// Return the last completed cycle
+     300             :   long long int getLastCycle(const std::string_view&name=StopwatchEmptyString());
+     301             : /// returns the total time
+     302             :   long long int getTotal(const std::string_view&name=StopwatchEmptyString());
+     303             : };
+     304             : 
+     305             : inline
+     306             : Stopwatch::Handler::Handler(Watch* watch,bool stop) :
+     307     3024632 :   watch(watch),
+     308     3024632 :   stop(stop)
+     309             : {
+     310             :   watch->start();
+     311             : }
+     312             : 
+     313             : inline
+     314     8534801 : Stopwatch::Handler::~Handler() {
+     315     8534801 :   if(watch) {
+     316     3024632 :     if(stop) watch->stop();
+     317     1326408 :     else watch->pause();
+     318             :   }
+     319     8534801 : }
+     320             : 
+     321             : inline
+     322           8 : Stopwatch& Stopwatch::start(const std::string_view & name) {
+     323           8 :   watches[name].start();
+     324           8 :   return *this;
+     325             : }
+     326             : 
+     327             : inline
+     328           4 : Stopwatch& Stopwatch::stop(const std::string_view & name) {
+     329           4 :   watches[name].stop();
+     330           4 :   return *this;
+     331             : }
+     332             : 
+     333             : inline
+     334           1 : Stopwatch& Stopwatch::pause(const std::string_view & name) {
+     335           1 :   watches[name].pause();
+     336           1 :   return *this;
+     337             : }
+     338             : 
+     339             : inline
+     340     1698224 : Stopwatch::Handler Stopwatch::startStop(const std::string_view&name) {
+     341     1698224 :   return watches[name].startStop();
+     342             : }
+     343             : 
+     344             : inline
+     345     1326408 : Stopwatch::Handler Stopwatch::startPause(const std::string_view&name) {
+     346     1326408 :   return watches[name].startPause();
+     347             : }
+     348             : 
+     349             : inline
+     350             : long long int Stopwatch::getLastCycle(const std::string_view&name) {
+     351           0 :   return watches[name].getLastCycle();
+     352             : }
+     353             : 
+     354             : inline
+     355             : long long int Stopwatch::getTotal(const std::string_view&name) {
+     356             :   return watches[name].getTotal();
+     357             : }
+     358             : 
+     359             : inline
+     360             : Stopwatch::Handler::Handler(Handler && handler) noexcept :
+     361             :   watch(handler.watch),
+     362             :   stop(handler.stop)
+     363             : {
+     364             :   handler.watch=nullptr;
+     365             : }
+     366             : 
+     367             : inline
+     368        5075 : Stopwatch::Handler & Stopwatch::Handler::operator=(Handler && handler) noexcept {
+     369        5075 :   if(this!=&handler) {
+     370        5075 :     if(watch) {
+     371             :       try {
+     372           0 :         if(stop) watch->stop();
+     373           0 :         else watch->pause();
+     374           0 :       } catch(...) {
+     375             : // this is to avoid problems with cppcheck, given than this method is declared as
+     376             : // noexcept and stop and pause might throw in case of an internal bug
+     377           0 :         std::terminate();
+     378             :       }
+     379             :     }
+     380        5075 :     watch=handler.watch;
+     381        5075 :     stop=handler.stop;
+     382        5075 :     handler.watch=nullptr;
+     383             :   }
+     384        5075 :   return *this;
+     385             : }
+     386             : 
+     387             : inline
+     388             : Stopwatch::Watch & Stopwatch::Watch::start() {
+     389     3025826 :   state=State::started;
+     390     3025826 :   running++;
+     391     3025826 :   lastStart=std::chrono::high_resolution_clock::now();
+     392             :   return *this;
+     393             : }
+     394             : 
+     395             : inline
+     396     1699414 : Stopwatch::Watch & Stopwatch::Watch::stop() {
+     397     1699414 :   pause();
+     398     1699414 :   state=State::stopped;
+     399     1699414 :   cycles++;
+     400     1699414 :   total+=lap;
+     401     1699414 :   if(lap>max)max=lap;
+     402     1699414 :   if(min>lap || cycles==1)min=lap;
+     403     1699414 :   lastLap=lap;
+     404     1699414 :   lap=0;
+     405     1699414 :   return *this;
+     406             : }
+     407             : 
+     408             : inline
+     409     3025669 : Stopwatch::Watch & Stopwatch::Watch::pause() {
+     410     3025669 :   state=State::paused;
+     411             : // In case of an internal bug (non matching start stop within the startStop or startPause interface)
+     412             : // this assertion could fail in a destructor.
+     413             : // If this happens, the program should crash immediately
+     414     3025669 :   plumed_assert(running>0) << "Non matching start/pause or start/stop commands in a Stopwatch";
+     415     3025669 :   running--;
+     416             : // notice: with exception safety the following might be converted to a plain error.
+     417             : // I leave it like this for now:
+     418     3025669 :   if(running!=0) return *this;
+     419     3025618 :   auto t=std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::high_resolution_clock::now()-lastStart);
+     420     3025618 :   lap+=t.count();
+     421     3025618 :   return *this;
+     422             : }
+     423             : 
+     424             : inline
+     425             : Stopwatch::Handler Stopwatch::Watch::startStop() {
+     426             :   return Handler( this,true );
+     427             : }
+     428             : 
+     429             : inline
+     430             : Stopwatch::Handler Stopwatch::Watch::startPause() {
+     431             :   return Handler( this,false );
+     432             : }
+     433             : 
+     434             : inline
+     435             : long long int Stopwatch::Watch::getLastCycle() noexcept {
+     436           0 :   return lastLap;
+     437             : }
+     438             : 
+     439             : inline
+     440             : long long int Stopwatch::Watch::getTotal() noexcept {
+     441             :   return total;
+     442             : }
+     443             : 
+     444             : inline
+     445             : Stopwatch::Stopwatch(Stopwatch&& other) noexcept:
+     446             :   mylog(other.mylog),
+     447             :   watches(std::move(other.watches))
+     448             : {
+     449             :   other.mylog=nullptr;
+     450             : }
+     451             : 
+     452             : inline
+     453           0 : Stopwatch& Stopwatch::operator=(Stopwatch&& other) noexcept {
+     454           0 :   if(this!=&other) {
+     455           0 :     mylog=other.mylog;
+     456           0 :     watches=std::move(other.watches);
+     457           0 :     other.mylog=nullptr;
+     458             :   }
+     459           0 :   return *this;
+     460             : }
+     461             : 
+     462             : 
+     463             : }
+     464             : 
+     465             : 
+     466             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Subprocess.cpp.func-sort-c.html b/coverage/tools/Subprocess.cpp.func-sort-c.html new file mode 100644 index 000000000000..0dea4a34eadc --- /dev/null +++ b/coverage/tools/Subprocess.cpp.func-sort-c.html @@ -0,0 +1,137 @@ + + + + + + + + LCOV - plumed test coverage - tools/Subprocess.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Subprocess.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:608174.1 %
Date:2024-04-19 12:12:35Functions:141687.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10Subprocess7HandlerC2EOS1_0
_ZN4PLMD10Subprocess7HandleraSEOS1_0
_ZN4PLMD10Subprocess4contEv8
_ZN4PLMD10Subprocess5flushEv8
_ZN4PLMD10Subprocess7HandlerC2EPS0_8
_ZN4PLMD10Subprocess7HandlerD2Ev8
_ZN4PLMD13SubprocessPid4contEv8
_ZN4PLMD10Subprocess4stopEv9
_ZN4PLMD13SubprocessPid4stopEv9
_ZN4PLMDL26SubprocessPidGetenvSignalsEv17
_ZN4PLMD10SubprocessC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE29
_ZN4PLMD10SubprocessD2Ev29
_ZN4PLMD13SubprocessPidC2Ei29
_ZN4PLMD13SubprocessPidD2Ev29
_ZN4PLMD10Subprocess7getlineERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE36
_ZN4PLMD10Subprocess9availableEv117
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Subprocess.cpp.func.html b/coverage/tools/Subprocess.cpp.func.html new file mode 100644 index 000000000000..f1ae6f82a89a --- /dev/null +++ b/coverage/tools/Subprocess.cpp.func.html @@ -0,0 +1,137 @@ + + + + + + + + LCOV - plumed test coverage - tools/Subprocess.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Subprocess.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:608174.1 %
Date:2024-04-19 12:12:35Functions:141687.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10Subprocess4contEv8
_ZN4PLMD10Subprocess4stopEv9
_ZN4PLMD10Subprocess5flushEv8
_ZN4PLMD10Subprocess7HandlerC2EOS1_0
_ZN4PLMD10Subprocess7HandlerC2EPS0_8
_ZN4PLMD10Subprocess7HandlerD2Ev8
_ZN4PLMD10Subprocess7HandleraSEOS1_0
_ZN4PLMD10Subprocess7getlineERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE36
_ZN4PLMD10Subprocess9availableEv117
_ZN4PLMD10SubprocessC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE29
_ZN4PLMD10SubprocessD2Ev29
_ZN4PLMD13SubprocessPid4contEv8
_ZN4PLMD13SubprocessPid4stopEv9
_ZN4PLMD13SubprocessPidC2Ei29
_ZN4PLMD13SubprocessPidD2Ev29
_ZN4PLMDL26SubprocessPidGetenvSignalsEv17
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Subprocess.cpp.gcov.html b/coverage/tools/Subprocess.cpp.gcov.html new file mode 100644 index 000000000000..ba2adfafefaa --- /dev/null +++ b/coverage/tools/Subprocess.cpp.gcov.html @@ -0,0 +1,257 @@ + + + + + + + + LCOV - plumed test coverage - tools/Subprocess.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Subprocess.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:608174.1 %
Date:2024-04-19 12:12:35Functions:141687.5 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2018-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "Subprocess.h"
+      23             : #include "Exception.h"
+      24             : #include "Tools.h"
+      25             : #ifdef __PLUMED_HAS_SUBPROCESS
+      26             : #include <unistd.h>
+      27             : #include <csignal>
+      28             : #endif
+      29             : 
+      30             : namespace PLMD {
+      31             : 
+      32             : /// Retrieve PLUMED_ENABLE_SIGNALS.
+      33             : /// Inline static so that it can store a static variable (for quicker access)
+      34             : /// without adding a unique global symbol to a library including this header file.
+      35          17 : inline static bool SubprocessPidGetenvSignals() noexcept {
+      36          17 :   static const bool res=std::getenv("PLUMED_ENABLE_SIGNALS");
+      37          17 :   return res;
+      38             : }
+      39             : 
+      40             : /// Small utility class, used to avoid inclusion of unistd.h> in a header file.
+      41             : class SubprocessPid {
+      42             : #ifdef __PLUMED_HAS_SUBPROCESS
+      43             : public:
+      44             :   pid_t pid;
+      45          29 :   explicit SubprocessPid(pid_t pid):
+      46          29 :     pid(pid)
+      47             :   {
+      48          29 :     plumed_assert(pid!=0 && pid!=-1);
+      49          29 :   }
+      50           9 :   void stop() noexcept {
+      51             :     // Signals give problems with MPI on Travis.
+      52             :     // I disable them for now.
+      53           9 :     if(SubprocessPidGetenvSignals()) if(pid!=0 && pid!=-1) kill(pid,SIGSTOP);
+      54           9 :   }
+      55           8 :   void cont() noexcept {
+      56             :     // Signals give problems with MPI on Travis.
+      57             :     // I disable them for now.
+      58           8 :     if(SubprocessPidGetenvSignals()) if(pid!=0 && pid!=-1) kill(pid,SIGCONT);
+      59           8 :   }
+      60          29 :   ~SubprocessPid() {
+      61             :     // this is apparently working also with MPI on Travis.
+      62          29 :     if(pid!=0 && pid!=-1) kill(pid,SIGINT);
+      63          29 :   }
+      64             : #endif
+      65             : };
+      66             : 
+      67          29 : Subprocess::Subprocess(const std::string & cmd) {
+      68             : #ifdef __PLUMED_HAS_SUBPROCESS
+      69          29 :   char* arr [] = {
+      70             :     // const_cast are necessary here due to the declaration of execv
+      71             :     const_cast<char*>("/bin/sh"),
+      72             :     const_cast<char*>("-c"),
+      73             :     const_cast<char*>(cmd.c_str()),
+      74             :     nullptr
+      75          29 :   };
+      76             :   int cp[2];
+      77             :   int pc[2];
+      78          29 :   if(pipe(pc)<0) plumed_error()<<"error creating parent to child pipe";
+      79          29 :   if(pipe(cp)<0) plumed_error()<<"error creating child to parent pipe";
+      80          29 :   pid_t pid=fork();
+      81          29 :   switch(pid) {
+      82           0 :   case -1:
+      83           0 :     plumed_error()<<"error forking";
+      84             :     break;
+      85             : // CHILD:
+      86           0 :   case 0:
+      87             :   {
+      88           0 :     if(close(1)<0) plumed_error()<<"error closing file";
+      89           0 :     if(dup(cp[1])<0) plumed_error()<<"error duplicating file";
+      90           0 :     if(close(0)<0) plumed_error()<<"error closing file";
+      91           0 :     if(dup(pc[0])<0) plumed_error()<<"error duplicating file";
+      92           0 :     if(close(pc[1])<0) plumed_error()<<"error closing file";
+      93           0 :     if(close(cp[0])<0) plumed_error()<<"error closing file";
+      94           0 :     auto err=execv(arr[0],arr);
+      95           0 :     plumed_error()<<"error in script file " << cmd << ", execv returned "<<err;
+      96             :   }
+      97             : // PARENT::
+      98          29 :   default:
+      99          29 :     this->pid=Tools::make_unique<SubprocessPid>(pid);
+     100          29 :     if(close(pc[0])<0) plumed_error()<<"error closing file";
+     101          29 :     if(close(cp[1])<0) plumed_error()<<"error closing file";
+     102          29 :     fpc=pc[1];
+     103          29 :     fcp=cp[0];
+     104          29 :     fppc=fdopen(fpc,"w");
+     105          29 :     parent_to_child.link(fppc);
+     106          29 :     fpcp=fdopen(fcp,"r");
+     107          29 :     child_to_parent.link(fpcp);
+     108             :   }
+     109             : #else
+     110             :   plumed_error()<<"Subprocess not supported";
+     111             : #endif
+     112          29 : }
+     113             : 
+     114          29 : Subprocess::~Subprocess() {
+     115             : #ifdef __PLUMED_HAS_SUBPROCESS
+     116             : // fpc should be closed to terminate the child executable
+     117          29 :   fclose(fppc);
+     118          29 :   close(fpc);
+     119             : // fcp should not be closed because it could make the child executable fail
+     120             : /// TODO: check if this is necessary and make this class exception safe!
+     121             : #endif
+     122          29 : }
+     123             : 
+     124         117 : bool Subprocess::available() noexcept {
+     125             : #ifdef __PLUMED_HAS_SUBPROCESS
+     126         117 :   return true;
+     127             : #else
+     128             :   return false;
+     129             : #endif
+     130             : }
+     131             : 
+     132           9 : void Subprocess::stop() noexcept {
+     133             : #ifdef __PLUMED_HAS_SUBPROCESS
+     134           9 :   pid->stop();
+     135             : #endif
+     136           9 : }
+     137             : 
+     138           8 : void Subprocess::cont() noexcept {
+     139             : #ifdef __PLUMED_HAS_SUBPROCESS
+     140           8 :   pid->cont();
+     141             : #endif
+     142           8 : }
+     143             : 
+     144           8 : void Subprocess::flush() {
+     145           8 :   parent_to_child.flush();
+     146           8 : }
+     147             : 
+     148          36 : Subprocess & Subprocess::getline(std::string & line) {
+     149          36 :   child_to_parent.getline(line);
+     150          36 :   if(!child_to_parent) plumed_error() <<"error reading subprocess";
+     151          36 :   return (*this);
+     152             : }
+     153             : 
+     154           8 : Subprocess::Handler::Handler(Subprocess *sp) noexcept:
+     155           8 :   sp(sp)
+     156             : {
+     157           8 :   sp->cont();
+     158           8 : }
+     159             : 
+     160           8 : Subprocess::Handler::~Handler() {
+     161           8 :   if(sp) sp->stop();
+     162           8 : }
+     163             : 
+     164           0 : Subprocess::Handler::Handler(Handler && handler) noexcept :
+     165           0 :   sp(handler.sp)
+     166             : {
+     167           0 :   handler.sp=nullptr;
+     168           0 : }
+     169             : 
+     170           0 : Subprocess::Handler & Subprocess::Handler::operator=(Handler && handler) noexcept {
+     171           0 :   if(this!=&handler) {
+     172           0 :     if(sp) sp->stop();
+     173           0 :     sp=handler.sp;
+     174           0 :     handler.sp=nullptr;
+     175             :   }
+     176           0 :   return *this;
+     177             : }
+     178             : 
+     179             : 
+     180             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Subprocess.h.func-sort-c.html b/coverage/tools/Subprocess.h.func-sort-c.html new file mode 100644 index 000000000000..9c4183f3d4d0 --- /dev/null +++ b/coverage/tools/Subprocess.h.func-sort-c.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - tools/Subprocess.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Subprocess.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:44100.0 %
Date:2024-04-19 12:12:35Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMDlsIA2_cEERNS_10SubprocessES3_RKT_8
_ZN4PLMDlsINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEERNS_10SubprocessES8_RKT_8
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Subprocess.h.func.html b/coverage/tools/Subprocess.h.func.html new file mode 100644 index 000000000000..68c25846aaa2 --- /dev/null +++ b/coverage/tools/Subprocess.h.func.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - tools/Subprocess.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Subprocess.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:44100.0 %
Date:2024-04-19 12:12:35Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMDlsIA2_cEERNS_10SubprocessES3_RKT_8
_ZN4PLMDlsINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEERNS_10SubprocessES8_RKT_8
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Subprocess.h.gcov.html b/coverage/tools/Subprocess.h.gcov.html new file mode 100644 index 000000000000..ce650a95493c --- /dev/null +++ b/coverage/tools/Subprocess.h.gcov.html @@ -0,0 +1,219 @@ + + + + + + + + LCOV - plumed test coverage - tools/Subprocess.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Subprocess.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:44100.0 %
Date:2024-04-19 12:12:35Functions:22100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2019-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_tools_Subprocess_h
+      23             : #define __PLUMED_tools_Subprocess_h
+      24             : 
+      25             : #include "OFile.h"
+      26             : #include "IFile.h"
+      27             : #include <string>
+      28             : #include <cstdio>
+      29             : #include <memory>
+      30             : 
+      31             : namespace PLMD {
+      32             : 
+      33             : /// Small class to avoid including unistd.h here
+      34             : class SubprocessPid;
+      35             : 
+      36             : /**
+      37             : Class managing a subprocess.
+      38             : 
+      39             : The subprocess is launched and one can interact with it through a pipe.
+      40             : 
+      41             : In order not to consume resources, it might be possible to use this syntax:
+      42             : 
+      43             : \verbatim
+      44             : // at construction:
+      45             : Subprocess sp;
+      46             : sp.stop();
+      47             : 
+      48             : // when needed
+      49             : {
+      50             :   auto h=sp.contStop();
+      51             :   sp<<"command\n";
+      52             :   sp.flush();
+      53             :   sp.getline(answer);
+      54             : }
+      55             : // when h goes out of scope, subprocess is stopped again.
+      56             : // If an exception is raised in the block, the subprocess is stopped as well.
+      57             : \endverbatim
+      58             : 
+      59             : \warning
+      60             : Currently `stop` and `cont` are giving problems with some MPI implementation,
+      61             : In addition, notice that the stop signal is only sent to the child process and
+      62             : not to the subsequently spawn processes, so it might not work as intended.
+      63             : This feature is left here but is probably no a good idea to use it.
+      64             : It can be enabled with `export PLUMED_ENABLE_SIGNALS=1`.
+      65             : 
+      66             : */
+      67             : class Subprocess {
+      68             :   /// Process ID.
+      69             :   /// We store this rather than pid_t to avoid including <unistd.h> in this header file.
+      70             :   /// This remains nullptr in the child process.
+      71             :   std::unique_ptr<SubprocessPid> pid;
+      72             :   /// File descriptor, parent to child
+      73             :   int fpc=0;
+      74             :   /// File descriptor, child to parent
+      75             :   int fcp=0;
+      76             :   /// File pointer, parent to child
+      77             :   FILE* fppc=NULL;
+      78             :   /// File pointer, child to parent
+      79             :   FILE* fpcp=NULL;
+      80             :   /// PLUMED file object, parent to child.
+      81             :   /// Used to simplify formatting
+      82             :   OFile parent_to_child;
+      83             :   /// PLUMED file object, child to parent.
+      84             :   /// Used to simplify formatting
+      85             :   IFile child_to_parent;
+      86             : public:
+      87             :   /// Class used to cont/stop a Subprocess in an exception safe manner.
+      88             :   class Handler {
+      89             :     Subprocess* sp=nullptr;
+      90             :     /// Private constructor.
+      91             :     /// Only to be called by Subprocess::contStop()
+      92             :     explicit Handler(Subprocess* sp) noexcept;
+      93             :     friend class Subprocess;
+      94             :   public:
+      95             :     /// Default constructor
+      96             :     Handler() = default;
+      97             :     /// Destructor stops the subprocess.
+      98             :     ~Handler();
+      99             :     /// Default copy constructor is deleted (not copyable)
+     100             :     Handler(const Handler &) = delete;
+     101             :     /// Default copy assignment is deleted (not copyable)
+     102             :     Handler & operator=(const Handler & handler) = delete;
+     103             :     /// Move constructor.
+     104             :     Handler(Handler &&) noexcept;
+     105             :     /// Move assignment.
+     106             :     Handler & operator=(Handler && handler) noexcept;
+     107             :   };
+     108             : /// Constructor with a command line.
+     109             :   explicit Subprocess(const std::string & cmd);
+     110             : /// Destructor
+     111             :   ~Subprocess();
+     112             : /// Flush communication to process.
+     113             :   void flush();
+     114             : /// Check if subprocess facilities are available.
+     115             : /// If it returns false, any call to Subprocess constructor will raise an exception.
+     116             :   static bool available() noexcept;
+     117             : /// Get a line from the subprocess.
+     118             :   Subprocess & getline(std::string &);
+     119             : /// Write something to the subprocess.
+     120             :   template <class T> friend Subprocess& operator<<(Subprocess& ep,const T &t);
+     121             : /// Send a SIGCONT to the subprocess.
+     122             : /// Better used through contStop() method.
+     123             :   void cont() noexcept;
+     124             : /// Send a SIGSTOP to the subprocess.
+     125             : /// Better used through contStop() method.
+     126             :   void stop() noexcept;
+     127             : /// Returns a handler to temporarily resume the process.
+     128             :   Handler contStop() noexcept {
+     129           8 :     return Handler(this);
+     130             :   }
+     131             : };
+     132             : 
+     133             : template <class T>
+     134          16 : Subprocess& operator<<(Subprocess& ep,const T &t) {
+     135          16 :   ep.parent_to_child<<t;
+     136          16 :   return ep;
+     137             : }
+     138             : 
+     139             : }
+     140             : 
+     141             : #endif
+     142             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/SwitchingFunction.cpp.func-sort-c.html b/coverage/tools/SwitchingFunction.cpp.func-sort-c.html new file mode 100644 index 000000000000..148b087285d5 --- /dev/null +++ b/coverage/tools/SwitchingFunction.cpp.func-sort-c.html @@ -0,0 +1,497 @@ + + + + + + + + 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:38540694.8 %
Date:2024-04-19 12:12:35Functions:8210677.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD16switchContainers10baseSwitch13removeStretchEv0
_ZN4PLMD16switchContainers10baseSwitchD0Ev0
_ZN4PLMD16switchContainers11cubicSwitchD2Ev0
_ZN4PLMD16switchContainers13fixedRationalILi10ELb1ELb1EEC2Eddd0
_ZN4PLMD16switchContainers13fixedRationalILi2ELb1ELb1EEC2Eddd0
_ZN4PLMD16switchContainers20fixedRationalFactoryILi0ELb1EEESt8optionalISt10unique_ptrINS0_10baseSwitchESt14default_deleteIS4_EEEdddi0
_ZN4PLMD16switchContainers20fixedRationalFactoryILi2ELb1EEESt8optionalISt10unique_ptrINS0_10baseSwitchESt14default_deleteIS4_EEEdddi0
_ZN4PLMD16switchContainers8rationalILNS0_11rationalPowE1ELNS0_12rationalFormE1EE10doRationalEdRddiid0
_ZN4PLMD16switchContainers8rationalILNS0_11rationalPowE1ELNS0_12rationalFormE1EEC2Edddii0
_ZN4PLMD17SwitchingFunction16registerKeywordsERNS_8KeywordsE0
_ZNK4PLMD16switchContainers12leptonSwitch8functionEdRd0
_ZNK4PLMD16switchContainers13fixedRationalILi10ELb1ELb1EE12calculateSqrEdRd0
_ZNK4PLMD16switchContainers13fixedRationalILi10ELb1ELb1EE19specificDescriptionB5cxx11Ev0
_ZNK4PLMD16switchContainers13fixedRationalILi10ELb1ELb1EE8functionEdRd0
_ZNK4PLMD16switchContainers13fixedRationalILi12ELb1ELb1EE12calculateSqrEdRd0
_ZNK4PLMD16switchContainers13fixedRationalILi2ELb1ELb1EE12calculateSqrEdRd0
_ZNK4PLMD16switchContainers13fixedRationalILi2ELb1ELb1EE19specificDescriptionB5cxx11Ev0
_ZNK4PLMD16switchContainers13fixedRationalILi2ELb1ELb1EE8functionEdRd0
_ZNK4PLMD16switchContainers13fixedRationalILi4ELb1ELb1EE8functionEdRd0
_ZNK4PLMD16switchContainers13fixedRationalILi8ELb1ELb1EE8functionEdRd0
_ZNK4PLMD16switchContainers13nativeqSwitch8functionEdRd0
_ZNK4PLMD16switchContainers8rationalILNS0_11rationalPowE1ELNS0_12rationalFormE1EE12calculateSqrEdRd0
_ZNK4PLMD16switchContainers8rationalILNS0_11rationalPowE1ELNS0_12rationalFormE1EE19specificDescriptionB5cxx11Ev0
_ZNK4PLMD16switchContainers8rationalILNS0_11rationalPowE1ELNS0_12rationalFormE1EE8functionEdRd0
_ZN4PLMD16switchContainers13fixedRationalILi4ELb1ELb1EEC2Eddd1
_ZN4PLMD16switchContainers20fixedRationalFactoryILi4ELb1EEESt8optionalISt10unique_ptrINS0_10baseSwitchESt14default_deleteIS4_EEEdddi1
_ZNK4PLMD16switchContainers13fixedRationalILi4ELb1ELb1EE19specificDescriptionB5cxx11Ev1
_ZNK4PLMD16switchContainers18fastGaussianSwitch8functionEdRd1
_ZN4PLMD16switchContainers13fixedRationalILi8ELb1ELb1EEC2Eddd2
_ZNK4PLMD16switchContainers13fixedRationalILi8ELb1ELb1EE19specificDescriptionB5cxx11Ev2
_ZN4PLMD16switchContainers13cosinusSwitchC2Eddd3
_ZN4PLMD16switchContainers8rationalILNS0_11rationalPowE0ELNS0_12rationalFormE0EEC2Edddii3
_ZNK4PLMD16switchContainers8rationalILNS0_11rationalPowE0ELNS0_12rationalFormE0EE19specificDescriptionB5cxx11Ev3
_ZN4PLMD16switchContainers10tanhSwitchC2Eddd4
_ZNK4PLMD16switchContainers10baseSwitch6get_d0Ev8
_ZNK4PLMD17SwitchingFunction6get_d0Ev8
_ZN4PLMD16switchContainers11cubicSwitchC2Edd14
_ZN4PLMD16switchContainers11cubicSwitchD0Ev14
_ZNK4PLMD16switchContainers11cubicSwitch19specificDescriptionB5cxx11Ev14
_ZN4PLMD16switchContainers10smapSwitchC2Edddii15
_ZNK4PLMD16switchContainers10smapSwitch19specificDescriptionB5cxx11Ev15
_ZN4PLMD16switchContainers13fixedRationalILi12ELb1ELb1EEC2Eddd16
_ZNK4PLMD16switchContainers13fixedRationalILi12ELb1ELb1EE19specificDescriptionB5cxx11Ev16
_ZNK4PLMD16switchContainers12leptonSwitch19specificDescriptionB5cxx11Ev18
_ZN4PLMD16switchContainers12leptonSwitch12funcAndDerivC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE20
_ZN4PLMD16switchContainers12leptonSwitchC2EdddRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE20
_ZNK4PLMD17SwitchingFunction6get_r0Ev32
_ZN4PLMD16switchContainers12leptonSwitch12funcAndDerivC2ERKS2_44
_ZN4PLMD16switchContainers8rationalILNS0_11rationalPowE1ELNS0_12rationalFormE0EEC2Edddii49
_ZNK4PLMD16switchContainers8rationalILNS0_11rationalPowE1ELNS0_12rationalFormE0EE19specificDescriptionB5cxx11Ev49
_ZN4PLMD16switchContainers8rationalILNS0_11rationalPowE0ELNS0_12rationalFormE0EE10doRationalEdRddiid52
_ZNK4PLMD16switchContainers8rationalILNS0_11rationalPowE0ELNS0_12rationalFormE0EE8functionEdRd52
_ZNK4PLMD16switchContainers8rationalILNS0_11rationalPowE0ELNS0_12rationalFormE0EE12calculateSqrEdRd60
_ZNK4PLMD16switchContainers8rationalILNS0_11rationalPowE1ELNS0_12rationalFormE0EE12calculateSqrEdRd60
_ZN4PLMD16switchContainers14gaussianSwitchC2Eddd66
_ZN4PLMD17SwitchingFunction3setEiidd74
_ZN4PLMD16switchContainers17exponentialSwitchC2Eddd75
_ZN4PLMD16switchContainers18fastGaussianSwitchC2Eddd112
_ZNK4PLMD16switchContainers8rationalILNS0_11rationalPowE0ELNS0_12rationalFormE1EE19specificDescriptionB5cxx11Ev113
_ZN4PLMD16switchContainers8rationalILNS0_11rationalPowE0ELNS0_12rationalFormE1EEC2Edddii132
_ZNK4PLMD16switchContainers10baseSwitch19specificDescriptionB5cxx11Ev150
_ZN4PLMD16switchContainers10baseSwitch12setupStretchEv215
_ZNK4PLMD16switchContainers13fixedRationalILi6ELb1ELb1EE19specificDescriptionB5cxx11Ev241
_ZN4PLMD16switchContainers13fixedRationalILi6ELb1ELb1EEC2Eddd260
_ZN4PLMD16switchContainers20fixedRationalFactoryILi6ELb1EEESt8optionalISt10unique_ptrINS0_10baseSwitchESt14default_deleteIS4_EEEdddi261
_ZN4PLMD16switchContainers20fixedRationalFactoryILi10ELb1EEESt8optionalISt10unique_ptrINS0_10baseSwitchESt14default_deleteIS4_EEEdddi263
_ZN4PLMD16switchContainers20fixedRationalFactoryILi8ELb1EEESt8optionalISt10unique_ptrINS0_10baseSwitchESt14default_deleteIS4_EEEdddi263
_ZN4PLMD16switchContainers20fixedRationalFactoryILi12ELb1EEESt8optionalISt10unique_ptrINS0_10baseSwitchESt14default_deleteIS4_EEEdddi279
_ZN4PLMD16switchContainers15rationalFactoryEdddii463
_ZNK4PLMD16switchContainers13nativeqSwitch19specificDescriptionB5cxx11Ev572
_ZNK4PLMD16switchContainers10baseSwitch11descriptionB5cxx11Ev1194
_ZNK4PLMD17SwitchingFunction11descriptionB5cxx11Ev1194
_ZNK4PLMD16switchContainers10baseSwitch6get_r0Ev1226
_ZN4PLMD17SwitchingFunction3setERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS6_1271
_ZN4PLMD16switchContainers10baseSwitchC2EdddSt17basic_string_viewIcSt11char_traitsIcEE1344
_ZN4PLMD16switchContainers10baseSwitchD2Ev1344
_ZN4PLMD16switchContainers13fixedRationalILi12ELb1ELb1EE10doRationalILi12EEEddRdd1382
_ZNK4PLMD16switchContainers13fixedRationalILi12ELb1ELb1EE8functionEdRd1382
_ZNK4PLMD16switchContainers13fixedRationalILi4ELb1ELb1EE12calculateSqrEdRd1428
_ZNK4PLMD16switchContainers10tanhSwitch8functionEdRd12718
_ZNK4PLMD16switchContainers11cubicSwitch8functionEdRd127255
_ZNK4PLMD16switchContainers13nativeqSwitch9calculateEdRd146632
_ZNK4PLMD16switchContainers14gaussianSwitch8functionEdRd279640
_ZNK4PLMD16switchContainers13cosinusSwitch8functionEdRd522111
_ZN4PLMD16switchContainers8rationalILNS0_11rationalPowE0ELNS0_12rationalFormE1EE10doRationalEdRddiid2113979
_ZNK4PLMD16switchContainers8rationalILNS0_11rationalPowE0ELNS0_12rationalFormE1EE8functionEdRd2113979
_ZNK4PLMD16switchContainers17exponentialSwitch8functionEdRd2404247
_ZNK4PLMD16switchContainers13fixedRationalILi8ELb1ELb1EE12calculateSqrEdRd3128712
_ZNK4PLMD16switchContainers8rationalILNS0_11rationalPowE0ELNS0_12rationalFormE1EE12calculateSqrEdRd3408239
_ZNK4PLMD16switchContainers12leptonSwitch9calculateEdRd5877796
_ZNK4PLMD16switchContainers12leptonSwitch12funcAndDerivclEd6515285
_ZNK4PLMD16switchContainers12leptonSwitch12calculateSqrEdRd7125890
_ZNK4PLMD16switchContainers13fixedRationalILi6ELb1ELb1EE12calculateSqrEdRd8345710
_ZNK4PLMD16switchContainers8rationalILNS0_11rationalPowE1ELNS0_12rationalFormE0EE8functionEdRd16093212
_ZN4PLMD16switchContainers8rationalILNS0_11rationalPowE1ELNS0_12rationalFormE0EE10doRationalEdRddiid16093264
_ZNK4PLMD16switchContainers13fixedRationalILi6ELb1ELb1EE8functionEdRd16153550
_ZNK4PLMD16switchContainers10smapSwitch8functionEdRd21911326
_ZNK4PLMD16switchContainers10baseSwitch12calculateSqrEdRd31818564
_ZNK4PLMD16switchContainers18fastGaussianSwitch12calculateSqrEdRd38317812
_ZNK4PLMD16switchContainers10baseSwitch9get_dmax2Ev49030642
_ZNK4PLMD17SwitchingFunction9get_dmax2Ev49030642
_ZNK4PLMD17SwitchingFunction12calculateSqrEdRd92146473
_ZNK4PLMD17SwitchingFunction9calculateEdRd127719055
_ZNK4PLMD16switchContainers10baseSwitch9calculateEdRd162799700
_ZNK4PLMD16switchContainers10baseSwitch8get_dmaxEv536580540
_ZNK4PLMD17SwitchingFunction8get_dmaxEv536580540
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/SwitchingFunction.cpp.func.html b/coverage/tools/SwitchingFunction.cpp.func.html new file mode 100644 index 000000000000..d19a4dff95e4 --- /dev/null +++ b/coverage/tools/SwitchingFunction.cpp.func.html @@ -0,0 +1,497 @@ + + + + + + + + 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:38540694.8 %
Date:2024-04-19 12:12:35Functions:8210677.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD16switchContainers10baseSwitch12setupStretchEv215
_ZN4PLMD16switchContainers10baseSwitch13removeStretchEv0
_ZN4PLMD16switchContainers10baseSwitchC2EdddSt17basic_string_viewIcSt11char_traitsIcEE1344
_ZN4PLMD16switchContainers10baseSwitchD0Ev0
_ZN4PLMD16switchContainers10baseSwitchD2Ev1344
_ZN4PLMD16switchContainers10smapSwitchC2Edddii15
_ZN4PLMD16switchContainers10tanhSwitchC2Eddd4
_ZN4PLMD16switchContainers11cubicSwitchC2Edd14
_ZN4PLMD16switchContainers11cubicSwitchD0Ev14
_ZN4PLMD16switchContainers11cubicSwitchD2Ev0
_ZN4PLMD16switchContainers12leptonSwitch12funcAndDerivC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE20
_ZN4PLMD16switchContainers12leptonSwitch12funcAndDerivC2ERKS2_44
_ZN4PLMD16switchContainers12leptonSwitchC2EdddRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE20
_ZN4PLMD16switchContainers13cosinusSwitchC2Eddd3
_ZN4PLMD16switchContainers13fixedRationalILi10ELb1ELb1EEC2Eddd0
_ZN4PLMD16switchContainers13fixedRationalILi12ELb1ELb1EE10doRationalILi12EEEddRdd1382
_ZN4PLMD16switchContainers13fixedRationalILi12ELb1ELb1EEC2Eddd16
_ZN4PLMD16switchContainers13fixedRationalILi2ELb1ELb1EEC2Eddd0
_ZN4PLMD16switchContainers13fixedRationalILi4ELb1ELb1EEC2Eddd1
_ZN4PLMD16switchContainers13fixedRationalILi6ELb1ELb1EEC2Eddd260
_ZN4PLMD16switchContainers13fixedRationalILi8ELb1ELb1EEC2Eddd2
_ZN4PLMD16switchContainers14gaussianSwitchC2Eddd66
_ZN4PLMD16switchContainers15rationalFactoryEdddii463
_ZN4PLMD16switchContainers17exponentialSwitchC2Eddd75
_ZN4PLMD16switchContainers18fastGaussianSwitchC2Eddd112
_ZN4PLMD16switchContainers20fixedRationalFactoryILi0ELb1EEESt8optionalISt10unique_ptrINS0_10baseSwitchESt14default_deleteIS4_EEEdddi0
_ZN4PLMD16switchContainers20fixedRationalFactoryILi10ELb1EEESt8optionalISt10unique_ptrINS0_10baseSwitchESt14default_deleteIS4_EEEdddi263
_ZN4PLMD16switchContainers20fixedRationalFactoryILi12ELb1EEESt8optionalISt10unique_ptrINS0_10baseSwitchESt14default_deleteIS4_EEEdddi279
_ZN4PLMD16switchContainers20fixedRationalFactoryILi2ELb1EEESt8optionalISt10unique_ptrINS0_10baseSwitchESt14default_deleteIS4_EEEdddi0
_ZN4PLMD16switchContainers20fixedRationalFactoryILi4ELb1EEESt8optionalISt10unique_ptrINS0_10baseSwitchESt14default_deleteIS4_EEEdddi1
_ZN4PLMD16switchContainers20fixedRationalFactoryILi6ELb1EEESt8optionalISt10unique_ptrINS0_10baseSwitchESt14default_deleteIS4_EEEdddi261
_ZN4PLMD16switchContainers20fixedRationalFactoryILi8ELb1EEESt8optionalISt10unique_ptrINS0_10baseSwitchESt14default_deleteIS4_EEEdddi263
_ZN4PLMD16switchContainers8rationalILNS0_11rationalPowE0ELNS0_12rationalFormE0EE10doRationalEdRddiid52
_ZN4PLMD16switchContainers8rationalILNS0_11rationalPowE0ELNS0_12rationalFormE0EEC2Edddii3
_ZN4PLMD16switchContainers8rationalILNS0_11rationalPowE0ELNS0_12rationalFormE1EE10doRationalEdRddiid2113979
_ZN4PLMD16switchContainers8rationalILNS0_11rationalPowE0ELNS0_12rationalFormE1EEC2Edddii132
_ZN4PLMD16switchContainers8rationalILNS0_11rationalPowE1ELNS0_12rationalFormE0EE10doRationalEdRddiid16093264
_ZN4PLMD16switchContainers8rationalILNS0_11rationalPowE1ELNS0_12rationalFormE0EEC2Edddii49
_ZN4PLMD16switchContainers8rationalILNS0_11rationalPowE1ELNS0_12rationalFormE1EE10doRationalEdRddiid0
_ZN4PLMD16switchContainers8rationalILNS0_11rationalPowE1ELNS0_12rationalFormE1EEC2Edddii0
_ZN4PLMD17SwitchingFunction16registerKeywordsERNS_8KeywordsE0
_ZN4PLMD17SwitchingFunction3setERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS6_1271
_ZN4PLMD17SwitchingFunction3setEiidd74
_ZNK4PLMD16switchContainers10baseSwitch11descriptionB5cxx11Ev1194
_ZNK4PLMD16switchContainers10baseSwitch12calculateSqrEdRd31818564
_ZNK4PLMD16switchContainers10baseSwitch19specificDescriptionB5cxx11Ev150
_ZNK4PLMD16switchContainers10baseSwitch6get_d0Ev8
_ZNK4PLMD16switchContainers10baseSwitch6get_r0Ev1226
_ZNK4PLMD16switchContainers10baseSwitch8get_dmaxEv536580540
_ZNK4PLMD16switchContainers10baseSwitch9calculateEdRd162799700
_ZNK4PLMD16switchContainers10baseSwitch9get_dmax2Ev49030642
_ZNK4PLMD16switchContainers10smapSwitch19specificDescriptionB5cxx11Ev15
_ZNK4PLMD16switchContainers10smapSwitch8functionEdRd21911326
_ZNK4PLMD16switchContainers10tanhSwitch8functionEdRd12718
_ZNK4PLMD16switchContainers11cubicSwitch19specificDescriptionB5cxx11Ev14
_ZNK4PLMD16switchContainers11cubicSwitch8functionEdRd127255
_ZNK4PLMD16switchContainers12leptonSwitch12calculateSqrEdRd7125890
_ZNK4PLMD16switchContainers12leptonSwitch12funcAndDerivclEd6515285
_ZNK4PLMD16switchContainers12leptonSwitch19specificDescriptionB5cxx11Ev18
_ZNK4PLMD16switchContainers12leptonSwitch8functionEdRd0
_ZNK4PLMD16switchContainers12leptonSwitch9calculateEdRd5877796
_ZNK4PLMD16switchContainers13cosinusSwitch8functionEdRd522111
_ZNK4PLMD16switchContainers13fixedRationalILi10ELb1ELb1EE12calculateSqrEdRd0
_ZNK4PLMD16switchContainers13fixedRationalILi10ELb1ELb1EE19specificDescriptionB5cxx11Ev0
_ZNK4PLMD16switchContainers13fixedRationalILi10ELb1ELb1EE8functionEdRd0
_ZNK4PLMD16switchContainers13fixedRationalILi12ELb1ELb1EE12calculateSqrEdRd0
_ZNK4PLMD16switchContainers13fixedRationalILi12ELb1ELb1EE19specificDescriptionB5cxx11Ev16
_ZNK4PLMD16switchContainers13fixedRationalILi12ELb1ELb1EE8functionEdRd1382
_ZNK4PLMD16switchContainers13fixedRationalILi2ELb1ELb1EE12calculateSqrEdRd0
_ZNK4PLMD16switchContainers13fixedRationalILi2ELb1ELb1EE19specificDescriptionB5cxx11Ev0
_ZNK4PLMD16switchContainers13fixedRationalILi2ELb1ELb1EE8functionEdRd0
_ZNK4PLMD16switchContainers13fixedRationalILi4ELb1ELb1EE12calculateSqrEdRd1428
_ZNK4PLMD16switchContainers13fixedRationalILi4ELb1ELb1EE19specificDescriptionB5cxx11Ev1
_ZNK4PLMD16switchContainers13fixedRationalILi4ELb1ELb1EE8functionEdRd0
_ZNK4PLMD16switchContainers13fixedRationalILi6ELb1ELb1EE12calculateSqrEdRd8345710
_ZNK4PLMD16switchContainers13fixedRationalILi6ELb1ELb1EE19specificDescriptionB5cxx11Ev241
_ZNK4PLMD16switchContainers13fixedRationalILi6ELb1ELb1EE8functionEdRd16153550
_ZNK4PLMD16switchContainers13fixedRationalILi8ELb1ELb1EE12calculateSqrEdRd3128712
_ZNK4PLMD16switchContainers13fixedRationalILi8ELb1ELb1EE19specificDescriptionB5cxx11Ev2
_ZNK4PLMD16switchContainers13fixedRationalILi8ELb1ELb1EE8functionEdRd0
_ZNK4PLMD16switchContainers13nativeqSwitch19specificDescriptionB5cxx11Ev572
_ZNK4PLMD16switchContainers13nativeqSwitch8functionEdRd0
_ZNK4PLMD16switchContainers13nativeqSwitch9calculateEdRd146632
_ZNK4PLMD16switchContainers14gaussianSwitch8functionEdRd279640
_ZNK4PLMD16switchContainers17exponentialSwitch8functionEdRd2404247
_ZNK4PLMD16switchContainers18fastGaussianSwitch12calculateSqrEdRd38317812
_ZNK4PLMD16switchContainers18fastGaussianSwitch8functionEdRd1
_ZNK4PLMD16switchContainers8rationalILNS0_11rationalPowE0ELNS0_12rationalFormE0EE12calculateSqrEdRd60
_ZNK4PLMD16switchContainers8rationalILNS0_11rationalPowE0ELNS0_12rationalFormE0EE19specificDescriptionB5cxx11Ev3
_ZNK4PLMD16switchContainers8rationalILNS0_11rationalPowE0ELNS0_12rationalFormE0EE8functionEdRd52
_ZNK4PLMD16switchContainers8rationalILNS0_11rationalPowE0ELNS0_12rationalFormE1EE12calculateSqrEdRd3408239
_ZNK4PLMD16switchContainers8rationalILNS0_11rationalPowE0ELNS0_12rationalFormE1EE19specificDescriptionB5cxx11Ev113
_ZNK4PLMD16switchContainers8rationalILNS0_11rationalPowE0ELNS0_12rationalFormE1EE8functionEdRd2113979
_ZNK4PLMD16switchContainers8rationalILNS0_11rationalPowE1ELNS0_12rationalFormE0EE12calculateSqrEdRd60
_ZNK4PLMD16switchContainers8rationalILNS0_11rationalPowE1ELNS0_12rationalFormE0EE19specificDescriptionB5cxx11Ev49
_ZNK4PLMD16switchContainers8rationalILNS0_11rationalPowE1ELNS0_12rationalFormE0EE8functionEdRd16093212
_ZNK4PLMD16switchContainers8rationalILNS0_11rationalPowE1ELNS0_12rationalFormE1EE12calculateSqrEdRd0
_ZNK4PLMD16switchContainers8rationalILNS0_11rationalPowE1ELNS0_12rationalFormE1EE19specificDescriptionB5cxx11Ev0
_ZNK4PLMD16switchContainers8rationalILNS0_11rationalPowE1ELNS0_12rationalFormE1EE8functionEdRd0
_ZNK4PLMD17SwitchingFunction11descriptionB5cxx11Ev1194
_ZNK4PLMD17SwitchingFunction12calculateSqrEdRd92146473
_ZNK4PLMD17SwitchingFunction6get_d0Ev8
_ZNK4PLMD17SwitchingFunction6get_r0Ev32
_ZNK4PLMD17SwitchingFunction8get_dmaxEv536580540
_ZNK4PLMD17SwitchingFunction9calculateEdRd127719055
_ZNK4PLMD17SwitchingFunction9get_dmax2Ev49030642
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/SwitchingFunction.cpp.gcov.html b/coverage/tools/SwitchingFunction.cpp.gcov.html new file mode 100644 index 000000000000..3fb49f0984fe --- /dev/null +++ b/coverage/tools/SwitchingFunction.cpp.gcov.html @@ -0,0 +1,1040 @@ + + + + + + + + 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:38540694.8 %
Date:2024-04-19 12:12:35Functions:8210677.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 "SwitchingFunction.h"
+      23             : #include "Tools.h"
+      24             : #include "Keywords.h"
+      25             : #include "OpenMP.h"
+      26             : #include <vector>
+      27             : #include <limits>
+      28             : #include <algorithm>
+      29             : #include <optional>
+      30             : 
+      31             : namespace PLMD {
+      32             : 
+      33             : //+PLUMEDOC INTERNAL switchingfunction
+      34             : /*
+      35             : Functions that measure whether values are less than a certain quantity.
+      36             : 
+      37             : Switching functions \f$s(r)\f$ take a minimum of one input parameter \f$r_0\f$.
+      38             : 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.
+      39             : The various switching functions available in PLUMED differ in terms of how this decay is performed.
+      40             : 
+      41             : Where there is an accepted convention in the literature (e.g. \ref COORDINATION) on the form of the
+      42             : switching function we use the convention as the default.  However, the flexibility to use different
+      43             : switching functions is always present generally through a single keyword. This keyword generally
+      44             : takes an input with the following form:
+      45             : 
+      46             : \verbatim
+      47             : KEYWORD={TYPE <list of parameters>}
+      48             : \endverbatim
+      49             : 
+      50             : The following table contains a list of the various switching functions that are available in PLUMED 2
+      51             : together with an example input.
+      52             : 
+      53             : <table align=center frame=void width=95%% cellpadding=5%%>
+      54             : <tr>
+      55             : <td> TYPE </td> <td> FUNCTION </td> <td> EXAMPLE INPUT </td> <td> DEFAULT PARAMETERS </td>
+      56             : </tr> <tr> <td>RATIONAL </td> <td>
+      57             : \f$
+      58             : s(r)=\frac{ 1 - \left(\frac{ r - d_0 }{ r_0 }\right)^{n} }{ 1 - \left(\frac{ r - d_0 }{ r_0 }\right)^{m} }
+      59             : \f$
+      60             : </td> <td>
+      61             : {RATIONAL R_0=\f$r_0\f$ D_0=\f$d_0\f$ NN=\f$n\f$ MM=\f$m\f$}
+      62             : </td> <td> \f$d_0=0.0\f$, \f$n=6\f$, \f$m=2n\f$ </td>
+      63             : </tr> <tr>
+      64             : <td> EXP </td> <td>
+      65             : \f$
+      66             : s(r)=\exp\left(-\frac{ r - d_0 }{ r_0 }\right)
+      67             : \f$
+      68             : </td> <td>
+      69             : {EXP  R_0=\f$r_0\f$ D_0=\f$d_0\f$}
+      70             : </td> <td> \f$d_0=0.0\f$ </td>
+      71             : </tr> <tr>
+      72             : <td> GAUSSIAN </td> <td>
+      73             : \f$
+      74             : s(r)=\exp\left(-\frac{ (r - d_0)^2 }{ 2r_0^2 }\right)
+      75             : \f$
+      76             : </td> <td>
+      77             : {GAUSSIAN R_0=\f$r_0\f$ D_0=\f$d_0\f$}
+      78             : </td> <td> \f$d_0=0.0\f$ </td>
+      79             : </tr> <tr>
+      80             : <td> SMAP </td> <td>
+      81             : \f$
+      82             : s(r) = \left[ 1 + ( 2^{a/b} -1 )\left( \frac{r-d_0}{r_0} \right)^a \right]^{-b/a}
+      83             : \f$
+      84             : </td> <td>
+      85             : {SMAP R_0=\f$r_0\f$ D_0=\f$d_0\f$ A=\f$a\f$ B=\f$b\f$}
+      86             : </td> <td> \f$d_0=0.0\f$ </td>
+      87             : </tr> <tr>
+      88             : <td> Q </td> <td>
+      89             : \f$
+      90             : s(r) = \frac{1}{1 + \exp(\beta(r_{ij} - \lambda r_{ij}^0))}
+      91             : \f$
+      92             : </td> <td>
+      93             : {Q REF=\f$r_{ij}^0\f$ BETA=\f$\beta\f$ LAMBDA=\f$\lambda\f$ }
+      94             : </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>
+      95             : </tr> <tr>
+      96             : <td> CUBIC </td> <td>
+      97             : \f$
+      98             : s(r) = (y-1)^2(1+2y) \qquad \textrm{where} \quad y = \frac{r - r_1}{r_0-r_1}
+      99             : \f$
+     100             : </td> <td>
+     101             : {CUBIC D_0=\f$r_1\f$ D_MAX=\f$r_0\f$}
+     102             : </td> <td> </td>
+     103             : </tr> <tr>
+     104             : <td> TANH </td> <td>
+     105             : \f$
+     106             : s(r) = 1 - \tanh\left( \frac{ r - d_0 }{ r_0 } \right)
+     107             : \f$
+     108             : </td> <td>
+     109             : {TANH R_0=\f$r_0\f$ D_0=\f$d_0\f$}
+     110             : </td> <td> </td>
+     111             : </tr> <tr>
+     112             : <td> COSINUS </td> <td>
+     113             : \f$s(r) =\left\{\begin{array}{ll}
+     114             :    1                                                           & \mathrm{if } r \leq d_0 \\
+     115             :    0.5 \left( \cos ( \frac{ r - d_0 }{ r_0 } \pi ) + 1 \right) & \mathrm{if } d_0 < r\leq d_0 + r_0 \\
+     116             :    0                                                           & \mathrm{if } r < d_0 + r_0
+     117             :   \end{array}\right.
+     118             : \f$
+     119             : </td> <td>
+     120             : {COSINUS R_0=\f$r_0\f$ D_0=\f$d_0\f$}
+     121             : </td> <td> </td>
+     122             : </tr> <tr>
+     123             : <td> CUSTOM </td> <td>
+     124             : \f$
+     125             : s(r) = FUNC
+     126             : \f$
+     127             : </td> <td>
+     128             : {CUSTOM FUNC=1/(1+x^6) R_0=\f$r_0\f$ D_0=\f$d_0\f$}
+     129             : </td> <td> </td>
+     130             : </tr>
+     131             : </table>
+     132             : 
+     133             : Notice that most commonly used rational functions are better optimized and might run faster.
+     134             : 
+     135             : Notice that for backward compatibility we allow using `MATHEVAL` instead of `CUSTOM`.
+     136             : Also notice that if the a `CUSTOM` switching function only depends on even powers of `x` it can be
+     137             : made faster by using `x2` as a variable. For instance
+     138             : \verbatim
+     139             : {CUSTOM FUNC=1/(1+x2^3) R_0=0.3}
+     140             : \endverbatim
+     141             : is equivalent to
+     142             : \verbatim
+     143             : {CUSTOM FUNC=1/(1+x^6) R_0=0.3}
+     144             : \endverbatim
+     145             : but runs faster. The reason is that there is an expensive square root calculation that can be optimized out.
+     146             : 
+     147             : 
+     148             : \attention
+     149             : With the default implementation CUSTOM is slower than other functions
+     150             : (e.g., it is slower than an equivalent RATIONAL function by approximately a factor 2).
+     151             : Checkout page \ref Lepton to see how to improve its performance.
+     152             : 
+     153             : For all the switching functions in the above table one can also specify a further (optional) parameter using the parameter
+     154             : keyword D_MAX to assert that for \f$r>d_{\textrm{max}}\f$ the switching function can be assumed equal to zero.
+     155             : In this case the function is brought smoothly to zero by stretching and shifting it.
+     156             : \verbatim
+     157             : KEYWORD={RATIONAL R_0=1 D_MAX=3}
+     158             : \endverbatim
+     159             : the resulting switching function will be
+     160             : \f$
+     161             : s(r) = \frac{s'(r)-s'(d_{max})}{s'(0)-s'(d_{max})}
+     162             : \f$
+     163             : where
+     164             : \f$
+     165             : s'(r)=\frac{1-r^6}{1-r^{12}}
+     166             : \f$
+     167             : Since PLUMED 2.2 this is the default. The old behavior (no stretching) can be obtained with the
+     168             : NOSTRETCH flag. The NOSTRETCH keyword is only provided for backward compatibility and might be
+     169             : removed in the future. Similarly, the STRETCH keyword is still allowed but has no effect.
+     170             : 
+     171             : Notice that switching functions defined with the simplified syntax are never stretched
+     172             : for backward compatibility. This might change in the future.
+     173             : 
+     174             : */
+     175             : //+ENDPLUMEDOC
+     176             : 
+     177             : namespace switchContainers {
+     178             : 
+     179        1344 : baseSwitch::baseSwitch(double D0,double DMAX, double R0, std::string_view name)
+     180        1344 :   : d0(D0),
+     181        1344 :     dmax(DMAX),
+     182        1344 :     dmax_2([](const double d) {
+     183        1344 :   if(d<std::sqrt(std::numeric_limits<double>::max())) {
+     184         243 :     return  d*d;
+     185             :   } else {
+     186             :     return std::numeric_limits<double>::max();
+     187             :   }
+     188             : }(dmax)),
+     189        1344 : invr0(1.0/R0),
+     190        1344 : invr0_2(invr0*invr0),
+     191        1587 : mytype(name) {}
+     192             : 
+     193        1344 : baseSwitch::~baseSwitch()=default;
+     194             : 
+     195   162799700 : double baseSwitch::calculate(const double distance, double& dfunc) const {
+     196             :   double res = 0.0;//RVO!
+     197   162799700 :   dfunc = 0.0;
+     198   162799700 :   if(distance <= dmax) {
+     199             :     res = 1.0;
+     200   155982169 :     const double rdist = (distance-d0)*invr0;
+     201   155982169 :     if(rdist > 0.0) {
+     202    59619473 :       res = function(rdist,dfunc);
+     203             :       //the following comments came from the original
+     204             :       // this is for the chain rule (derivative of rdist):
+     205    59619473 :       dfunc *= invr0;
+     206             :       // for any future switching functions, be aware that multiplying invr0 is only
+     207             :       // correct for functions of rdist = (r-d0)/r0.
+     208             : 
+     209             :       // this is because calculate() sets dfunc to the derivative divided times the
+     210             :       // distance.
+     211             :       // (I think this is misleading and I would like to modify it - GB)
+     212    59619473 :       dfunc /= distance;
+     213             :     }
+     214   155982169 :     res=res*stretch+shift;
+     215   155982169 :     dfunc*=stretch;
+     216             :   }
+     217   162799700 :   return res;
+     218             : }
+     219             : 
+     220    31818564 : double baseSwitch::calculateSqr(double distance2,double&dfunc) const {
+     221    31818564 :   double res= calculate(std::sqrt(distance2),dfunc);//RVO!
+     222    31818564 :   return res;
+     223             : }
+     224           8 : double baseSwitch::get_d0() const {return d0;}
+     225        1226 : double baseSwitch::get_r0() const {return 1.0/invr0;}
+     226   536580540 : double baseSwitch::get_dmax() const {return dmax;}
+     227    49030642 : double baseSwitch::get_dmax2() const {return dmax_2;}
+     228        1194 : std::string baseSwitch::description() const {
+     229        1194 :   std::ostringstream ostr;
+     230        1194 :   ostr<<get_r0()
+     231             :       <<".  Using "
+     232             :       << mytype
+     233        2388 :       <<" switching function with parameters d0="<< d0
+     234        2388 :       << specificDescription();
+     235        1194 :   return ostr.str();
+     236        1194 : }
+     237         150 : std::string baseSwitch::specificDescription() const {return "";}
+     238         215 : void baseSwitch::setupStretch() {
+     239         215 :   if(dmax!=std::numeric_limits<double>::max()) {
+     240         215 :     stretch=1.0;
+     241         215 :     shift=0.0;
+     242             :     double dummy;
+     243         215 :     double s0=calculate(0.0,dummy);
+     244         215 :     double sd=calculate(dmax,dummy);
+     245         215 :     stretch=1.0/(s0-sd);
+     246         215 :     shift=-sd*stretch;
+     247             :   }
+     248         215 : }
+     249           0 : void baseSwitch::removeStretch() {
+     250           0 :   stretch=1.0;
+     251           0 :   shift=0.0;
+     252           0 : }
+     253             : template<int N, std::enable_if_t< (N >0), bool> = true, std::enable_if_t< (N %2 == 0), bool> = true>
+     254             :     class fixedRational :public baseSwitch {
+     255         260 :   std::string specificDescription() const override {
+     256         260 :     std::ostringstream ostr;
+     257         260 :     ostr << " nn=" << N << " mm=" <<N*2;
+     258         260 :     return ostr.str();
+     259         260 :   }
+     260             : public:
+     261         279 :   fixedRational(double D0,double DMAX, double R0)
+     262         279 :     :baseSwitch(D0,DMAX,R0,"rational") {}
+     263             : 
+     264             :   template <int POW>
+     265        1382 :   static inline double doRational(const double rdist, double&dfunc, double result=0.0) {
+     266             :     const double rNdist=Tools::fastpow<POW-1>(rdist);
+     267    27485030 :     result=1.0/(1.0+rNdist*rdist);
+     268    27485030 :     dfunc = -POW*rNdist*result*result;
+     269        1382 :     return result;
+     270             :   }
+     271             : 
+     272    16154932 :   inline double function(double rdist,double&dfunc) const override {
+     273             :     //preRes and preDfunc are passed already set
+     274        1382 :     dfunc=0.0;
+     275        1382 :     double result = doRational<N>(rdist,dfunc);
+     276    16154932 :     return result;
+     277             :   }
+     278             : 
+     279    11475850 :   double calculateSqr(double distance2,double&dfunc) const override {
+     280             :     double result=0.0;
+     281    11475850 :     dfunc=0.0;
+     282    11475850 :     if(distance2 <= dmax_2) {
+     283    11330098 :       const double rdist = distance2*invr0_2;
+     284             :       result = doRational<N/2>(rdist,dfunc);
+     285    11330098 :       dfunc*=2*invr0_2;
+     286             :       // stretch:
+     287    11330098 :       result=result*stretch+shift;
+     288    11330098 :       dfunc*=stretch;
+     289             :     }
+     290    11475850 :     return result;
+     291             : 
+     292             :   }
+     293             : };
+     294             : 
+     295             : //these enums are useful for clarifying the settings in the factory
+     296             : //and the code is autodocumented ;)
+     297             : enum class rationalPow:bool {standard, fast};
+     298             : enum class rationalForm:bool {standard, simplified};
+     299             : 
+     300             : template<rationalPow isFast, rationalForm nis2m>
+     301             : class rational : public baseSwitch {
+     302             : protected:
+     303             :   const int nn=6;
+     304             :   const int mm=12;
+     305             :   const double preRes;
+     306             :   const double preDfunc;
+     307             :   const double preSecDev;
+     308             :   const int nnf;
+     309             :   const int mmf;
+     310             :   const double preDfuncF;
+     311             :   const double preSecDevF;
+     312             :   //I am using PLMD::epsilon to be certain to call the one defined in Tools.h
+     313             :   static constexpr double moreThanOne=1.0+5.0e10*PLMD::epsilon;
+     314             :   static constexpr double lessThanOne=1.0-5.0e10*PLMD::epsilon;
+     315             : 
+     316         165 :   std::string specificDescription() const override {
+     317         165 :     std::ostringstream ostr;
+     318         165 :     ostr << " nn=" << nn << " mm=" <<mm;
+     319         165 :     return ostr.str();
+     320         165 :   }
+     321             : public:
+     322         184 :   rational(double D0,double DMAX, double R0, int N, int M)
+     323             :     :baseSwitch(D0,DMAX,R0,"rational"),
+     324         184 :      nn(N),
+     325          89 :      mm([](int m,int n) {if (m==0) {return n*2;} else {return m;}}(M,N)),
+     326         184 :   preRes(static_cast<double>(nn)/mm),
+     327         184 :   preDfunc(0.5*nn*(nn-mm)/static_cast<double>(mm)),
+     328             :   //wolfram <3:lim_(x->1) d^2/(dx^2) (1 - x^N)/(1 - x^M) = (N (M^2 - 3 M (-1 + N) + N (-3 + 2 N)))/(6 M)
+     329         184 :   preSecDev ((nn * (mm * mm - 3.0* mm * (-1 + nn ) + nn *(-3 + 2* nn )))/(6.0* mm )),
+     330         184 :   nnf(nn/2),
+     331         184 :   mmf(mm/2),
+     332         184 :   preDfuncF(0.5*nnf*(nnf-mmf)/static_cast<double>(mmf)),
+     333         184 :   preSecDevF((nnf* (mmf*mmf - 3.0* mmf* (-1 + nnf) + nnf*(-3 + 2* nnf)))/(6.0* mmf)) {}
+     334             : 
+     335    18207295 :   static inline double doRational(const double rdist, double&dfunc,double secDev, const int N,
+     336             :                                   const int M,double result=0.0) {
+     337             :     //the result and dfunc are assigned in the drivers for doRational
+     338             :     //if(rdist>(1.0-100.0*epsilon) && rdist<(1.0+100.0*epsilon)) {
+     339             :     //result=preRes;
+     340             :     //dfunc=preDfunc;
+     341             :     //} else {
+     342             :     if constexpr (nis2m==rationalForm::simplified) {
+     343     2113979 :       const double rNdist=Tools::fastpow(rdist,N-1);
+     344     2113979 :       result=1.0/(1.0+rNdist*rdist);
+     345     2113979 :       dfunc = -N*rNdist*result*result;
+     346             :     } else {
+     347    16093316 :       if(!((rdist > lessThanOne) && (rdist < moreThanOne))) {
+     348    16093304 :         const double rNdist=Tools::fastpow(rdist,N-1);
+     349    16093304 :         const double rMdist=Tools::fastpow(rdist,M-1);
+     350    16093304 :         const double num = 1.0-rNdist*rdist;
+     351    16093304 :         const double iden = 1.0/(1.0-rMdist*rdist);
+     352    16093304 :         result = num*iden;
+     353    16093304 :         dfunc = ((M*result*rMdist)-(N*rNdist))*iden;
+     354    16093304 :       } else {
+     355             :         //here I imply that the correct initialized are being passed to doRational
+     356          12 :         const double x =(rdist-1.0);
+     357          12 :         result = result+ x * ( dfunc + 0.5 * x * secDev);
+     358          12 :         dfunc  = dfunc + x * secDev;
+     359             :       }
+     360             :     }
+     361    18207295 :     return result;
+     362             :   }
+     363    18207243 :   inline double function(double rdist,double&dfunc) const override {
+     364             :     //preRes and preDfunc are passed already set
+     365    18207243 :     dfunc=preDfunc;
+     366    18207243 :     double result = doRational(rdist,dfunc,preSecDev,nn,mm,preRes);
+     367    18207243 :     return result;
+     368             :   }
+     369             : 
+     370     3408359 :   double calculateSqr(double distance2,double&dfunc) const override {
+     371             :     if constexpr (isFast==rationalPow::fast) {
+     372             :       double result=0.0;
+     373          60 :       dfunc=0.0;
+     374          60 :       if(distance2 <= dmax_2) {
+     375          52 :         const double rdist = distance2*invr0_2;
+     376          52 :         dfunc=preDfuncF;
+     377          52 :         result = doRational(rdist,dfunc,preSecDevF,nnf,mmf,preRes);
+     378          52 :         dfunc*=2*invr0_2;
+     379             : // stretch:
+     380          52 :         result=result*stretch+shift;
+     381          52 :         dfunc*=stretch;
+     382             :       }
+     383          60 :       return result;
+     384             :     } else {
+     385     3408299 :       double res= calculate(std::sqrt(distance2),dfunc);//RVO!
+     386     3408299 :       return res;
+     387             :     }
+     388             :   }
+     389             : };
+     390             : 
+     391             : 
+     392             : template<int EXP,std::enable_if_t< (EXP %2 == 0), bool> = true>
+     393        1067 : std::optional<std::unique_ptr<baseSwitch>> fixedRationalFactory(double D0,double DMAX, double R0, int N) {
+     394             :   if constexpr (EXP == 0) {
+     395           0 :     return  std::nullopt;
+     396             :   } else {
+     397        1067 :     if (N==EXP) {
+     398         279 :       return PLMD::Tools::make_unique<switchContainers::fixedRational<EXP>>(D0,DMAX,R0);
+     399             :     } else {
+     400         788 :       return fixedRationalFactory<EXP-2>(D0,DMAX,R0,N);
+     401             :     }
+     402             :   }
+     403             : }
+     404             : 
+     405             : std::unique_ptr<baseSwitch>
+     406         463 : rationalFactory(double D0,double DMAX, double R0, int N, int M) {
+     407         463 :   bool fast = N%2==0 && M%2==0 && D0==0.0;
+     408             :   //if (M==0) M will automatically became 2*NN
+     409             :   constexpr int highestPrecompiledPower=12;
+     410             :   //precompiled rational
+     411         463 :   if(((2*N)==M || M == 0) && fast && N<=highestPrecompiledPower) {
+     412         279 :     auto tmp = fixedRationalFactory<highestPrecompiledPower>(D0,DMAX,R0,N);
+     413         279 :     if(tmp) {
+     414             :       return std::move(*tmp);
+     415             :     }
+     416             :     //else continue with the at runtime implementation
+     417             :   }
+     418             :   //template<bool isFast, bool n2m>
+     419             :   //class rational : public baseSwitch
+     420         184 :   if(2*N==M || M == 0) {
+     421         132 :     if(fast) {
+     422             :       //fast rational
+     423             :       return PLMD::Tools::make_unique<switchContainers::rational<
+     424           0 :              rationalPow::fast,rationalForm::simplified>>(D0,DMAX,R0,N,M);
+     425             :     }
+     426             :     return PLMD::Tools::make_unique<switchContainers::rational<
+     427         132 :            rationalPow::standard,rationalForm::simplified>>(D0,DMAX,R0,N,M);
+     428             :   }
+     429          52 :   if(fast) {
+     430             :     //fast rational
+     431             :     return PLMD::Tools::make_unique<switchContainers::rational<
+     432          49 :            rationalPow::fast,rationalForm::standard>>(D0,DMAX,R0,N,M);
+     433             :   }
+     434             :   return PLMD::Tools::make_unique<switchContainers::rational<
+     435           3 :          rationalPow::standard,rationalForm::standard>>(D0,DMAX,R0,N,M);
+     436             : }
+     437             : //function =
+     438             : 
+     439             : class exponentialSwitch: public baseSwitch {
+     440             : public:
+     441          75 :   exponentialSwitch(double D0, double DMAX, double R0)
+     442          75 :     :baseSwitch(D0,DMAX,R0,"exponential") {}
+     443             : protected:
+     444     2404247 :   inline double function(const double rdist,double&dfunc) const override {
+     445     2404247 :     double result = std::exp(-rdist);
+     446     2404247 :     dfunc=-result;
+     447     2404247 :     return result;
+     448             :   }
+     449             : };
+     450             : 
+     451             : class gaussianSwitch: public baseSwitch {
+     452             : public:
+     453          66 :   gaussianSwitch(double D0, double DMAX, double R0)
+     454          66 :     :baseSwitch(D0,DMAX,R0,"gaussian") {}
+     455             : protected:
+     456      279640 :   inline double function(const double rdist,double&dfunc) const override {
+     457      279640 :     double result = std::exp(-0.5*rdist*rdist);
+     458      279640 :     dfunc=-rdist*result;
+     459      279640 :     return result;
+     460             :   }
+     461             : };
+     462             : 
+     463             : class fastGaussianSwitch: public baseSwitch {
+     464             : public:
+     465         112 :   fastGaussianSwitch(double /*D0*/, double DMAX, double /*R0*/)
+     466         112 :     :baseSwitch(0.0,DMAX,1.0,"fastgaussian") {}
+     467             : protected:
+     468           1 :   inline double function(const double rdist,double&dfunc) const override {
+     469           1 :     double result = std::exp(-0.5*rdist*rdist);
+     470           1 :     dfunc=-rdist*result;
+     471           1 :     return result;
+     472             :   }
+     473    38317812 :   inline double calculateSqr(double distance2,double&dfunc) const override {
+     474             :     double result = 0.0;
+     475    38317812 :     if(distance2>dmax_2) {
+     476           8 :       dfunc=0.0;
+     477             :     } else  {
+     478    38317804 :       result = exp(-0.5*distance2);
+     479    38317804 :       dfunc = -result;
+     480             :       // stretch:
+     481    38317804 :       result=result*stretch+shift;
+     482    38317804 :       dfunc*=stretch;
+     483             :     }
+     484    38317812 :     return result;
+     485             :   }
+     486             : };
+     487             : 
+     488             : class smapSwitch: public baseSwitch {
+     489             :   const int a=0;
+     490             :   const int b=0;
+     491             :   const double c=0.0;
+     492             :   const double d=0.0;
+     493             : protected:
+     494          15 :   std::string specificDescription() const override {
+     495          15 :     std::ostringstream ostr;
+     496          15 :     ostr<<" a="<<a<<" b="<<b;
+     497          15 :     return ostr.str();
+     498          15 :   }
+     499             : public:
+     500          15 :   smapSwitch(double D0, double DMAX, double R0, int A, int B)
+     501          15 :     :baseSwitch(D0,DMAX,R0,"smap"),
+     502          15 :      a(A),
+     503          15 :      b(B),
+     504          15 :      c(std::pow(2., static_cast<double>(a)/static_cast<double>(b) ) - 1.0),
+     505          15 :      d(-static_cast<double>(b) / static_cast<double>(a)) {}
+     506             : protected:
+     507    21911326 :   inline double function(const double rdist,double&dfunc) const override {
+     508             : 
+     509    21911326 :     const double sx=c*Tools::fastpow( rdist, a );
+     510    21911326 :     double result=std::pow( 1.0 + sx, d );
+     511    21911326 :     dfunc=-b*sx/rdist*result/(1.0+sx);
+     512    21911326 :     return result;
+     513             :   }
+     514             : };
+     515             : 
+     516             : class cubicSwitch: public baseSwitch {
+     517             : protected:
+     518          14 :   std::string specificDescription() const override {
+     519          14 :     std::ostringstream ostr;
+     520          14 :     ostr<<" dmax="<<dmax;
+     521          14 :     return ostr.str();
+     522          14 :   }
+     523             : public:
+     524          14 :   cubicSwitch(double D0, double DMAX)
+     525          14 :     :baseSwitch(D0,DMAX,DMAX-D0,"cubic") {
+     526             :     //this operation should be already done!!
+     527             :     // R0 = dmax - d0;
+     528             :     // invr0 = 1/R0;
+     529             :     // invr0_2 = invr0*invr0;
+     530          14 :   }
+     531          14 :   ~cubicSwitch()=default;
+     532             : protected:
+     533      127255 :   inline double function(const double rdist,double&dfunc) const override {
+     534      127255 :     const double tmp1 = rdist - 1.0;
+     535      127255 :     const double tmp2 = 1.0+2.0*rdist;
+     536             :     //double result = tmp1*tmp1*tmp2;
+     537      127255 :     dfunc = 2*tmp1*tmp2 + 2*tmp1*tmp1;
+     538      127255 :     return tmp1*tmp1*tmp2;
+     539             :   }
+     540             : };
+     541             : 
+     542             : class tanhSwitch: public baseSwitch {
+     543             : public:
+     544           4 :   tanhSwitch(double D0, double DMAX, double R0)
+     545           4 :     :baseSwitch(D0,DMAX,R0,"tanh") {}
+     546             : protected:
+     547       12718 :   inline double function(const double rdist,double&dfunc) const override {
+     548       12718 :     const double tmp1 = std::tanh(rdist);
+     549             :     //was dfunc=-(1-tmp1*tmp1);
+     550       12718 :     dfunc = tmp1 * tmp1 - 1.0;
+     551             :     //return result;
+     552       12718 :     return 1.0 - tmp1;
+     553             :   }
+     554             : };
+     555             : 
+     556             : class cosinusSwitch: public baseSwitch {
+     557             : public:
+     558           3 :   cosinusSwitch(double D0, double DMAX, double R0)
+     559           3 :     :baseSwitch(D0,DMAX,R0,"cosinus") {}
+     560             : protected:
+     561      522111 :   inline double function(const double rdist,double&dfunc) const override {
+     562             :     double result = 0.0;
+     563      522111 :     dfunc=0.0;
+     564      522111 :     if(rdist<=1.0) {
+     565             : // rdist = (r-r1)/(r2-r1) ; 0.0<=rdist<=1.0 if r1 <= r <=r2; (r2-r1)/(r2-r1)=1
+     566      227012 :       double rdistPI = rdist * PLMD::pi;
+     567      227012 :       result = 0.5 * (std::cos ( rdistPI ) + 1.0);
+     568      227012 :       dfunc = -0.5 * PLMD::pi * std::sin ( rdistPI ) * invr0;
+     569             :     }
+     570      522111 :     return result;
+     571             :   }
+     572             : };
+     573             : 
+     574             : class nativeqSwitch: public baseSwitch {
+     575             :   double beta = 50.0;  // nm-1
+     576             :   double lambda = 1.8; // unitless
+     577             :   double ref=0.0;
+     578             : protected:
+     579         572 :   std::string specificDescription() const override {
+     580         572 :     std::ostringstream ostr;
+     581         572 :     ostr<<" beta="<<beta<<" lambda="<<lambda<<" ref="<<ref;
+     582         572 :     return ostr.str();
+     583         572 :   }
+     584           0 :   inline double function(const double rdist,double&dfunc) const override {return 0.0;  }
+     585             : public:
+     586             :   nativeqSwitch(double D0, double DMAX, double R0, double BETA, double LAMBDA,double REF)
+     587         572 :     :  baseSwitch(D0,DMAX,R0,"nativeq"),beta(BETA),lambda(LAMBDA),ref(REF) {}
+     588      146632 :   double calculate(const double distance, double& dfunc) const override {
+     589             :     double res = 0.0;//RVO!
+     590      146632 :     dfunc = 0.0;
+     591      146632 :     if(distance<=dmax) {
+     592             :       res = 1.0;
+     593      146624 :       if(distance > d0) {
+     594      146617 :         const double rdist = beta*(distance - lambda * ref);
+     595      146617 :         double exprdist=std::exp(rdist);
+     596      146617 :         res=1.0/(1.0+exprdist);
+     597             :         /*2.9
+     598             :         //need to see if this (5op+assign)
+     599             :         //double exprmdist=1.0 + exprdist;
+     600             :         //dfunc = - (beta *exprdist)/(exprmdist*exprmdist);
+     601             :         //or this (5op but 2 divisions) is faster
+     602             :         dfunc = - beta /(exprdist+ 2.0 +1.0/exprdist);
+     603             :         //this cames from - beta * exprdist/(exprdist*exprdist+ 2.0 *exprdist +1.0)
+     604             :         //dfunc *= invr0;
+     605             :         dfunc /= distance;
+     606             :         */
+     607             :         //2.10
+     608      146617 :         dfunc = - beta /(exprdist+ 2.0 +1.0/exprdist) /distance;
+     609             : 
+     610      146617 :         dfunc*=stretch;
+     611             :       }
+     612      146624 :       res=res*stretch+shift;
+     613             :     }
+     614      146632 :     return res;
+     615             :   }
+     616             : };
+     617             : 
+     618             : class leptonSwitch: public baseSwitch {
+     619             : /// Lepton expression.
+     620          62 :   class funcAndDeriv {
+     621             :     lepton::CompiledExpression expression;
+     622             :     lepton::CompiledExpression deriv;
+     623             :     double* varRef=nullptr;
+     624             :     double* varDevRef=nullptr;
+     625             :   public:
+     626          20 :     funcAndDeriv(const std::string &func) {
+     627          20 :       lepton::ParsedExpression pe=lepton::Parser::parse(func).optimize(lepton::Constants());
+     628          20 :       expression=pe.createCompiledExpression();
+     629          22 :       std::string arg="x";
+     630             : 
+     631             :       {
+     632          20 :         auto vars=expression.getVariables();
+     633          20 :         bool found_x=std::find(vars.begin(),vars.end(),"x")!=vars.end();
+     634          20 :         bool found_x2=std::find(vars.begin(),vars.end(),"x2")!=vars.end();
+     635             : 
+     636          20 :         if(found_x2) {
+     637             :           arg="x2";
+     638             :         }
+     639          20 :         if (vars.size()==0) {
+     640             : // this is necessary since in some cases lepton thinks a variable is not present even though it is present
+     641             : // e.g. func=0*x
+     642           0 :           varRef=nullptr;
+     643          20 :         } else if(vars.size()==1 && (found_x || found_x2)) {
+     644          18 :           varRef=&expression.getVariableReference(arg);
+     645             :         } else {
+     646           4 :           plumed_error()
+     647             :               <<"Please declare a function with only ONE argument that can only be x or x2. Your function is: "
+     648           4 :               << func;
+     649             :         }
+     650             :       }
+     651             : 
+     652          38 :       lepton::ParsedExpression ped=lepton::Parser::parse(func).differentiate(arg).optimize(lepton::Constants());
+     653          18 :       deriv=ped.createCompiledExpression();
+     654             :       {
+     655          18 :         auto vars=expression.getVariables();
+     656          18 :         if (vars.size()==0) {
+     657           0 :           varDevRef=nullptr;
+     658             :         } else {
+     659          18 :           varDevRef=&deriv.getVariableReference(arg);
+     660             :         }
+     661             :       }
+     662             : 
+     663          22 :     }
+     664          44 :     funcAndDeriv (const funcAndDeriv& other):
+     665          44 :       expression(other.expression),
+     666          44 :       deriv(other.deriv) {
+     667          44 :       std::string arg="x";
+     668             : 
+     669             :       {
+     670          44 :         auto vars=expression.getVariables();
+     671          44 :         bool found_x=std::find(vars.begin(),vars.end(),"x")!=vars.end();
+     672          44 :         bool found_x2=std::find(vars.begin(),vars.end(),"x2")!=vars.end();
+     673             : 
+     674          44 :         if(found_x2) {
+     675             :           arg="x2";
+     676             :         }
+     677          44 :         if (vars.size()==0) {
+     678           0 :           varRef=nullptr;
+     679          44 :         } else if(vars.size()==1 && (found_x || found_x2)) {
+     680          44 :           varRef=&expression.getVariableReference(arg);
+     681             :         }// UB: I assume that the function is already correct
+     682             :       }
+     683             : 
+     684             :       {
+     685          44 :         auto vars=expression.getVariables();
+     686          44 :         if (vars.size()==0) {
+     687           0 :           varDevRef=nullptr;
+     688             :         } else {
+     689          44 :           varDevRef=&deriv.getVariableReference(arg);
+     690             :         }
+     691             :       }
+     692          44 :     }
+     693             : 
+     694             :     funcAndDeriv& operator= (const funcAndDeriv& other) {
+     695             :       if(this != &other) {
+     696             :         expression = other.expression;
+     697             :         deriv = other.deriv;
+     698             :         std::string arg="x";
+     699             : 
+     700             :         {
+     701             :           auto vars=expression.getVariables();
+     702             :           bool found_x=std::find(vars.begin(),vars.end(),"x")!=vars.end();
+     703             :           bool found_x2=std::find(vars.begin(),vars.end(),"x2")!=vars.end();
+     704             : 
+     705             :           if(found_x2) {
+     706             :             arg="x2";
+     707             :           }
+     708             :           if (vars.size()==0) {
+     709             :             varRef=nullptr;
+     710             :           } else if(vars.size()==1 && (found_x || found_x2)) {
+     711             :             varRef=&expression.getVariableReference(arg);
+     712             :           }// UB: I assume that the function is already correct
+     713             :         }
+     714             : 
+     715             :         {
+     716             :           auto vars=expression.getVariables();
+     717             :           if (vars.size()==0) {
+     718             :             varDevRef=nullptr;
+     719             :           } else {
+     720             :             varDevRef=&deriv.getVariableReference(arg);
+     721             :           }
+     722             :         }
+     723             :       }
+     724             :       return *this;
+     725             :     }
+     726             : 
+     727     6515285 :     std::pair<double,double> operator()(double const x) const {
+     728             :       //FAQ: why this works? this thing is const and you are modifying things!
+     729             :       //Actually I am modifying something that is pointed at, not my pointers,
+     730             :       //so I am not mutating the state of this!
+     731     6515285 :       if(varRef) {
+     732     6515285 :         *varRef=x;
+     733             :       }
+     734     6515285 :       if(varDevRef) {
+     735     6515285 :         *varDevRef=x;
+     736             :       }
+     737             :       return std::make_pair(
+     738     6515285 :                expression.evaluate(),
+     739     6515285 :                deriv.evaluate());
+     740             :     }
+     741             : 
+     742             :     auto& getVariables() const {
+     743          18 :       return expression.getVariables();
+     744             :     }
+     745             :     auto& getVariables_derivative() const {
+     746             :       return deriv.getVariables();
+     747             :     }
+     748             :   };
+     749             :   /// Function for lepton
+     750             :   std::string lepton_func;
+     751             :   /// \warning Since lepton::CompiledExpression is mutable, a vector is necessary for multithreading!
+     752             :   std::vector <funcAndDeriv> expressions{};
+     753             :   /// Set to true if lepton only uses x2
+     754             :   bool leptonx2=false;
+     755             : protected:
+     756          18 :   std::string specificDescription() const override {
+     757          18 :     std::ostringstream ostr;
+     758          18 :     ostr<<" func=" << lepton_func;
+     759          18 :     return ostr.str();
+     760          18 :   }
+     761           0 :   inline double function(const double,double&) const override {return 0.0;}
+     762             : public:
+     763          20 :   leptonSwitch(double D0, double DMAX, double R0, const std::string & func)
+     764          20 :     :baseSwitch(D0,DMAX,R0,"lepton"),
+     765          20 :      lepton_func(func),
+     766          38 :      expressions  (OpenMP::getNumThreads(), lepton_func) {
+     767             :     //this is a bit odd, but it works
+     768             :     auto vars=expressions[0].getVariables();
+     769          18 :     leptonx2=std::find(vars.begin(),vars.end(),"x2")!=vars.end();
+     770          20 :   }
+     771             : 
+     772     5877796 :   double calculate(const double distance,double&dfunc) const override {
+     773     5877796 :     double res = 0.0;//RVO!
+     774     5877796 :     dfunc = 0.0;
+     775     5877796 :     if(leptonx2) {
+     776           2 :       res= calculateSqr(distance*distance,dfunc);
+     777             :     } else {
+     778     5877794 :       if(distance<=dmax) {
+     779     5573105 :         res = 1.0;
+     780     5573105 :         const double rdist = (distance-d0)*invr0;
+     781     5573105 :         if(rdist > 0.0) {
+     782     5267183 :           const unsigned t=OpenMP::getThreadNum();
+     783     5267183 :           plumed_assert(t<expressions.size());
+     784     5267183 :           std::tie(res,dfunc) = expressions[t](rdist);
+     785     5267183 :           dfunc *= invr0;
+     786     5267183 :           dfunc /= distance;
+     787             :         }
+     788     5573105 :         res=res*stretch+shift;
+     789     5573105 :         dfunc*=stretch;
+     790             :       }
+     791             :     }
+     792     5877796 :     return res;
+     793             :   }
+     794             : 
+     795     7125890 :   double calculateSqr(const double distance2,double&dfunc) const override {
+     796     7125890 :     double result =0.0;
+     797     7125890 :     dfunc=0.0;
+     798     7125890 :     if(leptonx2) {
+     799     1248110 :       if(distance2<=dmax_2) {
+     800     1248102 :         const unsigned t=OpenMP::getThreadNum();
+     801     1248102 :         const double rdist_2 = distance2*invr0_2;
+     802     1248102 :         plumed_assert(t<expressions.size());
+     803     1248102 :         std::tie(result,dfunc) = expressions[t](rdist_2);
+     804             :         // chain rule:
+     805     1248102 :         dfunc*=2*invr0_2;
+     806             :         // stretch:
+     807     1248102 :         result=result*stretch+shift;
+     808     1248102 :         dfunc*=stretch;
+     809             :       }
+     810             :     } else {
+     811     5877780 :       result = calculate(std::sqrt(distance2),dfunc);
+     812             :     }
+     813     7125890 :     return result;
+     814             :   }
+     815             : };
+     816             : } // namespace switchContainers
+     817             : 
+     818           0 : void SwitchingFunction::registerKeywords( Keywords& keys ) {
+     819           0 :   keys.add("compulsory","R_0","the value of R_0 in the switching function");
+     820           0 :   keys.add("compulsory","D_0","0.0","the value of D_0 in the switching function");
+     821           0 :   keys.add("optional","D_MAX","the value at which the switching function can be assumed equal to zero");
+     822           0 :   keys.add("compulsory","NN","6","the value of n in the switching function (only needed for TYPE=RATIONAL)");
+     823           0 :   keys.add("compulsory","MM","0","the value of m in the switching function (only needed for TYPE=RATIONAL); 0 implies 2*NN");
+     824           0 :   keys.add("compulsory","A","the value of a in the switching function (only needed for TYPE=SMAP)");
+     825           0 :   keys.add("compulsory","B","the value of b in the switching function (only needed for TYPE=SMAP)");
+     826           0 : }
+     827             : 
+     828        1271 : void SwitchingFunction::set(const std::string & definition,std::string& errormsg) {
+     829        1271 :   std::vector<std::string> data=Tools::getWords(definition);
+     830             : #define CHECKandPARSE(datastring,keyword,variable,errormsg) \
+     831             :   if(Tools::findKeyword(datastring,keyword) && !Tools::parse(datastring,keyword,variable))\
+     832             :     errormsg="could not parse " keyword; //adiacent strings are automagically concatenated
+     833             : #define REQUIREDPARSE(datastring,keyword,variable,errormsg) \
+     834             :   if(!Tools::parse(datastring,keyword,variable))\
+     835             :     errormsg=keyword " is required for " + name ; //adiacent strings are automagically concatenated
+     836             : 
+     837        1271 :   if( data.size()<1 ) {
+     838             :     errormsg="missing all input for switching function";
+     839             :     return;
+     840             :   }
+     841        1271 :   std::string name=data[0];
+     842             :   data.erase(data.begin());
+     843        1271 :   double r0=0.0;
+     844        1271 :   double d0=0.0;
+     845        1271 :   double dmax=std::numeric_limits<double>::max();
+     846        1271 :   init=true;
+     847        1697 :   CHECKandPARSE(data,"D_0",d0,errormsg);
+     848        1609 :   CHECKandPARSE(data,"D_MAX",dmax,errormsg);
+     849             : 
+     850        1271 :   bool dostretch=false;
+     851        1271 :   Tools::parseFlag(data,"STRETCH",dostretch); // this is ignored now
+     852        1271 :   dostretch=true;
+     853        1271 :   bool dontstretch=false;
+     854        1271 :   Tools::parseFlag(data,"NOSTRETCH",dontstretch); // this is ignored now
+     855        1271 :   if(dontstretch)
+     856         161 :     dostretch=false;
+     857        1271 :   if(name=="CUBIC") {
+     858             :     //cubic is the only switch type that only uses d0 and dmax
+     859          14 :     function = PLMD::Tools::make_unique<switchContainers::cubicSwitch>(d0,dmax);
+     860             :   } else {
+     861        2514 :     REQUIREDPARSE(data,"R_0",r0,errormsg);
+     862        1257 :     if(name=="RATIONAL") {
+     863         389 :       int nn=6;
+     864         389 :       int mm=0;
+     865         621 :       CHECKandPARSE(data,"NN",nn,errormsg);
+     866         615 :       CHECKandPARSE(data,"MM",mm,errormsg);
+     867         778 :       function = switchContainers::rationalFactory(d0,dmax,r0,nn,mm);
+     868         868 :     } else if(name=="SMAP") {
+     869          15 :       int a=0;
+     870          15 :       int b=0;
+     871             :       //in the original a and b are "default=0",
+     872             :       //but you divide by a and b during the initialization!
+     873             :       //better an error message than an UB, so no default
+     874          30 :       REQUIREDPARSE(data,"A",a,errormsg);
+     875          30 :       REQUIREDPARSE(data,"B",b,errormsg);
+     876          15 :       function = PLMD::Tools::make_unique<switchContainers::smapSwitch>(d0,dmax,r0,a,b);
+     877         853 :     } else if(name=="Q") {
+     878         572 :       double beta = 50.0;  // nm-1
+     879         572 :       double lambda = 1.8; // unitless
+     880             :       double ref;
+     881        1716 :       CHECKandPARSE(data,"BETA",beta,errormsg);
+     882        1716 :       CHECKandPARSE(data,"LAMBDA",lambda,errormsg);
+     883        1144 :       REQUIREDPARSE(data,"REF",ref,errormsg);
+     884             :       //the original error message was not standard
+     885             :       // if(!Tools::parse(data,"REF",ref))
+     886             :       //   errormsg="REF (reference distaance) is required for native Q";
+     887         572 :       function = PLMD::Tools::make_unique<switchContainers::nativeqSwitch>(d0,dmax,r0,beta,lambda,ref);
+     888         281 :     } else if(name=="EXP") {
+     889          75 :       function = PLMD::Tools::make_unique<switchContainers::exponentialSwitch>(d0,dmax,r0);
+     890         206 :     } else if(name=="GAUSSIAN") {
+     891         178 :       if ( r0==1.0 && d0==0.0 ) {
+     892         112 :         function = PLMD::Tools::make_unique<switchContainers::fastGaussianSwitch>(d0,dmax,r0);
+     893             :       } else {
+     894          66 :         function = PLMD::Tools::make_unique<switchContainers::gaussianSwitch>(d0,dmax,r0);
+     895             :       }
+     896          28 :     } else if(name=="TANH") {
+     897           4 :       function = PLMD::Tools::make_unique<switchContainers::tanhSwitch>(d0,dmax,r0);
+     898          24 :     } else if(name=="COSINUS") {
+     899           3 :       function = PLMD::Tools::make_unique<switchContainers::cosinusSwitch>(d0,dmax,r0);
+     900          39 :     } else if((name=="MATHEVAL" || name=="CUSTOM")) {
+     901             :       std::string func;
+     902          40 :       Tools::parse(data,"FUNC",func);
+     903          18 :       function = PLMD::Tools::make_unique<switchContainers::leptonSwitch>(d0,dmax,r0,func);
+     904             :     } else {
+     905           2 :       errormsg="cannot understand switching function type '"+name+"'";
+     906             :     }
+     907             :   }
+     908             : #undef CHECKandPARSE
+     909             : #undef REQUIREDPARSE
+     910             : 
+     911        1269 :   if( !data.empty() ) {
+     912             :     errormsg="found the following rogue keywords in switching function input : ";
+     913           2 :     for(unsigned i=0; i<data.size(); ++i) errormsg = errormsg + data[i] + " ";
+     914             :   }
+     915             : 
+     916        1269 :   if(dostretch && dmax!=std::numeric_limits<double>::max()) {
+     917         141 :     function->setupStretch();
+     918             :   }
+     919        1271 : }
+     920             : 
+     921        1194 : std::string SwitchingFunction::description() const {
+     922             :   // if this error is necessary, something went wrong in the constructor
+     923             :   //  plumed_merror("Unknown switching function type");
+     924        1194 :   return function->description();
+     925             : }
+     926             : 
+     927    92146473 : double SwitchingFunction::calculateSqr(double distance2,double&dfunc)const {
+     928    92146473 :   return function -> calculateSqr(distance2, dfunc);
+     929             : }
+     930             : 
+     931   127719055 : double SwitchingFunction::calculate(double distance,double&dfunc)const {
+     932   127719055 :   plumed_massert(init,"you are trying to use an unset SwitchingFunction");
+     933   127719055 :   double result=function->calculate(distance,dfunc);
+     934   127719055 :   return result;
+     935             : }
+     936             : 
+     937          74 : void SwitchingFunction::set(const int nn,int mm, const double r0, const double d0) {
+     938          74 :   init=true;
+     939          74 :   if(mm == 0) {
+     940          70 :     mm = 2*nn;
+     941             :   }
+     942          74 :   double dmax=d0+r0*std::pow(0.00001,1./(nn-mm));
+     943         148 :   function = switchContainers::rationalFactory(d0,dmax,r0,nn,mm);
+     944          74 :   function->setupStretch();
+     945          74 : }
+     946             : 
+     947          32 : double SwitchingFunction::get_r0() const {
+     948          32 :   return function->get_r0();
+     949             : }
+     950             : 
+     951           8 : double SwitchingFunction::get_d0() const {
+     952           8 :   return function->get_d0();
+     953             : }
+     954             : 
+     955   536580540 : double SwitchingFunction::get_dmax() const {
+     956   536580540 :   return function->get_dmax();
+     957             : }
+     958             : 
+     959    49030642 : double SwitchingFunction::get_dmax2() const {
+     960    49030642 :   return function->get_dmax2();
+     961             : }
+     962             : 
+     963             : }// Namespace PLMD
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/SwitchingFunction.h.func-sort-c.html b/coverage/tools/SwitchingFunction.h.func-sort-c.html new file mode 100644 index 000000000000..1245cceb26ff --- /dev/null +++ b/coverage/tools/SwitchingFunction.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage - tools/SwitchingFunction.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - SwitchingFunction.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-04-19 12:12:35Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/SwitchingFunction.h.func.html b/coverage/tools/SwitchingFunction.h.func.html new file mode 100644 index 000000000000..06f9a3bf42b1 --- /dev/null +++ b/coverage/tools/SwitchingFunction.h.func.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage - tools/SwitchingFunction.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - SwitchingFunction.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-04-19 12:12:35Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/SwitchingFunction.h.gcov.html b/coverage/tools/SwitchingFunction.h.gcov.html new file mode 100644 index 000000000000..d0ba9c4f8967 --- /dev/null +++ b/coverage/tools/SwitchingFunction.h.gcov.html @@ -0,0 +1,195 @@ + + + + + + + + LCOV - plumed test coverage - tools/SwitchingFunction.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - SwitchingFunction.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-04-19 12:12:35Functions: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_SwitchingFunction_h
+      23             : #define __PLUMED_tools_SwitchingFunction_h
+      24             : 
+      25             : #include <string>
+      26             : #include <vector>
+      27             : #include <memory>
+      28             : #include "lepton/Lepton.h"
+      29             : 
+      30             : namespace PLMD {
+      31             : 
+      32             : class Log;
+      33             : class Keywords;
+      34             : namespace switchContainers {
+      35             : /// container for the actual switching function used by PLMD::SwitchingFunction
+      36             : class baseSwitch {
+      37             : protected:
+      38             :   /// Minimum distance (before this, function is one)
+      39             :   double d0=0.0;
+      40             :   /// Maximum distance (after this, function is zero)
+      41             :   double dmax=0.0;
+      42             :   /// Square of dmax, useful in calculateSqr()
+      43             :   double dmax_2=0.0;
+      44             :   /// We store the inverse to avoid a division
+      45             :   double invr0=0.0;
+      46             :   /// Square of invr0, useful in calculateSqr()
+      47             :   double invr0_2=0.0;
+      48             :   /// Parameters for stretching the function to zero at d_max
+      49             :   double stretch=1.0;
+      50             :   double shift=0.0;
+      51             :   std::string mytype;
+      52             :   virtual std::string specificDescription() const;
+      53             :   //
+      54             :   virtual double function(double rdist, double& dfunc) const=0;
+      55             : public:
+      56             :   baseSwitch(double D0,double DMAX, double R0, std::string_view name);
+      57             :   virtual ~baseSwitch();
+      58             :   ///the driver for the function (prepares rdist or returns 1 or 0 automatically)
+      59             :   virtual double calculate(double distance, double& dfunc) const;
+      60             :   virtual double calculateSqr(double distance2, double& dfunc) const;
+      61             :   void setupStretch();
+      62             :   void removeStretch();
+      63             :   std::string description() const;
+      64             :   double get_d0() const;
+      65             :   double get_r0() const;
+      66             :   double get_dmax() const;
+      67             :   double get_dmax2() const;
+      68             : };
+      69             : } // namespace switchContainers
+      70             : 
+      71             : /// \ingroup TOOLBOX
+      72             : /// Small class to compute switching functions.
+      73             : /// Switching functions are created using set() and
+      74             : /// then can be used with function calculate() or calculateSqr().
+      75             : /// Since this is typically computed on a distance vector,
+      76             : /// the second all (calculateSqr()) allows to skip the calculation
+      77             : /// of a square root in some case, thus potentially increasing
+      78             : /// performances.
+      79        1884 : class SwitchingFunction {
+      80             : /// This is to check that switching function has been initialized
+      81             :   bool init=false;
+      82             :   std::unique_ptr<switchContainers::baseSwitch> function;
+      83             : public:
+      84             :   static void registerKeywords( Keywords& keys );
+      85             : /// Set a "rational" switching function.
+      86             : /// Notice that a d_max is set automatically to a value such that
+      87             : /// f(d_max)=0.00001.
+      88             :   void set(int nn,int mm,double r_0,double d_0);
+      89             : /// Set an arbitrary switching function.
+      90             : /// Parse the string in definition and possibly returns errors
+      91             : /// in the errormsg string
+      92             :   void set(const std::string& definition, std::string& errormsg);
+      93             : /// Returns a string with a description of the switching function
+      94             :   std::string description() const ;
+      95             : /// Compute the switching function.
+      96             : /// Returns s(x). df will be set to the value of the derivative
+      97             : /// of the switching function _divided_by_x
+      98             :   double calculate(double x,double&df)const;
+      99             : /// Compute the switching function.
+     100             : /// Returns \f$ s(\sqrt{x})\f$ .
+     101             : /// df will be set to the \f$ \frac{1}{\sqrt{x}}\frac{ds}{d\sqrt{x}}= 2 \frac{ds}{dx}\f$
+     102             : /// (same as calculate()).
+     103             : /// The advantage is that in some case the expensive square root can be avoided
+     104             : /// (namely for rational functions, if nn and mm are even and d0 is zero)
+     105             :   double calculateSqr(double distance2,double&dfunc)const;
+     106             : /// Returns d0
+     107             :   double get_d0() const;
+     108             : /// Returns r0
+     109             :   double get_r0() const;
+     110             : /// Return dmax
+     111             :   double get_dmax() const;
+     112             : /// Return dmax squared
+     113             :   double get_dmax2() const;
+     114             : };
+     115             : 
+     116             : } //namespace PLMD
+     117             : 
+     118             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Tensor.cpp.func-sort-c.html b/coverage/tools/Tensor.cpp.func-sort-c.html new file mode 100644 index 000000000000..b17eef00dda1 --- /dev/null +++ b/coverage/tools/Tensor.cpp.func-sort-c.html @@ -0,0 +1,77 @@ + + + + + + + + LCOV - plumed test coverage - tools/Tensor.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Tensor.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:33100.0 %
Date:2024-04-19 12:12:35Functions: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_605565
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Tensor.cpp.func.html b/coverage/tools/Tensor.cpp.func.html new file mode 100644 index 000000000000..c3d2325e0332 --- /dev/null +++ b/coverage/tools/Tensor.cpp.func.html @@ -0,0 +1,77 @@ + + + + + + + + LCOV - plumed test coverage - tools/Tensor.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Tensor.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:33100.0 %
Date:2024-04-19 12:12:35Functions: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_605565
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Tensor.cpp.gcov.html b/coverage/tools/Tensor.cpp.gcov.html new file mode 100644 index 000000000000..57c097e21c6b --- /dev/null +++ b/coverage/tools/Tensor.cpp.gcov.html @@ -0,0 +1,116 @@ + + + + + + + + LCOV - plumed test coverage - tools/Tensor.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Tensor.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:33100.0 %
Date:2024-04-19 12:12:35Functions: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      605565 : 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      605565 :   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      605565 : }
+      36             : 
+      37             : 
+      38             : }
+      39             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Tensor.h.func-sort-c.html b/coverage/tools/Tensor.h.func-sort-c.html new file mode 100644 index 000000000000..a365a89a7e6e --- /dev/null +++ b/coverage/tools/Tensor.h.func-sort-c.html @@ -0,0 +1,349 @@ + + + + + + + + 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-04-19 12:12:35Functions:586984.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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
_ZN4PLMD10diagMatSymILj3ELj3EEEvRKNS_13TensorGenericIXT_EXT_EEERNS_13VectorGenericIXT0_EEERNS1_IXT0_EXT_EEE466
_ZN4PLMDdvILj3ELj3EEENS_13TensorGenericIXT_EXT0_EEERKS2_d37363
_ZN4PLMD12VcrossTensorERKNS_13TensorGenericILj3ELj3EEERKNS_13VectorGenericILj3EEE48138
_ZN4PLMD8deriNormERKNS_13VectorGenericILj3EEERKNS_13TensorGenericILj3ELj3EEE48138
_ZN4PLMD10diagMatSymILj4ELj4EEEvRKNS_13TensorGenericIXT_EXT_EEERNS_13VectorGenericIXT0_EEERNS1_IXT0_EXT_EEE58770
_ZN4PLMD13TensorGenericILj3ELj3EE6setColEjRKNS_13VectorGenericILj3EEE79542
_ZNK4PLMD13TensorGenericILj3ELj3EE6getColEj109170
_ZN4PLMD12VcrossTensorERKNS_13VectorGenericILj3EEERKNS_13TensorGenericILj3ELj3EEE144414
_ZNK4PLMD13TensorGenericILj3ELj3EEpsEv177717
_ZNK4PLMD13TensorGenericILj3ELj3EE7inverseEv177725
_ZNK4PLMD13TensorGenericILj3ELj3EEngEv250599
_ZNK4PLMD13TensorGenericILj3ELj3EE11determinantEv271228
_ZN4PLMD6matmulILj3ELj3ELj3EEENS_13VectorGenericIXT_EEERKNS_13TensorGenericIXT_EXT0_EEERKNS3_IXT0_EXT1_EEERKNS1_IXT1_EEE359586
_ZN4PLMD6matmulILj3ELj4EEENS_13VectorGenericIXT_EEERKNS1_IXT0_EEERKNS_13TensorGenericIXT0_EXT_EEE384894
_ZN4PLMD10diagMatSymILj4ELj1EEEvRKNS_13TensorGenericIXT_EXT_EEERNS_13VectorGenericIXT0_EEERNS1_IXT0_EXT_EEE546326
_ZN4PLMD13TensorGenericILj1ELj4EEC2Ev546326
_ZN4PLMD9transposeILj3ELj3EEENS_13TensorGenericIXT_EXT0_EEERKNS1_IXT0_EXT_EEE857817
_ZN4PLMD13TensorGenericILj3ELj3EE4zeroEv902516
_ZN4PLMD13TensorGenericILj4ELj3EE6setRowEjRKNS_13VectorGenericILj3EEE1291728
_ZN4PLMD13TensorGenericILj4ELj4EEC2Ev1471790
_ZN4PLMD13TensorGenericILj3ELj3EE6setRowEjRKNS_13VectorGenericILj3EEE1783260
_ZN4PLMDmiILj3ELj3EEENS_13TensorGenericIXT_EXT0_EEERKS2_S4_1820362
_ZN4PLMD10extProductILj3ELj3EEENS_13TensorGenericIXT_EXT0_EEERKNS_13VectorGenericIXT_EEERKNS3_IXT0_EEE2610172
_ZN4PLMDplILj3ELj3EEENS_13TensorGenericIXT_EXT0_EEERKS2_S4_2930657
_ZNK4PLMD13TensorGenericILj3ELj3EE6getRowEj3535515
_ZN4PLMD13TensorGenericILj4ELj3EEclEjj3875184
_ZN4PLMD13TensorGenericILj1ELj4EEclEjj4152794
_ZNK4PLMD13TensorGenericILj4ELj3EEclEjj4618728
_ZNK4PLMD13TensorGenericILj3ELj3EE9transposeEv4873009
_ZN4PLMD9dcrossDv1ERKNS_13VectorGenericILj3EEES3_5176287
_ZN4PLMD6matmulILj3ELj3ELj3EEENS_13TensorGenericIXT_EXT1_EEERKNS1_IXT_EXT0_EEERKNS1_IXT0_EXT1_EEE5606979
_ZN4PLMD9dcrossDv2ERKNS_13VectorGenericILj3EEES3_5753943
_ZN4PLMD13TensorGenericILj4ELj3EEC2Ev10253394
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJEEEvdDpT_11518026
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJdEEEvdDpT_11518026
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJddEEEvdDpT_11518026
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJdddEEEvdDpT_11518026
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJddddEEEvdDpT_11518026
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJdddddEEEvdDpT_11518026
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJddddddEEEvdDpT_11518026
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJdddddddEEEvdDpT_11518026
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJddddddddEEEvdDpT_11518026
_ZN4PLMD13TensorGenericILj3ELj3EEC2IJddddddddEEEdDpT_11518026
_ZNK4PLMD13TensorGenericILj4ELj4EE6getColEj12203712
_ZN4PLMD13TensorGenericILj3ELj3EE8identityEv13274080
_ZN4PLMD13TensorGenericILj3ELj3EEC2Ev46865450
_ZNK4PLMD13TensorGenericILj4ELj4EEclEjj48814848
_ZN4PLMD13TensorGenericILj3ELj3EEmIERKS1_49150794
_ZN4PLMDmlILj3ELj3EEENS_13TensorGenericIXT_EXT0_EEEdRKS2_54513062
_ZN4PLMD13TensorGenericILj3ELj3EEpLERKS1_54927498
_ZN4PLMD6matmulILj3ELj3EEENS_13VectorGenericIXT_EEERKNS_13TensorGenericIXT_EXT0_EEERKNS1_IXT0_EEE60081015
_ZN4PLMD13TensorGenericILj4ELj4EEclEjj60972703
_ZN4PLMDmlILj3ELj3EEENS_13TensorGenericIXT_EXT0_EEERKS2_d79559638
_ZN4PLMD13TensorGenericILj3ELj3EEmLEd79564663
_ZN4PLMD13TensorGenericILj3ELj3EEC2ERKNS_13VectorGenericILj3EEES5_99115277
_ZN4PLMD6matmulILj3ELj3EEENS_13VectorGenericIXT_EEERKNS1_IXT0_EEERKNS_13TensorGenericIXT0_EXT_EEE107284997
_ZN4PLMD13TensorGenericILj3ELj3EEclEjj281009435
_ZNK4PLMD13TensorGenericILj3ELj3EEclEjj4993637846
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Tensor.h.func.html b/coverage/tools/Tensor.h.func.html new file mode 100644 index 000000000000..a280f462dd6d --- /dev/null +++ b/coverage/tools/Tensor.h.func.html @@ -0,0 +1,349 @@ + + + + + + + + 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-04-19 12:12:35Functions:586984.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10diagMatSymILj3ELj3EEEvRKNS_13TensorGenericIXT_EXT_EEERNS_13VectorGenericIXT0_EEERNS1_IXT0_EXT_EEE466
_ZN4PLMD10diagMatSymILj4ELj1EEEvRKNS_13TensorGenericIXT_EXT_EEERNS_13VectorGenericIXT0_EEERNS1_IXT0_EXT_EEE546326
_ZN4PLMD10diagMatSymILj4ELj4EEEvRKNS_13TensorGenericIXT_EXT_EEERNS_13VectorGenericIXT0_EEERNS1_IXT0_EXT_EEE58770
_ZN4PLMD10extProductILj3ELj3EEENS_13TensorGenericIXT_EXT0_EEERKNS_13VectorGenericIXT_EEERKNS3_IXT0_EEE2610172
_ZN4PLMD12VcrossTensorERKNS_13TensorGenericILj3ELj3EEERKNS_13VectorGenericILj3EEE48138
_ZN4PLMD12VcrossTensorERKNS_13VectorGenericILj3EEERKNS_13TensorGenericILj3ELj3EEE144414
_ZN4PLMD13TensorGenericILj1ELj4EEC2Ev546326
_ZN4PLMD13TensorGenericILj1ELj4EEclEjj4152794
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJEEEvdDpT_11518026
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJdEEEvdDpT_11518026
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJddEEEvdDpT_11518026
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJdddEEEvdDpT_11518026
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJddddEEEvdDpT_11518026
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJdddddEEEvdDpT_11518026
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJddddddEEEvdDpT_11518026
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJdddddddEEEvdDpT_11518026
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJddddddddEEEvdDpT_11518026
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJfEEEvdDpT_0
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJffEEEvdDpT_0
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJfffEEEvdDpT_0
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJffffEEEvdDpT_0
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJfffffEEEvdDpT_0
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJffffffEEEvdDpT_0
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJfffffffEEEvdDpT_0
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJffffffffEEEvdDpT_0
_ZN4PLMD13TensorGenericILj3ELj3EE4zeroEv902516
_ZN4PLMD13TensorGenericILj3ELj3EE6setColEjRKNS_13VectorGenericILj3EEE79542
_ZN4PLMD13TensorGenericILj3ELj3EE6setRowEjRKNS_13VectorGenericILj3EEE1783260
_ZN4PLMD13TensorGenericILj3ELj3EE8identityEv13274080
_ZN4PLMD13TensorGenericILj3ELj3EEC2ERKNS_13VectorGenericILj3EEES5_99115277
_ZN4PLMD13TensorGenericILj3ELj3EEC2Ev46865450
_ZN4PLMD13TensorGenericILj3ELj3EEC2IJddddddddEEEdDpT_11518026
_ZN4PLMD13TensorGenericILj3ELj3EEC2IJffffffffEEEdDpT_0
_ZN4PLMD13TensorGenericILj3ELj3EEclEjj281009435
_ZN4PLMD13TensorGenericILj3ELj3EEmIERKS1_49150794
_ZN4PLMD13TensorGenericILj3ELj3EEmLEd79564663
_ZN4PLMD13TensorGenericILj3ELj3EEpLERKS1_54927498
_ZN4PLMD13TensorGenericILj4ELj3EE6setRowEjRKNS_13VectorGenericILj3EEE1291728
_ZN4PLMD13TensorGenericILj4ELj3EEC2Ev10253394
_ZN4PLMD13TensorGenericILj4ELj3EEclEjj3875184
_ZN4PLMD13TensorGenericILj4ELj4EEC2Ev1471790
_ZN4PLMD13TensorGenericILj4ELj4EEclEjj60972703
_ZN4PLMD6matmulILj3ELj3EEENS_13VectorGenericIXT_EEERKNS1_IXT0_EEERKNS_13TensorGenericIXT0_EXT_EEE107284997
_ZN4PLMD6matmulILj3ELj3EEENS_13VectorGenericIXT_EEERKNS_13TensorGenericIXT_EXT0_EEERKNS1_IXT0_EEE60081015
_ZN4PLMD6matmulILj3ELj3ELj3EEENS_13TensorGenericIXT_EXT1_EEERKNS1_IXT_EXT0_EEERKNS1_IXT0_EXT1_EEE5606979
_ZN4PLMD6matmulILj3ELj3ELj3EEENS_13VectorGenericIXT_EEERKNS_13TensorGenericIXT_EXT0_EEERKNS3_IXT0_EXT1_EEERKNS1_IXT1_EEE359586
_ZN4PLMD6matmulILj3ELj4EEENS_13VectorGenericIXT_EEERKNS1_IXT0_EEERKNS_13TensorGenericIXT0_EXT_EEE384894
_ZN4PLMD8deriNormERKNS_13VectorGenericILj3EEERKNS_13TensorGenericILj3ELj3EEE48138
_ZN4PLMD9dcrossDv1ERKNS_13VectorGenericILj3EEES3_5176287
_ZN4PLMD9dcrossDv2ERKNS_13VectorGenericILj3EEES3_5753943
_ZN4PLMD9transposeILj3ELj3EEENS_13TensorGenericIXT_EXT0_EEERKNS1_IXT0_EXT_EEE857817
_ZN4PLMDdvILj3ELj3EEENS_13TensorGenericIXT_EXT0_EEERKS2_d37363
_ZN4PLMDlsILj3ELj3EEERSoS1_RKNS_13TensorGenericIXT_EXT0_EEE0
_ZN4PLMDlsILj4ELj4EEERSoS1_RKNS_13TensorGenericIXT_EXT0_EEE0
_ZN4PLMDmiILj3ELj3EEENS_13TensorGenericIXT_EXT0_EEERKS2_S4_1820362
_ZN4PLMDmlILj3ELj3EEENS_13TensorGenericIXT_EXT0_EEERKS2_d79559638
_ZN4PLMDmlILj3ELj3EEENS_13TensorGenericIXT_EXT0_EEEdRKS2_54513062
_ZN4PLMDplILj3ELj3EEENS_13TensorGenericIXT_EXT0_EEERKS2_S4_2930657
_ZNK4PLMD13TensorGenericILj3ELj3EE11determinantEv271228
_ZNK4PLMD13TensorGenericILj3ELj3EE6getColEj109170
_ZNK4PLMD13TensorGenericILj3ELj3EE6getRowEj3535515
_ZNK4PLMD13TensorGenericILj3ELj3EE7inverseEv177725
_ZNK4PLMD13TensorGenericILj3ELj3EE9transposeEv4873009
_ZNK4PLMD13TensorGenericILj3ELj3EEclEjj4993637846
_ZNK4PLMD13TensorGenericILj3ELj3EEngEv250599
_ZNK4PLMD13TensorGenericILj3ELj3EEpsEv177717
_ZNK4PLMD13TensorGenericILj4ELj3EEclEjj4618728
_ZNK4PLMD13TensorGenericILj4ELj4EE6getColEj12203712
_ZNK4PLMD13TensorGenericILj4ELj4EEclEjj48814848
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Tensor.h.gcov.html b/coverage/tools/Tensor.h.gcov.html new file mode 100644 index 000000000000..dd702baee4ec --- /dev/null +++ b/coverage/tools/Tensor.h.gcov.html @@ -0,0 +1,651 @@ + + + + + + + + LCOV - plumed test coverage - tools/Tensor.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Tensor.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:14615196.7 %
Date:2024-04-19 12:12:35Functions:586984.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_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   103662234 : void TensorGeneric<n,m>::auxiliaryConstructor(double first,Args... arg)
+     216             : {
+     217   103662234 :   d[n*m-(sizeof...(Args))-1]=first;
+     218    92144208 :   auxiliaryConstructor(arg...);
+     219   103662234 : }
+     220             : 
+     221             : template <unsigned n,unsigned m>
+     222             : template<typename... Args>
+     223    11518026 : 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    11518026 :   auxiliaryConstructor(first,arg...);
+     227    11518026 : }
+     228             : 
+     229             : template<unsigned n,unsigned m>
+     230    59136960 : TensorGeneric<n,m>::TensorGeneric() {
+     231    59136960 :   LoopUnroller<n*m>::_zero(d.data());
+     232    59136960 : }
+     233             : 
+     234             : template<unsigned n,unsigned m>
+     235    99115277 : TensorGeneric<n,m>::TensorGeneric(const VectorGeneric<n>&v1,const VectorGeneric<m>&v2) {
+     236  1288498601 :   for(unsigned i=0; i<n; i++)for(unsigned j=0; j<m; j++)d[i*m+j]=v1[i]*v2[j];
+     237    99115277 : }
+     238             : 
+     239             : template<unsigned n,unsigned m>
+     240      902516 : void TensorGeneric<n,m>::zero() {
+     241      902516 :   LoopUnroller<n*m>::_zero(d.data());
+     242      902516 : }
+     243             : 
+     244             : template<unsigned n,unsigned m>
+     245   350010116 : 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   350010116 :   return d[m*i+j];
+     251             : }
+     252             : 
+     253             : template<unsigned n,unsigned m>
+     254  5047071422 : 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  5047071422 :   return d[m*i+j];
+     260             : }
+     261             : 
+     262             : template<unsigned n,unsigned m>
+     263    54927498 : TensorGeneric<n,m>& TensorGeneric<n,m>::operator +=(const TensorGeneric<n,m>& b) {
+     264    54927498 :   LoopUnroller<n*m>::_add(d.data(),b.d.data());
+     265    54927498 :   return *this;
+     266             : }
+     267             : 
+     268             : template<unsigned n,unsigned m>
+     269    49150794 : TensorGeneric<n,m>& TensorGeneric<n,m>::operator -=(const TensorGeneric<n,m>& b) {
+     270    49150794 :   LoopUnroller<n*m>::_sub(d.data(),b.d.data());
+     271    49150794 :   return *this;
+     272             : }
+     273             : 
+     274             : template<unsigned n,unsigned m>
+     275    79564663 : TensorGeneric<n,m>& TensorGeneric<n,m>::operator *=(double s) {
+     276    79564663 :   LoopUnroller<n*m>::_mul(d.data(),s);
+     277    79564663 :   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      177717 : TensorGeneric<n,m> TensorGeneric<n,m>::operator+()const {
+     288      177717 :   return *this;
+     289             : }
+     290             : 
+     291             : template<unsigned n,unsigned m>
+     292      250599 : TensorGeneric<n,m> TensorGeneric<n,m>::operator-()const {
+     293      250599 :   TensorGeneric<n,m> r;
+     294      250599 :   LoopUnroller<n*m>::_neg(r.d.data(),d.data());
+     295      250599 :   return r;
+     296             : }
+     297             : 
+     298             : template<unsigned n,unsigned m>
+     299       79542 : TensorGeneric<n,m>& TensorGeneric<n,m>::setCol(unsigned j,const VectorGeneric<n> & c) {
+     300      318168 :   for(unsigned i=0; i<n; ++i) (*this)(i,j)=c(i);
+     301       79542 :   return *this;
+     302             : }
+     303             : 
+     304             : template<unsigned n,unsigned m>
+     305     3074988 : TensorGeneric<n,m>& TensorGeneric<n,m>::setRow(unsigned i,const VectorGeneric<m> & r) {
+     306    12299952 :   for(unsigned j=0; j<m; ++j) (*this)(i,j)=r(j);
+     307     3074988 :   return *this;
+     308             : }
+     309             : 
+     310             : template<unsigned n,unsigned m>
+     311    12312882 : VectorGeneric<n> TensorGeneric<n,m>::getCol(unsigned j)const {
+     312    12312882 :   VectorGeneric<n> v;
+     313    61455240 :   for(unsigned i=0; i<n; ++i) v(i)=(*this)(i,j);
+     314    12312882 :   return v;
+     315             : }
+     316             : 
+     317             : template<unsigned n,unsigned m>
+     318     3535515 : VectorGeneric<m> TensorGeneric<n,m>::getRow(unsigned i)const {
+     319     3535515 :   VectorGeneric<m> v;
+     320    14142060 :   for(unsigned j=0; j<m; ++j) v(j)=(*this)(i,j);
+     321     3535515 :   return v;
+     322             : }
+     323             : 
+     324             : template<unsigned n,unsigned m>
+     325     2930657 : TensorGeneric<n,m> operator+(const TensorGeneric<n,m>&t1,const TensorGeneric<n,m>&t2) {
+     326     2930657 :   TensorGeneric<n,m> t(t1);
+     327     2930657 :   t+=t2;
+     328     2930657 :   return t;
+     329             : }
+     330             : 
+     331             : template<unsigned n,unsigned m>
+     332     1820362 : TensorGeneric<n,m> operator-(const TensorGeneric<n,m>&t1,const TensorGeneric<n,m>&t2) {
+     333     1820362 :   TensorGeneric<n,m> t(t1);
+     334     1820362 :   t-=t2;
+     335     1820362 :   return t;
+     336             : }
+     337             : 
+     338             : template<unsigned n,unsigned m>
+     339    79559638 : TensorGeneric<n,m> operator*(const TensorGeneric<n,m>&t1,double s) {
+     340    79559638 :   TensorGeneric<n,m> t(t1);
+     341    79559638 :   t*=s;
+     342    79559638 :   return t;
+     343             : }
+     344             : 
+     345             : template<unsigned n,unsigned m>
+     346    54513062 : TensorGeneric<n,m> operator*(double s,const TensorGeneric<n,m>&t1) {
+     347    54513062 :   return t1*s;
+     348             : }
+     349             : 
+     350             : template<unsigned n,unsigned m>
+     351       37363 : TensorGeneric<n,m> operator/(const TensorGeneric<n,m>&t1,double s) {
+     352       37363 :   return t1*(1.0/s);
+     353             : }
+     354             : 
+     355             : template<>
+     356             : inline
+     357      271228 : double TensorGeneric<3,3>::determinant()const {
+     358             :   return
+     359      271228 :     d[0]*d[4]*d[8]
+     360      271228 :     + d[1]*d[5]*d[6]
+     361      271228 :     + d[2]*d[3]*d[7]
+     362      271228 :     - d[0]*d[5]*d[7]
+     363      271228 :     - d[1]*d[3]*d[8]
+     364      271228 :     - d[2]*d[4]*d[6];
+     365             : }
+     366             : 
+     367             : template<unsigned n,unsigned m>
+     368             : inline
+     369    13274080 : TensorGeneric<n,n> TensorGeneric<n,m>::identity() {
+     370    13274080 :   TensorGeneric<n,n> t;
+     371    53096320 :   for(unsigned i=0; i<n; i++) t(i,i)=1.0;
+     372    13274080 :   return t;
+     373             : }
+     374             : 
+     375             : template<unsigned n,unsigned m>
+     376     4873009 : TensorGeneric<m,n> TensorGeneric<n,m>::transpose()const {
+     377     4873009 :   TensorGeneric<m,n> t;
+     378    63349117 :   for(unsigned i=0; i<m; i++)for(unsigned j=0; j<n; j++) t(i,j)=(*this)(j,i);
+     379     4873009 :   return t;
+     380             : }
+     381             : 
+     382             : template<>
+     383             : inline
+     384      177725 : TensorGeneric<3,3> TensorGeneric<3,3>::inverse()const {
+     385      177725 :   TensorGeneric t;
+     386      177725 :   double invdet=1.0/determinant();
+     387     2310425 :   for(unsigned i=0; i<3; i++) for(unsigned j=0; j<3; j++)
+     388     1599525 :       t(j,i)=invdet*(   (*this)((i+1)%3,(j+1)%3)*(*this)((i+2)%3,(j+2)%3)
+     389     1599525 :                         -(*this)((i+1)%3,(j+2)%3)*(*this)((i+2)%3,(j+1)%3));
+     390      177725 :   return t;
+     391             : }
+     392             : 
+     393             : template<unsigned n,unsigned m,unsigned l>
+     394     5606979 : TensorGeneric<n,l> matmul(const TensorGeneric<n,m>&a,const TensorGeneric<m,l>&b) {
+     395     5606979 :   TensorGeneric<n,l> t;
+     396   224279160 :   for(unsigned i=0; i<n; i++) for(unsigned j=0; j<l; j++) for(unsigned k=0; k<m; k++) {
+     397   151388433 :         t(i,j)+=a(i,k)*b(k,j);
+     398             :       }
+     399     5606979 :   return t;
+     400             : }
+     401             : 
+     402             : template<unsigned n,unsigned m>
+     403    60081015 : VectorGeneric<n> matmul(const TensorGeneric<n,m>&a,const VectorGeneric<m>&b) {
+     404    60081015 :   VectorGeneric<n> t;
+     405   781053195 :   for(unsigned i=0; i<n; i++) for(unsigned j=0; j<m; j++) t(i)+=a(i,j)*b(j);
+     406    60081015 :   return t;
+     407             : }
+     408             : 
+     409             : template<unsigned n,unsigned m>
+     410   107669891 : VectorGeneric<n> matmul(const VectorGeneric<m>&a,const TensorGeneric<m,n>&b) {
+     411   107669891 :   VectorGeneric<n> t;
+     412  1400863265 :   for(unsigned i=0; i<n; i++) for(unsigned j=0; j<m; j++) t(i)+=a(j)*b(j,i);
+     413   107669891 :   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      359586 : VectorGeneric<n> matmul(const TensorGeneric<n,m>&a,const TensorGeneric<m,l>&b,const VectorGeneric<l>&c) {
+     428      359586 :   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       89063 :   return t.inverse();
+     449             : }
+     450             : 
+     451             : template<unsigned n,unsigned m>
+     452      857817 : TensorGeneric<n,m> transpose(const TensorGeneric<m,n>&t) {
+     453      857817 :   return t.transpose();
+     454             : }
+     455             : 
+     456             : template<unsigned n,unsigned m>
+     457     2610172 : TensorGeneric<n,m> extProduct(const VectorGeneric<n>&v1,const VectorGeneric<m>&v2) {
+     458     2610172 :   return TensorGeneric<n,m>(v1,v2);
+     459             : }
+     460             : 
+     461             : inline
+     462     5176287 : 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     5176287 :            -v2[2],   0.0, v2[0],
+     467     5176287 :            v2[1],-v2[0],   0.0);
+     468             : }
+     469             : 
+     470             : inline
+     471     5753943 : 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     5753943 :            v1[2],0.0,-v1[0],
+     476     5753943 :            -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      605562 : 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      605562 :   auto mat_copy=mat;
+     540             :   // documentation says this is size n (even if m<n)
+     541             :   std::array<double,n> evals_tmp;
+     542      605562 :   int nn=n;              // dimension of matrix
+     543      605562 :   double vl=0.0, vu=1.0; // ranges - not used
+     544      605562 :   int one=1,mm=m;        // minimum and maximum index
+     545      605562 :   double abstol=0.0;     // tolerance
+     546      605562 :   int mout=0;            // number of eigenvalues found (same as mm)
+     547      605562 :   int info=0;            // result
+     548      605562 :   int liwork=iwork.size();
+     549      605562 :   int lwork=work.size();
+     550      605562 :   TensorGenericAux::local_dsyevr("V", (n==m?"A":"I"), "U", &nn, const_cast<double*>(&mat_copy[0][0]), &nn, &vl, &vu, &one, &mm,
+     551      605562 :                                  &abstol, &mout, &evals_tmp[0], &evec[0][0], &nn,
+     552             :                                  isup.data(), work.data(), &lwork, iwork.data(), &liwork, &info);
+     553      605562 :   if(info!=0) plumed_error()<<"Error diagonalizing matrix\n"
+     554             :                               <<"Matrix:\n"<<mat<<"\n"
+     555             :                               <<"Info: "<<info<<"\n";
+     556      605562 :   plumed_assert(mout==m);
+     557     1388366 :   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     1388366 :   for(unsigned i=0; i<m; ++i) {
+     563             :     unsigned j=0;
+     564      783397 :     for(j=0; j<n; j++) if(evec(i,j)*evec(i,j)>1e-14) break;
+     565     1348239 :     if(j<n) if(evec(i,j)<0.0) for(j=0; j<n; j++) evec(i,j)*=-1;
+     566             :   }
+     567      605562 : }
+     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 000000000000..cb37b762e2b8 --- /dev/null +++ b/coverage/tools/Tools.cpp.func-sort-c.html @@ -0,0 +1,301 @@ + + + + + + + + LCOV - plumed test coverage - tools/Tools.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Tools.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:25829288.4 %
Date:2024-04-19 12:12:35Functions:525791.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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
_ZN4PLMD5Tools7bessel0ERKd0
_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
_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_93
_ZN4PLMD5Tools12convertToIntImEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_93
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERm93
_ZN4PLMD12_GLOBAL__N_1L22process_all_exceptionsINS0_21process_one_exceptionEEEvOT_120
_ZN4PLMD5Tools28concatenateExceptionMessagesB5cxx11Ev120
_ZN4PLMD12_GLOBAL__N_121process_one_exceptionclERKSt9exception133
_ZN4PLMD12_GLOBAL__N_121process_one_exception6updateEv134
_ZN4PLMD5Tools16DirectoryChangerD2Ev520
_ZN4PLMD5Tools16DirectoryChangerC2EPKc521
_ZN4PLMD5Tools5ltrimERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1080
_ZN4PLMD5Tools12convertToAnyIeEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_1208
_ZN4PLMD5Tools13convertToRealIeEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_1208
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERe1208
_ZN4PLMD5Tools29stripLeadingAndTrailingBlanksERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE4352
_ZN4PLMD5Tools2lsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE8754
_ZN4PLMD5Tools9extensionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE12515
_ZN4PLMD5Tools12molfile_lockEv18968
_ZN4PLMD5Tools13getParsedLineERNS_5IFileERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EEb19364
_ZN4PLMD5Tools15interpretRangesERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EE42874
_ZN4PLMD5Tools14interpretLabelERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EE70996
_ZN4PLMD5Tools11findKeywordERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EERKS7_347868
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS6_363484
_ZN4PLMD5Tools6getKeyERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EERKS7_RS7_i396146
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERNS_10AtomNumberE1049129
_ZN4PLMD5Tools23caseInSensStringCompareERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_1251121
_ZN4PLMD5Tools14getWordsSimpleERNS_3gch12small_vectorISt17basic_string_viewIcSt11char_traitsIcEELj2ESaIS6_EEES6_1343182
_ZN4PLMD5Tools4trimERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1394926
_ZN4PLMD5Tools12trimCommentsERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1613026
_ZN4PLMD5Tools12convertToIntIiEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_2477973
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERi2477973
_ZN4PLMD5Tools12convertToAnyIiEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_2483015
_ZN4PLMD5Tools12convertToIntIjEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_2995452
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERj2995452
_ZN4PLMD5Tools7getlineEP8_IO_FILERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3268315
_ZN4PLMD5Tools8getWordsB5cxx11ESt17basic_string_viewIcSt11char_traitsIcEEPKcPiS6_RKb3493066
_ZZN4PLMD5Tools23caseInSensStringCompareERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_ENKUlccE_clEcc3687450
_ZN4PLMD5Tools12convertToAnyIjEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_4044581
_ZN4PLMD5Tools12convertToAnyIdEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_14225883
_ZN4PLMD5Tools13convertToRealIdEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_14225883
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERd14225883
_ZN4PLMD5Tools9startWithERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_331790468
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Tools.cpp.func.html b/coverage/tools/Tools.cpp.func.html new file mode 100644 index 000000000000..1d20dffe55ad --- /dev/null +++ b/coverage/tools/Tools.cpp.func.html @@ -0,0 +1,301 @@ + + + + + + + + LCOV - plumed test coverage - tools/Tools.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Tools.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:25829288.4 %
Date:2024-04-19 12:12:35Functions:525791.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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_347868
_ZN4PLMD5Tools12convertToAnyIdEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_14225883
_ZN4PLMD5Tools12convertToAnyIeEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_1208
_ZN4PLMD5Tools12convertToAnyIfEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_0
_ZN4PLMD5Tools12convertToAnyIiEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_2483015
_ZN4PLMD5Tools12convertToAnyIjEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_4044581
_ZN4PLMD5Tools12convertToAnyIlEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_3
_ZN4PLMD5Tools12convertToAnyImEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_93
_ZN4PLMD5Tools12convertToAnyIxEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_85
_ZN4PLMD5Tools12convertToAnyIyEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_54
_ZN4PLMD5Tools12convertToIntIiEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_2477973
_ZN4PLMD5Tools12convertToIntIjEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_2995452
_ZN4PLMD5Tools12convertToIntIlEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_3
_ZN4PLMD5Tools12convertToIntImEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_93
_ZN4PLMD5Tools12convertToIntIxEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_85
_ZN4PLMD5Tools12convertToIntIyEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_54
_ZN4PLMD5Tools12molfile_lockEv18968
_ZN4PLMD5Tools12trimCommentsERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1613026
_ZN4PLMD5Tools13convertToRealIdEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_14225883
_ZN4PLMD5Tools13convertToRealIeEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_1208
_ZN4PLMD5Tools13convertToRealIfEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_0
_ZN4PLMD5Tools13getParsedLineERNS_5IFileERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EEb19364
_ZN4PLMD5Tools14getWordsSimpleERNS_3gch12small_vectorISt17basic_string_viewIcSt11char_traitsIcEELj2ESaIS6_EEES6_1343182
_ZN4PLMD5Tools14interpretLabelERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EE70996
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERNS_10AtomNumberE1049129
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS6_363484
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERd14225883
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERe1208
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERf0
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERi2477973
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERj2995452
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERl3
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERm93
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERx85
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERy54
_ZN4PLMD5Tools15interpretRangesERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EE42874
_ZN4PLMD5Tools16DirectoryChangerC2EPKc521
_ZN4PLMD5Tools16DirectoryChangerD2Ev520
_ZN4PLMD5Tools23caseInSensStringCompareERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_1251121
_ZN4PLMD5Tools28concatenateExceptionMessagesB5cxx11Ev120
_ZN4PLMD5Tools29stripLeadingAndTrailingBlanksERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE4352
_ZN4PLMD5Tools2lsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE8754
_ZN4PLMD5Tools4trimERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1394926
_ZN4PLMD5Tools5ltrimERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1080
_ZN4PLMD5Tools6getKeyERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EERKS7_RS7_i396146
_ZN4PLMD5Tools7bessel0ERKd0
_ZN4PLMD5Tools7getlineEP8_IO_FILERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3268315
_ZN4PLMD5Tools8getWordsB5cxx11ESt17basic_string_viewIcSt11char_traitsIcEEPKcPiS6_RKb3493066
_ZN4PLMD5Tools9extensionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE12515
_ZN4PLMD5Tools9startWithERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_331790468
_ZZN4PLMD5Tools23caseInSensStringCompareERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_ENKUlccE_clEcc3687450
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Tools.cpp.gcov.html b/coverage/tools/Tools.cpp.gcov.html new file mode 100644 index 000000000000..8da93be24049 --- /dev/null +++ b/coverage/tools/Tools.cpp.gcov.html @@ -0,0 +1,597 @@ + + + + + + + + LCOV - plumed test coverage - tools/Tools.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Tools.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:25829288.4 %
Date:2024-04-19 12:12:35Functions:525791.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 "Tools.h"
+      23             : #include "AtomNumber.h"
+      24             : #include "Exception.h"
+      25             : #include "IFile.h"
+      26             : #include "lepton/Lepton.h"
+      27             : #include <cstring>
+      28             : #include <iostream>
+      29             : #include <map>
+      30             : #include <iomanip>
+      31             : #include <filesystem>
+      32             : 
+      33             : namespace PLMD {
+      34             : 
+      35             : template<class T>
+      36    20754922 : bool Tools::convertToAny(const std::string & str,T & t) {
+      37    39026829 :   std::istringstream istr(str.c_str());
+      38    20754922 :   bool ok=static_cast<bool>(istr>>t);
+      39    20754922 :   if(!ok) return false;
+      40             :   std::string remaining;
+      41    20712337 :   istr>>remaining;
+      42    20712337 :   return remaining.length()==0;
+      43    20754922 : }
+      44             : 
+      45     2477973 : bool Tools::convertNoexcept(const std::string & str,int & t) {
+      46     2477973 :   return convertToInt(str,t);
+      47             : }
+      48             : 
+      49           3 : bool Tools::convertNoexcept(const std::string & str,long int & t) {
+      50           3 :   return convertToInt(str,t);
+      51             : }
+      52             : 
+      53          85 : bool Tools::convertNoexcept(const std::string & str,long long int & t) {
+      54          85 :   return convertToInt(str,t);
+      55             : }
+      56             : 
+      57     2995452 : bool Tools::convertNoexcept(const std::string & str,unsigned & t) {
+      58     2995452 :   return convertToInt(str,t);
+      59             : }
+      60             : 
+      61          93 : bool Tools::convertNoexcept(const std::string & str,long unsigned & t) {
+      62          93 :   return convertToInt(str,t);
+      63             : }
+      64             : 
+      65          54 : bool Tools::convertNoexcept(const std::string & str,long long unsigned & t) {
+      66          54 :   return convertToInt(str,t);
+      67             : }
+      68             : 
+      69     1049129 : bool Tools::convertNoexcept(const std::string & str,AtomNumber &a) {
+      70             :   // Note: AtomNumber's are NOT converted as int, so as to
+      71             :   // avoid using lepton conversions.
+      72             :   unsigned i;
+      73     1049129 :   bool r=convertToAny(str,i);
+      74     1049129 :   if(r) a.setSerial(i);
+      75     1049129 :   return r;
+      76             : }
+      77             : 
+      78             : template<class T>
+      79     5473660 : bool Tools::convertToInt(const std::string & str,T & t) {
+      80             :   // First try standard conversion
+      81     5473660 :   if(convertToAny(str,t)) return true;
+      82             :   // Then use lepton
+      83             :   try {
+      84     2008031 :     double r=lepton::Parser::parse(str).evaluate(lepton::Constants());
+      85             : 
+      86             :     // now sanity checks on the resulting number
+      87             : 
+      88             :     // it should not overflow the requested int type:
+      89             :     // (see https://stackoverflow.com/a/526092)
+      90     2008031 :     if(r>std::nextafter(std::numeric_limits<T>::max(), 0)) return false;
+      91     2008031 :     if(r<std::nextafter(std::numeric_limits<T>::min(), 0)) return false;
+      92             : 
+      93             :     // do the actual conversion
+      94     2008031 :     auto tmp=static_cast<T>(std::round(r));
+      95             : 
+      96             :     // it should be *very close* to itself if converted back to double
+      97     2008031 :     double diff= r-static_cast<double>(tmp);
+      98     2008031 :     if(diff*diff > 1e-20) return false;
+      99             :     // this is to accomodate small numerical errors and allow e.g. exp(log(7)) to be integer
+     100             : 
+     101             :     // it should be change if incremented or decremented by one (see https://stackoverflow.com/a/43656140)
+     102     2008027 :     if(r == static_cast<double>(tmp-1)) return false;
+     103     2008026 :     if(r == static_cast<double>(tmp+1)) return false;
+     104             : 
+     105             :     // everything is fine, then store in t
+     106     2008026 :     t=tmp;
+     107     2008026 :     return true;
+     108           0 :   } catch(const PLMD::lepton::Exception& exc) {
+     109             :   }
+     110           0 :   return false;
+     111             : }
+     112             : 
+     113             : 
+     114             : template<class T>
+     115    14227091 : bool Tools::convertToReal(const std::string & str,T & t) {
+     116    14227091 :   if(convertToAny(str,t)) return true;
+     117       67982 :   if(str=="PI" || str=="+PI" || str=="+pi" || str=="pi") {
+     118        8543 :     t=pi; return true;
+     119       17030 :   } else if(str=="-PI" || str=="-pi") {
+     120        8456 :     t=-pi; return true;
+     121             :   }
+     122             :   try {
+     123          59 :     t=lepton::Parser::parse(str).evaluate(lepton::Constants());
+     124          24 :     return true;
+     125          35 :   } catch(const PLMD::lepton::Exception& exc) {
+     126             :   }
+     127          35 :   if( str.find("PI")!=std::string::npos ) {
+     128           0 :     std::size_t pi_start=str.find_first_of("PI");
+     129           0 :     if(str.substr(pi_start)!="PI") return false;
+     130           0 :     std::istringstream nstr(str.substr(0,pi_start));
+     131           0 :     T ff=0.0; bool ok=static_cast<bool>(nstr>>ff);
+     132           0 :     if(!ok) return false;
+     133           0 :     t=ff*pi;
+     134           0 :     std::string remains; nstr>>remains;
+     135           0 :     return remains.length()==0;
+     136          35 :   } else if( str.find("pi")!=std::string::npos ) {
+     137          13 :     std::size_t pi_start=str.find_first_of("pi");
+     138          26 :     if(str.substr(pi_start)!="pi") return false;
+     139          13 :     std::istringstream nstr(str.substr(0,pi_start));
+     140          13 :     T ff=0.0; bool ok=static_cast<bool>(nstr>>ff);
+     141          13 :     if(!ok) return false;
+     142          13 :     t=ff*pi;
+     143          13 :     std::string remains; nstr>>remains;
+     144          13 :     return remains.length()==0;
+     145          35 :   } else if(str=="NAN") {
+     146           0 :     t=std::numeric_limits<double>::quiet_NaN();
+     147           0 :     return true;
+     148             :   }
+     149             :   return false;
+     150             : }
+     151             : 
+     152           0 : bool Tools::convertNoexcept(const std::string & str,float & t) {
+     153           0 :   return convertToReal(str,t);
+     154             : }
+     155             : 
+     156    14225883 : bool Tools::convertNoexcept(const std::string & str,double & t) {
+     157    14225883 :   return convertToReal(str,t);
+     158             : }
+     159             : 
+     160        1208 : bool Tools::convertNoexcept(const std::string & str,long double & t) {
+     161        1208 :   return convertToReal(str,t);
+     162             : }
+     163             : 
+     164      363484 : bool Tools::convertNoexcept(const std::string & str,std::string & t) {
+     165             :   t=str;
+     166      363484 :   return true;
+     167             : }
+     168             : 
+     169     3493066 : std::vector<std::string> Tools::getWords(std::string_view line,const char* separators,int * parlevel,const char* parenthesis, const bool& delete_parenthesis) {
+     170     3493066 :   plumed_massert(std::strlen(parenthesis)==1,"multiple parenthesis type not available");
+     171     3493066 :   plumed_massert(parenthesis[0]=='(' || parenthesis[0]=='[' || parenthesis[0]=='{',
+     172             :                  "only ( [ { allowed as parenthesis");
+     173     3493066 :   if(!separators) separators=" \t\n";
+     174     3493066 :   const std::string sep(separators);
+     175     3493066 :   char openpar=parenthesis[0];
+     176             :   char closepar;
+     177             :   if(openpar=='(') closepar=')';
+     178     3493066 :   if(openpar=='[') closepar=']';
+     179     3493066 :   if(openpar=='{') closepar='}';
+     180             :   std::vector<std::string> words;
+     181             :   std::string word;
+     182             :   int parenthesisLevel=0;
+     183     3493066 :   if(parlevel) parenthesisLevel=*parlevel;
+     184   259349516 :   for(unsigned i=0; i<line.length(); i++) {
+     185             :     bool found=false;
+     186             :     bool onParenthesis=false;
+     187   255856450 :     if( (line[i]==openpar || line[i]==closepar) && delete_parenthesis ) onParenthesis=true;
+     188   255856450 :     if(line[i]==closepar) {
+     189        3772 :       parenthesisLevel--;
+     190        3772 :       plumed_assert(parenthesisLevel>=0) << "Extra closed parenthesis in '" << line << "'";
+     191             :     }
+     192  1036273317 :     if(parenthesisLevel==0) for(unsigned j=0; j<sep.length(); j++) if(line[i]==sep[j]) found=true;
+     193             : // If at parenthesis level zero (outer)
+     194   255856450 :     if(!(parenthesisLevel==0 && (found||onParenthesis))) word.push_back(line[i]);
+     195             :     //if(onParenthesis) word.push_back(' ');
+     196   255856450 :     if(line[i]==openpar) parenthesisLevel++;
+     197   255856450 :     if(found && word.length()>0) {
+     198    16355360 :       if(!parlevel) plumed_assert(parenthesisLevel==0) << "Unmatching parenthesis in '" << line << "'";
+     199    16355360 :       words.push_back(word);
+     200             :       word.clear();
+     201             :     }
+     202             :   }
+     203     3493066 :   if(word.length()>0) {
+     204     3371528 :     if(!parlevel) plumed_assert(parenthesisLevel==0) << "Unmatching parenthesis in '" << line << "'";
+     205     3371528 :     words.push_back(word);
+     206             :   }
+     207     3493066 :   if(parlevel) *parlevel=parenthesisLevel;
+     208     3493066 :   return words;
+     209           0 : }
+     210             : 
+     211     1343182 : void Tools::getWordsSimple(gch::small_vector<std::string_view> & words,std::string_view line) {
+     212             :   words.clear();
+     213     1343182 :   auto ptr=line.data();
+     214     1343182 :   std::size_t size=0;
+     215    14464104 :   for(unsigned i=0; i<line.length(); i++) {
+     216    13120922 :     const bool is_separator=(line[i]==' ');
+     217    13120922 :     if(!is_separator) {
+     218    13079938 :       size++;
+     219       40984 :     } else if(size==0) {
+     220           0 :       ptr++;
+     221             :     } else {
+     222             :       words.emplace_back(ptr,size);
+     223       40984 :       ptr=&line[i]+1;
+     224       40984 :       size=0;
+     225             :     }
+     226             :   }
+     227     1343182 :   if(size>0) {
+     228             :     words.emplace_back(ptr,size);
+     229             :   }
+     230     1343182 : }
+     231             : 
+     232       19364 : bool Tools::getParsedLine(IFile& ifile,std::vector<std::string> & words, bool trimcomments) {
+     233       19364 :   std::string line("");
+     234             :   words.clear();
+     235             :   bool stat;
+     236             :   bool inside=false;
+     237       19364 :   int parlevel=0;
+     238             :   bool mergenext=false;
+     239       39521 :   while((stat=ifile.getline(line))) {
+     240       38522 :     if(trimcomments) trimComments(line);
+     241       38522 :     trim(line);
+     242       38522 :     if(line.length()==0) continue;
+     243       32130 :     std::vector<std::string> w=getWords(line,NULL,&parlevel,"{",trimcomments);
+     244       32130 :     if(!w.empty()) {
+     245       45489 :       if(inside && *(w.begin())=="...") {
+     246             :         inside=false;
+     247        1256 :         if(w.size()==2) plumed_massert(w[1]==words[0],"second word in terminating \"...\" "+w[1]+" line, if present, should be equal to first word of directive: "+words[0]);
+     248        1256 :         plumed_massert(w.size()<=2,"terminating \"...\" lines cannot consist of more than two words");
+     249        1256 :         w.clear(); if(!trimcomments) words.push_back("...");
+     250       30585 :       } else if(*(w.end()-1)=="...") {
+     251             :         inside=true;
+     252             :         w.erase(w.end()-1);
+     253             :       };
+     254             :       int i0=0;
+     255       31841 :       if(mergenext && words.size()>0 && w.size()>0) {
+     256         128 :         words[words.size()-1]+=" "+w[0];
+     257             :         i0=1;
+     258             :       }
+     259      117177 :       for(unsigned i=i0; i<w.size(); ++i) words.push_back(w[i]);
+     260             :     }
+     261       32130 :     mergenext=(parlevel>0);
+     262       32130 :     if(!inside)break;
+     263       13765 :     if(!trimcomments && parlevel==0) words.push_back("@newline");
+     264       13765 :     else if(!trimcomments) words[words.size()-1] += " @newline";
+     265       32130 :   }
+     266       19364 :   plumed_massert(parlevel==0,"non matching parenthesis");
+     267       19364 :   if(words.size()>0) return true;
+     268             :   return stat;
+     269             : }
+     270             : 
+     271             : 
+     272     3268315 : bool Tools::getline(FILE* fp,std::string & line) {
+     273             :   line="";
+     274             :   const int bufferlength=1024;
+     275             :   char buffer[bufferlength];
+     276             :   bool ret;
+     277  3350022875 :   for(int i=0; i<bufferlength; i++) buffer[i]='\0';
+     278     3268315 :   while((ret=fgets(buffer,bufferlength,fp))) {
+     279     3267229 :     line.append(buffer);
+     280     3267229 :     unsigned ss=std::strlen(buffer);
+     281     3267229 :     if(ss>0) if(buffer[ss-1]=='\n') break;
+     282             :   };
+     283     3268315 :   if(line.length()>0) if(*(line.end()-1)=='\n') line.erase(line.end()-1);
+     284     3268315 :   if(line.length()>0) if(*(line.end()-1)=='\r') line.erase(line.end()-1);
+     285     3268315 :   return ret;
+     286             : }
+     287             : 
+     288     1394926 : void Tools::trim(std::string & s) {
+     289     1394926 :   auto n=s.find_last_not_of(" \t");
+     290     1394926 :   if(n!=std::string::npos) s.resize(n+1);
+     291     1394926 : }
+     292             : 
+     293        1080 : void Tools::ltrim(std::string & s) {
+     294        1080 :   auto n=s.find_first_not_of(" \t");
+     295        1080 :   if(n!=std::string::npos) {
+     296        2160 :     s = s.substr(n, s.length()-n);
+     297             :     s.shrink_to_fit();
+     298             :   }
+     299        1080 : }
+     300             : 
+     301     1613026 : void Tools::trimComments(std::string & s) {
+     302     1613026 :   auto n=s.find_first_of("#");
+     303     1613026 :   if(n!=std::string::npos) s.resize(n);
+     304     1613026 : }
+     305             : 
+     306     1251121 : bool Tools::caseInSensStringCompare(const std::string & str1, const std::string &str2)
+     307             : {
+     308     1251121 :   return ((str1.size() == str2.size()) && std::equal(str1.begin(), str1.end(), str2.begin(), [](char c1, char c2) {
+     309     3687450 :     return (c1 == c2 || std::toupper(c1) == std::toupper(c2));
+     310     1251121 :   }));
+     311             : }
+     312             : 
+     313      396146 : bool Tools::getKey(std::vector<std::string>& line,const std::string & key,std::string & s,int rep) {
+     314             :   s.clear();
+     315     1339997 :   for(auto p=line.begin(); p!=line.end(); ++p) {
+     316     1251068 :     if((*p).length()==0) continue;
+     317     1251068 :     std::string x=(*p).substr(0,key.length());
+     318     1251068 :     if(caseInSensStringCompare(x,key)) {
+     319      307217 :       if((*p).length()==key.length())return false;
+     320      307216 :       std::string tmp=(*p).substr(key.length(),(*p).length());
+     321             :       line.erase(p);
+     322             :       s=tmp;
+     323      307216 :       const std::string multi("@replicas:");
+     324      307216 :       if(rep>=0 && startWith(s,multi)) {
+     325          24 :         s=s.substr(multi.length(),s.length());
+     326          24 :         std::vector<std::string> words=getWords(s,"\t\n ,");
+     327          24 :         plumed_massert(rep<static_cast<int>(words.size()),"Number of fields in " + s + " not consistent with number of replicas");
+     328          24 :         s=words[rep];
+     329          24 :       }
+     330             :       return true;
+     331             :     }
+     332             :   };
+     333             :   return false;
+     334             : }
+     335             : 
+     336       42874 : void Tools::interpretRanges(std::vector<std::string>&s) {
+     337             :   std::vector<std::string> news;
+     338      591522 :   for(const auto & p :s) {
+     339      548648 :     news.push_back(p);
+     340      548648 :     size_t dash=p.find("-");
+     341      549309 :     if(dash==std::string::npos) continue;
+     342             :     int first;
+     343        5638 :     if(!Tools::convertToAny(p.substr(0,dash),first)) continue;
+     344        2158 :     int stride=1;
+     345             :     int second;
+     346        2158 :     size_t colon=p.substr(dash+1).find(":");
+     347        2158 :     if(colon!=std::string::npos) {
+     348         195 :       if(!Tools::convertToAny(p.substr(dash+1).substr(0,colon),second) ||
+     349         260 :           !Tools::convertToAny(p.substr(dash+1).substr(colon+1),stride)) continue;
+     350             :     } else {
+     351        4186 :       if(!Tools::convertToAny(p.substr(dash+1),second)) continue;
+     352             :     }
+     353        2158 :     news.resize(news.size()-1);
+     354        2158 :     if(first<=second) {
+     355        2157 :       plumed_massert(stride>0,"interpreting ranges "+ p + ", stride should be positive");
+     356      511694 :       for(int i=first; i<=second; i+=stride) {
+     357             :         std::string ss;
+     358      509537 :         convert(i,ss);
+     359      509537 :         news.push_back(ss);
+     360             :       }
+     361             :     } else {
+     362           1 :       plumed_massert(stride<0,"interpreting ranges "+ p + ", stride should be positive");
+     363           3 :       for(int i=first; i>=second; i+=stride) {
+     364             :         std::string ss;
+     365           2 :         convert(i,ss);
+     366           2 :         news.push_back(ss);
+     367             :       }
+     368             :     }
+     369             :   }
+     370       42874 :   s=news;
+     371       42874 : }
+     372             : 
+     373       70996 : void Tools::interpretLabel(std::vector<std::string>&s) {
+     374       70996 :   if(s.size()<2)return;
+     375       70657 :   std::string s0=s[0];
+     376       70657 :   unsigned l=s0.length();
+     377       70657 :   if(l<1) return;
+     378       70657 :   if(s0[l-1]==':') {
+     379             :     s[0]=s[1];
+     380      132778 :     s[1]="LABEL="+s0.substr(0,l-1);
+     381             :   }
+     382       70657 :   std::transform(s[0].begin(), s[0].end(), s[0].begin(), ::toupper);
+     383             : }
+     384             : 
+     385        8754 : std::vector<std::string> Tools::ls(const std::string&d) {
+     386             :   std::vector<std::string> result;
+     387      140862 :   for (auto const& dir_entry : std::filesystem::directory_iterator{d}) {
+     388      343800 :     result.push_back(dir_entry.path().filename());
+     389             :   }
+     390        8754 :   return result;
+     391           0 : }
+     392             : 
+     393        4352 : void Tools::stripLeadingAndTrailingBlanks( std::string& str ) {
+     394        4352 :   std::size_t first=str.find_first_not_of(' ');
+     395        4352 :   std::size_t last=str.find_last_not_of(' ');
+     396        8667 :   if( first<=last && first!=std::string::npos) str=str.substr(first,last+1);
+     397        4352 : }
+     398             : 
+     399       12515 : std::string Tools::extension(const std::string&s) {
+     400       12515 :   size_t n=s.find_last_of(".");
+     401             :   std::string ext;
+     402       12515 :   if(n!=std::string::npos && n+1<s.length() && n+5>=s.length()) {
+     403        8969 :     ext=s.substr(n+1);
+     404        8969 :     if(ext.find("/")!=std::string::npos) ext="";
+     405        8969 :     std::string base=s.substr(0,n);
+     406        8969 :     if(base.length()==0) ext="";
+     407        8969 :     if(base.length()>0 && base[base.length()-1]=='/') ext="";
+     408             :   }
+     409       12515 :   return ext;
+     410             : }
+     411             : 
+     412           0 : double Tools::bessel0( const double& val ) {
+     413           0 :   if (std::abs(val)<3.75) {
+     414           0 :     double y = Tools::fastpow( val/3.75, 2 );
+     415           0 :     return 1 + y*(3.5156229 +y*(3.0899424 + y*(1.2067492+y*(0.2659732+y*(0.0360768+y*0.0045813)))));
+     416             :   }
+     417           0 :   double ax=std::abs(val), y=3.75/ax, bx=std::exp(ax)/std::sqrt(ax);
+     418           0 :   ax=0.39894228+y*(0.01328592+y*(0.00225319+y*(-0.00157565+y*(0.00916281+y*(-0.02057706+y*(0.02635537+y*(-0.01647633+y*0.00392377)))))));
+     419           0 :   return ax*bx;
+     420             : }
+     421             : 
+     422   331790468 : bool Tools::startWith(const std::string & full,const std::string &start) {
+     423   331790468 :   return (full.substr(0,start.length())==start);
+     424             : }
+     425             : 
+     426      347868 : bool Tools::findKeyword(const std::vector<std::string>&line,const std::string&key) {
+     427      347868 :   const std::string search(key+"=");
+     428   327996308 :   for(const auto & p : line) {
+     429   327791842 :     if(startWith(p,search)) return true;
+     430             :   }
+     431             :   return false;
+     432             : }
+     433             : 
+     434         521 : Tools::DirectoryChanger::DirectoryChanger(const char*path):
+     435         521 :   path(std::filesystem::current_path())
+     436             : {
+     437         521 :   if(!path) return;
+     438         521 :   if(std::strlen(path)==0) return;
+     439           4 :   std::filesystem::current_path(path);
+     440             : }
+     441             : 
+     442         520 : Tools::DirectoryChanger::~DirectoryChanger() {
+     443             :   try {
+     444         520 :     std::filesystem::current_path(path);
+     445           0 :   } catch(std::filesystem::filesystem_error & e) {
+     446           0 :     std::fprintf(stderr,"+++ WARNING: cannot cd back to directory %s\n",path.c_str());
+     447           0 :   }
+     448         520 : }
+     449             : 
+     450       18968 : std::unique_ptr<std::lock_guard<std::mutex>> Tools::molfile_lock() {
+     451             :   static std::mutex mtx;
+     452       18968 :   return Tools::make_unique<std::lock_guard<std::mutex>>(mtx);
+     453             : }
+     454             : 
+     455             : /// Internal tool, I am keeping it private for now
+     456             : namespace {
+     457             : 
+     458             : class process_one_exception {
+     459             :   std::string & msg;
+     460             :   bool first=true;
+     461         134 :   void update() {
+     462         134 :     if(!first) msg+="\n\nThe above exception was the direct cause of the following exception:\n";
+     463         134 :     first=false;
+     464         134 :   }
+     465             : public:
+     466         120 :   process_one_exception(std::string & msg):
+     467         120 :     msg(msg)
+     468             :   {}
+     469         133 :   void operator()(const std::exception & e) {
+     470         133 :     update();
+     471         133 :     msg+=e.what();
+     472         133 :   }
+     473           0 :   void operator()(const std::string & e) {
+     474           0 :     update();
+     475           0 :     msg+=e;
+     476           0 :   }
+     477           1 :   void operator()(const char* e) {
+     478           1 :     update();
+     479           1 :     msg+=e;
+     480           1 :   }
+     481             : };
+     482             : 
+     483             : template<class T>
+     484         134 : static void process_all_exceptions(T&& f) {
+     485             :   try {
+     486             :     // First throw the current exception
+     487         134 :     throw;
+     488         148 :   } catch(const std::nested_exception & e) {
+     489             :     // If nested, we go recursive
+     490             :     // notice that we apply function f only if exception is also a std::exception
+     491             :     try {
+     492          14 :       e.rethrow_nested();
+     493          28 :     } catch(...) {
+     494          14 :       process_all_exceptions(f);
+     495             :     }
+     496          14 :     auto d=dynamic_cast<const std::exception*>(&e);
+     497          14 :     if(d) f(*d);
+     498         238 :   } catch(const std::exception &e) {
+     499             :     // If not nested, we end recursion
+     500         119 :     f(e);
+     501           0 :   } catch(const std::string &e) {
+     502             :     // If not nested, we end recursion
+     503           0 :     f(e);
+     504           2 :   } catch(const char* e) {
+     505             :     // If not nested, we end recursion
+     506           1 :     f(e);
+     507           0 :   } catch(...) {
+     508             :     // If not nested and of unknown type, we stop the chain
+     509             :   }
+     510         134 : }
+     511             : 
+     512             : }
+     513             : 
+     514         120 : std::string Tools::concatenateExceptionMessages() {
+     515             :   std::string msg;
+     516         120 :   process_all_exceptions(process_one_exception(msg));
+     517         120 :   return msg;
+     518             : }
+     519             : 
+     520             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Tools.h.func-sort-c.html b/coverage/tools/Tools.h.func-sort-c.html new file mode 100644 index 000000000000..ce56c5f055ca --- /dev/null +++ b/coverage/tools/Tools.h.func-sort-c.html @@ -0,0 +1,297 @@ + + + + + + + + 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:949697.9 %
Date:2024-04-19 12:12:35Functions:505689.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5Tools15convertNoexceptIlEEbT_RNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD5Tools15convertNoexceptIxEEbT_RNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD5Tools7convertINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEfEEvRKT_RT0_0
_ZN4PLMD5Tools7convertIPciEEvRKT_RT0_0
_ZN4PLMD5Tools7convertIlNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKT_RT0_0
_ZN4PLMD5Tools7convertIxNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKT_RT0_0
_ZN4PLMD5Tools7convertINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEElEEvRKT_RT0_1
_ZN4PLMD5Tools7convertINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEmEEvRKT_RT0_1
_ZN4PLMD5Tools5parseImEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RT_i12
_ZN4PLMD5Tools11parseVectorIxEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RS2_IT_SaISE_EEi14
_ZN4PLMD5Tools7convertINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEyEEvRKT_RT0_14
_ZN4PLMD5Tools7convertINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEExEEvRKT_RT0_16
_ZN4PLMD5Tools22CriticalSectionWithKeyINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEE4stopERKS7_23
_ZN4PLMD5Tools22CriticalSectionWithKeyINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEE5startERKS7_23
_ZN4PLMD5Tools22CriticalSectionWithKeyINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEE7HandlerC2EPS8_RKS7_23
_ZN4PLMD5Tools22CriticalSectionWithKeyINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEE7HandlerD2Ev23
_ZN4PLMD5Tools11parseVectorIeEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RS2_IT_SaISE_EEi32
_ZN4PLMD5Tools11parseVectorIiEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RS2_IT_SaISE_EEi36
_ZN4PLMD5Tools10unique2rawINS_3ves12CoeffsMatrixEEESt6vectorIPT_SaIS6_EERKS4_ISt10unique_ptrIS5_St14default_deleteIS5_EESaISC_EE82
_ZN4PLMD5Tools5parseIxEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RT_i109
_ZN4PLMD5Tools10unique2rawINS_3ves12CoeffsVectorEEESt6vectorIPT_SaIS6_EERKS4_ISt10unique_ptrIS5_St14default_deleteIS5_EESaISC_EE437
_ZN4PLMD5Tools7convertIPcjEEvRKT_RT0_938
_ZN4PLMD5Tools5parseIeEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RT_i1080
_ZN4PLMD5Tools7convertINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEjEEvRKT_RT0_1103
_ZN4PLMD5Tools10unique2rawINS_5ValueEEESt6vectorIPT_SaIS5_EERKS3_ISt10unique_ptrIS4_St14default_deleteIS4_EESaISB_EE1788
_ZN4PLMDL18dp2cutoffNoStretchEv5719
_ZN4PLMD5Tools7convertINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEENS_10AtomNumberEEEvRKT_RT0_5782
_ZN4PLMD5Tools5parseIjEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RT_i5808
_ZN4PLMD5Tools7convertINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES7_EEvRKT_RT0_7030
_ZN4PLMD5Tools5parseIiEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RT_i7457
_ZN4PLMD5Tools22FastStringUnorderedMapIiEC2ESt16initializer_listISt4pairIKSt17basic_string_viewIcSt11char_traitsIcEEiEE10312
_ZN4PLMD5Tools22FastStringUnorderedMapINS_9Stopwatch5WatchEE4convESt17basic_string_viewIcSt11char_traitsIcEE13029
_ZN4PLMD5Tools16removeDuplicatesINS_10AtomNumberEEEvRSt6vectorIT_SaIS4_EE17093
_ZN4PLMD5Tools11parseVectorIdEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RS2_IT_SaISE_EEi17353
_ZN4PLMD5Tools15convertNoexceptImEEbT_RNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE19291
_ZN4PLMD5Tools7convertImNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKT_RT0_19291
_ZN4PLMD5Tools11set_to_zeroILj3EEEvRSt6vectorINS_13VectorGenericIXT_EEESaIS4_EE28739
_ZN4PLMD5Tools15convertNoexceptIdEEbT_RNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE31039
_ZN4PLMD5Tools7convertIdNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKT_RT0_31039
_ZN4PLMD5Tools5parseIdEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RT_i33402
_ZN4PLMD5Tools16removeDuplicatesIjEEvRSt6vectorIT_SaIS3_EE74837
_ZN4PLMD5Tools11parseVectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEbRSt6vectorIS7_SaIS7_EERKS7_RS8_IT_SaISE_EEi90632
_ZN4PLMD5Tools9parseFlagERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EERKS7_Rb94243
_ZN4PLMD5Tools11parseVectorIjEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RS2_IT_SaISE_EEi106650
_ZN4PLMD5Tools5parseINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEbRSt6vectorIS7_SaIS7_EERKS7_RT_i133561
_ZN4PLMD5Tools22FastStringUnorderedMapIiE4convESt17basic_string_viewIcSt11char_traitsIcEE459062
_ZN4PLMD5Tools22FastStringUnorderedMapIiEixERKSt17basic_string_viewIcSt11char_traitsIcEE459062
_ZN4PLMD5Tools15convertNoexceptIiEEbT_RNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE682751
_ZN4PLMD5Tools7convertIiNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKT_RT0_682751
_ZN4PLMD5Tools7convertINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiEEvRKT_RT0_2472760
_ZN4PLMD5Tools22FastStringUnorderedMapINS_9Stopwatch5WatchEEixERKSt17basic_string_viewIcSt11char_traitsIcEE3024492
_ZN4PLMD5Tools15convertNoexceptIjEEbT_RNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE5114023
_ZN4PLMD5Tools7convertIjNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKT_RT0_5114023
_ZN4PLMD5Tools7convertINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdEEvRKT_RT0_14023976
_ZN4PLMD5Tools7fastpowEdi56216359
_ZN4PLMD5Tools3pbcEd1783700944
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Tools.h.func.html b/coverage/tools/Tools.h.func.html new file mode 100644 index 000000000000..b45d95f0cda7 --- /dev/null +++ b/coverage/tools/Tools.h.func.html @@ -0,0 +1,297 @@ + + + + + + + + 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:949697.9 %
Date:2024-04-19 12:12:35Functions:505689.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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_EE1788
_ZN4PLMD5Tools11parseVectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEbRSt6vectorIS7_SaIS7_EERKS7_RS8_IT_SaISE_EEi90632
_ZN4PLMD5Tools11parseVectorIdEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RS2_IT_SaISE_EEi17353
_ZN4PLMD5Tools11parseVectorIeEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RS2_IT_SaISE_EEi32
_ZN4PLMD5Tools11parseVectorIiEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RS2_IT_SaISE_EEi36
_ZN4PLMD5Tools11parseVectorIjEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RS2_IT_SaISE_EEi106650
_ZN4PLMD5Tools11parseVectorIxEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RS2_IT_SaISE_EEi14
_ZN4PLMD5Tools11set_to_zeroILj3EEEvRSt6vectorINS_13VectorGenericIXT_EEESaIS4_EE28739
_ZN4PLMD5Tools15convertNoexceptIdEEbT_RNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE31039
_ZN4PLMD5Tools15convertNoexceptIiEEbT_RNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE682751
_ZN4PLMD5Tools15convertNoexceptIjEEbT_RNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE5114023
_ZN4PLMD5Tools15convertNoexceptIlEEbT_RNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD5Tools15convertNoexceptImEEbT_RNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE19291
_ZN4PLMD5Tools15convertNoexceptIxEEbT_RNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD5Tools16removeDuplicatesINS_10AtomNumberEEEvRSt6vectorIT_SaIS4_EE17093
_ZN4PLMD5Tools16removeDuplicatesIjEEvRSt6vectorIT_SaIS3_EE74837
_ZN4PLMD5Tools22CriticalSectionWithKeyINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEE4stopERKS7_23
_ZN4PLMD5Tools22CriticalSectionWithKeyINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEE5startERKS7_23
_ZN4PLMD5Tools22CriticalSectionWithKeyINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEE7HandlerC2EPS8_RKS7_23
_ZN4PLMD5Tools22CriticalSectionWithKeyINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEE7HandlerD2Ev23
_ZN4PLMD5Tools22FastStringUnorderedMapINS_9Stopwatch5WatchEE4convESt17basic_string_viewIcSt11char_traitsIcEE13029
_ZN4PLMD5Tools22FastStringUnorderedMapINS_9Stopwatch5WatchEEixERKSt17basic_string_viewIcSt11char_traitsIcEE3024492
_ZN4PLMD5Tools22FastStringUnorderedMapIiE4convESt17basic_string_viewIcSt11char_traitsIcEE459062
_ZN4PLMD5Tools22FastStringUnorderedMapIiEC2ESt16initializer_listISt4pairIKSt17basic_string_viewIcSt11char_traitsIcEEiEE10312
_ZN4PLMD5Tools22FastStringUnorderedMapIiEixERKSt17basic_string_viewIcSt11char_traitsIcEE459062
_ZN4PLMD5Tools3pbcEd1783700944
_ZN4PLMD5Tools5parseINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEbRSt6vectorIS7_SaIS7_EERKS7_RT_i133561
_ZN4PLMD5Tools5parseIdEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RT_i33402
_ZN4PLMD5Tools5parseIeEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RT_i1080
_ZN4PLMD5Tools5parseIiEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RT_i7457
_ZN4PLMD5Tools5parseIjEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RT_i5808
_ZN4PLMD5Tools5parseImEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RT_i12
_ZN4PLMD5Tools5parseIxEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RT_i109
_ZN4PLMD5Tools7convertINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEENS_10AtomNumberEEEvRKT_RT0_5782
_ZN4PLMD5Tools7convertINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES7_EEvRKT_RT0_7030
_ZN4PLMD5Tools7convertINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdEEvRKT_RT0_14023976
_ZN4PLMD5Tools7convertINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEfEEvRKT_RT0_0
_ZN4PLMD5Tools7convertINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiEEvRKT_RT0_2472760
_ZN4PLMD5Tools7convertINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEjEEvRKT_RT0_1103
_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_938
_ZN4PLMD5Tools7convertIdNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKT_RT0_31039
_ZN4PLMD5Tools7convertIiNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKT_RT0_682751
_ZN4PLMD5Tools7convertIjNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKT_RT0_5114023
_ZN4PLMD5Tools7convertIlNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKT_RT0_0
_ZN4PLMD5Tools7convertImNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKT_RT0_19291
_ZN4PLMD5Tools7convertIxNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKT_RT0_0
_ZN4PLMD5Tools7fastpowEdi56216359
_ZN4PLMD5Tools9parseFlagERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EERKS7_Rb94243
_ZN4PLMDL18dp2cutoffNoStretchEv5719
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Tools.h.gcov.html b/coverage/tools/Tools.h.gcov.html new file mode 100644 index 000000000000..af909d24bd63 --- /dev/null +++ b/coverage/tools/Tools.h.gcov.html @@ -0,0 +1,597 @@ + + + + + + + + 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:949697.9 %
Date:2024-04-19 12:12:35Functions:505689.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             : #ifndef __PLUMED_tools_Tools_h
+      23             : #define __PLUMED_tools_Tools_h
+      24             : 
+      25             : #include "AtomNumber.h"
+      26             : #include "Vector.h"
+      27             : #include "Tensor.h"
+      28             : #include "small_vector/small_vector.h"
+      29             : #include <vector>
+      30             : #include <string>
+      31             : #include <cctype>
+      32             : #include <cstdio>
+      33             : #include <cmath>
+      34             : #include <limits>
+      35             : #include <algorithm>
+      36             : #include <sstream>
+      37             : #include <memory>
+      38             : #include <cstddef>
+      39             : #include <queue>
+      40             : #include <mutex>
+      41             : #include <filesystem>
+      42             : #include <utility>
+      43             : #include <unordered_map>
+      44             : #include <map>
+      45             : #include <condition_variable>
+      46             : 
+      47             : namespace PLMD {
+      48             : 
+      49             : class IFile;
+      50             : 
+      51             : /// \ingroup TOOLBOX
+      52             : /// Very small non-zero number
+      53             : constexpr double epsilon(std::numeric_limits<double>::epsilon());
+      54             : 
+      55             : /// \ingroup TOOLBOX
+      56             : /// Boltzman constant in kj/K
+      57             : constexpr double kBoltzmann(0.0083144621);
+      58             : 
+      59             : /// \ingroup TOOLBOX
+      60             : /// PI
+      61             : constexpr double pi(3.141592653589793238462643383279502884197169399375105820974944592307);
+      62             : 
+      63             : constexpr double dp2cutoff(6.25);
+      64             : 
+      65             : constexpr double dp2cutoffA=1.00193418799744762399; // 1.0/(1-std::exp(-dp2cutoff));
+      66             : constexpr double dp2cutoffB=-.00193418799744762399; // -std::exp(-dp2cutoff)/(1-std::exp(-dp2cutoff));
+      67             : 
+      68        5719 : inline static bool dp2cutoffNoStretch() {
+      69        5719 :   static const auto* res=std::getenv("PLUMED_DP2CUTOFF_NOSTRETCH");
+      70        5719 :   return res;
+      71             : }
+      72             : 
+      73             : /// \ingroup TOOLBOX
+      74             : /// Empty class which just contains several (static) tools
+      75             : class Tools {
+      76             : /// class to convert a string to a generic type T
+      77             :   template<class T>
+      78             :   static bool convertToAny(const std::string & str,T &t);
+      79             : /// class to convert a string to a real type T.
+      80             : /// T should be either float, double, or long double
+      81             :   template<class T>
+      82             :   static bool convertToReal(const std::string & str,T &t);
+      83             : /// class to convert a string to a int type T
+      84             :   template<class T>
+      85             :   static bool convertToInt(const std::string & str,T &t);
+      86             : /// @brief the  recursive part of the template fastpow implementation
+      87             :   template <int exp, typename T=double, std::enable_if_t< (exp >=0), bool> = true>
+      88             :   static inline /*consteval*/ T fastpow_rec(T base, T result);
+      89             : public:
+      90             : /// Split the line in words using separators.
+      91             : /// It also take into account parenthesis. Outer parenthesis found are removed from
+      92             : /// output, and the text between them is considered as a single word. Only the
+      93             : /// outer parenthesis are processed, to allow nesting them.
+      94             : /// parlevel, if not NULL, is increased or decreased according to the number of opened/closed parenthesis
+      95             :   static std::vector<std::string> getWords(std::string_view line,const char* sep=NULL,int* parlevel=NULL,const char* parenthesis="{", const bool& delete_parenthesis=true);
+      96             : /// Faster version
+      97             : /// This version does not parse parenthesis and operates on a preallocated small_vector of string_view's
+      98             :   static void getWordsSimple(gch::small_vector<std::string_view> & words,std::string_view line);
+      99             : /// Get a line from the file pointer ifile
+     100             :   static bool getline(FILE*,std::string & line);
+     101             : /// Get a parsed line from the file pointer ifile
+     102             : /// This function already takes care of joining continued lines and splitting the
+     103             : /// resulting line into an array of words
+     104             :   static bool getParsedLine(IFile&ifile,std::vector<std::string> & line, const bool trimcomments=true);
+     105             : /// compare two string in a case insensitive manner
+     106             :   static bool caseInSensStringCompare(const std::string & str1, const std::string &str2);
+     107             : /// Convert a string to a double, reading it
+     108             :   static bool convertNoexcept(const std::string & str,double & t);
+     109             : /// Convert a string to a long double, reading it
+     110             :   static bool convertNoexcept(const std::string & str,long double & t);
+     111             : /// Convert a string to a float, reading it
+     112             :   static bool convertNoexcept(const std::string & str,float & t);
+     113             : /// Convert a string to a int, reading it
+     114             :   static bool convertNoexcept(const std::string & str,int & t);
+     115             : /// Convert a string to a long int, reading it
+     116             :   static bool convertNoexcept(const std::string & str,long int & t);
+     117             : /// Convert a string to a long long int, reading it
+     118             :   static bool convertNoexcept(const std::string & str,long long int & t);
+     119             : /// Convert a string to an unsigned int, reading it
+     120             :   static bool convertNoexcept(const std::string & str,unsigned & t);
+     121             : /// Convert a string to a long unsigned int, reading it
+     122             :   static bool convertNoexcept(const std::string & str,long unsigned & t);
+     123             : /// Convert a string to a long long unsigned int, reading it
+     124             :   static bool convertNoexcept(const std::string & str,long long unsigned & t);
+     125             : /// Convert a string to a atom number, reading it
+     126             :   static bool convertNoexcept(const std::string & str,AtomNumber & t);
+     127             : /// Convert a string to a string (i.e. copy)
+     128             :   static bool convertNoexcept(const std::string & str,std::string & t);
+     129             : /// Convert anything into a string
+     130             :   template<typename T>
+     131             :   static bool convertNoexcept(T i,std::string & str);
+     132             : /// Convert anything into anything, throwing an exception in case there is an error
+     133             : /// Remove trailing blanks
+     134             :   static void trim(std::string & s);
+     135             : /// Remove leading blanks
+     136             :   static void ltrim(std::string & s);
+     137             : /// Remove trailing comments
+     138             :   static void trimComments(std::string & s);
+     139             : /// Apply pbc for a unitary cell
+     140             :   static double pbc(double);
+     141             : /// Retrieve a key from a vector of options.
+     142             : /// It finds a key starting with "key=" or equal to "key" and copy the
+     143             : /// part after the = on s. E.g.:
+     144             : /// line.push_back("aa=xx");
+     145             : /// getKey(line,"aa",s);
+     146             : /// will set s="xx"
+     147             :   static bool getKey(std::vector<std::string>& line,const std::string & key,std::string & s,int rep=-1);
+     148             : /// Find a keyword on the input line, eventually deleting it, and saving its value to val
+     149             :   template <typename T,typename U>
+     150    22358725 :   static void convert(const T & t,U & u) {
+     151    22359664 :     plumed_assert(convertNoexcept(t,u)) <<"Error converting  "<<t;
+     152    22358724 :   }
+     153             :   template <typename T>
+     154             :   static bool parse(std::vector<std::string>&line,const std::string&key,T&val,int rep=-1);
+     155             : /// Find a keyword on the input line, eventually deleting it, and saving its value to a vector
+     156             :   template <class T>
+     157             :   static bool parseVector(std::vector<std::string>&line,const std::string&key,std::vector<T>&val,int rep=-1);
+     158             : /// Find a keyword without arguments on the input line
+     159             :   static bool parseFlag(std::vector<std::string>&line,const std::string&key,bool&val);
+     160             : /// Find a keyword on the input line, just reporting if it exists or not
+     161             :   static bool findKeyword(const std::vector<std::string>&line,const std::string&key);
+     162             : /// Interpret atom ranges
+     163             :   static void interpretRanges(std::vector<std::string>&);
+     164             : /// Remove duplicates from a vector of type T
+     165             :   template <typename T>
+     166             :   static void removeDuplicates(std::vector<T>& vec);
+     167             : /// interpret ":" syntax for labels
+     168             :   static void interpretLabel(std::vector<std::string>&s);
+     169             : /// list files in a directory
+     170             :   static std::vector<std::string> ls(const std::string&);
+     171             : /// removes leading and trailing blanks from a string
+     172             :   static void stripLeadingAndTrailingBlanks( std::string& str );
+     173             : /// Extract the extensions from a file name.
+     174             : /// E.g.: extension("pippo.xyz")="xyz".
+     175             : /// It only returns extensions with a length between 1 and 4
+     176             : /// E.g.: extension("pippo.12345")="" whereas extenion("pippo.1234")="1234";
+     177             : /// It is also smart enough to detect "/", so that
+     178             : /// extension("pippo/.t")="" whereas extension("pippo/a.t")="t"
+     179             :   static std::string extension(const std::string&);
+     180             : /// Fast int power
+     181             :   static double fastpow(double base,int exp);
+     182             : /// Fast int power for power known at compile time
+     183             :   template <int exp, typename T=double>
+     184             :   static inline /*consteval*/ T fastpow(T base);
+     185             : /// Modified 0th-order Bessel function of the first kind
+     186             :   static double bessel0(const double& val);
+     187             : /// Check if a string full starts with string start.
+     188             : /// Same as full.find(start)==0
+     189             :   static bool startWith(const std::string & full,const std::string &start);
+     190             :   /**
+     191             :     Tool to create a vector of raw pointers from a vector of unique_pointers (const version).
+     192             :   Returning a vector is fast in C++11. It can be used in order to feed a vector<unique_ptr<T>>
+     193             :   to a function that takes a vector<T*>.
+     194             :   \verbatim
+     195             :   // some function that takes a vec
+     196             :   void func(std::vector<Data*> & vec);
+     197             :   std::vector<std::unique_ptr<Data>> vec;
+     198             :   // func(vec); // does not compile
+     199             :   func(Tools::unique2raw(vec)); // compiles
+     200             :   \endverbatim
+     201             :   Notice that the conversion is fast but takes
+     202             :   some time to allocate the new vector and copy the pointers. In case the function
+     203             :   acting on the vector<T*> is very fast and we do not want to add significant overhead,
+     204             :   it might be convenient to store a separate set of raw pointers.
+     205             :   \verbatim
+     206             :   // some function that takes a vec
+     207             :   void func(std::vector<Data*> & vec);
+     208             :   std::vector<std::unique_ptr<Data>> vec;
+     209             : 
+     210             :   // conversion done only once:
+     211             :   auto vec_ptr=Tools::unique2raw(vec);
+     212             : 
+     213             :   for(int i=0;i<1000;i++){
+     214             :     func(vec_ptr);
+     215             :   }
+     216             :   \endverbatim
+     217             :   */
+     218             :   template <typename T>
+     219             :   static std::vector<T*> unique2raw(const std::vector<std::unique_ptr<T>>&);
+     220             : /// Tool to create a vector of raw pointers from a vector of unique_pointers.
+     221             : /// See the non const version.
+     222             :   template <typename T>
+     223             :   static std::vector<const T*> unique2raw(const std::vector<std::unique_ptr<const T>>&);
+     224             : /// Tiny class that changes directory and comes back when going out of scope.
+     225             : /// In case system calls to change dir are not available it throws an exception.
+     226             : /// \warning By construction, changing directory breaks thread safety! Use with care.
+     227             :   class DirectoryChanger {
+     228             :     const std::filesystem::path path;
+     229             :   public:
+     230             :     explicit DirectoryChanger(const char*path);
+     231             :     ~DirectoryChanger();
+     232             :   };
+     233             : 
+     234             :   template<class T, class... Args>
+     235             :   static auto make_unique(Args&&... args) {
+     236      140788 :     return std::make_unique<T>(std::forward<Args>(args)...);
+     237             :   }
+     238             : 
+     239             :   static void set_to_zero(double*ptr,unsigned n) {
+     240     1276640 :     for(unsigned i=0; i<n; i++) ptr[i]=0.0;
+     241             :   }
+     242             : 
+     243             :   template<unsigned n>
+     244       28739 :   static void set_to_zero(std::vector<VectorGeneric<n>> & vec) {
+     245       28739 :     unsigned s=vec.size();
+     246       28739 :     if(s==0) return;
+     247       28739 :     set_to_zero(&vec[0][0],s*n);
+     248             :   }
+     249             : 
+     250             :   template<unsigned n,unsigned m>
+     251             :   static void set_to_zero(std::vector<TensorGeneric<n,m>> & vec) {
+     252             :     unsigned s=vec.size();
+     253             :     if(s==0) return;
+     254             :     set_to_zero(&vec[0](0,0),s*n*m);
+     255             :   }
+     256             : 
+     257             :   static std::unique_ptr<std::lock_guard<std::mutex>> molfile_lock();
+     258             :   /// Build a concatenated exception message.
+     259             :   /// Should be called with an in-flight exception.
+     260             :   static std::string concatenateExceptionMessages();
+     261             : 
+     262             : 
+     263             :   /// Tiny class implementing faster std::string_view access to an unordered_map
+     264             :   /// It exposes a limited number of methods of std::unordered_map. Others could be added.
+     265             :   /// Importantly, when it is accessed via a std::string_view, the access does not
+     266             :   /// require constructing a std::string and is thus faster.
+     267             :   /// Deletion would be slower instead. It's not even implemented yet.
+     268             :   template<class T>
+     269      806394 :   class FastStringUnorderedMap {
+     270             :     std::unordered_map<std::string_view,T> map;
+     271             :     std::vector<std::unique_ptr<const char[]>> keys;
+     272             : 
+     273             :     // see https://stackoverflow.com/questions/34596768/stdunordered-mapfind-using-a-type-different-than-the-key-type
+     274      472091 :     std::unique_ptr<const char[]> conv(std::string_view str) {
+     275      472091 :       auto p=std::make_unique<char[]>(str.size()+1);
+     276             :       std::memcpy(p.get(), str.data(), str.size()+1);
+     277      472091 :       return p;
+     278             :     }
+     279             : 
+     280             :   public:
+     281             : 
+     282             :     FastStringUnorderedMap() = default;
+     283       10312 :     FastStringUnorderedMap(std::initializer_list<std::pair<const std::string_view,T>> init) {
+     284      469374 :       for(const auto & c : init) {
+     285      459062 :         (*this)[c.first]=c.second;
+     286             :       }
+     287       10312 :     }
+     288             : 
+     289     3483554 :     T& operator[]( const std::string_view & key ) {
+     290             :       auto f=map.find(key);
+     291     3483554 :       if(f!=map.end()) return f->second;
+     292      944182 :       keys.push_back(conv(key));
+     293      472091 :       return map[keys.back().get()];
+     294             :     }
+     295             : 
+     296             :     auto begin() {
+     297             :       return map.begin();
+     298             :     }
+     299             :     auto end() {
+     300             :       return map.end();
+     301             :     }
+     302             :     auto begin() const {
+     303             :       return map.begin();
+     304             :     }
+     305             :     auto end() const {
+     306             :       return map.end();
+     307             :     }
+     308             :     auto find(const std::string_view & key) {
+     309             :       return map.find(key);
+     310             :     }
+     311             :     auto find(const std::string_view & key) const {
+     312             :       return map.find(key);
+     313             :     }
+     314             :   };
+     315             : 
+     316             :   /// Utility to create named critical sections
+     317             :   /// Key should be usable in a std::map
+     318             :   template<class Key>
+     319             :   class CriticalSectionWithKey {
+     320             :     std::mutex mutex;
+     321             :     std::condition_variable notify;
+     322             :     std::map<Key, int> in_progress;
+     323             :   public:
+     324          23 :     void start(const Key & key) {
+     325          23 :       std::unique_lock<std::mutex> lock(mutex);
+     326         130 :       while (in_progress[key] > 0) {
+     327             :         // Wait if this command is already in progress.
+     328         107 :         notify.wait(lock);
+     329             :       }
+     330             :       // Mark this command as in progress.
+     331          23 :       in_progress[key]++;
+     332          23 :     }
+     333          23 :     void stop(const Key & key) {
+     334          23 :       std::unique_lock<std::mutex> lock(mutex);
+     335             :       // Mark this command as completed.
+     336          23 :       in_progress[key]--;
+     337             :       // Notify other threads that may be waiting for this command to complete.
+     338          23 :       notify.notify_all();
+     339          23 :     }
+     340             :     class Handler {
+     341             :       CriticalSectionWithKey* section{nullptr};
+     342             :       Key key;
+     343          23 :       Handler(CriticalSectionWithKey* section,const Key& key):
+     344          23 :         section(section),
+     345          23 :         key(key)
+     346             :       {
+     347          23 :         section->start(key);
+     348          23 :       }
+     349             :       friend class CriticalSectionWithKey;
+     350             :     public:
+     351             :       /// Default constructor
+     352             :       Handler() = default;
+     353             :       /// Default copy constructor is deleted (not copyable)
+     354             :       Handler(const Handler & handler) = delete;
+     355             :       /// Default copy assignment is deleted (not copyable)
+     356             :       Handler & operator=(const Handler & handler) = delete;
+     357             :       /// Move constructor.
+     358             :       Handler(Handler && handler) noexcept :
+     359             :         section(handler.section),
+     360             :         key(std::move(handler.key))
+     361             :       {
+     362             :         handler.section=nullptr;
+     363             :       };
+     364             :       /// Move assignment.
+     365             :       Handler & operator=(Handler && handler) noexcept {
+     366             :         if(this!=&handler) {
+     367             :           if(section) section->stop(key);
+     368             :           section=handler.section;
+     369             :           key=std::move(handler.key);
+     370             :         }
+     371             :         handler.watch=nullptr;
+     372             :         return *this;
+     373             :       }
+     374             :       /// Destructor
+     375          23 :       ~Handler() {
+     376          23 :         if(section) section->stop(key);
+     377          23 :       }
+     378             :     };
+     379             : 
+     380             :     Handler startStop(const Key & key) {
+     381          23 :       return Handler(this,key);
+     382             :     }
+     383             : 
+     384             :   };
+     385             : 
+     386             : };
+     387             : 
+     388             : template <class T>
+     389      181429 : bool Tools::parse(std::vector<std::string>&line,const std::string&key,T&val,int rep) {
+     390             :   std::string s;
+     391      362858 :   if(!getKey(line,key+"=",s,rep)) return false;
+     392      114134 :   if(s.length()>0 && !convertNoexcept(s,val))return false;
+     393             :   return true;
+     394             : }
+     395             : 
+     396             : template <class T>
+     397      214717 : bool Tools::parseVector(std::vector<std::string>&line,const std::string&key,std::vector<T>&val,int rep) {
+     398             :   std::string s;
+     399      429434 :   if(!getKey(line,key+"=",s,rep)) return false;
+     400             :   val.clear();
+     401      193082 :   std::vector<std::string> words=getWords(s,"\t\n ,");
+     402     3601070 :   for(unsigned i=0; i<words.size(); ++i) {
+     403             :     T v;
+     404     3407988 :     std::string s=words[i];
+     405     3407988 :     const std::string multi("@replicas:");
+     406     3407988 :     if(rep>=0 && startWith(s,multi)) {
+     407           6 :       s=s.substr(multi.length(),s.length());
+     408           6 :       std::vector<std::string> words=getWords(s,"\t\n ,");
+     409           6 :       plumed_assert(rep<static_cast<int>(words.size()));
+     410           6 :       s=words[rep];
+     411           6 :     }
+     412     3407988 :     if(!convertNoexcept(s,v))return false;
+     413     3407988 :     val.push_back(v);
+     414             :   }
+     415             :   return true;
+     416      193082 : }
+     417             : 
+     418             : template<typename T>
+     419       91930 : void Tools::removeDuplicates(std::vector<T>& vec)
+     420             : {
+     421       91930 :   std::sort(vec.begin(), vec.end());
+     422       91930 :   vec.erase(std::unique(vec.begin(), vec.end()), vec.end());
+     423       91930 : }
+     424             : 
+     425             : inline
+     426       94243 : bool Tools::parseFlag(std::vector<std::string>&line,const std::string&key,bool&val) {
+     427      580090 :   for(auto p=line.begin(); p!=line.end(); ++p) {
+     428      496996 :     if(key==*p) {
+     429       11149 :       val=true;
+     430             :       line.erase(p);
+     431             :       return true;
+     432             :     }
+     433             :   }
+     434             :   return false;
+     435             : }
+     436             : 
+     437             : /// beware: this brings any number into a pbc that ranges from -0.5 to 0.5
+     438             : inline
+     439  1783700944 : double Tools::pbc(double x) {
+     440             : #ifdef __PLUMED_PBC_WHILE
+     441             :   while (x>0.5) x-=1.0;
+     442             :   while (x<-0.5) x+=1.0;
+     443             :   return x;
+     444             : #else
+     445             :   if constexpr (std::numeric_limits<int>::round_style == std::round_toward_zero) {
+     446             :     constexpr double offset=100.0;
+     447  1783700944 :     const double y=x+offset;
+     448  1783700944 :     if(y>=0) return y-int(y+0.5);
+     449        4578 :     else     return y-int(y-0.5);
+     450             :   } else if constexpr (std::numeric_limits<int>::round_style == std::round_to_nearest) {
+     451             :     return x-int(x);
+     452             :   } else return x-floor(x+0.5);
+     453             : #endif
+     454             : }
+     455             : 
+     456             : template<typename T>
+     457     5847104 : bool Tools::convertNoexcept(T i,std::string & str) {
+     458     5847104 :   std::ostringstream ostr;
+     459      682751 :   ostr<<i;
+     460     5847104 :   str=ostr.str();
+     461     5847104 :   return true;
+     462     5847104 : }
+     463             : 
+     464             : inline
+     465    56216359 : double Tools::fastpow(double base, int exp)
+     466             : {
+     467    56216359 :   if(exp<0) {
+     468           0 :     exp=-exp;
+     469           0 :     base=1.0/base;
+     470             :   }
+     471             :   double result = 1.0;
+     472   288851532 :   while (exp)
+     473             :   {
+     474   199034981 :     if (exp & 1)
+     475   140786815 :       result *= base;
+     476   199034981 :     exp >>= 1;
+     477   199034981 :     base *= base;
+     478             :   }
+     479             : 
+     480    56216359 :   return result;
+     481             : }
+     482             : 
+     483             : template <int exp, typename T, std::enable_if_t< (exp >=0), bool>>
+     484             : inline T Tools::fastpow_rec(T const base, T result) {
+     485             :   if constexpr (exp == 0) {
+     486             :     return result;
+     487             :   }
+     488             :   if constexpr (exp & 1) {
+     489    19283644 :     result *= base;
+     490             :   }
+     491    11328670 :   return fastpow_rec<(exp>>1),T> (base*base, result);
+     492             : }
+     493             : 
+     494             : template <int exp, typename T>
+     495             : inline T Tools::fastpow(T const base) {
+     496             :   if constexpr (exp<0) {
+     497             :     return  fastpow_rec<-exp,T>(1.0/base,1.0);
+     498             :   } else {
+     499             :     return fastpow_rec<exp,T>(base, 1.0);
+     500             :   }
+     501             : }
+     502             : 
+     503             : template<typename T>
+     504        2307 : std::vector<T*> Tools::unique2raw(const std::vector<std::unique_ptr<T>> & x) {
+     505        2307 :   std::vector<T*> v(x.size());
+     506        3681 :   for(unsigned i=0; i<x.size(); i++) v[i]=x[i].get();
+     507        2307 :   return v;
+     508             : }
+     509             : 
+     510             : template<typename T>
+     511             : std::vector<const T*> Tools::unique2raw(const std::vector<std::unique_ptr<const T>> & x) {
+     512             :   std::vector<const T*> v(x.size());
+     513             :   for(unsigned i=0; i<x.size(); i++) v[i]=x[i].get();
+     514             :   return v;
+     515             : }
+     516             : 
+     517             : }
+     518             : 
+     519             : #endif
+     520             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Torsion.cpp.func-sort-c.html b/coverage/tools/Torsion.cpp.func-sort-c.html new file mode 100644 index 000000000000..b8eed6f2ebeb --- /dev/null +++ b/coverage/tools/Torsion.cpp.func-sort-c.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - tools/Torsion.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Torsion.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:283580.0 %
Date:2024-04-19 12:12:35Functions:1250.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD7Torsion7computeERKNS_13VectorGenericILj3EEES4_S4_0
_ZNK4PLMD7Torsion7computeERKNS_13VectorGenericILj3EEES4_S4_RS2_S5_S5_1294046
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Torsion.cpp.func.html b/coverage/tools/Torsion.cpp.func.html new file mode 100644 index 000000000000..af3e4b83b0f8 --- /dev/null +++ b/coverage/tools/Torsion.cpp.func.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - tools/Torsion.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Torsion.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:283580.0 %
Date:2024-04-19 12:12:35Functions:1250.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD7Torsion7computeERKNS_13VectorGenericILj3EEES4_S4_0
_ZNK4PLMD7Torsion7computeERKNS_13VectorGenericILj3EEES4_S4_RS2_S5_S5_1294046
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Torsion.cpp.gcov.html b/coverage/tools/Torsion.cpp.gcov.html new file mode 100644 index 000000000000..47aaad15e369 --- /dev/null +++ b/coverage/tools/Torsion.cpp.gcov.html @@ -0,0 +1,157 @@ + + + + + + + + LCOV - plumed test coverage - tools/Torsion.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Torsion.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:283580.0 %
Date:2024-04-19 12:12:35Functions: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     1294046 : double Torsion::compute(const Vector& v1,const Vector& v2,const Vector& v3,Vector& d1,Vector& d2,Vector& d3)const {
+      40             : 
+      41     1294046 :   const double modv2(1./v2.modulo());
+      42     1294046 :   const Vector nv2(v2*modv2);
+      43     1294046 :   const Tensor dnv2_v2((Tensor::identity()-extProduct(nv2,nv2))*modv2);
+      44             : 
+      45     1294046 :   const Vector a(crossProduct(v2,v1));
+      46     1294046 :   const Tensor da_dv2(dcrossDv1(v2,v1));
+      47     1294046 :   const Tensor da_dv1(dcrossDv2(v2,v1));
+      48     1294046 :   const Vector b(crossProduct(v3,v2));
+      49     1294046 :   const Tensor db_dv3(dcrossDv1(v3,v2));
+      50     1294046 :   const Tensor db_dv2(dcrossDv2(v3,v2));
+      51     1294046 :   const double cosangle=dotProduct(a,b);
+      52     1294046 :   const Vector dcosangle_dv1=matmul(b,da_dv1);
+      53     1294046 :   const Vector dcosangle_dv2=matmul(b,da_dv2) + matmul(a,db_dv2);
+      54     1294046 :   const Vector dcosangle_dv3=matmul(a,db_dv3);
+      55             : 
+      56     1294046 :   const Vector cab(crossProduct(a,b));
+      57     1294046 :   const Tensor dcab_dv1(matmul(dcrossDv1(a,b),da_dv1));
+      58     1294046 :   const Tensor dcab_dv2(matmul(dcrossDv1(a,b),da_dv2) + matmul(dcrossDv2(a,b),db_dv2));
+      59     1294046 :   const Tensor dcab_dv3(matmul(dcrossDv2(a,b),db_dv3));
+      60             : 
+      61     1294046 :   const double sinangle=dotProduct(cab,nv2);
+      62     1294046 :   const Vector dsinangle_dv1=matmul(nv2,dcab_dv1);
+      63     1294046 :   const Vector dsinangle_dv2=matmul(nv2,dcab_dv2)+matmul(cab,dnv2_v2);
+      64     1294046 :   const Vector dsinangle_dv3=matmul(nv2,dcab_dv3);
+      65             : 
+      66     1294046 :   const double torsion=std::atan2(-sinangle,cosangle);
+      67             : // this is required since v1 and v3 are not normalized:
+      68     1294046 :   const double invR2=1.0/(cosangle*cosangle+sinangle*sinangle);
+      69             : 
+      70     1294046 :   d1= ( -dsinangle_dv1*cosangle + sinangle * dcosangle_dv1 ) *invR2;
+      71     1294046 :   d2= ( -dsinangle_dv2*cosangle + sinangle * dcosangle_dv2 ) *invR2;
+      72     1294046 :   d3= ( -dsinangle_dv3*cosangle + sinangle * dcosangle_dv3 ) *invR2;
+      73             : 
+      74     1294046 :   return torsion;
+      75             : }
+      76             : 
+      77             : }
+      78             : 
+      79             : 
+      80             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Tree.cpp.func-sort-c.html b/coverage/tools/Tree.cpp.func-sort-c.html new file mode 100644 index 000000000000..38c2aa66e338 --- /dev/null +++ b/coverage/tools/Tree.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - tools/Tree.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Tree.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4242100.0 %
Date:2024-04-19 12:12:35Functions: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 000000000000..8ed99da95afd --- /dev/null +++ b/coverage/tools/Tree.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - tools/Tree.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Tree.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4242100.0 %
Date:2024-04-19 12:12:35Functions: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 000000000000..3d73e1b8f733 --- /dev/null +++ b/coverage/tools/Tree.cpp.gcov.html @@ -0,0 +1,201 @@ + + + + + + + + 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:4242100.0 %
Date:2024-04-19 12:12:35Functions: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             :   std::vector<Vector> positions;
+      53             : 
+      54             :   // remove atoms not in PDB file
+      55             :   std::vector<AtomNumber> addtotree, addtoroot;
+      56             :   std::vector<AtomNumber> newatoms;
+      57           2 :   newatoms.reserve(atoms.size());
+      58           2 :   positions.reserve(atoms.size());
+      59           2 :   tree.reserve(atoms.size());
+      60           2 :   root_.reserve(atoms.size());
+      61           2 :   if(!moldat_->checkForAtom(atoms[0])) plumed_merror("The first atom in the list should be present in the PDB file");
+      62             :   // store first atom
+      63           2 :   newatoms.push_back(atoms[0]);
+      64           2 :   positions.push_back(moldat_->getPosition(atoms[0]));
+      65         245 :   for(unsigned i=1; i<atoms.size(); ++i) {
+      66         243 :     if(!moldat_->checkForAtom(atoms[i])) {
+      67             :       // store this atom for later
+      68          61 :       addtotree.push_back(atoms[i]);
+      69             :       // along with its root (the previous atom)
+      70          61 :       addtoroot.push_back(atoms[i-1]);
+      71             :     } else {
+      72         182 :       newatoms.push_back(atoms[i]);
+      73         364 :       positions.push_back(moldat_->getPosition(atoms[i]));
+      74             :     }
+      75             :   }
+      76             :   // reassign atoms
+      77           2 :   atoms=newatoms;
+      78             :   // start EMST
+      79           2 :   std::vector<bool> intree(atoms.size(), false);
+      80           2 :   std::vector<double> mindist(atoms.size(), std::numeric_limits<double>::max());
+      81             :   // initialize tree with first atom
+      82           2 :   mindist[0] = 0.0;
+      83             :   // loops
+      84         186 :   for(unsigned i=0; i<atoms.size(); ++i) {
+      85             :     int selected_vertex = -1;
+      86       19034 :     for(unsigned j=0; j<atoms.size(); ++j) {
+      87        9517 :       if( !intree[j] && (selected_vertex==-1 || mindist[j] < mindist[selected_vertex]) )
+      88        1078 :         selected_vertex = j;
+      89             :     }
+      90             :     // add to tree
+      91         184 :     plumed_assert(selected_vertex>=0);
+      92         184 :     tree.push_back(atoms[selected_vertex]);
+      93             :     intree[selected_vertex] = true;
+      94             :     // update distances
+      95             :     double minroot = std::numeric_limits<double>::max();
+      96             :     int iroot = -1;
+      97       19034 :     for(unsigned j=0; j<atoms.size(); ++j) {
+      98       18850 :       double dist = delta(positions[selected_vertex], positions[j]).modulo2();
+      99       18850 :       if(dist < mindist[j]) mindist[j] = dist;
+     100       22401 :       if(dist < minroot && intree[j] && dist>0.0) {
+     101             :         minroot = dist;
+     102        2822 :         iroot = j;
+     103             :       }
+     104             :     }
+     105             :     // add to root vector
+     106         184 :     if(iroot>=0) root_.push_back(atoms[iroot]);
+     107             :   }
+     108             : 
+     109             :   // now re-add atoms not present in the PDB
+     110          63 :   for(unsigned i=0; i<addtotree.size(); ++i) {
+     111          61 :     tree.push_back(addtotree[i]);
+     112          61 :     root_.push_back(addtoroot[i]);
+     113             :   }
+     114             : 
+     115             :   // return
+     116           2 :   return tree;
+     117             : }
+     118             : 
+     119           2 : std::vector<AtomNumber> Tree::getRoot() const
+     120             : {
+     121           2 :   return root_;
+     122             : }
+     123             : 
+     124             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Tree.h.func-sort-c.html b/coverage/tools/Tree.h.func-sort-c.html new file mode 100644 index 000000000000..e5c29c868f40 --- /dev/null +++ b/coverage/tools/Tree.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage - tools/Tree.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Tree.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-04-19 12:12:35Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Tree.h.func.html b/coverage/tools/Tree.h.func.html new file mode 100644 index 000000000000..1815e7a1db0c --- /dev/null +++ b/coverage/tools/Tree.h.func.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage - tools/Tree.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Tree.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-04-19 12:12:35Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Tree.h.gcov.html b/coverage/tools/Tree.h.gcov.html new file mode 100644 index 000000000000..cedab0d075a5 --- /dev/null +++ b/coverage/tools/Tree.h.gcov.html @@ -0,0 +1,129 @@ + + + + + + + + LCOV - plumed test coverage - tools/Tree.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Tree.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-04-19 12:12:35Functions: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 000000000000..f7e83ebf5309 --- /dev/null +++ b/coverage/tools/TypesafePtr.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - tools/TypesafePtr.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - TypesafePtr.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1414100.0 %
Date:2024-04-19 12:12:35Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11TypesafePtr9extra_msgB5cxx11Ev8
_ZN4PLMD11TypesafePtr11fromSafePtrEPv18328
_ZNK4PLMD11TypesafePtr4copyEv991917
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/TypesafePtr.cpp.func.html b/coverage/tools/TypesafePtr.cpp.func.html new file mode 100644 index 000000000000..a53382aa4982 --- /dev/null +++ b/coverage/tools/TypesafePtr.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - tools/TypesafePtr.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - TypesafePtr.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1414100.0 %
Date:2024-04-19 12:12:35Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11TypesafePtr11fromSafePtrEPv18328
_ZN4PLMD11TypesafePtr9extra_msgB5cxx11Ev8
_ZNK4PLMD11TypesafePtr4copyEv991917
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/TypesafePtr.cpp.gcov.html b/coverage/tools/TypesafePtr.cpp.gcov.html new file mode 100644 index 000000000000..ade6c80f82aa --- /dev/null +++ b/coverage/tools/TypesafePtr.cpp.gcov.html @@ -0,0 +1,134 @@ + + + + + + + + LCOV - plumed test coverage - tools/TypesafePtr.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - TypesafePtr.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1414100.0 %
Date:2024-04-19 12:12:35Functions: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       18328 : TypesafePtr TypesafePtr::fromSafePtr(void* safe) {
+      30             :   auto s=(plumed_safeptr_x*)safe;
+      31       18328 :   return TypesafePtr(const_cast<void*>(s->ptr), s->nelem, s->shape, s->flags);
+      32             : }
+      33             : 
+      34      991917 : TypesafePtr TypesafePtr::copy() const {
+      35      991917 :   auto passbyvalue=((flags>>25)&0x7)==1;
+      36      991917 :   if(passbyvalue) throw ExceptionTypeError()<<"PLUMED is trying to copy the pointer of an object passed by value";
+      37      991917 :   auto forbidstore=flags&0x10000000;
+      38      991917 :   if(forbidstore) throw ExceptionTypeError()<<"PLUMED is trying to copy the pointer of an object for which this was forbidden";
+      39             :   TypesafePtr ret;
+      40      991917 :   ret.ptr=ptr;
+      41      991917 :   ret.flags=flags;
+      42      991917 :   ret.nelem=nelem;
+      43      991917 :   ret.shape=shape;
+      44      991917 :   return ret;
+      45             : }
+      46             : 
+      47           8 : std::string TypesafePtr::extra_msg() {
+      48             :   const char *text = "\n"
+      49             :                      "If you are sure your code is correct you can disable this check with export PLUMED_TYPESAFE_IGNORE=yes\n"
+      50             :                      "In case this is necessary, please report an issue to developers of PLUMED and of the MD code\n"
+      51             :                      "See also https://github.com/plumed/plumed2/pull/653";
+      52           8 :   return std::string(text);
+      53             : }
+      54             : 
+      55             : }
+      56             : 
+      57             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/TypesafePtr.h.func-sort-c.html b/coverage/tools/TypesafePtr.h.func-sort-c.html new file mode 100644 index 000000000000..55ad5fe5864b --- /dev/null +++ b/coverage/tools/TypesafePtr.h.func-sort-c.html @@ -0,0 +1,293 @@ + + + + + + + + LCOV - plumed test coverage - tools/TypesafePtr.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - TypesafePtr.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10812487.1 %
Date:2024-04-19 12:12:35Functions: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
_ZN4PLMD11TypesafePtrC2EjmPKm4
_ZNK4PLMD11TypesafePtr8type_strB5cxx11Ev5
_ZNK4PLMD11TypesafePtr8get_privIPKiEEPT_mPKmb116
_ZNK4PLMD11TypesafePtr3setIlEEvT_149
_ZN4PLMD17typesafePtrSizeofIlEEmv166
_ZNK4PLMD11TypesafePtr8get_privIlEEPT_mPKmb166
_ZNK4PLMD11TypesafePtr8get_privI8_IO_FILEEEPT_mPKmb990
_ZNK4PLMD11TypesafePtr8get_privIKvEEPT_mPKmb1727
_ZNK4PLMD11TypesafePtr8get_privIKcEEPT_mPKmb2783
_ZNK4PLMD11TypesafePtr8get_privIKPKcEEPT_mPKmb5056
_ZNK4PLMD11TypesafePtr3setIiEEvT_5479
_ZN4PLMD11TypesafePtrC2EimPKm6915
_ZNK4PLMD11TypesafePtr3setIdEEvT_7267
_ZN4PLMD11TypesafePtrC2EdmPKm7449
_ZN4PLMD17typesafePtrSizeofIKcEEmv7764
_ZNK4PLMD11TypesafePtr3getIdEENSt9enable_ifIXntsrSt10is_pointerIT_E5valueES4_E4typeEv7975
_ZNK4PLMD11TypesafePtr3getIiEENSt9enable_ifIXntsrSt10is_pointerIT_E5valueES4_E4typeEv24536
_ZNK4PLMD11TypesafePtr8get_privIKiEEPT_mPKmb25514
_ZN4PLMD17typesafePtrSizeofIKiEEmv25556
_ZNK4PLMD11TypesafePtr3getIPdEENSt9enable_ifIXsrSt10is_pointerIT_E5valueES5_E4typeEv216899
_ZNK4PLMD11TypesafePtr3getIPdEET_St16initializer_listImE245451
_ZN4PLMD11TypesafePtrC2ExmPKm264721
_ZNK4PLMD11TypesafePtr3getIPiEENSt9enable_ifIXsrSt10is_pointerIT_E5valueES5_E4typeEv265803
_ZN4PLMD17typesafePtrSizeofIKxEEmv268660
_ZNK4PLMD11TypesafePtr3getIxEENSt9enable_ifIXntsrSt10is_pointerIT_E5valueES4_E4typeEv268660
_ZNK4PLMD11TypesafePtr8get_privIKxEEPT_mPKmb268660
_ZN4PLMD17typesafePtrSizeofIiEEmv271275
_ZNK4PLMD11TypesafePtr8get_privIiEEPT_mPKmb271282
_ZNK4PLMD11TypesafePtr3getIPKdEET_St16initializer_listImE345870
_ZNK4PLMD11TypesafePtr3getIPKdEENSt9enable_ifIXsrSt10is_pointerIT_E5valueES6_E4typeEv353243
_ZN4PLMD17typesafePtrSizeofIdEEmv481962
_ZNK4PLMD11TypesafePtr8get_privIdEEPT_mPKmb482109
_ZN4PLMD17typesafePtrSizeofIKdEEmv755625
_ZNK4PLMD11TypesafePtr8get_privIKdEEPT_mPKmb755901
_ZN4PLMD11TypesafePtraSEOS0_991917
_ZN4PLMD11TypesafePtr10init_shapeEPKm1419219
_ZN4PLMDL20typesafePtrSkipCheckEv1814305
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/TypesafePtr.h.func.html b/coverage/tools/TypesafePtr.h.func.html new file mode 100644 index 000000000000..ec24f18e6c54 --- /dev/null +++ b/coverage/tools/TypesafePtr.h.func.html @@ -0,0 +1,293 @@ + + + + + + + + LCOV - plumed test coverage - tools/TypesafePtr.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - TypesafePtr.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10812487.1 %
Date:2024-04-19 12:12:35Functions:405572.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11TypesafePtr10init_shapeEPKm1419219
_ZN4PLMD11TypesafePtrC2EdmPKm7449
_ZN4PLMD11TypesafePtrC2EfmPKm0
_ZN4PLMD11TypesafePtrC2EimPKm6915
_ZN4PLMD11TypesafePtrC2EjmPKm4
_ZN4PLMD11TypesafePtrC2ExmPKm264721
_ZN4PLMD11TypesafePtraSEOS0_991917
_ZN4PLMD17typesafePtrSizeofI8_IO_FILEEEmv0
_ZN4PLMD17typesafePtrSizeofIKcEEmv7764
_ZN4PLMD17typesafePtrSizeofIKdEEmv755625
_ZN4PLMD17typesafePtrSizeofIKfEEmv0
_ZN4PLMD17typesafePtrSizeofIKiEEmv25556
_ZN4PLMD17typesafePtrSizeofIKjEEmv0
_ZN4PLMD17typesafePtrSizeofIKlEEmv0
_ZN4PLMD17typesafePtrSizeofIKxEEmv268660
_ZN4PLMD17typesafePtrSizeofIdEEmv481962
_ZN4PLMD17typesafePtrSizeofIfEEmv1
_ZN4PLMD17typesafePtrSizeofIiEEmv271275
_ZN4PLMD17typesafePtrSizeofIlEEmv166
_ZN4PLMDL20typesafePtrSkipCheckEv1814305
_ZNK4PLMD11TypesafePtr3getIPKdEENSt9enable_ifIXsrSt10is_pointerIT_E5valueES6_E4typeEv353243
_ZNK4PLMD11TypesafePtr3getIPKdEET_St16initializer_listImE345870
_ZNK4PLMD11TypesafePtr3getIPKfEENSt9enable_ifIXsrSt10is_pointerIT_E5valueES6_E4typeEv0
_ZNK4PLMD11TypesafePtr3getIPKfEET_St16initializer_listImE0
_ZNK4PLMD11TypesafePtr3getIPdEENSt9enable_ifIXsrSt10is_pointerIT_E5valueES5_E4typeEv216899
_ZNK4PLMD11TypesafePtr3getIPdEET_St16initializer_listImE245451
_ZNK4PLMD11TypesafePtr3getIPfEENSt9enable_ifIXsrSt10is_pointerIT_E5valueES5_E4typeEv0
_ZNK4PLMD11TypesafePtr3getIPfEET_St16initializer_listImE0
_ZNK4PLMD11TypesafePtr3getIPiEENSt9enable_ifIXsrSt10is_pointerIT_E5valueES5_E4typeEv265803
_ZNK4PLMD11TypesafePtr3getIdEENSt9enable_ifIXntsrSt10is_pointerIT_E5valueES4_E4typeEv7975
_ZNK4PLMD11TypesafePtr3getIfEENSt9enable_ifIXntsrSt10is_pointerIT_E5valueES4_E4typeEv0
_ZNK4PLMD11TypesafePtr3getIiEENSt9enable_ifIXntsrSt10is_pointerIT_E5valueES4_E4typeEv24536
_ZNK4PLMD11TypesafePtr3getIjEENSt9enable_ifIXntsrSt10is_pointerIT_E5valueES4_E4typeEv0
_ZNK4PLMD11TypesafePtr3getIlEENSt9enable_ifIXntsrSt10is_pointerIT_E5valueES4_E4typeEv0
_ZNK4PLMD11TypesafePtr3getIxEENSt9enable_ifIXntsrSt10is_pointerIT_E5valueES4_E4typeEv268660
_ZNK4PLMD11TypesafePtr3setIdEEvT_7267
_ZNK4PLMD11TypesafePtr3setIfEEvT_1
_ZNK4PLMD11TypesafePtr3setIiEEvT_5479
_ZNK4PLMD11TypesafePtr3setIlEEvT_149
_ZNK4PLMD11TypesafePtr8get_privI8_IO_FILEEEPT_mPKmb990
_ZNK4PLMD11TypesafePtr8get_privIKPKcEEPT_mPKmb5056
_ZNK4PLMD11TypesafePtr8get_privIKcEEPT_mPKmb2783
_ZNK4PLMD11TypesafePtr8get_privIKdEEPT_mPKmb755901
_ZNK4PLMD11TypesafePtr8get_privIKfEEPT_mPKmb0
_ZNK4PLMD11TypesafePtr8get_privIKiEEPT_mPKmb25514
_ZNK4PLMD11TypesafePtr8get_privIKjEEPT_mPKmb0
_ZNK4PLMD11TypesafePtr8get_privIKlEEPT_mPKmb0
_ZNK4PLMD11TypesafePtr8get_privIKvEEPT_mPKmb1727
_ZNK4PLMD11TypesafePtr8get_privIKxEEPT_mPKmb268660
_ZNK4PLMD11TypesafePtr8get_privIPKiEEPT_mPKmb116
_ZNK4PLMD11TypesafePtr8get_privIdEEPT_mPKmb482109
_ZNK4PLMD11TypesafePtr8get_privIfEEPT_mPKmb1
_ZNK4PLMD11TypesafePtr8get_privIiEEPT_mPKmb271282
_ZNK4PLMD11TypesafePtr8get_privIlEEPT_mPKmb166
_ZNK4PLMD11TypesafePtr8type_strB5cxx11Ev5
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/TypesafePtr.h.gcov.html b/coverage/tools/TypesafePtr.h.gcov.html new file mode 100644 index 000000000000..2558650ba7e2 --- /dev/null +++ b/coverage/tools/TypesafePtr.h.gcov.html @@ -0,0 +1,476 @@ + + + + + + + + LCOV - plumed test coverage - tools/TypesafePtr.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - TypesafePtr.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10812487.1 %
Date:2024-04-19 12:12:35Functions: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     1814305 : static inline bool typesafePtrSkipCheck() {
+      42     1814305 :   static const bool ret=std::getenv("PLUMED_TYPESAFE_IGNORE");
+      43     1814305 :   return ret;
+      44             : }
+      45             : 
+      46             : template<class T>
+      47     1811009 : std::size_t typesafePtrSizeof() {
+      48     1811009 :   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     1419219 :   inline void init_shape(const std::size_t* shape) {
+      70     1419219 :     this->shape[0]=0;
+      71     1419219 :     if(shape && *shape>0) {
+      72             :       std::size_t nelem_=1;
+      73             :       unsigned i=0;
+      74        1017 :       for(i=0; i<this->shape.size(); i++) {
+      75        1017 :         this->shape[i]=*shape;
+      76        1017 :         if(*shape==0) break;
+      77         589 :         nelem_*=*shape;
+      78         589 :         shape++;
+      79             :       }
+      80         428 :       plumed_assert(i<this->shape.size()); // check that last element is actually zero
+      81         428 :       if(nelem==0) nelem=nelem_;
+      82         428 :       plumed_assert(nelem==nelem_) << "Inconsistent shape/nelem";
+      83             :     }
+      84     1419219 :   }
+      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      404931 :     ptr(ptr),
+      92      404931 :     nelem(nelem),
+      93      404931 :     flags(flags)
+      94             :   {
+      95      404931 :     buffer[0]='\0';
+      96      404931 :     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      386246 :     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     1798287 :   TypesafePtr() {
+     112     1798287 :     shape[0]=0;
+     113     1798287 :     buffer[0]='\0';
+     114             :   }
+     115             : 
+     116             :   TypesafePtr(std::nullptr_t)
+     117      294178 :   {
+     118      294178 :     shape[0]=0;
+     119      287222 :     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        1223 :   __PLUMED_WRAPPER_TYPESAFEPTR_EMPTY(void,1)
+     169        2110 :   __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      286100 :   __PLUMED_WRAPPER_TYPESAFEPTR_SIZED(int,3)
+     175         102 :   __PLUMED_WRAPPER_TYPESAFEPTR_SIZED(unsigned int,0x100+3)
+     176          94 :   __PLUMED_WRAPPER_TYPESAFEPTR_SIZED(long,3)
+     177             :   __PLUMED_WRAPPER_TYPESAFEPTR_SIZED(unsigned long,0x100+3)
+     178      264721 :   __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      326910 :   __PLUMED_WRAPPER_TYPESAFEPTR_SIZED(double,4)
+     182             :   __PLUMED_WRAPPER_TYPESAFEPTR_SIZED(long double,4)
+     183         973 :   __PLUMED_WRAPPER_TYPESAFEPTR_EMPTY(FILE,5)
+     184             : 
+     185             :   ~TypesafePtr() {
+     186     3090847 :   }
+     187             : 
+     188             : 
+     189             :   TypesafePtr(const TypesafePtr&other) = delete;
+     190             : 
+     191             :   TypesafePtr & operator=(const TypesafePtr & other) = delete;
+     192             : 
+     193             :   TypesafePtr(TypesafePtr&&other):
+     194             :     buffer(other.buffer),
+     195             :     ptr(other.ptr==&other.buffer[0] ? &buffer[0] : other.ptr),
+     196             :     nelem(other.nelem),
+     197             :     shape(other.shape),
+     198             :     flags(other.flags)
+     199             :   {
+     200             :     other.ptr=nullptr;
+     201             :   }
+     202             : 
+     203             :   TypesafePtr copy() const;
+     204             : 
+     205      991917 :   TypesafePtr & operator=(TypesafePtr && other) {
+     206      991917 :     ptr=(other.ptr==&other.buffer[0] ? &buffer[0] : other.ptr);
+     207      991917 :     flags=other.flags;
+     208      991917 :     nelem=other.nelem;
+     209      991917 :     shape=other.shape;
+     210      991917 :     buffer=other.buffer;
+     211      991917 :     other.ptr=nullptr;
+     212      991917 :     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     1814305 :   T* get_priv(std::size_t nelem, const std::size_t* shape, bool byvalue) const {
+     230             : 
+     231     1814305 :     if(typesafePtrSkipCheck()) return (T*) ptr;
+     232             :     typedef typename std::remove_pointer<T>::type T_noptr;
+     233     1814305 :     if(flags==0) return (T*) ptr; // no check
+     234     1812005 :     auto size=flags&0xffff;
+     235     1812005 :     auto type=(flags>>16)&0xff;
+     236             :     // auto unsi=(flags>>24)&0x1; // ignored
+     237     1813732 :     auto cons=(flags>>25)&0x7;
+     238             : 
+     239             :     // type=0: ignore check
+     240             :     // type>5: undefined yet
+     241     1812005 :     if(type!=0 && type<=5) {
+     242      573426 :       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     1237588 :       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         990 :       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     1812000 :     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     1813727 :     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     1808670 :     if(cons>0) {
+     263             :       if(!std::is_pointer<T>::value) {
+     264             :         if(std::is_void<T>::value) {
+     265        1727 :           if(cons==1) {
+     266           0 :             throw ExceptionTypeError() << "This command expects a void pointer. It received a value instead"<<extra_msg();
+     267             :           }
+     268             :         } else {
+     269     1806827 :           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      754393 :           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      754393 :           } 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     1813726 :     if(shape && shape[0] && this->shape[0]) {
+     298         573 :       for(unsigned i=0; i<this->shape.size(); i++) {
+     299         573 :         if(shape[i]==0 && this->shape[i]!=0) {
+     300           0 :           throw ExceptionTypeError() << "Incorrect number of axis (passed greater than requested)"<<extra_msg();
+     301             :         }
+     302         573 :         if(shape[i]!=0 && this->shape[i]==0) {
+     303           0 :           throw ExceptionTypeError() << "Incorrect number of axis (requested greater than passed)"<<extra_msg();
+     304             :         }
+     305         573 :         if(shape[i]==0) break;
+     306         382 :         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         382 :         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     1813726 :     if(nelem==0 && shape && shape[0]>0) {
+     315      459614 :       nelem=1;
+     316     1378842 :       for(unsigned i=0; i<this->shape.size(); i++) {
+     317     1378842 :         if(shape[i]==0) break;
+     318      919228 :         nelem*=shape[i];
+     319             :       }
+     320             :     }
+     321             :     // check number of elements
+     322     1813726 :     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     1813724 :     return (T*) ptr;
+     326             :   }
+     327             : 
+     328             : public:
+     329             : 
+     330             :   template<typename T>
+     331       12896 :   void set(T val) const {
+     332       12896 :     *get_priv<T>(0,nullptr,false)=val;
+     333       12896 :   }
+     334             : 
+     335             :   template<typename T>
+     336      835945 :   typename std::enable_if<std::is_pointer<T>::value,T>::type get() const {
+     337             :     typedef typename std::remove_pointer<T>::type T_noptr;
+     338      842304 :     return get_priv<T_noptr>(0,nullptr,false);
+     339             :   }
+     340             : 
+     341             :   template<typename T>
+     342      301171 :   typename std::enable_if<!std::is_pointer<T>::value,T>::type get() const {
+     343      301171 :     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       66613 :     return get_priv<T_noptr>(nelem,nullptr,false);
+     351             :   }
+     352             : 
+     353             :   template<typename T>
+     354      591321 :   T get(std::initializer_list<std::size_t> shape) const {
+     355             :     static_assert(std::is_pointer<T>::value,"only pointer types allowed here");
+     356      591321 :     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     1773963 :     for(auto i : shape) {
+     361     1182642 :       shape_[j]=i;
+     362     1182642 :       j++;
+     363             :     }
+     364      591321 :     shape_[j]=0;
+     365      591321 :     return get_priv<T_noptr>(0,&shape_[0],false);
+     366             :   }
+     367             : 
+     368             :   operator bool() const noexcept {
+     369      726116 :     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 000000000000..d4f78ab5617e --- /dev/null +++ b/coverage/tools/Units.cpp.func-sort-c.html @@ -0,0 +1,117 @@ + + + + + + + + LCOV - plumed test coverage - tools/Units.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Units.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:889790.7 %
Date:2024-04-19 12:12:35Functions: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_traitsIcESaIcEEE29
_ZN4PLMD5Units9setEnergyEd45
_ZN4PLMD5Units9setLengthERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE58
_ZN4PLMD5Units7setMassEd933
_ZN4PLMD5Units9setChargeEd933
_ZN4PLMD5Units9setLengthEd933
_ZN4PLMD5UnitsC2Ev1615770
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Units.cpp.func.html b/coverage/tools/Units.cpp.func.html new file mode 100644 index 000000000000..cdb7fe7c0742 --- /dev/null +++ b/coverage/tools/Units.cpp.func.html @@ -0,0 +1,117 @@ + + + + + + + + LCOV - plumed test coverage - tools/Units.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Units.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:889790.7 %
Date:2024-04-19 12:12:35Functions:1111100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5Units7setMassERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3
_ZN4PLMD5Units7setMassEd933
_ZN4PLMD5Units7setTimeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE7
_ZN4PLMD5Units7setTimeEd6
_ZN4PLMD5Units9setChargeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE4
_ZN4PLMD5Units9setChargeEd933
_ZN4PLMD5Units9setEnergyERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE29
_ZN4PLMD5Units9setEnergyEd45
_ZN4PLMD5Units9setLengthERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE58
_ZN4PLMD5Units9setLengthEd933
_ZN4PLMD5UnitsC2Ev1615770
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Units.cpp.gcov.html b/coverage/tools/Units.cpp.gcov.html new file mode 100644 index 000000000000..2f1267f32b14 --- /dev/null +++ b/coverage/tools/Units.cpp.gcov.html @@ -0,0 +1,235 @@ + + + + + + + + LCOV - plumed test coverage - tools/Units.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Units.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:889790.7 %
Date:2024-04-19 12:12:35Functions: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     1615770 : Units::Units():
+      28     1615770 :   energy(1.0),
+      29     1615770 :   energyString("kj/mol"),
+      30     1615770 :   length(1.0),
+      31     1615770 :   lengthString("nm"),
+      32     1615770 :   time(1.0),
+      33     1615770 :   timeString("ps"),
+      34     1615770 :   charge(1.0),
+      35     1615770 :   chargeString("e"),
+      36     1615770 :   mass(1.0),
+      37     1615770 :   massString("amu")
+      38             : {
+      39     1615770 : }
+      40             : 
+      41          29 : void Units::setEnergy(const std::string &s) {
+      42          29 :   energyString=s;
+      43          29 :   if(s=="kj/mol") {
+      44          21 :     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          29 : }
+      62             : 
+      63          58 : void Units::setLength(const std::string &s) {
+      64          58 :   lengthString=s;
+      65          58 :   if(s=="nm") {
+      66           2 :     length=1.0;
+      67          56 :   } else if(s=="A") {
+      68          47 :     length=0.1;
+      69           9 :   } else if(s=="um") {
+      70           0 :     length=1000.0;
+      71           9 :   } else if(s=="Bohr") {
+      72           2 :     length=0.052917721067;
+      73             :   } else {
+      74           7 :     length=-1.0;
+      75             :     lengthString="";
+      76           7 :     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           7 :     plumed_massert(length>0.0,"length unit should be positive");
+      80             :   }
+      81          58 : }
+      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         933 : void Units::setLength(const double s) {
+     137         933 :   lengthString="";
+     138         933 :   length=s;
+     139         933 : }
+     140             : 
+     141           6 : void Units::setTime(const double s) {
+     142           6 :   timeString="";
+     143           6 :   time=s;
+     144           6 : }
+     145             : 
+     146         933 : void Units::setCharge(const double s) {
+     147         933 :   chargeString="";
+     148         933 :   charge=s;
+     149         933 : }
+     150             : 
+     151         933 : void Units::setMass(const double s) {
+     152         933 :   massString="";
+     153         933 :   mass=s;
+     154         933 : }
+     155             : 
+     156             : 
+     157             : 
+     158             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Units.h.func-sort-c.html b/coverage/tools/Units.h.func-sort-c.html new file mode 100644 index 000000000000..02ce35127c12 --- /dev/null +++ b/coverage/tools/Units.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage - tools/Units.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Units.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-04-19 12:12:35Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Units.h.func.html b/coverage/tools/Units.h.func.html new file mode 100644 index 000000000000..80dea0a68d24 --- /dev/null +++ b/coverage/tools/Units.h.func.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage - tools/Units.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Units.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-04-19 12:12:35Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Units.h.gcov.html b/coverage/tools/Units.h.gcov.html new file mode 100644 index 000000000000..08e1582c09cc --- /dev/null +++ b/coverage/tools/Units.h.gcov.html @@ -0,0 +1,244 @@ + + + + + + + + LCOV - plumed test coverage - tools/Units.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Units.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-04-19 12:12:35Functions: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 000000000000..0be505dacd10 --- /dev/null +++ b/coverage/tools/Vector.h.func-sort-c.html @@ -0,0 +1,341 @@ + + + + + + + + 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-04-19 12:12:35Functions:536779.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJjEEEvdDpT_0
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJjjEEEvdDpT_0
_ZN4PLMD13VectorGenericILj3EEC2IJjjEEEdDpT_0
_ZN4PLMD13VectorGenericILj5EE20auxiliaryConstructorIJEEEvdDpT_0
_ZN4PLMD13VectorGenericILj5EE20auxiliaryConstructorIJdEEEvdDpT_0
_ZN4PLMD13VectorGenericILj5EE20auxiliaryConstructorIJddEEEvdDpT_0
_ZN4PLMD13VectorGenericILj5EE20auxiliaryConstructorIJdddEEEvdDpT_0
_ZN4PLMD13VectorGenericILj5EE20auxiliaryConstructorIJddddEEEvdDpT_0
_ZN4PLMD13VectorGenericILj5EEC2Ev0
_ZN4PLMD13VectorGenericILj5EEC2IJddddEEEdDpT_0
_ZN4PLMD13VectorGenericILj5EEixEj0
_ZN4PLMD13VectorGenericILj5EEmLEd0
_ZN4PLMDmlILj5EEENS_13VectorGenericIXT_EEEdRKS2_0
_ZNK4PLMD13VectorGenericILj5EEixEj0
_ZN4PLMD13VectorGenericILj6EEC2Ev4004
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJdiEEEvdDpT_6774
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJidEEEvdDpT_6774
_ZN4PLMD13VectorGenericILj3EEC2IJdiEEEdDpT_6774
_ZN4PLMD13VectorGenericILj3EEC2IJidEEEdDpT_6774
_ZN4PLMD13VectorGenericILj3EEdVEd36678
_ZN4PLMD13VectorGenericILj1EEC2Ev546326
_ZN4PLMD13VectorGenericILj1EEixEj1092652
_ZN4PLMD13VectorGenericILj4EEmIERKS1_1119102
_ZN4PLMD5deltaILj4EEENS_13VectorGenericIXT_EEERKS2_S4_1119102
_ZN4PLMDmiILj4EEENS_13VectorGenericIXT_EEERKS2_S4_1119102
_ZNK4PLMD13VectorGenericILj4EE7modulo2Ev1119102
_ZNK4PLMD13VectorGenericILj4EEclEj4618728
_ZN4PLMD12crossProductERKNS_13VectorGenericILj3EEES3_5453065
_ZN4PLMD10dotProductILj4EEEdRKNS_13VectorGenericIXT_EEES4_12203712
_ZN4PLMD13VectorGenericILj4EE20auxiliaryConstructorIJEEEvdDpT_12808808
_ZN4PLMD13VectorGenericILj4EE20auxiliaryConstructorIJdEEEvdDpT_12808808
_ZN4PLMD13VectorGenericILj4EE20auxiliaryConstructorIJddEEEvdDpT_12808808
_ZN4PLMD13VectorGenericILj4EE20auxiliaryConstructorIJdddEEEvdDpT_12808808
_ZN4PLMD13VectorGenericILj4EEC2IJdddEEEdDpT_12808808
_ZN4PLMD13VectorGenericILj4EEC2Ev14052036
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJiiEEEvdDpT_14989316
_ZN4PLMD13VectorGenericILj3EEC2IJiiEEEdDpT_14989316
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJiEEEvdDpT_14996090
_ZN4PLMD6moduloILj3EEEdRKNS_13VectorGenericIXT_EEE22918220
_ZN4PLMD13VectorGenericILj3EE4zeroEv24582413
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJddEEEvdDpT_29335897
_ZN4PLMD13VectorGenericILj3EEC2IJddEEEdDpT_29335897
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJdEEEvdDpT_29342671
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJEEEvdDpT_44338761
_ZN4PLMD13VectorGenericILj4EEclEj48814848
_ZN4PLMD13VectorGenericILj4EEixEj51528067
_ZN4PLMD13VectorGenericILj6EEixEj63649362
_ZN4PLMD7modulo2ILj3EEEdRKNS_13VectorGenericIXT_EEE202834004
_ZNK4PLMD13VectorGenericILj3EEngEv206441557
_ZN4PLMD10dotProductILj3EEEdRKNS_13VectorGenericIXT_EEES4_250977423
_ZN4PLMDdvILj3EEENS_13VectorGenericIXT_EEERKS2_d309477127
_ZNK4PLMD13VectorGenericILj3EE6moduloEv362866680
_ZNK4PLMD13VectorGenericILj6EEixEj396376380
_ZN4PLMD13VectorGenericILj3EEC2Ev627283589
_ZN4PLMDmlILj3EEENS_13VectorGenericIXT_EEERKS2_d673058097
_ZN4PLMD5deltaILj3EEENS_13VectorGenericIXT_EEERKS2_S4_946473617
_ZNK4PLMD13VectorGenericILj3EE7modulo2Ev1062704556
_ZN4PLMDplILj3EEENS_13VectorGenericIXT_EEERKS2_S4_1317820127
_ZN4PLMDmiILj3EEENS_13VectorGenericIXT_EEERKS2_S4_1318846417
_ZNK4PLMD13VectorGenericILj3EEclEj1516049973
_ZN4PLMD13VectorGenericILj3EEclEj1521846891
_ZN4PLMD13VectorGenericILj3EEmIERKS1_1638217449
_ZN4PLMD13VectorGenericILj3EEpLERKS1_1721242317
_ZNK4PLMD13VectorGenericILj3EEixEj2037941470
_ZN4PLMDmlILj3EEENS_13VectorGenericIXT_EEEdRKS2_2155083976
_ZN4PLMD13VectorGenericILj3EEmLEd2157121467
_ZN4PLMD13VectorGenericILj3EEixEj2230989176
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Vector.h.func.html b/coverage/tools/Vector.h.func.html new file mode 100644 index 000000000000..4930d0310799 --- /dev/null +++ b/coverage/tools/Vector.h.func.html @@ -0,0 +1,341 @@ + + + + + + + + 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-04-19 12:12:35Functions:536779.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10dotProductILj3EEEdRKNS_13VectorGenericIXT_EEES4_250977423
_ZN4PLMD10dotProductILj4EEEdRKNS_13VectorGenericIXT_EEES4_12203712
_ZN4PLMD12crossProductERKNS_13VectorGenericILj3EEES3_5453065
_ZN4PLMD13VectorGenericILj1EEC2Ev546326
_ZN4PLMD13VectorGenericILj1EEixEj1092652
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJEEEvdDpT_44338761
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJdEEEvdDpT_29342671
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJddEEEvdDpT_29335897
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJdiEEEvdDpT_6774
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJiEEEvdDpT_14996090
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJidEEEvdDpT_6774
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJiiEEEvdDpT_14989316
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJjEEEvdDpT_0
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJjjEEEvdDpT_0
_ZN4PLMD13VectorGenericILj3EE4zeroEv24582413
_ZN4PLMD13VectorGenericILj3EEC2Ev627283589
_ZN4PLMD13VectorGenericILj3EEC2IJddEEEdDpT_29335897
_ZN4PLMD13VectorGenericILj3EEC2IJdiEEEdDpT_6774
_ZN4PLMD13VectorGenericILj3EEC2IJidEEEdDpT_6774
_ZN4PLMD13VectorGenericILj3EEC2IJiiEEEdDpT_14989316
_ZN4PLMD13VectorGenericILj3EEC2IJjjEEEdDpT_0
_ZN4PLMD13VectorGenericILj3EEclEj1521846891
_ZN4PLMD13VectorGenericILj3EEdVEd36678
_ZN4PLMD13VectorGenericILj3EEixEj2230989176
_ZN4PLMD13VectorGenericILj3EEmIERKS1_1638217449
_ZN4PLMD13VectorGenericILj3EEmLEd2157121467
_ZN4PLMD13VectorGenericILj3EEpLERKS1_1721242317
_ZN4PLMD13VectorGenericILj4EE20auxiliaryConstructorIJEEEvdDpT_12808808
_ZN4PLMD13VectorGenericILj4EE20auxiliaryConstructorIJdEEEvdDpT_12808808
_ZN4PLMD13VectorGenericILj4EE20auxiliaryConstructorIJddEEEvdDpT_12808808
_ZN4PLMD13VectorGenericILj4EE20auxiliaryConstructorIJdddEEEvdDpT_12808808
_ZN4PLMD13VectorGenericILj4EEC2Ev14052036
_ZN4PLMD13VectorGenericILj4EEC2IJdddEEEdDpT_12808808
_ZN4PLMD13VectorGenericILj4EEclEj48814848
_ZN4PLMD13VectorGenericILj4EEixEj51528067
_ZN4PLMD13VectorGenericILj4EEmIERKS1_1119102
_ZN4PLMD13VectorGenericILj5EE20auxiliaryConstructorIJEEEvdDpT_0
_ZN4PLMD13VectorGenericILj5EE20auxiliaryConstructorIJdEEEvdDpT_0
_ZN4PLMD13VectorGenericILj5EE20auxiliaryConstructorIJddEEEvdDpT_0
_ZN4PLMD13VectorGenericILj5EE20auxiliaryConstructorIJdddEEEvdDpT_0
_ZN4PLMD13VectorGenericILj5EE20auxiliaryConstructorIJddddEEEvdDpT_0
_ZN4PLMD13VectorGenericILj5EEC2Ev0
_ZN4PLMD13VectorGenericILj5EEC2IJddddEEEdDpT_0
_ZN4PLMD13VectorGenericILj5EEixEj0
_ZN4PLMD13VectorGenericILj5EEmLEd0
_ZN4PLMD13VectorGenericILj6EEC2Ev4004
_ZN4PLMD13VectorGenericILj6EEixEj63649362
_ZN4PLMD5deltaILj3EEENS_13VectorGenericIXT_EEERKS2_S4_946473617
_ZN4PLMD5deltaILj4EEENS_13VectorGenericIXT_EEERKS2_S4_1119102
_ZN4PLMD6moduloILj3EEEdRKNS_13VectorGenericIXT_EEE22918220
_ZN4PLMD7modulo2ILj3EEEdRKNS_13VectorGenericIXT_EEE202834004
_ZN4PLMDdvILj3EEENS_13VectorGenericIXT_EEERKS2_d309477127
_ZN4PLMDmiILj3EEENS_13VectorGenericIXT_EEERKS2_S4_1318846417
_ZN4PLMDmiILj4EEENS_13VectorGenericIXT_EEERKS2_S4_1119102
_ZN4PLMDmlILj3EEENS_13VectorGenericIXT_EEERKS2_d673058097
_ZN4PLMDmlILj3EEENS_13VectorGenericIXT_EEEdRKS2_2155083976
_ZN4PLMDmlILj5EEENS_13VectorGenericIXT_EEEdRKS2_0
_ZN4PLMDplILj3EEENS_13VectorGenericIXT_EEERKS2_S4_1317820127
_ZNK4PLMD13VectorGenericILj3EE6moduloEv362866680
_ZNK4PLMD13VectorGenericILj3EE7modulo2Ev1062704556
_ZNK4PLMD13VectorGenericILj3EEclEj1516049973
_ZNK4PLMD13VectorGenericILj3EEixEj2037941470
_ZNK4PLMD13VectorGenericILj3EEngEv206441557
_ZNK4PLMD13VectorGenericILj4EE7modulo2Ev1119102
_ZNK4PLMD13VectorGenericILj4EEclEj4618728
_ZNK4PLMD13VectorGenericILj5EEixEj0
_ZNK4PLMD13VectorGenericILj6EEixEj396376380
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Vector.h.gcov.html b/coverage/tools/Vector.h.gcov.html new file mode 100644 index 000000000000..d5e9a6a50b5e --- /dev/null +++ b/coverage/tools/Vector.h.gcov.html @@ -0,0 +1,420 @@ + + + + + + + + LCOV - plumed test coverage - tools/Vector.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Vector.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:6666100.0 %
Date:2024-04-19 12:12:35Functions:536779.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_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   184251515 : void VectorGeneric<n>::auxiliaryConstructor(double first,Args... arg)
+     164             : {
+     165   184251515 :   d[n-(sizeof...(Args))-1]=first;
+     166   127103946 :   auxiliaryConstructor(arg...);
+     167   184251515 : }
+     168             : 
+     169             : template <unsigned n>
+     170             : template<typename... Args>
+     171    57147569 : 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    57147569 :   auxiliaryConstructor(first,arg...);
+     175    57147569 : }
+     176             : 
+     177             : template <unsigned n>
+     178    24582413 : void VectorGeneric<n>::zero() {
+     179    24582413 :   LoopUnroller<n>::_zero(d.data());
+     180    24582413 : }
+     181             : 
+     182             : template <unsigned n>
+     183   641885955 : VectorGeneric<n>::VectorGeneric() {
+     184   641339629 :   LoopUnroller<n>::_zero(d.data());
+     185   641885955 : }
+     186             : 
+     187             : template <unsigned n>
+     188  2347259257 : double & VectorGeneric<n>::operator[](unsigned i) {
+     189  2347259257 :   return d[i];
+     190             : }
+     191             : 
+     192             : template <unsigned n>
+     193  2434317850 : const double & VectorGeneric<n>::operator[](unsigned i)const {
+     194  2434317850 :   return d[i];
+     195             : }
+     196             : 
+     197             : template <unsigned n>
+     198  1570661739 : double & VectorGeneric<n>::operator()(unsigned i) {
+     199  1570661739 :   return d[i];
+     200             : }
+     201             : 
+     202             : template <unsigned n>
+     203  1520668701 : const double & VectorGeneric<n>::operator()(unsigned i)const {
+     204  1520668701 :   return d[i];
+     205             : }
+     206             : 
+     207             : template <unsigned n>
+     208  1721242317 : VectorGeneric<n>& VectorGeneric<n>::operator +=(const VectorGeneric<n>& b) {
+     209  1721242317 :   LoopUnroller<n>::_add(d.data(),b.d.data());
+     210  1721242317 :   return *this;
+     211             : }
+     212             : 
+     213             : template <unsigned n>
+     214  1639336551 : VectorGeneric<n>& VectorGeneric<n>::operator -=(const VectorGeneric<n>& b) {
+     215  1639336551 :   LoopUnroller<n>::_sub(d.data(),b.d.data());
+     216  1639336551 :   return *this;
+     217             : }
+     218             : 
+     219             : template <unsigned n>
+     220  2157121467 : VectorGeneric<n>& VectorGeneric<n>::operator *=(double s) {
+     221  2157121467 :   LoopUnroller<n>::_mul(d.data(),s);
+     222  2157121467 :   return *this;
+     223             : }
+     224             : 
+     225             : template <unsigned n>
+     226       36678 : VectorGeneric<n>& VectorGeneric<n>::operator /=(double s) {
+     227       36678 :   LoopUnroller<n>::_mul(d.data(),1.0/s);
+     228       36678 :   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   206441557 : VectorGeneric<n> VectorGeneric<n>::operator -()const {
+     238   206441557 :   VectorGeneric<n> r;
+     239   206441557 :   LoopUnroller<n>::_neg(r.d.data(),d.data());
+     240   206441557 :   return r;
+     241             : }
+     242             : 
+     243             : template <unsigned n>
+     244  1317820127 : VectorGeneric<n> operator+(const VectorGeneric<n>&v1,const VectorGeneric<n>&v2) {
+     245  1317820127 :   VectorGeneric<n> v(v1);
+     246  1317820127 :   return v+=v2;
+     247             : }
+     248             : 
+     249             : template <unsigned n>
+     250  1319965519 : VectorGeneric<n> operator-(const VectorGeneric<n>&v1,const VectorGeneric<n>&v2) {
+     251  1319965519 :   VectorGeneric<n> v(v1);
+     252  1319965519 :   return v-=v2;
+     253             : }
+     254             : 
+     255             : template <unsigned n>
+     256  2155083976 : VectorGeneric<n> operator*(double s,const VectorGeneric<n>&v) {
+     257  2155083976 :   VectorGeneric<n> vv(v);
+     258  2155083976 :   return vv*=s;
+     259             : }
+     260             : 
+     261             : template <unsigned n>
+     262   673058097 : VectorGeneric<n> operator*(const VectorGeneric<n>&v,double s) {
+     263   673058097 :   return s*v;
+     264             : }
+     265             : 
+     266             : template <unsigned n>
+     267   309477127 : VectorGeneric<n> operator/(const VectorGeneric<n>&v,double s) {
+     268   309477127 :   return v*(1.0/s);
+     269             : }
+     270             : 
+     271             : template <unsigned n>
+     272   947592719 : VectorGeneric<n> delta(const VectorGeneric<n>&v1,const VectorGeneric<n>&v2) {
+     273   947592719 :   return v2-v1;
+     274             : }
+     275             : 
+     276             : template <unsigned n>
+     277  1063823658 : double VectorGeneric<n>::modulo2()const {
+     278  1063823658 :   return LoopUnroller<n>::_sum2(d.data());
+     279             : }
+     280             : 
+     281             : template <unsigned n>
+     282   263181135 : double dotProduct(const VectorGeneric<n>& v1,const VectorGeneric<n>& v2) {
+     283   263181135 :   return LoopUnroller<n>::_dot(v1.d.data(),v2.d.data());
+     284             : }
+     285             : 
+     286             : inline
+     287     5453065 : VectorGeneric<3> crossProduct(const VectorGeneric<3>& v1,const VectorGeneric<3>& v2) {
+     288             :   return VectorGeneric<3>(
+     289     5453065 :            v1[1]*v2[2]-v1[2]*v2[1],
+     290     5453065 :            v1[2]*v2[0]-v1[0]*v2[2],
+     291     5453065 :            v1[0]*v2[1]-v1[1]*v2[0]);
+     292             : }
+     293             : 
+     294             : template<unsigned n>
+     295   362866680 : double VectorGeneric<n>::modulo()const {
+     296   362866680 :   return sqrt(modulo2());
+     297             : }
+     298             : 
+     299             : template<unsigned n>
+     300   202834004 : double modulo2(const VectorGeneric<n>&v) {
+     301   202834004 :   return v.modulo2();
+     302             : }
+     303             : 
+     304             : template<unsigned n>
+     305    22918220 : double modulo(const VectorGeneric<n>&v) {
+     306    22918220 :   return v.modulo();
+     307             : }
+     308             : 
+     309             : template<unsigned n>
+     310             : std::ostream & operator<<(std::ostream &os, const VectorGeneric<n>& v) {
+     311             :   for(unsigned i=0; i<n-1; i++) os<<v(i)<<" ";
+     312             :   os<<v(n-1);
+     313             :   return os;
+     314             : }
+     315             : 
+     316             : 
+     317             : /// \ingroup TOOLBOX
+     318             : /// Alias for one dimensional vectors
+     319             : typedef VectorGeneric<1> Vector1d;
+     320             : /// \ingroup TOOLBOX
+     321             : /// Alias for two dimensional vectors
+     322             : typedef VectorGeneric<2> Vector2d;
+     323             : /// \ingroup TOOLBOX
+     324             : /// Alias for three dimensional vectors
+     325             : typedef VectorGeneric<3> Vector3d;
+     326             : /// \ingroup TOOLBOX
+     327             : /// Alias for four dimensional vectors
+     328             : typedef VectorGeneric<4> Vector4d;
+     329             : /// \ingroup TOOLBOX
+     330             : /// Alias for five dimensional vectors
+     331             : typedef VectorGeneric<5> Vector5d;
+     332             : /// \ingroup TOOLBOX
+     333             : /// Alias for three dimensional vectors
+     334             : typedef Vector3d Vector;
+     335             : 
+     336             : static_assert(sizeof(VectorGeneric<2>)==2*sizeof(double), "code cannot work if this is not satisfied");
+     337             : static_assert(sizeof(VectorGeneric<3>)==3*sizeof(double), "code cannot work if this is not satisfied");
+     338             : static_assert(sizeof(VectorGeneric<4>)==4*sizeof(double), "code cannot work if this is not satisfied");
+     339             : 
+     340             : }
+     341             : 
+     342             : #endif
+     343             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/h36.cpp.func-sort-c.html b/coverage/tools/h36.cpp.func-sort-c.html new file mode 100644 index 000000000000..dd8599707ed8 --- /dev/null +++ b/coverage/tools/h36.cpp.func-sort-c.html @@ -0,0 +1,121 @@ + + + + + + + + LCOV - plumed test coverage - tools/h36.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - h36.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:8712768.5 %
Date:2024-04-19 12:12:35Functions: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_clEv233
_ZZN4PLMD3h3610hy36decodeEjPKcjPiENKUlvE_clEv233
_ZN4PLMD3h36L12digits_lowerEv8389
_ZN4PLMD3h3610hy36encodeEjiPc102253
_ZN4PLMD3h36L11encode_pureEPKcjjiPc102253
_ZN4PLMD3h36L12digits_upperEv110640
_ZN4PLMD3h3610hy36decodeEjPKcjPi830928
_ZN4PLMD3h36L11decode_pureEPKijPKcjPi830928
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/h36.cpp.func.html b/coverage/tools/h36.cpp.func.html new file mode 100644 index 000000000000..b733bbd78d7f --- /dev/null +++ b/coverage/tools/h36.cpp.func.html @@ -0,0 +1,121 @@ + + + + + + + + LCOV - plumed test coverage - tools/h36.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - h36.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:8712768.5 %
Date:2024-04-19 12:12:35Functions:91275.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3h3610hy36decodeEjPKcjPi830928
_ZN4PLMD3h3610hy36encodeEjiPc102253
_ZN4PLMD3h36L11decode_pureEPKijPKcjPi830928
_ZN4PLMD3h36L11encode_pureEPKcjjiPc102253
_ZN4PLMD3h36L12digits_lowerEv8389
_ZN4PLMD3h36L12digits_upperEv110640
_ZN4PLMD3h36L15fill_with_starsEjPc0
_ZN4PLMD3h36L17unsupported_widthEv0
_ZN4PLMD3h36L18value_out_of_rangeEv0
_ZN4PLMD3h36L22invalid_number_literalEv2
_ZZN4PLMD3h3610hy36decodeEjPKcjPiENKUlvE0_clEv233
_ZZN4PLMD3h3610hy36decodeEjPKcjPiENKUlvE_clEv233
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/h36.cpp.gcov.html b/coverage/tools/h36.cpp.gcov.html new file mode 100644 index 000000000000..f3a4fe9b250b --- /dev/null +++ b/coverage/tools/h36.cpp.gcov.html @@ -0,0 +1,412 @@ + + + + + + + + LCOV - plumed test coverage - tools/h36.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - h36.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:8712768.5 %
Date:2024-04-19 12:12:35Functions: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      110640 : digits_upper() { return "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; }
+      62             : 
+      63             : static
+      64             : const char*
+      65        8389 : 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      102253 : 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      102253 :   if (value < 0) {
+     103             :     j = 1;
+     104           0 :     value = -value;
+     105             :   }
+     106             :   while (1) {
+     107      492778 :     rest = value / digits_size;
+     108      492778 :     buf[i++] = digits[value - rest * digits_size];
+     109      492778 :     if (rest == 0) break;
+     110             :     value = rest;
+     111             :   }
+     112      102253 :   if (j) buf[i++] = '-';
+     113      120739 :   for(j=i; j<width; j++) *result++ = ' ';
+     114      595031 :   while (i != 0) *result++ = buf[--i];
+     115      102253 :   *result = '\0';
+     116      102253 : }
+     117             : 
+     118             : static
+     119             : const char*
+     120      830928 : 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     4570103 :   for(; i<s_size; i++) {
+     133     3739176 :     si = s[i];
+     134     3739176 :     if (si < 0 || si > 127) {
+     135           0 :       *result = 0;
+     136           0 :       return invalid_number_literal();
+     137             :     }
+     138     3739176 :     if (si == ' ') {
+     139     1119904 :       if (!have_non_blank) continue;
+     140           0 :       value *= digits_size;
+     141             :     }
+     142     2619272 :     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     2619272 :       dv = digits_values[si];
+     154     2619272 :       if (dv < 0 || dv >= digits_size) {
+     155           1 :         *result = 0;
+     156           1 :         return invalid_number_literal();
+     157             :       }
+     158     2619271 :       value *= digits_size;
+     159     2619271 :       value += dv;
+     160             :     }
+     161             :   }
+     162      830927 :   if (have_minus) value = -value;
+     163      830927 :   *result = value;
+     164      830927 :   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      102253 : hy36encode(unsigned width, int value, char* result)
+     187             : {
+     188             :   int i = value;
+     189      102253 :   if (width == 4U) {
+     190           1 :     if (i >= -999) {
+     191           1 :       if (i < 10000) {
+     192           0 :         encode_pure(digits_upper(), 10U, 4U, i, result);
+     193           0 :         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      102252 :   else if (width == 5U) {
+     210      102252 :     if (i >= -9999) {
+     211      102252 :       if (i < 100000) {
+     212      102143 :         encode_pure(digits_upper(), 10U, 5U, i, result);
+     213      102143 :         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      830928 : hy36decode(unsigned width, const char* s, unsigned s_size, int* result)
+     261             : {
+     262         233 :   static const std::vector<int> digits_values_upper_vector([]() {
+     263         233 :     std::vector<int> ret(128U,-1);
+     264        8621 :     for(unsigned i=0; i<36U; i++) {
+     265        8388 :       int di = digits_upper()[i];
+     266        8388 :       if (di < 0 || di > 127) {
+     267           0 :         plumed_error()<<"internal error hy36decode: integer value out of range";
+     268             :       }
+     269        8388 :       ret[di] = i;
+     270             :     }
+     271         233 :     return ret;
+     272      830928 :   }());
+     273      830928 :   static const int* digits_values_upper=digits_values_upper_vector.data();
+     274         233 :   static const std::vector<int> digits_values_lower_vector([]() {
+     275         233 :     std::vector<int> ret(128U,-1);
+     276        8621 :     for(unsigned i=0; i<36U; i++) {
+     277        8388 :       int di = digits_lower()[i];
+     278        8388 :       if (di < 0 || di > 127) {
+     279           0 :         plumed_error()<<"internal error hy36decode: integer value out of range";
+     280             :       }
+     281        8388 :       ret[di] = i;
+     282             :     }
+     283         233 :     return ret;
+     284      830928 :   }());
+     285      830928 :   static const int* digits_values_lower=digits_values_lower_vector.data();
+     286             :   int di;
+     287             :   const char* errmsg;
+     288      830928 :   if (s_size == width) {
+     289      830928 :     di = s[0];
+     290      830928 :     if (di >= 0 && di <= 127) {
+     291      830928 :       if (digits_values_upper[di] >= 10) {
+     292          14 :         errmsg = decode_pure(digits_values_upper, 36U, s, s_size, result);
+     293          14 :         if (errmsg == 0) {
+     294             :           /* result - 10*36**(width-1) + 10**width */
+     295          13 :           if      (width == 4U) (*result) -= 456560;
+     296           6 :           else if (width == 5U) (*result) -= 16696160;
+     297             :           else {
+     298           0 :             *result = 0;
+     299           0 :             return unsupported_width();
+     300             :           }
+     301          13 :           return 0;
+     302             :         }
+     303             :       }
+     304      830914 :       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      830914 :         errmsg = decode_pure(digits_values_upper, 10U, s, s_size, result);
+     319      830914 :         if (errmsg) return errmsg;
+     320      830914 :         if (!(width == 4U || width == 5U)) {
+     321           0 :           *result = 0;
+     322           0 :           return unsupported_width();
+     323             :         }
+     324             :         return 0;
+     325             :       }
+     326             :     }
+     327             :   }
+     328           1 :   *result = 0;
+     329           1 :   return invalid_number_literal();
+     330             : }
+     331             : 
+     332             : }
+     333             : 
+     334             : }
+     335             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/index-sort-f.html b/coverage/tools/index-sort-f.html new file mode 100644 index 000000000000..5ce4670d862c --- /dev/null +++ b/coverage/tools/index-sort-f.html @@ -0,0 +1,864 @@ + + + + + + + + LCOV - plumed test coverage - tools + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - toolsHitTotalCoverage
Test:plumed test coverageLines:5702713879.9 %
Date:2024-04-19 12:12:35Functions:1137157172.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Exception.h +
91.7%91.7%
+
91.7 %33 / 3617.5 %24 / 137
Grid.cpp +
69.4%69.4%
+
69.4 %420 / 60537.5 %60 / 160
MultiValue.cpp +
53.8%53.8%
+
53.8 %49 / 9140.0 %4 / 10
DynamicList.h +
44.8%44.8%
+
44.8 %13 / 2942.9 %3 / 7
Torsion.cpp +
80.0%80.0%
+
80.0 %28 / 3550.0 %1 / 2
RMSD.cpp +
75.6%75.6%
+
75.6 %556 / 73555.0 %44 / 80
PDB.cpp +
52.5%52.5%
+
52.5 %219 / 41761.4 %27 / 44
PlumedHandle.cpp +
63.9%63.9%
+
63.9 %23 / 3662.5 %5 / 8
DLLoader.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
OpenMP.h +
100.0%
+
100.0 %8 / 866.7 %2 / 3
RootFindingBase.h +
100.0%
+
100.0 %16 / 1666.7 %4 / 6
Brent1DRootSearch.h +
97.4%97.4%
+
97.4 %38 / 3966.7 %6 / 9
KernelFunctions.cpp +
40.5%40.5%
+
40.5 %90 / 22270.0 %7 / 10
TypesafePtr.h +
87.1%87.1%
+
87.1 %108 / 12472.7 %40 / 55
h36.cpp +
68.5%68.5%
+
68.5 %87 / 12775.0 %9 / 12
Keywords.cpp +
53.1%53.1%
+
53.1 %214 / 40375.0 %33 / 44
SwitchingFunction.cpp +
94.8%94.8%
+
94.8 %385 / 40677.4 %82 / 106
RMSD.h +
85.7%85.7%
+
85.7 %30 / 3577.8 %7 / 9
Vector.h +
100.0%
+
100.0 %66 / 6679.1 %53 / 67
ERMSD.cpp +
98.4%98.4%
+
98.4 %120 / 12280.0 %4 / 5
LatticeReduction.cpp +
82.9%82.9%
+
82.9 %102 / 12380.0 %8 / 10
HistogramBead.cpp +
59.3%59.3%
+
59.3 %70 / 11881.8 %9 / 11
Communicator.cpp +
83.6%83.6%
+
83.6 %102 / 12283.3 %30 / 36
Tensor.h +
96.7%96.7%
+
96.7 %146 / 15184.1 %58 / 69
Subprocess.cpp +
74.1%74.1%
+
74.1 %60 / 8187.5 %14 / 16
NeighborList.cpp +
91.5%91.5%
+
91.5 %118 / 12987.5 %14 / 16
IFile.cpp +
96.0%96.0%
+
96.0 %145 / 15188.0 %22 / 25
Matrix.h +
86.7%86.7%
+
86.7 %117 / 13588.9 %8 / 9
MinimiseBase.h +
100.0%
+
100.0 %26 / 2688.9 %16 / 18
OFile.h +
100.0%
+
100.0 %6 / 688.9 %96 / 108
Tools.h +
97.9%97.9%
+
97.9 %94 / 9689.3 %50 / 56
Stopwatch.h +
81.5%81.5%
+
81.5 %53 / 6590.9 %10 / 11
Random.cpp +
91.6%91.6%
+
91.6 %76 / 8390.9 %10 / 11
Tools.cpp +
88.4%88.4%
+
88.4 %258 / 29291.2 %52 / 57
Pbc.cpp +
96.1%96.1%
+
96.1 %124 / 12992.3 %12 / 13
FileBase.cpp +
100.0%
+
100.0 %80 / 8093.3 %14 / 15
OFile.cpp +
92.5%92.5%
+
92.5 %210 / 22793.3 %28 / 30
Communicator.h +
93.0%93.0%
+
93.0 %40 / 4393.3 %56 / 60
Grid.h +
100.0%
+
100.0 %88 / 8896.0 %24 / 25
LinkCells.h +
100.0%
+
100.0 %1 / 1-0 / 0
NeighborList.h +
100.0%
+
100.0 %4 / 4-0 / 0
FileBase.h +
100.0%
+
100.0 %6 / 6-0 / 0
Tree.h +
100.0%
+
100.0 %1 / 1-0 / 0
IFile.h +
100.0%
+
100.0 %2 / 2-0 / 0
SwitchingFunction.h +
100.0%
+
100.0 %1 / 1-0 / 0
CheckInRange.h +
100.0%
+
100.0 %1 / 1-0 / 0
Pbc.h +
83.3%83.3%
+
83.3 %5 / 6-0 / 0
Random.h +
100.0%
+
100.0 %1 / 1-0 / 0
Units.h +
100.0%
+
100.0 %1 / 1-0 / 0
ERMSD.h +
50.0%50.0%
+
50.0 %1 / 2-0 / 0
Citations.h +
100.0%
+
100.0 %1 / 1-0 / 0
LeptonCall.h +
100.0%
+
100.0 %1 / 1-0 / 0
KernelFunctions.h +
100.0%
+
100.0 %9 / 9100.0 %1 / 1
Tensor.cpp +
100.0%
+
100.0 %3 / 3100.0 %1 / 1
MergeVectorTools.h +
100.0%
+
100.0 %25 / 25100.0 %2 / 2
Angle.cpp +
100.0%
+
100.0 %26 / 26100.0 %2 / 2
HistogramBead.h +
94.4%94.4%
+
94.4 %17 / 18100.0 %2 / 2
Keywords.h +
81.2%81.2%
+
81.2 %13 / 16100.0 %2 / 2
Subprocess.h +
100.0%
+
100.0 %4 / 4100.0 %2 / 2
AtomNumber.h +
100.0%
+
100.0 %17 / 17100.0 %2 / 2
LeptonCall.cpp +
95.0%95.0%
+
95.0 %38 / 40100.0 %3 / 3
Stopwatch.cpp +
100.0%
+
100.0 %21 / 21100.0 %3 / 3
ConjugateGradient.h +
92.9%92.9%
+
92.9 %13 / 14100.0 %3 / 3
Tree.cpp +
100.0%
+
100.0 %42 / 42100.0 %3 / 3
TypesafePtr.cpp +
100.0%
+
100.0 %14 / 14100.0 %3 / 3
OpenMP.cpp +
100.0%
+
100.0 %17 / 17100.0 %4 / 4
CheckInRange.cpp +
77.5%77.5%
+
77.5 %31 / 40100.0 %4 / 4
Citations.cpp +
100.0%
+
100.0 %16 / 16100.0 %4 / 4
MultiValue.h +
100.0%
+
100.0 %43 / 43100.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
Units.cpp +
90.7%90.7%
+
90.7 %88 / 97100.0 %11 / 11
LinkCells.cpp +
98.9%98.9%
+
98.9 %87 / 88100.0 %11 / 11
Minimise1DBrent.h +
98.8%98.8%
+
98.8 %82 / 83100.0 %12 / 12
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 %53 / 53
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/index-sort-l.html b/coverage/tools/index-sort-l.html new file mode 100644 index 000000000000..ced75626b22b --- /dev/null +++ b/coverage/tools/index-sort-l.html @@ -0,0 +1,864 @@ + + + + + + + + LCOV - plumed test coverage - tools + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - toolsHitTotalCoverage
Test:plumed test coverageLines:5702713879.9 %
Date:2024-04-19 12:12:35Functions:1137157172.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
KernelFunctions.cpp +
40.5%40.5%
+
40.5 %90 / 22270.0 %7 / 10
DynamicList.h +
44.8%44.8%
+
44.8 %13 / 2942.9 %3 / 7
ERMSD.h +
50.0%50.0%
+
50.0 %1 / 2-0 / 0
PDB.cpp +
52.5%52.5%
+
52.5 %219 / 41761.4 %27 / 44
Keywords.cpp +
53.1%53.1%
+
53.1 %214 / 40375.0 %33 / 44
MultiValue.cpp +
53.8%53.8%
+
53.8 %49 / 9140.0 %4 / 10
HistogramBead.cpp +
59.3%59.3%
+
59.3 %70 / 11881.8 %9 / 11
DLLoader.cpp +
62.9%62.9%
+
62.9 %22 / 3562.5 %5 / 8
PlumedHandle.cpp +
63.9%63.9%
+
63.9 %23 / 3662.5 %5 / 8
h36.cpp +
68.5%68.5%
+
68.5 %87 / 12775.0 %9 / 12
Grid.cpp +
69.4%69.4%
+
69.4 %420 / 60537.5 %60 / 160
Subprocess.cpp +
74.1%74.1%
+
74.1 %60 / 8187.5 %14 / 16
RMSD.cpp +
75.6%75.6%
+
75.6 %556 / 73555.0 %44 / 80
BiasRepresentation.cpp +
75.9%75.9%
+
75.9 %129 / 17063.2 %12 / 19
CheckInRange.cpp +
77.5%77.5%
+
77.5 %31 / 40100.0 %4 / 4
Torsion.cpp +
80.0%80.0%
+
80.0 %28 / 3550.0 %1 / 2
Keywords.h +
81.2%81.2%
+
81.2 %13 / 16100.0 %2 / 2
Stopwatch.h +
81.5%81.5%
+
81.5 %53 / 6590.9 %10 / 11
LatticeReduction.cpp +
82.9%82.9%
+
82.9 %102 / 12380.0 %8 / 10
Pbc.h +
83.3%83.3%
+
83.3 %5 / 6-0 / 0
Communicator.cpp +
83.6%83.6%
+
83.6 %102 / 12283.3 %30 / 36
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
Matrix.h +
86.7%86.7%
+
86.7 %117 / 13588.9 %8 / 9
TypesafePtr.h +
87.1%87.1%
+
87.1 %108 / 12472.7 %40 / 55
Tools.cpp +
88.4%88.4%
+
88.4 %258 / 29291.2 %52 / 57
Units.cpp +
90.7%90.7%
+
90.7 %88 / 97100.0 %11 / 11
NeighborList.cpp +
91.5%91.5%
+
91.5 %118 / 12987.5 %14 / 16
Random.cpp +
91.6%91.6%
+
91.6 %76 / 8390.9 %10 / 11
Exception.h +
91.7%91.7%
+
91.7 %33 / 3617.5 %24 / 137
OFile.cpp +
92.5%92.5%
+
92.5 %210 / 22793.3 %28 / 30
ConjugateGradient.h +
92.9%92.9%
+
92.9 %13 / 14100.0 %3 / 3
Communicator.h +
93.0%93.0%
+
93.0 %40 / 4393.3 %56 / 60
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
SwitchingFunction.cpp +
94.8%94.8%
+
94.8 %385 / 40677.4 %82 / 106
LeptonCall.cpp +
95.0%95.0%
+
95.0 %38 / 40100.0 %3 / 3
IFile.cpp +
96.0%96.0%
+
96.0 %145 / 15188.0 %22 / 25
Pbc.cpp +
96.1%96.1%
+
96.1 %124 / 12992.3 %12 / 13
Tensor.h +
96.7%96.7%
+
96.7 %146 / 15184.1 %58 / 69
Brent1DRootSearch.h +
97.4%97.4%
+
97.4 %38 / 3966.7 %6 / 9
Tools.h +
97.9%97.9%
+
97.9 %94 / 9689.3 %50 / 56
ERMSD.cpp +
98.4%98.4%
+
98.4 %120 / 12280.0 %4 / 5
Minimise1DBrent.h +
98.8%98.8%
+
98.8 %82 / 83100.0 %12 / 12
LinkCells.cpp +
98.9%98.9%
+
98.9 %87 / 88100.0 %11 / 11
LinkCells.h +
100.0%
+
100.0 %1 / 1-0 / 0
Tree.h +
100.0%
+
100.0 %1 / 1-0 / 0
SwitchingFunction.h +
100.0%
+
100.0 %1 / 1-0 / 0
CheckInRange.h +
100.0%
+
100.0 %1 / 1-0 / 0
Random.h +
100.0%
+
100.0 %1 / 1-0 / 0
Units.h +
100.0%
+
100.0 %1 / 1-0 / 0
Citations.h +
100.0%
+
100.0 %1 / 1-0 / 0
LeptonCall.h +
100.0%
+
100.0 %1 / 1-0 / 0
IFile.h +
100.0%
+
100.0 %2 / 2-0 / 0
Tensor.cpp +
100.0%
+
100.0 %3 / 3100.0 %1 / 1
NeighborList.h +
100.0%
+
100.0 %4 / 4-0 / 0
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 / 688.9 %96 / 108
OpenMP.h +
100.0%
+
100.0 %8 / 866.7 %2 / 3
KernelFunctions.h +
100.0%
+
100.0 %9 / 9100.0 %1 / 1
MatrixSquareBracketsAccess.h +
100.0%
+
100.0 %12 / 12100.0 %18 / 18
TypesafePtr.cpp +
100.0%
+
100.0 %14 / 14100.0 %3 / 3
RootFindingBase.h +
100.0%
+
100.0 %16 / 1666.7 %4 / 6
Citations.cpp +
100.0%
+
100.0 %16 / 16100.0 %4 / 4
OpenMP.cpp +
100.0%
+
100.0 %17 / 17100.0 %4 / 4
AtomNumber.h +
100.0%
+
100.0 %17 / 17100.0 %2 / 2
Stopwatch.cpp +
100.0%
+
100.0 %21 / 21100.0 %3 / 3
MergeVectorTools.h +
100.0%
+
100.0 %25 / 25100.0 %2 / 2
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 %53 / 53
Tree.cpp +
100.0%
+
100.0 %42 / 42100.0 %3 / 3
MultiValue.h +
100.0%
+
100.0 %43 / 43100.0 %4 / 4
Vector.h +
100.0%
+
100.0 %66 / 6679.1 %53 / 67
FileBase.cpp +
100.0%
+
100.0 %80 / 8093.3 %14 / 15
Grid.h +
100.0%
+
100.0 %88 / 8896.0 %24 / 25
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/index.html b/coverage/tools/index.html new file mode 100644 index 000000000000..cf117044e132 --- /dev/null +++ b/coverage/tools/index.html @@ -0,0 +1,864 @@ + + + + + + + + LCOV - plumed test coverage - tools + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - toolsHitTotalCoverage
Test:plumed test coverageLines:5702713879.9 %
Date:2024-04-19 12:12:35Functions:1137157172.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 %17 / 17100.0 %2 / 2
BiasRepresentation.cpp +
75.9%75.9%
+
75.9 %129 / 17063.2 %12 / 19
Brent1DRootSearch.h +
97.4%97.4%
+
97.4 %38 / 3966.7 %6 / 9
CheckInRange.cpp +
77.5%77.5%
+
77.5 %31 / 40100.0 %4 / 4
CheckInRange.h +
100.0%
+
100.0 %1 / 1-0 / 0
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 +
93.0%93.0%
+
93.0 %40 / 4393.3 %56 / 60
ConjugateGradient.h +
92.9%92.9%
+
92.9 %13 / 14100.0 %3 / 3
DLLoader.cpp +
62.9%62.9%
+
62.9 %22 / 3562.5 %5 / 8
DynamicList.h +
44.8%44.8%
+
44.8 %13 / 2942.9 %3 / 7
ERMSD.cpp +
98.4%98.4%
+
98.4 %120 / 12280.0 %4 / 5
ERMSD.h +
50.0%50.0%
+
50.0 %1 / 2-0 / 0
Exception.cpp +
94.1%94.1%
+
94.1 %48 / 51100.0 %6 / 6
Exception.h +
91.7%91.7%
+
91.7 %33 / 3617.5 %24 / 137
FileBase.cpp +
100.0%
+
100.0 %80 / 8093.3 %14 / 15
FileBase.h +
100.0%
+
100.0 %6 / 6-0 / 0
ForwardDecl.h +
100.0%
+
100.0 %4 / 4100.0 %13 / 13
Grid.cpp +
69.4%69.4%
+
69.4 %420 / 60537.5 %60 / 160
Grid.h +
100.0%
+
100.0 %88 / 8896.0 %24 / 25
HistogramBead.cpp +
59.3%59.3%
+
59.3 %70 / 11881.8 %9 / 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 +
40.5%40.5%
+
40.5 %90 / 22270.0 %7 / 10
KernelFunctions.h +
100.0%
+
100.0 %9 / 9100.0 %1 / 1
Keywords.cpp +
53.1%53.1%
+
53.1 %214 / 40375.0 %33 / 44
Keywords.h +
81.2%81.2%
+
81.2 %13 / 16100.0 %2 / 2
LatticeReduction.cpp +
82.9%82.9%
+
82.9 %102 / 12380.0 %8 / 10
LeptonCall.cpp +
95.0%95.0%
+
95.0 %38 / 40100.0 %3 / 3
LeptonCall.h +
100.0%
+
100.0 %1 / 1-0 / 0
LinkCells.cpp +
98.9%98.9%
+
98.9 %87 / 88100.0 %11 / 11
LinkCells.h +
100.0%
+
100.0 %1 / 1-0 / 0
LoopUnroller.h +
100.0%
+
100.0 %31 / 31100.0 %53 / 53
Matrix.h +
86.7%86.7%
+
86.7 %117 / 13588.9 %8 / 9
MatrixSquareBracketsAccess.h +
100.0%
+
100.0 %12 / 12100.0 %18 / 18
MergeVectorTools.h +
100.0%
+
100.0 %25 / 25100.0 %2 / 2
Minimise1DBrent.h +
98.8%98.8%
+
98.8 %82 / 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 +
53.8%53.8%
+
53.8 %49 / 9140.0 %4 / 10
MultiValue.h +
100.0%
+
100.0 %43 / 43100.0 %4 / 4
NeighborList.cpp +
91.5%91.5%
+
91.5 %118 / 12987.5 %14 / 16
NeighborList.h +
100.0%
+
100.0 %4 / 4-0 / 0
OFile.cpp +
92.5%92.5%
+
92.5 %210 / 22793.3 %28 / 30
OFile.h +
100.0%
+
100.0 %6 / 688.9 %96 / 108
OpenMP.cpp +
100.0%
+
100.0 %17 / 17100.0 %4 / 4
OpenMP.h +
100.0%
+
100.0 %8 / 866.7 %2 / 3
PDB.cpp +
52.5%52.5%
+
52.5 %219 / 41761.4 %27 / 44
Pbc.cpp +
96.1%96.1%
+
96.1 %124 / 12992.3 %12 / 13
Pbc.h +
83.3%83.3%
+
83.3 %5 / 6-0 / 0
PlumedHandle.cpp +
63.9%63.9%
+
63.9 %23 / 3662.5 %5 / 8
RMSD.cpp +
75.6%75.6%
+
75.6 %556 / 73555.0 %44 / 80
RMSD.h +
85.7%85.7%
+
85.7 %30 / 3577.8 %7 / 9
Random.cpp +
91.6%91.6%
+
91.6 %76 / 8390.9 %10 / 11
Random.h +
100.0%
+
100.0 %1 / 1-0 / 0
RootFindingBase.h +
100.0%
+
100.0 %16 / 1666.7 %4 / 6
Stopwatch.cpp +
100.0%
+
100.0 %21 / 21100.0 %3 / 3
Stopwatch.h +
81.5%81.5%
+
81.5 %53 / 6590.9 %10 / 11
Subprocess.cpp +
74.1%74.1%
+
74.1 %60 / 8187.5 %14 / 16
Subprocess.h +
100.0%
+
100.0 %4 / 4100.0 %2 / 2
SwitchingFunction.cpp +
94.8%94.8%
+
94.8 %385 / 40677.4 %82 / 106
SwitchingFunction.h +
100.0%
+
100.0 %1 / 1-0 / 0
Tensor.cpp +
100.0%
+
100.0 %3 / 3100.0 %1 / 1
Tensor.h +
96.7%96.7%
+
96.7 %146 / 15184.1 %58 / 69
Tools.cpp +
88.4%88.4%
+
88.4 %258 / 29291.2 %52 / 57
Tools.h +
97.9%97.9%
+
97.9 %94 / 9689.3 %50 / 56
Torsion.cpp +
80.0%80.0%
+
80.0 %28 / 3550.0 %1 / 2
Tree.cpp +
100.0%
+
100.0 %42 / 42100.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.1%87.1%
+
87.1 %108 / 12472.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 / 6679.1 %53 / 67
h36.cpp +
68.5%68.5%
+
68.5 %87 / 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/valtools/Concatenate.cpp.func-sort-c.html b/coverage/valtools/Concatenate.cpp.func-sort-c.html new file mode 100644 index 000000000000..4ff05892b2b6 --- /dev/null +++ b/coverage/valtools/Concatenate.cpp.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - valtools/Concatenate.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - valtools - Concatenate.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:838795.4 %
Date:2024-04-19 12:12:35Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8valtools11ConcatenateC2ERKNS_13ActionOptionsE0
_ZN4PLMD8valtools11ConcatenateC1ERKNS_13ActionOptionsE175
_ZN4PLMD8valtools11Concatenate16registerKeywordsERNS_8KeywordsE177
_ZN4PLMD8valtools11Concatenate22getNumberOfDerivativesEv257
_ZN4PLMD8valtools11Concatenate5applyEv12070
_ZN4PLMD8valtools11Concatenate9calculateEv12191
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/valtools/Concatenate.cpp.func.html b/coverage/valtools/Concatenate.cpp.func.html new file mode 100644 index 000000000000..875ed1a1ee18 --- /dev/null +++ b/coverage/valtools/Concatenate.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - valtools/Concatenate.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - valtools - Concatenate.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:838795.4 %
Date:2024-04-19 12:12:35Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8valtools11Concatenate16registerKeywordsERNS_8KeywordsE177
_ZN4PLMD8valtools11Concatenate22getNumberOfDerivativesEv257
_ZN4PLMD8valtools11Concatenate5applyEv12070
_ZN4PLMD8valtools11Concatenate9calculateEv12191
_ZN4PLMD8valtools11ConcatenateC1ERKNS_13ActionOptionsE175
_ZN4PLMD8valtools11ConcatenateC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/valtools/Concatenate.cpp.gcov.html b/coverage/valtools/Concatenate.cpp.gcov.html new file mode 100644 index 000000000000..65e91acf76fe --- /dev/null +++ b/coverage/valtools/Concatenate.cpp.gcov.html @@ -0,0 +1,266 @@ + + + + + + + + LCOV - plumed test coverage - valtools/Concatenate.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - valtools - Concatenate.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:838795.4 %
Date:2024-04-19 12:12:35Functions:5683.3 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2014-2017 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received 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/ActionWithArguments.h"
+      24             : #include "core/ActionRegister.h"
+      25             : 
+      26             : //+PLUMEDOC MCOLVAR CONCATENATE
+      27             : /*
+      28             : Join vectors or matrices together
+      29             : 
+      30             : \par Examples
+      31             : 
+      32             : */
+      33             : //+ENDPLUMEDOC
+      34             : 
+      35             : namespace PLMD {
+      36             : namespace valtools {
+      37             : 
+      38             : class Concatenate :
+      39             :   public ActionWithValue,
+      40             :   public ActionWithArguments {
+      41             : private:
+      42             :   bool vectors;
+      43             :   std::vector<unsigned> row_starts;
+      44             :   std::vector<unsigned> col_starts;
+      45             : public:
+      46             :   static void registerKeywords( Keywords& keys );
+      47             : /// Constructor
+      48             :   explicit Concatenate(const ActionOptions&);
+      49             : /// Get the number of derivatives
+      50         257 :   unsigned getNumberOfDerivatives() override { return 0; }
+      51             : /// Do the calculation
+      52             :   void calculate() override;
+      53             : ///
+      54             :   void apply();
+      55             : };
+      56             : 
+      57             : PLUMED_REGISTER_ACTION(Concatenate,"CONCATENATE")
+      58             : 
+      59         177 : void Concatenate::registerKeywords( Keywords& keys ) {
+      60         177 :   Action::registerKeywords( keys ); ActionWithValue::registerKeywords( keys ); ActionWithArguments::registerKeywords( keys ); keys.use("ARG");
+      61         531 :   keys.add("numbered","MATRIX","specify the matrices that you wish to join together into a single matrix"); keys.reset_style("MATRIX","compulsory");
+      62         177 : }
+      63             : 
+      64         175 : Concatenate::Concatenate(const ActionOptions& ao):
+      65             :   Action(ao),
+      66             :   ActionWithValue(ao),
+      67         175 :   ActionWithArguments(ao)
+      68             : {
+      69         175 :   if( getNumberOfArguments()>0 ) {
+      70         171 :     vectors=true; std::vector<unsigned> shape(1); shape[0]=0;
+      71         545 :     for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+      72         374 :       if( getPntrToArgument(i)->getRank()>1 ) error("cannot concatenate matrix with vectors");
+      73         374 :       getPntrToArgument(i)->buildDataStore(); shape[0] += getPntrToArgument(i)->getNumberOfValues();
+      74             :     }
+      75         171 :     log.printf("  creating vector with %d elements \n", shape[0] );
+      76         171 :     addValue( shape ); bool period=getPntrToArgument(0)->isPeriodic();
+      77         171 :     std::string min, max; if( period ) getPntrToArgument(0)->getDomain( min, max );
+      78         374 :     for(unsigned i=1; i<getNumberOfArguments(); ++i) {
+      79         203 :       if( period!=getPntrToArgument(i)->isPeriodic() ) error("periods of input arguments should match");
+      80         203 :       if( period ) {
+      81           0 :         std::string min0, max0; getPntrToArgument(i)->getDomain( min0, max0 );
+      82           0 :         if( min0!=min || max0!=max ) error("domains of input arguments should match");
+      83             :       }
+      84             :     }
+      85         171 :     if( period ) setPeriodic( min, max ); else setNotPeriodic();
+      86         171 :     getPntrToComponent(0)->buildDataStore();
+      87         171 :     if( getPntrToComponent(0)->getRank()==2 ) getPntrToComponent(0)->reshapeMatrixStore( shape[1] );
+      88             :   } else {
+      89           4 :     unsigned nrows=0, ncols=0; std::vector<Value*> arglist; vectors=false;
+      90           7 :     for(unsigned i=1;; i++) {
+      91             :       unsigned nt_cols=0; unsigned size_b4 = arglist.size();
+      92          14 :       for(unsigned j=1;; j++) {
+      93          25 :         if( j==10 ) error("cannot combine more than 9 matrices");
+      94          50 :         std::vector<Value*> argn; parseArgumentList("MATRIX", i*10+j, argn);
+      95          25 :         if( argn.size()==0 ) break;
+      96          14 :         if( argn.size()>1 ) error("should only be one argument to each matrix keyword");
+      97          14 :         if( argn[0]->getRank()!=0 && argn[0]->getRank()!=2 ) error("input arguments for this action should be matrices");
+      98          14 :         argn[0]->buildDataStore(); arglist.push_back( argn[0] ); nt_cols++;
+      99          14 :         if( argn[0]->getRank()==0 ) log.printf("  %d %d component of composed matrix is scalar labelled %s\n", i, j, argn[0]->getName().c_str() );
+     100          14 :         else log.printf("  %d %d component of composed matrix is %d by %d matrix labelled %s\n", i, j, argn[0]->getShape()[0], argn[0]->getShape()[1], argn[0]->getName().c_str() );
+     101          14 :       }
+     102          11 :       if( arglist.size()==size_b4 ) break;
+     103           7 :       if( i==1 ) ncols=nt_cols;
+     104           3 :       else if( nt_cols!=ncols ) error("should be joining same number of matrices in each row");
+     105           7 :       nrows++;
+     106           7 :     }
+     107             : 
+     108           4 :     std::vector<unsigned> shape(2); shape[0]=0; unsigned k=0;
+     109           4 :     row_starts.resize( arglist.size() ); col_starts.resize( arglist.size() );
+     110          11 :     for(unsigned i=0; i<nrows; ++i) {
+     111           7 :       unsigned cstart = 0, nr = 1; if( arglist[k]->getRank()==2 ) nr=arglist[k]->getShape()[0];
+     112          21 :       for(unsigned j=0; j<ncols; ++j) {
+     113          14 :         if( arglist[k]->getRank()==0 ) {
+     114           0 :           if( nr!=1 ) error("mismatched matrix sizes");
+     115          14 :         } else if( nrows>1 && arglist[k]->getShape()[0]!=nr ) error("mismatched matrix sizes");
+     116          14 :         row_starts[k] = shape[0]; col_starts[k] = cstart;
+     117          14 :         if( arglist[k]->getRank()==0 ) cstart += 1;
+     118          14 :         else cstart += arglist[k]->getShape()[1];
+     119          14 :         k++;
+     120             :       }
+     121           7 :       if( i==0 ) shape[1]=cstart;
+     122           3 :       else if( cstart!=shape[1] ) error("mismatched matrix sizes");
+     123           7 :       if( arglist[k-1]->getRank()==0 ) shape[0] += 1;
+     124           7 :       else shape[0] += arglist[k-1]->getShape()[0];
+     125             :     }
+     126             :     // Now request the arguments to make sure we store things we need
+     127           4 :     requestArguments(arglist); addValue( shape ); setNotPeriodic(); getPntrToComponent(0)->buildDataStore();
+     128           4 :     if( getPntrToComponent(0)->getRank()==2 ) getPntrToComponent(0)->reshapeMatrixStore( shape[1] );
+     129             :   }
+     130         175 : }
+     131             : 
+     132       12191 : void Concatenate::calculate() {
+     133       12191 :   Value* myval = getPntrToComponent(0);
+     134       12191 :   if( vectors ) {
+     135             :     unsigned k=0;
+     136       61297 :     for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     137       49158 :       Value* myarg=getPntrToArgument(i); unsigned nvals=myarg->getNumberOfValues();
+     138      404266 :       for(unsigned j=0; j<nvals; ++j) { myval->set( k, myarg->get(j) ); k++; }
+     139             :     }
+     140             :   } else {
+     141             :     // Retrieve the matrix from input
+     142          52 :     unsigned ncols = myval->getShape()[1];
+     143         258 :     for(unsigned k=0; k<getNumberOfArguments(); ++k) {
+     144             :       Value* argn = getPntrToArgument(k);
+     145         206 :       if( argn->getRank()==0 ) {
+     146           0 :         myval->set( ncols*row_starts[k]+col_starts[k], argn->get() );
+     147             :       } else {
+     148             :         std::vector<double> vals; std::vector<std::pair<unsigned,unsigned> > pairs;
+     149             :         bool symmetric=getPntrToArgument(k)->isSymmetric();
+     150         206 :         unsigned nedge=0; getPntrToArgument(k)->retrieveEdgeList( nedge, pairs, vals );
+     151        8946 :         for(unsigned l=0; l<nedge; ++l ) {
+     152        8740 :           unsigned i=pairs[l].first, j=pairs[l].second;
+     153        8740 :           myval->set( ncols*(row_starts[k]+i)+col_starts[k]+j, vals[l] );
+     154        8740 :           if( symmetric ) myval->set( ncols*(row_starts[k]+j)+col_starts[k]+i, vals[l] );
+     155             :         }
+     156             :       }
+     157             :     }
+     158             :   }
+     159       12191 : }
+     160             : 
+     161       12070 : void Concatenate::apply() {
+     162       12070 :   if( doNotCalculateDerivatives() || !getPntrToComponent(0)->forcesWereAdded() ) return;
+     163             : 
+     164        5033 :   Value* val=getPntrToComponent(0);
+     165        5033 :   if( vectors ) {
+     166             :     unsigned k=0;
+     167       19923 :     for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     168       14942 :       Value* myarg=getPntrToArgument(i); unsigned nvals=myarg->getNumberOfValues();
+     169      205938 :       for(unsigned j=0; j<nvals; ++j) { myarg->addForce( j, val->getForce(k) ); k++; }
+     170             :     }
+     171             :   } else {
+     172          52 :     unsigned ncols=val->getShape()[1];
+     173         258 :     for(unsigned k=0; k<getNumberOfArguments(); ++k) {
+     174             :       Value* argn=getPntrToArgument(k);
+     175         206 :       if( argn->getRank()==0 ) argn->addForce( 0, val->getForce(ncols*row_starts[k]+col_starts[k]) );
+     176             :       else {
+     177             :         unsigned val_ncols=val->getNumberOfColumns();
+     178             :         unsigned arg_ncols=argn->getNumberOfColumns();
+     179        1686 :         for(unsigned i=0; i<argn->getShape()[0]; ++i) {
+     180             :           unsigned ncol = argn->getRowLength(i);
+     181       13140 :           for(unsigned j=0; j<ncol; ++j) argn->addForce( i*arg_ncols+j, val->getForce( val_ncols*(row_starts[k]+i)+col_starts[k]+argn->getRowIndex(i,j) ), false );
+     182             :         }
+     183             :       }
+     184             :     }
+     185             :   }
+     186             : }
+     187             : 
+     188             : }
+     189             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/valtools/Flatten.cpp.func-sort-c.html b/coverage/valtools/Flatten.cpp.func-sort-c.html new file mode 100644 index 000000000000..98829e639924 --- /dev/null +++ b/coverage/valtools/Flatten.cpp.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - valtools/Flatten.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - valtools - Flatten.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2626100.0 %
Date:2024-04-19 12:12:35Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8valtools7FlattenC2ERKNS_13ActionOptionsE0
_ZN4PLMD8valtools7Flatten5applyEv7
_ZN4PLMD8valtools7Flatten9calculateEv9
_ZN4PLMD8valtools7FlattenC1ERKNS_13ActionOptionsE9
_ZN4PLMD8valtools7Flatten22getNumberOfDerivativesEv10
_ZN4PLMD8valtools7Flatten16registerKeywordsERNS_8KeywordsE11
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/valtools/Flatten.cpp.func.html b/coverage/valtools/Flatten.cpp.func.html new file mode 100644 index 000000000000..f1e4c5eda555 --- /dev/null +++ b/coverage/valtools/Flatten.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - valtools/Flatten.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - valtools - Flatten.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2626100.0 %
Date:2024-04-19 12:12:35Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8valtools7Flatten16registerKeywordsERNS_8KeywordsE11
_ZN4PLMD8valtools7Flatten22getNumberOfDerivativesEv10
_ZN4PLMD8valtools7Flatten5applyEv7
_ZN4PLMD8valtools7Flatten9calculateEv9
_ZN4PLMD8valtools7FlattenC1ERKNS_13ActionOptionsE9
_ZN4PLMD8valtools7FlattenC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/valtools/Flatten.cpp.gcov.html b/coverage/valtools/Flatten.cpp.gcov.html new file mode 100644 index 000000000000..a2ac6d75a158 --- /dev/null +++ b/coverage/valtools/Flatten.cpp.gcov.html @@ -0,0 +1,171 @@ + + + + + + + + LCOV - plumed test coverage - valtools/Flatten.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - valtools - Flatten.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2626100.0 %
Date:2024-04-19 12:12:35Functions:5683.3 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2014-2017 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received 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/ActionWithArguments.h"
+      24             : #include "core/ActionRegister.h"
+      25             : 
+      26             : //+PLUMEDOC FUNCTION FLATTEN
+      27             : /*
+      28             : Convert a matrix into a vector
+      29             : 
+      30             : \par Examples
+      31             : 
+      32             : 
+      33             : */
+      34             : //+ENDPLUMEDOC
+      35             : 
+      36             : namespace PLMD {
+      37             : namespace valtools {
+      38             : 
+      39             : class Flatten :
+      40             :   public ActionWithValue,
+      41             :   public ActionWithArguments {
+      42             : public:
+      43             :   static void registerKeywords( Keywords& keys );
+      44             : /// Constructor
+      45             :   explicit Flatten(const ActionOptions&);
+      46             : /// Get the number of derivatives
+      47          10 :   unsigned getNumberOfDerivatives() override { return 0; }
+      48             : /// Do the calculation
+      49             :   void calculate() override;
+      50             : ///
+      51             :   void apply() override;
+      52             : };
+      53             : 
+      54             : PLUMED_REGISTER_ACTION(Flatten,"FLATTEN")
+      55             : 
+      56          11 : void Flatten::registerKeywords( Keywords& keys ) {
+      57          11 :   Action::registerKeywords( keys ); ActionWithValue::registerKeywords( keys );
+      58          11 :   ActionWithArguments::registerKeywords( keys ); keys.use("ARG");
+      59          11 : }
+      60             : 
+      61           9 : Flatten::Flatten(const ActionOptions& ao):
+      62             :   Action(ao),
+      63             :   ActionWithValue(ao),
+      64           9 :   ActionWithArguments(ao)
+      65             : {
+      66           9 :   if( getNumberOfArguments()!=1 ) error("should only be one argument for this action");
+      67           9 :   if( getPntrToArgument(0)->getRank()!=2 || getPntrToArgument(0)->hasDerivatives() ) error("input to this action should be a matrix");
+      68           9 :   getPntrToArgument(0)->buildDataStore(true);
+      69           9 :   std::vector<unsigned> inshape( getPntrToArgument(0)->getShape() );
+      70           9 :   std::vector<unsigned> shape( 1 ); shape[0]=inshape[0]*inshape[1];
+      71           9 :   addValue( shape ); setNotPeriodic(); getPntrToComponent(0)->buildDataStore();
+      72           9 : }
+      73             : 
+      74           9 : void Flatten::calculate() {
+      75           9 :   Value* myval = getPntrToComponent(0); unsigned ss=getPntrToArgument(0)->getShape()[1];
+      76             :   std::vector<double> vals; std::vector<std::pair<unsigned,unsigned> > pairs;
+      77             :   bool symmetric=getPntrToArgument(0)->isSymmetric();
+      78           9 :   unsigned nedge=0; getPntrToArgument(0)->retrieveEdgeList( nedge, pairs, vals );
+      79        8139 :   for(unsigned l=0; l<nedge; ++l ) {
+      80        8130 :     unsigned i=pairs[l].first, j=pairs[l].second;
+      81        8130 :     myval->set( i*ss + j, vals[l] );
+      82        8130 :     if( symmetric ) myval->set( j*ss + i, vals[l] );
+      83             :   }
+      84           9 : }
+      85             : 
+      86           7 : void Flatten::apply() {
+      87           7 :   if( doNotCalculateDerivatives() || !getPntrToComponent(0)->forcesWereAdded() ) return;
+      88             : 
+      89           3 :   Value* myval=getPntrToComponent(0); Value* myarg=getPntrToArgument(0);
+      90          22 :   unsigned nvals=myval->getNumberOfValues(); for(unsigned j=0; j<nvals; ++j) myarg->addForce( j, myval->getForce(j) );
+      91             : }
+      92             : 
+      93             : }
+      94             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/valtools/SelectComponents.cpp.func-sort-c.html b/coverage/valtools/SelectComponents.cpp.func-sort-c.html new file mode 100644 index 000000000000..cc5f963ced92 --- /dev/null +++ b/coverage/valtools/SelectComponents.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - valtools/SelectComponents.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - valtools - SelectComponents.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:303196.8 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8valtools16SelectComponentsC2ERKNS_13ActionOptionsE0
_ZN4PLMD8valtools16SelectComponentsC1ERKNS_13ActionOptionsE57
_ZN4PLMD8valtools16SelectComponents16registerKeywordsERNS_8KeywordsE59
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/valtools/SelectComponents.cpp.func.html b/coverage/valtools/SelectComponents.cpp.func.html new file mode 100644 index 000000000000..03b6f20a6112 --- /dev/null +++ b/coverage/valtools/SelectComponents.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - valtools/SelectComponents.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - valtools - SelectComponents.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:303196.8 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8valtools16SelectComponents16registerKeywordsERNS_8KeywordsE59
_ZN4PLMD8valtools16SelectComponentsC1ERKNS_13ActionOptionsE57
_ZN4PLMD8valtools16SelectComponentsC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/valtools/SelectComponents.cpp.gcov.html b/coverage/valtools/SelectComponents.cpp.gcov.html new file mode 100644 index 000000000000..2b6efda60e67 --- /dev/null +++ b/coverage/valtools/SelectComponents.cpp.gcov.html @@ -0,0 +1,166 @@ + + + + + + + + LCOV - plumed test coverage - valtools/SelectComponents.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - valtools - SelectComponents.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:303196.8 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2014-2017 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionShortcut.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "core/ActionWithArguments.h"
+      25             : #include "core/PlumedMain.h"
+      26             : #include "core/ActionSet.h"
+      27             : 
+      28             : //+PLUMEDOC PRINTANALYSIS SELECT_COMPONENTS
+      29             : /*
+      30             : Create a new value to hold a subset of the components that are in a vector or matrix
+      31             : 
+      32             : \par Examples
+      33             : 
+      34             : */
+      35             : //+ENDPLUMEDOC
+      36             : 
+      37             : namespace PLMD {
+      38             : namespace valtools {
+      39             : 
+      40             : class SelectComponents : public ActionShortcut {
+      41             : public:
+      42             :   static void registerKeywords( Keywords& keys );
+      43             : /// Constructor
+      44             :   explicit SelectComponents(const ActionOptions&);
+      45             : };
+      46             : 
+      47             : PLUMED_REGISTER_ACTION(SelectComponents,"SELECT_COMPONENTS")
+      48             : 
+      49          59 : void SelectComponents::registerKeywords( Keywords& keys ) {
+      50          59 :   ActionShortcut::registerKeywords( keys );
+      51         118 :   keys.add("compulsory","ARG","the argument we are using to build the shortcut");
+      52         118 :   keys.add("compulsory","COMPONENTS","the components in the input value that you woul like to build a new vector from");
+      53         177 :   keys.needsAction("FLATTEN"); keys.needsAction("CONSTANT"); keys.needsAction("SELECT_WITH_MASK");
+      54          59 : }
+      55             : 
+      56          57 : SelectComponents::SelectComponents(const ActionOptions& ao):
+      57             :   Action(ao),
+      58          57 :   ActionShortcut(ao)
+      59             : {
+      60         114 :   std::vector<std::string> argn; parseVector("ARG",argn); std::vector<Value*> theargs;
+      61          57 :   ActionWithArguments::interpretArgumentList( argn, plumed.getActionSet(), this, theargs );
+      62          57 :   if( theargs.size()!=1 ) error("should only be one argument input to this action");
+      63             :   // Create an array that will eventually hold the mask
+      64          57 :   std::vector<double> mask( theargs[0]->getNumberOfValues(), 1 );
+      65         114 :   std::vector<std::string> elements; parseVector("COMPONENTS",elements);
+      66          57 :   if( theargs[0]->getRank()==1 ) {
+      67         189 :     for(unsigned i=0; i<elements.size(); ++i) { unsigned sel; Tools::convert( elements[i], sel ); mask[sel-1]=0; }
+      68           7 :   } else if( theargs[0]->getRank()==2 ) {
+      69          27 :     for(unsigned i=0; i<elements.size(); ++i) {
+      70          20 :       std::size_t dot = elements[i].find_first_of(".");
+      71          20 :       if( dot==std::string::npos ) error("found no dot in specification of required matrix element");
+      72          20 :       std::string istr=elements[i].substr(0,dot), jstr=elements[i].substr(dot+1);
+      73          20 :       unsigned ival, jval; Tools::convert( istr, ival ); Tools::convert( jstr, jval );
+      74          20 :       mask[(ival-1)*theargs[0]->getShape()[1] + jval - 1] = 0;
+      75             :     }
+      76          14 :     readInputLine( getShortcutLabel() + "_flat: FLATTEN ARG=" + theargs[0]->getName() );
+      77           0 :   } else error("input to this argument should be a vector/matrix");
+      78             :   // Now create the mask action
+      79          57 :   std::string mask_str; Tools::convert( mask[0], mask_str ); unsigned check_mask=mask[0];
+      80        1472 :   for(unsigned i=1; i<mask.size(); ++i) { std::string num; Tools::convert( mask[i], num ); mask_str += "," + num; check_mask +=mask[i]; }
+      81          57 :   if( mask.size()-check_mask!=elements.size() ) error("found repeated indexes in COMPONENTS");
+      82         114 :   readInputLine( getShortcutLabel() + "_mask: CONSTANT VALUES=" + mask_str );
+      83             :   // And finally create the selector
+      84         107 :   if( theargs[0]->getRank()==1 ) readInputLine( getShortcutLabel() + ": SELECT_WITH_MASK ARG=" + theargs[0]->getName() + " MASK=" + getShortcutLabel() + "_mask");
+      85          14 :   else if( theargs[0]->getRank()==2 ) readInputLine( getShortcutLabel() + ": SELECT_WITH_MASK ARG=" + getShortcutLabel() + "_flat MASK=" + getShortcutLabel() + "_mask");
+      86         114 : }
+      87             : 
+      88             : }
+      89             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/valtools/SelectWithMask.cpp.func-sort-c.html b/coverage/valtools/SelectWithMask.cpp.func-sort-c.html new file mode 100644 index 000000000000..57c251bbe2e5 --- /dev/null +++ b/coverage/valtools/SelectWithMask.cpp.func-sort-c.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - valtools/SelectWithMask.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - valtools - SelectWithMask.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:9110388.3 %
Date:2024-04-19 12:12:35Functions:8988.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8valtools14SelectWithMaskC2ERKNS_13ActionOptionsE0
_ZNK4PLMD8valtools14SelectWithMask21getMatrixColumnTitlesERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EE18
_ZN4PLMD8valtools14SelectWithMaskC1ERKNS_13ActionOptionsE93
_ZN4PLMD8valtools14SelectWithMask16registerKeywordsERNS_8KeywordsE95
_ZN4PLMD8valtools14SelectWithMask22getNumberOfDerivativesEv98
_ZN4PLMD8valtools14SelectWithMask5applyEv10505
_ZN4PLMD8valtools14SelectWithMask9calculateEv10543
_ZN4PLMD8valtools14SelectWithMask7prepareEv10551
_ZNK4PLMD8valtools14SelectWithMask21getOutputVectorLengthEPKNS_5ValueE10693
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/valtools/SelectWithMask.cpp.func.html b/coverage/valtools/SelectWithMask.cpp.func.html new file mode 100644 index 000000000000..cb72c0c1839d --- /dev/null +++ b/coverage/valtools/SelectWithMask.cpp.func.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - valtools/SelectWithMask.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - valtools - SelectWithMask.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:9110388.3 %
Date:2024-04-19 12:12:35Functions:8988.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8valtools14SelectWithMask16registerKeywordsERNS_8KeywordsE95
_ZN4PLMD8valtools14SelectWithMask22getNumberOfDerivativesEv98
_ZN4PLMD8valtools14SelectWithMask5applyEv10505
_ZN4PLMD8valtools14SelectWithMask7prepareEv10551
_ZN4PLMD8valtools14SelectWithMask9calculateEv10543
_ZN4PLMD8valtools14SelectWithMaskC1ERKNS_13ActionOptionsE93
_ZN4PLMD8valtools14SelectWithMaskC2ERKNS_13ActionOptionsE0
_ZNK4PLMD8valtools14SelectWithMask21getMatrixColumnTitlesERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EE18
_ZNK4PLMD8valtools14SelectWithMask21getOutputVectorLengthEPKNS_5ValueE10693
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/valtools/SelectWithMask.cpp.gcov.html b/coverage/valtools/SelectWithMask.cpp.gcov.html new file mode 100644 index 000000000000..96b770511162 --- /dev/null +++ b/coverage/valtools/SelectWithMask.cpp.gcov.html @@ -0,0 +1,281 @@ + + + + + + + + LCOV - plumed test coverage - valtools/SelectWithMask.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - valtools - SelectWithMask.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:9110388.3 %
Date:2024-04-19 12:12:35Functions:8988.9 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2014-2017 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received 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/ActionWithArguments.h"
+      24             : #include "core/ActionRegister.h"
+      25             : #include "core/PlumedMain.h"
+      26             : #include "core/ActionSet.h"
+      27             : 
+      28             : //+PLUMEDOC PRINTANALYSIS SELECT_WITH_MASK
+      29             : /*
+      30             : Use a mask to select elements of an array
+      31             : 
+      32             : \par Examples
+      33             : 
+      34             : */
+      35             : //+ENDPLUMEDOC
+      36             : 
+      37             : namespace PLMD {
+      38             : namespace valtools {
+      39             : 
+      40             : class SelectWithMask :
+      41             :   public ActionWithValue,
+      42             :   public ActionWithArguments {
+      43             : private:
+      44             :   unsigned getOutputVectorLength( const Value* mask ) const ;
+      45             : public:
+      46             :   static void registerKeywords( Keywords& keys );
+      47             : /// Constructor
+      48             :   explicit SelectWithMask(const ActionOptions&);
+      49             : /// Get the number of derivatives
+      50          98 :   unsigned getNumberOfDerivatives() override { return 0; }
+      51             : ///
+      52             :   void getMatrixColumnTitles( std::vector<std::string>& argnames ) const override ;
+      53             : ///
+      54             :   void prepare() override ;
+      55             : /// Do the calculation
+      56             :   void calculate() override;
+      57             : ///
+      58             :   void apply() override;
+      59             : };
+      60             : 
+      61             : PLUMED_REGISTER_ACTION(SelectWithMask,"SELECT_WITH_MASK")
+      62             : 
+      63          95 : void SelectWithMask::registerKeywords( Keywords& keys ) {
+      64          95 :   Action::registerKeywords( keys ); ActionWithValue::registerKeywords( keys );
+      65          95 :   ActionWithArguments::registerKeywords( keys ); keys.use("ARG");
+      66         190 :   keys.add("optional","ROW_MASK","an array with ones in the rows of the matrix that you want to discard");
+      67         190 :   keys.add("optional","COLUMN_MASK","an array with ones in the columns of the matrix that you want to discard");
+      68         190 :   keys.add("compulsory","MASK","an array with ones in the components that you want to discard");
+      69          95 : }
+      70             : 
+      71          93 : SelectWithMask::SelectWithMask(const ActionOptions& ao):
+      72             :   Action(ao),
+      73             :   ActionWithValue(ao),
+      74          93 :   ActionWithArguments(ao)
+      75             : {
+      76          93 :   if( getNumberOfArguments()!=1 ) error("should only be one argument for this action");
+      77          93 :   getPntrToArgument(0)->buildDataStore(); std::vector<unsigned> shape;
+      78          93 :   if( getPntrToArgument(0)->getRank()==1 ) {
+      79         136 :     std::vector<Value*> mask; parseArgumentList("MASK",mask);
+      80          68 :     if( mask.size()!=1 ) error("should only be one input for mask");
+      81          68 :     if( mask[0]->getNumberOfValues()!=getPntrToArgument(0)->getNumberOfValues() ) error("mismatch between size of mask and input vector");
+      82          68 :     log.printf("  creating vector from elements of %s who have a corresponding element in %s that is zero\n", getPntrToArgument(0)->getName().c_str(), mask[0]->getName().c_str() );
+      83          68 :     std::vector<Value*> args( getArguments() ); args.push_back( mask[0] ); requestArguments( args );
+      84          68 :     shape.resize(1,0); if( (mask[0]->getPntrToAction())->getName()=="CONSTANT" ) shape[0]=getOutputVectorLength(mask[0]);
+      85          25 :   } else if( getPntrToArgument(0)->getRank()==2 ) {
+      86          75 :     std::vector<Value*> rmask, cmask; parseArgumentList("ROW_MASK",rmask); parseArgumentList("COLUMN_MASK",cmask);
+      87          25 :     if( rmask.size()==0 && cmask.size()==0 ) {
+      88           0 :       error("no mask elements have been specified");
+      89          25 :     } else if( cmask.size()==0 ) {
+      90         144 :       std::string con="0"; for(unsigned i=1; i<getPntrToArgument(0)->getShape()[1]; ++i) con += ",0";
+      91          22 :       plumed.readInputLine( getLabel() + "_colmask: CONSTANT VALUES=" + con ); std::vector<std::string> labs(1, getLabel() + "_colmask");
+      92          11 :       ActionWithArguments::interpretArgumentList( labs, plumed.getActionSet(), this, cmask );
+      93          25 :     } else if( rmask.size()==0 ) {
+      94          13 :       std::string con="0"; for(unsigned i=1; i<getPntrToArgument(0)->getShape()[0]; ++i) con += ",0";
+      95           2 :       plumed.readInputLine( getLabel() + "_rowmask: CONSTANT VALUES=" + con ); std::vector<std::string> labs(1, getLabel() + "_rowmask");
+      96           1 :       ActionWithArguments::interpretArgumentList( labs, plumed.getActionSet(), this, rmask );
+      97           1 :     }
+      98          25 :     shape.resize(2);
+      99          25 :     rmask[0]->buildDataStore(); shape[0] = getOutputVectorLength( rmask[0] );
+     100          25 :     cmask[0]->buildDataStore(); shape[1] = getOutputVectorLength( cmask[0] );
+     101          25 :     std::vector<Value*> args( getArguments() ); args.push_back( rmask[0] );
+     102          25 :     args.push_back( cmask[0] ); requestArguments( args );
+     103           0 :   } else error("input should be vector or matrix");
+     104             : 
+     105          93 :   addValue( shape ); getPntrToComponent(0)->buildDataStore();
+     106          93 :   if( getPntrToArgument(0)->isPeriodic() ) {
+     107           7 :     std::string min, max; getPntrToArgument(0)->getDomain( min, max ); setPeriodic( min, max );
+     108          86 :   } else setNotPeriodic();
+     109          93 :   if( getPntrToComponent(0)->getRank()==2 ) getPntrToComponent(0)->reshapeMatrixStore( shape[1] );
+     110          93 : }
+     111             : 
+     112       10693 : unsigned SelectWithMask::getOutputVectorLength( const Value* mask ) const  {
+     113             :   unsigned l=0;
+     114      154139 :   for(unsigned i=0; i<mask->getNumberOfValues(); ++i) {
+     115      143446 :     if( fabs(mask->get(i))>0 ) continue;
+     116      133435 :     l++;
+     117             :   }
+     118       10693 :   return l;
+     119             : }
+     120             : 
+     121          18 : void SelectWithMask::getMatrixColumnTitles( std::vector<std::string>& argnames ) const {
+     122          18 :   std::vector<std::string> alltitles; (getPntrToArgument(0)->getPntrToAction())->getMatrixColumnTitles( alltitles );
+     123         103 :   for(unsigned i=0; i<alltitles.size(); ++i) {
+     124          85 :     if( fabs(getPntrToArgument(2)->get(i))>0 ) continue;
+     125          51 :     argnames.push_back( alltitles[i] );
+     126             :   }
+     127          18 : }
+     128             : 
+     129       10551 : void SelectWithMask::prepare() {
+     130       10551 :   Value* arg = getPntrToArgument(0); Value* out = getPntrToComponent(0);
+     131       10551 :   if( arg->getRank()==1 ) {
+     132             :     Value* mask = getPntrToArgument(1);
+     133       10516 :     std::vector<unsigned> shape(1); shape[0]=getOutputVectorLength( mask );
+     134       10516 :     if( out->getNumberOfValues()!=shape[0] ) {
+     135          19 :       if( shape[0]==1 ) shape.resize(0);
+     136          19 :       out->setShape(shape);
+     137             :     }
+     138          35 :   } else if( arg->getRank()==2 ) {
+     139          35 :     std::vector<unsigned> outshape(2);
+     140          35 :     Value* rmask = getPntrToArgument(1); outshape[0] = getOutputVectorLength( rmask );
+     141          35 :     Value* cmask = getPntrToArgument(2); outshape[1] = getOutputVectorLength( cmask );
+     142          35 :     if( out->getShape()[0]!=outshape[0] || out->getShape()[1]!=outshape[1] ) {
+     143          20 :       out->setShape(outshape); out->reshapeMatrixStore( outshape[1] );
+     144             :     }
+     145             :   }
+     146       10551 : }
+     147             : 
+     148       10543 : void SelectWithMask::calculate() {
+     149       10543 :   Value* arg = getPntrToArgument(0); Value* out = getPntrToComponent(0);
+     150       10543 :   if( arg->getRank()==1 ) {
+     151             :     Value* mask = getPntrToArgument(1); unsigned n=0;
+     152      149144 :     for(unsigned i=0; i<mask->getNumberOfValues(); ++i) {
+     153      138632 :       if( fabs(mask->get(i))>0 ) continue;
+     154      131198 :       out->set(n, arg->get(i) ); n++;
+     155             :     }
+     156          31 :   } else if ( arg->getRank()==2 ) {
+     157          31 :     std::vector<unsigned> outshape( out->getShape() );
+     158          31 :     unsigned n = 0; std::vector<unsigned> inshape( arg->getShape() );
+     159             :     Value* rmask = getPntrToArgument(1); Value* cmask = getPntrToArgument(2);
+     160        1774 :     for(unsigned i=0; i<inshape[0]; ++i) {
+     161        1743 :       if( fabs(rmask->get(i))>0 ) continue;
+     162             :       unsigned m = 0;
+     163      378651 :       for(unsigned j=0; j<inshape[1]; ++j) {
+     164      377500 :         if( fabs(cmask->get(j))>0 ) continue;
+     165      189405 :         out->set( n*outshape[1] + m, arg->get(i*inshape[1] + j) );
+     166      189405 :         m++;
+     167             :       }
+     168        1151 :       n++;
+     169             :     }
+     170             :   }
+     171       10543 : }
+     172             : 
+     173       10505 : void SelectWithMask::apply() {
+     174       10505 :   if( doNotCalculateDerivatives() || !getPntrToComponent(0)->forcesWereAdded() ) return ;
+     175             : 
+     176       10443 :   Value* arg = getPntrToArgument(0); Value* out = getPntrToComponent(0);
+     177       10443 :   if( arg->getRank()==1 ) {
+     178             :     unsigned n=0; Value* mask = getPntrToArgument(1);
+     179      145276 :     for(unsigned i=0; i<mask->getNumberOfValues(); ++i) {
+     180      134833 :       if( fabs(mask->get(i))>0 ) continue;
+     181      130680 :       arg->addForce(i, out->getForce(n) ); n++;
+     182             :     }
+     183           0 :   } else if( arg->getRank()==2 ) {
+     184             :     unsigned n = 0;
+     185           0 :     std::vector<unsigned> inshape( arg->getShape() );
+     186           0 :     std::vector<unsigned> outshape( out->getShape() );
+     187             :     Value* rmask = getPntrToArgument(1); Value* cmask = getPntrToArgument(2);
+     188           0 :     for(unsigned i=0; i<inshape[0]; ++i) {
+     189           0 :       if( fabs(rmask->get(i))>0 ) continue;
+     190             :       unsigned m = 0;
+     191           0 :       for(unsigned j=0; j<inshape[1]; ++j) {
+     192           0 :         if( fabs(cmask->get(j))>0 ) continue;
+     193           0 :         arg->addForce( i*inshape[1] + j, out->getForce(n*outshape[1] + m) );
+     194           0 :         m++;
+     195             :       }
+     196           0 :       n++;
+     197             :     }
+     198             :   }
+     199             : }
+     200             : 
+     201             : 
+     202             : 
+     203             : }
+     204             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/valtools/index-sort-f.html b/coverage/valtools/index-sort-f.html new file mode 100644 index 000000000000..26934a2b0945 --- /dev/null +++ b/coverage/valtools/index-sort-f.html @@ -0,0 +1,124 @@ + + + + + + + + LCOV - plumed test coverage - valtools + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - valtoolsHitTotalCoverage
Test:plumed test coverageLines:23024793.1 %
Date:2024-04-19 12:12:35Functions:202483.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
SelectComponents.cpp +
96.8%96.8%
+
96.8 %30 / 3166.7 %2 / 3
Flatten.cpp +
100.0%
+
100.0 %26 / 2683.3 %5 / 6
Concatenate.cpp +
95.4%95.4%
+
95.4 %83 / 8783.3 %5 / 6
SelectWithMask.cpp +
88.3%88.3%
+
88.3 %91 / 10388.9 %8 / 9
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/valtools/index-sort-l.html b/coverage/valtools/index-sort-l.html new file mode 100644 index 000000000000..b02bec1a6baa --- /dev/null +++ b/coverage/valtools/index-sort-l.html @@ -0,0 +1,124 @@ + + + + + + + + LCOV - plumed test coverage - valtools + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - valtoolsHitTotalCoverage
Test:plumed test coverageLines:23024793.1 %
Date:2024-04-19 12:12:35Functions:202483.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
SelectWithMask.cpp +
88.3%88.3%
+
88.3 %91 / 10388.9 %8 / 9
Concatenate.cpp +
95.4%95.4%
+
95.4 %83 / 8783.3 %5 / 6
SelectComponents.cpp +
96.8%96.8%
+
96.8 %30 / 3166.7 %2 / 3
Flatten.cpp +
100.0%
+
100.0 %26 / 2683.3 %5 / 6
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/valtools/index.html b/coverage/valtools/index.html new file mode 100644 index 000000000000..6e0f67629ab0 --- /dev/null +++ b/coverage/valtools/index.html @@ -0,0 +1,124 @@ + + + + + + + + LCOV - plumed test coverage - valtools + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - valtoolsHitTotalCoverage
Test:plumed test coverageLines:23024793.1 %
Date:2024-04-19 12:12:35Functions:202483.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Concatenate.cpp +
95.4%95.4%
+
95.4 %83 / 8783.3 %5 / 6
Flatten.cpp +
100.0%
+
100.0 %26 / 2683.3 %5 / 6
SelectComponents.cpp +
96.8%96.8%
+
96.8 %30 / 3166.7 %2 / 3
SelectWithMask.cpp +
88.3%88.3%
+
88.3 %91 / 10388.9 %8 / 9
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vatom/ArgsToVatom.cpp.func-sort-c.html b/coverage/vatom/ArgsToVatom.cpp.func-sort-c.html new file mode 100644 index 000000000000..8269c2020a27 --- /dev/null +++ b/coverage/vatom/ArgsToVatom.cpp.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - vatom/ArgsToVatom.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vatom - ArgsToVatom.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:627286.1 %
Date:2024-04-19 12:12:35Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5vatom11ArgsToVatomC2ERKNS_13ActionOptionsE0
_ZN4PLMD5vatom11ArgsToVatomC1ERKNS_13ActionOptionsE9
_ZN4PLMD5vatom11ArgsToVatom16registerKeywordsERNS_8KeywordsE11
_ZN4PLMD5vatom11ArgsToVatom5applyEv26
_ZN4PLMD5vatom11ArgsToVatom9calculateEv26
_ZN4PLMD5vatom11ArgsToVatom22getNumberOfDerivativesEv121
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vatom/ArgsToVatom.cpp.func.html b/coverage/vatom/ArgsToVatom.cpp.func.html new file mode 100644 index 000000000000..b5ebd1efa58e --- /dev/null +++ b/coverage/vatom/ArgsToVatom.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - vatom/ArgsToVatom.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vatom - ArgsToVatom.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:627286.1 %
Date:2024-04-19 12:12:35Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5vatom11ArgsToVatom16registerKeywordsERNS_8KeywordsE11
_ZN4PLMD5vatom11ArgsToVatom22getNumberOfDerivativesEv121
_ZN4PLMD5vatom11ArgsToVatom5applyEv26
_ZN4PLMD5vatom11ArgsToVatom9calculateEv26
_ZN4PLMD5vatom11ArgsToVatomC1ERKNS_13ActionOptionsE9
_ZN4PLMD5vatom11ArgsToVatomC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vatom/ArgsToVatom.cpp.gcov.html b/coverage/vatom/ArgsToVatom.cpp.gcov.html new file mode 100644 index 000000000000..1d20323a52f3 --- /dev/null +++ b/coverage/vatom/ArgsToVatom.cpp.gcov.html @@ -0,0 +1,238 @@ + + + + + + + + LCOV - plumed test coverage - vatom/ArgsToVatom.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vatom - ArgsToVatom.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:627286.1 %
Date:2024-04-19 12:12:35Functions:5683.3 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2014-2017 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received 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/ActionWithArguments.h"
+      23             : #include "core/ActionWithValue.h"
+      24             : #include "core/ActionRegister.h"
+      25             : #include "core/ActionSet.h"
+      26             : #include "core/PlumedMain.h"
+      27             : #include "core/PbcAction.h"
+      28             : #include "tools/Pbc.h"
+      29             : 
+      30             : //+PLUMEDOC VATOM ARGS2VATOM
+      31             : /*
+      32             : Create a virtual atom from the input scalars
+      33             : 
+      34             : \par Examples
+      35             : 
+      36             : */
+      37             : //+ENDPLUMEDOC
+      38             : 
+      39             : namespace PLMD {
+      40             : namespace vatom {
+      41             : 
+      42             : class ArgsToVatom :
+      43             :   public ActionWithValue,
+      44             :   public ActionWithArguments {
+      45             : private:
+      46             :   bool fractional;
+      47             :   PbcAction* pbc_action;
+      48             : public:
+      49             :   static void registerKeywords( Keywords& keys );
+      50             : /// Constructor
+      51             :   explicit ArgsToVatom(const ActionOptions&);
+      52             : /// Get the number of derivatives
+      53         121 :   unsigned getNumberOfDerivatives() override { return getNumberOfArguments(); }
+      54             : /// Do the calculation
+      55             :   void calculate() override;
+      56             : ///
+      57             :   void apply() override;
+      58             : };
+      59             : 
+      60             : PLUMED_REGISTER_ACTION(ArgsToVatom,"ARGS2VATOM")
+      61             : 
+      62          11 : void ArgsToVatom::registerKeywords( Keywords& keys ) {
+      63          11 :   Action::registerKeywords( keys ); ActionWithValue::registerKeywords( keys ); ActionWithArguments::registerKeywords( keys );
+      64          22 :   keys.add("compulsory","XPOS","the x position of the atom");
+      65          22 :   keys.add("compulsory","YPOS","the y position of the atom");
+      66          22 :   keys.add("compulsory","ZPOS","the z position of the atom");
+      67          22 :   keys.add("compulsory","MASS","the mass of the atom");
+      68          22 :   keys.add("compulsory","CHARGE","the charge of the atom");
+      69          22 :   keys.add("hidden","XBKP","x position to use in case PBC not set when using PHASES");
+      70          22 :   keys.add("hidden","YBKP","y position to use in case PBC not set when using PHASES");
+      71          22 :   keys.add("hidden","ZBKP","z position to use in case PBC not set when using PHASES");
+      72          22 :   keys.addFlag("FRACTIONAL",false,"the input arguments are calculated in fractional coordinates so you need to multiply by the cell");
+      73          22 :   keys.addOutputComponent("x","default","the x coordinate of the virtual atom");
+      74          22 :   keys.addOutputComponent("y","default","the y coordinate of the virtual atom");
+      75          22 :   keys.addOutputComponent("z","default","the z coordinate of the virtual atom");
+      76          22 :   keys.addOutputComponent("mass","default","the mass of the virtual atom");
+      77          22 :   keys.addOutputComponent("charge","default","the charge of the virtual atom");
+      78          11 : }
+      79             : 
+      80           9 : ArgsToVatom::ArgsToVatom(const ActionOptions& ao):
+      81             :   Action(ao),
+      82             :   ActionWithValue(ao),
+      83           9 :   ActionWithArguments(ao)
+      84             : {
+      85          18 :   parseFlag("FRACTIONAL",fractional);
+      86          18 :   std::vector<Value*> xpos; parseArgumentList("XPOS",xpos);
+      87           9 :   if( xpos.size()!=1 && xpos[0]->getRank()!=0 ) error("invalid input argument for XPOS");
+      88          18 :   std::vector<Value*> ypos; parseArgumentList("YPOS",ypos);
+      89           9 :   if( ypos.size()!=1 && ypos[0]->getRank()!=0 ) error("invalid input argument for YPOS");
+      90          18 :   std::vector<Value*> zpos; parseArgumentList("ZPOS",zpos);
+      91           9 :   if( zpos.size()!=1 && zpos[0]->getRank()!=0 ) error("invalid input argument for ZPOS");
+      92          18 :   std::vector<Value*> mass; parseArgumentList("MASS",mass);
+      93           9 :   if( mass.size()!=1 && mass[0]->getRank()!=0 ) error("invalid input argument for MASS");
+      94          18 :   std::vector<Value*> charge; parseArgumentList("CHARGE",charge);
+      95           9 :   if( charge.size()!=1 && charge[0]->getRank()!=0 ) error("invalid input argument for CHARGE");
+      96             :   // Make sure we have requested everything that we need in xpos
+      97           9 :   xpos.push_back(ypos[0]); xpos.push_back(zpos[0]); xpos.push_back(mass[0]); xpos.push_back(charge[0]);
+      98           9 :   if( fractional ) {
+      99           7 :     log.printf("  creating atom from fractional pos a=%s, b=%s and c=%s \n", xpos[0]->getName().c_str(), ypos[0]->getName().c_str(), zpos[0]->getName().c_str() );
+     100          14 :     std::vector<Value*> xbkp; parseArgumentList("XBKP",xbkp);
+     101           7 :     if( xbkp.size()>0 ) {
+     102           0 :       if( xbkp.size()!=1 && xbkp[0]->getRank()!=0 ) error("invalid input argument for XBKP");
+     103           0 :       std::vector<Value*> ybkp; parseArgumentList("YBKP",ybkp);
+     104           0 :       if( ybkp.size()!=1 && ybkp[0]->getRank()!=0 ) error("invalid input argument for YBKP");
+     105           0 :       std::vector<Value*> zbkp; parseArgumentList("ZBKP",zbkp);
+     106           0 :       if( zbkp.size()!=1 && zpos[0]->getRank()!=0 ) error("invalid input argument for ZBKP");
+     107             :       // Store backup for NOPBC
+     108           0 :       xpos.push_back(xbkp[0]); xpos.push_back(ybkp[0]); xpos.push_back(zbkp[0]);
+     109           0 :       log.printf("  using x=%s, y=%s and z=%s if PBC not set \n", xbkp[0]->getName().c_str(), ybkp[0]->getName().c_str(), zbkp[0]->getName().c_str() );
+     110             :     }
+     111           2 :   } else log.printf("  creating atom at x=%s, y=%s and z=%s \n", xpos[0]->getName().c_str(), ypos[0]->getName().c_str(), zpos[0]->getName().c_str() );
+     112           9 :   log.printf("  mass of atom is %s and charge is %s \n", mass[0]->getName().c_str(), charge[0]->getName().c_str() );
+     113             :   // Request the arguments
+     114           9 :   requestArguments(xpos);
+     115             :   // Create the components to hold the atom
+     116          27 :   addComponentWithDerivatives("x"); componentIsNotPeriodic("x");
+     117          27 :   addComponentWithDerivatives("y"); componentIsNotPeriodic("y");
+     118          27 :   addComponentWithDerivatives("z"); componentIsNotPeriodic("z");
+     119          27 :   addComponent("mass"); componentIsNotPeriodic("mass"); if( mass[0]->isConstant() ) getPntrToComponent(3)->setConstant();
+     120          27 :   addComponent("charge"); componentIsNotPeriodic("charge"); if( charge[0]->isConstant() ) getPntrToComponent(4)->setConstant();
+     121           9 :   pbc_action = plumed.getActionSet().selectWithLabel<PbcAction*>("Box");
+     122          36 :   for(unsigned i=0; i<3; ++i) getPntrToComponent(i)->resizeDerivatives( getNumberOfArguments() );
+     123           9 : }
+     124             : 
+     125          26 : void ArgsToVatom::calculate() {
+     126          26 :   if( fractional ) {
+     127          24 :     if( pbc_action->getPbc().isSet() ) {
+     128             :       // Get the position in fractional coordinates
+     129          96 :       Vector fpos; for(unsigned i=0; i<3; ++i) fpos[i] = getPntrToArgument(i)->get();
+     130             :       // Convert fractioanl coordinates to cartesian coordinates
+     131          24 :       Tensor box=pbc_action->getPbc().getBox(); Vector cpos=matmul(fpos,box);
+     132             :       // Set the final position and derivatives
+     133          96 :       for(unsigned i=0; i<3; ++i) {
+     134          72 :         Value* vv=getPntrToComponent(i); vv->set( cpos[i] );
+     135         288 :         for(unsigned j=0; j<3; ++j) vv->addDerivative( j, box[j][i] );
+     136             :       }
+     137             :     } else {
+     138           0 :       if( getNumberOfArguments()<8 ) error("cannot use PHASES option if box is not set");
+     139             :       // Set the values
+     140           0 :       for(unsigned i=0; i<3; ++i) getPntrToComponent(i)->set( getPntrToArgument(5+i)->get() );
+     141             :       // And the derivatives
+     142           0 :       for(unsigned i=0; i<3; ++i) getPntrToComponent(i)->addDerivative( 5+i, 1.0 );
+     143             :     }
+     144             :     // Set the mass and charge
+     145          72 :     for(unsigned i=3; i<5; ++i) getPntrToComponent(i)->set( getPntrToArgument(i)->get() );
+     146             :   } else {
+     147             :     // Set the values
+     148          12 :     for(unsigned i=0; i<5; ++i) getPntrToComponent(i)->set( getPntrToArgument(i)->get() );
+     149             :     // And the derivatives
+     150           8 :     for(unsigned i=0; i<3; ++i) getPntrToComponent(i)->addDerivative( i, 1.0 );
+     151             :   }
+     152          26 : }
+     153             : 
+     154          26 : void ArgsToVatom::apply() {
+     155          26 :   if( !checkForForces() ) return ;
+     156             : 
+     157           7 :   unsigned start=0; addForcesOnArguments( 0, getForcesToApply(), start, getLabel() );
+     158             : }
+     159             : 
+     160             : }
+     161             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vatom/Center.cpp.func-sort-c.html b/coverage/vatom/Center.cpp.func-sort-c.html new file mode 100644 index 000000000000..6e53601ff09a --- /dev/null +++ b/coverage/vatom/Center.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - vatom/Center.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vatom - Center.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12112299.2 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5vatom6CenterC2ERKNS_13ActionOptionsE0
_ZN4PLMD5vatom6CenterC1ERKNS_13ActionOptionsE9573
_ZN4PLMD5vatom6Center16registerKeywordsERNS_8KeywordsE9577
_ZN4PLMD5vatom6Center9calculateEv32946
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vatom/Center.cpp.func.html b/coverage/vatom/Center.cpp.func.html new file mode 100644 index 000000000000..7455ff3d08e4 --- /dev/null +++ b/coverage/vatom/Center.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - vatom/Center.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vatom - Center.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12112299.2 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5vatom6Center16registerKeywordsERNS_8KeywordsE9577
_ZN4PLMD5vatom6Center9calculateEv32946
_ZN4PLMD5vatom6CenterC1ERKNS_13ActionOptionsE9573
_ZN4PLMD5vatom6CenterC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vatom/Center.cpp.gcov.html b/coverage/vatom/Center.cpp.gcov.html new file mode 100644 index 000000000000..5227e619d9b8 --- /dev/null +++ b/coverage/vatom/Center.cpp.gcov.html @@ -0,0 +1,405 @@ + + + + + + + + LCOV - plumed test coverage - vatom/Center.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vatom - Center.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12112299.2 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "ActionWithVirtualAtom.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "core/PlumedMain.h"
+      25             : #include <cmath>
+      26             : #include <limits>
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace vatom {
+      30             : 
+      31             : //+PLUMEDOC VATOM CENTER_FAST
+      32             : /*
+      33             : Calculate the center for a group of atoms, with arbitrary weights.
+      34             : 
+      35             : \par Examples
+      36             : 
+      37             : */
+      38             : //+ENDPLUMEDOC
+      39             : 
+      40             : //+PLUMEDOC VATOM CENTER
+      41             : /*
+      42             : Calculate the center for a group of atoms, with arbitrary weights.
+      43             : 
+      44             : The computed
+      45             : center is stored as a virtual atom that can be accessed in
+      46             : an atom list through the label for the CENTER action that creates it.
+      47             : Notice that the generated virtual atom has charge equal to the sum of the
+      48             : charges and mass equal to the sum of the masses. If used with the MASS flag,
+      49             : then it provides a result identical to \ref COM.
+      50             : 
+      51             : When running with periodic boundary conditions, the atoms should be
+      52             : in the proper periodic image. This is done automatically since PLUMED 2.2,
+      53             : by considering the ordered list of atoms and rebuilding the molecule using a procedure
+      54             : that is equivalent to that done in \ref WHOLEMOLECULES . Notice that
+      55             : rebuilding is local to this action. This is different from \ref WHOLEMOLECULES
+      56             : which actually modifies the coordinates stored in PLUMED.
+      57             : 
+      58             : In case you want to recover the old behavior you should use the NOPBC flag.
+      59             : In that case you need to take care that atoms are in the correct
+      60             : periodic image.
+      61             : 
+      62             : \note As an experimental feature, CENTER also supports a keyword PHASES.
+      63             : 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
+      64             : trigonometric functions, similarly to \ref CENTER_OF_MULTICOLVAR.
+      65             : Notice that by construction this center position is
+      66             : not invariant with respect to rotations of the atoms at fixed cell lattice.
+      67             : In addition, for symmetric Bravais lattices, it is not invariant with respect
+      68             : to special symmetries. E.g., if you have an hexagonal cell, the center will
+      69             : not be invariant with respect to rotations of 120 degrees.
+      70             : On the other hand, it might make the treatment of PBC easier in difficult cases.
+      71             : 
+      72             : \par Examples
+      73             : 
+      74             : \plumedfile
+      75             : # a point which is on the line connecting atoms 1 and 10, so that its distance
+      76             : # from 10 is twice its distance from 1:
+      77             : c1: CENTER ATOMS=1,1,10
+      78             : # this is another way of stating the same:
+      79             : c1bis: CENTER ATOMS=1,10 WEIGHTS=2,1
+      80             : 
+      81             : # center of mass among these atoms:
+      82             : c2: CENTER ATOMS=2,3,4,5 MASS
+      83             : 
+      84             : d1: DISTANCE ATOMS=c1,c2
+      85             : 
+      86             : PRINT ARG=d1
+      87             : \endplumedfile
+      88             : 
+      89             : */
+      90             : //+ENDPLUMEDOC
+      91             : 
+      92             : //+PLUMEDOC VATOM COM
+      93             : /*
+      94             : Calculate the center of mass for a group of atoms.
+      95             : 
+      96             : The computed
+      97             : center of mass is stored as a virtual atom that can be accessed in
+      98             : an atom list through the label for the COM action that creates it.
+      99             : 
+     100             : For arbitrary weights (e.g. geometric center) see \ref CENTER.
+     101             : 
+     102             : When running with periodic boundary conditions, the atoms should be
+     103             : in the proper periodic image. This is done automatically since PLUMED 2.2,
+     104             : by considering the ordered list of atoms and rebuilding the molecule using a procedure
+     105             : that is equivalent to that done in \ref WHOLEMOLECULES . Notice that
+     106             : rebuilding is local to this action. This is different from \ref WHOLEMOLECULES
+     107             : which actually modifies the coordinates stored in PLUMED.
+     108             : 
+     109             : In case you want to recover the old behavior you should use the NOPBC flag.
+     110             : In that case you need to take care that atoms are in the correct
+     111             : periodic image.
+     112             : 
+     113             : \par Examples
+     114             : 
+     115             : The following input instructs plumed to print the distance between the
+     116             : center of mass for atoms 1,2,3,4,5,6,7 and that for atoms 15,20:
+     117             : \plumedfile
+     118             : c1: COM ATOMS=1-7
+     119             : c2: COM ATOMS=15,20
+     120             : d1: DISTANCE ATOMS=c1,c2
+     121             : PRINT ARG=d1
+     122             : \endplumedfile
+     123             : 
+     124             : */
+     125             : //+ENDPLUMEDOC
+     126             : 
+     127             : 
+     128             : class Center:
+     129             :   public ActionWithVirtualAtom
+     130             : {
+     131             :   std::vector<double> weights;
+     132             :   std::vector<Tensor> dcenter_sin;
+     133             :   std::vector<Tensor> dcenter_cos;
+     134             :   std::vector<Tensor> deriv;
+     135             :   bool isChargeSet_;
+     136             :   bool isMassSet_;
+     137             :   bool weight_mass;
+     138             :   bool nopbc;
+     139             :   bool first;
+     140             :   bool phases;
+     141             : public:
+     142             :   explicit Center(const ActionOptions&ao);
+     143             :   void calculate() override;
+     144             :   static void registerKeywords( Keywords& keys );
+     145             : };
+     146             : 
+     147             : PLUMED_REGISTER_ACTION(Center,"CENTER_FAST")
+     148             : PLUMED_REGISTER_ACTION(Center,"COM")
+     149             : 
+     150        9577 : void Center::registerKeywords(Keywords& keys) {
+     151        9577 :   ActionWithVirtualAtom::registerKeywords(keys);
+     152       19154 :   keys.add("optional","WEIGHTS","Center is computed as a weighted average.");
+     153       19154 :   keys.add("optional","SET_CHARGE","Set the charge of the virtual atom to a given value.");
+     154       19154 :   keys.add("optional","SET_MASS","Set the mass of the virtual atom to a given value.");
+     155       19154 :   keys.addFlag("NOPBC",false,"ignore the periodic boundary conditions when calculating distances");
+     156       19154 :   keys.addFlag("MASS",false,"If set center is mass weighted");
+     157       19154 :   keys.addFlag("PHASES",false,"Compute center using trigonometric phases");
+     158        9577 : }
+     159             : 
+     160        9573 : Center::Center(const ActionOptions&ao):
+     161             :   Action(ao),
+     162             :   ActionWithVirtualAtom(ao),
+     163        9573 :   isChargeSet_(false),
+     164        9573 :   isMassSet_(false),
+     165        9573 :   weight_mass(false),
+     166        9573 :   nopbc(false),
+     167        9573 :   first(true),
+     168        9573 :   phases(false)
+     169             : {
+     170             :   std::vector<AtomNumber> atoms;
+     171       19146 :   parseAtomList("ATOMS",atoms);
+     172        9573 :   if(atoms.size()==0) error("at least one atom should be specified");
+     173        9573 :   parseVector("WEIGHTS",weights);
+     174        9573 :   parseFlag("MASS",weight_mass);
+     175        9573 :   parseFlag("NOPBC",nopbc);
+     176        9573 :   parseFlag("PHASES",phases);
+     177       19146 :   double charge_=std::numeric_limits<double>::lowest(); parse("SET_CHARGE",charge_); setCharge(charge_);
+     178        9573 :   if(charge_!=std::numeric_limits<double>::lowest()) isChargeSet_=true;
+     179       19146 :   double mass_=-1; parse("SET_MASS",mass_); setMass(mass_);
+     180        9573 :   if(mass_>0.) isMassSet_=true;
+     181        9573 :   if(mass_==0.) error("SETMASS must be greater than 0");
+     182        9573 :   if( getName()=="COM") weight_mass=true;
+     183        9573 :   checkRead();
+     184        9573 :   log.printf("  of atoms:");
+     185       88592 :   for(unsigned i=0; i<atoms.size(); ++i) {
+     186       79019 :     if(i%25==0) log<<"\n";
+     187       79019 :     log.printf(" %d",atoms[i].serial());
+     188             :   }
+     189        9573 :   log<<"\n";
+     190        9573 :   if(weight_mass) {
+     191        1840 :     log<<"  mass weighted\n";
+     192        1840 :     if(weights.size()!=0) error("WEIGHTS and MASS keywords cannot not be used simultaneously");
+     193             :   } else {
+     194        7733 :     if( weights.size()==0) {
+     195         690 :       log<<" using the geometric center\n";
+     196         690 :       weights.resize( atoms.size() );
+     197        3106 :       for(unsigned i=0; i<atoms.size(); i++) weights[i] = 1.;
+     198             :     } else {
+     199        7043 :       log<<" with weights:";
+     200        7044 :       if( weights.size()!=atoms.size() ) error("number of elements in weight vector does not match the number of atoms");
+     201       35274 :       for(unsigned i=0; i<weights.size(); ++i) {
+     202       28232 :         if(i%25==0) log<<"\n";
+     203       28232 :         log.printf(" %f",weights[i]);
+     204             :       }
+     205        7042 :       log.printf("\n");
+     206             :     }
+     207             :   }
+     208        9572 :   if(phases) {
+     209           4 :     log<<"  Phases will be used to take into account PBC\n";
+     210        9568 :   } else if(nopbc) {
+     211          47 :     log<<"  PBC will be ignored\n";
+     212             :   } else {
+     213        9521 :     log<<"  broken molecules will be rebuilt assuming atoms are in the proper order\n";
+     214             :   }
+     215        9572 :   requestAtoms(atoms);
+     216        9574 : }
+     217             : 
+     218       32946 : void Center::calculate() {
+     219       32946 :   Vector pos;
+     220       32946 :   const bool dophases=(getPbc().isSet() ? phases : false);
+     221             : 
+     222       32946 :   if(!nopbc && !dophases) makeWhole();
+     223             : 
+     224       32946 :   if( first ) {
+     225       15376 :     if( weight_mass ) {
+     226      172257 :       for(unsigned i=0; i<getNumberOfAtoms(); i++) {
+     227      164230 :         if(std::isnan(getMass(i))) {
+     228           0 :           error(
+     229             :             "You are trying to compute a CENTER or COM but masses are not known.\n"
+     230             :             "        If you are using plumed driver, please use the --mc option"
+     231             :           );
+     232             :         }
+     233             :       }
+     234             :     }
+     235             :     double mass(0.0);
+     236      209364 :     for(unsigned i=0; i<getNumberOfAtoms(); i++) mass+=getMass(i);
+     237       15376 :     if( chargesWereSet && !isChargeSet_) {
+     238             :       double charge(0.0);
+     239      192732 :       for(unsigned i=0; i<getNumberOfAtoms(); i++) charge+=getCharge(i);
+     240       13318 :       setCharge(charge);
+     241        2058 :     } else if( !isChargeSet_ ) {
+     242        2056 :       setCharge(0.0);
+     243             :     }
+     244       15376 :     if(!isMassSet_) setMass(mass);
+     245             : 
+     246       15376 :     if( weight_mass ) {
+     247        8027 :       weights.resize( getNumberOfAtoms() );
+     248      172257 :       for(unsigned i=0; i<weights.size(); i++) weights[i] = getMass(i) / mass;
+     249             :     } else {
+     250             :       double wtot=0.0;
+     251       37107 :       for(unsigned i=0; i<weights.size(); i++) wtot+=weights[i];
+     252       37107 :       for(unsigned i=0; i<weights.size(); i++) weights[i]=weights[i]/wtot;
+     253        7349 :       first=false;
+     254             :     }
+     255             :   }
+     256             : 
+     257       32946 :   deriv.resize(getNumberOfAtoms());
+     258             : 
+     259       32946 :   if(dophases) {
+     260         241 :     dcenter_sin.resize(getNumberOfAtoms());
+     261         241 :     dcenter_cos.resize(getNumberOfAtoms());
+     262         241 :     Vector center_sin;
+     263         241 :     Vector center_cos;
+     264         241 :     Tensor invbox2pi=2*pi*getPbc().getInvBox();
+     265         241 :     Tensor box2pi=getPbc().getBox() / (2*pi);
+     266         964 :     for(unsigned i=0; i<getNumberOfAtoms(); ++i) {
+     267         723 :       double w=weights[i];
+     268             : 
+     269             :       // real to scaled
+     270         723 :       const Vector scaled=matmul(getPosition(i),invbox2pi);
+     271             :       const Vector ccos(
+     272         723 :         w*std::cos(scaled[0]),
+     273         723 :         w*std::cos(scaled[1]),
+     274         723 :         w*std::cos(scaled[2])
+     275         723 :       );
+     276             :       const Vector csin(
+     277         723 :         w*std::sin(scaled[0]),
+     278         723 :         w*std::sin(scaled[1]),
+     279         723 :         w*std::sin(scaled[2])
+     280         723 :       );
+     281         723 :       center_cos+=ccos;
+     282         723 :       center_sin+=csin;
+     283        9399 :       for(unsigned l=0; l<3; l++) for(unsigned k=0; k<3; k++) {
+     284             :           // k over real coordinates
+     285             :           // l over scaled coordinates
+     286        6507 :           dcenter_sin[i][l][k]=ccos[l]*invbox2pi[k][l];
+     287        6507 :           dcenter_cos[i][l][k]=-csin[l]*invbox2pi[k][l];
+     288             :         }
+     289             :     }
+     290             :     const Vector c(
+     291         241 :       std::atan2(center_sin[0],center_cos[0]),
+     292         241 :       std::atan2(center_sin[1],center_cos[1]),
+     293         241 :       std::atan2(center_sin[2],center_cos[2])
+     294         241 :     );
+     295             : 
+     296             :     // normalization is convenient for doing derivatives later
+     297         964 :     for(unsigned l=0; l<3; l++) {
+     298         723 :       double norm=1.0/(center_sin[l]*center_sin[l]+center_cos[l]*center_cos[l]);
+     299         723 :       center_sin[l]*=norm;
+     300         723 :       center_cos[l]*=norm;
+     301             :     }
+     302             : 
+     303         964 :     for(unsigned i=0; i<getNumberOfAtoms(); ++i) {
+     304         723 :       Tensor dd;
+     305        9399 :       for(unsigned l=0; l<3; l++) for(unsigned k=0; k<3; k++) {
+     306             :           // k over real coordinates
+     307             :           // l over scaled coordinates
+     308        6507 :           dd[l][k]= (center_cos[l]*dcenter_sin[i][l][k] - center_sin[l]*dcenter_cos[i][l][k]);
+     309             :         }
+     310             :       // scaled to real
+     311         723 :       deriv[i]=matmul(dd,box2pi);
+     312             :     }
+     313         241 :     setAtomsDerivatives(deriv);
+     314             :     // scaled to real
+     315         241 :     setPosition(matmul(c,box2pi));
+     316             :   } else {
+     317      412212 :     for(unsigned i=0; i<getNumberOfAtoms(); i++) {
+     318      379507 :       double w=weights[i];
+     319      379507 :       pos+=w*getPosition(i);
+     320      379507 :       deriv[i]=w*Tensor::identity();
+     321             :     }
+     322       32705 :     setPosition(pos);
+     323       32705 :     setAtomsDerivatives(deriv);
+     324             :   }
+     325       32946 : }
+     326             : 
+     327             : }
+     328             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vatom/CenterShortcut.cpp.func-sort-c.html b/coverage/vatom/CenterShortcut.cpp.func-sort-c.html new file mode 100644 index 000000000000..c1b95c40c99b --- /dev/null +++ b/coverage/vatom/CenterShortcut.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - vatom/CenterShortcut.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vatom - CenterShortcut.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:697888.5 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5vatom14CenterShortcutC2ERKNS_13ActionOptionsE0
_ZN4PLMD5vatom14CenterShortcutC1ERKNS_13ActionOptionsE7745
_ZN4PLMD5vatom14CenterShortcut16registerKeywordsERNS_8KeywordsE7747
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vatom/CenterShortcut.cpp.func.html b/coverage/vatom/CenterShortcut.cpp.func.html new file mode 100644 index 000000000000..2abe72e81ffa --- /dev/null +++ b/coverage/vatom/CenterShortcut.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - vatom/CenterShortcut.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vatom - CenterShortcut.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:697888.5 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5vatom14CenterShortcut16registerKeywordsERNS_8KeywordsE7747
_ZN4PLMD5vatom14CenterShortcutC1ERKNS_13ActionOptionsE7745
_ZN4PLMD5vatom14CenterShortcutC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vatom/CenterShortcut.cpp.gcov.html b/coverage/vatom/CenterShortcut.cpp.gcov.html new file mode 100644 index 000000000000..226c1f2032ce --- /dev/null +++ b/coverage/vatom/CenterShortcut.cpp.gcov.html @@ -0,0 +1,231 @@ + + + + + + + + LCOV - plumed test coverage - vatom/CenterShortcut.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vatom - CenterShortcut.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:697888.5 %
Date:2024-04-19 12:12:35Functions:2366.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2020 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             :    See http://www.plumed.org for more information.
+       5             :    This file is part of plumed, version 2.
+       6             :    plumed 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             :    plumed 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             :    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 "core/ActionRegister.h"
+      18             : #include "core/PlumedMain.h"
+      19             : #include "core/ActionSet.h"
+      20             : #include "core/Group.h"
+      21             : #include "core/ActionWithValue.h"
+      22             : #include "core/ActionShortcut.h"
+      23             : 
+      24             : namespace PLMD {
+      25             : namespace vatom {
+      26             : 
+      27             : class CenterShortcut : public ActionShortcut {
+      28             : public:
+      29             :   static void registerKeywords( Keywords& keys );
+      30             :   explicit CenterShortcut(const ActionOptions&);
+      31             : };
+      32             : 
+      33             : PLUMED_REGISTER_ACTION(CenterShortcut,"CENTER")
+      34             : 
+      35        7747 : void CenterShortcut::registerKeywords( Keywords& keys ) {
+      36        7747 :   ActionShortcut::registerKeywords( keys );
+      37       15494 :   keys.add("atoms","ATOMS","the group of atoms that you are calculating the Gyration Tensor for");
+      38       15494 :   keys.add("compulsory","TYPE","RADIUS","The type of calculation relative to the Gyration Tensor you want to perform");
+      39       15494 :   keys.addFlag("NOPBC",false,"ignore the periodic boundary conditions when calculating distances");
+      40       15494 :   keys.add("optional","WEIGHTS","what weights should be used when calculating the center.  If this keyword is not present the geometric center is computed. "
+      41             :            "If WEIGHTS=@Masses is used the center of mass is computed.  If WEIGHTS=@charges the center of charge is computed.  If "
+      42             :            "the label of an action is provided PLUMED assumes that that action calculates a list of symmetry functions that can be used "
+      43             :            "as weights. Lastly, an explicit list of numbers to use as weights can be provided");
+      44       15494 :   keys.addFlag("PHASES",false,"use trigonometric phases when computing position of center");
+      45       15494 :   keys.addFlag("SAFE_PHASES",false,"use trignomentric phases when computing position of center but also compute the center in ths usual way and use this when the pbc are not set. "
+      46             :                "There are two reasons for using this option (1) you are doing something that you know is really weird or (2) you are an idiot");
+      47       15494 :   keys.addFlag("MASS",false,"calculate the center of mass"); keys.addActionNameSuffix("_FAST");
+      48       30988 :   keys.needsAction("MASS"); keys.needsAction("SUM"); keys.needsAction("CHARGE"); keys.needsAction("CONSTANT");
+      49       23241 :   keys.needsAction("CUSTOM"); keys.needsAction("POSITION"); keys.needsAction("ARGS2VATOM");
+      50        7747 : }
+      51             : 
+      52        7745 : CenterShortcut::CenterShortcut(const ActionOptions& ao):
+      53             :   Action(ao),
+      54        7745 :   ActionShortcut(ao)
+      55             : {
+      56             :   // Read in what we are doing with the weights
+      57       15490 :   bool usemass; parseFlag("MASS",usemass);
+      58        7745 :   std::vector<std::string> str_weights; parseVector("WEIGHTS",str_weights);
+      59        7754 :   if( usemass || str_weights.size()==0 || str_weights.size()>1 || (str_weights.size()==1 && str_weights[0]=="@Masses") ) {
+      60        7736 :     if( usemass && str_weights.size()!=0 ) error("WEIGHTS and MASS keywords cannot not be used simultaneously");
+      61             :     std::string wt_str;
+      62        7735 :     if( str_weights.size()>0 ) {
+      63       35278 :       wt_str="WEIGHTS=" + str_weights[0]; for(unsigned i=1; i<str_weights.size(); ++i) wt_str += "," + str_weights[i];
+      64             :     }
+      65        7735 :     if( usemass || (str_weights.size()==1 && str_weights[0]=="@Masses") ) wt_str = "MASS";
+      66       15474 :     readInputLine( getShortcutLabel() + ": CENTER_FAST " + wt_str + " " + convertInputLineToString() );
+      67             :     return;
+      68             :   }
+      69             :   // Read in the atoms
+      70           9 :   std::string atlist; parse("ATOMS",atlist);
+      71             :   // Calculate the mass of the vatom
+      72          18 :   readInputLine( getShortcutLabel() + "_m: MASS ATOMS=" + atlist );
+      73          18 :   readInputLine( getShortcutLabel() + "_mass: SUM PERIODIC=NO ARG=" + getShortcutLabel() + "_m" );
+      74             :   // Calculate the charge of the vatom
+      75          18 :   readInputLine( getShortcutLabel() + "_q: CHARGE ATOMS=" + atlist );
+      76          18 :   readInputLine( getShortcutLabel() + "_charge: SUM PERIODIC=NO ARG=" + getShortcutLabel() + "_q" );
+      77             :   // Retrieve the number of atoms
+      78           9 :   ActionWithValue* am = plumed.getActionSet().selectWithLabel<ActionWithValue*>( getShortcutLabel() + "_m" );
+      79           9 :   unsigned nat=am->copyOutput(0)->getNumberOfValues();
+      80             :   // Get the weights to use for each atom
+      81           9 :   std::string wlab = getShortcutLabel() + "_w";
+      82           9 :   if( str_weights.size()>0 ) {
+      83           9 :     if( str_weights.size()==1 ) {
+      84           9 :       if( str_weights[0]=="@Charges" ) wlab = getShortcutLabel() + "_q";
+      85             :       else wlab=str_weights[0];
+      86           0 :     } else if( str_weights.size()==nat ) {
+      87           0 :       std::string vals=str_weights[0]; for(unsigned i=1; i<str_weights.size(); ++i) vals += "," + str_weights[i];
+      88           0 :       readInputLine( getShortcutLabel() + "_w: CONSTANT VALUES=" + vals );
+      89           0 :     } else error("invalid input for WEIGHTS keyword " + str_weights[0] );
+      90             :   } else {
+      91           0 :     std::string ones="1"; for(unsigned i=1; i<nat; ++i) ones += ",1";
+      92           0 :     readInputLine( getShortcutLabel() + "_w: CONSTANT VALUES=" + ones );
+      93             :   }
+      94             :   // Read in the instructions on how to compute the center of mass
+      95          18 :   bool safe_phases, phases, nopbc; parseFlag("SAFE_PHASES",safe_phases); parseFlag("NOPBC",nopbc);
+      96          18 :   if( safe_phases ) phases=true; else parseFlag("PHASES",phases);
+      97             :   // This computes a center in the conventional way
+      98           9 :   if( !phases || safe_phases ) {
+      99             :     // Calculate the sum of the weights
+     100           4 :     readInputLine( getShortcutLabel() + "_wnorm: SUM PERIODIC=NO ARG=" + wlab );
+     101             :     // Compute the normalised weights
+     102           4 :     readInputLine( getShortcutLabel() + "_weights: CUSTOM ARG=" + getShortcutLabel() + "_wnorm," + wlab + " FUNC=y/x PERIODIC=NO");
+     103             :     // Get the positions into a multicolvar
+     104           3 :     if( phases || nopbc ) readInputLine( getShortcutLabel() + "_pos: POSITION NOPBC ATOMS=" + atlist );
+     105           2 :     else readInputLine( getShortcutLabel() + "_pos: POSITION WHOLEMOLECULES ATOMS=" + atlist );
+     106             :     // Multiply each vector of positions by the weight
+     107           4 :     readInputLine( getShortcutLabel() + "_xwvec: CUSTOM ARG=" + getShortcutLabel() + "_weights," + getShortcutLabel() + "_pos.x FUNC=x*y PERIODIC=NO");
+     108           4 :     readInputLine( getShortcutLabel() + "_ywvec: CUSTOM ARG=" + getShortcutLabel() + "_weights," + getShortcutLabel() + "_pos.y FUNC=x*y PERIODIC=NO");
+     109           4 :     readInputLine( getShortcutLabel() + "_zwvec: CUSTOM ARG=" + getShortcutLabel() + "_weights," + getShortcutLabel() + "_pos.z FUNC=x*y PERIODIC=NO");
+     110             :     // And sum the weighted vectors
+     111           4 :     readInputLine( getShortcutLabel() + "_x: SUM ARG=" + getShortcutLabel() + "_xwvec PERIODIC=NO");
+     112           4 :     readInputLine( getShortcutLabel() + "_y: SUM ARG=" + getShortcutLabel() + "_ywvec PERIODIC=NO");
+     113           4 :     readInputLine( getShortcutLabel() + "_z: SUM ARG=" + getShortcutLabel() + "_zwvec PERIODIC=NO");
+     114             :   }
+     115             :   // This computes a center using the trigonometric phases
+     116           9 :   if( phases ) {
+     117             :     // Get the positions into a multicolvar
+     118          14 :     readInputLine( getShortcutLabel() + "_fpos: POSITION SCALED_COMPONENTS ATOMS=" + atlist );
+     119             :     // Calculate the sines and cosines of the positions and multiply by the weights
+     120          14 :     readInputLine( getShortcutLabel() + "_sina: CUSTOM ARG=" + wlab + "," + getShortcutLabel() + "_fpos.a FUNC=x*sin(2*pi*y) PERIODIC=NO");
+     121          14 :     readInputLine( getShortcutLabel() + "_cosa: CUSTOM ARG=" + wlab + "," + getShortcutLabel() + "_fpos.a FUNC=x*cos(2*pi*y) PERIODIC=NO");
+     122          14 :     readInputLine( getShortcutLabel() + "_sinb: CUSTOM ARG=" + wlab + "," + getShortcutLabel() + "_fpos.b FUNC=x*sin(2*pi*y) PERIODIC=NO");
+     123          14 :     readInputLine( getShortcutLabel() + "_cosb: CUSTOM ARG=" + wlab + "," + getShortcutLabel() + "_fpos.b FUNC=x*cos(2*pi*y) PERIODIC=NO");
+     124          14 :     readInputLine( getShortcutLabel() + "_sinc: CUSTOM ARG=" + wlab + "," + getShortcutLabel() + "_fpos.c FUNC=x*sin(2*pi*y) PERIODIC=NO");
+     125          14 :     readInputLine( getShortcutLabel() + "_cosc: CUSTOM ARG=" + wlab + "," + getShortcutLabel() + "_fpos.c FUNC=x*cos(2*pi*y) PERIODIC=NO");
+     126             :     // Sum the sines and cosines
+     127          14 :     readInputLine( getShortcutLabel() + "_sinsuma: SUM ARG=" + getShortcutLabel() + "_sina PERIODIC=NO");
+     128          14 :     readInputLine( getShortcutLabel() + "_cossuma: SUM ARG=" + getShortcutLabel() + "_cosa PERIODIC=NO");
+     129          14 :     readInputLine( getShortcutLabel() + "_sinsumb: SUM ARG=" + getShortcutLabel() + "_sinb PERIODIC=NO");
+     130          14 :     readInputLine( getShortcutLabel() + "_cossumb: SUM ARG=" + getShortcutLabel() + "_cosb PERIODIC=NO");
+     131          14 :     readInputLine( getShortcutLabel() + "_sinsumc: SUM ARG=" + getShortcutLabel() + "_sinc PERIODIC=NO");
+     132          14 :     readInputLine( getShortcutLabel() + "_cossumc: SUM ARG=" + getShortcutLabel() + "_cosc PERIODIC=NO");
+     133             :     // And get the final position in fractional coordinates
+     134          14 :     readInputLine( getShortcutLabel() + "_a: CUSTOM ARG=" + getShortcutLabel() + "_sinsuma," + getShortcutLabel() + "_cossuma FUNC=atan2(x,y)/(2*pi) PERIODIC=NO");
+     135          14 :     readInputLine( getShortcutLabel() + "_b: CUSTOM ARG=" + getShortcutLabel() + "_sinsumb," + getShortcutLabel() + "_cossumb FUNC=atan2(x,y)/(2*pi) PERIODIC=NO");
+     136          14 :     readInputLine( getShortcutLabel() + "_c: CUSTOM ARG=" + getShortcutLabel() + "_sinsumc," + getShortcutLabel() + "_cossumc FUNC=atan2(x,y)/(2*pi) PERIODIC=NO");
+     137             :     // And create the virtual atom
+     138           7 :     if( safe_phases ) {
+     139           0 :       readInputLine( getShortcutLabel() + ": ARGS2VATOM XPOS=" + getShortcutLabel() + "_a YPOS=" + getShortcutLabel() + "_b ZPOS=" + getShortcutLabel() + "_c "
+     140           0 :                      + " XBKP=" + getShortcutLabel() + "_x YBKP=" + getShortcutLabel() + "_y ZBKP=" + getShortcutLabel() + "_z "
+     141           0 :                      + " MASS=" + getShortcutLabel() + "_mass CHARGE=" + getShortcutLabel() + "_charge FRACTIONAL");
+     142             :     } else {
+     143          21 :       readInputLine( getShortcutLabel() + ": ARGS2VATOM XPOS=" + getShortcutLabel() + "_a YPOS=" + getShortcutLabel() + "_b ZPOS=" + getShortcutLabel() + "_c "
+     144          21 :                      + " MASS=" + getShortcutLabel() + "_mass CHARGE=" + getShortcutLabel() + "_charge FRACTIONAL");
+     145             :     }
+     146             :   } else {
+     147             :     // And create the virtual atom
+     148           6 :     readInputLine( getShortcutLabel() + ": ARGS2VATOM XPOS=" + getShortcutLabel() + "_x YPOS=" + getShortcutLabel() + "_y ZPOS=" + getShortcutLabel() + "_z "
+     149           6 :                    + " MASS=" + getShortcutLabel() + "_mass CHARGE=" + getShortcutLabel() + "_charge ");
+     150             :   }
+     151        7749 : }
+     152             : 
+     153             : }
+     154             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vatom/FixedAtom.cpp.func-sort-c.html b/coverage/vatom/FixedAtom.cpp.func-sort-c.html new file mode 100644 index 000000000000..2150b13a55d8 --- /dev/null +++ b/coverage/vatom/FixedAtom.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - vatom/FixedAtom.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vatom - FixedAtom.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3333100.0 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5vatom9FixedAtomC2ERKNS_13ActionOptionsE0
_ZN4PLMD5vatom9FixedAtomC1ERKNS_13ActionOptionsE35
_ZN4PLMD5vatom9FixedAtom16registerKeywordsERNS_8KeywordsE37
_ZN4PLMD5vatom9FixedAtom9calculateEv735
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vatom/FixedAtom.cpp.func.html b/coverage/vatom/FixedAtom.cpp.func.html new file mode 100644 index 000000000000..e8cecd1d6f20 --- /dev/null +++ b/coverage/vatom/FixedAtom.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - vatom/FixedAtom.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vatom - FixedAtom.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3333100.0 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5vatom9FixedAtom16registerKeywordsERNS_8KeywordsE37
_ZN4PLMD5vatom9FixedAtom9calculateEv735
_ZN4PLMD5vatom9FixedAtomC1ERKNS_13ActionOptionsE35
_ZN4PLMD5vatom9FixedAtomC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vatom/FixedAtom.cpp.gcov.html b/coverage/vatom/FixedAtom.cpp.gcov.html new file mode 100644 index 000000000000..9b2f1e336823 --- /dev/null +++ b/coverage/vatom/FixedAtom.cpp.gcov.html @@ -0,0 +1,227 @@ + + + + + + + + LCOV - plumed test coverage - vatom/FixedAtom.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vatom - FixedAtom.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3333100.0 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "ActionWithVirtualAtom.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "tools/Vector.h"
+      25             : #include "tools/Exception.h"
+      26             : 
+      27             : namespace PLMD {
+      28             : namespace vatom {
+      29             : 
+      30             : //+PLUMEDOC VATOM FIXEDATOM
+      31             : /*
+      32             : Add a virtual atom in a fixed position.
+      33             : 
+      34             : This action creates a virtual atom at a fixed position.
+      35             : The coordinates can be specified in Cartesian components (by default)
+      36             : or in scaled coordinates (SCALED_COMPONENTS).
+      37             : It is also possible to assign a predefined charge or mass to the atom.
+      38             : 
+      39             : \attention
+      40             : Similar to \ref POSITION this variable is not invariant for translation
+      41             : of the system. Adding a force on it can create serious troubles.
+      42             : 
+      43             : Notice that the distance between two atoms created
+      44             : using FIXEDATOM is invariant for translation.
+      45             : Additionally, if one first align atoms to a reference using \ref FIT_TO_TEMPLATE,
+      46             : then it is safe to add further fixed atoms without breaking translational invariance.
+      47             : 
+      48             : \par Examples
+      49             : 
+      50             : The following input instructs plumed to compute the angle between
+      51             : distance of atoms 15 and 20 and the z axis and keeping it close to zero.
+      52             : \plumedfile
+      53             : a: FIXEDATOM AT=0,0,0
+      54             : b: FIXEDATOM AT=0,0,1
+      55             : an: ANGLE ATOMS=a,b,15,20
+      56             : RESTRAINT ARG=an AT=0.0 KAPPA=100.0
+      57             : \endplumedfile
+      58             : 
+      59             : The following input instructs plumed to align a protein to a template
+      60             : and to then compute the distance between one of the atoms in the protein and the point
+      61             : (10,20,30).
+      62             : \plumedfile
+      63             : FIT_TO_TEMPLATE STRIDE=1 REFERENCE=ref.pdb TYPE=SIMPLE
+      64             : a: FIXEDATOM AT=10,20,30
+      65             : d: DISTANCE ATOMS=a,20
+      66             : PRINT ARG=d FILE=colvar
+      67             : \endplumedfile
+      68             : 
+      69             : The reference structure to align to is provided in a pdb file called ref.pdb as shown below:
+      70             : 
+      71             : \auxfile{ref.pdb}
+      72             : ATOM      8  HT3 ALA     2      -1.480  -1.560   1.212  1.00  1.00      DIA  H
+      73             : ATOM      9  CAY ALA     2      -0.096   2.144  -0.669  1.00  1.00      DIA  C
+      74             : ATOM     10  HY1 ALA     2       0.871   2.385  -0.588  1.00  1.00      DIA  H
+      75             : ATOM     12  HY3 ALA     2      -0.520   2.679  -1.400  1.00  1.00      DIA  H
+      76             : ATOM     14  OY  ALA     2      -1.139   0.931  -0.973  1.00  1.00      DIA  O
+      77             : END
+      78             : \endauxfile
+      79             : 
+      80             : 
+      81             : */
+      82             : //+ENDPLUMEDOC
+      83             : 
+      84             : 
+      85             : class FixedAtom:
+      86             :   public ActionWithVirtualAtom
+      87             : {
+      88             :   Vector coord;
+      89             :   std::vector<Tensor> deriv;
+      90             :   double mass,charge;
+      91             :   bool scaled_components;
+      92             : public:
+      93             :   explicit FixedAtom(const ActionOptions&ao);
+      94             :   void calculate() override;
+      95             :   static void registerKeywords( Keywords& keys );
+      96             : };
+      97             : 
+      98             : PLUMED_REGISTER_ACTION(FixedAtom,"FIXEDATOM")
+      99             : 
+     100          37 : void FixedAtom::registerKeywords(Keywords& keys) {
+     101          37 :   ActionWithVirtualAtom::registerKeywords(keys);
+     102          74 :   keys.add("compulsory","AT","coordinates of the virtual atom");
+     103          74 :   keys.add("compulsory","SET_MASS","1","mass of the virtual atom");
+     104          74 :   keys.add("compulsory","SET_CHARGE","0","charge of the virtual atom");
+     105          74 :   keys.addFlag("SCALED_COMPONENTS",false,"use scaled components");
+     106          37 : }
+     107             : 
+     108          35 : FixedAtom::FixedAtom(const ActionOptions&ao):
+     109             :   Action(ao),
+     110          35 :   ActionWithVirtualAtom(ao)
+     111             : {
+     112             :   std::vector<AtomNumber> atoms;
+     113          70 :   parseAtomList("ATOMS",atoms);
+     114          35 :   if(atoms.size()!=0) error("ATOMS should be empty");
+     115             : 
+     116          70 :   parseFlag("SCALED_COMPONENTS",scaled_components);
+     117             : 
+     118             :   std::vector<double> at;
+     119          70 :   parseVector("AT",at);
+     120          35 :   if(at.size()!=3) error("AT should be a list of three real numbers");
+     121             : 
+     122          35 :   parse("SET_MASS",mass);
+     123          70 :   parse("SET_CHARGE",charge);
+     124             : 
+     125          35 :   coord[0]=at[0];
+     126          35 :   coord[1]=at[1];
+     127          35 :   coord[2]=at[2];
+     128             : 
+     129          35 :   checkRead();
+     130          35 :   log<<"  AT position "<<coord[0]<<" "<<coord[1]<<" "<<coord[2]<<"\n";
+     131          35 :   if(scaled_components) log<<"  position is in scaled components\n";
+     132          35 : }
+     133             : 
+     134         735 : void FixedAtom::calculate() {
+     135         735 :   deriv.resize(getNumberOfAtoms());
+     136         735 :   if(scaled_components) {
+     137           5 :     setPosition(getPbc().scaledToReal(coord));
+     138             :   } else {
+     139         730 :     setPosition(coord);
+     140             :   }
+     141         735 :   setMass(mass);
+     142         735 :   setCharge(charge);
+     143         735 :   setAtomsDerivatives(deriv);
+     144             : // Virial contribution
+     145         735 :   if(!scaled_components) setBoxDerivativesNoPbc();
+     146             : // notice that with scaled components there is no additional virial contribution
+     147         735 : }
+     148             : 
+     149             : }
+     150             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vatom/Ghost.cpp.func-sort-c.html b/coverage/vatom/Ghost.cpp.func-sort-c.html new file mode 100644 index 000000000000..f3b0190bcf0f --- /dev/null +++ b/coverage/vatom/Ghost.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - vatom/Ghost.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vatom - Ghost.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:7373100.0 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5vatom5GhostC2ERKNS_13ActionOptionsE0
_ZN4PLMD5vatom5GhostC1ERKNS_13ActionOptionsE703
_ZN4PLMD5vatom5Ghost16registerKeywordsERNS_8KeywordsE705
_ZN4PLMD5vatom5Ghost9calculateEv1407
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vatom/Ghost.cpp.func.html b/coverage/vatom/Ghost.cpp.func.html new file mode 100644 index 000000000000..c79e5e05b67f --- /dev/null +++ b/coverage/vatom/Ghost.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - vatom/Ghost.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vatom - Ghost.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:7373100.0 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5vatom5Ghost16registerKeywordsERNS_8KeywordsE705
_ZN4PLMD5vatom5Ghost9calculateEv1407
_ZN4PLMD5vatom5GhostC1ERKNS_13ActionOptionsE703
_ZN4PLMD5vatom5GhostC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vatom/Ghost.cpp.gcov.html b/coverage/vatom/Ghost.cpp.gcov.html new file mode 100644 index 000000000000..6a7d84fdee3a --- /dev/null +++ b/coverage/vatom/Ghost.cpp.gcov.html @@ -0,0 +1,263 @@ + + + + + + + + LCOV - plumed test coverage - vatom/Ghost.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vatom - Ghost.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:7373100.0 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "ActionWithVirtualAtom.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "tools/Vector.h"
+      25             : #include "tools/Exception.h"
+      26             : #include <array>
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace vatom {
+      30             : 
+      31             : //+PLUMEDOC VATOM GHOST
+      32             : /*
+      33             : Calculate the absolute position of a ghost atom with fixed coordinates in the local reference frame formed by three atoms.
+      34             : 
+      35             : The computed ghost atom is stored as a virtual atom that can be accessed in
+      36             :  an atom list through the the label for the GHOST action that creates it.
+      37             : 
+      38             : \par Examples
+      39             : 
+      40             : The following input instructs plumed to print the distance between the
+      41             : ghost atom and the center of mass for atoms 15,20:
+      42             : \plumedfile
+      43             : c1: GHOST ATOMS=1,5,10 COORDINATES=10.0,10.0,10.0
+      44             : c2: COM ATOMS=15,20
+      45             : d1: DISTANCE ATOMS=c1,c2
+      46             : PRINT ARG=d1
+      47             : \endplumedfile
+      48             : 
+      49             : */
+      50             : //+ENDPLUMEDOC
+      51             : 
+      52             : 
+      53             : class Ghost:
+      54             :   public ActionWithVirtualAtom
+      55             : {
+      56             :   std::vector<double> coord;
+      57             :   std::vector<Tensor> deriv;
+      58             : public:
+      59             :   explicit Ghost(const ActionOptions&ao);
+      60             :   void calculate() override;
+      61             :   static void registerKeywords( Keywords& keys );
+      62             : };
+      63             : 
+      64             : PLUMED_REGISTER_ACTION(Ghost,"GHOST")
+      65             : 
+      66         705 : void Ghost::registerKeywords(Keywords& keys) {
+      67         705 :   ActionWithVirtualAtom::registerKeywords(keys);
+      68        1410 :   keys.add("atoms","COORDINATES","coordinates of the ghost atom in the local reference frame");
+      69         705 : }
+      70             : 
+      71         703 : Ghost::Ghost(const ActionOptions&ao):
+      72             :   Action(ao),
+      73         703 :   ActionWithVirtualAtom(ao)
+      74             : {
+      75             :   std::vector<AtomNumber> atoms;
+      76        1406 :   parseAtomList("ATOMS",atoms);
+      77         703 :   if(atoms.size()!=3) error("ATOMS should contain a list of three atoms");
+      78             : 
+      79        1406 :   parseVector("COORDINATES",coord);
+      80         703 :   if(coord.size()!=3) error("COORDINATES should be a list of three real numbers");
+      81             : 
+      82         703 :   checkRead();
+      83         703 :   log.printf("  of atoms");
+      84        2812 :   for(unsigned i=0; i<atoms.size(); ++i) log.printf(" %d",atoms[i].serial());
+      85         703 :   log.printf("\n");
+      86         703 :   requestAtoms(atoms);
+      87         703 : }
+      88             : 
+      89        1407 : void Ghost::calculate() {
+      90        1407 :   Vector pos;
+      91        1407 :   deriv.resize(getNumberOfAtoms());
+      92        1407 :   std::array<Vector,3> n;
+      93             : 
+      94             : // first versor
+      95        1407 :   Vector n01 = delta(getPosition(0), getPosition(1));
+      96        1407 :   n[0]=n01/n01.modulo();
+      97             : 
+      98             : // auxiliary vector
+      99        1407 :   Vector n02 = delta(getPosition(0), getPosition(2));
+     100             : 
+     101             : // second versor
+     102        1407 :   Vector n03 = crossProduct(n[0],n02);
+     103        1407 :   double n03_norm = n03.modulo();
+     104        1407 :   n[1]=n03/n03_norm;
+     105             : 
+     106             : // third versor
+     107        1407 :   n[2]=crossProduct(n[0],n[1]);
+     108             : 
+     109             : // origin of the reference system
+     110        1407 :   pos = getPosition(0);
+     111             : 
+     112        5628 :   for(unsigned i=0; i<3; ++i) {
+     113        4221 :     pos += coord[i] * n[i];
+     114             :   }
+     115             : 
+     116        1407 :   setPosition(pos);
+     117        1407 :   setMass(1.0);
+     118        1407 :   setCharge(0.0);
+     119             : 
+     120             : // some useful tensors for derivatives
+     121        1407 :   Tensor dn0d0  = (-Tensor::identity()+Tensor(n[0],n[0]))/n01.modulo();
+     122        1407 :   Tensor dn0d1  = (+Tensor::identity()-Tensor(n[0],n[0]))/n01.modulo();
+     123        1407 :   Tensor dn02d0 = -Tensor::identity();
+     124        1407 :   Tensor dn02d2 =  Tensor::identity();
+     125             : 
+     126             : // derivative of n1 = n0 x n02
+     127        1407 :   Tensor dn1d0, dn1d1, dn1d2;
+     128        1407 :   Vector aux0, aux1, aux2;
+     129             : 
+     130        5628 :   for(unsigned j=0; j<3; ++j) {
+     131             : // derivative of n0 x n02 with respect to point 0, coordinate j
+     132        4221 :     Vector tmp00  = Vector( dn0d0(j,0),  dn0d0(j,1),  dn0d0(j,2));
+     133        4221 :     Vector tmp020 = Vector(dn02d0(j,0), dn02d0(j,1), dn02d0(j,2));
+     134        4221 :     Vector tmp0   = crossProduct(tmp00,n02) + crossProduct(n[0],tmp020);
+     135        4221 :     aux0[j]       = dotProduct(tmp0,n[1]);
+     136             : // derivative of n0 x n02 with respect to point 1, coordinate j
+     137        4221 :     Vector tmp01  = Vector( dn0d1(j,0),  dn0d1(j,1),  dn0d1(j,2));
+     138        4221 :     Vector tmp1   = crossProduct(tmp01,n02);
+     139        4221 :     aux1[j]       = dotProduct(tmp1,n[1]);
+     140             : // derivative of n0 x n02 with respect to point 2, coordinate j
+     141        4221 :     Vector tmp022 = Vector(dn02d2(j,0), dn02d2(j,1), dn02d2(j,2));
+     142        4221 :     Vector tmp2   = crossProduct(n[0],tmp022);
+     143        4221 :     aux2[j]       = dotProduct(tmp2,n[1]);
+     144             : // derivative of n1 = (n0 x n02) / || (n0 x n02) ||
+     145       16884 :     for(unsigned i=0; i<3; ++i) {
+     146       12663 :       dn1d0(j,i) = ( tmp0[i] - aux0[j] * n[1][i] ) / n03_norm;
+     147       12663 :       dn1d1(j,i) = ( tmp1[i] - aux1[j] * n[1][i] ) / n03_norm;
+     148       12663 :       dn1d2(j,i) = ( tmp2[i] - aux2[j] * n[1][i] ) / n03_norm;
+     149             :     }
+     150             :   }
+     151             : 
+     152             : // Derivative of the last versor n2 = n0 x n1 =  ( n0( n0 n02 ) - n02 ) / || n0 x n02 ||
+     153             : // Scalar product and derivatives
+     154        1407 :   double n0_n02 = dotProduct(n[0],n02);
+     155        1407 :   Vector dn0_n02d0, dn0_n02d1, dn0_n02d2;
+     156             : 
+     157        5628 :   for(unsigned j=0; j<3; ++j) {
+     158       16884 :     for(unsigned i=0; i<3; ++i) {
+     159       12663 :       dn0_n02d0[j] += dn0d0(j,i)*n02[i] + n[0][i]*dn02d0(j,i);
+     160       12663 :       dn0_n02d1[j] += dn0d1(j,i)*n02[i];
+     161       12663 :       dn0_n02d2[j] +=                     n[0][i]*dn02d2(j,i);
+     162             :     }
+     163             :   }
+     164             : 
+     165        1407 :   Tensor dn2d0, dn2d1, dn2d2;
+     166        5628 :   for(unsigned j=0; j<3; ++j) {
+     167       16884 :     for(unsigned i=0; i<3; ++i) {
+     168       12663 :       dn2d0(j,i) = ( dn0d0(j,i) * n0_n02 + n[0][i] * dn0_n02d0[j] - dn02d0(j,i) - ( n[0][i] * n0_n02 - n02[i] ) * aux0[j] / n03_norm ) / n03_norm;
+     169       12663 :       dn2d1(j,i) = ( dn0d1(j,i) * n0_n02 + n[0][i] * dn0_n02d1[j]               - ( n[0][i] * n0_n02 - n02[i] ) * aux1[j] / n03_norm ) / n03_norm;
+     170       12663 :       dn2d2(j,i) = (                       n[0][i] * dn0_n02d2[j] - dn02d2(j,i) - ( n[0][i] * n0_n02 - n02[i] ) * aux2[j] / n03_norm ) / n03_norm;
+     171             :     }
+     172             :   }
+     173             : 
+     174             : // Finally, the derivative tensor
+     175        1407 :   deriv[0] = Tensor::identity() + coord[0]*dn0d0 + coord[1]*dn1d0 + coord[2]*dn2d0;
+     176        1407 :   deriv[1] =                      coord[0]*dn0d1 + coord[1]*dn1d1 + coord[2]*dn2d1;
+     177        1407 :   deriv[2] =                                       coord[1]*dn1d2 + coord[2]*dn2d2;
+     178             : 
+     179        1407 :   setAtomsDerivatives(deriv);
+     180             : 
+     181             : // Virial contribution
+     182        1407 :   setBoxDerivativesNoPbc();
+     183        1407 : }
+     184             : 
+     185             : }
+     186             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vatom/index-sort-f.html b/coverage/vatom/index-sort-f.html new file mode 100644 index 000000000000..4416bd7b1d14 --- /dev/null +++ b/coverage/vatom/index-sort-f.html @@ -0,0 +1,134 @@ + + + + + + + + LCOV - plumed test coverage - vatom + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vatomHitTotalCoverage
Test:plumed test coverageLines:35837894.7 %
Date:2024-04-19 12:12:35Functions:162176.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
CenterShortcut.cpp +
88.5%88.5%
+
88.5 %69 / 7866.7 %2 / 3
FixedAtom.cpp +
100.0%
+
100.0 %33 / 3375.0 %3 / 4
Ghost.cpp +
100.0%
+
100.0 %73 / 7375.0 %3 / 4
Center.cpp +
99.2%99.2%
+
99.2 %121 / 12275.0 %3 / 4
ArgsToVatom.cpp +
86.1%86.1%
+
86.1 %62 / 7283.3 %5 / 6
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vatom/index-sort-l.html b/coverage/vatom/index-sort-l.html new file mode 100644 index 000000000000..cf018410d3a0 --- /dev/null +++ b/coverage/vatom/index-sort-l.html @@ -0,0 +1,134 @@ + + + + + + + + LCOV - plumed test coverage - vatom + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vatomHitTotalCoverage
Test:plumed test coverageLines:35837894.7 %
Date:2024-04-19 12:12:35Functions:162176.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
ArgsToVatom.cpp +
86.1%86.1%
+
86.1 %62 / 7283.3 %5 / 6
CenterShortcut.cpp +
88.5%88.5%
+
88.5 %69 / 7866.7 %2 / 3
Center.cpp +
99.2%99.2%
+
99.2 %121 / 12275.0 %3 / 4
FixedAtom.cpp +
100.0%
+
100.0 %33 / 3375.0 %3 / 4
Ghost.cpp +
100.0%
+
100.0 %73 / 7375.0 %3 / 4
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vatom/index.html b/coverage/vatom/index.html new file mode 100644 index 000000000000..6b49c52b2175 --- /dev/null +++ b/coverage/vatom/index.html @@ -0,0 +1,134 @@ + + + + + + + + LCOV - plumed test coverage - vatom + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vatomHitTotalCoverage
Test:plumed test coverageLines:35837894.7 %
Date:2024-04-19 12:12:35Functions:162176.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
ArgsToVatom.cpp +
86.1%86.1%
+
86.1 %62 / 7283.3 %5 / 6
Center.cpp +
99.2%99.2%
+
99.2 %121 / 12275.0 %3 / 4
CenterShortcut.cpp +
88.5%88.5%
+
88.5 %69 / 7866.7 %2 / 3
FixedAtom.cpp +
100.0%
+
100.0 %33 / 3375.0 %3 / 4
Ghost.cpp +
100.0%
+
100.0 %73 / 7375.0 %3 / 4
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Chebyshev.cpp.func-sort-c.html b/coverage/ves/BF_Chebyshev.cpp.func-sort-c.html new file mode 100644 index 000000000000..802bd8a755f7 --- /dev/null +++ b/coverage/ves/BF_Chebyshev.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - ves/BF_Chebyshev.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BF_Chebyshev.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3535100.0 %
Date:2024-04-19 12:12:35Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12BF_Chebyshev21setupUniformIntegralsEv3
_ZN4PLMD3ves12BF_ChebyshevC2ERKNS_13ActionOptionsE4
_ZN4PLMD3ves12BF_Chebyshev16registerKeywordsERNS_8KeywordsE6
_ZNK4PLMD3ves12BF_Chebyshev12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_7882
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Chebyshev.cpp.func.html b/coverage/ves/BF_Chebyshev.cpp.func.html new file mode 100644 index 000000000000..522b5f66a513 --- /dev/null +++ b/coverage/ves/BF_Chebyshev.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - ves/BF_Chebyshev.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BF_Chebyshev.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3535100.0 %
Date:2024-04-19 12:12:35Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12BF_Chebyshev16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD3ves12BF_Chebyshev21setupUniformIntegralsEv3
_ZN4PLMD3ves12BF_ChebyshevC2ERKNS_13ActionOptionsE4
_ZNK4PLMD3ves12BF_Chebyshev12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_7882
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Chebyshev.cpp.gcov.html b/coverage/ves/BF_Chebyshev.cpp.gcov.html new file mode 100644 index 000000000000..012a3387088a --- /dev/null +++ b/coverage/ves/BF_Chebyshev.cpp.gcov.html @@ -0,0 +1,233 @@ + + + + + + + + LCOV - plumed test coverage - ves/BF_Chebyshev.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BF_Chebyshev.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3535100.0 %
Date:2024-04-19 12:12:35Functions:44100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "BasisFunctions.h"
+      24             : 
+      25             : #include "core/ActionRegister.h"
+      26             : 
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace ves {
+      30             : 
+      31             : //+PLUMEDOC VES_BASISF BF_CHEBYSHEV
+      32             : /*
+      33             : Chebyshev polynomial basis functions.
+      34             : 
+      35             : Use as basis functions [Chebyshev polynomials](https://en.wikipedia.org/wiki/Chebyshev_polynomials)
+      36             : of the first kind \f$T_{n}(x)\f$ defined on a bounded interval.
+      37             : You need to provide the interval \f$[a,b]\f$
+      38             : on which the basis functions are to be used, and the order of the
+      39             : expansion \f$N\f$ (i.e. the highest order polynomial used).
+      40             : The total number of basis functions is \f$N+1\f$ as the constant \f$T_{0}(x)=1\f$
+      41             : is also included.
+      42             : These basis functions should not be used for periodic CVs.
+      43             : 
+      44             : Intrinsically the Chebyshev polynomials are defined on the interval \f$[-1,1]\f$.
+      45             : A variable \f$t\f$ in the interval \f$[a,b]\f$ is transformed to a variable \f$x\f$
+      46             : in the intrinsic interval \f$[-1,1]\f$ by using the transform function
+      47             : \f[
+      48             : x(t) = \frac{t-(a+b)/2}
+      49             : {(b-a)/2}
+      50             : \f]
+      51             : 
+      52             : The Chebyshev polynomials are given by the recurrence relation
+      53             : \f{align}{
+      54             : T_{0}(x)    &= 1 \\
+      55             : T_{1}(x)    &= x \\
+      56             : T_{n+1}(x)  &= 2 \, x \, T_{n}(x) - T_{n-1}(x)
+      57             : \f}
+      58             : 
+      59             : The first 6 polynomials are shown below
+      60             : \image html ves_basisf-chebyshev.png
+      61             : 
+      62             : The Chebyshev polynomial are orthogonal over the interval \f$[-1,1]\f$
+      63             : with respect to the weight \f$\frac{1}{\sqrt{1-x^2}}\f$
+      64             : \f[
+      65             : \int_{-1}^{1} dx \, T_{n}(x)\, T_{m}(x) \, \frac{1}{\sqrt{1-x^2}} =
+      66             : \begin{cases}
+      67             : 0 & n \neq m \\
+      68             : \pi & n = m = 0 \\
+      69             : \pi/2 & n = m \neq 0
+      70             : \end{cases}
+      71             : \f]
+      72             : 
+      73             : For further mathematical properties of the Chebyshev polynomials see for example
+      74             : the [Wikipedia page](https://en.wikipedia.org/wiki/Chebyshev_polynomials).
+      75             : 
+      76             : \par Examples
+      77             : 
+      78             : Here we employ a Chebyshev expansion of order 20 over the interval 0.0 to 10.0.
+      79             : This results in a total number of 21 basis functions.
+      80             : The label used to identify  the basis function action can then be
+      81             : referenced later on in the input file.
+      82             : \plumedfile
+      83             : bfC: BF_CHEBYSHEV MINIMUM=0.0 MAXIMUM=10.0 ORDER=20
+      84             : \endplumedfile
+      85             : 
+      86             : */
+      87             : //+ENDPLUMEDOC
+      88             : 
+      89             : 
+      90             : class BF_Chebyshev : public BasisFunctions {
+      91             :   void setupUniformIntegrals() override;
+      92             : public:
+      93             :   static void registerKeywords(Keywords&);
+      94             :   explicit BF_Chebyshev(const ActionOptions&);
+      95             :   void getAllValues(const double, double&, bool&, std::vector<double>&, std::vector<double>&) const override;
+      96             : };
+      97             : 
+      98             : 
+      99             : PLUMED_REGISTER_ACTION(BF_Chebyshev,"BF_CHEBYSHEV")
+     100             : 
+     101             : 
+     102           6 : void BF_Chebyshev::registerKeywords(Keywords& keys) {
+     103           6 :   BasisFunctions::registerKeywords(keys);
+     104           6 : }
+     105             : 
+     106           4 : BF_Chebyshev::BF_Chebyshev(const ActionOptions&ao):
+     107           4 :   PLUMED_VES_BASISFUNCTIONS_INIT(ao)
+     108             : {
+     109           4 :   setNumberOfBasisFunctions(getOrder()+1);
+     110           8 :   setIntrinsicInterval("-1.0","+1.0");
+     111             :   setNonPeriodic();
+     112             :   setIntervalBounded();
+     113           4 :   setType("chebyshev-1st-kind");
+     114           4 :   setDescription("Chebyshev polynomials of the first kind");
+     115           4 :   setLabelPrefix("T");
+     116           4 :   setupBF();
+     117           4 :   checkRead();
+     118           4 : }
+     119             : 
+     120             : 
+     121        7882 : void BF_Chebyshev::getAllValues(const double arg, double& argT, bool& inside_range, std::vector<double>& values, std::vector<double>& derivs) const {
+     122             :   // plumed_assert(values.size()==numberOfBasisFunctions());
+     123             :   // plumed_assert(derivs.size()==numberOfBasisFunctions());
+     124        7882 :   inside_range=true;
+     125        7882 :   argT=translateArgument(arg, inside_range);
+     126        7882 :   std::vector<double> derivsT(derivs.size());
+     127             :   //
+     128        7882 :   values[0]=1.0;
+     129        7882 :   derivsT[0]=0.0;
+     130        7882 :   derivs[0]=0.0;
+     131        7882 :   values[1]=argT;
+     132        7882 :   derivsT[1]=1.0;
+     133        7882 :   derivs[1]=intervalDerivf();
+     134      135100 :   for(unsigned int i=1; i < getOrder(); i++) {
+     135      127218 :     values[i+1]  = 2.0*argT*values[i]-values[i-1];
+     136      127218 :     derivsT[i+1] = 2.0*values[i]+2.0*argT*derivsT[i]-derivsT[i-1];
+     137      127218 :     derivs[i+1]  = intervalDerivf()*derivsT[i+1];
+     138             :   }
+     139        9906 :   if(!inside_range) {for(unsigned int i=0; i<derivs.size(); i++) {derivs[i]=0.0;}}
+     140        7882 : }
+     141             : 
+     142             : 
+     143           3 : void BF_Chebyshev::setupUniformIntegrals() {
+     144          56 :   for(unsigned int i=0; i<numberOfBasisFunctions(); i++) {
+     145          53 :     double io = i;
+     146             :     double value = 0.0;
+     147          53 :     if(i % 2 == 0) {
+     148          28 :       value = -2.0/( pow(io,2.0)-1.0)*0.5;
+     149             :     }
+     150             :     setUniformIntegral(i,value);
+     151             :   }
+     152           3 : }
+     153             : 
+     154             : 
+     155             : }
+     156             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Combined.cpp.func-sort-c.html b/coverage/ves/BF_Combined.cpp.func-sort-c.html new file mode 100644 index 000000000000..d5ca4695337b --- /dev/null +++ b/coverage/ves/BF_Combined.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - ves/BF_Combined.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BF_Combined.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:636596.9 %
Date:2024-04-19 12:12:35Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves11BF_Combined11setupLabelsEv2
_ZN4PLMD3ves11BF_Combined21setupUniformIntegralsEv2
_ZN4PLMD3ves11BF_CombinedC2ERKNS_13ActionOptionsE2
_ZN4PLMD3ves11BF_Combined16registerKeywordsERNS_8KeywordsE4
_ZNK4PLMD3ves11BF_Combined12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_3616
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Combined.cpp.func.html b/coverage/ves/BF_Combined.cpp.func.html new file mode 100644 index 000000000000..1f2dda625d8e --- /dev/null +++ b/coverage/ves/BF_Combined.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - ves/BF_Combined.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BF_Combined.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:636596.9 %
Date:2024-04-19 12:12:35Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves11BF_Combined11setupLabelsEv2
_ZN4PLMD3ves11BF_Combined16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD3ves11BF_Combined21setupUniformIntegralsEv2
_ZN4PLMD3ves11BF_CombinedC2ERKNS_13ActionOptionsE2
_ZNK4PLMD3ves11BF_Combined12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_3616
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Combined.cpp.gcov.html b/coverage/ves/BF_Combined.cpp.gcov.html new file mode 100644 index 000000000000..b71661726ee6 --- /dev/null +++ b/coverage/ves/BF_Combined.cpp.gcov.html @@ -0,0 +1,279 @@ + + + + + + + + LCOV - plumed test coverage - ves/BF_Combined.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BF_Combined.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:636596.9 %
Date:2024-04-19 12:12:35Functions:55100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "BasisFunctions.h"
+      24             : #include "VesTools.h"
+      25             : 
+      26             : #include "core/ActionRegister.h"
+      27             : #include "core/ActionSet.h"
+      28             : #include "core/PlumedMain.h"
+      29             : 
+      30             : 
+      31             : namespace PLMD {
+      32             : namespace ves {
+      33             : 
+      34             : //+PLUMEDOC VES_BASISF BF_COMBINED
+      35             : /*
+      36             : Combining other basis functions types
+      37             : 
+      38             : \par Examples
+      39             : 
+      40             : Here we define both Fourier cosine and sine expansions of order 10,
+      41             : each with 11 basis functions, which are combined. This results
+      42             : in a total number of 21 basis functions as only the constant from
+      43             : is bf_cos is used.
+      44             : \plumedfile
+      45             : bf_cos: BF_COSINE MINIMUM=-pi MAXIMUM=+pi ORDER=10
+      46             : bf_sin: BF_SINE   MINIMUM=-pi MAXIMUM=+pi ORDER=10
+      47             : bf_comb: BF_COMBINED BASIS_FUNCTIONS=bf_cos,bf_sin
+      48             : \endplumedfile
+      49             : In principle this is the same as using BF_FOURIER with
+      50             : ORDER=10 but with different ordering of the basis functions.
+      51             : Note that the order used in BASIS_FUNCTIONS matters for the ordering
+      52             : of the basis functions, using BASIS_FUNCTIONS=bf_sin,bf_cos would
+      53             : results in a different order of the basis functions.
+      54             : This should be kept in mind when restarting from previous
+      55             : coefficients.
+      56             : 
+      57             : 
+      58             : 
+      59             : 
+      60             : 
+      61             : 
+      62             : */
+      63             : //+ENDPLUMEDOC
+      64             : 
+      65             : class BF_Combined : public BasisFunctions {
+      66             :   std::vector<BasisFunctions*> basisf_pntrs_;
+      67             :   void setupLabels() override;
+      68             :   void setupUniformIntegrals() override;
+      69             :   // void getBFandValueIndices(const unsigned int, unsigned int&, unsigned int&) const;
+      70             : public:
+      71             :   static void registerKeywords(Keywords&);
+      72             :   explicit BF_Combined(const ActionOptions&);
+      73             :   void getAllValues(const double, double&, bool&, std::vector<double>&, std::vector<double>&) const override;
+      74             : };
+      75             : 
+      76             : 
+      77             : PLUMED_REGISTER_ACTION(BF_Combined,"BF_COMBINED")
+      78             : 
+      79             : 
+      80           4 : void BF_Combined::registerKeywords(Keywords& keys) {
+      81           4 :   BasisFunctions::registerKeywords(keys);
+      82           4 :   keys.remove("ORDER");
+      83           4 :   keys.remove("MAXIMUM");
+      84           4 :   keys.remove("MINIMUM");
+      85           4 :   keys.remove("NUMERICAL_INTEGRALS");
+      86           4 :   keys.remove("NGRID_POINTS");
+      87           8 :   keys.add("compulsory","BASIS_FUNCTIONS","Labels of the basis functions that should be combined. Note that the order used matters for the ordering of the basis functions. This needs to be kept in mind when restarting from previous coefficients.");
+      88           4 : }
+      89             : 
+      90             : 
+      91           2 : BF_Combined::BF_Combined(const ActionOptions&ao):
+      92             :   PLUMED_VES_BASISFUNCTIONS_INIT(ao),
+      93           2 :   basisf_pntrs_(0)
+      94             : {
+      95             :   std::vector<std::string> basisf_labels;
+      96           6 :   parseVector("BASIS_FUNCTIONS",basisf_labels); addKeywordToList("BASIS_FUNCTIONS",basisf_labels);
+      97           2 :   if(basisf_labels.size()==1) {
+      98           0 :     plumed_merror("using only one basis function in BF_COMBINED does not make sense");
+      99             :   }
+     100           2 :   std::string error_msg = "";
+     101           4 :   basisf_pntrs_ = VesTools::getPointersFromLabels<BasisFunctions*>(basisf_labels,plumed.getActionSet(),error_msg);
+     102           2 :   if(error_msg.size()>0) {plumed_merror("Error in keyword BASIS_FUNCTIONS of "+getName()+": "+error_msg);}
+     103             : 
+     104             :   unsigned int nbasisf_total_ = 1;
+     105             :   bool periodic = true;
+     106           7 :   for(unsigned int i=0; i<basisf_pntrs_.size(); i++) {
+     107           5 :     nbasisf_total_ += basisf_pntrs_[i]->getNumberOfBasisFunctions() - 1;
+     108          15 :     if(basisf_pntrs_[i]->intervalMinStr()!=basisf_pntrs_[0]->intervalMinStr() || basisf_pntrs_[i]->intervalMaxStr()!=basisf_pntrs_[0]->intervalMaxStr()) {
+     109           0 :       plumed_merror("all the basis functions to be combined should have same MINIMUM and MAXIMUM");
+     110             :     }
+     111           5 :     if(!basisf_pntrs_[i]->arePeriodic()) {periodic=false;}
+     112             :   }
+     113           2 :   setOrder(nbasisf_total_-1);
+     114           2 :   setNumberOfBasisFunctions(nbasisf_total_);
+     115           4 :   setInterval(basisf_pntrs_[0]->intervalMinStr(),basisf_pntrs_[0]->intervalMaxStr());
+     116           4 :   setIntrinsicInterval("-1.0","+1.0");
+     117           2 :   if(periodic) {setPeriodic();}
+     118             :   else {setNonPeriodic();}
+     119             :   setIntervalBounded();
+     120           2 :   setType("combined");
+     121           2 :   setDescription("Combined");
+     122           2 :   setupBF();
+     123           2 :   checkRead();
+     124           2 : }
+     125             : 
+     126             : 
+     127             : // void BF_Combined::getBFandValueIndices(const unsigned int n, unsigned int& bf_index, unsigned int& value_index) const {
+     128             : //   bf_index = 0; value_index = 0;
+     129             : //   if(n==0){
+     130             : //     bf_index = 0;
+     131             : //     value_index = 0;
+     132             : //     return;
+     133             : //   }
+     134             : //   else{
+     135             : //     unsigned int r=1;
+     136             : //     for(unsigned int i=0; i<basisf_pntrs_.size(); i++){
+     137             : //       for(unsigned int l=1; l<basisf_pntrs_[i]->numberOfBasisFunctions(); l++){
+     138             : //         if(r==n){
+     139             : //           bf_index = i;
+     140             : //           value_index = l;
+     141             : //           return;
+     142             : //         }
+     143             : //         r++;
+     144             : //       }
+     145             : //     }
+     146             : //   }
+     147             : // }
+     148             : 
+     149             : 
+     150        3616 : void BF_Combined::getAllValues(const double arg, double& argT, bool& inside_range, std::vector<double>& values, std::vector<double>& derivs) const {
+     151             :   // first BF, constant, argT, and inside_range taken from here
+     152             :   unsigned int r=0;
+     153        3616 :   std::vector<double> values_tmp(basisf_pntrs_[0]->numberOfBasisFunctions(),0.0);
+     154        3616 :   std::vector<double> derivs_tmp(basisf_pntrs_[0]->numberOfBasisFunctions(),0.0);
+     155        3616 :   basisf_pntrs_[0]->getAllValues(arg,argT,inside_range,values_tmp,derivs_tmp);
+     156       43392 :   for(unsigned int l=0; l<basisf_pntrs_[0]->numberOfBasisFunctions(); l++) {
+     157       39776 :     values[r] = values_tmp[l];
+     158       39776 :     derivs[r] = derivs_tmp[l];
+     159       39776 :     r++;
+     160             :   }
+     161             :   // other BF
+     162        9043 :   for(unsigned int i=1; i<basisf_pntrs_.size(); i++) {
+     163        5427 :     values_tmp.assign(basisf_pntrs_[i]->numberOfBasisFunctions(),0.0);
+     164        5427 :     derivs_tmp.assign(basisf_pntrs_[i]->numberOfBasisFunctions(),0.0);
+     165        5427 :     double dummy_dbl; bool dummy_bool=true;
+     166        5427 :     basisf_pntrs_[i]->getAllValues(arg,dummy_dbl,dummy_bool,values_tmp,derivs_tmp);
+     167       59697 :     for(unsigned int l=1; l<basisf_pntrs_[i]->numberOfBasisFunctions(); l++) {
+     168       54270 :       values[r] = values_tmp[l];
+     169       54270 :       derivs[r] = derivs_tmp[l];
+     170       54270 :       r++;
+     171             :     }
+     172             :   }
+     173        3616 : }
+     174             : 
+     175             : 
+     176           2 : void BF_Combined::setupLabels() {
+     177           2 :   setLabel(0,basisf_pntrs_[0]->getBasisFunctionLabel(0));
+     178             :   unsigned int r=1;
+     179           7 :   for(unsigned int i=0; i<basisf_pntrs_.size(); i++) {
+     180          55 :     for(unsigned int l=1; l<basisf_pntrs_[i]->numberOfBasisFunctions(); l++) {
+     181          50 :       setLabel(r,basisf_pntrs_[i]->getBasisFunctionLabel(l));
+     182          50 :       r++;
+     183             :     }
+     184             :   }
+     185           2 : }
+     186             : 
+     187             : 
+     188           2 : void BF_Combined::setupUniformIntegrals() {
+     189           2 :   setUniformIntegral(0,basisf_pntrs_[0]->getUniformIntegrals()[0]);
+     190             :   unsigned int r=1;
+     191           7 :   for(unsigned int i=0; i<basisf_pntrs_.size(); i++) {
+     192           5 :     std::vector<double> uniform_tmp = basisf_pntrs_[i]->getUniformIntegrals();
+     193          55 :     for(unsigned int l=1; l<basisf_pntrs_[i]->numberOfBasisFunctions(); l++) {
+     194          50 :       setUniformIntegral(r,uniform_tmp[l]);
+     195          50 :       r++;
+     196             :     }
+     197             :   }
+     198           2 : }
+     199             : 
+     200             : 
+     201             : }
+     202             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Cosine.cpp.func-sort-c.html b/coverage/ves/BF_Cosine.cpp.func-sort-c.html new file mode 100644 index 000000000000..1b0b64e80dd9 --- /dev/null +++ b/coverage/ves/BF_Cosine.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - ves/BF_Cosine.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BF_Cosine.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3535100.0 %
Date:2024-04-19 12:12:35Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves9BF_Cosine21setupUniformIntegralsEv3
_ZN4PLMD3ves9BF_Cosine11setupLabelsEv4
_ZN4PLMD3ves9BF_CosineC2ERKNS_13ActionOptionsE4
_ZN4PLMD3ves9BF_Cosine16registerKeywordsERNS_8KeywordsE6
_ZNK4PLMD3ves9BF_Cosine12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_9229
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Cosine.cpp.func.html b/coverage/ves/BF_Cosine.cpp.func.html new file mode 100644 index 000000000000..76b6a6ab965f --- /dev/null +++ b/coverage/ves/BF_Cosine.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - ves/BF_Cosine.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BF_Cosine.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3535100.0 %
Date:2024-04-19 12:12:35Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves9BF_Cosine11setupLabelsEv4
_ZN4PLMD3ves9BF_Cosine16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD3ves9BF_Cosine21setupUniformIntegralsEv3
_ZN4PLMD3ves9BF_CosineC2ERKNS_13ActionOptionsE4
_ZNK4PLMD3ves9BF_Cosine12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_9229
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Cosine.cpp.gcov.html b/coverage/ves/BF_Cosine.cpp.gcov.html new file mode 100644 index 000000000000..785d768e8133 --- /dev/null +++ b/coverage/ves/BF_Cosine.cpp.gcov.html @@ -0,0 +1,229 @@ + + + + + + + + LCOV - plumed test coverage - ves/BF_Cosine.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BF_Cosine.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3535100.0 %
Date:2024-04-19 12:12:35Functions:55100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "BasisFunctions.h"
+      24             : 
+      25             : #include "core/ActionRegister.h"
+      26             : 
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace ves {
+      30             : 
+      31             : //+PLUMEDOC VES_BASISF BF_COSINE
+      32             : /*
+      33             : Fourier cosine basis functions.
+      34             : 
+      35             : Use as basis functions Fourier cosine series defined on a periodic interval.
+      36             : You need to provide the periodic interval \f$[a,b]\f$
+      37             : on which the basis functions are to be used, and the order of the
+      38             : expansion \f$N\f$ (i.e. the highest Fourier cosine mode used).
+      39             : The total number of basis functions is \f$N+1\f$ as
+      40             : the constant \f$f_{0}(x)=1\f$ is also included.
+      41             : These basis functions should only be used for periodic CVs.
+      42             : They can be useful if the periodic function being expanded is an
+      43             : even function, i.e. \f$F(-x)=F(x)\f$.
+      44             : 
+      45             : The Fourier cosine basis functions are given by
+      46             : \f{align}{
+      47             : f_{0}(x)    &= 1 \\
+      48             : f_{1}(x)    &= cos(\frac{2\pi }{P} x) \\
+      49             : f_{2}(x)    &= cos(2 \cdot \frac{2\pi}{P} x) \\
+      50             : f_{3}(x)    &= cos(3 \cdot \frac{2\pi}{P} x) \\
+      51             : & \vdots \\
+      52             : f_{n}(x) &= cos(n \cdot \frac{2\pi}{P} x) \\
+      53             : & \vdots \\
+      54             : f_{N}(x)   &= cos(N \cdot \frac{2\pi}{P} x) \\
+      55             : \f}
+      56             : where \f$P=(b-a)\f$ is the periodicity of the interval.
+      57             : They are orthogonal over the interval \f$[a,b]\f$
+      58             : \f[
+      59             : \int_{a}^{b} dx \, f_{n}(x)\, f_{m}(x)  =
+      60             : \begin{cases}
+      61             : 0 & n \neq m \\
+      62             : (b-a) & n = m = 0 \\
+      63             : (b-a)/2 & n = m \neq 0
+      64             : \end{cases}.
+      65             : \f]
+      66             : 
+      67             : \par Examples
+      68             : 
+      69             : Here we employ a Fourier cosine expansion of order 10 over the periodic interval
+      70             : \f$-\pi\f$ to \f$+\pi\f$.
+      71             : This results in a total number of 11 basis functions.
+      72             : The label used to identify  the basis function action can then be
+      73             : referenced later on in the input file.
+      74             : \plumedfile
+      75             : BF_COSINE MINIMUM=-pi MAXIMUM=+pi ORDER=10 LABEL=bf1
+      76             : \endplumedfile
+      77             : 
+      78             : 
+      79             : 
+      80             : */
+      81             : //+ENDPLUMEDOC
+      82             : 
+      83             : 
+      84             : class BF_Cosine : public BasisFunctions {
+      85             :   void setupLabels() override;
+      86             :   void setupUniformIntegrals() override;
+      87             : public:
+      88             :   static void registerKeywords(Keywords&);
+      89             :   explicit BF_Cosine(const ActionOptions&);
+      90             :   void getAllValues(const double, double&, bool&, std::vector<double>&, std::vector<double>&) const override;
+      91             : };
+      92             : 
+      93             : 
+      94             : PLUMED_REGISTER_ACTION(BF_Cosine,"BF_COSINE")
+      95             : 
+      96             : 
+      97           6 : void BF_Cosine::registerKeywords(Keywords& keys) {
+      98           6 :   BasisFunctions::registerKeywords(keys);
+      99           6 : }
+     100             : 
+     101             : 
+     102           4 : BF_Cosine::BF_Cosine(const ActionOptions&ao):
+     103           4 :   PLUMED_VES_BASISFUNCTIONS_INIT(ao)
+     104             : {
+     105           4 :   setNumberOfBasisFunctions(getOrder()+1);
+     106           8 :   setIntrinsicInterval("-pi","+pi");
+     107             :   setPeriodic();
+     108             :   setIntervalBounded();
+     109           4 :   setType("trigonometric_cos");
+     110           4 :   setDescription("Cosine");
+     111           4 :   setupBF();
+     112           4 :   checkRead();
+     113           4 : }
+     114             : 
+     115             : 
+     116        9229 : void BF_Cosine::getAllValues(const double arg, double& argT, bool& inside_range, std::vector<double>& values, std::vector<double>& derivs) const {
+     117             :   // plumed_assert(values.size()==numberOfBasisFunctions());
+     118             :   // plumed_assert(derivs.size()==numberOfBasisFunctions());
+     119        9229 :   inside_range=true;
+     120        9229 :   argT=translateArgument(arg, inside_range);
+     121        9229 :   values[0]=1.0;
+     122        9229 :   derivs[0]=0.0;
+     123      101519 :   for(unsigned int i=1; i < getOrder()+1; i++) {
+     124       92290 :     double io = i;
+     125       92290 :     double cos_tmp = cos(io*argT);
+     126       92290 :     double sin_tmp = sin(io*argT);
+     127       92290 :     values[i] = cos_tmp;
+     128       92290 :     derivs[i] = -io*sin_tmp*intervalDerivf();
+     129             :   }
+     130        9229 :   if(!inside_range) {
+     131         960 :     for(unsigned int i=0; i<derivs.size(); i++) {derivs[i]=0.0;}
+     132             :   }
+     133        9229 : }
+     134             : 
+     135             : 
+     136           4 : void BF_Cosine::setupLabels() {
+     137           4 :   setLabel(0,"1");
+     138          44 :   for(unsigned int i=1; i < getOrder()+1; i++) {
+     139          40 :     std::string is; Tools::convert(i,is);
+     140          80 :     setLabel(i,"cos("+is+"*s)");
+     141             :   }
+     142           4 : }
+     143             : 
+     144             : 
+     145           3 : void BF_Cosine::setupUniformIntegrals() {
+     146           3 :   setAllUniformIntegralsToZero();
+     147             :   setUniformIntegral(0,1.0);
+     148           3 : }
+     149             : 
+     150             : 
+     151             : }
+     152             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_CubicBsplines.cpp.func-sort-c.html b/coverage/ves/BF_CubicBsplines.cpp.func-sort-c.html new file mode 100644 index 000000000000..0c2e13220f28 --- /dev/null +++ b/coverage/ves/BF_CubicBsplines.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - ves/BF_CubicBsplines.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BF_CubicBsplines.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:5858100.0 %
Date:2024-04-19 12:12:35Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves16BF_CubicBsplinesC2ERKNS_13ActionOptionsE3
_ZN4PLMD3ves16BF_CubicBsplines16registerKeywordsERNS_8KeywordsE5
_ZNK4PLMD3ves16BF_CubicBsplines12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_9236
_ZNK4PLMD3ves16BF_CubicBsplines6splineEdRd202807
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_CubicBsplines.cpp.func.html b/coverage/ves/BF_CubicBsplines.cpp.func.html new file mode 100644 index 000000000000..4c3bed5b3528 --- /dev/null +++ b/coverage/ves/BF_CubicBsplines.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - ves/BF_CubicBsplines.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BF_CubicBsplines.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:5858100.0 %
Date:2024-04-19 12:12:35Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves16BF_CubicBsplines16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD3ves16BF_CubicBsplinesC2ERKNS_13ActionOptionsE3
_ZNK4PLMD3ves16BF_CubicBsplines12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_9236
_ZNK4PLMD3ves16BF_CubicBsplines6splineEdRd202807
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_CubicBsplines.cpp.gcov.html b/coverage/ves/BF_CubicBsplines.cpp.gcov.html new file mode 100644 index 000000000000..ad636210a181 --- /dev/null +++ b/coverage/ves/BF_CubicBsplines.cpp.gcov.html @@ -0,0 +1,278 @@ + + + + + + + + LCOV - plumed test coverage - ves/BF_CubicBsplines.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BF_CubicBsplines.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:5858100.0 %
Date:2024-04-19 12:12:35Functions:44100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "BasisFunctions.h"
+      24             : 
+      25             : #include "core/ActionRegister.h"
+      26             : #include "core/PlumedMain.h"
+      27             : 
+      28             : 
+      29             : namespace PLMD {
+      30             : namespace ves {
+      31             : 
+      32             : //+PLUMEDOC VES_BASISF BF_CUBIC_B_SPLINES
+      33             : /*
+      34             : Cubic B spline basis functions.
+      35             : 
+      36             : \attention
+      37             : __These basis functions do not form orthogonal bases. We recommend using wavelets (\ref BF_WAVELETS) instead that do for orthogonal bases__.
+      38             : 
+      39             : A basis using cubic B spline functions according to \cite habermann_multidimensional_2007. See \cite ValssonPampel_Wavelets_2022 for full details.
+      40             : 
+      41             : The mathematical expression of the individual splines is given by
+      42             : \f{align*}{
+      43             :   h\left(x\right) =
+      44             :   \begin{cases}
+      45             :     \left(2 - \lvert x \rvert\right)^3, & 1 \leq \lvert x \rvert \leq 2\\
+      46             :     4 - 6\lvert x \rvert^2 + 3 \lvert x \rvert^3,\qquad & \lvert x \rvert \leq 1\\
+      47             :     0, & \text{elsewhere}.
+      48             :   \end{cases}
+      49             : \f}
+      50             : 
+      51             : The full basis consists of equidistant splines at positions \f$\mu_i\f$ which are optimized in their height:
+      52             : \f{align*}{
+      53             :   f_i\left(x\right) = h\left(\frac{x-\mu_i}{\sigma}\right)
+      54             : \f}
+      55             : 
+      56             : Note that the distance between individual splines cannot be chosen freely but is equal to the width: \f$\mu_{i+1} = \mu_{i} + \sigma\f$.
+      57             : 
+      58             : 
+      59             : The ORDER keyword of the basis set determines the number of equally sized sub-intervalls to be used.
+      60             : On the borders of each of these sub-intervalls the mean \f$\mu_i\f$ of a spline function is placed.
+      61             : 
+      62             : The total number of basis functions is \f$\text{ORDER}+4\f$ as the constant \f$f_{0}(x)=1\f$, as well as the two splines with means just outside the interval are also included.
+      63             : 
+      64             : As an example two adjacent basis functions can be seen below.
+      65             : The full basis consists of shifted splines in the full specified interval.
+      66             : 
+      67             : \image html ves_basisf-splines.png
+      68             : 
+      69             : When the splines are used for a periodic CV (with the PERIODIC keyword),
+      70             : the sub-intervals are chosen in the same way, but only \f$\text{ORDER}+1\f$ functions
+      71             : are required to fill it (the ones at the boundary coincide and the ones outside
+      72             : can be omitted).
+      73             : 
+      74             : To avoid 'blind' optimization of the basis functions outside the currently sampled area, it is often beneficial to use the OPTIMIZATION_THRESHOLD keyword of the VES_LINEAR_EXPANSION (set it to a small value, e.g. 1e-6)
+      75             : 
+      76             : \par Examples
+      77             : The bias is expanded with cubic B splines in the intervall from 0.0 to 10.0 specifying an order of 20.
+      78             : This results in 24 basis functions.
+      79             : 
+      80             : \plumedfile
+      81             : bf: BF_CUBIC_B_SPLINES MINIMUM=0.0 MAXIMUM=10.0 ORDER=20
+      82             : \endplumedfile
+      83             : 
+      84             : */
+      85             : //+ENDPLUMEDOC
+      86             : 
+      87             : class BF_CubicBsplines : public BasisFunctions {
+      88             :   double spacing_;
+      89             :   double inv_spacing_;
+      90             :   double inv_normfactor_;
+      91             :   double spline(const double, double&) const;
+      92             : public:
+      93             :   static void registerKeywords( Keywords&);
+      94             :   explicit BF_CubicBsplines(const ActionOptions&);
+      95             :   void getAllValues(const double, double&, bool&, std::vector<double>&, std::vector<double>&) const;
+      96             : };
+      97             : 
+      98             : 
+      99             : PLUMED_REGISTER_ACTION(BF_CubicBsplines,"BF_CUBIC_B_SPLINES")
+     100             : 
+     101             : // See DOI 10.1007/s10614-007-9092-4 for more information;
+     102             : 
+     103             : 
+     104           5 : void BF_CubicBsplines::registerKeywords(Keywords& keys) {
+     105           5 :   BasisFunctions::registerKeywords(keys);
+     106          10 :   keys.add("optional","NORMALIZATION","the normalization factor that is used to normalize the basis functions by dividing the values. By default it is 2.");
+     107          10 :   keys.addFlag("PERIODIC", false, "Use periodic version of basis set.");
+     108           5 :   keys.remove("NUMERICAL_INTEGRALS");
+     109           5 : }
+     110             : 
+     111           3 : BF_CubicBsplines::BF_CubicBsplines(const ActionOptions&ao):
+     112           3 :   PLUMED_VES_BASISFUNCTIONS_INIT(ao)
+     113             : {
+     114           3 :   log.printf("  Cubic B spline basis functions, see and cite ");
+     115           6 :   log << plumed.cite("Pampel and Valsson, J. Chem. Theory Comput. 18, 4127-4141 (2022) - DOI:10.1021/acs.jctc.2c00197");
+     116             : 
+     117           3 :   setIntrinsicInterval(intervalMin(),intervalMax());
+     118           3 :   spacing_=(intervalMax()-intervalMin())/static_cast<double>(getOrder());
+     119           3 :   inv_spacing_ = 1.0/spacing_;
+     120             : 
+     121           3 :   bool periodic = false;
+     122           3 :   parseFlag("PERIODIC",periodic);
+     123           4 :   if (periodic) {addKeywordToList("PERIODIC",periodic);}
+     124             : 
+     125             :   // 1 constant, getOrder() on interval, 1 (left) + 2 (right) at boundaries if not periodic
+     126           3 :   unsigned int num_BFs = periodic ? getOrder()+1U : getOrder()+4U;
+     127           3 :   setNumberOfBasisFunctions(num_BFs);
+     128             : 
+     129           3 :   double normfactor_=2.0;
+     130           3 :   parse("NORMALIZATION",normfactor_);
+     131           3 :   if(normfactor_!=2.0) {addKeywordToList("NORMALIZATION",normfactor_);}
+     132           3 :   inv_normfactor_=1.0/normfactor_;
+     133             : 
+     134           3 :   periodic ? setPeriodic() : setNonPeriodic();
+     135             :   setIntervalBounded();
+     136           3 :   setType("splines_2nd-order");
+     137           3 :   setDescription("Cubic B-splines (2nd order splines)");
+     138           3 :   setLabelPrefix("S");
+     139           3 :   setupBF();
+     140           3 :   log.printf("   normalization factor: %f\n",normfactor_);
+     141           3 :   checkRead();
+     142           3 : }
+     143             : 
+     144             : 
+     145        9236 : void BF_CubicBsplines::getAllValues(const double arg, double& argT, bool& inside_range, std::vector<double>& values, std::vector<double>& derivs) const {
+     146             :   // plumed_assert(values.size()==numberOfBasisFunctions());
+     147             :   // plumed_assert(derivs.size()==numberOfBasisFunctions());
+     148        9236 :   inside_range=true;
+     149        9236 :   argT=checkIfArgumentInsideInterval(arg,inside_range);
+     150             :   //
+     151        9236 :   values[0]=1.0;
+     152        9236 :   derivs[0]=0.0;
+     153             :   //
+     154      212043 :   for(unsigned int i=1; i < getNumberOfBasisFunctions(); i++) {
+     155      202807 :     double argx = ((argT-intervalMin())*inv_spacing_) - (static_cast<double>(i) - 2.0);
+     156      202807 :     if(arePeriodic()) { // periodic range of argx is [-intervalRange/spacing,+intervalRange/spacing]
+     157       64140 :       argx /= intervalRange()*inv_spacing_;
+     158       64140 :       argx = Tools::pbc(argx);
+     159       64140 :       argx *= (intervalRange()*inv_spacing_);
+     160             :     }
+     161      202807 :     values[i] = spline(argx, derivs[i]);
+     162      202807 :     derivs[i] *= inv_spacing_;
+     163             :   }
+     164       11156 :   if(!inside_range) {for(unsigned int i=0; i<derivs.size(); i++) {derivs[i]=0.0;}}
+     165        9236 : }
+     166             : 
+     167             : 
+     168      202807 : double BF_CubicBsplines::spline(const double arg, double& deriv) const {
+     169             :   double value=0.0;
+     170             :   double x=arg;
+     171             :   // derivative of abs(x);
+     172             :   double dx = 1.0;
+     173      202807 :   if(x < 0) {
+     174      101208 :     x=-x;
+     175             :     dx = -1.0;
+     176             :   }
+     177             :   //
+     178      202807 :   if(x > 2) {
+     179             :     value=0.0;
+     180      165556 :     deriv=0.0;
+     181             :   }
+     182       37251 :   else if(x >= 1) {
+     183       18896 :     value = ((2.0-x)*(2.0-x)*(2.0-x));
+     184       18896 :     deriv = dx*(-3.0*(2.0-x)*(2.0-x));
+     185             :     // value=((2.0-x)*(2.0-x)*(2.0-x))/6.0;
+     186             :     // deriv=-x*x*(2.0-x)*(2.0-x);
+     187             :   }
+     188             :   else {
+     189       18355 :     value = 4.0-6.0*x*x+3.0*x*x*x;
+     190       18355 :     deriv = dx*(-12.0*x+9.0*x*x);
+     191             :     // value=x*x*x*0.5-x*x+2.0/3.0;
+     192             :     // deriv=(3.0/2.0)*x*x-2.0*x;
+     193             :   }
+     194      202807 :   value *= inv_normfactor_;
+     195      202807 :   deriv *= inv_normfactor_;
+     196      202807 :   return value;
+     197             : }
+     198             : 
+     199             : 
+     200             : }
+     201             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Custom.cpp.func-sort-c.html b/coverage/ves/BF_Custom.cpp.func-sort-c.html new file mode 100644 index 000000000000..d031d61ebb5f --- /dev/null +++ b/coverage/ves/BF_Custom.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - ves/BF_Custom.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BF_Custom.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12515282.2 %
Date:2024-04-19 12:12:35Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves9BF_CustomC2ERKNS_13ActionOptionsE10
_ZN4PLMD3ves9BF_CustomD0Ev10
_ZN4PLMD3ves9BF_CustomD2Ev10
_ZN4PLMD3ves9BF_Custom16registerKeywordsERNS_8KeywordsE12
_ZNK4PLMD3ves9BF_Custom12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_24204
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Custom.cpp.func.html b/coverage/ves/BF_Custom.cpp.func.html new file mode 100644 index 000000000000..81f58d8797d4 --- /dev/null +++ b/coverage/ves/BF_Custom.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - ves/BF_Custom.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BF_Custom.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12515282.2 %
Date:2024-04-19 12:12:35Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves9BF_Custom16registerKeywordsERNS_8KeywordsE12
_ZN4PLMD3ves9BF_CustomC2ERKNS_13ActionOptionsE10
_ZN4PLMD3ves9BF_CustomD0Ev10
_ZN4PLMD3ves9BF_CustomD2Ev10
_ZNK4PLMD3ves9BF_Custom12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_24204
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Custom.cpp.gcov.html b/coverage/ves/BF_Custom.cpp.gcov.html new file mode 100644 index 000000000000..ff352c6de554 --- /dev/null +++ b/coverage/ves/BF_Custom.cpp.gcov.html @@ -0,0 +1,446 @@ + + + + + + + + LCOV - plumed test coverage - ves/BF_Custom.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BF_Custom.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12515282.2 %
Date:2024-04-19 12:12:35Functions:55100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "BasisFunctions.h"
+      24             : 
+      25             : #include "core/ActionRegister.h"
+      26             : #include "lepton/Lepton.h"
+      27             : 
+      28             : 
+      29             : namespace PLMD {
+      30             : namespace ves {
+      31             : 
+      32             : //+PLUMEDOC VES_BASISF BF_CUSTOM
+      33             : /*
+      34             : Basis functions given by arbitrary mathematical expressions.
+      35             : 
+      36             : This allows you to define basis functions using arbitrary mathematical expressions
+      37             : that are parsed using the lepton library.
+      38             : The basis functions
+      39             : \f$f_{i}(x)\f$ are given in mathematical expressions with _x_ as a variable using
+      40             : the numbered FUNC keywords that start from
+      41             : FUNC1. Consistent with other basis functions is \f$f_{0}(x)=1\f$ defined as
+      42             : the constant. The interval on which the basis functions are defined is
+      43             : given using the MINIMUM and MAXIMUM keywords.
+      44             : 
+      45             : Using the TRANSFORM keyword it is possible to define a function \f$x(t)\f$ that
+      46             : is used to transform the argument before calculating the basis functions
+      47             : values. The variables _min_ and _max_ can be used to indicate the minimum
+      48             : and the maximum of the interval. By default the arguments are not transformed,
+      49             : i.e. \f$x(t)=t\f$.
+      50             : 
+      51             : For periodic basis functions you should use the PERIODIC flag to indicate
+      52             : that they are periodic.
+      53             : 
+      54             : The basis functions \f$f_{i}(x)\f$ and the transform function \f$x(t)\f$ need
+      55             : to be well behaved in the interval on which the basis functions are defined,
+      56             : e.g. not result in a not a number (nan) or infinity (inf).
+      57             : The code will not perform checks to make sure that this is the case unless the
+      58             : flag CHECK_NAN_INF is enabled.
+      59             : 
+      60             : \par Examples
+      61             : 
+      62             : Defining Legendre polynomial basis functions of order 6 using BF_CUSTOM
+      63             : where the appropriate transform function is given by the TRANSFORM keyword.
+      64             : This is just an example of what can be done, in practice you should use
+      65             : \ref BF_LEGENDRE for Legendre polynomial basis functions.
+      66             : \plumedfile
+      67             : BF_CUSTOM ...
+      68             :  TRANSFORM=(t-(min+max)/2)/((max-min)/2)
+      69             :  FUNC1=x
+      70             :  FUNC2=(1/2)*(3*x^2-1)
+      71             :  FUNC3=(1/2)*(5*x^3-3*x)
+      72             :  FUNC4=(1/8)*(35*x^4-30*x^2+3)
+      73             :  FUNC5=(1/8)*(63*x^5-70*x^3+15*x)
+      74             :  FUNC6=(1/16)*(231*x^6-315*x^4+105*x^2-5)
+      75             :  MINIMUM=-4.0
+      76             :  MAXIMUM=4.0
+      77             :  LABEL=bf1
+      78             : ... BF_CUSTOM
+      79             : \endplumedfile
+      80             : 
+      81             : 
+      82             : Defining Fourier basis functions of order 3 using BF_CUSTOM where the
+      83             : periodicity is indicated using the PERIODIC flag. This is just an example
+      84             : of what can be done, in practice you should use \ref BF_FOURIER
+      85             : for Fourier basis functions.
+      86             : \plumedfile
+      87             : BF_CUSTOM ...
+      88             :  FUNC1=cos(x)
+      89             :  FUNC2=sin(x)
+      90             :  FUNC3=cos(2*x)
+      91             :  FUNC4=sin(2*x)
+      92             :  FUNC5=cos(3*x)
+      93             :  FUNC6=sin(3*x)
+      94             :  MINIMUM=-pi
+      95             :  MAXIMUM=+pi
+      96             :  LABEL=bf1
+      97             :  PERIODIC
+      98             : ... BF_CUSTOM
+      99             : \endplumedfile
+     100             : 
+     101             : 
+     102             : */
+     103             : //+ENDPLUMEDOC
+     104             : 
+     105             : class BF_Custom : public BasisFunctions {
+     106             : private:
+     107             :   lepton::CompiledExpression transf_value_expression_;
+     108             :   lepton::CompiledExpression transf_deriv_expression_;
+     109             :   double* transf_value_lepton_ref_;
+     110             :   double* transf_deriv_lepton_ref_;
+     111             :   std::vector<lepton::CompiledExpression> bf_values_expressions_;
+     112             :   std::vector<lepton::CompiledExpression> bf_derivs_expressions_;
+     113             :   std::vector<double*> bf_values_lepton_ref_;
+     114             :   std::vector<double*> bf_derivs_lepton_ref_;
+     115             :   std::string variable_str_;
+     116             :   std::string transf_variable_str_;
+     117             :   bool do_transf_;
+     118             :   bool check_nan_inf_;
+     119             : public:
+     120             :   static void registerKeywords( Keywords&);
+     121             :   explicit BF_Custom(const ActionOptions&);
+     122          30 :   ~BF_Custom() {};
+     123             :   void getAllValues(const double, double&, bool&, std::vector<double>&, std::vector<double>&) const override;
+     124             : };
+     125             : 
+     126             : PLUMED_REGISTER_ACTION(BF_Custom,"BF_CUSTOM")
+     127             : 
+     128          12 : void BF_Custom::registerKeywords(Keywords& keys) {
+     129          12 :   BasisFunctions::registerKeywords(keys);
+     130          12 :   keys.remove("ORDER");
+     131          24 :   keys.add("numbered","FUNC","The basis functions f_i(x) given in mathematical expressions using _x_ as a variable.");
+     132          24 :   keys.add("optional","TRANSFORM","An optional function that can be used to transform the argument before calculating the basis function values. You should use _t_ as a variable. You can use the variables _min_ and _max_ to give the minimum and the maximum of the interval.");
+     133          24 :   keys.addFlag("PERIODIC",false,"Indicate that the basis functions are periodic.");
+     134          24 :   keys.addFlag("CHECK_NAN_INF",false,"Check that the basis functions do not result in a not a number (nan) or infinity (inf).");
+     135          12 :   keys.remove("NUMERICAL_INTEGRALS");
+     136          12 : }
+     137             : 
+     138             : 
+     139          10 : BF_Custom::BF_Custom(const ActionOptions&ao):
+     140             :   PLUMED_VES_BASISFUNCTIONS_INIT(ao),
+     141          10 :   transf_value_lepton_ref_(nullptr),
+     142          10 :   transf_deriv_lepton_ref_(nullptr),
+     143          10 :   bf_values_expressions_(0),
+     144          10 :   bf_derivs_expressions_(0),
+     145          10 :   bf_values_lepton_ref_(0,nullptr),
+     146          10 :   bf_derivs_lepton_ref_(0,nullptr),
+     147          10 :   variable_str_("x"),
+     148          10 :   transf_variable_str_("t"),
+     149          10 :   do_transf_(false),
+     150          20 :   check_nan_inf_(false)
+     151             : {
+     152             :   std::vector<std::string> bf_str;
+     153          10 :   std::string str_t1="1";
+     154          10 :   bf_str.push_back(str_t1);
+     155          10 :   for(int i=1;; i++) {
+     156             :     std::string str_t2;
+     157         112 :     if(!parseNumbered("FUNC",i,str_t2)) {break;}
+     158          46 :     std::string is; Tools::convert(i,is);
+     159          92 :     addKeywordToList("FUNC"+is,str_t2);
+     160          46 :     bf_str.push_back(str_t2);
+     161          46 :   }
+     162             :   //
+     163          10 :   if(bf_str.size()==1) {plumed_merror(getName()+" with label "+getLabel()+": No FUNC keywords given");}
+     164             : 
+     165          10 :   setOrder(bf_str.size()-1);
+     166          10 :   setNumberOfBasisFunctions(getOrder()+1);
+     167          10 :   setIntrinsicInterval(intervalMin(),intervalMax());
+     168          10 :   bool periodic = false;
+     169          20 :   parseFlag("PERIODIC",periodic); addKeywordToList("PERIODIC",periodic);
+     170          10 :   if(periodic) {setPeriodic();}
+     171             :   else {setNonPeriodic();}
+     172             :   setIntervalBounded();
+     173          10 :   setType("custom_functions");
+     174          20 :   setDescription("Custom Functions");
+     175             :   //
+     176          10 :   std::vector<std::string> bf_values_parsed(getNumberOfBasisFunctions());
+     177          10 :   std::vector<std::string> bf_derivs_parsed(getNumberOfBasisFunctions());
+     178             :   bf_values_parsed[0] = "1";
+     179             :   bf_derivs_parsed[0] = "0";
+     180             :   //
+     181          10 :   bf_values_expressions_.resize(getNumberOfBasisFunctions());
+     182          10 :   bf_derivs_expressions_.resize(getNumberOfBasisFunctions());
+     183          10 :   bf_values_lepton_ref_.resize(getNumberOfBasisFunctions());
+     184          10 :   bf_derivs_lepton_ref_.resize(getNumberOfBasisFunctions());
+     185             :   //
+     186          56 :   for(unsigned int i=1; i<getNumberOfBasisFunctions(); i++) {
+     187          46 :     std::string is; Tools::convert(i,is);
+     188             :     try {
+     189          46 :       lepton::ParsedExpression pe_value = lepton::Parser::parse(bf_str[i]).optimize(lepton::Constants());
+     190          46 :       std::ostringstream tmp_stream; tmp_stream << pe_value;
+     191          46 :       bf_values_parsed[i] = tmp_stream.str();
+     192          46 :       bf_values_expressions_[i] = pe_value.createCompiledExpression();
+     193          46 :     }
+     194           0 :     catch(PLMD::lepton::Exception& exc) {
+     195           0 :       plumed_merror("There was some problem in parsing the function "+bf_str[i]+" given in FUNC"+is + " with lepton");
+     196           0 :     }
+     197             : 
+     198             :     std::vector<std::string> var_str;
+     199          92 :     for(auto &p: bf_values_expressions_[i].getVariables()) {
+     200          46 :       var_str.push_back(p);
+     201             :     }
+     202          46 :     if(var_str.size()!=1) {
+     203           0 :       plumed_merror("Problem with function "+bf_str[i]+" given in FUNC"+is+": there should only be one variable");
+     204             :     }
+     205          46 :     if(var_str[0]!=variable_str_) {
+     206           0 :       plumed_merror("Problem with function "+bf_str[i]+" given in FUNC"+is+": you should use "+variable_str_+" as a variable");
+     207             :     }
+     208             : 
+     209             :     try {
+     210          92 :       lepton::ParsedExpression pe_deriv = lepton::Parser::parse(bf_str[i]).differentiate(variable_str_).optimize(lepton::Constants());
+     211          46 :       std::ostringstream tmp_stream2; tmp_stream2 << pe_deriv;
+     212          46 :       bf_derivs_parsed[i] = tmp_stream2.str();
+     213          46 :       bf_derivs_expressions_[i] = pe_deriv.createCompiledExpression();
+     214          46 :     }
+     215           0 :     catch(PLMD::lepton::Exception& exc) {
+     216           0 :       plumed_merror("There was some problem in parsing the derivative of the function "+bf_str[i]+" given in FUNC"+is + " with lepton");
+     217           0 :     }
+     218             : 
+     219             :     try {
+     220          46 :       bf_values_lepton_ref_[i] = &bf_values_expressions_[i].getVariableReference(variable_str_);
+     221           0 :     } catch(PLMD::lepton::Exception& exc) {}
+     222             : 
+     223             :     try {
+     224          46 :       bf_derivs_lepton_ref_[i] = &bf_derivs_expressions_[i].getVariableReference(variable_str_);
+     225           8 :     } catch(PLMD::lepton::Exception& exc) {}
+     226             : 
+     227          46 :   }
+     228             : 
+     229             :   std::string transf_value_parsed;
+     230             :   std::string transf_deriv_parsed;
+     231             :   std::string transf_str;
+     232          20 :   parse("TRANSFORM",transf_str);
+     233          10 :   if(transf_str.size()>0) {
+     234           6 :     do_transf_ = true;
+     235          12 :     addKeywordToList("TRANSFORM",transf_str);
+     236             :     for(unsigned int k=0;; k++) {
+     237          14 :       if(transf_str.find("min")!=std::string::npos) {transf_str.replace(transf_str.find("min"), std::string("min").length(),intervalMinStr());}
+     238             :       else {break;}
+     239             :     }
+     240             :     for(unsigned int k=0;; k++) {
+     241          14 :       if(transf_str.find("max")!=std::string::npos) {transf_str.replace(transf_str.find("max"), std::string("max").length(),intervalMaxStr());}
+     242             :       else {break;}
+     243             :     }
+     244             : 
+     245             :     try {
+     246           6 :       lepton::ParsedExpression pe_value = lepton::Parser::parse(transf_str).optimize(lepton::Constants());;
+     247           6 :       std::ostringstream tmp_stream; tmp_stream << pe_value;
+     248           6 :       transf_value_parsed = tmp_stream.str();
+     249           6 :       transf_value_expression_ = pe_value.createCompiledExpression();
+     250           6 :     }
+     251           0 :     catch(PLMD::lepton::Exception& exc) {
+     252           0 :       plumed_merror("There was some problem in parsing the function "+transf_str+" given in TRANSFORM with lepton");
+     253           0 :     }
+     254             : 
+     255             :     std::vector<std::string> var_str;
+     256          12 :     for(auto &p: transf_value_expression_.getVariables()) {
+     257           6 :       var_str.push_back(p);
+     258             :     }
+     259           6 :     if(var_str.size()!=1) {
+     260           0 :       plumed_merror("Problem with function "+transf_str+" given in TRANSFORM: there should only be one variable");
+     261             :     }
+     262           6 :     if(var_str[0]!=transf_variable_str_) {
+     263           0 :       plumed_merror("Problem with function "+transf_str+" given in TRANSFORM: you should use "+transf_variable_str_+" as a variable");
+     264             :     }
+     265             : 
+     266             :     try {
+     267          12 :       lepton::ParsedExpression pe_deriv = lepton::Parser::parse(transf_str).differentiate(transf_variable_str_).optimize(lepton::Constants());;
+     268           6 :       std::ostringstream tmp_stream2; tmp_stream2 << pe_deriv;
+     269           6 :       transf_deriv_parsed = tmp_stream2.str();
+     270           6 :       transf_deriv_expression_ = pe_deriv.createCompiledExpression();
+     271           6 :     }
+     272           0 :     catch(PLMD::lepton::Exception& exc) {
+     273           0 :       plumed_merror("There was some problem in parsing the derivative of the function "+transf_str+" given in TRANSFORM with lepton");
+     274           0 :     }
+     275             : 
+     276             :     try {
+     277           6 :       transf_value_lepton_ref_ = &transf_value_expression_.getVariableReference(transf_variable_str_);
+     278           0 :     } catch(PLMD::lepton::Exception& exc) {}
+     279             : 
+     280             :     try {
+     281           6 :       transf_deriv_lepton_ref_ = &transf_deriv_expression_.getVariableReference(transf_variable_str_);
+     282           3 :     } catch(PLMD::lepton::Exception& exc) {}
+     283             : 
+     284           6 :   }
+     285             :   //
+     286          10 :   log.printf("  Using the following functions [lepton parsed function and derivative]:\n");
+     287          66 :   for(unsigned int i=0; i<getNumberOfBasisFunctions(); i++) {
+     288          56 :     log.printf("   %u:  %s   [   %s   |   %s   ] \n",i,bf_str[i].c_str(),bf_values_parsed[i].c_str(),bf_derivs_parsed[i].c_str());
+     289             : 
+     290             :   }
+     291             :   //
+     292          10 :   if(do_transf_) {
+     293           6 :     log.printf("  Arguments are transformed using the following function [lepton parsed function and derivative]:\n");
+     294           6 :     log.printf("   %s   [   %s   |   %s   ] \n",transf_str.c_str(),transf_value_parsed.c_str(),transf_deriv_parsed.c_str());
+     295             :   }
+     296             :   else {
+     297           4 :     log.printf("  Arguments are not transformed\n");
+     298             :   }
+     299             :   //
+     300             : 
+     301          20 :   parseFlag("CHECK_NAN_INF",check_nan_inf_); addKeywordToList("CHECK_NAN_INF",check_nan_inf_);
+     302          10 :   if(check_nan_inf_) {
+     303           6 :     log.printf("  The code will check that values given are numercially stable, e.g. do not result in a not a number (nan) or infinity (inf).\n");
+     304             :   }
+     305             :   else {
+     306           4 :     log.printf("  The code will NOT check that values given are numercially stable, e.g. do not result in a not a number (nan) or infinity (inf).\n");
+     307             :   }
+     308             : 
+     309          10 :   setupBF();
+     310          10 :   checkRead();
+     311          20 : }
+     312             : 
+     313             : 
+     314       24204 : void BF_Custom::getAllValues(const double arg, double& argT, bool& inside_range, std::vector<double>& values, std::vector<double>& derivs) const {
+     315       24204 :   inside_range=true;
+     316       24204 :   argT=checkIfArgumentInsideInterval(arg,inside_range);
+     317       24204 :   double transf_derivf=1.0;
+     318             :   //
+     319       24204 :   if(do_transf_) {
+     320             : 
+     321       14062 :     if(transf_value_lepton_ref_) {*transf_value_lepton_ref_ = argT;}
+     322       14062 :     if(transf_deriv_lepton_ref_) {*transf_deriv_lepton_ref_ = argT;}
+     323             : 
+     324       14062 :     argT = transf_value_expression_.evaluate();
+     325       14062 :     transf_derivf = transf_deriv_expression_.evaluate();
+     326             : 
+     327       14062 :     if(check_nan_inf_ && (std::isnan(argT) || std::isinf(argT)) ) {
+     328           0 :       std::string vs; Tools::convert(argT,vs);
+     329           0 :       plumed_merror(getName()+" with label "+getLabel()+": problem with the transform function, it gives " + vs);
+     330             :     }
+     331             : 
+     332       14062 :     if(check_nan_inf_ && (std::isnan(transf_derivf) || std::isinf(transf_derivf)) ) {
+     333           0 :       std::string vs; Tools::convert(transf_derivf,vs);
+     334           0 :       plumed_merror(getName()+" with label "+getLabel()+": problem with the transform function, its derivative gives " + vs);
+     335             :     }
+     336             :   }
+     337             :   //
+     338       24204 :   values[0]=1.0;
+     339       24204 :   derivs[0]=0.0;
+     340      137488 :   for(unsigned int i=1; i < getNumberOfBasisFunctions(); i++) {
+     341             : 
+     342      113284 :     if(bf_values_lepton_ref_[i]) {*bf_values_lepton_ref_[i] = argT;}
+     343      113284 :     if(bf_derivs_lepton_ref_[i]) {*bf_derivs_lepton_ref_[i] = argT;}
+     344             : 
+     345      113284 :     values[i] = bf_values_expressions_[i].evaluate();
+     346      113284 :     derivs[i] = bf_derivs_expressions_[i].evaluate();
+     347             : 
+     348      113284 :     if(do_transf_) {derivs[i]*=transf_derivf;}
+     349             :     // NaN checks
+     350      113284 :     if(check_nan_inf_ && (std::isnan(values[i]) || std::isinf(values[i])) ) {
+     351           0 :       std::string vs; Tools::convert(values[i],vs);
+     352           0 :       std::string is; Tools::convert(i,is);
+     353           0 :       plumed_merror(getName()+" with label "+getLabel()+": problem with the basis function given in FUNC"+is+", it gives "+vs);
+     354             :     }
+     355             :     //
+     356      113284 :     if(check_nan_inf_ && (std::isnan(derivs[i])|| std::isinf(derivs[i])) ) {
+     357             :       std::string vs; Tools::convert(derivs[i],vs);
+     358           0 :       std::string is; Tools::convert(i,is);
+     359           0 :       plumed_merror(getName()+" with label "+getLabel()+": problem with derivative of the basis function given in FUNC"+is+", it gives "+vs);
+     360             :     }
+     361             :   }
+     362       26218 :   if(!inside_range) {for(unsigned int i=0; i<derivs.size(); i++) {derivs[i]=0.0;}}
+     363       24204 : }
+     364             : 
+     365             : 
+     366             : 
+     367             : 
+     368             : }
+     369             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Fourier.cpp.func-sort-c.html b/coverage/ves/BF_Fourier.cpp.func-sort-c.html new file mode 100644 index 000000000000..8905d4d32678 --- /dev/null +++ b/coverage/ves/BF_Fourier.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - ves/BF_Fourier.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BF_Fourier.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3838100.0 %
Date:2024-04-19 12:12:35Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves10BF_Fourier21setupUniformIntegralsEv94
_ZN4PLMD3ves10BF_Fourier11setupLabelsEv95
_ZN4PLMD3ves10BF_FourierC2ERKNS_13ActionOptionsE95
_ZN4PLMD3ves10BF_Fourier16registerKeywordsERNS_8KeywordsE97
_ZNK4PLMD3ves10BF_Fourier12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_3244265
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Fourier.cpp.func.html b/coverage/ves/BF_Fourier.cpp.func.html new file mode 100644 index 000000000000..cdb8a81dca6b --- /dev/null +++ b/coverage/ves/BF_Fourier.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - ves/BF_Fourier.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BF_Fourier.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3838100.0 %
Date:2024-04-19 12:12:35Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves10BF_Fourier11setupLabelsEv95
_ZN4PLMD3ves10BF_Fourier16registerKeywordsERNS_8KeywordsE97
_ZN4PLMD3ves10BF_Fourier21setupUniformIntegralsEv94
_ZN4PLMD3ves10BF_FourierC2ERKNS_13ActionOptionsE95
_ZNK4PLMD3ves10BF_Fourier12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_3244265
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Fourier.cpp.gcov.html b/coverage/ves/BF_Fourier.cpp.gcov.html new file mode 100644 index 000000000000..c1ed20807d41 --- /dev/null +++ b/coverage/ves/BF_Fourier.cpp.gcov.html @@ -0,0 +1,233 @@ + + + + + + + + LCOV - plumed test coverage - ves/BF_Fourier.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BF_Fourier.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3838100.0 %
Date:2024-04-19 12:12:35Functions:55100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "BasisFunctions.h"
+      24             : 
+      25             : #include "core/ActionRegister.h"
+      26             : 
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace ves {
+      30             : 
+      31             : //+PLUMEDOC VES_BASISF BF_FOURIER
+      32             : /*
+      33             : Fourier basis functions.
+      34             : 
+      35             : Use as basis functions Fourier series defined on a periodic interval.
+      36             : You need to provide the periodic interval \f$[a,b]\f$
+      37             : on which the basis functions are to be used, and the order of the
+      38             : expansion \f$N\f$ (i.e. the highest Fourier mode used).
+      39             : The total number of basis functions is \f$2N+1\f$ as for each Fourier
+      40             : mode there is both the cosine and sine term,
+      41             : and the constant \f$f_{0}(x)=1\f$ is also included.
+      42             : These basis functions should only be used for periodic CVs.
+      43             : 
+      44             : The Fourier series basis functions are given by
+      45             : \f{align}{
+      46             : f_{0}(x)    &= 1 \\
+      47             : f_{1}(x)    &= cos(\frac{2\pi }{P} x) \\
+      48             : f_{2}(x)    &= sin(\frac{2\pi }{P} x) \\
+      49             : f_{3}(x)    &= cos(2 \cdot \frac{2\pi}{P} x) \\
+      50             : f_{4}(x)    &= sin(2 \cdot \frac{2\pi}{P} x) \\
+      51             : & \vdots \\
+      52             : f_{2k-1}(x) &= cos(k \cdot \frac{2\pi}{P} x) \\
+      53             : f_{2k}(x)   &= sin(k \cdot \frac{2\pi}{P} x) \\
+      54             : & \vdots \\
+      55             : f_{2N-1}(x) &= cos(N \cdot \frac{2\pi}{P} x) \\
+      56             : f_{2N}(x)   &= sin(N \cdot \frac{2\pi}{P} x) \\
+      57             : \f}
+      58             : where \f$P=(b-a)\f$ is the periodicity of the interval.
+      59             : They are orthogonal over the interval \f$[a,b]\f$
+      60             : \f[
+      61             : \int_{a}^{b} dx \, f_{n}(x)\, f_{m}(x)  =
+      62             : \begin{cases}
+      63             : 0 & n \neq m \\
+      64             : (b-a) & n = m = 0 \\
+      65             : (b-a)/2 & n = m \neq 0
+      66             : \end{cases}.
+      67             : \f]
+      68             : 
+      69             : 
+      70             : \par Examples
+      71             : 
+      72             : Here we employ a Fourier expansion of order 10 over the periodic interval
+      73             : \f$-\pi\f$ to \f$+\pi\f$.
+      74             : This results in a total number of 21 basis functions.
+      75             : The label used to identify  the basis function action can then be
+      76             : referenced later on in the input file.
+      77             : \plumedfile
+      78             : BF_FOURIER MINIMUM=-pi MAXIMUM=+pi ORDER=10 LABEL=bf_fourier
+      79             : \endplumedfile
+      80             : 
+      81             : 
+      82             : */
+      83             : //+ENDPLUMEDOC
+      84             : 
+      85             : class BF_Fourier : public BasisFunctions {
+      86             :   void setupLabels() override;
+      87             :   void setupUniformIntegrals() override;
+      88             : public:
+      89             :   static void registerKeywords(Keywords&);
+      90             :   explicit BF_Fourier(const ActionOptions&);
+      91             :   void getAllValues(const double, double&, bool&, std::vector<double>&, std::vector<double>&) const override;
+      92             : };
+      93             : 
+      94             : 
+      95             : PLUMED_REGISTER_ACTION(BF_Fourier,"BF_FOURIER")
+      96             : 
+      97             : 
+      98          97 : void BF_Fourier::registerKeywords(Keywords& keys) {
+      99          97 :   BasisFunctions::registerKeywords(keys);
+     100          97 : }
+     101             : 
+     102             : 
+     103          95 : BF_Fourier::BF_Fourier(const ActionOptions&ao):
+     104          95 :   PLUMED_VES_BASISFUNCTIONS_INIT(ao)
+     105             : {
+     106          95 :   setNumberOfBasisFunctions(2*getOrder()+1);
+     107         190 :   setIntrinsicInterval("-pi","+pi");
+     108             :   setPeriodic();
+     109             :   setIntervalBounded();
+     110          95 :   setType("trigonometric_cos-sin");
+     111          95 :   setDescription("Trigonometric (cos/sin)");
+     112          95 :   setupBF();
+     113          95 :   checkRead();
+     114          95 : }
+     115             : 
+     116             : 
+     117     3244265 : void BF_Fourier::getAllValues(const double arg, double& argT, bool& inside_range, std::vector<double>& values, std::vector<double>& derivs) const {
+     118             :   // plumed_assert(values.size()==numberOfBasisFunctions());
+     119             :   // plumed_assert(derivs.size()==numberOfBasisFunctions());
+     120     3244265 :   inside_range=true;
+     121     3244265 :   argT=translateArgument(arg, inside_range);
+     122     3244265 :   values[0]=1.0;
+     123     3244265 :   derivs[0]=0.0;
+     124    17806383 :   for(unsigned int i=1; i < getOrder()+1; i++) {
+     125    14562118 :     double io = i;
+     126    14562118 :     double cos_tmp = cos(io*argT);
+     127    14562118 :     double sin_tmp = sin(io*argT);
+     128    14562118 :     values[2*i-1] = cos_tmp;
+     129    14562118 :     derivs[2*i-1] = -io*sin_tmp*intervalDerivf();
+     130    14562118 :     values[2*i] = sin_tmp;
+     131    14562118 :     derivs[2*i] = io*cos_tmp*intervalDerivf();
+     132             :   }
+     133     3244265 :   if(!inside_range) {
+     134       23980 :     for(unsigned int i=0; i<derivs.size(); i++) {derivs[i]=0.0;}
+     135             :   }
+     136     3244265 : }
+     137             : 
+     138             : 
+     139          95 : void BF_Fourier::setupLabels() {
+     140          95 :   setLabel(0,"1");
+     141         568 :   for(unsigned int i=1; i < getOrder()+1; i++) {
+     142         473 :     std::string is; Tools::convert(i,is);
+     143         946 :     setLabel(2*i-1,"cos("+is+"*s)");
+     144         946 :     setLabel(2*i,"sin("+is+"*s)");
+     145             :   }
+     146          95 : }
+     147             : 
+     148             : 
+     149          94 : void BF_Fourier::setupUniformIntegrals() {
+     150          94 :   setAllUniformIntegralsToZero();
+     151             :   setUniformIntegral(0,1.0);
+     152          94 : }
+     153             : 
+     154             : 
+     155             : }
+     156             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Gaussians.cpp.func-sort-c.html b/coverage/ves/BF_Gaussians.cpp.func-sort-c.html new file mode 100644 index 000000000000..df824a582bb8 --- /dev/null +++ b/coverage/ves/BF_Gaussians.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - ves/BF_Gaussians.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BF_Gaussians.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:5252100.0 %
Date:2024-04-19 12:12:35Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12BF_Gaussians11setupLabelsEv3
_ZN4PLMD3ves12BF_GaussiansC2ERKNS_13ActionOptionsE3
_ZN4PLMD3ves12BF_Gaussians16registerKeywordsERNS_8KeywordsE5
_ZNK4PLMD3ves12BF_Gaussians12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_9236
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Gaussians.cpp.func.html b/coverage/ves/BF_Gaussians.cpp.func.html new file mode 100644 index 000000000000..9a02a295e102 --- /dev/null +++ b/coverage/ves/BF_Gaussians.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - ves/BF_Gaussians.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BF_Gaussians.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:5252100.0 %
Date:2024-04-19 12:12:35Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12BF_Gaussians11setupLabelsEv3
_ZN4PLMD3ves12BF_Gaussians16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD3ves12BF_GaussiansC2ERKNS_13ActionOptionsE3
_ZNK4PLMD3ves12BF_Gaussians12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_9236
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Gaussians.cpp.gcov.html b/coverage/ves/BF_Gaussians.cpp.gcov.html new file mode 100644 index 000000000000..33b39c6d3e43 --- /dev/null +++ b/coverage/ves/BF_Gaussians.cpp.gcov.html @@ -0,0 +1,266 @@ + + + + + + + + LCOV - plumed test coverage - ves/BF_Gaussians.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BF_Gaussians.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:5252100.0 %
Date:2024-04-19 12:12:35Functions:44100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "BasisFunctions.h"
+      24             : 
+      25             : #include "core/ActionRegister.h"
+      26             : #include "core/PlumedMain.h"
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace ves {
+      30             : 
+      31             : //+PLUMEDOC VES_BASISF BF_GAUSSIANS
+      32             : /*
+      33             : Gaussian basis functions.
+      34             : 
+      35             : \attention
+      36             : __These basis functions do not form orthogonal bases. We recommend using wavelets (\ref BF_WAVELETS) instead that do form orthogonal bases__.
+      37             : 
+      38             : Basis functions given by Gaussian distributions with shifted centers defined on a
+      39             : bounded interval. See \cite ValssonPampel_Wavelets_2022 for full details.
+      40             : 
+      41             : You need to provide the interval \f$[a,b]\f$ on which the bias is to be
+      42             : expanded.
+      43             : The ORDER keyword of the basis set \f$N\f$ determines the number of equally sized
+      44             : sub-intervalls to be used.
+      45             : On the borders of each of these sub-intervalls the mean \f$\mu\f$ of a Gaussian
+      46             : basis function is placed:
+      47             : \f{align}{
+      48             :   \mu_i = a + (i-1) \frac{b-a}{N}
+      49             : \f}
+      50             : 
+      51             : The total number of basis functions is \f$N+4\f$ as the constant
+      52             : \f$f_{0}(x)=1\f$, as well as two additional Gaussians at the Boundaries are also included.
+      53             : 
+      54             : The basis functions are given by
+      55             : \f{align}{
+      56             :   f_0(x) &= 1 \\
+      57             :   f_i(x) &= \exp\left(-\frac{{\left(x-\mu_i\right)}^2}{2\sigma^2}\right)
+      58             : \f}
+      59             : 
+      60             : When the Gaussians are used for a periodic CV (with the PERIODIC keyword),
+      61             : the sub-intervals are chosen in the same way, but only \f$N+1\f$ functions
+      62             : are required to fill it (the ones at the boundary coincide and the ones outside
+      63             : can be omitted).
+      64             : 
+      65             : It is possible to specify the width \f$\sigma\f$ (i.e. the standard deviation)
+      66             : of the Gaussians using the WIDTH keyword.
+      67             : By default it is set to the sub-intervall length.
+      68             : It was found that performance can be typically improved with a smaller value (around 75 % of the sub-interval length), although a too small overlap will prevent the basis set from working correctly at all.
+      69             : 
+      70             : The optimization procedure then adjusts the heigths of the individual Gaussians.
+      71             : To avoid 'blind' optimization of the basis functions outside the currently sampled area, it is often beneficial to use the OPTIMIZATION_THRESHOLD keyword of the VES_LINEAR_EXPANSION (set it to a small value, e.g. 1e-6)
+      72             : 
+      73             : As an example two adjacent basis functions (with the mentioned width choice of 75% of the sub-interval length) can be seen below.
+      74             : The full basis consists of shifted Gaussians in the full specified interval.
+      75             : 
+      76             : \image html ves_basisf-gaussians.png
+      77             : 
+      78             : 
+      79             : \par Examples
+      80             : 
+      81             : The bias is expanded with Gaussian functions in the intervall from 0.0 to
+      82             : 10.0 using order 20.
+      83             : This results in 24 basis functions.
+      84             : 
+      85             : \plumedfile
+      86             : bfG: BF_GAUSSIANS MINIMUM=0.0 MAXIMUM=10.0 ORDER=20
+      87             : \endplumedfile
+      88             : 
+      89             : Because it was not specified, the width of the Gaussians is by default
+      90             : set to the sub-intervall length, i.e.\ \f$\sigma=0.5\f$.
+      91             : To e.g. enhance the overlap between neighbouring basis functions, it can be
+      92             : specified explicitely:
+      93             : 
+      94             : \plumedfile
+      95             : bfG: BF_GAUSSIANS MINIMUM=0.0 MAXIMUM=10.0 ORDER=20 WIDTH=0.7
+      96             : \endplumedfile
+      97             : 
+      98             : */
+      99             : //+ENDPLUMEDOC
+     100             : 
+     101             : class BF_Gaussians : public BasisFunctions {
+     102             :   /// one over width of the Gaussians
+     103             :   double inv_sigma_;
+     104             :   /// positions of the centers
+     105             :   std::vector<double> centers_;
+     106             :   void setupLabels() override;
+     107             : public:
+     108             :   static void registerKeywords( Keywords&);
+     109             :   explicit BF_Gaussians(const ActionOptions&);
+     110             :   void getAllValues(const double, double&, bool&, std::vector<double>&, std::vector<double>&) const override;
+     111             : };
+     112             : 
+     113             : 
+     114             : PLUMED_REGISTER_ACTION(BF_Gaussians,"BF_GAUSSIANS")
+     115             : 
+     116             : 
+     117           5 : void BF_Gaussians::registerKeywords(Keywords& keys) {
+     118           5 :   BasisFunctions::registerKeywords(keys);
+     119          10 :   keys.add("optional","WIDTH","The width (i.e. standart deviation) of the Gaussian functions. By default it is equal to the sub-intervall size.");
+     120          10 :   keys.addFlag("PERIODIC", false, "Use periodic version of basis set.");
+     121           5 :   keys.remove("NUMERICAL_INTEGRALS");
+     122           5 : }
+     123             : 
+     124           3 : BF_Gaussians::BF_Gaussians(const ActionOptions&ao):
+     125           3 :   PLUMED_VES_BASISFUNCTIONS_INIT(ao)
+     126             : {
+     127           3 :   log.printf("  Gaussian basis functions, see and cite ");
+     128           6 :   log << plumed.cite("Pampel and Valsson, J. Chem. Theory Comput. 18, 4127-4141 (2022) - DOI:10.1021/acs.jctc.2c00197");
+     129             : 
+     130           3 :   setIntrinsicInterval(intervalMin(),intervalMax());
+     131             : 
+     132           3 :   double width = (intervalMax()-intervalMin()) / getOrder();
+     133           3 :   parse("WIDTH",width);
+     134           3 :   if(width <= 0.0) {plumed_merror("WIDTH should be larger than 0");}
+     135           4 :   if(width != (intervalMax()-intervalMin())/getOrder()) {addKeywordToList("WIDTH",width);}
+     136           3 :   inv_sigma_ = 1/(width);
+     137             : 
+     138           3 :   bool periodic = false;
+     139           3 :   parseFlag("PERIODIC",periodic);
+     140           4 :   if (periodic) {addKeywordToList("PERIODIC",periodic);}
+     141             : 
+     142             :   // 1 constant, getOrder() on interval, 1 (left) + 2 (right) at boundaries if not periodic
+     143           3 :   unsigned int num_BFs = periodic ? getOrder()+1U : getOrder()+4U;
+     144           3 :   setNumberOfBasisFunctions(num_BFs);
+     145             : 
+     146           3 :   centers_.push_back(0.0); // constant one
+     147          69 :   for(unsigned int i=1; i < getNumberOfBasisFunctions(); i++) {
+     148          66 :     centers_.push_back(intervalMin()+(static_cast<int>(i) - 1 - static_cast<int>(!periodic))*(intervalMax()-intervalMin())/getOrder());
+     149             :   }
+     150           3 :   periodic ? setPeriodic() : setNonPeriodic();
+     151             :   setIntervalBounded();
+     152           3 :   setType("gaussian_functions");
+     153           3 :   setDescription("Gaussian functions with shifted centers that are being optimized in their height");
+     154           3 :   setupBF();
+     155           3 :   log.printf("   width: %f\n",width);
+     156           3 :   checkRead();
+     157           3 : }
+     158             : 
+     159             : 
+     160        9236 : void BF_Gaussians::getAllValues(const double arg, double& argT, bool& inside_range, std::vector<double>& values, std::vector<double>& derivs) const {
+     161        9236 :   inside_range=true;
+     162        9236 :   argT=checkIfArgumentInsideInterval(arg,inside_range);
+     163        9236 :   values[0]=1.0;
+     164        9236 :   derivs[0]=0.0;
+     165      212043 :   for(unsigned int i=1; i < getNumberOfBasisFunctions(); i++) {
+     166      202807 :     double dist = argT - centers_[i];
+     167      202807 :     if(arePeriodic()) { // wrap around similar to MetaD
+     168       64140 :       dist /= intervalRange();
+     169       64140 :       dist = Tools::pbc(dist);
+     170       64140 :       dist *= intervalRange();
+     171             :     }
+     172      202807 :     values[i] = exp(-0.5*pow(dist*inv_sigma_,2.0));
+     173      202807 :     derivs[i] = -values[i] * (dist)*pow(inv_sigma_,2.0);
+     174             :   }
+     175       11156 :   if(!inside_range) {for (auto& d: derivs) {d=0.0;}}
+     176        9236 : }
+     177             : 
+     178             : 
+     179             : // label according to position of mean
+     180           3 : void BF_Gaussians::setupLabels() {
+     181           3 :   setLabel(0,"const");
+     182          69 :   for(unsigned int i=1; i < getNumberOfBasisFunctions(); i++) {
+     183          66 :     std::string is; Tools::convert(centers_[i],is);
+     184         132 :     setLabel(i,"m="+is);
+     185             :   }
+     186           3 : }
+     187             : 
+     188             : }
+     189             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Legendre.cpp.func-sort-c.html b/coverage/ves/BF_Legendre.cpp.func-sort-c.html new file mode 100644 index 000000000000..d2a09ecaed09 --- /dev/null +++ b/coverage/ves/BF_Legendre.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - ves/BF_Legendre.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BF_Legendre.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4242100.0 %
Date:2024-04-19 12:12:35Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves11BF_Legendre21setupUniformIntegralsEv59
_ZN4PLMD3ves11BF_LegendreC2ERKNS_13ActionOptionsE61
_ZN4PLMD3ves11BF_Legendre16registerKeywordsERNS_8KeywordsE63
_ZNK4PLMD3ves11BF_Legendre12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_1625057
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Legendre.cpp.func.html b/coverage/ves/BF_Legendre.cpp.func.html new file mode 100644 index 000000000000..45c896ce0db5 --- /dev/null +++ b/coverage/ves/BF_Legendre.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - ves/BF_Legendre.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BF_Legendre.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4242100.0 %
Date:2024-04-19 12:12:35Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves11BF_Legendre16registerKeywordsERNS_8KeywordsE63
_ZN4PLMD3ves11BF_Legendre21setupUniformIntegralsEv59
_ZN4PLMD3ves11BF_LegendreC2ERKNS_13ActionOptionsE61
_ZNK4PLMD3ves11BF_Legendre12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_1625057
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Legendre.cpp.gcov.html b/coverage/ves/BF_Legendre.cpp.gcov.html new file mode 100644 index 000000000000..c766325684cd --- /dev/null +++ b/coverage/ves/BF_Legendre.cpp.gcov.html @@ -0,0 +1,249 @@ + + + + + + + + LCOV - plumed test coverage - ves/BF_Legendre.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BF_Legendre.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4242100.0 %
Date:2024-04-19 12:12:35Functions:44100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "BasisFunctions.h"
+      24             : 
+      25             : #include "core/ActionRegister.h"
+      26             : 
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace ves {
+      30             : 
+      31             : //+PLUMEDOC VES_BASISF BF_LEGENDRE
+      32             : /*
+      33             : Legendre polynomials basis functions.
+      34             : 
+      35             : Use as basis functions [Legendre polynomials](https://en.wikipedia.org/wiki/Legendre_polynomials)
+      36             : \f$P_{n}(x)\f$ defined on a bounded interval.
+      37             : You need to provide the interval \f$[a,b]\f$
+      38             : on which the basis functions are to be used, and the order of the
+      39             : expansion \f$N\f$ (i.e. the highest order polynomial used).
+      40             : The total number of basis functions is \f$N+1\f$ as the constant \f$P_{0}(x)=1\f$
+      41             : is also included.
+      42             : These basis functions should not be used for periodic CVs.
+      43             : 
+      44             : Intrinsically the Legendre polynomials are defined on the interval \f$[-1,1]\f$.
+      45             : A variable \f$t\f$ in the interval \f$[a,b]\f$ is transformed to a variable \f$x\f$
+      46             : in the intrinsic interval \f$[-1,1]\f$ by using the transform function
+      47             : \f[
+      48             : x(t) = \frac{t-(a+b)/2}
+      49             : {(b-a)/2}
+      50             : \f]
+      51             : 
+      52             : The Legendre polynomials are given by the recurrence relation
+      53             : \f{align}{
+      54             : P_{0}(x)    &= 1 \\
+      55             : P_{1}(x)    &= x \\
+      56             : P_{n+1}(x)  &= \frac{2n+1}{n+1} \, x \, P_{n}(x) -  \frac{n}{n+1} \, P_{n-1}(x)
+      57             : \f}
+      58             : 
+      59             : The first 6 polynomials are shown below
+      60             : \image html ves_basisf-legendre.png
+      61             : 
+      62             : The Legendre polynomial are orthogonal over the interval \f$[-1,1]\f$
+      63             : \f[
+      64             : \int_{-1}^{1} dx \, P_{n}(x)\, P_{m}(x)  =  \frac{2}{2n+1} \delta_{n,m}
+      65             : \f]
+      66             : By using the SCALED keyword the polynomials are scaled by a factor of
+      67             : \f$ \sqrt{\frac{2n+1}{2}}\f$ such that they are orthonormal to 1.
+      68             : 
+      69             : 
+      70             : From the above equation it follows that integral of the basis functions
+      71             : over the uniform target distribution \f$p_{\mathrm{u}}(x)\f$ are given by
+      72             : \f[
+      73             : \int_{-1}^{1} dx \, P_{n}(x) p_{\mathrm{u}}(x) =  \delta_{n,0},
+      74             : \f]
+      75             : and thus always zero except for the constant \f$P_{0}(x)=1\f$.
+      76             : 
+      77             : 
+      78             : For further mathematical properties of the Legendre polynomials see for example
+      79             : the [Wikipedia page](https://en.wikipedia.org/wiki/Legendre_polynomials).
+      80             : 
+      81             : \par Examples
+      82             : 
+      83             : Here we employ a Legendre expansion of order 20 over the interval -4.0 to 8.0.
+      84             : This results in a total number of 21 basis functions.
+      85             : The label used to identify  the basis function action can then be
+      86             : referenced later on in the input file.
+      87             : \plumedfile
+      88             : bf_leg: BF_LEGENDRE MINIMUM=-4.0 MAXIMUM=8.0 ORDER=20
+      89             : \endplumedfile
+      90             : 
+      91             : \par Examples
+      92             : 
+      93             : */
+      94             : //+ENDPLUMEDOC
+      95             : 
+      96             : class BF_Legendre : public BasisFunctions {
+      97             :   bool scaled_;
+      98             :   void setupUniformIntegrals() override;
+      99             : public:
+     100             :   static void registerKeywords(Keywords&);
+     101             :   explicit BF_Legendre(const ActionOptions&);
+     102             :   void getAllValues(const double, double&, bool&, std::vector<double>&, std::vector<double>&) const override;
+     103             : };
+     104             : 
+     105             : 
+     106             : PLUMED_REGISTER_ACTION(BF_Legendre,"BF_LEGENDRE")
+     107             : 
+     108             : 
+     109          63 : void BF_Legendre::registerKeywords(Keywords& keys) {
+     110          63 :   BasisFunctions::registerKeywords(keys);
+     111         126 :   keys.addFlag("SCALED",false,"Scale the polynomials such that they are orthonormal to 1.");
+     112          63 : }
+     113             : 
+     114          61 : BF_Legendre::BF_Legendre(const ActionOptions&ao):
+     115             :   PLUMED_VES_BASISFUNCTIONS_INIT(ao),
+     116          61 :   scaled_(false)
+     117             : {
+     118         183 :   parseFlag("SCALED",scaled_); addKeywordToList("SCALED",scaled_);
+     119          61 :   setNumberOfBasisFunctions(getOrder()+1);
+     120         122 :   setIntrinsicInterval("-1.0","+1.0");
+     121             :   setNonPeriodic();
+     122             :   setIntervalBounded();
+     123          61 :   setType("Legendre");
+     124          61 :   setDescription("Legendre polynomials");
+     125          61 :   setLabelPrefix("L");
+     126          61 :   setupBF();
+     127          61 :   checkRead();
+     128          61 : }
+     129             : 
+     130             : 
+     131     1625057 : void BF_Legendre::getAllValues(const double arg, double& argT, bool& inside_range, std::vector<double>& values, std::vector<double>& derivs) const {
+     132             :   // plumed_assert(values.size()==numberOfBasisFunctions());
+     133             :   // plumed_assert(derivs.size()==numberOfBasisFunctions());
+     134     1625057 :   inside_range=true;
+     135     1625057 :   argT=translateArgument(arg, inside_range);
+     136     1625057 :   std::vector<double> derivsT(derivs.size());
+     137             :   //
+     138     1625057 :   values[0]=1.0;
+     139     1625057 :   derivsT[0]=0.0;
+     140     1625057 :   derivs[0]=0.0;
+     141     1625057 :   values[1]=argT;
+     142     1625057 :   derivsT[1]=1.0;
+     143     1625057 :   derivs[1]=intervalDerivf();
+     144    15470320 :   for(unsigned int i=1; i < getOrder(); i++) {
+     145    13845263 :     double io = static_cast<double>(i);
+     146    13845263 :     values[i+1]  = ((2.0*io+1.0)/(io+1.0))*argT*values[i] - (io/(io+1.0))*values[i-1];
+     147    13845263 :     derivsT[i+1] = ((2.0*io+1.0)/(io+1.0))*(values[i]+argT*derivsT[i])-(io/(io+1.0))*derivsT[i-1];
+     148    13845263 :     derivs[i+1]  = intervalDerivf()*derivsT[i+1];
+     149             :   }
+     150     1625057 :   if(scaled_) {
+     151             :     // L0 is also scaled!
+     152     5088852 :     for(unsigned int i=0; i<values.size(); i++) {
+     153     4632062 :       double io = static_cast<double>(i);
+     154     4632062 :       double sf = sqrt(io+0.5);
+     155     4632062 :       values[i] *= sf;
+     156     4632062 :       derivs[i] *= sf;
+     157             :     }
+     158             :   }
+     159     1756541 :   if(!inside_range) {for(unsigned int i=0; i<derivs.size(); i++) {derivs[i]=0.0;}}
+     160     1625057 : }
+     161             : 
+     162             : 
+     163          59 : void BF_Legendre::setupUniformIntegrals() {
+     164          59 :   setAllUniformIntegralsToZero();
+     165             :   double L0_int = 1.0;
+     166          59 :   if(scaled_) {L0_int = sqrt(0.5);}
+     167             :   setUniformIntegral(0,L0_int);
+     168          59 : }
+     169             : 
+     170             : 
+     171             : }
+     172             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Powers.cpp.func-sort-c.html b/coverage/ves/BF_Powers.cpp.func-sort-c.html new file mode 100644 index 000000000000..ca530cbffee5 --- /dev/null +++ b/coverage/ves/BF_Powers.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - ves/BF_Powers.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BF_Powers.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3535100.0 %
Date:2024-04-19 12:12:35Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves9BF_Powers11setupLabelsEv16
_ZN4PLMD3ves9BF_PowersC2ERKNS_13ActionOptionsE16
_ZN4PLMD3ves9BF_Powers16registerKeywordsERNS_8KeywordsE18
_ZNK4PLMD3ves9BF_Powers12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_842119
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Powers.cpp.func.html b/coverage/ves/BF_Powers.cpp.func.html new file mode 100644 index 000000000000..b9f54dca0fc3 --- /dev/null +++ b/coverage/ves/BF_Powers.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - ves/BF_Powers.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BF_Powers.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3535100.0 %
Date:2024-04-19 12:12:35Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves9BF_Powers11setupLabelsEv16
_ZN4PLMD3ves9BF_Powers16registerKeywordsERNS_8KeywordsE18
_ZN4PLMD3ves9BF_PowersC2ERKNS_13ActionOptionsE16
_ZNK4PLMD3ves9BF_Powers12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_842119
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Powers.cpp.gcov.html b/coverage/ves/BF_Powers.cpp.gcov.html new file mode 100644 index 000000000000..61aaf90569bf --- /dev/null +++ b/coverage/ves/BF_Powers.cpp.gcov.html @@ -0,0 +1,222 @@ + + + + + + + + LCOV - plumed test coverage - ves/BF_Powers.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BF_Powers.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3535100.0 %
Date:2024-04-19 12:12:35Functions:44100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "BasisFunctions.h"
+      24             : 
+      25             : #include "core/ActionRegister.h"
+      26             : 
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace ves {
+      30             : 
+      31             : //+PLUMEDOC VES_BASISF BF_POWERS
+      32             : /*
+      33             : Polynomial power basis functions.
+      34             : 
+      35             : \attention
+      36             : __These basis functions should not be used in conventional biasing simulations__.
+      37             : Instead you should use orthogonal basis functions like Legendre or
+      38             : Chebyshev polynomials. They are only included for usage in \ref ves_md_linearexpansion
+      39             : and some special cases.
+      40             : 
+      41             : Basis functions given by polynomial powers defined on a bounded interval.
+      42             : You need to provide the interval \f$[a,b]\f$
+      43             : on which the basis functions are to be used, and the order of the
+      44             : expansion \f$N\f$ (i.e. the highest power used).
+      45             : The total number of basis functions is \f$N+1\f$ as the constant \f$f_{0}(x)=1\f$
+      46             : is also included.
+      47             : These basis functions should not be used for periodic CVs.
+      48             : 
+      49             : The basis functions are given by
+      50             : \f{align}{
+      51             : f_{0}(x)    &= 1 \\
+      52             : f_{1}(x)    &= x \\
+      53             : f_{2}(x)    &= x^2 \\
+      54             : & \vdots \\
+      55             : f_{n}(x)    &= x^n \\
+      56             : & \vdots \\
+      57             : f_{N}(x)    &= x^N \\
+      58             : \f}
+      59             : 
+      60             : Note that these basis functions are __not__ orthogonal. In fact the integral
+      61             : over the uniform target distribution blows up as the interval is increased.
+      62             : Therefore they should not be used in conventional biasing simulations.
+      63             : However, they can be useful for usage with \ref ves_md_linearexpansion.
+      64             : 
+      65             : \par Examples
+      66             : 
+      67             : Here we employ a polynomial power expansion of order 5
+      68             : over the interval -2.0 to 2.0.
+      69             : This results in a total number of 6 basis functions.
+      70             : The label used to identify  the basis function action can then be
+      71             : referenced later on in the input file.
+      72             : \plumedfile
+      73             : BF_POWERS MINIMUM=-2.0 MAXIMUM=2.0 ORDER=5 LABEL=bf_pow
+      74             : \endplumedfile
+      75             : 
+      76             : 
+      77             : */
+      78             : //+ENDPLUMEDOC
+      79             : 
+      80             : class BF_Powers : public BasisFunctions {
+      81             :   double inv_normfactor_;
+      82             :   void setupLabels() override;
+      83             : public:
+      84             :   static void registerKeywords( Keywords&);
+      85             :   explicit BF_Powers(const ActionOptions&);
+      86             :   void getAllValues(const double, double&, bool&, std::vector<double>&, std::vector<double>&) const override;
+      87             : };
+      88             : 
+      89             : 
+      90             : PLUMED_REGISTER_ACTION(BF_Powers,"BF_POWERS")
+      91             : 
+      92             : 
+      93          18 : void BF_Powers::registerKeywords(Keywords& keys) {
+      94          18 :   BasisFunctions::registerKeywords(keys);
+      95          36 :   keys.add("optional","NORMALIZATION","The normalization factor that is used to normalize the basis functions. By default it is 1.0.");
+      96          18 :   keys.remove("NUMERICAL_INTEGRALS");
+      97          18 : }
+      98             : 
+      99          16 : BF_Powers::BF_Powers(const ActionOptions&ao):
+     100          16 :   PLUMED_VES_BASISFUNCTIONS_INIT(ao)
+     101             : {
+     102          16 :   setNumberOfBasisFunctions(getOrder()+1);
+     103          16 :   setIntrinsicInterval(intervalMin(),intervalMax());
+     104          16 :   double normfactor_=1.0;
+     105          16 :   parse("NORMALIZATION",normfactor_);
+     106          16 :   if(normfactor_!=1.0) {addKeywordToList("NORMALIZATION",normfactor_);}
+     107          16 :   inv_normfactor_=1.0/normfactor_;
+     108             :   setNonPeriodic();
+     109             :   setIntervalBounded();
+     110          16 :   setType("polynom_powers");
+     111          16 :   setDescription("Polynomial Powers");
+     112          16 :   setupBF();
+     113          16 :   log.printf("   normalization factor: %f\n",normfactor_);
+     114          16 :   checkRead();
+     115          16 : }
+     116             : 
+     117             : 
+     118      842119 : void BF_Powers::getAllValues(const double arg, double& argT, bool& inside_range, std::vector<double>& values, std::vector<double>& derivs) const {
+     119      842119 :   inside_range=true;
+     120      842119 :   argT=checkIfArgumentInsideInterval(arg,inside_range);
+     121             :   //
+     122      842119 :   values[0]=1.0;
+     123      842119 :   derivs[0]=0.0;
+     124             :   //
+     125     4210595 :   for(unsigned int i=1; i < getNumberOfBasisFunctions(); i++) {
+     126             :     // double io = static_cast<double>(i);
+     127             :     // values[i] = pow(argT,io);
+     128             :     // derivs[i] = io*pow(argT,io-1.0);
+     129     3368476 :     values[i] = argT*values[i-1];
+     130     3368476 :     derivs[i]=values[i-1]+argT*derivs[i-1];
+     131             :   }
+     132      842599 :   if(!inside_range) {for(unsigned int i=0; i<derivs.size(); i++) {derivs[i]=0.0;}}
+     133      842119 : }
+     134             : 
+     135             : 
+     136          16 : void BF_Powers::setupLabels() {
+     137          16 :   setLabel(0,"1");
+     138          80 :   for(unsigned int i=1; i < getOrder()+1; i++) {
+     139          64 :     std::string is; Tools::convert(i,is);
+     140         128 :     setLabel(i,"s^"+is);
+     141             :   }
+     142          16 : }
+     143             : 
+     144             : }
+     145             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Sine.cpp.func-sort-c.html b/coverage/ves/BF_Sine.cpp.func-sort-c.html new file mode 100644 index 000000000000..d366853f96f9 --- /dev/null +++ b/coverage/ves/BF_Sine.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - ves/BF_Sine.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BF_Sine.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3535100.0 %
Date:2024-04-19 12:12:35Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves7BF_Sine21setupUniformIntegralsEv3
_ZN4PLMD3ves7BF_Sine11setupLabelsEv4
_ZN4PLMD3ves7BF_SineC2ERKNS_13ActionOptionsE4
_ZN4PLMD3ves7BF_Sine16registerKeywordsERNS_8KeywordsE6
_ZNK4PLMD3ves7BF_Sine12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_9229
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Sine.cpp.func.html b/coverage/ves/BF_Sine.cpp.func.html new file mode 100644 index 000000000000..a01ae17758cd --- /dev/null +++ b/coverage/ves/BF_Sine.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - ves/BF_Sine.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BF_Sine.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3535100.0 %
Date:2024-04-19 12:12:35Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves7BF_Sine11setupLabelsEv4
_ZN4PLMD3ves7BF_Sine16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD3ves7BF_Sine21setupUniformIntegralsEv3
_ZN4PLMD3ves7BF_SineC2ERKNS_13ActionOptionsE4
_ZNK4PLMD3ves7BF_Sine12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_9229
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Sine.cpp.gcov.html b/coverage/ves/BF_Sine.cpp.gcov.html new file mode 100644 index 000000000000..c908781b565a --- /dev/null +++ b/coverage/ves/BF_Sine.cpp.gcov.html @@ -0,0 +1,228 @@ + + + + + + + + LCOV - plumed test coverage - ves/BF_Sine.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BF_Sine.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3535100.0 %
Date:2024-04-19 12:12:35Functions:55100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "BasisFunctions.h"
+      24             : 
+      25             : #include "core/ActionRegister.h"
+      26             : 
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace ves {
+      30             : 
+      31             : //+PLUMEDOC VES_BASISF BF_SINE
+      32             : /*
+      33             : Fourier sine basis functions.
+      34             : 
+      35             : Use as basis functions Fourier sine series defined on a periodic interval.
+      36             : You need to provide the periodic interval \f$[a,b]\f$
+      37             : on which the basis functions are to be used, and the order of the
+      38             : expansion \f$N\f$ (i.e. the highest Fourier sine mode used).
+      39             : The total number of basis functions is \f$N+1\f$ as
+      40             : the constant \f$f_{0}(x)=1\f$ is also included.
+      41             : These basis functions should only be used for periodic CVs.
+      42             : They can be useful if the periodic function being expanded is an
+      43             : odd function, i.e. \f$F(-x)=-F(x)\f$.
+      44             : 
+      45             : The Fourier sine basis functions are given by
+      46             : \f{align}{
+      47             : f_{0}(x)    &= 1 \\
+      48             : f_{1}(x)    &= sin(\frac{2\pi }{P} x) \\
+      49             : f_{2}(x)    &= sin(2 \cdot \frac{2\pi}{P} x) \\
+      50             : f_{3}(x)    &= sin(3 \cdot \frac{2\pi}{P} x) \\
+      51             : & \vdots \\
+      52             : f_{n}(x) &= sin(n \cdot \frac{2\pi}{P} x) \\
+      53             : & \vdots \\
+      54             : f_{N}(x)   &= sin(N \cdot \frac{2\pi}{P} x) \\
+      55             : \f}
+      56             : where \f$P=(b-a)\f$ is the periodicity of the interval.
+      57             : They are orthogonal over the interval \f$[a,b]\f$
+      58             : \f[
+      59             : \int_{a}^{b} dx \, f_{n}(x)\, f_{m}(x)  =
+      60             : \begin{cases}
+      61             : 0 & n \neq m \\
+      62             : (b-a) & n = m = 0 \\
+      63             : (b-a)/2 & n = m \neq 0
+      64             : \end{cases}.
+      65             : \f]
+      66             : 
+      67             : \par Examples
+      68             : 
+      69             : Here we employ a Fourier sine expansion of order 10 over the periodic interval
+      70             : \f$-\pi\f$ to \f$+\pi\f$.
+      71             : This results in a total number of 11 basis functions.
+      72             : The label used to identify  the basis function action can then be
+      73             : referenced later on in the input file.
+      74             : \plumedfile
+      75             : BF_SINE MINIMUM=-pi MAXIMUM=+pi ORDER=10 LABEL=bfS
+      76             : \endplumedfile
+      77             : 
+      78             : \par Examples
+      79             : 
+      80             : */
+      81             : //+ENDPLUMEDOC
+      82             : 
+      83             : class BF_Sine : public BasisFunctions {
+      84             :   void setupLabels() override;
+      85             :   void setupUniformIntegrals() override;
+      86             : public:
+      87             :   static void registerKeywords(Keywords&);
+      88             :   explicit BF_Sine(const ActionOptions&);
+      89             :   void getAllValues(const double, double&, bool&, std::vector<double>&, std::vector<double>&) const override;
+      90             : };
+      91             : 
+      92             : 
+      93             : PLUMED_REGISTER_ACTION(BF_Sine,"BF_SINE")
+      94             : 
+      95             : 
+      96           6 : void BF_Sine::registerKeywords(Keywords& keys) {
+      97           6 :   BasisFunctions::registerKeywords(keys);
+      98           6 : }
+      99             : 
+     100             : 
+     101           4 : BF_Sine::BF_Sine(const ActionOptions&ao):
+     102           4 :   PLUMED_VES_BASISFUNCTIONS_INIT(ao)
+     103             : {
+     104           4 :   setNumberOfBasisFunctions(getOrder()+1);
+     105           8 :   setIntrinsicInterval("-pi","+pi");
+     106             :   setPeriodic();
+     107             :   setIntervalBounded();
+     108           4 :   setType("trigonometric_sin");
+     109           4 :   setDescription("Sine");
+     110           4 :   setupBF();
+     111           4 :   checkRead();
+     112           4 : }
+     113             : 
+     114             : 
+     115        9229 : void BF_Sine::getAllValues(const double arg, double& argT, bool& inside_range, std::vector<double>& values, std::vector<double>& derivs) const {
+     116             :   // plumed_assert(values.size()==numberOfBasisFunctions());
+     117             :   // plumed_assert(derivs.size()==numberOfBasisFunctions());
+     118        9229 :   inside_range=true;
+     119        9229 :   argT=translateArgument(arg, inside_range);
+     120        9229 :   values[0]=1.0;
+     121        9229 :   derivs[0]=0.0;
+     122      101519 :   for(unsigned int i=1; i < getOrder()+1; i++) {
+     123       92290 :     double io = i;
+     124       92290 :     double cos_tmp = cos(io*argT);
+     125       92290 :     double sin_tmp = sin(io*argT);
+     126       92290 :     values[i] = sin_tmp;
+     127       92290 :     derivs[i] = io*cos_tmp*intervalDerivf();
+     128             :   }
+     129        9229 :   if(!inside_range) {
+     130         960 :     for(unsigned int i=0; i<derivs.size(); i++) {derivs[i]=0.0;}
+     131             :   }
+     132        9229 : }
+     133             : 
+     134             : 
+     135           4 : void BF_Sine::setupLabels() {
+     136           4 :   setLabel(0,"1");
+     137          44 :   for(unsigned int i=1; i < getOrder()+1; i++) {
+     138          40 :     std::string is; Tools::convert(i,is);
+     139          80 :     setLabel(i,"sin("+is+"*s)");
+     140             :   }
+     141           4 : }
+     142             : 
+     143             : 
+     144           3 : void BF_Sine::setupUniformIntegrals() {
+     145           3 :   setAllUniformIntegralsToZero();
+     146             :   setUniformIntegral(0,1.0);
+     147           3 : }
+     148             : 
+     149             : 
+     150             : }
+     151             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Wavelets.cpp.func-sort-c.html b/coverage/ves/BF_Wavelets.cpp.func-sort-c.html new file mode 100644 index 000000000000..d0d2f872b04b --- /dev/null +++ b/coverage/ves/BF_Wavelets.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - ves/BF_Wavelets.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BF_Wavelets.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:118118100.0 %
Date:2024-04-19 12:12:35Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves11BF_Wavelets15getCutoffPointsERKd2
_ZN4PLMD3ves11BF_Wavelets11setupLabelsEv47
_ZN4PLMD3ves11BF_WaveletsC2ERKNS_13ActionOptionsE47
_ZN4PLMD3ves11BF_Wavelets16registerKeywordsERNS_8KeywordsE49
_ZNK4PLMD3ves11BF_Wavelets12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_62249
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Wavelets.cpp.func.html b/coverage/ves/BF_Wavelets.cpp.func.html new file mode 100644 index 000000000000..b53e3828b5e3 --- /dev/null +++ b/coverage/ves/BF_Wavelets.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - ves/BF_Wavelets.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BF_Wavelets.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:118118100.0 %
Date:2024-04-19 12:12:35Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves11BF_Wavelets11setupLabelsEv47
_ZN4PLMD3ves11BF_Wavelets15getCutoffPointsERKd2
_ZN4PLMD3ves11BF_Wavelets16registerKeywordsERNS_8KeywordsE49
_ZN4PLMD3ves11BF_WaveletsC2ERKNS_13ActionOptionsE47
_ZNK4PLMD3ves11BF_Wavelets12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_62249
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Wavelets.cpp.gcov.html b/coverage/ves/BF_Wavelets.cpp.gcov.html new file mode 100644 index 000000000000..12d3db6ec240 --- /dev/null +++ b/coverage/ves/BF_Wavelets.cpp.gcov.html @@ -0,0 +1,495 @@ + + + + + + + + LCOV - plumed test coverage - ves/BF_Wavelets.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BF_Wavelets.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:118118100.0 %
Date:2024-04-19 12:12:35Functions:55100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : 
+      24             : #include "BasisFunctions.h"
+      25             : #include "GridLinearInterpolation.h"
+      26             : #include "tools/Grid.h"
+      27             : #include "VesTools.h"
+      28             : #include "WaveletGrid.h"
+      29             : #include "core/ActionRegister.h"
+      30             : #include "tools/Exception.h"
+      31             : #include "core/PlumedMain.h"
+      32             : 
+      33             : 
+      34             : namespace PLMD {
+      35             : namespace ves {
+      36             : 
+      37             : 
+      38             : //+PLUMEDOC VES_BASISF BF_WAVELETS
+      39             : /*
+      40             : Daubechies Wavelets basis functions.
+      41             : 
+      42             : Note: at the moment only bases with a single level of scaling functions are usable, as multiscale optimization is not yet implemented.
+      43             : 
+      44             : This basis set uses Daubechies Wavelets \cite daubechies_ten_1992 to construct a complete and orthogonal basis. See \cite ValssonPampel_Wavelets_2022 for full details.
+      45             : 
+      46             : The basis set is based on using a pair of functions, the scaling function (or father wavelet) \f$\phi\f$ and the wavelet function (or mother wavelet) \f$\psi\f$.
+      47             : They are defined via the two-scale relations for scale \f$j\f$ and shift \f$k\f$:
+      48             : 
+      49             : \f{align*}{
+      50             :   \phi_k^j \left(x\right) = 2^{-j/2} \phi \left( 2^{-j} x - k\right)\\
+      51             :   \psi_k^j \left(x\right) = 2^{-j/2} \psi \left( 2^{-j} x - k\right)
+      52             : \f}
+      53             : 
+      54             : The exact properties are set by choosing filter coefficients, e.g. choosing \f$h_k\f$ for the father wavelet:
+      55             : 
+      56             : \f[
+      57             :   \phi\left(x\right) = \sqrt{2} \sum_k h_k\, \phi \left( 2 x - k\right)
+      58             : \f]
+      59             : 
+      60             : The filter coefficients by Daubechies result in an orthonormal basis of all integer shifted functions:
+      61             : \f[
+      62             :   \int \phi(x+i) \phi(x+j) \mathop{}\!\mathrm{d}x = \delta_{ij} \quad \text{for} \quad i,j \in \mathbb{Z}
+      63             : \f]
+      64             : 
+      65             : Because no analytic formula for these wavelets exist, they are instead constructed iteratively on a grid.
+      66             : The method of construction is close to the "Vector cascade algorithm" described in \cite strang_wavelets_1997 .
+      67             : The needed filter coefficients of the scaling function are hardcoded, and were previously generated via a python script.
+      68             : Currently the "maximum phase" type (Db) and the "least asymmetric" (Sym) type are implemented.
+      69             : We recommend to use Symlets.
+      70             : 
+      71             : As an example two adjacent basis functions of both Sym8 (ORDER=8, TYPE=SYMLET) and Db8 (ORDER=8, TYPE=DAUBECHIES) is shown in the figure.
+      72             : The full basis consists of shifted wavelets in the full specified interval.
+      73             : 
+      74             : \image html ves_basisf-wavelets.png
+      75             : 
+      76             : 
+      77             : \par Specify the wavelet type
+      78             : 
+      79             : The TYPE keyword sets the type of Wavelet, at the moment "DAUBECHIES" and "SYMLETS" are available.
+      80             : The specified ORDER of the basis corresponds to the number of vanishing moments of the wavelet, i.e. if TYPE was specified as "DAUBECHIES" an order of 8 results in Db8 wavelets.
+      81             : 
+      82             : 
+      83             : \par Specify the number of functions
+      84             : 
+      85             : The resulting basis set consists of integer shifts of the wavelet with some scaling \f$j\f$,
+      86             : \f[
+      87             :   V(x) = \sum_i \alpha_i * \phi_i (x) = \sum_i \alpha_i * \phi(\frac{x+i}{j})
+      88             : \f]
+      89             : with the variational parameters \f$ \alpha \f$.
+      90             : Additionally a constant basis function is included.
+      91             : 
+      92             : There are two different ways to specify the number of used basis functions implemented.
+      93             : You can either specify the scale or alternatively a fixed number of basis function.
+      94             : 
+      95             : Coming from the multiresolution aspect of wavelets, you can set the scale of the father wavelets, i.e. the largest scale used for approximation.
+      96             : This can be done with the FUNCTION_LENGTH keyword.
+      97             : It should be given in the same units as the used CV and specifies the length (of the domain interval) of the individual father wavelet functions.
+      98             : 
+      99             : Alternatively a fixed number of basis functions for the bias expansion can be specified with the NUM_BF keyword, which will set the scale automatically to match the desired number of functions.
+     100             : Note that this also includes the constant function.
+     101             : 
+     102             : If you do not specify anything, it is assumed that the range of the bias should match the scale of the wavelet functions.
+     103             : More precise, the basis functions are scaled to match the specified size of the CV space (MINIMUM and MAXIMUM keywords).
+     104             : This has so far been a good initial choice.
+     105             : 
+     106             : If the wavelets are scaled to match the CV range exactly there would be \f$4*\text{ORDER} -3\f$ basis functions whose domain is at least partially in this region.
+     107             : This number is adjusted if FUNCTION_LENGTH or NUM_BF is specified.
+     108             : Additionally, some of the shifted basis functions will not have significant contributions because of their function values being close to zero over the full range of the bias.
+     109             : These 'tail wavelets' can be omitted by using the TAILS_THRESHOLD keyword.
+     110             : This omits all shifted functions that have only function values smaller than a fraction of their maximum value inside the bias range.
+     111             : Using a value of e.g. 0.01 will already reduce the number of basis functions significantly.
+     112             : The default setting will not omit any tail wavelets (i.e. TAILS_THRESHOLD=0).
+     113             : 
+     114             : The number of basis functions is then not easily determinable a priori but will be given in the logfile.
+     115             : Additionally the starting point (leftmost defined point) of the individual basis functions is printed.
+     116             : 
+     117             : 
+     118             : With the PERIODIC keyword the basis set can also be used to bias periodic CVs.
+     119             : Then the shift between the functions will be chosen such that the function at the left border and right border coincide.
+     120             : If the FUNCTION_LENGTH keyword is used together with PERIODIC, a smaller length might be chosen to satisfy this requirement.
+     121             : 
+     122             : 
+     123             : \par Grid
+     124             : 
+     125             : The values of the wavelet function are generated on a grid.
+     126             : Using the cascade algorithm results in doubling the grid values for each iteration.
+     127             : This means that the grid size will always be a power of two multiplied by the number of coefficients (\f$ 2*\text{ORDER} -1\f$) for the specified wavelet.
+     128             : Using the MIN_GRID_SIZE keyword a lower bound for the number of grid points can be specified.
+     129             : By default at least 1,000 grid points are used.
+     130             : Function values in between grid points are calculated by linear interpolation.
+     131             : 
+     132             : \par Optimization notes
+     133             : 
+     134             : To avoid 'blind' optimization of the basis functions outside the currently sampled area, it is often beneficial to use the OPTIMIZATION_THRESHOLD keyword of the \ref VES_LINEAR_EXPANSION (set it to a small value, e.g. 1e-6)
+     135             : 
+     136             : \par Examples
+     137             : 
+     138             : 
+     139             : First a very simple example that relies on the default values.
+     140             : We want to bias some CV in the range of 0 to 4.
+     141             : The wavelets will therefore be scaled to match that range.
+     142             : Using Db8 wavelets this results in 30 basis functions (including the constant one), with their starting points given by \f$ -14*\frac{4}{15}, -13*\frac{4}{15}, \cdots , 0 , \cdots, 13*\frac{4}{15}, 14*\frac{4}{15} \f$.
+     143             : \plumedfile
+     144             : BF_WAVELETS ...
+     145             :  ORDER=8
+     146             :  TYPE=DAUBECHIES
+     147             :  MINIMUM=0.0
+     148             :  MAXIMUM=4.0
+     149             :  LABEL=bf
+     150             : ... BF_WAVELETS
+     151             : \endplumedfile
+     152             : 
+     153             : 
+     154             : By omitting wavelets with only insignificant parts, we can reduce the number of basis functions. Using a threshold of 0.01 will in this example remove the 8 leftmost shifts, which we can check in the logfile.
+     155             : \plumedfile
+     156             : BF_WAVELETS ...
+     157             :  ORDER=8
+     158             :  TYPE=DAUBECHIES
+     159             :  MINIMUM=0.0
+     160             :  MAXIMUM=4.0
+     161             :  TAILS_THRESHOLD=0.01
+     162             :  LABEL=bf
+     163             : ... BF_WAVELETS
+     164             : \endplumedfile
+     165             : 
+     166             : 
+     167             : The length of the individual basis functions can also be adjusted to fit the specific problem.
+     168             : If for example the wavelets are instead scaled to length 3, there will be 35 basis functions, with leftmost points at \f$ -14*\frac{3}{15}, -13*\frac{3}{15}, \cdots, 0, \cdots, 18*\frac{3}{15}, 19*\frac{3}{15} \f$.
+     169             : \plumedfile
+     170             : BF_WAVELETS ...
+     171             :  ORDER=8
+     172             :  TYPE=DAUBECHIES
+     173             :  MINIMUM=0.0
+     174             :  MAXIMUM=4.0
+     175             :  FUNCTION_LENGTH=3
+     176             :  LABEL=bf
+     177             : ... BF_WAVELETS
+     178             : \endplumedfile
+     179             : 
+     180             : 
+     181             : Alternatively you can also specify the number of basis functions. Here we specify the usage of 40 Sym10 wavelet functions. We also used a custom minimum size for the grid and want it to be printed to a file with a specific numerical format.
+     182             : \plumedfile
+     183             : BF_WAVELETS ...
+     184             :  ORDER=10
+     185             :  TYPE=SYMLETS
+     186             :  MINIMUM=0.0
+     187             :  MAXIMUM=4.0
+     188             :  NUM_BF=40
+     189             :  MIN_GRID_SIZE=500
+     190             :  DUMP_WAVELET_GRID
+     191             :  WAVELET_FILE_FMT=%11.4f
+     192             :  LABEL=bf
+     193             : ... BF_WAVELETS
+     194             : \endplumedfile
+     195             : 
+     196             : */
+     197             : //+ENDPLUMEDOC
+     198             : 
+     199             : 
+     200             : class BF_Wavelets : public BasisFunctions {
+     201             : private:
+     202             :   void setupLabels() override;
+     203             :   /// ptr to Grid that holds the Wavelet values and its derivative
+     204             :   std::unique_ptr<Grid> waveletGrid_;
+     205             :   /// calculate threshold for omitted tail wavelets
+     206             :   std::vector<double> getCutoffPoints(const double& threshold);
+     207             :   /// scale factor of the individual BFs to match specified length
+     208             :   double scale_;
+     209             :   /// shift of the individual BFs
+     210             :   std::vector<double> shifts_;
+     211             : public:
+     212             :   static void registerKeywords( Keywords&);
+     213             :   explicit BF_Wavelets(const ActionOptions&);
+     214             :   void getAllValues(const double, double&, bool&, std::vector<double>&, std::vector<double>&) const override;
+     215             : };
+     216             : 
+     217             : 
+     218             : PLUMED_REGISTER_ACTION(BF_Wavelets,"BF_WAVELETS")
+     219             : 
+     220             : 
+     221          49 : void BF_Wavelets::registerKeywords(Keywords& keys) {
+     222          49 :   BasisFunctions::registerKeywords(keys);
+     223          98 :   keys.add("compulsory","TYPE","Specify the wavelet type. Currently available are DAUBECHIES Wavelets with minimum phase and the more symmetric SYMLETS");
+     224          98 :   keys.add("optional","FUNCTION_LENGTH","The domain size of the individual basis functions. (length) This is used to alter the scaling of the basis functions. By default it is set to the total size of the interval. This also influences the number of actually used basis functions, as all shifted functions that are partially supported in the CV space are used.");
+     225          98 :   keys.add("optional","NUM_BF","The number of basis functions that should be used. Includes the constant one and N-1 shifted wavelets within the specified range. Cannot be used together with FUNCTION_LENGTH.");
+     226          98 :   keys.add("optional","TAILS_THRESHOLD","The threshold for cutting off tail wavelets as a fraction of the maximum value. All shifted wavelet functions that only have values smaller than the threshold in the bias range will be excluded from the basis set. Defaults to 0 (include all).");
+     227          98 :   keys.addFlag("MOTHER_WAVELET", false, "If this flag is set mother wavelets will be used instead of the scaling function (father wavelet). Makes only sense for multiresolution, which is at the moment not usable.");
+     228          98 :   keys.add("optional","MIN_GRID_SIZE","The minimal number of grid bins of the Wavelet function. The true number depends also on the used wavelet type and will probably be larger. Defaults to 1000.");
+     229          98 :   keys.addFlag("DUMP_WAVELET_GRID", false, "If this flag is set the grid with the wavelet values will be written to a file.  This file is called wavelet_grid.data.");
+     230          98 :   keys.add("optional","WAVELET_FILE_FMT","The number format of the wavelet grid values and derivatives written to file. By default it is %15.8f.\n");
+     231          98 :   keys.addFlag("PERIODIC", false, "Use periodic version of basis set.");
+     232          49 :   keys.remove("NUMERICAL_INTEGRALS");
+     233          49 : }
+     234             : 
+     235             : 
+     236          47 : BF_Wavelets::BF_Wavelets(const ActionOptions& ao):
+     237             :   PLUMED_VES_BASISFUNCTIONS_INIT(ao),
+     238          47 :   waveletGrid_(nullptr),
+     239          47 :   scale_(0.0)
+     240             : {
+     241          47 :   log.printf("  Wavelet basis functions, see and cite ");
+     242          94 :   log << plumed.cite("Pampel and Valsson, J. Chem. Theory Comput. 18, 4127-4141 (2022) - DOI:10.1021/acs.jctc.2c00197");
+     243             : 
+     244             :   // parse properties for waveletGrid and set it up
+     245             :   bool use_mother_wavelet;
+     246          94 :   parseFlag("MOTHER_WAVELET", use_mother_wavelet);
+     247             : 
+     248             :   std::string wavelet_type_str;
+     249          47 :   parse("TYPE", wavelet_type_str);
+     250          94 :   addKeywordToList("TYPE", wavelet_type_str);
+     251             : 
+     252          47 :   unsigned min_grid_size = 1000;
+     253          47 :   parse("MIN_GRID_SIZE", min_grid_size);
+     254          83 :   if(min_grid_size != 1000) {addKeywordToList("MIN_GRID_SIZE",min_grid_size);}
+     255             : 
+     256          94 :   waveletGrid_ = WaveletGrid::setupGrid(getOrder(), min_grid_size, use_mother_wavelet, WaveletGrid::stringToType(wavelet_type_str));
+     257          47 :   bool dump_wavelet_grid=false;
+     258          47 :   parseFlag("DUMP_WAVELET_GRID", dump_wavelet_grid);
+     259          47 :   if (dump_wavelet_grid) {
+     260          36 :     OFile wavelet_gridfile;
+     261          36 :     std::string fmt = "%13.6f";
+     262          72 :     parse("WAVELET_FILE_FMT",fmt);
+     263             :     waveletGrid_->setOutputFmt(fmt); // property of grid not OFile determines fmt
+     264          36 :     wavelet_gridfile.link(*this);
+     265          36 :     wavelet_gridfile.enforceBackup();
+     266          72 :     wavelet_gridfile.open(getLabel()+".wavelet_grid.data");
+     267          36 :     waveletGrid_->writeToFile(wavelet_gridfile);
+     268          36 :   }
+     269             : 
+     270          47 :   bool periodic = false;
+     271          47 :   parseFlag("PERIODIC",periodic);
+     272          51 :   if (periodic) {addKeywordToList("PERIODIC",periodic);}
+     273             : 
+     274             :   // now set up properties of basis set
+     275          47 :   unsigned intrinsic_length = 2*getOrder() - 1; // length of unscaled wavelet
+     276          47 :   double bias_length = intervalMax() - intervalMin(); // intervalRange() is not yet set
+     277             : 
+     278             :   // parse threshold for tail wavelets and get respective cutoff points
+     279          47 :   double threshold = 0.0;
+     280          47 :   std::vector<double> cutoffpoints (2);
+     281          47 :   parse("TAILS_THRESHOLD",threshold);
+     282          47 :   plumed_massert(threshold < 1, "TAILS_THRESHOLD should be significantly smaller than 1.");
+     283          47 :   if(threshold == 0.0) {
+     284          45 :     cutoffpoints = {0.0, static_cast<double>(intrinsic_length)};
+     285             :   }
+     286             :   else {
+     287           2 :     plumed_massert(!periodic, "TAILS_THRESHOLD can't be used with the periodic wavelet variant");
+     288           2 :     addKeywordToList("TAILS_THRESHOLD",threshold);
+     289           4 :     cutoffpoints = getCutoffPoints(threshold);
+     290             :   };
+     291             : 
+     292          47 :   double function_length = bias_length;
+     293          47 :   parse("FUNCTION_LENGTH",function_length);
+     294          47 :   if(function_length != bias_length) {
+     295           4 :     if (periodic) {  // shifted functions need to fit into interval exactly -> reduce size if not
+     296           2 :       unsigned num_shifts = ceil(bias_length * intrinsic_length / function_length);
+     297           2 :       function_length = bias_length * intrinsic_length / num_shifts;
+     298             :     }
+     299           8 :     addKeywordToList("FUNCTION_LENGTH",function_length);
+     300             :   }
+     301             : 
+     302             :   // determine number of BFs and needed scaling
+     303          47 :   unsigned num_BFs = 0;
+     304          47 :   parse("NUM_BF",num_BFs);
+     305          47 :   if(num_BFs == 0) { // get from function length
+     306          43 :     scale_ = intrinsic_length / function_length;
+     307          43 :     if (periodic) {
+     308             :       // this is the same value as num_shifts above + constant
+     309           2 :       num_BFs = static_cast<unsigned>(bias_length * scale_) + 1;
+     310             :     }
+     311             :     else {
+     312          41 :       num_BFs = 1; // constant one
+     313             :       // left shifts (w/o left cutoff) + right shifts - right cutoff - 1
+     314          41 :       num_BFs += static_cast<unsigned>(ceil(cutoffpoints[1] + (bias_length)*scale_ - cutoffpoints[0]) - 1);
+     315             :     }
+     316             :   }
+     317             :   else {
+     318             :     plumed_massert(num_BFs > 0, "The number of basis functions has to be positive (NUM_BF > 0)");
+     319             :     // check does not work if function length was given as intrinsic length, but can't check for keyword use directly
+     320           4 :     plumed_massert(function_length==bias_length,"The keywords \"NUM_BF\" and \"FUNCTION_LENGTH\" cannot be used at the same time");
+     321           4 :     addKeywordToList("NUM_BF",num_BFs);
+     322             : 
+     323           4 :     if (periodic) {  // inverted num_BFs calculation from where FUNCTION_LENGTH is specified
+     324           2 :       scale_ = (num_BFs  - 1) / bias_length ;
+     325             :     }
+     326             :     else {
+     327           2 :       double cutoff_length = cutoffpoints[1] - cutoffpoints [0];
+     328           2 :       double intrinsic_bias_length = num_BFs - cutoff_length + 1; // length of bias in intrinsic scale of wavelets
+     329           2 :       scale_ = intrinsic_bias_length / bias_length;
+     330             :     }
+     331             :   }
+     332             : 
+     333          47 :   setNumberOfBasisFunctions(num_BFs);
+     334             : 
+     335             :   // now set up the starting points of the basis functions
+     336          47 :   shifts_.push_back(0.0); // constant BF – never used, just for clearer notation
+     337        1908 :   for(unsigned int i = 1; i < getNumberOfBasisFunctions(); ++i) {
+     338        1861 :     shifts_.push_back(-intervalMin()*scale_ + cutoffpoints[1] - i);
+     339             :   }
+     340             : 
+     341             :   // set some properties
+     342          47 :   setIntrinsicInterval(0.0,intrinsic_length);
+     343          47 :   periodic ? setPeriodic() : setNonPeriodic();
+     344             :   setIntervalBounded();
+     345             :   setType(wavelet_type_str);
+     346          47 :   setDescription("Wavelets as localized basis functions");
+     347          47 :   setupBF();
+     348          47 :   checkRead();
+     349             : 
+     350          47 :   log.printf("  Each basisfunction spans %f in CV space\n", intrinsic_length/scale_);
+     351          47 : }
+     352             : 
+     353             : 
+     354       62249 : void BF_Wavelets::getAllValues(const double arg, double& argT, bool& inside_range, std::vector<double>& values, std::vector<double>& derivs) const {
+     355       62249 :   argT=checkIfArgumentInsideInterval(arg,inside_range);
+     356             :   //
+     357       62249 :   values[0]=1.0;
+     358       62249 :   derivs[0]=0.0;
+     359     2315762 :   for(unsigned int i = 1; i < getNumberOfBasisFunctions(); ++i) {
+     360             :     // scale and shift argument to match current wavelet
+     361     2253513 :     double x = shifts_[i] + argT*scale_;
+     362     2253513 :     if (arePeriodic()) { // periodic interval [0,intervalRange*scale]
+     363      171766 :       x = x - floor(x/(intervalRange()*scale_))*intervalRange()*scale_;
+     364             :     }
+     365             : 
+     366     2253513 :     if (x < 0 || x >= intrinsicIntervalMax()) { // Wavelets are 0 outside the defined range
+     367      989659 :       values[i] = 0.0; derivs[i] = 0.0;
+     368             :     }
+     369             :     else {
+     370     1263854 :       std::vector<double> temp_deriv (1);
+     371     1263854 :       values[i] = GridLinearInterpolation::getGridValueAndDerivativesWithLinearInterpolation(waveletGrid_.get(), {x}, temp_deriv);
+     372     1263854 :       derivs[i] = temp_deriv[0] * scale_; // scale derivative
+     373             :     }
+     374             :   }
+     375       67885 :   if(!inside_range) {for(auto& deriv : derivs) {deriv=0.0;}}
+     376       62249 : }
+     377             : 
+     378             : 
+     379             : // returns left and right cutoff point of Wavelet
+     380             : // threshold is a percent value of maximum
+     381           2 : std::vector<double> BF_Wavelets::getCutoffPoints(const double& threshold) {
+     382           2 :   double threshold_value = threshold * waveletGrid_->getMaxValue();
+     383             :   std::vector<double> cutoffpoints;
+     384             : 
+     385         475 :   for (size_t i = 0; i < waveletGrid_->getSize(); ++i) {
+     386         475 :     if (fabs(waveletGrid_->getValue(i)) >= threshold_value) {
+     387           2 :       cutoffpoints.push_back(waveletGrid_->getPoint(i)[0]);
+     388           2 :       break;
+     389             :     }
+     390             :   }
+     391             : 
+     392        1073 :   for (int i = waveletGrid_->getSize() - 1; i >= 0; --i) {
+     393        1073 :     if (fabs(waveletGrid_->getValue(i)) >= threshold_value) {
+     394           2 :       cutoffpoints.push_back(waveletGrid_->getPoint(i)[0]);
+     395           2 :       break;
+     396             :     }
+     397             :   }
+     398             : 
+     399           2 :   return cutoffpoints;
+     400             : }
+     401             : 
+     402             : 
+     403             : // labels according to minimum position in CV space
+     404          47 : void BF_Wavelets::setupLabels() {
+     405          47 :   setLabel(0,"const");
+     406        1908 :   for(unsigned int i=1; i < getNumberOfBasisFunctions(); i++) {
+     407        1861 :     double pos = -shifts_[i]/scale_;
+     408        1861 :     if (arePeriodic()) {
+     409          88 :       pos = pos - floor((pos-intervalMin())/intervalRange())*intervalRange();
+     410             :     }
+     411        1861 :     std::string is; Tools::convert(pos, is);
+     412        3722 :     setLabel(i,"i="+is);
+     413             :   }
+     414          47 : }
+     415             : 
+     416             : 
+     417             : }
+     418             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BasisFunctions.cpp.func-sort-c.html b/coverage/ves/BasisFunctions.cpp.func-sort-c.html new file mode 100644 index 000000000000..e0642b06da84 --- /dev/null +++ b/coverage/ves/BasisFunctions.cpp.func-sort-c.html @@ -0,0 +1,157 @@ + + + + + + + + LCOV - plumed test coverage - ves/BasisFunctions.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BasisFunctions.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22225387.7 %
Date:2024-04-19 12:12:35Functions:172181.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves14BasisFunctions10linkActionEPNS_6ActionE0
_ZN4PLMD3ves14BasisFunctions11linkVesBiasEPNS0_7VesBiasE0
_ZN4PLMD3ves14BasisFunctions11setIntervalEdd0
_ZNK4PLMD3ves14BasisFunctions27getAllValuesNumericalDerivsEdRdRbRSt6vectorIdSaIdEES7_0
_ZN4PLMD3ves14BasisFunctions11setIntervalERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_2
_ZNK4PLMD3ves14BasisFunctions16getMultipleValueERKSt6vectorIdSaIdEERS4_RS2_IS4_SaIS4_EESA_b71
_ZNK4PLMD3ves14BasisFunctions25writeBasisFunctionsToFileERNS_5OFileES3_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESB_jbSB_SB_b71
_ZN4PLMD3ves14BasisFunctions11setupLabelsEv78
_ZN4PLMD3ves14BasisFunctions20setIntrinsicIntervalEdd79
_ZN4PLMD3ves14BasisFunctions21setupUniformIntegralsEv79
_ZN4PLMD3ves14BasisFunctions25numericalUniformIntegralsEv85
_ZNK4PLMD3ves14BasisFunctions16getKeywordStringB5cxx11Ev142
_ZN4PLMD3ves14BasisFunctions20setIntrinsicIntervalERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_170
_ZNK4PLMD3ves14BasisFunctions30getTargetDistributionIntegralsEPKNS0_18TargetDistributionE247
_ZN4PLMD3ves14BasisFunctions13setupIntervalEv249
_ZN4PLMD3ves14BasisFunctions7setupBFEv249
_ZN4PLMD3ves14BasisFunctionsC2ERKNS_13ActionOptionsE249
_ZNK4PLMD3ves14BasisFunctions9printInfoEv249
_ZNK4PLMD3ves14BasisFunctions44numericalTargetDistributionIntegralsFromGridEPKNS_4GridE261
_ZNK4PLMD3ves14BasisFunctions8getValueEdjRdRb261
_ZN4PLMD3ves14BasisFunctions16registerKeywordsERNS_8KeywordsE271
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BasisFunctions.cpp.func.html b/coverage/ves/BasisFunctions.cpp.func.html new file mode 100644 index 000000000000..1382ec01c1e4 --- /dev/null +++ b/coverage/ves/BasisFunctions.cpp.func.html @@ -0,0 +1,157 @@ + + + + + + + + LCOV - plumed test coverage - ves/BasisFunctions.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BasisFunctions.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22225387.7 %
Date:2024-04-19 12:12:35Functions:172181.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves14BasisFunctions10linkActionEPNS_6ActionE0
_ZN4PLMD3ves14BasisFunctions11linkVesBiasEPNS0_7VesBiasE0
_ZN4PLMD3ves14BasisFunctions11setIntervalERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_2
_ZN4PLMD3ves14BasisFunctions11setIntervalEdd0
_ZN4PLMD3ves14BasisFunctions11setupLabelsEv78
_ZN4PLMD3ves14BasisFunctions13setupIntervalEv249
_ZN4PLMD3ves14BasisFunctions16registerKeywordsERNS_8KeywordsE271
_ZN4PLMD3ves14BasisFunctions20setIntrinsicIntervalERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_170
_ZN4PLMD3ves14BasisFunctions20setIntrinsicIntervalEdd79
_ZN4PLMD3ves14BasisFunctions21setupUniformIntegralsEv79
_ZN4PLMD3ves14BasisFunctions25numericalUniformIntegralsEv85
_ZN4PLMD3ves14BasisFunctions7setupBFEv249
_ZN4PLMD3ves14BasisFunctionsC2ERKNS_13ActionOptionsE249
_ZNK4PLMD3ves14BasisFunctions16getKeywordStringB5cxx11Ev142
_ZNK4PLMD3ves14BasisFunctions16getMultipleValueERKSt6vectorIdSaIdEERS4_RS2_IS4_SaIS4_EESA_b71
_ZNK4PLMD3ves14BasisFunctions25writeBasisFunctionsToFileERNS_5OFileES3_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESB_jbSB_SB_b71
_ZNK4PLMD3ves14BasisFunctions27getAllValuesNumericalDerivsEdRdRbRSt6vectorIdSaIdEES7_0
_ZNK4PLMD3ves14BasisFunctions30getTargetDistributionIntegralsEPKNS0_18TargetDistributionE247
_ZNK4PLMD3ves14BasisFunctions44numericalTargetDistributionIntegralsFromGridEPKNS_4GridE261
_ZNK4PLMD3ves14BasisFunctions8getValueEdjRdRb261
_ZNK4PLMD3ves14BasisFunctions9printInfoEv249
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BasisFunctions.cpp.gcov.html b/coverage/ves/BasisFunctions.cpp.gcov.html new file mode 100644 index 000000000000..1e87176310e1 --- /dev/null +++ b/coverage/ves/BasisFunctions.cpp.gcov.html @@ -0,0 +1,482 @@ + + + + + + + + LCOV - plumed test coverage - ves/BasisFunctions.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BasisFunctions.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22225387.7 %
Date:2024-04-19 12:12:35Functions:172181.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "BasisFunctions.h"
+      24             : #include "TargetDistribution.h"
+      25             : #include "VesBias.h"
+      26             : #include "VesTools.h"
+      27             : #include "GridIntegrationWeights.h"
+      28             : 
+      29             : #include "tools/Grid.h"
+      30             : #include "tools/Tools.h"
+      31             : 
+      32             : 
+      33             : namespace PLMD {
+      34             : namespace ves {
+      35             : 
+      36         271 : void BasisFunctions::registerKeywords(Keywords& keys) {
+      37         271 :   Action::registerKeywords(keys);
+      38         542 :   keys.add("compulsory","ORDER","The order of the basis function expansion.");
+      39         542 :   keys.add("compulsory","MINIMUM","The minimum of the interval on which the basis functions are defined.");
+      40         542 :   keys.add("compulsory","MAXIMUM","The maximum of the interval on which the basis functions are defined.");
+      41         542 :   keys.add("hidden","NGRID_POINTS","The number of grid points used for numerical integrals");
+      42         542 :   keys.addFlag("DEBUG_INFO",false,"Print out more detailed information about the basis set. Useful for debugging.");
+      43         542 :   keys.addFlag("NUMERICAL_INTEGRALS",false,"Calculate basis function integral for the uniform distribution numerically. Useful for debugging.");
+      44         271 : }
+      45             : 
+      46             : 
+      47         249 : BasisFunctions::BasisFunctions(const ActionOptions&ao):
+      48             :   Action(ao),
+      49         249 :   print_debug_info_(false),
+      50         249 :   has_been_set(false),
+      51         498 :   description_("Undefined"),
+      52         249 :   type_("Undefined"),
+      53         249 :   norder_(0),
+      54         249 :   nbasis_(1),
+      55         249 :   bf_label_prefix_("f"),
+      56         249 :   bf_labels_(nbasis_,"f0"),
+      57         249 :   periodic_(false),
+      58         249 :   interval_bounded_(true),
+      59         249 :   interval_intrinsic_min_str_("1.0"),
+      60         249 :   interval_intrinsic_max_str_("-1.0"),
+      61         249 :   interval_intrinsic_min_(1.0),
+      62         249 :   interval_intrinsic_max_(-1.0),
+      63         249 :   interval_intrinsic_range_(0.0),
+      64         249 :   interval_intrinsic_mean_(0.0),
+      65         249 :   interval_min_str_(""),
+      66         249 :   interval_max_str_(""),
+      67         249 :   interval_min_(0.0),
+      68         249 :   interval_max_(0.0),
+      69         249 :   interval_range_(0.0),
+      70         249 :   interval_mean_(0.0),
+      71         249 :   argT_derivf_(1.0),
+      72         249 :   numerical_uniform_integrals_(false),
+      73         249 :   nbins_(1001),
+      74         249 :   uniform_integrals_(nbasis_,0.0),
+      75         249 :   vesbias_pntr_(NULL),
+      76         747 :   action_pntr_(NULL)
+      77             : {
+      78         249 :   bf_keywords_.push_back(getName());
+      79         498 :   if(keywords.exists("ORDER")) {
+      80         711 :     parse("ORDER",norder_); addKeywordToList("ORDER",norder_);
+      81             :   }
+      82         249 :   nbasis_=norder_+1;
+      83             :   //
+      84             :   std::string str_imin; std::string str_imax;
+      85         496 :   if(keywords.exists("MINIMUM") && keywords.exists("MAXIMUM")) {
+      86         741 :     parse("MINIMUM",str_imin); addKeywordToList("MINIMUM",str_imin);
+      87         741 :     parse("MAXIMUM",str_imax); addKeywordToList("MAXIMUM",str_imax);
+      88             :   }
+      89             :   else {
+      90             :     str_imin = "-1.0";
+      91             :     str_imax = "1.0";
+      92             :   }
+      93             :   interval_min_str_ = str_imin;
+      94             :   interval_max_str_ = str_imax;
+      95         249 :   if(!Tools::convertNoexcept(str_imin,interval_min_)) {
+      96           0 :     plumed_merror(getName()+": cannot convert the value given in MINIMUM to a double");
+      97             :   }
+      98         249 :   if(!Tools::convertNoexcept(str_imax,interval_max_)) {
+      99           0 :     plumed_merror(getName()+": cannot convert the value given in MAXIMUM to a double");
+     100             :   }
+     101         249 :   if(interval_min_>interval_max_) {plumed_merror(getName()+": MINIMUM and MAXIMUM are not correctly defined");}
+     102             :   //
+     103         249 :   parseFlag("DEBUG_INFO",print_debug_info_);
+     104         498 :   if(keywords.exists("NUMERICAL_INTEGRALS")) {
+     105         336 :     parseFlag("NUMERICAL_INTEGRALS",numerical_uniform_integrals_);
+     106             :   }
+     107         498 :   if(keywords.exists("NGRID_POINTS")) {
+     108         494 :     parse("NGRID_POINTS",nbins_);
+     109             :   }
+     110             :   // log.printf(" %s \n",getKeywordString().c_str());
+     111             : 
+     112         249 : }
+     113             : 
+     114             : 
+     115          79 : void BasisFunctions::setIntrinsicInterval(const double interval_intrinsic_min_in, const double interval_intrinsic_max_in) {
+     116          79 :   interval_intrinsic_min_ = interval_intrinsic_min_in;
+     117          79 :   interval_intrinsic_max_ = interval_intrinsic_max_in;
+     118          79 :   VesTools::convertDbl2Str(interval_intrinsic_min_,interval_intrinsic_min_str_);
+     119          79 :   VesTools::convertDbl2Str(interval_intrinsic_max_,interval_intrinsic_max_str_);
+     120          79 :   plumed_massert(interval_intrinsic_min_<interval_intrinsic_max_,"setIntrinsicInterval: intrinsic intervals are not defined correctly");
+     121          79 : }
+     122             : 
+     123             : 
+     124         170 : void BasisFunctions::setIntrinsicInterval(const std::string& interval_intrinsic_min_str_in, const std::string& interval_intrinsic_max_str_in) {
+     125         170 :   interval_intrinsic_min_str_ = interval_intrinsic_min_str_in;
+     126         170 :   interval_intrinsic_max_str_ = interval_intrinsic_max_str_in;
+     127         170 :   if(!Tools::convertNoexcept(interval_intrinsic_min_str_,interval_intrinsic_min_)) {
+     128           0 :     plumed_merror("setIntrinsicInterval: cannot convert string value given for the minimum of the intrinsic interval to a double");
+     129             :   }
+     130         170 :   if(!Tools::convertNoexcept(interval_intrinsic_max_str_,interval_intrinsic_max_)) {
+     131           0 :     plumed_merror("setIntrinsicInterval: cannot convert string value given for the maximum of the intrinsic interval to a double");
+     132             :   }
+     133         170 :   plumed_massert(interval_intrinsic_min_<interval_intrinsic_max_,"setIntrinsicInterval: intrinsic intervals are not defined correctly");
+     134         170 : }
+     135             : 
+     136             : 
+     137           0 : void BasisFunctions::setInterval(const double interval_min_in, const double interval_max_in) {
+     138           0 :   interval_min_ = interval_min_in;
+     139           0 :   interval_max_ = interval_max_in;
+     140           0 :   VesTools::convertDbl2Str(interval_min_,interval_min_str_);
+     141           0 :   VesTools::convertDbl2Str(interval_max_,interval_max_str_);
+     142           0 :   plumed_massert(interval_min_<interval_max_,"setInterval: intervals are not defined correctly");
+     143           0 : }
+     144             : 
+     145             : 
+     146           2 : void BasisFunctions::setInterval(const std::string& interval_min_str_in, const std::string& interval_max_str_in) {
+     147           2 :   interval_min_str_ = interval_min_str_in;
+     148           2 :   interval_max_str_ = interval_max_str_in;
+     149           2 :   if(!Tools::convertNoexcept(interval_min_str_,interval_min_)) {
+     150           0 :     plumed_merror("setInterval: cannot convert string value given for the minimum of the interval to a double");
+     151             :   }
+     152           2 :   if(!Tools::convertNoexcept(interval_max_str_,interval_max_)) {
+     153           0 :     plumed_merror("setInterval: cannot convert string value given for the maximum of the interval to a double");
+     154             :   }
+     155           2 :   plumed_massert(interval_min_<interval_max_,"setInterval: intervals are not defined correctly");
+     156           2 : }
+     157             : 
+     158             : 
+     159         249 : void BasisFunctions::setupInterval() {
+     160             :   // if(!intervalBounded()){plumed_merror("setupInterval() only works for bounded interval");}
+     161         249 :   interval_intrinsic_range_ = interval_intrinsic_max_-interval_intrinsic_min_;
+     162         249 :   interval_intrinsic_mean_  = 0.5*(interval_intrinsic_max_+interval_intrinsic_min_);
+     163         249 :   interval_range_ = interval_max_-interval_min_;
+     164         249 :   interval_mean_  = 0.5*(interval_max_+interval_min_);
+     165         249 :   argT_derivf_ = interval_intrinsic_range_/interval_range_;
+     166         249 : }
+     167             : 
+     168             : 
+     169          78 : void BasisFunctions::setupLabels() {
+     170         884 :   for(unsigned int i=0; i < nbasis_; i++) {
+     171         806 :     std::string is; Tools::convert(i,is);
+     172        1612 :     bf_labels_[i]=bf_label_prefix_+is+"(s)";
+     173             :   }
+     174          78 : }
+     175             : 
+     176             : 
+     177          79 : void BasisFunctions::setupUniformIntegrals() {
+     178          79 :   numerical_uniform_integrals_=true;
+     179          79 :   numericalUniformIntegrals();
+     180          79 : }
+     181             : 
+     182             : 
+     183         249 : void BasisFunctions::setupBF() {
+     184         249 :   if(interval_intrinsic_min_>interval_intrinsic_max_) {plumed_merror("setupBF: default intervals are not correctly set");}
+     185         249 :   setupInterval();
+     186         249 :   setupLabels();
+     187         249 :   if(bf_labels_.size()==1) {plumed_merror("setupBF: the labels of the basis functions are not correct.");}
+     188         249 :   if(!numerical_uniform_integrals_) {setupUniformIntegrals();}
+     189           6 :   else {numericalUniformIntegrals();}
+     190         249 :   if(uniform_integrals_.size()==1) {plumed_merror("setupBF: the integrals of the basis functions is not correct.");}
+     191         249 :   if(type_=="Undefined") {plumed_merror("setupBF: the type of the basis function is not defined.");}
+     192         249 :   if(description_=="Undefined") {plumed_merror("setupBF: the description of the basis function is not defined.");}
+     193         249 :   has_been_set=true;
+     194         249 :   printInfo();
+     195         249 : }
+     196             : 
+     197             : 
+     198         249 : void BasisFunctions::printInfo() const {
+     199         249 :   if(!has_been_set) {plumed_merror("the basis set has not be setup correctly");}
+     200         249 :   log.printf("  One-dimensional basis set\n");
+     201         249 :   log.printf("   Description: %s\n",description_.c_str());
+     202         249 :   log.printf("   Type: %s\n",type_.c_str());
+     203         249 :   if(periodic_) {log.printf("   The basis functions are periodic\n");}
+     204         249 :   log.printf("   Order of basis set: %u\n",norder_);
+     205         249 :   log.printf("   Number of basis functions: %u\n",nbasis_);
+     206             :   // log.printf("   Interval of basis set: %f to %f\n",interval_min_,interval_max_);
+     207         249 :   log.printf("   Interval of basis set: %s to %s\n",interval_min_str_.c_str(),interval_max_str_.c_str());
+     208         249 :   log.printf("   Description of basis functions:\n");
+     209        4293 :   for(unsigned int i=0; i < nbasis_; i++) {log.printf("    %2u       %10s\n",i,bf_labels_[i].c_str());}
+     210             :   //
+     211         249 :   if(print_debug_info_) {
+     212          38 :     log.printf("  Debug information:\n");
+     213             :     // log.printf("   Default interval of basis set: [%f,%f]\n",interval_intrinsic_min_,interval_intrinsic_max_);
+     214          38 :     log.printf("   Intrinsic interval of basis set: [%s,%s]\n",interval_intrinsic_min_str_.c_str(),interval_intrinsic_max_str_.c_str());
+     215          38 :     log.printf("   Intrinsic interval of basis set: range=%f,  mean=%f\n",interval_intrinsic_range_,interval_intrinsic_mean_);
+     216             :     // log.printf("   Defined interval of basis set: [%f,%f]\n",interval_min_,interval_max_);
+     217          38 :     log.printf("   Defined interval of basis set: [%s,%s]\n",interval_min_str_.c_str(),interval_max_str_.c_str());
+     218          38 :     log.printf("   Defined interval of basis set: range=%f,  mean=%f\n",interval_range_,interval_mean_);
+     219          38 :     log.printf("   Derivative factor due to interval translation: %f\n",argT_derivf_);
+     220          38 :     log.printf("   Integral of basis functions over the interval:\n");
+     221          38 :     if(numerical_uniform_integrals_) {log.printf("   Note: calculated numerically\n");}
+     222         558 :     for(unsigned int i=0; i < nbasis_; i++) {log.printf("    %2u       %16.10f\n",i,uniform_integrals_[i]);}
+     223          38 :     log.printf("   --------------------------\n");
+     224             :   }
+     225         249 : }
+     226             : 
+     227             : 
+     228           0 : void BasisFunctions::linkVesBias(VesBias* vesbias_pntr_in) {
+     229           0 :   vesbias_pntr_ = vesbias_pntr_in;
+     230           0 :   action_pntr_ = static_cast<Action*>(vesbias_pntr_in);
+     231           0 : }
+     232             : 
+     233             : 
+     234           0 : void BasisFunctions::linkAction(Action* action_pntr_in) {
+     235           0 :   action_pntr_ = action_pntr_in;
+     236           0 : }
+     237             : 
+     238             : 
+     239          85 : void BasisFunctions::numericalUniformIntegrals() {
+     240          85 :   std::vector<std::string> grid_min(1); grid_min[0]=intervalMinStr();
+     241          85 :   std::vector<std::string> grid_max(1); grid_max[0]=intervalMaxStr();
+     242          85 :   std::vector<unsigned int> grid_bins(1); grid_bins[0]=nbins_;
+     243         170 :   std::vector<std::unique_ptr<Value>> arguments(1); arguments[0]= Tools::make_unique<Value>(nullptr,"arg",false);
+     244         105 :   if(arePeriodic()) {arguments[0]->setDomain(intervalMinStr(),intervalMaxStr());}
+     245          75 :   else {arguments[0]->setNotPeriodic();}
+     246         170 :   auto uniform_grid = Tools::make_unique<Grid>("uniform",Tools::unique2raw(arguments),grid_min,grid_max,grid_bins,false,false);
+     247             :   //
+     248          85 :   double inverse_normalization = 1.0/(intervalMax()-intervalMin());
+     249       85245 :   for(Grid::index_t l=0; l<uniform_grid->getSize(); l++) {
+     250       85160 :     uniform_grid->setValue(l,inverse_normalization);
+     251             :   }
+     252          85 :   uniform_integrals_ = numericalTargetDistributionIntegralsFromGrid(uniform_grid.get());
+     253         170 : }
+     254             : 
+     255             : 
+     256         261 : std::vector<double> BasisFunctions::numericalTargetDistributionIntegralsFromGrid(const Grid* grid_pntr) const {
+     257         261 :   plumed_massert(grid_pntr!=NULL,"the grid is not defined");
+     258         261 :   plumed_massert(grid_pntr->getDimension()==1,"the target distribution grid should be one dimensional");
+     259             :   //
+     260         261 :   std::vector<double> targetdist_integrals(nbasis_,0.0);
+     261         522 :   std::vector<double> integration_weights = GridIntegrationWeights::getIntegrationWeights(grid_pntr);
+     262             : 
+     263      138336 :   for(Grid::index_t k=0; k < grid_pntr->getSize(); k++) {
+     264      138075 :     double arg = grid_pntr->getPoint(k)[0];
+     265      138075 :     std::vector<double> bf_values(nbasis_);
+     266      138075 :     std::vector<double> bf_derivs(nbasis_);
+     267      138075 :     bool inside=true;
+     268      138075 :     double argT=0.0;
+     269      138075 :     getAllValues(arg,argT,inside,bf_values,bf_derivs);
+     270     3336092 :     for(unsigned int i=0; i < nbasis_; i++) {
+     271     3198017 :       targetdist_integrals[i] += (integration_weights[k] * grid_pntr->getValue(k)) * bf_values[i];
+     272             :     }
+     273             :   }
+     274             :   // assume that the first function is the constant
+     275         261 :   bool inside=true;
+     276         261 :   double argT=0.0;
+     277         261 :   targetdist_integrals[0] = getValue(0.0,0,argT,inside);
+     278         261 :   return targetdist_integrals;
+     279             : }
+     280             : 
+     281             : 
+     282         247 : std::vector<double> BasisFunctions::getTargetDistributionIntegrals(const TargetDistribution* targetdist_pntr) const {
+     283         247 :   if(targetdist_pntr==NULL) {
+     284             :     return getUniformIntegrals();
+     285             :   }
+     286             :   else {
+     287             :     Grid* targetdist_grid = targetdist_pntr->getTargetDistGridPntr();
+     288         176 :     return numericalTargetDistributionIntegralsFromGrid(targetdist_grid);
+     289             :   }
+     290             : }
+     291             : 
+     292             : 
+     293         142 : std::string BasisFunctions::getKeywordString() const {
+     294         142 :   std::string str_keywords=bf_keywords_[0];
+     295         762 :   for(unsigned int i=1; i<bf_keywords_.size(); i++) {str_keywords+=" "+bf_keywords_[i];}
+     296         142 :   return str_keywords;
+     297             : }
+     298             : 
+     299             : 
+     300         261 : double BasisFunctions::getValue(const double arg, const unsigned int n, double& argT, bool& inside_range) const {
+     301         261 :   plumed_massert(n<numberOfBasisFunctions(),"getValue: n is outside range of the defined order of the basis set");
+     302         261 :   inside_range=true;
+     303         261 :   std::vector<double> tmp_values(numberOfBasisFunctions());
+     304         261 :   std::vector<double> tmp_derivs(numberOfBasisFunctions());
+     305         261 :   getAllValues(arg, argT, inside_range, tmp_values, tmp_derivs);
+     306         522 :   return tmp_values[n];
+     307             : }
+     308             : 
+     309             : 
+     310           0 : void BasisFunctions::getAllValuesNumericalDerivs(const double arg, double& argT, bool& inside_range, std::vector<double>& values, std::vector<double>& derivs) const {
+     311             :   // use forward difference, unless very close to the boundary
+     312             :   double delta = sqrt(epsilon);
+     313           0 :   if((arg+delta)>intervalMax()) {
+     314             :     delta *= -1.0;
+     315             :   }
+     316           0 :   inside_range=true;
+     317           0 :   std::vector<double> values_delta(numberOfBasisFunctions());
+     318           0 :   std::vector<double> derivs_dummy(numberOfBasisFunctions());
+     319           0 :   getAllValues(arg+delta, argT, inside_range, values_delta, derivs_dummy);
+     320           0 :   getAllValues(arg, argT, inside_range, values, derivs_dummy);
+     321           0 :   for(unsigned int i=0; i<numberOfBasisFunctions(); i++) {
+     322           0 :     derivs[i] = (values_delta[i]-values[i])/delta;
+     323             :   }
+     324           0 : }
+     325             : 
+     326             : 
+     327          71 : void BasisFunctions::getMultipleValue(const std::vector<double>& args, std::vector<double>& argsT, std::vector<std::vector<double> >& values, std::vector<std::vector<double> >& derivs, const bool numerical_deriv) const {
+     328          71 :   argsT.resize(args.size());
+     329             :   values.clear();
+     330             :   derivs.clear();
+     331       23019 :   for(unsigned int i=0; i<args.size(); i++) {
+     332       22948 :     std::vector<double> tmp_values(getNumberOfBasisFunctions());
+     333       22948 :     std::vector<double> tmp_derivs(getNumberOfBasisFunctions());
+     334       22948 :     bool inside_interval=true;
+     335       22948 :     if(!numerical_deriv) {
+     336       22948 :       getAllValues(args[i],argsT[i],inside_interval,tmp_values,tmp_derivs);
+     337             :     } else {
+     338           0 :       getAllValuesNumericalDerivs(args[i],argsT[i],inside_interval,tmp_values,tmp_derivs);
+     339             :     }
+     340       22948 :     values.push_back(tmp_values);
+     341       22948 :     derivs.push_back(tmp_derivs);
+     342             :   }
+     343          71 : }
+     344             : 
+     345             : 
+     346          71 : void BasisFunctions::writeBasisFunctionsToFile(OFile& ofile_values, OFile& ofile_derivs, const std::string& min_in, const std::string& max_in, unsigned int nbins_in, const bool ignore_periodicity, const std::string& output_fmt_values, const std::string& output_fmt_derivs, const bool numerical_deriv) const {
+     347          71 :   std::vector<std::string> min(1); min[0]=min_in;
+     348          71 :   std::vector<std::string> max(1); max[0]=max_in;
+     349          71 :   std::vector<unsigned int> nbins(1); nbins[0]=nbins_in;
+     350          71 :   std::vector<std::unique_ptr<Value>> value_pntr(1);
+     351         142 :   value_pntr[0]= Tools::make_unique<Value>(nullptr,"arg",false);
+     352         117 :   if(arePeriodic() && !ignore_periodicity) {value_pntr[0]->setDomain(intervalMinStr(),intervalMaxStr());}
+     353          48 :   else {value_pntr[0]->setNotPeriodic();}
+     354         142 :   Grid args_grid = Grid("grid",Tools::unique2raw(value_pntr),min,max,nbins,false,false);
+     355             : 
+     356          71 :   std::vector<double> args(args_grid.getSize(),0.0);
+     357       23019 :   for(unsigned int i=0; i<args.size(); i++) {
+     358       22948 :     args[i] = args_grid.getPoint(i)[0];
+     359             :   }
+     360             :   std::vector<double> argsT;
+     361             :   std::vector<std::vector<double> > values;
+     362             :   std::vector<std::vector<double> > derivs;
+     363             : 
+     364         142 :   ofile_values.addConstantField("bf_keywords").printField("bf_keywords","{"+getKeywordString()+"}");
+     365         142 :   ofile_derivs.addConstantField("bf_keywords").printField("bf_keywords","{"+getKeywordString()+"}");
+     366             : 
+     367         213 :   ofile_values.addConstantField("min").printField("min",intervalMinStr());
+     368         213 :   ofile_values.addConstantField("max").printField("max",intervalMaxStr());
+     369             : 
+     370         213 :   ofile_derivs.addConstantField("min").printField("min",intervalMinStr());
+     371         213 :   ofile_derivs.addConstantField("max").printField("max",intervalMaxStr());
+     372             : 
+     373         142 :   ofile_values.addConstantField("nbins").printField("nbins",static_cast<int>(args_grid.getNbin()[0]));
+     374         142 :   ofile_derivs.addConstantField("nbins").printField("nbins",static_cast<int>(args_grid.getNbin()[0]));
+     375             : 
+     376          71 :   if(arePeriodic()) {
+     377          52 :     ofile_values.addConstantField("periodic").printField("periodic","true");
+     378          52 :     ofile_derivs.addConstantField("periodic").printField("periodic","true");
+     379             :   }
+     380             :   else {
+     381          90 :     ofile_values.addConstantField("periodic").printField("periodic","false");
+     382          90 :     ofile_derivs.addConstantField("periodic").printField("periodic","false");
+     383             :   }
+     384             : 
+     385          71 :   getMultipleValue(args,argsT,values,derivs,numerical_deriv);
+     386          71 :   ofile_values.fmtField(output_fmt_values);
+     387          71 :   ofile_derivs.fmtField(output_fmt_derivs);
+     388       23019 :   for(unsigned int i=0; i<args.size(); i++) {
+     389       45896 :     ofile_values.printField("arg",args[i]);
+     390       22948 :     ofile_derivs.printField("arg",args[i]);
+     391      410060 :     for(unsigned int k=0; k<getNumberOfBasisFunctions(); k++) {
+     392      774224 :       ofile_values.printField(getBasisFunctionLabel(k),values[i][k]);
+     393      774224 :       ofile_derivs.printField("d_"+getBasisFunctionLabel(k),derivs[i][k]);
+     394             :     }
+     395       22948 :     ofile_values.printField();
+     396       22948 :     ofile_derivs.printField();
+     397             :   }
+     398          71 :   ofile_values.fmtField();
+     399          71 :   ofile_derivs.fmtField();
+     400             : 
+     401         213 : }
+     402             : 
+     403             : 
+     404             : }
+     405             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BasisFunctions.h.func-sort-c.html b/coverage/ves/BasisFunctions.h.func-sort-c.html new file mode 100644 index 000000000000..96c916672893 --- /dev/null +++ b/coverage/ves/BasisFunctions.h.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - ves/BasisFunctions.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BasisFunctions.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:596196.7 %
Date:2024-04-19 12:12:35Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves14BasisFunctions5applyEv0
_ZN4PLMD3ves14BasisFunctions9calculateEv0
_ZN4PLMD3ves14BasisFunctions16addKeywordToListINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKS8_RKSt6vectorIT_SaISC_EE2
_ZN4PLMD3ves14BasisFunctions16addKeywordToListIdEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEET_7
_ZN4PLMD3ves14BasisFunctions28setAllUniformIntegralsToZeroEv159
_ZN4PLMD3ves14BasisFunctions25setNumberOfBasisFunctionsEj249
_ZN4PLMD3ves14BasisFunctions16addKeywordToListIjEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEET_277
_ZN4PLMD3ves14BasisFunctions16addKeywordToListINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKS8_T_593
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BasisFunctions.h.func.html b/coverage/ves/BasisFunctions.h.func.html new file mode 100644 index 000000000000..d633a36faa6b --- /dev/null +++ b/coverage/ves/BasisFunctions.h.func.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - ves/BasisFunctions.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BasisFunctions.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:596196.7 %
Date:2024-04-19 12:12:35Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves14BasisFunctions16addKeywordToListINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKS8_RKSt6vectorIT_SaISC_EE2
_ZN4PLMD3ves14BasisFunctions16addKeywordToListINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKS8_T_593
_ZN4PLMD3ves14BasisFunctions16addKeywordToListIdEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEET_7
_ZN4PLMD3ves14BasisFunctions16addKeywordToListIjEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEET_277
_ZN4PLMD3ves14BasisFunctions25setNumberOfBasisFunctionsEj249
_ZN4PLMD3ves14BasisFunctions28setAllUniformIntegralsToZeroEv159
_ZN4PLMD3ves14BasisFunctions5applyEv0
_ZN4PLMD3ves14BasisFunctions9calculateEv0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BasisFunctions.h.gcov.html b/coverage/ves/BasisFunctions.h.gcov.html new file mode 100644 index 000000000000..e360eadf888d --- /dev/null +++ b/coverage/ves/BasisFunctions.h.gcov.html @@ -0,0 +1,394 @@ + + + + + + + + LCOV - plumed test coverage - ves/BasisFunctions.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BasisFunctions.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:596196.7 %
Date:2024-04-19 12:12:35Functions:6875.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_ves_BasisFunctions_h
+      23             : #define __PLUMED_ves_BasisFunctions_h
+      24             : 
+      25             : #include "core/Action.h"
+      26             : 
+      27             : #include <vector>
+      28             : #include <string>
+      29             : #include <cmath>
+      30             : 
+      31             : 
+      32             : #define PLUMED_VES_BASISFUNCTIONS_INIT(ao) BasisFunctions(ao)
+      33             : 
+      34             : namespace PLMD {
+      35             : 
+      36             : /**
+      37             : \ingroup INHERIT
+      38             : Abstract base class for implenting new 1D basis sets.
+      39             : */
+      40             : 
+      41             : class Action;
+      42             : class Grid;
+      43             : 
+      44             : namespace ves {
+      45             : 
+      46             : class VesBias;
+      47             : class TargetDistribution;
+      48             : 
+      49             : class BasisFunctions :
+      50             :   public Action
+      51             : {
+      52             : private:
+      53             :   // print extra info about the basis set
+      54             :   bool print_debug_info_;
+      55             :   // to check if the basis set has been defined
+      56             :   bool has_been_set;
+      57             :   // description of the basis set
+      58             :   std::string description_;
+      59             :   // the type of the basis set
+      60             :   std::string type_;
+      61             :   // the maximum order of the basis functions
+      62             :   unsigned int norder_;
+      63             :   // the total number of basis functions
+      64             :   unsigned int nbasis_;
+      65             :   // the keywords used to invoke the basis set
+      66             :   std::vector<std::string> bf_keywords_;
+      67             :   // prefix for the basis function labels
+      68             :   std::string bf_label_prefix_;
+      69             :   // label of each basis function
+      70             :   std::vector<std::string> bf_labels_;
+      71             :   // if the basis functions are periodic or not
+      72             :   bool periodic_;
+      73             :   // if the basis functions are defined on a bounded interval or not
+      74             :   bool interval_bounded_;
+      75             :   // the intrinsic interval of the basis functions
+      76             :   std::string interval_intrinsic_min_str_;
+      77             :   std::string interval_intrinsic_max_str_;
+      78             :   double interval_intrinsic_min_;
+      79             :   double interval_intrinsic_max_;
+      80             :   double interval_intrinsic_range_;
+      81             :   double interval_intrinsic_mean_;
+      82             :   // the defined (translated) interval of the basis functions
+      83             :   std::string interval_min_str_;
+      84             :   std::string interval_max_str_;
+      85             :   double interval_min_;
+      86             :   double interval_max_;
+      87             :   double interval_range_;
+      88             :   double interval_mean_;
+      89             :   // the derivative term in the chain rule coming from the translation of the interval
+      90             :   double argT_derivf_;
+      91             :   // calculate numerically the integrals of the basis functions over the intervals
+      92             :   bool numerical_uniform_integrals_;
+      93             :   unsigned int nbins_;
+      94             :   // the integrals of the basis functions over the interval on which they are defined
+      95             :   std::vector <double> uniform_integrals_;
+      96             :   //
+      97             :   VesBias* vesbias_pntr_;
+      98             :   Action* action_pntr_;
+      99             :   //
+     100             :   void getAllValuesNumericalDerivs(const double, double&, bool&, std::vector<double>&, std::vector<double>&) const;
+     101             : 
+     102             : protected:
+     103             :   // setup various stuff
+     104             :   void setupBF();
+     105             :   void setupInterval();
+     106             :   void setNumericalIntegrationBins(const unsigned int nbins) {nbins_=nbins;}
+     107             :   void numericalUniformIntegrals();
+     108             :   std::vector<double> numericalTargetDistributionIntegralsFromGrid(const Grid*) const ;
+     109             :   virtual void setupLabels();
+     110             :   virtual void setupUniformIntegrals();
+     111             :   template<typename T>
+     112             :   void addKeywordToList(const std::string&, const T);
+     113             :   template<typename T>
+     114             :   void addKeywordToList(const std::string&, const std::vector<T>&);
+     115             :   void addKeywordToList(const std::string&, const bool);
+     116             :   //
+     117         111 :   void setPeriodic() {periodic_=true;}
+     118         138 :   void setNonPeriodic() {periodic_=false;}
+     119         249 :   void setIntervalBounded() {interval_bounded_=true;}
+     120             :   void setIntervalNonBounded() {interval_bounded_=false;}
+     121         249 :   void setType(const std::string& type_in) {type_=type_in;}
+     122         249 :   void setDescription(const std::string& description_in) {description_=description_in;}
+     123             :   //
+     124             :   void setNumberOfBasisFunctions(const unsigned int);
+     125          12 :   void setOrder(const unsigned int norder_in) {norder_=norder_in;}
+     126             :   void setIntrinsicInterval(const double, const double);
+     127             :   void setIntrinsicInterval(const std::string&, const std::string&);
+     128             :   void setInterval(const double, const double);
+     129             :   void setInterval(const std::string&, const std::string&);
+     130             :   //
+     131             :   double intrinsicIntervalMin() const {return interval_intrinsic_min_;}
+     132     1752567 :   double intrinsicIntervalMax() const {return interval_intrinsic_max_;}
+     133             :   std::string intrinsicIntervalMinStr() const {return interval_intrinsic_min_str_;}
+     134             :   std::string intrinsicIntervalMaxStr() const {return interval_intrinsic_max_str_;}
+     135             :   //
+     136             :   void setUniformIntegral(const unsigned int, const double);
+     137             :   void setUniformIntegrals(const std::vector<double>&);
+     138             :   void setAllUniformIntegralsToZero();
+     139             :   //
+     140             :   void setLabelPrefix(const std::string&);
+     141             :   void setLabel(const unsigned int, const std::string&);
+     142             :   void setLabels(const std::vector<std::string>&);
+     143             : 
+     144             : public:
+     145             :   static void registerKeywords(Keywords&);
+     146             :   explicit BasisFunctions(const ActionOptions&ao);
+     147             :   bool hasBeenSet() const {return has_been_set;}
+     148             :   std::string getType() const {return type_;}
+     149             :   std::string getDescription() const {return description_;}
+     150    33615870 :   unsigned int getOrder() const {return norder_;}
+     151    13201612 :   unsigned int getNumberOfBasisFunctions() const {return nbasis_;}
+     152      112559 :   unsigned int numberOfBasisFunctions() const {return nbasis_;}
+     153             :   unsigned int getSize() const {return nbasis_;}
+     154     2661456 :   bool arePeriodic() const {return periodic_;}
+     155             :   bool intervalBounded() const {return interval_bounded_;}
+     156      204981 :   double intervalMin() const {return interval_min_;}
+     157         281 :   double intervalMax() const {return interval_max_;}
+     158      300134 :   double intervalRange() const {return interval_range_;}
+     159             :   double intervalMean() const {return interval_mean_;}
+     160    30352118 :   double intervalDerivf() const {return argT_derivf_;}
+     161         601 :   std::string intervalMinStr() const {return interval_min_str_;}
+     162         601 :   std::string intervalMaxStr() const {return interval_max_str_;}
+     163         133 :   std::vector<double> getUniformIntegrals() const {return uniform_integrals_;}
+     164             :   std::vector<double> getTargetDistributionIntegrals(const TargetDistribution*) const;
+     165             :   //
+     166             :   std::vector<std::string> getKeywordList() const {return bf_keywords_;}
+     167             :   std::string getKeywordString() const;
+     168             :   //
+     169      787685 :   std::string getBasisFunctionLabel(const unsigned int index) const {return bf_labels_[index];}
+     170             :   std::vector<std::string> getBasisFunctionLabels() const {return bf_labels_;}
+     171             :   //
+     172             :   void linkVesBias(VesBias*);
+     173             :   void linkAction(Action*);
+     174             :   VesBias* getPntrToVesBias() const;
+     175             :   Action* getPntrToAction() const;
+     176             :   //
+     177             :   double translateArgument(const double, bool&) const;
+     178             :   double checkIfArgumentInsideInterval(const double, bool&) const;
+     179             :   //
+     180           0 :   void apply() override {};
+     181           0 :   void calculate() override {};
+     182             :   // calculate the value for the n-th basis function
+     183             :   double getValue(const double, const unsigned int, double&, bool&) const;
+     184             :   // calculate the values for all basis functions
+     185             :   virtual void getAllValues(const double, double&, bool&, std::vector<double>&, std::vector<double>&) const = 0;
+     186             :   //virtual void get2ndDerivatives(const double, std::vector<double>&)=0;
+     187             :   void printInfo() const;
+     188             :   //
+     189             :   void getMultipleValue(const std::vector<double>&, std::vector<double>&, std::vector<std::vector<double> >&, std::vector<std::vector<double> >&, const bool numerical_deriv=false) const;
+     190             :   void writeBasisFunctionsToFile(OFile&, OFile&, const std::string& min_in, const std::string& max_in, unsigned int nbins=1000, const bool ignore_periodicity=false, const std::string& output_fmt_values="%15.8f", const std::string& output_fmt_derivs="%15.8f", const bool numerical_deriv=false) const;
+     191             : };
+     192             : 
+     193             : 
+     194             : inline
+     195         249 : void BasisFunctions::setNumberOfBasisFunctions(const unsigned int nbasis_in) {
+     196         249 :   nbasis_=nbasis_in;
+     197         249 :   bf_labels_.assign(nbasis_,"");
+     198         249 :   uniform_integrals_.assign(nbasis_,0.0);
+     199         249 : }
+     200             : 
+     201             : 
+     202             : inline
+     203             : VesBias* BasisFunctions::getPntrToVesBias() const {
+     204             :   plumed_massert(vesbias_pntr_!=NULL,"the VES bias has not been linked");
+     205             :   return vesbias_pntr_;
+     206             : }
+     207             : 
+     208             : 
+     209             : inline
+     210             : Action* BasisFunctions::getPntrToAction() const {
+     211             :   plumed_massert(action_pntr_!=NULL,"the action has not been linked");
+     212             :   return action_pntr_;
+     213             : }
+     214             : 
+     215             : 
+     216             : inline
+     217             : void BasisFunctions::setUniformIntegral(const unsigned index, const double value) {
+     218         264 :   uniform_integrals_[index] = value;
+     219             : }
+     220             : 
+     221             : 
+     222             : inline
+     223             : void BasisFunctions::setUniformIntegrals(const std::vector<double>& uniform_integrals_in) {
+     224             :   plumed_assert(uniform_integrals_in.size()==nbasis_);
+     225             :   uniform_integrals_ = uniform_integrals_in;
+     226             : }
+     227             : 
+     228             : 
+     229             : inline
+     230         159 : void BasisFunctions::setAllUniformIntegralsToZero() {
+     231         159 :   uniform_integrals_.assign(nbasis_,0.0);
+     232         159 : }
+     233             : 
+     234             : inline
+     235             : void BasisFunctions::setLabelPrefix(const std::string& bf_label_prefix_in) {
+     236          68 :   bf_label_prefix_ = bf_label_prefix_in;
+     237          68 : }
+     238             : 
+     239             : 
+     240             : inline
+     241             : void BasisFunctions::setLabel(const unsigned int index, const std::string& label) {
+     242        1140 :   bf_labels_[index] = label;
+     243        3238 : }
+     244             : 
+     245             : 
+     246             : inline
+     247             : void BasisFunctions::setLabels(const std::vector<std::string>& bf_labels_in) {
+     248             :   bf_labels_ = bf_labels_in;
+     249             : }
+     250             : 
+     251             : 
+     252             : inline
+     253             : double BasisFunctions::translateArgument(const double arg, bool& inside_interval) const {
+     254             :   // NOTE: only works for symmetric intrinsic intervals
+     255             :   inside_interval=true;
+     256     4895662 :   double argT = (arg-interval_mean_)*argT_derivf_;
+     257     4895662 :   if(argT < interval_intrinsic_min_) {
+     258         433 :     inside_interval=false;
+     259         433 :     argT=interval_intrinsic_min_;
+     260             :   }
+     261     4895229 :   else if(argT > interval_intrinsic_max_) {
+     262       13665 :     inside_interval=false;
+     263       13665 :     argT=interval_intrinsic_max_;
+     264             :   }
+     265             :   return argT;
+     266             : }
+     267             : 
+     268             : 
+     269             : inline
+     270             : double BasisFunctions::checkIfArgumentInsideInterval(const double arg, bool& inside_interval) const {
+     271       62249 :   inside_interval=true;
+     272             :   double argT = arg;
+     273      947044 :   if(arg < interval_min_) {
+     274         362 :     inside_interval=false;
+     275         362 :     argT=interval_min_;
+     276             :   }
+     277      946682 :   else if(arg > interval_max_) {
+     278         369 :     inside_interval=false;
+     279         369 :     argT=interval_max_;
+     280             :   }
+     281             :   return argT;
+     282             : }
+     283             : 
+     284             : 
+     285             : 
+     286             : template<typename T>
+     287         877 : void BasisFunctions::addKeywordToList(const std::string& keyword, const T value) {
+     288             :   std::string str_value;
+     289         877 :   Tools::convert(value,str_value);
+     290        1754 :   bf_keywords_.push_back(keyword+"="+str_value);
+     291         877 : }
+     292             : 
+     293             : 
+     294             : template<typename T>
+     295           2 : void BasisFunctions::addKeywordToList(const std::string& keyword, const std::vector<T>& values) {
+     296             :   std::string str_value;
+     297             :   std::string str_keywordvalues;
+     298           2 :   Tools::convert(values[0],str_value);
+     299           4 :   str_keywordvalues = keyword + "=" + str_value;
+     300           5 :   for(unsigned int i=1; i<values.size(); i++) {
+     301           3 :     Tools::convert(values[i],str_value);
+     302           6 :     str_keywordvalues += "," + str_value;
+     303             :   }
+     304           2 :   bf_keywords_.push_back(str_keywordvalues);
+     305           2 : }
+     306             : 
+     307             : 
+     308             : inline
+     309             : void BasisFunctions::addKeywordToList(const std::string& keyword, const bool value) {
+     310          87 :   if(value) {bf_keywords_.push_back(keyword);}
+     311             : }
+     312             : 
+     313             : 
+     314             : }
+     315             : }
+     316             : 
+     317             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/CoeffsBase.cpp.func-sort-c.html b/coverage/ves/CoeffsBase.cpp.func-sort-c.html new file mode 100644 index 000000000000..b85df460a6db --- /dev/null +++ b/coverage/ves/CoeffsBase.cpp.func-sort-c.html @@ -0,0 +1,201 @@ + + + + + + + + LCOV - plumed test coverage - ves/CoeffsBase.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - CoeffsBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12730142.2 %
Date:2024-04-19 12:12:35Functions:153246.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves10CoeffsBase10linkActionEPNS_6ActionE0
_ZN4PLMD3ves10CoeffsBase12setDataLabelERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD3ves10CoeffsBase13resizeIndicesERKSt6vectorIjSaIjEE0
_ZN4PLMD3ves10CoeffsBase13resizeIndicesERSt6vectorIPNS0_14BasisFunctionsESaIS4_EE0
_ZN4PLMD3ves10CoeffsBase17setDimensionLabelEjRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD3ves10CoeffsBase19reinitializeIndicesERKSt6vectorIjSaIjEE0
_ZN4PLMD3ves10CoeffsBase19setCoeffDescriptionERKSt6vectorIjSaIjEERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD3ves10CoeffsBase21setAllDimensionLabelsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD3ves10CoeffsBase21setAllDimensionLabelsERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EE0
_ZN4PLMD3ves10CoeffsBase24setAllCoeffsDescriptionsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD3ves10CoeffsBase24setAllCoeffsDescriptionsERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EE0
_ZN4PLMD3ves10CoeffsBase7setTypeENS1_10CoeffsTypeE0
_ZN4PLMD3ves10CoeffsBase8setLabelERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD3ves10CoeffsBase9setLabelsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_0
_ZN4PLMD3ves10CoeffsBaseC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIS7_SaIS7_EERKSA_IjSaIjEEb0
_ZN4PLMD3ves10CoeffsBaseC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorISA_IPNS_5ValueESaISC_EESaISE_EERSA_ISA_IPNS0_14BasisFunctionsESaISJ_EESaISL_EEbS9_0
_ZNK4PLMD3ves10CoeffsBase12indicesExistERKSt6vectorIjSaIjEE0
_ZN4PLMD3ves10CoeffsBase18replaceLabelStringERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_5
_ZNK4PLMD3ves10CoeffsBase9sameShapeERKS1_6
_ZN4PLMD3ves10CoeffsBase11linkVesBiasEPNS0_7VesBiasE90
_ZN4PLMD3ves10CoeffsBase15checkCoeffsInfoERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_jmRKSt6vectorIjSaIjEE368
_ZN4PLMD3ves10CoeffsBase21getCoeffsInfoFromFileERNS_5IFileEb368
_ZN4PLMD3ves10CoeffsBase17initializeIndicesERKSt6vectorIjSaIjEERKS2_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISC_EE377
_ZN4PLMD3ves10CoeffsBase23setupBasisFunctionsInfoEv377
_ZN4PLMD3ves10CoeffsBaseC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIPNS_5ValueESaISC_EERSA_IPNS0_14BasisFunctionsESaISI_EEb377
_ZN4PLMD3ves10CoeffsBase34getIterationCounterAndTimeFromFileERNS_5IFileE406
_ZN4PLMD3ves10CoeffsBase9setLabelsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE754
_ZNK4PLMD3ves10CoeffsBase34writeIterationCounterAndTimeToFileERNS_5OFileE2721
_ZNK4PLMD3ves10CoeffsBase21writeCoeffsInfoToFileERNS_5OFileE3008
_ZNK4PLMD3ves10CoeffsBase10getTypeStrB5cxx11Ev3376
_ZN4PLMD3ves10CoeffsBase19setCoeffDescriptionEmRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE8928
_ZN4PLMD3ves10CoeffsBaseD2Ev342134
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/CoeffsBase.cpp.func.html b/coverage/ves/CoeffsBase.cpp.func.html new file mode 100644 index 000000000000..842168ef7173 --- /dev/null +++ b/coverage/ves/CoeffsBase.cpp.func.html @@ -0,0 +1,201 @@ + + + + + + + + LCOV - plumed test coverage - ves/CoeffsBase.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - CoeffsBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12730142.2 %
Date:2024-04-19 12:12:35Functions:153246.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves10CoeffsBase10linkActionEPNS_6ActionE0
_ZN4PLMD3ves10CoeffsBase11linkVesBiasEPNS0_7VesBiasE90
_ZN4PLMD3ves10CoeffsBase12setDataLabelERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD3ves10CoeffsBase13resizeIndicesERKSt6vectorIjSaIjEE0
_ZN4PLMD3ves10CoeffsBase13resizeIndicesERSt6vectorIPNS0_14BasisFunctionsESaIS4_EE0
_ZN4PLMD3ves10CoeffsBase15checkCoeffsInfoERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_jmRKSt6vectorIjSaIjEE368
_ZN4PLMD3ves10CoeffsBase17initializeIndicesERKSt6vectorIjSaIjEERKS2_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISC_EE377
_ZN4PLMD3ves10CoeffsBase17setDimensionLabelEjRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD3ves10CoeffsBase18replaceLabelStringERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_5
_ZN4PLMD3ves10CoeffsBase19reinitializeIndicesERKSt6vectorIjSaIjEE0
_ZN4PLMD3ves10CoeffsBase19setCoeffDescriptionERKSt6vectorIjSaIjEERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD3ves10CoeffsBase19setCoeffDescriptionEmRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE8928
_ZN4PLMD3ves10CoeffsBase21getCoeffsInfoFromFileERNS_5IFileEb368
_ZN4PLMD3ves10CoeffsBase21setAllDimensionLabelsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD3ves10CoeffsBase21setAllDimensionLabelsERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EE0
_ZN4PLMD3ves10CoeffsBase23setupBasisFunctionsInfoEv377
_ZN4PLMD3ves10CoeffsBase24setAllCoeffsDescriptionsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD3ves10CoeffsBase24setAllCoeffsDescriptionsERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EE0
_ZN4PLMD3ves10CoeffsBase34getIterationCounterAndTimeFromFileERNS_5IFileE406
_ZN4PLMD3ves10CoeffsBase7setTypeENS1_10CoeffsTypeE0
_ZN4PLMD3ves10CoeffsBase8setLabelERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD3ves10CoeffsBase9setLabelsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE754
_ZN4PLMD3ves10CoeffsBase9setLabelsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_0
_ZN4PLMD3ves10CoeffsBaseC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIPNS_5ValueESaISC_EERSA_IPNS0_14BasisFunctionsESaISI_EEb377
_ZN4PLMD3ves10CoeffsBaseC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIS7_SaIS7_EERKSA_IjSaIjEEb0
_ZN4PLMD3ves10CoeffsBaseC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorISA_IPNS_5ValueESaISC_EESaISE_EERSA_ISA_IPNS0_14BasisFunctionsESaISJ_EESaISL_EEbS9_0
_ZN4PLMD3ves10CoeffsBaseD2Ev342134
_ZNK4PLMD3ves10CoeffsBase10getTypeStrB5cxx11Ev3376
_ZNK4PLMD3ves10CoeffsBase12indicesExistERKSt6vectorIjSaIjEE0
_ZNK4PLMD3ves10CoeffsBase21writeCoeffsInfoToFileERNS_5OFileE3008
_ZNK4PLMD3ves10CoeffsBase34writeIterationCounterAndTimeToFileERNS_5OFileE2721
_ZNK4PLMD3ves10CoeffsBase9sameShapeERKS1_6
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/CoeffsBase.cpp.gcov.html b/coverage/ves/CoeffsBase.cpp.gcov.html new file mode 100644 index 000000000000..b503b7d076bc --- /dev/null +++ b/coverage/ves/CoeffsBase.cpp.gcov.html @@ -0,0 +1,594 @@ + + + + + + + + LCOV - plumed test coverage - ves/CoeffsBase.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - CoeffsBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12730142.2 %
Date:2024-04-19 12:12:35Functions:153246.9 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "CoeffsBase.h"
+      24             : #include "BasisFunctions.h"
+      25             : #include "VesBias.h"
+      26             : 
+      27             : #include "tools/Tools.h"
+      28             : #include "tools/File.h"
+      29             : #include "tools/Exception.h"
+      30             : #include "core/Value.h"
+      31             : 
+      32             : #include <vector>
+      33             : #include <string>
+      34             : 
+      35             : 
+      36             : namespace PLMD {
+      37             : namespace ves {
+      38             : 
+      39           0 : CoeffsBase::CoeffsBase(
+      40             :   const std::string& label,
+      41             :   const std::vector<std::string>& dimension_labels,
+      42             :   const std::vector<unsigned int>& indices_shape,
+      43           0 :   const bool use_iteration_counter):
+      44           0 :   label_(label),
+      45           0 :   data_label_(label),
+      46           0 :   coeffs_type_(Generic),
+      47           0 :   iteration_and_time_active_(use_iteration_counter),
+      48           0 :   iteration_opt(0),
+      49           0 :   time_md(-1.0),
+      50           0 :   active(true),
+      51           0 :   action_pntr_(NULL),
+      52           0 :   vesbias_pntr_(NULL),
+      53           0 :   ndimensions_(0),
+      54           0 :   indices_shape_(0),
+      55           0 :   ncoeffs_(0),
+      56           0 :   coeffs_descriptions_(0),
+      57           0 :   dimension_labels_(0),
+      58           0 :   args_(0),
+      59           0 :   basisf_(0),
+      60           0 :   multicoeffs_(false),
+      61           0 :   multicoeffs_args_(0),
+      62           0 :   multicoeffs_basisf_(0),
+      63           0 :   field_type_("type"),
+      64           0 :   field_ndimensions_("ndimensions"),
+      65           0 :   field_ncoeffs_total_("ncoeffs_total"),
+      66           0 :   field_shape_prefix_("shape_"),
+      67           0 :   field_time_("time"),
+      68           0 :   field_iteration_("iteration"),
+      69           0 :   output_fmt_("%30.16e")
+      70             : {
+      71           0 :   initializeIndices(indices_shape,dimension_labels);
+      72           0 :   setAllCoeffsDescriptions();
+      73           0 : }
+      74             : 
+      75             : 
+      76         377 : CoeffsBase::CoeffsBase(
+      77             :   const std::string& label,
+      78             :   const std::vector<Value*>& args,
+      79             :   std::vector<BasisFunctions*>& basisf,
+      80         377 :   const bool use_iteration_counter):
+      81         377 :   label_(label),
+      82         377 :   data_label_(label),
+      83         377 :   coeffs_type_(LinearBasisSet),
+      84         377 :   iteration_and_time_active_(use_iteration_counter),
+      85         377 :   iteration_opt(0),
+      86         377 :   time_md(-1.0),
+      87         377 :   active(true),
+      88         377 :   action_pntr_(NULL),
+      89         377 :   vesbias_pntr_(NULL),
+      90         377 :   ndimensions_(0),
+      91         377 :   indices_shape_(0),
+      92         377 :   ncoeffs_(0),
+      93         377 :   coeffs_descriptions_(0),
+      94         377 :   dimension_labels_(0),
+      95         377 :   args_(args),
+      96         377 :   basisf_(basisf),
+      97         377 :   multicoeffs_(false),
+      98         377 :   multicoeffs_args_(0),
+      99         377 :   multicoeffs_basisf_(0),
+     100         377 :   field_type_("type"),
+     101         377 :   field_ndimensions_("ndimensions"),
+     102         377 :   field_ncoeffs_total_("ncoeffs_total"),
+     103         377 :   field_shape_prefix_("shape_"),
+     104         377 :   field_time_("time"),
+     105         377 :   field_iteration_("iteration"),
+     106         377 :   output_fmt_("%30.16e")
+     107             : {
+     108         377 :   plumed_massert(args_.size()==basisf_.size(),"CoeffsBase: number of arguments do not match number of basis functions");
+     109         377 :   std::vector<std::string> dimension_labels(args_.size());
+     110         377 :   std::vector<unsigned int> indices_shape(args_.size());
+     111         789 :   for(unsigned int i=0; i<args_.size(); i++) {
+     112         412 :     dimension_labels[i]=args_[i]->getName();
+     113         412 :     indices_shape[i]=basisf_[i]->getNumberOfBasisFunctions();
+     114             :   }
+     115         377 :   initializeIndices(indices_shape,dimension_labels);
+     116         377 :   setupBasisFunctionsInfo();
+     117         377 : }
+     118             : 
+     119             : 
+     120           0 : CoeffsBase::CoeffsBase(
+     121             :   const std::string& label,
+     122             :   std::vector<std::vector<Value*> >& multicoeffs_args,
+     123             :   std::vector<std::vector<BasisFunctions*> >& multicoeffs_basisf,
+     124             :   const bool use_iteration_counter,
+     125           0 :   const std::string& multicoeffs_label):
+     126           0 :   label_(label),
+     127           0 :   data_label_(label),
+     128           0 :   coeffs_type_(MultiCoeffs_LinearBasisSet),
+     129           0 :   iteration_and_time_active_(use_iteration_counter),
+     130           0 :   iteration_opt(0),
+     131           0 :   time_md(-1.0),
+     132           0 :   active(true),
+     133           0 :   action_pntr_(NULL),
+     134           0 :   vesbias_pntr_(NULL),
+     135           0 :   ndimensions_(0),
+     136           0 :   indices_shape_(0),
+     137           0 :   ncoeffs_(0),
+     138           0 :   coeffs_descriptions_(0),
+     139           0 :   dimension_labels_(0),
+     140           0 :   args_(0),
+     141           0 :   basisf_(0),
+     142           0 :   multicoeffs_(true),
+     143           0 :   multicoeffs_args_(multicoeffs_args),
+     144           0 :   multicoeffs_basisf_(multicoeffs_basisf),
+     145           0 :   field_type_("type"),
+     146           0 :   field_ndimensions_("ndimensions"),
+     147           0 :   field_ncoeffs_total_("ncoeffs_total"),
+     148           0 :   field_shape_prefix_("shape_"),
+     149           0 :   field_time_("time"),
+     150           0 :   field_iteration_("iteration"),
+     151           0 :   output_fmt_("%30.16e")
+     152             : {
+     153           0 :   plumed_massert(multicoeffs_args.size()==multicoeffs_basisf.size(),"Multi Coeffs: number of arguments vectors does not match number of basis functions vectors");
+     154           0 :   unsigned int num_args = multicoeffs_args[0].size();
+     155           0 :   unsigned int dim = num_args+1;
+     156           0 :   std::vector<std::string> dimension_labels(dim);
+     157           0 :   std::vector<unsigned int> indices_shape(dim);
+     158           0 :   for(unsigned int i=0; i<num_args; i++) {
+     159             :     std::string ip;
+     160           0 :     Tools::convert(i+1,ip);
+     161           0 :     dimension_labels[i] = "bf" + ip;
+     162           0 :     indices_shape[i] = multicoeffs_basisf[0][i]->getNumberOfBasisFunctions();
+     163             :   }
+     164           0 :   indices_shape[dim-1] = multicoeffs_args.size();
+     165             :   dimension_labels[dim-1] = multicoeffs_label;
+     166           0 :   for(unsigned int k=0; k<multicoeffs_args.size(); k++) {
+     167           0 :     plumed_massert(multicoeffs_args[k].size()==num_args && multicoeffs_basisf[k].size()==num_args,"Multi Coeffs: arguments and basis functions vectors for each bias should be of the same size");
+     168           0 :     for(unsigned int i=0; i<num_args; i++) {
+     169           0 :       plumed_massert(indices_shape[i]==multicoeffs_basisf[k][i]->getNumberOfBasisFunctions(),"Multi Coeffs: the coeffs shape for each bias should be identical");
+     170             :     }
+     171             :   }
+     172           0 :   initializeIndices(indices_shape,dimension_labels);
+     173           0 :   setupBasisFunctionsInfo();
+     174           0 : }
+     175             : 
+     176             : 
+     177     1026402 : CoeffsBase::~CoeffsBase() {}
+     178             : 
+     179             : 
+     180         377 : void CoeffsBase::initializeIndices(const std::vector<unsigned int>& indices_shape, const std::vector<std::string>& dimension_labels) {
+     181         377 :   plumed_massert(indices_shape.size()==dimension_labels.size(),"indices shape and dimension labels must be of the same size");
+     182         377 :   ndimensions_=indices_shape.size();
+     183         377 :   indices_shape_=indices_shape;
+     184         377 :   dimension_labels_=dimension_labels;
+     185         377 :   ncoeffs_=1;
+     186         789 :   for(unsigned int i=0; i<ndimensions_; i++) {
+     187         412 :     ncoeffs_*=indices_shape_[i];
+     188             :   }
+     189         377 :   coeffs_descriptions_.resize(ncoeffs_);
+     190         377 : }
+     191             : 
+     192             : 
+     193           0 : void CoeffsBase::reinitializeIndices(const std::vector<unsigned int>& indices_shape_new) {
+     194           0 :   plumed_massert(indices_shape_.size()>0,"indices must have been previously initialized before using this function");
+     195           0 :   plumed_massert(dimension_labels_.size()>0,"indices must have been previously initialized before using this function");
+     196           0 :   plumed_massert(indices_shape_new.size()==numberOfDimensions(),"when resizeing Coeffs the dimension must be constant");
+     197           0 :   indices_shape_=indices_shape_new;
+     198           0 :   ncoeffs_=1;
+     199           0 :   for(unsigned int i=0; i<ndimensions_; i++) {
+     200           0 :     ncoeffs_*=indices_shape_[i];
+     201             :   }
+     202           0 :   coeffs_descriptions_.clear();
+     203           0 :   coeffs_descriptions_.resize(ncoeffs_);
+     204           0 : }
+     205             : 
+     206             : 
+     207         377 : void CoeffsBase::setupBasisFunctionsInfo() {
+     208         377 :   plumed_massert(indices_shape_.size()>0,"indices must be initialized before running this function");
+     209         377 :   if(coeffs_type_==LinearBasisSet) {
+     210        9305 :     for(unsigned int i=0; i<numberOfCoeffs(); i++) {
+     211        8928 :       std::vector<unsigned int> indices=getIndices(i);
+     212             :       std::string desc;
+     213        8928 :       desc=basisf_[0]->getBasisFunctionLabel(indices[0]);
+     214       13409 :       for(unsigned int k=1; k<numberOfDimensions(); k++) {
+     215        8962 :         desc+="*"+basisf_[k]->getBasisFunctionLabel(indices[k]);
+     216             :       }
+     217        8928 :       setCoeffDescription(i,desc);
+     218             :     }
+     219             :   }
+     220           0 :   else if(coeffs_type_==MultiCoeffs_LinearBasisSet) {
+     221           0 :     for(unsigned int i=0; i<numberOfCoeffs(); i++) {
+     222           0 :       std::vector<unsigned int> indices=getIndices(i);
+     223           0 :       unsigned int mc_id = indices[ndimensions_-1];
+     224             :       std::string mc_idstr;
+     225           0 :       Tools::convert(mc_id,mc_idstr);
+     226             :       // std::string mc_label = getDimensionLabel(ndimensions_-1);
+     227           0 :       std::string postfix = ":" + mc_idstr;
+     228           0 :       std::string desc ="";
+     229           0 :       desc+=multicoeffs_basisf_[mc_id][0]->getBasisFunctionLabel(indices[0]);
+     230           0 :       for(unsigned int k=1; k<(numberOfDimensions()-1); k++) {
+     231           0 :         desc+="*"+multicoeffs_basisf_[mc_id][k]->getBasisFunctionLabel(indices[k]);
+     232             :       }
+     233             :       desc+=postfix;
+     234           0 :       setCoeffDescription(i,desc);
+     235             :     }
+     236             :   }
+     237         377 : }
+     238             : 
+     239             : 
+     240           0 : void CoeffsBase::resizeIndices(const std::vector<unsigned int>& indices_shape_new) {
+     241           0 :   plumed_massert(coeffs_type_==Generic,"Coeffs type must be Generic when resizeing based on a new indices shape vector");
+     242           0 :   reinitializeIndices(indices_shape_new);
+     243           0 :   setAllCoeffsDescriptions();
+     244           0 : }
+     245             : 
+     246             : 
+     247           0 : void CoeffsBase::resizeIndices(std::vector<BasisFunctions*>& basisf_new) {
+     248           0 :   plumed_massert(coeffs_type_==LinearBasisSet,"Coeffs type must be LinearBasisSet when resizeing based on a new basis function set");
+     249           0 :   basisf_=basisf_new;
+     250           0 :   std::vector<unsigned int> indices_shape_new(basisf_new.size());
+     251           0 :   for(unsigned int i=0; i<basisf_new.size(); i++) {
+     252           0 :     indices_shape_new[i]=basisf_new[i]->getNumberOfBasisFunctions();
+     253             :   }
+     254           0 :   reinitializeIndices(indices_shape_new);
+     255           0 :   setupBasisFunctionsInfo();
+     256           0 : }
+     257             : 
+     258             : 
+     259           6 : bool CoeffsBase::sameShape(const CoeffsBase& coeffsbase_in) const {
+     260           6 :   if(numberOfDimensions()!=coeffsbase_in.numberOfDimensions()) {
+     261             :     return false;
+     262             :   }
+     263           6 :   if(numberOfCoeffs()!=coeffsbase_in.numberOfCoeffs()) {
+     264             :     return false;
+     265             :   }
+     266          12 :   for(unsigned int k=0; k<numberOfDimensions(); k++) {
+     267           6 :     if(shapeOfIndices(k)!=coeffsbase_in.shapeOfIndices(k)) {
+     268             :       return false;
+     269             :     }
+     270             :   }
+     271             :   return true;
+     272             : }
+     273             : 
+     274             : 
+     275           0 : void CoeffsBase::setLabel(const std::string& label) {
+     276           0 :   label_=label;
+     277           0 : }
+     278             : 
+     279             : 
+     280           0 : void CoeffsBase::setDataLabel(const std::string& data_label) {
+     281           0 :   data_label_=data_label;
+     282           0 : }
+     283             : 
+     284             : 
+     285         754 : void CoeffsBase::setLabels(const std::string& label) {
+     286         754 :   label_=label;
+     287         754 :   data_label_=label;
+     288         754 : }
+     289             : 
+     290             : 
+     291           0 : void CoeffsBase::setLabels(const std::string& label, const std::string& data_label) {
+     292           0 :   label_=label;
+     293           0 :   data_label_=data_label;
+     294           0 : }
+     295             : 
+     296             : 
+     297        3376 : std::string CoeffsBase::getTypeStr() const {
+     298        3376 :   std::string type_str="";
+     299        3376 :   if(coeffs_type_==Generic) {
+     300             :     type_str = "Generic";
+     301             :   }
+     302        3376 :   else if(coeffs_type_==LinearBasisSet) {
+     303             :     type_str = "LinearBasisSet";
+     304             :   }
+     305           0 :   else if(coeffs_type_==MultiCoeffs_LinearBasisSet) {
+     306             :     type_str = "MultiCoeffs_LinearBasisSet";
+     307             :   }
+     308        3376 :   return type_str;
+     309             : }
+     310             : 
+     311             : 
+     312           0 : void CoeffsBase::setType(const CoeffsType coeffs_type) {
+     313           0 :   coeffs_type_=coeffs_type;
+     314           0 : }
+     315             : 
+     316             : 
+     317          90 : void CoeffsBase::linkVesBias(VesBias* vesbias_pntr_in) {
+     318          90 :   vesbias_pntr_ = vesbias_pntr_in;
+     319          90 :   action_pntr_ = static_cast<Action*>(vesbias_pntr_in);
+     320          90 : }
+     321             : 
+     322             : 
+     323           0 : void CoeffsBase::linkAction(Action* action_pntr_in) {
+     324           0 :   action_pntr_ = action_pntr_in;
+     325           0 : }
+     326             : 
+     327             : 
+     328           0 : bool CoeffsBase::indicesExist(const std::vector<unsigned int>& indices) const {
+     329             :   plumed_dbg_assert(indices.size()==ndimensions_);
+     330           0 :   for(unsigned int k=0; k<ndimensions_; k++) {
+     331           0 :     if(indices[k]>=indices_shape_[k]) {
+     332             :       return false;
+     333             :     }
+     334             :   }
+     335             :   return true;
+     336             : }
+     337             : 
+     338             : 
+     339        8928 : void CoeffsBase::setCoeffDescription(const size_t index, const std::string& description) {
+     340             :   coeffs_descriptions_[index]=description;
+     341        8928 : }
+     342             : 
+     343             : 
+     344           0 : void CoeffsBase::setCoeffDescription(const std::vector<unsigned int>& indices, const std::string& description) {
+     345           0 :   setCoeffDescription(getIndex(indices), description);
+     346           0 : }
+     347             : 
+     348             : 
+     349           0 : void CoeffsBase::setAllCoeffsDescriptions(const std::string& description_prefix) {
+     350           0 :   for(size_t i=0; i<numberOfCoeffs(); i++) {
+     351           0 :     std::vector<unsigned int> indices=getIndices(i);
+     352           0 :     std::string is; Tools::convert(indices[0],is);
+     353           0 :     std::string desc=description_prefix+"("+is;
+     354           0 :     for(unsigned int k=1; k<numberOfDimensions(); k++) {
+     355           0 :       Tools::convert(indices[k],is); desc+=","+is;
+     356             :     }
+     357             :     desc+=")";
+     358             :     coeffs_descriptions_[i]=desc;
+     359             :   }
+     360           0 : }
+     361             : 
+     362             : 
+     363           0 : void CoeffsBase::setAllCoeffsDescriptions(const std::vector<std::string>& coeffs_descriptions) {
+     364           0 :   plumed_massert(coeffs_descriptions.size()==numberOfCoeffs(),"The coeffs description vector doesn't match the number of coeffs");
+     365           0 :   for(size_t i=0; i<numberOfCoeffs(); i++) {
+     366             :     coeffs_descriptions_[i]=coeffs_descriptions[i];
+     367             :   }
+     368           0 : }
+     369             : 
+     370             : 
+     371           0 : void CoeffsBase::setDimensionLabel(const unsigned int dim_index, const std::string& label) {
+     372           0 :   plumed_massert(dim_index<numberOfDimensions(),"Trying to set the label of a dimension outside the number of dimensions");
+     373           0 :   dimension_labels_[dim_index]=label;
+     374           0 : }
+     375             : 
+     376             : 
+     377           0 : void CoeffsBase::setAllDimensionLabels(const std::string& label_prefix) {
+     378           0 :   for(unsigned int i=0; i<numberOfDimensions(); i++) {
+     379           0 :     std::string is; Tools::convert(i,is);
+     380           0 :     dimension_labels_[i]=label_prefix + is;
+     381             :   }
+     382           0 : }
+     383             : 
+     384             : 
+     385           0 : void CoeffsBase::setAllDimensionLabels(const std::vector<std::string>& labels) {
+     386           0 :   for(unsigned int i=0; i<numberOfDimensions(); i++) {
+     387           0 :     dimension_labels_[i]=labels[i];
+     388             :   }
+     389           0 : }
+     390             : 
+     391             : 
+     392        3008 : void CoeffsBase::writeCoeffsInfoToFile(OFile& ofile) const {
+     393        3008 :   ofile.addConstantField(field_type_).printField(field_type_,getTypeStr());
+     394        3008 :   ofile.addConstantField(field_ndimensions_).printField(field_ndimensions_,(int) numberOfDimensions());
+     395        3008 :   ofile.addConstantField(field_ncoeffs_total_).printField(field_ncoeffs_total_,(int) numberOfCoeffs());
+     396        6780 :   for(unsigned int k=0; k<numberOfDimensions(); k++) {
+     397        7544 :     ofile.addConstantField(field_shape_prefix_+getDimensionLabel(k));
+     398        7544 :     ofile.printField(field_shape_prefix_+getDimensionLabel(k),(int) shapeOfIndices(k));
+     399             :   }
+     400        3008 : }
+     401             : 
+     402             : 
+     403         368 : void CoeffsBase::getCoeffsInfoFromFile(IFile& ifile, const bool ignore_coeffs_info) {
+     404             :   int int_tmp;
+     405             :   // label
+     406             :   std::string coeffs_type_f;
+     407         368 :   if(ifile.scanField(field_type_,coeffs_type_f)) {
+     408             :     // empty for now
+     409             :   }
+     410             :   else {
+     411             :     return;
+     412             :   }
+     413             :   // number of dimensions
+     414             :   unsigned int ndimensions_f = 0;
+     415         368 :   if(ifile.scanField(field_ndimensions_,int_tmp)) {
+     416         368 :     ndimensions_f=(unsigned int) int_tmp;
+     417             :   }
+     418             :   else {
+     419             :     return;
+     420             :   }
+     421             :   // total number of coeffs
+     422             :   size_t ncoeffs_total_f = 0;
+     423         368 :   if(ifile.scanField(field_ncoeffs_total_,int_tmp)) {
+     424         368 :     ncoeffs_total_f=(size_t) int_tmp;
+     425             :   }
+     426             :   else {
+     427             :     return;
+     428             :   }
+     429             :   // shape of indices
+     430         368 :   std::vector<unsigned int> indices_shape_f(numberOfDimensions());
+     431         747 :   for(unsigned int k=0; k<numberOfDimensions(); k++) {
+     432         758 :     if(ifile.scanField(field_shape_prefix_+getDimensionLabel(k),int_tmp)) {
+     433         379 :       indices_shape_f[k]=(unsigned int) int_tmp;
+     434             :     }
+     435             :     else {
+     436             :       return;
+     437             :     }
+     438             :   }
+     439         368 :   if(!ignore_coeffs_info) {
+     440         736 :     std::string msg_header="Error when reading in coeffs from file " + ifile.getPath() + ": ";
+     441         368 :     checkCoeffsInfo(msg_header, coeffs_type_f, ndimensions_f, ncoeffs_total_f, indices_shape_f);
+     442             :   }
+     443             : }
+     444             : 
+     445             : 
+     446         368 : void CoeffsBase::checkCoeffsInfo(const std::string& msg_header, const std::string& coeffs_type_f, const unsigned int ndimensions_f, const size_t ncoeffs_total_f, const std::vector<unsigned int>& indices_shape_f) {
+     447             : 
+     448         736 :   if(coeffs_type_f != getTypeStr()) {
+     449           0 :     std::string msg = msg_header + " coeffs type " + coeffs_type_f + " from file doesn't match the defined value " + getTypeStr();
+     450           0 :     plumed_merror(msg);
+     451             :   }
+     452         368 :   if(ndimensions_f != numberOfDimensions() ) {
+     453           0 :     std::string s1; Tools::convert(ndimensions_f,s1);
+     454           0 :     std::string s2; Tools::convert(numberOfDimensions(),s2);
+     455           0 :     std::string msg = msg_header + " the number of dimensions " + s1 + " in file doesn't match the defined value " + s2;
+     456           0 :     plumed_merror(msg);
+     457             :   }
+     458         368 :   if(ncoeffs_total_f != numberOfCoeffs() ) {
+     459           0 :     std::string s1; Tools::convert(ncoeffs_total_f,s1);
+     460           0 :     std::string s2; Tools::convert(numberOfCoeffs(),s2);
+     461           0 :     std::string msg = msg_header + " the number of coeffs " + s1 + " in file doesn't match the defined value " + s2;
+     462           0 :     plumed_merror(msg);
+     463             :   }
+     464         747 :   for(unsigned int k=0; k<numberOfDimensions(); k++) {
+     465         379 :     if(indices_shape_f[k] != shapeOfIndices(k) ) {
+     466           0 :       std::string s1; Tools::convert(indices_shape_f[k],s1);
+     467           0 :       std::string s2; Tools::convert(shapeOfIndices(k),s2);
+     468           0 :       std::string msg = msg_header + " for dimension labeled " + getDimensionLabel(k) + " the shape of indices " + s1 + " in file doesn't match defined value " + s2;
+     469           0 :       plumed_merror(msg);
+     470             :     }
+     471             :   }
+     472         368 : }
+     473             : 
+     474             : 
+     475        2721 : void CoeffsBase::writeIterationCounterAndTimeToFile(OFile& ofile) const {
+     476        2721 :   if(time_md>=0.0) {
+     477        2721 :     ofile.fmtField("%f");
+     478        2721 :     ofile.addConstantField(field_time_).printField(field_time_,time_md);
+     479        2721 :     ofile.fmtField();
+     480             :   }
+     481        2721 :   ofile.addConstantField(field_iteration_).printField(field_iteration_,(int) iteration_opt);
+     482        2721 : }
+     483             : 
+     484             : 
+     485         406 : bool CoeffsBase::getIterationCounterAndTimeFromFile(IFile& ifile) {
+     486             :   bool field_found=false;
+     487         406 :   if(ifile.FieldExist(field_time_)) {
+     488             :     field_found=true;
+     489             :     double time_tmp;
+     490         368 :     ifile.scanField(field_time_,time_tmp);
+     491         368 :     time_md=time_tmp;
+     492             :   }
+     493         406 :   if(ifile.FieldExist(field_iteration_)) {
+     494             :     field_found=true;
+     495             :     int iter_tmp;
+     496         368 :     ifile.scanField(field_iteration_,iter_tmp);
+     497         368 :     iteration_opt=(unsigned int) iter_tmp;
+     498             :   }
+     499         406 :   return field_found;
+     500             : }
+     501             : 
+     502             : 
+     503             : // replace string in Label, if old string was not found simply add the new string to the label
+     504           5 : void CoeffsBase::replaceLabelString(const std::string& oldstring, const std::string& newstring) {
+     505             :   std::string label = getLabel();
+     506           5 :   if(label.find(oldstring)!=std::string::npos) {
+     507           8 :     label.replace(label.find(oldstring), std::string(oldstring).length(), newstring);
+     508             :   }
+     509             :   else {
+     510           2 :     label += "_" + newstring;
+     511             :   }
+     512           5 :   setLabels(label);
+     513           5 : }
+     514             : 
+     515             : 
+     516             : }
+     517             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/CoeffsBase.h.func-sort-c.html b/coverage/ves/CoeffsBase.h.func-sort-c.html new file mode 100644 index 000000000000..26e775cce642 --- /dev/null +++ b/coverage/ves/CoeffsBase.h.func-sort-c.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - ves/CoeffsBase.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - CoeffsBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3333100.0 %
Date:2024-04-19 12:12:35Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD3ves10CoeffsBase8getIndexERKSt6vectorIjSaIjEE10870
_ZNK4PLMD3ves10CoeffsBase10getIndicesEm237974265
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/CoeffsBase.h.func.html b/coverage/ves/CoeffsBase.h.func.html new file mode 100644 index 000000000000..83381d9190b5 --- /dev/null +++ b/coverage/ves/CoeffsBase.h.func.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - ves/CoeffsBase.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - CoeffsBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3333100.0 %
Date:2024-04-19 12:12:35Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD3ves10CoeffsBase10getIndicesEm237974265
_ZNK4PLMD3ves10CoeffsBase8getIndexERKSt6vectorIjSaIjEE10870
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/CoeffsBase.h.gcov.html b/coverage/ves/CoeffsBase.h.gcov.html new file mode 100644 index 000000000000..933997041d60 --- /dev/null +++ b/coverage/ves/CoeffsBase.h.gcov.html @@ -0,0 +1,336 @@ + + + + + + + + LCOV - plumed test coverage - ves/CoeffsBase.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - CoeffsBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3333100.0 %
Date:2024-04-19 12:12:35Functions:22100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_ves_CoeffsBase_h
+      23             : #define __PLUMED_ves_CoeffsBase_h
+      24             : 
+      25             : #include <vector>
+      26             : #include <string>
+      27             : 
+      28             : 
+      29             : namespace PLMD {
+      30             : 
+      31             : class Action;
+      32             : class Value;
+      33             : class IFile;
+      34             : class OFile;
+      35             : 
+      36             : namespace ves {
+      37             : 
+      38             : class BasisFunctions;
+      39             : class VesBias;
+      40             : 
+      41             : /// \ingroup TOOLBOX
+      42             : class CoeffsBase
+      43             : {
+      44             : public:
+      45             :   // the type of 1D index
+      46             :   // typedef size_t index_t;
+      47             :   // typedef unsigned int index_t;
+      48             : private:
+      49             :   std::string label_;
+      50             :   std::string data_label_;
+      51             :   enum CoeffsType {
+      52             :     Generic,
+      53             :     LinearBasisSet,
+      54             :     MultiCoeffs_LinearBasisSet
+      55             :   } coeffs_type_;
+      56             :   //
+      57             :   bool iteration_and_time_active_;
+      58             :   unsigned int iteration_opt;
+      59             :   double time_md;
+      60             :   //
+      61             :   bool active;
+      62             :   //
+      63             :   Action* action_pntr_;
+      64             :   VesBias* vesbias_pntr_;
+      65             :   //
+      66             :   unsigned int ndimensions_;
+      67             :   std::vector<unsigned int> indices_shape_;
+      68             :   size_t ncoeffs_;
+      69             :   std::vector<std::string> coeffs_descriptions_;
+      70             :   std::vector<std::string> dimension_labels_;
+      71             :   //
+      72             :   std::vector<Value*> args_;
+      73             :   std::vector<BasisFunctions*> basisf_;
+      74             :   //
+      75             :   bool multicoeffs_;
+      76             :   std::vector<std::vector<Value*> > multicoeffs_args_;
+      77             :   std::vector<std::vector<BasisFunctions*> >multicoeffs_basisf_;
+      78             :   // Labels for fields in output/input files
+      79             :   const std::string field_type_;
+      80             :   const std::string field_ndimensions_;
+      81             :   const std::string field_ncoeffs_total_;
+      82             :   const std::string field_shape_prefix_;
+      83             :   const std::string field_time_;
+      84             :   const std::string field_iteration_;
+      85             :   //
+      86             :   std::string output_fmt_;
+      87             :   //
+      88             :   void initializeIndices(const std::vector<unsigned int>&, const std::vector<std::string>&);
+      89             :   void reinitializeIndices(const std::vector<unsigned int>&);
+      90             : public:
+      91             :   explicit CoeffsBase();
+      92             :   //
+      93             :   explicit CoeffsBase(
+      94             :     const std::string&,
+      95             :     const std::vector<std::string>&,
+      96             :     const std::vector<unsigned int>&,
+      97             :     const bool use_iteration_counter=false);
+      98             :   //
+      99             :   explicit CoeffsBase(
+     100             :     const std::string&,
+     101             :     const std::vector<Value*>&,
+     102             :     std::vector<BasisFunctions*>&,
+     103             :     const bool use_iteration_counter=false);
+     104             :   //
+     105             :   explicit CoeffsBase(
+     106             :     const std::string&,
+     107             :     std::vector<std::vector<Value*> >&,
+     108             :     std::vector<std::vector<BasisFunctions*> >&,
+     109             :     const bool use_iteration_counter=false,
+     110             :     const std::string& multicoeffs_label="bias"
+     111             :   );
+     112             :   //
+     113             :   ~CoeffsBase();
+     114             :   //
+     115         228 :   std::string getLabel() const {return label_;}
+     116             :   void setLabel(const std::string&);
+     117        4366 :   std::string getDataLabel() const {return data_label_;};
+     118             :   void setDataLabel(const std::string&);
+     119             :   void setLabels(const std::string&);
+     120             :   void setLabels(const std::string&, const std::string&);
+     121             :   //
+     122             :   CoeffsType getType() const {return coeffs_type_;}
+     123             :   std::string getTypeStr() const;
+     124             :   void setType(const CoeffsType coeffs_type);
+     125             :   void linkVesBias(VesBias*);
+     126             :   void linkAction(Action*);
+     127             :   VesBias* getPntrToVesBias() const {return vesbias_pntr_;}
+     128           9 :   Action* getPntrToAction() const {return action_pntr_;}
+     129             :   bool isGenericCoeffs() const {return coeffs_type_==Generic;}
+     130             :   bool isLinearBasisSetCoeffs() const {return coeffs_type_==LinearBasisSet;}
+     131             :   bool isMultiLinearBasisSetCoeffs() const {return coeffs_type_==MultiCoeffs_LinearBasisSet;}
+     132             :   //
+     133             :   std::vector<unsigned int> shapeOfIndices() const {return indices_shape_;}
+     134        4157 :   unsigned int shapeOfIndices(const unsigned int dim_index) const {return indices_shape_[dim_index];}
+     135   243037069 :   size_t numberOfCoeffs() const {return ncoeffs_;}
+     136     2992522 :   unsigned int numberOfDimensions() const {return ndimensions_;}
+     137             :   //
+     138       22810 :   bool isActive() const {return active;}
+     139       22810 :   void activate() {active=true;}
+     140          95 :   void deactivate() {active=false;}
+     141             :   //
+     142             :   size_t getIndex(const std::vector<unsigned int>&) const;
+     143             :   std::vector<unsigned int> getIndices(const size_t) const;
+     144             :   bool indicesExist(const std::vector<unsigned int>&) const;
+     145             :   //
+     146             :   std::string getCoeffDescription(const size_t index) const {return coeffs_descriptions_[index];}
+     147             :   std::string getCoeffDescription(const std::vector<unsigned int>&) const;
+     148        2348 :   std::vector<std::string> getAllCoeffsDescriptions() const {return coeffs_descriptions_;}
+     149             :   void setCoeffDescription(const size_t, const std::string&);
+     150             :   void setCoeffDescription(const std::vector<unsigned int>&, const std::string&);
+     151             :   void setAllCoeffsDescriptions(const std::string& description_prefix="C");
+     152             :   void setAllCoeffsDescriptions(const std::vector<std::string>&);
+     153             :   //
+     154             :   std::string getDimensionLabel(const unsigned int) const;
+     155             :   std::vector<std::string> getAllDimensionLabels() const {return dimension_labels_;}
+     156             :   void setDimensionLabel(const unsigned int, const std::string&);
+     157             :   void setAllDimensionLabels(const std::string&);
+     158             :   void setAllDimensionLabels(const std::vector<std::string>&);
+     159             :   void writeCoeffsInfoToFile(OFile&) const;
+     160             :   void writeTimeInfoToFile(OFile&, const double) const;
+     161             :   void getCoeffsInfoFromFile(IFile&, const bool ignore_coeffs_info=false);
+     162             :   void checkCoeffsInfo(const std::string&, const std::string&, const unsigned int, const size_t, const std::vector<unsigned int>&);
+     163             :   //
+     164         167 :   void turnOnIterationCounter() {iteration_and_time_active_=true;}
+     165             :   void turnOffIterationCounter() {iteration_and_time_active_=false;}
+     166        3414 :   bool isIterationCounterActive() const {return iteration_and_time_active_;}
+     167             :   void setIterationCounter(const unsigned int);
+     168             :   void setTime(const double);
+     169             :   void setIterationCounterAndTime(const unsigned int, const double);
+     170         161 :   unsigned int getIterationCounter() const {return iteration_opt;}
+     171             :   double getTimeValue() const {return time_md;}
+     172             :   //
+     173         679 :   void setOutputFmt(const std::string& ss) { output_fmt_=ss; }
+     174             :   void resetOutputFmt() {output_fmt_="%30.16e";}
+     175       29978 :   std::string getOutputFmt() const {return output_fmt_;}
+     176             :   //
+     177             :   void replaceLabelString(const std::string&, const std::string&);
+     178             : protected:
+     179             :   void setupBasisFunctionsInfo();
+     180             :   void resizeIndices(const std::vector<unsigned int>&);
+     181             :   void resizeIndices(std::vector<BasisFunctions*>&);
+     182             :   bool sameShape(const CoeffsBase&) const;
+     183             :   //
+     184             :   void writeIterationCounterAndTimeToFile(OFile&) const;
+     185             :   bool getIterationCounterAndTimeFromFile(IFile&);
+     186             :   //
+     187             : 
+     188             : };
+     189             : 
+     190             : inline
+     191             : void CoeffsBase::setIterationCounter(const unsigned int iteration_opt_in) {
+     192             :   iteration_opt=iteration_opt_in;
+     193             : }
+     194             : 
+     195             : inline
+     196             : void CoeffsBase::setTime(const double time_md_in) {
+     197             :   time_md=time_md_in;
+     198             : }
+     199             : 
+     200             : inline
+     201             : void CoeffsBase::setIterationCounterAndTime(const unsigned int iteration_opt_in, const double time_md_in) {
+     202       46613 :   iteration_opt=iteration_opt_in;
+     203       23077 :   time_md=time_md_in;
+     204       22780 : }
+     205             : 
+     206             : inline
+     207             : std::string CoeffsBase::getCoeffDescription(const std::vector<unsigned int>& indices) const {
+     208             :   return getCoeffDescription(getIndex(indices));
+     209             : }
+     210             : 
+     211             : inline
+     212             : std::string CoeffsBase::getDimensionLabel(const unsigned int dim_index) const {
+     213             :   // plumed_massert(dim_index<numberOfDimensions(),"Trying to get the label of a dimension outside the number of dimensions");
+     214       12156 :   return dimension_labels_[dim_index];
+     215             : }
+     216             : 
+     217             : 
+     218             : // we are flattening arrays using a column-major order
+     219             : inline
+     220       10870 : size_t CoeffsBase::getIndex(const std::vector<unsigned int>& indices) const {
+     221             :   // plumed_dbg_assert(indices.size()==ndimensions_);
+     222             :   // for(unsigned int i=0; i<ndimensions_; i++){
+     223             :   //   if(indices[i]>=indices_shape_[i]){
+     224             :   //     std::string is;
+     225             :   //     Tools::convert(i,is);
+     226             :   //     std::string msg="ERROR: the system is looking for a value outside the indices along the " + is + "dimension!";
+     227             :   //     plumed_merror(msg);
+     228             :   //   }
+     229             :   // }
+     230       10870 :   size_t index=indices[ndimensions_-1];
+     231       13392 :   for(unsigned int i=ndimensions_-1; i>0; --i) {
+     232        2522 :     index=index*indices_shape_[i-1]+indices[i-1];
+     233             :   }
+     234       10870 :   return index;
+     235             : }
+     236             : 
+     237             : // we are flattening arrays using a column-major order
+     238             : inline
+     239   237974265 : std::vector<unsigned int> CoeffsBase::getIndices(const size_t index) const {
+     240   237974265 :   std::vector<unsigned int> indices(ndimensions_);
+     241             :   size_t kk=index;
+     242   237974265 :   indices[0]=(index%indices_shape_[0]);
+     243   258960719 :   for(unsigned int i=1; i<ndimensions_-1; ++i) {
+     244    20986454 :     kk=(kk-indices[i-1])/indices_shape_[i-1];
+     245    20986454 :     indices[i]=(kk%indices_shape_[i]);
+     246             :   }
+     247   237974265 :   if(ndimensions_>=2) {
+     248   236955949 :     indices[ndimensions_-1]=((kk-indices[ndimensions_-2])/indices_shape_[ndimensions_-2]);
+     249             :   }
+     250   237974265 :   return indices;
+     251             : }
+     252             : 
+     253             : 
+     254             : 
+     255             : 
+     256             : }
+     257             : }
+     258             : 
+     259             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/CoeffsMatrix.cpp.func-sort-c.html b/coverage/ves/CoeffsMatrix.cpp.func-sort-c.html new file mode 100644 index 000000000000..e37f2e6a4ca8 --- /dev/null +++ b/coverage/ves/CoeffsMatrix.cpp.func-sort-c.html @@ -0,0 +1,389 @@ + + + + + + + + LCOV - plumed test coverage - ves/CoeffsMatrix.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - CoeffsMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10535629.5 %
Date:2024-04-19 12:12:35Functions:207925.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12CoeffsMatrix10addToValueERKSt6vectorIjSaIjEES6_d0
_ZN4PLMD3ves12CoeffsMatrix10addToValueEmmd0
_ZN4PLMD3ves12CoeffsMatrix10sumCommMPIERNS_12CommunicatorE0
_ZN4PLMD3ves12CoeffsMatrix10sumCommMPIEv0
_ZN4PLMD3ves12CoeffsMatrix11addToValuesERKS1_0
_ZN4PLMD3ves12CoeffsMatrix11addToValuesERKSt6vectorIdSaIdEE0
_ZN4PLMD3ves12CoeffsMatrix11addToValuesEd0
_ZN4PLMD3ves12CoeffsMatrix11writeToFileERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbPNS_6ActionE0
_ZN4PLMD3ves12CoeffsMatrix12addToAverageERKS1_0
_ZN4PLMD3ves12CoeffsMatrix14resetAveragingEv0
_ZN4PLMD3ves12CoeffsMatrix15averageMatricesERKSt6vectorIPS1_SaIS3_EE0
_ZN4PLMD3ves12CoeffsMatrix15averageMatricesERS1_S2_0
_ZN4PLMD3ves12CoeffsMatrix18setAllValuesToZeroEv0
_ZN4PLMD3ves12CoeffsMatrix18subtractFromValuesERKS1_0
_ZN4PLMD3ves12CoeffsMatrix18subtractFromValuesERKSt6vectorIdSaIdEE0
_ZN4PLMD3ves12CoeffsMatrix18subtractFromValuesEd0
_ZN4PLMD3ves12CoeffsMatrix18sumMultiSimCommMPIERNS_12CommunicatorE0
_ZN4PLMD3ves12CoeffsMatrix19writeDataFullToFileERNS_5OFileE0
_ZN4PLMD3ves12CoeffsMatrix23randomizeValuesGaussianEi0
_ZN4PLMD3ves12CoeffsMatrix8setValueERKSt6vectorIjSaIjEES6_d0
_ZN4PLMD3ves12CoeffsMatrix9sameShapeERNS0_12CoeffsVectorERS1_0
_ZN4PLMD3ves12CoeffsMatrix9sameShapeERS1_RNS0_12CoeffsVectorE0
_ZN4PLMD3ves12CoeffsMatrix9sameShapeERS1_S2_0
_ZN4PLMD3ves12CoeffsMatrix9setValuesERKS1_0
_ZN4PLMD3ves12CoeffsMatrix9setValuesEd0
_ZN4PLMD3ves12CoeffsMatrixC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIS7_SaIS7_EERKSA_IjSaIjEERNS_12CommunicatorEbb0
_ZN4PLMD3ves12CoeffsMatrixC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIPNS_5ValueESaISC_EERSA_IPNS0_14BasisFunctionsESaISH_EERNS_12CommunicatorEbb0
_ZN4PLMD3ves12CoeffsMatrixC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorISA_IPNS_5ValueESaISC_EESaISE_EERSA_ISA_IPNS0_14BasisFunctionsESaISJ_EESaISL_EERNS_12CommunicatorEbbS9_0
_ZN4PLMD3ves12CoeffsMatrixaSEd0
_ZN4PLMD3ves12CoeffsMatrixclERKSt6vectorIjSaIjEES6_0
_ZN4PLMD3ves12CoeffsMatrixclEmm0
_ZN4PLMD3ves12CoeffsMatrixmIERKS1_0
_ZN4PLMD3ves12CoeffsMatrixmIERKSt6vectorIdSaIdEE0
_ZN4PLMD3ves12CoeffsMatrixmIEd0
_ZN4PLMD3ves12CoeffsMatrixmLERKS1_0
_ZN4PLMD3ves12CoeffsMatrixpLERKS1_0
_ZN4PLMD3ves12CoeffsMatrixpLERKSt6vectorIdSaIdEE0
_ZN4PLMD3ves12CoeffsMatrixpLEd0
_ZN4PLMD3vesmiERKNS0_12CoeffsMatrixERKSt6vectorIdSaIdEE0
_ZN4PLMD3vesmiERKNS0_12CoeffsMatrixEd0
_ZN4PLMD3vesmiERKSt6vectorIdSaIdEERKNS0_12CoeffsMatrixE0
_ZN4PLMD3vesmiEdRKNS0_12CoeffsMatrixE0
_ZN4PLMD3vesmlERKNS0_12CoeffsMatrixEd0
_ZN4PLMD3vesmlEdRKNS0_12CoeffsMatrixE0
_ZN4PLMD3vesplERKNS0_12CoeffsMatrixERKSt6vectorIdSaIdEE0
_ZN4PLMD3vesplERKNS0_12CoeffsMatrixEd0
_ZN4PLMD3vesplERKSt6vectorIdSaIdEERKNS0_12CoeffsMatrixE0
_ZN4PLMD3vesplEdRKNS0_12CoeffsMatrixE0
_ZNK4PLMD3ves12CoeffsMatrix11getMaxValueEv0
_ZNK4PLMD3ves12CoeffsMatrix11getMinValueEv0
_ZNK4PLMD3ves12CoeffsMatrix8getValueERKSt6vectorIjSaIjEES6_0
_ZNK4PLMD3ves12CoeffsMatrix9sameShapeERNS0_12CoeffsVectorE0
_ZNK4PLMD3ves12CoeffsMatrix9sameShapeERS1_0
_ZNK4PLMD3ves12CoeffsMatrixclERKSt6vectorIjSaIjEES6_0
_ZNK4PLMD3ves12CoeffsMatrixmiERKS1_0
_ZNK4PLMD3ves12CoeffsMatrixmlERKS1_0
_ZNK4PLMD3ves12CoeffsMatrixngEv0
_ZNK4PLMD3ves12CoeffsMatrixplERKS1_0
_ZNK4PLMD3ves12CoeffsMatrixpsEv0
_ZN4PLMD3ves12CoeffsMatrix11setupMatrixEv172
_ZN4PLMD3ves12CoeffsMatrixC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPNS0_12CoeffsVectorERNS_12CommunicatorEb172
_ZN4PLMD3ves12CoeffsMatrixD2Ev172
_ZN4PLMD3ves12CoeffsMatrix8setValueEmmd219
_ZN4PLMD3ves12CoeffsMatrix5clearEv267
_ZNK4PLMD3ves12CoeffsMatrix7getSizeEv439
_ZN4PLMD3ves12CoeffsMatrix11writeToFileERNS_5OFileE660
_ZN4PLMD3ves12CoeffsMatrix15writeDataToFileERNS_5OFileE660
_ZN4PLMD3ves12CoeffsMatrix17writeHeaderToFileERNS_5OFileE660
_ZN4PLMD3ves12CoeffsMatrix21writeMatrixInfoToFileERNS_5OFileE660
_ZN4PLMD3ves12CoeffsMatrix23writeDataDiagonalToFileERNS_5OFileE660
_ZN4PLMD3vesmlERKNS0_12CoeffsMatrixERKNS0_12CoeffsVectorE22735
_ZN4PLMD3ves12CoeffsMatrix14scaleAllValuesEd22810
_ZN4PLMD3ves12CoeffsMatrix9setValuesERKSt6vectorIdSaIdEE22810
_ZN4PLMD3ves12CoeffsMatrixaSERKSt6vectorIdSaIdEE22810
_ZN4PLMD3ves12CoeffsMatrixmLEd22810
_ZNK4PLMD3ves12CoeffsMatrix10isDiagonalEv23395
_ZNK4PLMD3ves12CoeffsMatrix8getValueEmm27630
_ZNK4PLMD3ves12CoeffsMatrixclEmm1790345
_ZNK4PLMD3ves12CoeffsMatrix14getMatrixIndexEmm5425906
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/CoeffsMatrix.cpp.func.html b/coverage/ves/CoeffsMatrix.cpp.func.html new file mode 100644 index 000000000000..c2741978ca57 --- /dev/null +++ b/coverage/ves/CoeffsMatrix.cpp.func.html @@ -0,0 +1,389 @@ + + + + + + + + LCOV - plumed test coverage - ves/CoeffsMatrix.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - CoeffsMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10535629.5 %
Date:2024-04-19 12:12:35Functions:207925.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12CoeffsMatrix10addToValueERKSt6vectorIjSaIjEES6_d0
_ZN4PLMD3ves12CoeffsMatrix10addToValueEmmd0
_ZN4PLMD3ves12CoeffsMatrix10sumCommMPIERNS_12CommunicatorE0
_ZN4PLMD3ves12CoeffsMatrix10sumCommMPIEv0
_ZN4PLMD3ves12CoeffsMatrix11addToValuesERKS1_0
_ZN4PLMD3ves12CoeffsMatrix11addToValuesERKSt6vectorIdSaIdEE0
_ZN4PLMD3ves12CoeffsMatrix11addToValuesEd0
_ZN4PLMD3ves12CoeffsMatrix11setupMatrixEv172
_ZN4PLMD3ves12CoeffsMatrix11writeToFileERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbPNS_6ActionE0
_ZN4PLMD3ves12CoeffsMatrix11writeToFileERNS_5OFileE660
_ZN4PLMD3ves12CoeffsMatrix12addToAverageERKS1_0
_ZN4PLMD3ves12CoeffsMatrix14resetAveragingEv0
_ZN4PLMD3ves12CoeffsMatrix14scaleAllValuesEd22810
_ZN4PLMD3ves12CoeffsMatrix15averageMatricesERKSt6vectorIPS1_SaIS3_EE0
_ZN4PLMD3ves12CoeffsMatrix15averageMatricesERS1_S2_0
_ZN4PLMD3ves12CoeffsMatrix15writeDataToFileERNS_5OFileE660
_ZN4PLMD3ves12CoeffsMatrix17writeHeaderToFileERNS_5OFileE660
_ZN4PLMD3ves12CoeffsMatrix18setAllValuesToZeroEv0
_ZN4PLMD3ves12CoeffsMatrix18subtractFromValuesERKS1_0
_ZN4PLMD3ves12CoeffsMatrix18subtractFromValuesERKSt6vectorIdSaIdEE0
_ZN4PLMD3ves12CoeffsMatrix18subtractFromValuesEd0
_ZN4PLMD3ves12CoeffsMatrix18sumMultiSimCommMPIERNS_12CommunicatorE0
_ZN4PLMD3ves12CoeffsMatrix19writeDataFullToFileERNS_5OFileE0
_ZN4PLMD3ves12CoeffsMatrix21writeMatrixInfoToFileERNS_5OFileE660
_ZN4PLMD3ves12CoeffsMatrix23randomizeValuesGaussianEi0
_ZN4PLMD3ves12CoeffsMatrix23writeDataDiagonalToFileERNS_5OFileE660
_ZN4PLMD3ves12CoeffsMatrix5clearEv267
_ZN4PLMD3ves12CoeffsMatrix8setValueERKSt6vectorIjSaIjEES6_d0
_ZN4PLMD3ves12CoeffsMatrix8setValueEmmd219
_ZN4PLMD3ves12CoeffsMatrix9sameShapeERNS0_12CoeffsVectorERS1_0
_ZN4PLMD3ves12CoeffsMatrix9sameShapeERS1_RNS0_12CoeffsVectorE0
_ZN4PLMD3ves12CoeffsMatrix9sameShapeERS1_S2_0
_ZN4PLMD3ves12CoeffsMatrix9setValuesERKS1_0
_ZN4PLMD3ves12CoeffsMatrix9setValuesERKSt6vectorIdSaIdEE22810
_ZN4PLMD3ves12CoeffsMatrix9setValuesEd0
_ZN4PLMD3ves12CoeffsMatrixC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPNS0_12CoeffsVectorERNS_12CommunicatorEb172
_ZN4PLMD3ves12CoeffsMatrixC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIS7_SaIS7_EERKSA_IjSaIjEERNS_12CommunicatorEbb0
_ZN4PLMD3ves12CoeffsMatrixC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIPNS_5ValueESaISC_EERSA_IPNS0_14BasisFunctionsESaISH_EERNS_12CommunicatorEbb0
_ZN4PLMD3ves12CoeffsMatrixC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorISA_IPNS_5ValueESaISC_EESaISE_EERSA_ISA_IPNS0_14BasisFunctionsESaISJ_EESaISL_EERNS_12CommunicatorEbbS9_0
_ZN4PLMD3ves12CoeffsMatrixD2Ev172
_ZN4PLMD3ves12CoeffsMatrixaSERKSt6vectorIdSaIdEE22810
_ZN4PLMD3ves12CoeffsMatrixaSEd0
_ZN4PLMD3ves12CoeffsMatrixclERKSt6vectorIjSaIjEES6_0
_ZN4PLMD3ves12CoeffsMatrixclEmm0
_ZN4PLMD3ves12CoeffsMatrixmIERKS1_0
_ZN4PLMD3ves12CoeffsMatrixmIERKSt6vectorIdSaIdEE0
_ZN4PLMD3ves12CoeffsMatrixmIEd0
_ZN4PLMD3ves12CoeffsMatrixmLERKS1_0
_ZN4PLMD3ves12CoeffsMatrixmLEd22810
_ZN4PLMD3ves12CoeffsMatrixpLERKS1_0
_ZN4PLMD3ves12CoeffsMatrixpLERKSt6vectorIdSaIdEE0
_ZN4PLMD3ves12CoeffsMatrixpLEd0
_ZN4PLMD3vesmiERKNS0_12CoeffsMatrixERKSt6vectorIdSaIdEE0
_ZN4PLMD3vesmiERKNS0_12CoeffsMatrixEd0
_ZN4PLMD3vesmiERKSt6vectorIdSaIdEERKNS0_12CoeffsMatrixE0
_ZN4PLMD3vesmiEdRKNS0_12CoeffsMatrixE0
_ZN4PLMD3vesmlERKNS0_12CoeffsMatrixERKNS0_12CoeffsVectorE22735
_ZN4PLMD3vesmlERKNS0_12CoeffsMatrixEd0
_ZN4PLMD3vesmlEdRKNS0_12CoeffsMatrixE0
_ZN4PLMD3vesplERKNS0_12CoeffsMatrixERKSt6vectorIdSaIdEE0
_ZN4PLMD3vesplERKNS0_12CoeffsMatrixEd0
_ZN4PLMD3vesplERKSt6vectorIdSaIdEERKNS0_12CoeffsMatrixE0
_ZN4PLMD3vesplEdRKNS0_12CoeffsMatrixE0
_ZNK4PLMD3ves12CoeffsMatrix10isDiagonalEv23395
_ZNK4PLMD3ves12CoeffsMatrix11getMaxValueEv0
_ZNK4PLMD3ves12CoeffsMatrix11getMinValueEv0
_ZNK4PLMD3ves12CoeffsMatrix14getMatrixIndexEmm5425906
_ZNK4PLMD3ves12CoeffsMatrix7getSizeEv439
_ZNK4PLMD3ves12CoeffsMatrix8getValueERKSt6vectorIjSaIjEES6_0
_ZNK4PLMD3ves12CoeffsMatrix8getValueEmm27630
_ZNK4PLMD3ves12CoeffsMatrix9sameShapeERNS0_12CoeffsVectorE0
_ZNK4PLMD3ves12CoeffsMatrix9sameShapeERS1_0
_ZNK4PLMD3ves12CoeffsMatrixclERKSt6vectorIjSaIjEES6_0
_ZNK4PLMD3ves12CoeffsMatrixclEmm1790345
_ZNK4PLMD3ves12CoeffsMatrixmiERKS1_0
_ZNK4PLMD3ves12CoeffsMatrixmlERKS1_0
_ZNK4PLMD3ves12CoeffsMatrixngEv0
_ZNK4PLMD3ves12CoeffsMatrixplERKS1_0
_ZNK4PLMD3ves12CoeffsMatrixpsEv0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/CoeffsMatrix.cpp.gcov.html b/coverage/ves/CoeffsMatrix.cpp.gcov.html new file mode 100644 index 000000000000..b6a35ad7b2d0 --- /dev/null +++ b/coverage/ves/CoeffsMatrix.cpp.gcov.html @@ -0,0 +1,792 @@ + + + + + + + + LCOV - plumed test coverage - ves/CoeffsMatrix.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - CoeffsMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10535629.5 %
Date:2024-04-19 12:12:35Functions:207925.3 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "CoeffsMatrix.h"
+      24             : #include "CoeffsVector.h"
+      25             : #include "BasisFunctions.h"
+      26             : 
+      27             : #include "tools/Tools.h"
+      28             : #include "core/Value.h"
+      29             : #include "tools/File.h"
+      30             : #include "tools/Exception.h"
+      31             : #include "tools/Random.h"
+      32             : #include "tools/Communicator.h"
+      33             : 
+      34             : #include <vector>
+      35             : #include <cmath>
+      36             : #include <iostream>
+      37             : #include <sstream>
+      38             : #include <cstdio>
+      39             : #include <cfloat>
+      40             : 
+      41             : 
+      42             : namespace PLMD {
+      43             : namespace ves {
+      44             : 
+      45           0 : CoeffsMatrix::CoeffsMatrix(
+      46             :   const std::string& label,
+      47             :   const std::vector<std::string>& dimension_labels,
+      48             :   const std::vector<unsigned int>& indices_shape,
+      49             :   Communicator& cc,
+      50             :   const bool diagonal,
+      51           0 :   const bool use_iteration_counter):
+      52             :   CoeffsBase(label,dimension_labels,indices_shape,use_iteration_counter),
+      53           0 :   data(0),
+      54           0 :   size_(0),
+      55           0 :   nrows_(0),
+      56           0 :   ncolumns_(0),
+      57           0 :   diagonal_(diagonal),
+      58           0 :   averaging_counter(0),
+      59           0 :   averaging_exp_decay_(0),
+      60           0 :   mycomm(cc)
+      61             : {
+      62           0 :   setupMatrix();
+      63           0 : }
+      64             : 
+      65             : 
+      66           0 : CoeffsMatrix::CoeffsMatrix(
+      67             :   const std::string& label,
+      68             :   std::vector<Value*>& args,
+      69             :   std::vector<BasisFunctions*>& basisf,
+      70             :   Communicator& cc,
+      71             :   const bool diagonal,
+      72           0 :   const bool use_iteration_counter):
+      73             :   CoeffsBase(label,args,basisf,use_iteration_counter),
+      74           0 :   data(0),
+      75           0 :   size_(0),
+      76           0 :   nrows_(0),
+      77           0 :   ncolumns_(0),
+      78           0 :   diagonal_(diagonal),
+      79           0 :   averaging_counter(0),
+      80           0 :   averaging_exp_decay_(0),
+      81           0 :   mycomm(cc)
+      82             : {
+      83           0 :   setupMatrix();
+      84           0 : }
+      85             : 
+      86             : 
+      87           0 : CoeffsMatrix::CoeffsMatrix(
+      88             :   const std::string& label,
+      89             :   std::vector<std::vector<Value*> >& argsv,
+      90             :   std::vector<std::vector<BasisFunctions*> >& basisfv,
+      91             :   Communicator& cc,
+      92             :   const bool diagonal,
+      93             :   const bool use_iteration_counter,
+      94           0 :   const std::string& multicoeffs_label):
+      95             :   CoeffsBase(label,argsv,basisfv,use_iteration_counter,multicoeffs_label),
+      96           0 :   data(0),
+      97           0 :   size_(0),
+      98           0 :   nrows_(0),
+      99           0 :   ncolumns_(0),
+     100           0 :   diagonal_(diagonal),
+     101           0 :   averaging_counter(0),
+     102           0 :   averaging_exp_decay_(0),
+     103           0 :   mycomm(cc)
+     104             : {
+     105           0 :   setupMatrix();
+     106           0 : }
+     107             : 
+     108             : 
+     109         172 : CoeffsMatrix::CoeffsMatrix(
+     110             :   const std::string& label,
+     111             :   CoeffsVector* coeffsVec,
+     112             :   Communicator& cc,
+     113         172 :   const bool diagonal):
+     114             :   CoeffsBase( *(static_cast<CoeffsBase*>(coeffsVec)) ),
+     115         172 :   data(0),
+     116         172 :   size_(0),
+     117         172 :   nrows_(0),
+     118         172 :   ncolumns_(0),
+     119         172 :   diagonal_(diagonal),
+     120         172 :   averaging_counter(0),
+     121         172 :   averaging_exp_decay_(0),
+     122         172 :   mycomm(cc)
+     123             : {
+     124         172 :   setLabels(label);
+     125         172 :   setupMatrix();
+     126         172 : }
+     127             : 
+     128             : 
+     129         172 : CoeffsMatrix::~CoeffsMatrix() {}
+     130             : 
+     131             : 
+     132         172 : void CoeffsMatrix::setupMatrix() {
+     133         172 :   nrows_=numberOfCoeffs();
+     134         172 :   ncolumns_=nrows_;
+     135         172 :   if(diagonal_) {
+     136         172 :     size_=nrows_;
+     137             :   }
+     138             :   else {
+     139           0 :     size_=(nrows_*nrows_-nrows_)/2+nrows_;
+     140             :   }
+     141         172 :   clear();
+     142         172 : }
+     143             : 
+     144             : 
+     145         439 : size_t CoeffsMatrix::getSize() const {
+     146         439 :   return size_;
+     147             : }
+     148             : 
+     149             : 
+     150       23395 : bool CoeffsMatrix::isDiagonal() const {
+     151       23395 :   return diagonal_;
+     152             : }
+     153             : 
+     154             : 
+     155           0 : bool CoeffsMatrix::sameShape(CoeffsVector& coeffsvector_in) const {
+     156           0 :   return CoeffsBase::sameShape( *(static_cast<CoeffsBase*>(&coeffsvector_in)) );
+     157             : }
+     158             : 
+     159             : 
+     160           0 : bool CoeffsMatrix::sameShape(CoeffsMatrix& coeffsmat_in) const {
+     161           0 :   return CoeffsBase::sameShape( *(static_cast<CoeffsBase*>(&coeffsmat_in)) );
+     162             : }
+     163             : 
+     164             : 
+     165           0 : bool CoeffsMatrix::sameShape(CoeffsMatrix& coeffsmat0, CoeffsMatrix& coeffsmat1) {
+     166           0 :   return coeffsmat0.sameShape(coeffsmat1);
+     167             : }
+     168             : 
+     169             : 
+     170           0 : bool CoeffsMatrix::sameShape(CoeffsVector& coeffsvec, CoeffsMatrix& coeffsmat) {
+     171           0 :   return coeffsmat.sameShape(coeffsvec);
+     172             : }
+     173             : 
+     174             : 
+     175           0 : bool CoeffsMatrix::sameShape(CoeffsMatrix& coeffsmat, CoeffsVector& coeffsvec) {
+     176           0 :   return coeffsmat.sameShape(coeffsvec);
+     177             : }
+     178             : 
+     179             : 
+     180           0 : void CoeffsMatrix::sumCommMPI() {
+     181           0 :   mycomm.Sum(data);
+     182           0 : }
+     183             : 
+     184             : 
+     185           0 : void CoeffsMatrix::sumCommMPI(Communicator& cc) {
+     186           0 :   cc.Sum(data);
+     187           0 : }
+     188             : 
+     189             : 
+     190           0 : void CoeffsMatrix::sumMultiSimCommMPI(Communicator& multi_sim_cc) {
+     191           0 :   if(mycomm.Get_rank()==0) {
+     192           0 :     double nwalkers = static_cast<double>(multi_sim_cc.Get_size());
+     193           0 :     multi_sim_cc.Sum(data);
+     194           0 :     scaleAllValues(1.0/nwalkers);
+     195             :   }
+     196           0 :   mycomm.Bcast(data,0);
+     197           0 : }
+     198             : 
+     199             : 
+     200     5425906 : size_t CoeffsMatrix::getMatrixIndex(const size_t index1, const size_t index2) const {
+     201             :   size_t matrix_idx;
+     202             :   plumed_dbg_assert(index1<nrows_);
+     203             :   plumed_dbg_assert(index2<ncolumns_);
+     204     5425906 :   if(diagonal_) {
+     205             :     // plumed_massert(index1==index2,"CoeffsMatrix: you trying to access a off-diagonal element of a diagonal coeffs matrix");
+     206             :     matrix_idx=index1;
+     207             :   }
+     208           0 :   else if (index1<=index2) {
+     209           0 :     matrix_idx=index2+index1*(nrows_-1)-index1*(index1-1)/2;
+     210             :   }
+     211             :   else {
+     212           0 :     matrix_idx=index1+index2*(nrows_-1)-index2*(index2-1)/2;
+     213             :   }
+     214     5425906 :   return matrix_idx;
+     215             : }
+     216             : 
+     217             : 
+     218         267 : void CoeffsMatrix::clear() {
+     219         267 :   data.resize(getSize());
+     220       19388 :   for(size_t i=0; i<data.size(); i++) {
+     221       19121 :     data[i]=0.0;
+     222             :   }
+     223         267 : }
+     224             : 
+     225             : 
+     226           0 : void CoeffsMatrix::setAllValuesToZero() {
+     227           0 :   for(size_t i=0; i<data.size(); i++) {
+     228           0 :     data[i]=0.0;
+     229             :   }
+     230           0 : }
+     231             : 
+     232             : 
+     233       27630 : double CoeffsMatrix::getValue(const size_t index1, const size_t index2) const {
+     234       27630 :   return data[getMatrixIndex(index1,index2)];
+     235             : }
+     236             : 
+     237             : 
+     238           0 : double CoeffsMatrix::getValue(const std::vector<unsigned int>& indices1, const std::vector<unsigned int>& indices2) const {
+     239           0 :   return getValue(getIndex(indices1),getIndex(indices2));
+     240             : }
+     241             : 
+     242             : 
+     243         219 : void CoeffsMatrix::setValue(const size_t index1, const size_t index2, const double value) {
+     244         219 :   data[getMatrixIndex(index1,index2)]=value;
+     245         219 : }
+     246             : 
+     247             : 
+     248           0 : void CoeffsMatrix::setValue(const std::vector<unsigned int>& indices1, const std::vector<unsigned int>& indices2, const double value) {
+     249           0 :   setValue(getIndex(indices1),getIndex(indices2),value);
+     250           0 : }
+     251             : 
+     252             : 
+     253           0 : double& CoeffsMatrix::operator()(const size_t index1, const size_t index2) {
+     254           0 :   return data[getMatrixIndex(index1,index2)];
+     255             : }
+     256             : 
+     257             : 
+     258     1790345 : const double& CoeffsMatrix::operator()(const size_t index1, const size_t index2) const {
+     259     1790345 :   return data[getMatrixIndex(index1,index2)];
+     260             : }
+     261             : 
+     262             : 
+     263           0 : double& CoeffsMatrix::operator()(const std::vector<unsigned int>& indices1, const std::vector<unsigned int>& indices2) {
+     264           0 :   return data[getMatrixIndex(getIndex(indices1),getIndex(indices2))];
+     265             : }
+     266             : 
+     267             : 
+     268           0 : const double& CoeffsMatrix::operator()(const std::vector<unsigned int>& indices1, const std::vector<unsigned int>& indices2) const {
+     269           0 :   return data[getMatrixIndex(getIndex(indices1),getIndex(indices2))];
+     270             : }
+     271             : 
+     272             : 
+     273       22735 : CoeffsVector operator*(const CoeffsMatrix& coeffs_matrix, const CoeffsVector& coeffs_vector) {
+     274       22735 :   CoeffsVector new_coeffs_vector(coeffs_vector);
+     275       22735 :   new_coeffs_vector.clear();
+     276       22735 :   plumed_massert(coeffs_vector.numberOfCoeffs()==coeffs_matrix.numberOfCoeffs(),"CoeffsMatrix and CoeffsVector are of the wrong size");
+     277             :   size_t numcoeffs = coeffs_vector.numberOfCoeffs();
+     278       22735 :   if(coeffs_matrix.isDiagonal()) {
+     279     1813080 :     for(size_t i=0; i<numcoeffs; i++) {
+     280     1790345 :       new_coeffs_vector(i) = coeffs_matrix(i,i)*coeffs_vector(i);
+     281             :     }
+     282             :   }
+     283             :   else {
+     284           0 :     for(size_t i=0; i<numcoeffs; i++) {
+     285           0 :       for(size_t j=0; j<numcoeffs; j++) {
+     286           0 :         new_coeffs_vector(i) += coeffs_matrix(i,j)*coeffs_vector(j);
+     287             :       }
+     288             :     }
+     289             :   }
+     290       22735 :   return new_coeffs_vector;
+     291           0 : }
+     292             : 
+     293             : 
+     294           0 : void CoeffsMatrix::addToValue(const size_t index1, const size_t index2, const double value) {
+     295           0 :   data[getMatrixIndex(index1,index2)]+=value;
+     296           0 : }
+     297             : 
+     298             : 
+     299           0 : void CoeffsMatrix::addToValue(const std::vector<unsigned int>& indices1, const std::vector<unsigned int>& indices2, const double value) {
+     300           0 :   addToValue(getIndex(indices1),getIndex(indices2),value);
+     301           0 : }
+     302             : 
+     303             : 
+     304       22810 : void CoeffsMatrix::scaleAllValues(const double scalef) {
+     305     1823850 :   for(size_t i=0; i<data.size(); i++) {
+     306     1801040 :     data[i]*=scalef;
+     307             :   }
+     308       22810 : }
+     309             : 
+     310             : 
+     311       22810 : CoeffsMatrix& CoeffsMatrix::operator*=(const double scalef) {
+     312       22810 :   scaleAllValues(scalef);
+     313       22810 :   return *this;
+     314             : }
+     315             : 
+     316             : 
+     317           0 : CoeffsMatrix operator*(const double scalef, const CoeffsMatrix& coeffsmatrix) {
+     318           0 :   return CoeffsMatrix(coeffsmatrix)*=scalef;
+     319             : }
+     320             : 
+     321             : 
+     322           0 : CoeffsMatrix operator*(const CoeffsMatrix& coeffsmatrix, const double scalef) {
+     323           0 :   return scalef*coeffsmatrix;
+     324             : }
+     325             : 
+     326             : 
+     327           0 : CoeffsMatrix& CoeffsMatrix::operator*=(const CoeffsMatrix& other_coeffsmatrix) {
+     328           0 :   plumed_massert(data.size()==other_coeffsmatrix.getSize(),"Coeffs matrices do not have the same size");
+     329           0 :   for(size_t i=0; i<data.size(); i++) {
+     330           0 :     data[i]*=other_coeffsmatrix.data[i];
+     331             :   }
+     332           0 :   return *this;
+     333             : }
+     334             : 
+     335             : 
+     336           0 : CoeffsMatrix CoeffsMatrix::operator*(const CoeffsMatrix& other_coeffsmatrix) const {
+     337           0 :   return CoeffsMatrix(*this)*=other_coeffsmatrix;
+     338             : }
+     339             : 
+     340             : 
+     341           0 : void CoeffsMatrix::setValues(const double value) {
+     342           0 :   for(size_t i=0; i<data.size(); i++) {
+     343           0 :     data[i]=value;
+     344             :   }
+     345           0 : }
+     346             : 
+     347             : 
+     348       22810 : void CoeffsMatrix::setValues(const std::vector<double>& values) {
+     349       22810 :   plumed_massert( data.size()==values.size(), "Incorrect size");
+     350     1823850 :   for(size_t i=0; i<data.size(); i++) {
+     351     1801040 :     data[i]=values[i];
+     352             :   }
+     353       22810 : }
+     354             : 
+     355             : 
+     356           0 : void CoeffsMatrix::setValues(const CoeffsMatrix& other_coeffsmatrix) {
+     357           0 :   plumed_massert( data.size()==other_coeffsmatrix.getSize(), "Incorrect size");
+     358           0 :   for(size_t i=0; i<data.size(); i++) {
+     359           0 :     data[i]=other_coeffsmatrix.data[i];
+     360             :   }
+     361           0 : }
+     362             : 
+     363             : 
+     364           0 : CoeffsMatrix& CoeffsMatrix::operator=(const double value) {
+     365           0 :   setValues(value);
+     366           0 :   return *this;
+     367             : }
+     368             : 
+     369             : 
+     370       22810 : CoeffsMatrix& CoeffsMatrix::operator=(const std::vector<double>& values) {
+     371       22810 :   setValues(values);
+     372       22810 :   return *this;
+     373             : }
+     374             : 
+     375             : 
+     376             : // CoeffsMatrix& CoeffsMatrix::operator=(const CoeffsMatrix& other_coeffsmatrix) {
+     377             : //   setValues(other_coeffsmatrix);
+     378             : //   return *this;
+     379             : // }
+     380             : 
+     381             : 
+     382           0 : CoeffsMatrix CoeffsMatrix::operator+() const {
+     383           0 :   return *this;
+     384             : }
+     385             : 
+     386             : 
+     387           0 : CoeffsMatrix CoeffsMatrix::operator-() const {
+     388           0 :   return CoeffsMatrix(*this)*=-1.0;
+     389             : }
+     390             : 
+     391             : 
+     392           0 : void CoeffsMatrix::addToValues(const double value) {
+     393           0 :   for(size_t i=0; i<data.size(); i++) {
+     394           0 :     data[i]+=value;
+     395             :   }
+     396           0 : }
+     397             : 
+     398             : 
+     399           0 : void CoeffsMatrix::addToValues(const std::vector<double>& values) {
+     400           0 :   plumed_massert( data.size()==values.size(), "Incorrect size");
+     401           0 :   for(size_t i=0; i<data.size(); i++) {
+     402           0 :     data[i]+=values[i];
+     403             :   }
+     404           0 : }
+     405             : 
+     406             : 
+     407           0 : void CoeffsMatrix::addToValues(const CoeffsMatrix& other_coeffsmatrix) {
+     408           0 :   plumed_massert( data.size()==other_coeffsmatrix.getSize(), "Incorrect size");
+     409           0 :   for(size_t i=0; i<data.size(); i++) {
+     410           0 :     data[i]+=other_coeffsmatrix.data[i];
+     411             :   }
+     412           0 : }
+     413             : 
+     414             : 
+     415           0 : void CoeffsMatrix::subtractFromValues(const double value) {
+     416           0 :   for(size_t i=0; i<data.size(); i++) {
+     417           0 :     data[i]-=value;
+     418             :   }
+     419           0 : }
+     420             : 
+     421             : 
+     422           0 : void CoeffsMatrix::subtractFromValues(const std::vector<double>& values) {
+     423           0 :   plumed_massert( data.size()==values.size(), "Incorrect size");
+     424           0 :   for(size_t i=0; i<data.size(); i++) {
+     425           0 :     data[i]-=values[i];
+     426             :   }
+     427           0 : }
+     428             : 
+     429             : 
+     430           0 : void CoeffsMatrix::subtractFromValues(const CoeffsMatrix& other_coeffsmatrix) {
+     431           0 :   plumed_massert( data.size()==other_coeffsmatrix.getSize(), "Incorrect size");
+     432           0 :   for(size_t i=0; i<data.size(); i++) {
+     433           0 :     data[i]-=other_coeffsmatrix.data[i];
+     434             :   }
+     435           0 : }
+     436             : 
+     437             : 
+     438           0 : CoeffsMatrix& CoeffsMatrix::operator+=(const double value) {
+     439           0 :   addToValues(value);
+     440           0 :   return *this;
+     441             : }
+     442             : 
+     443             : 
+     444           0 : CoeffsMatrix operator+(const double value, const CoeffsMatrix& coeffsmatrix) {
+     445           0 :   return coeffsmatrix+value;
+     446             : }
+     447             : 
+     448             : 
+     449           0 : CoeffsMatrix operator+(const CoeffsMatrix& coeffsmatrix, const double value) {
+     450           0 :   return CoeffsMatrix(coeffsmatrix)+=value;
+     451             : }
+     452             : 
+     453             : 
+     454           0 : CoeffsMatrix& CoeffsMatrix::operator+=(const std::vector<double>& values) {
+     455           0 :   addToValues(values);
+     456           0 :   return *this;
+     457             : }
+     458             : 
+     459             : 
+     460           0 : CoeffsMatrix operator+(const std::vector<double>& values, const CoeffsMatrix& coeffsmatrix) {
+     461           0 :   return coeffsmatrix+values;
+     462             : }
+     463             : 
+     464             : 
+     465           0 : CoeffsMatrix operator+(const CoeffsMatrix& coeffsmatrix, const std::vector<double>& values) {
+     466           0 :   return CoeffsMatrix(coeffsmatrix)+=values;
+     467             : }
+     468             : 
+     469             : 
+     470           0 : CoeffsMatrix& CoeffsMatrix::operator-=(const double value) {
+     471           0 :   subtractFromValues(value);
+     472           0 :   return *this;
+     473             : }
+     474             : 
+     475             : 
+     476           0 : CoeffsMatrix operator-(const double value, const CoeffsMatrix& coeffsmatrix) {
+     477           0 :   return -1.0*coeffsmatrix+value;
+     478             : }
+     479             : 
+     480             : 
+     481           0 : CoeffsMatrix operator-(const CoeffsMatrix& coeffsmatrix, const double value) {
+     482           0 :   return CoeffsMatrix(coeffsmatrix)-=value;
+     483             : }
+     484             : 
+     485             : 
+     486           0 : CoeffsMatrix& CoeffsMatrix::operator-=(const std::vector<double>& values) {
+     487           0 :   subtractFromValues(values);
+     488           0 :   return *this;
+     489             : }
+     490             : 
+     491             : 
+     492           0 : CoeffsMatrix operator-(const std::vector<double>& values, const CoeffsMatrix& coeffsmatrix) {
+     493           0 :   return -1.0*coeffsmatrix+values;
+     494             : }
+     495             : 
+     496             : 
+     497           0 : CoeffsMatrix operator-(const CoeffsMatrix& coeffsmatrix, const std::vector<double>& values) {
+     498           0 :   return CoeffsMatrix(coeffsmatrix)-=values;
+     499             : }
+     500             : 
+     501             : 
+     502           0 : CoeffsMatrix& CoeffsMatrix::operator+=(const CoeffsMatrix& other_coeffsmatrix) {
+     503           0 :   addToValues(other_coeffsmatrix);
+     504           0 :   return *this;
+     505             : }
+     506             : 
+     507             : 
+     508           0 : CoeffsMatrix CoeffsMatrix::operator+(const CoeffsMatrix& other_coeffsmatrix) const {
+     509           0 :   return CoeffsMatrix(*this)+=other_coeffsmatrix;
+     510             : }
+     511             : 
+     512             : 
+     513           0 : CoeffsMatrix& CoeffsMatrix::operator-=(const CoeffsMatrix& other_coeffsmatrix) {
+     514           0 :   subtractFromValues(other_coeffsmatrix);
+     515           0 :   return *this;
+     516             : }
+     517             : 
+     518             : 
+     519           0 : CoeffsMatrix CoeffsMatrix::operator-(const CoeffsMatrix& other_coeffsmatrix) const {
+     520           0 :   return CoeffsMatrix(*this)-=other_coeffsmatrix;
+     521             : }
+     522             : 
+     523             : 
+     524           0 : void CoeffsMatrix::averageMatrices(CoeffsMatrix& coeffsmat0, CoeffsMatrix& coeffsmat1) {
+     525           0 :   plumed_massert(sameShape(coeffsmat0,coeffsmat1),"both CoeffsMatrix objects need to have the same shape");
+     526           0 :   for(size_t i=0; i<coeffsmat0.getSize(); i++) {
+     527           0 :     coeffsmat0.data[i] = coeffsmat1.data[i] = 0.5 * (coeffsmat0.data[i]+coeffsmat1.data[i]);
+     528             :   }
+     529           0 : }
+     530             : 
+     531             : 
+     532           0 : void CoeffsMatrix::averageMatrices(const std::vector<CoeffsMatrix*>& coeffsmatSet) {
+     533           0 :   double norm_factor = 1.0/static_cast<double>(coeffsmatSet.size());
+     534           0 :   for(unsigned int k=1; k<coeffsmatSet.size(); k++) {
+     535           0 :     plumed_massert(coeffsmatSet[0]->sameShape(*coeffsmatSet[k]),"All CoeffsMatrix objects need to have the same shape");
+     536             :   }
+     537           0 :   for(size_t i=0; i<coeffsmatSet[0]->getSize(); i++) {
+     538             :     double value = 0.0;
+     539           0 :     for(unsigned int k=0; k<coeffsmatSet.size(); k++) {
+     540           0 :       value += coeffsmatSet[k]->data[i];
+     541             :     }
+     542           0 :     value *= norm_factor;
+     543           0 :     for(unsigned int k=0; k<coeffsmatSet.size(); k++) {
+     544           0 :       coeffsmatSet[k]->data[i] = value;
+     545             :     }
+     546             :   }
+     547           0 : }
+     548             : 
+     549             : 
+     550             : 
+     551           0 : double CoeffsMatrix::getMinValue() const {
+     552             :   double min_value=DBL_MAX;
+     553           0 :   for(size_t i=0; i<data.size(); i++) {
+     554           0 :     if(data[i]<min_value) {
+     555             :       min_value=data[i];
+     556             :     }
+     557             :   }
+     558           0 :   return min_value;
+     559             : }
+     560             : 
+     561             : 
+     562           0 : double CoeffsMatrix::getMaxValue() const {
+     563             :   double max_value=DBL_MIN;
+     564           0 :   for(size_t i=0; i<data.size(); i++) {
+     565           0 :     if(data[i]>max_value) {
+     566             :       max_value=data[i];
+     567             :     }
+     568             :   }
+     569           0 :   return max_value;
+     570             : }
+     571             : 
+     572             : 
+     573           0 : void CoeffsMatrix::randomizeValuesGaussian(int randomSeed) {
+     574           0 :   Random rnd;
+     575             :   if (randomSeed<0) {randomSeed = -randomSeed;}
+     576           0 :   rnd.setSeed(-randomSeed);
+     577           0 :   for(size_t i=0; i<data.size(); i++) {
+     578           0 :     data[i]=rnd.Gaussian();
+     579             :   }
+     580           0 : }
+     581             : 
+     582             : 
+     583           0 : void CoeffsMatrix::resetAveraging() {
+     584           0 :   clear();
+     585             :   resetAveragingCounter();
+     586           0 : }
+     587             : 
+     588             : 
+     589           0 : void CoeffsMatrix::addToAverage(const CoeffsMatrix& coeffsmat) {
+     590           0 :   plumed_massert( data.size()==coeffsmat.getSize(), "Incorrect size");
+     591             :   //
+     592           0 :   double aver_decay = 1.0 / ( static_cast<double>(averaging_counter) + 1.0 );
+     593           0 :   if(averaging_exp_decay_>0 &&  (averaging_counter+1 > averaging_exp_decay_) ) {
+     594           0 :     aver_decay = 1.0 / static_cast<double>(averaging_exp_decay_);
+     595             :   }
+     596             :   //
+     597           0 :   for(size_t i=0; i<data.size(); i++) {
+     598           0 :     data[i]+=(coeffsmat.data[i]-data[i])*aver_decay;
+     599             :   }
+     600           0 :   averaging_counter++;
+     601           0 : }
+     602             : 
+     603             : 
+     604         660 : void CoeffsMatrix::writeToFile(OFile& ofile) {
+     605         660 :   writeHeaderToFile(ofile);
+     606         660 :   writeDataToFile(ofile);
+     607         660 : }
+     608             : 
+     609             : 
+     610           0 : void CoeffsMatrix::writeToFile(const std::string& filepath, const bool append_file, Action* action_pntr) {
+     611           0 :   OFile file;
+     612           0 :   if(action_pntr!=NULL) {
+     613           0 :     file.link(*action_pntr);
+     614             :   }
+     615             :   else {
+     616           0 :     file.link(mycomm);
+     617             :   }
+     618           0 :   if(append_file) { file.enforceRestart(); }
+     619           0 :   file.open(filepath);
+     620           0 :   writeToFile(file);
+     621           0 :   file.close();
+     622           0 : }
+     623             : 
+     624             : 
+     625         660 : void CoeffsMatrix::writeMatrixInfoToFile(OFile& ofile) {
+     626         660 :   std::string field_diagonal = "diagonal_matrix";
+     627         660 :   ofile.addConstantField(field_diagonal).printField(field_diagonal,isDiagonal());
+     628         660 : }
+     629             : 
+     630             : 
+     631         660 : void CoeffsMatrix::writeHeaderToFile(OFile& ofile) {
+     632         660 :   ofile.clearFields();
+     633         660 :   if(isIterationCounterActive()) {
+     634         660 :     writeIterationCounterAndTimeToFile(ofile);
+     635             :   }
+     636         660 :   writeCoeffsInfoToFile(ofile);
+     637         660 :   writeMatrixInfoToFile(ofile);
+     638         660 : }
+     639             : 
+     640             : 
+     641         660 : void CoeffsMatrix::writeDataToFile(OFile& ofile) {
+     642         660 :   if(diagonal_) {
+     643         660 :     writeDataDiagonalToFile(ofile);
+     644             :   }
+     645             :   else {
+     646           0 :     writeDataFullToFile(ofile);
+     647             :   }
+     648         660 : }
+     649             : 
+     650             : 
+     651         660 : void CoeffsMatrix::writeDataDiagonalToFile(OFile& ofile) {
+     652             :   //
+     653         660 :   std::string field_indices_prefix = "idx_";
+     654             :   std::string field_coeffs = getDataLabel();
+     655         660 :   std::string field_index = "index";
+     656             :   //
+     657         660 :   std::string int_fmt = "%8d";
+     658         660 :   std::string str_separate = "#!-------------------";
+     659             :   //
+     660         660 :   std::vector<char> s1(20);
+     661         660 :   std::vector<unsigned int> indices(numberOfDimensions());
+     662         660 :   std::vector<std::string> ilabels(numberOfDimensions());
+     663        1520 :   for(unsigned int k=0; k<numberOfDimensions(); k++) {
+     664        1720 :     ilabels[k]=field_indices_prefix+getDimensionLabel(k);
+     665             :   }
+     666             :   //
+     667       28290 :   for(size_t i=0; i<numberOfCoeffs(); i++) {
+     668       27630 :     indices=getIndices(i);
+     669       77540 :     for(unsigned int k=0; k<numberOfDimensions(); k++) {
+     670       49910 :       std::snprintf(s1.data(),s1.size(),int_fmt.c_str(),indices[k]);
+     671       99820 :       ofile.printField(ilabels[k],s1.data());
+     672             :     }
+     673       55260 :     ofile.fmtField(" "+getOutputFmt()).printField(field_coeffs,getValue(i,i));
+     674       27630 :     std::snprintf(s1.data(),s1.size(),int_fmt.c_str(),i); ofile.printField(field_index,s1.data());
+     675       27630 :     ofile.printField();
+     676             :   }
+     677         660 :   ofile.fmtField();
+     678             :   // blank line between iterations to allow proper plotting with gnuplot
+     679         660 :   ofile.printf("%s\n",str_separate.c_str());
+     680         660 :   ofile.printf("\n");
+     681         660 :   ofile.printf("\n");
+     682        1320 : }
+     683             : 
+     684             : 
+     685           0 : void CoeffsMatrix::writeDataFullToFile(OFile& ofile) {
+     686             :   //
+     687           0 :   std::string field_index_row = "idx_row";
+     688           0 :   std::string field_index_column = "idx_column";
+     689             :   std::string field_coeffs = getDataLabel();
+     690             :   //
+     691           0 :   std::string int_fmt = "%8d";
+     692           0 :   std::string str_separate = "#!-------------------";
+     693             :   //
+     694           0 :   std::vector<char> s1(20);
+     695             :   //
+     696           0 :   for(size_t i=0; i<nrows_; i++) {
+     697           0 :     for(size_t j=0; j<ncolumns_; j++) {
+     698             :       std::snprintf(s1.data(),s1.size(),int_fmt.c_str(),i);
+     699           0 :       ofile.printField(field_index_row,s1.data());
+     700             :       std::snprintf(s1.data(),s1.size(),int_fmt.c_str(),j);
+     701           0 :       ofile.printField(field_index_column,s1.data());
+     702           0 :       ofile.fmtField(" "+getOutputFmt()).printField(field_coeffs,getValue(i,j));
+     703           0 :       ofile.printField();
+     704             :     }
+     705             :   }
+     706           0 :   ofile.fmtField();
+     707             :   // blank line between iterations to allow proper plotting with gnuplot
+     708           0 :   ofile.printf("%s\n",str_separate.c_str());
+     709           0 :   ofile.printf("\n");
+     710           0 :   ofile.printf("\n");
+     711           0 : }
+     712             : 
+     713             : 
+     714             : }
+     715             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/CoeffsMatrix.h.func-sort-c.html b/coverage/ves/CoeffsMatrix.h.func-sort-c.html new file mode 100644 index 000000000000..7150cf031d42 --- /dev/null +++ b/coverage/ves/CoeffsMatrix.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage - ves/CoeffsMatrix.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - CoeffsMatrix.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:010.0 %
Date:2024-04-19 12:12:35Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/CoeffsMatrix.h.func.html b/coverage/ves/CoeffsMatrix.h.func.html new file mode 100644 index 000000000000..fdc37db652ae --- /dev/null +++ b/coverage/ves/CoeffsMatrix.h.func.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage - ves/CoeffsMatrix.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - CoeffsMatrix.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:010.0 %
Date:2024-04-19 12:12:35Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/CoeffsMatrix.h.gcov.html b/coverage/ves/CoeffsMatrix.h.gcov.html new file mode 100644 index 000000000000..42d045da6210 --- /dev/null +++ b/coverage/ves/CoeffsMatrix.h.gcov.html @@ -0,0 +1,288 @@ + + + + + + + + LCOV - plumed test coverage - ves/CoeffsMatrix.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - CoeffsMatrix.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:010.0 %
Date:2024-04-19 12:12:35Functions:00-
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_ves_CoeffsMatrix_h
+      23             : #define __PLUMED_ves_CoeffsMatrix_h
+      24             : 
+      25             : #include "CoeffsBase.h"
+      26             : 
+      27             : #include <vector>
+      28             : #include <string>
+      29             : #include <cmath>
+      30             : 
+      31             : 
+      32             : namespace PLMD {
+      33             : 
+      34             : class Action;
+      35             : class Value;
+      36             : class IFile;
+      37             : class OFile;
+      38             : class Communicator;
+      39             : 
+      40             : namespace ves {
+      41             : 
+      42             : class BasisFunctions;
+      43             : class CoeffsVector;
+      44             : 
+      45             : 
+      46             : class CoeffsMatrix:
+      47             :   public CoeffsBase
+      48             : {
+      49             : public:
+      50             : private:
+      51             :   std::vector<double> data;
+      52             :   //
+      53             :   size_t size_;
+      54             :   size_t nrows_;
+      55             :   size_t ncolumns_;
+      56             :   //
+      57             :   bool diagonal_;
+      58             :   //
+      59             :   unsigned int averaging_counter;
+      60             :   unsigned int averaging_exp_decay_;
+      61             :   //
+      62             :   Communicator& mycomm;
+      63             :   //
+      64             :   void setupMatrix();
+      65             :   //
+      66             :   CoeffsMatrix& operator=(const CoeffsMatrix&);
+      67             : public:
+      68             :   explicit CoeffsMatrix(
+      69             :     const std::string&,
+      70             :     const std::vector<std::string>&,
+      71             :     const std::vector<unsigned int>&,
+      72             :     Communicator& cc,
+      73             :     const bool diagonal=true,
+      74             :     const bool use_iteration_counter=false);
+      75             :   //
+      76             :   explicit CoeffsMatrix(
+      77             :     const std::string&,
+      78             :     std::vector<Value*>&,
+      79             :     std::vector<BasisFunctions*>&,
+      80             :     Communicator& cc,
+      81             :     const bool diagonal=true,
+      82             :     const bool use_iteration_counter=false);
+      83             :   //
+      84             :   explicit CoeffsMatrix(
+      85             :     const std::string&,
+      86             :     std::vector<std::vector<Value*> >& argsv,
+      87             :     std::vector<std::vector<BasisFunctions*> >& basisfv,
+      88             :     Communicator& cc,
+      89             :     const bool diagonal=true,
+      90             :     const bool use_iteration_counter=false,
+      91             :     const std::string& multicoeffs_label="bias");
+      92             :   //
+      93             :   explicit CoeffsMatrix(
+      94             :     const std::string&,
+      95             :     CoeffsVector*,
+      96             :     Communicator& cc,
+      97             :     const bool diagonal=true);
+      98             :   //
+      99             :   ~CoeffsMatrix();
+     100             :   //
+     101             :   size_t getSize() const;
+     102             :   //
+     103             :   bool isSymmetric() const;
+     104             :   bool isDiagonal() const;
+     105             :   //
+     106             :   bool sameShape(CoeffsVector&) const;
+     107             :   bool sameShape(CoeffsMatrix&) const;
+     108             :   static bool sameShape(CoeffsMatrix&, CoeffsMatrix&);
+     109             :   static bool sameShape(CoeffsVector&, CoeffsMatrix&);
+     110             :   static bool sameShape(CoeffsMatrix&, CoeffsVector&);
+     111             :   //
+     112             :   void sumCommMPI();
+     113             :   void sumCommMPI(Communicator&);
+     114             :   //
+     115             :   void sumMultiSimCommMPI(Communicator&);
+     116             :   //
+     117             :   size_t getMatrixIndex(const size_t, const size_t) const;
+     118             :   //
+     119             :   // clear coeffs
+     120             :   void clear();
+     121             :   void setAllValuesToZero();
+     122             :   //
+     123             :   std::vector<double> getDataAsVector() const {return data;}
+     124             :   // get value
+     125             :   double getValue(const size_t, const size_t) const;
+     126             :   double getValue(const std::vector<unsigned int>&, const std::vector<unsigned int>&) const;
+     127             :   // set value
+     128             :   void setValue(const size_t, const size_t, const double);
+     129             :   void setValue(const std::vector<unsigned int>&, const std::vector<unsigned int>&, const double);
+     130             :   double& operator()(const size_t, const size_t);
+     131             :   const double& operator()(const size_t, const size_t) const;
+     132             :   double& operator()(const std::vector<unsigned int>&, const std::vector<unsigned int>&);
+     133             :   const double& operator()(const std::vector<unsigned int>&, const std::vector<unsigned int>&) const;
+     134             :   //
+     135             :   friend CoeffsVector operator*(const CoeffsMatrix&, const CoeffsVector&);
+     136             :   // add to value
+     137             :   void addToValue(const size_t, const size_t, const double);
+     138             :   void addToValue(const std::vector<unsigned int>&, const std::vector<unsigned int>&, const double);
+     139             :   // scale all values
+     140             :   void scaleAllValues(const double);
+     141             :   CoeffsMatrix& operator*=(const double);
+     142             :   friend CoeffsMatrix operator*(const double, const CoeffsMatrix&);
+     143             :   friend CoeffsMatrix operator*(const CoeffsMatrix&, const double);
+     144             :   CoeffsMatrix& operator*=(const CoeffsMatrix&);
+     145             :   CoeffsMatrix operator*(const CoeffsMatrix&) const;
+     146             :   // set all values
+     147             :   void setValues(const double);
+     148             :   void setValues(const std::vector<double>&);
+     149             :   void setValues(const CoeffsMatrix&);
+     150             :   CoeffsMatrix& operator=(const double);
+     151             :   CoeffsMatrix& operator=(const std::vector<double>&);
+     152             :   // CoeffsMatrix& operator=(const CoeffsMatrix&);
+     153             :   // add to all values
+     154             :   CoeffsMatrix operator+() const;
+     155             :   CoeffsMatrix operator-() const;
+     156             :   void addToValues(const double);
+     157             :   void addToValues(const std::vector<double>&);
+     158             :   void addToValues(const CoeffsMatrix&);
+     159             :   void subtractFromValues(const double);
+     160             :   void subtractFromValues(const std::vector<double>&);
+     161             :   void subtractFromValues(const CoeffsMatrix&);
+     162             :   CoeffsMatrix& operator+=(const double);
+     163             :   friend CoeffsMatrix operator+(const double, const CoeffsMatrix&);
+     164             :   friend CoeffsMatrix operator+(const CoeffsMatrix&, const double);
+     165             :   CoeffsMatrix& operator+=(const std::vector<double>&);
+     166             :   friend CoeffsMatrix operator+(const std::vector<double>&, const CoeffsMatrix&);
+     167             :   friend CoeffsMatrix operator+(const CoeffsMatrix&, const std::vector<double>&);
+     168             :   CoeffsMatrix& operator-=(const double);
+     169             :   friend CoeffsMatrix operator-(const double, const CoeffsMatrix&);
+     170             :   friend CoeffsMatrix operator-(const CoeffsMatrix&, const double);
+     171             :   CoeffsMatrix& operator-=(const std::vector<double>&);
+     172             :   friend CoeffsMatrix operator-(const std::vector<double>&, const CoeffsMatrix&);
+     173             :   friend CoeffsMatrix operator-(const CoeffsMatrix&, const std::vector<double>&);
+     174             :   CoeffsMatrix& operator+=(const CoeffsMatrix&);
+     175             :   CoeffsMatrix operator+(const CoeffsMatrix&) const;
+     176             :   CoeffsMatrix& operator-=(const CoeffsMatrix&);
+     177             :   CoeffsMatrix operator-(const CoeffsMatrix&) const;
+     178             :   //
+     179             :   static void averageMatrices(CoeffsMatrix&, CoeffsMatrix&);
+     180             :   static void averageMatrices(const std::vector<CoeffsMatrix*>&);
+     181             :   //
+     182             :   double getMinValue() const;
+     183             :   double getMaxValue() const;
+     184             :   //
+     185             :   void randomizeValuesGaussian(int);
+     186             :   //
+     187           0 :   void resetAveragingCounter() {averaging_counter=0;}
+     188             :   void setupExponentiallyDecayingAveraging(const unsigned int averaging_exp_decay_in) {averaging_exp_decay_=averaging_exp_decay_in;}
+     189             :   void turnOffExponentiallyDecayingAveraging() { averaging_exp_decay_=0;}
+     190             :   void resetAveraging();
+     191             :   void addToAverage(const CoeffsMatrix&);
+     192             :   void addToAverage(const CoeffsMatrix&, const unsigned int);
+     193             :   //
+     194             :   // file input/output stuff
+     195             :   void writeToFile(OFile&);
+     196             :   void writeToFile(const std::string&, const bool append_file=false, Action* action_pntr=NULL);
+     197             : private:
+     198             :   void writeDataToFile(OFile&);
+     199             :   void writeMatrixInfoToFile(OFile&);
+     200             :   void writeHeaderToFile(OFile&);
+     201             :   void writeDataDiagonalToFile(OFile&);
+     202             :   void writeDataFullToFile(OFile&);
+     203             : public:
+     204             :   Communicator& getCommunicator() const {return mycomm;}
+     205             : 
+     206             : };
+     207             : }
+     208             : }
+     209             : 
+     210             : 
+     211             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/CoeffsVector.cpp.func-sort-c.html b/coverage/ves/CoeffsVector.cpp.func-sort-c.html new file mode 100644 index 000000000000..8b7f17cccf65 --- /dev/null +++ b/coverage/ves/CoeffsVector.cpp.func-sort-c.html @@ -0,0 +1,469 @@ + + + + + + + + LCOV - plumed test coverage - ves/CoeffsVector.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - CoeffsVector.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:23245850.7 %
Date:2024-04-19 12:12:35Functions:459945.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12CoeffsVector10addToValueERKSt6vectorIjSaIjEEd0
_ZN4PLMD3ves12CoeffsVector10addToValueEmd0
_ZN4PLMD3ves12CoeffsVector10sumCommMPIERNS_12CommunicatorE0
_ZN4PLMD3ves12CoeffsVector10sumCommMPIEv0
_ZN4PLMD3ves12CoeffsVector11addToValuesERKSt6vectorIdSaIdEE0
_ZN4PLMD3ves12CoeffsVector11addToValuesEd0
_ZN4PLMD3ves12CoeffsVector11writeToFileERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIPS1_SaISB_EEbbPNS_6ActionE0
_ZN4PLMD3ves12CoeffsVector11writeToFileERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbbPNS_6ActionE0
_ZN4PLMD3ves12CoeffsVector11writeToFileERNS_5OFileERKSt6vectorIPS1_SaIS5_EEb0
_ZN4PLMD3ves12CoeffsVector12resizeCoeffsERKSt6vectorIjSaIjEE0
_ZN4PLMD3ves12CoeffsVector12resizeCoeffsERSt6vectorIPNS0_14BasisFunctionsESaIS4_EE0
_ZN4PLMD3ves12CoeffsVector14averageVectorsERKSt6vectorIPS1_SaIS3_EE0
_ZN4PLMD3ves12CoeffsVector14averageVectorsERS1_S2_0
_ZN4PLMD3ves12CoeffsVector14resetAveragingEv0
_ZN4PLMD3ves12CoeffsVector15normalizeCoeffsEv0
_ZN4PLMD3ves12CoeffsVector18subtractFromValuesEd0
_ZN4PLMD3ves12CoeffsVector18sumMultiSimCommMPIERNS_12CommunicatorE0
_ZN4PLMD3ves12CoeffsVector23randomizeValuesGaussianEi0
_ZN4PLMD3ves12CoeffsVector27setValuesFromDifferentShapeERKS1_0
_ZN4PLMD3ves12CoeffsVector8setValueERKSt6vectorIjSaIjEEd0
_ZN4PLMD3ves12CoeffsVector9sameShapeERS1_S2_0
_ZN4PLMD3ves12CoeffsVectorC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPNS0_12CoeffsMatrixERNS_12CommunicatorE0
_ZN4PLMD3ves12CoeffsVectorC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIS7_SaIS7_EERKSA_IjSaIjEERNS_12CommunicatorEb0
_ZN4PLMD3ves12CoeffsVectorC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorISA_IPNS_5ValueESaISC_EESaISE_EERSA_ISA_IPNS0_14BasisFunctionsESaISJ_EESaISL_EERNS_12CommunicatorEbS9_0
_ZN4PLMD3ves12CoeffsVectoraSEd0
_ZN4PLMD3ves12CoeffsVectorclERKSt6vectorIjSaIjEE0
_ZN4PLMD3ves12CoeffsVectorixERKSt6vectorIjSaIjEE0
_ZN4PLMD3ves12CoeffsVectormIEd0
_ZN4PLMD3ves12CoeffsVectorpLERKSt6vectorIdSaIdEE0
_ZN4PLMD3ves12CoeffsVectorpLEd0
_ZN4PLMD3vesmiERKNS0_12CoeffsVectorEd0
_ZN4PLMD3vesmiERKSt6vectorIdSaIdEERKNS0_12CoeffsVectorE0
_ZN4PLMD3vesmiEdRKNS0_12CoeffsVectorE0
_ZN4PLMD3vesmlERKNS0_12CoeffsVectorEd0
_ZN4PLMD3vesmlERKSt6vectorIdSaIdEERKNS0_12CoeffsVectorE0
_ZN4PLMD3vesplERKNS0_12CoeffsVectorERKSt6vectorIdSaIdEE0
_ZN4PLMD3vesplERKNS0_12CoeffsVectorEd0
_ZN4PLMD3vesplERKSt6vectorIdSaIdEERKNS0_12CoeffsVectorE0
_ZN4PLMD3vesplEdRKNS0_12CoeffsVectorE0
_ZNK4PLMD3ves12CoeffsVector11getMaxValueERm0
_ZNK4PLMD3ves12CoeffsVector11getMaxValueEv0
_ZNK4PLMD3ves12CoeffsVector11getMinValueERm0
_ZNK4PLMD3ves12CoeffsVector11getMinValueEv0
_ZNK4PLMD3ves12CoeffsVector14getMaxAbsValueEv0
_ZNK4PLMD3ves12CoeffsVector14getMinAbsValueERm0
_ZNK4PLMD3ves12CoeffsVector14getMinAbsValueEv0
_ZNK4PLMD3ves12CoeffsVector9getL1NormEv0
_ZNK4PLMD3ves12CoeffsVector9getLpNormEd0
_ZNK4PLMD3ves12CoeffsVector9sameShapeERNS0_12CoeffsMatrixE0
_ZNK4PLMD3ves12CoeffsVectorclERKSt6vectorIjSaIjEE0
_ZNK4PLMD3ves12CoeffsVectorixERKSt6vectorIjSaIjEE0
_ZNK4PLMD3ves12CoeffsVectorixEm0
_ZNK4PLMD3ves12CoeffsVectorngEv0
_ZNK4PLMD3ves12CoeffsVectorpsEv0
_ZNK4PLMD3ves12CoeffsVector11countValuesEd1
_ZN4PLMD3ves12CoeffsVector18setAllValuesToZeroEv2
_ZNK4PLMD3ves12CoeffsVector9sameShapeERS1_6
_ZN4PLMD3ves12CoeffsVector12addToAverageERKS1_20
_ZN4PLMD3ves12CoeffsVector18multiplyWithValuesERKSt6vectorIdSaIdEE20
_ZN4PLMD3ves12CoeffsVectormLERKSt6vectorIdSaIdEE20
_ZN4PLMD3vesmlERKNS0_12CoeffsVectorERKSt6vectorIdSaIdEE20
_ZN4PLMD3ves12CoeffsVector18readOneSetFromFileERNS_5IFileEb36
_ZN4PLMD3ves12CoeffsVector12readFromFileERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbb40
_ZN4PLMD3ves12CoeffsVector12readFromFileERNS_5IFileEbb75
_ZNK4PLMD3ves12CoeffsVector14getMaxAbsValueERm80
_ZNK4PLMD3ves12CoeffsVector6getRMSEv80
_ZNK4PLMD3ves12CoeffsVector7getNormEv80
_ZNK4PLMD3ves12CoeffsVector9getL2NormEv80
_ZN4PLMD3ves12CoeffsVector9setValuesEd174
_ZN4PLMD3ves12CoeffsVectorixEm178
_ZN4PLMD3ves12CoeffsVector8setValueEmd219
_ZN4PLMD3ves12CoeffsVectorC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIPNS_5ValueESaISC_EERSA_IPNS0_14BasisFunctionsESaISI_EERNS_12CommunicatorEb377
_ZN4PLMD3ves12CoeffsVector18readHeaderFromFileERNS_5IFileEb406
_ZN4PLMD3ves12CoeffsVector16readDataFromFileERNS_5IFileEb442
_ZN4PLMD3ves12CoeffsVectoraSERKSt6vectorIdSaIdEE453
_ZN4PLMD3ves12CoeffsVector9setValuesERKSt6vectorIdSaIdEE700
_ZN4PLMD3ves12CoeffsVector11writeToFileERNS_5OFileEPS1_b881
_ZN4PLMD3ves12CoeffsVector11writeToFileERNS_5OFileEb1467
_ZN4PLMD3ves12CoeffsVector15writeDataToFileERNS_5OFileERKSt6vectorIPS1_SaIS5_EEb2348
_ZNK4PLMD3ves12CoeffsVector17writeHeaderToFileERNS_5OFileE2348
_ZNK4PLMD3ves12CoeffsVectorplERKS1_22735
_ZN4PLMD3ves12CoeffsVectormLERKS1_22765
_ZNK4PLMD3ves12CoeffsVectormlERKS1_22765
_ZN4PLMD3ves12CoeffsVector18subtractFromValuesERKSt6vectorIdSaIdEE22810
_ZN4PLMD3ves12CoeffsVectormIERKSt6vectorIdSaIdEE22810
_ZN4PLMD3vesmiERKNS0_12CoeffsVectorERKSt6vectorIdSaIdEE22810
_ZN4PLMD3ves12CoeffsVector5clearEv23209
_ZN4PLMD3ves12CoeffsVector9setValuesERKS1_23410
_ZNK4PLMD3ves12CoeffsVectormiERKS1_45420
_ZN4PLMD3vesmlEdRKNS0_12CoeffsVectorE45430
_ZN4PLMD3ves12CoeffsVector18subtractFromValuesERKS1_45440
_ZN4PLMD3ves12CoeffsVectormIERKS1_45440
_ZN4PLMD3ves12CoeffsVectormLEd45470
_ZN4PLMD3ves12CoeffsVector14scaleAllValuesEd45477
_ZN4PLMD3ves12CoeffsVector11addToValuesERKS1_68145
_ZN4PLMD3ves12CoeffsVectorpLERKS1_68145
_ZN4PLMD3ves12CoeffsVectorD2Ev341962
_ZN4PLMD3ves12CoeffsVectorclEm1790345
_ZNK4PLMD3ves12CoeffsVectorclEm1790345
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/CoeffsVector.cpp.func.html b/coverage/ves/CoeffsVector.cpp.func.html new file mode 100644 index 000000000000..b379297b3d17 --- /dev/null +++ b/coverage/ves/CoeffsVector.cpp.func.html @@ -0,0 +1,469 @@ + + + + + + + + LCOV - plumed test coverage - ves/CoeffsVector.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - CoeffsVector.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:23245850.7 %
Date:2024-04-19 12:12:35Functions:459945.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12CoeffsVector10addToValueERKSt6vectorIjSaIjEEd0
_ZN4PLMD3ves12CoeffsVector10addToValueEmd0
_ZN4PLMD3ves12CoeffsVector10sumCommMPIERNS_12CommunicatorE0
_ZN4PLMD3ves12CoeffsVector10sumCommMPIEv0
_ZN4PLMD3ves12CoeffsVector11addToValuesERKS1_68145
_ZN4PLMD3ves12CoeffsVector11addToValuesERKSt6vectorIdSaIdEE0
_ZN4PLMD3ves12CoeffsVector11addToValuesEd0
_ZN4PLMD3ves12CoeffsVector11writeToFileERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIPS1_SaISB_EEbbPNS_6ActionE0
_ZN4PLMD3ves12CoeffsVector11writeToFileERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbbPNS_6ActionE0
_ZN4PLMD3ves12CoeffsVector11writeToFileERNS_5OFileEPS1_b881
_ZN4PLMD3ves12CoeffsVector11writeToFileERNS_5OFileERKSt6vectorIPS1_SaIS5_EEb0
_ZN4PLMD3ves12CoeffsVector11writeToFileERNS_5OFileEb1467
_ZN4PLMD3ves12CoeffsVector12addToAverageERKS1_20
_ZN4PLMD3ves12CoeffsVector12readFromFileERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbb40
_ZN4PLMD3ves12CoeffsVector12readFromFileERNS_5IFileEbb75
_ZN4PLMD3ves12CoeffsVector12resizeCoeffsERKSt6vectorIjSaIjEE0
_ZN4PLMD3ves12CoeffsVector12resizeCoeffsERSt6vectorIPNS0_14BasisFunctionsESaIS4_EE0
_ZN4PLMD3ves12CoeffsVector14averageVectorsERKSt6vectorIPS1_SaIS3_EE0
_ZN4PLMD3ves12CoeffsVector14averageVectorsERS1_S2_0
_ZN4PLMD3ves12CoeffsVector14resetAveragingEv0
_ZN4PLMD3ves12CoeffsVector14scaleAllValuesEd45477
_ZN4PLMD3ves12CoeffsVector15normalizeCoeffsEv0
_ZN4PLMD3ves12CoeffsVector15writeDataToFileERNS_5OFileERKSt6vectorIPS1_SaIS5_EEb2348
_ZN4PLMD3ves12CoeffsVector16readDataFromFileERNS_5IFileEb442
_ZN4PLMD3ves12CoeffsVector18multiplyWithValuesERKSt6vectorIdSaIdEE20
_ZN4PLMD3ves12CoeffsVector18readHeaderFromFileERNS_5IFileEb406
_ZN4PLMD3ves12CoeffsVector18readOneSetFromFileERNS_5IFileEb36
_ZN4PLMD3ves12CoeffsVector18setAllValuesToZeroEv2
_ZN4PLMD3ves12CoeffsVector18subtractFromValuesERKS1_45440
_ZN4PLMD3ves12CoeffsVector18subtractFromValuesERKSt6vectorIdSaIdEE22810
_ZN4PLMD3ves12CoeffsVector18subtractFromValuesEd0
_ZN4PLMD3ves12CoeffsVector18sumMultiSimCommMPIERNS_12CommunicatorE0
_ZN4PLMD3ves12CoeffsVector23randomizeValuesGaussianEi0
_ZN4PLMD3ves12CoeffsVector27setValuesFromDifferentShapeERKS1_0
_ZN4PLMD3ves12CoeffsVector5clearEv23209
_ZN4PLMD3ves12CoeffsVector8setValueERKSt6vectorIjSaIjEEd0
_ZN4PLMD3ves12CoeffsVector8setValueEmd219
_ZN4PLMD3ves12CoeffsVector9sameShapeERS1_S2_0
_ZN4PLMD3ves12CoeffsVector9setValuesERKS1_23410
_ZN4PLMD3ves12CoeffsVector9setValuesERKSt6vectorIdSaIdEE700
_ZN4PLMD3ves12CoeffsVector9setValuesEd174
_ZN4PLMD3ves12CoeffsVectorC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPNS0_12CoeffsMatrixERNS_12CommunicatorE0
_ZN4PLMD3ves12CoeffsVectorC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIPNS_5ValueESaISC_EERSA_IPNS0_14BasisFunctionsESaISI_EERNS_12CommunicatorEb377
_ZN4PLMD3ves12CoeffsVectorC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIS7_SaIS7_EERKSA_IjSaIjEERNS_12CommunicatorEb0
_ZN4PLMD3ves12CoeffsVectorC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorISA_IPNS_5ValueESaISC_EESaISE_EERSA_ISA_IPNS0_14BasisFunctionsESaISJ_EESaISL_EERNS_12CommunicatorEbS9_0
_ZN4PLMD3ves12CoeffsVectorD2Ev341962
_ZN4PLMD3ves12CoeffsVectoraSERKSt6vectorIdSaIdEE453
_ZN4PLMD3ves12CoeffsVectoraSEd0
_ZN4PLMD3ves12CoeffsVectorclERKSt6vectorIjSaIjEE0
_ZN4PLMD3ves12CoeffsVectorclEm1790345
_ZN4PLMD3ves12CoeffsVectorixERKSt6vectorIjSaIjEE0
_ZN4PLMD3ves12CoeffsVectorixEm178
_ZN4PLMD3ves12CoeffsVectormIERKS1_45440
_ZN4PLMD3ves12CoeffsVectormIERKSt6vectorIdSaIdEE22810
_ZN4PLMD3ves12CoeffsVectormIEd0
_ZN4PLMD3ves12CoeffsVectormLERKS1_22765
_ZN4PLMD3ves12CoeffsVectormLERKSt6vectorIdSaIdEE20
_ZN4PLMD3ves12CoeffsVectormLEd45470
_ZN4PLMD3ves12CoeffsVectorpLERKS1_68145
_ZN4PLMD3ves12CoeffsVectorpLERKSt6vectorIdSaIdEE0
_ZN4PLMD3ves12CoeffsVectorpLEd0
_ZN4PLMD3vesmiERKNS0_12CoeffsVectorERKSt6vectorIdSaIdEE22810
_ZN4PLMD3vesmiERKNS0_12CoeffsVectorEd0
_ZN4PLMD3vesmiERKSt6vectorIdSaIdEERKNS0_12CoeffsVectorE0
_ZN4PLMD3vesmiEdRKNS0_12CoeffsVectorE0
_ZN4PLMD3vesmlERKNS0_12CoeffsVectorERKSt6vectorIdSaIdEE20
_ZN4PLMD3vesmlERKNS0_12CoeffsVectorEd0
_ZN4PLMD3vesmlERKSt6vectorIdSaIdEERKNS0_12CoeffsVectorE0
_ZN4PLMD3vesmlEdRKNS0_12CoeffsVectorE45430
_ZN4PLMD3vesplERKNS0_12CoeffsVectorERKSt6vectorIdSaIdEE0
_ZN4PLMD3vesplERKNS0_12CoeffsVectorEd0
_ZN4PLMD3vesplERKSt6vectorIdSaIdEERKNS0_12CoeffsVectorE0
_ZN4PLMD3vesplEdRKNS0_12CoeffsVectorE0
_ZNK4PLMD3ves12CoeffsVector11countValuesEd1
_ZNK4PLMD3ves12CoeffsVector11getMaxValueERm0
_ZNK4PLMD3ves12CoeffsVector11getMaxValueEv0
_ZNK4PLMD3ves12CoeffsVector11getMinValueERm0
_ZNK4PLMD3ves12CoeffsVector11getMinValueEv0
_ZNK4PLMD3ves12CoeffsVector14getMaxAbsValueERm80
_ZNK4PLMD3ves12CoeffsVector14getMaxAbsValueEv0
_ZNK4PLMD3ves12CoeffsVector14getMinAbsValueERm0
_ZNK4PLMD3ves12CoeffsVector14getMinAbsValueEv0
_ZNK4PLMD3ves12CoeffsVector17writeHeaderToFileERNS_5OFileE2348
_ZNK4PLMD3ves12CoeffsVector6getRMSEv80
_ZNK4PLMD3ves12CoeffsVector7getNormEv80
_ZNK4PLMD3ves12CoeffsVector9getL1NormEv0
_ZNK4PLMD3ves12CoeffsVector9getL2NormEv80
_ZNK4PLMD3ves12CoeffsVector9getLpNormEd0
_ZNK4PLMD3ves12CoeffsVector9sameShapeERNS0_12CoeffsMatrixE0
_ZNK4PLMD3ves12CoeffsVector9sameShapeERS1_6
_ZNK4PLMD3ves12CoeffsVectorclERKSt6vectorIjSaIjEE0
_ZNK4PLMD3ves12CoeffsVectorclEm1790345
_ZNK4PLMD3ves12CoeffsVectorixERKSt6vectorIjSaIjEE0
_ZNK4PLMD3ves12CoeffsVectorixEm0
_ZNK4PLMD3ves12CoeffsVectormiERKS1_45420
_ZNK4PLMD3ves12CoeffsVectormlERKS1_22765
_ZNK4PLMD3ves12CoeffsVectorngEv0
_ZNK4PLMD3ves12CoeffsVectorplERKS1_22735
_ZNK4PLMD3ves12CoeffsVectorpsEv0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/CoeffsVector.cpp.gcov.html b/coverage/ves/CoeffsVector.cpp.gcov.html new file mode 100644 index 000000000000..d968b7563f82 --- /dev/null +++ b/coverage/ves/CoeffsVector.cpp.gcov.html @@ -0,0 +1,972 @@ + + + + + + + + LCOV - plumed test coverage - ves/CoeffsVector.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - CoeffsVector.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:23245850.7 %
Date:2024-04-19 12:12:35Functions:459945.5 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "CoeffsVector.h"
+      24             : #include "CoeffsMatrix.h"
+      25             : #include "BasisFunctions.h"
+      26             : 
+      27             : #include "tools/Tools.h"
+      28             : #include "core/Value.h"
+      29             : #include "tools/File.h"
+      30             : #include "tools/Exception.h"
+      31             : #include "tools/Random.h"
+      32             : #include "tools/Communicator.h"
+      33             : 
+      34             : #include <vector>
+      35             : #include <cmath>
+      36             : #include <iostream>
+      37             : #include <sstream>
+      38             : #include <cstdio>
+      39             : #include <cfloat>
+      40             : 
+      41             : 
+      42             : namespace PLMD {
+      43             : namespace ves {
+      44             : 
+      45           0 : CoeffsVector::CoeffsVector(
+      46             :   const std::string& label,
+      47             :   const std::vector<std::string>& dimension_labels,
+      48             :   const std::vector<unsigned int>& indices_shape,
+      49             :   Communicator& cc,
+      50           0 :   const bool use_iteration_counter):
+      51             :   CoeffsBase(label,dimension_labels,indices_shape,use_iteration_counter),
+      52           0 :   data(0),
+      53           0 :   averaging_counter(0),
+      54           0 :   averaging_exp_decay_(0),
+      55           0 :   mycomm(cc)
+      56             : {
+      57           0 :   clear();
+      58           0 : }
+      59             : 
+      60             : 
+      61         377 : CoeffsVector::CoeffsVector(
+      62             :   const std::string& label,
+      63             :   const std::vector<Value*>& args,
+      64             :   std::vector<BasisFunctions*>& basisf,
+      65             :   Communicator& cc,
+      66         377 :   const bool use_iteration_counter):
+      67             :   CoeffsBase(label,args,basisf,use_iteration_counter),
+      68         377 :   data(0),
+      69         377 :   averaging_counter(0),
+      70         377 :   averaging_exp_decay_(0),
+      71         377 :   mycomm(cc)
+      72             : {
+      73         377 :   clear();
+      74         377 : }
+      75             : 
+      76             : 
+      77           0 : CoeffsVector::CoeffsVector(
+      78             :   const std::string& label,
+      79             :   std::vector<std::vector<Value*> >& argsv,
+      80             :   std::vector<std::vector<BasisFunctions*> >& basisfv,
+      81             :   Communicator& cc,
+      82             :   const bool use_iteration_counter,
+      83           0 :   const std::string& multicoeffs_label):
+      84             :   CoeffsBase(label,argsv,basisfv,use_iteration_counter,multicoeffs_label),
+      85           0 :   data(0),
+      86           0 :   averaging_counter(0),
+      87           0 :   averaging_exp_decay_(0),
+      88           0 :   mycomm(cc)
+      89             : {
+      90           0 :   clear();
+      91           0 : }
+      92             : 
+      93             : 
+      94           0 : CoeffsVector::CoeffsVector(
+      95             :   const std::string& label,
+      96             :   CoeffsMatrix* coeffsMat,
+      97           0 :   Communicator& cc):
+      98             :   CoeffsBase( *(static_cast<CoeffsBase*>(coeffsMat)) ),
+      99           0 :   data(0),
+     100           0 :   averaging_counter(0),
+     101           0 :   averaging_exp_decay_(0),
+     102           0 :   mycomm(cc)
+     103             : {
+     104           0 :   clear();
+     105           0 : }
+     106             : 
+     107             : 
+     108      341962 : CoeffsVector::~CoeffsVector() {}
+     109             : 
+     110             : 
+     111       23209 : void CoeffsVector::clear() {
+     112       23209 :   data.resize(getSize());
+     113     1833419 :   for(size_t i=0; i<data.size(); i++) {
+     114     1810210 :     data[i]=0.0;
+     115             :   }
+     116       23209 : }
+     117             : 
+     118             : 
+     119           2 : void CoeffsVector::setAllValuesToZero() {
+     120          24 :   for(size_t i=0; i<data.size(); i++) {
+     121          22 :     data[i]=0.0;
+     122             :   }
+     123           2 : }
+     124             : 
+     125             : 
+     126           6 : bool CoeffsVector::sameShape(CoeffsVector& coeffsvector_in) const {
+     127           6 :   return CoeffsBase::sameShape( *(static_cast<CoeffsBase*>(&coeffsvector_in)) );
+     128             : }
+     129             : 
+     130             : 
+     131           0 : bool CoeffsVector::sameShape(CoeffsMatrix& coeffsmat_in) const {
+     132           0 :   return CoeffsBase::sameShape( *(static_cast<CoeffsBase*>(&coeffsmat_in)) );
+     133             : }
+     134             : 
+     135             : 
+     136           0 : bool CoeffsVector::sameShape(CoeffsVector& coeffsvec0, CoeffsVector& coeffsvec1) {
+     137           0 :   return coeffsvec0.sameShape(coeffsvec1);
+     138             : }
+     139             : 
+     140             : 
+     141           0 : void CoeffsVector::resizeCoeffs(const std::vector<unsigned int>& indices_shape_new) {
+     142           0 :   CoeffsVector coeffsVecOld(*this);
+     143           0 :   resizeIndices(indices_shape_new);
+     144           0 :   clear();
+     145           0 :   setValuesFromDifferentShape(coeffsVecOld);
+     146           0 : }
+     147             : 
+     148             : 
+     149           0 : void CoeffsVector::resizeCoeffs(std::vector<BasisFunctions*>& basisf_new) {
+     150           0 :   CoeffsVector coeffsVecOld(*this);
+     151           0 :   resizeIndices(basisf_new);
+     152           0 :   clear();
+     153           0 :   setValuesFromDifferentShape(coeffsVecOld);
+     154           0 : }
+     155             : 
+     156             : 
+     157           0 : void CoeffsVector::sumCommMPI() {
+     158           0 :   mycomm.Sum(data);
+     159           0 : }
+     160             : 
+     161             : 
+     162           0 : void CoeffsVector::sumCommMPI(Communicator& cc) {
+     163           0 :   cc.Sum(data);
+     164           0 : }
+     165             : 
+     166             : 
+     167           0 : void CoeffsVector::sumMultiSimCommMPI(Communicator& multi_sim_cc) {
+     168           0 :   if(mycomm.Get_rank()==0) {
+     169           0 :     double nwalkers = static_cast<double>(multi_sim_cc.Get_size());
+     170           0 :     multi_sim_cc.Sum(data);
+     171           0 :     scaleAllValues(1.0/nwalkers);
+     172             :   }
+     173           0 :   mycomm.Bcast(data,0);
+     174           0 : }
+     175             : 
+     176             : 
+     177         178 : double& CoeffsVector::operator[](const size_t index) {
+     178             :   plumed_dbg_assert(index<data.size());
+     179         178 :   return data[index];
+     180             : }
+     181             : 
+     182             : 
+     183           0 : const double& CoeffsVector::operator[](const size_t index) const {
+     184             :   plumed_dbg_assert(index<data.size());
+     185           0 :   return data[index];
+     186             : }
+     187             : 
+     188             : 
+     189           0 : double& CoeffsVector::operator[](const std::vector<unsigned int>& indices) {
+     190           0 :   return data[getIndex(indices)];
+     191             : }
+     192             : 
+     193             : 
+     194           0 : const double& CoeffsVector::operator[](const std::vector<unsigned int>& indices) const {
+     195           0 :   return data[getIndex(indices)];
+     196             : }
+     197             : 
+     198             : 
+     199     1790345 : double& CoeffsVector::operator()(const size_t index) {
+     200             :   plumed_dbg_assert(index<data.size());
+     201     1790345 :   return data[index];
+     202             : }
+     203             : 
+     204             : 
+     205     1790345 : const double& CoeffsVector::operator()(const size_t index) const {
+     206             :   plumed_dbg_assert(index<data.size());
+     207     1790345 :   return data[index];
+     208             : }
+     209             : 
+     210             : 
+     211           0 : double& CoeffsVector::operator()(const std::vector<unsigned int>& indices) {
+     212           0 :   return data[getIndex(indices)];
+     213             : }
+     214             : 
+     215             : 
+     216           0 : const double& CoeffsVector::operator()(const std::vector<unsigned int>& indices) const {
+     217           0 :   return data[getIndex(indices)];
+     218             : }
+     219             : 
+     220             : 
+     221         219 : void CoeffsVector::setValue(const size_t index, const double value) {
+     222             :   plumed_dbg_assert(index<data.size());
+     223         219 :   data[index]=value;
+     224         219 : }
+     225             : 
+     226             : 
+     227           0 : void CoeffsVector::setValue(const std::vector<unsigned int>& indices, const double value) {
+     228           0 :   setValue(getIndex(indices),value);
+     229           0 : }
+     230             : 
+     231             : 
+     232           0 : void CoeffsVector::addToValue(const size_t index, const double value) {
+     233             :   plumed_dbg_assert(index<data.size());
+     234           0 :   data[index]+=value;
+     235           0 : }
+     236             : 
+     237             : 
+     238           0 : void CoeffsVector::addToValue(const std::vector<unsigned int>& indices, const double value) {
+     239           0 :   addToValue(getIndex(indices),value);
+     240           0 : }
+     241             : 
+     242             : 
+     243       45477 : void CoeffsVector::scaleAllValues(const double scalef) {
+     244     3626338 :   for(size_t i=0; i<data.size(); i++) {
+     245     3580861 :     data[i]*=scalef;
+     246             :   }
+     247       45477 : }
+     248             : 
+     249             : 
+     250       45470 : CoeffsVector& CoeffsVector::operator*=(const double scalef) {
+     251       45470 :   scaleAllValues(scalef);
+     252       45470 :   return *this;
+     253             : }
+     254             : 
+     255             : 
+     256       45430 : CoeffsVector operator*(const double scalef, const CoeffsVector& coeffsvector) {
+     257       45430 :   return CoeffsVector(coeffsvector)*=scalef;
+     258             : }
+     259             : 
+     260             : 
+     261           0 : CoeffsVector operator*(const CoeffsVector& coeffsvector, const double scalef) {
+     262           0 :   return scalef*coeffsvector;
+     263             : }
+     264             : 
+     265             : 
+     266          20 : void CoeffsVector::multiplyWithValues(const std::vector<double>& values) {
+     267          20 :   plumed_massert( data.size()==values.size(), "Incorrect size");
+     268         240 :   for(size_t i=0; i<data.size(); i++) {
+     269         220 :     data[i]*=values[i];
+     270             :   }
+     271          20 : }
+     272             : 
+     273             : 
+     274       22765 : CoeffsVector& CoeffsVector::operator*=(const CoeffsVector& other_coeffsvector) {
+     275       22765 :   plumed_massert(data.size()==other_coeffsvector.getSize(),"Coeffs vectors do not have the same size");
+     276     1813440 :   for(size_t i=0; i<data.size(); i++) {
+     277     1790675 :     data[i]*=other_coeffsvector.data[i];
+     278             :   }
+     279       22765 :   return *this;
+     280             : }
+     281             : 
+     282             : 
+     283       22765 : CoeffsVector CoeffsVector::operator*(const CoeffsVector& other_coeffsvector) const {
+     284       22765 :   return CoeffsVector(*this)*=other_coeffsvector;
+     285             : }
+     286             : 
+     287             : 
+     288           0 : CoeffsVector operator*(const std::vector<double>& values, const CoeffsVector& coeffsvector) {
+     289           0 :   return coeffsvector*values;
+     290             : }
+     291             : 
+     292             : 
+     293          20 : CoeffsVector& CoeffsVector::operator*=(const std::vector<double>& values) {
+     294          20 :   multiplyWithValues(values);
+     295          20 :   return *this;
+     296             : }
+     297             : 
+     298             : 
+     299          20 : CoeffsVector operator*(const CoeffsVector& coeffsvector, const std::vector<double>& values) {
+     300          20 :   return CoeffsVector(coeffsvector)*=values;
+     301             : }
+     302             : 
+     303             : 
+     304         174 : void CoeffsVector::setValues(const double value) {
+     305        8402 :   for(size_t i=0; i<data.size(); i++) {
+     306        8228 :     data[i]=value;
+     307             :   }
+     308         174 : }
+     309             : 
+     310             : 
+     311         700 : void CoeffsVector::setValues(const std::vector<double>& values) {
+     312         700 :   plumed_massert( data.size()==values.size(), "Incorrect size");
+     313       23133 :   for(size_t i=0; i<data.size(); i++) {
+     314       22433 :     data[i]=values[i];
+     315             :   }
+     316         700 : }
+     317             : 
+     318             : 
+     319       23410 : void CoeffsVector::setValues(const CoeffsVector& other_coeffsvector) {
+     320       23410 :   plumed_massert( data.size()==other_coeffsvector.getSize(), "Incorrect size");
+     321     1847404 :   for(size_t i=0; i<data.size(); i++) {
+     322     1823994 :     data[i]=other_coeffsvector.data[i];
+     323             :   }
+     324       23410 : }
+     325             : 
+     326             : 
+     327           0 : CoeffsVector& CoeffsVector::operator=(const double value) {
+     328           0 :   setValues(value);
+     329           0 :   return *this;
+     330             : }
+     331             : 
+     332             : 
+     333         453 : CoeffsVector& CoeffsVector::operator=(const std::vector<double>& values) {
+     334         453 :   setValues(values);
+     335         453 :   return *this;
+     336             : }
+     337             : 
+     338             : 
+     339             : // CoeffsVector& CoeffsVector::operator=(const CoeffsVector& other_coeffsvector) {
+     340             : //   setValues(other_coeffsvector);
+     341             : //   return *this;
+     342             : // }
+     343             : 
+     344             : 
+     345           0 : CoeffsVector CoeffsVector::operator+() const {
+     346           0 :   return *this;
+     347             : }
+     348             : 
+     349             : 
+     350           0 : CoeffsVector CoeffsVector::operator-() const {
+     351           0 :   return CoeffsVector(*this)*=-1.0;
+     352             : }
+     353             : 
+     354             : 
+     355           0 : void CoeffsVector::addToValues(const double value) {
+     356           0 :   for(size_t i=0; i<data.size(); i++) {
+     357           0 :     data[i]+=value;
+     358             :   }
+     359           0 : }
+     360             : 
+     361             : 
+     362           0 : void CoeffsVector::addToValues(const std::vector<double>& values) {
+     363           0 :   plumed_massert( data.size()==values.size(), "Incorrect size");
+     364           0 :   for(size_t i=0; i<data.size(); i++) {
+     365           0 :     data[i]+=values[i];
+     366             :   }
+     367           0 : }
+     368             : 
+     369             : 
+     370       68145 : void CoeffsVector::addToValues(const CoeffsVector& other_coeffsvector) {
+     371       68145 :   plumed_massert( data.size()==other_coeffsvector.getSize(), "Incorrect size");
+     372     5438520 :   for(size_t i=0; i<data.size(); i++) {
+     373     5370375 :     data[i]+=other_coeffsvector.data[i];
+     374             :   }
+     375       68145 : }
+     376             : 
+     377             : 
+     378           0 : void CoeffsVector::subtractFromValues(const double value) {
+     379           0 :   for(size_t i=0; i<data.size(); i++) {
+     380           0 :     data[i]-=value;
+     381             :   }
+     382           0 : }
+     383             : 
+     384             : 
+     385       22810 : void CoeffsVector::subtractFromValues(const std::vector<double>& values) {
+     386       22810 :   plumed_massert( data.size()==values.size(), "Incorrect size");
+     387     1823850 :   for(size_t i=0; i<data.size(); i++) {
+     388     1801040 :     data[i]-=values[i];
+     389             :   }
+     390       22810 : }
+     391             : 
+     392             : 
+     393       45440 : void CoeffsVector::subtractFromValues(const CoeffsVector& other_coeffsvector) {
+     394       45440 :   plumed_massert( data.size()==other_coeffsvector.getSize(), "Incorrect size");
+     395     3625800 :   for(size_t i=0; i<data.size(); i++) {
+     396     3580360 :     data[i]-=other_coeffsvector.data[i];
+     397             :   }
+     398       45440 : }
+     399             : 
+     400             : 
+     401           0 : CoeffsVector& CoeffsVector::operator+=(const double value) {
+     402           0 :   addToValues(value);
+     403           0 :   return *this;
+     404             : }
+     405             : 
+     406             : 
+     407           0 : CoeffsVector operator+(const double value, const CoeffsVector& coeffsvector) {
+     408           0 :   return coeffsvector+value;
+     409             : }
+     410             : 
+     411             : 
+     412           0 : CoeffsVector operator+(const CoeffsVector& coeffsvector, const double value) {
+     413           0 :   return CoeffsVector(coeffsvector)+=value;
+     414             : }
+     415             : 
+     416             : 
+     417           0 : CoeffsVector& CoeffsVector::operator+=(const std::vector<double>& values) {
+     418           0 :   addToValues(values);
+     419           0 :   return *this;
+     420             : }
+     421             : 
+     422             : 
+     423           0 : CoeffsVector operator+(const std::vector<double>& values, const CoeffsVector& coeffsvector) {
+     424           0 :   return coeffsvector+values;
+     425             : }
+     426             : 
+     427             : 
+     428           0 : CoeffsVector operator+(const CoeffsVector& coeffsvector, const std::vector<double>& values) {
+     429           0 :   return CoeffsVector(coeffsvector)+=values;
+     430             : }
+     431             : 
+     432             : 
+     433           0 : CoeffsVector& CoeffsVector::operator-=(const double value) {
+     434           0 :   subtractFromValues(value);
+     435           0 :   return *this;
+     436             : }
+     437             : 
+     438             : 
+     439           0 : CoeffsVector operator-(const double value, const CoeffsVector& coeffsvector) {
+     440           0 :   return -1.0*coeffsvector+value;
+     441             : }
+     442             : 
+     443             : 
+     444           0 : CoeffsVector operator-(const CoeffsVector& coeffsvector, const double value) {
+     445           0 :   return CoeffsVector(coeffsvector)-=value;
+     446             : }
+     447             : 
+     448             : 
+     449       22810 : CoeffsVector& CoeffsVector::operator-=(const std::vector<double>& values) {
+     450       22810 :   subtractFromValues(values);
+     451       22810 :   return *this;
+     452             : }
+     453             : 
+     454             : 
+     455           0 : CoeffsVector operator-(const std::vector<double>& values, const CoeffsVector& coeffsvector) {
+     456           0 :   return -1.0*coeffsvector+values;
+     457             : }
+     458             : 
+     459             : 
+     460       22810 : CoeffsVector operator-(const CoeffsVector& coeffsvector, const std::vector<double>& values) {
+     461       22810 :   return CoeffsVector(coeffsvector)-=values;
+     462             : }
+     463             : 
+     464             : 
+     465       68145 : CoeffsVector& CoeffsVector::operator+=(const CoeffsVector& other_coeffsvector) {
+     466       68145 :   addToValues(other_coeffsvector);
+     467       68145 :   return *this;
+     468             : }
+     469             : 
+     470             : 
+     471       22735 : CoeffsVector CoeffsVector::operator+(const CoeffsVector& other_coeffsvector) const {
+     472       22735 :   return CoeffsVector(*this)+=other_coeffsvector;
+     473             : }
+     474             : 
+     475             : 
+     476       45440 : CoeffsVector& CoeffsVector::operator-=(const CoeffsVector& other_coeffsvector) {
+     477       45440 :   subtractFromValues(other_coeffsvector);
+     478       45440 :   return *this;
+     479             : }
+     480             : 
+     481             : 
+     482       45420 : CoeffsVector CoeffsVector::operator-(const CoeffsVector& other_coeffsvector) const {
+     483       45420 :   return CoeffsVector(*this)-=other_coeffsvector;
+     484             : }
+     485             : 
+     486             : 
+     487           0 : void CoeffsVector::setValuesFromDifferentShape(const CoeffsVector& other_coeffsvector) {
+     488           0 :   plumed_massert(numberOfDimensions()==other_coeffsvector.numberOfDimensions(),"both coeffs vector need to have the same dimension");
+     489           0 :   for(size_t i=0; i<data.size(); i++) {
+     490           0 :     std::vector<unsigned int> indices=getIndices(i);
+     491           0 :     if(other_coeffsvector.indicesExist(indices)) {
+     492           0 :       size_t oidx = other_coeffsvector.getIndex(indices);
+     493           0 :       data[i] = other_coeffsvector.data[oidx];
+     494             :     }
+     495             :   }
+     496           0 : }
+     497             : 
+     498             : 
+     499           0 : void CoeffsVector::averageVectors(CoeffsVector& coeffsvec0, CoeffsVector& coeffsvec1) {
+     500           0 :   plumed_massert(sameShape(coeffsvec0,coeffsvec1),"both CoeffsVector objects need to have the same shape");
+     501           0 :   for(size_t i=0; i<coeffsvec0.getSize(); i++) {
+     502           0 :     coeffsvec0.data[i] = coeffsvec1.data[i] = 0.5 * (coeffsvec0.data[i]+coeffsvec1.data[i]);
+     503             :   }
+     504           0 : }
+     505             : 
+     506             : 
+     507           0 : void CoeffsVector::averageVectors(const std::vector<CoeffsVector*>& coeffsvecSet) {
+     508           0 :   const double norm_factor = 1.0/static_cast<double>(coeffsvecSet.size());
+     509           0 :   for(unsigned int k=1; k<coeffsvecSet.size(); k++) {
+     510           0 :     plumed_massert(coeffsvecSet[0]->sameShape(*coeffsvecSet[k]),"All CoeffsVector objects need to have the same shape");
+     511             :   }
+     512           0 :   for(size_t i=0; i<coeffsvecSet[0]->getSize(); i++) {
+     513             :     double value = 0.0;
+     514           0 :     for(unsigned int k=0; k<coeffsvecSet.size(); k++) {
+     515           0 :       value += coeffsvecSet[k]->data[i];
+     516             :     }
+     517           0 :     value *= norm_factor;
+     518           0 :     for(unsigned int k=0; k<coeffsvecSet.size(); k++) {
+     519           0 :       coeffsvecSet[k]->data[i] = value;
+     520             :     }
+     521             :   }
+     522           0 : }
+     523             : 
+     524             : 
+     525           0 : double CoeffsVector::getMinValue() const {
+     526           0 :   size_t min_index=0;
+     527           0 :   return getMinValue(min_index);
+     528             : }
+     529             : 
+     530             : 
+     531           0 : double CoeffsVector::getMinValue(size_t& min_index) const {
+     532           0 :   min_index=0;
+     533             :   double min_value=DBL_MAX;
+     534           0 :   for(size_t i=0; i<data.size(); i++) {
+     535           0 :     if(data[i]<min_value) {
+     536             :       min_value=data[i];
+     537           0 :       min_index=i;
+     538             :     }
+     539             :   }
+     540           0 :   return min_value;
+     541             : }
+     542             : 
+     543             : 
+     544           0 : double CoeffsVector::getMinAbsValue() const {
+     545           0 :   size_t min_index=0;
+     546           0 :   return getMinAbsValue(min_index);
+     547             : }
+     548             : 
+     549             : 
+     550           0 : double CoeffsVector::getMinAbsValue(size_t& min_index) const {
+     551           0 :   min_index=0;
+     552             :   double min_value=DBL_MAX;
+     553           0 :   for(size_t i=0; i<data.size(); i++) {
+     554           0 :     if(std::abs(data[i])<min_value) {
+     555             :       min_value=std::abs(data[i]);
+     556           0 :       min_index=i;
+     557             :     }
+     558             :   }
+     559           0 :   return min_value;
+     560             : }
+     561             : 
+     562             : 
+     563           0 : double CoeffsVector::getMaxValue() const {
+     564           0 :   size_t max_index=0;
+     565           0 :   return getMaxValue(max_index);
+     566             : }
+     567             : 
+     568             : 
+     569           0 : double CoeffsVector::getMaxValue(size_t& max_index) const {
+     570           0 :   max_index=0;
+     571             :   double max_value=DBL_MIN;
+     572           0 :   for(size_t i=0; i<data.size(); i++) {
+     573           0 :     if(data[i]>max_value) {
+     574             :       max_value=data[i];
+     575           0 :       max_index=i;
+     576             :     }
+     577             :   }
+     578           0 :   return max_value;
+     579             : }
+     580             : 
+     581             : 
+     582           0 : double CoeffsVector::getMaxAbsValue() const {
+     583           0 :   size_t max_index=0;
+     584           0 :   return getMaxAbsValue(max_index);
+     585             : }
+     586             : 
+     587             : 
+     588          80 : double CoeffsVector::getMaxAbsValue(size_t& max_index) const {
+     589          80 :   max_index=0;
+     590             :   double max_value=0.0;
+     591         960 :   for(size_t i=0; i<data.size(); i++) {
+     592         880 :     if(std::abs(data[i])>max_value) {
+     593             :       max_value=std::abs(data[i]);
+     594         180 :       max_index=i;
+     595             :     }
+     596             :   }
+     597          80 :   return max_value;
+     598             : }
+     599             : 
+     600             : 
+     601          80 : double CoeffsVector::getNorm() const {
+     602          80 :   return getL2Norm();
+     603             : }
+     604             : 
+     605             : 
+     606           0 : double CoeffsVector::getL1Norm() const {
+     607             :   double norm=0.0;
+     608           0 :   for(size_t i=0; i<data.size(); i++) {
+     609           0 :     norm+=std::abs(data[i]);
+     610             :   }
+     611           0 :   return norm;
+     612             : }
+     613             : 
+     614             : 
+     615          80 : double CoeffsVector::getL2Norm() const {
+     616             :   double norm=0.0;
+     617         960 :   for(size_t i=0; i<data.size(); i++) {
+     618         880 :     norm+=data[i]*data[i];
+     619             :   }
+     620          80 :   norm=sqrt(norm);
+     621          80 :   return norm;
+     622             : }
+     623             : 
+     624             : 
+     625           0 : double CoeffsVector::getLpNorm(const double p) const {
+     626             :   double norm=0.0;
+     627           0 :   for(size_t i=0; i<data.size(); i++) {
+     628           0 :     norm+=pow(data[i],p);
+     629             :   }
+     630           0 :   norm=pow(norm,(1.0/p));
+     631           0 :   return norm;
+     632             : }
+     633             : 
+     634             : 
+     635          80 : double CoeffsVector::getRMS() const {
+     636          80 :   return getNorm()/sqrt(numberOfCoeffs());
+     637             : }
+     638             : 
+     639             : 
+     640           0 : void CoeffsVector::normalizeCoeffs() {
+     641           0 :   double norm=getNorm();
+     642           0 :   scaleAllValues(norm);
+     643           0 : }
+     644             : 
+     645             : 
+     646           0 : void CoeffsVector::randomizeValuesGaussian(int randomSeed) {
+     647           0 :   Random rnd;
+     648             :   if (randomSeed<0) {randomSeed = -randomSeed;}
+     649           0 :   rnd.setSeed(-randomSeed);
+     650           0 :   for(size_t i=0; i<data.size(); i++) {
+     651           0 :     data[i]=rnd.Gaussian();
+     652             :   }
+     653           0 : }
+     654             : 
+     655             : 
+     656           0 : void CoeffsVector::resetAveraging() {
+     657           0 :   clear();
+     658             :   resetAveragingCounter();
+     659           0 : }
+     660             : 
+     661             : 
+     662          20 : void CoeffsVector::addToAverage(const CoeffsVector& coeffsvec) {
+     663          20 :   plumed_massert( data.size()==coeffsvec.getSize(), "Incorrect size");
+     664             :   //
+     665          20 :   double aver_decay = 1.0 / ( static_cast<double>(averaging_counter) + 1.0 );
+     666          20 :   if(averaging_exp_decay_>0 &&  (averaging_counter+1 > averaging_exp_decay_) ) {
+     667           9 :     aver_decay = 1.0 / static_cast<double>(averaging_exp_decay_);
+     668             :   }
+     669             :   //
+     670         240 :   for(size_t i=0; i<data.size(); i++) {
+     671         220 :     data[i]+=(coeffsvec.data[i]-data[i])*aver_decay;
+     672             :   }
+     673          20 :   averaging_counter++;
+     674          20 : }
+     675             : 
+     676             : 
+     677           1 : size_t CoeffsVector::countValues(const double value) const {
+     678             :   size_t numvalues=0;
+     679          12 :   for(size_t i=0; i<data.size(); i++) {
+     680          11 :     if(data[i]==value) {
+     681           2 :       numvalues++;
+     682             :     }
+     683             :   }
+     684           1 :   return numvalues;
+     685             : }
+     686             : 
+     687             : 
+     688           0 : void CoeffsVector::writeToFile(const std::string& filepath, const bool print_coeffs_descriptions, const bool append_file, Action* action_pntr) {
+     689           0 :   OFile file;
+     690           0 :   if(action_pntr!=NULL) {
+     691           0 :     file.link(*action_pntr);
+     692             :   }
+     693             :   else {
+     694           0 :     file.link(mycomm);
+     695             :   }
+     696           0 :   if(append_file) { file.enforceRestart(); }
+     697           0 :   file.open(filepath);
+     698           0 :   writeToFile(file,print_coeffs_descriptions);
+     699           0 :   file.close();
+     700           0 : }
+     701             : 
+     702             : 
+     703        1467 : void CoeffsVector::writeToFile(OFile& ofile, const bool print_coeffs_descriptions) {
+     704             :   std::vector<CoeffsVector*> CoeffsSetTmp;
+     705        1467 :   CoeffsSetTmp.push_back(this);
+     706        1467 :   writeHeaderToFile(ofile);
+     707        1467 :   writeDataToFile(ofile,CoeffsSetTmp,print_coeffs_descriptions);
+     708        1467 : }
+     709             : 
+     710             : 
+     711         881 : void CoeffsVector::writeToFile(OFile& ofile, CoeffsVector* aux_coeffsvector, const bool print_coeffs_descriptions) {
+     712             :   std::vector<CoeffsVector*> CoeffsSetTmp;
+     713         881 :   CoeffsSetTmp.push_back(this);
+     714         881 :   CoeffsSetTmp.push_back(aux_coeffsvector);
+     715         881 :   writeHeaderToFile(ofile);
+     716         881 :   writeDataToFile(ofile,CoeffsSetTmp,print_coeffs_descriptions);
+     717         881 : }
+     718             : 
+     719             : 
+     720           0 : void CoeffsVector::writeToFile(const std::string& filepath, const std::vector<CoeffsVector*>& coeffsvecSet, const bool print_coeffs_descriptions, const bool append_file, Action* action_pntr) {
+     721           0 :   OFile file;
+     722           0 :   if(action_pntr!=NULL) {
+     723           0 :     file.link(*action_pntr);
+     724             :   }
+     725             :   else {
+     726           0 :     file.link(coeffsvecSet[0]->getCommunicator());
+     727             :   }
+     728           0 :   if(append_file) { file.enforceRestart(); }
+     729           0 :   file.open(filepath);
+     730           0 :   writeToFile(file,coeffsvecSet,print_coeffs_descriptions);
+     731           0 :   file.close();
+     732           0 : }
+     733             : 
+     734             : 
+     735           0 : void CoeffsVector::writeToFile(OFile& ofile, const std::vector<CoeffsVector*>& coeffsvecSet, const bool print_coeffs_descriptions) {
+     736           0 :   for(unsigned int k=1; k<coeffsvecSet.size(); k++) {
+     737           0 :     plumed_massert(coeffsvecSet[k]->sameShape(*coeffsvecSet[0]),"Error in writing a set of coeffs to file: The coeffs do not have the same shape and size");
+     738             :   }
+     739           0 :   coeffsvecSet[0]->writeHeaderToFile(ofile);
+     740           0 :   writeDataToFile(ofile,coeffsvecSet, print_coeffs_descriptions);
+     741           0 : }
+     742             : 
+     743             : 
+     744        2348 : void CoeffsVector::writeHeaderToFile(OFile& ofile) const {
+     745        2348 :   ofile.clearFields();
+     746        2348 :   if(isIterationCounterActive()) {
+     747        2061 :     writeIterationCounterAndTimeToFile(ofile);
+     748             :   }
+     749        2348 :   writeCoeffsInfoToFile(ofile);
+     750        2348 : }
+     751             : 
+     752             : 
+     753        2348 : void CoeffsVector::writeDataToFile(OFile& ofile, const std::vector<CoeffsVector*>& coeffsvecSet, const bool print_coeffs_descriptions) {
+     754             :   //
+     755        2348 :   std::string field_indices_prefix = "idx_";
+     756        2348 :   std::string field_index = "index";
+     757        2348 :   std::string field_description = "description";
+     758             :   //
+     759        2348 :   std::string int_fmt = "%8d";
+     760        2348 :   std::string str_separate = "#!-------------------";
+     761             :   //
+     762        2348 :   unsigned int numvec = coeffsvecSet.size();
+     763        2348 :   unsigned int numdim = coeffsvecSet[0]->numberOfDimensions();
+     764             :   unsigned int numcoeffs = coeffsvecSet[0]->getSize();
+     765             :   std::vector<std::string> coeffs_descriptions = coeffsvecSet[0]->getAllCoeffsDescriptions();
+     766        2348 :   std::string output_fmt = coeffsvecSet[0]->getOutputFmt();
+     767        2348 :   std::vector<std::string> coeffs_datalabels(numvec);
+     768        5577 :   for(unsigned int k=0; k<numvec; k++) {
+     769        6458 :     coeffs_datalabels[k] = coeffsvecSet[k]->getDataLabel();
+     770             :   }
+     771             :   //
+     772        2348 :   std::vector<char> s1(20);
+     773        2348 :   std::vector<unsigned int> indices(numdim);
+     774        2348 :   std::vector<std::string> ilabels(numdim);
+     775        5260 :   for(unsigned int k=0; k<numdim; k++) {
+     776        5824 :     ilabels[k]=field_indices_prefix+coeffsvecSet[0]->getDimensionLabel(k);
+     777             :   }
+     778             :   //
+     779       86666 :   for(size_t i=0; i<numcoeffs; i++) {
+     780       84318 :     indices=coeffsvecSet[0]->getIndices(i);
+     781      233206 :     for(unsigned int k=0; k<numdim; k++) {
+     782      148888 :       std::snprintf(s1.data(),s1.size(),int_fmt.c_str(),indices[k]);
+     783      297776 :       ofile.printField(ilabels[k],s1.data());
+     784             :     }
+     785      203216 :     for(unsigned int l=0; l<numvec; l++) {
+     786      237796 :       ofile.fmtField(" "+output_fmt).printField(coeffs_datalabels[l],coeffsvecSet[l]->getValue(i));
+     787             :     }
+     788       84318 :     std::snprintf(s1.data(),s1.size(),int_fmt.c_str(),i); ofile.printField(field_index,s1.data());
+     789       89064 :     if(print_coeffs_descriptions) { ofile.printField(field_description,"  "+coeffs_descriptions[i]);}
+     790       84318 :     ofile.printField();
+     791             :   }
+     792        2348 :   ofile.fmtField();
+     793             :   // blank line between iterations to allow proper plotting with gnuplot
+     794        2348 :   ofile.printf("%s\n",str_separate.c_str());
+     795        2348 :   ofile.printf("\n");
+     796        2348 :   ofile.printf("\n");
+     797        9392 : }
+     798             : 
+     799             : 
+     800          75 : size_t CoeffsVector::readFromFile(IFile& ifile, const bool ignore_missing_coeffs, const bool ignore_header) {
+     801          75 :   ifile.allowIgnoredFields();
+     802             :   size_t ncoeffs_read=0;
+     803         594 :   while(ifile) {
+     804         444 :     if(!ignore_header) {readHeaderFromFile(ifile);}
+     805         444 :     if(ifile) {
+     806         409 :       ncoeffs_read=readDataFromFile(ifile,ignore_missing_coeffs);
+     807             :     }
+     808             :   }
+     809          75 :   return ncoeffs_read;
+     810             : }
+     811             : 
+     812             : 
+     813          36 : size_t CoeffsVector::readOneSetFromFile(IFile& ifile, const bool ignore_header) {
+     814          36 :   ifile.allowIgnoredFields();
+     815             :   size_t ncoeffs_read=0;
+     816          36 :   if(ifile) {
+     817          36 :     if(!ignore_header) {readHeaderFromFile(ifile);}
+     818          36 :     if(ifile) {ncoeffs_read=readDataFromFile(ifile,false);}
+     819             :   }
+     820          36 :   return ncoeffs_read;
+     821             : }
+     822             : 
+     823             : 
+     824          40 : size_t CoeffsVector::readFromFile(const std::string& filepath, const bool ignore_missing_coeffs, const bool ignore_header) {
+     825          40 :   IFile file;
+     826          40 :   file.link(mycomm);
+     827          40 :   file.open(filepath);
+     828          40 :   size_t ncoeffs_read=readFromFile(file,ignore_missing_coeffs, ignore_header);
+     829          40 :   file.close();
+     830          40 :   return ncoeffs_read;
+     831          40 : }
+     832             : 
+     833             : 
+     834         406 : void CoeffsVector::readHeaderFromFile(IFile& ifile, const bool ignore_coeffs_info) {
+     835         406 :   if(ifile && isIterationCounterActive()) {
+     836         406 :     getIterationCounterAndTimeFromFile(ifile);
+     837             :   }
+     838         406 :   if(ifile) {
+     839         368 :     getCoeffsInfoFromFile(ifile,ignore_coeffs_info);
+     840             :   }
+     841         406 : }
+     842             : 
+     843             : 
+     844         442 : size_t CoeffsVector::readDataFromFile(IFile& ifile, const bool ignore_missing_coeffs) {
+     845             :   //
+     846         442 :   std::string field_indices_prefix = "idx_";
+     847             :   std::string field_coeffs = getDataLabel();
+     848         442 :   std::string field_index = "index";
+     849         442 :   std::string field_description = "description";
+     850             :   //
+     851         442 :   std::vector<std::string> ilabels(numberOfDimensions());
+     852         903 :   for(unsigned int k=0; k<numberOfDimensions(); k++) {
+     853         922 :     ilabels[k]=field_indices_prefix+getDimensionLabel(k);
+     854             :   }
+     855             :   //
+     856         442 :   std::vector<unsigned int> indices(numberOfDimensions());
+     857         442 :   double coeff_tmp=0.0;
+     858             :   std::string str_tmp;
+     859             :   size_t ncoeffs_read=0;
+     860             :   //
+     861        5475 :   while(ifile.scanField(field_coeffs,coeff_tmp)) {
+     862             :     int idx_tmp;
+     863       12131 :     for(unsigned int k=0; k<numberOfDimensions(); k++) {
+     864        6696 :       ifile.scanField(ilabels[k],idx_tmp);
+     865        6696 :       indices[k] = static_cast<unsigned int>(idx_tmp);
+     866             :     }
+     867        5435 :     data[getIndex(indices)] = coeff_tmp;
+     868        5435 :     ifile.scanField(field_index,idx_tmp);
+     869        5435 :     if(getIndex(indices)!=static_cast<unsigned int>(idx_tmp)) {
+     870           0 :       std::string is1; Tools::convert(idx_tmp,is1);
+     871           0 :       std::string msg="ERROR: problem with indices at index " + is1 + " when reading coefficients from file";
+     872           0 :       plumed_merror(msg);
+     873             :     }
+     874        5435 :     if(ifile.FieldExist(field_description)) { ifile.scanField(field_description,str_tmp); }
+     875             :     //
+     876        5435 :     ifile.scanField();
+     877        5435 :     ncoeffs_read++;
+     878        5435 :     if(ncoeffs_read==numberOfCoeffs()) {
+     879         402 :       if((static_cast<unsigned int>(idx_tmp)+1)!=numberOfCoeffs()) {
+     880           0 :         plumed_merror("something strange about the coefficient file that is being read in, perhaps multiple entries or missing values");
+     881             :       }
+     882         402 :       break;
+     883             :     }
+     884             :   }
+     885             :   // checks on the coeffs read
+     886         442 :   if(ncoeffs_read>0 &&!ignore_missing_coeffs && ncoeffs_read < numberOfCoeffs()) {
+     887           0 :     plumed_merror("ERROR: missing coefficients when reading from file");
+     888             :   }
+     889             :   //
+     890         442 :   return ncoeffs_read;
+     891         442 : }
+     892             : 
+     893             : 
+     894             : }
+     895             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/CoeffsVector.h.func-sort-c.html b/coverage/ves/CoeffsVector.h.func-sort-c.html new file mode 100644 index 000000000000..c36b1a634ba1 --- /dev/null +++ b/coverage/ves/CoeffsVector.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage - ves/CoeffsVector.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - CoeffsVector.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2450.0 %
Date:2024-04-19 12:12:35Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/CoeffsVector.h.func.html b/coverage/ves/CoeffsVector.h.func.html new file mode 100644 index 000000000000..a607e2744040 --- /dev/null +++ b/coverage/ves/CoeffsVector.h.func.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage - ves/CoeffsVector.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - CoeffsVector.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2450.0 %
Date:2024-04-19 12:12:35Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/CoeffsVector.h.gcov.html b/coverage/ves/CoeffsVector.h.gcov.html new file mode 100644 index 000000000000..eabb3351f4d9 --- /dev/null +++ b/coverage/ves/CoeffsVector.h.gcov.html @@ -0,0 +1,317 @@ + + + + + + + + LCOV - plumed test coverage - ves/CoeffsVector.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - CoeffsVector.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2450.0 %
Date:2024-04-19 12:12:35Functions:00-
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_ves_CoeffsVector_h
+      23             : #define __PLUMED_ves_CoeffsVector_h
+      24             : 
+      25             : #include "CoeffsBase.h"
+      26             : 
+      27             : #include <vector>
+      28             : #include <string>
+      29             : #include <cmath>
+      30             : #include <memory>
+      31             : 
+      32             : 
+      33             : namespace PLMD {
+      34             : 
+      35             : class Action;
+      36             : class Value;
+      37             : class IFile;
+      38             : class OFile;
+      39             : class Communicator;
+      40             : 
+      41             : namespace ves {
+      42             : 
+      43             : class BasisFunctions;
+      44             : class CoeffsMatrix;
+      45             : 
+      46             : 
+      47             : class CoeffsVector:
+      48             :   public CoeffsBase
+      49             : {
+      50             : public:
+      51             : private:
+      52             :   std::vector<double> data;
+      53             :   //
+      54             :   unsigned int averaging_counter;
+      55             :   unsigned int averaging_exp_decay_;
+      56             :   //
+      57             :   Communicator& mycomm;
+      58             :   //
+      59             :   CoeffsVector& operator=(const CoeffsVector&);
+      60             : public:
+      61             :   explicit CoeffsVector(
+      62             :     const std::string&,
+      63             :     const std::vector<std::string>&,
+      64             :     const std::vector<unsigned int>&,
+      65             :     Communicator&,
+      66             :     const bool use_counter=false);
+      67             :   //
+      68             :   explicit CoeffsVector(
+      69             :     const std::string&,
+      70             :     const std::vector<Value*>&,
+      71             :     std::vector<BasisFunctions*>&,
+      72             :     Communicator&,
+      73             :     const bool use_counter=false);
+      74             :   //
+      75             :   explicit CoeffsVector(
+      76             :     const std::string&,
+      77             :     std::vector<std::vector<Value*> >&,
+      78             :     std::vector<std::vector<BasisFunctions*> >&,
+      79             :     Communicator&,
+      80             :     const bool use_counter=false,
+      81             :     const std::string& multicoeffs_label="bias");
+      82             :   //
+      83             :   explicit CoeffsVector(
+      84             :     const std::string&,
+      85             :     CoeffsMatrix*,
+      86             :     Communicator&);
+      87             :   //
+      88             :   ~CoeffsVector();
+      89             :   //
+      90             :   size_t getSize() const {return numberOfCoeffs();}
+      91             :   // clear coeffs
+      92             :   void clear();
+      93             :   void setAllValuesToZero();
+      94             :   //
+      95             :   std::vector<double> getDataAsVector() const {return data;}
+      96             :   //
+      97             :   bool sameShape(CoeffsVector&) const;
+      98             :   bool sameShape(CoeffsMatrix&) const;
+      99             :   static bool sameShape(CoeffsVector&, CoeffsVector&);
+     100             :   //
+     101             :   void resizeCoeffs(const std::vector<unsigned int>&);
+     102             :   void resizeCoeffs(std::vector<BasisFunctions*>&);
+     103             :   //
+     104             :   void sumCommMPI();
+     105             :   void sumCommMPI(Communicator& cc);
+     106             :   //
+     107             :   void sumMultiSimCommMPI(Communicator&);
+     108             :   // get value
+     109             :   double getValue(const size_t) const;
+     110             :   double getValue(const std::vector<unsigned int>&) const;
+     111             :   double& operator[](const size_t index);
+     112             :   const double& operator[](const size_t index) const;
+     113             :   double& operator[](const std::vector<unsigned int>&);
+     114             :   const double& operator[](const std::vector<unsigned int>&) const;
+     115             :   double& operator()(const size_t index);
+     116             :   const double& operator()(const size_t index) const;
+     117             :   double& operator()(const std::vector<unsigned int>&);
+     118             :   const double& operator()(const std::vector<unsigned int>&) const;
+     119             :   // set value
+     120             :   void setValue(const size_t, const double);
+     121             :   void setValue(const std::vector<unsigned int>&, const double);
+     122             :   // add to value
+     123             :   void addToValue(const size_t, const double);
+     124             :   void addToValue(const std::vector<unsigned int>&, const double);
+     125             :   // scale all values
+     126             :   void scaleAllValues(const double);
+     127             :   void multiplyWithValues(const std::vector<double>&);
+     128             :   CoeffsVector& operator*=(const double);
+     129             :   friend CoeffsVector operator*(const double, const CoeffsVector&);
+     130             :   friend CoeffsVector operator*(const CoeffsVector&, const double);
+     131             :   CoeffsVector& operator*=(const std::vector<double>&);
+     132             :   friend CoeffsVector operator*(const std::vector<double>&, const CoeffsVector&);
+     133             :   friend CoeffsVector operator*(const CoeffsVector&, const std::vector<double>&);
+     134             :   CoeffsVector& operator*=(const CoeffsVector&);
+     135             :   CoeffsVector operator*(const CoeffsVector&) const;
+     136             :   // set all values
+     137             :   void setValues(const double);
+     138             :   void setValues(const std::vector<double>&);
+     139             :   void setValues(const CoeffsVector&);
+     140             :   CoeffsVector& operator=(const double);
+     141             :   CoeffsVector& operator=(const std::vector<double>&);
+     142             :   // CoeffsVector& operator=(const CoeffsVector&);
+     143             :   // add to all values
+     144             :   CoeffsVector operator+() const;
+     145             :   CoeffsVector operator-() const;
+     146             :   void addToValues(const double);
+     147             :   void addToValues(const std::vector<double>&);
+     148             :   void addToValues(const CoeffsVector&);
+     149             :   void subtractFromValues(const double);
+     150             :   void subtractFromValues(const std::vector<double>&);
+     151             :   void subtractFromValues(const CoeffsVector&);
+     152             :   CoeffsVector& operator+=(const double);
+     153             :   friend CoeffsVector operator+(const double, const CoeffsVector&);
+     154             :   friend CoeffsVector operator+(const CoeffsVector&, const double);
+     155             :   CoeffsVector& operator+=(const std::vector<double>&);
+     156             :   friend CoeffsVector operator+(const std::vector<double>&, const CoeffsVector&);
+     157             :   friend CoeffsVector operator+(const CoeffsVector&, const std::vector<double>&);
+     158             :   CoeffsVector& operator-=(const double);
+     159             :   friend CoeffsVector operator-(const double, const CoeffsVector&);
+     160             :   friend CoeffsVector operator-(const CoeffsVector&, const double);
+     161             :   CoeffsVector& operator-=(const std::vector<double>&);
+     162             :   friend CoeffsVector operator-(const std::vector<double>&, const CoeffsVector&);
+     163             :   friend CoeffsVector operator-(const CoeffsVector&, const std::vector<double>&);
+     164             :   CoeffsVector& operator+=(const CoeffsVector&);
+     165             :   CoeffsVector operator+(const CoeffsVector&) const;
+     166             :   CoeffsVector& operator-=(const CoeffsVector&);
+     167             :   CoeffsVector operator-(const CoeffsVector&) const;
+     168             :   //
+     169             :   void setValuesFromDifferentShape(const CoeffsVector&);
+     170             :   //
+     171             :   static void averageVectors(CoeffsVector&, CoeffsVector&);
+     172             :   static void averageVectors(const std::vector<CoeffsVector*>&);
+     173             :   //
+     174             :   double getMinValue() const;
+     175             :   double getMinValue(size_t&) const;
+     176             :   double getMinAbsValue() const;
+     177             :   double getMinAbsValue(size_t&) const;
+     178             :   //
+     179             :   double getMaxValue() const;
+     180             :   double getMaxValue(size_t&) const;
+     181             :   double getMaxAbsValue() const;
+     182             :   double getMaxAbsValue(size_t&) const;
+     183             :   //
+     184             :   double getNorm() const;
+     185             :   double getL1Norm() const;
+     186             :   double getL2Norm() const;
+     187             :   double getLpNorm(const double) const;
+     188             :   double getRMS() const;
+     189             :   //
+     190             :   void normalizeCoeffs();
+     191             :   // Random values
+     192             :   void randomizeValuesGaussian(int);
+     193             :   //
+     194           0 :   void resetAveragingCounter() {averaging_counter=0;}
+     195           1 :   void setupExponentiallyDecayingAveraging(const unsigned int averaging_exp_decay_in) {averaging_exp_decay_=averaging_exp_decay_in;}
+     196             :   void turnOffExponentiallyDecayingAveraging() {averaging_exp_decay_=0;}
+     197             :   void resetAveraging();
+     198             :   void addToAverage(const CoeffsVector&);
+     199             :   //
+     200             :   size_t countValues(const double) const;
+     201             : 
+     202             :   // file input/output stuff
+     203             :   void writeToFile(const std::string&, const bool print_description=false, const bool append_file=false, Action* action_pntr=NULL);
+     204             :   void writeToFile(OFile&, const bool print_description=false);
+     205             :   void writeToFile(OFile& ofile, CoeffsVector*, const bool print_coeffs_descriptions=false);
+     206             :   static void writeToFile(const std::string&, const std::vector<CoeffsVector*>&, const bool print_description=false, const bool append_file=false, Action* action_pntr=NULL);
+     207             :   static void writeToFile(OFile&, const std::vector<CoeffsVector*>&, const bool print_description=false);
+     208             : private:
+     209             :   void writeHeaderToFile(OFile&) const;
+     210             :   static void writeDataToFile(OFile&, const std::vector<CoeffsVector*>&, const bool print_description=false);
+     211             : public:
+     212             :   size_t readFromFile(IFile&, const bool ignore_missing_coeffs=false, const bool ignore_header=false);
+     213             :   size_t readFromFile(const std::string&, const bool ignore_missing_coeffs=false, const bool ignore_header=false);
+     214             :   size_t readOneSetFromFile(IFile& ifile, const bool ignore_header=false);
+     215             : private:
+     216             :   void readHeaderFromFile(IFile&, const bool ignore_coeffs_info=false);
+     217             :   size_t readDataFromFile(IFile&, const bool ignore_missing_coeffs=false);
+     218             : public:
+     219           0 :   Communicator& getCommunicator() const {return mycomm;}
+     220             : };
+     221             : 
+     222             : 
+     223             : inline
+     224             : double CoeffsVector::getValue(const size_t index) const {
+     225   142877390 :   return data[index];
+     226             : }
+     227             : 
+     228             : 
+     229             : inline
+     230             : double CoeffsVector::getValue(const std::vector<unsigned int>& indices) const {
+     231             :   return data[getIndex(indices)];
+     232             : }
+     233             : 
+     234             : 
+     235             : }
+     236             : 
+     237             : }
+     238             : 
+     239             : 
+     240             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/FermiSwitchingFunction.cpp.func-sort-c.html b/coverage/ves/FermiSwitchingFunction.cpp.func-sort-c.html new file mode 100644 index 000000000000..2ef9f0c3647a --- /dev/null +++ b/coverage/ves/FermiSwitchingFunction.cpp.func-sort-c.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - ves/FermiSwitchingFunction.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - FermiSwitchingFunction.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:336749.3 %
Date:2024-04-19 12:12:35Functions:4944.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves22FermiSwitchingFunction16registerKeywordsERNS_8KeywordsE0
_ZN4PLMD3ves22FermiSwitchingFunction3setEddd0
_ZN4PLMD3ves22FermiSwitchingFunctionC2ERKS1_0
_ZNK4PLMD3ves22FermiSwitchingFunction11descriptionB5cxx11Ev0
_ZNK4PLMD3ves22FermiSwitchingFunction6get_r0Ev0
_ZN4PLMD3ves22FermiSwitchingFunction3setERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS7_3
_ZN4PLMD3ves22FermiSwitchingFunctionC2Ev3
_ZN4PLMD3ves22FermiSwitchingFunctionD2Ev3
_ZNK4PLMD3ves22FermiSwitchingFunction9calculateEdRd3263
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/FermiSwitchingFunction.cpp.func.html b/coverage/ves/FermiSwitchingFunction.cpp.func.html new file mode 100644 index 000000000000..86f1aa41bec1 --- /dev/null +++ b/coverage/ves/FermiSwitchingFunction.cpp.func.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - ves/FermiSwitchingFunction.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - FermiSwitchingFunction.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:336749.3 %
Date:2024-04-19 12:12:35Functions:4944.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves22FermiSwitchingFunction16registerKeywordsERNS_8KeywordsE0
_ZN4PLMD3ves22FermiSwitchingFunction3setERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS7_3
_ZN4PLMD3ves22FermiSwitchingFunction3setEddd0
_ZN4PLMD3ves22FermiSwitchingFunctionC2ERKS1_0
_ZN4PLMD3ves22FermiSwitchingFunctionC2Ev3
_ZN4PLMD3ves22FermiSwitchingFunctionD2Ev3
_ZNK4PLMD3ves22FermiSwitchingFunction11descriptionB5cxx11Ev0
_ZNK4PLMD3ves22FermiSwitchingFunction6get_r0Ev0
_ZNK4PLMD3ves22FermiSwitchingFunction9calculateEdRd3263
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/FermiSwitchingFunction.cpp.gcov.html b/coverage/ves/FermiSwitchingFunction.cpp.gcov.html new file mode 100644 index 000000000000..aae11f34bf8e --- /dev/null +++ b/coverage/ves/FermiSwitchingFunction.cpp.gcov.html @@ -0,0 +1,219 @@ + + + + + + + + LCOV - plumed test coverage - ves/FermiSwitchingFunction.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - FermiSwitchingFunction.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:336749.3 %
Date:2024-04-19 12:12:35Functions:4944.4 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "FermiSwitchingFunction.h"
+      24             : 
+      25             : #include "tools/Tools.h"
+      26             : #include "tools/Keywords.h"
+      27             : 
+      28             : #include <vector>
+      29             : #include <limits>
+      30             : 
+      31             : 
+      32             : namespace PLMD {
+      33             : namespace ves {
+      34             : 
+      35             : 
+      36           0 : void FermiSwitchingFunction::registerKeywords( Keywords& keys ) {
+      37           0 :   keys.add("compulsory","R_0","the value of R_0 in the switching function");
+      38           0 :   keys.add("compulsory","FERMI_LAMBDA","the value of lambda in the Fermi-type switching function (only needed for TYPE=FERMI).");
+      39           0 :   keys.add("optional","FERMI_EXP_MAX","only needed for TYPE=FERMI");
+      40           0 : }
+      41             : 
+      42           3 : void FermiSwitchingFunction::set(const std::string& definition,std::string& errormsg) {
+      43           3 :   std::vector<std::string> data=Tools::getWords(definition);
+      44           3 :   if( data.size()<1 ) {
+      45             :     errormsg="missing all input for switching function";
+      46             :     return;
+      47             :   }
+      48           3 :   std::string name=data[0];
+      49             :   data.erase(data.begin());
+      50           3 :   if(name!="FERMI") {errormsg="only FERMI is supported";}
+      51           3 :   type=fermi;
+      52             :   //
+      53           3 :   bool found_r0=Tools::parse(data,"R_0",r0_);
+      54           3 :   if(!found_r0) {errormsg="R_0 is required";}
+      55             : 
+      56             :   //
+      57           3 :   fermi_exp_max_=std::numeric_limits<double>::max();
+      58           3 :   Tools::parse(data,"FERMI_EXP_MAX",fermi_exp_max_);
+      59             :   //
+      60           3 :   bool found_lambda=Tools::parse(data,"FERMI_LAMBDA",fermi_lambda_);
+      61           3 :   if(!found_lambda) {errormsg="FERMI_LAMBDA is required for FERMI";}
+      62           3 :   if( !data.empty() ) {
+      63             :     errormsg="found the following rogue keywords in switching function input : ";
+      64           0 :     for(unsigned i=0; i<data.size(); ++i) errormsg = errormsg + data[i] + " ";
+      65             :   }
+      66           3 :   init=true;
+      67           3 :   if(errormsg.size()>0) {init=false;}
+      68           3 : }
+      69             : 
+      70           0 : std::string FermiSwitchingFunction::description() const {
+      71           0 :   std::ostringstream ostr;
+      72           0 :   ostr<<1./invr0_<<".  Using ";
+      73           0 :   if(type==fermi) {
+      74           0 :     ostr<< "fermi switching function with parameter";
+      75           0 :     ostr<< " lambda="<<fermi_lambda_;
+      76             :   }
+      77             :   else {
+      78           0 :     plumed_merror("Unknown switching function type");
+      79             :   }
+      80           0 :   return ostr.str();
+      81           0 : }
+      82             : 
+      83             : 
+      84        3263 : double FermiSwitchingFunction::calculate(double distance, double& dfunc) const {
+      85        3263 :   plumed_massert(init,"you are trying to use an unset FermiSwitchingFunction");
+      86        3263 :   double rdist=fermi_lambda_*(distance-r0_);
+      87        3263 :   if(rdist >= fermi_exp_max_) {rdist = fermi_exp_max_;}
+      88        3263 :   double result = 1.0/(1.0+exp(rdist));
+      89        3263 :   dfunc=-fermi_lambda_*exp(rdist)*result*result;
+      90             :   // this is because calculate() sets dfunc to the derivative divided times the distance.
+      91             :   // (I think this is misleading and I would like to modify it - GB)
+      92             :   // dfunc/=distance;
+      93             :   //
+      94        3263 :   return result;
+      95             : }
+      96             : 
+      97             : 
+      98           3 : FermiSwitchingFunction::FermiSwitchingFunction():
+      99           3 :   init(false),
+     100           3 :   type(fermi),
+     101           3 :   r0_(0.0),
+     102           3 :   invr0_(0.0),
+     103           3 :   fermi_lambda_(1.0),
+     104           3 :   fermi_exp_max_(100.0)
+     105             : {
+     106           3 : }
+     107             : 
+     108           0 : FermiSwitchingFunction::FermiSwitchingFunction(const FermiSwitchingFunction&sf):
+     109           0 :   init(sf.init),
+     110           0 :   type(sf.type),
+     111           0 :   r0_(sf.r0_),
+     112           0 :   invr0_(sf.invr0_),
+     113           0 :   fermi_lambda_(sf.fermi_lambda_),
+     114           0 :   fermi_exp_max_(sf.fermi_exp_max_)
+     115             : {
+     116           0 : }
+     117             : 
+     118           0 : void FermiSwitchingFunction::set(const double r0, const double fermi_lambda, const double fermi_exp_max) {
+     119           0 :   init=true;
+     120           0 :   type=fermi;
+     121           0 :   r0_=r0;
+     122           0 :   fermi_lambda_=fermi_lambda;
+     123           0 :   if(fermi_exp_max>0.0) {
+     124           0 :     fermi_exp_max_=fermi_exp_max;
+     125             :   }
+     126             :   else {
+     127           0 :     fermi_exp_max_=100.0;
+     128             :   }
+     129             : 
+     130           0 : }
+     131             : 
+     132           0 : double FermiSwitchingFunction::get_r0() const {
+     133           0 :   return r0_;
+     134             : }
+     135             : 
+     136             : 
+     137           3 : FermiSwitchingFunction::~FermiSwitchingFunction() {
+     138           3 : }
+     139             : 
+     140             : 
+     141             : }
+     142             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/GridIntegrationWeights.cpp.func-sort-c.html b/coverage/ves/GridIntegrationWeights.cpp.func-sort-c.html new file mode 100644 index 000000000000..60eba4029962 --- /dev/null +++ b/coverage/ves/GridIntegrationWeights.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - ves/GridIntegrationWeights.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - GridIntegrationWeights.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:344575.6 %
Date:2024-04-19 12:12:35Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves22GridIntegrationWeights44getOneDimensionalIntegrationPointsAndWeightsERSt6vectorIdSaIdEES5_jddRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE19
_ZN4PLMD3ves22GridIntegrationWeights21getIntegrationWeightsEPKNS_4GridERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESC_2036
_ZN4PLMD3ves22GridIntegrationWeights35getOneDimensionalTrapezoidalWeightsEjdb2563
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/GridIntegrationWeights.cpp.func.html b/coverage/ves/GridIntegrationWeights.cpp.func.html new file mode 100644 index 000000000000..56aee7d3cbed --- /dev/null +++ b/coverage/ves/GridIntegrationWeights.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - ves/GridIntegrationWeights.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - GridIntegrationWeights.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:344575.6 %
Date:2024-04-19 12:12:35Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves22GridIntegrationWeights21getIntegrationWeightsEPKNS_4GridERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESC_2036
_ZN4PLMD3ves22GridIntegrationWeights35getOneDimensionalTrapezoidalWeightsEjdb2563
_ZN4PLMD3ves22GridIntegrationWeights44getOneDimensionalIntegrationPointsAndWeightsERSt6vectorIdSaIdEES5_jddRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE19
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/GridIntegrationWeights.cpp.gcov.html b/coverage/ves/GridIntegrationWeights.cpp.gcov.html new file mode 100644 index 000000000000..1d2c7a8dbd5f --- /dev/null +++ b/coverage/ves/GridIntegrationWeights.cpp.gcov.html @@ -0,0 +1,185 @@ + + + + + + + + LCOV - plumed test coverage - ves/GridIntegrationWeights.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - GridIntegrationWeights.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:344575.6 %
Date:2024-04-19 12:12:35Functions:33100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "GridIntegrationWeights.h"
+      24             : 
+      25             : #include "tools/Grid.h"
+      26             : #include "tools/File.h"
+      27             : #include "tools/Exception.h"
+      28             : 
+      29             : 
+      30             : namespace PLMD {
+      31             : namespace ves {
+      32             : 
+      33        2036 : std::vector<double> GridIntegrationWeights::getIntegrationWeights(const Grid* grid_pntr, const std::string& fname_weights_grid, const std::string& weights_type) {
+      34        2036 :   std::vector<double> dx = grid_pntr->getDx();
+      35        2036 :   std::vector<bool> isPeriodic = grid_pntr->getIsPeriodic();
+      36        2036 :   std::vector<unsigned int> nbins = grid_pntr->getNbin();
+      37             :   std::vector<std::vector<double> > weights_perdim;
+      38        4580 :   for(unsigned int k=0; k<grid_pntr->getDimension(); k++) {
+      39             :     std::vector<double> weights_tmp;
+      40        2544 :     if(weights_type=="trapezoidal") {
+      41        2544 :       weights_tmp = getOneDimensionalTrapezoidalWeights(nbins[k],dx[k],isPeriodic[k]);
+      42             :     }
+      43             :     else {
+      44           0 :       plumed_merror("getIntegrationWeights: unknown weight type, the available type is trapezoidal");
+      45             :     }
+      46        2544 :     weights_perdim.push_back(weights_tmp);
+      47             :   }
+      48             : 
+      49        2036 :   std::vector<double> weights_vector(grid_pntr->getSize(),0.0);
+      50     5323391 :   for(Grid::index_t l=0; l<grid_pntr->getSize(); l++) {
+      51     5321355 :     std::vector<unsigned int> ind = grid_pntr->getIndices(l);
+      52             :     double value = 1.0;
+      53    15690443 :     for(unsigned int k=0; k<grid_pntr->getDimension(); k++) {
+      54    10369088 :       value *= weights_perdim[k][ind[k]];
+      55             :     }
+      56     5321355 :     weights_vector[l] = value;
+      57             :   }
+      58             : 
+      59        2036 :   if(fname_weights_grid.size()>0) {
+      60           0 :     Grid weights_grid = Grid(*grid_pntr);
+      61           0 :     for(Grid::index_t l=0; l<weights_grid.getSize(); l++) {
+      62           0 :       weights_grid.setValue(l,weights_vector[l]);
+      63             :     }
+      64           0 :     OFile ofile;
+      65           0 :     ofile.enforceBackup();
+      66           0 :     ofile.open(fname_weights_grid);
+      67           0 :     weights_grid.writeToFile(ofile);
+      68           0 :     ofile.close();
+      69           0 :   }
+      70             :   //
+      71        2036 :   return weights_vector;
+      72        2036 : }
+      73             : 
+      74             : 
+      75          19 : void GridIntegrationWeights::getOneDimensionalIntegrationPointsAndWeights(std::vector<double>& points, std::vector<double>& weights, const unsigned int nbins, const double min, const double max, const std::string& weights_type) {
+      76          19 :   double dx = (max-min)/(static_cast<double>(nbins)-1.0);
+      77          19 :   points.resize(nbins);
+      78       19038 :   for(unsigned int i=0; i<nbins; i++) {points[i] = min + i*dx;}
+      79          19 :   if(weights_type=="trapezoidal") {
+      80          19 :     weights = getOneDimensionalTrapezoidalWeights(nbins,dx,false);
+      81             :   }
+      82             :   else {
+      83           0 :     plumed_merror("getOneDimensionalIntegrationWeights: unknown weight type, the available type is trapezoidal");
+      84             :   }
+      85          19 : }
+      86             : 
+      87             : 
+      88        2563 : std::vector<double> GridIntegrationWeights::getOneDimensionalTrapezoidalWeights(const unsigned int nbins, const double dx, const bool periodic) {
+      89        2563 :   std::vector<double> weights_1d(nbins);
+      90      444294 :   for(unsigned int i=1; i<(nbins-1); i++) {
+      91      441731 :     weights_1d[i] = dx;
+      92             :   }
+      93        2563 :   if(!periodic) {
+      94        1202 :     weights_1d[0]= 0.5*dx;
+      95        1202 :     weights_1d[(nbins-1)]= 0.5*dx;
+      96             :   }
+      97             :   else {
+      98             :     // as for periodic arguments the first point should be counted twice as the
+      99             :     // grid doesn't include its periodic copy
+     100        1361 :     weights_1d[0]= dx;
+     101        1361 :     weights_1d[(nbins-1)]= dx;
+     102             :   }
+     103        2563 :   return weights_1d;
+     104             : }
+     105             : 
+     106             : 
+     107             : }
+     108             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/GridLinearInterpolation.cpp.func-sort-c.html b/coverage/ves/GridLinearInterpolation.cpp.func-sort-c.html new file mode 100644 index 000000000000..5e06caecbefa --- /dev/null +++ b/coverage/ves/GridLinearInterpolation.cpp.func-sort-c.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - ves/GridLinearInterpolation.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - GridLinearInterpolation.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:6612055.0 %
Date:2024-04-19 12:12:35Functions:5955.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves23GridLinearInterpolation17getAdjacentPointsEPNS_8GridBaseERKSt6vectorIdSaIdEE0
_ZN4PLMD3ves23GridLinearInterpolation18getAdjacentIndicesEPNS_8GridBaseERKSt6vectorIdSaIdEE0
_ZN4PLMD3ves23GridLinearInterpolation38getGridValueWithLinearInterpolation_NDEPNS_8GridBaseERKSt6vectorIdSaIdEE0
_ZN4PLMD3ves23GridLinearInterpolation52getGridValueAndDerivativesWithLinearInterpolation_NDEPNS_8GridBaseERKSt6vectorIdSaIdEERS6_0
_ZN4PLMD3ves23GridLinearInterpolation38getGridValueWithLinearInterpolation_1DEPNS_8GridBaseERKSt6vectorIdSaIdEE1869
_ZN4PLMD3ves23GridLinearInterpolation38getGridValueWithLinearInterpolation_2DEPNS_8GridBaseERKSt6vectorIdSaIdEE47164
_ZN4PLMD3ves23GridLinearInterpolation35getGridValueWithLinearInterpolationEPNS_8GridBaseERKSt6vectorIdSaIdEE49033
_ZN4PLMD3ves23GridLinearInterpolation49getGridValueAndDerivativesWithLinearInterpolationEPNS_8GridBaseERKSt6vectorIdSaIdEERS6_1263854
_ZN4PLMD3ves23GridLinearInterpolation52getGridValueAndDerivativesWithLinearInterpolation_1DEPNS_8GridBaseERKSt6vectorIdSaIdEERS6_1263854
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/GridLinearInterpolation.cpp.func.html b/coverage/ves/GridLinearInterpolation.cpp.func.html new file mode 100644 index 000000000000..6302042a9081 --- /dev/null +++ b/coverage/ves/GridLinearInterpolation.cpp.func.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - ves/GridLinearInterpolation.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - GridLinearInterpolation.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:6612055.0 %
Date:2024-04-19 12:12:35Functions:5955.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves23GridLinearInterpolation17getAdjacentPointsEPNS_8GridBaseERKSt6vectorIdSaIdEE0
_ZN4PLMD3ves23GridLinearInterpolation18getAdjacentIndicesEPNS_8GridBaseERKSt6vectorIdSaIdEE0
_ZN4PLMD3ves23GridLinearInterpolation35getGridValueWithLinearInterpolationEPNS_8GridBaseERKSt6vectorIdSaIdEE49033
_ZN4PLMD3ves23GridLinearInterpolation38getGridValueWithLinearInterpolation_1DEPNS_8GridBaseERKSt6vectorIdSaIdEE1869
_ZN4PLMD3ves23GridLinearInterpolation38getGridValueWithLinearInterpolation_2DEPNS_8GridBaseERKSt6vectorIdSaIdEE47164
_ZN4PLMD3ves23GridLinearInterpolation38getGridValueWithLinearInterpolation_NDEPNS_8GridBaseERKSt6vectorIdSaIdEE0
_ZN4PLMD3ves23GridLinearInterpolation49getGridValueAndDerivativesWithLinearInterpolationEPNS_8GridBaseERKSt6vectorIdSaIdEERS6_1263854
_ZN4PLMD3ves23GridLinearInterpolation52getGridValueAndDerivativesWithLinearInterpolation_1DEPNS_8GridBaseERKSt6vectorIdSaIdEERS6_1263854
_ZN4PLMD3ves23GridLinearInterpolation52getGridValueAndDerivativesWithLinearInterpolation_NDEPNS_8GridBaseERKSt6vectorIdSaIdEERS6_0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/GridLinearInterpolation.cpp.gcov.html b/coverage/ves/GridLinearInterpolation.cpp.gcov.html new file mode 100644 index 000000000000..629a02aef267 --- /dev/null +++ b/coverage/ves/GridLinearInterpolation.cpp.gcov.html @@ -0,0 +1,312 @@ + + + + + + + + LCOV - plumed test coverage - ves/GridLinearInterpolation.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - GridLinearInterpolation.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:6612055.0 %
Date:2024-04-19 12:12:35Functions:5955.6 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "GridLinearInterpolation.h"
+      24             : 
+      25             : #include "tools/Grid.h"
+      26             : #include "tools/Exception.h"
+      27             : #include "tools/Tools.h"
+      28             : 
+      29             : 
+      30             : namespace PLMD {
+      31             : namespace ves {
+      32             : 
+      33             : 
+      34        1869 : double GridLinearInterpolation::getGridValueWithLinearInterpolation_1D(GridBase* grid_pntr, const std::vector<double>& arg) {
+      35             : 
+      36        1869 :   plumed_massert(grid_pntr->getDimension()==1,"The grid is of the wrong dimension, should be one-dimensional");
+      37        1869 :   plumed_massert(arg.size()==1,"input value is of the wrong size");
+      38             : 
+      39        1869 :   double x = arg[0];
+      40        1869 :   double grid_dx = grid_pntr->getDx()[0];
+      41        1869 :   double grid_min; Tools::convert( grid_pntr->getMin()[0], grid_min);
+      42        1869 :   std::vector<unsigned int> i0(1); i0[0] = unsigned( std::floor( (x-grid_min)/grid_dx ) );
+      43        1869 :   std::vector<unsigned int> i1(1); i1[0] = unsigned( std::ceil(  (x-grid_min)/grid_dx ) );
+      44             :   //
+      45        1869 :   double x0 = grid_pntr->getPoint(i0)[0];
+      46        1869 :   double x1 = grid_pntr->getPoint(i1)[0];
+      47        1869 :   double y0 = grid_pntr->getValue(i0);
+      48        1869 :   double y1 = grid_pntr->getValue(i1);
+      49             :   //
+      50        1869 :   return linearInterpolation(x,x0,x1,y0,y1);
+      51             : }
+      52             : 
+      53             : 
+      54       47164 : double GridLinearInterpolation::getGridValueWithLinearInterpolation_2D(GridBase* grid_pntr, const std::vector<double>& arg) {
+      55       47164 :   plumed_massert(grid_pntr->getDimension()==2,"The grid is of the wrong dimension, should be two-dimensional");
+      56       47164 :   plumed_massert(arg.size()==2,"input value is of the wrong size");
+      57             : 
+      58       47164 :   std::vector<double> grid_delta = grid_pntr->getDx();
+      59       47164 :   std::vector<double> grid_min(2);
+      60       47164 :   Tools::convert( grid_pntr->getMin()[0], grid_min[0]);
+      61       47164 :   Tools::convert( grid_pntr->getMin()[1], grid_min[1]);
+      62             : 
+      63       47164 :   std::vector<unsigned int> i00(2);
+      64       47164 :   std::vector<unsigned int> i01(2);
+      65       47164 :   std::vector<unsigned int> i10(2);
+      66       47164 :   std::vector<unsigned int> i11(2);
+      67             : 
+      68       47164 :   i00[0] = i01[0] = unsigned( std::floor( (arg[0]-grid_min[0])/grid_delta[0] ) );
+      69       47164 :   i10[0] = i11[0] = unsigned( std::ceil(  (arg[0]-grid_min[0])/grid_delta[0] ) );
+      70             : 
+      71       47164 :   i00[1] = i10[1] = unsigned( std::floor( (arg[1]-grid_min[1])/grid_delta[1] ) );
+      72       47164 :   i01[1] = i11[1] = unsigned( std::ceil(  (arg[1]-grid_min[1])/grid_delta[1] ) );
+      73             : 
+      74             :   // https://en.wikipedia.org/wiki/Bilinear_interpolation
+      75       47164 :   double x = arg[0];
+      76       47164 :   double y = arg[1];
+      77             : 
+      78       47164 :   double x0 = grid_pntr->getPoint(i00)[0];
+      79       47164 :   double x1 = grid_pntr->getPoint(i10)[0];
+      80       47164 :   double y0 = grid_pntr->getPoint(i00)[1];
+      81       47164 :   double y1 = grid_pntr->getPoint(i11)[1];
+      82             : 
+      83       47164 :   double f00 = grid_pntr->getValue(i00);
+      84       47164 :   double f01 = grid_pntr->getValue(i01);
+      85       47164 :   double f10 = grid_pntr->getValue(i10);
+      86       47164 :   double f11 = grid_pntr->getValue(i11);
+      87             : 
+      88             :   // linear interpolation in x-direction
+      89             :   double fx0 = linearInterpolation(x,x0,x1,f00,f10);
+      90             :   double fx1 = linearInterpolation(x,x0,x1,f01,f11);
+      91             :   // linear interpolation in y-direction
+      92             :   double fxy = linearInterpolation(y,y0,y1,fx0,fx1);
+      93             :   //
+      94       47164 :   return fxy;
+      95             : }
+      96             : 
+      97             : 
+      98           0 : double GridLinearInterpolation::getGridValueWithLinearInterpolation_ND(GridBase* grid_pntr, const std::vector<double>& arg) {
+      99           0 :   unsigned int dimension = grid_pntr->getDimension();
+     100           0 :   plumed_massert(dimension==arg.size(),"The grid dimensions do not match the the given arguments.");
+     101             :   // get points first
+     102           0 :   std::vector<std::vector<unsigned>> point_indices = GridLinearInterpolation::getAdjacentPoints(grid_pntr, arg);
+     103             : 
+     104           0 :   unsigned npoints = point_indices.size();
+     105             :   // reserve space for the point vectors and values
+     106           0 :   std::vector<std::vector<double>> points(npoints, std::vector<double>(dimension));
+     107           0 :   std::vector<double> values(npoints);
+     108             : 
+     109             :   // fill point and value vectors for all the grid points
+     110           0 :   for (unsigned i = 0; i < npoints; ++i) {
+     111           0 :     points[i] = grid_pntr->getPoint(point_indices[i]);
+     112           0 :     values[i] = grid_pntr->getValue(point_indices[i]);
+     113             :   }
+     114             : 
+     115           0 :   return multiLinearInterpolation(arg, points, values, dimension);
+     116           0 : }
+     117             : 
+     118             : 
+     119     1263854 : double GridLinearInterpolation::getGridValueAndDerivativesWithLinearInterpolation_1D(GridBase* grid_pntr, const std::vector<double>& arg, std::vector<double>& der) {
+     120     1263854 :   plumed_massert(grid_pntr->getDimension()==1,"The grid is of the wrong dimension, should be one-dimensional");
+     121     1263854 :   plumed_massert(arg.size()==1,"input value is of the wrong size");
+     122             : 
+     123     1263854 :   double x = arg[0];
+     124     1263854 :   double grid_dx = grid_pntr->getDx()[0];
+     125     1263854 :   double grid_min; Tools::convert( grid_pntr->getMin()[0], grid_min);
+     126             : 
+     127     1263854 :   double xtoindex = (x-grid_min)/grid_dx;
+     128     1263854 :   std::vector<unsigned int> i0(1); i0[0] = unsigned(std::floor(xtoindex));
+     129     1263854 :   std::vector<unsigned int> i1(1); i1[0] = unsigned(std::ceil(xtoindex));
+     130             :   //
+     131     1263854 :   std::vector<double> d0 (1), d1 (1);
+     132     1263854 :   double x0 = grid_pntr->getPoint(i0)[0];
+     133     1263854 :   double x1 = grid_pntr->getPoint(i1)[0];
+     134     1263854 :   double y0 = grid_pntr->getValueAndDerivatives(i0, d0);
+     135     1263854 :   double y1 = grid_pntr->getValueAndDerivatives(i1, d1);
+     136             :   //
+     137     1263854 :   der.resize(1);
+     138     2500429 :   der[0] = linearInterpolation(arg[0],x0,x1,d0[0],d1[0]);
+     139     2527708 :   return linearInterpolation(arg[0],x0,x1,y0,y1);
+     140             : }
+     141             : 
+     142             : 
+     143           0 : double GridLinearInterpolation::getGridValueAndDerivativesWithLinearInterpolation_ND(GridBase* grid_pntr, const std::vector<double>& arg, std::vector<double>& der) {
+     144           0 :   unsigned int dimension = grid_pntr->getDimension();
+     145           0 :   plumed_massert(dimension==arg.size(),"The grid dimensions do not match the given arguments");
+     146             :   // get points first
+     147           0 :   std::vector<std::vector<unsigned>> point_indices = getAdjacentPoints(grid_pntr, arg);
+     148             : 
+     149           0 :   unsigned npoints = point_indices.size();
+     150             :   // allocate space for the point vectors and values
+     151           0 :   std::vector<std::vector<double>> points(npoints, std::vector<double>(dimension));
+     152           0 :   std::vector<double> values(npoints);
+     153           0 :   std::vector<std::vector<double>> derivs(npoints, std::vector<double>(dimension));
+     154             : 
+     155             :   // fill point, value and deriv vectors for all the grid points
+     156           0 :   for (unsigned i = 0; i < npoints; ++i) {
+     157           0 :     points[i] = grid_pntr->getPoint(point_indices[i]);
+     158           0 :     values[i] = grid_pntr->getValueAndDerivatives(point_indices[i], derivs[i]);
+     159             :   }
+     160             : 
+     161           0 :   for (size_t i = 0; i < derivs.size(); ++i) {
+     162           0 :     der[i] = multiLinearInterpolation(arg, points, derivs[i], dimension);
+     163             :   }
+     164           0 :   return multiLinearInterpolation(arg, points, values, dimension);
+     165           0 : }
+     166             : 
+     167             : 
+     168       49033 : double GridLinearInterpolation::getGridValueWithLinearInterpolation(GridBase* grid_pntr, const std::vector<double>& arg) {
+     169       49033 :   unsigned int dim = grid_pntr->getDimension();
+     170       49033 :   if(dim==1) {
+     171        1869 :     return getGridValueWithLinearInterpolation_1D(grid_pntr,arg);
+     172             :   }
+     173       47164 :   else if(dim==2) {
+     174       47164 :     return getGridValueWithLinearInterpolation_2D(grid_pntr,arg);
+     175             :   }
+     176             :   else {
+     177           0 :     return getGridValueWithLinearInterpolation_ND(grid_pntr,arg);
+     178             :   }
+     179             : }
+     180             : 
+     181             : 
+     182     1263854 : double GridLinearInterpolation::getGridValueAndDerivativesWithLinearInterpolation(GridBase* grid_pntr, const std::vector<double>& arg, std::vector<double>& der) {
+     183     1263854 :   unsigned int dim = grid_pntr->getDimension();
+     184     1263854 :   if(dim==1) {
+     185     1263854 :     return getGridValueAndDerivativesWithLinearInterpolation_1D(grid_pntr,arg,der);
+     186             :   }
+     187           0 :   return getGridValueAndDerivativesWithLinearInterpolation_ND(grid_pntr,arg,der);
+     188             : }
+     189             : 
+     190             : 
+     191             : // returns the adjacent Grid indices of all double arg as vector of vectors
+     192           0 : std::vector<std::vector<unsigned>> GridLinearInterpolation::getAdjacentIndices(GridBase* grid_pntr, const std::vector<double>& arg) {
+     193           0 :   unsigned int dimension = grid_pntr->getDimension();
+     194             : 
+     195           0 :   std::vector<std::vector<unsigned>> indices(dimension, std::vector<unsigned>(2));
+     196           0 :   for (unsigned i=0; i<dimension; ++i) {
+     197           0 :     std::vector<unsigned> temp_indices(2);
+     198             :     //
+     199           0 :     double grid_dx = grid_pntr->getDx()[i];
+     200           0 :     double grid_min; Tools::convert( grid_pntr->getMin()[i], grid_min);
+     201           0 :     double xtoindex = (arg[i]-grid_min)/grid_dx;
+     202           0 :     temp_indices[0] = static_cast<unsigned>(std::floor(xtoindex));
+     203           0 :     temp_indices[1] = static_cast<unsigned>(std::ceil(xtoindex));
+     204           0 :     indices[i] = temp_indices;
+     205             :   }
+     206           0 :   return indices;
+     207           0 : }
+     208             : 
+     209             : 
+     210           0 : std::vector<std::vector<unsigned>> GridLinearInterpolation::getAdjacentPoints(GridBase* grid_pntr, const std::vector<double>& arg) {
+     211             :   // upper and lower grid indices as vectors for each dimension
+     212           0 :   std::vector<std::vector<unsigned>> grid_indices = getAdjacentIndices(grid_pntr, arg);
+     213           0 :   unsigned npoints = 1U << grid_pntr->getDimension();
+     214             : 
+     215             :   // generate combination of grid indices if multidimensional to match the actual points
+     216             :   // the retrieved combinations will be in column-major order
+     217           0 :   std::vector<std::vector<unsigned>> point_indices(npoints);
+     218           0 :   for (unsigned i = 0; i < npoints; ++i) {
+     219             :     unsigned temp = i;
+     220             :     std::vector<unsigned> current_indices;
+     221           0 :     for (const auto& vec: grid_indices) {
+     222           0 :       unsigned j = temp % 2;
+     223           0 :       current_indices.push_back(vec[j]);
+     224           0 :       temp /= 2;
+     225             :     }
+     226           0 :     point_indices[i] = current_indices;
+     227             :   }
+     228           0 :   return point_indices;
+     229           0 : }
+     230             : 
+     231             : 
+     232             : 
+     233             : 
+     234             : }
+     235             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/GridLinearInterpolation.h.func-sort-c.html b/coverage/ves/GridLinearInterpolation.h.func-sort-c.html new file mode 100644 index 000000000000..953c30d5d8a1 --- /dev/null +++ b/coverage/ves/GridLinearInterpolation.h.func-sort-c.html @@ -0,0 +1,77 @@ + + + + + + + + LCOV - plumed test coverage - ves/GridLinearInterpolation.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - GridLinearInterpolation.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2922.2 %
Date:2024-04-19 12:12:35Functions:010.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves23GridLinearInterpolation24multiLinearInterpolationERKSt6vectorIdSaIdEERKS2_IS4_SaIS4_EERS4_d0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/GridLinearInterpolation.h.func.html b/coverage/ves/GridLinearInterpolation.h.func.html new file mode 100644 index 000000000000..b9ba477133a3 --- /dev/null +++ b/coverage/ves/GridLinearInterpolation.h.func.html @@ -0,0 +1,77 @@ + + + + + + + + LCOV - plumed test coverage - ves/GridLinearInterpolation.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - GridLinearInterpolation.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2922.2 %
Date:2024-04-19 12:12:35Functions:010.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves23GridLinearInterpolation24multiLinearInterpolationERKSt6vectorIdSaIdEERKS2_IS4_SaIS4_EERS4_d0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/GridLinearInterpolation.h.gcov.html b/coverage/ves/GridLinearInterpolation.h.gcov.html new file mode 100644 index 000000000000..2c6a75b2c6d8 --- /dev/null +++ b/coverage/ves/GridLinearInterpolation.h.gcov.html @@ -0,0 +1,159 @@ + + + + + + + + LCOV - plumed test coverage - ves/GridLinearInterpolation.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - GridLinearInterpolation.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2922.2 %
Date:2024-04-19 12:12:35Functions:010.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_ves_GridLinearInterpolation_h
+      23             : #define __PLUMED_ves_GridLinearInterpolation_h
+      24             : 
+      25             : #include <vector>
+      26             : 
+      27             : 
+      28             : namespace PLMD {
+      29             : 
+      30             : 
+      31             : class GridBase;
+      32             : 
+      33             : 
+      34             : namespace ves {
+      35             : 
+      36             : class GridLinearInterpolation {
+      37             : private:
+      38             :   static double getGridValueWithLinearInterpolation_1D(GridBase* grid_pntr, const std::vector<double>& arg);
+      39             :   static double getGridValueWithLinearInterpolation_2D(GridBase* grid_pntr, const std::vector<double>& arg);
+      40             :   static double getGridValueWithLinearInterpolation_ND(GridBase* grid_pntr, const std::vector<double>& arg);
+      41             :   static double getGridValueAndDerivativesWithLinearInterpolation_1D(GridBase* grid_pntr, const std::vector<double>& arg, std::vector<double>& der);
+      42             :   static double getGridValueAndDerivativesWithLinearInterpolation_ND(GridBase* grid_pntr, const std::vector<double>& arg, std::vector<double>& der);
+      43             :   static double linearInterpolation(const double x, const double x0, const double x1, const double y0, const double y1);
+      44             :   static double multiLinearInterpolation(const std::vector<double>& x, const std::vector<std::vector<double>>& points, std::vector<double>& values, const double dim);
+      45             : public:
+      46             :   static double getGridValueWithLinearInterpolation(GridBase* grid_pntr, const std::vector<double>& arg);
+      47             :   static double getGridValueAndDerivativesWithLinearInterpolation(GridBase* grid_pntr, const std::vector<double>& arg, std::vector<double>& der);
+      48             :   static std::vector<std::vector<unsigned>> getAdjacentIndices(GridBase* grid_pntr, const std::vector<double>& arg);
+      49             :   static std::vector<std::vector<unsigned>> getAdjacentPoints(GridBase* grid_pntr, const std::vector<double>& arg);
+      50             : };
+      51             : 
+      52             : 
+      53             : inline
+      54             : double GridLinearInterpolation::linearInterpolation(const double x, const double x0, const double x1, const double y0, const double y1) {
+      55             :   // https://en.wikipedia.org/wiki/Linear_interpolation
+      56     2624038 :   if(x1!=x0) {
+      57     2586242 :     return y0 + (x-x0) * ((y1-y0)/(x1-x0));
+      58             :   }
+      59             :   else {
+      60             :     return y0;
+      61             :   }
+      62             : }
+      63             : 
+      64             : 
+      65             : inline
+      66           0 : double GridLinearInterpolation::multiLinearInterpolation(const std::vector<double>& x, const std::vector<std::vector<double>>& points, std::vector<double>& values, const double dim) {
+      67           0 :   for (unsigned direction = 0; direction < dim; ++direction) {
+      68           0 :     unsigned shift = 1<<(direction+1); // shift by 2, then 4, then 8 etc
+      69           0 :     for (unsigned i = 0; i < points.size(); i += shift) {
+      70             :       // replace every second value with interpolated ones
+      71           0 :       values[i] = linearInterpolation(
+      72           0 :                     x[direction], points[i][direction], points[i+shift/2][direction], values[i], values[i+shift/2]);
+      73             :     }
+      74             :   }
+      75           0 :   return values[0];
+      76             : }
+      77             : 
+      78             : 
+      79             : }
+      80             : }
+      81             : 
+      82             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/GridProjWeights.h.func-sort-c.html b/coverage/ves/GridProjWeights.h.func-sort-c.html new file mode 100644 index 000000000000..d7922327febd --- /dev/null +++ b/coverage/ves/GridProjWeights.h.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - ves/GridProjWeights.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - GridProjWeights.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:66100.0 %
Date:2024-04-19 12:12:35Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves14MarginalWeight16projectOuterLoopERd2822
_ZN4PLMD3ves9FesWeight16projectOuterLoopERd5834
_ZN4PLMD3ves14MarginalWeight16projectInnerLoopERdS2_284402
_ZN4PLMD3ves9FesWeight16projectInnerLoopERdS2_703214
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/GridProjWeights.h.func.html b/coverage/ves/GridProjWeights.h.func.html new file mode 100644 index 000000000000..5f8b00ef596a --- /dev/null +++ b/coverage/ves/GridProjWeights.h.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - ves/GridProjWeights.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - GridProjWeights.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:66100.0 %
Date:2024-04-19 12:12:35Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves14MarginalWeight16projectInnerLoopERdS2_284402
_ZN4PLMD3ves14MarginalWeight16projectOuterLoopERd2822
_ZN4PLMD3ves9FesWeight16projectInnerLoopERdS2_703214
_ZN4PLMD3ves9FesWeight16projectOuterLoopERd5834
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/GridProjWeights.h.gcov.html b/coverage/ves/GridProjWeights.h.gcov.html new file mode 100644 index 000000000000..942e097f5bc4 --- /dev/null +++ b/coverage/ves/GridProjWeights.h.gcov.html @@ -0,0 +1,127 @@ + + + + + + + + LCOV - plumed test coverage - ves/GridProjWeights.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - GridProjWeights.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:66100.0 %
Date:2024-04-19 12:12:35Functions:44100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_ves_GridProjWeights_h
+      23             : #define __PLUMED_ves_GridProjWeights_h
+      24             : 
+      25             : #include "tools/Grid.h"
+      26             : 
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace ves {
+      30             : 
+      31             : 
+      32             : class MarginalWeight:public WeightBase {
+      33             : public:
+      34          28 :   explicit MarginalWeight() {}
+      35      284402 :   double projectInnerLoop(double &input, double &v) {return  input+v;}
+      36        2822 :   double projectOuterLoop(double &v) {return v;}
+      37             : };
+      38             : 
+      39             : class FesWeight:public WeightBase {
+      40             : public:
+      41             :   double beta,invbeta;
+      42          50 :   explicit FesWeight(double v) {beta=v; invbeta=1./beta;}
+      43      703214 :   double projectInnerLoop(double &input, double &v) {return  input+exp(-beta*v);}
+      44        5834 :   double projectOuterLoop(double &v) {return -invbeta*std::log(v);}
+      45             : };
+      46             : 
+      47             : }
+      48             : }
+      49             : 
+      50             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/LinearBasisSetExpansion.cpp.func-sort-c.html b/coverage/ves/LinearBasisSetExpansion.cpp.func-sort-c.html new file mode 100644 index 000000000000..200505c4e3d1 --- /dev/null +++ b/coverage/ves/LinearBasisSetExpansion.cpp.func-sort-c.html @@ -0,0 +1,217 @@ + + + + + + + + LCOV - plumed test coverage - ves/LinearBasisSetExpansion.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - LinearBasisSetExpansion.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:31335388.7 %
Date:2024-04-19 12:12:35Functions:303683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves23LinearBasisSetExpansion10linkActionEPNS_6ActionE0
_ZN4PLMD3ves23LinearBasisSetExpansion16registerKeywordsERNS_8KeywordsE0
_ZN4PLMD3ves23LinearBasisSetExpansion20setBiasMaximumToZeroEv0
_ZNK4PLMD3ves23LinearBasisSetExpansion23calculateReweightFactorEv0
_ZNK4PLMD3ves23LinearBasisSetExpansion29writeTargetDistributionToFileERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZNK4PLMD3ves23LinearBasisSetExpansion34isStaticTargetDistFileOutputActiveEv0
_ZNK4PLMD3ves23LinearBasisSetExpansion32writeBiasWithoutCutoffGridToFileERNS_5OFileEb5
_ZN4PLMD3ves23LinearBasisSetExpansion16setupFesProjGridEv8
_ZN4PLMD3ves23LinearBasisSetExpansion25restartTargetDistributionEv8
_ZN4PLMD3ves23LinearBasisSetExpansion31readInRestartTargetDistributionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE8
_ZNK4PLMD3ves23LinearBasisSetExpansion29writeTargetDistProjGridToFileERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERNS_5OFileEb20
_ZN4PLMD3ves23LinearBasisSetExpansion27updateBiasWithoutCutoffGridEv27
_ZNK4PLMD3ves23LinearBasisSetExpansion22writeFesProjGridToFileERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERNS_5OFileEb36
_ZN4PLMD3ves23LinearBasisSetExpansion11setGridBinsEj39
_ZN4PLMD3ves23LinearBasisSetExpansion20setBiasMinimumToZeroEv39
_ZN4PLMD3ves23LinearBasisSetExpansion23setupTargetDistributionEPNS0_18TargetDistributionE45
_ZN4PLMD3ves23LinearBasisSetExpansion30setupUniformTargetDistributionEv45
_ZNK4PLMD3ves23LinearBasisSetExpansion25writeTargetDistGridToFileERNS_5OFileEb82
_ZNK4PLMD3ves23LinearBasisSetExpansion28writeLogTargetDistGridToFileERNS_5OFileEb82
_ZN4PLMD3ves23LinearBasisSetExpansion11linkVesBiasEPNS0_7VesBiasE90
_ZN4PLMD3ves23LinearBasisSetExpansion12setupFesGridEv120
_ZN4PLMD3ves23LinearBasisSetExpansion11setGridBinsERKSt6vectorIjSaIjEE129
_ZN4PLMD3ves23LinearBasisSetExpansionC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdRNS_12CommunicatorERKSt6vectorIPNS_5ValueESaISE_EERSC_IPNS0_14BasisFunctionsESaISK_EEPNS0_12CoeffsVectorE130
_ZN4PLMD3ves23LinearBasisSetExpansionD2Ev130
_ZN4PLMD3ves23LinearBasisSetExpansion13setupBiasGridEb166
_ZNK4PLMD3ves23LinearBasisSetExpansion18writeFesGridToFileERNS_5OFileEb169
_ZNK4PLMD3ves23LinearBasisSetExpansion19writeBiasGridToFileERNS_5OFileEb212
_ZN4PLMD3ves23LinearBasisSetExpansion16setupGeneralGridERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEb220
_ZN4PLMD3ves23LinearBasisSetExpansion24updateTargetDistributionEv355
_ZN4PLMD3ves23LinearBasisSetExpansion16getBasisSetValueERKSt6vectorIdSaIdEEmRS2_IPNS0_14BasisFunctionsESaIS8_EEPNS0_12CoeffsVectorE408
_ZN4PLMD3ves23LinearBasisSetExpansion35calculateTargetDistAveragesFromGridEPKNS_4GridE408
_ZN4PLMD3ves23LinearBasisSetExpansion13updateFesGridEv539
_ZN4PLMD3ves23LinearBasisSetExpansion14updateBiasGridEv829
_ZN4PLMD3ves23LinearBasisSetExpansion17getBasisSetValuesERKSt6vectorIdSaIdEERS4_RS2_IPNS0_14BasisFunctionsESaIS9_EEPNS0_12CoeffsVectorEPNS_12CommunicatorE862315
_ZNK4PLMD3ves23LinearBasisSetExpansion16biasCutoffActiveEv1982225
_ZN4PLMD3ves23LinearBasisSetExpansion16getBiasAndForcesERKSt6vectorIdSaIdEERbRS4_S8_RS2_IPNS0_14BasisFunctionsESaISA_EEPNS0_12CoeffsVectorEPNS_12CommunicatorE2011787
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/LinearBasisSetExpansion.cpp.func.html b/coverage/ves/LinearBasisSetExpansion.cpp.func.html new file mode 100644 index 000000000000..93518b4aa16c --- /dev/null +++ b/coverage/ves/LinearBasisSetExpansion.cpp.func.html @@ -0,0 +1,217 @@ + + + + + + + + LCOV - plumed test coverage - ves/LinearBasisSetExpansion.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - LinearBasisSetExpansion.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:31335388.7 %
Date:2024-04-19 12:12:35Functions:303683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves23LinearBasisSetExpansion10linkActionEPNS_6ActionE0
_ZN4PLMD3ves23LinearBasisSetExpansion11linkVesBiasEPNS0_7VesBiasE90
_ZN4PLMD3ves23LinearBasisSetExpansion11setGridBinsERKSt6vectorIjSaIjEE129
_ZN4PLMD3ves23LinearBasisSetExpansion11setGridBinsEj39
_ZN4PLMD3ves23LinearBasisSetExpansion12setupFesGridEv120
_ZN4PLMD3ves23LinearBasisSetExpansion13setupBiasGridEb166
_ZN4PLMD3ves23LinearBasisSetExpansion13updateFesGridEv539
_ZN4PLMD3ves23LinearBasisSetExpansion14updateBiasGridEv829
_ZN4PLMD3ves23LinearBasisSetExpansion16getBasisSetValueERKSt6vectorIdSaIdEEmRS2_IPNS0_14BasisFunctionsESaIS8_EEPNS0_12CoeffsVectorE408
_ZN4PLMD3ves23LinearBasisSetExpansion16getBiasAndForcesERKSt6vectorIdSaIdEERbRS4_S8_RS2_IPNS0_14BasisFunctionsESaISA_EEPNS0_12CoeffsVectorEPNS_12CommunicatorE2011787
_ZN4PLMD3ves23LinearBasisSetExpansion16registerKeywordsERNS_8KeywordsE0
_ZN4PLMD3ves23LinearBasisSetExpansion16setupFesProjGridEv8
_ZN4PLMD3ves23LinearBasisSetExpansion16setupGeneralGridERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEb220
_ZN4PLMD3ves23LinearBasisSetExpansion17getBasisSetValuesERKSt6vectorIdSaIdEERS4_RS2_IPNS0_14BasisFunctionsESaIS9_EEPNS0_12CoeffsVectorEPNS_12CommunicatorE862315
_ZN4PLMD3ves23LinearBasisSetExpansion20setBiasMaximumToZeroEv0
_ZN4PLMD3ves23LinearBasisSetExpansion20setBiasMinimumToZeroEv39
_ZN4PLMD3ves23LinearBasisSetExpansion23setupTargetDistributionEPNS0_18TargetDistributionE45
_ZN4PLMD3ves23LinearBasisSetExpansion24updateTargetDistributionEv355
_ZN4PLMD3ves23LinearBasisSetExpansion25restartTargetDistributionEv8
_ZN4PLMD3ves23LinearBasisSetExpansion27updateBiasWithoutCutoffGridEv27
_ZN4PLMD3ves23LinearBasisSetExpansion30setupUniformTargetDistributionEv45
_ZN4PLMD3ves23LinearBasisSetExpansion31readInRestartTargetDistributionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE8
_ZN4PLMD3ves23LinearBasisSetExpansion35calculateTargetDistAveragesFromGridEPKNS_4GridE408
_ZN4PLMD3ves23LinearBasisSetExpansionC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdRNS_12CommunicatorERKSt6vectorIPNS_5ValueESaISE_EERSC_IPNS0_14BasisFunctionsESaISK_EEPNS0_12CoeffsVectorE130
_ZN4PLMD3ves23LinearBasisSetExpansionD2Ev130
_ZNK4PLMD3ves23LinearBasisSetExpansion16biasCutoffActiveEv1982225
_ZNK4PLMD3ves23LinearBasisSetExpansion18writeFesGridToFileERNS_5OFileEb169
_ZNK4PLMD3ves23LinearBasisSetExpansion19writeBiasGridToFileERNS_5OFileEb212
_ZNK4PLMD3ves23LinearBasisSetExpansion22writeFesProjGridToFileERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERNS_5OFileEb36
_ZNK4PLMD3ves23LinearBasisSetExpansion23calculateReweightFactorEv0
_ZNK4PLMD3ves23LinearBasisSetExpansion25writeTargetDistGridToFileERNS_5OFileEb82
_ZNK4PLMD3ves23LinearBasisSetExpansion28writeLogTargetDistGridToFileERNS_5OFileEb82
_ZNK4PLMD3ves23LinearBasisSetExpansion29writeTargetDistProjGridToFileERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERNS_5OFileEb20
_ZNK4PLMD3ves23LinearBasisSetExpansion29writeTargetDistributionToFileERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZNK4PLMD3ves23LinearBasisSetExpansion32writeBiasWithoutCutoffGridToFileERNS_5OFileEb5
_ZNK4PLMD3ves23LinearBasisSetExpansion34isStaticTargetDistFileOutputActiveEv0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/LinearBasisSetExpansion.cpp.gcov.html b/coverage/ves/LinearBasisSetExpansion.cpp.gcov.html new file mode 100644 index 000000000000..7f161e5a1370 --- /dev/null +++ b/coverage/ves/LinearBasisSetExpansion.cpp.gcov.html @@ -0,0 +1,694 @@ + + + + + + + + LCOV - plumed test coverage - ves/LinearBasisSetExpansion.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - LinearBasisSetExpansion.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:31335388.7 %
Date:2024-04-19 12:12:35Functions:303683.3 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "LinearBasisSetExpansion.h"
+      24             : #include "VesBias.h"
+      25             : #include "CoeffsVector.h"
+      26             : #include "VesTools.h"
+      27             : #include "GridIntegrationWeights.h"
+      28             : #include "BasisFunctions.h"
+      29             : #include "TargetDistribution.h"
+      30             : 
+      31             : 
+      32             : #include "tools/Keywords.h"
+      33             : #include "tools/Grid.h"
+      34             : #include "tools/Communicator.h"
+      35             : 
+      36             : #include "GridProjWeights.h"
+      37             : 
+      38             : #include <limits>
+      39             : 
+      40             : namespace PLMD {
+      41             : namespace ves {
+      42             : 
+      43           0 : void LinearBasisSetExpansion::registerKeywords(Keywords& keys) {
+      44           0 : }
+      45             : 
+      46             : 
+      47         130 : LinearBasisSetExpansion::LinearBasisSetExpansion(
+      48             :   const std::string& label,
+      49             :   const double beta_in,
+      50             :   Communicator& cc,
+      51             :   const std::vector<Value*>& args_pntrs_in,
+      52             :   std::vector<BasisFunctions*>& basisf_pntrs_in,
+      53         130 :   CoeffsVector* bias_coeffs_pntr_in):
+      54         130 :   label_(label),
+      55         130 :   action_pntr_(NULL),
+      56         130 :   vesbias_pntr_(NULL),
+      57         130 :   mycomm_(cc),
+      58         130 :   serial_(false),
+      59         130 :   beta_(beta_in),
+      60         130 :   kbt_(1.0/beta_),
+      61         130 :   args_pntrs_(args_pntrs_in),
+      62         130 :   nargs_(args_pntrs_.size()),
+      63         130 :   basisf_pntrs_(basisf_pntrs_in),
+      64         130 :   nbasisf_(basisf_pntrs_.size()),
+      65         130 :   bias_coeffs_pntr_(bias_coeffs_pntr_in),
+      66         130 :   ncoeffs_(0),
+      67         130 :   grid_min_(nargs_),
+      68         130 :   grid_max_(nargs_),
+      69         130 :   grid_bins_(nargs_,100),
+      70         130 :   targetdist_grid_label_("targetdist"),
+      71         130 :   step_of_last_biasgrid_update(-1000),
+      72         130 :   step_of_last_biaswithoutcutoffgrid_update(-1000),
+      73         130 :   step_of_last_fesgrid_update(-1000),
+      74         130 :   log_targetdist_grid_pntr_(NULL),
+      75         130 :   targetdist_grid_pntr_(NULL),
+      76         260 :   targetdist_pntr_(NULL)
+      77             : {
+      78         130 :   plumed_massert(args_pntrs_.size()==basisf_pntrs_.size(),"number of arguments and basis functions do not match");
+      79         295 :   for(unsigned int k=0; k<nargs_; k++) {nbasisf_[k]=basisf_pntrs_[k]->getNumberOfBasisFunctions();}
+      80             :   //
+      81         130 :   if(bias_coeffs_pntr_==NULL) {
+      82           0 :     bias_coeffs_pntr_ = new CoeffsVector(label_+".coeffs",args_pntrs_,basisf_pntrs_,mycomm_,true);
+      83             :   }
+      84         130 :   plumed_massert(bias_coeffs_pntr_->numberOfDimensions()==basisf_pntrs_.size(),"dimension of coeffs does not match with number of basis functions ");
+      85             :   //
+      86         130 :   ncoeffs_ = bias_coeffs_pntr_->numberOfCoeffs();
+      87         130 :   targetdist_averages_pntr_ = Tools::make_unique<CoeffsVector>(*bias_coeffs_pntr_);
+      88             : 
+      89         130 :   std::string targetdist_averages_label = bias_coeffs_pntr_->getLabel();
+      90         130 :   if(targetdist_averages_label.find("coeffs")!=std::string::npos) {
+      91         260 :     targetdist_averages_label.replace(targetdist_averages_label.find("coeffs"), std::string("coeffs").length(), "targetdist_averages");
+      92             :   }
+      93             :   else {
+      94             :     targetdist_averages_label += "_targetdist_averages";
+      95             :   }
+      96         130 :   targetdist_averages_pntr_->setLabels(targetdist_averages_label);
+      97             :   //
+      98         295 :   for(unsigned int k=0; k<nargs_; k++) {
+      99         330 :     grid_min_[k] = basisf_pntrs_[k]->intervalMinStr();
+     100         330 :     grid_max_[k] = basisf_pntrs_[k]->intervalMaxStr();
+     101             :   }
+     102         130 : }
+     103             : 
+     104         130 : LinearBasisSetExpansion::~LinearBasisSetExpansion() {
+     105         390 : }
+     106             : 
+     107             : 
+     108           0 : bool LinearBasisSetExpansion::isStaticTargetDistFileOutputActive() const {
+     109             :   bool output_static_targetdist_files=true;
+     110           0 :   if(vesbias_pntr_!=NULL) {
+     111             :     output_static_targetdist_files = vesbias_pntr_->isStaticTargetDistFileOutputActive();
+     112             :   }
+     113           0 :   return output_static_targetdist_files;
+     114             : }
+     115             : 
+     116             : 
+     117          90 : void LinearBasisSetExpansion::linkVesBias(VesBias* vesbias_pntr_in) {
+     118          90 :   vesbias_pntr_ = vesbias_pntr_in;
+     119          90 :   action_pntr_ = static_cast<Action*>(vesbias_pntr_in);
+     120             : 
+     121          90 : }
+     122             : 
+     123             : 
+     124           0 : void LinearBasisSetExpansion::linkAction(Action* action_pntr_in) {
+     125           0 :   action_pntr_ = action_pntr_in;
+     126           0 : }
+     127             : 
+     128             : 
+     129         129 : void LinearBasisSetExpansion::setGridBins(const std::vector<unsigned int>& grid_bins_in) {
+     130         129 :   plumed_massert(grid_bins_in.size()==nargs_,"the number of grid bins given doesn't match the number of arguments");
+     131         129 :   plumed_massert(!bias_grid_pntr_,"setGridBins should be used before setting up the grids, otherwise it doesn't work");
+     132         129 :   plumed_massert(!fes_grid_pntr_,"setGridBins should be used before setting up the grids, otherwise it doesn't work");
+     133         129 :   grid_bins_=grid_bins_in;
+     134         129 : }
+     135             : 
+     136             : 
+     137          39 : void LinearBasisSetExpansion::setGridBins(const unsigned int nbins) {
+     138          39 :   std::vector<unsigned int> grid_bins_in(nargs_,nbins);
+     139          39 :   setGridBins(grid_bins_in);
+     140          39 : }
+     141             : 
+     142             : 
+     143         220 : std::unique_ptr<Grid> LinearBasisSetExpansion::setupGeneralGrid(const std::string& label_suffix, const bool usederiv) {
+     144         220 :   bool use_spline = false;
+     145         440 :   auto grid_pntr = Tools::make_unique<Grid>(label_+"."+label_suffix,args_pntrs_,grid_min_,grid_max_,grid_bins_,use_spline,usederiv);
+     146         220 :   return grid_pntr;
+     147             : }
+     148             : 
+     149             : 
+     150         166 : void LinearBasisSetExpansion::setupBiasGrid(const bool usederiv) {
+     151         166 :   if(bias_grid_pntr_) {return;}
+     152         258 :   bias_grid_pntr_ = setupGeneralGrid("bias",usederiv);
+     153         129 :   if(biasCutoffActive()) {
+     154           6 :     bias_withoutcutoff_grid_pntr_ = setupGeneralGrid("bias_withoutcutoff",usederiv);
+     155             :   }
+     156             : }
+     157             : 
+     158             : 
+     159         120 : void LinearBasisSetExpansion::setupFesGrid() {
+     160         120 :   if(fes_grid_pntr_) {return;}
+     161          88 :   if(!bias_grid_pntr_) {
+     162          37 :     setupBiasGrid(true);
+     163             :   }
+     164         176 :   fes_grid_pntr_ = setupGeneralGrid("fes",false);
+     165             : }
+     166             : 
+     167             : 
+     168           8 : void LinearBasisSetExpansion::setupFesProjGrid() {
+     169           8 :   if(!fes_grid_pntr_) {
+     170           1 :     setupFesGrid();
+     171             :   }
+     172           8 : }
+     173             : 
+     174             : 
+     175         829 : void LinearBasisSetExpansion::updateBiasGrid() {
+     176         829 :   plumed_massert(bias_grid_pntr_,"the bias grid is not defined");
+     177         829 :   if(action_pntr_!=NULL &&  getStepOfLastBiasGridUpdate()==action_pntr_->getStep()) {
+     178             :     return;
+     179             :   }
+     180     1982290 :   for(Grid::index_t l=0; l<bias_grid_pntr_->getSize(); l++) {
+     181     1981698 :     std::vector<double> forces(nargs_);
+     182     1981698 :     std::vector<double> args = bias_grid_pntr_->getPoint(l);
+     183     1981698 :     bool all_inside=true;
+     184     1981698 :     double bias=getBiasAndForces(args,all_inside,forces);
+     185             :     //
+     186     1981698 :     if(biasCutoffActive()) {
+     187         600 :       vesbias_pntr_->applyBiasCutoff(bias,forces);
+     188             :     }
+     189             :     //
+     190     1981698 :     if(bias_grid_pntr_->hasDerivatives()) {
+     191     1473981 :       bias_grid_pntr_->setValueAndDerivatives(l,bias,forces);
+     192             :     }
+     193             :     else {
+     194      507717 :       bias_grid_pntr_->setValue(l,bias);
+     195             :     }
+     196             :     //
+     197             :   }
+     198         592 :   if(vesbias_pntr_!=NULL) {
+     199         475 :     vesbias_pntr_->setCurrentBiasMaxValue(bias_grid_pntr_->getMaxValue());
+     200             :   }
+     201         592 :   if(action_pntr_!=NULL) {
+     202         475 :     setStepOfLastBiasGridUpdate(action_pntr_->getStep());
+     203             :   }
+     204             : }
+     205             : 
+     206             : 
+     207          27 : void LinearBasisSetExpansion::updateBiasWithoutCutoffGrid() {
+     208          27 :   plumed_massert(bias_withoutcutoff_grid_pntr_,"the bias without cutoff grid is not defined");
+     209          27 :   plumed_massert(biasCutoffActive(),"the bias cutoff has to be active");
+     210          27 :   plumed_massert(vesbias_pntr_!=NULL,"has to be linked to a VesBias to work");
+     211          27 :   if(action_pntr_!=NULL &&  getStepOfLastBiasWithoutCutoffGridUpdate()==action_pntr_->getStep()) {
+     212             :     return;
+     213             :   }
+     214             :   //
+     215        2423 :   for(Grid::index_t l=0; l<bias_withoutcutoff_grid_pntr_->getSize(); l++) {
+     216        2400 :     std::vector<double> forces(nargs_);
+     217        2400 :     std::vector<double> args = bias_withoutcutoff_grid_pntr_->getPoint(l);
+     218        2400 :     bool all_inside=true;
+     219        2400 :     double bias=getBiasAndForces(args,all_inside,forces);
+     220        2400 :     if(bias_withoutcutoff_grid_pntr_->hasDerivatives()) {
+     221        2400 :       bias_withoutcutoff_grid_pntr_->setValueAndDerivatives(l,bias,forces);
+     222             :     }
+     223             :     else {
+     224           0 :       bias_withoutcutoff_grid_pntr_->setValue(l,bias);
+     225             :     }
+     226             :   }
+     227             :   //
+     228          23 :   double bias_max = bias_withoutcutoff_grid_pntr_->getMaxValue();
+     229          23 :   double bias_min = bias_withoutcutoff_grid_pntr_->getMinValue();
+     230             :   double shift = 0.0;
+     231             :   bool bias_shifted=false;
+     232          23 :   if(bias_min < 0.0) {
+     233          22 :     shift += -bias_min;
+     234             :     bias_shifted=true;
+     235          22 :     BiasCoeffs()[0] -= bias_min;
+     236          22 :     bias_max -= bias_min;
+     237             :   }
+     238          23 :   if(bias_max > vesbias_pntr_->getBiasCutoffValue()) {
+     239          22 :     shift += -(bias_max-vesbias_pntr_->getBiasCutoffValue());
+     240             :     bias_shifted=true;
+     241          22 :     BiasCoeffs()[0] -= (bias_max-vesbias_pntr_->getBiasCutoffValue());
+     242          22 :     bias_max -= (bias_max-vesbias_pntr_->getBiasCutoffValue());
+     243             :   }
+     244          23 :   if(bias_shifted) {
+     245             :     // this should be done inside a grid function really,
+     246             :     // need to define my grid class for that
+     247        2322 :     for(Grid::index_t l=0; l<bias_withoutcutoff_grid_pntr_->getSize(); l++) {
+     248        2300 :       if(bias_withoutcutoff_grid_pntr_->hasDerivatives()) {
+     249        2300 :         std::vector<double> zeros(nargs_,0.0);
+     250        2300 :         bias_withoutcutoff_grid_pntr_->addValueAndDerivatives(l,shift,zeros);
+     251             :       }
+     252             :       else {
+     253           0 :         bias_withoutcutoff_grid_pntr_->addValue(l,shift);
+     254             :       }
+     255             :     }
+     256             :   }
+     257          23 :   if(vesbias_pntr_!=NULL) {
+     258             :     vesbias_pntr_->setCurrentBiasMaxValue(bias_max);
+     259             :   }
+     260          23 :   if(action_pntr_!=NULL) {
+     261          23 :     setStepOfLastBiasWithoutCutoffGridUpdate(action_pntr_->getStep());
+     262             :   }
+     263             : }
+     264             : 
+     265             : 
+     266         539 : void LinearBasisSetExpansion::updateFesGrid() {
+     267         539 :   plumed_massert(fes_grid_pntr_,"the FES grid is not defined");
+     268         539 :   updateBiasGrid();
+     269         539 :   if(action_pntr_!=NULL && getStepOfLastFesGridUpdate() == action_pntr_->getStep()) {
+     270             :     return;
+     271             :   }
+     272             :   //
+     273             :   double bias2fes_scalingf = -1.0;
+     274     1474154 :   for(Grid::index_t l=0; l<fes_grid_pntr_->getSize(); l++) {
+     275     1473681 :     double fes_value = bias2fes_scalingf*bias_grid_pntr_->getValue(l);
+     276     1473681 :     if(log_targetdist_grid_pntr_!=NULL) {
+     277     1224051 :       fes_value += kBT()*log_targetdist_grid_pntr_->getValue(l);
+     278             :     }
+     279     1473681 :     fes_grid_pntr_->setValue(l,fes_value);
+     280             :   }
+     281         473 :   fes_grid_pntr_->setMinToZero();
+     282         473 :   if(action_pntr_!=NULL) {
+     283         473 :     setStepOfLastFesGridUpdate(action_pntr_->getStep());
+     284             :   }
+     285             : }
+     286             : 
+     287             : 
+     288         212 : void LinearBasisSetExpansion::writeBiasGridToFile(OFile& ofile, const bool append_file) const {
+     289         212 :   plumed_massert(bias_grid_pntr_,"the bias grid is not defined");
+     290         212 :   if(append_file) {ofile.enforceRestart();}
+     291         212 :   bias_grid_pntr_->writeToFile(ofile);
+     292         212 : }
+     293             : 
+     294             : 
+     295           5 : void LinearBasisSetExpansion::writeBiasWithoutCutoffGridToFile(OFile& ofile, const bool append_file) const {
+     296           5 :   plumed_massert(bias_withoutcutoff_grid_pntr_,"the bias without cutoff grid is not defined");
+     297           5 :   if(append_file) {ofile.enforceRestart();}
+     298           5 :   bias_withoutcutoff_grid_pntr_->writeToFile(ofile);
+     299           5 : }
+     300             : 
+     301             : 
+     302         169 : void LinearBasisSetExpansion::writeFesGridToFile(OFile& ofile, const bool append_file) const {
+     303         169 :   plumed_massert(fes_grid_pntr_!=NULL,"the FES grid is not defined");
+     304         169 :   if(append_file) {ofile.enforceRestart();}
+     305         169 :   fes_grid_pntr_->writeToFile(ofile);
+     306         169 : }
+     307             : 
+     308             : 
+     309          36 : void LinearBasisSetExpansion::writeFesProjGridToFile(const std::vector<std::string>& proj_arg, OFile& ofile, const bool append_file) const {
+     310          36 :   plumed_massert(fes_grid_pntr_,"the FES grid is not defined");
+     311          36 :   auto Fw = Tools::make_unique<FesWeight>(beta_);
+     312          36 :   Grid proj_grid = fes_grid_pntr_->project(proj_arg,Fw.get());
+     313          36 :   proj_grid.setMinToZero();
+     314          36 :   if(append_file) {ofile.enforceRestart();}
+     315          36 :   proj_grid.writeToFile(ofile);
+     316          36 : }
+     317             : 
+     318             : 
+     319          82 : void LinearBasisSetExpansion::writeTargetDistGridToFile(OFile& ofile, const bool append_file) const {
+     320          82 :   if(targetdist_grid_pntr_==NULL) {return;}
+     321          82 :   if(append_file) {ofile.enforceRestart();}
+     322          82 :   targetdist_grid_pntr_->writeToFile(ofile);
+     323             : }
+     324             : 
+     325             : 
+     326          82 : void LinearBasisSetExpansion::writeLogTargetDistGridToFile(OFile& ofile, const bool append_file) const {
+     327          82 :   if(log_targetdist_grid_pntr_==NULL) {return;}
+     328          82 :   if(append_file) {ofile.enforceRestart();}
+     329          82 :   log_targetdist_grid_pntr_->writeToFile(ofile);
+     330             : }
+     331             : 
+     332             : 
+     333          20 : void LinearBasisSetExpansion::writeTargetDistProjGridToFile(const std::vector<std::string>& proj_arg, OFile& ofile, const bool append_file) const {
+     334          20 :   if(targetdist_grid_pntr_==NULL) {return;}
+     335          20 :   if(append_file) {ofile.enforceRestart();}
+     336          20 :   Grid proj_grid = TargetDistribution::getMarginalDistributionGrid(targetdist_grid_pntr_,proj_arg);
+     337          20 :   proj_grid.writeToFile(ofile);
+     338          20 : }
+     339             : 
+     340             : 
+     341           0 : void LinearBasisSetExpansion::writeTargetDistributionToFile(const std::string& filename) const {
+     342           0 :   OFile of1; OFile of2;
+     343           0 :   if(action_pntr_!=NULL) {
+     344           0 :     of1.link(*action_pntr_); of2.link(*action_pntr_);
+     345             :   }
+     346           0 :   of1.enforceBackup(); of2.enforceBackup();
+     347           0 :   of1.open(filename);
+     348           0 :   of2.open(FileBase::appendSuffix(filename,".log"));
+     349           0 :   writeTargetDistGridToFile(of1);
+     350           0 :   writeLogTargetDistGridToFile(of2);
+     351           0 :   of1.close(); of2.close();
+     352           0 : }
+     353             : 
+     354             : 
+     355     2011787 : double LinearBasisSetExpansion::getBiasAndForces(const std::vector<double>& args_values, bool& all_inside, std::vector<double>& forces, std::vector<double>& coeffsderivs_values, std::vector<BasisFunctions*>& basisf_pntrs_in, CoeffsVector* coeffs_pntr_in, Communicator* comm_in) {
+     356     2011787 :   unsigned int nargs = args_values.size();
+     357     2011787 :   plumed_assert(coeffs_pntr_in->numberOfDimensions()==nargs);
+     358     2011787 :   plumed_assert(basisf_pntrs_in.size()==nargs);
+     359     2011787 :   plumed_assert(forces.size()==nargs);
+     360     2011787 :   plumed_assert(coeffsderivs_values.size()==coeffs_pntr_in->numberOfCoeffs());
+     361             : 
+     362     2011787 :   std::vector<double> args_values_trsfrm(nargs);
+     363             :   // std::vector<bool>   inside_interval(nargs,true);
+     364     2011787 :   all_inside = true;
+     365             :   //
+     366     2011787 :   std::vector< std::vector <double> > bf_values(nargs);
+     367     2011787 :   std::vector< std::vector <double> > bf_derivs(nargs);
+     368             :   //
+     369     5966255 :   for(unsigned int k=0; k<nargs; k++) {
+     370     3954468 :     bf_values[k].assign(basisf_pntrs_in[k]->getNumberOfBasisFunctions(),0.0);
+     371     3954468 :     bf_derivs[k].assign(basisf_pntrs_in[k]->getNumberOfBasisFunctions(),0.0);
+     372     3954468 :     bool curr_inside=true;
+     373     3954468 :     basisf_pntrs_in[k]->getAllValues(args_values[k],args_values_trsfrm[k],curr_inside,bf_values[k],bf_derivs[k]);
+     374             :     // inside_interval[k]=curr_inside;
+     375     3954468 :     if(!curr_inside) {all_inside=false;}
+     376     3954468 :     forces[k]=0.0;
+     377             :   }
+     378             :   //
+     379             :   size_t stride=1;
+     380             :   size_t rank=0;
+     381     2011787 :   if(comm_in!=NULL)
+     382             :   {
+     383     2011787 :     stride=comm_in->Get_size();
+     384     2011787 :     rank=comm_in->Get_rank();
+     385             :   }
+     386             :   // loop over coeffs
+     387     2011787 :   double bias=0.0;
+     388   144769949 :   for(size_t i=rank; i<coeffs_pntr_in->numberOfCoeffs(); i+=stride) {
+     389   142758162 :     std::vector<unsigned int> indices=coeffs_pntr_in->getIndices(i);
+     390             :     double coeff = coeffs_pntr_in->getValue(i);
+     391             :     double bf_curr=1.0;
+     392   435044808 :     for(unsigned int k=0; k<nargs; k++) {
+     393   292286646 :       bf_curr*=bf_values[k][indices[k]];
+     394             :     }
+     395   142758162 :     bias+=coeff*bf_curr;
+     396   142758162 :     coeffsderivs_values[i] = bf_curr;
+     397   435044808 :     for(unsigned int k=0; k<nargs; k++) {
+     398             :       double der = 1.0;
+     399   898592256 :       for(unsigned int l=0; l<nargs; l++) {
+     400   606305610 :         if(l!=k) {der*=bf_values[l][indices[l]];}
+     401   292286646 :         else {der*=bf_derivs[l][indices[l]];}
+     402             :       }
+     403   292286646 :       forces[k]-=coeff*der;
+     404             :       // maybe faster but dangerous
+     405             :       // forces[k]-=coeff*bf_curr*(bf_derivs[k][indices[k]]/bf_values[k][indices[k]]);
+     406             :     }
+     407             :   }
+     408             :   //
+     409     2011787 :   if(comm_in!=NULL) {
+     410             :     // coeffsderivs_values is not summed as the mpi Sum is done later on for the averages
+     411     2011787 :     comm_in->Sum(bias);
+     412     2011787 :     comm_in->Sum(forces);
+     413             :   }
+     414     2011787 :   return bias;
+     415     2011787 : }
+     416             : 
+     417             : 
+     418      862315 : void LinearBasisSetExpansion::getBasisSetValues(const std::vector<double>& args_values, std::vector<double>& basisset_values, std::vector<BasisFunctions*>& basisf_pntrs_in, CoeffsVector* coeffs_pntr_in, Communicator* comm_in) {
+     419      862315 :   unsigned int nargs = args_values.size();
+     420      862315 :   plumed_assert(coeffs_pntr_in->numberOfDimensions()==nargs);
+     421      862315 :   plumed_assert(basisf_pntrs_in.size()==nargs);
+     422             : 
+     423      862315 :   std::vector<double> args_values_trsfrm(nargs);
+     424             :   std::vector< std::vector <double> > bf_values;
+     425             :   //
+     426     2583312 :   for(unsigned int k=0; k<nargs; k++) {
+     427     1720997 :     std::vector<double> tmp_val(basisf_pntrs_in[k]->getNumberOfBasisFunctions());
+     428     1720997 :     std::vector<double> tmp_der(tmp_val.size());
+     429     1720997 :     bool inside=true;
+     430     1720997 :     basisf_pntrs_in[k]->getAllValues(args_values[k],args_values_trsfrm[k],inside,tmp_val,tmp_der);
+     431     1720997 :     bf_values.push_back(tmp_val);
+     432             :   }
+     433             :   //
+     434             :   size_t stride=1;
+     435             :   size_t rank=0;
+     436      862315 :   if(comm_in!=NULL)
+     437             :   {
+     438           0 :     stride=comm_in->Get_size();
+     439           0 :     rank=comm_in->Get_rank();
+     440             :   }
+     441             :   // loop over basis set
+     442    95955507 :   for(size_t i=rank; i<coeffs_pntr_in->numberOfCoeffs(); i+=stride) {
+     443    95093192 :     std::vector<unsigned int> indices=coeffs_pntr_in->getIndices(i);
+     444             :     double bf_curr=1.0;
+     445   298507612 :     for(unsigned int k=0; k<nargs; k++) {
+     446   203414420 :       bf_curr*=bf_values[k][indices[k]];
+     447             :     }
+     448    95093192 :     basisset_values[i] = bf_curr;
+     449             :   }
+     450             :   //
+     451      862315 :   if(comm_in!=NULL) {
+     452           0 :     comm_in->Sum(basisset_values);
+     453             :   }
+     454     1724630 : }
+     455             : 
+     456             : 
+     457         408 : double LinearBasisSetExpansion::getBasisSetValue(const std::vector<double>& args_values, const size_t index, std::vector<BasisFunctions*>& basisf_pntrs_in, CoeffsVector* coeffs_pntr_in) {
+     458         408 :   unsigned int nargs = args_values.size();
+     459         408 :   plumed_assert(coeffs_pntr_in->numberOfDimensions()==nargs);
+     460         408 :   plumed_assert(basisf_pntrs_in.size()==nargs);
+     461             : 
+     462         408 :   std::vector<double> args_values_trsfrm(nargs);
+     463             :   std::vector< std::vector <double> > bf_values;
+     464             :   //
+     465         938 :   for(unsigned int k=0; k<nargs; k++) {
+     466         530 :     std::vector<double> tmp_val(basisf_pntrs_in[k]->getNumberOfBasisFunctions());
+     467         530 :     std::vector<double> tmp_der(tmp_val.size());
+     468         530 :     bool inside=true;
+     469         530 :     basisf_pntrs_in[k]->getAllValues(args_values[k],args_values_trsfrm[k],inside,tmp_val,tmp_der);
+     470         530 :     bf_values.push_back(tmp_val);
+     471             :   }
+     472             :   //
+     473         408 :   std::vector<unsigned int> indices=coeffs_pntr_in->getIndices(index);
+     474             :   double bf_value=1.0;
+     475         938 :   for(unsigned int k=0; k<nargs; k++) {
+     476         530 :     bf_value*=bf_values[k][indices[k]];
+     477             :   }
+     478         408 :   return bf_value;
+     479         408 : }
+     480             : 
+     481             : 
+     482          45 : void LinearBasisSetExpansion::setupUniformTargetDistribution() {
+     483          45 :   std::vector< std::vector <double> > bf_integrals(0);
+     484          45 :   std::vector<double> targetdist_averages(ncoeffs_,0.0);
+     485             :   //
+     486         100 :   for(unsigned int k=0; k<nargs_; k++) {
+     487         110 :     bf_integrals.push_back(basisf_pntrs_[k]->getUniformIntegrals());
+     488             :   }
+     489             :   //
+     490        1672 :   for(size_t i=0; i<ncoeffs_; i++) {
+     491        1627 :     std::vector<unsigned int> indices=bias_coeffs_pntr_->getIndices(i);
+     492             :     double value = 1.0;
+     493        4492 :     for(unsigned int k=0; k<nargs_; k++) {
+     494        2865 :       value*=bf_integrals[k][indices[k]];
+     495             :     }
+     496        1627 :     targetdist_averages[i]=value;
+     497             :   }
+     498          45 :   TargetDistAverages() = targetdist_averages;
+     499          45 : }
+     500             : 
+     501             : 
+     502          45 : void LinearBasisSetExpansion::setupTargetDistribution(TargetDistribution* targetdist_pntr_in) {
+     503          45 :   targetdist_pntr_ = targetdist_pntr_in;
+     504             :   //
+     505          45 :   targetdist_pntr_->setupGrids(args_pntrs_,grid_min_,grid_max_,grid_bins_);
+     506          45 :   targetdist_grid_pntr_      = targetdist_pntr_->getTargetDistGridPntr();
+     507          45 :   log_targetdist_grid_pntr_  = targetdist_pntr_->getLogTargetDistGridPntr();
+     508             :   //
+     509          45 :   if(targetdist_pntr_->isDynamic()) {
+     510          39 :     vesbias_pntr_->enableDynamicTargetDistribution();
+     511             :   }
+     512             :   //
+     513          45 :   if(targetdist_pntr_->biasGridNeeded()) {
+     514           0 :     setupBiasGrid(true);
+     515           0 :     targetdist_pntr_->linkBiasGrid(bias_grid_pntr_.get());
+     516             :   }
+     517          45 :   if(targetdist_pntr_->biasWithoutCutoffGridNeeded()) {
+     518           3 :     setupBiasGrid(true);
+     519           3 :     targetdist_pntr_->linkBiasWithoutCutoffGrid(bias_withoutcutoff_grid_pntr_.get());
+     520             :   }
+     521          45 :   if(targetdist_pntr_->fesGridNeeded()) {
+     522          36 :     setupFesGrid();
+     523          36 :     targetdist_pntr_->linkFesGrid(fes_grid_pntr_.get());
+     524             :   }
+     525             :   //
+     526          45 :   targetdist_pntr_->updateTargetDist();
+     527          45 :   calculateTargetDistAveragesFromGrid(targetdist_grid_pntr_);
+     528          45 : }
+     529             : 
+     530             : 
+     531         355 : void LinearBasisSetExpansion::updateTargetDistribution() {
+     532         355 :   plumed_massert(targetdist_pntr_!=NULL,"the target distribution hasn't been setup!");
+     533         355 :   plumed_massert(targetdist_pntr_->isDynamic(),"this should only be used for dynamically updated target distributions!");
+     534         355 :   if(targetdist_pntr_->biasGridNeeded()) {updateBiasGrid();}
+     535         355 :   if(biasCutoffActive()) {updateBiasWithoutCutoffGrid();}
+     536         355 :   if(targetdist_pntr_->fesGridNeeded()) {updateFesGrid();}
+     537         355 :   targetdist_pntr_->updateTargetDist();
+     538         355 :   calculateTargetDistAveragesFromGrid(targetdist_grid_pntr_);
+     539         355 : }
+     540             : 
+     541             : 
+     542           8 : void LinearBasisSetExpansion::readInRestartTargetDistribution(const std::string& grid_fname) {
+     543           8 :   targetdist_pntr_->readInRestartTargetDistGrid(grid_fname);
+     544           8 :   if(biasCutoffActive()) {targetdist_pntr_->clearLogTargetDistGrid();}
+     545           8 : }
+     546             : 
+     547             : 
+     548           8 : void LinearBasisSetExpansion::restartTargetDistribution() {
+     549           8 :   plumed_massert(targetdist_pntr_!=NULL,"the target distribution hasn't been setup!");
+     550           8 :   plumed_massert(targetdist_pntr_->isDynamic(),"this should only be used for dynamically updated target distributions!");
+     551           8 :   if(biasCutoffActive()) {updateBiasWithoutCutoffGrid();}
+     552           8 :   calculateTargetDistAveragesFromGrid(targetdist_grid_pntr_);
+     553           8 : }
+     554             : 
+     555             : 
+     556         408 : void LinearBasisSetExpansion::calculateTargetDistAveragesFromGrid(const Grid* targetdist_grid_pntr) {
+     557         408 :   plumed_assert(targetdist_grid_pntr!=NULL);
+     558         408 :   std::vector<double> targetdist_averages(ncoeffs_,0.0);
+     559         816 :   std::vector<double> integration_weights = GridIntegrationWeights::getIntegrationWeights(targetdist_grid_pntr);
+     560         408 :   Grid::index_t stride=mycomm_.Get_size();
+     561         408 :   Grid::index_t rank=mycomm_.Get_rank();
+     562      862723 :   for(Grid::index_t l=rank; l<targetdist_grid_pntr->getSize(); l+=stride) {
+     563      862315 :     std::vector<double> args_values = targetdist_grid_pntr->getPoint(l);
+     564      862315 :     std::vector<double> basisset_values(ncoeffs_);
+     565             :     // parallelization done over the grid -> should NOT use parallel in getBasisSetValues!!
+     566      862315 :     getBasisSetValues(args_values,basisset_values,false);
+     567      862315 :     double weight = integration_weights[l]*targetdist_grid_pntr->getValue(l);
+     568    95955507 :     for(unsigned int i=0; i<ncoeffs_; i++) {
+     569    95093192 :       targetdist_averages[i] += weight*basisset_values[i];
+     570             :     }
+     571             :   }
+     572         408 :   mycomm_.Sum(targetdist_averages);
+     573             :   // the overall constant;
+     574         408 :   targetdist_averages[0] = getBasisSetConstant();
+     575         408 :   TargetDistAverages() = targetdist_averages;
+     576         408 : }
+     577             : 
+     578             : 
+     579          39 : void LinearBasisSetExpansion::setBiasMinimumToZero() {
+     580          39 :   plumed_massert(bias_grid_pntr_,"setBiasMinimumToZero can only be used if the bias grid is defined");
+     581          39 :   updateBiasGrid();
+     582          39 :   BiasCoeffs()[0]-=bias_grid_pntr_->getMinValue();
+     583          39 : }
+     584             : 
+     585             : 
+     586           0 : void LinearBasisSetExpansion::setBiasMaximumToZero() {
+     587           0 :   plumed_massert(bias_grid_pntr_,"setBiasMaximumToZero can only be used if the bias grid is defined");
+     588           0 :   updateBiasGrid();
+     589           0 :   BiasCoeffs()[0]-=bias_grid_pntr_->getMaxValue();
+     590           0 : }
+     591             : 
+     592             : 
+     593     1982225 : bool LinearBasisSetExpansion::biasCutoffActive() const {
+     594     1982225 :   if(vesbias_pntr_!=NULL) {return vesbias_pntr_->biasCutoffActive();}
+     595             :   else {return false;}
+     596             : }
+     597             : 
+     598             : 
+     599           0 : double LinearBasisSetExpansion::calculateReweightFactor() const {
+     600           0 :   plumed_massert(targetdist_grid_pntr_!=NULL,"calculateReweightFactor only be used if the target distribution grid is defined");
+     601           0 :   plumed_massert(bias_grid_pntr_,"calculateReweightFactor only be used if the bias grid is defined");
+     602             :   double sum = 0.0;
+     603           0 :   std::vector<double> integration_weights = GridIntegrationWeights::getIntegrationWeights(targetdist_grid_pntr_);
+     604             :   //
+     605           0 :   for(Grid::index_t l=0; l<targetdist_grid_pntr_->getSize(); l++) {
+     606           0 :     sum += integration_weights[l] * targetdist_grid_pntr_->getValue(l) * exp(+beta_*bias_grid_pntr_->getValue(l));
+     607             :   }
+     608           0 :   if(sum==0.0) sum=std::numeric_limits<double>::min();
+     609           0 :   return (1.0/beta_)*std::log(sum);
+     610             : }
+     611             : 
+     612             : 
+     613             : 
+     614             : 
+     615             : }
+     616             : 
+     617             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/LinearBasisSetExpansion.h.func-sort-c.html b/coverage/ves/LinearBasisSetExpansion.h.func-sort-c.html new file mode 100644 index 000000000000..78b01f469995 --- /dev/null +++ b/coverage/ves/LinearBasisSetExpansion.h.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - ves/LinearBasisSetExpansion.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - LinearBasisSetExpansion.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:212295.5 %
Date:2024-04-19 12:12:35Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves23LinearBasisSetExpansion19getBasisSetConstantEv408
_ZN4PLMD3ves23LinearBasisSetExpansion17getBasisSetValuesERKSt6vectorIdSaIdEERS4_b862315
_ZN4PLMD3ves23LinearBasisSetExpansion16getBiasAndForcesERKSt6vectorIdSaIdEERbRS4_1988037
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/LinearBasisSetExpansion.h.func.html b/coverage/ves/LinearBasisSetExpansion.h.func.html new file mode 100644 index 000000000000..f0e2e7bc52ab --- /dev/null +++ b/coverage/ves/LinearBasisSetExpansion.h.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - ves/LinearBasisSetExpansion.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - LinearBasisSetExpansion.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:212295.5 %
Date:2024-04-19 12:12:35Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves23LinearBasisSetExpansion16getBiasAndForcesERKSt6vectorIdSaIdEERbRS4_1988037
_ZN4PLMD3ves23LinearBasisSetExpansion17getBasisSetValuesERKSt6vectorIdSaIdEERS4_b862315
_ZN4PLMD3ves23LinearBasisSetExpansion19getBasisSetConstantEv408
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/LinearBasisSetExpansion.h.gcov.html b/coverage/ves/LinearBasisSetExpansion.h.gcov.html new file mode 100644 index 000000000000..b4b10079cfe5 --- /dev/null +++ b/coverage/ves/LinearBasisSetExpansion.h.gcov.html @@ -0,0 +1,327 @@ + + + + + + + + LCOV - plumed test coverage - ves/LinearBasisSetExpansion.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - LinearBasisSetExpansion.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:212295.5 %
Date:2024-04-19 12:12:35Functions:33100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_ves_LinearBasisSetExpansion_h
+      23             : #define __PLUMED_ves_LinearBasisSetExpansion_h
+      24             : 
+      25             : #include <vector>
+      26             : #include <string>
+      27             : #include <memory>
+      28             : 
+      29             : 
+      30             : namespace PLMD {
+      31             : 
+      32             : class Action;
+      33             : class Keywords;
+      34             : class Value;
+      35             : class Communicator;
+      36             : class Grid;
+      37             : class OFile;
+      38             : 
+      39             : 
+      40             : namespace ves {
+      41             : 
+      42             : class CoeffsVector;
+      43             : class BasisFunctions;
+      44             : class TargetDistribution;
+      45             : class VesBias;
+      46             : 
+      47             : 
+      48             : class LinearBasisSetExpansion {
+      49             :   LinearBasisSetExpansion& operator=(const LinearBasisSetExpansion&) = delete;
+      50             : private:
+      51             :   std::string label_;
+      52             :   //
+      53             :   Action* action_pntr_;
+      54             :   VesBias* vesbias_pntr_;
+      55             :   Communicator& mycomm_;
+      56             :   bool serial_;
+      57             :   //
+      58             :   double beta_;
+      59             :   double kbt_;
+      60             :   //
+      61             :   std::vector<Value*> args_pntrs_;
+      62             :   unsigned int nargs_;
+      63             :   //
+      64             :   std::vector<BasisFunctions*> basisf_pntrs_;
+      65             :   std::vector<unsigned int> nbasisf_;
+      66             :   //
+      67             :   CoeffsVector* bias_coeffs_pntr_;
+      68             :   size_t ncoeffs_;
+      69             :   std::unique_ptr<CoeffsVector> targetdist_averages_pntr_;
+      70             :   //
+      71             :   std::vector<std::string> grid_min_;
+      72             :   std::vector<std::string> grid_max_;
+      73             :   std::vector<unsigned int> grid_bins_;
+      74             :   //
+      75             :   std::string targetdist_grid_label_;
+      76             :   //
+      77             :   long long int step_of_last_biasgrid_update;
+      78             :   long long int step_of_last_biaswithoutcutoffgrid_update;
+      79             :   long long int step_of_last_fesgrid_update;
+      80             :   //
+      81             :   std::unique_ptr<Grid> bias_grid_pntr_;
+      82             :   std::unique_ptr<Grid> bias_withoutcutoff_grid_pntr_;
+      83             :   std::unique_ptr<Grid> fes_grid_pntr_;
+      84             :   Grid* log_targetdist_grid_pntr_;
+      85             :   Grid* targetdist_grid_pntr_;
+      86             :   //
+      87             :   TargetDistribution* targetdist_pntr_;
+      88             : public:
+      89             :   static void registerKeywords( Keywords& keys );
+      90             :   // Constructor
+      91             :   explicit LinearBasisSetExpansion(
+      92             :     const std::string&,
+      93             :     const double,
+      94             :     Communicator&,
+      95             :     const std::vector<Value*>&,
+      96             :     std::vector<BasisFunctions*>&,
+      97             :     CoeffsVector* bias_coeffs_pntr_in=NULL);
+      98             :   //
+      99             : private:
+     100             :   // copy constructor is disabled (private and unimplemented)
+     101             :   explicit LinearBasisSetExpansion(const LinearBasisSetExpansion&);
+     102             : public:
+     103             :   ~LinearBasisSetExpansion();
+     104             :   //
+     105             :   std::vector<Value*> getPntrsToArguments() const {return args_pntrs_;}
+     106             :   std::vector<BasisFunctions*> getPntrsToBasisFunctions() const {return basisf_pntrs_;}
+     107             :   CoeffsVector* getPntrToBiasCoeffs() const {return bias_coeffs_pntr_;}
+     108             :   Grid* getPntrToBiasGrid() const {return bias_grid_pntr_.get();};
+     109             :   //
+     110             :   unsigned int getNumberOfArguments() const {return nargs_;};
+     111             :   std::vector<unsigned int> getNumberOfBasisFunctions() const {return nbasisf_;};
+     112             :   size_t getNumberOfCoeffs() const {return ncoeffs_;};
+     113             :   //
+     114          83 :   CoeffsVector& BiasCoeffs() const {return *bias_coeffs_pntr_;};
+     115             :   CoeffsVector& TargetDistAverages() const {return *targetdist_averages_pntr_;};
+     116             :   //
+     117             :   void setSerial() {serial_=true;}
+     118             :   void setParallel() {serial_=false;}
+     119             :   //
+     120             :   void linkVesBias(VesBias*);
+     121             :   void linkAction(Action*);
+     122             :   // calculate bias and derivatives
+     123             :   static double getBiasAndForces(const std::vector<double>&, bool&, std::vector<double>&, std::vector<double>&, std::vector<BasisFunctions*>&, CoeffsVector*, Communicator* comm_in=NULL);
+     124             :   double getBiasAndForces(const std::vector<double>&, bool&, std::vector<double>&, std::vector<double>&);
+     125             :   double getBiasAndForces(const std::vector<double>&, bool&, std::vector<double>&);
+     126             :   double getBias(const std::vector<double>&, bool&, const bool parallel=true);
+     127             :   //
+     128             :   static void getBasisSetValues(const std::vector<double>&, std::vector<double>&, std::vector<BasisFunctions*>&, CoeffsVector*, Communicator* comm_in=NULL);
+     129             :   void getBasisSetValues(const std::vector<double>&, std::vector<double>&, const bool parallel=true);
+     130             :   //
+     131             :   static double getBasisSetValue(const std::vector<double>&, const size_t, std::vector<BasisFunctions*>&, CoeffsVector*);
+     132             :   double getBasisSetValue(const std::vector<double>&, const size_t);
+     133             :   double getBasisSetConstant();
+     134             :   // Bias grid and output stuff
+     135             :   void setupBiasGrid(const bool usederiv=false);
+     136             :   void updateBiasGrid();
+     137          36 :   void resetStepOfLastBiasGridUpdate() {step_of_last_biasgrid_update = -1000;}
+     138         475 :   void setStepOfLastBiasGridUpdate(long long int step) {step_of_last_biasgrid_update = step;}
+     139         712 :   long long int getStepOfLastBiasGridUpdate() const {return step_of_last_biasgrid_update;}
+     140             :   void writeBiasGridToFile(OFile&, const bool append=false) const;
+     141             :   //
+     142             :   void updateBiasWithoutCutoffGrid();
+     143             :   void resetStepOfLastBiasWithoutCutoffGridUpdate() {step_of_last_biaswithoutcutoffgrid_update = -1000;}
+     144          23 :   void setStepOfLastBiasWithoutCutoffGridUpdate(long long int step) {step_of_last_biaswithoutcutoffgrid_update = step;}
+     145          27 :   long long int getStepOfLastBiasWithoutCutoffGridUpdate() const {return step_of_last_biaswithoutcutoffgrid_update;}
+     146             :   void writeBiasWithoutCutoffGridToFile(OFile&, const bool append=false) const;
+     147             :   //
+     148             :   void setBiasMinimumToZero();
+     149             :   void setBiasMaximumToZero();
+     150             :   //
+     151             :   void setupFesGrid();
+     152             :   void updateFesGrid();
+     153          36 :   void resetStepOfLastFesGridUpdate() {step_of_last_fesgrid_update = -1000;}
+     154         473 :   void setStepOfLastFesGridUpdate(long long int step) {step_of_last_fesgrid_update = step;}
+     155         539 :   long long int getStepOfLastFesGridUpdate() const {return step_of_last_fesgrid_update;}
+     156             :   void writeFesGridToFile(OFile&, const bool append=false) const;
+     157             :   //
+     158             :   void setupFesProjGrid();
+     159             :   void writeFesProjGridToFile(const std::vector<std::string>&, OFile&, const bool append=false) const;
+     160             :   //
+     161             :   void writeTargetDistGridToFile(OFile&, const bool append=false) const;
+     162             :   void writeLogTargetDistGridToFile(OFile&, const bool append=false) const;
+     163             :   void writeTargetDistProjGridToFile(const std::vector<std::string>&, OFile&, const bool append=false) const;
+     164             :   void writeTargetDistributionToFile(const std::string&) const;
+     165             :   //
+     166             :   std::vector<unsigned int> getGridBins() const {return grid_bins_;}
+     167             :   void setGridBins(const std::vector<unsigned int>&);
+     168             :   void setGridBins(const unsigned int);
+     169             :   //
+     170             :   double getBeta() const {return beta_;}
+     171             :   double getKbT() const {return kbt_;}
+     172             :   double beta() const {return beta_;}
+     173     1224051 :   double kBT() const {return kbt_;}
+     174             :   //
+     175             :   void setupUniformTargetDistribution();
+     176             :   void setupTargetDistribution(TargetDistribution*);
+     177             :   void updateTargetDistribution();
+     178             :   //
+     179             :   void readInRestartTargetDistribution(const std::string&);
+     180             :   void restartTargetDistribution();
+     181             :   //
+     182             :   bool biasCutoffActive() const;
+     183             :   //
+     184             :   double calculateReweightFactor() const;
+     185             :   //
+     186             : private:
+     187             :   //
+     188             :   std::unique_ptr<Grid> setupGeneralGrid(const std::string&, const bool usederiv=false);
+     189             :   //
+     190             :   void calculateTargetDistAveragesFromGrid(const Grid*);
+     191             :   //
+     192             :   bool isStaticTargetDistFileOutputActive() const;
+     193             : };
+     194             : 
+     195             : 
+     196             : inline
+     197             : double LinearBasisSetExpansion::getBiasAndForces(const std::vector<double>& args_values, bool& all_inside, std::vector<double>& forces, std::vector<double>& coeffsderivs_values) {
+     198       23750 :   return getBiasAndForces(args_values,all_inside,forces,coeffsderivs_values,basisf_pntrs_, bias_coeffs_pntr_, &mycomm_);
+     199             : }
+     200             : 
+     201             : 
+     202             : inline
+     203     1988037 : double LinearBasisSetExpansion::getBiasAndForces(const std::vector<double>& args_values, bool& all_inside, std::vector<double>& forces) {
+     204     1988037 :   std::vector<double> coeffsderivs_values_dummy(ncoeffs_);
+     205     3976074 :   return getBiasAndForces(args_values,all_inside,forces,coeffsderivs_values_dummy,basisf_pntrs_, bias_coeffs_pntr_, &mycomm_);
+     206             : }
+     207             : 
+     208             : 
+     209             : inline
+     210             : double LinearBasisSetExpansion::getBias(const std::vector<double>& args_values, bool& all_inside, const bool parallel) {
+     211             :   std::vector<double> forces_dummy(nargs_);
+     212             :   std::vector<double> coeffsderivs_values_dummy(ncoeffs_);
+     213             :   if(parallel) {
+     214             :     return getBiasAndForces(args_values,all_inside,forces_dummy,coeffsderivs_values_dummy,basisf_pntrs_, bias_coeffs_pntr_, &mycomm_);
+     215             :   }
+     216             :   else {
+     217             :     return getBiasAndForces(args_values,all_inside,forces_dummy,coeffsderivs_values_dummy,basisf_pntrs_, bias_coeffs_pntr_, NULL);
+     218             :   }
+     219             : }
+     220             : 
+     221             : 
+     222             : inline
+     223      862315 : void LinearBasisSetExpansion::getBasisSetValues(const std::vector<double>& args_values, std::vector<double>& basisset_values, const bool parallel) {
+     224      862315 :   if(parallel) {
+     225           0 :     getBasisSetValues(args_values,basisset_values,basisf_pntrs_, bias_coeffs_pntr_, &mycomm_);
+     226             :   }
+     227             :   else {
+     228      862315 :     getBasisSetValues(args_values,basisset_values,basisf_pntrs_, bias_coeffs_pntr_, NULL);
+     229             :   }
+     230      862315 : }
+     231             : 
+     232             : 
+     233             : inline
+     234             : double LinearBasisSetExpansion::getBasisSetValue(const std::vector<double>& args_values, const size_t basisset_index) {
+     235             :   return getBasisSetValue(args_values,basisset_index,basisf_pntrs_, bias_coeffs_pntr_);
+     236             : }
+     237             : 
+     238             : 
+     239             : inline
+     240         408 : double LinearBasisSetExpansion::getBasisSetConstant() {
+     241         408 :   std::vector<double> args_dummy(nargs_,0.0);
+     242         816 :   return getBasisSetValue(args_dummy,0,basisf_pntrs_, bias_coeffs_pntr_);
+     243             : }
+     244             : 
+     245             : 
+     246             : }
+     247             : 
+     248             : }
+     249             : 
+     250             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/MD_LinearExpansionPES.cpp.func-sort-c.html b/coverage/ves/MD_LinearExpansionPES.cpp.func-sort-c.html new file mode 100644 index 000000000000..a05f539612c9 --- /dev/null +++ b/coverage/ves/MD_LinearExpansionPES.cpp.func-sort-c.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - ves/MD_LinearExpansionPES.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - MD_LinearExpansionPES.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:32533597.0 %
Date:2024-04-19 12:12:35Functions: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_LinearExpansionPESRegisterMeC2Ev5088
_ZN4PLMD3ves12_GLOBAL__N_131MD_LinearExpansionPESRegisterMeD2Ev5088
_ZN4PLMD3ves21MD_LinearExpansionPES16registerKeywordsERNS_8KeywordsE5088
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/MD_LinearExpansionPES.cpp.func.html b/coverage/ves/MD_LinearExpansionPES.cpp.func.html new file mode 100644 index 000000000000..2aae290ca664 --- /dev/null +++ b/coverage/ves/MD_LinearExpansionPES.cpp.func.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - ves/MD_LinearExpansionPES.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - MD_LinearExpansionPES.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:32533597.0 %
Date:2024-04-19 12:12:35Functions:99100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12_GLOBAL__N_131MD_LinearExpansionPESRegisterMe6createERKNS_13CLToolOptionsE44
_ZN4PLMD3ves12_GLOBAL__N_131MD_LinearExpansionPESRegisterMeC2Ev5088
_ZN4PLMD3ves12_GLOBAL__N_131MD_LinearExpansionPESRegisterMeD2Ev5088
_ZN4PLMD3ves21MD_LinearExpansionPES11calc_energyERKSt6vectorINS_13VectorGenericILj3EEESaIS4_EERS6_3939
_ZN4PLMD3ves21MD_LinearExpansionPES16registerKeywordsERNS_8KeywordsE5088
_ZN4PLMD3ves21MD_LinearExpansionPES4mainEP8_IO_FILES3_RNS_12CommunicatorE40
_ZN4PLMD3ves21MD_LinearExpansionPES9calc_tempERKSt6vectorINS_13VectorGenericILj3EEESaIS4_EE3939
_ZN4PLMD3ves21MD_LinearExpansionPESC2ERKNS_13CLToolOptionsE44
_ZNK4PLMD3ves21MD_LinearExpansionPES11descriptionB5cxx11Ev4
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/MD_LinearExpansionPES.cpp.gcov.html b/coverage/ves/MD_LinearExpansionPES.cpp.gcov.html new file mode 100644 index 000000000000..fcfd2e5c5145 --- /dev/null +++ b/coverage/ves/MD_LinearExpansionPES.cpp.gcov.html @@ -0,0 +1,758 @@ + + + + + + + + LCOV - plumed test coverage - ves/MD_LinearExpansionPES.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - MD_LinearExpansionPES.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:32533597.0 %
Date:2024-04-19 12:12:35Functions:99100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "BasisFunctions.h"
+      24             : #include "LinearBasisSetExpansion.h"
+      25             : #include "CoeffsVector.h"
+      26             : #include "GridIntegrationWeights.h"
+      27             : #include "GridProjWeights.h"
+      28             : 
+      29             : #include "cltools/CLTool.h"
+      30             : #include "core/CLToolRegister.h"
+      31             : #include "tools/Vector.h"
+      32             : #include "tools/Random.h"
+      33             : #include "tools/Grid.h"
+      34             : #include "tools/Communicator.h"
+      35             : #include "tools/FileBase.h"
+      36             : #include "core/PlumedMain.h"
+      37             : #include "core/ActionRegister.h"
+      38             : #include "core/ActionSet.h"
+      39             : #include "core/Value.h"
+      40             : 
+      41             : #include <string>
+      42             : #include <cstdio>
+      43             : #include <cmath>
+      44             : #include <vector>
+      45             : #include <iostream>
+      46             : 
+      47             : #ifdef __PLUMED_HAS_MPI
+      48             : #include <mpi.h>
+      49             : #endif
+      50             : 
+      51             : 
+      52             : namespace PLMD {
+      53             : namespace ves {
+      54             : 
+      55             : //+PLUMEDOC VES_TOOLS ves_md_linearexpansion
+      56             : /*
+      57             : Simple MD code for dynamics on a potential energy surface given by a linear basis set expansion.
+      58             : 
+      59             : This is simple MD code that allows running dynamics of a single particle on a
+      60             : potential energy surface given by some linear basis set expansion in one to three
+      61             : dimensions.
+      62             : 
+      63             : It is possible to run more than one replica of the system in parallel.
+      64             : 
+      65             : \par Examples
+      66             : 
+      67             : In the following example we perform dynamics on the
+      68             : Wolfe-Quapp potential that is defined as
+      69             : \f[
+      70             : U(x,y) = x^4 + y^4 - 2 x^2 - 4 y^2 + xy + 0.3 x + 0.1 y
+      71             : \f]
+      72             : To define the potential we employ polynomial power basis
+      73             : functions (\ref BF_POWERS). The input file is given as
+      74             : \verbatim
+      75             : nstep             10000
+      76             : tstep             0.005
+      77             : temperature       1.0
+      78             : friction          10.0
+      79             : random_seed       4525
+      80             : plumed_input      plumed.dat
+      81             : dimension         2
+      82             : replicas          1
+      83             : basis_functions_1 BF_POWERS ORDER=4 MINIMUM=-3.0 MAXIMUM=+3.0
+      84             : basis_functions_2 BF_POWERS ORDER=4 MINIMUM=-3.0 MAXIMUM=+3.0
+      85             : input_coeffs       pot_coeffs_input.data
+      86             : initial_position   -1.174,+1.477
+      87             : output_potential        potential.data
+      88             : output_potential_grid   150
+      89             : output_histogram        histogram.data
+      90             : 
+      91             : # Wolfe-Quapp potential given by the equation
+      92             : # U(x,y) = x**4 + y**4 - 2.0*x**2 - 4.0*y**2 + x*y + 0.3*x + 0.1*y
+      93             : # Minima around (-1.174,1.477); (-0.831,-1.366); (1.124,-1.486)
+      94             : # Maxima around (0.100,0.050)
+      95             : # Saddle points around (-1.013,-0.036); (0.093,0.174); (-0.208,-1.407)
+      96             : \endverbatim
+      97             : 
+      98             : This input is then run by using the following command.
+      99             : \verbatim
+     100             : plumed ves_md_linearexpansion input
+     101             : \endverbatim
+     102             : 
+     103             : The corresponding pot_coeffs_input.data file is
+     104             : \verbatim
+     105             : #! FIELDS idx_dim1 idx_dim2 pot.coeffs index description
+     106             : #! SET type LinearBasisSet
+     107             : #! SET ndimensions  2
+     108             : #! SET ncoeffs_total  25
+     109             : #! SET shape_dim1  5
+     110             : #! SET shape_dim2  5
+     111             :        0       0         0.0000000000000000e+00       0  1*1
+     112             :        1       0         0.3000000000000000e+00       1  s^1*1
+     113             :        2       0        -2.0000000000000000e+00       2  s^2*1
+     114             :        4       0         1.0000000000000000e+00       4  s^4*1
+     115             :        0       1         0.1000000000000000e+00       5  1*s^1
+     116             :        1       1        +1.0000000000000000e+00       6  s^1*s^1
+     117             :        0       2        -4.0000000000000000e+00      10  1*s^2
+     118             :        0       4         1.0000000000000000e+00      20  1*s^4
+     119             : #!-------------------
+     120             : \endverbatim
+     121             : 
+     122             : One then uses the (x,y) position of the particle as CVs by using the \ref POSITION
+     123             : action as shown in the following PLUMED input
+     124             : \plumedfile
+     125             : p: POSITION ATOM=1
+     126             : ene: ENERGY
+     127             : PRINT ARG=p.x,p.y,ene FILE=colvar.data FMT=%8.4f
+     128             : \endplumedfile
+     129             : 
+     130             : 
+     131             : 
+     132             : */
+     133             : //+ENDPLUMEDOC
+     134             : 
+     135             : class MD_LinearExpansionPES : public PLMD::CLTool {
+     136             : public:
+     137           4 :   std::string description() const override {return "MD of a one particle on a linear expansion PES";}
+     138             :   static void registerKeywords( Keywords& keys );
+     139             :   explicit MD_LinearExpansionPES( const CLToolOptions& co );
+     140             :   int main( FILE* in, FILE* out, PLMD::Communicator& pc) override;
+     141             : private:
+     142             :   size_t dim;
+     143             :   std::string dim_string_prefix;
+     144             :   std::unique_ptr<LinearBasisSetExpansion> potential_expansion_pntr;
+     145             :   //
+     146             :   double calc_energy( const std::vector<Vector>&, std::vector<Vector>& );
+     147             :   double calc_temp( const std::vector<Vector>& );
+     148             : };
+     149             : 
+     150       15308 : PLUMED_REGISTER_CLTOOL(MD_LinearExpansionPES,"ves_md_linearexpansion")
+     151             : 
+     152        5088 : void MD_LinearExpansionPES::registerKeywords( Keywords& keys ) {
+     153        5088 :   CLTool::registerKeywords( keys );
+     154       10176 :   keys.add("compulsory","nstep","10","The number of steps of dynamics you want to run.");
+     155       10176 :   keys.add("compulsory","tstep","0.005","The integration timestep.");
+     156       10176 :   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       10176 :   keys.add("compulsory","friction","10.","The friction of the Langevin thermostat. For multiple replica you can give a separate value for each replica.");
+     158       10176 :   keys.add("compulsory","random_seed","5293818","Value of random number seed.");
+     159       10176 :   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       10176 :   keys.add("compulsory","dimension","1","Number of dimensions, supports 1 to 3.");
+     161       10176 :   keys.add("compulsory","initial_position","Initial position of the particle. For multiple replica you can give a separate value for each replica.");
+     162       10176 :   keys.add("compulsory","replicas","1","Number of replicas.");
+     163       10176 :   keys.add("compulsory","basis_functions_1","Basis functions for dimension 1.");
+     164       10176 :   keys.add("optional","basis_functions_2","Basis functions for dimension 2 if needed.");
+     165       10176 :   keys.add("optional","basis_functions_3","Basis functions for dimension 3 if needed.");
+     166       10176 :   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       10176 :   keys.add("compulsory","output_coeffs","potential-coeffs.out.data","Filename of the output coefficient file for the potential.");
+     168       10176 :   keys.add("compulsory","output_coeffs_fmt","%30.16e","Format of the output coefficient file for the potential. Useful for regtests.");
+     169       10176 :   keys.add("optional","coeffs_prefactor","prefactor for multiplying the coefficients with. For multiple replica you can give a separate value for each replica.");
+     170       10176 :   keys.add("optional","template_coeffs_file","only generate a template coefficient file with the filename given and exit.");
+     171       10176 :   keys.add("compulsory","output_potential_grid","100","The number of grid points used for the potential and histogram output files.");
+     172       10176 :   keys.add("compulsory","output_potential","potential.data","Filename of the potential output file.");
+     173       10176 :   keys.add("compulsory","output_histogram","histogram.data","Filename of the histogram output file.");
+     174        5088 : }
+     175             : 
+     176             : 
+     177          44 : MD_LinearExpansionPES::MD_LinearExpansionPES( const CLToolOptions& co ):
+     178             :   CLTool(co),
+     179          44 :   dim(0),
+     180          44 :   dim_string_prefix("dim")
+     181             : {
+     182          44 :   inputdata=ifile; //commandline;
+     183          44 : }
+     184             : 
+     185             : inline
+     186        3939 : double MD_LinearExpansionPES::calc_energy( const std::vector<Vector>& pos, std::vector<Vector>& forces) {
+     187        3939 :   std::vector<double> pos_tmp(dim);
+     188        3939 :   std::vector<double> forces_tmp(dim,0.0);
+     189        8585 :   for(unsigned int j=0; j<dim; ++j) {
+     190        4646 :     pos_tmp[j]=pos[0][j];
+     191             :   }
+     192        3939 :   bool all_inside = true;
+     193        3939 :   double potential = potential_expansion_pntr->getBiasAndForces(pos_tmp,all_inside,forces_tmp);
+     194        8585 :   for(unsigned int j=0; j<dim; ++j) {
+     195        4646 :     forces[0][j] = forces_tmp[j];
+     196             :   }
+     197        3939 :   return potential;
+     198             : }
+     199             : 
+     200             : 
+     201             : inline
+     202        3939 : double MD_LinearExpansionPES::calc_temp( const std::vector<Vector>& vel) {
+     203             :   double total_KE=0.0;
+     204             :   //! Double the total kinetic energy of the system
+     205        8585 :   for(unsigned int j=0; j<dim; ++j) {
+     206        4646 :     total_KE+=vel[0][j]*vel[0][j];
+     207             :   }
+     208        3939 :   return total_KE / (double) dim; // total_KE is actually 2*KE
+     209             : }
+     210             : 
+     211          40 : int MD_LinearExpansionPES::main( FILE* in, FILE* out, PLMD::Communicator& pc) {
+     212             :   int plumedWantsToStop;
+     213          40 :   Random random;
+     214             :   unsigned int stepWrite=1000;
+     215             : 
+     216          40 :   std::unique_ptr<PLMD::PlumedMain> plumed;
+     217             : 
+     218             :   size_t replicas;
+     219             :   unsigned int coresPerReplica;
+     220          40 :   parse("replicas",replicas);
+     221          40 :   if(replicas==1) {
+     222           9 :     coresPerReplica = pc.Get_size();
+     223             :   } else {
+     224          31 :     if(pc.Get_size()%replicas!=0) {
+     225           0 :       error("the number of MPI processes is not a multiple of the number of replicas.");
+     226             :     }
+     227          31 :     coresPerReplica = pc.Get_size()/replicas;
+     228             :   }
+     229             :   // create intra and inter communicators
+     230          40 :   Communicator intra, inter;
+     231          40 :   if(Communicator::initialized()) {
+     232          33 :     int iworld=(pc.Get_rank() / coresPerReplica);
+     233          33 :     pc.Split(iworld,0,intra);
+     234          33 :     pc.Split(intra.Get_rank(),0,inter);
+     235             :   }
+     236             : 
+     237             :   long long unsigned int nsteps;
+     238          40 :   parse("nstep",nsteps);
+     239             :   double tstep;
+     240          40 :   parse("tstep",tstep);
+     241             :   // initialize to solve a cppcheck 1.86 warning
+     242          40 :   double temp=0.0;
+     243          40 :   std::vector<double> temps_vec(0);
+     244          80 :   parseVector("temperature",temps_vec);
+     245          40 :   if(temps_vec.size()==1) {
+     246          36 :     temp = temps_vec[0];
+     247             :   }
+     248           4 :   else if(replicas > 1 && temps_vec.size()==replicas) {
+     249           4 :     temp = temps_vec[inter.Get_rank()];
+     250             :   }
+     251             :   else {
+     252           0 :     error("problem with temperature keyword, you need to give either one value or a value for each replica.");
+     253             :   }
+     254             :   //
+     255             :   double friction;
+     256          40 :   std::vector<double> frictions_vec(0);
+     257          80 :   parseVector("friction",frictions_vec);
+     258          40 :   if(frictions_vec.size()==1) {
+     259          36 :     friction = frictions_vec[0];
+     260             :   }
+     261           4 :   else if(frictions_vec.size()==replicas) {
+     262           4 :     friction = frictions_vec[inter.Get_rank()];
+     263             :   }
+     264             :   else {
+     265           0 :     error("problem with friction keyword, you need to give either one value or a value for each replica.");
+     266             :   }
+     267             :   //
+     268             :   int seed;
+     269          40 :   std::vector<int> seeds_vec(0);
+     270          40 :   parseVector("random_seed",seeds_vec);
+     271          92 :   for(unsigned int i=0; i<seeds_vec.size(); i++) {
+     272          52 :     if(seeds_vec[i]>0) {seeds_vec[i] = -seeds_vec[i];}
+     273             :   }
+     274          40 :   if(replicas==1) {
+     275           9 :     if(seeds_vec.size()>1) {error("problem with random_seed keyword, for a single replica you should only give one value");}
+     276           9 :     seed = seeds_vec[0];
+     277             :   }
+     278             :   else {
+     279          31 :     if(seeds_vec.size()!=1 && seeds_vec.size()!=replicas) {
+     280           0 :       error("problem with random_seed keyword, for multiple replicas you should give either one value or a separate value for each replica");
+     281             :     }
+     282          31 :     if(seeds_vec.size()==1) {
+     283          27 :       seeds_vec.resize(replicas);
+     284         109 :       for(unsigned int i=1; i<seeds_vec.size(); i++) {seeds_vec[i] = seeds_vec[0] + i;}
+     285             :     }
+     286          31 :     seed = seeds_vec[inter.Get_rank()];
+     287             :   }
+     288             : 
+     289             :   //
+     290          80 :   parse("dimension",dim);
+     291             : 
+     292             :   std::vector<std::string> plumed_inputfiles;
+     293          80 :   parseVector("plumed_input",plumed_inputfiles);
+     294          40 :   if(plumed_inputfiles.size()!=1 && plumed_inputfiles.size()!=replicas) {
+     295           0 :     error("in plumed_input you should either give one file or separate files for each replica.");
+     296             :   }
+     297             : 
+     298          40 :   std::vector<Vector> initPos(replicas);
+     299             :   std::vector<double> initPosTmp;
+     300          80 :   parseVector("initial_position",initPosTmp);
+     301          40 :   if(initPosTmp.size()==dim) {
+     302          48 :     for(unsigned int i=0; i<replicas; i++) {
+     303          72 :       for(unsigned int k=0; k<dim; k++) {
+     304          38 :         initPos[i][k]=initPosTmp[k];
+     305             :       }
+     306             :     }
+     307             :   }
+     308          26 :   else if(initPosTmp.size()==dim*replicas) {
+     309         126 :     for(unsigned int i=0; i<replicas; i++) {
+     310         216 :       for(unsigned int k=0; k<dim; k++) {
+     311         116 :         initPos[i][k]=initPosTmp[i*dim+k];
+     312             :       }
+     313             :     }
+     314             :   }
+     315             :   else {
+     316           0 :     error("problem with initial_position keyword, you need to give either one value or a value for each replica.");
+     317             :   }
+     318             : 
+     319          79 :   auto deleter=[](FILE* f) { fclose(f); };
+     320          40 :   FILE* file_dummy = fopen("/dev/null","w+");
+     321          40 :   plumed_assert(file_dummy);
+     322             :   // call fclose when file_dummy_deleter goes out of scope
+     323             :   std::unique_ptr<FILE,decltype(deleter)> file_dummy_deleter(file_dummy,deleter);
+     324             :   // Note: this should be declared before plumed_bf to make sure the file is closed after plumed_bf has been destroyed
+     325             : 
+     326             :   auto plumed_bf = Tools::make_unique<PLMD::PlumedMain>();
+     327          40 :   unsigned int nn=1;
+     328          40 :   plumed_bf->cmd("setNatoms",&nn);
+     329          40 :   plumed_bf->cmd("setLog",file_dummy);
+     330          40 :   plumed_bf->cmd("init",&nn);
+     331          40 :   std::vector<BasisFunctions*> basisf_pntrs(dim);
+     332          40 :   std::vector<std::string> basisf_keywords(dim);
+     333          40 :   std::vector<std::unique_ptr<Value>> args(dim);
+     334          40 :   std::vector<bool> periodic(dim);
+     335          40 :   std::vector<double> interval_min(dim);
+     336          40 :   std::vector<double> interval_max(dim);
+     337          40 :   std::vector<double> interval_range(dim);
+     338          88 :   for(unsigned int i=0; i<dim; i++) {
+     339             :     std::string bf_keyword;
+     340          48 :     std::string is; Tools::convert(i+1,is);
+     341          96 :     parse("basis_functions_"+is,bf_keyword);
+     342          48 :     if(bf_keyword.size()==0) {
+     343           0 :       error("basis_functions_"+is+" is needed");
+     344             :     }
+     345          48 :     if(bf_keyword.at(0)=='{' && bf_keyword.at(bf_keyword.size()-1)=='}') {
+     346           4 :       bf_keyword = bf_keyword.substr(1,bf_keyword.size()-2);
+     347             :     }
+     348             :     basisf_keywords[i] = bf_keyword;
+     349          96 :     plumed_bf->readInputLine(bf_keyword+" LABEL="+dim_string_prefix+is);
+     350          48 :     basisf_pntrs[i] = plumed_bf->getActionSet().selectWithLabel<BasisFunctions*>(dim_string_prefix+is);
+     351          96 :     args[i] = Tools::make_unique<Value>(nullptr,dim_string_prefix+is,false);
+     352          48 :     args[i]->setNotPeriodic();
+     353          48 :     periodic[i] = basisf_pntrs[i]->arePeriodic();
+     354          48 :     interval_min[i] = basisf_pntrs[i]->intervalMin();
+     355          48 :     interval_max[i] = basisf_pntrs[i]->intervalMax();
+     356          48 :     interval_range[i] = basisf_pntrs[i]->intervalMax()-basisf_pntrs[i]->intervalMin();
+     357             :   }
+     358          40 :   Communicator comm_dummy;
+     359          80 :   auto coeffs_pntr = Tools::make_unique<CoeffsVector>("pot.coeffs",Tools::unique2raw(args),basisf_pntrs,comm_dummy,false);
+     360          80 :   potential_expansion_pntr = Tools::make_unique<LinearBasisSetExpansion>("potential",1.0/temp,comm_dummy,Tools::unique2raw(args),basisf_pntrs,coeffs_pntr.get());
+     361             : 
+     362          40 :   std::string template_coeffs_fname="";
+     363          80 :   parse("template_coeffs_file",template_coeffs_fname);
+     364          40 :   if(template_coeffs_fname.size()>0) {
+     365           1 :     OFile ofile_coeffstmpl;
+     366           1 :     ofile_coeffstmpl.link(pc);
+     367           1 :     ofile_coeffstmpl.open(template_coeffs_fname);
+     368           1 :     coeffs_pntr->writeToFile(ofile_coeffstmpl,true);
+     369           1 :     ofile_coeffstmpl.close();
+     370             :     std::printf("Only generating a template coefficient file - Should stop now.");
+     371             :     return 0;
+     372           1 :   }
+     373             : 
+     374          39 :   std::vector<std::string> input_coeffs_fnames(0);
+     375          78 :   parseVector("input_coeffs",input_coeffs_fnames);
+     376             :   std::string input_coeffs_fname;
+     377             :   bool diff_input_coeffs = false;
+     378          39 :   if(input_coeffs_fnames.size()==1) {
+     379             :     input_coeffs_fname = input_coeffs_fnames[0];
+     380             :   }
+     381           9 :   else if(replicas > 1 && input_coeffs_fnames.size()==replicas) {
+     382             :     diff_input_coeffs = true;
+     383           9 :     input_coeffs_fname = input_coeffs_fnames[inter.Get_rank()];
+     384             :   }
+     385             :   else {
+     386           0 :     error("problem with coeffs_file keyword, you need to give either one value or a value for each replica.");
+     387             :   }
+     388          39 :   coeffs_pntr->readFromFile(input_coeffs_fname,true,true);
+     389          39 :   std::vector<double> coeffs_prefactors(0);
+     390          78 :   parseVector("coeffs_prefactor",coeffs_prefactors);
+     391          39 :   if(coeffs_prefactors.size()>0) {
+     392             :     double coeffs_prefactor = 1.0;
+     393           7 :     if(coeffs_prefactors.size()==1) {
+     394           3 :       coeffs_prefactor = coeffs_prefactors[0];
+     395             :     }
+     396           4 :     else if(replicas > 1 && coeffs_prefactors.size()==replicas) {
+     397             :       diff_input_coeffs = true;
+     398           4 :       coeffs_prefactor = coeffs_prefactors[inter.Get_rank()];
+     399             :     }
+     400             :     else {
+     401           0 :       error("problem with coeffs_prefactor keyword, you need to give either one value or a value for each replica.");
+     402             :     }
+     403           7 :     coeffs_pntr->scaleAllValues(coeffs_prefactor);
+     404             :   }
+     405             :   unsigned int pot_grid_bins;
+     406          78 :   parse("output_potential_grid",pot_grid_bins);
+     407          39 :   potential_expansion_pntr->setGridBins(pot_grid_bins);
+     408          39 :   potential_expansion_pntr->setupBiasGrid(false);
+     409          39 :   potential_expansion_pntr->updateBiasGrid();
+     410          39 :   potential_expansion_pntr->setBiasMinimumToZero();
+     411          39 :   potential_expansion_pntr->updateBiasGrid();
+     412             : 
+     413          39 :   OFile ofile_potential;
+     414          39 :   ofile_potential.link(pc);
+     415             :   std::string output_potential_fname;
+     416          39 :   parse("output_potential",output_potential_fname);
+     417          39 :   if(diff_input_coeffs) {
+     418          13 :     ofile_potential.link(intra);
+     419             :     std::string suffix;
+     420          13 :     Tools::convert(inter.Get_rank(),suffix);
+     421          26 :     output_potential_fname = FileBase::appendSuffix(output_potential_fname,"."+suffix);
+     422             :   }
+     423          39 :   ofile_potential.open(output_potential_fname);
+     424          39 :   potential_expansion_pntr->writeBiasGridToFile(ofile_potential);
+     425          39 :   ofile_potential.close();
+     426          39 :   if(dim>1) {
+     427          21 :     for(unsigned int i=0; i<dim; i++) {
+     428          14 :       std::string is; Tools::convert(i+1,is);
+     429          14 :       std::vector<std::string> proj_arg(1);
+     430          14 :       proj_arg[0] = dim_string_prefix+is;
+     431          14 :       auto Fw = Tools::make_unique<FesWeight>(1/temp);
+     432          14 :       Grid proj_grid = (potential_expansion_pntr->getPntrToBiasGrid())->project(proj_arg,Fw.get());
+     433          14 :       proj_grid.setMinToZero();
+     434             : 
+     435          28 :       std::string output_potential_proj_fname = FileBase::appendSuffix(output_potential_fname,"."+dim_string_prefix+is);
+     436          14 :       OFile ofile_potential_proj;
+     437          14 :       ofile_potential_proj.link(pc);
+     438          14 :       ofile_potential_proj.open(output_potential_proj_fname);
+     439          14 :       proj_grid.writeToFile(ofile_potential_proj);
+     440          14 :       ofile_potential_proj.close();
+     441          28 :     }
+     442             :   }
+     443             : 
+     444             : 
+     445          39 :   Grid histo_grid(*potential_expansion_pntr->getPntrToBiasGrid());
+     446          78 :   std::vector<double> integration_weights = GridIntegrationWeights::getIntegrationWeights(&histo_grid);
+     447             :   double norm=0.0;
+     448      169278 :   for(Grid::index_t i=0; i<histo_grid.getSize(); i++) {
+     449      169239 :     double value = integration_weights[i]*exp(-histo_grid.getValue(i)/temp);
+     450      169239 :     norm += value;
+     451      169239 :     histo_grid.setValue(i,value);
+     452             :   }
+     453          39 :   histo_grid.scaleAllValuesAndDerivatives(1.0/norm);
+     454          39 :   OFile ofile_histogram;
+     455          39 :   ofile_histogram.link(pc);
+     456             :   std::string output_histogram_fname;
+     457          39 :   parse("output_histogram",output_histogram_fname);
+     458          39 :   if(diff_input_coeffs || temps_vec.size()>1) {
+     459          17 :     ofile_histogram.link(intra);
+     460             :     std::string suffix;
+     461          17 :     Tools::convert(inter.Get_rank(),suffix);
+     462          34 :     output_histogram_fname = FileBase::appendSuffix(output_histogram_fname,"."+suffix);
+     463             :   }
+     464          39 :   ofile_histogram.open(output_histogram_fname);
+     465          39 :   histo_grid.writeToFile(ofile_histogram);
+     466          39 :   ofile_histogram.close();
+     467             : 
+     468             :   std::string output_coeffs_fname;
+     469          78 :   parse("output_coeffs",output_coeffs_fname);
+     470             :   std::string output_coeffs_fmt;
+     471          78 :   parse("output_coeffs_fmt",output_coeffs_fmt);
+     472             :   coeffs_pntr->setOutputFmt(output_coeffs_fmt);
+     473          39 :   OFile ofile_coeffsout;
+     474          39 :   ofile_coeffsout.link(pc);
+     475          39 :   if(diff_input_coeffs) {
+     476          13 :     ofile_coeffsout.link(intra);
+     477             :     std::string suffix;
+     478          13 :     Tools::convert(inter.Get_rank(),suffix);
+     479          26 :     output_coeffs_fname = FileBase::appendSuffix(output_coeffs_fname,"."+suffix);
+     480             :   }
+     481          39 :   ofile_coeffsout.open(output_coeffs_fname);
+     482          39 :   coeffs_pntr->writeToFile(ofile_coeffsout,true);
+     483          39 :   ofile_coeffsout.close();
+     484             : 
+     485          39 :   if(pc.Get_rank() == 0) {
+     486          15 :     std::fprintf(out,"Replicas                              %zu\n",replicas);
+     487             :     std::fprintf(out,"Cores per replica                     %u\n",coresPerReplica);
+     488          15 :     std::fprintf(out,"Number of steps                       %llu\n",nsteps);
+     489          15 :     std::fprintf(out,"Timestep                              %f\n",tstep);
+     490          15 :     std::fprintf(out,"Temperature                           %f",temps_vec[0]);
+     491          18 :     for(unsigned int i=1; i<temps_vec.size(); i++) {std::fprintf(out,",%f",temps_vec[i]);}
+     492             :     std::fprintf(out,"\n");
+     493          15 :     std::fprintf(out,"Friction                              %f",frictions_vec[0]);
+     494          18 :     for(unsigned int i=1; i<frictions_vec.size(); i++) {std::fprintf(out,",%f",frictions_vec[i]);}
+     495             :     std::fprintf(out,"\n");
+     496          15 :     std::fprintf(out,"Random seed                           %d",seeds_vec[0]);
+     497          38 :     for(unsigned int i=1; i<seeds_vec.size(); i++) {std::fprintf(out,",%d",seeds_vec[i]);}
+     498             :     std::fprintf(out,"\n");
+     499          15 :     std::fprintf(out,"Dimensions                            %zu\n",dim);
+     500          34 :     for(unsigned int i=0; i<dim; i++) {
+     501          19 :       std::fprintf(out,"Basis Function %u                      %s\n",i+1,basisf_keywords[i].c_str());
+     502             :     }
+     503             :     std::fprintf(out,"PLUMED input                          %s",plumed_inputfiles[0].c_str());
+     504          16 :     for(unsigned int i=1; i<plumed_inputfiles.size(); i++) {std::fprintf(out,",%s",plumed_inputfiles[i].c_str());}
+     505             :     std::fprintf(out,"\n");
+     506             :     std::fprintf(out,"kBoltzmann taken as 1, use NATURAL_UNITS in the plumed input\n");
+     507          15 :     if(diff_input_coeffs) {std::fprintf(out,"using different coefficients for each replica\n");}
+     508             :   }
+     509             : 
+     510             : 
+     511          39 :   plumed=Tools::make_unique<PLMD::PlumedMain>();
+     512             : 
+     513             : 
+     514             : 
+     515          39 :   if(plumed) {
+     516          39 :     int s=sizeof(double);
+     517          39 :     plumed->cmd("setRealPrecision",&s);
+     518          39 :     if(replicas>1) {
+     519          31 :       if (Communicator::initialized()) {
+     520          62 :         plumed->cmd("GREX setMPIIntracomm",&intra.Get_comm());
+     521          31 :         if (intra.Get_rank()==0) {
+     522          62 :           plumed->cmd("GREX setMPIIntercomm",&inter.Get_comm());
+     523             :         }
+     524          31 :         plumed->cmd("GREX init");
+     525          62 :         plumed->cmd("setMPIComm",&intra.Get_comm());
+     526             :       } else {
+     527           0 :         error("More than 1 replica but no MPI");
+     528             :       }
+     529             :     } else {
+     530          10 :       if(Communicator::initialized()) plumed->cmd("setMPIComm",&pc.Get_comm());
+     531             :     }
+     532             :   }
+     533             : 
+     534          39 :   std::string plumed_logfile = "plumed.log";
+     535          39 :   std::string stats_filename = "stats.out";
+     536          39 :   std::string plumed_input = plumed_inputfiles[0];
+     537          39 :   if(inter.Get_size()>1) {
+     538             :     std::string suffix;
+     539          31 :     Tools::convert(inter.Get_rank(),suffix);
+     540          62 :     plumed_logfile = FileBase::appendSuffix(plumed_logfile,"."+suffix);
+     541          62 :     stats_filename = FileBase::appendSuffix(stats_filename,"."+suffix);
+     542          31 :     if(plumed_inputfiles.size()>1) {
+     543           2 :       plumed_input = plumed_inputfiles[inter.Get_rank()];
+     544             :     }
+     545             :   }
+     546             : 
+     547          39 :   if(plumed) {
+     548          39 :     int natoms=1;
+     549          39 :     plumed->cmd("setNatoms",&natoms);
+     550          39 :     plumed->cmd("setNoVirial");
+     551          39 :     plumed->cmd("setMDEngine","mdrunner_linearexpansion");
+     552          39 :     plumed->cmd("setTimestep",&tstep);
+     553          39 :     plumed->cmd("setPlumedDat",plumed_input.c_str());
+     554          39 :     plumed->cmd("setLogFile",plumed_logfile.c_str());
+     555          39 :     plumed->cmd("setKbT",&temp);
+     556          39 :     double energyunits=1.0;
+     557          39 :     plumed->cmd("setMDEnergyUnits",&energyunits);
+     558          39 :     plumed->cmd("init");
+     559             :   }
+     560             : 
+     561             :   // Setup random number generator
+     562          39 :   random.setSeed(seed);
+     563             : 
+     564          39 :   double potential, therm_eng=0; std::vector<double> masses(1,1);
+     565          39 :   std::vector<Vector> positions(1), velocities(1), forces(1);
+     566          85 :   for(unsigned int k=0; k<dim; k++) {
+     567          46 :     positions[0][k] = initPos[inter.Get_rank()][k];
+     568          46 :     if(periodic[k]) {
+     569           4 :       positions[0][k] = positions[0][k] - floor((positions[0][k]-interval_min[k])/interval_range[k])*interval_range[k];
+     570             :     }
+     571             :     else {
+     572          42 :       if(positions[0][k]>interval_max[k]) {positions[0][k]=interval_max[k];}
+     573          42 :       if(positions[0][k]<interval_min[k]) {positions[0][k]=interval_min[k];}
+     574             :     }
+     575             :   }
+     576             : 
+     577             : 
+     578          85 :   for(unsigned k=0; k<dim; ++k) {
+     579          46 :     velocities[0][k]=random.Gaussian() * sqrt( temp );
+     580             :   }
+     581             : 
+     582          39 :   potential=calc_energy(positions,forces); double ttt=calc_temp(velocities);
+     583             : 
+     584          39 :   FILE* fp=fopen(stats_filename.c_str(),"w+");
+     585             :   // call fclose when fp_deleter goes out of scope
+     586             :   std::unique_ptr<FILE,decltype(deleter)> fp_deleter(fp,deleter);
+     587             : 
+     588          39 :   double conserved = potential+1.5*ttt+therm_eng;
+     589             :   //std::fprintf(fp,"%d %f %f %f %f %f %f %f %f \n", 0, 0., positions[0][0], positions[0][1], positions[0][2], conserved, ttt, potential, therm_eng );
+     590          39 :   if( intra.Get_rank()==0 ) {
+     591          38 :     std::fprintf(fp,"%d %f %f %f %f %f %f %f %f \n", 0, 0., positions[0][0], positions[0][1], positions[0][2], conserved, ttt, potential, therm_eng );
+     592             :   }
+     593             : 
+     594          39 :   if(plumed) {
+     595          39 :     long long unsigned int step_tmp = 0;
+     596          39 :     plumed->cmd("setStepLongLong",&step_tmp);
+     597          39 :     plumed->cmd("setMasses",&masses[0]);
+     598          39 :     plumed->cmd("setForces",&forces[0][0]);
+     599          39 :     plumed->cmd("setEnergy",&potential);
+     600          39 :     plumed->cmd("setPositions",&positions[0][0]);
+     601          39 :     plumed->cmd("calc");
+     602             :   }
+     603             : 
+     604        3939 :   for(long long unsigned int istep=0; istep<nsteps; ++istep) {
+     605             :     //if( istep%20==0 && pc.Get_rank()==0 ) printf("Doing step %llu\n",istep);
+     606             : 
+     607             :     // Langevin thermostat
+     608        3900 :     double lscale=exp(-0.5*tstep*friction); //exp(-0.5*tstep/friction);
+     609        3900 :     double lrand=sqrt((1.-lscale*lscale)*temp);
+     610        8500 :     for(unsigned k=0; k<dim; ++k) {
+     611        4600 :       therm_eng=therm_eng+0.5*velocities[0][k]*velocities[0][k];
+     612        4600 :       velocities[0][k]=lscale*velocities[0][k]+lrand*random.Gaussian();
+     613        4600 :       therm_eng=therm_eng-0.5*velocities[0][k]*velocities[0][k];
+     614             :     }
+     615             : 
+     616             :     // First step of velocity verlet
+     617        8500 :     for(unsigned k=0; k<dim; ++k) {
+     618        4600 :       velocities[0][k] = velocities[0][k] + 0.5*tstep*forces[0][k];
+     619        4600 :       positions[0][k] = positions[0][k] + tstep*velocities[0][k];
+     620             : 
+     621        4600 :       if(periodic[k]) {
+     622         400 :         positions[0][k] = positions[0][k] - floor((positions[0][k]-interval_min[k])/interval_range[k])*interval_range[k];
+     623             :       }
+     624             :       else {
+     625        4200 :         if(positions[0][k]>interval_max[k]) {
+     626           7 :           positions[0][k]=interval_max[k];
+     627           7 :           velocities[0][k]=-std::abs(velocities[0][k]);
+     628             :         }
+     629        4200 :         if(positions[0][k]<interval_min[k]) {
+     630           2 :           positions[0][k]=interval_min[k];
+     631           2 :           velocities[0][k]=-std::abs(velocities[0][k]);
+     632             :         }
+     633             :       }
+     634             :     }
+     635             : 
+     636        3900 :     potential=calc_energy(positions,forces);
+     637             : 
+     638        3900 :     if(plumed) {
+     639        3900 :       long long unsigned int istepplusone=istep+1;
+     640        3900 :       plumedWantsToStop=0;
+     641        3900 :       plumed->cmd("setStepLongLong",&istepplusone);
+     642        3900 :       plumed->cmd("setMasses",&masses[0]);
+     643        3900 :       plumed->cmd("setForces",&forces[0][0]);
+     644        3900 :       plumed->cmd("setEnergy",&potential);
+     645        3900 :       plumed->cmd("setPositions",&positions[0][0]);
+     646        3900 :       plumed->cmd("setStopFlag",&plumedWantsToStop);
+     647        3900 :       plumed->cmd("calc");
+     648             :       //if(istep%2000==0) plumed->cmd("writeCheckPointFile");
+     649        3900 :       if(plumedWantsToStop) nsteps=istep;
+     650             :     }
+     651             : 
+     652             :     // Second step of velocity verlet
+     653        8500 :     for(unsigned k=0; k<dim; ++k) {
+     654        4600 :       velocities[0][k] = velocities[0][k] + 0.5*tstep*forces[0][k];
+     655             :     }
+     656             : 
+     657             :     // Langevin thermostat
+     658        3900 :     lscale=exp(-0.5*tstep*friction); //exp(-0.5*tstep/friction);
+     659        3900 :     lrand=sqrt((1.-lscale*lscale)*temp);
+     660        8500 :     for(unsigned k=0; k<dim; ++k) {
+     661        4600 :       therm_eng=therm_eng+0.5*velocities[0][k]*velocities[0][k];
+     662        4600 :       velocities[0][k]=lscale*velocities[0][k]+lrand*random.Gaussian();
+     663        4600 :       therm_eng=therm_eng-0.5*velocities[0][k]*velocities[0][k];
+     664             :     }
+     665             : 
+     666             :     // Print everything
+     667        3900 :     ttt = calc_temp( velocities );
+     668        3900 :     conserved = potential+1.5*ttt+therm_eng;
+     669        3900 :     if( (intra.Get_rank()==0) && ((istep % stepWrite)==0) ) {
+     670          38 :       std::fprintf(fp,"%llu %f %f %f %f %f %f %f %f \n", istep, istep*tstep, positions[0][0], positions[0][1], positions[0][2], conserved, ttt, potential, therm_eng );
+     671             :     }
+     672             :   }
+     673             : 
+     674             :   //printf("Rank: %d, Size: %d \n", pc.Get_rank(), pc.Get_size() );
+     675             :   //printf("Rank: %d, Size: %d, MultiSimCommRank: %d, MultiSimCommSize: %d \n", pc.Get_rank(), pc.Get_size(), multi_sim_comm.Get_rank(), multi_sim_comm.Get_size() );
+     676             : 
+     677             :   return 0;
+     678         395 : }
+     679             : 
+     680             : }
+     681             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/Opt_Adam.cpp.func-sort-c.html b/coverage/ves/Opt_Adam.cpp.func-sort-c.html new file mode 100644 index 000000000000..0a18ade32a70 --- /dev/null +++ b/coverage/ves/Opt_Adam.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - ves/Opt_Adam.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - Opt_Adam.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:677293.1 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves8Opt_AdamC2ERKNS_13ActionOptionsE0
_ZN4PLMD3ves8Opt_AdamC1ERKNS_13ActionOptionsE2
_ZN4PLMD3ves8Opt_Adam16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD3ves8Opt_Adam12coeffsUpdateEj20
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/Opt_Adam.cpp.func.html b/coverage/ves/Opt_Adam.cpp.func.html new file mode 100644 index 000000000000..36351add9a24 --- /dev/null +++ b/coverage/ves/Opt_Adam.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - ves/Opt_Adam.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - Opt_Adam.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:677293.1 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves8Opt_Adam12coeffsUpdateEj20
_ZN4PLMD3ves8Opt_Adam16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD3ves8Opt_AdamC1ERKNS_13ActionOptionsE2
_ZN4PLMD3ves8Opt_AdamC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/Opt_Adam.cpp.gcov.html b/coverage/ves/Opt_Adam.cpp.gcov.html new file mode 100644 index 000000000000..9d2c58362315 --- /dev/null +++ b/coverage/ves/Opt_Adam.cpp.gcov.html @@ -0,0 +1,273 @@ + + + + + + + + LCOV - plumed test coverage - ves/Opt_Adam.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - Opt_Adam.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:677293.1 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "Optimizer.h"
+      24             : #include "CoeffsVector.h"
+      25             : 
+      26             : #include "core/ActionRegister.h"
+      27             : #include "core/ActionSet.h"
+      28             : 
+      29             : 
+      30             : namespace PLMD {
+      31             : namespace ves {
+      32             : 
+      33             : //+PLUMEDOC VES_OPTIMIZER OPT_ADAM
+      34             : /*
+      35             : Adaptive moment estimation (ADAM) optimizer.
+      36             : 
+      37             : \attention
+      38             : __This optimizer is still experimental and not fully documented. The syntax might change. Restarting does not work. We recommend to use the averaged stochastic gradient decent optimizer (\ref OPT_AVERAGED_SGD) for now__.
+      39             : 
+      40             : 
+      41             : \par Examples
+      42             : 
+      43             : */
+      44             : //+ENDPLUMEDOC
+      45             : 
+      46             : class Opt_Adam: public Optimizer {
+      47             : private:
+      48             :   unsigned int time_;
+      49             :   double beta_1_;
+      50             :   double beta_2_;
+      51             :   double epsilon_;
+      52             :   double one_minus_weight_decay_;
+      53             :   bool amsgrad_;
+      54             :   bool adamw_;
+      55             :   // 1st gradient moment uses the "AuxCoeffs", so only 2nd moment needs new CoeffVectors
+      56             :   std::vector<std::unique_ptr<CoeffsVector>> var_coeffs_pntrs_;
+      57             :   // used only for AMSGrad variant
+      58             :   std::vector<std::unique_ptr<CoeffsVector>> varmax_coeffs_pntrs_;
+      59             : protected:
+      60             :   CoeffsVector& VarCoeffs(const unsigned int coeffs_id = 0) const;
+      61             :   CoeffsVector& VarmaxCoeffs(const unsigned int coeffs_id = 0) const;
+      62             : public:
+      63             :   static void registerKeywords(Keywords&);
+      64             :   explicit Opt_Adam(const ActionOptions&);
+      65             :   void coeffsUpdate(const unsigned int c_id = 0) override;
+      66             : };
+      67             : 
+      68             : inline
+      69             : CoeffsVector& Opt_Adam::VarCoeffs(const unsigned int coeffs_id) const {return *var_coeffs_pntrs_[coeffs_id];}
+      70             : 
+      71             : inline
+      72             : CoeffsVector& Opt_Adam::VarmaxCoeffs(const unsigned int coeffs_id) const {return *varmax_coeffs_pntrs_[coeffs_id];}
+      73             : 
+      74             : 
+      75             : PLUMED_REGISTER_ACTION(Opt_Adam,"OPT_ADAM")
+      76             : 
+      77             : 
+      78           4 : void Opt_Adam::registerKeywords(Keywords& keys) {
+      79           4 :   Optimizer::registerKeywords(keys);
+      80           4 :   Optimizer::useFixedStepSizeKeywords(keys);
+      81           4 :   Optimizer::useMultipleWalkersKeywords(keys);
+      82           4 :   Optimizer::useMaskKeywords(keys);
+      83           4 :   Optimizer::useDynamicTargetDistributionKeywords(keys);
+      84           8 :   keys.add("optional","BETA_1","Parameter for the first moment estimate. Defaults to 0.9");
+      85           8 :   keys.add("optional","BETA_2","Parameter for the second moment estimate. Defaults to 0.999");
+      86           8 :   keys.add("optional","EPSILON","Small parameter to avoid division by zero. Defaults to 1e-8");
+      87           8 :   keys.add("optional","ADAMW_WEIGHT_DECAY","Weight decay parameter for the AdamW variant. Defaults to 0");
+      88           8 :   keys.addFlag("AMSGRAD", false, "Use the AMSGrad variant");
+      89           4 : }
+      90             : 
+      91             : 
+      92           2 : Opt_Adam::Opt_Adam(const ActionOptions&ao):
+      93             :   PLUMED_VES_OPTIMIZER_INIT(ao),
+      94           2 :   time_(0),
+      95           2 :   beta_1_(0.9),
+      96           2 :   beta_2_(0.999),
+      97           2 :   epsilon_(0.00000001),
+      98           2 :   one_minus_weight_decay_(1.0),
+      99           2 :   amsgrad_(false),
+     100           2 :   adamw_(false),
+     101           2 :   var_coeffs_pntrs_(0)
+     102             : {
+     103             :   // add citation and print it to log
+     104           2 :   log << "  Adam type stochastic gradient decent\n";
+     105           2 :   parseFlag("AMSGRAD",amsgrad_);
+     106           2 :   if (amsgrad_) {
+     107           1 :     log << "  Using the AMSGrad variant of the Adam algorithm, see and cite\n";
+     108             :   }
+     109             : 
+     110           2 :   double tmp_weight_decay = 0.0;
+     111           2 :   parse("ADAMW_WEIGHT_DECAY",tmp_weight_decay);
+     112           2 :   if (tmp_weight_decay != 0.0) {
+     113           0 :     adamw_ = true;
+     114           0 :     log << "  Using the AdamW variant (Adam with weight decay), see and cite\n";
+     115           0 :     one_minus_weight_decay_ = 1 - tmp_weight_decay;
+     116           0 :     log << "    weight decay parameter: " << tmp_weight_decay << "\n";
+     117             :   }
+     118             : 
+     119           2 :   log << "  Adam parameters:\n";
+     120           2 :   parse("BETA_1",beta_1_);
+     121           2 :   plumed_massert(beta_1_ > 0 && beta_1_ <= 1, "BETA_1 must be between 0 and 1");
+     122           2 :   log << "    beta_1: " << beta_1_ << "\n";
+     123             : 
+     124           2 :   parse("BETA_2",beta_2_);
+     125           2 :   plumed_massert(beta_2_ > 0 && beta_2_ <= 1, "BETA_2 must be between 0 and 1");
+     126           2 :   log << "    beta_2: " << beta_2_ << "\n";
+     127             : 
+     128           2 :   parse("EPSILON",epsilon_);
+     129           2 :   plumed_massert(epsilon_ > 0 && epsilon_ <= 1, "EPSILON must be between 0 and 1");
+     130           2 :   log << "    epsilon: " << epsilon_ << "\n";
+     131             : 
+     132             : 
+     133             :   // set up the coeff vector for the 2nd moment of the gradient (variance)
+     134           4 :   for (unsigned i = 0; i < numberOfCoeffsSets(); ++i) {
+     135           2 :     var_coeffs_pntrs_.emplace_back(std::unique_ptr<CoeffsVector>(new CoeffsVector(Coeffs(i))));
+     136           4 :     VarCoeffs(i).replaceLabelString("coeffs","grad_var");
+     137           2 :     VarCoeffs(i).setAllValuesToZero(); // can Coeffs(i) even be non-zero at this point?
+     138             : 
+     139             :     // add second set of coefficients to store the maximum values of the 2nd moment
+     140           2 :     if (amsgrad_) {
+     141           1 :       varmax_coeffs_pntrs_.emplace_back(std::unique_ptr<CoeffsVector>(new CoeffsVector(VarCoeffs(i))));
+     142           2 :       VarmaxCoeffs(i).replaceLabelString("coeffs","grad_varmax");
+     143             :     }
+     144             : 
+     145             :     // also rename the Coeffs used for the mean of the gradient
+     146           4 :     AuxCoeffs(i).replaceLabelString("coeffs","grad_mean");
+     147             :   }
+     148             : 
+     149           2 :   checkRead();
+     150           2 : }
+     151             : 
+     152             : 
+     153          20 : void Opt_Adam::coeffsUpdate(const unsigned int c_id) {
+     154          20 :   time_++;
+     155             :   // AuxCoeffs is used for first moment (mean)
+     156          20 :   AuxCoeffs(c_id) *= beta_1_;
+     157          20 :   AuxCoeffs(c_id) += (1 - beta_1_ ) * Gradient(c_id) * CoeffsMask(c_id);
+     158          20 :   VarCoeffs(c_id) *= beta_2_;
+     159          20 :   VarCoeffs(c_id) += (1 - beta_2_ ) * Gradient(c_id) * Gradient(c_id) * CoeffsMask(c_id);
+     160             : 
+     161          20 :   if (amsgrad_) {
+     162         120 :     for (size_t i = 0; i< VarCoeffs(c_id).getSize(); ++i) {
+     163         110 :       if (VarCoeffs(c_id).getValue(i) > VarmaxCoeffs(c_id).getValue(i)) {
+     164          95 :         VarmaxCoeffs(c_id)[i] = VarCoeffs(c_id).getValue(i);
+     165             :       }
+     166             :     }
+     167             :   }
+     168             : 
+     169             :   // store sqrt of VarCoeffs in vector, easier than writing a CoeffsVector::sqrt() function
+     170             :   // also directly add epsilon and invert to multiply with the Coeffs in last step
+     171             :   std::vector<double> var_coeffs_sqrt;
+     172          20 :   if (!amsgrad_) {
+     173         120 :     for (size_t i = 0; i< VarCoeffs(c_id).getSize(); ++i) {
+     174         110 :       var_coeffs_sqrt.push_back(1 / (sqrt(VarCoeffs(c_id).getValue(i)) + epsilon));
+     175             :     }
+     176             :   }
+     177             :   else { // use VarmaxCoffs instead of VarCoeffs
+     178         120 :     for (size_t i = 0; i< VarmaxCoeffs(c_id).getSize(); ++i) {
+     179         110 :       var_coeffs_sqrt.push_back(1 / (sqrt(VarmaxCoeffs(c_id).getValue(i)) + epsilon));
+     180             :     }
+     181             :   }
+     182             : 
+     183             :   // bias correction
+     184          20 :   double scalefactor = StepSize(c_id) * sqrt(1 - pow(beta_2_, time_)) / (1 - pow(beta_1_, time_));
+     185             : 
+     186          20 :   if (adamw_) { // check is not necessary but probably faster than always multiplying by 1
+     187           0 :     Coeffs(c_id) *= one_minus_weight_decay_ * CoeffsMask(c_id);
+     188             :   }
+     189             : 
+     190             :   // coeff update
+     191          20 :   Coeffs(c_id) -= scalefactor * AuxCoeffs(c_id) * var_coeffs_sqrt * CoeffsMask(c_id);
+     192          20 : }
+     193             : 
+     194             : 
+     195             : }
+     196             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/Opt_BachAveragedSGD.cpp.func-sort-c.html b/coverage/ves/Opt_BachAveragedSGD.cpp.func-sort-c.html new file mode 100644 index 000000000000..8ce487ac83a3 --- /dev/null +++ b/coverage/ves/Opt_BachAveragedSGD.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - ves/Opt_BachAveragedSGD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - Opt_BachAveragedSGD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:596295.2 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves19Opt_BachAveragedSGDC2ERKNS_13ActionOptionsE0
_ZN4PLMD3ves19Opt_BachAveragedSGDC1ERKNS_13ActionOptionsE75
_ZN4PLMD3ves19Opt_BachAveragedSGD16registerKeywordsERNS_8KeywordsE77
_ZN4PLMD3ves19Opt_BachAveragedSGD12coeffsUpdateEj22675
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/Opt_BachAveragedSGD.cpp.func.html b/coverage/ves/Opt_BachAveragedSGD.cpp.func.html new file mode 100644 index 000000000000..cc4ff9c74db3 --- /dev/null +++ b/coverage/ves/Opt_BachAveragedSGD.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - ves/Opt_BachAveragedSGD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - Opt_BachAveragedSGD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:596295.2 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves19Opt_BachAveragedSGD12coeffsUpdateEj22675
_ZN4PLMD3ves19Opt_BachAveragedSGD16registerKeywordsERNS_8KeywordsE77
_ZN4PLMD3ves19Opt_BachAveragedSGDC1ERKNS_13ActionOptionsE75
_ZN4PLMD3ves19Opt_BachAveragedSGDC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/Opt_BachAveragedSGD.cpp.gcov.html b/coverage/ves/Opt_BachAveragedSGD.cpp.gcov.html new file mode 100644 index 000000000000..a9550bb84aed --- /dev/null +++ b/coverage/ves/Opt_BachAveragedSGD.cpp.gcov.html @@ -0,0 +1,379 @@ + + + + + + + + LCOV - plumed test coverage - ves/Opt_BachAveragedSGD.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - Opt_BachAveragedSGD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:596295.2 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "Optimizer.h"
+      24             : #include "CoeffsVector.h"
+      25             : #include "CoeffsMatrix.h"
+      26             : 
+      27             : #include "core/ActionRegister.h"
+      28             : #include "core/PlumedMain.h"
+      29             : 
+      30             : 
+      31             : 
+      32             : namespace PLMD {
+      33             : namespace ves {
+      34             : 
+      35             : //+PLUMEDOC VES_OPTIMIZER OPT_AVERAGED_SGD
+      36             : /*
+      37             : Averaged stochastic gradient decent with fixed step size.
+      38             : 
+      39             : \par Algorithm
+      40             : 
+      41             : This optimizer updates the coefficients according to the averaged stochastic gradient decent algorithm described in ref \cite Bach-NIPS-2013. This algorithm considers two sets of coefficients, the so-called instantaneous coefficients that are updated according to the recursion formula given by
+      42             : \f[
+      43             : \boldsymbol{\alpha}^{(n+1)} = \boldsymbol{\alpha}^{(n)} -
+      44             : \mu \left[
+      45             : \nabla \Omega(\bar{\boldsymbol{\alpha}}^{(n)}) +
+      46             : \mathbf{H}(\bar{\boldsymbol{\alpha}}^{(n)})
+      47             : [\boldsymbol{\alpha}^{(n)}-\bar{\boldsymbol{\alpha}}^{(n)}]
+      48             : \right],
+      49             : \f]
+      50             : where \f$\mu\f$ is a fixed step size and the gradient \f$ \nabla\Omega(\bar{\boldsymbol{\alpha}}^{(n)})\f$ and the Hessian \f$\mathbf{H}(\bar{\boldsymbol{\alpha}}^{(n)})\f$ depend on the averaged coefficients defined as
+      51             : \f[
+      52             : \bar{\boldsymbol{\alpha}}^{(n)} = \frac{1}{n+1} \sum_{k=0}^{n} \boldsymbol{\alpha}^{(k)}.
+      53             : \f]
+      54             : This means that the bias acting on the system depends on the averaged coefficients \f$\bar{\boldsymbol{\alpha}}^{(n)}\f$ which leads to a smooth convergence of the bias and the estimated free energy surface. Furthermore, this allows for a rather short sampling time for each iteration, for classical MD simulations typical sampling times are on the order of few ps (around 1000-4000 MD steps).
+      55             : 
+      56             : Currently it is only supported to employ the diagonal part of the Hessian which is generally sufficient. Support for employing the full Hessian will be added later on.
+      57             : 
+      58             : The VES bias that is to be optimized should be specified using the
+      59             : BIAS keyword.
+      60             : The fixed step size \f$\mu\f$ is given using the STEPSIZE keyword.
+      61             : The frequency of updating the coefficients is given using the
+      62             : STRIDE keyword where the value is given in the number of MD steps.
+      63             : For example, if the MD time step is 0.02 ps and STRIDE=2000 will the
+      64             : coefficients be updated every 4 ps.
+      65             : The coefficients will be outputted to the file given by the
+      66             : COEFFS_FILE keyword. How often the coefficients are written
+      67             : to this file is controlled by the COEFFS_OUTPUT keyword.
+      68             : 
+      69             : If the VES bias employs a dynamic target distribution that needs to be
+      70             : iteratively updated (e.g. \ref TD_WELLTEMPERED) \cite Valsson-JCTC-2015, you will need to specify
+      71             : the stride for updating the target distribution by using
+      72             : the TARGETDIST_STRIDE keyword where the stride
+      73             : is given in terms coefficient iterations. For example if the
+      74             : MD time step is 0.02 ps and STRIDE=1000, such that the coefficients
+      75             : are updated every 2 ps, will TARGETDIST_STRIDE=500 mean that the
+      76             : target distribution will be updated every 1000 ps.
+      77             : 
+      78             : The output of the free energy surfaces and biases is controlled by the FES_OUTPUT and the BIAS_OUTPUT
+      79             : keywords. It is also possible to output one-dimensional projections of the free energy surfaces
+      80             : by using the FES_PROJ_OUTPUT keyword but for that to work you will need to select
+      81             : for which argument to do the projections by using the numbered PROJ_ARG keyword in
+      82             : the VES bias that is optimized.
+      83             : You can also output dynamic target distributions by using the
+      84             : TARGETDIST_OUTPUT and TARGETDIST_PROJ_OUTPUT keywords.
+      85             : 
+      86             : It is possible to start the optimization from some initial set of
+      87             : coefficients that have been previously obtained by using the INITIAL_COEFFS
+      88             : keyword.
+      89             : 
+      90             : When restarting simulations it should be sufficient to put the \ref RESTART action
+      91             : in the beginning of the input files (or some MD codes the PLUMED should automatically
+      92             : detect if it is a restart run) and keep the same input as before The restarting of
+      93             : the optimization should be automatic as the optimizer will then read in the
+      94             : coefficients from the file given in COEFFS_FILE. For dynamic target
+      95             : distribution the code will also read in the final target distribution from the
+      96             : previous run (which is always outputted even if the TARGETDIST_OUTPUT keyword
+      97             : is not used).
+      98             : 
+      99             : This optimizer supports the usage of multiple walkers where different copies of the system share the same bias potential (i.e. coefficients) and cooperatively sample the averages needed for the gradient and Hessian. This can significantly help with convergence in difficult cases. It is of course best to start the different copies from different positions in CV space. To activate this option you just need to add the MULTIPLE_WALKERS flag. Note that this is only supported if the MD code support running multiple replicas connected via MPI.
+     100             : 
+     101             : The optimizer supports the usage of a so-called mask file that can be used to employ different step sizes for different coefficients and/or deactivate the optimization of certain coefficients (by putting values of 0.0). The mask file is read in by using the MASK_FILE keyword and should be in the same format as the coefficient file. It is possible to generate a template mask file by using the OUTPUT_MASK_FILE keyword.
+     102             : 
+     103             : \par Examples
+     104             : 
+     105             : In the following input we employ an averaged stochastic gradient decent with a
+     106             : fixed step size of 1.0 and update the coefficient every 1000 MD steps
+     107             : (e.g. every 2 ps if the MD time step is 0.02 ps). The coefficient are outputted
+     108             : to the coefficients.data every 50 iterations while the FES and bias is outputted
+     109             : to files every 500 iterations (e.g. every 1000 ps).
+     110             : \plumedfile
+     111             : phi:   TORSION ATOMS=5,7,9,15
+     112             : 
+     113             : bf1: BF_FOURIER ORDER=5 MINIMUM=-pi MAXIMUM=pi
+     114             : 
+     115             : VES_LINEAR_EXPANSION ...
+     116             :  ARG=phi
+     117             :  BASIS_FUNCTIONS=bf1
+     118             :  LABEL=ves1
+     119             :  TEMP=300.0
+     120             :  GRID_BINS=100
+     121             : ... VES_LINEAR_EXPANSION
+     122             : 
+     123             : OPT_AVERAGED_SGD ...
+     124             :   BIAS=ves1
+     125             :   STRIDE=1000
+     126             :   LABEL=o1
+     127             :   STEPSIZE=1.0
+     128             :   COEFFS_FILE=coefficients.data
+     129             :   COEFFS_OUTPUT=50
+     130             :   FES_OUTPUT=500
+     131             :   BIAS_OUTPUT=500
+     132             : ... OPT_AVERAGED_SGD
+     133             : \endplumedfile
+     134             : 
+     135             : 
+     136             : In the following example we employ a well-tempered target distribution that
+     137             : is updated every 500 iterations (e.g. every 1000 ps). The target distribution is
+     138             : also output to a file every 2000 iterations (the TARGETDIST_OUTPUT keyword).
+     139             : Here we also employ MULTIPLE_WALKERS flag to enable the usage of
+     140             : multiple walkers.
+     141             : \plumedfile
+     142             : #SETTINGS NREPLICAS=2
+     143             : phi:   TORSION ATOMS=5,7,9,15
+     144             : psi:   TORSION ATOMS=7,9,15,17
+     145             : 
+     146             : bf1: BF_FOURIER ORDER=5 MINIMUM=-pi MAXIMUM=pi
+     147             : bf2: BF_FOURIER ORDER=4 MINIMUM=-pi MAXIMUM=pi
+     148             : 
+     149             : td1: TD_WELLTEMPERED BIASFACTOR=10
+     150             : 
+     151             : VES_LINEAR_EXPANSION ...
+     152             :  ARG=phi,psi
+     153             :  BASIS_FUNCTIONS=bf1,bf2
+     154             :  LABEL=ves1
+     155             :  TEMP=300.0
+     156             :  GRID_BINS=100,100
+     157             :  TARGET_DISTRIBUTION=td1
+     158             :  PROJ_ARG1=phi
+     159             :  PROJ_ARG2=psi
+     160             : ... VES_LINEAR_EXPANSION
+     161             : 
+     162             : OPT_AVERAGED_SGD ...
+     163             :   BIAS=ves1
+     164             :   STRIDE=1000
+     165             :   LABEL=o1
+     166             :   STEPSIZE=1.0
+     167             :   MULTIPLE_WALKERS
+     168             :   COEFFS_FILE=coefficients.data
+     169             :   COEFFS_OUTPUT=50
+     170             :   FES_OUTPUT=500
+     171             :   FES_PROJ_OUTPUT=500
+     172             :   BIAS_OUTPUT=500
+     173             :   TARGETDIST_STRIDE=500
+     174             :   TARGETDIST_OUTPUT=2000
+     175             : ... OPT_AVERAGED_SGD
+     176             : \endplumedfile
+     177             : 
+     178             : 
+     179             : 
+     180             : */
+     181             : //+ENDPLUMEDOC
+     182             : 
+     183             : class Opt_BachAveragedSGD : public Optimizer {
+     184             : private:
+     185             :   std::vector<std::unique_ptr<CoeffsVector>> combinedgradient_pntrs_;
+     186             :   unsigned int combinedgradient_wstride_;
+     187             :   std::vector<std::unique_ptr<OFile>> combinedgradientOFiles_;
+     188             :   double decaying_aver_tau_;
+     189             : private:
+     190          60 :   CoeffsVector& CombinedGradient(const unsigned int c_id) const {return *combinedgradient_pntrs_[c_id];}
+     191             :   double getAverDecay() const;
+     192             : public:
+     193             :   static void registerKeywords(Keywords&);
+     194             :   explicit Opt_BachAveragedSGD(const ActionOptions&);
+     195             :   void coeffsUpdate(const unsigned int c_id = 0) override;
+     196             : };
+     197             : 
+     198             : 
+     199             : PLUMED_REGISTER_ACTION(Opt_BachAveragedSGD,"OPT_AVERAGED_SGD")
+     200             : 
+     201             : 
+     202          77 : void Opt_BachAveragedSGD::registerKeywords(Keywords& keys) {
+     203          77 :   Optimizer::registerKeywords(keys);
+     204          77 :   Optimizer::useFixedStepSizeKeywords(keys);
+     205          77 :   Optimizer::useMultipleWalkersKeywords(keys);
+     206          77 :   Optimizer::useHessianKeywords(keys);
+     207          77 :   Optimizer::useMaskKeywords(keys);
+     208          77 :   Optimizer::useRestartKeywords(keys);
+     209          77 :   Optimizer::useMonitorAverageGradientKeywords(keys);
+     210          77 :   Optimizer::useDynamicTargetDistributionKeywords(keys);
+     211         154 :   keys.add("hidden","COMBINED_GRADIENT_FILE","the name of output file for the combined gradient (gradient + Hessian term)");
+     212         154 :   keys.add("hidden","COMBINED_GRADIENT_OUTPUT","how often the combined gradient should be written to file. This parameter is given as the number of bias iterations. It is by default 100 if COMBINED_GRADIENT_FILE is specficed");
+     213         154 :   keys.add("hidden","COMBINED_GRADIENT_FMT","specify format for combined gradient file(s) (useful for decrease the number of digits in regtests)");
+     214         154 :   keys.add("optional","EXP_DECAYING_AVER","calculate the averaged coefficients using exponentially decaying averaging using the decaying constant given here in the number of iterations");
+     215          77 : }
+     216             : 
+     217             : 
+     218             : 
+     219          75 : Opt_BachAveragedSGD::Opt_BachAveragedSGD(const ActionOptions&ao):
+     220             :   PLUMED_VES_OPTIMIZER_INIT(ao),
+     221          75 :   combinedgradient_wstride_(100),
+     222          75 :   decaying_aver_tau_(0.0)
+     223             : {
+     224          75 :   log.printf("  Averaged stochastic gradient decent, see and cite ");
+     225         150 :   log << plumed.cite("Bach and Moulines, NIPS 26, 773-781 (2013)");
+     226          75 :   log.printf("\n");
+     227          75 :   unsigned int decaying_aver_tau_int=0;
+     228          75 :   parse("EXP_DECAYING_AVER",decaying_aver_tau_int);
+     229          75 :   if(decaying_aver_tau_int>0) {
+     230           2 :     decaying_aver_tau_ = static_cast<double>(decaying_aver_tau_int);
+     231           2 :     log.printf("  Coefficients calculated using an exponentially decaying average with a decaying constant of %u iterations, see and cite ",decaying_aver_tau_int);
+     232           4 :     log << plumed.cite("Invernizzi, Valsson, and Parrinello, Proc. Natl. Acad. Sci. USA 114, 3370-3374 (2017)");
+     233           2 :     log.printf("\n");
+     234             :   }
+     235             :   //
+     236             :   std::vector<std::string> combinedgradient_fnames;
+     237          75 :   parseFilenames("COMBINED_GRADIENT_FILE",combinedgradient_fnames);
+     238         150 :   parse("COMBINED_GRADIENT_OUTPUT",combinedgradient_wstride_);
+     239          75 :   setupOFiles(combinedgradient_fnames,combinedgradientOFiles_,useMultipleWalkers());
+     240          75 :   std::string combinedgradient_fmt="";
+     241         150 :   parse("COMBINED_GRADIENT_FMT",combinedgradient_fmt);
+     242          75 :   if(combinedgradient_fnames.size()>0) {
+     243          12 :     for(unsigned int i=0; i<numberOfCoeffsSets(); i++) {
+     244          12 :       auto combinedgradient_tmp = Tools::make_unique<CoeffsVector>(*getGradientPntrs()[i]);
+     245           6 :       std::string label = getGradientPntrs()[i]->getLabel();
+     246           6 :       if(label.find("gradient")!=std::string::npos) {
+     247          12 :         label.replace(label.find("gradient"), std::string("gradient").length(), "combined_gradient");
+     248             :       }
+     249             :       else {
+     250             :         label += "_combined";
+     251             :       }
+     252           6 :       combinedgradient_tmp->setLabels(label);
+     253           6 :       if(combinedgradient_fmt.size()>0) {
+     254             :         combinedgradient_tmp->setOutputFmt(combinedgradient_fmt);
+     255             :       }
+     256           6 :       combinedgradient_pntrs_.emplace_back(std::move(combinedgradient_tmp));
+     257           6 :     }
+     258             :     //
+     259           6 :     if(numberOfCoeffsSets()==1) {
+     260          12 :       log.printf("  Combined gradient (gradient + Hessian term) will be written out to file %s every %u iterations\n",combinedgradientOFiles_[0]->getPath().c_str(),combinedgradient_wstride_);
+     261             :     }
+     262             :     else {
+     263           0 :       log.printf("  Combined gradient (gradient + Hessian term) will be written out to the following files every %u iterations:\n",combinedgradient_wstride_);
+     264           0 :       for(unsigned int i=0; i<combinedgradientOFiles_.size(); i++) {
+     265           0 :         log.printf("   coefficient set %u: %s\n",i,combinedgradientOFiles_[i]->getPath().c_str());
+     266             :       }
+     267             :     }
+     268             :   }
+     269             :   //
+     270             : 
+     271          75 :   turnOnHessian();
+     272          75 :   checkRead();
+     273          75 : }
+     274             : 
+     275             : 
+     276       22675 : void Opt_BachAveragedSGD::coeffsUpdate(const unsigned int c_id) {
+     277             :   //
+     278       22675 :   if(combinedgradientOFiles_.size()>0 && (getIterationCounter()+1)%combinedgradient_wstride_==0) {
+     279          60 :     CombinedGradient(c_id).setValues( ( Gradient(c_id) + Hessian(c_id)*(AuxCoeffs(c_id)-Coeffs(c_id)) ) );
+     280          60 :     combinedgradient_pntrs_[c_id]->setIterationCounterAndTime(getIterationCounter()+1,getTime());
+     281          60 :     combinedgradient_pntrs_[c_id]->writeToFile(*combinedgradientOFiles_[c_id]);
+     282             :   }
+     283             :   //
+     284             :   double aver_decay = getAverDecay();
+     285       22675 :   AuxCoeffs(c_id) += - StepSize(c_id)*CoeffsMask(c_id) * ( Gradient(c_id) + Hessian(c_id)*(AuxCoeffs(c_id)-Coeffs(c_id)) );
+     286             :   //AuxCoeffs() = AuxCoeffs() - StepSize() * ( Gradient() + Hessian()*(AuxCoeffs()-Coeffs()) );
+     287       22675 :   Coeffs(c_id) += aver_decay * ( AuxCoeffs(c_id)-Coeffs(c_id) );
+     288       22675 : }
+     289             : 
+     290             : 
+     291             : inline
+     292             : double Opt_BachAveragedSGD::getAverDecay() const {
+     293       22675 :   double aver_decay = 1.0 / ( getIterationCounterDbl() + 1.0 );
+     294       22675 :   if(decaying_aver_tau_ > 0.0 && (getIterationCounterDbl() + 1.0) > decaying_aver_tau_) {
+     295          14 :     aver_decay = 1.0 / decaying_aver_tau_;
+     296             :   }
+     297             :   return aver_decay;
+     298             : }
+     299             : 
+     300             : 
+     301             : }
+     302             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/Opt_Dummy.cpp.func-sort-c.html b/coverage/ves/Opt_Dummy.cpp.func-sort-c.html new file mode 100644 index 000000000000..7139f64e8e28 --- /dev/null +++ b/coverage/ves/Opt_Dummy.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - ves/Opt_Dummy.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - Opt_Dummy.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:202195.2 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves9Opt_DummyC2ERKNS_13ActionOptionsE0
_ZN4PLMD3ves9Opt_DummyC1ERKNS_13ActionOptionsE1
_ZN4PLMD3ves9Opt_Dummy16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD3ves9Opt_Dummy12coeffsUpdateEj10
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/Opt_Dummy.cpp.func.html b/coverage/ves/Opt_Dummy.cpp.func.html new file mode 100644 index 000000000000..7f30874a161d --- /dev/null +++ b/coverage/ves/Opt_Dummy.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - ves/Opt_Dummy.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - Opt_Dummy.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:202195.2 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves9Opt_Dummy12coeffsUpdateEj10
_ZN4PLMD3ves9Opt_Dummy16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD3ves9Opt_DummyC1ERKNS_13ActionOptionsE1
_ZN4PLMD3ves9Opt_DummyC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/Opt_Dummy.cpp.gcov.html b/coverage/ves/Opt_Dummy.cpp.gcov.html new file mode 100644 index 000000000000..b65ceb9b9edf --- /dev/null +++ b/coverage/ves/Opt_Dummy.cpp.gcov.html @@ -0,0 +1,198 @@ + + + + + + + + LCOV - plumed test coverage - ves/Opt_Dummy.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - Opt_Dummy.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:202195.2 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "Optimizer.h"
+      24             : #include "CoeffsVector.h"
+      25             : 
+      26             : #include "core/ActionRegister.h"
+      27             : 
+      28             : 
+      29             : namespace PLMD {
+      30             : namespace ves {
+      31             : 
+      32             : //+PLUMEDOC VES_OPTIMIZER OPT_DUMMY
+      33             : /*
+      34             : Dummy optimizer for debugging.
+      35             : 
+      36             : This is dummy optimizer that can be used for debugging. It will not update the
+      37             : coefficients but can be used to monitor the gradient and Hessian for a given
+      38             : VES bias.
+      39             : 
+      40             : \par Examples
+      41             : 
+      42             : In the following input we use the OPT_DUMMY to monitor the gradient and
+      43             : Hessian for a given VES bias every 1 iteration.
+      44             : \plumedfile
+      45             : phi:   TORSION ATOMS=5,7,9,15
+      46             : 
+      47             : bf1: BF_FOURIER ORDER=5 MINIMUM=-pi MAXIMUM=pi
+      48             : 
+      49             : VES_LINEAR_EXPANSION ...
+      50             :  ARG=phi
+      51             :  BASIS_FUNCTIONS=bf1
+      52             :  LABEL=ves1
+      53             :  TEMP=300.0
+      54             :  GRID_BINS=100
+      55             : ... VES_LINEAR_EXPANSION
+      56             : 
+      57             : OPT_DUMMY ...
+      58             :   BIAS=ves1
+      59             :   STRIDE=1000
+      60             :   LABEL=o1
+      61             :   MONITOR_HESSIAN
+      62             :   GRADIENT_FILE=gradient.data
+      63             :   GRADIENT_OUTPUT=1
+      64             :   GRADIENT_FMT=%12.6f
+      65             :   HESSIAN_FILE=hessian.data
+      66             :   HESSIAN_OUTPUT=1
+      67             :   HESSIAN_FMT=%12.6f
+      68             : ... OPT_DUMMY
+      69             : \endplumedfile
+      70             : 
+      71             : */
+      72             : //+ENDPLUMEDOC
+      73             : 
+      74             : 
+      75             : 
+      76             : class Opt_Dummy : public Optimizer {
+      77             : 
+      78             : public:
+      79             :   static void registerKeywords(Keywords&);
+      80             :   explicit Opt_Dummy(const ActionOptions&);
+      81             :   void coeffsUpdate(const unsigned int c_id = 0) override;
+      82             : };
+      83             : 
+      84             : 
+      85             : PLUMED_REGISTER_ACTION(Opt_Dummy,"OPT_DUMMY")
+      86             : 
+      87             : 
+      88           3 : void Opt_Dummy::registerKeywords(Keywords& keys) {
+      89           3 :   Optimizer::registerKeywords(keys);
+      90             :   //
+      91           3 :   Optimizer::useMultipleWalkersKeywords(keys);
+      92           3 :   Optimizer::useHessianKeywords(keys);
+      93           3 :   Optimizer::useMonitorAverageGradientKeywords(keys);
+      94           6 :   keys.addFlag("MONITOR_HESSIAN",false,"also monitor the Hessian");
+      95           3 : }
+      96             : 
+      97             : 
+      98           1 : Opt_Dummy::Opt_Dummy(const ActionOptions&ao):
+      99           1 :   PLUMED_VES_OPTIMIZER_INIT(ao)
+     100             : {
+     101           1 :   log.printf("  fake optimizer that does not update coefficients\n");
+     102           1 :   log.printf("  can be used to monitor gradient and Hessian for debugging purposes\n");
+     103           1 :   bool monitor_hessian = false;
+     104           1 :   parseFlag("MONITOR_HESSIAN",monitor_hessian);
+     105           1 :   if(monitor_hessian) {
+     106           1 :     turnOnHessian();
+     107           1 :     log.printf("  the Hessian will also be monitored\n");
+     108             :   }
+     109             :   else {
+     110           0 :     turnOffHessian();
+     111             :   }
+     112           1 :   turnOffCoeffsOutputFiles();
+     113           1 :   checkRead();
+     114           1 : }
+     115             : 
+     116             : 
+     117          10 : void Opt_Dummy::coeffsUpdate(const unsigned int c_id) {}
+     118             : 
+     119             : 
+     120             : }
+     121             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/Opt_RobbinsMonroSGD.cpp.func-sort-c.html b/coverage/ves/Opt_RobbinsMonroSGD.cpp.func-sort-c.html new file mode 100644 index 000000000000..029013616aba --- /dev/null +++ b/coverage/ves/Opt_RobbinsMonroSGD.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - ves/Opt_RobbinsMonroSGD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - Opt_RobbinsMonroSGD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:232495.8 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves19Opt_RobbinsMonroSGDC2ERKNS_13ActionOptionsE0
_ZN4PLMD3ves19Opt_RobbinsMonroSGDC1ERKNS_13ActionOptionsE1
_ZN4PLMD3ves19Opt_RobbinsMonroSGD16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD3ves19Opt_RobbinsMonroSGD12coeffsUpdateEj10
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/Opt_RobbinsMonroSGD.cpp.func.html b/coverage/ves/Opt_RobbinsMonroSGD.cpp.func.html new file mode 100644 index 000000000000..6bc0fac7b971 --- /dev/null +++ b/coverage/ves/Opt_RobbinsMonroSGD.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - ves/Opt_RobbinsMonroSGD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - Opt_RobbinsMonroSGD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:232495.8 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves19Opt_RobbinsMonroSGD12coeffsUpdateEj10
_ZN4PLMD3ves19Opt_RobbinsMonroSGD16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD3ves19Opt_RobbinsMonroSGDC1ERKNS_13ActionOptionsE1
_ZN4PLMD3ves19Opt_RobbinsMonroSGDC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/Opt_RobbinsMonroSGD.cpp.gcov.html b/coverage/ves/Opt_RobbinsMonroSGD.cpp.gcov.html new file mode 100644 index 000000000000..1eeeeeed3a5b --- /dev/null +++ b/coverage/ves/Opt_RobbinsMonroSGD.cpp.gcov.html @@ -0,0 +1,173 @@ + + + + + + + + LCOV - plumed test coverage - ves/Opt_RobbinsMonroSGD.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - Opt_RobbinsMonroSGD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:232495.8 %
Date:2024-04-19 12:12:35Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "Optimizer.h"
+      24             : #include "CoeffsVector.h"
+      25             : 
+      26             : #include "core/ActionRegister.h"
+      27             : 
+      28             : 
+      29             : namespace PLMD {
+      30             : namespace ves {
+      31             : 
+      32             : //+PLUMEDOC VES_OPTIMIZER OPT_ROBBINS_MONRO_SGD
+      33             : /*
+      34             : Robbins-Monro stochastic gradient decent.
+      35             : 
+      36             : \attention
+      37             : __This optimizer is only included for reference. We recommend to use the averaged stochastic gradient decent optimizer (\ref OPT_AVERAGED_SGD)__.
+      38             : 
+      39             : \par Examples
+      40             : 
+      41             : */
+      42             : //+ENDPLUMEDOC
+      43             : 
+      44             : class Opt_RobbinsMonroSGD : public Optimizer {
+      45             : private:
+      46             :   double decay_constant_;
+      47             : public:
+      48             :   static void registerKeywords(Keywords&);
+      49             :   explicit Opt_RobbinsMonroSGD(const ActionOptions&);
+      50             :   void coeffsUpdate(const unsigned int c_id = 0);
+      51             : };
+      52             : 
+      53             : 
+      54             : PLUMED_REGISTER_ACTION(Opt_RobbinsMonroSGD,"OPT_ROBBINS_MONRO_SGD")
+      55             : 
+      56             : 
+      57           3 : void Opt_RobbinsMonroSGD::registerKeywords(Keywords& keys) {
+      58           3 :   Optimizer::registerKeywords(keys);
+      59           3 :   Optimizer::useDynamicStepSizeKeywords(keys);
+      60           3 :   Optimizer::useMultipleWalkersKeywords(keys);
+      61           3 :   Optimizer::useMaskKeywords(keys);
+      62           3 :   Optimizer::useRestartKeywords(keys);
+      63             :   // Optimizer::useMonitorAveragesKeywords(keys);
+      64           3 :   Optimizer::useDynamicTargetDistributionKeywords(keys);
+      65           6 :   keys.add("optional","DECAY_CONSTANT","the decay constant used for the step size.");
+      66           3 : }
+      67             : 
+      68             : 
+      69           1 : Opt_RobbinsMonroSGD::Opt_RobbinsMonroSGD(const ActionOptions&ao):
+      70             :   PLUMED_VES_OPTIMIZER_INIT(ao),
+      71           1 :   decay_constant_(1.0)
+      72             : {
+      73           1 :   parse("DECAY_CONSTANT",decay_constant_);
+      74           1 :   if(decay_constant_<1.0) {
+      75           0 :     plumed_merror("the value given in DECAY_CONSTANT doesn't make sense, it should be larger than 1.0");
+      76             :   }
+      77           1 :   if(decay_constant_>1.0) {
+      78           1 :     log.printf("  using a decay constant of %f\n",decay_constant_);
+      79             :   }
+      80           1 :   checkRead();
+      81           1 : }
+      82             : 
+      83             : 
+      84          10 : void Opt_RobbinsMonroSGD::coeffsUpdate(const unsigned int c_id) {
+      85             :   // getIterationCounterDbl() gives n-1 as it is updated afterwards.
+      86          10 :   double current_stepsize =  StepSize(c_id) /(1.0 + getIterationCounterDbl()/decay_constant_);
+      87             :   setCurrentStepSize(current_stepsize,c_id);
+      88          10 :   Coeffs(c_id) += - current_stepsize * CoeffsMask(c_id) * Gradient(c_id);
+      89             :   //
+      90          10 :   double aver_decay = 1.0 / ( getIterationCounterDbl() + 1.0 );
+      91          10 :   AuxCoeffs(c_id) += aver_decay * ( Coeffs(c_id)-AuxCoeffs(c_id) );
+      92          10 : }
+      93             : 
+      94             : 
+      95             : }
+      96             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/Optimizer.cpp.func-sort-c.html b/coverage/ves/Optimizer.cpp.func-sort-c.html new file mode 100644 index 000000000000..e160a92bfa76 --- /dev/null +++ b/coverage/ves/Optimizer.cpp.func-sort-c.html @@ -0,0 +1,201 @@ + + + + + + + + LCOV - plumed test coverage - ves/Optimizer.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - Optimizer.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:68276289.5 %
Date:2024-04-19 12:12:35Functions:273284.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves9Optimizer14turnOffHessianEv0
_ZN4PLMD3ves9Optimizer25useReweightFactorKeywordsERNS_8KeywordsE0
_ZN4PLMD3ves9OptimizerC1ERKNS_13ActionOptionsE0
_ZN4PLMD3ves9OptimizerD0Ev0
_ZN4PLMD3ves9OptimizerD1Ev0
_ZN4PLMD3ves9Optimizer24turnOffCoeffsOutputFilesEv1
_ZN4PLMD3ves9Optimizer26useDynamicStepSizeKeywordsERNS_8KeywordsE3
_ZNK4PLMD3ves9Optimizer30writeTargetDistProjOutputFilesEv4
_ZN4PLMD3ves9Optimizer19readCoeffsFromFilesERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EEb14
_ZNK4PLMD3ves9Optimizer23writeFesProjOutputFilesEv17
_ZNK4PLMD3ves9Optimizer26writeTargetDistOutputFilesEv38
_ZNK4PLMD3ves9Optimizer19writeFesOutputFilesEv75
_ZNK4PLMD3ves9Optimizer20writeBiasOutputFilesEv75
_ZN4PLMD3ves9Optimizer13turnOnHessianEv76
_ZN4PLMD3ves9OptimizerC2ERKNS_13ActionOptionsE79
_ZN4PLMD3ves9OptimizerD2Ev79
_ZN4PLMD3ves9Optimizer18useHessianKeywordsERNS_8KeywordsE80
_ZN4PLMD3ves9Optimizer18useRestartKeywordsERNS_8KeywordsE80
_ZN4PLMD3ves9Optimizer33useMonitorAverageGradientKeywordsERNS_8KeywordsE80
_ZN4PLMD3ves9Optimizer24useFixedStepSizeKeywordsERNS_8KeywordsE81
_ZN4PLMD3ves9Optimizer13enableHessianEPNS0_7VesBiasEb82
_ZN4PLMD3ves9Optimizer15useMaskKeywordsERNS_8KeywordsE84
_ZN4PLMD3ves9Optimizer36useDynamicTargetDistributionKeywordsERNS_8KeywordsE84
_ZN4PLMD3ves9Optimizer26addCoeffsSetIDsToFilenamesERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERS8_85
_ZN4PLMD3ves9Optimizer16registerKeywordsERNS_8KeywordsE87
_ZN4PLMD3ves9Optimizer26useMultipleWalkersKeywordsERNS_8KeywordsE87
_ZN4PLMD3ves9Optimizer32setAllCoeffsSetIterationCountersEv93
_ZNK4PLMD3ves9Optimizer22getIterationCounterStrB5cxx11Ei95
_ZN4PLMD3ves9Optimizer11setupOFilesERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERS2_ISt10unique_ptrINS_5OFileESt14default_deleteISD_EESaISG_EEb388
_ZN4PLMD3ves9Optimizer22updateOutputComponentsEv22750
_ZN4PLMD3ves9Optimizer16writeOutputFilesEj22810
_ZN4PLMD3ves9Optimizer6updateEv22879
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/Optimizer.cpp.func.html b/coverage/ves/Optimizer.cpp.func.html new file mode 100644 index 000000000000..df10ca4fa61e --- /dev/null +++ b/coverage/ves/Optimizer.cpp.func.html @@ -0,0 +1,201 @@ + + + + + + + + LCOV - plumed test coverage - ves/Optimizer.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - Optimizer.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:68276289.5 %
Date:2024-04-19 12:12:35Functions:273284.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves9Optimizer11setupOFilesERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERS2_ISt10unique_ptrINS_5OFileESt14default_deleteISD_EESaISG_EEb388
_ZN4PLMD3ves9Optimizer13enableHessianEPNS0_7VesBiasEb82
_ZN4PLMD3ves9Optimizer13turnOnHessianEv76
_ZN4PLMD3ves9Optimizer14turnOffHessianEv0
_ZN4PLMD3ves9Optimizer15useMaskKeywordsERNS_8KeywordsE84
_ZN4PLMD3ves9Optimizer16registerKeywordsERNS_8KeywordsE87
_ZN4PLMD3ves9Optimizer16writeOutputFilesEj22810
_ZN4PLMD3ves9Optimizer18useHessianKeywordsERNS_8KeywordsE80
_ZN4PLMD3ves9Optimizer18useRestartKeywordsERNS_8KeywordsE80
_ZN4PLMD3ves9Optimizer19readCoeffsFromFilesERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EEb14
_ZN4PLMD3ves9Optimizer22updateOutputComponentsEv22750
_ZN4PLMD3ves9Optimizer24turnOffCoeffsOutputFilesEv1
_ZN4PLMD3ves9Optimizer24useFixedStepSizeKeywordsERNS_8KeywordsE81
_ZN4PLMD3ves9Optimizer25useReweightFactorKeywordsERNS_8KeywordsE0
_ZN4PLMD3ves9Optimizer26addCoeffsSetIDsToFilenamesERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERS8_85
_ZN4PLMD3ves9Optimizer26useDynamicStepSizeKeywordsERNS_8KeywordsE3
_ZN4PLMD3ves9Optimizer26useMultipleWalkersKeywordsERNS_8KeywordsE87
_ZN4PLMD3ves9Optimizer32setAllCoeffsSetIterationCountersEv93
_ZN4PLMD3ves9Optimizer33useMonitorAverageGradientKeywordsERNS_8KeywordsE80
_ZN4PLMD3ves9Optimizer36useDynamicTargetDistributionKeywordsERNS_8KeywordsE84
_ZN4PLMD3ves9Optimizer6updateEv22879
_ZN4PLMD3ves9OptimizerC1ERKNS_13ActionOptionsE0
_ZN4PLMD3ves9OptimizerC2ERKNS_13ActionOptionsE79
_ZN4PLMD3ves9OptimizerD0Ev0
_ZN4PLMD3ves9OptimizerD1Ev0
_ZN4PLMD3ves9OptimizerD2Ev79
_ZNK4PLMD3ves9Optimizer19writeFesOutputFilesEv75
_ZNK4PLMD3ves9Optimizer20writeBiasOutputFilesEv75
_ZNK4PLMD3ves9Optimizer22getIterationCounterStrB5cxx11Ei95
_ZNK4PLMD3ves9Optimizer23writeFesProjOutputFilesEv17
_ZNK4PLMD3ves9Optimizer26writeTargetDistOutputFilesEv38
_ZNK4PLMD3ves9Optimizer30writeTargetDistProjOutputFilesEv4
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/Optimizer.cpp.gcov.html b/coverage/ves/Optimizer.cpp.gcov.html new file mode 100644 index 000000000000..0b6d5584fff1 --- /dev/null +++ b/coverage/ves/Optimizer.cpp.gcov.html @@ -0,0 +1,1338 @@ + + + + + + + + LCOV - plumed test coverage - ves/Optimizer.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - Optimizer.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:68276289.5 %
Date:2024-04-19 12:12:35Functions:273284.4 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "Optimizer.h"
+      24             : #include "CoeffsVector.h"
+      25             : #include "CoeffsMatrix.h"
+      26             : #include "VesBias.h"
+      27             : #include "VesTools.h"
+      28             : 
+      29             : #include "tools/Exception.h"
+      30             : #include "core/PlumedMain.h"
+      31             : #include "core/ActionSet.h"
+      32             : #include "tools/Communicator.h"
+      33             : #include "tools/File.h"
+      34             : #include "tools/FileBase.h"
+      35             : 
+      36             : namespace PLMD {
+      37             : namespace ves {
+      38             : 
+      39          79 : Optimizer::Optimizer(const ActionOptions&ao):
+      40             :   Action(ao),
+      41             :   ActionPilot(ao),
+      42             :   ActionWithValue(ao),
+      43         158 :   description_("Undefined"),
+      44          79 :   type_("Undefined"),
+      45          79 :   stepsizes_(0),
+      46          79 :   current_stepsizes(0),
+      47          79 :   fixed_stepsize_(true),
+      48          79 :   iter_counter(0),
+      49          79 :   use_hessian_(false),
+      50          79 :   diagonal_hessian_(true),
+      51          79 :   monitor_instantaneous_gradient_(false),
+      52          79 :   use_mwalkers_mpi_(false),
+      53          79 :   mwalkers_mpi_single_files_(true),
+      54          79 :   dynamic_targetdists_(0),
+      55          79 :   ustride_targetdist_(0),
+      56          79 :   ustride_reweightfactor_(0),
+      57          79 :   coeffssetid_prefix_(""),
+      58          79 :   coeffs_wstride_(100),
+      59          79 :   coeffs_output_fmt_(""),
+      60          79 :   gradient_wstride_(100),
+      61          79 :   gradient_output_fmt_(""),
+      62          79 :   hessian_wstride_(100),
+      63          79 :   hessianOFiles_(0),
+      64          79 :   hessian_output_fmt_(""),
+      65          79 :   targetdist_averages_wstride_(0),
+      66          79 :   targetdist_averages_output_fmt_(""),
+      67          79 :   nbiases_(0),
+      68          79 :   bias_pntrs_(0),
+      69          79 :   ncoeffssets_(0),
+      70          79 :   coeffs_pntrs_(0),
+      71          79 :   gradient_pntrs_(0),
+      72          79 :   hessian_pntrs_(0),
+      73          79 :   targetdist_averages_pntrs_(0),
+      74          79 :   identical_coeffs_shape_(true),
+      75          79 :   bias_output_active_(false),
+      76          79 :   bias_output_stride_(0),
+      77          79 :   fes_output_active_(false),
+      78          79 :   fes_output_stride_(0),
+      79          79 :   fesproj_output_active_(false),
+      80          79 :   fesproj_output_stride_(0),
+      81          79 :   targetdist_output_active_(false),
+      82          79 :   targetdist_output_stride_(0),
+      83          79 :   targetdist_proj_output_active_(false),
+      84          79 :   targetdist_proj_output_stride_(0),
+      85         316 :   isFirstStep(true)
+      86             : {
+      87          79 :   std::vector<std::string> bias_labels(0);
+      88         158 :   parseVector("BIAS",bias_labels);
+      89          79 :   plumed_massert(bias_labels.size()>0,"problem with BIAS keyword");
+      90          79 :   nbiases_ = bias_labels.size();
+      91             :   //
+      92          79 :   std::string error_msg = "";
+      93         158 :   bias_pntrs_ = VesTools::getPointersFromLabels<VesBias*>(bias_labels,plumed.getActionSet(),error_msg);
+      94          79 :   if(error_msg.size()>0) {plumed_merror("Error in keyword BIAS of "+getName()+": "+error_msg);}
+      95             : 
+      96         164 :   for(unsigned int i=0; i<bias_pntrs_.size(); i++) {
+      97          85 :     bias_pntrs_[i]->linkOptimizer(this);
+      98             :     //
+      99          85 :     std::vector<CoeffsVector*> pntrs_coeffs = bias_pntrs_[i]->getCoeffsPntrs();
+     100          85 :     std::vector<CoeffsVector*> pntrs_gradient = bias_pntrs_[i]->getGradientPntrs();
+     101          85 :     std::vector<CoeffsVector*> pntrs_targetdist_averages = bias_pntrs_[i]->getTargetDistAveragesPntrs();
+     102          85 :     plumed_massert(pntrs_coeffs.size()==pntrs_gradient.size(),"something wrong in the coefficients and gradient passed from VES bias");
+     103          85 :     plumed_massert(pntrs_coeffs.size()==pntrs_targetdist_averages.size(),"something wrong in the coefficients and target distribution averages passed from VES bias");
+     104         170 :     for(unsigned int k=0; k<pntrs_coeffs.size(); k++) {
+     105          85 :       plumed_massert(pntrs_coeffs[k] != NULL,"some coefficient is not linked correctly");
+     106          85 :       plumed_massert(pntrs_gradient[k] != NULL,"some gradient is not linked correctly");
+     107          85 :       plumed_massert(pntrs_targetdist_averages[k] != NULL,"some target distribution average is not linked correctly");
+     108             :       pntrs_coeffs[k]->turnOnIterationCounter();
+     109          85 :       coeffs_pntrs_.push_back(pntrs_coeffs[k]);
+     110          85 :       pntrs_gradient[k]->turnOnIterationCounter();
+     111          85 :       gradient_pntrs_.push_back(pntrs_gradient[k]);
+     112          85 :       pntrs_targetdist_averages[k]->turnOnIterationCounter();
+     113          85 :       targetdist_averages_pntrs_.push_back(pntrs_targetdist_averages[k]);
+     114             :       //
+     115          85 :       auto aux_coeffs_tmp = Tools::make_unique<CoeffsVector>(*pntrs_coeffs[k]);
+     116          85 :       std::string aux_label = pntrs_coeffs[k]->getLabel();
+     117          85 :       if(aux_label.find("coeffs")!=std::string::npos) {
+     118         170 :         aux_label.replace(aux_label.find("coeffs"), std::string("coeffs").length(), "aux_coeffs");
+     119             :       }
+     120             :       else {
+     121             :         aux_label += "_aux";
+     122             :       }
+     123          85 :       aux_coeffs_tmp->setLabels(aux_label);
+     124          85 :       aux_coeffs_pntrs_.emplace_back(std::move(aux_coeffs_tmp));
+     125          85 :       AuxCoeffs(i).setValues( Coeffs(i) );
+     126          85 :     }
+     127             :   }
+     128          79 :   ncoeffssets_ = coeffs_pntrs_.size();
+     129          79 :   plumed_massert(aux_coeffs_pntrs_.size()==ncoeffssets_,"problems in linking aux coefficients");
+     130          79 :   plumed_massert(gradient_pntrs_.size()==ncoeffssets_,"problems in linking gradients");
+     131          79 :   setAllCoeffsSetIterationCounters();
+     132             : 
+     133             : 
+     134             :   //
+     135          79 :   identical_coeffs_shape_ = true;
+     136          85 :   for(unsigned int i=1; i<ncoeffssets_; i++) {
+     137           6 :     if(!coeffs_pntrs_[0]->sameShape(*coeffs_pntrs_[i])) {
+     138           0 :       identical_coeffs_shape_ = false;
+     139           0 :       break;
+     140             :     }
+     141             :   }
+     142             :   //
+     143         158 :   if(keywords.exists("STEPSIZE")) {
+     144         154 :     plumed_assert(!keywords.exists("INITIAL_STEPSIZE"));
+     145          77 :     fixed_stepsize_=true;
+     146          77 :     parseMultipleValues("STEPSIZE",stepsizes_);
+     147          77 :     setCurrentStepSizes(stepsizes_);
+     148             :   }
+     149         158 :   if(keywords.exists("INITIAL_STEPSIZE")) {
+     150           2 :     plumed_assert(!keywords.exists("STEPSIZE"));
+     151           1 :     fixed_stepsize_=false;
+     152           1 :     parseMultipleValues("INITIAL_STEPSIZE",stepsizes_);
+     153           1 :     setCurrentStepSizes(stepsizes_);
+     154             :   }
+     155             :   //
+     156          79 :   if(ncoeffssets_==1) {
+     157          76 :     log.printf("  optimizing VES bias %s with label %s: \n",bias_pntrs_[0]->getName().c_str(),bias_pntrs_[0]->getLabel().c_str());
+     158          76 :     log.printf("   KbT: %f\n",bias_pntrs_[0]->getKbT());
+     159          76 :     log.printf("  number of coefficients: %zu\n",coeffs_pntrs_[0]->numberOfCoeffs());
+     160          76 :     if(stepsizes_.size()>0) {
+     161          75 :       if(fixed_stepsize_) {log.printf("  using a constant step size of %f\n",stepsizes_[0]);}
+     162           1 :       else {log.printf("  using an initial step size of %f\n",stepsizes_[0]);}
+     163             :     }
+     164             :   }
+     165             :   else {
+     166           3 :     log.printf("  optimizing %u coefficient sets from following %u VES biases:\n",ncoeffssets_,nbiases_);
+     167          12 :     for(unsigned int i=0; i<nbiases_; i++) {
+     168           9 :       log.printf("   %s of type %s (KbT: %f) \n",bias_pntrs_[i]->getLabel().c_str(),bias_pntrs_[i]->getName().c_str(),bias_pntrs_[i]->getKbT());
+     169             :     }
+     170             :     size_t tot_ncoeffs = 0;
+     171          12 :     for(unsigned int i=0; i<ncoeffssets_; i++) {
+     172           9 :       log.printf("  coefficient set %u: \n",i);
+     173           9 :       log.printf("   used in bias %s (type %s)\n",coeffs_pntrs_[i]->getPntrToAction()->getLabel().c_str(),coeffs_pntrs_[i]->getPntrToAction()->getName().c_str());
+     174           9 :       log.printf("   number of coefficients: %zu\n",coeffs_pntrs_[i]->numberOfCoeffs());
+     175           9 :       if(stepsizes_.size()>0) {
+     176           9 :         if(fixed_stepsize_) {log.printf("   using a constant step size of %f\n",stepsizes_[i]);}
+     177           0 :         else {log.printf("   using an initial step size of %f\n",stepsizes_[i]);}
+     178             :       }
+     179           9 :       tot_ncoeffs += coeffs_pntrs_[i]->numberOfCoeffs();
+     180             :     }
+     181           3 :     log.printf("  total number of coefficients: %zu\n",tot_ncoeffs);
+     182           3 :     if(identical_coeffs_shape_) {
+     183           3 :       log.printf("  the indices shape is identical for all coefficient sets\n");
+     184             :     }
+     185             :     else {
+     186           0 :       log.printf("  the indices shape differs between coefficient sets\n");
+     187             :     }
+     188             :   }
+     189             : 
+     190             :   //
+     191         158 :   if(keywords.exists("FULL_HESSIAN")) {
+     192           0 :     bool full_hessian=false;
+     193           0 :     parseFlag("FULL_HESSIAN",full_hessian);
+     194           0 :     diagonal_hessian_ = !full_hessian;
+     195             :   }
+     196             :   //
+     197             :   bool mw_single_files = false;
+     198         158 :   if(keywords.exists("MULTIPLE_WALKERS")) {
+     199          79 :     parseFlag("MULTIPLE_WALKERS",use_mwalkers_mpi_);
+     200          79 :     if(use_mwalkers_mpi_) {
+     201             :       mw_single_files=true;
+     202             :     }
+     203             :   }
+     204             : 
+     205          79 :   int numwalkers=1;
+     206          79 :   int walker_rank=0;
+     207          79 :   if(comm.Get_rank()==0) {
+     208          70 :     numwalkers = multi_sim_comm.Get_size();
+     209          70 :     walker_rank = multi_sim_comm.Get_rank();
+     210             :   }
+     211          79 :   comm.Bcast(numwalkers,0);
+     212          79 :   comm.Bcast(walker_rank,0);
+     213          79 :   if(use_mwalkers_mpi_ && numwalkers==1) {
+     214           0 :     plumed_merror("using the MULTIPLE_WALKERS keyword does not make sense if running the MD code with a single replica");
+     215             :   }
+     216          79 :   if(use_mwalkers_mpi_) {
+     217          12 :     log.printf("  optimization performed using multiple walkers connected via MPI:\n");
+     218          12 :     log.printf("   number of walkers: %d\n",numwalkers);
+     219          12 :     log.printf("   walker number: %d\n",walker_rank);
+     220          12 :     log.printf("   please see and cite ");
+     221          24 :     log << plumed.cite("Raiteri, Laio, Gervasio, Micheletti, and Parrinello, J. Phys. Chem. B 110, 3533 (2006)");
+     222          12 :     log.printf("\n");
+     223             :   }
+     224             : 
+     225          79 :   dynamic_targetdists_.resize(nbiases_,false);
+     226         158 :   if(keywords.exists("TARGETDIST_STRIDE")) {
+     227             :     bool need_stride = false;
+     228         162 :     for(unsigned int i=0; i<nbiases_; i++) {
+     229          84 :       dynamic_targetdists_[i] = bias_pntrs_[i]->dynamicTargetDistribution();
+     230          84 :       if(dynamic_targetdists_[i]) {need_stride = true;}
+     231             :     }
+     232          78 :     parse("TARGETDIST_STRIDE",ustride_targetdist_);
+     233          78 :     if(need_stride && ustride_targetdist_==0) {
+     234           0 :       plumed_merror("one of the biases has a dynamic target distribution so you need to give stride for updating it by using the TARGETDIST_STRIDE keyword");
+     235             :     }
+     236          78 :     if(!need_stride && ustride_targetdist_!=0) {
+     237           0 :       plumed_merror("using the TARGETDIST_STRIDE keyword doesn't make sense as there is no dynamic target distribution to update");
+     238             :     }
+     239          78 :     if(ustride_targetdist_>0) {
+     240          38 :       if(nbiases_==1) {
+     241          38 :         log.printf("  the target distribution will be updated very %u coefficient iterations\n",ustride_targetdist_);
+     242             :       }
+     243             :       else {
+     244           0 :         log.printf("  the target distribution will be updated very %u coefficient iterations for the following biases\n   ",ustride_targetdist_);
+     245           0 :         for(unsigned int i=0; i<nbiases_; i++) {
+     246           0 :           log.printf("%s ",bias_pntrs_[i]->getLabel().c_str());
+     247             :         }
+     248           0 :         log.printf("\n");
+     249             :       }
+     250          38 :       log.printf("  See and cite ");
+     251          76 :       log << plumed.cite("Valsson and Parrinello, J. Chem. Theory Comput. 11, 1996-2002 (2015)");
+     252          38 :       log.printf("\n");
+     253             :     }
+     254             :   }
+     255             : 
+     256         158 :   if(keywords.exists("REWEIGHT_FACTOR_STRIDE")) {
+     257             :     bool reweightfactor_calculated = false;
+     258           0 :     for(unsigned int i=0; i<nbiases_; i++) {
+     259           0 :       reweightfactor_calculated = bias_pntrs_[i]->isReweightFactorCalculated();
+     260             :     }
+     261           0 :     parse("REWEIGHT_FACTOR_STRIDE",ustride_reweightfactor_);
+     262           0 :     if(ustride_reweightfactor_==0 && reweightfactor_calculated) {
+     263           0 :       plumed_merror("the calculation of the reweight factor is enabled, You need to use the REWEIGHT_FACTOR_STRIDE keyword to specfiy how often it should be updated.");
+     264             :     }
+     265           0 :     if(ustride_reweightfactor_>0) {
+     266           0 :       if(!reweightfactor_calculated) {
+     267           0 :         plumed_merror("In order to use the REWEIGHT_FACTOR_STRIDE keyword you need to enable the calculation of the reweight factor in the VES bias by using the CALC_REWEIGHT_FACTOR flag.");
+     268             :       }
+     269           0 :       log.printf("  the reweight factor c(t) will be updated very %u coefficient iterations\n",ustride_reweightfactor_);
+     270             :     }
+     271             :   }
+     272             : 
+     273         158 :   if(keywords.exists("MONITOR_INSTANTANEOUS_GRADIENT")) {
+     274         158 :     parseFlag("MONITOR_INSTANTANEOUS_GRADIENT",monitor_instantaneous_gradient_);
+     275             :   }
+     276             : 
+     277         158 :   if(keywords.exists("MONITOR_AVERAGE_GRADIENT")) {
+     278          76 :     bool monitor_aver_gradient = false;
+     279          76 :     parseFlag("MONITOR_AVERAGE_GRADIENT",monitor_aver_gradient);
+     280          76 :     if(monitor_aver_gradient) {
+     281           2 :       unsigned int averaging_exp_decay=0;
+     282           4 :       parse("MONITOR_AVERAGES_GRADIENT_EXP_DECAY",averaging_exp_decay);
+     283             :       aver_gradient_pntrs_.clear();
+     284           4 :       for(unsigned int i=0; i<ncoeffssets_; i++) {
+     285           2 :         auto aver_gradient_tmp = Tools::make_unique<CoeffsVector>(*gradient_pntrs_[i]);
+     286           2 :         aver_gradient_tmp->clear();
+     287             :         std::string aver_grad_label = aver_gradient_tmp->getLabel();
+     288           2 :         if(aver_grad_label.find("gradient")!=std::string::npos) {
+     289           4 :           aver_grad_label.replace(aver_grad_label.find("gradient"), std::string("gradient").length(), "aver_gradient");
+     290             :         }
+     291             :         else {
+     292             :           aver_grad_label += "_aver";
+     293             :         }
+     294           2 :         aver_gradient_tmp->setLabels(aver_grad_label);
+     295           2 :         if(averaging_exp_decay>0) {
+     296             :           aver_gradient_tmp->setupExponentiallyDecayingAveraging(averaging_exp_decay);
+     297             :         }
+     298           2 :         aver_gradient_pntrs_.emplace_back(std::move(aver_gradient_tmp));
+     299           2 :       }
+     300             :     }
+     301             :   }
+     302             : 
+     303             : 
+     304          79 :   if(ncoeffssets_>1) {
+     305             :     coeffssetid_prefix_="c-";
+     306           6 :     if(keywords.exists("COEFFS_SET_ID_PREFIX")) {
+     307           6 :       parse("COEFFS_SET_ID_PREFIX",coeffssetid_prefix_);
+     308             :     }
+     309             :   }
+     310             :   else {
+     311             :     coeffssetid_prefix_="";
+     312         152 :     if(keywords.exists("COEFFS_SET_ID_PREFIX")) {
+     313         152 :       parse("COEFFS_SET_ID_PREFIX",coeffssetid_prefix_);
+     314             :     }
+     315          76 :     if(coeffssetid_prefix_.size()>0) {
+     316           0 :       plumed_merror("COEFFS_SET_ID_PREFIX should only be given if optimizing multiple coefficient sets");
+     317             :     }
+     318             :   }
+     319             : 
+     320         158 :   if(keywords.exists("INITIAL_COEFFS")) {
+     321             :     std::vector<std::string> initial_coeffs_fnames;
+     322         158 :     parseFilenames("INITIAL_COEFFS",initial_coeffs_fnames);
+     323          79 :     if(initial_coeffs_fnames.size()>0) {
+     324           1 :       readCoeffsFromFiles(initial_coeffs_fnames,false);
+     325           1 :       comm.Barrier();
+     326           1 :       if(comm.Get_rank()==0 && use_mwalkers_mpi_) {
+     327           0 :         multi_sim_comm.Barrier();
+     328             :       }
+     329           1 :       setAllCoeffsSetIterationCounters();
+     330             :     }
+     331          79 :   }
+     332             :   //
+     333             : 
+     334             :   std::vector<std::string> coeffs_fnames;
+     335         158 :   if(keywords.exists("COEFFS_FILE")) {
+     336         158 :     parseFilenames("COEFFS_FILE",coeffs_fnames,"coeffs.data");
+     337          79 :     bool start_opt_afresh=false;
+     338         158 :     if(keywords.exists("START_OPTIMIZATION_AFRESH")) {
+     339          76 :       parseFlag("START_OPTIMIZATION_AFRESH",start_opt_afresh);
+     340          76 :       if(start_opt_afresh && !getRestart()) {
+     341           0 :         plumed_merror("the START_OPTIMIZATION_AFRESH keyword should only be used when a restart has been triggered by the RESTART keyword or the MD code");
+     342             :       }
+     343             :     }
+     344          79 :     if(getRestart()) {
+     345          28 :       for(unsigned int i=0; i<coeffs_fnames.size(); i++) {
+     346          15 :         IFile ifile;
+     347          15 :         ifile.link(*this);
+     348          19 :         if(use_mwalkers_mpi_) {ifile.enforceSuffix("");}
+     349          15 :         bool file_exist = ifile.FileExist(coeffs_fnames[i]);
+     350          15 :         if(!file_exist) {
+     351           0 :           std::string fname = FileBase::appendSuffix(coeffs_fnames[i],ifile.getSuffix());
+     352           0 :           plumed_merror("Cannot find coefficient file " + fname + " when trying to restart an optimzation. If you don't want to restart the optimzation please remove the RESTART keyword or use the RESTART=NO within the "+getName()+" action to locally disable the restart.");
+     353             :         }
+     354          15 :       }
+     355          13 :       readCoeffsFromFiles(coeffs_fnames,true);
+     356          13 :       comm.Barrier();
+     357          13 :       if(comm.Get_rank()==0 && use_mwalkers_mpi_) {
+     358           4 :         multi_sim_comm.Barrier();
+     359             :       }
+     360          13 :       unsigned int iter_opt_tmp = coeffs_pntrs_[0]->getIterationCounter();
+     361          15 :       for(unsigned int i=1; i<ncoeffssets_; i++) {
+     362           2 :         plumed_massert(coeffs_pntrs_[i]->getIterationCounter()==iter_opt_tmp,"the iteraton counter should be the same for all files when restarting from previous coefficient files\n");
+     363             :       }
+     364          13 :       if(start_opt_afresh) {
+     365             :         setIterationCounter(0);
+     366           1 :         log.printf("  Optimization started afresh at iteration %u\n",getIterationCounter());
+     367           2 :         for(unsigned int i=0; i<ncoeffssets_; i++) {
+     368           1 :           AuxCoeffs(i).setValues( Coeffs(i) );
+     369             :         }
+     370             :       }
+     371             :       else {
+     372             :         setIterationCounter(coeffs_pntrs_[0]->getIterationCounter());
+     373          12 :         log.printf("  Optimization restarted at iteration %u\n",getIterationCounter());
+     374             :       }
+     375          13 :       setAllCoeffsSetIterationCounters();
+     376             :     }
+     377             : 
+     378          79 :     std::string coeffs_wstride_tmpstr="";
+     379         158 :     parse("COEFFS_OUTPUT",coeffs_wstride_tmpstr);
+     380          79 :     if(coeffs_wstride_tmpstr!="OFF" && coeffs_wstride_tmpstr.size()>0) {
+     381          79 :       Tools::convert(coeffs_wstride_tmpstr,coeffs_wstride_);
+     382             :     }
+     383          79 :     if(coeffs_wstride_tmpstr=="OFF") {
+     384             :       coeffs_fnames.clear();
+     385             :     }
+     386          79 :     setupOFiles(coeffs_fnames,coeffsOFiles_,mw_single_files);
+     387         158 :     parse("COEFFS_FMT",coeffs_output_fmt_);
+     388          79 :     if(coeffs_output_fmt_.size()>0) {
+     389         162 :       for(unsigned int i=0; i<ncoeffssets_; i++) {
+     390          84 :         coeffs_pntrs_[i]->setOutputFmt(coeffs_output_fmt_);
+     391             :       }
+     392             :     }
+     393          79 :     if(!getRestart()) {
+     394         136 :       for(unsigned int i=0; i<coeffsOFiles_.size(); i++) {
+     395          70 :         coeffs_pntrs_[i]->writeToFile(*coeffsOFiles_[i],aux_coeffs_pntrs_[i].get(),false);
+     396             :       }
+     397             :     }
+     398          79 :     if(coeffs_fnames.size()>0) {
+     399          79 :       if(ncoeffssets_==1) {
+     400         152 :         log.printf("  Coefficients will be written out to file %s every %u iterations\n",coeffsOFiles_[0]->getPath().c_str(),coeffs_wstride_);
+     401             :       }
+     402             :       else {
+     403           3 :         log.printf("  Coefficients will be written out to the following files every %u iterations:\n",coeffs_wstride_);
+     404          12 :         for(unsigned int i=0; i<coeffs_fnames.size(); i++) {
+     405          18 :           log.printf("   coefficient set %u: %s\n",i,coeffsOFiles_[i]->getPath().c_str());
+     406             :         }
+     407             :       }
+     408             :     }
+     409             :     else {
+     410           0 :       log.printf("  Output of coefficients to file has been disabled\n");
+     411             :     }
+     412             :   }
+     413             : 
+     414             :   std::vector<std::string> gradient_fnames;
+     415         158 :   if(keywords.exists("GRADIENT_FILE")) {
+     416          79 :     parseFilenames("GRADIENT_FILE",gradient_fnames);
+     417         158 :     parse("GRADIENT_OUTPUT",gradient_wstride_);
+     418             : 
+     419          79 :     if(coeffs_fnames.size()>0) {
+     420         151 :       for(unsigned int i=0; i<gradient_fnames.size(); i++) {
+     421          72 :         plumed_massert(gradient_fnames[i]!=coeffs_fnames[i],"COEFFS_FILE and GRADIENT_FILE cannot be the same");
+     422             :       }
+     423             :     }
+     424          79 :     setupOFiles(gradient_fnames,gradientOFiles_,mw_single_files);
+     425         158 :     parse("GRADIENT_FMT",gradient_output_fmt_);
+     426          79 :     if(gradient_output_fmt_.size()>0) {
+     427         138 :       for(unsigned int i=0; i<ncoeffssets_; i++) {
+     428          72 :         gradient_pntrs_[i]->setOutputFmt(gradient_output_fmt_);
+     429             :       }
+     430             :     }
+     431             : 
+     432          79 :     if(gradient_fnames.size()>0) {
+     433          66 :       if(ncoeffssets_==1) {
+     434         126 :         log.printf("  Gradient will be written out to file %s every %u iterations\n",gradientOFiles_[0]->getPath().c_str(),gradient_wstride_);
+     435             :       }
+     436             :       else {
+     437           3 :         log.printf("  Gradient will be written out to the following files every %u iterations:\n",gradient_wstride_);
+     438          12 :         for(unsigned int i=0; i<gradient_fnames.size(); i++) {
+     439          18 :           log.printf("   coefficient set %u: %s\n",i,gradientOFiles_[i]->getPath().c_str());
+     440             :         }
+     441             :       }
+     442             :     }
+     443             :   }
+     444             : 
+     445             :   std::vector<std::string> hessian_fnames;
+     446         158 :   if(keywords.exists("HESSIAN_FILE")) {
+     447          76 :     parseFilenames("HESSIAN_FILE",hessian_fnames);
+     448         152 :     parse("HESSIAN_OUTPUT",hessian_wstride_);
+     449             : 
+     450          76 :     if(coeffs_fnames.size()>0) {
+     451         142 :       for(unsigned int i=0; i<hessian_fnames.size(); i++) {
+     452          66 :         plumed_massert(hessian_fnames[i]!=coeffs_fnames[i],"COEFFS_FILE and HESSIAN_FILE cannot be the same");
+     453             :       }
+     454             :     }
+     455          76 :     if(gradient_fnames.size()>0) {
+     456         131 :       for(unsigned int i=0; i<hessian_fnames.size(); i++) {
+     457          66 :         plumed_massert(hessian_fnames[i]!=gradient_fnames[i],"GRADIENT_FILE and HESSIAN_FILE cannot be the same");
+     458             :       }
+     459             :     }
+     460          76 :     setupOFiles(hessian_fnames,hessianOFiles_,mw_single_files);
+     461         152 :     parse("HESSIAN_FMT",hessian_output_fmt_);
+     462             : 
+     463          76 :     if(hessian_fnames.size()>0) {
+     464          62 :       if(ncoeffssets_==1) {
+     465         120 :         log.printf("  Hessian will be written out to file %s every %u iterations\n",hessianOFiles_[0]->getPath().c_str(),hessian_wstride_);
+     466             :       }
+     467             :       else {
+     468           2 :         log.printf("  Hessian will be written out to the following files every %u iterations:\n",hessian_wstride_);
+     469           8 :         for(unsigned int i=0; i<hessian_fnames.size(); i++) {
+     470          12 :           log.printf("   coefficient set %u: %s\n",i,hessianOFiles_[i]->getPath().c_str());
+     471             :         }
+     472             :       }
+     473             :     }
+     474             :   }
+     475             : 
+     476             : 
+     477             :   //
+     478         158 :   if(keywords.exists("MASK_FILE")) {
+     479             :     std::vector<std::string> mask_fnames_in;
+     480         156 :     parseVector("MASK_FILE",mask_fnames_in);
+     481          78 :     if(mask_fnames_in.size()==1 && ncoeffssets_>1) {
+     482           0 :       if(identical_coeffs_shape_) {mask_fnames_in.resize(ncoeffssets_,mask_fnames_in[0]);}
+     483           0 :       else {plumed_merror("the coefficients indices shape differs between biases so you need to give a separate file for each coefficient set\n");}
+     484             :     }
+     485          78 :     if(mask_fnames_in.size()>0 && mask_fnames_in.size()!=ncoeffssets_) {
+     486           0 :       plumed_merror("Error in MASK_FILE keyword: either give one value for all biases or a separate value for each coefficient set");
+     487             :     }
+     488             : 
+     489          78 :     coeffs_mask_pntrs_.resize(ncoeffssets_);
+     490         162 :     for(unsigned int i=0; i<ncoeffssets_; i++) {
+     491         168 :       coeffs_mask_pntrs_[i] = Tools::make_unique<CoeffsVector>(*coeffs_pntrs_[i]);
+     492         168 :       coeffs_mask_pntrs_[i]->setLabels("mask");
+     493          84 :       coeffs_mask_pntrs_[i]->setValues(1.0);
+     494         168 :       coeffs_mask_pntrs_[i]->setOutputFmt("%f");
+     495             :     }
+     496             : 
+     497          78 :     if(mask_fnames_in.size()>0) {
+     498           1 :       if(ncoeffssets_==1) {
+     499           1 :         size_t nread = coeffs_mask_pntrs_[0]->readFromFile(mask_fnames_in[0],true,true);
+     500           1 :         log.printf("  read %zu values from mask file %s\n",nread,mask_fnames_in[0].c_str());
+     501           1 :         size_t ndeactived = coeffs_mask_pntrs_[0]->countValues(0.0);
+     502           1 :         log.printf("  deactived optimization of %zu coefficients\n",ndeactived);
+     503             :       }
+     504             :       else {
+     505           0 :         for(unsigned int i=0; i<ncoeffssets_; i++) {
+     506           0 :           size_t nread = coeffs_mask_pntrs_[i]->readFromFile(mask_fnames_in[i],true,true);
+     507           0 :           log.printf("  mask for coefficient set %u:\n",i);
+     508           0 :           log.printf("   read %zu values from file %s\n",nread,mask_fnames_in[i].c_str());
+     509           0 :           size_t ndeactived = coeffs_mask_pntrs_[0]->countValues(0.0);
+     510           0 :           log.printf("   deactived optimization of %zu coefficients\n",ndeactived);
+     511             :         }
+     512             :       }
+     513             :     }
+     514             : 
+     515             :     std::vector<std::string> mask_fnames_out;
+     516          78 :     parseFilenames("OUTPUT_MASK_FILE",mask_fnames_out);
+     517             : 
+     518          79 :     for(unsigned int i=0; i<mask_fnames_out.size(); i++) {
+     519           1 :       if(mask_fnames_in.size()>0) {
+     520           1 :         plumed_massert(mask_fnames_out[i]!=mask_fnames_in[i],"MASK_FILE and OUTPUT_MASK_FILE cannot be the same");
+     521             :       }
+     522           1 :       OFile maskOFile;
+     523           1 :       maskOFile.link(*this);
+     524           1 :       maskOFile.enforceBackup();
+     525           1 :       if(use_mwalkers_mpi_ && mwalkers_mpi_single_files_) {
+     526           0 :         unsigned int r=0;
+     527           0 :         if(comm.Get_rank()==0) {r=multi_sim_comm.Get_rank();}
+     528           0 :         comm.Bcast(r,0);
+     529           0 :         if(r>0) {mask_fnames_out[i]="/dev/null";}
+     530           0 :         maskOFile.enforceSuffix("");
+     531             :       }
+     532           1 :       maskOFile.open(mask_fnames_out[i]);
+     533           1 :       coeffs_mask_pntrs_[i]->writeToFile(maskOFile,true);
+     534           1 :       maskOFile.close();
+     535           1 :     }
+     536          78 :   }
+     537             : 
+     538          79 :   if(getRestart() && ustride_targetdist_>0) {
+     539          16 :     for(unsigned int i=0; i<nbiases_; i++) {
+     540           8 :       if(dynamic_targetdists_[i]) {
+     541           8 :         bias_pntrs_[i]->restartTargetDistributions();
+     542             :       }
+     543             :     }
+     544             :   }
+     545             : 
+     546             : 
+     547             :   std::vector<std::string> targetdist_averages_fnames;
+     548         158 :   if(keywords.exists("TARGETDIST_AVERAGES_FILE")) {
+     549         158 :     parseFilenames("TARGETDIST_AVERAGES_FILE",targetdist_averages_fnames,"targetdist-averages.data");
+     550         158 :     parse("TARGETDIST_AVERAGES_OUTPUT",targetdist_averages_wstride_);
+     551             : 
+     552          79 :     if(coeffs_fnames.size()>0) {
+     553         164 :       for(unsigned int i=0; i<targetdist_averages_fnames.size(); i++) {
+     554          85 :         plumed_massert(targetdist_averages_fnames[i]!=coeffs_fnames[i],"COEFFS_FILE and TARGETDIST_AVERAGES_FILE cannot be the same");
+     555             :       }
+     556             :     }
+     557          79 :     if(gradient_fnames.size()>0) {
+     558         138 :       for(unsigned int i=0; i<targetdist_averages_fnames.size(); i++) {
+     559          72 :         plumed_massert(targetdist_averages_fnames[i]!=gradient_fnames[i],"GRADIENT_FILE and TARGETDIST_AVERAGES_FILE cannot be the same");
+     560             :       }
+     561             :     }
+     562          79 :     if(hessian_fnames.size()>0) {
+     563         128 :       for(unsigned int i=0; i<targetdist_averages_fnames.size(); i++) {
+     564          66 :         plumed_massert(targetdist_averages_fnames[i]!=hessian_fnames[i],"HESSIAN_FILE and TARGETDIST_AVERAGES_FILE cannot be the same");
+     565             :       }
+     566             :     }
+     567          79 :     setupOFiles(targetdist_averages_fnames,targetdist_averagesOFiles_,mw_single_files);
+     568         158 :     parse("TARGETDIST_AVERAGES_FMT",targetdist_averages_output_fmt_);
+     569          79 :     if(targetdist_averages_output_fmt_.size()>0) {
+     570         156 :       for(unsigned int i=0; i<ncoeffssets_; i++) {
+     571          81 :         targetdist_averages_pntrs_[i]->setOutputFmt(targetdist_averages_output_fmt_);
+     572             :       }
+     573             :     }
+     574             : 
+     575         164 :     for(unsigned int i=0; i<targetdist_averagesOFiles_.size(); i++) {
+     576          85 :       targetdist_averages_pntrs_[i]->writeToFile(*targetdist_averagesOFiles_[i]);
+     577             :     }
+     578             : 
+     579          79 :     if(targetdist_averages_wstride_==0) {
+     580             :       targetdist_averagesOFiles_.clear();
+     581             :     }
+     582             : 
+     583          79 :     if(targetdist_averages_fnames.size()>0 && targetdist_averages_wstride_ > 0) {
+     584          34 :       if(ncoeffssets_==1) {
+     585          68 :         log.printf("  Target distribution averages will be written out to file %s every %u iterations\n",targetdist_averagesOFiles_[0]->getPath().c_str(),targetdist_averages_wstride_);
+     586             :       }
+     587             :       else {
+     588           0 :         log.printf("  Target distribution averages will be written out to the following files every %u iterations:\n",targetdist_averages_wstride_);
+     589           0 :         for(unsigned int i=0; i<targetdist_averages_fnames.size(); i++) {
+     590           0 :           log.printf("   coefficient set %u: %s\n",i,targetdist_averagesOFiles_[i]->getPath().c_str());
+     591             :         }
+     592             :       }
+     593             :     }
+     594             :   }
+     595             : 
+     596             : 
+     597         158 :   if(keywords.exists("BIAS_OUTPUT")) {
+     598          79 :     parse("BIAS_OUTPUT",bias_output_stride_);
+     599          79 :     if(bias_output_stride_>0) {
+     600          74 :       bias_output_active_=true;
+     601         154 :       for(unsigned int i=0; i<nbiases_; i++) {
+     602          80 :         bias_pntrs_[i]->enableBiasFileOutput();
+     603          80 :         bias_pntrs_[i]->setupBiasFileOutput();
+     604          80 :         bias_pntrs_[i]->writeBiasToFile();
+     605             :       }
+     606             :     }
+     607             :     else {
+     608           5 :       bias_output_active_=false;
+     609           5 :       bias_output_stride_=1000;
+     610             :     }
+     611             :   }
+     612             : 
+     613         158 :   if(keywords.exists("FES_OUTPUT")) {
+     614          79 :     parse("FES_OUTPUT",fes_output_stride_);
+     615          79 :     if(fes_output_stride_>0) {
+     616          74 :       fes_output_active_=true;
+     617         154 :       for(unsigned int i=0; i<nbiases_; i++) {
+     618          80 :         bias_pntrs_[i]->enableFesFileOutput();
+     619          80 :         bias_pntrs_[i]->setupFesFileOutput();
+     620          80 :         bias_pntrs_[i]->writeFesToFile();
+     621             :       }
+     622             :     }
+     623             :     else {
+     624           5 :       fes_output_active_=false;
+     625           5 :       fes_output_stride_=1000;
+     626             :     }
+     627             :   }
+     628             : 
+     629         158 :   if(keywords.exists("FES_PROJ_OUTPUT")) {
+     630          79 :     parse("FES_PROJ_OUTPUT",fesproj_output_stride_);
+     631          79 :     if(fesproj_output_stride_>0) {
+     632          16 :       fesproj_output_active_=true;
+     633          32 :       for(unsigned int i=0; i<nbiases_; i++) {
+     634          16 :         bias_pntrs_[i]->enableFesProjFileOutput();
+     635          16 :         bias_pntrs_[i]->setupFesProjFileOutput();
+     636          16 :         bias_pntrs_[i]->writeFesProjToFile();
+     637             :       }
+     638             :     }
+     639             :     else {
+     640          63 :       fesproj_output_active_=false;
+     641          63 :       fesproj_output_stride_=1000;
+     642             :     }
+     643             :   }
+     644             : 
+     645         164 :   for(unsigned int i=0; i<nbiases_; i++) {
+     646          85 :     if(!dynamic_targetdists_[i] && bias_pntrs_[i]->isStaticTargetDistFileOutputActive()) {
+     647           4 :       bias_pntrs_[i]->setupTargetDistFileOutput();
+     648           4 :       bias_pntrs_[i]->writeTargetDistToFile();
+     649           4 :       bias_pntrs_[i]->setupTargetDistProjFileOutput();
+     650           4 :       bias_pntrs_[i]->writeTargetDistProjToFile();
+     651             :     }
+     652             :   }
+     653             : 
+     654         158 :   if(keywords.exists("TARGETDIST_OUTPUT")) {
+     655          78 :     parse("TARGETDIST_OUTPUT",targetdist_output_stride_);
+     656          78 :     if(targetdist_output_stride_>0) {
+     657          37 :       if(ustride_targetdist_==0) {
+     658           0 :         plumed_merror("it doesn't make sense to use the TARGETDIST_OUTPUT keyword if you don't have a target distribution that needs to be updated");
+     659             :       }
+     660          37 :       if(targetdist_output_stride_%ustride_targetdist_!=0) {
+     661           0 :         plumed_merror("the value given in TARGETDIST_OUTPUT doesn't make sense, it should be multiple of TARGETDIST_STRIDE");
+     662             :       }
+     663          37 :       if(targetdist_output_stride_%coeffs_wstride_!=0) {
+     664           0 :         plumed_merror("the value given in TARGETDIST_OUTPUT doesn't make sense, it should be multiple of COEFFS_OUTPUT");
+     665             :       }
+     666             : 
+     667          37 :       targetdist_output_active_=true;
+     668          74 :       for(unsigned int i=0; i<nbiases_; i++) {
+     669          37 :         if(dynamic_targetdists_[i]) {
+     670          37 :           bias_pntrs_[i]->enableDynamicTargetDistFileOutput();
+     671          37 :           bias_pntrs_[i]->setupTargetDistFileOutput();
+     672          37 :           bias_pntrs_[i]->writeTargetDistToFile();
+     673             :         }
+     674             :       }
+     675             :     }
+     676             :     else {
+     677          41 :       targetdist_output_active_=false;
+     678          41 :       targetdist_output_stride_=1000;
+     679             :     }
+     680             :   }
+     681             : 
+     682         158 :   if(keywords.exists("TARGETDIST_PROJ_OUTPUT")) {
+     683          78 :     parse("TARGETDIST_PROJ_OUTPUT",targetdist_proj_output_stride_);
+     684          78 :     if(targetdist_proj_output_stride_>0) {
+     685           3 :       if(ustride_targetdist_==0) {
+     686           0 :         plumed_merror("it doesn't make sense to use the TARGETDIST_PROJ_OUTPUT keyword if you don't have a target distribution that needs to be updated");
+     687             :       }
+     688           3 :       if(targetdist_proj_output_stride_%ustride_targetdist_!=0) {
+     689           0 :         plumed_merror("the value given in TARGETDIST_PROJ_OUTPUT doesn't make sense, it should be multiple of TARGETDIST_STRIDE");
+     690             :       }
+     691             : 
+     692           3 :       targetdist_proj_output_active_=true;
+     693           6 :       for(unsigned int i=0; i<nbiases_; i++) {
+     694           3 :         if(dynamic_targetdists_[i]) {
+     695           3 :           bias_pntrs_[i]->enableDynamicTargetDistFileOutput();
+     696           3 :           bias_pntrs_[i]->setupTargetDistProjFileOutput();
+     697           3 :           bias_pntrs_[i]->writeTargetDistProjToFile();
+     698             :         }
+     699             :       }
+     700             :     }
+     701             :     else {
+     702          75 :       targetdist_proj_output_active_=false;
+     703          75 :       targetdist_proj_output_stride_=1000;
+     704             :     }
+     705             :   }
+     706             : 
+     707          79 :   if(ncoeffssets_==1) {
+     708          76 :     log.printf("  Output Components:\n");
+     709          76 :     log.printf(" ");
+     710          76 :     if(monitor_instantaneous_gradient_) {
+     711           6 :       addComponent("gradrms"); componentIsNotPeriodic("gradrms");
+     712           3 :       log.printf(" ");
+     713           9 :       addComponent("gradmax"); componentIsNotPeriodic("gradmax");
+     714             :     }
+     715          76 :     if(aver_gradient_pntrs_.size()>0) {
+     716           2 :       log.printf(" ");
+     717           4 :       addComponent("avergradrms"); componentIsNotPeriodic("avergradrms");
+     718           2 :       log.printf(" ");
+     719           6 :       addComponent("avergradmax"); componentIsNotPeriodic("avergradmax");
+     720             :     }
+     721          76 :     if(!fixed_stepsize_) {
+     722           1 :       log.printf(" ");
+     723           2 :       addComponent("stepsize"); componentIsNotPeriodic("stepsize");
+     724           2 :       getPntrToComponent("stepsize")->set( getCurrentStepSize(0) );
+     725             :     }
+     726             :   }
+     727             :   else {
+     728          12 :     for(unsigned int i=0; i<ncoeffssets_; i++) {
+     729           9 :       log.printf("  Output Components for coefficient set %u:\n",i);
+     730          18 :       std::string is=""; Tools::convert(i,is); is = "-" + coeffssetid_prefix_ + is;
+     731           9 :       log.printf(" ");
+     732           9 :       if(monitor_instantaneous_gradient_) {
+     733           6 :         addComponent("gradrms"+is); componentIsNotPeriodic("gradrms"+is);
+     734           3 :         log.printf(" ");
+     735           9 :         addComponent("gradmax"+is); componentIsNotPeriodic("gradmax"+is);
+     736             :       }
+     737           9 :       if(aver_gradient_pntrs_.size()>0) {
+     738           0 :         log.printf(" ");
+     739           0 :         addComponent("avergradrms"+is); componentIsNotPeriodic("avergradrms"+is);
+     740           0 :         log.printf(" ");
+     741           0 :         addComponent("avergradmax"+is); componentIsNotPeriodic("avergradmax"+is);
+     742             :       }
+     743           9 :       if(!fixed_stepsize_) {
+     744           0 :         log.printf(" ");
+     745           0 :         addComponent("stepsize"+is); componentIsNotPeriodic("stepsize"+is);
+     746           0 :         getPntrToComponent("stepsize"+is)->set( getCurrentStepSize(i) );
+     747             :       }
+     748             :     }
+     749             :   }
+     750             : 
+     751         158 : }
+     752             : 
+     753             : 
+     754          79 : Optimizer::~Optimizer() {
+     755             :   //
+     756         164 :   for(unsigned int i=0; i<ncoeffssets_; i++) {
+     757          85 :     if(coeffsOFiles_.size()>0 && getIterationCounter()%coeffs_wstride_!=0) {
+     758           2 :       coeffs_pntrs_[i]->writeToFile(*coeffsOFiles_[i],aux_coeffs_pntrs_[i].get(),false);
+     759             :     }
+     760          85 :     if(targetdist_averagesOFiles_.size()>0 && iter_counter%targetdist_averages_wstride_!=0) {
+     761           1 :       targetdist_averages_pntrs_[i]->writeToFile(*targetdist_averagesOFiles_[i]);
+     762             :     }
+     763             :   }
+     764             :   //
+     765          79 :   if(!isTargetDistOutputActive()) {
+     766          90 :     for(unsigned int i=0; i<nbiases_; i++) {
+     767          48 :       if(dynamic_targetdists_[i]) {
+     768           1 :         bias_pntrs_[i]->enableDynamicTargetDistFileOutput();
+     769           1 :         bias_pntrs_[i]->setupTargetDistFileOutput();
+     770           1 :         bias_pntrs_[i]->writeTargetDistToFile();
+     771             :       }
+     772             :     }
+     773             :   }
+     774             :   //
+     775          79 :   if(isBiasOutputActive() && getIterationCounter()%getBiasOutputStride()!=0) {
+     776           1 :     writeBiasOutputFiles();
+     777             :   }
+     778          79 :   if(isFesOutputActive() && getIterationCounter()%getFesOutputStride()!=0) {
+     779           1 :     writeFesOutputFiles();
+     780             :   }
+     781          79 :   if(isFesProjOutputActive() && getIterationCounter()%getFesProjOutputStride()!=0) {
+     782           1 :     writeFesProjOutputFiles();
+     783             :   }
+     784          79 :   if(isTargetDistOutputActive() && getIterationCounter()%getTargetDistOutputStride()!=0) {
+     785           2 :     writeTargetDistOutputFiles();
+     786             :   }
+     787          79 :   if(isTargetDistProjOutputActive() && getIterationCounter()%getTargetDistProjOutputStride()!=0) {
+     788           1 :     writeTargetDistProjOutputFiles();
+     789             :   }
+     790         395 : }
+     791             : 
+     792             : 
+     793          87 : void Optimizer::registerKeywords( Keywords& keys ) {
+     794          87 :   Action::registerKeywords(keys);
+     795          87 :   ActionPilot::registerKeywords(keys);
+     796          87 :   ActionWithValue::registerKeywords(keys);
+     797             :   //
+     798          87 :   keys.remove("NUMERICAL_DERIVATIVES");
+     799             :   // Default always active keywords
+     800         174 :   keys.add("compulsory","BIAS","the label of the VES bias to be optimized");
+     801         174 :   keys.add("compulsory","STRIDE","the frequency of updating the coefficients given in the number of MD steps.");
+     802         174 :   keys.add("compulsory","COEFFS_FILE","coeffs.data","the name of output file for the coefficients");
+     803         174 :   keys.add("compulsory","COEFFS_OUTPUT","100","how often the coefficients should be written to file. This parameter is given as the number of iterations.");
+     804         174 :   keys.add("optional","COEFFS_FMT","specify format for coefficient file(s) (useful for decrease the number of digits in regtests)");
+     805         174 :   keys.add("optional","COEFFS_SET_ID_PREFIX","suffix to add to the filename given in FILE to identify the bias, should only be given if a single filename is given in FILE when optimizing multiple biases.");
+     806             :   //
+     807         174 :   keys.add("optional","INITIAL_COEFFS","the name(s) of file(s) with the initial coefficients");
+     808             :   // Hidden keywords to output the gradient to a file.
+     809         174 :   keys.add("hidden","GRADIENT_FILE","the name of output file for the gradient");
+     810         174 :   keys.add("hidden","GRADIENT_OUTPUT","how often the gradient should be written to file. This parameter is given as the number of bias iterations. It is by default 100 if GRADIENT_FILE is specficed");
+     811         174 :   keys.add("hidden","GRADIENT_FMT","specify format for gradient file(s) (useful for decrease the number of digits in regtests)");
+     812             :   // Either use a fixed stepsize (useFixedStepSizeKeywords) or changing stepsize (useDynamicsStepSizeKeywords)
+     813         174 :   keys.reserve("compulsory","STEPSIZE","the step size used for the optimization");
+     814         174 :   keys.reserve("compulsory","INITIAL_STEPSIZE","the initial step size used for the optimization");
+     815             :   // Keywords related to the Hessian, actived with the useHessianKeywords function
+     816         174 :   keys.reserveFlag("FULL_HESSIAN",false,"if the full Hessian matrix should be used for the optimization, otherwise only the diagonal part of the Hessian is used");
+     817         174 :   keys.reserve("hidden","HESSIAN_FILE","the name of output file for the Hessian");
+     818         174 :   keys.reserve("hidden","HESSIAN_OUTPUT","how often the Hessian should be written to file. This parameter is given as the number of bias iterations. It is by default 100 if HESSIAN_FILE is specficed");
+     819         174 :   keys.reserve("hidden","HESSIAN_FMT","specify format for hessian file(s) (useful for decrease the number of digits in regtests)");
+     820             :   // Keywords related to the multiple walkers, actived with the useMultipleWalkersKeywords function
+     821         174 :   keys.reserveFlag("MULTIPLE_WALKERS",false,"if optimization is to be performed using multiple walkers connected via MPI");
+     822             :   // Keywords related to the mask file, actived with the useMaskKeywords function
+     823         174 :   keys.reserve("optional","MASK_FILE","read in a mask file which allows one to employ different step sizes for different coefficients and/or deactivate the optimization of certain coefficients (by putting values of 0.0). One can write out the resulting mask by using the OUTPUT_MASK_FILE keyword.");
+     824         174 :   keys.reserve("optional","OUTPUT_MASK_FILE","Name of the file to write out the mask resulting from using the MASK_FILE keyword. Can also be used to generate a template mask file.");
+     825             :   //
+     826         174 :   keys.reserveFlag("START_OPTIMIZATION_AFRESH",false,"if the iterations should be started afresh when a restart has been triggered by the RESTART keyword or the MD code.");
+     827             :   //
+     828         174 :   keys.addFlag("MONITOR_INSTANTANEOUS_GRADIENT",false,"if quantities related to the instantaneous gradient should be outputted.");
+     829             :   //
+     830         174 :   keys.reserveFlag("MONITOR_AVERAGE_GRADIENT",false,"if the averaged gradient should be monitored and quantities related to it should be outputted.");
+     831         174 :   keys.reserve("optional","MONITOR_AVERAGES_GRADIENT_EXP_DECAY","use an exponentially decaying averaging with a given time constant when monitoring the averaged gradient");
+     832             :   //
+     833         174 :   keys.reserve("optional","TARGETDIST_STRIDE","stride for updating a target distribution that is iteratively updated during the optimization. Note that the value is given in terms of coefficient iterations.");
+     834         174 :   keys.reserve("optional","TARGETDIST_OUTPUT","how often the dynamic target distribution(s) should be written out to file. Note that the value is given in terms of coefficient iterations.");
+     835         174 :   keys.reserve("optional","TARGETDIST_PROJ_OUTPUT","how often the projections of the dynamic target distribution(s) should be written out to file. Note that the value is given in terms of coefficient iterations.");
+     836             :   //
+     837         174 :   keys.add("optional","TARGETDIST_AVERAGES_FILE","the name of output file for the target distribution averages. By default it is targetdist-averages.data.");
+     838         174 :   keys.add("optional","TARGETDIST_AVERAGES_OUTPUT","how often the target distribution averages should be written out to file. Note that the value is given in terms of coefficient iterations. If no value is given are the averages only written at the beginning of the optimization");
+     839         174 :   keys.add("hidden","TARGETDIST_AVERAGES_FMT","specify format for target distribution averages file(s) (useful for decrease the number of digits in regtests)");
+     840             :   //
+     841         174 :   keys.add("optional","BIAS_OUTPUT","how often the bias(es) should be written out to file. Note that the value is given in terms of coefficient iterations.");
+     842         174 :   keys.add("optional","FES_OUTPUT","how often the FES(s) should be written out to file. Note that the value is given in terms of coefficient iterations.");
+     843         174 :   keys.add("optional","FES_PROJ_OUTPUT","how often the projections of the FES(s) should be written out to file. Note that the value is given in terms of coefficient iterations.");
+     844             :   //
+     845         174 :   keys.reserve("optional","REWEIGHT_FACTOR_STRIDE","stride for updating the reweighting factor c(t). Note that the value is given in terms of coefficient iterations.");
+     846             :   //
+     847          87 :   keys.use("RESTART");
+     848             :   //
+     849          87 :   keys.use("UPDATE_FROM");
+     850          87 :   keys.use("UPDATE_UNTIL");
+     851             :   // Components that are always active
+     852         174 :   keys.addOutputComponent("gradrms","MONITOR_INSTANTANEOUS_GRADIENT","the root mean square value of the coefficient gradient. For multiple biases this component is labeled using the number of the bias as gradrms-#.");
+     853         174 :   keys.addOutputComponent("gradmax","MONITOR_INSTANTANEOUS_GRADIENT","the largest absolute value of the coefficient gradient. For multiple biases this component is labeled using the number of the bias as gradmax-#.");
+     854             :   // keys.addOutputComponent("gradmaxidx","default","the index of the maximum absolute value of the gradient");
+     855             : 
+     856          87 : }
+     857             : 
+     858             : 
+     859          80 : void Optimizer::useHessianKeywords(Keywords& keys) {
+     860             :   // keys.use("FULL_HESSIAN");
+     861          80 :   keys.use("HESSIAN_FILE");
+     862          80 :   keys.use("HESSIAN_OUTPUT");
+     863          80 :   keys.use("HESSIAN_FMT");
+     864          80 : }
+     865             : 
+     866             : 
+     867          87 : void Optimizer::useMultipleWalkersKeywords(Keywords& keys) {
+     868          87 :   keys.use("MULTIPLE_WALKERS");
+     869          87 : }
+     870             : 
+     871             : 
+     872          81 : void Optimizer::useFixedStepSizeKeywords(Keywords& keys) {
+     873          81 :   keys.use("STEPSIZE");
+     874          81 : }
+     875             : 
+     876             : 
+     877           3 : void Optimizer::useDynamicStepSizeKeywords(Keywords& keys) {
+     878           3 :   keys.use("INITIAL_STEPSIZE");
+     879           6 :   keys.addOutputComponent("stepsize","default","the current value of step size used to update the coefficients. For multiple biases this component is labeled using the number of the bias as stepsize-#.");
+     880           3 : }
+     881             : 
+     882             : 
+     883          84 : void Optimizer::useMaskKeywords(Keywords& keys) {
+     884          84 :   keys.use("MASK_FILE");
+     885          84 :   keys.use("OUTPUT_MASK_FILE");
+     886          84 : }
+     887             : 
+     888             : 
+     889          80 : void Optimizer::useRestartKeywords(Keywords& keys) {
+     890          80 :   keys.use("START_OPTIMIZATION_AFRESH");
+     891          80 : }
+     892             : 
+     893             : 
+     894          80 : void Optimizer::useMonitorAverageGradientKeywords(Keywords& keys) {
+     895          80 :   keys.use("MONITOR_AVERAGE_GRADIENT");
+     896          80 :   keys.use("MONITOR_AVERAGES_GRADIENT_EXP_DECAY");
+     897         160 :   keys.addOutputComponent("avergradrms","MONITOR_AVERAGE_GRADIENT","the root mean square value of the averaged coefficient gradient. For multiple biases this component is labeled using the number of the bias as gradrms-#.");
+     898         160 :   keys.addOutputComponent("avergradmax","MONITOR_AVERAGE_GRADIENT","the largest absolute value of the averaged coefficient gradient. For multiple biases this component is labeled using the number of the bias as gradmax-#.");
+     899          80 : }
+     900             : 
+     901             : 
+     902          84 : void Optimizer::useDynamicTargetDistributionKeywords(Keywords& keys) {
+     903          84 :   keys.use("TARGETDIST_STRIDE");
+     904          84 :   keys.use("TARGETDIST_OUTPUT");
+     905          84 :   keys.use("TARGETDIST_PROJ_OUTPUT");
+     906          84 : }
+     907             : 
+     908             : 
+     909           0 : void Optimizer::useReweightFactorKeywords(Keywords& keys) {
+     910           0 :   keys.use("REWEIGHT_FACTOR_STRIDE");
+     911           0 : }
+     912             : 
+     913             : 
+     914          76 : void Optimizer::turnOnHessian() {
+     915          76 :   plumed_massert(hessian_pntrs_.size()==0,"turnOnHessian() should only be run during initialization");
+     916          76 :   use_hessian_=true;
+     917          76 :   hessian_pntrs_.clear();
+     918         158 :   for(unsigned int i=0; i<nbiases_; i++) {
+     919          82 :     std::vector<CoeffsMatrix*> pntrs_hessian = enableHessian(bias_pntrs_[i],diagonal_hessian_);
+     920         164 :     for(unsigned int k=0; k<pntrs_hessian.size(); k++) {
+     921          82 :       pntrs_hessian[k]->turnOnIterationCounter();
+     922          82 :       pntrs_hessian[k]->setIterationCounterAndTime(getIterationCounter(),getTime());
+     923          82 :       hessian_pntrs_.push_back(pntrs_hessian[k]);
+     924             :     }
+     925             :   }
+     926          76 :   plumed_massert(hessian_pntrs_.size()==ncoeffssets_,"problems in linking Hessians");
+     927          76 :   if(diagonal_hessian_) {
+     928          76 :     log.printf("  Optimization performed using diagonal Hessian matrix\n");
+     929             :   }
+     930             :   else {
+     931           0 :     log.printf("  Optimization performed using full Hessian matrix\n");
+     932             :   }
+     933             :   //
+     934          76 :   if(hessian_output_fmt_.size()>0) {
+     935         128 :     for(unsigned int i=0; i<ncoeffssets_; i++) {
+     936          66 :       hessian_pntrs_[i]->setOutputFmt(hessian_output_fmt_);
+     937             :     }
+     938             :   }
+     939             : 
+     940          76 : }
+     941             : 
+     942             : 
+     943           0 : void Optimizer::turnOffHessian() {
+     944           0 :   use_hessian_=false;
+     945           0 :   for(unsigned int i=0; i<nbiases_; i++) {
+     946           0 :     bias_pntrs_[i]->disableHessian();
+     947             :   }
+     948             :   hessian_pntrs_.clear();
+     949           0 :   hessianOFiles_.clear();
+     950           0 : }
+     951             : 
+     952             : 
+     953          82 : std::vector<CoeffsMatrix*> Optimizer::enableHessian(VesBias* bias_pntr_in, const bool diagonal_hessian) {
+     954          82 :   plumed_massert(use_hessian_,"the Hessian should not be used");
+     955          82 :   bias_pntr_in->enableHessian(diagonal_hessian);
+     956             :   std::vector<CoeffsMatrix*> hessian_pntrs_out = bias_pntr_in->getHessianPntrs();
+     957         164 :   for(unsigned int k=0; k<hessian_pntrs_out.size(); k++) {
+     958          82 :     plumed_massert(hessian_pntrs_out[k] != NULL,"Hessian is needed but not linked correctly");
+     959             :   }
+     960          82 :   return hessian_pntrs_out;
+     961             : }
+     962             : 
+     963             : 
+     964             : // CoeffsMatrix* Optimizer::switchToDiagonalHessian(VesBias* bias_pntr_in) {
+     965             : //   plumed_massert(use_hessian_,"it does not make sense to switch to diagonal Hessian if it Hessian is not used");
+     966             : //   diagonal_hessian_=true;
+     967             : //   bias_pntr_in->enableHessian(diagonal_hessian_);
+     968             : //   CoeffsMatrix* hessian_pntr_out = bias_pntr_in->getHessianPntr();
+     969             : //   plumed_massert(hessian_pntr_out != NULL,"Hessian is needed but not linked correctly");
+     970             : //   //
+     971             : //   log.printf("  %s (with label %s): switching to a diagonal Hessian for VES bias %s (with label %s) at time  %f\n",getName().c_str(),getLabel().c_str(),bias_pntr_in->getName().c_str(),bias_pntr_in->getLabel().c_str(),getTime());
+     972             : //   return hessian_pntr_out;
+     973             : // }
+     974             : 
+     975             : 
+     976             : // CoeffsMatrix* Optimizer::switchToFullHessian(VesBias* bias_pntr_in) {
+     977             : //   plumed_massert(use_hessian_,"it does not make sense to switch to diagonal Hessian if it Hessian is not used");
+     978             : //   diagonal_hessian_=false;
+     979             : //   bias_pntr_in->enableHessian(diagonal_hessian_);
+     980             : //   CoeffsMatrix* hessian_pntr_out = bias_pntr_in->getHessianPntr();
+     981             : //   plumed_massert(hessian_pntr_out != NULL,"Hessian is needed but not linked correctly");
+     982             : //   //
+     983             : //   log.printf("  %s (with label %s): switching to a diagonal Hessian for VES bias %s (with label %s) at time  %f\n",getName().c_str(),getLabel().c_str(),bias_pntr_in->getName().c_str(),bias_pntr_in->getLabel().c_str(),getTime());
+     984             : //   return hessian_pntr_out;
+     985             : // }
+     986             : 
+     987             : 
+     988       22879 : void Optimizer::update() {
+     989       22879 :   if(onStep() && !isFirstStep) {
+     990       45560 :     for(unsigned int i=0; i<nbiases_; i++) {
+     991       22810 :       bias_pntrs_[i]->updateGradientAndHessian(use_mwalkers_mpi_);
+     992             :     }
+     993       45560 :     for(unsigned int i=0; i<ncoeffssets_; i++) {
+     994       22810 :       if(gradient_pntrs_[i]->isActive()) {coeffsUpdate(i);}
+     995             :       else {
+     996         190 :         std::string msg = "iteration " + getIterationCounterStr(+1) +
+     997         285 :                           " for " + bias_pntrs_[i]->getLabel() +
+     998          95 :                           " - the coefficients are not updated as CV values are outside the bias intervals";
+     999          95 :         warning(msg);
+    1000             :       }
+    1001             : 
+    1002             :       // +1 as this is done before increaseIterationCounter() is used
+    1003       22810 :       unsigned int curr_iter = getIterationCounter()+1;
+    1004       22810 :       double curr_time = getTime();
+    1005       22810 :       coeffs_pntrs_[i]->setIterationCounterAndTime(curr_iter,curr_time);
+    1006             :       aux_coeffs_pntrs_[i]->setIterationCounterAndTime(curr_iter,curr_time);
+    1007       22810 :       gradient_pntrs_[i]->setIterationCounterAndTime(curr_iter,curr_time);
+    1008       22810 :       targetdist_averages_pntrs_[i]->setIterationCounterAndTime(curr_iter,curr_time);
+    1009       22810 :       if(use_hessian_) {
+    1010       22780 :         hessian_pntrs_[i]->setIterationCounterAndTime(curr_iter,curr_time);
+    1011             :       }
+    1012       22810 :       if(aver_gradient_pntrs_.size()>0) {
+    1013             :         aver_gradient_pntrs_[i]->setIterationCounterAndTime(curr_iter,curr_time);
+    1014          20 :         aver_gradient_pntrs_[i]->addToAverage(*gradient_pntrs_[i]);
+    1015             :       }
+    1016             :     }
+    1017             :     increaseIterationCounter();
+    1018             : 
+    1019       22750 :     if(ustride_targetdist_>0 && getIterationCounter()%ustride_targetdist_==0) {
+    1020         708 :       for(unsigned int i=0; i<nbiases_; i++) {
+    1021         354 :         if(dynamic_targetdists_[i]) {
+    1022         354 :           bias_pntrs_[i]->updateTargetDistributions();
+    1023             :         }
+    1024             :       }
+    1025             :     }
+    1026       22750 :     if(ustride_reweightfactor_>0 && getIterationCounter()%ustride_reweightfactor_==0) {
+    1027           0 :       for(unsigned int i=0; i<nbiases_; i++) {
+    1028           0 :         bias_pntrs_[i]->updateReweightFactor();
+    1029             :       }
+    1030             :     }
+    1031             : 
+    1032       22750 :     updateOutputComponents();
+    1033       45560 :     for(unsigned int i=0; i<ncoeffssets_; i++) {
+    1034       22810 :       writeOutputFiles(i);
+    1035             :     }
+    1036             :     //
+    1037       22750 :     if(isBiasOutputActive() && getIterationCounter()%getBiasOutputStride()==0) {
+    1038          74 :       writeBiasOutputFiles();
+    1039             :     }
+    1040       22750 :     if(isFesOutputActive() && getIterationCounter()%getFesOutputStride()==0) {
+    1041          74 :       writeFesOutputFiles();
+    1042             :     }
+    1043       22750 :     if(isFesProjOutputActive() && getIterationCounter()%getFesProjOutputStride()==0) {
+    1044          16 :       writeFesProjOutputFiles();
+    1045             :     }
+    1046       22750 :     if(isTargetDistOutputActive() && getIterationCounter()%getTargetDistOutputStride()==0) {
+    1047          36 :       writeTargetDistOutputFiles();
+    1048             :     }
+    1049       22750 :     if(isTargetDistProjOutputActive() && getIterationCounter()%getTargetDistProjOutputStride()==0) {
+    1050           3 :       writeTargetDistProjOutputFiles();
+    1051             :     }
+    1052             :   }
+    1053             :   else {
+    1054         129 :     isFirstStep=false;
+    1055             :   }
+    1056       22879 : }
+    1057             : 
+    1058             : 
+    1059       22750 : void Optimizer::updateOutputComponents() {
+    1060       22750 :   if(ncoeffssets_==1) {
+    1061       22720 :     if(!fixed_stepsize_) {
+    1062          20 :       getPntrToComponent("stepsize")->set( getCurrentStepSize(0) );
+    1063             :     }
+    1064       22720 :     if(monitor_instantaneous_gradient_) {
+    1065          30 :       getPntrToComponent("gradrms")->set( gradient_pntrs_[0]->getRMS() );
+    1066          30 :       size_t gradient_maxabs_idx=0;
+    1067          60 :       getPntrToComponent("gradmax")->set( gradient_pntrs_[0]->getMaxAbsValue(gradient_maxabs_idx) );
+    1068             :     }
+    1069       22720 :     if(aver_gradient_pntrs_.size()>0) {
+    1070          20 :       getPntrToComponent("avergradrms")->set( aver_gradient_pntrs_[0]->getRMS() );
+    1071          20 :       size_t avergradient_maxabs_idx=0;
+    1072          40 :       getPntrToComponent("avergradmax")->set( aver_gradient_pntrs_[0]->getMaxAbsValue(avergradient_maxabs_idx) );
+    1073             :     }
+    1074             :   }
+    1075             :   else {
+    1076         120 :     for(unsigned int i=0; i<ncoeffssets_; i++) {
+    1077         180 :       std::string is=""; Tools::convert(i,is); is = "-" + coeffssetid_prefix_ + is;
+    1078          90 :       if(!fixed_stepsize_) {
+    1079           0 :         getPntrToComponent("stepsize"+is)->set( getCurrentStepSize(i) );
+    1080             :       }
+    1081          90 :       if(monitor_instantaneous_gradient_) {
+    1082          30 :         getPntrToComponent("gradrms"+is)->set( gradient_pntrs_[i]->getRMS() );
+    1083          30 :         size_t gradient_maxabs_idx=0;
+    1084          60 :         getPntrToComponent("gradmax"+is)->set( gradient_pntrs_[i]->getMaxAbsValue(gradient_maxabs_idx) );
+    1085             :       }
+    1086          90 :       if(aver_gradient_pntrs_.size()>0) {
+    1087           0 :         getPntrToComponent("avergradrms"+is)->set( aver_gradient_pntrs_[0]->getRMS() );
+    1088           0 :         size_t avergradient_maxabs_idx=0;
+    1089           0 :         getPntrToComponent("avergradmax"+is)->set( aver_gradient_pntrs_[0]->getMaxAbsValue(avergradient_maxabs_idx) );
+    1090             :       }
+    1091             :     }
+    1092             :   }
+    1093       22750 : }
+    1094             : 
+    1095             : 
+    1096           1 : void Optimizer::turnOffCoeffsOutputFiles() {
+    1097           1 :   coeffsOFiles_.clear();
+    1098           1 : }
+    1099             : 
+    1100             : 
+    1101       22810 : void Optimizer::writeOutputFiles(const unsigned int coeffs_id) {
+    1102       22810 :   if(coeffsOFiles_.size()>0 && iter_counter%coeffs_wstride_==0) {
+    1103         789 :     coeffs_pntrs_[coeffs_id]->writeToFile(*coeffsOFiles_[coeffs_id],aux_coeffs_pntrs_[coeffs_id].get(),false);
+    1104             :   }
+    1105       22810 :   if(gradientOFiles_.size()>0 && iter_counter%gradient_wstride_==0) {
+    1106         720 :     if(aver_gradient_pntrs_.size()==0) {
+    1107         700 :       gradient_pntrs_[coeffs_id]->writeToFile(*gradientOFiles_[coeffs_id],false);
+    1108             :     }
+    1109             :     else {
+    1110          20 :       gradient_pntrs_[coeffs_id]->writeToFile(*gradientOFiles_[coeffs_id],aver_gradient_pntrs_[coeffs_id].get(),false);
+    1111             :     }
+    1112             :   }
+    1113       22810 :   if(hessianOFiles_.size()>0 && iter_counter%hessian_wstride_==0) {
+    1114         660 :     hessian_pntrs_[coeffs_id]->writeToFile(*hessianOFiles_[coeffs_id]);
+    1115             :   }
+    1116       22810 :   if(targetdist_averagesOFiles_.size()>0 && iter_counter%targetdist_averages_wstride_==0) {
+    1117         333 :     targetdist_averages_pntrs_[coeffs_id]->writeToFile(*targetdist_averagesOFiles_[coeffs_id]);
+    1118             :   }
+    1119       22810 : }
+    1120             : 
+    1121             : 
+    1122         388 : void Optimizer::setupOFiles(std::vector<std::string>& fnames, std::vector<std::unique_ptr<OFile>>& OFiles, const bool multi_sim_single_files) {
+    1123         388 :   plumed_assert(ncoeffssets_>0);
+    1124         388 :   OFiles.resize(fnames.size());
+    1125         702 :   for(unsigned int i=0; i<fnames.size(); i++) {
+    1126         314 :     OFiles[i] = Tools::make_unique<OFile>();
+    1127         314 :     OFiles[i]->link(*this);
+    1128         314 :     if(multi_sim_single_files) {
+    1129          48 :       unsigned int r=0;
+    1130          48 :       if(comm.Get_rank()==0) {r=multi_sim_comm.Get_rank();}
+    1131          48 :       comm.Bcast(r,0);
+    1132          48 :       if(r>0) {fnames[i]="/dev/null";}
+    1133          96 :       OFiles[i]->enforceSuffix("");
+    1134             :     }
+    1135         314 :     OFiles[i]->open(fnames[i]);
+    1136         314 :     OFiles[i]->setHeavyFlush();
+    1137             :   }
+    1138         388 : }
+    1139             : 
+    1140             : 
+    1141          14 : void Optimizer::readCoeffsFromFiles(const std::vector<std::string>& fnames, const bool read_aux_coeffs) {
+    1142          14 :   plumed_assert(ncoeffssets_>0);
+    1143          14 :   plumed_assert(fnames.size()==ncoeffssets_);
+    1144          14 :   if(ncoeffssets_==1) {
+    1145          13 :     log.printf("  Read in coefficients from file ");
+    1146             :   }
+    1147             :   else {
+    1148           1 :     log.printf("  Read in coefficients from files:\n");
+    1149             :   }
+    1150          30 :   for(unsigned int i=0; i<ncoeffssets_; i++) {
+    1151          16 :     IFile ifile;
+    1152          16 :     ifile.link(*this);
+    1153          16 :     if(use_mwalkers_mpi_ && mwalkers_mpi_single_files_) {
+    1154           8 :       ifile.enforceSuffix("");
+    1155             :     }
+    1156          16 :     ifile.open(fnames[i]);
+    1157          32 :     if(!ifile.FieldExist(coeffs_pntrs_[i]->getDataLabel())) {
+    1158           0 :       std::string error_msg = "Problem with reading coefficients from file " + ifile.getPath() + ": no field with name " + coeffs_pntrs_[i]->getDataLabel() + "\n";
+    1159           0 :       plumed_merror(error_msg);
+    1160             :     }
+    1161          16 :     size_t ncoeffs_read = coeffs_pntrs_[i]->readFromFile(ifile,false,false);
+    1162          16 :     if(ncoeffssets_==1) {
+    1163          26 :       log.printf("%s (read %zu of %zu values)\n", ifile.getPath().c_str(),ncoeffs_read,coeffs_pntrs_[i]->numberOfCoeffs());
+    1164             :     }
+    1165             :     else {
+    1166           6 :       log.printf("   coefficient set %u: %s (read %zu of %zu values)\n",i,ifile.getPath().c_str(),ncoeffs_read,coeffs_pntrs_[i]->numberOfCoeffs());
+    1167             :     }
+    1168          16 :     ifile.close();
+    1169          16 :     if(read_aux_coeffs) {
+    1170          15 :       ifile.open(fnames[i]);
+    1171          30 :       if(!ifile.FieldExist(aux_coeffs_pntrs_[i]->getDataLabel())) {
+    1172           0 :         std::string error_msg = "Problem with reading coefficients from file " + ifile.getPath() + ": no field with name " + aux_coeffs_pntrs_[i]->getDataLabel() + "\n";
+    1173           0 :         plumed_merror(error_msg);
+    1174             :       }
+    1175          15 :       aux_coeffs_pntrs_[i]->readFromFile(ifile,false,false);
+    1176          15 :       ifile.close();
+    1177             :     }
+    1178             :     else {
+    1179           1 :       AuxCoeffs(i).setValues( Coeffs(i) );
+    1180             :     }
+    1181          16 :   }
+    1182          14 : }
+    1183             : 
+    1184             : 
+    1185          85 : void Optimizer::addCoeffsSetIDsToFilenames(std::vector<std::string>& fnames, std::string& coeffssetid_prefix) {
+    1186          85 :   if(ncoeffssets_==1) {return;}
+    1187             :   //
+    1188           9 :   if(fnames.size()==1) {
+    1189           0 :     fnames.resize(ncoeffssets_,fnames[0]);
+    1190             :   }
+    1191           9 :   plumed_assert(fnames.size()==ncoeffssets_);
+    1192             :   //
+    1193          36 :   for(unsigned int i=0; i<ncoeffssets_; i++) {
+    1194          27 :     std::string is=""; Tools::convert(i,is);
+    1195          54 :     fnames[i] = FileBase::appendSuffix(fnames[i],"."+coeffssetid_prefix_+is);
+    1196             :   }
+    1197             : }
+    1198             : 
+    1199             : 
+    1200          93 : void Optimizer::setAllCoeffsSetIterationCounters() {
+    1201         194 :   for(unsigned int i=0; i<ncoeffssets_; i++) {
+    1202         101 :     coeffs_pntrs_[i]->setIterationCounterAndTime(getIterationCounter(),getTime());
+    1203         101 :     aux_coeffs_pntrs_[i]->setIterationCounterAndTime(getIterationCounter(),getTime());
+    1204         101 :     gradient_pntrs_[i]->setIterationCounterAndTime(getIterationCounter(),getTime());
+    1205         101 :     targetdist_averages_pntrs_[i]->setIterationCounterAndTime(getIterationCounter(),getTime());
+    1206         101 :     if(use_hessian_) {
+    1207           0 :       hessian_pntrs_[i]->setIterationCounterAndTime(getIterationCounter(),getTime());
+    1208             :     }
+    1209             :   }
+    1210          93 : }
+    1211             : 
+    1212             : 
+    1213          95 : std::string Optimizer::getIterationCounterStr(const int offset) const {
+    1214             :   std::string s;
+    1215          95 :   Tools::convert(getIterationCounter()+offset,s);
+    1216          95 :   return s;
+    1217             : }
+    1218             : 
+    1219             : 
+    1220          75 : void Optimizer::writeBiasOutputFiles() const {
+    1221         156 :   for(unsigned int i=0; i<nbiases_; i++) {
+    1222          81 :     bias_pntrs_[i]->writeBiasToFile();
+    1223             :   }
+    1224          75 : }
+    1225             : 
+    1226             : 
+    1227          75 : void Optimizer::writeFesOutputFiles() const {
+    1228         156 :   for(unsigned int i=0; i<nbiases_; i++) {
+    1229          81 :     bias_pntrs_[i]->writeFesToFile();
+    1230             :   }
+    1231          75 : }
+    1232             : 
+    1233             : 
+    1234          17 : void Optimizer::writeFesProjOutputFiles() const {
+    1235          34 :   for(unsigned int i=0; i<nbiases_; i++) {
+    1236          17 :     bias_pntrs_[i]->writeFesProjToFile();
+    1237             :   }
+    1238          17 : }
+    1239             : 
+    1240             : 
+    1241          38 : void Optimizer::writeTargetDistOutputFiles() const {
+    1242          76 :   for(unsigned int i=0; i<nbiases_; i++) {
+    1243          38 :     if(dynamic_targetdists_[i]) {
+    1244          38 :       bias_pntrs_[i]->writeTargetDistToFile();
+    1245             :     }
+    1246             :   }
+    1247          38 : }
+    1248             : 
+    1249             : 
+    1250           4 : void Optimizer::writeTargetDistProjOutputFiles() const {
+    1251           8 :   for(unsigned int i=0; i<nbiases_; i++) {
+    1252           4 :     if(dynamic_targetdists_[i]) {
+    1253           4 :       bias_pntrs_[i]->writeTargetDistProjToFile();
+    1254             :     }
+    1255             :   }
+    1256           4 : }
+    1257             : 
+    1258             : 
+    1259             : 
+    1260             : }
+    1261             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/Optimizer.h.func-sort-c.html b/coverage/ves/Optimizer.h.func-sort-c.html new file mode 100644 index 000000000000..f4c7ae47fc01 --- /dev/null +++ b/coverage/ves/Optimizer.h.func-sort-c.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - ves/Optimizer.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - Optimizer.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:535694.6 %
Date:2024-04-19 12:12:35Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves9Optimizer22getNumberOfDerivativesEv0
_ZN4PLMD3ves9Optimizer19parseMultipleValuesIdEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIT_SaISC_EE78
_ZN4PLMD3ves9Optimizer19setCurrentStepSizesERKSt6vectorIdSaIdEE78
_ZN4PLMD3ves9Optimizer14parseFilenamesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIS7_SaIS7_EES9_158
_ZN4PLMD3ves9Optimizer19parseMultipleValuesINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEbRKS8_RSt6vectorIT_SaISC_EERKSC_158
_ZN4PLMD3ves9Optimizer14parseFilenamesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIS7_SaIS7_EE387
_ZN4PLMD3ves9Optimizer19parseMultipleValuesINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEbRKS8_RSt6vectorIT_SaISC_EE545
_ZNK4PLMD3ves9Optimizer7HessianEj22735
_ZN4PLMD3ves9Optimizer5applyEv22879
_ZN4PLMD3ves9Optimizer9calculateEv22879
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/Optimizer.h.func.html b/coverage/ves/Optimizer.h.func.html new file mode 100644 index 000000000000..9dcc54e57e6b --- /dev/null +++ b/coverage/ves/Optimizer.h.func.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - ves/Optimizer.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - Optimizer.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:535694.6 %
Date:2024-04-19 12:12:35Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves9Optimizer14parseFilenamesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIS7_SaIS7_EE387
_ZN4PLMD3ves9Optimizer14parseFilenamesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIS7_SaIS7_EES9_158
_ZN4PLMD3ves9Optimizer19parseMultipleValuesINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEbRKS8_RSt6vectorIT_SaISC_EE545
_ZN4PLMD3ves9Optimizer19parseMultipleValuesINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEbRKS8_RSt6vectorIT_SaISC_EERKSC_158
_ZN4PLMD3ves9Optimizer19parseMultipleValuesIdEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIT_SaISC_EE78
_ZN4PLMD3ves9Optimizer19setCurrentStepSizesERKSt6vectorIdSaIdEE78
_ZN4PLMD3ves9Optimizer22getNumberOfDerivativesEv0
_ZN4PLMD3ves9Optimizer5applyEv22879
_ZN4PLMD3ves9Optimizer9calculateEv22879
_ZNK4PLMD3ves9Optimizer7HessianEj22735
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/Optimizer.h.gcov.html b/coverage/ves/Optimizer.h.gcov.html new file mode 100644 index 000000000000..afc1a4f0fdca --- /dev/null +++ b/coverage/ves/Optimizer.h.gcov.html @@ -0,0 +1,431 @@ + + + + + + + + LCOV - plumed test coverage - ves/Optimizer.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - Optimizer.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:535694.6 %
Date:2024-04-19 12:12:35Functions:91090.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_ves_Optimizer_h
+      23             : #define __PLUMED_ves_Optimizer_h
+      24             : 
+      25             : #include "VesBias.h"
+      26             : 
+      27             : #include "core/ActionPilot.h"
+      28             : #include "core/ActionWithValue.h"
+      29             : 
+      30             : #include <vector>
+      31             : #include <string>
+      32             : #include <cmath>
+      33             : #include <memory>
+      34             : 
+      35             : 
+      36             : #define PLUMED_VES_OPTIMIZER_INIT(ao) Action(ao),Optimizer(ao)
+      37             : 
+      38             : namespace PLMD {
+      39             : 
+      40             : /**
+      41             : \ingroup INHERIT
+      42             : Abstract base class for implenting new optimization methods
+      43             : */
+      44             : 
+      45             : class OFile;
+      46             : 
+      47             : namespace ves {
+      48             : 
+      49             : class CoeffsVector;
+      50             : class VesBias;
+      51             : 
+      52             : 
+      53             : class Optimizer :
+      54             :   public ActionPilot,
+      55             :   public ActionWithValue
+      56             : {
+      57             : private:
+      58             :   const std::string description_;
+      59             :   const std::string type_;
+      60             :   //
+      61             :   std::vector<double> stepsizes_;
+      62             :   std::vector<double> current_stepsizes;
+      63             :   bool fixed_stepsize_;
+      64             :   //
+      65             :   unsigned int iter_counter;
+      66             :   //
+      67             :   bool use_hessian_;
+      68             :   bool diagonal_hessian_;
+      69             :   bool hessian_covariance_from_averages_;
+      70             :   //
+      71             :   bool monitor_instantaneous_gradient_;
+      72             :   //
+      73             :   bool use_mwalkers_mpi_;
+      74             :   bool mwalkers_mpi_single_files_;
+      75             :   //
+      76             :   std::vector<bool> dynamic_targetdists_;
+      77             :   unsigned int ustride_targetdist_;
+      78             :   //
+      79             :   unsigned int ustride_reweightfactor_;
+      80             :   //
+      81             :   std::string coeffssetid_prefix_;
+      82             :   //
+      83             :   unsigned int coeffs_wstride_;
+      84             :   std::vector<std::unique_ptr<OFile>> coeffsOFiles_;
+      85             :   std::string coeffs_output_fmt_;
+      86             :   //
+      87             :   unsigned int gradient_wstride_;
+      88             :   std::vector<std::unique_ptr<OFile>> gradientOFiles_;
+      89             :   std::string gradient_output_fmt_;
+      90             :   //
+      91             :   unsigned int hessian_wstride_;
+      92             :   std::vector<std::unique_ptr<OFile>> hessianOFiles_;
+      93             :   std::string hessian_output_fmt_;
+      94             :   //
+      95             :   unsigned int targetdist_averages_wstride_;
+      96             :   std::vector<std::unique_ptr<OFile>> targetdist_averagesOFiles_;
+      97             :   std::string targetdist_averages_output_fmt_;
+      98             :   //
+      99             :   unsigned int nbiases_;
+     100             :   std::vector<VesBias*> bias_pntrs_;
+     101             :   //
+     102             :   unsigned int ncoeffssets_;
+     103             :   std::vector<CoeffsVector*> coeffs_pntrs_;
+     104             :   std::vector<std::unique_ptr<CoeffsVector>> aux_coeffs_pntrs_;
+     105             :   std::vector<CoeffsVector*> gradient_pntrs_;
+     106             :   std::vector<std::unique_ptr<CoeffsVector>> aver_gradient_pntrs_;
+     107             :   std::vector<CoeffsMatrix*> hessian_pntrs_;
+     108             :   std::vector<std::unique_ptr<CoeffsVector>> coeffs_mask_pntrs_;
+     109             :   std::vector<CoeffsVector*> targetdist_averages_pntrs_;
+     110             :   //
+     111             :   bool identical_coeffs_shape_;
+     112             :   //
+     113             :   bool bias_output_active_;
+     114             :   unsigned int bias_output_stride_;
+     115             :   bool fes_output_active_;
+     116             :   unsigned int fes_output_stride_;
+     117             :   bool fesproj_output_active_;
+     118             :   unsigned int fesproj_output_stride_;
+     119             :   bool targetdist_output_active_;
+     120             :   unsigned int targetdist_output_stride_;
+     121             :   bool targetdist_proj_output_active_;
+     122             :   unsigned int targetdist_proj_output_stride_;
+     123             :   //
+     124             :   bool isFirstStep;
+     125             :   //
+     126             : private:
+     127             :   void updateOutputComponents();
+     128             :   void writeOutputFiles(const unsigned int coeffs_id = 0);
+     129             :   void readCoeffsFromFiles(const std::vector<std::string>&, const bool);
+     130             :   void setAllCoeffsSetIterationCounters();
+     131             : protected:
+     132             :   void turnOnHessian();
+     133             :   void turnOffHessian();
+     134             :   std::vector<CoeffsMatrix*> enableHessian(VesBias*, const bool diagonal_hessian=false);
+     135             :   // CoeffsMatrix* switchToDiagonalHessian(VesBias*);
+     136             :   // CoeffsMatrix* switchToFullHessian(VesBias*);
+     137             :   //
+     138             :   CoeffsVector& Coeffs(const unsigned int coeffs_id = 0) const;
+     139             :   CoeffsVector& AuxCoeffs(const unsigned int coeffs_id = 0) const;
+     140             :   CoeffsVector& Gradient(const unsigned int coeffs_id = 0) const;
+     141             :   CoeffsMatrix& Hessian(const unsigned int coeffs_id = 0) const;
+     142             :   CoeffsVector& CoeffsMask(const unsigned int coeffs_id = 0) const;
+     143             :   CoeffsVector& TargetDistAverages(const unsigned int coeffs_id = 0) const;
+     144             :   double StepSize(const unsigned int coeffs_id = 0) const;
+     145             :   virtual void coeffsUpdate(const unsigned int coeffs_id = 0) = 0;
+     146             :   void setCurrentStepSize(const double,const unsigned int i = 0);
+     147             :   void setCurrentStepSizes(const std::vector<double>&);
+     148             :   //
+     149             :   void turnOffCoeffsOutputFiles();
+     150             :   //
+     151             :   template<class T>
+     152             :   bool parseMultipleValues(const std::string&, std::vector<T>&);
+     153             :   template<class T>
+     154             :   bool parseMultipleValues(const std::string&, std::vector<T>&, const T&);
+     155             :   void parseFilenames(const std::string&, std::vector<std::string>&, const std::string&);
+     156             :   void parseFilenames(const std::string&, std::vector<std::string>&);
+     157             :   void addCoeffsSetIDsToFilenames(std::vector<std::string>&, std::string&);
+     158             :   void setupOFiles(std::vector<std::string>&, std::vector<std::unique_ptr<OFile>>&, const bool multi_sim_single_files=false);
+     159             : public:
+     160             :   static void registerKeywords(Keywords&);
+     161             :   static void useMultipleWalkersKeywords(Keywords&);
+     162             :   static void useHessianKeywords(Keywords&);
+     163             :   static void useFixedStepSizeKeywords(Keywords&);
+     164             :   static void useDynamicStepSizeKeywords(Keywords&);
+     165             :   static void useMaskKeywords(Keywords&);
+     166             :   static void useRestartKeywords(Keywords&);
+     167             :   static void useMonitorAverageGradientKeywords(Keywords&);
+     168             :   static void useDynamicTargetDistributionKeywords(Keywords&);
+     169             :   static void useReweightFactorKeywords(Keywords&);
+     170             :   //
+     171             :   explicit Optimizer(const ActionOptions&ao);
+     172             :   ~Optimizer();
+     173             :   std::string getType() const {return type_;}
+     174             :   std::string getDescription() const {return description_;}
+     175             :   //
+     176             :   unsigned int numberOfBiases() const {return nbiases_;}
+     177          16 :   unsigned int numberOfCoeffsSets() const {return ncoeffssets_;}
+     178             :   //
+     179             :   std::vector<double> getStepSizes() const;
+     180             :   std::vector<double> getCurrentStepSizes() const;
+     181             :   double getStepSize(const unsigned int coeffs_id = 0) const;
+     182             :   double getCurrentStepSize(const unsigned int coeffs_id = 0) const;
+     183             :   void setStepSizes(const std::vector<double>&);
+     184             :   void setStepSize(const double, const unsigned int coeffs_id = 0);
+     185             :   //
+     186             :   unsigned int getIterationCounter() const;
+     187             :   double getIterationCounterDbl() const;
+     188             :   std::string getIterationCounterStr(const int offset=0) const;
+     189             :   void setIterationCounter(const unsigned int);
+     190             :   void increaseIterationCounter();
+     191             :   //
+     192       22879 :   void apply() override {};
+     193       22879 :   void calculate() override {};
+     194             :   void update() override;
+     195           0 :   unsigned int getNumberOfDerivatives() override {return 0;}
+     196             :   //
+     197             :   bool fixedStepSize() const {return fixed_stepsize_;}
+     198             :   bool dynamicStepSize() const {return !fixed_stepsize_;}
+     199             :   //
+     200             :   bool useHessian() const {return use_hessian_;}
+     201             :   bool diagonalHessian() const {return diagonal_hessian_;}
+     202             :   //
+     203         609 :   bool useMultipleWalkers() const {return use_mwalkers_mpi_;}
+     204             :   //
+     205             :   std::vector<VesBias*> getBiasPntrs() const {return bias_pntrs_;}
+     206             :   std::vector<CoeffsVector*> getCoeffsPntrs() const {return coeffs_pntrs_;}
+     207             :   std::vector<CoeffsVector*> getAuxCoeffsPntrs() const {return Tools::unique2raw(aux_coeffs_pntrs_);}
+     208          12 :   std::vector<CoeffsVector*> getGradientPntrs()const {return gradient_pntrs_;}
+     209             :   std::vector<CoeffsMatrix*> getHessianPntrs() const {return hessian_pntrs_;}
+     210             :   std::vector<CoeffsVector*> getCoeffsMaskPntrs() const {return Tools::unique2raw(coeffs_mask_pntrs_);}
+     211             :   std::vector<CoeffsVector*> getTargetDistAveragesPntrs() const {return targetdist_averages_pntrs_;}
+     212             :   //
+     213       22829 :   bool isBiasOutputActive() const {return bias_output_active_;}
+     214         814 :   unsigned int getBiasOutputStride() const {return bias_output_stride_;}
+     215             :   void setBiasOutputStride(unsigned int stride) {bias_output_stride_=stride;}
+     216             :   void writeBiasOutputFiles() const;
+     217             :   //
+     218       22829 :   bool isFesOutputActive() const {return fes_output_active_;}
+     219         814 :   unsigned int getFesOutputStride() const {return fes_output_stride_;}
+     220             :   void setFesOutputStride(unsigned int stride) {fes_output_stride_=stride;}
+     221             :   void writeFesOutputFiles() const;
+     222             :   //
+     223       22829 :   bool isFesProjOutputActive() const {return fesproj_output_active_;}
+     224         176 :   unsigned int getFesProjOutputStride() const {return fesproj_output_stride_;}
+     225             :   void setFesProjOutputStride(unsigned int stride) {fesproj_output_stride_=stride;}
+     226             :   void writeFesProjOutputFiles() const;
+     227             :   //
+     228       22908 :   bool isTargetDistOutputActive() const {return targetdist_output_active_;}
+     229       22367 :   unsigned int getTargetDistOutputStride() const {return targetdist_output_stride_;}
+     230             :   void setTargetDistOutputStride(unsigned int stride) {targetdist_output_stride_=stride;}
+     231             :   void writeTargetDistOutputFiles() const;
+     232             :   //
+     233       22829 :   bool isTargetDistProjOutputActive() const {return targetdist_proj_output_active_;}
+     234          33 :   unsigned int getTargetDistProjOutputStride() const {return targetdist_proj_output_stride_;}
+     235             :   void setTargetDistProjOutputStride(unsigned int stride) {targetdist_proj_output_stride_=stride;}
+     236             :   void writeTargetDistProjOutputFiles() const;
+     237             :   //
+     238             : };
+     239             : 
+     240             : inline
+     241       22705 : double Optimizer::StepSize(const unsigned int coeffs_id) const {return stepsizes_[coeffs_id];}
+     242             : 
+     243             : inline
+     244       68214 : CoeffsVector& Optimizer::Coeffs(const unsigned int coeffs_id) const {return *coeffs_pntrs_[coeffs_id];}
+     245             : 
+     246             : inline
+     247          21 : CoeffsVector& Optimizer::AuxCoeffs(const unsigned int coeffs_id) const {return *aux_coeffs_pntrs_[coeffs_id];}
+     248             : 
+     249             : inline
+     250       22785 : CoeffsVector& Optimizer::Gradient(const unsigned int coeffs_id) const {return *gradient_pntrs_[coeffs_id];}
+     251             : 
+     252             : inline
+     253       22735 : CoeffsMatrix& Optimizer::Hessian(const unsigned int coeffs_id) const {
+     254       22735 :   plumed_massert(use_hessian_,"You cannot use the Hessian without asking for before");
+     255       22735 :   return *hessian_pntrs_[coeffs_id];
+     256             : }
+     257             : 
+     258             : inline
+     259             : CoeffsVector& Optimizer::CoeffsMask(const unsigned int coeffs_id) const {return *coeffs_mask_pntrs_[coeffs_id];}
+     260             : 
+     261             : inline
+     262             : std::vector<double> Optimizer::getStepSizes() const {return stepsizes_;}
+     263             : 
+     264             : inline
+     265             : std::vector<double> Optimizer::getCurrentStepSizes() const {return current_stepsizes;}
+     266             : 
+     267             : inline
+     268             : double Optimizer::getStepSize(const unsigned int coeffs_id) const {return stepsizes_[coeffs_id];}
+     269             : 
+     270             : inline
+     271          11 : double Optimizer::getCurrentStepSize(const unsigned int coeffs_id) const {return current_stepsizes[coeffs_id];}
+     272             : 
+     273             : inline
+     274             : void Optimizer::setStepSizes(const std::vector<double>& stepsizes_in) {
+     275             :   plumed_assert(stepsizes_in.size()==ncoeffssets_);
+     276             :   stepsizes_ = stepsizes_in;
+     277             : }
+     278             : 
+     279             : inline
+     280             : void Optimizer::setStepSize(const double stepsize_in, const unsigned int coeffs_id) {
+     281             :   stepsizes_[coeffs_id] = stepsize_in;
+     282             : }
+     283             : 
+     284             : inline
+     285             : void Optimizer::setCurrentStepSize(const double current_stepsize_in, const unsigned int coeffs_id) {
+     286          10 :   current_stepsizes[coeffs_id] = current_stepsize_in;
+     287             : }
+     288             : 
+     289             : inline
+     290          78 : void Optimizer::setCurrentStepSizes(const std::vector<double>& current_stepsizes_in) {
+     291          78 :   plumed_assert(current_stepsizes_in.size()==ncoeffssets_);
+     292          78 :   current_stepsizes = current_stepsizes_in;
+     293          78 : }
+     294             : 
+     295             : inline
+     296       48388 : unsigned int Optimizer::getIterationCounter() const {return iter_counter;}
+     297             : 
+     298             : inline
+     299       22695 : double Optimizer::getIterationCounterDbl() const {return static_cast<double>(iter_counter);}
+     300             : 
+     301             : inline
+     302       22750 : void Optimizer::increaseIterationCounter() {iter_counter++;}
+     303             : 
+     304             : inline
+     305          13 : void Optimizer::setIterationCounter(const unsigned int iter_counter_in) {iter_counter = iter_counter_in;}
+     306             : 
+     307             : 
+     308             : template<class T>
+     309         623 : bool Optimizer::parseMultipleValues(const std::string& keyword, std::vector<T>& values) {
+     310         623 :   plumed_assert(ncoeffssets_>0);
+     311         623 :   plumed_assert(values.size()==0);
+     312             :   bool identical_values=false;
+     313             :   //
+     314         623 :   parseVector(keyword,values);
+     315         623 :   if(values.size()==1 && ncoeffssets_>1) {
+     316           9 :     values.resize(ncoeffssets_,values[0]);
+     317             :     identical_values=true;
+     318             :   }
+     319         623 :   if(values.size()>0 && values.size()!=ncoeffssets_) {
+     320           0 :     std::string s1; Tools::convert(ncoeffssets_,s1);
+     321           0 :     plumed_merror("Error in " + keyword + " keyword: either give 1 common value for all coefficient sets or " + s1 + " separate value for each set");
+     322             :   }
+     323         623 :   return identical_values;
+     324             : }
+     325             : 
+     326             : template<class T>
+     327         158 : bool Optimizer::parseMultipleValues(const std::string& keyword, std::vector<T>& values, const T& default_value) {
+     328         158 :   bool identical_values = parseMultipleValues(keyword,values);
+     329         158 :   if(values.size()==0) {
+     330          79 :     values.resize(ncoeffssets_,default_value);
+     331             :     identical_values=true;
+     332             :   }
+     333         158 :   return identical_values;
+     334             : }
+     335             : 
+     336             : inline
+     337         158 : void Optimizer::parseFilenames(const std::string& keyword, std::vector<std::string>& fnames, const std::string& default_fname) {
+     338         158 :   if(parseMultipleValues<std::string>(keyword,fnames,default_fname)) {
+     339          81 :     addCoeffsSetIDsToFilenames(fnames,coeffssetid_prefix_);
+     340             :   }
+     341         158 : }
+     342             : 
+     343             : inline
+     344         387 : void Optimizer::parseFilenames(const std::string& keyword, std::vector<std::string>& fnames) {
+     345         387 :   if(parseMultipleValues<std::string>(keyword,fnames)) {
+     346           4 :     addCoeffsSetIDsToFilenames(fnames,coeffssetid_prefix_);
+     347             :   }
+     348         387 : }
+     349             : 
+     350             : 
+     351             : }
+     352             : }
+     353             : 
+     354             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/OutputBasisFunctions.cpp.func-sort-c.html b/coverage/ves/OutputBasisFunctions.cpp.func-sort-c.html new file mode 100644 index 000000000000..cc9fdd3b2404 --- /dev/null +++ b/coverage/ves/OutputBasisFunctions.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - ves/OutputBasisFunctions.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - OutputBasisFunctions.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10811098.2 %
Date:2024-04-19 12:12:35Functions:2450.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves20OutputBasisFunctions5applyEv0
_ZN4PLMD3ves20OutputBasisFunctions9calculateEv0
_ZN4PLMD3ves20OutputBasisFunctionsC2ERKNS_13ActionOptionsE71
_ZN4PLMD3ves20OutputBasisFunctions16registerKeywordsERNS_8KeywordsE73
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/OutputBasisFunctions.cpp.func.html b/coverage/ves/OutputBasisFunctions.cpp.func.html new file mode 100644 index 000000000000..e9857c33e5e0 --- /dev/null +++ b/coverage/ves/OutputBasisFunctions.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - ves/OutputBasisFunctions.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - OutputBasisFunctions.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10811098.2 %
Date:2024-04-19 12:12:35Functions:2450.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves20OutputBasisFunctions16registerKeywordsERNS_8KeywordsE73
_ZN4PLMD3ves20OutputBasisFunctions5applyEv0
_ZN4PLMD3ves20OutputBasisFunctions9calculateEv0
_ZN4PLMD3ves20OutputBasisFunctionsC2ERKNS_13ActionOptionsE71
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/OutputBasisFunctions.cpp.gcov.html b/coverage/ves/OutputBasisFunctions.cpp.gcov.html new file mode 100644 index 000000000000..1c3d5dbadd71 --- /dev/null +++ b/coverage/ves/OutputBasisFunctions.cpp.gcov.html @@ -0,0 +1,313 @@ + + + + + + + + LCOV - plumed test coverage - ves/OutputBasisFunctions.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - OutputBasisFunctions.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10811098.2 %
Date:2024-04-19 12:12:35Functions:2450.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "BasisFunctions.h"
+      24             : #include "TargetDistribution.h"
+      25             : 
+      26             : #include "CoeffsVector.h"
+      27             : #include "VesTools.h"
+      28             : 
+      29             : #include "core/ActionRegister.h"
+      30             : #include "core/ActionSet.h"
+      31             : #include "core/PlumedMain.h"
+      32             : #include "core/Value.h"
+      33             : #include "tools/File.h"
+      34             : #include "tools/Grid.h"
+      35             : 
+      36             : 
+      37             : namespace PLMD {
+      38             : namespace ves {
+      39             : 
+      40             : //+PLUMEDOC VES_UTILS VES_OUTPUT_BASISFUNCTIONS
+      41             : /*
+      42             : Output basis functions to file.
+      43             : 
+      44             : This action can be used to write out to a grid file the values and derivatives of
+      45             : given basis functions. This is normally used for debugging when programming new
+      46             : types of basis functions. For example, it is possible to calculate the
+      47             : derivatives numerically and compare to the analytically calculated
+      48             : derivatives.
+      49             : 
+      50             : This action is normally used through the \ref driver.
+      51             : 
+      52             : \par Examples
+      53             : 
+      54             : In the following input we define a Legendre polynomials basis functions
+      55             : of order 14 over the interval -4.0 to 4.0 and output their values
+      56             : and derivatives to files called bfL.values.data and bfL.derivs.data.
+      57             : \plumedfile
+      58             : BF_LEGENDRE ...
+      59             :  ORDER=14
+      60             :  MINIMUM=-4.0
+      61             :  MAXIMUM=4.0
+      62             :  LABEL=bfL
+      63             : ... BF_LEGENDRE
+      64             : 
+      65             : VES_OUTPUT_BASISFUNCTIONS ...
+      66             :  BASIS_FUNCTIONS=bfL
+      67             :  GRID_BINS=200
+      68             :  FORMAT_VALUES_DERIVS=%13.6f
+      69             : ... VES_OUTPUT_BASISFUNCTIONS
+      70             : \endplumedfile
+      71             : 
+      72             : This input should be run through the driver by using a command similar to the
+      73             : following one where the trajectory/configuration file configuration.gro is needed to
+      74             : trick the code to exit correctly.
+      75             : \verbatim
+      76             : plumed driver --plumed plumed.dat --igro configuration.gro
+      77             : \endverbatim
+      78             : 
+      79             : */
+      80             : //+ENDPLUMEDOC
+      81             : 
+      82             : 
+      83             : class OutputBasisFunctions :
+      84             :   public Action
+      85             : {
+      86             :   std::vector<BasisFunctions*> bf_pntrs;
+      87             : public:
+      88             :   explicit OutputBasisFunctions(const ActionOptions&);
+      89             :   TargetDistribution* setupTargetDistPntr(std::string keyword) const;
+      90           0 :   void calculate() override {}
+      91           0 :   void apply() override {}
+      92             :   static void registerKeywords(Keywords& keys);
+      93             : };
+      94             : 
+      95             : 
+      96             : PLUMED_REGISTER_ACTION(OutputBasisFunctions,"VES_OUTPUT_BASISFUNCTIONS")
+      97             : 
+      98          73 : void OutputBasisFunctions::registerKeywords(Keywords& keys) {
+      99          73 :   Action::registerKeywords(keys);
+     100         146 :   keys.add("compulsory","BASIS_FUNCTIONS","the label of the basis functions that you want to use");
+     101         146 :   keys.add("optional","GRID_BINS","the number of bins used for the grid for writing the basis function values and derivatives. The default value is 1000.");
+     102         146 :   keys.add("optional","GRID_MIN","the minimum of the grid for writing the basis function values and derivatives. By default it is the minimum of the interval on which the basis functions are defined.");
+     103         146 :   keys.add("optional","GRID_MAX","the maximum of the grid for writing the basis function values and derivatives. By default it is the maximum of the interval on which the basis functions are defined.");
+     104         146 :   keys.add("optional","FILE_VALUES","filename of the file on which the basis function values are written. By default it is BF_LABEL.values.data.");
+     105         146 :   keys.add("optional","FILE_DERIVS","filename of the file on which the basis function derivatives are written. By default it is BF_LABEL.derivs.data.");
+     106         146 :   keys.add("optional","FORMAT_VALUES_DERIVS","the numerical format of the basis function values and derivatives written to file. By default it is %15.8f.\n. You can also use FORMAT_VALUES and FORMAT_DERIVS to give the numerical formats separately.");
+     107         146 :   keys.add("optional","FORMAT_VALUES","the numerical format of the basis function derivatives written to file. By default it is %15.8f.\n");
+     108         146 :   keys.add("optional","FORMAT_DERIVS","the numerical format of the basis function values written to file. By default it is %15.8f.\n");
+     109         146 :   keys.add("optional","FILE_TARGETDIST_AVERAGES","filename of the file on which the averages over the target distributions are written. By default it is BF_LABEL.targetdist-averages.data.");
+     110         146 :   keys.add("optional","FORMAT_TARGETDIST_AVERAGES","the numerical format of the target distribution averages written to file. By default it is %15.8f.\n");
+     111         146 :   keys.add("optional","FILE_TARGETDIST","filename of the files on which the target distributions are written. By default it is BF_LABEL.targetdist-#.data.");
+     112         146 :   keys.add("numbered","TARGET_DISTRIBUTION","the target distribution to be used.");
+     113         146 :   keys.addFlag("IGNORE_PERIODICITY",false,"if the periodicity of the basis functions should be ignored.");
+     114         146 :   keys.addFlag("NUMERICAL_DERIVATIVES",false,"if the derivatives of the basis functions should be calculated numerically.");
+     115          73 : }
+     116             : 
+     117          71 : OutputBasisFunctions::OutputBasisFunctions(const ActionOptions&ao):
+     118             :   Action(ao),
+     119          71 :   bf_pntrs(0)
+     120             : {
+     121          71 :   std::vector<std::string> basisset_labels(0);
+     122         142 :   parseVector("BASIS_FUNCTIONS",basisset_labels);
+     123          71 :   if(basisset_labels.size()>1) {plumed_merror("Only one basis set label allowed in keyword BASIS_FUNCTIONS of "+getName());}
+     124             : 
+     125          71 :   std::string error_msg = "";
+     126         142 :   bf_pntrs = VesTools::getPointersFromLabels<BasisFunctions*>(basisset_labels,plumed.getActionSet(),error_msg);
+     127          71 :   if(error_msg.size()>0) {plumed_merror("Error in keyword BASIS_FUNCTIONS of "+getName()+": "+error_msg);}
+     128             : 
+     129          71 :   unsigned int nbins = 1000;
+     130         142 :   parse("GRID_BINS",nbins);
+     131             : 
+     132          71 :   std::string min_str = bf_pntrs[0]->intervalMinStr();
+     133          71 :   std::string max_str = bf_pntrs[0]->intervalMaxStr();
+     134          71 :   parse("GRID_MIN",min_str);
+     135         142 :   parse("GRID_MAX",max_str);
+     136             : 
+     137          71 :   std::string fname_values = bf_pntrs[0]->getLabel()+".values.data";
+     138         142 :   parse("FILE_VALUES",fname_values);
+     139          71 :   std::string fname_derives = bf_pntrs[0]->getLabel()+".derivs.data";
+     140         142 :   parse("FILE_DERIVS",fname_derives);
+     141          71 :   std::string fname_targetdist_aver = bf_pntrs[0]->getLabel()+".targetdist-averages.data";
+     142         142 :   parse("FILE_TARGETDIST_AVERAGES",fname_targetdist_aver);
+     143          71 :   std::string fname_targetdist = bf_pntrs[0]->getLabel()+".targetdist-.data";
+     144          71 :   parse("FILE_TARGETDIST",fname_targetdist);
+     145             : 
+     146          71 :   std::string fmt_values_derivs = "%15.8f";
+     147          71 :   parse("FORMAT_VALUES_DERIVS",fmt_values_derivs);
+     148          71 :   std::string fmt_values = fmt_values_derivs;
+     149          71 :   std::string fmt_derivs = fmt_values_derivs;
+     150          71 :   parse("FORMAT_VALUES",fmt_values);
+     151          71 :   parse("FORMAT_DERIVS",fmt_derivs);
+     152             : 
+     153          71 :   std::string fmt_targetdist_aver = "%15.8f";
+     154          71 :   parse("FORMAT_TARGETDIST_AVERAGES",fmt_targetdist_aver);
+     155             : 
+     156          71 :   bool ignore_periodicity = false;
+     157          71 :   parseFlag("IGNORE_PERIODICITY",ignore_periodicity);
+     158             : 
+     159          71 :   bool numerical_deriv = false;
+     160         142 :   parseFlag("NUMERICAL_DERIVATIVES",numerical_deriv);
+     161             : 
+     162             :   std::vector<TargetDistribution*> targetdist_pntrs;
+     163          71 :   targetdist_pntrs.push_back(NULL);
+     164          71 :   std::string targetdist_label="";
+     165         176 :   for(int i=1;; i++) {
+     166         494 :     if(!parseNumbered("TARGET_DISTRIBUTION",i,targetdist_label)) {break;}
+     167         176 :     std::string error_msg = "";
+     168         176 :     TargetDistribution* pntr_tmp = VesTools::getPointerFromLabel<TargetDistribution*>(targetdist_label,plumed.getActionSet(),error_msg);
+     169         176 :     if(error_msg.size()>0) {plumed_merror("Error in keyword TARGET_DISTRIBUTION of "+getName()+": "+error_msg);}
+     170         176 :     targetdist_pntrs.push_back(pntr_tmp);
+     171         176 :   }
+     172          71 :   checkRead();
+     173             :   //
+     174          71 :   OFile ofile_values;
+     175          71 :   ofile_values.link(*this);
+     176          71 :   ofile_values.enforceBackup();
+     177          71 :   ofile_values.open(fname_values);
+     178          71 :   OFile ofile_derivs;
+     179          71 :   ofile_derivs.link(*this);
+     180          71 :   ofile_derivs.enforceBackup();
+     181          71 :   ofile_derivs.open(fname_derives);
+     182          71 :   bf_pntrs[0]->writeBasisFunctionsToFile(ofile_values,ofile_derivs,min_str,max_str,nbins,ignore_periodicity,fmt_values,fmt_derivs,numerical_deriv);
+     183          71 :   ofile_values.close();
+     184          71 :   ofile_derivs.close();
+     185             :   //
+     186          71 :   std::vector<std::string> grid_min(1); grid_min[0]=bf_pntrs[0]->intervalMinStr();
+     187          71 :   std::vector<std::string> grid_max(1); grid_max[0]=bf_pntrs[0]->intervalMaxStr();
+     188          71 :   std::vector<unsigned int> grid_bins(1); grid_bins[0]=nbins;
+     189          71 :   std::vector<std::unique_ptr<Value>> arguments(1);
+     190         142 :   arguments[0]= Tools::make_unique<Value>(nullptr,"arg",false);
+     191          71 :   if(bf_pntrs[0]->arePeriodic() && !ignore_periodicity) {
+     192          46 :     arguments[0]->setDomain(bf_pntrs[0]->intervalMinStr(),bf_pntrs[0]->intervalMaxStr());
+     193             :   }
+     194             :   else {
+     195          48 :     arguments[0]->setNotPeriodic();
+     196             :   }
+     197             : 
+     198          71 :   OFile ofile_targetdist_aver;
+     199          71 :   ofile_targetdist_aver.link(*this);
+     200          71 :   ofile_targetdist_aver.enforceBackup();
+     201          71 :   ofile_targetdist_aver.open(fname_targetdist_aver);
+     202             : 
+     203         318 :   for(unsigned int i=0; i<targetdist_pntrs.size(); i++) {
+     204         247 :     std::string is; Tools::convert(i,is);
+     205             :     //
+     206         247 :     if(targetdist_pntrs[i]!=NULL) {
+     207         352 :       targetdist_pntrs[i]->setupGrids(Tools::unique2raw(arguments),grid_min,grid_max,grid_bins);
+     208         176 :       plumed_massert(targetdist_pntrs[i]->getDimension()==1,"the target distribution must be one dimensional");
+     209         176 :       targetdist_pntrs[i]->updateTargetDist();
+     210             :     }
+     211             :     //
+     212         247 :     std::vector<double> bf_integrals = bf_pntrs[0]->getTargetDistributionIntegrals(targetdist_pntrs[i]);
+     213         494 :     CoeffsVector targetdist_averages = CoeffsVector("aver.targetdist-"+is,Tools::unique2raw(arguments),bf_pntrs,comm,false);
+     214         247 :     targetdist_averages.setValues(bf_integrals);
+     215         247 :     if(fmt_targetdist_aver.size()>0) {targetdist_averages.setOutputFmt(fmt_targetdist_aver);}
+     216         247 :     targetdist_averages.writeToFile(ofile_targetdist_aver,true);
+     217         247 :     if(targetdist_pntrs[i]!=NULL) {
+     218             :       Grid* targetdist_grid_pntr = targetdist_pntrs[i]->getTargetDistGridPntr();
+     219         176 :       std::string fname = FileBase::appendSuffix(fname_targetdist,is);
+     220         176 :       OFile ofile;
+     221         176 :       ofile.link(*this);
+     222         176 :       ofile.enforceBackup();
+     223         176 :       ofile.open(fname);
+     224         176 :       targetdist_grid_pntr->writeToFile(ofile);
+     225         176 :       ofile.close();
+     226         176 :     }
+     227         247 :   }
+     228          71 :   ofile_targetdist_aver.close();
+     229             : 
+     230             : 
+     231         213 : }
+     232             : 
+     233             : 
+     234             : 
+     235             : }
+     236             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/OutputFesBias.cpp.func-sort-c.html b/coverage/ves/OutputFesBias.cpp.func-sort-c.html new file mode 100644 index 000000000000..732c04a4d347 --- /dev/null +++ b/coverage/ves/OutputFesBias.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - ves/OutputFesBias.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - OutputFesBias.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:606888.2 %
Date:2024-04-19 12:12:35Functions:2540.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves13OutputFesBias5applyEv0
_ZN4PLMD3ves13OutputFesBias6updateEv0
_ZN4PLMD3ves13OutputFesBias9calculateEv0
_ZN4PLMD3ves13OutputFesBiasC2ERKNS_13ActionOptionsE3
_ZN4PLMD3ves13OutputFesBias16registerKeywordsERNS_8KeywordsE5
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/OutputFesBias.cpp.func.html b/coverage/ves/OutputFesBias.cpp.func.html new file mode 100644 index 000000000000..87a727ea412d --- /dev/null +++ b/coverage/ves/OutputFesBias.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - ves/OutputFesBias.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - OutputFesBias.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:606888.2 %
Date:2024-04-19 12:12:35Functions:2540.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves13OutputFesBias16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD3ves13OutputFesBias5applyEv0
_ZN4PLMD3ves13OutputFesBias6updateEv0
_ZN4PLMD3ves13OutputFesBias9calculateEv0
_ZN4PLMD3ves13OutputFesBiasC2ERKNS_13ActionOptionsE3
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/OutputFesBias.cpp.gcov.html b/coverage/ves/OutputFesBias.cpp.gcov.html new file mode 100644 index 000000000000..b4a05738b8c7 --- /dev/null +++ b/coverage/ves/OutputFesBias.cpp.gcov.html @@ -0,0 +1,307 @@ + + + + + + + + LCOV - plumed test coverage - ves/OutputFesBias.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - OutputFesBias.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:606888.2 %
Date:2024-04-19 12:12:35Functions:2540.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "CoeffsVector.h"
+      24             : #include "VesTools.h"
+      25             : #include "VesBias.h"
+      26             : 
+      27             : 
+      28             : #include "tools/File.h"
+      29             : #include "core/ActionRegister.h"
+      30             : #include "core/PlumedMain.h"
+      31             : 
+      32             : 
+      33             : namespace PLMD {
+      34             : namespace ves {
+      35             : 
+      36             : //+PLUMEDOC VES_UTILS VES_OUTPUT_FES
+      37             : /*
+      38             : Tool to output biases and free energy surfaces for VES biases from previously obtained coefficients.
+      39             : 
+      40             : This action can be used to output to file biases and free energy surfaces for VES biases from
+      41             : previously obtained coefficients. It should be used through the \ref driver and
+      42             : can only be used in post processing. The VES bias needs to be defined in the
+      43             : exact same way as during the simulation. At the current moment this action does
+      44             : not support dynamic target distributions (e.g. well-tempered).
+      45             : 
+      46             : \par Examples
+      47             : 
+      48             : In the following input we define a VES bias and then read in the coefficient
+      49             : file coeffs.input.data and output the FES and bias every 500 iterations.
+      50             : 
+      51             : \plumedfile
+      52             : phi:   TORSION ATOMS=5,7,9,15
+      53             : psi:   TORSION ATOMS=7,9,15,17
+      54             : 
+      55             : bf1: BF_FOURIER ORDER=5 MINIMUM=-pi MAXIMUM=pi
+      56             : bf2: BF_FOURIER ORDER=5 MINIMUM=-pi MAXIMUM=pi
+      57             : 
+      58             : VES_LINEAR_EXPANSION ...
+      59             :  ARG=phi,psi
+      60             :  BASIS_FUNCTIONS=bf1,bf2
+      61             :  LABEL=ves1
+      62             :  GRID_BINS=100,100
+      63             :  PROJ_ARG1=phi
+      64             :  PROJ_ARG2=psi
+      65             : ... VES_LINEAR_EXPANSION
+      66             : 
+      67             : VES_OUTPUT_FES ...
+      68             :   BIAS=ves1
+      69             :   FES_OUTPUT=500
+      70             :   FES_PROJ_OUTPUT=500
+      71             :   BIAS_OUTPUT=500
+      72             :   COEFFS_INPUT=coeffs.input.data
+      73             : ... VES_OUTPUT_FES
+      74             : \endplumedfile
+      75             : 
+      76             : The header of coeffs.input.data should look like the following:
+      77             : 
+      78             : \auxfile{coeffs.input.data}
+      79             : #! FIELDS idx_phi idx_psi ves1.coeffs ves1.aux_coeffs index
+      80             : #! SET time 100.000000
+      81             : #! SET iteration  10
+      82             : #! SET type LinearBasisSet
+      83             : #! SET ndimensions  2
+      84             : #! SET ncoeffs_total  121
+      85             : #! SET shape_phi  11
+      86             : #! SET shape_psi  11
+      87             : \endauxfile
+      88             : 
+      89             : This input should be run through the driver by using a command similar to the
+      90             : following one where the trajectory/configuration file configuration.gro is needed to
+      91             : correctly define the CVs
+      92             : \verbatim
+      93             : plumed driver --plumed plumed.dat --igro configuration.gro
+      94             : \endverbatim
+      95             : 
+      96             : */
+      97             : //+ENDPLUMEDOC
+      98             : 
+      99             : class OutputFesBias : public Action {
+     100             : 
+     101             : public:
+     102             :   static void registerKeywords(Keywords&);
+     103             :   explicit OutputFesBias(const ActionOptions&);
+     104           0 :   void update() override {}
+     105           0 :   void calculate() override {}
+     106           0 :   void apply() override {}
+     107             : };
+     108             : 
+     109             : 
+     110             : PLUMED_REGISTER_ACTION(OutputFesBias,"VES_OUTPUT_FES")
+     111             : 
+     112             : 
+     113           5 : void OutputFesBias::registerKeywords(Keywords& keys) {
+     114          10 :   keys.add("compulsory","BIAS","the label of the VES bias for to output the free energy surfaces and the bias files");
+     115          10 :   keys.add("compulsory","COEFFS_INPUT","the name of input coefficient file");
+     116          10 :   keys.add("optional","BIAS_OUTPUT","how often the bias(es) should be written out to file. Note that the value is given in terms of coefficient iterations.");
+     117          10 :   keys.add("optional","FES_OUTPUT","how often the FES(s) should be written out to file. Note that the value is given in terms of coefficient iterations.");
+     118          10 :   keys.add("optional","FES_PROJ_OUTPUT","how often the projections of the FES(s) should be written out to file. Note that the value is given in terms of coefficient iterations.");
+     119             :   //
+     120           5 : }
+     121             : 
+     122             : 
+     123           3 : OutputFesBias::OutputFesBias(const ActionOptions&ao):
+     124           3 :   Action(ao)
+     125             : {
+     126             : 
+     127             :   std::vector<std::string> bias_labels;
+     128           6 :   parseVector("BIAS",bias_labels);
+     129           3 :   if(bias_labels.size()>1) {
+     130           0 :     plumed_merror(getName()+" only support one VES bias");
+     131             :   }
+     132             : 
+     133           3 :   std::string error_msg = "";
+     134           3 :   std::vector<VesBias*> bias_pntrs = VesTools::getPointersFromLabels<VesBias*>(bias_labels,plumed.getActionSet(),error_msg);
+     135           3 :   if(error_msg.size()>0) {plumed_merror("Error in keyword BIAS of "+getName()+": "+error_msg);}
+     136             : 
+     137           6 :   for(unsigned int i=0; i<bias_pntrs.size(); i++) {
+     138           3 :     if(bias_pntrs[i]->numberOfCoeffsSets()>1) {
+     139           0 :       plumed_merror(getName()+" at the moment supports only VES biases with a single coefficient set");
+     140             :     }
+     141             :   }
+     142             : 
+     143             :   std::vector<std::string> coeffs_fnames;
+     144           6 :   parseVector("COEFFS_INPUT",coeffs_fnames);
+     145           3 :   if(coeffs_fnames.size()!=bias_pntrs.size()) {
+     146           0 :     plumed_merror(getName()+": there have to be as many coefficient file given in COEFFS_INPUT as VES biases given in BIAS");
+     147             :   }
+     148             : 
+     149           3 :   unsigned int bias_output_stride = 0;
+     150           3 :   parse("BIAS_OUTPUT",bias_output_stride);
+     151             : 
+     152           3 :   unsigned int fes_output_stride = 0;
+     153           3 :   parse("FES_OUTPUT",fes_output_stride);
+     154             : 
+     155           3 :   unsigned int fesproj_output_stride = 0;
+     156           3 :   parse("FES_PROJ_OUTPUT",fesproj_output_stride);
+     157             : 
+     158           3 :   if(bias_output_stride == 0 && fes_output_stride == 0 && fesproj_output_stride == 0) {
+     159           0 :     plumed_merror(getName()+": you are not telling the action to do anything, you need to use one of the keywords BIAS_OUTPUT, FES_OUTPUT, or FES_PROJ_OUTPUT");
+     160             :   }
+     161             : 
+     162           3 :   checkRead();
+     163             : 
+     164           6 :   for(unsigned int i=0; i<bias_pntrs.size(); i++) {
+     165             : 
+     166           3 :     if(bias_pntrs[i]->dynamicTargetDistribution()) {
+     167           0 :       plumed_merror(getName()+" does not support dynamic target distributions at the moment");
+     168             :     }
+     169             : 
+     170           3 :     if(bias_pntrs[i]->isStaticTargetDistFileOutputActive()) {
+     171           2 :       bias_pntrs[i]->setupTargetDistFileOutput();
+     172           2 :       bias_pntrs[i]->writeTargetDistToFile();
+     173           2 :       bias_pntrs[i]->setupTargetDistProjFileOutput();
+     174           2 :       bias_pntrs[i]->writeTargetDistProjToFile();
+     175             :     }
+     176             : 
+     177             : 
+     178           3 :     if(bias_output_stride>0) {
+     179           3 :       bias_pntrs[i]->enableBiasFileOutput();
+     180           3 :       bias_pntrs[i]->setupBiasFileOutput();
+     181             :     }
+     182             : 
+     183           3 :     if(fes_output_stride>0) {
+     184           3 :       bias_pntrs[i]->enableFesFileOutput();
+     185           3 :       bias_pntrs[i]->setupFesFileOutput();
+     186             :     }
+     187             : 
+     188           3 :     if(fesproj_output_stride>0) {
+     189           1 :       bias_pntrs[i]->enableFesProjFileOutput();
+     190           1 :       bias_pntrs[i]->setupFesProjFileOutput();
+     191             :     }
+     192             : 
+     193           3 :     bias_pntrs[i]->enableIterationNumberInFilenames();
+     194             : 
+     195           3 :     IFile ifile;
+     196           3 :     ifile.open(coeffs_fnames[i]);
+     197             : 
+     198          39 :     while(ifile) {
+     199             : 
+     200          36 :       bias_pntrs[i]->resetBiasFileOutput();
+     201          36 :       bias_pntrs[i]->resetFesFileOutput();
+     202             : 
+     203          72 :       if(bias_pntrs[i]->getCoeffsPntrs()[0]->readOneSetFromFile(ifile)>0) {
+     204          33 :         unsigned int iteration = bias_pntrs[i]->getCoeffsPntrs()[0]->getIterationCounter();
+     205             : 
+     206          33 :         if(bias_output_stride>0 && iteration%bias_output_stride==0) {
+     207           8 :           bias_pntrs[i]->writeBiasToFile();
+     208             :         }
+     209             : 
+     210          33 :         if(fes_output_stride>0 && iteration%fes_output_stride==0) {
+     211           8 :           bias_pntrs[i]->writeFesToFile();
+     212             :         }
+     213             : 
+     214          33 :         if(fesproj_output_stride>0 && iteration%fesproj_output_stride==0) {
+     215           3 :           bias_pntrs[i]->writeFesProjToFile();
+     216             :         }
+     217             : 
+     218             :       }
+     219             : 
+     220             :     }
+     221             : 
+     222           3 :   }
+     223             : 
+     224           3 :   log.printf("Stopping");
+     225           3 :   plumed.stop();
+     226           6 : }
+     227             : 
+     228             : 
+     229             : }
+     230             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/OutputTargetDistribution.cpp.func-sort-c.html b/coverage/ves/OutputTargetDistribution.cpp.func-sort-c.html new file mode 100644 index 000000000000..b96d1cef5183 --- /dev/null +++ b/coverage/ves/OutputTargetDistribution.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - ves/OutputTargetDistribution.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - OutputTargetDistribution.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:838993.3 %
Date:2024-04-19 12:12:35Functions:2450.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves24OutputTargetDistribution5applyEv0
_ZN4PLMD3ves24OutputTargetDistribution9calculateEv0
_ZN4PLMD3ves24OutputTargetDistributionC2ERKNS_13ActionOptionsE120
_ZN4PLMD3ves24OutputTargetDistribution16registerKeywordsERNS_8KeywordsE122
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/OutputTargetDistribution.cpp.func.html b/coverage/ves/OutputTargetDistribution.cpp.func.html new file mode 100644 index 000000000000..8a5ecb15283a --- /dev/null +++ b/coverage/ves/OutputTargetDistribution.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - ves/OutputTargetDistribution.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - OutputTargetDistribution.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:838993.3 %
Date:2024-04-19 12:12:35Functions:2450.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves24OutputTargetDistribution16registerKeywordsERNS_8KeywordsE122
_ZN4PLMD3ves24OutputTargetDistribution5applyEv0
_ZN4PLMD3ves24OutputTargetDistribution9calculateEv0
_ZN4PLMD3ves24OutputTargetDistributionC2ERKNS_13ActionOptionsE120
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/OutputTargetDistribution.cpp.gcov.html b/coverage/ves/OutputTargetDistribution.cpp.gcov.html new file mode 100644 index 000000000000..14e4f9cb9caa --- /dev/null +++ b/coverage/ves/OutputTargetDistribution.cpp.gcov.html @@ -0,0 +1,303 @@ + + + + + + + + LCOV - plumed test coverage - ves/OutputTargetDistribution.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - OutputTargetDistribution.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:838993.3 %
Date:2024-04-19 12:12:35Functions:2450.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "TargetDistribution.h"
+      24             : 
+      25             : #include "GridIntegrationWeights.h"
+      26             : #include "VesTools.h"
+      27             : 
+      28             : #include "core/ActionRegister.h"
+      29             : #include "core/PlumedMain.h"
+      30             : #include "core/Value.h"
+      31             : #include "tools/File.h"
+      32             : #include "tools/Grid.h"
+      33             : 
+      34             : 
+      35             : namespace PLMD {
+      36             : namespace ves {
+      37             : 
+      38             : //+PLUMEDOC VES_UTILS VES_OUTPUT_TARGET_DISTRIBUTION
+      39             : /*
+      40             : Output target distribution to file.
+      41             : 
+      42             : This action can be used to output target distributions to a grid file,
+      43             : for example to see how they look like before using them in a VES bias.
+      44             : This action only support static target distributions.
+      45             : 
+      46             : This action is normally used through the \ref driver.
+      47             : 
+      48             : 
+      49             : \par Examples
+      50             : 
+      51             : In the following input we define a target distribution that is uniform for
+      52             : argument 1 and a Gaussian for argument 2 and then output it to a file
+      53             : called targetdist-1.data.
+      54             : \plumedfile
+      55             : t1_1: TD_UNIFORM  MINIMA=-4.0  MAXIMA=+4.0
+      56             : t1_2: TD_GAUSSIAN  CENTER1=-2.0  SIGMA1=0.5
+      57             : t1: TD_PRODUCT_DISTRIBUTION  DISTRIBUTIONS=t1_1,t1_2
+      58             : 
+      59             : VES_OUTPUT_TARGET_DISTRIBUTION ...
+      60             :  GRID_MIN=-4.0,-4.0
+      61             :  GRID_MAX=+4.0,+4.0
+      62             :  GRID_BINS=100,100
+      63             :  TARGET_DISTRIBUTION=t1
+      64             :  TARGETDIST_FILE=targetdist-1.data
+      65             :  LOG_TARGETDIST_FILE=targetdist-1.log.data
+      66             :  FMT_GRIDS=%11.6f
+      67             : ... VES_OUTPUT_TARGET_DISTRIBUTION
+      68             : \endplumedfile
+      69             : 
+      70             : This input should be run through the driver by using a command similar to the
+      71             : following one where the trajectory/configuration file configuration.gro is needed to
+      72             : trick the code to exit correctly.
+      73             : \verbatim
+      74             : plumed driver --plumed plumed.dat --igro configuration.gro
+      75             : \endverbatim
+      76             : 
+      77             : */
+      78             : //+ENDPLUMEDOC
+      79             : 
+      80             : 
+      81             : class OutputTargetDistribution :
+      82             :   public Action
+      83             : {
+      84             : public:
+      85             :   explicit OutputTargetDistribution(const ActionOptions&);
+      86           0 :   void calculate() override {}
+      87           0 :   void apply() override {}
+      88             :   static void registerKeywords(Keywords& keys);
+      89             : };
+      90             : 
+      91             : 
+      92             : PLUMED_REGISTER_ACTION(OutputTargetDistribution,"VES_OUTPUT_TARGET_DISTRIBUTION")
+      93             : 
+      94         122 : void OutputTargetDistribution::registerKeywords(Keywords& keys) {
+      95         122 :   Action::registerKeywords(keys);
+      96         244 :   keys.add("compulsory","GRID_MIN","the lower bounds for the grid");
+      97         244 :   keys.add("compulsory","GRID_MAX","the upper bounds for the grid");
+      98         244 :   keys.add("compulsory","GRID_BINS","the number of bins used for the grid.");
+      99         244 :   keys.add("optional","GRID_PERIODICITY","specify if the individual arguments should be made periodic (YES) or not (NO). By default all arguments are taken as not periodic.");
+     100         244 :   keys.add("compulsory","TARGETDIST_FILE","filename of the file for writing the target distribution");
+     101         244 :   keys.add("optional","LOG_TARGETDIST_FILE","filename of the file for writing the log of the target distribution");
+     102         244 :   keys.add("compulsory","TARGET_DISTRIBUTION","the target distribution to be used.");
+     103         244 :   keys.add("optional","FMT_GRIDS","the numerical format of the target distribution grids written to file. By default it is %14.9f");
+     104         244 :   keys.addFlag("DO_1D_PROJECTIONS",false,"Also output the one-dimensional marginal distributions for multi-dimensional target distribution.");
+     105         122 : }
+     106             : 
+     107         120 : OutputTargetDistribution::OutputTargetDistribution(const ActionOptions&ao):
+     108         120 :   Action(ao)
+     109             : {
+     110             : 
+     111             :   std::string targetdist_fname;
+     112         240 :   parse("TARGETDIST_FILE",targetdist_fname);
+     113             :   std::string log_targetdist_fname;
+     114         120 :   parse("LOG_TARGETDIST_FILE",log_targetdist_fname);
+     115         120 :   if(targetdist_fname==log_targetdist_fname) {
+     116           0 :     plumed_merror("error in " + getName() + ":TARGETDIST_FILE and LOG_TARGETDIST_FILE cannot be the same");
+     117             :   }
+     118             : 
+     119             :   std::vector<unsigned int> grid_bins;
+     120         240 :   parseVector("GRID_BINS",grid_bins);
+     121         120 :   unsigned int nargs = grid_bins.size();
+     122             : 
+     123         120 :   std::vector<std::string> grid_min(nargs);
+     124         120 :   parseVector("GRID_MIN",grid_min);
+     125         120 :   std::vector<std::string> grid_max(nargs);
+     126         120 :   parseVector("GRID_MAX",grid_max);
+     127             : 
+     128         120 :   std::vector<std::string> grid_periodicity(nargs);
+     129         240 :   parseVector("GRID_PERIODICITY",grid_periodicity);
+     130         232 :   if(grid_periodicity.size()==0) {grid_periodicity.assign(nargs,"NO");}
+     131             : 
+     132         120 :   std::string fmt_grids="%14.9f";
+     133         120 :   parse("FMT_GRIDS",fmt_grids);
+     134             : 
+     135         120 :   bool do_1d_proj = false;
+     136         120 :   parseFlag("DO_1D_PROJECTIONS",do_1d_proj);
+     137         120 :   if(do_1d_proj && nargs==1) {
+     138           0 :     plumed_merror("doesn't make sense to use the DO_1D_PROJECTIONS keyword for a one-dimensional distribution");
+     139             :   }
+     140             : 
+     141         120 :   plumed_massert(grid_min.size()==nargs,"mismatch between number of values given for grid parameters");
+     142         120 :   plumed_massert(grid_max.size()==nargs,"mismatch between number of values given for grid parameters");
+     143         120 :   plumed_massert(grid_periodicity.size()==nargs,"mismatch between number of values given for grid parameters");
+     144             : 
+     145             :   std::string targetdist_label;
+     146         120 :   parse("TARGET_DISTRIBUTION",targetdist_label);
+     147         120 :   checkRead();
+     148             :   //
+     149         120 :   std::vector<std::unique_ptr<Value>> arguments(nargs);
+     150         287 :   for(unsigned int i=0; i < nargs; i++) {
+     151         167 :     std::string is; Tools::convert(i+1,is);
+     152         167 :     if(nargs==1) {is="";}
+     153         167 :     arguments[i]= Tools::make_unique<Value>(nullptr,"arg"+is,false);
+     154         167 :     if(grid_periodicity[i]=="YES") {
+     155          11 :       arguments[i]->setDomain(grid_min[i],grid_max[i]);
+     156             :     }
+     157         156 :     else if(grid_periodicity[i]=="NO") {
+     158         156 :       arguments[i]->setNotPeriodic();
+     159             :     }
+     160             :     else {
+     161           0 :       plumed_merror("wrong value given in GRID_PERIODICITY, either specify YES or NO");
+     162             :     }
+     163             :   }
+     164             : 
+     165         120 :   std::string error_msg = "";
+     166         120 :   TargetDistribution* targetdist_pntr = VesTools::getPointerFromLabel<TargetDistribution*>(targetdist_label,plumed.getActionSet(),error_msg);
+     167         120 :   if(error_msg.size()>0) {plumed_merror("Error in keyword TARGET_DISTRIBUTION of "+getName()+": "+error_msg);}
+     168             :   //
+     169         120 :   if(targetdist_pntr->isDynamic()) {
+     170           0 :     plumed_merror(getName() + " only works for static target distributions");
+     171             :   }
+     172         120 :   targetdist_pntr->setupGrids(Tools::unique2raw(arguments),grid_min,grid_max,grid_bins);
+     173         120 :   targetdist_pntr->updateTargetDist();
+     174             :   Grid* targetdist_grid_pntr = targetdist_pntr->getTargetDistGridPntr();
+     175             :   Grid* log_targetdist_grid_pntr = targetdist_pntr->getLogTargetDistGridPntr();
+     176             : 
+     177             : 
+     178         120 :   double sum_grid = TargetDistribution::integrateGrid(targetdist_grid_pntr);
+     179         120 :   log.printf("  target distribution integrated over the grid: %16.12f\n",sum_grid);
+     180         120 :   log.printf("                                                (%30.16e)\n",sum_grid);
+     181             :   //
+     182         120 :   OFile ofile;
+     183         120 :   ofile.link(*this);
+     184         120 :   ofile.enforceBackup();
+     185         120 :   ofile.open(targetdist_fname);
+     186             :   targetdist_grid_pntr->setOutputFmt(fmt_grids);
+     187         120 :   targetdist_grid_pntr->writeToFile(ofile);
+     188         120 :   ofile.close();
+     189         120 :   if(log_targetdist_fname.size()>0) {
+     190          23 :     OFile ofile2;
+     191          23 :     ofile2.link(*this);
+     192          23 :     ofile2.enforceBackup();
+     193          23 :     ofile2.open(log_targetdist_fname);
+     194             :     log_targetdist_grid_pntr->setOutputFmt(fmt_grids);
+     195          23 :     log_targetdist_grid_pntr->writeToFile(ofile2);
+     196          23 :     ofile2.close();
+     197          23 :   }
+     198             : 
+     199         120 :   if(do_1d_proj) {
+     200          12 :     for(unsigned int i=0; i<nargs; i++) {
+     201           8 :       std::vector<std::string> arg1d(1);
+     202           8 :       arg1d[0] = arguments[i]->getName();
+     203           8 :       Grid marginal_grid = targetdist_pntr->getMarginal(arg1d);
+     204             :       //
+     205             :       std::string suffix;
+     206           8 :       Tools::convert(i+1,suffix);
+     207           8 :       suffix = "proj-" + suffix;
+     208           8 :       std::string marginal_fname = FileBase::appendSuffix(targetdist_fname,"."+suffix);
+     209             :       //
+     210           8 :       OFile ofile3;
+     211           8 :       ofile3.link(*this);
+     212           8 :       ofile3.enforceBackup();
+     213           8 :       ofile3.open(marginal_fname);
+     214             :       marginal_grid.setOutputFmt(fmt_grids);
+     215           8 :       marginal_grid.writeToFile(ofile3);
+     216          16 :     }
+     217             :   }
+     218             : 
+     219         480 : }
+     220             : 
+     221             : 
+     222             : 
+     223             : 
+     224             : 
+     225             : }
+     226             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_Chi.cpp.func-sort-c.html b/coverage/ves/TD_Chi.cpp.func-sort-c.html new file mode 100644 index 000000000000..20ebc03d76a3 --- /dev/null +++ b/coverage/ves/TD_Chi.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_Chi.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_Chi.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4040100.0 %
Date:2024-04-19 12:12:35Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves6TD_ChiC2ERKNS_13ActionOptionsE9
_ZN4PLMD3ves6TD_Chi16registerKeywordsERNS_8KeywordsE11
_ZNK4PLMD3ves6TD_Chi8getValueERKSt6vectorIdSaIdEE1509
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_Chi.cpp.func.html b/coverage/ves/TD_Chi.cpp.func.html new file mode 100644 index 000000000000..b52103735a20 --- /dev/null +++ b/coverage/ves/TD_Chi.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_Chi.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_Chi.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4040100.0 %
Date:2024-04-19 12:12:35Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves6TD_Chi16registerKeywordsERNS_8KeywordsE11
_ZN4PLMD3ves6TD_ChiC2ERKNS_13ActionOptionsE9
_ZNK4PLMD3ves6TD_Chi8getValueERKSt6vectorIdSaIdEE1509
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_Chi.cpp.gcov.html b/coverage/ves/TD_Chi.cpp.gcov.html new file mode 100644 index 000000000000..19b0b73cd8f2 --- /dev/null +++ b/coverage/ves/TD_Chi.cpp.gcov.html @@ -0,0 +1,230 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_Chi.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_Chi.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4040100.0 %
Date:2024-04-19 12:12:35Functions:33100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "TargetDistribution.h"
+      24             : 
+      25             : #include "core/ActionRegister.h"
+      26             : 
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace ves {
+      30             : 
+      31             : //+PLUMEDOC VES_TARGETDIST TD_CHI
+      32             : /*
+      33             : Chi distribution (static).
+      34             : 
+      35             : Employ a target distribution given by a
+      36             : [chi distribution](https://en.wikipedia.org/wiki/Chi_distribution)
+      37             : that is defined as
+      38             : \f[
+      39             : p(s) =
+      40             : \frac
+      41             : {2^{1-\frac{k}{2}}}
+      42             : {\sigma \, \Gamma\left(\frac{k}{2}\right) }
+      43             : \, \left(\frac{s-a}{\sigma}\right)^{k-1} \, \exp\left(- \frac{1}{2} \left(\frac{s-a}{\sigma}\right)^2\right),
+      44             : \f]
+      45             : where \f$a\f$ is the minimum of the distribution that is defined on the interval \f$[a,\infty)\f$,
+      46             : the parameter \f$k\f$ (given as a positive integer larger than 1) determines how far
+      47             : the peak of the distribution is from the minimum (known as the "degrees of freedom"),
+      48             : and the parameter \f$\sigma>0\f$ determines the broadness of the distribution.
+      49             : 
+      50             : The minimum \f$a\f$ is given using the MINIMUM keyword, the parameter \f$k\f$ is given
+      51             : using the KAPPA keyword, and the parameter \f$\sigma\f$ is given using the SIGMA keyword.
+      52             : 
+      53             : This target distribution action is only defined for one dimension, for multiple dimensions
+      54             : it should be used in combination with the \ref TD_PRODUCT_DISTRIBUTION action.
+      55             : 
+      56             : 
+      57             : \par Examples
+      58             : 
+      59             : Chi distribution with \f$a=10.0\f$, \f$\sigma=2.0\f$, and \f$k=2\f$
+      60             : \plumedfile
+      61             : td: TD_CHI  MINIMUM=10.0  SIGMA=2.0  KAPPA=2
+      62             : \endplumedfile
+      63             : 
+      64             : The Chi distribution is only defined for one dimension so for multiple
+      65             : dimensions we have to use it in combination with the \ref TD_PRODUCT_DISTRIBUTION action as shown in
+      66             : the following example where we have a uniform distribution for argument 1 and
+      67             : a Chi distribution for argument 1
+      68             : \plumedfile
+      69             : td_uni: TD_UNIFORM
+      70             : 
+      71             : td_chi: TD_CHI  MINIMUM=-10.0  SIGMA=2.0  KAPPA=2
+      72             : 
+      73             : td_pd: TD_PRODUCT_DISTRIBUTION DISTRIBUTIONS=td_uni,td_chi
+      74             : \endplumedfile
+      75             : 
+      76             : */
+      77             : //+ENDPLUMEDOC
+      78             : 
+      79             : class TD_Chi: public TargetDistribution {
+      80             :   std::vector<double> minima_;
+      81             :   std::vector<double> sigma_;
+      82             :   std::vector<double> kappa_;
+      83             :   std::vector<double> normalization_;
+      84             : public:
+      85             :   static void registerKeywords(Keywords&);
+      86             :   explicit TD_Chi(const ActionOptions& ao);
+      87             :   double getValue(const std::vector<double>&) const override;
+      88             : };
+      89             : 
+      90             : 
+      91             : PLUMED_REGISTER_ACTION(TD_Chi,"TD_CHI")
+      92             : 
+      93             : 
+      94          11 : void TD_Chi::registerKeywords(Keywords& keys) {
+      95          11 :   TargetDistribution::registerKeywords(keys);
+      96          22 :   keys.add("compulsory","MINIMUM","The minimum of the chi distribution.");
+      97          22 :   keys.add("compulsory","SIGMA","The sigma parameter of the chi distribution given as a positive number.");
+      98          22 :   keys.add("compulsory","KAPPA","The k parameter of the chi distribution given as positive integer larger than 1.");
+      99          11 :   keys.use("WELLTEMPERED_FACTOR");
+     100          11 :   keys.use("SHIFT_TO_ZERO");
+     101          11 :   keys.use("NORMALIZE");
+     102          11 : }
+     103             : 
+     104             : 
+     105           9 : TD_Chi::TD_Chi(const ActionOptions& ao):
+     106             :   PLUMED_VES_TARGETDISTRIBUTION_INIT(ao),
+     107          18 :   minima_(0),
+     108           9 :   sigma_(0),
+     109           9 :   kappa_(0),
+     110          18 :   normalization_(0)
+     111             : {
+     112           9 :   parseVector("MINIMUM",minima_);
+     113           9 :   parseVector("SIGMA",sigma_);
+     114          18 :   for(unsigned int k=0; k<sigma_.size(); k++) {
+     115           9 :     if(sigma_[k] < 0.0) {plumed_merror(getName()+": the value given in SIGMA should be positive.");}
+     116             :   }
+     117             : 
+     118             : 
+     119           9 :   std::vector<unsigned int> kappa_int(0);
+     120          18 :   parseVector("KAPPA",kappa_int);
+     121           9 :   if(kappa_int.size()==0) {plumed_merror(getName()+": some problem with KAPPA keyword, should given as positive integer larger than 1");}
+     122           9 :   kappa_.resize(kappa_int.size());
+     123          18 :   for(unsigned int k=0; k<kappa_int.size(); k++) {
+     124           9 :     if(kappa_int[k] < 1) {plumed_merror(getName()+": KAPPA should be an integer 1 or higher");}
+     125           9 :     kappa_[k] = static_cast<double>(kappa_int[k]);
+     126             :   }
+     127             : 
+     128           9 :   setDimension(minima_.size());
+     129           9 :   if(getDimension()>1) {plumed_merror(getName()+": only defined for one dimension, for multiple dimensions it should be used in combination with the TD_PRODUCT_DISTRIBUTION action.");}
+     130           9 :   if(sigma_.size()!=getDimension()) {plumed_merror(getName()+": the SIGMA keyword does not match the given dimension in MINIMUM");}
+     131           9 :   if(kappa_.size()!=getDimension()) {plumed_merror(getName()+": the KAPPA keyword does not match the given dimension in MINIMUM");}
+     132             : 
+     133           9 :   normalization_.resize(getDimension());
+     134          18 :   for(unsigned int k=0; k<getDimension(); k++) {
+     135           9 :     normalization_[k] = pow(2.0,(1.0-0.5*kappa_[k]))/(tgamma(0.5*kappa_[k])*sigma_[k]);
+     136             :   }
+     137           9 :   checkRead();
+     138           9 : }
+     139             : 
+     140             : 
+     141        1509 : double TD_Chi::getValue(const std::vector<double>& argument) const {
+     142             :   double value = 1.0;
+     143        3018 :   for(unsigned int k=0; k<argument.size(); k++) {
+     144        1509 :     double arg=(argument[k]-minima_[k])/sigma_[k];
+     145        1509 :     if(arg<0.0) {plumed_merror(getName()+": the chi distribution is not defined for values less that ones given in MINIMUM");}
+     146        1509 :     value *= normalization_[k] * pow(arg,kappa_[k]-1.0) * exp(-0.5*arg*arg);
+     147             :   }
+     148        1509 :   return value;
+     149             : }
+     150             : 
+     151             : 
+     152             : }
+     153             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_ChiSquared.cpp.func-sort-c.html b/coverage/ves/TD_ChiSquared.cpp.func-sort-c.html new file mode 100644 index 000000000000..2d5778afbb4e --- /dev/null +++ b/coverage/ves/TD_ChiSquared.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_ChiSquared.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_ChiSquared.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4040100.0 %
Date:2024-04-19 12:12:35Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves13TD_ChiSquaredC2ERKNS_13ActionOptionsE9
_ZN4PLMD3ves13TD_ChiSquared16registerKeywordsERNS_8KeywordsE11
_ZNK4PLMD3ves13TD_ChiSquared8getValueERKSt6vectorIdSaIdEE1509
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_ChiSquared.cpp.func.html b/coverage/ves/TD_ChiSquared.cpp.func.html new file mode 100644 index 000000000000..9a15e7260e15 --- /dev/null +++ b/coverage/ves/TD_ChiSquared.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_ChiSquared.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_ChiSquared.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4040100.0 %
Date:2024-04-19 12:12:35Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves13TD_ChiSquared16registerKeywordsERNS_8KeywordsE11
_ZN4PLMD3ves13TD_ChiSquaredC2ERKNS_13ActionOptionsE9
_ZNK4PLMD3ves13TD_ChiSquared8getValueERKSt6vectorIdSaIdEE1509
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_ChiSquared.cpp.gcov.html b/coverage/ves/TD_ChiSquared.cpp.gcov.html new file mode 100644 index 000000000000..f0183b83ac2d --- /dev/null +++ b/coverage/ves/TD_ChiSquared.cpp.gcov.html @@ -0,0 +1,229 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_ChiSquared.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_ChiSquared.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4040100.0 %
Date:2024-04-19 12:12:35Functions:33100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "TargetDistribution.h"
+      24             : 
+      25             : #include "core/ActionRegister.h"
+      26             : 
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace ves {
+      30             : 
+      31             : //+PLUMEDOC VES_TARGETDIST TD_CHISQUARED
+      32             : /*
+      33             : Chi-squared distribution (static).
+      34             : 
+      35             : Employ a target distribution given by a
+      36             : [chi-squared distribution](https://en.wikipedia.org/wiki/Chi-squared_distribution)
+      37             : that is defined as
+      38             : \f[
+      39             : p(s) =
+      40             : \frac
+      41             : {1}
+      42             : {\sigma \, 2^{\frac{k}{2}}  \,  \Gamma\left(\frac{k}{2}\right) }
+      43             : \, \left(\frac{s-a}{\sigma}\right)^{\frac{k}{2}-1} \, \exp\left(- \frac{1}{2}
+      44             : \left(\frac{s-a}{\sigma}\right) \right),
+      45             : \f]
+      46             : where \f$a\f$ is the minimum of the distribution that is defined on the interval \f$[a,\infty)\f$,
+      47             : the parameter \f$k\f$ (given as a positive integer larger than 2) determines how far
+      48             : the peak of the distribution is from the minimum (known as the "degrees of freedom"),
+      49             : and the parameter \f$\sigma>0\f$ determines the broadness of the distribution.
+      50             : 
+      51             : The minimum \f$a\f$ is given using the MINIMUM keyword, the parameter \f$k\f$ is given
+      52             : using the KAPPA keyword, and the parameter \f$\sigma\f$ is given using the SIGMA keyword.
+      53             : 
+      54             : This target distribution action is only defined for one dimension, for multiple dimensions
+      55             : it should be used in combination with the \ref TD_PRODUCT_DISTRIBUTION action.
+      56             : 
+      57             : \par Examples
+      58             : 
+      59             : Chi-squared distribution with \f$a=-10.0\f$, \f$\sigma=2.0\f$, and \f$k=2\f$
+      60             : \plumedfile
+      61             : td: TD_CHISQUARED  MINIMUM=-10.0  SIGMA=2.0  KAPPA=2
+      62             : \endplumedfile
+      63             : 
+      64             : The Chi-squared distribution is only defined for one dimension so for multiple
+      65             : dimensions we have to use it in combination with the \ref TD_PRODUCT_DISTRIBUTION action as shown in
+      66             : the following example where we have a Chi-squared distribution for argument 1
+      67             : and uniform distribution for argument 2
+      68             : \plumedfile
+      69             : td_chisq: TD_CHISQUARED  MINIMUM=10.0  SIGMA=2.0  KAPPA=2
+      70             : 
+      71             : td_uni: TD_UNIFORM
+      72             : 
+      73             : td_pd: TD_PRODUCT_DISTRIBUTION DISTRIBUTIONS=td_chisq,td_uni
+      74             : \endplumedfile
+      75             : 
+      76             : */
+      77             : //+ENDPLUMEDOC
+      78             : 
+      79             : class TD_ChiSquared: public TargetDistribution {
+      80             :   std::vector<double> minima_;
+      81             :   std::vector<double> sigma_;
+      82             :   std::vector<double> kappa_;
+      83             :   std::vector<double> normalization_;
+      84             : public:
+      85             :   static void registerKeywords(Keywords&);
+      86             :   explicit TD_ChiSquared(const ActionOptions& ao);
+      87             :   double getValue(const std::vector<double>&) const override;
+      88             : };
+      89             : 
+      90             : 
+      91             : PLUMED_REGISTER_ACTION(TD_ChiSquared,"TD_CHISQUARED")
+      92             : 
+      93             : 
+      94          11 : void TD_ChiSquared::registerKeywords(Keywords& keys) {
+      95          11 :   TargetDistribution::registerKeywords(keys);
+      96          22 :   keys.add("compulsory","MINIMUM","The minimum of the chi-squared distribution.");
+      97          22 :   keys.add("compulsory","SIGMA","The sigma parameter of the chi-squared distribution given as a positive number.");
+      98          22 :   keys.add("compulsory","KAPPA","The k parameter of the chi-squared distribution given as positive integer larger than 2.");
+      99          11 :   keys.use("WELLTEMPERED_FACTOR");
+     100          11 :   keys.use("SHIFT_TO_ZERO");
+     101          11 :   keys.use("NORMALIZE");
+     102          11 : }
+     103             : 
+     104             : 
+     105           9 : TD_ChiSquared::TD_ChiSquared(const ActionOptions& ao):
+     106             :   PLUMED_VES_TARGETDISTRIBUTION_INIT(ao),
+     107          18 :   minima_(0),
+     108           9 :   sigma_(0),
+     109           9 :   kappa_(0),
+     110          18 :   normalization_(0)
+     111             : {
+     112           9 :   parseVector("MINIMUM",minima_);
+     113           9 :   parseVector("SIGMA",sigma_);
+     114          18 :   for(unsigned int k=0; k<sigma_.size(); k++) {
+     115           9 :     if(sigma_[k] < 0.0) {plumed_merror(getName()+": the value given in SIGMA should be positive.");}
+     116             :   }
+     117             : 
+     118           9 :   std::vector<unsigned int> kappa_int(0);
+     119          18 :   parseVector("KAPPA",kappa_int);
+     120           9 :   if(kappa_int.size()==0) {plumed_merror(getName()+": some problem with KAPPA keyword, should given as positive integer larger than 2");}
+     121           9 :   kappa_.resize(kappa_int.size());
+     122          18 :   for(unsigned int k=0; k<kappa_int.size(); k++) {
+     123           9 :     if(kappa_int[k] < 2) {plumed_merror(getName()+": KAPPA should be an integer 2 or higher");}
+     124           9 :     kappa_[k] = static_cast<double>(kappa_int[k]);
+     125             :   }
+     126             : 
+     127           9 :   setDimension(minima_.size());
+     128           9 :   if(getDimension()>1) {plumed_merror(getName()+": only defined for one dimension, for multiple dimensions it should be used in combination with the TD_PRODUCT_DISTRIBUTION action.");}
+     129           9 :   if(sigma_.size()!=getDimension()) {plumed_merror(getName()+": the SIGMA keyword does not match the given dimension in MINIMUM");}
+     130           9 :   if(kappa_.size()!=getDimension()) {plumed_merror(getName()+": the KAPPA keyword does not match the given dimension in MINIMUM");}
+     131             : 
+     132           9 :   normalization_.resize(getDimension());
+     133          18 :   for(unsigned int k=0; k<getDimension(); k++) {
+     134           9 :     normalization_[k] = 1.0/(pow(2.0,0.5*kappa_[k])*tgamma(0.5*kappa_[k])*sigma_[k]);
+     135             :   }
+     136           9 :   checkRead();
+     137           9 : }
+     138             : 
+     139             : 
+     140        1509 : double TD_ChiSquared::getValue(const std::vector<double>& argument) const {
+     141             :   double value = 1.0;
+     142        3018 :   for(unsigned int k=0; k<argument.size(); k++) {
+     143        1509 :     double arg=(argument[k]-minima_[k])/sigma_[k];
+     144        1509 :     if(arg<0.0) {plumed_merror(getName()+": the chi-squared istribution is not defined for values less that ones given in MINIMUM");}
+     145        1509 :     value *= normalization_[k] * pow(arg,0.5*kappa_[k]-1.0) * exp(-0.5*arg);
+     146             :   }
+     147        1509 :   return value;
+     148             : }
+     149             : 
+     150             : 
+     151             : }
+     152             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_Custom.cpp.func-sort-c.html b/coverage/ves/TD_Custom.cpp.func-sort-c.html new file mode 100644 index 000000000000..67badf3909f3 --- /dev/null +++ b/coverage/ves/TD_Custom.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_Custom.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_Custom.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:778986.5 %
Date:2024-04-19 12:12:35Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD3ves9TD_Custom8getValueERKSt6vectorIdSaIdEE0
_ZN4PLMD3ves9TD_Custom20setupAdditionalGridsERKSt6vectorIPNS_5ValueESaIS4_EERKS2_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISE_EESI_RKS2_IjSaIjEE16
_ZN4PLMD3ves9TD_CustomC2ERKNS_13ActionOptionsE16
_ZN4PLMD3ves9TD_CustomD0Ev16
_ZN4PLMD3ves9TD_CustomD2Ev16
_ZN4PLMD3ves9TD_Custom16registerKeywordsERNS_8KeywordsE18
_ZN4PLMD3ves9TD_Custom10updateGridEv46
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_Custom.cpp.func.html b/coverage/ves/TD_Custom.cpp.func.html new file mode 100644 index 000000000000..52a6b97fd287 --- /dev/null +++ b/coverage/ves/TD_Custom.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_Custom.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_Custom.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:778986.5 %
Date:2024-04-19 12:12:35Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves9TD_Custom10updateGridEv46
_ZN4PLMD3ves9TD_Custom16registerKeywordsERNS_8KeywordsE18
_ZN4PLMD3ves9TD_Custom20setupAdditionalGridsERKSt6vectorIPNS_5ValueESaIS4_EERKS2_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISE_EESI_RKS2_IjSaIjEE16
_ZN4PLMD3ves9TD_CustomC2ERKNS_13ActionOptionsE16
_ZN4PLMD3ves9TD_CustomD0Ev16
_ZN4PLMD3ves9TD_CustomD2Ev16
_ZNK4PLMD3ves9TD_Custom8getValueERKSt6vectorIdSaIdEE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_Custom.cpp.gcov.html b/coverage/ves/TD_Custom.cpp.gcov.html new file mode 100644 index 000000000000..e2033ec29328 --- /dev/null +++ b/coverage/ves/TD_Custom.cpp.gcov.html @@ -0,0 +1,372 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_Custom.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_Custom.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:778986.5 %
Date:2024-04-19 12:12:35Functions:6785.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "TargetDistribution.h"
+      24             : #include "GridIntegrationWeights.h"
+      25             : 
+      26             : #include "core/ActionRegister.h"
+      27             : #include "tools/Grid.h"
+      28             : 
+      29             : #include "lepton/Lepton.h"
+      30             : 
+      31             : 
+      32             : namespace PLMD {
+      33             : namespace ves {
+      34             : 
+      35             : //+PLUMEDOC VES_TARGETDIST TD_CUSTOM
+      36             : /*
+      37             : Target distribution given by an arbitrary mathematical expression (static or dynamic).
+      38             : 
+      39             : Use as a target distribution the distribution defined by
+      40             : \f[
+      41             : p(\mathbf{s}) =
+      42             : \frac{f(\mathbf{s})}{\int d\mathbf{s} \, f(\mathbf{s})}
+      43             : \f]
+      44             : where \f$f(\mathbf{s})\f$ is some arbitrary mathematical function that
+      45             : is parsed by the lepton library.
+      46             : 
+      47             : The function \f$f(\mathbf{s})\f$ is given by the FUNCTION keywords by
+      48             : using _s1_,_s2_,..., as variables for the arguments
+      49             : \f$\mathbf{s}=(s_1,s_2,\ldots,s_d)\f$.
+      50             : If one variable is not given the target distribution will be
+      51             : taken as uniform in that argument.
+      52             : 
+      53             : It is also possible to include the free energy surface \f$F(\mathbf{s})\f$
+      54             : in the target distribution by using the _FE_ variable. In this case the
+      55             : target distribution is dynamic and needs to be updated with current
+      56             : best estimate of \f$F(\mathbf{s})\f$, similarly as for the
+      57             : \ref TD_WELLTEMPERED "well-tempered target distribution".
+      58             : Furthermore, the inverse temperature \f$\beta = (k_{\mathrm{B}}T)^{-1}\f$ and
+      59             : the thermal energy \f$k_{\mathrm{B}}T\f$ can be included
+      60             : by using the _beta_ and \f$k_B T\f$ variables.
+      61             : 
+      62             : The target distribution will be automatically normalized over the region on
+      63             : which it is defined on. Therefore, the function given in
+      64             : FUNCTION needs to be non-negative and it must be possible to normalize the function. The
+      65             : code will perform checks to make sure that this is indeed the case.
+      66             : 
+      67             : 
+      68             : \par Examples
+      69             : 
+      70             : Here we use as shifted [Maxwell-Boltzmann distribution](https://en.wikipedia.org/wiki/Maxwell%E2%80%93Boltzmann_distribution)
+      71             : as a target distribution in one-dimension.
+      72             : Note that it is not need to include the normalization factor as the distribution will be
+      73             : automatically normalized.
+      74             : \plumedfile
+      75             : TD_CUSTOM ...
+      76             :  FUNCTION=(s1+20)^2*exp(-(s1+20)^2/(2*10.0^2))
+      77             :  LABEL=td
+      78             : ... TD_CUSTOM
+      79             : \endplumedfile
+      80             : 
+      81             : Here we have a two dimensional target distribution where we
+      82             : use a [generalized normal distribution](https://en.wikipedia.org/wiki/Generalized_normal_distribution)
+      83             : for argument \f$s_2\f$ while the distribution for \f$s_1\f$ is taken as
+      84             : uniform as the variable _s1_ is not included in the function.
+      85             : \plumedfile
+      86             : TD_CUSTOM ...
+      87             :  FUNCTION=exp(-(abs(s2-20.0)/5.0)^4.0)
+      88             :  LABEL=td
+      89             : ... TD_CUSTOM
+      90             : \endplumedfile
+      91             : 
+      92             : By using the _FE_ variable the target distribution can depend on
+      93             : the free energy surface \f$F(\mathbf{s})\f$. For example,
+      94             : the following input is identical to using \ref TD_WELLTEMPERED with
+      95             : a bias factor of 10.
+      96             : \plumedfile
+      97             : TD_CUSTOM ...
+      98             :  FUNCTION=exp(-(beta/10.0)*FE)
+      99             :  LABEL=td
+     100             : ... TD_CUSTOM
+     101             : \endplumedfile
+     102             : Here the inverse temperature is automatically obtained by using the _beta_
+     103             : variable. It is also possible to use the \f$k_B T\f$ variable. The following
+     104             : syntax will give the exact same results as the syntax above
+     105             : \plumedfile
+     106             : TD_CUSTOM ...
+     107             :  FUNCTION=exp(-(1.0/(kBT*10.0))*FE)
+     108             :  LABEL=td
+     109             : ... TD_CUSTOM
+     110             : \endplumedfile
+     111             : 
+     112             : 
+     113             : */
+     114             : //+ENDPLUMEDOC
+     115             : 
+     116             : class TD_Custom : public TargetDistribution {
+     117             : private:
+     118             :   void setupAdditionalGrids(const std::vector<Value*>&, const std::vector<std::string>&, const std::vector<std::string>&, const std::vector<unsigned int>&) override;
+     119             :   //
+     120             :   lepton::CompiledExpression expression;
+     121             :   //
+     122             :   std::vector<double*> cv_var_lepton_refs_;
+     123             :   double* kbt_var_lepton_ref_;
+     124             :   double* beta_var_lepton_ref_;
+     125             :   double* fes_var_lepton_ref_;
+     126             :   //
+     127             :   std::vector<unsigned int> cv_var_idx_;
+     128             :   std::vector<std::string> cv_var_str_;
+     129             :   //
+     130             :   std::string cv_var_prefix_str_;
+     131             :   std::string fes_var_str_;
+     132             :   std::string kbt_var_str_;
+     133             :   std::string beta_var_str_;
+     134             :   //
+     135             :   bool use_fes_;
+     136             :   bool use_kbt_;
+     137             :   bool use_beta_;
+     138             : public:
+     139             :   static void registerKeywords( Keywords&);
+     140             :   explicit TD_Custom(const ActionOptions& ao);
+     141             :   void updateGrid() override;
+     142             :   double getValue(const std::vector<double>&) const override;
+     143          48 :   ~TD_Custom() {};
+     144             : };
+     145             : 
+     146             : PLUMED_REGISTER_ACTION(TD_Custom,"TD_CUSTOM")
+     147             : 
+     148             : 
+     149          18 : void TD_Custom::registerKeywords(Keywords& keys) {
+     150          18 :   TargetDistribution::registerKeywords(keys);
+     151          36 :   keys.add("compulsory","FUNCTION","The function you wish to use for the target distribution where you should use the variables _s1_,_s2_,... for the arguments. You can also use the current estimate of the FES by using the variable _FE_ and the temperature by using the \\f$k_B T\\f$ and _beta_ variables.");
+     152          18 :   keys.use("WELLTEMPERED_FACTOR");
+     153          18 :   keys.use("SHIFT_TO_ZERO");
+     154          18 : }
+     155             : 
+     156             : 
+     157          16 : TD_Custom::TD_Custom(const ActionOptions& ao):
+     158             :   PLUMED_VES_TARGETDISTRIBUTION_INIT(ao),
+     159             : //
+     160          16 :   cv_var_lepton_refs_(0,nullptr),
+     161          16 :   kbt_var_lepton_ref_(nullptr),
+     162          16 :   beta_var_lepton_ref_(nullptr),
+     163          16 :   fes_var_lepton_ref_(nullptr),
+     164             : //
+     165          16 :   cv_var_idx_(0),
+     166          16 :   cv_var_str_(0),
+     167             : //
+     168          16 :   cv_var_prefix_str_("s"),
+     169          16 :   fes_var_str_("FE"),
+     170          16 :   kbt_var_str_("kBT"),
+     171          16 :   beta_var_str_("beta"),
+     172             : //
+     173          16 :   use_fes_(false),
+     174          16 :   use_kbt_(false),
+     175          32 :   use_beta_(false)
+     176             : {
+     177             :   std::string func_str;
+     178          16 :   parse("FUNCTION",func_str);
+     179          16 :   checkRead();
+     180             :   //
+     181             :   try {
+     182          16 :     lepton::ParsedExpression pe=lepton::Parser::parse(func_str).optimize(lepton::Constants());
+     183          16 :     log<<"  function as parsed by lepton: "<<pe<<"\n";
+     184          16 :     expression=pe.createCompiledExpression();
+     185             :   }
+     186           0 :   catch(PLMD::lepton::Exception& exc) {
+     187           0 :     plumed_merror("There was some problem in parsing the function "+func_str+" given in FUNCTION with lepton");
+     188           0 :   }
+     189             : 
+     190          39 :   for(auto &p: expression.getVariables()) {
+     191          23 :     std::string curr_var = p;
+     192             :     unsigned int cv_idx;
+     193          39 :     if(curr_var.substr(0,cv_var_prefix_str_.size())==cv_var_prefix_str_ && Tools::convertNoexcept(curr_var.substr(cv_var_prefix_str_.size()),cv_idx) && cv_idx>0) {
+     194          16 :       cv_var_idx_.push_back(cv_idx-1);
+     195             :     }
+     196           7 :     else if(curr_var==fes_var_str_) {
+     197           3 :       use_fes_=true;
+     198             :       setDynamic();
+     199             :       setFesGridNeeded();
+     200             :     }
+     201           4 :     else if(curr_var==kbt_var_str_) {
+     202           2 :       use_kbt_=true;
+     203             :     }
+     204           2 :     else if(curr_var==beta_var_str_) {
+     205           2 :       use_beta_=true;
+     206             :     }
+     207             :     else {
+     208           0 :       plumed_merror(getName()+": problem with parsing formula with lepton, cannot recognise the variable "+curr_var);
+     209             :     }
+     210             :   }
+     211             :   //
+     212          16 :   std::sort(cv_var_idx_.begin(),cv_var_idx_.end());
+     213          16 :   cv_var_str_.resize(cv_var_idx_.size());
+     214          16 :   cv_var_lepton_refs_.resize(cv_var_str_.size());
+     215          32 :   for(unsigned int j=0; j<cv_var_idx_.size(); j++) {
+     216          16 :     std::string str1; Tools::convert(cv_var_idx_[j]+1,str1);
+     217          32 :     cv_var_str_[j] = cv_var_prefix_str_+str1;
+     218             :     try {
+     219          16 :       cv_var_lepton_refs_[j] = &expression.getVariableReference(cv_var_str_[j]);
+     220           0 :     } catch(PLMD::lepton::Exception& exc) {}
+     221             :   }
+     222             : 
+     223          16 :   if(use_kbt_) {
+     224             :     try {
+     225           2 :       kbt_var_lepton_ref_ = &expression.getVariableReference(kbt_var_str_);
+     226           0 :     } catch(PLMD::lepton::Exception& exc) {}
+     227             :   }
+     228          16 :   if(use_beta_) {
+     229             :     try {
+     230           2 :       beta_var_lepton_ref_ = &expression.getVariableReference(beta_var_str_);
+     231           0 :     } catch(PLMD::lepton::Exception& exc) {}
+     232             :   }
+     233          16 :   if(use_fes_) {
+     234             :     try {
+     235           3 :       fes_var_lepton_ref_ = &expression.getVariableReference(fes_var_str_);
+     236           0 :     } catch(PLMD::lepton::Exception& exc) {}
+     237             :   }
+     238             : 
+     239          16 : }
+     240             : 
+     241             : 
+     242          16 : void TD_Custom::setupAdditionalGrids(const std::vector<Value*>& arguments, const std::vector<std::string>& min, const std::vector<std::string>& max, const std::vector<unsigned int>& nbins) {
+     243          16 :   if(cv_var_idx_.size()>0 && cv_var_idx_[cv_var_idx_.size()-1]>getDimension()) {
+     244           0 :     plumed_merror(getName()+": mismatch between CVs given in FUNC and the dimension of the target distribution");
+     245             :   }
+     246          16 : }
+     247             : 
+     248             : 
+     249           0 : double TD_Custom::getValue(const std::vector<double>& argument) const {
+     250           0 :   plumed_merror("getValue not implemented for TD_Custom");
+     251             :   return 0.0;
+     252             : }
+     253             : 
+     254             : 
+     255          46 : void TD_Custom::updateGrid() {
+     256          46 :   if(use_fes_) {
+     257          33 :     plumed_massert(getFesGridPntr()!=NULL,"the FES grid has to be linked to the free energy in the target distribution");
+     258             :   }
+     259          46 :   if(use_kbt_) {
+     260          22 :     if(kbt_var_lepton_ref_) {*kbt_var_lepton_ref_= 1.0/getBeta();}
+     261             :   }
+     262          46 :   if(use_beta_) {
+     263          22 :     if(beta_var_lepton_ref_) {*beta_var_lepton_ref_= getBeta();}
+     264             :   }
+     265             :   //
+     266          92 :   std::vector<double> integration_weights = GridIntegrationWeights::getIntegrationWeights(getTargetDistGridPntr());
+     267             :   double norm = 0.0;
+     268             :   //
+     269       40909 :   for(Grid::index_t l=0; l<targetDistGrid().getSize(); l++) {
+     270       40863 :     std::vector<double> point = targetDistGrid().getPoint(l);
+     271       99928 :     for(unsigned int k=0; k<cv_var_str_.size() ; k++) {
+     272       59065 :       if(cv_var_lepton_refs_[k]) {*cv_var_lepton_refs_[k] = point[cv_var_idx_[k]];}
+     273             :     }
+     274       40863 :     if(use_fes_) {
+     275        3300 :       if(fes_var_lepton_ref_) {*fes_var_lepton_ref_ = getFesGridPntr()->getValue(l);}
+     276             :     }
+     277       40863 :     double value = expression.evaluate();
+     278             : 
+     279       40863 :     if(value<0.0 && !isTargetDistGridShiftedToZero()) {plumed_merror(getName()+": The target distribution function gives negative values. You should change the definition of the function used for the target distribution to avoid this. You can also use the SHIFT_TO_ZERO keyword to avoid this problem.");}
+     280       40863 :     targetDistGrid().setValue(l,value);
+     281       40863 :     norm += integration_weights[l]*value;
+     282       40863 :     logTargetDistGrid().setValue(l,-std::log(value));
+     283             :   }
+     284          46 :   if(norm>0.0) {
+     285          45 :     targetDistGrid().scaleAllValuesAndDerivatives(1.0/norm);
+     286             :   }
+     287           1 :   else if(!isTargetDistGridShiftedToZero()) {
+     288           0 :     plumed_merror(getName()+": The target distribution function cannot be normalized proberly. You should change the definition of the function used for the target distribution to avoid this. You can also use the SHIFT_TO_ZERO keyword to avoid this problem.");
+     289             :   }
+     290          46 :   logTargetDistGrid().setMinToZero();
+     291          46 : }
+     292             : 
+     293             : 
+     294             : }
+     295             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_Exponential.cpp.func-sort-c.html b/coverage/ves/TD_Exponential.cpp.func-sort-c.html new file mode 100644 index 000000000000..bbab28c3c948 --- /dev/null +++ b/coverage/ves/TD_Exponential.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_Exponential.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_Exponential.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2626100.0 %
Date:2024-04-19 12:12:35Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves14TD_ExponentialC2ERKNS_13ActionOptionsE8
_ZN4PLMD3ves14TD_Exponential16registerKeywordsERNS_8KeywordsE10
_ZNK4PLMD3ves14TD_Exponential8getValueERKSt6vectorIdSaIdEE1308
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_Exponential.cpp.func.html b/coverage/ves/TD_Exponential.cpp.func.html new file mode 100644 index 000000000000..319bc3177878 --- /dev/null +++ b/coverage/ves/TD_Exponential.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_Exponential.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_Exponential.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2626100.0 %
Date:2024-04-19 12:12:35Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves14TD_Exponential16registerKeywordsERNS_8KeywordsE10
_ZN4PLMD3ves14TD_ExponentialC2ERKNS_13ActionOptionsE8
_ZNK4PLMD3ves14TD_Exponential8getValueERKSt6vectorIdSaIdEE1308
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_Exponential.cpp.gcov.html b/coverage/ves/TD_Exponential.cpp.gcov.html new file mode 100644 index 000000000000..0afc11f68c28 --- /dev/null +++ b/coverage/ves/TD_Exponential.cpp.gcov.html @@ -0,0 +1,206 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_Exponential.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_Exponential.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2626100.0 %
Date:2024-04-19 12:12:35Functions:33100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "TargetDistribution.h"
+      24             : 
+      25             : #include "core/ActionRegister.h"
+      26             : 
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace ves {
+      30             : 
+      31             : //+PLUMEDOC VES_TARGETDIST TD_EXPONENTIAL
+      32             : /*
+      33             : Exponential distribution (static).
+      34             : 
+      35             : Employ a target distribution given by an
+      36             : [exponential distribution](https://en.wikipedia.org/wiki/Exponential_distribution)
+      37             : that is defined as
+      38             : \f[
+      39             : p(s) =
+      40             : \lambda e^{-\lambda(s-a)}
+      41             : \f]
+      42             : where \f$a\f$ is the minimum of the distribution that is defined on the interval \f$[a,\infty)\f$,
+      43             : and \f$\lambda>0\f$ is the so-called rate parameter.
+      44             : 
+      45             : The minimum \f$a\f$ is given using the MINIMUM keyword, and the rate parameter \f$\lambda\f$ is given
+      46             : using the LAMBDA keyword.
+      47             : 
+      48             : This target distribution action is only defined for one dimension, for multiple dimensions
+      49             : it should be used in combination with \ref TD_PRODUCT_DISTRIBUTION action.
+      50             : 
+      51             : \par Examples
+      52             : 
+      53             : Exponential distribution with \f$a=10.0\f$ and \f$\lambda=0.5\f$
+      54             : \plumedfile
+      55             : td: TD_EXPONENTIAL  MINIMUM=-10.0  LAMBDA=0.5
+      56             : \endplumedfile
+      57             : 
+      58             : The exponential distribution is only defined for one dimension so for multiple
+      59             : dimensions we have to use it in combination with the \ref TD_PRODUCT_DISTRIBUTION action as shown in
+      60             : the following example where we have a uniform distribution for argument 1 and
+      61             : and an exponential distribution for argument 2
+      62             : \plumedfile
+      63             : td_uni: TD_UNIFORM
+      64             : 
+      65             : td_exp: TD_EXPONENTIAL  MINIMUM=-10.0  LAMBDA=0.5
+      66             : 
+      67             : td_pd: TD_PRODUCT_DISTRIBUTION DISTRIBUTIONS=td_uni,td_exp
+      68             : \endplumedfile
+      69             : 
+      70             : 
+      71             : */
+      72             : //+ENDPLUMEDOC
+      73             : 
+      74             : class TD_Exponential: public TargetDistribution {
+      75             :   std::vector<double> minima_;
+      76             :   std::vector<double> lambda_;
+      77             : public:
+      78             :   static void registerKeywords(Keywords&);
+      79             :   explicit TD_Exponential(const ActionOptions& ao);
+      80             :   double getValue(const std::vector<double>&) const override;
+      81             : };
+      82             : 
+      83             : 
+      84             : PLUMED_REGISTER_ACTION(TD_Exponential,"TD_EXPONENTIAL")
+      85             : 
+      86             : 
+      87          10 : void TD_Exponential::registerKeywords(Keywords& keys) {
+      88          10 :   TargetDistribution::registerKeywords(keys);
+      89          20 :   keys.add("compulsory","MINIMUM","The minimum of the exponential distribution.");
+      90          20 :   keys.add("compulsory","LAMBDA","The lambda parameter of the exponential distribution given as positive number.");
+      91          10 :   keys.use("WELLTEMPERED_FACTOR");
+      92          10 :   keys.use("SHIFT_TO_ZERO");
+      93          10 :   keys.use("NORMALIZE");
+      94          10 : }
+      95             : 
+      96             : 
+      97           8 : TD_Exponential::TD_Exponential(const ActionOptions& ao):
+      98             :   PLUMED_VES_TARGETDISTRIBUTION_INIT(ao),
+      99          16 :   minima_(0),
+     100           8 :   lambda_(0)
+     101             : {
+     102           8 :   parseVector("MINIMUM",minima_);
+     103           8 :   parseVector("LAMBDA",lambda_);
+     104          16 :   for(unsigned int k=0; k<lambda_.size(); k++) {
+     105           8 :     if(lambda_[k] < 0.0) {plumed_merror(getName()+": the value given in LAMBDA should be positive.");}
+     106             :   }
+     107             : 
+     108             : 
+     109           8 :   setDimension(minima_.size());
+     110           8 :   if(getDimension()>1) {plumed_merror(getName()+": only defined for one dimension, for multiple dimensions it should be used in combination with the TD_PRODUCT_DISTRIBUTION action.");}
+     111           8 :   if(lambda_.size()!=getDimension()) {plumed_merror(getName()+": the LAMBDA keyword does not match the given dimension in MINIMUM");}
+     112           8 :   checkRead();
+     113           8 : }
+     114             : 
+     115             : 
+     116        1308 : double TD_Exponential::getValue(const std::vector<double>& argument) const {
+     117             :   double value = 1.0;
+     118        2616 :   for(unsigned int k=0; k<argument.size(); k++) {
+     119        1308 :     double arg = (argument[k]-minima_[k])*lambda_[k];
+     120        1308 :     if(arg<0.0) {plumed_merror(getName()+": the exponential distribution is not defined for values less that ones given in MINIMUM");}
+     121        1308 :     value *= lambda_[k]*exp(-arg);
+     122             :   }
+     123        1308 :   return value;
+     124             : }
+     125             : 
+     126             : 
+     127             : 
+     128             : }
+     129             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_ExponentiallyModifiedGaussian.cpp.func-sort-c.html b/coverage/ves/TD_ExponentiallyModifiedGaussian.cpp.func-sort-c.html new file mode 100644 index 000000000000..aeacfceeb1df --- /dev/null +++ b/coverage/ves/TD_ExponentiallyModifiedGaussian.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_ExponentiallyModifiedGaussian.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_ExponentiallyModifiedGaussian.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:576390.5 %
Date:2024-04-19 12:12:35Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves32TD_ExponentiallyModifiedGaussianC2ERKNS_13ActionOptionsE6
_ZN4PLMD3ves32TD_ExponentiallyModifiedGaussian16registerKeywordsERNS_8KeywordsE8
_ZNK4PLMD3ves32TD_ExponentiallyModifiedGaussian8getValueERKSt6vectorIdSaIdEE11206
_ZNK4PLMD3ves32TD_ExponentiallyModifiedGaussian37ExponentiallyModifiedGaussianDiagonalERKSt6vectorIdSaIdEES6_S6_S6_21809
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_ExponentiallyModifiedGaussian.cpp.func.html b/coverage/ves/TD_ExponentiallyModifiedGaussian.cpp.func.html new file mode 100644 index 000000000000..6bed2b079862 --- /dev/null +++ b/coverage/ves/TD_ExponentiallyModifiedGaussian.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_ExponentiallyModifiedGaussian.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_ExponentiallyModifiedGaussian.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:576390.5 %
Date:2024-04-19 12:12:35Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves32TD_ExponentiallyModifiedGaussian16registerKeywordsERNS_8KeywordsE8
_ZN4PLMD3ves32TD_ExponentiallyModifiedGaussianC2ERKNS_13ActionOptionsE6
_ZNK4PLMD3ves32TD_ExponentiallyModifiedGaussian37ExponentiallyModifiedGaussianDiagonalERKSt6vectorIdSaIdEES6_S6_S6_21809
_ZNK4PLMD3ves32TD_ExponentiallyModifiedGaussian8getValueERKSt6vectorIdSaIdEE11206
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_ExponentiallyModifiedGaussian.cpp.gcov.html b/coverage/ves/TD_ExponentiallyModifiedGaussian.cpp.gcov.html new file mode 100644 index 000000000000..2d21b3204ef6 --- /dev/null +++ b/coverage/ves/TD_ExponentiallyModifiedGaussian.cpp.gcov.html @@ -0,0 +1,301 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_ExponentiallyModifiedGaussian.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_ExponentiallyModifiedGaussian.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:576390.5 %
Date:2024-04-19 12:12:35Functions:44100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "TargetDistribution.h"
+      24             : 
+      25             : #include "core/ActionRegister.h"
+      26             : 
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace ves {
+      30             : 
+      31             : //+PLUMEDOC VES_TARGETDIST TD_EXPONENTIALLY_MODIFIED_GAUSSIAN
+      32             : /*
+      33             : Target distribution given by a sum of exponentially modified Gaussian distributions (static).
+      34             : 
+      35             : Employ a target distribution that is given by a sum where each
+      36             : term is a product of one-dimensional
+      37             : [exponentially modified Gaussian distributions](http://en.wikipedia.org/wiki/Exponentially_modified_Gaussian_distribution),
+      38             : \f[
+      39             : p(\mathbf{s}) = \sum_{i} \, w_{i}
+      40             : \prod_{k}^{d}
+      41             : \frac{\lambda_{k,i}}{2}
+      42             : \,
+      43             : \exp\left[
+      44             : \frac{\lambda_{k,i}}{2}
+      45             : (2 \mu_{k,i} + \lambda_{k,i} \sigma_{k,i}^2 -2 s_{k})
+      46             : \right]
+      47             : \,
+      48             : \mathrm{erfc}\left[
+      49             : \frac{\mu_{k,i} + \lambda_{k,i} \sigma_{k,i}^2 - s_{k})}{\sqrt{2} \sigma_{k,i}}
+      50             : \right]
+      51             : \f]
+      52             : where \f$(\mu_{1,i},\mu_{2,i},\ldots,\mu_{d,i})\f$
+      53             : are the centers of the Gaussian component,
+      54             : \f$(\sigma_{1,i},\sigma_{2,i},\ldots,\sigma_{d,i})\f$ are the
+      55             : standard deviations of the Gaussian component,
+      56             : \f$(\lambda_{1,i},\lambda_{2,i},\ldots,\lambda_{d,i})\f$ are the
+      57             : rate parameters of the exponential component, and
+      58             : \f$\mathrm{erfc}(x)=1-\mathrm{erf}(x)\f$ is the
+      59             : complementary error function.
+      60             : The weights \f$w_{i}\f$ are normalized to 1, \f$\sum_{i}w_{i}=1\f$.
+      61             : 
+      62             : The centers \f$(\mu_{1,i},\mu_{2,i},\ldots,\mu_{d,i})\f$ are
+      63             : given using the numbered CENTER keywords, the standard deviations
+      64             : \f$(\sigma_{1,i},\sigma_{2,i},\ldots,\sigma_{d,i})\f$ using the
+      65             : the numbered SIGMA keywords, and the rate parameters
+      66             : \f$(\lambda_{1,i},\lambda_{2,i},\ldots,\lambda_{d,i})\f$ using the
+      67             : numbered LAMBDA keywords.
+      68             : The weights are given using the WEIGHTS keywords, if no weights are
+      69             : given are all terms weighted equally.
+      70             : 
+      71             : \par Examples
+      72             : 
+      73             : An exponentially modified Gaussian distribution in one-dimension
+      74             : \plumedfile
+      75             : td1: TD_EXPONENTIALLY_MODIFIED_GAUSSIAN CENTER1=-10.0 SIGMA1=1.0 LAMBDA1=0.25
+      76             : \endplumedfile
+      77             : 
+      78             : A sum of two one-dimensional exponentially modified Gaussian distributions
+      79             : \plumedfile
+      80             : TD_EXPONENTIALLY_MODIFIED_GAUSSIAN ...
+      81             :  CENTER1=-10.0 SIGMA1=1.0 LAMBDA1=0.5
+      82             :  CENTER2=+10.0 SIGMA2=1.0 LAMBDA2=1.0
+      83             :  WEIGHTS=2.0,1.0
+      84             :  LABEL=td1
+      85             : ... TD_EXPONENTIALLY_MODIFIED_GAUSSIAN
+      86             : \endplumedfile
+      87             : 
+      88             : A sum of two two-dimensional exponentially modified Gaussian distributions
+      89             : \plumedfile
+      90             : TD_EXPONENTIALLY_MODIFIED_GAUSSIAN ...
+      91             :  CENTER1=-5.0,+5.0 SIGMA1=1.0,1.0 LAMBDA1=0.5,0.5
+      92             :  CENTER2=+5.0,+5.0 SIGMA2=1.0,1.0 LAMBDA2=1.0,1.0
+      93             :  WEIGHTS=1.0,1.0
+      94             :  LABEL=td1
+      95             : ... TD_EXPONENTIALLY_MODIFIED_GAUSSIAN
+      96             : \endplumedfile
+      97             : 
+      98             : 
+      99             : 
+     100             : 
+     101             : 
+     102             : */
+     103             : //+ENDPLUMEDOC
+     104             : 
+     105             : class TD_ExponentiallyModifiedGaussian: public TargetDistribution {
+     106             :   std::vector< std::vector<double> > centers_;
+     107             :   std::vector< std::vector<double> > sigmas_;
+     108             :   std::vector< std::vector<double> > lambdas_;
+     109             :   std::vector<double> weights_;
+     110             :   unsigned int ncenters_;
+     111             :   double ExponentiallyModifiedGaussianDiagonal(const std::vector<double>&, const std::vector<double>&, const std::vector<double>&, const std::vector<double>&) const;
+     112             : public:
+     113             :   static void registerKeywords(Keywords&);
+     114             :   explicit TD_ExponentiallyModifiedGaussian(const ActionOptions& ao);
+     115             :   double getValue(const std::vector<double>&) const override;
+     116             : };
+     117             : 
+     118             : 
+     119             : PLUMED_REGISTER_ACTION(TD_ExponentiallyModifiedGaussian,"TD_EXPONENTIALLY_MODIFIED_GAUSSIAN")
+     120             : 
+     121             : 
+     122           8 : void TD_ExponentiallyModifiedGaussian::registerKeywords(Keywords& keys) {
+     123           8 :   TargetDistribution::registerKeywords(keys);
+     124          16 :   keys.add("numbered","CENTER","The center of each exponentially modified Gaussian distributions.");
+     125          16 :   keys.add("numbered","SIGMA","The sigma parameters for each exponentially modified Gaussian distributions.");
+     126          16 :   keys.add("numbered","LAMBDA","The lambda parameters for each exponentially modified Gaussian distributions");
+     127          16 :   keys.add("optional","WEIGHTS","The weights of the distributions. By default all are weighted equally.");
+     128           8 :   keys.use("WELLTEMPERED_FACTOR");
+     129           8 :   keys.use("SHIFT_TO_ZERO");
+     130           8 :   keys.use("NORMALIZE");
+     131           8 : }
+     132             : 
+     133             : 
+     134           6 : TD_ExponentiallyModifiedGaussian::TD_ExponentiallyModifiedGaussian(const ActionOptions& ao):
+     135             :   PLUMED_VES_TARGETDISTRIBUTION_INIT(ao),
+     136          12 :   centers_(0),
+     137           6 :   sigmas_(0),
+     138           6 :   lambdas_(0),
+     139           6 :   weights_(0),
+     140          12 :   ncenters_(0)
+     141             : {
+     142           9 :   for(unsigned int i=1;; i++) {
+     143             :     std::vector<double> tmp_center;
+     144          30 :     if(!parseNumberedVector("CENTER",i,tmp_center) ) {break;}
+     145           9 :     centers_.push_back(tmp_center);
+     146           9 :   }
+     147           9 :   for(unsigned int i=1;; i++) {
+     148             :     std::vector<double> tmp_sigma;
+     149          30 :     if(!parseNumberedVector("SIGMA",i,tmp_sigma) ) {break;}
+     150          20 :     for(unsigned int k=0; k<tmp_sigma.size(); k++) {
+     151          11 :       if(tmp_sigma[k]<=0.0) {plumed_merror(getName()+": the values given in SIGMA should be positive");}
+     152             :     }
+     153           9 :     sigmas_.push_back(tmp_sigma);
+     154           9 :   }
+     155           9 :   for(unsigned int i=1;; i++) {
+     156             :     std::vector<double> tmp_lambda;
+     157          30 :     if(!parseNumberedVector("LAMBDA",i,tmp_lambda) ) {break;}
+     158          20 :     for(unsigned int k=0; k<tmp_lambda.size(); k++) {
+     159          11 :       if(tmp_lambda[k]<=0.0) {plumed_merror(getName()+": the values given in LAMBDA should be positive");}
+     160             :     }
+     161           9 :     lambdas_.push_back(tmp_lambda);
+     162           9 :   }
+     163             :   //
+     164           6 :   if(centers_.size()==0) {
+     165           0 :     plumed_merror(getName()+": CENTER keywords seem to be missing. Note that numbered keywords start at CENTER1.");
+     166             :   }
+     167             :   //
+     168           6 :   if(centers_.size()!=sigmas_.size() || centers_.size()!=lambdas_.size() ) {
+     169           0 :     plumed_merror(getName()+": there has to be an equal amount of CENTER, SIGMA, and LAMBDA keywords");
+     170             :   }
+     171             :   //
+     172           6 :   setDimension(centers_[0].size());
+     173           6 :   ncenters_ = centers_.size();
+     174             :   //
+     175             :   // check centers and sigmas
+     176          15 :   for(unsigned int i=0; i<ncenters_; i++) {
+     177           9 :     if(centers_[i].size()!=getDimension()) {
+     178           0 :       plumed_merror(getName()+": one of the CENTER keyword does not match the given dimension");
+     179             :     }
+     180           9 :     if(sigmas_[i].size()!=getDimension()) {
+     181           0 :       plumed_merror(getName()+": one of the SIGMA keyword does not match the given dimension");
+     182             :     }
+     183           9 :     if(lambdas_[i].size()!=getDimension()) {
+     184           0 :       plumed_merror(getName()+": one of the LAMBDA keyword does not match the given dimension");
+     185             :     }
+     186             :   }
+     187             :   //
+     188          12 :   parseVector("WEIGHTS",weights_);
+     189           6 :   if(weights_.size()==0) {weights_.assign(centers_.size(),1.0);}
+     190           6 :   if(centers_.size()!=weights_.size()) {
+     191           0 :     plumed_merror(getName()+": there has to be as many weights given in WEIGHTS as numbered CENTER keywords");
+     192             :   }
+     193             :   //
+     194             :   double sum_weights=0.0;
+     195          15 :   for(unsigned int i=0; i<weights_.size(); i++) {sum_weights+=weights_[i];}
+     196          15 :   for(unsigned int i=0; i<weights_.size(); i++) {weights_[i]/=sum_weights;}
+     197             :   //
+     198           6 :   checkRead();
+     199           6 : }
+     200             : 
+     201             : 
+     202       11206 : double TD_ExponentiallyModifiedGaussian::getValue(const std::vector<double>& argument) const {
+     203             :   double value=0.0;
+     204       33015 :   for(unsigned int i=0; i<ncenters_; i++) {
+     205       21809 :     value+=weights_[i]*ExponentiallyModifiedGaussianDiagonal(argument,centers_[i],sigmas_[i],lambdas_[i]);
+     206             :   }
+     207       11206 :   return value;
+     208             : }
+     209             : 
+     210             : 
+     211       21809 : double TD_ExponentiallyModifiedGaussian::ExponentiallyModifiedGaussianDiagonal(const std::vector<double>& argument, const std::vector<double>& center, const std::vector<double>& sigma, const std::vector<double>& lambda) const {
+     212             :   double value = 1.0;
+     213       64020 :   for(unsigned int k=0; k<argument.size(); k++) {
+     214       42211 :     double arg1 = 0.5*lambda[k]*(2.0*center[k]+lambda[k]*sigma[k]*sigma[k]-2.0*argument[k]);
+     215       42211 :     double arg2 = (center[k]+lambda[k]*sigma[k]*sigma[k]-argument[k])/(sqrt(2.0)*sigma[k]);
+     216       42211 :     value *= 0.5*lambda[k]*exp(arg1)*erfc(arg2);
+     217             :   }
+     218       21809 :   return value;
+     219             : }
+     220             : 
+     221             : 
+     222             : 
+     223             : }
+     224             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_Gaussian.cpp.func-sort-c.html b/coverage/ves/TD_Gaussian.cpp.func-sort-c.html new file mode 100644 index 000000000000..abc815fabdc9 --- /dev/null +++ b/coverage/ves/TD_Gaussian.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_Gaussian.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_Gaussian.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:768490.5 %
Date:2024-04-19 12:12:35Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves11TD_GaussianC2ERKNS_13ActionOptionsE191
_ZN4PLMD3ves11TD_Gaussian16registerKeywordsERNS_8KeywordsE193
_ZNK4PLMD3ves11TD_Gaussian10Gaussian2DERKSt6vectorIdSaIdEES6_S6_S6_b40804
_ZNK4PLMD3ves11TD_Gaussian8getValueERKSt6vectorIdSaIdEE229739
_ZNK4PLMD3ves11TD_Gaussian16GaussianDiagonalERKSt6vectorIdSaIdEES6_S6_b292252
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_Gaussian.cpp.func.html b/coverage/ves/TD_Gaussian.cpp.func.html new file mode 100644 index 000000000000..9f8066767c2c --- /dev/null +++ b/coverage/ves/TD_Gaussian.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_Gaussian.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_Gaussian.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:768490.5 %
Date:2024-04-19 12:12:35Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves11TD_Gaussian16registerKeywordsERNS_8KeywordsE193
_ZN4PLMD3ves11TD_GaussianC2ERKNS_13ActionOptionsE191
_ZNK4PLMD3ves11TD_Gaussian10Gaussian2DERKSt6vectorIdSaIdEES6_S6_S6_b40804
_ZNK4PLMD3ves11TD_Gaussian16GaussianDiagonalERKSt6vectorIdSaIdEES6_S6_b292252
_ZNK4PLMD3ves11TD_Gaussian8getValueERKSt6vectorIdSaIdEE229739
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_Gaussian.cpp.gcov.html b/coverage/ves/TD_Gaussian.cpp.gcov.html new file mode 100644 index 000000000000..ee154ee7cac8 --- /dev/null +++ b/coverage/ves/TD_Gaussian.cpp.gcov.html @@ -0,0 +1,392 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_Gaussian.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_Gaussian.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:768490.5 %
Date:2024-04-19 12:12:35Functions:55100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "TargetDistribution.h"
+      24             : 
+      25             : #include "core/ActionRegister.h"
+      26             : 
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace ves {
+      30             : 
+      31             : //+PLUMEDOC VES_TARGETDIST TD_GAUSSIAN
+      32             : /*
+      33             : Target distribution given by a sum of Gaussian kernels (static).
+      34             : 
+      35             : Employ a target distribution that is given by a sum of multivariate Gaussian (or normal)
+      36             : distributions, defined as
+      37             : \f[
+      38             : p(\mathbf{s}) = \sum_{i} \, w_{i} \, N(\mathbf{s};\mathbf{\mu}_{i},\mathbf{\Sigma}_{i})
+      39             : \f]
+      40             : where \f$\mathbf{\mu}_{i}=(\mu_{1,i},\mu_{2,i},\ldots,\mu_{d,i})\f$
+      41             : and \f$\mathbf{\Sigma}_{i}\f$ are
+      42             : the center and the covariance matrix for the \f$i\f$-th Gaussian.
+      43             : The weights \f$w_{i}\f$ are normalized to 1, \f$\sum_{i}w_{i}=1\f$.
+      44             : 
+      45             : By default the Gaussian distributions are considered as separable into
+      46             : independent one-dimensional Gaussian distributions. In other words,
+      47             : the covariance matrix is taken as diagonal
+      48             : \f$\mathbf{\Sigma}_{i}=(\sigma^2_{1,i},\sigma^2_{2,i},\ldots,\sigma^{2}_{d,i})\f$.
+      49             : The Gaussian distribution is then written as
+      50             : \f[
+      51             : N(\mathbf{s};\mathbf{\mu}_{i},\mathbf{\sigma}_{i}) =
+      52             : \prod^{d}_{k} \, \frac{1}{\sqrt{2\pi\sigma^2_{d,i}}} \,
+      53             : \exp\left(
+      54             : -\frac{(s_{d}-\mu_{d,i})^2}{2\sigma^2_{d,i}}
+      55             : \right)
+      56             : \f]
+      57             : where
+      58             : \f$\mathbf{\sigma}_{i}=(\sigma_{1,i},\sigma_{2,i},\ldots,\sigma_{d,i})\f$
+      59             : is the standard deviation.
+      60             : In this case you need to specify the centers \f$\mathbf{\mu}_{i}\f$ using the
+      61             : numbered CENTER keywords and the standard deviations \f$\mathbf{\sigma}_{i}\f$
+      62             : using the numbered SIGMA keywords.
+      63             : 
+      64             : For two arguments it is possible to employ
+      65             : [bivariate Gaussian kernels](https://en.wikipedia.org/wiki/Multivariate_normal_distribution)
+      66             : with correlation between arguments, defined as
+      67             : \f[
+      68             : N(\mathbf{s};\mathbf{\mu}_{i},\mathbf{\sigma}_{i},\rho_i) =
+      69             : \frac{1}{2 \pi \sigma_{1,i} \sigma_{2,i} \sqrt{1-\rho_i^2}}
+      70             : \,
+      71             : \exp\left(
+      72             : -\frac{1}{2(1-\rho_i^2)}
+      73             : \left[
+      74             : \frac{(s_{1}-\mu_{1,i})^2}{\sigma_{1,i}^2}+
+      75             : \frac{(s_{2}-\mu_{2,i})^2}{\sigma_{2,i}^2}-
+      76             : \frac{2 \rho_i (s_{1}-\mu_{1,i})(s_{2}-\mu_{2,i})}{\sigma_{1,i}\sigma_{2,i}}
+      77             : \right]
+      78             : \right)
+      79             : \f]
+      80             : where \f$\rho_i\f$ is the correlation between \f$s_{1}\f$ and \f$s_{2}\f$
+      81             : that goes from -1 to 1. In this case the covariance matrix is given as
+      82             : \f[
+      83             : \mathbf{\Sigma}=
+      84             : \left[
+      85             : \begin{array}{cc}
+      86             : \sigma^2_{1,i} & \rho_i \sigma_{1,i} \sigma_{2,i} \\
+      87             : \rho_i \sigma_{1,i} \sigma_{2,i} & \sigma^2_{2,i}
+      88             : \end{array}
+      89             : \right]
+      90             : \f]
+      91             : The correlation \f$\rho\f$ is given using
+      92             : the numbered CORRELATION keywords. A value of \f$\rho=0\f$ means
+      93             : that the arguments are considered as
+      94             : un-correlated, which is the default behavior.
+      95             : 
+      96             : The Gaussian distributions are always defined with the conventional
+      97             : normalization factor such that they are normalized to 1 over an unbounded
+      98             : region. However, in calculation within VES we normally consider bounded
+      99             : region on which the target distribution is defined. Thus, if the center of
+     100             : a Gaussian is close to the boundary of the region it can happen that the
+     101             : tails go outside the region. In that case it might be needed to use the
+     102             : NORMALIZE keyword to make sure that the target distribution is properly
+     103             : normalized to 1 over the bounded region. The code will issue a warning
+     104             : if that is needed.
+     105             : 
+     106             : For periodic CVs it is generally better to use \ref TD_VONMISES "Von Mises"
+     107             : distributions instead of Gaussian kernels as these distributions properly
+     108             : account for the periodicity of the CVs.
+     109             : 
+     110             : 
+     111             : \par Examples
+     112             : 
+     113             : One single Gaussian kernel in one-dimension.
+     114             : \plumedfile
+     115             : td: TD_GAUSSIAN CENTER1=-1.5 SIGMA1=0.8
+     116             : \endplumedfile
+     117             : 
+     118             : Sum of three Gaussian kernels in two-dimensions with equal weights as
+     119             : no weights are given.
+     120             : \plumedfile
+     121             : TD_GAUSSIAN ...
+     122             :  CENTER1=-1.5,+1.5 SIGMA1=0.8,0.3
+     123             :  CENTER2=+1.5,-1.5 SIGMA2=0.3,0.8
+     124             :  CENTER3=+1.5,+1.5 SIGMA3=0.4,0.4
+     125             :  LABEL=td
+     126             : ... TD_GAUSSIAN
+     127             : \endplumedfile
+     128             : 
+     129             : Sum of three Gaussian kernels in two-dimensions which
+     130             : are weighted unequally. Note that weights are automatically
+     131             : normalized to 1 so that WEIGHTS=1.0,2.0,1.0 is equal to
+     132             : specifying WEIGHTS=0.25,0.50,0.25.
+     133             : \plumedfile
+     134             : TD_GAUSSIAN ...
+     135             :  CENTER1=-1.5,+1.5 SIGMA1=0.8,0.3
+     136             :  CENTER2=+1.5,-1.5 SIGMA2=0.3,0.8
+     137             :  CENTER3=+1.5,+1.5 SIGMA3=0.4,0.4
+     138             :  WEIGHTS=1.0,2.0,1.0
+     139             :  LABEL=td
+     140             : ... TD_GAUSSIAN
+     141             : \endplumedfile
+     142             : 
+     143             : Sum of two bivariate Gaussian kernels where there is correlation of
+     144             : \f$\rho_{2}=0.75\f$ between the two arguments for the second Gaussian.
+     145             : \plumedfile
+     146             : TD_GAUSSIAN ...
+     147             :  CENTER1=-1.5,+1.5 SIGMA1=0.8,0.3
+     148             :  CENTER2=+1.5,-1.5 SIGMA2=0.3,0.8 CORRELATION2=0.75
+     149             :  LABEL=td
+     150             : ... TD_GAUSSIAN
+     151             : \endplumedfile
+     152             : 
+     153             : 
+     154             : 
+     155             : 
+     156             : 
+     157             : */
+     158             : //+ENDPLUMEDOC
+     159             : 
+     160             : class TD_Gaussian: public TargetDistribution {
+     161             :   std::vector< std::vector<double> > centers_;
+     162             :   std::vector< std::vector<double> > sigmas_;
+     163             :   std::vector< std::vector<double> > correlation_;
+     164             :   std::vector<double> weights_;
+     165             :   bool diagonal_;
+     166             :   unsigned int ncenters_;
+     167             :   double GaussianDiagonal(const std::vector<double>&, const std::vector<double>&, const std::vector<double>&, const bool normalize=true) const;
+     168             :   double Gaussian2D(const std::vector<double>&, const std::vector<double>&, const std::vector<double>&, const std::vector<double>&, const bool normalize=true) const;
+     169             : public:
+     170             :   static void registerKeywords(Keywords&);
+     171             :   explicit TD_Gaussian(const ActionOptions& ao);
+     172             :   double getValue(const std::vector<double>&) const override;
+     173             : };
+     174             : 
+     175             : 
+     176             : PLUMED_REGISTER_ACTION(TD_Gaussian,"TD_GAUSSIAN")
+     177             : 
+     178             : 
+     179         193 : void TD_Gaussian::registerKeywords(Keywords& keys) {
+     180         193 :   TargetDistribution::registerKeywords(keys);
+     181         386 :   keys.add("numbered","CENTER","The centers of the Gaussian distributions.");
+     182         386 :   keys.add("numbered","SIGMA","The standard deviations of the Gaussian distributions.");
+     183         386 :   keys.add("numbered","CORRELATION","The correlation for two-dimensional bivariate Gaussian distributions. Only works for two arguments. The value should be between -1 and 1. If no value is given the Gaussian kernels is considered as un-correlated (i.e. value of 0.0).");
+     184         386 :   keys.add("optional","WEIGHTS","The weights of the Gaussian distributions. Have to be as many as the number of centers given with the numbered CENTER keywords. If no weights are given the distributions are weighted equally. The weights are automatically normalized to 1.");
+     185         193 :   keys.use("WELLTEMPERED_FACTOR");
+     186         193 :   keys.use("SHIFT_TO_ZERO");
+     187         193 :   keys.use("NORMALIZE");
+     188         193 : }
+     189             : 
+     190             : 
+     191         191 : TD_Gaussian::TD_Gaussian(const ActionOptions& ao):
+     192             :   PLUMED_VES_TARGETDISTRIBUTION_INIT(ao),
+     193         382 :   centers_(0),
+     194         191 :   sigmas_(0),
+     195         191 :   correlation_(0),
+     196         191 :   weights_(0),
+     197         191 :   diagonal_(true),
+     198         382 :   ncenters_(0)
+     199             : {
+     200         211 :   for(unsigned int i=1;; i++) {
+     201             :     std::vector<double> tmp_center;
+     202         804 :     if(!parseNumberedVector("CENTER",i,tmp_center) ) {break;}
+     203         211 :     centers_.push_back(tmp_center);
+     204         211 :   }
+     205         211 :   for(unsigned int i=1;; i++) {
+     206             :     std::vector<double> tmp_sigma;
+     207         804 :     if(!parseNumberedVector("SIGMA",i,tmp_sigma) ) {break;}
+     208         211 :     sigmas_.push_back(tmp_sigma);
+     209         211 :   }
+     210             : 
+     211         191 :   if(centers_.size()==0) {
+     212           0 :     plumed_merror(getName()+": CENTER keywords seem to be missing. Note that numbered keywords start at CENTER1.");
+     213             :   }
+     214             :   //
+     215         191 :   if(centers_.size()!=sigmas_.size()) {
+     216           0 :     plumed_merror(getName()+": there has to be an equal amount of CENTER and SIGMA keywords");
+     217             :   }
+     218             :   //
+     219         191 :   setDimension(centers_[0].size());
+     220         191 :   ncenters_ = centers_.size();
+     221             :   // check centers and sigmas
+     222         402 :   for(unsigned int i=0; i<ncenters_; i++) {
+     223         211 :     if(centers_[i].size()!=getDimension()) {
+     224           0 :       plumed_merror(getName()+": one of the CENTER keyword does not match the given dimension");
+     225             :     }
+     226         211 :     if(sigmas_[i].size()!=getDimension()) {
+     227           0 :       plumed_merror(getName()+": one of the SIGMA keyword does not match the given dimension");
+     228             :     }
+     229             :   }
+     230             :   //
+     231         191 :   correlation_.resize(ncenters_);
+     232             : 
+     233         402 :   for(unsigned int i=0; i<ncenters_; i++) {
+     234             :     std::vector<double> corr;
+     235         422 :     parseNumberedVector("CORRELATION",(i+1),corr);
+     236         211 :     if(corr.size()>0) {
+     237           3 :       diagonal_ = false;
+     238             :     }
+     239             :     else {
+     240         208 :       corr.assign(1,0.0);
+     241             :     }
+     242         211 :     correlation_[i] = corr;
+     243             :   }
+     244             : 
+     245         191 :   if(!diagonal_ && getDimension()!=2) {
+     246           0 :     plumed_merror(getName()+": CORRELATION is only defined for two-dimensional Gaussians for now.");
+     247             :   }
+     248         402 :   for(unsigned int i=0; i<correlation_.size(); i++) {
+     249         211 :     if(correlation_[i].size()!=1) {
+     250           0 :       plumed_merror(getName()+": only one value should be given in CORRELATION");
+     251             :     }
+     252         422 :     for(unsigned int k=0; k<correlation_[i].size(); k++) {
+     253         211 :       if(correlation_[i][k] <= -1.0 ||  correlation_[i][k] >= 1.0) {
+     254           0 :         plumed_merror(getName()+": values given in CORRELATION should be between -1.0 and 1.0" );
+     255             :       }
+     256             :     }
+     257             :   }
+     258             :   //
+     259         382 :   parseVector("WEIGHTS",weights_);
+     260         191 :   if(weights_.size()==0) {weights_.assign(centers_.size(),1.0);}
+     261         191 :   if(centers_.size()!=weights_.size()) {
+     262           0 :     plumed_merror(getName()+": there has to be as many weights given in WEIGHTS as numbered CENTER keywords");
+     263             :   }
+     264             :   //
+     265             :   double sum_weights=0.0;
+     266         402 :   for(unsigned int i=0; i<weights_.size(); i++) {sum_weights+=weights_[i];}
+     267         402 :   for(unsigned int i=0; i<weights_.size(); i++) {weights_[i]/=sum_weights;}
+     268             :   //
+     269         191 :   checkRead();
+     270         191 : }
+     271             : 
+     272             : 
+     273      229739 : double TD_Gaussian::getValue(const std::vector<double>& argument) const {
+     274             :   double value=0.0;
+     275      229739 :   if(diagonal_) {
+     276      501589 :     for(unsigned int i=0; i<ncenters_; i++) {
+     277      292252 :       value+=weights_[i]*GaussianDiagonal(argument, centers_[i], sigmas_[i]);
+     278             :     }
+     279             :   }
+     280       20402 :   else if(!diagonal_ && getDimension()==2) {
+     281       61206 :     for(unsigned int i=0; i<ncenters_; i++) {
+     282       40804 :       value+=weights_[i]*Gaussian2D(argument, centers_[i], sigmas_[i],correlation_[i]);
+     283             :     }
+     284             :   }
+     285      229739 :   return value;
+     286             : }
+     287             : 
+     288             : 
+     289      292252 : double TD_Gaussian::GaussianDiagonal(const std::vector<double>& argument, const std::vector<double>& center, const std::vector<double>& sigma, bool normalize) const {
+     290             :   double value = 1.0;
+     291      828323 :   for(unsigned int k=0; k<argument.size(); k++) {
+     292      536071 :     double arg=(argument[k]-center[k])/sigma[k];
+     293      536071 :     double tmp_exp = exp(-0.5*arg*arg);
+     294      536071 :     if(normalize) {tmp_exp/=(sigma[k]*sqrt(2.0*pi));}
+     295      536071 :     value*=tmp_exp;
+     296             :   }
+     297      292252 :   return value;
+     298             : }
+     299             : 
+     300             : 
+     301       40804 : double TD_Gaussian::Gaussian2D(const std::vector<double>& argument, const std::vector<double>& center, const std::vector<double>& sigma, const std::vector<double>& correlation, bool normalize) const {
+     302       40804 :   double arg1 = (argument[0]-center[0])/sigma[0];
+     303       40804 :   double arg2 = (argument[1]-center[1])/sigma[1];
+     304       40804 :   double corr = correlation[0];
+     305       40804 :   double value = (arg1*arg1 + arg2*arg2 - 2.0*corr*arg1*arg2);
+     306       40804 :   value *= -1.0 / ( 2.0*(1.0-corr*corr) );
+     307       40804 :   value = exp(value);
+     308       40804 :   if(normalize) {
+     309       40804 :     value /=  2*pi*sigma[0]*sigma[1]*sqrt(1.0-corr*corr);
+     310             :   }
+     311       40804 :   return value;
+     312             : }
+     313             : 
+     314             : }
+     315             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_GeneralizedExtremeValue.cpp.func-sort-c.html b/coverage/ves/TD_GeneralizedExtremeValue.cpp.func-sort-c.html new file mode 100644 index 000000000000..272ab89d6b12 --- /dev/null +++ b/coverage/ves/TD_GeneralizedExtremeValue.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_GeneralizedExtremeValue.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_GeneralizedExtremeValue.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3838100.0 %
Date:2024-04-19 12:12:35Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves26TD_GeneralizedExtremeValueC2ERKNS_13ActionOptionsE5
_ZN4PLMD3ves26TD_GeneralizedExtremeValue16registerKeywordsERNS_8KeywordsE7
_ZNK4PLMD3ves26TD_GeneralizedExtremeValue11GEVdiagonalERKSt6vectorIdSaIdEES6_S6_S6_S6_1605
_ZNK4PLMD3ves26TD_GeneralizedExtremeValue8getValueERKSt6vectorIdSaIdEE1605
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_GeneralizedExtremeValue.cpp.func.html b/coverage/ves/TD_GeneralizedExtremeValue.cpp.func.html new file mode 100644 index 000000000000..ebea04285fcd --- /dev/null +++ b/coverage/ves/TD_GeneralizedExtremeValue.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_GeneralizedExtremeValue.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_GeneralizedExtremeValue.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3838100.0 %
Date:2024-04-19 12:12:35Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves26TD_GeneralizedExtremeValue16registerKeywordsERNS_8KeywordsE7
_ZN4PLMD3ves26TD_GeneralizedExtremeValueC2ERKNS_13ActionOptionsE5
_ZNK4PLMD3ves26TD_GeneralizedExtremeValue11GEVdiagonalERKSt6vectorIdSaIdEES6_S6_S6_S6_1605
_ZNK4PLMD3ves26TD_GeneralizedExtremeValue8getValueERKSt6vectorIdSaIdEE1605
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_GeneralizedExtremeValue.cpp.gcov.html b/coverage/ves/TD_GeneralizedExtremeValue.cpp.gcov.html new file mode 100644 index 000000000000..c796c0ef2399 --- /dev/null +++ b/coverage/ves/TD_GeneralizedExtremeValue.cpp.gcov.html @@ -0,0 +1,254 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_GeneralizedExtremeValue.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_GeneralizedExtremeValue.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3838100.0 %
Date:2024-04-19 12:12:35Functions:44100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "TargetDistribution.h"
+      24             : 
+      25             : #include "core/ActionRegister.h"
+      26             : 
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace ves {
+      30             : 
+      31             : //+PLUMEDOC VES_TARGETDIST TD_GENERALIZED_EXTREME_VALUE
+      32             : /*
+      33             : Generalized extreme value distribution (static).
+      34             : 
+      35             : Employ a target distribution given by a
+      36             : [generalized extreme value distribution](https://en.wikipedia.org/wiki/Generalized_extreme_value_distribution)
+      37             : that is defined as
+      38             : \f[
+      39             : p(s) =
+      40             : \frac{1}{\sigma} \, t(s)^{\xi+1} \, e^{-t(s)},
+      41             : \f]
+      42             : where
+      43             : \f[
+      44             : t(s) =
+      45             : \begin{cases}
+      46             : \left( 1 + \xi \left( \frac{s-\mu}{\sigma} \right) \right)^{-1/\xi} & \mathrm{if\ }\xi \neq 0 \\
+      47             : \exp\left(- \frac{s-\mu}{\sigma} \right) & \mathrm{if\ } \xi = 0
+      48             : \end{cases},
+      49             : \f]
+      50             : and \f$\mu\f$ is the location parameter which approximately determines the location of the
+      51             : maximum of the distribution, \f$\sigma>0\f$ is the scale parameter that determines the
+      52             : broadness of the distribution, and \f$\xi\f$ is the shape parameter that determines
+      53             : the tail behavior of the distribution. For \f$\xi=0\f$, \f$\xi>0\f$, and \f$\xi<0\f$
+      54             : the Gumbel, Frechet, and Weibull families of distributions are obtained, respectively.
+      55             : 
+      56             : The location parameter \f$\mu\f$ is given using the LOCATION keyword, the scale parameter \f$\sigma\f$
+      57             : using the SCALE keyword, and the shape parameter \f$\xi\f$ using the SHAPE
+      58             : keyword.
+      59             : 
+      60             : This target distribution action is only defined for one dimension, for multiple dimensions
+      61             : it should be used in combination with \ref TD_PRODUCT_DISTRIBUTION action.
+      62             : 
+      63             : \par Examples
+      64             : 
+      65             : Generalized extreme value distribution with \f$\mu=0.0\f$, \f$\sigma=2.0\f$, and \f$\xi=0.0\f$ (Gumbel distribution)
+      66             : \plumedfile
+      67             : td: TD_GENERALIZED_EXTREME_VALUE  LOCATION=0.0  SCALE=2.0 SHAPE=0.0
+      68             : \endplumedfile
+      69             : 
+      70             : 
+      71             : Generalized extreme value distribution with \f$\mu=-5.0\f$, \f$\sigma=1.0\f$, and \f$\xi=0.5\f$ (Frechet distribution)
+      72             : \plumedfile
+      73             : td: TD_GENERALIZED_EXTREME_VALUE  LOCATION=-5.0  SCALE=1.0 SHAPE=0.5
+      74             : \endplumedfile
+      75             : 
+      76             : 
+      77             : Generalized extreme value distribution with \f$\mu=5.0\f$, \f$\sigma=2.0\f$, and \f$\xi=-0.5\f$ (Weibull distribution)
+      78             : \plumedfile
+      79             : td: TD_GENERALIZED_EXTREME_VALUE  LOCATION=5.0  SCALE=1.0 SHAPE=-0.5
+      80             : \endplumedfile
+      81             : 
+      82             : 
+      83             : The generalized extreme value distribution is only defined for one dimension so for multiple
+      84             : dimensions we have to use it in combination with the \ref TD_PRODUCT_DISTRIBUTION action as shown in
+      85             : the following example where we have a Generalized extreme value distribution for argument 1
+      86             : and uniform distribution for argument 2
+      87             : \plumedfile
+      88             : td_gev: TD_GENERALIZED_EXTREME_VALUE  LOCATION=-5.0  SCALE=1.0 SHAPE=0.5
+      89             : 
+      90             : td_uni: TD_UNIFORM
+      91             : 
+      92             : td_pd: TD_PRODUCT_DISTRIBUTION DISTRIBUTIONS=td_gev,td_uni
+      93             : \endplumedfile
+      94             : 
+      95             : 
+      96             : */
+      97             : //+ENDPLUMEDOC
+      98             : 
+      99             : class TD_GeneralizedExtremeValue: public TargetDistribution {
+     100             :   std::vector<double> center_;
+     101             :   std::vector<double> scale_;
+     102             :   std::vector<double> shape_;
+     103             :   std::vector<double> normalization_;
+     104             :   double GEVdiagonal(const std::vector<double>&, const std::vector<double>&, const std::vector<double>&, const std::vector<double>&, const std::vector<double>&) const;
+     105             : public:
+     106             :   static void registerKeywords(Keywords&);
+     107             :   explicit TD_GeneralizedExtremeValue(const ActionOptions& ao);
+     108             :   double getValue(const std::vector<double>&) const override;
+     109             : };
+     110             : 
+     111             : 
+     112             : PLUMED_REGISTER_ACTION(TD_GeneralizedExtremeValue,"TD_GENERALIZED_EXTREME_VALUE")
+     113             : 
+     114             : 
+     115           7 : void TD_GeneralizedExtremeValue::registerKeywords(Keywords& keys) {
+     116           7 :   TargetDistribution::registerKeywords(keys);
+     117          14 :   keys.add("compulsory","LOCATION","The mu parameter of the generalized extreme value distribution.");
+     118          14 :   keys.add("compulsory","SCALE","The sigma parameter for the generalized extreme value distribution given as a positive number.");
+     119          14 :   keys.add("compulsory","SHAPE","The xi parameter for the generalized extreme value distribution.");
+     120           7 :   keys.use("WELLTEMPERED_FACTOR");
+     121           7 :   keys.use("SHIFT_TO_ZERO");
+     122           7 :   keys.use("NORMALIZE");
+     123           7 : }
+     124             : 
+     125             : 
+     126           5 : TD_GeneralizedExtremeValue::TD_GeneralizedExtremeValue(const ActionOptions& ao):
+     127             :   PLUMED_VES_TARGETDISTRIBUTION_INIT(ao),
+     128          10 :   center_(0),
+     129           5 :   scale_(0),
+     130           5 :   shape_(0),
+     131          10 :   normalization_(0)
+     132             : {
+     133           5 :   parseVector("LOCATION",center_);
+     134           5 :   parseVector("SCALE",scale_);
+     135          10 :   parseVector("SHAPE",shape_);
+     136             : 
+     137           5 :   setDimension(center_.size());
+     138           5 :   if(getDimension()>1) {plumed_merror(getName()+": only defined for one dimension, for multiple dimensions it should be used in combination with the TD_PRODUCT_DISTRIBUTION action.");}
+     139           5 :   if(scale_.size()!=getDimension()) {plumed_merror(getName()+": the SCALE keyword does not match the given dimension in MINIMA");}
+     140           5 :   if(shape_.size()!=getDimension()) {plumed_merror(getName()+": the SHAPE keyword does not match the given dimension in MINIMA");}
+     141             : 
+     142           5 :   normalization_.resize(getDimension());
+     143          10 :   for(unsigned int k=0; k<getDimension(); k++) {
+     144           5 :     if(scale_[k]<0.0) {plumed_merror(getName()+": the value given for the scale parameter in SCALE should be larger than 0.0");}
+     145           5 :     normalization_[k] = 1.0/scale_[k];
+     146             :   }
+     147           5 :   checkRead();
+     148           5 : }
+     149             : 
+     150             : 
+     151        1605 : double TD_GeneralizedExtremeValue::getValue(const std::vector<double>& argument) const {
+     152        1605 :   return GEVdiagonal(argument,center_,scale_,shape_,normalization_);
+     153             : }
+     154             : 
+     155             : 
+     156        1605 : double TD_GeneralizedExtremeValue::GEVdiagonal(const std::vector<double>& argument, const std::vector<double>& center, const std::vector<double>& scale, const std::vector<double>& shape, const std::vector<double>& normalization) const {
+     157             :   double value = 1.0;
+     158        2940 :   for(unsigned int k=0; k<argument.size(); k++) {
+     159        1605 :     double arg=(argument[k]-center[k])/scale[k];
+     160             :     double tx;
+     161        1605 :     if(shape_[k]!=0.0) {
+     162        1404 :       if( shape_[k]>0 && argument[k] <= (center[k]-scale[k]/shape[k]) ) {return 0.0;}
+     163        1214 :       if( shape_[k]<0 && argument[k] > (center[k]-scale[k]/shape[k]) ) {return 0.0;}
+     164        1134 :       tx = pow( (1.0+arg*shape[k]), -1.0/shape[k] );
+     165             :     }
+     166             :     else {
+     167         201 :       tx = exp(-arg);
+     168             :     }
+     169        1335 :     value *= normalization[k] * pow(tx,shape[k]+1.0) * exp(-tx);
+     170             :   }
+     171             :   return value;
+     172             : }
+     173             : 
+     174             : 
+     175             : 
+     176             : }
+     177             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_GeneralizedNormal.cpp.func-sort-c.html b/coverage/ves/TD_GeneralizedNormal.cpp.func-sort-c.html new file mode 100644 index 000000000000..17513b5eafbb --- /dev/null +++ b/coverage/ves/TD_GeneralizedNormal.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_GeneralizedNormal.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_GeneralizedNormal.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:636991.3 %
Date:2024-04-19 12:12:35Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves20TD_GeneralizedNormalC2ERKNS_13ActionOptionsE8
_ZN4PLMD3ves20TD_GeneralizedNormal16registerKeywordsERNS_8KeywordsE10
_ZNK4PLMD3ves20TD_GeneralizedNormal8getValueERKSt6vectorIdSaIdEE21608
_ZNK4PLMD3ves20TD_GeneralizedNormal24ExponentialPowerDiagonalERKSt6vectorIdSaIdEES6_S6_S6_S6_53015
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_GeneralizedNormal.cpp.func.html b/coverage/ves/TD_GeneralizedNormal.cpp.func.html new file mode 100644 index 000000000000..17a37d51f593 --- /dev/null +++ b/coverage/ves/TD_GeneralizedNormal.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_GeneralizedNormal.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_GeneralizedNormal.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:636991.3 %
Date:2024-04-19 12:12:35Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves20TD_GeneralizedNormal16registerKeywordsERNS_8KeywordsE10
_ZN4PLMD3ves20TD_GeneralizedNormalC2ERKNS_13ActionOptionsE8
_ZNK4PLMD3ves20TD_GeneralizedNormal24ExponentialPowerDiagonalERKSt6vectorIdSaIdEES6_S6_S6_S6_53015
_ZNK4PLMD3ves20TD_GeneralizedNormal8getValueERKSt6vectorIdSaIdEE21608
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_GeneralizedNormal.cpp.gcov.html b/coverage/ves/TD_GeneralizedNormal.cpp.gcov.html new file mode 100644 index 000000000000..d47b2ebd9333 --- /dev/null +++ b/coverage/ves/TD_GeneralizedNormal.cpp.gcov.html @@ -0,0 +1,304 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_GeneralizedNormal.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_GeneralizedNormal.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:636991.3 %
Date:2024-04-19 12:12:35Functions:44100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "TargetDistribution.h"
+      24             : 
+      25             : #include "core/ActionRegister.h"
+      26             : 
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace ves {
+      30             : 
+      31             : //+PLUMEDOC VES_TARGETDIST TD_GENERALIZED_NORMAL
+      32             : /*
+      33             : Target distribution given by a sum of generalized normal distributions (static).
+      34             : 
+      35             : Employ a target distribution that is given by a sum where each
+      36             : term is a product of one-dimensional
+      37             : [generalized normal distributions](https://en.wikipedia.org/wiki/Generalized_normal_distribution)
+      38             : (version 1, also know as an exponential power distribution), defined as
+      39             : \f[
+      40             : p(\mathbf{s}) = \sum_{i} \, w_{i}
+      41             : \prod_{k}^{d}
+      42             : \frac{\beta_{k,i}}{2 \, \alpha_{k,i} \, \Gamma(1/\beta_{k,i})}
+      43             : \exp\left( -\left\vert \frac{s_{k}-\mu_{k,i}}{\alpha_{k,i}} \right\vert^{\beta_{k,i}} \right)
+      44             : \f]
+      45             : where \f$(\mu_{1,i},\mu_{2,i},\ldots,\mu_{d,i})\f$
+      46             : are the centers of the distributions,
+      47             : \f$(\alpha_{1,i},\alpha_{2,i},\ldots,\alpha_{d,i})\f$ are the scale
+      48             : parameters of the distributions,
+      49             : \f$(\beta_{1,i},\beta_{2,i},\ldots,\beta_{d,i})\f$ are the shape
+      50             : parameters of the distributions, and \f$\Gamma(x)\f$ is the
+      51             : gamma function.
+      52             : The weights \f$w_{i}\f$ are normalized to 1, \f$\sum_{i}w_{i}=1\f$.
+      53             : 
+      54             : Employing \f$\beta=2\f$ results in a
+      55             : Gaussian (normal) distributions with mean
+      56             : \f$\mu\f$ and variance \f$\alpha^2/2\f$,
+      57             : \f$\beta=1\f$ gives the Laplace distribution, and
+      58             : the limit \f$\beta \to \infty\f$ results in a
+      59             : uniform  distribution on the interval \f$[\mu-\alpha,\mu+\alpha]\f$.
+      60             : 
+      61             : The centers \f$(\mu_{1,i},\mu_{2,i},\ldots,\mu_{d,i})\f$
+      62             : are given using the numbered CENTER keywords, the scale
+      63             : parameters \f$(\alpha_{1,i},\alpha_{2,i},\ldots,\alpha_{d,i})\f$
+      64             : using the numbered SCALE keywords, and the shape parameters
+      65             : \f$(\beta_{1,i},\beta_{2,i},\ldots,\beta_{d,i})\f$ using the
+      66             : numbered SHAPE keywords.
+      67             : The weights are given using the WEIGHTS keywords, if no weights are
+      68             : given are all terms weighted equally.
+      69             : 
+      70             : \par Examples
+      71             : 
+      72             : A generalized normal distribution in one-dimensional
+      73             : \plumedfile
+      74             : td1: TD_GENERALIZED_NORMAL CENTER1=+20.0  ALPHA1=5.0  BETA1=4.0
+      75             : \endplumedfile
+      76             : 
+      77             : A sum of two one-dimensional generalized normal distributions
+      78             : \plumedfile
+      79             : TD_GENERALIZED_NORMAL ...
+      80             :  CENTER1=+20.0  ALPHA1=5.0  BETA1=4.0
+      81             :  CENTER2=-20.0  ALPHA2=5.0  BETA2=3.0
+      82             :  LABEL=td1
+      83             : ... TD_GENERALIZED_NORMAL
+      84             : \endplumedfile
+      85             : 
+      86             : A sum of two two-dimensional generalized normal distributions
+      87             : \plumedfile
+      88             : TD_GENERALIZED_NORMAL ...
+      89             :  CENTER1=-20.0,-20.0 ALPHA1=5.0,3.0 BETA1=2.0,4.0
+      90             :  CENTER2=-20.0,+20.0 ALPHA2=3.0,5.0 BETA2=4.0,2.0
+      91             :  WEIGHTS=2.0,1.0
+      92             :  LABEL=td1
+      93             : ... TD_GENERALIZED_NORMAL
+      94             : \endplumedfile
+      95             : 
+      96             : */
+      97             : //+ENDPLUMEDOC
+      98             : 
+      99             : class TD_GeneralizedNormal: public TargetDistribution {
+     100             :   std::vector< std::vector<double> > centers_;
+     101             :   std::vector< std::vector<double> > alphas_;
+     102             :   std::vector< std::vector<double> > betas_;
+     103             :   std::vector< std::vector<double> > normalization_;
+     104             :   std::vector<double> weights_;
+     105             :   unsigned int ncenters_;
+     106             :   double ExponentialPowerDiagonal(const std::vector<double>&, const std::vector<double>&, const std::vector<double>&, const std::vector<double>&, const std::vector<double>&) const;
+     107             : public:
+     108             :   static void registerKeywords(Keywords&);
+     109             :   explicit TD_GeneralizedNormal(const ActionOptions& ao);
+     110             :   double getValue(const std::vector<double>&) const override;
+     111             : };
+     112             : 
+     113             : 
+     114             : PLUMED_REGISTER_ACTION(TD_GeneralizedNormal,"TD_GENERALIZED_NORMAL")
+     115             : 
+     116             : 
+     117          10 : void TD_GeneralizedNormal::registerKeywords(Keywords& keys) {
+     118          10 :   TargetDistribution::registerKeywords(keys);
+     119          20 :   keys.add("numbered","CENTER","The center of each generalized normal distribution.");
+     120          20 :   keys.add("numbered","ALPHA","The alpha parameters for each generalized normal distribution.");
+     121          20 :   keys.add("numbered","BETA","The beta parameters for each generalized normal distribution.");
+     122          20 :   keys.add("optional","WEIGHTS","The weights of the generalized normal distribution. By default all are weighted equally.");
+     123          10 :   keys.use("WELLTEMPERED_FACTOR");
+     124          10 :   keys.use("SHIFT_TO_ZERO");
+     125          10 :   keys.use("NORMALIZE");
+     126          10 : }
+     127             : 
+     128             : 
+     129           8 : TD_GeneralizedNormal::TD_GeneralizedNormal(const ActionOptions& ao):
+     130             :   PLUMED_VES_TARGETDISTRIBUTION_INIT(ao),
+     131          16 :   centers_(0),
+     132           8 :   alphas_(0),
+     133           8 :   betas_(0),
+     134           8 :   normalization_(0),
+     135           8 :   weights_(0),
+     136          16 :   ncenters_(0)
+     137             : {
+     138          15 :   for(unsigned int i=1;; i++) {
+     139             :     std::vector<double> tmp_center;
+     140          46 :     if(!parseNumberedVector("CENTER",i,tmp_center) ) {break;}
+     141          15 :     centers_.push_back(tmp_center);
+     142          15 :   }
+     143          15 :   for(unsigned int i=1;; i++) {
+     144             :     std::vector<double> tmp_alpha;
+     145          46 :     if(!parseNumberedVector("ALPHA",i,tmp_alpha) ) {break;}
+     146          35 :     for(unsigned int k=0; k<tmp_alpha.size(); k++) {
+     147          20 :       if(tmp_alpha[k]<=0.0) {plumed_merror(getName()+": the values given in ALPHA should be positive");}
+     148             :     }
+     149          15 :     alphas_.push_back(tmp_alpha);
+     150          15 :   }
+     151          15 :   for(unsigned int i=1;; i++) {
+     152             :     std::vector<double> tmp_beta;
+     153          46 :     if(!parseNumberedVector("BETA",i,tmp_beta) ) {break;}
+     154          35 :     for(unsigned int k=0; k<tmp_beta.size(); k++) {
+     155          20 :       if(tmp_beta[k]<=0.0) {plumed_merror(getName()+": the values given in BETA should be positive");}
+     156             :     }
+     157          15 :     betas_.push_back(tmp_beta);
+     158          15 :   }
+     159             :   //
+     160           8 :   if(centers_.size()==0) {
+     161           0 :     plumed_merror(getName()+": CENTER keywords seem to be missing. Note that numbered keywords start at CENTER1.");
+     162             :   }
+     163             :   //
+     164           8 :   if(centers_.size()!=alphas_.size() || centers_.size()!=betas_.size() ) {
+     165           0 :     plumed_merror(getName()+": there has to be an equal amount of CENTER, ALPHA, and BETA keywords");
+     166             :   }
+     167             :   //
+     168           8 :   setDimension(centers_[0].size());
+     169           8 :   ncenters_ = centers_.size();
+     170             :   //
+     171             :   // check centers and sigmas
+     172          23 :   for(unsigned int i=0; i<ncenters_; i++) {
+     173          15 :     if(centers_[i].size()!=getDimension()) {
+     174           0 :       plumed_merror(getName()+": one of the CENTER keyword does not match the given dimension");
+     175             :     }
+     176          15 :     if(alphas_[i].size()!=getDimension()) {
+     177           0 :       plumed_merror(getName()+": one of the ALPHA keyword does not match the given dimension");
+     178             :     }
+     179          15 :     if(betas_[i].size()!=getDimension()) {
+     180           0 :       plumed_merror(getName()+": one of the BETA keyword does not match the given dimension");
+     181             :     }
+     182             :   }
+     183             :   //
+     184          16 :   parseVector("WEIGHTS",weights_);
+     185           8 :   if(weights_.size()==0) {weights_.assign(centers_.size(),1.0);}
+     186           8 :   if(centers_.size()!=weights_.size()) {
+     187           0 :     plumed_merror(getName()+": there has to be as many weights given in WEIGHTS as numbered CENTER keywords");
+     188             :   }
+     189             :   //
+     190             :   double sum_weights=0.0;
+     191          23 :   for(unsigned int i=0; i<weights_.size(); i++) {sum_weights+=weights_[i];}
+     192          23 :   for(unsigned int i=0; i<weights_.size(); i++) {weights_[i]/=sum_weights;}
+     193             :   //
+     194           8 :   normalization_.resize(ncenters_);
+     195          23 :   for(unsigned int i=0; i<ncenters_; i++) {
+     196          15 :     normalization_[i].resize(getDimension());
+     197          35 :     for(unsigned int k=0; k<getDimension(); k++) {
+     198          20 :       normalization_[i][k] = 0.5*betas_[i][k]/(alphas_[i][k]*tgamma(1.0/betas_[i][k]));
+     199             :     }
+     200             :   }
+     201           8 :   checkRead();
+     202           8 : }
+     203             : 
+     204             : 
+     205       21608 : double TD_GeneralizedNormal::getValue(const std::vector<double>& argument) const {
+     206             :   double value=0.0;
+     207       74623 :   for(unsigned int i=0; i<ncenters_; i++) {
+     208       53015 :     value+=weights_[i]*ExponentialPowerDiagonal(argument,centers_[i],alphas_[i],betas_[i],normalization_[i]);
+     209             :   }
+     210       21608 :   return value;
+     211             : }
+     212             : 
+     213             : 
+     214       53015 : double TD_GeneralizedNormal::ExponentialPowerDiagonal(const std::vector<double>& argument, const std::vector<double>& center, const std::vector<double>& alpha, const std::vector<double>& beta, const std::vector<double>& normalization) const {
+     215             :   double value = 1.0;
+     216      157035 :   for(unsigned int k=0; k<argument.size(); k++) {
+     217      104020 :     double arg=(std::abs(argument[k]-center[k]))/alpha[k];
+     218      104020 :     arg = pow(arg,beta[k]);
+     219      104020 :     value*=normalization[k]*exp(-arg);
+     220             :   }
+     221       53015 :   return value;
+     222             : }
+     223             : 
+     224             : 
+     225             : 
+     226             : }
+     227             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_Grid.cpp.func-sort-c.html b/coverage/ves/TD_Grid.cpp.func-sort-c.html new file mode 100644 index 000000000000..c73f8700ff70 --- /dev/null +++ b/coverage/ves/TD_Grid.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_Grid.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_Grid.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:555894.8 %
Date:2024-04-19 12:12:35Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves7TD_GridC2ERKNS_13ActionOptionsE9
_ZN4PLMD3ves7TD_Grid16registerKeywordsERNS_8KeywordsE11
_ZNK4PLMD3ves7TD_Grid8getValueERKSt6vectorIdSaIdEE49369
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_Grid.cpp.func.html b/coverage/ves/TD_Grid.cpp.func.html new file mode 100644 index 000000000000..e3a7304977b8 --- /dev/null +++ b/coverage/ves/TD_Grid.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_Grid.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_Grid.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:555894.8 %
Date:2024-04-19 12:12:35Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves7TD_Grid16registerKeywordsERNS_8KeywordsE11
_ZN4PLMD3ves7TD_GridC2ERKNS_13ActionOptionsE9
_ZNK4PLMD3ves7TD_Grid8getValueERKSt6vectorIdSaIdEE49369
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_Grid.cpp.gcov.html b/coverage/ves/TD_Grid.cpp.gcov.html new file mode 100644 index 000000000000..ca1dd86ea1ff --- /dev/null +++ b/coverage/ves/TD_Grid.cpp.gcov.html @@ -0,0 +1,295 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_Grid.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_Grid.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:555894.8 %
Date:2024-04-19 12:12:35Functions:33100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "TargetDistribution.h"
+      24             : #include "GridIntegrationWeights.h"
+      25             : #include "VesTools.h"
+      26             : #include "GridLinearInterpolation.h"
+      27             : 
+      28             : #include "core/ActionRegister.h"
+      29             : #include "tools/Grid.h"
+      30             : #include "core/Value.h"
+      31             : #include "tools/File.h"
+      32             : 
+      33             : 
+      34             : namespace PLMD {
+      35             : namespace ves {
+      36             : 
+      37             : 
+      38             : //+PLUMEDOC VES_TARGETDIST TD_GRID
+      39             : /*
+      40             : Target distribution from an external grid file (static).
+      41             : 
+      42             : Using this keyword you can use a target distribution that is read from an
+      43             : external grid file that is in the proper PLUMED file format. You do not to
+      44             : give any information about the external grid file as all relevant information
+      45             : should be automatically detected. It is assumed that the distribution read in
+      46             : from the grid is a proper probability distribution, i.e. always non-negative
+      47             : and can be normalized.
+      48             : 
+      49             : By default the target distribution from the external grid is always normalized
+      50             : inside the code. You can disable this normalization by using DO_NOT_NORMALIZE
+      51             : keyword. However, be warned that this will generally lead to the wrong
+      52             : behavior if the distribution from the external grid is not properly
+      53             : normalized to 1.
+      54             : 
+      55             : If the distribution from the external grid file has for some reason
+      56             : negative values can you use the SHIFT keyword to shift the distribution
+      57             : by a given value. Another option is to use
+      58             : the SHIFT_TO_ZERO keyword to shift the minimum of the distribution to zero.
+      59             : 
+      60             : Note that the number of grid bins used in the external grid file do not have
+      61             : to be the same as used in the bias or action where the target distribution is
+      62             : employed as the code will employ a linear (or bilinear for two dimensions)
+      63             : interpolation to calculate values. Currently only one or two dimensional grids
+      64             : are supported.
+      65             : 
+      66             : It can happen that the intervals on which the target distribution is defined is
+      67             : larger than the intervals covered by the external grid file. In this case the
+      68             : default option is to consider the target distribution as continuous such that
+      69             : values outside the boundary of the external grid file are the same as at
+      70             : the boundary. This can be changed by using the ZERO_OUTSIDE keyword which
+      71             : will make values outside to be taken as zero.
+      72             : 
+      73             : \par Examples
+      74             : 
+      75             : Generally you only need to provide the the filename of the external grid
+      76             : file.
+      77             : \plumedfile
+      78             : td: TD_GRID FILE=input-grid.data
+      79             : \endplumedfile
+      80             : 
+      81             : The input grid is then specified using the usual format employed by PLUMED an example of which
+      82             : is shown below:
+      83             : 
+      84             : \auxfile{input-grid.data}
+      85             : #! FIELDS d1 external.bias der_d1
+      86             : #! SET min_d1 1.14
+      87             : #! SET max_d1 1.32
+      88             : #! SET nbins_d1 6
+      89             : #! SET periodic_d1 false
+      90             :    1.1400   0.0031   0.1101
+      91             :    1.1700   0.0086   0.2842
+      92             :    1.2000   0.0222   0.6648
+      93             :    1.2300   0.0521   1.4068
+      94             :    1.2600   0.1120   2.6873
+      95             :    1.2900   0.2199   4.6183
+      96             :    1.3200   0.3948   7.1055
+      97             : \endauxfile
+      98             : 
+      99             : */
+     100             : //+ENDPLUMEDOC
+     101             : 
+     102             : 
+     103             : class TD_Grid : public TargetDistribution {
+     104             :   std::unique_ptr<GridBase> distGrid_;
+     105             :   std::vector<double> minima_;
+     106             :   std::vector<double> maxima_;
+     107             :   std::vector<bool> periodic_;
+     108             :   bool zero_outside_;
+     109             :   double shift_;
+     110             : public:
+     111             :   static void registerKeywords( Keywords&);
+     112             :   explicit TD_Grid(const ActionOptions& ao);
+     113             :   double getValue(const std::vector<double>&) const override;
+     114             : };
+     115             : 
+     116             : 
+     117             : PLUMED_REGISTER_ACTION(TD_Grid,"TD_GRID")
+     118             : 
+     119             : 
+     120          11 : void TD_Grid::registerKeywords(Keywords& keys) {
+     121          11 :   TargetDistribution::registerKeywords(keys);
+     122          22 :   keys.add("compulsory","FILE","The name of the external grid file to be used as a target distribution.");
+     123          22 :   keys.add("optional","SHIFT","Shift the grid read in by some constant value. Due to normalization the final shift in the target distribution will generally not be the same as the value given here");
+     124          22 :   keys.addFlag("ZERO_OUTSIDE",false,"By default the target distribution is continuous such that values outside the boundary of the external grid file are the same as at the boundary. This can be changed by using this flag which will make values outside to be taken as zero.");
+     125          22 :   keys.addFlag("DO_NOT_NORMALIZE",false,"By default the target distribution from the external grid is always normalized inside the code. You can use this flag to disable this normalization. However, be warned that this will generally lead to the wrong behavior if the distribution from the external grid is not properly normalized to 1.");
+     126          11 :   keys.use("WELLTEMPERED_FACTOR");
+     127          11 :   keys.use("SHIFT_TO_ZERO");
+     128          11 : }
+     129             : 
+     130           9 : TD_Grid::TD_Grid(const ActionOptions& ao):
+     131             :   PLUMED_VES_TARGETDISTRIBUTION_INIT(ao),
+     132           9 :   minima_(0),
+     133           9 :   maxima_(0),
+     134           9 :   zero_outside_(false),
+     135          18 :   shift_(0.0)
+     136             : {
+     137             :   std::string filename;
+     138           9 :   parse("FILE",filename);
+     139           9 :   parse("SHIFT",shift_);
+     140           9 :   if(shift_!=0.0) {
+     141           1 :     if(isTargetDistGridShiftedToZero()) {plumed_merror(getName() + ": using both SHIFT and SHIFT_TO_ZERO is not allowed.");}
+     142             :   }
+     143           9 :   parseFlag("ZERO_OUTSIDE",zero_outside_);
+     144             : 
+     145           9 :   bool do_not_normalize=false;
+     146           9 :   parseFlag("DO_NOT_NORMALIZE",do_not_normalize);
+     147           9 :   if(do_not_normalize && shift_!=0.0) {plumed_merror(getName() + ": using both SHIFT and DO_NOT_NORMALIZE is not allowed.");}
+     148           9 :   if(!do_not_normalize) {setForcedNormalization();}
+     149             : 
+     150           9 :   checkRead();
+     151             : 
+     152             :   std::string gridlabel;
+     153             :   std::vector<std::string> arglabels;
+     154             :   std::vector<std::string> argmin;
+     155             :   std::vector<std::string> argmax;
+     156             :   std::vector<bool> argperiodic;
+     157             :   std::vector<unsigned int> argnbins;
+     158           9 :   bool has_deriv = false;
+     159           9 :   unsigned int nargs = VesTools::getGridFileInfo(filename,gridlabel,arglabels,argmin,argmax,argperiodic,argnbins,has_deriv);
+     160           9 :   if(nargs==0) {
+     161           0 :     plumed_merror(getName() + ": problem in parsing information from grid file");
+     162             :   }
+     163             : 
+     164           9 :   setDimension(arglabels.size());
+     165           9 :   std::vector<std::unique_ptr<Value>> arguments(arglabels.size());
+     166          22 :   for(unsigned int i=0; i < arglabels.size(); i++) {
+     167          26 :     arguments[i]= Tools::make_unique<Value>(nullptr,arglabels[i],false);
+     168          13 :     if(argperiodic[i]) {
+     169           0 :       arguments[i]->setDomain(argmin[i],argmax[i]);
+     170             :     }
+     171             :     else {
+     172          13 :       arguments[i]->setNotPeriodic();
+     173             :     }
+     174             :   }
+     175             : 
+     176           9 :   IFile gridfile; gridfile.open(filename);
+     177           9 :   if(has_deriv) {
+     178           0 :     distGrid_=GridBase::create(gridlabel,Tools::unique2raw(arguments),gridfile,false,true,true);
+     179             :   }
+     180             :   else {
+     181          18 :     distGrid_=GridBase::create(gridlabel,Tools::unique2raw(arguments),gridfile,false,false,false);
+     182             :   }
+     183           9 :   gridfile.close();
+     184             : 
+     185             : 
+     186           9 :   minima_.resize(getDimension());
+     187           9 :   maxima_.resize(getDimension());
+     188           9 :   periodic_.resize(getDimension());
+     189          22 :   for (unsigned int i=0; i < getDimension(); i++) {
+     190          13 :     Tools::convert(distGrid_->getMin()[i],minima_[i]);
+     191          13 :     Tools::convert(distGrid_->getMax()[i],maxima_[i]);
+     192          13 :     periodic_[i] = argperiodic[i];
+     193          13 :     if(periodic_[i]) {maxima_[i]-=distGrid_->getDx()[i];}
+     194             :   }
+     195             : 
+     196          27 : }
+     197             : 
+     198             : 
+     199       49369 : double TD_Grid::getValue(const std::vector<double>& argument) const {
+     200             :   double outside = 0.0;
+     201       49369 :   std::vector<double> arg = argument;
+     202      145566 :   for(unsigned int k=0; k<getDimension(); k++) {
+     203       96533 :     if(zero_outside_ && (argument[k] < minima_[k] || argument[k] > maxima_[k])) {
+     204             :       return outside;
+     205             :     }
+     206       96197 :     else if(argument[k] < minima_[k]) {
+     207         168 :       arg[k] = minima_[k];
+     208             :     }
+     209       96029 :     else if(argument[k] > maxima_[k]) {
+     210         168 :       arg[k] =maxima_[k];
+     211             :     }
+     212             :   }
+     213       49033 :   return GridLinearInterpolation::getGridValueWithLinearInterpolation(distGrid_.get(),arg)+shift_;
+     214             : }
+     215             : 
+     216             : 
+     217             : }
+     218             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_LinearCombination.cpp.func-sort-c.html b/coverage/ves/TD_LinearCombination.cpp.func-sort-c.html new file mode 100644 index 000000000000..aa299d31ccca --- /dev/null +++ b/coverage/ves/TD_LinearCombination.cpp.func-sort-c.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_LinearCombination.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_LinearCombination.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:587775.3 %
Date:2024-04-19 12:12:35Functions:61060.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves20TD_LinearCombination10linkActionEPNS_6ActionE0
_ZN4PLMD3ves20TD_LinearCombination12linkBiasGridEPNS_4GridE0
_ZN4PLMD3ves20TD_LinearCombination25linkBiasWithoutCutoffGridEPNS_4GridE0
_ZNK4PLMD3ves20TD_LinearCombination8getValueERKSt6vectorIdSaIdEE0
_ZN4PLMD3ves20TD_LinearCombination11linkFesGridEPNS_4GridE1
_ZN4PLMD3ves20TD_LinearCombination11linkVesBiasEPNS0_7VesBiasE1
_ZN4PLMD3ves20TD_LinearCombination20setupAdditionalGridsERKSt6vectorIPNS_5ValueESaIS4_EERKS2_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISE_EESI_RKS2_IjSaIjEE12
_ZN4PLMD3ves20TD_LinearCombinationC2ERKNS_13ActionOptionsE12
_ZN4PLMD3ves20TD_LinearCombination16registerKeywordsERNS_8KeywordsE14
_ZN4PLMD3ves20TD_LinearCombination10updateGridEv22
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_LinearCombination.cpp.func.html b/coverage/ves/TD_LinearCombination.cpp.func.html new file mode 100644 index 000000000000..ab7924058e87 --- /dev/null +++ b/coverage/ves/TD_LinearCombination.cpp.func.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_LinearCombination.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_LinearCombination.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:587775.3 %
Date:2024-04-19 12:12:35Functions:61060.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves20TD_LinearCombination10linkActionEPNS_6ActionE0
_ZN4PLMD3ves20TD_LinearCombination10updateGridEv22
_ZN4PLMD3ves20TD_LinearCombination11linkFesGridEPNS_4GridE1
_ZN4PLMD3ves20TD_LinearCombination11linkVesBiasEPNS0_7VesBiasE1
_ZN4PLMD3ves20TD_LinearCombination12linkBiasGridEPNS_4GridE0
_ZN4PLMD3ves20TD_LinearCombination16registerKeywordsERNS_8KeywordsE14
_ZN4PLMD3ves20TD_LinearCombination20setupAdditionalGridsERKSt6vectorIPNS_5ValueESaIS4_EERKS2_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISE_EESI_RKS2_IjSaIjEE12
_ZN4PLMD3ves20TD_LinearCombination25linkBiasWithoutCutoffGridEPNS_4GridE0
_ZN4PLMD3ves20TD_LinearCombinationC2ERKNS_13ActionOptionsE12
_ZNK4PLMD3ves20TD_LinearCombination8getValueERKSt6vectorIdSaIdEE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_LinearCombination.cpp.gcov.html b/coverage/ves/TD_LinearCombination.cpp.gcov.html new file mode 100644 index 000000000000..25c6a3979a59 --- /dev/null +++ b/coverage/ves/TD_LinearCombination.cpp.gcov.html @@ -0,0 +1,354 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_LinearCombination.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_LinearCombination.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:587775.3 %
Date:2024-04-19 12:12:35Functions:61060.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "TargetDistribution.h"
+      24             : #include "VesTools.h"
+      25             : 
+      26             : #include "core/ActionRegister.h"
+      27             : #include "core/ActionSet.h"
+      28             : #include "core/PlumedMain.h"
+      29             : #include "tools/Grid.h"
+      30             : 
+      31             : #include <limits>
+      32             : 
+      33             : 
+      34             : namespace PLMD {
+      35             : 
+      36             : // class Grid;
+      37             : class Action;
+      38             : 
+      39             : namespace ves {
+      40             : 
+      41             : //+PLUMEDOC VES_TARGETDIST TD_LINEAR_COMBINATION
+      42             : /*
+      43             : Target distribution given by linear combination of distributions (static or dynamic).
+      44             : 
+      45             : Employ a target distribution that is a linear combination of the other
+      46             : distributions, defined as
+      47             : \f[
+      48             : p(\mathbf{s}) = \sum_{i} w_{i} \, p_{i}(\mathbf{s})
+      49             : \f]
+      50             : where the weights \f$w_{i}\f$ are normalized to 1, \f$\sum_{i}w_{i}=1\f$.
+      51             : 
+      52             : The labels of the distributions \f$p_{i}(\mathbf{s})\f$ to be used in the
+      53             : linear combination are given in the DISTRIBUTIONS keyword.
+      54             : 
+      55             : The weights \f$w_{i}\f$ can be given using
+      56             : the WEIGHTS keyword. The distributions are weighted equally if no weights are given.
+      57             : 
+      58             : It is assumed that all the distributions \f$p_{i}(\mathbf{s})\f$ are normalized.
+      59             : If that is not the case for some reason should you
+      60             : normalize each distribution separately by using the NORMALIZE
+      61             : keyword when defining them in the input file (i.e. before the
+      62             : TD_LINEAR_COMBINATION action).
+      63             : Note that normalizing the overall
+      64             : linear combination will generally lead to different results than normalizing
+      65             : each distribution separately.
+      66             : 
+      67             : The linear combination will be a dynamic target distribution if one or more
+      68             : of the distributions used is a dynamic distribution, otherwise it will be a
+      69             : static distribution.
+      70             : 
+      71             : \par Examples
+      72             : 
+      73             : Here we employ a linear combination of a uniform and a Gaussian distribution.
+      74             : No weights are given so the two distributions will be weighted equally.
+      75             : \plumedfile
+      76             : td_uni: TD_UNIFORM
+      77             : 
+      78             : td_gauss: TD_GAUSSIAN CENTER1=-2.0 SIGMA1=0.5
+      79             : 
+      80             : td_comb: TD_LINEAR_COMBINATION DISTRIBUTIONS=td_uni,td_gauss
+      81             : \endplumedfile
+      82             : 
+      83             : Here we employ a linear combination of a uniform and two Gaussian distribution.
+      84             : The weights are automatically normalized to 1 such that giving
+      85             : WEIGHTS=1.0,1.0,2.0 as we do here is equal to giving WEIGHTS=0.25,0.25,0.50.
+      86             : \plumedfile
+      87             : td_uni: TD_UNIFORM
+      88             : 
+      89             : td_gauss1: TD_GAUSSIAN CENTER1=-2.0,-2.0 SIGMA1=0.5,0.3
+      90             : 
+      91             : td_gauss2: TD_GAUSSIAN CENTER1=+2.0,+2.0 SIGMA1=0.3,0.5
+      92             : 
+      93             : TD_LINEAR_COMBINATION ...
+      94             :  DISTRIBUTIONS=td_uni,td_gauss1,td_gauss2
+      95             :  WEIGHTS=1.0,1.0,2.0
+      96             :  LABEL=td_comb
+      97             : ... TD_LINEAR_COMBINATION
+      98             : \endplumedfile
+      99             : 
+     100             : In the above example the two Gaussian kernels are given using two separate
+     101             : DISTRIBUTION keywords. As the \ref TD_GAUSSIAN target distribution allows multiple
+     102             : centers is it also possible to use just one DISTRIBUTION keyword for the two
+     103             : Gaussian kernels. This is shown in the following example which will give the
+     104             : exact same result as the one above as the weights have been appropriately
+     105             : adjusted
+     106             : \plumedfile
+     107             : td_uni: TD_UNIFORM
+     108             : 
+     109             : TD_GAUSSIAN ...
+     110             :  CENTER1=-2.0,-2.0  SIGMA1=0.5,0.3
+     111             :  CENTER2=+2.0,+2.0  SIGMA2=0.3,0.5
+     112             :  WEIGHTS=1.0,2.0
+     113             :  LABEL=td_gauss
+     114             : ... TD_GAUSSIAN
+     115             : 
+     116             : TD_LINEAR_COMBINATION ...
+     117             :  DISTRIBUTIONS=td_uni,td_gauss
+     118             :  WEIGHTS=0.25,0.75
+     119             :  LABEL=td_comb
+     120             : ... TD_LINEAR_COMBINATION
+     121             : \endplumedfile
+     122             : 
+     123             : */
+     124             : //+ENDPLUMEDOC
+     125             : 
+     126             : class VesBias;
+     127             : 
+     128             : class TD_LinearCombination: public TargetDistribution {
+     129             : private:
+     130             :   std::vector<TargetDistribution*> distribution_pntrs_;
+     131             :   std::vector<Grid*> grid_pntrs_;
+     132             :   std::vector<double> weights_;
+     133             :   unsigned int ndist_;
+     134             :   void setupAdditionalGrids(const std::vector<Value*>&, const std::vector<std::string>&, const std::vector<std::string>&, const std::vector<unsigned int>&) override;
+     135             : public:
+     136             :   static void registerKeywords(Keywords&);
+     137             :   explicit TD_LinearCombination(const ActionOptions& ao);
+     138             :   void updateGrid() override;
+     139             :   double getValue(const std::vector<double>&) const override;
+     140             :   //
+     141             :   void linkVesBias(VesBias*) override;
+     142             :   void linkAction(Action*) override;
+     143             :   //
+     144             :   void linkBiasGrid(Grid*) override;
+     145             :   void linkBiasWithoutCutoffGrid(Grid*) override;
+     146             :   void linkFesGrid(Grid*) override;
+     147             :   //
+     148             : };
+     149             : 
+     150             : 
+     151             : PLUMED_REGISTER_ACTION(TD_LinearCombination,"TD_LINEAR_COMBINATION")
+     152             : 
+     153             : 
+     154          14 : void TD_LinearCombination::registerKeywords(Keywords& keys) {
+     155          14 :   TargetDistribution::registerKeywords(keys);
+     156          28 :   keys.add("compulsory","DISTRIBUTIONS","The labels of the target distribution actions to be used in the linear combination.");
+     157          28 :   keys.add("optional","WEIGHTS","The weights of target distributions. Have to be as many as the number of target distribution labels given in DISTRIBUTIONS. If no weights are given the distributions are weighted equally. The weights are automatically normalized to 1.");
+     158          14 :   keys.use("WELLTEMPERED_FACTOR");
+     159             :   //keys.use("SHIFT_TO_ZERO");
+     160          14 :   keys.use("NORMALIZE");
+     161          14 : }
+     162             : 
+     163             : 
+     164          12 : TD_LinearCombination::TD_LinearCombination(const ActionOptions& ao):
+     165             :   PLUMED_VES_TARGETDISTRIBUTION_INIT(ao),
+     166          24 :   distribution_pntrs_(0),
+     167          12 :   grid_pntrs_(0),
+     168          12 :   weights_(0),
+     169          24 :   ndist_(0)
+     170             : {
+     171             :   std::vector<std::string> targetdist_labels;
+     172          12 :   parseVector("DISTRIBUTIONS",targetdist_labels);
+     173             : 
+     174          12 :   std::string error_msg = "";
+     175          24 :   distribution_pntrs_ = VesTools::getPointersFromLabels<TargetDistribution*>(targetdist_labels,plumed.getActionSet(),error_msg);
+     176          12 :   if(error_msg.size()>0) {plumed_merror("Error in keyword DISTRIBUTIONS of "+getName()+": "+error_msg);}
+     177             : 
+     178          40 :   for(unsigned int i=0; i<distribution_pntrs_.size(); i++) {
+     179          28 :     if(distribution_pntrs_[i]->isDynamic()) {setDynamic();}
+     180          28 :     if(distribution_pntrs_[i]->fesGridNeeded()) {setFesGridNeeded();}
+     181          28 :     if(distribution_pntrs_[i]->biasGridNeeded()) {setBiasGridNeeded();}
+     182             :   }
+     183             : 
+     184          12 :   ndist_ = distribution_pntrs_.size();
+     185          12 :   grid_pntrs_.assign(ndist_,NULL);
+     186          12 :   if(ndist_==0) {plumed_merror(getName()+ ": no distributions are given.");}
+     187          12 :   if(ndist_==1) {plumed_merror(getName()+ ": giving only one distribution does not make sense.");}
+     188             :   //
+     189          24 :   parseVector("WEIGHTS",weights_);
+     190          12 :   if(weights_.size()==0) {weights_.assign(distribution_pntrs_.size(),1.0);}
+     191          12 :   if(distribution_pntrs_.size()!=weights_.size()) {
+     192           0 :     plumed_merror(getName()+ ": there has to be as many weights given in WEIGHTS as the number of target distribution labels given in DISTRIBUTIONS");
+     193             :   }
+     194             :   //
+     195             :   double sum_weights=0.0;
+     196          40 :   for(unsigned int i=0; i<weights_.size(); i++) {sum_weights+=weights_[i];}
+     197          40 :   for(unsigned int i=0; i<weights_.size(); i++) {weights_[i]/=sum_weights;}
+     198          12 :   checkRead();
+     199          12 : }
+     200             : 
+     201             : 
+     202           0 : double TD_LinearCombination::getValue(const std::vector<double>& argument) const {
+     203           0 :   plumed_merror("getValue not implemented for TD_LinearCombination");
+     204             :   return 0.0;
+     205             : }
+     206             : 
+     207             : 
+     208          12 : void TD_LinearCombination::setupAdditionalGrids(const std::vector<Value*>& arguments, const std::vector<std::string>& min, const std::vector<std::string>& max, const std::vector<unsigned int>& nbins) {
+     209          40 :   for(unsigned int i=0; i<ndist_; i++) {
+     210          28 :     distribution_pntrs_[i]->setupGrids(arguments,min,max,nbins);
+     211          28 :     if(distribution_pntrs_[i]->getDimension()!=this->getDimension()) {
+     212           0 :       plumed_merror(getName() + ": all target distribution must have the same dimension");
+     213             :     }
+     214          28 :     grid_pntrs_[i]=distribution_pntrs_[i]->getTargetDistGridPntr();
+     215             :   }
+     216          12 : }
+     217             : 
+     218             : 
+     219          22 : void TD_LinearCombination::updateGrid() {
+     220          70 :   for(unsigned int i=0; i<ndist_; i++) {
+     221          48 :     distribution_pntrs_[i]->updateTargetDist();
+     222             :   }
+     223      162033 :   for(Grid::index_t l=0; l<targetDistGrid().getSize(); l++) {
+     224             :     double value = 0.0;
+     225      506837 :     for(unsigned int i=0; i<ndist_; i++) {
+     226      344826 :       value += weights_[i]*grid_pntrs_[i]->getValue(l);
+     227             :     }
+     228      162011 :     if(value==0.0) value=std::numeric_limits<double>::denorm_min();
+     229      162011 :     targetDistGrid().setValue(l,value);
+     230      162011 :     logTargetDistGrid().setValue(l,-std::log(value));
+     231             :   }
+     232          22 :   logTargetDistGrid().setMinToZero();
+     233          22 : }
+     234             : 
+     235             : 
+     236           1 : void TD_LinearCombination::linkVesBias(VesBias* vesbias_pntr_in) {
+     237           1 :   TargetDistribution::linkVesBias(vesbias_pntr_in);
+     238           3 :   for(unsigned int i=0; i<ndist_; i++) {
+     239           2 :     distribution_pntrs_[i]->linkVesBias(vesbias_pntr_in);
+     240             :   }
+     241           1 : }
+     242             : 
+     243             : 
+     244           0 : void TD_LinearCombination::linkAction(Action* action_pntr_in) {
+     245           0 :   TargetDistribution::linkAction(action_pntr_in);
+     246           0 :   for(unsigned int i=0; i<ndist_; i++) {
+     247           0 :     distribution_pntrs_[i]->linkAction(action_pntr_in);
+     248             :   }
+     249           0 : }
+     250             : 
+     251             : 
+     252           0 : void TD_LinearCombination::linkBiasGrid(Grid* bias_grid_pntr_in) {
+     253           0 :   TargetDistribution::linkBiasGrid(bias_grid_pntr_in);
+     254           0 :   for(unsigned int i=0; i<ndist_; i++) {
+     255           0 :     distribution_pntrs_[i]->linkBiasGrid(bias_grid_pntr_in);
+     256             :   }
+     257           0 : }
+     258             : 
+     259             : 
+     260           0 : void TD_LinearCombination::linkBiasWithoutCutoffGrid(Grid* bias_withoutcutoff_grid_pntr_in) {
+     261           0 :   TargetDistribution::linkBiasWithoutCutoffGrid(bias_withoutcutoff_grid_pntr_in);
+     262           0 :   for(unsigned int i=0; i<ndist_; i++) {
+     263           0 :     distribution_pntrs_[i]->linkBiasWithoutCutoffGrid(bias_withoutcutoff_grid_pntr_in);
+     264             :   }
+     265           0 : }
+     266             : 
+     267             : 
+     268           1 : void TD_LinearCombination::linkFesGrid(Grid* fes_grid_pntr_in) {
+     269           1 :   TargetDistribution::linkFesGrid(fes_grid_pntr_in);
+     270           3 :   for(unsigned int i=0; i<ndist_; i++) {
+     271           2 :     distribution_pntrs_[i]->linkFesGrid(fes_grid_pntr_in);
+     272             :   }
+     273           1 : }
+     274             : 
+     275             : 
+     276             : }
+     277             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_Multicanonical.cpp.func-sort-c.html b/coverage/ves/TD_Multicanonical.cpp.func-sort-c.html new file mode 100644 index 000000000000..c7af24984d5c --- /dev/null +++ b/coverage/ves/TD_Multicanonical.cpp.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_Multicanonical.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_Multicanonical.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:19720496.6 %
Date:2024-04-19 12:12:35Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD3ves17TD_Multicanonical8getValueERKSt6vectorIdSaIdEE0
_ZN4PLMD3ves17TD_MulticanonicalC2ERKNS_13ActionOptionsE2
_ZN4PLMD3ves17TD_MulticanonicalD0Ev2
_ZN4PLMD3ves17TD_MulticanonicalD2Ev2
_ZN4PLMD3ves17TD_Multicanonical16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD3ves17TD_Multicanonical10updateGridEv14
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_Multicanonical.cpp.func.html b/coverage/ves/TD_Multicanonical.cpp.func.html new file mode 100644 index 000000000000..b05aaa8f8f8d --- /dev/null +++ b/coverage/ves/TD_Multicanonical.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_Multicanonical.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_Multicanonical.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:19720496.6 %
Date:2024-04-19 12:12:35Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves17TD_Multicanonical10updateGridEv14
_ZN4PLMD3ves17TD_Multicanonical16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD3ves17TD_MulticanonicalC2ERKNS_13ActionOptionsE2
_ZN4PLMD3ves17TD_MulticanonicalD0Ev2
_ZN4PLMD3ves17TD_MulticanonicalD2Ev2
_ZNK4PLMD3ves17TD_Multicanonical8getValueERKSt6vectorIdSaIdEE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_Multicanonical.cpp.gcov.html b/coverage/ves/TD_Multicanonical.cpp.gcov.html new file mode 100644 index 000000000000..034f5096102a --- /dev/null +++ b/coverage/ves/TD_Multicanonical.cpp.gcov.html @@ -0,0 +1,551 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_Multicanonical.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_Multicanonical.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:19720496.6 %
Date:2024-04-19 12:12:35Functions:5683.3 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "TargetDistribution.h"
+      24             : #include "GridIntegrationWeights.h"
+      25             : #include "core/ActionRegister.h"
+      26             : #include "tools/Grid.h"
+      27             : #include "core/PlumedMain.h"
+      28             : #include <cfloat>
+      29             : 
+      30             : 
+      31             : namespace PLMD {
+      32             : namespace ves {
+      33             : 
+      34             : //+PLUMEDOC VES_TARGETDIST TD_MULTICANONICAL
+      35             : /*
+      36             : Multicanonical target distribution (dynamic).
+      37             : 
+      38             : Use the target distribution to sample the multicanonical ensemble \cite Berg-PRL-1992 \cite Piaggi-PRL-2019.
+      39             : In this way, in a single molecular dynamics simulation one can obtain information about the system in a range of temperatures.
+      40             : This range is determined through the keywords MIN_TEMP and MAX_TEMP.
+      41             : 
+      42             : The collective variables (CVs) used to construct the bias potential must be:
+      43             :  1. the energy or,
+      44             :  2. the energy and an order parameter.
+      45             : 
+      46             : Other choices of CVs or a different order of the above mentioned CVs are nonsensical.
+      47             : The second CV, the order parameter, must be used when one aims at studying a first order phase transition in the chosen temperature interval \cite Piaggi-JCP-2019.
+      48             : 
+      49             : The algorithm will explore the free energy at each temperature up to a predefined free
+      50             :  energy threshold \f$\epsilon\f$ specified through the keyword THRESHOLD (in kT units).
+      51             : If only the energy is biased, i.e. no phase transition is considered, then THRESHOLD can be set to around 5.
+      52             : If also an order parameter is used then the THRESHOLD should be greater than the barrier for the transformation in kT.
+      53             : For small systems undergoing a freezing transition THRESHOLD is typically between 20 and 50.
+      54             : 
+      55             : When only the potential energy is used as CV the method is equivalent to the Wang-Landau algorithm \cite wanglandau.
+      56             : The advantage with respect to Wang-Landau is that instead of sampling the potential energy indiscriminately, an interval is chosen on the fly based on the minimum and maximum targeted temperatures.
+      57             : 
+      58             : The algorithm works as follows.
+      59             : The target distribution for the potential energy is chosen to be:
+      60             : 
+      61             : \f[
+      62             : p(E)= \left\{\begin{array}{ll}
+      63             :          \frac{1}{E_2-E_1} & \mathrm{if} \quad E_1<E<E_2 \\
+      64             :          0 & \mathrm{otherwise}
+      65             :       \end{array}\right.
+      66             : \f]
+      67             : 
+      68             : where the energy limits \f$E_1\f$ and \f$E_2\f$ are yet to be determined.
+      69             : Clearly the interval \f$E_1–E_2\f$ chosen is related to the interval of temperatures \f$T_1-T_2\f$.
+      70             : To link these two intervals we make use of the following relation:
+      71             : \f[
+      72             : \beta' F_{\beta'}(E) = \beta F_{\beta}(E) + (\beta' - \beta) E + C,
+      73             : \f]
+      74             : where \f$F_{\beta}(E)\f$ is determined during the optimization and we shall choose \f$C\f$ such that \f$F_{\beta'}(E_{m})=0\f$ with \f$E_{m}\f$ the position of the free energy minimum.
+      75             : Using this relation we employ an iterative procedure to find the energy interval.
+      76             : At iteration \f$k\f$ we have the estimates \f$E_1^k\f$ and \f$E_2^k\f$ for \f$E_1\f$ and \f$E_2\f$, and the target distribution is:
+      77             : \f[
+      78             : p^k(E)=\frac{1}{E_2^k-E_1^k} \quad \mathrm{for} \quad E_1^k<E<E_2^k.
+      79             : \f]
+      80             : \f$E_1^k\f$ and \f$E_2^k\f$ are obtained from the leftmost solution of \f$\beta_2 F_{\beta_2}^{k-1}(E_1^k)=\epsilon\f$ and the rightmost solution of \f$\beta_1 F_{\beta_1}^{k-1}(E_2^k)=\epsilon\f$.
+      81             : The procedure is repeated until convergence.
+      82             : This iterative approach is similar to that in \ref TD_WELLTEMPERED.
+      83             : 
+      84             : The version of this algorithm in which the energy and an order parameter are biased is similar to the one described in \ref TD_MULTITHERMAL_MULTIBARIC.
+      85             : 
+      86             : The output of these simulations can be reweighted in order to obtain information at all temperatures in the targeted temperature interval.
+      87             : The reweighting can be performed using the action \ref REWEIGHT_TEMP_PRESS.
+      88             : 
+      89             : \par Examples
+      90             : 
+      91             : The following input can be used to run a simulation in the multicanonical ensemble.
+      92             : The temperature interval to be explored is 400-600 K.
+      93             : The energy is used as collective variable.
+      94             : Legendre polynomials are used to construct the bias potential.
+      95             : The averaged stochastic gradient descent algorithm is chosen to optimize the VES functional.
+      96             : The target distribution is updated every 100 optimization steps (200 ps here) using the last estimation of the free energy.
+      97             : 
+      98             : \plumedfile
+      99             : # Use energy and volume as CVs
+     100             : energy: ENERGY
+     101             : 
+     102             : # Basis functions
+     103             : bf1: BF_LEGENDRE ORDER=20 MINIMUM=-25000 MAXIMUM=-23500
+     104             : 
+     105             : # Target distributions
+     106             : TD_MULTICANONICAL ...
+     107             :  LABEL=td_multi
+     108             :  MIN_TEMP=400
+     109             :  MAX_TEMP=600
+     110             : ... TD_MULTICANONICAL
+     111             : 
+     112             : # Expansion
+     113             : VES_LINEAR_EXPANSION ...
+     114             :  ARG=energy
+     115             :  BASIS_FUNCTIONS=bf1
+     116             :  TEMP=500.0
+     117             :  GRID_BINS=1000
+     118             :  TARGET_DISTRIBUTION=td_multi
+     119             :  LABEL=b1
+     120             : ... VES_LINEAR_EXPANSION
+     121             : 
+     122             : # Optimization algorithm
+     123             : OPT_AVERAGED_SGD ...
+     124             :   BIAS=b1
+     125             :   STRIDE=500
+     126             :   LABEL=o1
+     127             :   STEPSIZE=1.0
+     128             :   FES_OUTPUT=500
+     129             :   BIAS_OUTPUT=500
+     130             :   TARGETDIST_OUTPUT=500
+     131             :   COEFFS_OUTPUT=10
+     132             :   TARGETDIST_STRIDE=100
+     133             : ... OPT_AVERAGED_SGD
+     134             : 
+     135             : \endplumedfile
+     136             : 
+     137             : The multicanonical target distribution can also be used to explore a temperature interval in which a first order phase transitions is observed.
+     138             : 
+     139             : */
+     140             : //+ENDPLUMEDOC
+     141             : 
+     142             : class TD_Multicanonical: public TargetDistribution {
+     143             : private:
+     144             :   double threshold_, min_temp_, max_temp_;
+     145             :   std::vector<double> sigma_;
+     146             :   unsigned steps_temp_;
+     147             :   double epsilon_;
+     148             :   bool smoothening_;
+     149             : public:
+     150             :   static void registerKeywords(Keywords&);
+     151             :   explicit TD_Multicanonical(const ActionOptions& ao);
+     152             :   void updateGrid() override;
+     153             :   double getValue(const std::vector<double>&) const override;
+     154           4 :   ~TD_Multicanonical() {}
+     155             :   double GaussianSwitchingFunc(const double, const double, const double) const;
+     156             : };
+     157             : 
+     158             : 
+     159             : PLUMED_REGISTER_ACTION(TD_Multicanonical,"TD_MULTICANONICAL")
+     160             : 
+     161             : 
+     162           4 : void TD_Multicanonical::registerKeywords(Keywords& keys) {
+     163           4 :   TargetDistribution::registerKeywords(keys);
+     164           8 :   keys.add("compulsory","THRESHOLD","5","Maximum exploration free energy in kT.");
+     165           8 :   keys.add("compulsory","EPSILON","10","The zeros of the target distribution are changed to e^-EPSILON.");
+     166           8 :   keys.add("compulsory","MIN_TEMP","Minimum temperature.");
+     167           8 :   keys.add("compulsory","MAX_TEMP","Maximum temperature.");
+     168           8 :   keys.add("optional","STEPS_TEMP","Number of temperature steps. Only for the 2D version, i.e. energy and order parameter.");
+     169           8 :   keys.add("optional","SIGMA","The standard deviation parameters of the Gaussian kernels used for smoothing the target distribution. One value must be specified for each argument, i.e. one value per CV. A value of 0.0 means that no smoothing is performed, this is the default behavior.");
+     170           4 : }
+     171             : 
+     172             : 
+     173           2 : TD_Multicanonical::TD_Multicanonical(const ActionOptions& ao):
+     174             :   PLUMED_VES_TARGETDISTRIBUTION_INIT(ao),
+     175           2 :   threshold_(5.0),
+     176           2 :   min_temp_(0.0),
+     177           2 :   max_temp_(1000.0),
+     178           4 :   sigma_(0.0),
+     179           2 :   steps_temp_(20),
+     180           2 :   epsilon_(10.0),
+     181           2 :   smoothening_(true)
+     182             : {
+     183           2 :   log.printf("  Multicanonical target distribution");
+     184           2 :   log.printf("\n");
+     185           2 :   log.printf("  Please read and cite ");
+     186           4 :   log << plumed.cite("Piaggi and Parrinello, Phys. Rev. Lett. 122 (5), 050601 (2019)");
+     187           2 :   log.printf(" and ");
+     188           4 :   log << plumed.cite("Piaggi and Parrinello, J. Chem. Phys. 150 (24), 244119 (2019)");
+     189           2 :   log.printf("\n");
+     190           2 :   parse("THRESHOLD",threshold_);
+     191           2 :   if(threshold_<=0.0) {
+     192           0 :     plumed_merror(getName()+": the value of the threshold should be positive.");
+     193             :   }
+     194           2 :   log.printf("  exploring free energy up to %f kT for each temperature \n",threshold_);
+     195             : 
+     196           2 :   parse("MIN_TEMP",min_temp_);
+     197           2 :   parse("MAX_TEMP",max_temp_);
+     198           2 :   log.printf("  temperatures between %f and %f will be explored \n",min_temp_,max_temp_);
+     199           4 :   parseVector("SIGMA",sigma_);
+     200           2 :   if(sigma_.size()==0) smoothening_=false;
+     201           2 :   if(smoothening_ && (sigma_.size()<1 || sigma_.size()>2) ) plumed_merror(getName()+": SIGMA takes 1 or 2 values as input.");
+     202           2 :   if (smoothening_) {
+     203           2 :     log.printf("  the target distribution will be smoothed using sigma values");
+     204           5 :     for(unsigned i=0; i<sigma_.size(); ++i) log.printf(" %f",sigma_[i]);
+     205           2 :     log.printf("\n");
+     206             :   }
+     207             : 
+     208           2 :   parse("STEPS_TEMP",steps_temp_); // Only used in the 2D version
+     209           2 :   steps_temp_ += 1;
+     210           2 :   log.printf("  %d steps in temperatures will be employed (if TD is two-dimensional) \n",steps_temp_);
+     211             : 
+     212           2 :   parse("EPSILON",epsilon_);
+     213           2 :   if(epsilon_<=1.0) {
+     214           0 :     plumed_merror(getName()+": the value of epsilon should be greater than 1.");
+     215             :   }
+     216           2 :   log.printf("  the non relevant regions of the target distribution are set to e^-%f \n",epsilon_);
+     217             : 
+     218             :   setDynamic();
+     219             :   setFesGridNeeded();
+     220           2 :   checkRead();
+     221           2 : }
+     222             : 
+     223             : 
+     224           0 : double TD_Multicanonical::getValue(const std::vector<double>& argument) const {
+     225           0 :   plumed_merror("getValue not implemented for TD_Multicanonical");
+     226             :   return 0.0;
+     227             : }
+     228             : 
+     229             : 
+     230          14 : void TD_Multicanonical::updateGrid() {
+     231          14 :   if (getStep() == 0) {
+     232           2 :     if(targetDistGrid().getDimension()>2 || targetDistGrid().getDimension()<1) plumed_merror(getName()+" works only with 1 or 2 arguments, i.e. energy, or energy and CV");
+     233           2 :     if(smoothening_ && sigma_.size()!=targetDistGrid().getDimension()) plumed_merror(getName()+": mismatch between SIGMA dimension and number of arguments");
+     234             :     // Use uniform TD
+     235           4 :     std::vector<double> integration_weights = GridIntegrationWeights::getIntegrationWeights(getTargetDistGridPntr());
+     236             :     double norm = 0.0;
+     237        2704 :     for(Grid::index_t l=0; l<targetDistGrid().getSize(); l++) {
+     238             :       double value = 1.0;
+     239        2702 :       norm += integration_weights[l]*value;
+     240        2702 :       targetDistGrid().setValue(l,value);
+     241             :     }
+     242           2 :     targetDistGrid().scaleAllValuesAndDerivatives(1.0/norm);
+     243             :   } else {
+     244             :     // Two variants: 1D and 2D
+     245          12 :     if(targetDistGrid().getDimension()==1) {
+     246             :       // 1D variant: Multicanonical without order parameter
+     247             :       // In this variant we find the minimum and maximum relevant potential energies.
+     248             :       // Using this information we construct a uniform target distribution in between these two.
+     249          10 :       double beta = getBeta();
+     250          10 :       double beta_prime_min = 1./(getKBoltzmann()*min_temp_);
+     251          10 :       double beta_prime_max = 1./(getKBoltzmann()*max_temp_);
+     252          10 :       plumed_massert(getFesGridPntr()!=NULL,"the FES grid has to be linked to use TD_Multicanonical!");
+     253             :       // Find minimum of F(U) at temperature min
+     254             :       double minval=DBL_MAX;
+     255          10 :       Grid::index_t minindex = (targetDistGrid().getSize())/2;
+     256          10 :       double minpos = targetDistGrid().getPoint(minindex)[0];
+     257        1020 :       for(Grid::index_t l=0; l<targetDistGrid().getSize(); l++) {
+     258        1010 :         double value = getFesGridPntr()->getValue(l);
+     259        1010 :         double argument = targetDistGrid().getPoint(l)[0];
+     260        1010 :         value = beta*value + (beta_prime_min-beta)*argument;
+     261        1010 :         if(value<minval) {
+     262             :           minval=value;
+     263             :           minpos=argument;
+     264             :           minindex=l;
+     265             :         }
+     266             :       }
+     267             :       // Find minimum energy at low temperature
+     268          10 :       double minimum_low = minpos;
+     269          11 :       for(Grid::index_t l=minindex; l>1; l-=1) {
+     270          11 :         double argument = targetDistGrid().getPoint(l)[0];
+     271          11 :         double argument_next = targetDistGrid().getPoint(l-1)[0];
+     272          11 :         double value = getFesGridPntr()->getValue(l);
+     273          11 :         double value_next = getFesGridPntr()->getValue(l-1);
+     274          11 :         value = beta*value + (beta_prime_min-beta)*argument - minval;
+     275          11 :         value_next = beta*value_next + (beta_prime_min-beta)*argument_next - minval;
+     276          11 :         if (value<threshold_ && value_next>threshold_) {
+     277          10 :           minimum_low = argument_next;
+     278          10 :           break;
+     279             :         }
+     280             :       }
+     281             :       // Find maximum energy at low temperature
+     282          10 :       double maximum_low = minpos;
+     283          12 :       for(Grid::index_t l=minindex; l<(targetDistGrid().getSize()-1); l++) {
+     284          12 :         double argument = targetDistGrid().getPoint(l)[0];
+     285          12 :         double argument_next = targetDistGrid().getPoint(l+1)[0];
+     286          12 :         double value = getFesGridPntr()->getValue(l);
+     287          12 :         double value_next = getFesGridPntr()->getValue(l+1);
+     288          12 :         value = beta*value + (beta_prime_min-beta)*argument - minval;
+     289          12 :         value_next = beta*value_next + (beta_prime_min-beta)*argument_next - minval;
+     290          12 :         if (value<threshold_ && value_next>threshold_) {
+     291          10 :           maximum_low = argument_next;
+     292          10 :           break;
+     293             :         }
+     294             :       }
+     295             :       // Find minimum of F(U) at temperature max
+     296             :       minval=DBL_MAX;
+     297        1020 :       for(Grid::index_t l=0; l<targetDistGrid().getSize(); l++) {
+     298        1010 :         double value = getFesGridPntr()->getValue(l);
+     299        1010 :         double argument = targetDistGrid().getPoint(l)[0];
+     300        1010 :         value = beta*value + (beta_prime_max-beta)*argument;
+     301        1010 :         if(value<minval) {
+     302             :           minval=value;
+     303             :           minpos=argument;
+     304             :           minindex=l;
+     305             :         }
+     306             :       }
+     307             :       // Find minimum energy at high temperature
+     308          10 :       double minimum_high = minpos;
+     309          13 :       for(Grid::index_t l=minindex; l>1; l-=1) {
+     310          13 :         double argument = targetDistGrid().getPoint(l)[0];
+     311          13 :         double argument_next = targetDistGrid().getPoint(l-1)[0];
+     312          13 :         double value = getFesGridPntr()->getValue(l);
+     313          13 :         double value_next = getFesGridPntr()->getValue(l-1);
+     314          13 :         value = beta*value + (beta_prime_max-beta)*argument - minval;
+     315          13 :         value_next = beta*value_next + (beta_prime_max-beta)*argument_next - minval;
+     316          13 :         if (value<threshold_ && value_next>threshold_) {
+     317          10 :           minimum_high = argument_next;
+     318          10 :           break;
+     319             :         }
+     320             :       }
+     321             :       // Find maximum energy at high temperature
+     322          10 :       double maximum_high = minpos;
+     323          11 :       for(Grid::index_t l=minindex; l<(targetDistGrid().getSize()-1); l++) {
+     324          11 :         double argument = targetDistGrid().getPoint(l)[0];
+     325          11 :         double argument_next = targetDistGrid().getPoint(l+1)[0];
+     326          11 :         double value = getFesGridPntr()->getValue(l);
+     327          11 :         double value_next = getFesGridPntr()->getValue(l+1);
+     328          11 :         value = beta*value + (beta_prime_max-beta)*argument - minval;
+     329          11 :         value_next = beta*value_next + (beta_prime_max-beta)*argument_next - minval;
+     330          11 :         if (value<threshold_ && value_next>threshold_) {
+     331          10 :           maximum_high = argument_next;
+     332          10 :           break;
+     333             :         }
+     334             :       }
+     335          10 :       double minimum = std::min(minimum_low,minimum_high);
+     336          10 :       double maximum = std::max(maximum_low,maximum_high);
+     337             :       // Construct uniform TD in the interval between minimum and maximum
+     338          20 :       std::vector<double> integration_weights = GridIntegrationWeights::getIntegrationWeights(getTargetDistGridPntr());
+     339             :       double norm = 0.0;
+     340        1020 :       for(Grid::index_t l=0; l<targetDistGrid().getSize(); l++) {
+     341        1010 :         double argument = targetDistGrid().getPoint(l)[0];
+     342             :         double value = 1.0;
+     343             :         double tmp;
+     344        1010 :         if(argument < minimum) {
+     345         217 :           if (smoothening_) tmp = GaussianSwitchingFunc(argument,minimum,sigma_[0]);
+     346           0 :           else tmp = exp(-1.0*epsilon_);
+     347             :         }
+     348         793 :         else if(argument > maximum) {
+     349         199 :           if (smoothening_) tmp = GaussianSwitchingFunc(argument,maximum,sigma_[0]);
+     350           0 :           else tmp = exp(-1.0*epsilon_);
+     351             :         }
+     352             :         else {
+     353             :           tmp = 1.0;
+     354             :         }
+     355             :         value *= tmp;
+     356        1010 :         norm += integration_weights[l]*value;
+     357        1010 :         targetDistGrid().setValue(l,value);
+     358             :       }
+     359          10 :       targetDistGrid().scaleAllValuesAndDerivatives(1.0/norm);
+     360           2 :     } else if(targetDistGrid().getDimension()==2) {
+     361             :       // 2D variant: Multicanonical with order parameter
+     362             :       // In this variant we find for each temperature the relevant region of potential energy and order parameter.
+     363             :       // The target distribution will be the union of the relevant regions at all temperatures in the temperature interval.
+     364           2 :       double beta = getBeta();
+     365           2 :       double beta_prime_min = 1./(getKBoltzmann()*min_temp_);
+     366           2 :       double beta_prime_max = 1./(getKBoltzmann()*max_temp_);
+     367           2 :       plumed_massert(getFesGridPntr()!=NULL,"the FES grid has to be linked to use TD_Multicanonical!");
+     368             :       // Set all to zero
+     369        5204 :       for(Grid::index_t l=0; l<targetDistGrid().getSize(); l++) {
+     370        5202 :         double value = exp(-1.0*epsilon_);
+     371        5202 :         targetDistGrid().setValue(l,value);
+     372             :       }
+     373             :       // Loop over temperatures
+     374          44 :       for(unsigned i=0; i<steps_temp_; i++) {
+     375          42 :         double beta_prime=beta_prime_min + (beta_prime_max-beta_prime_min)*i/(steps_temp_-1);
+     376             :         // Find minimum for this temperature
+     377             :         double minval=DBL_MAX;
+     378      109284 :         for(Grid::index_t l=0; l<targetDistGrid().getSize(); l++) {
+     379      109242 :           double energy = targetDistGrid().getPoint(l)[0];
+     380      109242 :           double value = getFesGridPntr()->getValue(l);
+     381      109242 :           value = beta*value + (beta_prime-beta)*energy;
+     382      109242 :           if(value<minval) {
+     383             :             minval=value;
+     384             :           }
+     385             :         }
+     386             :         // Now check which energies and volumes are below X kt
+     387      109284 :         for(Grid::index_t l=0; l<targetDistGrid().getSize(); l++) {
+     388      109242 :           double energy = targetDistGrid().getPoint(l)[0];
+     389      109242 :           double value = getFesGridPntr()->getValue(l);
+     390      109242 :           value = beta*value + (beta_prime-beta)*energy - minval;
+     391      109242 :           if (value<threshold_) {
+     392             :             double value = 1.0;
+     393        7076 :             targetDistGrid().setValue(l,value);
+     394             :           }
+     395             :         }
+     396             :       }
+     397           2 :       if (smoothening_) {
+     398           2 :         std::vector<unsigned> nbin=targetDistGrid().getNbin();
+     399           2 :         std::vector<double> dx=targetDistGrid().getDx();
+     400             :         // Smoothening
+     401         104 :         for(unsigned i=0; i<nbin[0]; i++) {
+     402        5304 :           for(unsigned j=0; j<nbin[1]; j++) {
+     403        5202 :             std::vector<unsigned> indices(2);
+     404        5202 :             indices[0]=i;
+     405        5202 :             indices[1]=j;
+     406        5202 :             Grid::index_t index = targetDistGrid().getIndex(indices);
+     407        5202 :             double energy = targetDistGrid().getPoint(index)[0];
+     408        5202 :             double volume = targetDistGrid().getPoint(index)[1];
+     409        5202 :             double value = targetDistGrid().getValue(index);
+     410        5202 :             if (value>(1-1.e-5)) { // Apply only if this grid point was 1.
+     411             :               // Apply gaussians around
+     412         773 :               std::vector<int> minBin(2), maxBin(2), deltaBin(2); // These cannot be unsigned
+     413             :               // Only consider contributions less than n*sigma bins apart from the actual distance
+     414         773 :               deltaBin[0]=std::floor(6*sigma_[0]/dx[0]);;
+     415         773 :               deltaBin[1]=std::floor(6*sigma_[1]/dx[1]);;
+     416             :               // For energy
+     417         773 :               minBin[0]=i - deltaBin[0];
+     418         773 :               if (minBin[0] < 0) minBin[0]=0;
+     419         773 :               if (minBin[0] > (nbin[0]-1)) minBin[0]=nbin[0]-1;
+     420         773 :               maxBin[0]=i +  deltaBin[0];
+     421         773 :               if (maxBin[0] > (nbin[0]-1)) maxBin[0]=nbin[0]-1;
+     422             :               // For volume
+     423         773 :               minBin[1]=j - deltaBin[1];
+     424         773 :               if (minBin[1] < 0) minBin[1]=0;
+     425         773 :               if (minBin[1] > (nbin[1]-1)) minBin[1]=nbin[1]-1;
+     426         773 :               maxBin[1]=j +  deltaBin[1];
+     427         773 :               if (maxBin[1] > (nbin[1]-1)) maxBin[1]=nbin[1]-1;
+     428       31273 :               for(unsigned l=minBin[0]; l<maxBin[0]+1; l++) {
+     429      549973 :                 for(unsigned m=minBin[1]; m<maxBin[1]+1; m++) {
+     430      519473 :                   std::vector<unsigned> indices_prime(2);
+     431      519473 :                   indices_prime[0]=l;
+     432      519473 :                   indices_prime[1]=m;
+     433      519473 :                   Grid::index_t index_prime = targetDistGrid().getIndex(indices_prime);
+     434      519473 :                   double energy_prime = targetDistGrid().getPoint(index_prime)[0];
+     435      519473 :                   double volume_prime = targetDistGrid().getPoint(index_prime)[1];
+     436      519473 :                   double value_prime = targetDistGrid().getValue(index_prime);
+     437             :                   // Apply gaussian
+     438     1558419 :                   double gaussian_value = GaussianSwitchingFunc(energy_prime,energy,sigma_[0])*GaussianSwitchingFunc(volume_prime,volume,sigma_[1]);
+     439      519473 :                   if (value_prime<gaussian_value) {
+     440       19817 :                     targetDistGrid().setValue(index_prime,gaussian_value);
+     441             :                   }
+     442             :                 }
+     443             :               }
+     444             :             }
+     445             :           }
+     446             :         }
+     447             :       }
+     448             :       // Normalize
+     449           4 :       std::vector<double> integration_weights = GridIntegrationWeights::getIntegrationWeights(getTargetDistGridPntr());
+     450             :       double norm = 0.0;
+     451        5204 :       for(Grid::index_t l=0; l<targetDistGrid().getSize(); l++) {
+     452        5202 :         double value = targetDistGrid().getValue(l);
+     453        5202 :         norm += integration_weights[l]*value;
+     454             :       }
+     455           2 :       targetDistGrid().scaleAllValuesAndDerivatives(1.0/norm);
+     456           0 :     } else plumed_merror(getName()+": Number of arguments for this target distribution must be 1 or 2");
+     457             :   }
+     458          14 :   updateLogTargetDistGrid();
+     459          14 : }
+     460             : 
+     461             : inline
+     462             : double TD_Multicanonical::GaussianSwitchingFunc(const double argument, const double center, const double sigma) const {
+     463     1039362 :   if(sigma>0.0) {
+     464     1039362 :     double arg=(argument-center)/sigma;
+     465     1039362 :     return exp(-0.5*arg*arg);
+     466             :   }
+     467             :   else {
+     468             :     return 0.0;
+     469             :   }
+     470             : }
+     471             : 
+     472             : 
+     473             : }
+     474             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_MultithermalMultibaric.cpp.func-sort-c.html b/coverage/ves/TD_MultithermalMultibaric.cpp.func-sort-c.html new file mode 100644 index 000000000000..733051f70700 --- /dev/null +++ b/coverage/ves/TD_MultithermalMultibaric.cpp.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_MultithermalMultibaric.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_MultithermalMultibaric.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:14715197.4 %
Date:2024-04-19 12:12:35Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD3ves25TD_MultithermalMultibaric8getValueERKSt6vectorIdSaIdEE0
_ZN4PLMD3ves25TD_MultithermalMultibaricC2ERKNS_13ActionOptionsE2
_ZN4PLMD3ves25TD_MultithermalMultibaricD0Ev2
_ZN4PLMD3ves25TD_MultithermalMultibaricD2Ev2
_ZN4PLMD3ves25TD_MultithermalMultibaric10updateGridEv4
_ZN4PLMD3ves25TD_MultithermalMultibaric16registerKeywordsERNS_8KeywordsE4
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_MultithermalMultibaric.cpp.func.html b/coverage/ves/TD_MultithermalMultibaric.cpp.func.html new file mode 100644 index 000000000000..e5dc0b9f8193 --- /dev/null +++ b/coverage/ves/TD_MultithermalMultibaric.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_MultithermalMultibaric.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_MultithermalMultibaric.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:14715197.4 %
Date:2024-04-19 12:12:35Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves25TD_MultithermalMultibaric10updateGridEv4
_ZN4PLMD3ves25TD_MultithermalMultibaric16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD3ves25TD_MultithermalMultibaricC2ERKNS_13ActionOptionsE2
_ZN4PLMD3ves25TD_MultithermalMultibaricD0Ev2
_ZN4PLMD3ves25TD_MultithermalMultibaricD2Ev2
_ZNK4PLMD3ves25TD_MultithermalMultibaric8getValueERKSt6vectorIdSaIdEE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_MultithermalMultibaric.cpp.gcov.html b/coverage/ves/TD_MultithermalMultibaric.cpp.gcov.html new file mode 100644 index 000000000000..8901df26df29 --- /dev/null +++ b/coverage/ves/TD_MultithermalMultibaric.cpp.gcov.html @@ -0,0 +1,534 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_MultithermalMultibaric.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_MultithermalMultibaric.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:14715197.4 %
Date:2024-04-19 12:12:35Functions:5683.3 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "TargetDistribution.h"
+      24             : #include "GridIntegrationWeights.h"
+      25             : #include "core/ActionRegister.h"
+      26             : #include "tools/Grid.h"
+      27             : #include "core/PlumedMain.h"
+      28             : #include <cfloat>
+      29             : 
+      30             : 
+      31             : namespace PLMD {
+      32             : namespace ves {
+      33             : 
+      34             : //+PLUMEDOC VES_TARGETDIST TD_MULTITHERMAL_MULTIBARIC
+      35             : /*
+      36             : Multithermal-multibaric target distribution (dynamic).
+      37             : 
+      38             : Use the target distribution to sample the multithermal-multibaric ensemble \cite Piaggi-PRL-2019 \cite Okumura-CPL-2004.
+      39             : In this way, in a single molecular dynamics simulation one can obtain information
+      40             : about the simulated system in a range of temperatures and pressures.
+      41             : This range is determined through the keywords MIN_TEMP, MAX_TEMP, MIN_PRESSURE, and MAX_PRESSURE.
+      42             : One should also specified the target pressure of the barostat with the keyword PRESSURE.
+      43             : 
+      44             : The collective variables (CVs) used to construct the bias potential must be:
+      45             :   1. the potential energy and the volume or,
+      46             :   2. the potential energy, the volume, and an order parameter.
+      47             : 
+      48             : Other choices of CVs or a different order of the above mentioned CVs are nonsensical.
+      49             : The third CV, the order parameter, must be used when the region of the phase diagram under study is crossed by a first order phase transition \cite Piaggi-JCP-2019 .
+      50             : 
+      51             : The algorithm will explore the free energy at each temperature and pressure up to a predefined free
+      52             :  energy threshold \f$\epsilon\f$ specified through the keyword THRESHOLD (in kT units).
+      53             : If only the energy and the volume are being biased, i.e. no phase transition is considered, then THRESHOLD can be set to around 5.
+      54             : If also an order parameter is used then the THRESHOLD should be greater than the barrier for the transformation in kT.
+      55             : For small systems undergoing a freezing transition THRESHOLD is typically between 20 and 50.
+      56             : 
+      57             : It is also important to specify the number of intermediate temperatures and pressures to consider.
+      58             : This is done through the keywords STEPS_TEMP and STEPS_PRESSURE.
+      59             : If the number of intermediate temperature and pressures is too small, then holes might appear in the target distribution.
+      60             : If it is too large, the performance will deteriorate with no additional advantage.
+      61             : 
+      62             : We now describe the algorithm more rigorously.
+      63             : The target distribution is given by
+      64             : \f[
+      65             : p(E,\mathcal{V},s)=
+      66             :   \begin{cases}
+      67             :     1/\Omega_{E,\mathcal{V},s} & \text{if there is at least one } \beta',P' \text{ such} \\
+      68             :              & \text{that } \beta' F_{\beta',P'}(E,\mathcal{V},s)<\epsilon \text{ with}  \\
+      69             :              & \beta_1>\beta'>\beta_2 \text{ and } P_1<P'<P_2 \\
+      70             :     0 & \text{otherwise}
+      71             :   \end{cases}
+      72             : \f]
+      73             : with \f$F_{\beta',P'}(E,\mathcal{V},s)\f$ the free energy as a function of energy \f$E\f$ and volume \f$\mathcal{V}\f$ (and optionally the order parameter \f$s\f$) at temperature \f$\beta'\f$ and pressure \f$P'\f$, \f$\Omega_{E,\mathcal{V},s}\f$ is a normalization constant, and \f$\epsilon\f$ is the THRESHOLD.
+      74             : In practice the condition \f$\beta' F_{\beta',P'}(E,\mathcal{V},s)<\epsilon\f$  is checked in equally spaced points in each dimension \f$\beta'\f$ and \f$P'\f$.
+      75             : The number of points is determined with the keywords STEPS_TEMP and STEPS_PRESSURE.
+      76             : In practice the target distribution is never set to zero but rather to a small value controlled by the keyword EPSILON.
+      77             : The small value is e^-EPSILON.
+      78             : 
+      79             : Much like in the Wang-Landau algorithm \cite wanglandau or in the multicanonical ensemble \cite Berg-PRL-1992 , a flat histogram is targeted.
+      80             : The idea behind this choice of target distribution is that all regions of potential energy and volume (and optionally order parameter) that are relevant at all temperatures \f$\beta_1<\beta'<\beta_2\f$ and pressure \f$P_1<P'<P_2\f$ are included in the distribution.
+      81             : 
+      82             : The free energy at temperature \f$\beta'\f$ and pressure \f$P'\f$ is calculated from the free energy at \f$\beta\f$ and \f$P\f$ using:
+      83             : \f[
+      84             : \beta' F_{\beta',P'}(E,\mathcal{V},s) = \beta F_{\beta,P}(E,\mathcal{V},s) + (\beta' - \beta) E + (\beta' P' - \beta P ) \mathcal{V} + C
+      85             : \f]
+      86             : with \f$C\f$ such that \f$F_{\beta',P'}(E_m,\mathcal{V}_m,s_m)=0\f$ with \f$E_{m},\mathcal{V}_m,s_m\f$ the position of the free energy minimum.
+      87             : \f$ \beta F_{\beta,P}(E,\mathcal{V},s) \f$ is not know from the start and is instead found during the simulation.
+      88             : Therefore \f$ p(E,\mathcal{V},s) \f$ is determined iteratively as done in the well tempered target distribution \cite Valsson-JCTC-2015.
+      89             : 
+      90             : The output of these simulations can be reweighted in order to obtain information at all temperatures and pressures in the targeted region of Temperature-Pressure plane.
+      91             : The reweighting can be performed using the action \ref REWEIGHT_TEMP_PRESS.
+      92             : 
+      93             : The multicanonical ensemble (fixed volume) can be targeted using \ref TD_MULTICANONICAL.
+      94             : 
+      95             : \par Examples
+      96             : 
+      97             : The following input can be used to run a simulation in the multithermal-multibaric ensemble.
+      98             : The region of the temperature-pressure plane that will be explored is 260-350 K and 1 bar- 300 MPa.
+      99             : The energy and the volume are used as collective variables.
+     100             : Legendre polynomials are used to construct the two dimensional bias potential.
+     101             : The averaged stochastic gradient descent algorithm is chosen to optimize the VES functional.
+     102             : The target distribution is updated every 100 optimization steps (200 ps here) using the last estimation of the free energy.
+     103             : 
+     104             : \plumedfile
+     105             : # Use energy and volume as CVs
+     106             : energy: ENERGY
+     107             : vol: VOLUME
+     108             : 
+     109             : # Basis functions
+     110             : bf1: BF_LEGENDRE ORDER=10 MINIMUM=-14750 MAXIMUM=-12250
+     111             : bf2: BF_LEGENDRE ORDER=10 MINIMUM=6.5 MAXIMUM=8.25
+     112             : 
+     113             : # Target distribution - 1 bar = 0.06022140857 and 300 MPa = 180.66422571
+     114             : TD_MULTITHERMAL_MULTIBARIC ...
+     115             :  MIN_TEMP=260
+     116             :  MAX_TEMP=350
+     117             :  MAX_PRESSURE=180.66422571
+     118             :  MIN_PRESSURE=0.06022140857
+     119             :  PRESSURE=0.06022140857
+     120             :  LABEL=td_multi
+     121             : ... TD_MULTITHERMAL_MULTIBARIC
+     122             : 
+     123             : # Bias expansion
+     124             : VES_LINEAR_EXPANSION ...
+     125             :  ARG=energy,vol
+     126             :  BASIS_FUNCTIONS=bf1,bf2
+     127             :  TEMP=300.0
+     128             :  GRID_BINS=200,200
+     129             :  TARGET_DISTRIBUTION=td_multi
+     130             :  LABEL=b1
+     131             : ... VES_LINEAR_EXPANSION
+     132             : 
+     133             : # Optimization algorithm
+     134             : OPT_AVERAGED_SGD ...
+     135             :   BIAS=b1
+     136             :   STRIDE=500
+     137             :   LABEL=o1
+     138             :   STEPSIZE=1.0
+     139             :   FES_OUTPUT=500
+     140             :   BIAS_OUTPUT=500
+     141             :   TARGETDIST_OUTPUT=500
+     142             :   COEFFS_OUTPUT=100
+     143             :   TARGETDIST_STRIDE=100
+     144             : ... OPT_AVERAGED_SGD
+     145             : 
+     146             : \endplumedfile
+     147             : 
+     148             : 
+     149             : The multithermal-multibaric target distribution can also be used to explore regions of the phase diagram crossed by first order phase transitions.
+     150             : Consider a system of 250 atoms that crystallizes in the FCC crystal structure.
+     151             : The region of the temperature-pressure plane that will be explored is 350-450 K and 1bar-1GPa.
+     152             : We assume that inside this region we can find the liquid-FCC coexistence line that we would like to obtain.
+     153             : In this case in addition to the energy and volume, an order parameter must also be biased.
+     154             : The energy, volume, and an order parameter are used as collective variables to construct the bias potential.
+     155             : We choose as order parameter the \ref FCCUBIC.
+     156             : Legendre polynomials are used to construct the three dimensional bias potential.
+     157             : The averaged stochastic gradient descent algorithm is chosen to optimize the VES functional.
+     158             : The target distribution is updated every 100 optimization steps (200 ps here) using the last estimation of the free energy.
+     159             : 
+     160             : \plumedfile
+     161             : # Use energy, volume and FCCUBIC as CVs
+     162             : energy: ENERGY
+     163             : vol: VOLUME
+     164             : fcc: FCCUBIC SPECIES=1-256 SWITCH={CUBIC D_0=0.4 D_MAX=0.5} MORE_THAN={RATIONAL R_0=0.45 NN=12 MM=24}
+     165             : 
+     166             : # Basis functions
+     167             : bf1: BF_LEGENDRE ORDER=8 MINIMUM=-26500 MAXIMUM=-23500
+     168             : bf2: BF_LEGENDRE ORDER=8 MINIMUM=8.0 MAXIMUM=11.5
+     169             : bf3: BF_LEGENDRE ORDER=8 MINIMUM=0.0 MAXIMUM=256.0
+     170             : 
+     171             : # Target distribution
+     172             : TD_MULTITHERMAL_MULTIBARIC ...
+     173             :  LABEL=td_multitp
+     174             :  MIN_TEMP=350.0
+     175             :  MAX_TEMP=450.0
+     176             :  MIN_PRESSURE=0.06022140857
+     177             :  MAX_PRESSURE=602.2140857
+     178             :  PRESSURE=301.10704285
+     179             :  SIGMA=250.0,0.1,10.0
+     180             :  THRESHOLD=15
+     181             :  STEPS_TEMP=20
+     182             :  STEPS_PRESSURE=20
+     183             : ... TD_MULTITHERMAL_MULTIBARIC
+     184             : 
+     185             : # Expansion
+     186             : VES_LINEAR_EXPANSION ...
+     187             :  ARG=energy,vol,fcc.morethan
+     188             :  BASIS_FUNCTIONS=bf1,bf2,bf3
+     189             :  TEMP=400.0
+     190             :  GRID_BINS=40,40,40
+     191             :  TARGET_DISTRIBUTION=td_multitp
+     192             :  LABEL=b1
+     193             : ... VES_LINEAR_EXPANSION
+     194             : 
+     195             : # Optimization algorithm
+     196             : OPT_AVERAGED_SGD ...
+     197             :   BIAS=b1
+     198             :   STRIDE=500
+     199             :   LABEL=o1
+     200             :   STEPSIZE=1.0
+     201             :   FES_OUTPUT=500
+     202             :   BIAS_OUTPUT=500
+     203             :   TARGETDIST_OUTPUT=500
+     204             :   COEFFS_OUTPUT=100
+     205             :   TARGETDIST_STRIDE=500
+     206             : ... OPT_AVERAGED_SGD
+     207             : 
+     208             : \endplumedfile
+     209             : 
+     210             : */
+     211             : //+ENDPLUMEDOC
+     212             : 
+     213             : class TD_MultithermalMultibaric: public TargetDistribution {
+     214             : private:
+     215             :   double threshold_, min_temp_, max_temp_;
+     216             :   double min_press_, max_press_, press_;
+     217             :   double epsilon_;
+     218             :   bool smoothening_;
+     219             :   std::vector<double> sigma_;
+     220             :   unsigned steps_temp_, steps_pressure_;
+     221             : public:
+     222             :   static void registerKeywords(Keywords&);
+     223             :   explicit TD_MultithermalMultibaric(const ActionOptions& ao);
+     224             :   void updateGrid() override;
+     225             :   double getValue(const std::vector<double>&) const override;
+     226           4 :   ~TD_MultithermalMultibaric() {}
+     227             :   double GaussianSwitchingFunc(const double, const double, const double) const;
+     228             : };
+     229             : 
+     230             : 
+     231             : PLUMED_REGISTER_ACTION(TD_MultithermalMultibaric,"TD_MULTITHERMAL_MULTIBARIC")
+     232             : 
+     233             : 
+     234           4 : void TD_MultithermalMultibaric::registerKeywords(Keywords& keys) {
+     235           4 :   TargetDistribution::registerKeywords(keys);
+     236           8 :   keys.add("compulsory","THRESHOLD","5","Maximum exploration free energy in kT.");
+     237           8 :   keys.add("compulsory","EPSILON","10","The zeros of the target distribution are changed to e^-EPSILON.");
+     238           8 :   keys.add("compulsory","MIN_TEMP","Minimum energy.");
+     239           8 :   keys.add("compulsory","MAX_TEMP","Maximum energy.");
+     240           8 :   keys.add("compulsory","MIN_PRESSURE","Minimum pressure.");
+     241           8 :   keys.add("compulsory","MAX_PRESSURE","Maximum pressure.");
+     242           8 :   keys.add("compulsory","PRESSURE","Target pressure of the barostat used in the MD engine.");
+     243           8 :   keys.add("compulsory","STEPS_TEMP","20","Number of temperature steps.");
+     244           8 :   keys.add("compulsory","STEPS_PRESSURE","20","Number of pressure steps.");
+     245           8 :   keys.add("optional","SIGMA","The standard deviation parameters of the Gaussian kernels used for smoothing the target distribution. One value must be specified for each argument, i.e. one value per CV. A value of 0.0 means that no smoothing is performed, this is the default behavior.");
+     246           4 : }
+     247             : 
+     248             : 
+     249           2 : TD_MultithermalMultibaric::TD_MultithermalMultibaric(const ActionOptions& ao):
+     250             :   PLUMED_VES_TARGETDISTRIBUTION_INIT(ao),
+     251           2 :   threshold_(5.0),
+     252           2 :   min_temp_(0.0),
+     253           2 :   max_temp_(1000.0),
+     254           2 :   min_press_(0.0),
+     255           2 :   max_press_(1000.0),
+     256           2 :   epsilon_(10.0),
+     257           2 :   smoothening_(true),
+     258           2 :   steps_temp_(20),
+     259           2 :   steps_pressure_(20)
+     260             : {
+     261           2 :   log.printf("  Multithermal-multibaric target distribution");
+     262           2 :   log.printf("\n");
+     263             : 
+     264           2 :   log.printf("  Please read and cite ");
+     265           4 :   log << plumed.cite("Piaggi and Parrinello, Phys. Rev. Lett. 122 (5), 050601 (2019)");
+     266           2 :   log.printf(" and ");
+     267           4 :   log << plumed.cite("Piaggi and Parrinello, J. Chem. Phys. 150 (24), 244119 (2019)");
+     268           2 :   log.printf("\n");
+     269             : 
+     270             : 
+     271           2 :   parse("THRESHOLD",threshold_);
+     272           2 :   if(threshold_<=0.0) {
+     273           0 :     plumed_merror(getName()+": the value of the threshold should be positive.");
+     274             :   }
+     275           2 :   log.printf("  exploring free energy up to %f kT for each temperature and pressure\n",threshold_);
+     276           2 :   parse("MIN_TEMP",min_temp_);
+     277           2 :   parse("MAX_TEMP",max_temp_);
+     278           2 :   log.printf("  temperatures between %f and %f will be explored \n",min_temp_,max_temp_);
+     279           2 :   parse("MIN_PRESSURE",min_press_);
+     280           2 :   parse("MAX_PRESSURE",max_press_);
+     281           2 :   log.printf("  pressures between %f and %f will be explored \n",min_press_,max_press_);
+     282           2 :   parse("PRESSURE",press_);
+     283           2 :   log.printf("  pressure of the barostat should have been set to %f. Please check this in the MD engine \n",press_);
+     284           4 :   parseVector("SIGMA",sigma_);
+     285           2 :   if(sigma_.size()==0) smoothening_=false;
+     286           2 :   if(smoothening_ && (sigma_.size()<2 || sigma_.size()>3) ) plumed_merror(getName()+": SIGMA takes 2 or 3 values as input.");
+     287           2 :   if (smoothening_) {
+     288           2 :     log.printf("  the target distribution will be smoothed using sigma values");
+     289           7 :     for(unsigned i=0; i<sigma_.size(); ++i) log.printf(" %f",sigma_[i]);
+     290           2 :     log.printf("\n");
+     291             :   }
+     292           2 :   parse("STEPS_TEMP",steps_temp_);
+     293           2 :   parse("STEPS_PRESSURE",steps_pressure_);
+     294           2 :   log.printf("  %d steps in temperatures and %d steps in pressure will be employed \n",steps_temp_,steps_pressure_);
+     295           2 :   steps_temp_ += 1;
+     296           2 :   steps_pressure_ += 1;
+     297           2 :   parse("EPSILON",epsilon_);
+     298           2 :   if(epsilon_<=1.0) {
+     299           0 :     plumed_merror(getName()+": the value of epsilon should be greater than 1.");
+     300             :   }
+     301           2 :   log.printf("  the non relevant regions of the target distribution are set to e^-%f \n",epsilon_);
+     302             :   setDynamic();
+     303             :   setFesGridNeeded();
+     304           2 :   checkRead();
+     305           2 : }
+     306             : 
+     307             : 
+     308           0 : double TD_MultithermalMultibaric::getValue(const std::vector<double>& argument) const {
+     309           0 :   plumed_merror("getValue not implemented for TD_MultithermalMultibaric");
+     310             :   return 0.0;
+     311             : }
+     312             : 
+     313             : 
+     314           4 : void TD_MultithermalMultibaric::updateGrid() {
+     315           4 :   if (getStep() == 0) {
+     316           2 :     if(targetDistGrid().getDimension()>3 || targetDistGrid().getDimension()<2) plumed_merror(getName()+" works only with 2 or 3 arguments, i.e. energy and volume, or energy, volume, and CV");
+     317           2 :     if(smoothening_ && sigma_.size()!=targetDistGrid().getDimension()) plumed_merror(getName()+": mismatch between SIGMA dimension and number of arguments");
+     318             :     // Use uniform TD
+     319           4 :     std::vector<double> integration_weights = GridIntegrationWeights::getIntegrationWeights(getTargetDistGridPntr());
+     320             :     double norm = 0.0;
+     321       11864 :     for(Grid::index_t l=0; l<targetDistGrid().getSize(); l++) {
+     322             :       double value = 1.0;
+     323       11862 :       norm += integration_weights[l]*value;
+     324       11862 :       targetDistGrid().setValue(l,value);
+     325             :     }
+     326           2 :     targetDistGrid().scaleAllValuesAndDerivatives(1.0/norm);
+     327             :   } else {
+     328           2 :     double beta = getBeta();
+     329           2 :     double beta_prime_min = 1./(getKBoltzmann()*min_temp_);
+     330           2 :     double beta_prime_max = 1./(getKBoltzmann()*max_temp_);
+     331           2 :     plumed_massert(getFesGridPntr()!=NULL,"the FES grid has to be linked to use TD_MultithermalMultibaric!");
+     332             :     // Set all to current epsilon value
+     333       11864 :     for(Grid::index_t l=0; l<targetDistGrid().getSize(); l++) {
+     334       11862 :       double value = exp(-1.0*epsilon_);
+     335       11862 :       targetDistGrid().setValue(l,value);
+     336             :     }
+     337             :     // Loop over pressures and temperatures
+     338          44 :     for(unsigned i=0; i<steps_temp_; i++) {
+     339          42 :       double beta_prime=beta_prime_min + (beta_prime_max-beta_prime_min)*i/(steps_temp_-1);
+     340         924 :       for(unsigned j=0; j<steps_pressure_; j++) {
+     341         882 :         double pressure_prime=min_press_ + (max_press_-min_press_)*j/(steps_pressure_-1);
+     342             :         // Find minimum for this pressure and temperature
+     343             :         double minval=DBL_MAX;
+     344     5232024 :         for(Grid::index_t l=0; l<targetDistGrid().getSize(); l++) {
+     345     5231142 :           double energy = targetDistGrid().getPoint(l)[0];
+     346     5231142 :           double volume = targetDistGrid().getPoint(l)[1];
+     347     5231142 :           double value = getFesGridPntr()->getValue(l);
+     348     5231142 :           value = beta*value + (beta_prime-beta)*energy + (beta_prime*pressure_prime-beta*press_)*volume;
+     349     5231142 :           if(value<minval) {
+     350             :             minval=value;
+     351             :           }
+     352             :         }
+     353             :         // Now check which energies and volumes are below X kt
+     354     5232024 :         for(Grid::index_t l=0; l<targetDistGrid().getSize(); l++) {
+     355     5231142 :           double energy = targetDistGrid().getPoint(l)[0];
+     356     5231142 :           double volume = targetDistGrid().getPoint(l)[1];
+     357     5231142 :           double value = getFesGridPntr()->getValue(l);
+     358     5231142 :           value = beta*value + (beta_prime-beta)*energy + (beta_prime*pressure_prime-beta*press_)*volume - minval;
+     359     5231142 :           if (value<threshold_) {
+     360             :             double value = 1.0;
+     361       65261 :             targetDistGrid().setValue(l,value);
+     362             :           }
+     363             :         }
+     364             :       }
+     365             :     }
+     366           2 :     if (smoothening_) {
+     367           2 :       std::vector<unsigned> nbin=targetDistGrid().getNbin();
+     368           2 :       std::vector<double> dx=targetDistGrid().getDx();
+     369           2 :       unsigned dim=targetDistGrid().getDimension();
+     370             :       // Smoothening
+     371       11864 :       for(Grid::index_t index=0; index<targetDistGrid().getSize(); index++) {
+     372       11862 :         std::vector<unsigned> indices = targetDistGrid().getIndices(index);
+     373       11862 :         std::vector<double> point = targetDistGrid().getPoint(index);
+     374       11862 :         double value = targetDistGrid().getValue(index);
+     375       11862 :         if (value>(1-1.e-5)) { // Apply only if this grid point was 1.
+     376             :           // Apply gaussians around
+     377        1242 :           std::vector<int> minBin(dim), maxBin(dim); // These cannot be unsigned
+     378             :           // Only consider contributions less than n*sigma bins apart from the actual distance
+     379        4384 :           for(unsigned k=0; k<dim; k++) {
+     380        3142 :             int deltaBin=std::floor(6*sigma_[k]/dx[k]);
+     381        3142 :             minBin[k]=indices[k] - deltaBin;
+     382        3142 :             if (minBin[k] < 0) minBin[k]=0;
+     383        3142 :             if (minBin[k] > (nbin[k]-1)) minBin[k]=nbin[k]-1;
+     384        3142 :             maxBin[k]=indices[k] + deltaBin;
+     385        3142 :             if (maxBin[k] > (nbin[k]-1)) maxBin[k]=nbin[k]-1;
+     386             :           }
+     387        1242 :           if (dim==2) {
+     388        7008 :             for(unsigned l=minBin[0]; l<maxBin[0]+1; l++) {
+     389      115632 :               for(unsigned m=minBin[1]; m<maxBin[1]+1; m++) {
+     390      109208 :                 std::vector<unsigned> indices_prime(dim);
+     391      109208 :                 indices_prime[0]=l;
+     392      109208 :                 indices_prime[1]=m;
+     393      109208 :                 Grid::index_t index_prime = targetDistGrid().getIndex(indices_prime);
+     394      109208 :                 std::vector<double> point_prime = targetDistGrid().getPoint(index_prime);
+     395      109208 :                 double value_prime = targetDistGrid().getValue(index_prime);
+     396             :                 // Apply gaussian
+     397             :                 double gaussian_value = 1;
+     398      327624 :                 for(unsigned k=0; k<dim; k++) {
+     399      436832 :                   gaussian_value *= GaussianSwitchingFunc(point_prime[k],point[k],sigma_[k]);
+     400             :                 }
+     401      109208 :                 if (value_prime<gaussian_value) {
+     402        2761 :                   targetDistGrid().setValue(index_prime,gaussian_value);
+     403             :                 }
+     404             :               }
+     405             :             }
+     406         658 :           } else if (dim==3) {
+     407       12352 :             for(unsigned l=minBin[0]; l<maxBin[0]+1; l++) {
+     408       84952 :               for(unsigned m=minBin[1]; m<maxBin[1]+1; m++) {
+     409      509608 :                 for(unsigned n=minBin[2]; n<maxBin[2]+1; n++) {
+     410      436350 :                   std::vector<unsigned> indices_prime(dim);
+     411      436350 :                   indices_prime[0]=l;
+     412      436350 :                   indices_prime[1]=m;
+     413      436350 :                   indices_prime[2]=n;
+     414      436350 :                   Grid::index_t index_prime = targetDistGrid().getIndex(indices_prime);
+     415      436350 :                   std::vector<double> point_prime = targetDistGrid().getPoint(index_prime);
+     416      436350 :                   double value_prime = targetDistGrid().getValue(index_prime);
+     417             :                   // Apply gaussian
+     418             :                   double gaussian_value = 1;
+     419     1745400 :                   for(unsigned k=0; k<dim; k++) {
+     420     2618100 :                     gaussian_value *= GaussianSwitchingFunc(point_prime[k],point[k],sigma_[k]);
+     421             :                   }
+     422      436350 :                   if (value_prime<gaussian_value) {
+     423       13789 :                     targetDistGrid().setValue(index_prime,gaussian_value);
+     424             :                   }
+     425             :                 }
+     426             :               }
+     427             :             }
+     428             :           }
+     429             :         }
+     430             :       }
+     431             :     }
+     432             :     // Normalize
+     433           4 :     std::vector<double> integration_weights = GridIntegrationWeights::getIntegrationWeights(getTargetDistGridPntr());
+     434             :     double norm = 0.0;
+     435       11864 :     for(Grid::index_t l=0; l<targetDistGrid().getSize(); l++) {
+     436       11862 :       double value = targetDistGrid().getValue(l);
+     437       11862 :       norm += integration_weights[l]*value;
+     438             :     }
+     439           2 :     targetDistGrid().scaleAllValuesAndDerivatives(1.0/norm);
+     440             :   }
+     441           4 :   updateLogTargetDistGrid();
+     442           4 : }
+     443             : 
+     444             : inline
+     445             : double TD_MultithermalMultibaric::GaussianSwitchingFunc(const double argument, const double center, const double sigma) const {
+     446     1527466 :   if(sigma>0.0) {
+     447     1527466 :     double arg=(argument-center)/sigma;
+     448     1527466 :     return exp(-0.5*arg*arg);
+     449             :   }
+     450             :   else {
+     451             :     return 0.0;
+     452             :   }
+     453             : }
+     454             : 
+     455             : 
+     456             : }
+     457             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_ProductCombination.cpp.func-sort-c.html b/coverage/ves/TD_ProductCombination.cpp.func-sort-c.html new file mode 100644 index 000000000000..577d4251f037 --- /dev/null +++ b/coverage/ves/TD_ProductCombination.cpp.func-sort-c.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_ProductCombination.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_ProductCombination.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:557573.3 %
Date:2024-04-19 12:12:35Functions:61060.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves21TD_ProductCombination10linkActionEPNS_6ActionE0
_ZN4PLMD3ves21TD_ProductCombination12linkBiasGridEPNS_4GridE0
_ZN4PLMD3ves21TD_ProductCombination25linkBiasWithoutCutoffGridEPNS_4GridE0
_ZNK4PLMD3ves21TD_ProductCombination8getValueERKSt6vectorIdSaIdEE0
_ZN4PLMD3ves21TD_ProductCombination11linkFesGridEPNS_4GridE1
_ZN4PLMD3ves21TD_ProductCombination11linkVesBiasEPNS0_7VesBiasE1
_ZN4PLMD3ves21TD_ProductCombination20setupAdditionalGridsERKSt6vectorIPNS_5ValueESaIS4_EERKS2_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISE_EESI_RKS2_IjSaIjEE4
_ZN4PLMD3ves21TD_ProductCombinationC2ERKNS_13ActionOptionsE4
_ZN4PLMD3ves21TD_ProductCombination16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD3ves21TD_ProductCombination10updateGridEv14
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_ProductCombination.cpp.func.html b/coverage/ves/TD_ProductCombination.cpp.func.html new file mode 100644 index 000000000000..32ee2b34bd56 --- /dev/null +++ b/coverage/ves/TD_ProductCombination.cpp.func.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_ProductCombination.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_ProductCombination.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:557573.3 %
Date:2024-04-19 12:12:35Functions:61060.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves21TD_ProductCombination10linkActionEPNS_6ActionE0
_ZN4PLMD3ves21TD_ProductCombination10updateGridEv14
_ZN4PLMD3ves21TD_ProductCombination11linkFesGridEPNS_4GridE1
_ZN4PLMD3ves21TD_ProductCombination11linkVesBiasEPNS0_7VesBiasE1
_ZN4PLMD3ves21TD_ProductCombination12linkBiasGridEPNS_4GridE0
_ZN4PLMD3ves21TD_ProductCombination16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD3ves21TD_ProductCombination20setupAdditionalGridsERKSt6vectorIPNS_5ValueESaIS4_EERKS2_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISE_EESI_RKS2_IjSaIjEE4
_ZN4PLMD3ves21TD_ProductCombination25linkBiasWithoutCutoffGridEPNS_4GridE0
_ZN4PLMD3ves21TD_ProductCombinationC2ERKNS_13ActionOptionsE4
_ZNK4PLMD3ves21TD_ProductCombination8getValueERKSt6vectorIdSaIdEE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_ProductCombination.cpp.gcov.html b/coverage/ves/TD_ProductCombination.cpp.gcov.html new file mode 100644 index 000000000000..2eb9ade55b54 --- /dev/null +++ b/coverage/ves/TD_ProductCombination.cpp.gcov.html @@ -0,0 +1,341 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_ProductCombination.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_ProductCombination.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:557573.3 %
Date:2024-04-19 12:12:35Functions:61060.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "TargetDistribution.h"
+      24             : #include "VesTools.h"
+      25             : 
+      26             : 
+      27             : #include "core/ActionRegister.h"
+      28             : #include "core/ActionSet.h"
+      29             : #include "core/PlumedMain.h"
+      30             : #include "tools/Grid.h"
+      31             : 
+      32             : #include "GridIntegrationWeights.h"
+      33             : 
+      34             : 
+      35             : namespace PLMD {
+      36             : 
+      37             : // class Grid;
+      38             : class Action;
+      39             : 
+      40             : namespace ves {
+      41             : 
+      42             : //+PLUMEDOC VES_TARGETDIST TD_PRODUCT_COMBINATION
+      43             : /*
+      44             : Target distribution given by product combination of distributions (static or dynamic).
+      45             : 
+      46             : Employ a target distribution that is a product combination of the other
+      47             : distributions, defined as
+      48             : \f[
+      49             : p(\mathbf{s}) =
+      50             : \frac{\prod_{i} p_{i}(\mathbf{s})}
+      51             : {\int d \mathbf{s} \prod_{i} p_{i}(\mathbf{s})}
+      52             : \f]
+      53             : where the distributions \f$p_{i}(\mathbf{s})\f$ are in full dimensional space
+      54             : of the arguments used.
+      55             : 
+      56             : Note the difference between this target distribution and the one defined in
+      57             : \ref TD_PRODUCT_DISTRIBUTION. Here we have a non-separable distribution given
+      58             : as a product of distribution \f$p_{i}(\mathbf{s})\f$ which are in full dimensional
+      59             : space of the arguments used.
+      60             : 
+      61             : The labels of the distributions \f$p_{i}(\mathbf{s})\f$ to be used in the
+      62             : product combination are given in the DISTRIBUTIONS keyword.
+      63             : 
+      64             : The target distribution resulting from the product combination will be
+      65             : automatically normalized. Therefore, the product combination needs to
+      66             : be a proper distribution that is non-negative and that can be normalized. The
+      67             : code will perform checks to make sure that this is indeed the case.
+      68             : 
+      69             : The product combination will be a dynamic target distribution if one or more
+      70             : of the distributions used is a dynamic distribution. Otherwise it will be a
+      71             : static distribution.
+      72             : 
+      73             : \par Examples
+      74             : 
+      75             : In the following example the overall interval on which the
+      76             : target distribution is defined is from 0.23 to 0.8.
+      77             : We employ a product combination of a well-tempered
+      78             : distribution and a uniform distribution that decays to
+      79             : zero at 0.6. This results in a target distribution that
+      80             : is well-tempered from 0.23 to 0.6 and then decays to zero.
+      81             : In other words, we cut off the tail of the well-tempered
+      82             : distribution at 0.6
+      83             : \plumedfile
+      84             : td_welltemp: TD_WELLTEMPERED BIASFACTOR=5
+      85             : td_uniform: TD_UNIFORM MINIMA=0.23 MAXIMA=0.6 SIGMA_MAXIMA=0.05
+      86             : td_combination: TD_PRODUCT_COMBINATION DISTRIBUTIONS=td_uniform,td_welltemp
+      87             : \endplumedfile
+      88             : 
+      89             : 
+      90             : In the following example the overall interval on which the
+      91             : target distribution is defined is from -4 to 4.
+      92             : We employ a product of a Gaussian distribution with two centers
+      93             : and distribution that is uniform on the interval -3 to 3 and
+      94             : then smoothly decays to zero outside that interval.
+      95             : The overall effect will then be to cut off the tails of the
+      96             : Gaussian distribution
+      97             : \plumedfile
+      98             : TD_GAUSSIAN ...
+      99             :  CENTER1=-2.9 SIGMA1=1.0
+     100             :  CENTER2=+2.9 SIGMA2=0.4
+     101             :  LABEL=td_gauss
+     102             : ... TD_GAUSSIAN
+     103             : 
+     104             : TD_UNIFORM ...
+     105             :  MINIMA=-3.0 SIGMA_MINIMA=0.20
+     106             :  MAXIMA=+3.0 SIGMA_MAXIMA=0.15
+     107             :  LABEL=td_uni
+     108             : ... TD_UNIFORM
+     109             : 
+     110             : td_pc: TD_PRODUCT_COMBINATION DISTRIBUTIONS=td_gauss,td_uni
+     111             : \endplumedfile
+     112             : 
+     113             : */
+     114             : //+ENDPLUMEDOC
+     115             : 
+     116             : class VesBias;
+     117             : 
+     118             : class TD_ProductCombination: public TargetDistribution {
+     119             : private:
+     120             :   std::vector<TargetDistribution*> distribution_pntrs_;
+     121             :   std::vector<Grid*> grid_pntrs_;
+     122             :   unsigned int ndist_;
+     123             :   void setupAdditionalGrids(const std::vector<Value*>&, const std::vector<std::string>&, const std::vector<std::string>&, const std::vector<unsigned int>&) override;
+     124             : public:
+     125             :   static void registerKeywords(Keywords&);
+     126             :   explicit TD_ProductCombination(const ActionOptions& ao);
+     127             :   void updateGrid() override;
+     128             :   double getValue(const std::vector<double>&) const override;
+     129             :   //
+     130             :   void linkVesBias(VesBias*) override;
+     131             :   void linkAction(Action*) override;
+     132             :   //
+     133             :   void linkBiasGrid(Grid*) override;
+     134             :   void linkBiasWithoutCutoffGrid(Grid*) override;
+     135             :   void linkFesGrid(Grid*) override;
+     136             :   //
+     137             : };
+     138             : 
+     139             : 
+     140             : PLUMED_REGISTER_ACTION(TD_ProductCombination,"TD_PRODUCT_COMBINATION")
+     141             : 
+     142             : 
+     143           6 : void TD_ProductCombination::registerKeywords(Keywords& keys) {
+     144           6 :   TargetDistribution::registerKeywords(keys);
+     145          12 :   keys.add("compulsory","DISTRIBUTIONS","The labels of the target distribution actions to be used in the product combination.");
+     146           6 :   keys.use("WELLTEMPERED_FACTOR");
+     147           6 :   keys.use("SHIFT_TO_ZERO");
+     148           6 : }
+     149             : 
+     150             : 
+     151           4 : TD_ProductCombination::TD_ProductCombination(const ActionOptions& ao):
+     152             :   PLUMED_VES_TARGETDISTRIBUTION_INIT(ao),
+     153           8 :   distribution_pntrs_(0),
+     154           4 :   grid_pntrs_(0),
+     155           8 :   ndist_(0)
+     156             : {
+     157             :   std::vector<std::string> targetdist_labels;
+     158           4 :   parseVector("DISTRIBUTIONS",targetdist_labels);
+     159             : 
+     160           4 :   std::string error_msg = "";
+     161           8 :   distribution_pntrs_ = VesTools::getPointersFromLabels<TargetDistribution*>(targetdist_labels,plumed.getActionSet(),error_msg);
+     162           4 :   if(error_msg.size()>0) {plumed_merror("Error in keyword DISTRIBUTIONS of "+getName()+": "+error_msg);}
+     163             : 
+     164          12 :   for(unsigned int i=0; i<distribution_pntrs_.size(); i++) {
+     165           8 :     if(distribution_pntrs_[i]->isDynamic()) {setDynamic();}
+     166           8 :     if(distribution_pntrs_[i]->fesGridNeeded()) {setFesGridNeeded();}
+     167           8 :     if(distribution_pntrs_[i]->biasGridNeeded()) {setBiasGridNeeded();}
+     168             :   }
+     169             : 
+     170           4 :   ndist_ = distribution_pntrs_.size();
+     171           4 :   grid_pntrs_.assign(ndist_,NULL);
+     172           4 :   if(ndist_==0) {plumed_merror(getName()+ ": no distributions are given.");}
+     173           4 :   if(ndist_==1) {plumed_merror(getName()+ ": giving only one distribution does not make sense.");}
+     174             :   //
+     175           4 :   checkRead();
+     176           4 : }
+     177             : 
+     178             : 
+     179           0 : double TD_ProductCombination::getValue(const std::vector<double>& argument) const {
+     180           0 :   plumed_merror("getValue not implemented for TD_ProductCombination");
+     181             :   return 0.0;
+     182             : }
+     183             : 
+     184             : 
+     185           4 : void TD_ProductCombination::setupAdditionalGrids(const std::vector<Value*>& arguments, const std::vector<std::string>& min, const std::vector<std::string>& max, const std::vector<unsigned int>& nbins) {
+     186          12 :   for(unsigned int i=0; i<ndist_; i++) {
+     187           8 :     distribution_pntrs_[i]->setupGrids(arguments,min,max,nbins);
+     188           8 :     if(distribution_pntrs_[i]->getDimension()!=this->getDimension()) {
+     189           0 :       plumed_merror(getName() + ": all target distribution must have the same dimension");
+     190             :     }
+     191           8 :     grid_pntrs_[i]=distribution_pntrs_[i]->getTargetDistGridPntr();
+     192             :   }
+     193           4 : }
+     194             : 
+     195             : 
+     196          14 : void TD_ProductCombination::updateGrid() {
+     197          42 :   for(unsigned int i=0; i<ndist_; i++) {
+     198          28 :     distribution_pntrs_[i]->updateTargetDist();
+     199             :   }
+     200          28 :   std::vector<double> integration_weights = GridIntegrationWeights::getIntegrationWeights(getTargetDistGridPntr());
+     201             :   double norm = 0.0;
+     202       11717 :   for(Grid::index_t l=0; l<targetDistGrid().getSize(); l++) {
+     203             :     double value = 1.0;
+     204       35109 :     for(unsigned int i=0; i<ndist_; i++) {
+     205       23406 :       value *= grid_pntrs_[i]->getValue(l);
+     206             :     }
+     207       11703 :     if(value<0.0 && !isTargetDistGridShiftedToZero()) {plumed_merror(getName()+": The target distribution function gives negative values. You should change the definition of the target distribution to avoid this. You can also use the SHIFT_TO_ZERO keyword to avoid this problem.");}
+     208       11703 :     norm += integration_weights[l]*value;
+     209       11703 :     targetDistGrid().setValue(l,value);
+     210       11703 :     logTargetDistGrid().setValue(l,-std::log(value));
+     211             :   }
+     212             : 
+     213          14 :   if(norm>0.0) {
+     214          14 :     targetDistGrid().scaleAllValuesAndDerivatives(1.0/norm);
+     215             :   }
+     216           0 :   else if(!isTargetDistGridShiftedToZero()) {
+     217           0 :     plumed_merror(getName()+": The target distribution function cannot be normalized proberly. You should change the definition of the target distribution to avoid this. You can also use the SHIFT_TO_ZERO keyword to avoid this problem.");
+     218             :   }
+     219          14 :   logTargetDistGrid().setMinToZero();
+     220          14 : }
+     221             : 
+     222             : 
+     223           1 : void TD_ProductCombination::linkVesBias(VesBias* vesbias_pntr_in) {
+     224           1 :   TargetDistribution::linkVesBias(vesbias_pntr_in);
+     225           3 :   for(unsigned int i=0; i<ndist_; i++) {
+     226           2 :     distribution_pntrs_[i]->linkVesBias(vesbias_pntr_in);
+     227             :   }
+     228           1 : }
+     229             : 
+     230             : 
+     231           0 : void TD_ProductCombination::linkAction(Action* action_pntr_in) {
+     232           0 :   TargetDistribution::linkAction(action_pntr_in);
+     233           0 :   for(unsigned int i=0; i<ndist_; i++) {
+     234           0 :     distribution_pntrs_[i]->linkAction(action_pntr_in);
+     235             :   }
+     236           0 : }
+     237             : 
+     238             : 
+     239           0 : void TD_ProductCombination::linkBiasGrid(Grid* bias_grid_pntr_in) {
+     240           0 :   TargetDistribution::linkBiasGrid(bias_grid_pntr_in);
+     241           0 :   for(unsigned int i=0; i<ndist_; i++) {
+     242           0 :     distribution_pntrs_[i]->linkBiasGrid(bias_grid_pntr_in);
+     243             :   }
+     244           0 : }
+     245             : 
+     246             : 
+     247           0 : void TD_ProductCombination::linkBiasWithoutCutoffGrid(Grid* bias_withoutcutoff_grid_pntr_in) {
+     248           0 :   TargetDistribution::linkBiasWithoutCutoffGrid(bias_withoutcutoff_grid_pntr_in);
+     249           0 :   for(unsigned int i=0; i<ndist_; i++) {
+     250           0 :     distribution_pntrs_[i]->linkBiasWithoutCutoffGrid(bias_withoutcutoff_grid_pntr_in);
+     251             :   }
+     252           0 : }
+     253             : 
+     254             : 
+     255           1 : void TD_ProductCombination::linkFesGrid(Grid* fes_grid_pntr_in) {
+     256           1 :   TargetDistribution::linkFesGrid(fes_grid_pntr_in);
+     257           3 :   for(unsigned int i=0; i<ndist_; i++) {
+     258           2 :     distribution_pntrs_[i]->linkFesGrid(fes_grid_pntr_in);
+     259             :   }
+     260           1 : }
+     261             : 
+     262             : 
+     263             : }
+     264             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_ProductDistribution.cpp.func-sort-c.html b/coverage/ves/TD_ProductDistribution.cpp.func-sort-c.html new file mode 100644 index 000000000000..f83a3dd52371 --- /dev/null +++ b/coverage/ves/TD_ProductDistribution.cpp.func-sort-c.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_ProductDistribution.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_ProductDistribution.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:487663.2 %
Date:2024-04-19 12:12:35Functions:41040.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves22TD_ProductDistribution10linkActionEPNS_6ActionE0
_ZN4PLMD3ves22TD_ProductDistribution11linkFesGridEPNS_4GridE0
_ZN4PLMD3ves22TD_ProductDistribution11linkVesBiasEPNS0_7VesBiasE0
_ZN4PLMD3ves22TD_ProductDistribution12linkBiasGridEPNS_4GridE0
_ZN4PLMD3ves22TD_ProductDistribution25linkBiasWithoutCutoffGridEPNS_4GridE0
_ZNK4PLMD3ves22TD_ProductDistribution8getValueERKSt6vectorIdSaIdEE0
_ZN4PLMD3ves22TD_ProductDistribution10updateGridEv15
_ZN4PLMD3ves22TD_ProductDistribution20setupAdditionalGridsERKSt6vectorIPNS_5ValueESaIS4_EERKS2_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISE_EESI_RKS2_IjSaIjEE15
_ZN4PLMD3ves22TD_ProductDistributionC2ERKNS_13ActionOptionsE15
_ZN4PLMD3ves22TD_ProductDistribution16registerKeywordsERNS_8KeywordsE17
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_ProductDistribution.cpp.func.html b/coverage/ves/TD_ProductDistribution.cpp.func.html new file mode 100644 index 000000000000..6ccd0542bec1 --- /dev/null +++ b/coverage/ves/TD_ProductDistribution.cpp.func.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_ProductDistribution.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_ProductDistribution.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:487663.2 %
Date:2024-04-19 12:12:35Functions:41040.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves22TD_ProductDistribution10linkActionEPNS_6ActionE0
_ZN4PLMD3ves22TD_ProductDistribution10updateGridEv15
_ZN4PLMD3ves22TD_ProductDistribution11linkFesGridEPNS_4GridE0
_ZN4PLMD3ves22TD_ProductDistribution11linkVesBiasEPNS0_7VesBiasE0
_ZN4PLMD3ves22TD_ProductDistribution12linkBiasGridEPNS_4GridE0
_ZN4PLMD3ves22TD_ProductDistribution16registerKeywordsERNS_8KeywordsE17
_ZN4PLMD3ves22TD_ProductDistribution20setupAdditionalGridsERKSt6vectorIPNS_5ValueESaIS4_EERKS2_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISE_EESI_RKS2_IjSaIjEE15
_ZN4PLMD3ves22TD_ProductDistribution25linkBiasWithoutCutoffGridEPNS_4GridE0
_ZN4PLMD3ves22TD_ProductDistributionC2ERKNS_13ActionOptionsE15
_ZNK4PLMD3ves22TD_ProductDistribution8getValueERKSt6vectorIdSaIdEE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_ProductDistribution.cpp.gcov.html b/coverage/ves/TD_ProductDistribution.cpp.gcov.html new file mode 100644 index 000000000000..9e7a6127573f --- /dev/null +++ b/coverage/ves/TD_ProductDistribution.cpp.gcov.html @@ -0,0 +1,302 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_ProductDistribution.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_ProductDistribution.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:487663.2 %
Date:2024-04-19 12:12:35Functions:41040.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "TargetDistribution.h"
+      24             : #include "VesTools.h"
+      25             : 
+      26             : #include "core/ActionRegister.h"
+      27             : #include "core/ActionSet.h"
+      28             : #include "core/PlumedMain.h"
+      29             : #include "tools/Grid.h"
+      30             : 
+      31             : namespace PLMD {
+      32             : namespace ves {
+      33             : 
+      34             : //+PLUMEDOC VES_TARGETDIST TD_PRODUCT_DISTRIBUTION
+      35             : /*
+      36             : Target distribution given by a separable product of one-dimensional distributions (static or dynamic).
+      37             : 
+      38             : Employ a target distribution that is a separable product
+      39             : of one-dimensional distributions, defined as
+      40             : \f[
+      41             : p(\mathbf{s}) =
+      42             : \prod_{k}^{d} p_{k}(s_{k})
+      43             : \f]
+      44             : where \f$d\f$ is the number of arguments used and \f$p_{k}(s_{k})\f$ is the
+      45             : one-dimensional distribution corresponding to the \f$k\f$-th argument.
+      46             : 
+      47             : Note the difference between this target distribution and the one defined in
+      48             : \ref TD_PRODUCT_COMBINATION. Here we have a separable distribution given as a
+      49             : product of one-dimensional distribution \f$p_{k}(s_{k})\f$.
+      50             : 
+      51             : The labels of the one-dimensional distributions \f$p_{k}(s_{k})\f$ to be
+      52             : used in the product distribution are given in the DISTRIBUTIONS keyword.
+      53             : Note that the order of the labels is very important.
+      54             : 
+      55             : It is assumed that all the distributions to be used in the product distribution
+      56             : are normalized. If that is not the case you need to
+      57             : normalize the distributions by using the NORMALIZE keyword.
+      58             : Here it does not matter if you normalize each distribution separately
+      59             : or the overall product, it will give the same results.
+      60             : 
+      61             : The product distribution will be a dynamic target distribution if one or more
+      62             : of the distributions used is a dynamic distribution. Otherwise it will be a
+      63             : static distribution.
+      64             : 
+      65             : \par Examples
+      66             : 
+      67             : In the following example we employ a uniform distribution for
+      68             : argument 1 and a Gaussian distribution for argument 2.
+      69             : \plumedfile
+      70             : target_uniform: TD_UNIFORM
+      71             : 
+      72             : target_Gaussian: TD_GAUSSIAN CENTER1=-2.0 SIGMA1=0.5
+      73             : 
+      74             : td_pd: TD_PRODUCT_DISTRIBUTION DISTRIBUTIONS=target_uniform,target_Gaussian
+      75             : \endplumedfile
+      76             : Note that order of the labels is important, using DISTRIBUTIONS=target_Gaussian,target_uniform
+      77             : would mean that we would employ a Gaussian distribution for argument 1 and a uniform
+      78             : distribution for argument 2, which would lead to completely different results.
+      79             : 
+      80             : */
+      81             : //+ENDPLUMEDOC
+      82             : 
+      83             : class TD_ProductDistribution: public TargetDistribution {
+      84             : private:
+      85             :   std::vector<TargetDistribution*> distribution_pntrs_;
+      86             :   std::vector<Grid*> grid_pntrs_;
+      87             :   unsigned int ndist_;
+      88             :   void setupAdditionalGrids(const std::vector<Value*>&, const std::vector<std::string>&, const std::vector<std::string>&, const std::vector<unsigned int>&) override;
+      89             : public:
+      90             :   static void registerKeywords(Keywords&);
+      91             :   explicit TD_ProductDistribution(const ActionOptions& ao);
+      92             :   void updateGrid() override;
+      93             :   double getValue(const std::vector<double>&) const override;
+      94             :   //
+      95             :   void linkVesBias(VesBias*) override;
+      96             :   void linkAction(Action*) override;
+      97             :   void linkBiasGrid(Grid*) override;
+      98             :   void linkBiasWithoutCutoffGrid(Grid*) override;
+      99             :   void linkFesGrid(Grid*) override;
+     100             : };
+     101             : 
+     102             : 
+     103             : PLUMED_REGISTER_ACTION(TD_ProductDistribution,"TD_PRODUCT_DISTRIBUTION")
+     104             : 
+     105             : 
+     106          17 : void TD_ProductDistribution::registerKeywords(Keywords& keys) {
+     107          17 :   TargetDistribution::registerKeywords(keys);
+     108          34 :   keys.add("compulsory","DISTRIBUTIONS","Labels of the one-dimensional target distribution actions for each argument to be used in the product distribution. Note that order of the labels is important.");
+     109          17 :   keys.use("WELLTEMPERED_FACTOR");
+     110          17 :   keys.use("SHIFT_TO_ZERO");
+     111          17 :   keys.use("NORMALIZE");
+     112          17 : }
+     113             : 
+     114             : 
+     115          15 : TD_ProductDistribution::TD_ProductDistribution(const ActionOptions& ao):
+     116             :   PLUMED_VES_TARGETDISTRIBUTION_INIT(ao),
+     117          30 :   distribution_pntrs_(0),
+     118          15 :   grid_pntrs_(0),
+     119          30 :   ndist_(0)
+     120             : {
+     121             :   std::vector<std::string> targetdist_labels;
+     122          15 :   parseVector("DISTRIBUTIONS",targetdist_labels);
+     123             : 
+     124          15 :   std::string error_msg = "";
+     125          30 :   distribution_pntrs_ = VesTools::getPointersFromLabels<TargetDistribution*>(targetdist_labels,plumed.getActionSet(),error_msg);
+     126          15 :   if(error_msg.size()>0) {plumed_merror("Error in keyword DISTRIBUTIONS of "+getName()+": "+error_msg);}
+     127             : 
+     128          45 :   for(unsigned int i=0; i<distribution_pntrs_.size(); i++) {
+     129          30 :     if(distribution_pntrs_[i]->isDynamic()) {setDynamic();}
+     130          30 :     if(distribution_pntrs_[i]->fesGridNeeded()) {setFesGridNeeded();}
+     131          30 :     if(distribution_pntrs_[i]->biasGridNeeded()) {setBiasGridNeeded();}
+     132             :   }
+     133             : 
+     134          15 :   ndist_ = distribution_pntrs_.size();
+     135          15 :   grid_pntrs_.assign(ndist_,NULL);
+     136          15 :   setDimension(ndist_);
+     137             : 
+     138          15 :   checkRead();
+     139          15 : }
+     140             : 
+     141             : 
+     142           0 : double TD_ProductDistribution::getValue(const std::vector<double>& argument) const {
+     143           0 :   plumed_merror("getValue not implemented for TD_ProductDistribution");
+     144             :   return 0.0;
+     145             : }
+     146             : 
+     147             : 
+     148          15 : void TD_ProductDistribution::setupAdditionalGrids(const std::vector<Value*>& arguments, const std::vector<std::string>& min, const std::vector<std::string>& max, const std::vector<unsigned int>& nbins) {
+     149          45 :   for(unsigned int i=0; i<ndist_; i++) {
+     150          30 :     std::vector<Value*> arg1d(1);
+     151          30 :     std::vector<std::string> min1d(1);
+     152          30 :     std::vector<std::string> max1d(1);
+     153          30 :     std::vector<unsigned int> nbins1d(1);
+     154          30 :     arg1d[0]=arguments[i];
+     155             :     min1d[0]=min[i];
+     156             :     max1d[0]=max[i];
+     157          30 :     nbins1d[0]=nbins[i];
+     158          30 :     distribution_pntrs_[i]->setupGrids(arg1d,min1d,max1d,nbins1d);
+     159          30 :     grid_pntrs_[i]=distribution_pntrs_[i]->getTargetDistGridPntr();
+     160          30 :     if(distribution_pntrs_[i]->getDimension()!=1 || grid_pntrs_[i]->getDimension()!=1) {
+     161           0 :       plumed_merror(getName() + ": all target distributions must be one dimensional");
+     162             :     }
+     163          30 :   }
+     164          15 : }
+     165             : 
+     166             : 
+     167          15 : void TD_ProductDistribution::updateGrid() {
+     168          45 :   for(unsigned int i=0; i<ndist_; i++) {
+     169          30 :     distribution_pntrs_[i]->updateTargetDist();
+     170             :   }
+     171      153030 :   for(Grid::index_t l=0; l<targetDistGrid().getSize(); l++) {
+     172      153015 :     std::vector<unsigned int> indices = targetDistGrid().getIndices(l);
+     173             :     double value = 1.0;
+     174      459045 :     for(unsigned int i=0; i<ndist_; i++) {
+     175      306030 :       value *= grid_pntrs_[i]->getValue(indices[i]);
+     176             :     }
+     177      153015 :     targetDistGrid().setValue(l,value);
+     178      153015 :     logTargetDistGrid().setValue(l,-std::log(value));
+     179             :   }
+     180          15 :   logTargetDistGrid().setMinToZero();
+     181          15 : }
+     182             : 
+     183             : 
+     184           0 : void TD_ProductDistribution::linkVesBias(VesBias* vesbias_pntr_in) {
+     185           0 :   TargetDistribution::linkVesBias(vesbias_pntr_in);
+     186           0 :   for(unsigned int i=0; i<ndist_; i++) {
+     187           0 :     distribution_pntrs_[i]->linkVesBias(vesbias_pntr_in);
+     188             :   }
+     189           0 : }
+     190             : 
+     191             : 
+     192           0 : void TD_ProductDistribution::linkAction(Action* action_pntr_in) {
+     193           0 :   TargetDistribution::linkAction(action_pntr_in);
+     194           0 :   for(unsigned int i=0; i<ndist_; i++) {
+     195           0 :     distribution_pntrs_[i]->linkAction(action_pntr_in);
+     196             :   }
+     197           0 : }
+     198             : 
+     199             : 
+     200           0 : void TD_ProductDistribution::linkBiasGrid(Grid* bias_grid_pntr_in) {
+     201           0 :   TargetDistribution::linkBiasGrid(bias_grid_pntr_in);
+     202           0 :   for(unsigned int i=0; i<ndist_; i++) {
+     203           0 :     distribution_pntrs_[i]->linkBiasGrid(bias_grid_pntr_in);
+     204             :   }
+     205           0 : }
+     206             : 
+     207             : 
+     208           0 : void TD_ProductDistribution::linkBiasWithoutCutoffGrid(Grid* bias_withoutcutoff_grid_pntr_in) {
+     209           0 :   TargetDistribution::linkBiasWithoutCutoffGrid(bias_withoutcutoff_grid_pntr_in);
+     210           0 :   for(unsigned int i=0; i<ndist_; i++) {
+     211           0 :     distribution_pntrs_[i]->linkBiasWithoutCutoffGrid(bias_withoutcutoff_grid_pntr_in);
+     212             :   }
+     213           0 : }
+     214             : 
+     215             : 
+     216           0 : void TD_ProductDistribution::linkFesGrid(Grid* fes_grid_pntr_in) {
+     217           0 :   TargetDistribution::linkFesGrid(fes_grid_pntr_in);
+     218           0 :   for(unsigned int i=0; i<ndist_; i++) {
+     219           0 :     distribution_pntrs_[i]->linkFesGrid(fes_grid_pntr_in);
+     220             :   }
+     221           0 : }
+     222             : 
+     223             : 
+     224             : }
+     225             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_Uniform.cpp.func-sort-c.html b/coverage/ves/TD_Uniform.cpp.func-sort-c.html new file mode 100644 index 000000000000..957dc02500e8 --- /dev/null +++ b/coverage/ves/TD_Uniform.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_Uniform.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_Uniform.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:545598.2 %
Date:2024-04-19 12:12:35Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves10TD_Uniform20setupAdditionalGridsERKSt6vectorIPNS_5ValueESaIS4_EERKS2_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISE_EESI_RKS2_IjSaIjEE73
_ZN4PLMD3ves10TD_UniformC2ERKNS_13ActionOptionsE73
_ZN4PLMD3ves10TD_Uniform16registerKeywordsERNS_8KeywordsE75
_ZNK4PLMD3ves10TD_Uniform8getValueERKSt6vectorIdSaIdEE118654
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_Uniform.cpp.func.html b/coverage/ves/TD_Uniform.cpp.func.html new file mode 100644 index 000000000000..85e6f8776049 --- /dev/null +++ b/coverage/ves/TD_Uniform.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_Uniform.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_Uniform.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:545598.2 %
Date:2024-04-19 12:12:35Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves10TD_Uniform16registerKeywordsERNS_8KeywordsE75
_ZN4PLMD3ves10TD_Uniform20setupAdditionalGridsERKSt6vectorIPNS_5ValueESaIS4_EERKS2_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISE_EESI_RKS2_IjSaIjEE73
_ZN4PLMD3ves10TD_UniformC2ERKNS_13ActionOptionsE73
_ZNK4PLMD3ves10TD_Uniform8getValueERKSt6vectorIdSaIdEE118654
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_Uniform.cpp.gcov.html b/coverage/ves/TD_Uniform.cpp.gcov.html new file mode 100644 index 000000000000..8798f81d2054 --- /dev/null +++ b/coverage/ves/TD_Uniform.cpp.gcov.html @@ -0,0 +1,382 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_Uniform.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_Uniform.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:545598.2 %
Date:2024-04-19 12:12:35Functions:44100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "TargetDistribution.h"
+      24             : 
+      25             : #include "core/ActionRegister.h"
+      26             : 
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace ves {
+      30             : 
+      31             : //+PLUMEDOC VES_TARGETDIST TD_UNIFORM
+      32             : /*
+      33             : Uniform target distribution (static).
+      34             : 
+      35             : Using this keyword you can define a uniform target distribution which is a
+      36             : product of one-dimensional distributions \f$p_{k}(s_{k})\f$ that are uniform
+      37             : over a given interval \f$[a_{k},b_{k}]\f$
+      38             : 
+      39             : \f[
+      40             : p_{k}(s_{k}) =
+      41             : \left \{\begin{array}{ll}
+      42             : \frac{1}{(b_{k}-a_{k})} & \mathrm{if} \ a_{k} \leq s_{k} \leq b_{k} \\
+      43             : &\\
+      44             : 0 & \mathrm{otherwise}
+      45             : \end{array}\right .
+      46             : \f]
+      47             : 
+      48             : The overall distribution is then given as
+      49             : \f[
+      50             : p(\mathbf{s}) =
+      51             : \prod^{d}_{k} p_{k}(s_{k}) =
+      52             : \left\{\begin{array}{ll}
+      53             : \prod^{d}_{k} \frac{1}{(b_{k}-a_{k})}
+      54             : & \mathrm{if} \ a_{k} \leq s_{k} \leq b_{k} \ \mathrm{for\ all}\ k \\
+      55             : \\
+      56             : 0 & \mathrm{otherwise}
+      57             : \end{array}\right.
+      58             : \f]
+      59             : The distribution is thus uniform inside a rectangular for two arguments
+      60             : and a cube for a three arguments.
+      61             : 
+      62             : The limits of the intervals \f$ a_{k}\f$ and \f$ b_{k}\f$ are given
+      63             : with the MINIMA and MAXIMA keywords, respectively. If one or both of
+      64             : these keywords are missing the code should automatically detect the limits.
+      65             : 
+      66             : 
+      67             : It is also possible to use one-dimensional distributions
+      68             : that go smoothly to zero at the boundaries.
+      69             : This is done by employing a function with
+      70             : Gaussian switching functions at the boundaries \f$a_{k}\f$ and \f$b_{k}\f$
+      71             : \f[
+      72             : f_{k}(s_{k}) =
+      73             : \begin{cases}
+      74             : \exp\left(-\frac{(s_{k}-a_{k})^2}{2 \sigma^2_{a,k}}\right)
+      75             : & \mathrm{if}\, s_{k} < a_{k} \\
+      76             : \\
+      77             : 1 & \mathrm{if}\, a_{k} \leq s_{k} \leq b_{k} \\
+      78             : \\
+      79             : \exp\left(-\frac{(s_{k}-b_{k})^2}{2 \sigma^2_{b,k}}\right)
+      80             : & \mathrm{if}\, s_{k} > b_{k}
+      81             : \end{cases}
+      82             : \f]
+      83             : where the standard deviation parameters \f$\sigma_{a,k}\f$
+      84             : and \f$\sigma_{b,k}\f$ determine how quickly the switching functions
+      85             : goes to zero.
+      86             : The overall distribution is then normalized
+      87             : \f[
+      88             : p(\mathbf{s}) =
+      89             : \prod^{d}_{k} p_{k}(s_{k}) =
+      90             : \prod^{d}_{k} \frac{f(s_{k})}{\int d s_{k} \, f(s_{k})}
+      91             : \f]
+      92             : To use this option you need to provide the standard deviation
+      93             : parameters \f$\sigma_{a,k}\f$ and \f$\sigma_{b,k}\f$ by using the
+      94             : SIGMA_MINIMA and SIGMA_MAXIMA keywords, respectively. Giving a value of
+      95             : 0.0 means that the boundary is sharp, which is the default behavior.
+      96             : 
+      97             : 
+      98             : 
+      99             : 
+     100             : 
+     101             : 
+     102             : \par Examples
+     103             : 
+     104             : If one or both of the MINIMA or MAXIMA keywords are missing
+     105             : the code should automatically detect the limits not given.
+     106             : Therefore, if we consider a target distribution that is
+     107             : defined over an interval from 0.0 to 10.0 for the first
+     108             : argument and from 0.2 to 1.0 for the second argument are
+     109             : the following example
+     110             : \plumedfile
+     111             : td: TD_UNIFORM
+     112             : \endplumedfile
+     113             : 
+     114             : is equivalent to this one
+     115             : 
+     116             : \plumedfile
+     117             : TD_UNIFORM ...
+     118             :  MINIMA=0.0,0.2
+     119             :  MAXIMA=10.0,1.0
+     120             :  LABEL=td
+     121             :  ... TD_UNIFORM
+     122             : \endplumedfile
+     123             : 
+     124             : and this one
+     125             : 
+     126             : \plumedfile
+     127             : td: TD_UNIFORM  MAXIMA=10.0,1.0
+     128             : \endplumedfile
+     129             : 
+     130             : and also this one
+     131             : 
+     132             : \plumedfile
+     133             : td: TD_UNIFORM MINIMA=0.0,0,2
+     134             : \endplumedfile
+     135             : 
+     136             : 
+     137             : We can also define a target distribution that goes smoothly to zero
+     138             : at the boundaries of the uniform distribution. In the following
+     139             : we consider an interval of 0 to 10 for the target distribution.
+     140             : The following input would result in a target distribution that
+     141             : would be uniform from 2 to 7 and then smoothly go to zero from
+     142             : 2 to 0 and from 7 to 10.
+     143             : \plumedfile
+     144             : TD_UNIFORM ...
+     145             :  MINIMA=2.0
+     146             :  MAXIMA=+7.0
+     147             :  SIGMA_MINIMA=0.5
+     148             :  SIGMA_MAXIMA=1.0
+     149             :  LABEL=td
+     150             : ... TD_UNIFORM
+     151             : \endplumedfile
+     152             : It is also possible to employ a smooth switching function for just one
+     153             : of the boundaries as shown here where the target distribution
+     154             : would be uniform from 0 to 7 and then smoothly go to zero from 7 to 10.
+     155             : \plumedfile
+     156             : TD_UNIFORM ...
+     157             :  MAXIMA=+7.0
+     158             :  SIGMA_MAXIMA=1.0
+     159             :  LABEL=td
+     160             : ... TD_UNIFORM
+     161             : \endplumedfile
+     162             : Furthermore, it is possible to employ a sharp boundary by
+     163             : using
+     164             : \plumedfile
+     165             : TD_UNIFORM ...
+     166             :  MAXIMA=+7.0
+     167             :  SIGMA_MAXIMA=0.0
+     168             :  LABEL=td
+     169             : ... TD_UNIFORM
+     170             : \endplumedfile
+     171             : or
+     172             : \plumedfile
+     173             : td: TD_UNIFORM MAXIMA=+7.0
+     174             : \endplumedfile
+     175             : 
+     176             : 
+     177             : */
+     178             : //+ENDPLUMEDOC
+     179             : 
+     180             : class TD_Uniform : public TargetDistribution {
+     181             :   std::vector<double> minima_;
+     182             :   std::vector<double> maxima_;
+     183             :   std::vector<double> sigma_min_;
+     184             :   std::vector<double> sigma_max_;
+     185             :   double GaussianSwitchingFunc(const double, const double, const double) const;
+     186             :   void setupAdditionalGrids(const std::vector<Value*>&, const std::vector<std::string>&, const std::vector<std::string>&, const std::vector<unsigned int>&) override;
+     187             : public:
+     188             :   static void registerKeywords( Keywords&);
+     189             :   explicit TD_Uniform(const ActionOptions& ao);
+     190             :   double getValue(const std::vector<double>&) const override;
+     191             : };
+     192             : 
+     193             : 
+     194             : PLUMED_REGISTER_ACTION(TD_Uniform,"TD_UNIFORM")
+     195             : 
+     196             : 
+     197          75 : void TD_Uniform::registerKeywords(Keywords& keys) {
+     198          75 :   TargetDistribution::registerKeywords(keys);
+     199         150 :   keys.add("optional","MINIMA","The minimum of the intervals where the target distribution is taken as uniform. You should give one value for each argument.");
+     200         150 :   keys.add("optional","MAXIMA","The maximum of the intervals where the target distribution is taken as uniform. You should give one value for each argument.");
+     201         150 :   keys.add("optional","SIGMA_MINIMA","The standard deviation parameters of the Gaussian switching functions for the minima of the intervals. You should give one value for each argument. Value of 0.0 means that switch is done without a smooth switching function, this is the default behavior.");
+     202         150 :   keys.add("optional","SIGMA_MAXIMA","The standard deviation parameters of the Gaussian switching functions for the maximum of the intervals. You should give one value for each argument. Value of 0.0 means that switch is done without a smooth switching function, this is the default behavior.");
+     203          75 : }
+     204             : 
+     205             : 
+     206          73 : TD_Uniform::TD_Uniform(const ActionOptions& ao):
+     207             :   PLUMED_VES_TARGETDISTRIBUTION_INIT(ao),
+     208         146 :   minima_(0),
+     209          73 :   maxima_(0),
+     210          73 :   sigma_min_(0),
+     211         146 :   sigma_max_(0)
+     212             : {
+     213          73 :   parseVector("MINIMA",minima_);
+     214          73 :   parseVector("MAXIMA",maxima_);
+     215             : 
+     216          73 :   parseVector("SIGMA_MINIMA",sigma_min_);
+     217         146 :   parseVector("SIGMA_MAXIMA",sigma_max_);
+     218          73 :   if(minima_.size()==0 && sigma_min_.size()>0) {plumed_merror(getName()+": you cannot give SIGMA_MINIMA if MINIMA is not given");}
+     219          73 :   if(maxima_.size()==0 && sigma_max_.size()>0) {plumed_merror(getName()+": you cannot give SIGMA_MAXIMA if MAXIMA is not given");}
+     220             : 
+     221          73 :   if(minima_.size()>0 && maxima_.size()>0) {
+     222             :     // both MINIMA and MAXIMA given, do all checks
+     223          58 :     if(minima_.size()!=maxima_.size()) {plumed_merror(getName()+": MINIMA and MAXIMA do not have the same number of values.");}
+     224          58 :     setDimension(minima_.size());
+     225         122 :     for(unsigned int k=0; k<getDimension(); k++) {
+     226          64 :       if(minima_[k]>maxima_[k]) {
+     227           0 :         plumed_merror(getName()+": error in MINIMA and MAXIMA keywords, one of the MINIMA values is larger than the corresponding MAXIMA values");
+     228             :       }
+     229             :     }
+     230             :   }
+     231          15 :   else if(minima_.size()>0 && maxima_.size()==0) {
+     232             :     // only MINIMA given, MAXIMA assigned later on.
+     233           1 :     setDimension(minima_.size());
+     234             :   }
+     235          14 :   else if(maxima_.size()>0 && minima_.size()==0) {
+     236             :     // only MAXIMA given, MINIMA assigned later on.
+     237           1 :     setDimension(maxima_.size());
+     238             :   }
+     239          13 :   else if(maxima_.size()==0 && minima_.size()==0) {
+     240             :     // neither MAXIMA nor MINIMA givenm, both assigned later on.
+     241          13 :     setDimension(0);
+     242             :   }
+     243             : 
+     244          73 :   if(sigma_min_.size()==0) {sigma_min_.assign(getDimension(),0.0);}
+     245          73 :   if(sigma_max_.size()==0) {sigma_max_.assign(getDimension(),0.0);}
+     246          73 :   if(sigma_min_.size()!=getDimension()) {plumed_merror(getName()+": SIGMA_MINIMA has the wrong number of values");}
+     247          73 :   if(sigma_max_.size()!=getDimension()) {plumed_merror(getName()+": SIGMA_MAXIMA has the wrong number of values");}
+     248             :   //
+     249             :   setForcedNormalization();
+     250          73 :   checkRead();
+     251          73 : }
+     252             : 
+     253             : 
+     254          73 : void TD_Uniform::setupAdditionalGrids(const std::vector<Value*>& arguments, const std::vector<std::string>& min, const std::vector<std::string>& max, const std::vector<unsigned int>& nbins) {
+     255             : 
+     256          73 :   if(minima_.size()==0) {
+     257          14 :     minima_.assign(getDimension(),0.0);
+     258          33 :     for(unsigned int k=0; k<getDimension(); k++) {Tools::convert(min[k],minima_[k]);}
+     259             :   }
+     260             : 
+     261          73 :   if(maxima_.size()==0) {
+     262          14 :     maxima_.assign(getDimension(),0.0);
+     263          33 :     for(unsigned int k=0; k<getDimension(); k++) {Tools::convert(max[k],maxima_[k]);}
+     264             :   }
+     265             : 
+     266          73 : }
+     267             : 
+     268             : 
+     269      118654 : double TD_Uniform::getValue(const std::vector<double>& argument) const {
+     270             :   //
+     271             :   double value = 1.0;
+     272      338719 :   for(unsigned int k=0; k<getDimension(); k++) {
+     273             :     double tmp;
+     274      220065 :     if(argument[k] < minima_[k]) {
+     275       15379 :       tmp = GaussianSwitchingFunc(argument[k],minima_[k],sigma_min_[k]);
+     276             :     }
+     277      204686 :     else if(argument[k] > maxima_[k]) {
+     278       15566 :       tmp = GaussianSwitchingFunc(argument[k],maxima_[k],sigma_max_[k]);
+     279             :     }
+     280             :     else {
+     281             :       tmp = 1.0;
+     282             :     }
+     283      220065 :     value *= tmp;
+     284             :   }
+     285      118654 :   return value;
+     286             : }
+     287             : 
+     288             : inline
+     289             : double TD_Uniform::GaussianSwitchingFunc(const double argument, const double center, const double sigma) const {
+     290       30945 :   if(sigma>0.0) {
+     291       23278 :     double arg=(argument-center)/sigma;
+     292       23278 :     return exp(-0.5*arg*arg);
+     293             :   }
+     294             :   else {
+     295             :     return 0.0;
+     296             :   }
+     297             : }
+     298             : 
+     299             : 
+     300             : 
+     301             : 
+     302             : 
+     303             : 
+     304             : }
+     305             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_VonMises.cpp.func-sort-c.html b/coverage/ves/TD_VonMises.cpp.func-sort-c.html new file mode 100644 index 000000000000..e032a37c4962 --- /dev/null +++ b/coverage/ves/TD_VonMises.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_VonMises.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_VonMises.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:747598.7 %
Date:2024-04-19 12:12:35Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves11TD_VonMisesC2ERKNS_13ActionOptionsE9
_ZN4PLMD3ves11TD_VonMises16registerKeywordsERNS_8KeywordsE11
_ZNK4PLMD3ves11TD_VonMises16getNormalizationEdd19
_ZNK4PLMD3ves11TD_VonMises8getValueERKSt6vectorIdSaIdEE31100
_ZNK4PLMD3ves11TD_VonMises16VonMisesDiagonalERKSt6vectorIdSaIdEES6_S6_S6_S6_80319
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_VonMises.cpp.func.html b/coverage/ves/TD_VonMises.cpp.func.html new file mode 100644 index 000000000000..d110caca2d28 --- /dev/null +++ b/coverage/ves/TD_VonMises.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_VonMises.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_VonMises.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:747598.7 %
Date:2024-04-19 12:12:35Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves11TD_VonMises16registerKeywordsERNS_8KeywordsE11
_ZN4PLMD3ves11TD_VonMisesC2ERKNS_13ActionOptionsE9
_ZNK4PLMD3ves11TD_VonMises16VonMisesDiagonalERKSt6vectorIdSaIdEES6_S6_S6_S6_80319
_ZNK4PLMD3ves11TD_VonMises16getNormalizationEdd19
_ZNK4PLMD3ves11TD_VonMises8getValueERKSt6vectorIdSaIdEE31100
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_VonMises.cpp.gcov.html b/coverage/ves/TD_VonMises.cpp.gcov.html new file mode 100644 index 000000000000..6f46b6d55292 --- /dev/null +++ b/coverage/ves/TD_VonMises.cpp.gcov.html @@ -0,0 +1,316 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_VonMises.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_VonMises.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:747598.7 %
Date:2024-04-19 12:12:35Functions:55100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "TargetDistribution.h"
+      24             : #include "GridIntegrationWeights.h"
+      25             : 
+      26             : #include "core/ActionRegister.h"
+      27             : #include "tools/Tools.h"
+      28             : 
+      29             : #include <iostream>
+      30             : 
+      31             : 
+      32             : 
+      33             : namespace PLMD {
+      34             : namespace ves {
+      35             : 
+      36             : //+PLUMEDOC VES_TARGETDIST TD_VONMISES
+      37             : /*
+      38             : Target distribution given by a sum of Von Mises distributions (static).
+      39             : 
+      40             : Employ a target distribution that is given by a sum where each
+      41             : term is a product of one-dimensional
+      42             : [Von Mises distributions](https://en.wikipedia.org/wiki/Von_Mises_distribution),
+      43             : \f[
+      44             : p(\mathbf{s}) = \sum_{i} \, w_{i}
+      45             : \prod_{k}^{d}
+      46             : \frac{\exp\left(\kappa_{k,i} \, \cos (s_{k}-\mu_{k,i}) \right)}
+      47             : {2\pi I_{0}(\kappa_{k,i})}
+      48             : \f]
+      49             : where \f$(\mu_{1,i},\mu_{2,i},\ldots,\mu_{d,i})\f$
+      50             : are the centers of the distributions,
+      51             : \f$(\kappa_{1,i},\kappa_{2,i},\ldots,\kappa_{d,i})\f$
+      52             : are parameters that determine the extend of each distribution,
+      53             : and \f$I_{0}(x)\f$ is the modified Bessel function of order 0.
+      54             : The weights \f$w_{i}\f$ are normalized to 1, \f$\sum_{i}w_{i}=1\f$.
+      55             : 
+      56             : The Von Mises distribution is defined for periodic variables with a
+      57             : periodicity of \f$2\pi\f$ and is analogous to the Gaussian distribution.
+      58             : The parameter \f$ \sqrt{1/\kappa}\f$ is comparable to the standard deviation
+      59             : \f$\sigma\f$ for the Gaussian distribution.
+      60             : 
+      61             : To use this target distribution you need to give the centers
+      62             : \f$(\mu_{1,i},\mu_{2,i},\ldots,\mu_{d,i})\f$ by
+      63             : using the numbered CENTER keywords and the "standard deviations"
+      64             : \f$(\sqrt{1/\kappa_{1,i}},\sqrt{1/\kappa_{2,i}},\ldots,\sqrt{1/\kappa_{d,i}})\f$ using the numbered SIGMA keywords.
+      65             : 
+      66             : 
+      67             : \par Examples
+      68             : 
+      69             : Sum of two Von Mises distribution in one dimension that have equal weights
+      70             : as no weights are given.
+      71             : \plumedfile
+      72             : TD_VONMISES ...
+      73             :  CENTER1=+2.0 SIGMA1=0.6
+      74             :  CENTER2=-2.0 SIGMA2=0.7
+      75             :  LABEL=td
+      76             : ... TD_VONMISES
+      77             : \endplumedfile
+      78             : 
+      79             : Sum of two Von Mises distribution in two dimensions that have different weights.
+      80             : Note that the weights are automatically normalized to 1 such that
+      81             : specifying WEIGHTS=1.0,2.0 is equal to specifying WEIGHTS=0.33333,0.66667.
+      82             : \plumedfile
+      83             : TD_VONMISES ...
+      84             :  CENTER1=+2.0,+2.0 SIGMA1=0.6,0.7
+      85             :  CENTER2=-2.0,+2.0 SIGMA2=0.7,0.6
+      86             :  WEIGHTS=1.0,2.0
+      87             :  LABEL=td
+      88             : ... TD_VONMISES
+      89             : \endplumedfile
+      90             : 
+      91             : */
+      92             : //+ENDPLUMEDOC
+      93             : 
+      94             : class TD_VonMises: public TargetDistribution {
+      95             :   // properties of the Gaussians
+      96             :   std::vector< std::vector<double> > sigmas_;
+      97             :   std::vector< std::vector<double> > kappas_;
+      98             :   std::vector< std::vector<double> > centers_;
+      99             :   std::vector< std::vector<double> > normalization_;
+     100             :   std::vector<double> weights_;
+     101             :   std::vector<double> periods_;
+     102             :   unsigned int ncenters_;
+     103             :   double VonMisesDiagonal(const std::vector<double>&, const std::vector<double>&, const std::vector<double>&, const std::vector<double>&, const std::vector<double>&) const;
+     104             :   double getNormalization(const double, const double) const;
+     105             : public:
+     106             :   static void registerKeywords(Keywords&);
+     107             :   explicit TD_VonMises(const ActionOptions& ao);
+     108             :   double getValue(const std::vector<double>&) const override;
+     109             : };
+     110             : 
+     111             : 
+     112             : PLUMED_REGISTER_ACTION(TD_VonMises,"TD_VONMISES")
+     113             : 
+     114             : 
+     115          11 : void TD_VonMises::registerKeywords(Keywords& keys) {
+     116          11 :   TargetDistribution::registerKeywords(keys);
+     117          22 :   keys.add("numbered","CENTER","The centers of the Von Mises distributions.");
+     118          22 :   keys.add("numbered","SIGMA","The standard deviations of the Von Mises distributions.");
+     119          22 :   keys.add("optional","WEIGHTS","The weights of the Von Mises distributions. Have to be as many as the number of centers given with the numbered CENTER keywords. If no weights are given the distributions are weighted equally. The weights are automatically normalized to 1.");
+     120          22 :   keys.add("hidden","PERIODS","The periods for each of the dimensions. By default they are 2*pi for each dimension.");
+     121          11 :   keys.use("WELLTEMPERED_FACTOR");
+     122          11 :   keys.use("SHIFT_TO_ZERO");
+     123             :   //keys.use("NORMALIZE");
+     124          11 : }
+     125             : 
+     126             : 
+     127           9 : TD_VonMises::TD_VonMises(const ActionOptions& ao):
+     128             :   PLUMED_VES_TARGETDISTRIBUTION_INIT(ao),
+     129          18 :   sigmas_(0),
+     130           9 :   centers_(0),
+     131           9 :   normalization_(0),
+     132           9 :   weights_(0),
+     133           9 :   periods_(0),
+     134          18 :   ncenters_(0)
+     135             : {
+     136          13 :   for(unsigned int i=1;; i++) {
+     137             :     std::vector<double> tmp_center;
+     138          44 :     if(!parseNumberedVector("CENTER",i,tmp_center) ) {break;}
+     139          13 :     centers_.push_back(tmp_center);
+     140          13 :   }
+     141          13 :   for(unsigned int i=1;; i++) {
+     142             :     std::vector<double> tmp_sigma;
+     143          44 :     if(!parseNumberedVector("SIGMA",i,tmp_sigma) ) {break;}
+     144          13 :     sigmas_.push_back(tmp_sigma);
+     145          13 :   }
+     146             :   //
+     147           9 :   plumed_massert(centers_.size()==sigmas_.size(),"there has to be an equal amount of CENTER and SIGMA keywords");
+     148           9 :   if(centers_.size()==0) {
+     149           0 :     plumed_merror(getName()+": CENTER and SIGMA keywords seem to be missing. Note that numbered keywords start at CENTER1 and SIGMA1.");
+     150             :   }
+     151             :   //
+     152           9 :   setDimension(centers_[0].size());
+     153           9 :   ncenters_ = centers_.size();
+     154             :   //
+     155             :   // check centers and sigmas
+     156          22 :   for(unsigned int i=0; i<ncenters_; i++) {
+     157          13 :     if(centers_[i].size()!=getDimension()) {plumed_merror(getName()+": one of the CENTER keyword does not match the given dimension");}
+     158          13 :     if(sigmas_[i].size()!=getDimension()) {plumed_merror(getName()+": one of the SIGMA keyword does not match the given dimension");}
+     159             :   }
+     160             :   //
+     161           9 :   kappas_.resize(sigmas_.size());
+     162          22 :   for(unsigned int i=0; i<sigmas_.size(); i++) {
+     163          13 :     kappas_[i].resize(sigmas_[i].size());
+     164          32 :     for(unsigned int k=0; k<kappas_[i].size(); k++) {
+     165          19 :       kappas_[i][k] = 1.0/(sigmas_[i][k]*sigmas_[i][k]);
+     166             :     }
+     167             :   }
+     168             :   //
+     169          18 :   parseVector("WEIGHTS",weights_);
+     170           9 :   if(weights_.size()==0) {weights_.assign(centers_.size(),1.0);}
+     171           9 :   if(centers_.size()!=weights_.size()) {plumed_merror(getName() + ": there has to be as many weights given in WEIGHTS as numbered CENTER keywords");}
+     172             :   //
+     173           9 :   if(periods_.size()==0) {periods_.assign(getDimension(),2*pi);}
+     174          18 :   parseVector("PERIODS",periods_);
+     175           9 :   if(periods_.size()!=getDimension()) {plumed_merror(getName() + ": the number of values given in PERIODS does not match the dimension of the distribution");}
+     176             :   //
+     177             :   double sum_weights=0.0;
+     178          22 :   for(unsigned int i=0; i<weights_.size(); i++) {sum_weights+=weights_[i];}
+     179          22 :   for(unsigned int i=0; i<weights_.size(); i++) {weights_[i]/=sum_weights;}
+     180             :   //
+     181           9 :   normalization_.resize(ncenters_);
+     182          22 :   for(unsigned int i=0; i<ncenters_; i++) {
+     183          13 :     normalization_[i].resize(getDimension());
+     184          32 :     for(unsigned int k=0; k<getDimension(); k++) {
+     185          19 :       normalization_[i][k] = getNormalization(kappas_[i][k],periods_[k]);
+     186             :     }
+     187             :   }
+     188           9 :   checkRead();
+     189           9 : }
+     190             : 
+     191             : 
+     192       31100 : double TD_VonMises::getValue(const std::vector<double>& argument) const {
+     193             :   double value=0.0;
+     194       92400 :   for(unsigned int i=0; i<ncenters_; i++) {
+     195       61300 :     value+=weights_[i]*VonMisesDiagonal(argument, centers_[i], kappas_[i],periods_,normalization_[i]);
+     196             :   }
+     197       31100 :   return value;
+     198             : }
+     199             : 
+     200             : 
+     201       80319 : double TD_VonMises::VonMisesDiagonal(const std::vector<double>& argument, const std::vector<double>& center, const std::vector<double>& kappa, const std::vector<double>& periods, const std::vector<double>& normalization) const {
+     202             :   double value = 1.0;
+     203      220638 :   for(unsigned int k=0; k<argument.size(); k++) {
+     204      140319 :     double arg = kappa[k]*cos( ((2*pi)/periods[k])*(argument[k]-center[k]) );
+     205      140319 :     value*=normalization[k]*exp(arg);
+     206             :   }
+     207       80319 :   return value;
+     208             : }
+     209             : 
+     210             : 
+     211          19 : double TD_VonMises::getNormalization(const double kappa, const double period) const {
+     212             :   //
+     213          19 :   std::vector<double> centers(1);
+     214          19 :   centers[0] = 0.0;
+     215          19 :   std::vector<double> kappas(1);
+     216          19 :   kappas[0] = kappa;
+     217          19 :   std::vector<double> periods(1);
+     218          19 :   periods[0] = period;
+     219          19 :   std::vector<double> norm(1);
+     220          19 :   norm[0] = 1.0;
+     221             :   //
+     222             :   const unsigned int nbins = 1001;
+     223             :   std::vector<double> points;
+     224             :   std::vector<double> weights;
+     225             :   double min = 0.0;
+     226             :   double max = period;
+     227          19 :   GridIntegrationWeights::getOneDimensionalIntegrationPointsAndWeights(points,weights,nbins,min,max);
+     228             :   //
+     229             :   double sum = 0.0;
+     230       19038 :   for(unsigned int l=0; l<nbins; l++) {
+     231       19019 :     std::vector<double> arg(1); arg[0]= points[l];
+     232       19019 :     sum += weights[l] * VonMisesDiagonal(arg,centers,kappas,periods,norm);
+     233             :   }
+     234          38 :   return 1.0/sum;
+     235             : }
+     236             : 
+     237             : 
+     238             : }
+     239             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_WellTempered.cpp.func-sort-c.html b/coverage/ves/TD_WellTempered.cpp.func-sort-c.html new file mode 100644 index 000000000000..b95456162b23 --- /dev/null +++ b/coverage/ves/TD_WellTempered.cpp.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_WellTempered.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_WellTempered.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:283190.3 %
Date:2024-04-19 12:12:35Functions:4666.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves15TD_WellTemperedD2Ev0
_ZNK4PLMD3ves15TD_WellTempered8getValueERKSt6vectorIdSaIdEE0
_ZN4PLMD3ves15TD_WellTemperedC2ERKNS_13ActionOptionsE29
_ZN4PLMD3ves15TD_WellTemperedD0Ev29
_ZN4PLMD3ves15TD_WellTempered16registerKeywordsERNS_8KeywordsE31
_ZN4PLMD3ves15TD_WellTempered10updateGridEv319
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_WellTempered.cpp.func.html b/coverage/ves/TD_WellTempered.cpp.func.html new file mode 100644 index 000000000000..8668713c6cca --- /dev/null +++ b/coverage/ves/TD_WellTempered.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_WellTempered.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_WellTempered.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:283190.3 %
Date:2024-04-19 12:12:35Functions:4666.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves15TD_WellTempered10updateGridEv319
_ZN4PLMD3ves15TD_WellTempered16registerKeywordsERNS_8KeywordsE31
_ZN4PLMD3ves15TD_WellTemperedC2ERKNS_13ActionOptionsE29
_ZN4PLMD3ves15TD_WellTemperedD0Ev29
_ZN4PLMD3ves15TD_WellTemperedD2Ev0
_ZNK4PLMD3ves15TD_WellTempered8getValueERKSt6vectorIdSaIdEE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_WellTempered.cpp.gcov.html b/coverage/ves/TD_WellTempered.cpp.gcov.html new file mode 100644 index 000000000000..a3a0c8ff1f12 --- /dev/null +++ b/coverage/ves/TD_WellTempered.cpp.gcov.html @@ -0,0 +1,241 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_WellTempered.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_WellTempered.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:283190.3 %
Date:2024-04-19 12:12:35Functions:4666.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "TargetDistribution.h"
+      24             : #include "GridIntegrationWeights.h"
+      25             : 
+      26             : #include "core/ActionRegister.h"
+      27             : #include "tools/Grid.h"
+      28             : #include "core/PlumedMain.h"
+      29             : 
+      30             : 
+      31             : 
+      32             : namespace PLMD {
+      33             : namespace ves {
+      34             : 
+      35             : //+PLUMEDOC VES_TARGETDIST TD_WELLTEMPERED
+      36             : /*
+      37             : Well-tempered target distribution (dynamic).
+      38             : 
+      39             : Use as a target distribution the well-tempered distribution \cite Barducci:2008
+      40             : given by
+      41             : \f[
+      42             : p(\mathbf{s}) =
+      43             : \frac{e^{-(\beta/\gamma) F(\mathbf{s})}}
+      44             : {\int d\mathbf{s}\, e^{-(\beta/\gamma) F(\mathbf{s})}} =
+      45             : \frac{[P_{0}(\mathbf{s})]^{1/\gamma}}
+      46             : {\int d\mathbf{s}\, [P_{0}(\mathbf{s})]^{1/\gamma}}
+      47             : \f]
+      48             : where \f$\gamma\f$ is a so-called bias factor and \f$P_{0}(\mathbf{s})\f$ is the
+      49             : unbiased canonical distribution of the CVs. This target distribution thus
+      50             : corresponds to a biased ensemble where, as compared to the unbiased one,
+      51             : the probability peaks have been broaden and the fluctuations of the CVs are
+      52             : enhanced.
+      53             : The value of the bias factor \f$\gamma\f$ determines by how much the fluctuations
+      54             : are enhanced.
+      55             : 
+      56             : The well-tempered distribution can be view as sampling on
+      57             : an effective free energy surface \f$\tilde{F}(\mathbf{s}) = (1/\gamma) F(\mathbf{s})\f$
+      58             : which has largely the same metastable states as the original \f$F(\mathbf{s})\f$
+      59             : but with barriers that have been reduced by a factor of \f$\gamma\f$.
+      60             : Generally one should use a value of \f$\gamma\f$ that results in
+      61             : effective barriers on the order of few \f$k_{\mathrm{B}}T\f$
+      62             : such that thermal fluctuations can easily induce transitions
+      63             : between different metastable states.
+      64             : 
+      65             : At convergence the relationship between the bias potential and the free
+      66             : energy surface is given by
+      67             : \f[
+      68             : F(\mathbf{s}) = - \left(\frac{1}{1-\gamma^{-1}} \right) V(\mathbf{s})
+      69             : \f]
+      70             : 
+      71             : This target distribution depends directly on the free energy surface
+      72             : \f$F(\mathbf{s})\f$ which is quantity that we do not know a-priori and
+      73             : want to obtain. Therefore, this target distribution
+      74             : is iteratively updated \cite Valsson-JCTC-2015 according to
+      75             : \f[
+      76             : p^{(m+1)}(\mathbf{s}) =
+      77             : \frac{e^{-(\beta/\gamma) F^{(m+1)}(\mathbf{s})}}
+      78             : {\int d\mathbf{s}\, e^{-(\beta/\gamma) F^{(m+1)}(\mathbf{s})}}
+      79             : \f]
+      80             : where \f$F^{(m+1)}(\mathbf{s})\f$ is the current best estimate of the
+      81             : free energy surface obtained according to
+      82             : \f[
+      83             : F^{(m+1)}(\mathbf{s}) =
+      84             : - V^{(m+1)}(\mathbf{s}) - \frac{1}{\beta} \log p^{(m)}(\mathbf{s}) =
+      85             : - V^{(m+1)}(\mathbf{s}) + \frac{1}{\gamma} F^{(m)}(\mathbf{s})
+      86             : \f]
+      87             : The frequency of performing this update needs to be set in the
+      88             : optimizer used in the calculation. Normally it is sufficient
+      89             : to do it every 100-1000 bias update iterations.
+      90             : 
+      91             : \par Examples
+      92             : 
+      93             : Employ a well-tempered target distribution with a bias factor of 10
+      94             : \plumedfile
+      95             : td_welltemp: TD_WELLTEMPERED BIASFACTOR=10
+      96             : \endplumedfile
+      97             : 
+      98             : */
+      99             : //+ENDPLUMEDOC
+     100             : 
+     101             : class TD_WellTempered: public TargetDistribution {
+     102             : private:
+     103             :   double bias_factor_;
+     104             : public:
+     105             :   static void registerKeywords(Keywords&);
+     106             :   explicit TD_WellTempered(const ActionOptions& ao);
+     107             :   void updateGrid() override;
+     108             :   double getValue(const std::vector<double>&) const override;
+     109          29 :   ~TD_WellTempered() {}
+     110             : };
+     111             : 
+     112             : 
+     113             : PLUMED_REGISTER_ACTION(TD_WellTempered,"TD_WELLTEMPERED")
+     114             : 
+     115             : 
+     116          31 : void TD_WellTempered::registerKeywords(Keywords& keys) {
+     117          31 :   TargetDistribution::registerKeywords(keys);
+     118          62 :   keys.add("compulsory","BIASFACTOR","The bias factor used for the well-tempered distribution.");
+     119          31 : }
+     120             : 
+     121             : 
+     122          29 : TD_WellTempered::TD_WellTempered(const ActionOptions& ao):
+     123             :   PLUMED_VES_TARGETDISTRIBUTION_INIT(ao),
+     124          29 :   bias_factor_(0.0)
+     125             : {
+     126          29 :   log.printf("  Well-tempered target distribution, see and cite ");
+     127          58 :   log << plumed.cite("Valsson and Parrinello, J. Chem. Theory Comput. 11, 1996-2002 (2015)");
+     128          58 :   log << plumed.cite("Barducci, Bussi, and Parrinello, Phys. Rev. Lett. 100, 020603 (2008)");
+     129          29 :   log.printf("\n");
+     130          29 :   parse("BIASFACTOR",bias_factor_);
+     131          29 :   if(bias_factor_<=1.0) {
+     132           0 :     plumed_merror("TD_WELLTEMPERED target distribution: the value of the bias factor doesn't make sense, it should be larger than 1.0");
+     133             :   }
+     134             :   setDynamic();
+     135             :   setFesGridNeeded();
+     136          29 :   checkRead();
+     137          29 : }
+     138             : 
+     139             : 
+     140           0 : double TD_WellTempered::getValue(const std::vector<double>& argument) const {
+     141           0 :   plumed_merror("getValue not implemented for TD_WellTempered");
+     142             :   return 0.0;
+     143             : }
+     144             : 
+     145             : 
+     146         319 : void TD_WellTempered::updateGrid() {
+     147         319 :   double beta_prime = getBeta()/bias_factor_;
+     148         319 :   plumed_massert(getFesGridPntr()!=NULL,"the FES grid has to be linked to use TD_WellTempered!");
+     149         638 :   std::vector<double> integration_weights = GridIntegrationWeights::getIntegrationWeights(getTargetDistGridPntr());
+     150             :   double norm = 0.0;
+     151     1127896 :   for(Grid::index_t l=0; l<targetDistGrid().getSize(); l++) {
+     152     1127577 :     double value = beta_prime * getFesGridPntr()->getValue(l);
+     153     1127577 :     logTargetDistGrid().setValue(l,value);
+     154     1127577 :     value = exp(-value);
+     155     1127577 :     norm += integration_weights[l]*value;
+     156     1127577 :     targetDistGrid().setValue(l,value);
+     157             :   }
+     158         319 :   targetDistGrid().scaleAllValuesAndDerivatives(1.0/norm);
+     159         319 :   logTargetDistGrid().setMinToZero();
+     160         319 : }
+     161             : 
+     162             : 
+     163             : }
+     164             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TargetDistModifer.h.func-sort-c.html b/coverage/ves/TargetDistModifer.h.func-sort-c.html new file mode 100644 index 000000000000..5b9624044057 --- /dev/null +++ b/coverage/ves/TargetDistModifer.h.func-sort-c.html @@ -0,0 +1,77 @@ + + + + + + + + LCOV - plumed test coverage - ves/TargetDistModifer.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TargetDistModifer.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:33100.0 %
Date:2024-04-19 12:12:35Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD3ves19WellTemperedModifer25getModifedTargetDistValueEdRKSt6vectorIdSaIdEE21206
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TargetDistModifer.h.func.html b/coverage/ves/TargetDistModifer.h.func.html new file mode 100644 index 000000000000..084ec0975acb --- /dev/null +++ b/coverage/ves/TargetDistModifer.h.func.html @@ -0,0 +1,77 @@ + + + + + + + + LCOV - plumed test coverage - ves/TargetDistModifer.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TargetDistModifer.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:33100.0 %
Date:2024-04-19 12:12:35Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD3ves19WellTemperedModifer25getModifedTargetDistValueEdRKSt6vectorIdSaIdEE21206
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TargetDistModifer.h.gcov.html b/coverage/ves/TargetDistModifer.h.gcov.html new file mode 100644 index 000000000000..ccfb3560527f --- /dev/null +++ b/coverage/ves/TargetDistModifer.h.gcov.html @@ -0,0 +1,130 @@ + + + + + + + + LCOV - plumed test coverage - ves/TargetDistModifer.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TargetDistModifer.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:33100.0 %
Date:2024-04-19 12:12:35Functions:11100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_ves_TargetDistModifer_h
+      23             : #define __PLUMED_ves_TargetDistModifer_h
+      24             : 
+      25             : #include <vector>
+      26             : #include <cmath>
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace ves {
+      30             : 
+      31             : class TargetDistModifer {
+      32             : public:
+      33             :   virtual double getModifedTargetDistValue(const double targetdist_value, const std::vector<double>& cv_values) const = 0;
+      34             :   virtual ~TargetDistModifer() {}
+      35             : };
+      36             : 
+      37             : class WellTemperedModifer:public TargetDistModifer {
+      38             : private:
+      39             :   double invbiasf_;
+      40             : public:
+      41           6 :   explicit WellTemperedModifer(double biasfactor):invbiasf_(1.0/biasfactor) {}
+      42       21206 :   double getModifedTargetDistValue(const double targetdist_value, const std::vector<double>& cv_values) const override {
+      43       21206 :     return std::pow(targetdist_value,invbiasf_);
+      44             :   }
+      45             : };
+      46             : 
+      47             : 
+      48             : 
+      49             : 
+      50             : }
+      51             : }
+      52             : 
+      53             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TargetDistribution.cpp.func-sort-c.html b/coverage/ves/TargetDistribution.cpp.func-sort-c.html new file mode 100644 index 000000000000..0c5cbff8aa7b --- /dev/null +++ b/coverage/ves/TargetDistribution.cpp.func-sort-c.html @@ -0,0 +1,177 @@ + + + + + + + + LCOV - plumed test coverage - ves/TargetDistribution.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TargetDistribution.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:18921787.1 %
Date:2024-04-19 12:12:35Functions:222684.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves18TargetDistribution10linkActionEPNS_6ActionE0
_ZN4PLMD3ves18TargetDistribution12linkBiasGridEPNS_4GridE0
_ZN4PLMD3ves18TargetDistribution14checkNanAndInfEv0
_ZN4PLMD3ves18TargetDistributionD0Ev0
_ZN4PLMD3ves18TargetDistribution22clearLogTargetDistGridEv1
_ZN4PLMD3ves18TargetDistribution15setupBiasCutoffEv3
_ZN4PLMD3ves18TargetDistribution25linkBiasWithoutCutoffGridEPNS_4GridE3
_ZN4PLMD3ves18TargetDistribution32setMinimumOfTargetDistGridToZeroEv3
_ZN4PLMD3ves18TargetDistribution28applyTargetDistModiferToGridEPNS0_17TargetDistModiferE6
_ZN4PLMD3ves18TargetDistribution11getMarginalERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EE8
_ZN4PLMD3ves18TargetDistribution27readInRestartTargetDistGridERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE8
_ZN4PLMD3ves18TargetDistribution33updateBiasCutoffForTargetDistGridEv24
_ZN4PLMD3ves18TargetDistribution27getMarginalDistributionGridEPNS_4GridERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISA_EE28
_ZN4PLMD3ves18TargetDistribution23updateLogTargetDistGridEv29
_ZN4PLMD3ves18TargetDistribution11linkFesGridEPNS_4GridE40
_ZN4PLMD3ves18TargetDistribution11linkVesBiasEPNS0_7VesBiasE49
_ZN4PLMD3ves18TargetDistribution13normalizeGridEPNS_4GridE90
_ZN4PLMD3ves18TargetDistribution31calculateStaticDistributionGridEv368
_ZNK4PLMD3ves18TargetDistribution7getBetaEv377
_ZN4PLMD3ves18TargetDistribution10setupGridsERKSt6vectorIPNS_5ValueESaIS4_EERKS2_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISE_EESI_RKS2_IjSaIjEE407
_ZN4PLMD3ves18TargetDistributionC2ERKNS_13ActionOptionsE407
_ZN4PLMD3ves18TargetDistributionD2Ev407
_ZN4PLMD3ves18TargetDistribution12setDimensionEj420
_ZN4PLMD3ves18TargetDistribution16registerKeywordsERNS_8KeywordsE441
_ZN4PLMD3ves18TargetDistribution16updateTargetDistEv802
_ZN4PLMD3ves18TargetDistribution13integrateGridEPKNS_4GridE901
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TargetDistribution.cpp.func.html b/coverage/ves/TargetDistribution.cpp.func.html new file mode 100644 index 000000000000..52ff7d8c97ee --- /dev/null +++ b/coverage/ves/TargetDistribution.cpp.func.html @@ -0,0 +1,177 @@ + + + + + + + + LCOV - plumed test coverage - ves/TargetDistribution.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TargetDistribution.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:18921787.1 %
Date:2024-04-19 12:12:35Functions:222684.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves18TargetDistribution10linkActionEPNS_6ActionE0
_ZN4PLMD3ves18TargetDistribution10setupGridsERKSt6vectorIPNS_5ValueESaIS4_EERKS2_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISE_EESI_RKS2_IjSaIjEE407
_ZN4PLMD3ves18TargetDistribution11getMarginalERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EE8
_ZN4PLMD3ves18TargetDistribution11linkFesGridEPNS_4GridE40
_ZN4PLMD3ves18TargetDistribution11linkVesBiasEPNS0_7VesBiasE49
_ZN4PLMD3ves18TargetDistribution12linkBiasGridEPNS_4GridE0
_ZN4PLMD3ves18TargetDistribution12setDimensionEj420
_ZN4PLMD3ves18TargetDistribution13integrateGridEPKNS_4GridE901
_ZN4PLMD3ves18TargetDistribution13normalizeGridEPNS_4GridE90
_ZN4PLMD3ves18TargetDistribution14checkNanAndInfEv0
_ZN4PLMD3ves18TargetDistribution15setupBiasCutoffEv3
_ZN4PLMD3ves18TargetDistribution16registerKeywordsERNS_8KeywordsE441
_ZN4PLMD3ves18TargetDistribution16updateTargetDistEv802
_ZN4PLMD3ves18TargetDistribution22clearLogTargetDistGridEv1
_ZN4PLMD3ves18TargetDistribution23updateLogTargetDistGridEv29
_ZN4PLMD3ves18TargetDistribution25linkBiasWithoutCutoffGridEPNS_4GridE3
_ZN4PLMD3ves18TargetDistribution27getMarginalDistributionGridEPNS_4GridERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISA_EE28
_ZN4PLMD3ves18TargetDistribution27readInRestartTargetDistGridERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE8
_ZN4PLMD3ves18TargetDistribution28applyTargetDistModiferToGridEPNS0_17TargetDistModiferE6
_ZN4PLMD3ves18TargetDistribution31calculateStaticDistributionGridEv368
_ZN4PLMD3ves18TargetDistribution32setMinimumOfTargetDistGridToZeroEv3
_ZN4PLMD3ves18TargetDistribution33updateBiasCutoffForTargetDistGridEv24
_ZN4PLMD3ves18TargetDistributionC2ERKNS_13ActionOptionsE407
_ZN4PLMD3ves18TargetDistributionD0Ev0
_ZN4PLMD3ves18TargetDistributionD2Ev407
_ZNK4PLMD3ves18TargetDistribution7getBetaEv377
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TargetDistribution.cpp.gcov.html b/coverage/ves/TargetDistribution.cpp.gcov.html new file mode 100644 index 000000000000..05a9041240a8 --- /dev/null +++ b/coverage/ves/TargetDistribution.cpp.gcov.html @@ -0,0 +1,465 @@ + + + + + + + + LCOV - plumed test coverage - ves/TargetDistribution.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TargetDistribution.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:18921787.1 %
Date:2024-04-19 12:12:35Functions:222684.6 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "TargetDistribution.h"
+      24             : #include "TargetDistModifer.h"
+      25             : 
+      26             : #include "VesBias.h"
+      27             : #include "GridIntegrationWeights.h"
+      28             : #include "VesTools.h"
+      29             : 
+      30             : #include "core/Value.h"
+      31             : #include "tools/Grid.h"
+      32             : #include "tools/File.h"
+      33             : #include "tools/Keywords.h"
+      34             : 
+      35             : #include "GridProjWeights.h"
+      36             : 
+      37             : namespace PLMD {
+      38             : namespace ves {
+      39             : 
+      40         441 : void TargetDistribution::registerKeywords( Keywords& keys ) {
+      41         441 :   Action::registerKeywords(keys);
+      42         882 :   keys.reserve("optional","WELLTEMPERED_FACTOR","Broaden the target distribution such that it is taken as [p(s)]^(1/gamma) where gamma is the well tempered factor given here. If this option is active the distribution will be automatically normalized.");
+      43         882 :   keys.reserveFlag("SHIFT_TO_ZERO",false,"Shift the minimum value of the target distribution to zero. This can for example be used to avoid negative values in the target distribution. If this option is active the distribution will be automatically normalized.");
+      44         882 :   keys.reserveFlag("NORMALIZE",false,"Renormalized the target distribution over the intervals on which it is defined to make sure that it is properly normalized to 1. In most cases this should not be needed as the target distributions should be normalized. The code will issue a warning (but still run) if this is needed for some reason.");
+      45         441 : }
+      46             : 
+      47             : 
+      48         407 : TargetDistribution::TargetDistribution(const ActionOptions&ao):
+      49             :   Action(ao),
+      50         407 :   type_(static_targetdist),
+      51         407 :   force_normalization_(false),
+      52         407 :   check_normalization_(true),
+      53         407 :   check_nonnegative_(true),
+      54         407 :   check_nan_inf_(false),
+      55         407 :   shift_targetdist_to_zero_(false),
+      56         407 :   dimension_(0),
+      57         814 :   grid_args_(0),
+      58         407 :   action_pntr_(NULL),
+      59         407 :   vesbias_pntr_(NULL),
+      60         407 :   needs_bias_grid_(false),
+      61         407 :   needs_bias_withoutcutoff_grid_(false),
+      62         407 :   needs_fes_grid_(false),
+      63         407 :   bias_grid_pntr_(NULL),
+      64         407 :   bias_withoutcutoff_grid_pntr_(NULL),
+      65         407 :   fes_grid_pntr_(NULL),
+      66         407 :   static_grid_calculated(false),
+      67         407 :   allow_bias_cutoff_(true),
+      68         407 :   bias_cutoff_active_(false)
+      69             : {
+      70             :   //
+      71         814 :   if(keywords.exists("WELLTEMPERED_FACTOR")) {
+      72         301 :     double welltempered_factor=0.0;
+      73         301 :     parse("WELLTEMPERED_FACTOR",welltempered_factor);
+      74             :     //
+      75         301 :     if(welltempered_factor>0.0) {
+      76             :       auto pntr = Tools::make_unique<WellTemperedModifer>(welltempered_factor);
+      77           6 :       targetdist_modifer_pntrs_.emplace_back(std::move(pntr));
+      78           6 :     }
+      79         295 :     else if(welltempered_factor<0.0) {
+      80           0 :       plumed_merror(getName()+": negative value in WELLTEMPERED_FACTOR does not make sense");
+      81             :     }
+      82             :   }
+      83             :   //
+      84         814 :   if(keywords.exists("SHIFT_TO_ZERO")) {
+      85         289 :     parseFlag("SHIFT_TO_ZERO",shift_targetdist_to_zero_);
+      86         289 :     if(shift_targetdist_to_zero_) {
+      87           3 :       if(bias_cutoff_active_) {plumed_merror(getName()+": using SHIFT_TO_ZERO with bias cutoff is not allowed.");}
+      88           3 :       check_nonnegative_=false;
+      89             :     }
+      90             :   }
+      91             :   //
+      92         814 :   if(keywords.exists("NORMALIZE")) {
+      93         263 :     bool force_normalization=false;
+      94         263 :     parseFlag("NORMALIZE",force_normalization);
+      95         263 :     if(force_normalization) {
+      96           3 :       if(shift_targetdist_to_zero_) {plumed_merror(getName()+" with label "+getLabel()+": using NORMALIZE with SHIFT_TO_ZERO is not needed, the target distribution will be automatically normalized.");}
+      97             :       setForcedNormalization();
+      98             :     }
+      99             :   }
+     100             : 
+     101         407 : }
+     102             : 
+     103             : 
+     104         407 : TargetDistribution::~TargetDistribution() {
+     105         814 : }
+     106         377 : double TargetDistribution::getBeta() const {
+     107         377 :   plumed_massert(vesbias_pntr_!=NULL,"The VesBias has to be linked to use TargetDistribution::getBeta()");
+     108         377 :   return vesbias_pntr_->getBeta();
+     109             : }
+     110             : 
+     111             : 
+     112         420 : void TargetDistribution::setDimension(const unsigned int dimension) {
+     113         420 :   plumed_massert(dimension_==0,"setDimension: the dimension of the target distribution has already been set");
+     114         420 :   dimension_=dimension;
+     115         420 : }
+     116             : 
+     117             : 
+     118          49 : void TargetDistribution::linkVesBias(VesBias* vesbias_pntr_in) {
+     119          49 :   vesbias_pntr_ = vesbias_pntr_in;
+     120          49 :   action_pntr_ = static_cast<Action*>(vesbias_pntr_in);
+     121          49 : }
+     122             : 
+     123             : 
+     124           0 : void TargetDistribution::linkAction(Action* action_pntr_in) {
+     125           0 :   action_pntr_ = action_pntr_in;
+     126           0 : }
+     127             : 
+     128             : 
+     129           0 : void TargetDistribution::linkBiasGrid(Grid* bias_grid_pntr_in) {
+     130           0 :   bias_grid_pntr_ = bias_grid_pntr_in;
+     131           0 : }
+     132             : 
+     133             : 
+     134           3 : void TargetDistribution::linkBiasWithoutCutoffGrid(Grid* bias_withoutcutoff_grid_pntr_in) {
+     135           3 :   bias_withoutcutoff_grid_pntr_ = bias_withoutcutoff_grid_pntr_in;
+     136           3 : }
+     137             : 
+     138             : 
+     139          40 : void TargetDistribution::linkFesGrid(Grid* fes_grid_pntr_in) {
+     140          40 :   fes_grid_pntr_ = fes_grid_pntr_in;
+     141          40 : }
+     142             : 
+     143             : 
+     144           3 : void TargetDistribution::setupBiasCutoff() {
+     145           3 :   if(!allow_bias_cutoff_) {
+     146           0 :     plumed_merror(getName()+" with label "+getLabel()+": this target distribution does not support a bias cutoff");
+     147             :   }
+     148           3 :   if(targetdist_modifer_pntrs_.size()>0) {
+     149           0 :     plumed_merror(getName()+" with label "+getLabel()+": using a bias cutoff with a target distribution modifer like WELLTEMPERED_FACTOR is not allowed");
+     150             :   }
+     151           3 :   bias_cutoff_active_=true;
+     152             :   setBiasWithoutCutoffGridNeeded();
+     153             :   setDynamic();
+     154             :   // as the p(s) includes the derivative factor so normalization
+     155             :   // check can be misleading
+     156           3 :   check_normalization_=false;
+     157           3 :   force_normalization_=false;
+     158           3 : }
+     159             : 
+     160             : 
+     161         407 : void TargetDistribution::setupGrids(const std::vector<Value*>& arguments, const std::vector<std::string>& min, const std::vector<std::string>& max, const std::vector<unsigned int>& nbins) {
+     162         407 :   if(getDimension()==0) {
+     163          78 :     setDimension(arguments.size());
+     164             :   }
+     165             :   unsigned int dimension = getDimension();
+     166         407 :   plumed_massert(arguments.size()==dimension,"TargetDistribution::setupGrids: mismatch between number of values given for grid parameters");
+     167         407 :   plumed_massert(min.size()==dimension,"TargetDistribution::setupGrids: mismatch between number of values given for grid parameters");
+     168         407 :   plumed_massert(max.size()==dimension,"TargetDistribution::setupGrids: mismatch between number of values given for grid parameters");
+     169         407 :   plumed_massert(nbins.size()==dimension,"TargetDistribution::setupGrids: mismatch between number of values given for grid parameters");
+     170         407 :   grid_args_=arguments;
+     171         814 :   targetdist_grid_pntr_ =     Tools::make_unique<Grid>("targetdist",arguments,min,max,nbins,false,false);
+     172         814 :   log_targetdist_grid_pntr_ = Tools::make_unique<Grid>("log_targetdist",arguments,min,max,nbins,false,false);
+     173         407 :   setupAdditionalGrids(arguments,min,max,nbins);
+     174         407 : }
+     175             : 
+     176             : 
+     177         368 : void TargetDistribution::calculateStaticDistributionGrid() {
+     178         368 :   if(static_grid_calculated && !bias_cutoff_active_) {return;}
+     179             :   // plumed_massert(isStatic(),"this should only be used for static distributions");
+     180         348 :   plumed_massert(targetdist_grid_pntr_,"the grids have not been setup using setupGrids");
+     181         348 :   plumed_massert(log_targetdist_grid_pntr_,"the grids have not been setup using setupGrids");
+     182      467955 :   for(Grid::index_t l=0; l<targetdist_grid_pntr_->getSize(); l++)
+     183             :   {
+     184      467607 :     std::vector<double> argument = targetdist_grid_pntr_->getPoint(l);
+     185      467607 :     double value = getValue(argument);
+     186      467607 :     targetdist_grid_pntr_->setValue(l,value);
+     187      467607 :     log_targetdist_grid_pntr_->setValue(l,-std::log(value));
+     188             :   }
+     189         348 :   log_targetdist_grid_pntr_->setMinToZero();
+     190         348 :   static_grid_calculated = true;
+     191             : }
+     192             : 
+     193             : 
+     194         901 : double TargetDistribution::integrateGrid(const Grid* grid_pntr) {
+     195        1802 :   std::vector<double> integration_weights = GridIntegrationWeights::getIntegrationWeights(grid_pntr);
+     196             :   double sum = 0.0;
+     197     2579140 :   for(Grid::index_t l=0; l<grid_pntr->getSize(); l++) {
+     198     2578239 :     sum += integration_weights[l]*grid_pntr->getValue(l);
+     199             :   }
+     200         901 :   return sum;
+     201             : }
+     202             : 
+     203             : 
+     204          90 : double TargetDistribution::normalizeGrid(Grid* grid_pntr) {
+     205          90 :   double normalization = TargetDistribution::integrateGrid(grid_pntr);
+     206          90 :   grid_pntr->scaleAllValuesAndDerivatives(1.0/normalization);
+     207          90 :   return normalization;
+     208             : }
+     209             : 
+     210             : 
+     211          28 : Grid TargetDistribution::getMarginalDistributionGrid(Grid* grid_pntr, const std::vector<std::string>& args) {
+     212          28 :   plumed_massert(grid_pntr->getDimension()>1,"doesn't make sense calculating the marginal distribution for a one-dimensional distribution");
+     213          28 :   plumed_massert(args.size()<grid_pntr->getDimension(),"the number of arguments for the marginal distribution should be less than the dimension of the full distribution");
+     214             :   //
+     215          28 :   std::vector<std::string> argnames = grid_pntr->getArgNames();
+     216          28 :   std::vector<unsigned int> args_index(0);
+     217          84 :   for(unsigned int i=0; i<argnames.size(); i++) {
+     218         112 :     for(unsigned int l=0; l<args.size(); l++) {
+     219          56 :       if(argnames[i]==args[l]) {args_index.push_back(i);}
+     220             :     }
+     221             :   }
+     222          28 :   plumed_massert(args.size()==args_index.size(),"getMarginalDistributionGrid: problem with the arguments of the marginal");
+     223             :   //
+     224             :   auto Pw = Tools::make_unique<MarginalWeight>();
+     225          28 :   Grid proj_grid = grid_pntr->project(args,Pw.get());
+     226             :   Pw.reset();
+     227             :   //
+     228             :   // scale with the bin volume used for the integral such that the
+     229             :   // marginals are proberly normalized to 1.0
+     230          28 :   double intVol = grid_pntr->getBinVolume();
+     231          56 :   for(unsigned int l=0; l<args_index.size(); l++) {
+     232          28 :     intVol/=grid_pntr->getDx()[args_index[l]];
+     233             :   }
+     234          28 :   proj_grid.scaleAllValuesAndDerivatives(intVol);
+     235             :   //
+     236          28 :   return proj_grid;
+     237          56 : }
+     238             : 
+     239             : 
+     240           8 : Grid TargetDistribution::getMarginal(const std::vector<std::string>& args) {
+     241           8 :   return TargetDistribution::getMarginalDistributionGrid(targetdist_grid_pntr_.get(),args);
+     242             : }
+     243             : 
+     244             : 
+     245         802 : void TargetDistribution::updateTargetDist() {
+     246             :   //
+     247         802 :   updateGrid();
+     248             :   //
+     249         808 :   for(unsigned int i=0; i<targetdist_modifer_pntrs_.size(); i++) {
+     250           6 :     applyTargetDistModiferToGrid(targetdist_modifer_pntrs_[i].get());
+     251             :   }
+     252             :   //
+     253         802 :   if(bias_cutoff_active_) {updateBiasCutoffForTargetDistGrid();}
+     254             :   //
+     255         802 :   if(shift_targetdist_to_zero_ && !(bias_cutoff_active_)) {setMinimumOfTargetDistGridToZero();}
+     256         802 :   if(force_normalization_ && !(bias_cutoff_active_) ) {normalizeTargetDistGrid();}
+     257             :   //
+     258             :   // if(check_normalization_ && !force_normalization_ && !shift_targetdist_to_zero_){
+     259         802 :   if(check_normalization_ && !(bias_cutoff_active_)) {
+     260         691 :     double normalization = integrateGrid(targetdist_grid_pntr_.get());
+     261             :     const double normalization_thrshold = 0.1;
+     262         691 :     if(normalization < 1.0-normalization_thrshold || normalization > 1.0+normalization_thrshold) {
+     263           9 :       std::string norm_str; Tools::convert(normalization,norm_str);
+     264           9 :       std::string msg = "the target distribution grid is not proberly normalized, integrating over the grid gives: " + norm_str + " - You can avoid this problem by using the NORMALIZE keyword";
+     265           9 :       warning(msg);
+     266             :     }
+     267             :   }
+     268             :   //
+     269         802 :   if(check_nonnegative_) {
+     270             :     const double nonnegative_thrshold = -0.02;
+     271         799 :     double grid_min_value = targetdist_grid_pntr_->getMinValue();
+     272         799 :     if(grid_min_value<nonnegative_thrshold) {
+     273           0 :       std::string grid_min_value_str; Tools::convert(grid_min_value,grid_min_value_str);
+     274           0 :       std::string msg = "the target distribution grid has negative values, the lowest value is: " + grid_min_value_str + " - You can avoid this problem by using the SHIFT_TO_ZERO keyword";
+     275           0 :       warning(msg);
+     276             :     }
+     277             :   }
+     278             :   //
+     279         802 :   if(check_nan_inf_) {checkNanAndInf();}
+     280             :   //
+     281         802 : }
+     282             : 
+     283             : 
+     284          24 : void TargetDistribution::updateBiasCutoffForTargetDistGrid() {
+     285          24 :   plumed_massert(vesbias_pntr_!=NULL,"The VesBias has to be linked to use updateBiasCutoffForTargetDistGrid()");
+     286          24 :   plumed_massert(vesbias_pntr_->biasCutoffActive(),"updateBiasCutoffForTargetDistGrid() should only be used if the bias cutoff is active");
+     287             :   // plumed_massert(targetdist_grid_pntr_!=NULL,"the grids have not been setup using setupGrids");
+     288             :   // plumed_massert(log_targetdist_grid_pntr_!=NULL,"the grids have not been setup using setupGrids");
+     289          24 :   plumed_massert(getBiasWithoutCutoffGridPntr()!=NULL,"the bias without cutoff grid has to be linked");
+     290             :   //
+     291          48 :   std::vector<double> integration_weights = GridIntegrationWeights::getIntegrationWeights(targetdist_grid_pntr_.get());
+     292             :   double norm = 0.0;
+     293        2624 :   for(Grid::index_t l=0; l<targetdist_grid_pntr_->getSize(); l++)
+     294             :   {
+     295        2600 :     double value = targetdist_grid_pntr_->getValue(l);
+     296        2600 :     double bias = getBiasWithoutCutoffGridPntr()->getValue(l);
+     297        2600 :     double deriv_factor_swf = 0.0;
+     298        2600 :     double swf = vesbias_pntr_->getBiasCutoffSwitchingFunction(bias,deriv_factor_swf);
+     299             :     // this comes from the p(s)
+     300        2600 :     value *= swf;
+     301        2600 :     norm += integration_weights[l]*value;
+     302             :     // this comes from the derivative of V(s)
+     303        2600 :     value *= deriv_factor_swf;
+     304        2600 :     targetdist_grid_pntr_->setValue(l,value);
+     305             :     // double log_value = log_targetdist_grid_pntr_->getValue(l) - std::log(swf);
+     306             :     // log_targetdist_grid_pntr_->setValue(l,log_value);
+     307             :   }
+     308          24 :   targetdist_grid_pntr_->scaleAllValuesAndDerivatives(1.0/norm);
+     309             :   // log_targetdist_grid_pntr_->setMinToZero();
+     310          24 : }
+     311             : 
+     312           6 : void TargetDistribution::applyTargetDistModiferToGrid(TargetDistModifer* modifer_pntr) {
+     313             :   // plumed_massert(targetdist_grid_pntr_!=NULL,"the grids have not been setup using setupGrids");
+     314             :   // plumed_massert(log_targetdist_grid_pntr_!=NULL,"the grids have not been setup using setupGrids");
+     315             :   //
+     316          12 :   std::vector<double> integration_weights = GridIntegrationWeights::getIntegrationWeights(targetdist_grid_pntr_.get());
+     317             :   double norm = 0.0;
+     318       21212 :   for(Grid::index_t l=0; l<targetdist_grid_pntr_->getSize(); l++)
+     319             :   {
+     320       21206 :     double value = targetdist_grid_pntr_->getValue(l);
+     321       21206 :     std::vector<double> cv_values = targetdist_grid_pntr_->getPoint(l);
+     322       21206 :     value = modifer_pntr->getModifedTargetDistValue(value,cv_values);
+     323       21206 :     norm += integration_weights[l]*value;
+     324       21206 :     targetdist_grid_pntr_->setValue(l,value);
+     325       21206 :     log_targetdist_grid_pntr_->setValue(l,-std::log(value));
+     326             :   }
+     327           6 :   targetdist_grid_pntr_->scaleAllValuesAndDerivatives(1.0/norm);
+     328           6 :   log_targetdist_grid_pntr_->setMinToZero();
+     329           6 : }
+     330             : 
+     331             : 
+     332          29 : void TargetDistribution::updateLogTargetDistGrid() {
+     333       44070 :   for(Grid::index_t l=0; l<targetdist_grid_pntr_->getSize(); l++)
+     334             :   {
+     335       44041 :     log_targetdist_grid_pntr_->setValue(l,-std::log(targetdist_grid_pntr_->getValue(l)));
+     336             :   }
+     337          29 :   log_targetdist_grid_pntr_->setMinToZero();
+     338          29 : }
+     339             : 
+     340             : 
+     341           3 : void TargetDistribution::setMinimumOfTargetDistGridToZero() {
+     342           3 :   targetDistGrid().setMinToZero();
+     343           3 :   normalizeTargetDistGrid();
+     344           3 :   updateLogTargetDistGrid();
+     345           3 : }
+     346             : 
+     347             : 
+     348           8 : void TargetDistribution::readInRestartTargetDistGrid(const std::string& grid_fname) {
+     349           8 :   plumed_massert(isDynamic(),"this should only be used for dynamically updated target distributions!");
+     350           8 :   IFile gridfile;
+     351           8 :   if(!gridfile.FileExist(grid_fname)) {
+     352           0 :     plumed_merror(getName()+": problem with reading previous target distribution when restarting, cannot find file " + grid_fname);
+     353             :   }
+     354           8 :   gridfile.open(grid_fname);
+     355          16 :   std::unique_ptr<GridBase> restart_grid = GridBase::create("targetdist",grid_args_,gridfile,false,false,false);
+     356           8 :   if(restart_grid->getSize()!=targetdist_grid_pntr_->getSize()) {
+     357           0 :     plumed_merror(getName()+": problem with reading previous target distribution when restarting, the grid is not of the correct size!");
+     358             :   }
+     359           8 :   VesTools::copyGridValues(restart_grid.get(),targetdist_grid_pntr_.get());
+     360           8 :   updateLogTargetDistGrid();
+     361           8 : }
+     362             : 
+     363           1 : void TargetDistribution::clearLogTargetDistGrid() {
+     364           1 :   log_targetdist_grid_pntr_->clear();
+     365           1 : }
+     366             : 
+     367             : 
+     368           0 : void TargetDistribution::checkNanAndInf() {
+     369           0 :   for(Grid::index_t l=0; l<targetdist_grid_pntr_->getSize(); l++)
+     370             :   {
+     371           0 :     double value = targetdist_grid_pntr_->getValue(l);
+     372           0 :     if(std::isnan(value) || std::isinf(value)) {
+     373           0 :       std::string vs; Tools::convert(value,vs);
+     374           0 :       std::vector<double> p = targetdist_grid_pntr_->getPoint(l);
+     375           0 :       std::string ps; Tools::convert(p[0],ps);
+     376           0 :       ps = "(" + ps;
+     377           0 :       for(unsigned int k=1; k<p.size(); k++) {
+     378           0 :         std::string t1; Tools::convert(p[k],t1);
+     379           0 :         ps = ps + "," + t1;
+     380             :       }
+     381           0 :       ps = ps + ")";
+     382           0 :       plumed_merror(getName()+": problem with target distribution, the value at " + ps + " is " + vs);
+     383             :     }
+     384             :   }
+     385           0 : }
+     386             : 
+     387             : }
+     388             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TargetDistribution.h.func-sort-c.html b/coverage/ves/TargetDistribution.h.func-sort-c.html new file mode 100644 index 000000000000..6726d9ff6611 --- /dev/null +++ b/coverage/ves/TargetDistribution.h.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - ves/TargetDistribution.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TargetDistribution.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:182281.8 %
Date:2024-04-19 12:12:35Functions:3650.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves18TargetDistribution5applyEv0
_ZN4PLMD3ves18TargetDistribution6updateEv0
_ZN4PLMD3ves18TargetDistribution9calculateEv0
_ZN4PLMD3ves18TargetDistribution23normalizeTargetDistGridEv90
_ZN4PLMD3ves18TargetDistribution20setupAdditionalGridsERKSt6vectorIPNS_5ValueESaIS4_EERKS2_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISE_EESI_RKS2_IjSaIjEE287
_ZN4PLMD3ves18TargetDistribution10updateGridEv368
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TargetDistribution.h.func.html b/coverage/ves/TargetDistribution.h.func.html new file mode 100644 index 000000000000..8749917abf8b --- /dev/null +++ b/coverage/ves/TargetDistribution.h.func.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - ves/TargetDistribution.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TargetDistribution.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:182281.8 %
Date:2024-04-19 12:12:35Functions:3650.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves18TargetDistribution10updateGridEv368
_ZN4PLMD3ves18TargetDistribution20setupAdditionalGridsERKSt6vectorIPNS_5ValueESaIS4_EERKS2_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISE_EESI_RKS2_IjSaIjEE287
_ZN4PLMD3ves18TargetDistribution23normalizeTargetDistGridEv90
_ZN4PLMD3ves18TargetDistribution5applyEv0
_ZN4PLMD3ves18TargetDistribution6updateEv0
_ZN4PLMD3ves18TargetDistribution9calculateEv0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TargetDistribution.h.gcov.html b/coverage/ves/TargetDistribution.h.gcov.html new file mode 100644 index 000000000000..2e1dcc33b7c8 --- /dev/null +++ b/coverage/ves/TargetDistribution.h.gcov.html @@ -0,0 +1,286 @@ + + + + + + + + LCOV - plumed test coverage - ves/TargetDistribution.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TargetDistribution.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:182281.8 %
Date:2024-04-19 12:12:35Functions:3650.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_ves_TargetDistribution_h
+      23             : #define __PLUMED_ves_TargetDistribution_h
+      24             : 
+      25             : #include "core/Action.h"
+      26             : 
+      27             : #include <vector>
+      28             : #include <string>
+      29             : #include <cmath>
+      30             : #include <memory>
+      31             : 
+      32             : #define PLUMED_VES_TARGETDISTRIBUTION_INIT(ao) TargetDistribution(ao)
+      33             : 
+      34             : namespace PLMD {
+      35             : 
+      36             : /**
+      37             : \ingroup INHERIT
+      38             : Abstract base class for implenting new target distributions.
+      39             : */
+      40             : 
+      41             : class Action;
+      42             : class Grid;
+      43             : class Value;
+      44             : class Keywords;
+      45             : 
+      46             : namespace ves {
+      47             : 
+      48             : class TargetDistModifer;
+      49             : class VesBias;
+      50             : 
+      51             : class TargetDistribution :
+      52             :   public Action
+      53             : {
+      54             : private:
+      55             :   enum TargetDistType {
+      56             :     static_targetdist,
+      57             :     dynamic_targetdist
+      58             :   } type_;
+      59             :   //
+      60             :   bool force_normalization_;
+      61             :   bool check_normalization_;
+      62             :   bool check_nonnegative_;
+      63             :   bool check_nan_inf_;
+      64             :   bool shift_targetdist_to_zero_;
+      65             :   // dimension of the distribution
+      66             :   unsigned int dimension_;
+      67             :   // grid parameters
+      68             :   std::vector<Value*> grid_args_;
+      69             :   //
+      70             :   std::unique_ptr<Grid> targetdist_grid_pntr_;
+      71             :   std::unique_ptr<Grid> log_targetdist_grid_pntr_;
+      72             :   //
+      73             :   std::vector<std::unique_ptr<TargetDistModifer>> targetdist_modifer_pntrs_;
+      74             :   //
+      75             :   Action* action_pntr_;
+      76             :   VesBias* vesbias_pntr_;
+      77             :   //
+      78             :   bool needs_bias_grid_;
+      79             :   bool needs_bias_withoutcutoff_grid_;
+      80             :   bool needs_fes_grid_;
+      81             :   //
+      82             :   Grid* bias_grid_pntr_;
+      83             :   Grid* bias_withoutcutoff_grid_pntr_;
+      84             :   Grid* fes_grid_pntr_;
+      85             :   //
+      86             :   bool static_grid_calculated;
+      87             :   //
+      88             :   bool allow_bias_cutoff_;
+      89             :   bool bias_cutoff_active_;
+      90             :   //
+      91             :   void calculateStaticDistributionGrid();
+      92             :   void updateBiasCutoffForTargetDistGrid();
+      93             :   void checkNanAndInf();
+      94             : protected:
+      95             :   void setStatic() {type_=static_targetdist;}
+      96          41 :   void setDynamic() {type_=dynamic_targetdist;}
+      97             :   // set the that target distribution is normalized
+      98          80 :   void setForcedNormalization() {force_normalization_=true; check_normalization_=false;}
+      99             :   void unsetForcedNormalization() {force_normalization_=false; check_normalization_=true;};
+     100             :   //
+     101           0 :   void setBiasGridNeeded() {needs_bias_grid_=true;}
+     102           3 :   void setBiasWithoutCutoffGridNeeded() {needs_bias_withoutcutoff_grid_=true;}
+     103          38 :   void setFesGridNeeded() {needs_fes_grid_=true;}
+     104             :   //
+     105             :   VesBias* getPntrToVesBias() const;
+     106             :   Action* getPntrToAction() const;
+     107             :   //
+     108         287 :   virtual void setupAdditionalGrids(const std::vector<Value*>&, const std::vector<std::string>&, const std::vector<std::string>&, const std::vector<unsigned int>&) {}
+     109             :   //
+     110             :   void normalizeTargetDistGrid();
+     111             :   //
+     112             :   Grid& targetDistGrid() const {return *targetdist_grid_pntr_;}
+     113             :   Grid& logTargetDistGrid() const {return *log_targetdist_grid_pntr_;}
+     114             :   //
+     115             :   Grid* getBiasGridPntr() const {return bias_grid_pntr_;}
+     116        2624 :   Grid* getBiasWithoutCutoffGridPntr() const {return bias_withoutcutoff_grid_pntr_;}
+     117    11814078 :   Grid* getFesGridPntr() const {return fes_grid_pntr_;}
+     118             :   //
+     119             :   double getBeta() const;
+     120             :   //
+     121             :   void applyTargetDistModiferToGrid(TargetDistModifer* modifer_pntr);
+     122             :   //
+     123             :   void setMinimumOfTargetDistGridToZero();
+     124             :   void updateLogTargetDistGrid();
+     125             :   //
+     126         368 :   virtual void updateGrid() {calculateStaticDistributionGrid();}
+     127             : public:
+     128             :   static void registerKeywords(Keywords&);
+     129             :   explicit TargetDistribution(const ActionOptions&);
+     130             :   ~TargetDistribution();
+     131             :   //
+     132             :   bool isStatic() const {return type_==static_targetdist;}
+     133         602 :   bool isDynamic() const {return type_==dynamic_targetdist;}
+     134             :   // is the target distribution normalize or not
+     135             :   bool forcedNormalization() const {return force_normalization_;};
+     136        5194 :   bool isTargetDistGridShiftedToZero() const {return shift_targetdist_to_zero_;}
+     137             :   //
+     138         466 :   bool biasGridNeeded() const {return needs_bias_grid_;}
+     139          45 :   bool biasWithoutCutoffGridNeeded() const {return needs_bias_withoutcutoff_grid_;}
+     140         466 :   bool fesGridNeeded()  const {return needs_fes_grid_;}
+     141             :   //
+     142             :   void allowBiasCutoff() {allow_bias_cutoff_=true;}
+     143             :   void doNotAllowBiasCutoff() {allow_bias_cutoff_=false;}
+     144             :   bool isBiasCutoffAllowed() const {return allow_bias_cutoff_;}
+     145             :   bool biasCutoffActive() const {return bias_cutoff_active_;}
+     146             :   //
+     147             :   void setDimension(const unsigned int dimension);
+     148      506318 :   unsigned getDimension() const {return dimension_;}
+     149             :   //
+     150             :   virtual void linkVesBias(VesBias*);
+     151             :   virtual void linkAction(Action*);
+     152             :   //
+     153             :   virtual void linkBiasGrid(Grid*);
+     154             :   virtual void linkBiasWithoutCutoffGrid(Grid*);
+     155             :   virtual void linkFesGrid(Grid*);
+     156             :   //
+     157             :   void setupBiasCutoff();
+     158             :   //
+     159             :   Grid* getTargetDistGridPntr() const {return targetdist_grid_pntr_.get();}
+     160             :   Grid* getLogTargetDistGridPntr() const {return log_targetdist_grid_pntr_.get();}
+     161             :   //
+     162             :   void clearLogTargetDistGrid();
+     163             :   // calculate the target distribution itself
+     164             :   virtual double getValue(const std::vector<double>&) const = 0;
+     165             :   //
+     166             :   void setupGrids(const std::vector<Value*>&, const std::vector<std::string>&, const std::vector<std::string>&, const std::vector<unsigned int>&);
+     167             :   //
+     168             :   Grid getMarginal(const std::vector<std::string>&);
+     169             :   //
+     170             :   void updateTargetDist();
+     171             :   //
+     172             :   void readInRestartTargetDistGrid(const std::string&);
+     173             :   //
+     174             :   static double integrateGrid(const Grid*);
+     175             :   static double normalizeGrid(Grid*);
+     176             :   static Grid getMarginalDistributionGrid(Grid*, const std::vector<std::string>&);
+     177             :   // empty standard action stuff
+     178           0 :   void update() override {};
+     179           0 :   void apply() override {};
+     180           0 :   void calculate() override {};
+     181             : };
+     182             : 
+     183             : 
+     184             : inline
+     185             : VesBias* TargetDistribution::getPntrToVesBias() const {
+     186             :   plumed_massert(vesbias_pntr_!=NULL,"the VES bias has not been linked");
+     187             :   return vesbias_pntr_;
+     188             : }
+     189             : 
+     190             : 
+     191             : inline
+     192             : Action* TargetDistribution::getPntrToAction() const {
+     193             :   plumed_massert(action_pntr_!=NULL,"the action has not been linked");
+     194             :   return action_pntr_;
+     195             : }
+     196             : 
+     197             : 
+     198             : inline
+     199          90 : void TargetDistribution::normalizeTargetDistGrid() {
+     200          90 :   double normalization = normalizeGrid(targetdist_grid_pntr_.get());
+     201          90 :   if(normalization<0.0) {plumed_merror(getName()+": something went wrong trying to normalize the target distribution, integrating over it gives a negative value.");}
+     202          90 : }
+     203             : 
+     204             : 
+     205             : 
+     206             : 
+     207             : }
+     208             : }
+     209             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/VesBias.cpp.func-sort-c.html b/coverage/ves/VesBias.cpp.func-sort-c.html new file mode 100644 index 000000000000..cb3d71dba998 --- /dev/null +++ b/coverage/ves/VesBias.cpp.func-sort-c.html @@ -0,0 +1,253 @@ + + + + + + + + LCOV - plumed test coverage - ves/VesBias.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - VesBias.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:32442576.2 %
Date:2024-04-19 12:12:35Functions:274560.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves7VesBias10setGridMaxERKSt6vectorIdSaIdEE0
_ZN4PLMD3ves7VesBias10setGridMinERKSt6vectorIdSaIdEE0
_ZN4PLMD3ves7VesBias11setGridBinsERKSt6vectorIjSaIjEE0
_ZN4PLMD3ves7VesBias11setGridBinsEj0
_ZN4PLMD3ves7VesBias12addCoeffsSetERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS2_IjSaIjEE0
_ZN4PLMD3ves7VesBias12addCoeffsSetESt10unique_ptrINS0_12CoeffsVectorESt14default_deleteIS3_EE0
_ZN4PLMD3ves7VesBias14disableHessianEv0
_ZN4PLMD3ves7VesBias20updateReweightFactorEv0
_ZN4PLMD3ves7VesBias21setTargetDistAveragesERKSt6vectorIdSaIdEEj0
_ZN4PLMD3ves7VesBias21useGridLimitsKeywordsERNS_8KeywordsE0
_ZN4PLMD3ves7VesBias25useReweightFactorKeywordsERNS_8KeywordsE0
_ZN4PLMD3ves7VesBias27setTargetDistAveragesToZeroEj0
_ZN4PLMD3ves7VesBias37useMultipleTargetDistributionKeywordsERNS_8KeywordsE0
_ZN4PLMD3ves7VesBiasC1ERKNS_13ActionOptionsE0
_ZN4PLMD3ves7VesBiasD0Ev0
_ZN4PLMD3ves7VesBiasD1Ev0
_ZNK4PLMD3ves7VesBias23calculateReweightFactorEv0
_ZNK4PLMD3ves7VesBias26getCoeffsSetFilenameSuffixB5cxx11Ej0
_ZN4PLMD3ves7VesBias15setupBiasCutoffEdd3
_ZN4PLMD3ves7VesBias13enableHessianEb82
_ZN4PLMD3ves7VesBias13linkOptimizerEPNS0_9OptimizerE85
_ZN4PLMD3ves7VesBias12addCoeffsSetERSt6vectorIPNS_5ValueESaIS4_EERS2_IPNS0_14BasisFunctionsESaIS9_EE90
_ZN4PLMD3ves7VesBias16initializeCoeffsESt10unique_ptrINS0_12CoeffsVectorESt14default_deleteIS3_EE90
_ZN4PLMD3ves7VesBias19readCoeffsFromFilesEv90
_ZN4PLMD3ves7VesBiasC2ERKNS_13ActionOptionsE90
_ZN4PLMD3ves7VesBiasD2Ev90
_ZN4PLMD3ves7VesBias16registerKeywordsERNS_8KeywordsE92
_ZN4PLMD3ves7VesBias18useGridBinKeywordsERNS_8KeywordsE92
_ZN4PLMD3ves7VesBias21useBiasCutoffKeywordsERNS_8KeywordsE92
_ZN4PLMD3ves7VesBias24useInitialCoeffsKeywordsERNS_8KeywordsE92
_ZN4PLMD3ves7VesBias24useProjectionArgKeywordsERNS_8KeywordsE92
_ZN4PLMD3ves7VesBias29useTargetDistributionKeywordsERNS_8KeywordsE92
_ZN4PLMD3ves7VesBias19multiSimSumAveragesEjd120
_ZN4PLMD3ves7VesBias27checkThatTemperatureIsGivenEv175
_ZNK4PLMD3ves7VesBias34getCurrentTargetDistOutputFilenameERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE192
_ZNK4PLMD3ves7VesBias24getCurrentOutputFilenameERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_383
_ZNK4PLMD3ves7VesBias23getCoeffsSetLabelStringERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEj442
_ZN4PLMD3ves7VesBias21setTargetDistAveragesERKNS0_12CoeffsVectorEj453
_ZNK4PLMD3ves7VesBias26getIterationFilenameSuffixB5cxx11Ev552
_ZN4PLMD3ves7VesBias8getOFileERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbb567
_ZNK4PLMD3ves7VesBias18useMultipleWalkersEv567
_ZNK4PLMD3ves7VesBias19getIterationCounterEv1005
_ZNK4PLMD3ves7VesBias30getBiasCutoffSwitchingFunctionEdRd3263
_ZN4PLMD3ves7VesBias24updateGradientAndHessianEb22810
_ZN4PLMD3ves7VesBias20addToSampledAveragesERKSt6vectorIdSaIdEEj23556
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/VesBias.cpp.func.html b/coverage/ves/VesBias.cpp.func.html new file mode 100644 index 000000000000..e13447e4ae55 --- /dev/null +++ b/coverage/ves/VesBias.cpp.func.html @@ -0,0 +1,253 @@ + + + + + + + + LCOV - plumed test coverage - ves/VesBias.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - VesBias.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:32442576.2 %
Date:2024-04-19 12:12:35Functions:274560.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves7VesBias10setGridMaxERKSt6vectorIdSaIdEE0
_ZN4PLMD3ves7VesBias10setGridMinERKSt6vectorIdSaIdEE0
_ZN4PLMD3ves7VesBias11setGridBinsERKSt6vectorIjSaIjEE0
_ZN4PLMD3ves7VesBias11setGridBinsEj0
_ZN4PLMD3ves7VesBias12addCoeffsSetERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS2_IjSaIjEE0
_ZN4PLMD3ves7VesBias12addCoeffsSetERSt6vectorIPNS_5ValueESaIS4_EERS2_IPNS0_14BasisFunctionsESaIS9_EE90
_ZN4PLMD3ves7VesBias12addCoeffsSetESt10unique_ptrINS0_12CoeffsVectorESt14default_deleteIS3_EE0
_ZN4PLMD3ves7VesBias13enableHessianEb82
_ZN4PLMD3ves7VesBias13linkOptimizerEPNS0_9OptimizerE85
_ZN4PLMD3ves7VesBias14disableHessianEv0
_ZN4PLMD3ves7VesBias15setupBiasCutoffEdd3
_ZN4PLMD3ves7VesBias16initializeCoeffsESt10unique_ptrINS0_12CoeffsVectorESt14default_deleteIS3_EE90
_ZN4PLMD3ves7VesBias16registerKeywordsERNS_8KeywordsE92
_ZN4PLMD3ves7VesBias18useGridBinKeywordsERNS_8KeywordsE92
_ZN4PLMD3ves7VesBias19multiSimSumAveragesEjd120
_ZN4PLMD3ves7VesBias19readCoeffsFromFilesEv90
_ZN4PLMD3ves7VesBias20addToSampledAveragesERKSt6vectorIdSaIdEEj23556
_ZN4PLMD3ves7VesBias20updateReweightFactorEv0
_ZN4PLMD3ves7VesBias21setTargetDistAveragesERKNS0_12CoeffsVectorEj453
_ZN4PLMD3ves7VesBias21setTargetDistAveragesERKSt6vectorIdSaIdEEj0
_ZN4PLMD3ves7VesBias21useBiasCutoffKeywordsERNS_8KeywordsE92
_ZN4PLMD3ves7VesBias21useGridLimitsKeywordsERNS_8KeywordsE0
_ZN4PLMD3ves7VesBias24updateGradientAndHessianEb22810
_ZN4PLMD3ves7VesBias24useInitialCoeffsKeywordsERNS_8KeywordsE92
_ZN4PLMD3ves7VesBias24useProjectionArgKeywordsERNS_8KeywordsE92
_ZN4PLMD3ves7VesBias25useReweightFactorKeywordsERNS_8KeywordsE0
_ZN4PLMD3ves7VesBias27checkThatTemperatureIsGivenEv175
_ZN4PLMD3ves7VesBias27setTargetDistAveragesToZeroEj0
_ZN4PLMD3ves7VesBias29useTargetDistributionKeywordsERNS_8KeywordsE92
_ZN4PLMD3ves7VesBias37useMultipleTargetDistributionKeywordsERNS_8KeywordsE0
_ZN4PLMD3ves7VesBias8getOFileERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbb567
_ZN4PLMD3ves7VesBiasC1ERKNS_13ActionOptionsE0
_ZN4PLMD3ves7VesBiasC2ERKNS_13ActionOptionsE90
_ZN4PLMD3ves7VesBiasD0Ev0
_ZN4PLMD3ves7VesBiasD1Ev0
_ZN4PLMD3ves7VesBiasD2Ev90
_ZNK4PLMD3ves7VesBias18useMultipleWalkersEv567
_ZNK4PLMD3ves7VesBias19getIterationCounterEv1005
_ZNK4PLMD3ves7VesBias23calculateReweightFactorEv0
_ZNK4PLMD3ves7VesBias23getCoeffsSetLabelStringERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEj442
_ZNK4PLMD3ves7VesBias24getCurrentOutputFilenameERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_383
_ZNK4PLMD3ves7VesBias26getCoeffsSetFilenameSuffixB5cxx11Ej0
_ZNK4PLMD3ves7VesBias26getIterationFilenameSuffixB5cxx11Ev552
_ZNK4PLMD3ves7VesBias30getBiasCutoffSwitchingFunctionEdRd3263
_ZNK4PLMD3ves7VesBias34getCurrentTargetDistOutputFilenameERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE192
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/VesBias.cpp.gcov.html b/coverage/ves/VesBias.cpp.gcov.html new file mode 100644 index 000000000000..4bc99b223cb0 --- /dev/null +++ b/coverage/ves/VesBias.cpp.gcov.html @@ -0,0 +1,830 @@ + + + + + + + + LCOV - plumed test coverage - ves/VesBias.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - VesBias.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:32442576.2 %
Date:2024-04-19 12:12:35Functions:274560.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "VesBias.h"
+      24             : #include "BasisFunctions.h"
+      25             : #include "CoeffsVector.h"
+      26             : #include "CoeffsMatrix.h"
+      27             : #include "Optimizer.h"
+      28             : #include "FermiSwitchingFunction.h"
+      29             : #include "VesTools.h"
+      30             : #include "TargetDistribution.h"
+      31             : 
+      32             : #include "tools/Communicator.h"
+      33             : #include "core/ActionSet.h"
+      34             : #include "core/PlumedMain.h"
+      35             : #include "tools/File.h"
+      36             : 
+      37             : 
+      38             : namespace PLMD {
+      39             : namespace ves {
+      40             : 
+      41          90 : VesBias::VesBias(const ActionOptions&ao):
+      42             :   Action(ao),
+      43             :   Bias(ao),
+      44          90 :   ncoeffssets_(0),
+      45          90 :   sampled_averages(0),
+      46          90 :   sampled_cross_averages(0),
+      47          90 :   use_multiple_coeffssets_(false),
+      48          90 :   coeffs_fnames(0),
+      49          90 :   ncoeffs_total_(0),
+      50          90 :   optimizer_pntr_(NULL),
+      51          90 :   optimize_coeffs_(false),
+      52          90 :   compute_hessian_(false),
+      53          90 :   diagonal_hessian_(true),
+      54          90 :   aver_counters(0),
+      55          90 :   kbt_(0.0),
+      56          90 :   targetdist_pntrs_(0),
+      57          90 :   dynamic_targetdist_(false),
+      58          90 :   grid_bins_(0),
+      59          90 :   grid_min_(0),
+      60          90 :   grid_max_(0),
+      61          90 :   bias_filename_(""),
+      62          90 :   fes_filename_(""),
+      63          90 :   targetdist_filename_(""),
+      64          90 :   coeffs_id_prefix_("c-"),
+      65          90 :   bias_file_fmt_("14.9f"),
+      66          90 :   fes_file_fmt_("14.9f"),
+      67          90 :   targetdist_file_fmt_("14.9f"),
+      68          90 :   targetdist_restart_file_fmt_("30.16e"),
+      69          90 :   filenames_have_iteration_number_(false),
+      70          90 :   bias_fileoutput_active_(false),
+      71          90 :   fes_fileoutput_active_(false),
+      72          90 :   fesproj_fileoutput_active_(false),
+      73          90 :   dynamic_targetdist_fileoutput_active_(false),
+      74          90 :   static_targetdist_fileoutput_active_(true),
+      75          90 :   bias_cutoff_active_(false),
+      76          90 :   bias_cutoff_value_(0.0),
+      77          90 :   bias_current_max_value(0.0),
+      78          90 :   calc_reweightfactor_(false),
+      79         270 :   optimization_threshold_(0.0)
+      80             : {
+      81          90 :   log.printf("  VES bias, please read and cite ");
+      82         180 :   log << plumed.cite("Valsson and Parrinello, Phys. Rev. Lett. 113, 090601 (2014)");
+      83          90 :   log.printf("\n");
+      84             : 
+      85          90 :   kbt_=getkBT();
+      86          90 :   if(kbt_>0.0) {
+      87          90 :     log.printf("  KbT: %f\n",kbt_);
+      88             :   }
+      89             :   // NOTE: the check for that the temperature is given is done when linking the optimizer later on.
+      90             : 
+      91         180 :   if(keywords.exists("COEFFS")) {
+      92         180 :     parseVector("COEFFS",coeffs_fnames);
+      93             :   }
+      94             : 
+      95         180 :   if(keywords.exists("GRID_BINS")) {
+      96         180 :     parseMultipleValues<unsigned int>("GRID_BINS",grid_bins_,getNumberOfArguments(),100);
+      97             :   }
+      98             : 
+      99          90 :   if(keywords.exists("GRID_MIN") && keywords.exists("GRID_MAX")) {
+     100           0 :     parseMultipleValues("GRID_MIN",grid_min_,getNumberOfArguments());
+     101           0 :     parseMultipleValues("GRID_MAX",grid_max_,getNumberOfArguments());
+     102             :   }
+     103             : 
+     104             :   std::vector<std::string> targetdist_labels;
+     105         180 :   if(keywords.exists("TARGET_DISTRIBUTION")) {
+     106         180 :     parseVector("TARGET_DISTRIBUTION",targetdist_labels);
+     107          90 :     if(targetdist_labels.size()>1) {
+     108           0 :       plumed_merror(getName()+" with label "+getLabel()+": multiple target distribution labels not allowed");
+     109             :     }
+     110             :   }
+     111           0 :   else if(keywords.exists("TARGET_DISTRIBUTIONS")) {
+     112           0 :     parseVector("TARGET_DISTRIBUTIONS",targetdist_labels);
+     113             :   }
+     114             : 
+     115          90 :   std::string error_msg = "";
+     116         180 :   targetdist_pntrs_ = VesTools::getPointersFromLabels<TargetDistribution*>(targetdist_labels,plumed.getActionSet(),error_msg);
+     117          90 :   if(error_msg.size()>0) {plumed_merror("Problem with target distribution in "+getName()+": "+error_msg);}
+     118             : 
+     119         135 :   for(unsigned int i=0; i<targetdist_pntrs_.size(); i++) {
+     120          45 :     targetdist_pntrs_[i]->linkVesBias(this);
+     121             :   }
+     122             : 
+     123             : 
+     124          90 :   if(getNumberOfArguments()>2) {
+     125             :     disableStaticTargetDistFileOutput();
+     126             :   }
+     127             : 
+     128             : 
+     129         180 :   if(keywords.exists("BIAS_FILE")) {
+     130         180 :     parse("BIAS_FILE",bias_filename_);
+     131          90 :     if(bias_filename_.size()==0) {
+     132         180 :       bias_filename_ = "bias." + getLabel() + ".data";
+     133             :     }
+     134             :   }
+     135         180 :   if(keywords.exists("FES_FILE")) {
+     136         180 :     parse("FES_FILE",fes_filename_);
+     137          90 :     if(fes_filename_.size()==0) {
+     138         180 :       fes_filename_ = "fes." + getLabel() + ".data";
+     139             :     }
+     140             :   }
+     141         180 :   if(keywords.exists("TARGETDIST_FILE")) {
+     142         180 :     parse("TARGETDIST_FILE",targetdist_filename_);
+     143          90 :     if(targetdist_filename_.size()==0) {
+     144         180 :       targetdist_filename_ = "targetdist." + getLabel() + ".data";
+     145             :     }
+     146             :   }
+     147             :   //
+     148         180 :   if(keywords.exists("BIAS_FILE_FMT")) {
+     149           0 :     parse("BIAS_FILE_FMT",bias_file_fmt_);
+     150             :   }
+     151         180 :   if(keywords.exists("FES_FILE_FMT")) {
+     152           0 :     parse("FES_FILE_FMT",fes_file_fmt_);
+     153             :   }
+     154         180 :   if(keywords.exists("TARGETDIST_FILE_FMT")) {
+     155           0 :     parse("TARGETDIST_FILE_FMT",targetdist_file_fmt_);
+     156             :   }
+     157         180 :   if(keywords.exists("TARGETDIST_RESTART_FILE_FMT")) {
+     158           0 :     parse("TARGETDIST_RESTART_FILE_FMT",targetdist_restart_file_fmt_);
+     159             :   }
+     160             : 
+     161             :   //
+     162         180 :   if(keywords.exists("BIAS_CUTOFF")) {
+     163          90 :     double cutoff_value=0.0;
+     164          90 :     parse("BIAS_CUTOFF",cutoff_value);
+     165          90 :     if(cutoff_value<0.0) {
+     166           0 :       plumed_merror("the value given in BIAS_CUTOFF doesn't make sense, it should be larger than 0.0");
+     167             :     }
+     168             :     //
+     169          90 :     if(cutoff_value>0.0) {
+     170           3 :       double fermi_lambda=10.0;
+     171           3 :       parse("BIAS_CUTOFF_FERMI_LAMBDA",fermi_lambda);
+     172           3 :       setupBiasCutoff(cutoff_value,fermi_lambda);
+     173           3 :       log.printf("  Employing a bias cutoff of %f (the lambda value for the Fermi switching function is %f), see and cite ",cutoff_value,fermi_lambda);
+     174           6 :       log << plumed.cite("McCarty, Valsson, Tiwary, and Parrinello, Phys. Rev. Lett. 115, 070601 (2015)");
+     175           3 :       log.printf("\n");
+     176             :     }
+     177             :   }
+     178             : 
+     179             : 
+     180         180 :   if(keywords.exists("PROJ_ARG")) {
+     181             :     std::vector<std::string> proj_arg;
+     182          90 :     for(int i=1;; i++) {
+     183         212 :       if(!parseNumberedVector("PROJ_ARG",i,proj_arg)) {break;}
+     184             :       // checks
+     185          16 :       if(proj_arg.size() > (getNumberOfArguments()-1) ) {
+     186           0 :         plumed_merror("PROJ_ARG must be a subset of ARG");
+     187             :       }
+     188             :       //
+     189          32 :       for(unsigned int k=0; k<proj_arg.size(); k++) {
+     190             :         bool found = false;
+     191          24 :         for(unsigned int l=0; l<getNumberOfArguments(); l++) {
+     192          24 :           if(proj_arg[k]==getPntrToArgument(l)->getName()) {
+     193             :             found = true;
+     194             :             break;
+     195             :           }
+     196             :         }
+     197          16 :         if(!found) {
+     198           0 :           std::string s1; Tools::convert(i,s1);
+     199           0 :           std::string error = "PROJ_ARG" + s1 + ": label " + proj_arg[k] + " is not among the arguments given in ARG";
+     200           0 :           plumed_merror(error);
+     201             :         }
+     202             :       }
+     203             :       //
+     204          16 :       projection_args_.push_back(proj_arg);
+     205          16 :     }
+     206          90 :   }
+     207             : 
+     208         180 :   if(keywords.exists("CALC_REWEIGHT_FACTOR")) {
+     209           0 :     parseFlag("CALC_REWEIGHT_FACTOR",calc_reweightfactor_);
+     210           0 :     if(calc_reweightfactor_) {
+     211           0 :       addComponent("rct"); componentIsNotPeriodic("rct");
+     212           0 :       updateReweightFactor();
+     213             :     }
+     214             :   }
+     215             : 
+     216         180 :   if(keywords.exists("OPTIMIZATION_THRESHOLD")) {
+     217          90 :     parse("OPTIMIZATION_THRESHOLD",optimization_threshold_);
+     218          90 :     if(optimization_threshold_ < 0.0) {
+     219           0 :       plumed_merror("OPTIMIZATION_THRESHOLD should be a postive value");
+     220             :     }
+     221          90 :     if(optimization_threshold_!=0.0) {
+     222           1 :       log.printf("  Employing a threshold value of %e for optimization of localized basis functions.\n",optimization_threshold_);
+     223             :     }
+     224             :   }
+     225             : 
+     226          90 : }
+     227             : 
+     228             : 
+     229          90 : VesBias::~VesBias() {
+     230         180 : }
+     231             : 
+     232             : 
+     233          92 : void VesBias::registerKeywords( Keywords& keys ) {
+     234          92 :   Bias::registerKeywords(keys);
+     235         184 :   keys.add("optional","TEMP","the system temperature - this is needed if the MD code does not pass the temperature to PLUMED.");
+     236             :   //
+     237         184 :   keys.reserve("optional","COEFFS","read in the coefficients from files.");
+     238             :   //
+     239         184 :   keys.reserve("optional","TARGET_DISTRIBUTION","the label of the target distribution to be used.");
+     240         184 :   keys.reserve("optional","TARGET_DISTRIBUTIONS","the label of the target distribution to be used. Here you are allows to use multiple labels.");
+     241             :   //
+     242         184 :   keys.reserve("optional","GRID_BINS","the number of bins used for the grid. The default value is 100 bins per dimension.");
+     243         184 :   keys.reserve("optional","GRID_MIN","the lower bounds used for the grid.");
+     244         184 :   keys.reserve("optional","GRID_MAX","the upper bounds used for the grid.");
+     245             :   //
+     246         184 :   keys.add("optional","BIAS_FILE","filename of the file on which the bias should be written out. By default it is bias.LABEL.data. Note that suffixes indicating the iteration number (iter-#) are added to the filename when optimizing coefficients.");
+     247         184 :   keys.add("optional","FES_FILE","filename of the file on which the FES should be written out. By default it is fes.LABEL.data. Note that suffixes indicating the iteration number (iter-#) are added to the filename when optimizing coefficients.");
+     248         184 :   keys.add("optional","TARGETDIST_FILE","filename of the file on which the target distribution should be written out. By default it is targetdist.LABEL.data. Note that suffixes indicating the iteration number (iter-#) are added to the filename when optimizing coefficients and the target distribution is dynamic.");
+     249             :   //
+     250             :   // keys.add("optional","BIAS_FILE_FMT","the format of the bias files, by default it is %14.9f.");
+     251             :   // keys.add("optional","FES_FILE_FMT","the format of the FES files, by default it is %14.9f.");
+     252             :   // keys.add("optional","TARGETDIST_FILE_FMT","the format of the target distribution files, by default it is %14.9f.");
+     253             :   // keys.add("hidden","TARGETDIST_RESTART_FILE_FMT","the format of the target distribution files that are used for restarting, by default it is %30.16e.");
+     254             :   //
+     255         184 :   keys.reserve("optional","BIAS_CUTOFF","cutoff the bias such that it only fills the free energy surface up to certain level F_cutoff, here you should give the value of the F_cutoff.");
+     256         184 :   keys.reserve("optional","BIAS_CUTOFF_FERMI_LAMBDA","the lambda value used in the Fermi switching function for the bias cutoff (BIAS_CUTOFF), the default value is 10.0.");
+     257             :   //
+     258         184 :   keys.reserve("numbered","PROJ_ARG","arguments for doing projections of the FES or the target distribution.");
+     259             :   //
+     260         184 :   keys.reserveFlag("CALC_REWEIGHT_FACTOR",false,"enable the calculation of the reweight factor c(t). You should also give a stride for updating the reweight factor in the optimizer by using the REWEIGHT_FACTOR_STRIDE keyword if the coefficients are updated.");
+     261         184 :   keys.add("optional","OPTIMIZATION_THRESHOLD","Threshold value to turn off optimization of localized basis functions.");
+     262             : 
+     263          92 : }
+     264             : 
+     265             : 
+     266          92 : void VesBias::useInitialCoeffsKeywords(Keywords& keys) {
+     267          92 :   keys.use("COEFFS");
+     268          92 : }
+     269             : 
+     270             : 
+     271          92 : void VesBias::useTargetDistributionKeywords(Keywords& keys) {
+     272         184 :   plumed_massert(!keys.exists("TARGET_DISTRIBUTIONS"),"you cannot use both useTargetDistributionKeywords and useMultipleTargetDistributionKeywords");
+     273          92 :   keys.use("TARGET_DISTRIBUTION");
+     274          92 : }
+     275             : 
+     276             : 
+     277           0 : void VesBias::useMultipleTargetDistributionKeywords(Keywords& keys) {
+     278           0 :   plumed_massert(!keys.exists("TARGET_DISTRIBUTION"),"you cannot use both useTargetDistributionKeywords and useMultipleTargetDistributionKeywords");
+     279           0 :   keys.use("TARGET_DISTRIBUTIONS");
+     280           0 : }
+     281             : 
+     282             : 
+     283          92 : void VesBias::useGridBinKeywords(Keywords& keys) {
+     284          92 :   keys.use("GRID_BINS");
+     285          92 : }
+     286             : 
+     287             : 
+     288           0 : void VesBias::useGridLimitsKeywords(Keywords& keys) {
+     289           0 :   keys.use("GRID_MIN");
+     290           0 :   keys.use("GRID_MAX");
+     291           0 : }
+     292             : 
+     293             : 
+     294          92 : void VesBias::useBiasCutoffKeywords(Keywords& keys) {
+     295          92 :   keys.use("BIAS_CUTOFF");
+     296          92 :   keys.use("BIAS_CUTOFF_FERMI_LAMBDA");
+     297          92 : }
+     298             : 
+     299             : 
+     300          92 : void VesBias::useProjectionArgKeywords(Keywords& keys) {
+     301          92 :   keys.use("PROJ_ARG");
+     302          92 : }
+     303             : 
+     304             : 
+     305           0 : void VesBias::useReweightFactorKeywords(Keywords& keys) {
+     306           0 :   keys.use("CALC_REWEIGHT_FACTOR");
+     307           0 :   keys.addOutputComponent("rct","CALC_REWEIGHT_FACTOR","the reweight factor c(t).");
+     308           0 : }
+     309             : 
+     310             : 
+     311           0 : void VesBias::addCoeffsSet(const std::vector<std::string>& dimension_labels,const std::vector<unsigned int>& indices_shape) {
+     312           0 :   auto coeffs_pntr_tmp = Tools::make_unique<CoeffsVector>("coeffs",dimension_labels,indices_shape,comm,true);
+     313           0 :   initializeCoeffs(std::move(coeffs_pntr_tmp));
+     314           0 : }
+     315             : 
+     316             : 
+     317          90 : void VesBias::addCoeffsSet(std::vector<Value*>& args,std::vector<BasisFunctions*>& basisf) {
+     318          90 :   auto coeffs_pntr_tmp = Tools::make_unique<CoeffsVector>("coeffs",args,basisf,comm,true);
+     319          90 :   initializeCoeffs(std::move(coeffs_pntr_tmp));
+     320          90 : }
+     321             : 
+     322             : 
+     323           0 : void VesBias::addCoeffsSet(std::unique_ptr<CoeffsVector> coeffs_pntr_in) {
+     324           0 :   initializeCoeffs(std::move(coeffs_pntr_in));
+     325           0 : }
+     326             : 
+     327             : 
+     328          90 : void VesBias::initializeCoeffs(std::unique_ptr<CoeffsVector> coeffs_pntr_in) {
+     329             :   //
+     330          90 :   coeffs_pntr_in->linkVesBias(this);
+     331             :   //
+     332             :   std::string label;
+     333          90 :   if(!use_multiple_coeffssets_ && ncoeffssets_==1) {
+     334           0 :     plumed_merror("you are not allowed to use multiple coefficient sets");
+     335             :   }
+     336             :   //
+     337         180 :   label = getCoeffsSetLabelString("coeffs",ncoeffssets_);
+     338          90 :   coeffs_pntr_in->setLabels(label);
+     339             : 
+     340          90 :   coeffs_pntrs_.emplace_back(std::move(coeffs_pntr_in));
+     341             :   auto aver_ps_tmp = Tools::make_unique<CoeffsVector>(*coeffs_pntrs_.back());
+     342         180 :   label = getCoeffsSetLabelString("targetdist_averages",ncoeffssets_);
+     343          90 :   aver_ps_tmp->setLabels(label);
+     344          90 :   aver_ps_tmp->setValues(0.0);
+     345          90 :   targetdist_averages_pntrs_.emplace_back(std::move(aver_ps_tmp));
+     346             :   //
+     347             :   auto gradient_tmp = Tools::make_unique<CoeffsVector>(*coeffs_pntrs_.back());
+     348         180 :   label = getCoeffsSetLabelString("gradient",ncoeffssets_);
+     349          90 :   gradient_tmp->setLabels(label);
+     350          90 :   gradient_pntrs_.emplace_back(std::move(gradient_tmp));
+     351             :   //
+     352         180 :   label = getCoeffsSetLabelString("hessian",ncoeffssets_);
+     353          90 :   auto hessian_tmp = Tools::make_unique<CoeffsMatrix>(label,coeffs_pntrs_.back().get(),comm,diagonal_hessian_);
+     354             : 
+     355          90 :   hessian_pntrs_.emplace_back(std::move(hessian_tmp));
+     356             :   //
+     357             :   std::vector<double> aver_sampled_tmp;
+     358          90 :   aver_sampled_tmp.assign(coeffs_pntrs_.back()->numberOfCoeffs(),0.0);
+     359          90 :   sampled_averages.push_back(aver_sampled_tmp);
+     360             :   //
+     361             :   std::vector<double> cross_aver_sampled_tmp;
+     362          90 :   cross_aver_sampled_tmp.assign(hessian_pntrs_.back()->getSize(),0.0);
+     363          90 :   sampled_cross_averages.push_back(cross_aver_sampled_tmp);
+     364             :   //
+     365          90 :   aver_counters.push_back(0);
+     366             :   //
+     367          90 :   ncoeffssets_++;
+     368         180 : }
+     369             : 
+     370             : 
+     371          90 : bool VesBias::readCoeffsFromFiles() {
+     372          90 :   plumed_assert(ncoeffssets_>0);
+     373         180 :   plumed_massert(keywords.exists("COEFFS"),"you are not allowed to use this function as the COEFFS keyword is not enabled");
+     374             :   bool read_coeffs = false;
+     375          90 :   if(coeffs_fnames.size()>0) {
+     376           4 :     plumed_massert(coeffs_fnames.size()==ncoeffssets_,"COEFFS keyword is of the wrong size");
+     377           4 :     if(ncoeffssets_==1) {
+     378           4 :       log.printf("  Read in coefficients from file ");
+     379             :     }
+     380             :     else {
+     381           0 :       log.printf("  Read in coefficients from files:\n");
+     382             :     }
+     383           8 :     for(unsigned int i=0; i<ncoeffssets_; i++) {
+     384           4 :       IFile ifile;
+     385           4 :       ifile.link(*this);
+     386           4 :       ifile.open(coeffs_fnames[i]);
+     387           8 :       if(!ifile.FieldExist(coeffs_pntrs_[i]->getDataLabel())) {
+     388           0 :         std::string error_msg = "Problem with reading coefficients from file " + ifile.getPath() + ": no field with name " + coeffs_pntrs_[i]->getDataLabel() + "\n";
+     389           0 :         plumed_merror(error_msg);
+     390             :       }
+     391           4 :       size_t ncoeffs_read = coeffs_pntrs_[i]->readFromFile(ifile,false,false);
+     392           4 :       coeffs_pntrs_[i]->setIterationCounterAndTime(0,getTime());
+     393           4 :       if(ncoeffssets_==1) {
+     394           8 :         log.printf("%s (read %zu of %zu values)\n", ifile.getPath().c_str(),ncoeffs_read,coeffs_pntrs_[i]->numberOfCoeffs());
+     395             :       }
+     396             :       else {
+     397           0 :         log.printf("   coefficient %u: %s (read %zu of %zu values)\n",i,ifile.getPath().c_str(),ncoeffs_read,coeffs_pntrs_[i]->numberOfCoeffs());
+     398             :       }
+     399           4 :       ifile.close();
+     400           4 :     }
+     401             :     read_coeffs = true;
+     402             :   }
+     403          90 :   return read_coeffs;
+     404             : }
+     405             : 
+     406             : 
+     407       22810 : void VesBias::updateGradientAndHessian(const bool use_mwalkers_mpi) {
+     408       45620 :   for(unsigned int k=0; k<ncoeffssets_; k++) {
+     409             :     //
+     410       22810 :     comm.Sum(sampled_averages[k]);
+     411       22810 :     comm.Sum(sampled_cross_averages[k]);
+     412       22810 :     if(use_mwalkers_mpi) {
+     413             :       double walker_weight=1.0;
+     414         120 :       if(aver_counters[k]==0) {walker_weight=0.0;}
+     415         120 :       multiSimSumAverages(k,walker_weight);
+     416             :     }
+     417             :     // NOTE: this assumes that all walkers have the same TargetDist, might change later on!!
+     418       22810 :     Gradient(k).setValues( TargetDistAverages(k) - sampled_averages[k] );
+     419       22810 :     Hessian(k) = computeCovarianceFromAverages(k);
+     420       22810 :     Hessian(k) *= getBeta();
+     421             : 
+     422       22810 :     if(optimization_threshold_ != 0.0) {
+     423         390 :       for(size_t c_id=0; c_id < sampled_averages[k].size(); ++c_id) {
+     424         380 :         if(fabs(sampled_averages[k][c_id]) < optimization_threshold_) {
+     425         219 :           Gradient(k).setValue(c_id, 0.0);
+     426         219 :           Hessian(k).setValue(c_id, c_id, 0.0);
+     427             :         }
+     428             :       }
+     429             :     }
+     430             :     //
+     431             :     Gradient(k).activate();
+     432             :     Hessian(k).activate();
+     433             :     //
+     434             :     // Check the total number of samples (from all walkers) and deactivate the Gradient and Hessian if it
+     435             :     // is zero
+     436       22810 :     unsigned int total_samples = aver_counters[k];
+     437       22810 :     if(use_mwalkers_mpi) {
+     438         120 :       if(comm.Get_rank()==0) {multi_sim_comm.Sum(total_samples);}
+     439         120 :       comm.Bcast(total_samples,0);
+     440             :     }
+     441       22810 :     if(total_samples==0) {
+     442             :       Gradient(k).deactivate();
+     443          95 :       Gradient(k).clear();
+     444             :       Hessian(k).deactivate();
+     445          95 :       Hessian(k).clear();
+     446             :     }
+     447             :     //
+     448             :     std::fill(sampled_averages[k].begin(), sampled_averages[k].end(), 0.0);
+     449             :     std::fill(sampled_cross_averages[k].begin(), sampled_cross_averages[k].end(), 0.0);
+     450       22810 :     aver_counters[k]=0;
+     451             :   }
+     452       22810 : }
+     453             : 
+     454             : 
+     455         120 : void VesBias::multiSimSumAverages(const unsigned int c_id, const double walker_weight) {
+     456         120 :   plumed_massert(walker_weight>=0.0,"the weight of the walker cannot be negative!");
+     457         120 :   if(walker_weight!=1.0) {
+     458        7860 :     for(size_t i=0; i<sampled_averages[c_id].size(); i++) {
+     459        7800 :       sampled_averages[c_id][i] *= walker_weight;
+     460             :     }
+     461        7860 :     for(size_t i=0; i<sampled_cross_averages[c_id].size(); i++) {
+     462        7800 :       sampled_cross_averages[c_id][i] *= walker_weight;
+     463             :     }
+     464             :   }
+     465             :   //
+     466         120 :   if(comm.Get_rank()==0) {
+     467         120 :     multi_sim_comm.Sum(sampled_averages[c_id]);
+     468         120 :     multi_sim_comm.Sum(sampled_cross_averages[c_id]);
+     469         120 :     double norm_weights = walker_weight;
+     470         120 :     multi_sim_comm.Sum(norm_weights);
+     471         120 :     if(norm_weights>0.0) {norm_weights=1.0/norm_weights;}
+     472        8580 :     for(size_t i=0; i<sampled_averages[c_id].size(); i++) {
+     473        8460 :       sampled_averages[c_id][i] *= norm_weights;
+     474             :     }
+     475        8580 :     for(size_t i=0; i<sampled_cross_averages[c_id].size(); i++) {
+     476        8460 :       sampled_cross_averages[c_id][i] *= norm_weights;
+     477             :     }
+     478             :   }
+     479         120 :   comm.Bcast(sampled_averages[c_id],0);
+     480         120 :   comm.Bcast(sampled_cross_averages[c_id],0);
+     481         120 : }
+     482             : 
+     483             : 
+     484       23556 : void VesBias::addToSampledAverages(const std::vector<double>& values, const unsigned int c_id) {
+     485             :   /*
+     486             :   use the following online equation to calculate the average and covariance
+     487             :   (see https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#Covariance)
+     488             :       xm[n+1] = xm[n] + (x[n+1]-xm[n])/(n+1)
+     489             :   */
+     490       23556 :   double counter_dbl = static_cast<double>(aver_counters[c_id]);
+     491             :   size_t ncoeffs = numberOfCoeffs(c_id);
+     492       23556 :   std::vector<double> deltas(ncoeffs,0.0);
+     493       23556 :   size_t stride = comm.Get_size();
+     494       23556 :   size_t rank = comm.Get_rank();
+     495             :   // update average and diagonal part of Hessian
+     496     1830228 :   for(size_t i=rank; i<ncoeffs; i+=stride) {
+     497             :     size_t midx = getHessianIndex(i,i,c_id);
+     498     1806672 :     deltas[i] = (values[i]-sampled_averages[c_id][i])/(counter_dbl+1); // (x[n+1]-xm[n])/(n+1)
+     499     1806672 :     sampled_averages[c_id][i] += deltas[i];
+     500     1806672 :     sampled_cross_averages[c_id][midx] += (values[i]*values[i]-sampled_cross_averages[c_id][midx])/(counter_dbl+1);
+     501             :   }
+     502       23556 :   comm.Sum(deltas);
+     503             :   // update off-diagonal part of the Hessian
+     504       23556 :   if(!diagonal_hessian_) {
+     505           0 :     for(size_t i=rank; i<ncoeffs; i+=stride) {
+     506           0 :       for(size_t j=(i+1); j<ncoeffs; j++) {
+     507             :         size_t midx = getHessianIndex(i,j,c_id);
+     508           0 :         sampled_cross_averages[c_id][midx] += (values[i]*values[j]-sampled_cross_averages[c_id][midx])/(counter_dbl+1);
+     509             :       }
+     510             :     }
+     511             :   }
+     512             :   // NOTE: the MPI sum for sampled_averages and sampled_cross_averages is done later
+     513       23556 :   aver_counters[c_id] += 1;
+     514       23556 : }
+     515             : 
+     516             : 
+     517           0 : void VesBias::setTargetDistAverages(const std::vector<double>& coeffderivs_aver_ps, const unsigned int coeffs_id) {
+     518           0 :   TargetDistAverages(coeffs_id) = coeffderivs_aver_ps;
+     519           0 :   TargetDistAverages(coeffs_id).setIterationCounterAndTime(this->getIterationCounter(),this->getTime());
+     520           0 : }
+     521             : 
+     522             : 
+     523         453 : void VesBias::setTargetDistAverages(const CoeffsVector& coeffderivs_aver_ps, const unsigned int coeffs_id) {
+     524         453 :   TargetDistAverages(coeffs_id).setValues( coeffderivs_aver_ps );
+     525         453 :   TargetDistAverages(coeffs_id).setIterationCounterAndTime(this->getIterationCounter(),this->getTime());
+     526         453 : }
+     527             : 
+     528             : 
+     529           0 : void VesBias::setTargetDistAveragesToZero(const unsigned int coeffs_id) {
+     530           0 :   TargetDistAverages(coeffs_id).setAllValuesToZero();
+     531           0 :   TargetDistAverages(coeffs_id).setIterationCounterAndTime(this->getIterationCounter(),this->getTime());
+     532           0 : }
+     533             : 
+     534             : 
+     535         175 : void VesBias::checkThatTemperatureIsGiven() {
+     536         175 :   if(kbt_==0.0) {
+     537           0 :     std::string err_msg = "VES bias " + getLabel() + " of type " + getName() + ": the temperature is needed so you need to give it using the TEMP keyword as the MD engine does not pass it to PLUMED.";
+     538           0 :     plumed_merror(err_msg);
+     539             :   }
+     540         175 : }
+     541             : 
+     542             : 
+     543        1005 : unsigned int VesBias::getIterationCounter() const {
+     544             :   unsigned int iteration = 0;
+     545        1005 :   if(optimizeCoeffs()) {
+     546             :     iteration = getOptimizerPntr()->getIterationCounter();
+     547             :   }
+     548             :   else {
+     549         113 :     iteration = getCoeffsPntrs()[0]->getIterationCounter();
+     550             :   }
+     551        1005 :   return iteration;
+     552             : }
+     553             : 
+     554             : 
+     555          85 : void VesBias::linkOptimizer(Optimizer* optimizer_pntr_in) {
+     556             :   //
+     557          85 :   if(optimizer_pntr_==NULL) {
+     558          85 :     optimizer_pntr_ = optimizer_pntr_in;
+     559             :   }
+     560             :   else {
+     561           0 :     std::string err_msg = "VES bias " + getLabel() + " of type " + getName() + " has already been linked with optimizer " + optimizer_pntr_->getLabel() + " of type " + optimizer_pntr_->getName() + ". You cannot link two optimizer to the same VES bias.";
+     562           0 :     plumed_merror(err_msg);
+     563             :   }
+     564          85 :   checkThatTemperatureIsGiven();
+     565          85 :   optimize_coeffs_ = true;
+     566          85 :   filenames_have_iteration_number_ = true;
+     567          85 : }
+     568             : 
+     569             : 
+     570          82 : void VesBias::enableHessian(const bool diagonal_hessian) {
+     571          82 :   compute_hessian_=true;
+     572          82 :   diagonal_hessian_=diagonal_hessian;
+     573          82 :   sampled_cross_averages.clear();
+     574         164 :   for (unsigned int i=0; i<ncoeffssets_; i++) {
+     575          82 :     std::string label = getCoeffsSetLabelString("hessian",i);
+     576         164 :     hessian_pntrs_[i] = Tools::make_unique<CoeffsMatrix>(label,coeffs_pntrs_[i].get(),comm,diagonal_hessian_);
+     577             :     //
+     578             :     std::vector<double> cross_aver_sampled_tmp;
+     579          82 :     cross_aver_sampled_tmp.assign(hessian_pntrs_[i]->getSize(),0.0);
+     580          82 :     sampled_cross_averages.push_back(cross_aver_sampled_tmp);
+     581             :   }
+     582          82 : }
+     583             : 
+     584             : 
+     585           0 : void VesBias::disableHessian() {
+     586           0 :   compute_hessian_=false;
+     587           0 :   diagonal_hessian_=true;
+     588           0 :   sampled_cross_averages.clear();
+     589           0 :   for (unsigned int i=0; i<ncoeffssets_; i++) {
+     590           0 :     std::string label = getCoeffsSetLabelString("hessian",i);
+     591           0 :     hessian_pntrs_[i] = Tools::make_unique<CoeffsMatrix>(label,coeffs_pntrs_[i].get(),comm,diagonal_hessian_);
+     592             :     //
+     593             :     std::vector<double> cross_aver_sampled_tmp;
+     594           0 :     cross_aver_sampled_tmp.assign(hessian_pntrs_[i]->getSize(),0.0);
+     595           0 :     sampled_cross_averages.push_back(cross_aver_sampled_tmp);
+     596             :   }
+     597           0 : }
+     598             : 
+     599             : 
+     600         442 : std::string VesBias::getCoeffsSetLabelString(const std::string& type, const unsigned int coeffs_id) const {
+     601         442 :   std::string label_prefix = getLabel() + ".";
+     602         442 :   std::string label_postfix = "";
+     603         442 :   if(use_multiple_coeffssets_) {
+     604           0 :     Tools::convert(coeffs_id,label_postfix);
+     605           0 :     label_postfix = "-" + label_postfix;
+     606             :   }
+     607        1326 :   return label_prefix+type+label_postfix;
+     608             : }
+     609             : 
+     610             : 
+     611         567 : std::unique_ptr<OFile> VesBias::getOFile(const std::string& filepath, const bool multi_sim_single_file, const bool enforce_backup) {
+     612             :   auto ofile_pntr = Tools::make_unique<OFile>();
+     613         567 :   std::string fp = filepath;
+     614         567 :   ofile_pntr->link(*static_cast<Action*>(this));
+     615         567 :   if(enforce_backup) {ofile_pntr->enforceBackup();}
+     616         567 :   if(multi_sim_single_file) {
+     617          56 :     unsigned int r=0;
+     618          56 :     if(comm.Get_rank()==0) {r=multi_sim_comm.Get_rank();}
+     619          56 :     comm.Bcast(r,0);
+     620          56 :     if(r>0) {fp="/dev/null";}
+     621         112 :     ofile_pntr->enforceSuffix("");
+     622             :   }
+     623         567 :   ofile_pntr->open(fp);
+     624         567 :   return ofile_pntr;
+     625           0 : }
+     626             : 
+     627             : 
+     628           0 : void VesBias::setGridBins(const std::vector<unsigned int>& grid_bins_in) {
+     629           0 :   plumed_massert(grid_bins_in.size()==getNumberOfArguments(),"the number of grid bins given doesn't match the number of arguments");
+     630           0 :   grid_bins_=grid_bins_in;
+     631           0 : }
+     632             : 
+     633             : 
+     634           0 : void VesBias::setGridBins(const unsigned int nbins) {
+     635           0 :   std::vector<unsigned int> grid_bins_in(getNumberOfArguments(),nbins);
+     636           0 :   grid_bins_=grid_bins_in;
+     637           0 : }
+     638             : 
+     639             : 
+     640           0 : void VesBias::setGridMin(const std::vector<double>& grid_min_in) {
+     641           0 :   plumed_massert(grid_min_in.size()==getNumberOfArguments(),"the number of lower bounds given for the grid doesn't match the number of arguments");
+     642           0 :   grid_min_=grid_min_in;
+     643           0 : }
+     644             : 
+     645             : 
+     646           0 : void VesBias::setGridMax(const std::vector<double>& grid_max_in) {
+     647           0 :   plumed_massert(grid_max_in.size()==getNumberOfArguments(),"the number of upper bounds given for the grid doesn't match the number of arguments");
+     648           0 :   grid_max_=grid_max_in;
+     649           0 : }
+     650             : 
+     651             : 
+     652         383 : std::string VesBias::getCurrentOutputFilename(const std::string& base_filename, const std::string& suffix) const {
+     653         383 :   std::string filename = base_filename;
+     654         383 :   if(suffix.size()>0) {
+     655          82 :     filename = FileBase::appendSuffix(filename,"."+suffix);
+     656             :   }
+     657         383 :   if(filenamesIncludeIterationNumber()) {
+     658         756 :     filename = FileBase::appendSuffix(filename,"."+getIterationFilenameSuffix());
+     659             :   }
+     660         383 :   return filename;
+     661             : }
+     662             : 
+     663             : 
+     664         192 : std::string VesBias::getCurrentTargetDistOutputFilename(const std::string& suffix) const {
+     665         192 :   std::string filename = targetdist_filename_;
+     666         192 :   if(suffix.size()>0) {
+     667         204 :     filename = FileBase::appendSuffix(filename,"."+suffix);
+     668             :   }
+     669         192 :   if(filenamesIncludeIterationNumber() && dynamicTargetDistribution()) {
+     670         348 :     filename = FileBase::appendSuffix(filename,"."+getIterationFilenameSuffix());
+     671             :   }
+     672         192 :   return filename;
+     673             : }
+     674             : 
+     675             : 
+     676         552 : std::string VesBias::getIterationFilenameSuffix() const {
+     677             :   std::string iter_str;
+     678         552 :   Tools::convert(getIterationCounter(),iter_str);
+     679         552 :   iter_str = "iter-" + iter_str;
+     680         552 :   return iter_str;
+     681             : }
+     682             : 
+     683             : 
+     684           0 : std::string VesBias::getCoeffsSetFilenameSuffix(const unsigned int coeffs_id) const {
+     685           0 :   std::string suffix = "";
+     686           0 :   if(use_multiple_coeffssets_) {
+     687           0 :     Tools::convert(coeffs_id,suffix);
+     688           0 :     suffix = coeffs_id_prefix_ + suffix;
+     689             :   }
+     690           0 :   return suffix;
+     691             : }
+     692             : 
+     693             : 
+     694           3 : void VesBias::setupBiasCutoff(const double bias_cutoff_value, const double fermi_lambda) {
+     695             :   //
+     696             :   double fermi_exp_max = 100.0;
+     697             :   //
+     698             :   std::string str_bias_cutoff_value; VesTools::convertDbl2Str(bias_cutoff_value,str_bias_cutoff_value);
+     699             :   std::string str_fermi_lambda; VesTools::convertDbl2Str(fermi_lambda,str_fermi_lambda);
+     700             :   std::string str_fermi_exp_max; VesTools::convertDbl2Str(fermi_exp_max,str_fermi_exp_max);
+     701           6 :   std::string swfunc_keywords = "FERMI R_0=" + str_bias_cutoff_value + " FERMI_LAMBDA=" + str_fermi_lambda + " FERMI_EXP_MAX=" + str_fermi_exp_max;
+     702             :   //
+     703           3 :   std::string swfunc_errors="";
+     704           3 :   bias_cutoff_swfunc_pntr_ = Tools::make_unique<FermiSwitchingFunction>();
+     705           3 :   bias_cutoff_swfunc_pntr_->set(swfunc_keywords,swfunc_errors);
+     706           3 :   if(swfunc_errors.size()>0) {
+     707           0 :     plumed_merror("problem with setting up Fermi switching function: " + swfunc_errors);
+     708             :   }
+     709             :   //
+     710           3 :   bias_cutoff_value_=bias_cutoff_value;
+     711           3 :   bias_cutoff_active_=true;
+     712             :   enableDynamicTargetDistribution();
+     713           3 : }
+     714             : 
+     715             : 
+     716        3263 : double VesBias::getBiasCutoffSwitchingFunction(const double bias, double& deriv_factor) const {
+     717        3263 :   plumed_massert(bias_cutoff_active_,"The bias cutoff is not active so you cannot call this function");
+     718        3263 :   double arg = -(bias-bias_current_max_value);
+     719        3263 :   double deriv=0.0;
+     720        3263 :   double value = bias_cutoff_swfunc_pntr_->calculate(arg,deriv);
+     721             :   // as FermiSwitchingFunction class has different behavior from normal SwitchingFunction class
+     722             :   // I was having problems with NaN as it was dividing with zero
+     723             :   // deriv *= arg;
+     724        3263 :   deriv_factor = value-bias*deriv;
+     725        3263 :   return value;
+     726             : }
+     727             : 
+     728             : 
+     729         567 : bool VesBias::useMultipleWalkers() const {
+     730             :   bool use_mwalkers_mpi=false;
+     731         567 :   if(optimizeCoeffs() && getOptimizerPntr()->useMultipleWalkers()) {
+     732             :     use_mwalkers_mpi=true;
+     733             :   }
+     734         567 :   return use_mwalkers_mpi;
+     735             : }
+     736             : 
+     737             : 
+     738           0 : void VesBias::updateReweightFactor() {
+     739           0 :   if(calc_reweightfactor_) {
+     740           0 :     double value = calculateReweightFactor();
+     741           0 :     getPntrToComponent("rct")->set(value);
+     742             :   }
+     743           0 : }
+     744             : 
+     745             : 
+     746           0 : double VesBias::calculateReweightFactor() const {
+     747           0 :   plumed_merror(getName()+" with label "+getLabel()+": calculation of the reweight factor c(t) has not been implemented for this type of VES bias");
+     748             :   return 0.0;
+     749             : }
+     750             : 
+     751             : 
+     752             : }
+     753             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/VesBias.h.func-sort-c.html b/coverage/ves/VesBias.h.func-sort-c.html new file mode 100644 index 000000000000..f984c4abf115 --- /dev/null +++ b/coverage/ves/VesBias.h.func-sort-c.html @@ -0,0 +1,173 @@ + + + + + + + + LCOV - plumed test coverage - ves/VesBias.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - VesBias.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:668974.2 %
Date:2024-04-19 12:12:35Functions:92536.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves7VesBias14writeFesToFileEv0
_ZN4PLMD3ves7VesBias15writeBiasToFileEv0
_ZN4PLMD3ves7VesBias18resetFesFileOutputEv0
_ZN4PLMD3ves7VesBias18setupFesFileOutputEv0
_ZN4PLMD3ves7VesBias18writeFesProjToFileEv0
_ZN4PLMD3ves7VesBias19parseMultipleValuesIdEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIT_SaISC_EEj0
_ZN4PLMD3ves7VesBias19resetBiasFileOutputEv0
_ZN4PLMD3ves7VesBias19setupBiasFileOutputEv0
_ZN4PLMD3ves7VesBias21writeTargetDistToFileEv0
_ZN4PLMD3ves7VesBias22resetFesProjFileOutputEv0
_ZN4PLMD3ves7VesBias22setupFesProjFileOutputEv0
_ZN4PLMD3ves7VesBias25resetTargetDistFileOutputEv0
_ZN4PLMD3ves7VesBias25updateTargetDistributionsEv0
_ZN4PLMD3ves7VesBias25writeTargetDistProjToFileEv0
_ZN4PLMD3ves7VesBias26restartTargetDistributionsEv0
_ZN4PLMD3ves7VesBias29resetTargetDistProjFileOutputEv0
_ZN4PLMD3ves7VesBias29setupTargetDistProjFileOutputEv9
_ZN4PLMD3ves7VesBias25setupTargetDistFileOutputEv44
_ZN4PLMD3ves7VesBias19parseMultipleValuesINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEbRKS8_RSt6vectorIT_SaISC_EEj90
_ZN4PLMD3ves7VesBias19parseMultipleValuesIjEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIT_SaISC_EEj90
_ZN4PLMD3ves7VesBias19parseMultipleValuesIjEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIT_SaISC_EEjRKSC_90
_ZNK4PLMD3ves7VesBias15applyBiasCutoffERdRSt6vectorIdSaIdEE600
_ZNK4PLMD3ves7VesBias15applyBiasCutoffERdRSt6vectorIdSaIdEES6_663
_ZNK4PLMD3ves7VesBias29computeCovarianceFromAveragesEj22810
_ZNK4PLMD3ves7VesBias7getBetaEv23277
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/VesBias.h.func.html b/coverage/ves/VesBias.h.func.html new file mode 100644 index 000000000000..3c511e1d53c5 --- /dev/null +++ b/coverage/ves/VesBias.h.func.html @@ -0,0 +1,173 @@ + + + + + + + + LCOV - plumed test coverage - ves/VesBias.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - VesBias.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:668974.2 %
Date:2024-04-19 12:12:35Functions:92536.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves7VesBias14writeFesToFileEv0
_ZN4PLMD3ves7VesBias15writeBiasToFileEv0
_ZN4PLMD3ves7VesBias18resetFesFileOutputEv0
_ZN4PLMD3ves7VesBias18setupFesFileOutputEv0
_ZN4PLMD3ves7VesBias18writeFesProjToFileEv0
_ZN4PLMD3ves7VesBias19parseMultipleValuesINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEbRKS8_RSt6vectorIT_SaISC_EEj90
_ZN4PLMD3ves7VesBias19parseMultipleValuesIdEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIT_SaISC_EEj0
_ZN4PLMD3ves7VesBias19parseMultipleValuesIjEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIT_SaISC_EEj90
_ZN4PLMD3ves7VesBias19parseMultipleValuesIjEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIT_SaISC_EEjRKSC_90
_ZN4PLMD3ves7VesBias19resetBiasFileOutputEv0
_ZN4PLMD3ves7VesBias19setupBiasFileOutputEv0
_ZN4PLMD3ves7VesBias21writeTargetDistToFileEv0
_ZN4PLMD3ves7VesBias22resetFesProjFileOutputEv0
_ZN4PLMD3ves7VesBias22setupFesProjFileOutputEv0
_ZN4PLMD3ves7VesBias25resetTargetDistFileOutputEv0
_ZN4PLMD3ves7VesBias25setupTargetDistFileOutputEv44
_ZN4PLMD3ves7VesBias25updateTargetDistributionsEv0
_ZN4PLMD3ves7VesBias25writeTargetDistProjToFileEv0
_ZN4PLMD3ves7VesBias26restartTargetDistributionsEv0
_ZN4PLMD3ves7VesBias29resetTargetDistProjFileOutputEv0
_ZN4PLMD3ves7VesBias29setupTargetDistProjFileOutputEv9
_ZNK4PLMD3ves7VesBias15applyBiasCutoffERdRSt6vectorIdSaIdEE600
_ZNK4PLMD3ves7VesBias15applyBiasCutoffERdRSt6vectorIdSaIdEES6_663
_ZNK4PLMD3ves7VesBias29computeCovarianceFromAveragesEj22810
_ZNK4PLMD3ves7VesBias7getBetaEv23277
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/VesBias.h.gcov.html b/coverage/ves/VesBias.h.gcov.html new file mode 100644 index 000000000000..108ab8a66ae3 --- /dev/null +++ b/coverage/ves/VesBias.h.gcov.html @@ -0,0 +1,492 @@ + + + + + + + + LCOV - plumed test coverage - ves/VesBias.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - VesBias.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:668974.2 %
Date:2024-04-19 12:12:35Functions:92536.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_ves_VesBias_h
+      23             : #define __PLUMED_ves_VesBias_h
+      24             : 
+      25             : #include "CoeffsVector.h"
+      26             : #include "CoeffsMatrix.h"
+      27             : 
+      28             : #include "core/ActionPilot.h"
+      29             : #include "core/ActionWithValue.h"
+      30             : #include "core/ActionWithArguments.h"
+      31             : #include "bias/Bias.h"
+      32             : 
+      33             : #include <vector>
+      34             : #include <string>
+      35             : #include <cmath>
+      36             : #include <memory>
+      37             : 
+      38             : 
+      39             : #define PLUMED_VES_VESBIAS_INIT(ao) Action(ao),VesBias(ao)
+      40             : 
+      41             : namespace PLMD {
+      42             : 
+      43             : class Value;
+      44             : 
+      45             : namespace ves {
+      46             : 
+      47             : class CoeffsVector;
+      48             : class CoeffsMatrix;
+      49             : class BasisFunctions;
+      50             : class Optimizer;
+      51             : class TargetDistribution;
+      52             : class FermiSwitchingFunction;
+      53             : 
+      54             : /**
+      55             : \ingroup INHERIT
+      56             : Abstract base class for implementing biases the extents the normal Bias.h class
+      57             : to include functions related to the variational approach.
+      58             : */
+      59             : 
+      60             : class VesBias:
+      61             :   public bias::Bias
+      62             : {
+      63             : private:
+      64             :   unsigned int ncoeffssets_;
+      65             :   std::vector<std::unique_ptr<CoeffsVector>> coeffs_pntrs_;
+      66             :   std::vector<std::unique_ptr<CoeffsVector>> targetdist_averages_pntrs_;
+      67             :   std::vector<std::unique_ptr<CoeffsVector>> gradient_pntrs_;
+      68             :   std::vector<std::unique_ptr<CoeffsMatrix>> hessian_pntrs_;
+      69             :   std::vector<std::vector<double> > sampled_averages;
+      70             :   std::vector<std::vector<double> > sampled_cross_averages;
+      71             :   bool use_multiple_coeffssets_;
+      72             :   //
+      73             :   std::vector<std::string> coeffs_fnames;
+      74             :   //
+      75             :   size_t ncoeffs_total_;
+      76             :   //
+      77             :   Optimizer* optimizer_pntr_;
+      78             :   bool optimize_coeffs_;
+      79             :   //
+      80             :   bool compute_hessian_;
+      81             :   bool diagonal_hessian_;
+      82             :   //
+      83             :   std::vector<unsigned int> aver_counters;
+      84             :   //
+      85             :   double kbt_;
+      86             :   //
+      87             :   std::vector<TargetDistribution*> targetdist_pntrs_;
+      88             :   bool dynamic_targetdist_;
+      89             :   //
+      90             :   std::vector<unsigned int> grid_bins_;
+      91             :   std::vector<double> grid_min_;
+      92             :   std::vector<double> grid_max_;
+      93             :   //
+      94             :   std::string bias_filename_;
+      95             :   std::string fes_filename_;
+      96             :   std::string targetdist_filename_;
+      97             :   std::string targetdist_averages_filename_;
+      98             :   std::string coeffs_id_prefix_;
+      99             :   //
+     100             :   std::string bias_file_fmt_;
+     101             :   std::string fes_file_fmt_;
+     102             :   std::string targetdist_file_fmt_;
+     103             :   std::string targetdist_restart_file_fmt_;
+     104             :   //
+     105             :   bool filenames_have_iteration_number_;
+     106             :   //
+     107             :   bool bias_fileoutput_active_;
+     108             :   bool fes_fileoutput_active_;
+     109             :   bool fesproj_fileoutput_active_;
+     110             :   bool dynamic_targetdist_fileoutput_active_;
+     111             :   bool static_targetdist_fileoutput_active_;
+     112             :   //
+     113             : 
+     114             :   bool bias_cutoff_active_;
+     115             :   double bias_cutoff_value_;
+     116             :   double bias_current_max_value;
+     117             :   std::unique_ptr<FermiSwitchingFunction> bias_cutoff_swfunc_pntr_;
+     118             :   //
+     119             :   std::vector< std::vector<std::string> > projection_args_;
+     120             :   //
+     121             :   bool calc_reweightfactor_;
+     122             :   //
+     123             :   double optimization_threshold_;
+     124             : private:
+     125             :   void initializeCoeffs(std::unique_ptr<CoeffsVector>);
+     126             :   std::vector<double> computeCovarianceFromAverages(const unsigned int) const;
+     127             :   void multiSimSumAverages(const unsigned int, const double walker_weight=1.0);
+     128             : protected:
+     129             :   //
+     130             :   void checkThatTemperatureIsGiven();
+     131             :   //
+     132             :   void addCoeffsSet(const std::vector<std::string>&,const std::vector<unsigned int>&);
+     133             :   void addCoeffsSet(std::vector<Value*>&,std::vector<BasisFunctions*>&);
+     134             :   void addCoeffsSet(std::unique_ptr<CoeffsVector>);
+     135             :   //
+     136             :   std::string getCoeffsSetLabelString(const std::string&, const unsigned int coeffs_id = 0) const;
+     137             :   void clearCoeffsPntrsVector() {coeffs_pntrs_.clear();}
+     138             :   void addToSampledAverages(const std::vector<double>&, const unsigned int c_id = 0);
+     139             :   void setTargetDistAverages(const std::vector<double>&, const unsigned int coeffs_id = 0);
+     140             :   void setTargetDistAverages(const CoeffsVector&, const unsigned int coeffs_id= 0);
+     141             :   void setTargetDistAveragesToZero(const unsigned int coeffs_id= 0);
+     142             :   //
+     143             :   bool readCoeffsFromFiles();
+     144             :   //
+     145             :   template<class T>
+     146             :   bool parseMultipleValues(const std::string&, std::vector<T>&, unsigned int);
+     147             :   template<class T>
+     148             :   bool parseMultipleValues(const std::string&, std::vector<T>&, unsigned int, const T&);
+     149             :   //
+     150             : public:
+     151             :   static void registerKeywords(Keywords&);
+     152             :   explicit VesBias(const ActionOptions&ao);
+     153             :   ~VesBias();
+     154             :   //
+     155             :   static void useInitialCoeffsKeywords(Keywords&);
+     156             :   static void useTargetDistributionKeywords(Keywords&);
+     157             :   static void useMultipleTargetDistributionKeywords(Keywords&);
+     158             :   static void useGridBinKeywords(Keywords&);
+     159             :   static void useGridLimitsKeywords(Keywords&);
+     160             :   static void useBiasCutoffKeywords(Keywords&);
+     161             :   static void useProjectionArgKeywords(Keywords&);
+     162             :   static void useReweightFactorKeywords(Keywords&);
+     163             :   //
+     164         267 :   std::vector<CoeffsVector*> getCoeffsPntrs() const {return Tools::unique2raw(coeffs_pntrs_);}
+     165          85 :   std::vector<CoeffsVector*> getTargetDistAveragesPntrs() const {return Tools::unique2raw(targetdist_averages_pntrs_);}
+     166          85 :   std::vector<CoeffsVector*> getGradientPntrs()const {return Tools::unique2raw(gradient_pntrs_);}
+     167          82 :   std::vector<CoeffsMatrix*> getHessianPntrs() const {return Tools::unique2raw(hessian_pntrs_);}
+     168          93 :   std::vector<TargetDistribution*> getTargetDistributionPntrs() const {return targetdist_pntrs_;}
+     169             :   //
+     170             :   CoeffsVector* getCoeffsPntr(const unsigned int coeffs_id = 0) const {return coeffs_pntrs_[coeffs_id].get();}
+     171             :   CoeffsVector* getTargetDistAveragesPntr(const unsigned int coeffs_id = 0) const {return targetdist_averages_pntrs_[coeffs_id].get();}
+     172             :   CoeffsVector* getGradientPntr(const unsigned int coeffs_id = 0)const {return gradient_pntrs_[coeffs_id].get();}
+     173             :   CoeffsMatrix* getHessianPntr(const unsigned int coeffs_id = 0) const {return hessian_pntrs_[coeffs_id].get();}
+     174             :   //
+     175          90 :   unsigned int getNumberOfTargetDistributionPntrs() const {return targetdist_pntrs_.size();}
+     176             :   //
+     177       22810 :   size_t numberOfCoeffs(const unsigned int coeffs_id = 0) const {return coeffs_pntrs_[coeffs_id]->numberOfCoeffs();}
+     178             :   size_t totalNumberOfCoeffs() const {return ncoeffs_total_;}
+     179           3 :   unsigned int numberOfCoeffsSets() const {return ncoeffssets_;}
+     180          85 :   double getKbT() const {return kbt_;}
+     181             :   double getBeta() const;
+     182             :   //
+     183             :   CoeffsVector& Coeffs(const unsigned int coeffs_id = 0) const {return *coeffs_pntrs_[coeffs_id];}
+     184         453 :   CoeffsVector& TargetDistAverages(const unsigned int coeffs_id = 0) const {return *targetdist_averages_pntrs_[coeffs_id];}
+     185             :   CoeffsVector& Gradient(const unsigned int coeffs_id = 0) const {return *gradient_pntrs_[coeffs_id];}
+     186             :   CoeffsMatrix& Hessian(const unsigned int coeffs_id = 0) const {return *hessian_pntrs_[coeffs_id];}
+     187             :   //
+     188             :   size_t getCoeffsIndex(const std::vector<unsigned int>& indices, const unsigned int coeffs_id = 0) const;
+     189             :   std::vector<unsigned int> getCoeffsIndices(const size_t index, const unsigned int coeffs_id = 0) const;
+     190             :   size_t getHessianIndex(const size_t index1, const size_t index2, const unsigned int coeffs_id = 0) const;
+     191             :   //
+     192             :   bool computeHessian() const {return compute_hessian_;}
+     193             :   bool diagonalHessian() const {return diagonal_hessian_;}
+     194             :   //
+     195        1572 :   bool optimizeCoeffs() const {return optimize_coeffs_;}
+     196        1426 :   Optimizer* getOptimizerPntr() const {return optimizer_pntr_;}
+     197             :   bool useMultipleWalkers() const;
+     198             :   //
+     199             :   unsigned int getIterationCounter() const;
+     200             :   //
+     201             :   void updateGradientAndHessian(const bool);
+     202             :   void clearGradientAndHessian() {};
+     203             :   //
+     204           0 :   virtual void updateTargetDistributions() {};
+     205           0 :   virtual void restartTargetDistributions() {};
+     206             :   //
+     207             :   void linkOptimizer(Optimizer*);
+     208             :   void enableHessian(const bool diagonal_hessian=true);
+     209             :   void disableHessian();
+     210             :   //
+     211             :   void enableMultipleCoeffsSets() {use_multiple_coeffssets_=true;}
+     212             :   //
+     213          42 :   void enableDynamicTargetDistribution() {dynamic_targetdist_=true;}
+     214             :   void disableDynamicTargetDistribution() {dynamic_targetdist_=false;}
+     215         273 :   bool dynamicTargetDistribution() const {return dynamic_targetdist_;}
+     216             :   //
+     217          90 :   std::vector<unsigned int> getGridBins() const {return grid_bins_;}
+     218             :   void setGridBins(const std::vector<unsigned int>&);
+     219             :   void setGridBins(const unsigned int);
+     220             :   std::vector<double> getGridMax() const {return grid_max_;}
+     221             :   void setGridMax(const std::vector<double>&);
+     222             :   std::vector<double> getGridMin() const {return grid_min_;}
+     223             :   void setGridMin(const std::vector<double>&);
+     224             :   //
+     225         575 :   bool filenamesIncludeIterationNumber() const {return filenames_have_iteration_number_;}
+     226           3 :   void enableIterationNumberInFilenames() {filenames_have_iteration_number_=true;}
+     227             :   //
+     228             :   std::string getIterationFilenameSuffix() const;
+     229             :   std::string getCoeffsSetFilenameSuffix(const unsigned int coeffs_id) const;
+     230             :   std::string getCurrentOutputFilename(const std::string&, const std::string& suffix="") const;
+     231             :   std::string getBiasOutputFilename() const {return bias_filename_;}
+     232             :   std::string getCurrentBiasOutputFilename(const std::string& suffix="") const;
+     233             :   std::string getFesOutputFilename() const {return fes_filename_;}
+     234             :   std::string getCurrentFesOutputFilename(const std::string& suffix="") const;
+     235             :   std::string getTargetDistOutputFilename() const {return targetdist_filename_;}
+     236             :   std::string getCurrentTargetDistOutputFilename(const std::string& suffix="") const;
+     237             :   //
+     238          83 :   void enableBiasFileOutput() {bias_fileoutput_active_=true;}
+     239             :   void disableBiasFileOutput() {bias_fileoutput_active_=false;}
+     240             :   bool isBiasFileOutputActive() const {return bias_fileoutput_active_;}
+     241             :   std::string getBiasFileFmt() const {return bias_file_fmt_;}
+     242             :   //
+     243          83 :   void enableFesFileOutput() {fes_fileoutput_active_=true;}
+     244             :   void disableFesFileOutput() {fes_fileoutput_active_=false;}
+     245             :   bool isFesFileOutputActive() const {return fes_fileoutput_active_;}
+     246             :   std::string getFesFileFmt() const {return fes_file_fmt_;}
+     247             :   //
+     248          17 :   void enableFesProjFileOutput() {fesproj_fileoutput_active_=true;}
+     249             :   void disableFesFileProjOutput() {fesproj_fileoutput_active_=false;}
+     250             :   bool isFesProjFileOutputActive() const {return fesproj_fileoutput_active_;}
+     251             :   //
+     252          41 :   void enableDynamicTargetDistFileOutput() {dynamic_targetdist_fileoutput_active_=true;}
+     253             :   void disableDynamicTargetDistFileOutput() {dynamic_targetdist_fileoutput_active_=false;}
+     254             :   bool isDynamicTargetDistFileOutputActive() const {return dynamic_targetdist_fileoutput_active_;}
+     255             :   std::string getTargetDistFileFmt() const {return targetdist_file_fmt_;}
+     256             :   std::string getTargetDistRestartFileFmt() const {return targetdist_restart_file_fmt_;}
+     257             :   //
+     258             :   void enableStaticTargetDistFileOutput() {static_targetdist_fileoutput_active_=true;}
+     259          46 :   void disableStaticTargetDistFileOutput() {static_targetdist_fileoutput_active_=false;}
+     260          50 :   bool isStaticTargetDistFileOutputActive() const {return static_targetdist_fileoutput_active_;}
+     261             :   //
+     262             :   std::vector< std::vector<std::string> > getProjectionArguments() const {return projection_args_;}
+     263          56 :   std::vector<std::string> getProjectionArgument(unsigned int i) const {return projection_args_[i];}
+     264         122 :   unsigned int getNumberOfProjectionArguments() const {return projection_args_.size();}
+     265             :   //
+     266             :   void setupBiasCutoff(const double, const double);
+     267     1498465 :   bool biasCutoffActive() const {return bias_cutoff_active_;}
+     268          45 :   double getBiasCutoffValue() const {return bias_cutoff_value_;}
+     269         498 :   void setCurrentBiasMaxValue(const double max_value) {bias_current_max_value=max_value;}
+     270             :   double getCurrentBiasMaxValue() const {return bias_current_max_value;}
+     271             :   double getBiasCutoffSwitchingFunction(const double, double&) const;
+     272             :   double getBiasCutoffSwitchingFunction(const double) const;
+     273             :   void applyBiasCutoff(double&, std::vector<double>&) const;
+     274             :   void applyBiasCutoff(double&, std::vector<double>&, std::vector<double>&) const;
+     275             :   //
+     276             :   std::unique_ptr<OFile> getOFile(const std::string& filename, const bool multi_sim_single_file=false, const bool enforce_backup=true);
+     277             :   //
+     278           0 :   virtual void setupBiasFileOutput() {};
+     279           0 :   virtual void writeBiasToFile() {};
+     280           0 :   virtual void resetBiasFileOutput() {};
+     281             :   //
+     282           0 :   virtual void setupFesFileOutput() {};
+     283           0 :   virtual void writeFesToFile() {};
+     284           0 :   virtual void resetFesFileOutput() {};
+     285             :   //
+     286           0 :   virtual void setupFesProjFileOutput() {};
+     287           0 :   virtual void writeFesProjToFile() {};
+     288           0 :   virtual void resetFesProjFileOutput() {};
+     289             :   //
+     290          44 :   virtual void setupTargetDistFileOutput() {};
+     291           0 :   virtual void writeTargetDistToFile() {};
+     292           0 :   virtual void resetTargetDistFileOutput() {};
+     293             :   //
+     294           9 :   virtual void setupTargetDistProjFileOutput() {};
+     295           0 :   virtual void writeTargetDistProjToFile() {};
+     296           0 :   virtual void resetTargetDistProjFileOutput() {};
+     297             :   //
+     298             :   void updateReweightFactor();
+     299             :   virtual double calculateReweightFactor() const;
+     300           0 :   bool isReweightFactorCalculated() const {return calc_reweightfactor_;}
+     301             : };
+     302             : 
+     303             : 
+     304             : inline
+     305             : size_t VesBias::getCoeffsIndex(const std::vector<unsigned int>& indices, const unsigned int coeffs_id) const {return coeffs_pntrs_[coeffs_id]->getIndex(indices);}
+     306             : 
+     307             : inline
+     308             : std::vector<unsigned int> VesBias::getCoeffsIndices(const size_t index, const unsigned int coeffs_id) const {return coeffs_pntrs_[coeffs_id]->getIndices(index);}
+     309             : 
+     310             : inline
+     311     3607712 : size_t VesBias::getHessianIndex(const size_t index1, const size_t index2, const unsigned int coeffs_id) const {return hessian_pntrs_[coeffs_id]->getMatrixIndex(index1,index2);}
+     312             : 
+     313             : 
+     314             : inline
+     315       23277 : double VesBias::getBeta() const {
+     316       23277 :   plumed_massert(kbt_!=0.0,"you are requesting beta=1/(kB*T) when kB*T has not been defined. You need to give the temperature using the TEMP keyword as the MD engine does not pass it to PLUMED.");
+     317       23277 :   return 1.0/kbt_;
+     318             : }
+     319             : 
+     320             : 
+     321             : inline
+     322             : std::string VesBias::getCurrentBiasOutputFilename(const std::string& suffix) const {
+     323         178 :   return getCurrentOutputFilename(bias_filename_,suffix);
+     324             : }
+     325             : 
+     326             : 
+     327             : inline
+     328             : std::string VesBias::getCurrentFesOutputFilename(const std::string& suffix) const {
+     329         205 :   return getCurrentOutputFilename(fes_filename_,suffix);
+     330             : }
+     331             : 
+     332             : 
+     333             : inline
+     334             : double VesBias::getBiasCutoffSwitchingFunction(const double bias) const {
+     335             :   double dummy=0.0;
+     336             :   return getBiasCutoffSwitchingFunction(bias,dummy);
+     337             : }
+     338             : 
+     339             : 
+     340             : inline
+     341         600 : void VesBias::applyBiasCutoff(double& bias, std::vector<double>& forces) const {
+     342         600 :   std::vector<double> dummy(0);
+     343         600 :   applyBiasCutoff(bias,forces,dummy);
+     344         600 : }
+     345             : 
+     346             : 
+     347             : inline
+     348         663 : void VesBias::applyBiasCutoff(double& bias, std::vector<double>& forces, std::vector<double>& coeffsderivs_values) const {
+     349         663 :   double deriv_factor_sf=0.0;
+     350         663 :   double value_sf = getBiasCutoffSwitchingFunction(bias,deriv_factor_sf);
+     351         663 :   bias *= value_sf;
+     352        1326 :   for(unsigned int i=0; i<forces.size(); i++) {
+     353         663 :     forces[i] *= deriv_factor_sf;
+     354             :   }
+     355             :   //
+     356        1398 :   for(unsigned int i=0; i<coeffsderivs_values.size(); i++) {
+     357         735 :     coeffsderivs_values[i] *= deriv_factor_sf;
+     358             :   }
+     359         663 : }
+     360             : 
+     361             : 
+     362             : inline
+     363       22810 : std::vector<double> VesBias::computeCovarianceFromAverages(const unsigned int c_id) const {
+     364             :   size_t ncoeffs = numberOfCoeffs(c_id);
+     365       22810 :   std::vector<double> covariance(sampled_cross_averages[c_id].size(),0.0);
+     366             :   // diagonal part
+     367     1823850 :   for(size_t i=0; i<ncoeffs; i++) {
+     368             :     size_t midx = getHessianIndex(i,i,c_id);
+     369     1801040 :     covariance[midx] = sampled_cross_averages[c_id][midx] - sampled_averages[c_id][i]*sampled_averages[c_id][i];
+     370             :   }
+     371       22810 :   if(!diagonal_hessian_) {
+     372           0 :     for(size_t i=0; i<ncoeffs; i++) {
+     373           0 :       for(size_t j=(i+1); j<ncoeffs; j++) {
+     374             :         size_t midx = getHessianIndex(i,j,c_id);
+     375           0 :         covariance[midx] = sampled_cross_averages[c_id][midx] - sampled_averages[c_id][i]*sampled_averages[c_id][j];
+     376             :       }
+     377             :     }
+     378             :   }
+     379       22810 :   return covariance;
+     380             : }
+     381             : 
+     382             : 
+     383             : template<class T>
+     384         180 : bool VesBias::parseMultipleValues(const std::string& keyword, std::vector<T>& values, unsigned int nvalues) {
+     385         180 :   plumed_assert(nvalues>0);
+     386         180 :   plumed_assert(values.size()==0);
+     387             :   bool identical_values=false;
+     388             :   //
+     389         180 :   parseVector(keyword,values);
+     390         180 :   if(values.size()==1 && nvalues>1) {
+     391           0 :     values.resize(nvalues,values[0]);
+     392             :     identical_values=true;
+     393             :   }
+     394         180 :   if(values.size()>0 && values.size()!=nvalues) {
+     395           0 :     std::string s1; Tools::convert(nvalues,s1);
+     396           0 :     plumed_merror("Error in " + keyword + " keyword: either give 1 common parameter value or " + s1 + " separate parameter values");
+     397             :   }
+     398         180 :   return identical_values;
+     399             : }
+     400             : 
+     401             : template<class T>
+     402          90 : bool VesBias::parseMultipleValues(const std::string& keyword, std::vector<T>& values, unsigned int nvalues, const T& default_value) {
+     403          90 :   bool identical_values = parseMultipleValues(keyword,values,nvalues);
+     404          90 :   if(values.size()==0) {
+     405           0 :     values.resize(nvalues,default_value);
+     406             :     identical_values=true;
+     407             :   }
+     408          90 :   return identical_values;
+     409             : }
+     410             : 
+     411             : 
+     412             : }
+     413             : }
+     414             : 
+     415             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/VesDeltaF.cpp.func-sort-c.html b/coverage/ves/VesDeltaF.cpp.func-sort-c.html new file mode 100644 index 000000000000..f6bf9243c6c8 --- /dev/null +++ b/coverage/ves/VesDeltaF.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - ves/VesDeltaF.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - VesDeltaF.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:34335197.7 %
Date:2024-04-19 12:12:35Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves9VesDeltaFC2ERKNS_13ActionOptionsE0
_ZN4PLMD3ves9VesDeltaFC1ERKNS_13ActionOptionsE4
_ZN4PLMD3ves9VesDeltaF16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD3ves9VesDeltaF12update_alphaEv16
_ZN4PLMD3ves9VesDeltaF17update_tg_and_rctEv16
_ZN4PLMD3ves9VesDeltaF6updateEv804
_ZN4PLMD3ves9VesDeltaF9calculateEv804
_ZNK4PLMD3ves9VesDeltaF9get_indexEjj4632
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/VesDeltaF.cpp.func.html b/coverage/ves/VesDeltaF.cpp.func.html new file mode 100644 index 000000000000..4a9cd18d85a8 --- /dev/null +++ b/coverage/ves/VesDeltaF.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - ves/VesDeltaF.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - VesDeltaF.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:34335197.7 %
Date:2024-04-19 12:12:35Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves9VesDeltaF12update_alphaEv16
_ZN4PLMD3ves9VesDeltaF16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD3ves9VesDeltaF17update_tg_and_rctEv16
_ZN4PLMD3ves9VesDeltaF6updateEv804
_ZN4PLMD3ves9VesDeltaF9calculateEv804
_ZN4PLMD3ves9VesDeltaFC1ERKNS_13ActionOptionsE4
_ZN4PLMD3ves9VesDeltaFC2ERKNS_13ActionOptionsE0
_ZNK4PLMD3ves9VesDeltaF9get_indexEjj4632
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/VesDeltaF.cpp.gcov.html b/coverage/ves/VesDeltaF.cpp.gcov.html new file mode 100644 index 000000000000..1a93fa75f073 --- /dev/null +++ b/coverage/ves/VesDeltaF.cpp.gcov.html @@ -0,0 +1,792 @@ + + + + + + + + LCOV - plumed test coverage - ves/VesDeltaF.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - VesDeltaF.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:34335197.7 %
Date:2024-04-19 12:12:35Functions:7887.5 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "bias/Bias.h"
+      24             : #include "core/PlumedMain.h"
+      25             : #include "core/ActionRegister.h"
+      26             : #include "tools/Communicator.h"
+      27             : #include "tools/Grid.h"
+      28             : #include "tools/File.h"
+      29             : //#include <algorithm> //std::fill
+      30             : 
+      31             : namespace PLMD {
+      32             : namespace ves {
+      33             : 
+      34             : //+PLUMEDOC VES_BIAS VES_DELTA_F
+      35             : /*
+      36             : Implementation of VES Delta F method
+      37             : 
+      38             : Implementation of VES\f$\Delta F\f$ method \cite Invernizzi2019vesdeltaf (step two only).
+      39             : 
+      40             : \warning
+      41             :   Notice that this is a stand-alone bias Action, it does not need any of the other VES module components
+      42             : 
+      43             : First you should create some estimate of the local free energy basins of your system,
+      44             : using e.g. multiple \ref METAD short runs, and combining them with the \ref sum_hills utility.
+      45             : Once you have them, you can use this bias Action to perform the VES optimization part of the method.
+      46             : 
+      47             : These \f$N+1\f$ local basins are used to model the global free energy.
+      48             : In particular, given the conditional probabilities \f$P(\mathbf{s}|i)\propto e^{-\beta F_i(\mathbf{s})}\f$
+      49             : and the probabilities of being in a given basin \f$P_i\f$, we can write:
+      50             : \f[
+      51             :   e^{-\beta F(\mathbf{s})}\propto P(\mathbf{s})=\sum_{i=0}^N P(\mathbf{s}|i)P_i \, .
+      52             : \f]
+      53             : We use this free energy model and the chosen bias factor \f$\gamma\f$ to build the bias potential:
+      54             : \f$V(\mathbf{s})=-(1-1/\gamma)F(\mathbf{s})\f$.
+      55             : Or, more explicitly:
+      56             : \f[
+      57             :   V(\mathbf{s})=(1-1/\gamma)\frac{1}{\beta}\log\left[e^{-\beta F_0(\mathbf{s})}
+      58             :   +\sum_{i=1}^{N} e^{-\beta F_i(\mathbf{s})} e^{-\beta \alpha_i}\right] \, ,
+      59             : \f]
+      60             : where the parameters \f$\boldsymbol{\alpha}\f$ are the \f$N\f$ free energy differences (see below) from the \f$F_0\f$ basin.
+      61             : 
+      62             : By default the \f$F_i(\mathbf{s})\f$ are shifted so that \f$\min[F_i(\mathbf{s})]=0\f$ for all \f$i=\{0,...,N\}\f$.
+      63             : In this case the optimization parameters \f$\alpha_i\f$ are the difference in height between the minima of the basins.
+      64             : Using the keyword `NORMALIZE`, you can also decide to normalize the local free energies so that
+      65             : \f$\int d\mathbf{s}\, e^{-\beta F_i(\mathbf{s})}=1\f$.
+      66             : In this case the parameters will represent not the difference in height (which depends on the chosen CVs),
+      67             : but the actual free energy difference, \f$\alpha_i=\Delta F_i\f$.
+      68             : 
+      69             : However, as discussed in Ref. \cite Invernizzi2019vesdeltaf, a better estimate of \f$\Delta F_i\f$ should be obtained through the reweighting procedure.
+      70             : 
+      71             : \par Examples
+      72             : 
+      73             : The following performs the optimization of the free energy difference between two metastable basins:
+      74             : 
+      75             : \plumedfile
+      76             : cv: DISTANCE ATOMS=1,2
+      77             : ves: VES_DELTA_F ...
+      78             :   ARG=cv
+      79             :   TEMP=300
+      80             :   FILE_F0=fesA.data
+      81             :   FILE_F1=fesB.data
+      82             :   BIASFACTOR=10.0
+      83             :   M_STEP=0.1
+      84             :   AV_STRIDE=500
+      85             :   PRINT_STRIDE=100
+      86             : ...
+      87             : PRINT FMT=%g STRIDE=500 FILE=Colvar.data ARG=cv,ves.bias,ves.rct
+      88             : \endplumedfile
+      89             : 
+      90             : The local FES files can be obtained as described in Sec. 4.2 of Ref. \cite Invernizzi2019vesdeltaf, i.e. for example:
+      91             : - run 4 independent metad runs, all starting from basin A, and kill them as soon as they make the first transition (see e.g. \ref COMMITTOR)
+      92             : - \verbatim cat HILLS* > all_HILLS \endverbatim
+      93             : - \verbatim plumed sum_hills --hills all_HILLS --outfile all_fesA.dat --mintozero --min 0 --max 1 --bin 100 \endverbatim
+      94             : - \verbatim awk -v n_rep=4 '{if($1!="#!" && $1!="") {for(i=1+(NF-1)/2; i<=NF; i++) $i/=n_rep;} print $0}' all_fesA.dat > fesA.data \endverbatim
+      95             : 
+      96             : The header of both FES files must be identical, and should be similar to the following:
+      97             : 
+      98             : \auxfile{fesA.data}
+      99             : #! FIELDS cv file.free der_cv
+     100             : #! SET min_cv 0
+     101             : #! SET max_cv 1
+     102             : #! SET nbins_cv  100
+     103             : #! SET periodic_cv false
+     104             : 0 0 0
+     105             : \endauxfile
+     106             : \auxfile{fesB.data}
+     107             : #! FIELDS cv file.free der_cv
+     108             : #! SET min_cv 0
+     109             : #! SET max_cv 1
+     110             : #! SET nbins_cv  100
+     111             : #! SET periodic_cv false
+     112             : 0 0 0
+     113             : \endauxfile
+     114             : 
+     115             : */
+     116             : //+ENDPLUMEDOC
+     117             : 
+     118             : class VesDeltaF : public bias::Bias {
+     119             : 
+     120             : private:
+     121             :   double beta_;
+     122             :   unsigned NumParallel_;
+     123             :   unsigned rank_;
+     124             :   unsigned NumWalkers_;
+     125             :   bool isFirstStep_;
+     126             :   bool afterCalculate_;
+     127             : 
+     128             : //prob
+     129             :   double tot_prob_;
+     130             :   std::vector<double> prob_;
+     131             :   std::vector< std::vector<double> > der_prob_;
+     132             : 
+     133             : //local basins
+     134             :   std::vector< std::unique_ptr<Grid> > grid_p_; //pointers because of GridBase::create
+     135             :   std::vector<double> norm_;
+     136             : 
+     137             : //optimizer-related stuff
+     138             :   long long unsigned mean_counter_;
+     139             :   unsigned mean_weight_tau_;
+     140             :   unsigned alpha_size_;
+     141             :   unsigned sym_alpha_size_;
+     142             :   std::vector<double> mean_alpha_;
+     143             :   std::vector<double> inst_alpha_;
+     144             :   std::vector<double> past_increment2_;
+     145             :   double minimization_step_;
+     146             :   bool damping_off_;
+     147             : //'tg' -> 'target distribution'
+     148             :   double inv_gamma_;
+     149             :   unsigned tg_counter_;
+     150             :   unsigned tg_stride_;
+     151             :   std::vector<double> tg_dV_dAlpha_;
+     152             :   std::vector<double> tg_d2V_dAlpha2_;
+     153             : //'av' -> 'ensemble average'
+     154             :   unsigned av_counter_;
+     155             :   unsigned av_stride_;
+     156             :   std::vector<double> av_dV_dAlpha_;
+     157             :   std::vector<double> av_dV_dAlpha_prod_;
+     158             :   std::vector<double> av_d2V_dAlpha2_;
+     159             : //printing
+     160             :   unsigned print_stride_;
+     161             :   OFile alphaOfile_;
+     162             : //other
+     163             :   std::vector<double> exp_alpha_;
+     164             :   std::vector<double> prev_exp_alpha_;
+     165             :   double work_;
+     166             : 
+     167             : //functions
+     168             :   void update_alpha();
+     169             :   void update_tg_and_rct();
+     170             :   inline unsigned get_index(const unsigned, const unsigned) const;
+     171             : 
+     172             : public:
+     173             :   explicit VesDeltaF(const ActionOptions&);
+     174             :   void calculate() override;
+     175             :   void update() override;
+     176             :   static void registerKeywords(Keywords& keys);
+     177             : };
+     178             : 
+     179             : PLUMED_REGISTER_ACTION(VesDeltaF,"VES_DELTA_F")
+     180             : 
+     181           6 : void VesDeltaF::registerKeywords(Keywords& keys) {
+     182           6 :   Bias::registerKeywords(keys);
+     183           6 :   keys.use("ARG");
+     184          12 :   keys.add("optional","TEMP","temperature is compulsory, but it can be sometimes fetched from the MD engine");
+     185             : //local free energies
+     186          12 :   keys.add("numbered","FILE_F","names of files containing local free energies and derivatives. "
+     187             :            "The first one, FILE_F0, is used as reference for all the free energy differences.");
+     188          12 :   keys.reset_style("FILE_F","compulsory");
+     189          12 :   keys.addFlag("NORMALIZE",false,"normalize all local free energies so that alpha will be (approx) Delta F");
+     190          12 :   keys.addFlag("NO_MINTOZERO",false,"leave local free energies as provided, without shifting them to zero min");
+     191             : //target distribution
+     192          12 :   keys.add("compulsory","BIASFACTOR","0","the gamma bias factor used for well-tempered target p(s)."
+     193             :            " Set to 0 for non-tempered flat target");
+     194          12 :   keys.add("optional","TG_STRIDE","( default=1 ) number of AV_STRIDE between updates"
+     195             :            " of target p(s) and reweighing factor c(t)");
+     196             : //optimization
+     197          12 :   keys.add("compulsory","M_STEP","1.0","the mu step used for the Omega functional minimization");
+     198          12 :   keys.add("compulsory","AV_STRIDE","500","number of simulation steps between alpha updates");
+     199          12 :   keys.add("optional","TAU_MEAN","exponentially decaying average for alpha (rescaled using AV_STRIDE)."
+     200             :            " Should be used only in very specific cases");
+     201          12 :   keys.add("optional","INITIAL_ALPHA","( default=0 ) an initial guess for the bias potential parameter alpha");
+     202          12 :   keys.addFlag("DAMPING_OFF",false,"do not use an AdaGrad-like term to rescale M_STEP");
+     203             : //output parameters file
+     204          12 :   keys.add("compulsory","ALPHA_FILE","ALPHA","file name for output minimization parameters");
+     205          12 :   keys.add("optional","PRINT_STRIDE","( default=10 ) stride for printing to ALPHA_FILE");
+     206          12 :   keys.add("optional","FMT","specify format for ALPHA_FILE");
+     207             : //debug flags
+     208          12 :   keys.addFlag("SERIAL",false,"perform the calculation in serial even if multiple tasks are available");
+     209          12 :   keys.addFlag("MULTIPLE_WALKERS",false,"use multiple walkers connected via MPI for the optimization");
+     210           6 :   keys.use("RESTART");
+     211             : 
+     212             : //output components
+     213           6 :   componentsAreNotOptional(keys);
+     214          12 :   keys.addOutputComponent("rct","default","the reweighting factor c(t)");
+     215          12 :   keys.addOutputComponent("work","default","the work done by the bias in one AV_STRIDE");
+     216           6 : }
+     217             : 
+     218           4 : VesDeltaF::VesDeltaF(const ActionOptions&ao)
+     219             :   : PLUMED_BIAS_INIT(ao)
+     220           4 :   , isFirstStep_(true)
+     221           4 :   , afterCalculate_(false)
+     222           4 :   , mean_counter_(0)
+     223           4 :   , av_counter_(0)
+     224           4 :   , work_(0)
+     225             : {
+     226             : //set beta
+     227           4 :   const double Kb=getKBoltzmann();
+     228           4 :   double KbT=getkBT();
+     229           4 :   plumed_massert(KbT>0,"your MD engine does not pass the temperature to plumed, you must specify it using TEMP");
+     230           4 :   beta_=1.0/KbT;
+     231             : 
+     232             : //initialize probability grids using local free energies
+     233             :   bool spline=true;
+     234             :   bool sparsegrid=false;
+     235           4 :   std::string funcl="file.free"; //typical name given by sum_hills
+     236             : 
+     237             :   std::vector<std::string> fes_names;
+     238           8 :   for(unsigned n=0;; n++)//NB: here we start from FILE_F0 not from FILE_F1
+     239             :   {
+     240             :     std::string filename;
+     241          24 :     if(!parseNumbered("FILE_F",n,filename))
+     242             :       break;
+     243           8 :     fes_names.push_back(filename);
+     244           8 :     IFile gridfile;
+     245           8 :     gridfile.open(filename);
+     246           8 :     auto g=GridBase::create(funcl,getArguments(),gridfile,sparsegrid,spline,true);
+     247             : // we assume this cannot be sparse. in case we want it to be sparse, some of the methods
+     248             : // that are available only in Grid should be ported to GridBase
+     249           8 :     auto gg=dynamic_cast<Grid*>(g.get());
+     250             : // if this throws, g is deleted
+     251           8 :     plumed_assert(gg);
+     252             : // release ownership in order to transfer it to emplaced pointer
+     253             : // cppcheck-suppress ignoredReturnValue
+     254             :     g.release();
+     255           8 :     grid_p_.emplace_back(gg);
+     256          16 :   }
+     257           4 :   plumed_massert(grid_p_.size()>1,"at least 2 basins must be defined, starting from FILE_F0");
+     258           4 :   alpha_size_=grid_p_.size()-1;
+     259           4 :   sym_alpha_size_=alpha_size_*(alpha_size_+1)/2; //useful for symmetric matrix [alpha_size_]x[alpha_size_]
+     260             :   //check for consistency with first local free energy
+     261           8 :   for(unsigned n=1; n<grid_p_.size(); n++)
+     262             :   {
+     263           8 :     std::string error_tag="FILE_F"+std::to_string(n)+" '"+fes_names[n]+"' not compatible with reference one, FILE_F0";
+     264           4 :     plumed_massert(grid_p_[n]->getSize()==grid_p_[0]->getSize(),error_tag);
+     265           4 :     plumed_massert(grid_p_[n]->getMin()==grid_p_[0]->getMin(),error_tag);
+     266           4 :     plumed_massert(grid_p_[n]->getMax()==grid_p_[0]->getMax(),error_tag);
+     267           4 :     plumed_massert(grid_p_[n]->getBinVolume()==grid_p_[0]->getBinVolume(),error_tag);
+     268             :   }
+     269             : 
+     270           4 :   bool no_mintozero=false;
+     271           4 :   parseFlag("NO_MINTOZERO",no_mintozero);
+     272           4 :   if(!no_mintozero)
+     273             :   {
+     274           6 :     for(unsigned n=0; n<grid_p_.size(); n++)
+     275           4 :       grid_p_[n]->setMinToZero();
+     276             :   }
+     277           4 :   bool normalize=false;
+     278           4 :   parseFlag("NORMALIZE",normalize);
+     279           4 :   norm_.resize(grid_p_.size(),0);
+     280           4 :   std::vector<double> c_norm(grid_p_.size());
+     281             :   //convert the FESs to probability distributions
+     282             :   //NB: the spline interpolation will be done on the probability distributions, not on the given FESs
+     283             :   const unsigned ncv=getNumberOfArguments(); //just for ease
+     284          12 :   for(unsigned n=0; n<grid_p_.size(); n++)
+     285             :   {
+     286         808 :     for(Grid::index_t t=0; t<grid_p_[n]->getSize(); t++)
+     287             :     {
+     288         800 :       std::vector<double> der(ncv);
+     289         800 :       const double val=std::exp(-beta_*grid_p_[n]->getValueAndDerivatives(t,der));
+     290        1600 :       for(unsigned s=0; s<ncv; s++)
+     291         800 :         der[s]*=-beta_*val;
+     292         800 :       grid_p_[n]->setValueAndDerivatives(t,val,der);
+     293         800 :       norm_[n]+=val;
+     294             :     }
+     295           8 :     c_norm[n]=1./beta_*std::log(norm_[n]);
+     296           8 :     if(normalize)
+     297             :     {
+     298           4 :       grid_p_[n]->scaleAllValuesAndDerivatives(1./norm_[n]);
+     299           4 :       norm_[n]=1;
+     300             :     }
+     301             :   }
+     302             : 
+     303             : //get target
+     304           4 :   double biasfactor=0;
+     305           4 :   parse("BIASFACTOR",biasfactor);
+     306           4 :   plumed_massert(biasfactor==0 || biasfactor>1,"BIASFACTOR must be zero (for uniform target) or greater than one");
+     307           4 :   if(biasfactor==0)
+     308           2 :     inv_gamma_=0;
+     309             :   else
+     310           2 :     inv_gamma_=1./biasfactor;
+     311           4 :   tg_counter_=0;
+     312           4 :   tg_stride_=1;
+     313           4 :   parse("TG_STRIDE",tg_stride_);
+     314           4 :   tg_dV_dAlpha_.resize(alpha_size_,0);
+     315           4 :   tg_d2V_dAlpha2_.resize(sym_alpha_size_,0);
+     316             : 
+     317             : //setup optimization stuff
+     318           4 :   minimization_step_=1;
+     319           4 :   parse("M_STEP",minimization_step_);
+     320             : 
+     321           4 :   av_stride_=500;
+     322           4 :   parse("AV_STRIDE",av_stride_);
+     323           4 :   av_dV_dAlpha_.resize(alpha_size_,0);
+     324           4 :   av_dV_dAlpha_prod_.resize(sym_alpha_size_,0);
+     325           4 :   av_d2V_dAlpha2_.resize(sym_alpha_size_,0);
+     326             : 
+     327           4 :   mean_weight_tau_=0;
+     328           4 :   parse("TAU_MEAN",mean_weight_tau_);
+     329           4 :   if(mean_weight_tau_!=1) //set it to 1 for basic SGD
+     330             :   {
+     331           4 :     plumed_massert((mean_weight_tau_==0 || mean_weight_tau_>av_stride_),"TAU_MEAN is rescaled with AV_STRIDE, so it has to be greater");
+     332           4 :     mean_weight_tau_/=av_stride_; //this way you can look at the number of simulation steps to choose TAU_MEAN
+     333             :   }
+     334             : 
+     335           8 :   parseVector("INITIAL_ALPHA",mean_alpha_);
+     336           4 :   if(mean_alpha_.size()>0)
+     337             :   {
+     338           2 :     plumed_massert(mean_alpha_.size()==alpha_size_,"provide one INITIAL_ALPHA for each basin beyond the first one");
+     339             :   }
+     340             :   else
+     341           2 :     mean_alpha_.resize(alpha_size_,0);
+     342           4 :   inst_alpha_=mean_alpha_;
+     343           4 :   exp_alpha_.resize(alpha_size_);
+     344           8 :   for(unsigned i=0; i<alpha_size_; i++)
+     345           4 :     exp_alpha_[i]=std::exp(-beta_*mean_alpha_[i]);
+     346           4 :   prev_exp_alpha_=exp_alpha_;
+     347             : 
+     348           4 :   damping_off_=false;
+     349           4 :   parseFlag("DAMPING_OFF",damping_off_);
+     350           4 :   if(damping_off_)
+     351           2 :     past_increment2_.resize(alpha_size_,1);
+     352             :   else
+     353           2 :     past_increment2_.resize(alpha_size_,0);
+     354             : 
+     355             : //file printing options
+     356           4 :   std::string alphaFileName("ALPHA");
+     357           4 :   parse("ALPHA_FILE",alphaFileName);
+     358           4 :   print_stride_=10;
+     359           8 :   parse("PRINT_STRIDE",print_stride_);
+     360             :   std::string fmt;
+     361           4 :   parse("FMT",fmt);
+     362             : 
+     363             : //other flags, mainly for debugging
+     364           4 :   NumParallel_=comm.Get_size();
+     365           4 :   rank_=comm.Get_rank();
+     366           4 :   bool serial=false;
+     367           4 :   parseFlag("SERIAL",serial);
+     368           4 :   if(serial)
+     369             :   {
+     370           2 :     log.printf(" -- SERIAL: running without loop parallelization\n");
+     371           2 :     NumParallel_=1;
+     372           2 :     rank_=0;
+     373             :   }
+     374             : 
+     375           4 :   bool multiple_walkers=false;
+     376           4 :   parseFlag("MULTIPLE_WALKERS",multiple_walkers);
+     377           4 :   if(!multiple_walkers)
+     378           2 :     NumWalkers_=1;
+     379             :   else
+     380             :   {
+     381           2 :     if(comm.Get_rank()==0)//multi_sim_comm works well on first rank only
+     382           2 :       NumWalkers_=multi_sim_comm.Get_size();
+     383           2 :     if(comm.Get_size()>1) //if each walker has more than one processor update them all
+     384           0 :       comm.Bcast(NumWalkers_,0);
+     385             :   }
+     386             : 
+     387           4 :   checkRead();
+     388             : 
+     389             : //restart if needed
+     390           4 :   if(getRestart())
+     391             :   {
+     392           2 :     IFile ifile;
+     393           2 :     ifile.link(*this);
+     394           2 :     if(NumWalkers_>1)
+     395           4 :       ifile.enforceSuffix("");
+     396           2 :     if(ifile.FileExist(alphaFileName))
+     397             :     {
+     398           2 :       log.printf("  Restarting from: %s\n",alphaFileName.c_str());
+     399           2 :       log.printf("    all options (also PRINT_STRIDE) must be consistent!\n");
+     400           2 :       log.printf("    any INITIAL_ALPHA will be overwritten\n");
+     401           2 :       ifile.open(alphaFileName);
+     402             :       double time;
+     403           2 :       std::vector<double> damping(alpha_size_);
+     404          20 :       while(ifile.scanField("time",time)) //room for improvements: only last line is important
+     405             :       {
+     406          16 :         for(unsigned i=0; i<alpha_size_; i++)
+     407             :         {
+     408           8 :           const std::string index(std::to_string(i+1));
+     409           8 :           prev_exp_alpha_[i]=std::exp(-beta_*mean_alpha_[i]);
+     410          16 :           ifile.scanField("alpha_"+index,mean_alpha_[i]);
+     411          16 :           ifile.scanField("auxiliary_"+index,inst_alpha_[i]);
+     412          16 :           ifile.scanField("damping_"+index,damping[i]);
+     413             :         }
+     414           8 :         ifile.scanField();
+     415           8 :         mean_counter_+=print_stride_;
+     416             :       }
+     417           4 :       for(unsigned i=0; i<alpha_size_; i++)
+     418             :       {
+     419           2 :         exp_alpha_[i]=std::exp(-beta_*mean_alpha_[i]);
+     420           2 :         past_increment2_[i]=damping[i]*damping[i];
+     421             :       }
+     422             :       //sync all walkers and treads. Not sure is mandatory but is no harm
+     423           2 :       comm.Barrier();
+     424           2 :       if(comm.Get_rank()==0)
+     425           2 :         multi_sim_comm.Barrier();
+     426             :     }
+     427             :     else
+     428           0 :       log.printf("  -- WARNING: restart requested, but no '%s' file found!\n",alphaFileName.c_str());
+     429           2 :   }
+     430             : 
+     431             : //setup output file with Alpha values
+     432           4 :   alphaOfile_.link(*this);
+     433           4 :   if(NumWalkers_>1)
+     434             :   {
+     435           2 :     if(comm.Get_rank()==0 && multi_sim_comm.Get_rank()>0)
+     436             :       alphaFileName="/dev/null"; //only first walker writes on file
+     437           4 :     alphaOfile_.enforceSuffix("");
+     438             :   }
+     439           4 :   alphaOfile_.open(alphaFileName);
+     440           4 :   if(fmt.length()>0)
+     441           8 :     alphaOfile_.fmtField(" "+fmt);
+     442             : 
+     443             : //add other output components
+     444          12 :   addComponent("rct"); componentIsNotPeriodic("rct");
+     445           8 :   addComponent("work"); componentIsNotPeriodic("work");
+     446             : 
+     447             : //print some info
+     448           4 :   log.printf("  Temperature T: %g\n",1./(Kb*beta_));
+     449           4 :   log.printf("  Beta (1/Kb*T): %g\n",beta_);
+     450           4 :   log.printf("  Local free energy basins files and normalization constants:\n");
+     451          12 :   for(unsigned n=0; n<grid_p_.size(); n++)
+     452           8 :     log.printf("    F_%d filename: %s  c_%d=%g\n",n,fes_names[n].c_str(),n,c_norm[n]);
+     453           4 :   if(no_mintozero)
+     454           2 :     log.printf(" -- NO_MINTOZERO: local free energies are not shifted to be zero at minimum\n");
+     455           4 :   if(normalize)
+     456           2 :     log.printf(" -- NORMALIZE: F_n+=c_n, alpha=DeltaF\n");
+     457           4 :   log.printf("  Using target distribution with 1/gamma = %g\n",inv_gamma_);
+     458           4 :   log.printf("    and updated with stride %d\n",tg_stride_);
+     459           4 :   log.printf("  Step for the minimization algorithm: %g\n",minimization_step_);
+     460           4 :   log.printf("  Stride for the ensemble average: %d\n",av_stride_);
+     461           4 :   if(mean_weight_tau_>1)
+     462           2 :     log.printf("  Exponentially decaying average with weight=tau/av_stride=%d\n",mean_weight_tau_);
+     463           4 :   if(mean_weight_tau_==1)
+     464           0 :     log.printf(" +++ WARNING +++ setting TAU_MEAN=1 is equivalent to use simple SGD, without mean alpha nor hessian contribution\n");
+     465           4 :   log.printf("  Initial guess for alpha:\n");
+     466           8 :   for(unsigned i=0; i<alpha_size_; i++)
+     467           4 :     log.printf("    alpha_%d = %g\n",i+1,mean_alpha_[i]);
+     468           4 :   if(damping_off_)
+     469           2 :     log.printf(" -- DAMPING_OFF: the minimization step will NOT become smaller as the simulation goes on\n");
+     470           4 :   log.printf("  Printing on file %s with stride %d\n",alphaFileName.c_str(),print_stride_);
+     471           4 :   if(serial)
+     472           2 :     log.printf(" -- SERIAL: running without loop parallelization\n");
+     473           4 :   if(NumParallel_>1)
+     474           2 :     log.printf("  Using multiple threads per simulation: %d\n",NumParallel_);
+     475           4 :   if(multiple_walkers)
+     476             :   {
+     477           2 :     log.printf(" -- MULTIPLE_WALKERS: multiple simulations will combine statistics for the optimization\n");
+     478           2 :     if(NumWalkers_>1)
+     479             :     {
+     480           2 :       log.printf("    number of walkers: %d\n",NumWalkers_);
+     481           2 :       log.printf("    walker rank: %d\n",multi_sim_comm.Get_rank()); //only comm.Get_rank()=0 prints, so this is fine
+     482             :     }
+     483             :     else
+     484           0 :       log.printf(" +++ WARNING +++ only one replica found: are you sure you are running MPI-connected simulations?\n");
+     485             :   }
+     486           4 :   log.printf(" Bibliography ");
+     487           8 :   log<<plumed.cite("Invernizzi and Parrinello, J. Chem. Theory Comput. 15, 2187-2194 (2019)");
+     488           8 :   log<<plumed.cite("Valsson and Parrinello, Phys. Rev. Lett. 113, 090601 (2014)");
+     489           4 :   if(inv_gamma_>0)
+     490           4 :     log<<plumed.cite("Valsson and Parrinello, J. Chem. Theory Comput. 11, 1996-2002 (2015)");
+     491             : 
+     492             : //last initializations
+     493           4 :   prob_.resize(grid_p_.size());
+     494           4 :   der_prob_.resize(grid_p_.size(),std::vector<double>(getNumberOfArguments()));
+     495           4 :   update_tg_and_rct();
+     496           8 : }
+     497             : 
+     498         804 : void VesDeltaF::calculate()
+     499             : {
+     500             : //get CVs
+     501         804 :   const unsigned ncv=getNumberOfArguments(); //just for ease
+     502         804 :   std::vector<double> cv(ncv);
+     503        1608 :   for(unsigned s=0; s<ncv; s++)
+     504         804 :     cv[s]=getArgument(s);
+     505             : //get probabilities for each basin, and total one
+     506        2412 :   for(unsigned n=0; n<grid_p_.size(); n++)
+     507        1608 :     prob_[n]=grid_p_[n]->getValueAndDerivatives(cv,der_prob_[n]);
+     508         804 :   tot_prob_=prob_[0];
+     509        1608 :   for(unsigned i=0; i<alpha_size_; i++)
+     510         804 :     tot_prob_+=prob_[i+1]*exp_alpha_[i];
+     511             : 
+     512             : //update bias and forces: V=-(1-inv_gamma_)*fes
+     513         804 :   setBias((1-inv_gamma_)/beta_*std::log(tot_prob_));
+     514        1608 :   for(unsigned s=0; s<ncv; s++)
+     515             :   {
+     516         804 :     double dProb_dCV_s=der_prob_[0][s];
+     517        1608 :     for(unsigned i=0; i<alpha_size_; i++)
+     518         804 :       dProb_dCV_s+=der_prob_[i+1][s]*exp_alpha_[i];
+     519         804 :     setOutputForce(s,-(1-inv_gamma_)/beta_/tot_prob_*dProb_dCV_s);
+     520             :   }
+     521         804 :   afterCalculate_=true;
+     522         804 : }
+     523             : 
+     524         804 : void VesDeltaF::update()
+     525             : {
+     526             : //skip first step to sync getTime() and av_counter_, as in METAD
+     527         804 :   if(isFirstStep_)
+     528             :   {
+     529           4 :     isFirstStep_=false;
+     530           4 :     return;
+     531             :   }
+     532         800 :   plumed_massert(afterCalculate_,"VesDeltaF::update() must be called after VesDeltaF::calculate() to work properly");
+     533         800 :   afterCalculate_=false;
+     534             : 
+     535             : //calculate derivatives for ensemble averages
+     536         800 :   std::vector<double> dV_dAlpha(alpha_size_);
+     537         800 :   std::vector<double> d2V_dAlpha2(sym_alpha_size_);
+     538        1600 :   for(unsigned i=0; i<alpha_size_; i++)
+     539         800 :     dV_dAlpha[i]=-(1-inv_gamma_)/tot_prob_*prob_[i+1]*exp_alpha_[i];
+     540        1600 :   for(unsigned i=0; i<alpha_size_; i++)
+     541             :   {
+     542         800 :     d2V_dAlpha2[get_index(i,i)]=-beta_*dV_dAlpha[i];
+     543        1600 :     for(unsigned j=i; j<alpha_size_; j++)
+     544         800 :       d2V_dAlpha2[get_index(i,j)]-=beta_/(1-inv_gamma_)*dV_dAlpha[i]*dV_dAlpha[j];
+     545             :   }
+     546             : //update ensemble averages
+     547         800 :   av_counter_++;
+     548        1600 :   for(unsigned i=0; i<alpha_size_; i++)
+     549             :   {
+     550         800 :     av_dV_dAlpha_[i]+=(dV_dAlpha[i]-av_dV_dAlpha_[i])/av_counter_;
+     551        1600 :     for(unsigned j=i; j<alpha_size_; j++)
+     552             :     {
+     553         800 :       const unsigned ij=get_index(i,j);
+     554         800 :       av_dV_dAlpha_prod_[ij]+=(dV_dAlpha[i]*dV_dAlpha[j]-av_dV_dAlpha_prod_[ij])/av_counter_;
+     555         800 :       av_d2V_dAlpha2_[ij]+=(d2V_dAlpha2[ij]-av_d2V_dAlpha2_[ij])/av_counter_;
+     556             :     }
+     557             :   }
+     558             : //update work
+     559         800 :   double prev_tot_prob=prob_[0];
+     560        1600 :   for(unsigned i=0; i<alpha_size_; i++)
+     561         800 :     prev_tot_prob+=prob_[i+1]*prev_exp_alpha_[i];
+     562         800 :   work_+=(1-inv_gamma_)/beta_*std::log(tot_prob_/prev_tot_prob);
+     563             : 
+     564             : //update coefficients
+     565         800 :   if(av_counter_==av_stride_)
+     566             :   {
+     567          16 :     update_alpha();
+     568          16 :     tg_counter_++;
+     569          16 :     if(tg_counter_==tg_stride_)
+     570             :     {
+     571          12 :       update_tg_and_rct();
+     572          12 :       tg_counter_=0;
+     573             :     }
+     574             :     //reset the ensemble averages
+     575          16 :     av_counter_=0;
+     576             :     std::fill(av_dV_dAlpha_.begin(),av_dV_dAlpha_.end(),0);
+     577             :     std::fill(av_dV_dAlpha_prod_.begin(),av_dV_dAlpha_prod_.end(),0);
+     578             :     std::fill(av_d2V_dAlpha2_.begin(),av_d2V_dAlpha2_.end(),0);
+     579             :   }
+     580             : }
+     581             : 
+     582          16 : void VesDeltaF::update_tg_and_rct()
+     583             : {
+     584             : //calculate target averages
+     585          16 :   double Z_0=norm_[0];
+     586          32 :   for(unsigned i=0; i<alpha_size_; i++)
+     587          16 :     Z_0+=norm_[i+1]*exp_alpha_[i];
+     588          16 :   double Z_tg=0;
+     589             :   std::fill(tg_dV_dAlpha_.begin(),tg_dV_dAlpha_.end(),0);
+     590             :   std::fill(tg_d2V_dAlpha2_.begin(),tg_d2V_dAlpha2_.end(),0);
+     591        1116 :   for(Grid::index_t t=rank_; t<grid_p_[0]->getSize(); t+=NumParallel_)
+     592             :   { //TODO can we recycle some code?
+     593        1100 :     std::vector<double> prob(grid_p_.size());
+     594        3300 :     for(unsigned n=0; n<grid_p_.size(); n++)
+     595        2200 :       prob[n]=grid_p_[n]->getValue(t);
+     596        1100 :     double tot_prob=prob[0];
+     597        2200 :     for(unsigned i=0; i<alpha_size_; i++)
+     598        1100 :       tot_prob+=prob[i+1]*exp_alpha_[i];
+     599        1100 :     std::vector<double> dV_dAlpha(alpha_size_);
+     600        1100 :     std::vector<double> d2V_dAlpha2(sym_alpha_size_);
+     601        2200 :     for(unsigned i=0; i<alpha_size_; i++)
+     602        1100 :       dV_dAlpha[i]=-(1-inv_gamma_)/tot_prob*prob[i+1]*exp_alpha_[i];
+     603        2200 :     for(unsigned i=0; i<alpha_size_; i++)
+     604             :     {
+     605        1100 :       d2V_dAlpha2[get_index(i,i)]=-beta_*dV_dAlpha[i];
+     606        2200 :       for(unsigned j=i; j<alpha_size_; j++)
+     607        1100 :         d2V_dAlpha2[get_index(i,j)]-=beta_/(1-inv_gamma_)*dV_dAlpha[i]*dV_dAlpha[j];
+     608             :     }
+     609        1100 :     const double unnorm_tg_p=std::pow(tot_prob,inv_gamma_);
+     610        1100 :     Z_tg+=unnorm_tg_p;
+     611        2200 :     for(unsigned i=0; i<alpha_size_; i++)
+     612        1100 :       tg_dV_dAlpha_[i]+=unnorm_tg_p*dV_dAlpha[i];
+     613        2200 :     for(unsigned ij=0; ij<sym_alpha_size_; ij++)
+     614        1100 :       tg_d2V_dAlpha2_[ij]+=unnorm_tg_p*d2V_dAlpha2[ij];
+     615             :   }
+     616          16 :   if(NumParallel_>1)
+     617             :   {
+     618          10 :     comm.Sum(Z_tg);
+     619          10 :     comm.Sum(tg_dV_dAlpha_);
+     620          10 :     comm.Sum(tg_d2V_dAlpha2_);
+     621             :   }
+     622          32 :   for(unsigned i=0; i<alpha_size_; i++)
+     623          16 :     tg_dV_dAlpha_[i]/=Z_tg;
+     624          32 :   for(unsigned ij=0; ij<sym_alpha_size_; ij++)
+     625          16 :     tg_d2V_dAlpha2_[ij]/=Z_tg;
+     626          16 :   getPntrToComponent("rct")->set(-1./beta_*std::log(Z_tg/Z_0)); //Z_tg is the best available estimate of Z_V
+     627          16 : }
+     628             : 
+     629          16 : void VesDeltaF::update_alpha()
+     630             : {
+     631             : //combining the averages of multiple walkers
+     632          16 :   if(NumWalkers_>1)
+     633             :   {
+     634           8 :     if(comm.Get_rank()==0) //sum only once: in the first rank of each walker
+     635             :     {
+     636           8 :       multi_sim_comm.Sum(av_dV_dAlpha_);
+     637           8 :       multi_sim_comm.Sum(av_dV_dAlpha_prod_);
+     638           8 :       multi_sim_comm.Sum(av_d2V_dAlpha2_);
+     639          16 :       for(unsigned i=0; i<alpha_size_; i++)
+     640           8 :         av_dV_dAlpha_[i]/=NumWalkers_;
+     641          16 :       for(unsigned ij=0; ij<sym_alpha_size_; ij++)
+     642             :       {
+     643           8 :         av_dV_dAlpha_prod_[ij]/=NumWalkers_;
+     644           8 :         av_d2V_dAlpha2_[ij]/=NumWalkers_;
+     645             :       }
+     646             :     }
+     647           8 :     if(comm.Get_size()>1)//if there are more ranks for each walker, everybody has to know
+     648             :     {
+     649           0 :       comm.Bcast(av_dV_dAlpha_,0);
+     650           0 :       comm.Bcast(av_dV_dAlpha_prod_,0);
+     651           0 :       comm.Bcast(av_d2V_dAlpha2_,0);
+     652             :     }
+     653             :   }
+     654             :   //set work and reset it
+     655          16 :   getPntrToComponent("work")->set(work_);
+     656          16 :   work_=0;
+     657             : 
+     658             : //build the gradient and the Hessian of the functional
+     659          16 :   std::vector<double> grad_omega(alpha_size_);
+     660          16 :   std::vector<double> hess_omega(sym_alpha_size_);
+     661          32 :   for(unsigned i=0; i<alpha_size_; i++)
+     662             :   {
+     663          16 :     grad_omega[i]=tg_dV_dAlpha_[i]-av_dV_dAlpha_[i];
+     664          32 :     for(unsigned j=i; j<alpha_size_; j++)
+     665             :     {
+     666          16 :       const unsigned ij=get_index(i,j);
+     667          16 :       hess_omega[ij]=beta_*(av_dV_dAlpha_prod_[ij]-av_dV_dAlpha_[i]*av_dV_dAlpha_[j])+tg_d2V_dAlpha2_[ij]-av_d2V_dAlpha2_[ij];
+     668             :     }
+     669             :   }
+     670             : //calculate the increment and update alpha
+     671          16 :   mean_counter_++;
+     672             :   long long unsigned mean_weight=mean_counter_;
+     673          16 :   if(mean_weight_tau_>0 && mean_weight_tau_<mean_counter_)
+     674             :     mean_weight=mean_weight_tau_;
+     675          16 :   std::vector<double> damping(alpha_size_);
+     676          32 :   for(unsigned i=0; i<alpha_size_; i++)
+     677             :   {
+     678          16 :     double increment_i=grad_omega[i];
+     679          32 :     for(unsigned j=0; j<alpha_size_; j++)
+     680          16 :       increment_i+=hess_omega[get_index(i,j)]*(inst_alpha_[j]-mean_alpha_[j]);
+     681          16 :     if(!damping_off_)
+     682           8 :       past_increment2_[i]+=increment_i*increment_i;
+     683          16 :     damping[i]=std::sqrt(past_increment2_[i]);
+     684          16 :     prev_exp_alpha_[i]=std::exp(-beta_*mean_alpha_[i]);
+     685          16 :     inst_alpha_[i]-=minimization_step_/damping[i]*increment_i;
+     686          16 :     mean_alpha_[i]+=(inst_alpha_[i]-mean_alpha_[i])/mean_weight;
+     687          16 :     exp_alpha_[i]=std::exp(-beta_*mean_alpha_[i]);
+     688             :   }
+     689             : 
+     690             : //update the Alpha file
+     691          16 :   if(mean_counter_%print_stride_==0)
+     692             :   {
+     693          16 :     alphaOfile_.printField("time",getTime());
+     694          32 :     for(unsigned i=0; i<alpha_size_; i++)
+     695             :     {
+     696          16 :       const std::string index(std::to_string(i+1));
+     697          32 :       alphaOfile_.printField("alpha_"+index,mean_alpha_[i]);
+     698          32 :       alphaOfile_.printField("auxiliary_"+index,inst_alpha_[i]);
+     699          32 :       alphaOfile_.printField("damping_"+index,damping[i]);
+     700             :     }
+     701          16 :     alphaOfile_.printField();
+     702             :   }
+     703          16 : }
+     704             : 
+     705             : //mapping of a [alpha_size_]x[alpha_size_] symmetric matrix into a vector of size sym_alpha_size_, useful for the communicator
+     706        4632 : inline unsigned VesDeltaF::get_index(const unsigned i, const unsigned j) const
+     707             : {
+     708        4632 :   if(i<=j)
+     709        4632 :     return j+i*(alpha_size_-1)-i*(i-1)/2;
+     710             :   else
+     711           0 :     return get_index(j,i);
+     712             : }
+     713             : 
+     714             : }
+     715             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/VesLinearExpansion.cpp.func-sort-c.html b/coverage/ves/VesLinearExpansion.cpp.func-sort-c.html new file mode 100644 index 000000000000..ac9ef8261231 --- /dev/null +++ b/coverage/ves/VesLinearExpansion.cpp.func-sort-c.html @@ -0,0 +1,157 @@ + + + + + + + + LCOV - plumed test coverage - ves/VesLinearExpansion.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - VesLinearExpansion.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:13914496.5 %
Date:2024-04-19 12:12:35Functions:182185.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves18VesLinearExpansionC2ERKNS_13ActionOptionsE0
_ZN4PLMD3ves18VesLinearExpansionD2Ev0
_ZNK4PLMD3ves18VesLinearExpansion23calculateReweightFactorEv0
_ZN4PLMD3ves18VesLinearExpansion26restartTargetDistributionsEv8
_ZN4PLMD3ves18VesLinearExpansion25writeTargetDistProjToFileEv13
_ZN4PLMD3ves18VesLinearExpansion22setupFesProjFileOutputEv17
_ZN4PLMD3ves18VesLinearExpansion18resetFesFileOutputEv36
_ZN4PLMD3ves18VesLinearExpansion18writeFesProjToFileEv36
_ZN4PLMD3ves18VesLinearExpansion19resetBiasFileOutputEv36
_ZN4PLMD3ves18VesLinearExpansion21writeTargetDistToFileEv82
_ZN4PLMD3ves18VesLinearExpansion18setupFesFileOutputEv83
_ZN4PLMD3ves18VesLinearExpansion19setupBiasFileOutputEv87
_ZN4PLMD3ves18VesLinearExpansionC1ERKNS_13ActionOptionsE90
_ZN4PLMD3ves18VesLinearExpansionD0Ev90
_ZN4PLMD3ves18VesLinearExpansionD1Ev90
_ZN4PLMD3ves18VesLinearExpansion16registerKeywordsERNS_8KeywordsE92
_ZN4PLMD3ves18VesLinearExpansion14writeFesToFileEv169
_ZN4PLMD3ves18VesLinearExpansion15writeBiasToFileEv173
_ZN4PLMD3ves18VesLinearExpansion25updateTargetDistributionsEv355
_ZN4PLMD3ves18VesLinearExpansion6updateEv23750
_ZN4PLMD3ves18VesLinearExpansion9calculateEv23750
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/VesLinearExpansion.cpp.func.html b/coverage/ves/VesLinearExpansion.cpp.func.html new file mode 100644 index 000000000000..d3ae945dd92a --- /dev/null +++ b/coverage/ves/VesLinearExpansion.cpp.func.html @@ -0,0 +1,157 @@ + + + + + + + + LCOV - plumed test coverage - ves/VesLinearExpansion.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - VesLinearExpansion.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:13914496.5 %
Date:2024-04-19 12:12:35Functions:182185.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves18VesLinearExpansion14writeFesToFileEv169
_ZN4PLMD3ves18VesLinearExpansion15writeBiasToFileEv173
_ZN4PLMD3ves18VesLinearExpansion16registerKeywordsERNS_8KeywordsE92
_ZN4PLMD3ves18VesLinearExpansion18resetFesFileOutputEv36
_ZN4PLMD3ves18VesLinearExpansion18setupFesFileOutputEv83
_ZN4PLMD3ves18VesLinearExpansion18writeFesProjToFileEv36
_ZN4PLMD3ves18VesLinearExpansion19resetBiasFileOutputEv36
_ZN4PLMD3ves18VesLinearExpansion19setupBiasFileOutputEv87
_ZN4PLMD3ves18VesLinearExpansion21writeTargetDistToFileEv82
_ZN4PLMD3ves18VesLinearExpansion22setupFesProjFileOutputEv17
_ZN4PLMD3ves18VesLinearExpansion25updateTargetDistributionsEv355
_ZN4PLMD3ves18VesLinearExpansion25writeTargetDistProjToFileEv13
_ZN4PLMD3ves18VesLinearExpansion26restartTargetDistributionsEv8
_ZN4PLMD3ves18VesLinearExpansion6updateEv23750
_ZN4PLMD3ves18VesLinearExpansion9calculateEv23750
_ZN4PLMD3ves18VesLinearExpansionC1ERKNS_13ActionOptionsE90
_ZN4PLMD3ves18VesLinearExpansionC2ERKNS_13ActionOptionsE0
_ZN4PLMD3ves18VesLinearExpansionD0Ev90
_ZN4PLMD3ves18VesLinearExpansionD1Ev90
_ZN4PLMD3ves18VesLinearExpansionD2Ev0
_ZNK4PLMD3ves18VesLinearExpansion23calculateReweightFactorEv0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/VesLinearExpansion.cpp.gcov.html b/coverage/ves/VesLinearExpansion.cpp.gcov.html new file mode 100644 index 000000000000..9537a0909268 --- /dev/null +++ b/coverage/ves/VesLinearExpansion.cpp.gcov.html @@ -0,0 +1,634 @@ + + + + + + + + LCOV - plumed test coverage - ves/VesLinearExpansion.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - VesLinearExpansion.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:13914496.5 %
Date:2024-04-19 12:12:35Functions:182185.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "VesBias.h"
+      24             : #include "LinearBasisSetExpansion.h"
+      25             : #include "CoeffsVector.h"
+      26             : #include "CoeffsMatrix.h"
+      27             : #include "BasisFunctions.h"
+      28             : #include "Optimizer.h"
+      29             : #include "TargetDistribution.h"
+      30             : #include "VesTools.h"
+      31             : 
+      32             : #include "bias/Bias.h"
+      33             : #include "core/ActionRegister.h"
+      34             : #include "core/ActionSet.h"
+      35             : #include "core/PlumedMain.h"
+      36             : 
+      37             : 
+      38             : namespace PLMD {
+      39             : namespace ves {
+      40             : 
+      41             : //+PLUMEDOC VES_BIAS VES_LINEAR_EXPANSION
+      42             : /*
+      43             : Linear basis set expansion bias.
+      44             : 
+      45             : This VES bias action takes the bias potential to be a linear expansion
+      46             : in some basis set that is written as a product of one-dimensional basis functions.
+      47             : For example, for one CV the bias would be written as
+      48             : \f[
+      49             : V(s_{1};\boldsymbol{\alpha}) = \sum_{i_{1}} \alpha_{i_{1}} \, f_{i_{1}}(s_{1}),
+      50             : \f]
+      51             : while for two CVs it is written as
+      52             : \f[
+      53             : V(s_{1},s_{2};\boldsymbol{\alpha}) = \sum_{i_{1},i_{2}} \alpha_{i_{1},i_{2}} \, f_{i_{1}}(s_{1}) \, f_{i_{2}}(s_{2})
+      54             : \f]
+      55             : where \f$\boldsymbol{\alpha}\f$ is the set of expansion coefficients that
+      56             : are optimized within VES. With an appropriate choice of the basis functions
+      57             : it is possible to represent any generic free energy surface.
+      58             : The relationship between the bias and the free energy surface is given by
+      59             : \f[
+      60             : V(\mathbf{s}) = - F(\mathbf{s}) - \frac{1}{\beta} \log p(\mathbf{s}).
+      61             : \f]
+      62             : where \f$p(\mathbf{s})\f$ is the target distribution that is employed in the VES simulation.
+      63             : 
+      64             : \par Basis Functions
+      65             : 
+      66             : Various one-dimensional basis functions are available in the VES code,
+      67             : see the complete list \ref ves_basisf "here".
+      68             : At the current moment we recommend to use Legendre polynomials (\ref BF_LEGENDRE)
+      69             : for non-periodic CVs and Fourier basis functions (\ref BF_FOURIER)
+      70             : for periodic CV (e.g. dihedral angles).
+      71             : 
+      72             : To use basis functions within VES_LINEAR_EXPANSION you first need to
+      73             : define them in the input file before the VES_LINEAR_EXPANSION action and
+      74             : then give their labels using the BASIS_FUNCTIONS keyword.
+      75             : 
+      76             : 
+      77             : \par Target Distributions
+      78             : 
+      79             : Various target distributions \f$p(\mathbf{s})\f$ are available in the VES code,
+      80             : see the complete list \ref ves_targetdist "here".
+      81             : 
+      82             : To use a target distribution within VES_LINEAR_EXPANSION you first need to
+      83             : define it in the input file before the VES_LINEAR_EXPANSION action and
+      84             : then give its label using the TARGET_DISTRIBUTION keyword.
+      85             : The default behavior if no TARGET_DISTRIBUTION is given is to
+      86             : employ a uniform target distribution.
+      87             : 
+      88             : Some target distribution, like the well-tempered one (\ref TD_WELLTEMPERED),
+      89             : are dynamic and need to be iteratively updated during the optimization.
+      90             : 
+      91             : \par Optimizer
+      92             : 
+      93             : In order to optimize the coefficients you will need to use VES_LINEAR_EXPANSION
+      94             : in combination with an optimizer, see the list of optimizers available in the
+      95             : VES code \ref ves_optimizer "here". At the current moment we recommend to
+      96             : use the averaged stochastic gradient decent optimizer (\ref OPT_AVERAGED_SGD).
+      97             : 
+      98             : The optimizer should be defined after the VES_LINEAR_EXPANSION action.
+      99             : 
+     100             : \par Grid
+     101             : 
+     102             : Internally the code uses grids to calculate the basis set averages
+     103             : over the target distribution that is needed for the gradient. The same grid is
+     104             : also used for the output files (see next section).
+     105             : The size of the grid is determined by the GRID_BINS keyword. By default it has
+     106             : 100 grid points in each dimension, and generally this value should be sufficient.
+     107             : 
+     108             : \par Outputting Free Energy Surfaces and Other Files
+     109             : 
+     110             : It is possible to output on-the-fly during the simulation the free energy surface
+     111             : estimated from the bias potential. How often this is done is specified within
+     112             : the \ref ves_optimizer "optimizer" by using the FES_OUTPUT keyword. The filename
+     113             : is specified by the FES_FILE keyword, but by default is it fes.LABEL.data,
+     114             : with an added suffix indicating
+     115             : the iteration number (iter-#).
+     116             : 
+     117             : For multi-dimensional case is it possible to also output projections of the
+     118             : free energy surfaces. The arguments for which to do these projections is
+     119             : specified using the numbered PROJ_ARG keywords. For these files a suffix
+     120             : indicating the projection (proj-#) will be added to the filenames.
+     121             : You will also need to specify the frequency of the output by using the
+     122             : FES_PROJ_OUTPUT keyword within the optimizer.
+     123             : 
+     124             : It is also possible to output the bias potential itself, for this the relevant
+     125             : keyword is BIAS_OUTPUT within the optimizer. The filename
+     126             : is specified by the BIAS_FILE keyword, but by default is it bias.LABEL.data,
+     127             : with an added suffix indicating the iteration number (iter-#).
+     128             : 
+     129             : Furthermore is it possible to output the target distribution, and its projections
+     130             : (i.e. marginal distributions). The filenames of these files are specified with
+     131             : the TARGETDIST_FILE, but by default is it targetdist.LABEL.data. The
+     132             : logarithm of the target distribution will also be outputted to file that has the
+     133             : added suffix log. For static target distribution these files will be outputted in
+     134             : the beginning of the
+     135             : simulation while for dynamic ones you will need to specify the frequency
+     136             : of the output by using the TARGETDIST_OUTPUT and TARGETDIST_PROJ_OUTPUT
+     137             : keywords within the optimizer.
+     138             : 
+     139             : It is also possible to output free energy surfaces and bias in post processing
+     140             : by using the \ref VES_OUTPUT_FES action. However, be aware that this action
+     141             : does does not support dynamic target distribution (e.g. well-tempered).
+     142             : 
+     143             : \par Static Bias
+     144             : 
+     145             : It is also possible to use VES_LINEAR_EXPANSION as a static bias that uses
+     146             : previously obtained coefficients. In this case the coefficients should be
+     147             : read in from the coefficient file given in the COEFFS keyword.
+     148             : 
+     149             : \par Bias Cutoff
+     150             : 
+     151             : It is possible to impose a cutoff on the bias potential using the procedure
+     152             : introduced in \cite McCarty-PRL-2015 such that the free energy surface
+     153             : is only flooded up to a certain value. The bias that results from this procedure
+     154             : can then be used as a static bias for obtaining kinetic rates.
+     155             : The value of the cutoff is given by the BIAS_CUTOFF keyword.
+     156             : To impose the cutoff the code uses a Fermi switching function \f$1/(1+e^{\lambda x})\f$
+     157             : where the parameter \f$\lambda\f$ controls how sharply the switchingfunction goes to zero.
+     158             : The default value is \f$\lambda=10\f$ but this can be changed by using the
+     159             : BIAS_CUTOFF_FERMI_LAMBDA keyword.
+     160             : 
+     161             : \par Examples
+     162             : 
+     163             : In the following example we run a VES_LINEAR_EXPANSION for one CV using
+     164             : a Legendre basis functions (\ref BF_LEGENDRE) and a uniform target
+     165             : distribution as no target distribution is specified. The coefficients
+     166             : are optimized using averaged stochastic gradient descent optimizer
+     167             : (\ref OPT_AVERAGED_SGD). Within the optimizer we specify that the
+     168             : FES should be outputted to file every 500 coefficients iterations (the
+     169             : FES_OUTPUT keyword).
+     170             : Parameters that are very specific to the problem at hand, like the
+     171             : order of the basis functions, the interval on which the
+     172             : basis functions are defined, and the step size used
+     173             : in the optimizer, are left unfilled.
+     174             : \plumedfile
+     175             : bf1: BF_LEGENDRE ORDER=__FILL__ MINIMUM=__FILL__ MAXIMUM=__FILL__
+     176             : 
+     177             : VES_LINEAR_EXPANSION ...
+     178             :  ARG=d1
+     179             :  BASIS_FUNCTIONS=bf1
+     180             :  TEMP=__FILL__
+     181             :  GRID_BINS=200
+     182             :  LABEL=b1
+     183             : ... VES_LINEAR_EXPANSION
+     184             : 
+     185             : OPT_AVERAGED_SGD ...
+     186             :  BIAS=b1
+     187             :  STRIDE=1000
+     188             :  LABEL=o1
+     189             :  STEPSIZE=__FILL__
+     190             :  FES_OUTPUT=500
+     191             :  COEFFS_OUTPUT=10
+     192             : ... OPT_AVERAGED_SGD
+     193             : \endplumedfile
+     194             : 
+     195             : In the following example we employ VES_LINEAR_EXPANSION for two CVs,
+     196             : The first CV is periodic and therefore we employ a Fourier basis functions
+     197             : (\ref BF_LEGENDRE) while the second CV is non-periodic so we employ a
+     198             : Legendre polynomials as in the previous example. For the target distribution
+     199             : we employ a well-tempered target distribution (\ref TD_WELLTEMPERED), which is
+     200             : dynamic and needs to be iteratively updated with a stride that is given
+     201             : using the TARGETDIST_STRIDE within the optimizer.
+     202             : 
+     203             : \plumedfile
+     204             : bf1: BF_FOURIER  ORDER=__FILL__ MINIMUM=__FILL__ MAXIMUM=__FILL__
+     205             : bf2: BF_LEGENDRE ORDER=__FILL__ MINIMUM=__FILL__ MAXIMUM=__FILL__
+     206             : 
+     207             : td_wt: TD_WELLTEMPERED BIASFACTOR=10.0
+     208             : 
+     209             : VES_LINEAR_EXPANSION ...
+     210             :  ARG=cv1,cv2
+     211             :  BASIS_FUNCTIONS=bf1,bf2
+     212             :  TEMP=__FILL__
+     213             :  GRID_BINS=100
+     214             :  LABEL=b1
+     215             :  TARGET_DISTRIBUTION=td_wt
+     216             : ... VES_LINEAR_EXPANSION
+     217             : 
+     218             : OPT_AVERAGED_SGD ...
+     219             :  BIAS=b1
+     220             :  STRIDE=1000
+     221             :  LABEL=o1
+     222             :  STEPSIZE=__FILL__
+     223             :  FES_OUTPUT=500
+     224             :  COEFFS_OUTPUT=10
+     225             :  TARGETDIST_STRIDE=500
+     226             : ... OPT_AVERAGED_SGD
+     227             : \endplumedfile
+     228             : 
+     229             : 
+     230             : In the following example we employ a bias cutoff such that the bias
+     231             : only fills the free energy landscape up a certain level. In this case
+     232             : the target distribution is also dynamic and needs to iteratively updated.
+     233             : 
+     234             : \plumedfile
+     235             : bf1: BF_LEGENDRE ORDER=__FILL__ MINIMUM=__FILL__ MAXIMUM=__FILL__
+     236             : bf2: BF_LEGENDRE ORDER=__FILL__ MINIMUM=__FILL__ MAXIMUM=__FILL__
+     237             : 
+     238             : VES_LINEAR_EXPANSION ...
+     239             :  ARG=cv1,cv2
+     240             :  BASIS_FUNCTIONS=bf1,bf2
+     241             :  TEMP=__FILL__
+     242             :  GRID_BINS=100
+     243             :  LABEL=b1
+     244             :  BIAS_CUTOFF=20.0
+     245             : ... VES_LINEAR_EXPANSION
+     246             : 
+     247             : OPT_AVERAGED_SGD ...
+     248             :  BIAS=b1
+     249             :  STRIDE=1000
+     250             :  LABEL=o1
+     251             :  STEPSIZE=__FILL__
+     252             :  FES_OUTPUT=500
+     253             :  COEFFS_OUTPUT=10
+     254             :  TARGETDIST_STRIDE=500
+     255             : ... OPT_AVERAGED_SGD
+     256             : \endplumedfile
+     257             : 
+     258             : The optimized bias potential can then be used as a static bias for obtaining
+     259             : kinetics. For this you need read in the final coefficients from file
+     260             : (e.g. coeffs_final.data in this case) by using the
+     261             : COEFFS keyword (also, no optimizer should be defined in the input)
+     262             : \plumedfile
+     263             : bf1: BF_LEGENDRE ORDER=__FILL__ MINIMUM=__FILL__ MAXIMUM=__FILL__
+     264             : bf2: BF_LEGENDRE ORDER=__FILL__ MINIMUM=__FILL__ MAXIMUM=__FILL__
+     265             : 
+     266             : VES_LINEAR_EXPANSION ...
+     267             :  ARG=cv1,cv2
+     268             :  BASIS_FUNCTIONS=bf1,bf2
+     269             :  TEMP=__FILL__
+     270             :  GRID_BINS=100
+     271             :  LABEL=b1
+     272             :  BIAS_CUTOFF=20.0
+     273             :  COEFFS=coeffs_final.data
+     274             : ... VES_LINEAR_EXPANSION
+     275             : \endplumedfile
+     276             : 
+     277             : 
+     278             : 
+     279             : */
+     280             : //+ENDPLUMEDOC
+     281             : 
+     282             : 
+     283             : class VesLinearExpansion : public VesBias {
+     284             : private:
+     285             :   unsigned int nargs_;
+     286             :   std::vector<BasisFunctions*> basisf_pntrs_;
+     287             :   std::unique_ptr<LinearBasisSetExpansion> bias_expansion_pntr_;
+     288             :   size_t ncoeffs_;
+     289             :   Value* valueForce2_;
+     290             :   bool all_values_inside;
+     291             :   std::vector<double> bf_values;
+     292             :   bool bf_values_set;
+     293             : public:
+     294             :   explicit VesLinearExpansion(const ActionOptions&);
+     295             :   ~VesLinearExpansion();
+     296             :   void calculate() override;
+     297             :   void update() override;
+     298             :   void updateTargetDistributions() override;
+     299             :   void restartTargetDistributions() override;
+     300             :   //
+     301             :   void setupBiasFileOutput() override;
+     302             :   void writeBiasToFile() override;
+     303             :   void resetBiasFileOutput() override;
+     304             :   //
+     305             :   void setupFesFileOutput() override;
+     306             :   void writeFesToFile() override;
+     307             :   void resetFesFileOutput() override;
+     308             :   //
+     309             :   void setupFesProjFileOutput() override;
+     310             :   void writeFesProjToFile() override;
+     311             :   //
+     312             :   void writeTargetDistToFile() override;
+     313             :   void writeTargetDistProjToFile() override;
+     314             :   //
+     315             :   double calculateReweightFactor() const override;
+     316             :   //
+     317             :   static void registerKeywords( Keywords& keys );
+     318             : };
+     319             : 
+     320             : PLUMED_REGISTER_ACTION(VesLinearExpansion,"VES_LINEAR_EXPANSION")
+     321             : 
+     322          92 : void VesLinearExpansion::registerKeywords( Keywords& keys ) {
+     323          92 :   VesBias::registerKeywords(keys);
+     324             :   //
+     325          92 :   VesBias::useInitialCoeffsKeywords(keys);
+     326          92 :   VesBias::useTargetDistributionKeywords(keys);
+     327          92 :   VesBias::useBiasCutoffKeywords(keys);
+     328          92 :   VesBias::useGridBinKeywords(keys);
+     329          92 :   VesBias::useProjectionArgKeywords(keys);
+     330             :   //
+     331          92 :   keys.use("ARG");
+     332         184 :   keys.add("compulsory","BASIS_FUNCTIONS","the label of the one dimensional basis functions that should be used.");
+     333         184 :   keys.addOutputComponent("force2","default","the instantaneous value of the squared force due to this bias potential.");
+     334          92 : }
+     335             : 
+     336          90 : VesLinearExpansion::VesLinearExpansion(const ActionOptions&ao):
+     337             :   PLUMED_VES_VESBIAS_INIT(ao),
+     338          90 :   nargs_(getNumberOfArguments()),
+     339          90 :   basisf_pntrs_(0),
+     340          90 :   valueForce2_(NULL),
+     341          90 :   all_values_inside(true),
+     342          90 :   bf_values(0),
+     343          90 :   bf_values_set(false)
+     344             : {
+     345             :   std::vector<std::string> basisf_labels;
+     346          90 :   parseMultipleValues("BASIS_FUNCTIONS",basisf_labels,nargs_);
+     347          90 :   checkRead();
+     348             : 
+     349          90 :   std::string error_msg = "";
+     350         180 :   basisf_pntrs_ = VesTools::getPointersFromLabels<BasisFunctions*>(basisf_labels,plumed.getActionSet(),error_msg);
+     351          90 :   if(error_msg.size()>0) {plumed_merror("Error in keyword BASIS_FUNCTIONS of "+getName()+": "+error_msg);}
+     352             :   //
+     353             : 
+     354          90 :   std::vector<Value*> args_pntrs = getArguments();
+     355             :   // check arguments and basis functions
+     356             :   // this is done to avoid some issues with integration of target distribution
+     357             :   // and periodic CVs, needs to be fixed later on.
+     358         207 :   for(unsigned int i=0; i<args_pntrs.size(); i++) {
+     359         117 :     if(args_pntrs[i]->isPeriodic() && !(basisf_pntrs_[i]->arePeriodic()) ) {
+     360           0 :       plumed_merror("argument "+args_pntrs[i]->getName()+" is periodic while the basis functions " + basisf_pntrs_[i]->getLabel()+ " are not. You need to use the COMBINE action to remove the periodicity of the argument if you want to use these basis functions");
+     361             :     }
+     362         117 :     else if(!(args_pntrs[i]->isPeriodic()) && basisf_pntrs_[i]->arePeriodic() ) {
+     363           1 :       log.printf("  warning: argument %s is not periodic while the basis functions %s used for it are periodic\n",args_pntrs[i]->getName().c_str(),basisf_pntrs_[i]->getLabel().c_str());
+     364             :     }
+     365             :   }
+     366             : 
+     367          90 :   addCoeffsSet(args_pntrs,basisf_pntrs_);
+     368          90 :   ncoeffs_ = numberOfCoeffs();
+     369          90 :   bool coeffs_read = readCoeffsFromFiles();
+     370             : 
+     371          90 :   checkThatTemperatureIsGiven();
+     372         180 :   bias_expansion_pntr_ = Tools::make_unique<LinearBasisSetExpansion>(getLabel(),getBeta(),comm,args_pntrs,basisf_pntrs_,getCoeffsPntr());
+     373          90 :   bias_expansion_pntr_->linkVesBias(this);
+     374          90 :   bias_expansion_pntr_->setGridBins(this->getGridBins());
+     375             :   //
+     376          90 :   bf_values.assign(ncoeffs_,0.0);
+     377             : 
+     378             : 
+     379             : 
+     380          90 :   if(getNumberOfTargetDistributionPntrs()==0) {
+     381          45 :     log.printf("  using an uniform target distribution: \n");
+     382          45 :     bias_expansion_pntr_->setupUniformTargetDistribution();
+     383             :     disableStaticTargetDistFileOutput();
+     384             :   }
+     385          45 :   else if(getNumberOfTargetDistributionPntrs()==1) {
+     386          51 :     if(biasCutoffActive()) {getTargetDistributionPntrs()[0]->setupBiasCutoff();}
+     387          45 :     bias_expansion_pntr_->setupTargetDistribution(getTargetDistributionPntrs()[0]);
+     388          90 :     log.printf("  using target distribution of type %s with label %s \n",getTargetDistributionPntrs()[0]->getName().c_str(),getTargetDistributionPntrs()[0]->getLabel().c_str());
+     389             :   }
+     390             :   else {
+     391           0 :     plumed_merror("problem with the TARGET_DISTRIBUTION keyword, either give no label or just one label.");
+     392             :   }
+     393          90 :   setTargetDistAverages(bias_expansion_pntr_->TargetDistAverages());
+     394             :   //
+     395          90 :   if(coeffs_read && biasCutoffActive()) {
+     396           1 :     VesLinearExpansion::updateTargetDistributions();
+     397             :   }
+     398             :   //
+     399          90 :   if(coeffs_read) {
+     400           4 :     VesLinearExpansion::setupBiasFileOutput();
+     401           4 :     VesLinearExpansion::writeBiasToFile();
+     402             :   }
+     403             : 
+     404         180 :   addComponent("force2"); componentIsNotPeriodic("force2");
+     405          90 :   valueForce2_=getPntrToComponent("force2");
+     406          90 : }
+     407             : 
+     408             : 
+     409         180 : VesLinearExpansion::~VesLinearExpansion() {
+     410         270 : }
+     411             : 
+     412             : 
+     413       23750 : void VesLinearExpansion::calculate() {
+     414             : 
+     415       23750 :   std::vector<double> cv_values(nargs_);
+     416       23750 :   std::vector<double> forces(nargs_);
+     417             : 
+     418       60967 :   for(unsigned int k=0; k<nargs_; k++) {
+     419       37217 :     cv_values[k]=getArgument(k);
+     420             :   }
+     421             : 
+     422       23750 :   all_values_inside = true;
+     423       23750 :   double bias = bias_expansion_pntr_->getBiasAndForces(cv_values,all_values_inside,forces,bf_values);
+     424       23750 :   if(biasCutoffActive()) {
+     425          63 :     applyBiasCutoff(bias,forces,bf_values);
+     426          63 :     bf_values[0]=1.0;
+     427             :   }
+     428             :   double totalForce2 = 0.0;
+     429       23750 :   if(all_values_inside) {
+     430       60408 :     for(unsigned int k=0; k<nargs_; k++) {
+     431       36852 :       setOutputForce(k,forces[k]);
+     432       36852 :       totalForce2 += forces[k]*forces[k];
+     433             :     }
+     434             :   }
+     435             : 
+     436       23750 :   setBias(bias);
+     437       23750 :   valueForce2_->set(totalForce2);
+     438             : 
+     439       23750 :   bf_values_set = true;
+     440       23750 : }
+     441             : 
+     442             : 
+     443       23750 : void VesLinearExpansion::update() {
+     444       23750 :   if(!bf_values_set) {
+     445           0 :     warning("VesLinearExpansion::update() is being called without calling VesLinearExpansion::calculate() first to calculate the basis function values. This can lead to incorrect behavior.");
+     446             :   }
+     447       23750 :   if(all_values_inside && bf_values_set) {
+     448       23556 :     addToSampledAverages(bf_values);
+     449             :   }
+     450             :   std::fill(bf_values.begin(), bf_values.end(), 0.0);
+     451       23750 :   bf_values_set = false;
+     452       23750 : }
+     453             : 
+     454             : 
+     455             : 
+     456             : 
+     457             : 
+     458             : 
+     459         355 : void VesLinearExpansion::updateTargetDistributions() {
+     460         355 :   bias_expansion_pntr_->updateTargetDistribution();
+     461         355 :   setTargetDistAverages(bias_expansion_pntr_->TargetDistAverages());
+     462         355 : }
+     463             : 
+     464             : 
+     465           8 : void VesLinearExpansion::restartTargetDistributions() {
+     466          16 :   bias_expansion_pntr_->readInRestartTargetDistribution(getCurrentTargetDistOutputFilename());
+     467           8 :   bias_expansion_pntr_->restartTargetDistribution();
+     468           8 :   setTargetDistAverages(bias_expansion_pntr_->TargetDistAverages());
+     469           8 : }
+     470             : 
+     471             : 
+     472          87 : void VesLinearExpansion::setupBiasFileOutput() {
+     473          87 :   bias_expansion_pntr_->setupBiasGrid(true);
+     474          87 : }
+     475             : 
+     476             : 
+     477         173 : void VesLinearExpansion::writeBiasToFile() {
+     478         173 :   bias_expansion_pntr_->updateBiasGrid();
+     479         519 :   auto ofile_pntr = getOFile(getCurrentBiasOutputFilename(),useMultipleWalkers());
+     480         173 :   bias_expansion_pntr_->writeBiasGridToFile(*ofile_pntr);
+     481         173 :   if(biasCutoffActive()) {
+     482           5 :     bias_expansion_pntr_->updateBiasWithoutCutoffGrid();
+     483          15 :     auto ofile_pntr2 = getOFile(getCurrentBiasOutputFilename("without-cutoff"),useMultipleWalkers());
+     484           5 :     bias_expansion_pntr_->writeBiasWithoutCutoffGridToFile(*ofile_pntr2);
+     485           5 :   }
+     486         173 : }
+     487             : 
+     488             : 
+     489          36 : void VesLinearExpansion::resetBiasFileOutput() {
+     490             :   bias_expansion_pntr_->resetStepOfLastBiasGridUpdate();
+     491          36 : }
+     492             : 
+     493             : 
+     494          83 : void VesLinearExpansion::setupFesFileOutput() {
+     495          83 :   bias_expansion_pntr_->setupFesGrid();
+     496          83 : }
+     497             : 
+     498             : 
+     499         169 : void VesLinearExpansion::writeFesToFile() {
+     500         169 :   bias_expansion_pntr_->updateFesGrid();
+     501         507 :   auto ofile_pntr = getOFile(getCurrentFesOutputFilename(),useMultipleWalkers());
+     502         169 :   bias_expansion_pntr_->writeFesGridToFile(*ofile_pntr);
+     503         169 : }
+     504             : 
+     505             : 
+     506          36 : void VesLinearExpansion::resetFesFileOutput() {
+     507             :   bias_expansion_pntr_->resetStepOfLastFesGridUpdate();
+     508          36 : }
+     509             : 
+     510             : 
+     511          17 : void VesLinearExpansion::setupFesProjFileOutput() {
+     512          17 :   if(getNumberOfProjectionArguments()>0) {
+     513           8 :     bias_expansion_pntr_->setupFesProjGrid();
+     514             :   }
+     515          17 : }
+     516             : 
+     517             : 
+     518          36 : void VesLinearExpansion::writeFesProjToFile() {
+     519          36 :   bias_expansion_pntr_->updateFesGrid();
+     520          72 :   for(unsigned int i=0; i<getNumberOfProjectionArguments(); i++) {
+     521             :     std::string suffix;
+     522          36 :     Tools::convert(i+1,suffix);
+     523          36 :     suffix = "proj-" + suffix;
+     524          72 :     auto ofile_pntr = getOFile(getCurrentFesOutputFilename(suffix),useMultipleWalkers());
+     525             :     std::vector<std::string> args = getProjectionArgument(i);
+     526          36 :     bias_expansion_pntr_->writeFesProjGridToFile(args,*ofile_pntr);
+     527          36 :   }
+     528          36 : }
+     529             : 
+     530             : 
+     531          82 : void VesLinearExpansion::writeTargetDistToFile() {
+     532         164 :   auto ofile1_pntr = getOFile(getCurrentTargetDistOutputFilename(),useMultipleWalkers());
+     533         164 :   auto ofile2_pntr = getOFile(getCurrentTargetDistOutputFilename("log"),useMultipleWalkers());
+     534          82 :   bias_expansion_pntr_->writeTargetDistGridToFile(*ofile1_pntr);
+     535          82 :   bias_expansion_pntr_->writeLogTargetDistGridToFile(*ofile2_pntr);
+     536          82 : }
+     537             : 
+     538             : 
+     539          13 : void VesLinearExpansion::writeTargetDistProjToFile() {
+     540          33 :   for(unsigned int i=0; i<getNumberOfProjectionArguments(); i++) {
+     541             :     std::string suffix;
+     542          20 :     Tools::convert(i+1,suffix);
+     543          20 :     suffix = "proj-" + suffix;
+     544          40 :     auto ofile_pntr = getOFile(getCurrentTargetDistOutputFilename(suffix),useMultipleWalkers());
+     545             :     std::vector<std::string> args = getProjectionArgument(i);
+     546          20 :     bias_expansion_pntr_->writeTargetDistProjGridToFile(args,*ofile_pntr);
+     547          20 :   }
+     548          13 : }
+     549             : 
+     550             : 
+     551           0 : double VesLinearExpansion::calculateReweightFactor() const {
+     552           0 :   return bias_expansion_pntr_->calculateReweightFactor();
+     553             : }
+     554             : 
+     555             : 
+     556             : }
+     557             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/VesTools.cpp.func-sort-c.html b/coverage/ves/VesTools.cpp.func-sort-c.html new file mode 100644 index 000000000000..704c19beeee0 --- /dev/null +++ b/coverage/ves/VesTools.cpp.func-sort-c.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - ves/VesTools.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - VesTools.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:353892.1 %
Date:2024-04-19 12:12:35Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves8VesTools14copyGridValuesEPNS_8GridBaseES3_8
_ZN4PLMD3ves8VesTools15getGridFileInfoERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS7_RSt6vectorIS7_SaIS7_EESE_SE_RSB_IbSaIbEERSB_IjSaIjEERb9
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/VesTools.cpp.func.html b/coverage/ves/VesTools.cpp.func.html new file mode 100644 index 000000000000..f1d09149fcf3 --- /dev/null +++ b/coverage/ves/VesTools.cpp.func.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - ves/VesTools.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - VesTools.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:353892.1 %
Date:2024-04-19 12:12:35Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves8VesTools14copyGridValuesEPNS_8GridBaseES3_8
_ZN4PLMD3ves8VesTools15getGridFileInfoERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS7_RSt6vectorIS7_SaIS7_EESE_SE_RSB_IbSaIbEERSB_IjSaIjEERb9
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/VesTools.cpp.gcov.html b/coverage/ves/VesTools.cpp.gcov.html new file mode 100644 index 000000000000..13f9cdef6c14 --- /dev/null +++ b/coverage/ves/VesTools.cpp.gcov.html @@ -0,0 +1,171 @@ + + + + + + + + LCOV - plumed test coverage - ves/VesTools.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - VesTools.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:353892.1 %
Date:2024-04-19 12:12:35Functions:22100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "VesTools.h"
+      24             : 
+      25             : #include "tools/Grid.h"
+      26             : #include "tools/IFile.h"
+      27             : #include "tools/Exception.h"
+      28             : 
+      29             : 
+      30             : namespace PLMD {
+      31             : namespace ves {
+      32             : 
+      33             : 
+      34           8 : void VesTools::copyGridValues(GridBase* grid_pntr_orig, GridBase* grid_pntr_copy) {
+      35             :   // plumed_massert(grid_pntr_orig!=NULL,"grid not defined");
+      36             :   // plumed_massert(grid_pntr_copy!=NULL,"grid not defined");
+      37           8 :   plumed_massert(grid_pntr_orig->getSize()==grid_pntr_copy->getSize(),"the two grids are not of the same size");
+      38           8 :   plumed_massert(grid_pntr_orig->getDimension()==grid_pntr_copy->getDimension(),"the two grids are not of the same dimension");
+      39             :   //
+      40         808 :   for(Grid::index_t i=0; i<grid_pntr_orig->getSize(); i++) {
+      41         800 :     double value = grid_pntr_orig->getValue(i);
+      42         800 :     grid_pntr_copy->setValue(i,value);
+      43             :   }
+      44           8 : }
+      45             : 
+      46             : 
+      47           9 : unsigned int VesTools::getGridFileInfo(const std::string& filepath, std::string& grid_label, std::vector<std::string>& arg_labels, std::vector<std::string>& arg_min, std::vector<std::string>& arg_max, std::vector<bool>& arg_periodic, std::vector<unsigned int>& arg_nbins, bool& derivatives) {
+      48             : 
+      49           9 :   IFile ifile; ifile.open(filepath);
+      50             :   std::vector<std::string> fields;
+      51           9 :   ifile.scanFieldList(fields);
+      52           9 :   ifile.allowIgnoredFields();
+      53           9 :   ifile.scanField();
+      54             : 
+      55             :   unsigned int nargs=0;
+      56          31 :   for(unsigned int i=0; i<fields.size(); i++) {
+      57          31 :     if(fields[i]=="min_"+fields[0]) {
+      58           9 :       derivatives = false;
+      59           9 :       nargs = i-1;
+      60           9 :       break;
+      61             :     }
+      62          22 :     else if(fields[i]=="der_"+fields[0]) {
+      63           0 :       derivatives = true;
+      64           0 :       nargs = i-1;
+      65           0 :       break;
+      66             :     }
+      67             :   }
+      68             : 
+      69           9 :   grid_label = fields[nargs];
+      70             : 
+      71           9 :   arg_labels.assign(nargs,"");
+      72           9 :   arg_min.assign(nargs,"");
+      73          18 :   arg_max.assign(nargs,"");
+      74             :   arg_periodic.assign(nargs,false);
+      75           9 :   arg_nbins.assign(nargs,0);
+      76          22 :   for(unsigned int i=0; i<nargs; i++) {
+      77          13 :     arg_labels[i] = fields[i];
+      78          26 :     ifile.scanField("min_"+arg_labels[i],arg_min[i]);
+      79          26 :     ifile.scanField("max_"+arg_labels[i],arg_max[i]);
+      80             :     std::string str_periodic;
+      81          26 :     ifile.scanField("periodic_"+arg_labels[i],str_periodic);
+      82          13 :     if(str_periodic=="true") {arg_periodic[i]=true;}
+      83             :     int nbins;
+      84          13 :     ifile.scanField("nbins_"+arg_labels[i],nbins);
+      85          13 :     arg_nbins[i] = static_cast<unsigned int>(nbins);
+      86             :   }
+      87           9 :   ifile.scanField();
+      88           9 :   ifile.close();
+      89           9 :   return nargs;
+      90           9 : }
+      91             : 
+      92             : 
+      93             : }
+      94             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/VesTools.h.func-sort-c.html b/coverage/ves/VesTools.h.func-sort-c.html new file mode 100644 index 000000000000..171a94692313 --- /dev/null +++ b/coverage/ves/VesTools.h.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - ves/VesTools.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - VesTools.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:213265.6 %
Date:2024-04-19 12:12:35Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves8VesTools21getPointersFromLabelsIPNS0_7VesBiasEEESt6vectorIT_SaIS6_EERKS5_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISE_EERKNS_9ActionSetERSE_82
_ZN4PLMD3ves8VesTools21getPointersFromLabelsIPNS0_14BasisFunctionsEEESt6vectorIT_SaIS6_EERKS5_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISE_EERKNS_9ActionSetERSE_163
_ZN4PLMD3ves8VesTools14convertDbl2StrEdRNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEj167
_ZN4PLMD3ves8VesTools19getPointerFromLabelIPNS0_18TargetDistributionEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_9ActionSetERSB_296
_ZN4PLMD3ves8VesTools21getPointersFromLabelsIPNS0_18TargetDistributionEEESt6vectorIT_SaIS6_EERKS5_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISE_EERKNS_9ActionSetERSE_417
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/VesTools.h.func.html b/coverage/ves/VesTools.h.func.html new file mode 100644 index 000000000000..7d36a3c6a969 --- /dev/null +++ b/coverage/ves/VesTools.h.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - ves/VesTools.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - VesTools.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:213265.6 %
Date:2024-04-19 12:12:35Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves8VesTools14convertDbl2StrEdRNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEj167
_ZN4PLMD3ves8VesTools19getPointerFromLabelIPNS0_18TargetDistributionEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_9ActionSetERSB_296
_ZN4PLMD3ves8VesTools21getPointersFromLabelsIPNS0_14BasisFunctionsEEESt6vectorIT_SaIS6_EERKS5_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISE_EERKNS_9ActionSetERSE_163
_ZN4PLMD3ves8VesTools21getPointersFromLabelsIPNS0_18TargetDistributionEEESt6vectorIT_SaIS6_EERKS5_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISE_EERKNS_9ActionSetERSE_417
_ZN4PLMD3ves8VesTools21getPointersFromLabelsIPNS0_7VesBiasEEESt6vectorIT_SaIS6_EERKS5_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISE_EERKNS_9ActionSetERSE_82
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/VesTools.h.gcov.html b/coverage/ves/VesTools.h.gcov.html new file mode 100644 index 000000000000..ccb59b59cd25 --- /dev/null +++ b/coverage/ves/VesTools.h.gcov.html @@ -0,0 +1,217 @@ + + + + + + + + LCOV - plumed test coverage - ves/VesTools.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - VesTools.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:213265.6 %
Date:2024-04-19 12:12:35Functions:55100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_ves_VesTools_h
+      23             : #define __PLUMED_ves_VesTools_h
+      24             : 
+      25             : #include <string>
+      26             : #include <sstream>
+      27             : #include <iomanip>
+      28             : #include <limits>
+      29             : #include <vector>
+      30             : 
+      31             : #include "core/ActionSet.h"
+      32             : 
+      33             : 
+      34             : namespace PLMD {
+      35             : 
+      36             : class GridBase;
+      37             : 
+      38             : namespace ves {
+      39             : 
+      40             : class VesTools {
+      41             : public:
+      42             :   // Convert double into a string with more digits
+      43             :   static void convertDbl2Str(const double value,std::string& str, unsigned int precision);
+      44             :   static void convertDbl2Str(const double value,std::string& str);
+      45             :   // get log2 of unsigned int
+      46             :   static unsigned int log2(unsigned value);
+      47             :   // copy grid values
+      48             :   static void copyGridValues(GridBase* grid_pntr_orig, GridBase* grid_pntr_copy);
+      49             :   static unsigned int getGridFileInfo(const std::string&, std::string&, std::vector<std::string>&, std::vector<std::string>&, std::vector<std::string>&, std::vector<bool>&, std::vector<unsigned int>&, bool&);
+      50             :   //
+      51             :   template<typename T> static std::vector<std::string> getLabelsOfAvailableActions(const ActionSet&);
+      52             :   template<typename T> static T getPointerFromLabel(const std::string&, const ActionSet&, std::string&);
+      53             :   template<typename T> static std::vector<T> getPointersFromLabels(const std::vector<std::string>&, const ActionSet&, std::string&);
+      54             : 
+      55             : };
+      56             : 
+      57             : inline
+      58         167 : void VesTools::convertDbl2Str(const double value,std::string& str, unsigned int precision) {
+      59         167 :   std::ostringstream ostr;
+      60         167 :   ostr<<std::setprecision(precision)<<value;
+      61         167 :   str=ostr.str();
+      62         167 : }
+      63             : 
+      64             : 
+      65             : inline
+      66             : void VesTools::convertDbl2Str(const double value,std::string& str) {
+      67             :   unsigned int precision = std::numeric_limits<double>::digits10 + 1;
+      68          88 :   convertDbl2Str(value,str,precision);
+      69           9 : }
+      70             : 
+      71             : 
+      72             : inline
+      73             : unsigned int log2(unsigned value) {
+      74             :   unsigned int result = 0;
+      75             :   while(value >>= 1) result++;
+      76             :   return result;
+      77             : }
+      78             : 
+      79             : 
+      80             : template<typename T>
+      81             : std::vector<std::string> VesTools::getLabelsOfAvailableActions(const ActionSet& actionset) {
+      82             :   std::vector<std::string> avail_action_str(0);
+      83             :   std::vector<T> avail_action_pntrs = actionset.select<T>();
+      84             :   for(unsigned int i=0; i<avail_action_pntrs.size(); i++) {
+      85             :     avail_action_str.push_back(avail_action_pntrs[i]->getLabel());
+      86             :   }
+      87             :   return avail_action_str;
+      88             : }
+      89             : 
+      90             : 
+      91             : template<typename T>
+      92         296 : T VesTools::getPointerFromLabel(const std::string& action_label, const ActionSet& actionset, std::string& error_msg) {
+      93         296 :   std::vector<std::string> action_labels(1);
+      94             :   action_labels[0] = action_label;
+      95         296 :   std::vector<T> action_pntrs = getPointersFromLabels<T>(action_labels,actionset,error_msg);
+      96         592 :   return action_pntrs[0];
+      97         296 : }
+      98             : 
+      99             : 
+     100             : template<typename T>
+     101         662 : std::vector<T> VesTools::getPointersFromLabels(const std::vector<std::string>& action_labels, const ActionSet& actionset, std::string& error_msg) {
+     102         662 :   std::vector<T> action_pntrs(action_labels.size(),NULL);
+     103             :   error_msg = "";
+     104         662 :   std::vector<std::string> missing(0);
+     105        1350 :   for(unsigned int i=0; i<action_labels.size(); i++) {
+     106         688 :     action_pntrs[i] = actionset.selectWithLabel<T>(action_labels[i]);
+     107         688 :     if(action_pntrs[i]==NULL) {
+     108           0 :       missing.push_back(action_labels[i]);
+     109             :     }
+     110             :   }
+     111             :   // error handling
+     112         662 :   if(missing.size()>0) {
+     113           0 :     if(missing.size()==1) {
+     114           0 :       error_msg = "label "+missing[0]+" does not exist\n";
+     115             :     }
+     116           0 :     else if(missing.size()>1) {
+     117           0 :       std::string tmp="";
+     118           0 :       for(unsigned int j=0; j<missing.size(); j++) {tmp +=missing[j]+" ";}
+     119           0 :       error_msg = "labels "+tmp+"do not exist\n";
+     120             :     }
+     121           0 :     std::vector<T> avail_action_pntrs = actionset.select<T>();
+     122           0 :     if(avail_action_pntrs.size()>0) {
+     123             :       error_msg += "             Hint! the actions defined in the input file that can be used here are: \n";
+     124           0 :       for(unsigned int i=0; i<avail_action_pntrs.size(); i++) {
+     125           0 :         error_msg += "             " + avail_action_pntrs[i]->getName() + " with label " + avail_action_pntrs[i]->getLabel() + "\n";
+     126             :       }
+     127             :     }
+     128             :     else {
+     129             :       error_msg += "             Hint! no actions defined in the input file that can be used here, they should be defined before this actions\n";
+     130             :     }
+     131             :   }
+     132         662 :   return action_pntrs;
+     133         662 : }
+     134             : 
+     135             : 
+     136             : 
+     137             : }
+     138             : }
+     139             : 
+     140             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/WaveletCoeffs.cpp.func-sort-c.html b/coverage/ves/WaveletCoeffs.cpp.func-sort-c.html new file mode 100644 index 000000000000..f4a106f449b0 --- /dev/null +++ b/coverage/ves/WaveletCoeffs.cpp.func-sort-c.html @@ -0,0 +1,77 @@ + + + + + + + + LCOV - plumed test coverage - ves/WaveletCoeffs.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - WaveletCoeffs.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:14515096.7 %
Date:2024-04-19 12:12:35Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves11WaveletGrid21getFilterCoefficientsEjbNS1_4TypeE49
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/WaveletCoeffs.cpp.func.html b/coverage/ves/WaveletCoeffs.cpp.func.html new file mode 100644 index 000000000000..46e0742d079c --- /dev/null +++ b/coverage/ves/WaveletCoeffs.cpp.func.html @@ -0,0 +1,77 @@ + + + + + + + + LCOV - plumed test coverage - ves/WaveletCoeffs.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - WaveletCoeffs.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:14515096.7 %
Date:2024-04-19 12:12:35Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves11WaveletGrid21getFilterCoefficientsEjbNS1_4TypeE49
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/WaveletCoeffs.cpp.gcov.html b/coverage/ves/WaveletCoeffs.cpp.gcov.html new file mode 100644 index 000000000000..659d4d210334 --- /dev/null +++ b/coverage/ves/WaveletCoeffs.cpp.gcov.html @@ -0,0 +1,1059 @@ + + + + + + + + LCOV - plumed test coverage - ves/WaveletCoeffs.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - WaveletCoeffs.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:14515096.7 %
Date:2024-04-19 12:12:35Functions:11100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "WaveletGrid.h"
+      24             : #include "tools/Exception.h"
+      25             : 
+      26             : #include <algorithm>
+      27             : #include <vector>
+      28             : 
+      29             : namespace PLMD {
+      30             : namespace ves {
+      31             : 
+      32             : // returns the filter coefficients, at the moment simply a lookup table (calculated with python script)
+      33             : // the coefficients are normalized such that their sum equals 2
+      34             : // lowpass coefficients are for the scaling function, highpass for the actual wavelets
+      35          49 : std::vector<double> WaveletGrid::getFilterCoefficients(const unsigned order, const bool lowpass, const Type type) {
+      36             :   std::vector<double> h;
+      37          49 :   if (type == Type::db) {
+      38          24 :     switch(order) {
+      39           1 :     case 4:
+      40           2 :       h = { 3.2580342805129858252399799312116e-01,
+      41             :             1.0109457150918295109676137144561e+00,
+      42             :             8.9220013824675992175627925462322e-01,
+      43             :             -3.9575026235645245631378230655173e-02,
+      44             :             -2.6450716736904000825347793579567e-01,
+      45             :             4.3616300474177409352005696518972e-02,
+      46             :             4.6503601070981823162320267783798e-02,
+      47             :             -1.4986989330361497746446630685568e-02
+      48           1 :           };
+      49           1 :       break;
+      50           1 :     case 5:
+      51           2 :       h = { 2.2641898258355833140065271891217e-01,
+      52             :             8.5394354270502825787758638398373e-01,
+      53             :             1.0243269442591973472644895082340e+00,
+      54             :             1.9576696134780988134416190860065e-01,
+      55             :             -3.4265671538293490661075679781788e-01,
+      56             :             -4.5601131883547744994000794349631e-02,
+      57             :             1.0970265864213350759381881971422e-01,
+      58             :             -8.8268001083581463378502363070766e-03,
+      59             :             -1.7791870101954165156454834573196e-02,
+      60             :             4.7174279390678596629582486343679e-03
+      61           1 :           };
+      62           1 :       break;
+      63           2 :     case 6:
+      64           4 :       h = { 1.5774243200290161137644417976844e-01,
+      65             :             6.9950381407523654075930608087219e-01,
+      66             :             1.0622637598817388226990487964940e+00,
+      67             :             4.4583132293003513435536433462403e-01,
+      68             :             -3.1998659889212388574009082731209e-01,
+      69             :             -1.8351806406029547158453851807280e-01,
+      70             :             1.3788809297474488579915430364053e-01,
+      71             :             3.8923209708329416234295905496765e-02,
+      72             :             -4.4663748330189156909852954413509e-02,
+      73             :             7.8325115229715134342741711392932e-04,
+      74             :             6.7560623629278858393032436424619e-03,
+      75             :             -1.5235338056025088393496957905882e-03
+      76           2 :           };
+      77           2 :       break;
+      78           1 :     case 7:
+      79           2 :       h = { 1.1009943074562379694558700293783e-01,
+      80             :             5.6079128362552554953879280219553e-01,
+      81             :             1.0311484916361983721344586228952e+00,
+      82             :             6.6437248221107991774658785288921e-01,
+      83             :             -2.0351382246269289488793674536282e-01,
+      84             :             -3.1683501128066671181926494682557e-01,
+      85             :             1.0084646500938766744415175935501e-01,
+      86             :             1.1400344515974307479933003151018e-01,
+      87             :             -5.3782452589690873945293958513503e-02,
+      88             :             -2.3439941564206586560592526780056e-02,
+      89             :             1.7749792379361528649184265304939e-02,
+      90             :             6.0751499540213742267535934615807e-04,
+      91             :             -2.5479047181873734281842835969201e-03,
+      92             :             5.0022685312249071977463987792589e-04
+      93           1 :           };
+      94           1 :       break;
+      95           2 :     case 8:
+      96           4 :       h = { 7.6955622108152516025469935811998e-02,
+      97             :             4.4246724715225010937658112197823e-01,
+      98             :             9.5548615042774787120549717656104e-01,
+      99             :             8.2781653242239250367617842130130e-01,
+     100             :             -2.2385735333760647947087818465661e-02,
+     101             :             -4.0165863278097890809448244908708e-01,
+     102             :             6.6819409243975983261898399234724e-04,
+     103             :             1.8207635684731554581716750362830e-01,
+     104             :             -2.4563901045696636543658186724315e-02,
+     105             :             -6.2350206650278829079159237380736e-02,
+     106             :             1.9772159296701483782721098236834e-02,
+     107             :             1.2368844819631834991424668146465e-02,
+     108             :             -6.8877192568836120845077175545157e-03,
+     109             :             -5.5400454895877760883027285387925e-04,
+     110             :             9.5522971129925185115872032781681e-04,
+     111             :             -1.6613726137322542978150274883831e-04
+     112           2 :           };
+     113           2 :       break;
+     114           1 :     case 9:
+     115           2 :       h = { 5.3850349589325587074117862584899e-02,
+     116             :             3.4483430381395580033299097522104e-01,
+     117             :             8.5534906435941493452190798052470e-01,
+     118             :             9.2954571436629451763877796111046e-01,
+     119             :             1.8836954950636755623527562875097e-01,
+     120             :             -4.1475176180187667274168461517547e-01,
+     121             :             -1.3695354902476589153970110146474e-01,
+     122             :             2.1006834227901241551883515512600e-01,
+     123             :             4.3452675461228981723671438430756e-02,
+     124             :             -9.5647264120193975500683336576913e-02,
+     125             :             3.5489281323312395211022618468633e-04,
+     126             :             3.1624165852511730567808712066835e-02,
+     127             :             -6.6796202262771747770742081229400e-03,
+     128             :             -6.0549605750901376935435571624566e-03,
+     129             :             2.6129672804944947123173548675368e-03,
+     130             :             3.2581467135218489857700907563753e-04,
+     131             :             -3.5632975902155574095264700673624e-04,
+     132             :             5.5645514034309739761618301967516e-05
+     133           1 :           };
+     134           1 :       break;
+     135           4 :     case 10:
+     136           8 :       h = { 3.7717157592241430663637657971776e-02,
+     137             :             2.6612218279384214358884719331400e-01,
+     138             :             7.4557507148646740002817523418344e-01,
+     139             :             9.7362811073364052827372461251798e-01,
+     140             :             3.9763774176901656165483700533514e-01,
+     141             :             -3.5333620179411384665257855886011e-01,
+     142             :             -2.7710987872096615181050083265291e-01,
+     143             :             1.8012744853339432427041799655854e-01,
+     144             :             1.3160298710107026787241579768306e-01,
+     145             :             -1.0096657119677993064144061463594e-01,
+     146             :             -4.1659248087601748189445771686223e-02,
+     147             :             4.6969814097397283303436665846675e-02,
+     148             :             5.1004369678145037442229536850391e-03,
+     149             :             -1.5179002335856551370030231851160e-02,
+     150             :             1.9733253649632047886652852497491e-03,
+     151             :             2.8176865901946854600645941957282e-03,
+     152             :             -9.6994783985641268905103506980936e-04,
+     153             :             -1.6470900609077862271692471729523e-04,
+     154             :             1.3235436685110702815550143274237e-04,
+     155             :             -1.8758415627500432871534175038875e-05
+     156           4 :           };
+     157           4 :       break;
+     158           1 :     case 11:
+     159           2 :       h = { 2.6437729433313437304997606247525e-02,
+     160             :             2.0374153520190504962350530604454e-01,
+     161             :             6.3625434846077988382262446975801e-01,
+     162             :             9.6970753662635966740879212011350e-01,
+     163             :             5.8260559778060438951285959774395e-01,
+     164             :             -2.2949185235529601101234220550396e-01,
+     165             :             -3.8782098279100135629349210830696e-01,
+     166             :             9.3399738135533413863065277382702e-02,
+     167             :             2.1186617983636121809176700026001e-01,
+     168             :             -6.5732582904507175225461423906381e-02,
+     169             :             -9.3958631797504951754795854412805e-02,
+     170             :             4.4314509565959142589619546015456e-02,
+     171             :             2.9473489598288812874038455902337e-02,
+     172             :             -2.1729138108983869076551442844902e-02,
+     173             :             -4.7246879281915600545804778676029e-03,
+     174             :             6.9698350902376990032016657039549e-03,
+     175             :             -4.3641620618785245374129933004781e-04,
+     176             :             -1.2629255926067382322097731872645e-03,
+     177             :             3.5235487790788363191354926051702e-04,
+     178             :             7.6988477762888945306503363230632e-05,
+     179             :             -4.8981264369811758688493669167130e-05,
+     180             :             6.3558636358923973935959594872003e-06
+     181           1 :           };
+     182           1 :       break;
+     183           3 :     case 12:
+     184           6 :       h = { 1.8543533036448515277649917720737e-02,
+     185             :             1.5495010900239064577377234854794e-01,
+     186             :             5.3366075005107249662472668205737e-01,
+     187             :             9.2941934664592906756297452375293e-01,
+     188             :             7.2957365443751254208137879686547e-01,
+     189             :             -6.3305694196084630331888831733522e-02,
+     190             :             -4.4714385742734169548739942001703e-01,
+     191             :             -3.3628948114692740201103760000478e-02,
+     192             :             2.5806371934571636916899706193362e-01,
+     193             :             7.5795761219506355491071225571886e-03,
+     194             :             -1.3637561208887127861544286133721e-01,
+     195             :             1.5342987147736677697174023649040e-02,
+     196             :             5.8755309099664532190843146963743e-02,
+     197             :             -1.7279779228315594180598324669518e-02,
+     198             :             -1.8159669147498957303410449526382e-02,
+     199             :             9.4914929220922782115987814677283e-03,
+     200             :             3.1800108566658129814752609121342e-03,
+     201             :             -3.0822835767046288281412191878417e-03,
+     202             :             9.2562090856036967085468392113512e-06,
+     203             :             5.4963843249920504071409643742641e-04,
+     204             :             -1.2516371156799253796382265235820e-04,
+     205             :             -3.4282722782480915088738904206167e-05,
+     206             :             1.8069339114439924513354912560814e-05,
+     207             :             -2.1624340181021667700003892342853e-06
+     208           3 :           };
+     209           3 :       break;
+     210           1 :     case 13:
+     211           2 :       h = { 1.3013782053568881749705532513417e-02,
+     212             :             1.1718349488016345516516736324775e-01,
+     213             :             4.4122943020981653106105113693047e-01,
+     214             :             8.6416347207619259584987503330922e-01,
+     215             :             8.3281561724389663314838117003092e-01,
+     216             :             1.2301639369613130703395853515758e-01,
+     217             :             -4.4543895786553527882389857950329e-01,
+     218             :             -1.7617810218390753118633540452720e-01,
+     219             :             2.5381750565052108026264932050253e-01,
+     220             :             1.0316537133807110460104183857766e-01,
+     221             :             -1.4963456864376814547945571121090e-01,
+     222             :             -3.7460263683081813923525515974688e-02,
+     223             :             7.9393209899753916514164586715196e-02,
+     224             :             3.3657890397617833827537126012430e-03,
+     225             :             -3.3702718379158690120700470060910e-02,
+     226             :             5.5492912148471726374587831287499e-03,
+     227             :             1.0260952934778005268823264373168e-02,
+     228             :             -3.9059323261223279077913872470162e-03,
+     229             :             -1.8606438898585472407204433054062e-03,
+     230             :             1.3185082588273093311126427096269e-03,
+     231             :             6.9652174801158197692090012775878e-05,
+     232             :             -2.3352765515756047508440229609761e-04,
+     233             :             4.3386003918454429126392440929649e-05,
+     234             :             1.4767119831443566670332347146033e-05,
+     235             :             -6.6473927339140924229086634933417e-06,
+     236             :             7.3822444322983881586676402353220e-07
+     237           1 :           };
+     238           1 :       break;
+     239           1 :     case 14:
+     240           2 :       h = { 9.1374508518302227644269919437647e-03,
+     241             :             8.8197087778947372282978278690280e-02,
+     242             :             3.6041270508674011496808020638127e-01,
+     243             :             7.8390652259161064385750705696410e-01,
+     244             :             8.9263441660919018438846705976175e-01,
+     245             :             3.0924705232209759309114360803505e-01,
+     246             :             -3.8422563537411602574422886391403e-01,
+     247             :             -3.0834597516857004118051577279402e-01,
+     248             :             1.9572038841513531015614546504366e-01,
+     249             :             1.9797436583701560897097238012066e-01,
+     250             :             -1.2268078015402955616153235496313e-01,
+     251             :             -1.0118550324745094470824113841445e-01,
+     252             :             7.8117093102298987283838016537629e-02,
+     253             :             3.8157473560976581938852802977635e-02,
+     254             :             -4.2688533533420329468821563523306e-02,
+     255             :             -7.9408791992275871984841018047518e-03,
+     256             :             1.8087074833128147927086004642661e-02,
+     257             :             -1.0553130151236629532401911646389e-03,
+     258             :             -5.4442114973955908763247890647108e-03,
+     259             :             1.5014579323156973956338022802015e-03,
+     260             :             1.0012931187669377956078742286650e-03,
+     261             :             -5.4706298624917549557056251074982e-04,
+     262             :             -5.9081947567055248949751539155884e-05,
+     263             :             9.7234313623187232453887185457120e-05,
+     264             :             -1.4619021425907697688093174470669e-05,
+     265             :             -6.2079802069149134127572231545145e-06,
+     266             :             2.4395108649265364349071390920320e-06,
+     267             :             -2.5273975810449469030721054638167e-07
+     268           1 :           };
+     269           1 :       break;
+     270           1 :     case 15:
+     271           2 :       h = { 6.4184610900818745565787892815024e-03,
+     272             :             6.6105143008711259033916007865628e-02,
+     273             :             2.9136174262291886227771442463563e-01,
+     274             :             6.9668653280553660689378148163087e-01,
+     275             :             9.1331770185222738156483046623180e-01,
+     276             :             4.7942198331894603224867523749708e-01,
+     277             :             -2.7323191454187872873049514055310e-01,
+     278             :             -4.0854168599855755772409793280531e-01,
+     279             :             9.2324037310499082464865239217033e-02,
+     280             :             2.6890806178955328764601517832489e-01,
+     281             :             -5.6096444852683710613483469842322e-02,
+     282             :             -1.5714873480744581679680038632796e-01,
+     283             :             4.7909516391089444764528337827869e-02,
+     284             :             7.7471397590875790140074741429999e-02,
+     285             :             -3.6440051225646634402988155443381e-02,
+     286             :             -2.9429855183644534899478628631186e-02,
+     287             :             2.1331881448689315322608806013704e-02,
+     288             :             7.2139038913583038159504923214627e-03,
+     289             :             -9.1750422042750877371641848867512e-03,
+     290             :             -3.4189530802674857664497087839095e-04,
+     291             :             2.7482751291413886653158815676079e-03,
+     292             :             -5.2818381052845782188537304691067e-04,
+     293             :             -5.0850204513539821755269132452781e-04,
+     294             :             2.2047093037207382386355458692151e-04,
+     295             :             3.6476384955660787364189329151642e-05,
+     296             :             -3.9786489133705268018015993591874e-05,
+     297             :             4.7559820825002058672348846657396e-06,
+     298             :             2.5615231760346128998698331941108e-06,
+     299             :             -8.9334206571767810297517772161191e-07,
+     300             :             8.6738807723125058175416435962690e-08
+     301           1 :           };
+     302           1 :       break;
+     303           1 :     case 16:
+     304           2 :       h = { 4.5102394860307721408121395256785e-03,
+     305             :             4.9366963027983538914167382927189e-02,
+     306             :             2.3343614837332890554755238099460e-01,
+     307             :             6.0855408871050020724879914268968e-01,
+     308             :             9.0135796889724240088526130421087e-01,
+     309             :             6.2266445266940384506426653388189e-01,
+     310             :             -1.2692720787074832089480480590282e-01,
+     311             :             -4.6253736950318169451890071286471e-01,
+     312             :             -3.9482308578843897106658289430925e-02,
+     313             :             2.9866874362698586642395071066858e-01,
+     314             :             3.8664971797927487340285068739831e-02,
+     315             :             -1.8722533722795392518989388008777e-01,
+     316             :             -8.8243005420050348031058007336469e-03,
+     317             :             1.0737308432663163204612288836870e-01,
+     318             :             -1.0732430476938423918875642470994e-02,
+     319             :             -5.2168072309854519874594558359604e-02,
+     320             :             1.4563089924943300318416206096117e-02,
+     321             :             1.9790177710283740619701120522222e-02,
+     322             :             -9.8853733967658469899975060002362e-03,
+     323             :             -5.1537896658028692006836557482075e-03,
+     324             :             4.4236930891221213843489401540410e-03,
+     325             :             5.7685344236866427022891734566201e-04,
+     326             :             -1.3308057204323708866411379858619e-03,
+     327             :             1.6156190702488963770351582116547e-04,
+     328             :             2.4718649272750667844275596074510e-04,
+     329             :             -8.6317891212541529946146445784194e-05,
+     330             :             -1.9722154219490776696404113477179e-05,
+     331             :             1.6032385720093409830870612164944e-05,
+     332             :             -1.4758327456010213390660444285341e-06,
+     333             :             -1.0413783294645852350716365430916e-06,
+     334             :             3.2651137682251684123506938785264e-07,
+     335             :             -2.9830567125395646088604952733681e-08
+     336           1 :           };
+     337           1 :       break;
+     338           1 :     case 17:
+     339           2 :       h = { 3.1703938650899862738974377407430e-03,
+     340             :             3.6748896199244887594836939115339e-02,
+     341             :             1.8556589584340402176998452432599e-01,
+     342             :             5.2375501693137660463861493553850e-01,
+     343             :             8.6407970046528492780169017351000e-01,
+     344             :             7.3300918312113150232534053429845e-01,
+     345             :             3.8629201600176063524649805458466e-02,
+     346             :             -4.6431565514482092682513325598848e-01,
+     347             :             -1.7903908657682734983929151439952e-01,
+     348             :             2.7903931176262103397434088947193e-01,
+     349             :             1.4302718043199780240115615015384e-01,
+     350             :             -1.7934447123456620509784897876671e-01,
+     351             :             -8.0739459938227717272773986678658e-02,
+     352             :             1.1470118631597893410489774623784e-01,
+     353             :             3.1554408431299391102342610793130e-02,
+     354             :             -6.6358348749728263138436545887089e-02,
+     355             :             -4.6258296806782469787200362532076e-03,
+     356             :             3.2150273747621076203540013693782e-02,
+     357             :             -4.3034377017964172210118256600708e-03,
+     358             :             -1.2166368290071909522009896420514e-02,
+     359             :             4.1973811742346631842304205406435e-03,
+     360             :             3.2543956632576265426692874171977e-03,
+     361             :             -2.0320061170844903701560024700257e-03,
+     362             :             -4.6404945920505854227433584213713e-04,
+     363             :             6.2149796814451457871442130453943e-04,
+     364             :             -3.6218164282872656299389763079333e-05,
+     365             :             -1.1603343965511909259211154044067e-04,
+     366             :             3.2791106542406162017901788408025e-05,
+     367             :             9.8862027222343679003311450737002e-06,
+     368             :             -6.3723649625617885940229850882943e-06,
+     369             :             4.2660453700255329024138440524583e-07,
+     370             :             4.1828207733402810550264326779069e-07,
+     371             :             -1.1913262141068780269119692198643e-07,
+     372             :             1.0277787120590941886621601220574e-08
+     373           1 :           };
+     374           1 :       break;
+     375           1 :     case 18:
+     376           2 :       h = { 2.2292392894261341476647153569957e-03,
+     377             :             2.7278103162550408622433195660051e-02,
+     378             :             1.4649621327148704130749479190854e-01,
+     379             :             4.4502322663201776542507559497608e-01,
+     380             :             8.0868522687201060961115217651241e-01,
+     381             :             8.0864965533087529436784279823769e-01,
+     382             :             2.0820492164265561041425200983213e-01,
+     383             :             -4.1528952705523225485961802405654e-01,
+     384             :             -3.0615027286519064242398258102185e-01,
+     385             :             2.1147297628013594916751571872737e-01,
+     386             :             2.3628865852884980980341822487389e-01,
+     387             :             -1.3057700280563036554504208197613e-01,
+     388             :             -1.5097047504012414687046828021266e-01,
+     389             :             9.1764381191532157222567889220954e-02,
+     390             :             8.0682648302152173980239524553326e-02,
+     391             :             -6.2969473759350580444049683137564e-02,
+     392             :             -3.3563828020481217828674402881006e-02,
+     393             :             3.7718074039279007869662763141605e-02,
+     394             :             8.8560428508370828137863384199591e-03,
+     395             :             -1.8457581363752618985873965584688e-02,
+     396             :             1.6776820278716257444327764059011e-04,
+     397             :             6.9909435703212766469172301242452e-03,
+     398             :             -1.5821269103307486047355068237152e-03,
+     399             :             -1.8958894667740898605512445129762e-03,
+     400             :             8.8878469233540330178555688434017e-04,
+     401             :             3.0204994152642787499235543791087e-04,
+     402             :             -2.8093147682505936052477224507129e-04,
+     403             :             -2.1721148267625707617217104689056e-07,
+     404             :             5.2909093510065790795602463925107e-05,
+     405             :             -1.2049951668048177800575404550187e-05,
+     406             :             -4.7130568784725091659583255665478e-06,
+     407             :             2.5013378893915945502541674921870e-06,
+     408             :             -1.0877611266828616855187312041989e-07,
+     409             :             -1.6632548270216130592390321382701e-07,
+     410             :             4.3399892982154842698451632180406e-08,
+     411             :             -3.5467549197311356709477164192218e-09
+     412           1 :           };
+     413           1 :       break;
+     414           1 :     case 19:
+     415           2 :       h = { 1.5678958152846272748603961844083e-03,
+     416             :             2.0196523114657562170126681166948e-02,
+     417             :             1.1494461010411641255224424185144e-01,
+     418             :             3.7390170590255294991166579166020e-01,
+     419             :             7.4166503761237689840157827347866e-01,
+     420             :             8.5093873391779384363076133013237e-01,
+     421             :             3.6896118039375752628572513458494e-01,
+     422             :             -3.2256994316024734104075832874514e-01,
+     423             :             -4.0423686967938060599081495638529e-01,
+     424             :             1.0557425228315596432704381868461e-01,
+     425             :             3.0030788695033916457788336629164e-01,
+     426             :             -4.7402376549099775604467765788286e-02,
+     427             :             -2.0192946643669554274147515116056e-01,
+     428             :             3.9010162763916250705520383235125e-02,
+     429             :             1.2290471236884119299315187845423e-01,
+     430             :             -3.7478407724544741952410475960278e-02,
+     431             :             -6.4593110252131366588734806555294e-02,
+     432             :             3.0580625140236610687294316335283e-02,
+     433             :             2.7401165431703535663165993696566e-02,
+     434             :             -1.9782568984933180528118512597757e-02,
+     435             :             -8.2970810591973861297665493452769e-03,
+     436             :             9.9571204158029405495433650230552e-03,
+     437             :             1.0874656837087327745233755749155e-03,
+     438             :             -3.8007722061321243950393622412776e-03,
+     439             :             4.8339043345746983285429743126826e-04,
+     440             :             1.0405819037270433446984441161476e-03,
+     441             :             -3.6865172646368375578354581456608e-04,
+     442             :             -1.7621212955287076360778864003720e-04,
+     443             :             1.2319596840241719124843522426005e-04,
+     444             :             7.2209044276267830383855654552416e-06,
+     445             :             -2.3532762999714585322235879671915e-05,
+     446             :             4.2581465719275421569255460352288e-06,
+     447             :             2.1664782709628571646042708570556e-06,
+     448             :             -9.7054021264692123684527432642133e-07,
+     449             :             2.0464918981107693371393718402909e-08,
+     450             :             6.5576202903915930451975407466242e-08,
+     451             :             -1.5788309442633350191744509658648e-08,
+     452             :             1.2256775171147230574615288761797e-09
+     453           1 :           };
+     454           1 :       break;
+     455           1 :     case 20:
+     456           2 :       h = { 1.1030209784697370036660180048216e-03,
+     457             :             1.4919096953433321622872753664524e-02,
+     458             :             8.9694770502224324681961320493429e-02,
+     459             :             3.1104511992145722487634884600993e-01,
+     460             :             6.6849335614886884471275152463932e-01,
+     461             :             8.6336781824427866194326952609117e-01,
+     462             :             5.1124145370634632712381062447093e-01,
+     463             :             -1.9687562291233057232275882597605e-01,
+     464             :             -4.6214632517885934070989151223330e-01,
+     465             :             -2.3655675146157809085600831622287e-02,
+     466             :             3.2285230023796102072353164658125e-01,
+     467             :             5.6356759004892016673426979878059e-02,
+     468             :             -2.1985187363946029348582555940084e-01,
+     469             :             -3.4954872441050534315198916601730e-02,
+     470             :             1.4466233657484778296620220316981e-01,
+     471             :             7.9651998921310210310942068190343e-03,
+     472             :             -8.7289361758279004899208075585193e-02,
+     473             :             8.3080546928725445415819805816682e-03,
+     474             :             4.5671036383773788713824615115300e-02,
+     475             :             -1.2429982511459568284006849125944e-02,
+     476             :             -1.9531033366661638278616308639357e-02,
+     477             :             9.5058164920688980464857920082977e-03,
+     478             :             6.2515909968039852853682880606812e-03,
+     479             :             -5.0649977555009108656780547619292e-03,
+     480             :             -1.1760065027624948871126653315855e-03,
+     481             :             1.9693767000596028478309751363895e-03,
+     482             :             -7.5657029268068814531825183600233e-05,
+     483             :             -5.4462035854466845589266776883619e-04,
+     484             :             1.4358918969252962532894002389838e-04,
+     485             :             9.5802798228155261386213004115575e-05,
+     486             :             -5.2475613049099814925394641429435e-05,
+     487             :             -6.1888020007977826320456210540399e-06,
+     488             :             1.0240671536937550416246876794357e-05,
+     489             :             -1.4311756540085687366042942539335e-06,
+     490             :             -9.6832328287254565765814970368375e-07,
+     491             :             3.7249313630534454078768497216345e-07,
+     492             :             2.8486815247482631938422053924332e-10,
+     493             :             -2.5665759353263497063665855347538e-08,
+     494             :             5.7362298926689411330572237329717e-09,
+     495             :             -4.2409952349582263523522284550586e-10
+     496           1 :           };
+     497           1 :       break;
+     498           0 :     default:
+     499           0 :       plumed_merror("Specified order currently not implemented");
+     500             :     }
+     501             :   }
+     502             : 
+     503          25 :   else if (type == Type::sym) {
+     504          25 :     switch(order) {
+     505           1 :     case 4:
+     506           2 :       h = { 4.55703458959498611258176481442206e-02,
+     507             :             -1.78247014416803885306084254125381e-02,
+     508             :             -1.40317624178845662408221528494323e-01,
+     509             :             4.21234534203536570284853723933338e-01,
+     510             :             1.13665824340874954678781705297297e+00,
+     511             :             7.03739068655225841197875524812844e-01,
+     512             :             -4.19109651250538992051097864077747e-02,
+     513             :             -1.07148901417882122522051702162571e-01
+     514           1 :           };
+     515           1 :       break;
+     516           1 :     case 5:
+     517           2 :       h = { 2.76321529578600101617613660209827e-02,
+     518             :             -2.98424998687600064040115199759384e-02,
+     519             :             -2.47951362613500064790983401508129e-01,
+     520             :             2.34789231361400077546797149352642e-02,
+     521             :             8.96581648381840179418134084698977e-01,
+     522             :             1.02305296689210023508564972871682e+00,
+     523             :             2.81990696854580058516859253359144e-01,
+     524             :             -5.53441861167200052640247065482981e-02,
+     525             :             4.17468644215800155361506540430128e-02,
+     526             :             3.86547959548800140749946763207845e-02
+     527           1 :           };
+     528           1 :       break;
+     529           2 :     case 6:
+     530           4 :       h = { -1.10318675093800024761270250905909e-02,
+     531             :             2.49992209278000017055876291749428e-03,
+     532             :             6.32505626598800080317985816691362e-02,
+     533             :             -2.97837512984400025473075146464907e-02,
+     534             :             -1.02724969861800033421594946503319e-01,
+     535             :             4.77904371332100064151404694712255e-01,
+     536             :             1.11389278392792001604050255991751e+00,
+     537             :             6.94457972956700086974990426824661e-01,
+     538             :             -6.83231215864800039971882483769150e-02,
+     539             :             -1.66863215411680032573826792940963e-01,
+     540             :             4.93661237184000057515165238442023e-03,
+     541             :             2.17847003265600018540038007586190e-02
+     542           2 :           };
+     543           2 :       break;
+     544           1 :     case 7:
+     545           2 :       h = { 1.45213947620201448696075630095947e-02,
+     546             :             5.67134268576005746986812283694235e-03,
+     547             :             -1.52463871896281522033689270756440e-01,
+     548             :             -1.98056706807362009614692510695022e-01,
+     549             :             4.08183939725744127091644486426958e-01,
+     550             :             1.08578270981199098699221394781489e+00,
+     551             :             7.58162601965387539237894998223055e-01,
+     552             :             2.46656594886402458222107725305250e-02,
+     553             :             -7.00782912221206977232412782541360e-02,
+     554             :             9.60147679356809641282310963106283e-02,
+     555             :             4.31554525820804293911869820021820e-02,
+     556             :             -1.78704316511401790912305642677893e-02,
+     557             :             -1.48122591460001472307705938646905e-03,
+     558             :             3.79265853420003790433256973813059e-03
+     559           1 :           };
+     560           1 :       break;
+     561           2 :     case 8:
+     562           4 :       h = { 2.67279339279997366768393263214421e-03,
+     563             :             -4.28394300239995752879740287255572e-04,
+     564             :             -2.11456865283597902904766385745461e-02,
+     565             :             5.38638875375994745364760518668845e-03,
+     566             :             6.94904659111793138182022744331334e-02,
+     567             :             -3.84935212633396237058569511191308e-02,
+     568             :             -7.34625087607592708316417429159628e-02,
+     569             :             5.15398670373074963002579806925496e-01,
+     570             :             1.09910663053800905508694540912984e+00,
+     571             :             6.80745347188773330948663442541147e-01,
+     572             :             -8.66536154056391505484668869030429e-02,
+     573             :             -2.02648655285637996348313549788145e-01,
+     574             :             1.07586117504798947641653228401992e-02,
+     575             :             4.48236230436195592918835473028594e-02,
+     576             :             -7.66690896219992417716382337999903e-04,
+     577             :             -4.78345851149995348466914535379146e-03
+     578           2 :           };
+     579           2 :       break;
+     580           1 :     case 9:
+     581           2 :       h = { 1.51248730936219739386106031275858e-03,
+     582             :             -6.69141509131216294554989065801465e-04,
+     583             :             -1.45155785529446045012402777274474e-02,
+     584             :             1.25288962418580607921514413760633e-02,
+     585             :             8.77912515542808719049006072054908e-02,
+     586             :             -2.57864459294240427889022271301656e-02,
+     587             :             -2.70893783504461360678305936744437e-01,
+     588             :             4.98828309581242426706815251691296e-02,
+     589             :             8.73048407349484634210057265590876e-01,
+     590             :             1.01525979083351192144846208975650e+00,
+     591             :             3.37658923602252358797670694912085e-01,
+     592             :             -7.71721610974591964993152259921771e-02,
+     593             :             8.25140928710566164128170640879034e-04,
+     594             :             4.27444336024572976717728067796997e-02,
+     595             :             -1.63033512255879239893907595160272e-02,
+     596             :             -1.87693968364245344915275381936226e-02,
+     597             :             8.76502538903070420837904119792938e-04,
+     598             :             1.98119373648757883879523156167579e-03
+     599           1 :           };
+     600           1 :       break;
+     601           5 :     case 10:
+     602          10 :       h = { -6.49589896781769724452837433403829e-04,
+     603             :             8.06612029979205351478896424133325e-05,
+     604             :             6.49572837868184205234456385369413e-03,
+     605             :             -1.13753531067373615109916684673408e-03,
+     606             :             -2.87862319438586915232303198308728e-02,
+     607             :             8.15281678377939578172828305469011e-03,
+     608             :             7.07035675622903064807545092662622e-02,
+     609             :             -4.52407723042161716286990724711359e-02,
+     610             :             -5.02565403406056709911808866309002e-02,
+     611             :             5.42813011102809772623345452302601e-01,
+     612             :             1.08825153073747227239209678373300e+00,
+     613             :             6.67071338429151339255440689157695e-01,
+     614             :             -1.00240215012934938410005258901947e-01,
+     615             :             -2.25558972319967215858227405078651e-01,
+     616             :             1.64188694163413528848138867033413e-02,
+     617             :             6.49509246029642689501670815843681e-02,
+     618             :             -2.07236392054689850042437093691206e-03,
+     619             :             -1.22206426340899319132882183680522e-02,
+     620             :             1.35245019942278199434962382419201e-04,
+     621             :             1.08917044724438603908733824709998e-03
+     622           5 :           };
+     623           5 :       break;
+     624           1 :     case 11:
+     625           2 :       h = { 6.91923233208036969968390828000793e-04,
+     626             :             1.56320234204571122593394050248605e-04,
+     627             :             -9.03626416328936338251409665645042e-03,
+     628             :             -2.83333713296809227427663913090328e-03,
+     629             :             6.08114528464804224294759649183106e-02,
+     630             :             4.98747296770196690829379804199561e-02,
+     631             :             -2.04498595618993084244152669270989e-01,
+     632             :             -2.89425585980639887839771517974441e-01,
+     633             :             3.36144293016675366203571684309281e-01,
+     634             :             1.03286175231250965111939876805991e+00,
+     635             :             8.08962653490911898224169362947578e-01,
+     636             :             1.37459287684679687391309244048898e-01,
+     637             :             -3.22902447410400722516143900975294e-02,
+     638             :             9.89621390609645434910390804361668e-02,
+     639             :             5.23788159925569485331209307332756e-02,
+     640             :             -3.40554527782290436532797173185827e-02,
+     641             :             -1.39412251318646231851294814418907e-02,
+     642             :             9.21005970815790518668730868512284e-03,
+     643             :             8.32056417857734271180392138234083e-04,
+     644             :             -2.45276429733504728117332582826293e-03,
+     645             :             -5.48653425032330071273514726648557e-05,
+     646             :             2.42851511636182730569100129969229e-04
+     647           1 :           };
+     648           1 :       break;
+     649           3 :     case 12:
+     650           6 :       h = { -2.53238395868029360011308703803934e-04,
+     651             :             -2.56794013941539134206898387091655e-05,
+     652             :             3.32382276159138428939243681270455e-03,
+     653             :             4.35079685976638231084678842819358e-04,
+     654             :             -2.06331445793122500442784428287268e-02,
+     655             :             -3.68316511823289565938366330044573e-03,
+     656             :             8.17474545336821928342985188464809e-02,
+     657             :             2.16399291162249034214948295584691e-02,
+     658             :             -2.40940550666163183501922162577102e-01,
+     659             :             -1.10779056856021962396141589124454e-01,
+     660             :             6.54414642216806785590677009167848e-01,
+     661             :             1.07972249467402248157554822682869e+00,
+     662             :             5.64109951994629099658595805522054e-01,
+     663             :             -3.13422339595566742942445159769704e-02,
+     664             :             -5.06979026234183824395351791736175e-02,
+     665             :             6.95500589276436959051963526690088e-02,
+     666             :             1.06826589882294663985673466299886e-02,
+     667             :             -3.42532744974815631100462098856951e-02,
+     668             :             -1.99249856148396879348960730737872e-03,
+     669             :             1.04863447995954799790707667739298e-02,
+     670             :             2.54861210329473779345743622570808e-04,
+     671             :             -1.90884289542041446843811947076119e-03,
+     672             :             -1.60568790225561159679470990546690e-05,
+     673             :             1.58345524644348421491879541633807e-04
+     674           3 :           };
+     675           3 :       break;
+     676           1 :     case 13:
+     677           2 :       h = { 9.96028729759322644298977222909741e-05,
+     678             :             5.21920796195277043654989213017359e-05,
+     679             :             -1.02016329687258286949835817125631e-03,
+     680             :             5.84439592204865189864482211135055e-04,
+     681             :             8.02545515204910846207564389942490e-03,
+     682             :             -2.11063917638504251403364087025238e-03,
+     683             :             -2.93444878165318237539516132983408e-02,
+     684             :             2.49160343945351858696568569939700e-02,
+     685             :             1.31417253195061006776356293812569e-01,
+     686             :             1.24730209143528725235228193923831e-02,
+     687             :             -1.98682995060360217953743244834186e-01,
+     688             :             1.55889076380235497287785051412357e-01,
+     689             :             9.11551693535715079619308198743965e-01,
+     690             :             9.83923742598004968940017533896025e-01,
+     691             :             2.79596836052714847742350912085385e-01,
+     692             :             -1.75875078644905619151828091162315e-01,
+     693             :             -8.45001480790217585070678296688129e-02,
+     694             :             1.96045318821402025921685208231793e-02,
+     695             :             -2.43409385742523465268050131271593e-02,
+     696             :             -2.85908276815921014168964120472083e-02,
+     697             :             7.49018377371175360368571460867315e-03,
+     698             :             1.06436900199696239666113939392744e-02,
+     699             :             -2.41749708924265434154335374650202e-04,
+     700             :             -1.60663632304836349537491280159429e-03,
+     701             :             -5.05420462645238263775342157924086e-05,
+     702             :             9.64539648683696427926281824483112e-05
+     703           1 :           };
+     704           1 :       break;
+     705           1 :     case 14:
+     706           2 :       h = { 6.31007638147709694776549271821864e-05,
+     707             :             2.73353579399835730078405920950857e-05,
+     708             :             -8.56674265589630994088832238730902e-04,
+     709             :             -1.03540533784965597756920485661425e-04,
+     710             :             6.41017395468853039969259199892804e-03,
+     711             :             1.43279913888553589278174182908288e-03,
+     712             :             -2.74913418748536537983273575491694e-02,
+     713             :             -3.34468414059296489937445073792333e-03,
+     714             :             9.87511620870536871441558446349518e-02,
+     715             :             3.66261337327129302132711075046245e-02,
+     716             :             -2.26270508787995705546336466795765e-01,
+     717             :             -8.21825286701456242388630357709189e-02,
+     718             :             6.72226282198253310973257157456828e-01,
+     719             :             1.07476870846271177484254621958826e+00,
+     720             :             5.56070925104528490656718986429041e-01,
+     721             :             -4.99473531504178586137854267690273e-02,
+     722             :             -8.15074892290164332298019189693150e-02,
+     723             :             5.29383812442578288726124924323813e-02,
+     724             :             6.05357014372925363032695855736165e-03,
+     725             :             -4.12896871319010858036868683029752e-02,
+     726             :             -3.89442565747022016384160103541490e-03,
+     727             :             1.41954425904793363893974245115714e-02,
+     728             :             5.18276140762161932271090414303671e-04,
+     729             :             -3.64788147216562339339440690366700e-03,
+     730             :             -8.89051363774028501323759554608728e-05,
+     731             :             5.63473132455830365457327690847933e-04,
+     732             :             1.58545584728775700955431815497576e-05,
+     733             :             -3.65985604352032339978313679740296e-05
+     734           1 :           };
+     735           1 :       break;
+     736           1 :     case 15:
+     737           2 :       h = { 4.05323627037270219162362616671658e-05,
+     738             :             3.07137347973606144061961553681783e-05,
+     739             :             -5.68752200237824536398212327270585e-04,
+     740             :             -1.52953421693918361354627699633113e-04,
+     741             :             4.92291805096766160038113113728286e-03,
+     742             :             2.15828545106170558570690687361093e-03,
+     743             :             -2.42838185667302274006740248069036e-02,
+     744             :             -1.23669990433466353563218831368431e-02,
+     745             :             9.61238540674488606274650237537571e-02,
+     746             :             9.67227466631194188195763672410976e-02,
+     747             :             -1.89584235398369660430262229056098e-01,
+     748             :             -2.78071663287250692153662612327025e-01,
+     749             :             3.45015366735401951547856924662483e-01,
+     750             :             1.02084020241597150935319859854644e+00,
+     751             :             8.18321122934300926310413615283323e-01,
+     752             :             1.57732464332277610985499904927565e-01,
+     753             :             -5.80996643342105573148970165675564e-02,
+     754             :             5.76086678570035190527498514256877e-02,
+     755             :             3.10245118607714344405312800745378e-02,
+     756             :             -5.49799802677569254827361078241665e-02,
+     757             :             -2.74428303436324676212176854050995e-02,
+     758             :             1.42552403061262534383901723344934e-02,
+     759             :             4.84149046146408433555219374966327e-03,
+     760             :             -5.07726066683766071724326351954915e-03,
+     761             :             -3.78042544045809091653870259719383e-04,
+     762             :             1.51401068119577392884211874957145e-03,
+     763             :             7.79550547699306238926333922911738e-05,
+     764             :             -2.27210190383633081493211514079178e-04,
+     765             :             -1.04081406015788967609316320594992e-05,
+     766             :             1.37354357168879101134487813462570e-05
+     767           1 :           };
+     768           1 :       break;
+     769           1 :     case 16:
+     770           2 :       h = { -1.52706527381910275756142503222890e-05,
+     771             :             -7.63177970130589524008421498102450e-06,
+     772             :             2.33991244594547811736645614999475e-04,
+     773             :             5.17120268202257300760825431407142e-05,
+     774             :             -1.89323683821244256181293152963008e-03,
+     775             :             -3.14120133085196543993450335463535e-04,
+     776             :             9.81147588368609310793821975948958e-03,
+     777             :             1.92311087754286520745683475297483e-03,
+     778             :             -3.52885288476778719024551378424803e-02,
+     779             :             -4.96427860935466733899312785638358e-03,
+     780             :             1.10362189954493067345353551900189e-01,
+     781             :             4.34462515148709496615175851275126e-02,
+     782             :             -2.25697442637171785673189106091741e-01,
+     783             :             -7.64249514011508951361051344974840e-02,
+     784             :             6.72236243037978686842848219384905e-01,
+     785             :             1.06988789812795226374930734891677e+00,
+     786             :             5.61616638655705324723044213897083e-01,
+     787             :             -4.88953427358677847336387856103102e-02,
+     788             :             -9.47283364442045167086448032023327e-02,
+     789             :             4.57258966692524679298337275668018e-02,
+     790             :             6.88619390233227712805330611445243e-03,
+     791             :             -4.39130321893507619135377240127127e-02,
+     792             :             -4.42156298801803758491413276487947e-03,
+     793             :             1.79134637043109300191812138791647e-02,
+     794             :             1.01570512112273466515111053354303e-03,
+     795             :             -5.48843874201232484466572714154609e-03,
+     796             :             -1.53365269849333965166901516674614e-04,
+     797             :             1.20541159197261760899211324726821e-03,
+     798             :             3.97091116582507492704760820867449e-05,
+     799             :             -1.54759482169960371376535301912725e-04,
+     800             :             -4.40323369887264181395027801135811e-06,
+     801             :             8.81055997054166680230915392746383e-06
+     802           1 :           };
+     803           1 :       break;
+     804           1 :     case 17:
+     805           2 :       h = { 5.36164168581481346588513137163545e-06,
+     806             :             -3.46866471633543758739618573239127e-06,
+     807             :             -1.07580985050661424558618439739632e-04,
+     808             :             3.56494009271542727150354490373019e-05,
+     809             :             1.01798919677591626770096766563256e-03,
+     810             :             8.25906783075320302753979939680562e-05,
+     811             :             -5.56114774235276932562443974461530e-03,
+     812             :             -2.69465339683962841130226983921148e-03,
+     813             :             1.75319890806961142803999109673896e-02,
+     814             :             1.40756428708096667512528199495137e-02,
+     815             :             -2.55108531297768073575760183757666e-02,
+     816             :             -1.02695023497632355324871156199151e-02,
+     817             :             2.28520064519878510211903233084740e-02,
+     818             :             -1.21722598355376729339916153094237e-01,
+     819             :             -2.19310589964256619222027211435488e-01,
+     820             :             2.55321529059814311679588172410149e-01,
+     821             :             9.63770979824808082803144770878134e-01,
+     822             :             9.20252282282772893218236731627258e-01,
+     823             :             2.01381678415994358477547621077974e-01,
+     824             :             -1.67678964148070125395051377381606e-01,
+     825             :             2.44251344634779481157504932298252e-02,
+     826             :             1.48145397031054587566600844183995e-01,
+     827             :             2.53200120416010171497944725160778e-02,
+     828             :             -4.70811260450583399239654625034746e-02,
+     829             :             -6.81539610621377002497300878758324e-03,
+     830             :             1.48243054824644532319055656444107e-02,
+     831             :             1.21165585310027278283240281808730e-03,
+     832             :             -3.87731534844140950796242961473581e-03,
+     833             :             -1.96069824769335180822404929301683e-04,
+     834             :             6.73160536609661666086756870441832e-04,
+     835             :             -1.91009105827510641166869231888370e-05,
+     836             :             -8.90063957100391663296648503411745e-05,
+     837             :             3.93169287554600132558258254733552e-06,
+     838             :             6.07736121570621208446468658470607e-06
+     839           1 :           };
+     840           1 :       break;
+     841           1 :     case 18:
+     842           2 :       h = { -2.13992159246166473816484938919036e-06,
+     843             :             1.10977553385413026034323619173350e-06,
+     844             :             4.18005291525171048536493878522435e-05,
+     845             :             -1.39424713387653467029560910850350e-05,
+     846             :             -3.75940547191951806357129717284238e-04,
+     847             :             6.70565555942921202913289957514564e-05,
+     848             :             2.01961905200075380467650276727909e-03,
+     849             :             -2.66969918023956154402853702123366e-04,
+     850             :             -7.41018163371885089235613364166966e-03,
+     851             :             1.53836000238939262126092177851433e-03,
+     852             :             2.12306779452164293142679696302366e-02,
+     853             :             -4.61138867117545040580361970228296e-03,
+     854             :             -4.48485088469943032896125600927917e-02,
+     855             :             8.87835433253391509422769445336598e-03,
+     856             :             4.03469430616465660199843057398539e-02,
+     857             :             -1.04367839842760060098392216332286e-01,
+     858             :             -4.59344672605674214649340569849301e-02,
+     859             :             5.67783920692876864499964995047776e-01,
+     860             :             1.06579255093152891475938304211013e+00,
+     861             :             6.70293472647235155648104409920052e-01,
+     862             :             -7.35803422739719908962641170546704e-02,
+     863             :             -2.26186698989002510362666953369626e-01,
+     864             :             4.80771334803232336385647727183823e-02,
+     865             :             1.19104967186232965636882852322742e-01,
+     866             :             -7.18008269166581052089792791548462e-03,
+     867             :             -4.28861550987859954653380611944158e-02,
+     868             :             2.32353364582536326202188980971641e-03,
+     869             :             1.34380897535976585183137288481703e-02,
+     870             :             -5.81978733884339397529339432679762e-04,
+     871             :             -3.27230890166736818752690751921364e-03,
+     872             :             9.92958015089934567000418130788830e-05,
+     873             :             5.60266733289934543670030020479089e-04,
+     874             :             -1.98286778613536816145718894022210e-05,
+     875             :             -6.39885786401657284281838111716922e-05,
+     876             :             1.91614024625604985099780984414419e-06,
+     877             :             3.69479211060541101930730298330552e-06
+     878           1 :           };
+     879           1 :       break;
+     880           1 :     case 19:
+     881           2 :       h = { 2.47619856876035267576182871684942e-06,
+     882             :             2.91655676074685013668191455038503e-06,
+     883             :             -3.98117220914099361156295031616281e-05,
+     884             :             -2.37890336748671808665862859033524e-05,
+     885             :             3.90632340413758891075474144471968e-04,
+     886             :             1.82868669835172258141334222791841e-04,
+     887             :             -2.41117792464671338789616861220111e-03,
+     888             :             -8.73874136465524497564827388629283e-04,
+     889             :             1.16845675580482498412404623877592e-02,
+     890             :             6.10848600213812192166740189236407e-03,
+     891             :             -3.91877120522209840269844960403134e-02,
+     892             :             -2.39118550567039567233962316095131e-02,
+     893             :             1.18896719019111141157907240994973e-01,
+     894             :             1.32414008615193368179063782008598e-01,
+     895             :             -1.64390631231593420391590143481153e-01,
+     896             :             -2.49745683326209749752777611320198e-01,
+     897             :             3.65243519237511582442579083362943e-01,
+     898             :             1.01760518334862726241851760278223e+00,
+     899             :             8.17620422715306993666217749705538e-01,
+     900             :             1.54185800478859824647059895141865e-01,
+     901             :             -9.54948528806143087654945134090667e-02,
+     902             :             1.26637042824246960626144442585428e-02,
+     903             :             9.92151969664582453201084888405603e-03,
+     904             :             -6.59532404097190189107280389180232e-02,
+     905             :             -3.20347562503009650192176138716604e-02,
+     906             :             2.23409529027087383479255322527024e-02,
+     907             :             1.12690735439448276589136099801181e-02,
+     908             :             -7.24389178390821321384951403388186e-03,
+     909             :             -1.64148228823170379275797614582189e-03,
+     910             :             3.00014804641317691172308634861565e-03,
+     911             :             2.25083469591080945247998923441912e-04,
+     912             :             -8.99106799594682343235163557437772e-04,
+     913             :             -6.52240895281959979666239202167333e-05,
+     914             :             1.63397150769660883320999467116508e-04,
+     915             :             1.25487584192582468661661745934488e-05,
+     916             :             -1.68015900652064169079266675588258e-05,
+     917             :             -9.14098333564239404867173867386132e-07,
+     918             :             7.76082610749008778884821136562211e-07
+     919           1 :           };
+     920           1 :       break;
+     921           1 :     case 20:
+     922           0 :       h = { -8.95074013313225034112988621332052e-07,
+     923             :             -4.60567304495735576428397861289965e-07,
+     924             :             1.73767995228992186179835244264069e-05,
+     925             :             6.39991346364665771576834066292072e-06,
+     926             :             -1.66016418292479542555967197969835e-04,
+     927             :             -3.76400722545106348484143798938106e-05,
+     928             :             1.05728141728119568419630436295620e-03,
+     929             :             1.77400246424138069000625561599804e-04,
+     930             :             -4.90965140656484527736935774555604e-03,
+     931             :             -8.64263223121293565169576122997341e-04,
+     932             :             1.71926521880978698531006187977255e-02,
+     933             :             2.74159026446779826788335832077337e-03,
+     934             :             -5.00254525875804267887048126794980e-02,
+     935             :             -9.67845613584030449449979727205573e-03,
+     936             :             1.25751400487193104593686143743980e-01,
+     937             :             5.12665874779235433700286250768841e-02,
+     938             :             -2.27092007441644233578514899818401e-01,
+     939             :             -7.22498274381410260369662523771694e-02,
+     940             :             6.67496745413005965197328350768657e-01,
+     941             :             1.06230451808460291118763052509166e+00,
+     942             :             5.73932332635040842738760602514958e-01,
+     943             :             -4.21709558919741780980139367329684e-02,
+     944             :             -1.11714873948519005653068347783119e-01,
+     945             :             3.61746629928947835419528189504490e-02,
+     946             :             1.14879797113225934346303347410867e-02,
+     947             :             -4.47307789806269048837883417490957e-02,
+     948             :             -4.68650205569037543035237902699919e-03,
+     949             :             2.40473567441355992602147750858421e-02,
+     950             :             2.01254944419308181777217292562909e-03,
+     951             :             -9.34312323805295934231462950947389e-03,
+     952             :             -4.31706836813935599089092631786002e-04,
+     953             :             2.95428464804820467212720380700830e-03,
+     954             :             1.02049526041390444994726161009879e-04,
+     955             :             -6.99655419422072467026951780866284e-04,
+     956             :             -2.72718682941954995583092036248729e-05,
+     957             :             1.13037635169613691495625606986408e-04,
+     958             :             4.27893798113462174641198274005482e-06,
+     959             :             -1.11996683141520158823655969881905e-05,
+     960             :             -2.68922267421127013513505862526975e-07,
+     961             :             5.22627921716999034327578478598131e-07
+     962           1 :           };
+     963           1 :       break;
+     964           0 :     default:
+     965           0 :       plumed_merror("Wavelets: Specified order currently not implemented");
+     966             :     }
+     967             :   }
+     968             : 
+     969             :   // to get highpass: reverse order and inverse sign of every second
+     970          49 :   if (!lowpass) {
+     971           2 :     std::reverse(h.begin(), h.end());
+     972          22 :     for (unsigned i=1; i < h.size(); i += 2) {
+     973          20 :       h[i] = -h[i];
+     974             :     }
+     975             :   }
+     976             : 
+     977          49 :   return h;
+     978             : }
+     979             : 
+     980             : 
+     981             : }
+     982             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/WaveletGrid.cpp.func-sort-c.html b/coverage/ves/WaveletGrid.cpp.func-sort-c.html new file mode 100644 index 000000000000..29e0d84b701b --- /dev/null +++ b/coverage/ves/WaveletGrid.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - ves/WaveletGrid.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - WaveletGrid.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10410599.0 %
Date:2024-04-19 12:12:35Functions:88100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves11WaveletGrid12stringToTypeERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE47
_ZN4PLMD3ves11WaveletGrid12typeToStringB5cxx11ENS1_4TypeEb47
_ZN4PLMD3ves11WaveletGrid16fillGridFromMapsERSt10unique_ptrINS_4GridESt14default_deleteIS3_EERKSt13unordered_mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESt6vectorIdSaIdEESt4hashISE_ESt8equal_toISE_ESaISt4pairIKSE_SH_EEESS_47
_ZN4PLMD3ves11WaveletGrid9setupGridEjjbNS1_4TypeE47
_ZN4PLMD3ves11WaveletGrid13setupMatricesERKSt6vectorIdSaIdEE49
_ZN4PLMD3ves11WaveletGrid14getEigenvectorERKNS_6MatrixIdEEd94
_ZN4PLMD3ves11WaveletGrid17calcIntegerValuesERKNS_6MatrixIdEEi94
_ZN4PLMD3ves11WaveletGrid7cascadeB5cxx11ERSt6vectorINS_6MatrixIdEESaIS4_EES7_RKS2_IdSaIdEEjjjb94
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/WaveletGrid.cpp.func.html b/coverage/ves/WaveletGrid.cpp.func.html new file mode 100644 index 000000000000..b5018a7c59ed --- /dev/null +++ b/coverage/ves/WaveletGrid.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - ves/WaveletGrid.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - WaveletGrid.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10410599.0 %
Date:2024-04-19 12:12:35Functions:88100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves11WaveletGrid12stringToTypeERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE47
_ZN4PLMD3ves11WaveletGrid12typeToStringB5cxx11ENS1_4TypeEb47
_ZN4PLMD3ves11WaveletGrid13setupMatricesERKSt6vectorIdSaIdEE49
_ZN4PLMD3ves11WaveletGrid14getEigenvectorERKNS_6MatrixIdEEd94
_ZN4PLMD3ves11WaveletGrid16fillGridFromMapsERSt10unique_ptrINS_4GridESt14default_deleteIS3_EERKSt13unordered_mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESt6vectorIdSaIdEESt4hashISE_ESt8equal_toISE_ESaISt4pairIKSE_SH_EEESS_47
_ZN4PLMD3ves11WaveletGrid17calcIntegerValuesERKNS_6MatrixIdEEi94
_ZN4PLMD3ves11WaveletGrid7cascadeB5cxx11ERSt6vectorINS_6MatrixIdEESaIS4_EES7_RKS2_IdSaIdEEjjjb94
_ZN4PLMD3ves11WaveletGrid9setupGridEjjbNS1_4TypeE47
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/WaveletGrid.cpp.gcov.html b/coverage/ves/WaveletGrid.cpp.gcov.html new file mode 100644 index 000000000000..912be82e2f28 --- /dev/null +++ b/coverage/ves/WaveletGrid.cpp.gcov.html @@ -0,0 +1,331 @@ + + + + + + + + LCOV - plumed test coverage - ves/WaveletGrid.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - WaveletGrid.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10410599.0 %
Date:2024-04-19 12:12:35Functions:88100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "WaveletGrid.h"
+      24             : #include "tools/Exception.h"
+      25             : #include "tools/Grid.h"
+      26             : #include "tools/Matrix.h"
+      27             : 
+      28             : #include <memory>
+      29             : #include <unordered_map>
+      30             : #include <vector>
+      31             : 
+      32             : namespace PLMD {
+      33             : namespace ves {
+      34             : 
+      35             : 
+      36             : // construction of Wavelet grid according to the Daubechies-Lagarias method
+      37             : // see Strang, Nguyen "Wavelets and Filter Banks" chapter 6.3
+      38          47 : std::unique_ptr<Grid> WaveletGrid::setupGrid(const unsigned order, unsigned gridsize, const bool use_mother_wavelet, const Type type) {
+      39          47 :   plumed_assert(order>=1) << "Wavelet order has to be a positive integer";
+      40             :   // calculate the grid properties of the scaling grid
+      41             :   // the range of the grid is from 0 to maxsupport
+      42          47 :   unsigned maxsupport = order*2 -1;
+      43             :   // determine needed recursion depth for specified size
+      44             :   unsigned recursion_number = 0;
+      45         173 :   while (maxsupport*(1U<<recursion_number) < gridsize) { recursion_number++; }
+      46             :   // set "true" gridsize
+      47          47 :   unsigned bins_per_int = 1U<<recursion_number;
+      48             :   gridsize = maxsupport*bins_per_int;
+      49             : 
+      50             :   // Filter coefficients
+      51          47 :   std::vector<double> h_coeffs = getFilterCoefficients(order, true, type);
+      52             :   // Vector with the Matrices M0 and M1 for the cascade
+      53          47 :   std::vector<Matrix<double>> h_Matvec = setupMatrices(h_coeffs);
+      54             :   std::vector<Matrix<double>> g_Matvec; // only filled if needed for wavelet
+      55             : 
+      56             :   // get the values at integers
+      57          47 :   std::vector<double> values_at_integers = calcIntegerValues(h_Matvec[0], 0);
+      58          47 :   std::vector<double> derivs_at_integers = calcIntegerValues(h_Matvec[0], 1);
+      59             : 
+      60             :   std::string gridvarname; // stores the name of the grid variable
+      61          47 :   if (use_mother_wavelet) { // get the highpass filter coefficients as well
+      62           2 :     std::vector<double> g_coeffs = getFilterCoefficients(order, false, type);
+      63           4 :     g_Matvec = setupMatrices(g_coeffs);
+      64           4 :     gridvarname = typeToString(type,true)+std::to_string(order)+"_psi";
+      65             :   }
+      66             :   else {
+      67          90 :     gridvarname = typeToString(type,true)+std::to_string(order)+"_phi";
+      68             :   }
+      69             : 
+      70             :   // Set up the grid with correct properties
+      71             :   auto grid = std::unique_ptr<Grid>(new Grid(gridvarname, {"position"}, {"0"},
+      72         517 :   {std::to_string(maxsupport)}, {gridsize}, false, true, {false}, {"0."}, {"0."}));
+      73             : 
+      74          47 :   BinaryMap values = cascade(h_Matvec, g_Matvec, values_at_integers, recursion_number, bins_per_int, 0, use_mother_wavelet);
+      75          47 :   BinaryMap derivs = cascade(h_Matvec, g_Matvec, derivs_at_integers, recursion_number, bins_per_int, 1, use_mother_wavelet);
+      76             : 
+      77          47 :   fillGridFromMaps(grid, values, derivs);
+      78             : 
+      79          47 :   return grid;
+      80          47 : }
+      81             : 
+      82             : 
+      83             : 
+      84          49 : std::vector<Matrix<double>> WaveletGrid::setupMatrices(const std::vector<double>& coeffs) {
+      85             :   Matrix<double> M0, M1;
+      86          49 :   const int N = coeffs.size() -1;
+      87             :   M0.resize(N,N); M1.resize(N,N);
+      88        1108 :   for (int i = 0; i < N; ++i) {
+      89       27644 :     for (int j = 0; j < N; ++j) {
+      90       26585 :       int shift = 2*i -j;
+      91       26585 :       if (0 <= shift && shift <= N) {
+      92       13822 :         M0[i][j] = coeffs[2*i -j]; // normalization is already included in coeffs
+      93             :       }
+      94       26585 :       if (-1 <= shift && shift <= N -1) {
+      95       13822 :         M1[i][j] = coeffs[2*i -j + 1];
+      96             :       }
+      97             :     }
+      98             :   }
+      99         196 :   return std::vector<Matrix<double>> {M0, M1};
+     100             : }
+     101             : 
+     102             : 
+     103          94 : std::vector<double> WaveletGrid::calcIntegerValues(const Matrix<double> &M, const int deriv) {
+     104             :   // corresponding eigenvalue of the matrix
+     105             :   double eigenvalue = std::pow(0.5, deriv);
+     106          94 :   std::vector<double> values = getEigenvector(M, eigenvalue);
+     107             : 
+     108             :   // normalization of the eigenvector
+     109             :   double normfactor = 0.;
+     110             :   // i=0 is always 0; for derivs > 1 an additional factorial would have to be added
+     111        2042 :   for (unsigned i=1; i<values.size(); ++i) {
+     112        1948 :     normfactor += values[i] * std::pow(-i, deriv);
+     113             :   }
+     114          94 :   normfactor = 1/normfactor;
+     115        2136 :   for (auto& value : values) {
+     116        2042 :     value *= normfactor;
+     117             :   }
+     118             : 
+     119          94 :   return values;
+     120             : }
+     121             : 
+     122             : 
+     123             : // maybe move this to the tools/matrix.h file?
+     124             : // this works reliably only for singular eigenvalues
+     125             : //
+     126          94 : std::vector<double> WaveletGrid::getEigenvector(const Matrix<double> &A, const double eigenvalue) {
+     127             :   // mostly copied from tools/matrix.h
+     128          94 :   int info, N = A.ncols(); // ncols == nrows
+     129          94 :   std::vector<double> da(N*N);
+     130          94 :   std::vector<double> S(N);
+     131          94 :   std::vector<double> U(N*N);
+     132          94 :   std::vector<double> VT(N*N);
+     133          94 :   std::vector<int> iwork(8*N);
+     134             : 
+     135             :   // Transfer the matrix to the local array and substract eigenvalue
+     136       53862 :   for (int i=0; i<N; ++i) for (int j=0; j<N; ++j) {
+     137       51726 :       da[i*N+j]=static_cast<double>( A(j,i) );
+     138       51726 :       if (i==j) da[i*N+j] -= eigenvalue;
+     139             :     }
+     140             : 
+     141             :   // This optimizes the size of the work array used in lapack singular value decomposition
+     142          94 :   int lwork=-1;
+     143          94 :   std::vector<double> work(1);
+     144          94 :   plumed_lapack_dgesdd( "A", &N, &N, da.data(), &N, S.data(), U.data(), &N, VT.data(), &N, work.data(), &lwork, iwork.data(), &info );
+     145             : 
+     146             :   // Retrieve correct sizes for work and reallocate
+     147          94 :   lwork=static_cast<int>(work[0]); work.resize(lwork);
+     148             : 
+     149             :   // This does the singular value decomposition
+     150          94 :   plumed_lapack_dgesdd( "A", &N, &N, da.data(), &N, S.data(), U.data(), &N, VT.data(), &N, work.data(), &lwork, iwork.data(), &info );
+     151             : 
+     152             :   // fill eigenvector with last column of VT
+     153          94 :   std::vector<double> eigenvector(N);
+     154        2136 :   for (int i=0; i<N; ++i) eigenvector[i] = VT[N-1 + i*N];
+     155             : 
+     156          94 :   return eigenvector;
+     157             : }
+     158             : 
+     159             : 
+     160          94 : WaveletGrid::BinaryMap WaveletGrid::cascade(std::vector<Matrix<double>>& h_Matvec, std::vector<Matrix<double>>& g_Matvec, const std::vector<double>& values_at_integers, const unsigned recursion_number, const unsigned bins_per_int, const unsigned derivnum, const bool use_mother_wavelet) {
+     161             :   BinaryMap scaling_map, wavelet_map;
+     162          94 :   scaling_map.reserve(bins_per_int);
+     163             :   // vector to store the binary representation of all the decimal parts
+     164             :   std::vector<std::string> binary_vec;
+     165             :   // vector used as result of the matrix multiplications
+     166             :   std::vector<double> temp_values;
+     167             : 
+     168             :   // multiply matrices by 2 if derivatives are calculated (assumes ascending order)
+     169         188 :   if (derivnum != 0) for (auto& M : h_Matvec) M *= 2;
+     170             : 
+     171          94 :   if (use_mother_wavelet) {
+     172             :     wavelet_map.reserve(bins_per_int);
+     173           8 :     if (derivnum != 0) for (auto& M : g_Matvec) M *= 2;
+     174             :   }
+     175             : 
+     176             :   // fill the first two datasets by hand
+     177         282 :   scaling_map["0"] = values_at_integers;
+     178          94 :   mult(h_Matvec[1], values_at_integers, temp_values);
+     179         188 :   scaling_map["1"] = temp_values;
+     180             : 
+     181          94 :   if (use_mother_wavelet) {
+     182           4 :     mult(g_Matvec[0], values_at_integers, temp_values);
+     183          12 :     wavelet_map["0"] = temp_values;
+     184           4 :     mult(g_Matvec[1], values_at_integers, temp_values);
+     185          12 :     wavelet_map["1"] = temp_values;
+     186             :   }
+     187             : 
+     188             :   // now do the cascade
+     189          94 :   binary_vec.emplace_back("1");
+     190         252 :   for (unsigned i=1; i<recursion_number; ++i) {
+     191             :     std::vector<std::string> new_binary_vec;
+     192        1144 :     for (const auto& binary : binary_vec) {
+     193        2958 :       for (unsigned k=0; k<2; ++k) {
+     194             :         // prepend the new bit
+     195        3944 :         std::string new_binary = std::to_string(k) + binary;
+     196        1972 :         mult(h_Matvec[k], scaling_map[binary], temp_values);
+     197        1972 :         scaling_map.insert(std::pair<std::string, std::vector<double>>(new_binary, temp_values));
+     198        1972 :         if (use_mother_wavelet) {
+     199           8 :           mult(g_Matvec[k], scaling_map[binary], temp_values);
+     200          16 :           wavelet_map.insert(std::pair<std::string, std::vector<double>>(new_binary, temp_values));
+     201             :         }
+     202        1972 :         new_binary_vec.push_back(new_binary);
+     203             :       }
+     204             :     }
+     205         158 :     binary_vec = new_binary_vec;
+     206         158 :   }
+     207             : 
+     208         188 :   return use_mother_wavelet ? wavelet_map : scaling_map;
+     209          94 : }
+     210             : 
+     211             : 
+     212             : // Fill the Grid with the values of the unordered maps
+     213          47 : void WaveletGrid::fillGridFromMaps(std::unique_ptr<Grid>& grid, const BinaryMap& values_map, const BinaryMap& derivs_map) {
+     214          47 :   unsigned bins_per_int = values_map.size();
+     215             :   // this is somewhat complicated… not sure if the unordered_map way is the best way for c++
+     216        1127 :   for (const auto& value_iter : values_map) {
+     217             :     // get decimal of binary key
+     218        1080 :     unsigned decimal = std::stoi(value_iter.first, nullptr, 2);
+     219             :     // corresponding iterator of deriv
+     220        1080 :     auto deriv_iter = derivs_map.find(value_iter.first);
+     221             :     // calculate first grid element
+     222        1080 :     unsigned first_grid_element = decimal * (bins_per_int >> value_iter.first.length());
+     223       19480 :     for (unsigned i=0; i<value_iter.second.size(); ++i) {
+     224             :       // derivative has to be passed as vector
+     225       18400 :       std::vector<double> deriv {deriv_iter->second[i]};
+     226       18400 :       grid->setValueAndDerivatives(first_grid_element + bins_per_int*i, value_iter.second[i], deriv);
+     227             :     }
+     228             :   }
+     229          47 : }
+     230             : 
+     231             : 
+     232          47 : WaveletGrid::Type WaveletGrid::stringToType(std::string& type_str) {
+     233         188 :   std::unordered_map<std::string, Type> typemap = { {"DAUBECHIES", Type::db}, {"SYMLETS", Type::sym} };
+     234          47 :   try { return typemap.at(type_str); }
+     235           0 :   catch(const std::out_of_range& e) {plumed_merror("The specified wavelet type "+type_str+" is not implemented."); }
+     236             : }
+     237             : 
+     238             : 
+     239          47 : std::string WaveletGrid::typeToString(Type type, bool abbrev) {
+     240             :   std::string type_str;
+     241          47 :   switch(type) {
+     242          23 :   case Type::db:
+     243          23 :     type_str = abbrev ? "Db" : "DAUBECHIES";
+     244             :     break;
+     245          24 :   case Type::sym:
+     246          24 :     type_str = abbrev ? "Sym" : "SYMLETS";
+     247             :     break;
+     248             :   }
+     249          47 :   return type_str;
+     250             : }
+     251             : 
+     252             : 
+     253             : }
+     254             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/index-sort-f.html b/coverage/ves/index-sort-f.html new file mode 100644 index 000000000000..2f6aa02ae14f --- /dev/null +++ b/coverage/ves/index-sort-f.html @@ -0,0 +1,724 @@ + + + + + + + + LCOV - plumed test coverage - ves + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesHitTotalCoverage
Test:plumed test coverageLines:5891718082.0 %
Date:2024-04-19 12:12:35Functions:44467765.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
GridLinearInterpolation.h +
22.2%22.2%
+
22.2 %2 / 90.0 %0 / 1
CoeffsMatrix.cpp +
29.5%29.5%
+
29.5 %105 / 35625.3 %20 / 79
VesBias.h +
74.2%74.2%
+
74.2 %66 / 8936.0 %9 / 25
OutputFesBias.cpp +
88.2%88.2%
+
88.2 %60 / 6840.0 %2 / 5
TD_ProductDistribution.cpp +
63.2%63.2%
+
63.2 %48 / 7640.0 %4 / 10
FermiSwitchingFunction.cpp +
49.3%49.3%
+
49.3 %33 / 6744.4 %4 / 9
CoeffsVector.cpp +
50.7%50.7%
+
50.7 %232 / 45845.5 %45 / 99
CoeffsBase.cpp +
42.2%42.2%
+
42.2 %127 / 30146.9 %15 / 32
OutputBasisFunctions.cpp +
98.2%98.2%
+
98.2 %108 / 11050.0 %2 / 4
OutputTargetDistribution.cpp +
93.3%93.3%
+
93.3 %83 / 8950.0 %2 / 4
TargetDistribution.h +
81.8%81.8%
+
81.8 %18 / 2250.0 %3 / 6
GridLinearInterpolation.cpp +
55.0%55.0%
+
55.0 %66 / 12055.6 %5 / 9
TD_ProductCombination.cpp +
73.3%73.3%
+
73.3 %55 / 7560.0 %6 / 10
TD_LinearCombination.cpp +
75.3%75.3%
+
75.3 %58 / 7760.0 %6 / 10
VesBias.cpp +
76.2%76.2%
+
76.2 %324 / 42560.0 %27 / 45
TD_WellTempered.cpp +
90.3%90.3%
+
90.3 %28 / 3166.7 %4 / 6
Opt_Adam.cpp +
93.1%93.1%
+
93.1 %67 / 7275.0 %3 / 4
Opt_Dummy.cpp +
95.2%95.2%
+
95.2 %20 / 2175.0 %3 / 4
Opt_RobbinsMonroSGD.cpp +
95.8%95.8%
+
95.8 %23 / 2475.0 %3 / 4
Opt_BachAveragedSGD.cpp +
95.2%95.2%
+
95.2 %59 / 6275.0 %3 / 4
BasisFunctions.h +
96.7%96.7%
+
96.7 %59 / 6175.0 %6 / 8
BasisFunctions.cpp +
87.7%87.7%
+
87.7 %222 / 25381.0 %17 / 21
TD_MultithermalMultibaric.cpp +
97.4%97.4%
+
97.4 %147 / 15183.3 %5 / 6
TD_Multicanonical.cpp +
96.6%96.6%
+
96.6 %197 / 20483.3 %5 / 6
LinearBasisSetExpansion.cpp +
88.7%88.7%
+
88.7 %313 / 35383.3 %30 / 36
Optimizer.cpp +
89.5%89.5%
+
89.5 %682 / 76284.4 %27 / 32
TargetDistribution.cpp +
87.1%87.1%
+
87.1 %189 / 21784.6 %22 / 26
TD_Custom.cpp +
86.5%86.5%
+
86.5 %77 / 8985.7 %6 / 7
VesLinearExpansion.cpp +
96.5%96.5%
+
96.5 %139 / 14485.7 %18 / 21
VesDeltaF.cpp +
97.7%97.7%
+
97.7 %343 / 35187.5 %7 / 8
Optimizer.h +
94.6%94.6%
+
94.6 %53 / 5690.0 %9 / 10
CoeffsVector.h +
50.0%50.0%
+
50.0 %2 / 4-0 / 0
CoeffsMatrix.h +
0.0%
+
0.0 %0 / 1-0 / 0
WaveletCoeffs.cpp +
96.7%96.7%
+
96.7 %145 / 150100.0 %1 / 1
TargetDistModifer.h +
100.0%
+
100.0 %3 / 3100.0 %1 / 1
CoeffsBase.h +
100.0%
+
100.0 %33 / 33100.0 %2 / 2
VesTools.cpp +
92.1%92.1%
+
92.1 %35 / 38100.0 %2 / 2
TD_Exponential.cpp +
100.0%
+
100.0 %26 / 26100.0 %3 / 3
TD_Grid.cpp +
94.8%94.8%
+
94.8 %55 / 58100.0 %3 / 3
TD_Chi.cpp +
100.0%
+
100.0 %40 / 40100.0 %3 / 3
LinearBasisSetExpansion.h +
95.5%95.5%
+
95.5 %21 / 22100.0 %3 / 3
GridIntegrationWeights.cpp +
75.6%75.6%
+
75.6 %34 / 45100.0 %3 / 3
TD_ChiSquared.cpp +
100.0%
+
100.0 %40 / 40100.0 %3 / 3
TD_Uniform.cpp +
98.2%98.2%
+
98.2 %54 / 55100.0 %4 / 4
TD_GeneralizedNormal.cpp +
91.3%91.3%
+
91.3 %63 / 69100.0 %4 / 4
TD_ExponentiallyModifiedGaussian.cpp +
90.5%90.5%
+
90.5 %57 / 63100.0 %4 / 4
BF_CubicBsplines.cpp +
100.0%
+
100.0 %58 / 58100.0 %4 / 4
BF_Chebyshev.cpp +
100.0%
+
100.0 %35 / 35100.0 %4 / 4
BF_Powers.cpp +
100.0%
+
100.0 %35 / 35100.0 %4 / 4
GridProjWeights.h +
100.0%
+
100.0 %6 / 6100.0 %4 / 4
BF_Gaussians.cpp +
100.0%
+
100.0 %52 / 52100.0 %4 / 4
TD_GeneralizedExtremeValue.cpp +
100.0%
+
100.0 %38 / 38100.0 %4 / 4
BF_Legendre.cpp +
100.0%
+
100.0 %42 / 42100.0 %4 / 4
BF_Wavelets.cpp +
100.0%
+
100.0 %118 / 118100.0 %5 / 5
BF_Cosine.cpp +
100.0%
+
100.0 %35 / 35100.0 %5 / 5
VesTools.h +
65.6%65.6%
+
65.6 %21 / 32100.0 %5 / 5
TD_VonMises.cpp +
98.7%98.7%
+
98.7 %74 / 75100.0 %5 / 5
BF_Sine.cpp +
100.0%
+
100.0 %35 / 35100.0 %5 / 5
TD_Gaussian.cpp +
90.5%90.5%
+
90.5 %76 / 84100.0 %5 / 5
BF_Combined.cpp +
96.9%96.9%
+
96.9 %63 / 65100.0 %5 / 5
BF_Fourier.cpp +
100.0%
+
100.0 %38 / 38100.0 %5 / 5
BF_Custom.cpp +
82.2%82.2%
+
82.2 %125 / 152100.0 %5 / 5
WaveletGrid.cpp +
99.0%99.0%
+
99.0 %104 / 105100.0 %8 / 8
MD_LinearExpansionPES.cpp +
97.0%97.0%
+
97.0 %325 / 335100.0 %9 / 9
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/index-sort-l.html b/coverage/ves/index-sort-l.html new file mode 100644 index 000000000000..bb36753fd8f3 --- /dev/null +++ b/coverage/ves/index-sort-l.html @@ -0,0 +1,724 @@ + + + + + + + + LCOV - plumed test coverage - ves + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesHitTotalCoverage
Test:plumed test coverageLines:5891718082.0 %
Date:2024-04-19 12:12:35Functions:44467765.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
CoeffsMatrix.h +
0.0%
+
0.0 %0 / 1-0 / 0
GridLinearInterpolation.h +
22.2%22.2%
+
22.2 %2 / 90.0 %0 / 1
CoeffsMatrix.cpp +
29.5%29.5%
+
29.5 %105 / 35625.3 %20 / 79
CoeffsBase.cpp +
42.2%42.2%
+
42.2 %127 / 30146.9 %15 / 32
FermiSwitchingFunction.cpp +
49.3%49.3%
+
49.3 %33 / 6744.4 %4 / 9
CoeffsVector.h +
50.0%50.0%
+
50.0 %2 / 4-0 / 0
CoeffsVector.cpp +
50.7%50.7%
+
50.7 %232 / 45845.5 %45 / 99
GridLinearInterpolation.cpp +
55.0%55.0%
+
55.0 %66 / 12055.6 %5 / 9
TD_ProductDistribution.cpp +
63.2%63.2%
+
63.2 %48 / 7640.0 %4 / 10
VesTools.h +
65.6%65.6%
+
65.6 %21 / 32100.0 %5 / 5
TD_ProductCombination.cpp +
73.3%73.3%
+
73.3 %55 / 7560.0 %6 / 10
VesBias.h +
74.2%74.2%
+
74.2 %66 / 8936.0 %9 / 25
TD_LinearCombination.cpp +
75.3%75.3%
+
75.3 %58 / 7760.0 %6 / 10
GridIntegrationWeights.cpp +
75.6%75.6%
+
75.6 %34 / 45100.0 %3 / 3
VesBias.cpp +
76.2%76.2%
+
76.2 %324 / 42560.0 %27 / 45
TargetDistribution.h +
81.8%81.8%
+
81.8 %18 / 2250.0 %3 / 6
BF_Custom.cpp +
82.2%82.2%
+
82.2 %125 / 152100.0 %5 / 5
TD_Custom.cpp +
86.5%86.5%
+
86.5 %77 / 8985.7 %6 / 7
TargetDistribution.cpp +
87.1%87.1%
+
87.1 %189 / 21784.6 %22 / 26
BasisFunctions.cpp +
87.7%87.7%
+
87.7 %222 / 25381.0 %17 / 21
OutputFesBias.cpp +
88.2%88.2%
+
88.2 %60 / 6840.0 %2 / 5
LinearBasisSetExpansion.cpp +
88.7%88.7%
+
88.7 %313 / 35383.3 %30 / 36
Optimizer.cpp +
89.5%89.5%
+
89.5 %682 / 76284.4 %27 / 32
TD_WellTempered.cpp +
90.3%90.3%
+
90.3 %28 / 3166.7 %4 / 6
TD_ExponentiallyModifiedGaussian.cpp +
90.5%90.5%
+
90.5 %57 / 63100.0 %4 / 4
TD_Gaussian.cpp +
90.5%90.5%
+
90.5 %76 / 84100.0 %5 / 5
TD_GeneralizedNormal.cpp +
91.3%91.3%
+
91.3 %63 / 69100.0 %4 / 4
VesTools.cpp +
92.1%92.1%
+
92.1 %35 / 38100.0 %2 / 2
Opt_Adam.cpp +
93.1%93.1%
+
93.1 %67 / 7275.0 %3 / 4
OutputTargetDistribution.cpp +
93.3%93.3%
+
93.3 %83 / 8950.0 %2 / 4
Optimizer.h +
94.6%94.6%
+
94.6 %53 / 5690.0 %9 / 10
TD_Grid.cpp +
94.8%94.8%
+
94.8 %55 / 58100.0 %3 / 3
Opt_BachAveragedSGD.cpp +
95.2%95.2%
+
95.2 %59 / 6275.0 %3 / 4
Opt_Dummy.cpp +
95.2%95.2%
+
95.2 %20 / 2175.0 %3 / 4
LinearBasisSetExpansion.h +
95.5%95.5%
+
95.5 %21 / 22100.0 %3 / 3
Opt_RobbinsMonroSGD.cpp +
95.8%95.8%
+
95.8 %23 / 2475.0 %3 / 4
VesLinearExpansion.cpp +
96.5%96.5%
+
96.5 %139 / 14485.7 %18 / 21
TD_Multicanonical.cpp +
96.6%96.6%
+
96.6 %197 / 20483.3 %5 / 6
WaveletCoeffs.cpp +
96.7%96.7%
+
96.7 %145 / 150100.0 %1 / 1
BasisFunctions.h +
96.7%96.7%
+
96.7 %59 / 6175.0 %6 / 8
BF_Combined.cpp +
96.9%96.9%
+
96.9 %63 / 65100.0 %5 / 5
MD_LinearExpansionPES.cpp +
97.0%97.0%
+
97.0 %325 / 335100.0 %9 / 9
TD_MultithermalMultibaric.cpp +
97.4%97.4%
+
97.4 %147 / 15183.3 %5 / 6
VesDeltaF.cpp +
97.7%97.7%
+
97.7 %343 / 35187.5 %7 / 8
TD_Uniform.cpp +
98.2%98.2%
+
98.2 %54 / 55100.0 %4 / 4
OutputBasisFunctions.cpp +
98.2%98.2%
+
98.2 %108 / 11050.0 %2 / 4
TD_VonMises.cpp +
98.7%98.7%
+
98.7 %74 / 75100.0 %5 / 5
WaveletGrid.cpp +
99.0%99.0%
+
99.0 %104 / 105100.0 %8 / 8
TargetDistModifer.h +
100.0%
+
100.0 %3 / 3100.0 %1 / 1
GridProjWeights.h +
100.0%
+
100.0 %6 / 6100.0 %4 / 4
TD_Exponential.cpp +
100.0%
+
100.0 %26 / 26100.0 %3 / 3
CoeffsBase.h +
100.0%
+
100.0 %33 / 33100.0 %2 / 2
BF_Cosine.cpp +
100.0%
+
100.0 %35 / 35100.0 %5 / 5
BF_Chebyshev.cpp +
100.0%
+
100.0 %35 / 35100.0 %4 / 4
BF_Sine.cpp +
100.0%
+
100.0 %35 / 35100.0 %5 / 5
BF_Powers.cpp +
100.0%
+
100.0 %35 / 35100.0 %4 / 4
BF_Fourier.cpp +
100.0%
+
100.0 %38 / 38100.0 %5 / 5
TD_GeneralizedExtremeValue.cpp +
100.0%
+
100.0 %38 / 38100.0 %4 / 4
TD_Chi.cpp +
100.0%
+
100.0 %40 / 40100.0 %3 / 3
TD_ChiSquared.cpp +
100.0%
+
100.0 %40 / 40100.0 %3 / 3
BF_Legendre.cpp +
100.0%
+
100.0 %42 / 42100.0 %4 / 4
BF_Gaussians.cpp +
100.0%
+
100.0 %52 / 52100.0 %4 / 4
BF_CubicBsplines.cpp +
100.0%
+
100.0 %58 / 58100.0 %4 / 4
BF_Wavelets.cpp +
100.0%
+
100.0 %118 / 118100.0 %5 / 5
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/index.html b/coverage/ves/index.html new file mode 100644 index 000000000000..3a7e55771d81 --- /dev/null +++ b/coverage/ves/index.html @@ -0,0 +1,724 @@ + + + + + + + + LCOV - plumed test coverage - ves + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesHitTotalCoverage
Test:plumed test coverageLines:5891718082.0 %
Date:2024-04-19 12:12:35Functions:44467765.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
BF_Chebyshev.cpp +
100.0%
+
100.0 %35 / 35100.0 %4 / 4
BF_Combined.cpp +
96.9%96.9%
+
96.9 %63 / 65100.0 %5 / 5
BF_Cosine.cpp +
100.0%
+
100.0 %35 / 35100.0 %5 / 5
BF_CubicBsplines.cpp +
100.0%
+
100.0 %58 / 58100.0 %4 / 4
BF_Custom.cpp +
82.2%82.2%
+
82.2 %125 / 152100.0 %5 / 5
BF_Fourier.cpp +
100.0%
+
100.0 %38 / 38100.0 %5 / 5
BF_Gaussians.cpp +
100.0%
+
100.0 %52 / 52100.0 %4 / 4
BF_Legendre.cpp +
100.0%
+
100.0 %42 / 42100.0 %4 / 4
BF_Powers.cpp +
100.0%
+
100.0 %35 / 35100.0 %4 / 4
BF_Sine.cpp +
100.0%
+
100.0 %35 / 35100.0 %5 / 5
BF_Wavelets.cpp +
100.0%
+
100.0 %118 / 118100.0 %5 / 5
BasisFunctions.cpp +
87.7%87.7%
+
87.7 %222 / 25381.0 %17 / 21
BasisFunctions.h +
96.7%96.7%
+
96.7 %59 / 6175.0 %6 / 8
CoeffsBase.cpp +
42.2%42.2%
+
42.2 %127 / 30146.9 %15 / 32
CoeffsBase.h +
100.0%
+
100.0 %33 / 33100.0 %2 / 2
CoeffsMatrix.cpp +
29.5%29.5%
+
29.5 %105 / 35625.3 %20 / 79
CoeffsMatrix.h +
0.0%
+
0.0 %0 / 1-0 / 0
CoeffsVector.cpp +
50.7%50.7%
+
50.7 %232 / 45845.5 %45 / 99
CoeffsVector.h +
50.0%50.0%
+
50.0 %2 / 4-0 / 0
FermiSwitchingFunction.cpp +
49.3%49.3%
+
49.3 %33 / 6744.4 %4 / 9
GridIntegrationWeights.cpp +
75.6%75.6%
+
75.6 %34 / 45100.0 %3 / 3
GridLinearInterpolation.cpp +
55.0%55.0%
+
55.0 %66 / 12055.6 %5 / 9
GridLinearInterpolation.h +
22.2%22.2%
+
22.2 %2 / 90.0 %0 / 1
GridProjWeights.h +
100.0%
+
100.0 %6 / 6100.0 %4 / 4
LinearBasisSetExpansion.cpp +
88.7%88.7%
+
88.7 %313 / 35383.3 %30 / 36
LinearBasisSetExpansion.h +
95.5%95.5%
+
95.5 %21 / 22100.0 %3 / 3
MD_LinearExpansionPES.cpp +
97.0%97.0%
+
97.0 %325 / 335100.0 %9 / 9
Opt_Adam.cpp +
93.1%93.1%
+
93.1 %67 / 7275.0 %3 / 4
Opt_BachAveragedSGD.cpp +
95.2%95.2%
+
95.2 %59 / 6275.0 %3 / 4
Opt_Dummy.cpp +
95.2%95.2%
+
95.2 %20 / 2175.0 %3 / 4
Opt_RobbinsMonroSGD.cpp +
95.8%95.8%
+
95.8 %23 / 2475.0 %3 / 4
Optimizer.cpp +
89.5%89.5%
+
89.5 %682 / 76284.4 %27 / 32
Optimizer.h +
94.6%94.6%
+
94.6 %53 / 5690.0 %9 / 10
OutputBasisFunctions.cpp +
98.2%98.2%
+
98.2 %108 / 11050.0 %2 / 4
OutputFesBias.cpp +
88.2%88.2%
+
88.2 %60 / 6840.0 %2 / 5
OutputTargetDistribution.cpp +
93.3%93.3%
+
93.3 %83 / 8950.0 %2 / 4
TD_Chi.cpp +
100.0%
+
100.0 %40 / 40100.0 %3 / 3
TD_ChiSquared.cpp +
100.0%
+
100.0 %40 / 40100.0 %3 / 3
TD_Custom.cpp +
86.5%86.5%
+
86.5 %77 / 8985.7 %6 / 7
TD_Exponential.cpp +
100.0%
+
100.0 %26 / 26100.0 %3 / 3
TD_ExponentiallyModifiedGaussian.cpp +
90.5%90.5%
+
90.5 %57 / 63100.0 %4 / 4
TD_Gaussian.cpp +
90.5%90.5%
+
90.5 %76 / 84100.0 %5 / 5
TD_GeneralizedExtremeValue.cpp +
100.0%
+
100.0 %38 / 38100.0 %4 / 4
TD_GeneralizedNormal.cpp +
91.3%91.3%
+
91.3 %63 / 69100.0 %4 / 4
TD_Grid.cpp +
94.8%94.8%
+
94.8 %55 / 58100.0 %3 / 3
TD_LinearCombination.cpp +
75.3%75.3%
+
75.3 %58 / 7760.0 %6 / 10
TD_Multicanonical.cpp +
96.6%96.6%
+
96.6 %197 / 20483.3 %5 / 6
TD_MultithermalMultibaric.cpp +
97.4%97.4%
+
97.4 %147 / 15183.3 %5 / 6
TD_ProductCombination.cpp +
73.3%73.3%
+
73.3 %55 / 7560.0 %6 / 10
TD_ProductDistribution.cpp +
63.2%63.2%
+
63.2 %48 / 7640.0 %4 / 10
TD_Uniform.cpp +
98.2%98.2%
+
98.2 %54 / 55100.0 %4 / 4
TD_VonMises.cpp +
98.7%98.7%
+
98.7 %74 / 75100.0 %5 / 5
TD_WellTempered.cpp +
90.3%90.3%
+
90.3 %28 / 3166.7 %4 / 6
TargetDistModifer.h +
100.0%
+
100.0 %3 / 3100.0 %1 / 1
TargetDistribution.cpp +
87.1%87.1%
+
87.1 %189 / 21784.6 %22 / 26
TargetDistribution.h +
81.8%81.8%
+
81.8 %18 / 2250.0 %3 / 6
VesBias.cpp +
76.2%76.2%
+
76.2 %324 / 42560.0 %27 / 45
VesBias.h +
74.2%74.2%
+
74.2 %66 / 8936.0 %9 / 25
VesDeltaF.cpp +
97.7%97.7%
+
97.7 %343 / 35187.5 %7 / 8
VesLinearExpansion.cpp +
96.5%96.5%
+
96.5 %139 / 14485.7 %18 / 21
VesTools.cpp +
92.1%92.1%
+
92.1 %35 / 38100.0 %2 / 2
VesTools.h +
65.6%65.6%
+
65.6 %21 / 32100.0 %5 / 5
WaveletCoeffs.cpp +
96.7%96.7%
+
96.7 %145 / 150100.0 %1 / 1
WaveletGrid.cpp +
99.0%99.0%
+
99.0 %104 / 105100.0 %8 / 8
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/volumes/ActionVolume.cpp.func-sort-c.html b/coverage/volumes/ActionVolume.cpp.func-sort-c.html new file mode 100644 index 000000000000..2f0d77b9d191 --- /dev/null +++ b/coverage/volumes/ActionVolume.cpp.func-sort-c.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - volumes/ActionVolume.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - volumes - ActionVolume.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:727497.3 %
Date:2024-04-19 12:12:35Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7volumes12ActionVolumeC1ERKNS_13ActionOptionsE0
_ZN4PLMD7volumes12ActionVolume12requestAtomsERKSt6vectorINS_10AtomNumberESaIS3_EE59
_ZN4PLMD7volumes12ActionVolumeC2ERKNS_13ActionOptionsE59
_ZN4PLMD7volumes12ActionVolume12isInSubChainERj104
_ZN4PLMD7volumes12ActionVolume16registerKeywordsERNS_8KeywordsE158
_ZN4PLMD7volumes12ActionVolume16getNumberOfTasksERj533
_ZN4PLMD7volumes12ActionVolume19areAllTasksRequiredERSt6vectorIPNS_16ActionWithVectorESaIS4_EE863
_ZN4PLMD7volumes12ActionVolume9calculateEv2081
_ZNK4PLMD7volumes12ActionVolume11performTaskERKjRNS_10MultiValueE62937
_ZNK4PLMD7volumes12ActionVolume15checkTaskStatusERKjRi464761
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/volumes/ActionVolume.cpp.func.html b/coverage/volumes/ActionVolume.cpp.func.html new file mode 100644 index 000000000000..7fad4ae26b68 --- /dev/null +++ b/coverage/volumes/ActionVolume.cpp.func.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - volumes/ActionVolume.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - volumes - ActionVolume.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:727497.3 %
Date:2024-04-19 12:12:35Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7volumes12ActionVolume12isInSubChainERj104
_ZN4PLMD7volumes12ActionVolume12requestAtomsERKSt6vectorINS_10AtomNumberESaIS3_EE59
_ZN4PLMD7volumes12ActionVolume16getNumberOfTasksERj533
_ZN4PLMD7volumes12ActionVolume16registerKeywordsERNS_8KeywordsE158
_ZN4PLMD7volumes12ActionVolume19areAllTasksRequiredERSt6vectorIPNS_16ActionWithVectorESaIS4_EE863
_ZN4PLMD7volumes12ActionVolume9calculateEv2081
_ZN4PLMD7volumes12ActionVolumeC1ERKNS_13ActionOptionsE0
_ZN4PLMD7volumes12ActionVolumeC2ERKNS_13ActionOptionsE59
_ZNK4PLMD7volumes12ActionVolume11performTaskERKjRNS_10MultiValueE62937
_ZNK4PLMD7volumes12ActionVolume15checkTaskStatusERKjRi464761
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/volumes/ActionVolume.cpp.gcov.html b/coverage/volumes/ActionVolume.cpp.gcov.html new file mode 100644 index 000000000000..c45614eb2a39 --- /dev/null +++ b/coverage/volumes/ActionVolume.cpp.gcov.html @@ -0,0 +1,214 @@ + + + + + + + + LCOV - plumed test coverage - volumes/ActionVolume.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - volumes - ActionVolume.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:727497.3 %
Date:2024-04-19 12:12:35Functions:91090.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2017 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received 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             : #include "core/ActionToPutData.h"
+      24             : #include "core/PlumedMain.h"
+      25             : 
+      26             : namespace PLMD {
+      27             : namespace volumes {
+      28             : 
+      29         158 : void ActionVolume::registerKeywords( Keywords& keys ) {
+      30         158 :   ActionWithVector::registerKeywords( keys );
+      31         316 :   keys.add("atoms","ATOMS","the group of atoms that you would like to investigate");
+      32         316 :   keys.add("compulsory","SIGMA","the width of the function to be used for kernel density estimation");
+      33         316 :   keys.add("compulsory","KERNEL","gaussian","the type of kernel function to be used");
+      34         316 :   keys.addFlag("OUTSIDE",false,"calculate quantities for colvars that are on atoms outside the region of interest");
+      35         158 : }
+      36             : 
+      37          59 : ActionVolume::ActionVolume(const ActionOptions&ao):
+      38             :   Action(ao),
+      39          59 :   ActionWithVector(ao)
+      40             : {
+      41         118 :   std::vector<AtomNumber> atoms; parseAtomList("ATOMS",atoms);
+      42          59 :   if( atoms.size()==0 ) error("no atoms were specified");
+      43          59 :   log.printf("  examining positions of atoms ");
+      44       33354 :   for(unsigned i=0; i<atoms.size(); ++i) log.printf(" %d", atoms[i].serial() );
+      45          59 :   log.printf("\n"); ActionAtomistic::requestAtoms( atoms );
+      46             : 
+      47          59 :   parseFlag("OUTSIDE",not_in); sigma=0.0;
+      48         166 :   if( keywords.exists("SIGMA") ) parse("SIGMA",sigma);
+      49         177 :   if( keywords.exists("KERNEL") ) parse("KERNEL",kerneltype);
+      50             : 
+      51          60 :   if( atoms.size()==1 ) ActionWithValue::addValueWithDerivatives();
+      52          58 :   else { std::vector<unsigned> shape(1); shape[0]=atoms.size(); ActionWithValue::addValue( shape ); }
+      53          59 :   setNotPeriodic(); getPntrToComponent(0)->setDerivativeIsZeroWhenValueIsZero();
+      54          59 : }
+      55             : 
+      56         104 : bool ActionVolume::isInSubChain( unsigned& nder ) {
+      57         104 :   nder = 0; getFirstActionInChain()->getNumberOfStreamedDerivatives( nder, getPntrToComponent(0) );
+      58         104 :   nder = nder - getNumberOfDerivatives();
+      59         104 :   return true;
+      60             : }
+      61             : 
+      62          59 : void ActionVolume::requestAtoms( const std::vector<AtomNumber> & a ) {
+      63          59 :   std::vector<AtomNumber> all_atoms( getAbsoluteIndexes() );
+      64         128 :   for(unsigned i=0; i<a.size(); ++i) all_atoms.push_back( a[i] );
+      65          59 :   ActionAtomistic::requestAtoms( all_atoms );
+      66          59 :   if( getPntrToComponent(0)->getRank()==0 ) getPntrToComponent(0)->resizeDerivatives( 3*getNumberOfAtoms()+9 );
+      67          59 : }
+      68             : 
+      69         863 : void ActionVolume::areAllTasksRequired( std::vector<ActionWithVector*>& task_reducing_actions ) {
+      70         863 :   task_reducing_actions.push_back(this);
+      71         863 : }
+      72             : 
+      73         533 : void ActionVolume::getNumberOfTasks( unsigned& ntasks ) {
+      74         533 :   setupRegions(); ActionWithVector::getNumberOfTasks( ntasks );
+      75         533 : }
+      76             : 
+      77      464761 : int ActionVolume::checkTaskStatus( const unsigned& taskno, int& flag ) const {
+      78      464761 :   unsigned nref=getNumberOfAtoms()-getConstPntrToComponent(0)->getShape()[0];
+      79      464761 :   Vector wdf; Tensor vir; std::vector<Vector> refders( nref );
+      80      464761 :   double weight=calculateNumberInside( ActionAtomistic::getPosition(taskno), wdf, vir, refders );
+      81      464761 :   if( not_in ) weight = 1.0 - weight;
+      82      464761 :   if( weight>epsilon ) return 1;
+      83             :   return 0;
+      84             : }
+      85             : 
+      86        2081 : void ActionVolume::calculate() {
+      87        2081 :   if( actionInChain() ) return;
+      88        1750 :   if( getPntrToComponent(0)->getRank()==0 ) {
+      89        1560 :     setupRegions(); unsigned nref = getNumberOfAtoms() - 1;
+      90        1560 :     Vector wdf; Tensor vir; std::vector<Vector> refders( nref );
+      91        1560 :     double weight=calculateNumberInside( ActionAtomistic::getPosition(0), wdf, vir, refders );
+      92        1560 :     if( not_in ) {
+      93           0 :       weight = 1.0 - weight; wdf *= -1.; vir *=-1;
+      94           0 :       for(unsigned i=0; i<refders.size(); ++i) refders[i]*=-1;
+      95             :     }
+      96             :     // Atom position
+      97        1560 :     Value* v = getPntrToComponent(0); v->set( weight );
+      98        6240 :     for(unsigned i=0; i<3; ++i ) v->addDerivative( i, wdf[i] );
+      99             :     // Add derivatives with respect to reference positions
+     100        7800 :     for(unsigned i=0; i<refders.size(); ++i) {
+     101       24960 :       for(unsigned j=0; j<3; ++j ) v->addDerivative( 3 + 3*i + j, refders[i][j] );
+     102             :     }
+     103             :     // Add virial
+     104             :     unsigned vbase = 3*getNumberOfAtoms();
+     105       20280 :     for(unsigned i=0; i<3; ++i) for(unsigned j=0; j<3; ++j) v->addDerivative( vbase + 3*i + j, vir(i,j) );
+     106         190 :   } else runAllTasks();
+     107             : }
+     108             : 
+     109       62937 : void ActionVolume::performTask( const unsigned& curr, MultiValue& outvals ) const {
+     110       62937 :   unsigned nref=getNumberOfAtoms()-getConstPntrToComponent(0)->getShape()[0];
+     111       62937 :   Vector wdf; Tensor vir; std::vector<Vector> refders( nref );
+     112       62937 :   double weight=calculateNumberInside( ActionAtomistic::getPosition(curr), wdf, vir, refders );
+     113             : 
+     114       62937 :   if( not_in ) {
+     115        4000 :     weight = 1.0 - weight; wdf *= -1.; vir *=-1;
+     116        8000 :     for(unsigned i=0; i<refders.size(); ++i) refders[i]*=-1;
+     117             :   }
+     118       62937 :   unsigned ostrn = getConstPntrToComponent(0)->getPositionInStream();
+     119       62937 :   outvals.setValue( ostrn, weight );
+     120             : 
+     121       62937 :   if( doNotCalculateDerivatives() ) return;
+     122             : 
+     123             :   // Atom position
+     124      146144 :   for(unsigned i=0; i<3; ++i ) { outvals.addDerivative( ostrn, 3*curr+i, wdf[i] ); outvals.updateIndex( ostrn, 3*curr+i ); }
+     125             :   // Add derivatives with respect to reference positions
+     126       36536 :   unsigned vbase = 3*(getNumberOfAtoms()-nref);
+     127       76572 :   for(unsigned i=0; i<refders.size(); ++i) {
+     128      160144 :     for(unsigned j=0; j<3; ++j ) { outvals.addDerivative( ostrn, vbase, refders[i][j] ); outvals.updateIndex( ostrn, vbase ); vbase++; }
+     129             :   }
+     130             :   // Add virial
+     131      146144 :   for(unsigned i=0; i<3; ++i) {
+     132      438432 :     for(unsigned j=0; j<3; ++j) { outvals.addDerivative( ostrn, vbase, vir(i,j) ); outvals.updateIndex( ostrn, vbase ); vbase++; }
+     133             :   }
+     134             : }
+     135             : 
+     136             : }
+     137             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/volumes/ActionVolume.h.func-sort-c.html b/coverage/volumes/ActionVolume.h.func-sort-c.html new file mode 100644 index 000000000000..52257b1ef2e9 --- /dev/null +++ b/coverage/volumes/ActionVolume.h.func-sort-c.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - volumes/ActionVolume.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - volumes - ActionVolume.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:77100.0 %
Date:2024-04-19 12:12:35Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7volumes12ActionVolume22getNumberOfDerivativesEv1765
_ZNK4PLMD7volumes12ActionVolume11getPositionERKj547218
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/volumes/ActionVolume.h.func.html b/coverage/volumes/ActionVolume.h.func.html new file mode 100644 index 000000000000..41e9f149137b --- /dev/null +++ b/coverage/volumes/ActionVolume.h.func.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - volumes/ActionVolume.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - volumes - ActionVolume.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:77100.0 %
Date:2024-04-19 12:12:35Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7volumes12ActionVolume22getNumberOfDerivativesEv1765
_ZNK4PLMD7volumes12ActionVolume11getPositionERKj547218
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/volumes/ActionVolume.h.gcov.html b/coverage/volumes/ActionVolume.h.gcov.html new file mode 100644 index 000000000000..f53d15388099 --- /dev/null +++ b/coverage/volumes/ActionVolume.h.gcov.html @@ -0,0 +1,165 @@ + + + + + + + + LCOV - plumed test coverage - volumes/ActionVolume.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - volumes - ActionVolume.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:77100.0 %
Date:2024-04-19 12:12:35Functions:22100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2020 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_volumes_ActionVolume_h
+      23             : #define __PLUMED_volumes_ActionVolume_h
+      24             : 
+      25             : #include "tools/HistogramBead.h"
+      26             : #include "core/ActionWithVector.h"
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace volumes {
+      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 ActionWithVector {
+      39             : private:
+      40             : /// The value of sigma
+      41             :   double sigma;
+      42             : /// Are we interested in the area outside the colvar
+      43             :   bool not_in;
+      44             : /// The kernel type for this histogram
+      45             :   std::string kerneltype;
+      46             : protected:
+      47             :   double getSigma() const ;
+      48             :   std::string getKernelType() const ;
+      49             :   Vector getPosition( const unsigned& index ) const ;
+      50             :   void requestAtoms( const std::vector<AtomNumber> & a );
+      51             : public:
+      52             :   static void registerKeywords( Keywords& keys );
+      53             :   explicit ActionVolume(const ActionOptions&);
+      54             :   unsigned getNumberOfDerivatives();
+      55             :   void areAllTasksRequired( std::vector<ActionWithVector*>& task_reducing_actions ) override;
+      56             :   void getNumberOfTasks( unsigned& ntasks ) override ;
+      57             :   int checkTaskStatus( const unsigned& taskno, int& flag ) const override;
+      58             :   void calculate();
+      59             :   virtual void setupRegions() = 0;
+      60             :   bool isInSubChain( unsigned& nder ) override ;
+      61             :   void performTask( const unsigned&, MultiValue& ) const ;
+      62             :   virtual double calculateNumberInside( const Vector& cpos, Vector& derivatives, Tensor& vir, std::vector<Vector>& refders ) const=0;
+      63             : };
+      64             : 
+      65             : inline
+      66        1765 : unsigned ActionVolume::getNumberOfDerivatives() {
+      67        1765 :   return 3*getNumberOfAtoms()+9;
+      68             : }
+      69             : 
+      70             : inline
+      71             : double ActionVolume::getSigma() const {
+      72      194172 :   return sigma;
+      73             : }
+      74             : 
+      75             : inline
+      76             : std::string ActionVolume::getKernelType() const {
+      77      100400 :   return kerneltype;
+      78             : }
+      79             : 
+      80             : inline
+      81      547218 : Vector ActionVolume::getPosition( const unsigned& index ) const {
+      82      547218 :   if( getConstPntrToComponent(0)->getRank()==0 ) return ActionAtomistic::getPosition( 1 + index );
+      83      534738 :   return ActionAtomistic::getPosition( getConstPntrToComponent(0)->getShape()[0] + index );
+      84             : }
+      85             : 
+      86             : }
+      87             : }
+      88             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/volumes/Density.cpp.func-sort-c.html b/coverage/volumes/Density.cpp.func-sort-c.html new file mode 100644 index 000000000000..347fafcafd26 --- /dev/null +++ b/coverage/volumes/Density.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - volumes/Density.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - volumes - Density.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:51050.0 %
Date:2024-04-19 12:12:35Functions:1333.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7volumes7DensityC1ERKNS_13ActionOptionsE0
_ZN4PLMD7volumes7DensityC2ERKNS_13ActionOptionsE0
_ZN4PLMD7volumes7Density16registerKeywordsERNS_8KeywordsE2
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/volumes/Density.cpp.func.html b/coverage/volumes/Density.cpp.func.html new file mode 100644 index 000000000000..54301c195203 --- /dev/null +++ b/coverage/volumes/Density.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - volumes/Density.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - volumes - Density.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:51050.0 %
Date:2024-04-19 12:12:35Functions:1333.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7volumes7Density16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD7volumes7DensityC1ERKNS_13ActionOptionsE0
_ZN4PLMD7volumes7DensityC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/volumes/Density.cpp.gcov.html b/coverage/volumes/Density.cpp.gcov.html new file mode 100644 index 000000000000..bb832269338c --- /dev/null +++ b/coverage/volumes/Density.cpp.gcov.html @@ -0,0 +1,140 @@ + + + + + + + + LCOV - plumed test coverage - volumes/Density.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - volumes - Density.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:51050.0 %
Date:2024-04-19 12:12:35Functions:1333.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 "core/ActionShortcut.h"
+      23             : #include "core/ActionRegister.h"
+      24             : 
+      25             : //+PLUMEDOC MCOLVAR DENSITY
+      26             : /*
+      27             : Depreciated command that is bascially equivalant to GROUP.
+      28             : 
+      29             : Plase don't use this anymore
+      30             : 
+      31             : \par Examples
+      32             : 
+      33             : 
+      34             : */
+      35             : //+ENDPLUMEDOC
+      36             : 
+      37             : namespace PLMD {
+      38             : namespace volumes {
+      39             : 
+      40             : class Density : public ActionShortcut {
+      41             : public:
+      42             :   static void registerKeywords(Keywords& keys);
+      43             :   explicit Density(const ActionOptions&);
+      44             : };
+      45             : 
+      46             : PLUMED_REGISTER_ACTION(Density,"DENSITY")
+      47             : 
+      48           2 : void Density::registerKeywords(Keywords& keys) {
+      49           2 :   ActionShortcut::registerKeywords( keys );
+      50           4 :   keys.add("compulsory","SPECIES","the atoms in the group");
+      51           4 :   keys.needsAction("ONES"); keys.needsAction("GROUP");
+      52           2 : }
+      53             : 
+      54           0 : Density::Density(const ActionOptions& ao):
+      55             :   Action(ao),
+      56           0 :   ActionShortcut(ao)
+      57             : {
+      58           0 :   std::string atoms; parse("SPECIES",atoms);
+      59           0 :   readInputLine( getShortcutLabel() + ": GROUP ATOMS=" + atoms);
+      60           0 : }
+      61             : 
+      62             : }
+      63             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/volumes/VolumeAround.cpp.func-sort-c.html b/coverage/volumes/VolumeAround.cpp.func-sort-c.html new file mode 100644 index 000000000000..55ed99397f0d --- /dev/null +++ b/coverage/volumes/VolumeAround.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - volumes/VolumeAround.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - volumes - VolumeAround.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4949100.0 %
Date:2024-04-19 12:12:35Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7volumes12VolumeAroundC2ERKNS_13ActionOptionsE0
_ZN4PLMD7volumes12VolumeAroundC1ERKNS_13ActionOptionsE46
_ZN4PLMD7volumes12VolumeAround16registerKeywordsERNS_8KeywordsE110
_ZN4PLMD7volumes12VolumeAround12setupRegionsEv388
_ZNK4PLMD7volumes12VolumeAround21calculateNumberInsideERKNS_13VectorGenericILj3EEERS3_RNS_13TensorGenericILj3ELj3EEERSt6vectorIS3_SaIS3_EE98837
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/volumes/VolumeAround.cpp.func.html b/coverage/volumes/VolumeAround.cpp.func.html new file mode 100644 index 000000000000..6cb1943c8c76 --- /dev/null +++ b/coverage/volumes/VolumeAround.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - volumes/VolumeAround.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - volumes - VolumeAround.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4949100.0 %
Date:2024-04-19 12:12:35Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7volumes12VolumeAround12setupRegionsEv388
_ZN4PLMD7volumes12VolumeAround16registerKeywordsERNS_8KeywordsE110
_ZN4PLMD7volumes12VolumeAroundC1ERKNS_13ActionOptionsE46
_ZN4PLMD7volumes12VolumeAroundC2ERKNS_13ActionOptionsE0
_ZNK4PLMD7volumes12VolumeAround21calculateNumberInsideERKNS_13VectorGenericILj3EEERS3_RNS_13TensorGenericILj3ELj3EEERSt6vectorIS3_SaIS3_EE98837
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/volumes/VolumeAround.cpp.gcov.html b/coverage/volumes/VolumeAround.cpp.gcov.html new file mode 100644 index 000000000000..fcad0742297e --- /dev/null +++ b/coverage/volumes/VolumeAround.cpp.gcov.html @@ -0,0 +1,245 @@ + + + + + + + + LCOV - plumed test coverage - volumes/VolumeAround.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - volumes - VolumeAround.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4949100.0 %
Date:2024-04-19 12:12:35Functions:4580.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2020 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received 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             : #include "VolumeShortcut.h"
+      26             : 
+      27             : //+PLUMEDOC VOLUMES AROUND
+      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) w(x_i,y_i,z_i) }{ \sum_i w(x_i,y_i,z_i) }
+      39             : \f]
+      40             : 
+      41             : where the sum is over the collective variables, \f$s_i\f$, each of which can be thought to be at \f$ (x_i,y_i,z_i)\f$.
+      42             : The function \f$ w(x_i,y_i,z_i) \f$ measures whether or not the system is in the subregion of interest. It
+      43             : is equal to:
+      44             : 
+      45             : \f[
+      46             : 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)
+      47             : \f]
+      48             : 
+      49             : where \f$K\f$ is one of the kernel functions described on \ref histogrambead and \f$\sigma\f$ is a bandwidth parameter.
+      50             : 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.
+      51             : 
+      52             : When AROUND is used with the \ref DENSITY action the number of atoms in the specified region is calculated
+      53             : 
+      54             : \par Examples
+      55             : 
+      56             : The following commands tell plumed to calculate the average coordination number for the atoms
+      57             : that have x (in fractional coordinates) within 2.0 nm of the com of mass c1. The final value will be labeled s.mean.
+      58             : \plumedfile
+      59             : COM ATOMS=1-100 LABEL=c1
+      60             : COORDINATIONNUMBER SPECIES=1-100 R_0=1.0 LABEL=c
+      61             : AROUND DATA=c ATOM=c1 XLOWER=-2.0 XUPPER=2.0 SIGMA=0.1 MEAN LABEL=s
+      62             : \endplumedfile
+      63             : 
+      64             : */
+      65             : //+ENDPLUMEDOC
+      66             : 
+      67             : //+PLUMEDOC MCOLVAR AROUND_CALC
+      68             : /*
+      69             : Calculate a vector from the input positions with elements equal to one when the positions are in a particular part of the cell and elements equal to zero otherwise
+      70             : 
+      71             : \par Examples
+      72             : 
+      73             : */
+      74             : //+ENDPLUMEDOC
+      75             : 
+      76             : namespace PLMD {
+      77             : namespace volumes {
+      78             : 
+      79             : class VolumeAround : public ActionVolume {
+      80             : private:
+      81             :   Vector origin;
+      82             :   bool dox, doy, doz;
+      83             :   double xlow, xhigh;
+      84             :   double ylow, yhigh;
+      85             :   double zlow, zhigh;
+      86             : public:
+      87             :   static void registerKeywords( Keywords& keys );
+      88             :   explicit VolumeAround(const ActionOptions& ao);
+      89             :   void setupRegions() override;
+      90             :   double calculateNumberInside( const Vector& cpos, Vector& derivatives, Tensor& vir, std::vector<Vector>& refders ) const override;
+      91             : };
+      92             : 
+      93             : PLUMED_REGISTER_ACTION(VolumeAround,"AROUND_CALC")
+      94             : char glob_around[] = "AROUND";
+      95             : typedef VolumeShortcut<glob_around> VolumeAroundShortcut;
+      96             : PLUMED_REGISTER_ACTION(VolumeAroundShortcut,"AROUND")
+      97             : 
+      98         110 : void VolumeAround::registerKeywords( Keywords& keys ) {
+      99         110 :   ActionVolume::registerKeywords( keys );
+     100         220 :   keys.add("atoms","ORIGIN","the atom whose vicinity we are interested in examining");
+     101         220 :   keys.add("atoms-2","ATOM","an alternative to ORIGIN");
+     102         220 :   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).");
+     103         220 :   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).");
+     104         220 :   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).");
+     105         220 :   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).");
+     106         220 :   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).");
+     107         220 :   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).");
+     108         110 : }
+     109             : 
+     110          46 : VolumeAround::VolumeAround(const ActionOptions& ao):
+     111             :   Action(ao),
+     112          46 :   ActionVolume(ao)
+     113             : {
+     114          92 :   std::vector<AtomNumber> atom; parseAtomList("ORIGIN",atom);
+     115          46 :   if( atom.size()==0 ) parseAtomList("ATOM",atom);
+     116          46 :   if( atom.size()!=1 ) error("should only be one atom specified");
+     117          46 :   log.printf("  boundaries for region are calculated based on positions of atom : %d\n",atom[0].serial() );
+     118             : 
+     119          92 :   dox=true; parse("XLOWER",xlow); parse("XUPPER",xhigh);
+     120          92 :   doy=true; parse("YLOWER",ylow); parse("YUPPER",yhigh);
+     121          92 :   doz=true; parse("ZLOWER",zlow); parse("ZUPPER",zhigh);
+     122          46 :   if( xlow==0.0 && xhigh==0.0 ) dox=false;
+     123          46 :   if( ylow==0.0 && yhigh==0.0 ) doy=false;
+     124          46 :   if( zlow==0.0 && zhigh==0.0 ) doz=false;
+     125          46 :   if( !dox && !doy && !doz ) error("no subregion defined use XLOWER, XUPPER, YLOWER, YUPPER, ZLOWER, ZUPPER");
+     126          46 :   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);
+     127          46 :   checkRead(); requestAtoms(atom);
+     128          46 : }
+     129             : 
+     130         388 : void VolumeAround::setupRegions() { }
+     131             : 
+     132       98837 : double VolumeAround::calculateNumberInside( const Vector& cpos, Vector& derivatives, Tensor& vir, std::vector<Vector>& refders ) const {
+     133             :   // Setup the histogram bead
+     134      197674 :   HistogramBead bead; bead.isNotPeriodic(); bead.setKernelType( getKernelType() );
+     135             : 
+     136             :   // Calculate position of atom wrt to origin
+     137       98837 :   Vector fpos=pbcDistance( getPosition(0), cpos );
+     138             :   double xcontr, ycontr, zcontr, xder, yder, zder;
+     139       98837 :   if( dox ) {
+     140       66341 :     bead.set( xlow, xhigh, getSigma() );
+     141       66341 :     xcontr=bead.calculate( fpos[0], xder );
+     142             :   } else {
+     143       32496 :     xcontr=1.; xder=0.;
+     144             :   }
+     145       98837 :   if( doy ) {
+     146       63681 :     bead.set( ylow, yhigh, getSigma() );
+     147       63681 :     ycontr=bead.calculate( fpos[1], yder );
+     148             :   } else {
+     149       35156 :     ycontr=1.; yder=0.;
+     150             :   }
+     151       98837 :   if( doz ) {
+     152       62589 :     bead.set( zlow, zhigh, getSigma() );
+     153       62589 :     zcontr=bead.calculate( fpos[2], zder );
+     154             :   } else {
+     155       36248 :     zcontr=1.; zder=0.;
+     156             :   }
+     157       98837 :   derivatives[0]=xder*ycontr*zcontr;
+     158       98837 :   derivatives[1]=xcontr*yder*zcontr;
+     159       98837 :   derivatives[2]=xcontr*ycontr*zder;
+     160             :   // Add derivatives wrt to position of origin atom
+     161       98837 :   refders[0] = -derivatives;
+     162             :   // Add virial contribution
+     163       98837 :   vir -= Tensor(fpos,derivatives);
+     164       98837 :   return xcontr*ycontr*zcontr;
+     165             : }
+     166             : 
+     167             : }
+     168             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/volumes/VolumeBetweenContours.cpp.func-sort-c.html b/coverage/volumes/VolumeBetweenContours.cpp.func-sort-c.html new file mode 100644 index 000000000000..72269c8abc65 --- /dev/null +++ b/coverage/volumes/VolumeBetweenContours.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - volumes/VolumeBetweenContours.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - volumes - VolumeBetweenContours.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:515298.1 %
Date:2024-04-19 12:12:35Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7volumes16VolumeInEnvelopeC2ERKNS_13ActionOptionsE0
_ZN4PLMD7volumes16VolumeInEnvelopeC1ERKNS_13ActionOptionsE1
_ZN4PLMD7volumes16VolumeInEnvelope12setupRegionsEv5
_ZN4PLMD7volumes16VolumeInEnvelope16registerKeywordsERNS_8KeywordsE6
_ZNK4PLMD7volumes16VolumeInEnvelope21calculateNumberInsideERKNS_13VectorGenericILj3EEERS3_RNS_13TensorGenericILj3ELj3EEERSt6vectorIS3_SaIS3_EE1000
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/volumes/VolumeBetweenContours.cpp.func.html b/coverage/volumes/VolumeBetweenContours.cpp.func.html new file mode 100644 index 000000000000..95eb23e5ce7c --- /dev/null +++ b/coverage/volumes/VolumeBetweenContours.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - volumes/VolumeBetweenContours.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - volumes - VolumeBetweenContours.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:515298.1 %
Date:2024-04-19 12:12:35Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7volumes16VolumeInEnvelope12setupRegionsEv5
_ZN4PLMD7volumes16VolumeInEnvelope16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD7volumes16VolumeInEnvelopeC1ERKNS_13ActionOptionsE1
_ZN4PLMD7volumes16VolumeInEnvelopeC2ERKNS_13ActionOptionsE0
_ZNK4PLMD7volumes16VolumeInEnvelope21calculateNumberInsideERKNS_13VectorGenericILj3EEERS3_RNS_13TensorGenericILj3ELj3EEERSt6vectorIS3_SaIS3_EE1000
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/volumes/VolumeBetweenContours.cpp.gcov.html b/coverage/volumes/VolumeBetweenContours.cpp.gcov.html new file mode 100644 index 000000000000..563c3fb74a7d --- /dev/null +++ b/coverage/volumes/VolumeBetweenContours.cpp.gcov.html @@ -0,0 +1,239 @@ + + + + + + + + LCOV - plumed test coverage - volumes/VolumeBetweenContours.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - volumes - VolumeBetweenContours.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:515298.1 %
Date:2024-04-19 12:12:35Functions:4580.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2017-2020 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received 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 "tools/LinkCells.h"
+      26             : #include "ActionVolume.h"
+      27             : #include "VolumeShortcut.h"
+      28             : #include <memory>
+      29             : 
+      30             : //+PLUMEDOC VOLUMES INENVELOPE
+      31             : /*
+      32             : 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.
+      33             : 
+      34             : This collective variable can be used to determine whether colvars are within region where the density
+      35             : of a particular atom is high.  This is achieved by calculating the following function at the point where
+      36             : the atom is located \f$(x,y,z)\f$:
+      37             : 
+      38             : \f[
+      39             : 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]
+      40             : \f]
+      41             : 
+      42             : Here \f$\sigma\f$ is a \ref switchingfunction and \f$K\f$ is a \ref kernelfunctions.  The sum runs over the atoms
+      43             : specified using the ATOMS keyword and a \f$w_j\f$ value is calculated for each of the central atoms of the input
+      44             : multicolvar.
+      45             : 
+      46             : \par Examples
+      47             : 
+      48             : The input below calculates a density field from the positions of atoms 1-14400.  The number of the atoms
+      49             : that are specified in the DENSITY action that are within a region where the density field is greater than
+      50             : 2.0 is then calculated.
+      51             : 
+      52             : \plumedfile
+      53             : d1: DENSITY SPECIES=14401-74134:3 LOWMEM
+      54             : 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
+      55             : PRINT ARG=fi FILE=colvar
+      56             : \endplumedfile
+      57             : 
+      58             : */
+      59             : //+ENDPLUMEDOC
+      60             : 
+      61             : //+PLUMEDOC VOLUMES INENVELOPE_CALC
+      62             : /*
+      63             : 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.
+      64             : 
+      65             : \par Examples
+      66             : 
+      67             : */
+      68             : //+ENDPLUMEDOC
+      69             : 
+      70             : namespace PLMD {
+      71             : namespace volumes {
+      72             : 
+      73             : class VolumeInEnvelope : public ActionVolume {
+      74             : private:
+      75             :   LinkCells mylinks;
+      76             :   double gvol;
+      77             :   std::vector<std::unique_ptr<Value>> pos;
+      78             :   std::vector<Vector> ltmp_pos;
+      79             :   std::vector<unsigned> ltmp_ind;
+      80             :   std::vector<double> bandwidth;
+      81             :   SwitchingFunction sfunc, switchingFunction;
+      82             : public:
+      83             :   static void registerKeywords( Keywords& keys );
+      84             :   explicit VolumeInEnvelope(const ActionOptions& ao);
+      85             :   void setupRegions() override;
+      86             :   double calculateNumberInside( const Vector& cpos, Vector& derivatives, Tensor& vir, std::vector<Vector>& refders ) const override;
+      87             : };
+      88             : 
+      89             : PLUMED_REGISTER_ACTION(VolumeInEnvelope,"INENVELOPE_CALC")
+      90             : char glob_contours[] = "INENVELOPE";
+      91             : typedef VolumeShortcut<glob_contours> VolumeInEnvelopeShortcut;
+      92             : PLUMED_REGISTER_ACTION(VolumeInEnvelopeShortcut,"INENVELOPE")
+      93             : 
+      94           6 : void VolumeInEnvelope::registerKeywords( Keywords& keys ) {
+      95           6 :   ActionVolume::registerKeywords( keys ); keys.remove("SIGMA");
+      96          12 :   keys.add("atoms","FIELD_ATOMS","the atom whose positions we are constructing a field from");
+      97          12 :   keys.add("compulsory","BANDWIDTH","the bandwidths for kernel density esimtation");
+      98          12 :   keys.add("compulsory","CONTOUR","a switching funciton that tells PLUMED how large the density should be");
+      99          12 :   keys.add("compulsory","CUTOFF","6.25","the cutoff at which to stop evaluating the kernel functions is set equal to sqrt(2*x)*bandwidth in each direction where x is this number");
+     100           6 : }
+     101             : 
+     102           1 : VolumeInEnvelope::VolumeInEnvelope(const ActionOptions& ao):
+     103             :   Action(ao),
+     104             :   ActionVolume(ao),
+     105           1 :   mylinks(comm)
+     106             : {
+     107           1 :   std::vector<AtomNumber> atoms; parseAtomList("FIELD_ATOMS",atoms);
+     108           1 :   log.printf("  creating density field from atoms : ");
+     109           9 :   for(unsigned i=0; i<atoms.size(); ++i) log.printf("%d ",atoms[i].serial() );
+     110           1 :   log.printf("\n"); ltmp_ind.resize( atoms.size() ); ltmp_pos.resize( atoms.size() );
+     111           9 :   for(unsigned i=0; i<atoms.size(); ++i) ltmp_ind[i]=i;
+     112             : 
+     113           2 :   std::string sw, errors; parse("CONTOUR",sw);
+     114           1 :   if(sw.length()==0) error("missing CONTOUR keyword");
+     115           1 :   sfunc.set(sw,errors);
+     116           1 :   if( errors.length()!=0 ) error("problem reading RADIUS keyword : " + errors );
+     117           1 :   log.printf("  density at atom must be larger than %s \n", ( sfunc.description() ).c_str() );
+     118             : 
+     119           1 :   std::vector<double> pp(3,0.0); bandwidth.resize(3); parseVector("BANDWIDTH",bandwidth);
+     120           2 :   log.printf("  using %s kernel with bandwidths %f %f %f \n",getKernelType().c_str(),bandwidth[0],bandwidth[1],bandwidth[2] );
+     121           2 :   std::string errors2; switchingFunction.set("GAUSSIAN R_0=1.0 NOSTRETCH", errors2 );
+     122           1 :   if( errors2.length()!=0 ) error("problem reading switching function description " + errors2);
+     123           4 :   double det=1; for(unsigned i=0; i<bandwidth.size(); ++i) det*=bandwidth[i]*bandwidth[i];
+     124           2 :   gvol=1.0; if( getKernelType()=="gaussian" ) gvol=pow( 2*pi, 0.5*bandwidth.size() ) * pow( det, 0.5 );
+     125           0 :   else error("cannot use kernel other than gaussian");
+     126           2 :   double dp2cutoff; parse("CUTOFF",dp2cutoff); double maxs =  sqrt(2*dp2cutoff)*bandwidth[0];
+     127           3 :   for(unsigned j=1; j<bandwidth.size(); ++j) {
+     128           2 :     if( sqrt(2*dp2cutoff)*bandwidth[j]>maxs ) maxs=sqrt(2*dp2cutoff)*bandwidth[j];
+     129             :   }
+     130           1 :   checkRead(); requestAtoms(atoms); mylinks.setCutoff( maxs );
+     131           1 : }
+     132             : 
+     133           5 : void VolumeInEnvelope::setupRegions() {
+     134          45 :   for(unsigned i=0; i<ltmp_ind.size(); ++i) { ltmp_pos[i]=getPosition(i); }
+     135           5 :   mylinks.buildCellLists( ltmp_pos, ltmp_ind, getPbc() );
+     136           5 : }
+     137             : 
+     138        1000 : double VolumeInEnvelope::calculateNumberInside( const Vector& cpos, Vector& derivatives, Tensor& vir, std::vector<Vector>& refders ) const {
+     139        1000 :   unsigned ncells_required=0, natoms=1; std::vector<unsigned> cells_required( mylinks.getNumberOfCells() ), indices( 1 + getNumberOfAtoms() );
+     140        1000 :   mylinks.addRequiredCells( mylinks.findMyCell( cpos ), ncells_required, cells_required );
+     141        1000 :   indices[0]=getNumberOfAtoms(); mylinks.retrieveAtomsInCells( ncells_required, cells_required, natoms, indices );
+     142        1000 :   double value=0; std::vector<double> der(3); Vector tder;
+     143             : 
+     144             :   // convert pointer once
+     145        1000 :   auto pos_ptr=Tools::unique2raw(pos);
+     146        9000 :   for(unsigned i=1; i<natoms; ++i) {
+     147        8000 :     Vector dist = pbcDistance( cpos, getPosition( indices[i] ) );
+     148       32000 :     double dval=0; for(unsigned j=0; j<3; ++j) { der[j] = dist[j]/bandwidth[j]; dval += der[j]*der[j]; der[j] = der[j] / bandwidth[j]; }
+     149        8000 :     double dfunc; value += switchingFunction.calculateSqr( dval, dfunc ) / gvol; double tmp = dfunc / gvol;
+     150       32000 :     for(unsigned j=0; j<3; ++j) {
+     151       24000 :       derivatives[j] -= tmp*der[j]; refders[ indices[i] ][j] += tmp*der[j]; tder[j]=tmp*der[j];
+     152             :     }
+     153        8000 :     vir -= Tensor( tder, dist );
+     154             :   }
+     155        1000 :   double deriv, fval = sfunc.calculate( value, deriv );
+     156        1000 :   derivatives *= -deriv*value; vir *= -deriv*value;
+     157        9000 :   for(unsigned i=1; i<natoms; ++i) refders[ indices[i] ] *= -deriv*value;
+     158        2000 :   return 1.0 - fval;
+     159             : }
+     160             : 
+     161             : }
+     162             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/volumes/VolumeCavity.cpp.func-sort-c.html b/coverage/volumes/VolumeCavity.cpp.func-sort-c.html new file mode 100644 index 000000000000..d280b4313c6a --- /dev/null +++ b/coverage/volumes/VolumeCavity.cpp.func-sort-c.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - volumes/VolumeCavity.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - volumes - VolumeCavity.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:16721179.1 %
Date:2024-04-19 12:12:35Functions:7977.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7volumes12VolumeCavityC2ERKNS_13ActionOptionsE0
_ZN4PLMD7volumes12VolumeCavityD2Ev0
_ZN4PLMD7volumes12VolumeCavityC1ERKNS_13ActionOptionsE1
_ZN4PLMD7volumes12VolumeCavityD0Ev1
_ZN4PLMD7volumes12VolumeCavityD1Ev1
_ZN4PLMD7volumes12VolumeCavity16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD7volumes12VolumeCavity6updateEv60
_ZN4PLMD7volumes12VolumeCavity12setupRegionsEv1560
_ZNK4PLMD7volumes12VolumeCavity21calculateNumberInsideERKNS_13VectorGenericILj3EEERS3_RNS_13TensorGenericILj3ELj3EEERSt6vectorIS3_SaIS3_EE1560
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/volumes/VolumeCavity.cpp.func.html b/coverage/volumes/VolumeCavity.cpp.func.html new file mode 100644 index 000000000000..51dc95c1f99e --- /dev/null +++ b/coverage/volumes/VolumeCavity.cpp.func.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - volumes/VolumeCavity.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - volumes - VolumeCavity.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:16721179.1 %
Date:2024-04-19 12:12:35Functions:7977.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7volumes12VolumeCavity12setupRegionsEv1560
_ZN4PLMD7volumes12VolumeCavity16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD7volumes12VolumeCavity6updateEv60
_ZN4PLMD7volumes12VolumeCavityC1ERKNS_13ActionOptionsE1
_ZN4PLMD7volumes12VolumeCavityC2ERKNS_13ActionOptionsE0
_ZN4PLMD7volumes12VolumeCavityD0Ev1
_ZN4PLMD7volumes12VolumeCavityD1Ev1
_ZN4PLMD7volumes12VolumeCavityD2Ev0
_ZNK4PLMD7volumes12VolumeCavity21calculateNumberInsideERKNS_13VectorGenericILj3EEERS3_RNS_13TensorGenericILj3ELj3EEERSt6vectorIS3_SaIS3_EE1560
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/volumes/VolumeCavity.cpp.gcov.html b/coverage/volumes/VolumeCavity.cpp.gcov.html new file mode 100644 index 000000000000..a524c2b7ed33 --- /dev/null +++ b/coverage/volumes/VolumeCavity.cpp.gcov.html @@ -0,0 +1,497 @@ + + + + + + + + LCOV - plumed test coverage - volumes/VolumeCavity.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - volumes - VolumeCavity.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:16721179.1 %
Date:2024-04-19 12:12:35Functions:7977.8 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2014-2020 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received 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 "tools/Units.h"
+      25             : #include "tools/Pbc.h"
+      26             : #include "ActionVolume.h"
+      27             : #include "VolumeShortcut.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             : //+PLUMEDOC MCOLVAR CAVITY_CALC
+     106             : /*
+     107             : Calculate a vector from the input positions with elements equal to one when the positions are in a particular part of the cell and elements equal to zero otherwise
+     108             : 
+     109             : \par Examples
+     110             : 
+     111             : */
+     112             : //+ENDPLUMEDOC
+     113             : 
+     114             : namespace PLMD {
+     115             : namespace volumes {
+     116             : 
+     117             : class VolumeCavity : public ActionVolume {
+     118             : private:
+     119             :   bool boxout;
+     120             :   OFile boxfile;
+     121             :   double lenunit;
+     122             :   double jacob_det;
+     123             :   double len_bi, len_cross, len_perp, sigma;
+     124             :   Vector origin, bi, cross, perp;
+     125             :   std::vector<Vector> dlbi, dlcross, dlperp;
+     126             :   std::vector<Tensor> dbi, dcross, dperp;
+     127             : public:
+     128             :   static void registerKeywords( Keywords& keys );
+     129             :   explicit VolumeCavity(const ActionOptions& ao);
+     130             :   ~VolumeCavity();
+     131             :   void setupRegions() override;
+     132             :   void update() override;
+     133             :   double calculateNumberInside( const Vector& cpos, Vector& derivatives, Tensor& vir, std::vector<Vector>& refders ) const override;
+     134             : };
+     135             : 
+     136             : PLUMED_REGISTER_ACTION(VolumeCavity,"CAVITY_CALC")
+     137             : char glob_cavity[] = "CAVITY";
+     138             : typedef VolumeShortcut<glob_cavity> VolumeCavityShortcut;
+     139             : PLUMED_REGISTER_ACTION(VolumeCavityShortcut,"CAVITY")
+     140             : 
+     141           6 : void VolumeCavity::registerKeywords( Keywords& keys ) {
+     142           6 :   ActionVolume::registerKeywords( keys );
+     143          12 :   keys.add("atoms","BOX","the positions of four atoms that define spatial extent of the cavity");
+     144          12 :   keys.addFlag("PRINT_BOX",false,"write out the positions of the corners of the box to an xyz file");
+     145          12 :   keys.add("optional","FILE","the file on which to write out the box coordinates");
+     146          12 :   keys.add("optional","UNITS","( default=nm ) the units in which to write out the corners of the box");
+     147           6 : }
+     148             : 
+     149           1 : VolumeCavity::VolumeCavity(const ActionOptions& ao):
+     150             :   Action(ao),
+     151             :   ActionVolume(ao),
+     152           1 :   boxout(false),
+     153           1 :   lenunit(1.0),
+     154           1 :   dlbi(4),
+     155           1 :   dlcross(4),
+     156           1 :   dlperp(4),
+     157           1 :   dbi(3),
+     158           1 :   dcross(3),
+     159           2 :   dperp(3)
+     160             : {
+     161           2 :   std::vector<AtomNumber> atoms; parseAtomList("BOX",atoms);
+     162           1 :   if( atoms.size()!=4 ) error("number of atoms in box should be equal to four");
+     163             : 
+     164           1 :   log.printf("  boundaries for region are calculated based on positions of atoms : ");
+     165           5 :   for(unsigned i=0; i<atoms.size(); ++i) log.printf("%d ",atoms[i].serial() );
+     166           1 :   log.printf("\n"); requestAtoms( atoms );
+     167             : 
+     168           1 :   boxout=false; parseFlag("PRINT_BOX",boxout);
+     169           1 :   if(boxout) {
+     170           0 :     std::string boxfname; parse("FILE",boxfname);
+     171           0 :     if(boxfname.length()==0) error("no name for box file specified");
+     172           0 :     std::string unitname; parse("UNITS",unitname);
+     173           0 :     if ( unitname.length()>0 ) {
+     174           0 :       Units u; u.setLength(unitname);
+     175           0 :       lenunit=getUnits().getLength()/u.getLength();
+     176           0 :     } else {
+     177             :       unitname="nm";
+     178             :     }
+     179           0 :     boxfile.link(*this);
+     180           0 :     boxfile.open( boxfname );
+     181           0 :     log.printf("  printing box coordinates on file named %s in %s \n",boxfname.c_str(), unitname.c_str() );
+     182             :   }
+     183             : 
+     184           1 :   checkRead();
+     185           1 : }
+     186             : 
+     187           2 : VolumeCavity::~VolumeCavity() {
+     188           2 : }
+     189             : 
+     190        1560 : void VolumeCavity::setupRegions() {
+     191             :   // Make some space for things
+     192        1560 :   Vector d1, d2, d3;
+     193             : 
+     194             :   // Retrieve the sigma value
+     195        1560 :   sigma=getSigma();
+     196             :   // Set the position of the origin
+     197        1560 :   origin=getPosition(0);
+     198             : 
+     199             :   // Get two vectors
+     200        1560 :   d1 = pbcDistance(origin,getPosition(1));
+     201        1560 :   double d1l=d1.modulo();
+     202        1560 :   d2 = pbcDistance(origin,getPosition(2));
+     203             : 
+     204             :   // Find the vector connecting the origin to the top corner of
+     205             :   // the subregion
+     206        1560 :   d3 = pbcDistance(origin,getPosition(3));
+     207             : 
+     208             :   // Create a set of unit vectors
+     209        1560 :   bi = d1 / d1l; len_bi=dotProduct( d3, bi );
+     210        1560 :   cross = crossProduct( d1, d2 ); double crossmod=cross.modulo();
+     211        1560 :   cross = cross / crossmod; len_cross=dotProduct( d3, cross );
+     212        1560 :   perp = crossProduct( cross, bi ); len_perp=dotProduct( d3, perp );
+     213             : 
+     214             :   // Calculate derivatives of box shape with respect to atoms
+     215        1560 :   double d1l3=d1l*d1l*d1l;
+     216        1560 :   dbi[0](0,0) = ( -(d1[1]*d1[1]+d1[2]*d1[2])/d1l3 );   // dx/dx
+     217        1560 :   dbi[0](0,1) = (  d1[0]*d1[1]/d1l3 );                 // dx/dy
+     218        1560 :   dbi[0](0,2) = (  d1[0]*d1[2]/d1l3 );                 // dx/dz
+     219        1560 :   dbi[0](1,0) = (  d1[1]*d1[0]/d1l3 );                 // dy/dx
+     220        1560 :   dbi[0](1,1) = ( -(d1[0]*d1[0]+d1[2]*d1[2])/d1l3 );   // dy/dy
+     221        1560 :   dbi[0](1,2) = (  d1[1]*d1[2]/d1l3 );
+     222        1560 :   dbi[0](2,0) = (  d1[2]*d1[0]/d1l3 );
+     223        1560 :   dbi[0](2,1) = (  d1[2]*d1[1]/d1l3 );
+     224        1560 :   dbi[0](2,2) = ( -(d1[1]*d1[1]+d1[0]*d1[0])/d1l3 );
+     225             : 
+     226        1560 :   dbi[1](0,0) = ( (d1[1]*d1[1]+d1[2]*d1[2])/d1l3 );
+     227        1560 :   dbi[1](0,1) = ( -d1[0]*d1[1]/d1l3 );
+     228        1560 :   dbi[1](0,2) = ( -d1[0]*d1[2]/d1l3 );
+     229        1560 :   dbi[1](1,0) = ( -d1[1]*d1[0]/d1l3 );
+     230        1560 :   dbi[1](1,1) = ( (d1[0]*d1[0]+d1[2]*d1[2])/d1l3 );
+     231        1560 :   dbi[1](1,2) = ( -d1[1]*d1[2]/d1l3 );
+     232        1560 :   dbi[1](2,0) = ( -d1[2]*d1[0]/d1l3 );
+     233        1560 :   dbi[1](2,1) = ( -d1[2]*d1[1]/d1l3 );
+     234        1560 :   dbi[1](2,2) = ( (d1[1]*d1[1]+d1[0]*d1[0])/d1l3 );
+     235        1560 :   dbi[2].zero();
+     236             : 
+     237        1560 :   Tensor tcderiv; double cmod3=crossmod*crossmod*crossmod; Vector ucross=crossmod*cross;
+     238        1560 :   tcderiv.setCol( 0, crossProduct( d1, Vector(-1.0,0.0,0.0) ) + crossProduct( Vector(-1.0,0.0,0.0), d2 ) );
+     239        1560 :   tcderiv.setCol( 1, crossProduct( d1, Vector(0.0,-1.0,0.0) ) + crossProduct( Vector(0.0,-1.0,0.0), d2 ) );
+     240        1560 :   tcderiv.setCol( 2, crossProduct( d1, Vector(0.0,0.0,-1.0) ) + crossProduct( Vector(0.0,0.0,-1.0), d2 ) );
+     241        1560 :   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
+     242        1560 :   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
+     243        1560 :   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
+     244        1560 :   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
+     245        1560 :   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
+     246        1560 :   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
+     247        1560 :   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
+     248        1560 :   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
+     249        1560 :   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
+     250             : 
+     251        1560 :   tcderiv.setCol( 0, crossProduct( Vector(1.0,0.0,0.0), d2 ) );
+     252        1560 :   tcderiv.setCol( 1, crossProduct( Vector(0.0,1.0,0.0), d2 ) );
+     253        1560 :   tcderiv.setCol( 2, crossProduct( Vector(0.0,0.0,1.0), d2 ) );
+     254        1560 :   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
+     255        1560 :   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
+     256        1560 :   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
+     257        1560 :   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
+     258        1560 :   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
+     259        1560 :   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
+     260        1560 :   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
+     261        1560 :   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
+     262        1560 :   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
+     263             : 
+     264        1560 :   tcderiv.setCol( 0, crossProduct( d1, Vector(1.0,0.0,0.0) ) );
+     265        1560 :   tcderiv.setCol( 1, crossProduct( d1, Vector(0.0,1.0,0.0) ) );
+     266        1560 :   tcderiv.setCol( 2, crossProduct( d1, Vector(0.0,0.0,1.0) ) );
+     267        1560 :   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
+     268        1560 :   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
+     269        1560 :   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
+     270        1560 :   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
+     271        1560 :   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
+     272        1560 :   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
+     273        1560 :   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
+     274        1560 :   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
+     275        1560 :   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
+     276             : 
+     277        1560 :   dperp[0].setCol( 0, ( crossProduct( dcross[0].getCol(0), bi ) + crossProduct( cross, dbi[0].getCol(0) ) ) );
+     278        1560 :   dperp[0].setCol( 1, ( crossProduct( dcross[0].getCol(1), bi ) + crossProduct( cross, dbi[0].getCol(1) ) ) );
+     279        1560 :   dperp[0].setCol( 2, ( crossProduct( dcross[0].getCol(2), bi ) + crossProduct( cross, dbi[0].getCol(2) ) ) );
+     280             : 
+     281        1560 :   dperp[1].setCol( 0, ( crossProduct( dcross[1].getCol(0), bi ) + crossProduct( cross, dbi[1].getCol(0) ) ) );
+     282        1560 :   dperp[1].setCol( 1, ( crossProduct( dcross[1].getCol(1), bi ) + crossProduct( cross, dbi[1].getCol(1) ) ) );
+     283        1560 :   dperp[1].setCol( 2, ( crossProduct( dcross[1].getCol(2), bi ) + crossProduct( cross, dbi[1].getCol(2) ) ) );
+     284             : 
+     285        1560 :   dperp[2].setCol( 0, ( crossProduct( dcross[2].getCol(0), bi ) ) );
+     286        1560 :   dperp[2].setCol( 1, ( crossProduct( dcross[2].getCol(1), bi ) ) );
+     287        1560 :   dperp[2].setCol( 2, ( crossProduct( dcross[2].getCol(2), bi ) ) );
+     288             : 
+     289             :   // Ensure that all lengths are positive
+     290        1560 :   if( len_bi<0 ) {
+     291           0 :     bi=-bi; len_bi=-len_bi;
+     292           0 :     for(unsigned i=0; i<3; ++i) dbi[i]*=-1.0;
+     293             :   }
+     294        1560 :   if( len_cross<0 ) {
+     295           0 :     cross=-cross; len_cross=-len_cross;
+     296           0 :     for(unsigned i=0; i<3; ++i) dcross[i]*=-1.0;
+     297             :   }
+     298        1560 :   if( len_perp<0 ) {
+     299           0 :     perp=-perp; len_perp=-len_perp;
+     300           0 :     for(unsigned i=0; i<3; ++i) dperp[i]*=-1.0;
+     301             :   }
+     302        1560 :   if( len_bi<=0 || len_cross<=0 || len_bi<=0 ) plumed_merror("Invalid box coordinates");
+     303             : 
+     304             :   // Now derivatives of lengths
+     305        1560 :   Tensor dd3( Tensor::identity() );
+     306        1560 :   dlbi[0] = matmul(d3,dbi[0]) - matmul(bi,dd3);
+     307        1560 :   dlbi[1] = matmul(d3,dbi[1]);
+     308        1560 :   dlbi[2] = matmul(d3,dbi[2]);
+     309        1560 :   dlbi[3] = matmul(bi,dd3);
+     310             : 
+     311        1560 :   dlcross[0] = matmul(d3,dcross[0]) - matmul(cross,dd3);
+     312        1560 :   dlcross[1] = matmul(d3,dcross[1]);
+     313        1560 :   dlcross[2] = matmul(d3,dcross[2]);
+     314        1560 :   dlcross[3] = matmul(cross,dd3);
+     315             : 
+     316        1560 :   dlperp[0] = matmul(d3,dperp[0]) - matmul(perp,dd3);
+     317        1560 :   dlperp[1] = matmul(d3,dperp[1]);
+     318        1560 :   dlperp[2] = matmul(d3,dperp[2]);
+     319        1560 :   dlperp[3] = matmul(perp,dd3);
+     320             : 
+     321             :   // Need to calculate the jacobian
+     322        1560 :   Tensor jacob;
+     323        1560 :   jacob(0,0)=bi[0]; jacob(1,0)=bi[1]; jacob(2,0)=bi[2];
+     324        1560 :   jacob(0,1)=cross[0]; jacob(1,1)=cross[1]; jacob(2,1)=cross[2];
+     325        1560 :   jacob(0,2)=perp[0]; jacob(1,2)=perp[1]; jacob(2,2)=perp[2];
+     326        1560 :   jacob_det = fabs( jacob.determinant() );
+     327        1560 : }
+     328             : 
+     329          60 : void VolumeCavity::update() {
+     330          60 :   if(boxout) {
+     331           0 :     boxfile.printf("%d\n",8);
+     332           0 :     const Tensor & t(getPbc().getBox());
+     333           0 :     if(getPbc().isOrthorombic()) {
+     334           0 :       boxfile.printf(" %f %f %f\n",lenunit*t(0,0),lenunit*t(1,1),lenunit*t(2,2));
+     335             :     } else {
+     336           0 :       boxfile.printf(" %f %f %f %f %f %f %f %f %f\n",
+     337           0 :                      lenunit*t(0,0),lenunit*t(0,1),lenunit*t(0,2),
+     338           0 :                      lenunit*t(1,0),lenunit*t(1,1),lenunit*t(1,2),
+     339           0 :                      lenunit*t(2,0),lenunit*t(2,1),lenunit*t(2,2)
+     340             :                     );
+     341             :     }
+     342           0 :     boxfile.printf("AR %f %f %f \n",lenunit*origin[0],lenunit*origin[1],lenunit*origin[2]);
+     343           0 :     Vector ut, vt, wt;
+     344           0 :     ut = origin + len_bi*bi;
+     345           0 :     vt = origin + len_cross*cross;
+     346           0 :     wt = origin + len_perp*perp;
+     347           0 :     boxfile.printf("AR %f %f %f \n",lenunit*(ut[0]), lenunit*(ut[1]), lenunit*(ut[2]) );
+     348           0 :     boxfile.printf("AR %f %f %f \n",lenunit*(vt[0]), lenunit*(vt[1]), lenunit*(vt[2]) );
+     349           0 :     boxfile.printf("AR %f %f %f \n",lenunit*(wt[0]), lenunit*(wt[1]), lenunit*(wt[2]) );
+     350           0 :     boxfile.printf("AR %f %f %f \n",lenunit*(vt[0]+len_bi*bi[0]),
+     351           0 :                    lenunit*(vt[1]+len_bi*bi[1]),
+     352           0 :                    lenunit*(vt[2]+len_bi*bi[2]) );
+     353           0 :     boxfile.printf("AR %f %f %f \n",lenunit*(ut[0]+len_perp*perp[0]),
+     354           0 :                    lenunit*(ut[1]+len_perp*perp[1]),
+     355           0 :                    lenunit*(ut[2]+len_perp*perp[2]) );
+     356           0 :     boxfile.printf("AR %f %f %f \n",lenunit*(vt[0]+len_perp*perp[0]),
+     357           0 :                    lenunit*(vt[1]+len_perp*perp[1]),
+     358           0 :                    lenunit*(vt[2]+len_perp*perp[2]) );
+     359           0 :     boxfile.printf("AR %f %f %f \n",lenunit*(vt[0]+len_perp*perp[0]+len_bi*bi[0]),
+     360           0 :                    lenunit*(vt[1]+len_perp*perp[1]+len_bi*bi[1]),
+     361           0 :                    lenunit*(vt[2]+len_perp*perp[2]+len_bi*bi[2]) );
+     362             :   }
+     363          60 : }
+     364             : 
+     365        1560 : double VolumeCavity::calculateNumberInside( const Vector& cpos, Vector& derivatives, Tensor& vir, std::vector<Vector>& rderiv ) const {
+     366             :   // Setup the histogram bead
+     367        3120 :   HistogramBead bead; bead.isNotPeriodic(); bead.setKernelType( getKernelType() );
+     368             : 
+     369             :   // Calculate distance of atom from origin of new coordinate frame
+     370        1560 :   Vector datom=pbcDistance( origin, cpos );
+     371             :   double ucontr, uder, vcontr, vder, wcontr, wder;
+     372             : 
+     373             :   // Calculate contribution from integral along bi
+     374        1560 :   bead.set( 0, len_bi, sigma );
+     375        1560 :   double upos=dotProduct( datom, bi );
+     376        1560 :   ucontr=bead.calculate( upos, uder );
+     377        1560 :   double udlen=bead.uboundDerivative( upos );
+     378        1560 :   double uder2 = bead.lboundDerivative( upos ) - udlen;
+     379             : 
+     380             :   // Calculate contribution from integral along cross
+     381        1560 :   bead.set( 0, len_cross, sigma );
+     382        1560 :   double vpos=dotProduct( datom, cross );
+     383        1560 :   vcontr=bead.calculate( vpos, vder );
+     384        1560 :   double vdlen=bead.uboundDerivative( vpos );
+     385        1560 :   double vder2 = bead.lboundDerivative( vpos ) - vdlen;
+     386             : 
+     387             :   // Calculate contribution from integral along perp
+     388        1560 :   bead.set( 0, len_perp, sigma );
+     389        1560 :   double wpos=dotProduct( datom, perp );
+     390        1560 :   wcontr=bead.calculate( wpos, wder );
+     391        1560 :   double wdlen=bead.uboundDerivative( wpos );
+     392        1560 :   double wder2 = bead.lboundDerivative( wpos ) - wdlen;
+     393             : 
+     394        1560 :   Vector dfd; dfd[0]=uder*vcontr*wcontr; dfd[1]=ucontr*vder*wcontr; dfd[2]=ucontr*vcontr*wder;
+     395        1560 :   derivatives[0] = (dfd[0]*bi[0]+dfd[1]*cross[0]+dfd[2]*perp[0]);
+     396        1560 :   derivatives[1] = (dfd[0]*bi[1]+dfd[1]*cross[1]+dfd[2]*perp[1]);
+     397        1560 :   derivatives[2] = (dfd[0]*bi[2]+dfd[1]*cross[2]+dfd[2]*perp[2]);
+     398        1560 :   double tot = ucontr*vcontr*wcontr*jacob_det;
+     399             : 
+     400             :   // Add reference atom derivatives
+     401        1560 :   dfd[0]=uder2*vcontr*wcontr; dfd[1]=ucontr*vder2*wcontr; dfd[2]=ucontr*vcontr*wder2;
+     402        1560 :   Vector dfld; dfld[0]=udlen*vcontr*wcontr; dfld[1]=ucontr*vdlen*wcontr; dfld[2]=ucontr*vcontr*wdlen;
+     403        1560 :   rderiv[0] = dfd[0]*matmul(datom,dbi[0]) + dfd[1]*matmul(datom,dcross[0]) + dfd[2]*matmul(datom,dperp[0]) +
+     404        3120 :               dfld[0]*dlbi[0] + dfld[1]*dlcross[0] + dfld[2]*dlperp[0] - derivatives;
+     405        1560 :   rderiv[1] = dfd[0]*matmul(datom,dbi[1]) + dfd[1]*matmul(datom,dcross[1]) + dfd[2]*matmul(datom,dperp[1]) +
+     406        3120 :               dfld[0]*dlbi[1] + dfld[1]*dlcross[1] + dfld[2]*dlperp[1];
+     407        1560 :   rderiv[2] = dfd[0]*matmul(datom,dbi[2]) + dfd[1]*matmul(datom,dcross[2]) + dfd[2]*matmul(datom,dperp[2]) +
+     408        3120 :               dfld[0]*dlbi[2] + dfld[1]*dlcross[2] + dfld[2]*dlperp[2];
+     409        1560 :   rderiv[3] = dfld[0]*dlbi[3] + dfld[1]*dlcross[3] + dfld[2]*dlperp[3];
+     410             : 
+     411        1560 :   vir.zero(); vir-=Tensor( cpos,derivatives );
+     412        7800 :   for(unsigned i=0; i<4; ++i) {
+     413        6240 :     vir -= Tensor( getPosition(i), rderiv[i] );
+     414             :   }
+     415             : 
+     416        1560 :   return tot;
+     417             : }
+     418             : 
+     419             : }
+     420             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/volumes/VolumeInCylinder.cpp.func-sort-c.html b/coverage/volumes/VolumeInCylinder.cpp.func-sort-c.html new file mode 100644 index 000000000000..b1eecfc90959 --- /dev/null +++ b/coverage/volumes/VolumeInCylinder.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - volumes/VolumeInCylinder.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - volumes - VolumeInCylinder.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:464895.8 %
Date:2024-04-19 12:12:35Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7volumes16VolumeInCylinderC2ERKNS_13ActionOptionsE0
_ZN4PLMD7volumes16VolumeInCylinderC1ERKNS_13ActionOptionsE1
_ZN4PLMD7volumes16VolumeInCylinder16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD7volumes16VolumeInCylinder12setupRegionsEv20
_ZNK4PLMD7volumes16VolumeInCylinder21calculateNumberInsideERKNS_13VectorGenericILj3EEERS3_RNS_13TensorGenericILj3ELj3EEERSt6vectorIS3_SaIS3_EE4667
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/volumes/VolumeInCylinder.cpp.func.html b/coverage/volumes/VolumeInCylinder.cpp.func.html new file mode 100644 index 000000000000..d1fc380951d9 --- /dev/null +++ b/coverage/volumes/VolumeInCylinder.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - volumes/VolumeInCylinder.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - volumes - VolumeInCylinder.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:464895.8 %
Date:2024-04-19 12:12:35Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7volumes16VolumeInCylinder12setupRegionsEv20
_ZN4PLMD7volumes16VolumeInCylinder16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD7volumes16VolumeInCylinderC1ERKNS_13ActionOptionsE1
_ZN4PLMD7volumes16VolumeInCylinderC2ERKNS_13ActionOptionsE0
_ZNK4PLMD7volumes16VolumeInCylinder21calculateNumberInsideERKNS_13VectorGenericILj3EEERS3_RNS_13TensorGenericILj3ELj3EEERSt6vectorIS3_SaIS3_EE4667
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/volumes/VolumeInCylinder.cpp.gcov.html b/coverage/volumes/VolumeInCylinder.cpp.gcov.html new file mode 100644 index 000000000000..84f55c4c7607 --- /dev/null +++ b/coverage/volumes/VolumeInCylinder.cpp.gcov.html @@ -0,0 +1,250 @@ + + + + + + + + LCOV - plumed test coverage - volumes/VolumeInCylinder.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - volumes - VolumeInCylinder.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:464895.8 %
Date:2024-04-19 12:12:35Functions:4580.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2020 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received 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             : #include "VolumeShortcut.h"
+      27             : 
+      28             : //+PLUMEDOC VOLUMES INCYLINDER
+      29             : /*
+      30             : 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.
+      31             : 
+      32             : Each of the base quantities calculated by a multicolvar can can be assigned to a particular point in three
+      33             : dimensional space. For example, if we have the coordination numbers for all the atoms in the
+      34             : system each coordination number can be assumed to lie on the position of the central atom.
+      35             : Because each base quantity can be assigned to a particular point in space we can calculate functions of the
+      36             : distribution of base quantities in a particular part of the box by using:
+      37             : 
+      38             : \f[
+      39             : \overline{s}_{\tau} = \frac{ \sum_i f(s_i) \sigma(r_{xy}) }{ \sum_i \sigma(r_{xy}) }
+      40             : \f]
+      41             : 
+      42             : 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$.
+      43             : The function \f$\sigma\f$ is a \ref switchingfunction that acts on the distance between the point at which the
+      44             : collective is located \f$(x_i,y_i,z_i)\f$ and the position of the atom that was specified using the ORIGIN keyword
+      45             : projected in the xy plane if DIRECTION=z is used.  In other words:
+      46             : \f[
+      47             : r_{xy} = sqrt{ ( x_i - x_0)^2 + ( y_i - y_0)^2 }
+      48             : \f]
+      49             : In short this function, \f$\sigma(r_{xy})\f$, measures whether or not the CV is within a cylinder that
+      50             : runs along the axis specified using the DIRECTION keyword and that is centered on the position of the atom specified using
+      51             : ORIGIN.
+      52             : 
+      53             : 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.
+      54             : 
+      55             : When INCYLINDER is used with the \ref DENSITY action the number of atoms in the specified region is calculated
+      56             : 
+      57             : \par Examples
+      58             : 
+      59             : The input below can be use to calculate the average coordination numbers for those atoms that are within a cylindrical tube
+      60             : 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.
+      61             : 
+      62             : \plumedfile
+      63             : c1: COORDINATIONNUMBER SPECIES=1-100 SWITCH={RATIONAL R_0=0.1}
+      64             : d2: INCYLINDER ATOM=101 DATA=c1 DIRECTION=Z RADIUS={TANH R_0=1.5} SIGMA=0.1 LOWER=-0.1 UPPER=0.1 MEAN
+      65             : PRINT ARG=d2.* FILE=colvar
+      66             : \endplumedfile
+      67             : 
+      68             : */
+      69             : //+ENDPLUMEDOC
+      70             : 
+      71             : //+PLUMEDOC MCOLVAR INCYLINDER_CALC
+      72             : /*
+      73             : Calculate a vector from the input positions with elements equal to one when the positions are in a particular part of the cell and elements equal to zero otherwise
+      74             : 
+      75             : \par Examples
+      76             : 
+      77             : */
+      78             : //+ENDPLUMEDOC
+      79             : 
+      80             : namespace PLMD {
+      81             : namespace volumes {
+      82             : 
+      83             : class VolumeInCylinder : public ActionVolume {
+      84             : private:
+      85             :   bool docylinder;
+      86             :   Vector origin;
+      87             :   HistogramBead bead;
+      88             :   std::vector<unsigned> dir;
+      89             :   SwitchingFunction switchingFunction;
+      90             : public:
+      91             :   static void registerKeywords( Keywords& keys );
+      92             :   explicit VolumeInCylinder (const ActionOptions& ao);
+      93             :   void setupRegions() override;
+      94             :   double calculateNumberInside( const Vector& cpos, Vector& derivatives, Tensor& vir, std::vector<Vector>& refders ) const override;
+      95             : };
+      96             : 
+      97             : PLUMED_REGISTER_ACTION(VolumeInCylinder,"INCYLINDER_CALC")
+      98             : char glob_cylinder[] = "INCYLINDER";
+      99             : typedef VolumeShortcut<glob_cylinder> VolumeInCylinderShortcut;
+     100             : PLUMED_REGISTER_ACTION(VolumeInCylinderShortcut,"INCYLINDER")
+     101             : 
+     102           6 : void VolumeInCylinder::registerKeywords( Keywords& keys ) {
+     103           6 :   ActionVolume::registerKeywords( keys );
+     104          12 :   keys.add("atoms","CENTER","the atom whose vicinity we are interested in examining");
+     105          12 :   keys.add("compulsory","DIRECTION","the direction of the long axis of the cylinder. Must be x, y or z");
+     106          12 :   keys.add("compulsory","RADIUS","a switching function that gives the extent of the cylinder in the plane perpendicular to the direction");
+     107          12 :   keys.add("compulsory","LOWER","0.0","the lower boundary on the direction parallel to the long axis of the cylinder");
+     108          12 :   keys.add("compulsory","UPPER","0.0","the upper boundary on the direction parallel to the long axis of the cylinder");
+     109          12 :   keys.reset_style("SIGMA","optional");
+     110           6 : }
+     111             : 
+     112           1 : VolumeInCylinder::VolumeInCylinder(const ActionOptions& ao):
+     113             :   Action(ao),
+     114             :   ActionVolume(ao),
+     115           1 :   docylinder(false)
+     116             : {
+     117             :   std::vector<AtomNumber> atom;
+     118           2 :   parseAtomList("CENTER",atom);
+     119           1 :   if( atom.size()!=1 ) error("should only be one atom specified");
+     120           1 :   log.printf("  center of cylinder is at position of atom : %d\n",atom[0].serial() );
+     121             : 
+     122           2 :   std::string sdir; parse("DIRECTION",sdir);
+     123           1 :   if( sdir=="X") {dir.push_back(1); dir.push_back(2); dir.push_back(0); }
+     124           1 :   else if( sdir=="Y") {dir.push_back(0); dir.push_back(2); dir.push_back(1); }
+     125           1 :   else if( sdir=="Z") {dir.push_back(0); dir.push_back(1); dir.push_back(2); }
+     126           0 :   else { error(sdir + "is not a valid direction.  Should be X, Y or Z"); }
+     127           1 :   log.printf("  cylinder's long axis is along %s axis\n",sdir.c_str() );
+     128             : 
+     129           2 :   std::string sw, errors; parse("RADIUS",sw);
+     130           1 :   if(sw.length()==0) error("missing RADIUS keyword");
+     131           1 :   switchingFunction.set(sw,errors);
+     132           1 :   if( errors.length()!=0 ) error("problem reading RADIUS keyword : " + errors );
+     133           1 :   log.printf("  radius of cylinder is given by %s \n", ( switchingFunction.description() ).c_str() );
+     134             : 
+     135           2 :   double min, max; parse("LOWER",min); parse("UPPER",max);
+     136           1 :   if( min!=0.0 ||  max!=0.0 ) {
+     137           1 :     if( min>max ) error("minimum of cylinder should be less than maximum");
+     138           1 :     docylinder=true;
+     139           1 :     log.printf("  cylinder extends from %f to %f along the %s axis\n",min,max,sdir.c_str() );
+     140           2 :     bead.isNotPeriodic(); bead.setKernelType( getKernelType() ); bead.set( min, max, getSigma() );
+     141             :   }
+     142             : 
+     143           1 :   checkRead(); requestAtoms(atom);
+     144           1 : }
+     145             : 
+     146          20 : void VolumeInCylinder::setupRegions() { }
+     147             : 
+     148        4667 : double VolumeInCylinder::calculateNumberInside( const Vector& cpos, Vector& derivatives, Tensor& vir, std::vector<Vector>& refders ) const {
+     149             :   // Calculate position of atom wrt to origin
+     150        4667 :   Vector fpos=pbcDistance( getPosition(0), cpos );
+     151             : 
+     152             :   double vcylinder, dcylinder;
+     153        4667 :   if( docylinder ) {
+     154        4667 :     vcylinder=bead.calculate( fpos[dir[2]], dcylinder );
+     155             :   } else {
+     156           0 :     vcylinder=1.0; dcylinder=0.0;
+     157             :   }
+     158             : 
+     159        4667 :   const double dd = fpos[dir[0]]*fpos[dir[0]] + fpos[dir[1]]*fpos[dir[1]];
+     160        4667 :   double dfunc, vswitch = switchingFunction.calculateSqr( dd, dfunc );
+     161        4667 :   derivatives.zero(); double value=vswitch*vcylinder;
+     162        4667 :   derivatives[dir[0]]=vcylinder*dfunc*fpos[dir[0]];
+     163        4667 :   derivatives[dir[1]]=vcylinder*dfunc*fpos[dir[1]];
+     164        4667 :   derivatives[dir[2]]=vswitch*dcylinder;
+     165             :   // Add derivatives wrt to position of origin atom
+     166        4667 :   refders[0] = -derivatives;
+     167             :   // Add virial contribution
+     168        4667 :   vir -= Tensor(fpos,derivatives);
+     169        4667 :   return value;
+     170             : }
+     171             : 
+     172             : }
+     173             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/volumes/VolumeInSphere.cpp.func-sort-c.html b/coverage/volumes/VolumeInSphere.cpp.func-sort-c.html new file mode 100644 index 000000000000..2e1c29907d1f --- /dev/null +++ b/coverage/volumes/VolumeInSphere.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - volumes/VolumeInSphere.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - volumes - VolumeInSphere.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2727100.0 %
Date:2024-04-19 12:12:35Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7volumes14VolumeInSphereC2ERKNS_13ActionOptionsE0
_ZN4PLMD7volumes14VolumeInSphereC1ERKNS_13ActionOptionsE10
_ZN4PLMD7volumes14VolumeInSphere16registerKeywordsERNS_8KeywordsE26
_ZN4PLMD7volumes14VolumeInSphere12setupRegionsEv120
_ZNK4PLMD7volumes14VolumeInSphere21calculateNumberInsideERKNS_13VectorGenericILj3EEERS3_RNS_13TensorGenericILj3ELj3EEERSt6vectorIS3_SaIS3_EE423194
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/volumes/VolumeInSphere.cpp.func.html b/coverage/volumes/VolumeInSphere.cpp.func.html new file mode 100644 index 000000000000..bfd79bdb172e --- /dev/null +++ b/coverage/volumes/VolumeInSphere.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - volumes/VolumeInSphere.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - volumes - VolumeInSphere.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2727100.0 %
Date:2024-04-19 12:12:35Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7volumes14VolumeInSphere12setupRegionsEv120
_ZN4PLMD7volumes14VolumeInSphere16registerKeywordsERNS_8KeywordsE26
_ZN4PLMD7volumes14VolumeInSphereC1ERKNS_13ActionOptionsE10
_ZN4PLMD7volumes14VolumeInSphereC2ERKNS_13ActionOptionsE0
_ZNK4PLMD7volumes14VolumeInSphere21calculateNumberInsideERKNS_13VectorGenericILj3EEERS3_RNS_13TensorGenericILj3ELj3EEERSt6vectorIS3_SaIS3_EE423194
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/volumes/VolumeInSphere.cpp.gcov.html b/coverage/volumes/VolumeInSphere.cpp.gcov.html new file mode 100644 index 000000000000..2bb93979f4a2 --- /dev/null +++ b/coverage/volumes/VolumeInSphere.cpp.gcov.html @@ -0,0 +1,214 @@ + + + + + + + + LCOV - plumed test coverage - volumes/VolumeInSphere.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - volumes - VolumeInSphere.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2727100.0 %
Date:2024-04-19 12:12:35Functions:4580.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2020 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received 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             : #include "VolumeShortcut.h"
+      27             : 
+      28             : //+PLUMEDOC VOLUMES INSPHERE
+      29             : /*
+      30             : 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.
+      31             : 
+      32             : Each of the base quantities calculated by a multicolvar can can be assigned to a particular point in three
+      33             : dimensional space. For example, if we have the coordination numbers for all the atoms in the
+      34             : system each coordination number can be assumed to lie on the position of the central atom.
+      35             : Because each base quantity can be assigned to a particular point in space we can calculate functions of the
+      36             : distribution of base quantities in a particular part of the box by using:
+      37             : 
+      38             : \f[
+      39             : \overline{s}_{\tau} = \frac{ \sum_i f(s_i) \sigma(r) }{ \sum_i \sigma(r) }
+      40             : \f]
+      41             : 
+      42             : 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$.
+      43             : The function \f$\sigma\f$ is a \ref switchingfunction that acts on the distance between the point at which the
+      44             : collective is located \f$(x_i,y_i,z_i)\f$ and the position of the atom that was specified using the ORIGIN keyword.
+      45             : In other words:
+      46             : \f[
+      47             : r = sqrt{ ( x_i - x_0)^2 + ( y_i - y_0)^2 + ( z_i - z_0)^2}
+      48             : \f]
+      49             : In short this function, \f$\sigma(r_{xy})\f$, measures whether or not the CV is within a sphere that is
+      50             : centered on the position of the atom specified using the keyword 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 sphere
+      59             : of radius 1.5 nm that is centered on the position of atom 101.
+      60             : 
+      61             : \plumedfile
+      62             : c1: COORDINATIONNUMBER SPECIES=1-100 SWITCH={RATIONAL R_0=0.1}
+      63             : d2: INSPHERE ATOM=101 DATA=c1 RADIUS={TANH R_0=1.5} MEAN
+      64             : PRINT ARG=d2.* FILE=colvar
+      65             : \endplumedfile
+      66             : 
+      67             : */
+      68             : //+ENDPLUMEDOC
+      69             : 
+      70             : //+PLUMEDOC MCOLVAR INSPHERE_CALC
+      71             : /*
+      72             : Calculate a vector from the input positions with elements equal to one when the positions are in a particular part of the cell and elements equal to zero otherwise
+      73             : 
+      74             : \par Examples
+      75             : 
+      76             : */
+      77             : //+ENDPLUMEDOC
+      78             : 
+      79             : namespace PLMD {
+      80             : namespace volumes {
+      81             : 
+      82             : class VolumeInSphere : public ActionVolume {
+      83             : private:
+      84             :   Vector origin;
+      85             :   SwitchingFunction switchingFunction;
+      86             : public:
+      87             :   static void registerKeywords( Keywords& keys );
+      88             :   explicit VolumeInSphere(const ActionOptions& ao);
+      89             :   void setupRegions() override;
+      90             :   double calculateNumberInside( const Vector& cpos, Vector& derivatives, Tensor& vir, std::vector<Vector>& refders ) const override;
+      91             : };
+      92             : 
+      93             : PLUMED_REGISTER_ACTION(VolumeInSphere,"INSPHERE_CALC")
+      94             : char glob_sphere[] = "INSPHERE";
+      95             : typedef VolumeShortcut<glob_sphere> VolumeInSphereShortcut;
+      96             : PLUMED_REGISTER_ACTION(VolumeInSphereShortcut,"INSPHERE")
+      97             : 
+      98          26 : void VolumeInSphere::registerKeywords( Keywords& keys ) {
+      99          26 :   ActionVolume::registerKeywords( keys );
+     100          52 :   keys.add("atoms","CENTER","the atom whose vicinity we are interested in examining");
+     101          52 :   keys.add("atoms-2","ATOM","the atom whose vicinity we are interested in examining");
+     102          52 :   keys.add("compulsory","RADIUS","the switching function that tells us the extent of the sphereical region of interest");
+     103          26 :   keys.remove("SIGMA");
+     104          26 : }
+     105             : 
+     106          10 : VolumeInSphere::VolumeInSphere(const ActionOptions& ao):
+     107             :   Action(ao),
+     108          10 :   ActionVolume(ao)
+     109             : {
+     110          20 :   std::vector<AtomNumber> atom; parseAtomList("CENTER",atom);
+     111          10 :   if( atom.size()==0 ) parseAtomList("ATOM",atom);
+     112          10 :   if( atom.size()!=1 ) error("should only be one atom specified");
+     113          10 :   log.printf("  center of sphere is at position of atom : %d\n",atom[0].serial() );
+     114             : 
+     115          20 :   std::string sw, errors; parse("RADIUS",sw);
+     116          10 :   if(sw.length()==0) error("missing RADIUS keyword");
+     117          10 :   switchingFunction.set(sw,errors);
+     118          10 :   if( errors.length()!=0 ) error("problem reading RADIUS keyword : " + errors );
+     119          10 :   log.printf("  radius of sphere is given by %s \n", ( switchingFunction.description() ).c_str() );
+     120             : 
+     121          10 :   checkRead(); requestAtoms(atom);
+     122          10 : }
+     123             : 
+     124         120 : void VolumeInSphere::setupRegions() { }
+     125             : 
+     126      423194 : double VolumeInSphere::calculateNumberInside( const Vector& cpos, Vector& derivatives, Tensor& vir, std::vector<Vector>& refders ) const {
+     127             :   // Calculate position of atom wrt to origin
+     128      423194 :   Vector fpos=pbcDistance( getPosition(0), cpos );
+     129      423194 :   double dfunc, value = switchingFunction.calculateSqr( fpos.modulo2(), dfunc );
+     130      423194 :   derivatives.zero(); derivatives = dfunc*fpos; refders[0] = -derivatives;
+     131             :   // Add a virial contribution
+     132      423194 :   vir -= Tensor(fpos,derivatives);
+     133      423194 :   return value;
+     134             : }
+     135             : 
+     136             : }
+     137             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/volumes/VolumeShortcut.h.func-sort-c.html b/coverage/volumes/VolumeShortcut.h.func-sort-c.html new file mode 100644 index 000000000000..e31fa3062f1e --- /dev/null +++ b/coverage/volumes/VolumeShortcut.h.func-sort-c.html @@ -0,0 +1,121 @@ + + + + + + + + LCOV - plumed test coverage - volumes/VolumeShortcut.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - volumes - VolumeShortcut.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:475388.7 %
Date:2024-04-19 12:12:35Functions:111291.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7volumes14VolumeShortcutIXadL_ZNS0_14glob_tetraporeEEEEC1ERKNS_13ActionOptionsE0
_ZN4PLMD7volumes14VolumeShortcutIXadL_ZNS0_11glob_cavityEEEEC1ERKNS_13ActionOptionsE1
_ZN4PLMD7volumes14VolumeShortcutIXadL_ZNS0_13glob_contoursEEEEC1ERKNS_13ActionOptionsE1
_ZN4PLMD7volumes14VolumeShortcutIXadL_ZNS0_13glob_cylinderEEEEC1ERKNS_13ActionOptionsE1
_ZN4PLMD7volumes14VolumeShortcutIXadL_ZNS0_14glob_tetraporeEEEE16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD7volumes14VolumeShortcutIXadL_ZNS0_11glob_cavityEEEE16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD7volumes14VolumeShortcutIXadL_ZNS0_13glob_contoursEEEE16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD7volumes14VolumeShortcutIXadL_ZNS0_13glob_cylinderEEEE16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD7volumes14VolumeShortcutIXadL_ZNS0_11glob_sphereEEEEC1ERKNS_13ActionOptionsE10
_ZN4PLMD7volumes14VolumeShortcutIXadL_ZNS0_11glob_sphereEEEE16registerKeywordsERNS_8KeywordsE14
_ZN4PLMD7volumes14VolumeShortcutIXadL_ZNS0_11glob_aroundEEEEC1ERKNS_13ActionOptionsE46
_ZN4PLMD7volumes14VolumeShortcutIXadL_ZNS0_11glob_aroundEEEE16registerKeywordsERNS_8KeywordsE62
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/volumes/VolumeShortcut.h.func.html b/coverage/volumes/VolumeShortcut.h.func.html new file mode 100644 index 000000000000..5dbe87159ecb --- /dev/null +++ b/coverage/volumes/VolumeShortcut.h.func.html @@ -0,0 +1,121 @@ + + + + + + + + LCOV - plumed test coverage - volumes/VolumeShortcut.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - volumes - VolumeShortcut.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:475388.7 %
Date:2024-04-19 12:12:35Functions:111291.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7volumes14VolumeShortcutIXadL_ZNS0_11glob_aroundEEEE16registerKeywordsERNS_8KeywordsE62
_ZN4PLMD7volumes14VolumeShortcutIXadL_ZNS0_11glob_aroundEEEEC1ERKNS_13ActionOptionsE46
_ZN4PLMD7volumes14VolumeShortcutIXadL_ZNS0_11glob_cavityEEEE16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD7volumes14VolumeShortcutIXadL_ZNS0_11glob_cavityEEEEC1ERKNS_13ActionOptionsE1
_ZN4PLMD7volumes14VolumeShortcutIXadL_ZNS0_11glob_sphereEEEE16registerKeywordsERNS_8KeywordsE14
_ZN4PLMD7volumes14VolumeShortcutIXadL_ZNS0_11glob_sphereEEEEC1ERKNS_13ActionOptionsE10
_ZN4PLMD7volumes14VolumeShortcutIXadL_ZNS0_13glob_contoursEEEE16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD7volumes14VolumeShortcutIXadL_ZNS0_13glob_contoursEEEEC1ERKNS_13ActionOptionsE1
_ZN4PLMD7volumes14VolumeShortcutIXadL_ZNS0_13glob_cylinderEEEE16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD7volumes14VolumeShortcutIXadL_ZNS0_13glob_cylinderEEEEC1ERKNS_13ActionOptionsE1
_ZN4PLMD7volumes14VolumeShortcutIXadL_ZNS0_14glob_tetraporeEEEE16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD7volumes14VolumeShortcutIXadL_ZNS0_14glob_tetraporeEEEEC1ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/volumes/VolumeShortcut.h.gcov.html b/coverage/volumes/VolumeShortcut.h.gcov.html new file mode 100644 index 000000000000..1f14840ae455 --- /dev/null +++ b/coverage/volumes/VolumeShortcut.h.gcov.html @@ -0,0 +1,199 @@ + + + + + + + + LCOV - plumed test coverage - volumes/VolumeShortcut.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - volumes - VolumeShortcut.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:475388.7 %
Date:2024-04-19 12:12:35Functions:111291.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2017 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_volumes_VolumeShortcut_h
+      23             : #define __PLUMED_volumes_VolumeShortcut_h
+      24             : 
+      25             : #include "core/ActionShortcut.h"
+      26             : #include "core/ActionRegister.h"
+      27             : #include "core/PlumedMain.h"
+      28             : #include "core/ActionSet.h"
+      29             : #include "core/Group.h"
+      30             : 
+      31             : namespace PLMD {
+      32             : namespace volumes {
+      33             : 
+      34             : template <const char* v>
+      35             : class VolumeShortcut : public ActionShortcut {
+      36             : public:
+      37             :   static void registerKeywords( Keywords& keys );
+      38             :   VolumeShortcut(const ActionOptions&ao);
+      39             : };
+      40             : 
+      41             : template <const char* v>
+      42          87 : void VolumeShortcut<v>::registerKeywords( Keywords& keys ) {
+      43         174 :   actionRegister().getKeywords( std::string(v) + "_CALC", keys );
+      44         174 :   keys.add("hidden","IS_SHORTCUT","hidden keyword to tell if actions are shortcuts so that example generator can provide expansions of shortcuts");
+      45         174 :   keys.add("optional","DATA","the label of an action that calculates multicolvars.  Weighted sums based on the location of the colvars calculated by this action will be calcualted");
+      46         174 :   keys.add("optional","LESS_THAN","calcualte the number of colvars that are inside the region of interest and that are less than a certain threshold");
+      47         174 :   keys.addOutputComponent("lessthan","LESS_THAN","the number of cvs in the region of interest that are less than a certain threshold");
+      48         174 :   keys.add("optional","MORE_THAN","calcualte the number of colvars that are inside the region of interest and that are greater that a certain threshold");
+      49         174 :   keys.addOutputComponent("morethan","MORE_THAN","the number of cvs in the region of interest that are more than a certain threshold");
+      50         174 :   keys.add("optional","BETWEEN","calculate the number of colvars that are inside the region of interest and that have a CV value that is between a particular set of bounds");
+      51         174 :   keys.addOutputComponent("between","BETWEEN","the number of cvs in the region of interest that are within a certain range");
+      52         174 :   keys.addFlag("SUM",false,"calculate the sum of all the quantities.");
+      53         174 :   keys.addOutputComponent("sum","SUM","the sum of all the colvars weighted by the function that determines if we are in the region");
+      54         174 :   keys.addFlag("MEAN",false,"calculate the average value of the colvar inside the region of interest");
+      55         174 :   keys.addOutputComponent("mean","MEAN","the average values of the colvar in the region of interest");
+      56         348 :   keys.addActionNameSuffix("_CALC"); keys.needsAction("LESS_THAN"); keys.needsAction("MORE_THAN"); keys.needsAction("GROUP");
+      57         348 :   keys.needsAction("BETWEEN"); keys.needsAction("SUM"); keys.needsAction("MEAN"); keys.needsAction("CUSTOM");
+      58          87 : }
+      59             : 
+      60             : template <const char* v>
+      61          59 : VolumeShortcut<v>::VolumeShortcut(const ActionOptions&ao):
+      62             :   Action(ao),
+      63          59 :   ActionShortcut(ao)
+      64             : {
+      65         177 :   std::string voltype(v), mc_lab; parse("DATA",mc_lab); bool dosum; parseFlag("SUM",dosum);
+      66          59 :   if( mc_lab.length()>0 ) {
+      67          12 :     Group* mygrp = plumed.getActionSet().template selectWithLabel<Group*>(mc_lab);
+      68          12 :     Group* mygrp2 = plumed.getActionSet().template selectWithLabel<Group*>(mc_lab + "_grp");
+      69          22 :     if( mygrp || mygrp2 ) readInputLine( getShortcutLabel() + "_grp: GROUP ATOMS=" + mc_lab );
+      70          24 :     bool domean; parseFlag("MEAN",domean); std::string lt_input, mt_input, bt_input;
+      71          48 :     parse("LESS_THAN",lt_input); parse("MORE_THAN",mt_input); parse("BETWEEN",bt_input);
+      72          24 :     std::string atomsd; parse("ATOMS",atomsd); if( atomsd.length()==0 ) atomsd=mc_lab;
+      73             :     // Create the apprpriate volume object
+      74          24 :     readInputLine( getShortcutLabel() + ": " + voltype + "_CALC " + convertInputLineToString() + " ATOMS=" + atomsd );
+      75             :     // Now create input for sums
+      76          12 :     if( dosum || domean ) {
+      77          24 :       readInputLine( getShortcutLabel() + "_prod: CUSTOM ARG=" + mc_lab + "," + getShortcutLabel() + " FUNC=x*y PERIODIC=NO");
+      78          12 :       std::string tlab = getShortcutLabel() + "_numer"; if( dosum ) tlab = getShortcutLabel() + "_sum:";
+      79          24 :       readInputLine( tlab + ": SUM ARG=" + getShortcutLabel() + "_prod PERIODIC=NO");
+      80             :     }
+      81          12 :     if( domean ) {
+      82             :       // Calculate denominator
+      83          24 :       readInputLine( getShortcutLabel() + "_norm: SUM ARG=" + getShortcutLabel() + " PERIODIC=NO");
+      84             :       // And calculate final quantity which is mean of these two actions
+      85          12 :       std::string arg1_lab = getShortcutLabel() + "_numer"; if( dosum ) arg1_lab = getShortcutLabel()  + "_sum";
+      86          24 :       readInputLine( getShortcutLabel() + "_mean: CUSTOM ARG=" + arg1_lab + "," + getShortcutLabel() + "_norm FUNC=x/y PERIODIC=NO");
+      87             :     }
+      88          12 :     if( lt_input.length()>0 ) {
+      89             :       // Calculate number less than
+      90          14 :       readInputLine( mc_lab + "_" + getShortcutLabel() + "_lt: LESS_THAN ARG=" + mc_lab + " SWITCH={" + lt_input +"}");
+      91             :       // And the matheval bit
+      92          14 :       readInputLine( getShortcutLabel() + "_lt: CUSTOM ARG=" + mc_lab + "_" + getShortcutLabel() + "_lt," + getShortcutLabel() + " FUNC=x*y PERIODIC=NO");
+      93             :       // And the final sum
+      94          14 :       readInputLine( getShortcutLabel() + "_lessthan: SUM ARG=" + getShortcutLabel() + "_lt PERIODIC=NO");
+      95             :     }
+      96          12 :     if( mt_input.length()>0 ) {
+      97             :       // Calculate number less than
+      98           0 :       readInputLine( mc_lab + "_" + getShortcutLabel() + "_mt: MORE_THAN ARG=" + mc_lab + " SWITCH={" + mt_input  + "}");
+      99             :       // And the matheval bit
+     100           0 :       readInputLine( getShortcutLabel() + "_mt: CUSTOM ARG=" + mc_lab + "_" + getShortcutLabel() + "_mt," + getShortcutLabel() + " FUNC=x*y PERIODIC=NO");
+     101             :       // And the final sum
+     102           0 :       readInputLine( getShortcutLabel() + "_morethan: SUM ARG=" + getShortcutLabel() + "_mt PERIODIC=NO");
+     103             :     }
+     104          12 :     if( bt_input.length()>0 ) {
+     105             :       // Calculate number less than
+     106           0 :       readInputLine( mc_lab + "_" + getShortcutLabel() + "_bt: BETWEEN ARG=" + mc_lab + " SWITCH={" + bt_input +"}");
+     107             :       // And the matheval bit
+     108           0 :       readInputLine( getShortcutLabel() + "_bt: CUSTOM ARG=" + mc_lab + "_" + getShortcutLabel() + "_bt," + getShortcutLabel() + " FUNC=x*y PERIODIC=NO");
+     109             :       // And the final sum
+     110           0 :       readInputLine( getShortcutLabel() + "_between: SUM ARG=" + getShortcutLabel() + "_bt PERIODIC=NO");
+     111             :     }
+     112          47 :   } else if( dosum ) {
+     113          20 :     readInputLine( getShortcutLabel() + "_vols: " + voltype + "_CALC " + convertInputLineToString() );
+     114          20 :     readInputLine( getShortcutLabel() + ": SUM ARG=" + getShortcutLabel() + "_vols PERIODIC=NO");
+     115             :   } else {
+     116          74 :     readInputLine( getShortcutLabel() + ": " + voltype + "_CALC " + convertInputLineToString() );
+     117             :   }
+     118          59 : }
+     119             : 
+     120             : }
+     121             : }
+     122             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/volumes/VolumeTetrapore.cpp.func-sort-c.html b/coverage/volumes/VolumeTetrapore.cpp.func-sort-c.html new file mode 100644 index 000000000000..4f2a889a9f7f --- /dev/null +++ b/coverage/volumes/VolumeTetrapore.cpp.func-sort-c.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - volumes/VolumeTetrapore.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - volumes - VolumeTetrapore.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:72303.0 %
Date:2024-04-19 12:12:35Functions:1911.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7volumes15VolumeTetrapore12setupRegionsEv0
_ZN4PLMD7volumes15VolumeTetrapore6updateEv0
_ZN4PLMD7volumes15VolumeTetraporeC1ERKNS_13ActionOptionsE0
_ZN4PLMD7volumes15VolumeTetraporeC2ERKNS_13ActionOptionsE0
_ZN4PLMD7volumes15VolumeTetraporeD0Ev0
_ZN4PLMD7volumes15VolumeTetraporeD1Ev0
_ZN4PLMD7volumes15VolumeTetraporeD2Ev0
_ZNK4PLMD7volumes15VolumeTetrapore21calculateNumberInsideERKNS_13VectorGenericILj3EEERS3_RNS_13TensorGenericILj3ELj3EEERSt6vectorIS3_SaIS3_EE0
_ZN4PLMD7volumes15VolumeTetrapore16registerKeywordsERNS_8KeywordsE4
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/volumes/VolumeTetrapore.cpp.func.html b/coverage/volumes/VolumeTetrapore.cpp.func.html new file mode 100644 index 000000000000..b04c2e1a666d --- /dev/null +++ b/coverage/volumes/VolumeTetrapore.cpp.func.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - volumes/VolumeTetrapore.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - volumes - VolumeTetrapore.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:72303.0 %
Date:2024-04-19 12:12:35Functions:1911.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7volumes15VolumeTetrapore12setupRegionsEv0
_ZN4PLMD7volumes15VolumeTetrapore16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD7volumes15VolumeTetrapore6updateEv0
_ZN4PLMD7volumes15VolumeTetraporeC1ERKNS_13ActionOptionsE0
_ZN4PLMD7volumes15VolumeTetraporeC2ERKNS_13ActionOptionsE0
_ZN4PLMD7volumes15VolumeTetraporeD0Ev0
_ZN4PLMD7volumes15VolumeTetraporeD1Ev0
_ZN4PLMD7volumes15VolumeTetraporeD2Ev0
_ZNK4PLMD7volumes15VolumeTetrapore21calculateNumberInsideERKNS_13VectorGenericILj3EEERS3_RNS_13TensorGenericILj3ELj3EEERSt6vectorIS3_SaIS3_EE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/volumes/VolumeTetrapore.cpp.gcov.html b/coverage/volumes/VolumeTetrapore.cpp.gcov.html new file mode 100644 index 000000000000..eb23f456a382 --- /dev/null +++ b/coverage/volumes/VolumeTetrapore.cpp.gcov.html @@ -0,0 +1,534 @@ + + + + + + + + LCOV - plumed test coverage - volumes/VolumeTetrapore.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - volumes - VolumeTetrapore.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:72303.0 %
Date:2024-04-19 12:12:35Functions:1911.1 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2020 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received 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 "tools/Units.h"
+      25             : #include "tools/Pbc.h"
+      26             : #include "ActionVolume.h"
+      27             : #include "VolumeShortcut.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             : //+PLUMEDOC MCOLVAR TETRAHEDRALPORE_CALC
+     114             : /*
+     115             : Calculate a vector from the input positions with elements equal to one when the positions are in a particular part of the cell and elements equal to zero otherwise
+     116             : 
+     117             : \par Examples
+     118             : 
+     119             : */
+     120             : //+ENDPLUMEDOC
+     121             : 
+     122             : namespace PLMD {
+     123             : namespace volumes {
+     124             : 
+     125             : class VolumeTetrapore : public ActionVolume {
+     126             : private:
+     127             :   bool boxout;
+     128             :   OFile boxfile;
+     129             :   double lenunit;
+     130             :   double jacob_det;
+     131             :   double len_bi, len_cross, len_perp, sigma;
+     132             :   Vector origin, bi, cross, perp;
+     133             :   std::vector<Vector> dlbi, dlcross, dlperp;
+     134             :   std::vector<Tensor> dbi, dcross, dperp;
+     135             : public:
+     136             :   static void registerKeywords( Keywords& keys );
+     137             :   explicit VolumeTetrapore(const ActionOptions& ao);
+     138             :   ~VolumeTetrapore();
+     139             :   void setupRegions() override;
+     140             :   void update() override;
+     141             :   double calculateNumberInside( const Vector& cpos, Vector& derivatives, Tensor& vir, std::vector<Vector>& refders ) const override;
+     142             : };
+     143             : 
+     144             : PLUMED_REGISTER_ACTION(VolumeTetrapore,"TETRAHEDRALPORE_CALC")
+     145             : char glob_tetrapore[] = "TETRAHEDRALPORE";
+     146             : typedef VolumeShortcut<glob_tetrapore> VolumeTetraporeShortcut;
+     147             : PLUMED_REGISTER_ACTION(VolumeTetraporeShortcut,"TETRAHEDRALPORE")
+     148             : 
+     149           4 : void VolumeTetrapore::registerKeywords( Keywords& keys ) {
+     150           4 :   ActionVolume::registerKeywords( keys );
+     151           8 :   keys.add("atoms","BOX","the positions of four atoms that define spatial extent of the cavity");
+     152           8 :   keys.addFlag("PRINT_BOX",false,"write out the positions of the corners of the box to an xyz file");
+     153           8 :   keys.add("optional","FILE","the file on which to write out the box coordinates");
+     154           8 :   keys.add("optional","UNITS","( default=nm ) the units in which to write out the corners of the box");
+     155           4 : }
+     156             : 
+     157           0 : VolumeTetrapore::VolumeTetrapore(const ActionOptions& ao):
+     158             :   Action(ao),
+     159             :   ActionVolume(ao),
+     160           0 :   boxout(false),
+     161           0 :   lenunit(1.0),
+     162           0 :   dlbi(4),
+     163           0 :   dlcross(4),
+     164           0 :   dlperp(4),
+     165           0 :   dbi(3),
+     166           0 :   dcross(3),
+     167           0 :   dperp(3)
+     168             : {
+     169             :   std::vector<AtomNumber> atoms;
+     170           0 :   parseAtomList("BOX",atoms);
+     171           0 :   if( atoms.size()!=4 ) error("number of atoms should be equal to four");
+     172             : 
+     173           0 :   log.printf("  boundaries for region are calculated based on positions of atoms : ");
+     174           0 :   for(unsigned i=0; i<atoms.size(); ++i) log.printf("%d ",atoms[i].serial() );
+     175           0 :   log.printf("\n");
+     176             : 
+     177           0 :   boxout=false; parseFlag("PRINT_BOX",boxout);
+     178           0 :   if(boxout) {
+     179           0 :     std::string boxfname; parse("FILE",boxfname);
+     180           0 :     if(boxfname.length()==0) error("no name for box file specified");
+     181           0 :     std::string unitname; parse("UNITS",unitname);
+     182           0 :     if ( unitname.length()>0 ) {
+     183           0 :       Units u; u.setLength(unitname);
+     184           0 :       lenunit=getUnits().getLength()/u.getLength();
+     185           0 :     } else {
+     186             :       unitname="nm";
+     187             :     }
+     188           0 :     boxfile.link(*this);
+     189           0 :     boxfile.open( boxfname );
+     190           0 :     log.printf("  printing box coordinates on file named %s in %s \n",boxfname.c_str(), unitname.c_str() );
+     191             :   }
+     192             : 
+     193           0 :   checkRead();
+     194           0 :   requestAtoms(atoms);
+     195           0 : }
+     196             : 
+     197           0 : VolumeTetrapore::~VolumeTetrapore() {
+     198           0 : }
+     199             : 
+     200           0 : void VolumeTetrapore::setupRegions() {
+     201             :   // Make some space for things
+     202           0 :   Vector d1, d2, d3;
+     203             : 
+     204             :   // Retrieve the sigma value
+     205           0 :   sigma=getSigma();
+     206             :   // Set the position of the origin
+     207           0 :   origin=getPosition(0);
+     208             : 
+     209             :   // Get two vectors
+     210           0 :   d1 = pbcDistance(origin,getPosition(1));
+     211           0 :   d2 = pbcDistance(origin,getPosition(2));
+     212             : 
+     213             :   // Find the vector connecting the origin to the top corner of
+     214             :   // the subregion
+     215           0 :   d3 = pbcDistance(origin,getPosition(3));
+     216             : 
+     217             :   // Create a set of unit vectors
+     218           0 :   Vector bisector = d1 + d2; double bmod=bisector.modulo(); bisector=bisector/bmod;
+     219             : 
+     220             :   // bi = d1 / d1l; len_bi=dotProduct( d3, bi );
+     221           0 :   cross = crossProduct( d1, d2 ); double crossmod=cross.modulo();
+     222           0 :   cross = cross / crossmod; len_cross=dotProduct( d3, cross );
+     223           0 :   Vector truep = crossProduct( cross, bisector );
+     224             : 
+     225             :   // These are our true vectors 45 degrees from bisector
+     226           0 :   bi = cos(pi/4.0)*bisector + sin(pi/4.0)*truep;
+     227           0 :   perp = cos(pi/4.0)*bisector - sin(pi/4.0)*truep;
+     228             : 
+     229             :   // And the lengths of the various parts average distance to opposite corners of tetetrahedron
+     230           0 :   len_bi = dotProduct( d1, bi ); double len_bi2 = dotProduct( d2, bi ); unsigned lbi=1;
+     231           0 :   if( len_bi2>len_bi ) { len_bi=len_bi2; lbi=2; }
+     232           0 :   len_perp = dotProduct( d1, perp ); double len_perp2 = dotProduct( d2, perp ); unsigned lpi=1;
+     233           0 :   if( len_perp2>len_perp ) { len_perp=len_perp2; lpi=2; }
+     234           0 :   plumed_assert( lbi!=lpi );
+     235             : 
+     236           0 :   Tensor tcderiv; double cmod3=crossmod*crossmod*crossmod; Vector ucross=crossmod*cross;
+     237           0 :   tcderiv.setCol( 0, crossProduct( d1, Vector(-1.0,0.0,0.0) ) + crossProduct( Vector(-1.0,0.0,0.0), d2 ) );
+     238           0 :   tcderiv.setCol( 1, crossProduct( d1, Vector(0.0,-1.0,0.0) ) + crossProduct( Vector(0.0,-1.0,0.0), d2 ) );
+     239           0 :   tcderiv.setCol( 2, crossProduct( d1, Vector(0.0,0.0,-1.0) ) + crossProduct( Vector(0.0,0.0,-1.0), d2 ) );
+     240           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
+     241           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
+     242           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
+     243           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
+     244           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
+     245           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
+     246           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
+     247           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
+     248           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
+     249             : 
+     250           0 :   tcderiv.setCol( 0, crossProduct( Vector(1.0,0.0,0.0), d2 ) );
+     251           0 :   tcderiv.setCol( 1, crossProduct( Vector(0.0,1.0,0.0), d2 ) );
+     252           0 :   tcderiv.setCol( 2, crossProduct( Vector(0.0,0.0,1.0), d2 ) );
+     253           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
+     254           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
+     255           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
+     256           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
+     257           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
+     258           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
+     259           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
+     260           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
+     261           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
+     262             : 
+     263           0 :   tcderiv.setCol( 0, crossProduct( d1, Vector(1.0,0.0,0.0) ) );
+     264           0 :   tcderiv.setCol( 1, crossProduct( d1, Vector(0.0,1.0,0.0) ) );
+     265           0 :   tcderiv.setCol( 2, crossProduct( d1, Vector(0.0,0.0,1.0) ) );
+     266           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
+     267           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
+     268           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
+     269           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
+     270           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
+     271           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
+     272           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
+     273           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
+     274           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
+     275             : 
+     276           0 :   std::vector<Tensor> dbisector(3);
+     277           0 :   double bmod3=bmod*bmod*bmod; Vector ubisector=bmod*bisector;
+     278           0 :   dbisector[0](0,0)= -2.0/bmod + 2*ubisector[0]*ubisector[0]/bmod3;
+     279           0 :   dbisector[0](0,1)= 2*ubisector[0]*ubisector[1]/bmod3;
+     280           0 :   dbisector[0](0,2)= 2*ubisector[0]*ubisector[2]/bmod3;
+     281           0 :   dbisector[0](1,0)= 2*ubisector[1]*ubisector[0]/bmod3;
+     282           0 :   dbisector[0](1,1)= -2.0/bmod + 2*ubisector[1]*ubisector[1]/bmod3;
+     283           0 :   dbisector[0](1,2)= 2*ubisector[1]*ubisector[2]/bmod3;
+     284           0 :   dbisector[0](2,0)= 2*ubisector[2]*ubisector[0]/bmod3;
+     285           0 :   dbisector[0](2,1)= 2*ubisector[2]*ubisector[1]/bmod3;
+     286           0 :   dbisector[0](2,2)= -2.0/bmod + 2*ubisector[2]*ubisector[2]/bmod3;
+     287             : 
+     288           0 :   dbisector[1](0,0)= 1.0/bmod - ubisector[0]*ubisector[0]/bmod3;
+     289           0 :   dbisector[1](0,1)= -ubisector[0]*ubisector[1]/bmod3;
+     290           0 :   dbisector[1](0,2)= -ubisector[0]*ubisector[2]/bmod3;
+     291           0 :   dbisector[1](1,0)= -ubisector[1]*ubisector[0]/bmod3;
+     292           0 :   dbisector[1](1,1)= 1.0/bmod - ubisector[1]*ubisector[1]/bmod3;
+     293           0 :   dbisector[1](1,2)= -ubisector[1]*ubisector[2]/bmod3;
+     294           0 :   dbisector[1](2,0)= -ubisector[2]*ubisector[0]/bmod3;
+     295           0 :   dbisector[1](2,1)= -ubisector[2]*ubisector[1]/bmod3;
+     296           0 :   dbisector[1](2,2)=1.0/bmod - ubisector[2]*ubisector[2]/bmod3;
+     297             : 
+     298           0 :   dbisector[2](0,0)=1.0/bmod - ubisector[0]*ubisector[0]/bmod3;
+     299           0 :   dbisector[2](0,1)= -ubisector[0]*ubisector[1]/bmod3;
+     300           0 :   dbisector[2](0,2)= -ubisector[0]*ubisector[2]/bmod3;
+     301           0 :   dbisector[2](1,0)= -ubisector[1]*ubisector[0]/bmod3;
+     302           0 :   dbisector[2](1,1)=1.0/bmod - ubisector[1]*ubisector[1]/bmod3;
+     303           0 :   dbisector[2](1,2)= -ubisector[1]*ubisector[2]/bmod3;
+     304           0 :   dbisector[2](2,0)= -ubisector[2]*ubisector[0]/bmod3;
+     305           0 :   dbisector[2](2,1)= -ubisector[2]*ubisector[1]/bmod3;
+     306           0 :   dbisector[2](2,2)=1.0/bmod - ubisector[2]*ubisector[2]/bmod3;
+     307             : 
+     308           0 :   std::vector<Tensor> dtruep(3);
+     309           0 :   dtruep[0].setCol( 0, ( crossProduct( dcross[0].getCol(0), bisector ) + crossProduct( cross, dbisector[0].getCol(0) ) ) );
+     310           0 :   dtruep[0].setCol( 1, ( crossProduct( dcross[0].getCol(1), bisector ) + crossProduct( cross, dbisector[0].getCol(1) ) ) );
+     311           0 :   dtruep[0].setCol( 2, ( crossProduct( dcross[0].getCol(2), bisector ) + crossProduct( cross, dbisector[0].getCol(2) ) ) );
+     312             : 
+     313           0 :   dtruep[1].setCol( 0, ( crossProduct( dcross[1].getCol(0), bisector ) + crossProduct( cross, dbisector[1].getCol(0) ) ) );
+     314           0 :   dtruep[1].setCol( 1, ( crossProduct( dcross[1].getCol(1), bisector ) + crossProduct( cross, dbisector[1].getCol(1) ) ) );
+     315           0 :   dtruep[1].setCol( 2, ( crossProduct( dcross[1].getCol(2), bisector ) + crossProduct( cross, dbisector[1].getCol(2) ) ) );
+     316             : 
+     317           0 :   dtruep[2].setCol( 0, ( crossProduct( dcross[2].getCol(0), bisector ) + crossProduct( cross, dbisector[2].getCol(0) ) ) );
+     318           0 :   dtruep[2].setCol( 1, ( crossProduct( dcross[2].getCol(1), bisector ) + crossProduct( cross, dbisector[2].getCol(1) ) ) );
+     319           0 :   dtruep[2].setCol( 2, ( crossProduct( dcross[2].getCol(2), bisector ) + crossProduct( cross, dbisector[2].getCol(2) ) ) );
+     320             : 
+     321             :   // Now convert these to the derivatives of the true axis
+     322           0 :   for(unsigned i=0; i<3; ++i) {
+     323           0 :     dbi[i] = cos(pi/4.0)*dbisector[i] + sin(pi/4.0)*dtruep[i];
+     324           0 :     dperp[i] = cos(pi/4.0)*dbisector[i] - sin(pi/4.0)*dtruep[i];
+     325             :   }
+     326             : 
+     327             :   // Ensure that all lengths are positive
+     328           0 :   if( len_bi<0 ) {
+     329           0 :     bi=-bi; len_bi=-len_bi;
+     330           0 :     for(unsigned i=0; i<3; ++i) dbi[i]*=-1.0;
+     331             :   }
+     332           0 :   if( len_cross<0 ) {
+     333           0 :     cross=-cross; len_cross=-len_cross;
+     334           0 :     for(unsigned i=0; i<3; ++i) dcross[i]*=-1.0;
+     335             :   }
+     336           0 :   if( len_perp<0 ) {
+     337           0 :     perp=-perp; len_perp=-len_perp;
+     338           0 :     for(unsigned i=0; i<3; ++i) dperp[i]*=-1.0;
+     339             :   }
+     340           0 :   if( len_bi<=0 || len_cross<=0 || len_bi<=0 ) plumed_merror("Invalid box coordinates");
+     341             : 
+     342             :   // Now derivatives of lengths
+     343           0 :   Tensor dd3( Tensor::identity() ); Vector ddb2=d1; if( lbi==2 ) ddb2=d2;
+     344           0 :   dlbi[1].zero(); dlbi[2].zero(); dlbi[3].zero();
+     345           0 :   dlbi[0] = matmul(ddb2,dbi[0]) - matmul(bi,dd3);
+     346           0 :   dlbi[lbi] = matmul(ddb2,dbi[lbi]) + matmul(bi,dd3);  // Derivative wrt d1
+     347             : 
+     348           0 :   dlcross[0] = matmul(d3,dcross[0]) - matmul(cross,dd3);
+     349           0 :   dlcross[1] = matmul(d3,dcross[1]);
+     350           0 :   dlcross[2] = matmul(d3,dcross[2]);
+     351           0 :   dlcross[3] = matmul(cross,dd3);
+     352             : 
+     353           0 :   ddb2=d1; if( lpi==2 ) ddb2=d2;
+     354           0 :   dlperp[1].zero(); dlperp[2].zero(); dlperp[3].zero();
+     355           0 :   dlperp[0] = matmul(ddb2,dperp[0]) - matmul( perp, dd3 );
+     356           0 :   dlperp[lpi] = matmul(ddb2,dperp[lpi]) + matmul(perp, dd3);
+     357             : 
+     358             :   // Need to calculate the jacobian
+     359           0 :   Tensor jacob;
+     360           0 :   jacob(0,0)=bi[0]; jacob(1,0)=bi[1]; jacob(2,0)=bi[2];
+     361           0 :   jacob(0,1)=cross[0]; jacob(1,1)=cross[1]; jacob(2,1)=cross[2];
+     362           0 :   jacob(0,2)=perp[0]; jacob(1,2)=perp[1]; jacob(2,2)=perp[2];
+     363           0 :   jacob_det = fabs( jacob.determinant() );
+     364           0 : }
+     365             : 
+     366           0 : void VolumeTetrapore::update() {
+     367           0 :   if(boxout) {
+     368           0 :     boxfile.printf("%d\n",8);
+     369           0 :     const Tensor & t(getPbc().getBox());
+     370           0 :     if(getPbc().isOrthorombic()) {
+     371           0 :       boxfile.printf(" %f %f %f\n",lenunit*t(0,0),lenunit*t(1,1),lenunit*t(2,2));
+     372             :     } else {
+     373           0 :       boxfile.printf(" %f %f %f %f %f %f %f %f %f\n",
+     374           0 :                      lenunit*t(0,0),lenunit*t(0,1),lenunit*t(0,2),
+     375           0 :                      lenunit*t(1,0),lenunit*t(1,1),lenunit*t(1,2),
+     376           0 :                      lenunit*t(2,0),lenunit*t(2,1),lenunit*t(2,2)
+     377             :                     );
+     378             :     }
+     379           0 :     boxfile.printf("AR %f %f %f \n",lenunit*origin[0],lenunit*origin[1],lenunit*origin[2]);
+     380           0 :     Vector ut, vt, wt;
+     381           0 :     ut = origin + len_bi*bi;
+     382           0 :     vt = origin + len_cross*cross;
+     383           0 :     wt = origin + len_perp*perp;
+     384           0 :     boxfile.printf("AR %f %f %f \n",lenunit*(ut[0]), lenunit*(ut[1]), lenunit*(ut[2]) );
+     385           0 :     boxfile.printf("AR %f %f %f \n",lenunit*(vt[0]), lenunit*(vt[1]), lenunit*(vt[2]) );
+     386           0 :     boxfile.printf("AR %f %f %f \n",lenunit*(wt[0]), lenunit*(wt[1]), lenunit*(wt[2]) );
+     387           0 :     boxfile.printf("AR %f %f %f \n",lenunit*(vt[0]+len_bi*bi[0]),
+     388           0 :                    lenunit*(vt[1]+len_bi*bi[1]),
+     389           0 :                    lenunit*(vt[2]+len_bi*bi[2]) );
+     390           0 :     boxfile.printf("AR %f %f %f \n",lenunit*(ut[0]+len_perp*perp[0]),
+     391           0 :                    lenunit*(ut[1]+len_perp*perp[1]),
+     392           0 :                    lenunit*(ut[2]+len_perp*perp[2]) );
+     393           0 :     boxfile.printf("AR %f %f %f \n",lenunit*(vt[0]+len_perp*perp[0]),
+     394           0 :                    lenunit*(vt[1]+len_perp*perp[1]),
+     395           0 :                    lenunit*(vt[2]+len_perp*perp[2]) );
+     396           0 :     boxfile.printf("AR %f %f %f \n",lenunit*(vt[0]+len_perp*perp[0]+len_bi*bi[0]),
+     397           0 :                    lenunit*(vt[1]+len_perp*perp[1]+len_bi*bi[1]),
+     398           0 :                    lenunit*(vt[2]+len_perp*perp[2]+len_bi*bi[2]) );
+     399             :   }
+     400           0 : }
+     401             : 
+     402           0 : double VolumeTetrapore::calculateNumberInside( const Vector& cpos, Vector& derivatives, Tensor& vir, std::vector<Vector>& rderiv ) const {
+     403             :   // Setup the histogram bead
+     404           0 :   HistogramBead bead; bead.isNotPeriodic(); bead.setKernelType( getKernelType() );
+     405             : 
+     406             :   // Calculate distance of atom from origin of new coordinate frame
+     407           0 :   Vector datom=pbcDistance( origin, cpos );
+     408             :   double ucontr, uder, vcontr, vder, wcontr, wder;
+     409             : 
+     410             :   // Calculate contribution from integral along bi
+     411           0 :   bead.set( 0, len_bi, sigma );
+     412           0 :   double upos=dotProduct( datom, bi );
+     413           0 :   ucontr=bead.calculate( upos, uder );
+     414           0 :   double udlen=bead.uboundDerivative( upos );
+     415           0 :   double uder2 = bead.lboundDerivative( upos ) - udlen;
+     416             : 
+     417             :   // Calculate contribution from integral along cross
+     418           0 :   bead.set( 0, len_cross, sigma );
+     419           0 :   double vpos=dotProduct( datom, cross );
+     420           0 :   vcontr=bead.calculate( vpos, vder );
+     421           0 :   double vdlen=bead.uboundDerivative( vpos );
+     422           0 :   double vder2 = bead.lboundDerivative( vpos ) - vdlen;
+     423             : 
+     424             :   // Calculate contribution from integral along perp
+     425           0 :   bead.set( 0, len_perp, sigma );
+     426           0 :   double wpos=dotProduct( datom, perp );
+     427           0 :   wcontr=bead.calculate( wpos, wder );
+     428           0 :   double wdlen=bead.uboundDerivative( wpos );
+     429           0 :   double wder2 = bead.lboundDerivative( wpos ) - wdlen;
+     430             : 
+     431           0 :   Vector dfd; dfd[0]=uder*vcontr*wcontr; dfd[1]=ucontr*vder*wcontr; dfd[2]=ucontr*vcontr*wder;
+     432           0 :   derivatives[0] = (dfd[0]*bi[0]+dfd[1]*cross[0]+dfd[2]*perp[0]);
+     433           0 :   derivatives[1] = (dfd[0]*bi[1]+dfd[1]*cross[1]+dfd[2]*perp[1]);
+     434           0 :   derivatives[2] = (dfd[0]*bi[2]+dfd[1]*cross[2]+dfd[2]*perp[2]);
+     435           0 :   double tot = ucontr*vcontr*wcontr*jacob_det;
+     436             : 
+     437             :   // Add reference atom derivatives
+     438           0 :   dfd[0]=uder2*vcontr*wcontr; dfd[1]=ucontr*vder2*wcontr; dfd[2]=ucontr*vcontr*wder2;
+     439           0 :   Vector dfld; dfld[0]=udlen*vcontr*wcontr; dfld[1]=ucontr*vdlen*wcontr; dfld[2]=ucontr*vcontr*wdlen;
+     440           0 :   rderiv[0] = dfd[0]*matmul(datom,dbi[0]) + dfd[1]*matmul(datom,dcross[0]) + dfd[2]*matmul(datom,dperp[0]) +
+     441           0 :               dfld[0]*dlbi[0] + dfld[1]*dlcross[0] + dfld[2]*dlperp[0] - derivatives;
+     442           0 :   rderiv[1] = dfd[0]*matmul(datom,dbi[1]) + dfd[1]*matmul(datom,dcross[1]) + dfd[2]*matmul(datom,dperp[1]) +
+     443           0 :               dfld[0]*dlbi[1] + dfld[1]*dlcross[1] + dfld[2]*dlperp[1];
+     444           0 :   rderiv[2] = dfd[0]*matmul(datom,dbi[2]) + dfd[1]*matmul(datom,dcross[2]) + dfd[2]*matmul(datom,dperp[2]) +
+     445           0 :               dfld[0]*dlbi[2] + dfld[1]*dlcross[2] + dfld[2]*dlperp[2];
+     446           0 :   rderiv[3] = dfld[0]*dlbi[3] + dfld[1]*dlcross[3] + dfld[2]*dlperp[3];
+     447             : 
+     448           0 :   vir.zero(); vir-=Tensor( cpos,derivatives );
+     449           0 :   for(unsigned i=0; i<4; ++i) {
+     450           0 :     vir -= Tensor( getPosition(i), rderiv[i] );
+     451             :   }
+     452             : 
+     453           0 :   return tot;
+     454             : }
+     455             : 
+     456             : }
+     457             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/volumes/index-sort-f.html b/coverage/volumes/index-sort-f.html new file mode 100644 index 000000000000..e93d7ada042e --- /dev/null +++ b/coverage/volumes/index-sort-f.html @@ -0,0 +1,184 @@ + + + + + + + + LCOV - plumed test coverage - volumes + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - volumesHitTotalCoverage
Test:plumed test coverageLines:47876162.8 %
Date:2024-04-19 12:12:35Functions:476572.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
VolumeTetrapore.cpp +
3.0%3.0%
+
3.0 %7 / 23011.1 %1 / 9
Density.cpp +
50.0%50.0%
+
50.0 %5 / 1033.3 %1 / 3
VolumeCavity.cpp +
79.1%79.1%
+
79.1 %167 / 21177.8 %7 / 9
VolumeBetweenContours.cpp +
98.1%98.1%
+
98.1 %51 / 5280.0 %4 / 5
VolumeInCylinder.cpp +
95.8%95.8%
+
95.8 %46 / 4880.0 %4 / 5
VolumeAround.cpp +
100.0%
+
100.0 %49 / 4980.0 %4 / 5
VolumeInSphere.cpp +
100.0%
+
100.0 %27 / 2780.0 %4 / 5
ActionVolume.cpp +
97.3%97.3%
+
97.3 %72 / 7490.0 %9 / 10
VolumeShortcut.h +
88.7%88.7%
+
88.7 %47 / 5391.7 %11 / 12
ActionVolume.h +
100.0%
+
100.0 %7 / 7100.0 %2 / 2
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/volumes/index-sort-l.html b/coverage/volumes/index-sort-l.html new file mode 100644 index 000000000000..1fc8e84dbd62 --- /dev/null +++ b/coverage/volumes/index-sort-l.html @@ -0,0 +1,184 @@ + + + + + + + + LCOV - plumed test coverage - volumes + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - volumesHitTotalCoverage
Test:plumed test coverageLines:47876162.8 %
Date:2024-04-19 12:12:35Functions:476572.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
VolumeTetrapore.cpp +
3.0%3.0%
+
3.0 %7 / 23011.1 %1 / 9
Density.cpp +
50.0%50.0%
+
50.0 %5 / 1033.3 %1 / 3
VolumeCavity.cpp +
79.1%79.1%
+
79.1 %167 / 21177.8 %7 / 9
VolumeShortcut.h +
88.7%88.7%
+
88.7 %47 / 5391.7 %11 / 12
VolumeInCylinder.cpp +
95.8%95.8%
+
95.8 %46 / 4880.0 %4 / 5
ActionVolume.cpp +
97.3%97.3%
+
97.3 %72 / 7490.0 %9 / 10
VolumeBetweenContours.cpp +
98.1%98.1%
+
98.1 %51 / 5280.0 %4 / 5
ActionVolume.h +
100.0%
+
100.0 %7 / 7100.0 %2 / 2
VolumeInSphere.cpp +
100.0%
+
100.0 %27 / 2780.0 %4 / 5
VolumeAround.cpp +
100.0%
+
100.0 %49 / 4980.0 %4 / 5
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/volumes/index.html b/coverage/volumes/index.html new file mode 100644 index 000000000000..3ffe6c593e08 --- /dev/null +++ b/coverage/volumes/index.html @@ -0,0 +1,184 @@ + + + + + + + + LCOV - plumed test coverage - volumes + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - volumesHitTotalCoverage
Test:plumed test coverageLines:47876162.8 %
Date:2024-04-19 12:12:35Functions:476572.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
ActionVolume.cpp +
97.3%97.3%
+
97.3 %72 / 7490.0 %9 / 10
ActionVolume.h +
100.0%
+
100.0 %7 / 7100.0 %2 / 2
Density.cpp +
50.0%50.0%
+
50.0 %5 / 1033.3 %1 / 3
VolumeAround.cpp +
100.0%
+
100.0 %49 / 4980.0 %4 / 5
VolumeBetweenContours.cpp +
98.1%98.1%
+
98.1 %51 / 5280.0 %4 / 5
VolumeCavity.cpp +
79.1%79.1%
+
79.1 %167 / 21177.8 %7 / 9
VolumeInCylinder.cpp +
95.8%95.8%
+
95.8 %46 / 4880.0 %4 / 5
VolumeInSphere.cpp +
100.0%
+
100.0 %27 / 2780.0 %4 / 5
VolumeShortcut.h +
88.7%88.7%
+
88.7 %47 / 5391.7 %11 / 12
VolumeTetrapore.cpp +
3.0%3.0%
+
3.0 %7 / 23011.1 %1 / 9
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/wrapper/Plumed.h.func-sort-c.html b/coverage/wrapper/Plumed.h.func-sort-c.html new file mode 100644 index 000000000000..a447d2aced59 --- /dev/null +++ b/coverage/wrapper/Plumed.h.func-sort-c.html @@ -0,0 +1,1089 @@ + + + + + + + + LCOV - plumed test coverage - wrapper/Plumed.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - wrapper - Plumed.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:25050050.0 %
Date:2024-04-19 12:12:35Functions:14425456.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
PLUMED_F_CREATE_INVALID0
PLUMED_F_CREATE_INVALID_0
PLUMED_F_CREATE_INVALID__0
PLUMED_F_GVALID__0
PLUMED_F_VALID0
PLUMED_F_VALID_0
PLUMED_F_VALID__0
_ZL16plumed_error_setPviPKcPKv0
_ZL21plumed_error_finalize12plumed_error0
_ZL26plumed_error_set_bad_allocP12plumed_error0
_ZN12_GLOBAL__N_115plumed_cmd_safeE6plumedPKc14plumed_safeptr0
_ZN12_GLOBAL__N_118plumed_cmd_nothrowE6plumedPKcPKv22plumed_nothrow_handler0
_ZN4PLMD12_GLOBAL__N_16Plumed13add_buffer_toISt10bad_typeidE4initEPKc0
_ZN4PLMD12_GLOBAL__N_16Plumed13add_buffer_toISt13bad_exceptionE4initEPKc0
_ZN4PLMD12_GLOBAL__N_16Plumed13add_buffer_toISt8bad_castE4initEPKc0
_ZN4PLMD12_GLOBAL__N_16Plumed13add_buffer_toISt9bad_allocE4initEPKc0
_ZN4PLMD12_GLOBAL__N_16Plumed13add_buffer_toISt9exceptionE4initEPKc0
_ZN4PLMD12_GLOBAL__N_16Plumed18exception_dispatchINS1_14rethrow_nestedEEEvR12plumed_errorT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18exception_dispatchINS1_18rethrow_not_nestedEEEvR12plumed_errorT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclINS1_13add_buffer_toISt10bad_typeidEEEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclINS1_13add_buffer_toISt13bad_exceptionEEEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclINS1_13add_buffer_toISt8bad_castEEEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclINS1_13add_buffer_toISt9bad_allocEEEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclINS1_13add_buffer_toISt9exceptionEEEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclINS1_7InvalidEEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclINS_14ExceptionDebugEEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclINS_14ExceptionErrorEEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclINS_18ExceptionTypeErrorEEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclINS_6lepton9ExceptionEEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclINS_9ExceptionEEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclINSt8ios_base7failureB5cxx11EEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclISt11logic_errorEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclISt11range_errorEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclISt12domain_errorEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclISt12length_errorEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclISt12out_of_rangeEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclISt13runtime_errorEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclISt14overflow_errorEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclISt15underflow_errorEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclISt16invalid_argumentEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed21finalize_plumed_errorD2Ev0
_ZN4PLMD12_GLOBAL__N_16Plumed7InvalidC2EPKc0
_ZN4PLMD12_GLOBAL__N_16Plumed7rethrowER12plumed_error0
_ZN4PLMD12_GLOBAL__N_16Plumed7rethrowEv0
_ZN4PLMD12_GLOBAL__N_1L27PlumedGetenvExceptionsDebugEv0
_ZN4PLMD6Plumed13add_buffer_toISt10bad_typeidE4initEPKc0
_ZN4PLMD6Plumed13add_buffer_toISt13bad_exceptionE4initEPKc0
_ZN4PLMD6Plumed13add_buffer_toISt8bad_castE4initEPKc0
_ZN4PLMD6Plumed13add_buffer_toISt9bad_allocE4initEPKc0
_ZN4PLMD6Plumed13add_buffer_toISt9exceptionE4initEPKc0
_ZN4PLMD6Plumed15LeptonExceptionC2EPKc0
_ZN4PLMD6Plumed18exception_dispatchINS0_14rethrow_nestedEEEvR12plumed_errorT_0
_ZN4PLMD6Plumed18exception_dispatchINS0_18rethrow_not_nestedEEEvR12plumed_errorT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclINS0_13add_buffer_toISt10bad_typeidEEEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclINS0_13add_buffer_toISt13bad_exceptionEEEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclINS0_13add_buffer_toISt8bad_castEEEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclINS0_13add_buffer_toISt9bad_allocEEEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclINS0_13add_buffer_toISt9exceptionEEEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclINS0_14ExceptionDebugEEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclINS0_14ExceptionErrorEEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclINS0_15LeptonExceptionEEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclINS0_18ExceptionTypeErrorEEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclINS0_7InvalidEEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclINS0_9ExceptionEEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclINSt8ios_base7failureB5cxx11EEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclISt11logic_errorEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclISt11range_errorEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclISt12domain_errorEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclISt12length_errorEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclISt12out_of_rangeEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclISt13runtime_errorEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclISt14overflow_errorEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclISt15underflow_errorEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclISt16invalid_argumentEEvRKT_0
_ZN4PLMD6Plumed21finalize_plumed_errorD2Ev0
_ZN4PLMD6Plumed7rethrowER12plumed_error0
_ZN4PLMD6Plumed7rethrowEv0
_ZN4PLMD6Plumed9ExceptionC2EPKc0
_ZN4PLMDL27PlumedGetenvExceptionsDebugEv0
_ZNK4PLMD12_GLOBAL__N_16Plumed13add_buffer_toISt10bad_typeidE4whatEv0
_ZNK4PLMD12_GLOBAL__N_16Plumed13add_buffer_toISt13bad_exceptionE4whatEv0
_ZNK4PLMD12_GLOBAL__N_16Plumed13add_buffer_toISt8bad_castE4whatEv0
_ZNK4PLMD12_GLOBAL__N_16Plumed13add_buffer_toISt9bad_allocE4whatEv0
_ZNK4PLMD12_GLOBAL__N_16Plumed13add_buffer_toISt9exceptionE4whatEv0
_ZNK4PLMD6Plumed13add_buffer_toISt10bad_typeidE4whatEv0
_ZNK4PLMD6Plumed13add_buffer_toISt13bad_exceptionE4whatEv0
_ZNK4PLMD6Plumed13add_buffer_toISt8bad_castE4whatEv0
_ZNK4PLMD6Plumed13add_buffer_toISt9bad_allocE4whatEv0
_ZNK4PLMD6Plumed13add_buffer_toISt9exceptionE4whatEv0
_ZNK4PLMD6Plumed15LeptonException4whatEv0
_ZNK4PLMD6Plumed9Exception4whatEv0
plumed_cmd_nothrow0
plumed_f_create_invalid0
plumed_f_create_invalid_0
plumed_f_create_invalid__0
plumed_f_create_invalid_static0
plumed_f_safeptr_char_scalar0
plumed_f_safeptr_float_scalar0
plumed_f_safeptr_long0
plumed_f_safeptr_long_double0
plumed_f_safeptr_long_double_scalar0
plumed_f_safeptr_long_scalar0
plumed_f_safeptr_ptr_scalar0
plumed_f_safeptr_short0
plumed_f_safeptr_short_scalar0
plumed_f_valid0
plumed_f_valid_0
plumed_f_valid__0
plumed_f_valid_static0
plumed_gcmd_safe0
PLUMED_F_CREATE_DLOPEN1
PLUMED_F_CREATE_DLOPEN_1
PLUMED_F_CREATE_DLOPEN__1
PLUMED_F_CREATE_REFERENCE1
PLUMED_F_CREATE_REFERENCE_1
PLUMED_F_CREATE_REFERENCE__1
PLUMED_F_GLOBAL1
PLUMED_F_GLOBAL_1
PLUMED_F_GLOBAL__1
PLUMED_F_GVALID1
PLUMED_F_INSTALLED1
PLUMED_F_INSTALLED_1
PLUMED_F_INSTALLED__1
_ZN12_GLOBAL__N_115plumed_finalizeE6plumed1
_ZN12_GLOBAL__N_119plumed_create_dlsymEPv1
_ZN12_GLOBAL__N_119plumed_malloc_pimplEv1
_ZN12_GLOBAL__N_120plumed_create_dlopenEPKc1
_ZN12_GLOBAL__N_121plumed_attempt_dlopenEPKci1
_ZN12_GLOBAL__N_121plumed_create_dlopen2EPKci1
_ZN12_GLOBAL__N_121plumed_search_symbolsEPvP33plumed_plumedmain_function_holderPP24plumed_symbol_table_type1
plumed_f_create_dlopen1
plumed_f_create_dlopen_1
plumed_f_create_dlopen__1
plumed_f_create_reference1
plumed_f_create_reference_1
plumed_f_create_reference__1
plumed_f_global_1
plumed_f_global__1
plumed_f_gvalid1
plumed_f_gvalid_1
plumed_f_gvalid__1
plumed_f_installed1
plumed_f_installed_1
plumed_f_installed__1
plumed_f_safeptr_float1
PLUMED_F_CREATE2
PLUMED_F_CREATE_2
PLUMED_F_CREATE__2
PLUMED_F_GCREATE2
PLUMED_F_GCREATE_2
PLUMED_F_GCREATE__2
PLUMED_F_GFINALIZE2
PLUMED_F_GFINALIZE_2
PLUMED_F_GFINALIZE__2
PLUMED_F_GINITIALIZED__2
PLUMED_F_GVALID_2
plumed_c2v2
plumed_create_invalid2
plumed_create_reference_v2
plumed_f_create__2
plumed_f_gcreate__2
plumed_f_gfinalize__2
plumed_v2c2
PLUMED_F_GINITIALIZED3
PLUMED_F_USE_COUNT3
PLUMED_F_USE_COUNT_3
PLUMED_F_USE_COUNT__3
plumed_f_gcreate3
plumed_f_gcreate_3
plumed_f_gfinalize3
plumed_f_gfinalize_3
plumed_f_ginitialized3
plumed_f_ginitialized_3
plumed_f_ginitialized__3
plumed_f_safeptr_double_scalar3
plumed_f_use_count3
plumed_f_use_count_3
plumed_f_use_count__3
PLUMED_F_FINALIZE4
PLUMED_F_FINALIZE_4
PLUMED_F_FINALIZE__4
PLUMED_F_GINITIALIZED_4
plumed_f_create_4
plumed_f_finalize__4
plumed_f_create6
plumed_f_create_dlopen_static6
plumed_f_create_reference_static6
plumed_f_finalize_6
plumed_f_gvalid_static6
plumed_f_installed_static6
plumed_f_safeptr_int6
plumed_attempt_dlopen8
plumed_create_dlopen8
plumed_create_dlopen28
plumed_create_dlsym8
plumed_create_reference_f8
plumed_f_finalize8
plumed_gvalid8
plumed_search_symbols8
plumed_installed9
PLUMED_F_GCMD10
PLUMED_F_GCMD_10
PLUMED_F_GCMD__10
plumed_f_gcmd10
plumed_f_gcmd__10
plumed_f_safeptr_int_scalar13
plumed_f_gcreate_static14
plumed_f_gfinalize_static14
plumed_f_safeptr_double16
plumed_f_create_static18
plumed_f_ginitialized_static18
plumed_f_use_count_static18
plumed_f_global19
plumed_f_safeptr_char20
plumed_gcreate22
plumed_gfinalize22
plumed_kernel_register23
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_error344
plumed_cmd357
plumed_f2c373
_ZN4PLMD6Plumed14plumed_cmd_cxxIPcEEv6plumedPKcPT_P12plumed_error5040
_ZN4PLMD6Plumed14plumed_cmd_cxxIiEEv6plumedPKcPT_P12plumed_error10080
_ZN4PLMD6Plumed8cmd_privE6plumedPKcPNS0_7SafePtrEPKvP12plumed_error15464
plumed_cmd_safe_nothrow17398
plumed_retrieve_functions689223
plumed_symbol_table_reexport689966
plumed_malloc_pimpl710020
plumed_malloc723787
plumed_free732865
plumed_create739158
plumed_create_reference7643371
plumed_finalize8581865
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/wrapper/Plumed.h.func.html b/coverage/wrapper/Plumed.h.func.html new file mode 100644 index 000000000000..a6a5a70d8475 --- /dev/null +++ b/coverage/wrapper/Plumed.h.func.html @@ -0,0 +1,1089 @@ + + + + + + + + LCOV - plumed test coverage - wrapper/Plumed.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - wrapper - Plumed.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:25050050.0 %
Date:2024-04-19 12:12:35Functions:14425456.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
PLUMED_F_CMD40
PLUMED_F_CMD_40
PLUMED_F_CMD__40
PLUMED_F_CREATE2
PLUMED_F_CREATE_2
PLUMED_F_CREATE_DLOPEN1
PLUMED_F_CREATE_DLOPEN_1
PLUMED_F_CREATE_DLOPEN__1
PLUMED_F_CREATE_INVALID0
PLUMED_F_CREATE_INVALID_0
PLUMED_F_CREATE_INVALID__0
PLUMED_F_CREATE_REFERENCE1
PLUMED_F_CREATE_REFERENCE_1
PLUMED_F_CREATE_REFERENCE__1
PLUMED_F_CREATE__2
PLUMED_F_FINALIZE4
PLUMED_F_FINALIZE_4
PLUMED_F_FINALIZE__4
PLUMED_F_GCMD10
PLUMED_F_GCMD_10
PLUMED_F_GCMD__10
PLUMED_F_GCREATE2
PLUMED_F_GCREATE_2
PLUMED_F_GCREATE__2
PLUMED_F_GFINALIZE2
PLUMED_F_GFINALIZE_2
PLUMED_F_GFINALIZE__2
PLUMED_F_GINITIALIZED3
PLUMED_F_GINITIALIZED_4
PLUMED_F_GINITIALIZED__2
PLUMED_F_GLOBAL1
PLUMED_F_GLOBAL_1
PLUMED_F_GLOBAL__1
PLUMED_F_GVALID1
PLUMED_F_GVALID_2
PLUMED_F_GVALID__0
PLUMED_F_INSTALLED1
PLUMED_F_INSTALLED_1
PLUMED_F_INSTALLED__1
PLUMED_F_USE_COUNT3
PLUMED_F_USE_COUNT_3
PLUMED_F_USE_COUNT__3
PLUMED_F_VALID0
PLUMED_F_VALID_0
PLUMED_F_VALID__0
_ZL16plumed_error_setPviPKcPKv0
_ZL21plumed_error_finalize12plumed_error0
_ZL26plumed_error_set_bad_allocP12plumed_error0
_ZN12_GLOBAL__N_115plumed_cmd_safeE6plumedPKc14plumed_safeptr0
_ZN12_GLOBAL__N_115plumed_finalizeE6plumed1
_ZN12_GLOBAL__N_118plumed_cmd_nothrowE6plumedPKcPKv22plumed_nothrow_handler0
_ZN12_GLOBAL__N_119plumed_create_dlsymEPv1
_ZN12_GLOBAL__N_119plumed_malloc_pimplEv1
_ZN12_GLOBAL__N_120plumed_create_dlopenEPKc1
_ZN12_GLOBAL__N_121plumed_attempt_dlopenEPKci1
_ZN12_GLOBAL__N_121plumed_create_dlopen2EPKci1
_ZN12_GLOBAL__N_121plumed_search_symbolsEPvP33plumed_plumedmain_function_holderPP24plumed_symbol_table_type1
_ZN12_GLOBAL__N_123plumed_cmd_safe_nothrowE6plumedPKc14plumed_safeptr22plumed_nothrow_handler222
_ZN4PLMD12_GLOBAL__N_16Plumed13add_buffer_toISt10bad_typeidE4initEPKc0
_ZN4PLMD12_GLOBAL__N_16Plumed13add_buffer_toISt13bad_exceptionE4initEPKc0
_ZN4PLMD12_GLOBAL__N_16Plumed13add_buffer_toISt8bad_castE4initEPKc0
_ZN4PLMD12_GLOBAL__N_16Plumed13add_buffer_toISt9bad_allocE4initEPKc0
_ZN4PLMD12_GLOBAL__N_16Plumed13add_buffer_toISt9exceptionE4initEPKc0
_ZN4PLMD12_GLOBAL__N_16Plumed14plumed_cmd_cxxI14plumed_safeptrEEv6plumedPKcT_P12plumed_error222
_ZN4PLMD12_GLOBAL__N_16Plumed18exception_dispatchINS1_14rethrow_nestedEEEvR12plumed_errorT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18exception_dispatchINS1_18rethrow_not_nestedEEEvR12plumed_errorT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclINS1_13add_buffer_toISt10bad_typeidEEEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclINS1_13add_buffer_toISt13bad_exceptionEEEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclINS1_13add_buffer_toISt8bad_castEEEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclINS1_13add_buffer_toISt9bad_allocEEEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclINS1_13add_buffer_toISt9exceptionEEEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclINS1_7InvalidEEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclINS_14ExceptionDebugEEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclINS_14ExceptionErrorEEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclINS_18ExceptionTypeErrorEEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclINS_6lepton9ExceptionEEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclINS_9ExceptionEEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclINSt8ios_base7failureB5cxx11EEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclISt11logic_errorEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclISt11range_errorEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclISt12domain_errorEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclISt12length_errorEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclISt12out_of_rangeEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclISt13runtime_errorEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclISt14overflow_errorEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclISt15underflow_errorEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclISt16invalid_argumentEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed21finalize_plumed_errorD2Ev0
_ZN4PLMD12_GLOBAL__N_16Plumed7InvalidC2EPKc0
_ZN4PLMD12_GLOBAL__N_16Plumed7rethrowER12plumed_error0
_ZN4PLMD12_GLOBAL__N_16Plumed7rethrowEv0
_ZN4PLMD12_GLOBAL__N_16Plumed8cmd_privE6plumedPKcPNS1_7SafePtrEPKvP12plumed_error222
_ZN4PLMD12_GLOBAL__N_1L27PlumedGetenvExceptionsDebugEv0
_ZN4PLMD6Plumed13add_buffer_toISt10bad_typeidE4initEPKc0
_ZN4PLMD6Plumed13add_buffer_toISt13bad_exceptionE4initEPKc0
_ZN4PLMD6Plumed13add_buffer_toISt8bad_castE4initEPKc0
_ZN4PLMD6Plumed13add_buffer_toISt9bad_allocE4initEPKc0
_ZN4PLMD6Plumed13add_buffer_toISt9exceptionE4initEPKc0
_ZN4PLMD6Plumed14plumed_cmd_cxxIP19ompi_communicator_tEEv6plumedPKcPT_P12plumed_error344
_ZN4PLMD6Plumed14plumed_cmd_cxxIPcEEv6plumedPKcPT_P12plumed_error5040
_ZN4PLMD6Plumed14plumed_cmd_cxxIiEEv6plumedPKcPT_P12plumed_error10080
_ZN4PLMD6Plumed15LeptonExceptionC2EPKc0
_ZN4PLMD6Plumed18exception_dispatchINS0_14rethrow_nestedEEEvR12plumed_errorT_0
_ZN4PLMD6Plumed18exception_dispatchINS0_18rethrow_not_nestedEEEvR12plumed_errorT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclINS0_13add_buffer_toISt10bad_typeidEEEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclINS0_13add_buffer_toISt13bad_exceptionEEEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclINS0_13add_buffer_toISt8bad_castEEEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclINS0_13add_buffer_toISt9bad_allocEEEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclINS0_13add_buffer_toISt9exceptionEEEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclINS0_14ExceptionDebugEEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclINS0_14ExceptionErrorEEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclINS0_15LeptonExceptionEEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclINS0_18ExceptionTypeErrorEEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclINS0_7InvalidEEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclINS0_9ExceptionEEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclINSt8ios_base7failureB5cxx11EEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclISt11logic_errorEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclISt11range_errorEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclISt12domain_errorEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclISt12length_errorEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclISt12out_of_rangeEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclISt13runtime_errorEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclISt14overflow_errorEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclISt15underflow_errorEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclISt16invalid_argumentEEvRKT_0
_ZN4PLMD6Plumed21finalize_plumed_errorD2Ev0
_ZN4PLMD6Plumed7rethrowER12plumed_error0
_ZN4PLMD6Plumed7rethrowEv0
_ZN4PLMD6Plumed8cmd_privE6plumedPKcPNS0_7SafePtrEPKvP12plumed_error15464
_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_nothrow17398
plumed_create739158
plumed_create_dlopen8
plumed_create_dlopen28
plumed_create_dlsym8
plumed_create_invalid2
plumed_create_reference7643371
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_finalize8581865
plumed_free732865
plumed_gcmd78
plumed_gcmd_safe0
plumed_gcreate22
plumed_gfinalize22
plumed_ginitialized24
plumed_global41
plumed_gvalid8
plumed_installed9
plumed_kernel_register23
plumed_malloc723787
plumed_malloc_pimpl710020
plumed_retrieve_functions689223
plumed_search_symbols8
plumed_symbol_table_reexport689966
plumed_use_count42
plumed_v2c2
plumed_valid23
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/wrapper/Plumed.h.gcov.html b/coverage/wrapper/Plumed.h.gcov.html new file mode 100644 index 000000000000..db726b13196a --- /dev/null +++ b/coverage/wrapper/Plumed.h.gcov.html @@ -0,0 +1,4478 @@ + + + + + + + + LCOV - plumed test coverage - wrapper/Plumed.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - wrapper - Plumed.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:25050050.0 %
Date:2024-04-19 12:12:35Functions:14425456.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_wrapper_Plumed_h
+      23             : #define __PLUMED_wrapper_Plumed_h
+      24             : 
+      25             : /*
+      26             :   This header might be included more than once in order to provide
+      27             :   the declarations and the definitions. The guard is thus closed before the end of the file
+      28             :   (match this brace) {
+      29             :   and a new guard is added for the definitions.
+      30             : */
+      31             : 
+      32             : /**
+      33             : \page ReferencePlumedH Reference for interfacing MD codes with PLUMED
+      34             : 
+      35             :   Plumed.h and Plumed.c contain the external plumed interface, which is used to
+      36             :   integrate it with MD engines. This interface is very general, and is expected
+      37             :   not to change across plumed versions. Plumed.c also implements a dummy version
+      38             :   of the interface, so as to allow a code to be fully linked even if the plumed
+      39             :   library is not available yet. These files could be directly included in the official
+      40             :   host MD distribution. In this manner, it will be sufficient to link the plumed
+      41             :   library at link time (on all systems) or directly at runtime (on systems where
+      42             :   dynamic loading is enabled) to include plumed features.
+      43             : 
+      44             :   Notice that in PLUMED 2.5 this interface has been rewritten in order to allow
+      45             :   more debugging features and a better behavior in multithread environments.
+      46             :   The interface is almost perfectly backward compatible, although it implements
+      47             :   a few additional functions. See more details below.
+      48             : 
+      49             :   A further improvement has been made in PLUMED 2.8, where the interface has
+      50             :   been modified to allow dynamic type checking. See more details below.
+      51             : 
+      52             :   Why is Plumed.c written in C and not C++? The reason is that the resulting Plumed.o
+      53             :   needs to be linked with the host MD code immediately (whereas the rest of plumed
+      54             :   could be linked a posteriori). Imagine the MD code is written in FORTRAN: when we
+      55             :   link the Plumed.o file we would like not to need any C++ library linked. In this
+      56             :   manner, we do not need to know which C++ compiler will be used to compile plumed.
+      57             :   The C++ library is only linked to the "rest" of plumed, which actually uses it.
+      58             :   Anyway, Plumed.c is written in such a manner to allow its compilation also in C++
+      59             :   (C++ is a bit stricter than C). This will
+      60             :   allow e.g. MD codes written in C++ to just incorporate Plumed.c (maybe renamed into
+      61             :   Plumed.cpp), without the need of configuring a plain C compiler.
+      62             : 
+      63             :   Plumed interface can be used from C, C++ and FORTRAN. Everything concerning plumed
+      64             :   is hidden inside a single object type, which is described in C by a structure
+      65             :   (struct \ref plumed), in C++ by a class (PLMD::Plumed) and in FORTRAN by a
+      66             :   fixed-length string (CHARACTER(LEN=32)). Obviously C++ can use both struct
+      67             :   and class interfaces, but the second should be preferred since it will automatically take
+      68             :   care of objects constructions and destructions. The reference interface
+      69             :   is the C one, whereas FORTRAN and C++ interfaces are implemented as wrappers
+      70             :   around it.
+      71             :   In the C++ interface, all the routines are implemented as methods of PLMD::Plumed.
+      72             :   In the C and FORTRAN interfaces, all the routines are named plumed_*, to
+      73             :   avoid potential name clashes. Notice that the entire plumed library
+      74             :   is implemented in C++, and it is hidden inside the PLMD namespace.
+      75             : 
+      76             :   Handlers to the plumed object can be converted among different representations,
+      77             :   to allow inter-operability among languages. In C, there are tools to convert
+      78             :   to/from FORTRAN, whereas in C++ there are tools to convert to/from FORTRAN and C.
+      79             : 
+      80             :   These handlers only contain a pointer to the real structure, so that
+      81             :   when a plumed object is brought from one language to another,
+      82             :   it brings a reference to the same environment.
+      83             : 
+      84             :   Moreover, to simplify life in all cases where a single Plumed object is
+      85             :   required for the entire simulation (which covers many of the practical
+      86             :   applications with conventional MD codes) it is possible to take advantage
+      87             :   of a global interface, which is implicitly referring to a unique global instance.
+      88             :   The global object should still be initialized and finalized properly.
+      89             :   This global object is obviously not usable in a multithread context. In addition,
+      90             :   it is difficult to use it in an exception-safe manner, so its usage in C++ is
+      91             :   allowed but discouraged.
+      92             : 
+      93             :   As of PLUMED 2.5, the interface contains a reference counter that allows
+      94             :   for a better control of plumed initializations and deallocations.
+      95             :   This is particularly useful for the C++ interface that now
+      96             :   behaves similarly to a primitive shared pointer and can be thus copied.
+      97             :   In other languages, to use the reference counter correctly it is sufficient to
+      98             :   remember the following rule: for any `plumed_create*` call, there should be a corresponding
+      99             :   `plumed_finalize` call. More examples can be found below.
+     100             : 
+     101             :   Notice that up to PLUMED 2.8 the reference counter was not thread safe. This is fixed
+     102             :   when using PLUMED>=2.9 wrappers with a PLUMED>=2.9 kernel.
+     103             : 
+     104             :   The basic method to send a message to plumed is
+     105             : \verbatim
+     106             :   (C) plumed_cmd
+     107             :   (C++) PLMD::Plumed::cmd
+     108             :   (FORTRAN)  PLUMED_F_CMD
+     109             : \endverbatim
+     110             : 
+     111             :   To initialize a plumed object, use:
+     112             : \verbatim
+     113             :   (C)        plumed_create
+     114             :   (C++)      (constructor of PLMD::Plumed)
+     115             :   (FORTRAN)  PLUMED_F_CREATE
+     116             : \endverbatim
+     117             : 
+     118             :   As of PLUMED 2.5, you can also initialize a plumed object using the following functions,
+     119             :   that load a specific kernel. The function plumed_create_dlopen2 allows to specify options
+     120             :   for dlopen. The C++ version accepts an optional argument to this aim.
+     121             : \verbatim
+     122             :   (C)        plumed_create_dlopen or plumed_create_dlopen2
+     123             :   (C++)      PLMD::Plumed::dlopen
+     124             :   (FORTRAN)  PLUMED_F_CREATE_DLOPEN
+     125             : \endverbatim
+     126             : 
+     127             :   As of PLUMED 2.8, you can also initialize a plumed object using the following function,
+     128             :   that loads a kernel from an already loaded shared library. It accepts a handler
+     129             :   returned by `dlopen`:
+     130             : \verbatim
+     131             :   (C)        plumed_create_dlsym
+     132             :   (C++)      PLMD::Plumed::dlsym
+     133             :   (FORTRAN not allowed)
+     134             : \endverbatim
+     135             : 
+     136             :   To finalize a plumed object, use
+     137             : \verbatim
+     138             :   (C)        plumed_finalize
+     139             :   (C++)      (destructor of PLMD::Plumed)
+     140             :   (FORTRAN)  PLUMED_F_FINALIZE
+     141             : \endverbatim
+     142             : 
+     143             :   To access to the global-object, use
+     144             : \verbatim
+     145             :   (C)        plumed_gcreate, plumed_gfinalize, plumed_gcmd
+     146             :   (C++)      PLMD::Plumed::gcreate, PLMD::Plumed::gfinalize, PLMD::Plumed::gcmd
+     147             :   (FORTRAN)  PLUMED_F_GCREATE, PLUMED_F_GFINALIZE, PLUMED_F_GCMD
+     148             : \endverbatim
+     149             : 
+     150             :   To check if the global object has been initialized, use
+     151             : \verbatim
+     152             :   (C)        plumed_ginitialized
+     153             :   (C++)      PLMD::Plumed::ginitialized
+     154             :   (FORTRAN)  PLUMED_F_GINITIALIZED
+     155             : \endverbatim
+     156             : 
+     157             :   Notice that when using runtime binding the plumed library might be not available.
+     158             :   In this case, plumed_create (and plumed_gcreate) will still succeed, but a subsequent
+     159             :   call to plumed_cmd (or plumed_gcmd) would exit. In order to avoid this
+     160             :   unpleasant situation you have two options.
+     161             : 
+     162             :   First, you can check if plumed library is available before actually creating an object
+     163             :   using this function:
+     164             : \verbatim
+     165             :   (C)        plumed_installed
+     166             :   (C++)      PLMD::Plumed::installed
+     167             :   (FORTRAN)  PLUMED_F_INSTALLED
+     168             : \endverbatim
+     169             : 
+     170             :   Alternatively, as of PLUMED 2.5, you can interrogate the just created plumed
+     171             :   object using the following function:
+     172             : \verbatim
+     173             :   (C)        plumed_valid
+     174             :   (C++)      PLMD::Plumed::valid
+     175             :   (FORTRAN)  PLUMED_F_VALID
+     176             : \endverbatim
+     177             : 
+     178             :   If you want to create on purpose an invalid Plumed object (useful in C++ to postpone
+     179             :   the loading of the library) you can use `Plumed p(Plumed::makeInvalid());`.
+     180             : 
+     181             :   To know if the global object is valid instead you should use the following function:
+     182             : \verbatim
+     183             :   (C)        plumed_gvalid
+     184             :   (C++)      PLMD::Plumed::gvalid
+     185             :   (FORTRAN)  PLUMED_F_GVALID
+     186             : \endverbatim
+     187             : 
+     188             :   To convert handlers between different languages, use
+     189             : \verbatim
+     190             :   (C)        plumed_c2f                 (C to FORTRAN)
+     191             :   (C)        plumed_f2c                 (FORTRAN to C)
+     192             :   (C++)      Plumed(plumed) constructor (C to C++)
+     193             :   (C++)      operator plumed() cast     (C++ to C)
+     194             :   (C++)      Plumed(char*)  constructor (FORTRAN to C++)
+     195             :   (C++)      toFortran(char*)           (C++ to FORTRAN)
+     196             : \endverbatim
+     197             : 
+     198             :   As of PLUMED 2.5, when using C or C++ we allow a user to explicitly store a plumed object as
+     199             :   a void pointer (indeed: that's the only thing contained in a plumed object).
+     200             :   This might be useful in case you do not want to include the Plumed.h header in some
+     201             :   of your headers. In order to convert to/from void pointers you can use the following functions
+     202             : \verbatim
+     203             :   (C)        plumed_v2c                 (void* to C)
+     204             :   (C)        plumed_c2v                 (C to void*)
+     205             :   (C++)      Plumed(void*) constructor  (void* to C++)
+     206             :   (C++)      toVoid()                   (C++ to void*)
+     207             : \endverbatim
+     208             :   Using the functions above is much safer than accessing directly the pointer contained in the \ref plumed struct
+     209             :   since, when compiling with debug options, it will check if the void pointer actually points to a plumed object.
+     210             : 
+     211             :   As of PLUMED 2.5, we added a reference count. It is in practice possible
+     212             :   to create multiple `plumed` objects that refer to the same environment.
+     213             :   This is done using the following functions
+     214             : \verbatim
+     215             :   (C)        plumed_create_reference     (from a C object)
+     216             :   (C)        plumed_create_reference_f   (from a FORTRAN object)
+     217             :   (C)        plumed_create_reference_v   (from a void pointer)
+     218             :   (FORTRAN)  plumed_f_create_reference   (from a FORTRAN object)
+     219             : \endverbatim
+     220             :   In C++ references are managed automatically by constructors and destructor.
+     221             :   In addition, you can manually manage them (with care!) using incref() and decref().
+     222             : 
+     223             :   The interface of the FORTRAN functions is very similar to that of the C functions
+     224             :   and is listed below:
+     225             : 
+     226             : \verbatim
+     227             :   FORTRAN interface
+     228             :     SUBROUTINE PLUMED_F_CREATE(p)
+     229             :       CHARACTER(LEN=32), INTENT(OUT)   :: p
+     230             :     SUBROUTINE PLUMED_F_CREATE_DLOPEN(p,path)
+     231             :       CHARACTER(LEN=32), INTENT(OUT)   :: p
+     232             :       CHARACTER(LEN=*),  INTENT(IN)    :: path
+     233             :     SUBROUTINE PLUMED_F_CREATE_REFERENCE(p,r)
+     234             :       CHARACTER(LEN=32), INTENT(OUT)   :: p
+     235             :       CHARACTER(LEN=32), INTENT(IN)    :: r
+     236             :     SUBROUTINE PLUMED_F_CREATE_INVALID(p)
+     237             :       CHARACTER(LEN=32), INTENT(OUT)   :: p
+     238             :     SUBROUTINE PLUMED_F_CMD(p,key,val)
+     239             :       CHARACTER(LEN=32), INTENT(IN)    :: p
+     240             :       CHARACTER(LEN=*),  INTENT(IN)    :: key
+     241             :       UNSPECIFIED_TYPE,  INTENT(INOUT) :: val(*)
+     242             :     SUBROUTINE PLUMED_F_FINALIZE(p)
+     243             :       CHARACTER(LEN=32), INTENT(IN)    :: p
+     244             :     SUBROUTINE PLUMED_F_INSTALLED(i)
+     245             :       INTEGER,           INTENT(OUT)   :: i
+     246             :     SUBROUTINE PLUMED_F_VALID(p,i)
+     247             :       CHARACTER(LEN=32), INTENT(IN)    :: p
+     248             :       INTEGER,           INTENT(OUT)   :: i
+     249             :     SUBROUTINE PLUMED_F_USE_COUNT(p,i)
+     250             :       CHARACTER(LEN=32), INTENT(IN)    :: p
+     251             :       INTEGER,           INTENT(OUT)   :: i
+     252             :     SUBROUTINE PLUMED_F_GLOBAL(p)
+     253             :       CHARACTER(LEN=32), INTENT(OUT)   :: p
+     254             :     SUBROUTINE PLUMED_F_GINITIALIZED(i)
+     255             :       INTEGER,           INTENT(OUT)   :: i
+     256             :     SUBROUTINE PLUMED_F_GCREATE()
+     257             :     SUBROUTINE PLUMED_F_GCMD(key,val)
+     258             :       CHARACTER(LEN=*), INTENT(IN)     :: key
+     259             :       UNSPECIFIED_TYPE, INTENT(INOUT)  :: val(*)
+     260             :     SUBROUTINE PLUMED_F_GFINALIZE()
+     261             :     SUBROUTINE PLUMED_F_GVALID(i)
+     262             :       INTEGER,           INTENT(OUT)   :: i
+     263             : \endverbatim
+     264             : 
+     265             :   Almost all C functions have a corresponding FORTRAN function.
+     266             :   As a simple mnemonic, if you know the name of the C function you can obtain the
+     267             :   corresponding FORTRAN subroutine by adding `F_` after the `PLUMED_` prefix.
+     268             :   In addition, all `plumed` objects are replaced by `CHARACTER(LEN=32)` objects
+     269             :   holding the same information. These pointers basically contain a text representation
+     270             :   of the stored pointer, that is suitable to be contained in a string.
+     271             :   Finally, whenever a C function returns a value,
+     272             :   the corresponding FORTRAN subroutine will have an additional `INTENT(OUT)` parameter
+     273             :   passed as the its last argument.
+     274             : 
+     275             :   When you compile the FORTRAN interface, wrapper functions are added with several possible
+     276             :   name manglings, so you should not experience problems linking the plumed library with a FORTRAN file.
+     277             : 
+     278             : \section ReferencePlumedH-exceptions Error handling
+     279             : 
+     280             :   In case an error is detected by PLUMED, either because of some user error, some internal bug,
+     281             :   or some mistake in using the library, an exception will be thrown. The behavior is different depending if you use
+     282             :   PLUMED from C/FORTRAN or from C++.
+     283             : 
+     284             :   First of all, notice that access to PLUMED goes through three functions:
+     285             :   - plumed_create: this, as of PLUMED 2.5, is guaranteed not to throw any exception. If there is a problem, it will
+     286             :     just return a plumed object containing a NULL pointer
+     287             :   - plumed_cmd: this function might throw exceptions.
+     288             :   - plumed_finalize: this is a destructor and is guaranteed not to throw any exception.
+     289             : 
+     290             :   The following discussion concerns all the exceptions thrown by plumed_cmd.
+     291             : 
+     292             :   If you use C/FORTRAN, you will basically have no way to intercept the exception and the program will just terminate.
+     293             : 
+     294             :   If you use C++ and you are calling the C++ interface (e.g. \ref Plumed::cmd), as of PLUMED 2.5 we implemented a complete
+     295             :   remapping of the exceptions thrown by PLUMED.  This solves both the problems mentioned above. In particular:
+     296             :   - Instead of throwing an exception, PLUMED will return (using a \ref plumed_nothrow_handler) the details about the occurred error.
+     297             :   - An equivalent exception will be thrown within the inline PLUMED interface compiled with your MD code.
+     298             : 
+     299             :   As a consequence, you will be able to combine different compilers and avoid stack unwinding in the C layer.
+     300             : 
+     301             :   If you use C++ but you are calling the C interface (e.g. \ref plumed_cmd), then you might be
+     302             :   able to catch the exceptions thrown by PLUMED. Notice that all the exceptions thrown by PLUMED inherit from std::exception,
+     303             :   so you might want to catch it by reference. By default, as of PLUMED 2.8 \ref plumed_cmd is redefined as a macro and directly calls
+     304             :   the \ref Plumed::cmd interface, and thus behaves in an equivalent manner. With previous versions of this header
+     305             :   one could have encountered problems with stack unwinding performed during exception handling in the C layer.
+     306             : 
+     307             :   Notice that, even if you use \ref Plumed::cmd, if you are loading a kernel <=2.4 any exception generated by PLUMED will
+     308             :   leak through the C layer. This might lead to undefined behavior. If you are lucky (with some compiler it works!) and
+     309             :   the exception arrives to C, PLUMED will catch it and rethrow it as it would do if you were using a kernel >=2.5.
+     310             : 
+     311             :   The remapping of exceptions takes care of all the standard C++ exceptions plus all the exceptions raised within
+     312             :   PLUMED. Unexpected exceptions that are derived from std::exception will be rethrown as std::exception.
+     313             :   Notice that this implies some loss of information, since the original exception might have been of a different type.
+     314             :   However, it also implies that the virtual table of the original exception won't be needed anymore. This allows to
+     315             :   completely decouple the MD code from the PLUMED library.
+     316             : 
+     317             : \section ReferencePlumedH-typesafe Typesafe interface
+     318             : 
+     319             :   Starting with PLUMED 2.8, the `cmd` function of the C++ interface, and the similar function `gcmd`, can be called
+     320             :   with several interfaces and can perform a typechecking on the passed argument. In particular, the following
+     321             :   forms are now possible:
+     322             : \verbatim
+     323             :   cmd("string",value);        // by value
+     324             :   cmd("string",&value);       // by pointer
+     325             :   cmd("string",&value,nelem); // by pointer, specifying the number of elements of the passed array
+     326             :   cmd("string",&value,shape); // by pointer, specifying the shape of the passed array
+     327             : \endverbati
+     328             :   The `nelem` and `shape` arguments are used by PLUMED to check that the user
+     329             :   provided enough elements. If nelem is provided, the check is done on the flatten array, whereas if shape
+     330             :   is passed a more thorough check is performed controlling each of the dimensions of the array.
+     331             :   In addition to this, the type of the pointer (or of the value) is checked at runtime.
+     332             : 
+     333             :   All these checks are only implemented if the PLUMED library is recent (>=2.8). However, it will still be
+     334             :   possible to load at runtime an older PLUMED library (<=2.7). For this reason, it is still compulsory
+     335             :   to pass the correct types to the `cmd` function, also when the argument is passed by value.
+     336             :   Type conversions are only performed between pointers and only in ways compatible with
+     337             :   what is allowed in C++ (e.g., `const void*` cannot be converted to `void*`, but `void*` can
+     338             :   be converted to `const void*`).
+     339             : 
+     340             :   Type checkes can be disabled in two ways:
+     341             :   - By compiling `Plumed.h` with `-D__PLUMED_WRAPPER_CXX_TYPESAFE=0`
+     342             :   - By setting `export PLUMED_TYPESAFE_IGNORE=yes` at runtime.
+     343             : 
+     344             :   Typechecks are also enabled in the C interface (plumed_cmd). This function is replaced with a macro by default.
+     345             :   In particular:
+     346             :   - If the C interface is used in C++ code, it calls the C++ interface. Can be disabled with `-D__PLUMED_WRAPPER_CXX_BIND_C=0`.
+     347             :   - If the C interface is used in C code and compiled with a C11 compiler, it uses _Generic to pass type information.
+     348             :     Can be disabled using `-D__PLUMED_WRAPPER_C_TYPESAFE=0`.
+     349             : 
+     350             : \section ReferencePlumedH-2-5 New in PLUMED 2.5
+     351             : 
+     352             :   The wrappers in PLUMED 2.5 have been completely rewritten with several improvements.
+     353             :   The interface is almost perfectly backward compatible, although the behavior of C++ constructors
+     354             :   has been modified slightly.
+     355             :   In addition, a few new functions are introduced (explicitly marked in the documentation).
+     356             :   As a consequence, if your code uses some of the new functions, you will not be able
+     357             :   to link it directly with an older PLUMED library (though you will still be able to load
+     358             :   an older PLUMED library at runtime). In addition, the reference counter changes slightly
+     359             :   the behavior of the C++ methods used to interoperate with C and FORTRAN.
+     360             : 
+     361             :   An important novelty is in the way the runtime loader is implemented.
+     362             :   In particular, the loader works also if the symbols of the main executable are not exported.
+     363             :   The proper functions from the kernel are indeed searched explicitly now using `dlsym`.
+     364             : 
+     365             :   Some additional features can be enabled using suitable environment variables. In particular:
+     366             :   - `PLUMED_LOAD_DEBUG` can be set to report more information about the loading process.
+     367             :   - `PLUMED_LOAD_NAMESPACE` can be set to choose in which namespace PLUMED is loaded when using runtime
+     368             :     loading. As of version 2.10, PLUMED is loaded with RTLD_LOCAL by default. The behavior can be reverted
+     369             :     by exporting `PLUMED_LOAD_NAMESPACE=GLOBAL`. The default setting facilitates loading multiple
+     370             :     versions of PLUMED simultaneously.
+     371             :   - `PLUMED_LOAD_NODEEPBIND` can be set to load the PLUMED kernel in not-deepbind mode. Deepbind
+     372             :     mode implies that the symbols defined in the library are preferred to other symbols with the same name.
+     373             :     Only works on systems supporting `RTLD_DEEPBIND` and is mostly for debugging purposes.
+     374             : 
+     375             :   Another difference is that the implementation of the wrappers is now completely contained in the `Plumed.h`
+     376             :   file. You can see that the `Plumed.c` is much simpler now and just includes `Plumed.h`. With a similar
+     377             :   procedure you could compile the wrappers directly into your code making it unnecessary to link
+     378             :   the libplumedWrapper.a library. The corresponding macros are still subject to change and are not documented here.
+     379             : 
+     380             :   As written above, the plumed object now implements a reference counter.  Consider the following example
+     381             : \verbatim
+     382             :   plumed p=plumed_create();
+     383             :   plumed_cmd(p,"init",NULL);
+     384             :   plumed q=plumed_create_reference(p);
+     385             :   plumed_finalize(p);
+     386             : // at this stage, object q still exists
+     387             :   plumed_cmd(q,"whatever",NULL);
+     388             :   plumed_finalize(q);
+     389             : // now plumed has been really finalized
+     390             : \endverbatim
+     391             : 
+     392             :   In other words, every \ref plumed_create, \ref plumed_create_dlopen, \ref plumed_create_reference,
+     393             :   \ref plumed_create_reference_f, and \ref plumed_create_reference_v call must be matched by a \ref plumed_finalize.
+     394             :   Notice that in C++ whenever an object goes out of scope the reference counter
+     395             :   will be decreased. In addition, consider that conversion from C/FORTRAN/void* to C++ implies calling a C++ constructor, that
+     396             :   is increases the number of references by one. Converting from C++ to C/FORTRAN/void* instead does not call any constructor,
+     397             :   that is the number of references is unchanged.
+     398             : 
+     399             :   The change in the behavior of C++ constructors means that the following code will behave in a backward incompatible manner:
+     400             : \verbatim
+     401             :   plumed p=plumed_create();
+     402             :   plumed_cmd(p,"init",NULL);
+     403             :   Plumed q(p);
+     404             :   plumed_finalize(p);
+     405             : // at this stage, object q still exists with PLUMED 2.5
+     406             : // on the other hand, with PLUMED 2.4 object q refers to an
+     407             : // already finalized object
+     408             :   q.cmd("whatever",NULL);
+     409             : \endverbatim
+     410             : 
+     411             :   Another difference is that the value of the variable `PLUMED_KERNEL` is read every time a new
+     412             :   plumed object is instantiated. So, you might even use it to load different plumed versions
+     413             :   simultaneously, although the preferred way to do this is using the function \ref plumed_create_dlopen.
+     414             :   Notice that if you want to load multiple versions simultaneously you should load them in a local namespace.
+     415             :   \ref plumed_create_dlopen does it automatically, whereas loading through env var `PLUMED_KERNEL` only does it if
+     416             :   you also set env var `PLUMED_NAMESPACE=LOCAL`.
+     417             : 
+     418             :   Finally, a few functions have been added, namely:
+     419             :   - Functions to find if a plumed object is valid
+     420             :     (\ref plumed_valid(), \ref plumed_gvalid(), \ref PLMD::Plumed::valid(), and \ref PLMD::Plumed::gvalid()).
+     421             :   - Functions to create a plumed object based on the path of a specific kernel
+     422             :     (\ref plumed_create_dlopen() and \ref PLMD::Plumed::dlopen()).
+     423             :   - Functions to create a plumed object referencing to another one, implementing a reference counter
+     424             :     (\ref plumed_create_reference(), \ref plumed_create_reference_v(), \ref plumed_create_reference_f().
+     425             : 
+     426             : */
+     427             : 
+     428             : 
+     429             : /* BEGINNING OF DECLARATIONS */
+     430             : 
+     431             : /* SETTING DEFAULT VALUES FOR CONTROL MACROS */
+     432             : 
+     433             : /*
+     434             :   1: make the C wrapper functions extern (default)
+     435             :   0: make the C wrapper functions static (C) or inline (C++)
+     436             : 
+     437             :   If set to zero, it disables all functions that only make sense as extern, such as
+     438             :   Fortran wrappers, global objects, and plumed_kernel_register.
+     439             : 
+     440             :   It can be set to zero to include multiple copies of the wrapper implementation without worrying
+     441             :   about duplicated symbols.
+     442             : 
+     443             :   Notice that C++ wrappers are always inline. What this function controls is if the C wrappers
+     444             :   (called by the C++ wrappers) is inline or not. Also consider that if this header is compiled
+     445             :   with C++ and inline C wrappers, the C wrappers will be actually compiled with C++ linkage
+     446             :   in the root namespace.
+     447             : 
+     448             :   Used both in declarations (to know which functions to declare) and definitions (to know which functions to define).
+     449             : */
+     450             : 
+     451             : #ifndef __PLUMED_WRAPPER_EXTERN
+     452             : #define __PLUMED_WRAPPER_EXTERN 1
+     453             : #endif
+     454             : 
+     455             : /*
+     456             :   1: emit global plumed object and related functions (default)
+     457             :   0: do not emit global plumed object and related functions
+     458             : 
+     459             :   Used both in declarations (to know which functions to declare) and definitions (to know which functions to define).
+     460             : */
+     461             : 
+     462             : #ifndef __PLUMED_WRAPPER_GLOBAL
+     463             : #define __PLUMED_WRAPPER_GLOBAL 1
+     464             : #endif
+     465             : 
+     466             : /*
+     467             :   1: Enable typesafe C interface (default)
+     468             :   0: Disable typesafe C interface
+     469             : 
+     470             :   Only used in declarations. Requires C11 _Generic and variadic macros, and so it is
+     471             :   disabled by default with C++ and pre C11 compilers.
+     472             : 
+     473             :   https://mort.coffee/home/c-compiler-quirks/
+     474             : */
+     475             : 
+     476             : #ifndef __PLUMED_WRAPPER_C_TYPESAFE
+     477             : #  if defined(__STDC_VERSION__)
+     478             : #    if ! defined(__cplusplus) && __STDC_VERSION__ >= 201112L
+     479             : #      if defined(__GNUC__) && !defined(__clang__)
+     480             : #        if (__GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9))
+     481             : #          define __PLUMED_WRAPPER_C_TYPESAFE 1
+     482             : #        endif
+     483             : #      else
+     484             : #        define __PLUMED_WRAPPER_C_TYPESAFE 1
+     485             : #      endif
+     486             : #    endif
+     487             : #  endif
+     488             : #  ifndef __PLUMED_WRAPPER_C_TYPESAFE
+     489             : #    define __PLUMED_WRAPPER_C_TYPESAFE 0
+     490             : #  endif
+     491             : #endif
+     492             : 
+     493             : /*
+     494             :   1: Enable RTLD_DEEPBIND when possible (default)
+     495             :   0: Disable RTLD_DEEPBIND
+     496             : */
+     497             : 
+     498             : #ifndef __PLUMED_WRAPPER_ENABLE_RTLD_DEEPBIND
+     499             : #define __PLUMED_WRAPPER_ENABLE_RTLD_DEEPBIND 1
+     500             : #endif
+     501             : 
+     502             : /*
+     503             :   1: enable C++ wrapper (default)
+     504             :   0: disable C++ wrapper
+     505             : 
+     506             :   Only used in declarations, but affects the scope of the C interface also in definitions.
+     507             : */
+     508             : 
+     509             : #ifndef __PLUMED_WRAPPER_CXX
+     510             : #define __PLUMED_WRAPPER_CXX 1
+     511             : #endif
+     512             : 
+     513             : /*
+     514             :   1: new headers such as cstdlib are included in C++ (default)
+     515             :   0: old headers such as stdlib.h are included in C++
+     516             : 
+     517             :   Should only be set to zero when including the Plumed.h file in a file using the
+     518             :   old (stdlib.h) convention.
+     519             : 
+     520             :   Used both in declarations and definitions.
+     521             : */
+     522             : 
+     523             : #ifndef __PLUMED_WRAPPER_CXX_STD
+     524             : #define __PLUMED_WRAPPER_CXX_STD 1
+     525             : #endif
+     526             : 
+     527             : /*
+     528             :   1: place C++ wrappers in an anonymous namespace
+     529             :   0: place C++ wrappers in the PLMD namespace (default)
+     530             : 
+     531             :   It will make PLMD::Plumed a different class (though with the same name)
+     532             :   in each of the translation units in which `Plumed.h` is included.
+     533             : 
+     534             :   Can be used to completey separate C++ implementations. However, it will make
+     535             :   it impossible to transfer Plumed objects between different translation units
+     536             :   without converting to a void* or plumed object.
+     537             : 
+     538             :   Only used in declarations, but affects the scope of the C interface also in definitions.
+     539             : */
+     540             : 
+     541             : #ifndef __PLUMED_WRAPPER_CXX_ANONYMOUS_NAMESPACE
+     542             : #define __PLUMED_WRAPPER_CXX_ANONYMOUS_NAMESPACE 0
+     543             : #endif
+     544             : 
+     545             : 
+     546             : /*
+     547             :   1: throw exceptions such as PLMD::Exception
+     548             :   0: throw exceptions such as PLMD::Plumed::Exception (default)
+     549             : 
+     550             :   This is useful when including Plumed.h within the plumed library
+     551             :   in anonymous mode, to make sure that the exception types from the
+     552             :   library are used.
+     553             : */
+     554             : #ifndef __PLUMED_WRAPPER_CXX_ANONYMOUS_NAMESPACE_PLMD_EXCEPTIONS
+     555             : #define __PLUMED_WRAPPER_CXX_ANONYMOUS_NAMESPACE_PLMD_EXCEPTIONS 0
+     556             : #endif
+     557             : 
+     558             : /*
+     559             :   1: make PLMD::Plumed class polymorphic (default)
+     560             :   0: make PLMD::Plumed class non-polymorphic
+     561             : 
+     562             :   Only used in declarations.
+     563             : */
+     564             : 
+     565             : #ifndef __PLUMED_WRAPPER_CXX_POLYMORPHIC
+     566             : #define __PLUMED_WRAPPER_CXX_POLYMORPHIC 1
+     567             : #endif
+     568             : 
+     569             : /*
+     570             :   1: Enable typesafe interface (default)
+     571             :   0: Disable typesafe interface
+     572             : 
+     573             :   Only used in declarations.
+     574             : */
+     575             : 
+     576             : #ifndef __PLUMED_WRAPPER_CXX_TYPESAFE
+     577             : #define __PLUMED_WRAPPER_CXX_TYPESAFE 1
+     578             : #endif
+     579             : 
+     580             : /*
+     581             :   1: Define macros plumed_cmd and plumed_gcmd to use the C++ interface (default).
+     582             :   0: Don't define macros plumed_cmd and plumed_gcmd.
+     583             : 
+     584             :   Only used in declarations.
+     585             : */
+     586             : 
+     587             : #ifndef __PLUMED_WRAPPER_CXX_BIND_C
+     588             : #define __PLUMED_WRAPPER_CXX_BIND_C 1
+     589             : #endif
+     590             : 
+     591             : /*
+     592             :   1: Enable passing long long int
+     593             :   0: Disable passing long long int
+     594             : 
+     595             :   Only used in declarations. Default is 0 in C++<11 and 1 in C++>=11
+     596             : */
+     597             : 
+     598             : #ifndef __PLUMED_WRAPPER_CXX_LONGLONG
+     599             : #if __cplusplus > 199711L
+     600             : #define __PLUMED_WRAPPER_CXX_LONGLONG 1
+     601             : #else
+     602             : #define __PLUMED_WRAPPER_CXX_LONGLONG 0
+     603             : #endif
+     604             : #endif
+     605             : 
+     606             : /*
+     607             :   1: make the default constructor create an invalid object
+     608             :   0: make the default constructor create a valid object
+     609             : 
+     610             :   Only for internal usage.
+     611             : */
+     612             : #ifndef __PLUMED_WRAPPER_CXX_DEFAULT_INVALID
+     613             : #define __PLUMED_WRAPPER_CXX_DEFAULT_INVALID 0
+     614             : #endif
+     615             : 
+     616             : /*
+     617             :   Size of a buffer used to store message for exceptions with noexcept constructor.
+     618             :   Should typically hold short messages. Anyway, as long as the stack size stays within the correct
+     619             :   limits it does not seem to affect efficiency. Notice that there cannot be recursive calls of
+     620             :   PLMD::Plumed::cmd, so that it should be in practice irrelevant.
+     621             : */
+     622             : #ifndef __PLUMED_WRAPPER_CXX_EXCEPTION_BUFFER
+     623             : #define __PLUMED_WRAPPER_CXX_EXCEPTION_BUFFER 512
+     624             : #endif
+     625             : 
+     626             : /*
+     627             :   1: enable nested exceptions (only with C++11) (default)
+     628             :   0: disable nested exceptions
+     629             : 
+     630             :   For internal testing, used to mimic pre C++11 behavior on
+     631             :   nested exception.
+     632             : 
+     633             :   Only used in declarations.
+     634             : */
+     635             : 
+     636             : #ifndef __PLUMED_WRAPPER_CXX_ENABLE_NESTED_EXCEPTIONS
+     637             : #define __PLUMED_WRAPPER_CXX_ENABLE_NESTED_EXCEPTIONS 1
+     638             : #endif
+     639             : 
+     640             : /*
+     641             :  By default, assume C++11 compliant library is not available.
+     642             : */
+     643             : 
+     644             : #ifndef __PLUMED_WRAPPER_LIBCXX11
+     645             : #define __PLUMED_WRAPPER_LIBCXX11 0
+     646             : #endif
+     647             : 
+     648             : /*
+     649             :  By default, assume C++17 compliant library is not available.
+     650             : */
+     651             : 
+     652             : #ifndef __PLUMED_WRAPPER_LIBCXX17
+     653             : #define __PLUMED_WRAPPER_LIBCXX17 0
+     654             : #endif
+     655             : 
+     656             : /* The following macros are just to define shortcuts */
+     657             : 
+     658             : /* Simplify addition of extern "C" blocks.  */
+     659             : #ifdef __cplusplus
+     660             : #define __PLUMED_WRAPPER_EXTERN_C_BEGIN extern "C" {
+     661             : #define __PLUMED_WRAPPER_EXTERN_C_END }
+     662             : #else
+     663             : #define __PLUMED_WRAPPER_EXTERN_C_BEGIN
+     664             : #define __PLUMED_WRAPPER_EXTERN_C_END
+     665             : #endif
+     666             : 
+     667             : /* Without C++, stdlib functions should not be prepended with ::std:: */
+     668             : #ifndef __cplusplus
+     669             : #undef __PLUMED_WRAPPER_CXX_STD
+     670             : #define __PLUMED_WRAPPER_CXX_STD 0
+     671             : #endif
+     672             : 
+     673             : /* Set prefix for stdlib functions */
+     674             : #if __PLUMED_WRAPPER_CXX_STD
+     675             : #define __PLUMED_WRAPPER_STD ::std::
+     676             : #else
+     677             : #define __PLUMED_WRAPPER_STD
+     678             : #endif
+     679             : 
+     680             : /* Allow using noexcept, explicit, and override with C++11 compilers */
+     681             : #ifdef __cplusplus /*{*/
+     682             : #if __cplusplus > 199711L
+     683             : #define __PLUMED_WRAPPER_CXX_NOEXCEPT noexcept
+     684             : #define __PLUMED_WRAPPER_CXX_NORETURN [[ noreturn ]]
+     685             : #define __PLUMED_WRAPPER_CXX_EXPLICIT explicit
+     686             : #define __PLUMED_WRAPPER_CXX_OVERRIDE override
+     687             : #define __PLUMED_WRAPPER_CXX_NULLPTR  nullptr
+     688             : #else
+     689             : #define __PLUMED_WRAPPER_CXX_NOEXCEPT throw()
+     690             : #define __PLUMED_WRAPPER_CXX_NORETURN
+     691             : #define __PLUMED_WRAPPER_CXX_EXPLICIT
+     692             : #define __PLUMED_WRAPPER_CXX_OVERRIDE
+     693             : #define __PLUMED_WRAPPER_CXX_NULLPTR  NULL
+     694             : #endif
+     695             : #else
+     696             : #define __PLUMED_WRAPPER_CXX_NOEXCEPT
+     697             : #define __PLUMED_WRAPPER_CXX_NORETURN
+     698             : #define __PLUMED_WRAPPER_CXX_EXPLICIT
+     699             : #define __PLUMED_WRAPPER_CXX_OVERRIDE
+     700             : #define __PLUMED_WRAPPER_CXX_NULLPTR  NULL
+     701             : #endif /*}*/
+     702             : 
+     703             : /* static inline, for to avoid compiler warnings */
+     704             : #if defined(__cplusplus) || __STDC_VERSION__>=199901L
+     705             : #define __PLUMED_WRAPPER_STATIC_INLINE static inline
+     706             : #else
+     707             : #define __PLUMED_WRAPPER_STATIC_INLINE static
+     708             : #endif
+     709             : 
+     710             : /* Macros for anonymous namespace */
+     711             : #if __PLUMED_WRAPPER_CXX_ANONYMOUS_NAMESPACE && defined(__cplusplus) /*{*/
+     712             : #define __PLUMED_WRAPPER_ANONYMOUS_BEGIN namespace {
+     713             : #define __PLUMED_WRAPPER_ANONYMOUS_END }
+     714             : #else
+     715             : #define __PLUMED_WRAPPER_ANONYMOUS_BEGIN
+     716             : #define __PLUMED_WRAPPER_ANONYMOUS_END
+     717             : #endif /*}*/
+     718             : 
+     719             : #if __PLUMED_WRAPPER_EXTERN /*{*/
+     720             : 
+     721             : #define __PLUMED_WRAPPER_C_BEGIN __PLUMED_WRAPPER_EXTERN_C_BEGIN extern
+     722             : #define __PLUMED_WRAPPER_C_END __PLUMED_WRAPPER_EXTERN_C_END
+     723             : #define __PLUMED_WRAPPER_INTERNALS_BEGIN __PLUMED_WRAPPER_EXTERN_C_BEGIN static
+     724             : #define __PLUMED_WRAPPER_INTERNALS_END __PLUMED_WRAPPER_EXTERN_C_END
+     725             : 
+     726             : #else
+     727             : 
+     728             : #ifdef __cplusplus
+     729             : #define __PLUMED_WRAPPER_C_BEGIN  __PLUMED_WRAPPER_ANONYMOUS_BEGIN inline
+     730             : #define __PLUMED_WRAPPER_C_END __PLUMED_WRAPPER_ANONYMOUS_END
+     731             : #else
+     732             : #define __PLUMED_WRAPPER_C_BEGIN __PLUMED_WRAPPER_STATIC_INLINE
+     733             : #define __PLUMED_WRAPPER_C_END
+     734             : #endif
+     735             : 
+     736             : #define __PLUMED_WRAPPER_INTERNALS_BEGIN __PLUMED_WRAPPER_C_BEGIN
+     737             : #define __PLUMED_WRAPPER_INTERNALS_END __PLUMED_WRAPPER_C_END
+     738             : 
+     739             : /* with an not-external interface, it does not make sense to define global functions */
+     740             : #undef __PLUMED_WRAPPER_GLOBAL
+     741             : #define __PLUMED_WRAPPER_GLOBAL 0
+     742             : 
+     743             : #endif /*}*/
+     744             : 
+     745             : #if __PLUMED_WRAPPER_CXX_STD
+     746             : #include <cstddef> /* size_t */
+     747             : #include <cstring> /* memcpy */
+     748             : #include <cstdio> /* fprintf */
+     749             : #include <cstdlib> /* abort */
+     750             : #include <cassert> /* assert */
+     751             : #else
+     752             : #include <stddef.h>
+     753             : #include <string.h>
+     754             : #include <stdio.h> /* FILE and fprintf */
+     755             : #include <stdlib.h> /* abort */
+     756             : #include <limits.h> /* CHAR_MIN */
+     757             : #include <assert.h> /* assert */
+     758             : #endif
+     759             : 
+     760             : /**
+     761             :   This is an internal tool, to make sure that all malloc calls inside the
+     762             :   plumed library refer to the same implementation. When compiling with
+     763             :   __PLUMED_WRAPPER_DEBUG_REFCOUNT=1 it is possible to log
+     764             :   allocations and deallocations, so as to debug the wrappers.
+     765             : */
+     766             : __PLUMED_WRAPPER_C_BEGIN
+     767             : void* plumed_malloc(__PLUMED_WRAPPER_STD size_t size);
+     768             : __PLUMED_WRAPPER_C_END
+     769             : 
+     770             : /**
+     771             :   This is an internal tool, to make sure that all free calls inside the
+     772             :   plumed library refer to the same implementation. When compiling with
+     773             :   __PLUMED_WRAPPER_DEBUG_REFCOUNT=1 it is possible to log
+     774             :   allocations and deallocations, so as to debug the wrappers.
+     775             : */
+     776             : __PLUMED_WRAPPER_C_BEGIN
+     777             : void plumed_free(void* ptr);
+     778             : __PLUMED_WRAPPER_C_END
+     779             : 
+     780             : /**
+     781             :   \brief Main plumed object
+     782             : 
+     783             :   This is an object containing a Plumed instance, which should be used in
+     784             :   the MD engine. It should first be initialized with plumed_create(),
+     785             :   then it communicates with the MD engine using plumed_cmd(). Finally,
+     786             :   before the termination, it should be deallocated with plumed_finalize().
+     787             :   Its interface is very simple and general, and is expected
+     788             :   not to change across plumed versions. See \ref ReferencePlumedH.
+     789             : */
+     790             : typedef struct {
+     791             :   /**
+     792             :     \private
+     793             :     \brief Void pointer holding the real PlumedMain structure
+     794             : 
+     795             :     To maintain binary compatibility, we should not add members to this structure.
+     796             :     As of PLUMED 2.5, in order to add new components we do not store the pointer
+     797             :     to \ref PlumedMain here but rather a pointer to an intermediate private structure
+     798             :     that contains all the details.
+     799             :   */
+     800             :   void*p;
+     801             : } plumed;
+     802             : 
+     803             : typedef struct {
+     804             :   void* ptr;
+     805             :   void (*handler)(void*,int,const char*,const void*);
+     806             : } plumed_nothrow_handler;
+     807             : 
+     808             : /** \relates plumed
+     809             :     \brief Structure holding a typesafe pointer.
+     810             : */
+     811             : 
+     812             : typedef struct {
+     813             :   /** Pointer to data */
+     814             :   const void* ptr;
+     815             :   /** Number of elements (in case pointing to an array) */
+     816             :   __PLUMED_WRAPPER_STD size_t nelem;
+     817             :   /** Shape (scanned up to a zero value is found) */
+     818             :   const __PLUMED_WRAPPER_STD size_t* shape;
+     819             :   /**
+     820             :     sum of:
+     821             :     sizeof(pointed data), up to 0x10000 (65536). 0 means size not checked
+     822             :     0x10000    * data type, up to 0xff (255)
+     823             :                0 not typechecked
+     824             :                1 void
+     825             :                2 nullptr
+     826             :                3 integral
+     827             :                4 floating point
+     828             :                5 FILE (size will not be computed as it might be incomplete)
+     829             :                >5 not typechecked, reserved for future extensions
+     830             :     0x1000000  * 1 for unsigned (ignored)
+     831             :     0x2000000  * pointer/const type, up to 8
+     832             :                0 not typechecked
+     833             :                1 T (pass-by-value)
+     834             :                2 T       *
+     835             :                3 T const *
+     836             :                4 T       *       *
+     837             :                5 T       * const *
+     838             :                6 T const *       *
+     839             :                7 T const * const *
+     840             :     0x10000000 * 1 to forbid pointer copy (pointer copy is also forbidden for pass-by-value)
+     841             :     0x20000000 and higher bits are ignored, reserved for future extensions
+     842             :   */
+     843             :   __PLUMED_WRAPPER_STD size_t flags;
+     844             :   /** Optional information, not used yet  */
+     845             :   const void* opt;
+     846             : } plumed_safeptr;
+     847             : 
+     848             : /* local structure */
+     849             : typedef struct plumed_error_filesystem_path {
+     850             :   __PLUMED_WRAPPER_STD size_t numbytes;
+     851             :   void* ptr;
+     852             : } plumed_error_filesystem_path;
+     853             : 
+     854             : /**
+     855             :   Small structure that is only defined locally to retrieve errors.
+     856             : 
+     857             :   It is supposed to be used in the C11/C++ plumed_cmd interface as follows:
+     858             : \verbatim
+     859             :   plumed p;
+     860             :   plumed_error error;
+     861             : 
+     862             :   p=plumed_create();
+     863             : 
+     864             :   plumed_cmd(p,"setNatoms",10,&error);
+     865             :   if(error.code) {
+     866             :     fprintf(errors,"%d\n",error.code);
+     867             :     plumed_error_finalize(error); // make sure the error object is finalized!
+     868             :   }
+     869             :   // if no error was raised (error.code==0), it is not necessary to call plumed_error_finalize.
+     870             :   // but doing it is harmless
+     871             : 
+     872             :   // no need to initialize error, it is written in the plumed_cmd function
+     873             :   plumed_cmd(p,"init",&error);
+     874             :   if(error.code) {
+     875             :     fprintf(errors,"%d\n",error.code);
+     876             :     plumed_error_finalize(error); // make sure the error object is finalized!
+     877             :   }
+     878             : \endverbatim
+     879             : 
+     880             :   The layout of this structure is subject to change, thus all the functions manipulating it
+     881             :   are defined as inline/static functions. In the future, we might reach some form
+     882             :   of ABI stability, and these functions might be moved below to the implementation
+     883             :   file.
+     884             : 
+     885             :   Notice that there is a macro plumed_error() defined in the PLUMED source code
+     886             :   (at tools/Exception.h). There is no conflict with this type since C preprocessor
+     887             :   distinguishes macros and function-like macros.
+     888             : */
+     889             : typedef struct plumed_error {
+     890             :   /** code used for translating messages */
+     891             :   int code;
+     892             :   /** error code for system_error */
+     893             :   int error_code;
+     894             :   /** category - for errors */
+     895             :   int error_category;
+     896             :   /** path1 - for filesystem_error */
+     897             :   plumed_error_filesystem_path path1;
+     898             :   /** path2 - for filesystem_error */
+     899             :   plumed_error_filesystem_path path2;
+     900             :   /** message */
+     901             :   const char* what;
+     902             :   /** the buffer containing the message to be deallocated */
+     903             :   char* what_buffer;
+     904             :   /** pointer to nested exception */
+     905             :   struct plumed_error* nested;
+     906             : } plumed_error;
+     907             : 
+     908             : /** Initialize error (for internal usage) */
+     909             : __PLUMED_WRAPPER_STATIC_INLINE void plumed_error_init(plumed_error* error) __PLUMED_WRAPPER_CXX_NOEXCEPT {
+     910             :   assert(error);
+     911       15686 :   error->code=0;
+     912       15686 :   error->error_code=0;
+     913       15686 :   error->error_category=0;
+     914       15686 :   error->path1.numbytes=0;
+     915       15686 :   error->path1.ptr=__PLUMED_WRAPPER_CXX_NULLPTR;
+     916       15686 :   error->path2.numbytes=0;
+     917       15686 :   error->path2.ptr=__PLUMED_WRAPPER_CXX_NULLPTR;
+     918       15686 :   error->what=__PLUMED_WRAPPER_CXX_NULLPTR;
+     919       15686 :   error->what_buffer=__PLUMED_WRAPPER_CXX_NULLPTR;
+     920       15686 :   error->nested=__PLUMED_WRAPPER_CXX_NULLPTR;
+     921             : }
+     922             : 
+     923             : /** Finalize error - should be called when an error is raised to avoid leaks */
+     924             : /* cppcheck-suppress passedByValue */
+     925           0 : __PLUMED_WRAPPER_STATIC_INLINE void plumed_error_finalize(plumed_error error) __PLUMED_WRAPPER_CXX_NOEXCEPT {
+     926           0 :   if(!error.code) return;
+     927           0 :   if(error.nested) {
+     928           0 :     plumed_error_finalize(*error.nested);
+     929           0 :     plumed_free(error.nested);
+     930             :   }
+     931           0 :   if(error.path1.ptr) {
+     932           0 :     plumed_free(error.path1.ptr);
+     933             :   }
+     934           0 :   if(error.path2.ptr) {
+     935           0 :     plumed_free(error.path2.ptr);
+     936             :   }
+     937           0 :   if(error.what_buffer) {
+     938           0 :     plumed_free(error.what_buffer);
+     939             :   }
+     940             : }
+     941             : 
+     942             : /** Access message - more robust than directly accessing what ptr, for future extensibility */
+     943             : /* cppcheck-suppress passedByValue */
+     944             : __PLUMED_WRAPPER_STATIC_INLINE const char* plumed_error_what(plumed_error error) __PLUMED_WRAPPER_CXX_NOEXCEPT {
+     945             :   return error.what;
+     946             : }
+     947             : 
+     948             : /** Set error to bad_alloc (for internal usage).
+     949             :     At variance with plumed_error_init, it also finalizes the error, possibly
+     950             :     deallocating any buffer.
+     951             : */
+     952           0 : __PLUMED_WRAPPER_STATIC_INLINE void plumed_error_set_bad_alloc(plumed_error*error) {
+     953             :   assert(error);
+     954           0 :   plumed_error_finalize(*error);
+     955             :   plumed_error_init(error);
+     956           0 :   error->what="[msg erased due to allocation failure]";
+     957           0 :   error->code=11400;
+     958           0 : }
+     959             : 
+     960             : /** Recursive merge (for internal usage) */
+     961             : __PLUMED_WRAPPER_STATIC_INLINE void plumed_error_recursive_merge(plumed_error* error,char*buffer,const char*join,__PLUMED_WRAPPER_STD size_t*len) __PLUMED_WRAPPER_CXX_NOEXCEPT {
+     962             :   if(error->nested) plumed_error_recursive_merge(error->nested,buffer,join,len);
+     963             :   __PLUMED_WRAPPER_STD strncat(buffer,plumed_error_what(*error),*len);
+     964             :   *len -= __PLUMED_WRAPPER_STD strlen(plumed_error_what(*error));
+     965             :   __PLUMED_WRAPPER_STD strncat(buffer,join,*len);
+     966             :   *len -= __PLUMED_WRAPPER_STD strlen(join);
+     967             : }
+     968             : 
+     969             : /** Merge with nested exceptions */
+     970             : __PLUMED_WRAPPER_STATIC_INLINE void plumed_error_merge_with_nested(plumed_error* error) __PLUMED_WRAPPER_CXX_NOEXCEPT {
+     971             :   __PLUMED_WRAPPER_STD size_t len;
+     972             :   __PLUMED_WRAPPER_STD size_t len_join;
+     973             :   /* The is temporarily holding the new message */
+     974             :   char* new_buffer;
+     975             :   /* This is the string used to concatenate messages */
+     976             :   const char* join="\n\nThe above exception was the direct cause of the following exception:\n";
+     977             :   /* This is used to iterate over the linked list of nested exceptions */
+     978             :   plumed_error*e;
+     979             : 
+     980             :   /* If exception is not nested, nothing to do */
+     981             :   if(!error->nested) return;
+     982             : 
+     983             :   /* Accumulate the total length of the concatenated message */
+     984             :   len_join=__PLUMED_WRAPPER_STD strlen(join);
+     985             :   e=error;
+     986             :   len=__PLUMED_WRAPPER_STD strlen(plumed_error_what(*e));
+     987             :   while(e->nested) {
+     988             :     e=e->nested;
+     989             :     len+=len_join+__PLUMED_WRAPPER_STD strlen(plumed_error_what(*e));
+     990             :   }
+     991             : 
+     992             :   /* Allocate the new message */
+     993             :   new_buffer=(char*)plumed_malloc(len+1);
+     994             :   if(new_buffer) {
+     995             :     /* If allocation was successful, merge the messages */
+     996             :     new_buffer[0]='\0';
+     997             :     /* Notice that we have a forward linked list but we need to go through that in backward order
+     998             :        (inner to outer). To do that without allocating an additional array, we use a recursive
+     999             :        function.
+    1000             :     */
+    1001             :     assert(error->nested);
+    1002             :     plumed_error_recursive_merge(error->nested,new_buffer,join,&len);
+    1003             :     __PLUMED_WRAPPER_STD strncat(new_buffer,plumed_error_what(*error),len);
+    1004             :     len -= __PLUMED_WRAPPER_STD strlen(plumed_error_what(*error));
+    1005             :     /* we keep track of length of buffer for safety */
+    1006             :     assert(len==0);
+    1007             :   }
+    1008             :   error->what=new_buffer;
+    1009             : 
+    1010             :   /* Deallocate the previous message */
+    1011             :   if(error->what_buffer) plumed_free(error->what_buffer);
+    1012             :   error->what_buffer=new_buffer;
+    1013             : 
+    1014             :   /* Finalize the chain of nested exceptions */
+    1015             :   plumed_error_finalize(*error->nested);
+    1016             :   plumed_free(error->nested);
+    1017             :   error->nested=__PLUMED_WRAPPER_CXX_NULLPTR;
+    1018             : 
+    1019             :   if(!error->what) {
+    1020             :     /* If allocation was not successful, reset to bad_alloc */
+    1021             :     plumed_error_set_bad_alloc(error);
+    1022             :   }
+    1023             : }
+    1024             : 
+    1025             : /** Rethrow error (calling abort) */
+    1026             : __PLUMED_WRAPPER_CXX_NORETURN __PLUMED_WRAPPER_STATIC_INLINE void plumed_error_rethrow(plumed_error h) {
+    1027             :   if(h.nested) plumed_error_merge_with_nested(&h);
+    1028             :   __PLUMED_WRAPPER_STD fprintf(stderr,"Terminate due to exception. Code: %d\n%s\n",h.code,plumed_error_what(h));
+    1029             :   __PLUMED_WRAPPER_STD abort();
+    1030             : }
+    1031             : 
+    1032             : /** Callback (for internal usage) */
+    1033           0 : __PLUMED_WRAPPER_STATIC_INLINE void plumed_error_set(void*ptr,int code,const char*what,const void* opt) __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    1034             :   plumed_error* error;
+    1035             :   __PLUMED_WRAPPER_STD size_t len;
+    1036             :   void*const* options;
+    1037             :   plumed_error_filesystem_path path;
+    1038             : 
+    1039             :   error=(plumed_error*) ptr;
+    1040             : 
+    1041           0 :   error->code=code;
+    1042           0 :   error->error_code=0;
+    1043           0 :   len=__PLUMED_WRAPPER_STD strlen(what);
+    1044           0 :   error->what_buffer=(char*) plumed_malloc(len+1);
+    1045           0 :   if(!error->what_buffer) {
+    1046           0 :     plumed_error_set_bad_alloc(error);
+    1047           0 :     return;
+    1048             :   }
+    1049             : 
+    1050             :   __PLUMED_WRAPPER_STD strncpy(error->what_buffer,what,len+1);
+    1051           0 :   error->what=error->what_buffer;
+    1052             : 
+    1053             :   /* interpret optional arguments */
+    1054           0 :   if(opt) {
+    1055             :     options=(void*const*)opt;
+    1056           0 :     while(*options) {
+    1057             :       /* c: error code */
+    1058           0 :       if(*((const char*)*options)=='c' && *(options+1)) {
+    1059           0 :         error->error_code=*((const int*)*(options+1));
+    1060           0 :         break;
+    1061             :       }
+    1062           0 :       options+=2;
+    1063             :     }
+    1064             : 
+    1065             :     options=(void*const*)opt;
+    1066           0 :     while(*options) {
+    1067             :       /* C: error_category */
+    1068           0 :       if(*((const char*)*options)=='C' && *(options+1)) {
+    1069           0 :         error->error_category=*((const int*)*(options+1));
+    1070           0 :         break;
+    1071             :       }
+    1072           0 :       options+=2;
+    1073             :     }
+    1074             : 
+    1075             :     options=(void*const*)opt;
+    1076           0 :     while(*options) {
+    1077             :       /* path 1 */
+    1078           0 :       if(*((const char*)*options)=='p' && *(options+1)) {
+    1079           0 :         path=*(plumed_error_filesystem_path*)*(options+1);
+    1080           0 :         error->path1.ptr=plumed_malloc(path.numbytes);
+    1081           0 :         if(!error->path1.ptr) {
+    1082           0 :           plumed_error_set_bad_alloc(error);
+    1083           0 :           return;
+    1084             :         }
+    1085           0 :         error->path1.numbytes=path.numbytes;
+    1086             :         __PLUMED_WRAPPER_STD memcpy(error->path1.ptr,path.ptr,path.numbytes);
+    1087             :         break;
+    1088             :       }
+    1089           0 :       options+=2;
+    1090             :     }
+    1091             : 
+    1092             :     options=(void*const*)opt;
+    1093           0 :     while(*options) {
+    1094             :       /* path 2 */
+    1095           0 :       if(*((const char*)*options)=='q' && *(options+1)) {
+    1096           0 :         path=*(plumed_error_filesystem_path*)*(options+1);
+    1097           0 :         error->path2.ptr=plumed_malloc(path.numbytes);
+    1098           0 :         if(!error->path2.ptr) {
+    1099           0 :           plumed_error_set_bad_alloc(error);
+    1100           0 :           return;
+    1101             :         }
+    1102           0 :         error->path2.numbytes=path.numbytes;
+    1103             :         __PLUMED_WRAPPER_STD memcpy(error->path2.ptr,path.ptr,path.numbytes);
+    1104             :         break;
+    1105             :       }
+    1106           0 :       options+=2;
+    1107             :     }
+    1108             : 
+    1109             :     options=(void*const*)opt;
+    1110           0 :     while(*options) {
+    1111             :       /* n: nested exception */
+    1112           0 :       if(*((const char*)*options)=='n' && *(options+1)) {
+    1113             :         /* notice that once this is allocated it is guaranteed to be deallocated by the recursive destructor */
+    1114           0 :         error->nested=(plumed_error*) plumed_malloc(sizeof(plumed_error));
+    1115             :         /* this is if malloc fails */
+    1116           0 :         if(!error->nested) {
+    1117           0 :           plumed_error_set_bad_alloc(error);
+    1118           0 :           break;
+    1119             :         }
+    1120             :         plumed_error_init((plumed_error*)error->nested);
+    1121             :         /* plumed will make sure to only use this if it is not null */
+    1122           0 :         *(void**)*(options+1)=error->nested;
+    1123           0 :         break;
+    1124             :       }
+    1125           0 :       options+=2;
+    1126             :     }
+    1127             :   }
+    1128             : }
+    1129             : 
+    1130             : /** \relates plumed
+    1131             :     \brief Constructor
+    1132             : 
+    1133             :     Constructs a plumed object.
+    1134             : 
+    1135             :     Notice that if you are linking against libplumedWrapper.a, if you are
+    1136             :     using a code patched in runtime mode, or if you are including the `Plumed.c`
+    1137             :     file directly in your code, this constructor might return an invalid plumed
+    1138             :     object. In particular, this could happen if the `PLUMED_KERNEL` environment
+    1139             :     variable is not set or set incorrectly. In order to detect an incorrect
+    1140             :     plumed object you might use \ref plumed_valid() on the resulting object.
+    1141             :     Alternatively, if you use \ref plumed_cmd() on an invalid plumed object the code will exit.
+    1142             :     Also notice that to avoid memory leaks you should call \ref plumed_finalize()
+    1143             :     to finalize a plumed object even if it is invalid:
+    1144             : \verbatim
+    1145             :   plumed p=plumed_create();
+    1146             :   if(!plumed_valid(p)) {
+    1147             : // this will happen if the PLUMED_KERNEL variable is not set correctly
+    1148             :     plumed_finalize(p);
+    1149             :     return whatever;
+    1150             :   }
+    1151             : \endverbatim
+    1152             : 
+    1153             :     \return The constructed plumed object
+    1154             : */
+    1155             : __PLUMED_WRAPPER_C_BEGIN
+    1156             : plumed plumed_create(void);
+    1157             : __PLUMED_WRAPPER_C_END
+    1158             : 
+    1159             : /** \relates plumed
+    1160             :     \brief Constructor from path. Available as of PLUMED 2.5
+    1161             : 
+    1162             :     It tries to construct a plumed object loading the kernel located at path.
+    1163             :     Notice that it could leave the resulting object in an invalid state.
+    1164             :     In order to detect an invalid
+    1165             :     plumed object you might use \ref plumed_valid() on the resulting object.
+    1166             :     Alternatively, if you use \ref plumed_cmd() on an invalid plumed object the code will exit.
+    1167             : 
+    1168             :     Also notice that to avoid memory leaks you should call \ref plumed_finalize()
+    1169             :     to finalize a plumed object even if it is invalid.
+    1170             : \verbatim
+    1171             :   plumed p=plumed_create(path);
+    1172             :   if(!plumed_valid(p)) {
+    1173             : // this will happen if the path argument is not set correctly
+    1174             :     plumed_finalize(p);
+    1175             :     return whatever;
+    1176             :   }
+    1177             : \endverbatim
+    1178             : 
+    1179             :     \return The constructed plumed object
+    1180             : */
+    1181             : __PLUMED_WRAPPER_C_BEGIN
+    1182             : plumed plumed_create_dlopen(const char*path);
+    1183             : __PLUMED_WRAPPER_C_END
+    1184             : 
+    1185             : 
+    1186             : /**
+    1187             :   \brief Constructor from path. Available as of PLUMED 2.5
+    1188             : 
+    1189             :   Same as \ref plumed_create_dlopen, but also allows to specify the mode for dlopen.
+    1190             : 
+    1191             :   \warning
+    1192             :   Use with care, since not all the possible modes work correctly with PLUMED.
+    1193             : */
+    1194             : __PLUMED_WRAPPER_C_BEGIN
+    1195             : plumed plumed_create_dlopen2(const char*path,int mode);
+    1196             : __PLUMED_WRAPPER_C_END
+    1197             : 
+    1198             : /**
+    1199             :   \brief Constructor from dlopen handle. Available as of PLUMED 2.8
+    1200             : 
+    1201             :   Same as  \ref plumed_create_dlopen, but it acts on an already loaded library.
+    1202             :   This allows to separate the library loading from the construction of the
+    1203             :   plumed object. By using this function, the caller takes the responsibility
+    1204             :   to later use dlclose on this handle.
+    1205             : */
+    1206             : __PLUMED_WRAPPER_C_BEGIN
+    1207             : plumed plumed_create_dlsym(void* dlhandle);
+    1208             : __PLUMED_WRAPPER_C_END
+    1209             : 
+    1210             : /** \relates plumed
+    1211             :     Create a new reference to an existing object, increasing its reference count. Available as of PLUMED 2.5
+    1212             : 
+    1213             :     Use it to increase by one the reference count of a plumed object.
+    1214             :     The resulting pointer might be identical to the one passed as an
+    1215             :     argument, but the reference count will be incremented by one.
+    1216             :     Notice that you should finalize the resulting object.
+    1217             : \verbatim
+    1218             :   plumed p1;
+    1219             :   plumed p2;
+    1220             :   p1=plumed_create();
+    1221             :   p2=plumed_create_reference(p1);
+    1222             :   plumed_finalize(p1);
+    1223             : // now you can still use p2
+    1224             :   plumed_cmd(p2,"init",NULL);
+    1225             :   plumed_finalize(p2);
+    1226             : // now the underlying object is destroyed.
+    1227             : \endverbatim
+    1228             : 
+    1229             :     If the `p` object is invalid, also the returned object will be invalid.
+    1230             : 
+    1231             :     \param p The plumed object that will be referenced to.
+    1232             :     \return The constructed plumed object
+    1233             : */
+    1234             : 
+    1235             : __PLUMED_WRAPPER_C_BEGIN
+    1236             : plumed plumed_create_reference(plumed p);
+    1237             : __PLUMED_WRAPPER_C_END
+    1238             : 
+    1239             : /** \relates plumed
+    1240             :     \brief Create a new reference to an existing object passed as a void pointer, increasing its reference count. Available as of PLUMED 2.5
+    1241             : 
+    1242             :   \return The constructed plumed object
+    1243             : */
+    1244             : 
+    1245             : __PLUMED_WRAPPER_C_BEGIN
+    1246             : plumed plumed_create_reference_v(void*v);
+    1247             : __PLUMED_WRAPPER_C_END
+    1248             : 
+    1249             : /** \relates plumed
+    1250             :     \brief Create a new reference to an existing object passed as a fortran string, increasing its reference count. Available as of PLUMED 2.5
+    1251             : 
+    1252             :   \return The constructed plumed object
+    1253             : */
+    1254             : 
+    1255             : __PLUMED_WRAPPER_C_BEGIN
+    1256             : plumed plumed_create_reference_f(const char*f);
+    1257             : __PLUMED_WRAPPER_C_END
+    1258             : 
+    1259             : /** \relates plumed
+    1260             :     \brief Constructor as invalid. Available as of PLUMED 2.5
+    1261             : 
+    1262             :    Can be used to create an object in the same state as if it was returned by
+    1263             :    plumed_create_dlopen with an incorrect path (or plumed_create using runtime binding
+    1264             :    and an incorrect PLUMED_KERNEL).
+    1265             : 
+    1266             :    Can be used to initialize a plumed object to a well-defined state without explicitly
+    1267             :    creating it. The resulting object can be checked later with \ref plumed_valid.
+    1268             :    Consider the following example
+    1269             : \verbatim
+    1270             :     plumed p;
+    1271             :     p=plumed_create_invalid();
+    1272             : // at this point p is initialized to a well-defined (invalid) state.
+    1273             :     setenv("PLUMED_KERNEL","/path/to/kernel/libplumedKernel.so",1);
+    1274             :     plumed_finalize(p);
+    1275             :     p=plumed_create();
+    1276             : \endverbatim
+    1277             : 
+    1278             :     \return The constructed plumed object
+    1279             : */
+    1280             : 
+    1281             : __PLUMED_WRAPPER_C_BEGIN
+    1282             : plumed plumed_create_invalid();
+    1283             : __PLUMED_WRAPPER_C_END
+    1284             : 
+    1285             : /** \relates plumed
+    1286             :     \brief Tells p to execute a command.
+    1287             : 
+    1288             :     If the object is not valid (see \ref plumed_valid), this command will exit.
+    1289             : 
+    1290             :     \param p The plumed object on which command is acting
+    1291             :     \param key The name of the command to be executed
+    1292             :     \param val The argument. It is declared as const to allow calls like plumed_cmd(p,"A","B"),
+    1293             :                but for some choice of key it can change the content.
+    1294             : 
+    1295             :     Notice that within PLUMED we use a const_cast to remove any const qualifier from the second
+    1296             :     argument of \ref plumed_cmd.
+    1297             : 
+    1298             :     In some cases val can be omitted: just pass a NULL pointer (in C++, val is optional and can be omitted,
+    1299             :     or you can equivalently pass NULL or nullptr).
+    1300             :     The set of possible keys is the real API of the plumed library, and will be expanded with time.
+    1301             :     New commands will be added, but backward compatibility will be retained as long as possible.
+    1302             : */
+    1303             : 
+    1304             : __PLUMED_WRAPPER_C_BEGIN
+    1305             : void plumed_cmd(plumed p,const char*key,const void*val);
+    1306             : __PLUMED_WRAPPER_C_END
+    1307             : 
+    1308             : /**
+    1309             :   \relates plumed
+    1310             :   \brief Same as \ref plumed_cmd, but does not throw exceptions.
+    1311             : 
+    1312             :   This function is meant to be used when errors should be handled explicitly.
+    1313             :   if an exception is raised within PLUMED, the function nothrow.handler() will
+    1314             :   be called with arguments (nothrow.ptr,code,message,opt). This allows the C++ interface
+    1315             :   to correctly rethrow exceptions, but might be used from C as well. opt can be used
+    1316             :   to pass further information (not used yet).
+    1317             : */
+    1318             : 
+    1319             : __PLUMED_WRAPPER_C_BEGIN
+    1320             : void plumed_cmd_nothrow(plumed p,const char*key,const void*val,plumed_nothrow_handler nothrow);
+    1321             : __PLUMED_WRAPPER_C_END
+    1322             : 
+    1323             : __PLUMED_WRAPPER_C_BEGIN
+    1324             : void plumed_cmd_safe_nothrow(plumed p,const char*key,plumed_safeptr,plumed_nothrow_handler nothrow);
+    1325             : __PLUMED_WRAPPER_C_END
+    1326             : 
+    1327             : __PLUMED_WRAPPER_C_BEGIN
+    1328             : void plumed_cmd_safe(plumed p,const char*key,plumed_safeptr);
+    1329             : __PLUMED_WRAPPER_C_END
+    1330             : 
+    1331             : /** \relates plumed
+    1332             :     \brief Destructor.
+    1333             : 
+    1334             :     It must be used for any object created using \ref plumed_create(),
+    1335             :     even if the created object is not valid.
+    1336             : 
+    1337             :     \param p The plumed object to be deallocated
+    1338             : */
+    1339             : 
+    1340             : __PLUMED_WRAPPER_C_BEGIN
+    1341             : void plumed_finalize(plumed p);
+    1342             : __PLUMED_WRAPPER_C_END
+    1343             : 
+    1344             : /** \relates plumed
+    1345             :     \brief Check if plumed is installed (for runtime binding).
+    1346             : 
+    1347             :     Notice that this is equivalent to creating a dummy object and checking if it is valid.
+    1348             : 
+    1349             : \verbatim
+    1350             :   // this:
+    1351             :   //int a=plumed_installed();
+    1352             :   // is equivalent to this:
+    1353             : 
+    1354             :   plumed p=plumed_create();
+    1355             :   int a=plumed_valid(p);
+    1356             :   plumed_finalize(p);
+    1357             : 
+    1358             : \endverbatim
+    1359             : 
+    1360             :     This function is mostly provided for compatibility with PLUMED 2.4, where \ref plumed_valid()
+    1361             :     was not available. Using \ref plumed_valid() is now preferred since it creates a single object
+    1362             :     instead of creating a dummy object that is then discarded.
+    1363             : 
+    1364             :     \return 1 if plumed is installed, 0 otherwise
+    1365             : */
+    1366             : 
+    1367             : __PLUMED_WRAPPER_C_BEGIN
+    1368             : int plumed_installed(void);
+    1369             : __PLUMED_WRAPPER_C_END
+    1370             : 
+    1371             : /** \relates plumed
+    1372             :     \brief Check if plumed object is valid. Available as of PLUMED 2.5
+    1373             : 
+    1374             :     It might return false if plumed is not available at runtime.
+    1375             : 
+    1376             :     \return 1 if plumed is valid, 0 otherwise
+    1377             : */
+    1378             : 
+    1379             : __PLUMED_WRAPPER_C_BEGIN
+    1380             : int plumed_valid(plumed p);
+    1381             : __PLUMED_WRAPPER_C_END
+    1382             : 
+    1383             : /** \relates plumed
+    1384             :     \brief Returns the number of references to the underlying object. Available as of PLUMED 2.5.
+    1385             : */
+    1386             : 
+    1387             : __PLUMED_WRAPPER_C_BEGIN
+    1388             : int plumed_use_count(plumed p);
+    1389             : __PLUMED_WRAPPER_C_END
+    1390             : 
+    1391             : 
+    1392             : /* routines to convert char handler from/to plumed objects */
+    1393             : 
+    1394             : /** \related plumed
+    1395             :     \brief Converts a C handler to a FORTRAN handler
+    1396             : 
+    1397             :     \param p The C handler
+    1398             :     \param c The FORTRAN handler (a char[32])
+    1399             : 
+    1400             :     This function can be used to convert a plumed object created in C to
+    1401             :     a plumed handler that can be used in FORTRAN. Notice that the reference counter
+    1402             :     is not incremented. In other words, the FORTRAN object will be a weak reference.
+    1403             :     If you later finalize the C handler, the FORTRAN handler will be invalid.
+    1404             : \verbatim
+    1405             : #include <plumed/wrapper/Plumed.h>
+    1406             : int main(int argc,char*argv[]){
+    1407             :   plumed p;
+    1408             :   p=plumed_create();
+    1409             :   char fortran_handler[32];
+    1410             :   plumed_c2f(p,fortran_handler);
+    1411             :   printf("DEBUG: this is a string representation for the plumed handler: %s\n",fortran_handler);
+    1412             :   fortran_routine(fortran_handler);
+    1413             :   plumed_finalize(p);
+    1414             :   return 0;
+    1415             : }
+    1416             : \endverbatim
+    1417             :   Here `fortran_routine` is a routine implemented in FORTRAN that manipulates the
+    1418             :   fortran_handler.
+    1419             : */
+    1420             : 
+    1421             : __PLUMED_WRAPPER_C_BEGIN
+    1422             : void   plumed_c2f(plumed p,char* c);
+    1423             : __PLUMED_WRAPPER_C_END
+    1424             : 
+    1425             : /** \related plumed
+    1426             :     \brief Converts a FORTRAN handler to a C handler
+    1427             :     \param c The FORTRAN handler (a char[32])
+    1428             :     \return The C handler
+    1429             : 
+    1430             :     This function can be used to convert a plumed object created in FORTRAN
+    1431             :     to a plumed handler that can be used in C.  Notice that the reference counter
+    1432             :     is not incremented. In other words, the C object will be a weak reference.
+    1433             :     If you later finalize the FORTRAN handler, the C handler will be invalid.
+    1434             : \verbatim
+    1435             : void c_routine(char handler[32]){
+    1436             :   plumed p;
+    1437             :   p=plumed_f2c(handler);
+    1438             :   plumed_cmd(p,"init",NULL);
+    1439             : }
+    1440             : \endverbatim
+    1441             :   Here `c_routine` is a C function that can be called from FORTRAN
+    1442             :   and interact with the provided plumed handler.
+    1443             : */
+    1444             : 
+    1445             : __PLUMED_WRAPPER_C_BEGIN
+    1446             : plumed plumed_f2c(const char* c);
+    1447             : __PLUMED_WRAPPER_C_END
+    1448             : 
+    1449             : /** \related plumed
+    1450             :     \brief Converts a plumed object to a void pointer. Available as of PLUMED 2.5.
+    1451             : 
+    1452             :     It returns a void pointer that can be converted back to a plumed object using \ref plumed_v2c.
+    1453             :     When compiling without NDEBUG, it checks if the plumed object was properly created.
+    1454             :     Notice that an invalid object (see \ref plumed_valid) can be converted to void* and back.
+    1455             : 
+    1456             :     Can be used to store a reference to a plumed object without including the Plumed.h header.
+    1457             : */
+    1458             : 
+    1459             : __PLUMED_WRAPPER_C_BEGIN
+    1460             : void* plumed_c2v(plumed p);
+    1461             : __PLUMED_WRAPPER_C_END
+    1462             : 
+    1463             : 
+    1464             : /** \related plumed
+    1465             :     \brief Converts a void pointer to a plumed object. Available as of PLUMED 2.5.
+    1466             : 
+    1467             :     It returns a plumed object from a void pointer obtained with \ref plumed_c2v.
+    1468             :     When compiling without NDEBUG, it checks if the plumed object was properly created.
+    1469             : 
+    1470             :     Can be used to store a reference to a plumed object without including the Plumed.h header.
+    1471             : */
+    1472             : 
+    1473             : __PLUMED_WRAPPER_C_BEGIN
+    1474             : plumed plumed_v2c(void*);
+    1475             : __PLUMED_WRAPPER_C_END
+    1476             : 
+    1477             : #if ! defined( __cplusplus) /*{*/
+    1478             : 
+    1479             : #if __PLUMED_WRAPPER_C_TYPESAFE /*{*/
+    1480             : 
+    1481             : #define __PLUMED_WRAPPER_C_TYPESAFE_INNER(type_,typen_,flags_) \
+    1482             :   static inline void plumed_cmdnse_ ## typen_(plumed p,const char*key,type_*ptr, size_t nelem, const size_t* shape,plumed_error* error) { \
+    1483             :     plumed_safeptr safe; \
+    1484             :     plumed_nothrow_handler nothrow; \
+    1485             :     safe.ptr=ptr; \
+    1486             :     safe.nelem=nelem; \
+    1487             :     safe.shape=(const size_t*)shape; \
+    1488             :     safe.flags=flags_; \
+    1489             :     safe.opt=NULL; \
+    1490             :     if(error) { \
+    1491             :       plumed_error_init(error); \
+    1492             :       nothrow.ptr=error; \
+    1493             :       nothrow.handler=plumed_error_set; \
+    1494             :       plumed_cmd_safe_nothrow(p,key,safe,nothrow); \
+    1495             :     } else { \
+    1496             :       plumed_cmd_safe(p,key,safe); \
+    1497             :     } \
+    1498             :   } \
+    1499             :   static inline void plumed_cmdne_ ## typen_(plumed p,const char*key,type_*ptr, size_t nelem, plumed_error* error) { \
+    1500             :     plumed_cmdnse_ ## typen_(p,key,ptr,nelem,NULL,error); \
+    1501             :   } \
+    1502             :   static inline void plumed_cmdse_ ## typen_(plumed p,const char*key,type_*ptr, const size_t* shape, plumed_error* error) { \
+    1503             :     plumed_cmdnse_ ## typen_(p,key,ptr,0,shape,error); \
+    1504             :   } \
+    1505             :   static inline void plumed_cmdn_ ## typen_(plumed p,const char*key,type_*ptr, size_t nelem) { \
+    1506             :     plumed_cmdnse_ ## typen_(p,key,ptr,nelem,NULL,NULL); \
+    1507             :   } \
+    1508             :   static inline void plumed_cmds_ ## typen_(plumed p,const char*key,type_*ptr, const size_t* shape) { \
+    1509             :     plumed_cmdnse_ ## typen_(p,key,ptr,0,shape,NULL); \
+    1510             :   } \
+    1511             :   static inline void plumed_cmde_ ## typen_(plumed p,const char*key,type_*ptr, plumed_error* error) { \
+    1512             :     plumed_cmdnse_ ## typen_(p,key,ptr,0,NULL,error); \
+    1513             :   }
+    1514             : 
+    1515             : #define __PLUMED_WRAPPER_C_TYPESAFE_OUTER(type,type_,code,size) \
+    1516             :   __PLUMED_WRAPPER_C_TYPESAFE_INNER(type,             type_ ## _p,  size | (0x10000*(code)) | (0x2000000*2)) \
+    1517             :   __PLUMED_WRAPPER_C_TYPESAFE_INNER(type const,       type_ ## _c,  size | (0x10000*(code)) | (0x2000000*3)) \
+    1518             :   __PLUMED_WRAPPER_C_TYPESAFE_INNER(type*,            type_ ## _pp, size | (0x10000*(code)) | (0x2000000*4)) \
+    1519             :   __PLUMED_WRAPPER_C_TYPESAFE_INNER(type*const,       type_ ## _pc, size | (0x10000*(code)) | (0x2000000*5)) \
+    1520             :   __PLUMED_WRAPPER_C_TYPESAFE_INNER(type const*,      type_ ## _cp, size | (0x10000*(code)) | (0x2000000*6)) \
+    1521             :   __PLUMED_WRAPPER_C_TYPESAFE_INNER(type const*const, type_ ## _cc, size | (0x10000*(code)) | (0x2000000*7))
+    1522             : 
+    1523             : #define __PLUMED_WRAPPER_C_TYPESAFE_EMPTY(type,type_,code) __PLUMED_WRAPPER_C_TYPESAFE_OUTER(type,type_,code,0)
+    1524             : 
+    1525             : #define __PLUMED_WRAPPER_C_TYPESAFE_SIZED(type,type_,code) \
+    1526             :   __PLUMED_WRAPPER_C_TYPESAFE_OUTER(type,type_,code,sizeof(type)) \
+    1527             :   static inline void plumed_cmdnse_ ## type_ ## _v(plumed p,const char*key,type val, size_t nelem, const size_t* shape, plumed_error* error) { \
+    1528             :     plumed_safeptr safe; \
+    1529             :     plumed_nothrow_handler nothrow; \
+    1530             :     (void) nelem; \
+    1531             :     (void) shape; \
+    1532             :     safe.ptr=&val; \
+    1533             :     safe.nelem=1; \
+    1534             :     safe.shape=NULL; \
+    1535             :     safe.flags=sizeof(type) | (0x10000*(code)) | (0x2000000*1); \
+    1536             :     safe.opt=NULL; \
+    1537             :     if(error) { \
+    1538             :       plumed_error_init(error); \
+    1539             :       nothrow.ptr=error; \
+    1540             :       nothrow.handler=plumed_error_set; \
+    1541             :       plumed_cmd_safe_nothrow(p,key,safe,nothrow); \
+    1542             :     } else { \
+    1543             :       plumed_cmd_safe(p,key,safe); \
+    1544             :     } \
+    1545             :   } \
+    1546             :   static inline void plumed_cmdne_ ## type_ ## _v(plumed p,const char*key,type val, size_t nelem, plumed_error* error) {  \
+    1547             :     plumed_cmdnse_ ## type_ ## _v(p,key,val,nelem,NULL,error); \
+    1548             :   } \
+    1549             :   static inline void plumed_cmdse_ ## type_ ## _v(plumed p,const char*key,type val, const size_t* shape, plumed_error* error) {  \
+    1550             :     plumed_cmdnse_ ## type_ ## _v(p,key,val,0,shape,error); \
+    1551             :   } \
+    1552             :   static inline void plumed_cmdn_ ## type_ ## _v(plumed p,const char*key,type val, size_t nelem) {  \
+    1553             :     plumed_cmdnse_ ## type_ ## _v(p,key,val,nelem,NULL,NULL); \
+    1554             :   } \
+    1555             :   static inline void plumed_cmds_ ## type_ ## _v(plumed p,const char*key,type val, const size_t* shape) {  \
+    1556             :     plumed_cmdnse_ ## type_ ## _v(p,key,val,0,shape,NULL); \
+    1557             :   } \
+    1558             :   static inline void plumed_cmde_ ## type_ ## _v(plumed p,const char*key,type val, plumed_error* error) {  \
+    1559             :     plumed_cmdnse_ ## type_ ## _v(p,key,val,0,NULL,error); \
+    1560             :   }
+    1561             : 
+    1562             : #define __PLUMED_WRAPPER_C_GENERIC1(flavor,type,typen_) \
+    1563             :     type: plumed_ ## flavor ## _ ## typen_,
+    1564             : 
+    1565             : #define __PLUMED_WRAPPER_C_GENERIC_EMPTY(flavor,type,type_) \
+    1566             :   __PLUMED_WRAPPER_C_GENERIC1(flavor,type*,             type_ ## _p) \
+    1567             :   __PLUMED_WRAPPER_C_GENERIC1(flavor,type const*,       type_ ## _c) \
+    1568             :   __PLUMED_WRAPPER_C_GENERIC1(flavor,type**,            type_ ## _pp) \
+    1569             :   __PLUMED_WRAPPER_C_GENERIC1(flavor,type*const*,       type_ ## _pc) \
+    1570             :   __PLUMED_WRAPPER_C_GENERIC1(flavor,type const**,      type_ ## _cp) \
+    1571             :   __PLUMED_WRAPPER_C_GENERIC1(flavor,type const*const*, type_ ## _cc)
+    1572             : 
+    1573             : #define __PLUMED_WRAPPER_C_GENERIC2(flavor,type,type_) \
+    1574             :   __PLUMED_WRAPPER_C_GENERIC_EMPTY(flavor,type,type_) \
+    1575             :   __PLUMED_WRAPPER_C_GENERIC1(flavor,type,             type_ ## _v)
+    1576             : 
+    1577             : /// Here we create all the required instances
+    1578             : /// 1: void
+    1579             : /// 3: integral
+    1580             : /// 4: floating
+    1581             : /// 5: FILE
+    1582             : /// 0x100: unsigned
+    1583             : __PLUMED_WRAPPER_C_TYPESAFE_EMPTY(void,void,1)
+    1584             : __PLUMED_WRAPPER_C_TYPESAFE_SIZED(char,char,(CHAR_MIN==0)*0x100+3)
+    1585             : __PLUMED_WRAPPER_C_TYPESAFE_SIZED(unsigned char,unsigned_char,0x100+3)
+    1586             : __PLUMED_WRAPPER_C_TYPESAFE_SIZED(signed char,signed_char,0x100+3)
+    1587             : __PLUMED_WRAPPER_C_TYPESAFE_SIZED(short,short,3)
+    1588             : __PLUMED_WRAPPER_C_TYPESAFE_SIZED(unsigned short,unsigned_short,0x100+3)
+    1589             : __PLUMED_WRAPPER_C_TYPESAFE_SIZED(int,int,3)
+    1590             : __PLUMED_WRAPPER_C_TYPESAFE_SIZED(unsigned int,unsigned_int,0x100+3)
+    1591             : __PLUMED_WRAPPER_C_TYPESAFE_SIZED(long,long,3)
+    1592             : __PLUMED_WRAPPER_C_TYPESAFE_SIZED(unsigned long,unsigned_long,0x100+3)
+    1593             : __PLUMED_WRAPPER_C_TYPESAFE_SIZED(long long,long_long,3)
+    1594             : __PLUMED_WRAPPER_C_TYPESAFE_SIZED(unsigned long long,unsigned_long_long,0x100+3)
+    1595             : __PLUMED_WRAPPER_C_TYPESAFE_SIZED(float,float,4)
+    1596             : __PLUMED_WRAPPER_C_TYPESAFE_SIZED(double,double,4)
+    1597             : __PLUMED_WRAPPER_C_TYPESAFE_SIZED(long double,long_double,4)
+    1598             : __PLUMED_WRAPPER_C_TYPESAFE_EMPTY(FILE,FILE,5)
+    1599             : 
+    1600             : static inline void plumed_cmd_null_e(plumed p,const char*key,plumed_error* error,int ignore) {
+    1601             :   (void) ignore;
+    1602             :   plumed_cmde_void_p(p,key,NULL,error);
+    1603             : }
+    1604             : 
+    1605             : #define plumed_cmdnse_inner(flavor,val) _Generic((val), \
+    1606             :     __PLUMED_WRAPPER_C_GENERIC_EMPTY(flavor,void,void) \
+    1607             :     __PLUMED_WRAPPER_C_GENERIC2(flavor,char,char) \
+    1608             :     __PLUMED_WRAPPER_C_GENERIC2(flavor,unsigned char,unsigned_char) \
+    1609             :     __PLUMED_WRAPPER_C_GENERIC2(flavor,signed char,signed_char) \
+    1610             :     __PLUMED_WRAPPER_C_GENERIC2(flavor,short,short) \
+    1611             :     __PLUMED_WRAPPER_C_GENERIC2(flavor,unsigned short,unsigned_short) \
+    1612             :     __PLUMED_WRAPPER_C_GENERIC2(flavor,int,int) \
+    1613             :     __PLUMED_WRAPPER_C_GENERIC2(flavor,unsigned int,unsigned_int) \
+    1614             :     __PLUMED_WRAPPER_C_GENERIC2(flavor,long,long) \
+    1615             :     __PLUMED_WRAPPER_C_GENERIC2(flavor,unsigned long,unsigned_long) \
+    1616             :     __PLUMED_WRAPPER_C_GENERIC2(flavor,long long,long_long) \
+    1617             :     __PLUMED_WRAPPER_C_GENERIC2(flavor,unsigned long long,unsigned_long_long) \
+    1618             :     __PLUMED_WRAPPER_C_GENERIC2(flavor,float,float) \
+    1619             :     __PLUMED_WRAPPER_C_GENERIC2(flavor,double,double) \
+    1620             :     __PLUMED_WRAPPER_C_GENERIC2(flavor,long double,long_double) \
+    1621             :     __PLUMED_WRAPPER_C_GENERIC_EMPTY(flavor,FILE,FILE) \
+    1622             :     default: plumed_ ## flavor ## _void_c)
+    1623             : 
+    1624             : #define plumed_cmd_2args(p,key) plumed_cmdnse_inner(cmdn,NULL) (p,key,NULL,0)
+    1625             : 
+    1626             : #define plumed_cmd_3args(p,key,X) _Generic((X), \
+    1627             :     plumed_error*: plumed_cmd_null_e, \
+    1628             :     default:       plumed_cmdnse_inner(cmdn,X)) (p,key,X,0)
+    1629             : 
+    1630             : /* ((X)+(size_t)0): for pointers, no op; for integers, convert to size_t */
+    1631             : #define plumed_cmd_4args(p,key,val,X) _Generic(((X)+(size_t)0), \
+    1632             :     const size_t *: plumed_cmdnse_inner(cmds,val), \
+    1633             :     size_t *: plumed_cmdnse_inner(cmds,val), \
+    1634             :     size_t: plumed_cmdnse_inner(cmdn,val), \
+    1635             :     plumed_error*: plumed_cmdnse_inner(cmde,val) \
+    1636             :     ) (p,key,val,X)
+    1637             : 
+    1638             : /* ((X)+(size_t)0): for pointers, no op; for integers, convert to size_t */
+    1639             : #define plumed_cmd_5args(p,key,val,X,error) _Generic(((X)+(size_t)0), \
+    1640             :     const size_t *: plumed_cmdnse_inner(cmdse,val), \
+    1641             :     size_t *: plumed_cmdnse_inner(cmdse,val), \
+    1642             :     size_t: plumed_cmdnse_inner(cmdne,val) \
+    1643             :     ) (p,key,val,X,error)
+    1644             : 
+    1645             : #define __PLUMED_WRAPPER_C_GET_MACRO(_1,_2,_3,_4,_5,NAME,...) NAME
+    1646             : #define plumed_cmd_c11(...) __PLUMED_WRAPPER_C_GET_MACRO(__VA_ARGS__, plumed_cmd_5args, plumed_cmd_4args, plumed_cmd_3args, plumed_cmd_2args)(__VA_ARGS__)
+    1647             : 
+    1648             : #define plumed_gcmd_c11(...) plumed_cmd(plumed_global(),__VA_ARGS__)
+    1649             : 
+    1650             : #define __PLUMED_WRAPPER_REDEFINE_CMD plumed_cmd_c11
+    1651             : #define __PLUMED_WRAPPER_REDEFINE_GCMD plumed_gcmd_c11
+    1652             : 
+    1653             : #endif /*}*/
+    1654             : 
+    1655             : #endif /*}*/
+    1656             : 
+    1657             : 
+    1658             : #if __PLUMED_WRAPPER_GLOBAL /*{*/
+    1659             : 
+    1660             : /* Global C functions are always extern */
+    1661             : __PLUMED_WRAPPER_EXTERN_C_BEGIN /*{*/
+    1662             : 
+    1663             : /** \relates plumed
+    1664             :     \brief Retrieves an handler to the global structure.
+    1665             : 
+    1666             :   You can use this if you work on a code that uses the global structure and you want to
+    1667             :   pass to a generic routine an handler to the same structure. E.g.
+    1668             : 
+    1669             : \verbatim
+    1670             :   plumed p=plumed_global();
+    1671             :   some_routine(p);
+    1672             : \endverbatim
+    1673             : */
+    1674             : extern
+    1675             : plumed plumed_global(void);
+    1676             : 
+    1677             : /** \relates plumed
+    1678             :     \brief Check if the global interface has been initialized.
+    1679             : 
+    1680             :     \return 1 if plumed has been initialized, 0 otherwise
+    1681             : */
+    1682             : extern
+    1683             : int plumed_ginitialized(void);
+    1684             : 
+    1685             : /** \relates plumed
+    1686             :     \brief Constructor for the global interface.
+    1687             : 
+    1688             :     \note Equivalent to plumed_create(), but initialize the static global plumed object
+    1689             : */
+    1690             : extern
+    1691             : void plumed_gcreate(void);
+    1692             : 
+    1693             : /** \relates plumed
+    1694             :     \brief Tells to the global interface to execute a command.
+    1695             : 
+    1696             :     \param key The name of the command to be executed
+    1697             :     \param val The argument. It is declared as const to allow calls like plumed_gcmd("A","B"),
+    1698             :                but for some choice of key it can change the content
+    1699             : 
+    1700             :     `plumed_gcmd(a,b);` is equivalent to `plumed_cmd(plumed_global(),a,b);`.
+    1701             : */
+    1702             : extern
+    1703             : void plumed_gcmd(const char* key,const void* val);
+    1704             : 
+    1705             : /** \relates plumed
+    1706             :     \brief Tells to the global interface to execute a command.
+    1707             : 
+    1708             :     \param key The name of the command to be executed
+    1709             :     \param safe A safe pointer
+    1710             : 
+    1711             :     `plumed_gcmd_safe(a,b);` is equivalent to `plumed_cmd_safe(plumed_global(),a,b);`.
+    1712             : */
+    1713             : extern
+    1714             : void plumed_gcmd_safe(const char* key,plumed_safeptr);
+    1715             : 
+    1716             : /** \relates plumed
+    1717             :     \brief Destructor for the global interface.
+    1718             : 
+    1719             :     `plumed_gfinalize(a,b);` is similar to `plumed_finalize(plumed_global(),a,b);`, but not completely
+    1720             :     equivalent. In particular, plumed_gfinalize() also makes sure that the global object
+    1721             :     is reset to its initial status. After calling it, \ref plumed_ginitialized() will thus return 0.
+    1722             : */
+    1723             : extern
+    1724             : void plumed_gfinalize(void);
+    1725             : 
+    1726             : /** \relates plumed
+    1727             :     \brief Check if global plumed object is valid. Available as of PLUMED 2.5
+    1728             : 
+    1729             :     It might return zero if plumed is not available at runtime.
+    1730             : 
+    1731             :     \return 1 if plumed is valid, 0 otherwise.
+    1732             : */
+    1733             : extern
+    1734             : int plumed_gvalid();
+    1735             : 
+    1736             : __PLUMED_WRAPPER_EXTERN_C_END /*}*/
+    1737             : 
+    1738             : #endif /*}*/
+    1739             : 
+    1740             : #if defined( __cplusplus) && __PLUMED_WRAPPER_CXX /*{*/
+    1741             : 
+    1742             : #if __PLUMED_WRAPPER_CXX_STD
+    1743             : #include <cstdlib> /* NULL getenv */
+    1744             : #include <cstddef> /* nullptr_t */
+    1745             : #include <cstring> /* strncat strlen */
+    1746             : #include <cassert> /* assert */
+    1747             : #include <climits> /* CHAR_MIN */
+    1748             : #else
+    1749             : #include <stddef.h>
+    1750             : #include <stdlib.h>
+    1751             : #include <string.h>
+    1752             : #include <assert.h>
+    1753             : #include <limits.h>
+    1754             : #endif
+    1755             : 
+    1756             : #include <exception> /* exception bad_exception */
+    1757             : #include <stdexcept> /* runtime_error logic_error invalid_argument domain_error length_error out_of_range range_error overflow_error underflow_error */
+    1758             : #include <string> /* string */
+    1759             : #include <ios> /* iostream_category (C++11) ios_base::failure (C++11 and C++<11) */
+    1760             : #include <new> /* bad_alloc bad_array_new_length (C++11) */
+    1761             : #include <typeinfo> /* bad_typeid bad_cast */
+    1762             : #if __cplusplus > 199711L && __PLUMED_WRAPPER_LIBCXX11
+    1763             : #include <system_error> /* system_error generic_category system_category */
+    1764             : #include <future> /* future_category */
+    1765             : #include <memory> /* bad_weak_ptr */
+    1766             : #include <functional> /* bad_function_call */
+    1767             : #include <regex> /* regex_error */
+    1768             : #endif
+    1769             : #if __cplusplus >= 201703L && __PLUMED_WRAPPER_LIBCXX17
+    1770             : #include <any> /* bad_any_cast */
+    1771             : #include <variant> /* bad_variant_access */
+    1772             : #include <optional> /* bad_optional_access */
+    1773             : #include <filesystem> /* filesystem_error */
+    1774             : #endif
+    1775             : 
+    1776             : #if __cplusplus > 199711L
+    1777             : #include <array> /* array */
+    1778             : #include <initializer_list> /* initializer_list */
+    1779             : #endif
+    1780             : 
+    1781             : /* C++ interface is hidden in PLMD namespace (same as plumed library) */
+    1782             : namespace PLMD {
+    1783             : 
+    1784             : /* Optionally, it is further hidden in an anonymous namespace */
+    1785             : 
+    1786             : __PLUMED_WRAPPER_ANONYMOUS_BEGIN /*{*/
+    1787             : 
+    1788             : /**
+    1789             :   Retrieve PLUMED_EXCEPTIONS_DEBUG (internal utility).
+    1790             : 
+    1791             :   This function should not be used by external programs. It is defined
+    1792             :   as inline static so that it can store a static variable (for quicker access)
+    1793             :   without adding a unique global symbol to a library including this header file.
+    1794             : */
+    1795           0 : inline static bool PlumedGetenvExceptionsDebug() __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    1796           0 :   static const char* res=__PLUMED_WRAPPER_STD getenv("PLUMED_EXCEPTIONS_DEBUG");
+    1797           0 :   return res;
+    1798             : }
+    1799             : 
+    1800             : /**
+    1801             :   C++ wrapper for \ref plumed.
+    1802             : 
+    1803             :   This class provides a C++ interface to PLUMED.
+    1804             :   It only containts a \ref plumed object, but wraps it with a number of useful methods.
+    1805             :   All methods are inlined so as to avoid the compilation of an extra c++ file.
+    1806             : 
+    1807             : */
+    1808             : 
+    1809             : class Plumed {
+    1810             :   /**
+    1811             :     C structure.
+    1812             :   */
+    1813             :   plumed main;
+    1814             : 
+    1815             : private:
+    1816             : 
+    1817             :   /**
+    1818             :     This is an internal utility to dispatch exceptions based on the plumed_error object.
+    1819             : 
+    1820             :     It takes information about the exception to be thrown by the passed h object
+    1821             :     and use it to call function f() on the resulting exception. Notice that:
+    1822             :     - this function does not consider if the error is nested.
+    1823             :     - f should be a callable object, so that it can store information
+    1824             :     - f operator() should be a template function so as to act based on the
+    1825             :       type of its argument
+    1826             : 
+    1827             :     New exceptions added here should be kept in sync with core/PlumedMainInitializer.cpp
+    1828             : 
+    1829             :     Notice that this function also finalizes in place plumed_error h, so as to avoid
+    1830             :     memory leaks.
+    1831             :   */
+    1832             :   template<typename F>
+    1833           0 :   __PLUMED_WRAPPER_CXX_NORETURN static void exception_dispatch(plumed_error&h,F f) {
+    1834             :     /* this is required to make sure h is finalized when leaving this function */
+    1835             :     finalize_plumed_error finalize(h);
+    1836             :     /* grab the message */
+    1837             :     const char* msg=plumed_error_what(h);
+    1838           0 :     if(h.code==1) f(Plumed::Invalid(msg));
+    1839             :     /* logic errors */
+    1840           0 :     if(h.code>=10100 && h.code<10200) {
+    1841           0 :       if(h.code>=10105 && h.code<10110) f(::std::invalid_argument(msg));
+    1842           0 :       if(h.code>=10110 && h.code<10115) f(::std::domain_error(msg));
+    1843           0 :       if(h.code>=10115 && h.code<10120) f(::std::length_error(msg));
+    1844           0 :       if(h.code>=10120 && h.code<10125) f(::std::out_of_range(msg));
+    1845             : #if __cplusplus >= 201703L && __PLUMED_WRAPPER_LIBCXX17
+    1846             :       if(h.code==10125) f(add_buffer_to< ::std::future_error>(::std::future_error(::std::future_errc::broken_promise),msg));
+    1847             :       if(h.code==10126) f(add_buffer_to< ::std::future_error>(::std::future_error(::std::future_errc::future_already_retrieved),msg));
+    1848             :       if(h.code==10127) f(add_buffer_to< ::std::future_error>(::std::future_error(::std::future_errc::promise_already_satisfied),msg));
+    1849             :       if(h.code==10128) f(add_buffer_to< ::std::future_error>(::std::future_error(::std::future_errc::no_state),msg));
+    1850             : #endif
+    1851           0 :       f(::std::logic_error(msg));
+    1852             :     }
+    1853             :     /* runtime errors */
+    1854           0 :     if(h.code>=10200 && h.code<10300) {
+    1855           0 :       if(h.code>=10205 && h.code<10210) f(::std::range_error(msg));
+    1856           0 :       if(h.code>=10210 && h.code<10215) f(::std::overflow_error(msg));
+    1857           0 :       if(h.code>=10215 && h.code<10220) f(::std::underflow_error(msg));
+    1858             : #if __cplusplus > 199711L && __PLUMED_WRAPPER_LIBCXX11
+    1859             :       if(h.code==10220) f(::std::system_error(h.error_code,::std::generic_category(),msg));
+    1860             :       if(h.code==10221) f(::std::system_error(h.error_code,::std::system_category(),msg));
+    1861             :       if(h.code==10222) f(::std::system_error(h.error_code,::std::iostream_category(),msg));
+    1862             :       if(h.code==10223) f(::std::system_error(h.error_code,::std::future_category(),msg));
+    1863             : #endif
+    1864             : #if __cplusplus >= 201703L && __PLUMED_WRAPPER_LIBCXX17
+    1865             :       if(h.code==10229) {
+    1866             :         ::std::error_code error_code;
+    1867             :         if(h.error_category==1) error_code=::std::error_code(h.error_code,::std::generic_category());
+    1868             :         if(h.error_category==2) error_code=::std::error_code(h.error_code,::std::system_category());
+    1869             :         if(h.error_category==3) error_code=::std::error_code(h.error_code,::std::iostream_category());
+    1870             :         if(h.error_category==4) error_code=::std::error_code(h.error_code,::std::future_category());
+    1871             : 
+    1872             :         if(!h.path1.ptr) {
+    1873             :           f(::std::filesystem::filesystem_error(msg,error_code));
+    1874             :         } else if(!h.path2.ptr) {
+    1875             :           /*
+    1876             :              In principle native_format is a possible value of an enum,
+    1877             :              so should be accessible as ::std::filesystem::path::native_format
+    1878             :              However, some clang versions declare it as enum class. Thus,
+    1879             :              ::std::filesystem::path::format::native_format is more portable.
+    1880             :           */
+    1881             :           f(::std::filesystem::filesystem_error(msg,
+    1882             :                                                 ::std::filesystem::path(::std::filesystem::path::string_type(
+    1883             :                                                     (::std::filesystem::path::value_type*) h.path1.ptr,h.path1.numbytes/sizeof(::std::filesystem::path::value_type)
+    1884             :                                                     ),::std::filesystem::path::format::native_format),
+    1885             :                                                 error_code));
+    1886             :         } else {
+    1887             :           f(::std::filesystem::filesystem_error(msg,
+    1888             :                                                 ::std::filesystem::path(::std::filesystem::path::string_type(
+    1889             :                                                     (::std::filesystem::path::value_type*) h.path1.ptr,h.path1.numbytes/sizeof(::std::filesystem::path::value_type)
+    1890             :                                                     ),::std::filesystem::path::format::native_format),
+    1891             :                                                 ::std::filesystem::path(::std::filesystem::path::string_type(
+    1892             :                                                     (::std::filesystem::path::value_type*) h.path2.ptr,h.path2.numbytes/sizeof(::std::filesystem::path::value_type)
+    1893             :                                                     ),::std::filesystem::path::format::native_format),
+    1894             :                                                 error_code));
+    1895             :         }
+    1896             :       }
+    1897             : #endif
+    1898           0 :       if(h.code>=10230 && h.code<10240) {
+    1899             : #if __cplusplus > 199711L && __PLUMED_WRAPPER_LIBCXX11
+    1900             : // These cases are probably useless as it looks like this should always be std::iostream_category
+    1901             :         if(h.code==10230) f(::std::ios_base::failure(msg,::std::error_code(h.error_code,::std::generic_category())));
+    1902             :         if(h.code==10231) f(::std::ios_base::failure(msg,::std::error_code(h.error_code,::std::system_category())));
+    1903             :         if(h.code==10232) f(::std::ios_base::failure(msg,::std::error_code(h.error_code,::std::iostream_category())));
+    1904             :         if(h.code==10233) f(::std::ios_base::failure(msg,::std::error_code(h.error_code,::std::future_category())));
+    1905             : #endif
+    1906           0 :         f(::std::ios_base::failure(msg));
+    1907             :       }
+    1908             : #if __cplusplus > 199711L && __PLUMED_WRAPPER_LIBCXX11
+    1909             :       if(h.code==10240) f(add_buffer_to< ::std::regex_error>(::std::regex_error(::std::regex_constants::error_collate),msg));
+    1910             :       if(h.code==10241) f(add_buffer_to< ::std::regex_error>(::std::regex_error(::std::regex_constants::error_ctype),msg));
+    1911             :       if(h.code==10242) f(add_buffer_to< ::std::regex_error>(::std::regex_error(::std::regex_constants::error_escape),msg));
+    1912             :       if(h.code==10243) f(add_buffer_to< ::std::regex_error>(::std::regex_error(::std::regex_constants::error_backref),msg));
+    1913             :       if(h.code==10244) f(add_buffer_to< ::std::regex_error>(::std::regex_error(::std::regex_constants::error_brack),msg));
+    1914             :       if(h.code==10245) f(add_buffer_to< ::std::regex_error>(::std::regex_error(::std::regex_constants::error_paren),msg));
+    1915             :       if(h.code==10246) f(add_buffer_to< ::std::regex_error>(::std::regex_error(::std::regex_constants::error_brace),msg));
+    1916             :       if(h.code==10247) f(add_buffer_to< ::std::regex_error>(::std::regex_error(::std::regex_constants::error_badbrace),msg));
+    1917             :       if(h.code==10248) f(add_buffer_to< ::std::regex_error>(::std::regex_error(::std::regex_constants::error_range),msg));
+    1918             :       if(h.code==10249) f(add_buffer_to< ::std::regex_error>(::std::regex_error(::std::regex_constants::error_space),msg));
+    1919             :       if(h.code==10250) f(add_buffer_to< ::std::regex_error>(::std::regex_error(::std::regex_constants::error_badrepeat),msg));
+    1920             :       if(h.code==10251) f(add_buffer_to< ::std::regex_error>(::std::regex_error(::std::regex_constants::error_complexity),msg));
+    1921             :       if(h.code==10252) f(add_buffer_to< ::std::regex_error>(::std::regex_error(::std::regex_constants::error_stack),msg));
+    1922             : #endif
+    1923           0 :       f(::std::runtime_error(msg));
+    1924             :     }
+    1925             :     /* "bad" errors */
+    1926             :     /* "< ::" space required in C++ < 11 */
+    1927           0 :     if(h.code>=11000 && h.code<11100) f(add_buffer_to< ::std::bad_typeid>(msg));
+    1928           0 :     if(h.code>=11100 && h.code<11200) {
+    1929             : #if __cplusplus >= 201703L && __PLUMED_WRAPPER_LIBCXX17
+    1930             :       if(h.code>=11150) f(add_buffer_to< ::std::bad_any_cast>(msg));
+    1931             : #endif
+    1932           0 :       f(add_buffer_to< ::std::bad_cast>(msg));
+    1933             :     }
+    1934             : #if __cplusplus > 199711L && __PLUMED_WRAPPER_LIBCXX11
+    1935             :     if(h.code>=11200 && h.code<11300) f(add_buffer_to< ::std::bad_weak_ptr>(msg));
+    1936             :     if(h.code>=11300 && h.code<11400) f(add_buffer_to< ::std::bad_function_call>(msg));
+    1937             : #endif
+    1938           0 :     if(h.code>=11400 && h.code<11500) {
+    1939             : #if __cplusplus > 199711L && __PLUMED_WRAPPER_LIBCXX11
+    1940             :       if(h.code>=11410 && h.code<11420) f(add_buffer_to< ::std::bad_array_new_length>(msg));
+    1941             : #endif
+    1942           0 :       f(add_buffer_to< ::std::bad_alloc>(msg));
+    1943             :     }
+    1944           0 :     if(h.code>=11500 && h.code<11600) f(add_buffer_to< ::std::bad_exception>(msg));
+    1945             : #if __cplusplus >= 201703L && __PLUMED_WRAPPER_LIBCXX17
+    1946             :     if(h.code>=11600 && h.code<11700) f(add_buffer_to< ::std::bad_optional_access>(msg));
+    1947             :     if(h.code>=11700 && h.code<11800) f(add_buffer_to< ::std::bad_variant_access>(msg));
+    1948             : #endif
+    1949             :     /* lepton error */
+    1950           0 :     if(h.code>=19900 && h.code<20000) f(Plumed::LeptonException(msg));
+    1951             :     /* plumed exceptions */
+    1952           0 :     if(h.code>=20000 && h.code<30000) {
+    1953             :       /* debug - only raised with debug options */
+    1954           0 :       if(h.code>=20100 && h.code<20200) f(Plumed::ExceptionDebug(msg));
+    1955             :       /* error - runtime check */
+    1956           0 :       if(h.code>=20200 && h.code<20300) f(Plumed::ExceptionError(msg));
+    1957             :       /* error - type error */
+    1958           0 :       if(h.code>=20300 && h.code<20400) f(Plumed::ExceptionTypeError(msg));
+    1959           0 :       f(Plumed::Exception(msg));
+    1960             :     }
+    1961             :     /* fallback for any other exception */
+    1962           0 :     f(add_buffer_to< ::std::exception>(msg));
+    1963           0 :   }
+    1964             : 
+    1965             : #if __cplusplus > 199711L && __PLUMED_WRAPPER_CXX_ENABLE_NESTED_EXCEPTIONS
+    1966             :   /** Internal class used by exception_dispatch. */
+    1967             :   class rethrow_nested {
+    1968             :   public:
+    1969             :     template<typename E>
+    1970             :     __PLUMED_WRAPPER_CXX_NORETURN void operator()(const E&e) {
+    1971           0 :       std::throw_with_nested(e);
+    1972             :     }
+    1973             :   };
+    1974             : #endif
+    1975             : 
+    1976             :   /** Internal class used by exception_dispatch. */
+    1977             :   class rethrow_not_nested {
+    1978             :   public:
+    1979             :     template<typename E>
+    1980           0 :     __PLUMED_WRAPPER_CXX_NORETURN void operator()(const E&e) {
+    1981           0 :       throw e;
+    1982             :     }
+    1983             :   };
+    1984             : 
+    1985             :   /** Internal class to simplify plumed_error finalization */
+    1986             :   class finalize_plumed_error {
+    1987             :     plumed_error&e;
+    1988             :     finalize_plumed_error(const finalize_plumed_error&); //not implemented
+    1989             :   public:
+    1990           0 :     __PLUMED_WRAPPER_CXX_EXPLICIT finalize_plumed_error(plumed_error&e):
+    1991           0 :       e(e)
+    1992             :     {}
+    1993           0 :     ~finalize_plumed_error() {
+    1994           0 :       plumed_error_finalize(e);
+    1995           0 :       e.code=0; // make sure it's not finalized again
+    1996           0 :     }
+    1997             :   };
+    1998             : 
+    1999             :   /**
+    2000             :     Recursive function that rethrows an exception with all the nested ones.
+    2001             : 
+    2002             :     In order to do so, we start throwing from the first exception that was originally thrown
+    2003             :     and recursively throw the others using throw_with_nested.
+    2004             : 
+    2005             :     plumed_error h is finalized at exit by the exception_dispatch function, to avoid memory leaks
+    2006             :   */
+    2007           0 :   __PLUMED_WRAPPER_CXX_NORETURN static void rethrow(plumed_error&h) {
+    2008             : #if __cplusplus > 199711L && __PLUMED_WRAPPER_CXX_ENABLE_NESTED_EXCEPTIONS
+    2009             :     /*
+    2010             :       When using C++11 nested exceptions, we need to rethrow recursively
+    2011             :     */
+    2012             :     try {
+    2013           0 :       if(h.nested) rethrow(*h.nested); /* recursive throw */
+    2014           0 :     } catch(...) {
+    2015           0 :       exception_dispatch(h,rethrow_nested());
+    2016           0 :     }
+    2017           0 :     exception_dispatch(h,rethrow_not_nested());
+    2018             : #else
+    2019             :     /*
+    2020             :       When using C++<11 exceptions, we merge the message and then throw the resulting exception
+    2021             :     */
+    2022             :     if(h.nested) plumed_error_merge_with_nested(&h);
+    2023             :     exception_dispatch(h,rethrow_not_nested());
+    2024             : #endif
+    2025             :   }
+    2026             : 
+    2027             : public:
+    2028             :   /**
+    2029             :     This is a tool to rethrow an error as an exception and finalize the error.
+    2030             : 
+    2031             :     In practice, this makes it possible to write a code like this:
+    2032             :     ```
+    2033             :     Plumed p;
+    2034             :     plumed_error e;
+    2035             :     // store error in e if something wrong happes
+    2036             :     // notice that Plumed (C++) is implicitly converted to plumed (C) when calling plumed_cmd
+    2037             :     plumed_cmd(p,"init",&e);
+    2038             :     // do other things here
+    2039             :     // then throw the exception
+    2040             :     if(e.code) plumed_error_rethrow(e);
+    2041             : 
+    2042             :     It should be used through the macro plumed_error_rethrow.
+    2043             :     ```
+    2044             :   */
+    2045             :   __PLUMED_WRAPPER_CXX_NORETURN static void plumed_error_rethrow_cxx(plumed_error h) {
+    2046           0 :     rethrow(h);
+    2047             :   }
+    2048             : 
+    2049             : private:
+    2050             :   /**
+    2051             :     Rethrow the current exception.
+    2052             : 
+    2053             :     This is useful in order to handle an exception thrown by a kernel <=2.4.
+    2054             :     Only std exceptions are handled, though some of them are thrown as special
+    2055             :     Plumed exceptions in order to be attached a message.
+    2056             :   */
+    2057           0 :   __PLUMED_WRAPPER_CXX_NORETURN static void rethrow() {
+    2058             :     try {
+    2059           0 :       throw;
+    2060           0 :     } catch(const ::std::bad_exception & e) {
+    2061           0 :       throw add_buffer_to< ::std::bad_exception>(e.what());
+    2062             : #if __cplusplus > 199711L && __PLUMED_WRAPPER_LIBCXX11
+    2063             :     } catch(const ::std::bad_array_new_length & e) {
+    2064             :       throw add_buffer_to< ::std::bad_array_new_length>(e.what());
+    2065             : #endif
+    2066           0 :     } catch(const ::std::bad_alloc & e) {
+    2067           0 :       throw add_buffer_to< ::std::bad_alloc>(e.what());
+    2068             : #if __cplusplus > 199711L && __PLUMED_WRAPPER_LIBCXX11
+    2069             :     } catch(const ::std::bad_function_call & e) {
+    2070             :       throw add_buffer_to< ::std::bad_function_call>(e.what());
+    2071             :     } catch(const ::std::bad_weak_ptr & e) {
+    2072             :       throw add_buffer_to< ::std::bad_weak_ptr>(e.what());
+    2073             : #endif
+    2074           0 :     } catch(const ::std::bad_cast & e) {
+    2075           0 :       throw add_buffer_to< ::std::bad_cast>(e.what());
+    2076           0 :     } catch(const ::std::bad_typeid & e) {
+    2077           0 :       throw add_buffer_to< ::std::bad_typeid>(e.what());
+    2078             :       // not implemented yet: std::regex_error
+    2079             :       // we do not allow regex yet due to portability problems with gcc 4.8
+    2080             :       // as soon as we transition to using <regex> it should be straightforward to add
+    2081           0 :     } catch(const ::std::ios_base::failure & e) {
+    2082             : #if __cplusplus > 199711L && __PLUMED_WRAPPER_LIBCXX11
+    2083             :       throw ::std::ios_base::failure(e.what(),e.code());
+    2084             : #else
+    2085           0 :       throw ::std::ios_base::failure(e.what());
+    2086             : #endif
+    2087             : #if __cplusplus > 199711L && __PLUMED_WRAPPER_LIBCXX11
+    2088             :     } catch(const ::std::system_error & e) {
+    2089             :       throw ::std::system_error(e.code(),e.what());
+    2090             : #endif
+    2091           0 :     } catch(const ::std::underflow_error &e) {
+    2092           0 :       throw ::std::underflow_error(e.what());
+    2093           0 :     } catch(const ::std::overflow_error &e) {
+    2094           0 :       throw ::std::overflow_error(e.what());
+    2095           0 :     } catch(const ::std::range_error &e) {
+    2096           0 :       throw ::std::range_error(e.what());
+    2097           0 :     } catch(const ::std::runtime_error & e) {
+    2098           0 :       throw ::std::runtime_error(e.what());
+    2099             :       // not implemented yet: std::future_error
+    2100             :       // not clear how useful it would be.
+    2101           0 :     } catch(const ::std::out_of_range & e) {
+    2102           0 :       throw ::std::out_of_range(e.what());
+    2103           0 :     } catch(const ::std::length_error & e) {
+    2104           0 :       throw ::std::length_error(e.what());
+    2105           0 :     } catch(const ::std::domain_error & e) {
+    2106           0 :       throw ::std::domain_error(e.what());
+    2107           0 :     } catch(const ::std::invalid_argument & e) {
+    2108           0 :       throw ::std::invalid_argument(e.what());
+    2109           0 :     } catch(const ::std::logic_error & e) {
+    2110           0 :       throw ::std::logic_error(e.what());
+    2111           0 :     } catch(const ::std::exception & e) {
+    2112           0 :       throw add_buffer_to< ::std::exception>(e.what());
+    2113           0 :     } catch(...) {
+    2114           0 :       throw add_buffer_to< ::std::bad_exception>("plumed could not translate exception");
+    2115           0 :     }
+    2116             :   }
+    2117             : 
+    2118             : public:
+    2119             : 
+    2120             : #if __PLUMED_WRAPPER_CXX_ANONYMOUS_NAMESPACE_PLMD_EXCEPTIONS
+    2121             :   using Exception = PLMD::Exception;
+    2122             : #else
+    2123             :   /**
+    2124             :     Base class used to rethrow PLUMED exceptions.
+    2125             :   */
+    2126             :   class Exception :
+    2127             :     public ::std::exception
+    2128             :   {
+    2129             :     ::std::string msg;
+    2130             :   public:
+    2131           0 :     __PLUMED_WRAPPER_CXX_EXPLICIT Exception(const char* msg): msg(msg) {}
+    2132           0 :     const char* what() const __PLUMED_WRAPPER_CXX_NOEXCEPT __PLUMED_WRAPPER_CXX_OVERRIDE {return msg.c_str();}
+    2133             : #if ! (__cplusplus > 199711L)
+    2134             :     /* Destructor should be declared in order to have the correct throw() before C++11 */
+    2135             :     /* see https://stackoverflow.com/questions/50025862/why-is-the-stdexception-destructor-not-noexcept */
+    2136             :     ~Exception() throw() {}
+    2137             : #endif
+    2138             :   };
+    2139             : #endif
+    2140             : 
+    2141             : #if __PLUMED_WRAPPER_CXX_ANONYMOUS_NAMESPACE_PLMD_EXCEPTIONS
+    2142             :   using ExceptionError = PLMD::ExceptionError;
+    2143             : #else
+    2144             :   /**
+    2145             :     Used to rethrow a PLMD::ExceptionError
+    2146             :   */
+    2147           0 :   class ExceptionError :
+    2148             :     public Exception {
+    2149             :   public:
+    2150           0 :     __PLUMED_WRAPPER_CXX_EXPLICIT ExceptionError(const char* msg): Exception(msg) {}
+    2151             : #if ! (__cplusplus > 199711L)
+    2152             :     /* Destructor should be declared in order to have the correct throw() before C++11 */
+    2153             :     /* see https://stackoverflow.com/questions/50025862/why-is-the-stdexception-destructor-not-noexcept */
+    2154             :     ~ExceptionError() throw() {}
+    2155             : #endif
+    2156             :   };
+    2157             : #endif
+    2158             : 
+    2159             : #if __PLUMED_WRAPPER_CXX_ANONYMOUS_NAMESPACE_PLMD_EXCEPTIONS
+    2160             :   using ExceptionDebug = PLMD::ExceptionDebug;
+    2161             : #else
+    2162             :   /**
+    2163             :     Used to rethrow a PLMD::ExceptionDebug
+    2164             :   */
+    2165           0 :   class ExceptionDebug :
+    2166             :     public Exception {
+    2167             :   public:
+    2168           0 :     __PLUMED_WRAPPER_CXX_EXPLICIT ExceptionDebug(const char* msg): Exception(msg) {}
+    2169             : #if ! (__cplusplus > 199711L)
+    2170             :     /* Destructor should be declared in order to have the correct throw() before C++11 */
+    2171             :     /* see https://stackoverflow.com/questions/50025862/why-is-the-stdexception-destructor-not-noexcept */
+    2172             :     ~ExceptionDebug() throw() {}
+    2173             : #endif
+    2174             :   };
+    2175             : #endif
+    2176             : 
+    2177             :   /**
+    2178             :     Thrown when trying to access an invalid plumed object
+    2179             :   */
+    2180             : 
+    2181           0 :   class Invalid :
+    2182             :     public Exception {
+    2183             :   public:
+    2184           0 :     __PLUMED_WRAPPER_CXX_EXPLICIT Invalid(const char* msg): Exception(msg) {}
+    2185             : #if ! (__cplusplus > 199711L)
+    2186             :     /* Destructor should be declared in order to have the correct throw() before C++11 */
+    2187             :     /* see https://stackoverflow.com/questions/50025862/why-is-the-stdexception-destructor-not-noexcept */
+    2188             :     ~Invalid() throw() {}
+    2189             : #endif
+    2190             :   };
+    2191             : 
+    2192             : #if __PLUMED_WRAPPER_CXX_ANONYMOUS_NAMESPACE_PLMD_EXCEPTIONS
+    2193             :   using ExceptionTypeError = PLMD::ExceptionTypeError;
+    2194             : #else
+    2195             :   /**
+    2196             :     Thrown when a wrong pointer is passed to the PLUMED interface.
+    2197             :   */
+    2198           0 :   class ExceptionTypeError:
+    2199             :     public Exception {
+    2200             :   public:
+    2201           0 :     __PLUMED_WRAPPER_CXX_EXPLICIT ExceptionTypeError(const char* msg): Exception(msg) {}
+    2202             : #if ! (__cplusplus > 199711L)
+    2203             :     /* Destructor should be declared in order to have the correct throw() before C++11 */
+    2204             :     /* see https://stackoverflow.com/questions/50025862/why-is-the-stdexception-destructor-not-noexcept */
+    2205             :     ~ExceptionTypeError() throw() {}
+    2206             : #endif
+    2207             :   };
+    2208             : #endif
+    2209             : 
+    2210             : #if __PLUMED_WRAPPER_CXX_ANONYMOUS_NAMESPACE_PLMD_EXCEPTIONS
+    2211             :   using LeptonException = PLMD::lepton::Exception;
+    2212             : #else
+    2213             :   /**
+    2214             :     Class used to rethrow Lepton exceptions.
+    2215             :   */
+    2216             : 
+    2217             :   class LeptonException :
+    2218             :     public ::std::exception
+    2219             :   {
+    2220             :     ::std::string msg;
+    2221             :   public:
+    2222           0 :     __PLUMED_WRAPPER_CXX_EXPLICIT LeptonException(const char* msg): msg(msg) {}
+    2223           0 :     const char* what() const __PLUMED_WRAPPER_CXX_NOEXCEPT __PLUMED_WRAPPER_CXX_OVERRIDE {return msg.c_str();}
+    2224             : #if ! (__cplusplus > 199711L)
+    2225             :     /* Destructor should be declared in order to have the correct throw() before C++11 */
+    2226             :     /* see https://stackoverflow.com/questions/50025862/why-is-the-stdexception-destructor-not-noexcept */
+    2227             :     ~LeptonException() throw() {}
+    2228             : #endif
+    2229             :   };
+    2230             : #endif
+    2231             : 
+    2232             : private:
+    2233             :   /*
+    2234             :     These exceptions are declared as private as they are not supposed to be
+    2235             :     catched by value. they only exist to allow a buffer to be attached to
+    2236             :     the std::exceptions that do not contain it already.
+    2237             :     Notice that these exceptions are those whose constructor should never throw, and as
+    2238             :     such they use a fixed size buffer.
+    2239             :   */
+    2240             : 
+    2241             :   template<typename T>
+    2242           0 :   class add_buffer_to:
+    2243             :     public T
+    2244             :   {
+    2245             :     char msg[__PLUMED_WRAPPER_CXX_EXCEPTION_BUFFER];
+    2246           0 :     void init(const char* msg) __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2247           0 :       this->msg[0]='\0';
+    2248           0 :       __PLUMED_WRAPPER_STD strncat(this->msg,msg,__PLUMED_WRAPPER_CXX_EXCEPTION_BUFFER-1);
+    2249           0 :       this->msg[__PLUMED_WRAPPER_CXX_EXCEPTION_BUFFER-1]='\0';
+    2250           0 :       if(PlumedGetenvExceptionsDebug() && __PLUMED_WRAPPER_STD strlen(msg) > __PLUMED_WRAPPER_CXX_EXCEPTION_BUFFER-1) __PLUMED_WRAPPER_STD fprintf(stderr,"+++ WARNING: message will be truncated\n");
+    2251           0 :     }
+    2252             :   public:
+    2253           0 :     __PLUMED_WRAPPER_CXX_EXPLICIT add_buffer_to(const char * msg) __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2254           0 :       init(msg);
+    2255             :     }
+    2256             :   add_buffer_to(const T& base,const char * msg) __PLUMED_WRAPPER_CXX_NOEXCEPT:
+    2257             :     T(base)
+    2258             :     {
+    2259             :       init(msg);
+    2260             :     }
+    2261           0 :   add_buffer_to(const add_buffer_to & other) __PLUMED_WRAPPER_CXX_NOEXCEPT:
+    2262           0 :     T(other)
+    2263             :     {
+    2264           0 :       init(other.msg);
+    2265             :     }
+    2266             :     add_buffer_to & operator=(const add_buffer_to & other) __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2267             :       if(this==&other) return *this;
+    2268             :       init(other.msg);
+    2269             :       return *this;
+    2270             :     }
+    2271           0 :     const char* what() const __PLUMED_WRAPPER_CXX_NOEXCEPT __PLUMED_WRAPPER_CXX_OVERRIDE {
+    2272           0 :       return msg;
+    2273             :     }
+    2274             : #if ! (__cplusplus > 199711L)
+    2275             :     /* Destructor should be declared in order to have the correct throw() before C++11 */
+    2276             :     /* see https://stackoverflow.com/questions/50025862/why-is-the-stdexception-destructor-not-noexcept */
+    2277             :     ~add_buffer_to() throw() {}
+    2278             : #endif
+    2279             :   };
+    2280             : 
+    2281             : private:
+    2282             :   /// Small class that wraps plumed_safeptr in order to make its initialization easier
+    2283             :   class SafePtr {
+    2284             :     /// non copyable (copy would require managing buffer, could be added in the future if needed)
+    2285             :     SafePtr(const SafePtr&);
+    2286             :     /// non assignable (assignment would require managing buffer, could be added in the future if needed)
+    2287             :     SafePtr& operator=(SafePtr const&);
+    2288             :   public:
+    2289             :     plumed_safeptr safe;
+    2290             :     /// This buffer holds a copy of the data when they are passed by value.
+    2291             :     /// The size is sufficient to hold any primitive type.
+    2292             :     /// Notice that the buffer is required to enable conversions (e.g., passing a class that can be converted to int)
+    2293             :     /// and, at the same time, allow the object to exist after SafePtr constructor has completed.
+    2294             :     /// A perhaps cleaner implementation would require a base class containing
+    2295             :     /// the plumed_safeptr object, derived classes depending on the
+    2296             :     /// argument type as a template parameter, and overloaded functions
+    2297             :     /// returning this derived class.
+    2298             :     char buffer[32];
+    2299             :     /// Default constructor, nullptr
+    2300             :     SafePtr() __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2301             :       safe.ptr=__PLUMED_WRAPPER_CXX_NULLPTR;
+    2302             :       safe.nelem=0;
+    2303             :       safe.shape=__PLUMED_WRAPPER_CXX_NULLPTR;
+    2304             :       safe.flags=0x10000*2;
+    2305             :       safe.opt=__PLUMED_WRAPPER_CXX_NULLPTR;
+    2306             :       buffer[0]='\0';
+    2307             :     }
+    2308             : 
+    2309         222 :     __PLUMED_WRAPPER_CXX_EXPLICIT SafePtr(const plumed_safeptr & safe,__PLUMED_WRAPPER_STD size_t nelem=0, const __PLUMED_WRAPPER_STD size_t* shape=__PLUMED_WRAPPER_CXX_NULLPTR) __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2310         222 :       this->safe=safe;
+    2311         222 :       buffer[0]='\0';
+    2312             :       if(nelem>0) this->safe.nelem=nelem;
+    2313             :       if(shape) this->safe.shape=const_cast<__PLUMED_WRAPPER_STD size_t*>(shape);
+    2314             :     }
+    2315             : 
+    2316             : #if __cplusplus > 199711L
+    2317             :     /// Construct from null
+    2318             :     SafePtr(__PLUMED_WRAPPER_STD nullptr_t,__PLUMED_WRAPPER_STD size_t nelem, const __PLUMED_WRAPPER_STD size_t* shape) noexcept {
+    2319             :       safe.ptr=nullptr;
+    2320             :       safe.nelem=0;
+    2321             :       safe.shape=nullptr;
+    2322             :       safe.flags=0x10000*2;
+    2323             :       safe.opt=nullptr;
+    2324             :       buffer[0]='\0';
+    2325             :       (void) nelem;
+    2326             :       (void) shape;
+    2327             :     }
+    2328             : #endif
+    2329             : 
+    2330             : /// Macro that generate a constructor with given type and flags
+    2331             : #define __PLUMED_WRAPPER_SAFEPTR_INNER(type_,flags_) \
+    2332             :   SafePtr(type_*ptr, __PLUMED_WRAPPER_STD size_t nelem, const __PLUMED_WRAPPER_STD size_t* shape) __PLUMED_WRAPPER_CXX_NOEXCEPT { \
+    2333             :     safe.ptr=ptr; \
+    2334             :     safe.nelem=nelem; \
+    2335             :     safe.shape=const_cast<__PLUMED_WRAPPER_STD size_t*>(shape); \
+    2336             :     safe.flags=flags_; \
+    2337             :     safe.opt=__PLUMED_WRAPPER_CXX_NULLPTR; \
+    2338             :     buffer[0]='\0'; \
+    2339             :   }
+    2340             : 
+    2341             : /// Macro that uses __PLUMED_WRAPPER_SAFEPTR_INNER to generate constructors with
+    2342             : /// all possible pointer-const combinations
+    2343             : #define __PLUMED_WRAPPER_SAFEPTR(type,code,size) \
+    2344             :   __PLUMED_WRAPPER_SAFEPTR_INNER(type,             size | (0x10000*(code)) | (0x2000000*2)) \
+    2345             :   __PLUMED_WRAPPER_SAFEPTR_INNER(type const,       size | (0x10000*(code)) | (0x2000000*3)) \
+    2346             :   __PLUMED_WRAPPER_SAFEPTR_INNER(type*,            size | (0x10000*(code)) | (0x2000000*4)) \
+    2347             :   __PLUMED_WRAPPER_SAFEPTR_INNER(type*const,       size | (0x10000*(code)) | (0x2000000*5)) \
+    2348             :   __PLUMED_WRAPPER_SAFEPTR_INNER(type const*,      size | (0x10000*(code)) | (0x2000000*6)) \
+    2349             :   __PLUMED_WRAPPER_SAFEPTR_INNER(type const*const, size | (0x10000*(code)) | (0x2000000*7))
+    2350             : 
+    2351             : /// Macro that generates the constructors from empy types (those of which sizeof cannot be computed)
+    2352             : #define __PLUMED_WRAPPER_SAFEPTR_EMPTY(type,code) __PLUMED_WRAPPER_SAFEPTR(type,code,0)
+    2353             : 
+    2354             : /// Macro that generates the constructors from sized types (those of which sizeof can be computed).
+    2355             : /// In addition to generating constructors with all pointer types, it generates a constructor to
+    2356             : /// allow pass-by-value
+    2357             : #define __PLUMED_WRAPPER_SAFEPTR_SIZED(type,code) \
+    2358             :   __PLUMED_WRAPPER_SAFEPTR(type,code,sizeof(type)) \
+    2359             :   SafePtr(type val, __PLUMED_WRAPPER_STD size_t nelem, const __PLUMED_WRAPPER_STD size_t* shape) __PLUMED_WRAPPER_CXX_NOEXCEPT { \
+    2360             :     assert(sizeof(type)<=32); \
+    2361             :     (void) nelem; \
+    2362             :     (void) shape; \
+    2363             :     safe.ptr=buffer; \
+    2364             :     safe.nelem=1; \
+    2365             :     safe.shape=__PLUMED_WRAPPER_CXX_NULLPTR; \
+    2366             :     safe.flags=sizeof(type) | (0x10000*(code)) | (0x2000000*1); \
+    2367             :     safe.opt=__PLUMED_WRAPPER_CXX_NULLPTR; \
+    2368             :     __PLUMED_WRAPPER_STD memcpy(buffer,&val,sizeof(type)); \
+    2369             :   }
+    2370             : 
+    2371             : /// Here we create all the required instances
+    2372             : /// 1: void
+    2373             : /// 3: integral
+    2374             : /// 4: floating
+    2375             : /// 5: FILE
+    2376             : /// 0x100: unsigned
+    2377         344 :     __PLUMED_WRAPPER_SAFEPTR_EMPTY(void,1)
+    2378        5040 :     __PLUMED_WRAPPER_SAFEPTR_SIZED(char,(CHAR_MIN==0)*0x100+3)
+    2379             :     __PLUMED_WRAPPER_SAFEPTR_SIZED(unsigned char,3)
+    2380             :     __PLUMED_WRAPPER_SAFEPTR_SIZED(signed char,0x100+3)
+    2381             :     __PLUMED_WRAPPER_SAFEPTR_SIZED(short,3)
+    2382             :     __PLUMED_WRAPPER_SAFEPTR_SIZED(unsigned short,0x100+3)
+    2383       10080 :     __PLUMED_WRAPPER_SAFEPTR_SIZED(int,3)
+    2384             :     __PLUMED_WRAPPER_SAFEPTR_SIZED(unsigned int,0x100+3)
+    2385             :     __PLUMED_WRAPPER_SAFEPTR_SIZED(long,3)
+    2386             :     __PLUMED_WRAPPER_SAFEPTR_SIZED(unsigned long,0x100+3)
+    2387             : #if __PLUMED_WRAPPER_CXX_LONGLONG
+    2388             :     __PLUMED_WRAPPER_SAFEPTR_SIZED(long long,3)
+    2389             :     __PLUMED_WRAPPER_SAFEPTR_SIZED(unsigned long long,0x100+3)
+    2390             : #endif
+    2391             :     __PLUMED_WRAPPER_SAFEPTR_SIZED(float,4)
+    2392             :     __PLUMED_WRAPPER_SAFEPTR_SIZED(double,4)
+    2393             :     __PLUMED_WRAPPER_SAFEPTR_SIZED(long double,4)
+    2394             :     __PLUMED_WRAPPER_SAFEPTR_EMPTY(FILE,5)
+    2395             : 
+    2396             :     /// Return the contained plumed_safeptr
+    2397             :     plumed_safeptr get_safeptr() const __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2398       15686 :       return safe;
+    2399             :     }
+    2400             : 
+    2401             :   };
+    2402             : 
+    2403             : public:
+    2404             : 
+    2405             :   /**
+    2406             :      Check if plumed is installed (for runtime binding)
+    2407             :      \return true if plumed is installed, false otherwise
+    2408             :      \note Equivalent to plumed_installed() but returns a bool
+    2409             :   */
+    2410             :   static bool installed() __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2411             :     return plumed_installed();
+    2412             :   }
+    2413             :   /**
+    2414             :      Check if Plumed object is valid. Available as of PLUMED 2.5
+    2415             :      \return true if plumed is valid, false otherwise
+    2416             :      \note Equivalent to plumed_valid() but returns a bool
+    2417             :   */
+    2418             :   bool valid() const __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2419             :     return plumed_valid(main);
+    2420             :   }
+    2421             : #if __cplusplus > 199711L
+    2422             :   /**
+    2423             :      Same as \ref valid(). Available as of PLUMED 2.5.
+    2424             : 
+    2425             :   Allow code such as
+    2426             :   \verbatim
+    2427             :   Plumed p;
+    2428             :   if(!p) raise_error();
+    2429             :   p.cmd("init");
+    2430             :   \endverbatim
+    2431             : 
+    2432             :   In order to avoid ambiguous conversions, this is only allowed when compiling with C++11
+    2433             :   where it is marked as explicit.
+    2434             :   */
+    2435             :   explicit
+    2436             :   operator bool() const __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2437             :     return plumed_valid(main);
+    2438             :   }
+    2439             : #endif
+    2440             : 
+    2441             :   /**
+    2442             :      Returns the number of references to this object. Available as of PLUMED 2.5.
+    2443             :     \note Equivalent to plumed_use_count()
+    2444             :   */
+    2445             :   int useCount() const __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2446             :     return plumed_use_count(main);
+    2447             :   }
+    2448             : 
+    2449             : #if __PLUMED_WRAPPER_GLOBAL /*{*/
+    2450             :   /**
+    2451             :      Check if global-plumed has been initialized
+    2452             :      \return true if global plumed object (see global()) is initialized (i.e. if gcreate() has been
+    2453             :              called), false otherwise.
+    2454             :      \note Equivalent to plumed_ginitialized() but returns a bool
+    2455             :   */
+    2456             :   static bool ginitialized() __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2457             :     return plumed_ginitialized();
+    2458             :   }
+    2459             :   /**
+    2460             :      Check if global-plumed is valid
+    2461             :      \return true if global plumed object (see global()) is valid.
+    2462             :      \note Equivalent to plumed_gvalid() but returns a bool
+    2463             :   */
+    2464             :   static bool gvalid() __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2465             :     return plumed_gvalid();
+    2466             :   }
+    2467             :   /**
+    2468             :      Initialize global-plumed.
+    2469             :      \warning Using the global objects in C++ is not recommended since they are difficult to use in
+    2470             :               an exception safe manner. In particular, one should explicitly catch exceptions to
+    2471             :               properly call gfinalize()
+    2472             :      \note Equivalent to plumed_gcreate()
+    2473             :   */
+    2474             :   static void gcreate() __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2475             :     plumed_gcreate();
+    2476             :   }
+    2477             :   /**
+    2478             :      Send a command to global-plumed
+    2479             :       \param key The name of the command to be executed
+    2480             :      \note Equivalent to plumed_gcmd()
+    2481             :   */
+    2482             :   static void gcmd(const char*key) {
+    2483             :     global().cmd(key);
+    2484             :   }
+    2485             :   /**
+    2486             :      Send a command to global-plumed
+    2487             :       \param key The name of the command to be executed
+    2488             :       \param val The argument.
+    2489             :      \note Equivalent to plumed_gcmd()
+    2490             :   */
+    2491             :   template<typename T>
+    2492             :   static void gcmd(const char*key,T val) {
+    2493             :     global().cmd(key,val);
+    2494             :   }
+    2495             :   /**
+    2496             :      Send a command to global-plumed
+    2497             :       \param key The name of the command to be executed
+    2498             :       \param val The argument.
+    2499             :       \param nelem Number of elements in the passed array, for typechecking.
+    2500             :      \note Equivalent to plumed_gcmd()
+    2501             :   */
+    2502             :   template<typename T>
+    2503             :   static void gcmd(const char*key,T* val,__PLUMED_WRAPPER_STD size_t nelem) {
+    2504             :     global().cmd(key,val,nelem);
+    2505             :   }
+    2506             : 
+    2507             :   /**
+    2508             :      Send a command to global-plumed
+    2509             :       \param key The name of the command to be executed
+    2510             :       \param val The argument.
+    2511             :       \param shape The shape of the argument.
+    2512             :      \note Equivalent to plumed_gcmd()
+    2513             :   */
+    2514             :   template<typename T>
+    2515             :   static void gcmd(const char*key,T* val, const __PLUMED_WRAPPER_STD size_t* shape) {
+    2516             :     global().cmd(key,val,shape);
+    2517             :   }
+    2518             : 
+    2519             : #if __cplusplus > 199711L
+    2520             :   /**
+    2521             :      Send a command to global-plumed
+    2522             :       \param key The name of the command to be executed
+    2523             :       \param val The argument.
+    2524             :       \param shape The shape of the argument, in the form of an initialier_list (e.g., {10,3}).
+    2525             :      \note Equivalent to plumed_gcmd()
+    2526             :   */
+    2527             :   template<typename T>
+    2528             :   static void gcmd(const char*key,T* val, std::initializer_list<std::size_t> shape) {
+    2529             :     global().cmd(key,val,shape);
+    2530             :   }
+    2531             : #endif
+    2532             : 
+    2533             :   /**
+    2534             :      Finalize global-plumed
+    2535             :   */
+    2536             :   static void gfinalize() __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2537             :     plumed_gfinalize();
+    2538             :   }
+    2539             :   /**
+    2540             :      Returns the Plumed global object
+    2541             : 
+    2542             :      Notice that the object is copied, thus increasing the reference counter of the
+    2543             :      global object. In this manner, the global object will survive after a call to
+    2544             :      \ref gfinalize() if the resulting object is still in scope.
+    2545             : 
+    2546             :      \return The Plumed global object
+    2547             :   */
+    2548             :   static Plumed global() __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2549             :     return Plumed(plumed_global());
+    2550             :   }
+    2551             : #endif /*}*/
+    2552             :   /**
+    2553             :      Constructor.
+    2554             : 
+    2555             :     Notice that when using runtime binding the constructed object might be
+    2556             :     invalid. One might check it using the \ref valid() method.
+    2557             : 
+    2558             :     \note Performs the same task a plumed_create()
+    2559             :   */
+    2560        5040 : Plumed()__PLUMED_WRAPPER_CXX_NOEXCEPT :
+    2561             : #if __PLUMED_WRAPPER_CXX_DEFAULT_INVALID
+    2562             :   main(plumed_create_invalid())
+    2563             : #else
+    2564        5040 :   main(plumed_create())
+    2565             : #endif
+    2566             :   {
+    2567             :   }
+    2568             : 
+    2569             :   /**
+    2570             :      Clone a Plumed object from a FORTRAN char* handler.
+    2571             : 
+    2572             :      \param c The FORTRAN handler (a char[32]).
+    2573             : 
+    2574             :      The reference counter for the corresponding object will be increased
+    2575             :      to make sure that the object will be available after plumed_f_finalize is called
+    2576             :      if the created object is still in scope.
+    2577             :   */
+    2578             : __PLUMED_WRAPPER_CXX_EXPLICIT Plumed(const char*c)__PLUMED_WRAPPER_CXX_NOEXCEPT :
+    2579             :   main(plumed_create_reference_f(c))
+    2580             :   {
+    2581             :   }
+    2582             : 
+    2583             :   /**
+    2584             :     Create a reference from a void* pointer. Available as of PLUMED 2.5.
+    2585             :   */
+    2586             : __PLUMED_WRAPPER_CXX_EXPLICIT Plumed(void*v)__PLUMED_WRAPPER_CXX_NOEXCEPT :
+    2587             :   main(plumed_create_reference_v(v))
+    2588             :   {
+    2589             :   }
+    2590             : 
+    2591             :   /**
+    2592             :      Clone a Plumed object from a C plumed structure
+    2593             : 
+    2594             :      \param p The C plumed structure.
+    2595             : 
+    2596             :      The reference counter for the corresponding object will be increased
+    2597             :      to make sure that the object will be available after plumed_finalize is called
+    2598             :      if the created object is still in scope.
+    2599             :   */
+    2600             : __PLUMED_WRAPPER_CXX_EXPLICIT Plumed(plumed p)__PLUMED_WRAPPER_CXX_NOEXCEPT :
+    2601             :   main(plumed_create_reference(p))
+    2602             :   {
+    2603             :   }
+    2604             : 
+    2605             :   /** Copy constructor.
+    2606             : 
+    2607             :     Takes a reference, incrementing the reference counter of the corresponding object.
+    2608             :   */
+    2609             : Plumed(const Plumed& p)__PLUMED_WRAPPER_CXX_NOEXCEPT :
+    2610             :   main(plumed_create_reference(p.main))
+    2611             :   {
+    2612             :   }
+    2613             : 
+    2614             :   /** Assignment operator. Available as of PLUMED 2.5.
+    2615             : 
+    2616             :     Takes a reference,incrementing the reference counter of the corresponding object.
+    2617             :   */
+    2618             :   Plumed&operator=(const Plumed&p) __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2619             :     if(this != &p) {
+    2620             : // the check is needed to avoid calling plumed_finalize on moved objects
+    2621             :       if(main.p) plumed_finalize(main);
+    2622             :       main=plumed_create_reference(p.main);
+    2623             :     }
+    2624             :     return *this;
+    2625             :   }
+    2626             : 
+    2627             :   /*
+    2628             :     PLUMED >= 2.4 requires a C++11 compiler.
+    2629             :     Anyway, since Plumed.h file might be redistributed with other codes
+    2630             :     and it should be possible to combine it with earlier PLUMED versions,
+    2631             :     we here explicitly check if C+11 is available before enabling move semantics.
+    2632             :   */
+    2633             : #if __cplusplus > 199711L
+    2634             :   /** Move constructor. Available as of PLUMED 2.5.
+    2635             :     Only if move semantics is enabled.
+    2636             :   */
+    2637             : Plumed(Plumed&&p)__PLUMED_WRAPPER_CXX_NOEXCEPT :
+    2638             :   main(p.main)
+    2639             :   {
+    2640             :     p.main.p=nullptr;
+    2641             :   }
+    2642             :   /** Move assignment. Available as of PLUMED 2.5.
+    2643             :     Only if move semantics is enabled.
+    2644             :   */
+    2645             :   Plumed& operator=(Plumed&&p)__PLUMED_WRAPPER_CXX_NOEXCEPT  {
+    2646             :     if(this != &p) {
+    2647             : // the check is needed to avoid calling plumed_finalize on moved objects
+    2648             :       if(main.p) plumed_finalize(main);
+    2649             :       main=p.main;
+    2650             :       p.main.p=nullptr;
+    2651             :     }
+    2652             :     return *this;
+    2653             :   }
+    2654             : #endif
+    2655             :   /**
+    2656             :     Create a PLUMED object loading a specific kernel. Available as of PLUMED 2.5.
+    2657             : 
+    2658             :     It returns an object created with \ref plumed_create_dlopen. The object is owned and
+    2659             :     is then finalized in the destructor. It can be used as follows:
+    2660             :   \verbatim
+    2661             :     PLMD::Plumed p = PLMD::Plumed::dlopen("/path/to/libplumedKernel.so");
+    2662             :   // or, equivalenty:
+    2663             :   //    PLMD::Plumed p(PLMD::Plumed::dlopen("/path/to/libplumedKernel.so"));
+    2664             :     p.cmd("init");
+    2665             :   \endverbatim
+    2666             :     or, equivalently, as
+    2667             :   \verbatim
+    2668             :     auto p = PLMD::Plumed::dlopen("/path/to/libplumedKernel.so");
+    2669             :     p.cmd("init");
+    2670             :   \endverbatim
+    2671             :   */
+    2672             :   static Plumed dlopen(const char* path)__PLUMED_WRAPPER_CXX_NOEXCEPT  {
+    2673             :     plumed p=plumed_create_dlopen(path);
+    2674             :     Plumed pp(p);
+    2675             :     plumed_finalize(p);
+    2676             :     return pp;
+    2677             :   }
+    2678             : 
+    2679             :   /**
+    2680             :     Create a PLUMED object loading a specific kernel. Available as of PLUMED 2.5.
+    2681             : 
+    2682             :     Same as \ref dlopen(const char* path), but allows a dlopen mode to be chosen explicitly.
+    2683             :   */
+    2684             :   static Plumed dlopen(const char* path,int mode)__PLUMED_WRAPPER_CXX_NOEXCEPT  {
+    2685             :     plumed p=plumed_create_dlopen2(path,mode);
+    2686             :     Plumed pp(p);
+    2687             :     plumed_finalize(p);
+    2688             :     return pp;
+    2689             :   }
+    2690             :   /**
+    2691             :     Create a PLUMED object loading from an already opened shared library. Available as of PLUMED 2.8.
+    2692             : 
+    2693             :     Same as \ref dlopen(const char* path), but searches functions in an already loaded library.
+    2694             :     See \ref plumed_create_dlsym.
+    2695             :   */
+    2696             :   static Plumed dlsym(void* dlhandle)__PLUMED_WRAPPER_CXX_NOEXCEPT  {
+    2697             :     plumed p=plumed_create_dlsym(dlhandle);
+    2698             :     Plumed pp(p);
+    2699             :     plumed_finalize(p);
+    2700             :     return pp;
+    2701             :   }
+    2702             : 
+    2703             :   /** Invalid constructor. Available as of PLUMED 2.5.
+    2704             : 
+    2705             :     Can be used to initialize an invalid object. It might be useful to postpone
+    2706             :     the initialization of a Plumed object. Consider the following case
+    2707             :   \verbatim
+    2708             :     Plumed p;
+    2709             :     setenv("PLUMED_KERNEL","/path/to/kernel/libplumedKernel.so",1);
+    2710             :     p.cmd("init")
+    2711             :   \endverbatim
+    2712             :     Here the `p` object will be initialized *before* the `PLUMED_KERNEL` env var has been set.
+    2713             :     This can be particularly problematic if `p` is stored in some high level class.
+    2714             :     The following case would do the job
+    2715             :   \verbatim
+    2716             :     Plumed p;
+    2717             :     setenv("PLUMED_KERNEL","/path/to/kernel/libplumedKernel.so",1);
+    2718             :     p=Plumed();
+    2719             :     p.cmd("init")
+    2720             :   \endverbatim
+    2721             :     However, there will be some error reported related to the attempt to load the kernel
+    2722             :     when `p` is initialized. The following solution is the optimal one:
+    2723             :   \verbatim
+    2724             :     Plumed p(Plumed::makeInvalid());
+    2725             :     setenv("PLUMED_KERNEL","/path/to/kernel/libplumedKernel.so",1);
+    2726             :     p=Plumed();
+    2727             :     p.cmd("init")
+    2728             :   \endverbatim
+    2729             :   */
+    2730             :   static Plumed makeInvalid() __PLUMED_WRAPPER_CXX_NOEXCEPT  {
+    2731             :     plumed p=plumed_create_invalid();
+    2732             :     Plumed pp(p);
+    2733             :     plumed_finalize(p);
+    2734             :     return pp;
+    2735             :   }
+    2736             : 
+    2737             :   /**
+    2738             :     Create a valid PLMD::Plumed object.
+    2739             : 
+    2740             :     Can be used to create a valid object e.g. when Plumed.h was compiled with
+    2741             :     `-D__PLUMED_WRAPPER_CXX_DEFAULT_INVALID`. For internal usage.
+    2742             :   */
+    2743             : 
+    2744             :   static Plumed makeValid()__PLUMED_WRAPPER_CXX_NOEXCEPT  {
+    2745             :     plumed p=plumed_create();
+    2746             :     Plumed pp(p);
+    2747             :     plumed_finalize(p);
+    2748             :     return pp;
+    2749             :   }
+    2750             : 
+    2751             : 
+    2752             :   /**
+    2753             :      Retrieve the C plumed structure for this object.
+    2754             : 
+    2755             :      Notice that the resulting plumed structure is a weak reference and
+    2756             :      should NOT be finalized, unless a new reference is explicitly added
+    2757             :   \verbatim
+    2758             :   Plumed p;
+    2759             :   plumed c=p;
+    2760             :   plumed_finalize(c); // <- this is wrong
+    2761             :   \endverbatim
+    2762             :   \verbatim
+    2763             :   Plumed p;
+    2764             :   plumed c=plumed_create_reference(p);
+    2765             :   plumed_finalize(c); // <- this is right
+    2766             :   \endverbatim
+    2767             :   */
+    2768             :   operator plumed()const __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2769             :     return main;
+    2770             :   }
+    2771             : 
+    2772             :   /**
+    2773             :      Retrieve a FORTRAN handler for this object
+    2774             :       \param c The FORTRAN handler (a char[32]).
+    2775             :     Notice that the resulting plumed structure is a weak reference and
+    2776             :     should NOT be finalized, unless a new reference is explicitly added.
+    2777             :   */
+    2778             :   void toFortran(char*c)const __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2779             :     plumed_c2f(main,c);
+    2780             :   }
+    2781             : 
+    2782             :   /**
+    2783             :      Retrieve a void* handler for this object. Available as of PLUMED 2.5.
+    2784             :     Notice that the resulting plumed structure is a weak reference and
+    2785             :     should NOT be finalized, unless a new reference is explicitly added.
+    2786             :   */
+    2787             :   void* toVoid()const __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2788             :     return plumed_c2v(main);
+    2789             :   }
+    2790             : 
+    2791             :   /**
+    2792             :     Increase reference counter. Available as of PLUMED 2.5.
+    2793             : 
+    2794             :     Using this method improperly might interfere with correct object construction
+    2795             :     and destruction.
+    2796             :     If you want to play with this, also try to compile using `-D__PLUMED_WRAPPER_DEBUG_REFCOUNT=1` and see what happens.
+    2797             : 
+    2798             :     A possible usage is to transfer the ownership of a temporary
+    2799             :     object when it is converted
+    2800             :   \verbatim
+    2801             :   plumed p=Plumed::dlopen(path).incref()
+    2802             :   // without incref(), the just constructed object will be destroyed
+    2803             :   // when the temporary object is deleted.
+    2804             :   ... do stuff ...
+    2805             :   plumed_finalize(p);
+    2806             :   \endverbatim
+    2807             : 
+    2808             :   */
+    2809             :   Plumed& incref() __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2810             :     plumed_create_reference(main);
+    2811             :     return *this;
+    2812             :   }
+    2813             : 
+    2814             :   /**
+    2815             :     Decrease reference counter. Available as of PLUMED 2.5.
+    2816             : 
+    2817             :     Using this method improperly might interfere with correct object construction
+    2818             :     and destruction.
+    2819             :     If you want to play with this, also try to compile using `-D__PLUMED_WRAPPER_DEBUG_REFCOUNT=1` and see what happens.
+    2820             :   */
+    2821             :   Plumed& decref() __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2822             : // calling decref on a moved plumed object should give an error, so we do not check if main.p!=NULL here:
+    2823             :     plumed_finalize(main);
+    2824             :     return *this;
+    2825             :   }
+    2826             : 
+    2827             : private:
+    2828             : 
+    2829             :   /**
+    2830             :     Private version of cmd. It is used here to avoid duplication of code between typesafe and not-typesafe versions
+    2831             :   */
+    2832       15686 :   static void cmd_priv(plumed main,const char*key, SafePtr*safe=__PLUMED_WRAPPER_CXX_NULLPTR, const void* unsafe=__PLUMED_WRAPPER_CXX_NULLPTR,plumed_error*error=__PLUMED_WRAPPER_CXX_NULLPTR) {
+    2833             : 
+    2834             :     plumed_error error_cxx;
+    2835             :     plumed_error_init(&error_cxx);
+    2836             : 
+    2837             :     plumed_nothrow_handler nothrow;
+    2838       15686 :     if(error) {
+    2839             :       plumed_error_init(error);
+    2840           0 :       nothrow.ptr=error;
+    2841             :     } else {
+    2842       15686 :       nothrow.ptr=&error_cxx;
+    2843             :     }
+    2844       15686 :     nothrow.handler=plumed_error_set;
+    2845             : 
+    2846             :     try {
+    2847       15686 :       if(safe) {
+    2848       15686 :         plumed_cmd_safe_nothrow(main,key,safe->get_safeptr(),nothrow);
+    2849             :       } else {
+    2850           0 :         plumed_cmd_nothrow(main,key,unsafe,nothrow);
+    2851             :       }
+    2852           0 :     } catch (...) {
+    2853             :       assert(error_cxx.code==0); /* no need to plumed_error_finalize here */
+    2854             :       /*
+    2855             :         When loading a kernel <=2.4, plumed_cmd_nothrow could throw an exception.
+    2856             :         If the exception is transmitted through the C interface and arrives here,
+    2857             :         we translate it so as to free the virtual tables of the loaded kernel.
+    2858             :       */
+    2859           0 :       rethrow();
+    2860           0 :     }
+    2861             :     /* plumed_error_rethrow is finalizing */
+    2862       15686 :     if(!error && error_cxx.code!=0) plumed_error_rethrow_cxx(error_cxx);
+    2863       15686 :   }
+    2864             : 
+    2865             : public:
+    2866             : 
+    2867             :   /**
+    2868             :      Send a command to this plumed object
+    2869             :       \param key The name of the command to be executed
+    2870             :       \note Similar to \ref plumed_cmd(). It actually called \ref plumed_cmd_nothrow() and
+    2871             :             rethrow any exception raised within PLUMED.
+    2872             :   */
+    2873             :   void cmd(const char*key) {
+    2874             :     plumed_cmd_cxx(main,key);
+    2875             :   }
+    2876             : 
+    2877             :   /**
+    2878             :      Send a command to this plumed object
+    2879             :       \param key The name of the command to be executed
+    2880             :       \param val The argument, passed by value.
+    2881             :       \note Similar to \ref plumed_cmd(). It actually called \ref plumed_cmd_nothrow() and
+    2882             :             rethrow any exception raised within PLUMED.
+    2883             :       \note Unless one defines __PLUMED_WRAPPER_CXX_TYPESAFE=0 or PLUMED library is <=2.7,
+    2884             :              the type of the argument is checked.
+    2885             :   */
+    2886             :   template<typename T>
+    2887             :   void cmd(const char*key,T val) {
+    2888       15464 :     plumed_cmd_cxx(main,key,val);
+    2889       15464 :   }
+    2890             : 
+    2891             :   /**
+    2892             :      Send a command to this plumed object
+    2893             :       \param key The name of the command to be executed
+    2894             :       \param val The argument, passed by pointer.
+    2895             :       \param shape A zero-terminated array containing the shape of the data.
+    2896             :       \note Similar to \ref plumed_cmd(). It actually called \ref plumed_cmd_nothrow() and
+    2897             :             rethrow any exception raised within PLUMED.
+    2898             :       \note Unless one defines __PLUMED_WRAPPER_CXX_TYPESAFE=0 or PLUMED library is <=2.7,
+    2899             :              the type of the argument is checked. If shape is passed, it is also
+    2900             :              checked that PLUMED access only compatible indexes.
+    2901             :   */
+    2902             :   template<typename T>
+    2903             :   void cmd(const char*key,T* val, const __PLUMED_WRAPPER_STD size_t* shape) {
+    2904             :     plumed_cmd_cxx(main,key,val,shape);
+    2905             :   }
+    2906             : 
+    2907             : #if __cplusplus > 199711L
+    2908             :   /**
+    2909             :      Send a command to this plumed object
+    2910             :       \param key The name of the command to be executed
+    2911             :       \param val The argument, passed by pointer.
+    2912             :       \param shape The shape of the argument, in the form of an initialier_list (e.g., {10,3}).
+    2913             :       \note Similar to \ref plumed_cmd(). It actually called \ref plumed_cmd_nothrow() and
+    2914             :             rethrow any exception raised within PLUMED.
+    2915             :       \note Unless one defines __PLUMED_WRAPPER_CXX_TYPESAFE=0 or PLUMED library is <=2.7,
+    2916             :              the type of the argument is checked. If shape is passed, it is also
+    2917             :              checked that PLUMED access only compatible indexes.
+    2918             :   */
+    2919             :   template<typename T>
+    2920             :   void cmd(const char*key,T* val, std::initializer_list<std::size_t> shape) {
+    2921             :     if(shape.size()>4) throw Plumed::ExceptionTypeError("Maximum shape size is 4");
+    2922             :     std::array<std::size_t,5> shape_;
+    2923             :     unsigned j=0;
+    2924             :     for(auto i : shape) {
+    2925             :       shape_[j]=i;
+    2926             :       j++;
+    2927             :     }
+    2928             :     shape_[j]=0;
+    2929             :     plumed_cmd_cxx(main,key,val,&shape_[0]);
+    2930             :   }
+    2931             : #endif
+    2932             :   /**
+    2933             :      Send a command to this plumed object
+    2934             :       \param key The name of the command to be executed
+    2935             :       \param val The argument, passed by pointer.
+    2936             :       \param nelem The number of elements passed.
+    2937             :       \note Similar to \ref plumed_cmd(). It actually called \ref plumed_cmd_nothrow() and
+    2938             :             rethrow any exception raised within PLUMED.
+    2939             :       \note Unless one defines __PLUMED_WRAPPER_CXX_TYPESAFE=0 or PLUMED library is <=2.7,
+    2940             :              the type of the argument is checked.  nelem is used to check
+    2941             :              the maximum index interpreting the array as flattened.
+    2942             :   */
+    2943             :   template<typename T>
+    2944             :   void cmd(const char*key,T* val, __PLUMED_WRAPPER_STD size_t nelem) {
+    2945             :     plumed_cmd_cxx(main,key,val,nelem);
+    2946             :   }
+    2947             : 
+    2948             :   /**
+    2949             :      Destructor
+    2950             : 
+    2951             :      It calls \ref plumed_finalize(). Notice that this is done also if the
+    2952             :      constructor failed (that is, if it returned an invalid object). This allows
+    2953             :      declaring Plumed objects also if PLUMED is actually not available, provided
+    2954             :      one does not use the \ref cmd method.
+    2955             : 
+    2956             :      Destructor is virtual so as to allow correct inheritance from Plumed object.
+    2957             :   */
+    2958             : #if __PLUMED_WRAPPER_CXX_POLYMORPHIC
+    2959             :   virtual
+    2960             : #endif
+    2961             :   ~Plumed() __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2962             : // the check is needed to avoid calling plumed_finalize on moved objects
+    2963        5040 :     if(main.p) plumed_finalize(main);
+    2964        5040 :   }
+    2965             : 
+    2966             :   /**
+    2967             :     These functions can be used to make plumed_cmd behave as the C++ wrapper PLMD::Plumed::cmd,
+    2968             :     namely implement typechecks and rethrowing exception.
+    2969             :     To be used through the macro plumed_cmd (defined when __PLUMED_WRAPPER_CXX_BIND_C==1).
+    2970             :     They are also used by the Plumed::cmd functions to avoid code duplication.
+    2971             :     Available as of PLUMED 2.8.
+    2972             :   */
+    2973             :   static void plumed_cmd_cxx(plumed p,const char*key,plumed_error* error=__PLUMED_WRAPPER_CXX_NULLPTR) {
+    2974             : #if __PLUMED_WRAPPER_CXX_TYPESAFE
+    2975             :     SafePtr s;
+    2976             :     cmd_priv(p,key,&s,__PLUMED_WRAPPER_CXX_NULLPTR,error);
+    2977             : #else
+    2978             :     cmd_priv(p,key,__PLUMED_WRAPPER_CXX_NULLPTR,__PLUMED_WRAPPER_CXX_NULLPTR,error);
+    2979             : #endif
+    2980             :   }
+    2981             : 
+    2982             :   /**
+    2983             :     These functions can be used to make plumed_cmd behave as the C++ wrapper PLMD::Plumed::cmd,
+    2984             :     namely implement typechecks and rethrowing exception.
+    2985             :     To be used through the macro plumed_cmd (defined when __PLUMED_WRAPPER_CXX_BIND_C==1).
+    2986             :     They are also used by the Plumed::cmd functions to avoid code duplication.
+    2987             :     Available as of PLUMED 2.8.
+    2988             :   */
+    2989             :   template<typename T>
+    2990         222 :   static void plumed_cmd_cxx(plumed p,const char*key,T val,plumed_error* error=__PLUMED_WRAPPER_CXX_NULLPTR) {
+    2991             : #if __PLUMED_WRAPPER_CXX_TYPESAFE
+    2992             :     SafePtr s(val,0,__PLUMED_WRAPPER_CXX_NULLPTR);
+    2993         222 :     cmd_priv(p,key,&s,__PLUMED_WRAPPER_CXX_NULLPTR,error);
+    2994             : #else
+    2995             :     cmd_priv(p,key,__PLUMED_WRAPPER_CXX_NULLPTR,&val,error);
+    2996             : #endif
+    2997         222 :   }
+    2998             : 
+    2999             :   /**
+    3000             :     These functions can be used to make plumed_cmd behave as the C++ wrapper PLMD::Plumed::cmd,
+    3001             :     namely implement typechecks and rethrowing exception.
+    3002             :     To be used through the macro plumed_cmd (defined when __PLUMED_WRAPPER_CXX_BIND_C==1).
+    3003             :     They are also used by the Plumed::cmd functions to avoid code duplication.
+    3004             :     Available as of PLUMED 2.8.
+    3005             :   */
+    3006             :   template<typename T>
+    3007       15464 :   static void plumed_cmd_cxx(plumed p,const char*key,T* val,plumed_error* error=__PLUMED_WRAPPER_CXX_NULLPTR) {
+    3008             : #if __PLUMED_WRAPPER_CXX_TYPESAFE
+    3009             :     SafePtr s(val,0,__PLUMED_WRAPPER_CXX_NULLPTR);
+    3010       15464 :     cmd_priv(p,key,&s,__PLUMED_WRAPPER_CXX_NULLPTR,error);
+    3011             : #else
+    3012             :     cmd_priv(p,key,__PLUMED_WRAPPER_CXX_NULLPTR,val,error);
+    3013             : #endif
+    3014       15464 :   }
+    3015             : 
+    3016             :   /**
+    3017             :     These functions can be used to make plumed_cmd behave as the C++ wrapper PLMD::Plumed::cmd,
+    3018             :     namely implement typechecks and rethrowing exception.
+    3019             :     To be used through the macro plumed_cmd (defined when __PLUMED_WRAPPER_CXX_BIND_C==1).
+    3020             :     They are also used by the Plumed::cmd functions to avoid code duplication.
+    3021             :     Available as of PLUMED 2.8.
+    3022             :   */
+    3023             :   template<typename T>
+    3024             :   static void plumed_cmd_cxx(plumed p,const char*key,T* val, __PLUMED_WRAPPER_STD size_t nelem,plumed_error* error=__PLUMED_WRAPPER_CXX_NULLPTR) {
+    3025             : #if __PLUMED_WRAPPER_CXX_TYPESAFE
+    3026             :     SafePtr s(val,nelem,__PLUMED_WRAPPER_CXX_NULLPTR);
+    3027             :     cmd_priv(p,key,&s,__PLUMED_WRAPPER_CXX_NULLPTR,error);
+    3028             : #else
+    3029             :     cmd_priv(p,key,__PLUMED_WRAPPER_CXX_NULLPTR,val,error);
+    3030             : #endif
+    3031             :   }
+    3032             : 
+    3033             :   /**
+    3034             :     These functions can be used to make plumed_cmd behave as the C++ wrapper PLMD::Plumed::cmd,
+    3035             :     namely implement typechecks and rethrowing exception.
+    3036             :     To be used through the macro plumed_cmd (defined when __PLUMED_WRAPPER_CXX_BIND_C==1).
+    3037             :     They are also used by the Plumed::cmd functions to avoid code duplication.
+    3038             :     Available as of PLUMED 2.8.
+    3039             :   */
+    3040             :   template<typename T>
+    3041             :   static void plumed_cmd_cxx(plumed p,const char*key,T* val, const __PLUMED_WRAPPER_STD size_t* shape,plumed_error* error=__PLUMED_WRAPPER_CXX_NULLPTR) {
+    3042             : #if __PLUMED_WRAPPER_CXX_TYPESAFE
+    3043             :     SafePtr s(val,0,shape);
+    3044             :     cmd_priv(p,key,&s,__PLUMED_WRAPPER_CXX_NULLPTR,error);
+    3045             : #else
+    3046             :     cmd_priv(p,key,__PLUMED_WRAPPER_CXX_NULLPTR,val,error);
+    3047             : #endif
+    3048             :   }
+    3049             : 
+    3050             : 
+    3051             : #if __PLUMED_WRAPPER_GLOBAL /*{*/
+    3052             :   /**
+    3053             :     \related Plumed
+    3054             :     This function can be used to make plumed_gcmd behave as the C++ wrapper PLMD::Plumed::gcmd,
+    3055             :     namely implement typechecks and rethrowing exception.
+    3056             :     To be used through the macro plumed_gcmd (defined when __PLUMED_WRAPPER_CXX_BIND_C==1).
+    3057             :     Available as of PLUMED 2.8.
+    3058             :   */
+    3059             : 
+    3060             :   /**
+    3061             :     These functions can be used to make plumed_cmd behave as the C++ wrapper PLMD::Plumed::cmd,
+    3062             :     namely implement typechecks and rethrowing exception.
+    3063             :     To be used through the macro plumed_cmd (defined when __PLUMED_WRAPPER_CXX_BIND_C==1).
+    3064             :     They are also used by the Plumed::cmd functions to avoid code duplication.
+    3065             :     Available as of PLUMED 2.8.
+    3066             :   */
+    3067             :   static void plumed_gcmd_cxx(const char*key,plumed_error* error=__PLUMED_WRAPPER_CXX_NULLPTR) {
+    3068             :     plumed_cmd_cxx(plumed_global(),key,error);
+    3069             :   }
+    3070             : 
+    3071             :   /**
+    3072             :     These functions can be used to make plumed_cmd behave as the C++ wrapper PLMD::Plumed::cmd,
+    3073             :     namely implement typechecks and rethrowing exception.
+    3074             :     To be used through the macro plumed_cmd (defined when __PLUMED_WRAPPER_CXX_BIND_C==1).
+    3075             :     They are also used by the Plumed::cmd functions to avoid code duplication.
+    3076             :     Available as of PLUMED 2.8.
+    3077             :   */
+    3078             :   template<typename T>
+    3079             :   static void plumed_gcmd_cxx(const char*key,T val,plumed_error* error=__PLUMED_WRAPPER_CXX_NULLPTR) {
+    3080             :     plumed_cmd_cxx(plumed_global(),key,val,error);
+    3081             :   }
+    3082             : 
+    3083             :   /**
+    3084             :     These functions can be used to make plumed_cmd behave as the C++ wrapper PLMD::Plumed::cmd,
+    3085             :     namely implement typechecks and rethrowing exception.
+    3086             :     To be used through the macro plumed_cmd (defined when __PLUMED_WRAPPER_CXX_BIND_C==1).
+    3087             :     They are also used by the Plumed::cmd functions to avoid code duplication.
+    3088             :     Available as of PLUMED 2.8.
+    3089             :   */
+    3090             :   template<typename T>
+    3091             :   static void plumed_gcmd_cxx(const char*key,T val, __PLUMED_WRAPPER_STD size_t nelem,plumed_error* error=__PLUMED_WRAPPER_CXX_NULLPTR) {
+    3092             :     plumed_cmd_cxx(plumed_global(),key,val,nelem,error);
+    3093             :   }
+    3094             : 
+    3095             :   /**
+    3096             :     These functions can be used to make plumed_cmd behave as the C++ wrapper PLMD::Plumed::cmd,
+    3097             :     namely implement typechecks and rethrowing exception.
+    3098             :     To be used through the macro plumed_cmd (defined when __PLUMED_WRAPPER_CXX_BIND_C==1).
+    3099             :     They are also used by the Plumed::cmd functions to avoid code duplication.
+    3100             :     Available as of PLUMED 2.8.
+    3101             :   */
+    3102             :   template<typename T>
+    3103             :   static void plumed_gcmd_cxx(const char*key,T val, const __PLUMED_WRAPPER_STD size_t* shape,plumed_error* error=__PLUMED_WRAPPER_CXX_NULLPTR) {
+    3104             :     plumed_cmd_cxx(plumed_global(),key,val,shape,error);
+    3105             :   }
+    3106             : 
+    3107             : #endif /*}*/
+    3108             : 
+    3109             : #if __PLUMED_WRAPPER_CXX_BIND_C /*{*/
+    3110             : 
+    3111             : #define __PLUMED_WRAPPER_REDEFINE_CMD ::PLMD::Plumed::plumed_cmd_cxx
+    3112             : 
+    3113             : #if __PLUMED_WRAPPER_GLOBAL /*{*/
+    3114             : #define __PLUMED_WRAPPER_REDEFINE_GCMD ::PLMD::Plumed::plumed_gcmd_cxx
+    3115             : #endif /*}*/
+    3116             : 
+    3117             : #define __PLUMED_WRAPPER_REDEFINE_ERROR_RETHROW ::PLMD::Plumed::plumed_error_rethrow_cxx
+    3118             : 
+    3119             : #endif /*}*/
+    3120             : 
+    3121             : };
+    3122             : 
+    3123             : /**
+    3124             :   \related Plumed
+    3125             :   Comparison operator. Available as of PLUMED 2.5.
+    3126             : */
+    3127             : inline
+    3128             : bool operator==(const Plumed&a,const Plumed&b) __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    3129             :   return a.toVoid()==b.toVoid();
+    3130             : }
+    3131             : 
+    3132             : /**
+    3133             :   \related Plumed
+    3134             :   Comparison operator. Available as of PLUMED 2.5.
+    3135             : */
+    3136             : inline
+    3137             : bool operator!=(const Plumed&a,const Plumed&b) __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    3138             :   return a.toVoid()!=b.toVoid();
+    3139             : }
+    3140             : 
+    3141             : /**
+    3142             :   \related Plumed
+    3143             :   Comparison operator. Available as of PLUMED 2.5.
+    3144             : */
+    3145             : inline
+    3146             : bool operator<=(const Plumed&a,const Plumed&b) __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    3147             :   return a.toVoid()<=b.toVoid();
+    3148             : }
+    3149             : 
+    3150             : /**
+    3151             :   \related Plumed
+    3152             :   Comparison operator. Available as of PLUMED 2.5.
+    3153             : */
+    3154             : inline
+    3155             : bool operator<(const Plumed&a,const Plumed&b) __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    3156             :   return a.toVoid()<b.toVoid();
+    3157             : }
+    3158             : 
+    3159             : /**
+    3160             :   \related Plumed
+    3161             :   Comparison operator. Available as of PLUMED 2.5.
+    3162             : */
+    3163             : inline
+    3164             : bool operator>=(const Plumed&a,const Plumed&b) __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    3165             :   return a.toVoid()>=b.toVoid();
+    3166             : }
+    3167             : 
+    3168             : /**
+    3169             :   \related Plumed
+    3170             :   Comparison operator. Available as of PLUMED 2.5.
+    3171             : */
+    3172             : inline
+    3173             : bool operator>(const Plumed&a,const Plumed&b) __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    3174             :   return a.toVoid()>b.toVoid();
+    3175             : }
+    3176             : 
+    3177             : __PLUMED_WRAPPER_ANONYMOUS_END /*}*/
+    3178             : 
+    3179             : }
+    3180             : 
+    3181             : #endif /*}*/
+    3182             : 
+    3183             : #endif /*}*/
+    3184             : 
+    3185             : /* END OF DECLARATIONS */
+    3186             : 
+    3187             : /*
+    3188             : 
+    3189             :   1: emit implementation
+    3190             :   0: do not emit implementation
+    3191             : 
+    3192             :   Allows an implementation to be emitted together with the declarations.
+    3193             : 
+    3194             :   Used to decide if definitions should be emitted. This macro could have a different
+    3195             :   value when Plumed.h is reincluded. As a consequence, we map it to a local
+    3196             :   macro (__PLUMED_WRAPPER_IMPLEMENTATION_) that is reset at the end of this file.
+    3197             : */
+    3198             : 
+    3199             : #ifdef __PLUMED_WRAPPER_IMPLEMENTATION
+    3200             : #define __PLUMED_WRAPPER_IMPLEMENTATION_ __PLUMED_WRAPPER_IMPLEMENTATION
+    3201             : #else
+    3202             : #define __PLUMED_WRAPPER_IMPLEMENTATION_ 0
+    3203             : #endif
+    3204             : 
+    3205             : /* BEGINNING OF DEFINITIONS */
+    3206             : 
+    3207             : #if __PLUMED_WRAPPER_IMPLEMENTATION_  /*{*/
+    3208             : #ifndef __PLUMED_wrapper_Plumed_implementation /*{*/
+    3209             : #define __PLUMED_wrapper_Plumed_implementation
+    3210             : 
+    3211             : /*
+    3212             :   the following macros only control the implementation
+    3213             : */
+    3214             : 
+    3215             : /*
+    3216             :   1: enable the definition of plumed_symbol_table_reexport
+    3217             :   0: does not enable the definition of plumed_symbol_table_reexport
+    3218             : 
+    3219             :   This is only needed in the official plumed library to make
+    3220             :   the symbol table available. This is a hack to reexport the function table
+    3221             :   and is only needed when creating the library libplumed.so.
+    3222             : */
+    3223             : 
+    3224             : #ifndef __PLUMED_WRAPPER_REEXPORT_SYMBOL_TABLE
+    3225             : #define __PLUMED_WRAPPER_REEXPORT_SYMBOL_TABLE 0
+    3226             : #endif
+    3227             : 
+    3228             : /*
+    3229             :   1: write on stderr changes in reference counters
+    3230             :   0: do not write changes in reference counters
+    3231             : 
+    3232             :   Used for debugging.
+    3233             : 
+    3234             :   Only used in definitions.
+    3235             : */
+    3236             : 
+    3237             : #ifndef __PLUMED_WRAPPER_DEBUG_REFCOUNT
+    3238             : #define __PLUMED_WRAPPER_DEBUG_REFCOUNT 0
+    3239             : #endif
+    3240             : 
+    3241             : /*
+    3242             :   1: emit plumed_kernel_register function (default)
+    3243             :   0: do not emit plumed_kernel_register function
+    3244             : 
+    3245             :   This function is only needed to avoid an extra warning when loading old (<=2.4) kernels.
+    3246             :   We might change its default in the future.
+    3247             : 
+    3248             :   Used only in definitions.
+    3249             : */
+    3250             : 
+    3251             : #ifndef __PLUMED_WRAPPER_KERNEL_REGISTER
+    3252             : #define __PLUMED_WRAPPER_KERNEL_REGISTER 1
+    3253             : #endif
+    3254             : 
+    3255             : /*
+    3256             :   1: emit Fortran wrappers
+    3257             :   0: do not emit Fortran wrappers (default)
+    3258             : 
+    3259             :   Used only in definitions.
+    3260             : */
+    3261             : 
+    3262             : #ifndef __PLUMED_WRAPPER_FORTRAN
+    3263             : #define __PLUMED_WRAPPER_FORTRAN 0
+    3264             : #endif
+    3265             : 
+    3266             : /*
+    3267             :   With internal interface, it does not make sense to emit kernel register or fortran interfaces
+    3268             : */
+    3269             : 
+    3270             : #if ! __PLUMED_WRAPPER_EXTERN /*{*/
+    3271             : #undef __PLUMED_WRAPPER_KERNEL_REGISTER
+    3272             : #define __PLUMED_WRAPPER_KERNEL_REGISTER 0
+    3273             : #undef __PLUMED_WRAPPER_FORTRAN
+    3274             : #define __PLUMED_WRAPPER_FORTRAN 0
+    3275             : #endif /*}*/
+    3276             : 
+    3277             : #ifdef __PLUMED_HAS_DLOPEN
+    3278             : #include <dlfcn.h> /* dlopen dlerror dlsym */
+    3279             : #endif
+    3280             : 
+    3281             : #if __PLUMED_WRAPPER_CXX_STD
+    3282             : #include <cstdio>  /* fprintf */
+    3283             : #include <cstring> /* memcpy strlen strncpy memcmp memmove strcmp memcpy */
+    3284             : #include <cassert> /* assert */
+    3285             : #include <cstdlib> /* getenv malloc free abort */
+    3286             : #include <climits> /* CHAR_BIT */
+    3287             : #else
+    3288             : #include <stdio.h>
+    3289             : #include <string.h>
+    3290             : #include <assert.h>
+    3291             : #include <stdlib.h>
+    3292             : #include <limits.h>
+    3293             : #endif
+    3294             : 
+    3295             : /**
+    3296             :   Function pointer to plumed_create
+    3297             : */
+    3298             : 
+    3299             : typedef void*(*plumed_create_pointer)(void);
+    3300             : /**
+    3301             :   Function pointer to plumed_cmd
+    3302             : */
+    3303             : typedef void(*plumed_cmd_pointer)(void*,const char*,const void*);
+    3304             : 
+    3305             : /**
+    3306             :   Function pointer to plumed_finalize
+    3307             : */
+    3308             : typedef void(*plumed_finalize_pointer)(void*);
+    3309             : 
+    3310             : /**
+    3311             :    Holder for plumedmain function pointers.
+    3312             : */
+    3313             : typedef struct {
+    3314             :   plumed_create_pointer create;
+    3315             :   plumed_cmd_pointer cmd;
+    3316             :   plumed_finalize_pointer finalize;
+    3317             : } plumed_plumedmain_function_holder;
+    3318             : 
+    3319             : /**
+    3320             :   Holder for plumed symbol table.
+    3321             : 
+    3322             :   The table contains pointers to function exported from plumed. Functions can be added increasing the version number.
+    3323             :   Notice that the default way to extend functionalities is by adding cmd strings. This is a last resort, and all new
+    3324             :   functions should be explicitly motivated. Here's the addition:
+    3325             : 
+    3326             :   version=2, cmd_nothrow.
+    3327             : 
+    3328             :   This function accepts an extra argument `plumed_nothrow_handler*handler`.
+    3329             :   In case an exception is thrown within plumed, it just calls `handler->handler(handler->ptr,code,message,opt)` and return.
+    3330             :   An alternative would have been to install an error handler (with a call to cmd("setErrorHandler")). However, the cost
+    3331             :   of doing it everytime Plumed::cmd is called is too high. On the other hand, installing it only at object construction
+    3332             :   is very risky since and object created in that way would not report any error if manipulated from the C interface.
+    3333             :   So, it looks like this is the only possibility.
+    3334             : 
+    3335             :   version=3, cmd_safe and cmd_safe_nothrow
+    3336             : 
+    3337             :   These are functions that accept a plumed_safeptr object, which can carry information about the passed type and size.
+    3338             :   Since new information should be passed at every cmd call, this can only be obtained by adding new cmd calls.
+    3339             : 
+    3340             :   version=4, thread-safe reference counter
+    3341             : 
+    3342             :   These functions allow to access a thread-safe reference counter that is stored within the PlumedMain object.
+    3343             :   This allows avoiding to enable atomic access also the C compiler used build Plumed.c. It's added here and not as a new
+    3344             :   cmd since this is a very low-level functionality.
+    3345             : */
+    3346             : typedef struct {
+    3347             :   /**
+    3348             :     Version number.
+    3349             : 
+    3350             :     Minimum value is 1.
+    3351             :   */
+    3352             :   int version;
+    3353             :   /**
+    3354             :     Pointers to standard plumed functions (create/cmd/finalize).
+    3355             : 
+    3356             :     Always available.
+    3357             :   */
+    3358             :   plumed_plumedmain_function_holder functions;
+    3359             :   /**
+    3360             :     Pointer to a cmd function guaranteed not to throw exceptions.
+    3361             : 
+    3362             :     Available with version>=2.
+    3363             :   */
+    3364             :   void (*cmd_nothrow)(void*plumed,const char*key,const void*val,plumed_nothrow_handler);
+    3365             :   /**
+    3366             :     Pointer to a cmd function that accepts typeinfos.
+    3367             : 
+    3368             :     Available with version>=3.
+    3369             :   */
+    3370             :   void (*cmd_safe)(void*plumed,const char*key,plumed_safeptr);
+    3371             : 
+    3372             :   /**
+    3373             :     Pointer to a cmd function guaranteed not to throw exceptions and that accepts typeinfos.
+    3374             : 
+    3375             :     Available with version>=3.
+    3376             :   */
+    3377             :   void (*cmd_safe_nothrow)(void*plumed,const char*key,plumed_safeptr,plumed_nothrow_handler);
+    3378             : 
+    3379             :   /**
+    3380             :     Pointer to a function that increments the internal reference counter.
+    3381             : 
+    3382             :     Available with version>=4.
+    3383             :   */
+    3384             :   unsigned (*create_reference)(void*);
+    3385             :   /**
+    3386             :     Pointer to a function that decrements the internal reference counter.
+    3387             : 
+    3388             :     Available with version>=4.
+    3389             :   */
+    3390             :   unsigned (*delete_reference)(void*);
+    3391             :   /**
+    3392             :     Pointer to a function that returns the internal reference counter.
+    3393             : 
+    3394             :     Available with version>=4.
+    3395             :   */
+    3396             :   unsigned (*use_count)(void*);
+    3397             : } plumed_symbol_table_type;
+    3398             : 
+    3399             : /* Utility to convert function pointers to pointers, just for the sake of printing them */
+    3400             : #define __PLUMED_CONVERT_FPTR(ptr,fptr) { ptr=__PLUMED_WRAPPER_CXX_NULLPTR; __PLUMED_WRAPPER_STD memcpy(&ptr,&fptr,(sizeof(fptr)>sizeof(ptr)?sizeof(ptr):sizeof(fptr))); }
+    3401             : 
+    3402             : #define __PLUMED_GETENV __PLUMED_WRAPPER_STD getenv
+    3403             : #define __PLUMED_FPRINTF __PLUMED_WRAPPER_STD fprintf
+    3404             : 
+    3405             : /**
+    3406             :   Historically (PLUMED<=2.4) register for plumedmain function pointers.
+    3407             :   As of PLUMED>=2.5, this function does not do anything except for reporting the attempt to register
+    3408             :   something. It always returns NULL. The function should be here anyway to allow an incomplete
+    3409             :   libplumedKernel (<=2.4), expecting this function to be present, to be loaded correctly.
+    3410             : */
+    3411             : #if __PLUMED_WRAPPER_KERNEL_REGISTER
+    3412             : /* Since it is only called from outside, it must be hardcoded to be extern */
+    3413             : __PLUMED_WRAPPER_EXTERN_C_BEGIN /*{*/
+    3414             : extern plumed_plumedmain_function_holder* plumed_kernel_register(const plumed_plumedmain_function_holder*);
+    3415          23 : plumed_plumedmain_function_holder* plumed_kernel_register(const plumed_plumedmain_function_holder* f) {
+    3416             :   void* tmpptr;
+    3417          23 :   if(f) {
+    3418          23 :     if(__PLUMED_GETENV("PLUMED_LOAD_DEBUG")) {
+    3419           0 :       __PLUMED_FPRINTF(stderr,"+++ Ignoring registration at %p (",(const void*)f);
+    3420             :       __PLUMED_CONVERT_FPTR(tmpptr,f->create);
+    3421           0 :       __PLUMED_FPRINTF(stderr,"%p,",tmpptr);
+    3422             :       __PLUMED_CONVERT_FPTR(tmpptr,f->cmd);
+    3423           0 :       __PLUMED_FPRINTF(stderr,"%p,",tmpptr);
+    3424             :       __PLUMED_CONVERT_FPTR(tmpptr,f->finalize);
+    3425           0 :       __PLUMED_FPRINTF(stderr,"%p) +++\n",tmpptr);
+    3426             :     }
+    3427             :   }
+    3428          23 :   return __PLUMED_WRAPPER_CXX_NULLPTR;
+    3429             : }
+    3430             : __PLUMED_WRAPPER_EXTERN_C_END /*}*/
+    3431             : #endif
+    3432             : 
+    3433             : #if defined( __PLUMED_HAS_DLOPEN) /*{*/
+    3434             : /**
+    3435             : Try to dlopen a path with a given mode.
+    3436             : If the dlopen command fails, it tries to strip the `Kernel` part of the name.
+    3437             : 
+    3438             : This function is declared static (internal linkage) so that it is not visible from outside.
+    3439             : It is first declared then defined to make sure it is a regular C static function.
+    3440             : */
+    3441             : 
+    3442             : __PLUMED_WRAPPER_INTERNALS_BEGIN
+    3443           9 : void* plumed_attempt_dlopen(const char*path,int mode) {
+    3444             :   char* pathcopy;
+    3445             :   void* p;
+    3446             :   char* pc;
+    3447             :   __PLUMED_WRAPPER_STD size_t strlenpath;
+    3448             :   pathcopy=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3449             :   p=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3450             :   pc=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3451             :   strlenpath=0;
+    3452           9 :   dlerror();
+    3453           9 :   p=dlopen(path,mode);
+    3454           9 :   if(!p) {
+    3455             :     /*
+    3456             :       Something went wrong. We try to remove "Kernel" string from the PLUMED_KERNEL variable
+    3457             :       and load directly the shared library. Notice that this particular path is only expected
+    3458             :       to be necessary when using PLUMED<=2.4 and the symbols in the main executable are
+    3459             :       not visible. All the other cases (either PLUMED>=2.5 or symbols in the main executable visible)
+    3460             :       should work correctly without entering here.
+    3461             :     */
+    3462           0 :     __PLUMED_FPRINTF(stderr,"+++ An error occurred. Message from dlopen(): %s +++\n",dlerror());
+    3463           0 :     strlenpath=__PLUMED_WRAPPER_STD strlen(path);
+    3464           0 :     pathcopy=(char*) plumed_malloc(strlenpath+1);
+    3465           0 :     if(!pathcopy) {
+    3466           0 :       __PLUMED_FPRINTF(stderr,"+++ Allocation error +++\n");
+    3467           0 :       __PLUMED_WRAPPER_STD abort();
+    3468             :     }
+    3469             :     __PLUMED_WRAPPER_STD strncpy(pathcopy,path,strlenpath+1);
+    3470           0 :     pc=pathcopy+strlenpath-6;
+    3471           0 :     while(pc>=pathcopy && __PLUMED_WRAPPER_STD memcmp(pc,"Kernel",6)) pc--;
+    3472           0 :     if(pc>=pathcopy) {
+    3473           0 :       __PLUMED_WRAPPER_STD memmove(pc, pc+6, __PLUMED_WRAPPER_STD strlen(pc)-5);
+    3474           0 :       __PLUMED_FPRINTF(stderr,"+++ This error is expected if you are trying to load a kernel <=2.4\n");
+    3475           0 :       __PLUMED_FPRINTF(stderr,"+++ Trying %s +++\n",pathcopy);
+    3476           0 :       dlerror();
+    3477           0 :       p=dlopen(pathcopy,mode);
+    3478           0 :       if(!p) __PLUMED_FPRINTF(stderr,"+++ An error occurred. Message from dlopen(): %s +++\n",dlerror());
+    3479             :     }
+    3480           0 :     plumed_free(pathcopy);
+    3481             :   }
+    3482           9 :   return p;
+    3483             : }
+    3484             : __PLUMED_WRAPPER_INTERNALS_END
+    3485             : 
+    3486             : /**
+    3487             :   Utility to search for a function.
+    3488             : */
+    3489             : #define __PLUMED_SEARCH_FUNCTION(tmpptr,handle,func,name,debug) \
+    3490             :   if(!func) { \
+    3491             :     tmpptr=dlsym(handle,name); \
+    3492             :     if(tmpptr) { \
+    3493             :       *(void **)(&func)=tmpptr; \
+    3494             :       if(debug) __PLUMED_FPRINTF(stderr,"+++ %s found at %p +++\n",name,tmpptr); \
+    3495             :     } else { \
+    3496             :       if(debug) __PLUMED_FPRINTF(stderr,"+++ Function %s not found\n",name); \
+    3497             :     } \
+    3498             :   }
+    3499             : 
+    3500             : /**
+    3501             : Search symbols in a dlopened library.
+    3502             : 
+    3503             : This function is declared static (internal linkage) so that it is not visible from outside.
+    3504             : */
+    3505             : __PLUMED_WRAPPER_INTERNALS_BEGIN
+    3506           9 : void plumed_search_symbols(void* handle, plumed_plumedmain_function_holder* f,plumed_symbol_table_type** table) {
+    3507             :   plumed_plumedmain_function_holder functions;
+    3508             :   plumed_symbol_table_type* table_ptr;
+    3509             :   void* tmpptr;
+    3510             :   char* debug;
+    3511             :   functions.create=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3512             :   functions.cmd=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3513             :   functions.finalize=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3514             :   table_ptr=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3515           9 :   tmpptr=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3516             :   /*
+    3517             :     Notice that as of PLUMED 2.5 we ignore self registrations.
+    3518             :     Pointers are searched in the form of a single pointer to a structure, which
+    3519             :     is the standard way in PLUMED 2.5, as well as using alternative names used in
+    3520             :     PLUMED 2.0 to 2.4 (e.g. plumedmain_create) and in some intermediate versions between
+    3521             :     PLUMED 2.4 and 2.5 (e.g. plumed_plumedmain_create). The last chance is probably
+    3522             :     unnecessary and might be removed at some point.
+    3523             :   */
+    3524           9 :   debug=__PLUMED_GETENV("PLUMED_LOAD_DEBUG");
+    3525           9 :   table_ptr=(plumed_symbol_table_type*) dlsym(handle,"plumed_symbol_table");
+    3526           9 :   if(table_ptr) functions=table_ptr->functions;
+    3527           9 :   if(debug) {
+    3528           0 :     if(table_ptr) {
+    3529           0 :       __PLUMED_FPRINTF(stderr,"+++ plumed_symbol_table version %i found at %p +++\n",table_ptr->version,(void*)table_ptr);
+    3530           0 :       __PLUMED_FPRINTF(stderr,"+++ plumed_function_pointers found at %p (",(void*)&table_ptr->functions);
+    3531             :       __PLUMED_CONVERT_FPTR(tmpptr,functions.create);
+    3532           0 :       __PLUMED_FPRINTF(stderr,"%p,",tmpptr);
+    3533             :       __PLUMED_CONVERT_FPTR(tmpptr,functions.cmd);
+    3534           0 :       __PLUMED_FPRINTF(stderr,"%p,",tmpptr);
+    3535             :       __PLUMED_CONVERT_FPTR(tmpptr,functions.finalize);
+    3536           0 :       __PLUMED_FPRINTF(stderr,"%p) +++\n",tmpptr);
+    3537             :     } else {
+    3538           0 :       __PLUMED_FPRINTF(stderr,"+++ plumed_symbol_table (available in PLUMED>=2.5) not found, perhaps kernel is older +++\n");
+    3539             :     }
+    3540             :   }
+    3541             :   /* only searches if they were not found already */
+    3542           9 :   __PLUMED_SEARCH_FUNCTION(tmpptr,handle,functions.create,"plumedmain_create",debug);
+    3543           9 :   __PLUMED_SEARCH_FUNCTION(tmpptr,handle,functions.create,"plumed_plumedmain_create",debug);
+    3544           9 :   __PLUMED_SEARCH_FUNCTION(tmpptr,handle,functions.cmd,"plumedmain_cmd",debug);
+    3545           9 :   __PLUMED_SEARCH_FUNCTION(tmpptr,handle,functions.cmd,"plumed_plumedmain_cmd",debug);
+    3546           9 :   __PLUMED_SEARCH_FUNCTION(tmpptr,handle,functions.finalize,"plumedmain_finalize",debug);
+    3547           9 :   __PLUMED_SEARCH_FUNCTION(tmpptr,handle,functions.finalize,"plumed_plumedmain_finalize",debug);
+    3548           9 :   if(functions.create && functions.cmd && functions.finalize) {
+    3549           9 :     if(debug) __PLUMED_FPRINTF(stderr,"+++ PLUMED was loaded correctly +++\n");
+    3550           9 :     *f=functions;
+    3551           9 :     if(table) *table=table_ptr;
+    3552             :   } else {
+    3553           0 :     if(!functions.create) __PLUMED_FPRINTF(stderr,"+++ Pointer to (plumed_)plumedmain_create not found +++\n");
+    3554           0 :     if(!functions.cmd) __PLUMED_FPRINTF(stderr,"+++ Pointer to (plumed_)plumedmain_cmd not found +++\n");
+    3555           0 :     if(!functions.finalize) __PLUMED_FPRINTF(stderr,"+++ Pointer to (plumed_)plumedmain_finalize not found +++\n");
+    3556           0 :     f->create=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3557           0 :     f->cmd=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3558           0 :     f->finalize=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3559           0 :     if(table) *table=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3560             :   }
+    3561           9 : }
+    3562             : __PLUMED_WRAPPER_INTERNALS_END
+    3563             : 
+    3564             : #endif /*}*/
+    3565             : 
+    3566             : 
+    3567             : #if __PLUMED_WRAPPER_REEXPORT_SYMBOL_TABLE
+    3568             : 
+    3569             : /*
+    3570             :   Here is the case where plumed_symbol_table is
+    3571             :   visible as extern. We first declare it (together with plumed_symbol_table_init) ...
+    3572             : */
+    3573             : 
+    3574             : __PLUMED_WRAPPER_EXTERN_C_BEGIN
+    3575             : extern
+    3576             : plumed_symbol_table_type plumed_symbol_table;
+    3577             : __PLUMED_WRAPPER_EXTERN_C_END
+    3578             : __PLUMED_WRAPPER_EXTERN_C_BEGIN
+    3579             : extern
+    3580             : void plumed_symbol_table_init(void);
+    3581             : __PLUMED_WRAPPER_EXTERN_C_END
+    3582             : 
+    3583             : /*
+    3584             :   ... and then make available a function that returns the address
+    3585             :   of the symbol table.
+    3586             : */
+    3587             : __PLUMED_WRAPPER_C_BEGIN
+    3588      689966 : plumed_symbol_table_type* plumed_symbol_table_reexport() {
+    3589             :   /* make sure the table is initialized */
+    3590      689966 :   plumed_symbol_table_init();
+    3591      700118 :   return &plumed_symbol_table;
+    3592             : }
+    3593             : __PLUMED_WRAPPER_C_END
+    3594             : 
+    3595             : #else
+    3596             : 
+    3597             : /*
+    3598             :   Here is the case where plumed_symbol_table is not
+    3599             :   visible as extern. We thus assume that plumed_symbol_table_reexport is
+    3600             :   available.
+    3601             : */
+    3602             : 
+    3603             : __PLUMED_WRAPPER_EXTERN_C_BEGIN
+    3604             : extern plumed_symbol_table_type* plumed_symbol_table_reexport();
+    3605             : __PLUMED_WRAPPER_EXTERN_C_END
+    3606             : #endif
+    3607             : 
+    3608             : 
+    3609             : /*
+    3610             :   Returns the global pointers, either those available at link time or those
+    3611             :   found in the library loaded at PLUMED_KERNEL env var.
+    3612             :   If plumed_symbol_table_ptr is not NULL, it is used to return a pointer to the symbol table
+    3613             :   (if available).
+    3614             :   Notice that problems can be detected checking if the functions have a NULL ptr.
+    3615             :   On the other hand, the symbol table pointer might be NULL just because the plumed version is <=2.4.
+    3616             :   If handle is not NULL, it is used to return a dlopen handle that could be subsequently dlclosed.
+    3617             : */
+    3618             : __PLUMED_WRAPPER_INTERNALS_BEGIN
+    3619      689223 : void plumed_retrieve_functions(plumed_plumedmain_function_holder* functions, plumed_symbol_table_type** plumed_symbol_table_ptr,void** handle) {
+    3620             : #if ! __PLUMED_WRAPPER_LINK_RUNTIME
+    3621             :   /*
+    3622             :     Real interface, constructed using the symbol table obtained with plumed_symbol_table_reexport.
+    3623             :     This makes the symbols hardcoded and independent of a mis-set PLUMED_KERNEL variable.
+    3624             :   */
+    3625      689223 :   plumed_symbol_table_type* ptr=plumed_symbol_table_reexport();
+    3626      704919 :   if(plumed_symbol_table_ptr) *plumed_symbol_table_ptr=ptr;
+    3627      704919 :   if(handle) *handle=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3628      704919 :   if(functions) *functions=ptr->functions;
+    3629             : #elif ! defined(__PLUMED_HAS_DLOPEN)
+    3630             :   /*
+    3631             :     When dlopen is not available, we hard code them to NULL
+    3632             :   */
+    3633             :   __PLUMED_FPRINTF(stderr,"+++ PLUMED has been compiled without dlopen and without a static kernel +++\n");
+    3634             :   plumed_plumedmain_function_holder g= {__PLUMED_WRAPPER_CXX_NULLPTR,__PLUMED_WRAPPER_CXX_NULLPTR,__PLUMED_WRAPPER_CXX_NULLPTR};
+    3635             :   if(plumed_symbol_table_ptr) *plumed_symbol_table_ptr=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3636             :   if(handle) *handle=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3637             :   if(functions) *functions=g;
+    3638             : #else
+    3639             :   /*
+    3640             :     On the other hand, for runtime binding, we use dlsym to find the relevant functions.
+    3641             :   */
+    3642             :   plumed_plumedmain_function_holder g;
+    3643             :   /* search is done once and only once */
+    3644             :   const char* path;
+    3645             :   void* p;
+    3646             :   char* debug;
+    3647             :   int dlopenmode;
+    3648             :   g.create=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3649             :   g.cmd=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3650             :   g.finalize=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3651             :   path=__PLUMED_GETENV("PLUMED_KERNEL");
+    3652             :   p=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3653             :   debug=__PLUMED_GETENV("PLUMED_LOAD_DEBUG");
+    3654             :   dlopenmode=0;
+    3655             :   if(plumed_symbol_table_ptr) *plumed_symbol_table_ptr=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3656             :   if(handle) *handle=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3657             : #ifdef __PLUMED_DEFAULT_KERNEL
+    3658             :   /*
+    3659             :     This variable allows a default path for the kernel to be hardcoded.
+    3660             :     Can be useful for hardcoding the predefined plumed location
+    3661             :     still allowing the user to override this choice setting PLUMED_KERNEL.
+    3662             :     The path should be chosen at compile time adding e.g.
+    3663             :     -D__PLUMED_DEFAULT_KERNEL=/opt/local/lib/libplumed.dylib
+    3664             :   */
+    3665             :   /* This is required to add quotes */
+    3666             : #define PLUMED_QUOTE_DIRECT(name) #name
+    3667             : #define PLUMED_QUOTE(macro) PLUMED_QUOTE_DIRECT(macro)
+    3668             :   if(! (path && (*path) )) path=PLUMED_QUOTE(__PLUMED_DEFAULT_KERNEL);
+    3669             : #endif
+    3670             : #if defined(__PLUMED_PROGRAM_NAME) && defined(__PLUMED_SOEXT)
+    3671             :   if(! (path && (*path) )) path="lib" __PLUMED_PROGRAM_NAME "Kernel." __PLUMED_SOEXT;
+    3672             : #endif
+    3673             :   if(path && (*path)) {
+    3674             :     __PLUMED_FPRINTF(stderr,"+++ Loading the PLUMED kernel runtime +++\n");
+    3675             :     __PLUMED_FPRINTF(stderr,"+++ PLUMED_KERNEL=\"%s\" +++\n",path);
+    3676             :     if(debug) __PLUMED_FPRINTF(stderr,"+++ Loading with mode RTLD_NOW");
+    3677             :     dlopenmode=RTLD_NOW;
+    3678             :     if(__PLUMED_GETENV("PLUMED_LOAD_NAMESPACE") && !__PLUMED_WRAPPER_STD strcmp(__PLUMED_GETENV("PLUMED_LOAD_NAMESPACE"),"GLOBAL")) {
+    3679             :       dlopenmode=dlopenmode|RTLD_GLOBAL;
+    3680             :       if(debug) __PLUMED_FPRINTF(stderr,"|RTLD_GLOBAL");
+    3681             :     } else {
+    3682             :       dlopenmode=dlopenmode|RTLD_LOCAL;
+    3683             :       if(debug) __PLUMED_FPRINTF(stderr,"|RTLD_LOCAL");
+    3684             :     }
+    3685             : #ifdef RTLD_DEEPBIND
+    3686             : #if __PLUMED_WRAPPER_ENABLE_RTLD_DEEPBIND
+    3687             :     if(!__PLUMED_GETENV("PLUMED_LOAD_NODEEPBIND")) {
+    3688             :       dlopenmode=dlopenmode|RTLD_DEEPBIND;
+    3689             :       if(debug) __PLUMED_FPRINTF(stderr,"|RTLD_DEEPBIND");
+    3690             :     }
+    3691             : #endif
+    3692             : #endif
+    3693             :     if(debug) __PLUMED_FPRINTF(stderr," +++\n");
+    3694             :     p=plumed_attempt_dlopen(path,dlopenmode);
+    3695             :     if(p) plumed_search_symbols(p,&g,plumed_symbol_table_ptr);
+    3696             :   }
+    3697             :   if(handle) *handle=p;
+    3698             :   if(functions) *functions=g;
+    3699             : #endif
+    3700      704919 : }
+    3701             : __PLUMED_WRAPPER_INTERNALS_END
+    3702             : 
+    3703             : /**
+    3704             :   Implementation.
+    3705             :   Small object used to store pointers directly into the plumed object defined in Plumed.h.
+    3706             :   This allows avoiding the extra function call to plumed_retrieve_functions at every cmd,
+    3707             :   at the cost of an extra indirection.
+    3708             : */
+    3709             : typedef struct {
+    3710             :   /* allows errors with pointers to be found when debugging */
+    3711             :   char magic[6];
+    3712             :   /* reference count. this is only used with PLUMED<=2.8. Later versions have an internal thread-safe reference counter. */
+    3713             :   int refcount;
+    3714             :   /* handler to dlopened library. NULL if there was no library opened */
+    3715             :   void* dlhandle;
+    3716             :   /* non zero if, upon destruction, the library should be dlclosed */
+    3717             :   int dlclose;
+    3718             :   /* 1 if path to kernel was taken from PLUMED_KERNEL var, 0 otherwise */
+    3719             :   int used_plumed_kernel;
+    3720             :   /* function pointers */
+    3721             :   plumed_plumedmain_function_holder functions;
+    3722             :   /* pointer to the symbol table. NULL if kernel <=2.4 */
+    3723             :   plumed_symbol_table_type* table;
+    3724             :   /* pointer to plumed object */
+    3725             :   void* p;
+    3726             : } plumed_implementation;
+    3727             : 
+    3728             : __PLUMED_WRAPPER_INTERNALS_BEGIN
+    3729      710021 : plumed_implementation* plumed_malloc_pimpl() {
+    3730             :   plumed_implementation* pimpl;
+    3731             :   /* allocate space for implementation object. this is free-ed in plumed_finalize(). */
+    3732      710020 :   pimpl=(plumed_implementation*) plumed_malloc(sizeof(plumed_implementation));
+    3733      729060 :   if(!pimpl) {
+    3734           0 :     __PLUMED_FPRINTF(stderr,"+++ Allocation error +++\n");
+    3735           0 :     __PLUMED_WRAPPER_STD abort();
+    3736             :   }
+    3737             :   /* cppcheck-suppress nullPointerRedundantCheck */
+    3738      729060 :   __PLUMED_WRAPPER_STD memcpy(pimpl->magic,"pLuMEd",6);
+    3739             :   /* cppcheck-suppress nullPointerRedundantCheck */
+    3740      729060 :   pimpl->refcount=1;
+    3741             : #if __PLUMED_WRAPPER_DEBUG_REFCOUNT
+    3742             :   /* cppcheck-suppress nullPointerRedundantCheck */
+    3743             :   __PLUMED_FPRINTF(stderr,"refcount: new at %p\n",(void*)pimpl);
+    3744             : #endif
+    3745             :   /* cppcheck-suppress nullPointerRedundantCheck */
+    3746      729060 :   pimpl->dlhandle=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3747             :   /* cppcheck-suppress nullPointerRedundantCheck */
+    3748      729060 :   pimpl->dlclose=0;
+    3749             :   /* cppcheck-suppress nullPointerRedundantCheck */
+    3750      729060 :   pimpl->used_plumed_kernel=0;
+    3751             :   /* cppcheck-suppress nullPointerRedundantCheck */
+    3752      729060 :   pimpl->functions.create=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3753             :   /* cppcheck-suppress nullPointerRedundantCheck */
+    3754      729060 :   pimpl->functions.cmd=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3755             :   /* cppcheck-suppress nullPointerRedundantCheck */
+    3756      729060 :   pimpl->functions.finalize=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3757             :   /* cppcheck-suppress nullPointerRedundantCheck */
+    3758      729060 :   pimpl->table=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3759             :   /* cppcheck-suppress nullPointerRedundantCheck */
+    3760      729060 :   pimpl->p=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3761      729060 :   return pimpl;
+    3762             : }
+    3763             : __PLUMED_WRAPPER_INTERNALS_END
+    3764             : 
+    3765             : #ifndef NDEBUG
+    3766             : 
+    3767             : __PLUMED_WRAPPER_INTERNALS_BEGIN
+    3768             : int plumed_check_pimpl(plumed_implementation*pimpl) {
+    3769             :   if(!pimpl) return 0;
+    3770             :   if(__PLUMED_WRAPPER_STD memcmp(pimpl->magic,"pLuMEd",6)) return 0;
+    3771             :   return 1;
+    3772             : }
+    3773             : __PLUMED_WRAPPER_INTERNALS_END
+    3774             : #endif
+    3775             : 
+    3776             : /* C wrappers: */
+    3777             : 
+    3778             : __PLUMED_WRAPPER_C_BEGIN
+    3779      739158 : plumed plumed_create(void) {
+    3780             :   /* returned object */
+    3781             :   plumed p;
+    3782             :   /* pointer to implementation */
+    3783             :   plumed_implementation* pimpl;
+    3784             :   /* allocate space for implementation object. this is free-ed in plumed_finalize(). */
+    3785      739158 :   pimpl=plumed_malloc_pimpl();
+    3786             :   /* store pointers in pimpl */
+    3787      718815 :   plumed_retrieve_functions(&pimpl->functions,&pimpl->table,&pimpl->dlhandle);
+    3788             : #if __PLUMED_WRAPPER_LINK_RUNTIME
+    3789             :   /* note if PLUMED_KERNEL variable was used */
+    3790             :   pimpl->used_plumed_kernel=1;
+    3791             : #endif
+    3792             :   /* note if handle should not be dlclosed */
+    3793      744899 :   pimpl->dlclose=1;
+    3794      744899 :   if(__PLUMED_GETENV("PLUMED_LOAD_DLCLOSE") && !__PLUMED_WRAPPER_STD strcmp(__PLUMED_GETENV("PLUMED_LOAD_DLCLOSE"),"no")) pimpl->dlclose=0;
+    3795             :   /* in case of failure, return */
+    3796             :   /* the resulting object should be plumed_finalized, though you cannot use plumed_cmd */
+    3797      784093 :   if(!pimpl->functions.create) {
+    3798             :     /* store pimpl in returned object */
+    3799             :     p.p=pimpl;
+    3800           0 :     return p;
+    3801             :   }
+    3802             :   assert(pimpl->functions.cmd);
+    3803             :   assert(pimpl->functions.finalize);
+    3804             :   /* obtain object */
+    3805      784093 :   pimpl->p=(*(pimpl->functions.create))();
+    3806             :   /* notice: we do not assert pimpl->p since in principle it might be nullptr */
+    3807             :   /* user might identify this using plumed_valid() */
+    3808             :   /* store pimpl in returned object */
+    3809             :   p.p=pimpl;
+    3810      786687 :   return p;
+    3811             : }
+    3812             : __PLUMED_WRAPPER_C_END
+    3813             : 
+    3814             : __PLUMED_WRAPPER_C_BEGIN
+    3815           9 : plumed plumed_create_dlopen(const char*path) {
+    3816             :   int dlopenmode;
+    3817             :   /* plumed_create_dlopen always uses RTLD_LOCAL and, when possible, RTLD_DEEPBIND to allow multiple versions */
+    3818             : #ifdef __PLUMED_HAS_DLOPEN
+    3819             :   dlopenmode=RTLD_NOW|RTLD_LOCAL;
+    3820             : #ifdef RTLD_DEEPBIND
+    3821             : #if __PLUMED_WRAPPER_ENABLE_RTLD_DEEPBIND
+    3822           9 :   if(!__PLUMED_GETENV("PLUMED_LOAD_NODEEPBIND")) dlopenmode=dlopenmode|RTLD_DEEPBIND;
+    3823             : #endif
+    3824             : #endif
+    3825             : #else
+    3826             :   dlopenmode=0;
+    3827             : #endif
+    3828           9 :   return plumed_create_dlopen2(path,dlopenmode);
+    3829             : }
+    3830             : __PLUMED_WRAPPER_C_END
+    3831             : 
+    3832             : __PLUMED_WRAPPER_C_BEGIN
+    3833           9 : plumed plumed_create_dlsym(void* dlhandle) {
+    3834             :   /* returned object */
+    3835             :   plumed p;
+    3836             :   /* pointer to implementation */
+    3837             :   plumed_implementation* pimpl;
+    3838             :   /* allocate space for implementation object. this is free-ed in plumed_finalize(). */
+    3839           9 :   pimpl=plumed_malloc_pimpl();
+    3840             : #ifdef __PLUMED_HAS_DLOPEN
+    3841           9 :   pimpl->dlhandle=dlhandle;
+    3842           9 :   plumed_search_symbols(pimpl->dlhandle,&pimpl->functions,&pimpl->table);
+    3843             : #endif
+    3844           9 :   if(!pimpl->functions.create) {
+    3845             :     p.p=pimpl;
+    3846           0 :     return p;
+    3847             :   }
+    3848             :   assert(pimpl->functions.cmd);
+    3849             :   assert(pimpl->functions.finalize);
+    3850             :   /* obtain object */
+    3851           9 :   pimpl->p=(*(pimpl->functions.create))();
+    3852             :   /* notice: we do not assert pimpl->p since in principle it might be nullptr */
+    3853             :   /* user might identify this using plumed_valid() */
+    3854             :   /* store pimpl in returned object */
+    3855             :   p.p=pimpl;
+    3856           9 :   return p;
+    3857             : }
+    3858             : __PLUMED_WRAPPER_C_END
+    3859             : 
+    3860             : __PLUMED_WRAPPER_C_BEGIN
+    3861           9 : plumed plumed_create_dlopen2(const char*path,int mode) {
+    3862             : #ifdef __PLUMED_HAS_DLOPEN
+    3863             :   /* returned object */
+    3864             :   plumed p;
+    3865             :   /* pointer to implementation */
+    3866             :   plumed_implementation* pimpl;
+    3867             :   /* handler */
+    3868             :   void* dlhandle;
+    3869             :   dlhandle=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3870           9 :   if(path) dlhandle=plumed_attempt_dlopen(path,mode);
+    3871             :   /* a NULL handle implies the file could not be loaded */
+    3872           9 :   if(dlhandle) {
+    3873           9 :     p=plumed_create_dlsym(dlhandle);
+    3874             :     /* obtain pimpl */
+    3875           9 :     pimpl=(plumed_implementation*) p.p;
+    3876             :     /* make sure the handler is closed when plumed is finalized */
+    3877           9 :     pimpl->dlclose=1;
+    3878           9 :     return p;
+    3879             :   }
+    3880             : #else
+    3881             :   (void) path;
+    3882             :   (void) mode;
+    3883             : #endif
+    3884           0 :   return plumed_create_invalid();
+    3885             : }
+    3886             : __PLUMED_WRAPPER_C_END
+    3887             : 
+    3888             : __PLUMED_WRAPPER_C_BEGIN
+    3889     7643371 : plumed plumed_create_reference(plumed p) {
+    3890             :   plumed_implementation* pimpl;
+    3891             :   /* obtain pimpl */
+    3892     7643371 :   pimpl=(plumed_implementation*) p.p;
+    3893             :   assert(plumed_check_pimpl(pimpl));
+    3894             :   /* increase reference count */
+    3895             :   /* with PLUMED > 2.8, we can use an internal reference counter which is thread safe */
+    3896     7643371 :   if(pimpl->p && pimpl->table && pimpl->table->version>3) {
+    3897     7615218 :     pimpl->table->create_reference(pimpl->p);
+    3898             :   } else {
+    3899       28153 :     pimpl->refcount++;
+    3900             :   }
+    3901             : #if __PLUMED_WRAPPER_DEBUG_REFCOUNT
+    3902             :   __PLUMED_FPRINTF(stderr,"refcount: increase at %p\n",(void*)pimpl);
+    3903             : #endif
+    3904     7572085 :   return p;
+    3905             : }
+    3906             : __PLUMED_WRAPPER_C_END
+    3907             : 
+    3908             : __PLUMED_WRAPPER_C_BEGIN
+    3909           2 : plumed plumed_create_reference_v(void*v) {
+    3910           2 :   return plumed_create_reference(plumed_v2c(v));
+    3911             : }
+    3912             : __PLUMED_WRAPPER_C_END
+    3913             : 
+    3914             : __PLUMED_WRAPPER_C_BEGIN
+    3915           8 : plumed plumed_create_reference_f(const char*f) {
+    3916           8 :   return plumed_create_reference(plumed_f2c(f));
+    3917             : }
+    3918             : __PLUMED_WRAPPER_C_END
+    3919             : 
+    3920             : __PLUMED_WRAPPER_C_BEGIN
+    3921           2 : plumed plumed_create_invalid() {
+    3922             :   plumed p;
+    3923             :   plumed_implementation* pimpl;
+    3924           2 :   pimpl=plumed_malloc_pimpl();
+    3925             :   p.p=pimpl;
+    3926           2 :   return p;
+    3927             : }
+    3928             : __PLUMED_WRAPPER_C_END
+    3929             : 
+    3930             : __PLUMED_WRAPPER_C_BEGIN
+    3931         357 : void plumed_cmd(plumed p,const char*key,const void*val) {
+    3932             :   plumed_implementation* pimpl;
+    3933             :   /* obtain pimpl */
+    3934         357 :   pimpl=(plumed_implementation*) p.p;
+    3935             :   assert(plumed_check_pimpl(pimpl));
+    3936         357 :   if(!pimpl->p) {
+    3937           0 :     __PLUMED_FPRINTF(stderr,"+++ ERROR: You are trying to use an invalid plumed object. +++\n");
+    3938           0 :     if(pimpl->used_plumed_kernel) __PLUMED_FPRINTF(stderr,"+++ Check your PLUMED_KERNEL environment variable. +++\n");
+    3939           0 :     __PLUMED_WRAPPER_STD abort();
+    3940             :   }
+    3941             :   assert(pimpl->functions.create);
+    3942             :   assert(pimpl->functions.cmd);
+    3943             :   assert(pimpl->functions.finalize);
+    3944             :   /* execute */
+    3945         357 :   (*(pimpl->functions.cmd))(pimpl->p,key,val);
+    3946         357 : }
+    3947             : __PLUMED_WRAPPER_C_END
+    3948             : 
+    3949             : __PLUMED_WRAPPER_C_BEGIN
+    3950       17620 : void plumed_cmd_safe_nothrow(plumed p,const char*key,plumed_safeptr safe,plumed_nothrow_handler nothrow) {
+    3951             :   plumed_implementation* pimpl;
+    3952             :   /* This is to allow caller to use a null handler to imply that handling is not done */
+    3953       17620 :   if(!nothrow.handler) {
+    3954          37 :     plumed_cmd_safe(p,key,safe);
+    3955          37 :     return;
+    3956             :   }
+    3957             :   /* obtain pimpl */
+    3958       17583 :   pimpl=(plumed_implementation*) p.p;
+    3959             :   assert(plumed_check_pimpl(pimpl));
+    3960       17583 :   if(!pimpl->p) {
+    3961           0 :     if(pimpl->used_plumed_kernel) {
+    3962           0 :       nothrow.handler(nothrow.ptr,1,"You are trying to use plumed, but it is not available.\nCheck your PLUMED_KERNEL environment variable.",__PLUMED_WRAPPER_CXX_NULLPTR);
+    3963             :     } else {
+    3964           0 :       nothrow.handler(nothrow.ptr,1,"You are trying to use plumed, but it is not available.",__PLUMED_WRAPPER_CXX_NULLPTR);
+    3965             :     }
+    3966           0 :     return;
+    3967             :   }
+    3968             :   assert(pimpl->functions.create);
+    3969             :   assert(pimpl->functions.cmd);
+    3970             :   assert(pimpl->functions.finalize);
+    3971             :   /* execute */
+    3972       17583 :   if(pimpl->table && pimpl->table->version>2) (*(pimpl->table->cmd_safe_nothrow))(pimpl->p,key,safe,nothrow);
+    3973           0 :   else if(pimpl->table && pimpl->table->version>1) (*(pimpl->table->cmd_nothrow))(pimpl->p,key,safe.ptr,nothrow);
+    3974           0 :   else (*(pimpl->functions.cmd))(pimpl->p,key,safe.ptr);
+    3975             : }
+    3976             : __PLUMED_WRAPPER_C_END
+    3977             : 
+    3978             : __PLUMED_WRAPPER_C_BEGIN
+    3979           0 : void plumed_cmd_nothrow(plumed p,const char*key,const void*val,plumed_nothrow_handler nothrow) {
+    3980             :   plumed_safeptr safe;
+    3981           0 :   safe.ptr=val;
+    3982           0 :   safe.flags=0;
+    3983           0 :   safe.nelem=0;
+    3984           0 :   safe.shape=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3985           0 :   safe.opt=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3986           0 :   plumed_cmd_safe_nothrow(p,key,safe,nothrow);
+    3987           0 : }
+    3988             : __PLUMED_WRAPPER_C_END
+    3989             : 
+    3990             : __PLUMED_WRAPPER_C_BEGIN
+    3991          95 : void plumed_cmd_safe(plumed p,const char*key,plumed_safeptr safe) {
+    3992             :   plumed_implementation* pimpl;
+    3993             :   /* obtain pimpl */
+    3994          95 :   pimpl=(plumed_implementation*) p.p;
+    3995             :   assert(plumed_check_pimpl(pimpl));
+    3996          95 :   if(!pimpl->p) {
+    3997           0 :     __PLUMED_FPRINTF(stderr,"+++ ERROR: You are trying to use an invalid plumed object. +++\n");
+    3998           0 :     if(pimpl->used_plumed_kernel) __PLUMED_FPRINTF(stderr,"+++ Check your PLUMED_KERNEL environment variable. +++\n");
+    3999           0 :     __PLUMED_WRAPPER_STD abort();
+    4000             :   }
+    4001             :   assert(pimpl->functions.create);
+    4002             :   assert(pimpl->functions.cmd);
+    4003             :   assert(pimpl->functions.finalize);
+    4004             :   /* execute */
+    4005          95 :   if(pimpl->table && pimpl->table->version>2) (*(pimpl->table->cmd_safe))(pimpl->p,key,safe);
+    4006           0 :   else (*(pimpl->functions.cmd))(pimpl->p,key,safe.ptr);
+    4007          95 : }
+    4008             : __PLUMED_WRAPPER_C_END
+    4009             : 
+    4010             : 
+    4011             : __PLUMED_WRAPPER_C_BEGIN
+    4012     8581866 : void plumed_finalize(plumed p) {
+    4013             :   plumed_implementation* pimpl;
+    4014             :   /* obtain pimpl */
+    4015     8581866 :   pimpl=(plumed_implementation*) p.p;
+    4016             :   assert(plumed_check_pimpl(pimpl));
+    4017             : #if __PLUMED_WRAPPER_DEBUG_REFCOUNT
+    4018             :   __PLUMED_FPRINTF(stderr,"refcount: decrease at %p\n",(void*)pimpl);
+    4019             : #endif
+    4020             :   /* with PLUMED > 2.8, we can use an internal reference counter which is thread safe */
+    4021     8581866 :   if(pimpl->p && pimpl->table && pimpl->table->version>3) {
+    4022     8515218 :     if(pimpl->table->delete_reference(pimpl->p)>0) return;
+    4023             :   } else {
+    4024       66648 :     if(--pimpl->refcount>0) return;
+    4025             :   }
+    4026             :   /* to allow finalizing an invalid plumed object, we only call
+    4027             :      finalize if the object is valid */
+    4028      778396 :   if(pimpl->p) {
+    4029             :     assert(pimpl->functions.create);
+    4030             :     assert(pimpl->functions.cmd);
+    4031             :     assert(pimpl->functions.finalize);
+    4032             :     /* finalize */
+    4033      778394 :     (*(pimpl->functions.finalize))(pimpl->p);
+    4034             :   }
+    4035             : #ifdef __PLUMED_HAS_DLOPEN
+    4036             :   /* dlclose library */
+    4037      749105 :   if(pimpl->dlhandle && pimpl->dlclose) {
+    4038           9 :     if(__PLUMED_GETENV("PLUMED_LOAD_DEBUG")) __PLUMED_FPRINTF(stderr,"+++ Unloading library\n");
+    4039           9 :     dlclose(pimpl->dlhandle);
+    4040             :   }
+    4041             : #endif
+    4042             : #if __PLUMED_WRAPPER_DEBUG_REFCOUNT
+    4043             :   __PLUMED_FPRINTF(stderr,"refcount: delete at %p\n",(void*)pimpl);
+    4044             : #endif
+    4045             :   /* free pimpl space */
+    4046      749104 :   plumed_free(pimpl);
+    4047             : }
+    4048             : __PLUMED_WRAPPER_C_END
+    4049             : 
+    4050             : __PLUMED_WRAPPER_C_BEGIN
+    4051          23 : int plumed_valid(plumed p) {
+    4052             :   plumed_implementation* pimpl;
+    4053             :   /* obtain pimpl */
+    4054          23 :   pimpl=(plumed_implementation*) p.p;
+    4055             :   assert(plumed_check_pimpl(pimpl));
+    4056          24 :   if(pimpl->p) return 1;
+    4057           2 :   else return 0;
+    4058             : }
+    4059             : __PLUMED_WRAPPER_C_END
+    4060             : 
+    4061             : __PLUMED_WRAPPER_C_BEGIN
+    4062          42 : int plumed_use_count(plumed p) {
+    4063             :   plumed_implementation* pimpl;
+    4064             :   /* obtain pimpl */
+    4065          42 :   pimpl=(plumed_implementation*) p.p;
+    4066             :   assert(plumed_check_pimpl(pimpl));
+    4067             :   /* with PLUMED > 2.8, we can use an internal reference counter which is thread safe */
+    4068          42 :   if(pimpl->p && pimpl->table && pimpl->table->version>3) {
+    4069          42 :     return pimpl->table->use_count(pimpl->p);
+    4070             :   } else {
+    4071           0 :     return pimpl->refcount;
+    4072             :   }
+    4073             : }
+    4074             : __PLUMED_WRAPPER_C_END
+    4075             : 
+    4076             : __PLUMED_WRAPPER_C_BEGIN
+    4077           9 : int plumed_installed(void) {
+    4078             :   plumed p;
+    4079             :   int result;
+    4080           9 :   p=plumed_create();
+    4081           9 :   result=plumed_valid(p);
+    4082           9 :   plumed_finalize(p);
+    4083           9 :   return result;
+    4084             : }
+    4085             : __PLUMED_WRAPPER_C_END
+    4086             : 
+    4087             : __PLUMED_WRAPPER_C_BEGIN
+    4088      723787 : void* plumed_malloc(__PLUMED_WRAPPER_STD size_t size) {
+    4089             :   void* ptr;
+    4090      723788 :   ptr=__PLUMED_WRAPPER_STD malloc(size);
+    4091             : #if __PLUMED_WRAPPER_DEBUG_REFCOUNT
+    4092             :   if(ptr) fprintf(stderr,"plumed_malloc: %p\n",ptr);
+    4093             : #endif
+    4094      723787 :   return ptr;
+    4095             : }
+    4096             : __PLUMED_WRAPPER_C_END
+    4097             : 
+    4098             : __PLUMED_WRAPPER_C_BEGIN
+    4099      732865 : void plumed_free(void* ptr) {
+    4100      732866 :   __PLUMED_WRAPPER_STD free(ptr);
+    4101             : #if __PLUMED_WRAPPER_DEBUG_REFCOUNT
+    4102             :   fprintf(stderr,"plumed_free: %p\n",ptr);
+    4103             : #endif
+    4104      732866 : }
+    4105             : __PLUMED_WRAPPER_C_END
+    4106             : 
+    4107             : #if __PLUMED_WRAPPER_GLOBAL /*{*/
+    4108             : 
+    4109             : __PLUMED_WRAPPER_EXTERN_C_BEGIN
+    4110             : 
+    4111             : /* we declare a Plumed_g_main object here, in such a way that it is always available */
+    4112             : 
+    4113             : static plumed plumed_gmain= {__PLUMED_WRAPPER_CXX_NULLPTR};
+    4114             : 
+    4115          41 : plumed plumed_global(void) {
+    4116          41 :   return plumed_gmain;
+    4117             : }
+    4118             : 
+    4119          22 : void plumed_gcreate(void) {
+    4120             :   /* should be created once */
+    4121             :   assert(plumed_gmain.p==__PLUMED_WRAPPER_CXX_NULLPTR);
+    4122          22 :   plumed_gmain=plumed_create();
+    4123          22 : }
+    4124             : 
+    4125          78 : void plumed_gcmd(const char*key,const void*val) {
+    4126          78 :   plumed_cmd(plumed_gmain,key,val);
+    4127          78 : }
+    4128             : 
+    4129             : /* cppcheck-suppress passedByValue */
+    4130           0 : void plumed_gcmd_safe(const char*key,plumed_safeptr safe) {
+    4131           0 :   plumed_cmd_safe(plumed_gmain,key,safe);
+    4132           0 : }
+    4133             : 
+    4134          22 : void plumed_gfinalize(void) {
+    4135          22 :   plumed_finalize(plumed_gmain);
+    4136          22 :   plumed_gmain.p=__PLUMED_WRAPPER_CXX_NULLPTR;
+    4137          22 : }
+    4138             : 
+    4139          24 : int plumed_ginitialized(void) {
+    4140          24 :   if(plumed_gmain.p) return 1;
+    4141          16 :   else        return 0;
+    4142             : }
+    4143             : 
+    4144           8 : int plumed_gvalid() {
+    4145             :   assert(plumed_gmain.p);
+    4146           8 :   return plumed_valid(plumed_gmain);
+    4147             : }
+    4148             : 
+    4149             : __PLUMED_WRAPPER_EXTERN_C_END
+    4150             : 
+    4151             : #endif /*}*/
+    4152             : 
+    4153             : __PLUMED_WRAPPER_C_BEGIN
+    4154          56 : void plumed_c2f(plumed p,char*c) {
+    4155             :   unsigned i;
+    4156             :   unsigned char* cc;
+    4157             :   /*
+    4158             :     Convert the address stored in p.p into a proper FORTRAN string
+    4159             :     made of only ASCII characters. For this to work, the two following
+    4160             :     assertions should be satisfied:
+    4161             :   */
+    4162             :   assert(CHAR_BIT<=12);
+    4163             :   assert(sizeof(p.p)<=16);
+    4164             : 
+    4165             :   assert(c);
+    4166             :   cc=(unsigned char*)&p.p;
+    4167         504 :   for(i=0; i<sizeof(p.p); i++) {
+    4168             :     /*
+    4169             :       characters will range between '0' (ASCII 48) and 'o' (ASCII 111=48+63)
+    4170             :     */
+    4171         448 :     c[2*i]=cc[i]/64+48;
+    4172         448 :     c[2*i+1]=cc[i]%64+48;
+    4173             :   }
+    4174         504 :   for(; i<16; i++) {
+    4175         448 :     c[2*i]=' ';
+    4176         448 :     c[2*i+1]=' ';
+    4177             :   }
+    4178          56 : }
+    4179             : __PLUMED_WRAPPER_C_END
+    4180             : 
+    4181             : __PLUMED_WRAPPER_C_BEGIN
+    4182         373 : plumed plumed_f2c(const char*c) {
+    4183             :   plumed p;
+    4184             :   unsigned i;
+    4185             :   unsigned char* cc;
+    4186             : 
+    4187             :   assert(CHAR_BIT<=12);
+    4188             :   assert(sizeof(p.p)<=16);
+    4189             : 
+    4190             :   assert(c);
+    4191             : 
+    4192             :   /*
+    4193             :      needed to avoid cppcheck warning on uninitialized p
+    4194             :   */
+    4195         373 :   p.p=__PLUMED_WRAPPER_CXX_NULLPTR;
+    4196             :   cc=(unsigned char*)&p.p;
+    4197        3357 :   for(i=0; i<sizeof(p.p); i++) {
+    4198             :     assert(c[2*i]>=48 && c[2*i]<48+64);
+    4199             :     assert(c[2*i+1]>=48 && c[2*i+1]<48+64);
+    4200             :     /*
+    4201             :       perform the reversed transform
+    4202             :     */
+    4203        2984 :     cc[i]=(c[2*i]-48)*64 + (c[2*i+1]-48);
+    4204             :   }
+    4205        3357 :   for(; i<16; i++) {
+    4206             :     assert(c[2*i]==' ');
+    4207             :     assert(c[2*i+1]==' ');
+    4208             :   }
+    4209         373 :   return p;
+    4210             : }
+    4211             : __PLUMED_WRAPPER_C_END
+    4212             : 
+    4213             : __PLUMED_WRAPPER_C_BEGIN
+    4214           2 : void* plumed_c2v(plumed p) {
+    4215             :   assert(plumed_check_pimpl((plumed_implementation*)p.p));
+    4216           2 :   return p.p;
+    4217             : }
+    4218             : __PLUMED_WRAPPER_C_END
+    4219             : 
+    4220             : __PLUMED_WRAPPER_C_BEGIN
+    4221           2 : plumed plumed_v2c(void* v) {
+    4222             :   assert(plumed_check_pimpl((plumed_implementation*)v));
+    4223             :   plumed p;
+    4224             :   p.p=v;
+    4225           2 :   return p;
+    4226             : }
+    4227             : __PLUMED_WRAPPER_C_END
+    4228             : 
+    4229             : #if __PLUMED_WRAPPER_FORTRAN /*{*/
+    4230             : 
+    4231             : /*
+    4232             :   Fortran wrappers
+    4233             :   These are just like the global C wrappers. They are
+    4234             :   just defined here and not declared since they
+    4235             :   should not be used from c/c++ anyway.
+    4236             : 
+    4237             :   We use a macro that does the following:
+    4238             :   - declare a static function named NAME_static
+    4239             :   - declare a number of functions named NAME_ etc, with all possible
+    4240             :     fortran mangling schemes (zero, one, or two underscores, lower and upper case)
+    4241             :   - define the NAME_static function.
+    4242             : 
+    4243             :   The static function is used basically as an inline function in a C-compatible manner.
+    4244             : */
+    4245             : 
+    4246             : #define __PLUMED_IMPLEMENT_FORTRAN(lower,upper,arg1,arg2) \
+    4247             :   static void lower ## _static arg1; \
+    4248             :   extern void lower      arg1 {lower ## _static arg2;} \
+    4249             :   extern void lower ##_  arg1 {lower ## _static arg2;} \
+    4250             :   extern void lower ##__ arg1 {lower ## _static arg2;} \
+    4251             :   extern void upper      arg1 {lower ## _static arg2;} \
+    4252             :   extern void upper ##_  arg1 {lower ## _static arg2;} \
+    4253             :   extern void upper ##__ arg1 {lower ## _static arg2;} \
+    4254             :   static void lower ## _static arg1
+    4255             : 
+    4256             : /* FORTRAN wrappers would only make sense as extern "C" */
+    4257             : 
+    4258             : __PLUMED_WRAPPER_EXTERN_C_BEGIN
+    4259             : 
+    4260          36 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_create,PLUMED_F_CREATE,(char*c),(c)) {
+    4261          18 :   plumed_c2f(plumed_create(),c);
+    4262          18 : }
+    4263             : 
+    4264          12 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_create_dlopen,PLUMED_F_CREATE_DLOPEN,(char*path,char*c),(path,c)) {
+    4265           6 :   plumed_c2f(plumed_create_dlopen(path),c);
+    4266           6 : }
+    4267             : 
+    4268          12 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_create_reference,PLUMED_F_CREATE_REFERENCE,(char* r,char*c),(r,c)) {
+    4269           6 :   plumed_c2f(plumed_create_reference_f(r),c);
+    4270           6 : }
+    4271             : 
+    4272           0 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_create_invalid,PLUMED_F_CREATE_INVALID,(char* c),(c)) {
+    4273           0 :   plumed_c2f(plumed_create_invalid(),c);
+    4274           0 : }
+    4275             : 
+    4276         558 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_cmd,PLUMED_F_CMD,(char*c,char*key,void*val),(c,key,val)) {
+    4277         279 :   plumed_cmd(plumed_f2c(c),key,val);
+    4278         279 : }
+    4279             : 
+    4280          60 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_finalize,PLUMED_F_FINALIZE,(char*c),(c)) {
+    4281          30 :   plumed_finalize(plumed_f2c(c));
+    4282          30 : }
+    4283             : 
+    4284          12 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_installed,PLUMED_F_INSTALLED,(int*i),(i)) {
+    4285             :   assert(i);
+    4286           6 :   *i=plumed_installed();
+    4287           6 : }
+    4288             : 
+    4289             : /* New in PLUMED 2.5 */
+    4290           0 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_valid,PLUMED_F_VALID,(char*c,int*i),(c,i)) {
+    4291             :   assert(i);
+    4292           0 :   *i=plumed_valid(plumed_f2c(c));
+    4293           0 : }
+    4294             : 
+    4295          36 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_use_count,PLUMED_F_USE_COUNT,(char*c,int*i),(c,i)) {
+    4296             :   assert(i);
+    4297          18 :   *i=plumed_use_count(plumed_f2c(c));
+    4298          18 : }
+    4299             : 
+    4300             : /* New in PLUMED 2.8 */
+    4301             : 
+    4302             : /* note: flags & (~0x1ffffff) removes bits that are set here (code and size) */
+    4303             : 
+    4304             : #define __PLUMED_IMPLEMENT_F_SAFEPTR_INNER(type,type_,size,code,suffix) \
+    4305             : plumed_safeptr plumed_f_safeptr_ ## type_ ## suffix(void*val,__PLUMED_WRAPPER_STD size_t nelem,__PLUMED_WRAPPER_STD size_t*shape,__PLUMED_WRAPPER_STD size_t flags,void*opt) {\
+    4306             :   plumed_safeptr safe; \
+    4307             :   safe.ptr=val; \
+    4308             :   safe.nelem=nelem; \
+    4309             :   safe.shape=shape; \
+    4310             :   safe.flags= (flags & (~0x1ffffffu)) + 0x10000*code + size; \
+    4311             :   safe.opt=opt; \
+    4312             :   return safe; \
+    4313             : }
+    4314             : 
+    4315             : #define __PLUMED_IMPLEMENT_F_SAFEPTR(type,type_,size,code) \
+    4316             :   __PLUMED_IMPLEMENT_F_SAFEPTR_INNER(type,type_,size,code,) \
+    4317             :   __PLUMED_IMPLEMENT_F_SAFEPTR_INNER(type,type_,size,code,_scalar)
+    4318             : 
+    4319             : #define __PLUMED_IMPLEMENT_F_SAFEPTR_EMPTY(type,type_,code) \
+    4320             :         __PLUMED_IMPLEMENT_F_SAFEPTR(type,type_,0,code)
+    4321             : 
+    4322             : #define __PLUMED_IMPLEMENT_F_SAFEPTR_SIZED(type,type_,code) \
+    4323             :         __PLUMED_IMPLEMENT_F_SAFEPTR(type,type_,sizeof(type),code)
+    4324             : 
+    4325          24 : __PLUMED_IMPLEMENT_F_SAFEPTR_EMPTY(void,ptr,0)
+    4326           1 : __PLUMED_IMPLEMENT_F_SAFEPTR_SIZED(float,float,4)
+    4327          19 : __PLUMED_IMPLEMENT_F_SAFEPTR_SIZED(double,double,4)
+    4328           0 : __PLUMED_IMPLEMENT_F_SAFEPTR_SIZED(long double,long_double,4)
+    4329          19 : __PLUMED_IMPLEMENT_F_SAFEPTR_SIZED(int,int,3)
+    4330           0 : __PLUMED_IMPLEMENT_F_SAFEPTR_SIZED(short,short,3)
+    4331           0 : __PLUMED_IMPLEMENT_F_SAFEPTR_SIZED(long,long,3)
+    4332          20 : __PLUMED_IMPLEMENT_F_SAFEPTR_SIZED(char,char,3)
+    4333             : 
+    4334             : #if __PLUMED_WRAPPER_GLOBAL /*{*/
+    4335             : 
+    4336          48 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_global,PLUMED_F_GLOBAL,(char*c),(c)) {
+    4337          24 :   plumed_c2f(plumed_gmain,c);
+    4338          24 : }
+    4339             : 
+    4340          36 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_ginitialized,PLUMED_F_GINITIALIZED,(int*i),(i)) {
+    4341             :   assert(i);
+    4342          18 :   *i=plumed_ginitialized();
+    4343          18 : }
+    4344             : 
+    4345          28 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_gcreate,PLUMED_F_GCREATE,(void),()) {
+    4346          14 :   plumed_gcreate();
+    4347          14 : }
+    4348             : 
+    4349         156 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_gcmd,PLUMED_F_GCMD,(char*key,void*val),(key,val)) {
+    4350          78 :   plumed_gcmd(key,val);
+    4351          78 : }
+    4352             : 
+    4353          28 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_gfinalize,PLUMED_F_GFINALIZE,(void),()) {
+    4354          14 :   plumed_gfinalize();
+    4355          14 : }
+    4356             : 
+    4357             : /* New in PLUMED 2.5 */
+    4358          12 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_gvalid,PLUMED_F_GVALID,(int*i),(i)) {
+    4359             :   assert(i);
+    4360           6 :   *i=plumed_gvalid();
+    4361           6 : }
+    4362             : 
+    4363             : #endif /*}*/
+    4364             : 
+    4365             : __PLUMED_WRAPPER_EXTERN_C_END
+    4366             : 
+    4367             : #endif /*}*/
+    4368             : 
+    4369             : #endif /*}*/
+    4370             : 
+    4371             : #endif /*}*/
+    4372             : 
+    4373             : /* END OF DEFINITIONS */
+    4374             : 
+    4375             : /* reset variable to allow it to be redefined upon re-inclusion */
+    4376             : 
+    4377             : #undef __PLUMED_WRAPPER_IMPLEMENTATION_
+    4378             : 
+    4379             : /* this macro is set in declarations */
+    4380             : #ifdef __PLUMED_WRAPPER_REDEFINE_CMD
+    4381             : #if defined(plumed_cmd)
+    4382             : #undef plumed_cmd
+    4383             : #endif
+    4384             : #define plumed_cmd __PLUMED_WRAPPER_REDEFINE_CMD
+    4385             : #endif
+    4386             : 
+    4387             : /* this macro is set in declarations */
+    4388             : #ifdef __PLUMED_WRAPPER_REDEFINE_GCMD
+    4389             : #if defined(plumed_gcmd)
+    4390             : #undef plumed_gcmd
+    4391             : #endif
+    4392             : #define plumed_gcmd __PLUMED_WRAPPER_REDEFINE_GCMD
+    4393             : #endif
+    4394             : 
+    4395             : /* this macro is set in declarations */
+    4396             : #ifdef __PLUMED_WRAPPER_REDEFINE_ERROR_RETHROW
+    4397             : #if defined(plumed_error_rethrow)
+    4398             : #undef plumed_error_rethrow
+    4399             : #endif
+    4400             : #define plumed_error_rethrow __PLUMED_WRAPPER_REDEFINE_ERROR_RETHROW
+    4401             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/wrapper/index-sort-f.html b/coverage/wrapper/index-sort-f.html new file mode 100644 index 000000000000..ee1680e1855e --- /dev/null +++ b/coverage/wrapper/index-sort-f.html @@ -0,0 +1,94 @@ + + + + + + + + LCOV - plumed test coverage - wrapper + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - wrapperHitTotalCoverage
Test:plumed test coverageLines:25050050.0 %
Date:2024-04-19 12:12:35Functions:14425456.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Plumed.h +
50.0%50.0%
+
50.0 %250 / 50056.7 %144 / 254
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/wrapper/index-sort-l.html b/coverage/wrapper/index-sort-l.html new file mode 100644 index 000000000000..ea17bcc1ab35 --- /dev/null +++ b/coverage/wrapper/index-sort-l.html @@ -0,0 +1,94 @@ + + + + + + + + LCOV - plumed test coverage - wrapper + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - wrapperHitTotalCoverage
Test:plumed test coverageLines:25050050.0 %
Date:2024-04-19 12:12:35Functions:14425456.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Plumed.h +
50.0%50.0%
+
50.0 %250 / 50056.7 %144 / 254
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/wrapper/index.html b/coverage/wrapper/index.html new file mode 100644 index 000000000000..2a765b67ba60 --- /dev/null +++ b/coverage/wrapper/index.html @@ -0,0 +1,94 @@ + + + + + + + + LCOV - plumed test coverage - wrapper + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - wrapperHitTotalCoverage
Test:plumed test coverageLines:25050050.0 %
Date:2024-04-19 12:12:35Functions:14425456.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Plumed.h +
50.0%50.0%
+
50.0 %250 / 50056.7 %144 / 254
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/index.html b/index.html new file mode 100644 index 000000000000..cc4afdd80de5 --- /dev/null +++ b/index.html @@ -0,0 +1,14 @@ + + + + Coverage scan +

Coverage scan

+Here you can find coverage scan reports for PLUMED: + +The first one is equivalent to the one you will find on CodeCov (if enabled). +The second one only contains third-party libraries included in PLUMED. + +